[
  {
    "path": ".ackrc",
    "content": "--ignore-dir=vendor\n--ignore-dir=build\n"
  },
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[Makefile]\nindent_style = tab\n\n[*.mk]\nindent_style = tab\n"
  },
  {
    "path": ".gitattributes",
    "content": "/vendor/** linguist-generated=true\n*.bin binary diff=hex\n* -text\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: JSON BinPack\n\non:\n  schedule:\n    # Once per day, Monday to Friday\n    - cron: '0 19 * * 1-5'\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  test:\n    strategy:\n      fail-fast: false\n      matrix:\n        platform:\n          - os: macos-latest\n            cc: clang\n            cxx: clang++\n            type: static\n          - os: macos-latest\n            cc: clang\n            cxx: clang++\n            type: shared\n          - os: macos-latest\n            cc: gcc-13\n            cxx: g++-13\n            type: static\n          - os: ubuntu-latest\n            cc: clang\n            cxx: clang++\n            type: static\n          - os: ubuntu-latest\n            cc: gcc\n            cxx: g++\n            type: static\n          - os: ubuntu-latest\n            cc: clang\n            cxx: clang++\n            type: shared\n          - os: ubuntu-latest\n            cc: gcc\n            cxx: g++\n            type: shared\n          - os: windows-latest\n            type: static\n          - os: windows-latest\n            type: shared\n\n          # Sanitizers\n          - os: ubuntu-latest\n            cc: clang\n            cxx: clang++\n            type: static\n            options: -DJSONBINPACK_ADDRESS_SANITIZER:BOOL=ON\n          - os: ubuntu-latest\n            cc: clang\n            cxx: clang++\n            type: static\n            options: -DJSONBINPACK_UNDEFINED_SANITIZER:BOOL=ON\n\n    runs-on: ${{ matrix.platform.os }}\n    env:\n      CC: ${{ matrix.platform.cc }}\n      CXX: ${{ matrix.platform.cxx }}\n    steps:\n      - uses: actions/checkout@v3\n      - name: Install dependencies (macOS)\n        if: runner.os == 'macos'\n        run: brew bundle\n        env:\n          HOMEBREW_NO_ANALYTICS: 1\n          HOMEBREW_NO_AUTO_UPDATE: 1\n\n      - run: cmake --version\n      - name: Configure JSON BinPack (static)\n        if: matrix.platform.type == 'static'\n        run: >\n          cmake -S . -B ./build\n          -DCMAKE_BUILD_TYPE:STRING=Release\n          -DJSONBINPACK_NUMERIC:BOOL=ON\n          -DJSONBINPACK_RUNTIME:BOOL=ON\n          -DJSONBINPACK_COMPILER:BOOL=ON\n          -DJSONBINPACK_TESTS:BOOL=ON\n          -DJSONBINPACK_DOCS:BOOL=OFF\n          -DBUILD_SHARED_LIBS:BOOL=OFF\n          -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON\n          ${{ matrix.platform.options }}\n      - name: Configure JSON BinPack (shared)\n        if: matrix.platform.type == 'shared'\n        run: >\n          cmake -S . -B ./build\n          -DCMAKE_BUILD_TYPE:STRING=Release\n          -DJSONBINPACK_NUMERIC:BOOL=ON\n          -DJSONBINPACK_RUNTIME:BOOL=ON\n          -DJSONBINPACK_COMPILER:BOOL=ON\n          -DJSONBINPACK_TESTS:BOOL=ON\n          -DJSONBINPACK_DOCS:BOOL=OFF\n          -DBUILD_SHARED_LIBS:BOOL=ON\n          -DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON\n          ${{ matrix.platform.options }}\n\n      - run: cmake --build ./build --config Release --target clang_format_test\n      - run: cmake --build ./build --config Release --parallel 4\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_core\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_core_dev\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_blaze\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_blaze_dev\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_jsonbinpack\n      - run: >\n          cmake --install ./build --prefix ./build/dist --config Release --verbose\n          --component sourcemeta_jsonbinpack_dev\n\n      # Not every CTest version supports the --test-dir option. If such option\n      # is not recognized, `ctest` will successfully exit finding no tests.\n      # Better to be sure and `cd` all the time here.\n      - run: cd ./build && ctest --build-config Release --output-on-failure --parallel\n        env:\n          # See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html\n          UBSAN_OPTIONS: print_stacktrace=1\n"
  },
  {
    "path": ".github/workflows/website-build.yml",
    "content": "name: website\non:\n  pull_request:\n\nconcurrency:\n  group: website-build-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n      - run: sudo apt update\n      - run: sudo apt-get install --yes doxygen\n      - run: >\n          cmake -S . -B ./build\n          -DCMAKE_BUILD_TYPE:STRING=Release\n          -DJSONBINPACK_NUMERIC:BOOL=OFF\n          -DJSONBINPACK_RUNTIME:BOOL=OFF\n          -DJSONBINPACK_COMPILER:BOOL=OFF\n          -DJSONBINPACK_TESTS:BOOL=OFF\n          -DJSONBINPACK_DOCS:BOOL=ON\n      - run: cmake --build ./build --config Release --target doxygen\n"
  },
  {
    "path": ".github/workflows/website-deploy.yml",
    "content": "name: website\non:\n  push:\n    branches: [ \"main\" ]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\nconcurrency:\n  group: website-deploy-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  deploy:\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n      - run: sudo apt update\n      - run: sudo apt-get install --yes doxygen\n      - run: >\n          cmake -S . -B ./build\n          -DCMAKE_BUILD_TYPE:STRING=Release\n          -DJSONBINPACK_NUMERIC:BOOL=OFF\n          -DJSONBINPACK_RUNTIME:BOOL=OFF\n          -DJSONBINPACK_COMPILER:BOOL=OFF\n          -DJSONBINPACK_TESTS:BOOL=OFF\n          -DJSONBINPACK_DOCS:BOOL=ON\n\n      - run: cmake --build ./build --config Release --target doxygen\n\n      - name: Setup Pages\n        uses: actions/configure-pages@v5\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n        with:\n          path: ./build/www\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by https://www.toptal.com/developers/gitignore/api/c,c++,node,cmake\n# Edit at https://www.toptal.com/developers/gitignore?templates=c,c++,node,cmake\n\n### C ###\n# Prerequisites\n*.d\n\n# Object files\n*.o\n*.ko\n*.obj\n*.elf\n\n# Linker output\n*.ilk\n*.map\n*.exp\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Libraries\n*.lib\n*.a\n*.la\n*.lo\n\n# Shared objects (inc. Windows DLLs)\n*.dll\n*.so\n*.so.*\n*.dylib\n\n# Executables\n*.exe\n*.out\n*.app\n*.i*86\n*.x86_64\n*.hex\n\n# Debug files\n*.dSYM/\n*.su\n*.idb\n*.pdb\n\n# Kernel Module Compile Results\n*.mod*\n*.cmd\n.tmp_versions/\nmodules.order\nModule.symvers\nMkfile.old\ndkms.conf\n\n### C++ ###\n# Prerequisites\n\n# Compiled Object files\n*.slo\n\n# Precompiled Headers\n\n# Compiled Dynamic libraries\n\n# Fortran module files\n*.mod\n*.smod\n\n# Compiled Static libraries\n*.lai\n\n# Executables\n\n### CMake ###\nCMakeLists.txt.user\nCMakeCache.txt\nCMakeFiles\nCMakeScripts\nTesting\nMakefile\ncmake_install.cmake\ninstall_manifest.txt\ncompile_commands.json\nCTestTestfile.cmake\n_deps\n\n### CMake Patch ###\n# External projects\n*-prefix/\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional stylelint cache\n.stylelintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# vuepress v2.x temp and cache directory\n.temp\n\n# Docusaurus cache and generated files\n.docusaurus\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n# yarn v2\n.yarn/cache\n.yarn/unplugged\n.yarn/build-state.yml\n.yarn/install-state.gz\n.pnp.*\n\n### Node Patch ###\n# Serverless Webpack directories\n.webpack/\n\n# Optional stylelint cache\n\n# SvelteKit build / generate output\n.svelte-kit\n\n# End of https://www.toptal.com/developers/gitignore/api/c,c++,node,cmake,jekyll\n\n/build\n!/Makefile\n.DS_Store\nCMakeUserPresets.json\nBrewfile.lock.json\n"
  },
  {
    "path": "Brewfile",
    "content": "brew \"cmake\"\nbrew \"gcc@13\"\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(jsonbinpack VERSION 0.0.1 LANGUAGES CXX\n  DESCRIPTION \"\\\nA space-efficient open-source binary JSON serialization \\\nformat based on JSON Schema with \\\nboth schema-driven and schema-less support.\"\n  HOMEPAGE_URL \"https://jsonbinpack.sourcemeta.com\")\nlist(APPEND CMAKE_MODULE_PATH \"${PROJECT_SOURCE_DIR}/cmake\")\n\n# Options\noption(JSONBINPACK_RUNTIME \"Build the JSON BinPack runtime\" ON)\noption(JSONBINPACK_COMPILER \"Build the JSON BinPack compiler\" ON)\noption(JSONBINPACK_TESTS \"Build the JSON BinPack tests\" OFF)\noption(JSONBINPACK_INSTALL \"Install the JSON BinPack library\" ON)\noption(JSONBINPACK_DOCS \"Build the JSON BinPack documentation\" OFF)\noption(JSONBINPACK_ADDRESS_SANITIZER \"Build JSON BinPack with an address sanitizer\" OFF)\noption(JSONBINPACK_UNDEFINED_SANITIZER \"Build JSON BinPack with an undefined behavior sanitizer\" OFF)\n\nfind_package(Core REQUIRED)\nfind_package(Blaze REQUIRED)\n\nif(JSONBINPACK_INSTALL)\n  include(GNUInstallDirs)\n  include(CMakePackageConfigHelpers)\n  configure_package_config_file(\n    config.cmake.in\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n  write_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    COMPATIBILITY SameMajorVersion)\n  install(FILES\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\"\n    COMPONENT sourcemeta_jsonbinpack_dev)\nendif()\n\n# Runtime\nif(JSONBINPACK_RUNTIME)\n  add_subdirectory(src/runtime)\nendif()\n\n# Compiler\nif(JSONBINPACK_COMPILER)\n  add_subdirectory(src/compiler)\nendif()\n\nif(JSONBINPACK_ADDRESS_SANITIZER)\n  sourcemeta_sanitizer(TYPE address)\nelseif(JSONBINPACK_UNDEFINED_SANITIZER)\n  sourcemeta_sanitizer(TYPE undefined)\nendif()\n\nif(JSONBINPACK_DOCS)\n  sourcemeta_target_doxygen(CONFIG \"${PROJECT_SOURCE_DIR}/doxygen/Doxyfile.in\"\n    OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/www\")\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_target_clang_format(SOURCES\n    src/*.h src/*.cc\n    test/*.h test/*.cc)\nendif()\n\n# Testing\nif(JSONBINPACK_TESTS)\n  enable_testing()\n\n  if(JSONBINPACK_RUNTIME)\n    add_subdirectory(test/runtime)\n  endif()\n\n  if(JSONBINPACK_COMPILER)\n    add_subdirectory(test/compiler)\n  endif()\n\n  add_subdirectory(test/e2e)\n\n  if(PROJECT_IS_TOP_LEVEL)\n    # Otherwise we need the child project to link\n    # against the sanitizers too.\n    if(NOT JSONBINPACK_ADDRESS_SANITIZER AND NOT JSONBINPACK_UNDEFINED_SANITIZER)\n      add_subdirectory(test/packaging)\n    endif()\n  endif()\nendif()\n"
  },
  {
    "path": "DEPENDENCIES",
    "content": "vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02\ncore https://github.com/sourcemeta/core aa314809fdb59ed6fcb1b10b3087f32eebf708c5\nblaze https://github.com/sourcemeta/blaze 5554d3106d7920b28b852e929f0a31d7805effe1\nbootstrap https://github.com/twbs/bootstrap 1a6fdfae6be09b09eaced8f0e442ca6f7680a61e\n"
  },
  {
    "path": "LICENSE",
    "content": "This software is dual-licensed: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version. For the terms of this license, see\n<http://www.gnu.org/licenses/>.\n\nYou are free to use this software under the terms of the GNU Affero General\nPublic License WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nAlternatively, you can use this software under a commercial license, as set out\nin <https://www.sourcemeta.com/licensing/>.\n"
  },
  {
    "path": "Makefile",
    "content": "# Programs\nCMAKE = cmake\nCTEST = ctest\nPYTHON = python3\n\n# Options\nPRESET = Debug\nSHARED = OFF\n\nall: configure compile test\n\nconfigure: .always\n\t$(CMAKE) -S . -B ./build \\\n\t\t-DCMAKE_BUILD_TYPE:STRING=$(PRESET) \\\n\t\t-DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON \\\n\t\t-DJSONBINPACK_NUMERIC:BOOL=ON \\\n\t\t-DJSONBINPACK_RUNTIME:BOOL=ON \\\n\t\t-DJSONBINPACK_COMPILER:BOOL=ON \\\n\t\t-DJSONBINPACK_TESTS:BOOL=ON \\\n\t\t-DJSONBINPACK_DOCS:BOOL=ON \\\n\t\t-DBUILD_SHARED_LIBS:BOOL=$(SHARED)\n\ncompile: .always\n\t$(CMAKE) --build ./build --config $(PRESET) --target clang_format\n\t$(CMAKE) --build ./build --config $(PRESET) --parallel 4\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_core\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_core_dev\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_blaze\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_blaze_dev\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_jsonbinpack\n\t$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \\\n\t\t--component sourcemeta_jsonbinpack_dev\n\ntest: .always\n\t$(CMAKE) -E env UBSAN_OPTIONS=print_stacktrace=1 \\\n\t\t$(CTEST) --test-dir ./build --build-config $(PRESET) \\\n\t\t\t--output-on-failure --progress --parallel\n\ndoxygen: .always\n\t$(CMAKE) --build ./build --config $(PRESET) --target doxygen\n\nclean: .always\n\t$(CMAKE) -E rm -R -f build\n\n# For NMake, which doesn't support .PHONY\n.always:\n"
  },
  {
    "path": "README.markdown",
    "content": "**This is a work-in-progress. Please consider starring or watching the repository\nto stay up to date.**\n\n***\n\n![JSON BinPack](./assets/banner.png)\n\nJSON BinPack is an open-source binary JSON serialization format with a **strong\nfocus on space efficiency**. It supports schema-driven and schema-less modes to\nencode any [JSON](https://www.json.org) document given a matching [JSON Schema\n2020-12](http://json-schema.org) definition.\n\n![](./assets/example.png)\n\n- **Highly Space-efficient**: A reproducible benchmark study has proven JSON\n  BinPack to be space-efficient in comparison to 12 alternative binary\n  serialization formats in every considered case. Additionally, JSON BinPack\n  typically provides higher average size reduction than general purpose\n  compressors such as GZIP, LZMA and LZ4 with the highest compression levels.\n\n    [Take a look at the benchmark](https://benchmark.sourcemeta.com)\n\n- **Based on JSON Schema**: JSON BinPack adopts the industry-standard schema\n  language for JSON documents. Re-use the same schemas you already have in your\n  OpenAPI, AsyncAPI, RAML or other specifications. No need to learn more\n  domain-specific schema languages or attempt to translate between them.\n\n    [Learn more about JSON Schema](https://json-schema.org/)\n\n- **Optional Schema**: JSON BinPack is a hybrid serialization format that runs\n  in both schema-driven and schema-less modes. Thanks to JSON Schema, JSON\n  BinPack allows you to be as loose or specific as your use case demands, even\n  within the same document, without having to use different serialization\n  technologies.\n\n    [Read more about JSON Schema as a constraint system](https://modern-json-schema.com/json-schema-is-a-constraint-system)\n\nDocumentation\n-------------\n\nRefer to the project website for reference documentation:\n[https://jsonbinpack.sourcemeta.com](https://jsonbinpack.sourcemeta.com).\n\nDo you have any questions? Open a ticket on [GitHub\nDiscussions](https://github.com/sourcemeta/jsonbinpack/discussions)!\n\nFrequently Asked Questions\n--------------------------\n\n### How does JSON BinPack compare to compression formats like GZIP?\n\nOur [reproducible benchmark study](https://benchmark.sourcemeta.com) shows that\nthe semantic information provided by detailed schema definitions enables a\nserialization format such as JSON BinPack to often outperform general-purpose\ncompressors configured with even their highest supported compression levels,\nspecially for small and medium-sized JSON documents. For large JSON documents,\nyou can experiment combining JSON BinPack with a compression format to\npotentially achieve greater space-efficiency.\n\n### JSON BinPack is space-efficient, but what about runtime-efficiency?\n\nWhen transmitting data over the Internet, time is the bottleneck, making\ncomputation much cheaper in comparison. Leaving extremely low-powered devices\naside, trading more CPU cycles for better compression is a sensible choice.\nJSON BinPack particularly excels at improving network performance when\ntransmitting data through unreliable and low-bandwidth connections on mobile\nand IoT systems, and it is still optimized to deliver the best runtime\nefficiency possible.\n\nIf your use-case demands extreme runtime-efficiency or zero-copy serialization,\nsuch as in the case of intra-service or inter-process communication, we suggest\nyou consider alternative serialization formats such as\n[FlatBuffers](https://google.github.io/flatbuffers/) and [Cap'n\nProto](https://capnproto.org/).\n\n### How does JSON BinPack handle unknown fields?\n\nJSON BinPack serializes any instance that matches its JSON Schema definition.\nJSON Schema is an expressive constrain-based language that permits\nschema-writers to be as strict or loose on defining data as they wish. As a\nconsequence of adopting JSON Schema, JSON BinPack elegantly supports encoding\nfree-form data and unknown fields as long as the corresponding JSON Schema\ndefinition successfully validates the data.\n\nHowever, deserializing data that does not match the given JSON Schema\ndefinition is undefined behavior and will likely result in an exception being\nthrown.\n\n### How does JSON BinPack compare to [alternative]?\n\nWe maintain a [live benchmark](https://benchmark.sourcemeta.com/) comparing\nJSON BinPack to various popular alternatives, including Protocol Buffers, CBOR,\nMessagePack, Apache Avro, and more. We also published an [academic\npaper](https://arxiv.org/abs/2211.12799) discussing the benchmark results in\nmore detail. In summary, you can expect JSON BinPack to be as or more\nspace-efficient than every alternative in every tested case.\n\n### How does JSON BinPack support schema evolution?\n\nIn comparison to schema-driven alternatives like Protocol Buffers and Apache\nAvro that invented their own specialized schema language, JSON BinPack adopts a\npopular and industry-standard one: [JSON Schema](https://json-schema.org/).\nThis means that you can use JSON BinPack alongside any schema evolution tooling\nor approach from the wider JSON Schema ecosystem. A popular one from the\ndecentralised systems world is\n[Cambria](https://www.inkandswitch.com/cambria/).\n\n***\n\nDo you have further questions or feedback? Don't hesitate in reaching out on\n[GitHub\nDiscussions](https://github.com/sourcemeta/jsonbinpack/discussions)!\n\nResearch\n--------\n\nJSON BinPack is the result of extensive binary serialization research at the\nDepartment of Computer Science of University of Oxford. The project is led by\nJuan Cruz Viotti, a computer scientist with first-hand exposure to the problem\nof space-efficient network communication in the context of IoT and APIs, under\nthe supervision of Mital Kinderkhedia.\n\n- [JSON BinPack: A space-efficient schema-driven and schema-less binary\nserialization specification based on JSON\nSchema](https://www.jviotti.com/dissertation.pdf)\n\n    - Awarded the 2022 CAR Hoare Prize for the best performance on the project\n      in the MSc in Software Engineering\n    - Awarded the 2022 CAR Hoare Prize for the best performance in the\n      examination by coursework in the MSc in Software Engineering\n\n- [Benchmarking JSON BinPack](https://arxiv.org/abs/2211.12799)\n- [A benchmark of JSON-compatible binary serialization\n  specifications](https://arxiv.org/abs/2201.03051)\n- [A survey of JSON-compatible binary serialization\n  specification](https://arxiv.org/abs/2201.02089)\n"
  },
  {
    "path": "cmake/FindBlaze.cmake",
    "content": "if(NOT Blaze_FOUND)\n  if(JSONBINPACK_INSTALL)\n    set(SOURCEMETA_BLAZE_INSTALL ON CACHE BOOL \"enable installation\")\n  else()\n    set(SOURCEMETA_BLAZE_INSTALL OFF CACHE BOOL \"disable installation\")\n  endif()\n\n  set(BLAZE_TEST OFF CACHE BOOL \"disable\")\n  set(BLAZE_CONFIGURATION OFF CACHE BOOL \"disable\")\n  set(BLAZE_CONTRIB OFF CACHE BOOL \"disable\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/blaze\")\n  include(Sourcemeta)\n  set(Blaze_FOUND ON)\nendif()\n"
  },
  {
    "path": "cmake/FindCore.cmake",
    "content": "if(NOT Core_FOUND)\n  if(JSONBINPACK_INSTALL)\n    set(SOURCEMETA_CORE_INSTALL ON CACHE BOOL \"enable installation\")\n  else()\n    set(SOURCEMETA_CORE_INSTALL OFF CACHE BOOL \"disable installation\")\n  endif()\n\n  set(SOURCEMETA_CORE_TIME OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_UUID OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_GZIP OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_MD5  OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_JSONL OFF CACHE BOOL \"disable JSONL support\")\n  set(SOURCEMETA_CORE_YAML ON CACHE BOOL \"needed by Blaze\")\n  set(SOURCEMETA_CORE_EXTENSION_OPTIONS OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_EXTENSION_BUILD OFF CACHE BOOL \"disable\")\n  set(SOURCEMETA_CORE_CONTRIB_GOOGLETEST ${JSONBINPACK_TESTS} CACHE BOOL \"GoogleTest\")\n  set(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK OFF CACHE BOOL \"GoogleBenchmark\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/core\")\n  include(Sourcemeta)\n  set(Core_FOUND ON)\nendif()\n"
  },
  {
    "path": "config.cmake.in",
    "content": "@PACKAGE_INIT@\n\n# Support both casing styles\nlist(APPEND JSONBINPACK_COMPONENTS ${JSONBinPack_FIND_COMPONENTS})\nlist(APPEND JSONBINPACK_COMPONENTS ${jsonbinpack_FIND_COMPONENTS})\nif(NOT JSONBINPACK_COMPONENTS)\n  list(APPEND JSONBINPACK_COMPONENTS runtime)\n  list(APPEND JSONBINPACK_COMPONENTS compiler)\nendif()\n\ninclude(CMakeFindDependencyMacro)\nfind_dependency(Core COMPONENTS numeric regex uri json jsonpointer jsonschema io)\nfind_dependency(Blaze COMPONENTS alterschema)\n\nforeach(component ${JSONBINPACK_COMPONENTS})\n  if(component STREQUAL \"runtime\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_jsonbinpack_runtime.cmake\")\n  elseif(component STREQUAL \"compiler\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_jsonbinpack_compiler.cmake\")\n  else()\n    message(FATAL_ERROR \"Unknown JSON BinPack component: ${component}\")\n  endif()\nendforeach()\n\ncheck_required_components(\"@PROJECT_NAME@\")\n"
  },
  {
    "path": "doxygen/Doxyfile.in",
    "content": "# Doxyfile 1.9.3\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the configuration\n# file that follow. The default is UTF-8 which is also the encoding used for all\n# text before the first occurrence of this tag. Doxygen uses libiconv (or the\n# iconv built into libc) for the transcoding. See\n# https://www.gnu.org/software/libiconv/ for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = JSON BinPack\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         = @CMAKE_PROJECT_VERSION@\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"@CMAKE_PROJECT_DESCRIPTION@\"\n\n# With the PROJECT_LOGO tag one can specify a logo or an icon that is included\n# in the documentation. The maximum height of the logo should not exceed 55\n# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy\n# the logo to the output directory.\n\nPROJECT_LOGO           = @PROJECT_SOURCE_DIR@/doxygen/logo.png\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = @SOURCEMETA_TARGET_DOXYGEN_OUTPUT@\n\n# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII\n# characters to appear in the names of generated files. If set to NO, non-ASCII\n# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode\n# U+3044.\n# The default value is: NO.\n\nALLOW_UNICODE_NAMES    = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        = @PROJECT_SOURCE_DIR@/doxygen\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = NO\n\n# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line\n# such as\n# /***************\n# as being the beginning of a Javadoc-style comment \"banner\". If set to NO, the\n# Javadoc-style will behave just like regular comments and it will not be\n# interpreted by doxygen.\n# The default value is: NO.\n\nJAVADOC_BANNER         = NO\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# By default Python docstrings are displayed as preformatted text and doxygen's\n# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the\n# doxygen's special commands can be used and the contents of the docstring\n# documentation blocks is shown as doxygen documentation.\n# The default value is: YES.\n\nPYTHON_DOCSTRING       = YES\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new\n# page for each member. If set to NO, the documentation of a member will be part\n# of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:^^\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". Note that you cannot put \\n's in the value part of an alias\n# to insert newlines (in the resulting output). You can put ^^ in the value part\n# of an alias to insert a newline as if a physical newline was in the original\n# file. When you need a literal { or } or , in the value part of an alias you\n# have to escape them by means of a backslash (\\), this can lead to conflicts\n# with the commands \\{ and \\} for these it is advised to use the version @{ and\n# @} or use a double escape (\\\\{ and \\\\})\n\nALIASES                =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice\n# sources only. Doxygen will then generate output that is more tailored for that\n# language. For instance, namespaces will be presented as modules, types will be\n# separated into more groups, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_SLICE  = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,\n# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,\n# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:\n# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser\n# tries to guess whether the code is fixed or free formatted code, this is the\n# default for Fortran type files). For instance to make doxygen treat .inc files\n# as Fortran files (default is PHP), and .f files as C (default is Fortran),\n# use: inc=Fortran f=C.\n#\n# Note: For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen. When specifying no_extension you should add\n# * to the FILE_PATTERNS.\n#\n# Note see also the list of default file extension mappings.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See https://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up\n# to that level are automatically included in the table of contents, even if\n# they do not have an id attribute.\n# Note: This feature currently applies only to Markdown headings.\n# Minimum value: 0, maximum value: 99, default value: 5.\n# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.\n\nTOC_INCLUDE_HEADINGS   = 5\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by putting a % sign in front of the word or\n# globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# If one adds a struct or class to a group and this option is enabled, then also\n# any nested class or struct is added to the same group. By default this option\n# is disabled and one has to add nested compounds explicitly via \\ingroup.\n# The default value is: NO.\n\nGROUP_NESTED_COMPOUNDS = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use\n# during processing. When set to 0 doxygen will based this on the number of\n# cores available in the system. You can set it explicitly to a value larger\n# than 0 to get more control over the balance between CPU load and processing\n# speed. At this moment only the input processing can be done using multiple\n# threads. Since this is still an experimental feature the default is set to 1,\n# which effectively disables parallel processing. Please report any issues you\n# encounter. Generating dot graphs in parallel is controlled by the\n# DOT_NUM_THREADS setting.\n# Minimum value: 0, maximum value: 32, default value: 1.\n\nNUM_PROC_THREADS       = 1\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual\n# methods of a class will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIV_VIRTUAL   = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO,\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. If set to YES, local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO, only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If this flag is set to YES, the name of an unnamed parameter in a declaration\n# will be determined by the corresponding definition. By default unnamed\n# parameters remain unnamed in the output.\n# The default value is: YES.\n\nRESOLVE_UNNAMED_PARAMS = YES\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO, these classes will be included in the various overviews. This option\n# has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# declarations. If set to NO, these declarations will be included in the\n# documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO, these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# With the correct setting of option CASE_SENSE_NAMES doxygen will better be\n# able to match the capabilities of the underlying filesystem. In case the\n# filesystem is case sensitive (i.e. it supports files in the same directory\n# whose names only differ in casing), the option must be set to YES to properly\n# deal with such files in case they appear in the input. For filesystems that\n# are not case sensitive the option should be be set to NO to properly deal with\n# output files written for symbols that only differ in casing, such as for two\n# classes, one named CLASS and the other named Class, and to also support\n# references to files without having to specify the exact matching casing. On\n# Windows (including Cygwin) and MacOS, users should typically set this option\n# to NO, whereas on Linux or other Unix flavors it should typically be set to\n# YES.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES, the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will\n# append additional text to a page's title, such as Class Reference. If set to\n# YES the compound reference will be hidden.\n# The default value is: NO.\n\nHIDE_COMPOUND_REFERENCE= NO\n\n# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class\n# will show which file needs to be included to use the class.\n# The default value is: YES.\n\nSHOW_HEADERFILE        = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo\n# list. This list is created by putting \\todo commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test\n# list. This list is created by putting \\test commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES, the\n# list will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = NO\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = NO\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file. See also section \"Changing the\n# layout of pages\" for information.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            =\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. See also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as documenting some parameters in\n# a documented function twice, or documenting parameters that don't exist or\n# using markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete\n# function parameter documentation. If set to NO, doxygen will accept that some\n# parameters have no documentation without warning.\n# The default value is: YES.\n\nWARN_IF_INCOMPLETE_DOC = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO, doxygen will only warn about wrong parameter\n# documentation, but not about the absence of documentation. If EXTRACT_ALL is\n# set to YES then this flag will automatically be disabled. See also\n# WARN_IF_INCOMPLETE_DOC\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when\n# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS\n# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but\n# at the end of the doxygen process doxygen will return with a non-zero status.\n# Possible values are: NO, YES and FAIL_ON_WARNINGS.\n# The default value is: NO.\n\nWARN_AS_ERROR          = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr). In case the file specified cannot be opened for writing the\n# warning and error messages are written to standard error. When as file - is\n# specified the warning and error messages are written to standard output\n# (stdout).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = @PROJECT_SOURCE_DIR@/src\nINPUT                  += @PROJECT_SOURCE_DIR@/doxygen/todo.markdown\nINPUT                  += @PROJECT_SOURCE_DIR@/doxygen/schemas.markdown\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see:\n# https://www.gnu.org/software/libiconv/) for the list of possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# read by doxygen.\n#\n# Note the list of default checked file patterns might differ from the list of\n# default file extension mappings.\n#\n# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,\n# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,\n# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,\n# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C\n# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,\n# *.vhdl, *.ucf, *.qsf and *.ice.\n\nFILE_PATTERNS          = */include/*.h\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# ANamespace::AClass, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             = @PROJECT_SOURCE_DIR@/assets\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/doxygen/todo.markdown\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# entity all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see https://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = .\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            =\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            =\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        =\n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# cascading style sheets that are included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefore more robust against future updates.\n# Doxygen will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list). For an example see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  =\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       =\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the style sheet and background images according to\n# this color. Hue is specified as an angle on a color-wheel, see\n# https://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use gray-scales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to YES can help to show when doxygen was last run and thus if the\n# documentation is up to date.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML\n# documentation will contain a main index with vertical navigation menus that\n# are dynamically created via JavaScript. If disabled, the navigation index will\n# consists of multiple levels of tabs that are statically embedded in every HTML\n# page. Disable this option to support browsers that do not have JavaScript,\n# like the Qt help browser.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_MENUS     = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see:\n# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To\n# create a documentation set, doxygen will generate a Makefile in the HTML\n# output directory. Running make will produce the docset in that directory and\n# running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy\n# genXcode/_index.html for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag determines the URL of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDURL         =\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = com.sourcemeta.jsonbinpack\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = com.sourcemeta.docs\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Sourcemeta\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# on Windows. In the beginning of 2021 Microsoft took the original page, with\n# a.o. the download links, offline the HTML help workshop was already many years\n# in maintenance mode). You can download the HTML help workshop from the web\n# archives at Installation executable (see:\n# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo\n# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler (hhc.exe). If non-empty,\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated\n# (YES) or that it should be included in the main .chm file (NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated\n# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it\n# enables the Previous and Next buttons.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = com.sourcemeta.jsonbinpack\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location (absolute path\n# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to\n# run qhelpgenerator on the generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = com.sourcemeta.jsonbinpack\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = YES\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine tune the look of the index (see \"Fine-tuning the output\"). As an\n# example, the default style sheet generated by doxygen has an example that\n# shows how to put an image at the root of the tree instead of the PROJECT_NAME.\n# Since the tree basically has the same information as the tab index, you could\n# consider setting DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = YES\n\n# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the\n# FULL_SIDEBAR option determines if the side bar is limited to only the treeview\n# area (value NO) or if it should extend to the full height of the window (value\n# YES). Setting this to YES gives a layout similar to\n# https://docs.readthedocs.io with more room for contents, but less room for the\n# project logo, title, and description. If either GENERATE_TREEVIEW or\n# DISABLE_INDEX is set to NO, this option has no effect.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFULL_SIDEBAR           = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email\n# addresses.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nOBFUSCATE_EMAILS       = YES\n\n# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg\n# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see\n# https://inkscape.org) to generate formulas as SVG images instead of PNGs for\n# the HTML output. These images will generally look nicer at scaled resolutions.\n# Possible values are: png (the default) and svg (looks nicer but requires the\n# pdf2svg or inkscape tool).\n# The default value is: png.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FORMULA_FORMAT    = png\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 20\n\n# Use the FORMULA_TRANSPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# The FORMULA_MACROFILE can contain LaTeX \\newcommand and \\renewcommand commands\n# to create new LaTeX commands to be used in formulas as building blocks. See\n# the section \"Including formulas\" for details.\n\nFORMULA_MACROFILE      =\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# https://www.mathjax.org) which uses client side JavaScript for the rendering\n# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.\n# Note that the different versions of MathJax have different requirements with\n# regards to the different settings, so it is possible that also other MathJax\n# settings have to be changed when switching between the different MathJax\n# versions.\n# Possible values are: MathJax_2 and MathJax_3.\n# The default value is: MathJax_2.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_VERSION        = MathJax_2\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. For more details about the output format see MathJax\n# version 2 (see:\n# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3\n# (see:\n# http://docs.mathjax.org/en/latest/web/components/output.html).\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility. This is the name for Mathjax version 2, for MathJax version 3\n# this will be translated into chtml), NativeMML (i.e. MathML. Only supported\n# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This\n# is the name for Mathjax version 3, for MathJax version 2 this will be\n# translated into HTML-CSS) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from https://www.mathjax.org before deployment. The default value is:\n# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2\n# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        =\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html\n# #tex-and-latex-extensions):\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# For example for MathJax version 3 (see\n# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):\n# MATHJAX_EXTENSIONS = ams\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see:\n# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using JavaScript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see:\n# https://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see:\n# https://xapian.org/). See the section \"External Indexing and Searching\" for\n# details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when not enabling USE_PDFLATEX the default is latex when enabling\n# USE_PDFLATEX the default is pdflatex and when in the later case latex is\n# chosen this is overwritten by pdflatex. For specific output languages the\n# default can have been set differently, this depends on the implementation of\n# the output language.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         =\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# Note: This tag is used in the Makefile / make.bat.\n# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file\n# (.tex).\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to\n# generate index for LaTeX. In case there is no backslash (\\) as first character\n# it will be automatically added in the LaTeX code.\n# Note: This tag is used in the generated output file (.tex).\n# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.\n# The default value is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_MAKEINDEX_CMD    = makeindex\n\n# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. The package can be specified just\n# by its name or with the correct syntax as to be used with the LaTeX\n# \\usepackage command. To get the times font for instance you can specify :\n# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}\n# To use the option intlimits with the amsmath package you can specify:\n# EXTRA_PACKAGES=[intlimits]{amsmath}\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         = amsfonts\n\n# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for\n# the generated LaTeX document. The header should contain everything until the\n# first chapter. If it is left blank doxygen will generate a standard header. It\n# is highly recommended to start with a default header using\n# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty\n# and then modify the file new_header.tex. See also section \"Doxygen usage\" for\n# information on how to generate the default header that doxygen normally uses.\n#\n# Note: Only use a user-defined header if you know what you are doing!\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. The following\n# commands have a special meaning inside the header (and footer): For a\n# description of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for\n# the generated LaTeX document. The footer should contain everything after the\n# last chapter. If it is left blank doxygen will generate a standard footer. See\n# LATEX_HEADER for more information on how to generate a default footer and what\n# special commands can be used inside the footer. See also section \"Doxygen\n# usage\" for information on how to generate the default footer that doxygen\n# normally uses. Note: Only use a user-defined footer if you know what you are\n# doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# LaTeX style sheets that are included after the standard style sheets created\n# by doxygen. Using this option one can overrule certain style aspects. Doxygen\n# will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_STYLESHEET =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as\n# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX\n# files. Set this option to YES, to get a higher quality PDF documentation.\n#\n# See also section LATEX_CMD_NAME for selecting the engine.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# https://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_TIMESTAMP        = NO\n\n# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)\n# path from which the emoji images will be read. If a relative path is entered,\n# it will be relative to the LATEX_OUTPUT directory. If left blank the\n# LATEX_OUTPUT directory will be used.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EMOJI_DIRECTORY  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's\n# configuration file, i.e. a series of assignments. You only have to provide\n# replacements, missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's configuration file. A template extensions file can be\n# generated using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# The MAN_SUBDIR tag determines the name of the directory created within\n# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by\n# MAN_EXTENSION with the initial . removed.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_SUBDIR             =\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include\n# namespace members in file scope as well, matching the HTML output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_NS_MEMB_FILE_SCOPE = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an\n# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures\n# the structure of the code including all documentation. Note that this feature\n# is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO, the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names\n# in the source code. If set to NO, only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES, the include files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             += SOURCEMETA_JSONBINPACK_NUMERIC_EXPORT=\nPREDEFINED             += SOURCEMETA_JSONBINPACK_COMPILER_EXPORT=\nPREDEFINED             += SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT=\nPREDEFINED             += DOXYGEN\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      += SOURCEMETA_JSONBINPACK_NUMERIC_EXPORT\nEXPAND_AS_DEFINED      += SOURCEMETA_JSONBINPACK_COMPILER_EXPORT\nEXPAND_AS_DEFINED      += SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES, all external class will be listed in\n# the class index. If set to NO, only the inherited external classes will be\n# listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed\n# in the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: NO.\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font in the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a\n# graph for each documented class showing the direct and indirect inheritance\n# relations. In case HAVE_DOT is set as well dot will be used to draw the graph,\n# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set\n# to TEXT the direct and indirect inheritance relations will be shown as texts /\n# links.\n# Possible values are: NO, YES, TEXT and GRAPH.\n# The default value is: YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag UML_LOOK is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and\n# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS\n# tag is set to YES, doxygen will add type and arguments for attributes and\n# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen\n# will not generate fields with class member information in the UML graphs. The\n# class diagrams will look similar to the default class diagrams but using UML\n# notation for the relationships.\n# Possible values are: NO, YES and NONE.\n# The default value is: NO.\n# This tag requires that the tag UML_LOOK is set to YES.\n\nDOT_UML_DETAILS        = NO\n\n# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters\n# to display on a single line. If the actual line length exceeds this threshold\n# significantly it will wrapped across multiple lines. Some heuristics are apply\n# to avoid ugly line breaks.\n# Minimum value: 0, maximum value: 1000, default value: 17.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_WRAP_THRESHOLD     = 17\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command. Disabling a call graph can be\n# accomplished by means of the command \\hidecallgraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command. Disabling a caller graph can be\n# accomplished by means of the command \\hidecallergraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels\n# of child directories generated in directory dependency graphs by dot.\n# Minimum value: 1, maximum value: 25, default value: 1.\n# This tag requires that the tag DIRECTORY_GRAPH is set to YES.\n\nDIR_GRAPH_MAX_DEPTH    = 1\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot. For an explanation of the image formats see the section\n# output formats in the documentation of the dot tool (Graphviz (see:\n# http://www.graphviz.org/)).\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,\n# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and\n# png:gdiplus:gdiplus.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the\n# path where java can find the plantuml.jar file or to the filename of jar file\n# to be used. If left blank, it is assumed PlantUML is not used or called during\n# a preprocessing step. Doxygen will generate a warning when it encounters a\n# \\startuml command in this case and will not generate output for the diagram.\n\nPLANTUML_JAR_PATH      =\n\n# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a\n# configuration file for plantuml.\n\nPLANTUML_CFG_FILE      =\n\n# When using plantuml, the specified paths are searched for files specified by\n# the !include statement in a plantuml block.\n\nPLANTUML_INCLUDE_PATH  =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal\n# graphical representation for inheritance and collaboration diagrams is used.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate\n# files that are used to generate the various graphs.\n#\n# Note: This setting is not only used for dot files but also for msc temporary\n# files.\n# The default value is: YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "doxygen/todo.markdown",
    "content": "Status\n======\n\nJSON BinPack is under heavy development. This page aims to document what's\nmissing. If you want to fund JSON BinPack's development, please consider\n[becoming a sponsor](https://github.com/sponsors/sourcemeta).\n\nMapper\n------\n\nDefined in @ref compiler.\n\n| Category | Status                           |\n|----------|----------------------------------|\n| Any      | Partial. Does not handle `oneOf` |\n| Array    | Missing implementation           |\n| Object   | Missing implementation           |\n| String   | Missing implementation           |\n\nEncodings\n---------\n\nDefined in @ref runtime.\n\n| Encoding                             | Type                 | Notes                  |\n|--------------------------------------|----------------------|------------------------|\n| `ONEOF_CHOICE_INDEX_PREFIX`          | @ref encoding_any    | Missing implementation |\n| `BOUNDED_TYPED_LENGTH_PREFIX`        | @ref encoding_array  | Missing implementation |\n| `REQUIRED_ONLY_BOUNDED_TYPED_OBJECT` | @ref encoding_object | Missing implementation |\n| `NON_REQUIRED_BOUNDED_TYPED_OBJECT`  | @ref encoding_object | Missing implementation |\n| `MIXED_BOUNDED_TYPED_OBJECT`         | @ref encoding_object | Missing implementation |\n| `REQUIRED_UNBOUNDED_TYPED_OBJECT`    | @ref encoding_object | Missing implementation |\n| `OPTIONAL_UNBOUNDED_TYPED_OBJECT`    | @ref encoding_object | Missing implementation |\n| `MIXED_UNBOUNDED_TYPED_OBJECT`       | @ref encoding_object | Missing implementation |\n| `PACKED_BOUNDED_REQUIRED_OBJECT`     | @ref encoding_object | Missing implementation |\n| `PACKED_UNBOUNDED_OBJECT`            | @ref encoding_object | Missing implementation |\n| `URL_PROTOCOL_HOST_REST`             | @ref encoding_string | Missing implementation |\n| `STRING_BROTLI`                      | @ref encoding_string | Missing implementation |\n| `STRING_DICTIONARY_COMPRESSOR`       | @ref encoding_string | Missing implementation |\n\nJSON Schema keywords\n--------------------\n\nA set of remaining keywords that JSON BinPack is expected to cover, without\nwhich a schema-less encoding is often unacceptable.\n\n| Keyword                 | Vocabulary  | Dialect |\n|-------------------------|-------------|---------|\n| `$ref`                  | Core        | 2020-12 |\n| `$anchor`               | Core        | 2020-12 |\n| `$dynamicRef`           | Core        | 2020-12 |\n| `$dynamicAnchor`        | Core        | 2020-12 |\n| `allOf`                 | Applicator  | 2020-12 |\n| `anyOf`                 | Applicator  | 2020-12 |\n| `oneOf`                 | Applicator  | 2020-12 |\n| `if`                    | Applicator  | 2020-12 |\n| `then`                  | Applicator  | 2020-12 |\n| `else`                  | Applicator  | 2020-12 |\n| `not`                   | Applicator  | 2020-12 |\n| `propertyNames`         | Applicator  | 2020-12 |\n| `dependentSchemas`      | Applicator  | 2020-12 |\n| `unevaluatedProperties` | Unevaluated | 2020-12 |\n| `unevaluatedItems`      | Unevaluated | 2020-12 |\n| `contentSchema`         | Content     | 2020-12 |\n| `contentMediaType`      | Content     | 2020-12 |\n| `contentEncoding`       | Content     | 2020-12 |\n\nOther\n-----\n\n- Support for recursive schemas\n- Deploy an online web playground\n"
  },
  {
    "path": "src/compiler/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT jsonbinpack NAME compiler\n  FOLDER \"JSON BinPack/Compiler\"\n  SOURCES\n    encoding.h compiler.cc\n    mapper/enum_8_bit.h\n    mapper/enum_8_bit_top_level.h\n    mapper/enum_arbitrary.h\n    mapper/enum_singleton.h\n    mapper/integer_bounded_8_bit.h\n    mapper/integer_bounded_greater_than_8_bit.h\n    mapper/integer_bounded_multiplier_8_bit.h\n    mapper/integer_bounded_multiplier_greater_than_8_bit.h\n    mapper/integer_lower_bound.h\n    mapper/integer_lower_bound_multiplier.h\n    mapper/integer_unbound.h\n    mapper/integer_unbound_multiplier.h\n    mapper/integer_upper_bound.h\n    mapper/integer_upper_bound_multiplier.h\n    mapper/number_arbitrary.h)\n\nif(JSONBINPACK_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT jsonbinpack NAME compiler)\nendif()\n\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler PRIVATE\n  sourcemeta::core::numeric)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler PRIVATE\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler PRIVATE\n  sourcemeta::blaze::alterschema)\n"
  },
  {
    "path": "src/compiler/compiler.cc",
    "content": "#include <sourcemeta/jsonbinpack/compiler.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <sourcemeta/blaze/alterschema.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include \"encoding.h\"\n\n#include <cassert>     // assert\n#include <type_traits> // std::true_type\n\nstatic auto transformer_callback_noop(\n    const sourcemeta::core::Pointer &, const std::string_view,\n    const std::string_view,\n    const sourcemeta::blaze::SchemaTransformRule::Result &,\n    [[maybe_unused]] const bool applied) -> void {\n  assert(applied);\n}\n\nnamespace sourcemeta::jsonbinpack {\n\nauto canonicalize(sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaWalker &walker,\n                  const sourcemeta::core::SchemaResolver &resolver,\n                  const std::string_view default_dialect) -> void {\n  sourcemeta::blaze::SchemaTransformer canonicalizer;\n  sourcemeta::blaze::add(canonicalizer,\n                         sourcemeta::blaze::AlterSchemaMode::Canonicalizer);\n  [[maybe_unused]] const auto result =\n      canonicalizer.apply(schema, walker, make_resolver(resolver),\n                          transformer_callback_noop, default_dialect);\n  assert(result.first);\n}\n\nauto make_encoding(sourcemeta::core::JSON &document,\n                   const std::string &encoding,\n                   const sourcemeta::core::JSON &options) -> void {\n  document.into_object();\n  document.assign(\"$schema\", sourcemeta::core::JSON{ENCODING_V1});\n  document.assign(\"binpackEncoding\", sourcemeta::core::JSON{encoding});\n  document.assign(\"binpackOptions\", options);\n}\n\n#include \"mapper/enum_8_bit.h\"\n#include \"mapper/enum_8_bit_top_level.h\"\n#include \"mapper/enum_arbitrary.h\"\n#include \"mapper/enum_singleton.h\"\n#include \"mapper/integer_bounded_8_bit.h\"\n#include \"mapper/integer_bounded_greater_than_8_bit.h\"\n#include \"mapper/integer_bounded_multiplier_8_bit.h\"\n#include \"mapper/integer_bounded_multiplier_greater_than_8_bit.h\"\n#include \"mapper/integer_lower_bound.h\"\n#include \"mapper/integer_lower_bound_multiplier.h\"\n#include \"mapper/integer_unbound.h\"\n#include \"mapper/integer_unbound_multiplier.h\"\n#include \"mapper/integer_upper_bound.h\"\n#include \"mapper/integer_upper_bound_multiplier.h\"\n#include \"mapper/number_arbitrary.h\"\n\nauto compile(sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const std::string_view default_dialect) -> void {\n  canonicalize(schema, walker, resolver, default_dialect);\n\n  sourcemeta::blaze::SchemaTransformer mapper;\n\n  // Enums\n  mapper.add<Enum8Bit>();\n  mapper.add<Enum8BitTopLevel>();\n  mapper.add<EnumArbitrary>();\n  mapper.add<EnumSingleton>();\n\n  // Integers\n  mapper.add<IntegerBounded8Bit>();\n  mapper.add<IntegerBoundedMultiplier8Bit>();\n  mapper.add<IntegerBoundedGreaterThan8Bit>();\n  mapper.add<IntegerBoundedMultiplierGreaterThan8Bit>();\n  mapper.add<IntegerLowerBound>();\n  mapper.add<IntegerLowerBoundMultiplier>();\n  mapper.add<IntegerUpperBound>();\n  mapper.add<IntegerUpperBoundMultiplier>();\n  mapper.add<IntegerUnbound>();\n  mapper.add<IntegerUnboundMultiplier>();\n\n  // Numbers\n  mapper.add<NumberArbitrary>();\n\n  [[maybe_unused]] const auto mapper_result =\n      mapper.apply(schema, walker, make_resolver(resolver),\n                   transformer_callback_noop, default_dialect);\n  assert(mapper_result.first);\n\n  // The \"any\" encoding is always the last resort\n  const auto dialect{sourcemeta::core::dialect(schema)};\n  if (dialect.empty() || dialect != ENCODING_V1) {\n    make_encoding(schema, \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n                  sourcemeta::core::JSON::make_object());\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/compiler/encoding.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_COMPILER_ENCODING_H_\n#define SOURCEMETA_JSONBINPACK_COMPILER_ENCODING_H_\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\nnamespace sourcemeta::jsonbinpack {\n\nconstexpr auto ENCODING_V1{\"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\"};\n\ninline auto make_resolver(const sourcemeta::core::SchemaResolver &fallback)\n    -> auto {\n  return [&fallback](std::string_view identifier)\n             -> std::optional<sourcemeta::core::JSON> {\n    if (identifier == ENCODING_V1) {\n      return sourcemeta::core::parse_json(R\"JSON({\n        \"$id\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n        \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n        \"$vocabulary\": {\n          \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n          \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\": true\n        }\n      })JSON\");\n    } else {\n      return fallback(identifier);\n    }\n  };\n}\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/compiler/include/sourcemeta/jsonbinpack/compiler.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_COMPILER_H_\n#define SOURCEMETA_JSONBINPACK_COMPILER_H_\n\n#ifndef SOURCEMETA_JSONBINPACK_COMPILER_EXPORT\n#include <sourcemeta/jsonbinpack/compiler_export.h>\n#endif\n\n/// @defgroup compiler Compiler\n/// @brief The built-time schema compiler of JSON BinPack\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/jsonbinpack/compiler.h>\n/// ```\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup compiler\n///\n/// Compile a JSON Schema into an encoding schema. Keep in mind this function\n/// mutates the input schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/binpack/compiler.h>\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// #include <iostream>\n///\n/// auto schema{sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\")};\n///\n/// sourcemeta::jsonbinpack::compile(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver);\n///\n/// sourcemeta::core::prettify(schema, std::cout);\n/// std::cout << std::endl;\n/// ```\nSOURCEMETA_JSONBINPACK_COMPILER_EXPORT\nauto compile(sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             std::string_view default_dialect = \"\") -> void;\n\n/// @ingroup compiler\n///\n/// Transform a JSON Schema into its canonical form to prepare it for\n/// compilation. Keep in mind this function mutates the input schema. Also, the\n/// `compile` function already performs canonicalization. This function is\n/// exposed mainly for debugging and testing purposes. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/binpack/compiler.h>\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// #include <iostream>\n///\n/// auto schema{sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\")};\n///\n/// sourcemeta::jsonbinpack::canonicalize(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver);\n///\n/// sourcemeta::core::prettify(schema, std::cout);\n/// std::cout << std::endl;\n/// ```\nSOURCEMETA_JSONBINPACK_COMPILER_EXPORT\nauto canonicalize(sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaWalker &walker,\n                  const sourcemeta::core::SchemaResolver &resolver,\n                  std::string_view default_dialect = \"\") -> void;\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/compiler/mapper/enum_8_bit.h",
    "content": "// TODO: Unit test this mapping once we have container encodings\nclass Enum8Bit final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  Enum8Bit() : sourcemeta::blaze::SchemaTransformRule{\"enum_8_bit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"enum\") &&\n           schema.at(\"enum\").is_array() && !location.pointer.empty() &&\n           schema.at(\"enum\").size() > 1 &&\n           sourcemeta::core::is_byte(schema.at(\"enum\").size() - 1);\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"choices\", schema.at(\"enum\"));\n    make_encoding(schema, \"BYTE_CHOICE_INDEX\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/enum_8_bit_top_level.h",
    "content": "class Enum8BitTopLevel final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  Enum8BitTopLevel()\n      : sourcemeta::blaze::SchemaTransformRule{\"enum_8_bit_top_level\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"enum\") &&\n           schema.at(\"enum\").is_array() && location.pointer.empty() &&\n           schema.at(\"enum\").size() > 1 &&\n           sourcemeta::core::is_byte(schema.at(\"enum\").size() - 1);\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"choices\", schema.at(\"enum\"));\n    make_encoding(schema, \"TOP_LEVEL_BYTE_CHOICE_INDEX\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/enum_arbitrary.h",
    "content": "// TODO: Unit test this mapping once we have container encodings\nclass EnumArbitrary final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumArbitrary()\n      : sourcemeta::blaze::SchemaTransformRule{\"enum_arbitrary\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"enum\") &&\n           schema.at(\"enum\").is_array() && !location.pointer.empty() &&\n           schema.at(\"enum\").size() > 1 &&\n           !sourcemeta::core::is_byte(schema.at(\"enum\").size() - 1);\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"choices\", schema.at(\"enum\"));\n    make_encoding(schema, \"LARGE_CHOICE_INDEX\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/enum_singleton.h",
    "content": "class EnumSingleton final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumSingleton()\n      : sourcemeta::blaze::SchemaTransformRule{\"enum_singleton\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"enum\") &&\n           schema.at(\"enum\").is_array() && schema.at(\"enum\").size() == 1;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"value\", schema.at(\"enum\").at(0));\n    make_encoding(schema, \"CONST_NONE\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_bounded_8_bit.h",
    "content": "class IntegerBounded8Bit final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerBounded8Bit()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_bounded_8_bit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"minimum\") && schema.defines(\"maximum\") &&\n           sourcemeta::core::is_byte(schema.at(\"maximum\").to_integer() -\n                                     schema.at(\"minimum\").to_integer()) &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto maximum = schema.at(\"maximum\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"maximum\", std::move(maximum));\n    options.assign(\"multiplier\", sourcemeta::core::JSON{1});\n    make_encoding(schema, \"BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_bounded_greater_than_8_bit.h",
    "content": "class IntegerBoundedGreaterThan8Bit final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerBoundedGreaterThan8Bit()\n      : sourcemeta::blaze::SchemaTransformRule{\n            \"integer_bounded_greater_than_8_bit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"minimum\") && schema.defines(\"maximum\") &&\n           !sourcemeta::core::is_byte(schema.at(\"maximum\").to_integer() -\n                                      schema.at(\"minimum\").to_integer()) &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"multiplier\", sourcemeta::core::JSON{1});\n    make_encoding(schema, \"FLOOR_MULTIPLE_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_bounded_multiplier_8_bit.h",
    "content": "class IntegerBoundedMultiplier8Bit final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerBoundedMultiplier8Bit()\n      : sourcemeta::blaze::SchemaTransformRule{\n            \"integer_bounded_multiplier_8_bit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    if (location.dialect != \"https://json-schema.org/draft/2020-12/schema\" ||\n        !vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                   JSON_Schema_2020_12_Validation) ||\n        !schema.is_object() || !schema.defines(\"type\") ||\n        schema.at(\"type\").to_string() != \"integer\" ||\n        !schema.defines(\"minimum\") || !schema.at(\"minimum\").is_integer() ||\n        !schema.defines(\"maximum\") || !schema.at(\"maximum\").is_integer() ||\n        !schema.defines(\"multipleOf\") ||\n        !schema.at(\"multipleOf\").is_integer()) {\n      return false;\n    }\n\n    return sourcemeta::core::is_byte(sourcemeta::core::count_multiples(\n        schema.at(\"minimum\").to_integer(), schema.at(\"maximum\").to_integer(),\n        schema.at(\"multipleOf\").to_integer()));\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto maximum = schema.at(\"maximum\");\n    auto multiplier = schema.at(\"multipleOf\");\n\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"maximum\", std::move(maximum));\n    options.assign(\"multiplier\", std::move(multiplier));\n    make_encoding(schema, \"BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_bounded_multiplier_greater_than_8_bit.h",
    "content": "class IntegerBoundedMultiplierGreaterThan8Bit final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerBoundedMultiplierGreaterThan8Bit()\n      : sourcemeta::blaze::SchemaTransformRule{\n            \"integer_bounded_multiplier_greater_than_8_bit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    if (location.dialect != \"https://json-schema.org/draft/2020-12/schema\" ||\n        !vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                   JSON_Schema_2020_12_Validation) ||\n        !schema.is_object() || !schema.defines(\"type\") ||\n        schema.at(\"type\").to_string() != \"integer\" ||\n        !schema.defines(\"minimum\") || !schema.at(\"minimum\").is_integer() ||\n        !schema.defines(\"maximum\") || !schema.at(\"maximum\").is_integer() ||\n        !schema.defines(\"multipleOf\") ||\n        !schema.at(\"multipleOf\").is_integer()) {\n      return false;\n    }\n\n    return !sourcemeta::core::is_byte(sourcemeta::core::count_multiples(\n        schema.at(\"minimum\").to_integer(), schema.at(\"maximum\").to_integer(),\n        schema.at(\"multipleOf\").to_integer()));\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto multiplier = schema.at(\"multipleOf\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"multiplier\", std::move(multiplier));\n    make_encoding(schema, \"FLOOR_MULTIPLE_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_lower_bound.h",
    "content": "class IntegerLowerBound final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerLowerBound()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_lower_bound\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"minimum\") && !schema.defines(\"maximum\") &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"multiplier\", sourcemeta::core::JSON{1});\n    make_encoding(schema, \"FLOOR_MULTIPLE_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_lower_bound_multiplier.h",
    "content": "class IntegerLowerBoundMultiplier final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerLowerBoundMultiplier()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_lower_bound_multiplier\",\n                                               \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"minimum\") && !schema.defines(\"maximum\") &&\n           schema.defines(\"multipleOf\") && schema.at(\"multipleOf\").is_integer();\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto minimum = schema.at(\"minimum\");\n    auto multiplier = schema.at(\"multipleOf\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"minimum\", std::move(minimum));\n    options.assign(\"multiplier\", std::move(multiplier));\n    make_encoding(schema, \"FLOOR_MULTIPLE_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_unbound.h",
    "content": "class IntegerUnbound final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerUnbound()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_unbound\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           !schema.defines(\"minimum\") && !schema.defines(\"maximum\") &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"multiplier\", sourcemeta::core::JSON{1});\n    make_encoding(schema, \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_unbound_multiplier.h",
    "content": "class IntegerUnboundMultiplier final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerUnboundMultiplier()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_unbound_multiplier\",\n                                               \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           !schema.defines(\"minimum\") && !schema.defines(\"maximum\") &&\n           schema.defines(\"multipleOf\") && schema.at(\"multipleOf\").is_integer();\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto multiplier = schema.at(\"multipleOf\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"multiplier\", std::move(multiplier));\n    make_encoding(schema, \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_upper_bound.h",
    "content": "class IntegerUpperBound final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerUpperBound()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_upper_bound\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           !schema.defines(\"minimum\") && schema.defines(\"maximum\") &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto maximum = schema.at(\"maximum\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"maximum\", std::move(maximum));\n    options.assign(\"multiplier\", sourcemeta::core::JSON{1});\n    make_encoding(schema, \"ROOF_MULTIPLE_MIRROR_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/integer_upper_bound_multiplier.h",
    "content": "class IntegerUpperBoundMultiplier final\n    : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IntegerUpperBoundMultiplier()\n      : sourcemeta::blaze::SchemaTransformRule{\"integer_upper_bound_multiplier\",\n                                               \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           !schema.defines(\"minimum\") && schema.defines(\"maximum\") &&\n           schema.defines(\"multipleOf\") && schema.at(\"multipleOf\").is_integer();\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    auto maximum = schema.at(\"maximum\");\n    auto multiplier = schema.at(\"multipleOf\");\n    auto options = sourcemeta::core::JSON::make_object();\n    options.assign(\"maximum\", std::move(maximum));\n    options.assign(\"multiplier\", std::move(multiplier));\n    make_encoding(schema, \"ROOF_MULTIPLE_MIRROR_ENUM_VARINT\", options);\n  }\n};\n"
  },
  {
    "path": "src/compiler/mapper/number_arbitrary.h",
    "content": "class NumberArbitrary final : public sourcemeta::blaze::SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NumberArbitrary()\n      : sourcemeta::blaze::SchemaTransformRule{\"number_arbitrary\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> sourcemeta::blaze::SchemaTransformRule::Result override {\n    return location.dialect == \"https://json-schema.org/draft/2020-12/schema\" &&\n           vocabularies.contains(sourcemeta::core::Vocabularies::Known::\n                                     JSON_Schema_2020_12_Validation) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").to_string() == \"number\";\n  }\n\n  auto transform(sourcemeta::core::JSON &schema,\n                 const sourcemeta::blaze::SchemaTransformRule::Result &) const\n      -> void override {\n    make_encoding(schema, \"DOUBLE_VARINT_TUPLE\",\n                  sourcemeta::core::JSON::make_object());\n  }\n};\n"
  },
  {
    "path": "src/runtime/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT jsonbinpack NAME runtime\n  FOLDER \"JSON BinPack/Runtime\"\n  PRIVATE_HEADERS\n    decoder.h\n    encoder.h\n    input_stream.h\n    output_stream.h\n    encoder_cache.h\n    encoding.h\n  SOURCES\n    input_stream.cc\n    output_stream.cc\n    unreachable.h\n    cache.cc\n\n    loader.cc\n    loader_v1_any.h\n    loader_v1_array.h\n    loader_v1_integer.h\n    loader_v1_number.h\n    loader_v1_string.h\n\n    decoder_any.cc\n    decoder_array.cc\n    decoder_common.cc\n    decoder_integer.cc\n    decoder_number.cc\n    decoder_object.cc\n    decoder_string.cc\n    encoder_any.cc\n    encoder_array.cc\n    encoder_common.cc\n    encoder_integer.cc\n    encoder_number.cc\n    encoder_object.cc\n    encoder_string.cc)\n\nif(JSONBINPACK_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT jsonbinpack NAME runtime)\nendif()\n\ntarget_link_libraries(sourcemeta_jsonbinpack_runtime PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_jsonbinpack_runtime PUBLIC\n  sourcemeta::core::numeric)\ntarget_link_libraries(sourcemeta_jsonbinpack_runtime PUBLIC\n  sourcemeta::core::io)\n"
  },
  {
    "path": "src/runtime/cache.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder_cache.h>\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Cache::record(const sourcemeta::core::JSON::String &value,\n                   const std::uint64_t offset, const Type type) -> void {\n  // Encoding a shared string has some overhead, such as the\n  // shared string marker + the offset, so its not worth\n  // doing for strings that are too small.\n  constexpr auto MINIMUM_STRING_LENGTH{3};\n\n  // We don't want to allow the context to grow\n  // forever, otherwise an attacker could force the\n  // program to exhaust memory given an input\n  // document that contains a high number of large strings.\n  constexpr auto MAXIMUM_BYTE_SIZE{20971520};\n\n  const auto value_size{value.size()};\n  if (value_size < MINIMUM_STRING_LENGTH || value_size >= MAXIMUM_BYTE_SIZE) {\n    return;\n  }\n\n  // Remove the oldest entries to make space if needed\n  while (!this->data.empty() &&\n         this->byte_size + value_size >= MAXIMUM_BYTE_SIZE) {\n    this->remove_oldest();\n  }\n\n  auto result{this->data.insert({std::make_pair(value, type), offset})};\n  if (result.second) {\n    this->byte_size += value_size;\n    this->order.emplace(offset, result.first->first);\n  } else if (offset > result.first->second) {\n    this->order.erase(result.first->second);\n    // If the string already exists, we want to\n    // bump the offset for locality purposes.\n    result.first->second = offset;\n    this->order.emplace(offset, result.first->first);\n  }\n\n  // Otherwise we are doing something wrong\n  assert(this->order.size() == this->data.size());\n}\n\nauto Cache::remove_oldest() -> void {\n  assert(!this->data.empty());\n  // std::map are by definition ordered by key,\n  // so the begin iterator points to the entry\n  // with the lowest offset, a.k.a. the oldest.\n  const auto iterator{this->order.cbegin()};\n  this->byte_size -= iterator->second.get().first.size();\n  this->data.erase(iterator->second.get());\n  this->order.erase(iterator);\n}\n\nauto Cache::find(const sourcemeta::core::JSON::String &value,\n                 const Type type) const -> std::optional<std::uint64_t> {\n  const auto result{this->data.find(std::make_pair(value, type))};\n  if (result == this->data.cend()) {\n    return std::nullopt;\n  }\n\n  return result->second;\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_any.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include \"unreachable.h\"\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint16_t, std::uint64_t\n#include <memory>  // std::make_shared\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::BYTE_CHOICE_INDEX(const struct BYTE_CHOICE_INDEX &options)\n    -> sourcemeta::core::JSON {\n  assert(!options.choices.empty());\n  assert(sourcemeta::core::is_byte(options.choices.size()));\n  const std::uint8_t index{this->get_byte()};\n  assert(options.choices.size() > index);\n  return options.choices[index];\n}\n\nauto Decoder::LARGE_CHOICE_INDEX(const struct LARGE_CHOICE_INDEX &options)\n    -> sourcemeta::core::JSON {\n  assert(!options.choices.empty());\n  const std::uint64_t index{this->get_varint()};\n  assert(options.choices.size() > index);\n  return options.choices[index];\n}\n\nauto Decoder::TOP_LEVEL_BYTE_CHOICE_INDEX(\n    const struct TOP_LEVEL_BYTE_CHOICE_INDEX &options)\n    -> sourcemeta::core::JSON {\n  assert(!options.choices.empty());\n  assert(sourcemeta::core::is_byte(options.choices.size()));\n  if (!this->has_more_data()) {\n    return options.choices.front();\n  } else {\n    const std::uint16_t index{static_cast<std::uint16_t>(this->get_byte() + 1)};\n    assert(options.choices.size() > index);\n    return options.choices[index];\n  }\n}\n\nauto Decoder::CONST_NONE(const struct CONST_NONE &options)\n    -> sourcemeta::core::JSON {\n  return options.value;\n}\n\nauto Decoder::ANY_PACKED_TYPE_TAG_BYTE_PREFIX(\n    const struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX &) -> sourcemeta::core::JSON {\n  using namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX;\n  const std::uint8_t byte{this->get_byte()};\n  const std::uint8_t type{\n      static_cast<std::uint8_t>(byte & (0xff >> subtype_size))};\n  const std::uint8_t subtype{static_cast<std::uint8_t>(byte >> type_size)};\n\n  if (type == TYPE_OTHER) {\n    switch (subtype) {\n      case SUBTYPE_NULL:\n        return sourcemeta::core::JSON{nullptr};\n      case SUBTYPE_FALSE:\n        return sourcemeta::core::JSON{false};\n      case SUBTYPE_TRUE:\n        return sourcemeta::core::JSON{true};\n      case SUBTYPE_NUMBER:\n        return this->DOUBLE_VARINT_TUPLE({});\n      case SUBTYPE_POSITIVE_REAL_INTEGER_BYTE:\n        return sourcemeta::core::JSON{static_cast<double>(this->get_byte())};\n      case SUBTYPE_POSITIVE_INTEGER:\n        return sourcemeta::core::JSON{\n            static_cast<std::int64_t>(this->get_varint())};\n      case SUBTYPE_NEGATIVE_INTEGER:\n        return sourcemeta::core::JSON{\n            -static_cast<std::int64_t>(this->get_varint()) - 1};\n      case SUBTYPE_LONG_STRING_BASE_EXPONENT_7:\n        return sourcemeta::core::JSON{\n            this->get_string_utf8(this->get_varint() + 128)};\n      case SUBTYPE_LONG_STRING_BASE_EXPONENT_8:\n        return sourcemeta::core::JSON{\n            this->get_string_utf8(this->get_varint() + 256)};\n      case SUBTYPE_LONG_STRING_BASE_EXPONENT_9:\n        return sourcemeta::core::JSON{\n            this->get_string_utf8(this->get_varint() + 512)};\n      case SUBTYPE_LONG_STRING_BASE_EXPONENT_10:\n        return sourcemeta::core::JSON{\n            this->get_string_utf8(this->get_varint() + 1024)};\n      default:\n        unreachable();\n    }\n  } else {\n    switch (type) {\n      case TYPE_POSITIVE_INTEGER_BYTE:\n        return sourcemeta::core::JSON{subtype > 0 ? subtype - 1\n                                                  : this->get_byte()};\n      case TYPE_NEGATIVE_INTEGER_BYTE:\n        return sourcemeta::core::JSON{\n            subtype > 0 ? static_cast<std::int64_t>(-subtype)\n                        : static_cast<std::int64_t>(-this->get_byte() - 1)};\n      case TYPE_SHARED_STRING: {\n        const auto length = subtype == 0\n                                ? this->get_varint() - 1 +\n                                      static_cast<std::uint64_t>(\n                                          sourcemeta::core::uint_max<5>) *\n                                          2\n                                : subtype - 1;\n        const std::uint64_t position{this->position()};\n        const std::uint64_t current{this->rewind(this->get_varint(), position)};\n        const sourcemeta::core::JSON value{this->get_string_utf8(length)};\n        this->seek(current);\n        return value;\n      };\n      case TYPE_STRING:\n        return subtype == 0\n                   ? this->FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(\n                         {static_cast<std::uint64_t>(\n                              sourcemeta::core::uint_max<5>) *\n                          2})\n                   : sourcemeta::core::JSON{this->get_string_utf8(subtype - 1)};\n      case TYPE_LONG_STRING:\n        return sourcemeta::core::JSON{\n            this->get_string_utf8(subtype + sourcemeta::core::uint_max<5>)};\n      case TYPE_ARRAY:\n        return subtype == 0\n                   ? this->FIXED_TYPED_ARRAY(\n                         {.size = this->get_varint() +\n                                  sourcemeta::core::uint_max<5>,\n                          .encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),\n                          .prefix_encodings = {}})\n                   : this->FIXED_TYPED_ARRAY(\n                         {.size = static_cast<std::uint64_t>(subtype - 1),\n                          .encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}),\n                          .prefix_encodings = {}});\n      case TYPE_OBJECT:\n        return subtype == 0\n                   ? this->FIXED_TYPED_ARBITRARY_OBJECT(\n                         {.size = this->get_varint() +\n                                  sourcemeta::core::uint_max<5>,\n                          .key_encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  PREFIX_VARINT_LENGTH_STRING_SHARED{}),\n                          .encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})})\n                   : this->FIXED_TYPED_ARBITRARY_OBJECT(\n                         {.size = static_cast<std::uint64_t>(subtype - 1),\n                          .key_encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  PREFIX_VARINT_LENGTH_STRING_SHARED{}),\n                          .encoding = std::make_shared<Encoding>(\n                              sourcemeta::jsonbinpack::\n                                  ANY_PACKED_TYPE_TAG_BYTE_PREFIX{})});\n      default:\n        unreachable();\n    }\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_array.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint64_t\n#include <utility> // std::move\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::FIXED_TYPED_ARRAY(const struct FIXED_TYPED_ARRAY &options)\n    -> sourcemeta::core::JSON {\n  const auto prefix_encodings{options.prefix_encodings.size()};\n  sourcemeta::core::JSON result = sourcemeta::core::JSON::make_array();\n  for (std::size_t index = 0; index < options.size; index++) {\n    const Encoding &encoding{prefix_encodings > index\n                                 ? options.prefix_encodings[index]\n                                 : *(options.encoding)};\n    result.push_back(this->read(encoding));\n  }\n\n  assert(result.size() == options.size);\n  return result;\n};\n\nauto Decoder::BOUNDED_8BITS_TYPED_ARRAY(\n    const struct BOUNDED_8BITS_TYPED_ARRAY &options) -> sourcemeta::core::JSON {\n  assert(options.maximum >= options.minimum);\n  assert(sourcemeta::core::is_byte(options.maximum - options.minimum));\n  const std::uint8_t byte{this->get_byte()};\n  const std::uint64_t size{byte + options.minimum};\n  assert(sourcemeta::core::is_within(size, options.minimum, options.maximum));\n  return this->FIXED_TYPED_ARRAY(\n      {.size = size,\n       .encoding = options.encoding,\n       .prefix_encodings = options.prefix_encodings});\n};\n\nauto Decoder::FLOOR_TYPED_ARRAY(const struct FLOOR_TYPED_ARRAY &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t value{this->get_varint()};\n  const std::uint64_t size{value + options.minimum};\n  assert(size >= value);\n  assert(size >= options.minimum);\n  return this->FIXED_TYPED_ARRAY(\n      {.size = size,\n       .encoding = options.encoding,\n       .prefix_encodings = options.prefix_encodings});\n};\n\nauto Decoder::ROOF_TYPED_ARRAY(const struct ROOF_TYPED_ARRAY &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t value{this->get_varint()};\n  const std::uint64_t size{options.maximum - value};\n  assert(size <= options.maximum);\n  return this->FIXED_TYPED_ARRAY(\n      {.size = size,\n       .encoding = options.encoding,\n       .prefix_encodings = options.prefix_encodings});\n};\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_common.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include \"unreachable.h\"\n\n#include <cassert> // assert\n#include <variant> // std::get\n\nnamespace sourcemeta::jsonbinpack {\n\nDecoder::Decoder(Stream &input) : InputStream{input} {}\n\nauto Decoder::read(const Encoding &encoding) -> sourcemeta::core::JSON {\n  switch (encoding.index()) {\n#define HANDLE_DECODING(index, name)                                           \\\n  case (index):                                                                \\\n    return this->name(std::get<sourcemeta::jsonbinpack::name>(encoding));\n    HANDLE_DECODING(0, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED)\n    HANDLE_DECODING(1, FLOOR_MULTIPLE_ENUM_VARINT)\n    HANDLE_DECODING(2, ROOF_MULTIPLE_MIRROR_ENUM_VARINT)\n    HANDLE_DECODING(3, ARBITRARY_MULTIPLE_ZIGZAG_VARINT)\n    HANDLE_DECODING(4, DOUBLE_VARINT_TUPLE)\n    HANDLE_DECODING(5, BYTE_CHOICE_INDEX)\n    HANDLE_DECODING(6, LARGE_CHOICE_INDEX)\n    HANDLE_DECODING(7, TOP_LEVEL_BYTE_CHOICE_INDEX)\n    HANDLE_DECODING(8, CONST_NONE)\n    HANDLE_DECODING(9, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)\n    HANDLE_DECODING(10, UTF8_STRING_NO_LENGTH)\n    HANDLE_DECODING(11, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_DECODING(12, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_DECODING(13, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_DECODING(14, RFC3339_DATE_INTEGER_TRIPLET)\n    HANDLE_DECODING(15, PREFIX_VARINT_LENGTH_STRING_SHARED)\n    HANDLE_DECODING(16, FIXED_TYPED_ARRAY)\n    HANDLE_DECODING(17, BOUNDED_8BITS_TYPED_ARRAY)\n    HANDLE_DECODING(18, FLOOR_TYPED_ARRAY)\n    HANDLE_DECODING(19, ROOF_TYPED_ARRAY)\n    HANDLE_DECODING(20, FIXED_TYPED_ARBITRARY_OBJECT)\n    HANDLE_DECODING(21, VARINT_TYPED_ARBITRARY_OBJECT)\n#undef HANDLE_DECODING\n    default:\n      // We should never get here. If so, it is definitely a bug\n      unreachable();\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_integer.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint32_t, std::int64_t, std::uint64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(\n    const struct BOUNDED_MULTIPLE_8BITS_ENUM_FIXED &options)\n    -> sourcemeta::core::JSON {\n  assert(options.multiplier > 0);\n  const std::uint8_t byte{this->get_byte()};\n  const std::int64_t closest_minimum{\n      sourcemeta::core::divide_ceil(options.minimum, options.multiplier)};\n  if (closest_minimum >= 0) {\n    const std::uint64_t closest_minimum_multiple{\n        static_cast<std::uint32_t>(closest_minimum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        (byte * options.multiplier) + closest_minimum_multiple)};\n  } else {\n    const std::uint64_t closest_minimum_multiple{\n        sourcemeta::core::abs(closest_minimum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        (byte * options.multiplier) - closest_minimum_multiple)};\n  }\n}\n\nauto Decoder::FLOOR_MULTIPLE_ENUM_VARINT(\n    const struct FLOOR_MULTIPLE_ENUM_VARINT &options)\n    -> sourcemeta::core::JSON {\n  assert(options.multiplier > 0);\n  const std::int64_t closest_minimum{\n      sourcemeta::core::divide_ceil(options.minimum, options.multiplier)};\n  if (closest_minimum >= 0) {\n    const std::uint64_t closest_minimum_multiple{\n        static_cast<std::uint32_t>(closest_minimum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        (this->get_varint() * options.multiplier) + closest_minimum_multiple)};\n  } else {\n    const std::uint64_t closest_minimum_multiple{\n        sourcemeta::core::abs(closest_minimum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        (this->get_varint() * options.multiplier) - closest_minimum_multiple)};\n  }\n}\n\nauto Decoder::ROOF_MULTIPLE_MIRROR_ENUM_VARINT(\n    const struct ROOF_MULTIPLE_MIRROR_ENUM_VARINT &options)\n    -> sourcemeta::core::JSON {\n  assert(options.multiplier > 0);\n  const std::int64_t closest_maximum{\n      sourcemeta::core::divide_floor(options.maximum, options.multiplier)};\n  if (closest_maximum >= 0) {\n    const std::uint64_t closest_maximum_multiple{\n        static_cast<std::uint32_t>(closest_maximum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        -(static_cast<std::int64_t>(this->get_varint() * options.multiplier)) +\n        static_cast<std::int64_t>(closest_maximum_multiple))};\n  } else {\n    const std::uint64_t closest_maximum_multiple{\n        sourcemeta::core::abs(closest_maximum) * options.multiplier};\n    // We trust the encoder that the data we are seeing\n    // corresponds to a valid 64-bit signed integer.\n    return sourcemeta::core::JSON{static_cast<std::int64_t>(\n        -(static_cast<std::int64_t>(this->get_varint() * options.multiplier)) -\n        static_cast<std::int64_t>(closest_maximum_multiple))};\n  }\n}\n\nauto Decoder::ARBITRARY_MULTIPLE_ZIGZAG_VARINT(\n    const struct ARBITRARY_MULTIPLE_ZIGZAG_VARINT &options)\n    -> sourcemeta::core::JSON {\n  assert(options.multiplier > 0);\n  // We trust the encoder that the data we are seeing\n  // corresponds to a valid 64-bit signed integer.\n  return sourcemeta::core::JSON{\n      static_cast<std::int64_t>(this->get_varint_zigzag() *\n                                static_cast<std::int64_t>(options.multiplier))};\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_number.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <cstdint> // std::int64_t, std::uint64_t\n\n#if defined(__GNUC__) && !defined(__clang__)\n#pragma GCC optimize(\"no-reciprocal-math\")\n#endif\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::DOUBLE_VARINT_TUPLE(const struct DOUBLE_VARINT_TUPLE &)\n    -> sourcemeta::core::JSON {\n#ifdef __clang__\n#pragma clang fp reciprocal(off)\n#endif\n  const std::int64_t digits{this->get_varint_zigzag()};\n  const std::uint64_t point{this->get_varint()};\n  double divisor{1.0};\n  for (std::uint64_t i = 0; i < point; ++i) {\n    divisor *= 10.0;\n  }\n  return sourcemeta::core::JSON{static_cast<double>(digits) / divisor};\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_object.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::FIXED_TYPED_ARBITRARY_OBJECT(\n    const struct FIXED_TYPED_ARBITRARY_OBJECT &options)\n    -> sourcemeta::core::JSON {\n  sourcemeta::core::JSON document = sourcemeta::core::JSON::make_object();\n  for (std::size_t index = 0; index < options.size; index++) {\n    const sourcemeta::core::JSON key = this->read(*(options.key_encoding));\n    assert(key.is_string());\n    document.assign(key.to_string(), this->read(*(options.encoding)));\n  }\n\n  assert(document.size() == options.size);\n  return document;\n};\n\nauto Decoder::VARINT_TYPED_ARBITRARY_OBJECT(\n    const struct VARINT_TYPED_ARBITRARY_OBJECT &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t size{this->get_varint()};\n  sourcemeta::core::JSON document = sourcemeta::core::JSON::make_object();\n  for (std::size_t index = 0; index < size; index++) {\n    const sourcemeta::core::JSON key = this->read(*(options.key_encoding));\n    assert(key.is_string());\n    document.assign(key.to_string(), this->read(*(options.encoding)));\n  }\n\n  assert(document.size() == size);\n  return document;\n};\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/decoder_string.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint16_t, std::uint64_t\n#include <iomanip> // std::setw, std::setfill\n#include <sstream> // std::basic_ostringstream\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Decoder::UTF8_STRING_NO_LENGTH(const struct UTF8_STRING_NO_LENGTH &options)\n    -> sourcemeta::core::JSON {\n  return sourcemeta::core::JSON{this->get_string_utf8(options.size)};\n}\n\nauto Decoder::FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const struct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t prefix{this->get_varint()};\n  const bool is_shared{prefix == 0};\n  const std::uint64_t length{(is_shared ? this->get_varint() : prefix) +\n                             options.minimum - 1};\n  assert(length >= options.minimum);\n\n  if (is_shared) {\n    const std::uint64_t position{this->position()};\n    const std::uint64_t current{this->rewind(this->get_varint(), position)};\n    const sourcemeta::core::JSON value{this->get_string_utf8(length)};\n    this->seek(current);\n    return value;\n  } else {\n    return UTF8_STRING_NO_LENGTH({length});\n  }\n}\n\nauto Decoder::ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const struct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t prefix{this->get_varint()};\n  const bool is_shared{prefix == 0};\n  const std::uint64_t length{options.maximum -\n                             (is_shared ? this->get_varint() : prefix) + 1};\n  assert(length <= options.maximum);\n\n  if (is_shared) {\n    const std::uint64_t position{this->position()};\n    const std::uint64_t current{this->rewind(this->get_varint(), position)};\n    const sourcemeta::core::JSON value{UTF8_STRING_NO_LENGTH({length})};\n    this->seek(current);\n    return value;\n  } else {\n    return UTF8_STRING_NO_LENGTH({length});\n  }\n}\n\nauto Decoder::BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(\n    const struct BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED &options)\n    -> sourcemeta::core::JSON {\n  assert(options.minimum <= options.maximum);\n  assert(sourcemeta::core::is_byte(options.maximum - options.minimum));\n  const std::uint8_t prefix{this->get_byte()};\n  const bool is_shared{prefix == 0};\n  const std::uint64_t length{(is_shared ? this->get_byte() : prefix) +\n                             options.minimum - 1};\n  assert(sourcemeta::core::is_within(length, options.minimum, options.maximum));\n\n  if (is_shared) {\n    const std::uint64_t position{this->position()};\n    const std::uint64_t current{this->rewind(this->get_varint(), position)};\n    const sourcemeta::core::JSON value{UTF8_STRING_NO_LENGTH({length})};\n    this->seek(current);\n    return value;\n  } else {\n    return UTF8_STRING_NO_LENGTH({length});\n  }\n}\n\nauto Decoder::RFC3339_DATE_INTEGER_TRIPLET(\n    const struct RFC3339_DATE_INTEGER_TRIPLET &) -> sourcemeta::core::JSON {\n  const std::uint16_t year{this->get_word()};\n  const std::uint8_t month{this->get_byte()};\n  const std::uint8_t day{this->get_byte()};\n\n  assert(year <= 9999);\n  assert(month >= 1 && month <= 12);\n  assert(day >= 1 && day <= 31);\n\n  std::basic_ostringstream<sourcemeta::core::JSON::Char,\n                           sourcemeta::core::JSON::CharTraits>\n      output;\n  output << std::setfill('0');\n  output << std::setw(4) << year;\n  output << \"-\";\n  // Cast the bytes to a larger integer, otherwise\n  // they will be interpreted as characters.\n  output << std::setw(2) << static_cast<std::uint16_t>(month);\n  output << \"-\";\n  output << std::setw(2) << static_cast<std::uint16_t>(day);\n\n  return sourcemeta::core::JSON{output.str()};\n}\n\nauto Decoder::PREFIX_VARINT_LENGTH_STRING_SHARED(\n    const struct PREFIX_VARINT_LENGTH_STRING_SHARED &options)\n    -> sourcemeta::core::JSON {\n  const std::uint64_t prefix{this->get_varint()};\n  if (prefix == 0) {\n    const std::uint64_t position{this->position()};\n    const std::uint64_t current{this->rewind(this->get_varint(), position)};\n    const sourcemeta::core::JSON value{\n        PREFIX_VARINT_LENGTH_STRING_SHARED(options)};\n    this->seek(current);\n    return value;\n  } else {\n    return sourcemeta::core::JSON{this->get_string_utf8(prefix - 1)};\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_any.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include \"unreachable.h\"\n\n#include <algorithm> // std::find_if\n#include <cassert>   // assert\n#include <cstdint>   // std::uint8_t, std::int64_t, std::uint64_t\n#include <iterator>  // std::cbegin, std::cend, std::distance\n#include <memory>    // std::make_shared\n#include <ranges>    // std::ranges\n#include <utility>   // std::move\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::BYTE_CHOICE_INDEX(const sourcemeta::core::JSON &document,\n                                const struct BYTE_CHOICE_INDEX &options)\n    -> void {\n  assert(!options.choices.empty());\n  assert(sourcemeta::core::is_byte(options.choices.size()));\n  const auto iterator{std::ranges::find(options.choices, document)};\n  assert(iterator != std::cend(options.choices));\n  const auto cursor{std::distance(std::cbegin(options.choices), iterator)};\n  assert(sourcemeta::core::is_within(\n      cursor, 0, static_cast<std::int64_t>(options.choices.size())));\n  this->put_byte(static_cast<std::uint8_t>(cursor));\n}\n\nauto Encoder::LARGE_CHOICE_INDEX(const sourcemeta::core::JSON &document,\n                                 const struct LARGE_CHOICE_INDEX &options)\n    -> void {\n  assert(options.choices.size() > 0);\n  const auto iterator{\n      std::ranges::find_if(options.choices, [&document](const auto &choice) {\n        return choice == document;\n      })};\n  assert(iterator != std::cend(options.choices));\n  const auto cursor{std::distance(std::cbegin(options.choices), iterator)};\n  assert(sourcemeta::core::is_within(cursor, static_cast<std::uint64_t>(0),\n                                     options.choices.size() - 1));\n  this->put_varint(static_cast<std::uint64_t>(cursor));\n}\n\nauto Encoder::TOP_LEVEL_BYTE_CHOICE_INDEX(\n    const sourcemeta::core::JSON &document,\n    const struct TOP_LEVEL_BYTE_CHOICE_INDEX &options) -> void {\n  assert(options.choices.size() > 0);\n  assert(sourcemeta::core::is_byte(options.choices.size()));\n  const auto iterator{\n      std::ranges::find_if(options.choices, [&document](auto const &choice) {\n        return choice == document;\n      })};\n  assert(iterator != std::cend(options.choices));\n  const auto cursor{std::distance(std::cbegin(options.choices), iterator)};\n  assert(sourcemeta::core::is_within(\n      cursor, 0, static_cast<std::int64_t>(options.choices.size()) - 1));\n  // This encoding encodes the first option of the enum as \"no data\"\n  if (cursor > 0) {\n    this->put_byte(static_cast<std::uint8_t>(cursor - 1));\n  }\n}\n\nauto Encoder::CONST_NONE(\n#ifndef NDEBUG\n    const sourcemeta::core::JSON &document, const struct CONST_NONE &options)\n#else\n    const sourcemeta::core::JSON &, const struct CONST_NONE &)\n#endif\n    -> void {\n  assert(document == options.value);\n}\n\nauto Encoder::ANY_PACKED_TYPE_TAG_BYTE_PREFIX(\n    const sourcemeta::core::JSON &document,\n    const struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX &) -> void {\n  using namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX;\n  if (document.is_null()) {\n    this->put_byte(TYPE_OTHER | (SUBTYPE_NULL << type_size));\n  } else if (document.is_boolean()) {\n    const std::uint8_t subtype{document.to_boolean() ? SUBTYPE_TRUE\n                                                     : SUBTYPE_FALSE};\n    this->put_byte(TYPE_OTHER |\n                   static_cast<std::uint8_t>(subtype << type_size));\n  } else if (document.is_real() && document.is_integral()) {\n    const auto value{document.as_integer()};\n    if (value >= 0 && sourcemeta::core::is_byte(value)) {\n      this->put_byte(TYPE_OTHER | SUBTYPE_POSITIVE_REAL_INTEGER_BYTE\n                                      << type_size);\n      this->put_byte(static_cast<std::uint8_t>(value));\n    } else {\n      this->put_byte(TYPE_OTHER | SUBTYPE_NUMBER << type_size);\n      this->DOUBLE_VARINT_TUPLE(document, {});\n    }\n  } else if (document.is_real()) {\n    this->put_byte(TYPE_OTHER | SUBTYPE_NUMBER << type_size);\n    this->DOUBLE_VARINT_TUPLE(document, {});\n  } else if (document.is_integer()) {\n    const std::int64_t value{document.to_integer()};\n    const bool is_positive{value >= 0};\n    const std::uint64_t absolute{is_positive\n                                     ? static_cast<std::uint64_t>(value)\n                                     : sourcemeta::core::abs(value) - 1};\n    if (sourcemeta::core::is_byte(absolute)) {\n      const std::uint8_t type{is_positive ? TYPE_POSITIVE_INTEGER_BYTE\n                                          : TYPE_NEGATIVE_INTEGER_BYTE};\n      const std::uint8_t absolute_byte{static_cast<std::uint8_t>(absolute)};\n      if (absolute < sourcemeta::core::uint_max<5>) {\n        this->put_byte(\n            type | static_cast<std::uint8_t>((absolute_byte + 1) << type_size));\n      } else {\n        this->put_byte(type);\n        this->put_byte(absolute_byte);\n      }\n    } else {\n      const std::uint8_t subtype{is_positive ? SUBTYPE_POSITIVE_INTEGER\n                                             : SUBTYPE_NEGATIVE_INTEGER};\n      this->put_byte(TYPE_OTHER |\n                     static_cast<std::uint8_t>(subtype << type_size));\n      this->put_varint(absolute);\n    }\n  } else if (document.is_string()) {\n    const sourcemeta::core::JSON::String &value{document.to_string()};\n    const auto size{document.byte_size()};\n    const auto shared{this->cache_.find(value, Cache::Type::Standalone)};\n    if (size < sourcemeta::core::uint_max<5>) {\n      const std::uint8_t type{shared.has_value() ? TYPE_SHARED_STRING\n                                                 : TYPE_STRING};\n      this->put_byte(\n          static_cast<std::uint8_t>(type | ((size + 1) << type_size)));\n      if (shared.has_value()) {\n        this->put_varint(this->position() - shared.value());\n      } else {\n        this->cache_.record(value, this->position(), Cache::Type::Standalone);\n        this->put_string_utf8(value, size);\n      }\n    } else if (size >= sourcemeta::core::uint_max<5> &&\n               size <\n                   static_cast<std::uint64_t>(sourcemeta::core::uint_max<5>) *\n                       2 &&\n               !shared.has_value()) {\n      this->put_byte(static_cast<std::uint8_t>(\n          TYPE_LONG_STRING |\n          ((size - sourcemeta::core::uint_max<5>) << type_size)));\n      this->put_string_utf8(value, size);\n    } else if (size >= 2 << (SUBTYPE_LONG_STRING_BASE_EXPONENT_7 - 1) &&\n               !shared.has_value()) {\n      const std::uint8_t exponent{sourcemeta::core::closest_smallest_exponent(\n          size, 2, SUBTYPE_LONG_STRING_BASE_EXPONENT_7,\n          SUBTYPE_LONG_STRING_BASE_EXPONENT_10)};\n      this->put_byte(\n          static_cast<std::uint8_t>(TYPE_OTHER | (exponent << type_size)));\n      this->put_varint(size - static_cast<std::uint64_t>(2 << (exponent - 1)));\n      this->put_string_utf8(value, size);\n    } else {\n      // Exploit the fact that a shared string always starts\n      // with an impossible length marker (0) to avoid having\n      // to encode an additional tag\n      if (!shared.has_value()) {\n        this->put_byte(TYPE_STRING);\n      }\n\n      // If we got this far, the string is at least a certain length\n      return FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(\n          document,\n          {static_cast<std::uint64_t>(sourcemeta::core::uint_max<5> * 2)});\n    }\n  } else if (document.is_array()) {\n    const auto size{document.size()};\n    if (size >= sourcemeta::core::uint_max<5>) {\n      this->put_byte(TYPE_ARRAY);\n      this->put_varint(size - sourcemeta::core::uint_max<5>);\n    } else {\n      this->put_byte(\n          static_cast<std::uint8_t>(TYPE_ARRAY | ((size + 1) << type_size)));\n    }\n\n    Encoding encoding{\n        sourcemeta::jsonbinpack::ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}};\n    this->FIXED_TYPED_ARRAY(\n        document, {.size = size,\n                   .encoding = std::make_shared<Encoding>(std::move(encoding)),\n                   .prefix_encodings = {}});\n  } else if (document.is_object()) {\n    const auto size{document.size()};\n    if (size >= sourcemeta::core::uint_max<5>) {\n      this->put_byte(TYPE_OBJECT);\n      this->put_varint(size - sourcemeta::core::uint_max<5>);\n    } else {\n      this->put_byte(\n          static_cast<std::uint8_t>(TYPE_OBJECT | ((size + 1) << type_size)));\n    }\n\n    Encoding key_encoding{\n        sourcemeta::jsonbinpack::PREFIX_VARINT_LENGTH_STRING_SHARED{}};\n    Encoding value_encoding{\n        sourcemeta::jsonbinpack::ANY_PACKED_TYPE_TAG_BYTE_PREFIX{}};\n    this->FIXED_TYPED_ARBITRARY_OBJECT(\n        document,\n        {.size = size,\n         .key_encoding = std::make_shared<Encoding>(std::move(key_encoding)),\n         .encoding = std::make_shared<Encoding>(std::move(value_encoding))});\n  } else {\n    // We should never get here\n    unreachable();\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_array.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t\n#include <utility> // std::move\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::FIXED_TYPED_ARRAY(const sourcemeta::core::JSON &document,\n                                const struct FIXED_TYPED_ARRAY &options)\n    -> void {\n  assert(document.is_array());\n  assert(document.size() == options.size);\n  const auto prefix_encodings{options.prefix_encodings.size()};\n  assert(prefix_encodings <= document.size());\n  for (std::size_t index = 0; index < options.size; index++) {\n    const Encoding &encoding{prefix_encodings > index\n                                 ? options.prefix_encodings[index]\n                                 : *(options.encoding)};\n    this->write(document.at(index), encoding);\n  }\n}\n\nauto Encoder::BOUNDED_8BITS_TYPED_ARRAY(\n    const sourcemeta::core::JSON &document,\n    const struct BOUNDED_8BITS_TYPED_ARRAY &options) -> void {\n  assert(options.maximum >= options.minimum);\n  const auto size{document.size()};\n  assert(sourcemeta::core::is_within(size, options.minimum, options.maximum));\n  assert(sourcemeta::core::is_byte(options.maximum - options.minimum));\n  this->put_byte(static_cast<std::uint8_t>(size - options.minimum));\n  this->FIXED_TYPED_ARRAY(document,\n                          {.size = size,\n                           .encoding = options.encoding,\n                           .prefix_encodings = options.prefix_encodings});\n}\n\nauto Encoder::FLOOR_TYPED_ARRAY(const sourcemeta::core::JSON &document,\n                                const struct FLOOR_TYPED_ARRAY &options)\n    -> void {\n  const auto size{document.size()};\n  assert(size >= options.minimum);\n  this->put_varint(size - options.minimum);\n  this->FIXED_TYPED_ARRAY(document,\n                          {.size = size,\n                           .encoding = options.encoding,\n                           .prefix_encodings = options.prefix_encodings});\n}\n\nauto Encoder::ROOF_TYPED_ARRAY(const sourcemeta::core::JSON &document,\n                               const struct ROOF_TYPED_ARRAY &options) -> void {\n  const auto size{document.size()};\n  assert(size <= options.maximum);\n  this->put_varint(options.maximum - size);\n  this->FIXED_TYPED_ARRAY(document,\n                          {.size = size,\n                           .encoding = options.encoding,\n                           .prefix_encodings = options.prefix_encodings});\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_common.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include \"unreachable.h\"\n\n#include <cassert> // assert\n#include <variant> // std::get\n\nnamespace sourcemeta::jsonbinpack {\n\nEncoder::Encoder(Stream &output) : OutputStream{output} {}\n\nauto Encoder::write(const sourcemeta::core::JSON &document,\n                    const Encoding &encoding) -> void {\n  switch (encoding.index()) {\n#define HANDLE_ENCODING(index, name)                                           \\\n  case (index):                                                                \\\n    return this->name(document,                                                \\\n                      std::get<sourcemeta::jsonbinpack::name>(encoding));\n    HANDLE_ENCODING(0, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED)\n    HANDLE_ENCODING(1, FLOOR_MULTIPLE_ENUM_VARINT)\n    HANDLE_ENCODING(2, ROOF_MULTIPLE_MIRROR_ENUM_VARINT)\n    HANDLE_ENCODING(3, ARBITRARY_MULTIPLE_ZIGZAG_VARINT)\n    HANDLE_ENCODING(4, DOUBLE_VARINT_TUPLE)\n    HANDLE_ENCODING(5, BYTE_CHOICE_INDEX)\n    HANDLE_ENCODING(6, LARGE_CHOICE_INDEX)\n    HANDLE_ENCODING(7, TOP_LEVEL_BYTE_CHOICE_INDEX)\n    HANDLE_ENCODING(8, CONST_NONE)\n    HANDLE_ENCODING(9, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)\n    HANDLE_ENCODING(10, UTF8_STRING_NO_LENGTH)\n    HANDLE_ENCODING(11, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_ENCODING(12, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_ENCODING(13, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)\n    HANDLE_ENCODING(14, RFC3339_DATE_INTEGER_TRIPLET)\n    HANDLE_ENCODING(15, PREFIX_VARINT_LENGTH_STRING_SHARED)\n    HANDLE_ENCODING(16, FIXED_TYPED_ARRAY)\n    HANDLE_ENCODING(17, BOUNDED_8BITS_TYPED_ARRAY)\n    HANDLE_ENCODING(18, FLOOR_TYPED_ARRAY)\n    HANDLE_ENCODING(19, ROOF_TYPED_ARRAY)\n    HANDLE_ENCODING(20, FIXED_TYPED_ARBITRARY_OBJECT)\n    HANDLE_ENCODING(21, VARINT_TYPED_ARBITRARY_OBJECT)\n#undef HANDLE_ENCODING\n    default:\n      // We should never get here. If so, it is definitely a bug\n      unreachable();\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_integer.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::int64_t, std::uint64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(\n    const sourcemeta::core::JSON &document,\n    const struct BOUNDED_MULTIPLE_8BITS_ENUM_FIXED &options) -> void {\n  assert(document.is_integer());\n  const std::int64_t value{document.to_integer()};\n  assert(sourcemeta::core::is_within(value, options.minimum, options.maximum));\n  assert(options.multiplier > 0);\n  assert(sourcemeta::core::abs(value) % options.multiplier == 0);\n  const std::int64_t enum_minimum{\n      sourcemeta::core::divide_ceil(options.minimum, options.multiplier)};\n#ifndef NDEBUG\n  const std::int64_t enum_maximum{\n      sourcemeta::core::divide_floor(options.maximum, options.multiplier)};\n#endif\n  assert(sourcemeta::core::is_byte(enum_maximum - enum_minimum));\n  this->put_byte(static_cast<std::uint8_t>(\n      (value / static_cast<std::int64_t>(options.multiplier)) - enum_minimum));\n}\n\nauto Encoder::FLOOR_MULTIPLE_ENUM_VARINT(\n    const sourcemeta::core::JSON &document,\n    const struct FLOOR_MULTIPLE_ENUM_VARINT &options) -> void {\n  assert(document.is_integer());\n  const std::int64_t value{document.to_integer()};\n  assert(options.minimum <= value);\n  assert(options.multiplier > 0);\n  assert(sourcemeta::core::abs(value) % options.multiplier == 0);\n  if (options.multiplier == 1) {\n    return this->put_varint(\n        static_cast<std::uint64_t>(value - options.minimum));\n  }\n\n  return this->put_varint(\n      (static_cast<std::uint64_t>(value) / options.multiplier) -\n      static_cast<std::uint64_t>(sourcemeta::core::divide_ceil(\n          options.minimum, static_cast<std::uint64_t>(options.multiplier))));\n}\n\nauto Encoder::ROOF_MULTIPLE_MIRROR_ENUM_VARINT(\n    const sourcemeta::core::JSON &document,\n    const struct ROOF_MULTIPLE_MIRROR_ENUM_VARINT &options) -> void {\n  assert(document.is_integer());\n  const std::int64_t value{document.to_integer()};\n  assert(value <= options.maximum);\n  assert(options.multiplier > 0);\n  assert(sourcemeta::core::abs(value) % options.multiplier == 0);\n  if (options.multiplier == 1) {\n    return this->put_varint(\n        static_cast<std::uint64_t>(options.maximum - value));\n  }\n\n  return this->put_varint(\n      static_cast<std::uint64_t>(\n          sourcemeta::core::divide_floor(options.maximum, options.multiplier)) -\n      (static_cast<std::uint64_t>(value) / options.multiplier));\n}\n\nauto Encoder::ARBITRARY_MULTIPLE_ZIGZAG_VARINT(\n    const sourcemeta::core::JSON &document,\n    const struct ARBITRARY_MULTIPLE_ZIGZAG_VARINT &options) -> void {\n  assert(document.is_integer());\n  const std::int64_t value{document.to_integer()};\n  assert(options.multiplier > 0);\n  assert(sourcemeta::core::abs(value) % options.multiplier == 0);\n  this->put_varint_zigzag(value /\n                          static_cast<std::int64_t>(options.multiplier));\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_number.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::DOUBLE_VARINT_TUPLE(const sourcemeta::core::JSON &document,\n                                  const struct DOUBLE_VARINT_TUPLE &) -> void {\n  assert(document.is_real());\n  const auto value{document.to_real()};\n  std::uint64_t point_position;\n  const std::int64_t integral{\n      sourcemeta::core::real_digits<std::int64_t>(value, point_position)};\n  this->put_varint_zigzag(integral);\n  this->put_varint(point_position);\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_object.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <cassert> // assert\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::FIXED_TYPED_ARBITRARY_OBJECT(\n    const sourcemeta::core::JSON &document,\n    const struct FIXED_TYPED_ARBITRARY_OBJECT &options) -> void {\n  assert(document.is_object());\n  assert(document.size() == options.size);\n\n  for (const auto &entry : document.as_object()) {\n    this->write(sourcemeta::core::JSON{entry.first}, *(options.key_encoding));\n    this->write(entry.second, *(options.encoding));\n  }\n}\n\nauto Encoder::VARINT_TYPED_ARBITRARY_OBJECT(\n    const sourcemeta::core::JSON &document,\n    const struct VARINT_TYPED_ARBITRARY_OBJECT &options) -> void {\n  assert(document.is_object());\n  const auto size{document.size()};\n  this->put_varint(size);\n\n  for (const auto &entry : document.as_object()) {\n    this->write(sourcemeta::core::JSON{entry.first}, *(options.key_encoding));\n    this->write(entry.second, *(options.encoding));\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/encoder_string.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint16_t\n#include <string>  // std::stoul\n\nnamespace sourcemeta::jsonbinpack {\n\nauto Encoder::UTF8_STRING_NO_LENGTH(const sourcemeta::core::JSON &document,\n                                    const struct UTF8_STRING_NO_LENGTH &options)\n    -> void {\n  assert(document.is_string());\n  const sourcemeta::core::JSON::String &value{document.to_string()};\n  this->put_string_utf8(value, options.size);\n}\n\nauto Encoder::FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &document,\n    const struct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED &options) -> void {\n  assert(document.is_string());\n  const sourcemeta::core::JSON::String &value{document.to_string()};\n  const auto size{value.size()};\n  assert(document.byte_size() == size);\n  const auto shared{this->cache_.find(value, Cache::Type::Standalone)};\n\n  // (1) Write 0x00 if shared, else do nothing\n  if (shared.has_value()) {\n    this->put_byte(0);\n  }\n\n  // (2) Write length of the string + 1 (so it will never be zero)\n  this->put_varint(size - options.minimum + 1);\n\n  // (3) Write relative offset if shared, else write plain string\n  if (shared.has_value()) {\n    this->put_varint(this->position() - shared.value());\n  } else {\n    this->cache_.record(value, this->position(), Cache::Type::Standalone);\n    this->put_string_utf8(value, size);\n  }\n}\n\nauto Encoder::ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &document,\n    const struct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED &options) -> void {\n  assert(document.is_string());\n  const sourcemeta::core::JSON::String &value{document.to_string()};\n  const auto size{value.size()};\n  assert(document.byte_size() == size);\n  assert(size <= options.maximum);\n  const auto shared{this->cache_.find(value, Cache::Type::Standalone)};\n\n  // (1) Write 0x00 if shared, else do nothing\n  if (shared.has_value()) {\n    this->put_byte(0);\n  }\n\n  // (2) Write length of the string + 1 (so it will never be zero)\n  this->put_varint(options.maximum - size + 1);\n\n  // (3) Write relative offset if shared, else write plain string\n  if (shared.has_value()) {\n    this->put_varint(this->position() - shared.value());\n  } else {\n    this->cache_.record(value, this->position(), Cache::Type::Standalone);\n    this->put_string_utf8(value, size);\n  }\n}\n\nauto Encoder::BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &document,\n    const struct BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED &options) -> void {\n  assert(document.is_string());\n  const sourcemeta::core::JSON::String &value{document.to_string()};\n  const auto size{value.size()};\n  assert(document.byte_size() == size);\n  assert(options.minimum <= options.maximum);\n  assert(sourcemeta::core::is_byte(options.maximum - options.minimum + 1));\n  assert(sourcemeta::core::is_within(size, options.minimum, options.maximum));\n  const auto shared{this->cache_.find(value, Cache::Type::Standalone)};\n\n  // (1) Write 0x00 if shared, else do nothing\n  if (shared.has_value()) {\n    this->put_byte(0);\n  }\n\n  // (2) Write length of the string + 1 (so it will never be zero)\n  this->put_byte(static_cast<std::uint8_t>(size - options.minimum + 1));\n\n  // (3) Write relative offset if shared, else write plain string\n  if (shared.has_value()) {\n    this->put_varint(this->position() - shared.value());\n  } else {\n    this->cache_.record(value, this->position(), Cache::Type::Standalone);\n    this->put_string_utf8(value, size);\n  }\n}\n\nauto Encoder::RFC3339_DATE_INTEGER_TRIPLET(\n    const sourcemeta::core::JSON &document,\n    const struct RFC3339_DATE_INTEGER_TRIPLET &) -> void {\n  assert(document.is_string());\n  const auto &value{document.to_string()};\n  assert(value.size() == 10);\n  assert(document.size() == value.size());\n\n  // As according to RFC3339: Internet Protocols MUST\n  // generate four digit years in dates.\n  const std::uint16_t year{\n      static_cast<std::uint16_t>(std::stoul(value.substr(0, 4)))};\n  const std::uint8_t month{\n      static_cast<std::uint8_t>(std::stoul(value.substr(5, 2)))};\n  const std::uint8_t day{\n      static_cast<std::uint8_t>(std::stoul(value.substr(8, 2)))};\n  assert(month >= 1 && month <= 12);\n  assert(day >= 1 && day <= 31);\n\n  this->put_word(year);\n  this->put_byte(month);\n  this->put_byte(day);\n}\n\nauto Encoder::PREFIX_VARINT_LENGTH_STRING_SHARED(\n    const sourcemeta::core::JSON &document,\n    const struct PREFIX_VARINT_LENGTH_STRING_SHARED &) -> void {\n  assert(document.is_string());\n  const sourcemeta::core::JSON::String &value{document.to_string()};\n\n  const auto shared{\n      this->cache_.find(value, Cache::Type::PrefixLengthVarintPlusOne)};\n  if (shared.has_value()) {\n    const auto new_offset{this->position()};\n    this->put_byte(0);\n    this->put_varint(this->position() - shared.value());\n    // Bump the context cache for locality purposes\n    this->cache_.record(value, new_offset,\n                        Cache::Type::PrefixLengthVarintPlusOne);\n  } else {\n    const auto size{value.size()};\n    assert(document.byte_size() == size);\n    this->cache_.record(value, this->position(),\n                        Cache::Type::PrefixLengthVarintPlusOne);\n    this->put_varint(size + 1);\n    // Also record a standalone variant of it\n    this->cache_.record(value, this->position(), Cache::Type::Standalone);\n    this->put_string_utf8(value, size);\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_H_\n\n/// @defgroup runtime Runtime\n/// @brief The encoder/decoder parts of JSON BinPack\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/jsonbinpack/runtime.h>\n/// ```\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <sourcemeta/jsonbinpack/runtime_decoder.h>\n#include <sourcemeta/jsonbinpack/runtime_encoder.h>\n#include <sourcemeta/jsonbinpack/runtime_encoding.h>\n\n#include <exception> // std::exception\n#include <utility>   // std::move\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup runtime\nSOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\nauto load(const sourcemeta::core::JSON &input) -> Encoding;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup runtime\n/// This class represents an encoding error\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT EncodingError\n    : public std::exception {\npublic:\n  EncodingError(sourcemeta::core::JSON::String message)\n      : message_{std::move(message)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_.c_str();\n  }\n\nprivate:\n  sourcemeta::core::JSON::String message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_decoder.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_DECODER_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_DECODER_H_\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/jsonbinpack/runtime_encoding.h>\n#include <sourcemeta/jsonbinpack/runtime_input_stream.h>\n\n#include <sourcemeta/core/json.h>\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup runtime\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT Decoder : private InputStream {\npublic:\n  Decoder(Stream &input);\n  auto read(const Encoding &encoding) -> sourcemeta::core::JSON;\n\n// The methods that implement individual encodings as considered private\n#ifndef DOXYGEN\n#define DECLARE_ENCODING(name)                                                 \\\n  auto name(const name &) -> sourcemeta::core::JSON;\n\n  // Integer\n  DECLARE_ENCODING(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED)\n  DECLARE_ENCODING(FLOOR_MULTIPLE_ENUM_VARINT)\n  DECLARE_ENCODING(ROOF_MULTIPLE_MIRROR_ENUM_VARINT)\n  DECLARE_ENCODING(ARBITRARY_MULTIPLE_ZIGZAG_VARINT)\n\n  // Number\n  DECLARE_ENCODING(DOUBLE_VARINT_TUPLE)\n\n  // Any\n  DECLARE_ENCODING(BYTE_CHOICE_INDEX)\n  DECLARE_ENCODING(LARGE_CHOICE_INDEX)\n  DECLARE_ENCODING(TOP_LEVEL_BYTE_CHOICE_INDEX)\n  DECLARE_ENCODING(CONST_NONE)\n  DECLARE_ENCODING(ANY_PACKED_TYPE_TAG_BYTE_PREFIX)\n\n  // String\n  DECLARE_ENCODING(UTF8_STRING_NO_LENGTH)\n  DECLARE_ENCODING(FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(RFC3339_DATE_INTEGER_TRIPLET)\n  DECLARE_ENCODING(PREFIX_VARINT_LENGTH_STRING_SHARED)\n  // TODO: Implement STRING_BROTLI encoding\n  // TODO: Implement STRING_DICTIONARY_COMPRESSOR encoding\n  // TODO: Implement STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH encoding\n  // TODO: Implement URL_PROTOCOL_HOST_REST encoding\n\n  // Array\n  DECLARE_ENCODING(FIXED_TYPED_ARRAY)\n  DECLARE_ENCODING(BOUNDED_8BITS_TYPED_ARRAY)\n  DECLARE_ENCODING(FLOOR_TYPED_ARRAY)\n  DECLARE_ENCODING(ROOF_TYPED_ARRAY)\n\n  // Object\n  DECLARE_ENCODING(FIXED_TYPED_ARBITRARY_OBJECT)\n  DECLARE_ENCODING(VARINT_TYPED_ARBITRARY_OBJECT)\n\n#undef DECLARE_ENCODING\n#endif\n};\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_encoder.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_H_\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/jsonbinpack/runtime_encoder_cache.h>\n#include <sourcemeta/jsonbinpack/runtime_encoding.h>\n#include <sourcemeta/jsonbinpack/runtime_output_stream.h>\n\n#include <sourcemeta/core/json.h>\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup runtime\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT Encoder : private OutputStream {\npublic:\n  Encoder(Stream &output);\n  auto write(const sourcemeta::core::JSON &document, const Encoding &encoding)\n      -> void;\n\n// The methods that implement individual encodings as considered private\n#ifndef DOXYGEN\n#define DECLARE_ENCODING(name)                                                 \\\n  auto name(const sourcemeta::core::JSON &document, const name &) -> void;\n\n  // Integer\n  DECLARE_ENCODING(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED)\n  DECLARE_ENCODING(FLOOR_MULTIPLE_ENUM_VARINT)\n  DECLARE_ENCODING(ROOF_MULTIPLE_MIRROR_ENUM_VARINT)\n  DECLARE_ENCODING(ARBITRARY_MULTIPLE_ZIGZAG_VARINT)\n\n  // Number\n  DECLARE_ENCODING(DOUBLE_VARINT_TUPLE)\n\n  // Any\n  DECLARE_ENCODING(BYTE_CHOICE_INDEX)\n  DECLARE_ENCODING(LARGE_CHOICE_INDEX)\n  DECLARE_ENCODING(TOP_LEVEL_BYTE_CHOICE_INDEX)\n  DECLARE_ENCODING(CONST_NONE)\n  DECLARE_ENCODING(ANY_PACKED_TYPE_TAG_BYTE_PREFIX)\n\n  // String\n  DECLARE_ENCODING(UTF8_STRING_NO_LENGTH)\n  DECLARE_ENCODING(FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)\n  DECLARE_ENCODING(RFC3339_DATE_INTEGER_TRIPLET)\n  DECLARE_ENCODING(PREFIX_VARINT_LENGTH_STRING_SHARED)\n  // TODO: Implement STRING_BROTLI encoding\n  // TODO: Implement STRING_DICTIONARY_COMPRESSOR encoding\n  // TODO: Implement STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH encoding\n  // TODO: Implement URL_PROTOCOL_HOST_REST encoding\n\n  // Array\n  DECLARE_ENCODING(FIXED_TYPED_ARRAY)\n  DECLARE_ENCODING(BOUNDED_8BITS_TYPED_ARRAY)\n  DECLARE_ENCODING(FLOOR_TYPED_ARRAY)\n  DECLARE_ENCODING(ROOF_TYPED_ARRAY)\n\n  // Object\n  DECLARE_ENCODING(FIXED_TYPED_ARBITRARY_OBJECT)\n  DECLARE_ENCODING(VARINT_TYPED_ARBITRARY_OBJECT)\n\n#undef DECLARE_ENCODING\n#endif\n\nprivate:\n  Cache cache_;\n};\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_encoder_cache.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_CACHE_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_CACHE_H_\n#ifndef DOXYGEN\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <functional> // std::reference_wrapper\n#include <map>        // std::map\n#include <optional>   // std::optional\n#include <utility>    // std::pair\n\nnamespace sourcemeta::jsonbinpack {\n\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT Cache {\npublic:\n  enum class Type : std::uint8_t { Standalone, PrefixLengthVarintPlusOne };\n  auto record(const sourcemeta::core::JSON::String &value,\n              const std::uint64_t offset, const Type type) -> void;\n  [[nodiscard]] auto find(const sourcemeta::core::JSON::String &value,\n                          const Type type) const\n      -> std::optional<std::uint64_t>;\n\n#ifndef DOXYGEN\n  // This method is considered private. We only expose it for testing purposes\n  auto remove_oldest() -> void;\n#endif\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n  std::uint64_t byte_size{0};\n  using Entry = std::pair<sourcemeta::core::JSON::String, Type>;\n  std::map<Entry, std::uint64_t> data;\n  std::map<std::uint64_t, std::reference_wrapper<const Entry>> order;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n};\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_encoding.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODING_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODING_H_\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/numeric.h>\n\n#include <cstdint> // std::int64_t, std::uint64_t\n#include <memory>  // std::shared_ptr\n#include <variant> // std::variant\n#include <vector>  // std::vector\n\nnamespace sourcemeta::jsonbinpack {\n\n// Forward declarations for the sole purpose of being bale to define circular\n// structures\n#ifndef DOXYGEN\nstruct BOUNDED_MULTIPLE_8BITS_ENUM_FIXED;\nstruct FLOOR_MULTIPLE_ENUM_VARINT;\nstruct ROOF_MULTIPLE_MIRROR_ENUM_VARINT;\nstruct ARBITRARY_MULTIPLE_ZIGZAG_VARINT;\nstruct DOUBLE_VARINT_TUPLE;\nstruct BYTE_CHOICE_INDEX;\nstruct LARGE_CHOICE_INDEX;\nstruct TOP_LEVEL_BYTE_CHOICE_INDEX;\nstruct CONST_NONE;\nstruct ANY_PACKED_TYPE_TAG_BYTE_PREFIX;\nstruct UTF8_STRING_NO_LENGTH;\nstruct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED;\nstruct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED;\nstruct BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED;\nstruct RFC3339_DATE_INTEGER_TRIPLET;\nstruct PREFIX_VARINT_LENGTH_STRING_SHARED;\nstruct FIXED_TYPED_ARRAY;\nstruct BOUNDED_8BITS_TYPED_ARRAY;\nstruct FLOOR_TYPED_ARRAY;\nstruct ROOF_TYPED_ARRAY;\nstruct FIXED_TYPED_ARBITRARY_OBJECT;\nstruct VARINT_TYPED_ARBITRARY_OBJECT;\n#endif\n\n/// @ingroup runtime\n/// Represents an encoding\nusing Encoding = std::variant<\n    BOUNDED_MULTIPLE_8BITS_ENUM_FIXED, FLOOR_MULTIPLE_ENUM_VARINT,\n    ROOF_MULTIPLE_MIRROR_ENUM_VARINT, ARBITRARY_MULTIPLE_ZIGZAG_VARINT,\n    DOUBLE_VARINT_TUPLE, BYTE_CHOICE_INDEX, LARGE_CHOICE_INDEX,\n    TOP_LEVEL_BYTE_CHOICE_INDEX, CONST_NONE, ANY_PACKED_TYPE_TAG_BYTE_PREFIX,\n    UTF8_STRING_NO_LENGTH, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED,\n    ROOF_VARINT_PREFIX_UTF8_STRING_SHARED,\n    BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED, RFC3339_DATE_INTEGER_TRIPLET,\n    PREFIX_VARINT_LENGTH_STRING_SHARED, FIXED_TYPED_ARRAY,\n    BOUNDED_8BITS_TYPED_ARRAY, FLOOR_TYPED_ARRAY, ROOF_TYPED_ARRAY,\n    FIXED_TYPED_ARBITRARY_OBJECT, VARINT_TYPED_ARBITRARY_OBJECT>;\n\n/// @ingroup runtime\n/// @defgroup encoding_integer Integer Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consists of the integer value divided by the\n/// `multiplier`, minus the ceil of `minimum` divided by the `multiplier`,\n/// encoded as an 8-bit fixed-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option       | Type   | Description                 |\n/// |--------------|--------|-----------------------------|\n/// | `minimum`    | `int`  | The inclusive minimum value |\n/// | `maximum`    | `int`  | The inclusive maximum value |\n/// | `multiplier` | `uint` | The multiplier value        |\n///\n/// ### Conditions\n///\n/// | Condition                    | Description                                                         |\n/// |------------------------------|---------------------------------------------------------------------|\n/// | `value >= minimum`           | The input value must be greater than or equal to the minimum        |\n/// | `value <= maximum`           | The input value must be less than or equal to the maximum           |\n/// | `value % multiplier == 0`    | The input value must be divisible by the multiplier                 |\n/// | `floor(maximum / multiplier) - ceil(minimum / multiplier) < 2 ** 8` | The divided range must be representable in 8 bits |\n///\n/// ### Examples\n///\n/// Given the input value 15, where the minimum is 1, the maximum is 19, and the\n/// multiplier is 5, the encoding results in the 8-bit unsigned integer 2:\n///\n/// ```\n/// +------+\n/// | 0x02 |\n/// +------+\n/// ```\n// clang-format on\nstruct BOUNDED_MULTIPLE_8BITS_ENUM_FIXED {\n  /// The inclusive minimum value\n  std::int64_t minimum;\n  /// The inclusive maximum value\n  std::int64_t maximum;\n  /// The multiplier value\n  std::uint64_t multiplier;\n};\n\n// clang-format off\n/// @brief The encoding consists of the integer value divided by the\n/// `multiplier`, minus the ceil of `minimum` divided by the `multiplier`,\n/// encoded as a Base-128 64-bit Little Endian variable-length unsigned\n/// integer.\n///\n/// ### Options\n///\n/// | Option       | Type   | Description                 |\n/// |--------------|--------|-----------------------------|\n/// | `minimum`    | `int`  | The inclusive minimum value |\n/// | `multiplier` | `uint` | The multiplier value        |\n///\n/// ### Conditions\n///\n/// | Condition                 | Description                                                  |\n/// |---------------------------|--------------------------------------------------------------|\n/// | `value >= minimum`        | The input value must be greater than or equal to the minimum |\n/// | `value % multiplier == 0` | The input value must be divisible by the multiplier          |\n///\n/// ### Examples\n///\n/// Given the input value 1000, where the minimum is -2 and the multiplier is 4,\n/// the encoding results in the Base-128 64-bit Little Endian variable-length\n/// unsigned integer 250:\n///\n/// ```\n/// +------+------+\n/// | 0xfa | 0x01 |\n/// +------+------+\n/// ```\n// clang-format on\nstruct FLOOR_MULTIPLE_ENUM_VARINT {\n  /// The inclusive minimum value\n  std::int64_t minimum;\n  /// The multiplier value\n  std::uint64_t multiplier;\n};\n\n// clang-format off\n/// @brief The encoding consists of the floor of `maximum` divided by the\n/// `multiplier`, minus the integer value divided by the `multiplier`, encoded\n/// as a Base-128 64-bit Little Endian variable-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option       | Type   | Description                 |\n/// |--------------|--------|-----------------------------|\n/// | `maximum`    | `int`  | The inclusive maximum value |\n/// | `multiplier` | `uint` | The multiplier value        |\n///\n/// ### Conditions\n///\n/// | Condition                 | Description                                               |\n/// |---------------------------|-----------------------------------------------------------|\n/// | `value <= maximum`        | The input value must be less than or equal to the maximum |\n/// | `value % multiplier == 0` | The input value must be divisible by the multiplier       |\n///\n/// ### Examples\n///\n/// Given the input value 5, where the maximum is 16 and the multiplier is 5, the\n/// encoding results in the Base-128 64-bit Little Endian variable-length unsigned\n/// integer 2:\n///\n/// ```\n/// +------+\n/// | 0x02 |\n/// +------+\n/// ```\n// clang-format on\nstruct ROOF_MULTIPLE_MIRROR_ENUM_VARINT {\n  /// The inclusive maximum value\n  std::int64_t maximum;\n  /// The multiplier value\n  std::uint64_t multiplier;\n};\n\n// clang-format off\n/// @brief The encoding consists of the the integer value divided by the\n/// `multiplier` encoded as a ZigZag-encoded Base-128 64-bit Little Endian\n/// variable-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option       | Type   | Description          |\n/// |--------------|--------|----------------------|\n/// | `multiplier` | `uint` | The multiplier value |\n///\n/// ### Conditions\n///\n/// | Condition                 | Description                                         |\n/// |---------------------------|-----------------------------------------------------|\n/// | `value % multiplier == 0` | The input value must be divisible by the multiplier |\n///\n/// ### Examples\n///\n/// Given the input value 10, where the multiplier is 5, the encoding results in\n/// the Base-128 64-bit Little Endian variable-length unsigned integer 4:\n///\n/// ```\n/// +------+\n/// | 0x04 |\n/// +------+\n/// ```\n// clang-format on\nstruct ARBITRARY_MULTIPLE_ZIGZAG_VARINT {\n  /// The multiplier value\n  std::uint64_t multiplier;\n};\n\n/// @}\n\n/// @ingroup runtime\n/// @defgroup encoding_number Number Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consists of a sequence of two integers: The signed\n/// integer that results from concatenating the integral part and the decimal\n/// part of the number, if any, as a ZigZag-encoded Base-128 64-bit Little\n/// Endian variable-length unsigned integer; and the position of the decimal\n/// mark from the last digit of the number encoded as a Base-128 64-bit Little\n/// Endian variable-length unsigned integer.\n///\n/// ### Options\n///\n/// None\n///\n/// ### Conditions\n///\n/// None\n///\n/// ### Examples\n///\n/// Given the input value 3.14, the encoding results in the variable-length integer\n/// 628 (the ZigZag encoding of 314) followed by the variable-length unsigned\n/// integer 2 (the number of decimal digits in the number).\n///\n/// ```\n/// +------+------+------+\n/// | 0xf4 | 0x04 | 0x02 |\n/// +------+------+------+\n/// ```\n///\n/// Real numbers that represent integers are encoded with a decimal mark of zero.\n/// Given the input value -5.0, the encoding results in the variable-length integer\n/// 9 (the ZigZag encoding of -5) followed by the variable-length unsigned integer\n/// 0.\n///\n/// ```\n/// +------+------+\n/// | 0x09 | 0x00 |\n/// +------+------+\n/// ```\n// clang-format on\nstruct DOUBLE_VARINT_TUPLE {};\n\n/// @}\n\n/// @ingroup runtime\n/// @defgroup encoding_any Any Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consists of an index to the enumeration choices encoded\n/// as an 8-bit fixed-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option    | Type    | Description              |\n/// |-----------|---------|--------------------------|\n/// | `choices` | `any[]` | The set of choice values |\n///\n/// ### Conditions\n///\n/// | Condition                | Description                                            |\n/// |--------------------------|--------------------------------------------------------|\n/// | `len(choices) > 0`       | The choices array must not be empty                    |\n/// | `len(choices) <  2 ** 8` | The number of choices must be representable in 8 bits  |\n/// | `value in choices`       | The input value must be included in the set of choices |\n///\n/// ### Examples\n///\n/// Given an enumeration `[ \"foo\", \"bar\", \"baz\" ]` and an input value `\"bar\"`, the\n/// encoding results in the unsigned 8 bit integer 1:\n///\n/// ```\n/// +------+\n/// | 0x01 |\n/// +------+\n/// ```\n///\n/// Given an enumeration `[ \"foo\", \"bar\", \"baz\" ]` and an input value `\"foo\"`, the\n/// encoding results in the unsigned 8 bit integer 0:\n///\n/// ```\n/// +------+\n/// | 0x00 |\n/// +------+\n/// ```\n// clang-format on\nstruct BYTE_CHOICE_INDEX {\n  /// The set of choice values\n  std::vector<sourcemeta::core::JSON> choices;\n};\n\n// clang-format off\n/// @brief The encoding consists of an index to the enumeration choices encoded\n/// as a Base-128 64-bit Little Endian variable-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option    | Type    | Description              |\n/// |-----------|---------|--------------------------|\n/// | `choices` | `any[]` | The set of choice values |\n///\n/// ### Conditions\n///\n/// | Condition                | Description                                            |\n/// |--------------------------|--------------------------------------------------------|\n/// | `len(choices) > 0`       | The choices array must not be empty                    |\n/// | `value in choices`       | The input value must be included in the set of choices |\n///\n/// ### Examples\n///\n/// Given an enumeration with 1000 members and an input value that equals the 300th\n/// enumeration value, the encoding results in the Base-128 64-bit Little Endian\n/// variable-length unsigned integer 300:\n///\n/// ```\n/// +------+------+\n/// | 0xac | 0x02 |\n/// +------+------+\n/// ```\n// clang-format on\nstruct LARGE_CHOICE_INDEX {\n  /// The set of choice values\n  std::vector<sourcemeta::core::JSON> choices;\n};\n\n// clang-format off\n/// @brief If the input value corresponds to the index 0 to the enumeration\n/// choices, the encoding stores no data. Otherwise, the encoding consists of\n/// an index to the enumeration choices minus 1 encoded as an 8-bit\n/// fixed-length unsigned integer.\n///\n/// ### Options\n///\n/// | Option    | Type    | Description              |\n/// |-----------|---------|--------------------------|\n/// | `choices` | `any[]` | The set of choice values |\n///\n/// ### Conditions\n///\n/// | Condition                | Description                                            |\n/// |--------------------------|--------------------------------------------------------|\n/// | `len(choices) > 0`       | The choices array must not be empty                    |\n/// | `len(choices) <  2 ** 8` | The number of choices must be representable in 8 bits  |\n/// | `value in choices`       | The input value must be included in the set of choices |\n///\n/// ### Examples\n///\n/// Given an enumeration `[ \"foo\", \"bar\", \"baz\" ]` and an input value `\"bar\"`, the\n/// encoding results in the unsigned 8 bit integer 0:\n///\n/// ```\n/// +------+\n/// | 0x00 |\n/// +------+\n/// ```\n///\n/// Given an enumeration `[ \"foo\", \"bar\", \"baz\" ]` and an input value `\"foo\"`, the\n/// value is not encoded.\n// clang-format on\nstruct TOP_LEVEL_BYTE_CHOICE_INDEX {\n  /// The set of choice values\n  std::vector<sourcemeta::core::JSON> choices;\n};\n\n// clang-format off\n/// @brief The constant input value is not encoded.\n///\n/// ### Options\n///\n/// | Option  | Type  | Description        |\n/// |---------|-------|--------------------|\n/// | `value` | `any` | The constant value |\n///\n/// ### Conditions\n///\n/// None\n///\n/// ### Examples\n///\n/// The input value that matches the `value` option is not encoded.\n// clang-format on\nstruct CONST_NONE {\n  /// The constant value\n  sourcemeta::core::JSON value;\n};\n\n// TODO: Write brief description\nstruct ANY_PACKED_TYPE_TAG_BYTE_PREFIX {};\n#ifndef DOXYGEN\nnamespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX {\nconstexpr auto type_size = 3;\nconstexpr std::uint8_t TYPE_SHARED_STRING = 0b00000000;\nconstexpr std::uint8_t TYPE_STRING = 0b00000001;\nconstexpr std::uint8_t TYPE_LONG_STRING = 0b00000010;\nconstexpr std::uint8_t TYPE_OBJECT = 0b00000011;\nconstexpr std::uint8_t TYPE_ARRAY = 0b00000100;\nconstexpr std::uint8_t TYPE_POSITIVE_INTEGER_BYTE = 0b00000101;\nconstexpr std::uint8_t TYPE_NEGATIVE_INTEGER_BYTE = 0b00000110;\nconstexpr std::uint8_t TYPE_OTHER = 0b00000111;\nstatic_assert(TYPE_SHARED_STRING <= sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_STRING <= sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_LONG_STRING <= sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_OBJECT <= sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_ARRAY <= sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_POSITIVE_INTEGER_BYTE <=\n              sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_NEGATIVE_INTEGER_BYTE <=\n              sourcemeta::core::uint_max<type_size>);\nstatic_assert(TYPE_OTHER <= sourcemeta::core::uint_max<type_size>);\n\nconstexpr auto subtype_size = 5;\nconstexpr std::uint8_t SUBTYPE_FALSE = 0b00000000;\nconstexpr std::uint8_t SUBTYPE_TRUE = 0b00000001;\nconstexpr std::uint8_t SUBTYPE_NULL = 0b00000010;\nconstexpr std::uint8_t SUBTYPE_POSITIVE_INTEGER = 0b00000011;\nconstexpr std::uint8_t SUBTYPE_NEGATIVE_INTEGER = 0b00000100;\nconstexpr std::uint8_t SUBTYPE_NUMBER = 0b00000101;\nconstexpr std::uint8_t SUBTYPE_POSITIVE_REAL_INTEGER_BYTE = 0b00000110;\nconstexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_7 = 0b00000111;\nconstexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_8 = 0b00001000;\nconstexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_9 = 0b00001001;\nconstexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_10 = 0b00001010;\n\nstatic_assert(SUBTYPE_FALSE <= sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_TRUE <= sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_NULL <= sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_POSITIVE_INTEGER <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_NEGATIVE_INTEGER <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_NUMBER <= sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_POSITIVE_REAL_INTEGER_BYTE <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 <=\n              sourcemeta::core::uint_max<subtype_size>);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 <=\n              sourcemeta::core::uint_max<subtype_size>);\n\n// Note that the binary values actually match the declared exponents\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 == 7);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 == 8);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 == 9);\nstatic_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 == 10);\n} // namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX\n#endif\n\n/// @}\n\n/// @ingroup runtime\n/// @defgroup encoding_string String Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consist in the UTF-8 encoding of the input string.\n///\n/// ### Options\n///\n/// | Option | Type   | Description                  |\n/// |--------|--------|------------------------------|\n/// | `size` | `uint` | The string UTF-8 byte-length |\n///\n/// ### Conditions\n///\n/// | Condition            | Description                                               |\n/// |----------------------|-----------------------------------------------------------|\n/// | `len(value) == size` | The input string must have the declared UTF-8 byte-length |\n///\n/// ### Examples\n///\n/// Given the input value \"foo bar\" with a corresponding size of 7, the encoding\n/// results in:\n///\n/// ```\n/// +------+------+------+------+------+------+------+\n/// | 0x66 | 0x6f | 0x6f | 0x20 | 0x62 | 0x61 | 0x72 |\n/// +------+------+------+------+------+------+------+\n///   f      o      o             b      a      r\n/// ```\n// clang-format on\nstruct UTF8_STRING_NO_LENGTH {\n  /// The string UTF-8 byte-length\n  std::uint64_t size;\n};\n\n// clang-format off\n/// @brief The encoding consists of the byte-length of the string minus\n/// `minimum` plus 1 as a Base-128 64-bit Little Endian variable-length\n/// unsigned integer followed by the UTF-8 encoding of the input value.\n///\n/// Optionally, if the input string has already been encoded to the buffer\n/// using UTF-8, the encoding may consist of the byte constant `0x00` followed\n/// by the byte-length of the string minus `minimum` plus 1 as a Base-128\n/// 64-bit Little Endian variable-length unsigned integer, followed by the\n/// current offset minus the offset to the start of the UTF-8 string value in\n/// the buffer encoded as a Base-128 64-bit Little Endian variable-length\n/// unsigned integer.\n///\n/// #### Options\n///\n/// | Option    | Type   | Description                                    |\n/// |-----------|--------|------------------------------------------------|\n/// | `minimum` | `uint` | The inclusive minimum string UTF-8 byte-length |\n///\n/// #### Conditions\n///\n/// | Condition               | Description                                                          |\n/// |-------------------------|----------------------------------------------------------------------|\n/// | `len(value) >= minimum` | The input string byte-length is equal to or greater than the minimum |\n///\n/// #### Examples\n///\n/// Given the input string `foo` with a minimum 3 where the string has not been\n/// previously encoded, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x01 | 0x66 | 0x6f | 0x6f |\n/// +------+------+------+------+\n///          f      o      o\n/// ```\n///\n/// Given the encoding of `foo` with a minimum of 0 followed by the encoding of\n/// `foo` with a minimum of 3, the encoding may result in:\n///\n/// ```\n/// 0      1      2      3      4      5      6\n/// ^      ^      ^      ^      ^      ^      ^\n/// +------+------+------+------+------+------+------+\n/// | 0x04 | 0x66 | 0x6f | 0x6f | 0x00 | 0x01 | 0x05 |\n/// +------+------+------+------+------+------+------+\n///          f      o      o                    6 - 1\n/// ```\n// clang-format on\nstruct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED {\n  /// The inclusive minimum string UTF-8 byte-length\n  std::uint64_t minimum;\n};\n\n// clang-format off\n/// @brief The encoding consists of `maximum` minus the byte-length of the\n/// string plus 1 as a Base-128 64-bit Little Endian variable-length unsigned\n/// integer followed by the UTF-8 encoding of the input value.\n///\n/// Optionally, if the input string has already been encoded to the buffer\n/// using UTF-8, the encoding may consist of the byte constant `0x00` followed\n/// by `maximum` minus the byte-length of the string plus 1 as a Base-128\n/// 64-bit Little Endian variable-length unsigned integer, followed by the\n/// current offset minus the offset to the start of the UTF-8 string value in\n/// the buffer encoded as a Base-128 64-bit Little Endian variable-length\n/// unsigned integer.\n///\n/// #### Options\n///\n/// | Option    | Type   | Description                                    |\n/// |-----------|--------|------------------------------------------------|\n/// | `maximum` | `uint` | The inclusive maximum string UTF-8 byte-length |\n///\n/// #### Conditions\n///\n/// | Condition               | Description                                                       |\n/// |-------------------------|-------------------------------------------------------------------|\n/// | `len(value) <= maximum` | The input string byte-length is equal to or less than the maximum |\n///\n/// #### Examples\n///\n/// Given the input string `foo` with a maximum 4 where the string has not been\n/// previously encoded, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x02 | 0x66 | 0x6f | 0x6f |\n/// +------+------+------+------+\n///          f      o      o\n/// ```\n///\n/// Given the encoding of `foo` with a maximum of 3 followed by the encoding of\n/// `foo` with a maximum of 5, the encoding may result in:\n///\n/// ```\n/// 0      1      2      3      4      5      6\n/// ^      ^      ^      ^      ^      ^      ^\n/// +------+------+------+------+------+------+------+\n/// | 0x01 | 0x66 | 0x6f | 0x6f | 0x00 | 0x03 | 0x05 |\n/// +------+------+------+------+------+------+------+\n///          f      o      o                    6 - 1\n/// ```\n// clang-format on\nstruct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED {\n  /// The inclusive maximum string UTF-8 byte-length\n  std::uint64_t maximum;\n};\n\n// clang-format off\n/// @brief The encoding consists of the byte-length of the string minus\n/// `minimum` plus 1 as an 8-bit fixed-length unsigned integer followed by the\n/// UTF-8 encoding of the input value.\n///\n/// Optionally, if the input string has already been encoded to the buffer\n/// using UTF-8, the encoding may consist of the byte constant `0x00` followed\n/// by the byte-length of the string minus `minimum` plus 1 as an 8-bit\n/// fixed-length unsigned integer, followed by the current offset minus the\n/// offset to the start of the UTF-8 string value in the buffer encoded as a\n/// Base-128 64-bit Little Endian variable-length unsigned integer.\n///\n/// The byte-length of the string is encoded even if `maximum` equals `minimum`\n/// in order to disambiguate between shared and non-shared fixed strings.\n///\n/// #### Options\n///\n/// | Option    | Type   | Description                                    |\n/// |-----------|--------|------------------------------------------------|\n/// | `minimum` | `uint` | The inclusive minimum string UTF-8 byte-length |\n/// | `maximum` | `uint` | The inclusive maximum string UTF-8 byte-length |\n///\n/// #### Conditions\n///\n/// | Condition                        | Description                                                          |\n/// |----------------------------------|----------------------------------------------------------------------|\n/// | `len(value) >= minimum`          | The input string byte-length is equal to or greater than the minimum |\n/// | `len(value) <= maximum`          | The input string byte-length is equal to or less than the maximum    |\n/// | `maximum - minimum < 2 ** 8 - 1` | The range minus 1 must be representable in 8 bits                    |\n///\n/// #### Examples\n///\n/// Given the input string `foo` with a minimum 3 and a maximum 5 where the string\n/// has not been previously encoded, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x01 | 0x66 | 0x6f | 0x6f |\n/// +------+------+------+------+\n///          f      o      o\n/// ```\n///\n/// Given the encoding of `foo` with a minimum of 0 and a maximum of 6 followed by\n/// the encoding of `foo` with a minimum of 3 and a maximum of 100, the encoding\n/// may result in:\n///\n/// ```\n/// 0      1      2      3      4      5      6\n/// ^      ^      ^      ^      ^      ^      ^\n/// +------+------+------+------+------+------+------+\n/// | 0x04 | 0x66 | 0x6f | 0x6f | 0x00 | 0x01 | 0x05 |\n/// +------+------+------+------+------+------+------+\n///          f      o      o                    6 - 1\n/// ```\n// clang-format on\nstruct BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED {\n  /// The inclusive minimum string UTF-8 byte-length\n  std::uint64_t minimum;\n  /// The inclusive maximum string UTF-8 byte-length\n  std::uint64_t maximum;\n};\n\n// clang-format off\n/// @brief The encoding consists of an implementation of\n/// [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) date expressions\n/// as the sequence of 3 integers: the year as a 16-bit fixed-length Little\n/// Endian unsigned integer, the month as an 8-bit fixed-length unsigned\n/// integer, and the day as an 8-bit fixed-length unsigned integer.\n///\n/// #### Options\n///\n/// None\n///\n/// #### Conditions\n///\n/// | Condition            | Description                                                 |\n/// |----------------------|-------------------------------------------------------------|\n/// | `len(value) == 10`   | The input string consists of 10 characters                  |\n/// | `value[0:4] >= 0`    | The year is greater than or equal to 0                      |\n/// | `value[0:4] <= 9999` | The year is less than or equal to 9999 as stated by RFC3339 |\n/// | `value[4] == \"-\"`    | The year and the month are divided by a hyphen              |\n/// | `value[5:7] >= 1`    | The month is greater than or equal to 1                     |\n/// | `value[5:7] <= 12`   | The month is less than or equal to 12                       |\n/// | `value[7] == \"-\"`    | The month and the day are divided by a hyphen               |\n/// | `value[8:10] >= 1`   | The day is greater than or equal to 1                       |\n/// | `value[8:10] <= 31`  | The day is less than or equal to 31                         |\n///\n/// #### Examples\n///\n/// Given the input string `2014-10-01`, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0xde | 0x07 | 0x0a | 0x01 |\n/// +------+------+------+------+\n///   year   ...    month  day\n/// ```\n// clang-format on\nstruct RFC3339_DATE_INTEGER_TRIPLET {};\n\n// clang-format off\n/// @brief The encoding consists of the byte-length of the string plus 1 as a\n/// Base-128 64-bit Little Endian variable-length unsigned integer followed by\n/// the UTF-8 encoding of the input value.\n///\n/// Optionally, if the input string has already been encoded to the buffer\n/// using this encoding the encoding may consist of the byte constant `0x00`\n/// followed by the current offset minus the offset to the start of the string\n/// as a Base-128 64-bit Little Endian variable-length unsigned integer.  It is\n/// permissible to point to another instance of the string that is a pointer\n/// itself.\n///\n/// ### Options\n///\n/// None\n///\n/// ### Conditions\n///\n/// None\n///\n/// ### Examples\n///\n/// Given the input string `foo` where the string has not been previously encoded,\n/// the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x04 | 0x66 | 0x6f | 0x6f |\n/// +------+------+------+------+\n///          f      o      o\n/// ```\n///\n/// Given the encoding of `foo` repeated 3 times, the encoding may result in:\n///\n/// ```\n/// 0      1      2      3      4      5      6      7\n/// ^      ^      ^      ^      ^      ^      ^      ^\n/// +------+------+------+------+------+------+------+------+\n/// | 0x04 | 0x66 | 0x6f | 0x6f | 0x00 | 0x05 | 0x00 | 0x03 |\n/// +------+------+------+------+------+------+------+------+\n///          f      o      o             5 - 0         7 - 4\n/// ```\n// clang-format on\nstruct PREFIX_VARINT_LENGTH_STRING_SHARED {};\n\n/// @}\n\n/// @ingroup runtime\n/// @defgroup encoding_array Array Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consists of the elements of the fixed array encoded in\n/// order. The encoding of the element at index `i` is either\n/// `prefix_encodings[i]` if set, or `encoding`.\n///\n/// ### Options\n///\n/// | Option            | Type         | Description          |\n/// |-------------------|--------------|----------------------|\n/// | `size`            | `uint`       | The array length     |\n/// | `prefixEncodings` | `encoding[]` | Positional encodings |\n/// | `encoding`        | `encoding`   | Element encoding     |\n///\n/// ### Conditions\n///\n/// | Condition                      | Description                                                           |\n/// |--------------------------------|-----------------------------------------------------------------------|\n/// | `len(prefixEncodings) <= size` | The number of prefix encodings must be less than or equal to the size |\n/// | `len(value) == size`           | The input array must have the declared size                           |\n///\n/// ### Examples\n///\n/// Given the array `[ 1, 2, true ]` where the `prefixEncodings` corresponds to\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED (minimum 0, maximum 10, multiplier 1) and\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED (minimum 0, maximum 10, multiplier 1) and\n/// `encoding` corresponds to BYTE_CHOICE_INDEX with choices `[ false, true ]`,\n/// the encoding results in:\n///\n/// ```\n/// +------+------+------+\n/// | 0x00 | 0x01 | 0x01 |\n/// +------+------+------+\n///   1      2      true\n/// ```\n// clang-format on\nstruct FIXED_TYPED_ARRAY {\n  /// The array length\n  std::uint64_t size;\n  /// Element encoding\n  std::shared_ptr<Encoding> encoding;\n  /// Positional encodings\n  std::vector<Encoding> prefix_encodings;\n};\n\n// clang-format off\n/// @brief The encoding consists of the length of the array minus `minimum`\n/// encoded as an 8-bit fixed-length unsigned integer followed by the elements\n/// of the array encoded in order. The encoding of the element at index `i` is\n/// either `prefix_encodings[i]` if set, or `encoding`.\n///\n/// ### Options\n///\n/// | Option            | Type         | Description                     |\n/// |-------------------|--------------|---------------------------------|\n/// | `minimum`         | `uint`       | The minimum length of the array |\n/// | `maximum`         | `uint`       | The maximum length of the array |\n/// | `prefixEncodings` | `encoding[]` | Positional encodings            |\n/// | `encoding`        | `encoding`   | Element encoding                |\n///\n/// ### Conditions\n///\n/// | Condition                              | Description                                                                           |\n/// |----------------------------------------|---------------------------------------------------------------------------------------|\n/// | `len(value) >= minimum`                | The length of the array must be greater than or equal to the minimum                  |\n/// | `len(value) <= maximum`                | The length of the array must be less than or equal to the maximum                     |\n/// | `len(prefixEncodings) <= maximum`      | The number of prefix encodings must be less than or equal to the maximum array length |\n/// | `len(maximum) - len(minimum) < 2 ** 8` | The array length must be representable in 8 bits                                      |\n///\n/// ### Examples\n///\n/// Given the array `[ true, false, 5 ]` where the minimum is 1 and the maximum is\n/// 3, the `prefixEncodings` corresponds to BYTE_CHOICE_INDEX with\n/// choices `[ false, true ]` and BYTE_CHOICE_INDEX with choices `[\n/// false, true ]` and `encoding` corresponds to\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED with minimum 0 and maximum\n/// 255, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x02 | 0x01 | 0x00 | 0x05 |\n/// +------+------+------+------+\n///   size   true   false  5\n/// ```\n// clang-format on\nstruct BOUNDED_8BITS_TYPED_ARRAY {\n  /// The minimum length of the array\n  std::uint64_t minimum;\n  /// The maximum length of the array\n  std::uint64_t maximum;\n  /// Element encoding\n  std::shared_ptr<Encoding> encoding;\n  /// Positional encodings\n  std::vector<Encoding> prefix_encodings;\n};\n\n// clang-format off\n/// @brief The encoding consists of the length of the array minus `minimum`\n/// encoded as a Base-128 64-bit Little Endian variable-length unsigned integer\n/// followed by the elements of the array encoded in order. The encoding of the\n/// element at index `i` is either `prefix_encodings[i]` if set, or `encoding`.\n///\n/// ### Options\n///\n/// | Option            | Type         | Description                     |\n/// |-------------------|--------------|---------------------------------|\n/// | `minimum`         | `uint`       | The minimum length of the array |\n/// | `prefixEncodings` | `encoding[]` | Positional encodings            |\n/// | `encoding`        | `encoding`   | Element encoding                |\n///\n/// ### Conditions\n///\n/// | Condition               | Description                                                          |\n/// |-------------------------|----------------------------------------------------------------------|\n/// | `len(value) >= minimum` | The length of the array must be greater than or equal to the minimum |\n///\n/// ### Examples\n///\n/// TODO: Give an example of an array with more than 8-bit of elements\n///\n/// Given the array `[ true, false, 5 ]` where the minimum is 1, the\n/// `prefixEncodings` corresponds to BYTE_CHOICE_INDEX with choices `[\n/// false, true ]` and BYTE_CHOICE_INDEX with choices `[ false, true ]`\n/// and `encoding` corresponds to BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\n/// with minimum 0 and maximum 255, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x02 | 0x01 | 0x00 | 0x05 |\n/// +------+------+------+------+\n///   size   true   false  5\n/// ```\n// clang-format on\nstruct FLOOR_TYPED_ARRAY {\n  /// The minimum length of the array\n  std::uint64_t minimum;\n  /// Element encoding\n  std::shared_ptr<Encoding> encoding;\n  /// Positional encodings\n  std::vector<Encoding> prefix_encodings;\n};\n\n// clang-format off\n/// @brief The encoding consists of `maximum` minus the length of the array\n/// encoded as a Base-128 64-bit Little Endian variable-length unsigned integer\n/// followed by the elements of the array encoded in order. The encoding of the\n/// element at index `i` is either `prefix_encodings[i]` if set, or `encoding`.\n///\n/// ### Options\n///\n/// | Option            | Type         | Description                     |\n/// |-------------------|--------------|---------------------------------|\n/// | `maximum`         | `uint`       | The maximum length of the array |\n/// | `prefixEncodings` | `encoding[]` | Positional encodings            |\n/// | `encoding`        | `encoding`   | Element encoding                |\n///\n/// ### Conditions\n///\n/// | Condition                         | Description                                                                           |\n/// |-----------------------------------|---------------------------------------------------------------------------------------|\n/// | `len(prefixEncodings) <= maximum` | The number of prefix encodings must be less than or equal to the maximum array length |\n///\n/// ### Examples\n///\n/// Given the array `[ true, false, 5 ]` where the maximum is 3, the\n/// `prefixEncodings` options corresponds to BYTE_CHOICE_INDEX with\n/// choices `[ false, true ]` and BYTE_CHOICE_INDEX with choices `[\n/// false, true ]` and `encoding` corresponds to\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED with minimum 0 and maximum\n/// 255, the encoding results in:\n///\n/// ```\n/// +------+------+------+------+\n/// | 0x00 | 0x01 | 0x00 | 0x05 |\n/// +------+------+------+------+\n///   size   true   false  5\n/// ```\n// clang-format on\nstruct ROOF_TYPED_ARRAY {\n  /// The maximum length of the array\n  std::uint64_t maximum;\n  /// Element encoding\n  std::shared_ptr<Encoding> encoding;\n  /// Positional encodings\n  std::vector<Encoding> prefix_encodings;\n};\n\n/// @}\n\n/// @ingroup runtime\n/// @defgroup encoding_object Object Encodings\n/// @{\n\n// clang-format off\n/// @brief The encoding consists of each pair encoded as the key followed by\n/// the value according to `key_encoding` and `encoding`. The order in which\n/// pairs are encoded is undefined.\n///\n/// ### Options\n///\n/// | Option        | Type       | Description     |\n/// |---------------|------------|-----------------|\n/// | `size`        | `uint`     | The object size |\n/// | `keyEncoding` | `encoding` | Key encoding    |\n/// | `encoding`    | `encoding` | Value encoding  |\n///\n/// ### Conditions\n///\n/// | Condition            | Description                                               |\n/// |----------------------|-----------------------------------------------------------|\n/// | `len(value) == size` | The input object must have the declared amount of entries |\n///\n/// ### Examples\n///\n/// Given the array `{ \"foo\": 1, \"bar\": 2 }` where `keyEncoding` corresponds to\n/// UTF8_STRING_NO_LENGTH (size 3) and `encoding` corresponds to\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED (minimum 0, maximum 10,\n/// multiplier 1), the encoding results in:\n///\n/// ```\n/// +------+------+------+------+------+------+------+------+\n/// | 0x66 | 0x6f | 0x6f | 0x01 | 0x62 | 0x61 | 0x72 | 0x02 |\n/// +------+------+------+------+------+------+------+------+\n///   f      o      o      1      b      a      r      2\n/// ```\n///\n/// Or:\n///\n/// ```\n/// +------+------+------+------+------+------+------+------+\n/// | 0x62 | 0x61 | 0x72 | 0x02 | 0x66 | 0x6f | 0x6f | 0x01 |\n/// +------+------+------+------+------+------+------+------+\n///   b      a      r      2      f      o      o      1\n/// ```\n// clang-format on\nstruct FIXED_TYPED_ARBITRARY_OBJECT {\n  /// The object size\n  std::uint64_t size;\n  /// Key encoding\n  std::shared_ptr<Encoding> key_encoding;\n  /// Value encoding\n  std::shared_ptr<Encoding> encoding;\n};\n\n// clang-format off\n/// @brief The encoding consists of the number of key-value pairs in the input\n/// object as a Base-128 64-bit Little Endian variable-length unsigned integer\n/// followed by each pair encoded as the key followed by the value according to\n/// `key_encoding` and `encoding`. The order in which pairs are encoded is\n/// undefined.\n///\n/// ### Options\n///\n/// | Option        | Type       | Description    |\n/// |---------------|------------|----------------|\n/// | `keyEncoding` | `encoding` | Key encoding   |\n/// | `encoding`    | `encoding` | Value encoding |\n///\n/// ### Examples\n///\n/// Given the array `{ \"foo\": 1, \"bar\": 2 }` where `keyEncoding` corresponds to\n/// UTF8_STRING_NO_LENGTH (size 3) and `encoding` corresponds to\n/// BOUNDED_MULTIPLE_8BITS_ENUM_FIXED (minimum 0, maximum 10,\n/// multiplier 1), the encoding results in:\n///\n/// ```\n/// +------+------+------+------+------+------+------+------+------+\n/// | 0x02 | 0x66 | 0x6f | 0x6f | 0x01 | 0x62 | 0x61 | 0x72 | 0x02 |\n/// +------+------+------+------+------+------+------+------+------+\n///   2      f      o      o      1      b      a      r      2\n/// ```\n///\n/// Or:\n///\n/// ```\n/// +------+------+------+------+------+------+------+------+------+\n/// | 0x02 | 0x62 | 0x61 | 0x72 | 0x02 | 0x66 | 0x6f | 0x6f | 0x01 |\n/// +------+------+------+------+------+------+------+------+------+\n///   2      b      a      r      2      f      o      o      1\n/// ```\n// clang-format on\nstruct VARINT_TYPED_ARBITRARY_OBJECT {\n  /// Key encoding\n  std::shared_ptr<Encoding> key_encoding;\n  /// Value encoding\n  std::shared_ptr<Encoding> encoding;\n};\n\n/// @}\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_input_stream.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_INPUT_STREAM_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_INPUT_STREAM_H_\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/json.h>\n\n#include <cstdint> // std::uint64_t, std::int64_t\n#include <istream> // std::basic_istream\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup runtime\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT InputStream\n    : public sourcemeta::core::BinaryReader {\npublic:\n  using Stream = std::basic_istream<sourcemeta::core::JSON::Char,\n                                    sourcemeta::core::JSON::CharTraits>;\n  InputStream(Stream &input);\n\n  // Seek backwards given a relative offset\n  auto rewind(const std::uint64_t relative_offset, const std::uint64_t position)\n      -> std::uint64_t;\n  auto get_varint() -> std::uint64_t;\n  auto get_varint_zigzag() -> std::int64_t;\n  auto get_string_utf8(const std::uint64_t length)\n      -> sourcemeta::core::JSON::String;\n};\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/include/sourcemeta/jsonbinpack/runtime_output_stream.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_OUTPUT_STREAM_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_OUTPUT_STREAM_H_\n\n#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT\n#include <sourcemeta/jsonbinpack/runtime_export.h>\n#endif\n\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/json.h>\n\n#include <cstdint> // std::uint64_t, std::int64_t\n#include <ostream> // std::basic_ostream\n\nnamespace sourcemeta::jsonbinpack {\n\n/// @ingroup runtime\nclass SOURCEMETA_JSONBINPACK_RUNTIME_EXPORT OutputStream\n    : public sourcemeta::core::BinaryWriter {\npublic:\n  using Stream = std::basic_ostream<sourcemeta::core::JSON::Char,\n                                    sourcemeta::core::JSON::CharTraits>;\n  OutputStream(Stream &output);\n\n  auto put_varint(const std::uint64_t value) -> void;\n  auto put_varint_zigzag(const std::int64_t value) -> void;\n  auto put_string_utf8(const sourcemeta::core::JSON::String &string,\n                       const std::uint64_t length) -> void;\n};\n\n} // namespace sourcemeta::jsonbinpack\n\n#endif\n"
  },
  {
    "path": "src/runtime/input_stream.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_input_stream.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstddef> // std::size_t\n#include <cstdint> // std::uint8_t, std::uint64_t, std::int64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nInputStream::InputStream(Stream &input)\n    : sourcemeta::core::BinaryReader{input} {}\n\nauto InputStream::rewind(const std::uint64_t relative_offset,\n                         const std::uint64_t position) -> std::uint64_t {\n  assert(position >= relative_offset);\n  const std::uint64_t offset{position - relative_offset};\n  assert(offset < position);\n  const std::uint64_t current{this->position()};\n  this->seek(offset);\n  return current;\n}\n\nauto InputStream::get_varint() -> std::uint64_t {\n  constexpr std::uint8_t LEAST_SIGNIFICANT_BITS{0b01111111};\n  constexpr std::uint8_t MOST_SIGNIFICANT_BIT{0b10000000};\n  constexpr std::uint8_t SHIFT{7};\n  std::uint64_t result{0};\n  std::size_t cursor{0};\n  while (true) {\n    const std::uint8_t byte{this->get_byte()};\n    const std::uint64_t value{\n        static_cast<std::uint64_t>(byte & LEAST_SIGNIFICANT_BITS)};\n#ifndef NDEBUG\n    const std::uint64_t current = result;\n#endif\n    result += static_cast<std::uint64_t>(value << SHIFT * cursor);\n    // Try to catch potential overflows from the above addition\n    assert(result >= current);\n    cursor += 1;\n    if ((byte & MOST_SIGNIFICANT_BIT) == 0) {\n      break;\n    }\n  }\n\n  return result;\n}\n\nauto InputStream::get_varint_zigzag() -> std::int64_t {\n  return sourcemeta::core::zigzag_decode(this->get_varint());\n}\n\nauto InputStream::get_string_utf8(const std::uint64_t length)\n    -> sourcemeta::core::JSON::String {\n  sourcemeta::core::JSON::String result;\n  result.reserve(length);\n  std::uint64_t counter = 0;\n  while (counter < length) {\n    result += static_cast<sourcemeta::core::JSON::Char>(this->get_byte());\n    counter += 1;\n  }\n\n  assert(counter == length);\n  assert(result.size() == length);\n  return result;\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/loader.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include \"loader_v1_any.h\"\n#include \"loader_v1_array.h\"\n#include \"loader_v1_integer.h\"\n#include \"loader_v1_number.h\"\n#include \"loader_v1_string.h\"\n\n#include <cassert>   // assert\n#include <sstream>   // std::ostringstream\n#include <stdexcept> // std::runtime_error\n\nnamespace sourcemeta::jsonbinpack {\n\nauto load(const sourcemeta::core::JSON &input) -> Encoding {\n  assert(input.defines(\"binpackEncoding\"));\n  assert(input.defines(\"binpackOptions\"));\n  const auto encoding{input.at(\"binpackEncoding\").to_string()};\n  const auto &options{input.at(\"binpackOptions\")};\n\n#define PARSE_ENCODING(version, name)                                          \\\n  if (encoding == #name)                                                       \\\n    return version::name(options);\n\n  // Integers\n  PARSE_ENCODING(v1, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED)\n  PARSE_ENCODING(v1, FLOOR_MULTIPLE_ENUM_VARINT)\n  PARSE_ENCODING(v1, ROOF_MULTIPLE_MIRROR_ENUM_VARINT)\n  PARSE_ENCODING(v1, ARBITRARY_MULTIPLE_ZIGZAG_VARINT)\n  // Numbers\n  PARSE_ENCODING(v1, DOUBLE_VARINT_TUPLE)\n  // Any\n  PARSE_ENCODING(v1, BYTE_CHOICE_INDEX)\n  PARSE_ENCODING(v1, LARGE_CHOICE_INDEX)\n  PARSE_ENCODING(v1, TOP_LEVEL_BYTE_CHOICE_INDEX)\n  PARSE_ENCODING(v1, CONST_NONE)\n  PARSE_ENCODING(v1, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)\n  // Strings\n  PARSE_ENCODING(v1, UTF8_STRING_NO_LENGTH)\n  PARSE_ENCODING(v1, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)\n  PARSE_ENCODING(v1, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)\n  PARSE_ENCODING(v1, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)\n  PARSE_ENCODING(v1, RFC3339_DATE_INTEGER_TRIPLET)\n  PARSE_ENCODING(v1, PREFIX_VARINT_LENGTH_STRING_SHARED)\n  // Arrays\n  PARSE_ENCODING(v1, FIXED_TYPED_ARRAY)\n  PARSE_ENCODING(v1, BOUNDED_8BITS_TYPED_ARRAY)\n  PARSE_ENCODING(v1, FLOOR_TYPED_ARRAY)\n  PARSE_ENCODING(v1, ROOF_TYPED_ARRAY)\n\n  // TODO: Handle object encodings\n\n#undef PARSE_ENCODING\n\n  std::ostringstream error;\n  error << \"Unrecognized encoding: \" << encoding;\n  throw EncodingError(error.str());\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/loader_v1_any.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_ANY_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_ANY_H_\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <cassert> // assert\n#include <utility> // std::move\n#include <vector>  // std::vector\n\nnamespace sourcemeta::jsonbinpack::v1 {\n\nauto BYTE_CHOICE_INDEX(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"choices\"));\n  const auto &choices{options.at(\"choices\")};\n  assert(choices.is_array());\n  const auto &array{choices.as_array()};\n  std::vector<sourcemeta::core::JSON> elements{array.cbegin(), array.cend()};\n  return sourcemeta::jsonbinpack::BYTE_CHOICE_INDEX{.choices =\n                                                        std::move(elements)};\n}\n\nauto LARGE_CHOICE_INDEX(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"choices\"));\n  const auto &choices{options.at(\"choices\")};\n  assert(choices.is_array());\n  const auto &array{choices.as_array()};\n  std::vector<sourcemeta::core::JSON> elements{array.cbegin(), array.cend()};\n  return sourcemeta::jsonbinpack::LARGE_CHOICE_INDEX{.choices =\n                                                         std::move(elements)};\n}\n\nauto TOP_LEVEL_BYTE_CHOICE_INDEX(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"choices\"));\n  const auto &choices{options.at(\"choices\")};\n  assert(choices.is_array());\n  const auto &array{choices.as_array()};\n  std::vector<sourcemeta::core::JSON> elements{array.cbegin(), array.cend()};\n  return sourcemeta::jsonbinpack::TOP_LEVEL_BYTE_CHOICE_INDEX{\n      .choices = std::move(elements)};\n}\n\nauto CONST_NONE(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"value\"));\n  return sourcemeta::jsonbinpack::CONST_NONE{.value = options.at(\"value\")};\n}\n\nauto ANY_PACKED_TYPE_TAG_BYTE_PREFIX(const sourcemeta::core::JSON &)\n    -> Encoding {\n  return sourcemeta::jsonbinpack::ANY_PACKED_TYPE_TAG_BYTE_PREFIX{};\n}\n\n} // namespace sourcemeta::jsonbinpack::v1\n\n#endif\n"
  },
  {
    "path": "src/runtime/loader_v1_array.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_ARRAY_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_ARRAY_H_\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <algorithm> // std::transform\n#include <cassert>   // assert\n#include <cstdint>   // std::uint64_t\n#include <iterator>  // std::back_inserter\n#include <memory>    // std::make_shared\n#include <vector>    // std::vector\n\nnamespace sourcemeta::jsonbinpack::v1 {\n\nauto FIXED_TYPED_ARRAY(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"size\"));\n  assert(options.defines(\"encoding\"));\n  assert(options.defines(\"prefixEncodings\"));\n  const auto &size{options.at(\"size\")};\n  const auto &array_encoding{options.at(\"encoding\")};\n  const auto &prefix_encodings{options.at(\"prefixEncodings\")};\n  assert(size.is_integer());\n  assert(size.is_positive());\n  assert(array_encoding.is_object());\n  assert(prefix_encodings.is_array());\n  std::vector<Encoding> encodings;\n  std::transform(prefix_encodings.as_array().cbegin(),\n                 prefix_encodings.as_array().cend(),\n                 std::back_inserter(encodings),\n                 [](const auto &element) { return load(element); });\n  assert(encodings.size() == prefix_encodings.size());\n  return sourcemeta::jsonbinpack::FIXED_TYPED_ARRAY{\n      .size = static_cast<std::uint64_t>(size.to_integer()),\n      .encoding = std::make_shared<Encoding>(load(array_encoding)),\n      .prefix_encodings = std::move(encodings)};\n}\n\nauto BOUNDED_8BITS_TYPED_ARRAY(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"minimum\"));\n  assert(options.defines(\"maximum\"));\n  assert(options.defines(\"encoding\"));\n  assert(options.defines(\"prefixEncodings\"));\n  const auto &minimum{options.at(\"minimum\")};\n  const auto &maximum{options.at(\"maximum\")};\n  const auto &array_encoding{options.at(\"encoding\")};\n  const auto &prefix_encodings{options.at(\"prefixEncodings\")};\n  assert(minimum.is_integer());\n  assert(maximum.is_integer());\n  assert(minimum.is_positive());\n  assert(maximum.is_positive());\n  assert(array_encoding.is_object());\n  assert(prefix_encodings.is_array());\n  std::vector<Encoding> encodings;\n  std::transform(prefix_encodings.as_array().cbegin(),\n                 prefix_encodings.as_array().cend(),\n                 std::back_inserter(encodings),\n                 [](const auto &element) { return load(element); });\n  assert(encodings.size() == prefix_encodings.size());\n  return sourcemeta::jsonbinpack::BOUNDED_8BITS_TYPED_ARRAY{\n      .minimum = static_cast<std::uint64_t>(minimum.to_integer()),\n      .maximum = static_cast<std::uint64_t>(maximum.to_integer()),\n      .encoding = std::make_shared<Encoding>(load(array_encoding)),\n      .prefix_encodings = std::move(encodings)};\n}\n\nauto FLOOR_TYPED_ARRAY(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"minimum\"));\n  assert(options.defines(\"encoding\"));\n  assert(options.defines(\"prefixEncodings\"));\n  const auto &minimum{options.at(\"minimum\")};\n  const auto &array_encoding{options.at(\"encoding\")};\n  const auto &prefix_encodings{options.at(\"prefixEncodings\")};\n  assert(minimum.is_integer());\n  assert(minimum.is_positive());\n  assert(array_encoding.is_object());\n  assert(prefix_encodings.is_array());\n  std::vector<Encoding> encodings;\n  std::transform(prefix_encodings.as_array().cbegin(),\n                 prefix_encodings.as_array().cend(),\n                 std::back_inserter(encodings),\n                 [](const auto &element) { return load(element); });\n  assert(encodings.size() == prefix_encodings.size());\n  return sourcemeta::jsonbinpack::FLOOR_TYPED_ARRAY{\n      .minimum = static_cast<std::uint64_t>(minimum.to_integer()),\n      .encoding = std::make_shared<Encoding>(load(array_encoding)),\n      .prefix_encodings = std::move(encodings)};\n}\n\nauto ROOF_TYPED_ARRAY(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"maximum\"));\n  assert(options.defines(\"encoding\"));\n  assert(options.defines(\"prefixEncodings\"));\n  const auto &maximum{options.at(\"maximum\")};\n  const auto &array_encoding{options.at(\"encoding\")};\n  const auto &prefix_encodings{options.at(\"prefixEncodings\")};\n  assert(maximum.is_integer());\n  assert(maximum.is_positive());\n  assert(array_encoding.is_object());\n  assert(prefix_encodings.is_array());\n  std::vector<Encoding> encodings;\n  std::transform(prefix_encodings.as_array().cbegin(),\n                 prefix_encodings.as_array().cend(),\n                 std::back_inserter(encodings),\n                 [](const auto &element) { return load(element); });\n  assert(encodings.size() == prefix_encodings.size());\n  return sourcemeta::jsonbinpack::ROOF_TYPED_ARRAY{\n      .maximum = static_cast<std::uint64_t>(maximum.to_integer()),\n      .encoding = std::make_shared<Encoding>(load(array_encoding)),\n      .prefix_encodings = std::move(encodings)};\n}\n\n} // namespace sourcemeta::jsonbinpack::v1\n\n#endif\n"
  },
  {
    "path": "src/runtime/loader_v1_integer.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_INTEGER_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_INTEGER_H_\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint64_t\n\nnamespace sourcemeta::jsonbinpack::v1 {\n\nauto BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"minimum\"));\n  assert(options.defines(\"maximum\"));\n  assert(options.defines(\"multiplier\"));\n  const auto &minimum{options.at(\"minimum\")};\n  const auto &maximum{options.at(\"maximum\")};\n  const auto &multiplier{options.at(\"multiplier\")};\n  assert(minimum.is_integer());\n  assert(maximum.is_integer());\n  assert(multiplier.is_integer());\n  assert(multiplier.is_positive());\n  return sourcemeta::jsonbinpack::BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{\n      .minimum = minimum.to_integer(),\n      .maximum = maximum.to_integer(),\n      .multiplier = static_cast<std::uint64_t>(multiplier.to_integer())};\n}\n\nauto FLOOR_MULTIPLE_ENUM_VARINT(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"minimum\"));\n  assert(options.defines(\"multiplier\"));\n  const auto &minimum{options.at(\"minimum\")};\n  const auto &multiplier{options.at(\"multiplier\")};\n  assert(minimum.is_integer());\n  assert(multiplier.is_integer());\n  assert(multiplier.is_positive());\n  return sourcemeta::jsonbinpack::FLOOR_MULTIPLE_ENUM_VARINT{\n      .minimum = minimum.to_integer(),\n      .multiplier = static_cast<std::uint64_t>(multiplier.to_integer())};\n}\n\nauto ROOF_MULTIPLE_MIRROR_ENUM_VARINT(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"maximum\"));\n  assert(options.defines(\"multiplier\"));\n  const auto &maximum{options.at(\"maximum\")};\n  const auto &multiplier{options.at(\"multiplier\")};\n  assert(maximum.is_integer());\n  assert(multiplier.is_integer());\n  assert(multiplier.is_positive());\n  return sourcemeta::jsonbinpack::ROOF_MULTIPLE_MIRROR_ENUM_VARINT{\n      .maximum = maximum.to_integer(),\n      .multiplier = static_cast<std::uint64_t>(multiplier.to_integer())};\n}\n\nauto ARBITRARY_MULTIPLE_ZIGZAG_VARINT(const sourcemeta::core::JSON &options)\n    -> Encoding {\n  assert(options.defines(\"multiplier\"));\n  const auto &multiplier{options.at(\"multiplier\")};\n  assert(multiplier.is_integer());\n  assert(multiplier.is_positive());\n  return sourcemeta::jsonbinpack::ARBITRARY_MULTIPLE_ZIGZAG_VARINT{\n      .multiplier = static_cast<std::uint64_t>(multiplier.to_integer())};\n}\n\n} // namespace sourcemeta::jsonbinpack::v1\n\n#endif\n"
  },
  {
    "path": "src/runtime/loader_v1_number.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_NUMBER_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_NUMBER_H_\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\nnamespace sourcemeta::jsonbinpack::v1 {\n\nauto DOUBLE_VARINT_TUPLE(const sourcemeta::core::JSON &) -> Encoding {\n  return sourcemeta::jsonbinpack::DOUBLE_VARINT_TUPLE{};\n}\n\n} // namespace sourcemeta::jsonbinpack::v1\n\n#endif\n"
  },
  {
    "path": "src/runtime/loader_v1_string.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_STRING_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_LOADER_V1_STRING_H_\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint64_t\n\nnamespace sourcemeta::jsonbinpack::v1 {\n\nauto UTF8_STRING_NO_LENGTH(const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"size\"));\n  const auto &size{options.at(\"size\")};\n  assert(size.is_integer());\n  assert(size.is_positive());\n  return sourcemeta::jsonbinpack::UTF8_STRING_NO_LENGTH{\n      .size = static_cast<std::uint64_t>(size.to_integer())};\n}\n\nauto FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"minimum\"));\n  const auto &minimum{options.at(\"minimum\")};\n  assert(minimum.is_integer());\n  assert(minimum.is_positive());\n  return sourcemeta::jsonbinpack::FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED{\n      .minimum = static_cast<std::uint64_t>(minimum.to_integer())};\n}\n\nauto ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"maximum\"));\n  const auto &maximum{options.at(\"maximum\")};\n  assert(maximum.is_integer());\n  assert(maximum.is_positive());\n  return sourcemeta::jsonbinpack::ROOF_VARINT_PREFIX_UTF8_STRING_SHARED{\n      .maximum = static_cast<std::uint64_t>(maximum.to_integer())};\n}\n\nauto BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(\n    const sourcemeta::core::JSON &options) -> Encoding {\n  assert(options.defines(\"minimum\"));\n  assert(options.defines(\"maximum\"));\n  const auto &minimum{options.at(\"minimum\")};\n  const auto &maximum{options.at(\"maximum\")};\n  assert(minimum.is_integer());\n  assert(maximum.is_integer());\n  assert(minimum.is_positive());\n  assert(maximum.is_positive());\n  return sourcemeta::jsonbinpack::BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED{\n      .minimum = static_cast<std::uint64_t>(minimum.to_integer()),\n      .maximum = static_cast<std::uint64_t>(maximum.to_integer())};\n}\n\nauto RFC3339_DATE_INTEGER_TRIPLET(const sourcemeta::core::JSON &) -> Encoding {\n  return sourcemeta::jsonbinpack::RFC3339_DATE_INTEGER_TRIPLET{};\n}\n\nauto PREFIX_VARINT_LENGTH_STRING_SHARED(const sourcemeta::core::JSON &)\n    -> Encoding {\n  return sourcemeta::jsonbinpack::PREFIX_VARINT_LENGTH_STRING_SHARED{};\n}\n\n} // namespace sourcemeta::jsonbinpack::v1\n\n#endif\n"
  },
  {
    "path": "src/runtime/output_stream.cc",
    "content": "#include <sourcemeta/jsonbinpack/runtime_output_stream.h>\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t, std::uint64_t, std::int64_t\n\nnamespace sourcemeta::jsonbinpack {\n\nOutputStream::OutputStream(Stream &output)\n    : sourcemeta::core::BinaryWriter{output} {}\n\nauto OutputStream::put_varint(const std::uint64_t value) -> void {\n  constexpr std::uint8_t LEAST_SIGNIFICANT_BITS{0b01111111};\n  constexpr std::uint8_t MOST_SIGNIFICANT_BIT{0b10000000};\n  constexpr std::uint8_t SHIFT{7};\n  std::uint64_t accumulator = value;\n\n  while (accumulator > LEAST_SIGNIFICANT_BITS) {\n    this->put_byte(static_cast<std::uint8_t>(\n        (accumulator & LEAST_SIGNIFICANT_BITS) | MOST_SIGNIFICANT_BIT));\n    accumulator >>= SHIFT;\n  }\n\n  this->put_byte(static_cast<std::uint8_t>(accumulator));\n}\n\nauto OutputStream::put_varint_zigzag(const std::int64_t value) -> void {\n  this->put_varint(sourcemeta::core::zigzag_encode(value));\n}\n\nauto OutputStream::put_string_utf8(const sourcemeta::core::JSON::String &string,\n                                   const std::uint64_t length) -> void {\n  assert(string.size() == length);\n  // Do a manual for-loop based on the provided length instead of a range\n  // loop based on the string value to avoid accidental overflows\n  for (std::uint64_t index = 0; index < length; index++) {\n    this->put_byte(static_cast<std::uint8_t>(string[index]));\n  }\n}\n\n} // namespace sourcemeta::jsonbinpack\n"
  },
  {
    "path": "src/runtime/unreachable.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_UNREACHABLE_H_\n#define SOURCEMETA_JSONBINPACK_RUNTIME_UNREACHABLE_H_\n\n#include <cassert> // assert\n\n// Until we are on C++23 and can use std::unreachable\n// See https://en.cppreference.com/w/cpp/utility/unreachable\n[[noreturn]] inline void unreachable() {\n  assert(false);\n#if defined(_MSC_VER) && !defined(__clang__)\n  __assume(false);\n#else\n  __builtin_unreachable();\n#endif\n}\n\n#endif\n"
  },
  {
    "path": "test/compiler/2020_12_compiler_any_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/compiler.h>\n\nTEST(JSONBinPack_Compiler_Any_2020_12, enum_singleton) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"enum\": [ 2 ]\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"CONST_NONE\",\n    \"binpackOptions\": {\n      \"value\": 2\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Any_2020_12, const_scalar) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"const\": 2\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"CONST_NONE\",\n    \"binpackOptions\": {\n      \"value\": 2\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Any_2020_12, enum_small_top_level) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"enum\": [ 1, 2, 3 ]\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"TOP_LEVEL_BYTE_CHOICE_INDEX\",\n    \"binpackOptions\": {\n      \"choices\": [ 1, 2, 3 ]\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Any_2020_12, only_metaschema) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Any_2020_12, empty) {\n  auto schema = sourcemeta::core::parse_json(\"{}\");\n\n  sourcemeta::jsonbinpack::compile(\n      schema, sourcemeta::core::schema_walker,\n      sourcemeta::core::schema_resolver,\n      \"https://json-schema.org/draft/2020-12/schema\");\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n"
  },
  {
    "path": "test/compiler/2020_12_compiler_integer_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/compiler.h>\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, maximum_minimum_8_bit) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": -100,\n    \"maximum\": 100\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\",\n    \"binpackOptions\": {\n      \"minimum\": -100,\n      \"maximum\": 100,\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, maximum_minimum_multiplier_8_bit) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": -100,\n    \"maximum\": 100,\n    \"multipleOf\": 5\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\",\n    \"binpackOptions\": {\n      \"minimum\": -100,\n      \"maximum\": 100,\n      \"multiplier\": 5\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, maximum_minimum_greater_than_8_bit) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": -100,\n    \"maximum\": 100000\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_MULTIPLE_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"minimum\": -100,\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12,\n     maximum_minimum_multiplier_greater_than_8_bit) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": -100,\n    \"maximum\": 10000,\n    \"multipleOf\": 5\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_MULTIPLE_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"minimum\": -100,\n      \"multiplier\": 5\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, minimum) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": 0\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_MULTIPLE_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"minimum\": 0,\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, minimum_multiplier) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": 0,\n    \"multipleOf\": 5\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_MULTIPLE_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"minimum\": 0,\n      \"multiplier\": 5\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, maximum) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"maximum\": 100\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ROOF_MULTIPLE_MIRROR_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"maximum\": 100,\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, maximum_multiplier) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"maximum\": 100,\n    \"multipleOf\": 5\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ROOF_MULTIPLE_MIRROR_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"maximum\": 100,\n      \"multiplier\": 5\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, unbounded) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n    \"binpackOptions\": {\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler_Integer_2020_12, unbounded_multiplier) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"multipleOf\": 5\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n    \"binpackOptions\": {\n      \"multiplier\": 5\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n"
  },
  {
    "path": "test/compiler/2020_12_compiler_number_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/compiler.h>\n\nTEST(JSONBinPack_Compiler_Number_2020_12, arbitrary) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"number\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n"
  },
  {
    "path": "test/compiler/CMakeLists.txt",
    "content": "sourcemeta_googletest(NAMESPACE sourcemeta PROJECT jsonbinpack NAME compiler\n  FOLDER \"JSON BinPack/Compiler\"\n  SOURCES\n    canonicalizer_test.cc compiler_test.cc\n\n    2020_12_compiler_any_test.cc\n    2020_12_compiler_integer_test.cc\n    2020_12_compiler_number_test.cc)\n\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler_unit\n  PRIVATE sourcemeta::jsonbinpack::compiler)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler_unit\n  PRIVATE sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_jsonbinpack_compiler_unit\n  PRIVATE sourcemeta::core::jsonschema)\n"
  },
  {
    "path": "test/compiler/canonicalizer_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n#include <sourcemeta/jsonbinpack/compiler.h>\n\n#include <optional> // std::optional\n#include <string>   // std::string\n\nstatic auto test_resolver(std::string_view identifier)\n    -> std::optional<sourcemeta::core::JSON> {\n  if (identifier == \"https://jsonbinpack.sourcemeta.com/draft/unknown\") {\n    return sourcemeta::core::parse_json(R\"JSON({\n        \"$schema\": \"https://jsonbinpack.sourcemeta.com/draft/unknown\",\n        \"$id\": \"https://jsonbinpack.sourcemeta.com/draft/unknown\"\n      })JSON\");\n  } else {\n    return sourcemeta::core::schema_resolver(identifier);\n  }\n}\n\nTEST(JSONBinPack_Canonicalizer, unsupported_draft) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://jsonbinpack.sourcemeta.com/draft/unknown\",\n    \"type\": \"boolean\"\n  })JSON\");\n\n  EXPECT_THROW(sourcemeta::jsonbinpack::canonicalize(\n                   schema, sourcemeta::core::schema_walker, test_resolver),\n               sourcemeta::core::SchemaUnknownBaseDialectError);\n}\n\nTEST(JSONBinPack_Canonicalizer, unknown_draft) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"type\": \"boolean\"\n  })JSON\");\n\n  EXPECT_THROW(sourcemeta::jsonbinpack::canonicalize(\n                   schema, sourcemeta::core::schema_walker, test_resolver,\n                   \"https://example.com/invalid\"),\n               sourcemeta::core::SchemaResolutionError);\n}\n"
  },
  {
    "path": "test/compiler/compiler_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/compiler.h>\n\n#include <stdexcept>\n\nTEST(JSONBinPack_Compiler, dialect_2020_12) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_2019_09) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft7) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft6) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-06/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft4) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-04/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft3) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-03/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft2) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-02/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft1) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-01/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, dialect_draft0) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"http://json-schema.org/draft-00/schema#\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, unknown_dialect_default) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"type\": \"integer\"\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(\n      schema, sourcemeta::core::schema_walker,\n      sourcemeta::core::schema_resolver,\n      \"https://json-schema.org/draft/2020-12/schema\");\n\n  const auto expected = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n    \"binpackOptions\": {\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  EXPECT_EQ(schema, expected);\n}\n\nTEST(JSONBinPack_Compiler, unknown_dialect_without_default) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"type\": \"integer\"\n  })JSON\");\n\n  EXPECT_THROW(\n      sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                       sourcemeta::core::schema_resolver),\n      sourcemeta::core::SchemaUnknownBaseDialectError);\n}\n\nTEST(JSONBinPack_Compiler, invalid_dialect) {\n  auto schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://foo.com\",\n    \"type\": \"integer\"\n  })JSON\");\n\n  EXPECT_THROW(\n      sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                       sourcemeta::core::schema_resolver),\n      sourcemeta::core::SchemaResolutionError);\n}\n"
  },
  {
    "path": "test/e2e/CMakeLists.txt",
    "content": "add_executable(jsonbinpack_e2e_test_runner runner.cc)\nsourcemeta_add_default_options(PRIVATE jsonbinpack_e2e_test_runner)\ntarget_link_libraries(jsonbinpack_e2e_test_runner PRIVATE sourcemeta::core::json)\ntarget_link_libraries(jsonbinpack_e2e_test_runner PRIVATE sourcemeta::jsonbinpack::compiler)\ntarget_link_libraries(jsonbinpack_e2e_test_runner PRIVATE sourcemeta::jsonbinpack::runtime)\nset_target_properties(jsonbinpack_e2e_test_runner\n  PROPERTIES FOLDER \"JSON BinPack/E2E\")\n\nmacro(add_jsonbinpack_e2e_test_schemaless name)\n  add_test(NAME JSONBinPack.e2e.${name}.schema-less\n    COMMAND \"$<TARGET_FILE:jsonbinpack_e2e_test_runner>\"\n    \"${CMAKE_CURRENT_SOURCE_DIR}/${name}/document.json\"\n    \"${CMAKE_CURRENT_SOURCE_DIR}/${name}/schema-less\")\nendmacro()\n\nmacro(add_jsonbinpack_e2e_test name)\n  add_jsonbinpack_e2e_test_schemaless(${name})\n  # TODO: Test schema-driven too\nendmacro()\n\nadd_jsonbinpack_e2e_test(circleciblank)\nadd_jsonbinpack_e2e_test(circlecimatrix)\nadd_jsonbinpack_e2e_test(commitlint)\nadd_jsonbinpack_e2e_test(commitlintbasic)\nadd_jsonbinpack_e2e_test(epr)\nadd_jsonbinpack_e2e_test(eslintrc)\nadd_jsonbinpack_e2e_test(esmrc)\nadd_jsonbinpack_e2e_test(geojson)\nadd_jsonbinpack_e2e_test(githubfundingblank)\nadd_jsonbinpack_e2e_test(githubworkflow)\nadd_jsonbinpack_e2e_test(gruntcontribclean)\nadd_jsonbinpack_e2e_test(imageoptimizerwebjob)\nadd_jsonbinpack_e2e_test(jsonereversesort)\nadd_jsonbinpack_e2e_test(jsonesort)\nadd_jsonbinpack_e2e_test(jsonfeed)\n# TODO: This case regresses and we are beaten by Smile. Should be 2612\nadd_jsonbinpack_e2e_test(jsonresume)\nadd_jsonbinpack_e2e_test(mixed-bounded-object)\nadd_jsonbinpack_e2e_test(netcoreproject)\nadd_jsonbinpack_e2e_test(nightwatch)\nadd_jsonbinpack_e2e_test(openweathermap)\nadd_jsonbinpack_e2e_test(openweatherroadrisk)\nadd_jsonbinpack_e2e_test(ox-test)\nadd_jsonbinpack_e2e_test(packagejson)\nadd_jsonbinpack_e2e_test(packagejsonlintrc)\nadd_jsonbinpack_e2e_test(sapcloudsdkpipeline)\nadd_jsonbinpack_e2e_test(travisnotifications)\nadd_jsonbinpack_e2e_test(tslintbasic)\nadd_jsonbinpack_e2e_test(tslintextend)\nadd_jsonbinpack_e2e_test(tslintmulti)\n"
  },
  {
    "path": "test/e2e/circleciblank/document.json",
    "content": "{\n  \"version\": 2.0\n}\n"
  },
  {
    "path": "test/e2e/circleciblank/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/circleciblank/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/circleciblank/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/circleciblank/schema-less/size.txt",
    "content": "11\n"
  },
  {
    "path": "test/e2e/circlecimatrix/document.json",
    "content": "{\n  \"version\": 2.1,\n  \"workflows\": {\n    \"test\": {\n      \"jobs\": [\n        {\n          \"m1\": {\n            \"matrix\": {\n              \"parameters\": {\n                \"a\": [1, 2, 3]\n              }\n            }\n          }\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/circlecimatrix/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/circlecimatrix/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/circlecimatrix/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/circlecimatrix/schema-less/size.txt",
    "content": "66\n"
  },
  {
    "path": "test/e2e/commitlint/document.json",
    "content": "{\n  \"rules\": {\n    \"scope-case\": [2, \"always\", [\"lower-case\"]],\n    \"subject-case\": [2, \"always\", [\"lower-case\"]]\n  }\n}\n"
  },
  {
    "path": "test/e2e/commitlint/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/commitlint/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/commitlint/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/commitlint/schema-less/size.txt",
    "content": "60\n"
  },
  {
    "path": "test/e2e/commitlintbasic/document.json",
    "content": "{\n  \"defaultIgnores\": false\n}\n"
  },
  {
    "path": "test/e2e/commitlintbasic/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/commitlintbasic/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/commitlintbasic/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/commitlintbasic/schema-less/size.txt",
    "content": "17\n"
  },
  {
    "path": "test/e2e/epr/document.json",
    "content": "{\n\t\"site\": \"https://eample.com\",\n\t\"maxAge\": 31536000,\n\t\"reportUrl\": \"https://example.com\",\n\t\"defaultNavBehavior\": \"block\",\n\t\"defaultResBehavior\": \"block\",\n\t\"rules\": [\n\t\t{ \"path\": \"/\", \"types\": [ \"navigation\" ], \"allowData\": false },\n\t\t{ \"regex\": \"^/\\\\d+$\", \"types\": [ \"navigation\" ], \"allowData\": false },\n\t\t{ \"path\": \"/image\", \"types\": [ \"image\" ], \"allowData\": true },\n\t\t{ \"regex\": \"^/(scoreboard|random|favorites|recentvisits|create)$\", \"types\": [ \"navigation\" ], \"allowData\": false },\n\t\t{ \"regex\": \"^/(recent|popular|metrics|template|search)$\", \"types\": [ \"navigation\" ], \"allowData\": true }\n\t]\n}\n"
  },
  {
    "path": "test/e2e/epr/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/epr/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/epr/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/epr/schema-less/size.txt",
    "content": "321\n"
  },
  {
    "path": "test/e2e/eslintrc/document.json",
    "content": "{\n\t\"extends\": \"defaults/configurations/eslint\",\n\t\"parser\": \"babel-eslint\",\n\t\"ecmaFeatures\": {\n\t\t\"jsx\": true\n\t},\n\t\"plugins\": [\n\t\t\"react\"\n\t],\n\t\"env\": {\n\t\t\"browser\": true,\n\t\t\"node\": true,\n\t\t\"es6\": true\n\t},\n\t\"rules\": {\n\n\t\t\"eqeqeq\": 2,\n\t\t\"comma-dangle\": 1,\n\t\t\"no-console\": 0,\n\t\t\"no-debugger\": 1,\n\t\t\"no-extra-semi\": 1,\n\t\t\"no-extra-parens\": 1,\n\t\t\"no-irregular-whitespace\": 0,\n\t\t\"no-undef\": 0,\n\t\t\"no-unused-vars\": 0,\n\t\t\"semi\": 1,\n\t\t\"semi-spacing\": 1,\n\t\t\"valid-jsdoc\": [\n\t\t\t2,\n\t\t\t{ \"requireReturn\": false }\n\t\t],\n\n\t\t\"react/display-name\": 2,\n\t\t\"react/forbid-prop-types\": 1,\n\t\t\"react/jsx-boolean-value\": 1,\n\t\t\"react/jsx-closing-bracket-location\": 1,\n\t\t\"react/jsx-curly-spacing\": 1,\n\t\t\"react/jsx-indent-props\": 1,\n\t\t\"react/jsx-max-props-per-line\": 1,\n\t\t\"react/jsx-no-duplicate-props\": 1,\n\t\t\"react/jsx-no-literals\": 0,\n\t\t\"react/jsx-no-undef\": 1,\n\t\t\"react/jsx-sort-prop-types\": 1,\n\t\t\"react/jsx-sort-props\": 1,\n\t\t\"react/jsx-uses-react\": 1,\n\t\t\"react/jsx-uses-vars\": 1,\n\t\t\"react/no-danger\": 1,\n\t\t\"react/no-did-mount-set-state\": 1,\n\t\t\"react/no-did-update-set-state\": 1,\n\t\t\"react/no-direct-mutation-state\": 1,\n\t\t\"react/no-multi-comp\": 1,\n\t\t\"react/no-set-state\": 1,\n\t\t\"react/no-unknown-property\": 1,\n\t\t\"react/prop-types\": 1,\n\t\t\"react/react-in-jsx-scope\": 0,\n\t\t\"react/require-extension\": 1,\n\t\t\"react/self-closing-comp\": 1,\n\t\t\"react/sort-comp\": 1,\n\t\t\"react/wrap-multilines\": 1\n\t}\n}\n"
  },
  {
    "path": "test/e2e/eslintrc/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/eslintrc/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/eslintrc/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/eslintrc/schema-less/size.txt",
    "content": "969\n"
  },
  {
    "path": "test/e2e/esmrc/document.json",
    "content": "{\n  \"cjs\": false,\n  \"mainFields\": [\n    \"main\",\n    \"app\"\n  ],\n  \"mode\": \"strict\",\n  \"force\": true,\n  \"cache\": false,\n  \"sourceMap\": true\n}\n"
  },
  {
    "path": "test/e2e/esmrc/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/esmrc/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/esmrc/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/esmrc/schema-less/size.txt",
    "content": "64\n"
  },
  {
    "path": "test/e2e/geojson/document.json",
    "content": "{\n  \"type\": \"MultiPolygon\",\n  \"coordinates\": [\n    [\n      [\n        [102.0, 2.0],\n        [103.0, 2.0],\n        [103.0, 3.0],\n        [102.0, 3.0],\n        [102.0, 2.0]\n      ]\n    ],\n    [\n      [\n        [100.0, 0.0],\n        [101.0, 0.0],\n        [101.0, 1.0],\n        [100.0, 1.0],\n        [100.0, 0.0]\n      ],\n      [\n        [100.2, 0.2],\n        [100.2, 0.8],\n        [100.8, 0.8],\n        [100.8, 0.2],\n        [100.2, 0.2]\n      ]\n    ]\n  ]\n}\n"
  },
  {
    "path": "test/e2e/geojson/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/geojson/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/geojson/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/geojson/schema-less/size.txt",
    "content": "127\n"
  },
  {
    "path": "test/e2e/githubfundingblank/document.json",
    "content": "{\n  \"github\": \"EbookFoundation\",\n  \"patreon\": null,\n  \"open_collective\": null,\n  \"ko_fi\": null,\n  \"tidelift\": null,\n  \"community_bridge\": null,\n  \"liberapay\": null,\n  \"issuehunt\": null,\n  \"otechie\": null,\n  \"custom\": null\n}\n"
  },
  {
    "path": "test/e2e/githubfundingblank/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/githubfundingblank/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/githubfundingblank/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/githubfundingblank/schema-less/size.txt",
    "content": "124\n"
  },
  {
    "path": "test/e2e/githubworkflow/document.json",
    "content": "{\n  \"name\": \"Test on Pull\",\n  \"on\": [\n    \"push\"\n  ],\n  \"jobs\": {\n    \"build\": {\n      \"runs-on\": \"ubuntu-latest\",\n      \"env\": {\n        \"build-suite-dir\": \"./build-suite\"\n      },\n      \"steps\": [\n        {\n          \"uses\": \"actions/checkout@v1\"\n        },\n        {\n          \"uses\": \"actions/setup-node@v1\",\n          \"with\": {\n            \"node-version\": \"10.x\"\n          }\n        },\n        {\n          \"name\": \"starting directory\",\n          \"run\": \"ls\"\n        },\n        {\n          \"name\": \"build directory\",\n          \"run\": \"ls\",\n          \"working-directory\": \"${{env.build-suite-dir}}\"\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/githubworkflow/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/githubworkflow/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/githubworkflow/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/githubworkflow/schema-less/size.txt",
    "content": "277\n"
  },
  {
    "path": "test/e2e/gruntcontribclean/document.json",
    "content": "{\n\t\"foo\": [ \"path\" ],\n\t\"main\": {\n\t\t\"files\": { },\n\t\t\"src\": [ \"path\" ]\n\t},\n\t\"options\": {\n\t\t\"force\": true,\n\t\t\"no-write\": true\n\t}\n}\n"
  },
  {
    "path": "test/e2e/gruntcontribclean/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/gruntcontribclean/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/gruntcontribclean/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/gruntcontribclean/schema-less/size.txt",
    "content": "57\n"
  },
  {
    "path": "test/e2e/imageoptimizerwebjob/document.json",
    "content": "{\n  \"optimizations\": [\n    {\n      \"includes\": [ \"node_modules\" ],\n      \"excludes\": [ \"ost\" ],\n      \"lossy\": true\n    }\n  ]\n}\n"
  },
  {
    "path": "test/e2e/imageoptimizerwebjob/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/imageoptimizerwebjob/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/imageoptimizerwebjob/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/imageoptimizerwebjob/schema-less/size.txt",
    "content": "61\n"
  },
  {
    "path": "test/e2e/jsonereversesort/document.json",
    "content": "{\n  \"$let\": {\n    \"x\": [10,30,10,10,10]\n  },\n  \"in\": {\n    \"$reverse\": {\n      \"$sort\": { \"$eval\": \"x\" },\n      \"by(x)\": \"x\"\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/jsonereversesort/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/jsonereversesort/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/jsonereversesort/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/jsonereversesort/schema-less/size.txt",
    "content": "52\n"
  },
  {
    "path": "test/e2e/jsonesort/document.json",
    "content": "{\n  \"$sort\": [1,2,1,3,1],\n  \"by(x)\": \"x\"\n}\n"
  },
  {
    "path": "test/e2e/jsonesort/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/jsonesort/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/jsonesort/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/jsonesort/schema-less/size.txt",
    "content": "21\n"
  },
  {
    "path": "test/e2e/jsonfeed/document.json",
    "content": "{\n  \"version\": \"https://jsonfeed.org/version/1\",\n  \"user_comment\": \"This is a microblog feed. You can add this to your feed reader using the following URL: https://example.org/feed.json\",\n  \"title\": \"Brent Simmons’s Microblog\",\n  \"home_page_url\": \"https://example.org/\",\n  \"feed_url\": \"https://example.org/feed.json\",\n  \"author\": {\n    \"name\": \"Brent Simmons\",\n    \"url\": \"http://example.org/\",\n    \"avatar\": \"https://example.org/avatar.png\"\n  },\n  \"items\": [\n    {\n      \"id\": \"2347259\",\n      \"url\": \"https://example.org/2347259\",\n      \"content_text\": \"Cats are neat. \\n\\nhttps://example.org/cats\",\n      \"date_published\": \"2016-02-09T14:22:00-07:00\"\n    }\n  ]\n}\n"
  },
  {
    "path": "test/e2e/jsonfeed/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/jsonfeed/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/jsonfeed/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/jsonfeed/schema-less/size.txt",
    "content": "514\n"
  },
  {
    "path": "test/e2e/jsonresume/document.json",
    "content": "{\n  \"basics\": {\n    \"name\": \"Richard Hendriks\",\n    \"label\": \"Programmer\",\n    \"picture\": \"\",\n    \"email\": \"richard.hendriks@gmail.com\",\n    \"phone\": \"(912) 555-4321\",\n    \"website\": \"http://richardhendricks.com\",\n    \"summary\": \"Richard hails from Tulsa. He has earned degrees from the University of Oklahoma and Stanford. (Go Sooners and Cardinals!) Before starting Pied Piper, he worked for Hooli as a part time software developer. While his work focuses on applied information theory, mostly optimizing lossless compression schema of both the length-limited and adaptive variants, his non-work interests range widely, everything from quantum computing to chaos theory. He could tell you about it, but THAT would NOT be a “length-limited” conversation!\",\n    \"location\": {\n      \"address\": \"2712 Broadway St\",\n      \"postalCode\": \"CA 94115\",\n      \"city\": \"San Francisco\",\n      \"countryCode\": \"US\",\n      \"region\": \"California\"\n    },\n    \"profiles\": [\n      {\n        \"network\": \"Twitter\",\n        \"username\": \"neutralthoughts\",\n        \"url\": \"\"\n      },\n      {\n        \"network\": \"SoundCloud\",\n        \"username\": \"dandymusicnl\",\n        \"url\": \"https://soundcloud.com/dandymusicnl\"\n      }\n    ]\n  },\n  \"work\": [\n    {\n      \"company\": \"Pied Piper\",\n      \"position\": \"CEO/President\",\n      \"website\": \"http://piedpiper.com\",\n      \"startDate\": \"2013-12-01\",\n      \"endDate\": \"2014-12-01\",\n      \"summary\": \"Pied Piper is a multi-platform technology based on a proprietary universal compression algorithm that has consistently fielded high Weisman Scores™ that are not merely competitive, but approach the theoretical limit of lossless compression.\",\n      \"highlights\": [\n        \"Build an algorithm for artist to detect if their music was violating copy right infringement laws\",\n        \"Successfully won Techcrunch Disrupt\",\n        \"Optimized an algorithm that holds the current world record for Weisman Scores\"\n      ]\n    }\n  ],\n  \"volunteer\": [\n    {\n      \"organization\": \"CoderDojo\",\n      \"position\": \"Teacher\",\n      \"website\": \"http://coderdojo.com/\",\n      \"startDate\": \"2012-01-01\",\n      \"endDate\": \"2013-01-01\",\n      \"summary\": \"Global movement of free coding clubs for young people.\",\n      \"highlights\": [\n        \"Awarded 'Teacher of the Month'\"\n      ]\n    }\n  ],\n  \"education\": [\n    {\n      \"institution\": \"University of Oklahoma\",\n      \"area\": \"Information Technology\",\n      \"studyType\": \"Bachelor\",\n      \"startDate\": \"2011-06-01\",\n      \"endDate\": \"2014-01-01\",\n      \"gpa\": \"4.0\",\n      \"courses\": [\n        \"DB1101 - Basic SQL\",\n        \"CS2011 - Java Introduction\"\n      ]\n    }\n  ],\n  \"awards\": [\n    {\n      \"title\": \"Digital Compression Pioneer Award\",\n      \"date\": \"2014-11-01\",\n      \"awarder\": \"Techcrunch\",\n      \"summary\": \"There is no spoon.\"\n    }\n  ],\n  \"publications\": [\n    {\n      \"name\": \"Video compression for 3d media\",\n      \"publisher\": \"Hooli\",\n      \"releaseDate\": \"2014-10-01\",\n      \"website\": \"http://en.wikipedia.org/wiki/Silicon_Valley_(TV_series)\",\n      \"summary\": \"Innovative middle-out compression algorithm that changes the way we store data.\"\n    }\n  ],\n  \"skills\": [\n    {\n      \"name\": \"Web Development\",\n      \"level\": \"Master\",\n      \"keywords\": [\n        \"HTML\",\n        \"CSS\",\n        \"Javascript\"\n      ]\n    },\n    {\n      \"name\": \"Compression\",\n      \"level\": \"Master\",\n      \"keywords\": [\n        \"Mpeg\",\n        \"MP4\",\n        \"GIF\"\n      ]\n    }\n  ],\n  \"languages\": [\n    {\n      \"language\": \"English\",\n      \"fluency\": \"Native speaker\"\n    }\n  ],\n  \"interests\": [\n    {\n      \"name\": \"Wildlife\",\n      \"keywords\": [\n        \"Ferrets\",\n        \"Unicorns\"\n      ]\n    }\n  ],\n  \"references\": [\n    {\n      \"name\": \"Erlich Bachman\",\n      \"reference\": \"It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company.\"\n    }\n  ]\n}\n\n"
  },
  {
    "path": "test/e2e/jsonresume/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/jsonresume/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/jsonresume/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/jsonresume/schema-less/size.txt",
    "content": "2619\n"
  },
  {
    "path": "test/e2e/mixed-bounded-object/document.json",
    "content": "{\n  \"foo\": \"bar\",\n  \"baz\": {\n    \"qux\": [ 1, 2 ]\n  }\n}\n"
  },
  {
    "path": "test/e2e/mixed-bounded-object/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/mixed-bounded-object/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/mixed-bounded-object/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/mixed-bounded-object/schema-less/size.txt",
    "content": "21\n"
  },
  {
    "path": "test/e2e/netcoreproject/document.json",
    "content": "{\n\t\"version\": \"0.1-alpha-*\",\n\t\"compilationOptions\": {\n\t\t\"warningsAsErrors\": true\n\t},\n\t\"dependencies\": {\n\t\t\"Microsoft.Bcl.Immutable\": \"1.1.18-beta-*\",\n\t\t\"Microsoft.AspNet.ConfigurationModel\": \"0.1-alpha-*\",\n\t\t\"Microsoft.AspNet.DependencyInjection\": \"0.1-alpha-*\",\n\t\t\"Microsoft.AspNet.Logging\": \"0.1-alpha-*\",\n\t\t\"System.Data.Common\": \"0.1-alpha-*\"\n\t},\n\t\"code\": \"**\\\\*.cs;..\\\\Shared\\\\*.cs\",\n\t\"frameworks\": {\n\t\t\"net45\": {\n\t\t\t\"dependencies\": {\n\t\t\t\t\"System.Runtime\": \"\",\n\t\t\t\t\"System.Collections\": \"\"\n\t\t\t}\n\t\t},\n\t\t\"k10\": {\n\t\t\t\"dependencies\": {\n\t\t\t\t\"System.Collections\": \"4.0.0.0\",\n\t\t\t\t\"System.Collections.Concurrent\": \"4.0.0.0\",\n\t\t\t\t\"System.ComponentModel\": \"4.0.0.0\",\n\t\t\t\t\"System.Console\": \"4.0.0.0\",\n\t\t\t\t\"System.Diagnostics.Contracts\": \"4.0.0.0\",\n\t\t\t\t\"System.Diagnostics.Debug\": \"4.0.10.0\",\n\t\t\t\t\"System.Globalization\": \"4.0.10.0\",\n\t\t\t\t\"System.Linq\": \"4.0.0.0\",\n\t\t\t\t\"System.Linq.Expressions\": \"4.0.0.0\",\n\t\t\t\t\"System.Linq.Queryable\": \"4.0.0.0\",\n\t\t\t\t\"System.Reflection\": \"4.0.10.0\",\n\t\t\t\t\"System.Reflection.Extensions\": \"4.0.0.0\",\n\t\t\t\t\"System.Resources.ResourceManager\": \"4.0.0.0\",\n\t\t\t\t\"System.Runtime\": \"4.0.20.0\",\n\t\t\t\t\"System.Runtime.Extensions\": \"4.0.10.0\",\n\t\t\t\t\"System.Threading\": \"4.0.0.0\",\n\t\t\t\t\"System.Threading.Tasks\": \"4.0.10.0\"\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/e2e/netcoreproject/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/netcoreproject/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/netcoreproject/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/netcoreproject/schema-less/size.txt",
    "content": "748\n"
  },
  {
    "path": "test/e2e/nightwatch/document.json",
    "content": "{\n  \"custom_commands_path\": null,\n  \"custom_assertions_path\": null,\n  \"page_objects_path\": null,\n  \"globals_path\": null,\n  \"globals\": {\n    \"abortOnAssertionFailure\": true,\n    \"abortOnElementLocateError\": false,\n    \"waitForConditionPollInterval\": 500,\n    \"waitForConditionTimeout\": 5000,\n    \"throwOnMultipleElementsReturned\": false,\n    \"suppressWarningsOnMultipleElementsReturned\": false,\n    \"asyncHookTimeout\": 10000,\n    \"unitTestsTimeout\": 2000,\n    \"customReporterCallbackTimeout\": 20000,\n    \"retryAssertionTimeout\": 5000\n  },\n  \"dotenv\": {},\n  \"persist_globals\": false,\n  \"output_folder\": \"tests_output\",\n  \"src_folders\": null,\n  \"live_output\": false,\n  \"disable_colors\": false,\n  \"parallel_process_delay\": 10,\n  \"selenium\": {\n    \"start_process\": false,\n    \"cli_args\": {},\n    \"server_path\": null,\n    \"log_path\": \"\",\n    \"check_process_delay\": 500,\n    \"max_status_poll_tries\": 15,\n    \"status_poll_interval\": 200\n  },\n  \"start_session\": true,\n  \"end_session_on_fail\": true,\n  \"test_workers\": false,\n  \"test_runner\": \"default\",\n  \"webdriver\": {\n    \"start_process\": false,\n    \"cli_args\": {},\n    \"server_path\": null,\n    \"log_path\": \"\",\n    \"check_process_delay\": 100,\n    \"max_status_poll_tries\": 10,\n    \"status_poll_interval\": 200,\n    \"process_create_timeout\": 120000,\n    \"timeout_options\": {}\n  },\n  \"test_settings\": {},\n  \"launch_url\": \"\",\n  \"silent\": true,\n  \"output\": true,\n  \"detailed_output\": true,\n  \"output_timestamp\": false,\n  \"disable_error_log\": false,\n  \"screenshots\": false,\n  \"log_screenshot_data\": false,\n  \"desiredCapabilities\": {\n    \"browserName\": \"firefox\"\n  },\n  \"exclude\": null,\n  \"filter\": null,\n  \"skipgroup\": \"\",\n  \"sync_test_names\": true,\n  \"skiptags\": \"\",\n  \"use_xpath\": false,\n  \"parallel_mode\": false,\n  \"report_prefix\": \"\",\n  \"unit_tests_mode\": false,\n  \"default_reporter\": \"junit\"\n}\n"
  },
  {
    "path": "test/e2e/nightwatch/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/nightwatch/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/nightwatch/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/nightwatch/schema-less/size.txt",
    "content": "1085\n"
  },
  {
    "path": "test/e2e/openweathermap/document.json",
    "content": "{\n  \"coord\": {\n    \"lon\": -122.08,\n    \"lat\": 37.39\n  },\n  \"weather\": [\n    {\n      \"id\": 800,\n      \"main\": \"Clear\",\n      \"description\": \"clear sky\",\n      \"icon\": \"01d\"\n    }\n  ],\n  \"base\": \"stations\",\n  \"main\": {\n    \"temp\": 282.55,\n    \"feels_like\": 281.86,\n    \"temp_min\": 280.37,\n    \"temp_max\": 284.26,\n    \"pressure\": 1023,\n    \"humidity\": 100\n  },\n  \"visibility\": 16093,\n  \"wind\": {\n    \"speed\": 1.5,\n    \"deg\": 350\n  },\n  \"clouds\": {\n    \"all\": 1\n  },\n  \"dt\": 1560350645,\n  \"sys\": {\n    \"type\": 1,\n    \"id\": 5122,\n    \"message\": 0.0139,\n    \"country\": \"US\",\n    \"sunrise\": 1560343627,\n    \"sunset\": 1560396563\n  },\n  \"timezone\": -25200,\n  \"id\": 420006353,\n  \"name\": \"Mountain View\",\n  \"cod\": 200\n}\n"
  },
  {
    "path": "test/e2e/openweathermap/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/openweathermap/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/openweathermap/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/openweathermap/schema-less/size.txt",
    "content": "349\n"
  },
  {
    "path": "test/e2e/openweatherroadrisk/document.json",
    "content": "[\n  {\n    \"dt\": 1602702000,\n    \"coord\": [\n      7.27,\n      44.04\n    ],\n    \"weather\": {\n      \"temp\": 278.44,\n      \"wind_speed\": 2.27,\n      \"wind_deg\": 7,\n      \"precipitation_intensity\": 0.38,\n      \"dew_point\": 276.13\n    },\n    \"alerts\": [\n      {\n        \"sender_name\": \"METEO-FRANCE\",\n        \"event\": \"Moderate thunderstorm warning\",\n        \"event_level\": 2\n      }\n    ]\n  },\n  {\n    \"dt\": 1602702400,\n    \"coord\": [\n      7.37,\n      45.04\n    ],\n    \"weather\": {\n      \"temp\": 282.44,\n      \"wind_speed\": 1.84,\n      \"wind_deg\": 316,\n      \"dew_point\": 275.99\n    },\n    \"alerts\": [\n\n    ]\n  }\n]\n"
  },
  {
    "path": "test/e2e/openweatherroadrisk/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/openweatherroadrisk/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/openweatherroadrisk/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/openweatherroadrisk/schema-less/size.txt",
    "content": "254\n"
  },
  {
    "path": "test/e2e/ox-test/document.json",
    "content": "{\n  \"tags\": [],\n  \"tz\": -25200,\n  \"days\": [ 1, 1, 2, 1 ],\n  \"coord\": [ -90.0715, 29.9510 ],\n  \"data\": [\n    { \"name\": \"ox03\", \"staff\": true },\n    {\n      \"name\": null,\n      \"staff\": false,\n      \"extra\": { \"info\": \"\" }\n    },\n    { \"name\": \"ox03\", \"staff\": true },\n    {}\n  ]\n}\n"
  },
  {
    "path": "test/e2e/ox-test/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/ox-test/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/ox-test/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/ox-test/schema-less/size.txt",
    "content": "94\n"
  },
  {
    "path": "test/e2e/packagejson/document.json",
    "content": "{\n    \"name\": \"grunt\",\n    \"description\": \"The JavaScript Task Runner\",\n    \"version\": \"0.4.5\",\n    \"author\": {\n        \"name\": \"\\\"Cowboy\\\" Ben Alman\",\n        \"url\": \"http://benalman.com/\"\n    },\n    \"homepage\": \"http://gruntjs.com/\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"git://github.com/gruntjs/grunt.git\"\n    },\n    \"bugs\": {\n        \"url\": \"http://github.com/gruntjs/grunt/issues\"\n    },\n    \"licenses\": [\n        {\n            \"type\": \"MIT\",\n            \"url\": \"http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT\"\n        }\n    ],\n    \"main\": \"lib/grunt\",\n    \"scripts\": {\n        \"test\": \"grunt test\"\n    },\n    \"engines\": {\n        \"node\": \">= 0.8.0\"\n    },\n    \"keywords\": [\n        \"task\",\n        \"async\",\n        \"cli\",\n        \"minify\",\n        \"uglify\",\n        \"build\",\n        \"lodash\",\n        \"unit\",\n        \"test\",\n        \"qunit\",\n        \"nodeunit\",\n        \"server\",\n        \"init\",\n        \"scaffold\",\n        \"make\",\n        \"jake\",\n        \"tool\"\n    ],\n    \"dependencies\": {\n        \"async\": \"~0.1.22\",\n        \"coffee-script\": \"~1.3.3\",\n        \"colors\": \"~0.6.2\",\n        \"dateformat\": \"1.0.2-1.2.3\",\n        \"eventemitter2\": \"~0.4.13\",\n        \"findup-sync\": \"~0.1.2\",\n        \"glob\": \"~3.1.21\",\n        \"hooker\": \"~0.2.3\",\n        \"iconv-lite\": \"~0.2.11\",\n        \"minimatch\": \"~0.2.12\",\n        \"nopt\": \"~1.0.10\",\n        \"rimraf\": \"~2.2.8\",\n        \"lodash\": \"~0.9.2\",\n        \"underscore.string\": \"~2.2.1\",\n        \"which\": \"~1.0.5\",\n        \"js-yaml\": \"~2.0.5\",\n        \"exit\": \"~0.1.1\",\n        \"getobject\": \"~0.1.0\",\n        \"grunt-legacy-util\": \"~0.2.0\",\n        \"grunt-legacy-log\": \"~0.1.0\"\n    },\n    \"devDependencies\": {\n        \"temporary\": \"~0.0.4\",\n        \"grunt-contrib-jshint\": \"~0.6.4\",\n        \"grunt-contrib-nodeunit\": \"~0.2.0\",\n        \"grunt-contrib-watch\": \"~0.5.3\",\n        \"difflet\": \"~0.2.3\",\n        \"semver\": \"2.1.0\",\n        \"shelljs\": \"~0.2.5\"\n    },\n    \"readme\": \"# Grunt: The JavaScript Task Runner\\n\\n[![Build Status: Linux](https://secure.travis-ci.org/gruntjs/grunt.png?branch=master)](http://travis-ci.org/gruntjs/grunt)\\n<a href=\\\"https://ci.appveyor.com/project/gruntjs/grunt\\\"><img src=\\\"https://ci.appveyor.com/api/projects/status/32r7s2skrgm9ubva/branch/master\\\" alt=\\\"Build Status: Windows\\\" height=\\\"18\\\" /></a>\\n[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)\\n\\n<img align=\\\"right\\\" height=\\\"260\\\" src=\\\"http://gruntjs.com/img/grunt-logo-no-wordmark.svg\\\">\\n\\n\\n### Documentation\\n\\nVisit the [gruntjs.com](http://gruntjs.com/) website for all the things.\\n\\n### Support / Contributing\\nBefore you make an issue, please read our [Contributing](http://gruntjs.com/contributing) guide.\\n\\nYou can find the grunt team in [#grunt on irc.freenode.net](http://webchat.freenode.net/?channels=grunt).\\n\\n### Release History\\nSee the [CHANGELOG](CHANGELOG).\\n\",\n    \"_id\": \"grunt@0.4.5\",\n    \"_from\": \"grunt@~0.4.4\"\n}\n"
  },
  {
    "path": "test/e2e/packagejson/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/packagejson/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/packagejson/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/packagejson/schema-less/size.txt",
    "content": "1957\n"
  },
  {
    "path": "test/e2e/packagejsonlintrc/document.json",
    "content": "{\n  \"rules\": {\n    \"require-author\": \"error\",\n    \"require-description\": \"error\",\n    \"require-engines\": \"error\",\n    \"require-license\": \"error\",\n    \"require-name\": \"error\",\n    \"require-repository\": \"error\",\n    \"require-version\": \"error\",\n    \"require-bugs\": \"error\",\n    \"require-homepage\": \"error\",\n    \"require-keywords\": \"error\",\n    \"bin-type\": \"error\",\n    \"config-type\": \"error\",\n    \"description-type\": \"error\",\n    \"devDependencies-type\": \"error\",\n    \"directories-type\": \"error\",\n    \"engines-type\": \"error\",\n    \"files-type\": \"error\",\n    \"homepage-type\": \"error\",\n    \"keywords-type\": \"error\",\n    \"license-type\": \"error\",\n    \"main-type\": \"error\",\n    \"man-type\": \"error\",\n    \"name-type\": \"error\",\n    \"preferGlobal-type\": \"error\",\n    \"private-type\": \"error\",\n    \"repository-type\": \"error\",\n    \"scripts-type\": \"error\",\n    \"version-type\": \"error\",\n    \"valid-values-author\": [\"error\", [\n      \"My name\"\n    ]],\n    \"valid-values-private\": [\"error\", [\n      false\n    ]],\n    \"no-restricted-dependencies\": [\"error\", [\n      \"gulping-npm-package-json-lint\"\n    ]],\n    \"no-restricted-pre-release-dependencies\": [\"error\", [\n      \"gulping-npm-package-json-lint\"\n    ]],\n    \"no-restricted-invalid-devDependencies\": [\"error\", [\n      \"gulping-npm-package-json-lint\"\n    ]],\n    \"no-restricted-pre-release-devDependencies\": [\"error\", [\n      \"gulping-npm-package-json-lint\"\n    ]],\n    \"name-format\": \"error\",\n    \"version-format\": \"error\"\n  }\n}\n"
  },
  {
    "path": "test/e2e/packagejsonlintrc/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/packagejsonlintrc/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/packagejsonlintrc/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/packagejsonlintrc/schema-less/size.txt",
    "content": "791\n"
  },
  {
    "path": "test/e2e/runner.cc",
    "content": "#include <sourcemeta/jsonbinpack/compiler.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cassert>    // assert\n#include <cstdlib>    // EXIT_SUCCESS, EXIT_FAILURE\n#include <filesystem> // std::filesystem\n#include <fstream>    // std::ifstream, std::ofstream\n#include <ios>        // std::ios_base, std::ios::binary\n#include <iostream>   // std::cerr\n#include <string>     // std::to_string\n\nconstexpr auto DEFAULT_METASCHEMA =\n    \"https://json-schema.org/draft/2020-12/schema\";\n\nauto main(int argc, char *argv[]) -> int {\n  if (argc <= 2) {\n    std::cerr << \"Usage: \" << argv[0] << \" <instance.json> <directory>\\n\";\n    return EXIT_FAILURE;\n  }\n\n  const std::filesystem::path instance_path{argv[1]};\n  assert(std::filesystem::is_regular_file(instance_path));\n  const sourcemeta::core::JSON instance =\n      sourcemeta::core::read_json(instance_path);\n  const std::filesystem::path directory{argv[2]};\n  assert(std::filesystem::is_directory(directory));\n\n  // Schema\n  const std::filesystem::path schema_path{directory / \"schema.json\"};\n  assert(std::filesystem::is_regular_file(schema_path));\n  sourcemeta::core::JSON schema = sourcemeta::core::read_json(schema_path);\n\n  // Canonicalize\n  sourcemeta::jsonbinpack::canonicalize(schema, sourcemeta::core::schema_walker,\n                                        sourcemeta::core::schema_resolver,\n                                        DEFAULT_METASCHEMA);\n\n  std::ofstream canonical_output_stream(directory / \"canonical.json\",\n                                        std::ios::binary);\n  canonical_output_stream.exceptions(std::ios_base::badbit);\n\n  sourcemeta::core::format(schema, sourcemeta::core::schema_walker,\n                           sourcemeta::core::schema_resolver,\n                           \"https://json-schema.org/draft/2020-12/schema\");\n  sourcemeta::core::prettify(schema, canonical_output_stream);\n  canonical_output_stream << \"\\n\";\n  canonical_output_stream.flush();\n  canonical_output_stream.close();\n\n  // Compile\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver,\n                                   DEFAULT_METASCHEMA);\n\n  std::ofstream encoding_output_stream(directory / \"encoding.json\",\n                                       std::ios::binary);\n  encoding_output_stream.exceptions(std::ios_base::badbit);\n  sourcemeta::core::prettify(schema, encoding_output_stream);\n  encoding_output_stream << \"\\n\";\n  encoding_output_stream.flush();\n  encoding_output_stream.close();\n\n  // Encoder\n  const sourcemeta::jsonbinpack::Encoding encoding{\n      sourcemeta::jsonbinpack::load(schema)};\n  std::ofstream output_stream(directory / \"output.bin\", std::ios::binary);\n  output_stream.exceptions(std::ios_base::badbit);\n  sourcemeta::jsonbinpack::Encoder encoder{output_stream};\n  encoder.write(instance, encoding);\n  output_stream.flush();\n  const auto size{output_stream.tellp()};\n  output_stream.close();\n  std::ofstream size_stream(directory / \"size.txt\", std::ios::binary);\n  size_stream.exceptions(std::ios_base::badbit);\n  size_stream << std::to_string(size) << \"\\n\";\n  size_stream.flush();\n  size_stream.close();\n\n  // Decoder\n  std::ifstream data_stream{directory / \"output.bin\", std::ios::binary};\n  data_stream.exceptions(std::ios_base::badbit);\n  sourcemeta::jsonbinpack::Decoder decoder{data_stream};\n  const sourcemeta::core::JSON result = decoder.read(encoding);\n\n  // Report results\n  if (result == instance) {\n    return EXIT_SUCCESS;\n  } else {\n    std::cerr << \"GOT:\\n\";\n    sourcemeta::core::prettify(result, std::cerr);\n    std::cerr << \"\\nEXPECTED:\\n\";\n    sourcemeta::core::prettify(instance, std::cerr);\n    std::cerr << \"\\n\";\n    return EXIT_FAILURE;\n  }\n}\n"
  },
  {
    "path": "test/e2e/sapcloudsdkpipeline/document.json",
    "content": "{\n  \"general\": null,\n  \"stages\": null,\n  \"steps\": null\n}\n"
  },
  {
    "path": "test/e2e/sapcloudsdkpipeline/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/sapcloudsdkpipeline/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/sapcloudsdkpipeline/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/sapcloudsdkpipeline/schema-less/size.txt",
    "content": "25\n"
  },
  {
    "path": "test/e2e/travisnotifications/document.json",
    "content": "{\n  \"notifications\": {\n    \"campfire\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"irc\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"flowdock\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"hipchat\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"slack\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"webhooks\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    },\n    \"email\": {\n      \"secure\": \"sdfusdhfsdofguhdfgubdsifgudfbgs3453durghssecurestringidsuag34522irueg=\"\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/travisnotifications/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/travisnotifications/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/travisnotifications/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/travisnotifications/schema-less/size.txt",
    "content": "185\n"
  },
  {
    "path": "test/e2e/tslintbasic/document.json",
    "content": "{\n  \"rules\": {\n    \"ordered-imports\": {\n      \"options\": {\n        \"grouped-imports\": true\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/tslintbasic/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/tslintbasic/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/tslintbasic/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/tslintbasic/schema-less/size.txt",
    "content": "51\n"
  },
  {
    "path": "test/e2e/tslintextend/document.json",
    "content": "{\n  \"extends\": [\"tslint-config-unional\", \"tslint-config-standard\"]\n}\n"
  },
  {
    "path": "test/e2e/tslintextend/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/tslintextend/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/tslintextend/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/tslintextend/schema-less/size.txt",
    "content": "55\n"
  },
  {
    "path": "test/e2e/tslintmulti/document.json",
    "content": "{\n  \"rules\": {\n    \"no-any\": [true],\n    \"radix\": [true],\n    \"ordered-imports\": {\n      \"options\": {\n        \"grouped-imports\": true\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/e2e/tslintmulti/schema-less/canonical.json",
    "content": "true\n"
  },
  {
    "path": "test/e2e/tslintmulti/schema-less/encoding.json",
    "content": "{\n  \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n  \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n  \"binpackOptions\": {}\n}\n"
  },
  {
    "path": "test/e2e/tslintmulti/schema-less/schema.json",
    "content": "{}\n"
  },
  {
    "path": "test/e2e/tslintmulti/schema-less/size.txt",
    "content": "68\n"
  },
  {
    "path": "test/packaging/CMakeLists.txt",
    "content": "# TODO: Get install path from a variable?\nadd_test(NAME packaging.find_package_configure COMMAND\n  \"${CMAKE_COMMAND}\"\n  -S \"${CMAKE_CURRENT_SOURCE_DIR}/find_package\"\n  -B \"${CMAKE_CURRENT_BINARY_DIR}/find_package\"\n  \"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}\"\n  \"-DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH};${PROJECT_SOURCE_DIR}/build/dist\"\n  \"-DCMAKE_TOOLCHAIN_FILE:PATH=${CMAKE_TOOLCHAIN_FILE}\")\nadd_test(NAME packaging.find_package_build COMMAND\n  \"${CMAKE_COMMAND}\"\n  --build \"${CMAKE_CURRENT_BINARY_DIR}/find_package\"\n  --config \"${CMAKE_BUILD_TYPE}\")\nset_tests_properties(packaging.find_package_build\n  PROPERTIES DEPENDS packaging.find_package_configure)\n"
  },
  {
    "path": "test/packaging/find_package/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.18)\nproject(jsonbinpack_hello VERSION 0.0.1 LANGUAGES CXX)\nset(CMAKE_CXX_STANDARD 23)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\nfind_package(JSONBinPack REQUIRED)\nadd_executable(jsonbinpack_hello hello.cc)\ntarget_link_libraries(jsonbinpack_hello PRIVATE sourcemeta::jsonbinpack::runtime)\ntarget_link_libraries(jsonbinpack_hello PRIVATE sourcemeta::jsonbinpack::compiler)\n"
  },
  {
    "path": "test/packaging/find_package/hello.cc",
    "content": "#include <sourcemeta/jsonbinpack/compiler.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cstdlib>  // EXIT_SUCCESS\n#include <iostream> // std::cout\n\nauto main() -> int {\n  sourcemeta::core::JSON schema = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"type\": \"integer\",\n    \"minimum\": -100,\n    \"maximum\": 100\n  })JSON\");\n\n  sourcemeta::jsonbinpack::compile(schema, sourcemeta::core::schema_walker,\n                                   sourcemeta::core::schema_resolver);\n\n  const sourcemeta::jsonbinpack::Encoding encoding{\n      sourcemeta::jsonbinpack::load(schema)};\n  sourcemeta::jsonbinpack::Encoder encoder{std::cout};\n\n  const sourcemeta::core::JSON instance{5};\n  encoder.write(instance, encoding);\n\n  std::cout << std::endl;\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "test/runtime/CMakeLists.txt",
    "content": "sourcemeta_googletest(NAMESPACE sourcemeta PROJECT jsonbinpack NAME runtime\n  FOLDER \"JSON BinPack/Runtime\"\n  SOURCES\n    decode_any_test.cc\n    decode_array_test.cc\n    decode_integer_test.cc\n    decode_number_test.cc\n    decode_object_test.cc\n    decode_string_test.cc\n    decode_test.cc\n    decode_traits_test.cc\n    decode_utils.h\n    encode_any_test.cc\n    encode_array_test.cc\n    encode_cache_test.cc\n    encode_integer_test.cc\n    encode_number_test.cc\n    encode_object_test.cc\n    encode_real_test.cc\n    encode_string_test.cc\n    encode_test.cc\n    encode_traits_test.cc\n    encode_utils.h\n    input_stream_varint_test.cc\n    output_stream_varint_test.cc\n    encoding_traits_test.cc\n    v1_loader_test.cc\n    v1_any_loader_test.cc\n    v1_array_loader_test.cc\n    v1_integer_loader_test.cc\n    v1_number_loader_test.cc\n    v1_string_loader_test.cc)\n\ntarget_link_libraries(sourcemeta_jsonbinpack_runtime_unit\n  PRIVATE sourcemeta::jsonbinpack::runtime)\ntarget_link_libraries(sourcemeta_jsonbinpack_runtime_unit\n  PRIVATE sourcemeta::core::json)\n"
  },
  {
    "path": "test/runtime/decode_any_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <string>\n#include <utility>\n#include <vector>\n\nTEST(JSONBinPack_Decoder, BYTE_CHOICE_INDEX_1__1_0_0) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  const auto result = decoder.BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BYTE_CHOICE_INDEX_1__0_1_0) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  const auto result = decoder.BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BYTE_CHOICE_INDEX_1__0_0_1) {\n  InputByteStream stream{0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  const auto result = decoder.BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BYTE_CHOICE_INDEX_bar__foo_bar_bar) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(\"foo\");\n  choices.emplace_back(\"bar\");\n  choices.emplace_back(\"bar\");\n  const auto result = decoder.BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{\"bar\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BYTE_CHOICE_INDEX_non_scalar_1) {\n  InputByteStream stream{0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n  const auto result = decoder.BYTE_CHOICE_INDEX({std::move(choices)});\n  const auto expected = sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_1__1_0_0) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_1__0_1_0) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_1__0_0_1) {\n  InputByteStream stream{0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_bar__foo_bar_bar) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(\"foo\");\n  choices.emplace_back(\"bar\");\n  choices.emplace_back(\"bar\");\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{\"bar\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_non_scalar_1) {\n  InputByteStream stream{0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const auto expected = sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, LARGE_CHOICE_INDEX_enum_250) {\n  InputByteStream stream{0xfa, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  for (std::int64_t x = 0; x < 255; x++) {\n    choices.emplace_back(x);\n  }\n\n  const auto result = decoder.LARGE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{250};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__1_0_0) {\n  InputByteStream stream{};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  const auto result = decoder.TOP_LEVEL_BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__0_1_0) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  choices.emplace_back(0);\n  const auto result = decoder.TOP_LEVEL_BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__0_0_1) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(0);\n  choices.emplace_back(0);\n  choices.emplace_back(1);\n  const auto result = decoder.TOP_LEVEL_BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, TOP_LEVEL_BYTE_CHOICE_INDEX_bar__foo_bar_bar) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(\"foo\");\n  choices.emplace_back(\"bar\");\n  choices.emplace_back(\"bar\");\n  const auto result = decoder.TOP_LEVEL_BYTE_CHOICE_INDEX({std::move(choices)});\n  const sourcemeta::core::JSON expected{\"bar\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, TOP_LEVEL_BYTE_CHOICE_INDEX_non_scalar_1) {\n  InputByteStream stream{0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n  const auto result = decoder.TOP_LEVEL_BYTE_CHOICE_INDEX({std::move(choices)});\n  const auto expected = sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, CONST_NONE_scalar) {\n  InputByteStream stream{};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.CONST_NONE({sourcemeta::core::JSON{1}});\n  const sourcemeta::core::JSON expected{1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, CONST_NONE_complex) {\n  InputByteStream stream{};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result =\n      decoder.CONST_NONE({sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\")});\n  const auto expected = sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__null) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x17};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{nullptr};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__false) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x07};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{false};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__true) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{true};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_3_14) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x2f, 0xf4, 0x04, 0x02};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{3.14};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_3_0) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x37, 0x03};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_real());\n  EXPECT_TRUE(result.is_integral());\n  const sourcemeta::core::JSON expected{3.0};\n  EXPECT_TRUE(expected.is_real());\n  EXPECT_TRUE(expected.is_integral());\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_103_0) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x37, 0x67};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_real());\n  EXPECT_TRUE(result.is_integral());\n  const sourcemeta::core::JSON expected{103.0};\n  EXPECT_TRUE(expected.is_real());\n  EXPECT_TRUE(expected.is_integral());\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__256) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x1f, 0x80, 0x02};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{256};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_257) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x27, 0x80, 0x02};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{-257};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__255) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x05, 0xff};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{255};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_256) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x06, 0xff};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{-256};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__0) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x0d};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_1) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x0e};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{-1};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_space) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x11, 0x20};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{\" \"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_foo) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x21, 0x66, 0x6f, 0x6f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_30_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0xf9, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(30, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__shared_string_foo) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x21, 0x66, 0x6f, 0x6f, 0x20, 0x04, 0x20, 0x06};\n  Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON result2 =\n      decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON result3 =\n      decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected1{\"foo\"};\n  const sourcemeta::core::JSON expected2{\"foo\"};\n  const sourcemeta::core::JSON expected3{\"foo\"};\n  EXPECT_EQ(result1, expected1);\n  EXPECT_EQ(result2, expected2);\n  EXPECT_EQ(result3, expected3);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_31_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(31, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_61_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0xf2, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                         0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(61, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_url) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,\n                         0x73, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x6c, 0x6f, 0x75,\n                         0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x61, 0x6e,\n                         0x64, 0x79, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x6e, 0x6c};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{\"https://soundcloud.com/dandymusicnl\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_128_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x3f, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(128, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_130_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x3f, 0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(130, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_256_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x47, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(256, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_258_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x47, 0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(258, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_512_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x4f, 0x00,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(512, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_513_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x4f, 0x01,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(513, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_1024_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x57, 0x00,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78,\n\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(1024, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_62_xs_non_shared) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x01, 0x01, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(62, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_63_xs_non_shared) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x01, 0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  const sourcemeta::core::JSON expected{std::string(63, 'x')};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__foo_true_2000) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x24, 0x21, 0x66, 0x6f, 0x6f, 0x0f, 0x1f, 0xd0, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n\n  EXPECT_TRUE(result.is_array());\n  EXPECT_EQ(result.size(), 3);\n  using namespace sourcemeta::core;\n  EXPECT_EQ(result.at(0), JSON{\"foo\"});\n  EXPECT_EQ(result.at(1), JSON{true});\n  EXPECT_EQ(result.at(2), JSON{2000});\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_30) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0xfc, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n\n  EXPECT_TRUE(result.is_array());\n  EXPECT_EQ(result.size(), 30);\n  using namespace sourcemeta::core;\n\n  EXPECT_EQ(result.at(0), JSON{true});\n  EXPECT_EQ(result.at(1), JSON{true});\n  EXPECT_EQ(result.at(2), JSON{true});\n  EXPECT_EQ(result.at(3), JSON{true});\n  EXPECT_EQ(result.at(4), JSON{true});\n  EXPECT_EQ(result.at(5), JSON{true});\n  EXPECT_EQ(result.at(6), JSON{true});\n  EXPECT_EQ(result.at(7), JSON{true});\n  EXPECT_EQ(result.at(8), JSON{true});\n  EXPECT_EQ(result.at(9), JSON{true});\n\n  EXPECT_EQ(result.at(10), JSON{true});\n  EXPECT_EQ(result.at(11), JSON{true});\n  EXPECT_EQ(result.at(12), JSON{true});\n  EXPECT_EQ(result.at(13), JSON{true});\n  EXPECT_EQ(result.at(14), JSON{true});\n  EXPECT_EQ(result.at(15), JSON{true});\n  EXPECT_EQ(result.at(16), JSON{true});\n  EXPECT_EQ(result.at(17), JSON{true});\n  EXPECT_EQ(result.at(18), JSON{true});\n  EXPECT_EQ(result.at(19), JSON{true});\n\n  EXPECT_EQ(result.at(20), JSON{true});\n  EXPECT_EQ(result.at(21), JSON{true});\n  EXPECT_EQ(result.at(22), JSON{true});\n  EXPECT_EQ(result.at(23), JSON{true});\n  EXPECT_EQ(result.at(24), JSON{true});\n  EXPECT_EQ(result.at(25), JSON{true});\n  EXPECT_EQ(result.at(26), JSON{true});\n  EXPECT_EQ(result.at(27), JSON{true});\n  EXPECT_EQ(result.at(28), JSON{true});\n  EXPECT_EQ(result.at(29), JSON{true});\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_31) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x04, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n\n  EXPECT_TRUE(result.is_array());\n  EXPECT_EQ(result.size(), 31);\n  using namespace sourcemeta::core;\n\n  EXPECT_EQ(result.at(0), JSON{true});\n  EXPECT_EQ(result.at(1), JSON{true});\n  EXPECT_EQ(result.at(2), JSON{true});\n  EXPECT_EQ(result.at(3), JSON{true});\n  EXPECT_EQ(result.at(4), JSON{true});\n  EXPECT_EQ(result.at(5), JSON{true});\n  EXPECT_EQ(result.at(6), JSON{true});\n  EXPECT_EQ(result.at(7), JSON{true});\n  EXPECT_EQ(result.at(8), JSON{true});\n  EXPECT_EQ(result.at(9), JSON{true});\n\n  EXPECT_EQ(result.at(10), JSON{true});\n  EXPECT_EQ(result.at(11), JSON{true});\n  EXPECT_EQ(result.at(12), JSON{true});\n  EXPECT_EQ(result.at(13), JSON{true});\n  EXPECT_EQ(result.at(14), JSON{true});\n  EXPECT_EQ(result.at(15), JSON{true});\n  EXPECT_EQ(result.at(16), JSON{true});\n  EXPECT_EQ(result.at(17), JSON{true});\n  EXPECT_EQ(result.at(18), JSON{true});\n  EXPECT_EQ(result.at(19), JSON{true});\n\n  EXPECT_EQ(result.at(20), JSON{true});\n  EXPECT_EQ(result.at(21), JSON{true});\n  EXPECT_EQ(result.at(22), JSON{true});\n  EXPECT_EQ(result.at(23), JSON{true});\n  EXPECT_EQ(result.at(24), JSON{true});\n  EXPECT_EQ(result.at(25), JSON{true});\n  EXPECT_EQ(result.at(26), JSON{true});\n  EXPECT_EQ(result.at(27), JSON{true});\n  EXPECT_EQ(result.at(28), JSON{true});\n  EXPECT_EQ(result.at(29), JSON{true});\n\n  EXPECT_EQ(result.at(30), JSON{true});\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_32) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x04, 0x01, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                         0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n\n  EXPECT_TRUE(result.is_array());\n  EXPECT_EQ(result.size(), 32);\n  using namespace sourcemeta::core;\n\n  EXPECT_EQ(result.at(0), JSON{true});\n  EXPECT_EQ(result.at(1), JSON{true});\n  EXPECT_EQ(result.at(2), JSON{true});\n  EXPECT_EQ(result.at(3), JSON{true});\n  EXPECT_EQ(result.at(4), JSON{true});\n  EXPECT_EQ(result.at(5), JSON{true});\n  EXPECT_EQ(result.at(6), JSON{true});\n  EXPECT_EQ(result.at(7), JSON{true});\n  EXPECT_EQ(result.at(8), JSON{true});\n  EXPECT_EQ(result.at(9), JSON{true});\n\n  EXPECT_EQ(result.at(10), JSON{true});\n  EXPECT_EQ(result.at(11), JSON{true});\n  EXPECT_EQ(result.at(12), JSON{true});\n  EXPECT_EQ(result.at(13), JSON{true});\n  EXPECT_EQ(result.at(14), JSON{true});\n  EXPECT_EQ(result.at(15), JSON{true});\n  EXPECT_EQ(result.at(16), JSON{true});\n  EXPECT_EQ(result.at(17), JSON{true});\n  EXPECT_EQ(result.at(18), JSON{true});\n  EXPECT_EQ(result.at(19), JSON{true});\n\n  EXPECT_EQ(result.at(20), JSON{true});\n  EXPECT_EQ(result.at(21), JSON{true});\n  EXPECT_EQ(result.at(22), JSON{true});\n  EXPECT_EQ(result.at(23), JSON{true});\n  EXPECT_EQ(result.at(24), JSON{true});\n  EXPECT_EQ(result.at(25), JSON{true});\n  EXPECT_EQ(result.at(26), JSON{true});\n  EXPECT_EQ(result.at(27), JSON{true});\n  EXPECT_EQ(result.at(28), JSON{true});\n  EXPECT_EQ(result.at(29), JSON{true});\n\n  EXPECT_EQ(result.at(30), JSON{true});\n  EXPECT_EQ(result.at(31), JSON{true});\n}\n\nTEST(JSONBinPack_Decoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_foo_bar_baz_1) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x1b, 0x04, 0x66, 0x6f, 0x6f, 0x21, 0x62,\n                         0x61, 0x72, 0x04, 0x62, 0x61, 0x7a, 0x15};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 2);\n\n  EXPECT_TRUE(result.defines(\"foo\"));\n  const auto &foo{result.at(\"foo\")};\n  EXPECT_TRUE(foo.is_string());\n  EXPECT_EQ(foo.to_string(), \"bar\");\n\n  EXPECT_TRUE(result.defines(\"baz\"));\n  const auto &baz{result.at(\"baz\")};\n  EXPECT_TRUE(baz.is_integer());\n  EXPECT_EQ(baz.to_integer(), 1);\n}\n\nstatic auto is_member_true(const sourcemeta::core::JSON &object,\n                           const std::string &key) -> bool {\n  return object.defines(key) && object.at(key).is_boolean() &&\n         object.at(key).to_boolean();\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_30_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0xfb, 0x03, 0x30, 0x30, 0x0f, 0x03, 0x30, 0x31, 0x0f, 0x03, 0x30,\n      0x32, 0x0f, 0x03, 0x30, 0x33, 0x0f, 0x03, 0x30, 0x34, 0x0f, 0x03,\n      0x30, 0x35, 0x0f, 0x03, 0x30, 0x36, 0x0f, 0x03, 0x30, 0x37, 0x0f,\n      0x03, 0x30, 0x38, 0x0f, 0x03, 0x30, 0x39, 0x0f, 0x03, 0x31, 0x30,\n      0x0f, 0x03, 0x31, 0x31, 0x0f, 0x03, 0x31, 0x32, 0x0f, 0x03, 0x31,\n      0x33, 0x0f, 0x03, 0x31, 0x34, 0x0f, 0x03, 0x31, 0x35, 0x0f, 0x03,\n      0x31, 0x36, 0x0f, 0x03, 0x31, 0x37, 0x0f, 0x03, 0x31, 0x38, 0x0f,\n      0x03, 0x31, 0x39, 0x0f, 0x03, 0x32, 0x30, 0x0f, 0x03, 0x32, 0x31,\n      0x0f, 0x03, 0x32, 0x32, 0x0f, 0x03, 0x32, 0x33, 0x0f, 0x03, 0x32,\n      0x34, 0x0f, 0x03, 0x32, 0x35, 0x0f, 0x03, 0x32, 0x36, 0x0f, 0x03,\n      0x32, 0x37, 0x0f, 0x03, 0x32, 0x38, 0x0f, 0x03, 0x32, 0x39, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 30);\n\n  EXPECT_TRUE(is_member_true(result, \"00\"));\n  EXPECT_TRUE(is_member_true(result, \"01\"));\n  EXPECT_TRUE(is_member_true(result, \"02\"));\n  EXPECT_TRUE(is_member_true(result, \"03\"));\n  EXPECT_TRUE(is_member_true(result, \"04\"));\n  EXPECT_TRUE(is_member_true(result, \"05\"));\n  EXPECT_TRUE(is_member_true(result, \"06\"));\n  EXPECT_TRUE(is_member_true(result, \"07\"));\n  EXPECT_TRUE(is_member_true(result, \"08\"));\n  EXPECT_TRUE(is_member_true(result, \"09\"));\n\n  EXPECT_TRUE(is_member_true(result, \"10\"));\n  EXPECT_TRUE(is_member_true(result, \"11\"));\n  EXPECT_TRUE(is_member_true(result, \"12\"));\n  EXPECT_TRUE(is_member_true(result, \"13\"));\n  EXPECT_TRUE(is_member_true(result, \"14\"));\n  EXPECT_TRUE(is_member_true(result, \"15\"));\n  EXPECT_TRUE(is_member_true(result, \"16\"));\n  EXPECT_TRUE(is_member_true(result, \"17\"));\n  EXPECT_TRUE(is_member_true(result, \"18\"));\n  EXPECT_TRUE(is_member_true(result, \"19\"));\n\n  EXPECT_TRUE(is_member_true(result, \"20\"));\n  EXPECT_TRUE(is_member_true(result, \"21\"));\n  EXPECT_TRUE(is_member_true(result, \"22\"));\n  EXPECT_TRUE(is_member_true(result, \"23\"));\n  EXPECT_TRUE(is_member_true(result, \"24\"));\n  EXPECT_TRUE(is_member_true(result, \"25\"));\n  EXPECT_TRUE(is_member_true(result, \"26\"));\n  EXPECT_TRUE(is_member_true(result, \"27\"));\n  EXPECT_TRUE(is_member_true(result, \"28\"));\n  EXPECT_TRUE(is_member_true(result, \"29\"));\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_31_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x03, 0x00, 0x03, 0x30, 0x30, 0x0f, 0x03, 0x30, 0x31, 0x0f, 0x03, 0x30,\n      0x32, 0x0f, 0x03, 0x30, 0x33, 0x0f, 0x03, 0x30, 0x34, 0x0f, 0x03, 0x30,\n      0x35, 0x0f, 0x03, 0x30, 0x36, 0x0f, 0x03, 0x30, 0x37, 0x0f, 0x03, 0x30,\n      0x38, 0x0f, 0x03, 0x30, 0x39, 0x0f, 0x03, 0x31, 0x30, 0x0f, 0x03, 0x31,\n      0x31, 0x0f, 0x03, 0x31, 0x32, 0x0f, 0x03, 0x31, 0x33, 0x0f, 0x03, 0x31,\n      0x34, 0x0f, 0x03, 0x31, 0x35, 0x0f, 0x03, 0x31, 0x36, 0x0f, 0x03, 0x31,\n      0x37, 0x0f, 0x03, 0x31, 0x38, 0x0f, 0x03, 0x31, 0x39, 0x0f, 0x03, 0x32,\n      0x30, 0x0f, 0x03, 0x32, 0x31, 0x0f, 0x03, 0x32, 0x32, 0x0f, 0x03, 0x32,\n      0x33, 0x0f, 0x03, 0x32, 0x34, 0x0f, 0x03, 0x32, 0x35, 0x0f, 0x03, 0x32,\n      0x36, 0x0f, 0x03, 0x32, 0x37, 0x0f, 0x03, 0x32, 0x38, 0x0f, 0x03, 0x32,\n      0x39, 0x0f, 0x03, 0x33, 0x30, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 31);\n\n  EXPECT_TRUE(is_member_true(result, \"00\"));\n  EXPECT_TRUE(is_member_true(result, \"01\"));\n  EXPECT_TRUE(is_member_true(result, \"02\"));\n  EXPECT_TRUE(is_member_true(result, \"03\"));\n  EXPECT_TRUE(is_member_true(result, \"04\"));\n  EXPECT_TRUE(is_member_true(result, \"05\"));\n  EXPECT_TRUE(is_member_true(result, \"06\"));\n  EXPECT_TRUE(is_member_true(result, \"07\"));\n  EXPECT_TRUE(is_member_true(result, \"08\"));\n  EXPECT_TRUE(is_member_true(result, \"09\"));\n\n  EXPECT_TRUE(is_member_true(result, \"10\"));\n  EXPECT_TRUE(is_member_true(result, \"11\"));\n  EXPECT_TRUE(is_member_true(result, \"12\"));\n  EXPECT_TRUE(is_member_true(result, \"13\"));\n  EXPECT_TRUE(is_member_true(result, \"14\"));\n  EXPECT_TRUE(is_member_true(result, \"15\"));\n  EXPECT_TRUE(is_member_true(result, \"16\"));\n  EXPECT_TRUE(is_member_true(result, \"17\"));\n  EXPECT_TRUE(is_member_true(result, \"18\"));\n  EXPECT_TRUE(is_member_true(result, \"19\"));\n\n  EXPECT_TRUE(is_member_true(result, \"20\"));\n  EXPECT_TRUE(is_member_true(result, \"21\"));\n  EXPECT_TRUE(is_member_true(result, \"22\"));\n  EXPECT_TRUE(is_member_true(result, \"23\"));\n  EXPECT_TRUE(is_member_true(result, \"24\"));\n  EXPECT_TRUE(is_member_true(result, \"25\"));\n  EXPECT_TRUE(is_member_true(result, \"26\"));\n  EXPECT_TRUE(is_member_true(result, \"27\"));\n  EXPECT_TRUE(is_member_true(result, \"28\"));\n  EXPECT_TRUE(is_member_true(result, \"29\"));\n\n  EXPECT_TRUE(is_member_true(result, \"30\"));\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_32_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x03, 0x01, 0x03, 0x30, 0x30, 0x0f, 0x03, 0x30, 0x31, 0x0f, 0x03, 0x30,\n      0x32, 0x0f, 0x03, 0x30, 0x33, 0x0f, 0x03, 0x30, 0x34, 0x0f, 0x03, 0x30,\n      0x35, 0x0f, 0x03, 0x30, 0x36, 0x0f, 0x03, 0x30, 0x37, 0x0f, 0x03, 0x30,\n      0x38, 0x0f, 0x03, 0x30, 0x39, 0x0f, 0x03, 0x31, 0x30, 0x0f, 0x03, 0x31,\n      0x31, 0x0f, 0x03, 0x31, 0x32, 0x0f, 0x03, 0x31, 0x33, 0x0f, 0x03, 0x31,\n      0x34, 0x0f, 0x03, 0x31, 0x35, 0x0f, 0x03, 0x31, 0x36, 0x0f, 0x03, 0x31,\n      0x37, 0x0f, 0x03, 0x31, 0x38, 0x0f, 0x03, 0x31, 0x39, 0x0f, 0x03, 0x32,\n      0x30, 0x0f, 0x03, 0x32, 0x31, 0x0f, 0x03, 0x32, 0x32, 0x0f, 0x03, 0x32,\n      0x33, 0x0f, 0x03, 0x32, 0x34, 0x0f, 0x03, 0x32, 0x35, 0x0f, 0x03, 0x32,\n      0x36, 0x0f, 0x03, 0x32, 0x37, 0x0f, 0x03, 0x32, 0x38, 0x0f, 0x03, 0x32,\n      0x39, 0x0f, 0x03, 0x33, 0x30, 0x0f, 0x03, 0x33, 0x31, 0x0f};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 32);\n\n  EXPECT_TRUE(is_member_true(result, \"00\"));\n  EXPECT_TRUE(is_member_true(result, \"01\"));\n  EXPECT_TRUE(is_member_true(result, \"02\"));\n  EXPECT_TRUE(is_member_true(result, \"03\"));\n  EXPECT_TRUE(is_member_true(result, \"04\"));\n  EXPECT_TRUE(is_member_true(result, \"05\"));\n  EXPECT_TRUE(is_member_true(result, \"06\"));\n  EXPECT_TRUE(is_member_true(result, \"07\"));\n  EXPECT_TRUE(is_member_true(result, \"08\"));\n  EXPECT_TRUE(is_member_true(result, \"09\"));\n\n  EXPECT_TRUE(is_member_true(result, \"10\"));\n  EXPECT_TRUE(is_member_true(result, \"11\"));\n  EXPECT_TRUE(is_member_true(result, \"12\"));\n  EXPECT_TRUE(is_member_true(result, \"13\"));\n  EXPECT_TRUE(is_member_true(result, \"14\"));\n  EXPECT_TRUE(is_member_true(result, \"15\"));\n  EXPECT_TRUE(is_member_true(result, \"16\"));\n  EXPECT_TRUE(is_member_true(result, \"17\"));\n  EXPECT_TRUE(is_member_true(result, \"18\"));\n  EXPECT_TRUE(is_member_true(result, \"19\"));\n\n  EXPECT_TRUE(is_member_true(result, \"20\"));\n  EXPECT_TRUE(is_member_true(result, \"21\"));\n  EXPECT_TRUE(is_member_true(result, \"22\"));\n  EXPECT_TRUE(is_member_true(result, \"23\"));\n  EXPECT_TRUE(is_member_true(result, \"24\"));\n  EXPECT_TRUE(is_member_true(result, \"25\"));\n  EXPECT_TRUE(is_member_true(result, \"26\"));\n  EXPECT_TRUE(is_member_true(result, \"27\"));\n  EXPECT_TRUE(is_member_true(result, \"28\"));\n  EXPECT_TRUE(is_member_true(result, \"29\"));\n\n  EXPECT_TRUE(is_member_true(result, \"30\"));\n  EXPECT_TRUE(is_member_true(result, \"31\"));\n}\n\nTEST(JSONBinPack_Decoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_62_xs_shared) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x1b, 0x04, 0x66, 0x6f, 0x6f, 0x01, 0x01, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n      0x78, 0x78, 0x78, 0x04, 0x62, 0x61, 0x72, 0x00, 0x01, 0x44};\n  Decoder decoder{stream};\n  const auto result = decoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX({});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 2);\n\n  EXPECT_TRUE(result.defines(\"foo\"));\n  const auto &foo{result.at(\"foo\")};\n  EXPECT_TRUE(foo.is_string());\n  EXPECT_EQ(foo.to_string(), std::string(62, 'x'));\n\n  EXPECT_TRUE(result.defines(\"bar\"));\n  const auto &baz{result.at(\"bar\")};\n  EXPECT_TRUE(baz.is_string());\n  EXPECT_EQ(baz.to_string(), std::string(62, 'x'));\n}\n"
  },
  {
    "path": "test/runtime/decode_array_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <vector>\n\nTEST(JSONBinPack_Decoder, FIXED_TYPED_ARRAY_0_1_2__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x00, 0x01, 0x02};\n  Decoder decoder{stream};\n  const auto result = decoder.FIXED_TYPED_ARRAY(\n      {3,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}),\n       {}});\n  const auto expected = sourcemeta::core::parse_json(\"[ 0, 1, 2 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FIXED_TYPED_ARRAY_0_1_true__semityped) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x00, 0x01, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  Encoding first{BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}};\n  Encoding second{BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}};\n\n  const auto result = decoder.FIXED_TYPED_ARRAY(\n      {3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {std::move(first), std::move(second)}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ 0, 1, true ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FIXED_TYPED_ARRAY_empty__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{};\n  Decoder decoder{stream};\n  const auto result = decoder.FIXED_TYPED_ARRAY(\n      {0,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}),\n       {}});\n  const auto expected = sourcemeta::core::parse_json(\"[]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     BOUNDED_8BITS_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x00, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.BOUNDED_8BITS_TYPED_ARRAY(\n      {0,\n       3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     BOUNDED_8BITS_TYPED_ARRAY_true_false_true__same_max_min) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x00, 0x01, 0x00, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.BOUNDED_8BITS_TYPED_ARRAY(\n      {3,\n       3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_8BITS_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x02, 0x01, 0x00, 0x05};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.BOUNDED_8BITS_TYPED_ARRAY(\n      {1,\n       3,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_8BITS_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.BOUNDED_8BITS_TYPED_ARRAY(\n      {0,\n       10,\n       std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n       {BYTE_CHOICE_INDEX{choices},\n        FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     FLOOR_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x00, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.FLOOR_TYPED_ARRAY(\n      {0,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x02, 0x01, 0x00, 0x05};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.FLOOR_TYPED_ARRAY(\n      {1,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.FLOOR_TYPED_ARRAY(\n      {0,\n       std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n       {BYTE_CHOICE_INDEX{choices},\n        FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     ROOF_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x00, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.ROOF_TYPED_ARRAY(\n      {6,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x02, 0x01, 0x00, 0x05};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.ROOF_TYPED_ARRAY(\n      {5,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01};\n  Decoder decoder{stream};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.emplace_back(false);\n  choices.emplace_back(true);\n\n  const auto result = decoder.ROOF_TYPED_ARRAY(\n      {6,\n       std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n       {BYTE_CHOICE_INDEX{choices}, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n\n  const auto expected = sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  EXPECT_EQ(result, expected);\n}\n"
  },
  {
    "path": "test/runtime/decode_integer_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <limits> // std::numeric_limits\n\nTEST(JSONBinPack_Decoder,\n     BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__minus_5_minus_5_minus_1_1) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED({-5, -1, 1});\n  const sourcemeta::core::JSON expected{-5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__2_minus_5_5_1) {\n  InputByteStream stream{0x07};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED({-5, 5, 1});\n  const sourcemeta::core::JSON expected{2};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__5_2_8_1) {\n  InputByteStream stream{0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED({2, 8, 1});\n  const sourcemeta::core::JSON expected{5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__5_1_19_5) {\n  InputByteStream stream{0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED({1, 19, 5});\n  const sourcemeta::core::JSON expected{5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__255_0_255_1) {\n  InputByteStream stream{0xff};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED({0, 255, 1});\n  const sourcemeta::core::JSON expected{255};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_MULTIPLE_ENUM_VARINT__minus_3_minus_10_1) {\n  InputByteStream stream{0x07};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_MULTIPLE_ENUM_VARINT({-10, 1});\n  const sourcemeta::core::JSON expected{-3};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_MULTIPLE_ENUM_VARINT__5_2_1) {\n  InputByteStream stream{0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_MULTIPLE_ENUM_VARINT({2, 1});\n  const sourcemeta::core::JSON expected{5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_MULTIPLE_ENUM_VARINT__10_5_5) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_MULTIPLE_ENUM_VARINT({5, 5});\n  const sourcemeta::core::JSON expected{10};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_MULTIPLE_ENUM_VARINT__10_2_5) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_MULTIPLE_ENUM_VARINT({2, 5});\n  const sourcemeta::core::JSON expected{10};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_MULTIPLE_ENUM_VARINT__1000_minus_2_4) {\n  InputByteStream stream{0xfa, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_MULTIPLE_ENUM_VARINT({-2, 4});\n  const sourcemeta::core::JSON expected{1000};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__minus_3_minus_2_1) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT({-2, 1});\n  const sourcemeta::core::JSON expected{-3};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__8_10_1) {\n  InputByteStream stream{0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT({10, 1});\n  const sourcemeta::core::JSON expected{8};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__5_16_5) {\n  InputByteStream stream{0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT({16, 5});\n  const sourcemeta::core::JSON expected{5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__10_15_5) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT({15, 5});\n  const sourcemeta::core::JSON expected{10};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__minus_25200_1) {\n  InputByteStream stream{0xdf, 0x89, 0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT({1});\n  const sourcemeta::core::JSON expected{-25200};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__10_5) {\n  InputByteStream stream{0x04};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT({5});\n  const sourcemeta::core::JSON expected{10};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__int64_max_1) {\n  InputByteStream stream{0xfe, 0xff, 0xff, 0xff, 0xff,\n                         0xff, 0xff, 0xff, 0xff, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT({1});\n  const std::int64_t value = std::numeric_limits<std::int64_t>::max();\n  const sourcemeta::core::JSON expected{value};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__int64_min_1) {\n  InputByteStream stream{0xfd, 0xff, 0xff, 0xff, 0xff,\n                         0xff, 0xff, 0xff, 0xff, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT({1});\n  const std::int64_t value = std::numeric_limits<std::int64_t>::min() + 1;\n  const sourcemeta::core::JSON expected{value};\n  EXPECT_EQ(result, expected);\n}\n"
  },
  {
    "path": "test/runtime/decode_number_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_5) {\n  InputByteStream stream{0x0a, 0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{5.0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_minus_3_point_14) {\n  InputByteStream stream{0xf3, 0x04, 0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{-3.14};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_minus_5) {\n  InputByteStream stream{0x09, 0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{-5.0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_zero) {\n  InputByteStream stream{0x00, 0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_1235) {\n  InputByteStream stream{0xa6, 0x13, 0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{1235.0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_0_point_1235) {\n  InputByteStream stream{0xa6, 0x13, 0x04};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.1235};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_1_point_235) {\n  InputByteStream stream{0xa6, 0x13, 0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{1.235};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_0_point_01235) {\n  InputByteStream stream{0xa6, 0x13, 0x05};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.01235};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_12_point_35) {\n  InputByteStream stream{0xa6, 0x13, 0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{12.35};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_0_point_001235) {\n  InputByteStream stream{0xa6, 0x13, 0x06};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.001235};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_123_point_5) {\n  InputByteStream stream{0xa6, 0x13, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{123.5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_314) {\n  InputByteStream stream{0xf4, 0x04, 0x00};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{314.0};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_0_point_314) {\n  InputByteStream stream{0xf4, 0x04, 0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.314};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_3_point_14) {\n  InputByteStream stream{0xf4, 0x04, 0x02};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{3.14};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_0_point_0314) {\n  InputByteStream stream{0xf4, 0x04, 0x04};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{0.0314};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, DOUBLE_VARINT_TUPLE_31_point_4) {\n  InputByteStream stream{0xf4, 0x04, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.DOUBLE_VARINT_TUPLE({});\n  const sourcemeta::core::JSON expected{31.4};\n  EXPECT_EQ(result, expected);\n}\n"
  },
  {
    "path": "test/runtime/decode_object_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\nTEST(JSONBinPack_Decoder,\n     FIXED_TYPED_ARBITRARY_OBJECT__no_length_string__integer) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x66, 0x6f, 0x6f, // \"foo\"\n      0x01,             // 1\n      0x62, 0x61, 0x72, // \"bar\"\n      0x02              // 2\n  };\n  Decoder decoder{stream};\n  const auto result = decoder.FIXED_TYPED_ARBITRARY_OBJECT(\n      {2, std::make_shared<Encoding>(UTF8_STRING_NO_LENGTH{3}),\n       std::make_shared<Encoding>(\n           BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1})});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 2);\n  EXPECT_TRUE(result.defines(\"foo\"));\n  EXPECT_TRUE(result.defines(\"bar\"));\n  const auto &foo{result.at(\"foo\")};\n  const auto &bar{result.at(\"bar\")};\n  EXPECT_TRUE(foo.is_integer());\n  EXPECT_TRUE(bar.is_integer());\n  EXPECT_EQ(foo.to_integer(), 1);\n  EXPECT_EQ(bar.to_integer(), 2);\n}\n\nTEST(JSONBinPack_Decoder,\n     VARINT_TYPED_ARBITRARY_OBJECT__no_length_string__integer) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{\n      0x02,             // length 2\n      0x66, 0x6f, 0x6f, // \"foo\"\n      0x01,             // 1\n      0x62, 0x61, 0x72, // \"bar\"\n      0x02              // 2\n  };\n  Decoder decoder{stream};\n  const auto result = decoder.VARINT_TYPED_ARBITRARY_OBJECT(\n      {std::make_shared<Encoding>(UTF8_STRING_NO_LENGTH{3}),\n       std::make_shared<Encoding>(\n           BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1})});\n  EXPECT_TRUE(result.is_object());\n  EXPECT_EQ(result.size(), 2);\n  EXPECT_TRUE(result.defines(\"foo\"));\n  EXPECT_TRUE(result.defines(\"bar\"));\n  const auto &foo{result.at(\"foo\")};\n  const auto &bar{result.at(\"bar\")};\n  EXPECT_TRUE(foo.is_integer());\n  EXPECT_TRUE(bar.is_integer());\n  EXPECT_EQ(foo.to_integer(), 1);\n  EXPECT_EQ(bar.to_integer(), 2);\n}\n"
  },
  {
    "path": "test/runtime/decode_string_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Decoder, UTF8_STRING_NO_LENGTH_foo_bar) {\n  InputByteStream stream{0x66, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.UTF8_STRING_NO_LENGTH({7});\n  const sourcemeta::core::JSON expected{\"foo bar\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_foo_3) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({3});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_foo_0_foo_3) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x05};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({0});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n\n  // The cursor is now on the second string\n  EXPECT_EQ(stream.tellg(), 4);\n\n  const sourcemeta::core::JSON result2 =\n      decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({3});\n  EXPECT_EQ(result2, expected);\n}\n\nTEST(JSONBinPack_Decoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_unicode_1) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0xc3, 0xb8};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({1});\n  const sourcemeta::core::JSON expected{\"foø\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_foo_4) {\n  InputByteStream stream{0x02, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED({4});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_foo_3_foo_5) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0x6f, 0x00, 0x03, 0x05};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED({3});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n\n  // The cursor is now on the second string\n  EXPECT_EQ(stream.tellg(), 4);\n\n  const sourcemeta::core::JSON result2 =\n      decoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED({5});\n  EXPECT_EQ(result2, expected);\n}\n\nTEST(JSONBinPack_Decoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_unicode_4) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0xc3, 0xb8};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({4});\n  const sourcemeta::core::JSON expected{\"foø\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_3_5) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED({3, 5});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_3_3) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED({3, 3});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_0_6_foo_3_100) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x05};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED({0, 6});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n\n  // The cursor is now on the second string\n  EXPECT_EQ(stream.tellg(), 4);\n\n  const sourcemeta::core::JSON result2 =\n      decoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED({3, 100});\n  EXPECT_EQ(result2, expected);\n}\n\nTEST(JSONBinPack_Decoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_unicode_0_6) {\n  InputByteStream stream{0x05, 0x66, 0x6f, 0xc3, 0xb8};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED({0, 6});\n  const sourcemeta::core::JSON expected{\"foø\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, RFC3339_DATE_INTEGER_TRIPLET_2014_10_01) {\n  InputByteStream stream{0xde, 0x07, 0x0a, 0x01};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.RFC3339_DATE_INTEGER_TRIPLET({});\n  const sourcemeta::core::JSON expected{\"2014-10-01\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, PREFIX_VARINT_LENGTH_STRING_SHARED_foo) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, PREFIX_VARINT_LENGTH_STRING_SHARED_foo_foo_foo_foo) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0x6f, 0x00,\n                         0x05, 0x00, 0x03, 0x00, 0x03};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON result2 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON result3 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON result4 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n  EXPECT_EQ(result2, expected);\n  EXPECT_EQ(result3, expected);\n  EXPECT_EQ(result4, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     PREFIX_VARINT_LENGTH_STRING_SHARED_non_key_foo_key_foo) {\n  InputByteStream stream{0x01, 0x66, 0x6f, 0x6f, 0x04, 0x66, 0x6f, 0x6f};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({3});\n  const sourcemeta::core::JSON result2 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n  EXPECT_EQ(result2, expected);\n}\n\nTEST(JSONBinPack_Decoder,\n     PREFIX_VARINT_LENGTH_STRING_SHARED_key_foo_non_key_foo) {\n  InputByteStream stream{0x04, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x05};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const sourcemeta::core::JSON result1 =\n      decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON result2 =\n      decoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED({3});\n  const sourcemeta::core::JSON expected{\"foo\"};\n  EXPECT_EQ(result1, expected);\n  EXPECT_EQ(result2, expected);\n}\n\nTEST(JSONBinPack_Decoder, PREFIX_VARINT_LENGTH_STRING_SHARED_unicode) {\n  InputByteStream stream{0x05, 0x66, 0x6f, 0xc3, 0xb8};\n  sourcemeta::jsonbinpack::Decoder decoder{stream};\n  const auto result = decoder.PREFIX_VARINT_LENGTH_STRING_SHARED({});\n  const sourcemeta::core::JSON expected{\"foø\"};\n  EXPECT_EQ(result, expected);\n}\n"
  },
  {
    "path": "test/runtime/decode_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Decoder, generic_decode_BOUNDED_MULTIPLE_8BITS_ENUM_FIXED) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x00};\n  Decoder decoder{stream};\n  BOUNDED_MULTIPLE_8BITS_ENUM_FIXED options{-5, -1, 1};\n  const auto result = decoder.read(options);\n  const sourcemeta::core::JSON expected{-5};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_Decoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX_many) {\n  using namespace sourcemeta::jsonbinpack;\n  InputByteStream stream{0x15, 0x1d, 0x25};\n  Decoder decoder{stream};\n  ANY_PACKED_TYPE_TAG_BYTE_PREFIX options;\n  const auto result_1 = decoder.read(options);\n  const auto result_2 = decoder.read(options);\n  const auto result_3 = decoder.read(options);\n  const sourcemeta::core::JSON expected_1{1};\n  const sourcemeta::core::JSON expected_2{2};\n  const sourcemeta::core::JSON expected_3{3};\n  EXPECT_EQ(result_1, expected_1);\n  EXPECT_EQ(result_2, expected_2);\n  EXPECT_EQ(result_3, expected_3);\n}\n"
  },
  {
    "path": "test/runtime/decode_traits_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <type_traits>\n\nTEST(JSONBinPack_Decoder, not_copy_constructible) {\n  const bool result{\n      std::is_copy_constructible_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Decoder, not_trivially_copy_constructible) {\n  const bool result{\n      std::is_trivially_copy_constructible_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Decoder, not_nothrow_copy_constructible) {\n  const bool result{\n      std::is_nothrow_copy_constructible_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Decoder, not_copy_assignable) {\n  const bool result{\n      std::is_copy_assignable_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Decoder, not_trivially_copy_assignable) {\n  const bool result{\n      std::is_trivially_copy_assignable_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Decoder, not_nothrow_copy_assignable) {\n  const bool result{\n      std::is_nothrow_copy_assignable_v<sourcemeta::jsonbinpack::Decoder>};\n  EXPECT_FALSE(result);\n}\n"
  },
  {
    "path": "test/runtime/decode_utils.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_TEST_RUNTIME_DECODE_UTILS_H_\n#define SOURCEMETA_JSONBINPACK_TEST_RUNTIME_DECODE_UTILS_H_\n\n#include <sourcemeta/core/json.h>\n\n#include <cstdint>          // std::uint8_t\n#include <initializer_list> // std::initializer_list\n#include <sstream> // std::basic_ostringstream, std::basic_istringstream\n\nstatic auto bytes_to_string(std::initializer_list<std::uint8_t> bytes)\n    -> sourcemeta::core::JSON::String {\n  std::basic_ostringstream<sourcemeta::core::JSON::Char,\n                           sourcemeta::core::JSON::CharTraits>\n      output{};\n  for (const auto byte : bytes) {\n    output.put(static_cast<sourcemeta::core::JSON::Char>(byte));\n  }\n  return output.str();\n}\n\nclass InputByteStream\n    : public std::basic_istringstream<sourcemeta::core::JSON::Char> {\npublic:\n  InputByteStream(std::initializer_list<std::uint8_t> bytes)\n      : std::basic_istringstream<sourcemeta::core::JSON::Char>{\n            bytes_to_string(bytes)} {}\n};\n\n#endif\n"
  },
  {
    "path": "test/runtime/encode_any_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"encode_utils.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder, BYTE_CHOICE_INDEX_1__1_0_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, BYTE_CHOICE_INDEX_1__0_1_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, BYTE_CHOICE_INDEX_1__0_0_1) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  encoder.BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, BYTE_CHOICE_INDEX_bar__foo_bar_bar) {\n  const sourcemeta::core::JSON document{\"bar\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{\"foo\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  encoder.BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, BYTE_CHOICE_INDEX_non_scalar_1) {\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n\n  encoder.BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x03});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_1__1_0_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_1__0_1_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_1__0_0_1) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_bar__foo_bar_bar) {\n  const sourcemeta::core::JSON document{\"bar\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{\"foo\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_non_scalar_1) {\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x03});\n}\n\nTEST(JSONBinPack_Encoder, LARGE_CHOICE_INDEX_enum_250) {\n  const sourcemeta::core::JSON document{250};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  for (std::int64_t x = 0; x < 255; x++) {\n    choices.push_back(sourcemeta::core::JSON{x});\n  }\n\n  encoder.LARGE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0xfa, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__1_0_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.TOP_LEVEL_BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {});\n}\n\nTEST(JSONBinPack_Encoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__0_1_0) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  choices.push_back(sourcemeta::core::JSON{0});\n  encoder.TOP_LEVEL_BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, TOP_LEVEL_BYTE_CHOICE_INDEX_1__0_0_1) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{0});\n  choices.push_back(sourcemeta::core::JSON{1});\n  encoder.TOP_LEVEL_BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, TOP_LEVEL_BYTE_CHOICE_INDEX_bar__foo_bar_bar) {\n  const sourcemeta::core::JSON document{\"bar\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON{\"foo\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  choices.push_back(sourcemeta::core::JSON{\"bar\"});\n  encoder.TOP_LEVEL_BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, TOP_LEVEL_BYTE_CHOICE_INDEX_non_scalar_1) {\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  std::vector<sourcemeta::core::JSON> choices;\n\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 2 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{}\"));\n  choices.push_back(sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\"));\n  choices.push_back(sourcemeta::core::parse_json(\"{ \\\"bar\\\": 1 }\"));\n\n  encoder.TOP_LEVEL_BYTE_CHOICE_INDEX(document, {std::move(choices)});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, CONST_NONE_scalar) {\n  const sourcemeta::core::JSON document{1};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.CONST_NONE(document, {document});\n  EXPECT_BYTES(stream, {});\n}\n\nTEST(JSONBinPack_Encoder, CONST_NONE_complex) {\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.CONST_NONE(document, {document});\n  EXPECT_BYTES(stream, {});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__null) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{nullptr};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x17});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__false) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{false};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x07});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__true) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{true};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x0f});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_3_14) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{3.14};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x2f,            // tag: real number\n                           0xf4, 0x04, 0x02 // 3.14\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_3_0) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{3.0};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x37, // tag: positive real integer byte\n                           0x03  // 3\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__real_103_0) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{103.0};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x37, // tag: positive real integer byte\n                           0x67  // 103\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__256) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{256};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x1f,      // tag: positive varint\n                           0x80, 0x02 // 256\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_257) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{-257};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x27,      // tag: negative varint\n                           0x80, 0x02 // 256 = abs(-257) - 1\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__255) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{255};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x05, // tag: positive byte\n                           0xff  // 255\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_256) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{-256};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x06, // tag: negative byte\n                           0xff  // 255 = abs(-256) - 1\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__0) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{0};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x0d});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__minus_1) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{-1};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x0e});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_space) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{\" \"};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x11, 0x20});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_foo) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x21, 0x66, 0x6f, 0x6f});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_30_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(30, 'x')};\n  EXPECT_EQ(document.size(), 30);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0xf9, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__shared_string_foo) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x21,             // tag: string with length 3\n                           0x66, 0x6f, 0x6f, // \"foo\"\n                           0x20,             // tag: shared string with length 3\n                           0x04,             // position (5) - offset (1) = 4\n                           0x20,             // tag: shared string with length 3\n                           0x06              // position (7) - offset (1) = 6\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_31_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(31, 'x')};\n  EXPECT_EQ(document.size(), 31);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_61_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(61, 'x')};\n  EXPECT_EQ(document.size(), 61);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0xf2, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                        0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_url) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{\"https://soundcloud.com/dandymusicnl\"};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,\n                        0x73, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x6c, 0x6f, 0x75,\n                        0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x61, 0x6e,\n                        0x64, 0x79, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x6e, 0x6c});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_128_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(128, 'x')};\n  EXPECT_EQ(document.size(), 128);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x3f, // tag: long string, minimum 2^7\n       0x00, // length - 2^7\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_130_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(130, 'x')};\n  EXPECT_EQ(document.size(), 130);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x3f, // tag: long string, minimum 2^7\n       0x02, // length - 2^7\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_256_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(256, 'x')};\n  EXPECT_EQ(document.size(), 256);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x47, // tag: long string, minimum 2^8\n       0x00, // length - 2^8\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_258_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(258, 'x')};\n  EXPECT_EQ(document.size(), 258);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x47, // tag: long string, minimum 2^8\n       0x02, // length - 2^8\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_512_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(512, 'x')};\n  EXPECT_EQ(document.size(), 512);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x4f, // tag: long string, minimum 2^9\n       0x00, // length - 2^9\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_513_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(513, 'x')};\n  EXPECT_EQ(document.size(), 513);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x4f, // tag: long string, minimum 2^9\n       0x01, // length - 2^9\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_1024_xs) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(1024, 'x')};\n  EXPECT_EQ(document.size(), 1024);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream,\n      {0x57, // tag: long string, minimum 2^10\n       0x00, // length - 2^10\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78,\n\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n       0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_62_xs_non_shared) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(62, 'x')};\n  EXPECT_EQ(document.size(), 62);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream, {0x01, 0x01, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__string_63_xs_non_shared) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{std::string(63, 'x')};\n  EXPECT_EQ(document.size(), 63);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(\n      stream, {0x01, 0x02, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n               0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__foo_true_2000) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ \\\"foo\\\", true, 2000 ]\");\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream, {\n                           0x24,                   // tag: array with length 3\n                           0x21, 0x66, 0x6f, 0x6f, // \"foo\"\n                           0x0f,                   // true\n                           0x1f, 0xd0, 0x0f        // 2000\n                       });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_30) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Array{}};\n  for (auto count = 0; count < 30; count++) {\n    document.push_back(sourcemeta::core::JSON{true});\n  }\n\n  EXPECT_EQ(document.size(), 30);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream,\n               {0xfc, // tag: array with length 30\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_31) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Array{}};\n  for (auto count = 0; count < 31; count++) {\n    document.push_back(sourcemeta::core::JSON{true});\n  }\n\n  EXPECT_EQ(document.size(), 31);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream,\n               {0x04, // tag: array\n                0x00, // length 31 - uint5_max\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__array_32) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Array{}};\n  for (auto count = 0; count < 32; count++) {\n    document.push_back(sourcemeta::core::JSON{true});\n  }\n\n  EXPECT_EQ(document.size(), 32);\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  EXPECT_BYTES(stream,\n               {0x04, // tag: array\n                0x01, // length 32 - uint5_max\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,\n                0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f});\n}\n\nTEST(JSONBinPack_Encoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_foo_bar_baz_1) {\n  using namespace sourcemeta::jsonbinpack;\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{ \\\"foo\\\": \\\"bar\\\", \\\"baz\\\": 1 }\");\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n\n  // Deal with object property non-determinism\n  if (document.as_object().cbegin()->first == \"foo\") {\n    EXPECT_BYTES(stream,\n                 {\n                     0x1b,                   // tag: object (with length 2)\n                     0x04, 0x66, 0x6f, 0x6f, // String length 3 + \"foo\"\n                     0x21, 0x62, 0x61, 0x72, // String tag + length + 'bar'\n                     0x04, 0x62, 0x61, 0x7a, // String length 3 + 'baz'\n                     0x15 // Positive integer tag with value 1\n                 });\n  } else {\n    EXPECT_BYTES(stream,\n                 {\n                     0x1b,                   // tag: object (with length 2)\n                     0x04, 0x62, 0x61, 0x7a, // String length 3 + 'baz'\n                     0x15, // Positive integer tag with value 1\n                     0x04, 0x66, 0x6f, 0x6f, // String length 3 + \"foo\"\n                     0x21, 0x62, 0x61, 0x72  // String tag + length + 'bar'\n                 });\n  }\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_30_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Object{}};\n  const sourcemeta::core::JSON value{true};\n\n  document.assign(\"00\", value);\n  document.assign(\"01\", value);\n  document.assign(\"02\", value);\n  document.assign(\"03\", value);\n  document.assign(\"04\", value);\n  document.assign(\"05\", value);\n  document.assign(\"06\", value);\n  document.assign(\"07\", value);\n  document.assign(\"08\", value);\n  document.assign(\"09\", value);\n\n  document.assign(\"10\", value);\n  document.assign(\"11\", value);\n  document.assign(\"12\", value);\n  document.assign(\"13\", value);\n  document.assign(\"14\", value);\n  document.assign(\"15\", value);\n  document.assign(\"16\", value);\n  document.assign(\"17\", value);\n  document.assign(\"18\", value);\n  document.assign(\"19\", value);\n\n  document.assign(\"20\", value);\n  document.assign(\"21\", value);\n  document.assign(\"22\", value);\n  document.assign(\"23\", value);\n  document.assign(\"24\", value);\n  document.assign(\"25\", value);\n  document.assign(\"26\", value);\n  document.assign(\"27\", value);\n  document.assign(\"28\", value);\n  document.assign(\"29\", value);\n\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n  // JSON object ordering is non-deterministic, so its\n  // impractical to validate the actual payload\n  EXPECT_BYTES_STARTS_WITH(stream,\n                           121, // prefix (1) + (30 properties * 4 bytes each)\n                           {\n                               0xfb // Object with size 30\n                           });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_31_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Object{}};\n  const sourcemeta::core::JSON value{true};\n\n  document.assign(\"00\", value);\n  document.assign(\"01\", value);\n  document.assign(\"02\", value);\n  document.assign(\"03\", value);\n  document.assign(\"04\", value);\n  document.assign(\"05\", value);\n  document.assign(\"06\", value);\n  document.assign(\"07\", value);\n  document.assign(\"08\", value);\n  document.assign(\"09\", value);\n\n  document.assign(\"10\", value);\n  document.assign(\"11\", value);\n  document.assign(\"12\", value);\n  document.assign(\"13\", value);\n  document.assign(\"14\", value);\n  document.assign(\"15\", value);\n  document.assign(\"16\", value);\n  document.assign(\"17\", value);\n  document.assign(\"18\", value);\n  document.assign(\"19\", value);\n\n  document.assign(\"20\", value);\n  document.assign(\"21\", value);\n  document.assign(\"22\", value);\n  document.assign(\"23\", value);\n  document.assign(\"24\", value);\n  document.assign(\"25\", value);\n  document.assign(\"26\", value);\n  document.assign(\"27\", value);\n  document.assign(\"28\", value);\n  document.assign(\"29\", value);\n\n  document.assign(\"30\", value);\n\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n\n  // JSON object ordering is non-deterministic, so its\n  // impractical to validate the actual payload\n  EXPECT_BYTES_STARTS_WITH(stream,\n                           126, // prefix (2) + (31 properties * 4 bytes each)\n                           {\n                               0x03, // tag: object\n                               0x00  // length 31 - uint5_max\n                           });\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_32_entries) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Object{}};\n  const sourcemeta::core::JSON value{true};\n\n  document.assign(\"00\", value);\n  document.assign(\"01\", value);\n  document.assign(\"02\", value);\n  document.assign(\"03\", value);\n  document.assign(\"04\", value);\n  document.assign(\"05\", value);\n  document.assign(\"06\", value);\n  document.assign(\"07\", value);\n  document.assign(\"08\", value);\n  document.assign(\"09\", value);\n\n  document.assign(\"10\", value);\n  document.assign(\"11\", value);\n  document.assign(\"12\", value);\n  document.assign(\"13\", value);\n  document.assign(\"14\", value);\n  document.assign(\"15\", value);\n  document.assign(\"16\", value);\n  document.assign(\"17\", value);\n  document.assign(\"18\", value);\n  document.assign(\"19\", value);\n\n  document.assign(\"20\", value);\n  document.assign(\"21\", value);\n  document.assign(\"22\", value);\n  document.assign(\"23\", value);\n  document.assign(\"24\", value);\n  document.assign(\"25\", value);\n  document.assign(\"26\", value);\n  document.assign(\"27\", value);\n  document.assign(\"28\", value);\n  document.assign(\"29\", value);\n\n  document.assign(\"30\", value);\n  document.assign(\"31\", value);\n\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n\n  // JSON object ordering is non-deterministic, so its\n  // impractical to validate the actual payload\n  EXPECT_BYTES_STARTS_WITH(stream,\n                           130, // prefix (2) + (32 properties * 4 bytes each)\n                           {\n                               0x03, // tag: object\n                               0x01  // length 32 - uint5_max\n                           });\n}\n\nTEST(JSONBinPack_Encoder,\n     ANY_PACKED_TYPE_TAG_BYTE_PREFIX__object_62_xs_shared) {\n  using namespace sourcemeta::jsonbinpack;\n\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Object{}};\n  document.assign(\"foo\", sourcemeta::core::JSON{std::string(62, 'x')});\n  document.assign(\"bar\", sourcemeta::core::JSON{std::string(62, 'x')});\n\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.ANY_PACKED_TYPE_TAG_BYTE_PREFIX(document, {});\n\n  // Deal with object property non-determinism\n  if (document.as_object().cbegin()->first == \"foo\") {\n    EXPECT_BYTES(stream,\n                 {\n                     0x1b,                   // tag: object (with length 2)\n                     0x04, 0x66, 0x6f, 0x6f, // String length 3 + \"foo\"\n                     0x01,                   // tag: string\n                     0x01, // length 62 (with uint5_max as minimum)\n\n                     // 62 \"x\"s\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78,\n\n                     0x04, 0x62, 0x61, 0x72, // String tag + length + 'bar'\n                     0x00,                   // tag: shared string\n                     0x01, // length 62 (with uint5_max as minimum)\n                     0x44  // pointer: 75 - 7 = 68\n                 });\n  } else {\n    EXPECT_BYTES(stream,\n                 {\n                     0x1b,                   // tag: object (with length 2)\n                     0x04, 0x62, 0x61, 0x72, // String tag + length + 'bar'\n                     0x01,                   // tag: string\n                     0x01, // length 62 (with uint5_max as minimum)\n\n                     // 62 \"x\"s\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,\n                     0x78, 0x78,\n\n                     0x04, 0x66, 0x6f, 0x6f, // String length 3 + \"foo\"\n                     0x00,                   // tag: shared string\n                     0x01, // length 62 (with uint5_max as minimum)\n                     0x44  // pointer: 75 - 7 = 68\n                 });\n  }\n}\n"
  },
  {
    "path": "test/runtime/encode_array_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <vector>\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include \"encode_utils.h\"\n\nTEST(JSONBinPack_Encoder, FIXED_TYPED_ARRAY_0_1_2__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document = sourcemeta::core::parse_json(\"[ 0, 1, 2 ]\");\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.FIXED_TYPED_ARRAY(\n      document,\n      {3,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}),\n       {}});\n  EXPECT_BYTES(stream, {0x00, 0x01, 0x02});\n}\n\nTEST(JSONBinPack_Encoder, FIXED_TYPED_ARRAY_0_1_true__semityped) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ 0, 1, true ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoding first{BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}};\n  Encoding second{BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}};\n\n  Encoder encoder{stream};\n  encoder.FIXED_TYPED_ARRAY(\n      document,\n      {3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {std::move(first), std::move(second)}});\n  EXPECT_BYTES(stream, {0x00, 0x01, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, FIXED_TYPED_ARRAY_empty__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document{sourcemeta::core::JSON::Array{}};\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.FIXED_TYPED_ARRAY(\n      document,\n      {0,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1}),\n       {}});\n  EXPECT_BYTES(stream, {});\n}\n\nTEST(JSONBinPack_Encoder,\n     BOUNDED_8BITS_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.BOUNDED_8BITS_TYPED_ARRAY(\n      document,\n      {0,\n       3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x00, 0x01});\n}\n\nTEST(JSONBinPack_Encoder,\n     BOUNDED_8BITS_TYPED_ARRAY_true_false_true__same_max_min) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.BOUNDED_8BITS_TYPED_ARRAY(\n      document,\n      {3,\n       3,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n  EXPECT_BYTES(stream, {0x00, 0x01, 0x00, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_8BITS_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.BOUNDED_8BITS_TYPED_ARRAY(\n      document,\n      {1,\n       3,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n  EXPECT_BYTES(stream, {0x02, 0x01, 0x00, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_8BITS_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.BOUNDED_8BITS_TYPED_ARRAY(\n      document, {0,\n                 10,\n                 std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n                 {BYTE_CHOICE_INDEX{choices},\n                  FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01});\n}\n\nTEST(JSONBinPack_Encoder,\n     FLOOR_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.FLOOR_TYPED_ARRAY(\n      document,\n      {0,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x00, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.FLOOR_TYPED_ARRAY(\n      document,\n      {1,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n  EXPECT_BYTES(stream, {0x02, 0x01, 0x00, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.FLOOR_TYPED_ARRAY(\n      document, {0,\n                 std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n                 {BYTE_CHOICE_INDEX{choices},\n                  FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01});\n}\n\nTEST(JSONBinPack_Encoder,\n     ROOF_TYPED_ARRAY_true_false_true__no_prefix_encodings) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, true ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.ROOF_TYPED_ARRAY(\n      document,\n      {6,\n       std::make_shared<Encoding>(BYTE_CHOICE_INDEX{std::move(choices)}),\n       {}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x00, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_TYPED_ARRAY_true_false_5__1_3) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, false, 5 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.ROOF_TYPED_ARRAY(\n      document,\n      {5,\n       std::make_shared<Encoding>(BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 255, 1}),\n       {BYTE_CHOICE_INDEX{choices}, BYTE_CHOICE_INDEX{choices}}});\n  EXPECT_BYTES(stream, {0x02, 0x01, 0x00, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_TYPED_ARRAY_complex) {\n  using namespace sourcemeta::jsonbinpack;\n  sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"[ true, \\\"foo\\\", 1000 ]\");\n  OutputByteStream stream{};\n\n  std::vector<sourcemeta::core::JSON> choices;\n  choices.push_back(sourcemeta::core::JSON(false));\n  choices.push_back(sourcemeta::core::JSON(true));\n\n  Encoder encoder{stream};\n  encoder.ROOF_TYPED_ARRAY(\n      document,\n      {6,\n       std::make_shared<Encoding>(FLOOR_MULTIPLE_ENUM_VARINT{-2, 4}),\n       {BYTE_CHOICE_INDEX{choices}, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED{3}}});\n  EXPECT_BYTES(stream, {0x03, 0x01, 0x01, 0x66, 0x6f, 0x6f, 0xfa, 0x01});\n}\n"
  },
  {
    "path": "test/runtime/encode_cache_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <cstdint>\n#include <stdexcept>\n#include <string>\n\n#include <sourcemeta/jsonbinpack/runtime_encoder_cache.h>\n\nTEST(JSONBinPack_Encoder, cache_record_string) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  const auto result_1{cache.find(\"foo\", CacheType::Standalone)};\n  EXPECT_FALSE(result_1.has_value());\n  cache.record(\"foo\", 2, CacheType::Standalone);\n  const auto result_2{cache.find(\"foo\", CacheType::Standalone)};\n  EXPECT_TRUE(result_2.has_value());\n  EXPECT_EQ(result_2.value(), 2);\n}\n\nTEST(JSONBinPack_Encoder, cache_record_string_too_short) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  const auto result_1{cache.find(\"fo\", CacheType::Standalone)};\n  EXPECT_FALSE(result_1.has_value());\n  cache.record(\"fo\", 2, CacheType::Standalone);\n  const auto result_2{cache.find(\"fo\", CacheType::Standalone)};\n  EXPECT_FALSE(result_2.has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_record_string_empty) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  const auto result_1{cache.find(\"fo\", CacheType::Standalone)};\n  EXPECT_FALSE(result_1.has_value());\n  cache.record(\"\", 2, CacheType::Standalone);\n  const auto result_2{cache.find(\"\", CacheType::Standalone)};\n  EXPECT_FALSE(result_2.has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_has_on_unknown_string) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  const auto result{cache.find(\"foobarbaz\", CacheType::Standalone)};\n  EXPECT_FALSE(result.has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_increase_offset) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(\"foo\", 2, CacheType::Standalone);\n  cache.record(\"foo\", 4, CacheType::Standalone);\n  const auto result{cache.find(\"foo\", CacheType::Standalone)};\n  EXPECT_TRUE(result.has_value());\n  EXPECT_EQ(result.value(), 4);\n}\n\nTEST(JSONBinPack_Encoder, cache_do_not_decrease_offset) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(\"foo\", 4, CacheType::Standalone);\n  cache.record(\"foo\", 2, CacheType::Standalone);\n  const auto result{cache.find(\"foo\", CacheType::Standalone)};\n  EXPECT_TRUE(result.has_value());\n  EXPECT_EQ(result.value(), 4);\n}\n\nTEST(JSONBinPack_Encoder, cache_not_record_too_big) {\n  const auto length{25000000};\n  const std::string too_big(length, 'x');\n  EXPECT_EQ(too_big.size(), length);\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(too_big, 1, CacheType::Standalone);\n  const auto result{cache.find(too_big, CacheType::Standalone)};\n  EXPECT_FALSE(result.has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_remove_oldest) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(\"foo\", 10, CacheType::Standalone);\n  cache.record(\"bar\", 3, CacheType::Standalone);\n  cache.record(\"baz\", 7, CacheType::PrefixLengthVarintPlusOne);\n\n  EXPECT_TRUE(cache.find(\"foo\", CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(\"bar\", CacheType::Standalone).has_value());\n  EXPECT_TRUE(\n      cache.find(\"baz\", CacheType::PrefixLengthVarintPlusOne).has_value());\n\n  cache.remove_oldest();\n\n  EXPECT_TRUE(cache.find(\"foo\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(cache.find(\"bar\", CacheType::Standalone).has_value());\n  EXPECT_TRUE(\n      cache.find(\"baz\", CacheType::PrefixLengthVarintPlusOne).has_value());\n\n  cache.remove_oldest();\n\n  EXPECT_TRUE(cache.find(\"foo\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(cache.find(\"bar\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(\n      cache.find(\"baz\", CacheType::PrefixLengthVarintPlusOne).has_value());\n\n  cache.remove_oldest();\n\n  EXPECT_FALSE(cache.find(\"foo\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(cache.find(\"bar\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(\n      cache.find(\"baz\", CacheType::PrefixLengthVarintPlusOne).has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_is_a_circular_buffer) {\n  const auto length{5000000};\n  const std::string string_1(length, 'u');\n  const std::string string_2(length, 'v');\n  const std::string string_3(length, 'w');\n  const std::string string_4(length, 'x');\n  const std::string string_5(length, 'y');\n  const std::string string_6(length, 'z');\n\n  EXPECT_EQ(string_1.size(), length);\n  EXPECT_EQ(string_2.size(), length);\n  EXPECT_EQ(string_3.size(), length);\n  EXPECT_EQ(string_4.size(), length);\n  EXPECT_EQ(string_5.size(), length);\n  EXPECT_EQ(string_6.size(), length);\n\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n\n  cache.record(string_1, length * 0, CacheType::Standalone);\n  cache.record(string_2, length * 1, CacheType::Standalone);\n  cache.record(string_3, length * 2, CacheType::Standalone);\n  cache.record(string_4, length * 3, CacheType::Standalone);\n\n  EXPECT_TRUE(cache.find(string_1, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_2, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_3, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_4, CacheType::Standalone).has_value());\n\n  cache.record(string_5, length * 4, CacheType::Standalone);\n\n  EXPECT_FALSE(cache.find(string_1, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_2, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_3, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_4, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_5, CacheType::Standalone).has_value());\n\n  cache.record(string_6, length * 5, CacheType::Standalone);\n\n  EXPECT_FALSE(cache.find(string_1, CacheType::Standalone).has_value());\n  EXPECT_FALSE(cache.find(string_2, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_3, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_4, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_5, CacheType::Standalone).has_value());\n  EXPECT_TRUE(cache.find(string_6, CacheType::Standalone).has_value());\n}\n\nTEST(JSONBinPack_Encoder, cache_same_string_different_type) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(\"foo\", 10, CacheType::Standalone);\n  cache.record(\"foo\", 20, CacheType::PrefixLengthVarintPlusOne);\n\n  const auto result_1{cache.find(\"foo\", CacheType::Standalone)};\n  const auto result_2{cache.find(\"foo\", CacheType::PrefixLengthVarintPlusOne)};\n\n  EXPECT_TRUE(result_1.has_value());\n  EXPECT_TRUE(result_2.has_value());\n\n  EXPECT_EQ(result_1.value(), 10);\n  EXPECT_EQ(result_2.value(), 20);\n}\n\nTEST(JSONBinPack_Encoder, cache_no_fallback_type) {\n  sourcemeta::jsonbinpack::Cache cache;\n  using CacheType = sourcemeta::jsonbinpack::Cache::Type;\n  cache.record(\"foo\", 10, CacheType::Standalone);\n  EXPECT_TRUE(cache.find(\"foo\", CacheType::Standalone).has_value());\n  EXPECT_FALSE(\n      cache.find(\"foo\", CacheType::PrefixLengthVarintPlusOne).has_value());\n}\n"
  },
  {
    "path": "test/runtime/encode_integer_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <limits> // std::numeric_limits\n\n#include \"encode_utils.h\"\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder,\n     BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__minus_5_minus_5_minus_1_1) {\n  const sourcemeta::core::JSON document{-5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {-5, -1, 1});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__2_minus_5_5_1) {\n  const sourcemeta::core::JSON document{2};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {-5, 5, 1});\n  EXPECT_BYTES(stream, {0x07});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__5_2_8_1) {\n  const sourcemeta::core::JSON document{5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {2, 8, 1});\n  EXPECT_BYTES(stream, {0x03});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__5_1_19_5) {\n  const sourcemeta::core::JSON document{5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {1, 19, 5});\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__15_1_19_5) {\n  const sourcemeta::core::JSON document{15};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {1, 19, 5});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED__255_0_255_1) {\n  const sourcemeta::core::JSON document{255};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(document, {0, 255, 1});\n  EXPECT_BYTES(stream, {0xff});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_MULTIPLE_ENUM_VARINT__minus_3_minus_10_1) {\n  const sourcemeta::core::JSON document{-3};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_MULTIPLE_ENUM_VARINT(document, {-10, 1});\n  EXPECT_BYTES(stream, {0x07});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_MULTIPLE_ENUM_VARINT__5_2_1) {\n  const sourcemeta::core::JSON document{5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_MULTIPLE_ENUM_VARINT(document, {2, 1});\n  EXPECT_BYTES(stream, {0x03});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_MULTIPLE_ENUM_VARINT__10_5_5) {\n  const sourcemeta::core::JSON document{10};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_MULTIPLE_ENUM_VARINT(document, {5, 5});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_MULTIPLE_ENUM_VARINT__10_2_5) {\n  const sourcemeta::core::JSON document{10};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_MULTIPLE_ENUM_VARINT(document, {2, 5});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_MULTIPLE_ENUM_VARINT__1000_minus_2_4) {\n  const sourcemeta::core::JSON document{1000};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_MULTIPLE_ENUM_VARINT(document, {-2, 4});\n  EXPECT_BYTES(stream, {0xfa, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__minus_3_minus_2_1) {\n  const sourcemeta::core::JSON document{-3};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT(document, {-2, 1});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__8_10_1) {\n  const sourcemeta::core::JSON document{8};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT(document, {10, 1});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__5_16_5) {\n  const sourcemeta::core::JSON document{5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT(document, {15, 5});\n  EXPECT_BYTES(stream, {0x02});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_MULTIPLE_MIRROR_ENUM_VARINT__10_15_5) {\n  const sourcemeta::core::JSON document{10};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_MULTIPLE_MIRROR_ENUM_VARINT(document, {15, 5});\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_Encoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__minus_25200_1) {\n  const sourcemeta::core::JSON document{-25200};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT(document, {1});\n  EXPECT_BYTES(stream, {0xdf, 0x89, 0x03});\n}\n\nTEST(JSONBinPack_Encoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__10_5) {\n  const sourcemeta::core::JSON document{10};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT(document, {5});\n  EXPECT_BYTES(stream, {0x04});\n}\n\nTEST(JSONBinPack_Encoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__int64_max_1) {\n  const std::int64_t value = std::numeric_limits<std::int64_t>::max();\n  const sourcemeta::core::JSON document{value};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT(document, {1});\n  EXPECT_BYTES(stream,\n               {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, ARBITRARY_MULTIPLE_ZIGZAG_VARINT__int64_min_1) {\n  const std::int64_t value = std::numeric_limits<std::int64_t>::min() + 1;\n  const sourcemeta::core::JSON document{value};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ARBITRARY_MULTIPLE_ZIGZAG_VARINT(document, {1});\n  EXPECT_BYTES(stream,\n               {0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01});\n}\n"
  },
  {
    "path": "test/runtime/encode_number_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"encode_utils.h\"\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_5) {\n  const sourcemeta::core::JSON document{5.0};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0x0a, 0x00});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_minus_3_point_14) {\n  const sourcemeta::core::JSON document{-3.14};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf3, 0x04, 0x02});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_minus_5) {\n  const sourcemeta::core::JSON document{-5.0};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0x09, 0x00});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_zero) {\n  const sourcemeta::core::JSON document{0.0};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0x00, 0x00});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_1235) {\n  const sourcemeta::core::JSON document{1235.0};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x00});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_0_point_1235) {\n  const sourcemeta::core::JSON document{0.1235};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x04});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_1_point_235) {\n  const sourcemeta::core::JSON document{1.235};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x03});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_0_point_01235) {\n  const sourcemeta::core::JSON document{0.01235};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_12_35) {\n  const sourcemeta::core::JSON document{12.35};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x02});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_0_point_001235) {\n  const sourcemeta::core::JSON document{0.001235};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x06});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_123_point_5) {\n  const sourcemeta::core::JSON document{123.5};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xa6, 0x13, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_314) {\n  const sourcemeta::core::JSON document{314.0};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf4, 0x04, 0x00});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_0_point_314) {\n  const sourcemeta::core::JSON document{0.314};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf4, 0x04, 0x03});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_3_point_14) {\n  const sourcemeta::core::JSON document{3.14};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf4, 0x04, 0x02});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_0_point_0314) {\n  const sourcemeta::core::JSON document{0.0314};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf4, 0x04, 0x04});\n}\n\nTEST(JSONBinPack_Encoder, DOUBLE_VARINT_TUPLE_31_point_4) {\n  const sourcemeta::core::JSON document{31.4};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.DOUBLE_VARINT_TUPLE(document, {});\n  EXPECT_BYTES(stream, {0xf4, 0x04, 0x01});\n}\n"
  },
  {
    "path": "test/runtime/encode_object_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <sourcemeta/core/json.h>\n\n#include \"encode_utils.h\"\n\nTEST(JSONBinPack_Encoder,\n     FIXED_TYPED_ARBITRARY_OBJECT__no_length_string__integer) {\n  using namespace sourcemeta::jsonbinpack;\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{\\\"foo\\\":1,\\\"bar\\\":2}\");\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.FIXED_TYPED_ARBITRARY_OBJECT(\n      document, {2, std::make_shared<Encoding>(UTF8_STRING_NO_LENGTH{3}),\n                 std::make_shared<Encoding>(\n                     BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1})});\n\n  // Deal with object property non-determinism\n  if (document.as_object().cbegin()->first == \"foo\") {\n    EXPECT_BYTES(stream, {\n                             0x66, 0x6f, 0x6f, // \"foo\"\n                             0x01,             // 1\n                             0x62, 0x61, 0x72, // \"bar\"\n                             0x02              // 2\n                         });\n  } else {\n    EXPECT_BYTES(stream, {\n                             0x62, 0x61, 0x72, // \"bar\"\n                             0x02,             // 2\n                             0x66, 0x6f, 0x6f, // \"foo\"\n                             0x01              // 1\n                         });\n  }\n}\n\nTEST(JSONBinPack_Encoder,\n     VARINT_TYPED_ARBITRARY_OBJECT__no_length_string__integer) {\n  using namespace sourcemeta::jsonbinpack;\n  const sourcemeta::core::JSON document =\n      sourcemeta::core::parse_json(\"{\\\"foo\\\":1,\\\"bar\\\":2}\");\n  OutputByteStream stream{};\n\n  Encoder encoder{stream};\n  encoder.VARINT_TYPED_ARBITRARY_OBJECT(\n      document, {std::make_shared<Encoding>(UTF8_STRING_NO_LENGTH{3}),\n                 std::make_shared<Encoding>(\n                     BOUNDED_MULTIPLE_8BITS_ENUM_FIXED{0, 10, 1})});\n\n  // Deal with object property non-determinism\n  if (document.as_object().cbegin()->first == \"foo\") {\n    EXPECT_BYTES(stream, {\n                             0x02,             // length 2\n                             0x66, 0x6f, 0x6f, // \"foo\"\n                             0x01,             // 1\n                             0x62, 0x61, 0x72, // \"bar\"\n                             0x02              // 2\n                         });\n  } else {\n    EXPECT_BYTES(stream, {\n                             0x02,             // length 2\n                             0x62, 0x61, 0x72, // \"bar\"\n                             0x02,             // 2\n                             0x66, 0x6f, 0x6f, // \"foo\"\n                             0x01              // 1\n                         });\n  }\n}\n"
  },
  {
    "path": "test/runtime/encode_real_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/numeric.h>\n\nTEST(JSONBinPack_Encoder, real_digits_1) {\n  const double input{3.14};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 314);\n  EXPECT_EQ(point_position, 2);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_2) {\n  const double input{123.456};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 123456);\n  EXPECT_EQ(point_position, 3);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_3) {\n  const double input{-3.14};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, -314);\n  EXPECT_EQ(point_position, 2);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_4) {\n  const double input{0};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 0);\n  EXPECT_EQ(point_position, 0);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_5) {\n  const double input{-0};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 0);\n  EXPECT_EQ(point_position, 0);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_6) {\n  const double input{1};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 1);\n  EXPECT_EQ(point_position, 0);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_7) {\n  const double input{-1};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, -1);\n  EXPECT_EQ(point_position, 0);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_8) {\n  const double input{0.0001};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 1);\n  EXPECT_EQ(point_position, 4);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_9) {\n  const double input{0.000123};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 123);\n  EXPECT_EQ(point_position, 6);\n}\n\nTEST(JSONBinPack_Encoder, real_digits_10) {\n  const double input{-0.000123};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, -123);\n  EXPECT_EQ(point_position, 6);\n}\n\nTEST(JSONBinPack_Encoder, integer_5) {\n  const double input{5};\n  std::uint64_t point_position;\n  const std::int64_t result{\n      sourcemeta::core::real_digits<std::int64_t>(input, point_position)};\n  EXPECT_EQ(result, 5);\n  EXPECT_EQ(point_position, 0);\n}\n"
  },
  {
    "path": "test/runtime/encode_string_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"encode_utils.h\"\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder, UTF8_STRING_NO_LENGTH_foo_bar) {\n  const sourcemeta::core::JSON document{\"foo bar\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.UTF8_STRING_NO_LENGTH(document, {7});\n  EXPECT_BYTES(stream, {0x66, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_foo_3) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {3});\n  EXPECT_BYTES(stream, {0x01, 0x66, 0x6f, 0x6f});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_foo_0_foo_3) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {0});\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {3});\n  EXPECT_BYTES(stream, {0x04, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_unicode_1) {\n  const sourcemeta::core::JSON document{\"foø\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {1});\n  EXPECT_BYTES(stream, {0x04, 0x66, 0x6f, 0xc3, 0xb8});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_foo_4) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(document, {4});\n  EXPECT_BYTES(stream, {0x02, 0x66, 0x6f, 0x6f});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_foo_3_foo_5) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(document, {3});\n  encoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(document, {5});\n  EXPECT_BYTES(stream, {0x01, 0x66, 0x6f, 0x6f, 0x00, 0x03, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_unicode_4) {\n  const sourcemeta::core::JSON document{\"foø\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.ROOF_VARINT_PREFIX_UTF8_STRING_SHARED(document, {4});\n  EXPECT_BYTES(stream, {0x01, 0x66, 0x6f, 0xc3, 0xb8});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_3_5) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(document, {3, 5});\n  EXPECT_BYTES(stream, {0x01, 0x66, 0x6f, 0x6f});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_3_3) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(document, {3, 3});\n  EXPECT_BYTES(stream, {0x01, 0x66, 0x6f, 0x6f});\n}\n\nTEST(JSONBinPack_Encoder,\n     BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_foo_0_6_foo_3_100) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(document, {0, 6});\n  encoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(document, {3, 100});\n  EXPECT_BYTES(stream, {0x04, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x05});\n}\n\nTEST(JSONBinPack_Encoder, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_unicode_0_6) {\n  const sourcemeta::core::JSON document{\"foø\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED(document, {0, 6});\n  EXPECT_BYTES(stream, {0x05, 0x66, 0x6f, 0xc3, 0xb8});\n}\n\nTEST(JSONBinPack_Encoder, RFC3339_DATE_INTEGER_TRIPLET_2014_10_01) {\n  const sourcemeta::core::JSON document{\"2014-10-01\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.RFC3339_DATE_INTEGER_TRIPLET(document, {});\n  EXPECT_BYTES(stream, {0xde, 0x07, 0x0a, 0x01});\n}\n\nTEST(JSONBinPack_Encoder, PREFIX_VARINT_LENGTH_STRING_SHARED_foo) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  EXPECT_BYTES(stream, {\n                           0x04,            // String length + 1\n                           0x66, 0x6f, 0x6f // \"foo\"\n                       });\n}\n\nTEST(JSONBinPack_Encoder, PREFIX_VARINT_LENGTH_STRING_SHARED_foo_foo_foo_foo) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n\n  EXPECT_BYTES(stream, {\n                           0x04,             // String length + 1\n                           0x66, 0x6f, 0x6f, // \"foo\"\n                           0x00,             // Start of pointer\n                           0x05, // Pointer (current = 5 - location = 0)\n                           0x00, // Start of pointer\n                           0x03, // Pointer (current = 7 - location = 3)\n                           0x00, // Start of pointer\n                           0x03  // Pointer (current = 9 - location = 3)\n                       });\n}\n\nTEST(JSONBinPack_Encoder,\n     PREFIX_VARINT_LENGTH_STRING_SHARED_non_key_foo_key_foo) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {3});\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n\n  EXPECT_BYTES(stream, {\n                           0x01,             // String length + 1 - 3\n                           0x66, 0x6f, 0x6f, // \"foo\"\n                           0x04,             // String length + 1\n                           0x66, 0x6f, 0x6f  // \"foo\"\n                       });\n}\n\nTEST(JSONBinPack_Encoder,\n     PREFIX_VARINT_LENGTH_STRING_SHARED_key_foo_non_key_foo) {\n  const sourcemeta::core::JSON document{\"foo\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  encoder.FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED(document, {3});\n\n  EXPECT_BYTES(stream, {\n                           0x04,             // String length + 1\n                           0x66, 0x6f, 0x6f, // \"foo\"\n                           0x00,             // Start of pointer\n                           0x01,             // String length + 1 - 3\n                           0x05              // Pointer (6 - 1 = 5)\n                       });\n}\n\nTEST(JSONBinPack_Encoder, PREFIX_VARINT_LENGTH_STRING_SHARED_unicode) {\n  const sourcemeta::core::JSON document{\"foø\"};\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::Encoder encoder{stream};\n  encoder.PREFIX_VARINT_LENGTH_STRING_SHARED(document, {});\n  EXPECT_BYTES(stream, {0x05, 0x66, 0x6f, 0xc3, 0xb8});\n}\n"
  },
  {
    "path": "test/runtime/encode_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include \"encode_utils.h\"\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder, generic_encode_BOUNDED_MULTIPLE_8BITS_ENUM_FIXED) {\n  using namespace sourcemeta::jsonbinpack;\n  const sourcemeta::core::JSON document{-5};\n  OutputByteStream stream{};\n  Encoder encoder{stream};\n  BOUNDED_MULTIPLE_8BITS_ENUM_FIXED options{-5, -1, 1};\n  encoder.write(document, options);\n  EXPECT_BYTES(stream, {0x00});\n}\n\nTEST(JSONBinPack_Encoder, ANY_PACKED_TYPE_TAG_BYTE_PREFIX_many) {\n  using namespace sourcemeta::jsonbinpack;\n  OutputByteStream stream{};\n  Encoder encoder{stream};\n  ANY_PACKED_TYPE_TAG_BYTE_PREFIX options;\n  encoder.write(sourcemeta::core::JSON{1}, options);\n  encoder.write(sourcemeta::core::JSON{2}, options);\n  encoder.write(sourcemeta::core::JSON{3}, options);\n  EXPECT_BYTES(stream, {0x15, 0x1d, 0x25});\n}\n"
  },
  {
    "path": "test/runtime/encode_traits_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <type_traits>\n\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Encoder, not_copy_constructible) {\n  const bool result{\n      std::is_copy_constructible_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Encoder, not_trivially_copy_constructible) {\n  const bool result{\n      std::is_trivially_copy_constructible_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Encoder, not_nothrow_copy_constructible) {\n  const bool result{\n      std::is_nothrow_copy_constructible_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Encoder, not_copy_assignable) {\n  const bool result{\n      std::is_copy_assignable_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Encoder, not_trivially_copy_assignable) {\n  const bool result{\n      std::is_trivially_copy_assignable_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n\nTEST(JSONBinPack_Encoder, not_nothrow_copy_assignable) {\n  const bool result{\n      std::is_nothrow_copy_assignable_v<sourcemeta::jsonbinpack::Encoder>};\n  EXPECT_FALSE(result);\n}\n"
  },
  {
    "path": "test/runtime/encode_utils.h",
    "content": "#ifndef SOURCEMETA_JSONBINPACK_TEST_RUNTIME_ENCODE_UTILS_H_\n#define SOURCEMETA_JSONBINPACK_TEST_RUNTIME_ENCODE_UTILS_H_\n\n#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <algorithm>        // std::transform\n#include <cassert>          // assert\n#include <cstddef>          // std::byte\n#include <cstdint>          // std::uint8_t\n#include <initializer_list> // std::initializer_list\n#include <iterator>         // std::back_inserter\n#include <sstream>          // std::basic_ostringstream\n#include <vector>           // std::vector\n\nstatic inline auto to_byte(const std::uint8_t input) -> std::byte {\n  return std::byte{input};\n}\n\nclass OutputByteStream\n    : public std::basic_ostringstream<sourcemeta::core::JSON::Char> {\npublic:\n  // Convert the stream into an array of bytes\n  auto bytes() const -> const std::vector<std::byte> {\n    std::vector<std::byte> result{};\n    const sourcemeta::core::JSON::String string{this->str()};\n    std::transform(string.cbegin(), string.cend(), std::back_inserter(result),\n                   [](const auto character) {\n                     return to_byte(static_cast<std::uint8_t>(character));\n                   });\n    return result;\n  }\n};\n\ninline auto EXPECT_BYTES(const OutputByteStream &stream,\n                         std::initializer_list<std::uint8_t> bytes) -> void {\n  const std::vector<std::byte> actual{stream.bytes()};\n  std::vector<std::byte> expected{};\n  std::transform(bytes.begin(), bytes.end(), std::back_inserter(expected),\n                 [](const auto character) {\n                   return to_byte(static_cast<std::uint8_t>(character));\n                 });\n  EXPECT_EQ(actual, expected);\n}\n\ninline auto EXPECT_BYTES_STARTS_WITH(const OutputByteStream &stream,\n                                     const std::size_t total,\n                                     std::initializer_list<std::uint8_t> bytes)\n    -> void {\n  const std::vector<std::byte> actual{stream.bytes()};\n  EXPECT_EQ(actual.size(), total);\n  std::vector<std::byte> expected{};\n  std::transform(bytes.begin(), bytes.end(), std::back_inserter(expected),\n                 [](const auto character) {\n                   return to_byte(static_cast<std::uint8_t>(character));\n                 });\n  assert(total > expected.size());\n  auto iterator{actual.cbegin()};\n  std::advance(iterator, expected.size());\n  const std::vector<std::byte> prefix{actual.cbegin(), iterator};\n  EXPECT_EQ(prefix, expected);\n}\n\n#endif\n"
  },
  {
    "path": "test/runtime/encoding_traits_test.cc",
    "content": "#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <gtest/gtest.h>\n#include <type_traits>\n\nTEST(JSONBinPack_Encoding, encoding_movable) {\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::is_move_constructible_v<Encoding>);\n}\n\nTEST(JSONBinPack_Encoding, encoding_nothrow_movable) {\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::is_nothrow_move_constructible_v<Encoding>);\n}\n\nTEST(JSONBinPack_Encoding, encoding_copyable) {\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::is_copy_constructible_v<Encoding>);\n}\n"
  },
  {
    "path": "test/runtime/input_stream_varint_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <limits> // std::numeric_limits\n\n#include \"decode_utils.h\"\n\n#include <sourcemeta/jsonbinpack/runtime_input_stream.h>\n\nTEST(JSONBinPack_InputStream, varint_0x01) {\n  InputByteStream stream{0x01};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  EXPECT_EQ(decoder.get_varint(), 1);\n}\n\nTEST(JSONBinPack_InputStream, varint_0x17) {\n  InputByteStream stream{0x17};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  EXPECT_EQ(decoder.get_varint(), 23);\n}\n\nTEST(JSONBinPack_InputStream, varint_0xac_0x02) {\n  InputByteStream stream{{0xac, 0x02}};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  EXPECT_EQ(decoder.get_varint(), 300);\n}\n\nTEST(JSONBinPack_InputStream, varint_0xdf_0x89_0x03) {\n  InputByteStream stream{{0xdf, 0x89, 0x03}};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  EXPECT_EQ(decoder.get_varint(), 50399);\n}\n\nTEST(JSONBinPack_InputStream, varint_0xfe_0xff_0xff_0xff_0x0f) {\n  InputByteStream stream{{0xfe, 0xff, 0xff, 0xff, 0x0f}};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  const std::uint64_t result{decoder.get_varint()};\n  const std::uint64_t expected{4294967294};\n  EXPECT_EQ(result, expected);\n}\n\nTEST(JSONBinPack_InputStream, varint_uint64_max) {\n  // In Base-128: (1)1111111 (1)1111111 (1)1111111 (1)1111111\n  // (1)1111111 (1)1111111 (1)1111111 (1)1111111 (1)1111111 (0)0000001\n  InputByteStream stream{\n      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}};\n  sourcemeta::jsonbinpack::InputStream decoder{stream};\n  const std::uint64_t result{decoder.get_varint()};\n  const std::uint64_t expected{18446744073709551615U};\n  EXPECT_EQ(result, expected);\n}\n"
  },
  {
    "path": "test/runtime/output_stream_varint_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <limits> // std::numeric_limits\n\n#include \"encode_utils.h\"\n\n#include <sourcemeta/jsonbinpack/runtime_output_stream.h>\n\nTEST(JSONBinPack_OutputStream, varint_1) {\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(1);\n  EXPECT_BYTES(stream, {0x01});\n}\n\nTEST(JSONBinPack_OutputStream, varint_23) {\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(23);\n  EXPECT_BYTES(stream, {0x17});\n}\n\nTEST(JSONBinPack_OutputStream, varint_300) {\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(300);\n  EXPECT_BYTES(stream, {0xac, 0x02});\n}\n\nTEST(JSONBinPack_OutputStream, varint_50399) {\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(50399);\n  EXPECT_BYTES(stream, {0xdf, 0x89, 0x03});\n}\n\nTEST(JSONBinPack_OutputStream, varint_4294967294) {\n  OutputByteStream stream{};\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(4294967294);\n  EXPECT_BYTES(stream, {0xfe, 0xff, 0xff, 0xff, 0x0f});\n}\n\nTEST(JSONBinPack_OutputStream, varint_uint64_max) {\n  OutputByteStream stream{};\n  const std::uint64_t value = std::numeric_limits<std::uint64_t>::max();\n  sourcemeta::jsonbinpack::OutputStream encoder{stream};\n  encoder.put_varint(value);\n  // The input is 18446744073709551615\n  // In hex: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff\n  // In binary: 11111111 11111111 11111111 11111111 11111111 11111111 11111111\n  // 11111111\n  // In Base-128: (1)1111111 (1)1111111 (1)1111111 (1)1111111\n  // (1)1111111 (1)1111111 (1)1111111 (1)1111111 (1)1111111 (0)0000001\n  EXPECT_BYTES(stream,\n               {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01});\n}\n"
  },
  {
    "path": "test/runtime/v1_any_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <variant>\n\nTEST(JSONBinPack_Loader_v1, BYTE_CHOICE_INDEX_scalars) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BYTE_CHOICE_INDEX\",\n    \"binpackOptions\": {\n      \"choices\": [ 1, 2, 3 ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<BYTE_CHOICE_INDEX>(result));\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(result).choices.size(), 3);\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(result).choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(result).choices.at(1),\n            sourcemeta::core::JSON{2});\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(result).choices.at(2),\n            sourcemeta::core::JSON{3});\n}\n\nTEST(JSONBinPack_Loader_v1, LARGE_CHOICE_INDEX_scalars) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"LARGE_CHOICE_INDEX\",\n    \"binpackOptions\": {\n      \"choices\": [ 1, 2, 3 ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<LARGE_CHOICE_INDEX>(result));\n  EXPECT_EQ(std::get<LARGE_CHOICE_INDEX>(result).choices.size(), 3);\n  EXPECT_EQ(std::get<LARGE_CHOICE_INDEX>(result).choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<LARGE_CHOICE_INDEX>(result).choices.at(1),\n            sourcemeta::core::JSON{2});\n  EXPECT_EQ(std::get<LARGE_CHOICE_INDEX>(result).choices.at(2),\n            sourcemeta::core::JSON{3});\n}\n\nTEST(JSONBinPack_Loader_v1, TOP_LEVEL_BYTE_CHOICE_INDEX_scalars) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"TOP_LEVEL_BYTE_CHOICE_INDEX\",\n    \"binpackOptions\": {\n      \"choices\": [ 1, 2, 3 ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<TOP_LEVEL_BYTE_CHOICE_INDEX>(result));\n  EXPECT_EQ(std::get<TOP_LEVEL_BYTE_CHOICE_INDEX>(result).choices.size(), 3);\n  EXPECT_EQ(std::get<TOP_LEVEL_BYTE_CHOICE_INDEX>(result).choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<TOP_LEVEL_BYTE_CHOICE_INDEX>(result).choices.at(1),\n            sourcemeta::core::JSON{2});\n  EXPECT_EQ(std::get<TOP_LEVEL_BYTE_CHOICE_INDEX>(result).choices.at(2),\n            sourcemeta::core::JSON{3});\n}\n\nTEST(JSONBinPack_Loader_v1, CONST_NONE_scalar) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"CONST_NONE\",\n    \"binpackOptions\": {\n      \"value\": 1\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<CONST_NONE>(result));\n  EXPECT_EQ(std::get<CONST_NONE>(result).value, sourcemeta::core::JSON{1});\n}\n\nTEST(JSONBinPack_Loader_v1, ANY_PACKED_TYPE_TAG_BYTE_PREFIX) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ANY_PACKED_TYPE_TAG_BYTE_PREFIX\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<ANY_PACKED_TYPE_TAG_BYTE_PREFIX>(result));\n}\n"
  },
  {
    "path": "test/runtime/v1_array_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <variant>\n\nTEST(JSONBinPack_Loader_v1, FIXED_TYPED_ARRAY_enum_integer_number) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FIXED_TYPED_ARRAY\",\n    \"binpackOptions\": {\n      \"size\": 3,\n      \"encoding\": {\n        \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n        \"binpackOptions\": {}\n      },\n      \"prefixEncodings\": [\n        {\n          \"binpackEncoding\": \"BYTE_CHOICE_INDEX\",\n          \"binpackOptions\": {\n            \"choices\": [ 1, 2 ]\n          }\n        },\n        {\n          \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n          \"binpackOptions\": {\n            \"multiplier\": 1\n          }\n        }\n      ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<FIXED_TYPED_ARRAY>(result));\n  EXPECT_EQ(std::get<FIXED_TYPED_ARRAY>(result).size, 3);\n  EXPECT_TRUE(std::holds_alternative<DOUBLE_VARINT_TUPLE>(\n      *(std::get<FIXED_TYPED_ARRAY>(result).encoding)));\n  EXPECT_EQ(std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.size(), 2);\n\n  EXPECT_TRUE(std::holds_alternative<BYTE_CHOICE_INDEX>(\n      std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(0)));\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.size(),\n            2);\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(1),\n            sourcemeta::core::JSON{2});\n\n  EXPECT_TRUE(std::holds_alternative<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n      std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(1)));\n  EXPECT_EQ(std::get<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n                std::get<FIXED_TYPED_ARRAY>(result).prefix_encodings.at(1))\n                .multiplier,\n            1);\n}\n\nTEST(JSONBinPack_Loader_v1, BOUNDED_8BITS_TYPED_ARRAY_enum_integer_number) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BOUNDED_8BITS_TYPED_ARRAY\",\n    \"binpackOptions\": {\n      \"minimum\": 1,\n      \"maximum\": 3,\n      \"encoding\": {\n        \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n        \"binpackOptions\": {}\n      },\n      \"prefixEncodings\": [\n        {\n          \"binpackEncoding\": \"BYTE_CHOICE_INDEX\",\n          \"binpackOptions\": {\n            \"choices\": [ 1, 2 ]\n          }\n        },\n        {\n          \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n          \"binpackOptions\": {\n            \"multiplier\": 1\n          }\n        }\n      ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<BOUNDED_8BITS_TYPED_ARRAY>(result));\n  EXPECT_EQ(std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).minimum, 1);\n  EXPECT_EQ(std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).maximum, 3);\n  EXPECT_TRUE(std::holds_alternative<DOUBLE_VARINT_TUPLE>(\n      *(std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).encoding)));\n  EXPECT_EQ(std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.size(),\n            2);\n\n  EXPECT_TRUE(std::holds_alternative<BYTE_CHOICE_INDEX>(\n      std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(0)));\n  EXPECT_EQ(\n      std::get<BYTE_CHOICE_INDEX>(\n          std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(0))\n          .choices.size(),\n      2);\n  EXPECT_EQ(\n      std::get<BYTE_CHOICE_INDEX>(\n          std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(0))\n          .choices.at(0),\n      sourcemeta::core::JSON{1});\n  EXPECT_EQ(\n      std::get<BYTE_CHOICE_INDEX>(\n          std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(0))\n          .choices.at(1),\n      sourcemeta::core::JSON{2});\n\n  EXPECT_TRUE(std::holds_alternative<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n      std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(1)));\n  EXPECT_EQ(\n      std::get<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n          std::get<BOUNDED_8BITS_TYPED_ARRAY>(result).prefix_encodings.at(1))\n          .multiplier,\n      1);\n}\n\nTEST(JSONBinPack_Loader_v1, FLOOR_TYPED_ARRAY_enum_integer_number) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_TYPED_ARRAY\",\n    \"binpackOptions\": {\n      \"minimum\": 1,\n      \"encoding\": {\n        \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n        \"binpackOptions\": {}\n      },\n      \"prefixEncodings\": [\n        {\n          \"binpackEncoding\": \"BYTE_CHOICE_INDEX\",\n          \"binpackOptions\": {\n            \"choices\": [ 1, 2 ]\n          }\n        },\n        {\n          \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n          \"binpackOptions\": {\n            \"multiplier\": 1\n          }\n        }\n      ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<FLOOR_TYPED_ARRAY>(result));\n  EXPECT_EQ(std::get<FLOOR_TYPED_ARRAY>(result).minimum, 1);\n  EXPECT_TRUE(std::holds_alternative<DOUBLE_VARINT_TUPLE>(\n      *(std::get<FLOOR_TYPED_ARRAY>(result).encoding)));\n  EXPECT_EQ(std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.size(), 2);\n\n  EXPECT_TRUE(std::holds_alternative<BYTE_CHOICE_INDEX>(\n      std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(0)));\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.size(),\n            2);\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(1),\n            sourcemeta::core::JSON{2});\n\n  EXPECT_TRUE(std::holds_alternative<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n      std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(1)));\n  EXPECT_EQ(std::get<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n                std::get<FLOOR_TYPED_ARRAY>(result).prefix_encodings.at(1))\n                .multiplier,\n            1);\n}\n\nTEST(JSONBinPack_Loader_v1, ROOF_TYPED_ARRAY_enum_integer_number) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ROOF_TYPED_ARRAY\",\n    \"binpackOptions\": {\n      \"maximum\": 3,\n      \"encoding\": {\n        \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n        \"binpackOptions\": {}\n      },\n      \"prefixEncodings\": [\n        {\n          \"binpackEncoding\": \"BYTE_CHOICE_INDEX\",\n          \"binpackOptions\": {\n            \"choices\": [ 1, 2 ]\n          }\n        },\n        {\n          \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n          \"binpackOptions\": {\n            \"multiplier\": 1\n          }\n        }\n      ]\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<ROOF_TYPED_ARRAY>(result));\n  EXPECT_EQ(std::get<ROOF_TYPED_ARRAY>(result).maximum, 3);\n  EXPECT_TRUE(std::holds_alternative<DOUBLE_VARINT_TUPLE>(\n      *(std::get<ROOF_TYPED_ARRAY>(result).encoding)));\n  EXPECT_EQ(std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.size(), 2);\n\n  EXPECT_TRUE(std::holds_alternative<BYTE_CHOICE_INDEX>(\n      std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(0)));\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.size(),\n            2);\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(0),\n            sourcemeta::core::JSON{1});\n  EXPECT_EQ(std::get<BYTE_CHOICE_INDEX>(\n                std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(0))\n                .choices.at(1),\n            sourcemeta::core::JSON{2});\n\n  EXPECT_TRUE(std::holds_alternative<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n      std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(1)));\n  EXPECT_EQ(std::get<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(\n                std::get<ROOF_TYPED_ARRAY>(result).prefix_encodings.at(1))\n                .multiplier,\n            1);\n}\n"
  },
  {
    "path": "test/runtime/v1_integer_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <variant>\n\nTEST(JSONBinPack_Loader_v1, BOUNDED_MULTIPLE_8BITS_ENUM_FIXED_positive) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BOUNDED_MULTIPLE_8BITS_ENUM_FIXED\",\n    \"binpackOptions\": {\n      \"minimum\": 0,\n      \"maximum\": 100,\n      \"multiplier\": 2\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(\n      std::holds_alternative<BOUNDED_MULTIPLE_8BITS_ENUM_FIXED>(result));\n  EXPECT_EQ(std::get<BOUNDED_MULTIPLE_8BITS_ENUM_FIXED>(result).minimum, 0);\n  EXPECT_EQ(std::get<BOUNDED_MULTIPLE_8BITS_ENUM_FIXED>(result).maximum, 100);\n  EXPECT_EQ(std::get<BOUNDED_MULTIPLE_8BITS_ENUM_FIXED>(result).multiplier, 2);\n}\n\nTEST(JSONBinPack_Loader_v1, FLOOR_MULTIPLE_ENUM_VARINT_positive) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_MULTIPLE_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"minimum\": 0,\n      \"multiplier\": 2\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<FLOOR_MULTIPLE_ENUM_VARINT>(result));\n  EXPECT_EQ(std::get<FLOOR_MULTIPLE_ENUM_VARINT>(result).minimum, 0);\n  EXPECT_EQ(std::get<FLOOR_MULTIPLE_ENUM_VARINT>(result).multiplier, 2);\n}\n\nTEST(JSONBinPack_Loader_v1, ROOF_MULTIPLE_MIRROR_ENUM_VARINT_positive) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ROOF_MULTIPLE_MIRROR_ENUM_VARINT\",\n    \"binpackOptions\": {\n      \"maximum\": 100,\n      \"multiplier\": 2\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<ROOF_MULTIPLE_MIRROR_ENUM_VARINT>(result));\n  EXPECT_EQ(std::get<ROOF_MULTIPLE_MIRROR_ENUM_VARINT>(result).maximum, 100);\n  EXPECT_EQ(std::get<ROOF_MULTIPLE_MIRROR_ENUM_VARINT>(result).multiplier, 2);\n}\n\nTEST(JSONBinPack_Loader_v1, ARBITRARY_MULTIPLE_ZIGZAG_VARINT_unit_multiplier) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ARBITRARY_MULTIPLE_ZIGZAG_VARINT\",\n    \"binpackOptions\": {\n      \"multiplier\": 1\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(result));\n  EXPECT_EQ(std::get<ARBITRARY_MULTIPLE_ZIGZAG_VARINT>(result).multiplier, 1);\n}\n"
  },
  {
    "path": "test/runtime/v1_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\nTEST(JSONBinPack_Loader_v1, invalid_encoding_name) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FOO_BAR\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  EXPECT_THROW(sourcemeta::jsonbinpack::load(input),\n               sourcemeta::jsonbinpack::EncodingError);\n}\n"
  },
  {
    "path": "test/runtime/v1_number_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <variant>\n\nTEST(JSONBinPack_Loader_v1, DOUBLE_VARINT_TUPLE) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"DOUBLE_VARINT_TUPLE\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<DOUBLE_VARINT_TUPLE>(result));\n}\n"
  },
  {
    "path": "test/runtime/v1_string_loader_test.cc",
    "content": "#include <gtest/gtest.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/jsonbinpack/runtime.h>\n\n#include <variant>\n\nTEST(JSONBinPack_Loader_v1, UTF8_STRING_NO_LENGTH_3) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"UTF8_STRING_NO_LENGTH\",\n    \"binpackOptions\": {\n      \"size\": 3\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<UTF8_STRING_NO_LENGTH>(result));\n  EXPECT_EQ(std::get<UTF8_STRING_NO_LENGTH>(result).size, 3);\n}\n\nTEST(JSONBinPack_Loader_v1, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED_3) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED\",\n    \"binpackOptions\": {\n      \"minimum\": 3\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(\n      std::holds_alternative<FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED>(result));\n  EXPECT_EQ(std::get<FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED>(result).minimum,\n            3);\n}\n\nTEST(JSONBinPack_Loader_v1, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED_3) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"ROOF_VARINT_PREFIX_UTF8_STRING_SHARED\",\n    \"binpackOptions\": {\n      \"maximum\": 3\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(\n      std::holds_alternative<ROOF_VARINT_PREFIX_UTF8_STRING_SHARED>(result));\n  EXPECT_EQ(std::get<ROOF_VARINT_PREFIX_UTF8_STRING_SHARED>(result).maximum, 3);\n}\n\nTEST(JSONBinPack_Loader_v1, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED_open) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED\",\n    \"binpackOptions\": {\n      \"minimum\": 1,\n      \"maximum\": 3\n    }\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(\n      std::holds_alternative<BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED>(result));\n  EXPECT_EQ(std::get<BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED>(result).minimum,\n            1);\n  EXPECT_EQ(std::get<BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED>(result).maximum,\n            3);\n}\n\nTEST(JSONBinPack_Loader_v1, RFC3339_DATE_INTEGER_TRIPLET) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"RFC3339_DATE_INTEGER_TRIPLET\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(std::holds_alternative<RFC3339_DATE_INTEGER_TRIPLET>(result));\n}\n\nTEST(JSONBinPack_Loader_v1, PREFIX_VARINT_LENGTH_STRING_SHARED) {\n  const sourcemeta::core::JSON input = sourcemeta::core::parse_json(R\"JSON({\n    \"$schema\": \"tag:sourcemeta.com,2024:jsonbinpack/encoding/v1\",\n    \"binpackEncoding\": \"PREFIX_VARINT_LENGTH_STRING_SHARED\",\n    \"binpackOptions\": {}\n  })JSON\");\n\n  const auto result{sourcemeta::jsonbinpack::load(input)};\n  using namespace sourcemeta::jsonbinpack;\n  EXPECT_TRUE(\n      std::holds_alternative<PREFIX_VARINT_LENGTH_STRING_SHARED>(result));\n}\n"
  },
  {
    "path": "vendor/alterschema/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(alterschema VERSION 0.0.1 LANGUAGES CXX\n  DESCRIPTION \"Perform advanced transformations on JSON Schemas\"\n  HOMEPAGE_URL \"https://alterschema.sourcemeta.com\")\nlist(APPEND CMAKE_MODULE_PATH \"${PROJECT_SOURCE_DIR}/cmake\")\n\n# Options\noption(ALTERSCHEMA_ENGINE \"Build the AlterSchema Engine library\" ON)\noption(ALTERSCHEMA_LINTER \"Build the AlterSchema Linter library\" ON)\noption(ALTERSCHEMA_TESTS \"Build the AlterSchema tests\" OFF)\noption(ALTERSCHEMA_DOCS \"Build the AlterSchema docs\" OFF)\noption(ALTERSCHEMA_INSTALL \"Install the AlterSchema library\" ON)\noption(ALTERSCHEMA_ADDRESS_SANITIZER \"Build AlterSchema with an address sanitizer\" OFF)\noption(ALTERSCHEMA_UNDEFINED_SANITIZER \"Build AlterSchema with an undefined behavior sanitizer\" OFF)\n\nfind_package(Noa REQUIRED)\n\nif(ALTERSCHEMA_INSTALL)\n  include(GNUInstallDirs)\n  include(CMakePackageConfigHelpers)\n  configure_package_config_file(\n    config.cmake.in\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n  write_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    COMPATIBILITY SameMajorVersion)\n  install(FILES\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\"\n    COMPONENT sourcemeta_alterschema_dev)\nendif()\n\nif(ALTERSCHEMA_ENGINE OR ALTERSCHEMA_LINTER)\n  find_package(JSONToolkit REQUIRED)\n  add_subdirectory(src/engine)\nendif()\n\nif(ALTERSCHEMA_LINTER)\n  add_subdirectory(src/linter)\nendif()\n\nif(ALTERSCHEMA_ADDRESS_SANITIZER)\n  noa_sanitizer(TYPE address)\nelseif(ALTERSCHEMA_UNDEFINED_SANITIZER)\n  noa_sanitizer(TYPE undefined)\nendif()\n\nif(ALTERSCHEMA_DOCS)\n  # TODO\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  noa_target_clang_format(SOURCES\n    src/*.h src/*.cc\n    test/*.h test/*.cc)\n  noa_target_clang_tidy(SOURCES\n    src/*.h src/*.cc)\nendif()\n\n# Testing\nif(ALTERSCHEMA_TESTS)\n  enable_testing()\n\n  if(ALTERSCHEMA_ENGINE)\n    add_subdirectory(test/engine)\n  endif()\n\n  if(ALTERSCHEMA_LINTER)\n    add_subdirectory(test/linter)\n  endif()\n\n  if(PROJECT_IS_TOP_LEVEL)\n    # Otherwise we need the child project to link\n    # against the sanitizers too.\n    if(NOT ALTERSCHEMA_ADDRESS_SANITIZER AND NOT ALTERSCHEMA_UNDEFINED_SANITIZER)\n      add_subdirectory(test/packaging)\n    endif()\n  endif()\nendif()\n"
  },
  {
    "path": "vendor/alterschema/LICENSE",
    "content": "This software is dual-licensed: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version. For the terms of this license, see\n<http://www.gnu.org/licenses/>.\n\nYou are free to use this software under the terms of the GNU Affero General\nPublic License WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nAlternatively, you can use this software under a commercial license, as set out\nin <https://www.sourcemeta.com/licensing/>.\n"
  },
  {
    "path": "vendor/alterschema/config.cmake.in",
    "content": "@PACKAGE_INIT@\n\n# Support both casing styles\nlist(APPEND ALTERSCHEMA_COMPONENTS ${AlterSchema_FIND_COMPONENTS})\nlist(APPEND ALTERSCHEMA_COMPONENTS ${alterschema_FIND_COMPONENTS})\nif(NOT ALTERSCHEMA_COMPONENTS)\n  list(APPEND ALTERSCHEMA_COMPONENTS engine)\n  list(APPEND ALTERSCHEMA_COMPONENTS linter)\nendif()\n\ninclude(CMakeFindDependencyMacro)\n\nforeach(component ${ALTERSCHEMA_COMPONENTS})\n  if(component STREQUAL \"engine\")\n    find_dependency(JSONToolkit COMPONENTS uri json jsonpointer jsonschema)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_alterschema_engine.cmake\")\n  elseif(component STREQUAL \"linter\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_alterschema_linter.cmake\")\n  else()\n    message(FATAL_ERROR \"Unknown AlterSchema component: ${component}\")\n  endif()\nendforeach()\n\ncheck_required_components(\"@PROJECT_NAME@\")\n"
  },
  {
    "path": "vendor/alterschema/src/engine/CMakeLists.txt",
    "content": "noa_library(NAMESPACE sourcemeta PROJECT alterschema NAME engine\n  FOLDER \"AlterSchema/Engine\"\n  PRIVATE_HEADERS bundle.h rule.h transformer.h\n  SOURCES bundle.cc rule.cc transformer.cc)\n\nif(ALTERSCHEMA_INSTALL)\n  noa_library_install(NAMESPACE sourcemeta PROJECT alterschema NAME engine)\nendif()\n\ntarget_link_libraries(sourcemeta_alterschema_engine PUBLIC\n  sourcemeta::jsontoolkit::json)\ntarget_link_libraries(sourcemeta_alterschema_engine PUBLIC\n  sourcemeta::jsontoolkit::jsonpointer)\ntarget_link_libraries(sourcemeta_alterschema_engine PUBLIC\n  sourcemeta::jsontoolkit::jsonschema)\n"
  },
  {
    "path": "vendor/alterschema/src/engine/bundle.cc",
    "content": "#include <sourcemeta/alterschema/engine.h>\n\n#include <set>       // std::set\n#include <sstream>   // std::ostringstream\n#include <stdexcept> // std::runtime_error\n\nauto sourcemeta::alterschema::Bundle::apply(\n    sourcemeta::jsontoolkit::JSON &schema,\n    const sourcemeta::jsontoolkit::SchemaWalker &walker,\n    const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n    const sourcemeta::jsontoolkit::Pointer &pointer,\n    const std::optional<std::string> &default_dialect) const -> void {\n  // There is no point in applying an empty bundle\n  assert(!this->rules.empty());\n\n  auto &current{sourcemeta::jsontoolkit::get(schema, pointer)};\n  const std::optional<std::string> root_dialect{\n      sourcemeta::jsontoolkit::dialect(schema, default_dialect)};\n  const std::optional<std::string> dialect{\n      sourcemeta::jsontoolkit::dialect(current, root_dialect)};\n\n  // (1) Transform the current schema object\n  // Avoid recursion to not blow up the stack even on highly complex schemas\n  std::set<std::string> processed_rules;\n  while (true) {\n    auto matches{processed_rules.size()};\n    for (const auto &[name, rule] : this->rules) {\n      // TODO: Process traces to fixup references\n      const auto traces{rule->apply(current, pointer, resolver, dialect)};\n      if (!traces.empty()) {\n        if (processed_rules.contains(name)) {\n          std::ostringstream error;\n          error << \"Rules must only be processed once: \" << name;\n          throw std::runtime_error(error.str());\n        }\n\n        processed_rules.insert(name);\n      }\n    }\n\n    if (matches < processed_rules.size()) {\n      continue;\n    }\n\n    break;\n  }\n\n  // (2) Transform its sub-schemas\n  for (const auto &entry : sourcemeta::jsontoolkit::SchemaIteratorFlat{\n           current, walker, resolver, dialect}) {\n    apply(schema, walker, resolver, pointer.concat(entry.pointer), dialect);\n  }\n}\n\nauto sourcemeta::alterschema::Bundle::check(\n    const sourcemeta::jsontoolkit::JSON &schema,\n    const sourcemeta::jsontoolkit::SchemaWalker &walker,\n    const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n    const sourcemeta::alterschema::Bundle::CheckCallback &callback,\n    const sourcemeta::jsontoolkit::Pointer &pointer,\n    const std::optional<std::string> &default_dialect) const -> bool {\n  const auto &current{sourcemeta::jsontoolkit::get(schema, pointer)};\n  const std::optional<std::string> root_dialect{\n      sourcemeta::jsontoolkit::dialect(schema, default_dialect)};\n  const std::optional<std::string> dialect{\n      sourcemeta::jsontoolkit::dialect(current, root_dialect)};\n\n  bool result{true};\n  for (const auto &entry : sourcemeta::jsontoolkit::SchemaIterator{\n           current, walker, resolver, dialect}) {\n    const auto current_pointer{pointer.concat(entry.pointer)};\n    for (const auto &[name, rule] : this->rules) {\n      if (rule->check(sourcemeta::jsontoolkit::get(current, entry.pointer),\n                      current_pointer, resolver, dialect)) {\n        result = false;\n        callback(current_pointer, name, rule->message());\n      }\n    }\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "vendor/alterschema/src/engine/include/sourcemeta/alterschema/engine.h",
    "content": "#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_H_\n#define SOURCEMETA_ALTERSCHEMA_ENGINE_H_\n\n/// @defgroup engine Engine\n/// @brief A general-purpose extensible schema transformation engine.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/alterschema/engine.h>\n/// ```\n\n#include <sourcemeta/alterschema/engine_bundle.h>\n#include <sourcemeta/alterschema/engine_rule.h>\n#include <sourcemeta/alterschema/engine_transformer.h>\n\n#endif\n"
  },
  {
    "path": "vendor/alterschema/src/engine/include/sourcemeta/alterschema/engine_bundle.h",
    "content": "#ifndef SOURCEMETA_ALTERSCHEMA_BUNDLE_H_\n#define SOURCEMETA_ALTERSCHEMA_BUNDLE_H_\n\n#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT\n#include <sourcemeta/alterschema/engine_export.h>\n#endif\n\n#include <sourcemeta/jsontoolkit/json.h>\n#include <sourcemeta/jsontoolkit/jsonpointer.h>\n#include <sourcemeta/jsontoolkit/jsonschema.h>\n\n#include <sourcemeta/alterschema/engine_rule.h>\n\n#include <cassert>     // assert\n#include <concepts>    // std::derived_from\n#include <functional>  // std::function\n#include <map>         // std::map\n#include <memory>      // std::make_unique, std::unique_ptr\n#include <optional>    // std::optional, std::nullopt\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::alterschema {\n/// @ingroup engine\n///\n/// You can use this class to perform top-down transformations on subschemas\n/// given a set of rules. For example, we can remove every property `foo` as\n/// follows:\n///\n/// ```cpp\n/// #include <sourcemeta/alterschema/engine.h>\n/// #include <cassert>\n///\n/// // Declare one or more rules\n/// class MyRule final : public sourcemeta::alterschema::Rule {\n/// public:\n///   MyRule() : sourcemeta::alterschema::Rule(\"my_rule\") {};\n///\n///   [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n///                                const std::string &dialect,\n///                                const std::set<std::string> &vocabularies,\n///                                const sourcemeta::jsontoolkit::Pointer\n///                                  &pointer) const\n///       -> bool override {\n///     return schema.defines(\"foo\");\n///   }\n///\n///   auto transform(sourcemeta::alterschema::Transformer &transformer)\n///       const -> void override {\n///     transformer.erase(\"foo\");\n///   }\n/// };\n///\n/// // Create a bundle\n/// sourcemeta::alterschema::Bundle bundle;\n///\n/// // Register every rule\n/// bundle.add<MyRule>();\n///\n/// // The input schema to transform\n/// sourcemeta::jsontoolkit::JSON schema =\n///   sourcemeta::jsontoolkit::parse(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"foo\": 1,\n///   \"items\": {\n///     \"type\": \"string\",\n///     \"foo\": 2\n///   }\n/// })JSON\");\n///\n/// // Apply the transformation bundle to the schema\n/// bundle.apply(schema, sourcemeta::jsontoolkit::default_schema_walker,\n///              sourcemeta::jsontoolkit::official_resolver);\n///\n/// // `foo` keywords are gone\n/// assert(!schema.defines(\"foo\"));\n/// assert(!schema.at(\"items\").defines(\"foo\"));\n/// ```\n///\n/// Every registered rule is applied to every subschema of the passed schema\n/// until no longer of them applies.\nclass SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT Bundle {\npublic:\n  /// Create a transform bundle\n  Bundle() = default;\n\n  // Not worth documenting these details\n#if !defined(DOXYGEN)\n  // Explicitly disallow copying, as this class makes use of unique pointers,\n  // which by definition do not support copying. MSVC gets confused unless we\n  // are explicit about it here.\n  Bundle(const Bundle &) = delete;\n  auto operator=(const Bundle &) -> Bundle & = delete;\n  Bundle(Bundle &&) = default;\n  auto operator=(Bundle &&) -> Bundle & = default;\n#endif\n\n  /// Add a rule to the bundle\n  template <std::derived_from<Rule> T> auto add() -> void {\n    auto rule{std::make_unique<T>()};\n    // Rules must only be defined once\n    assert(!this->rules.contains(rule->name()));\n    this->rules.emplace(rule->name(), std::move(rule));\n  }\n\n  /// Apply the bundle of rules to a schema\n  auto\n  apply(sourcemeta::jsontoolkit::JSON &schema,\n        const sourcemeta::jsontoolkit::SchemaWalker &walker,\n        const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n        const sourcemeta::jsontoolkit::Pointer &pointer =\n            sourcemeta::jsontoolkit::empty_pointer,\n        const std::optional<std::string> &default_dialect = std::nullopt) const\n      -> void;\n\n  /// The callback that is called whenever the \"check\" functionality reports a\n  /// rule whose condition holds true. The arguments are as follows:\n  ///\n  /// - The JSON Pointer to the given subschema\n  /// - The name of the rule\n  /// - The message of the rule\n  using CheckCallback =\n      std::function<void(const sourcemeta::jsontoolkit::Pointer &,\n                         const std::string_view, const std::string_view)>;\n\n  /// Report back the rules from the bundle that need to be applied to a schema\n  auto\n  check(const sourcemeta::jsontoolkit::JSON &schema,\n        const sourcemeta::jsontoolkit::SchemaWalker &walker,\n        const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n        const CheckCallback &callback,\n        const sourcemeta::jsontoolkit::Pointer &pointer =\n            sourcemeta::jsontoolkit::empty_pointer,\n        const std::optional<std::string> &default_dialect = std::nullopt) const\n      -> bool;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::map<std::string, std::unique_ptr<Rule>> rules;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n} // namespace sourcemeta::alterschema\n\n#endif\n"
  },
  {
    "path": "vendor/alterschema/src/engine/include/sourcemeta/alterschema/engine_rule.h",
    "content": "#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_RULE_H_\n#define SOURCEMETA_ALTERSCHEMA_ENGINE_RULE_H_\n\n#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT\n#include <sourcemeta/alterschema/engine_export.h>\n#endif\n\n#include <sourcemeta/jsontoolkit/json.h>\n#include <sourcemeta/jsontoolkit/jsonpointer.h>\n#include <sourcemeta/jsontoolkit/jsonschema.h>\n\n#include <sourcemeta/alterschema/engine_transformer.h>\n\n#include <optional> // std::optional, std::nullopt\n#include <set>      // std::set\n#include <string>   // std::string\n#include <vector>   // std::vector\n\nnamespace sourcemeta::alterschema {\n/// @ingroup engine\n///\n/// A class that represents a transformation rule to be used with\n/// sourcemeta::alterschema::Bundle. Clients of this class\n/// are expected to subclass and implement their own condition and\n/// transformation methods.\n///\n/// For example, this is a rule that deletes any property called `foo` in every\n/// subschema:\n///\n/// ```cpp\n/// #include <sourcemeta/alterschema/engine.h>\n///\n/// class MyRule final : public sourcemeta::alterschema::Rule {\n/// public:\n///   MyRule() : sourcemeta::alterschema::Rule(\"my_rule\", \"My rule\") {};\n///\n///   [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n///                                const std::string &dialect,\n///                                const std::set<std::string> &vocabularies,\n///                                const sourcemeta::jsontoolkit::Pointer\n///                                  &pointer) const\n///       -> bool override\n///     return schema.defines(\"foo\");\n///   }\n///\n///   auto transform(sourcemeta::alterschema::Transformer &transformer)\n///       const -> void override {\n///     transformer.erase(\"foo\");\n///   }\n/// };\n/// ```\nclass SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT Rule {\npublic:\n  /// Create a transformation rule. Each rule must have a unique name.\n  Rule(std::string &&name, std::string &&message);\n\n  // Necessary to wrap rules on smart pointers\n  virtual ~Rule() = default;\n\n  // We don't need any of these\n  Rule(const Rule &) = delete;\n  Rule(Rule &&) = delete;\n  auto operator=(const Rule &) -> Rule & = delete;\n  auto operator=(Rule &&) -> Rule & = delete;\n\n  /// Compare a rule against another rule.\n  auto operator==(const Rule &other) const -> bool;\n\n  /// Fetch the name of a rule\n  [[nodiscard]] auto name() const -> const std::string &;\n\n  /// Fetch the message of a rule\n  [[nodiscard]] auto message() const -> const std::string &;\n\n  /// Apply the rule to a schema\n  auto\n  apply(sourcemeta::jsontoolkit::JSON &schema,\n        const sourcemeta::jsontoolkit::Pointer &pointer,\n        const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n        const std::optional<std::string> &default_dialect = std::nullopt) const\n      -> std::vector<Operation>;\n\n  /// Check if the rule applies to a schema\n  auto\n  check(const sourcemeta::jsontoolkit::JSON &schema,\n        const sourcemeta::jsontoolkit::Pointer &pointer,\n        const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n        const std::optional<std::string> &default_dialect = std::nullopt) const\n      -> bool;\n\nprivate:\n  /// The rule condition\n  [[nodiscard]] virtual auto\n  condition(const sourcemeta::jsontoolkit::JSON &schema,\n            const std::string &dialect,\n            const std::set<std::string> &vocabularies,\n            const sourcemeta::jsontoolkit::Pointer &pointer) const -> bool = 0;\n\n  /// The rule transformation\n  virtual auto transform(Transformer &transformer) const -> void = 0;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  const std::string name_;\n  const std::string message_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n} // namespace sourcemeta::alterschema\n\n#endif\n"
  },
  {
    "path": "vendor/alterschema/src/engine/include/sourcemeta/alterschema/engine_transformer.h",
    "content": "#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_TRANSFORMER_H_\n#define SOURCEMETA_ALTERSCHEMA_ENGINE_TRANSFORMER_H_\n\n#ifndef SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT\n#include <sourcemeta/alterschema/engine_export.h>\n#endif\n\n#include <sourcemeta/jsontoolkit/json.h>\n#include <sourcemeta/jsontoolkit/jsonpointer.h>\n\n#include <variant> // std::variant\n#include <vector>  // std::vector\n\nnamespace sourcemeta::alterschema {\n\n/// @ingroup engine\n/// Represents a schema transformation operation that consists in deleting a\n/// property from a schema\nstruct OperationErase {\n  const sourcemeta::jsontoolkit::Pointer pointer;\n};\n\n/// @ingroup engine\n/// Represents a schema transformation operation that consists in adding a new\n/// property to a schema\nstruct OperationAssign {\n  const sourcemeta::jsontoolkit::Pointer pointer;\n};\n\n/// @ingroup engine\n/// Represents a schema transformation operation that consists in replacing a\n/// part of a schema\nstruct OperationReplace {\n  const sourcemeta::jsontoolkit::Pointer pointer;\n};\n\n/// @ingroup engine\n/// Represents a schema transformation operation\nusing Operation =\n    std::variant<OperationErase, OperationAssign, OperationReplace>;\n\n/// @ingroup engine\n/// This is a proxy class to intercept transformations applied to a schema. We\n/// use it to keep track of what changed to fix up schema references.\nclass SOURCEMETA_ALTERSCHEMA_ENGINE_EXPORT Transformer {\npublic:\n  /// Construct a transformer given a schema\n  Transformer(sourcemeta::jsontoolkit::JSON &schema);\n\n  /// Get the underlying schema\n  auto schema() const -> const sourcemeta::jsontoolkit::JSON &;\n  /// Trace the operations applied to the schema\n  auto traces() const -> const std::vector<Operation> &;\n\n  /// Replace a subschema with another value\n  auto replace(const sourcemeta::jsontoolkit::Pointer &path,\n               const sourcemeta::jsontoolkit::JSON &value) -> void;\n  /// Replace a subschema with another value\n  auto replace(const sourcemeta::jsontoolkit::Pointer &path,\n               sourcemeta::jsontoolkit::JSON &&value) -> void;\n  /// Assign an object property\n  auto assign(const sourcemeta::jsontoolkit::Pointer &path,\n              const sourcemeta::jsontoolkit::JSON::String &key,\n              const sourcemeta::jsontoolkit::JSON &value) -> void;\n  /// Assign an object property\n  auto assign(const sourcemeta::jsontoolkit::Pointer &path,\n              const sourcemeta::jsontoolkit::JSON::String &key,\n              sourcemeta::jsontoolkit::JSON &&value) -> void;\n  /// Remove an object property\n  auto erase(const sourcemeta::jsontoolkit::Pointer &path,\n             const sourcemeta::jsontoolkit::JSON::String &key) -> void;\n  /// Remove multiple object properties\n  template <typename Iterator>\n  auto erase_keys(const sourcemeta::jsontoolkit::Pointer &path, Iterator first,\n                  Iterator last) -> void {\n    for (auto iterator = first; iterator != last; ++iterator) {\n      this->erase(path, *iterator);\n    }\n  }\n\n  // For convenience\n\n  /// Replace a schema with another value\n  auto replace(const sourcemeta::jsontoolkit::JSON &value) -> void;\n  /// Replace a schema with another value\n  auto replace(sourcemeta::jsontoolkit::JSON &&value) -> void;\n  /// Assign an object property\n  auto assign(const sourcemeta::jsontoolkit::JSON::String &key,\n              const sourcemeta::jsontoolkit::JSON &value) -> void;\n  /// Assign an object property\n  auto assign(const sourcemeta::jsontoolkit::JSON::String &key,\n              sourcemeta::jsontoolkit::JSON &&value) -> void;\n  /// Remove an object property\n  auto erase(const sourcemeta::jsontoolkit::JSON::String &key) -> void;\n  /// Remove multiple object properties\n  template <typename Iterator>\n  auto erase_keys(Iterator first, Iterator last) -> void {\n    this->erase_keys(sourcemeta::jsontoolkit::empty_pointer, first, last);\n  }\n\nprivate:\n  sourcemeta::jsontoolkit::JSON &data;\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::vector<Operation> operations;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n} // namespace sourcemeta::alterschema\n\n#endif\n"
  },
  {
    "path": "vendor/alterschema/src/engine/rule.cc",
    "content": "#include <sourcemeta/alterschema/engine.h>\n\n#include <cassert>   // assert\n#include <sstream>   // std::ostringstream\n#include <stdexcept> // std::runtime_error\n#include <utility>   // std::move\n\nnamespace {\n\nauto vocabularies_to_set(const std::map<std::string, bool> &vocabularies)\n    -> std::set<std::string> {\n  std::set<std::string> result;\n  for (const auto &pair : vocabularies) {\n    result.insert(pair.first);\n  }\n\n  return result;\n}\n\n} // namespace\n\nsourcemeta::alterschema::Rule::Rule(std::string &&name, std::string &&message)\n    : name_{std::move(name)}, message_{std::move(message)} {}\n\nauto sourcemeta::alterschema::Rule::operator==(\n    const sourcemeta::alterschema::Rule &other) const -> bool {\n  return this->name() == other.name();\n}\n\nauto sourcemeta::alterschema::Rule::name() const -> const std::string & {\n  return this->name_;\n}\n\nauto sourcemeta::alterschema::Rule::message() const -> const std::string & {\n  return this->message_;\n}\n\nauto sourcemeta::alterschema::Rule::apply(\n    sourcemeta::jsontoolkit::JSON &schema,\n    const sourcemeta::jsontoolkit::Pointer &pointer,\n    const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n    const std::optional<std::string> &default_dialect) const\n    -> std::vector<Operation> {\n  const std::optional<std::string> dialect{\n      sourcemeta::jsontoolkit::dialect(schema, default_dialect)};\n  if (!dialect.has_value()) {\n    throw sourcemeta::jsontoolkit::SchemaError(\n        \"Could not determine the schema dialect\");\n  }\n\n  const auto vocabularies{\n      vocabularies_to_set(sourcemeta::jsontoolkit::vocabularies(\n          schema, resolver, default_dialect))};\n  if (!this->condition(schema, dialect.value(), vocabularies, pointer)) {\n    return {};\n  }\n\n  sourcemeta::alterschema::Transformer transformer{schema};\n  this->transform(transformer);\n  // Otherwise the transformation didn't do anything\n  assert(!transformer.traces().empty());\n\n  // The condition must always be false after applying the\n  // transformation in order to avoid infinite loops\n  if (this->condition(schema, dialect.value(), vocabularies, pointer)) {\n    std::ostringstream error;\n    error << \"Rule condition holds after application: \" << this->name();\n    throw std::runtime_error(error.str());\n  }\n\n  return transformer.traces();\n}\n\nauto sourcemeta::alterschema::Rule::check(\n    const sourcemeta::jsontoolkit::JSON &schema,\n    const sourcemeta::jsontoolkit::Pointer &pointer,\n    const sourcemeta::jsontoolkit::SchemaResolver &resolver,\n    const std::optional<std::string> &default_dialect) const -> bool {\n  const std::optional<std::string> dialect{\n      sourcemeta::jsontoolkit::dialect(schema, default_dialect)};\n  if (!dialect.has_value()) {\n    throw sourcemeta::jsontoolkit::SchemaError(\n        \"Could not determine the schema dialect\");\n  }\n\n  const auto vocabularies{\n      vocabularies_to_set(sourcemeta::jsontoolkit::vocabularies(\n          schema, resolver, default_dialect))};\n  return this->condition(schema, dialect.value(), vocabularies, pointer);\n}\n"
  },
  {
    "path": "vendor/alterschema/src/engine/transformer.cc",
    "content": "#include <sourcemeta/alterschema/engine.h>\n\n#include <utility> // std::move\n\nsourcemeta::alterschema::Transformer::Transformer(\n    sourcemeta::jsontoolkit::JSON &schema)\n    : data{schema} {}\n\nauto sourcemeta::alterschema::Transformer::schema() const\n    -> const sourcemeta::jsontoolkit::JSON & {\n  return this->data;\n}\n\nauto sourcemeta::alterschema::Transformer::replace(\n    const sourcemeta::jsontoolkit::Pointer &path,\n    const sourcemeta::jsontoolkit::JSON &value) -> void {\n  // TODO: Check that the path exists with an assert\n  sourcemeta::jsontoolkit::set(this->data, path, value);\n  this->operations.push_back(OperationReplace{path});\n}\n\nauto sourcemeta::alterschema::Transformer::replace(\n    const sourcemeta::jsontoolkit::Pointer &path,\n    sourcemeta::jsontoolkit::JSON &&value) -> void {\n  // TODO: Check that the path exists with an assert\n  sourcemeta::jsontoolkit::set(this->data, path, std::move(value));\n  this->operations.push_back(OperationReplace{path});\n}\n\nauto sourcemeta::alterschema::Transformer::replace(\n    const sourcemeta::jsontoolkit::JSON &value) -> void {\n  this->replace(sourcemeta::jsontoolkit::empty_pointer, value);\n}\n\nauto sourcemeta::alterschema::Transformer::replace(\n    sourcemeta::jsontoolkit::JSON &&value) -> void {\n  this->replace(sourcemeta::jsontoolkit::empty_pointer, std::move(value));\n}\n\nauto sourcemeta::alterschema::Transformer::erase(\n    const sourcemeta::jsontoolkit::Pointer &path,\n    const sourcemeta::jsontoolkit::JSON::String &key) -> void {\n  // TODO: Check that the path exists with an assert\n  sourcemeta::jsontoolkit::get(this->data, path).erase(key);\n  this->operations.push_back(OperationErase{path.concat({key})});\n}\n\nauto sourcemeta::alterschema::Transformer::erase(\n    const sourcemeta::jsontoolkit::JSON::String &key) -> void {\n  this->erase(sourcemeta::jsontoolkit::empty_pointer, key);\n}\n\nauto sourcemeta::alterschema::Transformer::assign(\n    const sourcemeta::jsontoolkit::Pointer &path,\n    const sourcemeta::jsontoolkit::JSON::String &key,\n    const sourcemeta::jsontoolkit::JSON &value) -> void {\n  const auto destination{path.concat({key})};\n  // TODO: Check that the path DOES NOT exist with an assert\n  sourcemeta::jsontoolkit::get(this->data, path).assign(key, value);\n  this->operations.push_back(OperationAssign{path.concat({key})});\n}\n\nauto sourcemeta::alterschema::Transformer::assign(\n    const sourcemeta::jsontoolkit::Pointer &path,\n    const sourcemeta::jsontoolkit::JSON::String &key,\n    sourcemeta::jsontoolkit::JSON &&value) -> void {\n  // TODO: Check that the path DOES NOT exist with an assert\n  sourcemeta::jsontoolkit::get(this->data, path).assign(key, std::move(value));\n  this->operations.push_back(OperationAssign{path.concat({key})});\n}\n\nauto sourcemeta::alterschema::Transformer::assign(\n    const sourcemeta::jsontoolkit::JSON::String &key,\n    const sourcemeta::jsontoolkit::JSON &value) -> void {\n  this->assign(sourcemeta::jsontoolkit::empty_pointer, key, value);\n}\n\nauto sourcemeta::alterschema::Transformer::assign(\n    const sourcemeta::jsontoolkit::JSON::String &key,\n    sourcemeta::jsontoolkit::JSON &&value) -> void {\n  this->assign(sourcemeta::jsontoolkit::empty_pointer, key, std::move(value));\n}\n\nauto sourcemeta::alterschema::Transformer::traces() const\n    -> const std::vector<Operation> & {\n  return this->operations;\n}\n"
  },
  {
    "path": "vendor/alterschema/src/linter/CMakeLists.txt",
    "content": "noa_library(NAMESPACE sourcemeta PROJECT alterschema NAME linter\n  FOLDER \"AlterSchema/Linter\"\n  SOURCES linter.cc\n    # Antipattern\n    antipattern/const_with_type.h\n    antipattern/duplicate_enum_values.h\n    antipattern/duplicate_required_values.h\n    antipattern/exclusive_maximum_number_and_maximum.h\n    antipattern/exclusive_minimum_number_and_minimum.h\n    antipattern/enum_with_type.h\n\n    # Simplify\n    simplify/dependencies_property_tautology.h\n    simplify/dependent_required_tautology.h\n    simplify/equal_numeric_bounds_to_enum.h\n    simplify/maximum_real_for_integer.h\n    simplify/minimum_real_for_integer.h\n    simplify/single_type_array.h\n\n    # Syntax Sugar\n    syntax_sugar/enum_to_const.h\n\n    # Desugar\n    desugar/boolean_true.h\n    desugar/const_as_enum.h\n    desugar/exclusive_maximum_integer_to_maximum.h\n    desugar/exclusive_minimum_integer_to_minimum.h\n    desugar/type_array_to_any_of_2020_12.h\n    desugar/type_boolean_as_enum.h\n    desugar/type_null_as_enum.h\n\n    # Redundant\n    redundant/additional_properties_default.h\n    redundant/content_schema_default.h\n    redundant/dependencies_default.h\n    redundant/dependent_required_default.h\n    redundant/items_array_default.h\n    redundant/items_schema_default.h\n    redundant/pattern_properties_default.h\n    redundant/properties_default.h\n    redundant/unevaluated_items_default.h\n    redundant/unevaluated_properties_default.h\n    redundant/unsatisfiable_max_contains.h\n    redundant/unsatisfiable_min_properties.h\n\n    # Implicit\n    implicit/max_contains_covered_by_max_items.h\n    implicit/min_items_given_min_contains.h\n    implicit/min_items_implicit.h\n    implicit/min_length_implicit.h\n    implicit/min_properties_covered_by_required.h\n    implicit/min_properties_implicit.h\n    implicit/multiple_of_implicit.h\n    implicit/properties_implicit.h\n    implicit/type_union_implicit.h\n\n    # Superfluous\n    superfluous/content_media_type_without_encoding.h\n    superfluous/content_schema_without_media_type.h\n    superfluous/drop_non_array_keywords_applicator_2019_09.h\n    superfluous/drop_non_array_keywords_applicator_2020_12.h\n    superfluous/drop_non_array_keywords_content_2019_09.h\n    superfluous/drop_non_array_keywords_content_2020_12.h\n    superfluous/drop_non_array_keywords_draft0.h\n    superfluous/drop_non_array_keywords_draft1.h\n    superfluous/drop_non_array_keywords_draft2.h\n    superfluous/drop_non_array_keywords_draft3.h\n    superfluous/drop_non_array_keywords_draft4.h\n    superfluous/drop_non_array_keywords_draft6.h\n    superfluous/drop_non_array_keywords_draft7.h\n    superfluous/drop_non_array_keywords_format_2019_09.h\n    superfluous/drop_non_array_keywords_format_2020_12.h\n    superfluous/drop_non_array_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_array_keywords_validation_2019_09.h\n    superfluous/drop_non_array_keywords_validation_2020_12.h\n    superfluous/drop_non_boolean_keywords_applicator_2019_09.h\n    superfluous/drop_non_boolean_keywords_applicator_2020_12.h\n    superfluous/drop_non_boolean_keywords_content_2019_09.h\n    superfluous/drop_non_boolean_keywords_content_2020_12.h\n    superfluous/drop_non_boolean_keywords_draft0.h\n    superfluous/drop_non_boolean_keywords_draft1.h\n    superfluous/drop_non_boolean_keywords_draft2.h\n    superfluous/drop_non_boolean_keywords_draft3.h\n    superfluous/drop_non_boolean_keywords_draft4.h\n    superfluous/drop_non_boolean_keywords_draft6.h\n    superfluous/drop_non_boolean_keywords_draft7.h\n    superfluous/drop_non_boolean_keywords_format_2019_09.h\n    superfluous/drop_non_boolean_keywords_format_2020_12.h\n    superfluous/drop_non_boolean_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_boolean_keywords_validation_2019_09.h\n    superfluous/drop_non_boolean_keywords_validation_2020_12.h\n    superfluous/drop_non_null_keywords_applicator_2019_09.h\n    superfluous/drop_non_null_keywords_applicator_2020_12.h\n    superfluous/drop_non_null_keywords_content_2019_09.h\n    superfluous/drop_non_null_keywords_content_2020_12.h\n    superfluous/drop_non_null_keywords_draft0.h\n    superfluous/drop_non_null_keywords_draft1.h\n    superfluous/drop_non_null_keywords_draft2.h\n    superfluous/drop_non_null_keywords_draft3.h\n    superfluous/drop_non_null_keywords_draft4.h\n    superfluous/drop_non_null_keywords_draft6.h\n    superfluous/drop_non_null_keywords_draft7.h\n    superfluous/drop_non_null_keywords_format_2019_09.h\n    superfluous/drop_non_null_keywords_format_2020_12.h\n    superfluous/drop_non_null_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_null_keywords_validation_2019_09.h\n    superfluous/drop_non_null_keywords_validation_2020_12.h\n    superfluous/drop_non_numeric_keywords_applicator_2019_09.h\n    superfluous/drop_non_numeric_keywords_applicator_2020_12.h\n    superfluous/drop_non_numeric_keywords_content_2019_09.h\n    superfluous/drop_non_numeric_keywords_content_2020_12.h\n    superfluous/drop_non_numeric_keywords_draft0.h\n    superfluous/drop_non_numeric_keywords_draft1.h\n    superfluous/drop_non_numeric_keywords_draft2.h\n    superfluous/drop_non_numeric_keywords_draft3.h\n    superfluous/drop_non_numeric_keywords_draft4.h\n    superfluous/drop_non_numeric_keywords_draft6.h\n    superfluous/drop_non_numeric_keywords_draft7.h\n    superfluous/drop_non_numeric_keywords_format_2019_09.h\n    superfluous/drop_non_numeric_keywords_format_2020_12.h\n    superfluous/drop_non_numeric_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_numeric_keywords_validation_2019_09.h\n    superfluous/drop_non_numeric_keywords_validation_2020_12.h\n    superfluous/drop_non_object_keywords_applicator_2019_09.h\n    superfluous/drop_non_object_keywords_applicator_2020_12.h\n    superfluous/drop_non_object_keywords_content_2019_09.h\n    superfluous/drop_non_object_keywords_content_2020_12.h\n    superfluous/drop_non_object_keywords_draft0.h\n    superfluous/drop_non_object_keywords_draft1.h\n    superfluous/drop_non_object_keywords_draft2.h\n    superfluous/drop_non_object_keywords_draft3.h\n    superfluous/drop_non_object_keywords_draft4.h\n    superfluous/drop_non_object_keywords_draft6.h\n    superfluous/drop_non_object_keywords_draft7.h\n    superfluous/drop_non_object_keywords_format_2019_09.h\n    superfluous/drop_non_object_keywords_format_2020_12.h\n    superfluous/drop_non_object_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_object_keywords_validation_2019_09.h\n    superfluous/drop_non_object_keywords_validation_2020_12.h\n    superfluous/drop_non_string_keywords_applicator_2019_09.h\n    superfluous/drop_non_string_keywords_applicator_2020_12.h\n    superfluous/drop_non_string_keywords_draft0.h\n    superfluous/drop_non_string_keywords_draft1.h\n    superfluous/drop_non_string_keywords_draft2.h\n    superfluous/drop_non_string_keywords_draft3.h\n    superfluous/drop_non_string_keywords_draft4.h\n    superfluous/drop_non_string_keywords_draft6.h\n    superfluous/drop_non_string_keywords_draft7.h\n    superfluous/drop_non_string_keywords_unevaluated_2020_12.h\n    superfluous/drop_non_string_keywords_validation_2019_09.h\n    superfluous/drop_non_string_keywords_validation_2020_12.h\n    superfluous/duplicate_allof_branches.h\n    superfluous/duplicate_anyof_branches.h\n    superfluous/else_without_if.h\n    superfluous/if_without_then_else.h\n    superfluous/max_contains_without_contains.h\n    superfluous/min_contains_without_contains.h\n    superfluous/then_without_if.h)\n\nif(ALTERSCHEMA_INSTALL)\n  noa_library_install(NAMESPACE sourcemeta PROJECT alterschema NAME linter)\nendif()\n\ntarget_link_libraries(sourcemeta_alterschema_linter PUBLIC\n  sourcemeta::alterschema::engine)\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/const_with_type.h",
    "content": "class ConstWithType final : public Rule {\npublic:\n  ConstWithType()\n      : Rule{\"const_with_type\",\n             \"Setting `type` alongside `const` is considered an anti-pattern, \"\n             \"as the constant already implies its respective type\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.defines(\"const\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/duplicate_enum_values.h",
    "content": "class DuplicateEnumValues final : public Rule {\npublic:\n  DuplicateEnumValues()\n      : Rule{\"duplicate_enum_values\", \"Setting duplicate values in `enum` is \"\n                                      \"considered an anti-pattern\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"enum\") &&\n           schema.at(\"enum\").is_array() && !schema.at(\"enum\").unique();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto collection = transformer.schema().at(\"enum\");\n    std::sort(collection.as_array().begin(), collection.as_array().end());\n    auto last =\n        std::unique(collection.as_array().begin(), collection.as_array().end());\n    collection.erase(last, collection.as_array().end());\n    transformer.replace({\"enum\"}, std::move(collection));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/duplicate_required_values.h",
    "content": "class DuplicateRequiredValues final : public Rule {\npublic:\n  DuplicateRequiredValues()\n      : Rule{\"duplicate_required_values\",\n             \"Setting duplicate values in `required` is considered an \"\n             \"anti-pattern\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"required\") &&\n           schema.at(\"required\").is_array() && !schema.at(\"required\").unique();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto collection = transformer.schema().at(\"required\");\n    std::sort(collection.as_array().begin(), collection.as_array().end());\n    auto last =\n        std::unique(collection.as_array().begin(), collection.as_array().end());\n    collection.erase(last, collection.as_array().end());\n    transformer.replace({\"required\"}, std::move(collection));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/enum_with_type.h",
    "content": "class EnumWithType final : public Rule {\npublic:\n  EnumWithType()\n      : Rule{\n            \"enum_with_type\",\n            \"Setting `type` alongside `enum` is considered an anti-pattern, as \"\n            \"the enumeration choices already imply their respective types\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.defines(\"enum\") &&\n\n           // Guard against cases where not all of the enumeration members\n           // match the desired type, in which case the type is adding\n           // an extra constraint and cannot be safely removed\n           schema.at(\"type\").is_string() && schema.at(\"enum\").is_array() &&\n           std::all_of(schema.at(\"enum\").as_array().cbegin(),\n                       schema.at(\"enum\").as_array().cend(),\n                       [&schema](const auto &item) {\n                         const auto &type{schema.at(\"type\").to_string()};\n                         if (type == \"object\") {\n                           return item.is_object();\n                         } else if (type == \"array\") {\n                           return item.is_array();\n                         } else if (type == \"string\") {\n                           return item.is_string();\n                         } else if (type == \"boolean\") {\n                           return item.is_boolean();\n                         } else if (type == \"null\") {\n                           return item.is_null();\n                         } else if (type == \"number\") {\n                           return item.is_number();\n                         } else if (type == \"integer\") {\n                           return item.is_integer();\n                         } else {\n                           return false;\n                         }\n                       });\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/exclusive_maximum_number_and_maximum.h",
    "content": "class ExclusiveMaximumNumberAndMaximum final : public Rule {\npublic:\n  ExclusiveMaximumNumberAndMaximum()\n      : Rule{\"exclusive_maximum_number_and_maximum\",\n             \"Setting both `exclusiveMaximum` and `maximum` at the same time \"\n             \"is considered an anti-pattern. You should choose one\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"maximum\") &&\n           schema.defines(\"exclusiveMaximum\") &&\n           schema.at(\"maximum\").is_number() &&\n           schema.at(\"exclusiveMaximum\").is_number();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().at(\"maximum\") <\n        transformer.schema().at(\"exclusiveMaximum\")) {\n      transformer.erase(\"exclusiveMaximum\");\n    } else {\n      transformer.erase(\"maximum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/antipattern/exclusive_minimum_number_and_minimum.h",
    "content": "class ExclusiveMinimumNumberAndMinimum final : public Rule {\npublic:\n  ExclusiveMinimumNumberAndMinimum()\n      : Rule{\"exclusive_minimum_number_and_minimum\",\n             \"Setting both `exclusiveMinimum` and `minimum` at the same time \"\n             \"is considered an anti-pattern. You should choose one\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"minimum\") &&\n           schema.defines(\"exclusiveMinimum\") &&\n           schema.at(\"minimum\").is_number() &&\n           schema.at(\"exclusiveMinimum\").is_number();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().at(\"exclusiveMinimum\") <\n        transformer.schema().at(\"minimum\")) {\n      transformer.erase(\"exclusiveMinimum\");\n    } else {\n      transformer.erase(\"minimum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/boolean_true.h",
    "content": "class BooleanTrue final : public Rule {\npublic:\n  BooleanTrue()\n      : Rule{\"boolean_true\",\n             \"The boolean schema `true` is syntax sugar for the empty schema\"} {\n        };\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return schema.is_boolean() && schema.to_boolean();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.replace(sourcemeta::jsontoolkit::JSON::make_object());\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/const_as_enum.h",
    "content": "class ConstAsEnum final : public Rule {\npublic:\n  ConstAsEnum()\n      : Rule{\"const_as_enum\", \"Setting `const` is syntax sugar for an \"\n                              \"enumeration of a single value\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"const\") &&\n           !schema.defines(\"enum\");\n  }\n\n  auto transform(sourcemeta::alterschema::Transformer &transformer) const\n      -> void override {\n    sourcemeta::jsontoolkit::JSON values =\n        sourcemeta::jsontoolkit::JSON::make_array();\n    values.push_back(transformer.schema().at(\"const\"));\n    transformer.assign(\"enum\", values);\n    transformer.erase(\"const\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/exclusive_maximum_integer_to_maximum.h",
    "content": "class ExclusiveMaximumIntegerToMaximum final : public Rule {\npublic:\n  ExclusiveMaximumIntegerToMaximum()\n      : Rule(\"exclusive_maximum_integer_to_maximum\",\n             \"Setting `exclusiveMaximum` when `type` is `integer` is syntax \"\n             \"sugar for `maximum`\") {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"exclusiveMaximum\") &&\n           schema.at(\"exclusiveMaximum\").is_number() &&\n           !schema.defines(\"maximum\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().at(\"exclusiveMaximum\").is_integer()) {\n      auto new_maximum = transformer.schema().at(\"exclusiveMaximum\");\n      new_maximum += sourcemeta::jsontoolkit::JSON{-1};\n      transformer.assign(\"maximum\", new_maximum);\n      transformer.erase(\"exclusiveMaximum\");\n    } else {\n      const auto current{transformer.schema().at(\"exclusiveMaximum\").to_real()};\n      const auto new_value{static_cast<std::int64_t>(std::floor(current))};\n      transformer.assign(\"maximum\", sourcemeta::jsontoolkit::JSON{new_value});\n      transformer.erase(\"exclusiveMaximum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/exclusive_minimum_integer_to_minimum.h",
    "content": "class ExclusiveMinimumIntegerToMinimum final : public Rule {\npublic:\n  ExclusiveMinimumIntegerToMinimum()\n      : Rule(\"exclusive_minimum_integer_to_minimum\",\n             \"Setting `exclusiveMinimum` when `type` is `integer` is syntax \"\n             \"sugar for `minimum`\") {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"exclusiveMinimum\") &&\n           schema.at(\"exclusiveMinimum\").is_number() &&\n           !schema.defines(\"minimum\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().at(\"exclusiveMinimum\").is_integer()) {\n      auto new_minimum = transformer.schema().at(\"exclusiveMinimum\");\n      new_minimum += sourcemeta::jsontoolkit::JSON{1};\n      transformer.assign(\"minimum\", new_minimum);\n      transformer.erase(\"exclusiveMinimum\");\n    } else {\n      const auto current{transformer.schema().at(\"exclusiveMinimum\").to_real()};\n      const auto new_value{static_cast<std::int64_t>(std::ceil(current))};\n      transformer.assign(\"minimum\", sourcemeta::jsontoolkit::JSON{new_value});\n      transformer.erase(\"exclusiveMinimum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/type_array_to_any_of_2020_12.h",
    "content": "class TypeArrayToAnyOf_2020_12 final : public Rule {\npublic:\n  TypeArrayToAnyOf_2020_12()\n      : Rule{\"type_array_to_any_of_2020_12\",\n             \"Setting `type` to more than one choice is syntax sugar to \"\n             \"`anyOf` over the corresponding types\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2020-12/vocab/applicator\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_array() &&\n           // Non type-specific applicators can leads to invalid schemas\n           !schema.defines(\"$defs\") && !schema.defines(\"$ref\") &&\n           !schema.defines(\"if\") && !schema.defines(\"then\") &&\n           !schema.defines(\"else\") && !schema.defines(\"allOf\") &&\n           !schema.defines(\"oneOf\") && !schema.defines(\"anyOf\");\n  }\n\n  auto transform(sourcemeta::alterschema::Transformer &transformer) const\n      -> void override {\n    const std::set<std::string> keep{\"$schema\", \"$id\", \"$anchor\",\n                                     \"$dynamicAnchor\", \"$vocabulary\"};\n    auto disjunctors{sourcemeta::jsontoolkit::JSON::make_array()};\n    for (const auto &type : transformer.schema().at(\"type\").as_array()) {\n      auto copy = transformer.schema();\n      copy.erase_keys(keep.cbegin(), keep.cend());\n      copy.assign(\"type\", type);\n      disjunctors.push_back(std::move(copy));\n    }\n\n    auto result{sourcemeta::jsontoolkit::JSON::make_object()};\n    for (const auto &keyword : keep) {\n      if (transformer.schema().defines(keyword)) {\n        result.assign(keyword, transformer.schema().at(keyword));\n      }\n    }\n\n    result.assign(\"anyOf\", std::move(disjunctors));\n    transformer.replace(std::move(result));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/type_boolean_as_enum.h",
    "content": "class TypeBooleanAsEnum final : public Rule {\npublic:\n  TypeBooleanAsEnum()\n      : Rule{\"type_boolean_as_enum\",\n             \"Setting `type` to `boolean` is syntax sugar for an enumeration \"\n             \"of two values: `false` and `true`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           !schema.defines(\"enum\") && !schema.defines(\"const\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto choices = sourcemeta::jsontoolkit::JSON::make_array();\n    choices.push_back(sourcemeta::jsontoolkit::JSON{false});\n    choices.push_back(sourcemeta::jsontoolkit::JSON{true});\n    transformer.assign(\"enum\", choices);\n    transformer.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/desugar/type_null_as_enum.h",
    "content": "class TypeNullAsEnum final : public Rule {\npublic:\n  TypeNullAsEnum()\n      : Rule{\"type_null_as_enum\",\n             \"Setting `type` to `null` is syntax sugar for an enumeration \"\n             \"of a single value: `null`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" && !schema.defines(\"enum\") &&\n           !schema.defines(\"const\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto choices = sourcemeta::jsontoolkit::JSON::make_array();\n    choices.push_back(sourcemeta::jsontoolkit::JSON{nullptr});\n    transformer.assign(\"enum\", choices);\n    transformer.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/max_contains_covered_by_max_items.h",
    "content": "class MaxContainsCoveredByMaxItems final : public Rule {\npublic:\n  MaxContainsCoveredByMaxItems()\n      : Rule{\"max_contains_covered_by_max_items\",\n             \"Setting the `maxContains` keyword to a number greater than or \"\n             \"equal to the array upper bound does not add any further \"\n             \"constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"maxContains\") &&\n           schema.at(\"maxContains\").is_integer() &&\n           schema.defines(\"maxItems\") && schema.at(\"maxItems\").is_integer() &&\n           schema.at(\"maxContains\").to_integer() >\n               schema.at(\"maxItems\").to_integer();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"maxContains\", transformer.schema().at(\"maxItems\"));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/min_items_given_min_contains.h",
    "content": "class MinItemsGivenMinContains final : public sourcemeta::alterschema::Rule {\npublic:\n  MinItemsGivenMinContains()\n      : Rule{\"min_items_given_min_contains\",\n             \"Every array has a minimum size of zero items but may be affected \"\n             \"by `minContains`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           !schema.defines(\"minItems\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().defines(\"contains\") &&\n        transformer.schema().defines(\"minContains\") &&\n        transformer.schema().at(\"minContains\").is_integer()) {\n      transformer.assign(\n          \"minItems\", sourcemeta::jsontoolkit::JSON{\n                          transformer.schema().at(\"minContains\").to_integer()});\n    } else {\n      transformer.assign(\"minItems\", sourcemeta::jsontoolkit::JSON{0});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/min_items_implicit.h",
    "content": "class MinItemsImplicit final : public Rule {\npublic:\n  MinItemsImplicit()\n      : Rule{\"min_items_implicit\",\n             \"Every array has a minimum size of zero items\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(vocabularies,\n                        {\"http://json-schema.org/draft-07/schema#\",\n                         \"http://json-schema.org/draft-06/schema#\",\n                         \"http://json-schema.org/draft-04/schema#\",\n                         \"http://json-schema.org/draft-03/schema#\",\n                         \"http://json-schema.org/draft-02/hyper-schema#\",\n                         \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           !schema.defines(\"minItems\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"minItems\", sourcemeta::jsontoolkit::JSON{0});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/min_length_implicit.h",
    "content": "class MinLengthImplicit final : public sourcemeta::alterschema::Rule {\npublic:\n  MinLengthImplicit()\n      : Rule{\"min_length_implicit\",\n             \"Every string has a minimum length of zero characters\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           !schema.defines(\"minLength\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"minLength\", sourcemeta::jsontoolkit::JSON{0});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/min_properties_covered_by_required.h",
    "content": "class MinPropertiesCoveredByRequired final : public Rule {\npublic:\n  MinPropertiesCoveredByRequired()\n      : Rule{\"min_properties_covered_by_required\",\n             \"Setting `minProperties` to a number less than `required` does \"\n             \"not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"minProperties\") &&\n           schema.at(\"minProperties\").is_integer() &&\n           schema.defines(\"required\") && schema.at(\"required\").is_array() &&\n           schema.at(\"required\").unique() &&\n           schema.at(\"required\").size() >\n               static_cast<std::uint64_t>(\n                   schema.at(\"minProperties\").to_integer());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"minProperties\",\n                       sourcemeta::jsontoolkit::JSON{\n                           transformer.schema().at(\"required\").size()});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/min_properties_implicit.h",
    "content": "class MinPropertiesImplicit final : public Rule {\npublic:\n  MinPropertiesImplicit()\n      : Rule{\"min_properties_implicit\",\n             \"The `minProperties` keyword has a logical default of 0 or the \"\n             \"size of `required`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           !schema.defines(\"minProperties\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    if (transformer.schema().defines(\"required\") &&\n        transformer.schema().at(\"required\").is_array()) {\n      transformer.assign(\"minProperties\",\n                         sourcemeta::jsontoolkit::JSON{\n                             transformer.schema().at(\"required\").size()});\n    } else {\n      transformer.assign(\"minProperties\", sourcemeta::jsontoolkit::JSON{0});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/multiple_of_implicit.h",
    "content": "class MultipleOfImplicit final : public Rule {\npublic:\n  MultipleOfImplicit()\n      : Rule{\"multiple_of_implicit\",\n             \"The unit of `multipleOf` is the integer 1\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           !schema.defines(\"multipleOf\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"multipleOf\", sourcemeta::jsontoolkit::JSON{1});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/properties_implicit.h",
    "content": "class PropertiesImplicit final : public sourcemeta::alterschema::Rule {\npublic:\n  PropertiesImplicit()\n      : Rule{\"properties_implicit\", \"Every object has an implicit `properties` \"\n                                    \"that consists of the empty object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return ((vocabularies.contains(\n                 \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n             vocabularies.contains(\n                 \"https://json-schema.org/draft/2020-12/vocab/applicator\")) ||\n            (vocabularies.contains(\n                 \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n             vocabularies.contains(\n                 \"https://json-schema.org/draft/2019-09/vocab/applicator\")) ||\n            contains_any(vocabularies,\n                         {\"http://json-schema.org/draft-07/schema#\",\n                          \"http://json-schema.org/draft-06/schema#\",\n                          \"http://json-schema.org/draft-04/schema#\",\n                          \"http://json-schema.org/draft-03/schema#\",\n                          \"http://json-schema.org/draft-02/hyper-schema#\",\n                          \"http://json-schema.org/draft-01/hyper-schema#\"})) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           !schema.defines(\"properties\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"properties\",\n                       sourcemeta::jsontoolkit::JSON::make_object());\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/implicit/type_union_implicit.h",
    "content": "class TypeUnionImplicit final : public sourcemeta::alterschema::Rule {\npublic:\n  TypeUnionImplicit()\n      : Rule{\"type_union_implicit\",\n             \"Not setting `type` is equivalent to accepting any type\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    if (!schema.is_object()) {\n      return false;\n    }\n\n    if (contains_any(vocabularies,\n                     {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                      \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                      \"http://json-schema.org/draft-07/schema#\",\n                      \"http://json-schema.org/draft-06/schema#\",\n                      \"http://json-schema.org/draft-04/schema#\",\n                      \"http://json-schema.org/draft-03/schema#\",\n                      \"http://json-schema.org/draft-02/hyper-schema#\",\n                      \"http://json-schema.org/draft-01/hyper-schema#\",\n                      \"http://json-schema.org/draft-00/hyper-schema#\"})) {\n      if (schema.defines(\"type\")) {\n        return false;\n      }\n\n      // Don't apply if we don't have the necessary vocabularies\n    } else {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2020-12/vocab/core\") &&\n        schema.defines_any({\"$ref\", \"$dynamicRef\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n        schema.defines_any(\n            {\"anyOf\", \"oneOf\", \"allOf\", \"if\", \"then\", \"else\", \"not\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n        schema.defines_any({\"enum\", \"const\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2019-09/vocab/core\") &&\n        schema.defines_any({\"$ref\", \"$recursiveRef\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n        schema.defines_any(\n            {\"anyOf\", \"oneOf\", \"allOf\", \"if\", \"then\", \"else\", \"not\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n        schema.defines_any({\"enum\", \"const\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n        schema.defines_any({\"$ref\", \"enum\", \"const\", \"anyOf\", \"oneOf\", \"allOf\",\n                            \"if\", \"then\", \"else\", \"not\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n        schema.defines_any(\n            {\"$ref\", \"enum\", \"const\", \"anyOf\", \"oneOf\", \"allOf\", \"not\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n        schema.defines_any(\n            {\"$ref\", \"enum\", \"anyOf\", \"oneOf\", \"allOf\", \"not\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n        schema.defines_any({\"$ref\", \"enum\", \"disallow\", \"extends\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"http://json-schema.org/draft-02/hyper-schema#\") &&\n        schema.defines_any({\"enum\", \"disallow\", \"extends\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"http://json-schema.org/draft-01/hyper-schema#\") &&\n        schema.defines_any({\"enum\", \"disallow\", \"extends\"})) {\n      return false;\n    }\n\n    if (vocabularies.contains(\n            \"http://json-schema.org/draft-00/hyper-schema#\") &&\n        schema.defines_any({\"enum\", \"disallow\", \"extends\"})) {\n      return false;\n    }\n\n    return true;\n  }\n\n  auto transform(sourcemeta::alterschema::Transformer &transformer) const\n      -> void override {\n    auto types{sourcemeta::jsontoolkit::JSON::make_array()};\n\n    // All possible JSON Schema types\n    // See\n    // https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.1.1\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"null\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"boolean\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"object\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"array\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"string\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"number\"});\n    types.push_back(sourcemeta::jsontoolkit::JSON{\"integer\"});\n\n    transformer.assign(\"type\", std::move(types));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/include/sourcemeta/alterschema/linter.h",
    "content": "#ifndef SOURCEMETA_ALTERSCHEMA_LINTER_H_\n#define SOURCEMETA_ALTERSCHEMA_LINTER_H_\n\n/// @defgroup linter Linter\n/// @brief A growing collection of linter rules.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/alterschema/linter.h>\n/// ```\n\n#ifndef SOURCEMETA_ALTERSCHEMA_LINTER_EXPORT\n#include <sourcemeta/alterschema/linter_export.h>\n#endif\n\n#include <sourcemeta/alterschema/engine.h>\n\nnamespace sourcemeta::alterschema {\n\n// TODO: Revise the category names to make incompatibilities more obvious\n\n/// @ingroup linter\n/// The category of a built-in transformation rule\nenum class LinterCategory {\n  /// Rules that detect clear anti-patterns that should not be happening on the\n  /// first place\n  AntiPattern,\n\n  /// Rules that simplify the given schema for both human readability and\n  /// performance\n  Simplify,\n\n  /// Rules that take advantage of syntax sugar to improve human readability of\n  /// a schema. As its name implies, this category is incompatible with\n  /// `Desugar`.\n  SyntaxSugar,\n\n  /// Rules that simplify keywords that are syntax sugar to other keywords,\n  /// potentially decreasing human readability in favor of explicitness\n  /// As its name implies, this category is incompatible with `SyntaxSugar`.\n  Desugar,\n\n  /// Rules that remove schema redundancies that do not contribute to the\n  /// schema.\n  /// This category is incompatible with `Implicit`\n  Redundant,\n\n  /// Rules that surface implicit constraints. This category is incompatible\n  /// with `Redundant`\n  Implicit,\n\n  /// Rules that remove keywords that are superfluous and take no effect on the\n  /// given schema\n  Superfluous\n};\n\n/// @ingroup linter\n/// Add a set of built-in linter rules given a category. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/alterschema/engine.h>\n/// #include <sourcemeta/alterschema/linter.h>\n///\n/// sourcemeta::alterschema::Bundle bundle;\n///\n/// sourcemeta::alterschema::add(bundle,\n///   sourcemeta::alterschema::LinterCategory::SyntaxSugar);\n///\n/// auto schema = sourcemeta::jsontoolkit::parse(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"foo\": 1,\n///   \"items\": {\n///     \"type\": \"string\",\n///     \"foo\": 2\n///   }\n/// })JSON\");\n///\n/// bundle.apply(schema, sourcemeta::jsontoolkit::default_schema_walker,\n///              sourcemeta::jsontoolkit::official_resolver);\n/// ```\nSOURCEMETA_ALTERSCHEMA_LINTER_EXPORT\nauto add(Bundle &bundle, const LinterCategory category) -> void;\n\n} // namespace sourcemeta::alterschema\n\n#endif\n"
  },
  {
    "path": "vendor/alterschema/src/linter/linter.cc",
    "content": "#include <sourcemeta/alterschema/linter.h>\n\n#include <cassert> // assert\n\n// For built-in rules\n#include <algorithm>\n#include <cmath>\n#include <iterator>\nnamespace sourcemeta::alterschema {\ntemplate <typename T>\nauto contains_any(const T &container, const T &values) -> bool {\n  return std::any_of(\n      std::cbegin(container), std::cend(container),\n      [&values](const auto &element) { return values.contains(element); });\n}\n\ntemplate <typename T> auto every_item_is_null(const T &container) -> bool {\n  return std::all_of(std::cbegin(container), std::cend(container),\n                     [](const auto &element) { return element.is_null(); });\n}\n\ntemplate <typename T> auto every_item_is_boolean(const T &container) -> bool {\n  return std::all_of(std::cbegin(container), std::cend(container),\n                     [](const auto &element) { return element.is_boolean(); });\n}\n\n// AntiPattern\n#include \"antipattern/const_with_type.h\"\n#include \"antipattern/duplicate_enum_values.h\"\n#include \"antipattern/duplicate_required_values.h\"\n#include \"antipattern/enum_with_type.h\"\n#include \"antipattern/exclusive_maximum_number_and_maximum.h\"\n#include \"antipattern/exclusive_minimum_number_and_minimum.h\"\n// Simplify\n#include \"simplify/dependencies_property_tautology.h\"\n#include \"simplify/dependent_required_tautology.h\"\n#include \"simplify/equal_numeric_bounds_to_enum.h\"\n#include \"simplify/maximum_real_for_integer.h\"\n#include \"simplify/minimum_real_for_integer.h\"\n#include \"simplify/single_type_array.h\"\n// Syntax sugar\n#include \"syntax_sugar/enum_to_const.h\"\n// Desugar\n#include \"desugar/boolean_true.h\"\n#include \"desugar/const_as_enum.h\"\n#include \"desugar/exclusive_maximum_integer_to_maximum.h\"\n#include \"desugar/exclusive_minimum_integer_to_minimum.h\"\n#include \"desugar/type_array_to_any_of_2020_12.h\"\n#include \"desugar/type_boolean_as_enum.h\"\n#include \"desugar/type_null_as_enum.h\"\n\n// Redundant\n#include \"redundant/additional_properties_default.h\"\n#include \"redundant/content_schema_default.h\"\n#include \"redundant/dependencies_default.h\"\n#include \"redundant/dependent_required_default.h\"\n#include \"redundant/items_array_default.h\"\n#include \"redundant/items_schema_default.h\"\n#include \"redundant/pattern_properties_default.h\"\n#include \"redundant/properties_default.h\"\n#include \"redundant/unevaluated_items_default.h\"\n#include \"redundant/unevaluated_properties_default.h\"\n#include \"redundant/unsatisfiable_max_contains.h\"\n#include \"redundant/unsatisfiable_min_properties.h\"\n// Implicit\n#include \"implicit/max_contains_covered_by_max_items.h\"\n#include \"implicit/min_items_given_min_contains.h\"\n#include \"implicit/min_items_implicit.h\"\n#include \"implicit/min_length_implicit.h\"\n#include \"implicit/min_properties_covered_by_required.h\"\n#include \"implicit/min_properties_implicit.h\"\n#include \"implicit/multiple_of_implicit.h\"\n#include \"implicit/properties_implicit.h\"\n#include \"implicit/type_union_implicit.h\"\n// Superfluous\n#include \"superfluous/content_media_type_without_encoding.h\"\n#include \"superfluous/content_schema_without_media_type.h\"\n#include \"superfluous/drop_non_array_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_array_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_array_keywords_content_2019_09.h\"\n#include \"superfluous/drop_non_array_keywords_content_2020_12.h\"\n#include \"superfluous/drop_non_array_keywords_draft0.h\"\n#include \"superfluous/drop_non_array_keywords_draft1.h\"\n#include \"superfluous/drop_non_array_keywords_draft2.h\"\n#include \"superfluous/drop_non_array_keywords_draft3.h\"\n#include \"superfluous/drop_non_array_keywords_draft4.h\"\n#include \"superfluous/drop_non_array_keywords_draft6.h\"\n#include \"superfluous/drop_non_array_keywords_draft7.h\"\n#include \"superfluous/drop_non_array_keywords_format_2019_09.h\"\n#include \"superfluous/drop_non_array_keywords_format_2020_12.h\"\n#include \"superfluous/drop_non_array_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_array_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_array_keywords_validation_2020_12.h\"\n#include \"superfluous/drop_non_boolean_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_boolean_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_boolean_keywords_content_2019_09.h\"\n#include \"superfluous/drop_non_boolean_keywords_content_2020_12.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft0.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft1.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft2.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft3.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft4.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft6.h\"\n#include \"superfluous/drop_non_boolean_keywords_draft7.h\"\n#include \"superfluous/drop_non_boolean_keywords_format_2019_09.h\"\n#include \"superfluous/drop_non_boolean_keywords_format_2020_12.h\"\n#include \"superfluous/drop_non_boolean_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_boolean_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_boolean_keywords_validation_2020_12.h\"\n#include \"superfluous/drop_non_null_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_null_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_null_keywords_content_2019_09.h\"\n#include \"superfluous/drop_non_null_keywords_content_2020_12.h\"\n#include \"superfluous/drop_non_null_keywords_draft0.h\"\n#include \"superfluous/drop_non_null_keywords_draft1.h\"\n#include \"superfluous/drop_non_null_keywords_draft2.h\"\n#include \"superfluous/drop_non_null_keywords_draft3.h\"\n#include \"superfluous/drop_non_null_keywords_draft4.h\"\n#include \"superfluous/drop_non_null_keywords_draft6.h\"\n#include \"superfluous/drop_non_null_keywords_draft7.h\"\n#include \"superfluous/drop_non_null_keywords_format_2019_09.h\"\n#include \"superfluous/drop_non_null_keywords_format_2020_12.h\"\n#include \"superfluous/drop_non_null_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_null_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_null_keywords_validation_2020_12.h\"\n#include \"superfluous/drop_non_numeric_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_numeric_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_numeric_keywords_content_2019_09.h\"\n#include \"superfluous/drop_non_numeric_keywords_content_2020_12.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft0.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft1.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft2.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft3.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft4.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft6.h\"\n#include \"superfluous/drop_non_numeric_keywords_draft7.h\"\n#include \"superfluous/drop_non_numeric_keywords_format_2019_09.h\"\n#include \"superfluous/drop_non_numeric_keywords_format_2020_12.h\"\n#include \"superfluous/drop_non_numeric_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_numeric_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_numeric_keywords_validation_2020_12.h\"\n#include \"superfluous/drop_non_object_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_object_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_object_keywords_content_2019_09.h\"\n#include \"superfluous/drop_non_object_keywords_content_2020_12.h\"\n#include \"superfluous/drop_non_object_keywords_draft0.h\"\n#include \"superfluous/drop_non_object_keywords_draft1.h\"\n#include \"superfluous/drop_non_object_keywords_draft2.h\"\n#include \"superfluous/drop_non_object_keywords_draft3.h\"\n#include \"superfluous/drop_non_object_keywords_draft4.h\"\n#include \"superfluous/drop_non_object_keywords_draft6.h\"\n#include \"superfluous/drop_non_object_keywords_draft7.h\"\n#include \"superfluous/drop_non_object_keywords_format_2019_09.h\"\n#include \"superfluous/drop_non_object_keywords_format_2020_12.h\"\n#include \"superfluous/drop_non_object_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_object_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_object_keywords_validation_2020_12.h\"\n#include \"superfluous/drop_non_string_keywords_applicator_2019_09.h\"\n#include \"superfluous/drop_non_string_keywords_applicator_2020_12.h\"\n#include \"superfluous/drop_non_string_keywords_draft0.h\"\n#include \"superfluous/drop_non_string_keywords_draft1.h\"\n#include \"superfluous/drop_non_string_keywords_draft2.h\"\n#include \"superfluous/drop_non_string_keywords_draft3.h\"\n#include \"superfluous/drop_non_string_keywords_draft4.h\"\n#include \"superfluous/drop_non_string_keywords_draft6.h\"\n#include \"superfluous/drop_non_string_keywords_draft7.h\"\n#include \"superfluous/drop_non_string_keywords_unevaluated_2020_12.h\"\n#include \"superfluous/drop_non_string_keywords_validation_2019_09.h\"\n#include \"superfluous/drop_non_string_keywords_validation_2020_12.h\"\n#include \"superfluous/duplicate_allof_branches.h\"\n#include \"superfluous/duplicate_anyof_branches.h\"\n#include \"superfluous/else_without_if.h\"\n#include \"superfluous/if_without_then_else.h\"\n#include \"superfluous/max_contains_without_contains.h\"\n#include \"superfluous/min_contains_without_contains.h\"\n#include \"superfluous/then_without_if.h\"\n} // namespace sourcemeta::alterschema\n\nnamespace sourcemeta::alterschema {\n\nauto add(Bundle &bundle, const LinterCategory category) -> void {\n  switch (category) {\n    case LinterCategory::AntiPattern:\n      bundle.add<EnumWithType>();\n      bundle.add<DuplicateEnumValues>();\n      bundle.add<DuplicateRequiredValues>();\n      bundle.add<ConstWithType>();\n      bundle.add<ExclusiveMaximumNumberAndMaximum>();\n      bundle.add<ExclusiveMinimumNumberAndMinimum>();\n      break;\n    case LinterCategory::Simplify:\n      bundle.add<DependenciesPropertyTautology>();\n      bundle.add<DependentRequiredTautology>();\n      bundle.add<EqualNumericBoundsToEnum>();\n      bundle.add<MaximumRealForInteger>();\n      bundle.add<MinimumRealForInteger>();\n      bundle.add<SingleTypeArray>();\n      break;\n    case LinterCategory::SyntaxSugar:\n      bundle.add<EnumToConst>();\n      break;\n    case LinterCategory::Desugar:\n      bundle.add<BooleanTrue>();\n      bundle.add<ConstAsEnum>();\n      bundle.add<ExclusiveMaximumIntegerToMaximum>();\n      bundle.add<ExclusiveMinimumIntegerToMinimum>();\n      bundle.add<TypeArrayToAnyOf_2020_12>();\n      bundle.add<TypeBooleanAsEnum>();\n      bundle.add<TypeNullAsEnum>();\n      break;\n    case LinterCategory::Redundant:\n      bundle.add<AdditionalPropertiesDefault>();\n      bundle.add<ContentSchemaDefault>();\n      bundle.add<DependenciesDefault>();\n      bundle.add<DependentRequiredDefault>();\n      bundle.add<ItemsArrayDefault>();\n      bundle.add<ItemsSchemaDefault>();\n      bundle.add<PatternPropertiesDefault>();\n      bundle.add<PropertiesDefault>();\n      bundle.add<UnevaluatedItemsDefault>();\n      bundle.add<UnevaluatedPropertiesDefault>();\n      bundle.add<UnsatisfiableMaxContains>();\n      bundle.add<UnsatisfiableMinProperties>();\n      break;\n    case LinterCategory::Implicit:\n      bundle.add<MaxContainsCoveredByMaxItems>();\n      bundle.add<MinItemsGivenMinContains>();\n      bundle.add<MinItemsImplicit>();\n      bundle.add<MinLengthImplicit>();\n      bundle.add<MinPropertiesCoveredByRequired>();\n      bundle.add<MinPropertiesImplicit>();\n      bundle.add<MultipleOfImplicit>();\n      bundle.add<PropertiesImplicit>();\n      bundle.add<TypeUnionImplicit>();\n      break;\n    case LinterCategory::Superfluous:\n      bundle.add<ContentMediaTypeWithoutEncoding>();\n      bundle.add<ContentSchemaWithoutMediaType>();\n      bundle.add<DropNonArrayKeywordsApplicator_2019_09>();\n      bundle.add<DropNonArrayKeywordsApplicator_2020_12>();\n      bundle.add<DropNonArrayKeywordsContent_2019_09>();\n      bundle.add<DropNonArrayKeywordsContent_2020_12>();\n      bundle.add<DropNonArrayKeywords_Draft0>();\n      bundle.add<DropNonArrayKeywords_Draft1>();\n      bundle.add<DropNonArrayKeywords_Draft2>();\n      bundle.add<DropNonArrayKeywords_Draft3>();\n      bundle.add<DropNonArrayKeywords_Draft4>();\n      bundle.add<DropNonArrayKeywords_Draft6>();\n      bundle.add<DropNonArrayKeywords_Draft7>();\n      bundle.add<DropNonArrayKeywordsFormat_2019_09>();\n      bundle.add<DropNonArrayKeywordsFormat_2020_12>();\n      bundle.add<DropNonArrayKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonArrayKeywordsValidation_2019_09>();\n      bundle.add<DropNonArrayKeywordsValidation_2020_12>();\n      bundle.add<DropNonBooleanKeywordsApplicator_2019_09>();\n      bundle.add<DropNonBooleanKeywordsApplicator_2020_12>();\n      bundle.add<DropNonBooleanKeywordsContent_2019_09>();\n      bundle.add<DropNonBooleanKeywordsContent_2020_12>();\n      bundle.add<DropNonBooleanKeywords_Draft0>();\n      bundle.add<DropNonBooleanKeywords_Draft1>();\n      bundle.add<DropNonBooleanKeywords_Draft2>();\n      bundle.add<DropNonBooleanKeywords_Draft3>();\n      bundle.add<DropNonBooleanKeywords_Draft4>();\n      bundle.add<DropNonBooleanKeywords_Draft6>();\n      bundle.add<DropNonBooleanKeywords_Draft7>();\n      bundle.add<DropNonBooleanKeywordsFormat_2019_09>();\n      bundle.add<DropNonBooleanKeywordsFormat_2020_12>();\n      bundle.add<DropNonBooleanKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonBooleanKeywordsValidation_2019_09>();\n      bundle.add<DropNonBooleanKeywordsValidation_2020_12>();\n      bundle.add<DropNonNullKeywordsApplicator_2019_09>();\n      bundle.add<DropNonNullKeywordsApplicator_2020_12>();\n      bundle.add<DropNonNullKeywordsContent_2019_09>();\n      bundle.add<DropNonNullKeywordsContent_2020_12>();\n      bundle.add<DropNonNullKeywords_Draft0>();\n      bundle.add<DropNonNullKeywords_Draft1>();\n      bundle.add<DropNonNullKeywords_Draft2>();\n      bundle.add<DropNonNullKeywords_Draft3>();\n      bundle.add<DropNonNullKeywords_Draft4>();\n      bundle.add<DropNonNullKeywords_Draft6>();\n      bundle.add<DropNonNullKeywords_Draft7>();\n      bundle.add<DropNonNullKeywordsFormat_2019_09>();\n      bundle.add<DropNonNullKeywordsFormat_2020_12>();\n      bundle.add<DropNonNullKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonNullKeywordsValidation_2019_09>();\n      bundle.add<DropNonNullKeywordsValidation_2020_12>();\n      bundle.add<DropNonNumericKeywordsApplicator_2019_09>();\n      bundle.add<DropNonNumericKeywordsApplicator_2020_12>();\n      bundle.add<DropNonNumericKeywordsContent_2019_09>();\n      bundle.add<DropNonNumericKeywordsContent_2020_12>();\n      bundle.add<DropNonNumericKeywords_Draft0>();\n      bundle.add<DropNonNumericKeywords_Draft1>();\n      bundle.add<DropNonNumericKeywords_Draft2>();\n      bundle.add<DropNonNumericKeywords_Draft3>();\n      bundle.add<DropNonNumericKeywords_Draft4>();\n      bundle.add<DropNonNumericKeywords_Draft6>();\n      bundle.add<DropNonNumericKeywords_Draft7>();\n      bundle.add<DropNonNumericKeywordsFormat_2019_09>();\n      bundle.add<DropNonNumericKeywordsFormat_2020_12>();\n      bundle.add<DropNonNumericKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonNumericKeywordsValidation_2019_09>();\n      bundle.add<DropNonNumericKeywordsValidation_2020_12>();\n      bundle.add<DropNonObjectKeywordsApplicator_2019_09>();\n      bundle.add<DropNonObjectKeywordsApplicator_2020_12>();\n      bundle.add<DropNonObjectKeywordsContent_2019_09>();\n      bundle.add<DropNonObjectKeywordsContent_2020_12>();\n      bundle.add<DropNonObjectKeywords_Draft0>();\n      bundle.add<DropNonObjectKeywords_Draft1>();\n      bundle.add<DropNonObjectKeywords_Draft2>();\n      bundle.add<DropNonObjectKeywords_Draft3>();\n      bundle.add<DropNonObjectKeywords_Draft4>();\n      bundle.add<DropNonObjectKeywords_Draft6>();\n      bundle.add<DropNonObjectKeywords_Draft7>();\n      bundle.add<DropNonObjectKeywordsFormat_2019_09>();\n      bundle.add<DropNonObjectKeywordsFormat_2020_12>();\n      bundle.add<DropNonObjectKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonObjectKeywordsValidation_2019_09>();\n      bundle.add<DropNonObjectKeywordsValidation_2020_12>();\n      bundle.add<DropNonStringKeywordsApplicator_2019_09>();\n      bundle.add<DropNonStringKeywordsApplicator_2020_12>();\n      bundle.add<DropNonStringKeywords_Draft0>();\n      bundle.add<DropNonStringKeywords_Draft1>();\n      bundle.add<DropNonStringKeywords_Draft2>();\n      bundle.add<DropNonStringKeywords_Draft3>();\n      bundle.add<DropNonStringKeywords_Draft4>();\n      bundle.add<DropNonStringKeywords_Draft6>();\n      bundle.add<DropNonStringKeywords_Draft7>();\n      bundle.add<DropNonStringKeywordsUnevaluated_2020_12>();\n      bundle.add<DropNonStringKeywordsValidation_2019_09>();\n      bundle.add<DropNonStringKeywordsValidation_2020_12>();\n      bundle.add<DuplicateAllOfBranches>();\n      bundle.add<DuplicateAnyOfBranches>();\n      bundle.add<ElseWithoutIf>();\n      bundle.add<IfWithoutThenElse>();\n      bundle.add<MaxContainsWithoutContains>();\n      bundle.add<MinContainsWithoutContains>();\n      bundle.add<ThenWithoutIf>();\n      break;\n    default:\n      // We should never get here\n      assert(false);\n      break;\n  }\n}\n\n} // namespace sourcemeta::alterschema\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/additional_properties_default.h",
    "content": "class AdditionalPropertiesDefault final : public Rule {\npublic:\n  AdditionalPropertiesDefault()\n      : Rule{\"additional_properties_default\",\n             \"Setting the `additionalProperties` keyword to the true schema \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"additionalProperties\") &&\n           ((schema.at(\"additionalProperties\").is_boolean() &&\n             schema.at(\"additionalProperties\").to_boolean()) ||\n            (schema.at(\"additionalProperties\").is_object() &&\n             schema.at(\"additionalProperties\").empty()));\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"additionalProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/content_schema_default.h",
    "content": "class ContentSchemaDefault final : public Rule {\npublic:\n  ContentSchemaDefault()\n      : Rule{\"content_schema_default\",\n             \"Setting the `contentSchema` keyword to the true schema \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/content\",\n                \"https://json-schema.org/draft/2019-09/vocab/content\"}) &&\n           schema.is_object() && schema.defines(\"contentSchema\") &&\n           ((schema.at(\"contentSchema\").is_boolean() &&\n             schema.at(\"contentSchema\").to_boolean()) ||\n            (schema.at(\"contentSchema\").is_object() &&\n             schema.at(\"contentSchema\").empty()));\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"contentSchema\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/dependencies_default.h",
    "content": "class DependenciesDefault final : public Rule {\npublic:\n  DependenciesDefault()\n      : Rule{\"dependencies_default\",\n             \"Setting the `dependencies` keyword to an empty object \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(vocabularies,\n                        {\"http://json-schema.org/draft-07/schema#\",\n                         \"http://json-schema.org/draft-06/schema#\",\n                         \"http://json-schema.org/draft-04/schema#\",\n                         \"http://json-schema.org/draft-03/schema#\"}) &&\n           schema.is_object() && schema.defines(\"dependencies\") &&\n           schema.at(\"dependencies\").is_object() &&\n           schema.at(\"dependencies\").empty();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"dependencies\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/dependent_required_default.h",
    "content": "class DependentRequiredDefault final : public Rule {\npublic:\n  DependentRequiredDefault()\n      : Rule{\"dependent_required_default\",\n             \"Setting the `dependentRequired` keyword to an empty object \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"dependentRequired\") &&\n           schema.at(\"dependentRequired\").is_object() &&\n           schema.at(\"dependentRequired\").empty();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"dependentRequired\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/items_array_default.h",
    "content": "class ItemsArrayDefault final : public Rule {\npublic:\n  ItemsArrayDefault()\n      : Rule{\"items_array_default\",\n             \"Setting the `items` keyword to the empty array \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"items\") &&\n           schema.at(\"items\").is_array() && schema.at(\"items\").empty();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"items\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/items_schema_default.h",
    "content": "class ItemsSchemaDefault final : public Rule {\npublic:\n  ItemsSchemaDefault()\n      : Rule{\"items_schema_default\",\n             \"Setting the `items` keyword to the true schema \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"items\") &&\n           ((schema.at(\"items\").is_boolean() &&\n             schema.at(\"items\").to_boolean()) ||\n            (schema.at(\"items\").is_object() && schema.at(\"items\").empty()));\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"items\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/pattern_properties_default.h",
    "content": "class PatternPropertiesDefault final : public Rule {\npublic:\n  PatternPropertiesDefault()\n      : Rule{\"pattern_properties_default\",\n             \"Setting the `patternProperties` keyword to the empty object \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\"}) &&\n           schema.is_object() && schema.defines(\"patternProperties\") &&\n           schema.at(\"patternProperties\").is_object() &&\n           schema.at(\"patternProperties\").empty();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"patternProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/properties_default.h",
    "content": "class PropertiesDefault final : public Rule {\npublic:\n  PropertiesDefault()\n      : Rule{\"properties_default\",\n             \"Setting the `properties` keyword to the empty object \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"properties\") &&\n           schema.at(\"properties\").is_object() &&\n           schema.at(\"properties\").empty();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"properties\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/unevaluated_items_default.h",
    "content": "class UnevaluatedItemsDefault final : public Rule {\npublic:\n  UnevaluatedItemsDefault()\n      : Rule{\"unevaluated_items_default\",\n             \"Setting the `unevaluatedItems` keyword to the true schema \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/unevaluated\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\"}) &&\n           schema.is_object() && schema.defines(\"unevaluatedItems\") &&\n           ((schema.at(\"unevaluatedItems\").is_boolean() &&\n             schema.at(\"unevaluatedItems\").to_boolean()) ||\n            (schema.at(\"unevaluatedItems\").is_object() &&\n             schema.at(\"unevaluatedItems\").empty()));\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"unevaluatedItems\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/unevaluated_properties_default.h",
    "content": "class UnevaluatedPropertiesDefault final : public Rule {\npublic:\n  UnevaluatedPropertiesDefault()\n      : Rule{\"unevaluated_properties_default\",\n             \"Setting the `unevaluatedProperties` keyword to the true schema \"\n             \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/unevaluated\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\"}) &&\n           schema.is_object() && schema.defines(\"unevaluatedProperties\") &&\n           ((schema.at(\"unevaluatedProperties\").is_boolean() &&\n             schema.at(\"unevaluatedProperties\").to_boolean()) ||\n            (schema.at(\"unevaluatedProperties\").is_object() &&\n             schema.at(\"unevaluatedProperties\").empty()));\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"unevaluatedProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/unsatisfiable_max_contains.h",
    "content": "class UnsatisfiableMaxContains final : public Rule {\npublic:\n  UnsatisfiableMaxContains()\n      : Rule{\"unsatisfiable_max_contains\",\n             \"Setting the `maxContains` keyword to a number greater than or \"\n             \"equal to the array upper bound does not add any further \"\n             \"constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"maxContains\") &&\n           schema.at(\"maxContains\").is_integer() &&\n           schema.defines(\"maxItems\") && schema.at(\"maxItems\").is_integer() &&\n           schema.at(\"maxContains\").to_integer() >=\n               schema.at(\"maxItems\").to_integer();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"maxContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/redundant/unsatisfiable_min_properties.h",
    "content": "class UnsatisfiableMinProperties final : public Rule {\npublic:\n  UnsatisfiableMinProperties()\n      : Rule{\"unsatisfiable_min_properties\",\n             \"Setting `minProperties` to a number less than `required` does \"\n             \"not add any further constraint\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"minProperties\") &&\n           schema.at(\"minProperties\").is_integer() &&\n           schema.defines(\"required\") && schema.at(\"required\").is_array() &&\n           schema.at(\"required\").unique() &&\n           schema.at(\"required\").size() >=\n               static_cast<std::uint64_t>(\n                   schema.at(\"minProperties\").to_integer());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"minProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/dependencies_property_tautology.h",
    "content": "class DependenciesPropertyTautology final : public Rule {\npublic:\n  DependenciesPropertyTautology()\n      : Rule{\"dependencies_property_tautology\",\n             \"Defining requirements for a property using `dependencies` \"\n             \"that is already marked as required is an unnecessarily complex \"\n             \"use of `dependencies`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(vocabularies,\n                        {\"http://json-schema.org/draft-07/schema#\",\n                         \"http://json-schema.org/draft-06/schema#\",\n                         \"http://json-schema.org/draft-04/schema#\",\n                         \"http://json-schema.org/draft-03/schema#\"}) &&\n           schema.is_object() && schema.defines(\"dependencies\") &&\n           schema.at(\"dependencies\").is_object() &&\n           schema.defines(\"required\") && schema.at(\"required\").is_array() &&\n           std::any_of(schema.at(\"required\").as_array().cbegin(),\n                       schema.at(\"required\").as_array().cend(),\n                       [&schema](const auto &element) {\n                         return element.is_string() &&\n                                schema.at(\"dependencies\")\n                                    .defines(element.to_string()) &&\n                                (schema.at(\"dependencies\")\n                                     .at(element.to_string())\n                                     .is_array() ||\n                                 schema.at(\"dependencies\")\n                                     .at(element.to_string())\n                                     .is_string());\n                       });\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto requirements{transformer.schema().at(\"required\")};\n    while (true) {\n      bool match{false};\n      const auto copy{requirements};\n      for (const auto &element : copy.as_array()) {\n        if (!element.is_string() || !transformer.schema()\n                                         .at(\"dependencies\")\n                                         .defines(element.to_string())) {\n          continue;\n        }\n\n        const auto &dependents{\n            transformer.schema().at(\"dependencies\").at(element.to_string())};\n        if (dependents.is_array()) {\n          for (const auto &dependent : dependents.as_array()) {\n            if (dependent.is_string()) {\n              match = true;\n              requirements.push_back(dependent);\n            }\n          }\n\n          transformer.erase({\"dependencies\"}, element.to_string());\n        } else if (dependents.is_string()) {\n          match = true;\n          requirements.push_back(dependents);\n          transformer.erase({\"dependencies\"}, element.to_string());\n        }\n      }\n\n      if (!match) {\n        break;\n      }\n    }\n\n    transformer.assign(\"required\", requirements);\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/dependent_required_tautology.h",
    "content": "class DependentRequiredTautology final : public Rule {\npublic:\n  DependentRequiredTautology()\n      : Rule{\"dependent_required_tautology\",\n             \"Defining requirements for a property using `dependentRequired` \"\n             \"that is already marked as required is an unnecessarily complex \"\n             \"use of `dependentRequired`\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"dependentRequired\") &&\n           schema.at(\"dependentRequired\").is_object() &&\n           schema.defines(\"required\") && schema.at(\"required\").is_array() &&\n           std::any_of(schema.at(\"required\").as_array().cbegin(),\n                       schema.at(\"required\").as_array().cend(),\n                       [&schema](const auto &element) {\n                         return element.is_string() &&\n                                schema.at(\"dependentRequired\")\n                                    .defines(element.to_string());\n                       });\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto requirements{transformer.schema().at(\"required\")};\n    while (true) {\n      bool match{false};\n      const auto copy{requirements};\n      for (const auto &element : copy.as_array()) {\n        if (!element.is_string() || !transformer.schema()\n                                         .at(\"dependentRequired\")\n                                         .defines(element.to_string())) {\n          continue;\n        }\n\n        const auto &dependents{transformer.schema()\n                                   .at(\"dependentRequired\")\n                                   .at(element.to_string())};\n        if (dependents.is_array()) {\n          for (const auto &dependent : dependents.as_array()) {\n            if (dependent.is_string()) {\n              match = true;\n              requirements.push_back(dependent);\n            }\n          }\n\n          transformer.erase({\"dependentRequired\"}, element.to_string());\n        }\n      }\n\n      if (!match) {\n        break;\n      }\n    }\n\n    transformer.assign(\"required\", requirements);\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/equal_numeric_bounds_to_enum.h",
    "content": "class EqualNumericBoundsToEnum final : public Rule {\npublic:\n  EqualNumericBoundsToEnum()\n      : Rule{\"equal_numeric_bounds_to_enum\",\n             \"Setting `minimum` and `maximum` to the same number only leaves \"\n             \"one possible value\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           schema.defines(\"minimum\") && schema.at(\"minimum\").is_number() &&\n           schema.defines(\"maximum\") && schema.at(\"maximum\").is_number() &&\n           schema.at(\"minimum\") == schema.at(\"maximum\");\n  }\n\n  auto transform(sourcemeta::alterschema::Transformer &transformer) const\n      -> void override {\n    sourcemeta::jsontoolkit::JSON values =\n        sourcemeta::jsontoolkit::JSON::make_array();\n    values.push_back(transformer.schema().at(\"minimum\"));\n    transformer.assign(\"enum\", std::move(values));\n    transformer.erase(\"type\");\n    transformer.erase(\"minimum\");\n    transformer.erase(\"maximum\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/maximum_real_for_integer.h",
    "content": "class MaximumRealForInteger final : public Rule {\npublic:\n  MaximumRealForInteger()\n      : Rule{\"maximum_real_for_integer\",\n             \"If an instance is guaranteed to be an integer, setting a real \"\n             \"number upper bound is the same as a floor of that upper bound\"} {\n        };\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"maximum\") && schema.at(\"maximum\").is_real();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    const auto current{transformer.schema().at(\"maximum\").to_real()};\n    const auto new_value{static_cast<std::int64_t>(std::floor(current))};\n    transformer.assign(\"maximum\", sourcemeta::jsontoolkit::JSON{new_value});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/minimum_real_for_integer.h",
    "content": "class MinimumRealForInteger final : public Rule {\npublic:\n  MinimumRealForInteger()\n      : Rule{\"minimum_real_for_integer\",\n             \"If an instance is guaranteed to be an integer, setting a real \"\n             \"number lower bound is the same as a ceil of that lower bound\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"integer\" &&\n           schema.defines(\"minimum\") && schema.at(\"minimum\").is_real();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    const auto current{transformer.schema().at(\"minimum\").to_real()};\n    const auto new_value{static_cast<std::int64_t>(std::ceil(current))};\n    transformer.assign(\"minimum\", sourcemeta::jsontoolkit::JSON{new_value});\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/simplify/single_type_array.h",
    "content": "class SingleTypeArray final : public Rule {\npublic:\n  SingleTypeArray()\n      : Rule{\"single_type_array\",\n             \"Setting `type` to an array of a single type is \"\n             \"the same as directly declaring such type\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\",\n                \"http://json-schema.org/draft-03/schema#\",\n                \"http://json-schema.org/draft-02/hyper-schema#\",\n                \"http://json-schema.org/draft-01/hyper-schema#\",\n                \"http://json-schema.org/draft-00/hyper-schema#\"}) &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_array() && schema.at(\"type\").size() == 1 &&\n           schema.at(\"type\").front().is_string();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto type{transformer.schema().at(\"type\").front()};\n    transformer.replace({\"type\"}, std::move(type));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/content_media_type_without_encoding.h",
    "content": "class ContentMediaTypeWithoutEncoding final : public Rule {\npublic:\n  ContentMediaTypeWithoutEncoding()\n      : Rule{\"content_media_type_without_encoding\",\n             \"The `contentMediaType` keyword is meaningless \"\n             \"without the presence of the `contentEncoding` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(vocabularies,\n                        {\"https://json-schema.org/draft/2020-12/vocab/content\",\n                         \"https://json-schema.org/draft/2019-09/vocab/content\",\n                         \"http://json-schema.org/draft-07/schema#\"}) &&\n           schema.is_object() && schema.defines(\"contentMediaType\") &&\n           !schema.defines(\"contentEncoding\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"contentMediaType\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/content_schema_without_media_type.h",
    "content": "class ContentSchemaWithoutMediaType final : public Rule {\npublic:\n  ContentSchemaWithoutMediaType()\n      : Rule{\"content_schema_without_media_type\",\n             \"The `contentSchema` keyword is meaningless without the presence \"\n             \"of the `contentMediaType` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/content\",\n                \"https://json-schema.org/draft/2019-09/vocab/content\"}) &&\n           schema.is_object() && schema.defines(\"contentSchema\") &&\n           !schema.defines(\"contentMediaType\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"contentSchema\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_applicator_2019_09.h",
    "content": "class DropNonArrayKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonArrayKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_array_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",       \"patternProperties\", \"additionalProperties\",\n      \"dependentSchemas\", \"propertyNames\",     \"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_applicator_2020_12.h",
    "content": "class DropNonArrayKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonArrayKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_array_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\", \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\", \"propertyNames\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_content_2019_09.h",
    "content": "class DropNonArrayKeywordsContent_2019_09 final : public Rule {\npublic:\n  DropNonArrayKeywordsContent_2019_09()\n      : Rule{\"drop_non_array_keywords_content_2019_09\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_content_2020_12.h",
    "content": "class DropNonArrayKeywordsContent_2020_12 final : public Rule {\npublic:\n  DropNonArrayKeywordsContent_2020_12()\n      : Rule{\"drop_non_array_keywords_content_2020_12\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft0.h",
    "content": "class DropNonArrayKeywords_Draft0 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft0()\n      : Rule{\"drop_non_array_keywords_draft0\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"maxDecimal\",      \"maximum\",   \"maximumCanEqual\", \"minimum\",\n      \"minimumCanEqual\", \"maxLength\", \"minLength\",       \"pattern\",\n      \"requires\",        \"optional\",  \"properties\",      \"additionalProperties\",\n      \"contentEncoding\", \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft1.h",
    "content": "class DropNonArrayKeywords_Draft1 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft1()\n      : Rule{\"drop_non_array_keywords_draft1\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"maxDecimal\",      \"maximum\",   \"maximumCanEqual\", \"minimum\",\n      \"minimumCanEqual\", \"maxLength\", \"minLength\",       \"pattern\",\n      \"requires\",        \"optional\",  \"properties\",      \"additionalProperties\",\n      \"contentEncoding\", \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft2.h",
    "content": "class DropNonArrayKeywords_Draft2 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft2()\n      : Rule{\"drop_non_array_keywords_draft2\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"optional\",        \"additionalProperties\",\n      \"requires\",        \"minimum\",         \"maximum\",\n      \"minimumCanEqual\", \"maximumCanEqual\", \"pattern\",\n      \"maxLength\",       \"minLength\",       \"format\",\n      \"contentEncoding\", \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft3.h",
    "content": "class DropNonArrayKeywords_Draft3 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft3()\n      : Rule{\"drop_non_array_keywords_draft3\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\", \"patternProperties\", \"additionalProperties\",\n      \"required\",   \"dependencies\",      \"minimum\",\n      \"maximum\",    \"exclusiveMinimum\",  \"exclusiveMaximum\",\n      \"pattern\",    \"minLength\",         \"maxLength\",\n      \"format\",     \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft4.h",
    "content": "class DropNonArrayKeywords_Draft4 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft4()\n      : Rule{\"drop_non_array_keywords_draft4\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"multipleOf\",        \"maximum\",\n      \"exclusiveMaximum\",  \"minimum\",\n      \"exclusiveMinimum\",  \"maxLength\",\n      \"minLength\",         \"pattern\",\n      \"maxProperties\",     \"minProperties\",\n      \"required\",          \"properties\",\n      \"patternProperties\", \"additionalProperties\",\n      \"dependencies\",      \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft6.h",
    "content": "class DropNonArrayKeywords_Draft6 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft6()\n      : Rule{\"drop_non_array_keywords_draft6\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_draft7.h",
    "content": "class DropNonArrayKeywords_Draft7 final : public Rule {\npublic:\n  DropNonArrayKeywords_Draft7()\n      : Rule{\"drop_non_array_keywords_draft7\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"contentEncoding\",\n                                        \"contentMediaType\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_format_2019_09.h",
    "content": "class DropNonArrayKeywordsFormat_2019_09 final : public Rule {\npublic:\n  DropNonArrayKeywordsFormat_2019_09()\n      : Rule{\"drop_non_array_keywords_format_2019_09\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/format\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_format_2020_12.h",
    "content": "class DropNonArrayKeywordsFormat_2020_12 final : public Rule {\npublic:\n  DropNonArrayKeywordsFormat_2020_12()\n      : Rule{\"drop_non_array_keywords_format_2020_12\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           (vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-annotation\") ||\n            vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-assertion\")) &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_unevaluated_2020_12.h",
    "content": "class DropNonArrayKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonArrayKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_array_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_validation_2019_09.h",
    "content": "class DropNonArrayKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonArrayKeywordsValidation_2019_09()\n      : Rule{\"drop_non_array_keywords_validation_2019_09\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_array_keywords_validation_2020_12.h",
    "content": "class DropNonArrayKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonArrayKeywordsValidation_2020_12()\n      : Rule{\"drop_non_array_keywords_validation_2020_12\",\n             \"Keywords that don't apply to arrays will never match if the \"\n             \"instance is guaranteed to be an array\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"array\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_applicator_2019_09.h",
    "content": "class DropNonBooleanKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonBooleanKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_boolean_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"additionalItems\",\n                                        \"contains\",\n                                        \"items\",\n                                        \"unevaluatedProperties\",\n                                        \"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_applicator_2020_12.h",
    "content": "class DropNonBooleanKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonBooleanKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_boolean_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"prefixItems\",\n                                        \"contains\",\n                                        \"items\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_content_2019_09.h",
    "content": "class DropNonBooleanKeywordsContent_2019_09 final : public Rule {\npublic:\n  DropNonBooleanKeywordsContent_2019_09()\n      : Rule{\"drop_non_boolean_keywords_content_2019_09\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_content_2020_12.h",
    "content": "class DropNonBooleanKeywordsContent_2020_12 final : public Rule {\npublic:\n  DropNonBooleanKeywordsContent_2020_12()\n      : Rule{\"drop_non_boolean_keywords_content_2020_12\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft0.h",
    "content": "class DropNonBooleanKeywords_Draft0 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft0()\n      : Rule{\"drop_non_boolean_keywords_draft0\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\",        \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft1.h",
    "content": "class DropNonBooleanKeywords_Draft1 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft1()\n      : Rule{\"drop_non_boolean_keywords_draft1\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\",        \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft2.h",
    "content": "class DropNonBooleanKeywords_Draft2 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft2()\n      : Rule{\"drop_non_boolean_keywords_draft2\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",      \"optional\",  \"additionalProperties\",\n      \"requires\",        \"minimum\",    \"maximum\",   \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\",   \"maxItems\",  \"uniqueItems\",\n      \"pattern\",         \"maxLength\",  \"minLength\", \"format\",\n      \"contentEncoding\", \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft3.h",
    "content": "class DropNonBooleanKeywords_Draft3 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft3()\n      : Rule{\"drop_non_boolean_keywords_draft3\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"items\",\n                                        \"additionalItems\",\n                                        \"required\",\n                                        \"dependencies\",\n                                        \"minimum\",\n                                        \"maximum\",\n                                        \"exclusiveMinimum\",\n                                        \"exclusiveMaximum\",\n                                        \"minItems\",\n                                        \"maxItems\",\n                                        \"uniqueItems\",\n                                        \"pattern\",\n                                        \"minLength\",\n                                        \"maxLength\",\n                                        \"format\",\n                                        \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft4.h",
    "content": "class DropNonBooleanKeywords_Draft4 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft4()\n      : Rule{\"drop_non_boolean_keywords_draft4\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft6.h",
    "content": "class DropNonBooleanKeywords_Draft6 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft6()\n      : Rule{\"drop_non_boolean_keywords_draft6\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_draft7.h",
    "content": "class DropNonBooleanKeywords_Draft7 final : public Rule {\npublic:\n  DropNonBooleanKeywords_Draft7()\n      : Rule{\"drop_non_boolean_keywords_draft7\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"boolean\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"contentEncoding\",\n                                        \"contentMediaType\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_format_2019_09.h",
    "content": "class DropNonBooleanKeywordsFormat_2019_09 final : public Rule {\npublic:\n  DropNonBooleanKeywordsFormat_2019_09()\n      : Rule{\"drop_non_boolean_keywords_format_2019_09\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/format\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_format_2020_12.h",
    "content": "class DropNonBooleanKeywordsFormat_2020_12 final : public Rule {\npublic:\n  DropNonBooleanKeywordsFormat_2020_12()\n      : Rule{\"drop_non_boolean_keywords_format_2020_12\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           (vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-annotation\") ||\n            vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-assertion\")) &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_unevaluated_2020_12.h",
    "content": "class DropNonBooleanKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonBooleanKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_boolean_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedItems\",\n                                        \"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_validation_2019_09.h",
    "content": "class DropNonBooleanKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonBooleanKeywordsValidation_2019_09()\n      : Rule{\"drop_non_boolean_keywords_validation_2019_09\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\",\n      \"minItems\",          \"maxItems\",      \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_boolean_keywords_validation_2020_12.h",
    "content": "class DropNonBooleanKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonBooleanKeywordsValidation_2020_12()\n      : Rule{\"drop_non_boolean_keywords_validation_2020_12\",\n             \"Keywords that don't apply to booleans will never match if the \"\n             \"instance is guaranteed to be a boolean\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"boolean\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_boolean(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\",\n      \"minItems\",          \"maxItems\",      \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_applicator_2019_09.h",
    "content": "class DropNonNullKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonNullKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_null_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"additionalItems\",\n                                        \"contains\",\n                                        \"items\",\n                                        \"unevaluatedProperties\",\n                                        \"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_applicator_2020_12.h",
    "content": "class DropNonNullKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonNullKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_null_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"prefixItems\",\n                                        \"contains\",\n                                        \"items\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_content_2019_09.h",
    "content": "class DropNonNullKeywordsContent_2019_09 final : public Rule {\npublic:\n  DropNonNullKeywordsContent_2019_09()\n      : Rule{\"drop_non_null_keywords_content_2019_09\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_content_2020_12.h",
    "content": "class DropNonNullKeywordsContent_2020_12 final : public Rule {\npublic:\n  DropNonNullKeywordsContent_2020_12()\n      : Rule{\"drop_non_null_keywords_content_2020_12\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft0.h",
    "content": "class DropNonNullKeywords_Draft0 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft0()\n      : Rule{\"drop_non_null_keywords_draft0\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\",        \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft1.h",
    "content": "class DropNonNullKeywords_Draft1 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft1()\n      : Rule{\"drop_non_null_keywords_draft1\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\",        \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft2.h",
    "content": "class DropNonNullKeywords_Draft2 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft2()\n      : Rule{\"drop_non_null_keywords_draft2\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",      \"optional\",  \"additionalProperties\",\n      \"requires\",        \"minimum\",    \"maximum\",   \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\",   \"maxItems\",  \"uniqueItems\",\n      \"pattern\",         \"maxLength\",  \"minLength\", \"format\",\n      \"contentEncoding\", \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft3.h",
    "content": "class DropNonNullKeywords_Draft3 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft3()\n      : Rule{\"drop_non_null_keywords_draft3\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"items\",\n                                        \"additionalItems\",\n                                        \"required\",\n                                        \"dependencies\",\n                                        \"minimum\",\n                                        \"maximum\",\n                                        \"exclusiveMinimum\",\n                                        \"exclusiveMaximum\",\n                                        \"minItems\",\n                                        \"maxItems\",\n                                        \"uniqueItems\",\n                                        \"pattern\",\n                                        \"minLength\",\n                                        \"maxLength\",\n                                        \"format\",\n                                        \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft4.h",
    "content": "class DropNonNullKeywords_Draft4 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft4()\n      : Rule{\"drop_non_null_keywords_draft4\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft6.h",
    "content": "class DropNonNullKeywords_Draft6 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft6()\n      : Rule{\"drop_non_null_keywords_draft6\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_draft7.h",
    "content": "class DropNonNullKeywords_Draft7 final : public Rule {\npublic:\n  DropNonNullKeywords_Draft7()\n      : Rule{\"drop_non_null_keywords_draft7\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"null\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"contentEncoding\",\n                                        \"contentMediaType\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_format_2019_09.h",
    "content": "class DropNonNullKeywordsFormat_2019_09 final : public Rule {\npublic:\n  DropNonNullKeywordsFormat_2019_09()\n      : Rule{\"drop_non_null_keywords_format_2019_09\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/format\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_format_2020_12.h",
    "content": "class DropNonNullKeywordsFormat_2020_12 final : public Rule {\npublic:\n  DropNonNullKeywordsFormat_2020_12()\n      : Rule{\"drop_non_null_keywords_format_2020_12\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           (vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-annotation\") ||\n            vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-assertion\")) &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_unevaluated_2020_12.h",
    "content": "class DropNonNullKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonNullKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_null_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedItems\",\n                                        \"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_validation_2019_09.h",
    "content": "class DropNonNullKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonNullKeywordsValidation_2019_09()\n      : Rule{\"drop_non_null_keywords_validation_2019_09\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\",\n      \"minItems\",          \"maxItems\",      \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_null_keywords_validation_2020_12.h",
    "content": "class DropNonNullKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonNullKeywordsValidation_2020_12()\n      : Rule{\"drop_non_null_keywords_validation_2020_12\",\n             \"Keywords that don't apply to null values will never match if the \"\n             \"instance is guaranteed to be null\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() &&\n           ((schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n             schema.at(\"type\").to_string() == \"null\") ||\n            (schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n             every_item_is_null(schema.at(\"enum\").as_array()))) &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",         \"maxLength\",     \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\", \"minimum\",\n      \"dependentRequired\", \"minProperties\", \"maxProperties\",    \"required\",\n      \"minItems\",          \"maxItems\",      \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_applicator_2019_09.h",
    "content": "class DropNonNumericKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonNumericKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_numeric_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"additionalItems\",\n                                        \"contains\",\n                                        \"items\",\n                                        \"unevaluatedProperties\",\n                                        \"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_applicator_2020_12.h",
    "content": "class DropNonNumericKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonNumericKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_numeric_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"prefixItems\",\n                                        \"contains\",\n                                        \"items\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_content_2019_09.h",
    "content": "class DropNonNumericKeywordsContent_2019_09 final : public Rule {\npublic:\n  DropNonNumericKeywordsContent_2019_09()\n      : Rule{\"drop_non_numeric_keywords_content_2019_09\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_content_2020_12.h",
    "content": "class DropNonNumericKeywordsContent_2020_12 final : public Rule {\npublic:\n  DropNonNumericKeywordsContent_2020_12()\n      : Rule{\"drop_non_numeric_keywords_content_2020_12\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft0.h",
    "content": "class DropNonNumericKeywords_Draft0 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft0()\n      : Rule{\"drop_non_numeric_keywords_draft0\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\", \"items\",    \"optional\",       \"additionalProperties\",\n      \"requires\",   \"minItems\", \"maxItems\",       \"maxLength\",\n      \"minLength\",  \"format\",   \"contentEncoding\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft1.h",
    "content": "class DropNonNumericKeywords_Draft1 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft1()\n      : Rule{\"drop_non_numeric_keywords_draft1\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\", \"items\",    \"optional\",       \"additionalProperties\",\n      \"requires\",   \"minItems\", \"maxItems\",       \"maxLength\",\n      \"minLength\",  \"format\",   \"contentEncoding\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft2.h",
    "content": "class DropNonNumericKeywords_Draft2 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft2()\n      : Rule{\"drop_non_numeric_keywords_draft2\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",     \"items\",     \"optional\",  \"additionalProperties\",\n      \"requires\",       \"minItems\",  \"maxItems\",  \"uniqueItems\",\n      \"pattern\",        \"maxLength\", \"minLength\", \"format\",\n      \"contentEncoding\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft3.h",
    "content": "class DropNonNumericKeywords_Draft3 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft3()\n      : Rule{\"drop_non_numeric_keywords_draft3\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"items\",\n                                        \"additionalItems\",\n                                        \"required\",\n                                        \"dependencies\",\n                                        \"minItems\",\n                                        \"maxItems\",\n                                        \"uniqueItems\",\n                                        \"pattern\",\n                                        \"minLength\",\n                                        \"maxLength\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft4.h",
    "content": "class DropNonNumericKeywords_Draft4 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft4()\n      : Rule{\"drop_non_numeric_keywords_draft4\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft6.h",
    "content": "class DropNonNumericKeywords_Draft6 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft6()\n      : Rule{\"drop_non_numeric_keywords_draft6\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_draft7.h",
    "content": "class DropNonNumericKeywords_Draft7 final : public Rule {\npublic:\n  DropNonNumericKeywords_Draft7()\n      : Rule{\"drop_non_numeric_keywords_draft7\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"number\" ||\n            schema.at(\"type\").to_string() == \"integer\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"contentEncoding\",\n                                        \"contentMediaType\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_format_2019_09.h",
    "content": "class DropNonNumericKeywordsFormat_2019_09 final : public Rule {\npublic:\n  DropNonNumericKeywordsFormat_2019_09()\n      : Rule{\"drop_non_numeric_keywords_format_2019_09\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/format\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_format_2020_12.h",
    "content": "class DropNonNumericKeywordsFormat_2020_12 final : public Rule {\npublic:\n  DropNonNumericKeywordsFormat_2020_12()\n      : Rule{\"drop_non_numeric_keywords_format_2020_12\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           (vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-annotation\") ||\n            vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-assertion\")) &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_unevaluated_2020_12.h",
    "content": "class DropNonNumericKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonNumericKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_numeric_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedItems\",\n                                        \"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_validation_2019_09.h",
    "content": "class DropNonNumericKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonNumericKeywordsValidation_2019_09()\n      : Rule{\"drop_non_numeric_keywords_validation_2019_09\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",     \"maxLength\",     \"pattern\",     \"dependentRequired\",\n      \"minProperties\", \"maxProperties\", \"required\",    \"minItems\",\n      \"maxItems\",      \"minContains\",   \"maxContains\", \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_numeric_keywords_validation_2020_12.h",
    "content": "class DropNonNumericKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonNumericKeywordsValidation_2020_12()\n      : Rule{\"drop_non_numeric_keywords_validation_2020_12\",\n             \"Keywords that don't apply to numbers will never match if the \"\n             \"instance is guaranteed to be a number\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           (schema.at(\"type\").to_string() == \"integer\" ||\n            schema.at(\"type\").to_string() == \"number\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",     \"maxLength\",     \"pattern\",     \"dependentRequired\",\n      \"minProperties\", \"maxProperties\", \"required\",    \"minItems\",\n      \"maxItems\",      \"minContains\",   \"maxContains\", \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_applicator_2019_09.h",
    "content": "class DropNonObjectKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonObjectKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_object_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"additionalItems\", \"contains\", \"items\",\n                                        \"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_applicator_2020_12.h",
    "content": "class DropNonObjectKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonObjectKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_object_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"prefixItems\", \"contains\", \"items\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_content_2019_09.h",
    "content": "class DropNonObjectKeywordsContent_2019_09 final : public Rule {\npublic:\n  DropNonObjectKeywordsContent_2019_09()\n      : Rule{\"drop_non_object_keywords_content_2019_09\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_content_2020_12.h",
    "content": "class DropNonObjectKeywordsContent_2020_12 final : public Rule {\npublic:\n  DropNonObjectKeywordsContent_2020_12()\n      : Rule{\"drop_non_object_keywords_content_2020_12\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/content\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"contentEncoding\", \"contentMediaType\",\n                                        \"contentSchema\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft0.h",
    "content": "class DropNonObjectKeywords_Draft0 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft0()\n      : Rule{\"drop_non_object_keywords_draft0\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"items\",           \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft1.h",
    "content": "class DropNonObjectKeywords_Draft1 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft1()\n      : Rule{\"drop_non_object_keywords_draft1\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"items\",           \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft2.h",
    "content": "class DropNonObjectKeywords_Draft2 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft2()\n      : Rule{\"drop_non_object_keywords_draft2\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"items\",           \"minimum\",  \"maximum\",         \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\",        \"maxLength\",\n      \"minLength\",       \"format\",   \"contentEncoding\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft3.h",
    "content": "class DropNonObjectKeywords_Draft3 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft3()\n      : Rule{\"drop_non_object_keywords_draft3\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"items\",     \"additionalItems\",  \"required\",         \"minimum\",\n      \"maximum\",   \"exclusiveMinimum\", \"exclusiveMaximum\", \"minItems\",\n      \"maxItems\",  \"uniqueItems\",      \"pattern\",          \"minLength\",\n      \"maxLength\", \"format\",           \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft4.h",
    "content": "class DropNonObjectKeywords_Draft4 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft4()\n      : Rule{\"drop_non_object_keywords_draft4\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"multipleOf\",       \"maximum\",   \"exclusiveMaximum\", \"minimum\",\n      \"exclusiveMinimum\", \"maxLength\", \"minLength\",        \"pattern\",\n      \"additionalItems\",  \"items\",     \"maxItems\",         \"minItems\",\n      \"uniqueItems\",      \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft6.h",
    "content": "class DropNonObjectKeywords_Draft6 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft6()\n      : Rule{\"drop_non_object_keywords_draft6\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"multipleOf\", \"maximum\",          \"exclusiveMaximum\",\n      \"minimum\",    \"exclusiveMinimum\", \"maxLength\",\n      \"minLength\",  \"pattern\",          \"additionalItems\",\n      \"items\",      \"contains\",         \"maxItems\",\n      \"minItems\",   \"uniqueItems\",      \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_draft7.h",
    "content": "class DropNonObjectKeywords_Draft7 final : public Rule {\npublic:\n  DropNonObjectKeywords_Draft7()\n      : Rule{\"drop_non_object_keywords_draft7\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"maxLength\",\n                                        \"minLength\",\n                                        \"pattern\",\n                                        \"contentEncoding\",\n                                        \"contentMediaType\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_format_2019_09.h",
    "content": "class DropNonObjectKeywordsFormat_2019_09 final : public Rule {\npublic:\n  DropNonObjectKeywordsFormat_2019_09()\n      : Rule{\"drop_non_object_keywords_format_2019_09\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/format\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_format_2020_12.h",
    "content": "class DropNonObjectKeywordsFormat_2020_12 final : public Rule {\npublic:\n  DropNonObjectKeywordsFormat_2020_12()\n      : Rule{\"drop_non_object_keywords_format_2020_12\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           (vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-annotation\") ||\n            vocabularies.contains(\"https://json-schema.org/draft/2020-12/vocab/\"\n                                  \"format-assertion\")) &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"format\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_unevaluated_2020_12.h",
    "content": "class DropNonObjectKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonObjectKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_object_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_validation_2019_09.h",
    "content": "class DropNonObjectKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonObjectKeywordsValidation_2019_09()\n      : Rule{\"drop_non_object_keywords_validation_2019_09\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",        \"maxLength\",  \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\", \"multipleOf\", \"exclusiveMaximum\", \"minimum\",\n      \"minItems\",         \"maxItems\",   \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_object_keywords_validation_2020_12.h",
    "content": "class DropNonObjectKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonObjectKeywordsValidation_2020_12()\n      : Rule{\"drop_non_object_keywords_validation_2020_12\",\n             \"Keywords that don't apply to objects will never match if the \"\n             \"instance is guaranteed to be an object\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"object\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"minLength\",        \"maxLength\",  \"pattern\",          \"maximum\",\n      \"exclusiveMinimum\", \"multipleOf\", \"exclusiveMaximum\", \"minimum\",\n      \"minItems\",         \"maxItems\",   \"minContains\",      \"maxContains\",\n      \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_applicator_2019_09.h",
    "content": "class DropNonStringKeywordsApplicator_2019_09 final : public Rule {\npublic:\n  DropNonStringKeywordsApplicator_2019_09()\n      : Rule{\"drop_non_string_keywords_applicator_2019_09\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"additionalItems\",\n                                        \"contains\",\n                                        \"items\",\n                                        \"unevaluatedProperties\",\n                                        \"unevaluatedItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_applicator_2020_12.h",
    "content": "class DropNonStringKeywordsApplicator_2020_12 final : public Rule {\npublic:\n  DropNonStringKeywordsApplicator_2020_12()\n      : Rule{\"drop_non_string_keywords_applicator_2020_12\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/applicator\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependentSchemas\",\n                                        \"propertyNames\",\n                                        \"prefixItems\",\n                                        \"contains\",\n                                        \"items\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft0.h",
    "content": "class DropNonStringKeywords_Draft0 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft0()\n      : Rule{\"drop_non_string_keywords_draft0\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-00/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\", \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",  \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft1.h",
    "content": "class DropNonStringKeywords_Draft1 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft1()\n      : Rule{\"drop_non_string_keywords_draft1\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-01/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\", \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",  \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\", \"maxDecimal\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft2.h",
    "content": "class DropNonStringKeywords_Draft2 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft2()\n      : Rule{\"drop_non_string_keywords_draft2\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"http://json-schema.org/draft-02/hyper-schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"properties\",      \"items\",    \"optional\", \"additionalProperties\",\n      \"requires\",        \"minimum\",  \"maximum\",  \"minimumCanEqual\",\n      \"maximumCanEqual\", \"minItems\", \"maxItems\", \"uniqueItems\",\n      \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft3.h",
    "content": "class DropNonStringKeywords_Draft3 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft3()\n      : Rule{\"drop_non_string_keywords_draft3\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-03/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"items\",\n                                        \"additionalItems\",\n                                        \"required\",\n                                        \"dependencies\",\n                                        \"minimum\",\n                                        \"maximum\",\n                                        \"exclusiveMinimum\",\n                                        \"exclusiveMaximum\",\n                                        \"minItems\",\n                                        \"maxItems\",\n                                        \"uniqueItems\",\n                                        \"divisibleBy\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft4.h",
    "content": "class DropNonStringKeywords_Draft4 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft4()\n      : Rule{\"drop_non_string_keywords_draft4\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-04/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"dependencies\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft6.h",
    "content": "class DropNonStringKeywords_Draft6 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft6()\n      : Rule{\"drop_non_string_keywords_draft6\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-06/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_draft7.h",
    "content": "class DropNonStringKeywords_Draft7 final : public Rule {\npublic:\n  DropNonStringKeywords_Draft7()\n      : Rule{\"drop_non_string_keywords_draft7\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\"http://json-schema.org/draft-07/schema#\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"multipleOf\",\n                                        \"maximum\",\n                                        \"exclusiveMaximum\",\n                                        \"minimum\",\n                                        \"exclusiveMinimum\",\n                                        \"additionalItems\",\n                                        \"items\",\n                                        \"contains\",\n                                        \"maxItems\",\n                                        \"minItems\",\n                                        \"uniqueItems\",\n                                        \"maxProperties\",\n                                        \"minProperties\",\n                                        \"required\",\n                                        \"properties\",\n                                        \"patternProperties\",\n                                        \"additionalProperties\",\n                                        \"propertyNames\",\n                                        \"dependencies\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_unevaluated_2020_12.h",
    "content": "class DropNonStringKeywordsUnevaluated_2020_12 final : public Rule {\npublic:\n  DropNonStringKeywordsUnevaluated_2020_12()\n      : Rule{\"drop_non_string_keywords_unevaluated_2020_12\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/unevaluated\") &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\"unevaluatedItems\",\n                                        \"unevaluatedProperties\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_validation_2019_09.h",
    "content": "class DropNonStringKeywordsValidation_2019_09 final : public Rule {\npublic:\n  DropNonStringKeywordsValidation_2019_09()\n      : Rule{\"drop_non_string_keywords_validation_2019_09\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2019-09/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"maximum\",     \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\",\n      \"minimum\",     \"dependentRequired\", \"minProperties\", \"maxProperties\",\n      \"required\",    \"minItems\",          \"maxItems\",      \"minContains\",\n      \"maxContains\", \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/drop_non_string_keywords_validation_2020_12.h",
    "content": "class DropNonStringKeywordsValidation_2020_12 final : public Rule {\npublic:\n  DropNonStringKeywordsValidation_2020_12()\n      : Rule{\"drop_non_string_keywords_validation_2020_12\",\n             \"Keywords that don't apply to strings will never match if the \"\n             \"instance is guaranteed to be a string\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return vocabularies.contains(\n               \"https://json-schema.org/draft/2020-12/vocab/validation\") &&\n           schema.is_object() && schema.defines(\"type\") &&\n           schema.at(\"type\").is_string() &&\n           schema.at(\"type\").to_string() == \"string\" &&\n           schema.defines_any(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase_keys(this->BLACKLIST.cbegin(), this->BLACKLIST.cend());\n  }\n\nprivate:\n  const std::set<std::string> BLACKLIST{\n      \"maximum\",     \"exclusiveMinimum\",  \"multipleOf\",    \"exclusiveMaximum\",\n      \"minimum\",     \"dependentRequired\", \"minProperties\", \"maxProperties\",\n      \"required\",    \"minItems\",          \"maxItems\",      \"minContains\",\n      \"maxContains\", \"uniqueItems\"};\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/duplicate_allof_branches.h",
    "content": "class DuplicateAllOfBranches final : public Rule {\npublic:\n  DuplicateAllOfBranches()\n      : Rule{\"duplicate_allof_branches\",\n             \"Setting duplicate subschemas in `allOf` is redundant, as it \"\n             \"produces \"\n             \"unnecessary additional validation that is guaranteed to not \"\n             \"affect the validation result\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"allOf\") &&\n           schema.at(\"allOf\").is_array() && !schema.at(\"allOf\").unique();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto collection = transformer.schema().at(\"allOf\");\n    std::sort(collection.as_array().begin(), collection.as_array().end());\n    auto last =\n        std::unique(collection.as_array().begin(), collection.as_array().end());\n    collection.erase(last, collection.as_array().end());\n    transformer.replace({\"allOf\"}, std::move(collection));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/duplicate_anyof_branches.h",
    "content": "class DuplicateAnyOfBranches final : public Rule {\npublic:\n  DuplicateAnyOfBranches()\n      : Rule{\"duplicate_anyof_branches\",\n             \"Setting duplicate subschemas in `anyOf` is redundant, as it \"\n             \"produces \"\n             \"unnecessary additional validation that is guaranteed to not \"\n             \"affect the validation result\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\",\n                \"http://json-schema.org/draft-04/schema#\"}) &&\n           schema.is_object() && schema.defines(\"anyOf\") &&\n           schema.at(\"anyOf\").is_array() && !schema.at(\"anyOf\").unique();\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    auto collection = transformer.schema().at(\"anyOf\");\n    std::sort(collection.as_array().begin(), collection.as_array().end());\n    auto last =\n        std::unique(collection.as_array().begin(), collection.as_array().end());\n    collection.erase(last, collection.as_array().end());\n    transformer.replace({\"anyOf\"}, std::move(collection));\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/else_without_if.h",
    "content": "class ElseWithoutIf final : public Rule {\npublic:\n  ElseWithoutIf()\n      : Rule{\"else_without_if\", \"The `else` keyword is meaningless \"\n                                \"without the presence of the `if` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\"}) &&\n           schema.is_object() && schema.defines(\"else\") &&\n           !schema.defines(\"if\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"else\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/if_without_then_else.h",
    "content": "class IfWithoutThenElse final : public Rule {\npublic:\n  IfWithoutThenElse()\n      : Rule{\"if_without_then_else\",\n             \"The `if` keyword is meaningless \"\n             \"without the presence of the `then` or `else` keywords\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\"}) &&\n           schema.is_object() && schema.defines(\"if\") &&\n           !schema.defines(\"then\") && !schema.defines(\"else\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"if\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/max_contains_without_contains.h",
    "content": "class MaxContainsWithoutContains final : public Rule {\npublic:\n  MaxContainsWithoutContains()\n      : Rule{\"max_contains_without_contains\",\n             \"The `maxContains` keyword is meaningless \"\n             \"without the presence of the `contains` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"maxContains\") &&\n           !schema.defines(\"contains\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"maxContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/min_contains_without_contains.h",
    "content": "class MinContainsWithoutContains final : public Rule {\npublic:\n  MinContainsWithoutContains()\n      : Rule{\"min_contains_without_contains\",\n             \"The `minContains` keyword is meaningless \"\n             \"without the presence of the `contains` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\"}) &&\n           schema.is_object() && schema.defines(\"minContains\") &&\n           !schema.defines(\"contains\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"minContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/superfluous/then_without_if.h",
    "content": "class ThenWithoutIf final : public Rule {\npublic:\n  ThenWithoutIf()\n      : Rule{\"then_without_if\", \"The `then` keyword is meaningless \"\n                                \"without the presence of the `if` keyword\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/applicator\",\n                \"https://json-schema.org/draft/2019-09/vocab/applicator\",\n                \"http://json-schema.org/draft-07/schema#\"}) &&\n           schema.is_object() && schema.defines(\"then\") &&\n           !schema.defines(\"if\");\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.erase(\"then\");\n  }\n};\n"
  },
  {
    "path": "vendor/alterschema/src/linter/syntax_sugar/enum_to_const.h",
    "content": "class EnumToConst final : public Rule {\npublic:\n  EnumToConst()\n      : Rule(\"enum_to_const\",\n             \"An `enum` of a single value can be expressed as `const`\") {};\n\n  [[nodiscard]] auto condition(const sourcemeta::jsontoolkit::JSON &schema,\n                               const std::string &,\n                               const std::set<std::string> &vocabularies,\n                               const sourcemeta::jsontoolkit::Pointer &) const\n      -> bool override {\n    return contains_any(\n               vocabularies,\n               {\"https://json-schema.org/draft/2020-12/vocab/validation\",\n                \"https://json-schema.org/draft/2019-09/vocab/validation\",\n                \"http://json-schema.org/draft-07/schema#\",\n                \"http://json-schema.org/draft-06/schema#\"}) &&\n           schema.is_object() && !schema.defines(\"const\") &&\n           schema.defines(\"enum\") && schema.at(\"enum\").is_array() &&\n           schema.at(\"enum\").size() == 1;\n  }\n\n  auto transform(Transformer &transformer) const -> void override {\n    transformer.assign(\"const\", transformer.schema().at(\"enum\").front());\n    transformer.erase(\"enum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(blaze VERSION 0.0.1 LANGUAGES CXX\n  DESCRIPTION \"The ultra high-performance JSON Schema evaluator\"\n  HOMEPAGE_URL \"https://github.com/sourcemeta/blaze\")\nlist(APPEND CMAKE_MODULE_PATH \"${PROJECT_SOURCE_DIR}/cmake\")\n\n# Options\noption(BLAZE_COMPILER \"Build the Blaze compiler library\" ON)\noption(BLAZE_EVALUATOR \"Build the Blaze evaluator library\" ON)\noption(BLAZE_OUTPUT \"Build the Blaze output formats library\" ON)\noption(BLAZE_TEST \"Build the Blaze test runner library\" ON)\noption(BLAZE_CONFIGURATION \"Build the Blaze configuration file library\" ON)\noption(BLAZE_ALTERSCHEMA \"Build the Blaze alterschema rule library\" ON)\noption(BLAZE_CODEGEN \"Build the Blaze codegen library\" ON)\noption(BLAZE_DOCUMENTATION \"Build the Blaze documentation generator library\" ON)\noption(BLAZE_TESTS \"Build the Blaze tests\" OFF)\noption(BLAZE_BENCHMARK \"Build the Blaze benchmarks\" OFF)\noption(BLAZE_CONTRIB \"Build the Blaze contrib programs\" OFF)\noption(BLAZE_DOCS \"Build the Blaze docs\" OFF)\noption(BLAZE_INSTALL \"Install the Blaze library\" ON)\noption(BLAZE_ADDRESS_SANITIZER \"Build Blaze with an address sanitizer\" OFF)\noption(BLAZE_UNDEFINED_SANITIZER \"Build Blaze with an undefined behavior sanitizer\" OFF)\n\nif(BLAZE_INSTALL)\n  include(GNUInstallDirs)\n  include(CMakePackageConfigHelpers)\n  configure_package_config_file(\n    config.cmake.in\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n  write_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    COMPATIBILITY SameMajorVersion)\n  install(FILES\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\"\n    COMPONENT sourcemeta_blaze_dev)\nendif()\n\nfind_package(Core REQUIRED)\n\n# Don't force downstream consumers on it\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_enable_simd()\nendif()\n\nif(BLAZE_COMPILER)\n  add_subdirectory(src/compiler)\nendif()\n\nif(BLAZE_EVALUATOR)\n  add_subdirectory(src/evaluator)\nendif()\n\nif(BLAZE_OUTPUT)\n  add_subdirectory(src/output)\nendif()\n\nif(BLAZE_TEST)\n  add_subdirectory(src/test)\nendif()\n\nif(BLAZE_CONFIGURATION)\n  add_subdirectory(src/configuration)\nendif()\n\nif(BLAZE_ALTERSCHEMA)\n  add_subdirectory(src/alterschema)\nendif()\n\nif(BLAZE_CODEGEN)\n  add_subdirectory(src/codegen)\nendif()\n\nif(BLAZE_DOCUMENTATION)\n  add_subdirectory(src/documentation)\nendif()\n\nif(BLAZE_CONTRIB)\n  add_subdirectory(contrib)\nendif()\n\nif(BLAZE_ADDRESS_SANITIZER)\n  sourcemeta_sanitizer(TYPE address)\nelseif(BLAZE_UNDEFINED_SANITIZER)\n  sourcemeta_sanitizer(TYPE undefined)\nendif()\n\nif(BLAZE_DOCS)\n  sourcemeta_target_doxygen(CONFIG \"${PROJECT_SOURCE_DIR}/doxygen/Doxyfile.in\"\n    OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/website\")\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_target_clang_format(SOURCES\n    contrib/*.cc\n    src/*.h src/*.cc\n    benchmark/*.h benchmark/*.cc\n    test/*.h test/*.cc)\n\n  find_package(Python3 COMPONENTS Interpreter)\n  if(Python3_FOUND)\n    add_custom_target(blaze_format_trace_json\n      COMMAND \"${Python3_EXECUTABLE}\"\n        \"${PROJECT_SOURCE_DIR}/contrib/format_trace_json.py\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_draft3.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_draft4.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_draft6.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_draft7.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_2019_09.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_2020_12.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_openapi_3_1.json\"\n        \"${PROJECT_SOURCE_DIR}/test/evaluator/evaluator_openapi_3_2.json\"\n        \"${PROJECT_SOURCE_DIR}/test/output/output_standard_basic.json\"\n        \"${PROJECT_SOURCE_DIR}/test/output/output_standard_flag.json\"\n      COMMENT \"Formatting trace JSON test files\"\n      VERBATIM)\n  endif()\nendif()\n\n# Testing\nif(BLAZE_TESTS)\n  enable_testing()\n\n  if(BLAZE_COMPILER)\n    add_subdirectory(test/compiler)\n  endif()\n\n  if(BLAZE_EVALUATOR)\n    add_subdirectory(test/evaluator)\n  endif()\n\n  if(BLAZE_OUTPUT)\n    add_subdirectory(test/output)\n  endif()\n\n  if(BLAZE_TEST)\n    add_subdirectory(test/test)\n  endif()\n\n  if(BLAZE_CONFIGURATION)\n    add_subdirectory(test/configuration)\n  endif()\n\n  if(BLAZE_ALTERSCHEMA)\n    add_subdirectory(test/alterschema)\n  endif()\n\n  if(BLAZE_CODEGEN)\n    add_subdirectory(test/codegen)\n  endif()\n\n  if(BLAZE_DOCUMENTATION)\n    add_subdirectory(test/documentation)\n  endif()\n\n  if(PROJECT_IS_TOP_LEVEL)\n    # Otherwise we need the child project to link\n    # against the sanitizers too.\n    if(NOT BLAZE_ADDRESS_SANITIZER AND NOT BLAZE_UNDEFINED_SANITIZER)\n      add_subdirectory(test/packaging)\n    endif()\n  endif()\n\n  if(BLAZE_BENCHMARK)\n    add_subdirectory(benchmark)\n  endif()\nendif()\n"
  },
  {
    "path": "vendor/blaze/DEPENDENCIES",
    "content": "vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02\ncore https://github.com/sourcemeta/core aa314809fdb59ed6fcb1b10b3087f32eebf708c5\njsonschema-test-suite https://github.com/json-schema-org/JSON-Schema-Test-Suite c7257e92580678a086f0b9243a1903ed88bd27f7\n"
  },
  {
    "path": "vendor/blaze/LICENSE",
    "content": "This software is dual-licensed: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version. For the terms of this license, see\n<http://www.gnu.org/licenses/>.\n\nYou are free to use this software under the terms of the GNU Affero General\nPublic License WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nAlternatively, you can use this software under a commercial license, as set out\nin <https://www.sourcemeta.com/licensing/>.\n"
  },
  {
    "path": "vendor/blaze/config.cmake.in",
    "content": "@PACKAGE_INIT@\n\n# Support both casing styles\nlist(APPEND BLAZE_COMPONENTS ${Blaze_FIND_COMPONENTS})\nlist(APPEND BLAZE_COMPONENTS ${blaze_FIND_COMPONENTS})\nif(NOT BLAZE_COMPONENTS)\n  list(APPEND BLAZE_COMPONENTS compiler)\n  list(APPEND BLAZE_COMPONENTS evaluator)\n  list(APPEND BLAZE_COMPONENTS output)\n  list(APPEND BLAZE_COMPONENTS test)\n  list(APPEND BLAZE_COMPONENTS configuration)\n  list(APPEND BLAZE_COMPONENTS alterschema)\n  list(APPEND BLAZE_COMPONENTS codegen)\n  list(APPEND BLAZE_COMPONENTS documentation)\nendif()\n\ninclude(CMakeFindDependencyMacro)\nfind_dependency(Core COMPONENTS regex uri json jsonpointer jsonschema io yaml crypto html)\n\nforeach(component ${BLAZE_COMPONENTS})\n  if(component STREQUAL \"compiler\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_compiler.cmake\")\n  elseif(component STREQUAL \"evaluator\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n  elseif(component STREQUAL \"test\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_compiler.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_test.cmake\")\n  elseif(component STREQUAL \"output\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_output.cmake\")\n  elseif(component STREQUAL \"configuration\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_configuration.cmake\")\n  elseif(component STREQUAL \"alterschema\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_compiler.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_output.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_alterschema.cmake\")\n  elseif(component STREQUAL \"codegen\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_compiler.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_output.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_alterschema.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_codegen.cmake\")\n  elseif(component STREQUAL \"documentation\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_documentation.cmake\")\n  else()\n    message(FATAL_ERROR \"Unknown Blaze component: ${component}\")\n  endif()\nendforeach()\n\ncheck_required_components(\"@PROJECT_NAME@\")\n"
  },
  {
    "path": "vendor/blaze/package.json",
    "content": "{\n  \"name\": \"@sourcemeta/blaze\",\n  \"version\": \"0.0.1\",\n  \"private\": true,\n  \"devDependencies\": {\n    \"typescript\": \"^5.9.3\"\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/patches/jsonschema-test-suite/0001-draft3-ref-sibling.patch",
    "content": "From 95fec2442e66b3de6651972e5f7d4635ca6f7ff9 Mon Sep 17 00:00:00 2001\nFrom: Juan Cruz Viotti <jv@jviotti.com>\nDate: Tue, 5 May 2026 09:15:10 -0400\nSubject: [PATCH] Do not use `definitions` sibling to `$ref` in `ref.json` for\n Draft 3\n\nI'm extending Blaze to support Draft 3. As per the spec (applies to all drafts up to 7), a `$ref` overrides any sibling keyword. This seems to be the only case in the test suite where we do this.\n---\n tests/draft3/ref.json | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/tests/draft3/ref.json b/tests/draft3/ref.json\nindex 609eaa46..6686c78e 100644\n--- a/tests/draft3/ref.json\n+++ b/tests/draft3/ref.json\n@@ -127,7 +127,9 @@\n                 \"b\": {\"$ref\": \"#/definitions/a\"},\n                 \"c\": {\"$ref\": \"#/definitions/b\"}\n             },\n-            \"$ref\": \"#/definitions/c\"\n+            \"extends\": {\n+                \"$ref\": \"#/definitions/c\"\n+            }\n         },\n         \"tests\": [\n             {\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/LICENSE",
    "content": "                   GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n  This version of the GNU Lesser General Public License incorporates\nthe terms and conditions of version 3 of the GNU General Public\nLicense, supplemented by the additional permissions listed below.\n\n  0. Additional Definitions.\n\n  As used herein, \"this License\" refers to version 3 of the GNU Lesser\nGeneral Public License, and the \"GNU GPL\" refers to version 3 of the GNU\nGeneral Public License.\n\n  \"The Library\" refers to a covered work governed by this License,\nother than an Application or a Combined Work as defined below.\n\n  An \"Application\" is any work that makes use of an interface provided\nby the Library, but which is not otherwise based on the Library.\nDefining a subclass of a class defined by the Library is deemed a mode\nof using an interface provided by the Library.\n\n  A \"Combined Work\" is a work produced by combining or linking an\nApplication with the Library.  The particular version of the Library\nwith which the Combined Work was made is also called the \"Linked\nVersion\".\n\n  The \"Minimal Corresponding Source\" for a Combined Work means the\nCorresponding Source for the Combined Work, excluding any source code\nfor portions of the Combined Work that, considered in isolation, are\nbased on the Application, and not on the Linked Version.\n\n  The \"Corresponding Application Code\" for a Combined Work means the\nobject code and/or source code for the Application, including any data\nand utility programs needed for reproducing the Combined Work from the\nApplication, but excluding the System Libraries of the Combined Work.\n\n  1. Exception to Section 3 of the GNU GPL.\n\n  You may convey a covered work under sections 3 and 4 of this License\nwithout being bound by section 3 of the GNU GPL.\n\n  2. Conveying Modified Versions.\n\n  If you modify a copy of the Library, and, in your modifications, a\nfacility refers to a function or data to be supplied by an Application\nthat uses the facility (other than as an argument passed when the\nfacility is invoked), then you may convey a copy of the modified\nversion:\n\n   a) under this License, provided that you make a good faith effort to\n   ensure that, in the event an Application does not supply the\n   function or data, the facility still operates, and performs\n   whatever part of its purpose remains meaningful, or\n\n   b) under the GNU GPL, with none of the additional permissions of\n   this License applicable to that copy.\n\n  3. Object Code Incorporating Material from Library Header Files.\n\n  The object code form of an Application may incorporate material from\na header file that is part of the Library.  You may convey such object\ncode under terms of your choice, provided that, if the incorporated\nmaterial is not limited to numerical parameters, data structure\nlayouts and accessors, or small macros, inline functions and templates\n(ten or fewer lines in length), you do both of the following:\n\n   a) Give prominent notice with each copy of the object code that the\n   Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the object code with a copy of the GNU GPL and this license\n   document.\n\n  4. Combined Works.\n\n  You may convey a Combined Work under terms of your choice that,\ntaken together, effectively do not restrict modification of the\nportions of the Library contained in the Combined Work and reverse\nengineering for debugging such modifications, if you also do each of\nthe following:\n\n   a) Give prominent notice with each copy of the Combined Work that\n   the Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the Combined Work with a copy of the GNU GPL and this license\n   document.\n\n   c) For a Combined Work that displays copyright notices during\n   execution, include the copyright notice for the Library among\n   these notices, as well as a reference directing the user to the\n   copies of the GNU GPL and this license document.\n\n   d) Do one of the following:\n\n       0) Convey the Minimal Corresponding Source under the terms of this\n       License, and the Corresponding Application Code in a form\n       suitable for, and under terms that permit, the user to\n       recombine or relink the Application with a modified version of\n       the Linked Version to produce a modified Combined Work, in the\n       manner specified by section 6 of the GNU GPL for conveying\n       Corresponding Source.\n\n       1) Use a suitable shared library mechanism for linking with the\n       Library.  A suitable mechanism is one that (a) uses at run time\n       a copy of the Library already present on the user's computer\n       system, and (b) will operate properly with a modified version\n       of the Library that is interface-compatible with the Linked\n       Version.\n\n   e) Provide Installation Information, but only if you would otherwise\n   be required to provide such information under section 6 of the\n   GNU GPL, and only to the extent that such information is\n   necessary to install and execute a modified version of the\n   Combined Work produced by recombining or relinking the\n   Application with a modified version of the Linked Version. (If\n   you use option 4d0, the Installation Information must accompany\n   the Minimal Corresponding Source and Corresponding Application\n   Code. If you use option 4d1, you must provide the Installation\n   Information in the manner specified by section 6 of the GNU GPL\n   for conveying Corresponding Source.)\n\n  5. Combined Libraries.\n\n  You may place library facilities that are a work based on the\nLibrary side by side in a single library together with other library\nfacilities that are not Applications and are not covered by this\nLicense, and convey such a combined library under terms of your\nchoice, if you do both of the following:\n\n   a) Accompany the combined library with a copy of the same work based\n   on the Library, uncombined with any other library facilities,\n   conveyed under the terms of this License.\n\n   b) Give prominent notice with the combined library that part of it\n   is a work based on the Library, and explaining where to find the\n   accompanying uncombined form of the same work.\n\n  6. Revised Versions of the GNU Lesser General Public License.\n\n  The Free Software Foundation may publish revised and/or new versions\nof the GNU Lesser General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\n  Each version is given a distinguishing version number. If the\nLibrary as you received it specifies that a certain numbered version\nof the GNU Lesser General Public License \"or any later version\"\napplies to it, you have the option of following the terms and\nconditions either of that published version or of any later version\npublished by the Free Software Foundation. If the Library as you\nreceived it does not specify a version number of the GNU Lesser\nGeneral Public License, you may choose any version of the GNU Lesser\nGeneral Public License ever published by the Free Software Foundation.\n\n  If the Library as you received it specifies that a proxy can decide\nwhether future versions of the GNU Lesser General Public License shall\napply, that proxy's public statement of acceptance of any version is\npermanent authorization for you to choose that version for the\nLibrary.\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/README.md",
    "content": "# @sourcemeta/blaze\n\n[![NPM Version](https://img.shields.io/npm/v/@sourcemeta/blaze)](https://www.npmjs.com/package/@sourcemeta/blaze)\n[![NPM Downloads](https://img.shields.io/npm/dm/%40sourcemeta%2Fblaze)](https://www.npmjs.com/package/@sourcemeta/blaze)\n[![GitHub contributors](https://img.shields.io/github/contributors/sourcemeta/blaze.svg)](https://github.com/sourcemeta/blaze/graphs/contributors/)\n\nA pure JavaScript port of the evaluator from\n[Blaze](https://github.com/sourcemeta/blaze), a high-performance\nC++ JSON Schema validator. Zero dependencies. Supports Draft 4,\nDraft 6, Draft 7, 2019-09, and 2020-12 with schema-specific code\ngeneration for near-native speed.\n\n## Install\n\n```sh\nnpm install --save @sourcemeta/blaze\n```\n\n## Usage\n\nBlaze evaluates pre-compiled schema templates. Compile your JSON Schema with\nthe [JSON Schema CLI](https://github.com/sourcemeta/jsonschema) (see the\n[`compile`](https://github.com/sourcemeta/jsonschema/blob/main/docs/compile.markdown)\ncommand), then load the resulting template and validate instances against it.\nThe mode (fast or exhaustive) is fixed at compile time, not evaluation time.\n\n```sh\nnpm install --global @sourcemeta/jsonschema\njsonschema compile schema.json --fast > template.json\n```\n\nPass a string as the second argument to `validate` to receive a JSON object\nthat follows the JSON Schema [Standard Output Format](https://json-schema.org/draft/2020-12/json-schema-core#name-output-formatting)\ninstead of a boolean. Two formats are supported:\n[`'flag'`](https://json-schema.org/draft/2020-12/json-schema-core#name-flag)\n(validity only) and\n[`'basic'`](https://json-schema.org/draft/2020-12/json-schema-core#name-basic)\n(errors and annotations):\n\n```javascript\nimport { readFileSync } from \"node:fs\";\nimport { Blaze } from \"@sourcemeta/blaze\";\n\nconst template =\n  JSON.parse(readFileSync(\"template.json\", \"utf-8\"));\nconst evaluator = new Blaze(template);\nconst instance = { name: \"John\", age: 30 };\n\n// Plain boolean\nevaluator.validate(instance);\n\n// { valid: true } or { valid: false }\nevaluator.validate(instance, \"flag\");\n\n// { valid: true, annotations?: [ ... ] }\n// { valid: false, errors: [ ... ] }\nevaluator.validate(instance, \"basic\");\n```\n\nFor lower-level integration, `validate` also accepts a callback that fires for\nevery instruction with `(type, valid, instruction, evaluatePath,\ninstanceLocation, annotation)`. The exported `describe(valid, instruction,\nevaluatePath, instanceLocation, instance, annotation)` helper turns any such\nevent into a human-readable message.\n\n### Parsing large integers\n\nJavaScript's\n[`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)\nsilently truncates integers that exceed\n[`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)\nto IEEE 754 double-precision floats. If your schemas or instances contain large\nintegers, pass `Blaze.reviver` to `JSON.parse` to preserve them as\n[`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)\nvalues. This relies on the\n[`JSON.parse` source text\naccess](https://github.com/tc39/proposal-json-parse-with-source) proposal\n(Stage 4, shipped in all major engines):\n\n```javascript\nconst template =\n  JSON.parse(readFileSync(\"template.json\", \"utf-8\"), Blaze.reviver);\nconst evaluator = new Blaze(template);\n\nconst instance =\n  JSON.parse(readFileSync(\"instance.json\", \"utf-8\"), Blaze.reviver);\nconsole.log(evaluator.validate(instance));\n```\n\nThe evaluator handles `BigInt` values natively in all numeric instructions.\nWithout a reviver, large integers are silently truncated and validation may\nproduce incorrect results for affected values.\n\n## Why compile separately?\n\nUnlike validators that compile and evaluate in a single step, Blaze separates\nthe two. You compile your schemas ahead of time using the [JSON Schema\nCLI](https://github.com/sourcemeta/jsonschema) (`jsonschema compile\nschema.json`) on CI or at build time.\n\nThe compilation step analyses the schema, resolves all references, and produces\na set of optimised low-level instructions serialised as JSON that every\nevaluator can rely on. This evaluator package then executes those instructions\nagainst your data, with no knowledge of JSON Schema itself.\n\n- **Consistent validation across languages.** The same compiled schema produces\n  identical results whether evaluated in JavaScript, Python, Java, or C++ (we\n  are working hard increase the number of ports) so you never have to rely on\n  multiple implementations with different interpretations of the standard\n\n- **No schema processing at startup.** The evaluator loads pre-compiled\n  instructions. There is no reference resolution, or vocabulary processing at\n  runtime\n\n- **Schema governance.** Compiled schemas can be managed, versioned, and\n  distributed centrally via [Sourcemeta One](https://one.sourcemeta.com),\n  ensuring all consumers validate against the same compiled artifact\n\n## Limitations\n\n**No arbitrary-precision real number support.** Large integers can be preserved\nas `BigInt` using a reviver (see above), but JavaScript has no equivalent type\nfor arbitrary-precision real numbers. `JSON.parse` truncates values like\n`0.1000000000000000000000000000000001` to IEEE 754 doubles, and there is no\nreviver-based workaround:\n\n```\n$ node --eval \"console.log(JSON.parse('0.1000000000000000000000000000000001'))\"\n0.1\n```\n\nNumeric keywords like `multipleOf` that depend on exact decimal arithmetic may\nproduce incorrect results for real values that lose precision during parsing.\nThe TC39 [Decimal proposal](https://github.com/tc39/proposal-decimal) (Stage 2)\naims to address this in the future.\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/describe.mjs",
    "content": "import {\n  ASSERTION_FAIL, ASSERTION_DEFINES, ASSERTION_DEFINES_STRICT,\n  ASSERTION_DEFINES_ALL, ASSERTION_DEFINES_ALL_STRICT,\n  ASSERTION_DEFINES_EXACTLY, ASSERTION_DEFINES_EXACTLY_STRICT,\n  ASSERTION_DEFINES_EXACTLY_STRICT_HASH3, ASSERTION_PROPERTY_DEPENDENCIES,\n  ASSERTION_TYPE, ASSERTION_TYPE_ANY, ASSERTION_TYPE_STRICT,\n  ASSERTION_TYPE_STRICT_ANY, ASSERTION_NOT_TYPE_STRICT_ANY,\n  ASSERTION_TYPE_STRING_BOUNDED,\n  ASSERTION_TYPE_STRING_UPPER, ASSERTION_TYPE_ARRAY_BOUNDED,\n  ASSERTION_TYPE_ARRAY_UPPER, ASSERTION_TYPE_OBJECT_BOUNDED,\n  ASSERTION_TYPE_OBJECT_UPPER, ASSERTION_REGEX,\n  ASSERTION_STRING_SIZE_LESS, ASSERTION_STRING_SIZE_GREATER,\n  ASSERTION_ARRAY_SIZE_LESS, ASSERTION_ARRAY_SIZE_GREATER,\n  ASSERTION_OBJECT_SIZE_LESS, ASSERTION_OBJECT_SIZE_GREATER,\n  ASSERTION_EQUAL, ASSERTION_EQUALS_ANY, ASSERTION_EQUALS_ANY_STRING_HASH,\n  ASSERTION_GREATER_EQUAL, ASSERTION_LESS_EQUAL,\n  ASSERTION_GREATER, ASSERTION_LESS,\n  ASSERTION_UNIQUE, ASSERTION_DIVISIBLE,\n  ASSERTION_TYPE_INTEGER_BOUNDED, ASSERTION_TYPE_INTEGER_BOUNDED_STRICT,\n  ASSERTION_TYPE_INTEGER_LOWER_BOUND, ASSERTION_TYPE_INTEGER_LOWER_BOUND_STRICT,\n  ASSERTION_STRING_TYPE,\n  ASSERTION_PROPERTY_TYPE, ASSERTION_PROPERTY_TYPE_EVALUATE,\n  ASSERTION_PROPERTY_TYPE_STRICT, ASSERTION_PROPERTY_TYPE_STRICT_EVALUATE,\n  ASSERTION_PROPERTY_TYPE_STRICT_ANY, ASSERTION_PROPERTY_TYPE_STRICT_ANY_EVALUATE,\n  ASSERTION_ARRAY_PREFIX, ASSERTION_ARRAY_PREFIX_EVALUATE,\n  ASSERTION_OBJECT_PROPERTIES_SIMPLE,\n  ANNOTATION_EMIT, ANNOTATION_TO_PARENT, ANNOTATION_BASENAME_TO_PARENT,\n  EVALUATE,\n  LOGICAL_NOT, LOGICAL_NOT_EVALUATE,\n  LOGICAL_OR, LOGICAL_AND, LOGICAL_XOR, LOGICAL_CONDITION,\n  LOGICAL_WHEN_TYPE, LOGICAL_WHEN_DEFINES, LOGICAL_WHEN_ARRAY_SIZE_GREATER,\n  LOOP_PROPERTIES_UNEVALUATED, LOOP_PROPERTIES_UNEVALUATED_EXCEPT,\n  LOOP_PROPERTIES_MATCH, LOOP_PROPERTIES_MATCH_CLOSED,\n  LOOP_PROPERTIES, LOOP_PROPERTIES_EVALUATE,\n  LOOP_PROPERTIES_REGEX, LOOP_PROPERTIES_REGEX_CLOSED,\n  LOOP_PROPERTIES_STARTS_WITH, LOOP_PROPERTIES_EXCEPT,\n  LOOP_PROPERTIES_TYPE, LOOP_PROPERTIES_TYPE_EVALUATE,\n  LOOP_PROPERTIES_EXACTLY_TYPE_STRICT, LOOP_PROPERTIES_EXACTLY_TYPE_STRICT_HASH,\n  LOOP_PROPERTIES_TYPE_STRICT, LOOP_PROPERTIES_TYPE_STRICT_EVALUATE,\n  LOOP_PROPERTIES_TYPE_STRICT_ANY, LOOP_PROPERTIES_TYPE_STRICT_ANY_EVALUATE,\n  LOOP_KEYS, LOOP_ITEMS, LOOP_ITEMS_FROM, LOOP_ITEMS_UNEVALUATED,\n  LOOP_ITEMS_TYPE, LOOP_ITEMS_TYPE_STRICT, LOOP_ITEMS_TYPE_STRICT_ANY,\n  LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH,\n  LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH3,\n  LOOP_ITEMS_INTEGER_BOUNDED, LOOP_ITEMS_INTEGER_BOUNDED_SIZED,\n  LOOP_CONTAINS,\n  CONTROL_DYNAMIC_ANCHOR_JUMP, CONTROL_JUMP\n} from './opcodes.mjs';\n\nconst TYPE_INTEGER = 2;\nconst TYPE_REAL = 3;\nconst TYPE_OBJECT = 6;\nconst TYPE_DECIMAL = 7;\n\nconst TYPE_NAMES = [ 'null', 'boolean', 'integer', 'number',\n                     'string', 'array', 'object', 'number' ];\n\nfunction typeName(typeIndex) {\n  return TYPE_NAMES[typeIndex];\n}\n\nfunction jsonTypeOf(value) {\n  if (value === null) return 0;\n  switch (typeof value) {\n    case 'boolean': return 1;\n    case 'number': return Number.isInteger(value) ? 2 : 3;\n    case 'bigint': return 2;\n    case 'string': return 4;\n    case 'object': return Array.isArray(value) ? 5 : 6;\n    default: return 0;\n  }\n}\n\nfunction valueTypeName(value) {\n  if (typeof value === 'bigint') return 'integer';\n  if (typeof value === 'number') {\n    return Number.isInteger(value) ? 'integer' : 'number';\n  }\n  return typeName(jsonTypeOf(value));\n}\n\nfunction escapeString(input) {\n  return '\"' + String(input).replaceAll('\"', '\\\\\"') + '\"';\n}\n\nfunction stringifyValue(value) {\n  if (typeof value === 'bigint') return String(value);\n  return JSON.stringify(value, (key, current) =>\n    typeof current === 'bigint' ? JSON.rawJSON(String(current)) : current);\n}\n\nfunction resolveTarget(instance, instanceLocation) {\n  if (instanceLocation === '') return instance;\n  const tokens = instanceLocation.slice(1).split('/');\n  let current = instance;\n  for (const raw of tokens) {\n    const token = raw.replaceAll('~1', '/').replaceAll('~0', '~');\n    if (Array.isArray(current)) {\n      current = current[Number(token)];\n    } else {\n      current = current[token];\n    }\n  }\n  return current;\n}\n\nfunction extractKeyword(evaluatePath) {\n  if (evaluatePath === '') return '';\n  const lastSlash = evaluatePath.lastIndexOf('/');\n  if (lastSlash === -1) return '';\n  const token = evaluatePath.slice(lastSlash + 1)\n    .replaceAll('~1', '/').replaceAll('~0', '~');\n  if (/^[0-9]+$/.test(token)) return '';\n  return token;\n}\n\nfunction isWithinKeyword(evaluatePath, keyword) {\n  const segments = evaluatePath.split('/');\n  for (let index = 1; index < segments.length; index++) {\n    if (segments[index].replaceAll('~1', '/').replaceAll('~0', '~') === keyword) {\n      return true;\n    }\n  }\n  return false;\n}\n\nfunction lastInstanceToken(instanceLocation) {\n  if (instanceLocation === '') return null;\n  const lastSlash = instanceLocation.lastIndexOf('/');\n  return instanceLocation.slice(lastSlash + 1)\n    .replaceAll('~1', '/').replaceAll('~0', '~');\n}\n\nfunction objectSize(value) {\n  let count = 0;\n  for (const _key in value) count++;\n  return count;\n}\n\nfunction objectKeys(value) {\n  const keys = [];\n  for (const key in value) keys.push(key);\n  return keys;\n}\n\nfunction unicodeLength(string) {\n  let count = 0;\n  for (let index = 0; index < string.length; index++) {\n    count++;\n    const code = string.charCodeAt(index);\n    if (code >= 0xD800 && code <= 0xDBFF) index++;\n  }\n  return count;\n}\n\nfunction isObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction jsonEqual(left, right) {\n  if (left === right) return true;\n  if (left === null || right === null) return left === right;\n  if (typeof left !== typeof right) return false;\n  if (typeof left !== 'object') return left === right;\n  if (Array.isArray(left) !== Array.isArray(right)) return false;\n  if (Array.isArray(left)) {\n    if (left.length !== right.length) return false;\n    for (let index = 0; index < left.length; index++) {\n      if (!jsonEqual(left[index], right[index])) return false;\n    }\n    return true;\n  }\n  const leftKeys = Object.keys(left).sort();\n  const rightKeys = Object.keys(right).sort();\n  if (leftKeys.length !== rightKeys.length) return false;\n  for (let index = 0; index < leftKeys.length; index++) {\n    if (leftKeys[index] !== rightKeys[index]) return false;\n    if (!jsonEqual(left[leftKeys[index]], right[rightKeys[index]])) return false;\n  }\n  return true;\n}\n\nfunction jsonCompare(left, right) {\n  const leftType = jsonTypeOf(left);\n  const rightType = jsonTypeOf(right);\n  if (leftType !== rightType) return leftType - rightType;\n  if (left === null) return 0;\n  if (typeof left === 'boolean') return (left ? 1 : 0) - (right ? 1 : 0);\n  if (typeof left === 'number' || typeof left === 'bigint') {\n    if (left < right) return -1;\n    if (left > right) return 1;\n    return 0;\n  }\n  if (typeof left === 'string') return left < right ? -1 : left > right ? 1 : 0;\n  const leftStr = JSON.stringify(left);\n  const rightStr = JSON.stringify(right);\n  return leftStr < rightStr ? -1 : leftStr > rightStr ? 1 : 0;\n}\n\nfunction normalizeTypes(bitmask) {\n  let types = bitmask;\n  const hasReal = (types & (1 << TYPE_REAL)) !== 0;\n  const hasInteger = (types & (1 << TYPE_INTEGER)) !== 0;\n  const hasDecimal = (types & (1 << 7)) !== 0;\n  if (hasReal && hasInteger) types &= ~(1 << TYPE_INTEGER);\n  if (hasReal && hasDecimal) types &= ~(1 << 7);\n  if (hasInteger && hasDecimal) types &= ~(1 << 7);\n  return types;\n}\n\nfunction describeTypeCheck(valid, currentType, expectedType) {\n  let message = 'The value was expected to be of type ' + typeName(expectedType);\n  if (!valid) {\n    message += ' but it was of type ' + typeName(currentType);\n  }\n  return message;\n}\n\nfunction describeNotTypeCheck(valid, currentType, expectedType) {\n  let message = 'The value was expected to NOT be of type ' + typeName(expectedType);\n  if (!valid) {\n    message += ' but it was of type ';\n    if (currentType === TYPE_DECIMAL && expectedType === TYPE_INTEGER) {\n      message += 'integer';\n    } else if ((currentType === TYPE_INTEGER && expectedType === TYPE_REAL) ||\n               currentType === TYPE_DECIMAL) {\n      message += 'number';\n    } else {\n      message += typeName(currentType);\n    }\n  }\n  return message;\n}\n\nfunction describeTypesCheck(valid, currentType, bitmask) {\n  let types = normalizeTypes(bitmask);\n  const hasReal = (bitmask & (1 << TYPE_REAL)) !== 0;\n  const hasInteger = (bitmask & (1 << TYPE_INTEGER)) !== 0;\n\n  let popcount = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) popcount++;\n  }\n\n  if (popcount === 1) {\n    let typeIndex = 0;\n    for (let bit = 0; bit < 8; bit++) {\n      if ((types & (1 << bit)) !== 0) { typeIndex = bit; break; }\n    }\n    return describeTypeCheck(valid, currentType, typeIndex);\n  }\n\n  let message = 'The value was expected to be of type ';\n  let first = true;\n  let lastBit = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) lastBit = bit;\n  }\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) {\n      if (!first) message += ', ';\n      if (bit === lastBit) message += 'or ';\n      message += typeName(bit);\n      first = false;\n    }\n  }\n\n  if (valid) {\n    message += ' and it was of type ';\n  } else {\n    message += ' but it was of type ';\n  }\n\n  if (valid && currentType === TYPE_INTEGER && hasReal) {\n    message += 'number';\n  } else if ((valid && currentType === TYPE_INTEGER && hasReal) ||\n             currentType === TYPE_REAL) {\n    message += 'number';\n  } else {\n    message += typeName(currentType);\n  }\n\n  return message;\n}\n\nfunction describeNotTypesCheck(valid, currentType, bitmask) {\n  let types = normalizeTypes(bitmask);\n  const hasReal = (bitmask & (1 << TYPE_REAL)) !== 0;\n  const hasInteger = (bitmask & (1 << TYPE_INTEGER)) !== 0;\n\n  let popcount = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) popcount++;\n  }\n\n  if (popcount === 1) {\n    let typeIndex = 0;\n    for (let bit = 0; bit < 8; bit++) {\n      if ((types & (1 << bit)) !== 0) { typeIndex = bit; break; }\n    }\n    return describeNotTypeCheck(valid, currentType, typeIndex);\n  }\n\n  let message = 'The value was expected to NOT be of type ';\n  let first = true;\n  let lastBit = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) lastBit = bit;\n  }\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) {\n      if (!first) message += ', ';\n      if (bit === lastBit) message += 'or ';\n      message += typeName(bit);\n      first = false;\n    }\n  }\n\n  if (valid) {\n    message += ' and it was of type ';\n  } else {\n    message += ' but it was of type ';\n  }\n\n  if (!valid && currentType === TYPE_INTEGER && hasReal) {\n    message += 'number';\n  } else if ((!valid && currentType === TYPE_INTEGER && hasReal) ||\n             currentType === TYPE_REAL) {\n    message += 'number';\n  } else {\n    message += typeName(currentType);\n  }\n\n  return message;\n}\n\nfunction describeReference(target) {\n  return 'The ' + typeName(jsonTypeOf(target)) +\n    ' value was expected to validate against the referenced schema';\n}\n\nfunction describeTypeList(bitmask) {\n  let types = normalizeTypes(bitmask);\n\n  let popcount = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) popcount++;\n  }\n\n  if (popcount === 1) {\n    for (let bit = 0; bit < 8; bit++) {\n      if ((types & (1 << bit)) !== 0) return typeName(bit);\n    }\n  }\n\n  let result = '';\n  let first = true;\n  let lastBit = 0;\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) lastBit = bit;\n  }\n  for (let bit = 0; bit < 8; bit++) {\n    if ((types & (1 << bit)) !== 0) {\n      if (!first) result += ', ';\n      if (bit === lastBit) result += 'or ';\n      result += typeName(bit);\n      first = false;\n    }\n  }\n  return result;\n}\n\nfunction formatList(items, conjunction) {\n  let result = '';\n  for (let index = 0; index < items.length; index++) {\n    if (index === items.length - 1) {\n      result += conjunction + ' ' + items[index];\n    } else {\n      result += items[index] + ', ';\n    }\n  }\n  return result;\n}\n\nexport function describe(valid, instruction, evaluatePath,\n                         instanceLocation, instance, annotation) {\n  const opcode = instruction[0];\n  const value = instruction[5];\n  const children = instruction[6];\n  const keyword = extractKeyword(evaluatePath);\n  const target = resolveTarget(instance, instanceLocation);\n  const targetType = jsonTypeOf(target);\n\n  if (opcode === ASSERTION_FAIL) {\n    if (keyword === 'enum') {\n      return 'The ' + typeName(targetType) +\n        ' value was not expected to validate against the empty enumeration';\n    }\n    if (keyword === 'contains') {\n      return 'The constraints declared for this keyword were not satisfiable';\n    }\n    if (keyword === 'additionalProperties' ||\n        keyword === 'unevaluatedProperties') {\n      const property = lastInstanceToken(instanceLocation);\n      return 'The object value was not expected to define the property ' +\n        escapeString(property);\n    }\n    if (keyword === 'unevaluatedItems') {\n      const tokenValue = lastInstanceToken(instanceLocation);\n      return 'The array value was not expected to define the item at index ' +\n        tokenValue;\n    }\n    return 'No instance is expected to succeed against the false schema';\n  }\n\n  if (opcode === LOGICAL_OR) {\n    const childCount = children ? children.length : 0;\n    let message = 'The ' + typeName(targetType) +\n      ' value was expected to validate against ';\n    if (childCount > 1) {\n      message += 'at least one of the ' + childCount + ' given subschemas';\n    } else {\n      message += 'the given subschema';\n    }\n    return message;\n  }\n\n  if (opcode === LOGICAL_AND) {\n    if (keyword === 'allOf' || keyword === 'extends') {\n      const childCount = children ? children.length : 0;\n      let message = 'The ' + typeName(targetType) +\n        ' value was expected to validate against the ';\n      if (childCount > 1) {\n        message += childCount + ' given subschemas';\n      } else {\n        message += 'given subschema';\n      }\n      return message;\n    }\n    if (keyword === '$ref') {\n      return describeReference(target);\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === LOGICAL_XOR) {\n    const childCount = children ? children.length : 0;\n    let message = '';\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '' && lastInstanceToken(instanceLocation) !== null) {\n      const propertyName = lastInstanceToken(instanceLocation);\n      message += 'The property name ' + escapeString(propertyName);\n    } else {\n      message += 'The ' + typeName(targetType) + ' value';\n    }\n    message += ' was expected to validate against ';\n    if (childCount > 1) {\n      message += 'one and only one of the ' + childCount + ' given subschemas';\n    } else {\n      message += 'the given subschema';\n    }\n    return message;\n  }\n\n  if (opcode === LOGICAL_CONDITION) {\n    return 'The ' + typeName(targetType) +\n      ' value was expected to validate against the given conditional';\n  }\n\n  if (opcode === LOGICAL_NOT) {\n    let message = 'The ' + typeName(targetType) +\n      ' value was expected to not validate against the given subschema';\n    if (!valid) message += ', but it did';\n    return message;\n  }\n\n  if (opcode === LOGICAL_NOT_EVALUATE) {\n    let message = 'The ' + typeName(targetType) +\n      ' value was expected to not validate against the given subschema';\n    if (!valid) message += ', but it did';\n    return message;\n  }\n\n  if (opcode === EVALUATE) {\n    return 'The instance location was marked as evaluated';\n  }\n\n  if (opcode === CONTROL_DYNAMIC_ANCHOR_JUMP) {\n    if (keyword === '$dynamicRef') {\n      return 'The ' + typeName(targetType) +\n        ' value was expected to validate against the first subschema ' +\n        'in scope that declared the dynamic anchor ' + escapeString(value);\n    }\n    return 'The ' + typeName(targetType) +\n      ' value was expected to validate against the first subschema ' +\n      'in scope that declared a recursive anchor';\n  }\n\n  if (opcode === ANNOTATION_EMIT) {\n    if (keyword === 'properties') {\n      return 'The object property ' + escapeString(annotation) +\n        ' successfully validated against its property subschema';\n    }\n\n    if ((keyword === 'items' || keyword === 'additionalItems') &&\n        annotation === true) {\n      return 'Every item in the array value was successfully validated';\n    }\n\n    if ((keyword === 'prefixItems' || keyword === 'items') &&\n        typeof annotation === 'number') {\n      if (annotation === 0) {\n        return 'The first item of the array value successfully validated ' +\n          'against the first positional subschema';\n      }\n      return 'The first ' + (annotation + 1) +\n        ' items of the array value successfully validated against the given ' +\n        'positional subschemas';\n    }\n\n    if (keyword === 'prefixItems' && annotation === true) {\n      return 'Every item of the array value validated against the given ' +\n        'positional subschemas';\n    }\n\n    if (keyword === 'title' || keyword === 'description') {\n      let message = 'The ' + keyword + ' of the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was ' + escapeString(annotation);\n      return message;\n    }\n\n    if (keyword === 'default') {\n      let message = 'The default value of the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was ' + stringifyValue(annotation);\n      return message;\n    }\n\n    if (keyword === 'deprecated' && typeof annotation === 'boolean') {\n      let message = '';\n      if (instanceLocation === '') {\n        message += 'The instance';\n      } else {\n        message += 'The instance location \"' + instanceLocation + '\"';\n      }\n      message += annotation\n        ? ' was considered deprecated'\n        : ' was not considered deprecated';\n      return message;\n    }\n\n    if (keyword === 'readOnly' && typeof annotation === 'boolean') {\n      let message = '';\n      if (instanceLocation === '') {\n        message += 'The instance';\n      } else {\n        message += 'The instance location \"' + instanceLocation + '\"';\n      }\n      message += annotation\n        ? ' was considered read-only'\n        : ' was not considered read-only';\n      return message;\n    }\n\n    if (keyword === 'writeOnly' && typeof annotation === 'boolean') {\n      let message = '';\n      if (instanceLocation === '') {\n        message += 'The instance';\n      } else {\n        message += 'The instance location \"' + instanceLocation + '\"';\n      }\n      message += annotation\n        ? ' was considered write-only'\n        : ' was not considered write-only';\n      return message;\n    }\n\n    if (keyword === 'examples') {\n      let message = '';\n      if (instanceLocation === '') {\n        message += 'Examples of the instance';\n      } else {\n        message += 'Examples of the instance location \"' +\n          instanceLocation + '\"';\n      }\n      message += ' were ';\n      for (let index = 0; index < annotation.length; index++) {\n        if (index === annotation.length - 1) {\n          message += 'and ' + stringifyValue(annotation[index]);\n        } else {\n          message += stringifyValue(annotation[index]) + ', ';\n        }\n      }\n      return message;\n    }\n\n    if (keyword === 'contentEncoding') {\n      let message = 'The content encoding of the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was ' + escapeString(annotation);\n      return message;\n    }\n\n    if (keyword === 'contentMediaType') {\n      let message = 'The content media type of the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was ' + escapeString(annotation);\n      return message;\n    }\n\n    if (keyword === 'contentSchema') {\n      let message = 'When decoded, the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was expected to validate against the schema ' +\n        stringifyValue(annotation);\n      return message;\n    }\n\n    if (keyword === 'format') {\n      let message = 'The logical type of the';\n      if (instanceLocation === '') {\n        message += ' instance';\n      } else {\n        message += ' instance location \"' + instanceLocation + '\"';\n      }\n      message += ' was expected to be ' + stringifyValue(annotation);\n      return message;\n    }\n\n    return 'The unrecognized keyword ' + escapeString(keyword) +\n      ' was collected as the annotation ' + stringifyValue(annotation);\n  }\n\n  if (opcode === ANNOTATION_TO_PARENT) {\n    if (keyword === 'unevaluatedItems' && annotation === true) {\n      return 'At least one item of the array value successfully validated ' +\n        'against the subschema for unevaluated items';\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ANNOTATION_BASENAME_TO_PARENT) {\n    if (keyword === 'patternProperties') {\n      return 'The object property ' + escapeString(String(annotation)) +\n        ' successfully validated against its pattern property subschema';\n    }\n    if (keyword === 'additionalProperties') {\n      return 'The object property ' + escapeString(String(annotation)) +\n        ' successfully validated against the additional properties subschema';\n    }\n    if (keyword === 'unevaluatedProperties') {\n      return 'The object property ' + escapeString(String(annotation)) +\n        ' successfully validated against the subschema for ' +\n        'unevaluated properties';\n    }\n    if (keyword === 'contains' && typeof annotation === 'number') {\n      return 'The item at index ' + annotation +\n        ' of the array value successfully validated against the ' +\n        'containment check subschema';\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === LOOP_PROPERTIES) {\n    const childCount = children ? children.length : 0;\n    if (childCount > 0 && children[0][0] === ASSERTION_FAIL) {\n      if (keyword === 'unevaluatedProperties') {\n        return 'The object value was not expected to define unevaluated properties';\n      }\n      return 'The object value was not expected to define additional properties';\n    }\n    if (keyword === 'unevaluatedProperties') {\n      return 'The object properties not covered by other object ' +\n        'keywords were expected to validate against this subschema';\n    }\n    return 'The object properties not covered by other adjacent object ' +\n      'keywords were expected to validate against this subschema';\n  }\n\n  if (opcode === LOOP_PROPERTIES_EVALUATE) {\n    const childCount = children ? children.length : 0;\n    if (childCount === 1 && children[0][0] === ASSERTION_FAIL) {\n      return 'The object value was not expected to define additional properties';\n    }\n    return 'The object properties not covered by other adjacent object ' +\n      'keywords were expected to validate against this subschema';\n  }\n\n  if (opcode === LOOP_PROPERTIES_UNEVALUATED) {\n    if (keyword === 'unevaluatedProperties') {\n      const childCount = children ? children.length : 0;\n      if (childCount > 0 && children[0][0] === ASSERTION_FAIL) {\n        return 'The object value was not expected to define unevaluated properties';\n      }\n      return 'The object properties not covered by other object ' +\n        'keywords were expected to validate against this subschema';\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === LOOP_PROPERTIES_UNEVALUATED_EXCEPT) {\n    if (keyword === 'unevaluatedProperties') {\n      const childCount = children ? children.length : 0;\n      if (childCount > 0 && children[0][0] === ASSERTION_FAIL) {\n        return 'The object value was not expected to define unevaluated properties';\n      }\n      return 'The object properties not covered by other object ' +\n        'keywords were expected to validate against this subschema';\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === LOOP_PROPERTIES_EXCEPT) {\n    const childCount = children ? children.length : 0;\n    if (childCount > 0 && children[0][0] === ASSERTION_FAIL) {\n      if (keyword === 'unevaluatedProperties') {\n        return 'The object value was not expected to define unevaluated properties';\n      }\n      return 'The object value was not expected to define additional properties';\n    }\n    if (keyword === 'unevaluatedProperties') {\n      return 'The object properties not covered by other object ' +\n        'keywords were expected to validate against this subschema';\n    }\n    return 'The object properties not covered by other adjacent object ' +\n      'keywords were expected to validate against this subschema';\n  }\n\n  if (opcode === LOOP_PROPERTIES_EXACTLY_TYPE_STRICT) {\n    return 'The required object properties were expected to be of type ' +\n      typeName(value[0]);\n  }\n\n  if (opcode === LOOP_PROPERTIES_EXACTLY_TYPE_STRICT_HASH) {\n    return 'The required object properties were expected to be of type ' +\n      typeName(value[0]);\n  }\n\n  if (opcode === LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH ||\n      opcode === LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH3) {\n    return 'Every item in the array was expected to be an object whose ' +\n      'required properties were of type ' + typeName(value[0]);\n  }\n\n  if (opcode === LOOP_ITEMS_INTEGER_BOUNDED ||\n      opcode === LOOP_ITEMS_INTEGER_BOUNDED_SIZED) {\n    return 'Every item in the array was expected to be a number within the given range';\n  }\n\n  if (opcode === ASSERTION_TYPE_INTEGER_BOUNDED ||\n      opcode === ASSERTION_TYPE_INTEGER_BOUNDED_STRICT) {\n    return 'The value was expected to be an integer within the given range';\n  }\n\n  if (opcode === ASSERTION_TYPE_INTEGER_LOWER_BOUND ||\n      opcode === ASSERTION_TYPE_INTEGER_LOWER_BOUND_STRICT) {\n    return 'The value was expected to be an integer above the given minimum';\n  }\n\n  if (opcode === ASSERTION_OBJECT_PROPERTIES_SIMPLE) {\n    return 'The object value was expected to validate against the defined property subschemas';\n  }\n\n  if (opcode === LOOP_PROPERTIES_TYPE ||\n      opcode === LOOP_PROPERTIES_TYPE_EVALUATE ||\n      opcode === LOOP_PROPERTIES_TYPE_STRICT ||\n      opcode === LOOP_PROPERTIES_TYPE_STRICT_EVALUATE) {\n    return 'The object properties were expected to be of type ' + typeName(value);\n  }\n\n  if (opcode === LOOP_PROPERTIES_TYPE_STRICT_ANY) {\n    return 'The object properties were expected to be of type ' +\n      describeTypeList(value);\n  }\n\n  if (opcode === LOOP_PROPERTIES_TYPE_STRICT_ANY_EVALUATE) {\n    return 'The object properties were expected to be of type ' +\n      describeTypeList(value);\n  }\n\n  if (opcode === LOOP_KEYS) {\n    const size = objectSize(target);\n    const keys = objectKeys(target);\n    if (size === 0) {\n      return 'The object is empty and no properties were expected to ' +\n        'validate against the given subschema';\n    }\n    if (size === 1) {\n      return 'The object property ' + escapeString(keys[0]) +\n        ' was expected to validate against the given subschema';\n    }\n    let message = 'The object properties ';\n    for (let index = 0; index < keys.length; index++) {\n      if (index === keys.length - 1) {\n        message += 'and ' + escapeString(keys[index]);\n      } else {\n        message += escapeString(keys[index]) + ', ';\n      }\n    }\n    message += ' were expected to validate against the given subschema';\n    return message;\n  }\n\n  if (opcode === LOOP_ITEMS) {\n    return 'Every item in the array value was expected to validate against the given subschema';\n  }\n\n  if (opcode === LOOP_ITEMS_FROM) {\n    let message = 'Every item in the array value';\n    if (value === 1) {\n      message += ' except for the first one';\n    } else if (value > 0) {\n      message += ' except for the first ' + value;\n    }\n    message += ' was expected to validate against the given subschema';\n    return message;\n  }\n\n  if (opcode === LOOP_ITEMS_UNEVALUATED) {\n    return 'The array items not covered by other array keywords, if any, ' +\n      'were expected to validate against this subschema';\n  }\n\n  if (opcode === LOOP_ITEMS_TYPE || opcode === LOOP_ITEMS_TYPE_STRICT) {\n    return 'The array items were expected to be of type ' + typeName(value);\n  }\n\n  if (opcode === LOOP_ITEMS_TYPE_STRICT_ANY) {\n    return 'The array items were expected to be of type ' + describeTypeList(value);\n  }\n\n  if (opcode === LOOP_CONTAINS) {\n    const minimum = value[0];\n    const maximum = value[1];\n    let plural = true;\n    let message = 'The array value was expected to contain ';\n    if (maximum !== null) {\n      if (minimum === maximum && minimum === 0) {\n        message += 'any number of';\n      } else if (minimum === maximum) {\n        message += 'exactly ' + minimum;\n        if (minimum === 1) plural = false;\n      } else if (minimum === 0) {\n        message += 'up to ' + maximum;\n        if (maximum === 1) plural = false;\n      } else {\n        message += minimum + ' to ' + maximum;\n        if (maximum === 1) plural = false;\n      }\n    } else {\n      message += 'at least ' + minimum;\n      if (minimum === 1) plural = false;\n    }\n    message += plural\n      ? ' items that validate against the given subschema'\n      : ' item that validates against the given subschema';\n    return message;\n  }\n\n  if (opcode === ASSERTION_DEFINES) {\n    return 'The object value was expected to define the property ' +\n      escapeString(value);\n  }\n\n  if (opcode === ASSERTION_DEFINES_STRICT) {\n    return 'The value was expected to be an object that defines the property ' +\n      escapeString(value);\n  }\n\n  if (opcode === ASSERTION_DEFINES_ALL) {\n    let message = 'The object value was expected to define properties ';\n    for (let index = 0; index < value.length; index++) {\n      if (index === value.length - 1) {\n        message += 'and ' + escapeString(value[index]);\n      } else {\n        message += escapeString(value[index]) + ', ';\n      }\n    }\n    if (valid) return message;\n\n    const missing = [];\n    for (let index = 0; index < value.length; index++) {\n      if (!Object.hasOwn(target, value[index])) {\n        missing.push(value[index]);\n      }\n    }\n    missing.sort();\n\n    if (missing.length === 1) {\n      message += ' but did not define the property ' + escapeString(missing[0]);\n    } else {\n      message += ' but did not define properties ';\n      for (let index = 0; index < missing.length; index++) {\n        if (index === missing.length - 1) {\n          message += 'and ' + escapeString(missing[index]);\n        } else {\n          message += escapeString(missing[index]) + ', ';\n        }\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_DEFINES_ALL_STRICT) {\n    let message = 'The value was expected to be an object that defines properties ';\n    for (let index = 0; index < value.length; index++) {\n      if (index === value.length - 1) {\n        message += 'and ' + escapeString(value[index]);\n      } else {\n        message += escapeString(value[index]) + ', ';\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_DEFINES_EXACTLY) {\n    const sorted = [...value].sort();\n    let message = 'The object value was expected to only define properties ';\n    for (let index = 0; index < sorted.length; index++) {\n      if (index === sorted.length - 1) {\n        message += 'and ' + escapeString(sorted[index]);\n      } else {\n        message += escapeString(sorted[index]) + ', ';\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_DEFINES_EXACTLY_STRICT) {\n    const sorted = [...value].sort();\n    let message =\n      'The value was expected to be an object that only defines properties ';\n    for (let index = 0; index < sorted.length; index++) {\n      if (index === sorted.length - 1) {\n        message += 'and ' + escapeString(sorted[index]);\n      } else {\n        message += escapeString(sorted[index]) + ', ';\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_DEFINES_EXACTLY_STRICT_HASH3) {\n    const entries = value[0];\n    return 'The value was expected to be an object that only defines the ' +\n      entries.length + ' given properties';\n  }\n\n  if (opcode === ASSERTION_TYPE || opcode === ASSERTION_TYPE_STRICT) {\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      const propertyName = lastInstanceToken(instanceLocation);\n      return 'The property name ' + escapeString(propertyName) +\n        ' was expected to be of type ' + typeName(value);\n    }\n    return describeTypeCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_TYPE_ANY) {\n    return describeTypesCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_TYPE_STRICT_ANY) {\n    return describeTypesCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_NOT_TYPE_STRICT_ANY) {\n    return describeNotTypesCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_TYPE_STRING_BOUNDED) {\n    const minimum = value[0];\n    const maximum = value[1];\n    if (minimum === 0 && maximum !== null) {\n      return 'The value was expected to consist of a string of at most ' +\n        maximum + (maximum === 1 ? ' character' : ' characters');\n    }\n    if (maximum !== null) {\n      return 'The value was expected to consist of a string of ' + minimum +\n        ' to ' + maximum + (maximum === 1 ? ' character' : ' characters');\n    }\n    return 'The value was expected to consist of a string of at least ' +\n      minimum + (minimum === 1 ? ' character' : ' characters');\n  }\n\n  if (opcode === ASSERTION_TYPE_STRING_UPPER) {\n    return 'The value was expected to consist of a string of at most ' +\n      value + (value === 1 ? ' character' : ' characters');\n  }\n\n  if (opcode === ASSERTION_TYPE_ARRAY_BOUNDED) {\n    const minimum = value[0];\n    const maximum = value[1];\n    if (minimum === 0 && maximum !== null) {\n      return 'The value was expected to consist of an array of at most ' +\n        maximum + (maximum === 1 ? ' item' : ' items');\n    }\n    if (maximum !== null) {\n      return 'The value was expected to consist of an array of ' + minimum +\n        ' to ' + maximum + (maximum === 1 ? ' item' : ' items');\n    }\n    return 'The value was expected to consist of an array of at least ' +\n      minimum + (minimum === 1 ? ' item' : ' items');\n  }\n\n  if (opcode === ASSERTION_TYPE_ARRAY_UPPER) {\n    return 'The value was expected to consist of an array of at most ' +\n      value + (value === 1 ? ' item' : ' items');\n  }\n\n  if (opcode === ASSERTION_TYPE_OBJECT_BOUNDED) {\n    const minimum = value[0];\n    const maximum = value[1];\n    if (minimum === 0 && maximum !== null) {\n      return 'The value was expected to consist of an object of at most ' +\n        maximum + (maximum === 1 ? ' property' : ' properties');\n    }\n    if (maximum !== null) {\n      return 'The value was expected to consist of an object of ' + minimum +\n        ' to ' + maximum + (maximum === 1 ? ' property' : ' properties');\n    }\n    return 'The value was expected to consist of an object of at least ' +\n      minimum + (minimum === 1 ? ' property' : ' properties');\n  }\n\n  if (opcode === ASSERTION_TYPE_OBJECT_UPPER) {\n    return 'The value was expected to consist of an object of at most ' +\n      value + (value === 1 ? ' property' : ' properties');\n  }\n\n  if (opcode === ASSERTION_REGEX) {\n    const pattern = value.source;\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      const propertyName = lastInstanceToken(instanceLocation);\n      return 'The property name ' + escapeString(propertyName) +\n        ' was expected to match the regular expression ' +\n        escapeString(pattern);\n    }\n    return 'The string value ' + escapeString(target) +\n      ' was expected to match the regular expression ' +\n      escapeString(pattern);\n  }\n\n  if (opcode === ASSERTION_STRING_SIZE_LESS) {\n    if (keyword === 'maxLength') {\n      const maximum = value - 1;\n      let message = '';\n      if (isWithinKeyword(evaluatePath, 'propertyNames')) {\n        const propertyName = lastInstanceToken(instanceLocation);\n        message += 'The object property name ' + escapeString(propertyName);\n        message += ' was expected to consist of at most ' + maximum +\n          (maximum === 1 ? ' character' : ' characters');\n        message += valid ? ' and' : ' but';\n        message += ' it consisted of ';\n        const length = unicodeLength(propertyName);\n        message += length + (length === 1 ? ' character' : ' characters');\n      } else {\n        message += 'The string value ' + stringifyValue(target);\n        message += ' was expected to consist of at most ' + maximum +\n          (maximum === 1 ? ' character' : ' characters');\n        message += valid ? ' and' : ' but';\n        message += ' it consisted of ';\n        const length = unicodeLength(target);\n        message += length + (length === 1 ? ' character' : ' characters');\n      }\n      return message;\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_STRING_SIZE_GREATER) {\n    if (keyword === 'minLength') {\n      const minimum = value + 1;\n      let message = '';\n      if (isWithinKeyword(evaluatePath, 'propertyNames')) {\n        const propertyName = lastInstanceToken(instanceLocation);\n        message += 'The object property name ' + escapeString(propertyName);\n        message += ' was expected to consist of at least ' + minimum +\n          (minimum === 1 ? ' character' : ' characters');\n        message += valid ? ' and' : ' but';\n        message += ' it consisted of ';\n        const length = unicodeLength(propertyName);\n        message += length + (length === 1 ? ' character' : ' characters');\n      } else {\n        message += 'The string value ' + stringifyValue(target);\n        message += ' was expected to consist of at least ' + minimum +\n          (minimum === 1 ? ' character' : ' characters');\n        message += valid ? ' and' : ' but';\n        message += ' it consisted of ';\n        const length = unicodeLength(target);\n        message += length + (length === 1 ? ' character' : ' characters');\n      }\n      return message;\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_ARRAY_SIZE_LESS) {\n    if (keyword === 'maxItems') {\n      const maximum = value - 1;\n      let message = 'The array value was expected to contain at most ' +\n        maximum + (maximum === 1 ? ' item' : ' items');\n      message += valid ? ' and' : ' but';\n      message += ' it contained ' + target.length +\n        (target.length === 1 ? ' item' : ' items');\n      return message;\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_ARRAY_SIZE_GREATER) {\n    const minimum = value + 1;\n    let message = 'The array value was expected to contain at least ' +\n      minimum + (minimum === 1 ? ' item' : ' items');\n    message += valid ? ' and' : ' but';\n    message += ' it contained ' + target.length +\n      (target.length === 1 ? ' item' : ' items');\n    return message;\n  }\n\n  if (opcode === ASSERTION_OBJECT_SIZE_LESS) {\n    if (keyword === 'additionalProperties') {\n      return 'The object value was not expected to define additional properties';\n    }\n    if (keyword === 'maxProperties') {\n      const maximum = value - 1;\n      const size = objectSize(target);\n      let message = 'The object value was expected to contain at most ' +\n        maximum + (maximum === 1 ? ' property' : ' properties');\n      message += valid ? ' and' : ' but';\n      message += ' it contained ' + size;\n      if (size === 0) {\n        message += ' properties';\n      } else if (size === 1) {\n        message += ' property: ' + escapeString(objectKeys(target)[0]);\n      } else {\n        message += ' properties: ';\n        const properties = objectKeys(target).sort();\n        message += formatList(properties.map(escapeString), 'and');\n      }\n      return message;\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_OBJECT_SIZE_GREATER) {\n    if (keyword === 'minProperties') {\n      const minimum = value + 1;\n      const size = objectSize(target);\n      let message = 'The object value was expected to contain at least ' +\n        minimum + (minimum === 1 ? ' property' : ' properties');\n      message += valid ? ' and' : ' but';\n      message += ' it contained ' + size;\n      if (size === 1) {\n        message += ' property: ' + escapeString(objectKeys(target)[0]);\n      } else {\n        message += ' properties: ';\n        const properties = objectKeys(target).sort();\n        message += formatList(properties.map(escapeString), 'and');\n      }\n      return message;\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_EQUAL) {\n    let message = '';\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      const propertyName = lastInstanceToken(instanceLocation);\n      message += 'The property name ' + escapeString(propertyName);\n    } else {\n      message += 'The ' + typeName(targetType) + ' value ';\n      message += stringifyValue(target);\n    }\n    message += ' was expected to equal the ' + typeName(jsonTypeOf(value)) +\n      ' constant ' + stringifyValue(value);\n    return message;\n  }\n\n  if (opcode === ASSERTION_EQUALS_ANY) {\n    let message = '';\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      const propertyName = lastInstanceToken(instanceLocation);\n      message += 'The property name ' + escapeString(propertyName);\n    } else {\n      message += 'The ' + typeName(targetType) + ' value ';\n      message += stringifyValue(target);\n    }\n\n    const values = Array.isArray(value) ? value : (value.values || []);\n    if (values.length === 1) {\n      message += ' was expected to equal the ' +\n        typeName(jsonTypeOf(values[0])) + ' constant ' +\n        stringifyValue(values[0]);\n    } else {\n      if (valid) {\n        message += ' was expected to equal one of the ' +\n          values.length + ' declared values';\n      } else {\n        message += ' was expected to equal one of the following values: ';\n        const sorted = [...values].sort(jsonCompare);\n        for (let index = 0; index < sorted.length; index++) {\n          if (index === sorted.length - 1) {\n            message += 'and ' + stringifyValue(sorted[index]);\n          } else {\n            message += stringifyValue(sorted[index]) + ', ';\n          }\n        }\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_EQUALS_ANY_STRING_HASH) {\n    let message = '';\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      const propertyName = lastInstanceToken(instanceLocation);\n      message += 'The property name ' + escapeString(propertyName);\n    } else {\n      message += 'The ' + typeName(targetType) + ' value ';\n      message += stringifyValue(target);\n    }\n    const entries = value[0];\n    if (entries.length === 1) {\n      message += ' was expected to equal the given constant';\n    } else {\n      message += ' was expected to equal one of the given declared values';\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_GREATER_EQUAL) {\n    return 'The ' + valueTypeName(target) + ' value ' +\n      stringifyValue(target) +\n      ' was expected to be greater than or equal to the ' +\n      valueTypeName(value) + ' ' + stringifyValue(value);\n  }\n\n  if (opcode === ASSERTION_LESS_EQUAL) {\n    return 'The ' + valueTypeName(target) + ' value ' +\n      stringifyValue(target) +\n      ' was expected to be less than or equal to the ' +\n      valueTypeName(value) + ' ' + stringifyValue(value);\n  }\n\n  if (opcode === ASSERTION_GREATER) {\n    let message = 'The ' + valueTypeName(target) + ' value ' +\n      stringifyValue(target) +\n      ' was expected to be greater than the ' +\n      valueTypeName(value) + ' ' + stringifyValue(value);\n    if (!valid && jsonEqual(value, target)) {\n      message += ', but they were equal';\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_LESS) {\n    let message = 'The ' + valueTypeName(target) + ' value ' +\n      stringifyValue(target) +\n      ' was expected to be less than the ' +\n      valueTypeName(value) + ' ' + stringifyValue(value);\n    if (!valid && jsonEqual(value, target)) {\n      message += ', but they were equal';\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_UNIQUE) {\n    if (valid) {\n      return 'The array value was expected to not contain duplicate items';\n    }\n    const duplicateStrs = new Set();\n    for (let index = 0; index < target.length; index++) {\n      for (let other = index + 1; other < target.length; other++) {\n        if (jsonEqual(target[index], target[other])) {\n          duplicateStrs.add(stringifyValue(target[index]));\n        }\n      }\n    }\n    const sorted = [...duplicateStrs].sort();\n    if (sorted.length === 1) {\n      return 'The array value contained the following duplicate item: ' + sorted[0];\n    }\n    let message = 'The array value contained the following duplicate items: ';\n    for (let index = 0; index < sorted.length; index++) {\n      if (index === sorted.length - 1) {\n        message += 'and ' + sorted[index];\n      } else {\n        message += sorted[index] + ', ';\n      }\n    }\n    return message;\n  }\n\n  if (opcode === ASSERTION_DIVISIBLE) {\n    return 'The ' + valueTypeName(target) + ' value ' +\n      stringifyValue(target) +\n      ' was expected to be divisible by the ' +\n      valueTypeName(value) + ' ' + stringifyValue(value);\n  }\n\n  if (opcode === ASSERTION_STRING_TYPE) {\n    return 'The string value ' + escapeString(target) +\n      ' was expected to represent a valid URI';\n  }\n\n  if (opcode === ASSERTION_PROPERTY_TYPE ||\n      opcode === ASSERTION_PROPERTY_TYPE_EVALUATE ||\n      opcode === ASSERTION_PROPERTY_TYPE_STRICT ||\n      opcode === ASSERTION_PROPERTY_TYPE_STRICT_EVALUATE) {\n    return describeTypeCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_PROPERTY_TYPE_STRICT_ANY ||\n      opcode === ASSERTION_PROPERTY_TYPE_STRICT_ANY_EVALUATE) {\n    return describeTypesCheck(valid, targetType, value);\n  }\n\n  if (opcode === ASSERTION_ARRAY_PREFIX ||\n      opcode === ASSERTION_ARRAY_PREFIX_EVALUATE) {\n    const childCount = children ? children.length : 0;\n    let message = 'The first ';\n    if (childCount <= 2) {\n      message += 'item of the array value was';\n    } else {\n      message += (childCount - 1) + ' items of the array value were';\n    }\n    message += ' expected to validate against the corresponding subschemas';\n    return message;\n  }\n\n  if (opcode === LOOP_PROPERTIES_MATCH) {\n    const childCount = children ? children.length : 0;\n    let message = 'The object value was expected to validate against the ';\n    if (childCount === 1) {\n      message += 'single defined property subschema';\n    } else {\n      message += childCount + ' defined properties subschemas';\n    }\n    return message;\n  }\n\n  if (opcode === LOOP_PROPERTIES_MATCH_CLOSED) {\n    const childCount = children ? children.length : 0;\n    if (childCount === 1) {\n      return 'The object value was expected to validate against the ' +\n        'single defined property subschema';\n    }\n    return 'Every object value was expected to validate against one of the ' +\n      childCount + ' defined properties subschemas';\n  }\n\n  if (opcode === LOGICAL_WHEN_DEFINES) {\n    return 'The object value defined the property \"' + value + '\"';\n  }\n\n  if (opcode === LOOP_PROPERTIES_REGEX) {\n    return 'The object properties that match the regular expression \"' +\n      value.source + '\" were expected to validate against the defined ' +\n      'pattern property subschema';\n  }\n\n  if (opcode === LOOP_PROPERTIES_REGEX_CLOSED) {\n    return 'The object properties were expected to match the regular ' +\n      'expression \"' + value.source + '\" and validate against the ' +\n      'defined pattern property subschema';\n  }\n\n  if (opcode === LOOP_PROPERTIES_STARTS_WITH) {\n    return 'The object properties that start with the string \"' + value +\n      '\" were expected to validate against the defined pattern property subschema';\n  }\n\n  if (opcode === LOGICAL_WHEN_TYPE) {\n    if (keyword === 'items') {\n      return describeTypeCheck(valid, targetType, value);\n    }\n\n    if (keyword === 'properties') {\n      const childCount = children ? children.length : 0;\n      if (targetType !== TYPE_OBJECT) {\n        return describeTypeCheck(valid, targetType, TYPE_OBJECT);\n      }\n      let message = 'The object value was expected to validate against the ';\n      if (childCount === 1) {\n        message += 'single defined property subschema';\n      } else {\n        message += 'defined properties subschemas';\n      }\n      return message;\n    }\n\n    if (keyword === 'dependencies') {\n      const childCount = children ? children.length : 0;\n      const present = new Set();\n      const presentWithSchemas = new Set();\n      const presentWithProperties = new Set();\n      const allDependencies = new Set();\n      const requiredProperties = new Set();\n\n      for (let index = 0; index < childCount; index++) {\n        const child = children[index];\n        if (child[0] === LOGICAL_WHEN_DEFINES) {\n          const property = child[5];\n          allDependencies.add(property);\n          if (!Object.hasOwn(target, property)) continue;\n          present.add(property);\n          presentWithSchemas.add(property);\n        } else if (child[0] === ASSERTION_PROPERTY_DEPENDENCIES) {\n          const entries = child[5];\n          for (const property in entries) {\n            allDependencies.add(property);\n            if (Object.hasOwn(target, property)) {\n              present.add(property);\n              presentWithProperties.add(property);\n              const dependencies = entries[property];\n              for (let depIndex = 0; depIndex < dependencies.length; depIndex++) {\n                if (valid || !Object.hasOwn(target, dependencies[depIndex])) {\n                  requiredProperties.add(dependencies[depIndex]);\n                }\n              }\n            }\n          }\n        }\n      }\n\n      const allDepsArr = [...allDependencies].sort();\n      const presentArr = [...present].sort();\n      const presentSchemasArr = [...presentWithSchemas].sort();\n      const requiredArr = [...requiredProperties].sort();\n\n      if (presentWithSchemas.size === 0 && presentWithProperties.size === 0) {\n        let message = 'The object value did not define the';\n        if (allDepsArr.length === 1) {\n          message += ' property ' + escapeString(allDepsArr[0]);\n        } else {\n          message += ' properties ';\n          message += formatList(allDepsArr.map(escapeString), 'or');\n        }\n        return message;\n      }\n\n      let message = '';\n      if (presentArr.length === 1) {\n        message += 'Because the object value defined the';\n        message += ' property ' + escapeString(presentArr[0]);\n      } else {\n        message += 'Because the object value defined the';\n        message += ' properties ';\n        message += formatList(presentArr.map(escapeString), 'and');\n      }\n\n      if (requiredArr.length > 0) {\n        message += ', it was also expected to define the';\n        if (requiredArr.length === 1) {\n          message += ' property ' + escapeString(requiredArr[0]);\n        } else {\n          message += ' properties ';\n          message += formatList(requiredArr.map(escapeString), 'and');\n        }\n      }\n\n      if (presentSchemasArr.length > 0) {\n        message += ', ';\n        if (requiredArr.length > 0) message += 'and ';\n        message += 'it was also expected to successfully validate against ' +\n          'the corresponding ';\n        if (presentSchemasArr.length === 1) {\n          message += escapeString(presentSchemasArr[0]) + ' subschema';\n        } else {\n          message += formatList(presentSchemasArr.map(escapeString), 'and');\n          message += ' subschemas';\n        }\n      }\n\n      return message;\n    }\n\n    if (keyword === 'dependentSchemas') {\n      const childCount = children ? children.length : 0;\n      const present = new Set();\n      const allDependencies = new Set();\n\n      for (let index = 0; index < childCount; index++) {\n        const child = children[index];\n        const property = child[5];\n        allDependencies.add(property);\n        if (Object.hasOwn(target, property)) {\n          present.add(property);\n        }\n      }\n\n      const allDepsArr = [...allDependencies].sort();\n      const presentArr = [...present].sort();\n\n      if (present.size === 0) {\n        let message = 'The object value did not define the';\n        if (allDepsArr.length === 1) {\n          message += ' property ' + escapeString(allDepsArr[0]);\n        } else {\n          message += ' properties ';\n          message += formatList(allDepsArr.map(escapeString), 'or');\n        }\n        return message;\n      }\n\n      if (present.size === 1) {\n        return 'Because the object value defined the property ' +\n          escapeString(presentArr[0]) +\n          ', it was also expected to validate against the corresponding subschema';\n      }\n\n      let message = 'Because the object value defined the properties ';\n      message += formatList(presentArr.map(escapeString), 'and');\n      message += ', it was also expected to validate against the ' +\n        'corresponding subschemas';\n      return message;\n    }\n\n    return '<unknown>';\n  }\n\n  if (opcode === ASSERTION_PROPERTY_DEPENDENCIES) {\n    const present = [];\n    const allDependencies = [];\n    const required = new Set();\n\n    for (const property in value) {\n      allDependencies.push(property);\n      if (Object.hasOwn(target, property)) {\n        present.push(property);\n        const dependencies = value[property];\n        for (let index = 0; index < dependencies.length; index++) {\n          if (valid || !Object.hasOwn(target, dependencies[index])) {\n            required.add(dependencies[index]);\n          }\n        }\n      }\n    }\n\n    allDependencies.sort();\n    present.sort();\n    const requiredArr = [...required].sort();\n\n    if (present.length === 0) {\n      let message = 'The object value did not define the';\n      if (allDependencies.length === 1) {\n        message += ' property ' + escapeString(allDependencies[0]);\n      } else {\n        message += ' properties ';\n        message += formatList(allDependencies.map(escapeString), 'or');\n      }\n      return message;\n    }\n\n    let message = '';\n    if (present.length === 1) {\n      message += 'Because the object value defined the';\n      message += ' property ' + escapeString(present[0]);\n    } else {\n      message += 'Because the object value defined the';\n      message += ' properties ';\n      message += formatList(present.map(escapeString), 'and');\n    }\n\n    message += ', it was also expected to define the';\n    if (requiredArr.length === 1) {\n      message += ' property ' + escapeString(requiredArr[0]);\n    } else {\n      message += ' properties ';\n      message += formatList(requiredArr.map(escapeString), 'and');\n    }\n    return message;\n  }\n\n  if (opcode === LOGICAL_WHEN_ARRAY_SIZE_GREATER) {\n    if (keyword === 'additionalItems' || keyword === 'items') {\n      if (target.length > value) {\n        const rest = target.length - value;\n        return 'The array value contains ' + rest + ' additional' +\n          (rest === 1 ? ' item' : ' items') +\n          ' not described by related keywords';\n      }\n      return 'The array value does not contain additional items not ' +\n        'described by related keywords';\n    }\n    return '<unknown>';\n  }\n\n  if (opcode === CONTROL_JUMP) {\n    if (isWithinKeyword(evaluatePath, 'propertyNames') &&\n        instanceLocation !== '') {\n      return 'The string value was expected to validate against the referenced schema';\n    }\n    return describeReference(target);\n  }\n\n  return '<unknown>';\n}\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/index.d.mts",
    "content": "export type Template = Array<unknown>;\n\nexport type EvaluationCallback = (\n  type: \"pre\" | \"post\",\n  valid: boolean,\n  instruction: unknown[],\n  evaluatePath: string,\n  instanceLocation: string,\n  annotation: unknown\n) => void;\n\nexport type StandardOutputFormat = 'flag' | 'basic';\n\nexport interface StandardOutputErrorEntry {\n  keywordLocation: string;\n  absoluteKeywordLocation: string;\n  instanceLocation: string;\n  error: string;\n}\n\nexport interface StandardOutputAnnotationEntry {\n  keywordLocation: string;\n  absoluteKeywordLocation: string;\n  instanceLocation: string;\n  annotation: unknown[];\n}\n\nexport type StandardOutputFlagResult = { valid: boolean };\n\nexport type StandardOutputBasicResult =\n  | { valid: true; annotations?: StandardOutputAnnotationEntry[] }\n  | { valid: false; errors: StandardOutputErrorEntry[] };\n\nexport type StandardOutputResult =\n  | StandardOutputFlagResult\n  | StandardOutputBasicResult;\n\nexport declare class Blaze {\n  static reviver(\n    key: string,\n    value: unknown,\n    context: { source: string }\n  ): unknown;\n  constructor(template: Template);\n  validate(instance: unknown, format: 'flag'): StandardOutputFlagResult;\n  validate(instance: unknown, format: 'basic'): StandardOutputBasicResult;\n  validate(instance: unknown, callback?: EvaluationCallback): boolean;\n}\n\nexport declare function describe(\n  valid: boolean,\n  instruction: unknown[],\n  evaluatePath: string,\n  instanceLocation: string,\n  instance: unknown,\n  annotation: unknown\n): string;\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/index.mjs",
    "content": "import {\n  ANNOTATION_EMIT, ANNOTATION_TO_PARENT, ANNOTATION_BASENAME_TO_PARENT,\n  ASSERTION_EQUALS_ANY,\n  CONTROL_GROUP as CONTROL_GROUP_START,\n  CONTROL_EVALUATE as CONTROL_EVALUATE_END,\n  CONTROL_JUMP, CONTROL_DYNAMIC_ANCHOR_JUMP\n} from './opcodes.mjs';\n\nconst JSON_VERSION = 5;\nconst DEPTH_LIMIT = 300;\nconst URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\\-.]*:[^\\s]*$/;\n\nfunction buildJsonPointer(tokens, length) {\n  if (length === 0) return '';\n  let result = '';\n  for (let index = 0; index < length; index++) {\n    const token = String(tokens[index]);\n    result += '/' + token.replaceAll('~', '~0').replaceAll('/', '~1');\n  }\n  return result;\n}\n\nconst Type = {\n  Null: 0,\n  Boolean: 1,\n  Integer: 2,\n  Real: 3,\n  String: 4,\n  Array: 5,\n  Object: 6,\n  Decimal: 7\n};\n\nfunction jsonTypeOf(value) {\n  if (value === null) return Type.Null;\n  switch (typeof value) {\n    case 'boolean': return Type.Boolean;\n    case 'number': return Number.isInteger(value) ? Type.Integer : Type.Real;\n    case 'bigint': return Type.Integer;\n    case 'string': return Type.String;\n    case 'object': return Array.isArray(value) ? Type.Array : Type.Object;\n    default: return Type.Null;\n  }\n}\n\nfunction isIntegral(value) {\n  return typeof value === 'bigint' ||\n    (typeof value === 'number' && Number.isFinite(value) && Math.floor(value) === value);\n}\n\nfunction resolveInstance(instance, relativeInstanceLocation) {\n  const length = relativeInstanceLocation.length;\n  if (length === 0) return instance;\n  if (length === 1) {\n    if (instance === undefined || instance === null) return undefined;\n    return instance[relativeInstanceLocation[0]];\n  }\n  let current = instance;\n  for (let index = 0; index < length; index++) {\n    if (current === undefined || current === null) return undefined;\n    current = current[relativeInstanceLocation[index]];\n  }\n  return current;\n}\n\nfunction prepareInstruction(instruction) {\n  const wrapper = instruction[5];\n  if (wrapper === undefined || wrapper === null) {\n    instruction[5] = null;\n  } else {\n    const typeIndex = wrapper[0];\n    if (typeIndex === 0 || wrapper.length === 1) {\n      instruction[5] = null;\n    } else {\n      const payload = wrapper[1];\n      switch (typeIndex) {\n        case 4:\n          instruction[5] = payload[0];\n          break;\n        case 9:\n          try { instruction[5] = new RegExp(payload, 'u'); }\n          catch { instruction[5] = new RegExp(payload); }\n          break;\n        case 13: {\n          if (Array.isArray(payload)) {\n            const object = Object.create(null);\n            for (let index = 0; index < payload.length; index++) {\n              object[payload[index][0]] = payload[index][1];\n            }\n            instruction[5] = object;\n          } else {\n            instruction[5] = payload;\n          }\n          break;\n        }\n        case 15: {\n          if (Array.isArray(payload)) {\n            const object = Object.create(null);\n            for (let index = 0; index < payload.length; index++) {\n              object[payload[index][0]] = payload[index][1];\n            }\n            instruction[5] = object;\n          } else {\n            instruction[5] = payload;\n          }\n          break;\n        }\n        case 16: {\n          payload[0] = new Set(payload[0]);\n          const regexes = payload[2];\n          for (let index = 0; index < regexes.length; index++) {\n            try { regexes[index] = new RegExp(regexes[index], 'u'); }\n            catch { regexes[index] = new RegExp(regexes[index]); }\n          }\n          instruction[5] = payload;\n          break;\n        }\n        default:\n          instruction[5] = payload;\n          break;\n      }\n    }\n  }\n\n  const opcode = instruction[0];\n  if (opcode === ASSERTION_EQUALS_ANY && Array.isArray(instruction[5])) {\n    const values = instruction[5];\n    let allPrimitive = true;\n    for (let index = 0; index < values.length; index++) {\n      const element = values[index];\n      if (element !== null && typeof element === 'object') {\n        allPrimitive = false;\n        break;\n      }\n    }\n    if (allPrimitive) {\n      instruction[5] = { set: new Set(values), values, primitive: true };\n    }\n  }\n\n  if (instruction.length < 7) {\n    instruction.push(undefined);\n  }\n\n  instruction.push(handlers[opcode] || null);\n\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      prepareInstruction(children[index]);\n    }\n  }\n}\n\nfunction resolveJumpTargets(instructions, targets) {\n  for (let index = 0; index < instructions.length; index++) {\n    const instruction = instructions[index];\n    if (instruction[0] === CONTROL_JUMP) {\n      const targetIndex = instruction[5];\n      if (targetIndex < targets.length) {\n        instruction[5] = targets[targetIndex];\n      }\n    }\n    const children = instruction[6];\n    if (children) {\n      resolveJumpTargets(children, targets);\n    }\n  }\n}\n\nconst FNV_OFFSET = 14695981039346656037n;\nconst FNV_PRIME = 1099511628211n;\nconst MASK_53 = (1n << 53n) - 1n;\n\nfunction blazeHash(resource, fragment) {\n  let result = FNV_OFFSET & MASK_53;\n  for (let index = 0; index < fragment.length; index++) {\n    result ^= BigInt(fragment.charCodeAt(index));\n    result = (result * FNV_PRIME) & MASK_53;\n  }\n  return Number((BigInt(resource) + result) & MASK_53);\n}\n\nfunction collectAnchorNames(targets, result) {\n  for (let targetIndex = 0; targetIndex < targets.length; targetIndex++) {\n    collectAnchorNamesFromInstructions(targets[targetIndex], result);\n  }\n}\n\nfunction collectAnchorNamesFromInstructions(instructions, result) {\n  for (let index = 0; index < instructions.length; index++) {\n    const instruction = instructions[index];\n    if (instruction[0] === CONTROL_DYNAMIC_ANCHOR_JUMP && typeof instruction[5] === 'string') {\n      result.add(instruction[5]);\n    }\n    if (instruction[6]) {\n      collectAnchorNamesFromInstructions(instruction[6], result);\n    }\n  }\n}\n\nfunction compile(template) {\n  const targets = template[3];\n  for (let targetIndex = 0; targetIndex < targets.length; targetIndex++) {\n    const target = targets[targetIndex];\n    for (let index = 0; index < target.length; index++) {\n      prepareInstruction(target[index]);\n    }\n  }\n\n  for (let targetIndex = 0; targetIndex < targets.length; targetIndex++) {\n    resolveJumpTargets(targets[targetIndex], targets);\n  }\n\n  const labels = new Map();\n  const rawLabels = template[4];\n  for (let index = 0; index < rawLabels.length; index++) {\n    const pair = rawLabels[index];\n    labels.set(pair[0], pair[1]);\n  }\n\n  const anchors = new Map();\n  if (template[1]) {\n    const anchorNames = new Set();\n    collectAnchorNames(targets, anchorNames);\n    const resourceCount = targets.length;\n    for (const anchor of anchorNames) {\n      for (let resource = 0; resource <= resourceCount; resource++) {\n        const hash = blazeHash(resource, anchor);\n        const targetIndex = labels.get(hash);\n        if (targetIndex !== undefined) {\n          anchors.set(resource + ':' + anchor, targets[targetIndex]);\n        }\n      }\n    }\n  }\n\n  template[4] = labels;\n  template[5] = anchors;\n  return template;\n}\n\nfunction emitResolve(varName, instanceExpr, relInstance) {\n  if (relInstance.length === 0) return `var ${varName}=${instanceExpr};`;\n  if (relInstance.length === 1) return `var ${varName}=${instanceExpr}==null?void 0:${instanceExpr}[${JSON.stringify(relInstance[0])}];`;\n  return null;\n}\n\nfunction compileInstructionToCode(instruction, captures, visited, budget) {\n  if (budget[0] <= 0) { var ci = captures.length; captures.push(instruction); return 'return _fh['+instruction[0]+'](_c['+ci+'],i,d,_t,_v);'; }\n  var opcode = instruction[0], ri = instruction[2], value = instruction[5], children = instruction[6];\n  function R(v) { return emitResolve(v, 'i', ri); }\n  function inlineCondition(child, tv) {\n    var op = child[0], cr = child[2], cv = child[5];\n    if (cr.length !== 0) return null;\n    switch (op) {\n      case 11: return '{if(_es(' + tv + ')!==' + cv + ')return false;}';\n      case 43: return 'if(' + tv + '!=null&&typeof ' + tv + \"==='object'&&!Array.isArray(\" + tv + ')){' + emitResolve('t', tv, cr) + 'if(t!==void 0&&_es(t)!==' + cv + ')return false;}';\n      default: return null;\n    }\n  }\n  function seq(ci, tv) { var c = ''; for (var j = 0; j < ci.length; j++) { var inl = inlineCondition(ci[j], tv); if (inl !== null) { budget[0] -= inl.length; c += inl; continue; } var r = compileInstructionToCode(ci[j], captures, visited, budget); if (r === null) { var idx = captures.length; captures.push(ci[j]); c += 'if(!_e(_c['+idx+'],'+tv+',d+1,_t,_v))return false;'; } else { budget[0] -= r.length; c += 'if(!(function(i,d,_t,_v){'+r+'})('+tv+',d+1,_t,_v))return false;'; } } return c; }\n  function lb(ci, iv) { return seq(ci, iv); }\n  function fb(op) { var ci = captures.length; captures.push(instruction); return 'return _fh['+op+'](_c['+ci+'],i,d,_t,_v);'; }\n  function cc(child, tv) { var r = compileInstructionToCode(child, captures, visited, budget); if (r === null) { var ci = captures.length; captures.push(child); return '_e(_c['+ci+'],'+tv+',d+1,_t,_v)'; } budget[0] -= r.length; return '(function(i,d,_t,_v){'+r+'})('+tv+',d+1,_t,_v)'; }\n  var IO = \"if(i==null||typeof i!=='object'||Array.isArray(i))return true;\";\n  var TO = \"if(t==null||typeof t!=='object'||Array.isArray(t))\";\n  switch (opcode) {\n    case 0: return 'return false;';\n    case 1: { var r=R('t'); return r?r+TO+'return true;return Object.hasOwn(t,'+JSON.stringify(value)+');':null; }\n    case 2: { var r=R('t'); return r?r+\"return t!=null&&typeof t==='object'&&!Array.isArray(t)&&Object.hasOwn(t,\"+JSON.stringify(value)+');':null; }\n    case 3: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;'; for(var j=0;j<value.length;j++)c+='if(!Object.hasOwn(t,'+JSON.stringify(value[j])+'))return false;'; return c+'return true;'; }\n    case 4: { var r=R('t'); if(!r)return null; var c=r+TO+'return false;'; for(var j=0;j<value.length;j++)c+='if(!Object.hasOwn(t,'+JSON.stringify(value[j])+'))return false;'; return c+'return true;'; }\n    case 5: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;var s=0;for(var k in t)s++;if(s!=='+value.length+')return false;'; for(var j=0;j<value.length;j++)c+='if(!Object.hasOwn(t,'+JSON.stringify(value[j])+'))return false;'; return c+'return true;'; }\n    case 6: { var r=R('t'); if(!r)return null; var c=r+TO+'return false;var s=0;for(var k in t)s++;if(s!=='+value.length+')return false;'; for(var j=0;j<value.length;j++)c+='if(!Object.hasOwn(t,'+JSON.stringify(value[j])+'))return false;'; return c+'return true;'; }\n    case 7: return fb(7); case 8: return fb(8);\n    case 9: { var r=R('t'); return r?r+'var a=_jt(t);if(a==='+value+')return true;return '+value+'===2&&_ii(t);':null; }\n    case 10: { var r=R('t'); return r?r+'var a=_jt(t);if(('+value+'&(1<<a))!==0)return true;return('+value+'&4)!==0&&_ii(t);':null; }\n    case 11: { var r=R('t'); return r?r+'return _es(t)==='+value+';':null; }\n    case 12: { var r=R('t'); return r?r+'return('+value+'&(1<<_es(t)))!==0;':null; }\n    case 13: { var r=R('t'); return r?r+'return('+value+'&(1<<_es(t)))===0;':null; }\n    case 14: { var r=R('t'); return r?r+\"if(typeof t!=='string')return false;var l=_ul(t);if(l<\"+value[0]+')return false;'+(value[1]!==null?'if(l>'+value[1]+')return false;':'')+'return true;':null; }\n    case 15: { var r=R('t'); return r?r+\"return typeof t==='string'&&_ul(t)<=\"+value+';':null; }\n    case 16: { var r=R('t'); return r?r+'if(!Array.isArray(t))return false;if(t.length<'+value[0]+')return false;'+(value[1]!==null?'if(t.length>'+value[1]+')return false;':'')+'return true;':null; }\n    case 17: { var r=R('t'); return r?r+'return Array.isArray(t)&&t.length<='+value+';':null; }\n    case 18: { var r=R('t'); return r?r+TO+'return false;var s=0;for(var k in t)s++;if(s<'+value[0]+')return false;'+(value[1]!==null?'if(s>'+value[1]+')return false;':'')+'return true;':null; }\n    case 19: { var r=R('t'); return r?r+TO+'return false;var s=0;for(var k in t)s++;return s<='+value+';':null; }\n    case 20: return fb(20); case 21: return fb(21); case 22: return fb(22);\n    case 23: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;return t.length<'+value+';':null; }\n    case 24: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;return t.length>'+value+';':null; }\n    case 25: { var r=R('t'); return r?r+TO+'return true;var s=0;for(var k in t)s++;return s<'+value+';':null; }\n    case 26: { var r=R('t'); return r?r+TO+'return true;var s=0;for(var k in t)s++;return s>'+value+';':null; }\n    case 27: { if(typeof value==='string'||typeof value==='number'||typeof value==='boolean'||value===null){var r=R('t');return r?r+'return t==='+JSON.stringify(value)+';':null;}return fb(27); }\n    case 28: return fb(28); case 29: return fb(29);\n    case 30: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+\"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t>=\"+v+';':null; }\n    case 31: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+\"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t<=\"+v+';':null; }\n    case 32: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+\"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t>\"+v+';':null; }\n    case 33: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+\"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t<\"+v+';':null; }\n    case 34: return fb(34); case 35: return fb(35);\n    case 36: return fb(36); case 37: return fb(37); case 38: return fb(38); case 39: return fb(39);\n    case 40: return fb(40);\n    case 41: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;var a=_jt(t);return a==='+value+'||('+value+'===2&&_ii(t));':null; }\n    case 42: return fb(42);\n    case 43: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return _es(t)==='+value+';':null; }\n    case 44: return fb(44);\n    case 45: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return('+value+'&(1<<_es(t)))!==0;':null; }\n    case 46: return fb(46); case 47: return fb(47); case 48: return fb(48);\n    case 49: return fb(49);\n    case 50: return 'return true;'; case 51: return 'return true;'; case 52: return 'return true;'; case 53: return 'return true;';\n    case 54: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r; for(var j=0;j<children.length;j++)c+='if(!'+cc(children[j],'t')+')return true;'; return c+'return false;'; }\n    case 55: return fb(55);\n    case 56: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; if(value){var c=r+'var __r=false;';for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')__r=true;';return c+'return __r;';} var c=r;for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')return true;';return c+'return false;'; }\n    case 57: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; return r+seq(children,'t')+'return true;'; }\n    case 58: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r+'var __r=true,__m=false;';for(var j=0;j<children.length;j++){c+='if('+cc(children[j],'t')+'){if(__m){__r=false;'+(!value?'return false;':'')+ '}else __m=true;}';}return c+'return __r&&__m;'; }\n    case 59: return fb(59);\n    case 60: { var r=R('t'); if(!r)return null; var c=r+'if(_jt(t)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }\n    case 61: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }\n    case 62: { var r=R('t'); if(!r)return null; var c=r+'if(!Array.isArray(t)||t.length<='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }\n    case 63: return fb(63); case 64: return fb(64);\n    case 65: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi!==void 0){var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}}return true;'; }\n    case 66: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi===void 0)return false;var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}return true;'; }\n    case 67: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+TO+'return true;for(var k in t){'+lb(children,'t[k]')+'}return true;'; }\n    case 68: return fb(68); case 69: return fb(69); case 70: return fb(70); case 71: return fb(71); case 72: return fb(72);\n    case 73: return fb(73); case 74: return fb(74); case 75: return fb(75); case 76: return fb(76);\n    case 77: { var r=R('t'); return r?r+TO+'return true;for(var k in t){if(_es(t[k])!=='+value+')return false;}return true;':null; }\n    case 78: return fb(78); case 79: return fb(79); case 80: return fb(80); case 81: return fb(81);\n    case 82: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }\n    case 83: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t)||'+value+'>=t.length)return true;for(var j='+value+';j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }\n    case 84: return fb(84);\n    case 85: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){var a=_jt(t[j]);if(a!=='+value+'&&!('+value+'===2&&_ii(t[j])))return false;}return true;':null; }\n    case 86: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(_es(t[j])!=='+value+')return false;}return true;':null; }\n    case 87: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(('+value+'&(1<<_es(t[j])))===0)return false;}return true;':null; }\n    case 88: return fb(88); case 89: return fb(89); case 90: return fb(90); case 91: return fb(91); case 92: return fb(92);\n    case 93: { if(!children||children.length===0)return 'return true;'; var c=''; for(var j=0;j<children.length;j++){var r2=compileInstructionToCode(children[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(children[j]);c+='if(!_e(_c['+ci+'],i,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(i,d+1,_t,_v))return false;';}} return c+'return true;'; }\n    case 94: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }\n    case 95: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }\n    case 96: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }\n    case 97: return 'return true;';\n    case 98: return fb(98);\n    case 99: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(99); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(99); var c=r; for(var j=0;j<value.length;j++){var r2=compileInstructionToCode(value[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(value[j]);c+='if(!_e(_c['+ci+'],t,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(t,d+1,_t,_v))return false;';}} return c+'return true;'; }\n    default: return null;\n  }\n}\n\nfunction generateNativeValidator(template) {\n  if (template[1] || template[2]) return null;\n  const targets = template[3];\n  if (targets.length === 0) return () => true;\n  const instructions = targets[0];\n  if (instructions.length === 0) return () => true;\n\n  const capturedInstructions = [];\n  const budget = [5000000];\n  let body = '';\n  for (let index = 0; index < instructions.length; index++) {\n    const code = compileInstructionToCode(instructions[index], capturedInstructions, null, budget);\n    if (code === null) return null;\n    budget[0] -= code.length;\n    body += `if(!(function(i,d,_t,_v){${code}})(instance,0,_t,_v))return false;`;\n  }\n  body += 'return true;';\n\n  try {\n    const fn = eval(\n      '(function(_es,_jt,_ii,_ul,_e,_fh,_c,_t){' +\n      'return function(instance,_v){' + body + '};' +\n      '})'\n    );\n    return fn(\n      effectiveTypeStrictReal, jsonTypeOf, isIntegral, unicodeLength,\n      evaluateInstructionFast, fastHandlers, capturedInstructions, template\n    );\n  } catch {\n    return null;\n  }\n}\n\nfunction sourceToBigInt(source) {\n  // Plain integer like \"99999999999999999999999999999999999\"\n  if (/^-?[0-9]+$/.test(source)) return BigInt(source);\n  // Exponential notation like \"9.9999999999999999e+34\". Parse the coefficient\n  // and exponent to reconstruct the exact integer, as `BigInt` cannot parse\n  // exponential notation directly\n  const match = source.match(/^(-?)([0-9]+)\\.?([0-9]*)[eE][+]?([0-9]+)$/);\n  if (!match) return null;\n  const exponent = parseInt(match[4]) - match[3].length;\n  if (exponent < 0) return null;\n  return BigInt(match[1] + match[2] + match[3]) * (10n ** BigInt(exponent));\n}\n\nfunction reviver(_key, value, context) {\n  // On older engines, `JSON.parse` calls the reviver with only two arguments\n  if (context === undefined) return value;\n  if (typeof value !== 'number') return value;\n  const source = context.source;\n  // Only convert when `JSON.parse` actually truncated the value, avoiding\n  // unnecessary `BigInt` conversion for integers that are exactly\n  // representable as doubles\n  if (String(value) === source) return value;\n  const bigint = sourceToBigInt(source);\n  return bigint !== null ? bigint : value;\n}\n\nclass Blaze {\n  static reviver = reviver;\n\n  constructor(template) {\n    if (!Array.isArray(template) || template[0] !== JSON_VERSION) {\n      throw new Error(\n        `Only version ${JSON_VERSION} of the compiled template is supported by this version of the evaluator`);\n    }\n    compile(template);\n    this.template = template;\n    this.callbackMode = false;\n    this.trackMode = false;\n    this.dynamicMode = false;\n    this.callback = null;\n    this.evaluatePathLength = 0;\n    this.evaluatePathTokens = null;\n    this.instanceLocationLength = 0;\n    this.instanceLocationTokens = null;\n    this.resources = null;\n    this.evaluated = null;\n    this.propertyTarget = undefined;\n    this.propertyParent = undefined;\n    this.propertyKey = undefined;\n    this._nativeValidate = generateNativeValidator(template);\n  }\n\n  validate(instance, callbackOrFormat) {\n    if (typeof callbackOrFormat === 'string') {\n      return runStandard(this, instance, callbackOrFormat);\n    }\n\n    const callback = callbackOrFormat;\n\n    if (callback === undefined && this._nativeValidate) {\n      return this._nativeValidate(instance, this);\n    }\n\n    const template = this.template;\n    const targets = template[3];\n    if (targets.length === 0) return true;\n\n    const track = template[2];\n    const dynamic = template[1];\n    this.trackMode = track;\n    this.dynamicMode = dynamic;\n    this.callbackMode = callback !== undefined;\n    this.callback = callback;\n\n    if (this.callbackMode) {\n      this.evaluatePathLength = 0;\n      this.evaluatePathTokens = [];\n      this.instanceLocationLength = 0;\n      this.instanceLocationTokens = [];\n      this.resources = [];\n      if (track || dynamic) {\n        evaluateInstruction = evaluateInstructionTrackedCallback;\n        if (track) {\n          this.evaluated = [];\n        }\n      } else {\n        evaluateInstruction = evaluateInstructionFastCallback;\n      }\n    } else if (track || dynamic) {\n      evaluateInstruction = evaluateInstructionTracked;\n      if (track) {\n        this.evaluatePathLength = 0;\n        this.evaluatePathTokens = [];\n        this.evaluated = [];\n      }\n      if (dynamic) {\n        this.resources = [];\n      }\n    } else {\n      evaluateInstruction = evaluateInstructionFast;\n    }\n\n    const instructions = targets[0];\n    let result = true;\n    for (let index = 0; index < instructions.length; index++) {\n      if (!evaluateInstruction(instructions[index], instance, 0, template, this)) {\n        result = false;\n        break;\n      }\n    }\n\n    this.resources = null;\n    this.evaluated = null;\n    this.evaluatePathTokens = null;\n    this.instanceLocationTokens = null;\n    this.callback = null;\n    this.callbackMode = false;\n    return result;\n  }\n\n  snapshotPathTokens() {\n    return this.evaluatePathTokens.slice(0, this.evaluatePathLength);\n  }\n\n  pushPath(relativeSchemaLocation) {\n    for (let index = 0; index < relativeSchemaLocation.length; index++) {\n      if (this.evaluatePathLength < this.evaluatePathTokens.length) {\n        this.evaluatePathTokens[this.evaluatePathLength] = relativeSchemaLocation[index];\n      } else {\n        this.evaluatePathTokens.push(relativeSchemaLocation[index]);\n      }\n      this.evaluatePathLength++;\n    }\n  }\n\n  popPath(count) {\n    this.evaluatePathLength -= count;\n  }\n\n  callbackPush(instruction) {\n    if (!this.trackMode) {\n      this.pushPath(instruction[1]);\n    }\n    const relInstance = instruction[2];\n    for (let index = 0; index < relInstance.length; index++) {\n      this.pushInstanceToken(relInstance[index]);\n    }\n    this.callback(\"pre\", true, instruction,\n      buildJsonPointer(this.evaluatePathTokens, this.evaluatePathLength),\n      buildJsonPointer(this.instanceLocationTokens, this.instanceLocationLength),\n      null);\n  }\n\n  callbackPop(instruction, result) {\n    const isAnnotation = instruction[0] >= ANNOTATION_EMIT &&\n                         instruction[0] <= ANNOTATION_BASENAME_TO_PARENT;\n    this.callback(\"post\", result, instruction,\n      buildJsonPointer(this.evaluatePathTokens, this.evaluatePathLength),\n      buildJsonPointer(this.instanceLocationTokens, this.instanceLocationLength),\n      isAnnotation ? instruction[5] : null);\n    if (!this.trackMode) {\n      this.popPath(instruction[1].length);\n    }\n    const relInstance = instruction[2];\n    for (let index = 0; index < relInstance.length; index++) {\n      this.popInstanceToken();\n    }\n  }\n\n  callbackAnnotation(instruction) {\n    if (!this.trackMode) {\n      this.pushPath(instruction[1]);\n    }\n    const relInstance = instruction[2];\n    for (let index = 0; index < relInstance.length; index++) {\n      this.pushInstanceToken(relInstance[index]);\n    }\n    const evaluatePath = buildJsonPointer(this.evaluatePathTokens, this.evaluatePathLength);\n    const opcode = instruction[0];\n    let instanceLocation;\n    if (opcode === ANNOTATION_EMIT) {\n      instanceLocation = buildJsonPointer(this.instanceLocationTokens, this.instanceLocationLength);\n    } else {\n      const parentLength = this.instanceLocationLength > 0 ? this.instanceLocationLength - 1 : 0;\n      instanceLocation = buildJsonPointer(this.instanceLocationTokens, parentLength);\n    }\n    let annotationValue = instruction[5];\n    if (opcode === ANNOTATION_BASENAME_TO_PARENT && this.instanceLocationLength > 0) {\n      annotationValue = this.instanceLocationTokens[this.instanceLocationLength - 1];\n    }\n    this.callback(\"pre\", true, instruction, evaluatePath, instanceLocation, null);\n    this.callback(\"post\", true, instruction, evaluatePath, instanceLocation, annotationValue);\n    if (!this.trackMode) {\n      this.popPath(instruction[1].length);\n    }\n    for (let index = 0; index < relInstance.length; index++) {\n      this.popInstanceToken();\n    }\n  }\n\n  pushInstanceToken(token) {\n    if (this.instanceLocationLength < this.instanceLocationTokens.length) {\n      this.instanceLocationTokens[this.instanceLocationLength] = token;\n    } else {\n      this.instanceLocationTokens.push(token);\n    }\n    this.instanceLocationLength++;\n  }\n\n  popInstanceToken() {\n    this.instanceLocationLength--;\n  }\n\n  markEvaluated(target, parent, key) {\n    this.evaluated.push({\n      instance: target,\n      parent: parent,\n      key: key,\n      pathTokens: this.snapshotPathTokens(),\n      pathLength: this.evaluatePathLength,\n      skip: false\n    });\n  }\n\n  isEvaluated(target, parent, key) {\n    const pathLen = this.evaluatePathLength;\n    const initialLen = pathLen <= 1 ? 0 : pathLen - 1;\n    const initialTokens = this.evaluatePathTokens;\n    const isPrimitive = target === null || typeof target !== 'object';\n    const hasLocation = parent !== undefined;\n\n    for (let index = this.evaluated.length - 1; index >= 0; index--) {\n      const entry = this.evaluated[index];\n      if (entry.skip) continue;\n\n      if (isPrimitive && hasLocation && entry.parent !== undefined) {\n        if (entry.parent !== parent || entry.key !== key) continue;\n      } else {\n        if (entry.instance !== target) continue;\n      }\n\n      if (initialLen === 0) return true;\n      if (entry.pathLength < initialLen) continue;\n      let match = true;\n      for (let token = 0; token < initialLen; token++) {\n        if (entry.pathTokens[token] !== initialTokens[token]) {\n          match = false;\n          break;\n        }\n      }\n      if (match) return true;\n    }\n    return false;\n  }\n\n  unevaluate() {\n    const pathLen = this.evaluatePathLength;\n    const tokens = this.evaluatePathTokens;\n    for (let index = 0; index < this.evaluated.length; index++) {\n      const entry = this.evaluated[index];\n      if (entry.skip) continue;\n      if (entry.pathLength < pathLen) continue;\n      let match = true;\n      for (let token = 0; token < pathLen; token++) {\n        if (entry.pathTokens[token] !== tokens[token]) {\n          match = false;\n          break;\n        }\n      }\n      if (match) entry.skip = true;\n    }\n  }\n}\n\nfunction evaluateInstructionFast(instruction, instance, depth, template, evaluator) {\n  if (depth > DEPTH_LIMIT) {\n    throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');\n  }\n  const handler = fastHandlers[instruction[0]];\n  if (!handler) return true;\n  return handler(instruction, instance, depth, template, evaluator);\n}\n\nfunction evaluateInstructionTracked(instruction, instance, depth, template, evaluator) {\n  if (depth > DEPTH_LIMIT) {\n    throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');\n  }\n  const handler = fastHandlers[instruction[0]];\n  if (!handler) return true;\n\n  const type = instruction[0];\n  if (type < CONTROL_GROUP_START || type > CONTROL_EVALUATE_END) {\n    if (evaluator.trackMode) {\n      evaluator.pushPath(instruction[1]);\n    }\n    if (evaluator.dynamicMode) {\n      evaluator.resources.push(instruction[4]);\n    }\n\n    const result = handler(instruction, instance, depth, template, evaluator);\n\n    if (evaluator.trackMode) {\n      evaluator.popPath(instruction[1].length);\n    }\n    if (evaluator.dynamicMode) {\n      evaluator.resources.pop();\n    }\n    return result;\n  }\n\n  return handler(instruction, instance, depth, template, evaluator);\n}\n\nfunction evaluateInstructionFastCallback(instruction, instance, depth, template, evaluator) {\n  if (depth > DEPTH_LIMIT) {\n    throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');\n  }\n  const handler = handlers[instruction[0]];\n  if (!handler) return true;\n  return handler(instruction, instance, depth, template, evaluator);\n}\n\nfunction evaluateInstructionTrackedCallback(instruction, instance, depth, template, evaluator) {\n  if (depth > DEPTH_LIMIT) {\n    throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');\n  }\n  const handler = handlers[instruction[0]];\n  if (!handler) return true;\n\n  const type = instruction[0];\n  if (type < CONTROL_GROUP_START || type > CONTROL_EVALUATE_END) {\n    if (evaluator.trackMode) {\n      evaluator.pushPath(instruction[1]);\n    }\n    if (evaluator.dynamicMode) {\n      evaluator.resources.push(instruction[4]);\n    }\n\n    const result = handler(instruction, instance, depth, template, evaluator);\n\n    if (evaluator.trackMode) {\n      evaluator.popPath(instruction[1].length);\n    }\n    if (evaluator.dynamicMode) {\n      evaluator.resources.pop();\n    }\n    return result;\n  }\n\n  return handler(instruction, instance, depth, template, evaluator);\n}\n\nlet evaluateInstruction = evaluateInstructionFast;\n\nfunction effectiveTypeStrictReal(value) {\n  if (value === null) return Type.Null;\n  switch (typeof value) {\n    case 'boolean': return Type.Boolean;\n    case 'number': return Number.isInteger(value) ? Type.Integer : Type.Real;\n    case 'bigint': return Type.Integer;\n    case 'string': return Type.String;\n    case 'object': return Array.isArray(value) ? Type.Array : Type.Object;\n    default: return Type.Null;\n  }\n}\n\nfunction typeSetTest(bitmask, typeIndex) {\n  return (bitmask & (1 << typeIndex)) !== 0;\n}\n\nfunction jsonEqual(left, right) {\n  if (left === right) return true;\n  if (left === null || right === null) return left === right;\n  if (typeof left !== typeof right) return false;\n  if (typeof left !== 'object') return left === right;\n  if (Array.isArray(left) !== Array.isArray(right)) return false;\n  if (Array.isArray(left)) {\n    if (left.length !== right.length) return false;\n    for (let index = 0; index < left.length; index++) {\n      if (!jsonEqual(left[index], right[index])) return false;\n    }\n    return true;\n  }\n  const keysLeft = Object.keys(left);\n  const keysRight = Object.keys(right);\n  if (keysLeft.length !== keysRight.length) return false;\n  for (let index = 0; index < keysLeft.length; index++) {\n    const key = keysLeft[index];\n    if (!Object.hasOwn(right, key)) return false;\n    if (!jsonEqual(left[key], right[key])) return false;\n  }\n  return true;\n}\n\nfunction fastHash(value) {\n  if (value === null) return 2;\n  switch (typeof value) {\n    case 'boolean': return value ? 1 : 0;\n    case 'number': return 4 + ((value | 0) & 255);\n    case 'bigint': return 4 + Number(value & 255n);\n    case 'string': return 3 + value.length;\n    case 'object':\n      if (Array.isArray(value)) {\n        let hash = 6;\n        for (let index = 0; index < value.length; index++) hash += 1 + fastHash(value[index]);\n        return hash;\n      } else {\n        let hash = 7;\n        for (const key in value) hash += 1 + key.length + fastHash(value[key]);\n        return hash;\n      }\n    default: return 2;\n  }\n}\n\nfunction isUnique(array) {\n  const length = array.length;\n  if (length <= 1) return true;\n  const first = array[0];\n  const firstType = typeof first;\n  if (first !== null && firstType !== 'object') {\n    let allPrimitive = true;\n    for (let index = 1; index < length; index++) {\n      const element = array[index];\n      if (element === null || typeof element === 'object') {\n        allPrimitive = false;\n        break;\n      }\n    }\n    if (allPrimitive) {\n      const set = new Set();\n      for (let index = 0; index < length; index++) {\n        const size = set.size;\n        set.add(array[index]);\n        if (set.size === size) return false;\n      }\n      return true;\n    }\n  }\n  const hashes = new Array(length);\n  for (let index = 0; index < length; index++) {\n    hashes[index] = fastHash(array[index]);\n  }\n  for (let index = 1; index < length; index++) {\n    for (let previous = 0; previous < index; previous++) {\n      if (hashes[index] === hashes[previous] && jsonEqual(array[index], array[previous])) return false;\n    }\n  }\n  return true;\n}\n\nfunction isDivisibleBy(value, divisor) {\n  if (divisor === 0 || divisor === 0n) return false;\n  if (typeof value === 'bigint' && typeof divisor === 'bigint') {\n    return value % divisor === 0n;\n  }\n  if (typeof value === 'bigint') {\n    value = Number(value);\n  } else if (typeof divisor === 'bigint') {\n    divisor = Number(divisor);\n  }\n  const remainder = value % divisor;\n  if (remainder === 0) return true;\n  return Math.abs(remainder) < 1e-9 || Math.abs(remainder - divisor) < 1e-9 ||\n         Math.abs(remainder + divisor) < 1e-9;\n}\n\nfunction unicodeLength(string) {\n  let count = 0;\n  for (let index = 0; index < string.length; index++) {\n    count++;\n    const code = string.charCodeAt(index);\n    if (code >= 0xD800 && code <= 0xDBFF) index++;\n  }\n  return count;\n}\n\nfunction objectSize(object) {\n  let count = 0;\n  for (const key in object) count++;\n  return count;\n}\n\nfunction isObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction AssertionFail(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction AssertionDefines(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = Object.hasOwn(target, instruction[5]);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionDefinesStrict(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const __result = Object.hasOwn(target, instruction[5]);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionDefinesAll(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const strings = instruction[5];\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionDefinesAllStrict(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const strings = instruction[5];\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionDefinesExactly(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  let targetSize = 0;\n  for (const key in target) targetSize++;\n  const strings = instruction[5];\n  if (targetSize !== strings.length) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionDefinesExactlyStrict(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  let targetSize = 0;\n  for (const key in target) targetSize++;\n  const strings = instruction[5];\n  if (targetSize !== strings.length) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionDefinesExactlyStrictHash3(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const entries = instruction[5][0];\n  let count = 0;\n  for (const key in target) count++;\n  if (count !== 3) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const __result = Object.hasOwn(target, entries[0][1]) &&\n    Object.hasOwn(target, entries[1][1]) &&\n    Object.hasOwn(target, entries[2][1]);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionPropertyDependencies(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const value = instruction[5];\n  for (const property in value) {\n    if (!Object.hasOwn(target, property)) continue;\n    const dependencies = value[property];\n    for (let index = 0; index < dependencies.length; index++) {\n      if (!Object.hasOwn(target, dependencies[index])) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionType(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  if (actual === expected) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  if (expected === Type.Integer && isIntegral(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction AssertionTypeAny(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const bitmask = instruction[5];\n  const typeIndex = jsonTypeOf(target);\n  if (typeSetTest(bitmask, typeIndex)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  if (typeSetTest(bitmask, Type.Integer) && isIntegral(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction AssertionTypeStrict(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const __result = effectiveTypeStrictReal(target) === instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeStrictAny(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const __result = typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionNotTypeStrictAny(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const __result = !typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeStringBounded(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const range = instruction[5];\n  const length = unicodeLength(target);\n  if (length < range[0]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (range[1] !== null && length > range[1]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionTypeStringUpper(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const __result = typeof target === 'string' && unicodeLength(target) <= instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeArrayBounded(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const range = instruction[5];\n  if (target.length < range[0]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (range[1] !== null && target.length > range[1]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionTypeArrayUpper(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const __result = Array.isArray(target) && target.length <= instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeObjectBounded(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const range = instruction[5];\n  const size = objectSize(target);\n  if (size < range[0]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (range[1] !== null && size > range[1]) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionTypeObjectUpper(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const __result = objectSize(target) <= instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionRegex(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = instruction[5].test(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionStringSizeLess(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = unicodeLength(target) < instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionStringSizeGreater(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = unicodeLength(target) > instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionArraySizeLess(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target.length < instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionArraySizeGreater(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target.length > instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionObjectSizeLess(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = objectSize(target) < instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionObjectSizeGreater(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = objectSize(target) > instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionEqual(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  let __result;\n  if (evaluator.propertyTarget !== undefined) {\n    const value = instruction[5];\n    __result = typeof value === 'string' && value === evaluator.propertyTarget;\n  } else {\n    __result = jsonEqual(resolveInstance(instance, instruction[2]), instruction[5]);\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionEqualsAny(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const value = instruction[5];\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (value.primitive) {\n    const __result = value.set.has(target);\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n    return __result;\n  }\n  const values = Array.isArray(value) ? value : value.values;\n  for (let index = 0; index < values.length; index++) {\n    if (jsonEqual(target, values[index])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n      return true;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction AssertionEqualsAnyStringHash(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget\n    : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n\n  const value = instruction[5];\n  const entries = value[0];\n  const tableOfContents = value[1];\n\n  const stringSize = target.length;\n  if (stringSize < tableOfContents.length) {\n    const hint = tableOfContents[stringSize];\n    if (hint[1] === 0) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    for (let index = hint[0] - 1; index < hint[1]; index++) {\n      if (entries[index][1] === target) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n        return true;\n      }\n    }\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction AssertionGreaterEqual(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target >= instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionLessEqual(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target <= instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionGreater(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target > instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionLess(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = target < instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionUnique(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = isUnique(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionDivisible(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = isDivisibleBy(target, instruction[5]);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeIntegerBounded(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const range = instruction[5];\n  const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeIntegerBoundedStrict(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const range = instruction[5];\n  const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeIntegerLowerBound(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const range = instruction[5];\n  const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionTypeIntegerLowerBoundStrict(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const range = instruction[5];\n  const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionStringType(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = URI_REGEX.test(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionPropertyType(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  const __result = actual === expected || (expected === Type.Integer && isIntegral(target));\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionPropertyTypeEvaluate(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  const result = actual === expected || (expected === Type.Integer && isIntegral(target));\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction AssertionPropertyTypeStrict(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = effectiveTypeStrictReal(target) === instruction[5];\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionPropertyTypeStrictEvaluate(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const result = effectiveTypeStrictReal(target) === instruction[5];\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction AssertionPropertyTypeStrictAny(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const __result = typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction AssertionPropertyTypeStrictAnyEvaluate(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const result = typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction AssertionArrayPrefix(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (target.length === 0) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const children = instruction[6];\n  const prefixes = children.length - 1;\n  const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;\n  const entry = children[pointer];\n  const entryChildren = entry[6];\n  if (entryChildren) {\n    for (let index = 0; index < entryChildren.length; index++) {\n      if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionArrayPrefixEvaluate(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (target.length === 0) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const children = instruction[6];\n  const prefixes = children.length - 1;\n  const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;\n  const entry = children[pointer];\n  const entryChildren = entry[6];\n  if (entryChildren) {\n    for (let index = 0; index < entryChildren.length; index++) {\n      if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.trackMode) {\n    if (target.length === prefixes) {\n      evaluator.markEvaluated(target);\n    } else {\n      for (let cursor = 0; cursor <= pointer; cursor++) {\n        evaluator.markEvaluated(target[cursor], target, cursor);\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AssertionObjectPropertiesSimple(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const value = instruction[5];\n  const children = instruction[6];\n  for (let index = 0; index < value.length; index++) {\n    const entry = value[index];\n    const name = entry[0];\n    const required = entry[2];\n    if (!Object.hasOwn(target, name)) {\n      if (required) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n      continue;\n    }\n    if (index < children.length) {\n      if (!evaluateInstructionFast(children[index], target[name], depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction AnnotationEmit(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackAnnotation(instruction);\n  return true;\n}\nfunction AnnotationToParent(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackAnnotation(instruction);\n  return true;\n}\nfunction AnnotationBasenameToParent(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackAnnotation(instruction);\n  return true;\n}\n\nfunction Evaluate(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (evaluator.trackMode) {\n    const target = resolveInstance(instance, instruction[2]);\n    evaluator.markEvaluated(target);\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LogicalNot(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n        return true;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction LogicalNotEvaluate(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const children = instruction[6];\n  let result = false;\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        result = true;\n        break;\n      }\n    }\n  }\n  if (evaluator.trackMode) evaluator.unevaluate();\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction LogicalOr(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  if (!children || children.length === 0) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const target = resolveInstance(instance, instruction[2]);\n  const exhaustive = instruction[5];\n  let result = false;\n  if (exhaustive) {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        result = true;\n      }\n    }\n  } else {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        result = true;\n        break;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction LogicalAnd(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LogicalXor(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  const exhaustive = instruction[5];\n  const children = instruction[6];\n  let result = true;\n  let hasMatched = false;\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (hasMatched) {\n          result = false;\n          if (!exhaustive) break;\n        } else {\n          hasMatched = true;\n        }\n      }\n    }\n  }\n  const __result = result && hasMatched;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction LogicalCondition(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const value = instruction[5];\n  const thenStart = value[0];\n  const elseStart = value[1];\n  const children = instruction[6];\n  const childrenSize = children ? children.length : 0;\n\n  let conditionEnd = childrenSize;\n  if (thenStart > 0) conditionEnd = thenStart;\n  else if (elseStart > 0) conditionEnd = elseStart;\n\n  const target = resolveInstance(instance, instruction[2]);\n\n  let conditionResult = true;\n  for (let cursor = 0; cursor < conditionEnd; cursor++) {\n    if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {\n      conditionResult = false;\n      break;\n    }\n  }\n\n  const consequenceStart = conditionResult ? thenStart : elseStart;\n  const consequenceEnd = (conditionResult && elseStart > 0) ? elseStart : childrenSize;\n\n  if (consequenceStart > 0) {\n    if (evaluator.trackMode || evaluator.callbackMode) {\n      evaluator.popPath(instruction[1].length);\n    }\n\n    let result = true;\n    for (let cursor = consequenceStart; cursor < consequenceEnd; cursor++) {\n      if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {\n        result = false;\n        break;\n      }\n    }\n\n    if (evaluator.trackMode || evaluator.callbackMode) {\n      evaluator.pushPath(instruction[1]);\n    }\n\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n    return result;\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LogicalWhenType(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (jsonTypeOf(target) !== instruction[5]) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LogicalWhenDefines(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (!Object.hasOwn(target, instruction[5])) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LogicalWhenArraySizeGreater(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target) || target.length <= instruction[5]) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesUnevaluated(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const children = instruction[6];\n  for (const key in target) {\n    if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesUnevaluatedExcept(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const filter = instruction[5];\n  const filterStrings = filter[0];\n  const filterPrefixes = filter[1];\n  const filterRegexes = filter[2];\n  const children = instruction[6];\n  for (const key in target) {\n    if (filterStrings.has(key)) continue;\n    let matched = false;\n    for (let index = 0; index < filterPrefixes.length; index++) {\n      if (key.startsWith(filterPrefixes[index])) { matched = true; break; }\n    }\n    if (matched) continue;\n    for (let index = 0; index < filterRegexes.length; index++) {\n      filterRegexes[index].lastIndex = 0;\n      if (filterRegexes[index].test(key)) { matched = true; break; }\n    }\n    if (matched) continue;\n    if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesMatch(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (const key in target) {\n    const index = instruction[5][key];\n    if (index === undefined) continue;\n    const subinstruction = children[index];\n    const subchildren = subinstruction[6];\n    if (subchildren) {\n      for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {\n        if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesMatchClosed(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (const key in target) {\n    const index = instruction[5][key];\n    if (index === undefined) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    const subinstruction = children[index];\n    const subchildren = subinstruction[6];\n    if (subchildren) {\n      for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {\n        if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopProperties(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (const key in target) {\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesEvaluate(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (const key in target) {\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesRegex(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const regex = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    regex.lastIndex = 0;\n    if (!regex.test(key)) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesRegexClosed(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const regex = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    regex.lastIndex = 0;\n    if (!regex.test(key)) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesStartsWith(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const prefix = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    if (!key.startsWith(prefix)) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesExcept(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const filter = instruction[5];\n  const filterStrings = filter[0];\n  const filterPrefixes = filter[1];\n  const filterRegexes = filter[2];\n  const children = instruction[6];\n  for (const key in target) {\n    if (filterStrings.has(key)) continue;\n    let matched = false;\n    for (let index = 0; index < filterPrefixes.length; index++) {\n      if (key.startsWith(filterPrefixes[index])) { matched = true; break; }\n    }\n    if (matched) continue;\n    for (let index = 0; index < filterRegexes.length; index++) {\n      filterRegexes[index].lastIndex = 0;\n      if (filterRegexes[index].test(key)) { matched = true; break; }\n    }\n    if (matched) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesType(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (const key in target) {\n    const actual = jsonTypeOf(target[key]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesTypeEvaluate(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (const key in target) {\n    const actual = jsonTypeOf(target[key]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesExactlyTypeStrict(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const value = instruction[5];\n  let count = 0;\n  for (const key in target) {\n    count++;\n    if (effectiveTypeStrictReal(target[key]) !== value[0]) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  const __result = count === value[1].length;\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);\n  return __result;\n};\n\nfunction LoopPropertiesExactlyTypeStrictHash(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const value = instruction[5];\n  const entries = value[1][0];\n  const expectedCount = entries.length;\n  let count = 0;\n  for (const key in target) {\n    count++;\n    if (effectiveTypeStrictReal(target[key]) !== value[0]) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (count !== expectedCount) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  for (let index = 0; index < expectedCount; index++) {\n    if (!Object.hasOwn(target, entries[index][1])) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesTypeStrict(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (const key in target) {\n    if (effectiveTypeStrictReal(target[key]) !== expected) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesTypeStrictEvaluate(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (const key in target) {\n    if (effectiveTypeStrictReal(target[key]) !== expected) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesTypeStrictAny(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const bitmask = instruction[5];\n  for (const key in target) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopPropertiesTypeStrictAnyEvaluate(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const bitmask = instruction[5];\n  for (const key in target) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopKeys(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (const key in target) {\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(key);\n    const previousPropertyTarget = evaluator.propertyTarget;\n    evaluator.propertyTarget = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], null, depth + 1, template, evaluator)) {\n          evaluator.propertyTarget = previousPropertyTarget;\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    evaluator.propertyTarget = previousPropertyTarget;\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItems(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (let index = 0; index < target.length; index++) {\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(index);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsFrom(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const startIndex = instruction[5];\n  if (!Array.isArray(target) || startIndex >= target.length) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const children = instruction[6];\n  for (let index = startIndex; index < target.length; index++) {\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(index);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsUnevaluated(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const children = instruction[6];\n  for (let index = 0; index < target.length; index++) {\n    if (evaluator.trackMode && evaluator.isEvaluated(target[index], target, index)) continue;\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(index);\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.popInstanceToken();\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsType(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    const actual = jsonTypeOf(target[index]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[index]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsTypeStrict(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const expected = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    if (effectiveTypeStrictReal(target[index]) !== expected) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsTypeStrictAny(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const bitmask = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[index]))) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsPropertiesExactlyTypeStrictHash(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  const expectedType = instruction[5][0];\n  const entries = instruction[5][1][0];\n  const expectedCount = entries.length;\n  for (let index = 0; index < target.length; index++) {\n    const item = target[index];\n    if (!isObject(item)) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    let count = 0;\n    for (const key in item) {\n      count++;\n      if (effectiveTypeStrictReal(item[key]) !== expectedType) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n    if (count !== expectedCount) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    for (let entry = 0; entry < expectedCount; entry++) {\n      if (!Object.hasOwn(item, entries[entry][1])) {\n        if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n        return false;\n      }\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsIntegerBounded(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target) || target.length === 0) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const minimum = instruction[5][0];\n  const maximum = instruction[5][1];\n  for (let index = 0; index < target.length; index++) {\n    const element = target[index];\n    const elementType = typeof element;\n    if (elementType !== 'number' && elementType !== 'bigint') {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    if (element < minimum || element > maximum) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopItemsIntegerBoundedSized(instruction, instance, depth, template, evaluator) {\n  const value = instruction[5];\n  const minimum = value[0][0];\n  const maximum = value[0][1];\n  const minimumSize = value[1][0];\n  const target = resolveInstance(instance, instruction[2]);\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  if (!Array.isArray(target) || target.length < minimumSize) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n  for (let index = 0; index < target.length; index++) {\n    const element = target[index];\n    const elementType = typeof element;\n    if (elementType !== 'number' && elementType !== 'bigint') {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n    if (element < minimum || element > maximum) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nfunction LoopContains(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  const range = instruction[5];\n  const minimum = range[0];\n  const maximum = range[1];\n  const isExhaustive = range[2];\n  if (minimum === 0 && target.length === 0) return true;\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n\n  const children = instruction[6];\n  let result = false;\n  let matchCount = 0;\n  for (let index = 0; index < target.length; index++) {\n    if (evaluator.callbackMode) evaluator.pushInstanceToken(index);\n    let subresult = true;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {\n          subresult = false;\n          break;\n        }\n      }\n    }\n    if (evaluator.callbackMode) evaluator.popInstanceToken();\n    if (subresult) {\n      matchCount++;\n      if (maximum !== null && matchCount > maximum) {\n        result = false;\n        break;\n      }\n      if (matchCount >= minimum) {\n        result = true;\n        if (maximum === null && !isExhaustive) break;\n      }\n    }\n  }\n\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, result);\n  return result;\n};\n\nfunction ControlGroup(instruction, instance, depth, template, evaluator) {\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], instance, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n};\n\nfunction ControlGroupWhenDefines(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (!Object.hasOwn(target, instruction[5])) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], instance, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n};\n\nfunction ControlGroupWhenDefinesDirect(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  if (!Object.hasOwn(instance, instruction[5])) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], instance, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n};\n\nfunction ControlGroupWhenType(instruction, instance, depth, template, evaluator) {\n  if (jsonTypeOf(instance) !== instruction[5]) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], instance, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n};\n\nfunction ControlEvaluate(instruction, instance, depth, template, evaluator) {\n  if (evaluator.trackMode) {\n    const target = resolveInstance(instance, instruction[5]);\n    evaluator.markEvaluated(target, evaluator.propertyParent, evaluator.propertyKey);\n  }\n  return true;\n};\n\nfunction ControlDynamicAnchorJump(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const resolved = resolveInstance(instance, instruction[2]);\n  const anchor = instruction[5];\n\n  if (!evaluator.resources) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n    return false;\n  }\n\n  const anchors = template[5];\n  for (let index = 0; index < evaluator.resources.length; index++) {\n    const jumpTarget = anchors.get(evaluator.resources[index] + ':' + anchor);\n    if (jumpTarget !== undefined) {\n      for (let childIndex = 0; childIndex < jumpTarget.length; childIndex++) {\n        if (!evaluateInstruction(jumpTarget[childIndex], resolved, depth + 1, template, evaluator)) {\n          if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n          return false;\n        }\n      }\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n      return true;\n    }\n  }\n\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n  return false;\n};\n\nfunction ControlJump(instruction, instance, depth, template, evaluator) {\n  if (evaluator.callbackMode) evaluator.callbackPush(instruction);\n  const jumpTarget = instruction[5];\n  if (!jumpTarget) {\n    if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n    return true;\n  }\n  const resolved = resolveInstance(instance, instruction[2]);\n  for (let index = 0; index < jumpTarget.length; index++) {\n    if (!evaluateInstruction(jumpTarget[index], resolved, depth + 1, template, evaluator)) {\n      if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);\n      return false;\n    }\n  }\n  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);\n  return true;\n};\n\nconst handlers = [\n  AssertionFail,                              // 0\n  AssertionDefines,                           // 1\n  AssertionDefinesStrict,                     // 2\n  AssertionDefinesAll,                        // 3\n  AssertionDefinesAllStrict,                  // 4\n  AssertionDefinesExactly,                    // 5\n  AssertionDefinesExactlyStrict,              // 6\n  AssertionDefinesExactlyStrictHash3,         // 7\n  AssertionPropertyDependencies,              // 8\n  AssertionType,                              // 9\n  AssertionTypeAny,                           // 10\n  AssertionTypeStrict,                        // 11\n  AssertionTypeStrictAny,                     // 12\n  AssertionNotTypeStrictAny,                  // 13\n  AssertionTypeStringBounded,                 // 14\n  AssertionTypeStringUpper,                   // 15\n  AssertionTypeArrayBounded,                  // 16\n  AssertionTypeArrayUpper,                    // 17\n  AssertionTypeObjectBounded,                 // 18\n  AssertionTypeObjectUpper,                   // 19\n  AssertionRegex,                             // 20\n  AssertionStringSizeLess,                    // 21\n  AssertionStringSizeGreater,                 // 22\n  AssertionArraySizeLess,                     // 23\n  AssertionArraySizeGreater,                  // 24\n  AssertionObjectSizeLess,                    // 25\n  AssertionObjectSizeGreater,                 // 26\n  AssertionEqual,                             // 27\n  AssertionEqualsAny,                         // 28\n  AssertionEqualsAnyStringHash,               // 29\n  AssertionGreaterEqual,                      // 30\n  AssertionLessEqual,                         // 31\n  AssertionGreater,                           // 32\n  AssertionLess,                              // 33\n  AssertionUnique,                            // 34\n  AssertionDivisible,                         // 35\n  AssertionTypeIntegerBounded,                // 36\n  AssertionTypeIntegerBoundedStrict,          // 37\n  AssertionTypeIntegerLowerBound,             // 38\n  AssertionTypeIntegerLowerBoundStrict,       // 39\n  AssertionStringType,                        // 40\n  AssertionPropertyType,                      // 41\n  AssertionPropertyTypeEvaluate,              // 42\n  AssertionPropertyTypeStrict,                // 43\n  AssertionPropertyTypeStrictEvaluate,        // 44\n  AssertionPropertyTypeStrictAny,             // 45\n  AssertionPropertyTypeStrictAnyEvaluate,     // 46\n  AssertionArrayPrefix,                       // 47\n  AssertionArrayPrefixEvaluate,               // 48\n  AssertionObjectPropertiesSimple,            // 49\n  AnnotationEmit,                             // 50\n  AnnotationToParent,                         // 51\n  AnnotationBasenameToParent,                 // 52\n  Evaluate,                                   // 53\n  LogicalNot,                                 // 54\n  LogicalNotEvaluate,                         // 55\n  LogicalOr,                                  // 56\n  LogicalAnd,                                 // 57\n  LogicalXor,                                 // 58\n  LogicalCondition,                           // 59\n  LogicalWhenType,                            // 60\n  LogicalWhenDefines,                         // 61\n  LogicalWhenArraySizeGreater,                // 62\n  LoopPropertiesUnevaluated,                  // 63\n  LoopPropertiesUnevaluatedExcept,            // 64\n  LoopPropertiesMatch,                        // 65\n  LoopPropertiesMatchClosed,                  // 66\n  LoopProperties,                             // 67\n  LoopPropertiesEvaluate,                     // 68\n  LoopPropertiesRegex,                        // 69\n  LoopPropertiesRegexClosed,                  // 70\n  LoopPropertiesStartsWith,                   // 71\n  LoopPropertiesExcept,                       // 72\n  LoopPropertiesType,                         // 73\n  LoopPropertiesTypeEvaluate,                 // 74\n  LoopPropertiesExactlyTypeStrict,            // 75\n  LoopPropertiesExactlyTypeStrictHash,        // 76\n  LoopPropertiesTypeStrict,                   // 77\n  LoopPropertiesTypeStrictEvaluate,           // 78\n  LoopPropertiesTypeStrictAny,                // 79\n  LoopPropertiesTypeStrictAnyEvaluate,        // 80\n  LoopKeys,                                   // 81\n  LoopItems,                                  // 82\n  LoopItemsFrom,                              // 83\n  LoopItemsUnevaluated,                       // 84\n  LoopItemsType,                              // 85\n  LoopItemsTypeStrict,                        // 86\n  LoopItemsTypeStrictAny,                     // 87\n  LoopItemsPropertiesExactlyTypeStrictHash,   // 88\n  LoopItemsPropertiesExactlyTypeStrictHash,   // 89\n  LoopItemsIntegerBounded,                    // 90\n  LoopItemsIntegerBoundedSized,               // 91\n  LoopContains,                               // 92\n  ControlGroup,                               // 93\n  ControlGroupWhenDefines,                    // 94\n  ControlGroupWhenDefinesDirect,              // 95\n  ControlGroupWhenType,                       // 96\n  ControlEvaluate,                            // 97\n  ControlDynamicAnchorJump,                   // 98\n  ControlJump                                 // 99\n];\n\nfunction AssertionTypeArrayBounded_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return false;\n  const range = instruction[5];\n  if (target.length < range[0]) return false;\n  if (range[1] !== null && target.length > range[1]) return false;\n  return true;\n}\n\nfunction LoopItemsTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return true;\n  const bitmask = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[index]))) return false;\n  }\n  return true;\n}\n\nfunction AssertionPropertyTypeStrict_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  return effectiveTypeStrictReal(target) === instruction[5];\n}\n\nfunction AssertionTypeStrict_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  return effectiveTypeStrictReal(target) === instruction[5];\n}\n\nfunction AssertionDefinesAllStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  const strings = instruction[5];\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) return false;\n  }\n  return true;\n}\n\nfunction AssertionEqual_fast(instruction, instance, depth, template, evaluator) {\n  if (evaluator.propertyTarget !== undefined) {\n    const value = instruction[5];\n    return typeof value === 'string' && value === evaluator.propertyTarget;\n  }\n  return jsonEqual(resolveInstance(instance, instruction[2]), instruction[5]);\n}\n\nfunction LoopPropertiesMatch_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    const index = instruction[5][key];\n    if (index === undefined) continue;\n    const subinstruction = children[index];\n    const subchildren = subinstruction[6];\n    if (subchildren) {\n      for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {\n        if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  return true;\n}\n\nfunction LogicalOr_fast(instruction, instance, depth, template, evaluator) {\n  const children = instruction[6];\n  if (!children || children.length === 0) return true;\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const exhaustive = instruction[5];\n  let result = false;\n  if (exhaustive) {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) result = true;\n    }\n  } else {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return true;\n    }\n  }\n  return result;\n}\n\nfunction ControlJump_fast(instruction, instance, depth, template, evaluator) {\n  const jumpTarget = instruction[5];\n  if (!jumpTarget) return true;\n  const relInstance = instruction[2];\n  const resolved = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  for (let index = 0; index < jumpTarget.length; index++) {\n    if (!evaluateInstruction(jumpTarget[index], resolved, depth + 1, template, evaluator)) return false;\n  }\n  return true;\n}\n\nfunction AssertionEqualsAnyStringHash_fast(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget\n    : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return false;\n  const value = instruction[5];\n  const entries = value[0];\n  const tableOfContents = value[1];\n  const stringSize = target.length;\n  if (stringSize < tableOfContents.length) {\n    const hint = tableOfContents[stringSize];\n    if (hint[1] === 0) return false;\n    for (let index = hint[0] - 1; index < hint[1]; index++) {\n      if (entries[index][1] === target) return true;\n    }\n  }\n  return false;\n}\n\nfunction LogicalXor_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const exhaustive = instruction[5];\n  const children = instruction[6];\n  let result = true;\n  let hasMatched = false;\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        if (hasMatched) {\n          result = false;\n          if (!exhaustive) break;\n        } else {\n          hasMatched = true;\n        }\n      }\n    }\n  }\n  return result && hasMatched;\n}\n\nfunction AssertionDefinesStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  return isObject(target) && Object.hasOwn(target, instruction[5]);\n}\n\nfunction LoopItems_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return true;\n  const children = instruction[6];\n  for (let index = 0; index < target.length; index++) {\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  return true;\n}\n\nfunction LoopPropertiesMatchClosed_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    const index = instruction[5][key];\n    if (index === undefined) return false;\n    const subinstruction = children[index];\n    const subchildren = subinstruction[6];\n    if (subchildren) {\n      for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {\n        if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  return true;\n}\n\nfunction LogicalAnd_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction AssertionTypeStringBounded_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (typeof target !== 'string') return false;\n  const range = instruction[5];\n  const length = unicodeLength(target);\n  if (length < range[0]) return false;\n  return range[1] === null || length <= range[1];\n}\n\nfunction AssertionPropertyDependencies_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  const value = instruction[5];\n  for (const property in value) {\n    if (!Object.hasOwn(target, property)) continue;\n    const dependencies = value[property];\n    for (let index = 0; index < dependencies.length; index++) {\n      if (!Object.hasOwn(target, dependencies[index])) return false;\n    }\n  }\n  return true;\n}\n\nfunction AssertionTypeAny_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const bitmask = instruction[5];\n  const typeIndex = jsonTypeOf(target);\n  if (typeSetTest(bitmask, typeIndex)) return true;\n  return typeSetTest(bitmask, Type.Integer) && isIntegral(target);\n}\n\nfunction LogicalCondition_fast(instruction, instance, depth, template, evaluator) {\n  const value = instruction[5];\n  const thenStart = value[0];\n  const elseStart = value[1];\n  const children = instruction[6];\n  const childrenSize = children ? children.length : 0;\n  let conditionEnd = childrenSize;\n  if (thenStart > 0) conditionEnd = thenStart;\n  else if (elseStart > 0) conditionEnd = elseStart;\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  let conditionResult = true;\n  for (let cursor = 0; cursor < conditionEnd; cursor++) {\n    if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {\n      conditionResult = false;\n      break;\n    }\n  }\n  const consequenceStart = conditionResult ? thenStart : elseStart;\n  const consequenceEnd = (conditionResult && elseStart > 0) ? elseStart : childrenSize;\n  if (consequenceStart > 0) {\n    if (evaluator.trackMode) {\n      evaluator.popPath(instruction[1].length);\n    }\n    let result = true;\n    for (let cursor = consequenceStart; cursor < consequenceEnd; cursor++) {\n      if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {\n        result = false;\n        break;\n      }\n    }\n    if (evaluator.trackMode) {\n      evaluator.pushPath(instruction[1]);\n    }\n    return result;\n  }\n  return true;\n}\n\nfunction LoopPropertiesExcept_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const filter = instruction[5];\n  const filterStrings = filter[0];\n  const filterPrefixes = filter[1];\n  const filterRegexes = filter[2];\n  const children = instruction[6];\n  for (const key in target) {\n    if (filterStrings.has(key)) continue;\n    let matched = false;\n    for (let index = 0; index < filterPrefixes.length; index++) {\n      if (key.startsWith(filterPrefixes[index])) { matched = true; break; }\n    }\n    if (matched) continue;\n    for (let index = 0; index < filterRegexes.length; index++) {\n      filterRegexes[index].lastIndex = 0;\n      if (filterRegexes[index].test(key)) { matched = true; break; }\n    }\n    if (matched) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  return true;\n}\n\nfunction AssertionRegex_fast(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  return instruction[5].test(target);\n}\n\nfunction LoopProperties_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  return true;\n}\n\nfunction AssertionDefines_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  return Object.hasOwn(target, instruction[5]);\n}\n\nfunction LogicalWhenType_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (jsonTypeOf(target) !== instruction[5]) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction LogicalWhenDefines_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (!Object.hasOwn(target, instruction[5])) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction AssertionFail_fast() { return false; }\n\nfunction LoopContains_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return true;\n  const range = instruction[5];\n  const minimum = range[0];\n  const maximum = range[1];\n  const isExhaustive = range[2];\n  if (minimum === 0 && target.length === 0) return true;\n  const children = instruction[6];\n  let matchCount = 0;\n  for (let index = 0; index < target.length; index++) {\n    let subresult = true;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {\n          subresult = false;\n          break;\n        }\n      }\n    }\n    if (subresult) {\n      matchCount++;\n      if (maximum !== null && matchCount > maximum) return false;\n      if (matchCount >= minimum && maximum === null && !isExhaustive) return true;\n    }\n  }\n  return matchCount >= minimum;\n}\n\nfunction LogicalNot_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return true;\n    }\n  }\n  return false;\n}\n\nfunction LoopItemsType_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return true;\n  const expected = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    const actual = jsonTypeOf(target[index]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[index]))) return false;\n  }\n  return true;\n}\n\nfunction LoopItemsTypeStrict_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!Array.isArray(target)) return true;\n  const expected = instruction[5];\n  for (let index = 0; index < target.length; index++) {\n    if (effectiveTypeStrictReal(target[index]) !== expected) return false;\n  }\n  return true;\n}\n\nfunction AssertionEqualsAny_fast(instruction, instance, depth, template, evaluator) {\n  const value = instruction[5];\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (value.primitive) return value.set.has(target);\n  const values = Array.isArray(value) ? value : value.values;\n  for (let index = 0; index < values.length; index++) {\n    if (jsonEqual(target, values[index])) return true;\n  }\n  return false;\n}\n\nfunction AssertionDefinesAll_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  const strings = instruction[5];\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) return false;\n  }\n  return true;\n}\n\nfunction AssertionDefinesExactly_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  let targetSize = 0;\n  for (const key in target) targetSize++;\n  const strings = instruction[5];\n  if (targetSize !== strings.length) return false;\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) return false;\n  }\n  return true;\n}\n\nfunction AssertionDefinesExactlyStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  let targetSize = 0;\n  for (const key in target) targetSize++;\n  const strings = instruction[5];\n  if (targetSize !== strings.length) return false;\n  for (let index = 0; index < strings.length; index++) {\n    if (!Object.hasOwn(target, strings[index])) return false;\n  }\n  return true;\n}\n\nfunction AssertionDefinesExactlyStrictHash3_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  const entries = instruction[5][0];\n  let count = 0;\n  for (const key in target) count++;\n  if (count !== 3) return false;\n  return Object.hasOwn(target, entries[0][1]) &&\n    Object.hasOwn(target, entries[1][1]) &&\n    Object.hasOwn(target, entries[2][1]);\n}\n\nfunction AssertionType_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  if (actual === expected) return true;\n  return expected === Type.Integer && isIntegral(target);\n}\n\nfunction AssertionTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  return typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n}\n\nfunction AssertionNotTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  return !typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n}\n\nfunction AssertionTypeStringUpper_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  return typeof target === 'string' && unicodeLength(target) <= instruction[5];\n}\n\nfunction AssertionTypeArrayUpper_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  return Array.isArray(target) && target.length <= instruction[5];\n}\n\nfunction AssertionTypeObjectBounded_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return false;\n  const range = instruction[5];\n  const size = objectSize(target);\n  if (size < range[0]) return false;\n  return range[1] === null || size <= range[1];\n}\n\nfunction AssertionTypeObjectUpper_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return false;\n  return objectSize(target) <= instruction[5];\n}\n\nfunction AssertionStringSizeLess_fast(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  return unicodeLength(target) < instruction[5];\n}\n\nfunction AssertionStringSizeGreater_fast(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  return unicodeLength(target) > instruction[5];\n}\n\nfunction AssertionArraySizeLess_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  return target.length < instruction[5];\n}\n\nfunction AssertionArraySizeGreater_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  return target.length > instruction[5];\n}\n\nfunction AssertionObjectSizeLess_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  return objectSize(target) < instruction[5];\n}\n\nfunction AssertionObjectSizeGreater_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  return objectSize(target) > instruction[5];\n}\n\nfunction AssertionGreaterEqual_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  return target >= instruction[5];\n}\n\nfunction AssertionLessEqual_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  return target <= instruction[5];\n}\n\nfunction AssertionGreater_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  return target > instruction[5];\n}\n\nfunction AssertionLess_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  return target < instruction[5];\n}\n\nfunction AssertionUnique_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  return isUnique(target);\n}\n\nfunction AssertionDivisible_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const targetType = typeof target;\n  if (targetType !== 'number' && targetType !== 'bigint') return true;\n  return isDivisibleBy(target, instruction[5]);\n}\n\nfunction AssertionStringType_fast(instruction, instance, depth, template, evaluator) {\n  const target = evaluator.propertyTarget !== undefined\n    ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);\n  if (typeof target !== 'string') return true;\n  return URI_REGEX.test(target);\n}\n\nfunction AssertionPropertyType_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  return actual === expected || (expected === Type.Integer && isIntegral(target));\n}\n\nfunction AssertionPropertyTypeEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  const expected = instruction[5];\n  const actual = jsonTypeOf(target);\n  const result = actual === expected || (expected === Type.Integer && isIntegral(target));\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  return result;\n}\n\nfunction AssertionPropertyTypeStrictEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  const result = effectiveTypeStrictReal(target) === instruction[5];\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  return result;\n}\n\nfunction AssertionPropertyTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  return typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n}\n\nfunction AssertionPropertyTypeStrictAnyEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  if (!isObject(instance)) return true;\n  const target = resolveInstance(instance, instruction[2]);\n  if (target === undefined) return true;\n  const result = typeSetTest(instruction[5], effectiveTypeStrictReal(target));\n  if (result && evaluator.trackMode) {\n    const location = instruction[2];\n    evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);\n  }\n  return result;\n}\n\nfunction AssertionArrayPrefix_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (target.length === 0) return true;\n  const children = instruction[6];\n  const prefixes = children.length - 1;\n  const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;\n  const entry = children[pointer];\n  const entryChildren = entry[6];\n  if (entryChildren) {\n    for (let index = 0; index < entryChildren.length; index++) {\n      if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction AssertionArrayPrefixEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (target.length === 0) return true;\n  const children = instruction[6];\n  const prefixes = children.length - 1;\n  const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;\n  const entry = children[pointer];\n  const entryChildren = entry[6];\n  if (entryChildren) {\n    for (let index = 0; index < entryChildren.length; index++) {\n      if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  if (evaluator.trackMode) {\n    if (target.length === prefixes) {\n      evaluator.markEvaluated(target);\n    } else {\n      for (let cursor = 0; cursor <= pointer; cursor++) {\n        evaluator.markEvaluated(target[cursor], target, cursor);\n      }\n    }\n  }\n  return true;\n}\n\nfunction AssertionObjectPropertiesSimple_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  const value = instruction[5];\n  const children = instruction[6];\n  for (let index = 0; index < value.length; index++) {\n    const entry = value[index];\n    const name = entry[0];\n    const required = entry[2];\n    if (!Object.hasOwn(target, name)) {\n      if (required) return false;\n      continue;\n    }\n    if (index < children.length) {\n      if (!evaluateInstructionFast(children[index], target[name], depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction AnnotationEmit_fast() { return true; }\nfunction AnnotationToParent_fast() { return true; }\nfunction AnnotationBasenameToParent_fast() { return true; }\n\nfunction Evaluate_fast(instruction, instance, depth, template, evaluator) {\n  if (evaluator.trackMode) {\n    const target = resolveInstance(instance, instruction[2]);\n    evaluator.markEvaluated(target);\n  }\n  return true;\n}\n\nfunction LogicalNotEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  const children = instruction[6];\n  let result = false;\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {\n        result = true;\n        break;\n      }\n    }\n  }\n  if (evaluator.trackMode) evaluator.unevaluate();\n  return result;\n}\n\nfunction LogicalWhenArraySizeGreater_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target) || target.length <= instruction[5]) return true;\n  const children = instruction[6];\n  if (children) {\n    for (let index = 0; index < children.length; index++) {\n      if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;\n    }\n  }\n  return true;\n}\n\nfunction LoopPropertiesUnevaluated_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopPropertiesUnevaluatedExcept_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;\n  const filter = instruction[5];\n  const filterStrings = filter[0];\n  const filterPrefixes = filter[1];\n  const filterRegexes = filter[2];\n  const children = instruction[6];\n  for (const key in target) {\n    if (filterStrings.has(key)) continue;\n    let matched = false;\n    for (let index = 0; index < filterPrefixes.length; index++) {\n      if (key.startsWith(filterPrefixes[index])) { matched = true; break; }\n    }\n    if (matched) continue;\n    for (let index = 0; index < filterRegexes.length; index++) {\n      filterRegexes[index].lastIndex = 0;\n      if (filterRegexes[index].test(key)) { matched = true; break; }\n    }\n    if (matched) continue;\n    if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopPropertiesEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopPropertiesRegex_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const regex = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    regex.lastIndex = 0;\n    if (!regex.test(key)) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  return true;\n}\n\nfunction LoopPropertiesRegexClosed_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const regex = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    regex.lastIndex = 0;\n    if (!regex.test(key)) return false;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  return true;\n}\n\nfunction LoopPropertiesStartsWith_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const prefix = instruction[5];\n  const children = instruction[6];\n  for (const key in target) {\n    if (!key.startsWith(prefix)) continue;\n    evaluator.propertyParent = target;\n    evaluator.propertyKey = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {\n          evaluator.propertyParent = undefined;\n          evaluator.propertyKey = undefined;\n          return false;\n        }\n      }\n    }\n  }\n  evaluator.propertyParent = undefined;\n  evaluator.propertyKey = undefined;\n  return true;\n}\n\nfunction LoopPropertiesType_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const expected = instruction[5];\n  for (const key in target) {\n    const actual = jsonTypeOf(target[key]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) return false;\n  }\n  return true;\n}\n\nfunction LoopPropertiesTypeEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const expected = instruction[5];\n  for (const key in target) {\n    const actual = jsonTypeOf(target[key]);\n    if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) return false;\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopPropertiesExactlyTypeStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  const value = instruction[5];\n  let count = 0;\n  for (const key in target) {\n    count++;\n    if (effectiveTypeStrictReal(target[key]) !== value[0]) return false;\n  }\n  return count === value[1].length;\n}\n\nfunction LoopPropertiesExactlyTypeStrictHash_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return false;\n  const value = instruction[5];\n  const entries = value[1][0];\n  const expectedCount = entries.length;\n  let count = 0;\n  for (const key in target) {\n    count++;\n    if (effectiveTypeStrictReal(target[key]) !== value[0]) return false;\n  }\n  if (count !== expectedCount) return false;\n  for (let index = 0; index < expectedCount; index++) {\n    if (!Object.hasOwn(target, entries[index][1])) return false;\n  }\n  return true;\n}\n\nfunction LoopPropertiesTypeStrict_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const expected = instruction[5];\n  for (const key in target) {\n    if (effectiveTypeStrictReal(target[key]) !== expected) return false;\n  }\n  return true;\n}\n\nfunction LoopPropertiesTypeStrictEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const expected = instruction[5];\n  for (const key in target) {\n    if (effectiveTypeStrictReal(target[key]) !== expected) return false;\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopPropertiesTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const bitmask = instruction[5];\n  for (const key in target) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) return false;\n  }\n  return true;\n}\n\nfunction LoopPropertiesTypeStrictAnyEvaluate_fast(instruction, instance, depth, template, evaluator) {\n  const relInstance = instruction[2];\n  const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);\n  if (!isObject(target)) return true;\n  const bitmask = instruction[5];\n  for (const key in target) {\n    if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) return false;\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopKeys_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!isObject(target)) return true;\n  const children = instruction[6];\n  for (const key in target) {\n    const previousPropertyTarget = evaluator.propertyTarget;\n    evaluator.propertyTarget = key;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], null, depth + 1, template, evaluator)) {\n          evaluator.propertyTarget = previousPropertyTarget;\n          return false;\n        }\n      }\n    }\n    evaluator.propertyTarget = previousPropertyTarget;\n  }\n  return true;\n}\n\nfunction LoopItemsFrom_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const startIndex = instruction[5];\n  if (!Array.isArray(target) || startIndex >= target.length) return true;\n  const children = instruction[6];\n  for (let index = startIndex; index < target.length; index++) {\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  return true;\n}\n\nfunction LoopItemsUnevaluated_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return true;\n  if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;\n  const children = instruction[6];\n  for (let index = 0; index < target.length; index++) {\n    if (evaluator.trackMode && evaluator.isEvaluated(target[index], target, index)) continue;\n    if (children) {\n      for (let childIndex = 0; childIndex < children.length; childIndex++) {\n        if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;\n      }\n    }\n  }\n  if (evaluator.trackMode) evaluator.markEvaluated(target);\n  return true;\n}\n\nfunction LoopItemsPropertiesExactlyTypeStrictHash_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target)) return false;\n  const expectedType = instruction[5][0];\n  const entries = instruction[5][1][0];\n  const expectedCount = entries.length;\n  for (let index = 0; index < target.length; index++) {\n    const item = target[index];\n    if (!isObject(item)) return false;\n    let count = 0;\n    for (const key in item) {\n      count++;\n      if (effectiveTypeStrictReal(item[key]) !== expectedType) return false;\n    }\n    if (count !== expectedCount) return false;\n    for (let entry = 0; entry < expectedCount; entry++) {\n      if (!Object.hasOwn(item, entries[entry][1])) return false;\n    }\n  }\n  return true;\n}\n\nfunction ControlDynamicAnchorJump_fast(instruction, instance, depth, template, evaluator) {\n  const resolved = resolveInstance(instance, instruction[2]);\n  const anchor = instruction[5];\n  if (!evaluator.resources) return false;\n  const anchors = template[5];\n  for (let index = 0; index < evaluator.resources.length; index++) {\n    const jumpTarget = anchors.get(evaluator.resources[index] + ':' + anchor);\n    if (jumpTarget !== undefined) {\n      for (let childIndex = 0; childIndex < jumpTarget.length; childIndex++) {\n        if (!evaluateInstruction(jumpTarget[childIndex], resolved, depth + 1, template, evaluator)) return false;\n      }\n      return true;\n    }\n  }\n  return false;\n}\n\nfunction LoopItemsIntegerBounded_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target) || target.length === 0) return true;\n  const minimum = instruction[5][0];\n  const maximum = instruction[5][1];\n  for (let index = 0; index < target.length; index++) {\n    const element = target[index];\n    const elementType = typeof element;\n    if ((elementType !== 'number' && elementType !== 'bigint') || element < minimum || element > maximum) return false;\n  }\n  return true;\n}\n\nfunction LoopItemsIntegerBoundedSized_fast(instruction, instance, depth, template, evaluator) {\n  const value = instruction[5];\n  const minimum = value[0][0];\n  const maximum = value[0][1];\n  const minimumSize = value[1][0];\n  const target = resolveInstance(instance, instruction[2]);\n  if (!Array.isArray(target) || target.length < minimumSize) return false;\n  for (let index = 0; index < target.length; index++) {\n    const element = target[index];\n    const elementType = typeof element;\n    if ((elementType !== 'number' && elementType !== 'bigint') || element < minimum || element > maximum) return false;\n  }\n  return true;\n}\n\nfunction AssertionTypeIntegerBounded_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const range = instruction[5];\n  return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];\n}\n\nfunction AssertionTypeIntegerBoundedStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const range = instruction[5];\n  return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];\n}\n\nfunction AssertionTypeIntegerLowerBound_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const range = instruction[5];\n  return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];\n}\n\nfunction AssertionTypeIntegerLowerBoundStrict_fast(instruction, instance, depth, template, evaluator) {\n  const target = resolveInstance(instance, instruction[2]);\n  const range = instruction[5];\n  return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];\n}\n\nconst fastHandlers = handlers.slice();\nfastHandlers[16] = AssertionTypeArrayBounded_fast;\nfastHandlers[87] = LoopItemsTypeStrictAny_fast;\nfastHandlers[43] = AssertionPropertyTypeStrict_fast;\nfastHandlers[11] = AssertionTypeStrict_fast;\nfastHandlers[4] = AssertionDefinesAllStrict_fast;\nfastHandlers[27] = AssertionEqual_fast;\nfastHandlers[65] = LoopPropertiesMatch_fast;\nfastHandlers[56] = LogicalOr_fast;\nfastHandlers[99] = ControlJump_fast;\nfastHandlers[29] = AssertionEqualsAnyStringHash_fast;\nfastHandlers[58] = LogicalXor_fast;\nfastHandlers[2] = AssertionDefinesStrict_fast;\nfastHandlers[82] = LoopItems_fast;\nfastHandlers[66] = LoopPropertiesMatchClosed_fast;\nfastHandlers[14] = AssertionTypeStringBounded_fast;\nfastHandlers[57] = LogicalAnd_fast;\nfastHandlers[8] = AssertionPropertyDependencies_fast;\nfastHandlers[10] = AssertionTypeAny_fast;\nfastHandlers[59] = LogicalCondition_fast;\nfastHandlers[72] = LoopPropertiesExcept_fast;\nfastHandlers[20] = AssertionRegex_fast;\nfastHandlers[67] = LoopProperties_fast;\nfastHandlers[1] = AssertionDefines_fast;\nfastHandlers[60] = LogicalWhenType_fast;\nfastHandlers[61] = LogicalWhenDefines_fast;\nfastHandlers[0] = AssertionFail_fast;\nfastHandlers[92] = LoopContains_fast;\nfastHandlers[54] = LogicalNot_fast;\nfastHandlers[85] = LoopItemsType_fast;\nfastHandlers[86] = LoopItemsTypeStrict_fast;\nfastHandlers[28] = AssertionEqualsAny_fast;\nfastHandlers[3] = AssertionDefinesAll_fast;\nfastHandlers[5] = AssertionDefinesExactly_fast;\nfastHandlers[6] = AssertionDefinesExactlyStrict_fast;\nfastHandlers[7] = AssertionDefinesExactlyStrictHash3_fast;\nfastHandlers[9] = AssertionType_fast;\nfastHandlers[12] = AssertionTypeStrictAny_fast;\nfastHandlers[13] = AssertionNotTypeStrictAny_fast;\nfastHandlers[15] = AssertionTypeStringUpper_fast;\nfastHandlers[17] = AssertionTypeArrayUpper_fast;\nfastHandlers[18] = AssertionTypeObjectBounded_fast;\nfastHandlers[19] = AssertionTypeObjectUpper_fast;\nfastHandlers[21] = AssertionStringSizeLess_fast;\nfastHandlers[22] = AssertionStringSizeGreater_fast;\nfastHandlers[23] = AssertionArraySizeLess_fast;\nfastHandlers[24] = AssertionArraySizeGreater_fast;\nfastHandlers[25] = AssertionObjectSizeLess_fast;\nfastHandlers[26] = AssertionObjectSizeGreater_fast;\nfastHandlers[30] = AssertionGreaterEqual_fast;\nfastHandlers[31] = AssertionLessEqual_fast;\nfastHandlers[32] = AssertionGreater_fast;\nfastHandlers[33] = AssertionLess_fast;\nfastHandlers[34] = AssertionUnique_fast;\nfastHandlers[35] = AssertionDivisible_fast;\nfastHandlers[36] = AssertionTypeIntegerBounded_fast;\nfastHandlers[37] = AssertionTypeIntegerBoundedStrict_fast;\nfastHandlers[38] = AssertionTypeIntegerLowerBound_fast;\nfastHandlers[39] = AssertionTypeIntegerLowerBoundStrict_fast;\nfastHandlers[40] = AssertionStringType_fast;\nfastHandlers[41] = AssertionPropertyType_fast;\nfastHandlers[42] = AssertionPropertyTypeEvaluate_fast;\nfastHandlers[44] = AssertionPropertyTypeStrictEvaluate_fast;\nfastHandlers[45] = AssertionPropertyTypeStrictAny_fast;\nfastHandlers[46] = AssertionPropertyTypeStrictAnyEvaluate_fast;\nfastHandlers[47] = AssertionArrayPrefix_fast;\nfastHandlers[48] = AssertionArrayPrefixEvaluate_fast;\nfastHandlers[49] = AssertionObjectPropertiesSimple_fast;\nfastHandlers[50] = AnnotationEmit_fast;\nfastHandlers[51] = AnnotationToParent_fast;\nfastHandlers[52] = AnnotationBasenameToParent_fast;\nfastHandlers[53] = Evaluate_fast;\nfastHandlers[55] = LogicalNotEvaluate_fast;\nfastHandlers[62] = LogicalWhenArraySizeGreater_fast;\nfastHandlers[63] = LoopPropertiesUnevaluated_fast;\nfastHandlers[64] = LoopPropertiesUnevaluatedExcept_fast;\nfastHandlers[68] = LoopPropertiesEvaluate_fast;\nfastHandlers[69] = LoopPropertiesRegex_fast;\nfastHandlers[70] = LoopPropertiesRegexClosed_fast;\nfastHandlers[71] = LoopPropertiesStartsWith_fast;\nfastHandlers[73] = LoopPropertiesType_fast;\nfastHandlers[74] = LoopPropertiesTypeEvaluate_fast;\nfastHandlers[75] = LoopPropertiesExactlyTypeStrict_fast;\nfastHandlers[76] = LoopPropertiesExactlyTypeStrictHash_fast;\nfastHandlers[77] = LoopPropertiesTypeStrict_fast;\nfastHandlers[78] = LoopPropertiesTypeStrictEvaluate_fast;\nfastHandlers[79] = LoopPropertiesTypeStrictAny_fast;\nfastHandlers[80] = LoopPropertiesTypeStrictAnyEvaluate_fast;\nfastHandlers[81] = LoopKeys_fast;\nfastHandlers[83] = LoopItemsFrom_fast;\nfastHandlers[84] = LoopItemsUnevaluated_fast;\nfastHandlers[88] = LoopItemsPropertiesExactlyTypeStrictHash_fast;\nfastHandlers[89] = LoopItemsPropertiesExactlyTypeStrictHash_fast;\nfastHandlers[90] = LoopItemsIntegerBounded_fast;\nfastHandlers[91] = LoopItemsIntegerBoundedSized_fast;\nfastHandlers[98] = ControlDynamicAnchorJump_fast;\n\nimport { describe } from './describe.mjs';\n\nconst STANDARD_MASK_KEYWORDS =\n  new Set([ 'anyOf', 'oneOf', 'not', 'if', 'contains' ]);\n\nfunction isAnnotationOpcode(opcode) {\n  return opcode >= ANNOTATION_EMIT && opcode <= ANNOTATION_BASENAME_TO_PARENT;\n}\n\nfunction lastEvaluatePathToken(evaluatePath) {\n  const lastSlash = evaluatePath.lastIndexOf('/');\n  if (lastSlash < 0) return '';\n  return evaluatePath.slice(lastSlash + 1);\n}\n\nfunction isPathPrefix(path, prefix) {\n  if (path === prefix) return true;\n  return path.startsWith(prefix) && path[prefix.length] === '/';\n}\n\nfunction maskKey(evaluatePath, instanceLocation) {\n  return evaluatePath + '\\u0000' + instanceLocation;\n}\n\nclass SimpleOutput {\n  constructor(instance) {\n    this.instance = instance;\n    this.errors = [];\n    this.mask = [];\n    this.maskedTraces = new Map();\n    this.annotations = new Map();\n  }\n\n  callback(type, valid, instruction, evaluatePath, instanceLocation, annotation) {\n    if (evaluatePath === '') return;\n\n    const opcode = instruction[0];\n    const isAnnotation = isAnnotationOpcode(opcode);\n    const keyword = lastEvaluatePathToken(evaluatePath);\n\n    if (valid && !isAnnotation) {\n      if (type === 'pre' && STANDARD_MASK_KEYWORDS.has(keyword)) {\n        this.mask.push({\n          evaluatePath, instanceLocation,\n          key: maskKey(evaluatePath, instanceLocation)\n        });\n      } else if (type === 'post' && this.mask.length > 0) {\n        const top = this.mask[this.mask.length - 1];\n        if (top.evaluatePath === evaluatePath &&\n            top.instanceLocation === instanceLocation) {\n          this.maskedTraces.delete(top.key);\n          this.mask.pop();\n        }\n      }\n      return;\n    }\n\n    if (isAnnotation) {\n      if (type !== 'post') return;\n      const annotationKey =\n        evaluatePath + '\\u0000' + instanceLocation + '\\u0000' + instruction[3];\n      let bucket = this.annotations.get(annotationKey);\n      if (bucket === undefined) {\n        bucket = {\n          keywordLocation: evaluatePath,\n          absoluteKeywordLocation: instruction[3],\n          instanceLocation,\n          annotation: [ annotation ]\n        };\n        this.annotations.set(annotationKey, bucket);\n      } else {\n        const last = bucket.annotation[bucket.annotation.length - 1];\n        let isSame = last === annotation;\n        if (!isSame && Array.isArray(last) && Array.isArray(annotation) &&\n            last.length === annotation.length) {\n          isSame = last.every((value, index) => value === annotation[index]);\n        }\n        if (!isSame) bucket.annotation.push(annotation);\n      }\n      return;\n    }\n\n    if (type === 'pre') {\n      if (STANDARD_MASK_KEYWORDS.has(keyword)) {\n        this.mask.push({\n          evaluatePath, instanceLocation,\n          key: maskKey(evaluatePath, instanceLocation)\n        });\n      }\n      return;\n    }\n\n    const currentKey = maskKey(evaluatePath, instanceLocation);\n    const matchIndex = this.mask.findIndex(entry => entry.key === currentKey);\n    if (matchIndex >= 0) {\n      if (!valid && keyword !== 'not' && keyword !== 'if') {\n        const buffered = this.maskedTraces.get(currentKey);\n        if (buffered !== undefined) {\n          for (const entry of buffered) this.errors.push(entry);\n          this.maskedTraces.delete(currentKey);\n        }\n      } else {\n        this.maskedTraces.delete(currentKey);\n      }\n      this.mask.splice(matchIndex, 1);\n    }\n\n    if (valid) return;\n\n    if (this.annotations.size > 0) {\n      const lastSlash = evaluatePath.lastIndexOf('/');\n      const parentPath = lastSlash <= 0 ? '' : evaluatePath.slice(0, lastSlash);\n      for (const [ key, value ] of this.annotations) {\n        if (value.instanceLocation === instanceLocation &&\n            (parentPath === '' ||\n             isPathPrefix(value.keywordLocation, parentPath))) {\n          this.annotations.delete(key);\n        }\n      }\n    }\n\n    if (keyword === 'if') return;\n\n    const entry = {\n      keywordLocation: evaluatePath,\n      absoluteKeywordLocation: instruction[3],\n      instanceLocation,\n      error: describe(valid, instruction, evaluatePath, instanceLocation,\n                      this.instance, annotation)\n    };\n\n    for (const maskEntry of this.mask) {\n      if (isPathPrefix(evaluatePath, maskEntry.evaluatePath)) {\n        let buffer = this.maskedTraces.get(maskEntry.key);\n        if (buffer === undefined) {\n          buffer = [];\n          this.maskedTraces.set(maskEntry.key, buffer);\n        }\n        buffer.push(entry);\n        return;\n      }\n    }\n\n    this.errors.push(entry);\n  }\n\n  toBasic(valid) {\n    if (valid) {\n      const result = { valid: true };\n      if (this.annotations.size > 0) {\n        result.annotations = [ ...this.annotations.values() ];\n      }\n      return result;\n    }\n    return { valid: false, errors: this.errors };\n  }\n}\n\nfunction runStandard(evaluator, instance, format) {\n  if (format === 'flag') {\n    return { valid: evaluator.validate(instance) };\n  }\n  if (format !== 'basic') {\n    throw new Error(`Unknown standard output format: ${format}`);\n  }\n  const collector = new SimpleOutput(instance);\n  const valid = evaluator.validate(instance,\n    (type, ok, instruction, evaluatePath, instanceLocation, annotation) =>\n      collector.callback(type, ok, instruction, evaluatePath, instanceLocation,\n                         annotation));\n  return collector.toBasic(valid);\n}\n\nexport { Blaze };\nexport { describe } from './describe.mjs';\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/opcodes.mjs",
    "content": "export const ASSERTION_FAIL = 0;\nexport const ASSERTION_DEFINES = 1;\nexport const ASSERTION_DEFINES_STRICT = 2;\nexport const ASSERTION_DEFINES_ALL = 3;\nexport const ASSERTION_DEFINES_ALL_STRICT = 4;\nexport const ASSERTION_DEFINES_EXACTLY = 5;\nexport const ASSERTION_DEFINES_EXACTLY_STRICT = 6;\nexport const ASSERTION_DEFINES_EXACTLY_STRICT_HASH3 = 7;\nexport const ASSERTION_PROPERTY_DEPENDENCIES = 8;\nexport const ASSERTION_TYPE = 9;\nexport const ASSERTION_TYPE_ANY = 10;\nexport const ASSERTION_TYPE_STRICT = 11;\nexport const ASSERTION_TYPE_STRICT_ANY = 12;\nexport const ASSERTION_NOT_TYPE_STRICT_ANY = 13;\nexport const ASSERTION_TYPE_STRING_BOUNDED = 14;\nexport const ASSERTION_TYPE_STRING_UPPER = 15;\nexport const ASSERTION_TYPE_ARRAY_BOUNDED = 16;\nexport const ASSERTION_TYPE_ARRAY_UPPER = 17;\nexport const ASSERTION_TYPE_OBJECT_BOUNDED = 18;\nexport const ASSERTION_TYPE_OBJECT_UPPER = 19;\nexport const ASSERTION_REGEX = 20;\nexport const ASSERTION_STRING_SIZE_LESS = 21;\nexport const ASSERTION_STRING_SIZE_GREATER = 22;\nexport const ASSERTION_ARRAY_SIZE_LESS = 23;\nexport const ASSERTION_ARRAY_SIZE_GREATER = 24;\nexport const ASSERTION_OBJECT_SIZE_LESS = 25;\nexport const ASSERTION_OBJECT_SIZE_GREATER = 26;\nexport const ASSERTION_EQUAL = 27;\nexport const ASSERTION_EQUALS_ANY = 28;\nexport const ASSERTION_EQUALS_ANY_STRING_HASH = 29;\nexport const ASSERTION_GREATER_EQUAL = 30;\nexport const ASSERTION_LESS_EQUAL = 31;\nexport const ASSERTION_GREATER = 32;\nexport const ASSERTION_LESS = 33;\nexport const ASSERTION_UNIQUE = 34;\nexport const ASSERTION_DIVISIBLE = 35;\nexport const ASSERTION_TYPE_INTEGER_BOUNDED = 36;\nexport const ASSERTION_TYPE_INTEGER_BOUNDED_STRICT = 37;\nexport const ASSERTION_TYPE_INTEGER_LOWER_BOUND = 38;\nexport const ASSERTION_TYPE_INTEGER_LOWER_BOUND_STRICT = 39;\nexport const ASSERTION_STRING_TYPE = 40;\nexport const ASSERTION_PROPERTY_TYPE = 41;\nexport const ASSERTION_PROPERTY_TYPE_EVALUATE = 42;\nexport const ASSERTION_PROPERTY_TYPE_STRICT = 43;\nexport const ASSERTION_PROPERTY_TYPE_STRICT_EVALUATE = 44;\nexport const ASSERTION_PROPERTY_TYPE_STRICT_ANY = 45;\nexport const ASSERTION_PROPERTY_TYPE_STRICT_ANY_EVALUATE = 46;\nexport const ASSERTION_ARRAY_PREFIX = 47;\nexport const ASSERTION_ARRAY_PREFIX_EVALUATE = 48;\nexport const ASSERTION_OBJECT_PROPERTIES_SIMPLE = 49;\nexport const ANNOTATION_EMIT = 50;\nexport const ANNOTATION_TO_PARENT = 51;\nexport const ANNOTATION_BASENAME_TO_PARENT = 52;\nexport const EVALUATE = 53;\nexport const LOGICAL_NOT = 54;\nexport const LOGICAL_NOT_EVALUATE = 55;\nexport const LOGICAL_OR = 56;\nexport const LOGICAL_AND = 57;\nexport const LOGICAL_XOR = 58;\nexport const LOGICAL_CONDITION = 59;\nexport const LOGICAL_WHEN_TYPE = 60;\nexport const LOGICAL_WHEN_DEFINES = 61;\nexport const LOGICAL_WHEN_ARRAY_SIZE_GREATER = 62;\nexport const LOOP_PROPERTIES_UNEVALUATED = 63;\nexport const LOOP_PROPERTIES_UNEVALUATED_EXCEPT = 64;\nexport const LOOP_PROPERTIES_MATCH = 65;\nexport const LOOP_PROPERTIES_MATCH_CLOSED = 66;\nexport const LOOP_PROPERTIES = 67;\nexport const LOOP_PROPERTIES_EVALUATE = 68;\nexport const LOOP_PROPERTIES_REGEX = 69;\nexport const LOOP_PROPERTIES_REGEX_CLOSED = 70;\nexport const LOOP_PROPERTIES_STARTS_WITH = 71;\nexport const LOOP_PROPERTIES_EXCEPT = 72;\nexport const LOOP_PROPERTIES_TYPE = 73;\nexport const LOOP_PROPERTIES_TYPE_EVALUATE = 74;\nexport const LOOP_PROPERTIES_EXACTLY_TYPE_STRICT = 75;\nexport const LOOP_PROPERTIES_EXACTLY_TYPE_STRICT_HASH = 76;\nexport const LOOP_PROPERTIES_TYPE_STRICT = 77;\nexport const LOOP_PROPERTIES_TYPE_STRICT_EVALUATE = 78;\nexport const LOOP_PROPERTIES_TYPE_STRICT_ANY = 79;\nexport const LOOP_PROPERTIES_TYPE_STRICT_ANY_EVALUATE = 80;\nexport const LOOP_KEYS = 81;\nexport const LOOP_ITEMS = 82;\nexport const LOOP_ITEMS_FROM = 83;\nexport const LOOP_ITEMS_UNEVALUATED = 84;\nexport const LOOP_ITEMS_TYPE = 85;\nexport const LOOP_ITEMS_TYPE_STRICT = 86;\nexport const LOOP_ITEMS_TYPE_STRICT_ANY = 87;\nexport const LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH = 88;\nexport const LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH3 = 89;\nexport const LOOP_ITEMS_INTEGER_BOUNDED = 90;\nexport const LOOP_ITEMS_INTEGER_BOUNDED_SIZED = 91;\nexport const LOOP_CONTAINS = 92;\nexport const CONTROL_GROUP = 93;\nexport const CONTROL_GROUP_WHEN_DEFINES = 94;\nexport const CONTROL_GROUP_WHEN_DEFINES_DIRECT = 95;\nexport const CONTROL_GROUP_WHEN_TYPE = 96;\nexport const CONTROL_EVALUATE = 97;\nexport const CONTROL_DYNAMIC_ANCHOR_JUMP = 98;\nexport const CONTROL_JUMP = 99;\n\nexport const INSTRUCTION_NAMES = {\n  \"AssertionFail\": ASSERTION_FAIL,\n  \"AssertionDefines\": ASSERTION_DEFINES,\n  \"AssertionDefinesStrict\": ASSERTION_DEFINES_STRICT,\n  \"AssertionDefinesAll\": ASSERTION_DEFINES_ALL,\n  \"AssertionDefinesAllStrict\": ASSERTION_DEFINES_ALL_STRICT,\n  \"AssertionDefinesExactly\": ASSERTION_DEFINES_EXACTLY,\n  \"AssertionDefinesExactlyStrict\": ASSERTION_DEFINES_EXACTLY_STRICT,\n  \"AssertionDefinesExactlyStrictHash3\": ASSERTION_DEFINES_EXACTLY_STRICT_HASH3,\n  \"AssertionPropertyDependencies\": ASSERTION_PROPERTY_DEPENDENCIES,\n  \"AssertionType\": ASSERTION_TYPE,\n  \"AssertionTypeAny\": ASSERTION_TYPE_ANY,\n  \"AssertionTypeStrict\": ASSERTION_TYPE_STRICT,\n  \"AssertionTypeStrictAny\": ASSERTION_TYPE_STRICT_ANY,\n  \"AssertionNotTypeStrictAny\": ASSERTION_NOT_TYPE_STRICT_ANY,\n  \"AssertionTypeStringBounded\": ASSERTION_TYPE_STRING_BOUNDED,\n  \"AssertionTypeStringUpper\": ASSERTION_TYPE_STRING_UPPER,\n  \"AssertionTypeArrayBounded\": ASSERTION_TYPE_ARRAY_BOUNDED,\n  \"AssertionTypeArrayUpper\": ASSERTION_TYPE_ARRAY_UPPER,\n  \"AssertionTypeObjectBounded\": ASSERTION_TYPE_OBJECT_BOUNDED,\n  \"AssertionTypeObjectUpper\": ASSERTION_TYPE_OBJECT_UPPER,\n  \"AssertionRegex\": ASSERTION_REGEX,\n  \"AssertionStringSizeLess\": ASSERTION_STRING_SIZE_LESS,\n  \"AssertionStringSizeGreater\": ASSERTION_STRING_SIZE_GREATER,\n  \"AssertionArraySizeLess\": ASSERTION_ARRAY_SIZE_LESS,\n  \"AssertionArraySizeGreater\": ASSERTION_ARRAY_SIZE_GREATER,\n  \"AssertionObjectSizeLess\": ASSERTION_OBJECT_SIZE_LESS,\n  \"AssertionObjectSizeGreater\": ASSERTION_OBJECT_SIZE_GREATER,\n  \"AssertionEqual\": ASSERTION_EQUAL,\n  \"AssertionEqualsAny\": ASSERTION_EQUALS_ANY,\n  \"AssertionEqualsAnyStringHash\": ASSERTION_EQUALS_ANY_STRING_HASH,\n  \"AssertionGreaterEqual\": ASSERTION_GREATER_EQUAL,\n  \"AssertionLessEqual\": ASSERTION_LESS_EQUAL,\n  \"AssertionGreater\": ASSERTION_GREATER,\n  \"AssertionLess\": ASSERTION_LESS,\n  \"AssertionUnique\": ASSERTION_UNIQUE,\n  \"AssertionDivisible\": ASSERTION_DIVISIBLE,\n  \"AssertionTypeIntegerBounded\": ASSERTION_TYPE_INTEGER_BOUNDED,\n  \"AssertionTypeIntegerBoundedStrict\": ASSERTION_TYPE_INTEGER_BOUNDED_STRICT,\n  \"AssertionTypeIntegerLowerBound\": ASSERTION_TYPE_INTEGER_LOWER_BOUND,\n  \"AssertionTypeIntegerLowerBoundStrict\": ASSERTION_TYPE_INTEGER_LOWER_BOUND_STRICT,\n  \"AssertionStringType\": ASSERTION_STRING_TYPE,\n  \"AssertionPropertyType\": ASSERTION_PROPERTY_TYPE,\n  \"AssertionPropertyTypeEvaluate\": ASSERTION_PROPERTY_TYPE_EVALUATE,\n  \"AssertionPropertyTypeStrict\": ASSERTION_PROPERTY_TYPE_STRICT,\n  \"AssertionPropertyTypeStrictEvaluate\": ASSERTION_PROPERTY_TYPE_STRICT_EVALUATE,\n  \"AssertionPropertyTypeStrictAny\": ASSERTION_PROPERTY_TYPE_STRICT_ANY,\n  \"AssertionPropertyTypeStrictAnyEvaluate\": ASSERTION_PROPERTY_TYPE_STRICT_ANY_EVALUATE,\n  \"AssertionArrayPrefix\": ASSERTION_ARRAY_PREFIX,\n  \"AssertionArrayPrefixEvaluate\": ASSERTION_ARRAY_PREFIX_EVALUATE,\n  \"AssertionObjectPropertiesSimple\": ASSERTION_OBJECT_PROPERTIES_SIMPLE,\n  \"AnnotationEmit\": ANNOTATION_EMIT,\n  \"AnnotationToParent\": ANNOTATION_TO_PARENT,\n  \"AnnotationBasenameToParent\": ANNOTATION_BASENAME_TO_PARENT,\n  \"Evaluate\": EVALUATE,\n  \"LogicalNot\": LOGICAL_NOT,\n  \"LogicalNotEvaluate\": LOGICAL_NOT_EVALUATE,\n  \"LogicalOr\": LOGICAL_OR,\n  \"LogicalAnd\": LOGICAL_AND,\n  \"LogicalXor\": LOGICAL_XOR,\n  \"LogicalCondition\": LOGICAL_CONDITION,\n  \"LogicalWhenType\": LOGICAL_WHEN_TYPE,\n  \"LogicalWhenDefines\": LOGICAL_WHEN_DEFINES,\n  \"LogicalWhenArraySizeGreater\": LOGICAL_WHEN_ARRAY_SIZE_GREATER,\n  \"LoopPropertiesUnevaluated\": LOOP_PROPERTIES_UNEVALUATED,\n  \"LoopPropertiesUnevaluatedExcept\": LOOP_PROPERTIES_UNEVALUATED_EXCEPT,\n  \"LoopPropertiesMatch\": LOOP_PROPERTIES_MATCH,\n  \"LoopPropertiesMatchClosed\": LOOP_PROPERTIES_MATCH_CLOSED,\n  \"LoopProperties\": LOOP_PROPERTIES,\n  \"LoopPropertiesEvaluate\": LOOP_PROPERTIES_EVALUATE,\n  \"LoopPropertiesRegex\": LOOP_PROPERTIES_REGEX,\n  \"LoopPropertiesRegexClosed\": LOOP_PROPERTIES_REGEX_CLOSED,\n  \"LoopPropertiesStartsWith\": LOOP_PROPERTIES_STARTS_WITH,\n  \"LoopPropertiesExcept\": LOOP_PROPERTIES_EXCEPT,\n  \"LoopPropertiesType\": LOOP_PROPERTIES_TYPE,\n  \"LoopPropertiesTypeEvaluate\": LOOP_PROPERTIES_TYPE_EVALUATE,\n  \"LoopPropertiesExactlyTypeStrict\": LOOP_PROPERTIES_EXACTLY_TYPE_STRICT,\n  \"LoopPropertiesExactlyTypeStrictHash\": LOOP_PROPERTIES_EXACTLY_TYPE_STRICT_HASH,\n  \"LoopPropertiesTypeStrict\": LOOP_PROPERTIES_TYPE_STRICT,\n  \"LoopPropertiesTypeStrictEvaluate\": LOOP_PROPERTIES_TYPE_STRICT_EVALUATE,\n  \"LoopPropertiesTypeStrictAny\": LOOP_PROPERTIES_TYPE_STRICT_ANY,\n  \"LoopPropertiesTypeStrictAnyEvaluate\": LOOP_PROPERTIES_TYPE_STRICT_ANY_EVALUATE,\n  \"LoopKeys\": LOOP_KEYS,\n  \"LoopItems\": LOOP_ITEMS,\n  \"LoopItemsFrom\": LOOP_ITEMS_FROM,\n  \"LoopItemsUnevaluated\": LOOP_ITEMS_UNEVALUATED,\n  \"LoopItemsType\": LOOP_ITEMS_TYPE,\n  \"LoopItemsTypeStrict\": LOOP_ITEMS_TYPE_STRICT,\n  \"LoopItemsTypeStrictAny\": LOOP_ITEMS_TYPE_STRICT_ANY,\n  \"LoopItemsPropertiesExactlyTypeStrictHash\": LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH,\n  \"LoopItemsPropertiesExactlyTypeStrictHash3\": LOOP_ITEMS_PROPERTIES_EXACTLY_TYPE_STRICT_HASH3,\n  \"LoopItemsIntegerBounded\": LOOP_ITEMS_INTEGER_BOUNDED,\n  \"LoopItemsIntegerBoundedSized\": LOOP_ITEMS_INTEGER_BOUNDED_SIZED,\n  \"LoopContains\": LOOP_CONTAINS,\n  \"ControlGroup\": CONTROL_GROUP,\n  \"ControlGroupWhenDefines\": CONTROL_GROUP_WHEN_DEFINES,\n  \"ControlGroupWhenDefinesDirect\": CONTROL_GROUP_WHEN_DEFINES_DIRECT,\n  \"ControlGroupWhenType\": CONTROL_GROUP_WHEN_TYPE,\n  \"ControlEvaluate\": CONTROL_EVALUATE,\n  \"ControlDynamicAnchorJump\": CONTROL_DYNAMIC_ANCHOR_JUMP,\n  \"ControlJump\": CONTROL_JUMP,\n  \"Annotation\": -1\n};\n\nexport const ANNOTATION_OPCODES = new Set([\n  ANNOTATION_EMIT, ANNOTATION_TO_PARENT, ANNOTATION_BASENAME_TO_PARENT\n]);\n"
  },
  {
    "path": "vendor/blaze/ports/javascript/package.json",
    "content": "{\n  \"name\": \"@sourcemeta/blaze\",\n  \"version\": \"0.0.0\",\n  \"description\": \"A pure JavaScript port of the evaluator from Blaze, a high-performance C++ JSON Schema validator. Zero dependencies. Supports Draft 4, Draft 6, Draft 7, 2019-09, and 2020-12 with schema-specific code generation for near-native speed\",\n  \"type\": \"module\",\n  \"main\": \"./index.mjs\",\n  \"module\": \"./index.mjs\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./index.mjs\",\n      \"default\": \"./index.mjs\"\n    }\n  },\n  \"types\": \"./index.d.mts\",\n  \"license\": \"LGPL-3.0-or-later\",\n  \"homepage\": \"https://github.com/sourcemeta/blaze\",\n  \"author\": {\n    \"email\": \"hello@sourcemeta.com\",\n    \"name\": \"Sourcemeta\",\n    \"url\": \"https://www.sourcemeta.com\"\n  },\n  \"engines\": {\n    \"node\": \">=21.7\"\n  },\n  \"funding\": \"https://github.com/sponsors/sourcemeta\",\n  \"keywords\": [\n    \"jsonschema\",\n    \"json\",\n    \"schema\",\n    \"json-schema\",\n    \"validator\",\n    \"validation\",\n    \"json-schema-validator\",\n    \"json-schema-validation\",\n    \"blaze\",\n    \"sourcemeta\",\n    \"fast\",\n    \"performance\",\n    \"codegen\",\n    \"draft-04\",\n    \"draft-06\",\n    \"draft-07\",\n    \"draft4\",\n    \"draft6\",\n    \"draft7\",\n    \"2019-09\",\n    \"2020-12\",\n    \"ajv\",\n    \"ajv-alternative\",\n    \"$ref\",\n    \"validate\",\n    \"evaluator\"\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/sourcemeta/blaze/issues\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/sourcemeta/jsonschema.git\",\n    \"directory\": \"vendor/blaze/ports/javascript\"\n  },\n  \"publishConfig\": {\n    \"provenance\": true,\n    \"access\": \"public\"\n  },\n  \"files\": [\n    \"index.mjs\",\n    \"index.d.mts\",\n    \"opcodes.mjs\",\n    \"describe.mjs\",\n    \"README.md\",\n    \"LICENSE\"\n  ]\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-2019-09.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:2019-09\",\n  \"title\": \"Canonical JSON Schema 2019-09\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema 2019-09 document is in canonical form\",\n  \"examples\": [\n    true,\n    {\n      \"$ref\": \"#/$defs/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true,\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"examples\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"unevaluated\": {\n      \"not\": {\n        \"required\": [ \"unevaluatedProperties\", \"unevaluatedItems\" ]\n      },\n      \"properties\": {\n        \"unevaluatedProperties\": {\n          \"$ref\": \"#/$defs/schema\",\n          \"not\": {\n            \"const\": true\n          }\n        },\n        \"unevaluatedItems\": {\n          \"$ref\": \"#/$defs/schema\",\n          \"not\": {\n            \"const\": true\n          }\n        }\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"$id\": {\n          \"type\": \"string\"\n        },\n        \"$anchor\": {\n          \"type\": \"string\"\n        },\n        \"$recursiveAnchor\": {\n          \"const\": true\n        },\n        \"$vocabulary\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"type\": \"boolean\"\n          }\n        },\n        \"$defs\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/schema\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$recursiveRef\" ],\n          \"properties\": {\n            \"$recursiveRef\": {\n              \"const\": \"#\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"contentEncoding\": {\n              \"type\": \"string\"\n            },\n            \"contentMediaType\": {\n              \"type\": \"string\"\n            },\n            \"contentSchema\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"multipleOf\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"unevaluatedProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"unevaluatedProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"contains\",\n            \"minContains\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"contains\",\n            \"minContains\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"additionalItems\",\n            \"contains\",\n            \"minContains\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"unevaluatedItems\",\n            \"contains\",\n            \"minContains\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"unevaluatedItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"contains\",\n            \"minContains\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"if\", \"then\", \"else\" ],\n          \"properties\": {\n            \"if\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"then\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"else\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"anyOf\" ],\n          \"properties\": {\n            \"anyOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"not\": {\n            \"anyOf\": [\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedProperties\" ]\n              },\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedItems\" ]\n              }\n            ]\n          },\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"not\": {\n            \"anyOf\": [\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedProperties\" ]\n              },\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedItems\" ]\n              }\n            ]\n          },\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"maxItems\": 1,\n              \"minItems\": 1,\n              \"items\": {\n                \"x-lint-exclude\": \"simple_properties_identifiers\",\n                \"$ref\": \"#/$defs/metadata\",\n                \"type\": \"object\",\n                \"oneOf\": [\n                  {\n                    \"x-lint-exclude\": \"simple_properties_identifiers\",\n                    \"required\": [ \"$ref\" ],\n                    \"properties\": {\n                      \"$ref\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  {\n                    \"x-lint-exclude\": \"simple_properties_identifiers\",\n                    \"required\": [ \"$recursiveRef\" ],\n                    \"properties\": {\n                      \"$recursiveRef\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  }\n                ],\n                \"unevaluatedProperties\": false\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"anyOf\": [\n            {\n              \"x-lint-exclude\": \"required_properties_in_properties\",\n              \"required\": [ \"unevaluatedProperties\" ]\n            },\n            {\n              \"x-lint-exclude\": \"required_properties_in_properties\",\n              \"required\": [ \"unevaluatedItems\" ]\n            }\n          ],\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"oneOf\" ],\n          \"properties\": {\n            \"oneOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"not\" ],\n          \"properties\": {\n            \"not\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-2020-12.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:2020-12\",\n  \"title\": \"Canonical JSON Schema 2020-12\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema 2020-12 document is in canonical form\",\n  \"examples\": [\n    true,\n    {\n      \"$ref\": \"#/$defs/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true,\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"examples\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"$id\": {\n          \"type\": \"string\"\n        },\n        \"$anchor\": {\n          \"type\": \"string\"\n        },\n        \"$dynamicAnchor\": {\n          \"type\": \"string\"\n        },\n        \"$vocabulary\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"type\": \"boolean\"\n          }\n        },\n        \"$defs\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/schema\"\n          }\n        }\n      }\n    },\n    \"unevaluated\": {\n      \"not\": {\n        \"required\": [ \"unevaluatedProperties\", \"unevaluatedItems\" ]\n      },\n      \"properties\": {\n        \"unevaluatedProperties\": {\n          \"$ref\": \"#/$defs/schema\",\n          \"not\": {\n            \"const\": true\n          }\n        },\n        \"unevaluatedItems\": {\n          \"$ref\": \"#/$defs/schema\",\n          \"not\": {\n            \"const\": true\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$dynamicRef\" ],\n          \"properties\": {\n            \"$dynamicRef\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"contentEncoding\": {\n              \"type\": \"string\"\n            },\n            \"contentMediaType\": {\n              \"type\": \"string\"\n            },\n            \"contentSchema\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"multipleOf\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"unevaluatedProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"unevaluatedProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"prefixItems\",\n            \"items\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"prefixItems\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"prefixItems\",\n            \"unevaluatedItems\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"prefixItems\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"unevaluatedItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"prefixItems\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"prefixItems\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxContains\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"if\", \"then\", \"else\" ],\n          \"properties\": {\n            \"if\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"then\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"else\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"anyOf\" ],\n          \"properties\": {\n            \"anyOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"not\": {\n            \"anyOf\": [\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedProperties\" ]\n              },\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedItems\" ]\n              }\n            ]\n          },\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"not\": {\n            \"anyOf\": [\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedProperties\" ]\n              },\n              {\n                \"x-lint-exclude\": \"required_properties_in_properties\",\n                \"required\": [ \"unevaluatedItems\" ]\n              }\n            ]\n          },\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"maxItems\": 1,\n              \"minItems\": 1,\n              \"items\": {\n                \"x-lint-exclude\": \"simple_properties_identifiers\",\n                \"$ref\": \"#/$defs/metadata\",\n                \"type\": \"object\",\n                \"oneOf\": [\n                  {\n                    \"x-lint-exclude\": \"simple_properties_identifiers\",\n                    \"required\": [ \"$ref\" ],\n                    \"properties\": {\n                      \"$ref\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  },\n                  {\n                    \"x-lint-exclude\": \"simple_properties_identifiers\",\n                    \"required\": [ \"$dynamicRef\" ],\n                    \"properties\": {\n                      \"$dynamicRef\": {\n                        \"type\": \"string\"\n                      }\n                    }\n                  }\n                ],\n                \"unevaluatedProperties\": false\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"anyOf\": [\n            {\n              \"x-lint-exclude\": \"required_properties_in_properties\",\n              \"required\": [ \"unevaluatedProperties\" ]\n            },\n            {\n              \"x-lint-exclude\": \"required_properties_in_properties\",\n              \"required\": [ \"unevaluatedItems\" ]\n            }\n          ],\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/unevaluated\"\n            }\n          ],\n          \"required\": [ \"oneOf\" ],\n          \"properties\": {\n            \"oneOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"not\" ],\n          \"properties\": {\n            \"not\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft1.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft1\",\n  \"title\": \"Canonical JSON Schema Draft 1\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 1 document is in canonical form\",\n  \"examples\": [\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"typed\": {\n      \"properties\": {\n        \"optional\": {\n          \"type\": \"boolean\"\n        },\n        \"requires\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          ]\n        }\n      }\n    },\n    \"subproperty\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/$defs/schema\",\n          \"required\": [ \"optional\" ],\n          \"properties\": {\n            \"optional\": {\n              \"type\": \"boolean\"\n            }\n          }\n        },\n        {\n          \"const\": {}\n        }\n      ]\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"const\": {}\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"contentEncoding\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"maxDecimal\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"maxDecimal\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"maxDecimal\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"minimumCanEqual\": {\n              \"type\": \"boolean\"\n            },\n            \"maximumCanEqual\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"properties\", \"additionalProperties\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/subproperty\"\n              }\n            },\n            \"additionalProperties\": {\n              \"anyOf\": [\n                {\n                  \"$ref\": \"#/$defs/schema\"\n                },\n                {\n                  \"type\": \"boolean\"\n                }\n              ]\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"extends\" ],\n          \"properties\": {\n            \"extends\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"disallow\" ],\n          \"properties\": {\n            \"disallow\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft2.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft2\",\n  \"title\": \"Canonical JSON Schema Draft 2\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 2 document is in canonical form\",\n  \"examples\": [\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"typed\": {\n      \"properties\": {\n        \"optional\": {\n          \"type\": \"boolean\"\n        },\n        \"requires\": {\n          \"anyOf\": [\n            {\n              \"type\": \"string\"\n            },\n            {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          ]\n        }\n      }\n    },\n    \"subproperty\": {\n      \"anyOf\": [\n        {\n          \"$ref\": \"#/$defs/schema\",\n          \"required\": [ \"optional\" ],\n          \"properties\": {\n            \"optional\": {\n              \"type\": \"boolean\"\n            }\n          }\n        },\n        {\n          \"const\": {}\n        }\n      ]\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"const\": {}\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"contentEncoding\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"divisibleBy\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"divisibleBy\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"divisibleBy\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"minimumCanEqual\": {\n              \"type\": \"boolean\"\n            },\n            \"maximumCanEqual\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"properties\", \"additionalProperties\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/subproperty\"\n              }\n            },\n            \"additionalProperties\": {\n              \"anyOf\": [\n                {\n                  \"$ref\": \"#/$defs/schema\"\n                },\n                {\n                  \"type\": \"boolean\"\n                }\n              ]\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            },\n            {\n              \"$ref\": \"#/$defs/typed\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"extends\" ],\n          \"properties\": {\n            \"extends\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"disallow\" ],\n          \"properties\": {\n            \"disallow\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft3.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft3\",\n  \"title\": \"Canonical JSON Schema Draft 3\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 3 document is in canonical form\",\n  \"examples\": [\n    {\n      \"$ref\": \"#/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"id\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"subproperty\": {\n      \"$ref\": \"#/$defs/schema\",\n      \"if\": {\n        \"type\": \"object\",\n        \"not\": {\n          \"anyOf\": [\n            {\n              \"maxProperties\": 0\n            },\n            {\n              \"x-lint-exclude\": \"simple_properties_identifiers\",\n              \"required\": [ \"$ref\" ],\n              \"properties\": {\n                \"$ref\": true\n              }\n            }\n          ]\n        }\n      },\n      \"then\": {\n        \"required\": [ \"required\" ],\n        \"properties\": {\n          \"required\": {\n            \"type\": \"boolean\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"const\": {}\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"divisibleBy\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"divisibleBy\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"divisibleBy\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"boolean\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"boolean\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/subproperty\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"anyOf\": [\n                {\n                  \"$ref\": \"#/$defs/schema\"\n                },\n                {\n                  \"type\": \"boolean\"\n                }\n              ]\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"additionalItems\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalItems\": {\n              \"anyOf\": [\n                {\n                  \"$ref\": \"#/$defs/schema\"\n                },\n                {\n                  \"type\": \"boolean\"\n                }\n              ]\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"extends\" ],\n          \"properties\": {\n            \"extends\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"disallow\" ],\n          \"properties\": {\n            \"disallow\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft4.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft4\",\n  \"title\": \"Canonical JSON Schema Draft 4\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 4 document is in canonical form\",\n  \"examples\": [\n    true,\n    {\n      \"$ref\": \"#/definitions/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"definitions\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/schema\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"multipleOf\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"boolean\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"additionalItems\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"anyOf\" ],\n          \"properties\": {\n            \"anyOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"oneOf\" ],\n          \"properties\": {\n            \"oneOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"not\" ],\n          \"properties\": {\n            \"not\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft6.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft6\",\n  \"title\": \"Canonical JSON Schema Draft 6\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 6 document is in canonical form\",\n  \"examples\": [\n    true,\n    {\n      \"$ref\": \"#/definitions/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true,\n        \"examples\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"$id\": {\n          \"type\": \"string\"\n        },\n        \"definitions\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/schema\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"multipleOf\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"additionalItems\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"anyOf\" ],\n          \"properties\": {\n            \"anyOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"oneOf\" ],\n          \"properties\": {\n            \"oneOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"not\" ],\n          \"properties\": {\n            \"not\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/canonical-draft7.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"tag:sourcemeta.com,2026:canonical:draft7\",\n  \"title\": \"Canonical JSON Schema Draft 7\",\n  \"description\": \"Meta-schema that validates whether a given JSON Schema Draft 7 document is in canonical form\",\n  \"examples\": [\n    true,\n    {\n      \"$ref\": \"#/definitions/foo\"\n    },\n    {\n      \"enum\": [ 1, 2, 3 ]\n    },\n    {\n      \"type\": \"string\",\n      \"minLength\": 0\n    }\n  ],\n  \"$ref\": \"#/$defs/schema\",\n  \"$defs\": {\n    \"metadata\": {\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"default\": true,\n        \"readOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"examples\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"core\": {\n      \"x-lint-exclude\": \"simple_properties_identifiers\",\n      \"properties\": {\n        \"$schema\": {\n          \"type\": \"string\"\n        },\n        \"$id\": {\n          \"type\": \"string\"\n        },\n        \"definitions\": {\n          \"type\": \"object\",\n          \"minProperties\": 1,\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/schema\"\n          }\n        }\n      }\n    },\n    \"schema\": {\n      \"anyOf\": [\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"$ref\": \"#/$defs/metadata\",\n          \"type\": \"object\",\n          \"required\": [ \"$ref\" ],\n          \"properties\": {\n            \"$ref\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"enum\" ],\n          \"properties\": {\n            \"enum\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"minLength\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"string\"\n            },\n            \"minLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxLength\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"pattern\": {\n              \"type\": \"string\"\n            },\n            \"format\": {\n              \"type\": \"string\"\n            },\n            \"contentEncoding\": {\n              \"type\": \"string\"\n            },\n            \"contentMediaType\": {\n              \"type\": \"string\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"multipleOf\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"integer\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"number\"\n            },\n            \"multipleOf\": {\n              \"type\": \"number\",\n              \"exclusiveMinimum\": 0\n            },\n            \"minimum\": {\n              \"type\": \"number\"\n            },\n            \"maximum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMinimum\": {\n              \"type\": \"number\"\n            },\n            \"exclusiveMaximum\": {\n              \"type\": \"number\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"properties\",\n            \"patternProperties\",\n            \"additionalProperties\",\n            \"propertyNames\",\n            \"minProperties\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"object\"\n            },\n            \"properties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"patternProperties\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalProperties\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"propertyNames\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"required\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"minProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxProperties\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"type\", \"items\", \"minItems\", \"uniqueItems\" ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [\n            \"type\",\n            \"items\",\n            \"additionalItems\",\n            \"minItems\",\n            \"uniqueItems\"\n          ],\n          \"properties\": {\n            \"type\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            },\n            \"additionalItems\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"contains\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"minItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"maxItems\": {\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"uniqueItems\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"if\", \"then\", \"else\" ],\n          \"properties\": {\n            \"if\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"then\": {\n              \"$ref\": \"#/$defs/schema\"\n            },\n            \"else\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"anyOf\" ],\n          \"properties\": {\n            \"anyOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"allOf\" ],\n          \"properties\": {\n            \"allOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"oneOf\" ],\n          \"properties\": {\n            \"oneOf\": {\n              \"type\": \"array\",\n              \"minItems\": 2,\n              \"items\": {\n                \"$ref\": \"#/$defs/schema\"\n              }\n            }\n          },\n          \"unevaluatedProperties\": false\n        },\n        {\n          \"x-lint-exclude\": \"simple_properties_identifiers\",\n          \"type\": \"object\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/metadata\"\n            },\n            {\n              \"$ref\": \"#/$defs/core\"\n            }\n          ],\n          \"required\": [ \"not\" ],\n          \"properties\": {\n            \"not\": {\n              \"$ref\": \"#/$defs/schema\"\n            }\n          },\n          \"unevaluatedProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/documentation.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"Blaze Documentation Format\",\n  \"description\": \"The JSON representation of a documentation table\",\n  \"examples\": [\n    {\n      \"identifier\": 0,\n      \"rows\": [\n        {\n          \"identifier\": 1,\n          \"path\": [\n            {\n              \"type\": \"synthetic\",\n              \"value\": \"root\"\n            }\n          ],\n          \"type\": {\n            \"kind\": \"primitive\",\n            \"name\": \"string\"\n          }\n        }\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/table\",\n  \"$defs\": {\n    \"table\": {\n      \"type\": \"object\",\n      \"required\": [ \"identifier\", \"rows\" ],\n      \"properties\": {\n        \"identifier\": {\n          \"description\": \"A unique monotonic identifier for this table\",\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"title\": {\n          \"description\": \"The title annotation from the source schema branch\",\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"dynamicAnchor\": {\n          \"description\": \"The dynamic anchor value declared by this schema\",\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"rows\": {\n          \"type\": \"array\",\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/row\"\n          }\n        },\n        \"children\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/section\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"row\": {\n      \"type\": \"object\",\n      \"required\": [ \"identifier\", \"path\", \"type\" ],\n      \"properties\": {\n        \"identifier\": {\n          \"description\": \"A unique monotonic identifier for this row\",\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"path\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"items\": {\n            \"$ref\": \"#/$defs/pathSegment\"\n          }\n        },\n        \"modifiers\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"enum\": [ \"readOnly\", \"writeOnly\", \"deprecated\" ]\n          }\n        },\n        \"type\": {\n          \"$ref\": \"#/$defs/typeExpression\"\n        },\n        \"badges\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/badge\"\n          }\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        },\n        \"constraints\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1\n          }\n        },\n        \"title\": {\n          \"description\": \"The title annotation for this property\",\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"description\": {\n          \"description\": \"The description annotation for this property\",\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"default\": {\n          \"description\": \"The default value annotation for this property. Any JSON value is valid, including null\"\n        },\n        \"examples\": {\n          \"description\": \"Example values for this property\",\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        },\n        \"children\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/section\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"section\": {\n      \"type\": \"object\",\n      \"required\": [ \"label\", \"children\" ],\n      \"properties\": {\n        \"label\": {\n          \"anyOf\": [\n            {\n              \"enum\": [\n                \"Any of\",\n                \"All of\",\n                \"One of\",\n                \"Property names\",\n                \"Contains\",\n                \"Decoded content\",\n                \"Must NOT match\",\n                \"If\",\n                \"Then\",\n                \"Else\"\n              ]\n            },\n            {\n              \"type\": \"string\",\n              \"pattern\": \"^Array item \\\\d+$\"\n            }\n          ]\n        },\n        \"position\": {\n          \"description\": \"The JSON Pointer of the operator within the parent schema\",\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"children\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"uniqueItems\": true,\n          \"items\": {\n            \"$ref\": \"#/$defs/table\"\n          }\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"pathSegment\": {\n      \"type\": \"object\",\n      \"required\": [ \"type\", \"value\" ],\n      \"properties\": {\n        \"type\": {\n          \"enum\": [ \"literal\", \"pattern\", \"wildcard\", \"synthetic\" ]\n        },\n        \"value\": {\n          \"type\": \"string\",\n          \"minLength\": 1\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"badge\": {\n      \"type\": \"object\",\n      \"required\": [ \"kind\", \"value\" ],\n      \"properties\": {\n        \"kind\": {\n          \"enum\": [ \"format\", \"encoding\", \"mime\" ]\n        },\n        \"value\": {\n          \"type\": \"string\",\n          \"minLength\": 1\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"typeExpression\": {\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"object\"\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"name\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"primitive\"\n            },\n            \"name\": {\n              \"enum\": [ \"string\", \"integer\", \"number\" ]\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"array\"\n            },\n            \"items\": {\n              \"description\": \"The homogeneous item type. Absent when the array has no items constraint\",\n              \"$ref\": \"#/$defs/typeExpression\"\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"items\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"tuple\"\n            },\n            \"items\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true,\n              \"items\": {\n                \"$ref\": \"#/$defs/typeExpression\"\n              }\n            },\n            \"additional\": {\n              \"description\": \"The open tail type. Absent when the tuple has no tail\",\n              \"$ref\": \"#/$defs/typeExpression\"\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"values\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"enum\"\n            },\n            \"values\": {\n              \"description\": \"The visible enum values (first 10 by default)\",\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            },\n            \"overflow\": {\n              \"description\": \"The remaining enum values beyond the visible portion\",\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"uniqueItems\": true\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"url\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"externalRef\"\n            },\n            \"url\": {\n              \"type\": \"string\",\n              \"format\": \"uri\",\n              \"minLength\": 1\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"identifier\", \"path\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"recursiveRef\"\n            },\n            \"identifier\": {\n              \"description\": \"The identifier of the target table in the same documentation tree\",\n              \"type\": \"integer\",\n              \"minimum\": 0\n            },\n            \"path\": {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/$defs/pathSegment\"\n              }\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\", \"anchor\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"dynamicRef\"\n            },\n            \"anchor\": {\n              \"type\": \"string\",\n              \"minLength\": 1\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"any\"\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"object\",\n          \"required\": [ \"kind\" ],\n          \"properties\": {\n            \"kind\": {\n              \"const\": \"never\"\n            }\n          },\n          \"additionalProperties\": false\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/blaze/schemas/jsonschema.json",
    "content": "{\n  \"defaultDialect\": \"https://json-schema.org/draft/2020-12/schema\"\n}\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME alterschema\n  FOLDER \"Blaze/AlterSchema\"\n  PRIVATE_HEADERS error.h transformer.h\n  SOURCES alterschema.cc schema_rule.cc transformer.cc\n    # Canonicalizer\n    canonicalizer/additional_items_implicit.h\n    canonicalizer/comment_drop.h\n    canonicalizer/const_as_enum.h\n    canonicalizer/dependencies_to_any_of.h\n    canonicalizer/dependencies_to_extends_disallow.h\n    canonicalizer/dependent_required_to_any_of.h\n    canonicalizer/dependent_schemas_to_any_of.h\n    canonicalizer/deprecated_false_drop.h\n    canonicalizer/draft3_type_any.h\n    canonicalizer/disallow_to_array_of_schemas.h\n    canonicalizer/divisible_by_implicit.h\n    canonicalizer/empty_definitions_drop.h\n    canonicalizer/empty_defs_drop.h\n    canonicalizer/empty_dependencies_drop.h\n    canonicalizer/empty_dependent_required_drop.h\n    canonicalizer/empty_dependent_schemas_drop.h\n    canonicalizer/enum_drop_redundant_validation.h\n    canonicalizer/enum_filter_by_type.h\n    canonicalizer/exclusive_maximum_boolean_integer_fold.h\n    canonicalizer/exclusive_maximum_integer_to_maximum.h\n    canonicalizer/exclusive_minimum_boolean_integer_fold.h\n    canonicalizer/exclusive_minimum_integer_to_minimum.h\n    canonicalizer/extends_to_array.h\n    canonicalizer/if_then_else_implicit.h\n    canonicalizer/implicit_contains_keywords.h\n    canonicalizer/implicit_object_keywords.h\n    canonicalizer/items_implicit.h\n    canonicalizer/max_contains_covered_by_max_items.h\n    canonicalizer/max_decimal_implicit.h\n    canonicalizer/maximum_can_equal_integer_fold.h\n    canonicalizer/maximum_can_equal_true_drop.h\n    canonicalizer/min_items_given_min_contains.h\n    canonicalizer/min_length_implicit.h\n    canonicalizer/min_properties_covered_by_required.h\n    canonicalizer/minimum_can_equal_integer_fold.h\n    canonicalizer/minimum_can_equal_true_drop.h\n    canonicalizer/multiple_of_implicit.h\n    canonicalizer/optional_property_implicit.h\n    canonicalizer/recursive_anchor_false_drop.h\n    canonicalizer/required_property_implicit.h\n    canonicalizer/single_branch_allof.h\n    canonicalizer/single_branch_anyof.h\n    canonicalizer/single_branch_oneof.h\n    canonicalizer/type_array_to_any_of.h\n    canonicalizer/type_boolean_as_enum.h\n    canonicalizer/type_inherit_in_place.h\n    canonicalizer/type_null_as_enum.h\n    canonicalizer/type_union_implicit.h\n    canonicalizer/type_union_to_schemas.h\n    canonicalizer/type_with_applicator_to_allof.h\n    canonicalizer/type_with_applicator_to_extends.h\n    canonicalizer/unevaluated_items_to_items.h\n    canonicalizer/unevaluated_properties_to_additional_properties.h\n    canonicalizer/unsatisfiable_can_equal_bounds.h\n    canonicalizer/unsatisfiable_exclusive_equal_bounds.h\n    canonicalizer/unsatisfiable_type_and_enum.h\n\n    # Common\n    common/allof_false_simplify.h\n    common/anyof_false_simplify.h\n    common/anyof_remove_false_schemas.h\n    common/anyof_true_simplify.h\n    common/const_in_enum.h\n    common/const_with_type.h\n    common/orphan_definitions.h\n    common/content_media_type_without_encoding.h\n    common/content_schema_without_media_type.h\n    common/dependencies_property_tautology.h\n    common/dependent_required_tautology.h\n    common/disallow_narrows_type.h\n    common/double_negation_elimination.h\n    common/draft_official_dialect_with_https.h\n    common/draft_official_dialect_without_empty_fragment.h\n    common/draft_ref_siblings.h\n    common/drop_allof_empty_schemas.h\n    common/drop_extends_empty_schemas.h\n    common/duplicate_allof_branches.h\n    common/flatten_nested_allof.h\n    common/flatten_nested_anyof.h\n    common/flatten_nested_extends.h\n    common/duplicate_anyof_branches.h\n    common/dynamic_ref_to_static_ref.h\n    common/duplicate_enum_values.h\n    common/duplicate_required_values.h\n    common/empty_object_as_true.h\n    common/else_without_if.h\n    common/enum_with_type.h\n    common/equal_numeric_bounds_to_enum.h\n    common/exclusive_bounds_false_drop.h\n    common/exclusive_maximum_number_and_maximum.h\n    common/exclusive_minimum_number_and_minimum.h\n    common/if_without_then_else.h\n    common/ignored_metaschema.h\n    common/max_contains_without_contains.h\n    common/maximum_real_for_integer.h\n    common/min_contains_without_contains.h\n    common/minimum_real_for_integer.h\n    common/modern_official_dialect_with_empty_fragment.h\n    common/modern_official_dialect_with_http.h\n    common/non_applicable_additional_items.h\n    common/non_applicable_disallow_types.h\n    common/non_applicable_enum_validation_keywords.h\n    common/non_applicable_type_specific_keywords.h\n    common/not_false.h\n    common/oneof_false_simplify.h\n    common/oneof_to_anyof_disjoint_types.h\n    common/required_properties_in_properties.h\n    common/single_type_array.h\n    common/then_without_if.h\n    common/unknown_keywords_prefix.h\n    common/unknown_local_ref.h\n    common/unsatisfiable_drop_validation.h\n    common/unnecessary_allof_ref_wrapper_draft.h\n    common/unnecessary_extends_ref_wrapper.h\n    common/unsatisfiable_in_place_applicator_type.h\n\n    # Linter\n    linter/comment_trim.h\n    linter/const_not_in_enum.h\n    linter/content_schema_default.h\n    linter/definitions_to_defs.h\n    linter/dependencies_default.h\n    linter/dependent_required_default.h\n    linter/description_trailing_period.h\n    linter/description_trim.h\n    linter/disallow_default.h\n    linter/divisible_by_default.h\n    linter/duplicate_examples.h\n    linter/else_empty.h\n    linter/enum_to_const.h\n    linter/equal_numeric_bounds_to_const.h\n    linter/forbid_empty_enum.h\n    linter/incoherent_min_max_contains.h\n    linter/invalid_external_ref.h\n    linter/items_array_default.h\n    linter/items_schema_default.h\n    linter/multiple_of_default.h\n    linter/pattern_properties_default.h\n    linter/portable_anchor_names.h\n    linter/properties_default.h\n    linter/property_names_default.h\n    linter/property_names_type_default.h\n    linter/simple_properties_identifiers.h\n    linter/then_empty.h\n    linter/title_description_equal.h\n    linter/title_trailing_period.h\n    linter/title_trim.h\n    linter/top_level_description.h\n    linter/top_level_examples.h\n    linter/top_level_title.h\n    linter/unevaluated_items_default.h\n    linter/unevaluated_properties_default.h\n    linter/unnecessary_allof_ref_wrapper_modern.h\n    linter/unnecessary_allof_wrapper.h\n    linter/unnecessary_extends_wrapper.h\n    linter/unsatisfiable_max_contains.h\n    linter/unsatisfiable_min_properties.h\n    linter/valid_default.h\n    linter/valid_examples.h)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME alterschema)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_alterschema PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_blaze_alterschema PUBLIC\n  sourcemeta::blaze::compiler)\ntarget_link_libraries(sourcemeta_blaze_alterschema PRIVATE\n  sourcemeta::blaze::evaluator)\ntarget_link_libraries(sourcemeta_blaze_alterschema PRIVATE\n  sourcemeta::blaze::output)\ntarget_link_libraries(sourcemeta_blaze_alterschema PRIVATE\n  sourcemeta::core::regex)\ntarget_link_libraries(sourcemeta_blaze_alterschema PRIVATE\n  sourcemeta::core::uri)\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/alterschema.cc",
    "content": "#include <sourcemeta/blaze/alterschema.h>\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n#include <sourcemeta/blaze/output.h>\n#include <sourcemeta/core/regex.h>\n#include <sourcemeta/core/uri.h>\n\n// For built-in rules\n#include <algorithm>     // std::sort, std::unique, std::ranges::none_of\n#include <array>         // std::array\n#include <bit>           // std::popcount\n#include <cassert>       // assert\n#include <cmath>         // std::floor, std::ceil, std::isfinite\n#include <cstddef>       // std::size_t\n#include <functional>    // std::ref\n#include <iterator>      // std::back_inserter\n#include <limits>        // std::numeric_limits\n#include <memory>        // std::unique_ptr, std::make_unique\n#include <sstream>       // std::ostringstream\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::move, std::to_underlying\n\nnamespace sourcemeta::blaze {\n\nusing namespace sourcemeta::core;\n\ntemplate <typename... Args>\nauto APPLIES_TO_KEYWORDS(Args &&...args) -> SchemaTransformRule::Result {\n  std::vector<Pointer> result;\n  result.reserve(sizeof...(args));\n  (result.push_back(Pointer{std::forward<Args>(args)}), ...);\n  return result;\n}\n\ninline auto APPLIES_TO_POINTERS(std::vector<Pointer> &&keywords)\n    -> SchemaTransformRule::Result {\n  return {std::move(keywords)};\n}\n\n// TODO: Move upstream\ninline auto IS_IN_PLACE_APPLICATOR(const SchemaKeywordType type) -> bool {\n  return type == SchemaKeywordType::ApplicatorValueOrElementsInPlace ||\n         type == SchemaKeywordType::ApplicatorMembersInPlaceSome ||\n         type == SchemaKeywordType::ApplicatorElementsInPlace ||\n         type == SchemaKeywordType::ApplicatorElementsInPlaceSome ||\n         type == SchemaKeywordType::ApplicatorElementsInPlaceSomeNegate ||\n         type == SchemaKeywordType::ApplicatorValueInPlaceMaybe ||\n         type == SchemaKeywordType::ApplicatorValueInPlaceOther ||\n         type == SchemaKeywordType::ApplicatorValueInPlaceNegate;\n}\n\n// Walk up from a schema location, continuing as long as the traversal\n// predicate returns true for each keyword type encountered. Returns a\n// reference to the pointer of the ancestor where the match callback returned\n// true, or nullopt if no match was found or the traversal predicate stopped\n// the walk.\ntemplate <typename TraversePredicate, typename MatchCallback>\nauto WALK_UP(const JSON &root, const SchemaFrame &frame,\n             const SchemaFrame::Location &location, const SchemaWalker &walker,\n             const SchemaResolver &resolver,\n             const TraversePredicate &should_continue,\n             const MatchCallback &matches)\n    -> std::optional<std::reference_wrapper<const WeakPointer>> {\n  auto current_pointer{location.pointer};\n  auto current_parent{location.parent};\n\n  while (current_parent.has_value()) {\n    const auto &parent_pointer{current_parent.value()};\n    const auto relative_pointer{current_pointer.resolve_from(parent_pointer)};\n    assert(!relative_pointer.empty() && relative_pointer.at(0).is_property());\n    const auto parent{frame.traverse(frame.uri(parent_pointer).value().get())};\n    assert(parent.has_value());\n    const auto parent_vocabularies{\n        frame.vocabularies(parent.value().get(), resolver)};\n    const auto keyword_type{\n        walker(relative_pointer.at(0).to_property(), parent_vocabularies).type};\n\n    if (!should_continue(keyword_type)) {\n      return std::nullopt;\n    }\n\n    if (matches(get(root, parent_pointer), parent_vocabularies)) {\n      return std::cref(parent.value().get().pointer);\n    }\n\n    current_pointer = parent_pointer;\n    current_parent = parent.value().get().parent;\n  }\n\n  return std::nullopt;\n}\n\ntemplate <typename MatchCallback>\nauto WALK_UP_IN_PLACE_APPLICATORS(const JSON &root, const SchemaFrame &frame,\n                                  const SchemaFrame::Location &location,\n                                  const SchemaWalker &walker,\n                                  const SchemaResolver &resolver,\n                                  const MatchCallback &matches)\n    -> std::optional<std::reference_wrapper<const WeakPointer>> {\n  return WALK_UP(root, frame, location, walker, resolver,\n                 IS_IN_PLACE_APPLICATOR, matches);\n}\n\n#define ONLY_CONTINUE_IF(condition)                                            \\\n  if (!(condition)) {                                                          \\\n    return false;                                                              \\\n  }\n\n#include \"canonicalizer/additional_items_implicit.h\"\n#include \"canonicalizer/allof_merge_compatible_branches.h\"\n#include \"canonicalizer/comment_drop.h\"\n#include \"canonicalizer/const_as_enum.h\"\n#include \"canonicalizer/dependencies_to_any_of.h\"\n#include \"canonicalizer/dependencies_to_extends_disallow.h\"\n#include \"canonicalizer/dependent_required_to_any_of.h\"\n#include \"canonicalizer/dependent_schemas_to_any_of.h\"\n#include \"canonicalizer/deprecated_false_drop.h\"\n#include \"canonicalizer/disallow_to_array_of_schemas.h\"\n#include \"canonicalizer/divisible_by_implicit.h\"\n#include \"canonicalizer/draft3_type_any.h\"\n#include \"canonicalizer/empty_definitions_drop.h\"\n#include \"canonicalizer/empty_defs_drop.h\"\n#include \"canonicalizer/empty_dependencies_drop.h\"\n#include \"canonicalizer/empty_dependent_required_drop.h\"\n#include \"canonicalizer/empty_dependent_schemas_drop.h\"\n#include \"canonicalizer/enum_drop_redundant_validation.h\"\n#include \"canonicalizer/enum_filter_by_type.h\"\n#include \"canonicalizer/exclusive_maximum_boolean_integer_fold.h\"\n#include \"canonicalizer/exclusive_maximum_integer_to_maximum.h\"\n#include \"canonicalizer/exclusive_minimum_boolean_integer_fold.h\"\n#include \"canonicalizer/exclusive_minimum_integer_to_minimum.h\"\n#include \"canonicalizer/extends_to_array.h\"\n#include \"canonicalizer/if_then_else_implicit.h\"\n#include \"canonicalizer/implicit_contains_keywords.h\"\n#include \"canonicalizer/implicit_object_keywords.h\"\n#include \"canonicalizer/inline_single_use_ref.h\"\n#include \"canonicalizer/items_implicit.h\"\n#include \"canonicalizer/max_contains_covered_by_max_items.h\"\n#include \"canonicalizer/max_decimal_implicit.h\"\n#include \"canonicalizer/maximum_can_equal_integer_fold.h\"\n#include \"canonicalizer/maximum_can_equal_true_drop.h\"\n#include \"canonicalizer/min_items_given_min_contains.h\"\n#include \"canonicalizer/min_length_implicit.h\"\n#include \"canonicalizer/min_properties_covered_by_required.h\"\n#include \"canonicalizer/minimum_can_equal_integer_fold.h\"\n#include \"canonicalizer/minimum_can_equal_true_drop.h\"\n#include \"canonicalizer/multiple_of_implicit.h\"\n#include \"canonicalizer/optional_property_implicit.h\"\n#include \"canonicalizer/recursive_anchor_false_drop.h\"\n#include \"canonicalizer/required_property_implicit.h\"\n#include \"canonicalizer/single_branch_allof.h\"\n#include \"canonicalizer/single_branch_anyof.h\"\n#include \"canonicalizer/single_branch_oneof.h\"\n#include \"canonicalizer/type_array_to_any_of.h\"\n#include \"canonicalizer/type_boolean_as_enum.h\"\n#include \"canonicalizer/type_inherit_in_place.h\"\n#include \"canonicalizer/type_null_as_enum.h\"\n#include \"canonicalizer/type_union_implicit.h\"\n#include \"canonicalizer/type_union_to_schemas.h\"\n#include \"canonicalizer/type_with_applicator_to_allof.h\"\n#include \"canonicalizer/type_with_applicator_to_extends.h\"\n#include \"canonicalizer/unevaluated_items_to_items.h\"\n#include \"canonicalizer/unevaluated_properties_to_additional_properties.h\"\n#include \"canonicalizer/unsatisfiable_can_equal_bounds.h\"\n#include \"canonicalizer/unsatisfiable_exclusive_equal_bounds.h\"\n#include \"canonicalizer/unsatisfiable_type_and_enum.h\"\n\n// Common\n#include \"common/allof_false_simplify.h\"\n#include \"common/anyof_false_simplify.h\"\n#include \"common/anyof_remove_false_schemas.h\"\n#include \"common/anyof_true_simplify.h\"\n#include \"common/const_in_enum.h\"\n#include \"common/const_with_type.h\"\n#include \"common/content_media_type_without_encoding.h\"\n#include \"common/content_schema_without_media_type.h\"\n#include \"common/dependencies_property_tautology.h\"\n#include \"common/dependent_required_tautology.h\"\n#include \"common/disallow_narrows_type.h\"\n#include \"common/double_negation_elimination.h\"\n#include \"common/draft_official_dialect_with_https.h\"\n#include \"common/draft_official_dialect_without_empty_fragment.h\"\n#include \"common/draft_ref_siblings.h\"\n#include \"common/drop_allof_empty_schemas.h\"\n#include \"common/drop_extends_empty_schemas.h\"\n#include \"common/duplicate_allof_branches.h\"\n#include \"common/duplicate_anyof_branches.h\"\n#include \"common/duplicate_enum_values.h\"\n#include \"common/duplicate_required_values.h\"\n#include \"common/dynamic_ref_to_static_ref.h\"\n#include \"common/else_without_if.h\"\n#include \"common/empty_object_as_true.h\"\n#include \"common/enum_with_type.h\"\n#include \"common/equal_numeric_bounds_to_enum.h\"\n#include \"common/exclusive_bounds_false_drop.h\"\n#include \"common/exclusive_maximum_number_and_maximum.h\"\n#include \"common/exclusive_minimum_number_and_minimum.h\"\n#include \"common/flatten_nested_allof.h\"\n#include \"common/flatten_nested_anyof.h\"\n#include \"common/flatten_nested_extends.h\"\n#include \"common/if_without_then_else.h\"\n#include \"common/ignored_metaschema.h\"\n#include \"common/max_contains_without_contains.h\"\n#include \"common/maximum_real_for_integer.h\"\n#include \"common/min_contains_without_contains.h\"\n#include \"common/minimum_real_for_integer.h\"\n#include \"common/modern_official_dialect_with_empty_fragment.h\"\n#include \"common/modern_official_dialect_with_http.h\"\n#include \"common/non_applicable_additional_items.h\"\n#include \"common/non_applicable_disallow_types.h\"\n#include \"common/non_applicable_enum_validation_keywords.h\"\n#include \"common/non_applicable_type_specific_keywords.h\"\n#include \"common/not_false.h\"\n#include \"common/oneof_false_simplify.h\"\n#include \"common/oneof_to_anyof_disjoint_types.h\"\n#include \"common/orphan_definitions.h\"\n#include \"common/required_properties_in_properties.h\"\n#include \"common/single_type_array.h\"\n#include \"common/then_without_if.h\"\n#include \"common/unknown_keywords_prefix.h\"\n#include \"common/unknown_local_ref.h\"\n#include \"common/unnecessary_allof_ref_wrapper_draft.h\"\n#include \"common/unnecessary_extends_ref_wrapper.h\"\n#include \"common/unsatisfiable_drop_validation.h\"\n#include \"common/unsatisfiable_in_place_applicator_type.h\"\n#include \"linter/else_empty.h\"\n#include \"linter/then_empty.h\"\n#include \"linter/unnecessary_allof_ref_wrapper_modern.h\"\n#include \"linter/unnecessary_allof_wrapper.h\"\n#include \"linter/unnecessary_extends_wrapper.h\"\n\n// Linter\n#include \"linter/comment_trim.h\"\n#include \"linter/const_not_in_enum.h\"\n#include \"linter/content_schema_default.h\"\n#include \"linter/definitions_to_defs.h\"\n#include \"linter/dependencies_default.h\"\n#include \"linter/dependent_required_default.h\"\n#include \"linter/description_trailing_period.h\"\n#include \"linter/description_trim.h\"\n#include \"linter/disallow_default.h\"\n#include \"linter/divisible_by_default.h\"\n#include \"linter/duplicate_examples.h\"\n#include \"linter/enum_to_const.h\"\n#include \"linter/equal_numeric_bounds_to_const.h\"\n#include \"linter/forbid_empty_enum.h\"\n#include \"linter/incoherent_min_max_contains.h\"\n#include \"linter/invalid_external_ref.h\"\n#include \"linter/items_array_default.h\"\n#include \"linter/items_schema_default.h\"\n#include \"linter/multiple_of_default.h\"\n#include \"linter/pattern_properties_default.h\"\n#include \"linter/portable_anchor_names.h\"\n#include \"linter/properties_default.h\"\n#include \"linter/property_names_default.h\"\n#include \"linter/property_names_type_default.h\"\n#include \"linter/simple_properties_identifiers.h\"\n#include \"linter/title_description_equal.h\"\n#include \"linter/title_trailing_period.h\"\n#include \"linter/title_trim.h\"\n#include \"linter/top_level_description.h\"\n#include \"linter/top_level_examples.h\"\n#include \"linter/top_level_title.h\"\n#include \"linter/unevaluated_items_default.h\"\n#include \"linter/unevaluated_properties_default.h\"\n#include \"linter/unknown_format_prefix.h\"\n#include \"linter/unsatisfiable_max_contains.h\"\n#include \"linter/unsatisfiable_min_properties.h\"\n#include \"linter/valid_default.h\"\n#include \"linter/valid_examples.h\"\n\n// Upgrade\n#include \"upgrade/helpers.h\"\n#include \"upgrade/prefix_promoted_2020_12_keywords.h\"\n#include \"upgrade/prefix_promoted_draft_2019_09_keywords.h\"\n#include \"upgrade/prefix_promoted_draft_4_keywords.h\"\n#include \"upgrade/prefix_promoted_draft_6_keywords.h\"\n#include \"upgrade/prefix_promoted_draft_7_keywords.h\"\n#include \"upgrade/upgrade_2019_09_to_2020_12.h\"\n#include \"upgrade/upgrade_dialect_override_cleanup.h\"\n#include \"upgrade/upgrade_draft_3_to_draft_4.h\"\n#include \"upgrade/upgrade_draft_4_to_draft_6.h\"\n#include \"upgrade/upgrade_draft_6_to_draft_7.h\"\n#include \"upgrade/upgrade_draft_7_to_draft_2019_09.h\"\n\n#undef ONLY_CONTINUE_IF\n} // namespace sourcemeta::blaze\n\nnamespace sourcemeta::blaze {\n\nauto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void {\n  if (mode == AlterSchemaMode::UpgradeDraft4 ||\n      mode == AlterSchemaMode::UpgradeDraft6 ||\n      mode == AlterSchemaMode::UpgradeDraft7 ||\n      mode == AlterSchemaMode::Upgrade201909 ||\n      mode == AlterSchemaMode::Upgrade202012) {\n    bundle.add<DraftOfficialDialectWithHttps>();\n    bundle.add<DraftOfficialDialectWithoutEmptyFragment>();\n    bundle.add<PrefixPromotedDraft4Keywords>();\n    bundle.add<UpgradeDraft3ToDraft4>();\n\n    if (mode == AlterSchemaMode::UpgradeDraft6 ||\n        mode == AlterSchemaMode::UpgradeDraft7 ||\n        mode == AlterSchemaMode::Upgrade201909 ||\n        mode == AlterSchemaMode::Upgrade202012) {\n      bundle.add<PrefixPromotedDraft6Keywords>();\n      bundle.add<UpgradeDraft4ToDraft6>();\n      bundle.add<EmptyObjectAsTrue>();\n    }\n\n    if (mode == AlterSchemaMode::UpgradeDraft7 ||\n        mode == AlterSchemaMode::Upgrade201909 ||\n        mode == AlterSchemaMode::Upgrade202012) {\n      bundle.add<PrefixPromotedDraft7Keywords>();\n      bundle.add<UpgradeDraft6ToDraft7>();\n      bundle.add<EnumToConst>();\n    }\n\n    if (mode == AlterSchemaMode::Upgrade201909 ||\n        mode == AlterSchemaMode::Upgrade202012) {\n      bundle.add<PrefixPromoted201909Keywords>();\n      bundle.add<UpgradeDraft7To201909>();\n      bundle.add<DefinitionsToDefs>();\n    }\n\n    if (mode == AlterSchemaMode::Upgrade202012) {\n      bundle.add<PrefixPromoted202012Keywords>();\n      bundle.add<Upgrade201909To202012>();\n    }\n\n    bundle.add<UpgradeDialectOverrideCleanup>();\n\n    return;\n  }\n\n  if (mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<ExclusiveMinimumBooleanIntegerFold>();\n    bundle.add<ExclusiveMaximumBooleanIntegerFold>();\n    bundle.add<UnsatisfiableExclusiveEqualBounds>();\n    bundle.add<MinimumCanEqualIntegerFold>();\n    bundle.add<MaximumCanEqualIntegerFold>();\n    bundle.add<MinimumCanEqualTrueDrop>();\n    bundle.add<MaximumCanEqualTrueDrop>();\n    bundle.add<CommentDrop>();\n    bundle.add<DeprecatedFalseDrop>();\n    bundle.add<RecursiveAnchorFalseDrop>();\n    bundle.add<UnevaluatedItemsToItems>();\n    bundle.add<UnevaluatedPropertiesToAdditionalProperties>();\n    bundle.add<IfThenElseImplicit>();\n    bundle.add<ImplicitObjectKeywords>();\n    bundle.add<ImplicitContainsKeywords>();\n    bundle.add<ExtendsToArray>();\n    bundle.add<DisallowToArrayOfSchemas>();\n  }\n\n  if (mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<InlineSingleUseRef>();\n    bundle.add<AllOfMergeCompatibleBranches>();\n    bundle.add<TypeInheritInPlace>();\n    bundle.add<TypeUnionImplicit>();\n    bundle.add<TypeArrayToAnyOf>();\n  }\n\n  if (mode == AlterSchemaMode::Linter ||\n      mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<DefinitionsToDefs>();\n  }\n\n  bundle.add<ContentMediaTypeWithoutEncoding>();\n  bundle.add<ContentSchemaWithoutMediaType>();\n  bundle.add<DraftOfficialDialectWithHttps>();\n  bundle.add<DraftOfficialDialectWithoutEmptyFragment>();\n  bundle.add<NonApplicableTypeSpecificKeywords>();\n  bundle.add<NonApplicableDisallowTypes>();\n  bundle.add<DisallowNarrowsType>();\n  bundle.add<AnyOfRemoveFalseSchemas>();\n  bundle.add<AnyOfTrueSimplify>();\n  bundle.add<DuplicateAllOfBranches>();\n  bundle.add<DuplicateAnyOfBranches>();\n  bundle.add<FlattenNestedAllOf>();\n  bundle.add<FlattenNestedExtends>();\n  bundle.add<FlattenNestedAnyOf>();\n  if (mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<Draft3TypeAny>();\n  }\n  bundle.add<UnsatisfiableInPlaceApplicatorType>();\n  bundle.add<AllOfFalseSimplify>();\n  bundle.add<AnyOfFalseSimplify>();\n  bundle.add<OneOfFalseSimplify>();\n  bundle.add<DoubleNegationElimination>();\n  bundle.add<OneOfToAnyOfDisjointTypes>();\n  bundle.add<UnsatisfiableDropValidation>();\n  bundle.add<ElseWithoutIf>();\n  bundle.add<IfWithoutThenElse>();\n  bundle.add<IgnoredMetaschema>();\n  bundle.add<MaxContainsWithoutContains>();\n  bundle.add<MinContainsWithoutContains>();\n  bundle.add<NotFalse>();\n  if (mode != AlterSchemaMode::Canonicalizer) {\n    bundle.add<ThenEmpty>();\n    bundle.add<ElseEmpty>();\n  }\n  bundle.add<ThenWithoutIf>();\n  bundle.add<DependenciesPropertyTautology>();\n  bundle.add<DependentRequiredTautology>();\n  bundle.add<EqualNumericBoundsToEnum>();\n  bundle.add<MaximumRealForInteger>();\n  bundle.add<MinimumRealForInteger>();\n  bundle.add<SingleTypeArray>();\n  bundle.add<EnumWithType>();\n  bundle.add<NonApplicableEnumValidationKeywords>();\n  bundle.add<DuplicateEnumValues>();\n  bundle.add<DuplicateRequiredValues>();\n  bundle.add<ConstWithType>();\n  bundle.add<ConstInEnum>();\n  bundle.add<NonApplicableAdditionalItems>();\n  bundle.add<ModernOfficialDialectWithEmptyFragment>();\n  bundle.add<ModernOfficialDialectWithHttp>();\n  bundle.add<ExclusiveMaximumNumberAndMaximum>();\n  bundle.add<ExclusiveMinimumNumberAndMinimum>();\n  bundle.add<ExclusiveBoundsFalseDrop>();\n  bundle.add<DraftRefSiblings>();\n  bundle.add<DynamicRefToStaticRef>();\n  bundle.add<UnknownKeywordsPrefix>();\n  bundle.add<UnknownLocalRef>();\n  bundle.add<RequiredPropertiesInProperties>();\n  bundle.add<OrphanDefinitions>();\n\n  if (mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<ConstAsEnum>();\n    bundle.add<EqualNumericBoundsToConst>();\n    bundle.add<ExclusiveMaximumIntegerToMaximum>();\n    bundle.add<ExclusiveMinimumIntegerToMinimum>();\n    bundle.add<TypeBooleanAsEnum>();\n    bundle.add<TypeNullAsEnum>();\n    bundle.add<MaxContainsCoveredByMaxItems>();\n    bundle.add<MinItemsGivenMinContains>();\n    bundle.add<MinPropertiesCoveredByRequired>();\n    bundle.add<MinLengthImplicit>();\n    bundle.add<MultipleOfImplicit>();\n    bundle.add<DivisibleByImplicit>();\n    bundle.add<MaxDecimalImplicit>();\n    bundle.add<ItemsImplicit>();\n  }\n\n  if (mode == AlterSchemaMode::Linter) {\n    bundle.add<EqualNumericBoundsToConst>();\n    bundle.add<ConstNotInEnum>();\n    bundle.add<ContentSchemaDefault>();\n    bundle.add<DependenciesDefault>();\n    bundle.add<DependentRequiredDefault>();\n    bundle.add<ItemsArrayDefault>();\n    bundle.add<ItemsSchemaDefault>();\n    bundle.add<DisallowDefault>();\n    bundle.add<DivisibleByDefault>();\n    bundle.add<MultipleOfDefault>();\n    bundle.add<PatternPropertiesDefault>();\n    bundle.add<PropertiesDefault>();\n    bundle.add<PropertyNamesDefault>();\n    bundle.add<PropertyNamesTypeDefault>();\n    bundle.add<UnevaluatedItemsDefault>();\n    bundle.add<UnevaluatedPropertiesDefault>();\n    bundle.add<UnsatisfiableMaxContains>();\n    bundle.add<IncoherentMinMaxContains>();\n    bundle.add<UnsatisfiableMinProperties>();\n    bundle.add<EnumToConst>();\n    bundle.add<ForbidEmptyEnum>();\n    bundle.add<TopLevelTitle>();\n    bundle.add<TopLevelDescription>();\n    bundle.add<TopLevelExamples>();\n    bundle.add<TitleDescriptionEqual>();\n    bundle.add<TitleTrailingPeriod>();\n    bundle.add<DescriptionTrailingPeriod>();\n    bundle.add<TitleTrim>();\n    bundle.add<DescriptionTrim>();\n    bundle.add<CommentTrim>();\n    bundle.add<DuplicateExamples>();\n    bundle.add<SimplePropertiesIdentifiers>();\n    bundle.add<PortableAnchorNames>();\n    bundle.add<InvalidExternalRef>();\n    bundle.add<UnknownFormatPrefix>();\n    bundle.add<ValidDefault>();\n    bundle.add<ValidExamples>();\n  }\n\n  if (mode != AlterSchemaMode::Canonicalizer) {\n    bundle.add<UnnecessaryAllOfRefWrapperModern>();\n  }\n  bundle.add<UnnecessaryAllOfRefWrapperDraft>();\n  bundle.add<UnnecessaryExtendsRefWrapper>();\n\n  if (mode != AlterSchemaMode::Canonicalizer) {\n    bundle.add<UnnecessaryAllOfWrapper>();\n    bundle.add<UnnecessaryExtendsWrapper>();\n  }\n\n  bundle.add<DropAllOfEmptySchemas>();\n  bundle.add<DropExtendsEmptySchemas>();\n  bundle.add<EmptyObjectAsTrue>();\n\n  if (mode == AlterSchemaMode::Canonicalizer) {\n    bundle.add<UnsatisfiableTypeAndEnum>();\n    bundle.add<EnumFilterByType>();\n    bundle.add<TypeUnionToSchemas>();\n    bundle.add<DependenciesToAnyOf>();\n    bundle.add<DependenciesToExtendsDisallow>();\n    bundle.add<DependentSchemasToAnyOf>();\n    bundle.add<DependentRequiredToAnyOf>();\n    bundle.add<EnumDropRedundantValidation>();\n    bundle.add<TypeWithApplicatorToAllOf>();\n    bundle.add<TypeWithApplicatorToExtends>();\n    bundle.add<EmptyDefinitionsDrop>();\n    bundle.add<EmptyDefsDrop>();\n    bundle.add<EmptyDependenciesDrop>();\n    bundle.add<EmptyDependentSchemasDrop>();\n    bundle.add<EmptyDependentRequiredDrop>();\n    bundle.add<AdditionalItemsImplicit>();\n    bundle.add<RequiredPropertyImplicit>();\n    bundle.add<OptionalPropertyImplicit>();\n    bundle.add<SingleBranchAllOf>();\n    bundle.add<SingleBranchAnyOf>();\n    bundle.add<SingleBranchOneOf>();\n  }\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/additional_items_implicit.h",
    "content": "class AdditionalItemsImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AdditionalItemsImplicit()\n      : SchemaTransformRule{\"additional_items_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() && type->to_string() == \"array\");\n    const auto *items{schema.try_at(\"items\")};\n    ONLY_CONTINUE_IF(items && items->is_array() &&\n                     !schema.defines(\"additionalItems\"));\n    this->is_draft3_ =\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"additionalItems\", this->is_draft3_\n                                         ? sourcemeta::core::JSON::make_object()\n                                         : sourcemeta::core::JSON{true});\n  }\n\nprivate:\n  mutable bool is_draft3_{false};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/allof_merge_compatible_branches.h",
    "content": "class AllOfMergeCompatibleBranches final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AllOfMergeCompatibleBranches()\n      : SchemaTransformRule{\"allof_merge_compatible_branches\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *all_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array() && all_of->size() >= 2);\n\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n\n    const auto &branches{*all_of};\n\n    for (std::size_t index_a = 0; index_a < branches.size(); ++index_a) {\n      const auto &branch_a{branches.at(index_a)};\n      if (!is_mergeable_branch(branch_a)) {\n        continue;\n      }\n\n      for (std::size_t index_b = index_a + 1; index_b < branches.size();\n           ++index_b) {\n        const auto &branch_b{branches.at(index_b)};\n        if (!is_mergeable_branch(branch_b)) {\n          continue;\n        }\n\n        const auto a_is_type_only{is_type_only_branch(branch_a)};\n        const auto b_is_type_only{is_type_only_branch(branch_b)};\n        if (!a_is_type_only && !b_is_type_only) {\n          continue;\n        }\n\n        const auto &non_type_branch{a_is_type_only ? branch_b : branch_a};\n        if (has_in_place_applicators(non_type_branch)) {\n          continue;\n        }\n\n        if (has_overlapping_keywords(branch_a, branch_b)) {\n          continue;\n        }\n\n        if (has_cross_dependencies(branch_a, branch_b, walker, vocabularies)) {\n          continue;\n        }\n\n        this->merge_into_ = index_a;\n        this->merge_from_ = index_b;\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    auto &target{schema.at(KEYWORD).at(this->merge_into_)};\n    const auto &source{schema.at(KEYWORD).at(this->merge_from_)};\n    target.merge(source.as_object());\n    schema.at(KEYWORD).erase(\n        std::next(schema.at(KEYWORD).as_array().begin(),\n                  static_cast<std::ptrdiff_t>(this->merge_from_)));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    const auto relative{target.resolve_from(current)};\n    if (relative.size() < 2 || !relative.at(0).is_property() ||\n        relative.at(0).to_property() != KEYWORD || !relative.at(1).is_index()) {\n      return target;\n    }\n\n    const auto index{relative.at(1).to_index()};\n    if (index == this->merge_from_) {\n      const Pointer old_prefix{current.concat({KEYWORD, this->merge_from_})};\n      const Pointer new_prefix{current.concat({KEYWORD, this->merge_into_})};\n      return target.rebase(old_prefix, new_prefix);\n    }\n\n    if (index > this->merge_from_) {\n      const Pointer old_prefix{current.concat({KEYWORD, index})};\n      const Pointer new_prefix{current.concat({KEYWORD, index - 1})};\n      return target.rebase(old_prefix, new_prefix);\n    }\n\n    return target;\n  }\n\nprivate:\n  static auto is_type_only_branch(const JSON &branch) -> bool {\n    return branch.size() == 1 && branch.defines(\"type\");\n  }\n\n  static auto has_in_place_applicators(const JSON &branch) -> bool {\n    return branch.defines(\"anyOf\") || branch.defines(\"oneOf\") ||\n           branch.defines(\"allOf\") || branch.defines(\"not\") ||\n           branch.defines(\"if\");\n  }\n\n  static auto is_mergeable_branch(const JSON &branch) -> bool {\n    if (!branch.is_object()) {\n      return false;\n    }\n    return !branch.defines(\"$ref\") && !branch.defines(\"$dynamicRef\") &&\n           !branch.defines(\"$recursiveRef\") && !branch.defines(\"$id\") &&\n           !branch.defines(\"$schema\") && !branch.defines(\"id\") &&\n           !branch.defines(\"$anchor\") && !branch.defines(\"$dynamicAnchor\") &&\n           !branch.defines(\"$recursiveAnchor\");\n  }\n\n  static auto has_overlapping_keywords(const JSON &branch_a,\n                                       const JSON &branch_b) -> bool {\n    for (const auto &entry : branch_a.as_object()) {\n      if (branch_b.defines(entry.first)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  static auto\n  has_cross_dependencies(const JSON &branch_a, const JSON &branch_b,\n                         const sourcemeta::core::SchemaWalker &walker,\n                         const sourcemeta::core::Vocabularies &vocabularies)\n      -> bool {\n    for (const auto &entry_a : branch_a.as_object()) {\n      const auto &metadata{walker(entry_a.first, vocabularies)};\n      for (const auto &dependency : metadata.dependencies) {\n        if (branch_b.defines(JSON::String{dependency})) {\n          return true;\n        }\n      }\n    }\n\n    for (const auto &entry_b : branch_b.as_object()) {\n      const auto &metadata{walker(entry_b.first, vocabularies)};\n      for (const auto &dependency : metadata.dependencies) {\n        if (branch_a.defines(JSON::String{dependency})) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  mutable std::size_t merge_into_{0};\n  mutable std::size_t merge_from_{0};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/comment_drop.h",
    "content": "class CommentDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  CommentDrop() : SchemaTransformRule{\"comment_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_2019_09_Core,\n                          Vocabularies::Known::JSON_Schema_2020_12_Core}) &&\n                     schema.is_object() && schema.defines(\"$comment\"));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"$comment\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/const_as_enum.h",
    "content": "class ConstAsEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ConstAsEnum()\n      : SchemaTransformRule{\"const_as_enum\",\n                            \"Setting `const` is syntax sugar for an \"\n                            \"enumeration of a single value\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && schema.defines(\"const\") &&\n                     !schema.defines(\"enum\"));\n    return APPLIES_TO_KEYWORDS(\"const\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto values = sourcemeta::core::JSON::make_array();\n    values.push_back(schema.at(\"const\"));\n    schema.at(\"const\").into(std::move(values));\n    schema.rename(\"const\", \"enum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/dependencies_to_any_of.h",
    "content": "class DependenciesToAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependenciesToAnyOf() : SchemaTransformRule{\"dependencies_to_any_of\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_4,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7}) &&\n        schema.is_object());\n\n    const auto *dependencies{schema.try_at(\"dependencies\")};\n    ONLY_CONTINUE_IF(dependencies && dependencies->is_object());\n\n    ONLY_CONTINUE_IF(\n        std::ranges::any_of(dependencies->as_object(), [](const auto &entry) {\n          return is_schema(entry.second) || entry.second.is_array();\n        }));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto result_branches{JSON::make_array()};\n\n    std::vector<JSON::String> processed;\n    for (const auto &entry : schema.at(\"dependencies\").as_object()) {\n      if (is_schema(entry.second)) {\n        auto not_required{JSON::make_object()};\n        not_required.assign(\"type\", JSON{\"object\"});\n        not_required.assign(\"required\", JSON::make_array());\n        not_required.at(\"required\").push_back(JSON{entry.first});\n        auto not_branch{JSON::make_object()};\n        not_branch.assign(\"not\", std::move(not_required));\n\n        auto required_obj{JSON::make_object()};\n        required_obj.assign(\"type\", JSON{\"object\"});\n        required_obj.assign(\"required\", JSON::make_array());\n        required_obj.at(\"required\").push_back(JSON{entry.first});\n\n        auto all_of{JSON::make_array()};\n        all_of.push_back(std::move(required_obj));\n        all_of.push_back(entry.second);\n\n        auto allof_branch{JSON::make_object()};\n        allof_branch.assign(\"allOf\", std::move(all_of));\n\n        auto pair{JSON::make_array()};\n        pair.push_back(std::move(not_branch));\n        pair.push_back(std::move(allof_branch));\n\n        auto wrapper{JSON::make_object()};\n        wrapper.assign(\"anyOf\", std::move(pair));\n        result_branches.push_back(std::move(wrapper));\n      } else if (entry.second.is_array()) {\n        auto required_all{JSON::make_array()};\n        required_all.push_back(JSON{entry.first});\n        for (const auto &dependent : entry.second.as_array()) {\n          required_all.push_back(dependent);\n        }\n\n        auto not_required{JSON::make_object()};\n        not_required.assign(\"type\", JSON{\"object\"});\n        not_required.assign(\"required\", JSON::make_array());\n        not_required.at(\"required\").push_back(JSON{entry.first});\n        auto not_branch{JSON::make_object()};\n        not_branch.assign(\"not\", std::move(not_required));\n\n        auto required_branch{JSON::make_object()};\n        required_branch.assign(\"type\", JSON{\"object\"});\n        required_branch.assign(\"required\", std::move(required_all));\n\n        auto pair{JSON::make_array()};\n        pair.push_back(std::move(not_branch));\n        pair.push_back(std::move(required_branch));\n\n        auto wrapper{JSON::make_object()};\n        wrapper.assign(\"anyOf\", std::move(pair));\n        result_branches.push_back(std::move(wrapper));\n      } else {\n        continue;\n      }\n\n      processed.emplace_back(entry.first);\n    }\n\n    for (const auto &key : processed) {\n      schema.at(\"dependencies\").erase(key);\n    }\n\n    if (schema.at(\"dependencies\").empty()) {\n      schema.erase(\"dependencies\");\n    }\n\n    if (schema.defines(\"allOf\") && schema.at(\"allOf\").is_array()) {\n      for (auto &item : result_branches.as_array()) {\n        schema.at(\"allOf\").push_back(std::move(item));\n      }\n    } else {\n      schema.assign(\"allOf\", std::move(result_branches));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/dependencies_to_extends_disallow.h",
    "content": "class DependenciesToExtendsDisallow final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependenciesToExtendsDisallow()\n      : SchemaTransformRule{\"dependencies_to_extends_disallow\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3) &&\n        schema.is_object());\n\n    const auto *dependencies{schema.try_at(\"dependencies\")};\n    ONLY_CONTINUE_IF(dependencies && dependencies->is_object());\n\n    ONLY_CONTINUE_IF(\n        std::ranges::any_of(dependencies->as_object(), [](const auto &entry) {\n          return is_schema(entry.second) || entry.second.is_array() ||\n                 entry.second.is_string();\n        }));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto result_branches{JSON::make_array()};\n    std::vector<JSON::String> processed;\n\n    for (const auto &entry : schema.at(\"dependencies\").as_object()) {\n      auto required_property{JSON::make_object()};\n      required_property.assign(\"type\", JSON{\"object\"});\n      auto required_props{JSON::make_object()};\n      auto required_prop_schema{JSON::make_object()};\n      required_prop_schema.assign(\"required\", JSON{true});\n      required_props.assign(entry.first, std::move(required_prop_schema));\n      required_property.assign(\"properties\", std::move(required_props));\n      required_property.assign(\"patternProperties\", JSON::make_object());\n      required_property.assign(\"additionalProperties\", JSON::make_object());\n\n      auto not_required{JSON::make_object()};\n      auto disallow_array{JSON::make_array()};\n      disallow_array.push_back(required_property);\n      not_required.assign(\"disallow\", std::move(disallow_array));\n\n      if (is_schema(entry.second)) {\n        auto extends_array{JSON::make_array()};\n        auto required_copy{JSON::make_object()};\n        required_copy.assign(\"type\", JSON{\"object\"});\n        auto req_props_copy{JSON::make_object()};\n        auto req_prop_schema_copy{JSON::make_object()};\n        req_prop_schema_copy.assign(\"required\", JSON{true});\n        req_props_copy.assign(entry.first, std::move(req_prop_schema_copy));\n        required_copy.assign(\"properties\", std::move(req_props_copy));\n        required_copy.assign(\"patternProperties\", JSON::make_object());\n        required_copy.assign(\"additionalProperties\", JSON::make_object());\n        extends_array.push_back(std::move(required_copy));\n        extends_array.push_back(entry.second);\n\n        auto extends_branch{JSON::make_object()};\n        extends_branch.assign(\"extends\", std::move(extends_array));\n\n        auto type_array{JSON::make_array()};\n        type_array.push_back(std::move(not_required));\n        type_array.push_back(std::move(extends_branch));\n\n        auto wrapper{JSON::make_object()};\n        wrapper.assign(\"type\", std::move(type_array));\n        result_branches.push_back(std::move(wrapper));\n      } else if (entry.second.is_string() || entry.second.is_array()) {\n        std::vector<std::string> dependent_props;\n        if (entry.second.is_string()) {\n          dependent_props.push_back(entry.second.to_string());\n        } else {\n          for (const auto &dependent : entry.second.as_array()) {\n            if (dependent.is_string()) {\n              dependent_props.push_back(dependent.to_string());\n            }\n          }\n        }\n\n        auto required_all{JSON::make_object()};\n        required_all.assign(\"type\", JSON{\"object\"});\n        auto all_props{JSON::make_object()};\n        auto trigger_schema{JSON::make_object()};\n        trigger_schema.assign(\"required\", JSON{true});\n        all_props.assign(entry.first, std::move(trigger_schema));\n        for (const auto &dependent_prop : dependent_props) {\n          auto dep_schema{JSON::make_object()};\n          dep_schema.assign(\"required\", JSON{true});\n          all_props.assign(dependent_prop, std::move(dep_schema));\n        }\n        required_all.assign(\"properties\", std::move(all_props));\n        required_all.assign(\"patternProperties\", JSON::make_object());\n        required_all.assign(\"additionalProperties\", JSON::make_object());\n\n        auto type_array{JSON::make_array()};\n        type_array.push_back(std::move(not_required));\n        type_array.push_back(std::move(required_all));\n\n        auto wrapper{JSON::make_object()};\n        wrapper.assign(\"type\", std::move(type_array));\n        result_branches.push_back(std::move(wrapper));\n      } else {\n        continue;\n      }\n\n      processed.emplace_back(entry.first);\n    }\n\n    for (const auto &key : processed) {\n      schema.at(\"dependencies\").erase(key);\n    }\n\n    if (schema.at(\"dependencies\").empty()) {\n      schema.erase(\"dependencies\");\n    }\n\n    if (schema.defines(\"extends\") && schema.at(\"extends\").is_array()) {\n      for (auto &item : result_branches.as_array()) {\n        schema.at(\"extends\").push_back(std::move(item));\n      }\n    } else {\n      schema.assign(\"extends\", std::move(result_branches));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/dependent_required_to_any_of.h",
    "content": "class DependentRequiredToAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependentRequiredToAnyOf()\n      : SchemaTransformRule{\"dependent_required_to_any_of\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        schema.is_object());\n\n    const auto *dependent_required{schema.try_at(\"dependentRequired\")};\n    ONLY_CONTINUE_IF(dependent_required && dependent_required->is_object() &&\n                     !dependent_required->empty());\n\n    ONLY_CONTINUE_IF(std::ranges::any_of(\n        dependent_required->as_object(),\n        [](const auto &entry) { return entry.second.is_array(); }));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto result_branches{JSON::make_array()};\n\n    std::vector<JSON::String> processed;\n    for (const auto &entry : schema.at(\"dependentRequired\").as_object()) {\n      if (!entry.second.is_array()) {\n        continue;\n      }\n\n      auto required_all{JSON::make_array()};\n      required_all.push_back(JSON{entry.first});\n      for (const auto &dependent : entry.second.as_array()) {\n        required_all.push_back(dependent);\n      }\n\n      auto not_required{JSON::make_object()};\n      not_required.assign(\"type\", JSON{\"object\"});\n      not_required.assign(\"required\", JSON::make_array());\n      not_required.at(\"required\").push_back(JSON{entry.first});\n      auto not_branch{JSON::make_object()};\n      not_branch.assign(\"not\", std::move(not_required));\n\n      auto required_branch{JSON::make_object()};\n      required_branch.assign(\"type\", JSON{\"object\"});\n      required_branch.assign(\"required\", std::move(required_all));\n\n      auto pair{JSON::make_array()};\n      pair.push_back(std::move(not_branch));\n      pair.push_back(std::move(required_branch));\n\n      auto wrapper{JSON::make_object()};\n      wrapper.assign(\"anyOf\", std::move(pair));\n      result_branches.push_back(std::move(wrapper));\n\n      processed.emplace_back(entry.first);\n    }\n\n    for (const auto &key : processed) {\n      schema.at(\"dependentRequired\").erase(key);\n    }\n\n    if (schema.at(\"dependentRequired\").empty()) {\n      schema.erase(\"dependentRequired\");\n    }\n\n    if (schema.defines(\"allOf\") && schema.at(\"allOf\").is_array()) {\n      for (auto &item : result_branches.as_array()) {\n        schema.at(\"allOf\").push_back(std::move(item));\n      }\n    } else {\n      schema.assign(\"allOf\", std::move(result_branches));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/dependent_schemas_to_any_of.h",
    "content": "class DependentSchemasToAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependentSchemasToAnyOf()\n      : SchemaTransformRule{\"dependent_schemas_to_any_of\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.is_object());\n\n    const auto *dependent_schemas{schema.try_at(\"dependentSchemas\")};\n    ONLY_CONTINUE_IF(dependent_schemas && dependent_schemas->is_object() &&\n                     !dependent_schemas->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto result_branches{JSON::make_array()};\n\n    for (const auto &entry : schema.at(\"dependentSchemas\").as_object()) {\n      auto not_required{JSON::make_object()};\n      not_required.assign(\"type\", JSON{\"object\"});\n      not_required.assign(\"required\", JSON::make_array());\n      not_required.at(\"required\").push_back(JSON{entry.first});\n      auto not_branch{JSON::make_object()};\n      not_branch.assign(\"not\", std::move(not_required));\n\n      auto required_obj{JSON::make_object()};\n      required_obj.assign(\"type\", JSON{\"object\"});\n      required_obj.assign(\"required\", JSON::make_array());\n      required_obj.at(\"required\").push_back(JSON{entry.first});\n\n      auto all_of{JSON::make_array()};\n      all_of.push_back(std::move(required_obj));\n      all_of.push_back(entry.second);\n\n      auto allof_branch{JSON::make_object()};\n      allof_branch.assign(\"allOf\", std::move(all_of));\n\n      auto pair{JSON::make_array()};\n      pair.push_back(std::move(not_branch));\n      pair.push_back(std::move(allof_branch));\n\n      auto wrapper{JSON::make_object()};\n      wrapper.assign(\"anyOf\", std::move(pair));\n      result_branches.push_back(std::move(wrapper));\n    }\n\n    schema.erase(\"dependentSchemas\");\n\n    if (schema.defines(\"allOf\") && schema.at(\"allOf\").is_array()) {\n      for (auto &item : result_branches.as_array()) {\n        schema.at(\"allOf\").push_back(std::move(item));\n      }\n    } else {\n      schema.assign(\"allOf\", std::move(result_branches));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/deprecated_false_drop.h",
    "content": "class DeprecatedFalseDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DeprecatedFalseDrop() : SchemaTransformRule{\"deprecated_false_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n             Vocabularies::Known::JSON_Schema_2020_12_Meta_Data}) &&\n        schema.is_object());\n\n    const auto *deprecated{schema.try_at(\"deprecated\")};\n    ONLY_CONTINUE_IF(deprecated && deprecated->is_boolean() &&\n                     !deprecated->to_boolean());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"deprecated\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/disallow_to_array_of_schemas.h",
    "content": "class DisallowToArrayOfSchemas final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DisallowToArrayOfSchemas()\n      : SchemaTransformRule{\"disallow_to_array_of_schemas\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3}) &&\n        schema.is_object() && schema.defines(\"disallow\"));\n\n    this->convert_to_schemas_ =\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3);\n\n    const auto &disallow{schema.at(\"disallow\")};\n    if (disallow.is_string()) {\n      return true;\n    }\n\n    if (this->convert_to_schemas_) {\n      ONLY_CONTINUE_IF(disallow.is_array());\n      for (const auto &element : disallow.as_array()) {\n        if (element.is_string()) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    const auto &disallow{schema.at(\"disallow\")};\n\n    if (disallow.is_string()) {\n      auto array{JSON::make_array()};\n      if (this->convert_to_schemas_) {\n        array.push_back(type_string_to_schema(disallow.to_string()));\n      } else {\n        array.push_back(disallow);\n      }\n      schema.assign(\"disallow\", std::move(array));\n      return;\n    }\n\n    auto new_array{JSON::make_array()};\n    for (const auto &element : disallow.as_array()) {\n      if (element.is_string() && this->convert_to_schemas_) {\n        new_array.push_back(type_string_to_schema(element.to_string()));\n      } else {\n        new_array.push_back(element);\n      }\n    }\n    schema.assign(\"disallow\", std::move(new_array));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    return target.rebase(current.concat({\"disallow\"}),\n                         current.concat({\"disallow\", 0}));\n  }\n\nprivate:\n  static auto type_string_to_schema(const std::string &type_name) -> JSON {\n    if (type_name == \"null\") {\n      auto result{JSON::make_object()};\n      auto values{JSON::make_array()};\n      values.push_back(JSON{nullptr});\n      result.assign(\"enum\", std::move(values));\n      return result;\n    }\n\n    if (type_name == \"boolean\") {\n      auto result{JSON::make_object()};\n      auto values{JSON::make_array()};\n      values.push_back(JSON{false});\n      values.push_back(JSON{true});\n      result.assign(\"enum\", std::move(values));\n      return result;\n    }\n\n    if (type_name == \"any\") {\n      return JSON::make_object();\n    }\n\n    auto result{JSON::make_object()};\n    result.assign(\"type\", JSON{type_name});\n    return result;\n  }\n\n  mutable bool convert_to_schemas_{true};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/divisible_by_implicit.h",
    "content": "class DivisibleByImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DivisibleByImplicit() : SchemaTransformRule{\"divisible_by_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3}) &&\n        schema.is_object() && !schema.defines(\"divisibleBy\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"divisibleBy\", sourcemeta::core::JSON{1});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/draft3_type_any.h",
    "content": "class Draft3TypeAny final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  Draft3TypeAny() : SchemaTransformRule{\"draft3_type_any\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type);\n\n    if (type->is_string()) {\n      return type->to_string() == \"any\";\n    }\n\n    if (type->is_array()) {\n      for (const auto &element : type->as_array()) {\n        if (element.is_string() && element.to_string() == \"any\") {\n          return true;\n        }\n        if (element.is_object()) {\n          if (element.empty()) {\n            return true;\n          }\n          if (element.size() == 1) {\n            const auto *element_type{element.try_at(\"type\")};\n            if (element_type && element_type->is_string() &&\n                element_type->to_string() == \"any\") {\n              return true;\n            }\n          }\n        }\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/empty_definitions_drop.h",
    "content": "class EmptyDefinitionsDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EmptyDefinitionsDrop() : SchemaTransformRule{\"empty_definitions_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_4,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7}) &&\n        schema.is_object());\n\n    const auto *definitions{schema.try_at(\"definitions\")};\n    ONLY_CONTINUE_IF(definitions && definitions->is_object() &&\n                     definitions->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"definitions\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/empty_defs_drop.h",
    "content": "class EmptyDefsDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EmptyDefsDrop() : SchemaTransformRule{\"empty_defs_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2019_09_Core,\n                          Vocabularies::Known::JSON_Schema_2020_12_Core}) &&\n                     schema.is_object());\n\n    const auto *defs{schema.try_at(\"$defs\")};\n    ONLY_CONTINUE_IF(defs && defs->is_object() && defs->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"$defs\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/empty_dependencies_drop.h",
    "content": "class EmptyDependenciesDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EmptyDependenciesDrop()\n      : SchemaTransformRule{\"empty_dependencies_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7}) &&\n        schema.is_object());\n\n    const auto *dependencies{schema.try_at(\"dependencies\")};\n    ONLY_CONTINUE_IF(dependencies && dependencies->is_object() &&\n                     dependencies->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"dependencies\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/empty_dependent_required_drop.h",
    "content": "class EmptyDependentRequiredDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EmptyDependentRequiredDrop()\n      : SchemaTransformRule{\"empty_dependent_required_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        schema.is_object());\n\n    const auto *dependent_required{schema.try_at(\"dependentRequired\")};\n    ONLY_CONTINUE_IF(dependent_required && dependent_required->is_object() &&\n                     dependent_required->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"dependentRequired\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/empty_dependent_schemas_drop.h",
    "content": "class EmptyDependentSchemasDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EmptyDependentSchemasDrop()\n      : SchemaTransformRule{\"empty_dependent_schemas_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.is_object());\n\n    const auto *dependent_schemas{schema.try_at(\"dependentSchemas\")};\n    ONLY_CONTINUE_IF(dependent_schemas && dependent_schemas->is_object() &&\n                     dependent_schemas->empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"dependentSchemas\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/enum_drop_redundant_validation.h",
    "content": "class EnumDropRedundantValidation final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumDropRedundantValidation()\n      : SchemaTransformRule{\"enum_drop_redundant_validation\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_0,\n             Vocabularies::Known::JSON_Schema_Draft_1,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        schema.is_object() && !schema.defines(\"type\"));\n\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array());\n\n    this->keywords_.clear();\n    this->wrap_keywords_.clear();\n    this->is_pre_draft4_ =\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3});\n    this->has_if_group_ =\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.defines(\"if\");\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"enum\") {\n        continue;\n      }\n\n      if (this->has_if_group_ &&\n          (entry.first == \"then\" || entry.first == \"else\")) {\n        continue;\n      }\n\n      const auto &metadata{walker(entry.first, vocabularies)};\n      if (metadata.type == sourcemeta::core::SchemaKeywordType::Unknown ||\n          metadata.type == sourcemeta::core::SchemaKeywordType::Annotation ||\n          metadata.type == sourcemeta::core::SchemaKeywordType::Other ||\n          metadata.type == sourcemeta::core::SchemaKeywordType::Comment ||\n          metadata.type ==\n              sourcemeta::core::SchemaKeywordType::LocationMembers) {\n        continue;\n      }\n\n      if (entry.second.is_boolean() && entry.second.to_boolean()) {\n        if (!frame.has_references_through(\n                location.pointer, WeakPointer::Token{std::cref(entry.first)})) {\n          this->keywords_.emplace_back(entry.first);\n        }\n        continue;\n      }\n\n      if (entry.second.is_object() && entry.second.empty()) {\n        this->keywords_.emplace_back(entry.first);\n        continue;\n      }\n\n      if (!frame.has_references_through(\n              location.pointer, WeakPointer::Token{std::cref(entry.first)})) {\n        this->wrap_keywords_.emplace_back(entry.first);\n      }\n    }\n\n    ONLY_CONTINUE_IF(!this->keywords_.empty() || !this->wrap_keywords_.empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    for (const auto &keyword : this->keywords_) {\n      schema.erase(keyword);\n    }\n\n    if (this->wrap_keywords_.empty()) {\n      return;\n    }\n\n    auto new_allof{JSON::make_array()};\n    for (const auto &keyword : this->wrap_keywords_) {\n      auto branch{JSON::make_object()};\n      branch.assign(keyword, schema.at(keyword));\n      if (keyword == \"if\" && this->has_if_group_) {\n        if (schema.defines(\"then\")) {\n          branch.assign(\"then\", schema.at(\"then\"));\n        }\n        if (schema.defines(\"else\")) {\n          branch.assign(\"else\", schema.at(\"else\"));\n        }\n      }\n      new_allof.push_back(std::move(branch));\n      schema.erase(keyword);\n      if (keyword == \"if\" && this->has_if_group_) {\n        if (schema.defines(\"then\")) {\n          schema.erase(\"then\");\n        }\n        if (schema.defines(\"else\")) {\n          schema.erase(\"else\");\n        }\n      }\n    }\n\n    auto enum_branch{JSON::make_object()};\n    enum_branch.assign(\"enum\", schema.at(\"enum\"));\n    schema.erase(\"enum\");\n    new_allof.push_back(std::move(enum_branch));\n\n    const auto wrapper_keyword{this->is_pre_draft4_ ? \"extends\" : \"allOf\"};\n    schema.assign(wrapper_keyword, std::move(new_allof));\n  }\n\nprivate:\n  mutable std::vector<JSON::String> keywords_;\n  mutable std::vector<JSON::String> wrap_keywords_;\n  mutable bool has_if_group_{false};\n  mutable bool is_pre_draft4_{false};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/enum_filter_by_type.h",
    "content": "class EnumFilterByType final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumFilterByType() : SchemaTransformRule{\"enum_filter_by_type\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_0,\n             Vocabularies::Known::JSON_Schema_Draft_1,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string());\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\n                     !enum_value->empty());\n\n    const auto declared_types{parse_schema_type(*type)};\n    ONLY_CONTINUE_IF(declared_types.any());\n    const bool integer_matches_integral{\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        declared_types.test(std::to_underlying(JSON::Type::Integer))};\n\n    this->matching_indices_.clear();\n    bool has_mismatch{false};\n    std::size_t index{0};\n    for (const auto &value : enum_value->as_array()) {\n      const bool matches{\n          declared_types.test(std::to_underlying(value.type())) ||\n          (integer_matches_integral && value.is_integral())};\n      if (matches) {\n        this->matching_indices_.push_back(index);\n      } else {\n        has_mismatch = true;\n      }\n      index++;\n    }\n\n    ONLY_CONTINUE_IF(!this->matching_indices_.empty() && has_mismatch);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto filtered{JSON::make_array()};\n    for (const auto &index : this->matching_indices_) {\n      filtered.push_back(schema.at(\"enum\").at(index));\n    }\n\n    schema.assign(\"enum\", std::move(filtered));\n  }\n\nprivate:\n  mutable std::vector<std::size_t> matching_indices_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/exclusive_maximum_boolean_integer_fold.h",
    "content": "class ExclusiveMaximumBooleanIntegerFold final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMaximumBooleanIntegerFold()\n      : SchemaTransformRule{\"exclusive_maximum_boolean_integer_fold\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    ONLY_CONTINUE_IF(exclusive_maximum && exclusive_maximum->is_boolean() &&\n                     exclusive_maximum->to_boolean());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    const auto &maximum{schema.at(\"maximum\")};\n    if (maximum.is_integer()) {\n      if (maximum.to_integer() > std::numeric_limits<std::int64_t>::min()) {\n        auto new_maximum = maximum;\n        new_maximum += sourcemeta::core::JSON{-1};\n        schema.assign(\"maximum\", std::move(new_maximum));\n      } else {\n        auto result{\n            sourcemeta::core::Decimal{std::to_string(maximum.to_integer())}};\n        result -= sourcemeta::core::Decimal{1};\n        schema.assign(\"maximum\", sourcemeta::core::JSON{std::move(result)});\n      }\n    } else if (maximum.is_decimal()) {\n      auto current{maximum.to_decimal()};\n      auto floored{current.to_integral()};\n      if (floored > current) {\n        floored -= sourcemeta::core::Decimal{1};\n      }\n\n      if (floored == current) {\n        floored -= sourcemeta::core::Decimal{1};\n      }\n\n      if (floored.is_int64()) {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{floored.to_int64()});\n      } else {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{std::move(floored)});\n      }\n    } else {\n      const auto value{maximum.to_real()};\n      const auto floor_value{std::floor(value)};\n      if (floor_value == value) {\n        if (value >=\n                static_cast<double>(std::numeric_limits<std::int64_t>::min()) &&\n            value <\n                static_cast<double>(std::numeric_limits<std::int64_t>::max()) +\n                    1.0) {\n          auto decimal_result{sourcemeta::core::Decimal{\n              std::to_string(static_cast<std::int64_t>(value))}};\n          decimal_result -= sourcemeta::core::Decimal{1};\n          if (decimal_result.is_int64()) {\n            schema.assign(\"maximum\",\n                          sourcemeta::core::JSON{decimal_result.to_int64()});\n          } else {\n            schema.assign(\"maximum\",\n                          sourcemeta::core::JSON{std::move(decimal_result)});\n          }\n        } else {\n          auto decimal_fallback{sourcemeta::core::Decimal{value}};\n          decimal_fallback -= sourcemeta::core::Decimal{1};\n          schema.assign(\"maximum\",\n                        sourcemeta::core::JSON{std::move(decimal_fallback)});\n        }\n      } else if (std::isfinite(floor_value) &&\n                 floor_value >= static_cast<double>(\n                                    std::numeric_limits<std::int64_t>::min()) &&\n                 floor_value < static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::max()) +\n                                   1.0) {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{\n                                     static_cast<std::int64_t>(floor_value)});\n      } else {\n        auto decimal_result{sourcemeta::core::Decimal{value}};\n        decimal_result = decimal_result.to_integral();\n        if (decimal_result > sourcemeta::core::Decimal{value}) {\n          decimal_result -= sourcemeta::core::Decimal{1};\n        }\n\n        schema.assign(\"maximum\",\n                      sourcemeta::core::JSON{std::move(decimal_result)});\n      }\n    }\n\n    schema.erase(\"exclusiveMaximum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/exclusive_maximum_integer_to_maximum.h",
    "content": "class ExclusiveMaximumIntegerToMaximum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMaximumIntegerToMaximum()\n      : SchemaTransformRule{\n            \"exclusive_maximum_integer_to_maximum\",\n            \"Setting `exclusiveMaximum` when `type` is `integer` is syntax \"\n            \"sugar for `maximum`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"maximum\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    ONLY_CONTINUE_IF(exclusive_maximum && exclusive_maximum->is_number());\n    return APPLIES_TO_KEYWORDS(\"exclusiveMaximum\", \"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"exclusiveMaximum\").is_integer()) {\n      if (schema.at(\"exclusiveMaximum\").to_integer() >\n          std::numeric_limits<std::int64_t>::min()) {\n        auto new_maximum = schema.at(\"exclusiveMaximum\");\n        new_maximum += sourcemeta::core::JSON{-1};\n        schema.at(\"exclusiveMaximum\").into(new_maximum);\n      } else {\n        auto result{sourcemeta::core::Decimal{\n            std::to_string(schema.at(\"exclusiveMaximum\").to_integer())}};\n        result -= sourcemeta::core::Decimal{1};\n        schema.at(\"exclusiveMaximum\")\n            .into(sourcemeta::core::JSON{std::move(result)});\n      }\n\n      schema.rename(\"exclusiveMaximum\", \"maximum\");\n    } else if (schema.at(\"exclusiveMaximum\").is_decimal()) {\n      const auto current{schema.at(\"exclusiveMaximum\").to_decimal()};\n      auto new_value{current.to_integral()};\n      if (new_value > current) {\n        new_value -= sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value == current) {\n        new_value -= sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value.is_int64()) {\n        schema.at(\"exclusiveMaximum\")\n            .into(sourcemeta::core::JSON{new_value.to_int64()});\n      } else {\n        schema.at(\"exclusiveMaximum\").into(sourcemeta::core::JSON{new_value});\n      }\n\n      schema.rename(\"exclusiveMaximum\", \"maximum\");\n    } else {\n      const auto current{schema.at(\"exclusiveMaximum\").to_real()};\n      const auto floor_value{std::floor(current)};\n      if (floor_value == current) {\n        auto result{sourcemeta::core::Decimal{current}};\n        result -= sourcemeta::core::Decimal{1};\n        if (result.is_int64()) {\n          schema.at(\"exclusiveMaximum\")\n              .into(sourcemeta::core::JSON{result.to_int64()});\n        } else {\n          schema.at(\"exclusiveMaximum\")\n              .into(sourcemeta::core::JSON{std::move(result)});\n        }\n      } else if (std::isfinite(floor_value) &&\n                 floor_value >= static_cast<double>(\n                                    std::numeric_limits<std::int64_t>::min()) &&\n                 floor_value < static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::max()) +\n                                   1.0) {\n        schema.at(\"exclusiveMaximum\")\n            .into(\n                sourcemeta::core::JSON{static_cast<std::int64_t>(floor_value)});\n      } else {\n        auto result{sourcemeta::core::Decimal{current}};\n        result = result.to_integral();\n        if (result > sourcemeta::core::Decimal{current}) {\n          result -= sourcemeta::core::Decimal{1};\n        }\n\n        schema.at(\"exclusiveMaximum\")\n            .into(sourcemeta::core::JSON{std::move(result)});\n      }\n\n      schema.rename(\"exclusiveMaximum\", \"maximum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/exclusive_minimum_boolean_integer_fold.h",
    "content": "class ExclusiveMinimumBooleanIntegerFold final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMinimumBooleanIntegerFold()\n      : SchemaTransformRule{\"exclusive_minimum_boolean_integer_fold\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    ONLY_CONTINUE_IF(exclusive_minimum && exclusive_minimum->is_boolean() &&\n                     exclusive_minimum->to_boolean());\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    const auto &minimum{schema.at(\"minimum\")};\n    if (minimum.is_integer()) {\n      if (minimum.to_integer() < std::numeric_limits<std::int64_t>::max()) {\n        auto new_minimum = minimum;\n        new_minimum += sourcemeta::core::JSON{1};\n        schema.assign(\"minimum\", std::move(new_minimum));\n      } else {\n        auto result{\n            sourcemeta::core::Decimal{std::to_string(minimum.to_integer())}};\n        result += sourcemeta::core::Decimal{1};\n        schema.assign(\"minimum\", sourcemeta::core::JSON{std::move(result)});\n      }\n    } else if (minimum.is_decimal()) {\n      auto current{minimum.to_decimal()};\n      auto ceiled{current.to_integral()};\n      if (ceiled < current) {\n        ceiled += sourcemeta::core::Decimal{1};\n      }\n\n      if (ceiled == current) {\n        ceiled += sourcemeta::core::Decimal{1};\n      }\n\n      if (ceiled.is_int64()) {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{ceiled.to_int64()});\n      } else {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{std::move(ceiled)});\n      }\n    } else {\n      const auto value{minimum.to_real()};\n      const auto ceil_value{std::ceil(value)};\n      if (ceil_value == value) {\n        if (value >=\n                static_cast<double>(std::numeric_limits<std::int64_t>::min()) &&\n            value <\n                static_cast<double>(std::numeric_limits<std::int64_t>::max()) +\n                    1.0) {\n          auto decimal_result{sourcemeta::core::Decimal{\n              std::to_string(static_cast<std::int64_t>(value))}};\n          decimal_result += sourcemeta::core::Decimal{1};\n          if (decimal_result.is_int64()) {\n            schema.assign(\"minimum\",\n                          sourcemeta::core::JSON{decimal_result.to_int64()});\n          } else {\n            schema.assign(\"minimum\",\n                          sourcemeta::core::JSON{std::move(decimal_result)});\n          }\n        } else {\n          auto decimal_fallback{sourcemeta::core::Decimal{value}};\n          decimal_fallback += sourcemeta::core::Decimal{1};\n          schema.assign(\"minimum\",\n                        sourcemeta::core::JSON{std::move(decimal_fallback)});\n        }\n      } else if (std::isfinite(ceil_value) &&\n                 ceil_value >= static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::min()) &&\n                 ceil_value < static_cast<double>(\n                                  std::numeric_limits<std::int64_t>::max()) +\n                                  1.0) {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{\n                                     static_cast<std::int64_t>(ceil_value)});\n      } else {\n        auto decimal_result{sourcemeta::core::Decimal{value}};\n        decimal_result = decimal_result.to_integral();\n        if (decimal_result < sourcemeta::core::Decimal{value}) {\n          decimal_result += sourcemeta::core::Decimal{1};\n        }\n\n        schema.assign(\"minimum\",\n                      sourcemeta::core::JSON{std::move(decimal_result)});\n      }\n    }\n\n    schema.erase(\"exclusiveMinimum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/exclusive_minimum_integer_to_minimum.h",
    "content": "class ExclusiveMinimumIntegerToMinimum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMinimumIntegerToMinimum()\n      : SchemaTransformRule{\n            \"exclusive_minimum_integer_to_minimum\",\n            \"Setting `exclusiveMinimum` when `type` is `integer` is syntax \"\n            \"sugar for `minimum`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"minimum\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    ONLY_CONTINUE_IF(exclusive_minimum && exclusive_minimum->is_number());\n    return APPLIES_TO_KEYWORDS(\"exclusiveMinimum\", \"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"exclusiveMinimum\").is_integer()) {\n      if (schema.at(\"exclusiveMinimum\").to_integer() <\n          std::numeric_limits<std::int64_t>::max()) {\n        auto new_minimum = schema.at(\"exclusiveMinimum\");\n        new_minimum += sourcemeta::core::JSON{1};\n        schema.at(\"exclusiveMinimum\").into(new_minimum);\n      } else {\n        auto result{sourcemeta::core::Decimal{\n            std::to_string(schema.at(\"exclusiveMinimum\").to_integer())}};\n        result += sourcemeta::core::Decimal{1};\n        schema.at(\"exclusiveMinimum\")\n            .into(sourcemeta::core::JSON{std::move(result)});\n      }\n\n      schema.rename(\"exclusiveMinimum\", \"minimum\");\n    } else if (schema.at(\"exclusiveMinimum\").is_decimal()) {\n      const auto current{schema.at(\"exclusiveMinimum\").to_decimal()};\n      auto new_value{current.to_integral()};\n      if (new_value < current) {\n        new_value += sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value == current) {\n        new_value += sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value.is_int64()) {\n        schema.at(\"exclusiveMinimum\")\n            .into(sourcemeta::core::JSON{new_value.to_int64()});\n      } else {\n        schema.at(\"exclusiveMinimum\").into(sourcemeta::core::JSON{new_value});\n      }\n\n      schema.rename(\"exclusiveMinimum\", \"minimum\");\n    } else {\n      const auto current{schema.at(\"exclusiveMinimum\").to_real()};\n      const auto ceil_value{std::ceil(current)};\n      if (ceil_value == current) {\n        auto result{sourcemeta::core::Decimal{current}};\n        result += sourcemeta::core::Decimal{1};\n        if (result.is_int64()) {\n          schema.at(\"exclusiveMinimum\")\n              .into(sourcemeta::core::JSON{result.to_int64()});\n        } else {\n          schema.at(\"exclusiveMinimum\")\n              .into(sourcemeta::core::JSON{std::move(result)});\n        }\n      } else if (std::isfinite(ceil_value) &&\n                 ceil_value >= static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::min()) &&\n                 ceil_value < static_cast<double>(\n                                  std::numeric_limits<std::int64_t>::max()) +\n                                  1.0) {\n        schema.at(\"exclusiveMinimum\")\n            .into(\n                sourcemeta::core::JSON{static_cast<std::int64_t>(ceil_value)});\n      } else {\n        auto result{sourcemeta::core::Decimal{current}};\n        result = result.to_integral();\n        if (result < sourcemeta::core::Decimal{current}) {\n          result += sourcemeta::core::Decimal{1};\n        }\n\n        schema.at(\"exclusiveMinimum\")\n            .into(sourcemeta::core::JSON{std::move(result)});\n      }\n\n      schema.rename(\"exclusiveMinimum\", \"minimum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/extends_to_array.h",
    "content": "class ExtendsToArray final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExtendsToArray() : SchemaTransformRule{\"extends_to_array\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3}) &&\n        schema.is_object());\n\n    const auto *extends{schema.try_at(\"extends\")};\n    ONLY_CONTINUE_IF(extends && !extends->is_array());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto array{sourcemeta::core::JSON::make_array()};\n    array.push_back(schema.at(\"extends\"));\n    schema.assign(\"extends\", std::move(array));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    return target.rebase(current.concat({\"extends\"}),\n                         current.concat({\"extends\", 0}));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/if_then_else_implicit.h",
    "content": "class IfThenElseImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IfThenElseImplicit() : SchemaTransformRule{\"if_then_else_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.is_object() && schema.defines(\"if\") &&\n        (schema.defines(\"then\") || schema.defines(\"else\")) &&\n        (!schema.defines(\"then\") || !schema.defines(\"else\")));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (!schema.defines(\"then\")) {\n      schema.assign(\"then\", JSON{true});\n    }\n    if (!schema.defines(\"else\")) {\n      schema.assign(\"else\", JSON{true});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/implicit_contains_keywords.h",
    "content": "class ImplicitContainsKeywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ImplicitContainsKeywords()\n      : SchemaTransformRule{\"implicit_contains_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() && type->to_string() == \"array\");\n\n    if (schema.defines(\"contains\")) {\n      ONLY_CONTINUE_IF(!schema.defines(\"minContains\"));\n    } else {\n      ONLY_CONTINUE_IF(!schema.defines(\"minContains\") &&\n                       !schema.defines(\"maxContains\"));\n      ONLY_CONTINUE_IF(!WALK_UP_IN_PLACE_APPLICATORS(\n                            root, frame, location, walker, resolver,\n                            [](const JSON &ancestor,\n                               const Vocabularies &ancestor_vocabularies) {\n                              return ancestor.defines(\"unevaluatedItems\") &&\n                                     ancestor_vocabularies.contains(\n                                         Vocabularies::Known::\n                                             JSON_Schema_2020_12_Unevaluated);\n                            })\n                            .has_value());\n    }\n\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (!schema.defines(\"contains\")) {\n      schema.assign(\"contains\", sourcemeta::core::JSON{true});\n      schema.assign(\"minContains\", sourcemeta::core::JSON{0});\n    } else {\n      schema.assign(\"minContains\", sourcemeta::core::JSON{1});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/implicit_object_keywords.h",
    "content": "class ImplicitObjectKeywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ImplicitObjectKeywords()\n      : SchemaTransformRule{\"implicit_object_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string());\n\n    const auto &type_value{type->to_string()};\n    this->reset();\n\n    if (type_value == \"object\") {\n      this->check_object(schema, vocabularies);\n    } else if (type_value == \"array\") {\n      this->check_array(schema, vocabularies);\n    }\n\n    ONLY_CONTINUE_IF(this->has_work_);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    // Object keywords\n    if (this->add_pattern_properties_) {\n      schema.assign(\"patternProperties\", sourcemeta::core::JSON::make_object());\n    }\n\n    if (this->add_property_names_) {\n      schema.assign(\"propertyNames\", sourcemeta::core::JSON{true});\n    }\n\n    if (this->add_min_properties_) {\n      if (schema.defines(\"required\") && schema.at(\"required\").is_array()) {\n        schema.assign(\"minProperties\",\n                      sourcemeta::core::JSON{schema.at(\"required\").size()});\n      } else {\n        schema.assign(\"minProperties\", sourcemeta::core::JSON{0});\n      }\n    }\n\n    if (this->add_properties_) {\n      schema.assign(\"properties\", sourcemeta::core::JSON::make_object());\n    }\n\n    if (this->add_additional_properties_) {\n      schema.assign(\"additionalProperties\",\n                    this->additional_properties_as_object_\n                        ? sourcemeta::core::JSON::make_object()\n                        : sourcemeta::core::JSON{true});\n    }\n\n    // Array keywords\n    if (this->add_unique_items_) {\n      schema.assign(\"uniqueItems\", sourcemeta::core::JSON{false});\n    }\n\n    if (this->add_items_) {\n      schema.assign(\"items\", this->items_as_object_\n                                 ? sourcemeta::core::JSON::make_object()\n                                 : sourcemeta::core::JSON{true});\n    }\n\n    if (this->add_min_items_) {\n      schema.assign(\"minItems\", sourcemeta::core::JSON{0});\n    }\n  }\n\nprivate:\n  auto reset() const -> void {\n    this->has_work_ = false;\n    this->add_pattern_properties_ = false;\n    this->add_property_names_ = false;\n    this->add_min_properties_ = false;\n    this->add_properties_ = false;\n    this->add_additional_properties_ = false;\n    this->additional_properties_as_object_ = false;\n    this->add_unique_items_ = false;\n    this->add_items_ = false;\n    this->items_as_object_ = false;\n    this->add_min_items_ = false;\n  }\n\n  auto check_object(const sourcemeta::core::JSON &schema,\n                    const sourcemeta::core::Vocabularies &vocabularies) const\n      -> void {\n    this->add_pattern_properties_ =\n        !schema.defines(\"patternProperties\") &&\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator});\n\n    this->add_property_names_ =\n        !schema.defines(\"propertyNames\") &&\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator});\n\n    this->add_min_properties_ =\n        !schema.defines(\"minProperties\") &&\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_4});\n\n    this->add_properties_ =\n        !schema.defines(\"properties\") &&\n        ((vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Applicator)) ||\n         (vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Applicator)) ||\n         vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_7,\n                                    Vocabularies::Known::JSON_Schema_Draft_6,\n                                    Vocabularies::Known::JSON_Schema_Draft_4,\n                                    Vocabularies::Known::JSON_Schema_Draft_3,\n                                    Vocabularies::Known::JSON_Schema_Draft_2,\n                                    Vocabularies::Known::JSON_Schema_Draft_1,\n                                    Vocabularies::Known::JSON_Schema_Draft_0}));\n\n    const bool is_legacy{\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7})};\n\n    this->add_additional_properties_ =\n        is_legacy && !schema.defines(\"additionalProperties\");\n    this->additional_properties_as_object_ =\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3});\n\n    this->has_work_ = this->add_pattern_properties_ ||\n                      this->add_property_names_ || this->add_min_properties_ ||\n                      this->add_properties_ || this->add_additional_properties_;\n  }\n\n  auto check_array(const sourcemeta::core::JSON &schema,\n                   const sourcemeta::core::Vocabularies &vocabularies) const\n      -> void {\n    if (!vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_0,\n             Vocabularies::Known::JSON_Schema_Draft_1,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator})) {\n      return;\n    }\n\n    const bool is_modern{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n         Vocabularies::Known::JSON_Schema_2020_12_Applicator})};\n    const bool is_pre_draft4{\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3})};\n\n    this->add_unique_items_ =\n        !schema.defines(\"uniqueItems\") &&\n        !vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                    Vocabularies::Known::JSON_Schema_Draft_1});\n\n    this->add_items_ = !is_modern && !schema.defines(\"items\");\n    this->items_as_object_ = is_pre_draft4;\n\n    this->add_min_items_ = !schema.defines(\"minItems\");\n\n    this->has_work_ =\n        this->add_unique_items_ || this->add_items_ || this->add_min_items_;\n  }\n\n  mutable bool has_work_{false};\n  // Object\n  mutable bool add_pattern_properties_{false};\n  mutable bool add_property_names_{false};\n  mutable bool add_min_properties_{false};\n  mutable bool add_properties_{false};\n  mutable bool add_additional_properties_{false};\n  mutable bool additional_properties_as_object_{false};\n  // Array\n  mutable bool add_unique_items_{false};\n  mutable bool add_items_{false};\n  mutable bool items_as_object_{false};\n  mutable bool add_min_items_{false};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/inline_single_use_ref.h",
    "content": "class InlineSingleUseRef final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  InlineSingleUseRef() : SchemaTransformRule{\"inline_single_use_ref\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object() && schema.size() == 1);\n\n    const auto *ref{schema.try_at(\"$ref\")};\n    ONLY_CONTINUE_IF(ref && ref->is_string());\n\n    if (!location.parent.has_value()) {\n      return false;\n    }\n    {\n      const auto &parent_pointer{location.parent.value()};\n      const auto relative{location.pointer.resolve_from(parent_pointer)};\n      ONLY_CONTINUE_IF(!relative.empty() && relative.at(0).is_property() &&\n                       relative.at(0).to_property() == \"allOf\" &&\n                       relative.size() >= 2 && relative.at(1).is_index());\n      const auto &parent_schema{sourcemeta::core::get(root, parent_pointer)};\n      ONLY_CONTINUE_IF(parent_schema.is_object());\n      const auto *parent_all_of{parent_schema.try_at(\"allOf\")};\n      ONLY_CONTINUE_IF(parent_all_of && parent_all_of->is_array());\n      const auto current_index{relative.at(1).to_index()};\n      bool has_typed_sibling{false};\n      for (std::size_t index = 0; index < parent_all_of->size(); ++index) {\n        if (index == current_index) {\n          continue;\n        }\n        const auto &sibling{parent_all_of->at(index)};\n        if (sibling.is_object() &&\n            (sibling.defines(\"type\") || sibling.defines(\"enum\"))) {\n          has_typed_sibling = true;\n          break;\n        }\n      }\n      ONLY_CONTINUE_IF(has_typed_sibling);\n    }\n\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Core,\n         Vocabularies::Known::JSON_Schema_2019_09_Core,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4}));\n\n    const auto target{frame.traverse(ref->to_string())};\n    ONLY_CONTINUE_IF(target.has_value());\n    const auto &target_pointer{target->get().pointer};\n\n    if (target_pointer.size() < 2 || !target_pointer.at(0).is_property()) {\n      return false;\n    }\n    const auto &container{target_pointer.at(0).to_property()};\n    ONLY_CONTINUE_IF(container == \"definitions\" || container == \"$defs\");\n\n    std::size_t ref_count{0};\n    for (const auto &reference : frame.references()) {\n      const auto dest{frame.traverse(reference.second.destination)};\n      if (!dest.has_value()) {\n        continue;\n      }\n      if (dest->get().pointer.starts_with(target_pointer) ||\n          target_pointer.starts_with(dest->get().pointer)) {\n        ++ref_count;\n      }\n    }\n\n    ONLY_CONTINUE_IF(ref_count == 1);\n\n    const auto &target_schema{sourcemeta::core::get(root, target_pointer)};\n    ONLY_CONTINUE_IF(!target_schema.is_boolean());\n    ONLY_CONTINUE_IF(target_schema.is_object() &&\n                     !target_schema.defines(\"type\") &&\n                     !target_schema.defines(\"enum\"));\n    ONLY_CONTINUE_IF((!target_schema.defines(\"$id\") &&\n                      !target_schema.defines(\"id\") &&\n                      !target_schema.defines(\"$anchor\") &&\n                      !target_schema.defines(\"$dynamicAnchor\") &&\n                      !target_schema.defines(\"$recursiveAnchor\")));\n\n    this->target_pointer_ = sourcemeta::core::to_pointer(target_pointer);\n    this->target_copy_ = target_schema;\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.into(std::move(this->target_copy_));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    if (target.starts_with(this->target_pointer_)) {\n      const auto relative{target.resolve_from(this->target_pointer_)};\n      return current.concat(relative);\n    }\n    return target;\n  }\n\nprivate:\n  mutable Pointer target_pointer_;\n  mutable sourcemeta::core::JSON target_copy_{sourcemeta::core::JSON{nullptr}};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/items_implicit.h",
    "content": "class ItemsImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ItemsImplicit()\n      : SchemaTransformRule{\"items_implicit\",\n                            \"Every array has an implicit `items` \"\n                            \"that consists of the boolean schema `true`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        ((vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Applicator)) ||\n         (vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Applicator)) ||\n         vocabularies.contains_any(\n             {Vocabularies::Known::JSON_Schema_Draft_7,\n              Vocabularies::Known::JSON_Schema_Draft_6})) &&\n        schema.is_object() && !schema.defines(\"items\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() && type->to_string() == \"array\");\n    ONLY_CONTINUE_IF(\n        !(schema.defines(\"unevaluatedItems\") &&\n          vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n               Vocabularies::Known::JSON_Schema_2019_09_Applicator})));\n    ONLY_CONTINUE_IF(\n        !WALK_UP_IN_PLACE_APPLICATORS(\n             root, frame, location, walker, resolver,\n             [](const JSON &ancestor,\n                const Vocabularies &ancestor_vocabularies) {\n               return ancestor.defines(\"unevaluatedItems\") &&\n                      ancestor_vocabularies.contains_any(\n                          {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n                           Vocabularies::Known::\n                               JSON_Schema_2019_09_Applicator});\n             })\n             .has_value());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"items\", JSON{true});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/max_contains_covered_by_max_items.h",
    "content": "class MaxContainsCoveredByMaxItems final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  MaxContainsCoveredByMaxItems()\n      : SchemaTransformRule{\n            \"max_contains_covered_by_max_items\",\n            \"Setting the `maxContains` keyword to a number greater than or \"\n            \"equal to the array upper bound does not add any further \"\n            \"constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object());\n\n    const auto *max_contains{schema.try_at(\"maxContains\")};\n    ONLY_CONTINUE_IF(max_contains && max_contains->is_integer());\n    const auto *max_items{schema.try_at(\"maxItems\")};\n    ONLY_CONTINUE_IF(max_items && max_items->is_integer() &&\n                     max_contains->to_integer() > max_items->to_integer());\n    return APPLIES_TO_KEYWORDS(\"maxContains\", \"maxItems\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"maxContains\", schema.at(\"maxItems\"));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/max_decimal_implicit.h",
    "content": "class MaxDecimalImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MaxDecimalImplicit() : SchemaTransformRule{\"max_decimal_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1}) &&\n        schema.is_object() && !schema.defines(\"maxDecimal\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"maxDecimal\", sourcemeta::core::JSON{0});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/maximum_can_equal_integer_fold.h",
    "content": "class MaximumCanEqualIntegerFold final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MaximumCanEqualIntegerFold()\n      : SchemaTransformRule{\"maximum_can_equal_integer_fold\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *maximum_can_equal{schema.try_at(\"maximumCanEqual\")};\n    ONLY_CONTINUE_IF(maximum_can_equal && maximum_can_equal->is_boolean() &&\n                     !maximum_can_equal->to_boolean());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    const auto &maximum{schema.at(\"maximum\")};\n    if (maximum.is_integer()) {\n      if (maximum.to_integer() > std::numeric_limits<std::int64_t>::min()) {\n        auto new_maximum = maximum;\n        new_maximum += sourcemeta::core::JSON{-1};\n        schema.assign(\"maximum\", std::move(new_maximum));\n      } else {\n        auto result{\n            sourcemeta::core::Decimal{std::to_string(maximum.to_integer())}};\n        result -= sourcemeta::core::Decimal{1};\n        schema.assign(\"maximum\", sourcemeta::core::JSON{std::move(result)});\n      }\n    } else if (maximum.is_decimal()) {\n      auto current{maximum.to_decimal()};\n      auto floored{current.to_integral()};\n      if (floored > current) {\n        floored -= sourcemeta::core::Decimal{1};\n      }\n      if (floored == current) {\n        floored -= sourcemeta::core::Decimal{1};\n      }\n      if (floored.is_int64()) {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{floored.to_int64()});\n      } else {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{std::move(floored)});\n      }\n    } else {\n      const auto value{maximum.to_real()};\n      const auto floor_value{std::floor(value)};\n      if (floor_value == value) {\n        if (value >=\n                static_cast<double>(std::numeric_limits<std::int64_t>::min()) &&\n            value <\n                static_cast<double>(std::numeric_limits<std::int64_t>::max()) +\n                    1.0) {\n          auto decimal_result{sourcemeta::core::Decimal{\n              std::to_string(static_cast<std::int64_t>(value))}};\n          decimal_result -= sourcemeta::core::Decimal{1};\n          if (decimal_result.is_int64()) {\n            schema.assign(\"maximum\",\n                          sourcemeta::core::JSON{decimal_result.to_int64()});\n          } else {\n            schema.assign(\"maximum\",\n                          sourcemeta::core::JSON{std::move(decimal_result)});\n          }\n        } else {\n          auto decimal_fallback{sourcemeta::core::Decimal{value}};\n          decimal_fallback -= sourcemeta::core::Decimal{1};\n          schema.assign(\"maximum\",\n                        sourcemeta::core::JSON{std::move(decimal_fallback)});\n        }\n      } else if (std::isfinite(floor_value) &&\n                 floor_value >= static_cast<double>(\n                                    std::numeric_limits<std::int64_t>::min()) &&\n                 floor_value < static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::max()) +\n                                   1.0) {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{\n                                     static_cast<std::int64_t>(floor_value)});\n      } else {\n        auto decimal_result{sourcemeta::core::Decimal{value}};\n        decimal_result = decimal_result.to_integral();\n        if (decimal_result > sourcemeta::core::Decimal{value}) {\n          decimal_result -= sourcemeta::core::Decimal{1};\n        }\n        schema.assign(\"maximum\",\n                      sourcemeta::core::JSON{std::move(decimal_result)});\n      }\n    }\n\n    schema.erase(\"maximumCanEqual\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/maximum_can_equal_true_drop.h",
    "content": "class MaximumCanEqualTrueDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MaximumCanEqualTrueDrop()\n      : SchemaTransformRule{\"maximum_can_equal_true_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"integer\" || type->to_string() == \"number\"));\n    const auto *maximum_can_equal{schema.try_at(\"maximumCanEqual\")};\n    ONLY_CONTINUE_IF(maximum_can_equal && maximum_can_equal->is_boolean() &&\n                     maximum_can_equal->to_boolean());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"maximumCanEqual\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/min_items_given_min_contains.h",
    "content": "class MinItemsGivenMinContains final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MinItemsGivenMinContains()\n      : SchemaTransformRule{\n            \"min_items_given_min_contains\",\n            \"Every array has a minimum size of zero items but may be affected \"\n            \"by `minContains`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object() && !schema.defines(\"minItems\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() && type->to_string() == \"array\");\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.defines(\"contains\") && schema.defines(\"minContains\") &&\n        schema.at(\"minContains\").is_integer()) {\n      schema.assign(\"minItems\", sourcemeta::core::JSON{\n                                    schema.at(\"minContains\").to_integer()});\n    } else {\n      schema.assign(\"minItems\", sourcemeta::core::JSON{0});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/min_length_implicit.h",
    "content": "class MinLengthImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MinLengthImplicit()\n      : SchemaTransformRule{\n            \"min_length_implicit\",\n            \"Every string has a minimum length of zero characters\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_0}) &&\n                     schema.is_object() && !schema.defines(\"minLength\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"string\");\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"minLength\", sourcemeta::core::JSON{0});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/min_properties_covered_by_required.h",
    "content": "class MinPropertiesCoveredByRequired final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  MinPropertiesCoveredByRequired()\n      : SchemaTransformRule{\n            \"min_properties_covered_by_required\",\n            \"Setting `minProperties` to a number less than `required` does \"\n            \"not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *min_properties{schema.try_at(\"minProperties\")};\n    ONLY_CONTINUE_IF(min_properties && min_properties->is_integer());\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(\n        required && required->is_array() && required->unique() &&\n        std::cmp_greater(required->size(), static_cast<std::uint64_t>(\n                                               min_properties->to_integer())));\n    return APPLIES_TO_KEYWORDS(\"minProperties\", \"required\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"minProperties\",\n                  sourcemeta::core::JSON{schema.at(\"required\").size()});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/minimum_can_equal_integer_fold.h",
    "content": "class MinimumCanEqualIntegerFold final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MinimumCanEqualIntegerFold()\n      : SchemaTransformRule{\"minimum_can_equal_integer_fold\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *minimum_can_equal{schema.try_at(\"minimumCanEqual\")};\n    ONLY_CONTINUE_IF(minimum_can_equal && minimum_can_equal->is_boolean() &&\n                     !minimum_can_equal->to_boolean());\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    const auto &minimum{schema.at(\"minimum\")};\n    if (minimum.is_integer()) {\n      if (minimum.to_integer() < std::numeric_limits<std::int64_t>::max()) {\n        auto new_minimum = minimum;\n        new_minimum += sourcemeta::core::JSON{1};\n        schema.assign(\"minimum\", std::move(new_minimum));\n      } else {\n        auto result{\n            sourcemeta::core::Decimal{std::to_string(minimum.to_integer())}};\n        result += sourcemeta::core::Decimal{1};\n        schema.assign(\"minimum\", sourcemeta::core::JSON{std::move(result)});\n      }\n    } else if (minimum.is_decimal()) {\n      auto current{minimum.to_decimal()};\n      auto ceiled{current.to_integral()};\n      if (ceiled < current) {\n        ceiled += sourcemeta::core::Decimal{1};\n      }\n      if (ceiled == current) {\n        ceiled += sourcemeta::core::Decimal{1};\n      }\n      if (ceiled.is_int64()) {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{ceiled.to_int64()});\n      } else {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{std::move(ceiled)});\n      }\n    } else {\n      const auto value{minimum.to_real()};\n      const auto ceil_value{std::ceil(value)};\n      if (ceil_value == value) {\n        if (value >=\n                static_cast<double>(std::numeric_limits<std::int64_t>::min()) &&\n            value <\n                static_cast<double>(std::numeric_limits<std::int64_t>::max()) +\n                    1.0) {\n          auto decimal_result{sourcemeta::core::Decimal{\n              std::to_string(static_cast<std::int64_t>(value))}};\n          decimal_result += sourcemeta::core::Decimal{1};\n          if (decimal_result.is_int64()) {\n            schema.assign(\"minimum\",\n                          sourcemeta::core::JSON{decimal_result.to_int64()});\n          } else {\n            schema.assign(\"minimum\",\n                          sourcemeta::core::JSON{std::move(decimal_result)});\n          }\n        } else {\n          auto decimal_fallback{sourcemeta::core::Decimal{value}};\n          decimal_fallback += sourcemeta::core::Decimal{1};\n          schema.assign(\"minimum\",\n                        sourcemeta::core::JSON{std::move(decimal_fallback)});\n        }\n      } else if (std::isfinite(ceil_value) &&\n                 ceil_value >= static_cast<double>(\n                                   std::numeric_limits<std::int64_t>::min()) &&\n                 ceil_value < static_cast<double>(\n                                  std::numeric_limits<std::int64_t>::max()) +\n                                  1.0) {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{\n                                     static_cast<std::int64_t>(ceil_value)});\n      } else {\n        auto decimal_result{sourcemeta::core::Decimal{value}};\n        decimal_result = decimal_result.to_integral();\n        if (decimal_result < sourcemeta::core::Decimal{value}) {\n          decimal_result += sourcemeta::core::Decimal{1};\n        }\n        schema.assign(\"minimum\",\n                      sourcemeta::core::JSON{std::move(decimal_result)});\n      }\n    }\n\n    schema.erase(\"minimumCanEqual\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/minimum_can_equal_true_drop.h",
    "content": "class MinimumCanEqualTrueDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MinimumCanEqualTrueDrop()\n      : SchemaTransformRule{\"minimum_can_equal_true_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"integer\" || type->to_string() == \"number\"));\n    const auto *minimum_can_equal{schema.try_at(\"minimumCanEqual\")};\n    ONLY_CONTINUE_IF(minimum_can_equal && minimum_can_equal->is_boolean() &&\n                     minimum_can_equal->to_boolean());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"minimumCanEqual\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/multiple_of_implicit.h",
    "content": "class MultipleOfImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MultipleOfImplicit()\n      : SchemaTransformRule{\"multiple_of_implicit\",\n                            \"The unit of `multipleOf` is the integer 1\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && !schema.defines(\"multipleOf\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    // Applying this to numbers would be a semantic problem\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"multipleOf\", sourcemeta::core::JSON{1});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/optional_property_implicit.h",
    "content": "class OptionalPropertyImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  OptionalPropertyImplicit()\n      : SchemaTransformRule{\"optional_property_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"object\");\n    const auto *properties{schema.try_at(\"properties\")};\n    ONLY_CONTINUE_IF(properties && properties->is_object());\n\n    for (const auto &entry : properties->as_object()) {\n      if (entry.second.is_object() && !entry.second.empty() &&\n          !entry.second.defines(\"optional\")) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    std::vector<JSON::String> keys;\n    for (const auto &entry : schema.at(\"properties\").as_object()) {\n      if (entry.second.is_object() && !entry.second.empty() &&\n          !entry.second.defines(\"optional\")) {\n        keys.emplace_back(entry.first);\n      }\n    }\n    for (const auto &key : keys) {\n      schema.at(\"properties\")\n          .at(key)\n          .assign(\"optional\", sourcemeta::core::JSON{false});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/recursive_anchor_false_drop.h",
    "content": "class RecursiveAnchorFalseDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  RecursiveAnchorFalseDrop()\n      : SchemaTransformRule{\"recursive_anchor_false_drop\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n        schema.is_object());\n\n    const auto *recursive_anchor{schema.try_at(\"$recursiveAnchor\")};\n    ONLY_CONTINUE_IF(recursive_anchor && recursive_anchor->is_boolean() &&\n                     !recursive_anchor->to_boolean());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"$recursiveAnchor\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/required_property_implicit.h",
    "content": "class RequiredPropertyImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  RequiredPropertyImplicit()\n      : SchemaTransformRule{\"required_property_implicit\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"object\");\n    const auto *properties{schema.try_at(\"properties\")};\n    ONLY_CONTINUE_IF(properties && properties->is_object());\n\n    for (const auto &entry : properties->as_object()) {\n      if (entry.second.is_object() && !entry.second.empty() &&\n          !entry.second.defines(\"$ref\") && !entry.second.defines(\"required\")) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    std::vector<JSON::String> keys;\n    for (const auto &entry : schema.at(\"properties\").as_object()) {\n      if (entry.second.is_object() && !entry.second.empty() &&\n          !entry.second.defines(\"$ref\") && !entry.second.defines(\"required\")) {\n        keys.emplace_back(entry.first);\n      }\n    }\n    for (const auto &key : keys) {\n      schema.at(\"properties\")\n          .at(key)\n          .assign(\"required\", sourcemeta::core::JSON{false});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/single_branch_allof.h",
    "content": "class SingleBranchAllOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  SingleBranchAllOf() : SchemaTransformRule{\"single_branch_allof\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *all_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array() && all_of->size() == 1);\n    ONLY_CONTINUE_IF(\n        !(vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n               Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n          (schema.defines(\"unevaluatedProperties\") ||\n           schema.defines(\"unevaluatedItems\"))));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    const auto &branch{all_of->at(0)};\n    if (branch.is_object()) {\n      ONLY_CONTINUE_IF(!branch.defines(\"$ref\") &&\n                       !branch.defines(\"$dynamicRef\") &&\n                       !branch.defines(\"$recursiveRef\"));\n    }\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto &branch{schema.at(\"allOf\").at(0)};\n    if (branch.is_boolean()) {\n      if (branch.to_boolean()) {\n        schema.erase(\"allOf\");\n      } else {\n        schema.into(JSON{false});\n      }\n      return;\n    }\n\n    schema.merge(branch.as_object());\n    schema.erase(\"allOf\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    const auto prefix{current.concat({KEYWORD, 0})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty()) {\n      return target;\n    }\n    const Pointer new_prefix{current.concat({relative.at(0)})};\n    return target.rebase(prefix.concat({relative.at(0)}), new_prefix);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/single_branch_anyof.h",
    "content": "class SingleBranchAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  SingleBranchAnyOf() : SchemaTransformRule{\"single_branch_anyof\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *any_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(any_of && any_of->is_array() && any_of->size() == 1);\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    this->has_unevaluated_ =\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        (schema.defines(\"unevaluatedProperties\") ||\n         schema.defines(\"unevaluatedItems\"));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (this->has_unevaluated_) {\n      schema.rename(\"anyOf\", \"allOf\");\n      return;\n    }\n\n    auto &branch{schema.at(\"anyOf\").at(0)};\n    if (branch.is_boolean()) {\n      if (branch.to_boolean()) {\n        schema.erase(\"anyOf\");\n      } else {\n        schema.into(JSON{false});\n      }\n      return;\n    }\n\n    schema.merge(branch.as_object());\n    schema.erase(\"anyOf\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    if (this->has_unevaluated_) {\n      const auto old_prefix{current.concat({KEYWORD})};\n      const Pointer new_prefix{current.concat({\"allOf\"})};\n      return target.rebase(old_prefix, new_prefix);\n    }\n    const auto prefix{current.concat({KEYWORD, 0})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty()) {\n      return target;\n    }\n    const Pointer new_prefix{current.concat({relative.at(0)})};\n    return target.rebase(prefix.concat({relative.at(0)}), new_prefix);\n  }\n\nprivate:\n  mutable bool has_unevaluated_{false};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/single_branch_oneof.h",
    "content": "class SingleBranchOneOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  SingleBranchOneOf() : SchemaTransformRule{\"single_branch_oneof\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"oneOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *one_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(one_of && one_of->is_array() && one_of->size() == 1);\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    this->has_unevaluated_ =\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        (schema.defines(\"unevaluatedProperties\") ||\n         schema.defines(\"unevaluatedItems\"));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (this->has_unevaluated_) {\n      schema.rename(\"oneOf\", \"allOf\");\n      return;\n    }\n\n    auto &branch{schema.at(\"oneOf\").at(0)};\n    if (branch.is_boolean()) {\n      if (branch.to_boolean()) {\n        schema.erase(\"oneOf\");\n      } else {\n        schema.into(JSON{false});\n      }\n      return;\n    }\n\n    schema.merge(branch.as_object());\n    schema.erase(\"oneOf\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"oneOf\"};\n    if (this->has_unevaluated_) {\n      const auto old_prefix{current.concat({KEYWORD})};\n      const Pointer new_prefix{current.concat({\"allOf\"})};\n      return target.rebase(old_prefix, new_prefix);\n    }\n    const auto prefix{current.concat({KEYWORD, 0})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty()) {\n      return target;\n    }\n    const Pointer new_prefix{current.concat({relative.at(0)})};\n    return target.rebase(prefix.concat({relative.at(0)}), new_prefix);\n  }\n\nprivate:\n  mutable bool has_unevaluated_{false};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_array_to_any_of.h",
    "content": "class TypeArrayToAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeArrayToAnyOf()\n      : SchemaTransformRule{\n            \"type_array_to_any_of\",\n            \"Setting `type` to more than one choice is syntax sugar to \"\n            \"`anyOf` over the corresponding types\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_array());\n\n    this->keyword_instances_.clear();\n\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"type\") {\n        continue;\n      }\n\n      const auto &metadata{walker(entry.first, vocabularies)};\n      if (metadata.instances.any() &&\n          !(vocabularies.contains_any(\n                {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n                 Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n            (entry.first == \"unevaluatedProperties\" ||\n             entry.first == \"unevaluatedItems\"))) {\n        this->keyword_instances_[entry.first] = metadata.instances;\n      }\n    }\n\n    return APPLIES_TO_KEYWORDS(\"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    this->keyword_branch_index_.clear();\n    auto disjunctors{sourcemeta::core::JSON::make_array()};\n    std::size_t branch_index{0};\n    for (const auto &type : schema.at(\"type\").as_array()) {\n      auto branch{sourcemeta::core::JSON::make_object()};\n      branch.assign(\"type\", type);\n      const auto current_type_set{parse_schema_type(type)};\n      for (const auto &[keyword, instances] : this->keyword_instances_) {\n        if ((instances & current_type_set).any()) {\n          branch.assign(keyword, schema.at(keyword));\n          if (!this->keyword_branch_index_.contains(keyword)) {\n            this->keyword_branch_index_[keyword] = branch_index;\n          }\n        }\n      }\n\n      disjunctors.push_back(std::move(branch));\n      branch_index++;\n    }\n\n    for (const auto &[keyword, instances] : this->keyword_instances_) {\n      schema.erase(keyword);\n    }\n\n    static const std::string anyof_keyword{\"anyOf\"};\n    static const std::string allof_keyword{\"allOf\"};\n    if (schema.defines(\"anyOf\")) {\n      auto first_branch{sourcemeta::core::JSON::make_object()};\n      first_branch.assign(\"anyOf\", schema.at(\"anyOf\"));\n      auto second_branch{sourcemeta::core::JSON::make_object()};\n      second_branch.assign(\"anyOf\", std::move(disjunctors));\n      schema.erase(\"anyOf\");\n\n      if (schema.defines(\"allOf\")) {\n        const auto allof_index{schema.at(\"allOf\").size() + 1};\n        schema.at(\"allOf\").push_back(std::move(first_branch));\n        schema.at(\"allOf\").push_back(std::move(second_branch));\n        schema.erase(\"type\");\n        this->disjunctors_prefix_ = {allof_keyword, allof_index, anyof_keyword};\n      } else {\n        auto allof_wrapper{sourcemeta::core::JSON::make_array()};\n        allof_wrapper.push_back(std::move(first_branch));\n        allof_wrapper.push_back(std::move(second_branch));\n        schema.at(\"type\").into(std::move(allof_wrapper));\n        schema.rename(\"type\", \"allOf\");\n        this->disjunctors_prefix_ = {allof_keyword, 1, anyof_keyword};\n      }\n    } else {\n      schema.at(\"type\").into(std::move(disjunctors));\n      schema.rename(\"type\", \"anyOf\");\n      this->disjunctors_prefix_ = {anyof_keyword};\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view reference,\n                                 const Pointer &origin, const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    const auto relative{target.resolve_from(current)};\n    assert(!relative.empty() && relative.at(0).is_property());\n    const auto &keyword{relative.at(0).to_property()};\n    const auto match{this->keyword_branch_index_.find(keyword)};\n    if (match == this->keyword_branch_index_.end()) {\n      return SchemaTransformRule::rereference(reference, origin, target,\n                                              current);\n    }\n\n    const Pointer old_prefix{current.concat({keyword})};\n    const Pointer new_prefix{current.concat(this->disjunctors_prefix_)\n                                 .concat({match->second, keyword})};\n    return target.rebase(old_prefix, new_prefix);\n  }\n\nprivate:\n  mutable std::unordered_map<std::string, sourcemeta::core::JSON::TypeSet>\n      keyword_instances_;\n  mutable std::unordered_map<std::string, std::size_t> keyword_branch_index_;\n  mutable Pointer disjunctors_prefix_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_boolean_as_enum.h",
    "content": "class TypeBooleanAsEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeBooleanAsEnum()\n      : SchemaTransformRule{\n            \"type_boolean_as_enum\",\n            \"Setting `type` to `boolean` is syntax sugar for an enumeration \"\n            \"of two values: `false` and `true`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_0}) &&\n                     schema.is_object() && !schema.defines(\"enum\") &&\n                     !schema.defines(\"const\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"boolean\");\n    return APPLIES_TO_KEYWORDS(\"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto choices = sourcemeta::core::JSON::make_array();\n    choices.push_back(sourcemeta::core::JSON{false});\n    choices.push_back(sourcemeta::core::JSON{true});\n    schema.at(\"type\").into(std::move(choices));\n    schema.rename(\"type\", \"enum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_inherit_in_place.h",
    "content": "class TypeInheritInPlace final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeInheritInPlace()\n      : SchemaTransformRule{\n            \"type_inherit_in_place\",\n            \"An untyped schema inside an in-place applicator inherits \"\n            \"the type from its nearest typed ancestor\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    using namespace sourcemeta::core;\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1,\n         Vocabularies::Known::JSON_Schema_Draft_0}));\n    ONLY_CONTINUE_IF(!schema.defines(\"type\"));\n    ONLY_CONTINUE_IF(!schema.defines(\"enum\"));\n    ONLY_CONTINUE_IF(!vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) ||\n                     !schema.defines(\"const\"));\n\n    for (const auto &entry : schema.as_object()) {\n      const auto &keyword_type{walker(entry.first, vocabularies).type};\n      ONLY_CONTINUE_IF(keyword_type != SchemaKeywordType::Reference);\n      ONLY_CONTINUE_IF(keyword_type ==\n                           SchemaKeywordType::ApplicatorValueInPlaceOther ||\n                       !IS_IN_PLACE_APPLICATOR(keyword_type));\n    }\n\n    // Walk up through in-place applicators excluding `allOf`. In `allOf` the\n    // parent's type already constrains all branches (a conjunction), and other\n    // rules may want to lift type out of conjunctions\n    const auto ancestor{WALK_UP(\n        root, frame, location, walker, resolver,\n        [](const SchemaKeywordType keyword_type) {\n          return IS_IN_PLACE_APPLICATOR(keyword_type) &&\n                 keyword_type != SchemaKeywordType::ApplicatorElementsInPlace;\n        },\n        [](const JSON &ancestor_schema, const Vocabularies &) {\n          return ancestor_schema.defines(\"type\");\n        })};\n\n    if (ancestor.has_value()) {\n      const auto &ancestor_type{get(root, ancestor.value().get()).at(\"type\")};\n      if (ancestor_type.is_array()) {\n        for (const auto &element : ancestor_type.as_array()) {\n          if (!element.is_string()) {\n            return false;\n          }\n        }\n      }\n      this->inherited_type_ = ancestor_type;\n      return true;\n    }\n\n    auto walk_pointer{location.pointer};\n    auto walk_parent{location.parent};\n    while (walk_parent.has_value()) {\n      const auto &wp{walk_parent.value()};\n      const auto walk_relative{walk_pointer.resolve_from(wp)};\n      if (walk_relative.empty() || !walk_relative.at(0).is_property()) {\n        break;\n      }\n      const auto walk_entry{frame.traverse(frame.uri(wp).value().get())};\n      if (!walk_entry.has_value()) {\n        break;\n      }\n      const auto walk_vocabularies{\n          frame.vocabularies(walk_entry.value().get(), resolver)};\n      const auto walk_keyword_type{\n          walker(walk_relative.at(0).to_property(), walk_vocabularies).type};\n\n      if (!IS_IN_PLACE_APPLICATOR(walk_keyword_type)) {\n        break;\n      }\n\n      if (walk_keyword_type == SchemaKeywordType::ApplicatorElementsInPlace &&\n          walk_relative.size() >= 2 && walk_relative.at(1).is_index()) {\n        const auto branch_index{walk_relative.at(1).to_index()};\n        const auto &allof_parent{get(root, wp)};\n        const auto &keyword_name{walk_relative.at(0).to_property()};\n        const auto *branches{allof_parent.is_object()\n                                 ? allof_parent.try_at(keyword_name)\n                                 : nullptr};\n        if (branches && branches->is_array()) {\n          for (std::size_t index = 0; index < branches->size(); ++index) {\n            if (index == branch_index) {\n              continue;\n            }\n            const auto &sibling{branches->at(index)};\n            if (!sibling.is_object()) {\n              continue;\n            }\n            const auto *sibling_type{sibling.try_at(\"type\")};\n            if (sibling_type && sibling_type->is_string()) {\n              this->inherited_type_ = *sibling_type;\n              return true;\n            }\n            const auto *sibling_enum{sibling.try_at(\"enum\")};\n            if (sibling_enum && sibling_enum->is_array() &&\n                !sibling_enum->empty()) {\n              const auto inferred{infer_type_from_enum(*sibling_enum)};\n              if (!inferred.empty()) {\n                this->inherited_type_ = JSON{inferred};\n                return true;\n              }\n            }\n            const auto *sibling_ref{sibling.try_at(\"$ref\")};\n            if (sibling_ref && sibling_ref->is_string()) {\n              const auto ref_target{frame.traverse(sibling_ref->to_string())};\n              if (ref_target.has_value()) {\n                const auto &ref_schema{\n                    get(root, ref_target.value().get().pointer)};\n                const auto *ref_type{ref_schema.is_object()\n                                         ? ref_schema.try_at(\"type\")\n                                         : nullptr};\n                if (ref_type && ref_type->is_string()) {\n                  this->inherited_type_ = *ref_type;\n                  return true;\n                }\n              }\n            }\n          }\n        }\n      }\n\n      walk_pointer = wp;\n      walk_parent = walk_entry.value().get().parent;\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.assign(\"type\", this->inherited_type_);\n  }\n\nprivate:\n  static auto infer_type_from_enum(const sourcemeta::core::JSON &enum_array)\n      -> sourcemeta::core::JSON::String {\n    using Type = sourcemeta::core::JSON::Type;\n    bool all_null{true};\n    bool all_boolean{true};\n    bool all_integer{true};\n    bool all_number{true};\n    bool all_string{true};\n    bool all_array{true};\n    bool all_object{true};\n\n    for (const auto &value : enum_array.as_array()) {\n      const auto value_type{value.type()};\n      if (value_type != Type::Null) {\n        all_null = false;\n      }\n      if (value_type != Type::Boolean) {\n        all_boolean = false;\n      }\n      if (value_type != Type::Integer) {\n        all_integer = false;\n      }\n      if (value_type != Type::Integer && value_type != Type::Real) {\n        all_number = false;\n      }\n      if (value_type != Type::String) {\n        all_string = false;\n      }\n      if (value_type != Type::Array) {\n        all_array = false;\n      }\n      if (value_type != Type::Object) {\n        all_object = false;\n      }\n    }\n\n    if (all_string) {\n      return \"string\";\n    }\n    if (all_integer) {\n      return \"integer\";\n    }\n    if (all_number) {\n      return \"number\";\n    }\n    if (all_object) {\n      return \"object\";\n    }\n    if (all_array) {\n      return \"array\";\n    }\n    if (all_null) {\n      return \"null\";\n    }\n    if (all_boolean) {\n      return \"boolean\";\n    }\n    return \"\";\n  }\n\n  mutable sourcemeta::core::JSON inherited_type_{\n      sourcemeta::core::JSON{nullptr}};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_null_as_enum.h",
    "content": "class TypeNullAsEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeNullAsEnum()\n      : SchemaTransformRule{\n            \"type_null_as_enum\",\n            \"Setting `type` to `null` is syntax sugar for an enumeration \"\n            \"of a single value: `null`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_0}) &&\n                     schema.is_object() && !schema.defines(\"enum\") &&\n                     !schema.defines(\"const\"));\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() && type->to_string() == \"null\");\n    return APPLIES_TO_KEYWORDS(\"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto choices = sourcemeta::core::JSON::make_array();\n    choices.push_back(sourcemeta::core::JSON{nullptr});\n    schema.at(\"type\").into(std::move(choices));\n    schema.rename(\"type\", \"enum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_union_implicit.h",
    "content": "class TypeUnionImplicit final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeUnionImplicit()\n      : SchemaTransformRule{\n            \"type_union_implicit\",\n            \"Not setting `type` is equivalent to accepting any type\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    using namespace sourcemeta::core;\n    ONLY_CONTINUE_IF(schema.is_object() && !schema.empty());\n    ONLY_CONTINUE_IF(!vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_0,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_3}) ||\n                     !schema.defines(\"disallow\"));\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1,\n         Vocabularies::Known::JSON_Schema_Draft_0}));\n    ONLY_CONTINUE_IF(!schema.defines(\"type\"));\n    ONLY_CONTINUE_IF(!schema.defines(\"enum\"));\n    ONLY_CONTINUE_IF(!vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) ||\n                     !schema.defines(\"const\"));\n\n    for (const auto &entry : schema.as_object()) {\n      const auto &keyword_type{walker(entry.first, vocabularies).type};\n\n      ONLY_CONTINUE_IF(keyword_type != SchemaKeywordType::Reference);\n      ONLY_CONTINUE_IF(\n          // Applicators like `contentSchema` applies to decoded content, not\n          // the current instance\n          keyword_type == SchemaKeywordType::ApplicatorValueInPlaceOther ||\n          !IS_IN_PLACE_APPLICATOR(keyword_type));\n    }\n\n    ONLY_CONTINUE_IF(!this->allof_sibling_constrains_type(root, frame, location,\n                                                          walker, resolver));\n\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto types{sourcemeta::core::JSON::make_array()};\n\n    types.push_back(sourcemeta::core::JSON{\"null\"});\n    types.push_back(sourcemeta::core::JSON{\"boolean\"});\n    types.push_back(sourcemeta::core::JSON{\"object\"});\n    types.push_back(sourcemeta::core::JSON{\"array\"});\n    types.push_back(sourcemeta::core::JSON{\"string\"});\n\n    // Note we don't add `integer`, as its covered by `number`\n    types.push_back(sourcemeta::core::JSON{\"number\"});\n\n    schema.assign(\"type\", std::move(types));\n  }\n\nprivate:\n  static auto allof_sibling_constrains_type(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &location,\n      const sourcemeta::core::SchemaWalker &walker,\n      const sourcemeta::core::SchemaResolver &resolver) -> bool {\n    using namespace sourcemeta::core;\n    auto walk_pointer{location.pointer};\n    auto walk_parent{location.parent};\n    while (walk_parent.has_value()) {\n      const auto &wp{walk_parent.value()};\n      const auto walk_relative{walk_pointer.resolve_from(wp)};\n      if (walk_relative.empty() || !walk_relative.at(0).is_property()) {\n        break;\n      }\n      const auto walk_entry{frame.traverse(frame.uri(wp).value().get())};\n      if (!walk_entry.has_value()) {\n        break;\n      }\n      const auto walk_vocabularies{\n          frame.vocabularies(walk_entry.value().get(), resolver)};\n      const auto walk_keyword_type{\n          walker(walk_relative.at(0).to_property(), walk_vocabularies).type};\n\n      if (!IS_IN_PLACE_APPLICATOR(walk_keyword_type)) {\n        break;\n      }\n\n      if (walk_keyword_type == SchemaKeywordType::ApplicatorElementsInPlace &&\n          walk_relative.size() >= 2 && walk_relative.at(1).is_index()) {\n        const auto branch_index{walk_relative.at(1).to_index()};\n        const auto &allof_parent{get(root, wp)};\n        const auto &keyword_name{walk_relative.at(0).to_property()};\n        const auto *branches{allof_parent.is_object()\n                                 ? allof_parent.try_at(keyword_name)\n                                 : nullptr};\n        if (branches && branches->is_array()) {\n          for (std::size_t index = 0; index < branches->size(); ++index) {\n            if (index == branch_index) {\n              continue;\n            }\n            const auto &sibling{branches->at(index)};\n            if (!sibling.is_object()) {\n              continue;\n            }\n\n            if (sibling.defines(\"type\")) {\n              return true;\n            }\n\n            const auto *sibling_enum{sibling.try_at(\"enum\")};\n            if (sibling_enum && sibling_enum->is_array() &&\n                !sibling_enum->empty()) {\n              return true;\n            }\n          }\n        }\n      }\n\n      walk_pointer = wp;\n      walk_parent = walk_entry.value().get().parent;\n    }\n    return false;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_union_to_schemas.h",
    "content": "class TypeUnionToSchemas final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeUnionToSchemas() : SchemaTransformRule{\"type_union_to_schemas\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_array());\n\n    for (const auto &element : type->as_array()) {\n      if (element.is_string()) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto new_array{JSON::make_array()};\n    for (const auto &element : schema.at(\"type\").as_array()) {\n      if (element.is_string()) {\n        new_array.push_back(type_string_to_schema(element.to_string()));\n      } else {\n        new_array.push_back(element);\n      }\n    }\n    schema.assign(\"type\", std::move(new_array));\n  }\n\nprivate:\n  static auto type_string_to_schema(const std::string &type_name) -> JSON {\n    if (type_name == \"null\") {\n      auto result{JSON::make_object()};\n      auto values{JSON::make_array()};\n      values.push_back(JSON{nullptr});\n      result.assign(\"enum\", std::move(values));\n      return result;\n    }\n\n    if (type_name == \"boolean\") {\n      auto result{JSON::make_object()};\n      auto values{JSON::make_array()};\n      values.push_back(JSON{false});\n      values.push_back(JSON{true});\n      result.assign(\"enum\", std::move(values));\n      return result;\n    }\n\n    if (type_name == \"any\") {\n      return JSON::make_object();\n    }\n\n    auto result{JSON::make_object()};\n    result.assign(\"type\", JSON{type_name});\n    return result;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_with_applicator_to_allof.h",
    "content": "class TypeWithApplicatorToAllOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeWithApplicatorToAllOf()\n      : SchemaTransformRule{\"type_with_applicator_to_allof\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.is_object());\n\n    const bool has_not{schema.defines(\"not\")};\n    const bool has_anyof{schema.defines(\"anyOf\")};\n    const bool has_allof{schema.defines(\"allOf\")};\n    const bool has_oneof{schema.defines(\"oneOf\")};\n    const bool has_if{\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator}) &&\n        schema.defines(\"if\")};\n    this->has_if_then_else_ = has_if;\n    const auto *type_value{schema.try_at(\"type\")};\n    const bool has_type{type_value && type_value->is_string()};\n    const bool has_enum{schema.defines(\"enum\")};\n    const bool is_modern{\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) ||\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2020_12_Core)};\n    const bool has_ref{!is_modern && schema.defines(\"$ref\")};\n    this->has_modern_ref_ = is_modern && schema.defines(\"$ref\");\n    this->has_dynamic_ref_ =\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2020_12_Core) &&\n        schema.defines(\"$dynamicRef\");\n    this->has_recursive_ref_ =\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n        schema.defines(\"$recursiveRef\");\n    const unsigned int applicator_count{\n        (has_not ? 1U : 0U) + (has_anyof ? 1U : 0U) + (has_allof ? 1U : 0U) +\n        (has_oneof ? 1U : 0U) + (has_if ? 1U : 0U) +\n        (this->has_modern_ref_ ? 1U : 0U) + (this->has_dynamic_ref_ ? 1U : 0U) +\n        (this->has_recursive_ref_ ? 1U : 0U)};\n    const bool has_structural{has_type || has_enum || has_ref};\n\n    bool modern_ref_needs_wrapping{false};\n    this->ref_annotations_only_ = false;\n    if (this->has_modern_ref_ || this->has_dynamic_ref_ ||\n        this->has_recursive_ref_) {\n      this->ref_annotations_only_ = true;\n      for (const auto &entry : schema.as_object()) {\n        if (entry.first == \"$ref\" || entry.first == \"$dynamicRef\" ||\n            entry.first == \"$recursiveRef\") {\n          continue;\n        }\n        const auto keyword_type{walker(entry.first, vocabularies).type};\n        if (keyword_type != sourcemeta::core::SchemaKeywordType::Unknown &&\n            keyword_type != sourcemeta::core::SchemaKeywordType::Annotation &&\n            keyword_type != sourcemeta::core::SchemaKeywordType::Comment) {\n          modern_ref_needs_wrapping = true;\n          if (keyword_type != sourcemeta::core::SchemaKeywordType::Reference &&\n              keyword_type != sourcemeta::core::SchemaKeywordType::Other &&\n              keyword_type !=\n                  sourcemeta::core::SchemaKeywordType::LocationMembers) {\n            this->ref_annotations_only_ = false;\n          }\n        }\n      }\n    }\n\n    this->has_unevaluated_ =\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        (schema.defines(\"unevaluatedProperties\") ||\n         schema.defines(\"unevaluatedItems\"));\n    bool has_orphaned_typed_keywords{false};\n    if (is_modern && applicator_count >= 1 && !has_structural) {\n      for (const auto &entry : schema.as_object()) {\n        if (entry.first == \"unevaluatedProperties\" ||\n            entry.first == \"unevaluatedItems\") {\n          continue;\n        }\n        const auto &metadata{walker(entry.first, vocabularies)};\n        if (metadata.instances.any()) {\n          has_orphaned_typed_keywords = true;\n          break;\n        }\n      }\n    }\n\n    ONLY_CONTINUE_IF(\n        (has_structural && applicator_count >= 1) || applicator_count >= 2 ||\n        modern_ref_needs_wrapping ||\n        (has_orphaned_typed_keywords && !this->ref_annotations_only_));\n\n    this->strategy_ = Strategy::FullRestructure;\n    this->applicators_with_refs_ = 0;\n    for (const auto &reference : frame.references()) {\n      const auto &source_pointer{reference.first.second};\n      if (!source_pointer.starts_with(location.pointer)) {\n        continue;\n      }\n      const auto relative{source_pointer.resolve_from(location.pointer)};\n      if (relative.empty() || !relative.at(0).is_property()) {\n        continue;\n      }\n      const auto &first_keyword{relative.at(0).to_property()};\n      const auto bit{applicator_bit(first_keyword)};\n      if (bit != 0) {\n        const auto destination{frame.traverse(reference.second.destination)};\n        if (destination.has_value()) {\n          const auto &dest_pointer{destination->get().pointer};\n          if (dest_pointer.starts_with(location.pointer)) {\n            const auto relative_dest{\n                dest_pointer.resolve_from(location.pointer)};\n            if (!relative_dest.empty() && relative_dest.at(0).is_property() &&\n                (relative_dest.at(0).to_property() == \"definitions\" ||\n                 relative_dest.at(0).to_property() == \"$defs\" ||\n                 relative_dest.at(0).to_property() == \"dependencies\" ||\n                 relative_dest.at(0).to_property() == \"dependentSchemas\")) {\n              continue;\n            }\n          } else {\n            continue;\n          }\n        }\n        this->strategy_ = Strategy::SafeExtract;\n        this->applicators_with_refs_ |= bit;\n      }\n    }\n\n    if (this->strategy_ == Strategy::SafeExtract && !has_structural) {\n      if (!has_allof) {\n        this->strategy_ = Strategy::FullRestructure;\n        return true;\n      }\n\n      bool all_refs_fixed{true};\n      for (const auto &reference : frame.references()) {\n        const auto &source_pointer{reference.first.second};\n        if (!source_pointer.starts_with(location.pointer)) {\n          continue;\n        }\n        const auto relative_src{source_pointer.resolve_from(location.pointer)};\n        if (relative_src.empty() || !relative_src.at(0).is_property()) {\n          continue;\n        }\n        const auto &src_keyword{relative_src.at(0).to_property()};\n        if (src_keyword != \"not\" && src_keyword != \"anyOf\" &&\n            src_keyword != \"oneOf\" &&\n            !(this->has_if_then_else_ &&\n              (src_keyword == \"if\" || src_keyword == \"then\" ||\n               src_keyword == \"else\"))) {\n          continue;\n        }\n\n        const auto destination{frame.traverse(reference.second.destination)};\n        if (!destination.has_value()) {\n          all_refs_fixed = false;\n          break;\n        }\n\n        const auto relative_dest{\n            destination->get().pointer.resolve_from(location.pointer)};\n        if (relative_dest.empty() || !relative_dest.at(0).is_property() ||\n            relative_dest.at(0).to_property() != \"allOf\") {\n          all_refs_fixed = false;\n          break;\n        }\n      }\n\n      if (all_refs_fixed) {\n        this->strategy_ = Strategy::MergeIntoAllOf;\n      } else {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    this->typed_keywords_.clear();\n\n    if (this->strategy_ == Strategy::MergeIntoAllOf) {\n      for (const auto &applicator : APPLICATORS_WITHOUT_ALLOF) {\n        if (!schema.defines(applicator)) {\n          continue;\n        }\n        auto branch{JSON::make_object()};\n        branch.assign(applicator, schema.at(applicator));\n        if (std::string_view{applicator} == \"if\" && this->has_if_then_else_) {\n          if (schema.defines(\"then\")) {\n            branch.assign(\"then\", schema.at(\"then\"));\n          }\n          if (schema.defines(\"else\")) {\n            branch.assign(\"else\", schema.at(\"else\"));\n          }\n        }\n        schema.at(\"allOf\").push_back(std::move(branch));\n        schema.erase(applicator);\n      }\n      if (this->has_if_then_else_) {\n        if (schema.defines(\"then\")) {\n          schema.erase(\"then\");\n        }\n        if (schema.defines(\"else\")) {\n          schema.erase(\"else\");\n        }\n      }\n      return;\n    }\n\n    auto typed_branch{JSON::make_object()};\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"not\" || entry.first == \"anyOf\" ||\n          entry.first == \"allOf\" || entry.first == \"oneOf\" ||\n          entry.first == \"$schema\" || entry.first == \"id\" ||\n          entry.first == \"$id\" || entry.first == \"definitions\" ||\n          entry.first == \"$defs\" || entry.first == \"$anchor\" ||\n          entry.first == \"$dynamicAnchor\" ||\n          entry.first == \"$recursiveAnchor\" || entry.first == \"$vocabulary\" ||\n          entry.first == \"dependencies\" || entry.first == \"dependentSchemas\" ||\n          (this->has_if_then_else_ &&\n           (entry.first == \"if\" || entry.first == \"then\" ||\n            entry.first == \"else\")) ||\n          (this->has_modern_ref_ && entry.first == \"$ref\") ||\n          (this->has_dynamic_ref_ && entry.first == \"$dynamicRef\") ||\n          (this->has_recursive_ref_ && entry.first == \"$recursiveRef\") ||\n          (this->has_unevaluated_ && (entry.first == \"unevaluatedProperties\" ||\n                                      entry.first == \"unevaluatedItems\"))) {\n        continue;\n      }\n      typed_branch.assign(entry.first, entry.second);\n      this->typed_keywords_.emplace_back(entry.first);\n    }\n\n    for (const auto &key : this->typed_keywords_) {\n      schema.erase(key);\n    }\n\n    if (this->strategy_ == Strategy::SafeExtract) {\n      if (schema.defines(\"allOf\") && schema.at(\"allOf\").is_array()) {\n        this->typed_branch_index_ = schema.at(\"allOf\").size();\n        schema.at(\"allOf\").push_back(std::move(typed_branch));\n      } else {\n        this->typed_branch_index_ = 0;\n        auto new_allof{JSON::make_array()};\n        new_allof.push_back(std::move(typed_branch));\n        schema.assign(\"allOf\", std::move(new_allof));\n      }\n\n      if (this->has_modern_ref_ && schema.defines(\"$ref\")) {\n        auto branch{JSON::make_object()};\n        branch.assign(\"$ref\", schema.at(\"$ref\"));\n        schema.at(\"allOf\").push_back(std::move(branch));\n        schema.erase(\"$ref\");\n      }\n      if (this->has_dynamic_ref_ && schema.defines(\"$dynamicRef\")) {\n        auto branch{JSON::make_object()};\n        branch.assign(\"$dynamicRef\", schema.at(\"$dynamicRef\"));\n        schema.at(\"allOf\").push_back(std::move(branch));\n        schema.erase(\"$dynamicRef\");\n      }\n      if (this->has_recursive_ref_ && schema.defines(\"$recursiveRef\")) {\n        auto branch{JSON::make_object()};\n        branch.assign(\"$recursiveRef\", schema.at(\"$recursiveRef\"));\n        schema.at(\"allOf\").push_back(std::move(branch));\n        schema.erase(\"$recursiveRef\");\n      }\n\n      for (const auto &applicator : APPLICATORS_WITHOUT_ALLOF) {\n        if (!schema.defines(applicator)) {\n          continue;\n        }\n        if (this->applicators_with_refs_ & applicator_bit(applicator)) {\n          continue;\n        }\n        auto branch{JSON::make_object()};\n        branch.assign(applicator, schema.at(applicator));\n        if (std::string_view{applicator} == \"if\" && this->has_if_then_else_) {\n          if (schema.defines(\"then\")) {\n            branch.assign(\"then\", schema.at(\"then\"));\n          }\n          if (schema.defines(\"else\")) {\n            branch.assign(\"else\", schema.at(\"else\"));\n          }\n        }\n        schema.at(\"allOf\").push_back(std::move(branch));\n        schema.erase(applicator);\n        if (std::string_view{applicator} == \"if\" && this->has_if_then_else_) {\n          if (schema.defines(\"then\")) {\n            schema.erase(\"then\");\n          }\n          if (schema.defines(\"else\")) {\n            schema.erase(\"else\");\n          }\n        }\n      }\n\n      return;\n    }\n\n    auto new_allof{JSON::make_array()};\n    this->applicator_indices_ = 0;\n\n    if (this->has_modern_ref_ && schema.defines(\"$ref\")) {\n      auto branch{JSON::make_object()};\n      branch.assign(\"$ref\", schema.at(\"$ref\"));\n      if (this->ref_annotations_only_ && !this->typed_keywords_.empty()) {\n        for (const auto &entry : typed_branch.as_object()) {\n          branch.assign(entry.first, entry.second);\n        }\n        this->typed_keywords_.clear();\n      }\n      new_allof.push_back(std::move(branch));\n    }\n    if (this->has_dynamic_ref_ && schema.defines(\"$dynamicRef\")) {\n      auto branch{JSON::make_object()};\n      branch.assign(\"$dynamicRef\", schema.at(\"$dynamicRef\"));\n      if (this->ref_annotations_only_ && !this->typed_keywords_.empty()) {\n        for (const auto &entry : typed_branch.as_object()) {\n          branch.assign(entry.first, entry.second);\n        }\n        this->typed_keywords_.clear();\n      }\n      new_allof.push_back(std::move(branch));\n    }\n    if (this->has_recursive_ref_ && schema.defines(\"$recursiveRef\")) {\n      auto branch{JSON::make_object()};\n      branch.assign(\"$recursiveRef\", schema.at(\"$recursiveRef\"));\n      if (this->ref_annotations_only_ && !this->typed_keywords_.empty()) {\n        for (const auto &entry : typed_branch.as_object()) {\n          branch.assign(entry.first, entry.second);\n        }\n        this->typed_keywords_.clear();\n      }\n      new_allof.push_back(std::move(branch));\n    }\n\n    for (const auto &applicator : APPLICATORS) {\n      if (!schema.defines(applicator)) {\n        continue;\n      }\n      auto branch{JSON::make_object()};\n      branch.assign(applicator, schema.at(applicator));\n      if (std::string_view{applicator} == \"if\" && this->has_if_then_else_) {\n        if (schema.defines(\"then\")) {\n          branch.assign(\"then\", schema.at(\"then\"));\n        }\n        if (schema.defines(\"else\")) {\n          branch.assign(\"else\", schema.at(\"else\"));\n        }\n      }\n      new_allof.push_back(std::move(branch));\n      this->applicator_indices_ |= applicator_bit(applicator);\n    }\n\n    if (!this->typed_keywords_.empty()) {\n      new_allof.push_back(std::move(typed_branch));\n    }\n\n    auto new_schema{JSON::make_object()};\n    if (schema.defines(\"$schema\")) {\n      new_schema.assign(\"$schema\", schema.at(\"$schema\"));\n    }\n    if (schema.defines(\"id\")) {\n      new_schema.assign(\"id\", schema.at(\"id\"));\n    }\n    if (schema.defines(\"$id\")) {\n      new_schema.assign(\"$id\", schema.at(\"$id\"));\n    }\n    if (schema.defines(\"definitions\")) {\n      new_schema.assign(\"definitions\", schema.at(\"definitions\"));\n    }\n    if (schema.defines(\"$defs\")) {\n      new_schema.assign(\"$defs\", schema.at(\"$defs\"));\n    }\n    if (schema.defines(\"$anchor\")) {\n      new_schema.assign(\"$anchor\", schema.at(\"$anchor\"));\n    }\n    if (schema.defines(\"$dynamicAnchor\")) {\n      new_schema.assign(\"$dynamicAnchor\", schema.at(\"$dynamicAnchor\"));\n    }\n    if (schema.defines(\"$recursiveAnchor\")) {\n      new_schema.assign(\"$recursiveAnchor\", schema.at(\"$recursiveAnchor\"));\n    }\n    if (schema.defines(\"$vocabulary\")) {\n      new_schema.assign(\"$vocabulary\", schema.at(\"$vocabulary\"));\n    }\n    if (schema.defines(\"dependencies\")) {\n      new_schema.assign(\"dependencies\", schema.at(\"dependencies\"));\n    }\n    if (schema.defines(\"dependentSchemas\")) {\n      new_schema.assign(\"dependentSchemas\", schema.at(\"dependentSchemas\"));\n    }\n    if (this->has_unevaluated_) {\n      if (schema.defines(\"unevaluatedProperties\")) {\n        new_schema.assign(\"unevaluatedProperties\",\n                          schema.at(\"unevaluatedProperties\"));\n      }\n      if (schema.defines(\"unevaluatedItems\")) {\n        new_schema.assign(\"unevaluatedItems\", schema.at(\"unevaluatedItems\"));\n      }\n    }\n    new_schema.assign(\"allOf\", std::move(new_allof));\n    schema.into(std::move(new_schema));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    const auto relative{target.resolve_from(current)};\n    if (relative.empty() || !relative.at(0).is_property()) {\n      return target;\n    }\n\n    const auto &keyword{relative.at(0).to_property()};\n    static const JSON::String allof_keyword{\"allOf\"};\n\n    for (const auto &typed_kw : this->typed_keywords_) {\n      if (typed_kw == keyword) {\n        const Pointer old_prefix{current.concat({keyword})};\n        if (this->strategy_ == Strategy::SafeExtract) {\n          const Pointer new_prefix{current.concat(\n              {allof_keyword, this->typed_branch_index_, keyword})};\n          return target.rebase(old_prefix, new_prefix);\n        } else {\n          const std::size_t typed_index{(this->has_modern_ref_ ? 1U : 0U) +\n                                        (this->has_dynamic_ref_ ? 1U : 0U) +\n                                        (this->has_recursive_ref_ ? 1U : 0U) +\n                                        static_cast<std::size_t>(std::popcount(\n                                            this->applicator_indices_))};\n          const Pointer new_prefix{\n              current.concat({allof_keyword, typed_index, keyword})};\n          return target.rebase(old_prefix, new_prefix);\n        }\n      }\n    }\n\n    if (this->strategy_ == Strategy::FullRestructure) {\n      std::size_t index{0};\n      if (this->has_modern_ref_) {\n        index++;\n      }\n      if (this->has_dynamic_ref_) {\n        index++;\n      }\n      if (this->has_recursive_ref_) {\n        index++;\n      }\n\n      for (const auto &applicator : APPLICATORS) {\n        if (keyword == applicator ||\n            (this->has_if_then_else_ && std::string_view{applicator} == \"if\" &&\n             (keyword == \"then\" || keyword == \"else\"))) {\n          const Pointer old_prefix{current.concat({keyword})};\n          const Pointer new_prefix{\n              current.concat({allof_keyword, index, keyword})};\n          return target.rebase(old_prefix, new_prefix);\n        }\n        if (this->applicator_indices_ & applicator_bit(applicator)) {\n          index++;\n        }\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static constexpr std::array<const char *, 5> APPLICATORS{\n      {\"not\", \"anyOf\", \"allOf\", \"oneOf\", \"if\"}};\n  static constexpr std::array<const char *, 4> APPLICATORS_WITHOUT_ALLOF{\n      {\"not\", \"anyOf\", \"oneOf\", \"if\"}};\n\n  static constexpr auto applicator_bit(std::string_view keyword)\n      -> std::uint8_t {\n    if (keyword == \"not\")\n      return 1;\n    if (keyword == \"anyOf\")\n      return 2;\n    if (keyword == \"allOf\")\n      return 4;\n    if (keyword == \"oneOf\")\n      return 8;\n    if (keyword == \"if\" || keyword == \"then\" || keyword == \"else\")\n      return 16;\n    return 0;\n  }\n\n  enum class Strategy : std::uint8_t {\n    FullRestructure,\n    SafeExtract,\n    MergeIntoAllOf\n  };\n  mutable Strategy strategy_{Strategy::FullRestructure};\n  mutable bool has_if_then_else_{false};\n  mutable bool has_modern_ref_{false};\n  mutable bool has_dynamic_ref_{false};\n  mutable bool has_recursive_ref_{false};\n  mutable bool has_unevaluated_{false};\n  mutable bool ref_annotations_only_{false};\n  mutable std::vector<std::string> typed_keywords_;\n  mutable std::uint8_t applicator_indices_{0};\n  mutable std::uint8_t applicators_with_refs_{0};\n  mutable std::size_t typed_branch_index_{0};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/type_with_applicator_to_extends.h",
    "content": "class TypeWithApplicatorToExtends final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TypeWithApplicatorToExtends()\n      : SchemaTransformRule{\"type_with_applicator_to_extends\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_0,\n                                   Vocabularies::Known::JSON_Schema_Draft_1,\n                                   Vocabularies::Known::JSON_Schema_Draft_2,\n                                   Vocabularies::Known::JSON_Schema_Draft_3}) &&\n        schema.is_object());\n\n    const auto *extends_value{schema.try_at(\"extends\")};\n    const bool has_extends{extends_value && extends_value->is_array()};\n    const auto *disallow_value{schema.try_at(\"disallow\")};\n    const bool has_disallow{disallow_value && disallow_value->is_array()};\n    const auto *type_value{schema.try_at(\"type\")};\n    const bool has_type_array{type_value && type_value->is_array()};\n    const bool has_type{type_value && type_value->is_string()};\n    const bool has_enum{schema.defines(\"enum\")};\n    const unsigned int applicator_count{(has_extends ? 1U : 0U) +\n                                        (has_disallow ? 1U : 0U) +\n                                        (has_type_array ? 1U : 0U)};\n    const bool has_structural{has_type || has_enum};\n\n    ONLY_CONTINUE_IF((has_structural && applicator_count >= 1) ||\n                     applicator_count >= 2);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    this->typed_keywords_.clear();\n\n    auto typed_branch{JSON::make_object()};\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"extends\" || entry.first == \"disallow\" ||\n          entry.first == \"$schema\" || entry.first == \"id\" ||\n          (entry.first == \"type\" && entry.second.is_array())) {\n        continue;\n      }\n      typed_branch.assign(entry.first, entry.second);\n      this->typed_keywords_.emplace_back(entry.first);\n    }\n\n    for (const auto &key : this->typed_keywords_) {\n      schema.erase(key);\n    }\n\n    auto new_extends{JSON::make_array()};\n    this->applicator_indices_ = 0;\n\n    for (const auto &applicator : APPLICATORS) {\n      if (!schema.defines(applicator)) {\n        continue;\n      }\n      const auto &value{schema.at(applicator)};\n      if (std::string_view{applicator} == \"type\" && !value.is_array()) {\n        continue;\n      }\n      auto branch{JSON::make_object()};\n      branch.assign(applicator, value);\n      new_extends.push_back(std::move(branch));\n      this->applicator_indices_ |= applicator_bit(applicator);\n    }\n\n    if (!this->typed_keywords_.empty()) {\n      new_extends.push_back(std::move(typed_branch));\n    }\n\n    auto new_schema{JSON::make_object()};\n    if (schema.defines(\"$schema\")) {\n      new_schema.assign(\"$schema\", schema.at(\"$schema\"));\n    }\n    if (schema.defines(\"id\")) {\n      new_schema.assign(\"id\", schema.at(\"id\"));\n    }\n    new_schema.assign(\"extends\", std::move(new_extends));\n    schema.into(std::move(new_schema));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    const auto relative{target.resolve_from(current)};\n    if (relative.empty() || !relative.at(0).is_property()) {\n      return target;\n    }\n\n    const auto &keyword{relative.at(0).to_property()};\n    static const JSON::String extends_keyword{\"extends\"};\n\n    for (const auto &typed_keyword : this->typed_keywords_) {\n      if (typed_keyword == keyword) {\n        const Pointer old_prefix{current.concat({keyword})};\n        const std::size_t typed_index{\n            static_cast<std::size_t>(std::popcount(this->applicator_indices_))};\n        const Pointer new_prefix{\n            current.concat({extends_keyword, typed_index, keyword})};\n        return target.rebase(old_prefix, new_prefix);\n      }\n    }\n\n    std::size_t index{0};\n    for (const auto &applicator : APPLICATORS) {\n      if (keyword == applicator) {\n        const Pointer old_prefix{current.concat({keyword})};\n        const Pointer new_prefix{\n            current.concat({extends_keyword, index, keyword})};\n        return target.rebase(old_prefix, new_prefix);\n      }\n      if (this->applicator_indices_ & applicator_bit(applicator)) {\n        index++;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static constexpr std::array<const char *, 3> APPLICATORS{\n      {\"extends\", \"disallow\", \"type\"}};\n\n  static constexpr auto applicator_bit(std::string_view keyword)\n      -> std::uint8_t {\n    if (keyword == \"extends\")\n      return 1;\n    if (keyword == \"disallow\")\n      return 2;\n    if (keyword == \"type\")\n      return 4;\n    return 0;\n  }\n\n  mutable std::vector<std::string> typed_keywords_;\n  mutable std::uint8_t applicator_indices_{0};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/unevaluated_items_to_items.h",
    "content": "class UnevaluatedItemsToItems final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnevaluatedItemsToItems()\n      : SchemaTransformRule{\"unevaluated_items_to_items\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        schema.is_object() && schema.defines(\"unevaluatedItems\"));\n\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"unevaluatedItems\") {\n        continue;\n      }\n      const auto &metadata{walker(entry.first, vocabularies)};\n      const auto keyword_type{metadata.type};\n      if (keyword_type != sourcemeta::core::SchemaKeywordType::Unknown &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Assertion &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Annotation &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Comment &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Other &&\n          keyword_type !=\n              sourcemeta::core::SchemaKeywordType::LocationMembers) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.rename(\"unevaluatedItems\", \"items\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    return target.rebase(current.concat({\"unevaluatedItems\"}),\n                         current.concat({\"items\"}));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/unevaluated_properties_to_additional_properties.h",
    "content": "class UnevaluatedPropertiesToAdditionalProperties final\n    : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnevaluatedPropertiesToAdditionalProperties()\n      : SchemaTransformRule{\"unevaluated_properties_to_additional_properties\",\n                            \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        schema.is_object() && schema.defines(\"unevaluatedProperties\"));\n\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"unevaluatedProperties\") {\n        continue;\n      }\n      const auto &metadata{walker(entry.first, vocabularies)};\n      const auto keyword_type{metadata.type};\n      if (keyword_type != sourcemeta::core::SchemaKeywordType::Unknown &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Assertion &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Annotation &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Comment &&\n          keyword_type != sourcemeta::core::SchemaKeywordType::Other &&\n          keyword_type !=\n              sourcemeta::core::SchemaKeywordType::LocationMembers) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.rename(\"unevaluatedProperties\", \"additionalProperties\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    return target.rebase(current.concat({\"unevaluatedProperties\"}),\n                         current.concat({\"additionalProperties\"}));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/unsatisfiable_can_equal_bounds.h",
    "content": "class UnsatisfiableCanEqualBounds final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  UnsatisfiableCanEqualBounds()\n      : SchemaTransformRule{\"unsatisfiable_can_equal_bounds\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_2) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"number\" || type->to_string() == \"integer\"));\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number() && *minimum == *maximum);\n\n    const auto *minimum_can_equal{schema.try_at(\"minimumCanEqual\")};\n    const bool min_exclusive{minimum_can_equal &&\n                             minimum_can_equal->is_boolean() &&\n                             !minimum_can_equal->to_boolean()};\n    const auto *maximum_can_equal{schema.try_at(\"maximumCanEqual\")};\n    const bool max_exclusive{maximum_can_equal &&\n                             maximum_can_equal->is_boolean() &&\n                             !maximum_can_equal->to_boolean()};\n    ONLY_CONTINUE_IF(min_exclusive || max_exclusive);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.into(JSON{false});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/unsatisfiable_exclusive_equal_bounds.h",
    "content": "class UnsatisfiableExclusiveEqualBounds final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  UnsatisfiableExclusiveEqualBounds()\n      : SchemaTransformRule{\"unsatisfiable_exclusive_equal_bounds\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_3,\n                                   Vocabularies::Known::JSON_Schema_Draft_4}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"number\" || type->to_string() == \"integer\"));\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number() && *minimum == *maximum);\n\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    const bool exclusive_min{exclusive_minimum &&\n                             exclusive_minimum->is_boolean() &&\n                             exclusive_minimum->to_boolean()};\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    const bool exclusive_max{exclusive_maximum &&\n                             exclusive_maximum->is_boolean() &&\n                             exclusive_maximum->to_boolean()};\n    ONLY_CONTINUE_IF(exclusive_min || exclusive_max);\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.into(JSON{false});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/canonicalizer/unsatisfiable_type_and_enum.h",
    "content": "class UnsatisfiableTypeAndEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  UnsatisfiableTypeAndEnum()\n      : SchemaTransformRule{\"unsatisfiable_type_and_enum\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_0,\n             Vocabularies::Known::JSON_Schema_Draft_1,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string());\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\n                     !enum_value->empty());\n\n    const auto declared_types{parse_schema_type(*type)};\n    ONLY_CONTINUE_IF(declared_types.any());\n    const bool integer_matches_integral{\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_2020_12_Validation}) &&\n        declared_types.test(std::to_underlying(JSON::Type::Integer))};\n    ONLY_CONTINUE_IF(std::ranges::none_of(\n        enum_value->as_array(),\n        [&declared_types, integer_matches_integral](const auto &value) {\n          return declared_types.test(std::to_underlying(value.type())) ||\n                 (integer_matches_integral && value.is_integral());\n        }));\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.into(JSON{false});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/allof_false_simplify.h",
    "content": "class AllOfFalseSimplify final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AllOfFalseSimplify()\n      : SchemaTransformRule{\"allof_false_simplify\",\n                            \"When `allOf` contains a `false` branch, the \"\n                            \"schema is unsatisfiable\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"not\"));\n\n    const auto *all_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array());\n\n    for (std::size_t index = 0; index < all_of->size(); ++index) {\n      const auto &entry{all_of->at(index)};\n      if (entry.is_boolean() && !entry.to_boolean()) {\n        ONLY_CONTINUE_IF(!frame.has_references_through(\n            location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n        return APPLIES_TO_POINTERS({Pointer{KEYWORD, index}});\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"allOf\").into(JSON{true});\n    schema.rename(\"allOf\", \"not\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/anyof_false_simplify.h",
    "content": "class AnyOfFalseSimplify final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AnyOfFalseSimplify()\n      : SchemaTransformRule{\"anyof_false_simplify\",\n                            \"An `anyOf` of a single `false` branch is \"\n                            \"unsatisfiable\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"not\"));\n\n    const auto *any_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(any_of && any_of->is_array() && any_of->size() == 1);\n\n    const auto &entry{any_of->front()};\n    ONLY_CONTINUE_IF(entry.is_boolean() && !entry.to_boolean());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_POINTERS({Pointer{KEYWORD, 0}});\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"anyOf\").into(JSON{true});\n    schema.rename(\"anyOf\", \"not\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/anyof_remove_false_schemas.h",
    "content": "class AnyOfRemoveFalseSchemas final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AnyOfRemoveFalseSchemas()\n      : SchemaTransformRule{\n            \"anyof_remove_false_schemas\",\n            \"The boolean schema `false` is guaranteed to never match in \"\n            \"`anyOf`, as it is sufficient for any other branch to match\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_array() &&\n                     schema.at(KEYWORD).contains(JSON{false}));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n\n    std::vector<Pointer> false_locations;\n    bool has_non_false{false};\n    const auto &anyof{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < anyof.size(); ++index) {\n      const auto &entry{anyof.at(index)};\n      if (entry.is_boolean() && !entry.to_boolean()) {\n        false_locations.push_back(Pointer{KEYWORD, index});\n      } else {\n        has_non_false = true;\n      }\n    }\n\n    ONLY_CONTINUE_IF(has_non_false);\n    return APPLIES_TO_POINTERS(std::move(false_locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n\n    std::unordered_set<std::size_t> indices_to_remove;\n    for (const auto &location : result.locations) {\n      indices_to_remove.insert(location.at(1).to_index());\n    }\n\n    auto new_anyof{JSON::make_array()};\n    const auto &anyof{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < anyof.size(); ++index) {\n      if (!indices_to_remove.contains(index)) {\n        new_anyof.push_back(anyof.at(index));\n      }\n    }\n\n    schema.assign(KEYWORD, std::move(new_anyof));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/anyof_true_simplify.h",
    "content": "class AnyOfTrueSimplify final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  AnyOfTrueSimplify()\n      : SchemaTransformRule{\n            \"anyof_true_simplify\",\n            \"An `anyOf` with a `true` or `{}` branch always succeeds\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_array());\n\n    // When unevaluated keywords are present at this level or any\n    // ancestor, `anyOf` annotations are semantically meaningful even\n    // if one branch always succeeds\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_2020_12_Applicator})) {\n      auto cursor{std::cref(location)};\n      while (true) {\n        const auto &current_schema{\n            sourcemeta::core::get(root, cursor.get().pointer)};\n        if (current_schema.is_object() &&\n            (current_schema.defines(\"unevaluatedItems\") ||\n             current_schema.defines(\"unevaluatedProperties\"))) {\n          return false;\n        }\n        if (!cursor.get().parent.has_value()) {\n          break;\n        }\n        const auto parent_location{frame.traverse(cursor.get().parent.value())};\n        if (!parent_location.has_value()) {\n          break;\n        }\n        cursor = parent_location.value();\n      }\n    }\n\n    const auto &anyof{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < anyof.size(); ++index) {\n      const auto &entry{anyof.at(index)};\n      if ((entry.is_boolean() && entry.to_boolean()) ||\n          (entry.is_object() && entry.empty())) {\n        ONLY_CONTINUE_IF(!frame.has_references_through(\n            location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n        return APPLIES_TO_POINTERS({Pointer{KEYWORD, index}});\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"anyOf\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/const_in_enum.h",
    "content": "class ConstInEnum final : public SchemaTransformRule {\r\npublic:\r\n  using mutates = std::true_type;\r\n  using reframe_after_transform = std::true_type;\r\n  ConstInEnum()\r\n      : SchemaTransformRule{\r\n            \"const_in_enum\",\r\n            \"If the `const` and `enum` keyword overlap, then `enum` is \"\r\n            \"redundant and can be removed\"} {};\r\n\r\n  [[nodiscard]] auto\r\n  condition(const sourcemeta::core::JSON &schema,\r\n            const sourcemeta::core::JSON &,\r\n            const sourcemeta::core::Vocabularies &vocabularies,\r\n            const sourcemeta::core::SchemaFrame &,\r\n            const sourcemeta::core::SchemaFrame::Location &,\r\n            const sourcemeta::core::SchemaWalker &,\r\n            const sourcemeta::core::SchemaResolver &) const\r\n      -> SchemaTransformRule::Result override {\r\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\r\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\r\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\r\n                          Vocabularies::Known::JSON_Schema_Draft_7,\r\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\r\n                     schema.is_object());\r\n\r\n    const auto *const_value{schema.try_at(\"const\")};\r\n    ONLY_CONTINUE_IF(const_value);\r\n    const auto *enum_value{schema.try_at(\"enum\")};\r\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\r\n                     enum_value->contains(*const_value));\r\n    return APPLIES_TO_KEYWORDS(\"const\", \"enum\");\r\n  }\r\n\r\n  auto transform(JSON &schema, const Result &) const -> void override {\r\n    schema.erase(\"enum\");\r\n  }\r\n};\r\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/const_with_type.h",
    "content": "class ConstWithType final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ConstWithType()\n      : SchemaTransformRule{\n            \"const_with_type\",\n            \"Setting `type` alongside `const` is considered an anti-pattern, \"\n            \"as the constant already implies its respective type\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type);\n    const auto *const_value{schema.try_at(\"const\")};\n    ONLY_CONTINUE_IF(const_value);\n\n    const auto current_types{parse_schema_type(*type)};\n    ONLY_CONTINUE_IF(current_types.any());\n    ONLY_CONTINUE_IF(\n        current_types.test(std::to_underlying(const_value->type())));\n    return APPLIES_TO_KEYWORDS(\"const\", \"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/content_media_type_without_encoding.h",
    "content": "class ContentMediaTypeWithoutEncoding final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ContentMediaTypeWithoutEncoding()\n      : SchemaTransformRule{\n            \"content_media_type_without_encoding\",\n            \"The `contentMediaType` keyword is meaningless \"\n            \"without the presence of the `contentEncoding` keyword\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Content,\n                          Vocabularies::Known::JSON_Schema_2019_09_Content,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object() && schema.defines(\"contentMediaType\") &&\n                     !schema.defines(\"contentEncoding\"));\n    return APPLIES_TO_KEYWORDS(\"contentMediaType\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"contentMediaType\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/content_schema_without_media_type.h",
    "content": "class ContentSchemaWithoutMediaType final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"contentSchema\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ContentSchemaWithoutMediaType()\n      : SchemaTransformRule{\n            \"content_schema_without_media_type\",\n            \"The `contentSchema` keyword is meaningless without the presence \"\n            \"of the `contentMediaType` keyword\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Content,\n                          Vocabularies::Known::JSON_Schema_2019_09_Content}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     !schema.defines(\"contentMediaType\"));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/dependencies_property_tautology.h",
    "content": "class DependenciesPropertyTautology final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependenciesPropertyTautology()\n      : SchemaTransformRule{\n            \"dependencies_property_tautology\",\n            \"Defining requirements for a property using `dependencies` \"\n            \"that is already marked as required is an unnecessarily complex \"\n            \"use of `dependencies`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *dependencies{schema.try_at(\"dependencies\")};\n    ONLY_CONTINUE_IF(dependencies && dependencies->is_object());\n\n    const bool is_draft_3{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper})};\n\n    if (is_draft_3) {\n      const auto *properties{schema.try_at(\"properties\")};\n      ONLY_CONTINUE_IF(properties && properties->is_object());\n\n      ONLY_CONTINUE_IF(std::ranges::any_of(\n          properties->as_object(), [dependencies](const auto &entry) {\n            if (!entry.second.is_object()) {\n              return false;\n            }\n            const auto *required{entry.second.try_at(\"required\")};\n            if (!required || !required->is_boolean() ||\n                !required->to_boolean()) {\n              return false;\n            }\n            const auto *dependent{dependencies->try_at(entry.first)};\n            return dependent &&\n                   (dependent->is_array() || dependent->is_string());\n          }));\n      return APPLIES_TO_KEYWORDS(\"dependencies\", \"properties\");\n    }\n\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(required && required->is_array());\n\n    ONLY_CONTINUE_IF(std::ranges::any_of(\n        required->as_array(), [dependencies](const auto &element) {\n          if (!element.is_string()) {\n            return false;\n          }\n          const auto *dependent{dependencies->try_at(element.to_string())};\n          return dependent && (dependent->is_array() || dependent->is_string());\n        }));\n    return APPLIES_TO_KEYWORDS(\"dependencies\", \"required\");\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    const bool is_draft_3_path{\n        std::ranges::any_of(result.locations, [](const auto &pointer) {\n          return pointer.size() == 1 && pointer.at(0).is_property() &&\n                 pointer.at(0).to_property() == \"properties\";\n        })};\n    if (is_draft_3_path) {\n      this->transform_boolean(schema);\n    } else {\n      this->transform_array(schema);\n    }\n  }\n\nprivate:\n  static auto transform_array(JSON &schema) -> void {\n    auto requirements{schema.at(\"required\")};\n    while (true) {\n      bool match{false};\n      const auto copy{requirements};\n      for (const auto &element : copy.as_array()) {\n        if (!element.is_string() ||\n            !schema.at(\"dependencies\").defines(element.to_string())) {\n          continue;\n        }\n\n        const auto &dependents{\n            schema.at(\"dependencies\").at(element.to_string())};\n        if (dependents.is_array()) {\n          for (const auto &dependent : dependents.as_array()) {\n            if (dependent.is_string()) {\n              match = true;\n              requirements.push_back(dependent);\n            }\n          }\n\n          schema.at(\"dependencies\").erase(element.to_string());\n        } else if (dependents.is_string()) {\n          match = true;\n          requirements.push_back(dependents);\n          schema.at(\"dependencies\").erase(element.to_string());\n        }\n      }\n\n      if (!match) {\n        break;\n      }\n    }\n\n    schema.assign(\"required\", requirements);\n  }\n\n  static auto transform_boolean(JSON &schema) -> void {\n    while (true) {\n      bool match{false};\n\n      std::vector<JSON::String> snapshot;\n      for (const auto &entry : schema.at(\"properties\").as_object()) {\n        if (!entry.second.is_object()) {\n          continue;\n        }\n        const auto *required{entry.second.try_at(\"required\")};\n        if (required && required->is_boolean() && required->to_boolean()) {\n          snapshot.push_back(entry.first);\n        }\n      }\n\n      for (const auto &name : snapshot) {\n        if (!schema.at(\"dependencies\").defines(name)) {\n          continue;\n        }\n\n        const auto dependents_copy{schema.at(\"dependencies\").at(name)};\n        std::vector<JSON::String> new_required;\n        if (dependents_copy.is_string()) {\n          new_required.push_back(dependents_copy.to_string());\n        } else if (dependents_copy.is_array()) {\n          for (const auto &dependent : dependents_copy.as_array()) {\n            if (dependent.is_string()) {\n              new_required.push_back(dependent.to_string());\n            }\n          }\n        } else {\n          continue;\n        }\n\n        for (const auto &dependency_name : new_required) {\n          if (!schema.at(\"properties\").defines(dependency_name)) {\n            auto new_property{JSON::make_object()};\n            new_property.assign(\"required\", JSON{true});\n            schema.at(\"properties\")\n                .assign(dependency_name, std::move(new_property));\n            match = true;\n          } else if (schema.at(\"properties\").at(dependency_name).is_object()) {\n            auto &existing{schema.at(\"properties\").at(dependency_name)};\n            const auto *current_required{existing.try_at(\"required\")};\n            if (!current_required || !current_required->is_boolean() ||\n                !current_required->to_boolean()) {\n              existing.assign(\"required\", JSON{true});\n              match = true;\n            }\n          }\n        }\n\n        schema.at(\"dependencies\").erase(name);\n      }\n\n      if (!match) {\n        break;\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/dependent_required_tautology.h",
    "content": "class DependentRequiredTautology final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DependentRequiredTautology()\n      : SchemaTransformRule{\n            \"dependent_required_tautology\",\n            \"Defining requirements for a property using `dependentRequired` \"\n            \"that is already marked as required is an unnecessarily complex \"\n            \"use of `dependentRequired`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object());\n\n    const auto *dependent_required{schema.try_at(\"dependentRequired\")};\n    ONLY_CONTINUE_IF(dependent_required && dependent_required->is_object());\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(required && required->is_array());\n\n    ONLY_CONTINUE_IF(\n        std::any_of(required->as_array().cbegin(), required->as_array().cend(),\n                    [dependent_required](const auto &element) {\n                      return element.is_string() &&\n                             dependent_required->defines(element.to_string());\n                    }));\n    return APPLIES_TO_KEYWORDS(\"dependentRequired\", \"required\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto requirements{schema.at(\"required\")};\n    while (true) {\n      bool match{false};\n      const auto copy{requirements};\n      for (const auto &element : copy.as_array()) {\n        if (!element.is_string() ||\n            !schema.at(\"dependentRequired\").defines(element.to_string())) {\n          continue;\n        }\n\n        const auto &dependents{\n            schema.at(\"dependentRequired\").at(element.to_string())};\n        if (dependents.is_array()) {\n          for (const auto &dependent : dependents.as_array()) {\n            if (dependent.is_string()) {\n              match = true;\n              requirements.push_back(dependent);\n            }\n          }\n\n          schema.at(\"dependentRequired\").erase(element.to_string());\n        }\n      }\n\n      if (!match) {\n        break;\n      }\n    }\n\n    schema.assign(\"required\", requirements);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/disallow_narrows_type.h",
    "content": "class DisallowNarrowsType final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DisallowNarrowsType()\n      : SchemaTransformRule{\n            \"disallow_narrows_type\",\n            \"When `disallow` excludes types that are also in the parent \"\n            \"`type`, those types can be removed from `type` and the \"\n            \"corresponding `disallow` entries dropped\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"disallow\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *disallow{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(disallow && disallow->is_array() && !disallow->empty());\n\n    const auto *parent_type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(parent_type && parent_type->is_array() &&\n                     parent_type->size() > 1);\n\n    std::unordered_set<JSON::String> parent_type_names;\n    for (const auto &entry : parent_type->as_array()) {\n      ONLY_CONTINUE_IF(entry.is_string() && entry.to_string() != \"any\");\n      parent_type_names.insert(entry.to_string());\n    }\n\n    std::vector<Pointer> locations;\n    std::unordered_set<JSON::String> narrowed_types;\n    for (std::size_t index = 0; index < disallow->size(); ++index) {\n      const auto entry_types{extract_type_names(disallow->at(index))};\n      if (entry_types.empty()) {\n        continue;\n      }\n\n      const bool all_in_parent{std::ranges::all_of(\n          entry_types, [&parent_type_names](const auto &type_name) {\n            return parent_type_names.contains(type_name);\n          })};\n      if (!all_in_parent) {\n        continue;\n      }\n\n      locations.push_back(Pointer{KEYWORD, index});\n      narrowed_types.insert(entry_types.cbegin(), entry_types.cend());\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    ONLY_CONTINUE_IF(narrowed_types.size() < parent_type_names.size());\n\n    auto keyword_pointer{location.pointer};\n    keyword_pointer.push_back(std::cref(KEYWORD));\n    ONLY_CONTINUE_IF(!frame.has_references_through(keyword_pointer));\n\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    std::unordered_set<JSON::String> narrowed_types;\n    std::vector<std::size_t> dead_indices;\n    dead_indices.reserve(result.locations.size());\n    const auto &disallow{schema.at(\"disallow\")};\n    for (const auto &location : result.locations) {\n      assert(location.size() == 2);\n      const auto index{location.at(1).to_index()};\n      dead_indices.push_back(index);\n      const auto entry_types{extract_type_names(disallow.at(index))};\n      narrowed_types.insert(entry_types.cbegin(), entry_types.cend());\n    }\n\n    auto new_type{JSON::make_array()};\n    for (const auto &entry : schema.at(\"type\").as_array()) {\n      if (entry.is_string() && !narrowed_types.contains(entry.to_string())) {\n        new_type.push_back(entry);\n      }\n    }\n    schema.assign(\"type\", std::move(new_type));\n\n    auto new_disallow{JSON::make_array()};\n    for (std::size_t index = 0; index < disallow.size(); ++index) {\n      if (std::ranges::find(dead_indices, index) == dead_indices.end()) {\n        new_disallow.push_back(disallow.at(index));\n      }\n    }\n    if (new_disallow.empty()) {\n      schema.erase(\"disallow\");\n    } else {\n      schema.assign(\"disallow\", std::move(new_disallow));\n    }\n  }\n\nprivate:\n  static auto extract_type_names(const sourcemeta::core::JSON &entry)\n      -> std::unordered_set<JSON::String> {\n    std::unordered_set<JSON::String> result;\n    if (entry.is_string()) {\n      if (entry.to_string() != \"any\") {\n        result.insert(entry.to_string());\n      }\n      return result;\n    }\n    if (!entry.is_object() || entry.size() != 1) {\n      return result;\n    }\n    const auto *entry_type{entry.try_at(\"type\")};\n    if (!entry_type) {\n      return result;\n    }\n    if (entry_type->is_string()) {\n      if (entry_type->to_string() != \"any\") {\n        result.insert(entry_type->to_string());\n      }\n      return result;\n    }\n    if (!entry_type->is_array()) {\n      return result;\n    }\n    for (const auto &type_entry : entry_type->as_array()) {\n      if (!type_entry.is_string() || type_entry.to_string() == \"any\") {\n        return std::unordered_set<JSON::String>{};\n      }\n      result.insert(type_entry.to_string());\n    }\n    return result;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/double_negation_elimination.h",
    "content": "class DoubleNegationElimination final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DoubleNegationElimination()\n      : SchemaTransformRule{\n            \"double_negation_elimination\",\n            \"A `not` whose value is a schema containing only another \"\n            \"`not` is equivalent to the inner value\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"not\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *outer_not{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(outer_not && outer_not->is_object() &&\n                     outer_not->size() == 1);\n    const auto *inner_not{outer_not->try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(inner_not &&\n                     !(inner_not->is_boolean() && !inner_not->to_boolean()));\n    ONLY_CONTINUE_IF(\n        !(vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n               Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n          (schema.defines(\"unevaluatedProperties\") ||\n           schema.defines(\"unevaluatedItems\"))));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto inner{schema.at(\"not\").at(\"not\")};\n    schema.erase(\"not\");\n\n    while (inner.is_object() && inner.size() == 1 && inner.defines(\"not\") &&\n           inner.at(\"not\").is_object() && inner.at(\"not\").size() == 1 &&\n           inner.at(\"not\").defines(\"not\") &&\n           !(inner.at(\"not\").at(\"not\").is_boolean() &&\n             !inner.at(\"not\").at(\"not\").to_boolean())) {\n      auto next{inner.at(\"not\").at(\"not\")};\n      inner = std::move(next);\n    }\n\n    if (inner.is_object()) {\n      schema.merge(inner.as_object());\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    auto old_prefix{current.concat({\"not\", \"not\"})};\n    while (target.starts_with(old_prefix.concat({\"not\", \"not\"}))) {\n      old_prefix = old_prefix.concat({\"not\", \"not\"});\n    }\n    if (!target.starts_with(old_prefix)) {\n      return target;\n    }\n    return target.rebase(old_prefix, current);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/draft_official_dialect_with_https.h",
    "content": "class DraftOfficialDialectWithHttps final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DraftOfficialDialectWithHttps()\n      : SchemaTransformRule{\n            \"draft_official_dialect_with_https\",\n            \"The official dialect URI of Draft 7 and older must use \"\n            \"\\\"http://\\\" instead of \\\"https://\\\"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    using sourcemeta::core::SchemaBaseDialect;\n    ONLY_CONTINUE_IF(\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_7 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_7_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_6 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_6_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_4 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_4_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_3 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_3_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_2_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_1_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_Draft_0_Hyper);\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *schema_keyword{schema.try_at(\"$schema\")};\n    ONLY_CONTINUE_IF(schema_keyword && schema_keyword->is_string());\n    const auto &dialect{schema_keyword->to_string()};\n    ONLY_CONTINUE_IF(dialect.starts_with(\"https://json-schema.org/\"));\n    ONLY_CONTINUE_IF(\n        dialect == \"https://json-schema.org/draft-07/schema\" ||\n        dialect == \"https://json-schema.org/draft-07/schema#\" ||\n        dialect == \"https://json-schema.org/draft-07/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-07/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-06/schema\" ||\n        dialect == \"https://json-schema.org/draft-06/schema#\" ||\n        dialect == \"https://json-schema.org/draft-06/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-06/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-04/schema\" ||\n        dialect == \"https://json-schema.org/draft-04/schema#\" ||\n        dialect == \"https://json-schema.org/draft-04/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-04/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-03/schema\" ||\n        dialect == \"https://json-schema.org/draft-03/schema#\" ||\n        dialect == \"https://json-schema.org/draft-03/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-03/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-02/schema\" ||\n        dialect == \"https://json-schema.org/draft-02/schema#\" ||\n        dialect == \"https://json-schema.org/draft-02/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-02/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-01/schema\" ||\n        dialect == \"https://json-schema.org/draft-01/schema#\" ||\n        dialect == \"https://json-schema.org/draft-01/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-01/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft-00/schema\" ||\n        dialect == \"https://json-schema.org/draft-00/schema#\" ||\n        dialect == \"https://json-schema.org/draft-00/hyper-schema\" ||\n        dialect == \"https://json-schema.org/draft-00/hyper-schema#\");\n    return APPLIES_TO_KEYWORDS(\"$schema\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    const auto &old_dialect{schema.at(\"$schema\").to_string()};\n    std::string new_dialect{\"http://\"};\n    new_dialect += old_dialect.substr(8);\n    schema.at(\"$schema\").into(sourcemeta::core::JSON{new_dialect});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/draft_official_dialect_without_empty_fragment.h",
    "content": "class DraftOfficialDialectWithoutEmptyFragment final\n    : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DraftOfficialDialectWithoutEmptyFragment()\n      : SchemaTransformRule{\"draft_official_dialect_without_empty_fragment\",\n                            \"The official dialect URI of Draft 7 and older \"\n                            \"versions must contain the empty fragment\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::core::JSON &schema,\n                               const sourcemeta::core::JSON &,\n                               const sourcemeta::core::Vocabularies &,\n                               const sourcemeta::core::SchemaFrame &,\n                               const sourcemeta::core::SchemaFrame::Location &,\n                               const sourcemeta::core::SchemaWalker &,\n                               const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *schema_keyword{schema.try_at(\"$schema\")};\n    ONLY_CONTINUE_IF(schema_keyword && schema_keyword->is_string());\n    const auto &dialect{schema_keyword->to_string()};\n    ONLY_CONTINUE_IF(\n        dialect == \"http://json-schema.org/draft-07/schema\" ||\n        dialect == \"http://json-schema.org/draft-07/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-06/schema\" ||\n        dialect == \"http://json-schema.org/draft-06/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-04/schema\" ||\n        dialect == \"http://json-schema.org/draft-04/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-03/schema\" ||\n        dialect == \"http://json-schema.org/draft-03/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-02/schema\" ||\n        dialect == \"http://json-schema.org/draft-02/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-01/schema\" ||\n        dialect == \"http://json-schema.org/draft-01/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft-00/schema\" ||\n        dialect == \"http://json-schema.org/draft-00/hyper-schema\");\n    return APPLIES_TO_KEYWORDS(\"$schema\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    auto dialect{std::move(schema.at(\"$schema\")).to_string()};\n    dialect += \"#\";\n    schema.at(\"$schema\").into(sourcemeta::core::JSON{dialect});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/draft_ref_siblings.h",
    "content": "class DraftRefSiblings final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DraftRefSiblings()\n      : SchemaTransformRule{\"draft_ref_siblings\",\n                            \"In Draft 7 and older dialects, keywords sibling \"\n                            \"to `$ref` are never evaluated\"} {}\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1,\n         Vocabularies::Known::JSON_Schema_Draft_0}));\n    ONLY_CONTINUE_IF(schema.is_object() && schema.defines(\"$ref\"));\n\n    std::vector<Pointer> locations;\n    for (const auto &entry : schema.as_object()) {\n      const auto &metadata{walker(entry.first, vocabularies)};\n      if (metadata.type == sourcemeta::core::SchemaKeywordType::Reference ||\n          metadata.type == sourcemeta::core::SchemaKeywordType::Comment ||\n          // If we disallow this, we end up deleting it and the linter will fail\n          // with an error about not knowing the dialect\n          entry.first == \"$schema\") {\n        continue;\n      } else {\n        locations.push_back(Pointer{entry.first});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      schema.erase(location.at(0).to_property());\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/drop_allof_empty_schemas.h",
    "content": "class DropAllOfEmptySchemas final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DropAllOfEmptySchemas()\n      : SchemaTransformRule{\"drop_allof_empty_schemas\",\n                            \"Empty schemas in `allOf` are redundant and can be \"\n                            \"removed\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &, const SchemaFrame::Location &,\n            const SchemaWalker &, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n         Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *all_of{schema.try_at(\"allOf\")};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array() && !all_of->empty());\n    ONLY_CONTINUE_IF(std::ranges::any_of(all_of->as_array(), is_empty_schema));\n    return APPLIES_TO_KEYWORDS(\"allOf\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto new_allof{JSON::make_array()};\n    for (const auto &entry : schema.at(\"allOf\").as_array()) {\n      if (!is_empty_schema(entry)) {\n        new_allof.push_back(entry);\n      }\n    }\n\n    if (new_allof.empty()) {\n      schema.erase(\"allOf\");\n    } else {\n      // Re-assign instead of the deleting in place to invalid memory addresses\n      // and avoid confusing the transformer\n      schema.assign(\"allOf\", std::move(new_allof));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/drop_extends_empty_schemas.h",
    "content": "class DropExtendsEmptySchemas final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DropExtendsEmptySchemas()\n      : SchemaTransformRule{\n            \"drop_extends_empty_schemas\",\n            \"Empty schemas in `extends` are redundant and can be removed\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"extends\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *extends{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(extends);\n\n    auto keyword_pointer{location.pointer};\n    keyword_pointer.push_back(std::cref(KEYWORD));\n    ONLY_CONTINUE_IF(!frame.has_references_through(keyword_pointer));\n\n    if (sourcemeta::core::is_empty_schema(*extends)) {\n      return APPLIES_TO_POINTERS({Pointer{KEYWORD}});\n    }\n\n    if (extends->is_array() && !extends->empty()) {\n      std::vector<Pointer> locations;\n      for (std::size_t index = 0; index < extends->size(); ++index) {\n        if (sourcemeta::core::is_empty_schema(extends->at(index))) {\n          locations.push_back(Pointer{KEYWORD, index});\n        }\n      }\n      ONLY_CONTINUE_IF(!locations.empty());\n      return APPLIES_TO_POINTERS(std::move(locations));\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    if (result.locations.size() == 1 && result.locations.at(0).size() == 1) {\n      schema.erase(\"extends\");\n      return;\n    }\n\n    auto new_extends{JSON::make_array()};\n    for (const auto &entry : schema.at(\"extends\").as_array()) {\n      if (!sourcemeta::core::is_empty_schema(entry)) {\n        new_extends.push_back(entry);\n      }\n    }\n\n    if (new_extends.empty()) {\n      schema.erase(\"extends\");\n    } else {\n      schema.assign(\"extends\", std::move(new_extends));\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/duplicate_allof_branches.h",
    "content": "class DuplicateAllOfBranches final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DuplicateAllOfBranches()\n      : SchemaTransformRule{\n            \"duplicate_allof_branches\",\n            \"Setting duplicate subschemas in `allOf` is redundant, as it \"\n            \"produces \"\n            \"unnecessary additional validation that is guaranteed to not \"\n            \"affect the validation result\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *all_of{schema.try_at(\"allOf\")};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array() && !all_of->unique());\n    // TODO: Highlight which specific entries in `allOf` are duplicated\n    return APPLIES_TO_KEYWORDS(\"allOf\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    this->index_mapping_.clear();\n    const auto &original{schema.at(\"allOf\")};\n\n    std::unordered_map<std::reference_wrapper<const JSON>, std::size_t,\n                       HashJSON<std::reference_wrapper<const JSON>>,\n                       EqualJSON<std::reference_wrapper<const JSON>>>\n        seen;\n    auto result{JSON::make_array()};\n\n    for (std::size_t index = 0; index < original.size(); ++index) {\n      const auto &value{original.at(index)};\n      const auto match{seen.find(std::cref(value))};\n\n      if (match == seen.end()) {\n        this->index_mapping_[index] = seen.size();\n        seen.emplace(std::cref(value), seen.size());\n        result.push_back(value);\n      } else {\n        this->index_mapping_[index] = match->second;\n      }\n    }\n\n    schema.assign(\"allOf\", std::move(result));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    const auto allof_prefix{current.concat({\"allOf\"})};\n    const auto relative{target.resolve_from(allof_prefix)};\n    const auto old_index{relative.at(0).to_index()};\n    const auto new_index{this->index_mapping_.at(old_index)};\n    const Pointer old_prefix{allof_prefix.concat({old_index})};\n    const Pointer new_prefix{allof_prefix.concat({new_index})};\n    return target.rebase(old_prefix, new_prefix);\n  }\n\nprivate:\n  mutable std::unordered_map<std::size_t, std::size_t> index_mapping_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/duplicate_anyof_branches.h",
    "content": "class DuplicateAnyOfBranches final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DuplicateAnyOfBranches()\n      : SchemaTransformRule{\n            \"duplicate_anyof_branches\",\n            \"Setting duplicate subschemas in `anyOf` is redundant, as it \"\n            \"produces \"\n            \"unnecessary additional validation that is guaranteed to not \"\n            \"affect the validation result\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *any_of{schema.try_at(\"anyOf\")};\n    ONLY_CONTINUE_IF(any_of && any_of->is_array() && !any_of->unique());\n    // TODO: Highlight which specific entries in `anyOf` are duplicated\n    return APPLIES_TO_KEYWORDS(\"anyOf\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    this->index_mapping_.clear();\n    const auto &original{schema.at(\"anyOf\")};\n\n    std::unordered_map<std::reference_wrapper<const JSON>, std::size_t,\n                       HashJSON<std::reference_wrapper<const JSON>>,\n                       EqualJSON<std::reference_wrapper<const JSON>>>\n        seen;\n    auto result{JSON::make_array()};\n\n    for (std::size_t index = 0; index < original.size(); ++index) {\n      const auto &value{original.at(index)};\n      const auto match{seen.find(std::cref(value))};\n\n      if (match == seen.end()) {\n        this->index_mapping_[index] = seen.size();\n        seen.emplace(std::cref(value), seen.size());\n        result.push_back(value);\n      } else {\n        this->index_mapping_[index] = match->second;\n      }\n    }\n\n    schema.assign(\"anyOf\", std::move(result));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    const auto anyof_prefix{current.concat({\"anyOf\"})};\n    const auto relative{target.resolve_from(anyof_prefix)};\n    const auto old_index{relative.at(0).to_index()};\n    const auto new_index{this->index_mapping_.at(old_index)};\n    const Pointer old_prefix{anyof_prefix.concat({old_index})};\n    const Pointer new_prefix{anyof_prefix.concat({new_index})};\n    return target.rebase(old_prefix, new_prefix);\n  }\n\nprivate:\n  mutable std::unordered_map<std::size_t, std::size_t> index_mapping_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/duplicate_enum_values.h",
    "content": "class DuplicateEnumValues final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DuplicateEnumValues()\n      : SchemaTransformRule{\"duplicate_enum_values\",\n                            \"Setting duplicate values in `enum` is \"\n                            \"considered an anti-pattern\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1}) &&\n                     schema.is_object());\n\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\n                     !enum_value->unique());\n    // TODO: Highlight which specific entries in `enum` are duplicated\n    return APPLIES_TO_KEYWORDS(\"enum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    // We want to be super careful to maintain the current ordering\n    // as we delete the duplicates\n    auto &enumeration{schema.at(\"enum\")};\n    std::unordered_set<JSON, HashJSON<JSON>> cache;\n    for (auto iterator = enumeration.as_array().cbegin();\n         iterator != enumeration.as_array().cend();) {\n      if (cache.contains(*iterator)) {\n        iterator = enumeration.erase(iterator);\n      } else {\n        cache.emplace(*iterator);\n        iterator++;\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/duplicate_required_values.h",
    "content": "class DuplicateRequiredValues final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DuplicateRequiredValues()\n      : SchemaTransformRule{\n            \"duplicate_required_values\",\n            \"Setting duplicate values in `required` is considered an \"\n            \"anti-pattern\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(required && required->is_array() && !required->unique());\n    // TODO: Highlight which specific entries in `required` are duplicated\n    return APPLIES_TO_KEYWORDS(\"required\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto collection = schema.at(\"required\");\n    std::sort(collection.as_array().begin(), collection.as_array().end());\n    auto last =\n        std::unique(collection.as_array().begin(), collection.as_array().end());\n    collection.erase(last, collection.as_array().end());\n    schema.at(\"required\").into(std::move(collection));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/dynamic_ref_to_static_ref.h",
    "content": "class DynamicRefToStaticRef final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD_DYNAMIC_REF{\"$dynamicRef\"};\n  static inline const std::string KEYWORD_RECURSIVE_REF{\"$recursiveRef\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DynamicRefToStaticRef()\n      : SchemaTransformRule{\n            \"dynamic_ref_to_static_ref\",\n            \"A dynamic reference whose destination is unambiguous can be \"\n            \"expressed as a static reference\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object() && !schema.defines(\"$ref\"));\n\n    if (vocabularies.contains(Vocabularies::Known::JSON_Schema_2020_12_Core) &&\n        schema.defines(\"$dynamicRef\")) {\n      auto reference_pointer{location.pointer};\n      reference_pointer.push_back(std::cref(KEYWORD_DYNAMIC_REF));\n\n      auto reference_entry{frame.reference(\n          sourcemeta::core::SchemaReferenceType::Static, reference_pointer)};\n      if (!reference_entry.has_value()) {\n        reference_entry = frame.reference(\n            sourcemeta::core::SchemaReferenceType::Dynamic, reference_pointer);\n      }\n      if (!reference_entry.has_value()) {\n        return false;\n      }\n\n      const auto destination{\n          frame.traverse(reference_entry->get().destination)};\n      if (!destination.has_value()) {\n        return false;\n      }\n\n      if (destination->get().type ==\n          sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n        const auto &subschema{sourcemeta::core::get(\n            root, sourcemeta::core::to_pointer(destination->get().pointer))};\n        if (subschema.is_object()) {\n          const auto *dynamic_anchor{subschema.try_at(\"$dynamicAnchor\")};\n          if (dynamic_anchor != nullptr && dynamic_anchor->is_string()) {\n            const auto &destination_uri{reference_entry->get().destination};\n            const auto fragment_position{destination_uri.find('#')};\n            const std::string_view fragment{\n                fragment_position == std::string::npos\n                    ? std::string_view{destination_uri}\n                    : std::string_view{\n                          destination_uri.data() + fragment_position + 1,\n                          destination_uri.size() - fragment_position - 1}};\n            if (fragment == dynamic_anchor->to_string()) {\n              return false;\n            }\n          }\n        }\n      }\n\n      this->keyword_ = &KEYWORD_DYNAMIC_REF;\n      return APPLIES_TO_KEYWORDS(\"$dynamicRef\");\n    }\n\n    if (vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n        schema.defines(\"$recursiveRef\")) {\n      auto reference_pointer{location.pointer};\n      reference_pointer.push_back(std::cref(KEYWORD_RECURSIVE_REF));\n\n      auto reference_entry{frame.reference(\n          sourcemeta::core::SchemaReferenceType::Static, reference_pointer)};\n      if (!reference_entry.has_value()) {\n        reference_entry = frame.reference(\n            sourcemeta::core::SchemaReferenceType::Dynamic, reference_pointer);\n      }\n      if (!reference_entry.has_value()) {\n        return false;\n      }\n\n      const auto destination{\n          frame.traverse(reference_entry->get().destination)};\n      if (!destination.has_value()) {\n        return false;\n      }\n\n      const auto &subschema{sourcemeta::core::get(\n          root, sourcemeta::core::to_pointer(destination->get().pointer))};\n      if (subschema.is_object()) {\n        const auto *recursive_anchor{subschema.try_at(\"$recursiveAnchor\")};\n        if (recursive_anchor != nullptr && recursive_anchor->is_boolean() &&\n            recursive_anchor->to_boolean()) {\n          return false;\n        }\n      }\n\n      this->keyword_ = &KEYWORD_RECURSIVE_REF;\n      return APPLIES_TO_KEYWORDS(\"$recursiveRef\");\n    }\n\n    return false;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    assert(this->keyword_ != nullptr);\n    schema.rename(*this->keyword_, \"$ref\");\n  }\n\nprivate:\n  mutable const std::string *keyword_{nullptr};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/else_without_if.h",
    "content": "class ElseWithoutIf final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"else\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ElseWithoutIf()\n      : SchemaTransformRule{\"else_without_if\",\n                            \"The `else` keyword is meaningless \"\n                            \"without the presence of the `if` keyword\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     !schema.defines(\"if\"));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/empty_object_as_true.h",
    "content": "class EmptyObjectAsTrue final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  EmptyObjectAsTrue()\n      : SchemaTransformRule{\n            \"empty_object_as_true\",\n            \"The empty schema `{}` accepts all values and is equivalent to the \"\n            \"boolean schema `true`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Core,\n                          Vocabularies::Known::JSON_Schema_2019_09_Core,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && schema.empty());\n    return true;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.into(JSON{true});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/enum_with_type.h",
    "content": "class EnumWithType final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumWithType()\n      : SchemaTransformRule{\n            \"enum_with_type\",\n            \"Setting `type` alongside `enum` is considered an anti-pattern, as \"\n            \"the enumeration choices already imply their respective types\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type);\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array());\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_3_Hyper})) {\n      if (type->is_string() && type->to_string() == \"any\") {\n        return APPLIES_TO_KEYWORDS(\"enum\", \"type\");\n      }\n\n      if (type->is_array()) {\n        bool has_tautology{false};\n        bool has_unknown_subschema{false};\n        for (const auto &entry : type->as_array()) {\n          if (entry.is_string() && entry.to_string() == \"any\") {\n            has_tautology = true;\n            break;\n          }\n          if (entry.is_object()) {\n            if (entry.empty()) {\n              has_tautology = true;\n              break;\n            }\n            has_unknown_subschema = true;\n          }\n        }\n\n        if (has_tautology) {\n          return APPLIES_TO_KEYWORDS(\"enum\", \"type\");\n        }\n\n        if (has_unknown_subschema) {\n          return false;\n        }\n      }\n    }\n\n    const auto current_types{parse_schema_type(*type)};\n    ONLY_CONTINUE_IF(current_types.any());\n    const bool integer_matches_integral{\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_7}) &&\n        current_types.test(std::to_underlying(JSON::Type::Integer))};\n    ONLY_CONTINUE_IF(std::ranges::all_of(\n        enum_value->as_array(),\n        [&current_types, integer_matches_integral](const auto &item) {\n          return current_types.test(std::to_underlying(item.type())) ||\n                 (integer_matches_integral && item.is_integral());\n        }));\n\n    return APPLIES_TO_KEYWORDS(\"enum\", \"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/equal_numeric_bounds_to_enum.h",
    "content": "class EqualNumericBoundsToEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EqualNumericBoundsToEnum()\n      : SchemaTransformRule{\n            \"equal_numeric_bounds_to_enum\",\n            \"Setting `minimum` and `maximum` to the same number only leaves \"\n            \"one possible value\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_0}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"integer\" || type->to_string() == \"number\"));\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number() && *minimum == *maximum);\n\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    ONLY_CONTINUE_IF(!(exclusive_minimum && exclusive_minimum->is_boolean() &&\n                       exclusive_minimum->to_boolean()));\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    ONLY_CONTINUE_IF(!(exclusive_maximum && exclusive_maximum->is_boolean() &&\n                       exclusive_maximum->to_boolean()));\n    const auto *minimum_can_equal{schema.try_at(\"minimumCanEqual\")};\n    ONLY_CONTINUE_IF(!(minimum_can_equal && minimum_can_equal->is_boolean() &&\n                       !minimum_can_equal->to_boolean()));\n    const auto *maximum_can_equal{schema.try_at(\"maximumCanEqual\")};\n    ONLY_CONTINUE_IF(!(maximum_can_equal && maximum_can_equal->is_boolean() &&\n                       !maximum_can_equal->to_boolean()));\n    return APPLIES_TO_KEYWORDS(\"minimum\", \"maximum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    sourcemeta::core::JSON values = sourcemeta::core::JSON::make_array();\n    values.push_back(schema.at(\"minimum\"));\n    schema.assign(\"enum\", std::move(values));\n    schema.erase(\"type\");\n    schema.erase(\"minimum\");\n    schema.erase(\"maximum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/exclusive_bounds_false_drop.h",
    "content": "class ExclusiveBoundsFalseDrop final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveBoundsFalseDrop()\n      : SchemaTransformRule{\n            \"exclusive_bounds_false_drop\",\n            \"Setting `exclusiveMinimum` or `exclusiveMaximum` to `false` \"\n            \"adds no constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"integer\" || type->to_string() == \"number\"));\n\n    std::vector<Pointer> locations;\n    const auto *exclusive_min{schema.try_at(\"exclusiveMinimum\")};\n    if (exclusive_min && exclusive_min->is_boolean() &&\n        !exclusive_min->to_boolean()) {\n      locations.push_back(Pointer{\"exclusiveMinimum\"});\n    }\n    const auto *exclusive_max{schema.try_at(\"exclusiveMaximum\")};\n    if (exclusive_max && exclusive_max->is_boolean() &&\n        !exclusive_max->to_boolean()) {\n      locations.push_back(Pointer{\"exclusiveMaximum\"});\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      schema.erase(location.at(0).to_property());\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/exclusive_maximum_number_and_maximum.h",
    "content": "class ExclusiveMaximumNumberAndMaximum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMaximumNumberAndMaximum()\n      : SchemaTransformRule{\n            \"exclusive_maximum_number_and_maximum\",\n            \"Setting both `exclusiveMaximum` and `maximum` at the same time \"\n            \"is considered an anti-pattern. You should choose one\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object());\n\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number());\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    ONLY_CONTINUE_IF(exclusive_maximum && exclusive_maximum->is_number());\n    return APPLIES_TO_KEYWORDS(\"exclusiveMaximum\", \"maximum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"maximum\") < schema.at(\"exclusiveMaximum\")) {\n      schema.erase(\"exclusiveMaximum\");\n    } else {\n      schema.erase(\"maximum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/exclusive_minimum_number_and_minimum.h",
    "content": "class ExclusiveMinimumNumberAndMinimum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ExclusiveMinimumNumberAndMinimum()\n      : SchemaTransformRule{\n            \"exclusive_minimum_number_and_minimum\",\n            \"Setting both `exclusiveMinimum` and `minimum` at the same time \"\n            \"is considered an anti-pattern. You should choose one\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object());\n\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    ONLY_CONTINUE_IF(exclusive_minimum && exclusive_minimum->is_number());\n    return APPLIES_TO_KEYWORDS(\"exclusiveMinimum\", \"minimum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"exclusiveMinimum\") < schema.at(\"minimum\")) {\n      schema.erase(\"exclusiveMinimum\");\n    } else {\n      schema.erase(\"minimum\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/flatten_nested_allof.h",
    "content": "class FlattenNestedAllOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  FlattenNestedAllOf()\n      : SchemaTransformRule{\n            \"flatten_nested_allof\",\n            \"An `allOf` branch that only contains another `allOf` can \"\n            \"be flattened into the parent `allOf`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_array());\n\n    this->flatten_indices_.clear();\n    const auto &branches{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < branches.size(); ++index) {\n      const auto &branch{branches.at(index)};\n      if (branch.is_object() && branch.size() == 1 && branch.defines(KEYWORD) &&\n          branch.at(KEYWORD).is_array()) {\n        this->flatten_indices_.push_back(index);\n      }\n    }\n\n    ONLY_CONTINUE_IF(!this->flatten_indices_.empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    this->index_mapping_.clear();\n    const auto &original{schema.at(KEYWORD)};\n    auto result{JSON::make_array()};\n    std::size_t new_index{0};\n    std::size_t flatten_cursor{0};\n\n    for (std::size_t index = 0; index < original.size(); ++index) {\n      if (flatten_cursor < this->flatten_indices_.size() &&\n          this->flatten_indices_[flatten_cursor] == index) {\n        this->collect_leaves_(original.at(index), KEYWORD, index, result,\n                              new_index);\n        ++flatten_cursor;\n      } else {\n        this->index_mapping_.emplace_back(index, std::nullopt, new_index);\n        result.push_back(original.at(index));\n        ++new_index;\n      }\n    }\n\n    schema.assign(KEYWORD, std::move(result));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"allOf\"};\n    const auto prefix{current.concat({KEYWORD})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty() || !relative.at(0).is_index()) {\n      return target;\n    }\n    const auto old_index{relative.at(0).to_index()};\n    for (const auto &[outer, inner, mapped] : this->index_mapping_) {\n      if (outer == old_index && inner.has_value()) {\n        const Pointer old_prefix{\n            prefix.concat({old_index, KEYWORD, inner.value()})};\n        if (target.starts_with(old_prefix)) {\n          const Pointer new_prefix{prefix.concat({mapped})};\n          return target.rebase(old_prefix, new_prefix);\n        }\n      } else if (outer == old_index) {\n        const Pointer old_prefix{prefix.concat({old_index})};\n        const Pointer new_prefix{prefix.concat({mapped})};\n        return target.rebase(old_prefix, new_prefix);\n      }\n    }\n    return target;\n  }\n\nprivate:\n  auto collect_leaves_(const JSON &node, const JSON::String &keyword,\n                       std::size_t outer_index, JSON &result,\n                       std::size_t &new_index) const -> void {\n    const auto &inner{node.at(keyword)};\n    for (std::size_t inner_index = 0; inner_index < inner.size();\n         ++inner_index) {\n      const auto &child{inner.at(inner_index)};\n      if (child.is_object() && child.size() == 1 && child.defines(keyword) &&\n          child.at(keyword).is_array()) {\n        this->collect_leaves_(child, keyword, outer_index, result, new_index);\n      } else {\n        this->index_mapping_.emplace_back(outer_index, inner_index, new_index);\n        result.push_back(child);\n        ++new_index;\n      }\n    }\n  }\n\n  mutable std::vector<std::size_t> flatten_indices_;\n  mutable std::vector<\n      std::tuple<std::size_t, std::optional<std::size_t>, std::size_t>>\n      index_mapping_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/flatten_nested_anyof.h",
    "content": "class FlattenNestedAnyOf final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  FlattenNestedAnyOf()\n      : SchemaTransformRule{\n            \"flatten_nested_anyof\",\n            \"An `anyOf` branch that only contains another `anyOf` can \"\n            \"be flattened into the parent `anyOf`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_array());\n\n    this->flatten_indices_.clear();\n    const auto &branches{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < branches.size(); ++index) {\n      const auto &branch{branches.at(index)};\n      if (branch.is_object() && branch.size() == 1 && branch.defines(KEYWORD) &&\n          branch.at(KEYWORD).is_array()) {\n        this->flatten_indices_.push_back(index);\n      }\n    }\n\n    ONLY_CONTINUE_IF(!this->flatten_indices_.empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    this->index_mapping_.clear();\n    const auto &original{schema.at(KEYWORD)};\n    auto result{JSON::make_array()};\n    std::size_t new_index{0};\n    std::size_t flatten_cursor{0};\n\n    for (std::size_t index = 0; index < original.size(); ++index) {\n      if (flatten_cursor < this->flatten_indices_.size() &&\n          this->flatten_indices_[flatten_cursor] == index) {\n        this->collect_leaves_(original.at(index), KEYWORD, index, result,\n                              new_index);\n        ++flatten_cursor;\n      } else {\n        this->index_mapping_.emplace_back(index, std::nullopt, new_index);\n        result.push_back(original.at(index));\n        ++new_index;\n      }\n    }\n\n    schema.assign(KEYWORD, std::move(result));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"anyOf\"};\n    const auto prefix{current.concat({KEYWORD})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty() || !relative.at(0).is_index()) {\n      return target;\n    }\n    const auto old_index{relative.at(0).to_index()};\n    for (const auto &[outer, inner, mapped] : this->index_mapping_) {\n      if (outer == old_index && inner.has_value()) {\n        const Pointer old_prefix{\n            prefix.concat({old_index, KEYWORD, inner.value()})};\n        if (target.starts_with(old_prefix)) {\n          const Pointer new_prefix{prefix.concat({mapped})};\n          return target.rebase(old_prefix, new_prefix);\n        }\n      } else if (outer == old_index) {\n        const Pointer old_prefix{prefix.concat({old_index})};\n        const Pointer new_prefix{prefix.concat({mapped})};\n        return target.rebase(old_prefix, new_prefix);\n      }\n    }\n    return target;\n  }\n\nprivate:\n  auto collect_leaves_(const JSON &node, const JSON::String &keyword,\n                       std::size_t outer_index, JSON &result,\n                       std::size_t &new_index) const -> void {\n    const auto &inner{node.at(keyword)};\n    for (std::size_t inner_index = 0; inner_index < inner.size();\n         ++inner_index) {\n      const auto &child{inner.at(inner_index)};\n      if (child.is_object() && child.size() == 1 && child.defines(keyword) &&\n          child.at(keyword).is_array()) {\n        this->collect_leaves_(child, keyword, outer_index, result, new_index);\n      } else {\n        this->index_mapping_.emplace_back(outer_index, inner_index, new_index);\n        result.push_back(child);\n        ++new_index;\n      }\n    }\n  }\n\n  mutable std::vector<std::size_t> flatten_indices_;\n  mutable std::vector<\n      std::tuple<std::size_t, std::optional<std::size_t>, std::size_t>>\n      index_mapping_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/flatten_nested_extends.h",
    "content": "class FlattenNestedExtends final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  FlattenNestedExtends()\n      : SchemaTransformRule{\n            \"flatten_nested_extends\",\n            \"An `extends` branch that only contains another `extends` can \"\n            \"be flattened into the parent `extends`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"extends\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_array());\n\n    this->flatten_indices_.clear();\n    const auto &branches{schema.at(KEYWORD)};\n    for (std::size_t index = 0; index < branches.size(); ++index) {\n      const auto &branch{branches.at(index)};\n      if (branch.is_object() && branch.size() == 1 && branch.defines(KEYWORD) &&\n          branch.at(KEYWORD).is_array()) {\n        this->flatten_indices_.push_back(index);\n      }\n    }\n\n    ONLY_CONTINUE_IF(!this->flatten_indices_.empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    static const JSON::String KEYWORD{\"extends\"};\n    this->index_mapping_.clear();\n    const auto &original{schema.at(KEYWORD)};\n    auto result{JSON::make_array()};\n    std::size_t new_index{0};\n    std::size_t flatten_cursor{0};\n\n    for (std::size_t index = 0; index < original.size(); ++index) {\n      if (flatten_cursor < this->flatten_indices_.size() &&\n          this->flatten_indices_[flatten_cursor] == index) {\n        this->collect_leaves_(original.at(index), KEYWORD, index, result,\n                              new_index);\n        ++flatten_cursor;\n      } else {\n        this->index_mapping_.emplace_back(index, std::nullopt, new_index);\n        result.push_back(original.at(index));\n        ++new_index;\n      }\n    }\n\n    schema.assign(KEYWORD, std::move(result));\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    static const JSON::String KEYWORD{\"extends\"};\n    const auto prefix{current.concat({KEYWORD})};\n    if (!target.starts_with(prefix)) {\n      return target;\n    }\n    const auto relative{target.resolve_from(prefix)};\n    if (relative.empty() || !relative.at(0).is_index()) {\n      return target;\n    }\n    const auto old_index{relative.at(0).to_index()};\n    for (const auto &[outer, inner, mapped] : this->index_mapping_) {\n      if (outer == old_index && inner.has_value()) {\n        const Pointer old_prefix{\n            prefix.concat({old_index, KEYWORD, inner.value()})};\n        if (target.starts_with(old_prefix)) {\n          const Pointer new_prefix{prefix.concat({mapped})};\n          return target.rebase(old_prefix, new_prefix);\n        }\n      } else if (outer == old_index) {\n        const Pointer old_prefix{prefix.concat({old_index})};\n        const Pointer new_prefix{prefix.concat({mapped})};\n        return target.rebase(old_prefix, new_prefix);\n      }\n    }\n    return target;\n  }\n\nprivate:\n  auto collect_leaves_(const JSON &node, const JSON::String &keyword,\n                       std::size_t outer_index, JSON &result,\n                       std::size_t &new_index) const -> void {\n    const auto &inner{node.at(keyword)};\n    for (std::size_t inner_index = 0; inner_index < inner.size();\n         ++inner_index) {\n      const auto &child{inner.at(inner_index)};\n      if (child.is_object() && child.size() == 1 && child.defines(keyword) &&\n          child.at(keyword).is_array()) {\n        this->collect_leaves_(child, keyword, outer_index, result, new_index);\n      } else {\n        this->index_mapping_.emplace_back(outer_index, inner_index, new_index);\n        result.push_back(child);\n        ++new_index;\n      }\n    }\n  }\n\n  mutable std::vector<std::size_t> flatten_indices_;\n  mutable std::vector<\n      std::tuple<std::size_t, std::optional<std::size_t>, std::size_t>>\n      index_mapping_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/if_without_then_else.h",
    "content": "class IfWithoutThenElse final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"if\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IfWithoutThenElse()\n      : SchemaTransformRule{\n            \"if_without_then_else\",\n            \"The `if` keyword is meaningless \"\n            \"without the presence of the `then` or `else` keywords\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     !schema.defines(\"then\") && !schema.defines(\"else\"));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/ignored_metaschema.h",
    "content": "class IgnoredMetaschema final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  IgnoredMetaschema()\n      : SchemaTransformRule{\n            \"ignored_metaschema\",\n            \"A `$schema` declaration without a sibling identifier (or with a \"\n            \"sibling `$ref` in Draft 7 and older dialects), is ignored\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *schema_keyword{schema.try_at(\"$schema\")};\n    ONLY_CONTINUE_IF(schema_keyword && schema_keyword->is_string());\n    const auto dialect{sourcemeta::core::dialect(schema)};\n    ONLY_CONTINUE_IF(!dialect.empty());\n    ONLY_CONTINUE_IF(dialect != location.dialect);\n    return APPLIES_TO_KEYWORDS(\"$schema\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"$schema\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/max_contains_without_contains.h",
    "content": "class MaxContainsWithoutContains final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MaxContainsWithoutContains()\n      : SchemaTransformRule{\"max_contains_without_contains\",\n                            \"The `maxContains` keyword is meaningless \"\n                            \"without the presence of the `contains` keyword\"} {\n        };\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object() && schema.defines(\"maxContains\") &&\n        !schema.defines(\"contains\"));\n    return APPLIES_TO_KEYWORDS(\"maxContains\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"maxContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/maximum_real_for_integer.h",
    "content": "class MaximumRealForInteger final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  MaximumRealForInteger()\n      : SchemaTransformRule{\n            \"maximum_real_for_integer\",\n            \"If an instance is guaranteed to be an integer, setting a real \"\n            \"number upper bound is the same as a floor of that upper bound\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number() &&\n                     !maximum->is_integral());\n    return APPLIES_TO_KEYWORDS(\"maximum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"maximum\").is_decimal()) {\n      auto current{schema.at(\"maximum\").to_decimal()};\n      auto new_value{current.to_integral()};\n      if (new_value > current) {\n        new_value -= sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value.is_int64()) {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{new_value.to_int64()});\n      } else {\n        schema.assign(\"maximum\", sourcemeta::core::JSON{std::move(new_value)});\n      }\n    } else {\n      const auto current{schema.at(\"maximum\").to_real()};\n      const auto new_value{static_cast<std::int64_t>(std::floor(current))};\n      schema.assign(\"maximum\", sourcemeta::core::JSON{new_value});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/min_contains_without_contains.h",
    "content": "class MinContainsWithoutContains final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MinContainsWithoutContains()\n      : SchemaTransformRule{\"min_contains_without_contains\",\n                            \"The `minContains` keyword is meaningless \"\n                            \"without the presence of the `contains` keyword\"} {\n        };\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object() && schema.defines(\"minContains\") &&\n        !schema.defines(\"contains\"));\n    return APPLIES_TO_KEYWORDS(\"minContains\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"minContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/minimum_real_for_integer.h",
    "content": "class MinimumRealForInteger final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  MinimumRealForInteger()\n      : SchemaTransformRule{\n            \"minimum_real_for_integer\",\n            \"If an instance is guaranteed to be an integer, setting a real \"\n            \"number lower bound is the same as a ceil of that lower bound\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number() &&\n                     !minimum->is_integral());\n    return APPLIES_TO_KEYWORDS(\"minimum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    if (schema.at(\"minimum\").is_decimal()) {\n      const auto current{schema.at(\"minimum\").to_decimal()};\n      auto new_value{current.to_integral()};\n      if (new_value < current) {\n        new_value += sourcemeta::core::Decimal{1};\n      }\n\n      if (new_value.is_int64()) {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{new_value.to_int64()});\n      } else {\n        schema.assign(\"minimum\", sourcemeta::core::JSON{new_value});\n      }\n    } else {\n      const auto current{schema.at(\"minimum\").to_real()};\n      const auto new_value{static_cast<std::int64_t>(std::ceil(current))};\n      schema.assign(\"minimum\", sourcemeta::core::JSON{new_value});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/modern_official_dialect_with_empty_fragment.h",
    "content": "class ModernOfficialDialectWithEmptyFragment final\n    : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ModernOfficialDialectWithEmptyFragment()\n      : SchemaTransformRule{\n            \"modern_official_dialect_with_empty_fragment\",\n            \"The official dialect URI of 2019-09 and newer versions must \"\n            \"not contain the empty fragment\"} {};\n\n  [[nodiscard]] auto condition(const sourcemeta::core::JSON &schema,\n                               const sourcemeta::core::JSON &,\n                               const sourcemeta::core::Vocabularies &,\n                               const sourcemeta::core::SchemaFrame &,\n                               const sourcemeta::core::SchemaFrame::Location &,\n                               const sourcemeta::core::SchemaWalker &,\n                               const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *schema_keyword{schema.try_at(\"$schema\")};\n    ONLY_CONTINUE_IF(schema_keyword && schema_keyword->is_string());\n    const auto &dialect{schema_keyword->to_string()};\n    ONLY_CONTINUE_IF(\n        dialect == \"https://json-schema.org/draft/2019-09/schema#\" ||\n        dialect == \"https://json-schema.org/draft/2019-09/hyper-schema#\" ||\n        dialect == \"https://json-schema.org/draft/2020-12/schema#\" ||\n        dialect == \"https://json-schema.org/draft/2020-12/hyper-schema#\");\n    return APPLIES_TO_KEYWORDS(\"$schema\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    auto dialect{std::move(schema.at(\"$schema\")).to_string()};\n    dialect.pop_back();\n    schema.at(\"$schema\").into(sourcemeta::core::JSON{dialect});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/modern_official_dialect_with_http.h",
    "content": "class ModernOfficialDialectWithHttp final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ModernOfficialDialectWithHttp()\n      : SchemaTransformRule{\n            \"modern_official_dialect_with_http\",\n            \"The official dialect URI of 2019-09 and later must use \"\n            \"\\\"https://\\\" instead of \\\"http://\\\"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    using sourcemeta::core::SchemaBaseDialect;\n    ONLY_CONTINUE_IF(\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_2020_12 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_2020_12_Hyper ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_2019_09 ||\n        location.base_dialect == SchemaBaseDialect::JSON_Schema_2019_09_Hyper);\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *schema_keyword{schema.try_at(\"$schema\")};\n    ONLY_CONTINUE_IF(schema_keyword && schema_keyword->is_string());\n    const auto &dialect{schema_keyword->to_string()};\n    ONLY_CONTINUE_IF(dialect.starts_with(\"http://json-schema.org/\"));\n    ONLY_CONTINUE_IF(\n        dialect == \"http://json-schema.org/draft/2020-12/schema\" ||\n        dialect == \"http://json-schema.org/draft/2020-12/schema#\" ||\n        dialect == \"http://json-schema.org/draft/2020-12/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft/2020-12/hyper-schema#\" ||\n        dialect == \"http://json-schema.org/draft/2019-09/schema\" ||\n        dialect == \"http://json-schema.org/draft/2019-09/schema#\" ||\n        dialect == \"http://json-schema.org/draft/2019-09/hyper-schema\" ||\n        dialect == \"http://json-schema.org/draft/2019-09/hyper-schema#\");\n    return APPLIES_TO_KEYWORDS(\"$schema\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    const auto &old_dialect{schema.at(\"$schema\").to_string()};\n    std::string new_dialect{\"https://\"};\n    new_dialect += old_dialect.substr(7);\n    schema.at(\"$schema\").into(sourcemeta::core::JSON{new_dialect});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/non_applicable_additional_items.h",
    "content": "class NonApplicableAdditionalItems final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"additionalItems\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NonApplicableAdditionalItems()\n      : SchemaTransformRule{\n            \"non_applicable_additional_items\",\n            \"The `additionalItems` keyword is ignored when the \"\n            \"`items` keyword is either not present or set to a schema\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object() && schema.defines(KEYWORD));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n\n    const auto *items{schema.try_at(\"items\")};\n    if (items && is_schema(*items)) {\n      return APPLIES_TO_KEYWORDS(KEYWORD, \"items\");\n    } else if (!items) {\n      return APPLIES_TO_KEYWORDS(KEYWORD);\n    } else {\n      return false;\n    }\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/non_applicable_disallow_types.h",
    "content": "class NonApplicableDisallowTypes final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NonApplicableDisallowTypes()\n      : SchemaTransformRule{\n            \"non_applicable_disallow_types\",\n            \"`disallow` entries whose type cannot overlap with the parent \"\n            \"`type` can never match and can be dropped\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"disallow\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *disallow{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(disallow && disallow->is_array() && !disallow->empty());\n\n    const auto *parent_type_value{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(parent_type_value &&\n                     is_known_type_form(*parent_type_value));\n\n    const auto parent_types{parse_schema_type(*parent_type_value)};\n    ONLY_CONTINUE_IF(parent_types.any());\n\n    std::vector<Pointer> locations;\n    for (std::size_t index = 0; index < disallow->size(); ++index) {\n      const auto &entry{disallow->at(index)};\n      JSON::TypeSet entry_types;\n      if (entry.is_string() && entry.to_string() != \"any\") {\n        entry_types = parse_schema_type(entry);\n      } else if (entry.is_object()) {\n        const auto *entry_type{entry.try_at(\"type\")};\n        if (entry_type && is_known_type_form(*entry_type)) {\n          entry_types = parse_schema_type(*entry_type);\n        }\n      }\n\n      if (entry_types.any() && (parent_types & entry_types).none()) {\n        locations.push_back(Pointer{KEYWORD, index});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n\n    auto keyword_pointer{location.pointer};\n    keyword_pointer.push_back(std::cref(KEYWORD));\n    ONLY_CONTINUE_IF(!frame.has_references_through(keyword_pointer));\n\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    std::vector<std::size_t> dead_indices;\n    dead_indices.reserve(result.locations.size());\n    for (const auto &location : result.locations) {\n      assert(location.size() == 2);\n      dead_indices.push_back(location.at(1).to_index());\n    }\n\n    auto new_disallow{JSON::make_array()};\n    const auto &disallow{schema.at(\"disallow\")};\n    for (std::size_t index = 0; index < disallow.size(); ++index) {\n      if (std::ranges::find(dead_indices, index) == dead_indices.end()) {\n        new_disallow.push_back(disallow.at(index));\n      }\n    }\n\n    if (new_disallow.empty()) {\n      schema.erase(\"disallow\");\n    } else {\n      schema.assign(\"disallow\", std::move(new_disallow));\n    }\n  }\n\nprivate:\n  static auto is_known_type_form(const sourcemeta::core::JSON &type) -> bool {\n    if (type.is_string()) {\n      return type.to_string() != \"any\";\n    }\n    if (!type.is_array()) {\n      return false;\n    }\n    return std::ranges::all_of(type.as_array(), [](const auto &entry) {\n      return entry.is_string() && entry.to_string() != \"any\";\n    });\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/non_applicable_enum_validation_keywords.h",
    "content": "class NonApplicableEnumValidationKeywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NonApplicableEnumValidationKeywords()\n      : SchemaTransformRule{\n            \"non_applicable_enum_validation_keywords\",\n            \"Setting validation keywords that do not apply to any item in \"\n            \"`enum` is considered an anti-pattern\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_1_Hyper}) &&\n                     schema.is_object() && !schema.defines(\"type\"));\n\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array());\n\n    sourcemeta::core::JSON::TypeSet enum_types;\n    for (const auto &value : enum_value->as_array()) {\n      enum_types.set(std::to_underlying(value.type()));\n    }\n\n    ONLY_CONTINUE_IF(enum_types.any());\n\n    const bool is_draft3{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper})};\n\n    std::vector<Pointer> positions;\n    for (const auto &entry : schema.as_object()) {\n      const auto &metadata = walker(entry.first, vocabularies);\n\n      // If instances is empty (none set), the keyword applies to all types\n      if (metadata.instances.none()) {\n        continue;\n      }\n\n      if (is_draft3 && entry.first == \"required\" && entry.second.is_boolean()) {\n        continue;\n      }\n\n      // Check if there's any overlap between keyword's applicable types and\n      // enum types\n      if ((metadata.instances & enum_types).none()) {\n        positions.push_back(Pointer{entry.first});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!positions.empty());\n\n    return APPLIES_TO_POINTERS(std::move(positions));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      schema.erase(location.at(0).to_property());\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/non_applicable_type_specific_keywords.h",
    "content": "class NonApplicableTypeSpecificKeywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NonApplicableTypeSpecificKeywords()\n      : SchemaTransformRule{\"non_applicable_type_specific_keywords\",\n                            \"Avoid keywords that don't apply to the type or \"\n                            \"types that the current subschema expects\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    const auto *type_value{schema.try_at(\"type\")};\n    auto current_types{vocabularies.contains_any(\n                           {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                            Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                            Vocabularies::Known::JSON_Schema_Draft_7,\n                            Vocabularies::Known::JSON_Schema_Draft_6,\n                            Vocabularies::Known::JSON_Schema_Draft_4,\n                            Vocabularies::Known::JSON_Schema_Draft_3,\n                            Vocabularies::Known::JSON_Schema_Draft_2,\n                            Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n                            Vocabularies::Known::JSON_Schema_Draft_1,\n                            Vocabularies::Known::JSON_Schema_Draft_1_Hyper,\n                            Vocabularies::Known::JSON_Schema_Draft_0,\n                            Vocabularies::Known::JSON_Schema_Draft_0_Hyper}) &&\n                               type_value\n                           ? parse_schema_type(*type_value)\n                           : sourcemeta::core::JSON::TypeSet{}};\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_1})) {\n      const auto *enum_value{schema.try_at(\"enum\")};\n      if (enum_value && enum_value->is_array()) {\n        for (const auto &entry : enum_value->as_array()) {\n          current_types.set(std::to_underlying(entry.type()));\n        }\n      }\n    }\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_Draft_6})) {\n      const auto *const_value{schema.try_at(\"const\")};\n      if (const_value) {\n        current_types.set(std::to_underlying(const_value->type()));\n      }\n    }\n\n    // This means that the schema has no explicit type constraints,\n    // so we cannot remove anything from it.\n    ONLY_CONTINUE_IF(current_types.any());\n\n    std::vector<Pointer> positions;\n    for (const auto &entry : schema.as_object()) {\n      const auto &metadata{walker(entry.first, vocabularies)};\n\n      // The keyword applies to any type, so it cannot be removed\n      if (metadata.instances.none()) {\n        continue;\n      }\n\n      if (entry.first == \"required\" &&\n          vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_Draft_3,\n               Vocabularies::Known::JSON_Schema_Draft_3_Hyper})) {\n        continue;\n      }\n\n      if (entry.first == \"maxDecimal\" &&\n          vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_Draft_0,\n               Vocabularies::Known::JSON_Schema_Draft_0_Hyper,\n               Vocabularies::Known::JSON_Schema_Draft_1,\n               Vocabularies::Known::JSON_Schema_Draft_1_Hyper})) {\n        continue;\n      }\n\n      if (entry.first == \"optional\" &&\n          vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_Draft_0,\n               Vocabularies::Known::JSON_Schema_Draft_0_Hyper,\n               Vocabularies::Known::JSON_Schema_Draft_1,\n               Vocabularies::Known::JSON_Schema_Draft_1_Hyper,\n               Vocabularies::Known::JSON_Schema_Draft_2,\n               Vocabularies::Known::JSON_Schema_Draft_2_Hyper})) {\n        continue;\n      }\n\n      // If none of the types that the keyword applies to is a valid\n      // type for the current schema, then by definition we can remove it\n      if ((metadata.instances & current_types).none()) {\n        // Skip keywords that have references pointing to them\n        if (frame.has_references_through(\n                location.pointer, WeakPointer::Token{std::cref(entry.first)})) {\n          continue;\n        }\n\n        positions.push_back(Pointer{entry.first});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!positions.empty());\n    return APPLIES_TO_POINTERS(std::move(positions));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      schema.erase(location.at(0).to_property());\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/not_false.h",
    "content": "class NotFalse final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"not\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  NotFalse()\n      : SchemaTransformRule{\"not_false\",\n                            \"Setting the `not` keyword to `false` imposes no \"\n                            \"constraints. Negating `false` yields the \"\n                            \"always-true schema\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_boolean() &&\n                     !schema.at(KEYWORD).to_boolean());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/oneof_false_simplify.h",
    "content": "class OneOfFalseSimplify final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  OneOfFalseSimplify()\n      : SchemaTransformRule{\"oneof_false_simplify\",\n                            \"A `oneOf` of a single `false` branch is \"\n                            \"unsatisfiable\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"oneOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"not\"));\n\n    const auto *one_of{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(one_of && one_of->is_array() && one_of->size() == 1);\n\n    const auto &entry{one_of->front()};\n    ONLY_CONTINUE_IF(entry.is_boolean() && !entry.to_boolean());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_POINTERS({Pointer{KEYWORD, 0}});\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"oneOf\").into(JSON{true});\n    schema.rename(\"oneOf\", \"not\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/oneof_to_anyof_disjoint_types.h",
    "content": "class OneOfToAnyOfDisjointTypes final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  OneOfToAnyOfDisjointTypes()\n      : SchemaTransformRule{\n            \"oneof_to_anyof_disjoint_types\",\n            \"A `oneOf` where all branches have disjoint types can be safely \"\n            \"converted to `anyOf`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    static const JSON::String KEYWORD{\"oneOf\"};\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *oneof_value{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(oneof_value && oneof_value->is_array() &&\n                     oneof_value->size() > 1);\n\n    const auto has_validation_vocabulary{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1})};\n\n    const auto has_const_vocabulary{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6})};\n\n    std::vector<JSON::TypeSet> type_sets;\n    type_sets.reserve(oneof_value->size());\n\n    for (const auto &branch : oneof_value->as_array()) {\n      ONLY_CONTINUE_IF(branch.is_object());\n\n      const auto *type_value{branch.try_at(\"type\")};\n      const auto *const_value{has_const_vocabulary ? branch.try_at(\"const\")\n                                                   : nullptr};\n      const auto *enum_value{has_validation_vocabulary ? branch.try_at(\"enum\")\n                                                       : nullptr};\n      const auto has_enum{enum_value && enum_value->is_array()};\n\n      if (type_value) {\n        const auto branch_types{parse_schema_type(*type_value)};\n        ONLY_CONTINUE_IF(branch_types.any());\n        type_sets.push_back(branch_types);\n      } else if (const_value && !has_enum) {\n        JSON::TypeSet branch_types;\n        branch_types.set(std::to_underlying(const_value->type()));\n        type_sets.push_back(branch_types);\n      } else if (has_enum && !const_value) {\n        JSON::TypeSet branch_types;\n        for (const auto &item : enum_value->as_array()) {\n          branch_types.set(std::to_underlying(item.type()));\n        }\n        type_sets.push_back(branch_types);\n      } else {\n        return false;\n      }\n    }\n\n    for (std::size_t index = 0; index < type_sets.size(); ++index) {\n      for (std::size_t other = index + 1; other < type_sets.size(); ++other) {\n        ONLY_CONTINUE_IF((type_sets[index] & type_sets[other]).none());\n      }\n    }\n\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.rename(\"oneOf\", \"anyOf\");\n  }\n\n  [[nodiscard]] auto\n  rereference(const std::string_view, const Pointer &origin [[maybe_unused]],\n              const Pointer &target, const Pointer &current) const\n      -> Pointer override {\n    const Pointer oneof_prefix{current.concat({\"oneOf\"})};\n    const Pointer anyof_prefix{current.concat({\"anyOf\"})};\n    return target.rebase(oneof_prefix, anyof_prefix);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/orphan_definitions.h",
    "content": "class OrphanDefinitions final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  OrphanDefinitions()\n      : SchemaTransformRule{\n            \"orphan_definitions\",\n            \"Schema definitions in `$defs` or `definitions` that \"\n            \"are never internally referenced can be removed\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n    const bool has_modern_core{\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2020_12_Core) ||\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core)};\n    const bool has_draft_definitions{\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_7) ||\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_6) ||\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_4)};\n    const bool has_defs{has_modern_core && schema.defines(\"$defs\")};\n    const bool has_definitions{(has_modern_core || has_draft_definitions) &&\n                               schema.defines(\"definitions\")};\n    ONLY_CONTINUE_IF(has_defs || has_definitions);\n\n    const auto base{frame.traverse(frame.root())};\n    ONLY_CONTINUE_IF(base.has_value());\n\n    std::vector<Pointer> orphans;\n    collect_orphans(frame, base->get(), walker, resolver, location.pointer,\n                    schema, \"$defs\", has_defs, orphans);\n    collect_orphans(frame, base->get(), walker, resolver, location.pointer,\n                    schema, \"definitions\", has_definitions, orphans);\n\n    ONLY_CONTINUE_IF(!orphans.empty());\n    return APPLIES_TO_POINTERS(std::move(orphans));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &pointer : result.locations) {\n      assert(pointer.size() == 2);\n      assert(pointer.at(0).is_property());\n      assert(pointer.at(1).is_property());\n      const auto &container{pointer.at(0).to_property()};\n      schema.at(container).erase(pointer.at(1).to_property());\n    }\n\n    const auto *defs{schema.try_at(\"$defs\")};\n    if (defs && defs->empty()) {\n      schema.erase(\"$defs\");\n    }\n\n    const auto *definitions{schema.try_at(\"definitions\")};\n    if (definitions && definitions->empty()) {\n      schema.erase(\"definitions\");\n    }\n  }\n\nprivate:\n  static auto\n  subtree_has_dynamic_anchor(const sourcemeta::core::SchemaFrame &frame,\n                             const WeakPointer &entry_pointer) -> bool {\n    for (const auto &[key, location] : frame.locations()) {\n      if (key.first != sourcemeta::core::SchemaReferenceType::Dynamic) {\n        continue;\n      }\n      if (location.type !=\n          sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n        continue;\n      }\n      if (location.pointer.starts_with(entry_pointer)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  static auto has_reachable_reference_through(\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &base,\n      const sourcemeta::core::SchemaWalker &walker,\n      const sourcemeta::core::SchemaResolver &resolver,\n      const WeakPointer &pointer) -> bool {\n    for (const auto &reference : frame.references()) {\n      const auto destination{frame.traverse(reference.second.destination)};\n      if (!destination.has_value()) {\n        continue;\n      }\n\n      if (!destination->get().pointer.starts_with(pointer)) {\n        continue;\n      }\n\n      const auto &source_pointer{reference.first.second};\n      if (source_pointer.empty()) {\n        return true;\n      }\n\n      const auto source_location{frame.traverse(\n          source_pointer.initial(),\n          sourcemeta::core::SchemaFrame::LocationType::Subschema)};\n      if (source_location.has_value() &&\n          frame.is_reachable(base, source_location->get(), walker, resolver)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  static auto\n  collect_orphans(const sourcemeta::core::SchemaFrame &frame,\n                  const sourcemeta::core::SchemaFrame::Location &base,\n                  const sourcemeta::core::SchemaWalker &walker,\n                  const sourcemeta::core::SchemaResolver &resolver,\n                  const WeakPointer &prefix, const JSON &schema,\n                  const JSON::String &container, const bool has_container,\n                  std::vector<Pointer> &orphans) -> void {\n    if (!has_container || !schema.at(container).is_object()) {\n      return;\n    }\n\n    for (const auto &entry : schema.at(container).as_object()) {\n      const WeakPointer entry_pointer{std::cref(container),\n                                      std::cref(entry.first)};\n      const auto absolute_entry_pointer{prefix.concat(entry_pointer)};\n      const auto entry_location{frame.traverse(\n          absolute_entry_pointer,\n          sourcemeta::core::SchemaFrame::LocationType::Subschema)};\n      if (entry_location.has_value() &&\n          !frame.is_reachable(base, entry_location->get(), walker, resolver) &&\n          !has_reachable_reference_through(frame, base, walker, resolver,\n                                           absolute_entry_pointer) &&\n          !(!frame.standalone() &&\n            subtree_has_dynamic_anchor(frame, absolute_entry_pointer))) {\n        orphans.push_back(Pointer{container, entry.first});\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/required_properties_in_properties.h",
    "content": "class RequiredPropertiesInProperties final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  RequiredPropertiesInProperties()\n      : SchemaTransformRule{\n            \"required_properties_in_properties\",\n            \"Every property listed in the `required` keyword must be \"\n            \"explicitly defined using the `properties` keyword\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        ((vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Applicator)) ||\n         (vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Validation) &&\n          vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Applicator)) ||\n         vocabularies.contains_any(\n             {Vocabularies::Known::JSON_Schema_Draft_7,\n              Vocabularies::Known::JSON_Schema_Draft_6,\n              Vocabularies::Known::JSON_Schema_Draft_4})) &&\n        schema.is_object());\n\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(required && required->is_array() && !required->empty());\n\n    const auto *additional_properties{schema.try_at(\"additionalProperties\")};\n    ONLY_CONTINUE_IF(!additional_properties ||\n                     (additional_properties->is_boolean() &&\n                      additional_properties->to_boolean()));\n\n    std::vector<Pointer> locations;\n    std::size_t index{0};\n    for (const auto &property : required->as_array()) {\n      if (property.is_string() &&\n          !this->defined_in_properties_sibling(schema, property.to_string()) &&\n          !WALK_UP_IN_PLACE_APPLICATORS(\n               root, frame, location, walker, resolver,\n               [&](const JSON &ancestor, const Vocabularies &) {\n                 return this->defined_in_properties_sibling(\n                     ancestor, property.to_string());\n               })\n               .has_value()) {\n        locations.push_back(Pointer{\"required\", index});\n      }\n\n      index += 1;\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    schema.assign_if_missing(\"properties\",\n                             sourcemeta::core::JSON::make_object());\n    for (const auto &location : result.locations) {\n      const auto &property{\n          schema.at(\"required\").at(location.at(1).to_index()).to_string()};\n      schema.at(\"properties\").assign(property, sourcemeta::core::JSON{true});\n    }\n  }\n\nprivate:\n  [[nodiscard]] auto\n  defined_in_properties_sibling(const JSON &schema,\n                                const JSON::String &property) const -> bool {\n    assert(schema.is_object());\n    const auto *properties{schema.try_at(\"properties\")};\n    return properties && properties->is_object() &&\n           properties->defines(property);\n  };\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/single_type_array.h",
    "content": "class SingleTypeArray final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  SingleTypeArray()\n      : SchemaTransformRule{\"single_type_array\",\n                            \"Setting `type` to an array of a single type is \"\n                            \"the same as directly declaring such type\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_0}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_array() && type->size() == 1 &&\n                     type->front().is_string());\n    return APPLIES_TO_KEYWORDS(\"type\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto type{schema.at(\"type\").front()};\n    schema.at(\"type\").into(std::move(type));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/then_without_if.h",
    "content": "class ThenWithoutIf final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"then\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ThenWithoutIf()\n      : SchemaTransformRule{\"then_without_if\",\n                            \"The `then` keyword is meaningless \"\n                            \"without the presence of the `if` keyword\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     !schema.defines(\"if\"));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unknown_keywords_prefix.h",
    "content": "class UnknownKeywordsPrefix final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnknownKeywordsPrefix()\n      : SchemaTransformRule{\n            \"unknown_keywords_prefix\",\n            \"Future versions of JSON Schema will refuse to evaluate unknown \"\n            \"keywords or custom keywords from optional vocabularies that don't \"\n            \"have an x- prefix\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &, const SchemaFrame::Location &,\n            const SchemaWalker &walker, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object());\n    std::vector<Pointer> locations;\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first.starts_with(\"x-\")) {\n        continue;\n      }\n\n      const auto &metadata = walker(entry.first, vocabularies);\n      if (metadata.type == SchemaKeywordType::Unknown &&\n          // If there is any i.e. optional vocabulary we don't recognise, then\n          // this seemingly unknown keyword might belong to one of those, and\n          // thus it might not be safe to flag it\n          !vocabularies.has_unknown()) {\n        locations.push_back(Pointer{entry.first});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    this->renames_.clear();\n    for (const auto &location : result.locations) {\n      const auto &keyword{location.at(0).to_property()};\n      assert(schema.defines(keyword));\n      std::string prefixed_name = \"x-\" + keyword;\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword, prefixed_name);\n      schema.rename(keyword, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{target.rebase(current.concat(Pointer{old_name}),\n                                      current.concat(Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unknown_local_ref.h",
    "content": "class UnknownLocalRef final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"$ref\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnknownLocalRef()\n      : SchemaTransformRule{\n            \"unknown_local_ref\",\n            \"Local references that point to unknown locations are invalid and \"\n            \"will result in evaluation failures\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Core,\n         Vocabularies::Known::JSON_Schema_2019_09_Core,\n         // In JSON Schema Draft 7 and older, `$ref` overrides siblings.\n         // However, we do not need to worry about this case here, as if the\n         // `$ref` points to an unknown local location, the entire schema is\n         // invalid anyway. We just help at least making the schema valid\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper}));\n    ONLY_CONTINUE_IF(schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_string());\n\n    // Find the keyword location entry\n    auto keyword_pointer{location.pointer};\n    keyword_pointer.push_back(std::cref(KEYWORD));\n    const auto reference_entry{\n        frame.reference(SchemaReferenceType::Static, keyword_pointer)};\n    ONLY_CONTINUE_IF(reference_entry.has_value());\n\n    // If the keyword has no fragment, continue\n    const auto &reference_fragment{reference_entry->get().fragment};\n    ONLY_CONTINUE_IF(reference_fragment.has_value());\n\n    // Only continue if the reference target does not exist\n    ONLY_CONTINUE_IF(\n        !frame.traverse(reference_entry->get().destination).has_value());\n\n    // If there is a base beyond the fragment, the base must exist.\n    // Otherwise it is likely an external reference?\n    const auto &reference_base{reference_entry->get().base};\n    if (!reference_base.empty()) {\n      ONLY_CONTINUE_IF(frame.traverse(reference_base).has_value());\n    }\n\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unnecessary_allof_ref_wrapper_draft.h",
    "content": "class UnnecessaryAllOfRefWrapperDraft final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnnecessaryAllOfRefWrapperDraft()\n      : SchemaTransformRule{\"unnecessary_allof_ref_wrapper_draft\",\n                            \"Wrapping `$ref` in `allOf` is only necessary if \"\n                            \"there are other sibling keywords\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_7,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_4}));\n    ONLY_CONTINUE_IF(schema.is_object() && schema.size() == 1);\n    const auto *all_of{schema.try_at(\"allOf\")};\n    ONLY_CONTINUE_IF(all_of && all_of->is_array());\n\n    // In Draft 7 and older, `$ref` overrides sibling keywords, so we can only\n    // elevate it if it is the only keyword of the only branch, and the outer\n    // subschema only declares `allOf`\n    ONLY_CONTINUE_IF(all_of->size() == 1);\n    const auto &entry{all_of->at(0)};\n    ONLY_CONTINUE_IF(entry.is_object());\n    ONLY_CONTINUE_IF(entry.size() == 1 && entry.defines(\"$ref\"));\n\n    return APPLIES_TO_POINTERS({{\"allOf\", 0, \"$ref\"}});\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto value{schema.at(\"allOf\").at(0).at(\"$ref\")};\n    schema.at(\"allOf\").into(std::move(value));\n    schema.rename(\"allOf\", \"$ref\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unnecessary_extends_ref_wrapper.h",
    "content": "class UnnecessaryExtendsRefWrapper final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnnecessaryExtendsRefWrapper()\n      : SchemaTransformRule{\"unnecessary_extends_ref_wrapper\",\n                            \"Wrapping `$ref` in `extends` is only necessary if \"\n                            \"there are other sibling keywords\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper}));\n    ONLY_CONTINUE_IF(schema.is_object() && schema.size() == 1);\n    const auto *extends{schema.try_at(\"extends\")};\n    ONLY_CONTINUE_IF(extends);\n\n    // In Draft 3, `$ref` overrides sibling keywords, so we can only elevate\n    // it if it is the only keyword of the only branch, and the outer\n    // subschema only declares `extends`\n    if (extends->is_object()) {\n      ONLY_CONTINUE_IF(extends->size() == 1 && extends->defines(\"$ref\"));\n      return APPLIES_TO_POINTERS({{\"extends\", \"$ref\"}});\n    }\n\n    if (extends->is_array()) {\n      ONLY_CONTINUE_IF(extends->size() == 1);\n      const auto &branch{extends->at(0)};\n      ONLY_CONTINUE_IF(branch.is_object());\n      ONLY_CONTINUE_IF(branch.size() == 1 && branch.defines(\"$ref\"));\n      return APPLIES_TO_POINTERS({{\"extends\", 0, \"$ref\"}});\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    const auto &location{result.locations.at(0)};\n    if (location.size() == 3) {\n      auto value{schema.at(\"extends\").at(0).at(\"$ref\")};\n      schema.at(\"extends\").into(std::move(value));\n    } else {\n      auto value{schema.at(\"extends\").at(\"$ref\")};\n      schema.at(\"extends\").into(std::move(value));\n    }\n    schema.rename(\"extends\", \"$ref\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unsatisfiable_drop_validation.h",
    "content": "class UnsatisfiableDropValidation final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnsatisfiableDropValidation()\n      : SchemaTransformRule{\"unsatisfiable_drop_validation\",\n                            \"Do not place assertions or applicators next to an \"\n                            \"unsatisfiable negation\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const bool is_draft_3{vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper})};\n\n    std::string_view trigger_keyword;\n    if (is_draft_3) {\n      const auto *disallow_value{schema.try_at(\"disallow\")};\n      if (disallow_value && is_disallow_tautology(*disallow_value)) {\n        trigger_keyword = \"disallow\";\n      }\n    } else {\n      const auto *not_value{schema.try_at(\"not\")};\n      if (not_value && sourcemeta::core::is_empty_schema(*not_value)) {\n        trigger_keyword = \"not\";\n      }\n    }\n\n    ONLY_CONTINUE_IF(!trigger_keyword.empty());\n\n    std::vector<Pointer> positions;\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == trigger_keyword) {\n        continue;\n      }\n\n      const auto &metadata{walker(entry.first, vocabularies)};\n      if (!is_removable_keyword_type(metadata.type)) {\n        continue;\n      }\n\n      if (frame.has_references_through(\n              location.pointer, WeakPointer::Token{std::cref(entry.first)})) {\n        continue;\n      }\n\n      positions.push_back(Pointer{entry.first});\n    }\n\n    ONLY_CONTINUE_IF(!positions.empty());\n    return APPLIES_TO_POINTERS(std::move(positions));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      schema.erase(location.at(0).to_property());\n    }\n  }\n\nprivate:\n  static auto is_disallow_tautology(const sourcemeta::core::JSON &value)\n      -> bool {\n    if (value.is_string()) {\n      return value.to_string() == \"any\";\n    }\n    if (sourcemeta::core::is_empty_schema(value)) {\n      return true;\n    }\n    if (value.is_array()) {\n      return std::ranges::any_of(value.as_array(), [](const auto &entry) {\n        if (entry.is_string()) {\n          return entry.to_string() == \"any\";\n        }\n        return sourcemeta::core::is_empty_schema(entry);\n      });\n    }\n    return false;\n  }\n\n  static auto is_removable_keyword_type(const SchemaKeywordType type) -> bool {\n    switch (type) {\n      case SchemaKeywordType::Assertion:\n      case SchemaKeywordType::Reference:\n      case SchemaKeywordType::LocationMembers:\n      case SchemaKeywordType::ApplicatorMembersTraversePropertyStatic:\n      case SchemaKeywordType::ApplicatorMembersTraversePropertyRegex:\n      case SchemaKeywordType::ApplicatorValueTraverseSomeProperty:\n      case SchemaKeywordType::ApplicatorValueTraverseAnyPropertyKey:\n      case SchemaKeywordType::ApplicatorValueTraverseAnyItem:\n      case SchemaKeywordType::ApplicatorValueTraverseSomeItem:\n      case SchemaKeywordType::ApplicatorValueTraverseParent:\n      case SchemaKeywordType::ApplicatorElementsTraverseItem:\n      case SchemaKeywordType::ApplicatorValueOrElementsTraverseAnyItemOrItem:\n      case SchemaKeywordType::ApplicatorValueOrElementsInPlace:\n      case SchemaKeywordType::ApplicatorMembersInPlaceSome:\n      case SchemaKeywordType::ApplicatorElementsInPlace:\n      case SchemaKeywordType::ApplicatorElementsInPlaceSome:\n      case SchemaKeywordType::ApplicatorElementsInPlaceSomeNegate:\n      case SchemaKeywordType::ApplicatorValueInPlaceMaybe:\n      case SchemaKeywordType::ApplicatorValueInPlaceOther:\n      case SchemaKeywordType::ApplicatorValueInPlaceNegate:\n        return true;\n      default:\n        return false;\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/common/unsatisfiable_in_place_applicator_type.h",
    "content": "class UnsatisfiableInPlaceApplicatorType final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnsatisfiableInPlaceApplicatorType()\n      : SchemaTransformRule{\n            \"unsatisfiable_in_place_applicator_type\",\n            \"An in-place applicator branch that defines a `type` with no \"\n            \"overlap with the parent `type` can never be satisfied\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object() && schema.defines(\"type\"));\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1,\n         Vocabularies::Known::JSON_Schema_Draft_0}));\n    const auto parent_types{parse_schema_type(schema.at(\"type\"))};\n    ONLY_CONTINUE_IF(parent_types.any());\n\n    std::vector<Pointer> locations;\n\n    for (const auto &entry : schema.as_object()) {\n      const auto &keyword{entry.first};\n      const auto &keyword_type{walker(keyword, vocabularies).type};\n\n      if (keyword_type == SchemaKeywordType::ApplicatorElementsInPlace ||\n          keyword_type == SchemaKeywordType::ApplicatorElementsInPlaceSome) {\n        if (!entry.second.is_array()) {\n          continue;\n        }\n\n        const auto &branches{entry.second};\n        for (std::size_t index = 0; index < branches.size(); ++index) {\n          const auto &branch{branches.at(index)};\n          if (!branch.is_object()) {\n            continue;\n          }\n          const auto *branch_type{branch.try_at(\"type\")};\n          if (!branch_type) {\n            continue;\n          }\n\n          const auto branch_types{parse_schema_type(*branch_type)};\n          if (branch_types.any() && (parent_types & branch_types).none()) {\n            locations.push_back(Pointer{keyword, index});\n          }\n        }\n      } else if (keyword_type ==\n                     SchemaKeywordType::ApplicatorValueInPlaceMaybe ||\n                 keyword_type ==\n                     SchemaKeywordType::ApplicatorValueInPlaceNegate) {\n        if (!entry.second.is_object()) {\n          continue;\n        }\n        const auto *branch_type{entry.second.try_at(\"type\")};\n        if (!branch_type) {\n          continue;\n        }\n\n        const auto branch_types{parse_schema_type(*branch_type)};\n        if (branch_types.any() && (parent_types & branch_types).none()) {\n          locations.push_back(Pointer{keyword});\n        }\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      if (location.size() == 2) {\n        const auto &keyword{location.at(0).to_property()};\n        const auto index{location.at(1).to_index()};\n        schema.at(keyword).at(index).into(JSON{false});\n      } else {\n        assert(location.size() == 1);\n        const auto &keyword{location.at(0).to_property()};\n        schema.at(keyword).into(JSON{false});\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/include/sourcemeta/blaze/alterschema.h",
    "content": "#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_H_\n#define SOURCEMETA_BLAZE_ALTERSCHEMA_H_\n\n/// @defgroup alterschema AlterSchema\n/// @brief A growing collection of JSON Schema transformation rules.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/alterschema.h>\n/// ```\n\n#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT\n#include <sourcemeta/blaze/alterschema_export.h>\n#endif\n\n#include <sourcemeta/blaze/alterschema_error.h>\n#include <sourcemeta/blaze/alterschema_transformer.h>\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cstdint>     // std::uint8_t\n#include <optional>    // std::optional, std::nullopt\n#include <string_view> // std::string_view\n#include <type_traits> // std::false_type\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup alterschema\n/// The category of a built-in transformation rule\nenum class AlterSchemaMode : std::uint8_t {\n  /// Rules that simplify the given schema for both human readability and\n  /// performance\n  Linter,\n\n  /// Rules that surface implicit constraints and simplifies keywords that\n  /// are syntax sugar to other keywords, potentially decreasing human\n  /// readability in favor of explicitness\n  Canonicalizer,\n\n  /// Rules that upgrade a JSON Schema document up to JSON Schema Draft 4\n  UpgradeDraft4,\n\n  /// Rules that upgrade a JSON Schema document up to JSON Schema Draft 6\n  UpgradeDraft6,\n\n  /// Rules that upgrade a JSON Schema document up to JSON Schema Draft 7\n  UpgradeDraft7,\n\n  /// Rules that upgrade a JSON Schema document up to JSON Schema 2019-09\n  Upgrade201909,\n\n  /// Rules that upgrade a JSON Schema document up to JSON Schema 2020-12\n  Upgrade202012,\n};\n\n/// @ingroup alterschema\n/// Add a set of built-in schema transformation rules given a category. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <sourcemeta/blaze/alterschema.h>\n///\n/// sourcemeta::blaze::SchemaTransformer bundle;\n///\n/// sourcemeta::blaze::add(bundle,\n///   sourcemeta::blaze::AlterSchemaMode::Linter);\n///\n/// auto schema = sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"foo\": 1,\n///   \"items\": {\n///     \"type\": \"string\",\n///     \"foo\": 2\n///   }\n/// })JSON\");\n///\n/// bundle.apply(schema, sourcemeta::core::schema_walker,\n///              sourcemeta::core::schema_resolver);\n/// ```\nSOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT\nauto add(SchemaTransformer &bundle, const AlterSchemaMode mode) -> void;\n\n/// @ingroup alterschema\n///\n/// A linter rule driven by a JSON Schema. Every subschema in the document\n/// under inspection is validated as a JSON instance against the provided\n/// rule schema. When a subschema does not conform, the rule fires and\n/// reports the validation errors. The rule name is extracted from the\n/// `title` keyword of the rule schema, and the rule description from the\n/// `description` keyword. The title must consist only of lowercase ASCII\n/// letters, digits, underscores, or slashes.\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaRule final\n    : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  SchemaRule(const sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const Compiler &compiler,\n             const std::string_view default_dialect = \"\",\n             const std::optional<Tweaks> &tweaks = std::nullopt);\n  [[nodiscard]] auto condition(const sourcemeta::core::JSON &,\n                               const sourcemeta::core::JSON &,\n                               const sourcemeta::core::Vocabularies &,\n                               const sourcemeta::core::SchemaFrame &,\n                               const sourcemeta::core::SchemaFrame::Location &,\n                               const sourcemeta::core::SchemaWalker &,\n                               const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override;\n\nprivate:\n  Template template_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/include/sourcemeta/blaze/alterschema_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_ERROR_H_\n#define SOURCEMETA_BLAZE_ALTERSCHEMA_ERROR_H_\n\n#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT\n#include <sourcemeta/blaze/alterschema_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup alterschema\n/// An error that represents a missing schema rule name\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaRuleMissingNameError\n    : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The schema rule is missing a title\";\n  }\n};\n\n/// @ingroup alterschema\n/// An error that represents an invalid schema rule name. The name must\n/// consist only of lowercase ASCII letters, digits, underscores, or slashes.\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaRuleInvalidNameError\n    : public std::exception {\npublic:\n  SchemaRuleInvalidNameError(const std::string_view identifier,\n                             const char *message)\n      : identifier_{identifier}, message_{message} {}\n  SchemaRuleInvalidNameError(const std::string_view identifier,\n                             std::string message) = delete;\n  SchemaRuleInvalidNameError(const std::string_view identifier,\n                             std::string &&message) = delete;\n  SchemaRuleInvalidNameError(const std::string_view identifier,\n                             std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> const std::string & {\n    return this->identifier_;\n  }\n\nprivate:\n  std::string identifier_;\n  const char *message_;\n};\n\n/// @ingroup alterschema\n/// An error that represents a schema rule name that does not match\n/// the required pattern\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaRuleInvalidNamePatternError\n    : public std::exception {\npublic:\n  SchemaRuleInvalidNamePatternError(const std::string_view identifier,\n                                    const std::string_view regex)\n      : identifier_{identifier}, regex_{regex} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The schema rule name does not match the required pattern\";\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> const std::string & {\n    return this->identifier_;\n  }\n\n  [[nodiscard]] auto regex() const noexcept -> const std::string & {\n    return this->regex_;\n  }\n\nprivate:\n  std::string identifier_;\n  std::string regex_;\n};\n\n/// @ingroup alterschema\n/// An error that represents that a schema operation cannot continue\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaAbortError\n    : public std::exception {\npublic:\n  SchemaAbortError(const char *message) : message_{message} {}\n  SchemaAbortError(std::string message) = delete;\n  SchemaAbortError(std::string &&message) = delete;\n  SchemaAbortError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n/// @ingroup alterschema\n/// An error that represents a broken schema reference after transformation\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaBrokenReferenceError\n    : public std::exception {\npublic:\n  SchemaBrokenReferenceError(const std::string_view identifier,\n                             sourcemeta::core::Pointer schema_location,\n                             const char *message)\n      : identifier_{identifier}, schema_location_{std::move(schema_location)},\n        message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->schema_location_;\n  }\n\nprivate:\n  std::string identifier_;\n  sourcemeta::core::Pointer schema_location_;\n  const char *message_;\n};\n\n/// @ingroup alterschema\n/// An error that signifies that a transform rule was applied more than once\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaTransformRuleProcessedTwiceError\n    : public std::exception {\npublic:\n  SchemaTransformRuleProcessedTwiceError(const std::string_view name,\n                                         sourcemeta::core::Pointer location)\n      : name_{name}, location_{std::move(location)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Transformation rules must only be processed once\";\n  }\n\n  [[nodiscard]] auto name() const noexcept -> std::string_view {\n    return this->name_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->location_;\n  }\n\nprivate:\n  std::string name_;\n  sourcemeta::core::Pointer location_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/include/sourcemeta/blaze/alterschema_transformer.h",
    "content": "#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_TRANSFORMER_H_\n#define SOURCEMETA_BLAZE_ALTERSCHEMA_TRANSFORMER_H_\n\n#ifndef SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT\n#include <sourcemeta/blaze/alterschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cassert>     // assert\n#include <concepts>    // std::derived_from, std::same_as\n#include <cstdint>     // std::uint8_t\n#include <functional>  // std::function\n#include <iterator>    // std::make_move_iterator, std::begin, std::end\n#include <memory>      // std::make_unique, std::unique_ptr\n#include <optional>    // std::optional, std::nullopt\n#include <set>         // std::set\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <tuple>       // std::tuple\n#include <type_traits> // std::is_same_v, std::true_type\n#include <utility>     // std::move, std::forward\n#include <vector>      // std::vector\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup alterschema\n///\n/// A class that represents a transformation rule. Clients of this class\n/// are expected to subclass and implement their own condition and\n/// transformation methods.\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaTransformRule {\npublic:\n  SchemaTransformRule(const std::string_view name,\n                      const std::string_view message);\n\n  virtual ~SchemaTransformRule() = default;\n\n  SchemaTransformRule(const SchemaTransformRule &) = delete;\n  SchemaTransformRule(SchemaTransformRule &&) = delete;\n  auto operator=(const SchemaTransformRule &) -> SchemaTransformRule & = delete;\n  auto operator=(SchemaTransformRule &&) -> SchemaTransformRule & = delete;\n\n  /// Compare a rule against another rule\n  auto operator==(const SchemaTransformRule &other) const -> bool;\n\n  /// Fetch the name of a rule\n  [[nodiscard]] auto name() const noexcept -> std::string_view;\n\n  /// Fetch the message of a rule\n  [[nodiscard]] auto message() const noexcept -> std::string_view;\n\n  /// The result of evaluating a rule\n  struct Result {\n    Result(const bool applies_) : applies{applies_} {}\n    Result(const sourcemeta::core::Pointer &pointer)\n        : applies{true}, locations{pointer} {\n      assert(this->locations.size() == 1);\n    }\n\n    template <typename T>\n      requires std::same_as<typename T::value_type, sourcemeta::core::Pointer>\n    Result(T &&container) : applies{true} {\n      auto &&input = std::forward<T>(container);\n      if constexpr (requires { input.size(); }) {\n        locations.reserve(input.size());\n      }\n\n#if __cpp_lib_containers_ranges >= 202202L\n      locations.assign_range(input);\n#else\n      locations.assign(std::make_move_iterator(std::begin(input)),\n                       std::make_move_iterator(std::end(input)));\n#endif\n    }\n\n    Result(std::vector<sourcemeta::core::Pointer> &&locations_,\n           sourcemeta::core::JSON::String &&description_)\n        : applies{true}, locations{std::move(locations_)},\n          description{std::move(description_)} {}\n\n    bool applies;\n    std::vector<sourcemeta::core::Pointer> locations;\n    std::optional<sourcemeta::core::JSON::String> description;\n  };\n\n  /// Check if the rule applies to a schema\n  [[nodiscard]] auto\n  check(const sourcemeta::core::JSON &schema,\n        const sourcemeta::core::JSON &root,\n        const sourcemeta::core::Vocabularies &vocabularies,\n        const sourcemeta::core::SchemaWalker &walker,\n        const sourcemeta::core::SchemaResolver &resolver,\n        const sourcemeta::core::SchemaFrame &frame,\n        const sourcemeta::core::SchemaFrame::Location &location,\n        const sourcemeta::core::JSON::String &exclude_keyword) const -> Result;\n\n  /// A method to optionally fix any reference location that was affected by the\n  /// transformation\n  [[nodiscard]] virtual auto\n  rereference(const std::string_view reference,\n              const sourcemeta::core::Pointer &origin,\n              const sourcemeta::core::Pointer &target,\n              const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer;\n\n  /// The rule condition\n  [[nodiscard]] virtual auto condition(\n      const sourcemeta::core::JSON &schema, const sourcemeta::core::JSON &root,\n      const sourcemeta::core::Vocabularies &vocabularies,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &location,\n      const sourcemeta::core::SchemaWalker &walker,\n      const sourcemeta::core::SchemaResolver &resolver) const -> Result = 0;\n\n  /// The rule transformation. If this virtual method is not overriden,\n  /// then the rule is considered to not mutate the schema\n  virtual auto transform(sourcemeta::core::JSON &schema,\n                         const Result &result) const -> void;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  const std::string name_{};\n  const std::string message_{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n/// @ingroup alterschema\n///\n/// You can use this class to perform top-down transformations on subschemas\n/// given a set of rules. Every registered rule is applied to every subschema\n/// of the passed schema until no longer of them applies.\nclass SOURCEMETA_BLAZE_ALTERSCHEMA_EXPORT SchemaTransformer {\npublic:\n  SchemaTransformer() = default;\n\n#if !defined(DOXYGEN)\n  SchemaTransformer(const SchemaTransformer &) = delete;\n  auto operator=(const SchemaTransformer &) -> SchemaTransformer & = delete;\n  SchemaTransformer(SchemaTransformer &&) = default;\n  auto operator=(SchemaTransformer &&) -> SchemaTransformer & = default;\n#endif\n\n  /// Add a rule to the bundle. Rules are evaluated in the order they are added.\n  /// It is the caller's responsibility to not add duplicate rules.\n  template <std::derived_from<SchemaTransformRule> T, typename... Args>\n  auto add(Args &&...args) -> std::string_view {\n    static_assert(requires { typename T::mutates; });\n    static_assert(requires { typename T::reframe_after_transform; });\n    static_assert(\n        std::is_same_v<typename T::mutates, std::true_type> ||\n        std::is_same_v<typename T::reframe_after_transform, std::false_type>);\n    auto &entry{this->rules.emplace_back(\n        std::make_unique<T>(std::forward<Args>(args)...),\n        std::is_same_v<typename T::mutates, std::true_type>,\n        std::is_same_v<typename T::reframe_after_transform, std::true_type>)};\n    return std::get<0>(entry)->name();\n  }\n\n  /// Remove a rule from the bundle\n  auto remove(const std::string_view name) -> bool;\n\n  /// The callback that is called whenever the condition of a rule holds true\n  using Callback = std::function<void(\n      const sourcemeta::core::Pointer &, const std::string_view,\n      const std::string_view, const SchemaTransformRule::Result &, const bool)>;\n\n  /// Apply the bundle of rules to a schema\n  [[nodiscard]] auto\n  apply(sourcemeta::core::JSON &schema,\n        const sourcemeta::core::SchemaWalker &walker,\n        const sourcemeta::core::SchemaResolver &resolver,\n        const Callback &callback, std::string_view default_dialect = \"\",\n        std::string_view default_id = \"\",\n        const sourcemeta::core::JSON::String &exclude_keyword = \"\") const\n      -> std::pair<bool, std::uint8_t>;\n\n  /// Report back the rules from the bundle that need to be applied to a schema\n  [[nodiscard]] auto\n  check(const sourcemeta::core::JSON &schema,\n        const sourcemeta::core::SchemaWalker &walker,\n        const sourcemeta::core::SchemaResolver &resolver,\n        const Callback &callback, std::string_view default_dialect = \"\",\n        std::string_view default_id = \"\",\n        const sourcemeta::core::JSON::String &exclude_keyword = \"\") const\n      -> std::pair<bool, std::uint8_t>;\n\n  [[nodiscard]] auto begin() const -> auto { return this->rules.cbegin(); }\n  [[nodiscard]] auto end() const -> auto { return this->rules.cend(); }\n\nprivate:\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::vector<std::tuple<std::unique_ptr<SchemaTransformRule>, bool, bool>>\n      rules;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/comment_trim.h",
    "content": "class CommentTrim final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  CommentTrim()\n      : SchemaTransformRule{\n            \"comment_trim\",\n            \"Comments should not contain leading or trailing whitespace\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Core,\n         Vocabularies::Known::JSON_Schema_2019_09_Core,\n         Vocabularies::Known::JSON_Schema_Draft_7}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"$comment\"));\n    ONLY_CONTINUE_IF(schema.at(\"$comment\").is_string());\n    ONLY_CONTINUE_IF(!schema.at(\"$comment\").is_trimmed());\n    return APPLIES_TO_KEYWORDS(\"$comment\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"$comment\").trim();\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/const_not_in_enum.h",
    "content": "class ConstNotInEnum final : public SchemaTransformRule {\r\npublic:\r\n  using mutates = std::false_type;\r\n  using reframe_after_transform = std::false_type;\r\n  ConstNotInEnum()\r\n      : SchemaTransformRule{\r\n            \"const_not_in_enum\",\r\n            \"Do not set the `const` and `enum` keyword at the same time, \"\r\n            \"mainly when their values diverge\"} {};\r\n\r\n  [[nodiscard]] auto\r\n  condition(const sourcemeta::core::JSON &schema,\r\n            const sourcemeta::core::JSON &,\r\n            const sourcemeta::core::Vocabularies &vocabularies,\r\n            const sourcemeta::core::SchemaFrame &,\r\n            const sourcemeta::core::SchemaFrame::Location &,\r\n            const sourcemeta::core::SchemaWalker &,\r\n            const sourcemeta::core::SchemaResolver &) const\r\n      -> SchemaTransformRule::Result override {\r\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\r\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\r\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\r\n                          Vocabularies::Known::JSON_Schema_Draft_7,\r\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\r\n                     schema.is_object());\r\n\r\n    const auto *const_value{schema.try_at(\"const\")};\r\n    ONLY_CONTINUE_IF(const_value);\r\n    const auto *enum_value{schema.try_at(\"enum\")};\r\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\r\n                     !enum_value->contains(*const_value));\r\n    return APPLIES_TO_KEYWORDS(\"const\", \"enum\");\r\n  }\r\n};\r\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/content_schema_default.h",
    "content": "class ContentSchemaDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"contentSchema\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ContentSchemaDefault()\n      : SchemaTransformRule{\n            \"content_schema_default\",\n            \"Setting the `contentSchema` keyword to the true schema \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Content,\n             Vocabularies::Known::JSON_Schema_2019_09_Content}) &&\n        schema.is_object() && schema.defines(KEYWORD) &&\n        ((schema.at(KEYWORD).is_boolean() && schema.at(KEYWORD).to_boolean()) ||\n         (schema.at(KEYWORD).is_object() && schema.at(KEYWORD).empty())));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/definitions_to_defs.h",
    "content": "class DefinitionsToDefs final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DefinitionsToDefs()\n      : SchemaTransformRule{\"definitions_to_defs\",\n                            \"`definitions` was superseded by `$defs` in \"\n                            \"2019-09 and later versions\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Core,\n                          Vocabularies::Known::JSON_Schema_2019_09_Core}) &&\n                     schema.is_object() && schema.defines(\"definitions\") &&\n                     !schema.defines(\"$defs\"));\n    return APPLIES_TO_KEYWORDS(\"definitions\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.rename(\"definitions\", \"$defs\");\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    return target.rebase(current.concat({\"definitions\"}),\n                         current.concat({\"$defs\"}));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/dependencies_default.h",
    "content": "class DependenciesDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"dependencies\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependenciesDefault()\n      : SchemaTransformRule{\n            \"dependencies_default\",\n            \"Setting the `dependencies` keyword to an empty object \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_object() &&\n                     schema.at(KEYWORD).empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/dependent_required_default.h",
    "content": "class DependentRequiredDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DependentRequiredDefault()\n      : SchemaTransformRule{\n            \"dependent_required_default\",\n            \"Setting the `dependentRequired` keyword to an empty object \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object());\n\n    const auto *dependent_required{schema.try_at(\"dependentRequired\")};\n    ONLY_CONTINUE_IF(dependent_required && dependent_required->is_object() &&\n                     dependent_required->empty());\n    return APPLIES_TO_KEYWORDS(\"dependentRequired\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"dependentRequired\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/description_trailing_period.h",
    "content": "class DescriptionTrailingPeriod final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DescriptionTrailingPeriod()\n      : SchemaTransformRule{\n            \"description_trailing_period\",\n            \"Descriptions should not end with a period to give user interfaces \"\n            \"flexibility in presenting the text\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"description\"));\n    ONLY_CONTINUE_IF(schema.at(\"description\").is_string());\n    const auto &description{schema.at(\"description\").to_string()};\n    ONLY_CONTINUE_IF(!description.empty() && description.back() == '.');\n    return APPLIES_TO_KEYWORDS(\"description\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto &description{schema.at(\"description\")};\n    auto value{description.to_string()};\n    while (!value.empty() && value.back() == '.') {\n      value.pop_back();\n    }\n\n    description.into(JSON{value});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/description_trim.h",
    "content": "class DescriptionTrim final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DescriptionTrim()\n      : SchemaTransformRule{\n            \"description_trim\",\n            \"Descriptions should not contain leading or trailing whitespace\"} {\n        };\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"description\"));\n    ONLY_CONTINUE_IF(schema.at(\"description\").is_string());\n    ONLY_CONTINUE_IF(!schema.at(\"description\").is_trimmed());\n    return APPLIES_TO_KEYWORDS(\"description\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"description\").trim();\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/disallow_default.h",
    "content": "class DisallowDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DisallowDefault()\n      : SchemaTransformRule{\"disallow_default\",\n                            \"Setting the `disallow` keyword to the empty \"\n                            \"array does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *disallow{schema.try_at(\"disallow\")};\n    ONLY_CONTINUE_IF(disallow && disallow->is_array() && disallow->empty());\n    return APPLIES_TO_KEYWORDS(\"disallow\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"disallow\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/divisible_by_default.h",
    "content": "class DivisibleByDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  DivisibleByDefault()\n      : SchemaTransformRule{\n            \"divisible_by_default\",\n            \"Setting `divisibleBy` to 1 does not add any further constraint\"} {\n        };\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n\n    const auto *divisible_by{schema.try_at(\"divisibleBy\")};\n    ONLY_CONTINUE_IF(\n        divisible_by &&\n        ((divisible_by->is_integer() && divisible_by->to_integer() == 1) ||\n         (divisible_by->is_real() && divisible_by->to_real() == 1.0) ||\n         (divisible_by->is_decimal() &&\n          divisible_by->to_decimal() == sourcemeta::core::Decimal{1})));\n    return APPLIES_TO_KEYWORDS(\"divisibleBy\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"divisibleBy\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/duplicate_examples.h",
    "content": "class DuplicateExamples final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  DuplicateExamples()\n      : SchemaTransformRule{\n            \"duplicate_examples\",\n            \"Setting duplicate values in `examples` is redundant\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n                          Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object());\n\n    const auto *examples{schema.try_at(\"examples\")};\n    ONLY_CONTINUE_IF(examples && examples->is_array() && !examples->unique());\n    return APPLIES_TO_KEYWORDS(\"examples\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    std::unordered_set<JSON, HashJSON<JSON>> seen;\n    auto result = JSON::make_array();\n    for (const auto &element : schema.at(\"examples\").as_array()) {\n      if (!seen.contains(element)) {\n        seen.insert(element);\n        result.push_back(element);\n      }\n    }\n\n    schema.at(\"examples\").into(std::move(result));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/else_empty.h",
    "content": "class ElseEmpty final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"else\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ElseEmpty()\n      : SchemaTransformRule{\"else_empty\",\n                            \"Setting the `else` keyword to the empty schema \"\n                            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object());\n\n    const auto *else_value{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(else_value && is_schema(*else_value) &&\n                     is_empty_schema(*else_value));\n    const auto *if_value{schema.try_at(\"if\")};\n    ONLY_CONTINUE_IF(else_value->is_object() || !if_value ||\n                     !(if_value->is_boolean() && if_value->to_boolean()));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/enum_to_const.h",
    "content": "class EnumToConst final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EnumToConst()\n      : SchemaTransformRule{\n            \"enum_to_const\",\n            \"An `enum` of a single value can be expressed as `const`\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && !schema.defines(\"const\"));\n\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\n                     enum_value->size() == 1);\n    return APPLIES_TO_KEYWORDS(\"enum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto front{schema.at(\"enum\").front()};\n    schema.at(\"enum\").into(front);\n    schema.rename(\"enum\", \"const\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/equal_numeric_bounds_to_const.h",
    "content": "class EqualNumericBoundsToConst final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  EqualNumericBoundsToConst()\n      : SchemaTransformRule{\n            \"equal_numeric_bounds_to_const\",\n            \"Setting `minimum` and `maximum` to the same number only leaves \"\n            \"one possible value\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any({\n                         Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                         Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                         Vocabularies::Known::JSON_Schema_Draft_7,\n                         Vocabularies::Known::JSON_Schema_Draft_6,\n                     }) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && type->is_string() &&\n        (type->to_string() == \"integer\" || type->to_string() == \"number\"));\n    const auto *minimum{schema.try_at(\"minimum\")};\n    ONLY_CONTINUE_IF(minimum && minimum->is_number());\n    const auto *maximum{schema.try_at(\"maximum\")};\n    ONLY_CONTINUE_IF(maximum && maximum->is_number() && *minimum == *maximum);\n\n    const auto *exclusive_minimum{schema.try_at(\"exclusiveMinimum\")};\n    ONLY_CONTINUE_IF(!(exclusive_minimum && exclusive_minimum->is_number() &&\n                       *exclusive_minimum >= *minimum));\n    const auto *exclusive_maximum{schema.try_at(\"exclusiveMaximum\")};\n    ONLY_CONTINUE_IF(!(exclusive_maximum && exclusive_maximum->is_number() &&\n                       *exclusive_maximum <= *maximum));\n\n    return APPLIES_TO_KEYWORDS(\"minimum\", \"maximum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.rename(\"minimum\", \"const\");\n    schema.erase(\"type\");\n    schema.erase(\"maximum\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/forbid_empty_enum.h",
    "content": "class ForbidEmptyEnum final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ForbidEmptyEnum()\n      : SchemaTransformRule{\"forbid_empty_enum\",\n                            \"An empty `enum` validates nothing and is \"\n                            \"unsatisfiable\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object() && !schema.defines(\"not\"));\n\n    const auto *enum_value{schema.try_at(\"enum\")};\n    ONLY_CONTINUE_IF(enum_value && enum_value->is_array() &&\n                     enum_value->empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(location.pointer));\n    return APPLIES_TO_KEYWORDS(\"enum\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"enum\").into(JSON::make_object());\n    schema.rename(\"enum\", \"not\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/incoherent_min_max_contains.h",
    "content": "class IncoherentMinMaxContains final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  IncoherentMinMaxContains()\n      : SchemaTransformRule{\n            \"incoherent_min_max_contains\",\n            \"`minContains` greater than `maxContains` makes the schema \"\n            \"unsatisfiable\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object() && schema.defines(\"contains\"));\n\n    const auto *min_contains{schema.try_at(\"minContains\")};\n    ONLY_CONTINUE_IF(min_contains && min_contains->is_integer());\n    const auto *max_contains{schema.try_at(\"maxContains\")};\n    ONLY_CONTINUE_IF(max_contains && max_contains->is_integer() &&\n                     min_contains->to_integer() > max_contains->to_integer());\n    return APPLIES_TO_KEYWORDS(\"minContains\", \"maxContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/invalid_external_ref.h",
    "content": "class InvalidExternalRef final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  InvalidExternalRef()\n      : SchemaTransformRule{\n            \"invalid_external_ref\",\n            \"External references must point to schemas that can be \"\n            \"resolved\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &walker, const SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(!frame.standalone());\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Core,\n         Vocabularies::Known::JSON_Schema_2019_09_Core,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper}));\n    ONLY_CONTINUE_IF(schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_string());\n\n    auto keyword_pointer{location.pointer};\n    keyword_pointer.push_back(std::cref(KEYWORD));\n    const auto reference_entry{\n        frame.reference(SchemaReferenceType::Static, keyword_pointer)};\n    ONLY_CONTINUE_IF(reference_entry.has_value());\n\n    // If the destination exists in the frame, it is an internal reference\n    ONLY_CONTINUE_IF(\n        !frame.traverse(reference_entry->get().destination).has_value());\n\n    const auto &reference_base{reference_entry->get().base};\n\n    // Empty base with unresolvable destination is a local reference problem\n    ONLY_CONTINUE_IF(!reference_base.empty());\n\n    // Known official metaschemas are always resolvable\n    ONLY_CONTINUE_IF(!is_known_schema(reference_base));\n\n    // If the base exists in the frame, the reference is internal (e.g. an\n    // embedded $id). A bad fragment on an internal base is handled by the\n    // unknown_local_ref rule instead\n    ONLY_CONTINUE_IF(!frame.traverse(reference_base).has_value());\n\n    const auto &has_fragment{reference_entry->get().fragment.has_value()};\n    const JSON::String base_key{reference_base};\n\n    // Check the resolver cache to avoid redundant lookups\n    const auto cached{this->resolver_cache_.find(base_key)};\n    if (cached != this->resolver_cache_.end()) {\n      if (!cached->second.has_value()) {\n        return APPLIES_TO_KEYWORDS(KEYWORD);\n      }\n\n      if (has_fragment) {\n        return this->is_fragment_invalid(reference_entry->get(), cached->second,\n                                         base_key, walker, resolver, location)\n                   ? APPLIES_TO_KEYWORDS(KEYWORD)\n                   : false;\n      }\n\n      return false;\n    }\n\n    auto remote{resolver(reference_base)};\n    const auto &[entry,\n                 _]{this->resolver_cache_.emplace(base_key, std::move(remote))};\n    if (!entry->second.has_value()) {\n      return APPLIES_TO_KEYWORDS(KEYWORD);\n    }\n\n    if (has_fragment) {\n      return this->is_fragment_invalid(reference_entry->get(), entry->second,\n                                       base_key, walker, resolver, location)\n                 ? APPLIES_TO_KEYWORDS(KEYWORD)\n                 : false;\n    }\n\n    return false;\n  }\n\nprivate:\n  static inline const std::string KEYWORD{\"$ref\"};\n  mutable std::unordered_map<JSON::String, std::optional<JSON>> resolver_cache_;\n  mutable std::unordered_map<JSON::String, std::unique_ptr<SchemaFrame>>\n      frame_cache_;\n\n  [[nodiscard]] auto\n  is_fragment_invalid(const SchemaFrame::ReferencesEntry &reference_entry,\n                      const std::optional<JSON> &remote,\n                      const JSON::String &base_key, const SchemaWalker &walker,\n                      const SchemaResolver &resolver,\n                      const SchemaFrame::Location &location) const -> bool {\n    auto frame_iterator{this->frame_cache_.find(base_key)};\n    if (frame_iterator == this->frame_cache_.end()) {\n      auto remote_frame{\n          std::make_unique<SchemaFrame>(SchemaFrame::Mode::Locations)};\n      remote_frame->analyse(remote.value(), walker, resolver, location.dialect,\n                            base_key);\n      frame_iterator =\n          this->frame_cache_.emplace(base_key, std::move(remote_frame)).first;\n    }\n\n    return !frame_iterator->second->traverse(reference_entry.destination)\n                .has_value();\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/items_array_default.h",
    "content": "class ItemsArrayDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ItemsArrayDefault()\n      : SchemaTransformRule{\"items_array_default\",\n                            \"Setting the `items` keyword to the empty array \"\n                            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_1_Hyper}) &&\n                     schema.is_object());\n\n    const auto *items{schema.try_at(\"items\")};\n    ONLY_CONTINUE_IF(items && items->is_array() && items->empty());\n    return APPLIES_TO_KEYWORDS(\"items\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"items\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/items_schema_default.h",
    "content": "class ItemsSchemaDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"items\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ItemsSchemaDefault()\n      : SchemaTransformRule{\"items_schema_default\",\n                            \"Setting the `items` keyword to the true schema \"\n                            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n             Vocabularies::Known::JSON_Schema_Draft_7,\n             Vocabularies::Known::JSON_Schema_Draft_6,\n             Vocabularies::Known::JSON_Schema_Draft_4,\n             Vocabularies::Known::JSON_Schema_Draft_3,\n             Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n             Vocabularies::Known::JSON_Schema_Draft_2,\n             Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n             Vocabularies::Known::JSON_Schema_Draft_1,\n             Vocabularies::Known::JSON_Schema_Draft_1_Hyper}) &&\n        schema.is_object() && schema.defines(KEYWORD) &&\n        ((schema.at(KEYWORD).is_boolean() && schema.at(KEYWORD).to_boolean()) ||\n         (schema.at(KEYWORD).is_object() && schema.at(KEYWORD).empty())));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/multiple_of_default.h",
    "content": "class MultipleOfDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  MultipleOfDefault()\n      : SchemaTransformRule{\n            \"multiple_of_default\",\n            \"Setting `multipleOf` to 1 does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *type{schema.try_at(\"type\")};\n    ONLY_CONTINUE_IF(type && type->is_string() &&\n                     type->to_string() == \"integer\");\n\n    const auto *multiple_of{schema.try_at(\"multipleOf\")};\n    ONLY_CONTINUE_IF(\n        multiple_of &&\n        ((multiple_of->is_integer() && multiple_of->to_integer() == 1) ||\n         (multiple_of->is_real() && multiple_of->to_real() == 1.0) ||\n         (multiple_of->is_decimal() &&\n          multiple_of->to_decimal() == sourcemeta::core::Decimal{1})));\n    return APPLIES_TO_KEYWORDS(\"multipleOf\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"multipleOf\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/pattern_properties_default.h",
    "content": "class PatternPropertiesDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PatternPropertiesDefault()\n      : SchemaTransformRule{\n            \"pattern_properties_default\",\n            \"Setting the `patternProperties` keyword to the empty object \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper}) &&\n                     schema.is_object());\n\n    const auto *pattern_properties{schema.try_at(\"patternProperties\")};\n    ONLY_CONTINUE_IF(pattern_properties && pattern_properties->is_object() &&\n                     pattern_properties->empty());\n    return APPLIES_TO_KEYWORDS(\"patternProperties\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"patternProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/portable_anchor_names.h",
    "content": "class PortableAnchorNames final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  PortableAnchorNames()\n      : SchemaTransformRule{\n            \"portable_anchor_names\",\n            \"Keep anchors within the safe allowed character set across JSON \"\n            \"Schema dialects (`^[A-Za-z][A-Za-z0-9_.-]*$`)\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Core,\n         Vocabularies::Known::JSON_Schema_2019_09_Core,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4}));\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    std::vector<Pointer> offenders;\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Core,\n             Vocabularies::Known::JSON_Schema_2019_09_Core})) {\n      this->check_anchor_keyword(schema, ANCHOR, offenders);\n    }\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Core})) {\n      this->check_anchor_keyword(schema, DYNAMIC_ANCHOR, offenders);\n    }\n\n    if (vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_7,\n                                   Vocabularies::Known::JSON_Schema_Draft_6,\n                                   Vocabularies::Known::JSON_Schema_Draft_4})) {\n      const auto &id_keyword{\n          vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_4})\n              ? ID_DRAFT_4\n              : ID_MODERN};\n      this->check_id_fragment(schema, id_keyword, offenders);\n    }\n\n    ONLY_CONTINUE_IF(!offenders.empty());\n    return APPLIES_TO_POINTERS(std::move(offenders));\n  }\n\nprivate:\n  static inline const sourcemeta::core::JSON::String ANCHOR{\"$anchor\"};\n  static inline const sourcemeta::core::JSON::String DYNAMIC_ANCHOR{\n      \"$dynamicAnchor\"};\n  static inline const sourcemeta::core::JSON::String ID_MODERN{\"$id\"};\n  static inline const sourcemeta::core::JSON::String ID_DRAFT_4{\"id\"};\n  static inline const Regex SAFE_ANCHOR_PATTERN{\n      to_regex(\"^[A-Za-z][A-Za-z0-9_.-]*$\").value()};\n\n  static auto\n  check_anchor_keyword(const sourcemeta::core::JSON &schema,\n                       const sourcemeta::core::JSON::String &keyword,\n                       std::vector<Pointer> &offenders) -> void {\n    if (!schema.defines(keyword) || !schema.at(keyword).is_string()) {\n      return;\n    }\n\n    const auto &value{schema.at(keyword).to_string()};\n    if (value.empty()) {\n      return;\n    }\n\n    if (!matches(SAFE_ANCHOR_PATTERN, value)) {\n      offenders.push_back(Pointer{keyword});\n    }\n  }\n\n  static auto check_id_fragment(const sourcemeta::core::JSON &schema,\n                                const sourcemeta::core::JSON::String &keyword,\n                                std::vector<Pointer> &offenders) -> void {\n    if (!schema.defines(keyword) || !schema.at(keyword).is_string()) {\n      return;\n    }\n\n    const auto &value{schema.at(keyword).to_string()};\n    if (value.find('#') == sourcemeta::core::JSON::String::npos) {\n      return;\n    }\n\n    const sourcemeta::core::URI uri{value};\n    const auto fragment{uri.fragment()};\n    if (!fragment.has_value() || fragment.value().empty()) {\n      return;\n    }\n\n    if (!matches(SAFE_ANCHOR_PATTERN,\n                 sourcemeta::core::JSON::String{fragment.value()})) {\n      offenders.push_back(Pointer{keyword});\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/properties_default.h",
    "content": "class PropertiesDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PropertiesDefault()\n      : SchemaTransformRule{\n            \"properties_default\",\n            \"Setting the `properties` keyword to the empty object \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4,\n                          Vocabularies::Known::JSON_Schema_Draft_3,\n                          Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_2,\n                          Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n                          Vocabularies::Known::JSON_Schema_Draft_1,\n                          Vocabularies::Known::JSON_Schema_Draft_1_Hyper}) &&\n                     schema.is_object());\n\n    const auto *properties{schema.try_at(\"properties\")};\n    ONLY_CONTINUE_IF(properties && properties->is_object() &&\n                     properties->empty());\n    return APPLIES_TO_KEYWORDS(\"properties\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"properties\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/property_names_default.h",
    "content": "class PropertyNamesDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"propertyNames\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PropertyNamesDefault()\n      : SchemaTransformRule{\n            \"property_names_default\",\n            \"Setting the `propertyNames` keyword to the empty object \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object() && schema.defines(KEYWORD) &&\n                     schema.at(KEYWORD).is_object() &&\n                     schema.at(KEYWORD).empty());\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/property_names_type_default.h",
    "content": "class PropertyNamesTypeDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PropertyNamesTypeDefault()\n      : SchemaTransformRule{\n            \"property_names_type_default\",\n            \"Setting the `type` keyword to `string` inside \"\n            \"`propertyNames` does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6}) &&\n                     schema.is_object());\n\n    const auto *property_names{schema.try_at(\"propertyNames\")};\n    ONLY_CONTINUE_IF(property_names && property_names->is_object());\n    const auto *type{property_names->try_at(\"type\")};\n    ONLY_CONTINUE_IF(\n        type && ((type->is_string() && type->to_string() == \"string\") ||\n                 (type->is_array() &&\n                  std::all_of(type->as_array().begin(), type->as_array().end(),\n                              [](const auto &item) {\n                                return item.is_string() &&\n                                       item.to_string() == \"string\";\n                              }))));\n    return APPLIES_TO_POINTERS({{\"propertyNames\", \"type\"}});\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"propertyNames\").erase(\"type\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/simple_properties_identifiers.h",
    "content": "class SimplePropertiesIdentifiers final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  SimplePropertiesIdentifiers()\n      // Inspired by\n      // https://json-structure.github.io/core/draft-vasters-json-structure-core.html#section-3.6\n      : SchemaTransformRule{\n            \"simple_properties_identifiers\",\n            \"Set `properties` to identifier names that can be easily mapped to \"\n            \"programming languages (matching [A-Za-z_][A-Za-z0-9_]*)\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n         Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_2_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_1,\n         Vocabularies::Known::JSON_Schema_Draft_1_Hyper}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *properties{schema.try_at(\"properties\")};\n    ONLY_CONTINUE_IF(properties && properties->is_object() &&\n                     !properties->empty());\n\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Core,\n             Vocabularies::Known::JSON_Schema_2019_09_Core})) {\n      // Skip meta-schemas with `$vocabulary` (2019-09+)\n      // We check the current schema resource (not root) to handle bundled\n      // schemas\n      const auto base_location{frame.traverse(location.base)};\n      if (base_location.has_value()) {\n        const auto &resource{get(root, base_location->get().pointer)};\n        ONLY_CONTINUE_IF(!resource.is_object() ||\n                         !resource.defines(\"$vocabulary\"));\n      }\n    } else {\n      // Skip pre-vocabulary meta-schemas\n      JSON::String base_with_hash{location.base};\n      base_with_hash += '#';\n      ONLY_CONTINUE_IF(location.base != location.dialect &&\n                       base_with_hash != location.dialect);\n    }\n\n    std::vector<Pointer> offenders;\n    for (const auto &entry : properties->as_object()) {\n      static const Regex IDENTIFIER_PATTERN{\n          to_regex(\"^[A-Za-z_][A-Za-z0-9_]*$\").value()};\n      if (!matches(IDENTIFIER_PATTERN, entry.first)) {\n        offenders.push_back(Pointer{\"properties\", entry.first});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!offenders.empty());\n    return APPLIES_TO_POINTERS(std::move(offenders));\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/then_empty.h",
    "content": "class ThenEmpty final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"then\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ThenEmpty()\n      : SchemaTransformRule{\"then_empty\",\n                            \"Setting the `then` keyword to the empty schema \"\n                            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n                          Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n                          Vocabularies::Known::JSON_Schema_Draft_7}) &&\n                     schema.is_object());\n\n    const auto *then_value{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(then_value && is_schema(*then_value) &&\n                     is_empty_schema(*then_value));\n    const auto *if_value{schema.try_at(\"if\")};\n    ONLY_CONTINUE_IF(then_value->is_object() || !if_value ||\n                     !(if_value->is_boolean() && if_value->to_boolean()));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/title_description_equal.h",
    "content": "class TitleDescriptionEqual final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  TitleDescriptionEqual()\n      : SchemaTransformRule{\n            \"title_description_equal\",\n            \"The title and description metadata keywords should not be set to \"\n            \"the same value\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"title\") && schema.defines(\"description\"));\n    ONLY_CONTINUE_IF(schema.at(\"title\").is_string() &&\n                     schema.at(\"description\").is_string());\n    ONLY_CONTINUE_IF(schema.at(\"title\") == schema.at(\"description\"));\n    return APPLIES_TO_KEYWORDS(\"title\", \"description\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"description\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/title_trailing_period.h",
    "content": "class TitleTrailingPeriod final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  TitleTrailingPeriod()\n      : SchemaTransformRule{\n            \"title_trailing_period\",\n            \"Titles should not end with a period to give user interfaces \"\n            \"flexibility in presenting the text\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"title\"));\n    ONLY_CONTINUE_IF(schema.at(\"title\").is_string());\n    const auto &title{schema.at(\"title\").to_string()};\n    ONLY_CONTINUE_IF(!title.empty() && title.back() == '.');\n    return APPLIES_TO_KEYWORDS(\"title\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    auto &title{schema.at(\"title\")};\n    auto value{title.to_string()};\n    while (!value.empty() && value.back() == '.') {\n      value.pop_back();\n    }\n\n    title.into(JSON{value});\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/title_trim.h",
    "content": "class TitleTrim final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::false_type;\n  TitleTrim()\n      : SchemaTransformRule{\n            \"title_trim\",\n            \"Titles should not contain leading or trailing whitespace\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    ONLY_CONTINUE_IF(schema.defines(\"title\"));\n    ONLY_CONTINUE_IF(schema.at(\"title\").is_string());\n    ONLY_CONTINUE_IF(!schema.at(\"title\").is_trimmed());\n    return APPLIES_TO_KEYWORDS(\"title\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.at(\"title\").trim();\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/top_level_description.h",
    "content": "class TopLevelDescription final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  TopLevelDescription()\n      : SchemaTransformRule{\n            \"top_level_description\",\n            \"Set a non-empty description at the top level of the \"\n            \"schema to explain what the definition is about in detail\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(location.pointer.empty());\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *description{schema.try_at(\"description\")};\n    if (description && description->is_string() && description->empty()) {\n      return APPLIES_TO_KEYWORDS(\"description\");\n    } else {\n      return !description;\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/top_level_examples.h",
    "content": "class TopLevelExamples final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  TopLevelExamples()\n      : SchemaTransformRule{\n            \"top_level_examples\",\n            \"Set a non-empty examples array at the top level of the schema to \"\n            \"illustrate the expected data\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(location.pointer.empty());\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *examples{schema.try_at(\"examples\")};\n    if (examples && examples->is_array() && examples->empty()) {\n      return APPLIES_TO_KEYWORDS(\"examples\");\n    } else {\n      return !examples;\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/top_level_title.h",
    "content": "class TopLevelTitle final : public SchemaTransformRule {\npublic:\n  using mutates = std::false_type;\n  using reframe_after_transform = std::false_type;\n  TopLevelTitle()\n      : SchemaTransformRule{\n            \"top_level_title\",\n            \"Set a concise non-empty title at the top level of the \"\n            \"schema to explain what the definition is about\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(location.pointer.empty());\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n         Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4,\n         Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper,\n         Vocabularies::Known::JSON_Schema_Draft_2,\n         Vocabularies::Known::JSON_Schema_Draft_1}));\n    ONLY_CONTINUE_IF(schema.is_object());\n    const auto *title{schema.try_at(\"title\")};\n    if (title && title->is_string() && title->empty()) {\n      return APPLIES_TO_KEYWORDS(\"title\");\n    } else {\n      return !title;\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unevaluated_items_default.h",
    "content": "class UnevaluatedItemsDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"unevaluatedItems\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnevaluatedItemsDefault()\n      : SchemaTransformRule{\n            \"unevaluated_items_default\",\n            \"Setting the `unevaluatedItems` keyword to the true schema \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        schema.is_object() && schema.defines(KEYWORD) &&\n        ((schema.at(KEYWORD).is_boolean() && schema.at(KEYWORD).to_boolean()) ||\n         (schema.at(KEYWORD).is_object() && schema.at(KEYWORD).empty())));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unevaluated_properties_default.h",
    "content": "class UnevaluatedPropertiesDefault final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"unevaluatedProperties\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnevaluatedPropertiesDefault()\n      : SchemaTransformRule{\n            \"unevaluated_properties_default\",\n            \"Setting the `unevaluatedProperties` keyword to the true schema \"\n            \"does not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n             Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n        schema.is_object() && schema.defines(KEYWORD) &&\n        ((schema.at(KEYWORD).is_boolean() && schema.at(KEYWORD).to_boolean()) ||\n         (schema.at(KEYWORD).is_object() && schema.at(KEYWORD).empty())));\n    ONLY_CONTINUE_IF(!frame.has_references_through(\n        location.pointer, WeakPointer::Token{std::cref(KEYWORD)}));\n    return APPLIES_TO_KEYWORDS(KEYWORD);\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(KEYWORD);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unknown_format_prefix.h",
    "content": "class UnknownFormatPrefix final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnknownFormatPrefix()\n      : SchemaTransformRule{\n            \"unknown_format_prefix\",\n            \"For interoperability purposes, the JSON Schema specification \"\n            \"advises against the use of \"\n            \"`format` values that are not explicitly defined by the \"\n            \"specification\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(schema.is_object() && schema.defines(\"format\"));\n    const auto &format_value{schema.at(\"format\")};\n    ONLY_CONTINUE_IF(format_value.is_string());\n\n    const auto *recognized{recognized_formats_for(vocabularies)};\n    if (recognized == nullptr) {\n      return false;\n    }\n\n    if (recognized->contains(format_value.to_string())) {\n      return false;\n    }\n\n    return APPLIES_TO_KEYWORDS(\"format\");\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    std::string prefixed_name{\"x-format\"};\n    while (schema.defines(prefixed_name)) {\n      prefixed_name.insert(0, \"x-\");\n    }\n    schema.rename(\"format\", std::move(prefixed_name));\n  }\n\nprivate:\n  static auto\n  recognized_formats_for(const sourcemeta::core::Vocabularies &vocabularies)\n      -> const std::unordered_set<std::string_view> * {\n    using Known = sourcemeta::core::Vocabularies::Known;\n    if (vocabularies.contains_any(\n            {Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper})) {\n      return &DRAFT_3_FORMATS;\n    }\n    if (vocabularies.contains_any(\n            {Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper})) {\n      return &DRAFT_4_FORMATS;\n    }\n    if (vocabularies.contains_any(\n            {Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper})) {\n      return &DRAFT_6_FORMATS;\n    }\n    if (vocabularies.contains_any(\n            {Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper})) {\n      return &DRAFT_7_FORMATS;\n    }\n    if (vocabularies.contains(Known::JSON_Schema_2019_09_Format)) {\n      return &DRAFT_2019_09_FORMATS;\n    }\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Format_Annotation) ||\n        vocabularies.contains(Known::JSON_Schema_2020_12_Format_Assertion)) {\n      return &DRAFT_2020_12_FORMATS;\n    }\n    return nullptr;\n  }\n\n  static inline const std::unordered_set<std::string_view> DRAFT_3_FORMATS{\n      \"date-time\",  \"date\",  \"time\",     \"utc-millisec\", \"regex\",\n      \"color\",      \"style\", \"phone\",    \"uri\",          \"email\",\n      \"ip-address\", \"ipv6\",  \"host-name\"};\n  static inline const std::unordered_set<std::string_view> DRAFT_4_FORMATS{\n      \"date-time\", \"email\", \"hostname\", \"ipv4\", \"ipv6\", \"uri\"};\n  static inline const std::unordered_set<std::string_view> DRAFT_6_FORMATS{\n      \"date-time\", \"email\",         \"hostname\",     \"ipv4\",        \"ipv6\",\n      \"uri\",       \"uri-reference\", \"uri-template\", \"json-pointer\"};\n  static inline const std::unordered_set<std::string_view> DRAFT_7_FORMATS{\n      \"date-time\",     \"date\",         \"time\",          \"email\",\n      \"idn-email\",     \"hostname\",     \"idn-hostname\",  \"ipv4\",\n      \"ipv6\",          \"uri\",          \"uri-reference\", \"iri\",\n      \"iri-reference\", \"uri-template\", \"json-pointer\",  \"relative-json-pointer\",\n      \"regex\"};\n  static inline const std::unordered_set<std::string_view>\n      DRAFT_2019_09_FORMATS{\n          \"date-time\",    \"date\",          \"time\",\n          \"duration\",     \"email\",         \"idn-email\",\n          \"hostname\",     \"idn-hostname\",  \"ipv4\",\n          \"ipv6\",         \"uri\",           \"uri-reference\",\n          \"iri\",          \"iri-reference\", \"uuid\",\n          \"uri-template\", \"json-pointer\",  \"relative-json-pointer\",\n          \"regex\"};\n  static inline const std::unordered_set<std::string_view>\n      DRAFT_2020_12_FORMATS{\n          \"date-time\",    \"date\",          \"time\",\n          \"duration\",     \"email\",         \"idn-email\",\n          \"hostname\",     \"idn-hostname\",  \"ipv4\",\n          \"ipv6\",         \"uri\",           \"uri-reference\",\n          \"iri\",          \"iri-reference\", \"uuid\",\n          \"uri-template\", \"json-pointer\",  \"relative-json-pointer\",\n          \"regex\"};\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unnecessary_allof_ref_wrapper_modern.h",
    "content": "class UnnecessaryAllOfRefWrapperModern final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnnecessaryAllOfRefWrapperModern()\n      : SchemaTransformRule{\"unnecessary_allof_ref_wrapper_modern\",\n                            \"Wrapping `$ref` in `allOf` was only necessary in \"\n                            \"JSON Schema Draft 7 and older\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n         Vocabularies::Known::JSON_Schema_2019_09_Applicator}));\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    const auto *all_of_value{schema.try_at(\"allOf\")};\n    ONLY_CONTINUE_IF(all_of_value && all_of_value->is_array());\n\n    const auto &all_of{*all_of_value};\n\n    // Don't do anything if there is more than one branch and ALL branches\n    // define `$ref` (a common multiple composition pattern)\n    ONLY_CONTINUE_IF(\n        !(all_of.size() > 1 &&\n          std::ranges::all_of(all_of.as_array(), [](const auto &entry) {\n            return entry.is_object() && entry.defines(\"$ref\");\n          })));\n\n    std::vector<Pointer> locations;\n    for (std::size_t index = 0; index < all_of.size(); index++) {\n      const auto &entry{all_of.at(index)};\n      if (entry.is_object() && entry.defines(\"$ref\") &&\n          // We cannot safely elevate a reference on a subschema with its own\n          // base URI\n          // TODO: In theory we can if the URI is absolute\n          !entry.defines(\"$id\") && !schema.defines(\"$ref\")) {\n        locations.push_back(Pointer{\"allOf\", index, \"$ref\"});\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      assert(location.size() == 3);\n      const auto allof_index{location.at(1).to_index()};\n      const auto &keyword{location.at(2).to_property()};\n\n      if (!schema.defines(keyword)) {\n        schema.try_assign_before(\n            keyword, schema.at(\"allOf\").at(allof_index).at(keyword), \"allOf\");\n        schema.at(\"allOf\").at(allof_index).erase(keyword);\n      }\n    }\n\n    schema.at(\"allOf\").erase_if(sourcemeta::core::is_empty_schema);\n\n    if (schema.at(\"allOf\").empty()) {\n      schema.erase(\"allOf\");\n    }\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unnecessary_allof_wrapper.h",
    "content": "class UnnecessaryAllOfWrapper final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"allOf\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnnecessaryAllOfWrapper()\n      : SchemaTransformRule{\"unnecessary_allof_wrapper\",\n                            \"Keywords inside `allOf` that do not conflict with \"\n                            \"the parent schema can be elevated\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &walker, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n         Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n         Vocabularies::Known::JSON_Schema_Draft_7,\n         Vocabularies::Known::JSON_Schema_Draft_6,\n         Vocabularies::Known::JSON_Schema_Draft_4}));\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    const auto *all_of_value{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(all_of_value && all_of_value->is_array() &&\n                     !all_of_value->empty());\n\n    std::unordered_map<std::string_view, std::size_t> keyword_frequency;\n    for (const auto &entry : all_of_value->as_array()) {\n      if (!entry.is_object()) {\n        continue;\n      }\n      for (const auto &property : entry.as_object()) {\n        const auto &metadata{walker(property.first, vocabularies)};\n        if (metadata.type == SchemaKeywordType::Annotation ||\n            metadata.type == SchemaKeywordType::Comment) {\n          continue;\n        }\n        keyword_frequency[property.first]++;\n      }\n    }\n\n    std::unordered_set<std::string_view> dependency_blocked;\n    for (const auto &entry : schema.as_object()) {\n      if ((entry.first == \"unevaluatedProperties\" ||\n           entry.first == \"unevaluatedItems\") &&\n          vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n               Vocabularies::Known::JSON_Schema_2019_09_Applicator})) {\n        continue;\n      }\n\n      for (const auto &dependency :\n           walker(entry.first, vocabularies).dependencies) {\n        dependency_blocked.emplace(dependency);\n      }\n    }\n\n    const auto *parent_type_value{schema.try_at(\"type\")};\n    const JSON::TypeSet parent_types{\n        parent_type_value &&\n                vocabularies.contains_any(\n                    {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                     Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                     Vocabularies::Known::JSON_Schema_Draft_7,\n                     Vocabularies::Known::JSON_Schema_Draft_6,\n                     Vocabularies::Known::JSON_Schema_Draft_4})\n            ? parse_schema_type(*parent_type_value)\n            : JSON::TypeSet{}};\n\n    const auto &all_of{*all_of_value};\n    std::vector<Pointer> locations;\n    std::unordered_set<std::string_view> elevated;\n\n    for (auto index = all_of.size(); index > 0; index--) {\n      const auto &entry{all_of.at(index - 1)};\n      if (!entry.is_object() || entry.empty() ||\n          // We separately handle this case, as it has many other subtleties\n          entry.defines(\"$ref\")) {\n        continue;\n      }\n\n      // Skip entries that have direct references pointing to them\n      auto entry_pointer{location.pointer};\n      entry_pointer.push_back(std::cref(KEYWORD));\n      entry_pointer.push_back(index - 1);\n      if (frame.has_references_to(entry_pointer)) {\n        continue;\n      }\n\n      // Skip entries that define their own identity, as elevating keywords\n      // from them could break references that target those anchors\n      if (!this->is_anonymous(entry, vocabularies)) {\n        continue;\n      }\n\n      if (vocabularies.contains_any(\n              {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n               Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n          (entry.defines(\"unevaluatedProperties\") ||\n           entry.defines(\"unevaluatedItems\"))) {\n        continue;\n      }\n\n      const auto try_elevate_keyword = [&](const auto &keyword_entry) -> bool {\n        const auto &keyword{keyword_entry.first};\n        const auto &metadata{walker(keyword, vocabularies)};\n\n        if (elevated.contains(keyword) ||\n            (schema.defines(keyword) &&\n             schema.at(keyword) != keyword_entry.second)) {\n          return false;\n        }\n\n        if (dependency_blocked.contains(keyword)) {\n          return false;\n        }\n\n        if (keyword_frequency[keyword] > 1) {\n          return false;\n        }\n\n        if (metadata.instances.any() && parent_types.any() &&\n            (metadata.instances & parent_types).none()) {\n          return false;\n        }\n\n        if (std::ranges::any_of(metadata.dependencies,\n                                [&](const auto &dependency) {\n                                  return !entry.defines(dependency) &&\n                                         (schema.defines(dependency) ||\n                                          elevated.contains(dependency));\n                                })) {\n          return false;\n        }\n\n        locations.push_back(Pointer{KEYWORD, index - 1, keyword});\n        elevated.emplace(keyword);\n\n        if (!(vocabularies.contains_any(\n                  {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n                   Vocabularies::Known::JSON_Schema_2019_09_Applicator}) &&\n              (keyword == \"unevaluatedProperties\" ||\n               keyword == \"unevaluatedItems\"))) {\n          for (const auto &dependency : metadata.dependencies) {\n            if (!entry.defines(dependency)) {\n              dependency_blocked.emplace(dependency);\n            }\n          }\n        }\n\n        return true;\n      };\n\n      bool entry_has_non_annotation = false;\n      bool non_annotation_elevated = false;\n      for (const auto &keyword_entry : entry.as_object()) {\n        const auto &metadata{walker(keyword_entry.first, vocabularies)};\n        if (metadata.type == SchemaKeywordType::Annotation ||\n            metadata.type == SchemaKeywordType::Comment) {\n          continue;\n        }\n        entry_has_non_annotation = true;\n        if (try_elevate_keyword(keyword_entry)) {\n          non_annotation_elevated = true;\n        }\n      }\n\n      if (!entry_has_non_annotation || non_annotation_elevated) {\n        for (const auto &keyword_entry : entry.as_object()) {\n          const auto &metadata{walker(keyword_entry.first, vocabularies)};\n          if (metadata.type != SchemaKeywordType::Annotation &&\n              metadata.type != SchemaKeywordType::Comment) {\n            continue;\n          }\n          try_elevate_keyword(keyword_entry);\n        }\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      assert(location.size() == 3);\n      const auto allof_index{location.at(1).to_index()};\n      const auto &keyword{location.at(2).to_property()};\n      schema.try_assign_before(\n          keyword, schema.at(KEYWORD).at(allof_index).at(keyword), KEYWORD);\n      schema.at(KEYWORD).at(allof_index).erase(keyword);\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    // The rule moves keywords from /allOf/<index>/<keyword> to /<keyword>\n    const auto allof_prefix{current.concat({KEYWORD})};\n    const auto relative{target.resolve_from(allof_prefix)};\n    const auto &keyword{relative.at(1).to_property()};\n    const Pointer old_prefix{allof_prefix.concat({relative.at(0), keyword})};\n    const Pointer new_prefix{current.concat({keyword})};\n    return target.rebase(old_prefix, new_prefix);\n  }\n\nprivate:\n  // TODO: Ideally we this information from the frame out of the box\n  [[nodiscard]] auto is_anonymous(const JSON &entry,\n                                  const Vocabularies &vocabularies) const\n      -> bool {\n    if (vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Core,\n             Vocabularies::Known::JSON_Schema_2019_09_Core})) {\n      if (entry.defines(\"$id\") || entry.defines(\"$anchor\")) {\n        return false;\n      }\n\n      if (vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Core) &&\n          entry.defines(\"$dynamicAnchor\")) {\n        return false;\n      }\n\n      if (vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n          entry.defines(\"$recursiveAnchor\") &&\n          entry.at(\"$recursiveAnchor\").is_boolean() &&\n          entry.at(\"$recursiveAnchor\").to_boolean()) {\n        return false;\n      }\n\n      return true;\n    }\n\n    if (vocabularies.contains_any({Vocabularies::Known::JSON_Schema_Draft_7,\n                                   Vocabularies::Known::JSON_Schema_Draft_6})) {\n      return !entry.defines(\"$id\");\n    }\n\n    if (vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_4)) {\n      return !entry.defines(\"id\");\n    }\n\n    return false;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unnecessary_extends_wrapper.h",
    "content": "class UnnecessaryExtendsWrapper final : public SchemaTransformRule {\nprivate:\n  static inline const std::string KEYWORD{\"extends\"};\n\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnnecessaryExtendsWrapper()\n      : SchemaTransformRule{\"unnecessary_extends_wrapper\",\n                            \"Keywords inside `extends` that do not conflict \"\n                            \"with the parent schema can be elevated\"} {};\n\n  [[nodiscard]] auto\n  condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,\n            const SchemaFrame &frame, const SchemaFrame::Location &location,\n            const SchemaWalker &walker, const SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n        {Vocabularies::Known::JSON_Schema_Draft_3,\n         Vocabularies::Known::JSON_Schema_Draft_3_Hyper}));\n    ONLY_CONTINUE_IF(schema.is_object());\n\n    const auto *extends_value{schema.try_at(KEYWORD)};\n    ONLY_CONTINUE_IF(extends_value && extends_value->is_array() &&\n                     !extends_value->empty());\n\n    std::unordered_set<std::string_view> dependency_blocked;\n    for (const auto &entry : schema.as_object()) {\n      for (const auto &dependency :\n           walker(entry.first, vocabularies).dependencies) {\n        dependency_blocked.emplace(dependency);\n      }\n    }\n\n    const auto *parent_type_value{schema.try_at(\"type\")};\n    const JSON::TypeSet parent_types{\n        parent_type_value && is_known_type_form(*parent_type_value)\n            ? parse_schema_type(*parent_type_value)\n            : JSON::TypeSet{}};\n\n    const auto &extends{*extends_value};\n    std::vector<Pointer> locations;\n    std::unordered_set<std::string_view> elevated;\n\n    for (auto index = extends.size(); index > 0; index--) {\n      const auto &entry{extends.at(index - 1)};\n      if (!entry.is_object() || entry.empty() ||\n          // We separately handle this case via\n          // `unnecessary_extends_ref_wrapper`\n          entry.defines(\"$ref\")) {\n        continue;\n      }\n\n      auto entry_pointer{location.pointer};\n      entry_pointer.push_back(std::cref(KEYWORD));\n      entry_pointer.push_back(index - 1);\n      if (frame.has_references_to(entry_pointer)) {\n        continue;\n      }\n\n      // Skip entries that define their own identity, as elevating keywords\n      // from them could break references that target those identifiers\n      if (entry.defines(\"id\")) {\n        continue;\n      }\n\n      for (const auto &keyword_entry : entry.as_object()) {\n        const auto &keyword{keyword_entry.first};\n        const auto &metadata{walker(keyword, vocabularies)};\n\n        if (elevated.contains(keyword) ||\n            (schema.defines(keyword) &&\n             schema.at(keyword) != keyword_entry.second)) {\n          continue;\n        }\n\n        if (dependency_blocked.contains(keyword)) {\n          continue;\n        }\n\n        if (metadata.instances.any() && parent_types.any() &&\n            (metadata.instances & parent_types).none()) {\n          continue;\n        }\n\n        if (std::ranges::any_of(\n                metadata.dependencies, [&](const auto &dependency) {\n                  return !entry.defines(std::string{dependency}) &&\n                         (schema.defines(std::string{dependency}) ||\n                          elevated.contains(dependency));\n                })) {\n          continue;\n        }\n\n        locations.push_back(Pointer{KEYWORD, index - 1, keyword});\n        elevated.emplace(keyword);\n\n        for (const auto &dependency : metadata.dependencies) {\n          if (!entry.defines(std::string{dependency})) {\n            dependency_blocked.emplace(dependency);\n          }\n        }\n      }\n    }\n\n    ONLY_CONTINUE_IF(!locations.empty());\n    return APPLIES_TO_POINTERS(std::move(locations));\n  }\n\n  auto transform(JSON &schema, const Result &result) const -> void override {\n    for (const auto &location : result.locations) {\n      assert(location.size() == 3);\n      const auto extends_index{location.at(1).to_index()};\n      const auto &keyword{location.at(2).to_property()};\n      schema.try_assign_before(\n          keyword, schema.at(KEYWORD).at(extends_index).at(keyword), KEYWORD);\n      schema.at(KEYWORD).at(extends_index).erase(keyword);\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view, const Pointer &,\n                                 const Pointer &target,\n                                 const Pointer &current) const\n      -> Pointer override {\n    // The rule moves keywords from /extends/<index>/<keyword> to /<keyword>\n    const auto extends_prefix{current.concat({KEYWORD})};\n    const auto relative{target.resolve_from(extends_prefix)};\n    const auto &keyword{relative.at(1).to_property()};\n    const Pointer old_prefix{extends_prefix.concat({relative.at(0), keyword})};\n    const Pointer new_prefix{current.concat({keyword})};\n    return target.rebase(old_prefix, new_prefix);\n  }\n\nprivate:\n  static auto is_known_type_form(const sourcemeta::core::JSON &type) -> bool {\n    if (type.is_string()) {\n      return type.to_string() != \"any\";\n    }\n    if (!type.is_array()) {\n      return false;\n    }\n    return std::ranges::all_of(type.as_array(), [](const auto &entry) {\n      return entry.is_string() && entry.to_string() != \"any\";\n    });\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unsatisfiable_max_contains.h",
    "content": "class UnsatisfiableMaxContains final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnsatisfiableMaxContains()\n      : SchemaTransformRule{\n            \"unsatisfiable_max_contains\",\n            \"Setting the `maxContains` keyword to a number greater than or \"\n            \"equal to the array upper bound does not add any further \"\n            \"constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n             Vocabularies::Known::JSON_Schema_2019_09_Validation}) &&\n        schema.is_object());\n\n    const auto *max_contains{schema.try_at(\"maxContains\")};\n    ONLY_CONTINUE_IF(max_contains && max_contains->is_integer());\n    const auto *max_items{schema.try_at(\"maxItems\")};\n    ONLY_CONTINUE_IF(max_items && max_items->is_integer() &&\n                     max_contains->to_integer() >= max_items->to_integer());\n    return APPLIES_TO_KEYWORDS(\"maxContains\", \"maxItems\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"maxContains\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/unsatisfiable_min_properties.h",
    "content": "class UnsatisfiableMinProperties final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UnsatisfiableMinProperties()\n      : SchemaTransformRule{\n            \"unsatisfiable_min_properties\",\n            \"Setting `minProperties` to a number less than `required` does \"\n            \"not add any further constraint\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(vocabularies.contains_any(\n                         {Vocabularies::Known::JSON_Schema_2020_12_Validation,\n                          Vocabularies::Known::JSON_Schema_2019_09_Validation,\n                          Vocabularies::Known::JSON_Schema_Draft_7,\n                          Vocabularies::Known::JSON_Schema_Draft_6,\n                          Vocabularies::Known::JSON_Schema_Draft_4}) &&\n                     schema.is_object());\n\n    const auto *min_properties{schema.try_at(\"minProperties\")};\n    ONLY_CONTINUE_IF(min_properties && min_properties->is_integer());\n    const auto *required{schema.try_at(\"required\")};\n    ONLY_CONTINUE_IF(required && required->is_array() && required->unique() &&\n                     std::cmp_greater_equal(required->size(),\n                                            static_cast<std::uint64_t>(\n                                                min_properties->to_integer())));\n    return APPLIES_TO_KEYWORDS(\"minProperties\", \"required\");\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"minProperties\");\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/valid_default.h",
    "content": "class ValidDefault final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ValidDefault(Compiler compiler = default_schema_compiler)\n      : SchemaTransformRule{\"valid_default\", \"Only set a `default` value that \"\n                                             \"validates against the schema\"},\n        compiler_{std::move(compiler)} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    using Known = Vocabularies::Known;\n    // Technically, the `default` keyword goes back to Draft 1, but Blaze\n    // only supports Draft 3 and later\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any(\n            {Known::JSON_Schema_2020_12_Meta_Data,\n             Known::JSON_Schema_2019_09_Meta_Data, Known::JSON_Schema_Draft_7,\n             Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_4,\n             Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper}) &&\n        schema.is_object() && schema.defines(\"default\"));\n\n    if (vocabularies.contains_any(\n            {Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_6,\n             Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_3,\n             Known::JSON_Schema_Draft_3_Hyper})) {\n      ONLY_CONTINUE_IF(!schema.defines(\"$ref\"));\n    }\n\n    const auto &instance{schema.at(\"default\")};\n\n    if (frame.standalone()) {\n      const auto base{frame.uri(location.pointer)};\n      assert(base.has_value());\n      Template schema_template;\n      try {\n        schema_template = compile(root, walker, resolver, this->compiler_,\n                                  frame, base.value().get(), Mode::Exhaustive);\n      } catch (const CompilerReferenceTargetNotSchemaError &) {\n        throw;\n      } catch (const sourcemeta::core::SchemaVocabularyError &) {\n        throw;\n      } catch (...) {\n        return false;\n      }\n      SimpleOutput output{instance};\n      Evaluator evaluator;\n      const auto result{\n          evaluator.validate(schema_template, instance, std::ref(output))};\n      if (result) {\n        return false;\n      }\n\n      std::ostringstream message;\n      for (const auto &entry : output) {\n        message << entry.message << \"\\n\";\n        message << \"  at instance location \\\"\";\n        sourcemeta::core::stringify(entry.instance_location, message);\n        message << \"\\\"\\n\";\n        message << \"  at evaluate path \\\"\";\n        sourcemeta::core::stringify(entry.evaluate_path, message);\n        message << \"\\\"\\n\";\n      }\n\n      return {{{\"default\"}}, std::move(message).str()};\n    }\n\n    const auto &root_base_dialect{\n        frame.traverse(frame.root()).value_or(location).get().base_dialect};\n    std::string_view default_id{location.base};\n    if (!sourcemeta::core::identify(root, root_base_dialect).empty() ||\n        default_id.empty()) {\n      default_id = \"\";\n    }\n\n    sourcemeta::core::WeakPointer base;\n    const auto subschema{\n        sourcemeta::core::wrap(root, frame, location, resolver, base)};\n    Template schema_template;\n    try {\n      schema_template = compile(subschema, walker, resolver, this->compiler_,\n                                Mode::Exhaustive, location.dialect, default_id);\n    } catch (const CompilerReferenceTargetNotSchemaError &) {\n      throw;\n    } catch (const sourcemeta::core::SchemaVocabularyError &) {\n      throw;\n    } catch (...) {\n      return false;\n    }\n    SimpleOutput output{instance, base};\n    Evaluator evaluator;\n    const auto result{\n        evaluator.validate(schema_template, instance, std::ref(output))};\n    if (result) {\n      return false;\n    }\n\n    std::ostringstream message;\n    for (const auto &entry : output) {\n      message << entry.message << \"\\n\";\n      message << \"  at instance location \\\"\";\n      sourcemeta::core::stringify(entry.instance_location, message);\n      message << \"\\\"\\n\";\n      message << \"  at evaluate path \\\"\";\n      sourcemeta::core::stringify(entry.evaluate_path, message);\n      message << \"\\\"\\n\";\n    }\n\n    return {{{\"default\"}}, std::move(message).str()};\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"default\");\n  }\n\nprivate:\n  const Compiler compiler_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/linter/valid_examples.h",
    "content": "class ValidExamples final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  ValidExamples(Compiler compiler = default_schema_compiler)\n      : SchemaTransformRule{\"valid_examples\",\n                            \"Only include instances in the `examples` array \"\n                            \"that validate against the schema\"},\n        compiler_{std::move(compiler)} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    using Known = Vocabularies::Known;\n    ONLY_CONTINUE_IF(\n        vocabularies.contains_any({Known::JSON_Schema_2020_12_Meta_Data,\n                                   Known::JSON_Schema_2019_09_Meta_Data,\n                                   Known::JSON_Schema_Draft_7,\n                                   Known::JSON_Schema_Draft_6}) &&\n        schema.is_object());\n\n    const auto *examples{schema.try_at(\"examples\")};\n    ONLY_CONTINUE_IF(examples && examples->is_array() && !examples->empty());\n\n    if (vocabularies.contains_any({Known::JSON_Schema_Draft_7,\n                                   Known::JSON_Schema_Draft_6,\n                                   Known::JSON_Schema_Draft_4})) {\n      ONLY_CONTINUE_IF(!schema.defines(\"$ref\"));\n    }\n\n    // TODO(C++23): Use std::views::enumerate when available in libc++\n    std::size_t cursor{0};\n\n    if (frame.standalone()) {\n      const auto base{frame.uri(location.pointer)};\n      assert(base.has_value());\n      Template schema_template;\n      try {\n        schema_template = compile(root, walker, resolver, this->compiler_,\n                                  frame, base.value().get(), Mode::Exhaustive);\n      } catch (const CompilerReferenceTargetNotSchemaError &) {\n        throw;\n      } catch (const sourcemeta::core::SchemaVocabularyError &) {\n        throw;\n      } catch (...) {\n        return false;\n      }\n\n      for (const auto &example : examples->as_array()) {\n        SimpleOutput output{example};\n        Evaluator evaluator;\n        const auto result{\n            evaluator.validate(schema_template, example, std::ref(output))};\n        if (!result) {\n          std::ostringstream message;\n          message << \"Invalid example instance at index \" << cursor << \"\\n\";\n          for (const auto &entry : output) {\n            message << \"  \" << entry.message << \"\\n\";\n            message << \"  \"\n                    << \"  at instance location \\\"\";\n            sourcemeta::core::stringify(entry.instance_location, message);\n            message << \"\\\"\\n\";\n            message << \"  \"\n                    << \"  at evaluate path \\\"\";\n            sourcemeta::core::stringify(entry.evaluate_path, message);\n            message << \"\\\"\\n\";\n          }\n\n          return {{{\"examples\", cursor}}, std::move(message).str()};\n        }\n\n        cursor += 1;\n      }\n\n      return false;\n    }\n\n    const auto &root_base_dialect{\n        frame.traverse(frame.root()).value_or(location).get().base_dialect};\n    std::string_view default_id{location.base};\n    if (!sourcemeta::core::identify(root, root_base_dialect).empty() ||\n        default_id.empty()) {\n      default_id = \"\";\n    }\n\n    sourcemeta::core::WeakPointer base;\n    const auto subschema{\n        sourcemeta::core::wrap(root, frame, location, resolver, base)};\n    Template schema_template;\n    try {\n      schema_template = compile(subschema, walker, resolver, this->compiler_,\n                                Mode::Exhaustive, location.dialect, default_id);\n    } catch (const CompilerReferenceTargetNotSchemaError &) {\n      throw;\n    } catch (const sourcemeta::core::SchemaVocabularyError &) {\n      throw;\n    } catch (...) {\n      return false;\n    }\n\n    for (const auto &example : schema.at(\"examples\").as_array()) {\n      SimpleOutput output{example, base};\n      Evaluator evaluator;\n      const auto result{\n          evaluator.validate(schema_template, example, std::ref(output))};\n      if (!result) {\n        std::ostringstream message;\n        message << \"Invalid example instance at index \" << cursor << \"\\n\";\n        for (const auto &entry : output) {\n          message << \"  \" << entry.message << \"\\n\";\n          message << \"  \"\n                  << \"  at instance location \\\"\";\n          sourcemeta::core::stringify(entry.instance_location, message);\n          message << \"\\\"\\n\";\n          message << \"  \"\n                  << \"  at evaluate path \\\"\";\n          sourcemeta::core::stringify(entry.evaluate_path, message);\n          message << \"\\\"\\n\";\n        }\n\n        return {{{\"examples\", cursor}}, std::move(message).str()};\n      }\n\n      cursor += 1;\n    }\n\n    return false;\n  }\n\n  auto transform(JSON &schema, const Result &) const -> void override {\n    schema.erase(\"examples\");\n  }\n\nprivate:\n  const Compiler compiler_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/schema_rule.cc",
    "content": "#include <sourcemeta/blaze/alterschema.h>\n#include <sourcemeta/blaze/alterschema_error.h>\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n#include <sourcemeta/blaze/output.h>\n\n#include <sourcemeta/core/regex.h>\n\n#include <cassert>     // assert\n#include <functional>  // std::ref\n#include <sstream>     // std::ostringstream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\nstatic constexpr std::string_view NAME_PATTERN{\"^[a-z0-9_/]+$\"};\n\nstatic auto validate_name(const std::string_view name) -> void {\n  static const auto pattern{sourcemeta::core::to_regex(NAME_PATTERN)};\n  assert(pattern.has_value());\n  if (name.empty()) [[unlikely]] {\n    throw SchemaRuleInvalidNameError(name,\n                                     \"The schema rule name must not be empty\");\n  }\n\n  if (!sourcemeta::core::matches(pattern.value(), name)) [[unlikely]] {\n    throw SchemaRuleInvalidNamePatternError(name, NAME_PATTERN);\n  }\n}\n\nstatic auto extract_description(const sourcemeta::core::JSON &schema)\n    -> std::string {\n  if (!schema.defines(\"description\")) {\n    return \"\";\n  }\n\n  if (schema.at(\"description\").is_string()) {\n    return schema.at(\"description\").to_string();\n  }\n\n  std::ostringstream result;\n  sourcemeta::core::stringify(schema.at(\"description\"), result);\n  return std::move(result).str();\n}\n\nstatic auto extract_title(const sourcemeta::core::JSON &schema) -> std::string {\n  if (!schema.defines(\"title\")) [[unlikely]] {\n    throw SchemaRuleMissingNameError{};\n  }\n\n  if (!schema.at(\"title\").is_string()) [[unlikely]] {\n    std::ostringstream result;\n    sourcemeta::core::stringify(schema.at(\"title\"), result);\n    throw SchemaRuleInvalidNameError(std::move(result).str(),\n                                     \"The schema rule title is not a string\");\n  }\n\n  auto title{schema.at(\"title\").to_string()};\n  validate_name(title);\n  return title;\n}\n\nSchemaRule::SchemaRule(const sourcemeta::core::JSON &schema,\n                       const sourcemeta::core::SchemaWalker &walker,\n                       const sourcemeta::core::SchemaResolver &resolver,\n                       const Compiler &compiler,\n                       const std::string_view default_dialect,\n                       const std::optional<Tweaks> &tweaks)\n    : SchemaTransformRule{extract_title(schema), extract_description(schema)},\n      template_{compile(schema, walker, resolver, compiler, Mode::Exhaustive,\n                        default_dialect, \"\", \"\", tweaks)} {};\n\nauto SchemaRule::condition(const sourcemeta::core::JSON &schema,\n                           const sourcemeta::core::JSON &,\n                           const sourcemeta::core::Vocabularies &,\n                           const sourcemeta::core::SchemaFrame &,\n                           const sourcemeta::core::SchemaFrame::Location &,\n                           const sourcemeta::core::SchemaWalker &,\n                           const sourcemeta::core::SchemaResolver &) const\n    -> SchemaTransformRule::Result {\n  SimpleOutput output{schema};\n  Evaluator evaluator;\n  const auto result{\n      evaluator.validate(this->template_, schema, std::ref(output))};\n  if (result) {\n    return false;\n  }\n\n  if (output.cbegin() != output.cend()) {\n    if (output.cbegin()->instance_location.empty()) {\n      return {{}, std::string{output.cbegin()->message}};\n    }\n\n    return {{sourcemeta::core::to_pointer(output.cbegin()->instance_location)},\n            std::string{output.cbegin()->message}};\n  } else {\n    return true;\n  }\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/transformer.cc",
    "content": "#include <sourcemeta/blaze/alterschema.h>\n#include <sourcemeta/core/jsonschema.h>\n#include <sourcemeta/core/uri.h>\n\n#include <algorithm>     // std::erase_if\n#include <cassert>       // assert\n#include <functional>    // std::hash\n#include <sstream>       // std::ostringstream\n#include <tuple>         // std::tuple\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::move, std::pair\n#include <vector>        // std::vector\n\nnamespace {\n\nstruct ProcessedRuleHasher {\n  auto\n  operator()(const std::tuple<sourcemeta::core::Pointer, std::string_view,\n                              sourcemeta::core::JSON> &value) const noexcept\n      -> std::size_t {\n    return sourcemeta::core::Pointer::Hasher{}(std::get<0>(value)) ^\n           (std::hash<std::string_view>{}(std::get<1>(value)) << 1) ^\n           (std::hash<std::uint64_t>{}(std::get<2>(value).fast_hash()) << 2);\n  }\n};\n\nauto calculate_health_percentage(const std::size_t subschemas,\n                                 const std::size_t failed_subschemas)\n    -> std::uint8_t {\n  assert(failed_subschemas <= subschemas);\n  if (subschemas == 0) {\n    return 100;\n  }\n\n  const auto result{100 - (failed_subschemas * 100 / subschemas)};\n  assert(result <= 100);\n  return static_cast<std::uint8_t>(result);\n}\n\nauto check_rules(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaFrame &frame,\n    const std::vector<std::tuple<\n        std::unique_ptr<sourcemeta::blaze::SchemaTransformRule>, bool, bool>>\n        &rules,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver,\n    const sourcemeta::blaze::SchemaTransformer::Callback &callback,\n    const sourcemeta::core::JSON::String &exclude_keyword,\n    const bool non_mutating_only) -> std::pair<bool, std::uint8_t> {\n  std::unordered_set<sourcemeta::core::Pointer,\n                     sourcemeta::core::Pointer::Hasher>\n      visited;\n  bool result{true};\n  std::size_t subschema_count{0};\n  std::size_t subschema_failures{0};\n\n  for (const auto &entry : frame.locations()) {\n    if (entry.second.type !=\n            sourcemeta::core::SchemaFrame::LocationType::Resource &&\n        entry.second.type !=\n            sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n      continue;\n    }\n\n    const auto [visited_iterator, inserted] =\n        visited.insert(sourcemeta::core::to_pointer(entry.second.pointer));\n    if (!inserted) {\n      continue;\n    }\n    const auto &entry_pointer{*visited_iterator};\n\n    subschema_count += 1;\n\n    const auto &current{sourcemeta::core::get(schema, entry_pointer)};\n    const auto current_vocabularies{frame.vocabularies(entry.second, resolver)};\n\n    bool subschema_failed{false};\n    for (const auto &[rule, mutates, _] : rules) {\n      if (non_mutating_only && mutates) {\n        continue;\n      }\n\n      const auto outcome{rule->check(current, schema, current_vocabularies,\n                                     walker, resolver, frame, entry.second,\n                                     exclude_keyword)};\n      if (outcome.applies) {\n        subschema_failed = true;\n        callback(entry_pointer, rule->name(), rule->message(), outcome,\n                 mutates);\n      }\n    }\n\n    if (subschema_failed) {\n      subschema_failures += 1;\n      result = false;\n    }\n  }\n\n  return {result,\n          calculate_health_percentage(subschema_count, subschema_failures)};\n}\n\nauto analyse_frame(sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::JSON &schema,\n                   const sourcemeta::core::SchemaWalker &walker,\n                   const sourcemeta::core::SchemaResolver &resolver,\n                   const std::string_view default_dialect,\n                   const std::string_view default_id) -> void {\n  if (!sourcemeta::core::identify(schema, resolver, default_dialect).empty()) {\n    frame.analyse(schema, walker, resolver, default_dialect);\n  } else {\n    frame.analyse(schema, walker, resolver, default_dialect, default_id);\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nSchemaTransformRule::SchemaTransformRule(const std::string_view name,\n                                         const std::string_view message)\n    : name_{name}, message_{message} {}\n\nauto SchemaTransformRule::operator==(const SchemaTransformRule &other) const\n    -> bool {\n  return this->name() == other.name();\n}\n\nauto SchemaTransformRule::name() const noexcept -> std::string_view {\n  return this->name_;\n}\n\nauto SchemaTransformRule::message() const noexcept -> std::string_view {\n  return this->message_;\n}\n\nauto SchemaTransformRule::transform(core::JSON &, const Result &) const\n    -> void {\n  throw SchemaAbortError(\"This rule cannot be automatically transformed\");\n}\n\nauto SchemaTransformRule::rereference(const std::string_view reference,\n                                      const core::Pointer &origin,\n                                      const core::Pointer &,\n                                      const core::Pointer &) const\n    -> core::Pointer {\n  throw SchemaBrokenReferenceError(reference, origin,\n                                   \"The reference broke after transformation\");\n}\n\nauto SchemaTransformRule::check(const core::JSON &schema,\n                                const core::JSON &root,\n                                const core::Vocabularies &vocabularies,\n                                const core::SchemaWalker &walker,\n                                const core::SchemaResolver &resolver,\n                                const core::SchemaFrame &frame,\n                                const core::SchemaFrame::Location &location,\n                                const core::JSON::String &exclude_keyword) const\n    -> SchemaTransformRule::Result {\n  auto result{this->condition(schema, root, vocabularies, frame, location,\n                              walker, resolver)};\n\n  if (result.applies && !exclude_keyword.empty() && schema.is_object()) {\n    const auto *exclude_value{schema.try_at(exclude_keyword)};\n    if (exclude_value != nullptr &&\n        ((exclude_value->is_string() &&\n          exclude_value->to_string() == this->name()) ||\n         (exclude_value->is_array() &&\n          exclude_value->contains(this->name())))) {\n      return false;\n    }\n  }\n\n  return result;\n}\n\nauto SchemaTransformer::check(const core::JSON &schema,\n                              const core::SchemaWalker &walker,\n                              const core::SchemaResolver &resolver,\n                              const SchemaTransformer::Callback &callback,\n                              std::string_view default_dialect,\n                              std::string_view default_id,\n                              const core::JSON::String &exclude_keyword) const\n    -> std::pair<bool, std::uint8_t> {\n  core::SchemaFrame frame{core::SchemaFrame::Mode::References};\n  analyse_frame(frame, schema, walker, resolver, default_dialect, default_id);\n  return check_rules(schema, frame, this->rules, walker, resolver, callback,\n                     exclude_keyword, false);\n}\n\nauto SchemaTransformer::apply(core::JSON &schema,\n                              const core::SchemaWalker &walker,\n                              const core::SchemaResolver &resolver,\n                              const SchemaTransformer::Callback &callback,\n                              std::string_view default_dialect,\n                              std::string_view default_id,\n                              const core::JSON::String &exclude_keyword) const\n    -> std::pair<bool, std::uint8_t> {\n  assert(!this->rules.empty());\n  std::unordered_set<std::tuple<core::Pointer, std::string_view, core::JSON>,\n                     ProcessedRuleHasher>\n      processed_rules;\n\n  core::SchemaFrame frame{core::SchemaFrame::Mode::References};\n\n  struct PotentiallyBrokenReference {\n    core::Pointer origin;\n    core::JSON::String original;\n    core::JSON::String destination;\n    core::JSON::String fragment;\n    core::Pointer target_pointer;\n    std::size_t target_relative_pointer;\n  };\n\n  std::vector<PotentiallyBrokenReference> potentially_broken_references;\n\n  while (true) {\n    if (frame.empty()) {\n      if (schema.is_boolean()) {\n        break;\n      }\n\n      analyse_frame(frame, schema, walker, resolver, default_dialect,\n                    default_id);\n    }\n\n    std::unordered_set<core::Pointer, core::Pointer::Hasher> visited;\n    bool applied{false};\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type != core::SchemaFrame::LocationType::Resource &&\n          entry.second.type != core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      const auto [visited_iterator, inserted] =\n          visited.insert(core::to_pointer(entry.second.pointer));\n      if (!inserted) {\n        continue;\n      }\n      const auto &entry_pointer{*visited_iterator};\n      auto &current{core::get(schema, entry_pointer)};\n      const auto current_vocabularies{\n          frame.vocabularies(entry.second, resolver)};\n\n      for (const auto &[rule, mutates, reframe_after_transform] : this->rules) {\n        if (!mutates) {\n          continue;\n        }\n\n        auto outcome{rule->check(current, schema, current_vocabularies, walker,\n                                 resolver, frame, entry.second,\n                                 exclude_keyword)};\n\n        if (!outcome.applies) {\n          continue;\n        }\n\n        potentially_broken_references.clear();\n        for (const auto &reference : frame.references()) {\n          const auto destination{frame.traverse(reference.second.destination)};\n          if (!destination.has_value() ||\n              !reference.second.fragment.has_value() ||\n              !reference.second.fragment.value().starts_with('/')) {\n            continue;\n          }\n\n          const auto &target{destination.value().get()};\n          potentially_broken_references.push_back(\n              {core::to_pointer(reference.first.second),\n               core::JSON::String{reference.second.original},\n               reference.second.destination,\n               core::JSON::String{reference.second.fragment.value()},\n               core::to_pointer(target.pointer), target.relative_pointer});\n        }\n\n        rule->transform(current, outcome);\n        callback(entry_pointer, rule->name(), rule->message(), outcome, true);\n\n        applied = true;\n\n        if (reframe_after_transform) {\n          analyse_frame(frame, schema, walker, resolver, default_dialect,\n                        default_id);\n        } else if (current.is_boolean()) {\n          std::tuple<core::Pointer, std::string_view, core::JSON> mark{\n              entry_pointer, rule->name(), current};\n          if (processed_rules.contains(mark)) {\n            throw SchemaTransformRuleProcessedTwiceError(rule->name(),\n                                                         entry_pointer);\n          }\n\n          processed_rules.emplace(std::move(mark));\n          frame.reset();\n          goto blaze_transformer_start_again;\n        }\n\n        const auto new_location{\n            frame.traverse(core::to_weak_pointer(entry_pointer))};\n        assert(new_location.has_value());\n\n        // Fix broken references before re-checking the condition,\n        // as the re-check may mutate rule state that rereference needs\n        bool references_fixed{false};\n        const auto resource_offset{new_location.value().get().relative_pointer};\n        const auto current_slice{entry_pointer.slice(resource_offset)};\n        for (const auto &saved_reference : potentially_broken_references) {\n          if (core::try_get(schema, saved_reference.target_pointer)) {\n            continue;\n          }\n\n          // If the origin was also relocated, resolve its new location\n          auto effective_origin{saved_reference.origin};\n          if (!core::try_get(schema, saved_reference.origin.initial())) {\n            try {\n              const auto new_origin{rule->rereference(\n                  saved_reference.destination, saved_reference.origin,\n                  saved_reference.origin.slice(resource_offset),\n                  current_slice)};\n              effective_origin =\n                  saved_reference.origin.slice(0, resource_offset)\n                      .concat(new_origin);\n            } catch (...) {\n              continue;\n            }\n            if (!core::try_get(schema, effective_origin.initial())) {\n              continue;\n            }\n          }\n\n          const auto new_relative{rule->rereference(\n              saved_reference.destination, saved_reference.origin,\n              saved_reference.target_pointer.slice(\n                  saved_reference.target_relative_pointer),\n              current_slice)};\n          const auto new_fragment{\n              saved_reference.fragment ==\n                      core::to_string(saved_reference.target_pointer)\n                  ? saved_reference.target_pointer\n                        .slice(0, saved_reference.target_relative_pointer)\n                        .concat(new_relative)\n                  : new_relative};\n\n          core::URI original{saved_reference.original};\n          original.fragment(core::to_string(new_fragment));\n          core::set(schema, effective_origin, core::JSON{original.recompose()});\n          references_fixed = true;\n        }\n\n        const auto new_vocabularies{\n            frame.vocabularies(new_location.value().get(), resolver)};\n\n        if (rule->check(current, schema, new_vocabularies, walker, resolver,\n                        frame, new_location.value().get(), exclude_keyword)\n                .applies) {\n          std::ostringstream error;\n          error << \"Rule condition holds after application: \" << rule->name();\n          throw std::runtime_error(error.str());\n        }\n\n        std::tuple<core::Pointer, std::string_view, core::JSON> mark{\n            entry_pointer, rule->name(), current};\n        if (processed_rules.contains(mark)) {\n          throw SchemaTransformRuleProcessedTwiceError(rule->name(),\n                                                       entry_pointer);\n        }\n\n        processed_rules.emplace(std::move(mark));\n\n        if (references_fixed) {\n          frame.reset();\n        }\n\n        if (references_fixed || reframe_after_transform) {\n          goto blaze_transformer_start_again;\n        }\n      }\n    }\n\n  blaze_transformer_start_again:\n    if (!applied) {\n      break;\n    }\n  }\n\n  if (frame.empty() && !schema.is_boolean()) {\n    analyse_frame(frame, schema, walker, resolver, default_dialect, default_id);\n  }\n\n  if (frame.empty()) {\n    return {true, static_cast<std::uint8_t>(100)};\n  }\n\n  return check_rules(schema, frame, this->rules, walker, resolver, callback,\n                     exclude_keyword, true);\n}\n\nauto SchemaTransformer::remove(const std::string_view name) -> bool {\n  return std::erase_if(this->rules, [&name](const auto &entry) {\n           return std::get<0>(entry)->name() == name;\n         }) > 0;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/helpers.h",
    "content": "static const std::string DIALECT_OVERRIDE_KEYWORD{\n    \"x-sourcemeta-dialect-override-subschema\"};\n\nstatic auto mark_dialect_override(sourcemeta::core::JSON &schema,\n                                  const std::string_view dialect) -> void {\n  schema.assign(DIALECT_OVERRIDE_KEYWORD, sourcemeta::core::JSON{dialect});\n}\n\nstatic auto current_dialect_or_override(const sourcemeta::core::JSON &schema)\n    -> std::string_view {\n  if (!schema.is_object()) {\n    return {};\n  }\n  const auto *override_value{schema.try_at(DIALECT_OVERRIDE_KEYWORD)};\n  if (override_value != nullptr && override_value->is_string()) {\n    return override_value->to_string();\n  }\n  if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string()) {\n    return schema.at(\"$schema\").to_string();\n  }\n  return {};\n}\n\nstatic auto\nsubschema_at_dialect(const sourcemeta::core::JSON &schema,\n                     const sourcemeta::core::SchemaFrame::Location &location,\n                     const std::string_view dialect) -> bool {\n  const auto current{current_dialect_or_override(schema)};\n  if (!current.empty()) {\n    return current == dialect;\n  }\n  return schema.is_object() && location.pointer.empty();\n}\n\nstatic auto drop_dialect_overrides(sourcemeta::core::JSON &schema,\n                                   const bool is_root) -> void {\n  if (schema.is_array()) {\n    for (auto &item : schema.as_array()) {\n      drop_dialect_overrides(item, false);\n    }\n    return;\n  }\n\n  if (!schema.is_object()) {\n    return;\n  }\n\n  if (!is_root && schema.defines(\"$schema\") &&\n      schema.at(\"$schema\").is_string()) {\n    return;\n  }\n\n  schema.erase(DIALECT_OVERRIDE_KEYWORD);\n\n  std::vector<std::string> keys;\n  keys.reserve(schema.size());\n  for (const auto &entry : schema.as_object()) {\n    keys.push_back(entry.first);\n  }\n  for (const auto &key : keys) {\n    drop_dialect_overrides(schema.at(key), false);\n  }\n}\n\nstruct AnchorCharPolicy {\n  std::function<bool(char)> is_valid_first;\n  std::function<bool(char)> is_valid_body;\n};\n\nstatic auto sanitize_anchor_with_policy(const std::string_view original,\n                                        const std::set<std::string> &in_use,\n                                        const AnchorCharPolicy &policy)\n    -> std::string {\n  std::string sanitized;\n  sanitized.reserve(original.size());\n  for (const char character : original) {\n    sanitized.push_back(policy.is_valid_body(character) ? character : '-');\n  }\n  while (sanitized.empty() || !policy.is_valid_first(sanitized.front()) ||\n         in_use.contains(sanitized)) {\n    sanitized.insert(0, \"x-\");\n  }\n  return sanitized;\n}\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/prefix_promoted_2020_12_keywords.h",
    "content": "class PrefixPromoted202012Keywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PrefixPromoted202012Keywords()\n      : SchemaTransformRule{\"prefix_promoted_2020_12_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n        schema.is_object());\n\n    return schema.defines_any({\"prefixItems\", \"$dynamicAnchor\", \"$dynamicRef\"});\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    for (const auto &keyword : KEYWORDS) {\n      const std::string keyword_name{keyword};\n      if (!schema.defines(keyword_name)) {\n        continue;\n      }\n\n      std::string prefixed_name{\"x-\" + keyword_name};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword_name, prefixed_name);\n      schema.rename(keyword_name, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{\n          target.rebase(current.concat(sourcemeta::core::Pointer{old_name}),\n                        current.concat(sourcemeta::core::Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static inline const std::array<std::string_view, 3> KEYWORDS{\n      {\"prefixItems\", \"$dynamicAnchor\", \"$dynamicRef\"}};\n\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/prefix_promoted_draft_2019_09_keywords.h",
    "content": "class PrefixPromoted201909Keywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PrefixPromoted201909Keywords()\n      : SchemaTransformRule{\"prefix_promoted_2019_09_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_7) &&\n        schema.is_object());\n\n    for (const auto &keyword : KEYWORDS) {\n      if (schema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    for (const auto &keyword : KEYWORDS) {\n      const std::string keyword_name{keyword};\n      if (!schema.defines(keyword_name)) {\n        continue;\n      }\n\n      std::string prefixed_name{\"x-\" + keyword_name};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword_name, prefixed_name);\n      schema.rename(keyword_name, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{\n          target.rebase(current.concat(sourcemeta::core::Pointer{old_name}),\n                        current.concat(sourcemeta::core::Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static inline const std::array<std::string_view, 13> KEYWORDS{\n      {\"$anchor\", \"$recursiveAnchor\", \"$recursiveRef\", \"$vocabulary\", \"$defs\",\n       \"dependentSchemas\", \"dependentRequired\", \"unevaluatedItems\",\n       \"unevaluatedProperties\", \"maxContains\", \"minContains\", \"contentSchema\",\n       \"deprecated\"}};\n\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/prefix_promoted_draft_4_keywords.h",
    "content": "class PrefixPromotedDraft4Keywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PrefixPromotedDraft4Keywords()\n      : SchemaTransformRule{\"prefix_promoted_draft_4_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3) &&\n        schema.is_object());\n\n    for (const auto &keyword : KEYWORDS) {\n      if (schema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    for (const auto &keyword : KEYWORDS) {\n      const std::string keyword_name{keyword};\n      if (!schema.defines(keyword_name)) {\n        continue;\n      }\n\n      std::string prefixed_name{\"x-\" + keyword_name};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword_name, prefixed_name);\n      schema.rename(keyword_name, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{\n          target.rebase(current.concat(sourcemeta::core::Pointer{old_name}),\n                        current.concat(sourcemeta::core::Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static inline const std::array<std::string_view, 7> KEYWORDS{\n      {\"multipleOf\", \"maxProperties\", \"minProperties\", \"allOf\", \"anyOf\",\n       \"oneOf\", \"not\"}};\n\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/prefix_promoted_draft_6_keywords.h",
    "content": "class PrefixPromotedDraft6Keywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PrefixPromotedDraft6Keywords()\n      : SchemaTransformRule{\"prefix_promoted_draft_6_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_4) &&\n        schema.is_object());\n\n    for (const auto &keyword : KEYWORDS) {\n      if (schema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    for (const auto &keyword : KEYWORDS) {\n      const std::string keyword_name{keyword};\n      if (!schema.defines(keyword_name)) {\n        continue;\n      }\n\n      std::string prefixed_name{\"x-\" + keyword_name};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword_name, prefixed_name);\n      schema.rename(keyword_name, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{\n          target.rebase(current.concat(sourcemeta::core::Pointer{old_name}),\n                        current.concat(sourcemeta::core::Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static inline const std::array<std::string_view, 4> KEYWORDS{\n      {\"const\", \"contains\", \"propertyNames\", \"examples\"}};\n\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/prefix_promoted_draft_7_keywords.h",
    "content": "class PrefixPromotedDraft7Keywords final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  PrefixPromotedDraft7Keywords()\n      : SchemaTransformRule{\"prefix_promoted_draft_7_keywords\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_6) &&\n        schema.is_object());\n\n    for (const auto &keyword : KEYWORDS) {\n      if (schema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    for (const auto &keyword : KEYWORDS) {\n      const std::string keyword_name{keyword};\n      if (!schema.defines(keyword_name)) {\n        continue;\n      }\n\n      std::string prefixed_name{\"x-\" + keyword_name};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace(keyword_name, prefixed_name);\n      schema.rename(keyword_name, std::move(prefixed_name));\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_name, new_name] : this->renames_) {\n      const auto result{\n          target.rebase(current.concat(sourcemeta::core::Pointer{old_name}),\n                        current.concat(sourcemeta::core::Pointer{new_name}))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static inline const std::array<std::string_view, 8> KEYWORDS{\n      {\"$comment\", \"if\", \"then\", \"else\", \"readOnly\", \"writeOnly\",\n       \"contentMediaType\", \"contentEncoding\"}};\n\n  mutable std::unordered_map<std::string, std::string> renames_;\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_2019_09_to_2020_12.h",
    "content": "class Upgrade201909To202012 final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  Upgrade201909To202012()\n      : SchemaTransformRule{\"upgrade_2019_09_to_2020_12\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_2019_09_Core) &&\n        schema.is_object());\n\n    const bool is_resource_scope{\n        location.type ==\n            sourcemeta::core::SchemaFrame::LocationType::Resource ||\n        location.pointer.empty()};\n\n    if (is_resource_scope) {\n      compute_anchor_sanitization(root, frame, location);\n      if (!this->anchor_renames_.empty() ||\n          !this->anchor_ref_rewrites_.empty()) {\n        this->descendant_has_pending_pattern_ =\n            any_descendant_has_pending_pattern(root, frame, location);\n        this->resource_has_recursive_anchor_ =\n            compute_resource_has_recursive_anchor(root, frame, location);\n        this->document_has_unevaluated_items_ =\n            compute_document_has_unevaluated_items(root, frame, walker,\n                                                   resolver);\n        this->is_inside_contains_wrapper_ = false;\n        return Result{std::vector<sourcemeta::core::Pointer>{},\n                      std::string{\"sanitize\"}};\n      }\n    }\n\n    if (enclosing_resource_has_pending_sanitization(root, frame, location)) {\n      return false;\n    }\n\n    this->is_inside_contains_wrapper_ =\n        location_inside_contains_wrapper(location);\n\n    if (any_descendant_has_pending_pattern(root, frame, location)) {\n      return false;\n    }\n\n    this->resource_has_recursive_anchor_ =\n        compute_resource_has_recursive_anchor(root, frame, location);\n    this->document_has_unevaluated_items_ =\n        compute_document_has_unevaluated_items(root, frame, walker, resolver);\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &result) const\n      -> void override {\n    const bool is_sanitize_phase{result.description.has_value() &&\n                                 result.description.value() == \"sanitize\"};\n    if (is_sanitize_phase) {\n      apply_anchor_sanitization(schema);\n      if (this->descendant_has_pending_pattern_) {\n        return;\n      }\n    }\n\n    this->renames_.clear();\n\n    if (schema.defines(\"$recursiveAnchor\") &&\n        schema.at(\"$recursiveAnchor\").is_boolean()) {\n      if (schema.at(\"$recursiveAnchor\").to_boolean()) {\n        schema.rename(\"$recursiveAnchor\", \"$dynamicAnchor\");\n        schema.at(\"$dynamicAnchor\").into(sourcemeta::core::JSON{\"meta\"});\n      } else {\n        schema.erase(\"$recursiveAnchor\");\n      }\n    }\n\n    if (schema.defines(\"$recursiveRef\")) {\n      schema.rename(\"$recursiveRef\", \"$dynamicRef\");\n      if (this->resource_has_recursive_anchor_) {\n        schema.at(\"$dynamicRef\").into(sourcemeta::core::JSON{\"#meta\"});\n      }\n    }\n\n    if (schema.defines(\"items\") && schema.at(\"items\").is_array()) {\n      if (schema.at(\"items\").empty()) {\n        schema.erase(\"items\");\n      } else {\n        this->renames_.emplace_back(sourcemeta::core::Pointer{\"items\"},\n                                    sourcemeta::core::Pointer{\"prefixItems\"});\n        schema.rename(\"items\", \"prefixItems\");\n      }\n      if (schema.defines(\"additionalItems\")) {\n        this->renames_.emplace_back(\n            sourcemeta::core::Pointer{\"additionalItems\"},\n            sourcemeta::core::Pointer{\"items\"});\n        schema.rename(\"additionalItems\", \"items\");\n      }\n    } else if (schema.defines(\"additionalItems\")) {\n      schema.erase(\"additionalItems\");\n    }\n\n    if (schema.defines(\"contains\") && !this->is_inside_contains_wrapper_ &&\n        this->document_has_unevaluated_items_) {\n      auto wrapper_inner{sourcemeta::core::JSON::make_object()};\n      wrapper_inner.assign(\"contains\", schema.at(\"contains\"));\n      if (schema.defines(\"minContains\")) {\n        wrapper_inner.assign(\"minContains\", schema.at(\"minContains\"));\n        schema.erase(\"minContains\");\n      }\n      if (schema.defines(\"maxContains\")) {\n        wrapper_inner.assign(\"maxContains\", schema.at(\"maxContains\"));\n        schema.erase(\"maxContains\");\n      }\n\n      auto inner_not{sourcemeta::core::JSON::make_object()};\n      inner_not.assign(\"not\", std::move(wrapper_inner));\n\n      if (!schema.defines(\"not\")) {\n        schema.rename(\"contains\", \"not\");\n        schema.at(\"not\").into(std::move(inner_not));\n        this->renames_.emplace_back(\n            sourcemeta::core::Pointer{\"contains\"},\n            sourcemeta::core::Pointer{\"not\", \"not\", \"contains\"});\n      } else {\n        schema.erase(\"contains\");\n        auto outer_not{sourcemeta::core::JSON::make_object()};\n        outer_not.assign(\"not\", std::move(inner_not));\n        if (schema.defines(\"allOf\") && schema.at(\"allOf\").is_array()) {\n          const auto allof_index{schema.at(\"allOf\").size()};\n          schema.at(\"allOf\").push_back(std::move(outer_not));\n          this->renames_.emplace_back(\n              sourcemeta::core::Pointer{\"contains\"},\n              sourcemeta::core::Pointer{\n                  \"allOf\",\n                  static_cast<sourcemeta::core::Pointer::Token::Index>(\n                      allof_index),\n                  \"not\", \"not\", \"contains\"});\n        } else {\n          auto allof_array{sourcemeta::core::JSON::make_array()};\n          allof_array.push_back(std::move(outer_not));\n          schema.assign(\"allOf\", std::move(allof_array));\n          this->renames_.emplace_back(\n              sourcemeta::core::Pointer{\"contains\"},\n              sourcemeta::core::Pointer{\n                  \"allOf\",\n                  static_cast<sourcemeta::core::Pointer::Token::Index>(0),\n                  \"not\", \"not\", \"contains\"});\n        }\n      }\n    }\n\n    if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string() &&\n        schema.at(\"$schema\").to_string() == DRAFT_2019_09_URL) {\n      schema.assign(\"$schema\", sourcemeta::core::JSON{DRAFT_2020_12_URL});\n      drop_dialect_overrides(schema, true);\n    } else {\n      mark_dialect_override(schema, DRAFT_2020_12_URL);\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_pointer, new_pointer] : this->renames_) {\n      const auto result{target.rebase(current.concat(old_pointer),\n                                      current.concat(new_pointer))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static constexpr std::string_view DRAFT_2019_09_URL{\n      \"https://json-schema.org/draft/2019-09/schema\"};\n  static constexpr std::string_view DRAFT_2020_12_URL{\n      \"https://json-schema.org/draft/2020-12/schema\"};\n\n  struct AnchorRename {\n    sourcemeta::core::Pointer subschema_pointer;\n    std::string new_name;\n  };\n\n  struct AnchorRefRewrite {\n    sourcemeta::core::Pointer ref_pointer;\n    std::string new_value;\n  };\n\n  mutable std::vector<\n      std::pair<sourcemeta::core::Pointer, sourcemeta::core::Pointer>>\n      renames_;\n  mutable bool resource_has_recursive_anchor_{false};\n  mutable bool is_inside_contains_wrapper_{false};\n  mutable bool descendant_has_pending_pattern_{false};\n  mutable bool document_has_unevaluated_items_{false};\n  mutable std::vector<AnchorRename> anchor_renames_;\n  mutable std::vector<AnchorRefRewrite> anchor_ref_rewrites_;\n\n  static auto compute_document_has_unevaluated_items(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaWalker &walker,\n      const sourcemeta::core::SchemaResolver &resolver) -> bool {\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n      const auto absolute{sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &subschema{sourcemeta::core::get(root, absolute)};\n      if (!subschema.is_object() || !subschema.defines(\"unevaluatedItems\")) {\n        continue;\n      }\n      const auto location_vocabularies{\n          frame.vocabularies(entry.second, resolver)};\n      const auto &keyword_metadata{\n          walker(\"unevaluatedItems\", location_vocabularies)};\n      if (keyword_metadata.type !=\n          sourcemeta::core::SchemaKeywordType::Unknown) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  static auto any_descendant_has_pending_pattern(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &location) -> bool {\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n      if (entry.second.pointer.size() <= location.pointer.size() ||\n          !entry.second.pointer.starts_with(location.pointer)) {\n        continue;\n      }\n      const auto absolute{sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &descendant{sourcemeta::core::get(root, absolute)};\n      if (has_pending_pattern(descendant, entry.second)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  static auto is_2020_12_anchor_first_char(const char character) -> bool {\n    return (character >= 'A' && character <= 'Z') ||\n           (character >= 'a' && character <= 'z') || character == '_';\n  }\n\n  static auto is_2020_12_anchor_body_char(const char character) -> bool {\n    return (character >= 'A' && character <= 'Z') ||\n           (character >= 'a' && character <= 'z') ||\n           (character >= '0' && character <= '9') || character == '_' ||\n           character == '.' || character == '-';\n  }\n\n  static auto is_valid_2020_12_anchor(const std::string_view name) -> bool {\n    if (name.empty()) {\n      return false;\n    }\n    if (!is_2020_12_anchor_first_char(name.front())) {\n      return false;\n    }\n    for (std::size_t index{1}; index < name.size(); ++index) {\n      if (!is_2020_12_anchor_body_char(name[index])) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  static auto location_inside_contains_wrapper(\n      const sourcemeta::core::SchemaFrame::Location &location) -> bool {\n    if (location.pointer.size() < 2) {\n      return false;\n    }\n    const auto &last{location.pointer.back()};\n    if (!last.is_property() || last.to_property() != \"not\") {\n      return false;\n    }\n    const auto &second_last{location.pointer.at(location.pointer.size() - 2)};\n    if (!second_last.is_property() || second_last.to_property() != \"not\") {\n      return false;\n    }\n    return true;\n  }\n\n  static auto\n  has_pending_pattern(const sourcemeta::core::JSON &subschema,\n                      const sourcemeta::core::SchemaFrame::Location &location)\n      -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n    if (!subschema.defines_any({\"$schema\", \"$recursiveAnchor\", \"$recursiveRef\",\n                                \"items\", \"additionalItems\", \"contains\"})) {\n      return false;\n    }\n    if (subschema.defines(\"$schema\") && subschema.at(\"$schema\").is_string() &&\n        subschema.at(\"$schema\").to_string() == DRAFT_2019_09_URL) {\n      return true;\n    }\n    if (subschema.defines_any(\n            {\"$recursiveAnchor\", \"$recursiveRef\", \"additionalItems\"})) {\n      return true;\n    }\n    if (subschema.defines(\"items\") && subschema.at(\"items\").is_array()) {\n      return true;\n    }\n    if (subschema.defines(\"contains\") &&\n        !location_inside_contains_wrapper(location)) {\n      return true;\n    }\n    return false;\n  }\n\n  static auto find_enclosing_resource(\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &current_location)\n      -> std::optional<std::reference_wrapper<\n          const sourcemeta::core::SchemaFrame::Location>> {\n    std::optional<\n        std::reference_wrapper<const sourcemeta::core::SchemaFrame::Location>>\n        closest;\n    for (const auto &entry : frame.locations()) {\n      const bool entry_is_resource_scope{\n          entry.second.type ==\n              sourcemeta::core::SchemaFrame::LocationType::Resource ||\n          entry.second.pointer.empty()};\n      if (!entry_is_resource_scope) {\n        continue;\n      }\n      if (entry.second.pointer.size() > current_location.pointer.size()) {\n        continue;\n      }\n      if (!current_location.pointer.starts_with(entry.second.pointer)) {\n        continue;\n      }\n      if (!closest.has_value() ||\n          entry.second.pointer.size() > closest.value().get().pointer.size()) {\n        closest = std::cref(entry.second);\n      }\n    }\n    return closest;\n  }\n\n  static auto\n  pointer_within_resource(const sourcemeta::core::WeakPointer &candidate,\n                          const sourcemeta::core::WeakPointer &resource_pointer)\n      -> bool {\n    if (!candidate.starts_with(resource_pointer)) {\n      return false;\n    }\n    return true;\n  }\n\n  auto compute_anchor_sanitization(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &resource_location) const\n      -> void {\n    this->anchor_renames_.clear();\n    this->anchor_ref_rewrites_.clear();\n\n    const auto &resource_pointer{resource_location.pointer};\n\n    std::set<std::string> existing_valid;\n    std::vector<std::pair<std::string, sourcemeta::core::WeakPointer>> invalid;\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n          sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n        continue;\n      }\n      if (entry.first.first != sourcemeta::core::SchemaReferenceType::Static) {\n        continue;\n      }\n      if (!pointer_within_resource(entry.second.pointer, resource_pointer)) {\n        continue;\n      }\n      const sourcemeta::core::URI anchor_uri{entry.first.second};\n      const auto fragment{anchor_uri.fragment()};\n      if (!fragment.has_value() || fragment.value().empty()) {\n        continue;\n      }\n      const std::string anchor_name{fragment.value()};\n      if (is_valid_2020_12_anchor(anchor_name)) {\n        existing_valid.insert(anchor_name);\n      } else {\n        invalid.emplace_back(anchor_name, entry.second.pointer);\n      }\n    }\n\n    if (invalid.empty()) {\n      return;\n    }\n\n    static const AnchorCharPolicy POLICY{\n        .is_valid_first = &is_2020_12_anchor_first_char,\n        .is_valid_body = &is_2020_12_anchor_body_char};\n\n    std::map<std::string, std::string> rename_map;\n    std::set<std::string> in_use{existing_valid};\n    for (const auto &[original, pointer] : invalid) {\n      if (rename_map.contains(original)) {\n        continue;\n      }\n      in_use.erase(original);\n      const auto sanitized{\n          sanitize_anchor_with_policy(original, in_use, POLICY)};\n      rename_map.emplace(original, sanitized);\n      in_use.insert(sanitized);\n    }\n\n    std::set<std::string> processed_pointers;\n    for (const auto &[original, pointer] : invalid) {\n      const auto pointer_str{sourcemeta::core::to_string(pointer)};\n      if (processed_pointers.contains(pointer_str)) {\n        continue;\n      }\n      processed_pointers.insert(pointer_str);\n\n      const auto absolute{sourcemeta::core::to_pointer(pointer)};\n      const auto &subschema{sourcemeta::core::get(root, absolute)};\n      if (!subschema.is_object() || !subschema.defines(\"$anchor\") ||\n          !subschema.at(\"$anchor\").is_string()) {\n        continue;\n      }\n      const auto current_value{subschema.at(\"$anchor\").to_string()};\n      const auto rename_iter{rename_map.find(current_value)};\n      if (rename_iter == rename_map.end()) {\n        continue;\n      }\n\n      const auto relative_weak{pointer.resolve_from(resource_pointer)};\n      this->anchor_renames_.push_back(\n          {sourcemeta::core::to_pointer(relative_weak), rename_iter->second});\n    }\n\n    for (const auto &reference : frame.references()) {\n      if (!pointer_within_resource(reference.first.second, resource_pointer)) {\n        continue;\n      }\n      if (!reference.second.fragment.has_value()) {\n        continue;\n      }\n      const auto &fragment{reference.second.fragment.value()};\n      if (fragment.empty() || fragment.front() == '/') {\n        continue;\n      }\n      const auto rename_iter{rename_map.find(std::string{fragment})};\n      if (rename_iter == rename_map.end()) {\n        continue;\n      }\n\n      sourcemeta::core::URI ref_uri{reference.second.original};\n      ref_uri.fragment(rename_iter->second);\n      const auto new_value{ref_uri.recompose()};\n\n      const auto relative_weak{\n          reference.first.second.resolve_from(resource_pointer)};\n      this->anchor_ref_rewrites_.push_back(\n          {sourcemeta::core::to_pointer(relative_weak), new_value});\n    }\n  }\n\n  static auto enclosing_resource_has_pending_sanitization(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &current_location) -> bool {\n    const auto closest{find_enclosing_resource(frame, current_location)};\n    if (!closest.has_value()) {\n      return false;\n    }\n    const auto &resource_pointer{closest.value().get().pointer};\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n          sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n        continue;\n      }\n      if (entry.first.first != sourcemeta::core::SchemaReferenceType::Static) {\n        continue;\n      }\n      if (!pointer_within_resource(entry.second.pointer, resource_pointer)) {\n        continue;\n      }\n      const sourcemeta::core::URI anchor_uri{entry.first.second};\n      const auto fragment{anchor_uri.fragment()};\n      if (!fragment.has_value() || fragment.value().empty()) {\n        continue;\n      }\n      if (!is_valid_2020_12_anchor(fragment.value())) {\n        const auto absolute{sourcemeta::core::to_pointer(entry.second.pointer)};\n        const auto &subschema{sourcemeta::core::get(root, absolute)};\n        if (subschema.is_object() && subschema.defines(\"$anchor\") &&\n            subschema.at(\"$anchor\").is_string() &&\n            subschema.at(\"$anchor\").to_string() == fragment.value()) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  auto apply_anchor_sanitization(sourcemeta::core::JSON &schema) const -> void {\n    for (const auto &rename : this->anchor_renames_) {\n      auto &target{sourcemeta::core::get(schema, rename.subschema_pointer)};\n      target.at(\"$anchor\").into(sourcemeta::core::JSON{rename.new_name});\n    }\n    for (const auto &rewrite : this->anchor_ref_rewrites_) {\n      auto &target{sourcemeta::core::get(schema, rewrite.ref_pointer)};\n      target.into(sourcemeta::core::JSON{rewrite.new_value});\n    }\n  }\n\n  static auto compute_resource_has_recursive_anchor(\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame,\n      const sourcemeta::core::SchemaFrame::Location &current_location) -> bool {\n    const auto closest{find_enclosing_resource(frame, current_location)};\n    if (!closest.has_value()) {\n      return false;\n    }\n\n    const auto &resource_pointer{closest.value().get().pointer};\n    std::set<std::string> seen;\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n      if (!entry.second.pointer.starts_with(resource_pointer)) {\n        continue;\n      }\n      if (entry.second.type ==\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.pointer.size() > resource_pointer.size()) {\n        continue;\n      }\n      const auto pointer_str{sourcemeta::core::to_string(entry.second.pointer)};\n      if (seen.contains(pointer_str)) {\n        continue;\n      }\n      seen.insert(pointer_str);\n\n      const auto absolute{sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &subschema{sourcemeta::core::get(root, absolute)};\n      if (!subschema.is_object()) {\n        continue;\n      }\n      if (subschema.defines(\"$recursiveAnchor\") &&\n          subschema.at(\"$recursiveAnchor\").is_boolean() &&\n          subschema.at(\"$recursiveAnchor\").to_boolean()) {\n        return true;\n      }\n    }\n    return false;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_dialect_override_cleanup.h",
    "content": "class UpgradeDialectOverrideCleanup final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UpgradeDialectOverrideCleanup()\n      : SchemaTransformRule{\"upgrade_dialect_override_cleanup\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &,\n            const sourcemeta::core::Vocabularies &,\n            const sourcemeta::core::SchemaFrame &,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(location.pointer.empty() && schema.is_object());\n\n    const auto *override_value{schema.try_at(DIALECT_OVERRIDE_KEYWORD)};\n    ONLY_CONTINUE_IF(override_value != nullptr && override_value->is_string());\n\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    if (!schema.defines(\"$schema\")) {\n      sourcemeta::core::JSON dialect_value{\n          schema.at(DIALECT_OVERRIDE_KEYWORD).to_string()};\n\n      bool placed{false};\n      for (const auto &entry : schema.as_object()) {\n        if (entry.first != DIALECT_OVERRIDE_KEYWORD) {\n          schema.try_assign_before(\"$schema\", dialect_value, entry.first);\n          placed = true;\n          break;\n        }\n      }\n\n      if (!placed) {\n        schema.assign(\"$schema\", std::move(dialect_value));\n      }\n    }\n\n    drop_dialect_overrides(schema, true);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_draft_3_to_draft_4.h",
    "content": "class UpgradeDraft3ToDraft4 final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UpgradeDraft3ToDraft4()\n      : SchemaTransformRule{\"upgrade_draft_3_to_draft_4\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_3) &&\n        schema.is_object());\n\n    const bool root_via_default_dialect =\n        location.pointer.empty() && !schema.defines(\"$schema\");\n\n    ONLY_CONTINUE_IF(has_pending_draft_3_pattern(schema) ||\n                     root_via_default_dialect);\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      if (!is_strict_descendant(location.pointer, entry.second.pointer)) {\n        continue;\n      }\n\n      const auto entry_pointer{\n          sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &entry_schema{sourcemeta::core::get(root, entry_pointer)};\n\n      if (entry_schema.is_object() && entry_schema.defines(\"$ref\")) {\n        continue;\n      }\n\n      if (has_pending_draft_3_pattern(entry_schema)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    rewrite_type_any(schema);\n    rewrite_type_array_with_subschemas(schema);\n    rewrite_disallow(schema);\n    rewrite_extends(schema);\n    rewrite_divisible_by(schema);\n    rewrite_required_property_booleans(schema);\n    rewrite_dependencies_string_form(schema);\n    rewrite_format(schema);\n\n    if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string() &&\n        schema.at(\"$schema\").to_string() == DRAFT_3_URL) {\n      schema.assign(\"$schema\", sourcemeta::core::JSON{DRAFT_4_URL});\n      drop_dialect_overrides(schema, true);\n    } else {\n      mark_dialect_override(schema, DRAFT_4_URL);\n    }\n  }\n\nprivate:\n  static inline const std::string DRAFT_3_URL{\n      \"http://json-schema.org/draft-03/schema#\"};\n  static inline const std::string DRAFT_4_URL{\n      \"http://json-schema.org/draft-04/schema#\"};\n\n  static auto\n  has_pending_draft_3_pattern(const sourcemeta::core::JSON &subschema) -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n\n    if (subschema.defines(\"$schema\") && subschema.at(\"$schema\").is_string() &&\n        subschema.at(\"$schema\").to_string() == DRAFT_3_URL) {\n      return true;\n    }\n\n    const auto *type_value{subschema.try_at(\"type\")};\n    if (type_value != nullptr) {\n      if (type_value->is_string() && type_value->to_string() == \"any\") {\n        return true;\n      }\n      if (type_value->is_array()) {\n        for (const auto &element : type_value->as_array()) {\n          if (element.is_string() && element.to_string() == \"any\") {\n            return true;\n          }\n          if (element.is_object()) {\n            return true;\n          }\n        }\n      }\n    }\n\n    const auto *disallow_value{subschema.try_at(\"disallow\")};\n    if (disallow_value != nullptr &&\n        (disallow_value->is_string() || disallow_value->is_array() ||\n         disallow_value->is_object())) {\n      return true;\n    }\n\n    const auto *extends_value{subschema.try_at(\"extends\")};\n    if (extends_value != nullptr &&\n        (extends_value->is_array() || extends_value->is_object())) {\n      return true;\n    }\n\n    if (subschema.defines(\"divisibleBy\")) {\n      return true;\n    }\n\n    const auto *properties{subschema.try_at(\"properties\")};\n    if (properties != nullptr && properties->is_object()) {\n      for (const auto &entry : properties->as_object()) {\n        if (entry.second.is_object() && entry.second.defines(\"required\") &&\n            entry.second.at(\"required\").is_boolean()) {\n          return true;\n        }\n      }\n    }\n\n    const auto *dependencies{subschema.try_at(\"dependencies\")};\n    if (dependencies != nullptr && dependencies->is_object()) {\n      for (const auto &entry : dependencies->as_object()) {\n        if (entry.second.is_string()) {\n          return true;\n        }\n      }\n    }\n\n    if (has_renamable_draft_3_format(subschema)) {\n      return true;\n    }\n\n    return false;\n  }\n\n  static auto\n  has_renamable_draft_3_format(const sourcemeta::core::JSON &subschema)\n      -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n    const auto *format_value{subschema.try_at(\"format\")};\n    if (format_value == nullptr || !format_value->is_string()) {\n      return false;\n    }\n    const auto &name{format_value->to_string()};\n    return name == \"host-name\" || name == \"ip-address\";\n  }\n\n  static auto rewrite_type_any(sourcemeta::core::JSON &schema) -> void {\n    if (!schema.defines(\"type\")) {\n      return;\n    }\n    auto &type_value{schema.at(\"type\")};\n    if (type_value.is_string()) {\n      if (type_value.to_string() == \"any\") {\n        schema.erase(\"type\");\n      }\n      return;\n    }\n    if (!type_value.is_array()) {\n      return;\n    }\n    bool collapses{false};\n    for (const auto &element : type_value.as_array()) {\n      if (element.is_string() && element.to_string() == \"any\") {\n        collapses = true;\n        break;\n      }\n    }\n    if (collapses) {\n      schema.erase(\"type\");\n    }\n  }\n\n  static auto rewrite_type_array_with_subschemas(sourcemeta::core::JSON &schema)\n      -> void {\n    if (!schema.defines(\"type\")) {\n      return;\n    }\n    auto &type_value{schema.at(\"type\")};\n    if (!type_value.is_array()) {\n      return;\n    }\n    bool has_subschema{false};\n    for (const auto &element : type_value.as_array()) {\n      if (element.is_object()) {\n        has_subschema = true;\n        break;\n      }\n    }\n    if (!has_subschema) {\n      return;\n    }\n\n    auto branches{sourcemeta::core::JSON::make_array()};\n    for (const auto &element : type_value.as_array()) {\n      if (element.is_string()) {\n        auto branch{sourcemeta::core::JSON::make_object()};\n        branch.assign(\"type\", element);\n        branches.push_back(std::move(branch));\n      } else if (element.is_object()) {\n        branches.push_back(element);\n      }\n    }\n    schema.erase(\"type\");\n    schema.assign(\"anyOf\", std::move(branches));\n  }\n\n  static auto type_string_to_branch(const std::string &type_name)\n      -> sourcemeta::core::JSON {\n    auto branch{sourcemeta::core::JSON::make_object()};\n    branch.assign(\"type\", sourcemeta::core::JSON{type_name});\n    return branch;\n  }\n\n  static auto rewrite_disallow(sourcemeta::core::JSON &schema) -> void {\n    if (!schema.defines(\"disallow\") || schema.defines(\"not\")) {\n      return;\n    }\n\n    const auto &disallow{schema.at(\"disallow\")};\n    if (!disallow.is_string() && !disallow.is_array() &&\n        !disallow.is_object()) {\n      return;\n    }\n\n    if (disallow.is_string() && disallow.to_string() == \"any\") {\n      schema.erase(\"disallow\");\n      schema.assign(\"not\", sourcemeta::core::JSON::make_object());\n      return;\n    }\n\n    if (disallow.is_array()) {\n      for (const auto &element : disallow.as_array()) {\n        if (element.is_string() && element.to_string() == \"any\") {\n          schema.erase(\"disallow\");\n          schema.assign(\"not\", sourcemeta::core::JSON::make_object());\n          return;\n        }\n      }\n    }\n\n    auto negated{sourcemeta::core::JSON::make_object()};\n    if (disallow.is_string()) {\n      negated.assign(\"type\", disallow);\n    } else if (disallow.is_array()) {\n      bool has_subschema{false};\n      for (const auto &element : disallow.as_array()) {\n        if (element.is_object()) {\n          has_subschema = true;\n          break;\n        }\n      }\n      if (!has_subschema) {\n        negated.assign(\"type\", disallow);\n      } else {\n        auto branches{sourcemeta::core::JSON::make_array()};\n        for (const auto &element : disallow.as_array()) {\n          if (element.is_string()) {\n            branches.push_back(type_string_to_branch(element.to_string()));\n          } else if (element.is_object()) {\n            branches.push_back(element);\n          }\n        }\n        negated.assign(\"anyOf\", std::move(branches));\n      }\n    } else {\n      negated = disallow;\n    }\n\n    schema.erase(\"disallow\");\n    schema.assign(\"not\", std::move(negated));\n  }\n\n  static auto rewrite_extends(sourcemeta::core::JSON &schema) -> void {\n    if (!schema.defines(\"extends\") || schema.defines(\"allOf\")) {\n      return;\n    }\n\n    const auto &extends{schema.at(\"extends\")};\n    if (!extends.is_array() && !extends.is_object()) {\n      return;\n    }\n\n    auto value{extends};\n    schema.erase(\"extends\");\n\n    if (value.is_array()) {\n      schema.assign(\"allOf\", std::move(value));\n      return;\n    }\n\n    auto array{sourcemeta::core::JSON::make_array()};\n    array.push_back(std::move(value));\n    schema.assign(\"allOf\", std::move(array));\n  }\n\n  static auto rewrite_divisible_by(sourcemeta::core::JSON &schema) -> void {\n    if (!schema.defines(\"divisibleBy\") || schema.defines(\"multipleOf\")) {\n      return;\n    }\n    schema.rename(\"divisibleBy\", \"multipleOf\");\n  }\n\n  static auto rewrite_required_property_booleans(sourcemeta::core::JSON &schema)\n      -> void {\n    if (!schema.defines(\"properties\") || !schema.at(\"properties\").is_object()) {\n      return;\n    }\n\n    std::vector<std::string> newly_required;\n    auto &properties{schema.at(\"properties\")};\n    std::vector<std::string> property_keys;\n    property_keys.reserve(properties.size());\n    for (const auto &entry : properties.as_object()) {\n      property_keys.push_back(entry.first);\n    }\n\n    for (const auto &key : property_keys) {\n      auto &property{properties.at(key)};\n      if (!property.is_object() || !property.defines(\"required\")) {\n        continue;\n      }\n      const auto &required_value{property.at(\"required\")};\n      if (!required_value.is_boolean()) {\n        continue;\n      }\n      const bool is_required{required_value.to_boolean()};\n      property.erase(\"required\");\n      if (is_required) {\n        newly_required.push_back(key);\n      }\n    }\n\n    if (newly_required.empty()) {\n      return;\n    }\n\n    if (!schema.defines(\"required\") || !schema.at(\"required\").is_array()) {\n      auto fresh{sourcemeta::core::JSON::make_array()};\n      for (const auto &name : newly_required) {\n        fresh.push_back(sourcemeta::core::JSON{name});\n      }\n      schema.try_assign_before(\"required\", fresh, \"properties\");\n      return;\n    }\n\n    auto &existing{schema.at(\"required\")};\n    std::set<std::string> already;\n    for (const auto &item : existing.as_array()) {\n      if (item.is_string()) {\n        already.insert(item.to_string());\n      }\n    }\n    for (const auto &name : newly_required) {\n      if (already.contains(name)) {\n        continue;\n      }\n      existing.push_back(sourcemeta::core::JSON{name});\n      already.insert(name);\n    }\n  }\n\n  static auto rewrite_dependencies_string_form(sourcemeta::core::JSON &schema)\n      -> void {\n    if (!schema.defines(\"dependencies\") ||\n        !schema.at(\"dependencies\").is_object()) {\n      return;\n    }\n    auto &dependencies{schema.at(\"dependencies\")};\n    std::vector<std::string> string_keys;\n    for (const auto &entry : dependencies.as_object()) {\n      if (entry.second.is_string()) {\n        string_keys.push_back(entry.first);\n      }\n    }\n    for (const auto &key : string_keys) {\n      const auto value{dependencies.at(key).to_string()};\n      auto array{sourcemeta::core::JSON::make_array()};\n      array.push_back(sourcemeta::core::JSON{value});\n      dependencies.assign(key, std::move(array));\n    }\n  }\n\n  static auto rewrite_format(sourcemeta::core::JSON &schema) -> void {\n    if (!schema.defines(\"format\")) {\n      return;\n    }\n    auto &format_value{schema.at(\"format\")};\n    if (!format_value.is_string()) {\n      return;\n    }\n    const auto &name{format_value.to_string()};\n    if (name == \"host-name\") {\n      schema.assign(\"format\", sourcemeta::core::JSON{\"hostname\"});\n    } else if (name == \"ip-address\") {\n      schema.assign(\"format\", sourcemeta::core::JSON{\"ipv4\"});\n    }\n  }\n\n  static auto\n  is_strict_descendant(const sourcemeta::core::WeakPointer &ancestor,\n                       const sourcemeta::core::WeakPointer &candidate) -> bool {\n    if (candidate.size() <= ancestor.size()) {\n      return false;\n    }\n    for (std::size_t index{0}; index < ancestor.size(); ++index) {\n      if (!(ancestor.at(index) == candidate.at(index))) {\n        return false;\n      }\n    }\n    return true;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_draft_4_to_draft_6.h",
    "content": "class UpgradeDraft4ToDraft6 final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UpgradeDraft4ToDraft6()\n      : SchemaTransformRule{\"upgrade_draft_4_to_draft_6\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_4) &&\n        schema.is_object());\n\n    const bool is_resource_scope =\n        location.type ==\n            sourcemeta::core::SchemaFrame::LocationType::Resource ||\n        location.pointer.empty();\n\n    const bool sanitization_branch =\n        is_resource_scope && resource_needs_anchor_sanitization(schema);\n\n    const bool other_branch = has_pending_draft_4_pattern(schema);\n\n    const bool root_via_default_dialect =\n        location.pointer.empty() && !schema.defines(\"$schema\");\n\n    ONLY_CONTINUE_IF(sanitization_branch || other_branch ||\n                     root_via_default_dialect);\n\n    if (!sanitization_branch && other_branch &&\n        enclosing_resource_has_pending_sanitization(location, root, frame)) {\n      return false;\n    }\n\n    if (!sanitization_branch) {\n      for (const auto &entry : frame.locations()) {\n        if (entry.second.type !=\n                sourcemeta::core::SchemaFrame::LocationType::Resource &&\n            entry.second.type !=\n                sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n          continue;\n        }\n\n        if (!is_strict_descendant(location.pointer, entry.second.pointer)) {\n          continue;\n        }\n\n        const auto entry_pointer{\n            sourcemeta::core::to_pointer(entry.second.pointer)};\n        const auto &entry_schema{sourcemeta::core::get(root, entry_pointer)};\n\n        if (entry_schema.is_object() && entry_schema.defines(\"$ref\")) {\n          continue;\n        }\n\n        if (has_pending_draft_4_pattern(entry_schema)) {\n          return false;\n        }\n      }\n    }\n\n    if (sanitization_branch) {\n      return Result{std::vector<sourcemeta::core::Pointer>{},\n                    std::string{\"sanitize\"}};\n    }\n\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &result) const\n      -> void override {\n    if (result.description.has_value()) {\n      const auto renames{build_resource_rename_map(schema)};\n      std::optional<std::string> resource_base;\n      if (schema.defines(\"id\") && schema.at(\"id\").is_string()) {\n        const sourcemeta::core::URI uri{schema.at(\"id\").to_string()};\n        const auto without_fragment{uri.recompose_without_fragment()};\n        if (without_fragment.has_value() && !without_fragment.value().empty()) {\n          resource_base = without_fragment.value();\n        }\n      }\n      apply_anchor_renames_in_resource(schema, true, renames, resource_base);\n      if (resource_has_descendant_with_pending_pattern(schema, true)) {\n        return;\n      }\n    }\n\n    if (schema.defines(\"id\") && schema.at(\"id\").is_string() &&\n        !schema.defines(\"$id\")) {\n      schema.rename(\"id\", \"$id\");\n    }\n\n    if (schema.defines(\"exclusiveMinimum\") &&\n        schema.at(\"exclusiveMinimum\").is_boolean()) {\n      const bool exclusive{schema.at(\"exclusiveMinimum\").to_boolean()};\n      schema.erase(\"exclusiveMinimum\");\n      if (exclusive && schema.defines(\"minimum\") &&\n          schema.at(\"minimum\").is_number()) {\n        schema.rename(\"minimum\", \"exclusiveMinimum\");\n      }\n    }\n\n    if (schema.defines(\"exclusiveMaximum\") &&\n        schema.at(\"exclusiveMaximum\").is_boolean()) {\n      const bool exclusive{schema.at(\"exclusiveMaximum\").to_boolean()};\n      schema.erase(\"exclusiveMaximum\");\n      if (exclusive && schema.defines(\"maximum\") &&\n          schema.at(\"maximum\").is_number()) {\n        schema.rename(\"maximum\", \"exclusiveMaximum\");\n      }\n    }\n\n    if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string() &&\n        schema.at(\"$schema\").to_string() == DRAFT_4_URL) {\n      schema.assign(\"$schema\", sourcemeta::core::JSON{DRAFT_6_URL});\n      drop_dialect_overrides(schema, true);\n    } else {\n      mark_dialect_override(schema, DRAFT_6_URL);\n    }\n  }\n\nprivate:\n  static inline const std::string DRAFT_4_URL{\n      \"http://json-schema.org/draft-04/schema#\"};\n  static inline const std::string DRAFT_6_URL{\n      \"http://json-schema.org/draft-06/schema#\"};\n  static inline const std::array<std::string_view, 4> PROMOTED_KEYWORDS{\n      {\"const\", \"contains\", \"propertyNames\", \"examples\"}};\n\n  static auto\n  has_pending_draft_4_pattern(const sourcemeta::core::JSON &subschema) -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n\n    if (subschema.defines(\"$schema\") && subschema.at(\"$schema\").is_string() &&\n        subschema.at(\"$schema\").to_string() == DRAFT_4_URL) {\n      return true;\n    }\n\n    if (subschema.defines(\"id\") && subschema.at(\"id\").is_string() &&\n        !subschema.defines(\"$id\")) {\n      const auto fragment{extract_id_fragment(subschema.at(\"id\"))};\n      if (!fragment.has_value() || fragment.value().empty() ||\n          is_strict_plain_name(fragment.value())) {\n        return true;\n      }\n    }\n\n    const auto *exclusive_minimum{subschema.try_at(\"exclusiveMinimum\")};\n    if (exclusive_minimum != nullptr && exclusive_minimum->is_boolean()) {\n      return true;\n    }\n\n    const auto *exclusive_maximum{subschema.try_at(\"exclusiveMaximum\")};\n    if (exclusive_maximum != nullptr && exclusive_maximum->is_boolean()) {\n      return true;\n    }\n\n    for (const auto &keyword : PROMOTED_KEYWORDS) {\n      if (subschema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  static auto\n  is_strict_descendant(const sourcemeta::core::WeakPointer &ancestor,\n                       const sourcemeta::core::WeakPointer &candidate) -> bool {\n    if (candidate.size() <= ancestor.size()) {\n      return false;\n    }\n    for (std::size_t index{0}; index < ancestor.size(); ++index) {\n      if (!(ancestor.at(index) == candidate.at(index))) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  static auto is_strict_plain_name_first_char(const char character) -> bool {\n    return (character >= 'A' && character <= 'Z') ||\n           (character >= 'a' && character <= 'z');\n  }\n\n  static auto is_strict_plain_name_body_char(const char character) -> bool {\n    return (character >= 'A' && character <= 'Z') ||\n           (character >= 'a' && character <= 'z') ||\n           (character >= '0' && character <= '9') || character == '_' ||\n           character == ':' || character == '.' || character == '-';\n  }\n\n  static auto is_strict_plain_name(const std::string_view fragment) -> bool {\n    if (fragment.empty()) {\n      return false;\n    }\n    if (!is_strict_plain_name_first_char(fragment.front())) {\n      return false;\n    }\n    for (std::size_t index{1}; index < fragment.size(); ++index) {\n      if (!is_strict_plain_name_body_char(fragment[index])) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  static auto sanitize_anchor_name(const std::string_view original,\n                                   const std::set<std::string> &existing_names)\n      -> std::string {\n    static const AnchorCharPolicy POLICY{\n        .is_valid_first = &is_strict_plain_name_first_char,\n        .is_valid_body = &is_strict_plain_name_body_char};\n    return sanitize_anchor_with_policy(original, existing_names, POLICY);\n  }\n\n  static auto extract_id_fragment(const sourcemeta::core::JSON &id_value)\n      -> std::optional<std::string> {\n    if (!id_value.is_string()) {\n      return std::nullopt;\n    }\n    const sourcemeta::core::URI uri{id_value.to_string()};\n    const auto fragment{uri.fragment()};\n    if (!fragment.has_value()) {\n      return std::nullopt;\n    }\n    return std::string{fragment.value()};\n  }\n\n  static auto\n  subschema_id_fragment_is_invalid(const sourcemeta::core::JSON &subschema)\n      -> bool {\n    if (!subschema.is_object() || !subschema.defines(\"id\") ||\n        !subschema.at(\"id\").is_string()) {\n      return false;\n    }\n    const auto fragment{extract_id_fragment(subschema.at(\"id\"))};\n    if (!fragment.has_value() || fragment.value().empty()) {\n      return false;\n    }\n    return !is_strict_plain_name(fragment.value());\n  }\n\n  static auto\n  subschema_starts_sub_resource(const sourcemeta::core::JSON &subschema)\n      -> bool {\n    if (!subschema.is_object() || !subschema.defines(\"id\") ||\n        !subschema.at(\"id\").is_string()) {\n      return false;\n    }\n    const sourcemeta::core::URI uri{subschema.at(\"id\").to_string()};\n    if (uri.is_fragment_only()) {\n      return false;\n    }\n    const auto without_fragment{uri.recompose_without_fragment()};\n    return without_fragment.has_value() && !without_fragment.value().empty();\n  }\n\n  static auto collect_resource_anchors(const sourcemeta::core::JSON &subschema,\n                                       const bool is_root,\n                                       std::set<std::string> &result) -> void {\n    if (!subschema.is_object()) {\n      return;\n    }\n\n    if (!is_root && subschema_starts_sub_resource(subschema)) {\n      return;\n    }\n\n    if (subschema.defines(\"id\") && subschema.at(\"id\").is_string()) {\n      const auto fragment{extract_id_fragment(subschema.at(\"id\"))};\n      if (fragment.has_value() && !fragment.value().empty()) {\n        result.insert(fragment.value());\n      }\n    }\n\n    for (const std::string_view object_keyword :\n         {\"definitions\", \"properties\", \"patternProperties\", \"dependencies\"}) {\n      if (subschema.defines(object_keyword) &&\n          subschema.at(object_keyword).is_object()) {\n        for (const auto &entry : subschema.at(object_keyword).as_object()) {\n          collect_resource_anchors(entry.second, false, result);\n        }\n      }\n    }\n\n    for (const std::string_view array_keyword : {\"allOf\", \"anyOf\", \"oneOf\"}) {\n      if (subschema.defines(array_keyword) &&\n          subschema.at(array_keyword).is_array()) {\n        for (const auto &item : subschema.at(array_keyword).as_array()) {\n          collect_resource_anchors(item, false, result);\n        }\n      }\n    }\n\n    for (const std::string_view single_keyword :\n         {\"additionalProperties\", \"additionalItems\", \"not\"}) {\n      if (subschema.defines(single_keyword)) {\n        collect_resource_anchors(subschema.at(single_keyword), false, result);\n      }\n    }\n\n    if (subschema.defines(\"items\")) {\n      const auto &items{subschema.at(\"items\")};\n      if (items.is_array()) {\n        for (const auto &item : items.as_array()) {\n          collect_resource_anchors(item, false, result);\n        }\n      } else {\n        collect_resource_anchors(items, false, result);\n      }\n    }\n  }\n\n  static auto collect_invalid_anchors(const sourcemeta::core::JSON &subschema,\n                                      const bool is_root,\n                                      std::vector<std::string> &result)\n      -> void {\n    if (!subschema.is_object()) {\n      return;\n    }\n\n    if (!is_root && subschema_starts_sub_resource(subschema)) {\n      return;\n    }\n\n    if (subschema_id_fragment_is_invalid(subschema)) {\n      const auto fragment{extract_id_fragment(subschema.at(\"id\"))};\n      result.push_back(fragment.value());\n    }\n\n    for (const std::string_view object_keyword :\n         {\"definitions\", \"properties\", \"patternProperties\", \"dependencies\"}) {\n      if (subschema.defines(object_keyword) &&\n          subschema.at(object_keyword).is_object()) {\n        for (const auto &entry : subschema.at(object_keyword).as_object()) {\n          collect_invalid_anchors(entry.second, false, result);\n        }\n      }\n    }\n\n    for (const std::string_view array_keyword : {\"allOf\", \"anyOf\", \"oneOf\"}) {\n      if (subschema.defines(array_keyword) &&\n          subschema.at(array_keyword).is_array()) {\n        for (const auto &item : subschema.at(array_keyword).as_array()) {\n          collect_invalid_anchors(item, false, result);\n        }\n      }\n    }\n\n    for (const std::string_view single_keyword :\n         {\"additionalProperties\", \"additionalItems\", \"not\"}) {\n      if (subschema.defines(single_keyword)) {\n        collect_invalid_anchors(subschema.at(single_keyword), false, result);\n      }\n    }\n\n    if (subschema.defines(\"items\")) {\n      const auto &items{subschema.at(\"items\")};\n      if (items.is_array()) {\n        for (const auto &item : items.as_array()) {\n          collect_invalid_anchors(item, false, result);\n        }\n      } else {\n        collect_invalid_anchors(items, false, result);\n      }\n    }\n  }\n\n  static auto\n  build_resource_rename_map(const sourcemeta::core::JSON &resource_root)\n      -> std::map<std::string, std::string> {\n    std::set<std::string> existing;\n    collect_resource_anchors(resource_root, true, existing);\n\n    std::vector<std::string> invalid;\n    collect_invalid_anchors(resource_root, true, invalid);\n\n    std::map<std::string, std::string> renames;\n    std::set<std::string> in_use{existing};\n    for (const auto &original : invalid) {\n      if (renames.contains(original)) {\n        continue;\n      }\n      in_use.erase(original);\n      const auto sanitized{sanitize_anchor_name(original, in_use)};\n      renames.emplace(original, sanitized);\n      in_use.insert(sanitized);\n    }\n    return renames;\n  }\n\n  static auto resource_has_descendant_with_pending_pattern(\n      const sourcemeta::core::JSON &subschema, const bool is_root) -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n    if (!is_root && subschema_starts_sub_resource(subschema)) {\n      return false;\n    }\n    if (!is_root && has_pending_draft_4_pattern(subschema)) {\n      return true;\n    }\n\n    for (const std::string_view object_keyword :\n         {\"definitions\", \"properties\", \"patternProperties\", \"dependencies\"}) {\n      if (subschema.defines(object_keyword) &&\n          subschema.at(object_keyword).is_object()) {\n        for (const auto &entry : subschema.at(object_keyword).as_object()) {\n          if (resource_has_descendant_with_pending_pattern(entry.second,\n                                                           false)) {\n            return true;\n          }\n        }\n      }\n    }\n\n    for (const std::string_view array_keyword : {\"allOf\", \"anyOf\", \"oneOf\"}) {\n      if (subschema.defines(array_keyword) &&\n          subschema.at(array_keyword).is_array()) {\n        for (const auto &item : subschema.at(array_keyword).as_array()) {\n          if (resource_has_descendant_with_pending_pattern(item, false)) {\n            return true;\n          }\n        }\n      }\n    }\n\n    for (const std::string_view single_keyword :\n         {\"additionalProperties\", \"additionalItems\", \"not\"}) {\n      if (subschema.defines(single_keyword)) {\n        if (resource_has_descendant_with_pending_pattern(\n                subschema.at(single_keyword), false)) {\n          return true;\n        }\n      }\n    }\n\n    if (subschema.defines(\"items\")) {\n      const auto &items{subschema.at(\"items\")};\n      if (items.is_array()) {\n        for (const auto &item : items.as_array()) {\n          if (resource_has_descendant_with_pending_pattern(item, false)) {\n            return true;\n          }\n        }\n      } else if (resource_has_descendant_with_pending_pattern(items, false)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  static auto apply_anchor_renames_in_resource(\n      sourcemeta::core::JSON &subschema, const bool is_root,\n      const std::map<std::string, std::string> &renames,\n      const std::optional<std::string> &resource_base) -> void {\n    if (!subschema.is_object()) {\n      return;\n    }\n\n    if (!is_root && subschema_starts_sub_resource(subschema)) {\n      return;\n    }\n\n    if (subschema.defines(\"id\") && subschema.at(\"id\").is_string()) {\n      const auto &id_string{subschema.at(\"id\").to_string()};\n      const sourcemeta::core::URI uri{id_string};\n      const auto fragment{uri.fragment()};\n      if (fragment.has_value() && !fragment.value().empty()) {\n        const auto rename_iter{renames.find(std::string{fragment.value()})};\n        if (rename_iter != renames.end()) {\n          if (uri.is_fragment_only()) {\n            subschema.assign(\"id\",\n                             sourcemeta::core::JSON{\"#\" + rename_iter->second});\n          } else {\n            const auto without_fragment{uri.recompose_without_fragment()};\n            subschema.assign(\n                \"id\", sourcemeta::core::JSON{(without_fragment.has_value()\n                                                  ? without_fragment.value()\n                                                  : std::string{}) +\n                                             \"#\" + rename_iter->second});\n          }\n        }\n      }\n    }\n\n    if (subschema.defines(\"$ref\") && subschema.at(\"$ref\").is_string()) {\n      const auto &ref_string{subschema.at(\"$ref\").to_string()};\n      const sourcemeta::core::URI ref_uri{ref_string};\n      const auto fragment{ref_uri.fragment()};\n      if (fragment.has_value() &&\n          renames.contains(std::string{fragment.value()})) {\n        const auto without_fragment{ref_uri.recompose_without_fragment()};\n        const bool same_base =\n            ref_uri.is_fragment_only() ||\n            (resource_base.has_value() && without_fragment.has_value() &&\n             without_fragment.value() == resource_base.value());\n        if (same_base) {\n          const auto &new_name{renames.at(std::string{fragment.value()})};\n          subschema.assign(\n              \"$ref\", sourcemeta::core::JSON{\n                          ref_uri.is_fragment_only()\n                              ? \"#\" + new_name\n                              : (without_fragment.value() + \"#\" + new_name)});\n        }\n      }\n    }\n\n    for (const std::string_view object_keyword :\n         {\"definitions\", \"properties\", \"patternProperties\", \"dependencies\"}) {\n      if (subschema.defines(object_keyword) &&\n          subschema.at(object_keyword).is_object()) {\n        std::vector<std::string> keys;\n        keys.reserve(subschema.at(object_keyword).size());\n        for (const auto &entry : subschema.at(object_keyword).as_object()) {\n          keys.push_back(entry.first);\n        }\n        for (const auto &key : keys) {\n          apply_anchor_renames_in_resource(subschema.at(object_keyword).at(key),\n                                           false, renames, resource_base);\n        }\n      }\n    }\n\n    for (const std::string_view array_keyword : {\"allOf\", \"anyOf\", \"oneOf\"}) {\n      if (subschema.defines(array_keyword) &&\n          subschema.at(array_keyword).is_array()) {\n        auto &array_value{subschema.at(array_keyword)};\n        for (std::size_t index{0}; index < array_value.size(); ++index) {\n          apply_anchor_renames_in_resource(array_value.at(index), false,\n                                           renames, resource_base);\n        }\n      }\n    }\n\n    for (const std::string_view single_keyword :\n         {\"additionalProperties\", \"additionalItems\", \"not\"}) {\n      if (subschema.defines(single_keyword)) {\n        apply_anchor_renames_in_resource(subschema.at(single_keyword), false,\n                                         renames, resource_base);\n      }\n    }\n\n    if (subschema.defines(\"items\")) {\n      auto &items{subschema.at(\"items\")};\n      if (items.is_array()) {\n        for (std::size_t index{0}; index < items.size(); ++index) {\n          apply_anchor_renames_in_resource(items.at(index), false, renames,\n                                           resource_base);\n        }\n      } else {\n        apply_anchor_renames_in_resource(items, false, renames, resource_base);\n      }\n    }\n  }\n\n  static auto resource_needs_anchor_sanitization(\n      const sourcemeta::core::JSON &resource_root) -> bool {\n    std::vector<std::string> invalid;\n    collect_invalid_anchors(resource_root, true, invalid);\n    return !invalid.empty();\n  }\n\n  static auto enclosing_resource_has_pending_sanitization(\n      const sourcemeta::core::SchemaFrame::Location &location,\n      const sourcemeta::core::JSON &root,\n      const sourcemeta::core::SchemaFrame &frame) -> bool {\n    std::optional<sourcemeta::core::WeakPointer> closest;\n    for (const auto &entry : frame.locations()) {\n      const bool entry_is_resource_scope =\n          entry.second.type ==\n              sourcemeta::core::SchemaFrame::LocationType::Resource ||\n          entry.second.pointer.empty();\n      if (!entry_is_resource_scope) {\n        continue;\n      }\n      if (entry.second.pointer.size() > location.pointer.size()) {\n        continue;\n      }\n      bool is_ancestor{true};\n      for (std::size_t index{0}; index < entry.second.pointer.size(); ++index) {\n        if (!(entry.second.pointer.at(index) == location.pointer.at(index))) {\n          is_ancestor = false;\n          break;\n        }\n      }\n      if (!is_ancestor) {\n        continue;\n      }\n      if (!closest.has_value() ||\n          entry.second.pointer.size() > closest.value().size()) {\n        closest = entry.second.pointer;\n      }\n    }\n    if (!closest.has_value()) {\n      return false;\n    }\n    const auto closest_pointer{sourcemeta::core::to_pointer(closest.value())};\n    const auto &resource_schema{sourcemeta::core::get(root, closest_pointer)};\n    return resource_needs_anchor_sanitization(resource_schema);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_draft_6_to_draft_7.h",
    "content": "class UpgradeDraft6ToDraft7 final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UpgradeDraft6ToDraft7()\n      : SchemaTransformRule{\"upgrade_draft_6_to_draft_7\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_6) &&\n        subschema_at_dialect(schema, location, DRAFT_6_URL));\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      if (!is_strict_descendant(location.pointer, entry.second.pointer)) {\n        continue;\n      }\n\n      const auto entry_pointer{\n          sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &entry_schema{sourcemeta::core::get(root, entry_pointer)};\n\n      if (entry_schema.is_object() && entry_schema.defines(\"$ref\")) {\n        continue;\n      }\n\n      if (has_pending_pattern(entry_schema)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string() &&\n        schema.at(\"$schema\").to_string() == DRAFT_6_URL) {\n      schema.assign(\"$schema\", sourcemeta::core::JSON{DRAFT_7_URL});\n      drop_dialect_overrides(schema, true);\n    } else {\n      mark_dialect_override(schema, DRAFT_7_URL);\n    }\n  }\n\nprivate:\n  static inline const std::string DRAFT_4_URL{\n      \"http://json-schema.org/draft-04/schema#\"};\n  static inline const std::string DRAFT_6_URL{\n      \"http://json-schema.org/draft-06/schema#\"};\n  static inline const std::string DRAFT_7_URL{\n      \"http://json-schema.org/draft-07/schema#\"};\n  static inline const std::array<std::string_view, 8> PROMOTED_KEYWORDS{\n      {\"$comment\", \"if\", \"then\", \"else\", \"readOnly\", \"writeOnly\",\n       \"contentMediaType\", \"contentEncoding\"}};\n\n  static auto has_pending_pattern(const sourcemeta::core::JSON &subschema)\n      -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n\n    if (subschema.defines(\"$schema\") && subschema.at(\"$schema\").is_string()) {\n      const auto &dialect{subschema.at(\"$schema\").to_string()};\n      if (dialect == DRAFT_4_URL || dialect == DRAFT_6_URL) {\n        return true;\n      }\n    }\n\n    for (const auto &keyword : PROMOTED_KEYWORDS) {\n      if (subschema.defines(keyword)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  static auto\n  is_strict_descendant(const sourcemeta::core::WeakPointer &ancestor,\n                       const sourcemeta::core::WeakPointer &candidate) -> bool {\n    if (candidate.size() <= ancestor.size()) {\n      return false;\n    }\n    for (std::size_t index{0}; index < ancestor.size(); ++index) {\n      if (!(ancestor.at(index) == candidate.at(index))) {\n        return false;\n      }\n    }\n    return true;\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/alterschema/upgrade/upgrade_draft_7_to_draft_2019_09.h",
    "content": "class UpgradeDraft7To201909 final : public SchemaTransformRule {\npublic:\n  using mutates = std::true_type;\n  using reframe_after_transform = std::true_type;\n  UpgradeDraft7To201909()\n      : SchemaTransformRule{\"upgrade_draft_7_to_2019_09\", \"\"} {};\n\n  [[nodiscard]] auto\n  condition(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::JSON &root,\n            const sourcemeta::core::Vocabularies &vocabularies,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location,\n            const sourcemeta::core::SchemaWalker &,\n            const sourcemeta::core::SchemaResolver &) const\n      -> SchemaTransformRule::Result override {\n    ONLY_CONTINUE_IF(\n        vocabularies.contains(Vocabularies::Known::JSON_Schema_Draft_7) &&\n        schema.is_object());\n\n    ONLY_CONTINUE_IF(subschema_at_dialect(schema, location, DRAFT_7_URL) ||\n                     has_actionable_id_fragment(schema) ||\n                     has_actionable_dependencies(schema) ||\n                     has_actionable_ref_siblings(schema));\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Resource &&\n          entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      if (entry.second.pointer.size() <= location.pointer.size() ||\n          !entry.second.pointer.starts_with(location.pointer)) {\n        continue;\n      }\n\n      const auto entry_pointer{\n          sourcemeta::core::to_pointer(entry.second.pointer)};\n      const auto &entry_schema{sourcemeta::core::get(root, entry_pointer)};\n\n      if (has_descendant_pending_pattern(entry_schema, entry.second.dialect)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto transform(sourcemeta::core::JSON &schema, const Result &) const\n      -> void override {\n    this->renames_.clear();\n    this->prefix_ref_siblings(schema);\n    this->split_id_fragment(schema);\n    this->split_dependencies(schema);\n    if (bump_schema(schema)) {\n      drop_dialect_overrides(schema, true);\n    } else {\n      mark_dialect_override(schema, DRAFT_2019_09_URL);\n    }\n  }\n\n  [[nodiscard]] auto rereference(const std::string_view,\n                                 const sourcemeta::core::Pointer &,\n                                 const sourcemeta::core::Pointer &target,\n                                 const sourcemeta::core::Pointer &current) const\n      -> sourcemeta::core::Pointer override {\n    for (const auto &[old_pointer, new_pointer] : this->renames_) {\n      const auto result{target.rebase(current.concat(old_pointer),\n                                      current.concat(new_pointer))};\n      if (result != target) {\n        return result;\n      }\n    }\n\n    return target;\n  }\n\nprivate:\n  static constexpr std::string_view DRAFT_4_URL{\n      \"http://json-schema.org/draft-04/schema#\"};\n  static constexpr std::string_view DRAFT_6_URL{\n      \"http://json-schema.org/draft-06/schema#\"};\n  static constexpr std::string_view DRAFT_7_URL{\n      \"http://json-schema.org/draft-07/schema#\"};\n  static constexpr std::string_view DRAFT_2019_09_URL{\n      \"https://json-schema.org/draft/2019-09/schema\"};\n\n  static inline const std::array<std::string_view, 12> SHADOW_EXEMPT_KEYWORDS{\n      {\"$schema\", \"$id\", \"title\", \"description\", \"default\", \"examples\",\n       \"$comment\", \"readOnly\", \"writeOnly\", \"deprecated\", \"contentMediaType\",\n       \"contentEncoding\"}};\n\n  static inline const std::array<std::string_view, 13>\n      PROMOTED_2019_09_KEYWORDS{{\"$anchor\", \"$recursiveAnchor\", \"$recursiveRef\",\n                                 \"$vocabulary\", \"$defs\", \"dependentSchemas\",\n                                 \"dependentRequired\", \"unevaluatedItems\",\n                                 \"unevaluatedProperties\", \"maxContains\",\n                                 \"minContains\", \"contentSchema\", \"deprecated\"}};\n\n  static inline const std::array<std::string_view, 8> PROMOTED_DRAFT_7_KEYWORDS{\n      {\"$comment\", \"if\", \"then\", \"else\", \"readOnly\", \"writeOnly\",\n       \"contentMediaType\", \"contentEncoding\"}};\n\n  static inline const std::array<std::string_view, 4> PROMOTED_DRAFT_6_KEYWORDS{\n      {\"const\", \"contains\", \"propertyNames\", \"examples\"}};\n\n  mutable std::vector<\n      std::pair<sourcemeta::core::Pointer, sourcemeta::core::Pointer>>\n      renames_;\n\n  static auto is_shadow_exempt(const std::string_view keyword) -> bool {\n    return std::ranges::any_of(\n        SHADOW_EXEMPT_KEYWORDS,\n        [&keyword](const auto &candidate) { return candidate == keyword; });\n  }\n\n  static auto is_plain_name_fragment(const std::string_view fragment) -> bool {\n    if (fragment.empty()) {\n      return false;\n    }\n\n    for (const auto character : fragment) {\n      const bool is_alpha{(character >= 'A' && character <= 'Z') ||\n                          (character >= 'a' && character <= 'z')};\n      const bool is_digit{character >= '0' && character <= '9'};\n      const bool is_punct{character == '_' || character == ':' ||\n                          character == '.' || character == '-'};\n      if (!is_alpha && !is_digit && !is_punct) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  static auto\n  has_actionable_id_fragment(const sourcemeta::core::JSON &subschema) -> bool {\n    if (!(subschema.defines(\"$id\") && subschema.at(\"$id\").is_string())) {\n      return false;\n    }\n\n    const sourcemeta::core::URI uri{subschema.at(\"$id\").to_string()};\n    const auto fragment{uri.fragment()};\n    return fragment.has_value() && (fragment.value().empty() ||\n                                    is_plain_name_fragment(fragment.value()));\n  }\n\n  static auto\n  has_actionable_dependencies(const sourcemeta::core::JSON &subschema) -> bool {\n    if (!(subschema.defines(\"dependencies\") &&\n          subschema.at(\"dependencies\").is_object())) {\n      return false;\n    }\n\n    if (subschema.defines(\"dependentRequired\") ||\n        subschema.defines(\"dependentSchemas\")) {\n      return false;\n    }\n\n    for (const auto &entry : subschema.at(\"dependencies\").as_object()) {\n      if (!entry.second.is_array() && !entry.second.is_object() &&\n          !entry.second.is_boolean()) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  static auto\n  has_actionable_ref_siblings(const sourcemeta::core::JSON &subschema) -> bool {\n    if (!subschema.defines(\"$ref\")) {\n      return false;\n    }\n\n    for (const auto &entry : subschema.as_object()) {\n      if (entry.first == \"$ref\" || is_shadow_exempt(entry.first) ||\n          entry.first.starts_with(\"x-\")) {\n        continue;\n      }\n      return true;\n    }\n\n    return false;\n  }\n\n  auto prefix_ref_siblings(sourcemeta::core::JSON &schema) const -> void {\n    if (!schema.defines(\"$ref\")) {\n      return;\n    }\n\n    std::vector<std::string> siblings_to_prefix;\n    for (const auto &entry : schema.as_object()) {\n      if (entry.first == \"$ref\" || is_shadow_exempt(entry.first) ||\n          entry.first.starts_with(\"x-\")) {\n        continue;\n      }\n\n      siblings_to_prefix.push_back(entry.first);\n    }\n\n    for (const auto &keyword : siblings_to_prefix) {\n      std::string prefixed_name{\"x-\" + keyword};\n      while (schema.defines(prefixed_name)) {\n        prefixed_name.insert(0, \"x-\");\n      }\n\n      this->renames_.emplace_back(sourcemeta::core::Pointer{keyword},\n                                  sourcemeta::core::Pointer{prefixed_name});\n      schema.rename(keyword, std::move(prefixed_name));\n    }\n  }\n\n  static auto split_id_fragment(sourcemeta::core::JSON &schema) -> void {\n    if (!(schema.defines(\"$id\") && schema.at(\"$id\").is_string())) {\n      return;\n    }\n\n    const sourcemeta::core::URI uri{schema.at(\"$id\").to_string()};\n    const auto fragment{uri.fragment()};\n    if (!fragment.has_value()) {\n      return;\n    }\n\n    const auto &fragment_value{fragment.value()};\n    const bool plain_name{is_plain_name_fragment(fragment_value)};\n\n    if (uri.is_fragment_only()) {\n      if (plain_name) {\n        schema.rename(\"$id\", \"$anchor\");\n        schema.at(\"$anchor\").into(sourcemeta::core::JSON{fragment_value});\n      } else if (fragment_value.empty()) {\n        schema.erase(\"$id\");\n      }\n      return;\n    }\n\n    if (!plain_name && !fragment_value.empty()) {\n      return;\n    }\n\n    const auto without_fragment{uri.recompose_without_fragment()};\n    if (!without_fragment.has_value()) {\n      return;\n    }\n\n    schema.assign(\"$id\", sourcemeta::core::JSON{without_fragment.value()});\n    if (plain_name) {\n      schema.assign(\"$anchor\", sourcemeta::core::JSON{fragment_value});\n    }\n  }\n\n  auto split_dependencies(sourcemeta::core::JSON &schema) const -> void {\n    if (!has_actionable_dependencies(schema)) {\n      return;\n    }\n\n    auto dependent_required{sourcemeta::core::JSON::make_object()};\n    auto dependent_schemas{sourcemeta::core::JSON::make_object()};\n\n    for (const auto &entry : schema.at(\"dependencies\").as_object()) {\n      if (entry.second.is_array()) {\n        dependent_required.assign(entry.first, entry.second);\n      } else {\n        dependent_schemas.assign(entry.first, entry.second);\n      }\n    }\n\n    if (dependent_required.empty() && dependent_schemas.empty()) {\n      schema.erase(\"dependencies\");\n      return;\n    }\n\n    if (!dependent_required.empty() && !dependent_schemas.empty()) {\n      for (const auto &entry : dependent_schemas.as_object()) {\n        this->renames_.emplace_back(\n            sourcemeta::core::Pointer{\"dependencies\", entry.first},\n            sourcemeta::core::Pointer{\"dependentSchemas\", entry.first});\n      }\n      for (const auto &entry : dependent_required.as_object()) {\n        this->renames_.emplace_back(\n            sourcemeta::core::Pointer{\"dependencies\", entry.first},\n            sourcemeta::core::Pointer{\"dependentRequired\", entry.first});\n      }\n      schema.try_assign_before(\"dependentSchemas\", dependent_schemas,\n                               \"dependencies\");\n      schema.rename(\"dependencies\", \"dependentRequired\");\n      schema.at(\"dependentRequired\").into(std::move(dependent_required));\n      return;\n    }\n\n    if (!dependent_schemas.empty()) {\n      this->renames_.emplace_back(\n          sourcemeta::core::Pointer{\"dependencies\"},\n          sourcemeta::core::Pointer{\"dependentSchemas\"});\n      schema.rename(\"dependencies\", \"dependentSchemas\");\n      schema.at(\"dependentSchemas\").into(std::move(dependent_schemas));\n      return;\n    }\n\n    this->renames_.emplace_back(sourcemeta::core::Pointer{\"dependencies\"},\n                                sourcemeta::core::Pointer{\"dependentRequired\"});\n    schema.rename(\"dependencies\", \"dependentRequired\");\n    schema.at(\"dependentRequired\").into(std::move(dependent_required));\n  }\n\n  static auto bump_schema(sourcemeta::core::JSON &schema) -> bool {\n    if (schema.defines(\"$schema\") && schema.at(\"$schema\").is_string() &&\n        schema.at(\"$schema\").to_string() == DRAFT_7_URL) {\n      schema.assign(\"$schema\", sourcemeta::core::JSON{DRAFT_2019_09_URL});\n      return true;\n    }\n    return false;\n  }\n\n  static auto has_pending_pattern(const sourcemeta::core::JSON &subschema)\n      -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n\n    if (current_dialect_or_override(subschema) == DRAFT_7_URL) {\n      return true;\n    }\n\n    return has_actionable_id_fragment(subschema) ||\n           has_actionable_dependencies(subschema) ||\n           has_actionable_ref_siblings(subschema);\n  }\n\n  static auto\n  has_descendant_pending_pattern(const sourcemeta::core::JSON &subschema,\n                                 const std::string_view descendant_dialect)\n      -> bool {\n    if (!subschema.is_object()) {\n      return false;\n    }\n\n    if (subschema.defines(\"$schema\") && subschema.at(\"$schema\").is_string()) {\n      const auto &dialect{subschema.at(\"$schema\").to_string()};\n      if (dialect == DRAFT_4_URL || dialect == DRAFT_6_URL ||\n          dialect == DRAFT_7_URL) {\n        return true;\n      }\n    }\n\n    if (subschema.defines(\"id\") && subschema.at(\"id\").is_string() &&\n        !subschema.defines(\"$id\")) {\n      return true;\n    }\n\n    const auto *exclusive_minimum{subschema.try_at(\"exclusiveMinimum\")};\n    if (exclusive_minimum != nullptr && exclusive_minimum->is_boolean()) {\n      return true;\n    }\n\n    const auto *exclusive_maximum{subschema.try_at(\"exclusiveMaximum\")};\n    if (exclusive_maximum != nullptr && exclusive_maximum->is_boolean()) {\n      return true;\n    }\n\n    if (descendant_dialect == DRAFT_4_URL) {\n      for (const auto &keyword : PROMOTED_DRAFT_6_KEYWORDS) {\n        if (subschema.defines(keyword)) {\n          return true;\n        }\n      }\n    }\n\n    if (descendant_dialect == DRAFT_6_URL) {\n      for (const auto &keyword : PROMOTED_DRAFT_7_KEYWORDS) {\n        if (subschema.defines(keyword)) {\n          return true;\n        }\n      }\n    }\n\n    if (descendant_dialect == DRAFT_7_URL) {\n      for (const auto &keyword : PROMOTED_2019_09_KEYWORDS) {\n        if (subschema.defines(keyword)) {\n          return true;\n        }\n      }\n    }\n\n    return has_pending_pattern(subschema);\n  }\n};\n"
  },
  {
    "path": "vendor/blaze/src/codegen/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME codegen\n  FOLDER \"Blaze/Codegen\"\n  PRIVATE_HEADERS error.h typescript.h\n  SOURCES\n    codegen.cc\n    codegen_symbol.cc\n    codegen_default_compiler.h\n    codegen_typescript.cc\n    codegen_mangle.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME codegen)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_codegen PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_codegen PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_blaze_codegen PRIVATE\n  sourcemeta::blaze::alterschema)\n"
  },
  {
    "path": "vendor/blaze/src/codegen/codegen.cc",
    "content": "#include <sourcemeta/blaze/alterschema.h>\n#include <sourcemeta/blaze/codegen.h>\n\n#include <algorithm>     // std::ranges::sort\n#include <cassert>       // assert\n#include <unordered_set> // std::unordered_set\n\n#include \"codegen_default_compiler.h\"\n\nnamespace {\n\nauto is_validation_subschema(\n    const sourcemeta::core::SchemaFrame &frame,\n    const sourcemeta::core::SchemaFrame::Location &location,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver) -> bool {\n  if (!location.parent.has_value()) {\n    return false;\n  }\n\n  const auto &parent{location.parent.value()};\n  if (parent.size() >= location.pointer.size()) {\n    return false;\n  }\n\n  const auto &keyword_token{location.pointer.at(parent.size())};\n  if (!keyword_token.is_property()) {\n    return false;\n  }\n\n  const auto parent_location{frame.traverse(parent)};\n  if (!parent_location.has_value()) {\n    return false;\n  }\n\n  const auto vocabularies{\n      frame.vocabularies(parent_location.value().get(), resolver)};\n  const auto &walker_result{walker(keyword_token.to_property(), vocabularies)};\n  using Type = sourcemeta::core::SchemaKeywordType;\n  if (walker_result.type == Type::ApplicatorValueTraverseAnyPropertyKey ||\n      walker_result.type == Type::ApplicatorValueTraverseAnyItem) {\n    return true;\n  }\n\n  return is_validation_subschema(frame, parent_location.value().get(), walker,\n                                 resolver);\n}\n\n} // anonymous namespace\n\nnamespace sourcemeta::blaze {\n\nauto compile(const sourcemeta::core::JSON &input,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const CodegenCompiler &compiler,\n             const std::string_view default_dialect,\n             const std::string_view default_id) -> CodegenIRResult {\n  // --------------------------------------------------------------------------\n  // (1) Bundle the schema to resolve external references\n  // --------------------------------------------------------------------------\n\n  auto schema{sourcemeta::core::bundle(input, walker, resolver, default_dialect,\n                                       default_id)};\n\n  // --------------------------------------------------------------------------\n  // (2) Canonicalize the schema for easier analysis\n  // --------------------------------------------------------------------------\n\n  sourcemeta::blaze::SchemaTransformer canonicalizer;\n  sourcemeta::blaze::add(canonicalizer,\n                         sourcemeta::blaze::AlterSchemaMode::Canonicalizer);\n  [[maybe_unused]] const auto canonicalized{canonicalizer.apply(\n      schema, walker, resolver,\n      [](const auto &, const auto, const auto, const auto &,\n         [[maybe_unused]] const auto applied) { assert(applied); },\n      default_dialect, default_id)};\n  assert(canonicalized.first);\n\n  // --------------------------------------------------------------------------\n  // (3) Frame the resulting schema with instance location information\n  // --------------------------------------------------------------------------\n\n  sourcemeta::core::SchemaFrame frame{\n      sourcemeta::core::SchemaFrame::Mode::References};\n  frame.analyse(schema, walker, resolver, default_dialect, default_id);\n\n  // --------------------------------------------------------------------------\n  // (4) Convert every subschema into a code generation object\n  // --------------------------------------------------------------------------\n\n  std::unordered_set<sourcemeta::core::WeakPointer,\n                     sourcemeta::core::WeakPointer::Hasher,\n                     sourcemeta::core::WeakPointer::Comparator>\n      visited;\n  CodegenIRResult result;\n  for (const auto &[key, location] : frame.locations()) {\n    if (location.type !=\n            sourcemeta::core::SchemaFrame::LocationType::Resource &&\n        location.type !=\n            sourcemeta::core::SchemaFrame::LocationType::Subschema) {\n      continue;\n    }\n\n    // Framing may report resource twice or more given default identifiers and\n    // nested resources\n    const auto [visited_iterator, inserted] = visited.insert(location.pointer);\n    if (!inserted) {\n      continue;\n    }\n\n    // Skip subschemas under validation-only keywords that do not contribute\n    // to the type structure (like `contains`)\n    if (is_validation_subschema(frame, location, walker, resolver)) {\n      continue;\n    }\n\n    const auto &subschema{sourcemeta::core::get(schema, location.pointer)};\n    result.push_back(compiler(schema, frame, location, resolver, subschema));\n  }\n\n  // --------------------------------------------------------------------------\n  // (5) Sort entries so that dependencies come before dependents\n  // --------------------------------------------------------------------------\n\n  std::ranges::sort(\n      result,\n      [](const CodegenIREntity &left, const CodegenIREntity &right) -> bool {\n        return std::visit([](const auto &entry) { return entry.pointer; },\n                          right) <\n               std::visit([](const auto &entry) { return entry.pointer; },\n                          left);\n      });\n\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/codegen/codegen_default_compiler.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CODEGEN_DEFAULT_COMPILER_H_\n#define SOURCEMETA_BLAZE_CODEGEN_DEFAULT_COMPILER_H_\n\n#include <sourcemeta/blaze/codegen.h>\n\n#include <sourcemeta/core/jsonschema.h>\n#include <sourcemeta/core/regex.h>\n#include <sourcemeta/core/uri.h>\n\n#include <cassert>       // assert\n#include <string_view>   // std::string_view\n#include <unordered_set> // std::unordered_set\n\n// We do not check vocabularies here because the canonicaliser ensures\n// we never get an official keyword when its vocabulary is not present\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#define ONLY_WHITELIST_KEYWORDS(schema, subschema, pointer, ...)               \\\n  {                                                                            \\\n    static const std::unordered_set<std::string_view> allowed{__VA_ARGS__};    \\\n    for (const auto &entry : (subschema).as_object()) {                        \\\n      if (!allowed.contains(entry.first)) {                                    \\\n        throw sourcemeta::blaze::CodegenUnsupportedKeywordError(               \\\n            (schema), (pointer), entry.first,                                  \\\n            \"Unsupported keyword in subschema\");                               \\\n      }                                                                        \\\n    }                                                                          \\\n  }\n\nnamespace sourcemeta::blaze {\n\nauto handle_impossible(const sourcemeta::core::JSON &,\n                       const sourcemeta::core::SchemaFrame &frame,\n                       const sourcemeta::core::SchemaFrame::Location &location,\n                       const sourcemeta::core::Vocabularies &,\n                       const sourcemeta::core::SchemaResolver &,\n                       const sourcemeta::core::JSON &) -> CodegenIRImpossible {\n  return CodegenIRImpossible{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)}};\n}\n\nauto handle_any(const sourcemeta::core::JSON &,\n                const sourcemeta::core::SchemaFrame &frame,\n                const sourcemeta::core::SchemaFrame::Location &location,\n                const sourcemeta::core::Vocabularies &,\n                const sourcemeta::core::SchemaResolver &,\n                const sourcemeta::core::JSON &) -> CodegenIRAny {\n  return CodegenIRAny{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)}};\n}\n\nauto handle_string(const sourcemeta::core::JSON &schema,\n                   const sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::SchemaFrame::Location &location,\n                   const sourcemeta::core::Vocabularies &,\n                   const sourcemeta::core::SchemaResolver &,\n                   const sourcemeta::core::JSON &subschema) -> CodegenIRScalar {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\",\n                           \"$id\",\n                           \"$anchor\",\n                           \"$dynamicAnchor\",\n                           \"$defs\",\n                           \"$vocabulary\",\n                           \"type\",\n                           \"minLength\",\n                           \"maxLength\",\n                           \"pattern\",\n                           \"format\",\n                           \"title\",\n                           \"description\",\n                           \"default\",\n                           \"deprecated\",\n                           \"readOnly\",\n                           \"writeOnly\",\n                           \"examples\",\n                           \"contentEncoding\",\n                           \"contentMediaType\",\n                           \"contentSchema\"});\n  return CodegenIRScalar{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      CodegenIRScalarType::String};\n}\n\nauto handle_object(const sourcemeta::core::JSON &schema,\n                   const sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::SchemaFrame::Location &location,\n                   const sourcemeta::core::Vocabularies &,\n                   const sourcemeta::core::SchemaResolver &,\n                   const sourcemeta::core::JSON &subschema) -> CodegenIRObject {\n  ONLY_WHITELIST_KEYWORDS(\n      schema, subschema, location.pointer,\n      {\"$defs\", \"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\", \"$vocabulary\",\n       \"type\", \"properties\", \"required\",\n       // Note that most programming languages CANNOT represent the idea\n       // of additional properties, mainly if they differ from the types of the\n       // other properties. Therefore, we whitelist this, but we consider it to\n       // be the responsability of the validator\n       \"additionalProperties\", \"minProperties\", \"maxProperties\",\n       \"propertyNames\", \"patternProperties\", \"title\", \"description\", \"default\",\n       \"deprecated\", \"readOnly\", \"writeOnly\", \"examples\"});\n\n  std::vector<std::pair<sourcemeta::core::JSON::String, CodegenIRObjectValue>>\n      members;\n\n  // Guaranteed by canonicalisation\n  assert(subschema.defines(\"properties\"));\n\n  const auto &properties{subschema.at(\"properties\")};\n\n  std::unordered_set<std::string_view> required_set;\n  if (subschema.defines(\"required\")) {\n    const auto &required{subschema.at(\"required\")};\n    for (const auto &item : required.as_array()) {\n      // Guaranteed by canonicalisation\n      assert(properties.defines(item.to_string()));\n      required_set.insert(item.to_string());\n    }\n  }\n\n  for (const auto &entry : properties.as_object()) {\n    auto property_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    property_pointer.push_back(\"properties\");\n    property_pointer.push_back(entry.first);\n\n    const auto property_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(property_pointer))};\n    assert(property_location.has_value());\n\n    CodegenIRObjectValue member_value{\n        {.pointer = std::move(property_pointer),\n         .symbol = symbol(frame, property_location.value().get())},\n        required_set.contains(entry.first),\n        false};\n\n    members.emplace_back(entry.first, std::move(member_value));\n  }\n\n  std::variant<bool, CodegenIRType> additional{true};\n  if (subschema.defines(\"additionalProperties\")) {\n    const auto &additional_schema{subschema.at(\"additionalProperties\")};\n    if (additional_schema.is_boolean()) {\n      additional = additional_schema.to_boolean();\n    } else {\n      auto additional_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      additional_pointer.push_back(\"additionalProperties\");\n\n      const auto additional_location{frame.traverse(\n          sourcemeta::core::to_weak_pointer(additional_pointer))};\n      assert(additional_location.has_value());\n\n      additional = CodegenIRType{\n          .pointer = std::move(additional_pointer),\n          .symbol = symbol(frame, additional_location.value().get())};\n    }\n  }\n\n  std::vector<CodegenIRObjectPatternProperty> pattern;\n  if (subschema.defines(\"patternProperties\")) {\n    const auto &pattern_props{subschema.at(\"patternProperties\")};\n    for (const auto &entry : pattern_props.as_object()) {\n      auto pattern_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      pattern_pointer.push_back(\"patternProperties\");\n      pattern_pointer.push_back(entry.first);\n\n      const auto pattern_location{\n          frame.traverse(sourcemeta::core::to_weak_pointer(pattern_pointer))};\n      assert(pattern_location.has_value());\n\n      std::optional<std::string> prefix{std::nullopt};\n      const auto regex{sourcemeta::core::to_regex(entry.first)};\n      if (regex.has_value() &&\n          std::holds_alternative<sourcemeta::core::RegexTypePrefix>(\n              regex.value())) {\n        prefix = std::get<sourcemeta::core::RegexTypePrefix>(regex.value());\n      }\n\n      pattern.push_back(CodegenIRObjectPatternProperty{\n          {.pointer = std::move(pattern_pointer),\n           .symbol = symbol(frame, pattern_location.value().get())},\n          std::move(prefix)});\n    }\n  }\n\n  return CodegenIRObject{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(members),\n      std::move(additional),\n      std::move(pattern)};\n}\n\nauto handle_integer(const sourcemeta::core::JSON &schema,\n                    const sourcemeta::core::SchemaFrame &frame,\n                    const sourcemeta::core::SchemaFrame::Location &location,\n                    const sourcemeta::core::Vocabularies &,\n                    const sourcemeta::core::SchemaResolver &,\n                    const sourcemeta::core::JSON &subschema)\n    -> CodegenIRScalar {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"type\", \"minimum\", \"maximum\",\n                           \"exclusiveMinimum\", \"exclusiveMaximum\", \"multipleOf\",\n                           \"title\", \"description\", \"default\", \"deprecated\",\n                           \"readOnly\", \"writeOnly\", \"examples\"});\n  return CodegenIRScalar{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      CodegenIRScalarType::Integer};\n}\n\nauto handle_number(const sourcemeta::core::JSON &schema,\n                   const sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::SchemaFrame::Location &location,\n                   const sourcemeta::core::Vocabularies &,\n                   const sourcemeta::core::SchemaResolver &,\n                   const sourcemeta::core::JSON &subschema) -> CodegenIRScalar {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"type\", \"minimum\", \"maximum\",\n                           \"exclusiveMinimum\", \"exclusiveMaximum\", \"multipleOf\",\n                           \"title\", \"description\", \"default\", \"deprecated\",\n                           \"readOnly\", \"writeOnly\", \"examples\"});\n  return CodegenIRScalar{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      CodegenIRScalarType::Number};\n}\n\nauto handle_array(const sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaFrame &frame,\n                  const sourcemeta::core::SchemaFrame::Location &location,\n                  const sourcemeta::core::Vocabularies &vocabularies,\n                  const sourcemeta::core::SchemaResolver &,\n                  const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\",        \"$id\",         \"$anchor\",\n                           \"$dynamicAnchor\", \"$defs\",       \"$vocabulary\",\n                           \"type\",           \"items\",       \"minItems\",\n                           \"maxItems\",       \"uniqueItems\", \"contains\",\n                           \"minContains\",    \"maxContains\", \"additionalItems\",\n                           \"prefixItems\",    \"title\",       \"description\",\n                           \"default\",        \"deprecated\",  \"readOnly\",\n                           \"writeOnly\",      \"examples\"});\n\n  using Vocabularies = sourcemeta::core::Vocabularies;\n\n  if (vocabularies.contains(\n          Vocabularies::Known::JSON_Schema_2020_12_Applicator) &&\n      subschema.defines(\"prefixItems\")) {\n    const auto &prefix_items{subschema.at(\"prefixItems\")};\n    assert(prefix_items.is_array());\n\n    std::vector<CodegenIRType> tuple_items;\n    for (std::size_t index = 0; index < prefix_items.size(); ++index) {\n      auto item_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      item_pointer.push_back(\"prefixItems\");\n      item_pointer.push_back(index);\n\n      const auto item_location{\n          frame.traverse(sourcemeta::core::to_weak_pointer(item_pointer))};\n      assert(item_location.has_value());\n\n      tuple_items.push_back(\n          {.pointer = std::move(item_pointer),\n           .symbol = symbol(frame, item_location.value().get())});\n    }\n\n    std::optional<CodegenIRType> additional{std::nullopt};\n    if (subschema.defines(\"items\")) {\n      auto additional_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      additional_pointer.push_back(\"items\");\n\n      const auto additional_location{frame.traverse(\n          sourcemeta::core::to_weak_pointer(additional_pointer))};\n      assert(additional_location.has_value());\n\n      additional = CodegenIRType{\n          .pointer = std::move(additional_pointer),\n          .symbol = symbol(frame, additional_location.value().get())};\n    }\n\n    return CodegenIRTuple{\n        {.pointer = sourcemeta::core::to_pointer(location.pointer),\n         .symbol = symbol(frame, location)},\n        std::move(tuple_items),\n        std::move(additional)};\n  }\n\n  if (vocabularies.contains_any(\n          {Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n           Vocabularies::Known::JSON_Schema_Draft_7,\n           Vocabularies::Known::JSON_Schema_Draft_6,\n           Vocabularies::Known::JSON_Schema_Draft_4,\n           Vocabularies::Known::JSON_Schema_Draft_3}) &&\n      subschema.defines(\"items\") && subschema.at(\"items\").is_array()) {\n    const auto &items_array{subschema.at(\"items\")};\n\n    std::vector<CodegenIRType> tuple_items;\n    for (std::size_t index = 0; index < items_array.size(); ++index) {\n      auto item_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      item_pointer.push_back(\"items\");\n      item_pointer.push_back(index);\n\n      const auto item_location{\n          frame.traverse(sourcemeta::core::to_weak_pointer(item_pointer))};\n      assert(item_location.has_value());\n\n      tuple_items.push_back(\n          {.pointer = std::move(item_pointer),\n           .symbol = symbol(frame, item_location.value().get())});\n    }\n\n    std::optional<CodegenIRType> additional{std::nullopt};\n    if (subschema.defines(\"additionalItems\")) {\n      auto additional_pointer{sourcemeta::core::to_pointer(location.pointer)};\n      additional_pointer.push_back(\"additionalItems\");\n\n      const auto additional_location{frame.traverse(\n          sourcemeta::core::to_weak_pointer(additional_pointer))};\n      assert(additional_location.has_value());\n\n      additional = CodegenIRType{\n          .pointer = std::move(additional_pointer),\n          .symbol = symbol(frame, additional_location.value().get())};\n    }\n\n    return CodegenIRTuple{\n        {.pointer = sourcemeta::core::to_pointer(location.pointer),\n         .symbol = symbol(frame, location)},\n        std::move(tuple_items),\n        std::move(additional)};\n  }\n\n  std::optional<CodegenIRType> items_type{std::nullopt};\n  if (subschema.defines(\"items\")) {\n    auto items_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    items_pointer.push_back(\"items\");\n\n    const auto items_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(items_pointer))};\n    assert(items_location.has_value());\n\n    items_type =\n        CodegenIRType{.pointer = std::move(items_pointer),\n                      .symbol = symbol(frame, items_location.value().get())};\n  }\n\n  return CodegenIRArray{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(items_type)};\n}\n\nauto handle_enum(const sourcemeta::core::JSON &schema,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::SchemaFrame::Location &location,\n                 const sourcemeta::core::Vocabularies &,\n                 const sourcemeta::core::SchemaResolver &,\n                 const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"enum\", \"title\",\n                           \"description\", \"default\", \"deprecated\", \"readOnly\",\n                           \"writeOnly\", \"examples\"});\n  const auto &enum_json{subschema.at(\"enum\")};\n\n  // Boolean and null special cases\n  if (enum_json.size() == 1 && enum_json.at(0).is_null()) {\n    return CodegenIRScalar{\n        {.pointer = sourcemeta::core::to_pointer(location.pointer),\n         .symbol = symbol(frame, location)},\n        CodegenIRScalarType::Null};\n  } else if (enum_json.size() == 2) {\n    const auto &first{enum_json.at(0)};\n    const auto &second{enum_json.at(1)};\n    if ((first.is_boolean() && second.is_boolean()) &&\n        (first.to_boolean() != second.to_boolean())) {\n      return CodegenIRScalar{\n          {.pointer = sourcemeta::core::to_pointer(location.pointer),\n           .symbol = symbol(frame, location)},\n          CodegenIRScalarType::Boolean};\n    }\n  }\n\n  std::vector<sourcemeta::core::JSON> values{enum_json.as_array().cbegin(),\n                                             enum_json.as_array().cend()};\n  return CodegenIREnumeration{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(values)};\n}\n\nauto handle_anyof(const sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaFrame &frame,\n                  const sourcemeta::core::SchemaFrame::Location &location,\n                  const sourcemeta::core::Vocabularies &,\n                  const sourcemeta::core::SchemaResolver &,\n                  const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(\n      schema, subschema, location.pointer,\n      {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\", \"$defs\", \"$vocabulary\",\n       \"anyOf\", \"title\", \"description\", \"default\", \"deprecated\", \"readOnly\",\n       \"writeOnly\", \"examples\", \"unevaluatedProperties\", \"unevaluatedItems\"});\n\n  const auto &any_of{subschema.at(\"anyOf\")};\n  assert(any_of.is_array());\n  assert(any_of.size() >= 2);\n\n  std::vector<CodegenIRType> branches;\n  for (std::size_t index = 0; index < any_of.size(); ++index) {\n    auto branch_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    branch_pointer.push_back(\"anyOf\");\n    branch_pointer.push_back(index);\n\n    const auto branch_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(branch_pointer))};\n    assert(branch_location.has_value());\n\n    branches.push_back(\n        {.pointer = std::move(branch_pointer),\n         .symbol = symbol(frame, branch_location.value().get())});\n  }\n\n  return CodegenIRUnion{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(branches)};\n}\n\nauto handle_oneof(const sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaFrame &frame,\n                  const sourcemeta::core::SchemaFrame::Location &location,\n                  const sourcemeta::core::Vocabularies &,\n                  const sourcemeta::core::SchemaResolver &,\n                  const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(\n      schema, subschema, location.pointer,\n      {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\", \"$defs\", \"$vocabulary\",\n       \"oneOf\", \"title\", \"description\", \"default\", \"deprecated\", \"readOnly\",\n       \"writeOnly\", \"examples\", \"unevaluatedProperties\", \"unevaluatedItems\"});\n\n  const auto &one_of{subschema.at(\"oneOf\")};\n  assert(one_of.is_array());\n  assert(one_of.size() >= 2);\n\n  std::vector<CodegenIRType> branches;\n  for (std::size_t index = 0; index < one_of.size(); ++index) {\n    auto branch_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    branch_pointer.push_back(\"oneOf\");\n    branch_pointer.push_back(index);\n\n    const auto branch_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(branch_pointer))};\n    assert(branch_location.has_value());\n\n    branches.push_back(\n        {.pointer = std::move(branch_pointer),\n         .symbol = symbol(frame, branch_location.value().get())});\n  }\n\n  return CodegenIRUnion{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(branches)};\n}\n\nauto handle_ref(const sourcemeta::core::JSON &schema,\n                const sourcemeta::core::SchemaFrame &frame,\n                const sourcemeta::core::SchemaFrame::Location &location,\n                const sourcemeta::core::Vocabularies &,\n                const sourcemeta::core::SchemaResolver &,\n                const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"$ref\", \"title\",\n                           \"description\", \"default\", \"deprecated\", \"readOnly\",\n                           \"writeOnly\", \"examples\"});\n\n  auto ref_pointer{sourcemeta::core::to_pointer(location.pointer)};\n  ref_pointer.push_back(\"$ref\");\n  const auto ref_weak_pointer{sourcemeta::core::to_weak_pointer(ref_pointer)};\n\n  const auto &references{frame.references()};\n  const auto reference{references.find(\n      {sourcemeta::core::SchemaReferenceType::Static, ref_weak_pointer})};\n  assert(reference != references.cend());\n\n  const auto &destination{reference->second.destination};\n  const auto target{frame.traverse(destination)};\n  if (!target.has_value()) {\n    throw CodegenUnexpectedSchemaError(\n        schema, location.pointer, \"Could not resolve reference destination\");\n  }\n\n  const auto &target_location{target.value().get()};\n\n  return CodegenIRReference{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      {.pointer = sourcemeta::core::to_pointer(target_location.pointer),\n       .symbol = symbol(frame, target_location)}};\n}\n\nauto handle_dynamic_ref(const sourcemeta::core::JSON &schema,\n                        const sourcemeta::core::SchemaFrame &frame,\n                        const sourcemeta::core::SchemaFrame::Location &location,\n                        const sourcemeta::core::Vocabularies &,\n                        const sourcemeta::core::SchemaResolver &,\n                        const sourcemeta::core::JSON &subschema)\n    -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"$dynamicRef\", \"title\",\n                           \"description\", \"default\", \"deprecated\", \"readOnly\",\n                           \"writeOnly\", \"examples\"});\n\n  auto ref_pointer{sourcemeta::core::to_pointer(location.pointer)};\n  ref_pointer.push_back(\"$dynamicRef\");\n  const auto ref_weak_pointer{sourcemeta::core::to_weak_pointer(ref_pointer)};\n\n  const auto &references{frame.references()};\n\n  // Note: The frame internally converts single-target dynamic references to\n  // static reference\n  const auto static_reference{references.find(\n      {sourcemeta::core::SchemaReferenceType::Static, ref_weak_pointer})};\n  if (static_reference != references.cend()) {\n    const auto &destination{static_reference->second.destination};\n    const auto target{frame.traverse(destination)};\n    if (!target.has_value()) {\n      throw CodegenUnexpectedSchemaError(\n          schema, location.pointer, \"Could not resolve reference destination\");\n    }\n\n    const auto &target_location{target.value().get()};\n\n    return CodegenIRReference{\n        {.pointer = sourcemeta::core::to_pointer(location.pointer),\n         .symbol = symbol(frame, location)},\n        {.pointer = sourcemeta::core::to_pointer(target_location.pointer),\n         .symbol = symbol(frame, target_location)}};\n  }\n\n  // Multi-target dynamic reference: find all dynamic anchors with the matching\n  // fragment and emit a union of all possible targets\n  const auto dynamic_reference{references.find(\n      {sourcemeta::core::SchemaReferenceType::Dynamic, ref_weak_pointer})};\n  assert(dynamic_reference != references.cend());\n  assert(dynamic_reference->second.fragment.has_value());\n  const auto &fragment{dynamic_reference->second.fragment.value()};\n\n  std::vector<CodegenIRType> branches;\n  for (const auto &[key, entry] : frame.locations()) {\n    if (key.first != sourcemeta::core::SchemaReferenceType::Dynamic ||\n        entry.type != sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n      continue;\n    }\n\n    const sourcemeta::core::URI anchor_uri{key.second};\n    const auto anchor_fragment{anchor_uri.fragment()};\n    if (!anchor_fragment.has_value() || anchor_fragment.value() != fragment) {\n      continue;\n    }\n\n    branches.push_back({.pointer = sourcemeta::core::to_pointer(entry.pointer),\n                        .symbol = symbol(frame, entry)});\n  }\n\n  assert(!branches.empty());\n  return CodegenIRUnion{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(branches)};\n}\n\nauto handle_allof(const sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::SchemaFrame &frame,\n                  const sourcemeta::core::SchemaFrame::Location &location,\n                  const sourcemeta::core::Vocabularies &,\n                  const sourcemeta::core::SchemaResolver &,\n                  const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(\n      schema, subschema, location.pointer,\n      {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\", \"$defs\", \"$vocabulary\",\n       \"allOf\", \"title\", \"description\", \"default\", \"deprecated\", \"readOnly\",\n       \"writeOnly\", \"examples\", \"unevaluatedProperties\", \"unevaluatedItems\"});\n\n  const auto &all_of{subschema.at(\"allOf\")};\n  assert(all_of.is_array());\n\n  if (all_of.size() == 1) {\n    auto target_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    target_pointer.push_back(\"allOf\");\n    target_pointer.push_back(static_cast<std::size_t>(0));\n\n    const auto target_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(target_pointer))};\n    assert(target_location.has_value());\n\n    return CodegenIRReference{\n        {.pointer = sourcemeta::core::to_pointer(location.pointer),\n         .symbol = symbol(frame, location)},\n        {.pointer = std::move(target_pointer),\n         .symbol = symbol(frame, target_location.value().get())}};\n  }\n\n  std::vector<CodegenIRType> branches;\n  for (std::size_t index = 0; index < all_of.size(); ++index) {\n    auto branch_pointer{sourcemeta::core::to_pointer(location.pointer)};\n    branch_pointer.push_back(\"allOf\");\n    branch_pointer.push_back(index);\n\n    const auto branch_location{\n        frame.traverse(sourcemeta::core::to_weak_pointer(branch_pointer))};\n    assert(branch_location.has_value());\n\n    branches.push_back(\n        {.pointer = std::move(branch_pointer),\n         .symbol = symbol(frame, branch_location.value().get())});\n  }\n\n  return CodegenIRIntersection{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      std::move(branches)};\n}\n\nauto handle_if_then_else(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaFrame &frame,\n    const sourcemeta::core::SchemaFrame::Location &location,\n    const sourcemeta::core::Vocabularies &,\n    const sourcemeta::core::SchemaResolver &,\n    const sourcemeta::core::JSON &subschema) -> CodegenIREntity {\n  ONLY_WHITELIST_KEYWORDS(schema, subschema, location.pointer,\n                          {\"$schema\", \"$id\", \"$anchor\", \"$dynamicAnchor\",\n                           \"$defs\", \"$vocabulary\", \"if\", \"then\", \"else\",\n                           \"title\", \"description\", \"default\", \"deprecated\",\n                           \"readOnly\", \"writeOnly\", \"examples\",\n                           \"unevaluatedProperties\", \"unevaluatedItems\"});\n\n  assert(subschema.defines(\"if\"));\n  assert(subschema.defines(\"then\"));\n  assert(subschema.defines(\"else\"));\n\n  auto if_pointer{sourcemeta::core::to_pointer(location.pointer)};\n  if_pointer.push_back(\"if\");\n  const auto if_location{\n      frame.traverse(sourcemeta::core::to_weak_pointer(if_pointer))};\n  assert(if_location.has_value());\n\n  auto then_pointer{sourcemeta::core::to_pointer(location.pointer)};\n  then_pointer.push_back(\"then\");\n  const auto then_location{\n      frame.traverse(sourcemeta::core::to_weak_pointer(then_pointer))};\n  assert(then_location.has_value());\n\n  auto else_pointer{sourcemeta::core::to_pointer(location.pointer)};\n  else_pointer.push_back(\"else\");\n  const auto else_location{\n      frame.traverse(sourcemeta::core::to_weak_pointer(else_pointer))};\n  assert(else_location.has_value());\n\n  return CodegenIRConditional{\n      {.pointer = sourcemeta::core::to_pointer(location.pointer),\n       .symbol = symbol(frame, location)},\n      {.pointer = std::move(if_pointer),\n       .symbol = symbol(frame, if_location.value().get())},\n      {.pointer = std::move(then_pointer),\n       .symbol = symbol(frame, then_location.value().get())},\n      {.pointer = std::move(else_pointer),\n       .symbol = symbol(frame, else_location.value().get())}};\n}\n\nauto default_compiler(const sourcemeta::core::JSON &schema,\n                      const sourcemeta::core::SchemaFrame &frame,\n                      const sourcemeta::core::SchemaFrame::Location &location,\n                      const sourcemeta::core::SchemaResolver &resolver,\n                      const sourcemeta::core::JSON &subschema)\n    -> CodegenIREntity {\n  const auto vocabularies{frame.vocabularies(location, resolver)};\n  assert(!vocabularies.empty());\n\n  // Be strict with vocabulary support\n  using Vocabularies = sourcemeta::core::Vocabularies;\n  static const std::unordered_set<Vocabularies::URI> supported{\n      Vocabularies::Known::JSON_Schema_2020_12_Core,\n      Vocabularies::Known::JSON_Schema_2020_12_Applicator,\n      Vocabularies::Known::JSON_Schema_2020_12_Validation,\n      Vocabularies::Known::JSON_Schema_2020_12_Unevaluated,\n      Vocabularies::Known::JSON_Schema_2020_12_Content,\n      Vocabularies::Known::JSON_Schema_2020_12_Meta_Data,\n      Vocabularies::Known::JSON_Schema_2020_12_Format_Annotation,\n      Vocabularies::Known::JSON_Schema_2020_12_Format_Assertion,\n      Vocabularies::Known::JSON_Schema_2019_09_Core,\n      Vocabularies::Known::JSON_Schema_2019_09_Applicator,\n      Vocabularies::Known::JSON_Schema_2019_09_Validation,\n      Vocabularies::Known::JSON_Schema_2019_09_Content,\n      Vocabularies::Known::JSON_Schema_2019_09_Meta_Data,\n      Vocabularies::Known::JSON_Schema_2019_09_Format,\n      Vocabularies::Known::JSON_Schema_Draft_7,\n      Vocabularies::Known::JSON_Schema_Draft_6,\n      Vocabularies::Known::JSON_Schema_Draft_4};\n  vocabularies.throw_if_any_unsupported(supported,\n                                        \"Unsupported required vocabulary\");\n\n  // The canonicaliser ensures that every subschema schema is only in one of the\n  // following shapes\n\n  if (subschema.is_boolean()) {\n    if (subschema.to_boolean()) {\n      return handle_any(schema, frame, location, vocabularies, resolver,\n                        subschema);\n    } else {\n      return handle_impossible(schema, frame, location, vocabularies, resolver,\n                               subschema);\n    }\n  } else if (subschema.defines(\"type\")) {\n    const auto &type_value{subschema.at(\"type\")};\n    if (!type_value.is_string()) {\n      throw CodegenUnsupportedKeywordValueError(\n          schema, location.pointer, \"type\", \"Expected a string value\");\n    }\n\n    const auto &type_string{type_value.to_string()};\n\n    // The canonicaliser transforms any other type\n    if (type_string == \"string\") {\n      return handle_string(schema, frame, location, vocabularies, resolver,\n                           subschema);\n    } else if (type_string == \"object\") {\n      return handle_object(schema, frame, location, vocabularies, resolver,\n                           subschema);\n    } else if (type_string == \"integer\") {\n      return handle_integer(schema, frame, location, vocabularies, resolver,\n                            subschema);\n    } else if (type_string == \"number\") {\n      return handle_number(schema, frame, location, vocabularies, resolver,\n                           subschema);\n    } else if (type_string == \"array\") {\n      return handle_array(schema, frame, location, vocabularies, resolver,\n                          subschema);\n    } else {\n      throw CodegenUnsupportedKeywordValueError(\n          schema, location.pointer, \"type\", \"Unsupported type value\");\n    }\n  } else if (subschema.defines(\"enum\")) {\n    return handle_enum(schema, frame, location, vocabularies, resolver,\n                       subschema);\n  } else if (subschema.defines(\"anyOf\")) {\n    return handle_anyof(schema, frame, location, vocabularies, resolver,\n                        subschema);\n    // This is usually a good enough approximation. We usually can't check that\n    // the other types DO NOT match, but that is in a way a validation concern\n  } else if (subschema.defines(\"oneOf\")) {\n    return handle_oneof(schema, frame, location, vocabularies, resolver,\n                        subschema);\n  } else if (subschema.defines(\"allOf\")) {\n    return handle_allof(schema, frame, location, vocabularies, resolver,\n                        subschema);\n  } else if (subschema.defines(\"$dynamicRef\")) {\n    return handle_dynamic_ref(schema, frame, location, vocabularies, resolver,\n                              subschema);\n  } else if (subschema.defines(\"$ref\")) {\n    return handle_ref(schema, frame, location, vocabularies, resolver,\n                      subschema);\n  } else if (subschema.defines(\"if\")) {\n    return handle_if_then_else(schema, frame, location, vocabularies, resolver,\n                               subschema);\n  } else if (subschema.defines(\"not\")) {\n    throw CodegenUnsupportedKeywordError(schema, location.pointer, \"not\",\n                                         \"Unsupported keyword in subschema\");\n  } else {\n    throw CodegenUnexpectedSchemaError(schema, location.pointer,\n                                       \"Unsupported schema\");\n  }\n}\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/codegen/codegen_mangle.cc",
    "content": "#include <sourcemeta/blaze/codegen.h>\n\nnamespace {\n\nauto is_alpha(char character) -> bool {\n  return (character >= 'a' && character <= 'z') ||\n         (character >= 'A' && character <= 'Z');\n}\n\nauto is_digit(char character) -> bool {\n  return character >= '0' && character <= '9';\n}\n\nauto to_upper(char character) -> char {\n  if (character >= 'a' && character <= 'z') {\n    return static_cast<char>(character - 'a' + 'A');\n  }\n  return character;\n}\n\nauto symbol_to_identifier(const std::string_view prefix,\n                          const std::vector<std::string> &symbol)\n    -> std::string {\n  std::string result{prefix};\n\n  for (const auto &segment : symbol) {\n    if (segment.empty()) {\n      continue;\n    }\n\n    bool first_in_segment{true};\n    for (const auto character : segment) {\n      if (is_alpha(character)) {\n        if (first_in_segment) {\n          result += to_upper(character);\n          first_in_segment = false;\n        } else {\n          result += character;\n        }\n      } else if (is_digit(character)) {\n        if (first_in_segment) {\n          result += '_';\n        }\n        result += character;\n        first_in_segment = false;\n      } else if (character == '_' || character == '$') {\n        result += character;\n        first_in_segment = false;\n      }\n    }\n  }\n\n  if (result.empty()) {\n    return \"_\";\n  }\n\n  if (is_digit(result[0])) {\n    result.insert(0, \"_\");\n  }\n\n  return result;\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto mangle(const std::string_view prefix,\n            const sourcemeta::core::Pointer &pointer,\n            const std::vector<std::string> &symbol,\n            std::map<std::string, sourcemeta::core::Pointer> &cache)\n    -> const std::string & {\n  auto name{symbol_to_identifier(prefix, symbol)};\n\n  while (true) {\n    auto iterator{cache.find(name)};\n    if (iterator != cache.end()) {\n      if (iterator->second == pointer) {\n        return iterator->first;\n      }\n\n      name.insert(0, \"_\");\n    } else {\n      auto result{cache.insert({std::move(name), pointer})};\n      return result.first->first;\n    }\n  }\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/codegen/codegen_symbol.cc",
    "content": "#include <sourcemeta/blaze/codegen.h>\n\n#include <sourcemeta/core/uri.h>\n\n#include <algorithm>  // std::ranges::reverse\n#include <cassert>    // assert\n#include <filesystem> // std::filesystem::path\n#include <sstream>    // std::istringstream\n#include <string>     // std::string, std::getline\n#include <vector>     // std::vector\n\nnamespace {\n\n// Strip all extensions from a filename (e.g., \"user.schema.json\" -> \"user\")\nauto strip_extensions(const std::string &filename) -> std::string {\n  std::filesystem::path path{filename};\n  while (path.has_extension()) {\n    path = path.stem();\n  }\n  return path.string();\n}\n\n// If the input looks like an absolute URI, extract its path segments.\n// For file URIs, only the filename (without extensions) is used.\n// For other URIs, all path segments are used with extensions stripped from\n// the last segment.\n// Otherwise, add the input as a single segment.\n// Note: segments are added in reverse order because the caller reverses\n// the entire result at the end.\nauto push_token_segments(std::vector<std::string> &result,\n                         const std::string &value) -> void {\n  try {\n    const sourcemeta::core::URI uri{value};\n    if (uri.is_absolute()) {\n      const auto path{uri.path()};\n      if (path.has_value() && !path->empty()) {\n        std::vector<std::string> segments;\n        std::istringstream stream{std::string{path.value()}};\n        std::string segment;\n        while (std::getline(stream, segment, '/')) {\n          if (!segment.empty()) {\n            segments.emplace_back(segment);\n          }\n        }\n\n        if (!segments.empty()) {\n          // Strip extensions from the last segment\n          segments.back() = strip_extensions(segments.back());\n\n          // For file URIs, only use the filename\n          if (uri.is_file()) {\n            result.emplace_back(segments.back());\n          } else {\n            // Reverse segments since the caller will reverse the entire result\n            std::ranges::reverse(segments);\n            for (const auto &path_segment : segments) {\n              result.emplace_back(path_segment);\n            }\n          }\n\n          return;\n        }\n      }\n    }\n    // NOLINTNEXTLINE(bugprone-empty-catch)\n  } catch (const sourcemeta::core::URIParseError &) {\n    // Not a valid URI, fall through to default behavior\n  }\n\n  result.emplace_back(value);\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto symbol(const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location)\n    -> std::vector<std::string> {\n  std::vector<std::string> result;\n\n  auto current_pointer{location.pointer};\n\n  while (true) {\n    const auto current_location{frame.traverse(current_pointer)};\n    assert(current_location.has_value());\n\n    if (!current_location->get().parent.has_value()) {\n      break;\n    }\n\n    const auto &parent_pointer{current_location->get().parent.value()};\n    const auto segments_skipped{current_pointer.size() - parent_pointer.size()};\n    assert(segments_skipped >= 1);\n\n    if (segments_skipped >= 2) {\n      const auto &last_token{current_pointer.back()};\n      if (last_token.is_property()) {\n        push_token_segments(result, last_token.to_property());\n      } else {\n        result.emplace_back(std::to_string(last_token.to_index()));\n      }\n    } else {\n      const auto &token{current_pointer.back()};\n      if (token.is_property()) {\n        push_token_segments(result, token.to_property());\n      } else {\n        result.emplace_back(std::to_string(token.to_index()));\n      }\n    }\n\n    current_pointer = parent_pointer;\n  }\n\n  std::ranges::reverse(result);\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/codegen/codegen_typescript.cc",
    "content": "#include <sourcemeta/blaze/codegen.h>\n\n#include <algorithm> // std::ranges::any_of\n#include <iomanip>   // std::hex, std::setfill, std::setw\n#include <sstream>   // std::ostringstream\n\nnamespace {\n\n// TODO: Move to Core\nauto escape_string(const std::string &input) -> std::string {\n  std::ostringstream result;\n  for (const auto character : input) {\n    switch (character) {\n      case '\\\\':\n        result << \"\\\\\\\\\";\n        break;\n      case '\"':\n        result << \"\\\\\\\"\";\n        break;\n      case '\\b':\n        result << \"\\\\b\";\n        break;\n      case '\\f':\n        result << \"\\\\f\";\n        break;\n      case '\\n':\n        result << \"\\\\n\";\n        break;\n      case '\\r':\n        result << \"\\\\r\";\n        break;\n      case '\\t':\n        result << \"\\\\t\";\n        break;\n      default:\n        // Escape other control characters (< 0x20) using \\uXXXX format\n        if (static_cast<unsigned char>(character) < 0x20) {\n          result << \"\\\\u\" << std::hex << std::setfill('0') << std::setw(4)\n                 << static_cast<int>(static_cast<unsigned char>(character));\n        } else {\n          result << character;\n        }\n        break;\n    }\n  }\n\n  return result.str();\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nTypeScript::TypeScript(std::ostream &stream, const std::string_view type_prefix)\n    : output{stream}, prefix{type_prefix} {}\n\nauto TypeScript::operator()(const CodegenIRScalar &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = \";\n\n  switch (entry.value) {\n    case CodegenIRScalarType::String:\n      this->output << \"string\";\n      break;\n    case CodegenIRScalarType::Number:\n    case CodegenIRScalarType::Integer:\n      this->output << \"number\";\n      break;\n    case CodegenIRScalarType::Boolean:\n      this->output << \"boolean\";\n      break;\n    case CodegenIRScalarType::Null:\n      this->output << \"null\";\n      break;\n  }\n\n  this->output << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIREnumeration &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = \";\n\n  const char *separator{\"\"};\n  for (const auto &value : entry.values) {\n    this->output << separator;\n    sourcemeta::core::prettify(value, this->output);\n    separator = \" | \";\n  }\n\n  this->output << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRObject &entry) -> void {\n  const auto type_name{\n      mangle(this->prefix, entry.pointer, entry.symbol, this->cache)};\n  const auto has_typed_additional{\n      std::holds_alternative<CodegenIRType>(entry.additional)};\n  const auto allows_any_additional{\n      std::holds_alternative<bool>(entry.additional) &&\n      std::get<bool>(entry.additional)};\n\n  if (has_typed_additional && entry.members.empty() && entry.pattern.empty()) {\n    const auto &additional_type{std::get<CodegenIRType>(entry.additional)};\n    this->output << \"export type \" << type_name << \" = Record<string, \"\n                 << mangle(this->prefix, additional_type.pointer,\n                           additional_type.symbol, this->cache)\n                 << \">;\\n\";\n    return;\n  }\n\n  if (allows_any_additional && entry.members.empty() && entry.pattern.empty()) {\n    this->output << \"export type \" << type_name\n                 << \" = Record<string, unknown>;\\n\";\n    return;\n  }\n\n  this->output << \"export interface \" << type_name << \" {\\n\";\n\n  // We always quote property names for safety. JSON Schema allows any string\n  // as a property name, but unquoted TypeScript/ECMAScript property names\n  // must be valid IdentifierName productions (see ECMA-262 section 12.7).\n  // Quoting allows any string to be used as a property name.\n  // See: https://tc39.es/ecma262/#sec-names-and-keywords\n  // See: https://mathiasbynens.be/notes/javascript-properties\n  for (const auto &[member_name, member_value] : entry.members) {\n    const auto optional_marker{member_value.required ? \"\" : \"?\"};\n    const auto readonly_marker{member_value.immutable ? \"readonly \" : \"\"};\n\n    this->output << \"  \" << readonly_marker << \"\\\"\"\n                 << escape_string(member_name) << \"\\\"\" << optional_marker\n                 << \": \"\n                 << mangle(this->prefix, member_value.pointer,\n                           member_value.symbol, this->cache)\n                 << \";\\n\";\n  }\n\n  for (const auto &pattern_property : entry.pattern) {\n    if (!pattern_property.prefix.has_value()) {\n      continue;\n    }\n\n    this->output << \"  [key: `\" << pattern_property.prefix.value()\n                 << \"${string}`]: \"\n                 << mangle(this->prefix, pattern_property.pointer,\n                           pattern_property.symbol, this->cache);\n\n    // TypeScript requires that a more specific index signature type is\n    // assignable to any less specific one that overlaps it. When a prefix\n    // is a sub-prefix of another (i.e. \"x-data-\" starts with \"x-\"),\n    // intersect the types so the constraint is satisfied\n    for (const auto &other : entry.pattern) {\n      if (&other == &pattern_property || !other.prefix.has_value()) {\n        continue;\n      }\n\n      if (pattern_property.prefix.value().starts_with(other.prefix.value())) {\n        this->output << \" & \"\n                     << mangle(this->prefix, other.pointer, other.symbol,\n                               this->cache);\n      }\n    }\n\n    this->output << \";\\n\";\n  }\n\n  const auto has_non_prefix_pattern{\n      std::ranges::any_of(entry.pattern, [](const auto &pattern_property) {\n        return !pattern_property.prefix.has_value();\n      })};\n\n  if (allows_any_additional) {\n    this->output << \"  [key: string]: unknown | undefined;\\n\";\n  } else if (has_typed_additional || has_non_prefix_pattern) {\n    // TypeScript index signatures must be a supertype of all property value\n    // types. We use a union of all member types plus the additional properties\n    // type plus undefined (for optional properties).\n    this->output << \"  [key: string]:\\n\";\n    this->output << \"    // As a notable limitation, TypeScript requires index \"\n                    \"signatures\\n\";\n    this->output << \"    // to also include the types of all of its \"\n                    \"properties, so we must\\n\";\n    this->output << \"    // match a superset of what JSON Schema allows\\n\";\n    for (const auto &[member_name, member_value] : entry.members) {\n      this->output << \"    \"\n                   << mangle(this->prefix, member_value.pointer,\n                             member_value.symbol, this->cache)\n                   << \" |\\n\";\n    }\n\n    for (const auto &pattern_property : entry.pattern) {\n      this->output << \"    \"\n                   << mangle(this->prefix, pattern_property.pointer,\n                             pattern_property.symbol, this->cache)\n                   << \" |\\n\";\n    }\n\n    if (has_typed_additional) {\n      const auto &additional_type{std::get<CodegenIRType>(entry.additional)};\n      this->output << \"    \"\n                   << mangle(this->prefix, additional_type.pointer,\n                             additional_type.symbol, this->cache)\n                   << \" |\\n\";\n    }\n\n    this->output << \"    undefined;\\n\";\n  }\n\n  this->output << \"}\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRImpossible &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = never;\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRAny &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = unknown;\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRArray &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = \";\n\n  if (entry.items.has_value()) {\n    this->output << mangle(this->prefix, entry.items->pointer,\n                           entry.items->symbol, this->cache)\n                 << \"[]\";\n  } else {\n    this->output << \"unknown[]\";\n  }\n\n  this->output << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRReference &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = \"\n               << mangle(this->prefix, entry.target.pointer,\n                         entry.target.symbol, this->cache)\n               << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRTuple &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" = [\";\n\n  const char *separator{\"\"};\n  for (const auto &item : entry.items) {\n    this->output << separator\n                 << mangle(this->prefix, item.pointer, item.symbol,\n                           this->cache);\n    separator = \", \";\n  }\n\n  if (entry.additional.has_value()) {\n    this->output << separator << \"...\"\n                 << mangle(this->prefix, entry.additional->pointer,\n                           entry.additional->symbol, this->cache)\n                 << \"[]\";\n  }\n\n  this->output << \"];\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRUnion &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" =\\n\";\n\n  const char *separator{\"\"};\n  for (const auto &value : entry.values) {\n    this->output << separator << \"  \"\n                 << mangle(this->prefix, value.pointer, value.symbol,\n                           this->cache);\n    separator = \" |\\n\";\n  }\n\n  this->output << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRIntersection &entry) -> void {\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" =\\n\";\n\n  const char *separator{\"\"};\n  for (const auto &value : entry.values) {\n    this->output << separator << \"  \"\n                 << mangle(this->prefix, value.pointer, value.symbol,\n                           this->cache);\n    separator = \" &\\n\";\n  }\n\n  this->output << \";\\n\";\n}\n\nauto TypeScript::operator()(const CodegenIRConditional &entry) -> void {\n  // As a notable limitation, TypeScript cannot express the negation of an\n  // if/then/else condition, so the else branch is wider than what JSON\n  // Schema allows\n  this->output << \"// (if & then) | else approximation: the else branch is \"\n                  \"wider than what\\n\";\n  this->output << \"// JSON Schema allows, as TypeScript cannot express type \"\n                  \"negation\\n\";\n  this->output << \"export type \"\n               << mangle(this->prefix, entry.pointer, entry.symbol, this->cache)\n               << \" =\\n  (\"\n               << mangle(this->prefix, entry.condition.pointer,\n                         entry.condition.symbol, this->cache)\n               << \" & \"\n               << mangle(this->prefix, entry.consequent.pointer,\n                         entry.consequent.symbol, this->cache)\n               << \") | \"\n               << mangle(this->prefix, entry.alternative.pointer,\n                         entry.alternative.symbol, this->cache)\n               << \";\\n\";\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/codegen/include/sourcemeta/blaze/codegen.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CODEGEN_H_\n#define SOURCEMETA_BLAZE_CODEGEN_H_\n\n#ifndef SOURCEMETA_BLAZE_CODEGEN_EXPORT\n#include <sourcemeta/blaze/codegen_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/blaze/codegen_error.h>\n#include <sourcemeta/blaze/codegen_typescript.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cstdint>     // std::uint8_t\n#include <functional>  // std::function\n#include <map>         // std::map\n#include <optional>    // std::optional, std::nullopt\n#include <ostream>     // std::ostream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n#include <variant>     // std::variant, std::visit\n#include <vector>      // std::vector\n\n/// @defgroup codegen Codegen\n/// @brief A code generation utility built on top of Blaze\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup codegen\nenum class CodegenIRScalarType : std::uint8_t {\n  String,\n  Number,\n  Integer,\n  Boolean,\n  Null\n};\n\n/// @ingroup codegen\nstruct CodegenIRType {\n  sourcemeta::core::Pointer pointer;\n  std::vector<std::string> symbol;\n};\n\n/// @ingroup codegen\nstruct CodegenIRScalar : CodegenIRType {\n  CodegenIRScalarType value;\n};\n\n/// @ingroup codegen\nstruct CodegenIREnumeration : CodegenIRType {\n  std::vector<sourcemeta::core::JSON> values;\n};\n\n/// @ingroup codegen\nstruct CodegenIRUnion : CodegenIRType {\n  std::vector<CodegenIRType> values;\n};\n\n/// @ingroup codegen\nstruct CodegenIRIntersection : CodegenIRType {\n  std::vector<CodegenIRType> values;\n};\n\n/// @ingroup codegen\nstruct CodegenIRObjectValue : CodegenIRType {\n  bool required;\n  bool immutable;\n};\n\n/// @ingroup codegen\nstruct CodegenIRObjectPatternProperty : CodegenIRType {\n  std::optional<std::string> prefix;\n};\n\n/// @ingroup codegen\nstruct CodegenIRObject : CodegenIRType {\n  // To preserve the user's ordering\n  std::vector<std::pair<sourcemeta::core::JSON::String, CodegenIRObjectValue>>\n      members;\n  std::variant<bool, CodegenIRType> additional;\n  std::vector<CodegenIRObjectPatternProperty> pattern;\n};\n\n/// @ingroup codegen\nstruct CodegenIRArray : CodegenIRType {\n  std::optional<CodegenIRType> items;\n};\n\n/// @ingroup codegen\nstruct CodegenIRTuple : CodegenIRType {\n  std::vector<CodegenIRType> items;\n  std::optional<CodegenIRType> additional;\n};\n\n/// @ingroup codegen\nstruct CodegenIRImpossible : CodegenIRType {};\n\n/// @ingroup codegen\nstruct CodegenIRAny : CodegenIRType {};\n\n/// @ingroup codegen\nstruct CodegenIRConditional : CodegenIRType {\n  CodegenIRType condition;\n  CodegenIRType consequent;\n  CodegenIRType alternative;\n};\n\n/// @ingroup codegen\nstruct CodegenIRReference : CodegenIRType {\n  CodegenIRType target;\n};\n\n/// @ingroup codegen\nusing CodegenIREntity =\n    std::variant<CodegenIRObject, CodegenIRScalar, CodegenIREnumeration,\n                 CodegenIRUnion, CodegenIRIntersection, CodegenIRConditional,\n                 CodegenIRArray, CodegenIRTuple, CodegenIRImpossible,\n                 CodegenIRAny, CodegenIRReference>;\n\n/// @ingroup codegen\nusing CodegenIRResult = std::vector<CodegenIREntity>;\n\n/// @ingroup codegen\nusing CodegenCompiler = std::function<CodegenIREntity(\n    const sourcemeta::core::JSON &, const sourcemeta::core::SchemaFrame &,\n    const sourcemeta::core::SchemaFrame::Location &,\n    const sourcemeta::core::SchemaResolver &, const sourcemeta::core::JSON &)>;\n\n/// @ingroup codegen\nSOURCEMETA_BLAZE_CODEGEN_EXPORT\nauto default_compiler(const sourcemeta::core::JSON &schema,\n                      const sourcemeta::core::SchemaFrame &frame,\n                      const sourcemeta::core::SchemaFrame::Location &location,\n                      const sourcemeta::core::SchemaResolver &resolver,\n                      const sourcemeta::core::JSON &subschema)\n    -> CodegenIREntity;\n\n/// @ingroup codegen\nSOURCEMETA_BLAZE_CODEGEN_EXPORT\nauto compile(const sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const CodegenCompiler &compiler,\n             const std::string_view default_dialect = \"\",\n             const std::string_view default_id = \"\") -> CodegenIRResult;\n\n/// @ingroup codegen\nSOURCEMETA_BLAZE_CODEGEN_EXPORT\nauto symbol(const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaFrame::Location &location)\n    -> std::vector<std::string>;\n\n/// @ingroup codegen\nSOURCEMETA_BLAZE_CODEGEN_EXPORT\nauto mangle(const std::string_view prefix,\n            const sourcemeta::core::Pointer &pointer,\n            const std::vector<std::string> &symbol,\n            std::map<std::string, sourcemeta::core::Pointer> &cache)\n    -> const std::string &;\n\n/// @ingroup codegen\ntemplate <typename T>\nauto generate(std::ostream &output, const CodegenIRResult &result,\n              const std::string_view prefix = \"Schema\") -> void {\n  T visitor{output, prefix};\n  const char *separator{\"\"};\n  for (const auto &entity : result) {\n    output << separator;\n    separator = \"\\n\";\n    std::visit(visitor, entity);\n  }\n}\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/codegen/include/sourcemeta/blaze/codegen_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CODEGEN_ERROR_H_\n#define SOURCEMETA_BLAZE_CODEGEN_ERROR_H_\n\n#ifndef SOURCEMETA_BLAZE_CODEGEN_EXPORT\n#include <sourcemeta/blaze/codegen_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup codegen\n/// An error that represents an unsupported keyword during IR compilation\nclass SOURCEMETA_BLAZE_CODEGEN_EXPORT CodegenUnsupportedKeywordError\n    : public std::exception {\npublic:\n  CodegenUnsupportedKeywordError(sourcemeta::core::JSON json,\n                                 sourcemeta::core::Pointer pointer,\n                                 std::string keyword, const char *message)\n      : json_{std::move(json)}, pointer_{std::move(pointer)},\n        keyword_{std::move(keyword)}, message_{message} {}\n  CodegenUnsupportedKeywordError(sourcemeta::core::JSON json,\n                                 const sourcemeta::core::WeakPointer &pointer,\n                                 std::string keyword, const char *message)\n      : CodegenUnsupportedKeywordError{std::move(json),\n                                       sourcemeta::core::to_pointer(pointer),\n                                       std::move(keyword), message} {}\n  CodegenUnsupportedKeywordError(sourcemeta::core::JSON json,\n                                 sourcemeta::core::Pointer pointer,\n                                 std::string keyword,\n                                 std::string message) = delete;\n  CodegenUnsupportedKeywordError(sourcemeta::core::JSON json,\n                                 sourcemeta::core::Pointer pointer,\n                                 std::string keyword,\n                                 std::string &&message) = delete;\n  CodegenUnsupportedKeywordError(sourcemeta::core::JSON json,\n                                 sourcemeta::core::Pointer pointer,\n                                 std::string keyword,\n                                 std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto json() const noexcept -> const sourcemeta::core::JSON & {\n    return this->json_;\n  }\n\n  [[nodiscard]] auto pointer() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->pointer_;\n  }\n\n  [[nodiscard]] auto keyword() const noexcept -> std::string_view {\n    return this->keyword_;\n  }\n\nprivate:\n  sourcemeta::core::JSON json_;\n  sourcemeta::core::Pointer pointer_;\n  std::string keyword_;\n  const char *message_;\n};\n\n/// @ingroup codegen\n/// An error that represents an unsupported keyword value during IR compilation\nclass SOURCEMETA_BLAZE_CODEGEN_EXPORT CodegenUnsupportedKeywordValueError\n    : public std::exception {\npublic:\n  CodegenUnsupportedKeywordValueError(sourcemeta::core::JSON json,\n                                      sourcemeta::core::Pointer pointer,\n                                      std::string keyword, const char *message)\n      : json_{std::move(json)}, pointer_{std::move(pointer)},\n        keyword_{std::move(keyword)}, message_{message} {}\n  CodegenUnsupportedKeywordValueError(\n      sourcemeta::core::JSON json, const sourcemeta::core::WeakPointer &pointer,\n      std::string keyword, const char *message)\n      : CodegenUnsupportedKeywordValueError{\n            std::move(json), sourcemeta::core::to_pointer(pointer),\n            std::move(keyword), message} {}\n  CodegenUnsupportedKeywordValueError(sourcemeta::core::JSON json,\n                                      sourcemeta::core::Pointer pointer,\n                                      std::string keyword,\n                                      std::string message) = delete;\n  CodegenUnsupportedKeywordValueError(sourcemeta::core::JSON json,\n                                      sourcemeta::core::Pointer pointer,\n                                      std::string keyword,\n                                      std::string &&message) = delete;\n  CodegenUnsupportedKeywordValueError(sourcemeta::core::JSON json,\n                                      sourcemeta::core::Pointer pointer,\n                                      std::string keyword,\n                                      std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto json() const noexcept -> const sourcemeta::core::JSON & {\n    return this->json_;\n  }\n\n  [[nodiscard]] auto pointer() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->pointer_;\n  }\n\n  [[nodiscard]] auto keyword() const noexcept -> std::string_view {\n    return this->keyword_;\n  }\n\nprivate:\n  sourcemeta::core::JSON json_;\n  sourcemeta::core::Pointer pointer_;\n  std::string keyword_;\n  const char *message_;\n};\n\n/// @ingroup codegen\n/// An error that represents an unexpected schema during IR compilation\nclass SOURCEMETA_BLAZE_CODEGEN_EXPORT CodegenUnexpectedSchemaError\n    : public std::exception {\npublic:\n  CodegenUnexpectedSchemaError(sourcemeta::core::JSON json,\n                               sourcemeta::core::Pointer pointer,\n                               const char *message)\n      : json_{std::move(json)}, pointer_{std::move(pointer)},\n        message_{message} {}\n  CodegenUnexpectedSchemaError(sourcemeta::core::JSON json,\n                               const sourcemeta::core::WeakPointer &pointer,\n                               const char *message)\n      : CodegenUnexpectedSchemaError{\n            std::move(json), sourcemeta::core::to_pointer(pointer), message} {}\n  CodegenUnexpectedSchemaError(sourcemeta::core::JSON json,\n                               sourcemeta::core::Pointer pointer,\n                               std::string message) = delete;\n  CodegenUnexpectedSchemaError(sourcemeta::core::JSON json,\n                               sourcemeta::core::Pointer pointer,\n                               std::string &&message) = delete;\n  CodegenUnexpectedSchemaError(sourcemeta::core::JSON json,\n                               sourcemeta::core::Pointer pointer,\n                               std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto json() const noexcept -> const sourcemeta::core::JSON & {\n    return this->json_;\n  }\n\n  [[nodiscard]] auto pointer() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->pointer_;\n  }\n\nprivate:\n  sourcemeta::core::JSON json_;\n  sourcemeta::core::Pointer pointer_;\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/codegen/include/sourcemeta/blaze/codegen_typescript.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CODEGEN_TYPESCRIPT_H_\n#define SOURCEMETA_BLAZE_CODEGEN_TYPESCRIPT_H_\n\n#ifndef SOURCEMETA_BLAZE_CODEGEN_EXPORT\n#include <sourcemeta/blaze/codegen_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <map>         // std::map\n#include <ostream>     // std::ostream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::blaze {\n\nstruct CodegenIRScalar;\nstruct CodegenIREnumeration;\nstruct CodegenIRObject;\nstruct CodegenIRImpossible;\nstruct CodegenIRAny;\nstruct CodegenIRArray;\nstruct CodegenIRReference;\nstruct CodegenIRTuple;\nstruct CodegenIRUnion;\nstruct CodegenIRIntersection;\nstruct CodegenIRConditional;\n\n/// @ingroup codegen\nclass SOURCEMETA_BLAZE_CODEGEN_EXPORT TypeScript {\npublic:\n  TypeScript(std::ostream &stream, std::string_view type_prefix);\n  auto operator()(const CodegenIRScalar &entry) -> void;\n  auto operator()(const CodegenIREnumeration &entry) -> void;\n  auto operator()(const CodegenIRObject &entry) -> void;\n  auto operator()(const CodegenIRImpossible &entry) -> void;\n  auto operator()(const CodegenIRAny &entry) -> void;\n  auto operator()(const CodegenIRArray &entry) -> void;\n  auto operator()(const CodegenIRReference &entry) -> void;\n  auto operator()(const CodegenIRTuple &entry) -> void;\n  auto operator()(const CodegenIRUnion &entry) -> void;\n  auto operator()(const CodegenIRIntersection &entry) -> void;\n  auto operator()(const CodegenIRConditional &entry) -> void;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)\n  std::ostream &output;\n  std::string_view prefix;\n  std::map<std::string, sourcemeta::core::Pointer> cache;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME compiler\n  FOLDER \"Blaze/Compiler\"\n  PRIVATE_HEADERS error.h unevaluated.h\n  SOURCES\n    compile.cc compile_json.cc\n    compile_helpers.h postprocess.h\n    default_compiler.cc unevaluated.cc\n    default_compiler_2020_12.h\n    default_compiler_2019_09.h\n    default_compiler_draft7.h\n    default_compiler_draft6.h\n    default_compiler_draft4.h\n    default_compiler_openapi.h)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME compiler)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_compiler PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_compiler PRIVATE\n  sourcemeta::core::regex)\ntarget_link_libraries(sourcemeta_blaze_compiler PUBLIC\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_blaze_compiler PRIVATE\n  sourcemeta::core::uri)\ntarget_link_libraries(sourcemeta_blaze_compiler PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_blaze_compiler PUBLIC\n  sourcemeta::blaze::evaluator)\n"
  },
  {
    "path": "vendor/blaze/src/compiler/compile.cc",
    "content": "#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <sourcemeta/core/jsonschema.h>\n\n#include <algorithm> // std::move, std::sort, std::unique\n#include <cassert>   // assert\n// TODO(C++23): Consider std::flat_map/std::flat_set when available in libc++\n#include <map>           // std::map\n#include <set>           // std::set\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <utility>       // std::move, std::pair\n#include <vector>        // std::vector\n\n#include \"compile_helpers.h\"\n#include \"postprocess.h\"\n\nnamespace {\n\nauto compile_subschema(const sourcemeta::blaze::Context &context,\n                       const sourcemeta::blaze::SchemaContext &schema_context,\n                       const sourcemeta::blaze::DynamicContext &dynamic_context,\n                       const std::string_view default_dialect)\n    -> sourcemeta::blaze::Instructions {\n  using namespace sourcemeta::blaze;\n  assert(is_schema(schema_context.schema));\n\n  // Handle boolean schemas earlier on, as nobody should be able to\n  // override what these mean.\n  if (schema_context.schema.is_boolean()) {\n    if (schema_context.schema.to_boolean()) {\n      return {};\n    } else {\n      return {make(\n          sourcemeta::blaze::InstructionIndex::AssertionFail, context,\n          schema_context,\n          {.keyword = KEYWORD_EMPTY,\n           .base_schema_location = dynamic_context.base_schema_location,\n           .base_instance_location = dynamic_context.base_instance_location},\n          ValueNone{})};\n    }\n  }\n\n  Instructions steps;\n  for (const auto &entry : sourcemeta::core::SchemaKeywordIterator{\n           schema_context.schema, context.walker, context.resolver,\n           default_dialect}) {\n    assert(entry.pointer.back().is_property());\n    const auto &keyword{entry.pointer.back().to_property()};\n    // Bases must not contain fragments\n    assert(!schema_context.base.fragment().has_value());\n    for (auto &&step : context.compiler(\n             context,\n             {.relative_pointer = schema_context.relative_pointer.concat(\n                  make_weak_pointer(keyword)),\n              .schema = schema_context.schema,\n              .vocabularies = entry.vocabularies,\n              .base = schema_context.base,\n              .is_property_name = schema_context.is_property_name},\n             {.keyword = keyword,\n              .base_schema_location = dynamic_context.base_schema_location,\n              .base_instance_location = dynamic_context.base_instance_location},\n             steps)) {\n      // Just a sanity check to ensure every keyword location is indeed valid\n      assert(context.frame.locations().contains(\n          {sourcemeta::core::SchemaReferenceType::Static,\n           context.extra[step.extra_index].keyword_location}));\n      steps.push_back(std::move(step));\n    }\n  }\n\n  return steps;\n}\n\n// TODO: Somehow move this logic up to `SchemaFrame`\nauto schema_frame_populate_target_types(\n    const sourcemeta::core::SchemaFrame &frame,\n    std::unordered_map<std::string_view, std::pair<bool, bool>> &target_types)\n    -> void {\n  for (const auto &reference : frame.references()) {\n    if (!reference.first.second.empty() &&\n        reference.first.second.back().is_property() &&\n        reference.first.second.back().to_property() == \"$schema\") {\n      continue;\n    }\n\n    const auto reference_location{frame.traverse(reference.first.second)};\n    assert(reference_location.has_value());\n    auto &context{target_types[reference.second.destination]};\n    if (reference_location->get().property_name) {\n      context.first = true;\n    } else {\n      context.second = true;\n    }\n  }\n\n  std::unordered_map<std::string_view, const sourcemeta::core::WeakPointer *>\n      destination_pointers;\n  for (const auto &[destination, _] : target_types) {\n    const auto destination_location{frame.traverse(destination)};\n    if (destination_location.has_value()) {\n      destination_pointers.emplace(destination,\n                                   &destination_location->get().pointer);\n    }\n  }\n\n  std::unordered_map<std::string_view, std::vector<std::string_view>>\n      references_within;\n  for (const auto &reference : frame.references()) {\n    if (!reference.first.second.empty() &&\n        reference.first.second.back().is_property() &&\n        reference.first.second.back().to_property() == \"$schema\") {\n      continue;\n    }\n\n    for (const auto &[destination, destination_pointer] :\n         destination_pointers) {\n      if (reference.first.second.starts_with(*destination_pointer) &&\n          reference.first.second.size() > destination_pointer->size()) {\n        references_within[destination].push_back(reference.second.destination);\n      }\n    }\n  }\n\n  bool changed{true};\n  while (changed) {\n    changed = false;\n    for (const auto &[current_destination, context] : target_types) {\n      if (!context.first) {\n        continue;\n      }\n\n      const auto iterator{references_within.find(current_destination)};\n      if (iterator == references_within.end()) {\n        continue;\n      }\n\n      for (const auto &referenced_destination : iterator->second) {\n        auto &next_context{target_types[referenced_destination]};\n        if (!next_context.first) {\n          next_context.first = true;\n          changed = true;\n        }\n      }\n    }\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto compile(const sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const Compiler &compiler,\n             const sourcemeta::core::SchemaFrame &frame,\n             const std::string_view entrypoint, const Mode mode,\n             const std::optional<Tweaks> &tweaks) -> Template {\n  assert(is_schema(schema));\n  const auto effective_tweaks{tweaks.value_or(Tweaks{})};\n\n  const auto maybe_entrypoint_location{frame.traverse(entrypoint)};\n  if (!maybe_entrypoint_location.has_value()) [[unlikely]] {\n    throw CompilerInvalidEntryPoint{\n        entrypoint, \"The given entry point URI does not exist in the schema\"};\n  }\n\n  const auto &entrypoint_location{maybe_entrypoint_location->get()};\n  if (entrypoint_location.type ==\n      sourcemeta::core::SchemaFrame::LocationType::Pointer) [[unlikely]] {\n    throw CompilerInvalidEntryPoint{\n        entrypoint, \"The given entry point URI is not a valid subschema\"};\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (1) Determine all the schema resources in the schema\n  ///////////////////////////////////////////////////////////////////\n\n  std::vector<std::string> resources;\n  for (const auto &entry : frame.locations()) {\n    if (entry.second.type ==\n        sourcemeta::core::SchemaFrame::LocationType::Resource) {\n      resources.push_back(entry.first.second);\n    }\n  }\n\n  // Rule out any duplicates as we will use this list as the\n  // source for a perfect hash function on schema resources.\n  std::ranges::sort(resources);\n  auto [first, last] = std::ranges::unique(resources);\n  resources.erase(first, last);\n  assert(resources.size() ==\n         std::set<std::string>(resources.cbegin(), resources.cend()).size());\n\n  ///////////////////////////////////////////////////////////////////\n  // (2) Check if the schema relies on dynamic scopes\n  ///////////////////////////////////////////////////////////////////\n\n  bool uses_dynamic_scopes{false};\n  for (const auto &reference : frame.references()) {\n    // Check whether dynamic referencing takes places in this schema. If not,\n    // we can avoid the overhead of keeping track of dynamics scopes, etc\n    if (reference.first.first ==\n        sourcemeta::core::SchemaReferenceType::Dynamic) {\n      uses_dynamic_scopes = true;\n      break;\n    }\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (3) Plan which static references we will precompile\n  ///////////////////////////////////////////////////////////////////\n\n  std::unordered_map<std::string_view, std::pair<bool, bool>> target_types;\n  schema_frame_populate_target_types(frame, target_types);\n\n  std::map<\n      std::tuple<sourcemeta::core::SchemaReferenceType, std::string_view, bool>,\n      std::pair<std::size_t, const sourcemeta::core::WeakPointer *>>\n      targets_map;\n  targets_map.emplace(\n      std::make_tuple(sourcemeta::core::SchemaReferenceType::Static, entrypoint,\n                      false),\n      std::make_pair(0, nullptr));\n\n  for (const auto &reference : frame.references()) {\n    // Ignore meta-schema references\n    if (!reference.first.second.empty() &&\n        reference.first.second.back().is_property() &&\n        reference.first.second.back().to_property() == \"$schema\") {\n      continue;\n    }\n\n    auto reference_origin{frame.traverse(reference.first.second)};\n    assert(reference_origin.has_value());\n    while (reference_origin->get().type ==\n               sourcemeta::core::SchemaFrame::LocationType::Pointer &&\n           reference_origin->get().parent.has_value()) {\n      reference_origin = frame.traverse(reference_origin->get().parent.value());\n      assert(reference_origin.has_value());\n    }\n\n    // Skip unreachable targets\n    if (reference_origin->get().type !=\n            sourcemeta::core::SchemaFrame::LocationType::Pointer &&\n        !frame.is_reachable(entrypoint_location, reference_origin->get(),\n                            walker, resolver)) {\n      continue;\n    }\n\n    assert(target_types.contains(reference.second.destination));\n    const auto &[needs_name,\n                 needs_instance]{target_types.at(reference.second.destination)};\n\n    if (needs_name) {\n      targets_map.emplace(\n          std::make_tuple(reference.first.first,\n                          std::string_view{reference.second.destination}, true),\n          std::make_pair(targets_map.size(), &reference.first.second));\n    }\n\n    if (needs_instance) {\n      targets_map.emplace(\n          std::make_tuple(reference.first.first,\n                          std::string_view{reference.second.destination},\n                          false),\n          std::make_pair(targets_map.size(), &reference.first.second));\n    }\n  }\n\n  // Also add dynamic anchors that may not be directly referenced\n  // but could be used as override targets during dynamic resolution\n  for (const auto &entry : frame.locations()) {\n    if (entry.second.type !=\n            sourcemeta::core::SchemaFrame::LocationType::Anchor ||\n        entry.first.first != sourcemeta::core::SchemaReferenceType::Dynamic) {\n      continue;\n    }\n\n    // Skip unreachable dynamic anchors\n    if (!frame.is_reachable(entrypoint_location, entry.second, walker,\n                            resolver)) {\n      continue;\n    }\n\n    targets_map.emplace(std::make_tuple(entry.first.first,\n                                        std::string_view{entry.first.second},\n                                        false),\n                        std::make_pair(targets_map.size(), nullptr));\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (4) Build the global compilation context\n  ///////////////////////////////////////////////////////////////////\n\n  auto unevaluated{\n      sourcemeta::blaze::unevaluated(schema, frame, walker, resolver)};\n\n  std::vector<InstructionExtra> instruction_extra;\n  const Context context{.root = schema,\n                        .frame = frame,\n                        .resources = std::move(resources),\n                        .walker = walker,\n                        .resolver = resolver,\n                        .compiler = compiler,\n                        .mode = mode,\n                        .uses_dynamic_scopes = uses_dynamic_scopes,\n                        .unevaluated = std::move(unevaluated),\n                        .tweaks = effective_tweaks,\n                        .targets = std::move(targets_map),\n                        .extra = instruction_extra};\n\n  ///////////////////////////////////////////////////////////////////\n  // (5) Build labels map for dynamic anchors\n  ///////////////////////////////////////////////////////////////////\n\n  std::vector<std::pair<std::size_t, std::size_t>> labels_map;\n  if (uses_dynamic_scopes) {\n    for (const auto &entry : context.frame.locations()) {\n      // We are only trying to find dynamic anchors\n      if (entry.second.type !=\n              sourcemeta::core::SchemaFrame::LocationType::Anchor ||\n          entry.first.first != sourcemeta::core::SchemaReferenceType::Dynamic) {\n        continue;\n      }\n\n      // Skip unreachable dynamic anchors\n      if (!context.frame.is_reachable(entrypoint_location, entry.second,\n                                      context.walker, context.resolver)) {\n        continue;\n      }\n\n      // Compute the hash for this dynamic anchor\n      const sourcemeta::core::URI anchor_uri{entry.first.second};\n      const auto label{Evaluator::hash(\n          schema_resource_id(\n              context.resources,\n              anchor_uri.recompose_without_fragment().value_or(\"\")),\n          anchor_uri.fragment().value_or(\"\"))};\n\n      // Find the index in targets for this dynamic anchor\n      const auto key{\n          std::make_tuple(sourcemeta::core::SchemaReferenceType::Dynamic,\n                          std::string_view{entry.first.second}, false)};\n      assert(context.targets.contains(key));\n      const auto index{context.targets.at(key).first};\n      assert(index < context.targets.size());\n\n      labels_map.emplace_back(label, index);\n    }\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (6) Compile targets for static references\n  ///////////////////////////////////////////////////////////////////\n\n  std::vector<Instructions> compiled_targets;\n  compiled_targets.resize(context.targets.size());\n  for (const auto &[destination, target_info] : context.targets) {\n    const auto &[reference_type, destination_uri, is_property_name] =\n        destination;\n    const auto &[index, reference_pointer] = target_info;\n    const auto location{context.frame.traverse(destination_uri)};\n    assert(location.has_value());\n    const auto &entry{location->get()};\n\n    if (entry.type != sourcemeta::core::SchemaFrame::LocationType::Subschema &&\n        entry.type != sourcemeta::core::SchemaFrame::LocationType::Resource &&\n        entry.type != sourcemeta::core::SchemaFrame::LocationType::Anchor)\n        [[unlikely]] {\n      assert(reference_pointer != nullptr);\n      const auto parent_size{entry.parent ? entry.parent->size() : 0};\n      throw CompilerReferenceTargetNotSchemaError(\n          destination_uri,\n          to_pointer(entry.pointer.slice(\n              0, std::min(parent_size + 1, entry.pointer.size()))));\n    }\n\n    auto subschema{sourcemeta::core::get(context.root, entry.pointer)};\n    auto nested_vocabularies{sourcemeta::core::vocabularies(\n        subschema, context.resolver, entry.dialect)};\n    const auto nested_relative_pointer{\n        entry.pointer.slice(entry.relative_pointer)};\n    const sourcemeta::core::URI nested_base{entry.base};\n\n    const SchemaContext schema_context{\n        .relative_pointer = nested_relative_pointer,\n        .schema = std::move(subschema),\n        .vocabularies = std::move(nested_vocabularies),\n        .base = nested_base,\n        .is_property_name = is_property_name};\n\n    compiled_targets[index] =\n        compile(context, schema_context, relative_dynamic_context(),\n                sourcemeta::core::empty_weak_pointer,\n                sourcemeta::core::empty_weak_pointer, destination_uri);\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (7) Postprocess compiled targets\n  ///////////////////////////////////////////////////////////////////\n\n  if (mode == Mode::FastValidation) {\n    postprocess(compiled_targets, instruction_extra, effective_tweaks,\n                uses_dynamic_scopes);\n  }\n\n  ///////////////////////////////////////////////////////////////////\n  // (8) Return final template\n  ///////////////////////////////////////////////////////////////////\n\n  const bool track{\n      context.mode != Mode::FastValidation ||\n      requires_evaluation(context, entrypoint_location.pointer) ||\n      // TODO: This expression should go away if we start properly compiling\n      // `unevaluatedItems` like we compile `unevaluatedProperties`\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n  return {.dynamic = uses_dynamic_scopes,\n          .track = track,\n          .targets = std::move(compiled_targets),\n          .labels = std::move(labels_map),\n          .extra = std::move(instruction_extra)};\n}\n\nauto compile(const sourcemeta::core::JSON &schema,\n             const sourcemeta::core::SchemaWalker &walker,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const Compiler &compiler, const Mode mode,\n             const std::string_view default_dialect,\n             const std::string_view default_id,\n             const std::string_view entrypoint,\n             const std::optional<Tweaks> &tweaks) -> Template {\n  assert(is_schema(schema));\n\n  // Make sure the input schema is bundled, otherwise we won't be able to\n  // resolve remote references here\n  const sourcemeta::core::JSON result{sourcemeta::core::bundle(\n      schema, walker, resolver, default_dialect, default_id)};\n\n  sourcemeta::core::SchemaFrame frame{\n      sourcemeta::core::SchemaFrame::Mode::References};\n  frame.analyse(result, walker, resolver, default_dialect, default_id);\n  return compile(result, walker, resolver, compiler, frame,\n                 entrypoint.empty() ? frame.root() : entrypoint, mode, tweaks);\n}\n\nauto compile(const Context &context, const SchemaContext &schema_context,\n             const DynamicContext &dynamic_context,\n             const sourcemeta::core::WeakPointer &schema_suffix,\n             const sourcemeta::core::WeakPointer &instance_suffix,\n             const std::optional<std::string_view> uri) -> Instructions {\n  // Determine URI of the destination after recursion\n  const std::string destination{\n      uri.has_value()\n          ? sourcemeta::core::URI::canonicalize(uri.value())\n          : to_uri(schema_context.relative_pointer.concat(schema_suffix),\n                   schema_context.base)\n                .canonicalize()\n                .recompose()};\n\n  // Otherwise the recursion attempt is non-sense\n  if (!context.frame.locations().contains(\n          {sourcemeta::core::SchemaReferenceType::Static, destination}))\n      [[unlikely]] {\n    throw sourcemeta::core::SchemaReferenceError(\n        destination, to_pointer(schema_context.relative_pointer),\n        \"The target of the reference does not exist in the schema\");\n  }\n\n  const auto &entry{context.frame.locations().at(\n      {sourcemeta::core::SchemaReferenceType::Static, destination})};\n  const auto &new_schema{get(context.root, entry.pointer)};\n  assert(is_schema(new_schema));\n\n  const sourcemeta::core::WeakPointer destination_pointer{\n      dynamic_context.keyword.empty()\n          ? dynamic_context.base_schema_location.concat(schema_suffix)\n          : dynamic_context.base_schema_location\n                .concat(make_weak_pointer(dynamic_context.keyword))\n                .concat(schema_suffix)};\n\n  const auto new_relative_pointer{entry.pointer.slice(entry.relative_pointer)};\n  const sourcemeta::core::URI new_base{\n      sourcemeta::core::URI{entry.base}.recompose_without_fragment().value_or(\n          \"\")};\n\n  return compile_subschema(\n      context,\n      {.relative_pointer = new_relative_pointer,\n       .schema = new_schema,\n       .vocabularies =\n           vocabularies(new_schema, context.resolver, entry.dialect),\n       .base = new_base,\n       .is_property_name = schema_context.is_property_name},\n      {.keyword = dynamic_context.keyword,\n       .base_schema_location = destination_pointer,\n       .base_instance_location =\n           dynamic_context.base_instance_location.concat(instance_suffix)},\n      entry.dialect);\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/compiler/compile_helpers.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_COMPILE_HELPERS_H_\n#define SOURCEMETA_BLAZE_COMPILER_COMPILE_HELPERS_H_\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/core/uri.h>\n\n#include <algorithm>  // std::ranges::find, std::ranges::any_of\n#include <cassert>    // assert\n#include <functional> // std::cref\n#include <iterator>   // std::distance\n#include <regex>      // std::regex, std::regex_match, std::smatch\n#include <utility>    // std::declval, std::move\n\nnamespace sourcemeta::blaze {\n\n// Static keyword strings for use in DynamicContext references\nstatic const sourcemeta::core::JSON::String KEYWORD_EMPTY{};\nstatic const sourcemeta::core::JSON::String KEYWORD_PROPERTIES{\"properties\"};\nstatic const sourcemeta::core::JSON::String KEYWORD_THEN{\"then\"};\nstatic const sourcemeta::core::JSON::String KEYWORD_ELSE{\"else\"};\n\n// Helper to create a single-element WeakPointer from a property name reference\ninline auto make_weak_pointer(const std::string &property)\n    -> sourcemeta::core::WeakPointer {\n  sourcemeta::core::WeakPointer result;\n  result.push_back(std::cref(property));\n  return result;\n}\n\n// Helper to create a two-element WeakPointer from property name and index\ninline auto make_weak_pointer(const std::string &property,\n                              const std::size_t index)\n    -> sourcemeta::core::WeakPointer {\n  sourcemeta::core::WeakPointer result;\n  result.push_back(std::cref(property));\n  result.push_back(index);\n  return result;\n}\n\n// Helper to create a two-element WeakPointer from two property names\ninline auto make_weak_pointer(const std::string &property1,\n                              const std::string &property2)\n    -> sourcemeta::core::WeakPointer {\n  sourcemeta::core::WeakPointer result;\n  result.push_back(std::cref(property1));\n  result.push_back(std::cref(property2));\n  return result;\n}\n\ninline auto relative_dynamic_context() -> DynamicContext {\n  return {.keyword = KEYWORD_EMPTY,\n          .base_schema_location = sourcemeta::core::empty_weak_pointer,\n          .base_instance_location = sourcemeta::core::empty_weak_pointer};\n}\n\ninline auto schema_resource_id(const std::vector<std::string> &resources,\n                               const std::string_view resource) -> std::size_t {\n  const auto iterator{std::ranges::find(\n      resources, sourcemeta::core::URI::canonicalize(resource))};\n  if (iterator == resources.cend()) {\n    assert(resource.empty());\n    return 0;\n  }\n\n  return 1 +\n         static_cast<std::size_t>(std::distance(resources.cbegin(), iterator));\n}\n\n// Instantiate a value-oriented step with a custom resource\ninline auto make_with_resource(const InstructionIndex type,\n                               const Context &context,\n                               const SchemaContext &schema_context,\n                               const DynamicContext &dynamic_context,\n                               const Value &value, const std::string &resource)\n    -> Instruction {\n  const auto schema_location{\n      dynamic_context.keyword.empty()\n          ? to_pointer(dynamic_context.base_schema_location)\n          : to_pointer(dynamic_context.base_schema_location)\n                .concat({dynamic_context.keyword})};\n  const auto extra_index{context.extra.size()};\n  context.extra.push_back(\n      {.relative_schema_location = schema_location,\n       .keyword_location =\n           to_uri(schema_context.relative_pointer, schema_context.base)\n               .recompose(),\n       .schema_resource = schema_resource_id(context.resources, resource)});\n  return {.type = type,\n          .relative_instance_location =\n              to_pointer(dynamic_context.base_instance_location),\n          .value = value,\n          .children = {},\n          .extra_index = extra_index};\n}\n\n// Instantiate a value-oriented step\ninline auto make(const InstructionIndex type, const Context &context,\n                 const SchemaContext &schema_context,\n                 const DynamicContext &dynamic_context, const Value &value)\n    -> Instruction {\n  return make_with_resource(type, context, schema_context, dynamic_context,\n                            value, schema_context.base.recompose());\n}\n\n// Instantiate an applicator step\ninline auto make(const InstructionIndex type, const Context &context,\n                 const SchemaContext &schema_context,\n                 const DynamicContext &dynamic_context, Value &&value,\n                 Instructions &&children) -> Instruction {\n  const auto schema_location{\n      dynamic_context.keyword.empty()\n          ? to_pointer(dynamic_context.base_schema_location)\n          : to_pointer(dynamic_context.base_schema_location)\n                .concat({dynamic_context.keyword})};\n  const auto extra_index{context.extra.size()};\n  context.extra.push_back(\n      {.relative_schema_location = schema_location,\n       .keyword_location =\n           to_uri(schema_context.relative_pointer, schema_context.base)\n               .recompose(),\n       .schema_resource = schema_resource_id(context.resources,\n                                             schema_context.base.recompose())});\n  return {.type = type,\n          .relative_instance_location =\n              to_pointer(dynamic_context.base_instance_location),\n          .value = std::move(value),\n          .children = std::move(children),\n          .extra_index = extra_index};\n}\n\ninline auto unroll(const Context &context, const Instruction &step,\n                   const sourcemeta::core::WeakPointer &base_instance_location =\n                       sourcemeta::core::empty_weak_pointer) -> Instruction {\n  auto source_extra{context.extra[step.extra_index]};\n  const auto extra_index{context.extra.size()};\n  context.extra.push_back(std::move(source_extra));\n  return {.type = step.type,\n          .relative_instance_location =\n              to_pointer(base_instance_location)\n                  .concat(step.relative_instance_location),\n          .value = step.value,\n          .children = {},\n          .extra_index = extra_index};\n}\n\ninline auto rephrase(const Context &context, const InstructionIndex type,\n                     const Instruction &step) -> Instruction {\n  auto source_extra{context.extra[step.extra_index]};\n  const auto extra_index{context.extra.size()};\n  context.extra.push_back(std::move(source_extra));\n  return {.type = type,\n          .relative_instance_location = step.relative_instance_location,\n          .value = step.value,\n          .children = {},\n          .extra_index = extra_index};\n}\n\ninline auto\nunsigned_integer_property(const sourcemeta::core::JSON &document,\n                          const sourcemeta::core::JSON::String &property)\n    -> std::optional<std::size_t> {\n  if (document.defines(property) && document.at(property).is_integer()) {\n    const auto value{document.at(property).to_integer()};\n    assert(value >= 0);\n    return static_cast<std::size_t>(value);\n  }\n\n  return std::nullopt;\n}\n\ninline auto\nunsigned_integer_property(const sourcemeta::core::JSON &document,\n                          const sourcemeta::core::JSON::String &property,\n                          const std::size_t otherwise) -> std::size_t {\n  return unsigned_integer_property(document, property).value_or(otherwise);\n}\n\ninline auto static_frame_entry(const Context &context,\n                               const SchemaContext &schema_context)\n    -> const sourcemeta::core::SchemaFrame::Location & {\n  const auto current{\n      to_uri(schema_context.relative_pointer, schema_context.base).recompose()};\n  const auto type{sourcemeta::core::SchemaReferenceType::Static};\n  assert(context.frame.locations().contains({type, current}));\n  return context.frame.locations().at({type, current});\n}\n\ninline auto walk_subschemas(const Context &context,\n                            const SchemaContext &schema_context,\n                            const DynamicContext &dynamic_context) -> auto {\n  const auto &entry{static_frame_entry(context, schema_context)};\n  return sourcemeta::core::SchemaIterator{\n      schema_context.schema.at(dynamic_context.keyword), context.walker,\n      context.resolver, entry.dialect};\n}\n\n// TODO: Get rid of this given the new Core regex optimisations\ninline auto pattern_as_prefix(const std::string &pattern)\n    -> std::optional<std::string> {\n  static const std::regex starts_with_regex{R\"(^\\^([a-zA-Z0-9-_/]+)$)\"};\n  std::smatch matches;\n  if (std::regex_match(pattern, matches, starts_with_regex)) {\n    return matches[1].str();\n  } else {\n    return std::nullopt;\n  }\n}\n\ninline auto find_adjacent(const Context &context,\n                          const SchemaContext &schema_context,\n                          const std::set<std::string> &vocabularies,\n                          const std::string &keyword,\n                          const sourcemeta::core::JSON::Type type) -> auto {\n  std::vector<std::string> possible_keyword_uris;\n  possible_keyword_uris.push_back(\n      to_uri(schema_context.relative_pointer.initial().concat(\n                 make_weak_pointer(keyword)),\n             schema_context.base)\n          .recompose());\n\n  // TODO: Do something similar with `allOf`\n\n  // Attempt to statically follow references\n  static const std::string ref_keyword{\"$ref\"};\n  if (schema_context.schema.defines(\"$ref\")) {\n    const auto reference_type{sourcemeta::core::SchemaReferenceType::Static};\n    const auto destination_uri{\n        to_uri(schema_context.relative_pointer.initial().concat(\n                   make_weak_pointer(ref_keyword)),\n               schema_context.base)\n            .recompose()};\n    assert(\n        context.frame.locations().contains({reference_type, destination_uri}));\n    const auto &destination{\n        context.frame.locations().at({reference_type, destination_uri})};\n    assert(context.frame.references().contains(\n        {reference_type, destination.pointer}));\n    const auto &reference{\n        context.frame.references().at({reference_type, destination.pointer})};\n    const auto keyword_uri{\n        sourcemeta::core::to_uri(\n            sourcemeta::core::to_pointer(\n                std::string{reference.fragment.value_or(\"\")})\n                .concat({keyword}))\n            .resolve_from(sourcemeta::core::URI{reference.base})};\n\n    // TODO: When this logic is used by\n    // `unevaluatedProperties`/`unevaluatedItems`, how can we let the\n    // applicators we detect here know that they have already been taken into\n    // consideration and thus do not have to track evaluation?\n    possible_keyword_uris.push_back(keyword_uri.recompose());\n  }\n\n  std::vector<std::reference_wrapper<const sourcemeta::core::JSON>> result;\n\n  for (const auto &possible_keyword_uri : possible_keyword_uris) {\n    if (!context.frame.locations().contains(\n            {sourcemeta::core::SchemaReferenceType::Static,\n             possible_keyword_uri})) {\n      continue;\n    }\n\n    const auto &frame_entry{context.frame.locations().at(\n        {sourcemeta::core::SchemaReferenceType::Static, possible_keyword_uri})};\n    const auto &subschema{\n        sourcemeta::core::get(context.root, frame_entry.pointer)};\n    const auto &subschema_vocabularies{sourcemeta::core::vocabularies(\n        subschema, context.resolver, frame_entry.dialect)};\n\n    if (std::ranges::any_of(vocabularies,\n                            [&subschema_vocabularies](const auto &vocabulary) {\n                              return subschema_vocabularies.contains(\n                                  vocabulary);\n                            }) &&\n        subschema.type() == type) {\n      result.emplace_back(subschema);\n    }\n  }\n\n  return result;\n}\n\ninline auto recursive_template_size(const Instructions &steps) -> std::size_t {\n  std::size_t result{steps.size()};\n  for (const auto &variant : steps) {\n    result += recursive_template_size(variant.children);\n  }\n\n  return result;\n}\n\ninline auto make_property(const ValueString &property) -> ValueProperty {\n  static const sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n  return {property, hasher(property)};\n}\n\ninline auto requires_evaluation(const Context &context,\n                                const sourcemeta::core::WeakPointer &pointer)\n    -> bool {\n  for (const auto &unevaluated : context.unevaluated) {\n    if (unevaluated.second.unresolved ||\n        unevaluated.second.dynamic_dependencies.contains(pointer)) {\n      return true;\n    }\n\n    for (const auto &dependency : unevaluated.second.dynamic_dependencies) {\n      if (dependency.starts_with(pointer)) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n}\n\ninline auto requires_evaluation(const Context &context,\n                                const SchemaContext &schema_context) -> bool {\n  const auto &entry{static_frame_entry(context, schema_context)};\n  return requires_evaluation(context, entry.pointer);\n}\n\n// TODO: Elevate to Core and test\n\ninline auto\nis_circular(const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::WeakPointer &reference_origin,\n            const sourcemeta::core::SchemaFrame::ReferencesEntry &reference,\n            std::unordered_set<std::string> &visited) -> bool {\n  if (visited.contains(reference.destination)) {\n    return false;\n  }\n  visited.insert(reference.destination);\n\n  const auto destination_location{frame.traverse(reference.destination)};\n  if (!destination_location.has_value()) {\n    return false;\n  }\n\n  const auto &destination_pointer{destination_location->get().pointer};\n  if (reference_origin.starts_with(destination_pointer) ||\n      destination_pointer.starts_with(reference_origin)) {\n    return true;\n  }\n\n  for (const auto &ref_entry : frame.references()) {\n    if (ref_entry.first.first ==\n            sourcemeta::core::SchemaReferenceType::Static &&\n        ref_entry.first.second.starts_with(destination_pointer)) {\n      if (is_circular(frame, reference_origin, ref_entry.second, visited)) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n}\n\n// The set of property names that this schema declares as required at this\n// level\ninline auto required_properties(const SchemaContext &schema_context)\n    -> ValueStringSet {\n  using Known = sourcemeta::core::Vocabularies::Known;\n  const auto imports_validation_vocabulary{\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_4) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_6) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_7) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2019_09_Validation) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2020_12_Validation)};\n\n  ValueStringSet result;\n\n  if (imports_validation_vocabulary && schema_context.schema.is_object() &&\n      schema_context.schema.defines(\"required\") &&\n      schema_context.schema.at(\"required\").is_array()) {\n    for (const auto &entry : schema_context.schema.at(\"required\").as_array()) {\n      if (entry.is_string()) {\n        result.insert(entry.to_string());\n      }\n    }\n\n    return result;\n  }\n\n  const auto imports_draft3_vocabulary{\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper)};\n\n  if (imports_draft3_vocabulary && schema_context.schema.is_object() &&\n      schema_context.schema.defines(\"properties\") &&\n      schema_context.schema.at(\"properties\").is_object()) {\n    for (const auto &entry :\n         schema_context.schema.at(\"properties\").as_object()) {\n      if (entry.second.is_object() && entry.second.defines(\"required\") &&\n          entry.second.at(\"required\").is_boolean() &&\n          entry.second.at(\"required\").to_boolean()) {\n        result.insert(entry.first);\n      }\n    }\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/compile_json.cc",
    "content": "#include <sourcemeta/blaze/compiler.h>\n\n#include <cassert> // assert\n#include <variant> // std::visit\n\nnamespace {\nauto to_json(const sourcemeta::blaze::Instruction &instruction,\n             const std::vector<sourcemeta::blaze::InstructionExtra> &extra)\n    -> sourcemeta::core::JSON {\n  // Note that we purposely avoid objects to help consumers avoid potentially\n  // expensive hash-map or flat-map lookups when parsing back\n  auto result{sourcemeta::core::JSON::make_array()};\n  result.push_back(sourcemeta::core::to_json(instruction.type));\n\n  const auto &meta{extra[instruction.extra_index]};\n  result.push_back(sourcemeta::core::to_json(meta.relative_schema_location));\n  result.push_back(\n      sourcemeta::core::to_json(instruction.relative_instance_location));\n  result.push_back(sourcemeta::core::to_json(meta.keyword_location));\n  result.push_back(sourcemeta::core::to_json(meta.schema_resource));\n\n  // Note that we purposely avoid objects to help consumers avoid potentially\n  // expensive hash-map or flat-map lookups when parsing back\n  auto value{sourcemeta::core::JSON::make_array()};\n  const auto value_index{instruction.value.index()};\n  value.push_back(sourcemeta::core::to_json(value_index));\n  // Don't encode empty values, which tend to happen a lot\n  if (value_index != 0) {\n    value.push_back(std::visit(\n        [](const auto &variant) { return sourcemeta::core::to_json(variant); },\n        instruction.value));\n  }\n  assert(value.is_array());\n  assert(!value.empty());\n  assert(value.at(0).is_integer());\n  result.push_back(std::move(value));\n\n  if (!instruction.children.empty()) {\n    auto children_json{sourcemeta::core::JSON::make_array()};\n    result.push_back(sourcemeta::core::to_json(\n        instruction.children, [&extra](const auto &subinstruction) {\n          return to_json(subinstruction, extra);\n        }));\n  }\n\n  return result;\n}\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto to_json(const Template &schema_template) -> sourcemeta::core::JSON {\n  // Note that we purposely avoid objects to help consumers avoid potentially\n  // expensive hash-map or flat-map lookups when parsing back\n  auto result{sourcemeta::core::JSON::make_array()};\n  result.push_back(sourcemeta::core::JSON{\n      static_cast<std::int64_t>(sourcemeta::blaze::JSON_VERSION)});\n  result.push_back(sourcemeta::core::JSON{schema_template.dynamic});\n  result.push_back(sourcemeta::core::JSON{schema_template.track});\n\n  auto targets{sourcemeta::core::JSON::make_array()};\n  for (const auto &target : schema_template.targets) {\n    targets.push_back(sourcemeta::core::to_json(\n        target, [&schema_template](const auto &instruction) {\n          return ::to_json(instruction, schema_template.extra);\n        }));\n  }\n\n  result.push_back(std::move(targets));\n\n  auto labels{sourcemeta::core::JSON::make_array()};\n  for (const auto &[key, value] : schema_template.labels) {\n    auto pair{sourcemeta::core::JSON::make_array()};\n    pair.push_back(sourcemeta::core::JSON{static_cast<std::int64_t>(key)});\n    pair.push_back(sourcemeta::core::JSON{static_cast<std::int64_t>(value)});\n    labels.push_back(std::move(pair));\n  }\n  result.push_back(std::move(labels));\n\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler.cc",
    "content": "#include <sourcemeta/blaze/compiler.h>\n\n#include \"default_compiler_2019_09.h\"\n#include \"default_compiler_2020_12.h\"\n#include \"default_compiler_draft3.h\"\n#include \"default_compiler_draft4.h\"\n#include \"default_compiler_draft6.h\"\n#include \"default_compiler_draft7.h\"\n#include \"default_compiler_openapi.h\"\n\n#include <cassert>       // assert\n#include <string>        // std::string\n#include <unordered_set> // std::unordered_set\n\nauto sourcemeta::blaze::default_schema_compiler(\n    const sourcemeta::blaze::Context &context,\n    const sourcemeta::blaze::SchemaContext &schema_context,\n    const sourcemeta::blaze::DynamicContext &dynamic_context,\n    const sourcemeta::blaze::Instructions &current)\n    -> sourcemeta::blaze::Instructions {\n  assert(!dynamic_context.keyword.empty());\n\n  using Known = sourcemeta::core::Vocabularies::Known;\n  static std::unordered_set<sourcemeta::core::Vocabularies::URI>\n      SUPPORTED_VOCABULARIES{Known::JSON_Schema_2020_12_Core,\n                             Known::JSON_Schema_2020_12_Applicator,\n                             Known::JSON_Schema_2020_12_Unevaluated,\n                             Known::JSON_Schema_2020_12_Validation,\n                             Known::JSON_Schema_2020_12_Meta_Data,\n                             Known::JSON_Schema_2020_12_Format_Annotation,\n                             Known::JSON_Schema_2020_12_Content,\n                             Known::JSON_Schema_2019_09_Core,\n                             Known::JSON_Schema_2019_09_Applicator,\n                             Known::JSON_Schema_2019_09_Validation,\n                             Known::JSON_Schema_2019_09_Meta_Data,\n                             Known::JSON_Schema_2019_09_Format,\n                             Known::JSON_Schema_2019_09_Content,\n                             Known::JSON_Schema_2019_09_Hyper_Schema,\n                             Known::JSON_Schema_Draft_7,\n                             Known::JSON_Schema_Draft_7_Hyper,\n                             Known::JSON_Schema_Draft_6,\n                             Known::JSON_Schema_Draft_6_Hyper,\n                             Known::JSON_Schema_Draft_4,\n                             Known::JSON_Schema_Draft_4_Hyper,\n                             Known::JSON_Schema_Draft_3,\n                             Known::JSON_Schema_Draft_3_Hyper,\n                             Known::OpenAPI_3_1_Base,\n                             Known::OpenAPI_3_2_Base};\n\n  schema_context.vocabularies.throw_if_any_unsupported(\n      SUPPORTED_VOCABULARIES, \"Cannot compile unsupported vocabulary\");\n\n  using namespace sourcemeta::blaze;\n\n#define COMPILE(vocabulary, _keyword, handler)                                 \\\n  if (schema_context.vocabularies.contains(vocabulary) &&                      \\\n      dynamic_context.keyword == (_keyword)) {                                 \\\n    return internal::handler(context, schema_context, dynamic_context,         \\\n                             current);                                         \\\n  }\n\n#define COMPILE_ANY(vocabulary_1, vocabulary_2, _keyword, handler)             \\\n  if ((schema_context.vocabularies.contains(vocabulary_1) ||                   \\\n       schema_context.vocabularies.contains(vocabulary_2)) &&                  \\\n      dynamic_context.keyword == (_keyword)) {                                 \\\n    return internal::handler(context, schema_context, dynamic_context,         \\\n                             current);                                         \\\n  }\n\n#define STOP_IF_SIBLING_KEYWORD(vocabulary, _keyword)                          \\\n  if (schema_context.vocabularies.contains(vocabulary) &&                      \\\n      schema_context.schema.is_object() &&                                     \\\n      schema_context.schema.defines(_keyword)) {                               \\\n    return {};                                                                 \\\n  }\n\n  // ********************************************\n  // 2020-12\n  // ********************************************\n\n  COMPILE(Known::JSON_Schema_2020_12_Core, \"$dynamicRef\",\n          compiler_2020_12_core_dynamicref);\n\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"prefixItems\",\n          compiler_2020_12_applicator_prefixitems);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"items\",\n          compiler_2020_12_applicator_items);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"contains\",\n          compiler_2020_12_applicator_contains);\n\n  // Same as 2019-09\n\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"dependentRequired\",\n          compiler_2019_09_validation_dependentrequired);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"dependentSchemas\",\n          compiler_2019_09_applicator_dependentschemas);\n\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"properties\",\n          compiler_2019_09_applicator_properties);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"patternProperties\",\n          compiler_2019_09_applicator_patternproperties);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"additionalProperties\",\n          compiler_2019_09_applicator_additionalproperties);\n  COMPILE(Known::JSON_Schema_2020_12_Unevaluated, \"unevaluatedProperties\",\n          compiler_2019_09_applicator_unevaluatedproperties);\n  COMPILE(Known::JSON_Schema_2020_12_Unevaluated, \"unevaluatedItems\",\n          compiler_2019_09_applicator_unevaluateditems);\n  COMPILE(Known::JSON_Schema_2020_12_Content, \"contentEncoding\",\n          compiler_2019_09_content_contentencoding);\n  COMPILE(Known::JSON_Schema_2020_12_Content, \"contentMediaType\",\n          compiler_2019_09_content_contentmediatype);\n  COMPILE(Known::JSON_Schema_2020_12_Content, \"contentSchema\",\n          compiler_2019_09_content_contentschema);\n  COMPILE(Known::JSON_Schema_2020_12_Format_Annotation, \"format\",\n          compiler_2019_09_format_format);\n\n  // Same as Draft 7\n\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"if\",\n          compiler_draft7_applicator_if);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"then\",\n          compiler_draft7_applicator_then);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"else\",\n          compiler_draft7_applicator_else);\n\n  // Same as Draft 6\n\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"propertyNames\",\n          compiler_draft6_validation_propertynames);\n\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"type\",\n          compiler_draft6_validation_type);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"const\",\n          compiler_draft6_validation_const);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"exclusiveMaximum\",\n          compiler_draft6_validation_exclusivemaximum);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"exclusiveMinimum\",\n          compiler_draft6_validation_exclusiveminimum);\n\n  // Same as Draft 4\n\n  // As per compatibility optional test\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"dependencies\",\n          compiler_draft3_applicator_dependencies);\n\n  COMPILE(Known::JSON_Schema_2020_12_Core, \"$ref\", compiler_draft3_core_ref);\n\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"allOf\",\n          compiler_draft4_applicator_allof);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"anyOf\",\n          compiler_draft4_applicator_anyof);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"oneOf\",\n          compiler_draft4_applicator_oneof);\n  COMPILE(Known::JSON_Schema_2020_12_Applicator, \"not\",\n          compiler_draft4_applicator_not);\n\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"enum\",\n          compiler_draft3_validation_enum);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"uniqueItems\",\n          compiler_draft3_validation_uniqueitems);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"maxItems\",\n          compiler_draft3_validation_maxitems);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"minItems\",\n          compiler_draft3_validation_minitems);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"required\",\n          compiler_draft4_validation_required);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"maxProperties\",\n          compiler_draft4_validation_maxproperties);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"minProperties\",\n          compiler_draft4_validation_minproperties);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"maximum\",\n          compiler_draft3_validation_maximum);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"minimum\",\n          compiler_draft3_validation_minimum);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"multipleOf\",\n          compiler_draft3_validation_divisibleby);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"maxLength\",\n          compiler_draft3_validation_maxlength);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"minLength\",\n          compiler_draft3_validation_minlength);\n  COMPILE(Known::JSON_Schema_2020_12_Validation, \"pattern\",\n          compiler_draft3_validation_pattern);\n\n  // ********************************************\n  // 2019-09\n  // ********************************************\n\n  COMPILE(Known::JSON_Schema_2019_09_Core, \"$recursiveRef\",\n          compiler_2019_09_core_recursiveref);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"dependentRequired\",\n          compiler_2019_09_validation_dependentrequired);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"dependentSchemas\",\n          compiler_2019_09_applicator_dependentschemas);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"contains\",\n          compiler_2019_09_applicator_contains);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"unevaluatedItems\",\n          compiler_2019_09_applicator_unevaluateditems);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"unevaluatedProperties\",\n          compiler_2019_09_applicator_unevaluatedproperties);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"items\",\n          compiler_2019_09_applicator_items);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"additionalItems\",\n          compiler_2019_09_applicator_additionalitems);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"properties\",\n          compiler_2019_09_applicator_properties);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"patternProperties\",\n          compiler_2019_09_applicator_patternproperties);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"additionalProperties\",\n          compiler_2019_09_applicator_additionalproperties);\n  COMPILE(Known::JSON_Schema_2019_09_Content, \"contentEncoding\",\n          compiler_2019_09_content_contentencoding);\n  COMPILE(Known::JSON_Schema_2019_09_Content, \"contentMediaType\",\n          compiler_2019_09_content_contentmediatype);\n  COMPILE(Known::JSON_Schema_2019_09_Content, \"contentSchema\",\n          compiler_2019_09_content_contentschema);\n  COMPILE(Known::JSON_Schema_2019_09_Format, \"format\",\n          compiler_2019_09_format_format);\n\n  // Same as Draft 7\n\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"if\",\n          compiler_draft7_applicator_if);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"then\",\n          compiler_draft7_applicator_then);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"else\",\n          compiler_draft7_applicator_else);\n\n  // Same as Draft 6\n\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"propertyNames\",\n          compiler_draft6_validation_propertynames);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"type\",\n          compiler_draft6_validation_type);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"const\",\n          compiler_draft6_validation_const);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"exclusiveMaximum\",\n          compiler_draft6_validation_exclusivemaximum);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"exclusiveMinimum\",\n          compiler_draft6_validation_exclusiveminimum);\n\n  // Same as Draft 4\n\n  // As per compatibility optional test\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"dependencies\",\n          compiler_draft3_applicator_dependencies);\n\n  COMPILE(Known::JSON_Schema_2019_09_Core, \"$ref\", compiler_draft3_core_ref);\n\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"allOf\",\n          compiler_draft4_applicator_allof);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"anyOf\",\n          compiler_draft4_applicator_anyof);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"oneOf\",\n          compiler_draft4_applicator_oneof);\n  COMPILE(Known::JSON_Schema_2019_09_Applicator, \"not\",\n          compiler_draft4_applicator_not);\n\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"enum\",\n          compiler_draft3_validation_enum);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"uniqueItems\",\n          compiler_draft3_validation_uniqueitems);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"maxItems\",\n          compiler_draft3_validation_maxitems);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"minItems\",\n          compiler_draft3_validation_minitems);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"required\",\n          compiler_draft4_validation_required);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"maxProperties\",\n          compiler_draft4_validation_maxproperties);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"minProperties\",\n          compiler_draft4_validation_minproperties);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"maximum\",\n          compiler_draft3_validation_maximum);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"minimum\",\n          compiler_draft3_validation_minimum);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"multipleOf\",\n          compiler_draft3_validation_divisibleby);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"maxLength\",\n          compiler_draft3_validation_maxlength);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"minLength\",\n          compiler_draft3_validation_minlength);\n  COMPILE(Known::JSON_Schema_2019_09_Validation, \"pattern\",\n          compiler_draft3_validation_pattern);\n\n  // ********************************************\n  // DRAFT 7\n  // ********************************************\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"$ref\", compiler_draft3_core_ref);\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_7, \"$ref\");\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_7_Hyper, \"$ref\");\n\n  // Any\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"if\", compiler_draft7_applicator_if);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"then\", compiler_draft7_applicator_then);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"else\", compiler_draft7_applicator_else);\n\n  // Same as Draft 6\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"type\", compiler_draft6_validation_type);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"const\", compiler_draft6_validation_const);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"contains\", compiler_draft6_applicator_contains);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"propertyNames\", compiler_draft6_validation_propertynames);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"exclusiveMaximum\", compiler_draft6_validation_exclusivemaximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"exclusiveMinimum\", compiler_draft6_validation_exclusiveminimum);\n\n  // Same as Draft 4\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"allOf\", compiler_draft4_applicator_allof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"anyOf\", compiler_draft4_applicator_anyof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"oneOf\", compiler_draft4_applicator_oneof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"not\", compiler_draft4_applicator_not);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"enum\", compiler_draft3_validation_enum);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"items\", compiler_draft3_applicator_items);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"additionalItems\", compiler_draft3_applicator_additionalitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"uniqueItems\", compiler_draft3_validation_uniqueitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"maxItems\", compiler_draft3_validation_maxitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"minItems\", compiler_draft3_validation_minitems);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"required\", compiler_draft4_validation_required);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"maxProperties\", compiler_draft4_validation_maxproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"minProperties\", compiler_draft4_validation_minproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"properties\", compiler_draft3_applicator_properties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"patternProperties\",\n              compiler_draft3_applicator_patternproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"additionalProperties\",\n              compiler_draft3_applicator_additionalproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"dependencies\", compiler_draft3_applicator_dependencies);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"maximum\", compiler_draft3_validation_maximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"minimum\", compiler_draft3_validation_minimum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"multipleOf\", compiler_draft3_validation_divisibleby);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"maxLength\", compiler_draft3_validation_maxlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"minLength\", compiler_draft3_validation_minlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_7, Known::JSON_Schema_Draft_7_Hyper,\n              \"pattern\", compiler_draft3_validation_pattern);\n\n  // ********************************************\n  // DRAFT 6\n  // ********************************************\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"$ref\", compiler_draft3_core_ref);\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_6, \"$ref\");\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_6_Hyper, \"$ref\");\n\n  // Any\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"type\", compiler_draft6_validation_type);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"const\", compiler_draft6_validation_const);\n\n  // Array\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"contains\", compiler_draft6_applicator_contains);\n\n  // Object\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"propertyNames\", compiler_draft6_validation_propertynames);\n\n  // Number\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"exclusiveMaximum\", compiler_draft6_validation_exclusivemaximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"exclusiveMinimum\", compiler_draft6_validation_exclusiveminimum);\n\n  // Same as Draft 4\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"allOf\", compiler_draft4_applicator_allof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"anyOf\", compiler_draft4_applicator_anyof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"oneOf\", compiler_draft4_applicator_oneof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"not\", compiler_draft4_applicator_not);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"enum\", compiler_draft3_validation_enum);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"items\", compiler_draft3_applicator_items);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"additionalItems\", compiler_draft3_applicator_additionalitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"uniqueItems\", compiler_draft3_validation_uniqueitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"maxItems\", compiler_draft3_validation_maxitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"minItems\", compiler_draft3_validation_minitems);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"required\", compiler_draft4_validation_required);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"maxProperties\", compiler_draft4_validation_maxproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"minProperties\", compiler_draft4_validation_minproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"properties\", compiler_draft3_applicator_properties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"patternProperties\",\n              compiler_draft3_applicator_patternproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"additionalProperties\",\n              compiler_draft3_applicator_additionalproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"dependencies\", compiler_draft3_applicator_dependencies);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"maximum\", compiler_draft3_validation_maximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"minimum\", compiler_draft3_validation_minimum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"multipleOf\", compiler_draft3_validation_divisibleby);\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"maxLength\", compiler_draft3_validation_maxlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"minLength\", compiler_draft3_validation_minlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_6, Known::JSON_Schema_Draft_6_Hyper,\n              \"pattern\", compiler_draft3_validation_pattern);\n\n  // ********************************************\n  // DRAFT 4\n  // ********************************************\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"$ref\", compiler_draft3_core_ref);\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_4, \"$ref\");\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_4_Hyper, \"$ref\");\n\n  // Applicators\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"allOf\", compiler_draft4_applicator_allof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"anyOf\", compiler_draft4_applicator_anyof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"oneOf\", compiler_draft4_applicator_oneof);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"not\", compiler_draft4_applicator_not);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"properties\", compiler_draft3_applicator_properties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"patternProperties\",\n              compiler_draft3_applicator_patternproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"additionalProperties\",\n              compiler_draft3_applicator_additionalproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"items\", compiler_draft3_applicator_items);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"additionalItems\", compiler_draft3_applicator_additionalitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"dependencies\", compiler_draft3_applicator_dependencies);\n\n  // Any\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"type\", compiler_draft3_validation_type);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"enum\", compiler_draft3_validation_enum);\n\n  // Object\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"required\", compiler_draft4_validation_required);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"maxProperties\", compiler_draft4_validation_maxproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"minProperties\", compiler_draft4_validation_minproperties);\n\n  // Array\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"uniqueItems\", compiler_draft3_validation_uniqueitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"maxItems\", compiler_draft3_validation_maxitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"minItems\", compiler_draft3_validation_minitems);\n\n  // String\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"pattern\", compiler_draft3_validation_pattern);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"maxLength\", compiler_draft3_validation_maxlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"minLength\", compiler_draft3_validation_minlength);\n\n  // Number\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"maximum\", compiler_draft3_validation_maximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"minimum\", compiler_draft3_validation_minimum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_4, Known::JSON_Schema_Draft_4_Hyper,\n              \"multipleOf\", compiler_draft3_validation_divisibleby);\n\n  // ********************************************\n  // DRAFT 3\n  // ********************************************\n\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"$ref\", compiler_draft3_core_ref);\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_3, \"$ref\");\n  STOP_IF_SIBLING_KEYWORD(Known::JSON_Schema_Draft_3_Hyper, \"$ref\");\n\n  // Applicators\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"extends\", compiler_draft3_applicator_extends);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"properties\", compiler_draft3_applicator_properties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"patternProperties\",\n              compiler_draft3_applicator_patternproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"additionalProperties\",\n              compiler_draft3_applicator_additionalproperties);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"items\", compiler_draft3_applicator_items);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"additionalItems\", compiler_draft3_applicator_additionalitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"dependencies\", compiler_draft3_applicator_dependencies);\n\n  // Any\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"type\", compiler_draft3_validation_type);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"disallow\", compiler_draft3_validation_disallow);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"enum\", compiler_draft3_validation_enum);\n\n  // Array\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"uniqueItems\", compiler_draft3_validation_uniqueitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"maxItems\", compiler_draft3_validation_maxitems);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"minItems\", compiler_draft3_validation_minitems);\n\n  // String\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"pattern\", compiler_draft3_validation_pattern);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"maxLength\", compiler_draft3_validation_maxlength);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"minLength\", compiler_draft3_validation_minlength);\n\n  // Number\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"maximum\", compiler_draft3_validation_maximum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"minimum\", compiler_draft3_validation_minimum);\n  COMPILE_ANY(Known::JSON_Schema_Draft_3, Known::JSON_Schema_Draft_3_Hyper,\n              \"divisibleBy\", compiler_draft3_validation_divisibleby);\n\n  // ********************************************\n  // OpenAPI\n  // ********************************************\n\n  COMPILE_ANY(Known::OpenAPI_3_1_Base, Known::OpenAPI_3_2_Base, \"discriminator\",\n              compiler_openapi_noop);\n  COMPILE_ANY(Known::OpenAPI_3_1_Base, Known::OpenAPI_3_2_Base, \"xml\",\n              compiler_openapi_noop);\n  COMPILE_ANY(Known::OpenAPI_3_1_Base, Known::OpenAPI_3_2_Base, \"externalDocs\",\n              compiler_openapi_noop);\n  COMPILE_ANY(Known::OpenAPI_3_1_Base, Known::OpenAPI_3_2_Base, \"example\",\n              compiler_openapi_noop);\n\n#undef COMPILE\n#undef COMPILE_ANY\n#undef STOP_IF_SIBLING_KEYWORD\n\n  if ((schema_context.vocabularies.contains(Known::JSON_Schema_2019_09_Core) ||\n       schema_context.vocabularies.contains(Known::JSON_Schema_2020_12_Core)) &&\n      !dynamic_context.keyword.starts_with('$') &&\n      dynamic_context.keyword != \"definitions\") {\n\n    // We handle these keywords as part of \"contains\"\n    if ((schema_context.vocabularies.contains(\n             Known::JSON_Schema_2019_09_Validation) ||\n         schema_context.vocabularies.contains(\n             Known::JSON_Schema_2020_12_Validation)) &&\n        (dynamic_context.keyword == \"minContains\" ||\n         dynamic_context.keyword == \"maxContains\")) {\n      return {};\n    }\n\n    if (context.mode == Mode::FastValidation ||\n        schema_context.is_property_name) {\n      return {};\n    }\n\n    return internal::compiler_2019_09_core_annotation(context, schema_context,\n                                                      dynamic_context, current);\n  }\n\n  return {};\n}\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_2019_09.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_2019_09_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_2019_09_H_\n\n#include <sourcemeta/blaze/compiler.h>\n\n#include \"compile_helpers.h\"\n#include \"default_compiler_draft4.h\"\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compiler_2019_09_applicator_dependentschemas(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  Instructions children;\n\n  // To guarantee order\n  std::vector<std::string> dependents;\n  for (const auto &entry :\n       schema_context.schema.at(dynamic_context.keyword).as_object()) {\n    dependents.push_back(entry.first);\n  }\n  std::ranges::sort(dependents);\n\n  for (const auto &dependent : dependents) {\n    const auto &dependency{\n        schema_context.schema.at(dynamic_context.keyword).at(dependent)};\n    if (!is_schema(dependency)) {\n      continue;\n    }\n\n    if (!dependency.is_boolean() || !dependency.to_boolean()) {\n      children.push_back(make(\n          sourcemeta::blaze::InstructionIndex::LogicalWhenDefines, context,\n          schema_context, relative_dynamic_context(), make_property(dependent),\n          compile(context, schema_context, relative_dynamic_context(),\n                  sourcemeta::blaze::make_weak_pointer(dependent))));\n    }\n  }\n\n  // TODO: Is this wrapper really necessary?\n  return {make(sourcemeta::blaze::InstructionIndex::LogicalWhenType, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON::Type::Object, std::move(children))};\n}\n\nauto compiler_2019_09_validation_dependentrequired(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  ValueStringMap dependencies;\n  for (const auto &entry :\n       schema_context.schema.at(dynamic_context.keyword).as_object()) {\n    if (!entry.second.is_array()) {\n      continue;\n    }\n\n    std::vector<sourcemeta::core::JSON::String> properties;\n    for (const auto &property : entry.second.as_array()) {\n      assert(property.is_string());\n      properties.push_back(property.to_string());\n    }\n\n    if (!properties.empty()) {\n      dependencies.emplace(entry.first, properties);\n    }\n  }\n\n  if (dependencies.empty()) {\n    return {};\n  }\n\n  return {\n      make(sourcemeta::blaze::InstructionIndex::AssertionPropertyDependencies,\n           context, schema_context, dynamic_context, std::move(dependencies))};\n}\n\nauto compiler_2019_09_core_annotation(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  return {make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON{\n                   schema_context.schema.at(dynamic_context.keyword)})};\n}\n\nauto compiler_2019_09_applicator_contains_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &,\n    const bool annotate, const bool track_evaluation) -> Instructions {\n  if (schema_context.is_property_name) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  std::size_t minimum{1};\n  if (schema_context.schema.defines(\"minContains\")) {\n    if (schema_context.schema.at(\"minContains\").is_integer() &&\n        schema_context.schema.at(\"minContains\").is_positive()) {\n      minimum = static_cast<std::size_t>(\n          schema_context.schema.at(\"minContains\").to_integer());\n    } else if (schema_context.schema.at(\"minContains\").is_real() &&\n               schema_context.schema.at(\"minContains\").is_positive()) {\n      minimum = static_cast<std::size_t>(\n          schema_context.schema.at(\"minContains\").as_integer());\n    }\n  }\n\n  std::optional<std::size_t> maximum;\n  if (schema_context.schema.defines(\"maxContains\")) {\n    if (schema_context.schema.at(\"maxContains\").is_integer() &&\n        schema_context.schema.at(\"maxContains\").is_positive()) {\n      maximum = schema_context.schema.at(\"maxContains\").to_integer();\n    } else if (schema_context.schema.at(\"maxContains\").is_real() &&\n               schema_context.schema.at(\"maxContains\").is_positive()) {\n      maximum = schema_context.schema.at(\"maxContains\").as_integer();\n    }\n  }\n\n  if (maximum.has_value() && minimum > maximum.value()) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionFail, context,\n                 schema_context, dynamic_context, ValueNone{})};\n  }\n\n  if (minimum == 0 && !maximum.has_value() && !track_evaluation) {\n    return {};\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (annotate) {\n    children.push_back(\n        make(sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent,\n             context, schema_context, relative_dynamic_context(), ValueNone{}));\n\n    // TODO: If after emitting the above annotation, the number of annotations\n    // for the current schema location + instance location is equal to the\n    // array size (which means we annotated all of the items), then emit\n    // an annotation \"true\"\n  }\n\n  if (track_evaluation) {\n    children.push_back(\n        make(sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n             schema_context, relative_dynamic_context(), ValuePointer{}));\n  }\n\n  if (children.empty()) {\n    // We still need to check the instance is not empty\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionArraySizeGreater,\n                 context, schema_context, dynamic_context,\n                 ValueUnsignedInteger{0})};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::LoopContains, context,\n               schema_context, dynamic_context,\n               ValueRange{minimum, maximum, annotate || track_evaluation},\n               std::move(children))};\n}\n\nauto compiler_2019_09_applicator_contains(const Context &context,\n                                          const SchemaContext &schema_context,\n                                          const DynamicContext &dynamic_context,\n                                          const Instructions &current)\n    -> Instructions {\n  return compiler_2019_09_applicator_contains_with_options(\n      context, schema_context, dynamic_context, current, false, false);\n}\n\nauto compiler_2019_09_applicator_additionalproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n\n    -> Instructions {\n  return compiler_draft3_applicator_additionalproperties_with_options(\n      context, schema_context, dynamic_context,\n      context.mode == Mode::Exhaustive,\n      requires_evaluation(context, schema_context));\n}\n\nauto compiler_2019_09_applicator_items(const Context &context,\n                                       const SchemaContext &schema_context,\n                                       const DynamicContext &dynamic_context,\n                                       const Instructions &) -> Instructions {\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  if (schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return compiler_draft3_applicator_items_with_options(\n        context, schema_context, dynamic_context,\n        context.mode == Mode::Exhaustive, track);\n  }\n\n  return compiler_draft3_applicator_items_with_options(\n      context, schema_context, dynamic_context,\n      context.mode == Mode::Exhaustive,\n      track && !schema_context.schema.defines(\"unevaluatedItems\"));\n}\n\nauto compiler_2019_09_applicator_additionalitems(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  return compiler_draft3_applicator_additionalitems_with_options(\n      context, schema_context, dynamic_context,\n      context.mode == Mode::Exhaustive,\n      track && !schema_context.schema.defines(\"unevaluatedItems\"));\n}\n\nauto compiler_2019_09_applicator_unevaluateditems(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  const auto current_uri{\n      to_uri(schema_context.relative_pointer, schema_context.base).recompose()};\n  assert(context.unevaluated.contains(current_uri));\n  const auto &dependencies{context.unevaluated.at(current_uri)};\n\n  for (const auto &dependency : dependencies.static_dependencies) {\n    assert(!dependency.empty());\n    assert(dependency.back().is_property());\n    const auto &keyword{dependency.back().to_property()};\n    const auto &subschema{sourcemeta::core::get(context.root, dependency)};\n    // NOLINTBEGIN(bugprone-branch-clone)\n    if (keyword == \"items\" && sourcemeta::core::is_schema(subschema)) {\n      return {};\n    } else if (keyword == \"additionalItems\" || keyword == \"unevaluatedItems\") {\n      return {};\n    }\n    // NOLINTEND(bugprone-branch-clone)\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (context.mode == Mode::Exhaustive) {\n    children.push_back(\n        make(sourcemeta::blaze::InstructionIndex::AnnotationToParent, context,\n             schema_context, relative_dynamic_context(),\n             sourcemeta::core::JSON{true}));\n  }\n\n  if (children.empty()) {\n    if (dependencies.dynamic_dependencies.empty() && !dependencies.unresolved &&\n        !requires_evaluation(context, schema_context)) {\n      return {};\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::Evaluate, context,\n                 schema_context, dynamic_context, ValueNone{})};\n  }\n\n  // TODO: Attempt to short-circuit evaluation tracking by looking at sibling\n  // and adjacent keywords like we do for `unevaluatedProperties`\n\n  return {make(sourcemeta::blaze::InstructionIndex::LoopItemsUnevaluated,\n               context, schema_context, dynamic_context, ValueNone{},\n               std::move(children))};\n}\n\nauto compiler_2019_09_applicator_unevaluatedproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (context.mode == Mode::Exhaustive) {\n    children.push_back(\n        make(sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent,\n             context, schema_context, relative_dynamic_context(), ValueNone{}));\n  }\n\n  ValueStringSet filter_strings;\n  ValueStrings filter_prefixes;\n  std::vector<ValueRegex> filter_regexes;\n\n  const auto current_uri{\n      to_uri(schema_context.relative_pointer, schema_context.base).recompose()};\n  assert(context.unevaluated.contains(current_uri));\n  const auto &dependencies{context.unevaluated.at(current_uri)};\n\n  for (const auto &dependency : dependencies.static_dependencies) {\n    assert(!dependency.empty());\n    assert(dependency.back().is_property());\n    const auto &keyword{dependency.back().to_property()};\n    const auto &subschema{sourcemeta::core::get(context.root, dependency)};\n    if (keyword == \"properties\") {\n      if (subschema.is_object()) {\n        for (const auto &property : subschema.as_object()) {\n          filter_strings.insert(property.first);\n        }\n      }\n    } else if (keyword == \"patternProperties\") {\n      if (subschema.is_object()) {\n        for (const auto &property : subschema.as_object()) {\n          const auto maybe_prefix{pattern_as_prefix(property.first)};\n          if (maybe_prefix.has_value()) {\n            filter_prefixes.push_back(maybe_prefix.value());\n          } else {\n            static const std::string pattern_properties_keyword{\n                \"patternProperties\"};\n            filter_regexes.push_back(\n                {parse_regex(property.first, schema_context.base,\n                             schema_context.relative_pointer.initial().concat(\n                                 sourcemeta::blaze::make_weak_pointer(\n                                     pattern_properties_keyword))),\n                 property.first});\n          }\n        }\n      }\n    } else if (keyword == \"additionalProperties\" ||\n               keyword == \"unevaluatedProperties\") {\n      return {};\n    }\n  }\n\n  if (dependencies.dynamic_dependencies.empty() && !dependencies.unresolved &&\n      !requires_evaluation(context, schema_context)) {\n    if (children.empty()) {\n      return {};\n    } else if (!filter_strings.empty() || !filter_prefixes.empty() ||\n               !filter_regexes.empty()) {\n      return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesExcept,\n                   context, schema_context, dynamic_context,\n                   ValuePropertyFilter{std::move(filter_strings),\n                                       std::move(filter_prefixes),\n                                       std::move(filter_regexes)},\n                   std::move(children))};\n    } else {\n      return {make(sourcemeta::blaze::InstructionIndex::LoopProperties, context,\n                   schema_context, dynamic_context, ValueNone{},\n                   std::move(children))};\n    }\n  }\n\n  if (children.empty()) {\n    return {make(sourcemeta::blaze::InstructionIndex::Evaluate, context,\n                 schema_context, dynamic_context, ValueNone{})};\n  } else if (!filter_strings.empty() || !filter_prefixes.empty() ||\n             !filter_regexes.empty()) {\n    return {make(\n        sourcemeta::blaze::InstructionIndex::LoopPropertiesUnevaluatedExcept,\n        context, schema_context, dynamic_context,\n        ValuePropertyFilter{std::move(filter_strings),\n                            std::move(filter_prefixes),\n                            std::move(filter_regexes)},\n        std::move(children))};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesUnevaluated,\n                 context, schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n}\n\nauto compiler_2019_09_core_recursiveref(const Context &context,\n                                        const SchemaContext &schema_context,\n                                        const DynamicContext &dynamic_context,\n                                        const Instructions &current)\n    -> Instructions {\n  const auto &entry{static_frame_entry(context, schema_context)};\n  // In this case, just behave as a normal static reference\n  if (!context.frame.references().contains(\n          {sourcemeta::core::SchemaReferenceType::Dynamic, entry.pointer})) {\n    return compiler_draft3_core_ref(context, schema_context, dynamic_context,\n                                    current);\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::ControlDynamicAnchorJump,\n               context, schema_context, dynamic_context, \"\")};\n}\n\nauto compiler_2019_09_applicator_properties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &current)\n    -> Instructions {\n  return compiler_draft3_applicator_properties_with_options(\n      context, schema_context, dynamic_context, current,\n      context.mode == Mode::Exhaustive,\n      requires_evaluation(context, schema_context));\n}\n\nauto compiler_2019_09_applicator_patternproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  return compiler_draft3_applicator_patternproperties_with_options(\n      context, schema_context, dynamic_context,\n      context.mode == Mode::Exhaustive,\n      requires_evaluation(context, schema_context));\n}\n\nauto compiler_2019_09_content_contentencoding(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (context.mode == Mode::FastValidation) {\n    return {};\n  }\n\n  Instructions children{\n      make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n           schema_context, dynamic_context,\n           sourcemeta::core::JSON{\n               schema_context.schema.at(dynamic_context.keyword)})};\n\n  return {make(sourcemeta::blaze::InstructionIndex::ControlGroupWhenType,\n               context, schema_context, relative_dynamic_context(),\n               ValueType::String, std::move(children))};\n}\n\nauto compiler_2019_09_content_contentmediatype(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (context.mode == Mode::FastValidation) {\n    return {};\n  }\n\n  Instructions children{\n      make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n           schema_context, dynamic_context,\n           sourcemeta::core::JSON{\n               schema_context.schema.at(dynamic_context.keyword)})};\n\n  return {make(sourcemeta::blaze::InstructionIndex::ControlGroupWhenType,\n               context, schema_context, relative_dynamic_context(),\n               ValueType::String, std::move(children))};\n}\n\nauto compiler_2019_09_content_contentschema(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (context.mode == Mode::FastValidation) {\n    return {};\n  }\n\n  // The `contentSchema` keyword does nothing without `contentMediaType`\n  if (!schema_context.schema.defines(\"contentMediaType\")) {\n    return {};\n  }\n\n  Instructions children{\n      make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n           schema_context, dynamic_context,\n           sourcemeta::core::JSON{\n               schema_context.schema.at(dynamic_context.keyword)})};\n\n  return {make(sourcemeta::blaze::InstructionIndex::ControlGroupWhenType,\n               context, schema_context, relative_dynamic_context(),\n               ValueType::String, std::move(children))};\n}\n\nauto compiler_2019_09_format_format(const Context &context,\n                                    const SchemaContext &schema_context,\n                                    const DynamicContext &dynamic_context,\n                                    const Instructions &) -> Instructions {\n  if (context.mode == Mode::FastValidation) {\n    return {};\n  }\n\n  Instructions children{\n      make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n           schema_context, dynamic_context,\n           sourcemeta::core::JSON{\n               schema_context.schema.at(dynamic_context.keyword)})};\n\n  return {make(sourcemeta::blaze::InstructionIndex::ControlGroupWhenType,\n               context, schema_context, relative_dynamic_context(),\n               ValueType::String, std::move(children))};\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_2020_12.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_2020_12_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_2020_12_H_\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/core/uri.h>\n\n#include \"compile_helpers.h\"\n#include \"default_compiler_draft4.h\"\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compiler_2020_12_applicator_prefixitems(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  return compiler_draft3_applicator_items_array(\n      context, schema_context, dynamic_context,\n      context.mode == Mode::Exhaustive, track);\n}\n\nauto compiler_2020_12_applicator_items(const Context &context,\n                                       const SchemaContext &schema_context,\n                                       const DynamicContext &dynamic_context,\n                                       const Instructions &) -> Instructions {\n  const auto cursor{(schema_context.schema.defines(\"prefixItems\") &&\n                     schema_context.schema.at(\"prefixItems\").is_array())\n                        ? schema_context.schema.at(\"prefixItems\").size()\n                        : 0};\n\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  return compiler_draft3_applicator_additionalitems_from_cursor(\n      context, schema_context, dynamic_context, cursor,\n      context.mode == Mode::Exhaustive,\n      track && !schema_context.schema.defines(\"unevaluatedItems\"));\n}\n\nauto compiler_2020_12_applicator_contains(const Context &context,\n                                          const SchemaContext &schema_context,\n                                          const DynamicContext &dynamic_context,\n                                          const Instructions &current)\n    -> Instructions {\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  return compiler_2019_09_applicator_contains_with_options(\n      context, schema_context, dynamic_context, current,\n      context.mode == Mode::Exhaustive, track);\n}\n\nauto compiler_2020_12_core_dynamicref(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &current)\n    -> Instructions {\n  const auto &entry{static_frame_entry(context, schema_context)};\n  // In this case, just behave as a normal static reference\n  if (!context.frame.references().contains(\n          {sourcemeta::core::SchemaReferenceType::Dynamic, entry.pointer})) {\n    return compiler_draft3_core_ref(context, schema_context, dynamic_context,\n                                    current);\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_string());\n  sourcemeta::core::URI reference{\n      schema_context.schema.at(dynamic_context.keyword).to_string()};\n  reference.resolve_from(schema_context.base);\n  reference.canonicalize();\n  // We handle the non-anchor variant by not treating it as a dynamic reference\n  assert(reference.fragment().has_value());\n\n  // TODO: Here we can potentially optimize `$dynamicRef` as a static reference\n  // if we determine (by traversing the frame) that the given dynamic anchor\n  // is only defined once. That means there is only one schema resource, and\n  // the jump and be always statically determined\n\n  // Note we don't need to even care about the static part of the dynamic\n  // reference (if any), as even if we jump first there, we will still\n  // look for the oldest dynamic anchor in the schema resource chain.\n\n  if (reference.is_fragment_only()) {\n    return {make(sourcemeta::blaze::InstructionIndex::ControlDynamicAnchorJump,\n                 context, schema_context, dynamic_context,\n                 std::string{reference.fragment().value()})};\n  } else {\n    const auto base_resource{reference.recompose_without_fragment()};\n    assert(base_resource.has_value());\n\n    // If the dynamic reference has a static component, we need to make sure we\n    // append such static part as a resource before we begin the lookup\n    return {make_with_resource(\n        sourcemeta::blaze::InstructionIndex::ControlDynamicAnchorJump, context,\n        schema_context, dynamic_context,\n        // TODO: The amount of possible anchors is known at compile time.\n        // We could convert it into integers like we do for resources\n        std::string{reference.fragment().value()}, base_resource.value())};\n  }\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_draft3.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT3_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT3_H_\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <sourcemeta/core/regex.h>\n\n#include <algorithm> // std::sort, std::ranges::any_of, std::ranges::all_of, std::find_if, std::ranges::none_of\n#include <cassert>   // assert\n#include <set>       // std::set\n#include <utility>   // std::move, std::to_underlying\n\n#include \"compile_helpers.h\"\n\nstatic auto parse_regex(const std::string &pattern,\n                        const sourcemeta::core::URI &base,\n                        const sourcemeta::core::WeakPointer &schema_location)\n    -> sourcemeta::core::Regex {\n  const auto result{sourcemeta::core::to_regex(pattern)};\n  if (!result.has_value()) [[unlikely]] {\n    throw sourcemeta::blaze::CompilerInvalidRegexError(\n        base, to_pointer(schema_location), pattern);\n  }\n\n  return result.value();\n}\n\nstatic auto\nrelative_schema_location_size(const sourcemeta::blaze::Context &context,\n                              const sourcemeta::blaze::Instruction &step)\n    -> std::size_t {\n  return context.extra[step.extra_index].relative_schema_location.size();\n}\n\nstatic auto\ndefines_direct_enumeration(const sourcemeta::blaze::Instructions &steps)\n    -> std::optional<std::size_t> {\n  const auto iterator{std::ranges::find_if(steps, [](const auto &step) {\n    return step.type == sourcemeta::blaze::InstructionIndex::AssertionEqual ||\n           step.type == sourcemeta::blaze::InstructionIndex::AssertionEqualsAny;\n  })};\n\n  if (iterator == steps.cend()) {\n    return std::nullopt;\n  }\n\n  return std::distance(steps.cbegin(), iterator);\n}\n\nstatic auto is_inside_disjunctor(const sourcemeta::core::WeakPointer &pointer)\n    -> bool {\n  return pointer.size() > 2 && pointer.at(pointer.size() - 2).is_index() &&\n         pointer.at(pointer.size() - 3).is_property() &&\n         (pointer.at(pointer.size() - 3).to_property() == \"oneOf\" ||\n          pointer.at(pointer.size() - 3).to_property() == \"anyOf\");\n}\n\nstatic auto json_array_to_string_set(const sourcemeta::core::JSON &document)\n    -> sourcemeta::blaze::ValueStringSet {\n  sourcemeta::blaze::ValueStringSet result;\n  for (const auto &value : document.as_array()) {\n    assert(value.is_string());\n    result.insert(value.to_string());\n  }\n\n  return result;\n}\n\nstatic auto\nis_closed_properties_required(const sourcemeta::core::JSON &schema,\n                              const sourcemeta::blaze::ValueStringSet &required)\n    -> bool {\n  return !schema.defines(\"patternProperties\") &&\n         schema.defines(\"additionalProperties\") &&\n         schema.at(\"additionalProperties\").is_boolean() &&\n         !schema.at(\"additionalProperties\").to_boolean() &&\n         schema.defines(\"properties\") && schema.at(\"properties\").is_object() &&\n         schema.at(\"properties\").size() == required.size() &&\n         std::ranges::all_of(required, [&schema](const auto &property) {\n           return schema.at(\"properties\")\n               .defines(property.first, property.second);\n         });\n}\n\nstatic auto\ncompile_properties(const sourcemeta::blaze::Context &context,\n                   const sourcemeta::blaze::SchemaContext &schema_context,\n                   const sourcemeta::blaze::DynamicContext &dynamic_context,\n                   const sourcemeta::blaze::Instructions &)\n    -> std::vector<std::pair<std::string, sourcemeta::blaze::Instructions>> {\n  std::vector<std::pair<std::string, sourcemeta::blaze::Instructions>>\n      properties;\n  for (const auto &entry : schema_context.schema.at(\"properties\").as_object()) {\n    properties.emplace_back(\n        entry.first,\n        compile(context, schema_context, dynamic_context,\n                sourcemeta::blaze::make_weak_pointer(entry.first),\n                sourcemeta::blaze::make_weak_pointer(entry.first)));\n  }\n\n  // In many cases, `properties` have some subschemas that are small\n  // and some subschemas that are large. To attempt to improve performance,\n  // we prefer to evaluate smaller subschemas first, in the hope of failing\n  // earlier without spending a lot of time on other subschemas\n  if (context.tweaks.properties_reorder) {\n    std::ranges::sort(properties, [&context](const auto &left,\n                                             const auto &right) {\n      const auto left_size{recursive_template_size(left.second)};\n      const auto right_size{recursive_template_size(right.second)};\n      if (left_size == right_size) {\n        const auto left_direct_enumeration{\n            defines_direct_enumeration(left.second)};\n        const auto right_direct_enumeration{\n            defines_direct_enumeration(right.second)};\n\n        // Enumerations always take precedence\n        if (left_direct_enumeration.has_value() &&\n            right_direct_enumeration.has_value()) {\n          // If both options have a direct enumeration, we choose\n          // the one with the shorter relative schema location\n          return relative_schema_location_size(\n                     context, left.second.at(left_direct_enumeration.value())) <\n                 relative_schema_location_size(\n                     context,\n                     right.second.at(right_direct_enumeration.value()));\n        } else if (left_direct_enumeration.has_value()) {\n          return true;\n        } else if (right_direct_enumeration.has_value()) {\n          return false;\n        }\n\n        return left.first < right.first;\n      } else {\n        return left_size < right_size;\n      }\n    });\n  }\n\n  return properties;\n}\n\nstatic auto to_string_hashes(\n    std::vector<std::pair<sourcemeta::blaze::ValueString,\n                          sourcemeta::blaze::ValueStringSet::hash_type>>\n        &hashes) -> sourcemeta::blaze::ValueStringHashes {\n  assert(!hashes.empty());\n  std::ranges::sort(hashes, [](const auto &left, const auto &right) {\n    return left.first.size() < right.first.size();\n  });\n\n  sourcemeta::blaze::ValueStringHashes result;\n  // The idea with the table of contents is as follows: each index\n  // marks the starting and end positions for a string where the size\n  // is equal to the index.\n  result.second.resize(hashes.back().first.size() + 1, std::make_pair(0, 0));\n  // TODO(C++23): Use std::views::enumerate when available in libc++\n  for (std::size_t index = 0; index < hashes.size(); index++) {\n    result.first.emplace_back(hashes[index].second, hashes[index].first);\n    const auto string_size{hashes[index].first.size()};\n    // We leave index 0 to represent the empty string\n    const auto position{index + 1};\n    const auto lower_bound{\n        result.second[string_size].first == 0\n            ? position\n            : std::min(result.second[string_size].first, position)};\n    const auto upper_bound{\n        result.second[string_size].second == 0\n            ? position\n            : std::max(result.second[string_size].second, position)};\n    assert(lower_bound <= upper_bound);\n    assert(lower_bound > 0 && upper_bound > 0);\n    assert(string_size < result.second.size());\n    result.second[string_size] = std::make_pair(lower_bound, upper_bound);\n  }\n\n  assert(result.second.size() == hashes.back().first.size() + 1);\n  return result;\n}\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compile_required_assertions(const Context &context,\n                                 const SchemaContext &schema_context,\n                                 const DynamicContext &dynamic_context,\n                                 const Instructions &current,\n                                 ValueStringSet properties_set)\n    -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  const auto assume_object{schema_context.schema.defines(\"type\") &&\n                           schema_context.schema.at(\"type\").is_string() &&\n                           schema_context.schema.at(\"type\").to_string() ==\n                               \"object\"};\n\n  if (properties_set.empty()) {\n    return {};\n  } else if (properties_set.size() > 1) {\n    if (is_closed_properties_required(schema_context.schema, properties_set)) {\n      if (context.mode == Mode::FastValidation && assume_object) {\n        static const std::string properties_keyword{\"properties\"};\n        const SchemaContext new_schema_context{\n            .relative_pointer =\n                schema_context.relative_pointer.initial().concat(\n                    sourcemeta::blaze::make_weak_pointer(properties_keyword)),\n            .schema = schema_context.schema,\n            .vocabularies = schema_context.vocabularies,\n            .base = schema_context.base,\n            .is_property_name = schema_context.is_property_name};\n        const DynamicContext new_dynamic_context{\n            .keyword = KEYWORD_PROPERTIES,\n            .base_schema_location = sourcemeta::core::empty_weak_pointer,\n            .base_instance_location = sourcemeta::core::empty_weak_pointer};\n        auto properties{compile_properties(context, new_schema_context,\n                                           new_dynamic_context, current)};\n        if (std::ranges::all_of(properties, [](const auto &property) {\n              return property.second.size() == 1 &&\n                     property.second.front().type ==\n                         InstructionIndex::AssertionTypeStrict;\n            })) {\n          std::set<ValueType> types;\n          for (const auto &property : properties) {\n            types.insert(std::get<ValueType>(property.second.front().value));\n          }\n\n          if (types.size() == 1) {\n            // Handled in `properties`\n            return {};\n          }\n        }\n\n        sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n        if (context.mode == Mode::FastValidation &&\n            properties_set.size() == 3 &&\n            std::ranges::all_of(properties_set,\n                                [&hasher](const auto &property) {\n                                  return hasher.is_perfect(property.second);\n                                })) {\n          std::vector<std::pair<ValueString, ValueStringSet::hash_type>> hashes;\n          for (const auto &property : properties_set) {\n            hashes.emplace_back(property.first, property.second);\n          }\n\n          return {make(sourcemeta::blaze::InstructionIndex::\n                           AssertionDefinesExactlyStrictHash3,\n                       context, schema_context, dynamic_context,\n                       to_string_hashes(hashes))};\n        }\n\n        return {make(\n            sourcemeta::blaze::InstructionIndex::AssertionDefinesExactlyStrict,\n            context, schema_context, dynamic_context,\n            std::move(properties_set))};\n      } else {\n        return {\n            make(sourcemeta::blaze::InstructionIndex::AssertionDefinesExactly,\n                 context, schema_context, dynamic_context,\n                 std::move(properties_set))};\n      }\n    } else if (assume_object) {\n      return {make(\n          sourcemeta::blaze::InstructionIndex::AssertionDefinesAllStrict,\n          context, schema_context, dynamic_context, std::move(properties_set))};\n    } else {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionDefinesAll,\n                   context, schema_context, dynamic_context,\n                   std::move(properties_set))};\n    }\n  } else if (assume_object) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionDefinesStrict,\n                 context, schema_context, dynamic_context,\n                 make_property(properties_set.begin()->first))};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionDefines, context,\n                 schema_context, dynamic_context,\n                 make_property(properties_set.begin()->first))};\n  }\n}\n\nauto compiler_draft3_core_ref(const Context &context,\n                              const SchemaContext &schema_context,\n                              const DynamicContext &dynamic_context,\n                              const Instructions &) -> Instructions {\n  const auto &entry{static_frame_entry(context, schema_context)};\n  const auto type{sourcemeta::core::SchemaReferenceType::Static};\n  const auto reference{context.frame.reference(type, entry.pointer)};\n  if (!reference.has_value()) [[unlikely]] {\n    throw sourcemeta::core::SchemaReferenceError(\n        schema_context.schema.at(dynamic_context.keyword).to_string(),\n        to_pointer(schema_context.relative_pointer),\n        \"Could not resolve schema reference\");\n  }\n\n  const auto key{std::make_tuple(type,\n                                 std::string_view{reference->get().destination},\n                                 schema_context.is_property_name)};\n  assert(context.targets.contains(key));\n  return {make(sourcemeta::blaze::InstructionIndex::ControlJump, context,\n               schema_context, dynamic_context,\n               ValueUnsignedInteger{context.targets.at(key).first})};\n}\n\n// There are two ways to compile `properties` depending on whether\n// most of the properties are marked as required using `required`\n// or whether most of the properties are optional. Each shines\n// in the corresponding case.\nauto properties_as_loop(const Context &context,\n                        const SchemaContext &schema_context,\n                        const sourcemeta::core::JSON &properties) -> bool {\n  if (context.tweaks.properties_always_unroll) {\n    return false;\n  }\n\n  using Known = sourcemeta::core::Vocabularies::Known;\n  const auto size{properties.size()};\n  const auto imports_validation_vocabulary =\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_4) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_6) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_7) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2019_09_Validation) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2020_12_Validation);\n  const auto imports_const =\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_6) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_7) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2019_09_Validation) ||\n      schema_context.vocabularies.contains(\n          Known::JSON_Schema_2020_12_Validation);\n  ValueStringSet required;\n  for (const auto &entry : required_properties(schema_context)) {\n    // Only count the required property if its indeed in \"properties\"\n    if (properties.defines(entry.first)) {\n      required.insert(entry.first);\n    }\n  }\n\n  const auto &current_entry{static_frame_entry(context, schema_context)};\n  const auto inside_disjunctor{\n      is_inside_disjunctor(schema_context.relative_pointer) ||\n      // Check if any reference from `anyOf` or `oneOf` points to us\n      std::ranges::any_of(\n          context.frame.references(),\n          [&context, &current_entry](const auto &reference) {\n            if (!context.frame.locations().contains(\n                    {sourcemeta::core::SchemaReferenceType::Static,\n                     reference.second.destination})) {\n              return false;\n            }\n\n            const auto &target{\n                context.frame.locations()\n                    .at({sourcemeta::core::SchemaReferenceType::Static,\n                         reference.second.destination})\n                    .pointer};\n            return is_inside_disjunctor(reference.first.second) &&\n                   current_entry.pointer.initial() == target;\n          })};\n\n  if (!inside_disjunctor &&\n      schema_context.schema.defines(\"additionalProperties\") &&\n      schema_context.schema.at(\"additionalProperties\").is_boolean() &&\n      !schema_context.schema.at(\"additionalProperties\").to_boolean() &&\n      // If all properties are required, we should still unroll\n      required.size() < size) {\n    return true;\n  }\n\n  return\n      // This strategy only makes sense if most of the properties are \"optional\"\n      required.size() <= (size / 4) &&\n      // If `properties` only defines a relatively small amount of properties,\n      // then its probably still faster to unroll\n      size > 5 &&\n      // Always unroll inside `oneOf` or `anyOf`, to have a\n      // better chance at quickly short-circuiting\n      (!inside_disjunctor ||\n       std::ranges::none_of(properties.as_object(), [&](const auto &pair) {\n         return pair.second.is_object() &&\n                ((imports_validation_vocabulary &&\n                  pair.second.defines(\"enum\")) ||\n                 (imports_const && pair.second.defines(\"const\")));\n       }));\n}\n\nauto draft3_any_type_instructions(const Context &context,\n                                  const SchemaContext &schema_context,\n                                  const DynamicContext &dynamic_context)\n    -> Instructions {\n  if (context.mode != Mode::Exhaustive) {\n    return {};\n  }\n\n  using sourcemeta::core::JSON;\n  ValueTypes types{};\n  types.set(std::to_underlying(JSON::Type::Null));\n  types.set(std::to_underlying(JSON::Type::Boolean));\n  types.set(std::to_underlying(JSON::Type::Object));\n  types.set(std::to_underlying(JSON::Type::Array));\n  types.set(std::to_underlying(JSON::Type::Integer));\n  types.set(std::to_underlying(JSON::Type::Real));\n  types.set(std::to_underlying(JSON::Type::Decimal));\n  types.set(std::to_underlying(JSON::Type::String));\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n               context, schema_context, dynamic_context, types)};\n}\n\nauto draft3_set_type_bits(const std::string &name, ValueTypes &types) -> bool {\n  using sourcemeta::core::JSON;\n  if (name == \"null\") {\n    types.set(std::to_underlying(JSON::Type::Null));\n  } else if (name == \"boolean\") {\n    types.set(std::to_underlying(JSON::Type::Boolean));\n  } else if (name == \"object\") {\n    types.set(std::to_underlying(JSON::Type::Object));\n  } else if (name == \"array\") {\n    types.set(std::to_underlying(JSON::Type::Array));\n  } else if (name == \"integer\") {\n    types.set(std::to_underlying(JSON::Type::Integer));\n  } else if (name == \"string\") {\n    types.set(std::to_underlying(JSON::Type::String));\n  } else if (name == \"number\") {\n    types.set(std::to_underlying(JSON::Type::Real));\n    types.set(std::to_underlying(JSON::Type::Integer));\n    types.set(std::to_underlying(JSON::Type::Decimal));\n  } else {\n    return false;\n  }\n  return true;\n}\n\nauto is_integer_type_check(const Instruction &instruction) -> bool {\n  return (instruction.type == InstructionIndex::AssertionType ||\n          instruction.type == InstructionIndex::AssertionTypeStrict) &&\n         std::get<ValueType>(instruction.value) ==\n             sourcemeta::core::JSON::Type::Integer;\n}\n\nauto has_strict_integer_type(const Instructions &children) -> bool {\n  for (const auto &child : children) {\n    if (child.type == InstructionIndex::AssertionTypeStrict &&\n        std::get<ValueType>(child.value) ==\n            sourcemeta::core::JSON::Type::Integer) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nauto is_integer_type_bounded_pattern(const Instructions &children) -> bool {\n  if (children.size() != 3) {\n    return false;\n  }\n\n  bool has_type{false};\n  bool has_min{false};\n  bool has_max{false};\n  for (const auto &child : children) {\n    if (is_integer_type_check(child)) {\n      has_type = true;\n    } else if (child.type == InstructionIndex::AssertionGreaterEqual &&\n               std::get<ValueJSON>(child.value).is_integer()) {\n      has_min = true;\n    } else if (child.type == InstructionIndex::AssertionLessEqual &&\n               std::get<ValueJSON>(child.value).is_integer()) {\n      has_max = true;\n    }\n  }\n\n  return has_type && has_min && has_max;\n}\n\nauto is_integer_type_lower_bound_pattern(const Instructions &children) -> bool {\n  if (children.size() != 2) {\n    return false;\n  }\n\n  bool has_type{false};\n  bool has_min{false};\n  for (const auto &child : children) {\n    if (is_integer_type_check(child)) {\n      has_type = true;\n    } else if (child.type == InstructionIndex::AssertionGreaterEqual &&\n               std::get<ValueJSON>(child.value).is_integer()) {\n      has_min = true;\n    }\n  }\n\n  return has_type && has_min;\n}\n\nauto extract_integer_lower_bound(const Instructions &children) -> std::int64_t {\n  for (const auto &child : children) {\n    if (child.type == InstructionIndex::AssertionGreaterEqual) {\n      return std::get<ValueJSON>(child.value).to_integer();\n    }\n  }\n\n  return 0;\n}\n\nauto extract_integer_bounds(const Instructions &children)\n    -> ValueIntegerBounds {\n  std::int64_t minimum{0};\n  std::int64_t maximum{0};\n  for (const auto &child : children) {\n    if (child.type == InstructionIndex::AssertionGreaterEqual) {\n      minimum = std::get<ValueJSON>(child.value).to_integer();\n    } else if (child.type == InstructionIndex::AssertionLessEqual) {\n      maximum = std::get<ValueJSON>(child.value).to_integer();\n    }\n  }\n\n  return {minimum, maximum};\n}\n\nauto compiler_draft3_applicator_properties_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &current,\n    const bool annotate, const bool track_evaluation) -> Instructions {\n  if (schema_context.is_property_name) {\n    return {};\n  }\n\n  if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {\n    return {};\n  }\n\n  if (schema_context.schema.at(dynamic_context.keyword).empty()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  if (properties_as_loop(context, schema_context,\n                         schema_context.schema.at(dynamic_context.keyword))) {\n    ValueNamedIndexes indexes;\n    Instructions children;\n    std::size_t cursor = 0;\n\n    for (auto &&[name, substeps] : compile_properties(\n             context, schema_context, relative_dynamic_context(), current)) {\n      indexes.emplace(name, cursor);\n\n      if (track_evaluation) {\n        substeps.push_back(make(\n            sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n            schema_context, relative_dynamic_context(), ValuePointer{name}));\n      }\n\n      if (annotate) {\n        substeps.push_back(\n            make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n                 schema_context, relative_dynamic_context(),\n                 sourcemeta::core::JSON{name}));\n      }\n\n      // Note that the evaluator completely ignores this wrapper anyway\n      children.push_back(make(sourcemeta::blaze::InstructionIndex::ControlGroup,\n                              context, schema_context,\n                              relative_dynamic_context(), ValueNone{},\n                              std::move(substeps)));\n      cursor += 1;\n    }\n\n    if (context.mode == Mode::FastValidation && !track_evaluation &&\n        !schema_context.schema.defines(\"patternProperties\") &&\n        schema_context.schema.defines(\"additionalProperties\") &&\n        schema_context.schema.at(\"additionalProperties\").is_boolean() &&\n        !schema_context.schema.at(\"additionalProperties\").to_boolean()) {\n      return {\n          make(sourcemeta::blaze::InstructionIndex::LoopPropertiesMatchClosed,\n               context, schema_context, dynamic_context, std::move(indexes),\n               std::move(children))};\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesMatch,\n                 context, schema_context, dynamic_context, std::move(indexes),\n                 std::move(children))};\n  }\n\n  Instructions children;\n\n  const auto effective_dynamic_context{context.mode == Mode::FastValidation\n                                           ? dynamic_context\n                                           : relative_dynamic_context()};\n\n  const auto assume_object{schema_context.schema.defines(\"type\") &&\n                           schema_context.schema.at(\"type\").is_string() &&\n                           schema_context.schema.at(\"type\").to_string() ==\n                               \"object\"};\n\n  ValueStringSet required{required_properties(schema_context)};\n\n  auto properties{compile_properties(context, schema_context,\n                                     effective_dynamic_context, current)};\n\n  if (context.mode == Mode::FastValidation && !required.empty() &&\n      schema_context.schema.defines(\"additionalProperties\") &&\n      schema_context.schema.at(\"additionalProperties\").is_boolean() &&\n      !schema_context.schema.at(\"additionalProperties\").to_boolean() &&\n      required.size() ==\n          schema_context.schema.at(dynamic_context.keyword).size() &&\n      std::ranges::all_of(properties, [&required](const auto &property) {\n        return required.contains(property.first);\n      })) {\n    if (std::ranges::all_of(properties, [](const auto &property) {\n          return property.second.size() == 1 &&\n                 property.second.front().type ==\n                     InstructionIndex::AssertionTypeStrict;\n        })) {\n      std::set<ValueType> types;\n      for (const auto &property : properties) {\n        types.insert(std::get<ValueType>(property.second.front().value));\n      }\n\n      if (types.size() == 1 &&\n          !schema_context.schema.defines(\"patternProperties\")) {\n        if (assume_object) {\n          if (is_closed_properties_required(schema_context.schema, required)) {\n            sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n            std::vector<std::pair<ValueString, ValueStringSet::hash_type>>\n                perfect_hashes;\n            for (const auto &entry : required) {\n              assert(required.contains(entry.first, entry.second));\n              if (hasher.is_perfect(entry.second)) {\n                perfect_hashes.emplace_back(entry.first, entry.second);\n              }\n            }\n\n            if (perfect_hashes.size() == required.size()) {\n              return {make(sourcemeta::blaze::InstructionIndex::\n                               LoopPropertiesExactlyTypeStrictHash,\n                           context, schema_context, dynamic_context,\n                           ValueTypedHashes{*types.cbegin(),\n                                            to_string_hashes(perfect_hashes)})};\n            }\n\n            return {make(\n                sourcemeta::blaze::InstructionIndex::\n                    LoopPropertiesExactlyTypeStrict,\n                context, schema_context, dynamic_context,\n                ValueTypedProperties{*types.cbegin(), std::move(required)})};\n          }\n        }\n\n        return {\n            make(sourcemeta::blaze::InstructionIndex::LoopPropertiesTypeStrict,\n                 context, schema_context, dynamic_context, *types.cbegin())};\n      }\n    }\n\n    if (std::ranges::all_of(properties, [](const auto &property) {\n          return property.second.size() == 1 &&\n                 property.second.front().type ==\n                     InstructionIndex::AssertionType;\n        })) {\n      std::set<ValueType> types;\n      for (const auto &property : properties) {\n        types.insert(std::get<ValueType>(property.second.front().value));\n      }\n\n      if (types.size() == 1) {\n        return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesType,\n                     context, schema_context, dynamic_context,\n                     *types.cbegin())};\n      }\n    }\n  }\n\n  auto attempt_object_fusion{context.mode == Mode::FastValidation &&\n                             !annotate && !track_evaluation && assume_object};\n  if (attempt_object_fusion) {\n    for (const auto &entry : schema_context.schema.as_object()) {\n      const auto &keyword{entry.first};\n      if (keyword == \"type\" || keyword == \"required\" ||\n          keyword == dynamic_context.keyword) {\n        continue;\n      }\n\n      if (keyword == \"additionalProperties\" && entry.second.is_boolean() &&\n          entry.second.to_boolean()) {\n        continue;\n      }\n\n      const auto &keyword_type{\n          context.walker(keyword, schema_context.vocabularies).type};\n      using enum sourcemeta::core::SchemaKeywordType;\n      if (keyword_type == Assertion || keyword_type == Annotation ||\n          keyword_type == Unknown || keyword_type == Comment ||\n          keyword_type == Other || keyword_type == LocationMembers) {\n        continue;\n      }\n\n      attempt_object_fusion = false;\n      break;\n    }\n  }\n  ValueObjectProperties fusion_entries;\n  Instructions fusion_children;\n  bool fusion_possible{attempt_object_fusion};\n\n  for (auto &&[name, substeps] : properties) {\n    if (annotate) {\n      substeps.push_back(\n          make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n               schema_context, effective_dynamic_context,\n               sourcemeta::core::JSON{name}));\n    }\n\n    // Optimize `properties` where its subschemas just include a type check\n\n    if (context.mode == Mode::FastValidation && track_evaluation &&\n        substeps.size() == 1 &&\n        substeps.front().type == InstructionIndex::AssertionTypeStrict) {\n      children.push_back(rephrase(context,\n                                  sourcemeta::blaze::InstructionIndex::\n                                      AssertionPropertyTypeStrictEvaluate,\n                                  substeps.front()));\n    } else if (context.mode == Mode::FastValidation && track_evaluation &&\n               substeps.size() == 1 &&\n               substeps.front().type == InstructionIndex::AssertionType) {\n      children.push_back(rephrase(\n          context,\n          sourcemeta::blaze::InstructionIndex::AssertionPropertyTypeEvaluate,\n          substeps.front()));\n    } else if (context.mode == Mode::FastValidation && track_evaluation &&\n               substeps.size() == 1 &&\n               substeps.front().type ==\n                   InstructionIndex::AssertionTypeStrictAny) {\n      children.push_back(rephrase(context,\n                                  sourcemeta::blaze::InstructionIndex::\n                                      AssertionPropertyTypeStrictAnyEvaluate,\n                                  substeps.front()));\n\n      // NOLINTBEGIN(bugprone-branch-clone)\n    } else if (!fusion_possible && context.mode == Mode::FastValidation &&\n               substeps.size() == 1 &&\n               substeps.front().type ==\n                   InstructionIndex::AssertionPropertyTypeStrict) {\n      children.push_back(\n          unroll(context, substeps.front(),\n                 effective_dynamic_context.base_instance_location));\n    } else if (!fusion_possible && context.mode == Mode::FastValidation &&\n               substeps.size() == 1 &&\n               substeps.front().type ==\n                   InstructionIndex::AssertionPropertyType) {\n      children.push_back(\n          unroll(context, substeps.front(),\n                 effective_dynamic_context.base_instance_location));\n    } else if (!fusion_possible && context.mode == Mode::FastValidation &&\n               substeps.size() == 1 &&\n               substeps.front().type ==\n                   InstructionIndex::AssertionPropertyTypeStrictAny) {\n      children.push_back(\n          unroll(context, substeps.front(),\n                 effective_dynamic_context.base_instance_location));\n      // NOLINTEND(bugprone-branch-clone)\n\n    } else {\n      if (track_evaluation) {\n        auto new_base_instance_location{\n            effective_dynamic_context.base_instance_location};\n        new_base_instance_location.push_back({name});\n        substeps.push_back(\n            make(sourcemeta::blaze::InstructionIndex::Evaluate, context,\n                 schema_context,\n                 DynamicContext{\n                     .keyword = effective_dynamic_context.keyword,\n                     .base_schema_location =\n                         effective_dynamic_context.base_schema_location,\n                     .base_instance_location = new_base_instance_location},\n                 ValueNone{}));\n      }\n\n      if (context.mode == Mode::FastValidation && !substeps.empty()) {\n        if (is_integer_type_bounded_pattern(substeps)) {\n          auto bounds = extract_integer_bounds(substeps);\n          const auto index =\n              has_strict_integer_type(substeps)\n                  ? InstructionIndex::AssertionTypeIntegerBoundedStrict\n                  : InstructionIndex::AssertionTypeIntegerBounded;\n          auto instance_location = substeps.front().relative_instance_location;\n          substeps.clear();\n          auto fused = make(index, context, schema_context,\n                            relative_dynamic_context(), bounds);\n          fused.relative_instance_location = std::move(instance_location);\n          substeps.push_back(std::move(fused));\n        } else if (is_integer_type_lower_bound_pattern(substeps)) {\n          const auto minimum = extract_integer_lower_bound(substeps);\n          const auto index =\n              has_strict_integer_type(substeps)\n                  ? InstructionIndex::AssertionTypeIntegerLowerBoundStrict\n                  : InstructionIndex::AssertionTypeIntegerLowerBound;\n          auto instance_location = substeps.front().relative_instance_location;\n          substeps.clear();\n          auto fused =\n              make(index, context, schema_context, relative_dynamic_context(),\n                   ValueIntegerBounds{minimum, 0});\n          fused.relative_instance_location = std::move(instance_location);\n          substeps.push_back(std::move(fused));\n        } else if (substeps.size() == 2) {\n          bool has_items_bounded{false};\n          bool has_array_type{false};\n          std::size_t items_index{0};\n          std::size_t array_index{0};\n          for (std::size_t step_index = 0; step_index < 2; step_index++) {\n            if (substeps[step_index].type ==\n                InstructionIndex::LoopItemsIntegerBounded) {\n              has_items_bounded = true;\n              items_index = step_index;\n            } else if (substeps[step_index].type ==\n                       InstructionIndex::AssertionTypeArrayBounded) {\n              has_array_type = true;\n              array_index = step_index;\n            }\n          }\n\n          if (has_items_bounded && has_array_type) {\n            auto integer_bounds{\n                std::get<ValueIntegerBounds>(substeps[items_index].value)};\n            auto range{std::get<ValueRange>(substeps[array_index].value)};\n            auto instance_location =\n                substeps[items_index].relative_instance_location;\n            Value fused_value{\n                ValueIntegerBoundsWithSize{integer_bounds, std::move(range)}};\n            substeps.clear();\n            auto fused =\n                make(InstructionIndex::LoopItemsIntegerBoundedSized, context,\n                     schema_context, effective_dynamic_context, fused_value);\n            fused.relative_instance_location = std::move(instance_location);\n            substeps.push_back(std::move(fused));\n          }\n        }\n      }\n\n      if (fusion_possible && substeps.size() >= 2 &&\n          std::ranges::any_of(substeps, [](const auto &step) {\n            return step.type ==\n                   InstructionIndex::AssertionObjectPropertiesSimple;\n          })) {\n        std::erase_if(substeps, [](const auto &step) {\n          if (step.type == InstructionIndex::AssertionDefinesAllStrict ||\n              step.type == InstructionIndex::AssertionDefinesAll) {\n            return true;\n          }\n\n          if ((step.type == InstructionIndex::AssertionTypeStrict ||\n               step.type == InstructionIndex::AssertionType) &&\n              std::get<ValueType>(step.value) ==\n                  sourcemeta::core::JSON::Type::Object) {\n            return true;\n          }\n\n          return false;\n        });\n      }\n\n      if (fusion_possible && substeps.size() == 1 &&\n          substeps.front().type != InstructionIndex::ControlJump &&\n          substeps.front().type != InstructionIndex::ControlDynamicAnchorJump) {\n        const auto is_required{assume_object && required.contains(name)};\n        auto prop{make_property(name)};\n        auto fusion_child{substeps.front()};\n        fusion_child.relative_instance_location = {};\n        auto fusion_extra{context.extra[fusion_child.extra_index]};\n        fusion_extra.relative_schema_location = {};\n        fusion_child.extra_index = context.extra.size();\n        context.extra.push_back(std::move(fusion_extra));\n\n        fusion_entries.emplace_back(prop.first, prop.second, is_required);\n        fusion_children.push_back(std::move(fusion_child));\n      } else {\n        fusion_possible = false;\n      }\n\n      if (!substeps.empty()) {\n        // As a performance shortcut\n        if (effective_dynamic_context.base_instance_location.empty()) {\n          if (assume_object && required.contains(name)) {\n            for (auto &&step : substeps) {\n              children.push_back(std::move(step));\n            }\n          } else {\n            children.push_back(make(sourcemeta::blaze::InstructionIndex::\n                                        ControlGroupWhenDefinesDirect,\n                                    context, schema_context,\n                                    effective_dynamic_context,\n                                    make_property(name), std::move(substeps)));\n          }\n        } else {\n          children.push_back(\n              make(sourcemeta::blaze::InstructionIndex::ControlGroupWhenDefines,\n                   context, schema_context, effective_dynamic_context,\n                   make_property(name), std::move(substeps)));\n        }\n      }\n    }\n  }\n\n  if (context.mode == Mode::FastValidation) {\n    if (fusion_possible && !fusion_entries.empty()) {\n      for (const auto &req : required) {\n        const auto &req_name{req.first};\n        bool already_tracked{false};\n        for (const auto &entry : fusion_entries) {\n          if (std::get<0>(entry) == req_name) {\n            already_tracked = true;\n            break;\n          }\n        }\n        if (!already_tracked) {\n          auto prop{make_property(req_name)};\n          fusion_entries.emplace_back(prop.first, prop.second, true);\n        }\n      }\n\n      if (fusion_entries.size() > 32) {\n        return children;\n      }\n\n      return {make(InstructionIndex::AssertionObjectPropertiesSimple, context,\n                   schema_context, dynamic_context,\n                   Value{std::move(fusion_entries)},\n                   std::move(fusion_children))};\n    }\n\n    return children;\n  } else if (children.empty()) {\n    return {};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::LogicalWhenType, context,\n                 schema_context, dynamic_context,\n                 sourcemeta::core::JSON::Type::Object, std::move(children))};\n  }\n}\n\nauto compiler_draft3_applicator_properties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &current)\n    -> Instructions {\n  auto property_instructions{compiler_draft3_applicator_properties_with_options(\n      context, schema_context, dynamic_context, current, false, false)};\n\n  using Known = sourcemeta::core::Vocabularies::Known;\n  const auto is_draft3{\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper)};\n  if (!is_draft3) {\n    return property_instructions;\n  }\n\n  ValueStringSet required{required_properties(schema_context)};\n  if (required.empty()) {\n    return property_instructions;\n  }\n\n  auto required_instructions{compile_required_assertions(\n      context, schema_context, dynamic_context, current, std::move(required))};\n  if (required_instructions.empty()) {\n    return property_instructions;\n  }\n\n  Instructions result{std::move(required_instructions)};\n  for (auto &&step : property_instructions) {\n    result.push_back(std::move(step));\n  }\n  return result;\n}\n\nauto compiler_draft3_applicator_patternproperties_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const bool annotate,\n    const bool track_evaluation) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {\n    return {};\n  }\n\n  if (schema_context.schema.at(dynamic_context.keyword).empty()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  Instructions children;\n\n  // To guarantee ordering\n  std::vector<std::string> patterns;\n  for (auto &entry :\n       schema_context.schema.at(dynamic_context.keyword).as_object()) {\n    patterns.push_back(entry.first);\n  }\n\n  std::ranges::sort(patterns);\n\n  // For each regular expression and corresponding subschema in the object\n  for (const auto &pattern : patterns) {\n    auto substeps{compile(context, schema_context, relative_dynamic_context(),\n                          sourcemeta::blaze::make_weak_pointer(pattern))};\n\n    if (annotate) {\n      substeps.push_back(make(\n          sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent,\n          context, schema_context, relative_dynamic_context(), ValueNone{}));\n    }\n\n    if (track_evaluation) {\n      substeps.push_back(\n          make(sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n               schema_context, relative_dynamic_context(), ValuePointer{}));\n    }\n\n    if (context.mode == Mode::FastValidation && !track_evaluation &&\n        patterns.size() == 1 &&\n        (!schema_context.schema.defines(\"properties\") ||\n         (schema_context.schema.at(\"properties\").is_object() &&\n          schema_context.schema.at(\"properties\").empty())) &&\n        schema_context.schema.defines(\"additionalProperties\") &&\n        schema_context.schema.at(\"additionalProperties\").is_boolean() &&\n        !schema_context.schema.at(\"additionalProperties\").to_boolean()) {\n      children.push_back(\n          make(sourcemeta::blaze::InstructionIndex::LoopPropertiesRegexClosed,\n               context, schema_context, dynamic_context,\n               ValueRegex{.first = parse_regex(pattern, schema_context.base,\n                                               schema_context.relative_pointer),\n                          .second = pattern},\n               std::move(substeps)));\n\n      // If the `patternProperties` subschema for the given pattern does\n      // nothing, then we can avoid generating an entire loop for it\n    } else if (!substeps.empty()) {\n      const auto maybe_prefix{pattern_as_prefix(pattern)};\n      if (maybe_prefix.has_value()) {\n        children.push_back(\n            make(sourcemeta::blaze::InstructionIndex::LoopPropertiesStartsWith,\n                 context, schema_context, dynamic_context,\n                 ValueString{maybe_prefix.value()}, std::move(substeps)));\n      } else {\n        children.push_back(make(\n            sourcemeta::blaze::InstructionIndex::LoopPropertiesRegex, context,\n            schema_context, dynamic_context,\n            ValueRegex{.first = parse_regex(pattern, schema_context.base,\n                                            schema_context.relative_pointer),\n                       .second = pattern},\n            std::move(substeps)));\n      }\n    }\n  }\n\n  return children;\n}\n\nauto compiler_draft3_applicator_patternproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  return compiler_draft3_applicator_patternproperties_with_options(\n      context, schema_context, dynamic_context, false, false);\n}\n\nauto compiler_draft3_applicator_additionalproperties_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const bool annotate,\n    const bool track_evaluation) -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (annotate) {\n    children.push_back(\n        make(sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent,\n             context, schema_context, relative_dynamic_context(), ValueNone{}));\n  }\n\n  ValueStringSet filter_strings;\n  ValueStrings filter_prefixes;\n  std::vector<ValueRegex> filter_regexes;\n\n  if (schema_context.schema.defines(\"properties\") &&\n      schema_context.schema.at(\"properties\").is_object()) {\n    for (const auto &entry :\n         schema_context.schema.at(\"properties\").as_object()) {\n      filter_strings.insert(entry.first);\n    }\n  }\n\n  if (schema_context.schema.defines(\"patternProperties\") &&\n      schema_context.schema.at(\"patternProperties\").is_object()) {\n    for (const auto &entry :\n         schema_context.schema.at(\"patternProperties\").as_object()) {\n      const auto maybe_prefix{pattern_as_prefix(entry.first)};\n      if (maybe_prefix.has_value()) {\n        filter_prefixes.push_back(maybe_prefix.value());\n      } else {\n        static const std::string pattern_properties_keyword{\n            \"patternProperties\"};\n        filter_regexes.push_back(\n            {parse_regex(entry.first, schema_context.base,\n                         schema_context.relative_pointer.initial().concat(\n                             sourcemeta::blaze::make_weak_pointer(\n                                 pattern_properties_keyword))),\n             entry.first});\n      }\n    }\n  }\n\n  // For performance, if a schema sets `additionalProperties: true` (or its\n  // variants), we don't need to do anything\n  if (!track_evaluation && children.empty()) {\n    return {};\n  }\n\n  // When `additionalProperties: false` with only `properties` (no\n  // patternProperties), and `properties` is compiled as a loop\n  // (LoopPropertiesMatchClosed), that loop already handles rejecting unknown\n  // properties, so we don't need to emit anything for `additionalProperties`\n  if (context.mode == Mode::FastValidation && children.size() == 1 &&\n      children.front().type == InstructionIndex::AssertionFail &&\n      !filter_strings.empty() && filter_prefixes.empty() &&\n      filter_regexes.empty() &&\n      properties_as_loop(context, schema_context,\n                         schema_context.schema.at(\"properties\"))) {\n    return {};\n  }\n\n  // When all properties are required and `additionalProperties: false`,\n  // the `required` keyword compiles to `AssertionDefinesExactly` which already\n  // checks that the object has exactly the required properties, so we don't\n  // need to emit anything for `additionalProperties`\n  if (context.mode == Mode::FastValidation && children.size() == 1 &&\n      children.front().type == InstructionIndex::AssertionFail &&\n      !filter_strings.empty() && filter_prefixes.empty() &&\n      filter_regexes.empty() &&\n      is_closed_properties_required(schema_context.schema,\n                                    required_properties(schema_context))) {\n    return {};\n  }\n\n  if (context.mode == Mode::FastValidation && filter_strings.empty() &&\n      filter_prefixes.empty() && filter_regexes.size() == 1 &&\n      !track_evaluation && !children.empty() &&\n      children.front().type == InstructionIndex::AssertionFail) {\n    return {};\n  }\n\n  if (!filter_strings.empty() || !filter_prefixes.empty() ||\n      !filter_regexes.empty()) {\n    if (track_evaluation) {\n      children.push_back(\n          make(sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n               schema_context, relative_dynamic_context(), ValuePointer{}));\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesExcept,\n                 context, schema_context, dynamic_context,\n                 ValuePropertyFilter{std::move(filter_strings),\n                                     std::move(filter_prefixes),\n                                     std::move(filter_regexes)},\n                 std::move(children))};\n  } else if (track_evaluation) {\n    if (children.empty()) {\n      return {make(sourcemeta::blaze::InstructionIndex::Evaluate, context,\n                   schema_context, dynamic_context, ValueNone{})};\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LoopPropertiesEvaluate,\n                 context, schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  } else if (children.size() == 1 &&\n             children.front().type == InstructionIndex::AssertionFail) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionObjectSizeLess,\n                 context, schema_context, dynamic_context,\n                 ValueUnsignedInteger{1})};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::LoopProperties, context,\n                 schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n}\n\nauto compiler_draft3_applicator_additionalproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  return compiler_draft3_applicator_additionalproperties_with_options(\n      context, schema_context, dynamic_context, false, false);\n}\n\nauto compiler_draft3_validation_pattern(const Context &context,\n                                        const SchemaContext &schema_context,\n                                        const DynamicContext &dynamic_context,\n                                        const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_string()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"string\") {\n    return {};\n  }\n\n  const auto &regex_string{\n      schema_context.schema.at(dynamic_context.keyword).to_string()};\n  return {\n      make(sourcemeta::blaze::InstructionIndex::AssertionRegex, context,\n           schema_context, dynamic_context,\n           ValueRegex{.first = parse_regex(regex_string, schema_context.base,\n                                           schema_context.relative_pointer),\n                      .second = regex_string})};\n}\n\nauto compiler_draft3_applicator_items_array(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const bool annotate,\n    const bool track_evaluation) -> Instructions {\n  if (schema_context.is_property_name) {\n    return {};\n  }\n\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  const auto items_size{\n      schema_context.schema.at(dynamic_context.keyword).size()};\n  if (items_size == 0) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  // Precompile subschemas\n  std::vector<Instructions> subschemas;\n  subschemas.reserve(items_size);\n  const auto &array{\n      schema_context.schema.at(dynamic_context.keyword).as_array()};\n  for (auto iterator{array.cbegin()}; iterator != array.cend(); ++iterator) {\n    subschemas.push_back(compile(context, schema_context,\n                                 relative_dynamic_context(),\n                                 {subschemas.size()}, {subschemas.size()}));\n  }\n\n  Instructions children;\n  for (std::size_t cursor = 0; cursor < items_size; cursor++) {\n    Instructions subchildren;\n    for (std::size_t index = 0; index < cursor + 1; index++) {\n      for (const auto &substep : subschemas.at(index)) {\n        subchildren.push_back(substep);\n      }\n    }\n\n    if (annotate) {\n      subchildren.push_back(\n          make(sourcemeta::blaze::InstructionIndex::AnnotationEmit, context,\n               schema_context, relative_dynamic_context(),\n               sourcemeta::core::JSON{cursor}));\n    }\n\n    children.push_back(make(sourcemeta::blaze::InstructionIndex::ControlGroup,\n                            context, schema_context, relative_dynamic_context(),\n                            ValueNone{}, std::move(subchildren)));\n  }\n\n  Instructions tail;\n  for (const auto &subschema : subschemas) {\n    for (const auto &substep : subschema) {\n      tail.push_back(substep);\n    }\n  }\n\n  if (annotate) {\n    tail.push_back(make(sourcemeta::blaze::InstructionIndex::AnnotationEmit,\n                        context, schema_context, relative_dynamic_context(),\n                        sourcemeta::core::JSON{children.size() - 1}));\n    tail.push_back(make(sourcemeta::blaze::InstructionIndex::AnnotationEmit,\n                        context, schema_context, relative_dynamic_context(),\n                        sourcemeta::core::JSON{true}));\n  }\n\n  children.push_back(make(sourcemeta::blaze::InstructionIndex::ControlGroup,\n                          context, schema_context, relative_dynamic_context(),\n                          ValueNone{}, std::move(tail)));\n\n  if (track_evaluation) {\n    return {\n        make(sourcemeta::blaze::InstructionIndex::AssertionArrayPrefixEvaluate,\n             context, schema_context, dynamic_context, ValueNone{},\n             std::move(children))};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionArrayPrefix,\n                 context, schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n}\n\nauto is_number_type_check(const Instruction &instruction) -> bool {\n  if (instruction.type != InstructionIndex::AssertionTypeStrictAny) {\n    return false;\n  }\n\n  const auto &value{std::get<ValueTypes>(instruction.value)};\n  const auto numeric_count{\n      static_cast<std::size_t>(value.test(\n          std::to_underlying(sourcemeta::core::JSON::Type::Integer))) +\n      static_cast<std::size_t>(\n          value.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))) +\n      static_cast<std::size_t>(value.test(\n          std::to_underlying(sourcemeta::core::JSON::Type::Decimal)))};\n  return numeric_count >= 2 && value.count() == numeric_count;\n}\n\nauto is_integer_bounded_pattern(const Instructions &children) -> bool {\n  if (children.size() != 3) {\n    return false;\n  }\n\n  bool has_type{false};\n  bool has_min{false};\n  bool has_max{false};\n  for (const auto &child : children) {\n    if (is_number_type_check(child)) {\n      has_type = true;\n    } else if (child.type == InstructionIndex::AssertionGreaterEqual) {\n      if (!std::get<ValueJSON>(child.value).is_integer()) {\n        return false;\n      }\n      has_min = true;\n    } else if (child.type == InstructionIndex::AssertionLessEqual) {\n      if (!std::get<ValueJSON>(child.value).is_integer()) {\n        return false;\n      }\n      has_max = true;\n    }\n  }\n\n  return has_type && has_min && has_max;\n}\n\nauto compiler_draft3_applicator_items_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const bool annotate,\n    const bool track_evaluation) -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  if (is_schema(schema_context.schema.at(dynamic_context.keyword))) {\n    if (annotate || track_evaluation) {\n      Instructions subchildren{compile(context, schema_context,\n                                       relative_dynamic_context(),\n                                       sourcemeta::core::empty_weak_pointer,\n                                       sourcemeta::core::empty_weak_pointer)};\n\n      Instructions children;\n\n      if (!subchildren.empty()) {\n        children.push_back(make(sourcemeta::blaze::InstructionIndex::LoopItems,\n                                context, schema_context, dynamic_context,\n                                ValueNone{}, std::move(subchildren)));\n      }\n\n      if (!annotate && !track_evaluation) {\n        return children;\n      }\n\n      Instructions tail;\n\n      if (annotate) {\n        tail.push_back(make(sourcemeta::blaze::InstructionIndex::AnnotationEmit,\n                            context, schema_context, relative_dynamic_context(),\n                            sourcemeta::core::JSON{true}));\n      }\n\n      if (track_evaluation) {\n        tail.push_back(\n            make(sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n                 schema_context, relative_dynamic_context(), ValuePointer{}));\n      }\n\n      children.push_back(\n          make(sourcemeta::blaze::InstructionIndex::LogicalWhenType, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON::Type::Array, std::move(tail)));\n\n      return children;\n    }\n\n    Instructions children{compile(context, schema_context,\n                                  relative_dynamic_context(),\n                                  sourcemeta::core::empty_weak_pointer,\n                                  sourcemeta::core::empty_weak_pointer)};\n    if (track_evaluation) {\n      children.push_back(\n          make(sourcemeta::blaze::InstructionIndex::ControlEvaluate, context,\n               schema_context, relative_dynamic_context(), ValuePointer{}));\n    }\n\n    if (children.empty()) {\n      return {};\n    }\n\n    if (context.mode == Mode::FastValidation && children.size() == 3 &&\n        is_integer_bounded_pattern(children)) {\n      return {make(sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded,\n                   context, schema_context, dynamic_context,\n                   extract_integer_bounds(children))};\n    }\n\n    if (context.mode == Mode::FastValidation && children.size() == 1) {\n      if (children.front().type == InstructionIndex::AssertionTypeStrict) {\n        return {make(sourcemeta::blaze::InstructionIndex::LoopItemsTypeStrict,\n                     context, schema_context, dynamic_context,\n                     children.front().value)};\n      } else if (children.front().type == InstructionIndex::AssertionType) {\n        return {make(sourcemeta::blaze::InstructionIndex::LoopItemsType,\n                     context, schema_context, dynamic_context,\n                     children.front().value)};\n      } else if (children.front().type ==\n                 InstructionIndex::AssertionTypeStrictAny) {\n        return {make(\n            sourcemeta::blaze::InstructionIndex::LoopItemsTypeStrictAny,\n            context, schema_context, dynamic_context, children.front().value)};\n      } else if (children.front().type ==\n                 InstructionIndex::LoopPropertiesExactlyTypeStrictHash) {\n        auto value_copy = children.front().value;\n        auto current{make(sourcemeta::blaze::InstructionIndex::LoopItems,\n                          context, schema_context, dynamic_context, ValueNone{},\n                          std::move(children))};\n        if (std::get<ValueTypedHashes>(value_copy).second.first.size() == 3) {\n          return {Instruction{.type = sourcemeta::blaze::InstructionIndex::\n                                  LoopItemsPropertiesExactlyTypeStrictHash3,\n                              .relative_instance_location =\n                                  current.relative_instance_location,\n                              .value = std::move(value_copy),\n                              .children = {},\n                              .extra_index = current.extra_index}};\n        }\n\n        return {Instruction{.type = sourcemeta::blaze::InstructionIndex::\n                                LoopItemsPropertiesExactlyTypeStrictHash,\n                            .relative_instance_location =\n                                current.relative_instance_location,\n                            .value = std::move(value_copy),\n                            .children = {},\n                            .extra_index = current.extra_index}};\n      }\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LoopItems, context,\n                 schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n\n  return compiler_draft3_applicator_items_array(\n      context, schema_context, dynamic_context, annotate, track_evaluation);\n}\n\nauto compiler_draft3_applicator_items(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  return compiler_draft3_applicator_items_with_options(\n      context, schema_context, dynamic_context, false, false);\n}\n\nauto compiler_draft3_applicator_additionalitems_from_cursor(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const std::size_t cursor,\n    const bool annotate, const bool track_evaluation) -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  Instructions subchildren{compile(context, schema_context,\n                                   relative_dynamic_context(),\n                                   sourcemeta::core::empty_weak_pointer,\n                                   sourcemeta::core::empty_weak_pointer)};\n\n  Instructions children;\n\n  if (!subchildren.empty()) {\n    if (context.mode == Mode::FastValidation && cursor == 0 && !annotate &&\n        !track_evaluation && is_integer_bounded_pattern(subchildren)) {\n      children.push_back(\n          make(sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded,\n               context, schema_context, dynamic_context,\n               extract_integer_bounds(subchildren)));\n      return children;\n    }\n\n    children.push_back(make(sourcemeta::blaze::InstructionIndex::LoopItemsFrom,\n                            context, schema_context, dynamic_context,\n                            ValueUnsignedInteger{cursor},\n                            std::move(subchildren)));\n  }\n\n  // Avoid one extra wrapper instruction if possible\n  if (!annotate && !track_evaluation) {\n    return children;\n  }\n\n  Instructions tail;\n\n  if (annotate) {\n    tail.push_back(make(sourcemeta::blaze::InstructionIndex::AnnotationEmit,\n                        context, schema_context, relative_dynamic_context(),\n                        sourcemeta::core::JSON{true}));\n  }\n\n  if (track_evaluation) {\n    tail.push_back(make(sourcemeta::blaze::InstructionIndex::ControlEvaluate,\n                        context, schema_context, relative_dynamic_context(),\n                        ValuePointer{}));\n  }\n\n  assert(!tail.empty());\n  children.push_back(\n      make(sourcemeta::blaze::InstructionIndex::LogicalWhenArraySizeGreater,\n           context, schema_context, dynamic_context,\n           ValueUnsignedInteger{cursor}, std::move(tail)));\n\n  return children;\n}\n\nauto compiler_draft3_applicator_additionalitems_with_options(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const bool annotate,\n    const bool track_evaluation) -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  assert(schema_context.schema.is_object());\n\n  // Nothing to do here\n  if (!schema_context.schema.defines(\"items\") ||\n      schema_context.schema.at(\"items\").is_object()) {\n    return {};\n  }\n\n  const auto cursor{(schema_context.schema.defines(\"items\") &&\n                     schema_context.schema.at(\"items\").is_array())\n                        ? schema_context.schema.at(\"items\").size()\n                        : 0};\n\n  return compiler_draft3_applicator_additionalitems_from_cursor(\n      context, schema_context, dynamic_context, cursor, annotate,\n      track_evaluation);\n}\n\nauto compiler_draft3_applicator_additionalitems(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  return compiler_draft3_applicator_additionalitems_with_options(\n      context, schema_context, dynamic_context, false, false);\n}\n\nauto compiler_draft3_validation_enum(const Context &context,\n                                     const SchemaContext &schema_context,\n                                     const DynamicContext &dynamic_context,\n                                     const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  if (schema_context.schema.at(dynamic_context.keyword).empty()) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionFail, context,\n                 schema_context, dynamic_context, ValueNone{})};\n  }\n\n  if (schema_context.schema.at(dynamic_context.keyword).size() == 1) {\n    return {\n        make(sourcemeta::blaze::InstructionIndex::AssertionEqual, context,\n             schema_context, dynamic_context,\n             sourcemeta::core::JSON{\n                 schema_context.schema.at(dynamic_context.keyword).front()})};\n  }\n\n  std::vector<std::pair<sourcemeta::blaze::ValueString,\n                        sourcemeta::blaze::ValueStringSet::hash_type>>\n      perfect_string_hashes;\n  ValueSet options;\n  sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n  for (const auto &option :\n       schema_context.schema.at(dynamic_context.keyword).as_array()) {\n    if (option.is_string()) {\n      const auto hash{hasher(option.to_string())};\n      if (hasher.is_perfect(hash)) {\n        perfect_string_hashes.emplace_back(option.to_string(), hash);\n      }\n    }\n\n    options.insert(option);\n  }\n\n  // Only apply this optimisation on fast validation, as it\n  // can affect error messages\n  if (context.mode == Mode::FastValidation &&\n      perfect_string_hashes.size() == options.size()) {\n    return {\n        make(sourcemeta::blaze::InstructionIndex::AssertionEqualsAnyStringHash,\n             context, schema_context, dynamic_context,\n             to_string_hashes(perfect_string_hashes))};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionEqualsAny, context,\n               schema_context, dynamic_context, std::move(options))};\n}\n\nauto compiler_draft3_validation_uniqueitems(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_boolean() ||\n      !schema_context.schema.at(dynamic_context.keyword).to_boolean()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionUnique, context,\n               schema_context, dynamic_context, ValueNone{})};\n}\n\nauto compiler_draft3_validation_maxlength(const Context &context,\n                                          const SchemaContext &schema_context,\n                                          const DynamicContext &dynamic_context,\n                                          const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"string\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"string\") {\n    return {};\n  }\n\n  return {make(\n      sourcemeta::blaze::InstructionIndex::AssertionStringSizeLess, context,\n      schema_context, dynamic_context,\n      ValueUnsignedInteger{\n          static_cast<unsigned long>(\n              schema_context.schema.at(dynamic_context.keyword).as_integer()) +\n          1})};\n}\n\nauto compiler_draft3_validation_minlength(const Context &context,\n                                          const SchemaContext &schema_context,\n                                          const DynamicContext &dynamic_context,\n                                          const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"string\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"string\") {\n    return {};\n  }\n\n  const auto value{\n      schema_context.schema.at(dynamic_context.keyword).as_integer()};\n  if (value <= 0) {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionStringSizeGreater,\n               context, schema_context, dynamic_context,\n               ValueUnsignedInteger{static_cast<unsigned long>(value - 1)})};\n}\n\nauto compiler_draft3_validation_maxitems(const Context &context,\n                                         const SchemaContext &schema_context,\n                                         const DynamicContext &dynamic_context,\n                                         const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"array\") {\n    return {};\n  }\n\n  return {make(\n      sourcemeta::blaze::InstructionIndex::AssertionArraySizeLess, context,\n      schema_context, dynamic_context,\n      ValueUnsignedInteger{\n          static_cast<unsigned long>(\n              schema_context.schema.at(dynamic_context.keyword).as_integer()) +\n          1})};\n}\n\nauto compiler_draft3_validation_minitems(const Context &context,\n                                         const SchemaContext &schema_context,\n                                         const DynamicContext &dynamic_context,\n                                         const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"array\") {\n    return {};\n  }\n\n  const auto value{\n      schema_context.schema.at(dynamic_context.keyword).as_integer()};\n  if (value <= 0) {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionArraySizeGreater,\n               context, schema_context, dynamic_context,\n               ValueUnsignedInteger{static_cast<unsigned long>(value - 1)})};\n}\n\nauto compiler_draft3_validation_maximum(const Context &context,\n                                        const SchemaContext &schema_context,\n                                        const DynamicContext &dynamic_context,\n                                        const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_number()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"integer\" &&\n      schema_context.schema.at(\"type\").to_string() != \"number\") {\n    return {};\n  }\n\n  // TODO: As an optimization, if `minimum` is set to the same number, do\n  // a single equality assertion\n\n  assert(schema_context.schema.is_object());\n  if (schema_context.schema.defines(\"exclusiveMaximum\") &&\n      schema_context.schema.at(\"exclusiveMaximum\").is_boolean() &&\n      schema_context.schema.at(\"exclusiveMaximum\").to_boolean()) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionLess, context,\n                 schema_context, dynamic_context,\n                 sourcemeta::core::JSON{\n                     schema_context.schema.at(dynamic_context.keyword)})};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionLessEqual,\n                 context, schema_context, dynamic_context,\n                 sourcemeta::core::JSON{\n                     schema_context.schema.at(dynamic_context.keyword)})};\n  }\n}\n\nauto compiler_draft3_validation_minimum(const Context &context,\n                                        const SchemaContext &schema_context,\n                                        const DynamicContext &dynamic_context,\n                                        const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_number()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"integer\" &&\n      schema_context.schema.at(\"type\").to_string() != \"number\") {\n    return {};\n  }\n\n  // TODO: As an optimization, if `maximum` is set to the same number, do\n  // a single equality assertion\n\n  assert(schema_context.schema.is_object());\n  if (schema_context.schema.defines(\"exclusiveMinimum\") &&\n      schema_context.schema.at(\"exclusiveMinimum\").is_boolean() &&\n      schema_context.schema.at(\"exclusiveMinimum\").to_boolean()) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionGreater, context,\n                 schema_context, dynamic_context,\n                 sourcemeta::core::JSON{\n                     schema_context.schema.at(dynamic_context.keyword)})};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionGreaterEqual,\n                 context, schema_context, dynamic_context,\n                 sourcemeta::core::JSON{\n                     schema_context.schema.at(dynamic_context.keyword)})};\n  }\n}\n\nauto compiler_draft3_validation_type(const Context &context,\n                                     const SchemaContext &schema_context,\n                                     const DynamicContext &dynamic_context,\n                                     const Instructions &) -> Instructions {\n  const auto &value{schema_context.schema.at(dynamic_context.keyword)};\n\n  using Known = sourcemeta::core::Vocabularies::Known;\n  const auto is_draft3{\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper)};\n\n  if (is_draft3) {\n    if (value.is_string() && value.to_string() == \"any\") {\n      return draft3_any_type_instructions(context, schema_context,\n                                          dynamic_context);\n    }\n\n    if (value.is_array()) {\n      bool has_object{false};\n      for (const auto &element : value.as_array()) {\n        if (element.is_string() && element.to_string() == \"any\") {\n          return draft3_any_type_instructions(context, schema_context,\n                                              dynamic_context);\n        }\n        if (element.is_object()) {\n          has_object = true;\n        }\n      }\n\n      if (has_object) {\n        if (context.mode == Mode::FastValidation && value.size() == 1) {\n          return compile(\n              context, schema_context, dynamic_context,\n              {static_cast<sourcemeta::core::Pointer::Token::Index>(0)});\n        }\n\n        Instructions disjunctors;\n        for (std::uint64_t index = 0; index < value.size(); index++) {\n          const auto &element{value.at(index)};\n          Instructions branch;\n\n          if (element.is_object()) {\n            branch = compile(\n                context, schema_context, relative_dynamic_context(),\n                {static_cast<sourcemeta::core::Pointer::Token::Index>(index)});\n          } else if (element.is_string()) {\n            const auto &type_string{element.to_string()};\n            if (type_string == \"null\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::Null));\n            } else if (type_string == \"boolean\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::Boolean));\n            } else if (type_string == \"object\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::Object));\n            } else if (type_string == \"array\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::Array));\n            } else if (type_string == \"number\") {\n              ValueTypes types{};\n              types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n              types.set(\n                  std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n              types.set(\n                  std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n              branch.push_back(make(\n                  sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                  context, schema_context, relative_dynamic_context(), types));\n            } else if (type_string == \"integer\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::Integer));\n            } else if (type_string == \"string\") {\n              branch.push_back(\n                  make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                       context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::JSON::Type::String));\n            } else {\n              continue;\n            }\n          } else {\n            continue;\n          }\n\n          disjunctors.push_back(\n              make(sourcemeta::blaze::InstructionIndex::ControlGroup, context,\n                   schema_context, relative_dynamic_context(), ValueNone{},\n                   std::move(branch)));\n        }\n\n        return {make(sourcemeta::blaze::InstructionIndex::LogicalOr, context,\n                     schema_context, dynamic_context, ValueBoolean{false},\n                     std::move(disjunctors))};\n      }\n    }\n  }\n\n  if (value.is_string()) {\n    const auto &type{value.to_string()};\n    if (type == \"null\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_null(); })) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Null)};\n    } else if (type == \"boolean\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_boolean(); })) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Boolean)};\n    } else if (type == \"object\") {\n      if (!is_draft3) {\n        const auto minimum{unsigned_integer_property(schema_context.schema,\n                                                     \"minProperties\", 0)};\n        const auto maximum{\n            unsigned_integer_property(schema_context.schema, \"maxProperties\")};\n\n        if (context.mode == Mode::FastValidation) {\n          if (maximum.has_value() && minimum == 0) {\n            return {make(\n                sourcemeta::blaze::InstructionIndex::AssertionTypeObjectUpper,\n                context, schema_context, dynamic_context,\n                ValueUnsignedInteger{maximum.value()})};\n          } else if (minimum > 0 || maximum.has_value()) {\n            return {make(\n                sourcemeta::blaze::InstructionIndex::AssertionTypeObjectBounded,\n                context, schema_context, dynamic_context,\n                ValueRange{minimum, maximum, false})};\n          }\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_object(); })) {\n        return {};\n      }\n\n      if (!is_draft3 && context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"required\")) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Object)};\n    } else if (type == \"array\") {\n      const auto minimum{\n          unsigned_integer_property(schema_context.schema, \"minItems\", 0)};\n      const auto maximum{\n          unsigned_integer_property(schema_context.schema, \"maxItems\")};\n\n      if (context.mode == Mode::FastValidation) {\n        if (maximum.has_value() && minimum == 0) {\n          return {\n              make(sourcemeta::blaze::InstructionIndex::AssertionTypeArrayUpper,\n                   context, schema_context, dynamic_context,\n                   ValueUnsignedInteger{maximum.value()})};\n        } else if (minimum > 0 || maximum.has_value()) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeArrayBounded,\n              context, schema_context, dynamic_context,\n              ValueRange{minimum, maximum, false})};\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_array(); })) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Array)};\n    } else if (type == \"number\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_number(); })) {\n        return {};\n      }\n\n      ValueTypes types{};\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                   context, schema_context, dynamic_context, types)};\n    } else if (type == \"integer\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_integer(); })) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Integer)};\n    } else if (type == \"string\") {\n      const auto minimum{\n          unsigned_integer_property(schema_context.schema, \"minLength\", 0)};\n      const auto maximum{\n          unsigned_integer_property(schema_context.schema, \"maxLength\")};\n\n      if (context.mode == Mode::FastValidation) {\n        if (maximum.has_value() && minimum == 0) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeStringUpper,\n              context, schema_context, dynamic_context,\n              ValueUnsignedInteger{maximum.value()})};\n        } else if (minimum > 0 || maximum.has_value()) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeStringBounded,\n              context, schema_context, dynamic_context,\n              ValueRange{minimum, maximum, false})};\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &candidate) { return candidate.is_string(); })) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::String)};\n    } else {\n      return {};\n    }\n  } else if (value.is_array() && value.size() == 1 &&\n             value.front().is_string()) {\n    const auto &type{value.front().to_string()};\n    if (type == \"null\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Null)};\n    } else if (type == \"boolean\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Boolean)};\n    } else if (type == \"object\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Object)};\n    } else if (type == \"array\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Array)};\n    } else if (type == \"number\") {\n      ValueTypes types{};\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                   context, schema_context, dynamic_context, types)};\n    } else if (type == \"integer\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Integer)};\n    } else if (type == \"string\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::String)};\n    } else {\n      return {};\n    }\n  } else if (value.is_array()) {\n    ValueTypes types{};\n    for (const auto &element : value.as_array()) {\n      assert(element.is_string());\n      const auto &type_string{element.to_string()};\n      if (type_string == \"null\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Null));\n      } else if (type_string == \"boolean\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Boolean));\n      } else if (type_string == \"object\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Object));\n      } else if (type_string == \"array\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Array));\n      } else if (type_string == \"number\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      } else if (type_string == \"integer\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      } else if (type_string == \"string\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::String));\n      }\n    }\n\n    if (!types.any()) {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionFail, context,\n                   schema_context, dynamic_context, ValueNone{})};\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                 context, schema_context, dynamic_context, types)};\n  }\n\n  return {};\n}\n\nauto compiler_draft3_validation_disallow(const Context &context,\n                                         const SchemaContext &schema_context,\n                                         const DynamicContext &dynamic_context,\n                                         const Instructions &) -> Instructions {\n  const auto &value{schema_context.schema.at(dynamic_context.keyword)};\n\n  const auto contains_any{\n      (value.is_string() && value.to_string() == \"any\") ||\n      (value.is_array() &&\n       std::ranges::any_of(value.as_array(), [](const auto &element) {\n         return element.is_string() && element.to_string() == \"any\";\n       }))};\n  if (contains_any) {\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionFail, context,\n                 schema_context, dynamic_context, ValueNone{})};\n  }\n\n  ValueTypes types{};\n  Instructions subschema_nots;\n\n  if (value.is_string()) {\n    draft3_set_type_bits(value.to_string(), types);\n  } else if (value.is_array()) {\n    for (std::uint64_t index = 0; index < value.size(); index++) {\n      const auto &element{value.at(index)};\n      if (element.is_string()) {\n        draft3_set_type_bits(element.to_string(), types);\n      } else if (element.is_object()) {\n        sourcemeta::core::WeakPointer index_suffix;\n        index_suffix.push_back(index);\n        const auto element_uri{\n            sourcemeta::core::to_uri(\n                schema_context.relative_pointer.concat(index_suffix),\n                schema_context.base)\n                .canonicalize()\n                .recompose()};\n\n        auto inner_instructions{\n            compile(context, schema_context, relative_dynamic_context(),\n                    sourcemeta::core::empty_weak_pointer,\n                    sourcemeta::core::empty_weak_pointer, element_uri)};\n\n        const auto element_relative_pointer{\n            schema_context.relative_pointer.concat(index_suffix)};\n        const SchemaContext element_schema_context{\n            .relative_pointer = element_relative_pointer,\n            .schema = schema_context.schema,\n            .vocabularies = schema_context.vocabularies,\n            .base = schema_context.base,\n            .is_property_name = schema_context.is_property_name};\n\n        const auto element_base_schema_location{\n            sourcemeta::blaze::make_weak_pointer(dynamic_context.keyword,\n                                                 index)};\n        const DynamicContext element_dynamic_context{\n            .keyword = KEYWORD_EMPTY,\n            .base_schema_location = element_base_schema_location,\n            .base_instance_location = dynamic_context.base_instance_location};\n\n        subschema_nots.push_back(\n            make(sourcemeta::blaze::InstructionIndex::LogicalNot, context,\n                 element_schema_context, element_dynamic_context, ValueNone{},\n                 std::move(inner_instructions)));\n      }\n    }\n  }\n\n  Instructions result;\n  if (types.any()) {\n    result.push_back(\n        make(sourcemeta::blaze::InstructionIndex::AssertionNotTypeStrictAny,\n             context, schema_context, dynamic_context, types));\n  }\n  for (auto &&instruction : subschema_nots) {\n    result.push_back(std::move(instruction));\n  }\n  return result;\n}\n\nauto compiler_draft3_applicator_extends(const Context &context,\n                                        const SchemaContext &schema_context,\n                                        const DynamicContext &dynamic_context,\n                                        const Instructions &) -> Instructions {\n  assert(!context.uses_dynamic_scopes);\n\n  const auto &value{schema_context.schema.at(dynamic_context.keyword)};\n\n  if (value.is_object()) {\n    if (context.mode == Mode::FastValidation) {\n      return compile(context, schema_context, dynamic_context,\n                     sourcemeta::core::empty_weak_pointer,\n                     sourcemeta::core::empty_weak_pointer);\n    }\n\n    auto inner{compile(context, schema_context, relative_dynamic_context(),\n                       sourcemeta::core::empty_weak_pointer,\n                       sourcemeta::core::empty_weak_pointer)};\n    if (inner.empty()) {\n      return {};\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LogicalAnd, context,\n                 schema_context, dynamic_context, ValueNone{},\n                 std::move(inner))};\n  }\n\n  if (!value.is_array()) {\n    return {};\n  }\n\n  if (value.empty()) {\n    return {};\n  }\n\n  Instructions children;\n\n  if (context.mode == Mode::FastValidation) {\n    for (std::uint64_t index = 0; index < value.size(); index++) {\n      for (auto &&step : compile(\n               context, schema_context, dynamic_context,\n               {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})) {\n        children.push_back(std::move(step));\n      }\n    }\n\n    return children;\n  }\n\n  for (std::uint64_t index = 0; index < value.size(); index++) {\n    auto arm{\n        compile(context, schema_context, relative_dynamic_context(),\n                {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})};\n    if (arm.empty()) {\n      continue;\n    }\n    children.push_back(make(sourcemeta::blaze::InstructionIndex::ControlGroup,\n                            context, schema_context, relative_dynamic_context(),\n                            ValueNone{}, std::move(arm)));\n  }\n\n  if (children.empty()) {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::LogicalAnd, context,\n               schema_context, dynamic_context, ValueNone{},\n               std::move(children))};\n}\n\nauto compiler_draft3_applicator_dependencies(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  if (!schema_context.schema.at(dynamic_context.keyword).is_object()) {\n    return {};\n  }\n\n  using Known = sourcemeta::core::Vocabularies::Known;\n  const auto is_draft3{\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      schema_context.vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper)};\n\n  Instructions children;\n  ValueStringMap dependencies;\n\n  for (const auto &entry :\n       schema_context.schema.at(dynamic_context.keyword).as_object()) {\n    if (is_schema(entry.second)) {\n      if (!entry.second.is_boolean() || !entry.second.to_boolean()) {\n        children.push_back(make(\n            sourcemeta::blaze::InstructionIndex::LogicalWhenDefines, context,\n            schema_context, dynamic_context, make_property(entry.first),\n            compile(context, schema_context, relative_dynamic_context(),\n                    sourcemeta::blaze::make_weak_pointer(entry.first))));\n      }\n    } else if (entry.second.is_array()) {\n      std::vector<sourcemeta::core::JSON::String> properties;\n      for (const auto &property : entry.second.as_array()) {\n        assert(property.is_string());\n        properties.push_back(property.to_string());\n      }\n\n      if (!properties.empty()) {\n        dependencies.emplace(entry.first, properties);\n      }\n    } else if (is_draft3 && entry.second.is_string()) {\n      dependencies.emplace(entry.first,\n                           std::vector<sourcemeta::core::JSON::String>{\n                               entry.second.to_string()});\n    }\n  }\n\n  if (!dependencies.empty()) {\n    children.push_back(make(\n        sourcemeta::blaze::InstructionIndex::AssertionPropertyDependencies,\n        context, schema_context, dynamic_context, std::move(dependencies)));\n  }\n\n  return children;\n}\n\nauto compiler_draft3_validation_divisibleby(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_number()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"integer\" &&\n      schema_context.schema.at(\"type\").to_string() != \"number\") {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionDivisible, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON{\n                   schema_context.schema.at(dynamic_context.keyword)})};\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_draft4.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT4_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT4_H_\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <algorithm> // std::ranges::any_of, std::ranges::all_of, std::ranges::none_of, std::find_if\n#include <cassert> // assert\n#include <set>     // std::set\n#include <utility> // std::move, std::to_underlying\n\n#include \"compile_helpers.h\"\n#include \"default_compiler_draft3.h\"\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compiler_draft4_validation_required(const Context &context,\n                                         const SchemaContext &schema_context,\n                                         const DynamicContext &dynamic_context,\n                                         const Instructions &current)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  return compile_required_assertions(\n      context, schema_context, dynamic_context, current,\n      json_array_to_string_set(\n          schema_context.schema.at(dynamic_context.keyword)));\n}\n\nauto compiler_draft4_applicator_allof(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  assert(!schema_context.schema.at(dynamic_context.keyword).empty());\n\n  Instructions children;\n\n  if (context.mode == Mode::FastValidation &&\n      // TODO: Make this work with `$dynamicRef`\n      !context.uses_dynamic_scopes) {\n    for (std::uint64_t index = 0;\n         index < schema_context.schema.at(dynamic_context.keyword).size();\n         index++) {\n      for (auto &&step : compile(\n               context, schema_context, dynamic_context,\n               {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})) {\n        children.push_back(std::move(step));\n      }\n    }\n\n    return children;\n  } else {\n    for (std::uint64_t index = 0;\n         index < schema_context.schema.at(dynamic_context.keyword).size();\n         index++) {\n      for (auto &&step : compile(\n               context, schema_context, relative_dynamic_context(),\n               {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})) {\n        children.push_back(std::move(step));\n      }\n    }\n\n    return {make(sourcemeta::blaze::InstructionIndex::LogicalAnd, context,\n                 schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n}\n\nauto compiler_draft4_applicator_anyof(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  assert(!schema_context.schema.at(dynamic_context.keyword).empty());\n\n  Instructions disjunctors;\n  for (std::uint64_t index = 0;\n       index < schema_context.schema.at(dynamic_context.keyword).size();\n       index++) {\n    disjunctors.push_back(make(\n        sourcemeta::blaze::InstructionIndex::ControlGroup, context,\n        schema_context, relative_dynamic_context(), ValueNone{},\n        compile(\n            context, schema_context, relative_dynamic_context(),\n            {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})));\n  }\n\n  if (context.mode == Mode::FastValidation &&\n      std::ranges::all_of(disjunctors, [](const auto &instruction) {\n        return instruction.children.size() == 1 &&\n               (instruction.children.front().type ==\n                    sourcemeta::blaze::InstructionIndex::AssertionTypeStrict ||\n                instruction.children.front().type ==\n                    sourcemeta::blaze::InstructionIndex::\n                        AssertionTypeStrictAny);\n      })) {\n    ValueTypes types{};\n    for (const auto &instruction : disjunctors) {\n      if (instruction.children.front().type ==\n          sourcemeta::blaze::InstructionIndex::AssertionTypeStrict) {\n        const auto &value{\n            *std::get_if<ValueType>(&instruction.children.front().value)};\n        types.set(static_cast<std::uint8_t>(value));\n      }\n\n      if (instruction.children.front().type ==\n          sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny) {\n        const auto &value{\n            *std::get_if<ValueTypes>(&instruction.children.front().value)};\n        types |= value;\n      }\n    }\n\n    assert(types.any());\n    const auto popcount{types.count()};\n    if (popcount > 1) {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                   context, schema_context, dynamic_context, types)};\n    } else {\n      std::uint8_t type_index{0};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          type_index = bit;\n          break;\n        }\n      }\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   static_cast<ValueType>(type_index))};\n    }\n  }\n\n  const auto requires_exhaustive{context.mode == Mode::Exhaustive ||\n                                 requires_evaluation(context, schema_context)};\n\n  return {make(sourcemeta::blaze::InstructionIndex::LogicalOr, context,\n               schema_context, dynamic_context,\n               ValueBoolean{requires_exhaustive}, std::move(disjunctors))};\n}\n\nauto compiler_draft4_applicator_oneof(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    return {};\n  }\n\n  assert(!schema_context.schema.at(dynamic_context.keyword).empty());\n\n  Instructions disjunctors;\n  for (std::uint64_t index = 0;\n       index < schema_context.schema.at(dynamic_context.keyword).size();\n       index++) {\n    disjunctors.push_back(make(\n        sourcemeta::blaze::InstructionIndex::ControlGroup, context,\n        schema_context, relative_dynamic_context(), ValueNone{},\n        compile(\n            context, schema_context, relative_dynamic_context(),\n            {static_cast<sourcemeta::core::Pointer::Token::Index>(index)})));\n  }\n\n  const auto requires_exhaustive{context.mode == Mode::Exhaustive ||\n                                 requires_evaluation(context, schema_context)};\n\n  return {make(sourcemeta::blaze::InstructionIndex::LogicalXor, context,\n               schema_context, dynamic_context,\n               ValueBoolean{requires_exhaustive}, std::move(disjunctors))};\n}\n\nauto compiler_draft4_applicator_not(const Context &context,\n                                    const SchemaContext &schema_context,\n                                    const DynamicContext &dynamic_context,\n                                    const Instructions &) -> Instructions {\n  std::size_t subschemas{0};\n  for (const auto &subschema :\n       walk_subschemas(context, schema_context, dynamic_context)) {\n    if (subschema.pointer.empty()) {\n      continue;\n    }\n\n    subschemas += 1;\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  // TODO: Be smarter about how we treat `unevaluatedItems` like how we do for\n  // `unevaluatedProperties`\n  const bool track_items{\n      std::ranges::any_of(context.unevaluated, [](const auto &dependency) {\n        return dependency.first.ends_with(\"unevaluatedItems\");\n      })};\n\n  // Only emit a `not` instruction that keeps track of\n  // evaluation if we really need it. If the \"not\" subschema\n  // does not define applicators, then that's an easy case\n  // we can skip\n  if (subschemas > 0 &&\n      (requires_evaluation(context, schema_context) || track_items)) {\n    return {make(sourcemeta::blaze::InstructionIndex::LogicalNotEvaluate,\n                 context, schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  } else {\n    return {make(sourcemeta::blaze::InstructionIndex::LogicalNot, context,\n                 schema_context, dynamic_context, ValueNone{},\n                 std::move(children))};\n  }\n}\n\nauto compiler_draft4_validation_maxproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"object\") {\n    return {};\n  }\n\n  return {make(\n      sourcemeta::blaze::InstructionIndex::AssertionObjectSizeLess, context,\n      schema_context, dynamic_context,\n      ValueUnsignedInteger{\n          static_cast<unsigned long>(\n              schema_context.schema.at(dynamic_context.keyword).as_integer()) +\n          1})};\n}\n\nauto compiler_draft4_validation_minproperties(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_integral()) {\n    return {};\n  }\n\n  assert(schema_context.schema.at(dynamic_context.keyword).is_positive());\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  // We'll handle it at the type level as an optimization\n  if (context.mode == Mode::FastValidation &&\n      schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() == \"object\") {\n    return {};\n  }\n\n  const auto value{static_cast<unsigned long>(\n      schema_context.schema.at(dynamic_context.keyword).as_integer())};\n  if (value <= 0) {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionObjectSizeGreater,\n               context, schema_context, dynamic_context,\n               ValueUnsignedInteger{value - 1})};\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_draft6.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT6_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT6_H_\n\n#include <sourcemeta/blaze/compiler.h>\n\n#include <algorithm> // std::ranges::all_of\n#include <utility>   // std::to_underlying\n\n#include \"compile_helpers.h\"\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compiler_draft6_validation_type(const Context &context,\n                                     const SchemaContext &schema_context,\n                                     const DynamicContext &dynamic_context,\n                                     const Instructions &current)\n    -> Instructions {\n  if (schema_context.schema.at(dynamic_context.keyword).is_string()) {\n    const auto &type{\n        schema_context.schema.at(dynamic_context.keyword).to_string()};\n    if (type == \"null\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_null(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_null()) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Null)};\n    } else if (type == \"boolean\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_boolean(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_boolean()) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Boolean)};\n    } else if (type == \"object\") {\n      const auto minimum{\n          unsigned_integer_property(schema_context.schema, \"minProperties\", 0)};\n      const auto maximum{\n          unsigned_integer_property(schema_context.schema, \"maxProperties\")};\n\n      if (context.mode == Mode::FastValidation) {\n        if (maximum.has_value() && minimum == 0) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeObjectUpper,\n              context, schema_context, dynamic_context,\n              ValueUnsignedInteger{maximum.value()})};\n        } else if (minimum > 0 || maximum.has_value()) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeObjectBounded,\n              context, schema_context, dynamic_context,\n              ValueRange{minimum, maximum, false})};\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_object(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_object()) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"required\")) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Object)};\n    } else if (type == \"array\") {\n      if (context.mode == Mode::FastValidation && !current.empty() &&\n          (current.back().type ==\n               sourcemeta::blaze::InstructionIndex::\n                   LoopItemsPropertiesExactlyTypeStrictHash ||\n           current.back().type ==\n               sourcemeta::blaze::InstructionIndex::\n                   LoopItemsPropertiesExactlyTypeStrictHash3 ||\n           current.back().type ==\n               sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded ||\n           current.back().type == sourcemeta::blaze::InstructionIndex::\n                                      LoopItemsIntegerBoundedSized) &&\n          current.back().relative_instance_location ==\n              to_pointer(dynamic_context.base_instance_location)) {\n        return {};\n      }\n\n      const auto minimum{\n          unsigned_integer_property(schema_context.schema, \"minItems\", 0)};\n      const auto maximum{\n          unsigned_integer_property(schema_context.schema, \"maxItems\")};\n\n      if (context.mode == Mode::FastValidation) {\n        if (maximum.has_value() && minimum == 0) {\n          return {\n              make(sourcemeta::blaze::InstructionIndex::AssertionTypeArrayUpper,\n                   context, schema_context, dynamic_context,\n                   ValueUnsignedInteger{maximum.value()})};\n        } else if (minimum > 0 || maximum.has_value()) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeArrayBounded,\n              context, schema_context, dynamic_context,\n              ValueRange{minimum, maximum, false})};\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_array(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_array()) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Array)};\n    } else if (type == \"number\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_number(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_number()) {\n        return {};\n      }\n\n      ValueTypes types{};\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                   context, schema_context, dynamic_context, types)};\n    } else if (type == \"integer\") {\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_integral(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          (schema_context.schema.at(\"const\").is_integral())) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionType, context,\n                   schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Integer)};\n    } else if (type == \"string\") {\n      if (schema_context.is_property_name) {\n        return {};\n      }\n\n      const auto minimum{\n          unsigned_integer_property(schema_context.schema, \"minLength\", 0)};\n      const auto maximum{\n          unsigned_integer_property(schema_context.schema, \"maxLength\")};\n\n      if (context.mode == Mode::FastValidation) {\n        if (maximum.has_value() && minimum == 0) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeStringUpper,\n              context, schema_context, dynamic_context,\n              ValueUnsignedInteger{maximum.value()})};\n        } else if (minimum > 0 || maximum.has_value()) {\n          return {make(\n              sourcemeta::blaze::InstructionIndex::AssertionTypeStringBounded,\n              context, schema_context, dynamic_context,\n              ValueRange{minimum, maximum, false})};\n        }\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"enum\") &&\n          schema_context.schema.at(\"enum\").is_array() &&\n          std::ranges::all_of(\n              schema_context.schema.at(\"enum\").as_array(),\n              [](const auto &value) { return value.is_string(); })) {\n        return {};\n      }\n\n      if (context.mode == Mode::FastValidation &&\n          schema_context.schema.defines(\"const\") &&\n          schema_context.schema.at(\"const\").is_string()) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::String)};\n    } else {\n      return {};\n    }\n  } else if (schema_context.schema.at(dynamic_context.keyword).is_array() &&\n             schema_context.schema.at(dynamic_context.keyword).size() == 1 &&\n             schema_context.schema.at(dynamic_context.keyword)\n                 .front()\n                 .is_string()) {\n    const auto &type{\n        schema_context.schema.at(dynamic_context.keyword).front().to_string()};\n    if (type == \"null\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Null)};\n    } else if (type == \"boolean\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Boolean)};\n    } else if (type == \"object\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Object)};\n    } else if (type == \"array\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Array)};\n    } else if (type == \"number\") {\n      ValueTypes types{};\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,\n                   context, schema_context, dynamic_context, types)};\n    } else if (type == \"integer\") {\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionType, context,\n                   schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::Integer)};\n    } else if (type == \"string\") {\n      if (schema_context.is_property_name) {\n        return {};\n      }\n\n      return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,\n                   context, schema_context, dynamic_context,\n                   sourcemeta::core::JSON::Type::String)};\n    } else {\n      return {};\n    }\n  } else if (schema_context.schema.at(dynamic_context.keyword).is_array()) {\n    ValueTypes types{};\n    for (const auto &type :\n         schema_context.schema.at(dynamic_context.keyword).as_array()) {\n      assert(type.is_string());\n      const auto &type_string{type.to_string()};\n      if (type_string == \"null\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Null));\n      } else if (type_string == \"boolean\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Boolean));\n      } else if (type_string == \"object\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Object));\n      } else if (type_string == \"array\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Array));\n      } else if (type_string == \"number\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n      } else if (type_string == \"integer\") {\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n      } else if (type_string == \"string\") {\n        if (schema_context.is_property_name) {\n          continue;\n        }\n\n        types.set(std::to_underlying(sourcemeta::core::JSON::Type::String));\n      }\n    }\n\n    assert(types.any());\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionTypeAny, context,\n                 schema_context, dynamic_context, types)};\n  }\n\n  return {};\n}\n\nauto compiler_draft6_validation_const(const Context &context,\n                                      const SchemaContext &schema_context,\n                                      const DynamicContext &dynamic_context,\n                                      const Instructions &) -> Instructions {\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionEqual, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON{\n                   schema_context.schema.at(dynamic_context.keyword)})};\n}\n\nauto compiler_draft6_validation_exclusivemaximum(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_number()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"integer\" &&\n      schema_context.schema.at(\"type\").to_string() != \"number\") {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionLess, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON{\n                   schema_context.schema.at(dynamic_context.keyword)})};\n}\n\nauto compiler_draft6_validation_exclusiveminimum(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (!schema_context.schema.at(dynamic_context.keyword).is_number()) {\n    return {};\n  }\n\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"integer\" &&\n      schema_context.schema.at(\"type\").to_string() != \"number\") {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::AssertionGreater, context,\n               schema_context, dynamic_context,\n               sourcemeta::core::JSON{\n                   schema_context.schema.at(dynamic_context.keyword)})};\n}\n\nauto compiler_draft6_applicator_contains(const Context &context,\n                                         const SchemaContext &schema_context,\n                                         const DynamicContext &dynamic_context,\n                                         const Instructions &) -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"array\") {\n    return {};\n  }\n\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (children.empty()) {\n    // We still need to check the instance is not empty\n    return {make(sourcemeta::blaze::InstructionIndex::AssertionArraySizeGreater,\n                 context, schema_context, dynamic_context,\n                 ValueUnsignedInteger{0})};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::LoopContains, context,\n               schema_context, dynamic_context,\n               ValueRange{1, std::nullopt, false}, std::move(children))};\n}\n\nauto compiler_draft6_validation_propertynames(\n    const Context &context, const SchemaContext &schema_context,\n    const DynamicContext &dynamic_context, const Instructions &)\n    -> Instructions {\n  if (schema_context.schema.defines(\"type\") &&\n      schema_context.schema.at(\"type\").is_string() &&\n      schema_context.schema.at(\"type\").to_string() != \"object\") {\n    return {};\n  }\n\n  // TODO: How can we avoid this copy?\n  auto nested_schema_context = schema_context;\n  nested_schema_context.is_property_name = true;\n  Instructions children{compile(context, nested_schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  if (children.empty()) {\n    return {};\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::LoopKeys, context,\n               schema_context, dynamic_context, ValueNone{},\n               std::move(children))};\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_draft7.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT7_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_DRAFT7_H_\n\n#include <sourcemeta/blaze/compiler.h>\n\n#include \"compile_helpers.h\"\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\n// TODO: Don't generate `if` if neither `then` nor `else` is defined\nauto compiler_draft7_applicator_if(const Context &context,\n                                   const SchemaContext &schema_context,\n                                   const DynamicContext &dynamic_context,\n                                   const Instructions &) -> Instructions {\n  // `if`\n  Instructions children{compile(context, schema_context,\n                                relative_dynamic_context(),\n                                sourcemeta::core::empty_weak_pointer,\n                                sourcemeta::core::empty_weak_pointer)};\n\n  // `then`\n  std::size_t then_cursor{children.size()};\n  if (schema_context.schema.defines(\"then\")) {\n    const auto destination{\n        to_uri(schema_context.relative_pointer.initial().concat(\n                   make_weak_pointer(KEYWORD_THEN)),\n               schema_context.base)\n            .recompose()};\n    assert(context.frame.locations().contains(\n        {sourcemeta::core::SchemaReferenceType::Static, destination}));\n    DynamicContext new_dynamic_context{\n        .keyword = KEYWORD_THEN,\n        .base_schema_location = dynamic_context.base_schema_location,\n        .base_instance_location = sourcemeta::core::empty_weak_pointer};\n    for (auto &&step :\n         compile(context, schema_context, new_dynamic_context,\n                 sourcemeta::core::empty_weak_pointer,\n                 sourcemeta::core::empty_weak_pointer, destination)) {\n      children.push_back(std::move(step));\n    }\n\n    // In this case, `if` did nothing, so we can short-circuit\n    if (then_cursor == 0) {\n      return children;\n    }\n  }\n\n  // `else`\n  std::size_t else_cursor{0};\n  if (schema_context.schema.defines(\"else\")) {\n    else_cursor = children.size();\n    const auto destination{\n        to_uri(schema_context.relative_pointer.initial().concat(\n                   make_weak_pointer(KEYWORD_ELSE)),\n               schema_context.base)\n            .recompose()};\n    assert(context.frame.locations().contains(\n        {sourcemeta::core::SchemaReferenceType::Static, destination}));\n    DynamicContext new_dynamic_context{\n        .keyword = KEYWORD_ELSE,\n        .base_schema_location = dynamic_context.base_schema_location,\n        .base_instance_location = sourcemeta::core::empty_weak_pointer};\n    for (auto &&step :\n         compile(context, schema_context, new_dynamic_context,\n                 sourcemeta::core::empty_weak_pointer,\n                 sourcemeta::core::empty_weak_pointer, destination)) {\n      children.push_back(std::move(step));\n    }\n  }\n\n  return {make(sourcemeta::blaze::InstructionIndex::LogicalCondition, context,\n               schema_context, dynamic_context,\n               ValueIndexPair{then_cursor, else_cursor}, std::move(children))};\n}\n\n// We handle `then` as part of `if`\n// TODO: Stop collapsing this keyword on exhaustive mode for debuggability\n// purposes\nauto compiler_draft7_applicator_then(const Context &, const SchemaContext &,\n                                     const DynamicContext &,\n                                     const Instructions &) -> Instructions {\n  return {};\n}\n\n// We handle `else` as part of `if`\n// TODO: Stop collapsing this keyword on exhaustive mode for debuggability\n// purposes\nauto compiler_draft7_applicator_else(const Context &, const SchemaContext &,\n                                     const DynamicContext &,\n                                     const Instructions &) -> Instructions {\n  return {};\n}\n\n} // namespace internal\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/default_compiler_openapi.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_OPENAPI_H_\n#define SOURCEMETA_BLAZE_COMPILER_DEFAULT_COMPILER_OPENAPI_H_\n\n#include <sourcemeta/blaze/compiler.h>\n\nnamespace internal {\nusing namespace sourcemeta::blaze;\n\nauto compiler_openapi_noop(const Context &, const SchemaContext &,\n                           const DynamicContext &, const Instructions &)\n    -> Instructions {\n  return {};\n}\n\n} // namespace internal\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/include/sourcemeta/blaze/compiler.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_COMPILE_H_\n#define SOURCEMETA_BLAZE_COMPILER_COMPILE_H_\n\n#ifndef SOURCEMETA_BLAZE_COMPILER_EXPORT\n#include <sourcemeta/blaze/compiler_export.h>\n#endif\n\n#include <sourcemeta/blaze/compiler_error.h>\n#include <sourcemeta/blaze/compiler_unevaluated.h>\n\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n#include <sourcemeta/core/uri.h>\n\n#include <cstddef>       // std::size_t\n#include <cstdint>       // std::uint8_t\n#include <functional>    // std::function\n#include <map>           // std::map\n#include <optional>      // std::optional, std::nullopt\n#include <string>        // std::string\n#include <string_view>   // std::string_view\n#include <tuple>         // std::tuple\n#include <unordered_map> // std::unordered_map\n#include <vector>        // std::vector\n\n/// @defgroup compiler Compiler\n/// @brief Compile a JSON Schema into a set of low-level instructions for fast\n/// evaluation\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup compiler\n/// The schema compiler context is the current subschema information you have at\n/// your disposal to implement a keyword\nstruct SchemaContext {\n  // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)\n  /// The schema location relative to the base URI\n  const sourcemeta::core::WeakPointer &relative_pointer;\n  /// The current subschema\n  const sourcemeta::core::JSON &schema;\n  /// The schema vocabularies in use\n  const sourcemeta::core::Vocabularies &vocabularies;\n  /// The schema base URI\n  const sourcemeta::core::URI &base;\n  // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)\n  /// Whether the current schema targets a property name\n  bool is_property_name;\n};\n\n/// @ingroup compiler\n/// The dynamic compiler context is the read-write information you have at your\n/// disposal to implement a keyword\nstruct DynamicContext {\n  // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)\n  /// The schema keyword\n  const sourcemeta::core::JSON::String &keyword;\n  /// The schema base keyword path\n  const sourcemeta::core::WeakPointer &base_schema_location;\n  /// The base instance location that the keyword must be evaluated to\n  const sourcemeta::core::WeakPointer &base_instance_location;\n  // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)\n};\n\n#if !defined(DOXYGEN)\nstruct Context;\n#endif\n\n/// @ingroup compiler\n/// A compiler is represented as a function that maps a keyword compiler\n/// contexts into a compiler template. You can provide your own to implement\n/// your own keywords\nusing Compiler =\n    // TODO(C++23): Use std::move_only_function when available in libc++\n    std::function<Instructions(const Context &, const SchemaContext &,\n                               const DynamicContext &, const Instructions &)>;\n\n/// @ingroup evaluator\n/// Represents the mode of compilation\nenum class Mode : std::uint8_t {\n  /// Attempt to get to a boolean result as fast as possible\n  FastValidation,\n  /// Perform exhaustive evaluation, including annotations\n  Exhaustive\n};\n\n/// @ingroup compiler\n/// Advanced knobs that you can tweak for higher control and optimisations\nstruct Tweaks {\n  /// Always unroll `properties` in a logical AND operation\n  bool properties_always_unroll{false};\n  /// Attempt to re-order `properties` subschemas to evaluate cheaper ones first\n  bool properties_reorder{true};\n  /// Inline jump targets with fewer instructions than this threshold\n  std::size_t target_inline_threshold{50};\n};\n\n/// @ingroup compiler\n/// The static compiler context is the information you have at your\n/// disposal to implement a keyword that will never change throughout\n/// the compilation process\nstruct Context {\n  // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)\n  /// The root schema resource\n  const sourcemeta::core::JSON &root;\n  /// The reference frame of the entire schema\n  const sourcemeta::core::SchemaFrame &frame;\n  /// The set of all schema resources in the schema without duplicates\n  const std::vector<std::string> resources;\n  /// The schema walker in use\n  const sourcemeta::core::SchemaWalker &walker;\n  /// The schema resolver in use\n  const sourcemeta::core::SchemaResolver &resolver;\n  /// The schema compiler in use\n  const Compiler &compiler;\n  /// The mode of the schema compiler\n  const Mode mode;\n  /// Whether the schema makes use of dynamic scoping\n  const bool uses_dynamic_scopes;\n  /// The list of unevaluated entries and their dependencies\n  const SchemaUnevaluatedEntries unevaluated;\n  /// The set of tweaks for the compiler\n  const Tweaks tweaks;\n  /// All possible reference targets (key includes is_property_name context)\n  const std::map<\n      std::tuple<sourcemeta::core::SchemaReferenceType, std::string_view, bool>,\n      std::pair<std::size_t, const sourcemeta::core::WeakPointer *>>\n      targets;\n  /// Accumulator for instruction extra data during compilation\n  std::vector<InstructionExtra> &extra;\n  // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)\n};\n\n/// @ingroup compiler\n/// A default compiler that aims to implement every keyword for official JSON\n/// Schema dialects.\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT default_schema_compiler(\n    const Context &, const SchemaContext &, const DynamicContext &,\n    const Instructions &) -> Instructions;\n\n/// @ingroup compiler\n///\n/// This function compiles an input JSON Schema into a template that can be\n/// later evaluated. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/compiler.h>\n///\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// const sourcemeta::core::JSON schema =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\");\n///\n/// const auto schema_template{sourcemeta::blaze::compile(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver,\n///     sourcemeta::core::default_schema_compiler)};\n///\n/// // Evaluate or encode\n/// ```\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT\ncompile(const sourcemeta::core::JSON &schema,\n        const sourcemeta::core::SchemaWalker &walker,\n        const sourcemeta::core::SchemaResolver &resolver,\n        const Compiler &compiler, const Mode mode = Mode::FastValidation,\n        const std::string_view default_dialect = \"\",\n        const std::string_view default_id = \"\",\n        const std::string_view entrypoint = \"\",\n        const std::optional<Tweaks> &tweaks = std::nullopt) -> Template;\n\n/// @ingroup compiler\n///\n/// This function compiles an input JSON Schema into a template that can be\n/// later evaluated, but given an existing schema frame. The schema frame must\n/// contain reference information for the given schema and the input schema must\n/// be bundled. If those pre-conditions are not met, you will hit undefined\n/// behavior.\n///\n/// Don't use this function unless you know what you are doing.\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT compile(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver, const Compiler &compiler,\n    const sourcemeta::core::SchemaFrame &frame,\n    const std::string_view entrypoint, const Mode mode = Mode::FastValidation,\n    const std::optional<Tweaks> &tweaks = std::nullopt) -> Template;\n\n/// @ingroup compiler\n///\n/// This function compiles a single subschema into a compiler template as\n/// determined by the given pointer. If a URI is given, the compiler will\n/// attempt to jump to that corresponding frame entry. Otherwise, it will\n/// navigate within the current keyword. This function is not meant to be used\n/// directly, but instead as a building block for supporting applicators on\n/// compiler functions.\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT\ncompile(const Context &context, const SchemaContext &schema_context,\n        const DynamicContext &dynamic_context,\n        const sourcemeta::core::WeakPointer &schema_suffix,\n        const sourcemeta::core::WeakPointer &instance_suffix =\n            sourcemeta::core::empty_weak_pointer,\n        std::optional<std::string_view> uri = std::nullopt) -> Instructions;\n\n/// @ingroup compiler\n/// Serialise a template as JSON\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT to_json(const Template &schema_template)\n    -> sourcemeta::core::JSON;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/include/sourcemeta/blaze/compiler_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_ERROR_H\n#define SOURCEMETA_BLAZE_COMPILER_ERROR_H\n\n#ifndef SOURCEMETA_BLAZE_COMPILER_EXPORT\n#include <sourcemeta/blaze/compiler_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/uri.h>\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup jsonschema\n/// An error that represents a schema compilation failure event\nclass SOURCEMETA_BLAZE_COMPILER_EXPORT CompilerError : public std::exception {\npublic:\n  CompilerError(sourcemeta::core::URI base,\n                sourcemeta::core::Pointer schema_location, const char *message)\n      : base_{std::move(base)}, schema_location_{std::move(schema_location)},\n        message_{message} {}\n  CompilerError(sourcemeta::core::URI base,\n                sourcemeta::core::Pointer schema_location,\n                std::string message) = delete;\n  CompilerError(sourcemeta::core::URI base,\n                sourcemeta::core::Pointer schema_location,\n                std::string &&message) = delete;\n  CompilerError(sourcemeta::core::URI base,\n                sourcemeta::core::Pointer schema_location,\n                std::string_view message) = delete;\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto base() const noexcept -> const sourcemeta::core::URI & {\n    return this->base_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->schema_location_;\n  }\n\nprivate:\n  sourcemeta::core::URI base_;\n  sourcemeta::core::Pointer schema_location_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents an invalid regular expression during compilation\nclass SOURCEMETA_BLAZE_COMPILER_EXPORT CompilerInvalidRegexError\n    : public std::exception {\npublic:\n  CompilerInvalidRegexError(sourcemeta::core::URI base,\n                            sourcemeta::core::Pointer schema_location,\n                            std::string regex)\n      : base_{std::move(base)}, schema_location_{std::move(schema_location)},\n        regex_{std::move(regex)} {}\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Invalid regular expression\";\n  }\n\n  [[nodiscard]] auto base() const noexcept -> const sourcemeta::core::URI & {\n    return this->base_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->schema_location_;\n  }\n\n  [[nodiscard]] auto regex() const noexcept -> const std::string & {\n    return this->regex_;\n  }\n\nprivate:\n  sourcemeta::core::URI base_;\n  sourcemeta::core::Pointer schema_location_;\n  std::string regex_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a reference target that is not a valid schema\nclass SOURCEMETA_BLAZE_COMPILER_EXPORT CompilerReferenceTargetNotSchemaError\n    : public std::exception {\npublic:\n  CompilerReferenceTargetNotSchemaError(\n      const std::string_view identifier,\n      sourcemeta::core::Pointer schema_location)\n      : identifier_{identifier}, schema_location_{std::move(schema_location)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The referenced schema is not considered to be a valid subschema \"\n           \"given the dialect and vocabularies in use\";\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> const std::string & {\n    return this->identifier_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->schema_location_;\n  }\n\nprivate:\n  std::string identifier_;\n  sourcemeta::core::Pointer schema_location_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents an invalid compilation entrypoint\nclass SOURCEMETA_BLAZE_COMPILER_EXPORT CompilerInvalidEntryPoint\n    : public std::exception {\npublic:\n  CompilerInvalidEntryPoint(const std::string_view entrypoint,\n                            const char *message)\n      : identifier_{entrypoint}, message_{message} {}\n  CompilerInvalidEntryPoint(const std::string_view entrypoint,\n                            std::string message) = delete;\n  CompilerInvalidEntryPoint(const std::string_view entrypoint,\n                            std::string &&message) = delete;\n  CompilerInvalidEntryPoint(const std::string_view entrypoint,\n                            std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> const std::string & {\n    return this->identifier_;\n  }\n\nprivate:\n  std::string identifier_;\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/include/sourcemeta/blaze/compiler_unevaluated.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_UNEVALUATED_H\n#define SOURCEMETA_BLAZE_COMPILER_UNEVALUATED_H\n\n#ifndef SOURCEMETA_BLAZE_COMPILER_EXPORT\n#include <sourcemeta/blaze/compiler_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <map> // std::map\n#include <set> // std::set\n\n// TODO: Eventually this file should dissapear and move this analysis as part of\n// framing\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup compiler\nstruct SchemaUnevaluatedEntry {\n  /// The absolute pointers of the static keyword dependencies\n  std::set<sourcemeta::core::WeakPointer> static_dependencies;\n  /// The absolute pointers of the static keyword dependencies\n  std::set<sourcemeta::core::WeakPointer> dynamic_dependencies;\n  /// Whether the entry cannot be fully resolved, which means\n  /// there might be unknown dynamic dependencies\n  bool unresolved{false};\n};\n\n/// @ingroup compiler\n/// The flattened set of unevaluated cases in the schema by absolute URI\nusing SchemaUnevaluatedEntries =\n    std::map<sourcemeta::core::JSON::String, SchemaUnevaluatedEntry>;\n\n/// @ingroup compiler\n///\n/// This function performs a static analysis pass on `unevaluatedProperties` and\n/// `unevaluatedItems` occurences throughout the entire schema (if any).\n/// ```\nauto SOURCEMETA_BLAZE_COMPILER_EXPORT\nunevaluated(const sourcemeta::core::JSON &schema,\n            const sourcemeta::core::SchemaFrame &frame,\n            const sourcemeta::core::SchemaWalker &walker,\n            const sourcemeta::core::SchemaResolver &resolver)\n    -> SchemaUnevaluatedEntries;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/postprocess.h",
    "content": "#ifndef SOURCEMETA_BLAZE_COMPILER_POSTPROCESS_H\n#define SOURCEMETA_BLAZE_COMPILER_POSTPROCESS_H\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <algorithm>\n#include <cstddef>\n#include <string> // std::string\n#include <unordered_map>\n#include <unordered_set> // std::unordered_set\n#include <vector>\n\n// TODO: Move all `FastValidation` conditional optimisations from the default\n// compilers here. Only the structural ones from Draft 4 seem to be missing\n\nnamespace sourcemeta::blaze {\n\nstruct TargetStatistics {\n  std::size_t count;\n  std::unordered_map<std::size_t, std::size_t> jump_targets;\n  bool requires_empty_instance_location;\n};\n\ninline auto is_noop_without_children(const InstructionIndex type) noexcept\n    -> bool {\n  switch (type) {\n    case InstructionIndex::LogicalAnd:\n    case InstructionIndex::LogicalCondition:\n    case InstructionIndex::LogicalWhenType:\n    case InstructionIndex::LogicalWhenDefines:\n    case InstructionIndex::LogicalWhenArraySizeGreater:\n    case InstructionIndex::LoopPropertiesMatch:\n    case InstructionIndex::LoopProperties:\n    case InstructionIndex::LoopPropertiesEvaluate:\n    case InstructionIndex::LoopPropertiesRegex:\n    case InstructionIndex::LoopPropertiesStartsWith:\n    case InstructionIndex::LoopPropertiesExcept:\n    case InstructionIndex::LoopKeys:\n    case InstructionIndex::LoopItems:\n    case InstructionIndex::LoopItemsFrom:\n    case InstructionIndex::LoopItemsUnevaluated:\n    case InstructionIndex::LoopContains:\n    case InstructionIndex::ControlGroupWhenDefines:\n    case InstructionIndex::ControlGroupWhenDefinesDirect:\n    case InstructionIndex::ControlGroupWhenType:\n      return true;\n    default:\n      return false;\n  }\n}\n\ninline auto\nis_parent_to_children_instruction(const InstructionIndex type) noexcept\n    -> bool {\n  switch (type) {\n    case InstructionIndex::LoopPropertiesMatch:\n    case InstructionIndex::LoopPropertiesMatchClosed:\n    case InstructionIndex::ControlGroupWhenDefines:\n    case InstructionIndex::ControlGroupWhenDefinesDirect:\n      return true;\n    default:\n      return false;\n  }\n}\n\ninline auto convert_to_property_type_assertions(Instructions &instructions)\n    -> void {\n  for (auto &instruction : instructions) {\n    if (!instruction.relative_instance_location.empty()) {\n      switch (instruction.type) {\n        case InstructionIndex::AssertionTypeStrict:\n          instruction.type = InstructionIndex::AssertionPropertyTypeStrict;\n          break;\n        case InstructionIndex::AssertionType:\n          instruction.type = InstructionIndex::AssertionPropertyType;\n          break;\n        case InstructionIndex::AssertionTypeStrictAny:\n          instruction.type = InstructionIndex::AssertionPropertyTypeStrictAny;\n          break;\n        default:\n          break;\n      }\n    }\n\n    if (!is_parent_to_children_instruction(instruction.type)) {\n      convert_to_property_type_assertions(instruction.children);\n    }\n  }\n}\n\ninline auto duplicate_metadata(Instruction &instruction,\n                               std::vector<InstructionExtra> &extra) -> void {\n  const auto new_index{extra.size()};\n  auto source_extra{extra[instruction.extra_index]};\n  extra.push_back(std::move(source_extra));\n  instruction.extra_index = new_index;\n  for (auto &child : instruction.children) {\n    duplicate_metadata(child, extra);\n  }\n}\n\ninline auto rebase(Instruction &instruction,\n                   std::vector<InstructionExtra> &extra,\n                   const sourcemeta::core::Pointer &schema_prefix,\n                   const sourcemeta::core::Pointer &instance_prefix) -> void {\n  extra[instruction.extra_index].relative_schema_location =\n      schema_prefix.concat(\n          extra[instruction.extra_index].relative_schema_location);\n  instruction.relative_instance_location =\n      instance_prefix.concat(instruction.relative_instance_location);\n\n  if (instruction.type == InstructionIndex::LogicalCondition) {\n    const auto &value{std::get<ValueIndexPair>(instruction.value)};\n    const auto then_cursor{value.first};\n    // TODO(C++23): Use std::views::enumerate when available in libc++\n    for (std::size_t index = then_cursor; index < instruction.children.size();\n         ++index) {\n      auto &child{instruction.children[index]};\n      extra[child.extra_index].relative_schema_location = schema_prefix.concat(\n          extra[child.extra_index].relative_schema_location);\n      for (auto &grandchild : child.children) {\n        extra[grandchild.extra_index].relative_schema_location =\n            schema_prefix.concat(\n                extra[grandchild.extra_index].relative_schema_location);\n      }\n    }\n  }\n}\n\ninline auto collect_statistics(const Instructions &instructions,\n                               TargetStatistics &statistics) -> void {\n  for (const auto &instruction : instructions) {\n    statistics.count += 1;\n\n    if (instruction.type == InstructionIndex::ControlJump) {\n      statistics\n          .jump_targets[std::get<ValueUnsignedInteger>(instruction.value)]++;\n    }\n\n    if (instruction.type == InstructionIndex::ControlGroupWhenDefinesDirect ||\n        instruction.type == InstructionIndex::ControlGroupWhenType) {\n      statistics.requires_empty_instance_location = true;\n    }\n\n    collect_statistics(instruction.children, statistics);\n  }\n}\n\ninline auto\ntransform_instruction(Instruction &instruction, Instructions &output,\n                      std::vector<InstructionExtra> &extra,\n                      const std::vector<Instructions> &targets,\n                      const std::vector<TargetStatistics> &statistics,\n                      TargetStatistics &current_stats, const Tweaks &tweaks,\n                      const bool uses_dynamic_scopes) -> bool {\n  if (instruction.type == InstructionIndex::ControlJump) {\n    const auto jump_target_index{\n        std::get<ValueUnsignedInteger>(instruction.value)};\n    const auto &jump_target_stats{statistics[jump_target_index]};\n\n    if (jump_target_stats.count == 0) {\n      current_stats.jump_targets[jump_target_index]--;\n      return true;\n    }\n\n    const auto jump_target_self_loop{\n        jump_target_stats.jump_targets.find(jump_target_index)};\n    if (jump_target_stats.count < tweaks.target_inline_threshold &&\n        (jump_target_self_loop == jump_target_stats.jump_targets.end() ||\n         jump_target_self_loop->second == 0) &&\n        !uses_dynamic_scopes &&\n        (!jump_target_stats.requires_empty_instance_location ||\n         instruction.relative_instance_location.empty())) {\n      current_stats.jump_targets[jump_target_index]--;\n      for (const auto &[inlined_jump, inlined_count] :\n           jump_target_stats.jump_targets) {\n        current_stats.jump_targets[inlined_jump] += inlined_count;\n      }\n      current_stats.requires_empty_instance_location |=\n          jump_target_stats.requires_empty_instance_location;\n\n      const auto schema_prefix{\n          extra[instruction.extra_index].relative_schema_location};\n      for (auto target_instruction : targets[jump_target_index]) {\n        duplicate_metadata(target_instruction, extra);\n        rebase(target_instruction, extra, schema_prefix,\n               instruction.relative_instance_location);\n        output.push_back(std::move(target_instruction));\n      }\n      return true;\n    }\n  }\n\n  if (is_noop_without_children(instruction.type) &&\n      instruction.children.empty()) {\n    return true;\n  }\n\n  // TODO: De-duplicate this logic from default_compiler_draft4.h. Just do it\n  // all here\n\n  if (instruction.type == InstructionIndex::LoopProperties &&\n      instruction.children.size() == 1) {\n    auto &child{instruction.children.front()};\n    if (child.type == InstructionIndex::AssertionTypeStrict) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(\n          Instruction{.type = InstructionIndex::LoopPropertiesTypeStrict,\n                      .relative_instance_location =\n                          std::move(instruction.relative_instance_location),\n                      .value = std::move(child.value),\n                      .children = {},\n                      .extra_index = new_extra_index});\n      return true;\n    }\n\n    if (child.type == InstructionIndex::AssertionType) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(Instruction{.type = InstructionIndex::LoopPropertiesType,\n                                   .relative_instance_location = std::move(\n                                       instruction.relative_instance_location),\n                                   .value = std::move(child.value),\n                                   .children = {},\n                                   .extra_index = new_extra_index});\n      return true;\n    }\n\n    if (child.type == InstructionIndex::AssertionTypeStrictAny) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(\n          Instruction{.type = InstructionIndex::LoopPropertiesTypeStrictAny,\n                      .relative_instance_location =\n                          std::move(instruction.relative_instance_location),\n                      .value = std::move(child.value),\n                      .children = {},\n                      .extra_index = new_extra_index});\n      return true;\n    }\n  }\n\n  if (instruction.type == InstructionIndex::LoopPropertiesEvaluate &&\n      instruction.children.size() == 1) {\n    auto &child{instruction.children.front()};\n    if (child.type == InstructionIndex::AssertionTypeStrict) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(Instruction{\n          .type = InstructionIndex::LoopPropertiesTypeStrictEvaluate,\n          .relative_instance_location =\n              std::move(instruction.relative_instance_location),\n          .value = std::move(child.value),\n          .children = {},\n          .extra_index = new_extra_index});\n      return true;\n    }\n\n    if (child.type == InstructionIndex::AssertionType) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(\n          Instruction{.type = InstructionIndex::LoopPropertiesTypeEvaluate,\n                      .relative_instance_location =\n                          std::move(instruction.relative_instance_location),\n                      .value = std::move(child.value),\n                      .children = {},\n                      .extra_index = new_extra_index});\n      return true;\n    }\n\n    if (child.type == InstructionIndex::AssertionTypeStrictAny) {\n      const auto new_extra_index{extra.size()};\n      auto &instruction_meta{extra[instruction.extra_index]};\n      auto &child_meta{extra[child.extra_index]};\n      extra.push_back(\n          {.relative_schema_location =\n               instruction_meta.relative_schema_location.concat(\n                   child_meta.relative_schema_location),\n           .keyword_location = std::move(child_meta.keyword_location),\n           .schema_resource = child_meta.schema_resource});\n      output.push_back(Instruction{\n          .type = InstructionIndex::LoopPropertiesTypeStrictAnyEvaluate,\n          .relative_instance_location =\n              std::move(instruction.relative_instance_location),\n          .value = std::move(child.value),\n          .children = {},\n          .extra_index = new_extra_index});\n      return true;\n    }\n  }\n\n  if (is_parent_to_children_instruction(instruction.type)) {\n    convert_to_property_type_assertions(instruction.children);\n  }\n\n  if (!instruction.relative_instance_location.empty() &&\n      std::ranges::all_of(\n          instruction.relative_instance_location,\n          [](const auto &token) { return token.is_property(); })) {\n    switch (instruction.type) {\n      case InstructionIndex::AssertionTypeStrict:\n        instruction.type = InstructionIndex::AssertionPropertyTypeStrict;\n        break;\n      case InstructionIndex::AssertionType:\n        instruction.type = InstructionIndex::AssertionPropertyType;\n        break;\n      case InstructionIndex::AssertionTypeStrictAny:\n        instruction.type = InstructionIndex::AssertionPropertyTypeStrictAny;\n        break;\n      default:\n        break;\n    }\n  }\n\n  output.push_back(std::move(instruction));\n  return false;\n}\n\ninline auto postprocess(std::vector<Instructions> &targets,\n                        std::vector<InstructionExtra> &extra,\n                        const Tweaks &tweaks, const bool uses_dynamic_scopes)\n    -> void {\n  std::vector<TargetStatistics> statistics;\n  statistics.reserve(targets.size());\n  for (const auto &target : targets) {\n    TargetStatistics entry{.count = 0,\n                           .jump_targets = {},\n                           .requires_empty_instance_location = false};\n    collect_statistics(target, entry);\n    statistics.push_back(std::move(entry));\n  }\n\n  bool changed{true};\n  while (changed) {\n    changed = false;\n\n    for (std::size_t current_target_index = 0;\n         current_target_index < targets.size(); ++current_target_index) {\n      auto &target{targets[current_target_index]};\n      auto &current_stats{statistics[current_target_index]};\n\n      std::vector<Instructions *> worklist;\n      std::vector<std::pair<Instructions *, std::size_t>> stack;\n      stack.emplace_back(&target, 0);\n\n      while (!stack.empty()) {\n        auto current{stack.back().first};\n        auto index{stack.back().second};\n        stack.pop_back();\n\n        while (index < current->size() && (*current)[index].children.empty()) {\n          ++index;\n        }\n\n        if (index < current->size()) {\n          stack.emplace_back(current, index + 1);\n          stack.emplace_back(&(*current)[index].children, 0);\n        } else {\n          worklist.push_back(current);\n        }\n      }\n\n      for (auto *current : worklist) {\n        Instructions result;\n        result.reserve(current->size());\n\n        std::unordered_set<std::string> fusion_covered_properties;\n        for (const auto &instruction : *current) {\n          if (instruction.type ==\n              InstructionIndex::AssertionObjectPropertiesSimple) {\n            const auto &entries{\n                std::get<ValueObjectProperties>(instruction.value)};\n            for (const auto &entry : entries) {\n              fusion_covered_properties.insert(std::get<0>(entry));\n            }\n          }\n        }\n\n        for (auto &instruction : *current) {\n          if (!fusion_covered_properties.empty()) {\n            switch (instruction.type) {\n              case InstructionIndex::AssertionDefinesAllStrict:\n              case InstructionIndex::AssertionDefinesAll: {\n                const auto &value{std::get<ValueStringSet>(instruction.value)};\n                bool all_covered{true};\n                for (const auto &property : value) {\n                  if (!fusion_covered_properties.contains(property.first)) {\n                    all_covered = false;\n                    break;\n                  }\n                }\n                if (all_covered) {\n                  changed = true;\n                  continue;\n                }\n                break;\n              }\n              case InstructionIndex::AssertionDefinesStrict:\n              case InstructionIndex::AssertionDefines: {\n                const auto &value{std::get<ValueProperty>(instruction.value)};\n                if (fusion_covered_properties.contains(value.first)) {\n                  changed = true;\n                  continue;\n                }\n                break;\n              }\n              case InstructionIndex::AssertionTypeStrict:\n              case InstructionIndex::AssertionType:\n                if (std::get<ValueType>(instruction.value) ==\n                    sourcemeta::core::JSON::Type::Object) {\n                  changed = true;\n                  continue;\n                }\n                break;\n              default:\n                break;\n            }\n          }\n\n          if (transform_instruction(instruction, result, extra, targets,\n                                    statistics, current_stats, tweaks,\n                                    uses_dynamic_scopes))\n            changed = true;\n        }\n\n        *current = std::move(result);\n      }\n    }\n  }\n}\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/compiler/unevaluated.cc",
    "content": "#include <sourcemeta/blaze/compiler.h>\n\n#include \"compile_helpers.h\"\n\nnamespace {\nusing namespace sourcemeta::core;\nusing namespace sourcemeta::blaze;\nusing Known = Vocabularies::Known;\n\nstatic const std::string UNEVALUATED_PROPERTIES{\"unevaluatedProperties\"};\nstatic const std::string UNEVALUATED_ITEMS{\"unevaluatedItems\"};\n\nauto find_adjacent_dependencies(\n    const JSON::String &current, const JSON &schema, const SchemaFrame &frame,\n    const SchemaWalker &walker, const SchemaResolver &resolver,\n    const std::set<JSON::String> &keywords, const SchemaFrame::Location &root,\n    const SchemaFrame::Location &entry, const bool is_static,\n    sourcemeta::blaze::SchemaUnevaluatedEntry &result) -> void {\n  const auto &subschema{get(schema, entry.pointer)};\n  if (!subschema.is_object()) {\n    return;\n  }\n\n  const auto subschema_vocabularies{\n      vocabularies(subschema, resolver, entry.dialect)};\n\n  for (const auto &property : subschema.as_object()) {\n    if (property.first == current && entry.pointer == root.pointer) {\n      continue;\n    } else if (keywords.contains(property.first)) {\n      // In 2019-09, `additionalItems` takes no effect without `items`\n      if (subschema_vocabularies.contains(\n              Known::JSON_Schema_2019_09_Applicator) &&\n          property.first == \"additionalItems\" && !subschema.defines(\"items\")) {\n        continue;\n      }\n\n      auto pointer{entry.pointer.concat(make_weak_pointer(property.first))};\n      if (is_static) {\n        result.static_dependencies.emplace(std::move(pointer));\n      } else {\n        result.dynamic_dependencies.emplace(std::move(pointer));\n      }\n\n      continue;\n    }\n\n    switch (walker(property.first, subschema_vocabularies).type) {\n      // References\n      case SchemaKeywordType::Reference: {\n        const auto reference{\n            frame.dereference(entry, make_weak_pointer(property.first))};\n        if (reference.first == SchemaReferenceType::Static &&\n            reference.second.has_value()) {\n          find_adjacent_dependencies(\n              current, schema, frame, walker, resolver, keywords, root,\n              reference.second.value().get(), is_static, result);\n        } else if (reference.first == SchemaReferenceType::Dynamic) {\n          result.unresolved = true;\n        }\n\n        break;\n      }\n\n      // Static\n      case SchemaKeywordType::ApplicatorElementsInPlace:\n        // TODO(C++23): Use std::views::enumerate when available in libc++\n        for (std::size_t index = 0; index < property.second.size(); index++) {\n          find_adjacent_dependencies(\n              current, schema, frame, walker, resolver, keywords, root,\n              frame.traverse(entry, make_weak_pointer(property.first, index)),\n              is_static, result);\n        }\n\n        break;\n\n      // Dynamic\n      case SchemaKeywordType::ApplicatorElementsInPlaceSome:\n        if (property.second.is_array()) {\n          for (std::size_t index = 0; index < property.second.size(); index++) {\n            find_adjacent_dependencies(\n                current, schema, frame, walker, resolver, keywords, root,\n                frame.traverse(entry, make_weak_pointer(property.first, index)),\n                false, result);\n          }\n        }\n\n        break;\n      case SchemaKeywordType::ApplicatorValueTraverseAnyItem:\n        [[fallthrough]];\n      case SchemaKeywordType::ApplicatorValueTraverseParent:\n        [[fallthrough]];\n      case SchemaKeywordType::ApplicatorValueInPlaceMaybe:\n        if (is_schema(property.second)) {\n          find_adjacent_dependencies(\n              current, schema, frame, walker, resolver, keywords, root,\n              frame.traverse(entry, make_weak_pointer(property.first)), false,\n              result);\n        }\n\n        break;\n      case SchemaKeywordType::ApplicatorValueOrElementsInPlace:\n        if (property.second.is_array()) {\n          for (std::size_t index = 0; index < property.second.size(); index++) {\n            find_adjacent_dependencies(\n                current, schema, frame, walker, resolver, keywords, root,\n                frame.traverse(entry, make_weak_pointer(property.first, index)),\n                false, result);\n          }\n        } else if (is_schema(property.second)) {\n          find_adjacent_dependencies(\n              current, schema, frame, walker, resolver, keywords, root,\n              frame.traverse(entry, make_weak_pointer(property.first)), false,\n              result);\n        }\n\n        break;\n      case SchemaKeywordType::ApplicatorMembersInPlaceSome:\n        if (property.second.is_object()) {\n          for (const auto &pair : property.second.as_object()) {\n            find_adjacent_dependencies(\n                current, schema, frame, walker, resolver, keywords, root,\n                frame.traverse(entry,\n                               make_weak_pointer(property.first, pair.first)),\n                false, result);\n          }\n        }\n\n        break;\n\n      // Anything else does not contribute to the dependency list\n      default:\n        break;\n    }\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\n// TODO: Refactor this entire function using `SchemaFrame`'s new `Instances`\n// mode. We can loop over every subschema that defines `unevaluatedProperties`\n// or `unevaluatedItems`, find all other subschemas with the same unresolved\n// instance location (static dependency) or conditional equivalent unresolved\n// instance location (dynamic dependency) and see if those ones define any of\n// the dependent keywords.\nauto unevaluated(const JSON &schema, const SchemaFrame &frame,\n                 const SchemaWalker &walker, const SchemaResolver &resolver)\n    -> SchemaUnevaluatedEntries {\n  SchemaUnevaluatedEntries result;\n\n  for (const auto &entry : frame.locations()) {\n    if (entry.second.type != SchemaFrame::LocationType::Subschema &&\n        entry.second.type != SchemaFrame::LocationType::Resource) {\n      continue;\n    }\n\n    const auto &subschema{get(schema, entry.second.pointer)};\n    assert(is_schema(subschema));\n    if (!subschema.is_object()) {\n      continue;\n    }\n\n    const bool has_unevaluated_properties{\n        subschema.defines(\"unevaluatedProperties\")};\n    const bool has_unevaluated_items{subschema.defines(\"unevaluatedItems\")};\n    if (!has_unevaluated_properties && !has_unevaluated_items) {\n      continue;\n    }\n\n    const auto subschema_vocabularies{\n        frame.vocabularies(entry.second, resolver)};\n\n    if (has_unevaluated_properties) {\n      if ((subschema_vocabularies.contains(\n               Known::JSON_Schema_2020_12_Unevaluated) &&\n           subschema_vocabularies.contains(\n               Known::JSON_Schema_2020_12_Applicator)) ||\n          subschema_vocabularies.contains(\n              Known::JSON_Schema_2019_09_Applicator)) {\n        SchemaUnevaluatedEntry unevaluated;\n        find_adjacent_dependencies(\n            \"unevaluatedProperties\", schema, frame, walker, resolver,\n            {\"properties\", \"patternProperties\", \"additionalProperties\",\n             \"unevaluatedProperties\"},\n            entry.second, entry.second, true, unevaluated);\n        result.emplace(\n            frame.uri(entry.second, make_weak_pointer(UNEVALUATED_PROPERTIES)),\n            std::move(unevaluated));\n      }\n    }\n\n    if (has_unevaluated_items) {\n      SchemaUnevaluatedEntry unevaluated;\n      if (subschema_vocabularies.contains(\n              Known::JSON_Schema_2020_12_Unevaluated) &&\n          subschema_vocabularies.contains(\n              Known::JSON_Schema_2020_12_Applicator)) {\n        find_adjacent_dependencies(\n            \"unevaluatedItems\", schema, frame, walker, resolver,\n            {\"prefixItems\", \"items\", \"contains\", \"unevaluatedItems\"},\n            entry.second, entry.second, true, unevaluated);\n        result.emplace(\n            frame.uri(entry.second, make_weak_pointer(UNEVALUATED_ITEMS)),\n            std::move(unevaluated));\n      } else if (subschema_vocabularies.contains(\n                     Known::JSON_Schema_2019_09_Applicator)) {\n        find_adjacent_dependencies(\n            \"unevaluatedItems\", schema, frame, walker, resolver,\n            {\"items\", \"additionalItems\", \"unevaluatedItems\"}, entry.second,\n            entry.second, true, unevaluated);\n        result.emplace(\n            frame.uri(entry.second, make_weak_pointer(UNEVALUATED_ITEMS)),\n            std::move(unevaluated));\n      }\n    }\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/configuration/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME configuration\n  PRIVATE_HEADERS error.h SOURCES parse.cc json.cc configuration.cc lock.cc fetch.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME configuration)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_configuration PUBLIC sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_configuration PUBLIC sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::uri)\ntarget_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::io)\ntarget_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::crypto)\ntarget_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::jsonschema)\n"
  },
  {
    "path": "vendor/blaze/src/configuration/configuration.cc",
    "content": "#include <sourcemeta/blaze/configuration.h>\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <algorithm>    // std::ranges::any_of\n#include <cassert>      // assert\n#include <string>       // std::string\n#include <system_error> // std::error_code\n\nnamespace sourcemeta::blaze {\n\nauto Configuration::add_dependency(const sourcemeta::core::URI &uri,\n                                   const std::filesystem::path &path) -> void {\n  assert(path.is_absolute());\n  const auto canonical_uri{\n      sourcemeta::core::URI::canonicalize(uri.recompose())};\n\n  if (this->dependencies.contains(canonical_uri)) [[unlikely]] {\n    throw ConfigurationParseError(\n        \"The dependency already exists\",\n        sourcemeta::core::Pointer({\"dependencies\", canonical_uri}));\n  }\n\n  for (const auto &existing : this->dependencies) {\n    if (existing.second == path) [[unlikely]] {\n      throw ConfigurationParseError(\n          \"Multiple dependencies cannot point to the same path\",\n          sourcemeta::core::Pointer({\"dependencies\", existing.first}));\n    }\n  }\n\n  this->dependencies.emplace(canonical_uri, path);\n}\n\nauto Configuration::find(const std::filesystem::path &path)\n    -> std::optional<std::filesystem::path> {\n  // Note we use non-throwing overloads of filesystem functions to gracefully\n  // handle I/O errors on FUSE and other unusual filesystems\n  std::filesystem::path canonical;\n  try {\n    canonical = sourcemeta::core::weakly_canonical(path);\n  } catch (const std::filesystem::filesystem_error &) {\n    return std::nullopt;\n  }\n\n  assert(canonical.is_absolute());\n  std::error_code error;\n  const auto is_directory = std::filesystem::is_directory(canonical, error);\n  auto current = !error && !is_directory ? canonical.parent_path() : canonical;\n\n  while (!current.empty()) {\n    auto candidate = current / \"jsonschema.json\";\n    if (std::filesystem::exists(candidate, error) &&\n        std::filesystem::is_regular_file(candidate, error)) {\n      return candidate;\n    }\n\n    auto parent = current.parent_path();\n    if (parent == current) {\n      break;\n    } else {\n      current = parent;\n    }\n  }\n\n  return std::nullopt;\n}\n\nauto Configuration::applies_to(const std::filesystem::path &path) const\n    -> bool {\n  if (this->extension.empty()) {\n    return true;\n  }\n\n  const std::string filename{path.filename().string()};\n  return std::ranges::any_of(this->extension,\n                             [&path, &filename](const auto &suffix) {\n                               if (suffix.empty()) {\n                                 return path.extension().empty();\n                               }\n\n                               return filename.ends_with(suffix);\n                             });\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/configuration/fetch.cc",
    "content": "#include <sourcemeta/blaze/configuration.h>\n\n#include <sourcemeta/core/crypto.h>\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t\n#include <sstream> // std::ostringstream\n#include <utility> // std::move\n#include <vector>  // std::vector\n\nnamespace {\n\nauto compute_sha256(const std::string &content)\n    -> sourcemeta::core::JSON::String {\n  std::ostringstream result;\n  sourcemeta::core::sha256(content, result);\n  return result.str();\n}\n\nauto emit_event(\n    const sourcemeta::blaze::Configuration::FetchEvent::Callback &callback,\n    sourcemeta::blaze::Configuration::FetchEvent::Type type,\n    const std::string &event_uri, const std::filesystem::path &event_path,\n    std::size_t index, std::size_t total, std::string details = {},\n    const std::exception_ptr &exception = nullptr,\n    bool emit_error_if_aborted = false) -> bool {\n  const auto result{callback({.type = type,\n                              .uri = event_uri,\n                              .path = event_path,\n                              .index = index,\n                              .total = total,\n                              .details = std::move(details),\n                              .exception = exception})};\n  if (!result && emit_error_if_aborted) {\n    emit_event(\n        callback, sourcemeta::blaze::Configuration::FetchEvent::Type::Error,\n        event_uri, event_path, index, total, \"Operation aborted by callback\");\n  }\n\n  return result;\n}\n\nenum class FetchResult : std::uint8_t { Success, Error, Aborted };\n\nauto verify_written_schema(\n    const std::string &dependency_uri,\n    const std::filesystem::path &dependency_path,\n    const sourcemeta::blaze::Configuration::ReadCallback &reader,\n    const sourcemeta::blaze::Configuration::FetchEvent::Callback &callback,\n    std::size_t index, std::size_t total,\n    sourcemeta::core::JSON::String &out_hash) -> FetchResult {\n  using FetchEvent = sourcemeta::blaze::Configuration::FetchEvent;\n\n  if (!emit_event(callback, FetchEvent::Type::VerifyStart, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  std::string written_content;\n  try {\n    written_content = reader(dependency_path);\n  } catch (...) {\n    emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n               dependency_path, index, total, \"Failed to verify written schema\",\n               std::current_exception());\n    return FetchResult::Error;\n  }\n\n  out_hash = compute_sha256(written_content);\n\n  if (!emit_event(callback, FetchEvent::Type::VerifyEnd, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  return FetchResult::Success;\n}\n\nauto fetch_and_write(\n    const std::string &dependency_uri,\n    const std::filesystem::path &dependency_path,\n    const sourcemeta::blaze::Configuration::FetchCallback &fetcher,\n    const sourcemeta::core::SchemaResolver &resolver,\n    const sourcemeta::blaze::Configuration::WriteCallback &writer,\n    const sourcemeta::blaze::Configuration::FetchEvent::Callback &callback,\n    const std::optional<sourcemeta::core::JSON::String> &default_dialect,\n    std::size_t index, std::size_t total, sourcemeta::core::JSON &out_schema)\n    -> FetchResult {\n  using FetchEvent = sourcemeta::blaze::Configuration::FetchEvent;\n\n  if (!emit_event(callback, FetchEvent::Type::FetchStart, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  try {\n    out_schema = fetcher(dependency_uri);\n  } catch (...) {\n    emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n               dependency_path, index, total, \"Failed to fetch schema\",\n               std::current_exception());\n    return FetchResult::Error;\n  }\n\n  if (!emit_event(callback, FetchEvent::Type::FetchEnd, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  if (!emit_event(callback, FetchEvent::Type::BundleStart, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  try {\n    const std::string default_dialect_value{default_dialect.value_or(\"\")};\n    sourcemeta::core::bundle(out_schema, sourcemeta::core::schema_walker,\n                             resolver, default_dialect_value, dependency_uri);\n  } catch (...) {\n    emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n               dependency_path, index, total, \"Failed to bundle schema\",\n               std::current_exception());\n    return FetchResult::Error;\n  }\n\n  if (!emit_event(callback, FetchEvent::Type::BundleEnd, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  if (!emit_event(callback, FetchEvent::Type::WriteStart, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  try {\n    writer(dependency_path, out_schema);\n  } catch (...) {\n    emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n               dependency_path, index, total, \"Failed to write schema\",\n               std::current_exception());\n    return FetchResult::Error;\n  }\n\n  if (!emit_event(callback, FetchEvent::Type::WriteEnd, dependency_uri,\n                  dependency_path, index, total, {}, nullptr, true)) {\n    return FetchResult::Aborted;\n  }\n\n  return FetchResult::Success;\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto Configuration::fetch(Lock &lock, const FetchCallback &fetcher,\n                          const sourcemeta::core::SchemaResolver &resolver,\n                          const ReadCallback &reader,\n                          const WriteCallback &writer,\n                          const FetchEvent::Callback &callback,\n                          const FetchMode mode,\n                          [[maybe_unused]] std::size_t concurrency) const\n    -> void {\n  const auto dependency_count{this->dependencies.size()};\n  std::size_t current_index{0};\n\n  for (const auto &[dependency_uri, dependency_path] : this->dependencies) {\n    assert(dependency_path.is_absolute());\n    const auto entry_status{\n        lock.check(dependency_uri, dependency_path, reader)};\n\n    bool should_fetch{false};\n    switch (entry_status) {\n      case Lock::Entry::Status::Untracked:\n      case Lock::Entry::Status::FileMissing:\n      case Lock::Entry::Status::Mismatched:\n      case Lock::Entry::Status::PathMismatch:\n        should_fetch = true;\n        break;\n      case Lock::Entry::Status::UpToDate:\n        should_fetch = (mode == FetchMode::All);\n        break;\n    }\n\n    if (should_fetch) {\n      sourcemeta::core::JSON schema{sourcemeta::core::JSON::make_object()};\n      const auto result{fetch_and_write(\n          dependency_uri, dependency_path, fetcher, resolver, writer, callback,\n          this->default_dialect, current_index, dependency_count, schema)};\n\n      switch (result) {\n        case FetchResult::Aborted:\n        case FetchResult::Error:\n          return;\n        case FetchResult::Success:\n          break;\n      }\n\n      sourcemeta::core::JSON::String written_hash;\n      const auto verify_result{verify_written_schema(\n          dependency_uri, dependency_path, reader, callback, current_index,\n          dependency_count, written_hash)};\n\n      switch (verify_result) {\n        case FetchResult::Aborted:\n        case FetchResult::Error:\n          return;\n        case FetchResult::Success:\n          break;\n      }\n\n      lock.emplace(dependency_uri, dependency_path, written_hash);\n    } else {\n      if (!emit_event(callback, FetchEvent::Type::UpToDate, dependency_uri,\n                      dependency_path, current_index, dependency_count, {},\n                      nullptr, true)) {\n        return;\n      }\n    }\n\n    current_index += 1;\n  }\n\n  std::vector<sourcemeta::core::JSON::String> orphaned_uris;\n  for (const auto &[lock_uri, lock_entry] : lock) {\n    if (!this->dependencies.contains(lock_uri)) {\n      orphaned_uris.push_back(lock_uri);\n      if (!emit_event(callback, FetchEvent::Type::Orphaned, lock_uri,\n                      lock_entry.path, 0, 0, {}, nullptr, true)) {\n        return;\n      }\n    }\n  }\n\n  for (const auto &uri : orphaned_uris) {\n    lock.erase(uri);\n  }\n}\n\nauto Configuration::fetch(const Lock &lock, const FetchCallback &fetcher,\n                          const sourcemeta::core::SchemaResolver &resolver,\n                          const ReadCallback &reader,\n                          const WriteCallback &writer,\n                          const FetchEvent::Callback &callback,\n                          const bool dry_run,\n                          [[maybe_unused]] std::size_t concurrency) const\n    -> void {\n  const auto dependency_count{this->dependencies.size()};\n  std::size_t current_index{0};\n\n  for (const auto &[dependency_uri, dependency_path] : this->dependencies) {\n    assert(dependency_path.is_absolute());\n    const auto entry_status{\n        lock.check(dependency_uri, dependency_path, reader)};\n    switch (entry_status) {\n      case Lock::Entry::Status::Untracked:\n        if (!emit_event(callback, FetchEvent::Type::Untracked, dependency_uri,\n                        dependency_path, current_index, dependency_count, {},\n                        nullptr, true)) {\n          return;\n        }\n        break;\n\n      case Lock::Entry::Status::FileMissing: {\n        if (dry_run) {\n          if (!emit_event(callback, FetchEvent::Type::FileMissing,\n                          dependency_uri, dependency_path, current_index,\n                          dependency_count, {}, nullptr, true)) {\n            return;\n          }\n        } else {\n          sourcemeta::core::JSON schema{sourcemeta::core::JSON::make_object()};\n          const auto result{\n              fetch_and_write(dependency_uri, dependency_path, fetcher,\n                              resolver, writer, callback, this->default_dialect,\n                              current_index, dependency_count, schema)};\n\n          switch (result) {\n            case FetchResult::Aborted:\n            case FetchResult::Error:\n              return;\n            case FetchResult::Success:\n              break;\n          }\n\n          sourcemeta::core::JSON::String written_hash;\n          const auto verify_result{verify_written_schema(\n              dependency_uri, dependency_path, reader, callback, current_index,\n              dependency_count, written_hash)};\n\n          switch (verify_result) {\n            case FetchResult::Aborted:\n            case FetchResult::Error:\n              return;\n            case FetchResult::Success:\n              break;\n          }\n\n          assert(lock.at(dependency_uri).has_value());\n          const auto &lock_entry{lock.at(dependency_uri)->get()};\n          if (written_hash != lock_entry.hash) {\n            emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n                       dependency_path, current_index, dependency_count,\n                       \"Written file hash does not match lock file\");\n            return;\n          }\n        }\n        break;\n      }\n\n      case Lock::Entry::Status::Mismatched:\n        if (!emit_event(callback, FetchEvent::Type::Mismatched, dependency_uri,\n                        dependency_path, current_index, dependency_count, {},\n                        nullptr, true)) {\n          return;\n        }\n        if (!dry_run) {\n          emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n                     dependency_path, current_index, dependency_count,\n                     \"File hash does not match lock file in frozen mode\");\n          return;\n        }\n        break;\n\n      case Lock::Entry::Status::PathMismatch:\n        if (!emit_event(callback, FetchEvent::Type::PathMismatch,\n                        dependency_uri, dependency_path, current_index,\n                        dependency_count, {}, nullptr, true)) {\n          return;\n        }\n        if (!dry_run) {\n          emit_event(callback, FetchEvent::Type::Error, dependency_uri,\n                     dependency_path, current_index, dependency_count,\n                     \"Configured path does not match lock file in frozen mode\");\n          return;\n        }\n        break;\n\n      case Lock::Entry::Status::UpToDate:\n        if (!emit_event(callback, FetchEvent::Type::UpToDate, dependency_uri,\n                        dependency_path, current_index, dependency_count, {},\n                        nullptr, true)) {\n          return;\n        }\n        break;\n    }\n\n    current_index += 1;\n  }\n\n  for (const auto &[lock_uri, lock_entry] : lock) {\n    if (!this->dependencies.contains(lock_uri)) {\n      if (!emit_event(callback, FetchEvent::Type::Orphaned, lock_uri,\n                      lock_entry.path, 0, 0, {}, nullptr, true)) {\n        return;\n      }\n    }\n  }\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/configuration/include/sourcemeta/blaze/configuration.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CONFIGURATION_H_\n#define SOURCEMETA_BLAZE_CONFIGURATION_H_\n\n/// @defgroup configuration Configuration\n/// @brief A configuration manifest for JSON Schema projects\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/configuration.h>\n/// ```\n\n#ifndef SOURCEMETA_BLAZE_CONFIGURATION_EXPORT\n#include <sourcemeta/blaze/configuration_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/blaze/configuration_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n#include <sourcemeta/core/uri.h>\n\n#include <cstddef>       // std::size_t\n#include <cstdint>       // std::uint8_t\n#include <exception>     // std::exception_ptr\n#include <filesystem>    // std::filesystem\n#include <functional>    // std::function\n#include <map>           // std::map\n#include <optional>      // std::optional\n#include <string>        // std::string\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n// TODO(C++23): Consider std::flat_map/std::flat_set when available in libc++\n#include <unordered_set> // std::unordered_set\n#include <vector>        // std::vector\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup configuration\n/// A configuration file format for JSON Schema projects\nstruct SOURCEMETA_BLAZE_CONFIGURATION_EXPORT Configuration {\n  std::optional<sourcemeta::core::JSON::String> title;\n  std::optional<sourcemeta::core::JSON::String> description;\n  std::optional<sourcemeta::core::JSON::String> email;\n  std::optional<sourcemeta::core::JSON::String> github;\n  std::optional<sourcemeta::core::JSON::String> website;\n  std::filesystem::path absolute_path;\n  bool absolute_path_explicit{false};\n  std::filesystem::path base_path;\n  sourcemeta::core::JSON::String base;\n  std::optional<sourcemeta::core::JSON::String> default_dialect;\n  std::unordered_set<sourcemeta::core::JSON::String> extension{\".json\", \".yml\",\n                                                               \".yaml\"};\n  std::unordered_map<sourcemeta::core::JSON::String,\n                     sourcemeta::core::JSON::String>\n      resolve;\n  // Ordered to guarantee deterministic iteration\n  std::map<sourcemeta::core::JSON::String, std::filesystem::path> dependencies;\n  std::vector<std::filesystem::path> ignore;\n\n  struct Lint {\n    std::vector<std::filesystem::path> rules;\n  };\n\n  Lint lint;\n  sourcemeta::core::JSON extra = sourcemeta::core::JSON::make_object();\n\n  /// A callback to read file contents from a path\n  using ReadCallback =\n      // TODO(C++23): Use std::move_only_function when available in libc++\n      std::function<std::string(const std::filesystem::path &)>;\n\n  /// A lock file that tracks fetched dependency hashes\n  class SOURCEMETA_BLAZE_CONFIGURATION_EXPORT Lock {\n  public:\n    struct Entry {\n      std::filesystem::path path;\n      // TODO: Separately store the server ETag for exploiting HTTP caching?\n      sourcemeta::core::JSON::String hash;\n      enum class HashAlgorithm : std::uint8_t { SHA256 };\n      HashAlgorithm hash_algorithm;\n      enum class Status : std::uint8_t {\n        Untracked,\n        FileMissing,\n        Mismatched,\n        PathMismatch,\n        UpToDate\n      };\n    };\n\n    using const_iterator =\n        std::map<sourcemeta::core::JSON::String, Entry>::const_iterator;\n\n    auto\n    emplace(const sourcemeta::core::JSON::String &uri,\n            const std::filesystem::path &path,\n            const sourcemeta::core::JSON::String &hash,\n            Entry::HashAlgorithm hash_algorithm = Entry::HashAlgorithm::SHA256)\n        -> void;\n    auto erase(const sourcemeta::core::JSON::String &uri) -> void;\n\n    [[nodiscard]] auto size() const noexcept -> std::size_t;\n    [[nodiscard]] auto at(const sourcemeta::core::JSON::String &uri) const\n        -> std::optional<std::reference_wrapper<const Entry>>;\n    [[nodiscard]] auto begin() const noexcept -> const_iterator;\n    [[nodiscard]] auto end() const noexcept -> const_iterator;\n\n    [[nodiscard]]\n    auto check(const sourcemeta::core::JSON::String &uri,\n               const std::filesystem::path &expected_path,\n               const ReadCallback &reader) const -> Entry::Status;\n    [[nodiscard]]\n    static auto from_json(const sourcemeta::core::JSON &value,\n                          const std::filesystem::path &lock_base_path) -> Lock;\n    [[nodiscard]]\n    auto to_json(const std::filesystem::path &lock_base_path) const\n        -> sourcemeta::core::JSON;\n\n  private:\n    // Ordered to guarantee deterministic iteration\n    std::map<sourcemeta::core::JSON::String, Entry> entries_;\n  };\n\n  /// An event emitted during dependency fetching\n  struct FetchEvent {\n    enum class Type : std::uint8_t {\n      FetchStart,\n      FetchEnd,\n      BundleStart,\n      BundleEnd,\n      WriteStart,\n      WriteEnd,\n      VerifyStart,\n      VerifyEnd,\n      UpToDate,\n      FileMissing,\n      Orphaned,\n      Mismatched,\n      PathMismatch,\n      Untracked,\n      Error\n    };\n\n    Type type;\n    std::string uri;\n    std::filesystem::path path;\n    std::size_t index;\n    std::size_t total;\n    std::string details;\n    std::exception_ptr exception;\n\n    using Callback = std::function<bool(const FetchEvent &)>;\n  };\n\n  /// A callback to fetch a JSON Schema from a URI\n  using FetchCallback =\n      std::function<sourcemeta::core::JSON(std::string_view uri)>;\n\n  /// A callback to write a JSON Schema to a path\n  using WriteCallback = std::function<void(const std::filesystem::path &,\n                                           const sourcemeta::core::JSON &)>;\n\n  /// The mode for fetching dependencies with a mutable lock\n  enum class FetchMode : std::uint8_t {\n    /// Fetch only what's missing or untracked\n    Missing,\n    /// Re-fetch everything regardless of current state\n    All\n  };\n\n  /// Fetch dependencies, modifying the lock in-place\n  auto fetch(Lock &lock, const FetchCallback &fetcher,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const ReadCallback &reader, const WriteCallback &writer,\n             const FetchEvent::Callback &on_event, FetchMode mode,\n             // TODO: Make this work for real\n             std::size_t concurrency = 1) const -> void;\n\n  /// Fetch dependencies without modifying the lock file (frozen mode)\n  auto fetch(const Lock &lock, const FetchCallback &fetcher,\n             const sourcemeta::core::SchemaResolver &resolver,\n             const ReadCallback &reader, const WriteCallback &writer,\n             const FetchEvent::Callback &on_event, bool dry_run = false,\n             // TODO: Make this work for real\n             std::size_t concurrency = 1) const -> void;\n\n  /// Add a dependency to the configuration\n  auto add_dependency(const sourcemeta::core::URI &uri,\n                      const std::filesystem::path &path) -> void;\n\n  /// Check if the given path represents a schema described by this\n  /// configuration\n  [[nodiscard]]\n  auto applies_to(const std::filesystem::path &path) const -> bool;\n\n  /// Parse a configuration file from its contents\n  [[nodiscard]]\n  static auto from_json(const sourcemeta::core::JSON &value,\n                        const std::filesystem::path &base_path)\n      -> Configuration;\n\n  /// Serialize a configuration to JSON\n  [[nodiscard]]\n  auto to_json() const -> sourcemeta::core::JSON;\n\n  /// Read and parse a configuration file\n  [[nodiscard]]\n  static auto read_json(const std::filesystem::path &path,\n                        const ReadCallback &reader) -> Configuration;\n\n  /// A nearest ancestor configuration lookup\n  [[nodiscard]]\n  static auto find(const std::filesystem::path &path)\n      -> std::optional<std::filesystem::path>;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/configuration/include/sourcemeta/blaze/configuration_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_CONFIGURATION_ERROR_H_\n#define SOURCEMETA_BLAZE_CONFIGURATION_ERROR_H_\n\n#ifndef SOURCEMETA_BLAZE_CONFIGURATION_EXPORT\n#include <sourcemeta/blaze/configuration_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup configuration\nclass SOURCEMETA_BLAZE_CONFIGURATION_EXPORT ConfigurationParseError\n    : public std::exception {\npublic:\n  ConfigurationParseError(const char *message,\n                          sourcemeta::core::Pointer location)\n      : message_{message}, location_{std::move(location)} {}\n  ConfigurationParseError(std::string message,\n                          sourcemeta::core::Pointer location) = delete;\n  ConfigurationParseError(std::string &&message,\n                          sourcemeta::core::Pointer location) = delete;\n  ConfigurationParseError(std::string_view message,\n                          sourcemeta::core::Pointer location) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto location() const noexcept -> const auto & {\n    return this->location_;\n  }\n\nprivate:\n  const char *message_;\n  sourcemeta::core::Pointer location_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/configuration/json.cc",
    "content": "#include <sourcemeta/blaze/configuration.h>\n\n#include <sourcemeta/core/json.h>\n\n#include <algorithm> // std::ranges::sort\n#include <string>    // std::string\n#include <vector>    // std::vector\n\nnamespace sourcemeta::blaze {\n\nstatic auto relative_display_path(const std::filesystem::path &path,\n                                  const std::filesystem::path &base)\n    -> std::string {\n  auto relative_path{std::filesystem::relative(path, base).generic_string()};\n  if (relative_path.starts_with(\"..\")) {\n    return relative_path;\n  }\n\n  return \"./\" + relative_path;\n}\n\nauto Configuration::to_json() const -> sourcemeta::core::JSON {\n  auto result{sourcemeta::core::JSON::make_object()};\n\n  if (this->title.has_value()) {\n    result.assign(\"title\", sourcemeta::core::JSON{this->title.value()});\n  }\n\n  if (this->description.has_value()) {\n    result.assign(\"description\",\n                  sourcemeta::core::JSON{this->description.value()});\n  }\n\n  if (this->email.has_value()) {\n    result.assign(\"email\", sourcemeta::core::JSON{this->email.value()});\n  }\n\n  if (this->github.has_value()) {\n    result.assign(\"github\", sourcemeta::core::JSON{this->github.value()});\n  }\n\n  if (this->website.has_value()) {\n    result.assign(\"website\", sourcemeta::core::JSON{this->website.value()});\n  }\n\n  if (this->absolute_path_explicit) {\n    result.assign(\"path\",\n                  sourcemeta::core::JSON{this->absolute_path.generic_string()});\n  }\n\n  if (!this->base.empty()) {\n    result.assign(\"baseUri\", sourcemeta::core::JSON{this->base});\n  }\n\n  if (this->default_dialect.has_value()) {\n    result.assign(\"defaultDialect\",\n                  sourcemeta::core::JSON{this->default_dialect.value()});\n  }\n\n  static const Configuration defaults;\n  if (!this->extension.empty() && this->extension != defaults.extension) {\n    auto extension_array{sourcemeta::core::JSON::make_array()};\n    // Sort for deterministic output\n    std::vector<std::string> sorted_extensions{this->extension.cbegin(),\n                                               this->extension.cend()};\n    std::ranges::sort(sorted_extensions);\n    for (const auto &entry : sorted_extensions) {\n      extension_array.push_back(sourcemeta::core::JSON{entry});\n    }\n\n    result.assign(\"extension\", std::move(extension_array));\n  }\n\n  if (!this->resolve.empty()) {\n    auto resolve_object{sourcemeta::core::JSON::make_object()};\n    for (const auto &pair : this->resolve) {\n      resolve_object.assign(pair.first, sourcemeta::core::JSON{pair.second});\n    }\n\n    result.assign(\"resolve\", std::move(resolve_object));\n  }\n\n  if (!this->dependencies.empty()) {\n    auto dependencies_object{sourcemeta::core::JSON::make_object()};\n    for (const auto &pair : this->dependencies) {\n      dependencies_object.assign(\n          pair.first, sourcemeta::core::JSON{\n                          relative_display_path(pair.second, this->base_path)});\n    }\n\n    result.assign(\"dependencies\", std::move(dependencies_object));\n  }\n\n  if (!this->ignore.empty()) {\n    auto ignore_array{sourcemeta::core::JSON::make_array()};\n    for (const auto &entry : this->ignore) {\n      ignore_array.push_back(sourcemeta::core::JSON{\n          relative_display_path(entry, this->base_path)});\n    }\n\n    result.assign(\"ignore\", std::move(ignore_array));\n  }\n\n  if (!this->lint.rules.empty()) {\n    auto lint_object{sourcemeta::core::JSON::make_object()};\n    auto rules_array{sourcemeta::core::JSON::make_array()};\n    for (const auto &rule : this->lint.rules) {\n      rules_array.push_back(\n          sourcemeta::core::JSON{relative_display_path(rule, this->base_path)});\n    }\n\n    lint_object.assign(\"rules\", std::move(rules_array));\n    result.assign(\"lint\", std::move(lint_object));\n  }\n\n  for (const auto &pair : this->extra.as_object()) {\n    result.assign(pair.first, pair.second);\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/configuration/lock.cc",
    "content": "#include <sourcemeta/blaze/configuration.h>\n\n#include <sourcemeta/core/crypto.h>\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <cassert> // assert\n#include <sstream> // std::ostringstream\n#include <utility> // std::move\n\nnamespace {\n\nauto compute_hash(\n    const std::string &content,\n    const sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm\n        algorithm,\n    const sourcemeta::core::Pointer &location)\n    -> sourcemeta::core::JSON::String {\n  using HashAlgorithm =\n      sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm;\n  switch (algorithm) {\n    case HashAlgorithm::SHA256: {\n      std::ostringstream result;\n      sourcemeta::core::sha256(content, result);\n      return result.str();\n    }\n    default:\n      throw sourcemeta::blaze::ConfigurationParseError(\"Unknown hash algorithm\",\n                                                       location);\n  }\n}\n\nauto hash_algorithm_to_string(\n    const sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm\n        algorithm,\n    const sourcemeta::core::Pointer &location)\n    -> sourcemeta::core::JSON::String {\n  using HashAlgorithm =\n      sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm;\n  switch (algorithm) {\n    case HashAlgorithm::SHA256:\n      return \"sha256\";\n    default:\n      throw sourcemeta::blaze::ConfigurationParseError(\"Unknown hash algorithm\",\n                                                       location);\n  }\n}\n\nauto string_to_hash_algorithm(const sourcemeta::core::JSON::String &value,\n                              const sourcemeta::core::Pointer &location)\n    -> sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm {\n  using HashAlgorithm =\n      sourcemeta::blaze::Configuration::Lock::Entry::HashAlgorithm;\n  if (value == \"sha256\") {\n    return HashAlgorithm::SHA256;\n  }\n\n  throw sourcemeta::blaze::ConfigurationParseError(\"Unknown hash algorithm\",\n                                                   location);\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto Configuration::Lock::from_json(const sourcemeta::core::JSON &value,\n                                    const std::filesystem::path &lock_base_path)\n    -> Lock {\n  assert(lock_base_path.is_absolute());\n  Lock result;\n\n  if (!value.is_object()) [[unlikely]] {\n    throw ConfigurationParseError(\"The lock file must be an object\", {});\n  }\n\n  if (!value.defines(\"version\")) [[unlikely]] {\n    throw ConfigurationParseError(\"The lock file must have a version property\",\n                                  {});\n  }\n\n  if (!value.at(\"version\").is_integer() ||\n      value.at(\"version\").to_integer() != 1) [[unlikely]] {\n    throw ConfigurationParseError(\"Unsupported lock file version\", {\"version\"});\n  }\n\n  if (value.defines(\"dependencies\")) {\n    if (!value.at(\"dependencies\").is_object()) [[unlikely]] {\n      throw ConfigurationParseError(\n          \"The lock file dependencies property must be an object\",\n          {\"dependencies\"});\n    }\n\n    for (const auto &pair : value.at(\"dependencies\").as_object()) {\n      if (!pair.second.is_object()) [[unlikely]] {\n        throw ConfigurationParseError(\n            \"The lock file dependency entry must be an object\",\n            {\"dependencies\", pair.first});\n      }\n\n      if (!pair.second.defines(\"path\") || !pair.second.at(\"path\").is_string())\n          [[unlikely]] {\n        throw ConfigurationParseError(\n            \"The lock file dependency entry must have a path\",\n            {\"dependencies\", pair.first, \"path\"});\n      }\n\n      if (!pair.second.defines(\"hash\") || !pair.second.at(\"hash\").is_string())\n          [[unlikely]] {\n        throw ConfigurationParseError(\n            \"The lock file dependency entry must have a hash\",\n            {\"dependencies\", pair.first, \"hash\"});\n      }\n\n      if (!pair.second.defines(\"hashAlgorithm\") ||\n          !pair.second.at(\"hashAlgorithm\").is_string()) [[unlikely]] {\n        throw ConfigurationParseError(\n            \"The lock file dependency entry must have a hash algorithm\",\n            {\"dependencies\", pair.first, \"hashAlgorithm\"});\n      }\n\n      const std::filesystem::path entry_path{\n          pair.second.at(\"path\").to_string()};\n\n      Entry entry;\n      if (entry_path.is_absolute()) {\n        entry.path = entry_path;\n      } else {\n        try {\n          entry.path =\n              sourcemeta::core::weakly_canonical(lock_base_path / entry_path);\n        } catch (const std::filesystem::filesystem_error &) {\n          throw ConfigurationParseError(\n              \"The lock file dependency entry path could not be resolved\",\n              {\"dependencies\", pair.first, \"path\"});\n        }\n      }\n\n      entry.hash = pair.second.at(\"hash\").to_string();\n      entry.hash_algorithm = string_to_hash_algorithm(\n          pair.second.at(\"hashAlgorithm\").to_string(),\n          {\"dependencies\", pair.first, \"hashAlgorithm\"});\n\n      result.entries_.emplace(pair.first, std::move(entry));\n    }\n  }\n\n  return result;\n}\n\nauto Configuration::Lock::to_json(const std::filesystem::path &lock_base_path)\n    const -> sourcemeta::core::JSON {\n  assert(lock_base_path.is_absolute());\n  auto result{sourcemeta::core::JSON::make_object()};\n  result.assign(\"version\", sourcemeta::core::JSON{1});\n\n  auto dependencies_json{sourcemeta::core::JSON::make_object()};\n  for (const auto &pair : this->entries_) {\n    assert(pair.second.path.is_absolute());\n    auto entry_json{sourcemeta::core::JSON::make_object()};\n    auto relative_path{\n        std::filesystem::relative(pair.second.path, lock_base_path)\n            .generic_string()};\n    if (!relative_path.starts_with(\"..\")) {\n      relative_path.insert(0, \"./\");\n    }\n\n    entry_json.assign(\"path\", sourcemeta::core::JSON{relative_path});\n    entry_json.assign(\"hash\", sourcemeta::core::JSON{pair.second.hash});\n    entry_json.assign(\"hashAlgorithm\",\n                      sourcemeta::core::JSON{hash_algorithm_to_string(\n                          pair.second.hash_algorithm,\n                          {\"dependencies\", pair.first, \"hashAlgorithm\"})});\n    dependencies_json.assign(pair.first, std::move(entry_json));\n  }\n\n  result.assign(\"dependencies\", std::move(dependencies_json));\n  return result;\n}\n\nauto Configuration::Lock::emplace(const sourcemeta::core::JSON::String &uri,\n                                  const std::filesystem::path &path,\n                                  const sourcemeta::core::JSON::String &hash,\n                                  Entry::HashAlgorithm hash_algorithm) -> void {\n  assert(path.is_absolute());\n  Entry entry;\n  entry.path = path;\n  entry.hash = hash;\n  entry.hash_algorithm = hash_algorithm;\n  this->entries_.insert_or_assign(uri, std::move(entry));\n}\n\nauto Configuration::Lock::erase(const sourcemeta::core::JSON::String &uri)\n    -> void {\n  this->entries_.erase(uri);\n}\n\nauto Configuration::Lock::size() const noexcept -> std::size_t {\n  return this->entries_.size();\n}\n\nauto Configuration::Lock::at(const sourcemeta::core::JSON::String &uri) const\n    -> std::optional<std::reference_wrapper<const Entry>> {\n  const auto iterator{this->entries_.find(uri)};\n  if (iterator == this->entries_.cend()) {\n    return std::nullopt;\n  }\n\n  return std::cref(iterator->second);\n}\n\nauto Configuration::Lock::begin() const noexcept -> const_iterator {\n  return this->entries_.cbegin();\n}\n\nauto Configuration::Lock::end() const noexcept -> const_iterator {\n  return this->entries_.cend();\n}\n\nauto Configuration::Lock::check(const sourcemeta::core::JSON::String &uri,\n                                const std::filesystem::path &expected_path,\n                                const Configuration::ReadCallback &reader) const\n    -> Entry::Status {\n  const auto iterator{this->entries_.find(uri)};\n  if (iterator == this->entries_.cend()) {\n    return Entry::Status::Untracked;\n  }\n\n  const auto &entry{iterator->second};\n\n  if (entry.path != expected_path) {\n    return Entry::Status::PathMismatch;\n  }\n\n  std::string content;\n  try {\n    content = reader(entry.path);\n  } catch (...) {\n    return Entry::Status::FileMissing;\n  }\n\n  const auto current_hash{\n      compute_hash(content, entry.hash_algorithm, {\"dependencies\", uri})};\n  if (current_hash != entry.hash) {\n    return Entry::Status::Mismatched;\n  }\n\n  return Entry::Status::UpToDate;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/configuration/parse.cc",
    "content": "#include <sourcemeta/blaze/configuration.h>\n\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/uri.h>\n\n#include <cassert> // assert\n\nnamespace sourcemeta::blaze {\n\nauto Configuration::from_json(const sourcemeta::core::JSON &value,\n                              const std::filesystem::path &base_path)\n    -> Configuration {\n  assert(base_path.is_absolute());\n  Configuration result;\n  result.base_path = base_path;\n\n#define CONFIGURATION_ENSURE(condition, message, location)                     \\\n  if (!(condition)) [[unlikely]] {                                             \\\n    throw ConfigurationParseError((message),                                   \\\n                                  sourcemeta::core::Pointer(location));        \\\n  }\n\n  // Just to keep this decoupled from actual JSON Schema validator, which we\n  // don't do in this repository\n  CONFIGURATION_ENSURE(value.is_object(), \"The configuration must be an object\",\n                       {});\n  CONFIGURATION_ENSURE(!value.defines(\"title\") || value.at(\"title\").is_string(),\n                       \"The title property must be a string\", {\"title\"});\n  CONFIGURATION_ENSURE(\n      !value.defines(\"description\") || value.at(\"description\").is_string(),\n      \"The description property must be a string\", {\"description\"});\n  CONFIGURATION_ENSURE(!value.defines(\"email\") || value.at(\"email\").is_string(),\n                       \"The email property must be a string\", {\"email\"});\n  CONFIGURATION_ENSURE(!value.defines(\"github\") ||\n                           value.at(\"github\").is_string(),\n                       \"The github property must be a string\", {\"github\"});\n  CONFIGURATION_ENSURE(!value.defines(\"website\") ||\n                           value.at(\"website\").is_string(),\n                       \"The website property must be a string\", {\"website\"});\n  CONFIGURATION_ENSURE(!value.defines(\"path\") || value.at(\"path\").is_string(),\n                       \"The path property must be a string\", {\"path\"});\n  CONFIGURATION_ENSURE(!value.defines(\"baseUri\") ||\n                           value.at(\"baseUri\").is_string(),\n                       \"The baseUri property must be a string\", {\"baseUri\"});\n  CONFIGURATION_ENSURE(!value.defines(\"defaultDialect\") ||\n                           value.at(\"defaultDialect\").is_string(),\n                       \"The defaultDialect property must be a string\",\n                       {\"defaultDialect\"});\n  CONFIGURATION_ENSURE(\n      !value.defines(\"extension\") || value.at(\"extension\").is_array() ||\n          value.at(\"extension\").is_string(),\n      \"The extension property must be a string or an array\", {\"extension\"});\n  CONFIGURATION_ENSURE(!value.defines(\"resolve\") ||\n                           value.at(\"resolve\").is_object(),\n                       \"The resolve property must be an object\", {\"resolve\"});\n  CONFIGURATION_ENSURE(\n      !value.defines(\"dependencies\") || value.at(\"dependencies\").is_object(),\n      \"The dependencies property must be an object\", {\"dependencies\"});\n\n  result.title =\n      sourcemeta::core::from_json<decltype(result.title)::value_type>(\n          value.at_or(\"title\", sourcemeta::core::JSON{nullptr}));\n  result.description =\n      sourcemeta::core::from_json<decltype(result.description)::value_type>(\n          value.at_or(\"description\", sourcemeta::core::JSON{nullptr}));\n  result.email =\n      sourcemeta::core::from_json<decltype(result.email)::value_type>(\n          value.at_or(\"email\", sourcemeta::core::JSON{nullptr}));\n  result.github =\n      sourcemeta::core::from_json<decltype(result.github)::value_type>(\n          value.at_or(\"github\", sourcemeta::core::JSON{nullptr}));\n  result.website =\n      sourcemeta::core::from_json<decltype(result.website)::value_type>(\n          value.at_or(\"website\", sourcemeta::core::JSON{nullptr}));\n\n  if (value.defines(\"path\")) {\n    const std::filesystem::path path{value.at(\"path\").to_string()};\n    if (path.is_absolute()) {\n      result.absolute_path = sourcemeta::core::weakly_canonical(path);\n    } else {\n      result.absolute_path =\n          sourcemeta::core::weakly_canonical(base_path / path);\n    }\n\n    result.absolute_path_explicit = true;\n  } else {\n    result.absolute_path = sourcemeta::core::weakly_canonical(base_path);\n  }\n\n  assert(result.absolute_path.is_absolute());\n\n  if (value.defines(\"baseUri\")) {\n    try {\n      sourcemeta::core::URI base{value.at(\"baseUri\").to_string()};\n      base.canonicalize();\n      if (!base.is_absolute()) {\n        CONFIGURATION_ENSURE(\n            false, \"The baseUri property must be an absolute URI\", {\"baseUri\"});\n      }\n\n      result.base = base.recompose();\n    } catch (const sourcemeta::core::URIParseError &) {\n      CONFIGURATION_ENSURE(false,\n                           \"The baseUri property must represent a valid URI\",\n                           {\"baseUri\"});\n    }\n  } else {\n    // Otherwise the base is the directory\n    result.base =\n        sourcemeta::core::URI::from_path(result.absolute_path).recompose();\n  }\n\n  result.default_dialect =\n      sourcemeta::core::from_json<decltype(result.default_dialect)::value_type>(\n          value.at_or(\"defaultDialect\", sourcemeta::core::JSON{nullptr}));\n\n  if (value.defines(\"extension\")) {\n    result.extension.clear();\n    const auto &extension_value{value.at(\"extension\")};\n    if (extension_value.is_string()) {\n      auto extension_string{extension_value.to_string()};\n      if (!extension_string.empty() && extension_string.front() != '.') {\n        extension_string.insert(extension_string.begin(), '.');\n      }\n\n      result.extension.emplace(std::move(extension_string));\n    } else {\n      // TODO(C++23): Use std::views::enumerate when available in libc++\n      std::size_t index{0};\n      for (const auto &element : extension_value.as_array()) {\n        CONFIGURATION_ENSURE(\n            element.is_string(),\n            \"The values in the extension array must be strings\",\n            sourcemeta::core::Pointer({\"extension\", index}));\n\n        auto extension_string{element.to_string()};\n        if (!extension_string.empty() && extension_string.front() != '.') {\n          extension_string.insert(extension_string.begin(), '.');\n        }\n\n        result.extension.emplace(std::move(extension_string));\n        index += 1;\n      }\n    }\n  }\n\n  if (value.defines(\"resolve\")) {\n    for (const auto &pair : value.at(\"resolve\").as_object()) {\n      CONFIGURATION_ENSURE(pair.second.is_string(),\n                           \"The values in the resolve object must be strings\",\n                           sourcemeta::core::Pointer({\"resolve\", pair.first}));\n\n      try {\n        result.resolve.emplace(pair.first, sourcemeta::core::URI::canonicalize(\n                                               pair.second.to_string()));\n      } catch (const sourcemeta::core::URIParseError &) {\n        CONFIGURATION_ENSURE(\n            false, \"The values in the resolve object must represent valid URIs\",\n            sourcemeta::core::Pointer({\"resolve\", pair.first}));\n      }\n    }\n  }\n\n  if (value.defines(\"dependencies\")) {\n    for (const auto &pair : value.at(\"dependencies\").as_object()) {\n      CONFIGURATION_ENSURE(\n          pair.second.is_string(),\n          \"The values in the dependencies object must be strings\",\n          sourcemeta::core::Pointer({\"dependencies\", pair.first}));\n\n      const std::filesystem::path dependency_path{pair.second.to_string()};\n      const auto absolute_dependency_path =\n          dependency_path.is_absolute()\n              ? sourcemeta::core::weakly_canonical(dependency_path)\n              : sourcemeta::core::weakly_canonical(base_path / dependency_path);\n      try {\n        result.add_dependency(sourcemeta::core::URI{pair.first},\n                              absolute_dependency_path);\n      } catch (const sourcemeta::core::URIParseError &) {\n        CONFIGURATION_ENSURE(\n            false, \"The dependency URI is not valid\",\n            sourcemeta::core::Pointer({\"dependencies\", pair.first}));\n      }\n    }\n  }\n\n  CONFIGURATION_ENSURE(!value.defines(\"lint\") || value.at(\"lint\").is_object(),\n                       \"The lint property must be an object\", {\"lint\"});\n\n  if (value.defines(\"lint\")) {\n    const auto &lint_value{value.at(\"lint\")};\n    CONFIGURATION_ENSURE(!lint_value.defines(\"rules\") ||\n                             lint_value.at(\"rules\").is_array(),\n                         \"The lint rules property must be an array\",\n                         sourcemeta::core::Pointer({\"lint\", \"rules\"}));\n\n    if (lint_value.defines(\"rules\")) {\n      std::size_t index{0};\n      for (const auto &element : lint_value.at(\"rules\").as_array()) {\n        CONFIGURATION_ENSURE(\n            element.is_string(),\n            \"The values in the lint rules array must be strings\",\n            sourcemeta::core::Pointer({\"lint\", \"rules\", index}));\n\n        const std::filesystem::path path{element.to_string()};\n        result.lint.rules.push_back(\n            path.is_absolute()\n                ? sourcemeta::core::weakly_canonical(path)\n                : sourcemeta::core::weakly_canonical(base_path / path));\n        index += 1;\n      }\n    }\n  }\n\n  CONFIGURATION_ENSURE(!value.defines(\"ignore\") ||\n                           value.at(\"ignore\").is_array(),\n                       \"The ignore property must be an array\", {\"ignore\"});\n\n  if (value.defines(\"ignore\")) {\n    std::size_t index{0};\n    for (const auto &element : value.at(\"ignore\").as_array()) {\n      CONFIGURATION_ENSURE(element.is_string(),\n                           \"The values in the ignore array must be strings\",\n                           sourcemeta::core::Pointer({\"ignore\", index}));\n\n      const std::filesystem::path path{element.to_string()};\n      result.ignore.push_back(\n          path.is_absolute()\n              ? sourcemeta::core::weakly_canonical(path)\n              : sourcemeta::core::weakly_canonical(base_path / path));\n      index += 1;\n    }\n  }\n\n  assert(result.extra.is_object());\n  for (const auto &subentry : value.as_object()) {\n    if (subentry.first.starts_with(\"x-\")) {\n      result.extra.assign(subentry.first, subentry.second);\n    }\n  }\n\n#undef CONFIGURATION_ENSURE\n  return result;\n}\n\nauto Configuration::read_json(const std::filesystem::path &path,\n                              const Configuration::ReadCallback &reader)\n    -> Configuration {\n  assert(path.is_absolute());\n  const auto value{sourcemeta::core::parse_json(reader(path))};\n  return from_json(value, path.parent_path());\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/documentation/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME documentation\n  FOLDER \"Blaze/Documentation\"\n  SOURCES documentation.cc documentation_html.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME documentation)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_documentation PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_documentation PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_blaze_documentation PRIVATE\n  sourcemeta::blaze::alterschema)\ntarget_link_libraries(sourcemeta_blaze_documentation PRIVATE\n  sourcemeta::core::html)\n"
  },
  {
    "path": "vendor/blaze/src/documentation/documentation.cc",
    "content": "#include <sourcemeta/blaze/documentation.h>\n\n#include <sourcemeta/blaze/alterschema.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::int64_t\n#include <map>     // std::map\n#include <set>     // std::set\n#include <sstream> // std::ostringstream\n#include <string>  // std::to_string\n#include <utility> // std::move\n\nnamespace sourcemeta::blaze {\n\nnamespace {\n\nauto resolve_destination(const sourcemeta::core::JSON::String &raw_ref,\n                         const sourcemeta::core::SchemaFrame &frame)\n    -> std::optional<\n        std::reference_wrapper<const sourcemeta::core::SchemaFrame::Location>> {\n  auto result{frame.traverse(raw_ref)};\n  if (result.has_value()) {\n    return result;\n  }\n  for (const auto &[key, entry] : frame.references()) {\n    if (key.first == sourcemeta::core::SchemaReferenceType::Static &&\n        entry.original == raw_ref) {\n      return frame.traverse(entry.destination);\n    }\n  }\n  return std::nullopt;\n}\n\nstruct VisitedEntry {\n  std::size_t identifier;\n  sourcemeta::core::JSON path;\n};\nusing VisitedSchemas = std::map<const sourcemeta::core::JSON *, VisitedEntry>;\nusing RefChain = std::set<const sourcemeta::core::JSON *>;\n\nauto type_expression_of(const sourcemeta::core::JSON &schema,\n                        const sourcemeta::core::SchemaFrame &frame,\n                        const sourcemeta::core::JSON &root,\n                        const VisitedSchemas &visited, RefChain &ref_chain)\n    -> sourcemeta::core::JSON {\n  auto result{sourcemeta::core::JSON::make_object()};\n\n  if (schema.is_boolean()) {\n    if (schema.to_boolean()) {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"any\"});\n    } else {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"never\"});\n    }\n    return result;\n  }\n\n  if (!schema.is_object()) {\n    return result;\n  }\n\n  if (schema.defines(\"$ref\") && schema.at(\"$ref\").is_string()) {\n    const auto &destination{schema.at(\"$ref\").to_string()};\n    const auto target{resolve_destination(destination, frame)};\n    if (!target.has_value()) {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"externalRef\"});\n      result.assign(\"url\", sourcemeta::core::JSON{destination});\n      return result;\n    }\n    const auto &target_schema{\n        sourcemeta::core::get(root, target->get().pointer)};\n    const auto visited_entry{visited.find(&target_schema)};\n    if (visited_entry != visited.end()) {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"recursiveRef\"});\n      result.assign(\"identifier\",\n                    sourcemeta::core::JSON{static_cast<std::int64_t>(\n                        visited_entry->second.identifier)});\n      result.assign(\"path\", visited_entry->second.path);\n      return result;\n    }\n\n    if (ref_chain.contains(&target_schema)) {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"any\"});\n      return result;\n    }\n\n    ref_chain.insert(&target_schema);\n    auto ref_result{\n        type_expression_of(target_schema, frame, root, visited, ref_chain)};\n    ref_chain.erase(&target_schema);\n    return ref_result;\n  }\n\n  if (schema.defines(\"$dynamicRef\") && schema.at(\"$dynamicRef\").is_string()) {\n    const auto &value{schema.at(\"$dynamicRef\").to_string()};\n    result.assign(\"kind\", sourcemeta::core::JSON{\"dynamicRef\"});\n    const auto fragment_start{value.find('#')};\n    if (fragment_start != sourcemeta::core::JSON::String::npos) {\n      result.assign(\"anchor\",\n                    sourcemeta::core::JSON{value.substr(fragment_start + 1)});\n    } else {\n      result.assign(\"anchor\", sourcemeta::core::JSON{value});\n    }\n    return result;\n  }\n\n  if (schema.defines(\"enum\") && schema.at(\"enum\").is_array()) {\n    result.assign(\"kind\", sourcemeta::core::JSON{\"enum\"});\n    auto values{sourcemeta::core::JSON::make_array()};\n    auto overflow{sourcemeta::core::JSON::make_array()};\n    std::size_t index{0};\n    for (const auto &value : schema.at(\"enum\").as_array()) {\n      if (index < 10) {\n        values.push_back(value);\n      } else {\n        overflow.push_back(value);\n      }\n      ++index;\n    }\n    result.assign(\"values\", std::move(values));\n    if (!overflow.empty()) {\n      result.assign(\"overflow\", std::move(overflow));\n    }\n    return result;\n  }\n\n  if (!schema.defines(\"type\") || !schema.at(\"type\").is_string()) {\n    result.assign(\"kind\", sourcemeta::core::JSON{\"any\"});\n    return result;\n  }\n\n  {\n    const auto &type{schema.at(\"type\").to_string()};\n    if (type == \"object\") {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"object\"});\n    } else if (type == \"array\") {\n      if (schema.defines(\"prefixItems\") &&\n          schema.at(\"prefixItems\").is_array()) {\n        result.assign(\"kind\", sourcemeta::core::JSON{\"tuple\"});\n        auto items{sourcemeta::core::JSON::make_array()};\n        for (const auto &item : schema.at(\"prefixItems\").as_array()) {\n          items.push_back(\n              type_expression_of(item, frame, root, visited, ref_chain));\n        }\n        result.assign(\"items\", std::move(items));\n        if (schema.defines(\"items\") && schema.at(\"items\").is_object()) {\n          result.assign(\"additional\",\n                        type_expression_of(schema.at(\"items\"), frame, root,\n                                           visited, ref_chain));\n        } else if (schema.defines(\"unevaluatedItems\") &&\n                   schema.at(\"unevaluatedItems\").is_object()) {\n          result.assign(\"additional\",\n                        type_expression_of(schema.at(\"unevaluatedItems\"), frame,\n                                           root, visited, ref_chain));\n        }\n      } else if (schema.defines(\"items\") && schema.at(\"items\").is_array()) {\n        result.assign(\"kind\", sourcemeta::core::JSON{\"tuple\"});\n        auto items{sourcemeta::core::JSON::make_array()};\n        for (const auto &item : schema.at(\"items\").as_array()) {\n          items.push_back(\n              type_expression_of(item, frame, root, visited, ref_chain));\n        }\n        result.assign(\"items\", std::move(items));\n        if (schema.defines(\"additionalItems\") &&\n            schema.at(\"additionalItems\").is_object()) {\n          result.assign(\"additional\",\n                        type_expression_of(schema.at(\"additionalItems\"), frame,\n                                           root, visited, ref_chain));\n        }\n      } else {\n        result.assign(\"kind\", sourcemeta::core::JSON{\"array\"});\n        if (schema.defines(\"items\") && schema.at(\"items\").is_object()) {\n          result.assign(\"items\", type_expression_of(schema.at(\"items\"), frame,\n                                                    root, visited, ref_chain));\n        }\n      }\n    } else if (type == \"string\") {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"primitive\"});\n      result.assign(\"name\", sourcemeta::core::JSON{\"string\"});\n    } else if (type == \"integer\") {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"primitive\"});\n      result.assign(\"name\", sourcemeta::core::JSON{\"integer\"});\n    } else if (type == \"number\") {\n      result.assign(\"kind\", sourcemeta::core::JSON{\"primitive\"});\n      result.assign(\"name\", sourcemeta::core::JSON{\"number\"});\n    }\n  }\n\n  return result;\n}\n\nauto type_expression_of(const sourcemeta::core::JSON &schema,\n                        const sourcemeta::core::SchemaFrame &frame,\n                        const sourcemeta::core::JSON &root,\n                        const VisitedSchemas &visited)\n    -> sourcemeta::core::JSON {\n  RefChain ref_chain;\n  return type_expression_of(schema, frame, root, visited, ref_chain);\n}\n\nauto badges_of(const sourcemeta::core::JSON &schema) -> sourcemeta::core::JSON {\n  auto badges{sourcemeta::core::JSON::make_array()};\n  if (!schema.is_object()) {\n    return badges;\n  }\n  if (schema.defines(\"format\") && schema.at(\"format\").is_string()) {\n    auto badge{sourcemeta::core::JSON::make_object()};\n    badge.assign(\"kind\", sourcemeta::core::JSON{\"format\"});\n    badge.assign(\"value\",\n                 sourcemeta::core::JSON{schema.at(\"format\").to_string()});\n    badges.push_back(std::move(badge));\n  }\n  if (schema.defines(\"contentEncoding\") &&\n      schema.at(\"contentEncoding\").is_string()) {\n    auto badge{sourcemeta::core::JSON::make_object()};\n    badge.assign(\"kind\", sourcemeta::core::JSON{\"encoding\"});\n    badge.assign(\"value\", sourcemeta::core::JSON{\n                              schema.at(\"contentEncoding\").to_string()});\n    badges.push_back(std::move(badge));\n  }\n  if (schema.defines(\"contentMediaType\") &&\n      schema.at(\"contentMediaType\").is_string()) {\n    auto badge{sourcemeta::core::JSON::make_object()};\n    badge.assign(\"kind\", sourcemeta::core::JSON{\"mime\"});\n    badge.assign(\"value\", sourcemeta::core::JSON{\n                              schema.at(\"contentMediaType\").to_string()});\n    badges.push_back(std::move(badge));\n  }\n  return badges;\n}\n\nauto modifiers_of(const sourcemeta::core::JSON &schema)\n    -> sourcemeta::core::JSON {\n  auto modifiers{sourcemeta::core::JSON::make_array()};\n  if (!schema.is_object()) {\n    return modifiers;\n  }\n  if (schema.defines(\"readOnly\") && schema.at(\"readOnly\").is_boolean() &&\n      schema.at(\"readOnly\").to_boolean()) {\n    modifiers.push_back(sourcemeta::core::JSON{\"readOnly\"});\n  }\n  if (schema.defines(\"writeOnly\") && schema.at(\"writeOnly\").is_boolean() &&\n      schema.at(\"writeOnly\").to_boolean()) {\n    modifiers.push_back(sourcemeta::core::JSON{\"writeOnly\"});\n  }\n  if (schema.defines(\"deprecated\") && schema.at(\"deprecated\").is_boolean() &&\n      schema.at(\"deprecated\").to_boolean()) {\n    modifiers.push_back(sourcemeta::core::JSON{\"deprecated\"});\n  }\n  return modifiers;\n}\n\nauto format_json_number(const sourcemeta::core::JSON &value)\n    -> sourcemeta::core::JSON::String {\n  std::ostringstream result;\n  sourcemeta::core::stringify(value, result);\n  return result.str();\n}\n\nauto constraints_of(const sourcemeta::core::JSON &schema)\n    -> sourcemeta::core::JSON {\n  auto constraints{sourcemeta::core::JSON::make_array()};\n  if (!schema.is_object()) {\n    return constraints;\n  }\n\n  const auto has_min_length{schema.defines(\"minLength\") &&\n                            schema.at(\"minLength\").is_integer()};\n  const auto has_max_length{schema.defines(\"maxLength\") &&\n                            schema.at(\"maxLength\").is_integer()};\n  if (has_min_length && has_max_length &&\n      schema.at(\"minLength\") == schema.at(\"maxLength\")) {\n    const auto value{schema.at(\"minLength\").to_integer()};\n    if (value != 0) {\n      constraints.push_back(sourcemeta::core::JSON{\n          \"exactly \" + std::to_string(value) + \" chars\"});\n    }\n  } else {\n    if (has_min_length) {\n      const auto value{schema.at(\"minLength\").to_integer()};\n      if (value > 0) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\">= \" + std::to_string(value) + \" chars\"});\n      }\n    }\n    if (has_max_length) {\n      constraints.push_back(sourcemeta::core::JSON{\n          \"<= \" + std::to_string(schema.at(\"maxLength\").to_integer()) +\n          \" chars\"});\n    }\n  }\n\n  if (schema.defines(\"minimum\") && schema.at(\"minimum\").is_number()) {\n    const auto exclusive{schema.defines(\"exclusiveMinimum\") &&\n                         schema.at(\"exclusiveMinimum\").is_boolean() &&\n                         schema.at(\"exclusiveMinimum\").to_boolean()};\n    constraints.push_back(sourcemeta::core::JSON{\n        (exclusive ? \"> \" : \">= \") + format_json_number(schema.at(\"minimum\"))});\n  }\n  if (schema.defines(\"maximum\") && schema.at(\"maximum\").is_number()) {\n    const auto exclusive{schema.defines(\"exclusiveMaximum\") &&\n                         schema.at(\"exclusiveMaximum\").is_boolean() &&\n                         schema.at(\"exclusiveMaximum\").to_boolean()};\n    constraints.push_back(sourcemeta::core::JSON{\n        (exclusive ? \"< \" : \"<= \") + format_json_number(schema.at(\"maximum\"))});\n  }\n  if (schema.defines(\"exclusiveMinimum\") &&\n      schema.at(\"exclusiveMinimum\").is_number()) {\n    constraints.push_back(sourcemeta::core::JSON{\n        \"> \" + format_json_number(schema.at(\"exclusiveMinimum\"))});\n  }\n  if (schema.defines(\"exclusiveMaximum\") &&\n      schema.at(\"exclusiveMaximum\").is_number()) {\n    constraints.push_back(sourcemeta::core::JSON{\n        \"< \" + format_json_number(schema.at(\"exclusiveMaximum\"))});\n  }\n\n  if (schema.defines(\"multipleOf\") && schema.at(\"multipleOf\").is_number()) {\n    const auto &value{schema.at(\"multipleOf\")};\n    if (!value.is_integer() || value.to_integer() != 1) {\n      constraints.push_back(\n          sourcemeta::core::JSON{\"multiple of \" + format_json_number(value)});\n    }\n  }\n\n  if (schema.defines(\"minItems\") && schema.at(\"minItems\").is_integer()) {\n    const auto value{schema.at(\"minItems\").to_integer()};\n    if (value > 0) {\n      constraints.push_back(\n          sourcemeta::core::JSON{\">= \" + std::to_string(value) + \" items\"});\n    }\n  }\n  if (schema.defines(\"maxItems\") && schema.at(\"maxItems\").is_integer()) {\n    constraints.push_back(sourcemeta::core::JSON{\n        \"<= \" + std::to_string(schema.at(\"maxItems\").to_integer()) + \" items\"});\n  }\n\n  if (schema.defines(\"uniqueItems\") && schema.at(\"uniqueItems\").is_boolean() &&\n      schema.at(\"uniqueItems\").to_boolean()) {\n    constraints.push_back(sourcemeta::core::JSON{\"unique\"});\n  }\n\n  if (schema.defines(\"minProperties\") &&\n      schema.at(\"minProperties\").is_integer()) {\n    const auto value{schema.at(\"minProperties\").to_integer()};\n    if (value > 0) {\n      bool covered_by_required{false};\n      if (schema.defines(\"required\") && schema.at(\"required\").is_array() &&\n          schema.defines(\"properties\") && schema.at(\"properties\").is_object() &&\n          std::cmp_equal(schema.at(\"required\").size(), value)) {\n        covered_by_required = true;\n        for (const auto &req : schema.at(\"required\").as_array()) {\n          if (!req.is_string() ||\n              !schema.at(\"properties\").defines(req.to_string())) {\n            covered_by_required = false;\n            break;\n          }\n        }\n      }\n      if (!covered_by_required) {\n        constraints.push_back(sourcemeta::core::JSON{\n            \">= \" + std::to_string(value) + \" properties\"});\n      }\n    }\n  }\n  if (schema.defines(\"maxProperties\") &&\n      schema.at(\"maxProperties\").is_integer()) {\n    constraints.push_back(sourcemeta::core::JSON{\n        \"<= \" + std::to_string(schema.at(\"maxProperties\").to_integer()) +\n        \" properties\"});\n  }\n\n  if (schema.defines(\"pattern\") && schema.at(\"pattern\").is_string()) {\n    constraints.push_back(\n        sourcemeta::core::JSON{\"pattern: \" + schema.at(\"pattern\").to_string()});\n  }\n\n  const auto has_trivial_contains{schema.defines(\"contains\") &&\n                                  schema.at(\"contains\").is_boolean() &&\n                                  schema.at(\"contains\").to_boolean()};\n\n  if (schema.defines(\"contains\") && schema.at(\"contains\").is_object()) {\n    const auto &contains_schema{schema.at(\"contains\")};\n    const auto is_flat{!contains_schema.defines(\"anyOf\") &&\n                       !contains_schema.defines(\"oneOf\") &&\n                       !contains_schema.defines(\"allOf\") &&\n                       !contains_schema.defines(\"not\") &&\n                       !contains_schema.defines(\"enum\")};\n    if (is_flat) {\n      if (contains_schema.defines(\"type\") &&\n          contains_schema.at(\"type\").is_string()) {\n        constraints.push_back(sourcemeta::core::JSON{\n            \"contains: \" + contains_schema.at(\"type\").to_string()});\n      }\n\n      const auto inner{constraints_of(contains_schema)};\n      for (const auto &constraint : inner.as_array()) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\"contains \" + constraint.to_string()});\n      }\n    }\n  }\n\n  const auto has_min_contains{!has_trivial_contains &&\n                              schema.defines(\"minContains\") &&\n                              schema.at(\"minContains\").is_integer()};\n  const auto has_max_contains{!has_trivial_contains &&\n                              schema.defines(\"maxContains\") &&\n                              schema.at(\"maxContains\").is_integer()};\n  if (has_min_contains && has_max_contains &&\n      schema.at(\"minContains\") == schema.at(\"maxContains\")) {\n    constraints.push_back(sourcemeta::core::JSON{\n        \"exactly \" + std::to_string(schema.at(\"minContains\").to_integer()) +\n        \" matching items\"});\n  } else {\n    if (has_min_contains) {\n      const auto value{schema.at(\"minContains\").to_integer()};\n      if (value == 0) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\"0 or more matching items\"});\n      } else {\n        constraints.push_back(sourcemeta::core::JSON{\n            \">= \" + std::to_string(value) + \" matching items\"});\n      }\n    }\n    if (has_max_contains) {\n      constraints.push_back(sourcemeta::core::JSON{\n          \"<= \" + std::to_string(schema.at(\"maxContains\").to_integer()) +\n          \" matching items\"});\n    }\n  }\n\n  if (schema.defines(\"propertyNames\") &&\n      schema.at(\"propertyNames\").is_object()) {\n    const auto &names_schema{schema.at(\"propertyNames\")};\n    const auto is_branching{\n        names_schema.defines(\"anyOf\") || names_schema.defines(\"oneOf\") ||\n        names_schema.defines(\"allOf\") || names_schema.defines(\"not\")};\n    if (!is_branching) {\n      const auto inner{constraints_of(names_schema)};\n      if (inner.empty() && names_schema.defines(\"type\") &&\n          names_schema.at(\"type\").is_string()) {\n        constraints.push_back(sourcemeta::core::JSON{\n            \"keys: \" + names_schema.at(\"type\").to_string()});\n      }\n\n      for (const auto &constraint : inner.as_array()) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\"keys \" + constraint.to_string()});\n      }\n    }\n  }\n\n  if (schema.defines(\"contentSchema\") &&\n      schema.at(\"contentSchema\").is_object()) {\n    const auto &content_schema{schema.at(\"contentSchema\")};\n    const auto is_branching{\n        content_schema.defines(\"anyOf\") || content_schema.defines(\"oneOf\") ||\n        content_schema.defines(\"allOf\") || content_schema.defines(\"not\")};\n    if (!is_branching) {\n      const auto inner{constraints_of(content_schema)};\n      if (inner.empty() && content_schema.defines(\"type\") &&\n          content_schema.at(\"type\").is_string()) {\n        constraints.push_back(sourcemeta::core::JSON{\n            \"decoded: \" + content_schema.at(\"type\").to_string()});\n      }\n\n      for (const auto &constraint : inner.as_array()) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\"decoded \" + constraint.to_string()});\n      }\n    }\n  }\n\n  if (schema.defines(\"not\") && schema.at(\"not\").is_object()) {\n    const auto &not_schema{schema.at(\"not\")};\n    const auto is_branching{\n        not_schema.defines(\"anyOf\") || not_schema.defines(\"oneOf\") ||\n        not_schema.defines(\"allOf\") || not_schema.defines(\"not\")};\n    if (!is_branching) {\n      const auto inner{constraints_of(not_schema)};\n      for (const auto &constraint : inner.as_array()) {\n        constraints.push_back(\n            sourcemeta::core::JSON{\"must NOT match \" + constraint.to_string()});\n      }\n    }\n  }\n\n  return constraints;\n}\n\nauto is_required_property(const sourcemeta::core::JSON &schema,\n                          const sourcemeta::core::JSON::String &property)\n    -> bool {\n  if (!schema.is_object() || !schema.defines(\"required\") ||\n      !schema.at(\"required\").is_array()) {\n    return false;\n  }\n  for (const auto &item : schema.at(\"required\").as_array()) {\n    if (item.is_string() && item.to_string() == property) {\n      return true;\n    }\n  }\n  return false;\n}\n\nauto make_path_segment(const sourcemeta::core::JSON::String &type,\n                       const sourcemeta::core::JSON::String &value)\n    -> sourcemeta::core::JSON {\n  auto segment{sourcemeta::core::JSON::make_object()};\n  segment.assign(\"type\", sourcemeta::core::JSON{type});\n  segment.assign(\"value\", sourcemeta::core::JSON{value});\n  return segment;\n}\n\nauto make_section(const std::string &label, sourcemeta::core::JSON tables)\n    -> sourcemeta::core::JSON {\n  auto section{sourcemeta::core::JSON::make_object()};\n  section.assign(\"label\", sourcemeta::core::JSON{label});\n  section.assign(\"children\", std::move(tables));\n  return section;\n}\n\nauto walk_schema(const sourcemeta::core::JSON &schema, bool include_root,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                 std::size_t &next_identifier) -> sourcemeta::core::JSON;\n\nauto is_complex_schema(const sourcemeta::core::JSON &schema) -> bool;\n\nauto walk_branching_subschema(const std::string &label,\n                              const std::string &synthetic_name,\n                              const sourcemeta::core::JSON &inner_schema,\n                              sourcemeta::core::JSON &doc_children,\n                              const sourcemeta::core::SchemaFrame &frame,\n                              const sourcemeta::core::JSON &root,\n                              VisitedSchemas &visited,\n                              std::size_t &next_identifier,\n                              bool include_properties) -> void;\n\nauto walk_branches(const std::string &keyword, const std::string &label,\n                   const sourcemeta::core::JSON &schema,\n                   sourcemeta::core::JSON &children,\n                   const sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                   std::size_t &next_identifier) -> void;\n\nauto walk_all_of(const sourcemeta::core::JSON &schema,\n                 sourcemeta::core::JSON &rows, sourcemeta::core::JSON &children,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                 std::size_t &next_identifier) -> void;\n\nauto walk_if_then_else(const sourcemeta::core::JSON &schema,\n                       sourcemeta::core::JSON &children,\n                       const sourcemeta::core::SchemaFrame &frame,\n                       const sourcemeta::core::JSON &root,\n                       VisitedSchemas &visited, std::size_t &next_identifier)\n    -> void;\n\nauto walk_wildcard_keyword(const sourcemeta::core::JSON &schema,\n                           const std::string &keyword,\n                           const sourcemeta::core::JSON &base_path,\n                           sourcemeta::core::JSON &rows,\n                           const sourcemeta::core::SchemaFrame &frame,\n                           const sourcemeta::core::JSON &root,\n                           VisitedSchemas &visited,\n                           std::size_t &next_identifier) -> void;\n\nauto walk_pattern_properties(const sourcemeta::core::JSON &schema,\n                             const sourcemeta::core::JSON &base_path,\n                             sourcemeta::core::JSON &rows,\n                             const sourcemeta::core::SchemaFrame &frame,\n                             const sourcemeta::core::JSON &root,\n                             VisitedSchemas &visited,\n                             std::size_t &next_identifier) -> void;\n\nauto resolve_ref(const sourcemeta::core::JSON &schema,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::JSON &root,\n                 const VisitedSchemas &visited)\n    -> const sourcemeta::core::JSON & {\n  if (schema.is_object() && schema.defines(\"$ref\") &&\n      schema.at(\"$ref\").is_string()) {\n    const auto target{\n        resolve_destination(schema.at(\"$ref\").to_string(), frame)};\n    if (target.has_value()) {\n      const auto &target_schema{\n          sourcemeta::core::get(root, target->get().pointer)};\n      if (visited.find(&target_schema) != visited.end()) {\n        return schema; // NOLINT(bugprone-return-const-ref-from-parameter)\n      }\n      return target_schema;\n    }\n  }\n  return schema; // NOLINT(bugprone-return-const-ref-from-parameter)\n}\n\nauto emit_row(const sourcemeta::core::JSON &schema, sourcemeta::core::JSON path,\n              sourcemeta::core::JSON &rows,\n              const sourcemeta::core::SchemaFrame &frame,\n              const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n              std::size_t &next_identifier,\n              const bool expand_applicators = true) -> void {\n  auto row{sourcemeta::core::JSON::make_object()};\n  row.assign(\"identifier\", sourcemeta::core::JSON{\n                               static_cast<std::int64_t>(next_identifier++)});\n  row.assign(\"path\", std::move(path));\n\n  auto modifiers{modifiers_of(schema)};\n  if (!modifiers.empty()) {\n    row.assign(\"modifiers\", std::move(modifiers));\n  }\n\n  row.assign(\"type\", type_expression_of(schema, frame, root, visited));\n\n  auto badges{badges_of(schema)};\n  if (!badges.empty()) {\n    row.assign(\"badges\", std::move(badges));\n  }\n\n  auto constraints{constraints_of(schema)};\n  if (!constraints.empty()) {\n    row.assign(\"constraints\", std::move(constraints));\n  }\n\n  if (schema.is_object()) {\n    if (schema.defines(\"title\") && schema.at(\"title\").is_string()) {\n      row.assign(\"title\",\n                 sourcemeta::core::JSON{schema.at(\"title\").to_string()});\n    }\n    if (schema.defines(\"description\") && schema.at(\"description\").is_string()) {\n      row.assign(\"description\",\n                 sourcemeta::core::JSON{schema.at(\"description\").to_string()});\n    }\n    if (schema.defines(\"default\")) {\n      row.assign(\"default\", schema.at(\"default\"));\n    }\n    if (schema.defines(\"examples\") && schema.at(\"examples\").is_array()) {\n      auto examples{sourcemeta::core::JSON::make_array()};\n      for (const auto &example : schema.at(\"examples\").as_array()) {\n        examples.push_back(example);\n      }\n      row.assign(\"examples\", std::move(examples));\n    }\n  }\n\n  if (expand_applicators && is_complex_schema(schema)) {\n    auto row_children{sourcemeta::core::JSON::make_array()};\n    walk_branches(\"anyOf\", \"Any of\", schema, row_children, frame, root, visited,\n                  next_identifier);\n    walk_branches(\"oneOf\", \"One of\", schema, row_children, frame, root, visited,\n                  next_identifier);\n    walk_all_of(schema, rows, row_children, frame, root, visited,\n                next_identifier);\n    walk_if_then_else(schema, row_children, frame, root, visited,\n                      next_identifier);\n    if (schema.is_object() && schema.defines(\"not\")) {\n      const auto &not_schema{schema.at(\"not\")};\n      const auto has_inline{\n          not_schema.is_object() &&\n          !(not_schema.defines(\"anyOf\") || not_schema.defines(\"oneOf\") ||\n            not_schema.defines(\"allOf\") || not_schema.defines(\"not\")) &&\n          !constraints_of(not_schema).empty()};\n      if (!has_inline) {\n        walk_branching_subschema(\"Must NOT match\", \"value\", not_schema,\n                                 row_children, frame, root, visited,\n                                 next_identifier, false);\n      }\n    }\n    if (!row_children.empty()) {\n      row.assign(\"children\", std::move(row_children));\n    }\n  }\n\n  rows.push_back(std::move(row));\n}\n\nauto walk_properties(const sourcemeta::core::JSON &schema,\n                     const sourcemeta::core::JSON &base_path,\n                     sourcemeta::core::JSON &rows,\n                     const sourcemeta::core::SchemaFrame &frame,\n                     const sourcemeta::core::JSON &root,\n                     VisitedSchemas &visited, std::size_t &next_identifier)\n    -> void {\n  if (!schema.is_object() || !schema.defines(\"properties\") ||\n      !schema.at(\"properties\").is_object()) {\n    return;\n  }\n\n  for (const auto &entry : schema.at(\"properties\").as_object()) {\n    const auto &resolved{resolve_ref(entry.second, frame, root, visited)};\n    auto path{base_path};\n    path.push_back(make_path_segment(\"literal\", entry.first));\n\n    auto row{sourcemeta::core::JSON::make_object()};\n    row.assign(\"identifier\", sourcemeta::core::JSON{\n                                 static_cast<std::int64_t>(next_identifier++)});\n    row.assign(\"path\", path);\n\n    auto modifiers{modifiers_of(resolved)};\n    if (!modifiers.empty()) {\n      row.assign(\"modifiers\", std::move(modifiers));\n    }\n\n    row.assign(\"type\", type_expression_of(resolved, frame, root, visited));\n\n    auto badges{badges_of(resolved)};\n    if (!badges.empty()) {\n      row.assign(\"badges\", std::move(badges));\n    }\n\n    row.assign(\"required\", sourcemeta::core::JSON{\n                               is_required_property(schema, entry.first)});\n\n    auto constraints{constraints_of(resolved)};\n    if (!constraints.empty()) {\n      row.assign(\"constraints\", std::move(constraints));\n    }\n\n    if (resolved.is_object()) {\n      if (resolved.defines(\"title\") && resolved.at(\"title\").is_string()) {\n        row.assign(\"title\",\n                   sourcemeta::core::JSON{resolved.at(\"title\").to_string()});\n      }\n      if (resolved.defines(\"description\") &&\n          resolved.at(\"description\").is_string()) {\n        row.assign(\"description\", sourcemeta::core::JSON{\n                                      resolved.at(\"description\").to_string()});\n      }\n      if (resolved.defines(\"default\")) {\n        row.assign(\"default\", resolved.at(\"default\"));\n      }\n      if (resolved.defines(\"examples\") && resolved.at(\"examples\").is_array()) {\n        auto examples{sourcemeta::core::JSON::make_array()};\n        for (const auto &example : resolved.at(\"examples\").as_array()) {\n          examples.push_back(example);\n        }\n        row.assign(\"examples\", std::move(examples));\n      }\n    }\n\n    const auto row_identifier{\n        static_cast<std::size_t>(row.at(\"identifier\").to_integer())};\n\n    if (is_complex_schema(resolved)) {\n      auto prop_children{sourcemeta::core::JSON::make_array()};\n      walk_branches(\"anyOf\", \"Any of\", resolved, prop_children, frame, root,\n                    visited, next_identifier);\n      walk_branches(\"oneOf\", \"One of\", resolved, prop_children, frame, root,\n                    visited, next_identifier);\n      walk_all_of(resolved, rows, prop_children, frame, root, visited,\n                  next_identifier);\n      walk_if_then_else(resolved, prop_children, frame, root, visited,\n                        next_identifier);\n      if (resolved.defines(\"not\")) {\n        const auto &not_schema{resolved.at(\"not\")};\n        const auto has_inline{\n            not_schema.is_object() &&\n            !(not_schema.defines(\"anyOf\") || not_schema.defines(\"oneOf\") ||\n              not_schema.defines(\"allOf\") || not_schema.defines(\"not\")) &&\n            !constraints_of(not_schema).empty()};\n        if (!has_inline) {\n          walk_branching_subschema(\"Must NOT match\", \"value\", not_schema,\n                                   prop_children, frame, root, visited,\n                                   next_identifier, false);\n        }\n      }\n      if (!prop_children.empty()) {\n        row.assign(\"children\", std::move(prop_children));\n      }\n    }\n\n    rows.push_back(std::move(row));\n\n    if (resolved.is_object() && resolved.defines(\"type\") &&\n        resolved.at(\"type\").is_string()) {\n      const auto &resolved_type{resolved.at(\"type\").to_string()};\n      if (resolved_type == \"object\") {\n        visited.emplace(&resolved, VisitedEntry{.identifier = row_identifier,\n                                                .path = path});\n        walk_properties(resolved, path, rows, frame, root, visited,\n                        next_identifier);\n        walk_pattern_properties(resolved, path, rows, frame, root, visited,\n                                next_identifier);\n        walk_wildcard_keyword(resolved, \"additionalProperties\", path, rows,\n                              frame, root, visited, next_identifier);\n        walk_wildcard_keyword(resolved, \"unevaluatedProperties\", path, rows,\n                              frame, root, visited, next_identifier);\n        if (!resolved.defines(\"additionalProperties\") &&\n            !resolved.defines(\"unevaluatedProperties\")) {\n          auto open_path{path};\n          open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n          emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows,\n                   frame, root, visited, next_identifier);\n        }\n        visited.erase(&resolved);\n      } else if (resolved_type == \"array\" && resolved.defines(\"items\") &&\n                 resolved.at(\"items\").is_object() &&\n                 !resolved.defines(\"prefixItems\")) {\n        const auto &items_schema{\n            resolve_ref(resolved.at(\"items\"), frame, root, visited)};\n        if (items_schema.is_object()) {\n          auto wildcard_path{path};\n          wildcard_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n          const auto items_row_id{next_identifier};\n          emit_row(items_schema, wildcard_path, rows, frame, root, visited,\n                   next_identifier);\n          if (items_schema.defines(\"type\") &&\n              items_schema.at(\"type\").is_string() &&\n              items_schema.at(\"type\").to_string() == \"object\") {\n            visited.emplace(&items_schema,\n                            VisitedEntry{.identifier = items_row_id,\n                                         .path = wildcard_path});\n            walk_properties(items_schema, wildcard_path, rows, frame, root,\n                            visited, next_identifier);\n            walk_pattern_properties(items_schema, wildcard_path, rows, frame,\n                                    root, visited, next_identifier);\n            walk_wildcard_keyword(items_schema, \"additionalProperties\",\n                                  wildcard_path, rows, frame, root, visited,\n                                  next_identifier);\n            walk_wildcard_keyword(items_schema, \"unevaluatedProperties\",\n                                  wildcard_path, rows, frame, root, visited,\n                                  next_identifier);\n            if (!items_schema.defines(\"additionalProperties\") &&\n                !items_schema.defines(\"unevaluatedProperties\")) {\n              auto open_path{wildcard_path};\n              open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n              emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows,\n                       frame, root, visited, next_identifier);\n            }\n            visited.erase(&items_schema);\n          }\n        }\n      }\n    }\n  }\n}\n\nauto walk_wildcard_keyword(const sourcemeta::core::JSON &schema,\n                           const std::string &keyword,\n                           const sourcemeta::core::JSON &base_path,\n                           sourcemeta::core::JSON &rows,\n                           const sourcemeta::core::SchemaFrame &frame,\n                           const sourcemeta::core::JSON &root,\n                           VisitedSchemas &visited,\n                           std::size_t &next_identifier) -> void {\n  if (!schema.is_object() || !schema.defines(keyword)) {\n    return;\n  }\n\n  const auto &value{schema.at(keyword)};\n\n  if (keyword == \"unevaluatedItems\" && schema.defines(\"prefixItems\")) {\n    return;\n  }\n\n  if (value.is_boolean() && value.to_boolean()) {\n    auto path{base_path};\n    path.push_back(make_path_segment(\"wildcard\", \"*\"));\n    emit_row(value, std::move(path), rows, frame, root, visited,\n             next_identifier);\n    return;\n  }\n\n  if (!value.is_object()) {\n    return;\n  }\n\n  auto path{base_path};\n  path.push_back(make_path_segment(\"wildcard\", \"*\"));\n  const auto wildcard_row_id{next_identifier};\n  emit_row(value, path, rows, frame, root, visited, next_identifier);\n\n  if (value.defines(\"type\") && value.at(\"type\").is_string() &&\n      value.at(\"type\").to_string() == \"object\") {\n    visited.emplace(&value,\n                    VisitedEntry{.identifier = wildcard_row_id, .path = path});\n    walk_properties(value, path, rows, frame, root, visited, next_identifier);\n    walk_pattern_properties(value, path, rows, frame, root, visited,\n                            next_identifier);\n    walk_wildcard_keyword(value, \"additionalProperties\", path, rows, frame,\n                          root, visited, next_identifier);\n    walk_wildcard_keyword(value, \"unevaluatedProperties\", path, rows, frame,\n                          root, visited, next_identifier);\n    if (!value.defines(\"additionalProperties\") &&\n        !value.defines(\"unevaluatedProperties\")) {\n      auto open_path{path};\n      open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n      emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows, frame,\n               root, visited, next_identifier);\n    }\n    visited.erase(&value);\n  } else if (value.defines(\"type\") && value.at(\"type\").is_string() &&\n             value.at(\"type\").to_string() == \"array\" &&\n             value.defines(\"items\") && value.at(\"items\").is_object() &&\n             !value.defines(\"prefixItems\")) {\n    const auto &items_schema{\n        resolve_ref(value.at(\"items\"), frame, root, visited)};\n    if (items_schema.is_object()) {\n      auto items_path{path};\n      items_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n      const auto items_row_id{next_identifier};\n      emit_row(items_schema, items_path, rows, frame, root, visited,\n               next_identifier);\n      if (items_schema.defines(\"type\") && items_schema.at(\"type\").is_string() &&\n          items_schema.at(\"type\").to_string() == \"object\") {\n        visited.emplace(&items_schema, VisitedEntry{.identifier = items_row_id,\n                                                    .path = items_path});\n        walk_properties(items_schema, items_path, rows, frame, root, visited,\n                        next_identifier);\n        walk_pattern_properties(items_schema, items_path, rows, frame, root,\n                                visited, next_identifier);\n        walk_wildcard_keyword(items_schema, \"additionalProperties\", items_path,\n                              rows, frame, root, visited, next_identifier);\n        walk_wildcard_keyword(items_schema, \"unevaluatedProperties\", items_path,\n                              rows, frame, root, visited, next_identifier);\n        if (!items_schema.defines(\"additionalProperties\") &&\n            !items_schema.defines(\"unevaluatedProperties\")) {\n          auto open_path{items_path};\n          open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n          emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows,\n                   frame, root, visited, next_identifier);\n        }\n        visited.erase(&items_schema);\n      }\n    }\n  }\n}\n\nauto walk_pattern_properties(const sourcemeta::core::JSON &schema,\n                             const sourcemeta::core::JSON &base_path,\n                             sourcemeta::core::JSON &rows,\n                             const sourcemeta::core::SchemaFrame &frame,\n                             const sourcemeta::core::JSON &root,\n                             VisitedSchemas &visited,\n                             std::size_t &next_identifier) -> void {\n  if (!schema.is_object() || !schema.defines(\"patternProperties\") ||\n      !schema.at(\"patternProperties\").is_object()) {\n    return;\n  }\n\n  for (const auto &entry : schema.at(\"patternProperties\").as_object()) {\n    const auto &resolved{resolve_ref(entry.second, frame, root, visited)};\n    auto path{base_path};\n    path.push_back(make_path_segment(\"pattern\", entry.first));\n\n    const auto row_id{next_identifier};\n    emit_row(resolved, path, rows, frame, root, visited, next_identifier);\n\n    if (resolved.is_object() && resolved.defines(\"type\") &&\n        resolved.at(\"type\").is_string() &&\n        resolved.at(\"type\").to_string() == \"object\") {\n      visited.emplace(&resolved,\n                      VisitedEntry{.identifier = row_id, .path = path});\n      walk_properties(resolved, path, rows, frame, root, visited,\n                      next_identifier);\n      walk_pattern_properties(resolved, path, rows, frame, root, visited,\n                              next_identifier);\n      walk_wildcard_keyword(resolved, \"additionalProperties\", path, rows, frame,\n                            root, visited, next_identifier);\n      walk_wildcard_keyword(resolved, \"unevaluatedProperties\", path, rows,\n                            frame, root, visited, next_identifier);\n      if (!resolved.defines(\"additionalProperties\") &&\n          !resolved.defines(\"unevaluatedProperties\")) {\n        auto open_path{path};\n        open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n        emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows,\n                 frame, root, visited, next_identifier);\n      }\n      visited.erase(&resolved);\n    }\n  }\n}\n\nauto is_complex_schema(const sourcemeta::core::JSON &schema) -> bool {\n  if (!schema.is_object()) {\n    return false;\n  }\n  return schema.defines(\"properties\") || schema.defines(\"anyOf\") ||\n         schema.defines(\"oneOf\") || schema.defines(\"allOf\") ||\n         schema.defines(\"not\") || schema.defines(\"if\") ||\n         schema.defines(\"prefixItems\") || schema.defines(\"contains\") ||\n         schema.defines(\"patternProperties\") ||\n         schema.defines(\"additionalProperties\") ||\n         schema.defines(\"propertyNames\") || schema.defines(\"contentSchema\");\n}\n\nauto walk_prefix_items(const sourcemeta::core::JSON &schema,\n                       const sourcemeta::core::JSON &base_path,\n                       sourcemeta::core::JSON &rows,\n                       sourcemeta::core::JSON &children,\n                       const sourcemeta::core::SchemaFrame &frame,\n                       const sourcemeta::core::JSON &root,\n                       VisitedSchemas &visited, std::size_t &next_identifier)\n    -> void {\n  const auto has_prefix_items{schema.is_object() &&\n                              schema.defines(\"prefixItems\") &&\n                              schema.at(\"prefixItems\").is_array()};\n  const auto has_draft4_tuple{!has_prefix_items && schema.is_object() &&\n                              schema.defines(\"items\") &&\n                              schema.at(\"items\").is_array()};\n  if (!has_prefix_items && !has_draft4_tuple) {\n    return;\n  }\n\n  const auto &tuple_items{has_prefix_items ? schema.at(\"prefixItems\")\n                                           : schema.at(\"items\")};\n\n  std::size_t min_items{0};\n  if (schema.defines(\"minItems\") && schema.at(\"minItems\").is_integer() &&\n      schema.at(\"minItems\").to_integer() > 0) {\n    min_items = static_cast<std::size_t>(schema.at(\"minItems\").to_integer());\n  }\n\n  std::size_t index{0};\n  for (const auto &item : tuple_items.as_array()) {\n    if (is_complex_schema(item)) {\n      auto section_children{sourcemeta::core::JSON::make_array()};\n      section_children.push_back(\n          walk_schema(item, true, frame, root, visited, next_identifier));\n      children.push_back(make_section(\"Array item \" + std::to_string(index),\n                                      std::move(section_children)));\n    } else {\n      auto path{base_path};\n      path.push_back(make_path_segment(\"literal\", std::to_string(index)));\n\n      auto row{sourcemeta::core::JSON::make_object()};\n      row.assign(\"identifier\", sourcemeta::core::JSON{static_cast<std::int64_t>(\n                                   next_identifier++)});\n      row.assign(\"path\", std::move(path));\n\n      auto modifiers{modifiers_of(item)};\n      if (!modifiers.empty()) {\n        row.assign(\"modifiers\", std::move(modifiers));\n      }\n\n      row.assign(\"type\", type_expression_of(item, frame, root, visited));\n\n      auto badges{badges_of(item)};\n      if (!badges.empty()) {\n        row.assign(\"badges\", std::move(badges));\n      }\n\n      row.assign(\"required\", sourcemeta::core::JSON{index < min_items});\n\n      auto constraints{constraints_of(item)};\n      if (!constraints.empty()) {\n        row.assign(\"constraints\", std::move(constraints));\n      }\n\n      if (item.is_object()) {\n        if (item.defines(\"title\") && item.at(\"title\").is_string()) {\n          row.assign(\"title\",\n                     sourcemeta::core::JSON{item.at(\"title\").to_string()});\n        }\n        if (item.defines(\"description\") && item.at(\"description\").is_string()) {\n          row.assign(\"description\", sourcemeta::core::JSON{\n                                        item.at(\"description\").to_string()});\n        }\n        if (item.defines(\"default\")) {\n          row.assign(\"default\", item.at(\"default\"));\n        }\n        if (item.defines(\"examples\") && item.at(\"examples\").is_array()) {\n          auto examples{sourcemeta::core::JSON::make_array()};\n          for (const auto &example : item.at(\"examples\").as_array()) {\n            examples.push_back(example);\n          }\n          row.assign(\"examples\", std::move(examples));\n        }\n      }\n\n      rows.push_back(std::move(row));\n    }\n    ++index;\n  }\n\n  if (has_prefix_items && schema.defines(\"items\") &&\n      schema.at(\"items\").is_object()) {\n    auto path{base_path};\n    path.push_back(make_path_segment(\"wildcard\", \"*\"));\n    emit_row(schema.at(\"items\"), std::move(path), rows, frame, root, visited,\n             next_identifier);\n  } else if (has_draft4_tuple && schema.defines(\"additionalItems\") &&\n             schema.at(\"additionalItems\").is_object()) {\n    auto path{base_path};\n    path.push_back(make_path_segment(\"wildcard\", \"*\"));\n    emit_row(schema.at(\"additionalItems\"), std::move(path), rows, frame, root,\n             visited, next_identifier);\n  }\n}\n\nauto walk_branches(const std::string &keyword, const std::string &label,\n                   const sourcemeta::core::JSON &schema,\n                   sourcemeta::core::JSON &children,\n                   const sourcemeta::core::SchemaFrame &frame,\n                   const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                   std::size_t &next_identifier) -> void {\n  if (!schema.is_object() || !schema.defines(keyword) ||\n      !schema.at(keyword).is_array()) {\n    return;\n  }\n\n  auto section_children{sourcemeta::core::JSON::make_array()};\n  for (const auto &branch : schema.at(keyword).as_array()) {\n    section_children.push_back(\n        walk_schema(branch, false, frame, root, visited, next_identifier));\n  }\n  children.push_back(make_section(label, std::move(section_children)));\n}\n\nauto has_recursive_ref_in_rows(const sourcemeta::core::JSON &rows) -> bool {\n  for (const auto &row : rows.as_array()) {\n    const auto &type{row.at(\"type\")};\n    if (type.defines(\"kind\") && type.at(\"kind\").to_string() == \"recursiveRef\") {\n      return true;\n    }\n    if (type.defines(\"kind\") && type.at(\"kind\").to_string() == \"array\" &&\n        type.defines(\"items\")) {\n      const auto &items{type.at(\"items\")};\n      if (items.is_object() && items.defines(\"kind\") &&\n          items.at(\"kind\").to_string() == \"recursiveRef\") {\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\nauto walk_all_of(const sourcemeta::core::JSON &schema,\n                 sourcemeta::core::JSON &rows, sourcemeta::core::JSON &children,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                 std::size_t &next_identifier) -> void {\n  if (!schema.is_object() || !schema.defines(\"allOf\") ||\n      !schema.at(\"allOf\").is_array()) {\n    return;\n  }\n\n  const auto &all_of{schema.at(\"allOf\").as_array()};\n\n  if (all_of.size() == 1) {\n    auto branch{walk_schema(schema.at(\"allOf\").at(0), false, frame, root,\n                            visited, next_identifier)};\n    const auto &branch_rows{branch.at(\"rows\")};\n    const auto branch_has_recursive_ref{has_recursive_ref_in_rows(branch_rows)};\n\n    if (!branch_has_recursive_ref) {\n      // Merge the branch's root row info into the parent's root row\n      if (!rows.empty() && !branch_rows.empty()) {\n        const auto &parent_last_type{rows.at(rows.size() - 1).at(\"type\")};\n        const auto &branch_first{branch_rows.at(0)};\n        const auto parent_is_any{parent_last_type.defines(\"kind\") &&\n                                 parent_last_type.at(\"kind\").to_string() ==\n                                     \"any\"};\n        const auto &branch_first_path{branch_first.at(\"path\")};\n        const auto branch_first_is_synthetic_root{\n            !branch_first_path.empty() &&\n            branch_first_path.at(0).at(\"type\").to_string() == \"synthetic\" &&\n            branch_first_path.at(0).at(\"value\").to_string() == \"root\"};\n\n        if (parent_is_any && branch_first_is_synthetic_root) {\n          // Copy fields from branch root into parent root\n          auto &parent_root{rows.at(rows.size() - 1)};\n          parent_root.assign(\"type\", branch_first.at(\"type\"));\n\n          if (branch_first.defines(\"constraints\")) {\n            parent_root.assign(\"constraints\", branch_first.at(\"constraints\"));\n          } else if (parent_root.defines(\"constraints\")) {\n            parent_root.erase(\"constraints\");\n          }\n\n          if (branch_first.defines(\"title\") && !parent_root.defines(\"title\")) {\n            parent_root.assign(\"title\", branch_first.at(\"title\"));\n          }\n          if (branch_first.defines(\"description\") &&\n              !parent_root.defines(\"description\")) {\n            parent_root.assign(\"description\", branch_first.at(\"description\"));\n          }\n          if (branch_first.defines(\"default\") &&\n              !parent_root.defines(\"default\")) {\n            parent_root.assign(\"default\", branch_first.at(\"default\"));\n          }\n\n          if (branch_first.defines(\"modifiers\")) {\n            parent_root.assign(\"modifiers\", branch_first.at(\"modifiers\"));\n          } else if (parent_root.defines(\"modifiers\")) {\n            parent_root.erase(\"modifiers\");\n          }\n\n          if (branch_first.defines(\"badges\")) {\n            parent_root.assign(\"badges\", branch_first.at(\"badges\"));\n          } else if (parent_root.defines(\"badges\")) {\n            parent_root.erase(\"badges\");\n          }\n\n          for (std::size_t index = 1; index < branch_rows.size(); ++index) {\n            rows.push_back(branch_rows.at(index));\n          }\n        } else {\n          for (const auto &row : branch_rows.as_array()) {\n            rows.push_back(row);\n          }\n        }\n      } else {\n        for (const auto &row : branch_rows.as_array()) {\n          rows.push_back(row);\n        }\n      }\n\n      if (branch.defines(\"children\")) {\n        for (const auto &child : branch.at(\"children\").as_array()) {\n          children.push_back(child);\n        }\n      }\n      return;\n    }\n\n    auto section_children{sourcemeta::core::JSON::make_array()};\n    section_children.push_back(std::move(branch));\n    children.push_back(make_section(\"All of\", std::move(section_children)));\n    return;\n  }\n\n  auto section_children{sourcemeta::core::JSON::make_array()};\n  for (const auto &branch : all_of) {\n    section_children.push_back(\n        walk_schema(branch, false, frame, root, visited, next_identifier));\n  }\n  children.push_back(make_section(\"All of\", std::move(section_children)));\n}\n\nauto walk_if_then_else(const sourcemeta::core::JSON &schema,\n                       sourcemeta::core::JSON &children,\n                       const sourcemeta::core::SchemaFrame &frame,\n                       const sourcemeta::core::JSON &root,\n                       VisitedSchemas &visited, std::size_t &next_identifier)\n    -> void {\n  if (!schema.is_object() || !schema.defines(\"if\") || !schema.defines(\"then\") ||\n      !schema.defines(\"else\")) {\n    return;\n  }\n\n  {\n    auto section_children{sourcemeta::core::JSON::make_array()};\n    section_children.push_back(walk_schema(schema.at(\"if\"), false, frame, root,\n                                           visited, next_identifier));\n    children.push_back(make_section(\"If\", std::move(section_children)));\n  }\n\n  {\n    auto section_children{sourcemeta::core::JSON::make_array()};\n    section_children.push_back(walk_schema(schema.at(\"then\"), false, frame,\n                                           root, visited, next_identifier));\n    children.push_back(make_section(\"Then\", std::move(section_children)));\n  }\n\n  {\n    auto section_children{sourcemeta::core::JSON::make_array()};\n    section_children.push_back(walk_schema(schema.at(\"else\"), false, frame,\n                                           root, visited, next_identifier));\n    children.push_back(make_section(\"Else\", std::move(section_children)));\n  }\n}\n\nauto walk_branching_subschema(const std::string &label,\n                              const std::string &synthetic_name,\n                              const sourcemeta::core::JSON &inner_schema,\n                              sourcemeta::core::JSON &doc_children,\n                              const sourcemeta::core::SchemaFrame &frame,\n                              const sourcemeta::core::JSON &root,\n                              VisitedSchemas &visited,\n                              std::size_t &next_identifier,\n                              const bool include_properties) -> void {\n  auto table{sourcemeta::core::JSON::make_object()};\n  table.assign(\"identifier\", sourcemeta::core::JSON{\n                                 static_cast<std::int64_t>(next_identifier++)});\n  auto table_rows{sourcemeta::core::JSON::make_array()};\n  auto table_children{sourcemeta::core::JSON::make_array()};\n  auto synthetic_path{sourcemeta::core::JSON::make_array()};\n  synthetic_path.push_back(make_path_segment(\"synthetic\", synthetic_name));\n  if (include_properties) {\n    walk_properties(inner_schema, synthetic_path, table_rows, frame, root,\n                    visited, next_identifier);\n  }\n  emit_row(inner_schema, std::move(synthetic_path), table_rows, frame, root,\n           visited, next_identifier, false);\n  walk_branches(\"anyOf\", \"Any of\", inner_schema, table_children, frame, root,\n                visited, next_identifier);\n  walk_branches(\"oneOf\", \"One of\", inner_schema, table_children, frame, root,\n                visited, next_identifier);\n  walk_all_of(inner_schema, table_rows, table_children, frame, root, visited,\n              next_identifier);\n  table.assign(\"rows\", std::move(table_rows));\n  if (!table_children.empty()) {\n    table.assign(\"children\", std::move(table_children));\n  }\n  auto section_children{sourcemeta::core::JSON::make_array()};\n  section_children.push_back(std::move(table));\n  doc_children.push_back(make_section(label, std::move(section_children)));\n}\n\nauto walk_schema(const sourcemeta::core::JSON &schema, const bool include_root,\n                 const sourcemeta::core::SchemaFrame &frame,\n                 const sourcemeta::core::JSON &root, VisitedSchemas &visited,\n                 std::size_t &next_identifier) -> sourcemeta::core::JSON {\n  if (schema.is_object() && schema.defines(\"$ref\") &&\n      schema.at(\"$ref\").is_string()) {\n    const auto target{\n        resolve_destination(schema.at(\"$ref\").to_string(), frame)};\n    if (target.has_value()) {\n      const auto &target_schema{\n          sourcemeta::core::get(root, target->get().pointer)};\n      const auto visited_entry{visited.find(&target_schema)};\n      if (visited_entry != visited.end()) {\n        auto documentation{sourcemeta::core::JSON::make_object()};\n        documentation.assign(\"identifier\",\n                             sourcemeta::core::JSON{\n                                 static_cast<std::int64_t>(next_identifier++)});\n        auto rows{sourcemeta::core::JSON::make_array()};\n        auto row{sourcemeta::core::JSON::make_object()};\n        row.assign(\"identifier\",\n                   sourcemeta::core::JSON{\n                       static_cast<std::int64_t>(next_identifier++)});\n        auto path{sourcemeta::core::JSON::make_array()};\n        path.push_back(make_path_segment(\"synthetic\", \"root\"));\n        row.assign(\"path\", std::move(path));\n        auto type_expr{sourcemeta::core::JSON::make_object()};\n        type_expr.assign(\"kind\", sourcemeta::core::JSON{\"recursiveRef\"});\n        type_expr.assign(\"identifier\",\n                         sourcemeta::core::JSON{static_cast<std::int64_t>(\n                             visited_entry->second.identifier)});\n        type_expr.assign(\"path\", visited_entry->second.path);\n        row.assign(\"type\", std::move(type_expr));\n        rows.push_back(std::move(row));\n        documentation.assign(\"rows\", std::move(rows));\n        return documentation;\n      }\n      auto ref_path{sourcemeta::core::JSON::make_array()};\n      ref_path.push_back(make_path_segment(\"synthetic\", \"root\"));\n      visited.emplace(&target_schema,\n                      VisitedEntry{.identifier = next_identifier,\n                                   .path = std::move(ref_path)});\n      auto result{walk_schema(target_schema, include_root, frame, root, visited,\n                              next_identifier)};\n      visited.erase(&target_schema);\n      return result;\n    }\n  }\n\n  auto documentation{sourcemeta::core::JSON::make_object()};\n  const auto doc_identifier{next_identifier++};\n  documentation.assign(\n      \"identifier\",\n      sourcemeta::core::JSON{static_cast<std::int64_t>(doc_identifier)});\n\n  if (schema.is_object() && schema.defines(\"$dynamicAnchor\") &&\n      schema.at(\"$dynamicAnchor\").is_string()) {\n    documentation.assign(\n        \"dynamicAnchor\",\n        sourcemeta::core::JSON{schema.at(\"$dynamicAnchor\").to_string()});\n  }\n\n  auto rows{sourcemeta::core::JSON::make_array()};\n  auto doc_children{sourcemeta::core::JSON::make_array()};\n\n  if (include_root) {\n    auto root_path{sourcemeta::core::JSON::make_array()};\n    root_path.push_back(make_path_segment(\"synthetic\", \"root\"));\n    emit_row(schema, std::move(root_path), rows, frame, root, visited,\n             next_identifier, false);\n    const auto root_row_identifier{static_cast<std::size_t>(\n        rows.at(rows.size() - 1).at(\"identifier\").to_integer())};\n    auto visited_root_path{sourcemeta::core::JSON::make_array()};\n    visited_root_path.push_back(make_path_segment(\"synthetic\", \"root\"));\n    visited.emplace(&schema,\n                    VisitedEntry{.identifier = root_row_identifier,\n                                 .path = std::move(visited_root_path)});\n  }\n\n  if (!schema.is_object()) {\n    if (!include_root) {\n      auto root_path{sourcemeta::core::JSON::make_array()};\n      root_path.push_back(make_path_segment(\"synthetic\", \"root\"));\n      emit_row(schema, std::move(root_path), rows, frame, root, visited,\n               next_identifier, false);\n    }\n    documentation.assign(\"rows\", std::move(rows));\n    return documentation;\n  }\n\n  if (!include_root) {\n    auto root_path{sourcemeta::core::JSON::make_array()};\n    root_path.push_back(make_path_segment(\"synthetic\", \"root\"));\n    emit_row(schema, std::move(root_path), rows, frame, root, visited,\n             next_identifier, false);\n  }\n\n  const auto empty_path{sourcemeta::core::JSON::make_array()};\n  walk_properties(schema, empty_path, rows, frame, root, visited,\n                  next_identifier);\n  walk_pattern_properties(schema, empty_path, rows, frame, root, visited,\n                          next_identifier);\n  walk_wildcard_keyword(schema, \"additionalProperties\", empty_path, rows, frame,\n                        root, visited, next_identifier);\n  if (schema.defines(\"type\") && schema.at(\"type\").is_string() &&\n      schema.at(\"type\").to_string() == \"object\" &&\n      !schema.defines(\"additionalProperties\") &&\n      !schema.defines(\"unevaluatedProperties\")) {\n    auto open_path{empty_path};\n    open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n    emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows, frame,\n             root, visited, next_identifier);\n  }\n  walk_prefix_items(schema, empty_path, rows, doc_children, frame, root,\n                    visited, next_identifier);\n\n  if (schema.is_object() && schema.defines(\"items\") &&\n      schema.at(\"items\").is_object() && !schema.defines(\"prefixItems\")) {\n    const auto &items_schema{\n        resolve_ref(schema.at(\"items\"), frame, root, visited)};\n    if (items_schema.is_object()) {\n      auto wildcard_path{sourcemeta::core::JSON::make_array()};\n      wildcard_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n      const auto items_row_id{next_identifier};\n      emit_row(items_schema, wildcard_path, rows, frame, root, visited,\n               next_identifier);\n      if (items_schema.defines(\"type\") && items_schema.at(\"type\").is_string() &&\n          items_schema.at(\"type\").to_string() == \"object\") {\n        visited.emplace(&items_schema, VisitedEntry{.identifier = items_row_id,\n                                                    .path = wildcard_path});\n        walk_properties(items_schema, wildcard_path, rows, frame, root, visited,\n                        next_identifier);\n        walk_pattern_properties(items_schema, wildcard_path, rows, frame, root,\n                                visited, next_identifier);\n        walk_wildcard_keyword(items_schema, \"additionalProperties\",\n                              wildcard_path, rows, frame, root, visited,\n                              next_identifier);\n        walk_wildcard_keyword(items_schema, \"unevaluatedProperties\",\n                              wildcard_path, rows, frame, root, visited,\n                              next_identifier);\n        if (!items_schema.defines(\"additionalProperties\") &&\n            !items_schema.defines(\"unevaluatedProperties\")) {\n          auto open_path{wildcard_path};\n          open_path.push_back(make_path_segment(\"wildcard\", \"*\"));\n          emit_row(sourcemeta::core::JSON{true}, std::move(open_path), rows,\n                   frame, root, visited, next_identifier);\n        }\n        visited.erase(&items_schema);\n      }\n    }\n  }\n\n  walk_branches(\"anyOf\", \"Any of\", schema, doc_children, frame, root, visited,\n                next_identifier);\n  walk_branches(\"oneOf\", \"One of\", schema, doc_children, frame, root, visited,\n                next_identifier);\n  walk_all_of(schema, rows, doc_children, frame, root, visited,\n              next_identifier);\n  walk_if_then_else(schema, doc_children, frame, root, visited,\n                    next_identifier);\n  walk_wildcard_keyword(schema, \"unevaluatedProperties\", empty_path, rows,\n                        frame, root, visited, next_identifier);\n  walk_wildcard_keyword(schema, \"unevaluatedItems\", empty_path, rows, frame,\n                        root, visited, next_identifier);\n\n  if (schema.is_object() && schema.defines(\"contains\") &&\n      schema.at(\"contains\").is_object()) {\n    const auto &contains_schema{schema.at(\"contains\")};\n    const auto is_branching{\n        contains_schema.defines(\"anyOf\") || contains_schema.defines(\"oneOf\") ||\n        contains_schema.defines(\"allOf\") || contains_schema.defines(\"not\") ||\n        contains_schema.defines(\"enum\")};\n    if (is_branching) {\n      walk_branching_subschema(\"Contains\", \"matching item\", contains_schema,\n                               doc_children, frame, root, visited,\n                               next_identifier, false);\n    }\n  }\n\n  if (schema.is_object() && schema.defines(\"contentSchema\") &&\n      schema.at(\"contentSchema\").is_object()) {\n    const auto &content_schema{schema.at(\"contentSchema\")};\n    const auto is_branching{\n        content_schema.defines(\"anyOf\") || content_schema.defines(\"oneOf\") ||\n        content_schema.defines(\"allOf\") || content_schema.defines(\"not\")};\n    if (is_branching) {\n      walk_branching_subschema(\"Decoded content\", \"decoded\", content_schema,\n                               doc_children, frame, root, visited,\n                               next_identifier, true);\n    }\n  }\n\n  if (schema.is_object() && schema.defines(\"propertyNames\") &&\n      schema.at(\"propertyNames\").is_object()) {\n    const auto &names_schema{schema.at(\"propertyNames\")};\n    const auto is_branching{\n        names_schema.defines(\"anyOf\") || names_schema.defines(\"oneOf\") ||\n        names_schema.defines(\"allOf\") || names_schema.defines(\"not\")};\n    if (is_branching) {\n      walk_branching_subschema(\"Property names\", \"key\", names_schema,\n                               doc_children, frame, root, visited,\n                               next_identifier, false);\n    }\n  }\n\n  if (schema.is_object() && schema.defines(\"not\")) {\n    const auto &not_schema{schema.at(\"not\")};\n    const auto is_branching{\n        not_schema.is_object() &&\n        (not_schema.defines(\"anyOf\") || not_schema.defines(\"oneOf\") ||\n         not_schema.defines(\"allOf\") || not_schema.defines(\"not\"))};\n    const auto has_inline_constraints{!is_branching && not_schema.is_object() &&\n                                      !constraints_of(not_schema).empty()};\n    if (!has_inline_constraints) {\n      walk_branching_subschema(\"Must NOT match\", \"value\", not_schema,\n                               doc_children, frame, root, visited,\n                               next_identifier, false);\n    }\n  }\n\n  assert(!rows.empty() || !doc_children.empty());\n\n  documentation.assign(\"rows\", std::move(rows));\n  if (!doc_children.empty()) {\n    documentation.assign(\"children\", std::move(doc_children));\n  }\n\n  return documentation;\n}\n\n} // namespace\n\nauto to_documentation(const sourcemeta::core::JSON &schema,\n                      const sourcemeta::core::SchemaWalker &walker,\n                      const sourcemeta::core::SchemaResolver &resolver)\n    -> sourcemeta::core::JSON {\n  sourcemeta::blaze::SchemaTransformer canonicalizer;\n  sourcemeta::blaze::add(canonicalizer,\n                         sourcemeta::blaze::AlterSchemaMode::Canonicalizer);\n  sourcemeta::core::JSON canonical{schema};\n  [[maybe_unused]] const auto canonicalized{canonicalizer.apply(\n      canonical, walker, resolver,\n      [](const auto &, const auto, const auto, const auto &,\n         [[maybe_unused]] const auto applied) { assert(applied); })};\n  assert(canonicalized.first);\n\n  sourcemeta::core::SchemaFrame frame{\n      sourcemeta::core::SchemaFrame::Mode::References};\n  frame.analyse(canonical, walker, resolver);\n\n  VisitedSchemas visited;\n  std::size_t next_identifier{0};\n  return walk_schema(canonical, true, frame, canonical, visited,\n                     next_identifier);\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/documentation/documentation_html.cc",
    "content": "#include <sourcemeta/blaze/documentation.h>\n\n#include <sourcemeta/core/html.h>\n#include <sourcemeta/core/json.h>\n\n#include <cassert> // assert\n#include <set>     // std::set\n#include <sstream> // std::ostringstream\n#include <string>  // std::string, std::to_string\n\nnamespace sourcemeta::blaze {\n\nnamespace {\n\nauto json_to_string(const sourcemeta::core::JSON &value) -> std::string {\n  std::ostringstream stream;\n  sourcemeta::core::stringify(value, stream);\n  return stream.str();\n}\n\nauto is_empty_row(const sourcemeta::core::JSON &row) -> bool {\n  assert(row.is_object());\n  assert(row.defines(\"type\"));\n  return row.at(\"type\").defines(\"kind\") &&\n         row.at(\"type\").at(\"kind\").to_string() == \"any\" &&\n         !row.defines(\"constraints\") && !row.defines(\"badges\") &&\n         !row.defines(\"modifiers\") && !row.defines(\"title\") &&\n         !row.defines(\"description\") && !row.defines(\"default\") &&\n         !row.defines(\"examples\");\n}\n\nauto collect_ref_targets(const sourcemeta::core::JSON &table,\n                         std::set<std::int64_t> &targets) -> void {\n  for (const auto &row : table.at(\"rows\").as_array()) {\n    if (row.defines(\"type\") && row.at(\"type\").defines(\"kind\") &&\n        row.at(\"type\").at(\"kind\").to_string() == \"recursiveRef\" &&\n        row.at(\"type\").defines(\"identifier\")) {\n      targets.insert(row.at(\"type\").at(\"identifier\").to_integer());\n    }\n    if (row.defines(\"children\")) {\n      for (const auto &section : row.at(\"children\").as_array()) {\n        for (const auto &child : section.at(\"children\").as_array()) {\n          collect_ref_targets(child, targets);\n        }\n      }\n    }\n  }\n  if (table.defines(\"children\")) {\n    for (const auto &section : table.at(\"children\").as_array()) {\n      for (const auto &child : section.at(\"children\").as_array()) {\n        collect_ref_targets(child, targets);\n      }\n    }\n  }\n}\n\nauto render_path(sourcemeta::core::HTMLWriter &writer,\n                 const sourcemeta::core::JSON &path) -> void {\n  assert(path.is_array());\n  writer.code();\n  bool first{true};\n  for (const auto &segment : path.as_array()) {\n    assert(segment.defines(\"type\"));\n    assert(segment.defines(\"value\"));\n    const auto &type{segment.at(\"type\").to_string()};\n    const auto &value{segment.at(\"value\").to_string()};\n\n    if (!first) {\n      writer.text(\"/\");\n    }\n\n    if (type == \"literal\" || type == \"pattern\") {\n      writer.text(first ? \"/\" + value : value);\n    } else if (type == \"wildcard\") {\n      writer.text(first ? \"/*\" : \"*\");\n    } else if (type == \"synthetic\") {\n      writer.em(\"(\" + value + \")\");\n    }\n\n    first = false;\n  }\n\n  writer.close();\n}\n\nauto render_modifiers(sourcemeta::core::HTMLWriter &writer,\n                      const sourcemeta::core::JSON &row) -> void {\n  if (!row.defines(\"modifiers\")) {\n    return;\n  }\n\n  for (const auto &modifier : row.at(\"modifiers\").as_array()) {\n    writer.span(modifier.to_string());\n  }\n}\n\nauto render_enum_values(sourcemeta::core::HTMLWriter &writer,\n                        const sourcemeta::core::JSON &values,\n                        const bool leading_separator) -> void {\n  assert(values.is_array());\n  bool first{true};\n  for (const auto &value : values.as_array()) {\n    if (!first || leading_separator) {\n      writer.text(\" | \");\n    }\n\n    writer.code(json_to_string(value));\n    first = false;\n  }\n}\n\nauto render_type_expression(sourcemeta::core::HTMLWriter &writer,\n                            const sourcemeta::core::JSON &type) -> void {\n  assert(type.is_object());\n  assert(type.defines(\"kind\"));\n  const auto &kind{type.at(\"kind\").to_string()};\n\n  if (kind == \"object\") {\n    writer.text(\"Object\");\n  } else if (kind == \"primitive\") {\n    assert(type.defines(\"name\"));\n    const auto &name{type.at(\"name\").to_string()};\n    if (name == \"string\") {\n      writer.text(\"String\");\n    } else if (name == \"integer\") {\n      writer.text(\"Integer\");\n    } else if (name == \"number\") {\n      writer.text(\"Number\");\n    }\n  } else if (kind == \"array\" || kind == \"tuple\") {\n    writer.text(\"Array\");\n  } else if (kind == \"enum\") {\n    assert(type.defines(\"values\"));\n    render_enum_values(writer, type.at(\"values\"), false);\n    if (type.defines(\"overflow\")) {\n      writer.details();\n      writer.summary(\"+ \" + std::to_string(type.at(\"overflow\").array_size()) +\n                     \" more\");\n      render_enum_values(writer, type.at(\"overflow\"), true);\n      writer.close();\n    }\n  } else if (kind == \"externalRef\") {\n    assert(type.defines(\"url\"));\n    const auto &url{type.at(\"url\").to_string()};\n    writer.a().attribute(\"href\", url);\n    writer.text(url);\n    writer.close();\n  } else if (kind == \"recursiveRef\") {\n    assert(type.defines(\"identifier\"));\n    const auto identifier{std::to_string(type.at(\"identifier\").to_integer())};\n    writer.a().attribute(\"data-index\", identifier);\n    if (type.defines(\"path\")) {\n      bool first_seg{true};\n      for (const auto &segment : type.at(\"path\").as_array()) {\n        const auto &seg_type{segment.at(\"type\").to_string()};\n        const auto &seg_value{segment.at(\"value\").to_string()};\n        if (!first_seg) {\n          writer.text(\"/\");\n        }\n        if (seg_type == \"synthetic\") {\n          writer.text(\"(\" + seg_value + \")\");\n        } else if (seg_type == \"literal\" || seg_type == \"pattern\") {\n          writer.text(first_seg ? \"/\" + seg_value : seg_value);\n        } else if (seg_type == \"wildcard\") {\n          writer.text(first_seg ? \"/*\" : \"*\");\n        }\n        first_seg = false;\n      }\n      writer.text(\" #\" + identifier);\n    } else {\n      writer.text(identifier);\n    }\n    writer.close();\n  } else if (kind == \"dynamicRef\") {\n    assert(type.defines(\"anchor\"));\n    writer.text(\"dynamic: \" + type.at(\"anchor\").to_string());\n  } else if (kind == \"any\") {\n    writer.text(\"Any\");\n  } else if (kind == \"never\") {\n    writer.text(\"Never\");\n  }\n}\n\nauto render_badges(sourcemeta::core::HTMLWriter &writer,\n                   const sourcemeta::core::JSON &row) -> void {\n  if (!row.defines(\"badges\")) {\n    return;\n  }\n\n  for (const auto &badge : row.at(\"badges\").as_array()) {\n    assert(badge.defines(\"kind\"));\n    assert(badge.defines(\"value\"));\n    const auto &kind{badge.at(\"kind\").to_string()};\n    const auto &value{badge.at(\"value\").to_string()};\n    if (kind == \"format\") {\n      writer.span(value);\n    } else if (kind == \"encoding\") {\n      writer.span(\"encoding: \" + value);\n    } else if (kind == \"mime\") {\n      writer.span(\"mime: \" + value);\n    }\n  }\n}\n\nauto render_notes(sourcemeta::core::HTMLWriter &writer,\n                  const sourcemeta::core::JSON &row) -> void {\n  if (row.defines(\"title\")) {\n    writer.strong(row.at(\"title\").to_string());\n  }\n\n  if (row.defines(\"description\")) {\n    writer.p(row.at(\"description\").to_string());\n  }\n\n  if (row.defines(\"default\")) {\n    writer.span();\n    writer.text(\"default: \");\n    writer.code(json_to_string(row.at(\"default\")));\n    writer.close();\n  }\n}\n\nauto render_row(sourcemeta::core::HTMLWriter &writer,\n                const sourcemeta::core::JSON &row,\n                const std::set<std::int64_t> &ref_targets) -> void;\nauto render_section(sourcemeta::core::HTMLWriter &writer,\n                    const sourcemeta::core::JSON &section,\n                    const std::set<std::int64_t> &ref_targets) -> void;\nauto render_table(sourcemeta::core::HTMLWriter &writer,\n                  const sourcemeta::core::JSON &table,\n                  const std::set<std::int64_t> &ref_targets) -> void;\n\nauto emit_header(sourcemeta::core::HTMLWriter &writer) -> void {\n  writer.thead();\n  writer.tr();\n  writer.th(\"Path\");\n  writer.th(\"Type\");\n  writer.th(\"Required\");\n  writer.th(\"Constraints\");\n  writer.th(\"Notes\");\n  writer.close();\n  writer.close();\n}\n\nauto render_row(sourcemeta::core::HTMLWriter &writer,\n                const sourcemeta::core::JSON &row,\n                const std::set<std::int64_t> &ref_targets) -> void {\n  assert(row.defines(\"identifier\"));\n  assert(row.defines(\"path\"));\n  assert(row.defines(\"type\"));\n\n  const auto identifier{row.at(\"identifier\").to_integer()};\n  writer.tr().attribute(\"data-index\", std::to_string(identifier));\n\n  // Path\n  writer.td();\n  render_path(writer, row.at(\"path\"));\n  if (ref_targets.contains(identifier)) {\n    writer.text(\" \");\n    writer.strong(\"#\" + std::to_string(identifier));\n  }\n  render_modifiers(writer, row);\n  writer.close();\n\n  // Type\n  writer.td();\n  render_type_expression(writer, row.at(\"type\"));\n  render_badges(writer, row);\n  writer.close();\n\n  // Required\n  writer.td();\n  if (row.defines(\"required\")) {\n    writer.text(row.at(\"required\").to_boolean() ? \"Yes\" : \"No\");\n  }\n  writer.close();\n\n  // Constraints\n  writer.td();\n  if (row.defines(\"constraints\")) {\n    for (const auto &constraint : row.at(\"constraints\").as_array()) {\n      writer.span(constraint.to_string());\n    }\n  }\n  writer.close();\n\n  // Notes\n  writer.td();\n  render_notes(writer, row);\n  writer.close();\n\n  writer.close();\n\n  if (row.defines(\"children\")) {\n    for (const auto &section : row.at(\"children\").as_array()) {\n      render_section(writer, section, ref_targets);\n    }\n  }\n}\n\nauto render_section(sourcemeta::core::HTMLWriter &writer,\n                    const sourcemeta::core::JSON &section,\n                    const std::set<std::int64_t> &ref_targets) -> void {\n  assert(section.defines(\"label\"));\n  assert(section.defines(\"children\"));\n\n  writer.tr();\n  writer.td().attribute(\"colspan\", \"5\");\n  writer.div();\n\n  writer.div();\n  writer.text(section.at(\"label\").to_string());\n  if (section.defines(\"position\")) {\n    writer.text(\" \");\n    writer.code(section.at(\"position\").to_string());\n  }\n  writer.close();\n\n  for (const auto &child : section.at(\"children\").as_array()) {\n    writer.div();\n    if (child.defines(\"title\")) {\n      writer.div(child.at(\"title\").to_string());\n    }\n\n    render_table(writer, child, ref_targets);\n    writer.close();\n  }\n\n  writer.close();\n  writer.close();\n  writer.close();\n}\n\nauto render_table(sourcemeta::core::HTMLWriter &writer,\n                  const sourcemeta::core::JSON &table,\n                  const std::set<std::int64_t> &ref_targets) -> void {\n  assert(table.defines(\"identifier\"));\n  assert(table.defines(\"rows\"));\n\n  writer.table().attribute(\"data-index\",\n                           std::to_string(table.at(\"identifier\").to_integer()));\n\n  const auto &rows{table.at(\"rows\")};\n  const auto has_children{table.defines(\"children\")};\n  const auto root_is_ref_target{\n      !rows.empty() && rows.at(0).defines(\"identifier\") &&\n      ref_targets.contains(rows.at(0).at(\"identifier\").to_integer())};\n  const auto skip_root{has_children && !rows.empty() &&\n                       is_empty_row(rows.at(0)) && !root_is_ref_target};\n\n  if (!skip_root || rows.array_size() > 1) {\n    emit_header(writer);\n  }\n\n  writer.tbody();\n  for (std::size_t index = skip_root ? 1 : 0; index < rows.array_size();\n       ++index) {\n    render_row(writer, rows.at(index), ref_targets);\n  }\n\n  if (has_children) {\n    for (const auto &section : table.at(\"children\").as_array()) {\n      render_section(writer, section, ref_targets);\n    }\n  }\n\n  writer.close();\n  writer.close();\n}\n\n} // namespace\n\nauto to_html(const sourcemeta::core::JSON &documentation) -> std::string {\n  assert(documentation.is_object());\n  assert(documentation.defines(\"rows\"));\n\n  std::set<std::int64_t> ref_targets;\n  collect_ref_targets(documentation, ref_targets);\n\n  sourcemeta::core::HTMLWriter writer;\n  writer.table().attribute(\"class\", \"sourcemeta-blaze-documentation\");\n\n  const auto &rows{documentation.at(\"rows\")};\n  const auto has_children{documentation.defines(\"children\")};\n  const auto root_is_ref_target{\n      !rows.empty() && rows.at(0).defines(\"identifier\") &&\n      ref_targets.contains(rows.at(0).at(\"identifier\").to_integer())};\n  const auto skip_root{has_children && !rows.empty() &&\n                       is_empty_row(rows.at(0)) && !root_is_ref_target};\n\n  if (!skip_root || rows.array_size() > 1) {\n    emit_header(writer);\n  }\n\n  writer.tbody();\n  for (std::size_t index = skip_root ? 1 : 0; index < rows.array_size();\n       ++index) {\n    render_row(writer, rows.at(index), ref_targets);\n  }\n\n  if (has_children) {\n    for (const auto &section : documentation.at(\"children\").as_array()) {\n      render_section(writer, section, ref_targets);\n    }\n  }\n\n  writer.close();\n  writer.close();\n  return writer.str();\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/documentation/include/sourcemeta/blaze/documentation.h",
    "content": "#ifndef SOURCEMETA_BLAZE_DOCUMENTATION_H_\n#define SOURCEMETA_BLAZE_DOCUMENTATION_H_\n\n/// @defgroup documentation Documentation\n/// @brief Generate human-readable documentation from a JSON Schema\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/documentation.h>\n/// ```\n\n#ifndef SOURCEMETA_BLAZE_DOCUMENTATION_EXPORT\n#include <sourcemeta/blaze/documentation_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <string> // std::string\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup documentation\n///\n/// Generate documentation JSON from an input JSON Schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/documentation.h>\n///\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// const sourcemeta::core::JSON schema =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\");\n///\n/// const auto documentation{sourcemeta::blaze::to_documentation(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver)};\n/// ```\n[[nodiscard]] SOURCEMETA_BLAZE_DOCUMENTATION_EXPORT auto\nto_documentation(const sourcemeta::core::JSON &schema,\n                 const sourcemeta::core::SchemaWalker &walker,\n                 const sourcemeta::core::SchemaResolver &resolver)\n    -> sourcemeta::core::JSON;\n\n/// @ingroup documentation\n/// Render a documentation JSON object as an HTML string\n[[nodiscard]] SOURCEMETA_BLAZE_DOCUMENTATION_EXPORT auto\nto_html(const sourcemeta::core::JSON &documentation) -> std::string;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME evaluator\n  FOLDER \"Blaze/Evaluator\"\n  PRIVATE_HEADERS error.h value.h instruction.h string_set.h dispatch.h\n  SOURCES evaluator_json.cc evaluator_describe.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME evaluator)\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_add_vectorization_diagnostics(sourcemeta_blaze_evaluator)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_evaluator PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_evaluator PUBLIC\n  sourcemeta::core::regex)\ntarget_link_libraries(sourcemeta_blaze_evaluator PUBLIC\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_blaze_evaluator PRIVATE\n  sourcemeta::core::uri)\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/evaluator_describe.cc",
    "content": "#include <sourcemeta/blaze/evaluator.h>\n\n#include <algorithm>   // std::ranges::any_of\n#include <cassert>     // assert\n#include <sstream>     // std::ostringstream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::to_underlying, std::unreachable\n#include <variant>     // std::visit\n\nnamespace {\nusing namespace sourcemeta::blaze;\n\ntemplate <typename X, typename T>\nauto instruction_value(const T &step) -> decltype(auto) {\n  if constexpr (requires { step.value; }) {\n    return std::get<X>(step.value);\n  } else {\n    return step.id;\n  }\n}\n\ntemplate <typename T>\nauto describe_stringify(const sourcemeta::core::JSON &value, T &stream)\n    -> void {\n  if (value.is_decimal()) {\n    stream << value.to_decimal().to_string();\n  } else {\n    sourcemeta::core::stringify(value, stream);\n  }\n}\n\nauto type_name(const sourcemeta::core::JSON::Type type) -> std::string_view {\n  using Type = sourcemeta::core::JSON::Type;\n  switch (type) {\n    case Type::Null:\n      return \"null\";\n    case Type::Boolean:\n      return \"boolean\";\n    case Type::Integer:\n      return \"integer\";\n    case Type::Real:\n    case Type::Decimal:\n      return \"number\";\n    case Type::String:\n      return \"string\";\n    case Type::Array:\n      return \"array\";\n    case Type::Object:\n      return \"object\";\n    default:\n      std::unreachable();\n  }\n}\n\nauto value_type_name(const sourcemeta::core::JSON &value) -> std::string_view {\n  if (value.type() == sourcemeta::core::JSON::Type::Decimal) {\n    return value.to_decimal().is_integer() ? \"integer\" : \"number\";\n  }\n  return type_name(value.type());\n}\n\nauto escape_string(const std::string &input) -> std::string {\n  std::size_t size{2};\n  for (const auto character : input) {\n    size += (character == '\"') ? 2 : 1;\n  }\n\n  std::string result;\n  result.resize_and_overwrite(size, [&](char *buffer, std::size_t) {\n    auto *cursor{buffer};\n    *cursor++ = '\"';\n    for (const auto character : input) {\n      if (character == '\"') {\n        *cursor++ = '\\\\';\n      }\n      *cursor++ = character;\n    }\n    *cursor++ = '\"';\n    return static_cast<std::size_t>(cursor - buffer);\n  });\n\n  return result;\n}\n\nauto describe_type_check(const bool valid,\n                         const sourcemeta::core::JSON::Type current,\n                         const sourcemeta::core::JSON::Type expected,\n                         std::ostringstream &message) -> void {\n  message << \"The value was expected to be of type \";\n  message << type_name(expected);\n  if (!valid) {\n    message << \" but it was of type \";\n    if (current == sourcemeta::core::JSON::Type::Decimal) {\n      message << \"number\";\n    } else {\n      message << type_name(current);\n    }\n  }\n}\n\nauto describe_not_type_check(const bool valid,\n                             const sourcemeta::core::JSON::Type current,\n                             const sourcemeta::core::JSON::Type expected,\n                             std::ostringstream &message) -> void {\n  message << \"The value was expected to NOT be of type \";\n  message << type_name(expected);\n  if (!valid) {\n    message << \" but it was of type \";\n    if (current == sourcemeta::core::JSON::Type::Decimal &&\n        expected == sourcemeta::core::JSON::Type::Integer) {\n      message << \"integer\";\n    } else if ((current == sourcemeta::core::JSON::Type::Integer &&\n                expected == sourcemeta::core::JSON::Type::Real) ||\n               current == sourcemeta::core::JSON::Type::Decimal) {\n      message << \"number\";\n    } else {\n      message << type_name(current);\n    }\n  }\n}\n\nauto describe_types_check(const bool valid,\n                          const sourcemeta::core::JSON::Type current,\n                          const ValueTypes expected,\n                          std::ostringstream &message) -> void {\n  ValueTypes types{expected};\n  const auto has_real{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))};\n  const auto has_integer{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Integer))};\n  const auto has_decimal{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Decimal))};\n\n  if (has_real && has_integer) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n  }\n  if (has_real && has_decimal) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n  }\n  if (has_integer && has_decimal) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n  }\n\n  const auto popcount{types.count()};\n\n  if (popcount == 1) {\n    std::uint8_t type_index{0};\n    for (std::uint8_t bit{0}; bit < 8; bit++) {\n      if (types.test(bit)) {\n        type_index = bit;\n        break;\n      }\n    }\n    describe_type_check(valid, current,\n                        static_cast<sourcemeta::core::JSON::Type>(type_index),\n                        message);\n    return;\n  }\n\n  message << \"The value was expected to be of type \";\n  bool first{true};\n  std::uint8_t last_bit{255};\n  for (std::uint8_t bit{0}; bit < 8; bit++) {\n    if (types.test(bit)) {\n      last_bit = bit;\n    }\n  }\n\n  for (std::uint8_t bit{0}; bit < 8; bit++) {\n    if (types.test(bit)) {\n      if (!first) {\n        message << \", \";\n      }\n      if (bit == last_bit) {\n        message << \"or \";\n      }\n      message << type_name(static_cast<sourcemeta::core::JSON::Type>(bit));\n      first = false;\n    }\n  }\n\n  if (valid) {\n    message << \" and it was of type \";\n  } else {\n    message << \" but it was of type \";\n  }\n\n  if (valid && current == sourcemeta::core::JSON::Type::Decimal &&\n      has_integer && !has_real) {\n    message << \"integer\";\n  } else if ((valid && current == sourcemeta::core::JSON::Type::Integer &&\n              has_real) ||\n             current == sourcemeta::core::JSON::Type::Decimal) {\n    message << \"number\";\n  } else {\n    message << type_name(current);\n  }\n}\n\nauto describe_not_types_check(const bool valid,\n                              const sourcemeta::core::JSON::Type current,\n                              const ValueTypes expected,\n                              std::ostringstream &message) -> void {\n  ValueTypes types{expected};\n  const auto has_real{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))};\n  const auto has_integer{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Integer))};\n  const auto has_decimal{\n      types.test(std::to_underlying(sourcemeta::core::JSON::Type::Decimal))};\n\n  if (has_real && has_integer) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n  }\n  if (has_real && has_decimal) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n  }\n  if (has_integer && has_decimal) {\n    types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n  }\n\n  const auto popcount{types.count()};\n\n  if (popcount == 1) {\n    std::uint8_t type_index{0};\n    for (std::uint8_t bit{0}; bit < 8; bit++) {\n      if (types.test(bit)) {\n        type_index = bit;\n        break;\n      }\n    }\n    describe_not_type_check(\n        valid, current, static_cast<sourcemeta::core::JSON::Type>(type_index),\n        message);\n    return;\n  }\n\n  message << \"The value was expected to NOT be of type \";\n  bool first{true};\n  std::uint8_t last_bit{255};\n  for (std::uint8_t bit{0}; bit < 8; bit++) {\n    if (types.test(bit)) {\n      last_bit = bit;\n    }\n  }\n\n  for (std::uint8_t bit{0}; bit < 8; bit++) {\n    if (types.test(bit)) {\n      if (!first) {\n        message << \", \";\n      }\n      if (bit == last_bit) {\n        message << \"or \";\n      }\n      message << type_name(static_cast<sourcemeta::core::JSON::Type>(bit));\n      first = false;\n    }\n  }\n\n  if (valid) {\n    message << \" and it was of type \";\n  } else {\n    message << \" but it was of type \";\n  }\n\n  if (!valid && current == sourcemeta::core::JSON::Type::Decimal &&\n      has_integer && !has_real) {\n    message << \"integer\";\n  } else if ((!valid && current == sourcemeta::core::JSON::Type::Integer &&\n              has_real) ||\n             current == sourcemeta::core::JSON::Type::Decimal) {\n    message << \"number\";\n  } else {\n    message << type_name(current);\n  }\n}\n\nauto describe_reference(const sourcemeta::core::JSON &target) -> std::string {\n  std::ostringstream message;\n  message << \"The \" << type_name(target.type())\n          << \" value was expected to validate against the referenced schema\";\n  return message.str();\n}\n\nauto is_within_keyword(const sourcemeta::core::WeakPointer &evaluate_path,\n                       const std::string &keyword) -> bool {\n  return std::ranges::any_of(evaluate_path, [&keyword](const auto &token) {\n    return token.is_property() && token.to_property() == keyword;\n  });\n}\n\nauto unknown() -> std::string {\n  assert(false);\n  return \"<unknown>\";\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\n// TODO: What will unlock even better error messages is being able to\n// get the subschema being evaluated along with the keyword\nauto describe(const bool valid, const Instruction &step,\n              const sourcemeta::core::WeakPointer &evaluate_path,\n              const sourcemeta::core::WeakPointer &instance_location,\n              const sourcemeta::core::JSON &instance,\n              const sourcemeta::core::JSON &annotation) -> std::string {\n  const std::string keyword{evaluate_path.empty() ||\n                                    // The last token can be an index for\n                                    // boolean schemas inside array applicators\n                                    !evaluate_path.back().is_property()\n                                ? \"\"\n                                : evaluate_path.back().to_property()};\n  const sourcemeta::core::JSON &target{get(instance, instance_location)};\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionFail) {\n    if (keyword == \"enum\") {\n      std::ostringstream message;\n      message << \"The \" << type_name(target.type())\n              << \" value was not expected to validate against the empty \"\n                 \"enumeration\";\n      return message.str();\n    }\n\n    if (keyword == \"contains\") {\n      return \"The constraints declared for this keyword were not satisfiable\";\n    }\n\n    if (keyword == \"additionalProperties\" ||\n        keyword == \"unevaluatedProperties\") {\n      std::ostringstream message;\n      assert(!instance_location.empty());\n      assert(instance_location.back().is_property());\n      message << \"The object value was not expected to define the property \"\n              << escape_string(instance_location.back().to_property());\n      return message.str();\n    }\n\n    if (keyword == \"unevaluatedItems\") {\n      std::ostringstream message;\n      assert(!instance_location.empty());\n      assert(instance_location.back().is_index());\n      message << \"The array value was not expected to define the item at index \"\n              << instance_location.back().to_index();\n      return message.str();\n    }\n\n    return \"No instance is expected to succeed against the false schema\";\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalOr) {\n    assert(!step.children.empty());\n    std::ostringstream message;\n    message << \"The \" << type_name(target.type())\n            << \" value was expected to validate against \";\n    if (step.children.size() > 1) {\n      message << \"at least one of the \" << step.children.size()\n              << \" given subschemas\";\n    } else {\n      message << \"the given subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalAnd) {\n    if (keyword == \"allOf\" || keyword == \"extends\") {\n      assert(!step.children.empty());\n      std::ostringstream message;\n      message << \"The \" << type_name(target.type())\n              << \" value was expected to validate against the \";\n      if (step.children.size() > 1) {\n        message << step.children.size() << \" given subschemas\";\n      } else {\n        message << \"given subschema\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"$ref\") {\n      return describe_reference(target);\n    }\n\n    return unknown();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalXor) {\n    assert(!step.children.empty());\n    std::ostringstream message;\n\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property());\n    } else {\n      message << \"The \" << type_name(target.type()) << \" value\";\n    }\n\n    message << \" was expected to validate against \";\n    if (step.children.size() > 1) {\n      message << \"one and only one of the \" << step.children.size()\n              << \" given subschemas\";\n    } else {\n      message << \"the given subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalCondition) {\n    std::ostringstream message;\n    message << \"The \" << type_name(target.type())\n            << \" value was expected to validate against the given conditional\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalNot) {\n    std::ostringstream message;\n    message\n        << \"The \" << type_name(target.type())\n        << \" value was expected to not validate against the given subschema\";\n    if (!valid) {\n      message << \", but it did\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalNotEvaluate) {\n    std::ostringstream message;\n    message\n        << \"The \" << type_name(target.type())\n        << \" value was expected to not validate against the given subschema\";\n    if (!valid) {\n      message << \", but it did\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::Evaluate) {\n    return \"The instance location was marked as evaluated\";\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::ControlDynamicAnchorJump) {\n    if (keyword == \"$dynamicRef\") {\n      const auto &value{instruction_value<ValueString>(step)};\n      std::ostringstream message;\n      message << \"The \" << type_name(target.type())\n              << \" value was expected to validate against the first subschema \"\n                 \"in scope that declared the dynamic anchor \"\n              << escape_string(value);\n      return message.str();\n    }\n\n    assert(keyword == \"$recursiveRef\");\n    std::ostringstream message;\n    message << \"The \" << type_name(target.type())\n            << \" value was expected to validate against the first subschema \"\n               \"in scope that declared a recursive anchor\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AnnotationEmit) {\n    if (keyword == \"properties\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The object property \" << escape_string(annotation.to_string())\n              << \" successfully validated against its property \"\n                 \"subschema\";\n      return message.str();\n    }\n\n    if ((keyword == \"items\" || keyword == \"additionalItems\") &&\n        annotation.is_boolean() && annotation.to_boolean()) {\n      assert(target.is_array());\n      return \"Every item in the array value was successfully validated\";\n    }\n\n    if ((keyword == \"prefixItems\" || keyword == \"items\") &&\n        annotation.is_integer()) {\n      assert(target.is_array());\n      assert(annotation.is_positive());\n      std::ostringstream message;\n      if (annotation.to_integer() == 0) {\n        message << \"The first item of the array value successfully validated \"\n                   \"against the first \"\n                   \"positional subschema\";\n      } else {\n        message << \"The first \" << annotation.to_integer() + 1\n                << \" items of the array value successfully validated against \"\n                   \"the given \"\n                   \"positional subschemas\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"prefixItems\" && annotation.is_boolean() &&\n        annotation.to_boolean()) {\n      assert(target.is_array());\n      std::ostringstream message;\n      message << \"Every item of the array value validated against the given \"\n                 \"positional subschemas\";\n      return message.str();\n    }\n\n    if (keyword == \"title\" || keyword == \"description\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The \" << keyword << \" of the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was \" << escape_string(annotation.to_string());\n      return message.str();\n    }\n\n    if (keyword == \"default\") {\n      std::ostringstream message;\n      message << \"The default value of the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was \";\n      stringify(annotation, message);\n      return message.str();\n    }\n\n    if (keyword == \"deprecated\" && annotation.is_boolean()) {\n      std::ostringstream message;\n      if (instance_location.empty()) {\n        message << \"The instance\";\n      } else {\n        message << \"The instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      if (annotation.to_boolean()) {\n        message << \" was considered deprecated\";\n      } else {\n        message << \" was not considered deprecated\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"readOnly\" && annotation.is_boolean()) {\n      std::ostringstream message;\n      if (instance_location.empty()) {\n        message << \"The instance\";\n      } else {\n        message << \"The instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      if (annotation.to_boolean()) {\n        message << \" was considered read-only\";\n      } else {\n        message << \" was not considered read-only\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"writeOnly\" && annotation.is_boolean()) {\n      std::ostringstream message;\n      if (instance_location.empty()) {\n        message << \"The instance\";\n      } else {\n        message << \"The instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      if (annotation.to_boolean()) {\n        message << \" was considered write-only\";\n      } else {\n        message << \" was not considered write-only\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"examples\") {\n      assert(annotation.is_array());\n      std::ostringstream message;\n      if (instance_location.empty()) {\n        message << \"Examples of the instance\";\n      } else {\n        message << \"Examples of the instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" were \";\n      for (auto iterator = annotation.as_array().cbegin();\n           iterator != annotation.as_array().cend(); ++iterator) {\n        if (std::next(iterator) == annotation.as_array().cend()) {\n          message << \"and \";\n          describe_stringify(*iterator, message);\n        } else {\n          describe_stringify(*iterator, message);\n          message << \", \";\n        }\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"contentEncoding\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The content encoding of the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was \" << escape_string(annotation.to_string());\n      return message.str();\n    }\n\n    if (keyword == \"contentMediaType\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The content media type of the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was \" << escape_string(annotation.to_string());\n      return message.str();\n    }\n\n    if (keyword == \"contentSchema\") {\n      std::ostringstream message;\n      message << \"When decoded, the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was expected to validate against the schema \";\n      describe_stringify(annotation, message);\n      return message.str();\n    }\n\n    if (keyword == \"format\") {\n      std::ostringstream message;\n      message << \"The logical type of the\";\n      if (instance_location.empty()) {\n        message << \" instance\";\n      } else {\n        message << \" instance location \\\"\";\n        stringify(instance_location, message);\n        message << \"\\\"\";\n      }\n\n      message << \" was expected to be \";\n      describe_stringify(annotation, message);\n      return message.str();\n    }\n\n    std::ostringstream message;\n    message << \"The unrecognized keyword \" << escape_string(keyword)\n            << \" was collected as the annotation \";\n    describe_stringify(annotation, message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AnnotationToParent) {\n    if (keyword == \"unevaluatedItems\" && annotation.is_boolean() &&\n        annotation.to_boolean()) {\n      assert(target.is_array());\n      std::ostringstream message;\n      message << \"At least one item of the array value successfully validated \"\n                 \"against the subschema for unevaluated items\";\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent) {\n    if (keyword == \"patternProperties\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The object property \" << escape_string(annotation.to_string())\n              << \" successfully validated against its pattern property \"\n                 \"subschema\";\n      return message.str();\n    }\n\n    if (keyword == \"additionalProperties\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The object property \" << escape_string(annotation.to_string())\n              << \" successfully validated against the additional properties \"\n                 \"subschema\";\n      return message.str();\n    }\n\n    if (keyword == \"unevaluatedProperties\") {\n      assert(annotation.is_string());\n      std::ostringstream message;\n      message << \"The object property \" << escape_string(annotation.to_string())\n              << \" successfully validated against the subschema for \"\n                 \"unevaluated properties\";\n      return message.str();\n    }\n\n    if (keyword == \"contains\" && annotation.is_integer()) {\n      assert(target.is_array());\n      assert(annotation.is_positive());\n      std::ostringstream message;\n      message << \"The item at index \" << annotation.to_integer()\n              << \" of the array value successfully validated against the \"\n                 \"containment check subschema\";\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopProperties) {\n    assert(keyword == \"additionalProperties\" ||\n           keyword == \"unevaluatedProperties\");\n    std::ostringstream message;\n    if (!step.children.empty() &&\n        step.children.front().type == InstructionIndex::AssertionFail) {\n      if (keyword == \"unevaluatedProperties\") {\n        message << \"The object value was not expected to define unevaluated \"\n                   \"properties\";\n      } else {\n        message << \"The object value was not expected to define additional \"\n                   \"properties\";\n      }\n    } else if (keyword == \"unevaluatedProperties\") {\n      message << \"The object properties not covered by other object \"\n                 \"keywords were expected to validate against this subschema\";\n    } else {\n      message << \"The object properties not covered by other adjacent object \"\n                 \"keywords were expected to validate against this subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesEvaluate) {\n    assert(keyword == \"additionalProperties\");\n    std::ostringstream message;\n    if (step.children.size() == 1 &&\n        step.children.front().type == InstructionIndex::AssertionFail) {\n      message << \"The object value was not expected to define additional \"\n                 \"properties\";\n    } else {\n      message << \"The object properties not covered by other adjacent object \"\n                 \"keywords were expected to validate against this subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesUnevaluated) {\n    if (keyword == \"unevaluatedProperties\") {\n      std::ostringstream message;\n      if (!step.children.empty() &&\n          step.children.front().type == InstructionIndex::AssertionFail) {\n        message << \"The object value was not expected to define unevaluated \"\n                   \"properties\";\n      } else {\n        message << \"The object properties not covered by other object \"\n                   \"keywords were expected to validate against this subschema\";\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesUnevaluatedExcept) {\n    if (keyword == \"unevaluatedProperties\") {\n      std::ostringstream message;\n      if (!step.children.empty() &&\n          step.children.front().type == InstructionIndex::AssertionFail) {\n        message << \"The object value was not expected to define unevaluated \"\n                   \"properties\";\n      } else {\n        message << \"The object properties not covered by other object \"\n                   \"keywords were expected to validate against this subschema\";\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopPropertiesExcept) {\n    assert(keyword == \"additionalProperties\" ||\n           keyword == \"unevaluatedProperties\");\n    std::ostringstream message;\n    if (!step.children.empty() &&\n        step.children.front().type == InstructionIndex::AssertionFail) {\n      if (keyword == \"unevaluatedProperties\") {\n        message << \"The object value was not expected to define unevaluated \"\n                   \"properties\";\n      } else {\n        message << \"The object value was not expected to define additional \"\n                   \"properties\";\n      }\n    } else if (keyword == \"unevaluatedProperties\") {\n      message << \"The object properties not covered by other object \"\n                 \"keywords were expected to validate against this subschema\";\n    } else {\n      message << \"The object properties not covered by other adjacent object \"\n                 \"keywords were expected to validate against this subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesExactlyTypeStrict) {\n    std::ostringstream message;\n    message << \"The required object properties were expected to be of type \"\n            << type_name(instruction_value<ValueTypedProperties>(step).first);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::\n                       LoopPropertiesExactlyTypeStrictHash) {\n    std::ostringstream message;\n    message << \"The required object properties were expected to be of type \"\n            << type_name(instruction_value<ValueTypedHashes>(step).first);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::\n                       LoopItemsPropertiesExactlyTypeStrictHash ||\n      step.type == sourcemeta::blaze::InstructionIndex::\n                       LoopItemsPropertiesExactlyTypeStrictHash3) {\n    std::ostringstream message;\n    message << \"Every item in the array was expected to be an object whose \"\n               \"required properties were of type \"\n            << type_name(instruction_value<ValueTypedHashes>(step).first);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBounded) {\n    return \"Every item in the array was expected to be a number within the \"\n           \"given range\";\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopItemsIntegerBoundedSized) {\n    return \"Every item in the array was expected to be a number within the \"\n           \"given range\";\n  }\n\n  if (step.type ==\n          sourcemeta::blaze::InstructionIndex::AssertionTypeIntegerBounded ||\n      step.type == sourcemeta::blaze::InstructionIndex::\n                       AssertionTypeIntegerBoundedStrict) {\n    return \"The value was expected to be an integer within the given range\";\n  }\n\n  if (step.type ==\n          sourcemeta::blaze::InstructionIndex::AssertionTypeIntegerLowerBound ||\n      step.type == sourcemeta::blaze::InstructionIndex::\n                       AssertionTypeIntegerLowerBoundStrict) {\n    return \"The value was expected to be an integer above the given minimum\";\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionObjectPropertiesSimple) {\n    return \"The object value was expected to validate against the defined \"\n           \"property subschemas\";\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopPropertiesType) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesTypeEvaluate) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesTypeStrict) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesTypeStrictEvaluate) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesTypeStrictAny) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \";\n    ValueTypes types{instruction_value<ValueTypes>(step)};\n\n    const auto has_real{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))};\n    const auto has_integer{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Integer))};\n    const auto has_decimal{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Decimal))};\n\n    if (has_real && has_integer) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n    }\n    if (has_real && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n    if (has_integer && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n\n    const auto popcount{types.count()};\n\n    if (popcount == 1) {\n      std::uint8_t type_index{0};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          type_index = bit;\n          break;\n        }\n      }\n      message << type_name(\n          static_cast<sourcemeta::core::JSON::Type>(type_index));\n    } else {\n      bool first{true};\n      std::uint8_t last_bit{255};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          last_bit = bit;\n        }\n      }\n\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          if (!first) {\n            message << \", \";\n          }\n          if (bit == last_bit) {\n            message << \"or \";\n          }\n          message << type_name(static_cast<sourcemeta::core::JSON::Type>(bit));\n          first = false;\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::\n                       LoopPropertiesTypeStrictAnyEvaluate) {\n    std::ostringstream message;\n    message << \"The object properties were expected to be of type \";\n    ValueTypes types{instruction_value<ValueTypes>(step)};\n\n    const auto has_real{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))};\n    const auto has_integer{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Integer))};\n    const auto has_decimal{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Decimal))};\n\n    if (has_real && has_integer) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n    }\n    if (has_real && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n    if (has_integer && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n\n    const auto popcount{types.count()};\n\n    if (popcount == 1) {\n      std::uint8_t type_index{0};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          type_index = bit;\n          break;\n        }\n      }\n      message << type_name(\n          static_cast<sourcemeta::core::JSON::Type>(type_index));\n    } else {\n      bool first{true};\n      std::uint8_t last_bit{255};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          last_bit = bit;\n        }\n      }\n\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          if (!first) {\n            message << \", \";\n          }\n          if (bit == last_bit) {\n            message << \"or \";\n          }\n          message << type_name(static_cast<sourcemeta::core::JSON::Type>(bit));\n          first = false;\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopKeys) {\n    assert(keyword == \"propertyNames\");\n    assert(target.is_object());\n    std::ostringstream message;\n\n    if (target.size() == 0) {\n      assert(valid);\n      message << \"The object is empty and no properties were expected to \"\n                 \"validate against the given subschema\";\n    } else if (target.size() == 1) {\n      message << \"The object property \";\n      message << escape_string(target.as_object().cbegin()->first);\n      message << \" was expected to validate against the given subschema\";\n    } else {\n      message << \"The object properties \";\n      for (auto iterator = target.as_object().cbegin();\n           iterator != target.as_object().cend(); ++iterator) {\n        if (std::next(iterator) == target.as_object().cend()) {\n          message << \"and \" << escape_string(iterator->first);\n        } else {\n          message << escape_string(iterator->first) << \", \";\n        }\n      }\n\n      message << \" were expected to validate against the given subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopItems) {\n    assert(target.is_array());\n    return \"Every item in the array value was expected to validate against the \"\n           \"given subschema\";\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopItemsFrom) {\n    assert(target.is_array());\n    const auto &value{instruction_value<ValueUnsignedInteger>(step)};\n    std::ostringstream message;\n    message << \"Every item in the array value\";\n    if (value == 1) {\n      message << \" except for the first one\";\n    } else if (value > 0) {\n      message << \" except for the first \" << value;\n    }\n\n    message << \" was expected to validate against the given subschema\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopItemsUnevaluated) {\n    assert(keyword == \"unevaluatedItems\");\n    std::ostringstream message;\n    message << \"The array items not covered by other array keywords, if any, \"\n               \"were expected to validate against this subschema\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopItemsType) {\n    std::ostringstream message;\n    message << \"The array items were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopItemsTypeStrict) {\n    std::ostringstream message;\n    message << \"The array items were expected to be of type \"\n            << type_name(instruction_value<ValueType>(step));\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopItemsTypeStrictAny) {\n    std::ostringstream message;\n    message << \"The array items were expected to be of type \";\n    ValueTypes types{instruction_value<ValueTypes>(step)};\n\n    const auto has_real{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Real))};\n    const auto has_integer{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Integer))};\n    const auto has_decimal{\n        types.test(std::to_underlying(sourcemeta::core::JSON::Type::Decimal))};\n\n    if (has_real && has_integer) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n    }\n    if (has_real && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n    if (has_integer && has_decimal) {\n      types.reset(std::to_underlying(sourcemeta::core::JSON::Type::Decimal));\n    }\n\n    const auto popcount{types.count()};\n\n    if (popcount == 1) {\n      std::uint8_t type_index{0};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          type_index = bit;\n          break;\n        }\n      }\n      message << type_name(\n          static_cast<sourcemeta::core::JSON::Type>(type_index));\n    } else {\n      bool first{true};\n      std::uint8_t last_bit{255};\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          last_bit = bit;\n        }\n      }\n\n      for (std::uint8_t bit{0}; bit < 8; bit++) {\n        if (types.test(bit)) {\n          if (!first) {\n            message << \", \";\n          }\n          if (bit == last_bit) {\n            message << \"or \";\n          }\n          message << type_name(static_cast<sourcemeta::core::JSON::Type>(bit));\n          first = false;\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopContains) {\n    assert(target.is_array());\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueRange>(step)};\n    const auto &[minimum, maximum, exhaustive] = value;\n    bool plural{true};\n\n    message << \"The array value was expected to contain \";\n    if (maximum.has_value()) {\n      if (minimum == maximum.value() && minimum == 0) {\n        message << \"any number of\";\n      } else if (minimum == maximum.value()) {\n        message << \"exactly \" << minimum;\n        if (minimum == 1) {\n          plural = false;\n        }\n      } else if (minimum == 0) {\n        message << \"up to \" << maximum.value();\n        if (maximum.value() == 1) {\n          plural = false;\n        }\n      } else {\n        message << minimum << \" to \" << maximum.value();\n        if (maximum.value() == 1) {\n          plural = false;\n        }\n      }\n    } else {\n      message << \"at least \" << minimum;\n      if (minimum == 1) {\n        plural = false;\n      }\n    }\n\n    if (plural) {\n      message << \" items that validate against the given subschema\";\n    } else {\n      message << \" item that validates against the given subschema\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionDefines) {\n    std::ostringstream message;\n    message << \"The object value was expected to define the property \"\n            << escape_string(instruction_value<ValueProperty>(step).first);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionDefinesStrict) {\n    std::ostringstream message;\n    message\n        << \"The value was expected to be an object that defines the property \"\n        << escape_string(instruction_value<ValueProperty>(step).first);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionDefinesAll) {\n    const auto &value{instruction_value<ValueStringSet>(step)};\n    assert(value.size() > 1);\n\n    std::vector<ValueString> value_vector;\n    for (const auto &entry : value) {\n      value_vector.push_back(entry.first);\n    }\n\n    std::ostringstream message;\n    message << \"The object value was expected to define properties \";\n    for (auto iterator = value_vector.cbegin(); iterator != value_vector.cend();\n         ++iterator) {\n      if (std::next(iterator) == value_vector.cend()) {\n        message << \"and \" << escape_string(*iterator);\n      } else {\n        message << escape_string(*iterator) << \", \";\n      }\n    }\n\n    if (valid) {\n      return message.str();\n    }\n\n    assert(target.is_object());\n    std::set<std::string> missing;\n    for (const auto &property : value) {\n      if (!target.defines(property.first, property.second)) {\n        missing.insert(property.first);\n      }\n    }\n\n    assert(!missing.empty());\n    if (missing.size() == 1) {\n      message << \" but did not define the property \"\n              << escape_string(*(missing.cbegin()));\n    } else {\n      message << \" but did not define properties \";\n      for (auto iterator = missing.cbegin(); iterator != missing.cend();\n           ++iterator) {\n        if (std::next(iterator) == missing.cend()) {\n          message << \"and \" << escape_string(*iterator);\n        } else {\n          message << escape_string(*iterator) << \", \";\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionDefinesAllStrict) {\n    const auto &value{instruction_value<ValueStringSet>(step)};\n    assert(value.size() > 1);\n\n    std::vector<ValueString> value_vector;\n    for (const auto &entry : value) {\n      value_vector.push_back(entry.first);\n    }\n\n    std::ostringstream message;\n    message\n        << \"The value was expected to be an object that defines properties \";\n    for (auto iterator = value_vector.cbegin(); iterator != value_vector.cend();\n         ++iterator) {\n      if (std::next(iterator) == value_vector.cend()) {\n        message << \"and \" << escape_string(*iterator);\n      } else {\n        message << escape_string(*iterator) << \", \";\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionDefinesExactly) {\n    const auto &value{instruction_value<ValueStringSet>(step)};\n    assert(value.size() > 1);\n    std::vector<ValueString> value_vector;\n    for (const auto &entry : value) {\n      value_vector.push_back(entry.first);\n    }\n\n    std::ranges::sort(value_vector);\n    std::ostringstream message;\n    message << \"The object value was expected to only define properties \";\n    for (auto iterator = value_vector.cbegin(); iterator != value_vector.cend();\n         ++iterator) {\n      if (std::next(iterator) == value_vector.cend()) {\n        message << \"and \" << escape_string(*iterator);\n      } else {\n        message << escape_string(*iterator) << \", \";\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionDefinesExactlyStrict) {\n    const auto &value{instruction_value<ValueStringSet>(step)};\n    assert(value.size() > 1);\n    std::vector<ValueString> value_vector;\n    for (const auto &entry : value) {\n      value_vector.push_back(entry.first);\n    }\n\n    std::ranges::sort(value_vector);\n    std::ostringstream message;\n    message << \"The value was expected to be an object that only defines \"\n               \"properties \";\n    for (auto iterator = value_vector.cbegin(); iterator != value_vector.cend();\n         ++iterator) {\n      if (std::next(iterator) == value_vector.cend()) {\n        message << \"and \" << escape_string(*iterator);\n      } else {\n        message << escape_string(*iterator) << \", \";\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionDefinesExactlyStrictHash3) {\n    const auto &value{instruction_value<ValueStringHashes>(step).first};\n    std::ostringstream message;\n    message << \"The value was expected to be an object that only defines \"\n               \"the \"\n            << value.size() << \" given properties\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionType ||\n      step.type == sourcemeta::blaze::InstructionIndex::AssertionTypeStrict) {\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      std::ostringstream message;\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property())\n              << \" was expected to be of type \"\n              << type_name(instruction_value<ValueType>(step));\n      return message.str();\n    }\n\n    std::ostringstream message;\n    describe_type_check(valid, target.type(),\n                        instruction_value<ValueType>(step), message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionTypeAny) {\n    std::ostringstream message;\n    describe_types_check(valid, target.type(),\n                         instruction_value<ValueTypes>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny) {\n    std::ostringstream message;\n    describe_types_check(valid, target.type(),\n                         instruction_value<ValueTypes>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionNotTypeStrictAny) {\n    std::ostringstream message;\n    describe_not_types_check(valid, target.type(),\n                             instruction_value<ValueTypes>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeStringBounded) {\n    std::ostringstream message;\n\n    const auto &[minimum, maximum, exhaustive] =\n        instruction_value<ValueRange>(step);\n    if (minimum == 0 && maximum.has_value()) {\n      message << \"The value was expected to consist of a string of at most \"\n              << maximum.value()\n              << (maximum.value() == 1 ? \" character\" : \" characters\");\n    } else if (maximum.has_value()) {\n      message << \"The value was expected to consist of a string of \" << minimum\n              << \" to \" << maximum.value()\n              << (maximum.value() == 1 ? \" character\" : \" characters\");\n    } else {\n      message << \"The value was expected to consist of a string of at least \"\n              << minimum << (minimum == 1 ? \" character\" : \" characters\");\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeStringUpper) {\n    std::ostringstream message;\n    message << \"The value was expected to consist of a string of at most \"\n            << instruction_value<ValueUnsignedInteger>(step)\n            << (instruction_value<ValueUnsignedInteger>(step) == 1\n                    ? \" character\"\n                    : \" characters\");\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeArrayBounded) {\n    std::ostringstream message;\n\n    const auto &[minimum, maximum, exhaustive] =\n        instruction_value<ValueRange>(step);\n    if (minimum == 0 && maximum.has_value()) {\n      message << \"The value was expected to consist of an array of at most \"\n              << maximum.value() << (maximum.value() == 1 ? \" item\" : \" items\");\n    } else if (maximum.has_value()) {\n      message << \"The value was expected to consist of an array of \" << minimum\n              << \" to \" << maximum.value()\n              << (maximum.value() == 1 ? \" item\" : \" items\");\n    } else {\n      message << \"The value was expected to consist of an array of at least \"\n              << minimum << (minimum == 1 ? \" item\" : \" items\");\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeArrayUpper) {\n    std::ostringstream message;\n    message << \"The value was expected to consist of an array of at most \"\n            << instruction_value<ValueUnsignedInteger>(step)\n            << (instruction_value<ValueUnsignedInteger>(step) == 1 ? \" item\"\n                                                                   : \" items\");\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeObjectBounded) {\n    std::ostringstream message;\n\n    const auto &[minimum, maximum, exhaustive] =\n        instruction_value<ValueRange>(step);\n    if (minimum == 0 && maximum.has_value()) {\n      message << \"The value was expected to consist of an object of at most \"\n              << maximum.value()\n              << (maximum.value() == 1 ? \" property\" : \" properties\");\n    } else if (maximum.has_value()) {\n      message << \"The value was expected to consist of an object of \" << minimum\n              << \" to \" << maximum.value()\n              << (maximum.value() == 1 ? \" property\" : \" properties\");\n    } else {\n      message << \"The value was expected to consist of an object of at least \"\n              << minimum << (minimum == 1 ? \" property\" : \" properties\");\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionTypeObjectUpper) {\n    std::ostringstream message;\n    message << \"The value was expected to consist of an object of at most \"\n            << instruction_value<ValueUnsignedInteger>(step)\n            << (instruction_value<ValueUnsignedInteger>(step) == 1\n                    ? \" property\"\n                    : \" properties\");\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionRegex) {\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      std::ostringstream message;\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property())\n              << \" was expected to match the regular expression \"\n              << escape_string(instruction_value<ValueRegex>(step).second);\n      return message.str();\n    }\n\n    assert(target.is_string());\n    std::ostringstream message;\n    message << \"The string value \" << escape_string(target.to_string())\n            << \" was expected to match the regular expression \"\n            << escape_string(instruction_value<ValueRegex>(step).second);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionStringSizeLess) {\n    if (keyword == \"maxLength\") {\n      std::ostringstream message;\n      const auto maximum{instruction_value<ValueUnsignedInteger>(step) - 1};\n\n      if (is_within_keyword(evaluate_path, \"propertyNames\")) {\n        assert(instance_location.back().is_property());\n        message << \"The object property name \"\n                << escape_string(instance_location.back().to_property());\n      } else {\n        message << \"The string value \";\n        describe_stringify(target, message);\n      }\n\n      message << \" was expected to consist of at most \" << maximum\n              << (maximum == 1 ? \" character\" : \" characters\");\n\n      if (valid) {\n        message << \" and\";\n      } else {\n        message << \" but\";\n      }\n\n      message << \" it consisted of \";\n\n      if (is_within_keyword(evaluate_path, \"propertyNames\")) {\n        message << instance_location.back().to_property().size();\n        message << (instance_location.back().to_property().size() == 1\n                        ? \" character\"\n                        : \" characters\");\n      } else {\n        message << target.size();\n        message << (target.size() == 1 ? \" character\" : \" characters\");\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionStringSizeGreater) {\n    if (keyword == \"minLength\") {\n      std::ostringstream message;\n      const auto minimum{instruction_value<ValueUnsignedInteger>(step) + 1};\n\n      if (is_within_keyword(evaluate_path, \"propertyNames\")) {\n        assert(instance_location.back().is_property());\n        message << \"The object property name \"\n                << escape_string(instance_location.back().to_property());\n      } else {\n        message << \"The string value \";\n        describe_stringify(target, message);\n      }\n\n      message << \" was expected to consist of at least \" << minimum\n              << (minimum == 1 ? \" character\" : \" characters\");\n\n      if (valid) {\n        message << \" and\";\n      } else {\n        message << \" but\";\n      }\n\n      message << \" it consisted of \";\n\n      if (is_within_keyword(evaluate_path, \"propertyNames\")) {\n        message << instance_location.back().to_property().size();\n        message << (instance_location.back().to_property().size() == 1\n                        ? \" character\"\n                        : \" characters\");\n      } else {\n        message << target.size();\n        message << (target.size() == 1 ? \" character\" : \" characters\");\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionArraySizeLess) {\n    if (keyword == \"maxItems\") {\n      assert(target.is_array());\n      std::ostringstream message;\n      const auto maximum{instruction_value<ValueUnsignedInteger>(step) - 1};\n      message << \"The array value was expected to contain at most \" << maximum;\n      if (maximum == 1) {\n        message << \" item\";\n      } else {\n        message << \" items\";\n      }\n\n      if (valid) {\n        message << \" and\";\n      } else {\n        message << \" but\";\n      }\n\n      message << \" it contained \" << target.size();\n      if (target.size() == 1) {\n        message << \" item\";\n      } else {\n        message << \" items\";\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionArraySizeGreater) {\n    assert(target.is_array());\n    std::ostringstream message;\n    const auto minimum{instruction_value<ValueUnsignedInteger>(step) + 1};\n    message << \"The array value was expected to contain at least \" << minimum;\n    if (minimum == 1) {\n      message << \" item\";\n    } else {\n      message << \" items\";\n    }\n\n    if (valid) {\n      message << \" and\";\n    } else {\n      message << \" but\";\n    }\n\n    message << \" it contained \" << target.size();\n    if (target.size() == 1) {\n      message << \" item\";\n    } else {\n      message << \" items\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionObjectSizeLess) {\n    if (keyword == \"additionalProperties\") {\n      return \"The object value was not expected to define additional \"\n             \"properties\";\n    }\n\n    if (keyword == \"maxProperties\") {\n      assert(target.is_object());\n      std::ostringstream message;\n      const auto maximum{instruction_value<ValueUnsignedInteger>(step) - 1};\n      message << \"The object value was expected to contain at most \" << maximum;\n      if (maximum == 1) {\n        message << \" property\";\n      } else {\n        message << \" properties\";\n      }\n\n      if (valid) {\n        message << \" and\";\n      } else {\n        message << \" but\";\n      }\n\n      message << \" it contained \" << target.size();\n      if (target.size() == 0) {\n        message << \" properties\";\n      } else if (target.size() == 1) {\n        message << \" property: \";\n        message << escape_string(target.as_object().cbegin()->first);\n      } else {\n        message << \" properties: \";\n\n        std::vector<std::string> properties;\n        for (const auto &entry : target.as_object()) {\n          properties.push_back(entry.first);\n        }\n        std::ranges::sort(properties);\n\n        for (auto iterator = properties.cbegin(); iterator != properties.cend();\n             ++iterator) {\n          if (std::next(iterator) == properties.cend()) {\n            message << \"and \" << escape_string(*iterator);\n          } else {\n            message << escape_string(*iterator) << \", \";\n          }\n        }\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionObjectSizeGreater) {\n    if (keyword == \"minProperties\") {\n      assert(target.is_object());\n      std::ostringstream message;\n      const auto minimum{instruction_value<ValueUnsignedInteger>(step) + 1};\n      message << \"The object value was expected to contain at least \"\n              << minimum;\n      if (minimum == 1) {\n        message << \" property\";\n      } else {\n        message << \" properties\";\n      }\n\n      if (valid) {\n        message << \" and\";\n      } else {\n        message << \" but\";\n      }\n\n      message << \" it contained \" << target.size();\n      if (target.size() == 1) {\n        message << \" property: \";\n        message << escape_string(target.as_object().cbegin()->first);\n      } else {\n        message << \" properties: \";\n        std::vector<std::string> properties;\n        for (const auto &entry : target.as_object()) {\n          properties.push_back(entry.first);\n        }\n        std::ranges::sort(properties);\n\n        for (auto iterator = properties.cbegin(); iterator != properties.cend();\n             ++iterator) {\n          if (std::next(iterator) == properties.cend()) {\n            message << \"and \" << escape_string(*iterator);\n          } else {\n            message << escape_string(*iterator) << \", \";\n          }\n        }\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionEqual) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property());\n    } else {\n      message << \"The \" << type_name(target.type()) << \" value \";\n      describe_stringify(target, message);\n    }\n\n    message << \" was expected to equal the \" << type_name(value.type())\n            << \" constant \";\n    describe_stringify(value, message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionGreaterEqual) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n    message << \"The \" << value_type_name(target) << \" value \";\n    describe_stringify(target, message);\n    message << \" was expected to be greater than or equal to the \"\n            << value_type_name(value) << \" \";\n    describe_stringify(value, message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionLessEqual) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n    message << \"The \" << value_type_name(target) << \" value \";\n    describe_stringify(target, message);\n    message << \" was expected to be less than or equal to the \"\n            << value_type_name(value) << \" \";\n    describe_stringify(value, message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionGreater) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n    message << \"The \" << value_type_name(target) << \" value \";\n    describe_stringify(target, message);\n    message << \" was expected to be greater than the \" << value_type_name(value)\n            << \" \";\n    describe_stringify(value, message);\n    if (!valid && value == target) {\n      message << \", but they were equal\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionLess) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n    message << \"The \" << value_type_name(target) << \" value \";\n    describe_stringify(target, message);\n    message << \" was expected to be less than the \" << value_type_name(value)\n            << \" \";\n    describe_stringify(value, message);\n    if (!valid && value == target) {\n      message << \", but they were equal\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionUnique) {\n    assert(target.is_array());\n    auto array{target.as_array()};\n    std::ostringstream message;\n    if (valid) {\n      message << \"The array value was expected to not contain duplicate items\";\n    } else {\n      std::set<sourcemeta::core::JSON> duplicates;\n      for (auto iterator = array.cbegin(); iterator != array.cend();\n           ++iterator) {\n        for (auto subiterator = std::next(iterator);\n             subiterator != array.cend(); ++subiterator) {\n          if (*iterator == *subiterator) {\n            duplicates.insert(*iterator);\n          }\n        }\n      }\n\n      assert(!duplicates.empty());\n      message << \"The array value contained the following duplicate\";\n      if (duplicates.size() == 1) {\n        message << \" item: \";\n        describe_stringify(*(duplicates.cbegin()), message);\n      } else {\n        message << \" items: \";\n        for (auto subiterator = duplicates.cbegin();\n             subiterator != duplicates.cend(); ++subiterator) {\n          if (std::next(subiterator) == duplicates.cend()) {\n            message << \"and \";\n            describe_stringify(*subiterator, message);\n          } else {\n            describe_stringify(*subiterator, message);\n            message << \", \";\n          }\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionDivisible) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueJSON>(step)};\n    message << \"The \" << value_type_name(target) << \" value \";\n    describe_stringify(target, message);\n    message << \" was expected to be divisible by the \" << value_type_name(value)\n            << \" \";\n    describe_stringify(value, message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionEqualsAny) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueSet>(step)};\n    assert(!value.empty());\n\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property());\n    } else {\n      message << \"The \" << type_name(target.type()) << \" value \";\n      describe_stringify(target, message);\n    }\n\n    if (value.size() == 1) {\n      message << \" was expected to equal the \"\n              << type_name(value.cbegin()->type()) << \" constant \";\n      describe_stringify(*(value.cbegin()), message);\n    } else {\n      if (valid) {\n        message << \" was expected to equal one of the \" << value.size()\n                << \" declared values\";\n      } else {\n        message << \" was expected to equal one of the following values: \";\n        std::vector<sourcemeta::core::JSON> copy{value.cbegin(), value.cend()};\n        std::ranges::sort(copy);\n        for (auto iterator = copy.cbegin(); iterator != copy.cend();\n             ++iterator) {\n          if (std::next(iterator) == copy.cend()) {\n            message << \"and \";\n            describe_stringify(*iterator, message);\n          } else {\n            describe_stringify(*iterator, message);\n            message << \", \";\n          }\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionEqualsAnyStringHash) {\n    std::ostringstream message;\n    const auto &value{instruction_value<ValueStringHashes>(step).first};\n    assert(!value.empty());\n\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      message << \"The property name \"\n              << escape_string(instance_location.back().to_property());\n    } else {\n      message << \"The \" << type_name(target.type()) << \" value \";\n      describe_stringify(target, message);\n    }\n\n    if (value.size() == 1) {\n      message << \" was expected to equal the given constant\";\n    } else {\n      message << \" was expected to equal one of the given declared values\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionStringType) {\n    assert(target.is_string());\n    std::ostringstream message;\n    message << \"The string value \" << escape_string(target.to_string())\n            << \" was expected to represent a valid\";\n    switch (instruction_value<ValueStringType>(step)) {\n      case ValueStringType::URI:\n        message << \" URI\";\n        break;\n      default:\n        return unknown();\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionPropertyType) {\n    std::ostringstream message;\n    describe_type_check(valid, target.type(),\n                        instruction_value<ValueType>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionPropertyTypeEvaluate) {\n    std::ostringstream message;\n    describe_type_check(valid, target.type(),\n                        instruction_value<ValueType>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionPropertyTypeStrict) {\n    std::ostringstream message;\n    describe_type_check(valid, target.type(),\n                        instruction_value<ValueType>(step), message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::\n                       AssertionPropertyTypeStrictEvaluate) {\n    std::ostringstream message;\n    describe_type_check(valid, target.type(),\n                        instruction_value<ValueType>(step), message);\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionPropertyTypeStrictAny) {\n    std::ostringstream message;\n    describe_types_check(valid, target.type(),\n                         instruction_value<ValueTypes>(step), message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::\n                       AssertionPropertyTypeStrictAnyEvaluate) {\n    std::ostringstream message;\n    describe_types_check(valid, target.type(),\n                         instruction_value<ValueTypes>(step), message);\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::AssertionArrayPrefix) {\n    assert(keyword == \"items\" || keyword == \"prefixItems\");\n    assert(!step.children.empty());\n    assert(target.is_array());\n\n    std::ostringstream message;\n    message << \"The first \";\n    if (step.children.size() <= 2) {\n      message << \"item of the array value was\";\n    } else {\n      message << (step.children.size() - 1) << \" items of the array value were\";\n    }\n\n    message << \" expected to validate against the corresponding subschemas\";\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionArrayPrefixEvaluate) {\n    assert(keyword == \"items\" || keyword == \"prefixItems\");\n    assert(!step.children.empty());\n    assert(target.is_array());\n\n    std::ostringstream message;\n    message << \"The first \";\n    if (step.children.size() <= 2) {\n      message << \"item of the array value was\";\n    } else {\n      message << (step.children.size() - 1) << \" items of the array value were\";\n    }\n\n    message << \" expected to validate against the corresponding subschemas\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopPropertiesMatch) {\n    assert(!step.children.empty());\n    assert(target.is_object());\n    std::ostringstream message;\n    message << \"The object value was expected to validate against the \";\n    if (step.children.size() == 1) {\n      message << \"single defined property subschema\";\n    } else {\n      message << step.children.size() << \" defined properties subschemas\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesMatchClosed) {\n    assert(!step.children.empty());\n    assert(target.is_object());\n    std::ostringstream message;\n    if (step.children.size() == 1) {\n      message << \"The object value was expected to validate against the \";\n      message << \"single defined property subschema\";\n    } else {\n      message\n          << \"Every object value was expected to validate against one of the \";\n      message << step.children.size() << \" defined properties subschemas\";\n    }\n\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalWhenDefines) {\n    std::ostringstream message;\n    message << \"The object value defined the property \\\"\"\n            << instruction_value<ValueProperty>(step).first << \"\\\"\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LoopPropertiesRegex) {\n    assert(target.is_object());\n    std::ostringstream message;\n    message << \"The object properties that match the regular expression \\\"\"\n            << instruction_value<ValueRegex>(step).second\n            << \"\\\" were expected to validate against the defined pattern \"\n               \"property subschema\";\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesRegexClosed) {\n    assert(target.is_object());\n    std::ostringstream message;\n    message << \"The object properties were expected to match the regular \"\n               \"expression \\\"\"\n            << instruction_value<ValueRegex>(step).second\n            << \"\\\" and validate against the defined pattern \"\n               \"property subschema\";\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LoopPropertiesStartsWith) {\n    assert(target.is_object());\n    std::ostringstream message;\n    message << \"The object properties that start with the string \\\"\"\n            << instruction_value<ValueString>(step)\n            << \"\\\" were expected to validate against the defined pattern \"\n               \"property subschema\";\n    return message.str();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::LogicalWhenType) {\n    if (keyword == \"items\") {\n      std::ostringstream message;\n      describe_type_check(valid, target.type(),\n                          instruction_value<ValueType>(step), message);\n      return message.str();\n    }\n\n    if (keyword == \"properties\") {\n      assert(!step.children.empty());\n      if (!target.is_object()) {\n        std::ostringstream message;\n        describe_type_check(valid, target.type(),\n                            sourcemeta::core::JSON::Type::Object, message);\n        return message.str();\n      }\n\n      std::ostringstream message;\n      message << \"The object value was expected to validate against the \";\n      if (step.children.size() == 1) {\n        message << \"single defined property subschema\";\n      } else {\n        // We cannot provide the specific number of properties,\n        // as the number of children might be flatten out\n        // for performance reasons\n        message << \"defined properties subschemas\";\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"dependencies\") {\n      assert(target.is_object());\n      assert(!step.children.empty());\n\n      std::set<std::string> present;\n      std::set<std::string> present_with_schemas;\n      std::set<std::string> present_with_properties;\n      std::set<std::string> all_dependencies;\n      std::set<std::string> required_properties;\n\n      for (const auto &child : step.children) {\n        // Schema\n        if (child.type == InstructionIndex::LogicalWhenDefines) {\n          const auto &substep{child};\n          const auto &property{instruction_value<ValueProperty>(substep).first};\n          all_dependencies.insert(property);\n          if (!target.defines(property)) {\n            continue;\n          }\n\n          present.insert(property);\n          present_with_schemas.insert(property);\n\n          // Properties\n        } else {\n          assert(child.type == InstructionIndex::AssertionPropertyDependencies);\n          const auto &substep{child};\n\n          for (const auto &entry : std::get<ValueStringMap>(substep.value)) {\n            all_dependencies.insert(entry.first);\n            if (target.defines(entry.first)) {\n              present.insert(entry.first);\n              present_with_properties.insert(entry.first);\n              for (const auto &dependency : entry.second) {\n                if (valid || !target.defines(dependency)) {\n                  required_properties.insert(dependency);\n                }\n              }\n            }\n          }\n        }\n      }\n\n      std::ostringstream message;\n\n      if (present_with_schemas.empty() && present_with_properties.empty()) {\n        message << \"The object value did not define the\";\n        assert(!all_dependencies.empty());\n        if (all_dependencies.size() == 1) {\n          message << \" property \"\n                  << escape_string(*(all_dependencies.cbegin()));\n        } else {\n          message << \" properties \";\n          for (auto iterator = all_dependencies.cbegin();\n               iterator != all_dependencies.cend(); ++iterator) {\n            if (std::next(iterator) == all_dependencies.cend()) {\n              message << \"or \" << escape_string(*iterator);\n            } else {\n              message << escape_string(*iterator) << \", \";\n            }\n          }\n        }\n\n        return message.str();\n      }\n\n      if (present.size() == 1) {\n        message << \"Because the object value defined the\";\n        message << \" property \" << escape_string(*(present.cbegin()));\n      } else {\n        message << \"Because the object value defined the\";\n        message << \" properties \";\n        for (auto iterator = present.cbegin(); iterator != present.cend();\n             ++iterator) {\n          if (std::next(iterator) == present.cend()) {\n            message << \"and \" << escape_string(*iterator);\n          } else {\n            message << escape_string(*iterator) << \", \";\n          }\n        }\n      }\n\n      if (!required_properties.empty()) {\n        message << \", it was also expected to define the\";\n        if (required_properties.size() == 1) {\n          message << \" property \"\n                  << escape_string(*(required_properties.cbegin()));\n        } else {\n          message << \" properties \";\n          for (auto iterator = required_properties.cbegin();\n               iterator != required_properties.cend(); ++iterator) {\n            if (std::next(iterator) == required_properties.cend()) {\n              message << \"and \" << escape_string(*iterator);\n            } else {\n              message << escape_string(*iterator) << \", \";\n            }\n          }\n        }\n      }\n\n      if (!present_with_schemas.empty()) {\n        message << \", \";\n        if (!required_properties.empty()) {\n          message << \"and \";\n        }\n\n        message << \"it was also expected to successfully validate against the \"\n                   \"corresponding \";\n        if (present_with_schemas.size() == 1) {\n          message << escape_string(*(present_with_schemas.cbegin()));\n          message << \" subschema\";\n        } else {\n          for (auto iterator = present_with_schemas.cbegin();\n               iterator != present_with_schemas.cend(); ++iterator) {\n            if (std::next(iterator) == present_with_schemas.cend()) {\n              message << \"and \" << escape_string(*iterator);\n            } else {\n              message << escape_string(*iterator) << \", \";\n            }\n          }\n\n          message << \" subschemas\";\n        }\n      }\n\n      return message.str();\n    }\n\n    if (keyword == \"dependentSchemas\") {\n      assert(target.is_object());\n      assert(!step.children.empty());\n      std::set<std::string> present;\n      std::set<std::string> all_dependencies;\n      for (const auto &child : step.children) {\n        assert(child.type == InstructionIndex::LogicalWhenDefines);\n        const auto &substep{child};\n        const auto &property{instruction_value<ValueProperty>(substep).first};\n        all_dependencies.insert(property);\n        if (!target.defines(property)) {\n          continue;\n        }\n\n        present.insert(property);\n      }\n\n      std::ostringstream message;\n\n      if (present.empty()) {\n        message << \"The object value did not define the\";\n        assert(!all_dependencies.empty());\n        if (all_dependencies.size() == 1) {\n          message << \" property \"\n                  << escape_string(*(all_dependencies.cbegin()));\n        } else {\n          message << \" properties \";\n          for (auto iterator = all_dependencies.cbegin();\n               iterator != all_dependencies.cend(); ++iterator) {\n            if (std::next(iterator) == all_dependencies.cend()) {\n              message << \"or \" << escape_string(*iterator);\n            } else {\n              message << escape_string(*iterator) << \", \";\n            }\n          }\n        }\n      } else if (present.size() == 1) {\n        message << \"Because the object value defined the\";\n        message << \" property \" << escape_string(*(present.cbegin()));\n        message\n            << \", it was also expected to validate against the corresponding \"\n               \"subschema\";\n      } else {\n        message << \"Because the object value defined the\";\n        message << \" properties \";\n        for (auto iterator = present.cbegin(); iterator != present.cend();\n             ++iterator) {\n          if (std::next(iterator) == present.cend()) {\n            message << \"and \" << escape_string(*iterator);\n          } else {\n            message << escape_string(*iterator) << \", \";\n          }\n        }\n\n        message\n            << \", it was also expected to validate against the corresponding \"\n               \"subschemas\";\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::AssertionPropertyDependencies) {\n    assert(target.is_object());\n    std::set<std::string> present;\n    std::set<std::string> all_dependencies;\n    std::set<std::string> required;\n\n    for (const auto &entry : instruction_value<ValueStringMap>(step)) {\n      all_dependencies.insert(entry.first);\n      if (target.defines(entry.first)) {\n        present.insert(entry.first);\n        for (const auto &dependency : entry.second) {\n          if (valid || !target.defines(dependency)) {\n            required.insert(dependency);\n          }\n        }\n      }\n    }\n\n    std::ostringstream message;\n\n    if (present.empty()) {\n      message << \"The object value did not define the\";\n      assert(!all_dependencies.empty());\n      if (all_dependencies.size() == 1) {\n        message << \" property \" << escape_string(*(all_dependencies.cbegin()));\n      } else {\n        message << \" properties \";\n        for (auto iterator = all_dependencies.cbegin();\n             iterator != all_dependencies.cend(); ++iterator) {\n          if (std::next(iterator) == all_dependencies.cend()) {\n            message << \"or \" << escape_string(*iterator);\n          } else {\n            message << escape_string(*iterator) << \", \";\n          }\n        }\n      }\n\n      return message.str();\n    } else if (present.size() == 1) {\n      message << \"Because the object value defined the\";\n      message << \" property \" << escape_string(*(present.cbegin()));\n    } else {\n      message << \"Because the object value defined the\";\n      message << \" properties \";\n      for (auto iterator = present.cbegin(); iterator != present.cend();\n           ++iterator) {\n        if (std::next(iterator) == present.cend()) {\n          message << \"and \" << escape_string(*iterator);\n        } else {\n          message << escape_string(*iterator) << \", \";\n        }\n      }\n    }\n\n    assert(!required.empty());\n    message << \", it was also expected to define the\";\n    if (required.size() == 1) {\n      message << \" property \" << escape_string(*(required.cbegin()));\n    } else {\n      message << \" properties \";\n      for (auto iterator = required.cbegin(); iterator != required.cend();\n           ++iterator) {\n        if (std::next(iterator) == required.cend()) {\n          message << \"and \" << escape_string(*iterator);\n        } else {\n          message << escape_string(*iterator) << \", \";\n        }\n      }\n    }\n\n    return message.str();\n  }\n\n  if (step.type ==\n      sourcemeta::blaze::InstructionIndex::LogicalWhenArraySizeGreater) {\n    if (keyword == \"additionalItems\" || keyword == \"items\") {\n      assert(target.is_array());\n      std::ostringstream message;\n\n      if (target.size() > instruction_value<ValueUnsignedInteger>(step)) {\n        const auto rest{target.size() -\n                        instruction_value<ValueUnsignedInteger>(step)};\n        message << \"The array value contains \" << rest << \" additional\"\n                << (rest == 1 ? \" item\" : \" items\")\n                << \" not described by related keywords\";\n      } else {\n        message << \"The array value does not contain additional items not \"\n                   \"described by related keywords\";\n      }\n\n      return message.str();\n    }\n\n    return unknown();\n  }\n\n  if (step.type == sourcemeta::blaze::InstructionIndex::ControlJump) {\n    if (std::ranges::any_of(evaluate_path,\n                            [](const auto &token) {\n                              return token.is_property() &&\n                                     token.to_property() == \"propertyNames\";\n                            }) &&\n        !instance_location.empty() && instance_location.back().is_property()) {\n      std::ostringstream message;\n      message << \"The string value was expected to validate against the \"\n                 \"referenced schema\";\n      return message.str();\n    }\n\n    return describe_reference(target);\n  }\n\n  return unknown();\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/evaluator_json.cc",
    "content": "#include <sourcemeta/blaze/evaluator.h>\n\n#include <cassert> // assert\n#include <utility> // std::unreachable\n\nnamespace {\nauto value_from_json(const sourcemeta::core::JSON &wrapper)\n    -> std::optional<sourcemeta::blaze::Value> {\n  if (!wrapper.is_array() || wrapper.array_size() == 0 ||\n      !wrapper.at(0).is_integer()) {\n    return std::nullopt;\n  } else if (wrapper.array_size() == 1) {\n    return sourcemeta::blaze::ValueNone{};\n  }\n\n  const auto &value{wrapper.at(1)};\n\n  using namespace sourcemeta::blaze;\n  switch (wrapper.at(0).to_integer()) {\n      // clang-format off\n    case 0:  return ValueNone{};\n    case 1:  return sourcemeta::core::from_json<ValueJSON>(value);\n    case 2:  return sourcemeta::core::from_json<ValueSet>(value);\n    case 3:  return sourcemeta::core::from_json<ValueString>(value);\n    case 4:  return sourcemeta::core::from_json<ValueProperty>(value);\n    case 5:  return sourcemeta::core::from_json<ValueStrings>(value);\n    case 6:  return sourcemeta::core::from_json<ValueStringSet>(value);\n    case 7:  return sourcemeta::core::from_json<ValueTypes>(value);\n    case 8:  return sourcemeta::core::from_json<ValueType>(value);\n    case 9:  return sourcemeta::core::from_json<ValueRegex>(value);\n    case 10: return sourcemeta::core::from_json<ValueUnsignedInteger>(value);\n    case 11: return sourcemeta::core::from_json<ValueRange>(value);\n    case 12: return sourcemeta::core::from_json<ValueBoolean>(value);\n    case 13: return sourcemeta::core::from_json<ValueNamedIndexes>(value);\n    case 14: return sourcemeta::core::from_json<ValueStringType>(value);\n    case 15: return sourcemeta::core::from_json<ValueStringMap>(value);\n    case 16: return sourcemeta::core::from_json<ValuePropertyFilter>(value);\n    case 17: return sourcemeta::core::from_json<ValueIndexPair>(value);\n    case 18: return sourcemeta::core::from_json<ValuePointer>(value);\n    case 19: return sourcemeta::core::from_json<ValueTypedProperties>(value);\n    case 20: return sourcemeta::core::from_json<ValueStringHashes>(value);\n    case 21: return sourcemeta::core::from_json<ValueTypedHashes>(value);\n    case 22: return sourcemeta::core::from_json<ValueIntegerBounds>(value);\n    case 23: return sourcemeta::core::from_json<ValueIntegerBoundsWithSize>(value);\n    case 24: return sourcemeta::core::from_json<ValueObjectProperties>(value);\n    // clang-format on\n    default:\n      std::unreachable();\n  }\n}\n\nauto instructions_from_json(\n    const sourcemeta::core::JSON &instructions,\n    std::vector<sourcemeta::blaze::InstructionExtra> &extra)\n    -> std::optional<sourcemeta::blaze::Instructions> {\n  if (!instructions.is_array()) {\n    return std::nullopt;\n  }\n\n  sourcemeta::blaze::Instructions result;\n  result.reserve(instructions.size());\n  for (const auto &instruction : instructions.as_array()) {\n    if (!instruction.is_array() || instruction.array_size() < 6) {\n      return std::nullopt;\n    }\n\n    const auto &type{instruction.at(0)};\n    const auto &relative_schema_location{instruction.at(1)};\n    const auto &relative_instance_location{instruction.at(2)};\n    const auto &keyword_location{instruction.at(3)};\n    const auto &schema_resource{instruction.at(4)};\n    const auto &value{instruction.at(5)};\n\n    auto type_result{\n        sourcemeta::core::from_json<sourcemeta::blaze::InstructionIndex>(type)};\n    auto relative_schema_location_result{\n        sourcemeta::core::from_json<sourcemeta::core::Pointer>(\n            relative_schema_location)};\n    auto relative_instance_location_result{\n        sourcemeta::core::from_json<sourcemeta::core::Pointer>(\n            relative_instance_location)};\n    auto keyword_location_result{\n        sourcemeta::core::from_json<std::string>(keyword_location)};\n    auto schema_resource_result{\n        sourcemeta::core::from_json<std::size_t>(schema_resource)};\n    auto value_result{value_from_json(value)};\n\n    // Parse children if there\n    std::optional<sourcemeta::blaze::Instructions> children_result{\n        instruction.array_size() == 7\n            ? instructions_from_json(instruction.at(6), extra)\n            : sourcemeta::blaze::Instructions{}};\n\n    if (!type_result.has_value() ||\n        !relative_schema_location_result.has_value() ||\n        !relative_instance_location_result.has_value() ||\n        !keyword_location_result.has_value() ||\n        !schema_resource_result.has_value() || !value_result.has_value() ||\n        !children_result.has_value()) {\n      return std::nullopt;\n    }\n\n    const auto extra_index{extra.size()};\n    extra.push_back(\n        {.relative_schema_location =\n             std::move(relative_schema_location_result).value(),\n         .keyword_location = std::move(keyword_location_result).value(),\n         .schema_resource = std::move(schema_resource_result).value()});\n\n    // TODO: Maybe we should emplace here?\n    result.push_back({std::move(type_result).value(),\n                      std::move(relative_instance_location_result).value(),\n                      std::move(value_result).value(),\n                      std::move(children_result).value(), extra_index});\n  }\n\n  return result;\n}\n\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto from_json(const sourcemeta::core::JSON &json) -> std::optional<Template> {\n  if (!json.is_array() || json.array_size() != 5) {\n    return std::nullopt;\n  }\n\n  const auto &version{json.at(0)};\n  if (!version.is_integer() ||\n      version.to_integer() != static_cast<std::int64_t>(JSON_VERSION)) {\n    return std::nullopt;\n  }\n\n  const auto &dynamic{json.at(1)};\n  const auto &track{json.at(2)};\n\n  if (!dynamic.is_boolean() || !track.is_boolean()) {\n    return std::nullopt;\n  }\n\n  const auto &targets{json.at(3)};\n  if (!targets.is_array()) {\n    return std::nullopt;\n  }\n\n  std::vector<InstructionExtra> template_extra;\n  std::vector<Instructions> targets_result;\n  targets_result.reserve(targets.size());\n  for (const auto &target : targets.as_array()) {\n    auto target_result{instructions_from_json(target, template_extra)};\n    if (!target_result.has_value()) {\n      return std::nullopt;\n    }\n    targets_result.push_back(std::move(target_result).value());\n  }\n\n  const auto &labels{json.at(4)};\n  if (!labels.is_array()) {\n    return std::nullopt;\n  }\n\n  std::vector<std::pair<std::size_t, std::size_t>> labels_result;\n  labels_result.reserve(labels.size());\n  for (const auto &label : labels.as_array()) {\n    if (!label.is_array() || label.array_size() != 2 ||\n        !label.at(0).is_integer() || !label.at(1).is_integer()) {\n      return std::nullopt;\n    }\n    labels_result.emplace_back(\n        static_cast<std::size_t>(label.at(0).to_integer()),\n        static_cast<std::size_t>(label.at(1).to_integer()));\n  }\n\n  return Template{.dynamic = dynamic.to_boolean(),\n                  .track = track.to_boolean(),\n                  .targets = std::move(targets_result),\n                  .labels = std::move(labels_result),\n                  .extra = std::move(template_extra)};\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_H_\n#define SOURCEMETA_BLAZE_EVALUATOR_H_\n\n#ifndef SOURCEMETA_BLAZE_EVALUATOR_EXPORT\n#include <sourcemeta/blaze/evaluator_export.h>\n#endif\n\n#include <sourcemeta/blaze/evaluator_error.h>\n#include <sourcemeta/blaze/evaluator_instruction.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/regex.h>\n\n#include <algorithm>   // std::min, std::any_of, std::find\n#include <cassert>     // assert\n#include <cstdint>     // std::uint8_t\n#include <functional>  // std::function\n#include <limits>      // std::numeric_limits\n#include <ranges>      // std::ranges\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n#include <vector>      // std::vector\n\n/// @defgroup evaluator Evaluator\n/// @brief A high-performance JSON Schema evaluator\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/evaluator.h>\n/// ```\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup evaluator\n/// Represents a compiled schema ready for execution\nstruct Template {\n  bool dynamic;\n  bool track;\n  std::vector<Instructions> targets;\n  std::vector<std::pair<std::size_t, std::size_t>> labels;\n  std::vector<InstructionExtra> extra;\n};\n\n/// @ingroup evaluator\nconstexpr std::size_t JSON_VERSION{5};\n\n/// @ingroup evaluator\n/// Parse a template from JSON\nauto SOURCEMETA_BLAZE_EVALUATOR_EXPORT\nfrom_json(const sourcemeta::core::JSON &json) -> std::optional<Template>;\n\n/// @ingroup evaluator\n/// Represents the state of an instruction evaluation\nenum class EvaluationType : std::uint8_t { Pre, Post };\n\n/// @ingroup evaluator\n/// A callback of this type is invoked after evaluating any keyword. The\n/// arguments go as follows:\n///\n/// - The stage at which the instruction in question is\n/// - Whether the evaluation was successful or not (always true before\n/// evaluation)\n/// - The instruction that was just evaluated\n/// - The extra data associated with the instruction\n/// - The evaluation path\n/// - The instance location\n/// - The annotation result, if any (otherwise null)\n///\n/// You can use this callback mechanism to implement arbitrary output formats.\n// TODO(C++23): Use std::move_only_function when available in libc++\nusing Callback = std::function<void(\n    const EvaluationType, bool, const Instruction &, const InstructionExtra &,\n    const sourcemeta::core::WeakPointer &,\n    const sourcemeta::core::WeakPointer &, const sourcemeta::core::JSON &)>;\n\n/// @ingroup evaluator\nclass SOURCEMETA_BLAZE_EVALUATOR_EXPORT Evaluator {\npublic:\n  /// This function evaluates a schema compiler template, returning a boolean\n  /// without error information. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/blaze/evaluator.h>\n  /// #include <sourcemeta/blaze/compiler.h>\n  ///\n  /// #include <sourcemeta/core/json.h>\n  /// #include <sourcemeta/core/jsonschema.h>\n  ///\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON schema =\n  ///     sourcemeta::core::parse_json(R\"JSON({\n  ///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  ///   \"type\": \"string\"\n  /// })JSON\");\n  ///\n  /// const auto schema_template{sourcemeta::blaze::compile(\n  ///     schema, sourcemeta::core::schema_walker,\n  ///     sourcemeta::core::schema_resolver,\n  ///     sourcemeta::core::default_schema_compiler)};\n  ///\n  /// sourcemeta::blaze::Evaluator evaluator;\n  /// const sourcemeta::core::JSON instance{\"foo bar\"};\n  /// const auto result{evaluator.validate(schema_template, instance)};\n  /// assert(result);\n  /// ```\n  inline auto validate(const Template &schema,\n                       const sourcemeta::core::JSON &instance) -> bool {\n    assert(this->evaluate_path.empty());\n    assert(this->instance_location.empty());\n    assert(this->resources.empty());\n\n    if (schema.track && schema.dynamic) [[unlikely]] {\n      this->evaluated_.clear();\n      return this->evaluate_impl<true, true, false>(schema, instance, nullptr);\n    } else if (schema.track) [[unlikely]] {\n      this->evaluated_.clear();\n      return this->evaluate_impl<true, false, false>(schema, instance, nullptr);\n    } else if (schema.dynamic) [[unlikely]] {\n      return this->evaluate_impl<false, true, false>(schema, instance, nullptr);\n    } else {\n      return this->evaluate_impl<false, false, false>(schema, instance,\n                                                      nullptr);\n    }\n  }\n\n  /// This method evaluates a schema compiler template, executing the given\n  /// callback at every step of the way. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/blaze/evaluator.h>\n  /// #include <sourcemeta/blaze/compiler.h>\n  ///\n  /// #include <sourcemeta/core/json.h>\n  /// #include <sourcemeta/core/jsonschema.h>\n  ///\n  /// #include <cassert>\n  /// #include <iostream>\n  ///\n  /// const sourcemeta::core::JSON schema =\n  ///     sourcemeta::core::parse_json(R\"JSON({\n  ///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  ///   \"type\": \"string\"\n  /// })JSON\");\n  ///\n  /// const auto schema_template{sourcemeta::blaze::compile(\n  ///     schema, sourcemeta::core::schema_walker,\n  ///     sourcemeta::core::schema_resolver,\n  ///     sourcemeta::core::default_schema_compiler)};\n  ///\n  /// static auto callback(\n  ///     bool result,\n  ///     const sourcemeta::blaze::Instruction &instruction,\n  ///     const sourcemeta::core::Pointer &evaluate_path,\n  ///     const sourcemeta::core::Pointer &instance_location,\n  ///     const sourcemeta::core::JSON &document,\n  ///     const sourcemeta::core::JSON &annotation) -> void {\n  ///   std::cout << \"TYPE: \" << (result ? \"Success\" : \"Failure\") << \"\\n\";\n  ///   std::cout << \"INSTRUCTION:\\n\";\n  ///   sourcemeta::core::prettify(sourcemeta::blaze::to_json({instruction}),\n  ///                                     std::cout);\n  ///   std::cout << \"\\nEVALUATE PATH:\";\n  ///   sourcemeta::core::stringify(evaluate_path, std::cout);\n  ///   std::cout << \"\\nINSTANCE LOCATION:\";\n  ///   sourcemeta::core::stringify(instance_location, std::cout);\n  ///   std::cout << \"\\nANNOTATION:\\n\";\n  ///   sourcemeta::core::prettify(annotation, std::cout);\n  ///   std::cout << \"\\n\";\n  /// }\n  ///\n  /// sourcemeta::blaze::Evaluator evaluator;\n  /// const sourcemeta::core::JSON instance{\"foo bar\"};\n  /// const auto result{evaluator.validate(\n  ///   schema_template, instance, callback)};\n  ///\n  /// assert(result);\n  /// ```\n  inline auto validate(const Template &schema,\n                       const sourcemeta::core::JSON &instance,\n                       const Callback &callback) -> bool {\n    assert(this->evaluate_path.empty());\n    assert(this->instance_location.empty());\n    assert(this->resources.empty());\n    this->evaluated_.clear();\n    return this->evaluate_impl<true, true, true>(schema, instance, &callback);\n  }\n\n#ifndef DOXYGEN\n  template <bool Track, bool Dynamic, bool HasCallback>\n  auto evaluate_impl(const Template &schema,\n                     const sourcemeta::core::JSON &instance,\n                     const Callback *callback) -> bool;\n\n  // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)\n  static inline const sourcemeta::core::JSON null{nullptr};\n  static inline const sourcemeta::core::JSON empty_string{\"\"};\n  // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)\n\n  // Compute a hash that fits within the IEEE 754 double-precision safe\n  // integer range (2^53 - 1), ensuring the serialized template labels\n  // are usable from JavaScript and other languages whose numbers are doubles\n  [[nodiscard]] static auto hash(const std::size_t resource,\n                                 const std::string_view fragment) noexcept\n      -> std::size_t {\n    constexpr std::size_t mask{(1ULL << 53) - 1};\n    std::size_t result{14695981039346656037ULL & mask};\n    for (const auto byte : fragment) {\n      result ^= static_cast<std::size_t>(static_cast<unsigned char>(byte));\n      result = (result * 1099511628211ULL) & mask;\n    }\n\n    return (resource + result) & mask;\n  }\n\n  auto evaluate(const sourcemeta::core::JSON *target) -> void {\n    Evaluation mark{.instance = target,\n                    .evaluate_path = this->evaluate_path,\n                    .skip = false};\n    this->evaluated_.push_back(std::move(mark));\n  }\n\n  [[nodiscard]] auto is_evaluated(const sourcemeta::core::JSON *target) const\n      -> bool {\n    // NOLINTNEXTLINE(modernize-loop-convert)\n    for (auto iterator = this->evaluated_.rbegin();\n         iterator != this->evaluated_.rend(); ++iterator) {\n      if (target == iterator->instance && !iterator->skip &&\n          iterator->evaluate_path.starts_with_initial(this->evaluate_path)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto unevaluate() -> void {\n    for (auto &entry : this->evaluated_) {\n      if (!entry.skip && entry.evaluate_path.starts_with(this->evaluate_path)) {\n        entry.skip = true;\n      }\n    }\n  }\n\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n  sourcemeta::core::WeakPointer evaluate_path;\n  sourcemeta::core::WeakPointer instance_location;\n  std::vector<std::size_t> resources;\n\n  struct Evaluation {\n    const sourcemeta::core::JSON *instance;\n    sourcemeta::core::WeakPointer evaluate_path;\n    bool skip;\n  };\n\n  std::vector<Evaluation> evaluated_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n#endif\n};\n\n} // namespace sourcemeta::blaze\n\n#ifndef DOXYGEN\n\n#include <sourcemeta/blaze/evaluator_dispatch.h>\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\nauto sourcemeta::blaze::Evaluator::evaluate_impl(\n    const Template &schema, const sourcemeta::core::JSON &instance,\n    const Callback *callback) -> bool {\n  assert(!schema.targets.empty());\n  dispatch::DispatchContext<Track, Dynamic, HasCallback> context{\n      .schema = &schema,\n      .callback = callback,\n      .evaluator = this,\n      .property_target = nullptr};\n  bool overall{true};\n  for (const auto &instruction : schema.targets[0]) {\n    if (!dispatch::evaluate_instruction(instruction, instance, 0, context))\n        [[unlikely]] {\n      overall = false;\n      break;\n    }\n  }\n\n  if constexpr (Track || HasCallback) {\n    assert(this->evaluate_path.empty());\n  }\n  if constexpr (HasCallback) {\n    assert(this->instance_location.empty());\n  }\n  if constexpr (Dynamic) {\n    assert(this->resources.empty());\n  }\n\n  return overall;\n}\n\n#endif // !DOXYGEN\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator_dispatch.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_DISPATCH_H_\n#define SOURCEMETA_BLAZE_EVALUATOR_DISPATCH_H_\n\n#include <sourcemeta/blaze/evaluator.h>\n\n// TODO(C++23): Replace SOURCEMETA_ASSUME with [[assume]] when available\n// across all compilers (Clang 19, GCC 13)\n#if defined(__clang__)\n#define SOURCEMETA_ASSUME(x)                                                   \\\n  assert(x);                                                                   \\\n  __builtin_assume(x)\n#else\n#define SOURCEMETA_ASSUME(x) assert(x)\n#endif\n\n#define SOURCEMETA_STRINGIFY(x) #x\n\n#define EVALUATE_PUSH()                                                        \\\n  if constexpr (Track) {                                                       \\\n    context.evaluator->evaluate_path.push_back(                                \\\n        context.schema->extra[instruction.extra_index]                         \\\n            .relative_schema_location);                                        \\\n  }                                                                            \\\n  if constexpr (HasCallback) {                                                 \\\n    context.evaluator->instance_location.push_back(                            \\\n        instruction.relative_instance_location);                               \\\n  }                                                                            \\\n  if constexpr (Dynamic) {                                                     \\\n    context.evaluator->resources.push_back(                                    \\\n        context.schema->extra[instruction.extra_index].schema_resource);       \\\n  }                                                                            \\\n  if constexpr (HasCallback) {                                                 \\\n    (*context.callback)(EvaluationType::Pre, true, instruction,                \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path,                      \\\n                        context.evaluator->instance_location,                  \\\n                        Evaluator::null);                                      \\\n  }\n\n#define EVALUATE_POP()                                                         \\\n  if constexpr (HasCallback) {                                                 \\\n    (*context.callback)(EvaluationType::Post, result, instruction,             \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path,                      \\\n                        context.evaluator->instance_location,                  \\\n                        Evaluator::null);                                      \\\n  }                                                                            \\\n  if constexpr (Track) {                                                       \\\n    context.evaluator->evaluate_path.pop_back(                                 \\\n        context.schema->extra[instruction.extra_index]                         \\\n            .relative_schema_location.size());                                 \\\n  }                                                                            \\\n  if constexpr (HasCallback) {                                                 \\\n    context.evaluator->instance_location.pop_back(                             \\\n        instruction.relative_instance_location.size());                        \\\n  }                                                                            \\\n  if constexpr (Dynamic) {                                                     \\\n    context.evaluator->resources.pop_back();                                   \\\n  }\n\n#define EVALUATE_BEGIN(instruction_type, precondition)                         \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  const auto &target{resolve_target(                                           \\\n      context.property_target,                                                 \\\n      resolve_instance(instance, instruction.relative_instance_location))};    \\\n  if (!(precondition)) [[unlikely]] {                                          \\\n    return true;                                                               \\\n  }                                                                            \\\n  [[maybe_unused]] constexpr bool track{Track || HasCallback};                 \\\n  EVALUATE_PUSH()                                                              \\\n  bool result{false};\n\n#define EVALUATE_BEGIN_NON_STRING(instruction_type, precondition)              \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  const auto &target{                                                          \\\n      resolve_instance(instance, instruction.relative_instance_location)};     \\\n  if (!(precondition)) [[unlikely]] {                                          \\\n    return true;                                                               \\\n  }                                                                            \\\n  [[maybe_unused]] constexpr bool track{Track || HasCallback};                 \\\n  EVALUATE_PUSH()                                                              \\\n  bool result{false};\n\n#define EVALUATE_BEGIN_IF_STRING(instruction_type)                             \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  const auto *maybe_target{                                                    \\\n      resolve_string_target(context.property_target, instance,                 \\\n                            instruction.relative_instance_location)};          \\\n  if (!maybe_target) [[unlikely]] {                                            \\\n    return true;                                                               \\\n  }                                                                            \\\n  EVALUATE_PUSH()                                                              \\\n  const auto &target{*maybe_target};                                           \\\n  bool result{false};\n\n#define EVALUATE_BEGIN_TRY_TARGET(instruction_type)                            \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  const auto &target{instance};                                                \\\n  if (!target.is_object()) [[unlikely]] {                                      \\\n    return true;                                                               \\\n  }                                                                            \\\n  assert(!instruction.relative_instance_location.empty());                     \\\n  const auto *target_check{                                                    \\\n      instruction.relative_instance_location.size() == 1                       \\\n          ? target.try_at(                                                     \\\n                instruction.relative_instance_location.at(0).to_property(),    \\\n                instruction.relative_instance_location.at(0).property_hash())  \\\n          : try_get(target, instruction.relative_instance_location)};          \\\n  if (!target_check) [[unlikely]] {                                            \\\n    return true;                                                               \\\n  }                                                                            \\\n  EVALUATE_PUSH()                                                              \\\n  bool result{false};\n\n#define EVALUATE_BEGIN_NO_PRECONDITION(instruction_type)                       \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  [[maybe_unused]] constexpr bool track{Track || HasCallback};                 \\\n  EVALUATE_PUSH()                                                              \\\n  bool result{false};\n\n#define EVALUATE_BEGIN_NO_PRECONDITION_AND_NO_PUSH(instruction_type)           \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  if constexpr (HasCallback) {                                                 \\\n    (*context.callback)(EvaluationType::Pre, true, instruction,                \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path,                      \\\n                        context.evaluator->instance_location,                  \\\n                        Evaluator::null);                                      \\\n  }                                                                            \\\n  bool result{true};\n\n#define EVALUATE_BEGIN_PASS_THROUGH(instruction_type)                          \\\n  assert(instruction.type == InstructionIndex::instruction_type);              \\\n  bool result{true};\n\n#define EVALUATE_END(instruction_type)                                         \\\n  EVALUATE_POP()                                                               \\\n  return result;\n\n#define EVALUATE_END_NO_POP(instruction_type)                                  \\\n  if constexpr (HasCallback) {                                                 \\\n    (*context.callback)(EvaluationType::Post, result, instruction,             \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path,                      \\\n                        context.evaluator->instance_location,                  \\\n                        Evaluator::null);                                      \\\n  }                                                                            \\\n  return result;\n\n#define EVALUATE_END_PASS_THROUGH(instruction_type) return result;\n\n#define EVALUATE_ANNOTATION(instruction_type, destination, annotation_value)   \\\n  if constexpr (HasCallback) {                                                 \\\n    context.evaluator->evaluate_path.push_back(                                \\\n        context.schema->extra[instruction.extra_index]                         \\\n            .relative_schema_location);                                        \\\n    context.evaluator->instance_location.push_back(                            \\\n        instruction.relative_instance_location);                               \\\n    (*context.callback)(EvaluationType::Pre, true, instruction,                \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path, destination,         \\\n                        Evaluator::null);                                      \\\n    (*context.callback)(EvaluationType::Post, true, instruction,               \\\n                        context.schema->extra[instruction.extra_index],        \\\n                        context.evaluator->evaluate_path, destination,         \\\n                        annotation_value);                                     \\\n    context.evaluator->evaluate_path.pop_back(                                 \\\n        context.schema->extra[instruction.extra_index]                         \\\n            .relative_schema_location.size());                                 \\\n    context.evaluator->instance_location.pop_back(                             \\\n        instruction.relative_instance_location.size());                        \\\n  }                                                                            \\\n  return true;\n\n#define EVALUATE_RECURSE(child, target)                                        \\\n  evaluate_instruction(child, target, depth + 1, context)\n#define EVALUATE_RECURSE_ON_PROPERTY_NAME(child, target, name)                 \\\n  evaluate_instruction_with_property(child, target, depth + 1, context, name)\n\nnamespace sourcemeta::blaze::dispatch {\nusing namespace sourcemeta::core;\n\ninline auto resolve_target(const JSON::String *property_target,\n                           const JSON &instance) noexcept -> const JSON & {\n  if (property_target) [[unlikely]] {\n    return Evaluator::empty_string;\n  }\n\n  // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)\n  return instance;\n}\n\ninline auto resolve_instance(const JSON &instance,\n                             const Pointer &relative_instance_location)\n    -> const JSON & {\n  if (relative_instance_location.empty()) {\n    // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)\n    return instance;\n  }\n\n  return get(instance, relative_instance_location);\n}\n\ninline auto\nresolve_string_target(const JSON::String *property_target, const JSON &instance,\n                      const Pointer &relative_instance_location) noexcept\n    -> const JSON::String * {\n  if (property_target) [[unlikely]] {\n    return property_target;\n  }\n\n  const auto &target{resolve_instance(instance, relative_instance_location)};\n  if (!target.is_string()) [[unlikely]] {\n    return nullptr;\n  } else {\n    return &target.to_string();\n  }\n}\n\ninline auto effective_type_strict_real(const JSON &instance) noexcept\n    -> JSON::Type {\n  const auto real_type{instance.type()};\n  switch (real_type) {\n    case JSON::Type::Decimal:\n      return instance.to_decimal().is_integer() ? JSON::Type::Integer\n                                                : JSON::Type::Real;\n    default:\n      return real_type;\n  }\n}\n\ntemplate <typename T>\ninline auto assume_value(const Value &variant) noexcept -> const T & {\n  const auto *pointer{std::get_if<T>(&variant)};\n  SOURCEMETA_ASSUME(pointer != nullptr);\n  return *pointer;\n}\n\ntemplate <typename T>\ninline auto assume_value_copy(const Value &variant) noexcept -> T {\n  const auto *pointer{std::get_if<T>(&variant)};\n  SOURCEMETA_ASSUME(pointer != nullptr);\n  return *pointer;\n}\n\ntemplate <bool Track, bool Dynamic, bool HasCallback> struct DispatchContext {\n  const sourcemeta::blaze::Template *schema;\n  const sourcemeta::blaze::Callback *callback;\n  sourcemeta::blaze::Evaluator *evaluator;\n  const sourcemeta::core::JSON::String *property_target;\n};\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\ninline auto\nevaluate_instruction(const sourcemeta::blaze::Instruction &instruction,\n                     const sourcemeta::core::JSON &instance,\n                     const std::uint64_t depth,\n                     DispatchContext<Track, Dynamic, HasCallback> &context)\n    -> bool;\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\ninline auto evaluate_instruction_with_property(\n    const sourcemeta::blaze::Instruction &instruction,\n    const sourcemeta::core::JSON &instance, const std::uint64_t depth,\n    DispatchContext<Track, Dynamic, HasCallback> &context,\n    const sourcemeta::core::JSON::String &name) -> bool;\n\n#define INSTRUCTION_HANDLER(name)                                              \\\n  template <bool Track, bool Dynamic, bool HasCallback>                        \\\n  static inline auto name(                                                     \\\n      [[maybe_unused]] const sourcemeta::blaze::Instruction &instruction,      \\\n      [[maybe_unused]] const sourcemeta::core::JSON &instance,                 \\\n      [[maybe_unused]] const std::uint64_t depth,                              \\\n      [[maybe_unused]] DispatchContext<Track, Dynamic, HasCallback> &context)  \\\n      -> bool\n\n#define INSTRUCTION_DIRECT(name, value_type)                                   \\\n  SOURCEMETA_FORCEINLINE inline auto DIRECT_##name(                            \\\n      const sourcemeta::core::JSON &target, const value_type &value)           \\\n      ->bool\n\n#define INSTRUCTION_DIRECT_COPY(name, value_type)                              \\\n  SOURCEMETA_FORCEINLINE inline auto DIRECT_##name(                            \\\n      const sourcemeta::core::JSON &target, const value_type value)            \\\n      ->bool\n\n#define DIRECT(name, target, value) DIRECT_##name(target, value)\n\n// Forward declarations\nINSTRUCTION_DIRECT_COPY(LoopItemsIntegerBounded, ValueIntegerBounds);\n\nINSTRUCTION_HANDLER(AssertionFail) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionFail);\n  EVALUATE_END(AssertionFail);\n}\n\nINSTRUCTION_HANDLER(AssertionDefines) {\n  EVALUATE_BEGIN_NON_STRING(AssertionDefines, target.is_object());\n  const auto &value{assume_value<ValueProperty>(instruction.value)};\n  result = target.defines(value.first, value.second);\n  EVALUATE_END(AssertionDefines);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesStrict) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionDefinesStrict);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueProperty>(instruction.value)};\n  result = target.is_object() && target.defines(value.first, value.second);\n  EVALUATE_END(AssertionDefinesStrict);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesAll) {\n  EVALUATE_BEGIN_NON_STRING(AssertionDefinesAll, target.is_object());\n  const auto &value{assume_value<ValueStringSet>(instruction.value)};\n  // Otherwise we are we even emitting this instruction?\n  assert(value.size() > 1);\n\n  // Otherwise there is no way the instance can satisfy it anyway\n  if (value.size() <= target.object_size()) [[likely]] {\n    result = true;\n    const auto &object{target.as_object()};\n    for (const auto &property : value) {\n      if (!object.defines(property.first, property.second)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionDefinesAll);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesAllStrict) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionDefinesAllStrict);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueStringSet>(instruction.value)};\n  // Otherwise we are we even emitting this instruction?\n  assert(value.size() > 1);\n\n  // Otherwise there is no way the instance can satisfy it anyway\n  if (target.is_object() && value.size() <= target.object_size()) [[likely]] {\n    result = true;\n    const auto &object{target.as_object()};\n    for (const auto &property : value) {\n      if (!object.defines(property.first, property.second)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionDefinesAllStrict);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesExactly) {\n  EVALUATE_BEGIN_NON_STRING(AssertionDefinesExactly, target.is_object());\n  const auto &value{assume_value<ValueStringSet>(instruction.value)};\n  // Otherwise we are we even emitting this instruction?\n  assert(value.size() > 1);\n  const auto &object{target.as_object()};\n\n  if (value.size() == object.size()) [[likely]] {\n    result = true;\n    for (const auto &property : value) {\n      if (!object.defines(property.first, property.second)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionDefinesExactly);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesExactlyStrict) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionDefinesExactlyStrict);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  if (target.is_object()) [[likely]] {\n    const auto &value{assume_value<ValueStringSet>(instruction.value)};\n    // Otherwise we are we even emitting this instruction?\n    assert(value.size() > 1);\n    const auto &object{target.as_object()};\n\n    if (value.size() == object.size()) [[likely]] {\n      result = true;\n      for (const auto &property : value) {\n        if (!object.defines(property.first, property.second)) [[unlikely]] {\n          result = false;\n          break;\n        }\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionDefinesExactlyStrict);\n}\n\nINSTRUCTION_HANDLER(AssertionDefinesExactlyStrictHash3) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionDefinesExactlyStrictHash3);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  if (target.is_object()) [[likely]] {\n    // TODO: Take advantage of the table of contents structure to speed up\n    // checks\n    const auto &value{assume_value<ValueStringHashes>(instruction.value)};\n    assert(value.first.size() == 3);\n    const auto &object{target.as_object()};\n\n    result =\n        object.size() == 3 && ((value.first.at(0).first == object.at(0).hash &&\n                                value.first.at(1).first == object.at(1).hash &&\n                                value.first.at(2).first == object.at(2).hash) ||\n                               (value.first.at(0).first == object.at(0).hash &&\n                                value.first.at(1).first == object.at(2).hash &&\n                                value.first.at(2).first == object.at(1).hash) ||\n                               (value.first.at(0).first == object.at(1).hash &&\n                                value.first.at(1).first == object.at(0).hash &&\n                                value.first.at(2).first == object.at(2).hash) ||\n                               (value.first.at(0).first == object.at(1).hash &&\n                                value.first.at(1).first == object.at(2).hash &&\n                                value.first.at(2).first == object.at(0).hash) ||\n                               (value.first.at(0).first == object.at(2).hash &&\n                                value.first.at(1).first == object.at(0).hash &&\n                                value.first.at(2).first == object.at(1).hash) ||\n                               (value.first.at(0).first == object.at(2).hash &&\n                                value.first.at(1).first == object.at(1).hash &&\n                                value.first.at(2).first == object.at(0).hash));\n  }\n\n  EVALUATE_END(AssertionDefinesExactlyStrictHash3);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyDependencies) {\n  EVALUATE_BEGIN_NON_STRING(AssertionPropertyDependencies, target.is_object());\n  const auto &value{assume_value<ValueStringMap>(instruction.value)};\n  // Otherwise we are we even emitting this instruction?\n  assert(!value.empty());\n  result = true;\n  const auto &object{target.as_object()};\n  const sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n  for (const auto &entry : value) {\n    if (!object.defines(entry.first, entry.hash)) {\n      continue;\n    }\n\n    assert(!entry.second.empty());\n    for (const auto &dependency : entry.second) {\n      if (!object.defines(dependency, hasher(dependency))) [[unlikely]] {\n        result = false;\n        EVALUATE_END(AssertionPropertyDependencies);\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionPropertyDependencies);\n}\n\nINSTRUCTION_DIRECT_COPY(AssertionType, ValueType) {\n  // In non-strict mode, we consider a real number that represents an\n  // integer to be an integer\n  return target.type() == value ||\n         (value == JSON::Type::Integer && target.is_integral());\n}\n\nINSTRUCTION_HANDLER(AssertionType) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionType);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  // TODO: Maybe make this instruction about integers, as it is the\n  // only where where it is actually useful?\n  assert(value == JSON::Type::Integer);\n  SOURCEMETA_ASSUME(value == JSON::Type::Integer);\n  result = DIRECT(AssertionType, target, value);\n  EVALUATE_END(AssertionType);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeAny, ValueTypes) {\n  // In non-strict mode, we consider a real number that represents an\n  // integer to be an integer\n  return value.test(std::to_underlying(target.type())) ||\n         (value.test(std::to_underlying(JSON::Type::Integer)) &&\n          target.is_integral());\n}\n\nINSTRUCTION_HANDLER(AssertionTypeAny) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeAny);\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  result = DIRECT(AssertionTypeAny, target, value);\n  EVALUATE_END(AssertionTypeAny);\n}\n\nINSTRUCTION_DIRECT_COPY(AssertionTypeStrict, ValueType) {\n  return effective_type_strict_real(target) == value;\n}\n\nINSTRUCTION_HANDLER(AssertionTypeStrict) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeStrict);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  result = DIRECT(AssertionTypeStrict, target, value);\n  EVALUATE_END(AssertionTypeStrict);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeStrictAny, ValueTypes) {\n  return value.test(std::to_underlying(effective_type_strict_real(target)));\n}\n\nINSTRUCTION_HANDLER(AssertionTypeStrictAny) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeStrictAny);\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  result = DIRECT(AssertionTypeStrictAny, target, value);\n  EVALUATE_END(AssertionTypeStrictAny);\n}\n\nINSTRUCTION_DIRECT(AssertionNotTypeStrictAny, ValueTypes) {\n  return !value.test(std::to_underlying(effective_type_strict_real(target)));\n}\n\nINSTRUCTION_HANDLER(AssertionNotTypeStrictAny) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionNotTypeStrictAny);\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  result = DIRECT(AssertionNotTypeStrictAny, target, value);\n  EVALUATE_END(AssertionNotTypeStrictAny);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeStringBounded, ValueRange) {\n  const auto &[minimum, maximum, exhaustive] = value;\n  return target.type() == JSON::Type::String &&\n         target.string_size() >= minimum &&\n         (!maximum.has_value() || target.string_size() <= maximum.value());\n}\n\nINSTRUCTION_HANDLER(AssertionTypeStringBounded) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeStringBounded);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueRange>(instruction.value)};\n  assert(!std::get<1>(value).has_value() ||\n         std::get<1>(value).value() >= std::get<0>(value));\n  assert(!std::get<2>(value));\n  result = DIRECT(AssertionTypeStringBounded, target, value);\n  EVALUATE_END(AssertionTypeStringBounded);\n}\n\nINSTRUCTION_HANDLER(AssertionTypeStringUpper) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeStringUpper);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = target.is_string() && target.string_size() <= value;\n  EVALUATE_END(AssertionTypeStringUpper);\n}\n\nINSTRUCTION_HANDLER(AssertionTypeArrayBounded) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeArrayBounded);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueRange>(instruction.value)};\n  const auto &[minimum, maximum, exhaustive] = value;\n  assert(!maximum.has_value() || maximum.value() >= minimum);\n  // Require early breaking\n  assert(!exhaustive);\n  SOURCEMETA_ASSUME(!exhaustive);\n  result = target.type() == JSON::Type::Array &&\n           target.array_size() >= minimum &&\n           (!maximum.has_value() || target.array_size() <= maximum.value());\n  EVALUATE_END(AssertionTypeArrayBounded);\n}\n\nINSTRUCTION_HANDLER(AssertionTypeArrayUpper) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeArrayUpper);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = target.is_array() && target.array_size() <= value;\n  EVALUATE_END(AssertionTypeArrayUpper);\n}\n\nINSTRUCTION_HANDLER(AssertionTypeObjectBounded) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeObjectBounded);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueRange>(instruction.value)};\n  const auto &[minimum, maximum, exhaustive] = value;\n  assert(!maximum.has_value() || maximum.value() >= minimum);\n  // Require early breaking\n  assert(!exhaustive);\n  SOURCEMETA_ASSUME(!exhaustive);\n  result = target.type() == JSON::Type::Object &&\n           target.object_size() >= minimum &&\n           (!maximum.has_value() || target.object_size() <= maximum.value());\n  EVALUATE_END(AssertionTypeObjectBounded);\n}\n\nINSTRUCTION_HANDLER(AssertionTypeObjectUpper) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionTypeObjectUpper);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = target.is_object() && target.object_size() <= value;\n  EVALUATE_END(AssertionTypeObjectUpper);\n}\n\nINSTRUCTION_HANDLER(AssertionRegex) {\n  EVALUATE_BEGIN_IF_STRING(AssertionRegex);\n  const auto &value{assume_value<ValueRegex>(instruction.value)};\n  result = matches(value.first, target);\n  EVALUATE_END(AssertionRegex);\n}\n\nINSTRUCTION_HANDLER(AssertionStringSizeLess) {\n  EVALUATE_BEGIN_IF_STRING(AssertionStringSizeLess);\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (JSON::size(target) < value);\n  EVALUATE_END(AssertionStringSizeLess);\n}\n\nINSTRUCTION_HANDLER(AssertionStringSizeGreater) {\n  EVALUATE_BEGIN_IF_STRING(AssertionStringSizeGreater);\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (JSON::size(target) > value);\n  EVALUATE_END(AssertionStringSizeGreater);\n}\n\nINSTRUCTION_HANDLER(AssertionArraySizeLess) {\n  EVALUATE_BEGIN_NON_STRING(AssertionArraySizeLess, target.is_array());\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (target.array_size() < value);\n  EVALUATE_END(AssertionArraySizeLess);\n}\n\nINSTRUCTION_HANDLER(AssertionArraySizeGreater) {\n  EVALUATE_BEGIN_NON_STRING(AssertionArraySizeGreater, target.is_array());\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (target.array_size() > value);\n  EVALUATE_END(AssertionArraySizeGreater);\n}\n\nINSTRUCTION_HANDLER(AssertionObjectSizeLess) {\n  EVALUATE_BEGIN_NON_STRING(AssertionObjectSizeLess, target.is_object());\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (target.object_size() < value);\n  EVALUATE_END(AssertionObjectSizeLess);\n}\n\nINSTRUCTION_HANDLER(AssertionObjectSizeGreater) {\n  EVALUATE_BEGIN_NON_STRING(AssertionObjectSizeGreater, target.is_object());\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  result = (target.object_size() > value);\n  EVALUATE_END(AssertionObjectSizeGreater);\n}\n\nINSTRUCTION_DIRECT(AssertionEqual, ValueJSON) { return target == value; }\n\nINSTRUCTION_HANDLER(AssertionEqual) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionEqual);\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n\n  if (context.property_target) [[unlikely]] {\n    result = value.is_string() && value.to_string() == *context.property_target;\n  } else {\n    const auto &target{\n        resolve_instance(instance, instruction.relative_instance_location)};\n    result = DIRECT(AssertionEqual, target, value);\n  }\n\n  EVALUATE_END(AssertionEqual);\n}\n\nINSTRUCTION_DIRECT(AssertionEqualsAny, ValueSet) {\n  return value.contains(target);\n}\n\nINSTRUCTION_HANDLER(AssertionEqualsAny) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionEqualsAny);\n  const auto &value{assume_value<ValueSet>(instruction.value)};\n\n  if (context.property_target) [[unlikely]] {\n    // TODO: This involves a string copy\n    result = value.contains(JSON{*context.property_target});\n  } else {\n    const auto &target{\n        resolve_instance(instance, instruction.relative_instance_location)};\n    result = DIRECT(AssertionEqualsAny, target, value);\n  }\n\n  EVALUATE_END(AssertionEqualsAny);\n}\n\nINSTRUCTION_DIRECT(AssertionEqualsAnyStringHash, ValueStringHashes) {\n  if (!target.is_string()) [[unlikely]] {\n    return false;\n  }\n  const auto &target_string{target.to_string()};\n  const auto string_size{target_string.size()};\n  const sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n  const auto value_hash{hasher(target_string)};\n  if (string_size < value.second.size()) [[likely]] {\n    const auto &hint{value.second[string_size]};\n    if (hint.second != 0) [[likely]] {\n      for (std::size_t index = hint.first - 1; index < hint.second; index++) {\n        if (value.first[index].first == value_hash) {\n          return true;\n        }\n      }\n    }\n  }\n  return false;\n}\n\nINSTRUCTION_HANDLER(AssertionEqualsAnyStringHash) {\n  EVALUATE_BEGIN_NO_PRECONDITION(AssertionEqualsAnyStringHash);\n  const auto &value{assume_value<ValueStringHashes>(instruction.value)};\n\n  if (context.property_target) [[unlikely]] {\n    const sourcemeta::core::PropertyHashJSON<ValueString> hasher;\n    const auto value_hash{hasher(*context.property_target)};\n    const auto string_size{context.property_target->size()};\n    if (string_size < value.second.size()) [[likely]] {\n      const auto &hint{value.second[string_size]};\n      assert(hint.first <= hint.second);\n      SOURCEMETA_ASSUME(hint.first <= hint.second);\n      if (hint.second != 0) [[likely]] {\n        for (std::size_t index = hint.first - 1; index < hint.second; index++) {\n          assert(hasher.is_perfect(value.first[index].first));\n          if (value.first[index].first == value_hash) {\n            result = true;\n            break;\n          }\n        }\n      }\n    }\n  } else {\n    const auto &target{\n        resolve_instance(instance, instruction.relative_instance_location)};\n    result = DIRECT(AssertionEqualsAnyStringHash, target, value);\n  }\n\n  EVALUATE_END(AssertionEqualsAnyStringHash);\n}\n\nINSTRUCTION_HANDLER(AssertionGreaterEqual) {\n  EVALUATE_BEGIN_NON_STRING(AssertionGreaterEqual, target.is_number());\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  result = target >= value;\n  EVALUATE_END(AssertionGreaterEqual);\n}\n\nINSTRUCTION_HANDLER(AssertionLessEqual) {\n  EVALUATE_BEGIN_NON_STRING(AssertionLessEqual, target.is_number());\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  result = target <= value;\n  EVALUATE_END(AssertionLessEqual);\n}\n\nINSTRUCTION_HANDLER(AssertionGreater) {\n  EVALUATE_BEGIN_NON_STRING(AssertionGreater, target.is_number());\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  result = target > value;\n  EVALUATE_END(AssertionGreater);\n}\n\nINSTRUCTION_HANDLER(AssertionLess) {\n  EVALUATE_BEGIN_NON_STRING(AssertionLess, target.is_number());\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  result = target < value;\n  EVALUATE_END(AssertionLess);\n}\n\nINSTRUCTION_HANDLER(AssertionUnique) {\n  EVALUATE_BEGIN_NON_STRING(AssertionUnique, target.is_array());\n  result = target.unique();\n  EVALUATE_END(AssertionUnique);\n}\n\nINSTRUCTION_HANDLER(AssertionDivisible) {\n  EVALUATE_BEGIN_NON_STRING(AssertionDivisible, target.is_number());\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  assert(value.is_number());\n  result = target.divisible_by(value);\n  EVALUATE_END(AssertionDivisible);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeIntegerBounded, ValueIntegerBounds) {\n  if (target.is_integer()) {\n    const auto integer{target.to_integer()};\n    return integer >= value.first && integer <= value.second;\n  }\n  if (target.is_integral()) {\n    const auto integer{target.as_integer()};\n    return integer >= value.first && integer <= value.second;\n  }\n  return false;\n}\n\nINSTRUCTION_HANDLER(AssertionTypeIntegerBounded) {\n  EVALUATE_BEGIN_NON_STRING(AssertionTypeIntegerBounded, true);\n  result = DIRECT(AssertionTypeIntegerBounded, target,\n                  assume_value_copy<ValueIntegerBounds>(instruction.value));\n  EVALUATE_END(AssertionTypeIntegerBounded);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeIntegerBoundedStrict, ValueIntegerBounds) {\n  if (target.is_integer()) {\n    const auto integer{target.to_integer()};\n    return integer >= value.first && integer <= value.second;\n  }\n  return false;\n}\n\nINSTRUCTION_HANDLER(AssertionTypeIntegerBoundedStrict) {\n  EVALUATE_BEGIN_NON_STRING(AssertionTypeIntegerBoundedStrict, true);\n  result = DIRECT(AssertionTypeIntegerBoundedStrict, target,\n                  assume_value_copy<ValueIntegerBounds>(instruction.value));\n  EVALUATE_END(AssertionTypeIntegerBoundedStrict);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeIntegerLowerBound, ValueIntegerBounds) {\n  if (target.is_integer()) {\n    return target.to_integer() >= value.first;\n  }\n  if (target.is_integral()) {\n    return target.as_integer() >= value.first;\n  }\n  return false;\n}\n\nINSTRUCTION_HANDLER(AssertionTypeIntegerLowerBound) {\n  EVALUATE_BEGIN_NON_STRING(AssertionTypeIntegerLowerBound, true);\n  result = DIRECT(AssertionTypeIntegerLowerBound, target,\n                  assume_value_copy<ValueIntegerBounds>(instruction.value));\n  EVALUATE_END(AssertionTypeIntegerLowerBound);\n}\n\nINSTRUCTION_DIRECT(AssertionTypeIntegerLowerBoundStrict, ValueIntegerBounds) {\n  if (target.is_integer()) {\n    return target.to_integer() >= value.first;\n  }\n  return false;\n}\n\nINSTRUCTION_HANDLER(AssertionTypeIntegerLowerBoundStrict) {\n  EVALUATE_BEGIN_NON_STRING(AssertionTypeIntegerLowerBoundStrict, true);\n  result = DIRECT(AssertionTypeIntegerLowerBoundStrict, target,\n                  assume_value_copy<ValueIntegerBounds>(instruction.value));\n  EVALUATE_END(AssertionTypeIntegerLowerBoundStrict);\n}\n\nINSTRUCTION_HANDLER(AssertionStringType) {\n  EVALUATE_BEGIN_IF_STRING(AssertionStringType);\n  const auto value{assume_value_copy<ValueStringType>(instruction.value)};\n  switch (value) {\n    case ValueStringType::URI:\n      result = URI::is_uri(target);\n      break;\n    default:\n      std::unreachable();\n  }\n\n  EVALUATE_END(AssertionStringType);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyType) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyType);\n  // Now here we refer to the actual property\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  // In non-strict mode, we consider a real number that represents an\n  // integer to be an integer\n  result = target_check->type() == value ||\n           (value == JSON::Type::Integer && target_check->is_integral());\n  EVALUATE_END(AssertionPropertyType);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyTypeEvaluate) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyTypeEvaluate);\n  // Now here we refer to the actual property\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  // In non-strict mode, we consider a real number that represents an\n  // integer to be an integer\n  result = target_check->type() == value ||\n           (value == JSON::Type::Integer && target_check->is_integral());\n\n  if (result) {\n    context.evaluator->evaluate(target_check);\n  }\n\n  EVALUATE_END(AssertionPropertyTypeEvaluate);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyTypeStrict) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyTypeStrict);\n  // Now here we refer to the actual property\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  result = target_check->type() == value ||\n           (value == JSON::Type::Integer && target_check->is_decimal() &&\n            target_check->to_decimal().is_integer());\n  EVALUATE_END(AssertionPropertyTypeStrict);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyTypeStrictEvaluate) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyTypeStrictEvaluate);\n  // Now here we refer to the actual property\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  result = target_check->type() == value;\n\n  if (result) {\n    context.evaluator->evaluate(target_check);\n  }\n\n  EVALUATE_END(AssertionPropertyTypeStrictEvaluate);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyTypeStrictAny) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyTypeStrictAny);\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  // Now here we refer to the actual property\n  const auto type_index{std::to_underlying(target_check->type())};\n  result =\n      value.test(type_index) ||\n      (value.test(std::to_underlying(JSON::Type::Integer)) &&\n       target_check->is_decimal() && target_check->to_decimal().is_integer());\n  EVALUATE_END(AssertionPropertyTypeStrictAny);\n}\n\nINSTRUCTION_HANDLER(AssertionPropertyTypeStrictAnyEvaluate) {\n  EVALUATE_BEGIN_TRY_TARGET(AssertionPropertyTypeStrictAnyEvaluate);\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  // Now here we refer to the actual property\n  const auto type_index{std::to_underlying(target_check->type())};\n  result = value.test(type_index);\n\n  if (result) {\n    context.evaluator->evaluate(target_check);\n  }\n\n  EVALUATE_END(AssertionPropertyTypeStrictAnyEvaluate);\n}\n\nINSTRUCTION_HANDLER(AssertionObjectPropertiesSimple) {\n  EVALUATE_BEGIN_NON_STRING(AssertionObjectPropertiesSimple, true);\n  if (!target.is_object()) {\n    EVALUATE_END(AssertionObjectPropertiesSimple);\n  }\n\n  const auto &value{assume_value<ValueObjectProperties>(instruction.value)};\n  assert(value.size() >= instruction.children.size());\n  assert(value.size() <= 32);\n  static constexpr sourcemeta::core::PropertyHashJSON<ValueString>\n      property_hasher;\n  const auto &object{target.as_object()};\n  const auto schema_size{value.size()};\n  std::uint32_t seen{0};\n  result = true;\n\n  for (const auto &instance_entry : object) {\n    const auto &instance_hash{instance_entry.hash};\n    for (std::size_t schema_index = 0; schema_index < schema_size;\n         schema_index++) {\n      const auto &schema_hash{std::get<1>(value[schema_index])};\n      if (schema_hash == instance_hash &&\n          (property_hasher.is_perfect(instance_hash) ||\n           instance_entry.first == std::get<0>(value[schema_index]))) {\n        seen |= (static_cast<std::uint32_t>(1) << schema_index);\n        if (schema_index < instruction.children.size()) {\n          const auto &child{instruction.children[schema_index]};\n          const auto &property_value{instance_entry.second};\n          bool child_ok{false};\n\n// NOLINTBEGIN(bugprone-macro-parentheses)\n#define CHILD_DIRECT(name, accessor, value_type)                               \\\n  case name:                                                                   \\\n    child_ok =                                                                 \\\n        DIRECT(name, property_value, accessor<value_type>(child.value));       \\\n    break\n\n          switch (child.type) {\n            using enum InstructionIndex;\n            CHILD_DIRECT(AssertionTypeStrict, assume_value_copy, ValueType);\n            CHILD_DIRECT(AssertionType, assume_value_copy, ValueType);\n            CHILD_DIRECT(AssertionTypeStrictAny, assume_value, ValueTypes);\n            CHILD_DIRECT(AssertionTypeAny, assume_value, ValueTypes);\n            CHILD_DIRECT(AssertionTypeStringBounded, assume_value, ValueRange);\n            CHILD_DIRECT(AssertionEqual, assume_value, ValueJSON);\n            CHILD_DIRECT(AssertionEqualsAny, assume_value, ValueSet);\n            CHILD_DIRECT(AssertionEqualsAnyStringHash, assume_value,\n                         ValueStringHashes);\n            CHILD_DIRECT(AssertionTypeIntegerBounded, assume_value_copy,\n                         ValueIntegerBounds);\n            CHILD_DIRECT(AssertionTypeIntegerBoundedStrict, assume_value_copy,\n                         ValueIntegerBounds);\n            CHILD_DIRECT(AssertionTypeIntegerLowerBound, assume_value_copy,\n                         ValueIntegerBounds);\n            CHILD_DIRECT(AssertionTypeIntegerLowerBoundStrict,\n                         assume_value_copy, ValueIntegerBounds);\n            CHILD_DIRECT(LoopItemsIntegerBounded, assume_value_copy,\n                         ValueIntegerBounds);\n            default:\n              child_ok = evaluate_instruction_without_callback(\n                  child, property_value, depth + 1, context);\n              break;\n          }\n\n// NOLINTEND(bugprone-macro-parentheses)\n#undef CHILD_DIRECT\n\n          if (!child_ok) [[unlikely]] {\n            result = false;\n            EVALUATE_END(AssertionObjectPropertiesSimple);\n          }\n        }\n\n        break;\n      }\n    }\n  }\n\n  // Check required properties that were not seen\n  const auto all_seen{schema_size == 32\n                          ? ~std::uint32_t{0}\n                          : (std::uint32_t{1} << schema_size) - 1};\n  if (seen != all_seen) [[unlikely]] {\n    for (std::size_t schema_index = 0; schema_index < schema_size;\n         schema_index++) {\n      if (std::get<2>(value[schema_index]) &&\n          !(seen & (static_cast<std::uint32_t>(1) << schema_index))) {\n        result = false;\n        EVALUATE_END(AssertionObjectPropertiesSimple);\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionObjectPropertiesSimple);\n}\n\nINSTRUCTION_HANDLER(AssertionArrayPrefix) {\n  EVALUATE_BEGIN_NON_STRING(AssertionArrayPrefix, target.is_array());\n  // Otherwise there is no point in emitting this instruction\n  assert(!instruction.children.empty());\n  result = target.empty();\n  const auto prefixes{instruction.children.size() - 1};\n  const auto array_size{target.array_size()};\n  if (!result) [[likely]] {\n    const auto pointer{\n        array_size == prefixes ? prefixes : std::min(array_size, prefixes) - 1};\n    const auto &entry{instruction.children[pointer]};\n    result = true;\n    assert(entry.type == sourcemeta::blaze::InstructionIndex::ControlGroup);\n    SOURCEMETA_ASSUME(entry.type ==\n                      sourcemeta::blaze::InstructionIndex::ControlGroup);\n    for (const auto &child : entry.children) {\n      if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionArrayPrefix);\n}\n\nINSTRUCTION_HANDLER(AssertionArrayPrefixEvaluate) {\n  EVALUATE_BEGIN_NON_STRING(AssertionArrayPrefixEvaluate, target.is_array());\n  // Otherwise there is no point in emitting this instruction\n  assert(!instruction.children.empty());\n  result = target.empty();\n  const auto prefixes{instruction.children.size() - 1};\n  const auto array_size{target.array_size()};\n  if (!result) [[likely]] {\n    const auto pointer{\n        array_size == prefixes ? prefixes : std::min(array_size, prefixes) - 1};\n    const auto &entry{instruction.children[pointer]};\n    result = true;\n    assert(entry.type == sourcemeta::blaze::InstructionIndex::ControlGroup);\n    SOURCEMETA_ASSUME(entry.type ==\n                      sourcemeta::blaze::InstructionIndex::ControlGroup);\n    for (const auto &child : entry.children) {\n      if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n        result = false;\n        EVALUATE_END(AssertionArrayPrefixEvaluate);\n      }\n    }\n\n    assert(result);\n    SOURCEMETA_ASSUME(result);\n    if (array_size == prefixes) {\n      context.evaluator->evaluate(&target);\n    } else {\n      for (std::size_t cursor = 0; cursor <= pointer; cursor++) {\n        context.evaluator->evaluate(&target.at(cursor));\n      }\n    }\n  }\n\n  EVALUATE_END(AssertionArrayPrefixEvaluate);\n}\n\nINSTRUCTION_HANDLER(LogicalOr) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalOr);\n  result = instruction.children.empty();\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueBoolean>(instruction.value)};\n\n  // This boolean value controls whether we should be exhaustive\n  if (value) {\n    for (const auto &child : instruction.children) {\n      if (EVALUATE_RECURSE(child, target)) {\n        result = true;\n      }\n    }\n  } else {\n    for (const auto &child : instruction.children) {\n      if (EVALUATE_RECURSE(child, target)) {\n        result = true;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(LogicalOr);\n}\n\nINSTRUCTION_HANDLER(LogicalAnd) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalAnd);\n  result = true;\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LogicalAnd);\n}\n\nINSTRUCTION_HANDLER(LogicalWhenType) {\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n\n  // Not having to worry about numbers in this instruction\n  // makes things a lot simpler\n  assert(value != JSON::Type::Integer);\n  SOURCEMETA_ASSUME(value != JSON::Type::Integer);\n  assert(value != JSON::Type::Real);\n  SOURCEMETA_ASSUME(value != JSON::Type::Real);\n  assert(value != JSON::Type::Decimal);\n  SOURCEMETA_ASSUME(value != JSON::Type::Decimal);\n\n  EVALUATE_BEGIN(LogicalWhenType, target.type() == value);\n  result = true;\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LogicalWhenType);\n}\n\nINSTRUCTION_HANDLER(LogicalWhenDefines) {\n  const auto &value{assume_value<ValueProperty>(instruction.value)};\n  EVALUATE_BEGIN_NON_STRING(LogicalWhenDefines,\n                            target.is_object() &&\n                                target.defines(value.first, value.second));\n  result = true;\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LogicalWhenDefines);\n}\n\nINSTRUCTION_HANDLER(LogicalWhenArraySizeGreater) {\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  EVALUATE_BEGIN_NON_STRING(LogicalWhenArraySizeGreater,\n                            target.is_array() && target.array_size() > value);\n  result = true;\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LogicalWhenArraySizeGreater);\n}\n\nINSTRUCTION_HANDLER(LogicalXor) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalXor);\n  result = true;\n  bool has_matched{false};\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto value{assume_value_copy<ValueBoolean>(instruction.value)};\n  for (const auto &child : instruction.children) {\n    if (EVALUATE_RECURSE(child, target)) {\n      if (has_matched) [[unlikely]] {\n        result = false;\n        // This boolean value controls whether we should be exhaustive\n        if (!value) {\n          break;\n        }\n      } else {\n        has_matched = true;\n      }\n    }\n  }\n\n  result = result && has_matched;\n  EVALUATE_END(LogicalXor);\n}\n\nINSTRUCTION_HANDLER(LogicalCondition) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalCondition);\n  result = true;\n  const auto value{assume_value_copy<ValueIndexPair>(instruction.value)};\n  const auto children_size{instruction.children.size()};\n  assert(children_size >= value.first);\n  SOURCEMETA_ASSUME(children_size >= value.first);\n  assert(children_size >= value.second);\n  SOURCEMETA_ASSUME(children_size >= value.second);\n\n  auto condition_end{children_size};\n  if (value.first > 0) {\n    condition_end = value.first;\n  } else if (value.second > 0) {\n    condition_end = value.second;\n  }\n\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  for (std::size_t cursor = 0; cursor < condition_end; cursor++) {\n    if (!EVALUATE_RECURSE(instruction.children[cursor], target)) {\n      result = false;\n      break;\n    }\n  }\n\n  const auto consequence_start{result ? value.first : value.second};\n  const auto consequence_end{(result && value.second > 0) ? value.second\n                                                          : children_size};\n  result = true;\n  if (consequence_start > 0) {\n    if constexpr (Track || HasCallback) {\n      if (track) {\n        context.evaluator->evaluate_path.pop_back(\n            context.schema->extra[instruction.extra_index]\n                .relative_schema_location.size());\n      }\n    }\n\n    for (auto cursor = consequence_start; cursor < consequence_end; cursor++) {\n      if (!EVALUATE_RECURSE(instruction.children[cursor], target)) {\n        result = false;\n        break;\n      }\n    }\n\n    if constexpr (Track || HasCallback) {\n      if (track) {\n        context.evaluator->evaluate_path.push_back(\n            context.schema->extra[instruction.extra_index]\n                .relative_schema_location);\n      }\n    }\n  }\n\n  EVALUATE_END(LogicalCondition);\n}\n\nINSTRUCTION_HANDLER(ControlGroup) {\n  EVALUATE_BEGIN_PASS_THROUGH(ControlGroup);\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, instance)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END_PASS_THROUGH(ControlGroup);\n}\n\nINSTRUCTION_HANDLER(ControlGroupWhenDefines) {\n  EVALUATE_BEGIN_PASS_THROUGH(ControlGroupWhenDefines);\n  assert(!instruction.children.empty());\n  // Otherwise why are we emitting this property?\n  assert(!instruction.relative_instance_location.empty());\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueProperty>(instruction.value)};\n  if (target.is_object() && target.defines(value.first, value.second)) {\n    for (const auto &child : instruction.children) {\n      // Note that in this control instruction, we purposely\n      // don't navigate into the target\n      if (!EVALUATE_RECURSE(child, instance)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END_PASS_THROUGH(ControlGroupWhenDefines);\n}\n\nINSTRUCTION_HANDLER(ControlGroupWhenDefinesDirect) {\n  EVALUATE_BEGIN_PASS_THROUGH(ControlGroupWhenDefinesDirect);\n  assert(!instruction.children.empty());\n  assert(instruction.relative_instance_location.empty());\n  const auto &value{assume_value<ValueProperty>(instruction.value)};\n\n  if (instance.is_object() && instance.defines(value.first, value.second)) {\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, instance)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END_PASS_THROUGH(ControlGroupWhenDefinesDirect);\n}\n\nINSTRUCTION_HANDLER(ControlGroupWhenType) {\n  EVALUATE_BEGIN_PASS_THROUGH(ControlGroupWhenType);\n  assert(!instruction.children.empty());\n  assert(instruction.relative_instance_location.empty());\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n\n  // Not having to worry about numbers in this instruction\n  // makes things a lot simpler\n  assert(value != JSON::Type::Integer);\n  SOURCEMETA_ASSUME(value != JSON::Type::Integer);\n  assert(value != JSON::Type::Real);\n  SOURCEMETA_ASSUME(value != JSON::Type::Real);\n  assert(value != JSON::Type::Decimal);\n  SOURCEMETA_ASSUME(value != JSON::Type::Decimal);\n\n  if (instance.type() == value) [[likely]] {\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, instance)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END_PASS_THROUGH(ControlGroupWhenType);\n}\n\nINSTRUCTION_HANDLER(ControlEvaluate) {\n  EVALUATE_BEGIN_PASS_THROUGH(ControlEvaluate);\n  const auto &value{assume_value<ValuePointer>(instruction.value)};\n  context.evaluator->evaluate(&get(instance, value));\n  EVALUATE_END_PASS_THROUGH(ControlEvaluate);\n}\n\nINSTRUCTION_HANDLER(ControlDynamicAnchorJump) {\n  EVALUATE_BEGIN_NO_PRECONDITION(ControlDynamicAnchorJump);\n  result = false;\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueString>(instruction.value)};\n  for (const auto &resource : context.evaluator->resources) {\n    const auto label{Evaluator::hash(resource, value)};\n    const auto match{std::ranges::find_if(\n        context.schema->labels,\n        [&label](const auto &entry) { return entry.first == label; })};\n    if (match != context.schema->labels.cend()) [[likely]] {\n      result = true;\n      assert(match->second < context.schema->targets.size());\n      for (const auto &child : context.schema->targets[match->second]) {\n        if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n          result = false;\n          EVALUATE_END(ControlDynamicAnchorJump);\n        }\n      }\n\n      break;\n    }\n  }\n\n  EVALUATE_END(ControlDynamicAnchorJump);\n}\n\nINSTRUCTION_HANDLER(ControlJump) {\n  EVALUATE_BEGIN_NO_PRECONDITION(ControlJump);\n  result = true;\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  assert(context.schema->targets.size() > value);\n  const auto &target{resolve_target(\n      context.property_target,\n      resolve_instance(instance, instruction.relative_instance_location))};\n  for (const auto &child : context.schema->targets[value]) {\n    if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(ControlJump);\n}\n\nINSTRUCTION_HANDLER(AnnotationEmit) {\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  EVALUATE_ANNOTATION(AnnotationEmit, context.evaluator->instance_location,\n                      value);\n}\n\nINSTRUCTION_HANDLER(AnnotationToParent) {\n  const auto &value{assume_value<ValueJSON>(instruction.value)};\n  EVALUATE_ANNOTATION(\n      AnnotationToParent,\n      // TODO: Can we avoid a copy of the instance location here?\n      context.evaluator->instance_location.initial(), value);\n}\n\nINSTRUCTION_HANDLER(AnnotationBasenameToParent) {\n  EVALUATE_ANNOTATION(\n      AnnotationBasenameToParent,\n      // TODO: Can we avoid a copy of the instance location here?\n      context.evaluator->instance_location.initial(),\n      context.evaluator->instance_location.back().to_json());\n}\n\nINSTRUCTION_HANDLER(Evaluate) {\n  EVALUATE_BEGIN_NO_PRECONDITION(Evaluate);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  context.evaluator->evaluate(&target);\n  result = true;\n  EVALUATE_END(Evaluate);\n}\n\nINSTRUCTION_HANDLER(LogicalNot) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalNot);\n\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[likely]] {\n      result = true;\n      break;\n    }\n  }\n\n  EVALUATE_END(LogicalNot);\n}\n\nINSTRUCTION_HANDLER(LogicalNotEvaluate) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LogicalNotEvaluate);\n\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  for (const auto &child : instruction.children) {\n    if (!EVALUATE_RECURSE(child, target)) [[likely]] {\n      result = true;\n      break;\n    }\n  }\n\n  context.evaluator->unevaluate();\n\n  EVALUATE_END(LogicalNotEvaluate);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesUnevaluated) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesUnevaluated, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n\n  if (!context.evaluator->is_evaluated(&target)) {\n    for (const auto &entry : target.as_object()) {\n      if (context.evaluator->is_evaluated(&entry.second)) {\n        continue;\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n      for (const auto &child : instruction.children) {\n        if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n          result = false;\n          if constexpr (HasCallback) {\n            context.evaluator->instance_location.pop_back();\n          }\n          EVALUATE_END(LoopPropertiesUnevaluated);\n        }\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n\n    context.evaluator->evaluate(&target);\n  }\n\n  EVALUATE_END(LoopPropertiesUnevaluated);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesUnevaluatedExcept) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesUnevaluatedExcept,\n                            target.is_object());\n  assert(!instruction.children.empty());\n  const auto &value{assume_value<ValuePropertyFilter>(instruction.value)};\n  const auto &[filter_strings, filter_prefixes, filter_regexes] = value;\n  result = true;\n  // Otherwise why emit this instruction?\n  assert(!filter_strings.empty() || !filter_prefixes.empty() ||\n         !filter_regexes.empty());\n\n  if (!context.evaluator->is_evaluated(&target)) {\n    for (const auto &entry : target.as_object()) {\n      if (filter_strings.contains(entry.first, entry.hash)) {\n        continue;\n      }\n\n      if (std::ranges::any_of(filter_prefixes, [&entry](const auto &prefix) {\n            return entry.first.starts_with(prefix);\n          })) {\n        continue;\n      }\n\n      if (std::ranges::any_of(filter_regexes, [&entry](const auto &pattern) {\n            return matches(pattern.first, entry.first);\n          })) {\n        continue;\n      }\n\n      if (context.evaluator->is_evaluated(&entry.second)) {\n        continue;\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n      for (const auto &child : instruction.children) {\n        if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n          result = false;\n          if constexpr (HasCallback) {\n            context.evaluator->instance_location.pop_back();\n          }\n          EVALUATE_END(LoopPropertiesUnevaluatedExcept);\n        }\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n\n    context.evaluator->evaluate(&target);\n  }\n\n  EVALUATE_END(LoopPropertiesUnevaluatedExcept);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesMatch) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesMatch, target.is_object());\n  const auto &value{assume_value<ValueNamedIndexes>(instruction.value)};\n  assert(!value.empty());\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    const auto *index{value.try_at(entry.first, entry.hash)};\n    if (!index) {\n      continue;\n    }\n\n    const auto &subinstruction{instruction.children[*index]};\n    assert(subinstruction.type ==\n           sourcemeta::blaze::InstructionIndex::ControlGroup);\n    for (const auto &child : subinstruction.children) {\n      if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n        result = false;\n        EVALUATE_END(LoopPropertiesMatch);\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesMatch);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesMatchClosed) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesMatchClosed, target.is_object());\n  const auto &value{assume_value<ValueNamedIndexes>(instruction.value)};\n  assert(!value.empty());\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    const auto *index{value.try_at(entry.first, entry.hash)};\n    if (!index) [[unlikely]] {\n      result = false;\n      break;\n    }\n\n    const auto &subinstruction{instruction.children[*index]};\n    assert(subinstruction.type ==\n           sourcemeta::blaze::InstructionIndex::ControlGroup);\n    for (const auto &child : subinstruction.children) {\n      if (!EVALUATE_RECURSE(child, target)) [[unlikely]] {\n        result = false;\n        EVALUATE_END(LoopPropertiesMatchClosed);\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesMatchClosed);\n}\n\nINSTRUCTION_HANDLER(LoopProperties) {\n  EVALUATE_BEGIN_NON_STRING(LoopProperties, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopProperties);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopProperties);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesEvaluate) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesEvaluate, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopPropertiesEvaluate);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  context.evaluator->evaluate(&target);\n  EVALUATE_END(LoopPropertiesEvaluate);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesRegex) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesRegex, target.is_object());\n  assert(!instruction.children.empty());\n  const auto &value{assume_value<ValueRegex>(instruction.value)};\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    if (!matches(value.first, entry.first)) {\n      continue;\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopPropertiesRegex);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesRegex);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesRegexClosed) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesRegexClosed, target.is_object());\n  result = true;\n  const auto &value{assume_value<ValueRegex>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (!matches(value.first, entry.first)) [[unlikely]] {\n      result = false;\n      break;\n    }\n\n    if (instruction.children.empty()) {\n      continue;\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopPropertiesRegexClosed);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesRegexClosed);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesStartsWith) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesStartsWith, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n  const auto &value{assume_value<ValueString>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (!entry.first.starts_with(value)) {\n      continue;\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopPropertiesStartsWith);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesStartsWith);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesExcept) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesExcept, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n  const auto &value{assume_value<ValuePropertyFilter>(instruction.value)};\n  const auto &[filter_strings, filter_prefixes, filter_regexes] = value;\n  // Otherwise why emit this instruction?\n  assert(!filter_strings.empty() || !filter_prefixes.empty() ||\n         !filter_regexes.empty());\n\n  for (const auto &entry : target.as_object()) {\n    if (filter_strings.contains(entry.first, entry.hash)) {\n      continue;\n    }\n\n    if (std::ranges::any_of(filter_prefixes, [&entry](const auto &prefix) {\n          return entry.first.starts_with(prefix);\n        })) {\n      continue;\n    }\n\n    if (std::ranges::any_of(filter_regexes, [&entry](const auto &pattern) {\n          return matches(pattern.first, entry.first);\n        })) {\n      continue;\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, entry.second)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopPropertiesExcept);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesExcept);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesType) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesType, target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (entry.second.type() != value &&\n        // In non-strict mode, we consider a real number that represents an\n        // integer to be an integer\n        (value != JSON::Type::Integer || !entry.second.is_integral()))\n        [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesType);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesTypeEvaluate) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesTypeEvaluate, target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (entry.second.type() != value &&\n        // In non-strict mode, we consider a real number that represents an\n        // integer to be an integer\n        (value != JSON::Type::Integer || !entry.second.is_integral()))\n        [[unlikely]] {\n      result = false;\n      EVALUATE_END(LoopPropertiesTypeEvaluate);\n    }\n  }\n\n  context.evaluator->evaluate(&target);\n  EVALUATE_END(LoopPropertiesTypeEvaluate);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesExactlyTypeStrict) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LoopPropertiesExactlyTypeStrict);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  const auto &value{assume_value<ValueTypedProperties>(instruction.value)};\n  if (!target.is_object()) [[unlikely]] {\n    EVALUATE_END(LoopPropertiesExactlyTypeStrict);\n  }\n\n  const auto &object{target.as_object()};\n  if (object.size() == value.second.size()) [[likely]] {\n    // Otherwise why emit this instruction?\n    assert(!value.second.empty());\n    result = true;\n    for (const auto &entry : object) {\n      if (effective_type_strict_real(entry.second) != value.first)\n          [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesExactlyTypeStrict);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesExactlyTypeStrictHash) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LoopPropertiesExactlyTypeStrictHash);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  // TODO: Take advantage of the table of contents structure to speed up checks\n  const auto &value{assume_value<ValueTypedHashes>(instruction.value)};\n\n  if (!target.is_object()) [[unlikely]] {\n    EVALUATE_END(LoopPropertiesExactlyTypeStrictHash);\n  }\n\n  const auto &object{target.as_object()};\n  const auto size{object.size()};\n  if (size == value.second.first.size()) [[likely]] {\n    // Otherwise why emit this instruction?\n    assert(!value.second.first.empty());\n\n    // The idea is to first assume the object property ordering and the\n    // hashes collection aligns. If they don't we do a full comparison\n    // from where we left of.\n\n    std::size_t index{0};\n    for (const auto &entry : object) {\n      if (effective_type_strict_real(entry.second) != value.first) {\n        EVALUATE_END(LoopPropertiesExactlyTypeStrictHash);\n      }\n\n      if (entry.hash != value.second.first[index].first) {\n        break;\n      }\n\n      index += 1;\n    }\n\n    result = true;\n    if (index < size) {\n      auto iterator = object.cbegin();\n      // Continue where we left\n      std::advance(iterator, index);\n      for (; iterator != object.cend(); ++iterator) {\n        // NOLINTNEXTLINE(modernize-use-ranges)\n        if (std::ranges::none_of(value.second.first,\n                                 [&iterator](const auto &entry) {\n                                   return entry.first == iterator->hash;\n                                 })) {\n          result = false;\n          break;\n        }\n      }\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesExactlyTypeStrictHash);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesTypeStrict) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesTypeStrict, target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (effective_type_strict_real(entry.second) != value) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesTypeStrict);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesTypeStrictEvaluate) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesTypeStrictEvaluate,\n                            target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_object()) {\n    if (effective_type_strict_real(entry.second) != value) [[unlikely]] {\n      result = false;\n      EVALUATE_END(LoopPropertiesTypeStrictEvaluate);\n    }\n  }\n\n  context.evaluator->evaluate(&target);\n  EVALUATE_END(LoopPropertiesTypeStrictEvaluate);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesTypeStrictAny) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesTypeStrictAny, target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  for (const auto &entry : target.as_object()) {\n    const auto type_index{\n        std::to_underlying(effective_type_strict_real(entry.second))};\n    if (!value.test(type_index)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopPropertiesTypeStrictAny);\n}\n\nINSTRUCTION_HANDLER(LoopPropertiesTypeStrictAnyEvaluate) {\n  EVALUATE_BEGIN_NON_STRING(LoopPropertiesTypeStrictAnyEvaluate,\n                            target.is_object());\n  result = true;\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n  for (const auto &entry : target.as_object()) {\n    const auto type_index{\n        std::to_underlying(effective_type_strict_real(entry.second))};\n    if (!value.test(type_index)) [[unlikely]] {\n      result = false;\n      EVALUATE_END(LoopPropertiesTypeStrictAnyEvaluate);\n    }\n  }\n\n  context.evaluator->evaluate(&target);\n  EVALUATE_END(LoopPropertiesTypeStrictAnyEvaluate);\n}\n\nINSTRUCTION_HANDLER(LoopKeys) {\n  EVALUATE_BEGIN_NON_STRING(LoopKeys, target.is_object());\n  assert(!instruction.children.empty());\n  result = true;\n  for (const auto &entry : target.as_object()) {\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(entry.first);\n      }\n    }\n\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE_ON_PROPERTY_NAME(child, Evaluator::null,\n                                             entry.first)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopKeys);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopKeys);\n}\n\nINSTRUCTION_HANDLER(LoopItems) {\n  EVALUATE_BEGIN_NON_STRING(LoopItems, target.is_array());\n  assert(!instruction.children.empty());\n  result = true;\n\n  // To avoid index lookups and unnecessary conditionals\n  if constexpr (!Track && !HasCallback) {\n    for (const auto &new_instance : target.as_array()) {\n      for (const auto &child : instruction.children) {\n        if (!EVALUATE_RECURSE(child, new_instance)) [[unlikely]] {\n          result = false;\n          EVALUATE_END(LoopItems);\n        }\n      }\n    }\n  } else {\n    for (std::size_t index = 0; index < target.array_size(); index++) {\n      if constexpr (HasCallback) {\n        if (track) {\n          context.evaluator->instance_location.push_back(index);\n        }\n      }\n\n      const auto &new_instance{target.at(index)};\n      for (const auto &child : instruction.children) {\n        if (!EVALUATE_RECURSE(child, new_instance)) [[unlikely]] {\n          result = false;\n\n          if constexpr (HasCallback) {\n            if (track) {\n              context.evaluator->instance_location.pop_back();\n            }\n          }\n\n          EVALUATE_END(LoopItems);\n        }\n      }\n\n      if constexpr (HasCallback) {\n        if (track) {\n          context.evaluator->instance_location.pop_back();\n        }\n      }\n    }\n  }\n\n  EVALUATE_END(LoopItems);\n}\n\nINSTRUCTION_HANDLER(LoopItemsFrom) {\n  const auto value{assume_value_copy<ValueUnsignedInteger>(instruction.value)};\n  EVALUATE_BEGIN_NON_STRING(LoopItemsFrom,\n                            target.is_array() && value < target.array_size());\n  assert(!instruction.children.empty());\n  result = true;\n  for (std::size_t index = value; index < target.array_size(); index++) {\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(index);\n      }\n    }\n\n    const auto &new_instance{target.at(index)};\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, new_instance)) [[unlikely]] {\n        result = false;\n\n        if constexpr (HasCallback) {\n          if (track) {\n            context.evaluator->instance_location.pop_back();\n          }\n        }\n\n        EVALUATE_END(LoopItemsFrom);\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n  }\n\n  EVALUATE_END(LoopItemsFrom);\n}\n\nINSTRUCTION_HANDLER(LoopItemsUnevaluated) {\n  EVALUATE_BEGIN_NON_STRING(LoopItemsUnevaluated, target.is_array());\n  assert(!instruction.children.empty());\n  result = true;\n\n  if (!context.evaluator->is_evaluated(&target)) {\n    for (std::size_t index = 0; index < target.array_size(); index++) {\n      const auto &new_instance{target.at(index)};\n      if (context.evaluator->is_evaluated(&new_instance)) {\n        continue;\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.push_back(index);\n      }\n      for (const auto &child : instruction.children) {\n        if (!EVALUATE_RECURSE(child, new_instance)) [[unlikely]] {\n          result = false;\n          if constexpr (HasCallback) {\n            context.evaluator->instance_location.pop_back();\n          }\n          EVALUATE_END(LoopItemsUnevaluated);\n        }\n      }\n\n      if constexpr (HasCallback) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n\n    context.evaluator->evaluate(&target);\n  }\n\n  EVALUATE_END(LoopItemsUnevaluated);\n}\n\nINSTRUCTION_HANDLER(LoopItemsType) {\n  EVALUATE_BEGIN_NON_STRING(LoopItemsType, target.is_array());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_array()) {\n    if (entry.type() != value &&\n        // In non-strict mode, we consider a real number that represents an\n        // integer to be an integer\n        (value != JSON::Type::Integer || !entry.is_integral())) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopItemsType);\n}\n\nINSTRUCTION_HANDLER(LoopItemsTypeStrict) {\n  EVALUATE_BEGIN_NON_STRING(LoopItemsTypeStrict, target.is_array());\n  result = true;\n  const auto value{assume_value_copy<ValueType>(instruction.value)};\n  for (const auto &entry : target.as_array()) {\n    if (effective_type_strict_real(entry) != value) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopItemsTypeStrict);\n}\n\nINSTRUCTION_HANDLER(LoopItemsTypeStrictAny) {\n  EVALUATE_BEGIN_NON_STRING(LoopItemsTypeStrictAny, target.is_array());\n  const auto value{assume_value_copy<ValueTypes>(instruction.value)};\n  assert(value.any());\n\n  result = true;\n  for (const auto &entry : target.as_array()) {\n    const auto type_index{\n        std::to_underlying(effective_type_strict_real(entry))};\n    if (!value.test(type_index)) [[unlikely]] {\n      result = false;\n      break;\n    }\n  }\n\n  EVALUATE_END(LoopItemsTypeStrictAny);\n}\n\nINSTRUCTION_HANDLER(LoopItemsPropertiesExactlyTypeStrictHash) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LoopItemsPropertiesExactlyTypeStrictHash);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  // TODO: Take advantage of the table of contents structure to speed up checks\n  const auto &value{assume_value<ValueTypedHashes>(instruction.value)};\n  // Otherwise why emit this instruction?\n  assert(!value.second.first.empty());\n\n  if (!target.is_array()) [[unlikely]] {\n    EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n  }\n\n  result = true;\n\n  const auto hashes_size{value.second.first.size()};\n  for (const auto &item : target.as_array()) {\n    if (!item.is_object()) [[unlikely]] {\n      result = false;\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n    }\n\n    const auto &object{item.as_object()};\n    const auto size{object.size()};\n    if (size != hashes_size) [[unlikely]] {\n      result = false;\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n    }\n\n    // Unroll, for performance reasons, for small collections\n    if (hashes_size == 3) {\n      for (const auto &entry : object) {\n        if (effective_type_strict_real(entry.second) != value.first)\n            // NOLINTNEXTLINE(bugprone-branch-clone)\n            [[unlikely]] {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        } else if (entry.hash != value.second.first[0].first &&\n                   entry.hash != value.second.first[1].first &&\n                   entry.hash != value.second.first[2].first) {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        }\n      }\n    } else if (hashes_size == 2) {\n      for (const auto &entry : object) {\n        if (effective_type_strict_real(entry.second) != value.first)\n            // NOLINTNEXTLINE(bugprone-branch-clone)\n            [[unlikely]] {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        } else if (entry.hash != value.second.first[0].first &&\n                   entry.hash != value.second.first[1].first) {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        }\n      }\n    } else if (hashes_size == 1) {\n      const auto &entry{*object.cbegin()};\n      if (effective_type_strict_real(entry.second) != value.first ||\n          entry.hash != value.second.first[0].first) [[unlikely]] {\n        result = false;\n        EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n      }\n    } else {\n      std::size_t index{0};\n      for (const auto &entry : object) {\n        if (effective_type_strict_real(entry.second) != value.first)\n            // NOLINTNEXTLINE(bugprone-branch-clone)\n            [[unlikely]] {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        } else if (entry.hash == value.second.first[index].first) {\n          index += 1;\n          continue;\n        } else if (!std::ranges::any_of(value.second.first,\n                                        [&entry](const auto &hash_entry) {\n                                          return hash_entry.first == entry.hash;\n                                        })) {\n          result = false;\n          EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n        } else {\n          index += 1;\n        }\n      }\n    }\n  }\n\n  EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash);\n}\n\nINSTRUCTION_HANDLER(LoopItemsPropertiesExactlyTypeStrictHash3) {\n  EVALUATE_BEGIN_NO_PRECONDITION(LoopItemsPropertiesExactlyTypeStrictHash3);\n  const auto &target{\n      resolve_instance(instance, instruction.relative_instance_location)};\n  // TODO: Take advantage of the table of contents structure to speed up checks\n  const auto &value{assume_value<ValueTypedHashes>(instruction.value)};\n  assert(value.second.first.size() == 3);\n  // Otherwise why emit this instruction?\n  assert(!value.second.first.empty());\n\n  if (!target.is_array()) [[unlikely]] {\n    EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n  }\n\n  for (const auto &item : target.as_array()) {\n    if (!item.is_object()) [[unlikely]] {\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n    }\n\n    const auto &object{item.as_object()};\n    if (object.size() != 3) [[unlikely]] {\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n    }\n\n    const auto &value_1{object.at(0)};\n    const auto &value_2{object.at(1)};\n    const auto &value_3{object.at(2)};\n\n    if (effective_type_strict_real(value_1.second) != value.first ||\n        effective_type_strict_real(value_2.second) != value.first ||\n        effective_type_strict_real(value_3.second) != value.first)\n        [[unlikely]] {\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n    }\n\n    if ((value_1.hash == value.second.first[0].first &&\n         value_2.hash == value.second.first[1].first &&\n         value_3.hash == value.second.first[2].first) ||\n        (value_1.hash == value.second.first[0].first &&\n         value_2.hash == value.second.first[2].first &&\n         value_3.hash == value.second.first[1].first) ||\n        (value_1.hash == value.second.first[1].first &&\n         value_2.hash == value.second.first[0].first &&\n         value_3.hash == value.second.first[2].first) ||\n        (value_1.hash == value.second.first[1].first &&\n         value_2.hash == value.second.first[2].first &&\n         value_3.hash == value.second.first[0].first) ||\n        (value_1.hash == value.second.first[2].first &&\n         value_2.hash == value.second.first[0].first &&\n         value_3.hash == value.second.first[1].first) ||\n        (value_1.hash == value.second.first[2].first &&\n         value_2.hash == value.second.first[1].first &&\n         value_3.hash == value.second.first[0].first)) {\n      continue;\n    } else {\n      EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n    }\n  }\n\n  result = true;\n  EVALUATE_END(LoopItemsPropertiesExactlyTypeStrictHash3);\n}\n\nINSTRUCTION_DIRECT_COPY(LoopItemsIntegerBounded, ValueIntegerBounds) {\n  if (!target.is_array() || target.empty()) {\n    return true;\n  }\n  for (const auto &element : target.as_array()) {\n    if (!element.is_number()) [[unlikely]] {\n      return false;\n    }\n\n    if (element.is_integer()) {\n      const auto integer{element.to_integer()};\n      if (integer < value.first || integer > value.second) [[unlikely]] {\n        return false;\n      }\n    } else if (element.is_real()) {\n      const auto real{element.to_real()};\n      if (real < static_cast<double>(value.first) ||\n          real > static_cast<double>(value.second)) [[unlikely]] {\n        return false;\n      }\n    } else {\n      const auto real{element.to_decimal().to_double()};\n      if (real < static_cast<double>(value.first) ||\n          real > static_cast<double>(value.second)) [[unlikely]] {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nINSTRUCTION_HANDLER(LoopItemsIntegerBounded) {\n  EVALUATE_BEGIN_NON_STRING(LoopItemsIntegerBounded,\n                            target.is_array() && !target.empty());\n  result = DIRECT(LoopItemsIntegerBounded, target,\n                  assume_value_copy<ValueIntegerBounds>(instruction.value));\n  EVALUATE_END(LoopItemsIntegerBounded);\n}\n\nINSTRUCTION_HANDLER(LoopItemsIntegerBoundedSized) {\n  const auto &value{\n      assume_value<ValueIntegerBoundsWithSize>(instruction.value)};\n  const auto &integer_bounds{value.first};\n  const auto minimum_size{std::get<0>(value.second)};\n  EVALUATE_BEGIN_NON_STRING(LoopItemsIntegerBoundedSized, true);\n  if (!target.is_array() || target.array_size() < minimum_size) {\n    EVALUATE_END(LoopItemsIntegerBoundedSized);\n  }\n\n  result = true;\n  for (const auto &element : target.as_array()) {\n    if (!element.is_number()) [[unlikely]] {\n      result = false;\n      break;\n    }\n\n    if (element.is_integer()) {\n      const auto integer{element.to_integer()};\n      if (integer < integer_bounds.first || integer > integer_bounds.second)\n          [[unlikely]] {\n        result = false;\n        break;\n      }\n    } else if (element.is_real()) {\n      const auto real{element.to_real()};\n      if (real < static_cast<double>(integer_bounds.first) ||\n          real > static_cast<double>(integer_bounds.second)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    } else {\n      const auto real{element.to_decimal().to_double()};\n      if (real < static_cast<double>(integer_bounds.first) ||\n          real > static_cast<double>(integer_bounds.second)) [[unlikely]] {\n        result = false;\n        break;\n      }\n    }\n  }\n\n  EVALUATE_END(LoopItemsIntegerBoundedSized);\n}\n\nINSTRUCTION_HANDLER(LoopContains) {\n  EVALUATE_BEGIN_NON_STRING(LoopContains, target.is_array());\n  assert(!instruction.children.empty());\n  const auto &value{assume_value<ValueRange>(instruction.value)};\n  const auto &[minimum, maximum, is_exhaustive] = value;\n  assert(!maximum.has_value() || maximum.value() >= minimum);\n  result = minimum == 0 && target.empty();\n  auto match_count{\n      std::numeric_limits<std::remove_cvref_t<decltype(minimum)>>::min()};\n\n  for (std::size_t index = 0; index < target.array_size(); index++) {\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.push_back(index);\n      }\n    }\n\n    const auto &new_instance{target.at(index)};\n    bool subresult{true};\n    for (const auto &child : instruction.children) {\n      if (!EVALUATE_RECURSE(child, new_instance)) {\n        subresult = false;\n        break;\n      }\n    }\n\n    if constexpr (HasCallback) {\n      if (track) {\n        context.evaluator->instance_location.pop_back();\n      }\n    }\n\n    if (subresult) {\n      match_count += 1;\n\n      // Exceeding the upper bound is definitely a failure\n      if (maximum.has_value() && match_count > maximum.value()) {\n        result = false;\n\n        // Note that here we don't want to consider whether to run\n        // exhaustively or not. At this point, its already a failure,\n        // and anything that comes after would not run at all anyway\n        break;\n      }\n\n      if (match_count >= minimum) {\n        result = true;\n\n        // Exceeding the lower bound when there is no upper bound\n        // is definitely a success\n        if (!maximum.has_value() && !is_exhaustive) {\n          break;\n        }\n      }\n    }\n  }\n\n  EVALUATE_END(LoopContains);\n}\n\n#undef INSTRUCTION_HANDLER\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\nusing DispatchHandler = bool (*)(\n    const sourcemeta::blaze::Instruction &, const sourcemeta::core::JSON &,\n    std::uint64_t, DispatchContext<Track, Dynamic, HasCallback> &);\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\n// Must have same order as InstructionIndex\n// NOLINTNEXTLINE(modernize-avoid-c-arrays)\nstatic constexpr DispatchHandler<Track, Dynamic, HasCallback> handlers[100] = {\n    AssertionFail,\n    AssertionDefines,\n    AssertionDefinesStrict,\n    AssertionDefinesAll,\n    AssertionDefinesAllStrict,\n    AssertionDefinesExactly,\n    AssertionDefinesExactlyStrict,\n    AssertionDefinesExactlyStrictHash3,\n    AssertionPropertyDependencies,\n    AssertionType,\n    AssertionTypeAny,\n    AssertionTypeStrict,\n    AssertionTypeStrictAny,\n    AssertionNotTypeStrictAny,\n    AssertionTypeStringBounded,\n    AssertionTypeStringUpper,\n    AssertionTypeArrayBounded,\n    AssertionTypeArrayUpper,\n    AssertionTypeObjectBounded,\n    AssertionTypeObjectUpper,\n    AssertionRegex,\n    AssertionStringSizeLess,\n    AssertionStringSizeGreater,\n    AssertionArraySizeLess,\n    AssertionArraySizeGreater,\n    AssertionObjectSizeLess,\n    AssertionObjectSizeGreater,\n    AssertionEqual,\n    AssertionEqualsAny,\n    AssertionEqualsAnyStringHash,\n    AssertionGreaterEqual,\n    AssertionLessEqual,\n    AssertionGreater,\n    AssertionLess,\n    AssertionUnique,\n    AssertionDivisible,\n    AssertionTypeIntegerBounded,\n    AssertionTypeIntegerBoundedStrict,\n    AssertionTypeIntegerLowerBound,\n    AssertionTypeIntegerLowerBoundStrict,\n    AssertionStringType,\n    AssertionPropertyType,\n    AssertionPropertyTypeEvaluate,\n    AssertionPropertyTypeStrict,\n    AssertionPropertyTypeStrictEvaluate,\n    AssertionPropertyTypeStrictAny,\n    AssertionPropertyTypeStrictAnyEvaluate,\n    AssertionArrayPrefix,\n    AssertionArrayPrefixEvaluate,\n    AssertionObjectPropertiesSimple,\n    AnnotationEmit,\n    AnnotationToParent,\n    AnnotationBasenameToParent,\n    Evaluate,\n    LogicalNot,\n    LogicalNotEvaluate,\n    LogicalOr,\n    LogicalAnd,\n    LogicalXor,\n    LogicalCondition,\n    LogicalWhenType,\n    LogicalWhenDefines,\n    LogicalWhenArraySizeGreater,\n    LoopPropertiesUnevaluated,\n    LoopPropertiesUnevaluatedExcept,\n    LoopPropertiesMatch,\n    LoopPropertiesMatchClosed,\n    LoopProperties,\n    LoopPropertiesEvaluate,\n    LoopPropertiesRegex,\n    LoopPropertiesRegexClosed,\n    LoopPropertiesStartsWith,\n    LoopPropertiesExcept,\n    LoopPropertiesType,\n    LoopPropertiesTypeEvaluate,\n    LoopPropertiesExactlyTypeStrict,\n    LoopPropertiesExactlyTypeStrictHash,\n    LoopPropertiesTypeStrict,\n    LoopPropertiesTypeStrictEvaluate,\n    LoopPropertiesTypeStrictAny,\n    LoopPropertiesTypeStrictAnyEvaluate,\n    LoopKeys,\n    LoopItems,\n    LoopItemsFrom,\n    LoopItemsUnevaluated,\n    LoopItemsType,\n    LoopItemsTypeStrict,\n    LoopItemsTypeStrictAny,\n    LoopItemsPropertiesExactlyTypeStrictHash,\n    LoopItemsPropertiesExactlyTypeStrictHash3,\n    LoopItemsIntegerBounded,\n    LoopItemsIntegerBoundedSized,\n    LoopContains,\n    ControlGroup,\n    ControlGroupWhenDefines,\n    ControlGroupWhenDefinesDirect,\n    ControlGroupWhenType,\n    ControlEvaluate,\n    ControlDynamicAnchorJump,\n    ControlJump};\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\ninline auto\nevaluate_instruction(const sourcemeta::blaze::Instruction &instruction,\n                     const sourcemeta::core::JSON &instance,\n                     const std::uint64_t depth,\n                     DispatchContext<Track, Dynamic, HasCallback> &context)\n    -> bool {\n  constexpr auto DEPTH_LIMIT{300};\n  if (depth > DEPTH_LIMIT) [[unlikely]] {\n    throw EvaluationError(\"The evaluation path depth limit was reached \"\n                          \"likely due to infinite recursion\");\n  }\n\n  return handlers<Track, Dynamic, HasCallback>[std::to_underlying(\n      instruction.type)](instruction, instance, depth, context);\n}\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\ninline auto evaluate_instruction_without_callback(\n    const sourcemeta::blaze::Instruction &instruction,\n    const sourcemeta::core::JSON &instance, const std::uint64_t depth,\n    DispatchContext<Track, Dynamic, HasCallback> &context) -> bool {\n  constexpr auto DEPTH_LIMIT{300};\n  if (depth > DEPTH_LIMIT) [[unlikely]] {\n    throw EvaluationError(\"The evaluation path depth limit was reached \"\n                          \"likely due to infinite recursion\");\n  }\n\n  DispatchContext<false, Dynamic, false> plain_context{\n      context.schema, context.callback, context.evaluator,\n      context.property_target};\n  return handlers<false, Dynamic, false>[std::to_underlying(instruction.type)](\n      instruction, instance, depth, plain_context);\n}\n\ntemplate <bool Track, bool Dynamic, bool HasCallback>\ninline auto evaluate_instruction_with_property(\n    const sourcemeta::blaze::Instruction &instruction,\n    const sourcemeta::core::JSON &instance, const std::uint64_t depth,\n    DispatchContext<Track, Dynamic, HasCallback> &context,\n    const sourcemeta::core::JSON::String &name) -> bool {\n  const auto *previous = context.property_target;\n  context.property_target = &name;\n  const auto result =\n      evaluate_instruction(instruction, instance, depth, context);\n  context.property_target = previous;\n  return result;\n}\n\n} // namespace sourcemeta::blaze::dispatch\n\n#undef EVALUATE_PUSH\n#undef EVALUATE_POP\n#undef EVALUATE_BEGIN\n#undef EVALUATE_BEGIN_NON_STRING\n#undef EVALUATE_BEGIN_IF_STRING\n#undef EVALUATE_BEGIN_TRY_TARGET\n#undef EVALUATE_BEGIN_NO_PRECONDITION\n#undef EVALUATE_BEGIN_NO_PRECONDITION_AND_NO_PUSH\n#undef EVALUATE_BEGIN_PASS_THROUGH\n#undef EVALUATE_END\n#undef EVALUATE_END_NO_POP\n#undef EVALUATE_END_PASS_THROUGH\n#undef EVALUATE_ANNOTATION\n#undef EVALUATE_RECURSE\n#undef EVALUATE_RECURSE_ON_PROPERTY_NAME\n#undef SOURCEMETA_ASSUME\n#undef SOURCEMETA_STRINGIFY\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_ERROR_H\n#define SOURCEMETA_BLAZE_EVALUATOR_ERROR_H\n\n#ifndef SOURCEMETA_BLAZE_EVALUATOR_EXPORT\n#include <sourcemeta/blaze/evaluator_export.h>\n#endif\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup evaluator\n/// An error that represents a schema evaluation error event\nclass SOURCEMETA_BLAZE_EVALUATOR_EXPORT EvaluationError\n    : public std::exception {\npublic:\n  EvaluationError(const char *message) : message_{message} {}\n  EvaluationError(std::string message) = delete;\n  EvaluationError(std::string &&message) = delete;\n  EvaluationError(std::string_view message) = delete;\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator_instruction.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_TEMPLATE_H\n#define SOURCEMETA_BLAZE_EVALUATOR_TEMPLATE_H\n\n#ifndef SOURCEMETA_BLAZE_EVALUATOR_EXPORT\n#include <sourcemeta/blaze/evaluator_export.h>\n#endif\n\n#include <sourcemeta/blaze/evaluator_value.h>\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <cstdint>     // std::uint8_t\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <vector>      // std::vector\n\nnamespace sourcemeta::blaze {\n\n// For fast internal instruction dispatching. It must stay\n// in sync with the variant ordering above\n/// @ingroup evaluator\nenum class InstructionIndex : std::uint8_t {\n  AssertionFail = 0,\n  AssertionDefines,\n  AssertionDefinesStrict,\n  AssertionDefinesAll,\n  AssertionDefinesAllStrict,\n  AssertionDefinesExactly,\n  AssertionDefinesExactlyStrict,\n  AssertionDefinesExactlyStrictHash3,\n  AssertionPropertyDependencies,\n  AssertionType,\n  AssertionTypeAny,\n  AssertionTypeStrict,\n  AssertionTypeStrictAny,\n  AssertionNotTypeStrictAny,\n  AssertionTypeStringBounded,\n  AssertionTypeStringUpper,\n  AssertionTypeArrayBounded,\n  AssertionTypeArrayUpper,\n  AssertionTypeObjectBounded,\n  AssertionTypeObjectUpper,\n  AssertionRegex,\n  AssertionStringSizeLess,\n  AssertionStringSizeGreater,\n  AssertionArraySizeLess,\n  AssertionArraySizeGreater,\n  AssertionObjectSizeLess,\n  AssertionObjectSizeGreater,\n  AssertionEqual,\n  AssertionEqualsAny,\n  AssertionEqualsAnyStringHash,\n  AssertionGreaterEqual,\n  AssertionLessEqual,\n  AssertionGreater,\n  AssertionLess,\n  AssertionUnique,\n  AssertionDivisible,\n  AssertionTypeIntegerBounded,\n  AssertionTypeIntegerBoundedStrict,\n  AssertionTypeIntegerLowerBound,\n  AssertionTypeIntegerLowerBoundStrict,\n  AssertionStringType,\n  AssertionPropertyType,\n  AssertionPropertyTypeEvaluate,\n  AssertionPropertyTypeStrict,\n  AssertionPropertyTypeStrictEvaluate,\n  AssertionPropertyTypeStrictAny,\n  AssertionPropertyTypeStrictAnyEvaluate,\n  AssertionArrayPrefix,\n  AssertionArrayPrefixEvaluate,\n  AssertionObjectPropertiesSimple,\n  AnnotationEmit,\n  AnnotationToParent,\n  AnnotationBasenameToParent,\n  Evaluate,\n  LogicalNot,\n  LogicalNotEvaluate,\n  LogicalOr,\n  LogicalAnd,\n  LogicalXor,\n  LogicalCondition,\n  LogicalWhenType,\n  LogicalWhenDefines,\n  LogicalWhenArraySizeGreater,\n  LoopPropertiesUnevaluated,\n  LoopPropertiesUnevaluatedExcept,\n  LoopPropertiesMatch,\n  LoopPropertiesMatchClosed,\n  LoopProperties,\n  LoopPropertiesEvaluate,\n  LoopPropertiesRegex,\n  LoopPropertiesRegexClosed,\n  LoopPropertiesStartsWith,\n  LoopPropertiesExcept,\n  LoopPropertiesType,\n  LoopPropertiesTypeEvaluate,\n  LoopPropertiesExactlyTypeStrict,\n  LoopPropertiesExactlyTypeStrictHash,\n  LoopPropertiesTypeStrict,\n  LoopPropertiesTypeStrictEvaluate,\n  LoopPropertiesTypeStrictAny,\n  LoopPropertiesTypeStrictAnyEvaluate,\n  LoopKeys,\n  LoopItems,\n  LoopItemsFrom,\n  LoopItemsUnevaluated,\n  LoopItemsType,\n  LoopItemsTypeStrict,\n  LoopItemsTypeStrictAny,\n  LoopItemsPropertiesExactlyTypeStrictHash,\n  LoopItemsPropertiesExactlyTypeStrictHash3,\n  LoopItemsIntegerBounded,\n  LoopItemsIntegerBoundedSized,\n  LoopContains,\n  ControlGroup,\n  ControlGroupWhenDefines,\n  ControlGroupWhenDefinesDirect,\n  ControlGroupWhenType,\n  ControlEvaluate,\n  ControlDynamicAnchorJump,\n  ControlJump\n};\n\n/// @ingroup evaluator\n// NOLINTNEXTLINE(modernize-avoid-c-arrays)\nconstexpr std::string_view InstructionNames[] = {\n    \"AssertionFail\",\n    \"AssertionDefines\",\n    \"AssertionDefinesStrict\",\n    \"AssertionDefinesAll\",\n    \"AssertionDefinesAllStrict\",\n    \"AssertionDefinesExactly\",\n    \"AssertionDefinesExactlyStrict\",\n    \"AssertionDefinesExactlyStrictHash3\",\n    \"AssertionPropertyDependencies\",\n    \"AssertionType\",\n    \"AssertionTypeAny\",\n    \"AssertionTypeStrict\",\n    \"AssertionTypeStrictAny\",\n    \"AssertionNotTypeStrictAny\",\n    \"AssertionTypeStringBounded\",\n    \"AssertionTypeStringUpper\",\n    \"AssertionTypeArrayBounded\",\n    \"AssertionTypeArrayUpper\",\n    \"AssertionTypeObjectBounded\",\n    \"AssertionTypeObjectUpper\",\n    \"AssertionRegex\",\n    \"AssertionStringSizeLess\",\n    \"AssertionStringSizeGreater\",\n    \"AssertionArraySizeLess\",\n    \"AssertionArraySizeGreater\",\n    \"AssertionObjectSizeLess\",\n    \"AssertionObjectSizeGreater\",\n    \"AssertionEqual\",\n    \"AssertionEqualsAny\",\n    \"AssertionEqualsAnyStringHash\",\n    \"AssertionGreaterEqual\",\n    \"AssertionLessEqual\",\n    \"AssertionGreater\",\n    \"AssertionLess\",\n    \"AssertionUnique\",\n    \"AssertionDivisible\",\n    \"AssertionTypeIntegerBounded\",\n    \"AssertionTypeIntegerBoundedStrict\",\n    \"AssertionTypeIntegerLowerBound\",\n    \"AssertionTypeIntegerLowerBoundStrict\",\n    \"AssertionStringType\",\n    \"AssertionPropertyType\",\n    \"AssertionPropertyTypeEvaluate\",\n    \"AssertionPropertyTypeStrict\",\n    \"AssertionPropertyTypeStrictEvaluate\",\n    \"AssertionPropertyTypeStrictAny\",\n    \"AssertionPropertyTypeStrictAnyEvaluate\",\n    \"AssertionArrayPrefix\",\n    \"AssertionArrayPrefixEvaluate\",\n    \"AssertionObjectPropertiesSimple\",\n    \"AnnotationEmit\",\n    \"AnnotationToParent\",\n    \"AnnotationBasenameToParent\",\n    \"Evaluate\",\n    \"LogicalNot\",\n    \"LogicalNotEvaluate\",\n    \"LogicalOr\",\n    \"LogicalAnd\",\n    \"LogicalXor\",\n    \"LogicalCondition\",\n    \"LogicalWhenType\",\n    \"LogicalWhenDefines\",\n    \"LogicalWhenArraySizeGreater\",\n    \"LoopPropertiesUnevaluated\",\n    \"LoopPropertiesUnevaluatedExcept\",\n    \"LoopPropertiesMatch\",\n    \"LoopPropertiesMatchClosed\",\n    \"LoopProperties\",\n    \"LoopPropertiesEvaluate\",\n    \"LoopPropertiesRegex\",\n    \"LoopPropertiesRegexClosed\",\n    \"LoopPropertiesStartsWith\",\n    \"LoopPropertiesExcept\",\n    \"LoopPropertiesType\",\n    \"LoopPropertiesTypeEvaluate\",\n    \"LoopPropertiesExactlyTypeStrict\",\n    \"LoopPropertiesExactlyTypeStrictHash\",\n    \"LoopPropertiesTypeStrict\",\n    \"LoopPropertiesTypeStrictEvaluate\",\n    \"LoopPropertiesTypeStrictAny\",\n    \"LoopPropertiesTypeStrictAnyEvaluate\",\n    \"LoopKeys\",\n    \"LoopItems\",\n    \"LoopItemsFrom\",\n    \"LoopItemsUnevaluated\",\n    \"LoopItemsType\",\n    \"LoopItemsTypeStrict\",\n    \"LoopItemsTypeStrictAny\",\n    \"LoopItemsPropertiesExactlyTypeStrictHash\",\n    \"LoopItemsPropertiesExactlyTypeStrictHash3\",\n    \"LoopItemsIntegerBounded\",\n    \"LoopItemsIntegerBoundedSized\",\n    \"LoopContains\",\n    \"ControlGroup\",\n    \"ControlGroupWhenDefines\",\n    \"ControlGroupWhenDefinesDirect\",\n    \"ControlGroupWhenType\",\n    \"ControlEvaluate\",\n    \"ControlDynamicAnchorJump\",\n    \"ControlJump\"};\n\n/// @ingroup evaluator\n/// Check if a given instruction type corresponds to an annotation\ninline auto is_annotation(const InstructionIndex type) noexcept -> bool {\n  switch (type) {\n    // NOLINTNEXTLINE(bugprone-branch-clone)\n    case InstructionIndex::AnnotationBasenameToParent:\n      return true;\n    case InstructionIndex::AnnotationToParent:\n      return true;\n    case InstructionIndex::AnnotationEmit:\n      return true;\n    default:\n      return false;\n  }\n}\n\n// Forward declaration for defining a circular structure\n#ifndef DOXYGEN\nstruct Instruction;\n#endif\n\n/// @ingroup evaluator\n/// Represents a set of schema compilation steps that can be evaluated\nusing Instructions = std::vector<Instruction>;\n\n/// @ingroup evaluator\n/// Satellite data for an instruction that is not needed during fast evaluation\nstruct InstructionExtra {\n  sourcemeta::core::Pointer relative_schema_location;\n  std::string keyword_location;\n  std::size_t schema_resource;\n};\n\n/// @ingroup evaluator\n/// Represents a single instruction to be evaluated\n// NOLINTNEXTLINE(bugprone-exception-escape)\nstruct Instruction {\n  InstructionIndex type;\n  sourcemeta::core::Pointer relative_instance_location;\n  Value value;\n  Instructions children;\n  std::size_t extra_index;\n};\n\n/// @ingroup evaluator\n///\n/// This function translates a \"post\" step execution into a human-readable\n/// string. Useful as the building block for producing user-friendly evaluation\n/// results.\n///\n/// Note that describing a \"pre\" step execution is NOT supported.\nauto SOURCEMETA_BLAZE_EVALUATOR_EXPORT\ndescribe(const bool valid, const Instruction &step,\n         const sourcemeta::core::WeakPointer &evaluate_path,\n         const sourcemeta::core::WeakPointer &instance_location,\n         const sourcemeta::core::JSON &instance,\n         const sourcemeta::core::JSON &annotation) -> std::string;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator_string_set.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_STRING_SET_H\n#define SOURCEMETA_BLAZE_EVALUATOR_STRING_SET_H\n\n#ifndef SOURCEMETA_BLAZE_EVALUATOR_EXPORT\n#include <sourcemeta/blaze/evaluator_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <algorithm> // std::ranges::sort\n#include <optional>  // std::optional\n#include <utility>   // std::pair, std::move\n#include <vector>    // std::vector\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup evaluator\nclass SOURCEMETA_BLAZE_EVALUATOR_EXPORT StringSet {\npublic:\n  StringSet() = default;\n\n  using string_type = sourcemeta::core::JSON::String;\n  using hash_type = sourcemeta::core::JSON::Object::hash_type;\n  using value_type = std::pair<string_type, hash_type>;\n  using underlying_type = std::vector<value_type>;\n  using size_type = typename underlying_type::size_type;\n  using difference_type = typename underlying_type::difference_type;\n  using const_iterator = typename underlying_type::const_iterator;\n\n  [[nodiscard]] inline auto contains(const string_type &value,\n                                     const hash_type hash) const -> bool {\n    if (this->hasher.is_perfect(hash)) {\n      for (const auto &entry : this->data) {\n        if (entry.second == hash) {\n          return true;\n        }\n      }\n    } else {\n      for (const auto &entry : this->data) {\n        if (entry.second == hash && entry.first == value) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n  [[nodiscard]] inline auto contains(const string_type &value) const -> bool {\n    return this->contains(value, this->hasher(value));\n  }\n\n  [[nodiscard]] inline auto at(const size_type index) const noexcept\n      -> const value_type & {\n    return this->data[index];\n  }\n\n  inline auto insert(const string_type &value) -> void {\n    const auto hash{this->hasher(value)};\n    if (!this->contains(value, hash)) {\n      this->data.emplace_back(value, hash);\n      std::ranges::sort(this->data, [](const auto &left, const auto &right) {\n        return left.first < right.first;\n      });\n    }\n  }\n  inline auto insert(string_type &&value) -> void {\n    const auto hash{this->hasher(value)};\n    if (!this->contains(value, hash)) {\n      this->data.emplace_back(std::move(value), hash);\n      std::ranges::sort(this->data, [](const auto &left, const auto &right) {\n        return left.first < right.first;\n      });\n    }\n  }\n\n  [[nodiscard]] inline auto empty() const noexcept -> bool {\n    return this->data.empty();\n  }\n  [[nodiscard]] inline auto size() const noexcept -> size_type {\n    return this->data.size();\n  }\n\n  [[nodiscard]] inline auto begin() const -> const_iterator {\n    return this->data.begin();\n  }\n  [[nodiscard]] inline auto end() const -> const_iterator {\n    return this->data.end();\n  }\n  [[nodiscard]] inline auto cbegin() const -> const_iterator {\n    return this->data.cbegin();\n  }\n  [[nodiscard]] inline auto cend() const -> const_iterator {\n    return this->data.cend();\n  }\n\n  [[nodiscard]] auto to_json() const -> sourcemeta::core::JSON {\n    return sourcemeta::core::to_json(this->data, [](const auto &item) {\n      return sourcemeta::core::to_json(item.first);\n    });\n  }\n\n  static auto from_json(const sourcemeta::core::JSON &value)\n      -> std::optional<StringSet> {\n    if (!value.is_array()) {\n      return std::nullopt;\n    }\n\n    StringSet result;\n    for (const auto &item : value.as_array()) {\n      auto subvalue{\n          sourcemeta::core::from_json<sourcemeta::core::JSON::String>(item)};\n      if (!subvalue.has_value()) {\n        return std::nullopt;\n      }\n\n      result.insert(std::move(subvalue).value());\n    }\n\n    return result;\n  }\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n  underlying_type data;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n  sourcemeta::core::PropertyHashJSON<string_type> hasher;\n};\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator_value.h",
    "content": "#ifndef SOURCEMETA_BLAZE_EVALUATOR_VALUE_H\n#define SOURCEMETA_BLAZE_EVALUATOR_VALUE_H\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/regex.h>\n\n#include <sourcemeta/blaze/evaluator_string_set.h>\n\n#include <cstdint>       // std::uint8_t\n#include <optional>      // std::optional\n#include <string>        // std::string\n#include <tuple>         // std::tuple\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::pair\n#include <vector>        // std::vector\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup evaluator\n/// @brief Represents a compiler step empty value\nstruct ValueNone {\n  [[nodiscard]] auto to_json() const -> sourcemeta::core::JSON {\n    return sourcemeta::core::JSON{nullptr};\n  }\n\n  static auto from_json(const sourcemeta::core::JSON &)\n      -> std::optional<ValueNone> {\n    return ValueNone{};\n  }\n};\n\n/// @ingroup evaluator\n/// Represents a compiler step JSON value\nusing ValueJSON = sourcemeta::core::JSON;\n\n/// @ingroup evaluator\n/// Represents a set of JSON values\nusing ValueSet =\n    std::unordered_set<sourcemeta::core::JSON,\n                       sourcemeta::core::HashJSON<sourcemeta::core::JSON>>;\n\n/// @ingroup evaluator\n/// Represents a compiler step string value\nusing ValueString = sourcemeta::core::JSON::String;\n\n/// @ingroup evaluator\n/// Represents a compiler step object property value\nusing ValueProperty =\n    std::pair<ValueString, sourcemeta::core::JSON::Object::hash_type>;\n\n/// @ingroup evaluator\n/// Represents a compiler step string values\nusing ValueStrings = std::vector<ValueString>;\n\n/// @ingroup evaluator\n/// Represents a compiler step string set of values\nusing ValueStringSet = StringSet;\n\n/// @ingroup evaluator\n/// Represents a compiler step JSON types value as a bitmask\nusing ValueTypes = sourcemeta::core::JSON::TypeSet;\n\n/// @ingroup evaluator\n/// Represents a compiler step JSON type value\nusing ValueType = sourcemeta::core::JSON::Type;\n\n/// @ingroup evaluator\n/// Represents a compiler step ECMA regular expression value. We store both the\n/// original string and the regular expression as standard regular expressions\n/// do not keep a copy of their original value (which we need for serialization\n/// purposes)\n// NOLINTNEXTLINE(bugprone-exception-escape)\nstruct ValueRegex {\n  using second_type = ValueString;\n  using first_type = sourcemeta::core::Regex;\n  first_type first;\n  second_type second;\n\n  [[nodiscard]] auto to_json() const -> sourcemeta::core::JSON {\n    return sourcemeta::core::to_json(this->second);\n  }\n\n  static auto from_json(const sourcemeta::core::JSON &value)\n      -> std::optional<ValueRegex> {\n    if (!value.is_string()) {\n      return std::nullopt;\n    }\n\n    auto string{value.to_string()};\n    auto regex{sourcemeta::core::to_regex(string)};\n    if (!regex.has_value()) {\n      return std::nullopt;\n    }\n\n    // NOLINTNEXTLINE(modernize-use-designated-initializers)\n    return ValueRegex{std::move(regex).value(), std::move(string)};\n  }\n};\n\n/// @ingroup evaluator\n/// Represents a compiler step JSON unsigned integer value\nusing ValueUnsignedInteger = std::size_t;\n\n/// @ingroup evaluator\n/// Represents a compiler step range value. The boolean option\n/// modifies whether the range is considered exhaustively or\n/// if the evaluator is allowed to break early\nusing ValueRange = std::tuple<std::size_t, std::optional<std::size_t>, bool>;\n\n/// @ingroup evaluator\n/// Represents a compiler step boolean value\nusing ValueBoolean = bool;\n\n/// @ingroup evaluator\n/// Represents a compiler step string to index map\nusing ValueNamedIndexes = sourcemeta::core::JSONObject<\n    ValueString, ValueUnsignedInteger,\n    sourcemeta::core::PropertyHashJSON<ValueString>>;\n\n/// @ingroup evaluator\n/// Represents a compiler step string logical type\nenum class ValueStringType : std::uint8_t { URI };\n\n/// @ingroup evaluator\n/// Represents an compiler step that maps strings to strings\nusing ValueStringMap = sourcemeta::core::JSONObject<\n    ValueString, ValueStrings, sourcemeta::core::PropertyHashJSON<ValueString>>;\n\n/// @ingroup evaluator\n/// Represents a compiler step value that consist of object property filters\n/// (strings, prefixes, regexes)\nusing ValuePropertyFilter =\n    std::tuple<ValueStringSet, ValueStrings, std::vector<ValueRegex>>;\n\n/// @ingroup evaluator\n/// Represents a compiler step value that consists of two indexes\nusing ValueIndexPair = std::pair<std::size_t, std::size_t>;\n\n/// @ingroup evaluator\n/// Represents a compiler step value that consists of a pointer\nusing ValuePointer = sourcemeta::core::Pointer;\n\n/// @ingroup evaluator\n/// Represents a compiler step types properties value\nusing ValueTypedProperties = std::pair<ValueType, ValueStringSet>;\n\n/// @ingroup evaluator\n/// Represents a compiler step types property hashes value\nusing ValueStringHashes =\n    std::pair<std::vector<std::pair<ValueStringSet::hash_type, ValueString>>,\n              std::vector<ValueIndexPair>>;\n\n/// @ingroup evaluator\n/// Represents a compiler step types property hashes value\nusing ValueTypedHashes = std::pair<ValueType, ValueStringHashes>;\n\n/// @ingroup evaluator\n/// Represents integer bounds with minimum and maximum\nusing ValueIntegerBounds = std::pair<std::int64_t, std::int64_t>;\n\n/// @ingroup evaluator\n/// Represents integer bounds combined with array size range\nusing ValueIntegerBoundsWithSize = std::pair<ValueIntegerBounds, ValueRange>;\n\n/// @ingroup evaluator\n/// Represents a list of object property entries: (name, hash, required)\nusing ValueObjectProperties = std::vector<\n    std::tuple<ValueString, sourcemeta::core::JSON::Object::hash_type, bool>>;\n\n/// @ingroup evaluator\nusing Value = std::variant<\n    ValueNone, ValueJSON, ValueSet, ValueString, ValueProperty, ValueStrings,\n    ValueStringSet, ValueTypes, ValueType, ValueRegex, ValueUnsignedInteger,\n    ValueRange, ValueBoolean, ValueNamedIndexes, ValueStringType,\n    ValueStringMap, ValuePropertyFilter, ValueIndexPair, ValuePointer,\n    ValueTypedProperties, ValueStringHashes, ValueTypedHashes,\n    ValueIntegerBounds, ValueIntegerBoundsWithSize, ValueObjectProperties>;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/output/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME output\n  FOLDER \"Blaze/Output\"\n  PRIVATE_HEADERS simple.h trace.h standard.h\n  SOURCES\n    output_simple.cc\n    output_trace.cc\n    output_standard.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME output)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_output PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_output PUBLIC\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_blaze_output PUBLIC\n  sourcemeta::core::jsonschema)\n\ntarget_link_libraries(sourcemeta_blaze_output PUBLIC\n  sourcemeta::blaze::evaluator)\n"
  },
  {
    "path": "vendor/blaze/src/output/include/sourcemeta/blaze/output.h",
    "content": "#ifndef SOURCEMETA_BLAZE_OUTPUT_H_\n#define SOURCEMETA_BLAZE_OUTPUT_H_\n\n#include <sourcemeta/blaze/output_simple.h>\n#include <sourcemeta/blaze/output_standard.h>\n#include <sourcemeta/blaze/output_trace.h>\n\n/// @defgroup output Output\n/// @brief A collection of Blaze output processing utilities\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/output.h>\n/// ```\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/output/include/sourcemeta/blaze/output_simple.h",
    "content": "#ifndef SOURCEMETA_BLAZE_OUTPUT_SIMPLE_H_\n#define SOURCEMETA_BLAZE_OUTPUT_SIMPLE_H_\n\n#ifndef SOURCEMETA_BLAZE_OUTPUT_EXPORT\n#include <sourcemeta/blaze/output_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <functional> // std::reference_wrapper\n// TODO(C++23): Consider std::flat_map/std::flat_set when available in libc++\n#include <map>     // std::map\n#include <ostream> // std::ostream\n#include <string>  // std::string\n#include <tuple>   // std::tie\n#include <utility> // std::pair\n#include <vector>  // std::vector\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup output\n///\n/// A simple evaluation callback that reports a stack trace in the case of\n/// validation error that you can report as you with. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/compiler.h>\n/// #include <sourcemeta/blaze/evaluator.h>\n/// #include <sourcemeta/blaze/output.h>\n///\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// #include <cassert>\n/// #include <functional>\n///\n/// const sourcemeta::core::JSON schema =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\");\n///\n/// const auto schema_template{sourcemeta::blaze::compile(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver,\n///     sourcemeta::core::default_schema_compiler)};\n///\n/// const sourcemeta::core::JSON instance{5};\n///\n/// sourcemeta::blaze::SimpleOutput output{instance};\n/// sourcemeta::blaze::Evaluator evaluator;\n/// const auto result{evaluator.validate(\n///   schema_template, instance, std::ref(output))};\n///\n/// if (!result) {\n///   for (const auto &entry : output) {\n///     std::cerr << entry.message << \"\\n\";\n///     sourcemeta::core::stringify(entry.instance_location, std::cerr);\n///     std::cerr << \"\\n\";\n///     sourcemeta::core::stringify(entry.evaluate_path, std::cerr);\n///     std::cerr << \"\\n\";\n///   }\n/// }\n/// ```\nclass SOURCEMETA_BLAZE_OUTPUT_EXPORT SimpleOutput {\npublic:\n  SimpleOutput(const sourcemeta::core::JSON &instance,\n               sourcemeta::core::WeakPointer base =\n                   sourcemeta::core::empty_weak_pointer);\n\n  // Prevent accidental copies\n  SimpleOutput(const SimpleOutput &) = delete;\n  auto operator=(const SimpleOutput &) -> SimpleOutput & = delete;\n\n  struct Entry {\n    std::string message;\n    sourcemeta::core::WeakPointer instance_location;\n    sourcemeta::core::WeakPointer evaluate_path;\n    std::reference_wrapper<const std::string> schema_location;\n  };\n\n  auto operator()(const EvaluationType type, const bool result,\n                  const Instruction &step,\n                  const InstructionExtra &step_metadata,\n                  const sourcemeta::core::WeakPointer &evaluate_path,\n                  const sourcemeta::core::WeakPointer &instance_location,\n                  const sourcemeta::core::JSON &annotation) -> void;\n\n  using container_type = typename std::vector<Entry>;\n  using const_iterator = typename container_type::const_iterator;\n  [[nodiscard]] auto begin() const -> const_iterator;\n  [[nodiscard]] auto end() const -> const_iterator;\n  [[nodiscard]] auto cbegin() const -> const_iterator;\n  [[nodiscard]] auto cend() const -> const_iterator;\n\n  /// Access annotations that were collected during evaluation, indexed by\n  /// instance location and evaluation path\n  [[nodiscard]] auto annotations() const -> const auto & {\n    return this->annotations_;\n  }\n\n  // NOLINTNEXTLINE(bugprone-exception-escape)\n  struct Location {\n    auto operator<(const Location &other) const noexcept -> bool {\n      // Perform a lexicographical comparison\n      return std::tie(this->instance_location, this->evaluate_path,\n                      this->schema_location.get()) <\n             std::tie(other.instance_location, other.evaluate_path,\n                      other.schema_location.get());\n    }\n\n    // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)\n    const sourcemeta::core::WeakPointer instance_location;\n    const sourcemeta::core::WeakPointer evaluate_path;\n    const std::reference_wrapper<const std::string> schema_location;\n    // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)\n  };\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  const sourcemeta::core::JSON &instance_;\n  const sourcemeta::core::WeakPointer base_;\n  container_type output;\n  std::vector<\n      std::pair<sourcemeta::core::WeakPointer, sourcemeta::core::WeakPointer>>\n      mask;\n  std::map<\n      std::pair<sourcemeta::core::WeakPointer, sourcemeta::core::WeakPointer>,\n      std::vector<Entry>>\n      masked_traces;\n  std::map<Location, std::vector<sourcemeta::core::JSON>> annotations_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n}; // namespace sourcemeta::blaze\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/output/include/sourcemeta/blaze/output_standard.h",
    "content": "#ifndef SOURCEMETA_BLAZE_OUTPUT_STANDARD_H_\n#define SOURCEMETA_BLAZE_OUTPUT_STANDARD_H_\n\n#ifndef SOURCEMETA_BLAZE_OUTPUT_EXPORT\n#include <sourcemeta/blaze/output_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <cstdint> // std::uint8_t\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup output\n/// Represents standard output formats\n/// See\n/// https://json-schema.org/draft/2020-12/json-schema-core#name-output-structure\n/// See\n/// https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.10\nenum class StandardOutput : std::uint8_t {\n  Flag,\n  Basic\n  // TODO: Implement the \"detailed\" and \"verbose\" output formats\n};\n\n// TODO: Integrate with\n// https://github.com/json-schema-org/JSON-Schema-Test-Suite/tree/main/output-tests\n\n/// @ingroup output\n/// Perform JSON Schema evaluation using Standard Output formats. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/compiler.h>\n/// #include <sourcemeta/blaze/evaluator.h>\n/// #include <sourcemeta/blaze/output.h>\n///\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// #include <cassert>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON schema =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\");\n///\n/// const auto schema_template{sourcemeta::blaze::compile(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver,\n///     sourcemeta::core::default_schema_compiler)};\n///\n/// const sourcemeta::core::JSON instance{\"foo bar\"};\n///\n/// sourcemeta::blaze::Evaluator evaluator;\n///\n/// const auto result{sourcemeta::blaze::standard(\n///   evaluator, schema_template, instance,\n///   sourcemeta::blaze::StandardOutput::Basic)};\n///\n/// assert(result.is_object());\n/// assert(result.defines(\"valid\"));\n/// assert(result.at(\"valid\").is_boolean());\n/// assert(result.at(\"valid\").to_boolean());\n///\n/// sourcemeta::core::prettify(result,\n///   std::cout, sourcemeta::blaze::standard_output_compare);\n/// std::cout << \"\\n\";\n/// ```\n///\n/// Note that this output format is not a class like the others\n/// in order to have additional control over how and whether to\n/// pass a callback to the evaluator instance.\nauto SOURCEMETA_BLAZE_OUTPUT_EXPORT\nstandard(Evaluator &evaluator, const Template &schema,\n         const sourcemeta::core::JSON &instance, const StandardOutput format)\n    -> sourcemeta::core::JSON;\n\n/// @ingroup output\n///\n/// An overload of the standard output function that includes line and column\n/// position information as an extension.\nauto SOURCEMETA_BLAZE_OUTPUT_EXPORT\nstandard(Evaluator &evaluator, const Template &schema,\n         const sourcemeta::core::JSON &instance, const StandardOutput format,\n         const sourcemeta::core::PointerPositionTracker &instanceTracker)\n    -> sourcemeta::core::JSON;\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/output/include/sourcemeta/blaze/output_trace.h",
    "content": "#ifndef SOURCEMETA_BLAZE_OUTPUT_TRACE_H_\n#define SOURCEMETA_BLAZE_OUTPUT_TRACE_H_\n\n#ifndef SOURCEMETA_BLAZE_OUTPUT_EXPORT\n#include <sourcemeta/blaze/output_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <cstdint>     // std::uint8_t\n#include <functional>  // std::function, std::reference_wrapper\n#include <optional>    // std::optional, std::nullopt\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup output\n///\n/// An evaluation callback that reports a trace of execution. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/compiler.h>\n/// #include <sourcemeta/blaze/evaluator.h>\n/// #include <sourcemeta/blaze/output.h>\n///\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// #include <cassert>\n/// #include <functional>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON schema =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"string\"\n/// })JSON\");\n///\n/// const auto schema_template{sourcemeta::blaze::compile(\n///     schema, sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver,\n///     sourcemeta::core::default_schema_compiler)};\n///\n/// const sourcemeta::core::JSON instance{5};\n///\n/// sourcemeta::blaze::TraceOutput output{\n///     sourcemeta::core::schema_walker,\n///     sourcemeta::core::schema_resolver,\n///     [](const sourcemeta::blaze::TraceOutput::Entry &entry) {\n///       std::cerr << entry.name << \"\\n\";\n///     }};\n/// sourcemeta::blaze::Evaluator evaluator;\n/// const auto result{evaluator.validate(\n///   schema_template, instance, std::ref(output))};\n/// ```\nclass SOURCEMETA_BLAZE_OUTPUT_EXPORT TraceOutput {\npublic:\n  enum class EntryType : std::uint8_t { Push, Pass, Fail, Annotation };\n\n  // NOLINTNEXTLINE(bugprone-exception-escape)\n  struct Entry {\n    // NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)\n    const EntryType type;\n    const std::string_view name;\n    const sourcemeta::core::WeakPointer &instance_location;\n    const sourcemeta::core::WeakPointer &evaluate_path;\n    const std::string_view keyword_location;\n    const sourcemeta::core::JSON &annotation;\n    const std::pair<bool, std::optional<sourcemeta::core::Vocabularies::URI>>\n        &vocabulary;\n    // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members)\n  };\n\n  // TODO(C++23): Use std::move_only_function when available in libc++\n  using Callback = std::function<void(const Entry &)>;\n\n  TraceOutput(\n      sourcemeta::core::SchemaWalker walker,\n      sourcemeta::core::SchemaResolver resolver, Callback callback,\n      sourcemeta::core::WeakPointer base = sourcemeta::core::empty_weak_pointer,\n      const std::optional<\n          std::reference_wrapper<const sourcemeta::core::SchemaFrame>> &frame =\n          std::nullopt);\n\n  // Prevent accidental copies\n  TraceOutput(const TraceOutput &) = delete;\n  auto operator=(const TraceOutput &) -> TraceOutput & = delete;\n\n  auto operator()(const EvaluationType type, const bool result,\n                  const Instruction &step,\n                  const InstructionExtra &step_metadata,\n                  const sourcemeta::core::WeakPointer &evaluate_path,\n                  const sourcemeta::core::WeakPointer &instance_location,\n                  const sourcemeta::core::JSON &annotation) -> void;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  const sourcemeta::core::SchemaWalker walker_;\n  const sourcemeta::core::SchemaResolver resolver_;\n  const sourcemeta::core::WeakPointer base_;\n  const std::optional<\n      std::reference_wrapper<const sourcemeta::core::SchemaFrame>>\n      frame_;\n  Callback callback_;\n  std::vector<\n      std::pair<bool, std::optional<sourcemeta::core::Vocabularies::URI>>>\n      vocabulary_stack_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/output/output_simple.cc",
    "content": "#include <sourcemeta/blaze/output_simple.h>\n\n#include <sourcemeta/core/jsonschema.h>\n\n#include <algorithm> // std::any_of, std::sort\n#include <cassert>   // assert\n#include <iterator>  // std::back_inserter, std::make_move_iterator\n#include <utility>   // std::move\n\nnamespace sourcemeta::blaze {\n\nSimpleOutput::SimpleOutput(const sourcemeta::core::JSON &instance,\n                           sourcemeta::core::WeakPointer base)\n    : instance_{instance}, base_{std::move(base)} {}\n\nauto SimpleOutput::begin() const -> const_iterator {\n  return this->output.begin();\n}\n\nauto SimpleOutput::end() const -> const_iterator { return this->output.end(); }\n\nauto SimpleOutput::cbegin() const -> const_iterator {\n  return this->output.cbegin();\n}\n\nauto SimpleOutput::cend() const -> const_iterator {\n  return this->output.cend();\n}\n\nauto SimpleOutput::operator()(\n    const EvaluationType type, const bool result, const Instruction &step,\n    const InstructionExtra &step_metadata,\n    const sourcemeta::core::WeakPointer &evaluate_path,\n    const sourcemeta::core::WeakPointer &instance_location,\n    const sourcemeta::core::JSON &annotation) -> void {\n  if (evaluate_path.empty()) {\n    return;\n  }\n\n  assert(evaluate_path.back().is_property());\n\n  // Fast path: passing non-annotation instructions that are not\n  // closing a mask entry can be skipped entirely\n  if (result && !is_annotation(step.type)) {\n    if (type == EvaluationType::Pre) {\n      const auto &keyword{evaluate_path.back().to_property()};\n      if (keyword == \"anyOf\" || keyword == \"oneOf\" || keyword == \"not\" ||\n          keyword == \"if\" || keyword == \"contains\") {\n        this->mask.emplace_back(evaluate_path, instance_location);\n      }\n    } else if (type == EvaluationType::Post && !this->mask.empty() &&\n               this->mask.back().first == evaluate_path &&\n               this->mask.back().second == instance_location) {\n      const auto mask_key{std::make_pair(evaluate_path, instance_location)};\n      this->masked_traces.erase(mask_key);\n      this->mask.pop_back();\n    }\n\n    return;\n  }\n\n  auto effective_evaluate_path{evaluate_path.resolve_from(this->base_)};\n  if (effective_evaluate_path.empty()) {\n    return;\n  }\n\n  if (is_annotation(step.type)) {\n    if (type == EvaluationType::Post) {\n      Location location{.instance_location = instance_location,\n                        .evaluate_path = std::move(effective_evaluate_path),\n                        .schema_location = step_metadata.keyword_location};\n      const auto match{this->annotations_.find(location)};\n      if (match == this->annotations_.cend()) {\n        this->annotations_[std::move(location)].push_back(annotation);\n\n        // To avoid emitting the exact same annotation more than once\n        // This is right now mostly because of `unevaluatedItems`\n      } else if (match->second.back() != annotation) {\n        match->second.push_back(annotation);\n      }\n    }\n\n    return;\n  }\n\n  const auto &keyword{evaluate_path.back().to_property()};\n\n  if (type == EvaluationType::Pre) {\n    assert(result);\n    // To ease the output\n    if (keyword == \"anyOf\" || keyword == \"oneOf\" || keyword == \"not\" ||\n        keyword == \"if\" || keyword == \"contains\") {\n      this->mask.emplace_back(evaluate_path, instance_location);\n    }\n  } else if (type == EvaluationType::Post) {\n    const auto mask_key{std::make_pair(evaluate_path, instance_location)};\n    const auto mask_it{std::ranges::find(this->mask, mask_key)};\n    if (mask_it != this->mask.end()) {\n      // Present unexpected traces only when needed\n      if (!result && keyword != \"not\" && keyword != \"if\") {\n        auto buffered{this->masked_traces.find(mask_key)};\n        if (buffered != this->masked_traces.end()) {\n#ifdef __cpp_lib_containers_ranges\n          this->output.append_range(std::move(buffered->second));\n#else\n          this->output.insert(this->output.end(),\n                              std::make_move_iterator(buffered->second.begin()),\n                              std::make_move_iterator(buffered->second.end()));\n#endif\n          this->masked_traces.erase(buffered);\n        }\n      } else {\n        this->masked_traces.erase(mask_key);\n      }\n\n      this->mask.erase(mask_it);\n    }\n  }\n\n  if (result) {\n    return;\n  }\n\n  if (type == EvaluationType::Post && !this->annotations_.empty()) {\n    for (auto iterator = this->annotations_.begin();\n         iterator != this->annotations_.end();) {\n      if (iterator->first.evaluate_path.starts_with_initial(evaluate_path) &&\n          iterator->first.instance_location == instance_location) {\n        iterator = this->annotations_.erase(iterator);\n      } else {\n        ++iterator;\n      }\n    }\n  }\n\n  if (keyword == \"if\") {\n    return;\n  } else {\n    for (const auto &mask_entry : this->mask) {\n      if (evaluate_path.starts_with(mask_entry.first)) {\n        this->masked_traces[mask_entry].push_back(\n            {describe(result, step, evaluate_path, instance_location,\n                      this->instance_, annotation),\n             instance_location, std::move(effective_evaluate_path),\n             step_metadata.keyword_location});\n\n        return;\n      }\n    }\n  }\n\n  this->output.push_back(\n      {describe(result, step, evaluate_path, instance_location, this->instance_,\n                annotation),\n       instance_location, std::move(effective_evaluate_path),\n       step_metadata.keyword_location});\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/output/output_standard.cc",
    "content": "#include <sourcemeta/blaze/output_simple.h>\n#include <sourcemeta/blaze/output_standard.h>\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <cassert>    // assert\n#include <functional> // std::ref\n\nnamespace sourcemeta::blaze {\n\nnamespace {\n\nauto handle_standard(Evaluator &evaluator, const Template &schema,\n                     const sourcemeta::core::JSON &instance,\n                     const StandardOutput format,\n                     const sourcemeta::core::PointerPositionTracker *tracker)\n    -> sourcemeta::core::JSON {\n  // We avoid a callback for this specific case for performance reasons\n  if (format == StandardOutput::Flag) {\n    auto result{sourcemeta::core::JSON::make_object()};\n    const auto valid{evaluator.validate(schema, instance)};\n    result.assign_assume_new(\"valid\", sourcemeta::core::JSON{valid});\n    return result;\n  } else {\n    assert(format == StandardOutput::Basic);\n    SimpleOutput output{instance};\n    const auto valid{evaluator.validate(schema, instance, std::ref(output))};\n\n    if (valid) {\n      auto result{sourcemeta::core::JSON::make_object()};\n      result.assign_assume_new(\"valid\", sourcemeta::core::JSON{valid});\n      auto annotations{sourcemeta::core::JSON::make_array()};\n      for (const auto &annotation : output.annotations()) {\n        auto unit{sourcemeta::core::JSON::make_object()};\n        unit.assign_assume_new(\n            \"keywordLocation\",\n            sourcemeta::core::JSON{\n                sourcemeta::core::to_string(annotation.first.evaluate_path)});\n        unit.assign_assume_new(\n            \"absoluteKeywordLocation\",\n            sourcemeta::core::JSON{annotation.first.schema_location});\n        unit.assign_assume_new(\n            \"instanceLocation\",\n            sourcemeta::core::JSON{sourcemeta::core::to_string(\n                annotation.first.instance_location)});\n\n        if (tracker != nullptr) {\n          const auto position{tracker->get(sourcemeta::core::to_pointer(\n              annotation.first.instance_location))};\n          if (position.has_value()) {\n            unit.assign_assume_new(\"instancePosition\",\n                                   sourcemeta::core::to_json(position.value()));\n          }\n        }\n\n        unit.assign_assume_new(\"annotation\",\n                               sourcemeta::core::to_json(annotation.second));\n        annotations.push_back(std::move(unit));\n      }\n\n      if (!annotations.empty()) {\n        result.assign_assume_new(\"annotations\", std::move(annotations));\n      }\n\n      return result;\n    } else {\n      auto result{sourcemeta::core::JSON::make_object()};\n      result.assign_assume_new(\"valid\", sourcemeta::core::JSON{valid});\n      auto errors{sourcemeta::core::JSON::make_array()};\n      for (const auto &entry : output) {\n        auto unit{sourcemeta::core::JSON::make_object()};\n        unit.assign_assume_new(\n            \"keywordLocation\",\n            sourcemeta::core::JSON{\n                sourcemeta::core::to_string(entry.evaluate_path)});\n        unit.assign_assume_new(\"absoluteKeywordLocation\",\n                               sourcemeta::core::JSON{entry.schema_location});\n        unit.assign_assume_new(\n            \"instanceLocation\",\n            sourcemeta::core::JSON{\n                sourcemeta::core::to_string(entry.instance_location)});\n\n        if (tracker != nullptr) {\n          const auto position{tracker->get(\n              sourcemeta::core::to_pointer(entry.instance_location))};\n          if (position.has_value()) {\n            unit.assign_assume_new(\"instancePosition\",\n                                   sourcemeta::core::to_json(position.value()));\n          }\n        }\n\n        unit.assign_assume_new(\"error\", sourcemeta::core::JSON{entry.message});\n        errors.push_back(std::move(unit));\n      }\n\n      assert(!errors.empty());\n      result.assign_assume_new(\"errors\", std::move(errors));\n      return result;\n    }\n  }\n}\n\n} // namespace\n\nauto standard(Evaluator &evaluator, const Template &schema,\n              const sourcemeta::core::JSON &instance,\n              const StandardOutput format) -> sourcemeta::core::JSON {\n  return handle_standard(evaluator, schema, instance, format, nullptr);\n}\n\nauto standard(Evaluator &evaluator, const Template &schema,\n              const sourcemeta::core::JSON &instance,\n              const StandardOutput format,\n              const sourcemeta::core::PointerPositionTracker &instanceTracker)\n    -> sourcemeta::core::JSON {\n  return handle_standard(evaluator, schema, instance, format, &instanceTracker);\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/output/output_trace.cc",
    "content": "#include <sourcemeta/blaze/output_trace.h>\n\n#include <sourcemeta/core/jsonschema.h>\n\n#include <utility> // std::move, std::to_underlying\n#include <variant> // std::visit\n\nstatic auto try_vocabulary(\n    const std::optional<\n        std::reference_wrapper<const sourcemeta::core::SchemaFrame>> &frame,\n    const sourcemeta::core::WeakPointer &evaluate_path,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver,\n    const std::string &keyword_location)\n    -> std::pair<bool, std::optional<sourcemeta::core::Vocabularies::URI>> {\n  if (!frame.has_value() || evaluate_path.empty() ||\n      !evaluate_path.back().is_property()) {\n    return {false, std::nullopt};\n  }\n\n  const auto entry{frame.value().get().traverse(keyword_location)};\n  if (!entry.has_value()) {\n    return {false, std::nullopt};\n  }\n\n  const auto vocabularies{\n      frame.value().get().vocabularies(entry.value().get(), resolver)};\n  const auto &result{walker(evaluate_path.back().to_property(), vocabularies)};\n  return {true, result.vocabulary};\n}\n\nnamespace sourcemeta::blaze {\n\nTraceOutput::TraceOutput(\n    sourcemeta::core::SchemaWalker walker,\n    sourcemeta::core::SchemaResolver resolver, Callback callback,\n    sourcemeta::core::WeakPointer base,\n    const std::optional<\n        std::reference_wrapper<const sourcemeta::core::SchemaFrame>> &frame)\n    : walker_{std::move(walker)}, resolver_{std::move(resolver)},\n      base_{std::move(base)}, frame_{frame}, callback_{std::move(callback)} {}\n\nauto TraceOutput::operator()(\n    const EvaluationType type, const bool result, const Instruction &step,\n    const InstructionExtra &step_metadata,\n    const sourcemeta::core::WeakPointer &evaluate_path,\n    const sourcemeta::core::WeakPointer &instance_location,\n    const sourcemeta::core::JSON &annotation) -> void {\n\n  const auto short_step_name{InstructionNames[std::to_underlying(step.type)]};\n\n  // Only resolve vocabulary on Pre callbacks and cache for Post\n  if (is_annotation(step.type)) {\n    if (type == EvaluationType::Pre) {\n      return;\n    }\n\n    auto vocabulary{try_vocabulary(this->frame_, evaluate_path, this->walker_,\n                                   this->resolver_,\n                                   step_metadata.keyword_location)};\n    this->vocabulary_stack_.push_back(std::move(vocabulary));\n  } else if (type == EvaluationType::Pre) {\n    this->vocabulary_stack_.push_back(\n        try_vocabulary(this->frame_, evaluate_path, this->walker_,\n                       this->resolver_, step_metadata.keyword_location));\n  }\n\n  const auto &vocabulary{this->vocabulary_stack_.back()};\n\n  // Determine the entry type\n  EntryType entry_type;\n  if (is_annotation(step.type)) {\n    entry_type = EntryType::Annotation;\n  } else if (type == EvaluationType::Pre) {\n    entry_type = EntryType::Push;\n  } else if (result) {\n    entry_type = EntryType::Pass;\n  } else {\n    entry_type = EntryType::Fail;\n  }\n\n  if (this->base_.empty()) {\n    const Entry entry{.type = entry_type,\n                      .name = short_step_name,\n                      .instance_location = instance_location,\n                      .evaluate_path = evaluate_path,\n                      .keyword_location = step_metadata.keyword_location,\n                      .annotation = annotation,\n                      .vocabulary = vocabulary};\n    this->callback_(entry);\n  } else {\n    auto effective_evaluate_path{evaluate_path.resolve_from(this->base_)};\n    const Entry entry{.type = entry_type,\n                      .name = short_step_name,\n                      .instance_location = instance_location,\n                      .evaluate_path = effective_evaluate_path,\n                      .keyword_location = step_metadata.keyword_location,\n                      .annotation = annotation,\n                      .vocabulary = vocabulary};\n    this->callback_(entry);\n  }\n\n  if (type == EvaluationType::Post || is_annotation(step.type)) {\n    this->vocabulary_stack_.pop_back();\n  }\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/test/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME test\n  FOLDER \"Blaze/Test\"\n  PRIVATE_HEADERS error.h\n  SOURCES test_parser.cc test_runner.cc)\n\nif(BLAZE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME test)\nendif()\n\ntarget_link_libraries(sourcemeta_blaze_test PRIVATE\n  sourcemeta::core::uri)\ntarget_link_libraries(sourcemeta_blaze_test PRIVATE\n  sourcemeta::core::io)\ntarget_link_libraries(sourcemeta_blaze_test PRIVATE\n  sourcemeta::core::yaml)\ntarget_link_libraries(sourcemeta_blaze_test PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_blaze_test PUBLIC\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_blaze_test PUBLIC\n  sourcemeta::core::jsonschema)\ntarget_link_libraries(sourcemeta_blaze_test PUBLIC\n  sourcemeta::blaze::compiler)\ntarget_link_libraries(sourcemeta_blaze_test PUBLIC\n  sourcemeta::blaze::evaluator)\n"
  },
  {
    "path": "vendor/blaze/src/test/include/sourcemeta/blaze/test.h",
    "content": "#ifndef SOURCEMETA_BLAZE_TEST_H_\n#define SOURCEMETA_BLAZE_TEST_H_\n\n#ifndef SOURCEMETA_BLAZE_TEST_EXPORT\n#include <sourcemeta/blaze/test_export.h>\n#endif\n\n#include <sourcemeta/blaze/test_error.h>\n\n#include <sourcemeta/blaze/compiler.h>\n#include <sourcemeta/blaze/evaluator.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <chrono>     // std::chrono::steady_clock\n#include <cstddef>    // std::size_t\n#include <filesystem> // std::filesystem\n#include <functional> // std::function\n#include <optional>   // std::optional\n#include <string>     // std::string\n#include <vector>     // std::vector\n\n/// @defgroup test Test\n/// @brief A JSON Schema test runner\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/blaze/test.h>\n/// ```\n\nnamespace sourcemeta::blaze {\n\n/// @ingroup test\n/// The monotonic timestamp type used for timing measurements\nusing TestTimestamp = std::chrono::steady_clock::time_point;\n\n/// @ingroup test\n/// Represents a single test case in a test suite\nstruct SOURCEMETA_BLAZE_TEST_EXPORT TestCase {\n// See\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4251?view=msvc-170\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  /// The optional description of the test case\n  sourcemeta::core::JSON::String description;\n  /// Whether the test data is expected to be valid against the schema\n  bool valid;\n  /// The test data to validate\n  sourcemeta::core::JSON data;\n  /// The position tracker for error reporting on the data\n  sourcemeta::core::PointerPositionTracker tracker;\n  /// The position of this test case in the test suite file\n  sourcemeta::core::PointerPositionTracker::Position position;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n\n  /// Parse a single test case\n  static auto\n  parse(const sourcemeta::core::JSON &test_case_json,\n        const sourcemeta::core::PointerPositionTracker &tracker,\n        const std::filesystem::path &base_path,\n        const sourcemeta::core::Pointer &location,\n        const sourcemeta::core::PointerPositionTracker::Position &position)\n      -> TestCase;\n};\n\n/// @ingroup test\n/// Represents a test suite containing multiple test cases\nstruct SOURCEMETA_BLAZE_TEST_EXPORT TestSuite {\n\n  /// The result of running a test suite\n  struct Result {\n    /// The total number of test cases\n    std::size_t total;\n    /// The number of test cases that passed\n    std::size_t passed;\n    /// The timestamp when the test suite started executing\n    TestTimestamp start;\n    /// The timestamp when the test suite finished executing\n    TestTimestamp end;\n  };\n\n// See\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4251?view=msvc-170\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  /// The target schema URIs or file paths\n  std::vector<sourcemeta::core::JSON::String> targets;\n  /// The list of test cases in the suite\n  std::vector<TestCase> tests;\n  /// The compiled schema templates for fast validation\n  std::vector<Template> schemas_fast;\n  /// The compiled schema templates for exhaustive validation\n  std::vector<Template> schemas_exhaustive;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n  /// The evaluator instance used for validation\n  Evaluator evaluator;\n\n  /// A callback invoked for each test case during execution\n  // TODO(C++23): Use std::move_only_function when available in libc++\n  using Callback = std::function<void(\n      const sourcemeta::core::JSON::String &target, std::size_t index,\n      std::size_t total, const TestCase &test_case, bool actual,\n      TestTimestamp start, TestTimestamp end)>;\n\n  /// Run all test cases in the suite, invoking the callback for each.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/blaze/test.h>\n  /// #include <sourcemeta/blaze/compiler.h>\n  ///\n  /// #include <sourcemeta/core/json.h>\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <sourcemeta/core/jsonschema.h>\n  ///\n  /// #include <iostream>\n  ///\n  /// const auto input{R\"JSON({\n  ///   \"target\": \"https://json-schema.org/draft/2020-12/schema\",\n  ///   \"tests\": [\n  ///     {\n  ///       \"data\": {\n  ///         \"$schema\": \"https://json-schema.org/draft/2020-12/schema\"\n  ///       },\n  ///       \"valid\": true,\n  ///       \"description\": \"valid schema\"\n  ///     }\n  ///   ]\n  /// })JSON\"};\n  ///\n  /// sourcemeta::core::PointerPositionTracker tracker;\n  /// const auto document{\n  ///     sourcemeta::core::parse_json(input, std::ref(tracker))};\n  ///\n  /// auto suite{sourcemeta::blaze::TestSuite::parse(\n  ///     document, tracker, std::filesystem::current_path(),\n  ///     sourcemeta::core::schema_resolver,\n  ///     sourcemeta::core::schema_walker,\n  ///     sourcemeta::blaze::default_schema_compiler)};\n  ///\n  /// const auto result{suite.run(\n  ///     [](const sourcemeta::core::JSON::String &target,\n  ///        std::size_t index, std::size_t total,\n  ///        const sourcemeta::blaze::TestCase &test_case, bool actual,\n  ///        sourcemeta::blaze::TestTimestamp start,\n  ///        sourcemeta::blaze::TestTimestamp end) {\n  ///       std::cout << target << \" \" << index << \"/\" << total << \": \"\n  ///                 << test_case.description << \" - \"\n  ///                 << (test_case.valid == actual ? \"PASS\" : \"FAIL\")\n  ///                 << \"\\n\";\n  ///     })};\n  ///\n  /// std::cout << result.passed << \"/\" << result.total << \" passed\\n\";\n  /// ```\n  auto run(const Callback &callback) -> Result;\n\n  /// Parse a test suite from a JSON object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/blaze/test.h>\n  /// #include <sourcemeta/blaze/compiler.h>\n  ///\n  /// #include <sourcemeta/core/json.h>\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <sourcemeta/core/jsonschema.h>\n  ///\n  /// #include <cassert>\n  ///\n  /// const auto input{R\"JSON({\n  ///   \"target\": \"https://json-schema.org/draft/2020-12/schema\",\n  ///   \"tests\": [\n  ///     { \"data\": {}, \"valid\": true },\n  ///     { \"data\": [], \"valid\": false, \"description\": \"Not an object\" }\n  ///   ]\n  /// })JSON\"};\n  ///\n  /// sourcemeta::core::PointerPositionTracker tracker;\n  /// const auto document{\n  ///     sourcemeta::core::parse_json(input, std::ref(tracker))};\n  ///\n  /// const auto suite{sourcemeta::blaze::TestSuite::parse(\n  ///     document, tracker, std::filesystem::current_path(),\n  ///     sourcemeta::core::schema_resolver,\n  ///     sourcemeta::core::schema_walker,\n  ///     sourcemeta::blaze::default_schema_compiler)};\n  ///\n  /// assert(suite.targets.size() == 1);\n  /// assert(suite.targets.front() ==\n  ///   \"https://json-schema.org/draft/2020-12/schema\");\n  /// assert(suite.tests.size() == 2);\n  /// ```\n  static auto\n  parse(const sourcemeta::core::JSON &document,\n        const sourcemeta::core::PointerPositionTracker &tracker,\n        const std::filesystem::path &base_path,\n        const sourcemeta::core::SchemaResolver &schema_resolver,\n        const sourcemeta::core::SchemaWalker &walker, const Compiler &compiler,\n        std::string_view default_dialect = \"\", std::string_view default_id = \"\",\n        const std::optional<Tweaks> &tweaks = std::nullopt) -> TestSuite;\n};\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/test/include/sourcemeta/blaze/test_error.h",
    "content": "#ifndef SOURCEMETA_BLAZE_TEST_ERROR_H_\n#define SOURCEMETA_BLAZE_TEST_ERROR_H_\n\n#ifndef SOURCEMETA_BLAZE_TEST_EXPORT\n#include <sourcemeta/blaze/test_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <cstdint>     // std::uint64_t\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::blaze {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup test\n/// An error that occurs when parsing a test file\nclass SOURCEMETA_BLAZE_TEST_EXPORT TestParseError : public std::exception {\npublic:\n  TestParseError(const char *message, sourcemeta::core::Pointer location,\n                 std::uint64_t line, std::uint64_t column)\n      : message_{message}, location_{std::move(location)}, line_{line},\n        column_{column} {}\n  TestParseError(std::string message, sourcemeta::core::Pointer location,\n                 std::uint64_t line, std::uint64_t column) = delete;\n  TestParseError(std::string &&message, sourcemeta::core::Pointer location,\n                 std::uint64_t line, std::uint64_t column) = delete;\n  TestParseError(std::string_view message, sourcemeta::core::Pointer location,\n                 std::uint64_t line, std::uint64_t column) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto location() const noexcept\n      -> const sourcemeta::core::Pointer & {\n    return this->location_;\n  }\n\n  [[nodiscard]] auto line() const noexcept -> std::uint64_t {\n    return this->line_;\n  }\n\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  const char *message_;\n  sourcemeta::core::Pointer location_;\n  std::uint64_t line_;\n  std::uint64_t column_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::blaze\n\n#endif\n"
  },
  {
    "path": "vendor/blaze/src/test/test_parser.cc",
    "content": "#include <sourcemeta/blaze/test.h>\n\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/uri.h>\n#include <sourcemeta/core/yaml.h>\n\n#include <cassert>     // assert\n#include <string_view> // std::string_view\n#include <tuple>       // std::get\n#include <utility>     // std::move\n\nnamespace {\ninline auto TEST_ERROR_IF(\n    bool condition, const sourcemeta::core::PointerPositionTracker &tracker,\n    const sourcemeta::core::Pointer &pointer, const char *message) -> void {\n  if (condition) [[unlikely]] {\n    const auto position{tracker.get(pointer)};\n    assert(position.has_value());\n    throw sourcemeta::blaze::TestParseError{message, pointer,\n                                            std::get<0>(position.value()),\n                                            std::get<1>(position.value())};\n  }\n}\n} // namespace\n\nnamespace sourcemeta::blaze {\n\nauto TestCase::parse(\n    const sourcemeta::core::JSON &test_case_json,\n    const sourcemeta::core::PointerPositionTracker &tracker,\n    const std::filesystem::path &base_path,\n    const sourcemeta::core::Pointer &location,\n    const sourcemeta::core::PointerPositionTracker::Position &position)\n    -> TestCase {\n  TEST_ERROR_IF(!test_case_json.is_object(), tracker, location,\n                \"Test case documents must be objects\");\n  TEST_ERROR_IF(!test_case_json.defines(\"data\") &&\n                    !test_case_json.defines(\"dataPath\"),\n                tracker, location,\n                \"Test case documents must contain a `data` or `dataPath` \"\n                \"property\");\n  TEST_ERROR_IF(test_case_json.defines(\"data\") &&\n                    test_case_json.defines(\"dataPath\"),\n                tracker, location,\n                \"Test case documents must contain either a `data` or \"\n                \"`dataPath` property, but not both\");\n  TEST_ERROR_IF(test_case_json.defines(\"dataPath\") &&\n                    !test_case_json.at(\"dataPath\").is_string(),\n                tracker, location.concat({\"dataPath\"}),\n                \"Test case documents must set the `dataPath` property to a \"\n                \"string\");\n  TEST_ERROR_IF(test_case_json.defines(\"description\") &&\n                    !test_case_json.at(\"description\").is_string(),\n                tracker, location.concat({\"description\"}),\n                \"If you set a test case description, it must be a string\");\n  TEST_ERROR_IF(!test_case_json.defines(\"valid\"), tracker, location,\n                \"Test case documents must contain a `valid` property\");\n  TEST_ERROR_IF(!test_case_json.at(\"valid\").is_boolean(), tracker,\n                location.concat({\"valid\"}),\n                \"The test case document `valid` property must be a boolean\");\n\n  sourcemeta::core::JSON::String description;\n  if (test_case_json.defines(\"description\")) {\n    description = test_case_json.at(\"description\").to_string();\n  }\n\n  sourcemeta::core::PointerPositionTracker data_tracker;\n\n  if (test_case_json.defines(\"data\")) {\n    return TestCase{.description = std::move(description),\n                    .valid = test_case_json.at(\"valid\").to_boolean(),\n                    .data = test_case_json.at(\"data\"),\n                    .tracker = std::move(data_tracker),\n                    .position = position};\n  } else {\n    const std::filesystem::path data_path{sourcemeta::core::weakly_canonical(\n        base_path / test_case_json.at(\"dataPath\").to_string())};\n    sourcemeta::core::JSON data{nullptr};\n    sourcemeta::core::read_yaml_or_json(data_path, data,\n                                        std::ref(data_tracker));\n    return TestCase{.description = std::move(description),\n                    .valid = test_case_json.at(\"valid\").to_boolean(),\n                    .data = std::move(data),\n                    .tracker = std::move(data_tracker),\n                    .position = position};\n  }\n}\n\nauto TestSuite::parse(const sourcemeta::core::JSON &document,\n                      const sourcemeta::core::PointerPositionTracker &tracker,\n                      const std::filesystem::path &base_path,\n                      const sourcemeta::core::SchemaResolver &schema_resolver,\n                      const sourcemeta::core::SchemaWalker &walker,\n                      const Compiler &compiler,\n                      const std::string_view default_dialect,\n                      const std::string_view default_id,\n                      const std::optional<Tweaks> &tweaks) -> TestSuite {\n  assert(std::filesystem::is_directory(base_path));\n  TEST_ERROR_IF(!document.is_object(), tracker, sourcemeta::core::empty_pointer,\n                \"The test document must be an object\");\n  TEST_ERROR_IF(!document.defines(\"target\"), tracker,\n                sourcemeta::core::empty_pointer,\n                \"The test document must contain a `target` property\");\n  TEST_ERROR_IF(!document.at(\"target\").is_string() &&\n                    !document.at(\"target\").is_array(),\n                tracker, sourcemeta::core::Pointer{\"target\"},\n                \"The test document `target` property must be a URI or an \"\n                \"array of URIs\");\n  TEST_ERROR_IF(!document.defines(\"tests\"), tracker,\n                sourcemeta::core::empty_pointer,\n                \"The test document must contain a `tests` property\");\n  TEST_ERROR_IF(!document.at(\"tests\").is_array(), tracker,\n                sourcemeta::core::Pointer{\"tests\"},\n                \"The test document `tests` property must be an array\");\n\n  const auto base_path_uri{\n      sourcemeta::core::URI::from_path(base_path / \"test.json\")};\n\n  TestSuite test_suite;\n\n  if (document.at(\"target\").is_string()) {\n    sourcemeta::core::URI schema_uri{document.at(\"target\").to_string()};\n    schema_uri.resolve_from(base_path_uri);\n    schema_uri.canonicalize();\n    test_suite.targets.push_back(schema_uri.recompose());\n  } else {\n    TEST_ERROR_IF(document.at(\"target\").empty(), tracker,\n                  sourcemeta::core::Pointer{\"target\"},\n                  \"The test document `target` array must contain at least \"\n                  \"one URI\");\n    // TODO(C++23): Use std::views::enumerate when available in libc++\n    std::size_t target_index{0};\n    for (const auto &target_entry : document.at(\"target\").as_array()) {\n      const sourcemeta::core::Pointer target_location{\"target\", target_index};\n      TEST_ERROR_IF(!target_entry.is_string(), tracker, target_location,\n                    \"Each entry in the test document `target` array must be \"\n                    \"a URI\");\n      sourcemeta::core::URI schema_uri{target_entry.to_string()};\n      schema_uri.resolve_from(base_path_uri);\n      schema_uri.canonicalize();\n      test_suite.targets.push_back(schema_uri.recompose());\n      target_index += 1;\n    }\n  }\n\n  // TODO(C++23): Use std::views::enumerate when available in libc++\n  std::size_t index{0};\n  for (const auto &test_case_json : document.at(\"tests\").as_array()) {\n    const sourcemeta::core::Pointer location{\"tests\", index};\n    const auto position{tracker.get(location)};\n    assert(position.has_value());\n    test_suite.tests.push_back(TestCase::parse(\n        test_case_json, tracker, base_path, location, position.value()));\n    index += 1;\n  }\n\n  test_suite.schemas_fast.reserve(test_suite.targets.size());\n  test_suite.schemas_exhaustive.reserve(test_suite.targets.size());\n\n  for (const auto &target : test_suite.targets) {\n    const auto target_schema{sourcemeta::core::wrap(target)};\n\n    try {\n      test_suite.schemas_fast.push_back(compile(\n          target_schema, walker, schema_resolver, compiler,\n          Mode::FastValidation, default_dialect, default_id, \"\", tweaks));\n      test_suite.schemas_exhaustive.push_back(\n          compile(target_schema, walker, schema_resolver, compiler,\n                  Mode::Exhaustive, default_dialect, default_id, \"\", tweaks));\n    } catch (const sourcemeta::core::SchemaReferenceError &error) {\n      if (error.location() == sourcemeta::core::Pointer{\"$ref\"} &&\n          error.identifier() == target) {\n        throw sourcemeta::core::SchemaResolutionError{\n            target, \"Could not resolve schema under test\"};\n      }\n\n      throw;\n    }\n  }\n\n  return test_suite;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/blaze/src/test/test_runner.cc",
    "content": "#include <sourcemeta/blaze/test.h>\n\n#include <chrono> // std::chrono::steady_clock\n\nnamespace sourcemeta::blaze {\n\nauto TestSuite::run(const Callback &callback) -> Result {\n  const auto total{this->targets.size() * this->tests.size()};\n  Result result{.total = total,\n                .passed = 0,\n                .start = std::chrono::steady_clock::now(),\n                .end = {}};\n\n  std::size_t step{0};\n  for (std::size_t target_index = 0; target_index < this->targets.size();\n       ++target_index) {\n    const auto &target = this->targets[target_index];\n    const auto &schema_fast = this->schemas_fast[target_index];\n    for (const auto &test_case : this->tests) {\n      const auto start{std::chrono::steady_clock::now()};\n      const auto actual{this->evaluator.validate(schema_fast, test_case.data)};\n      const auto end{std::chrono::steady_clock::now()};\n      step += 1;\n      callback(target, step, total, test_case, actual, start, end);\n      if (test_case.valid == actual) {\n        result.passed += 1;\n      }\n    }\n  }\n\n  result.end = std::chrono::steady_clock::now();\n  return result;\n}\n\n} // namespace sourcemeta::blaze\n"
  },
  {
    "path": "vendor/bootstrap/scss/_accordion.scss",
    "content": "//\n// Base styles\n//\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: $accordion-button-padding-y $accordion-button-padding-x;\n  @include font-size($font-size-base);\n  color: $accordion-button-color;\n  text-align: left; // Reset button style\n  background-color: $accordion-button-bg;\n  border: 0;\n  @include border-radius(0);\n  overflow-anchor: none;\n  @include transition($accordion-transition);\n\n  &:not(.collapsed) {\n    color: $accordion-button-active-color;\n    background-color: $accordion-button-active-bg;\n    box-shadow: inset 0 ($accordion-border-width * -1) 0 $accordion-border-color;\n\n    &::after {\n      background-image: escape-svg($accordion-button-active-icon);\n      transform: $accordion-icon-transform;\n    }\n  }\n\n  // Accordion icon\n  &::after {\n    flex-shrink: 0;\n    width: $accordion-icon-width;\n    height: $accordion-icon-width;\n    margin-left: auto;\n    content: \"\";\n    background-image: escape-svg($accordion-button-icon);\n    background-repeat: no-repeat;\n    background-size: $accordion-icon-width;\n    @include transition($accordion-icon-transition);\n  }\n\n  &:hover {\n    z-index: 2;\n  }\n\n  &:focus {\n    z-index: 3;\n    border-color: $accordion-button-focus-border-color;\n    outline: 0;\n    box-shadow: $accordion-button-focus-box-shadow;\n  }\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  background-color: $accordion-bg;\n  border: $accordion-border-width solid $accordion-border-color;\n\n  &:first-of-type {\n    @include border-top-radius($accordion-border-radius);\n\n    .accordion-button {\n      @include border-top-radius($accordion-inner-border-radius);\n    }\n  }\n\n  &:not(:first-of-type) {\n    border-top: 0;\n  }\n\n  // Only set a border-radius on the last item if the accordion is collapsed\n  &:last-of-type {\n    @include border-bottom-radius($accordion-border-radius);\n\n    .accordion-button {\n      &.collapsed {\n        @include border-bottom-radius($accordion-inner-border-radius);\n      }\n    }\n\n    .accordion-collapse {\n      @include border-bottom-radius($accordion-border-radius);\n    }\n  }\n}\n\n.accordion-body {\n  padding: $accordion-body-padding-y $accordion-body-padding-x;\n}\n\n\n// Flush accordion items\n//\n// Remove borders and border-radius to keep accordion items edge-to-edge.\n\n.accordion-flush {\n  .accordion-collapse {\n    border-width: 0;\n  }\n\n  .accordion-item {\n    border-right: 0;\n    border-left: 0;\n    @include border-radius(0);\n\n    &:first-child { border-top: 0; }\n    &:last-child { border-bottom: 0; }\n\n    .accordion-button {\n      @include border-radius(0);\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_alert.scss",
    "content": "//\n// Base styles\n//\n\n.alert {\n  position: relative;\n  padding: $alert-padding-y $alert-padding-x;\n  margin-bottom: $alert-margin-bottom;\n  border: $alert-border-width solid transparent;\n  @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n  // Specified to prevent conflicts of changing $headings-color\n  color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n  font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n  padding-right: $alert-dismissible-padding-r;\n\n  // Adjust close link position\n  .btn-close {\n    position: absolute;\n    top: 0;\n    right: 0;\n    z-index: $stretched-link-z-index + 1;\n    padding: $alert-padding-y * 1.25 $alert-padding-x;\n  }\n}\n\n\n// scss-docs-start alert-modifiers\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $state, $value in $theme-colors {\n  $alert-background: shift-color($value, $alert-bg-scale);\n  $alert-border: shift-color($value, $alert-border-scale);\n  $alert-color: shift-color($value, $alert-color-scale);\n  @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {\n    $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));\n  }\n  .alert-#{$state} {\n    @include alert-variant($alert-background, $alert-border, $alert-color);\n  }\n}\n// scss-docs-end alert-modifiers\n"
  },
  {
    "path": "vendor/bootstrap/scss/_badge.scss",
    "content": "// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n  display: inline-block;\n  padding: $badge-padding-y $badge-padding-x;\n  @include font-size($badge-font-size);\n  font-weight: $badge-font-weight;\n  line-height: 1;\n  color: $badge-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  @include border-radius($badge-border-radius);\n  @include gradient-bg();\n\n  // Empty badges collapse automatically\n  &:empty {\n    display: none;\n  }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_breadcrumb.scss",
    "content": ".breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n  margin-bottom: $breadcrumb-margin-bottom;\n  @include font-size($breadcrumb-font-size);\n  list-style: none;\n  background-color: $breadcrumb-bg;\n  @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n  // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n  + .breadcrumb-item {\n    padding-left: $breadcrumb-item-padding-x;\n\n    &::before {\n      float: left; // Suppress inline spacings and underlining of the separator\n      padding-right: $breadcrumb-item-padding-x;\n      color: $breadcrumb-divider-color;\n      content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{\"/* rtl:\"} var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{\"*/\"};\n    }\n  }\n\n  &.active {\n    color: $breadcrumb-active-color;\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_button-group.scss",
    "content": "// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n\n  > .btn {\n    position: relative;\n    flex: 1 1 auto;\n  }\n\n  // Bring the hover, focused, and \"active\" buttons to the front to overlay\n  // the borders properly\n  > .btn-check:checked + .btn,\n  > .btn-check:focus + .btn,\n  > .btn:hover,\n  > .btn:focus,\n  > .btn:active,\n  > .btn.active {\n    z-index: 1;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n\n  .input-group {\n    width: auto;\n  }\n}\n\n.btn-group {\n  // Prevent double borders when buttons are next to each other\n  > .btn:not(:first-child),\n  > .btn-group:not(:first-child) {\n    margin-left: -$btn-border-width;\n  }\n\n  // Reset rounded corners\n  > .btn:not(:last-child):not(.dropdown-toggle),\n  > .btn-group:not(:last-child) > .btn {\n    @include border-end-radius(0);\n  }\n\n  // The left radius should be 0 if the button is:\n  // - the \"third or more\" child\n  // - the second child and the previous element isn't `.btn-check` (making it the first child visually)\n  // - part of a btn-group which isn't the first child\n  > .btn:nth-child(n + 3),\n  > :not(.btn-check) + .btn,\n  > .btn-group:not(:first-child) > .btn {\n    @include border-start-radius(0);\n  }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n  padding-right: $btn-padding-x * .75;\n  padding-left: $btn-padding-x * .75;\n\n  &::after,\n  .dropup &::after,\n  .dropend &::after {\n    margin-left: 0;\n  }\n\n  .dropstart &::before {\n    margin-right: 0;\n  }\n}\n\n.btn-sm + .dropdown-toggle-split {\n  padding-right: $btn-padding-x-sm * .75;\n  padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n  padding-right: $btn-padding-x-lg * .75;\n  padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n  @include box-shadow($btn-active-box-shadow);\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    @include box-shadow(none);\n  }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n\n  > .btn,\n  > .btn-group {\n    width: 100%;\n  }\n\n  > .btn:not(:first-child),\n  > .btn-group:not(:first-child) {\n    margin-top: -$btn-border-width;\n  }\n\n  // Reset rounded corners\n  > .btn:not(:last-child):not(.dropdown-toggle),\n  > .btn-group:not(:last-child) > .btn {\n    @include border-bottom-radius(0);\n  }\n\n  > .btn ~ .btn,\n  > .btn-group:not(:first-child) > .btn {\n    @include border-top-radius(0);\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_buttons.scss",
    "content": "//\n// Base styles\n//\n\n.btn {\n  display: inline-block;\n  font-family: $btn-font-family;\n  font-weight: $btn-font-weight;\n  line-height: $btn-line-height;\n  color: $body-color;\n  text-align: center;\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: $btn-white-space;\n  vertical-align: middle;\n  cursor: if($enable-button-pointers, pointer, null);\n  user-select: none;\n  background-color: transparent;\n  border: $btn-border-width solid transparent;\n  @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius);\n  @include transition($btn-transition);\n\n  &:hover {\n    color: $body-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    outline: 0;\n    box-shadow: $btn-focus-box-shadow;\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active {\n    @include box-shadow($btn-active-box-shadow);\n\n    &:focus {\n      @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n    }\n  }\n\n  &:disabled,\n  &.disabled,\n  fieldset:disabled & {\n    pointer-events: none;\n    opacity: $btn-disabled-opacity;\n    @include box-shadow(none);\n  }\n}\n\n\n//\n// Alternate buttons\n//\n\n// scss-docs-start btn-variant-loops\n@each $color, $value in $theme-colors {\n  .btn-#{$color} {\n    @include button-variant($value, $value);\n  }\n}\n\n@each $color, $value in $theme-colors {\n  .btn-outline-#{$color} {\n    @include button-outline-variant($value);\n  }\n}\n// scss-docs-end btn-variant-loops\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n  font-weight: $font-weight-normal;\n  color: $btn-link-color;\n  text-decoration: $link-decoration;\n\n  &:hover {\n    color: $btn-link-hover-color;\n    text-decoration: $link-hover-decoration;\n  }\n\n  &:focus {\n    text-decoration: $link-hover-decoration;\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $btn-link-disabled-color;\n  }\n\n  // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n  @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n  @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_card.scss",
    "content": "//\n// Base styles\n//\n\n.card {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n  height: $card-height;\n  word-wrap: break-word;\n  background-color: $card-bg;\n  background-clip: border-box;\n  border: $card-border-width solid $card-border-color;\n  @include border-radius($card-border-radius);\n  @include box-shadow($card-box-shadow);\n\n  > hr {\n    margin-right: 0;\n    margin-left: 0;\n  }\n\n  > .list-group {\n    border-top: inherit;\n    border-bottom: inherit;\n\n    &:first-child {\n      border-top-width: 0;\n      @include border-top-radius($card-inner-border-radius);\n    }\n\n    &:last-child  {\n      border-bottom-width: 0;\n      @include border-bottom-radius($card-inner-border-radius);\n    }\n  }\n\n  // Due to specificity of the above selector (`.card > .list-group`), we must\n  // use a child selector here to prevent double borders.\n  > .card-header + .list-group,\n  > .list-group + .card-footer {\n    border-top: 0;\n  }\n}\n\n.card-body {\n  // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n  // as much space as possible, ensuring footers are aligned to the bottom.\n  flex: 1 1 auto;\n  padding: $card-spacer-y $card-spacer-x;\n  color: $card-color;\n}\n\n.card-title {\n  margin-bottom: $card-title-spacer-y;\n}\n\n.card-subtitle {\n  margin-top: -$card-title-spacer-y * .5;\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link {\n  &:hover {\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  + .card-link {\n    margin-left: $card-spacer-x;\n  }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n  padding: $card-cap-padding-y $card-cap-padding-x;\n  margin-bottom: 0; // Removes the default margin-bottom of <hN>\n  color: $card-cap-color;\n  background-color: $card-cap-bg;\n  border-bottom: $card-border-width solid $card-border-color;\n\n  &:first-child {\n    @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n  }\n}\n\n.card-footer {\n  padding: $card-cap-padding-y $card-cap-padding-x;\n  color: $card-cap-color;\n  background-color: $card-cap-bg;\n  border-top: $card-border-width solid $card-border-color;\n\n  &:last-child {\n    @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n  }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n  margin-right: -$card-cap-padding-x * .5;\n  margin-bottom: -$card-cap-padding-y;\n  margin-left: -$card-cap-padding-x * .5;\n  border-bottom: 0;\n\n  @if $nav-tabs-link-active-bg != $card-bg {\n    .nav-link.active {\n      background-color: $card-bg;\n      border-bottom-color: $card-bg;\n    }\n  }\n}\n\n.card-header-pills {\n  margin-right: -$card-cap-padding-x * .5;\n  margin-left: -$card-cap-padding-x * .5;\n}\n\n// Card image\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: $card-img-overlay-padding;\n  @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n  @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n  @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n  // The child selector allows nested `.card` within `.card-group`\n  // to display properly.\n  > .card {\n    margin-bottom: $card-group-margin;\n  }\n\n  @include media-breakpoint-up(sm) {\n    display: flex;\n    flex-flow: row wrap;\n    // The child selector allows nested `.card` within `.card-group`\n    // to display properly.\n    > .card {\n      // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n      flex: 1 0 0%;\n      margin-bottom: 0;\n\n      + .card {\n        margin-left: 0;\n        border-left: 0;\n      }\n\n      // Handle rounded corners\n      @if $enable-rounded {\n        &:not(:last-child) {\n          @include border-end-radius(0);\n\n          .card-img-top,\n          .card-header {\n            // stylelint-disable-next-line property-disallowed-list\n            border-top-right-radius: 0;\n          }\n          .card-img-bottom,\n          .card-footer {\n            // stylelint-disable-next-line property-disallowed-list\n            border-bottom-right-radius: 0;\n          }\n        }\n\n        &:not(:first-child) {\n          @include border-start-radius(0);\n\n          .card-img-top,\n          .card-header {\n            // stylelint-disable-next-line property-disallowed-list\n            border-top-left-radius: 0;\n          }\n          .card-img-bottom,\n          .card-footer {\n            // stylelint-disable-next-line property-disallowed-list\n            border-bottom-left-radius: 0;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_carousel.scss",
    "content": "// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n//    even when their scroll action started on a carousel, but for compatibility (with Firefox)\n//    we're preventing all actions instead\n// 2. The .carousel-item-start and .carousel-item-end is used to indicate where\n//    the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-start and .active.carousel-item-end is the current\n//    slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end\n//    is the upcoming slide in transition.\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n  @include clearfix();\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: left;\n  width: 100%;\n  margin-right: -100%;\n  backface-visibility: hidden;\n  @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n\n/* rtl:begin:ignore */\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n\n/* rtl:end:ignore */\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n  .carousel-item {\n    opacity: 0;\n    transition-property: opacity;\n    transform: none;\n  }\n\n  .carousel-item.active,\n  .carousel-item-next.carousel-item-start,\n  .carousel-item-prev.carousel-item-end {\n    z-index: 1;\n    opacity: 1;\n  }\n\n  .active.carousel-item-start,\n  .active.carousel-item-end {\n    z-index: 0;\n    opacity: 0;\n    @include transition(opacity 0s $carousel-transition-duration);\n  }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  // Use flex for alignment (1-3)\n  display: flex; // 1. allow flex styles\n  align-items: center; // 2. vertically center contents\n  justify-content: center; // 3. horizontally center contents\n  width: $carousel-control-width;\n  padding: 0;\n  color: $carousel-control-color;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: $carousel-control-opacity;\n  @include transition($carousel-control-transition);\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    color: $carousel-control-color;\n    text-decoration: none;\n    outline: 0;\n    opacity: $carousel-control-hover-opacity;\n  }\n}\n.carousel-control-prev {\n  left: 0;\n  background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);\n}\n.carousel-control-next {\n  right: 0;\n  background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: $carousel-control-icon-width;\n  height: $carousel-control-icon-width;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n\n/* rtl:options: {\n  \"autoRename\": true,\n  \"stringMap\":[ {\n    \"name\"    : \"prev-next\",\n    \"search\"  : \"prev\",\n    \"replace\" : \"next\"\n  } ]\n} */\n.carousel-control-prev-icon {\n  background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n  background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n// Optional indicator pips/controls\n//\n// Add a container (such as a list) with the following class and add an item (ideally a focusable control,\n// like a button) with data-bs-target for each slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  // Use the .carousel-control's width as margin so we don't overlay those\n  margin-right: $carousel-control-width;\n  margin-bottom: 1rem;\n  margin-left: $carousel-control-width;\n  list-style: none;\n\n  [data-bs-target] {\n    box-sizing: content-box;\n    flex: 0 1 auto;\n    width: $carousel-indicator-width;\n    height: $carousel-indicator-height;\n    padding: 0;\n    margin-right: $carousel-indicator-spacer;\n    margin-left: $carousel-indicator-spacer;\n    text-indent: -999px;\n    cursor: pointer;\n    background-color: $carousel-indicator-active-bg;\n    background-clip: padding-box;\n    border: 0;\n    // Use transparent borders to increase the hit area by 10px on top and bottom.\n    border-top: $carousel-indicator-hit-area-height solid transparent;\n    border-bottom: $carousel-indicator-hit-area-height solid transparent;\n    opacity: $carousel-indicator-opacity;\n    @include transition($carousel-indicator-transition);\n  }\n\n  .active {\n    opacity: $carousel-indicator-active-opacity;\n  }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n  position: absolute;\n  right: (100% - $carousel-caption-width) * .5;\n  bottom: $carousel-caption-spacer;\n  left: (100% - $carousel-caption-width) * .5;\n  padding-top: $carousel-caption-padding-y;\n  padding-bottom: $carousel-caption-padding-y;\n  color: $carousel-caption-color;\n  text-align: center;\n}\n\n// Dark mode carousel\n\n.carousel-dark {\n  .carousel-control-prev-icon,\n  .carousel-control-next-icon {\n    filter: $carousel-dark-control-icon-filter;\n  }\n\n  .carousel-indicators [data-bs-target] {\n    background-color: $carousel-dark-indicator-active-bg;\n  }\n\n  .carousel-caption {\n    color: $carousel-dark-caption-color;\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_close.scss",
    "content": "// transparent background and border properties included for button version.\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n.btn-close {\n  box-sizing: content-box;\n  width: $btn-close-width;\n  height: $btn-close-height;\n  padding: $btn-close-padding-y $btn-close-padding-x;\n  color: $btn-close-color;\n  background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements\n  border: 0; // for button elements\n  @include border-radius();\n  opacity: $btn-close-opacity;\n\n  // Override <a>'s hover style\n  &:hover {\n    color: $btn-close-color;\n    text-decoration: none;\n    opacity: $btn-close-hover-opacity;\n  }\n\n  &:focus {\n    outline: 0;\n    box-shadow: $btn-close-focus-shadow;\n    opacity: $btn-close-focus-opacity;\n  }\n\n  &:disabled,\n  &.disabled {\n    pointer-events: none;\n    user-select: none;\n    opacity: $btn-close-disabled-opacity;\n  }\n}\n\n.btn-close-white {\n  filter: $btn-close-white-filter;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_containers.scss",
    "content": "// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n  // Single container class with breakpoint max-widths\n  .container,\n  // 100% wide container at all breakpoints\n  .container-fluid {\n    @include make-container();\n  }\n\n  // Responsive containers that are 100% wide until a breakpoint\n  @each $breakpoint, $container-max-width in $container-max-widths {\n    .container-#{$breakpoint} {\n      @extend .container-fluid;\n    }\n\n    @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n      %responsive-container-#{$breakpoint} {\n        max-width: $container-max-width;\n      }\n\n      // Extend each breakpoint which is smaller or equal to the current breakpoint\n      $extend-breakpoint: true;\n\n      @each $name, $width in $grid-breakpoints {\n        @if ($extend-breakpoint) {\n          .container#{breakpoint-infix($name, $grid-breakpoints)} {\n            @extend %responsive-container-#{$breakpoint};\n          }\n\n          // Once the current breakpoint is reached, stop extending\n          @if ($breakpoint == $name) {\n            $extend-breakpoint: false;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_dropdown.scss",
    "content": "// The dropdown wrapper (`<div>`)\n.dropup,\n.dropend,\n.dropdown,\n.dropstart {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n\n  // Generate the caret automatically\n  @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n  position: absolute;\n  z-index: $zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  min-width: $dropdown-min-width;\n  padding: $dropdown-padding-y $dropdown-padding-x;\n  margin: 0; // Override default margin of ul\n  @include font-size($dropdown-font-size);\n  color: $dropdown-color;\n  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n  list-style: none;\n  background-color: $dropdown-bg;\n  background-clip: padding-box;\n  border: $dropdown-border-width solid $dropdown-border-color;\n  @include border-radius($dropdown-border-radius);\n  @include box-shadow($dropdown-box-shadow);\n\n  &[data-bs-popper] {\n    top: 100%;\n    left: 0;\n    margin-top: $dropdown-spacer;\n  }\n}\n\n// scss-docs-start responsive-breakpoints\n// We deliberately hardcode the `bs-` prefix because we check\n// this custom property in JS to determine Popper's positioning\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .dropdown-menu#{$infix}-start {\n      --bs-position: start;\n\n      &[data-bs-popper] {\n        right: auto;\n        left: 0;\n      }\n    }\n\n    .dropdown-menu#{$infix}-end {\n      --bs-position: end;\n\n      &[data-bs-popper] {\n        right: 0;\n        left: auto;\n      }\n    }\n  }\n}\n// scss-docs-end responsive-breakpoints\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n  .dropdown-menu[data-bs-popper] {\n    top: auto;\n    bottom: 100%;\n    margin-top: 0;\n    margin-bottom: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(up);\n  }\n}\n\n.dropend {\n  .dropdown-menu[data-bs-popper] {\n    top: 0;\n    right: auto;\n    left: 100%;\n    margin-top: 0;\n    margin-left: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(end);\n    &::after {\n      vertical-align: 0;\n    }\n  }\n}\n\n.dropstart {\n  .dropdown-menu[data-bs-popper] {\n    top: 0;\n    right: 100%;\n    left: auto;\n    margin-top: 0;\n    margin-right: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(start);\n    &::before {\n      vertical-align: 0;\n    }\n  }\n}\n\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n  height: 0;\n  margin: $dropdown-divider-margin-y 0;\n  overflow: hidden;\n  border-top: 1px solid $dropdown-divider-bg;\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n  display: block;\n  width: 100%; // For `<button>`s\n  padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n  clear: both;\n  font-weight: $font-weight-normal;\n  color: $dropdown-link-color;\n  text-align: inherit; // For `<button>`s\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: nowrap; // prevent links from randomly breaking onto new lines\n  background-color: transparent; // For `<button>`s\n  border: 0; // For `<button>`s\n\n  // Prevent dropdown overflow if there's no padding\n  // See https://github.com/twbs/bootstrap/pull/27703\n  @if $dropdown-padding-y == 0 {\n    &:first-child {\n      @include border-top-radius($dropdown-inner-border-radius);\n    }\n\n    &:last-child {\n      @include border-bottom-radius($dropdown-inner-border-radius);\n    }\n  }\n\n  &:hover,\n  &:focus {\n    color: $dropdown-link-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n    @include gradient-bg($dropdown-link-hover-bg);\n  }\n\n  &.active,\n  &:active {\n    color: $dropdown-link-active-color;\n    text-decoration: none;\n    @include gradient-bg($dropdown-link-active-bg);\n  }\n\n  &.disabled,\n  &:disabled {\n    color: $dropdown-link-disabled-color;\n    pointer-events: none;\n    background-color: transparent;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n  }\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: $dropdown-header-padding;\n  margin-bottom: 0; // for use with heading elements\n  @include font-size($font-size-sm);\n  color: $dropdown-header-color;\n  white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n  display: block;\n  padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n  color: $dropdown-link-color;\n}\n\n// Dark dropdowns\n.dropdown-menu-dark {\n  color: $dropdown-dark-color;\n  background-color: $dropdown-dark-bg;\n  border-color: $dropdown-dark-border-color;\n  @include box-shadow($dropdown-dark-box-shadow);\n\n  .dropdown-item {\n    color: $dropdown-dark-link-color;\n\n    &:hover,\n    &:focus {\n      color: $dropdown-dark-link-hover-color;\n      @include gradient-bg($dropdown-dark-link-hover-bg);\n    }\n\n    &.active,\n    &:active {\n      color: $dropdown-dark-link-active-color;\n      @include gradient-bg($dropdown-dark-link-active-bg);\n    }\n\n    &.disabled,\n    &:disabled {\n      color: $dropdown-dark-link-disabled-color;\n    }\n  }\n\n  .dropdown-divider {\n    border-color: $dropdown-dark-divider-bg;\n  }\n\n  .dropdown-item-text {\n    color: $dropdown-dark-link-color;\n  }\n\n  .dropdown-header {\n    color: $dropdown-dark-header-color;\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_forms.scss",
    "content": "@import \"forms/labels\";\n@import \"forms/form-text\";\n@import \"forms/form-control\";\n@import \"forms/form-select\";\n@import \"forms/form-check\";\n@import \"forms/form-range\";\n@import \"forms/floating-labels\";\n@import \"forms/input-group\";\n@import \"forms/validation\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/_functions.scss",
    "content": "// Bootstrap functions\n//\n// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.\n\n// Ascending\n// Used to evaluate Sass maps like our grid breakpoints.\n@mixin _assert-ascending($map, $map-name) {\n  $prev-key: null;\n  $prev-num: null;\n  @each $key, $num in $map {\n    @if $prev-num == null or unit($num) == \"%\" or unit($prev-num) == \"%\" {\n      // Do nothing\n    } @else if not comparable($prev-num, $num) {\n      @warn \"Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n    } @else if $prev-num >= $num {\n      @warn \"Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n    }\n    $prev-key: $key;\n    $prev-num: $num;\n  }\n}\n\n// Starts at zero\n// Used to ensure the min-width of the lowest breakpoint starts at 0.\n@mixin _assert-starts-at-zero($map, $map-name: \"$grid-breakpoints\") {\n  @if length($map) > 0 {\n    $values: map-values($map);\n    $first-value: nth($values, 1);\n    @if $first-value != 0 {\n      @warn \"First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.\";\n    }\n  }\n}\n\n// Colors\n@function to-rgb($value) {\n  @return red($value), green($value), blue($value);\n}\n\n// stylelint-disable scss/dollar-variable-pattern\n@function rgba-css-var($identifier, $target) {\n  @if $identifier == \"body\" and $target == \"bg\" {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-bg-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  } @if $identifier == \"body\" and $target == \"text\" {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-color-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  } @else {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  }\n}\n\n@function map-loop($map, $func, $args...) {\n  $_map: ();\n\n  @each $key, $value in $map {\n    // allow to pass the $key and $value of the map as an function argument\n    $_args: ();\n    @each $arg in $args {\n      $_args: append($_args, if($arg == \"$key\", $key, if($arg == \"$value\", $value, $arg)));\n    }\n\n    $_map: map-merge($_map, ($key: call(get-function($func), $_args...)));\n  }\n\n  @return $_map;\n}\n// stylelint-enable scss/dollar-variable-pattern\n\n@function varify($list) {\n  $result: null;\n  @each $entry in $list {\n    $result: append($result, var(--#{$variable-prefix}#{$entry}), space);\n  }\n  @return $result;\n}\n\n// Internal Bootstrap function to turn maps into its negative variant.\n// It prefixes the keys with `n` and makes the value negative.\n@function negativify-map($map) {\n  $result: ();\n  @each $key, $value in $map {\n    @if $key != 0 {\n      $result: map-merge($result, (\"n\" + $key: (-$value)));\n    }\n  }\n  @return $result;\n}\n\n// Get multiple keys from a sass map\n@function map-get-multiple($map, $values) {\n  $result: ();\n  @each $key, $value in $map {\n    @if (index($values, $key) != null) {\n      $result: map-merge($result, ($key: $value));\n    }\n  }\n  @return $result;\n}\n\n// Merge multiple maps\n@function map-merge-multiple($maps...) {\n  $merged-maps: ();\n\n  @each $map in $maps {\n    $merged-maps: map-merge($merged-maps, $map);\n  }\n  @return $merged-maps;\n}\n\n// Replace `$search` with `$replace` in `$string`\n// Used on our SVG icon backgrounds for custom forms.\n//\n// @author Hugo Giraudel\n// @param {String} $string - Initial string\n// @param {String} $search - Substring to replace\n// @param {String} $replace ('') - New value\n// @return {String} - Updated string\n@function str-replace($string, $search, $replace: \"\") {\n  $index: str-index($string, $search);\n\n  @if $index {\n    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);\n  }\n\n  @return $string;\n}\n\n// See https://codepen.io/kevinweber/pen/dXWoRw\n//\n// Requires the use of quotes around data URIs.\n\n@function escape-svg($string) {\n  @if str-index($string, \"data:image/svg+xml\") {\n    @each $char, $encoded in $escaped-characters {\n      // Do not escape the url brackets\n      @if str-index($string, \"url(\") == 1 {\n        $string: url(\"#{str-replace(str-slice($string, 6, -3), $char, $encoded)}\");\n      } @else {\n        $string: str-replace($string, $char, $encoded);\n      }\n    }\n  }\n\n  @return $string;\n}\n\n// Color contrast\n// See https://github.com/twbs/bootstrap/pull/30168\n\n// A list of pre-calculated numbers of pow(divide((divide($value, 255) + .055), 1.055), 2.4). (from 0 to 255)\n// stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern\n$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1;\n\n@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {\n  $foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;\n  $max-ratio: 0;\n  $max-ratio-color: null;\n\n  @each $color in $foregrounds {\n    $contrast-ratio: contrast-ratio($background, $color);\n    @if $contrast-ratio > $min-contrast-ratio {\n      @return $color;\n    } @else if $contrast-ratio > $max-ratio {\n      $max-ratio: $contrast-ratio;\n      $max-ratio-color: $color;\n    }\n  }\n\n  @warn \"Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}...\";\n\n  @return $max-ratio-color;\n}\n\n@function contrast-ratio($background, $foreground: $color-contrast-light) {\n  $l1: luminance($background);\n  $l2: luminance(opaque($background, $foreground));\n\n  @return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05));\n}\n\n// Return WCAG2.0 relative luminance\n// See https://www.w3.org/WAI/GL/wiki/Relative_luminance\n// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests\n@function luminance($color) {\n  $rgb: (\n    \"r\": red($color),\n    \"g\": green($color),\n    \"b\": blue($color)\n  );\n\n  @each $name, $value in $rgb {\n    $value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));\n    $rgb: map-merge($rgb, ($name: $value));\n  }\n\n  @return (map-get($rgb, \"r\") * .2126) + (map-get($rgb, \"g\") * .7152) + (map-get($rgb, \"b\") * .0722);\n}\n\n// Return opaque color\n// opaque(#fff, rgba(0, 0, 0, .5)) => #808080\n@function opaque($background, $foreground) {\n  @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);\n}\n\n// scss-docs-start color-functions\n// Tint a color: mix a color with white\n@function tint-color($color, $weight) {\n  @return mix(white, $color, $weight);\n}\n\n// Shade a color: mix a color with black\n@function shade-color($color, $weight) {\n  @return mix(black, $color, $weight);\n}\n\n// Shade the color if the weight is positive, else tint it\n@function shift-color($color, $weight) {\n  @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));\n}\n// scss-docs-end color-functions\n\n// Return valid calc\n@function add($value1, $value2, $return-calc: true) {\n  @if $value1 == null {\n    @return $value2;\n  }\n\n  @if $value2 == null {\n    @return $value1;\n  }\n\n  @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n    @return $value1 + $value2;\n  }\n\n  @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(\" + \") + $value2);\n}\n\n@function subtract($value1, $value2, $return-calc: true) {\n  @if $value1 == null and $value2 == null {\n    @return null;\n  }\n\n  @if $value1 == null {\n    @return -$value2;\n  }\n\n  @if $value2 == null {\n    @return $value1;\n  }\n\n  @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n    @return $value1 - $value2;\n  }\n\n  @if type-of($value2) != number {\n    $value2: unquote(\"(\") + $value2 + unquote(\")\");\n  }\n\n  @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(\" - \") + $value2);\n}\n\n@function divide($dividend, $divisor, $precision: 10) {\n  $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n  $dividend: abs($dividend);\n  $divisor: abs($divisor);\n  @if $dividend == 0 {\n    @return 0;\n  }\n  @if $divisor == 0 {\n    @error \"Cannot divide by 0\";\n  }\n  $remainder: $dividend;\n  $result: 0;\n  $factor: 10;\n  @while ($remainder > 0 and $precision >= 0) {\n    $quotient: 0;\n    @while ($remainder >= $divisor) {\n      $remainder: $remainder - $divisor;\n      $quotient: $quotient + 1;\n    }\n    $result: $result * 10 + $quotient;\n    $factor: $factor * .1;\n    $remainder: $remainder * 10;\n    $precision: $precision - 1;\n    @if ($precision < 0 and $remainder >= $divisor * 5) {\n      $result: $result + 1;\n    }\n  }\n  $result: $result * $factor * $sign;\n  $dividend-unit: unit($dividend);\n  $divisor-unit: unit($divisor);\n  $unit-map: (\n    \"px\": 1px,\n    \"rem\": 1rem,\n    \"em\": 1em,\n    \"%\": 1%\n  );\n  @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n    $result: $result * map-get($unit-map, $dividend-unit);\n  }\n  @return $result;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_grid.scss",
    "content": "// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n  .row {\n    @include make-row();\n\n    > * {\n      @include make-col-ready();\n    }\n  }\n}\n\n@if $enable-cssgrid {\n  .grid {\n    display: grid;\n    grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr);\n    grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr);\n    gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width});\n\n    @include make-cssgrid();\n  }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n  @include make-grid-columns();\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_helpers.scss",
    "content": "@import \"helpers/clearfix\";\n@import \"helpers/colored-links\";\n@import \"helpers/ratio\";\n@import \"helpers/position\";\n@import \"helpers/stacks\";\n@import \"helpers/visually-hidden\";\n@import \"helpers/stretched-link\";\n@import \"helpers/text-truncation\";\n@import \"helpers/vr\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/_images.scss",
    "content": "// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n  @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n  padding: $thumbnail-padding;\n  background-color: $thumbnail-bg;\n  border: $thumbnail-border-width solid $thumbnail-border-color;\n  @include border-radius($thumbnail-border-radius);\n  @include box-shadow($thumbnail-box-shadow);\n\n  // Keep them at most 100% wide\n  @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n  // Ensures the caption's text aligns with the image.\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: $spacer * .5;\n  line-height: 1;\n}\n\n.figure-caption {\n  @include font-size($figure-caption-font-size);\n  color: $figure-caption-color;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_list-group.scss",
    "content": "// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  display: flex;\n  flex-direction: column;\n\n  // No need to set list-style: none; since .list-group-item is block level\n  padding-left: 0; // reset padding because ul and ol\n  margin-bottom: 0;\n  @include border-radius($list-group-border-radius);\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n\n  > li::before {\n    // Increments only this instance of the section counter\n    content: counters(section, \".\") \". \";\n    counter-increment: section;\n  }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n  width: 100%; // For `<button>`s (anchors become 100% by default though)\n  color: $list-group-action-color;\n  text-align: inherit; // For `<button>`s (anchors inherit)\n\n  // Hover state\n  &:hover,\n  &:focus {\n    z-index: 1; // Place hover/focus items above their siblings for proper border styling\n    color: $list-group-action-hover-color;\n    text-decoration: none;\n    background-color: $list-group-hover-bg;\n  }\n\n  &:active {\n    color: $list-group-action-active-color;\n    background-color: $list-group-action-active-bg;\n  }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: $list-group-item-padding-y $list-group-item-padding-x;\n  color: $list-group-color;\n  text-decoration: if($link-decoration == none, null, none);\n  background-color: $list-group-bg;\n  border: $list-group-border-width solid $list-group-border-color;\n\n  &:first-child {\n    @include border-top-radius(inherit);\n  }\n\n  &:last-child {\n    @include border-bottom-radius(inherit);\n  }\n\n  &.disabled,\n  &:disabled {\n    color: $list-group-disabled-color;\n    pointer-events: none;\n    background-color: $list-group-disabled-bg;\n  }\n\n  // Include both here for `<a>`s and `<button>`s\n  &.active {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: $list-group-active-color;\n    background-color: $list-group-active-bg;\n    border-color: $list-group-active-border-color;\n  }\n\n  & + & {\n    border-top-width: 0;\n\n    &.active {\n      margin-top: -$list-group-border-width;\n      border-top-width: $list-group-border-width;\n    }\n  }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .list-group-horizontal#{$infix} {\n      flex-direction: row;\n\n      > .list-group-item {\n        &:first-child {\n          @include border-bottom-start-radius($list-group-border-radius);\n          @include border-top-end-radius(0);\n        }\n\n        &:last-child {\n          @include border-top-end-radius($list-group-border-radius);\n          @include border-bottom-start-radius(0);\n        }\n\n        &.active {\n          margin-top: 0;\n        }\n\n        + .list-group-item {\n          border-top-width: $list-group-border-width;\n          border-left-width: 0;\n\n          &.active {\n            margin-left: -$list-group-border-width;\n            border-left-width: $list-group-border-width;\n          }\n        }\n      }\n    }\n  }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n  @include border-radius(0);\n\n  > .list-group-item {\n    border-width: 0 0 $list-group-border-width;\n\n    &:last-child {\n      border-bottom-width: 0;\n    }\n  }\n}\n\n\n// scss-docs-start list-group-modifiers\n// List group contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $state, $value in $theme-colors {\n  $list-group-variant-bg: shift-color($value, $list-group-item-bg-scale);\n  $list-group-variant-color: shift-color($value, $list-group-item-color-scale);\n  @if (contrast-ratio($list-group-variant-bg, $list-group-variant-color) < $min-contrast-ratio) {\n    $list-group-variant-color: mix($value, color-contrast($list-group-variant-bg), abs($list-group-item-color-scale));\n  }\n\n  @include list-group-item-variant($state, $list-group-variant-bg, $list-group-variant-color);\n}\n// scss-docs-end list-group-modifiers\n"
  },
  {
    "path": "vendor/bootstrap/scss/_mixins.scss",
    "content": "// Toggles\n//\n// Used in conjunction with global variables to enable certain theme features.\n\n// Vendor\n@import \"vendor/rfs\";\n\n// Deprecate\n@import \"mixins/deprecate\";\n\n// Helpers\n@import \"mixins/breakpoints\";\n@import \"mixins/color-scheme\";\n@import \"mixins/image\";\n@import \"mixins/resize\";\n@import \"mixins/visually-hidden\";\n@import \"mixins/reset-text\";\n@import \"mixins/text-truncate\";\n\n// Utilities\n@import \"mixins/utilities\";\n\n// Components\n@import \"mixins/alert\";\n@import \"mixins/backdrop\";\n@import \"mixins/buttons\";\n@import \"mixins/caret\";\n@import \"mixins/pagination\";\n@import \"mixins/lists\";\n@import \"mixins/list-group\";\n@import \"mixins/forms\";\n@import \"mixins/table-variants\";\n\n// Skins\n@import \"mixins/border-radius\";\n@import \"mixins/box-shadow\";\n@import \"mixins/gradients\";\n@import \"mixins/transition\";\n\n// Layout\n@import \"mixins/clearfix\";\n@import \"mixins/container\";\n@import \"mixins/grid\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/_modal.scss",
    "content": "// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and stuff\n\n\n// Container that the modal scrolls within\n.modal {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $zindex-modal;\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n  // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n  // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: $modal-dialog-margin;\n  // allow clicks to pass through for custom click handling to close modal\n  pointer-events: none;\n\n  // When fading in the modal, animate it to slide down\n  .modal.fade & {\n    @include transition($modal-transition);\n    transform: $modal-fade-transform;\n  }\n  .modal.show & {\n    transform: $modal-show-transform;\n  }\n\n  // When trying to close, animate focus to scale\n  .modal.modal-static & {\n    transform: $modal-scale-transform;\n  }\n}\n\n.modal-dialog-scrollable {\n  height: subtract(100%, $modal-dialog-margin * 2);\n\n  .modal-content {\n    max-height: 100%;\n    overflow: hidden;\n  }\n\n  .modal-body {\n    overflow-y: auto;\n  }\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: subtract(100%, $modal-dialog-margin * 2);\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n  // counteract the pointer-events: none; in the .modal-dialog\n  color: $modal-content-color;\n  pointer-events: auto;\n  background-color: $modal-content-bg;\n  background-clip: padding-box;\n  border: $modal-content-border-width solid $modal-content-border-color;\n  @include border-radius($modal-content-border-radius);\n  @include box-shadow($modal-content-box-shadow-xs);\n  // Remove focus outline from opened modal\n  outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n  @include overlay-backdrop($zindex-modal-backdrop, $modal-backdrop-bg, $modal-backdrop-opacity);\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n  padding: $modal-header-padding;\n  border-bottom: $modal-header-border-width solid $modal-header-border-color;\n  @include border-top-radius($modal-content-inner-border-radius);\n\n  .btn-close {\n    padding: ($modal-header-padding-y * .5) ($modal-header-padding-x * .5);\n    margin: ($modal-header-padding-y * -.5) ($modal-header-padding-x * -.5) ($modal-header-padding-y * -.5) auto;\n  }\n}\n\n// Title text within header\n.modal-title {\n  margin-bottom: 0;\n  line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  // Enable `flex-grow: 1` so that the body take up as much space as possible\n  // when there should be a fixed height on `.modal-dialog`.\n  flex: 1 1 auto;\n  padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  display: flex;\n  flex-wrap: wrap;\n  flex-shrink: 0;\n  align-items: center; // vertically center\n  justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n  padding: $modal-inner-padding - $modal-footer-margin-between * .5;\n  border-top: $modal-footer-border-width solid $modal-footer-border-color;\n  @include border-bottom-radius($modal-content-inner-border-radius);\n\n  // Place margin between footer elements\n  // This solution is far from ideal because of the universal selector usage,\n  // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n  > * {\n    margin: $modal-footer-margin-between * .5;\n  }\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    max-width: $modal-md;\n    margin: $modal-dialog-margin-y-sm-up auto;\n  }\n\n  .modal-dialog-scrollable {\n    height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n  }\n\n  .modal-dialog-centered {\n    min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n  }\n\n  .modal-content {\n    @include box-shadow($modal-content-box-shadow-sm-up);\n  }\n\n  .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n  .modal-lg,\n  .modal-xl {\n    max-width: $modal-lg;\n  }\n}\n\n@include media-breakpoint-up(xl) {\n  .modal-xl { max-width: $modal-xl; }\n}\n\n// scss-docs-start modal-fullscreen-loop\n@each $breakpoint in map-keys($grid-breakpoints) {\n  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n  $postfix: if($infix != \"\", $infix + \"-down\", \"\");\n\n  @include media-breakpoint-down($breakpoint) {\n    .modal-fullscreen#{$postfix} {\n      width: 100vw;\n      max-width: none;\n      height: 100%;\n      margin: 0;\n\n      .modal-content {\n        height: 100%;\n        border: 0;\n        @include border-radius(0);\n      }\n\n      .modal-header {\n        @include border-radius(0);\n      }\n\n      .modal-body {\n        overflow-y: auto;\n      }\n\n      .modal-footer {\n        @include border-radius(0);\n      }\n    }\n  }\n}\n// scss-docs-end modal-fullscreen-loop\n"
  },
  {
    "path": "vendor/bootstrap/scss/_nav.scss",
    "content": "// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n  display: flex;\n  flex-wrap: wrap;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: $nav-link-padding-y $nav-link-padding-x;\n  @include font-size($nav-link-font-size);\n  font-weight: $nav-link-font-weight;\n  color: $nav-link-color;\n  text-decoration: if($link-decoration == none, null, none);\n  @include transition($nav-link-transition);\n\n  &:hover,\n  &:focus {\n    color: $nav-link-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  // Disabled state lightens text\n  &.disabled {\n    color: $nav-link-disabled-color;\n    pointer-events: none;\n    cursor: default;\n  }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n  border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n  .nav-link {\n    margin-bottom: -$nav-tabs-border-width;\n    background: none;\n    border: $nav-tabs-border-width solid transparent;\n    @include border-top-radius($nav-tabs-border-radius);\n\n    &:hover,\n    &:focus {\n      border-color: $nav-tabs-link-hover-border-color;\n      // Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link\n      isolation: isolate;\n    }\n\n    &.disabled {\n      color: $nav-link-disabled-color;\n      background-color: transparent;\n      border-color: transparent;\n    }\n  }\n\n  .nav-link.active,\n  .nav-item.show .nav-link {\n    color: $nav-tabs-link-active-color;\n    background-color: $nav-tabs-link-active-bg;\n    border-color: $nav-tabs-link-active-border-color;\n  }\n\n  .dropdown-menu {\n    // Make dropdown border overlap tab border\n    margin-top: -$nav-tabs-border-width;\n    // Remove the top rounded corners here since there is a hard edge above the menu\n    @include border-top-radius(0);\n  }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n  .nav-link {\n    background: none;\n    border: 0;\n    @include border-radius($nav-pills-border-radius);\n  }\n\n  .nav-link.active,\n  .show > .nav-link {\n    color: $nav-pills-link-active-color;\n    @include gradient-bg($nav-pills-link-active-bg);\n  }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n  > .nav-link,\n  .nav-item {\n    flex: 1 1 auto;\n    text-align: center;\n  }\n}\n\n.nav-justified {\n  > .nav-link,\n  .nav-item {\n    flex-basis: 0;\n    flex-grow: 1;\n    text-align: center;\n  }\n}\n\n.nav-fill,\n.nav-justified {\n  .nav-item .nav-link {\n    width: 100%; // Make sure button will grow\n  }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_navbar.scss",
    "content": "// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap; // allow us to do the line break for collapsing content\n  align-items: center;\n  justify-content: space-between; // space out brand from logo\n  padding-top: $navbar-padding-y;\n  padding-right: $navbar-padding-x; // default: null\n  padding-bottom: $navbar-padding-y;\n  padding-left: $navbar-padding-x; // default: null\n  @include gradient-bg();\n\n  // Because flex properties aren't inherited, we need to redeclare these first\n  // few properties so that content nested within behave properly.\n  // The `flex-wrap` property is inherited to simplify the expanded navbars\n  %container-flex-properties {\n    display: flex;\n    flex-wrap: inherit;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  > .container,\n  > .container-fluid {\n    @extend %container-flex-properties;\n  }\n\n  @each $breakpoint, $container-max-width in $container-max-widths {\n    > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n      @extend %container-flex-properties;\n    }\n  }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n  padding-top: $navbar-brand-padding-y;\n  padding-bottom: $navbar-brand-padding-y;\n  margin-right: $navbar-brand-margin-end;\n  @include font-size($navbar-brand-font-size);\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: nowrap;\n\n  &:hover,\n  &:focus {\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n  display: flex;\n  flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n\n  .nav-link {\n    padding-right: 0;\n    padding-left: 0;\n  }\n\n  .dropdown-menu {\n    position: static;\n  }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n  padding-top: $nav-link-padding-y;\n  padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  // For always expanded or extra full navbars, ensure content aligns itself\n  // properly vertically. Can be easily overridden with flex utilities.\n  align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n  padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n  @include font-size($navbar-toggler-font-size);\n  line-height: 1;\n  background-color: transparent; // remove default button style\n  border: $border-width solid transparent; // remove default button style\n  @include border-radius($navbar-toggler-border-radius);\n  @include transition($navbar-toggler-transition);\n\n  &:hover {\n    text-decoration: none;\n  }\n\n  &:focus {\n    text-decoration: none;\n    outline: 0;\n    box-shadow: 0 0 0 $navbar-toggler-focus-width;\n  }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--#{$variable-prefix}scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n// scss-docs-start navbar-expand-loop\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n  @each $breakpoint in map-keys($grid-breakpoints) {\n    $next: breakpoint-next($breakpoint, $grid-breakpoints);\n    $infix: breakpoint-infix($next, $grid-breakpoints);\n\n    // stylelint-disable-next-line scss/selector-no-union-class-name\n    &#{$infix} {\n      @include media-breakpoint-up($next) {\n        flex-wrap: nowrap;\n        justify-content: flex-start;\n\n        .navbar-nav {\n          flex-direction: row;\n\n          .dropdown-menu {\n            position: absolute;\n          }\n\n          .nav-link {\n            padding-right: $navbar-nav-link-padding-x;\n            padding-left: $navbar-nav-link-padding-x;\n          }\n        }\n\n        .navbar-nav-scroll {\n          overflow: visible;\n        }\n\n        .navbar-collapse {\n          display: flex !important; // stylelint-disable-line declaration-no-important\n          flex-basis: auto;\n        }\n\n        .navbar-toggler {\n          display: none;\n        }\n\n        .offcanvas-header {\n          display: none;\n        }\n\n        .offcanvas {\n          position: inherit;\n          bottom: 0;\n          z-index: 1000;\n          flex-grow: 1;\n          visibility: visible !important; // stylelint-disable-line declaration-no-important\n          background-color: transparent;\n          border-right: 0;\n          border-left: 0;\n          @include transition(none);\n          transform: none;\n        }\n        .offcanvas-top,\n        .offcanvas-bottom {\n          height: auto;\n          border-top: 0;\n          border-bottom: 0;\n        }\n\n        .offcanvas-body {\n          display: flex;\n          flex-grow: 0;\n          padding: 0;\n          overflow-y: visible;\n        }\n      }\n    }\n  }\n}\n// scss-docs-end navbar-expand-loop\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n  .navbar-brand {\n    color: $navbar-light-brand-color;\n\n    &:hover,\n    &:focus {\n      color: $navbar-light-brand-hover-color;\n    }\n  }\n\n  .navbar-nav {\n    .nav-link {\n      color: $navbar-light-color;\n\n      &:hover,\n      &:focus {\n        color: $navbar-light-hover-color;\n      }\n\n      &.disabled {\n        color: $navbar-light-disabled-color;\n      }\n    }\n\n    .show > .nav-link,\n    .nav-link.active {\n      color: $navbar-light-active-color;\n    }\n  }\n\n  .navbar-toggler {\n    color: $navbar-light-color;\n    border-color: $navbar-light-toggler-border-color;\n  }\n\n  .navbar-toggler-icon {\n    background-image: escape-svg($navbar-light-toggler-icon-bg);\n  }\n\n  .navbar-text {\n    color: $navbar-light-color;\n\n    a,\n    a:hover,\n    a:focus  {\n      color: $navbar-light-active-color;\n    }\n  }\n}\n\n// White links against a dark background\n.navbar-dark {\n  .navbar-brand {\n    color: $navbar-dark-brand-color;\n\n    &:hover,\n    &:focus {\n      color: $navbar-dark-brand-hover-color;\n    }\n  }\n\n  .navbar-nav {\n    .nav-link {\n      color: $navbar-dark-color;\n\n      &:hover,\n      &:focus {\n        color: $navbar-dark-hover-color;\n      }\n\n      &.disabled {\n        color: $navbar-dark-disabled-color;\n      }\n    }\n\n    .show > .nav-link,\n    .nav-link.active {\n      color: $navbar-dark-active-color;\n    }\n  }\n\n  .navbar-toggler {\n    color: $navbar-dark-color;\n    border-color: $navbar-dark-toggler-border-color;\n  }\n\n  .navbar-toggler-icon {\n    background-image: escape-svg($navbar-dark-toggler-icon-bg);\n  }\n\n  .navbar-text {\n    color: $navbar-dark-color;\n    a,\n    a:hover,\n    a:focus {\n      color: $navbar-dark-active-color;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_offcanvas.scss",
    "content": ".offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: $zindex-offcanvas;\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  color: $offcanvas-color;\n  visibility: hidden;\n  background-color: $offcanvas-bg-color;\n  background-clip: padding-box;\n  outline: 0;\n  @include box-shadow($offcanvas-box-shadow);\n  @include transition(transform $offcanvas-transition-duration ease-in-out);\n}\n\n.offcanvas-backdrop {\n  @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: $offcanvas-padding-y $offcanvas-padding-x;\n\n  .btn-close {\n    padding: ($offcanvas-padding-y * .5) ($offcanvas-padding-x * .5);\n    margin-top: $offcanvas-padding-y * -.5;\n    margin-right: $offcanvas-padding-x * -.5;\n    margin-bottom: $offcanvas-padding-y * -.5;\n  }\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: $offcanvas-title-line-height;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: $offcanvas-padding-y $offcanvas-padding-x;\n  overflow-y: auto;\n}\n\n.offcanvas-start {\n  top: 0;\n  left: 0;\n  width: $offcanvas-horizontal-width;\n  border-right: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateX(-100%);\n}\n\n.offcanvas-end {\n  top: 0;\n  right: 0;\n  width: $offcanvas-horizontal-width;\n  border-left: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateX(100%);\n}\n\n.offcanvas-top {\n  top: 0;\n  right: 0;\n  left: 0;\n  height: $offcanvas-vertical-height;\n  max-height: 100%;\n  border-bottom: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateY(-100%);\n}\n\n.offcanvas-bottom {\n  right: 0;\n  left: 0;\n  height: $offcanvas-vertical-height;\n  max-height: 100%;\n  border-top: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateY(100%);\n}\n\n.offcanvas.show {\n  transform: none;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_pagination.scss",
    "content": ".pagination {\n  display: flex;\n  @include list-unstyled();\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  color: $pagination-color;\n  text-decoration: if($link-decoration == none, null, none);\n  background-color: $pagination-bg;\n  border: $pagination-border-width solid $pagination-border-color;\n  @include transition($pagination-transition);\n\n  &:hover {\n    z-index: 2;\n    color: $pagination-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n    background-color: $pagination-hover-bg;\n    border-color: $pagination-hover-border-color;\n  }\n\n  &:focus {\n    z-index: 3;\n    color: $pagination-focus-color;\n    background-color: $pagination-focus-bg;\n    outline: $pagination-focus-outline;\n    box-shadow: $pagination-focus-box-shadow;\n  }\n}\n\n.page-item {\n  &:not(:first-child) .page-link {\n    margin-left: $pagination-margin-start;\n  }\n\n  &.active .page-link {\n    z-index: 3;\n    color: $pagination-active-color;\n    @include gradient-bg($pagination-active-bg);\n    border-color: $pagination-active-border-color;\n  }\n\n  &.disabled .page-link {\n    color: $pagination-disabled-color;\n    pointer-events: none;\n    background-color: $pagination-disabled-bg;\n    border-color: $pagination-disabled-border-color;\n  }\n}\n\n\n//\n// Sizing\n//\n@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius);\n\n.pagination-lg {\n  @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);\n}\n\n.pagination-sm {\n  @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_placeholders.scss",
    "content": ".placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentColor;\n  opacity: $placeholder-opacity-max;\n\n  &.btn::before {\n    display: inline-block;\n    content: \"\";\n  }\n}\n\n// Sizing\n.placeholder-xs {\n  min-height: .6em;\n}\n\n.placeholder-sm {\n  min-height: .8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n// Animation\n.placeholder-glow {\n  .placeholder {\n    animation: placeholder-glow 2s ease-in-out infinite;\n  }\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: $placeholder-opacity-min;\n  }\n}\n\n.placeholder-wave {\n  mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%);\n  mask-size: 200% 100%;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@keyframes placeholder-wave {\n  100% {\n    mask-position: -200% 0%;\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_popover.scss",
    "content": ".popover {\n  position: absolute;\n  top: 0;\n  left: 0 #{\"/* rtl:ignore */\"};\n  z-index: $zindex-popover;\n  display: block;\n  max-width: $popover-max-width;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  @include reset-text();\n  @include font-size($popover-font-size);\n  // Allow breaking very long words so they don't overflow the popover's bounds\n  word-wrap: break-word;\n  background-color: $popover-bg;\n  background-clip: padding-box;\n  border: $popover-border-width solid $popover-border-color;\n  @include border-radius($popover-border-radius);\n  @include box-shadow($popover-box-shadow);\n\n  .popover-arrow {\n    position: absolute;\n    display: block;\n    width: $popover-arrow-width;\n    height: $popover-arrow-height;\n\n    &::before,\n    &::after {\n      position: absolute;\n      display: block;\n      content: \"\";\n      border-color: transparent;\n      border-style: solid;\n    }\n  }\n}\n\n.bs-popover-top {\n  > .popover-arrow {\n    bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n    &::before {\n      bottom: 0;\n      border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-top-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      bottom: $popover-border-width;\n      border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-top-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-end {\n  > .popover-arrow {\n    left: subtract(-$popover-arrow-height, $popover-border-width);\n    width: $popover-arrow-height;\n    height: $popover-arrow-width;\n\n    &::before {\n      left: 0;\n      border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-right-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      left: $popover-border-width;\n      border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-right-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-bottom {\n  > .popover-arrow {\n    top: subtract(-$popover-arrow-height, $popover-border-width);\n\n    &::before {\n      top: 0;\n      border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);\n      border-bottom-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      top: $popover-border-width;\n      border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);\n      border-bottom-color: $popover-arrow-color;\n    }\n  }\n\n  // This will remove the popover-header's border just below the arrow\n  .popover-header::before {\n    position: absolute;\n    top: 0;\n    left: 50%;\n    display: block;\n    width: $popover-arrow-width;\n    margin-left: -$popover-arrow-width * .5;\n    content: \"\";\n    border-bottom: $popover-border-width solid $popover-header-bg;\n  }\n}\n\n.bs-popover-start {\n  > .popover-arrow {\n    right: subtract(-$popover-arrow-height, $popover-border-width);\n    width: $popover-arrow-height;\n    height: $popover-arrow-width;\n\n    &::before {\n      right: 0;\n      border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;\n      border-left-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      right: $popover-border-width;\n      border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;\n      border-left-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-auto {\n  &[data-popper-placement^=\"top\"] {\n    @extend .bs-popover-top;\n  }\n  &[data-popper-placement^=\"right\"] {\n    @extend .bs-popover-end;\n  }\n  &[data-popper-placement^=\"bottom\"] {\n    @extend .bs-popover-bottom;\n  }\n  &[data-popper-placement^=\"left\"] {\n    @extend .bs-popover-start;\n  }\n}\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n  padding: $popover-header-padding-y $popover-header-padding-x;\n  margin-bottom: 0; // Reset the default from Reboot\n  @include font-size($font-size-base);\n  color: $popover-header-color;\n  background-color: $popover-header-bg;\n  border-bottom: $popover-border-width solid $popover-border-color;\n  @include border-top-radius($popover-inner-border-radius);\n\n  &:empty {\n    display: none;\n  }\n}\n\n.popover-body {\n  padding: $popover-body-padding-y $popover-body-padding-x;\n  color: $popover-body-color;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_progress.scss",
    "content": "// Disable animation if transitions are disabled\n\n// scss-docs-start progress-keyframes\n@if $enable-transitions {\n  @keyframes progress-bar-stripes {\n    0% { background-position-x: $progress-height; }\n  }\n}\n// scss-docs-end progress-keyframes\n\n.progress {\n  display: flex;\n  height: $progress-height;\n  overflow: hidden; // force rounded corners by cropping it\n  @include font-size($progress-font-size);\n  background-color: $progress-bg;\n  @include border-radius($progress-border-radius);\n  @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: $progress-bar-color;\n  text-align: center;\n  white-space: nowrap;\n  background-color: $progress-bar-bg;\n  @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n  @include gradient-striped();\n  background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n  .progress-bar-animated {\n    animation: $progress-bar-animation-timing progress-bar-stripes;\n\n    @if $enable-reduced-motion {\n      @media (prefers-reduced-motion: reduce) {\n        animation: none;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_reboot.scss",
    "content": "// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n  @if $font-size-root != null {\n    font-size: var(--#{$variable-prefix}root-font-size);\n  }\n\n  @if $enable-smooth-scroll {\n    @media (prefers-reduced-motion: no-preference) {\n      scroll-behavior: smooth;\n    }\n  }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n  margin: 0; // 1\n  font-family: var(--#{$variable-prefix}body-font-family);\n  @include font-size(var(--#{$variable-prefix}body-font-size));\n  font-weight: var(--#{$variable-prefix}body-font-weight);\n  line-height: var(--#{$variable-prefix}body-line-height);\n  color: var(--#{$variable-prefix}body-color);\n  text-align: var(--#{$variable-prefix}body-text-align);\n  background-color: var(--#{$variable-prefix}body-bg); // 2\n  -webkit-text-size-adjust: 100%; // 3\n  -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field\n\nhr {\n  margin: $hr-margin-y 0;\n  color: $hr-color; // 1\n  background-color: currentColor;\n  border: 0;\n  opacity: $hr-opacity;\n}\n\nhr:not([size]) {\n  height: $hr-height; // 2\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n//    By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n//    margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n  margin-top: 0; // 1\n  margin-bottom: $headings-margin-bottom;\n  font-family: $headings-font-family;\n  font-style: $headings-font-style;\n  font-weight: $headings-font-weight;\n  line-height: $headings-line-height;\n  color: $headings-color;\n}\n\nh1 {\n  @extend %heading;\n  @include font-size($h1-font-size);\n}\n\nh2 {\n  @extend %heading;\n  @include font-size($h2-font-size);\n}\n\nh3 {\n  @extend %heading;\n  @include font-size($h3-font-size);\n}\n\nh4 {\n  @extend %heading;\n  @include font-size($h4-font-size);\n}\n\nh5 {\n  @extend %heading;\n  @include font-size($h5-font-size);\n}\n\nh6 {\n  @extend %heading;\n  @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n  margin-top: 0;\n  margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n  text-decoration: underline dotted; // 2\n  cursor: help; // 3\n  text-decoration-skip-ink: none; // 4\n}\n\n\n// Address\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n  margin-bottom: .5rem;\n  margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n  font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n  @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n  padding: $mark-padding;\n  background-color: $mark-bg;\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n  position: relative;\n  @include font-size($sub-sup-font-size);\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n  color: $link-color;\n  text-decoration: $link-decoration;\n\n  &:hover {\n    color: $link-hover-color;\n    text-decoration: $link-hover-decoration;\n  }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n  &,\n  &:hover {\n    color: inherit;\n    text-decoration: none;\n  }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: $font-family-code;\n  @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n  direction: ltr #{\"/* rtl:ignore */\"};\n  unicode-bidi: bidi-override;\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n  display: block;\n  margin-top: 0; // 1\n  margin-bottom: 1rem; // 2\n  overflow: auto; // 3\n  @include font-size($code-font-size);\n  color: $pre-color;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    @include font-size(inherit);\n    color: inherit;\n    word-break: normal;\n  }\n}\n\ncode {\n  @include font-size($code-font-size);\n  color: $code-color;\n  word-wrap: break-word;\n\n  // Streamline the style when inside anchors to avoid broken underline and more\n  a > & {\n    color: inherit;\n  }\n}\n\nkbd {\n  padding: $kbd-padding-y $kbd-padding-x;\n  @include font-size($kbd-font-size);\n  color: $kbd-color;\n  background-color: $kbd-bg;\n  @include border-radius($border-radius-sm);\n\n  kbd {\n    padding: 0;\n    @include font-size(1em);\n    font-weight: $nested-kbd-font-weight;\n  }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n  margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: $table-cell-padding-y;\n  padding-bottom: $table-cell-padding-y;\n  color: $table-caption-color;\n  text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n  font-weight: $table-th-font-weight; // 1\n  text-align: inherit; // 2\n  text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n  display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0; // 1\n  font-family: inherit;\n  @include font-size(inherit);\n  line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n  text-transform: none;\n}\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n  cursor: pointer;\n}\n\nselect {\n  // Remove the inheritance of word-wrap in Safari.\n  // See https://github.com/twbs/bootstrap/issues/24990\n  word-wrap: normal;\n\n  // Undo the opacity change from Chrome\n  &:disabled {\n    opacity: 1;\n  }\n}\n\n// Remove the dropdown arrow in Chrome from inputs built with datalists.\n// See https://stackoverflow.com/a/54997118\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n//    controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\n// 3. Opinionated: add \"hand\" cursor to non-disabled button elements.\n\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n\n  @if $enable-button-pointers {\n    &:not(:disabled) {\n      cursor: pointer; // 3\n    }\n  }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\n// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.\n\ntextarea {\n  resize: vertical; // 1\n}\n\n// 1. Browsers set a default `min-width: min-content;` on fieldsets,\n//    unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n//    So we reset that to ensure fieldsets behave more like a standard block element.\n//    See https://github.com/twbs/bootstrap/issues/12359\n//    and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.\n\nfieldset {\n  min-width: 0; // 1\n  padding: 0; // 2\n  margin: 0; // 2\n  border: 0; // 2\n}\n\n// 1. By using `float: left`, the legend will behave like a block element.\n//    This way the border of a fieldset wraps around the legend if present.\n// 2. Fix wrapping bug.\n//    See https://github.com/twbs/bootstrap/issues/29712\n\nlegend {\n  float: left; // 1\n  width: 100%;\n  padding: 0;\n  margin-bottom: $legend-margin-bottom;\n  @include font-size($legend-font-size);\n  font-weight: $legend-font-weight;\n  line-height: inherit;\n\n  + * {\n    clear: left; // 2\n  }\n}\n\n// Fix height of inputs with a type of datetime-local, date, month, week, or time\n// See https://github.com/twbs/bootstrap/issues/18842\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n// 1. Correct the outline style in Safari.\n// 2. This overrides the extra rounded corners on search inputs in iOS so that our\n//    `.form-control` class can properly style them. Note that this cannot simply\n//    be added to `.form-control` as it's not specific enough. For details, see\n//    https://github.com/twbs/bootstrap/issues/11586.\n\n[type=\"search\"] {\n  outline-offset: -2px; // 1\n  -webkit-appearance: textfield; // 2\n}\n\n// 1. A few input types should stay LTR\n// See https://rtlstyling.com/posts/rtl-styling#form-inputs\n// 2. RTL only output\n// See https://rtlcss.com/learn/usage-guide/control-directives/#raw\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n\n// Remove the inner padding in Chrome and Safari on macOS.\n\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n// Remove padding around color pickers in webkit browsers\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n\n// Inherit font family and line height for file input buttons\n\n::file-selector-button {\n  font: inherit;\n}\n\n// 1. Change font properties to `inherit`\n// 2. Correct the inability to style clickable types in iOS and Safari.\n\n::-webkit-file-upload-button {\n  font: inherit; // 1\n  -webkit-appearance: button; // 2\n}\n\n// Correct element displays\n\noutput {\n  display: inline-block;\n}\n\n// Remove border from iframe\n\niframe {\n  border: 0;\n}\n\n// Summary\n//\n// 1. Add the correct display in all browsers\n\nsummary {\n  display: list-item; // 1\n  cursor: pointer;\n}\n\n\n// Progress\n//\n// Add the correct vertical alignment in Chrome, Firefox, and Opera.\n\nprogress {\n  vertical-align: baseline;\n}\n\n\n// Hidden attribute\n//\n// Always hide an element with the `hidden` HTML attribute.\n\n[hidden] {\n  display: none !important;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_root.scss",
    "content": ":root {\n  // Note: Custom variable values only support SassScript inside `#{}`.\n\n  // Colors\n  //\n  // Generate palettes for full colors, grays, and theme colors.\n\n  @each $color, $value in $colors {\n    --#{$variable-prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $grays {\n    --#{$variable-prefix}gray-#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors {\n    --#{$variable-prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors-rgb {\n    --#{$variable-prefix}#{$color}-rgb: #{$value};\n  }\n\n  --#{$variable-prefix}white-rgb: #{to-rgb($white)};\n  --#{$variable-prefix}black-rgb: #{to-rgb($black)};\n  --#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)};\n  --#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n  // Fonts\n\n  // Note: Use `inspect` for lists so that quoted items keep the quotes.\n  // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n  --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n  --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};\n  --#{$variable-prefix}gradient: #{$gradient};\n\n  // Root and body\n  // stylelint-disable custom-property-empty-line-before\n  // scss-docs-start root-body-variables\n  @if $font-size-root != null {\n    --#{$variable-prefix}root-font-size: #{$font-size-root};\n  }\n  --#{$variable-prefix}body-font-family: #{$font-family-base};\n  --#{$variable-prefix}body-font-size: #{$font-size-base};\n  --#{$variable-prefix}body-font-weight: #{$font-weight-base};\n  --#{$variable-prefix}body-line-height: #{$line-height-base};\n  --#{$variable-prefix}body-color: #{$body-color};\n  @if $body-text-align != null {\n    --#{$variable-prefix}body-text-align: #{$body-text-align};\n  }\n  --#{$variable-prefix}body-bg: #{$body-bg};\n  // scss-docs-end root-body-variables\n  // stylelint-enable custom-property-empty-line-before\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_spinners.scss",
    "content": "//\n// Rotating border\n//\n\n// scss-docs-start spinner-border-keyframes\n@keyframes spinner-border {\n  to { transform: rotate(360deg) #{\"/* rtl:ignore */\"}; }\n}\n// scss-docs-end spinner-border-keyframes\n\n.spinner-border {\n  display: inline-block;\n  width: $spinner-width;\n  height: $spinner-height;\n  vertical-align: $spinner-vertical-align;\n  border: $spinner-border-width solid currentColor;\n  border-right-color: transparent;\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 50%;\n  animation: $spinner-animation-speed linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n  width: $spinner-width-sm;\n  height: $spinner-height-sm;\n  border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n// scss-docs-start spinner-grow-keyframes\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n// scss-docs-end spinner-grow-keyframes\n\n.spinner-grow {\n  display: inline-block;\n  width: $spinner-width;\n  height: $spinner-height;\n  vertical-align: $spinner-vertical-align;\n  background-color: currentColor;\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 50%;\n  opacity: 0;\n  animation: $spinner-animation-speed linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n  width: $spinner-width-sm;\n  height: $spinner-height-sm;\n}\n\n@if $enable-reduced-motion {\n  @media (prefers-reduced-motion: reduce) {\n    .spinner-border,\n    .spinner-grow {\n      animation-duration: $spinner-animation-speed * 2;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_tables.scss",
    "content": "//\n// Basic Bootstrap table\n//\n\n.table {\n  --#{$variable-prefix}table-bg: #{$table-bg};\n  --#{$variable-prefix}table-accent-bg: #{$table-accent-bg};\n  --#{$variable-prefix}table-striped-color: #{$table-striped-color};\n  --#{$variable-prefix}table-striped-bg: #{$table-striped-bg};\n  --#{$variable-prefix}table-active-color: #{$table-active-color};\n  --#{$variable-prefix}table-active-bg: #{$table-active-bg};\n  --#{$variable-prefix}table-hover-color: #{$table-hover-color};\n  --#{$variable-prefix}table-hover-bg: #{$table-hover-bg};\n\n  width: 100%;\n  margin-bottom: $spacer;\n  color: $table-color;\n  vertical-align: $table-cell-vertical-align;\n  border-color: $table-border-color;\n\n  // Target th & td\n  // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.\n  // We use the universal selectors here to simplify the selector (else we would need 6 different selectors).\n  // Another advantage is that this generates less code and makes the selector less specific making it easier to override.\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y $table-cell-padding-x;\n    background-color: var(--#{$variable-prefix}table-bg);\n    border-bottom-width: $table-border-width;\n    box-shadow: inset 0 0 0 9999px var(--#{$variable-prefix}table-accent-bg);\n  }\n\n  > tbody {\n    vertical-align: inherit;\n  }\n\n  > thead {\n    vertical-align: bottom;\n  }\n\n  // Highlight border color between thead, tbody and tfoot.\n  > :not(:first-child) {\n    border-top: (2 * $table-border-width) solid $table-group-separator-color;\n  }\n}\n\n\n//\n// Change placement of captions with a class\n//\n\n.caption-top {\n  caption-side: top;\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;\n  }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n//\n// When borders are added on all sides of the cells, the corners can render odd when\n// these borders do not have the same color or if they are semi-transparent.\n// Therefor we add top and border bottoms to the `tr`s and left and right borders\n// to the `td`s or `th`s\n\n.table-bordered {\n  > :not(caption) > * {\n    border-width: $table-border-width 0;\n\n    // stylelint-disable-next-line selector-max-universal\n    > * {\n      border-width: 0 $table-border-width;\n    }\n  }\n}\n\n.table-borderless {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    border-bottom-width: 0;\n  }\n\n  > :not(:first-child) {\n    border-top-width: 0;\n  }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-of-type(#{$table-striped-order}) > * {\n    --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-striped-bg);\n    color: var(--#{$variable-prefix}table-striped-color);\n  }\n}\n\n// Active table\n//\n// The `.table-active` class can be added to highlight rows or cells\n\n.table-active {\n  --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-active-bg);\n  color: var(--#{$variable-prefix}table-active-color);\n}\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover > * {\n    --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-hover-bg);\n    color: var(--#{$variable-prefix}table-hover-color);\n  }\n}\n\n\n// Table variants\n//\n// Table variants set the table cell backgrounds, border colors\n// and the colors of the striped, hovered & active tables\n\n@each $color, $value in $table-variants {\n  @include table-variant($color, $value);\n}\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n  @include media-breakpoint-down($breakpoint) {\n    .table-responsive#{$infix} {\n      overflow-x: auto;\n      -webkit-overflow-scrolling: touch;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_toasts.scss",
    "content": ".toast {\n  width: $toast-max-width;\n  max-width: 100%;\n  @include font-size($toast-font-size);\n  color: $toast-color;\n  pointer-events: auto;\n  background-color: $toast-background-color;\n  background-clip: padding-box;\n  border: $toast-border-width solid $toast-border-color;\n  box-shadow: $toast-box-shadow;\n  @include border-radius($toast-border-radius);\n\n  &.showing {\n    opacity: 0;\n  }\n\n  &:not(.show) {\n    display: none;\n  }\n}\n\n.toast-container {\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n\n  > :not(:last-child) {\n    margin-bottom: $toast-spacing;\n  }\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: $toast-padding-y $toast-padding-x;\n  color: $toast-header-color;\n  background-color: $toast-header-background-color;\n  background-clip: padding-box;\n  border-bottom: $toast-border-width solid $toast-header-border-color;\n  @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n\n  .btn-close {\n    margin-right: $toast-padding-x * -.5;\n    margin-left: $toast-padding-x;\n  }\n}\n\n.toast-body {\n  padding: $toast-padding-x; // apply to both vertical and horizontal\n  word-wrap: break-word;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_tooltip.scss",
    "content": "// Base class\n.tooltip {\n  position: absolute;\n  z-index: $zindex-tooltip;\n  display: block;\n  margin: $tooltip-margin;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  @include reset-text();\n  @include font-size($tooltip-font-size);\n  // Allow breaking very long words so they don't overflow the tooltip's bounds\n  word-wrap: break-word;\n  opacity: 0;\n\n  &.show { opacity: $tooltip-opacity; }\n\n  .tooltip-arrow {\n    position: absolute;\n    display: block;\n    width: $tooltip-arrow-width;\n    height: $tooltip-arrow-height;\n\n    &::before {\n      position: absolute;\n      content: \"\";\n      border-color: transparent;\n      border-style: solid;\n    }\n  }\n}\n\n.bs-tooltip-top {\n  padding: $tooltip-arrow-height 0;\n\n  .tooltip-arrow {\n    bottom: 0;\n\n    &::before {\n      top: -1px;\n      border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;\n      border-top-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-end {\n  padding: 0 $tooltip-arrow-height;\n\n  .tooltip-arrow {\n    left: 0;\n    width: $tooltip-arrow-height;\n    height: $tooltip-arrow-width;\n\n    &::before {\n      right: -1px;\n      border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;\n      border-right-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-bottom {\n  padding: $tooltip-arrow-height 0;\n\n  .tooltip-arrow {\n    top: 0;\n\n    &::before {\n      bottom: -1px;\n      border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;\n      border-bottom-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-start {\n  padding: 0 $tooltip-arrow-height;\n\n  .tooltip-arrow {\n    right: 0;\n    width: $tooltip-arrow-height;\n    height: $tooltip-arrow-width;\n\n    &::before {\n      left: -1px;\n      border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;\n      border-left-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-auto {\n  &[data-popper-placement^=\"top\"] {\n    @extend .bs-tooltip-top;\n  }\n  &[data-popper-placement^=\"right\"] {\n    @extend .bs-tooltip-end;\n  }\n  &[data-popper-placement^=\"bottom\"] {\n    @extend .bs-tooltip-bottom;\n  }\n  &[data-popper-placement^=\"left\"] {\n    @extend .bs-tooltip-start;\n  }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: $tooltip-max-width;\n  padding: $tooltip-padding-y $tooltip-padding-x;\n  color: $tooltip-color;\n  text-align: center;\n  background-color: $tooltip-bg;\n  @include border-radius($tooltip-border-radius);\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_transitions.scss",
    "content": ".fade {\n  @include transition($transition-fade);\n\n  &:not(.show) {\n    opacity: 0;\n  }\n}\n\n// scss-docs-start collapse-classes\n.collapse {\n  &:not(.show) {\n    display: none;\n  }\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  @include transition($transition-collapse);\n\n  &.collapse-horizontal {\n    width: 0;\n    height: auto;\n    @include transition($transition-collapse-width);\n  }\n}\n// scss-docs-end collapse-classes\n"
  },
  {
    "path": "vendor/bootstrap/scss/_type.scss",
    "content": "//\n// Headings\n//\n.h1 {\n  @extend h1;\n}\n\n.h2 {\n  @extend h2;\n}\n\n.h3 {\n  @extend h3;\n}\n\n.h4 {\n  @extend h4;\n}\n\n.h5 {\n  @extend h5;\n}\n\n.h6 {\n  @extend h6;\n}\n\n\n.lead {\n  @include font-size($lead-font-size);\n  font-weight: $lead-font-weight;\n}\n\n// Type display classes\n@each $display, $font-size in $display-font-sizes {\n  .display-#{$display} {\n    @include font-size($font-size);\n    font-weight: $display-font-weight;\n    line-height: $display-line-height;\n  }\n}\n\n//\n// Emphasis\n//\n.small {\n  @extend small;\n}\n\n.mark {\n  @extend mark;\n}\n\n//\n// Lists\n//\n\n.list-unstyled {\n  @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  @include list-unstyled();\n}\n.list-inline-item {\n  display: inline-block;\n\n  &:not(:last-child) {\n    margin-right: $list-inline-padding;\n  }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n  @include font-size($initialism-font-size);\n  text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-font-size);\n\n  > :last-child {\n    margin-bottom: 0;\n  }\n}\n\n.blockquote-footer {\n  margin-top: -$blockquote-margin-y;\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-footer-font-size);\n  color: $blockquote-footer-color;\n\n  &::before {\n    content: \"\\2014\\00A0\"; // em dash, nbsp\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/_utilities.scss",
    "content": "// stylelint-disable indentation\n\n// Utilities\n\n$utilities: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$utilities: map-merge(\n  (\n    // scss-docs-start utils-vertical-align\n    \"align\": (\n      property: vertical-align,\n      class: align,\n      values: baseline top middle bottom text-bottom text-top\n    ),\n    // scss-docs-end utils-vertical-align\n    // scss-docs-start utils-float\n    \"float\": (\n      responsive: true,\n      property: float,\n      values: (\n        start: left,\n        end: right,\n        none: none,\n      )\n    ),\n    // scss-docs-end utils-float\n    // Opacity utilities\n    // scss-docs-start utils-opacity\n    \"opacity\": (\n      property: opacity,\n      values: (\n        0: 0,\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1,\n      )\n    ),\n    // scss-docs-end utils-opacity\n    // scss-docs-start utils-overflow\n    \"overflow\": (\n      property: overflow,\n      values: auto hidden visible scroll,\n    ),\n    // scss-docs-end utils-overflow\n    // scss-docs-start utils-display\n    \"display\": (\n      responsive: true,\n      print: true,\n      property: display,\n      class: d,\n      values: inline inline-block block grid table table-row table-cell flex inline-flex none\n    ),\n    // scss-docs-end utils-display\n    // scss-docs-start utils-shadow\n    \"shadow\": (\n      property: box-shadow,\n      class: shadow,\n      values: (\n        null: $box-shadow,\n        sm: $box-shadow-sm,\n        lg: $box-shadow-lg,\n        none: none,\n      )\n    ),\n    // scss-docs-end utils-shadow\n    // scss-docs-start utils-position\n    \"position\": (\n      property: position,\n      values: static relative absolute fixed sticky\n    ),\n    \"top\": (\n      property: top,\n      values: $position-values\n    ),\n    \"bottom\": (\n      property: bottom,\n      values: $position-values\n    ),\n    \"start\": (\n      property: left,\n      class: start,\n      values: $position-values\n    ),\n    \"end\": (\n      property: right,\n      class: end,\n      values: $position-values\n    ),\n    \"translate-middle\": (\n      property: transform,\n      class: translate-middle,\n      values: (\n        null: translate(-50%, -50%),\n        x: translateX(-50%),\n        y: translateY(-50%),\n      )\n    ),\n    // scss-docs-end utils-position\n    // scss-docs-start utils-borders\n    \"border\": (\n      property: border,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-top\": (\n      property: border-top,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-end\": (\n      property: border-right,\n      class: border-end,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-bottom\": (\n      property: border-bottom,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-start\": (\n      property: border-left,\n      class: border-start,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-color\": (\n      property: border-color,\n      class: border,\n      values: map-merge($theme-colors, (\"white\": $white))\n    ),\n    \"border-width\": (\n      property: border-width,\n      class: border,\n      values: $border-widths\n    ),\n    // scss-docs-end utils-borders\n    // Sizing utilities\n    // scss-docs-start utils-sizing\n    \"width\": (\n      property: width,\n      class: w,\n      values: (\n        25: 25%,\n        50: 50%,\n        75: 75%,\n        100: 100%,\n        auto: auto\n      )\n    ),\n    \"max-width\": (\n      property: max-width,\n      class: mw,\n      values: (100: 100%)\n    ),\n    \"viewport-width\": (\n      property: width,\n      class: vw,\n      values: (100: 100vw)\n    ),\n    \"min-viewport-width\": (\n      property: min-width,\n      class: min-vw,\n      values: (100: 100vw)\n    ),\n    \"height\": (\n      property: height,\n      class: h,\n      values: (\n        25: 25%,\n        50: 50%,\n        75: 75%,\n        100: 100%,\n        auto: auto\n      )\n    ),\n    \"max-height\": (\n      property: max-height,\n      class: mh,\n      values: (100: 100%)\n    ),\n    \"viewport-height\": (\n      property: height,\n      class: vh,\n      values: (100: 100vh)\n    ),\n    \"min-viewport-height\": (\n      property: min-height,\n      class: min-vh,\n      values: (100: 100vh)\n    ),\n    // scss-docs-end utils-sizing\n    // Flex utilities\n    // scss-docs-start utils-flex\n    \"flex\": (\n      responsive: true,\n      property: flex,\n      values: (fill: 1 1 auto)\n    ),\n    \"flex-direction\": (\n      responsive: true,\n      property: flex-direction,\n      class: flex,\n      values: row column row-reverse column-reverse\n    ),\n    \"flex-grow\": (\n      responsive: true,\n      property: flex-grow,\n      class: flex,\n      values: (\n        grow-0: 0,\n        grow-1: 1,\n      )\n    ),\n    \"flex-shrink\": (\n      responsive: true,\n      property: flex-shrink,\n      class: flex,\n      values: (\n        shrink-0: 0,\n        shrink-1: 1,\n      )\n    ),\n    \"flex-wrap\": (\n      responsive: true,\n      property: flex-wrap,\n      class: flex,\n      values: wrap nowrap wrap-reverse\n    ),\n    \"gap\": (\n      responsive: true,\n      property: gap,\n      class: gap,\n      values: $spacers\n    ),\n    \"justify-content\": (\n      responsive: true,\n      property: justify-content,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        between: space-between,\n        around: space-around,\n        evenly: space-evenly,\n      )\n    ),\n    \"align-items\": (\n      responsive: true,\n      property: align-items,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        baseline: baseline,\n        stretch: stretch,\n      )\n    ),\n    \"align-content\": (\n      responsive: true,\n      property: align-content,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        between: space-between,\n        around: space-around,\n        stretch: stretch,\n      )\n    ),\n    \"align-self\": (\n      responsive: true,\n      property: align-self,\n      values: (\n        auto: auto,\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        baseline: baseline,\n        stretch: stretch,\n      )\n    ),\n    \"order\": (\n      responsive: true,\n      property: order,\n      values: (\n        first: -1,\n        0: 0,\n        1: 1,\n        2: 2,\n        3: 3,\n        4: 4,\n        5: 5,\n        last: 6,\n      ),\n    ),\n    // scss-docs-end utils-flex\n    // Margin utilities\n    // scss-docs-start utils-spacing\n    \"margin\": (\n      responsive: true,\n      property: margin,\n      class: m,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-x\": (\n      responsive: true,\n      property: margin-right margin-left,\n      class: mx,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-y\": (\n      responsive: true,\n      property: margin-top margin-bottom,\n      class: my,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-top\": (\n      responsive: true,\n      property: margin-top,\n      class: mt,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-end\": (\n      responsive: true,\n      property: margin-right,\n      class: me,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-bottom\": (\n      responsive: true,\n      property: margin-bottom,\n      class: mb,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-start\": (\n      responsive: true,\n      property: margin-left,\n      class: ms,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    // Negative margin utilities\n    \"negative-margin\": (\n      responsive: true,\n      property: margin,\n      class: m,\n      values: $negative-spacers\n    ),\n    \"negative-margin-x\": (\n      responsive: true,\n      property: margin-right margin-left,\n      class: mx,\n      values: $negative-spacers\n    ),\n    \"negative-margin-y\": (\n      responsive: true,\n      property: margin-top margin-bottom,\n      class: my,\n      values: $negative-spacers\n    ),\n    \"negative-margin-top\": (\n      responsive: true,\n      property: margin-top,\n      class: mt,\n      values: $negative-spacers\n    ),\n    \"negative-margin-end\": (\n      responsive: true,\n      property: margin-right,\n      class: me,\n      values: $negative-spacers\n    ),\n    \"negative-margin-bottom\": (\n      responsive: true,\n      property: margin-bottom,\n      class: mb,\n      values: $negative-spacers\n    ),\n    \"negative-margin-start\": (\n      responsive: true,\n      property: margin-left,\n      class: ms,\n      values: $negative-spacers\n    ),\n    // Padding utilities\n    \"padding\": (\n      responsive: true,\n      property: padding,\n      class: p,\n      values: $spacers\n    ),\n    \"padding-x\": (\n      responsive: true,\n      property: padding-right padding-left,\n      class: px,\n      values: $spacers\n    ),\n    \"padding-y\": (\n      responsive: true,\n      property: padding-top padding-bottom,\n      class: py,\n      values: $spacers\n    ),\n    \"padding-top\": (\n      responsive: true,\n      property: padding-top,\n      class: pt,\n      values: $spacers\n    ),\n    \"padding-end\": (\n      responsive: true,\n      property: padding-right,\n      class: pe,\n      values: $spacers\n    ),\n    \"padding-bottom\": (\n      responsive: true,\n      property: padding-bottom,\n      class: pb,\n      values: $spacers\n    ),\n    \"padding-start\": (\n      responsive: true,\n      property: padding-left,\n      class: ps,\n      values: $spacers\n    ),\n    // scss-docs-end utils-spacing\n    // Text\n    // scss-docs-start utils-text\n    \"font-family\": (\n      property: font-family,\n      class: font,\n      values: (monospace: var(--#{$variable-prefix}font-monospace))\n    ),\n    \"font-size\": (\n      rfs: true,\n      property: font-size,\n      class: fs,\n      values: $font-sizes\n    ),\n    \"font-style\": (\n      property: font-style,\n      class: fst,\n      values: italic normal\n    ),\n    \"font-weight\": (\n      property: font-weight,\n      class: fw,\n      values: (\n        light: $font-weight-light,\n        lighter: $font-weight-lighter,\n        normal: $font-weight-normal,\n        bold: $font-weight-bold,\n        bolder: $font-weight-bolder\n      )\n    ),\n    \"line-height\": (\n      property: line-height,\n      class: lh,\n      values: (\n        1: 1,\n        sm: $line-height-sm,\n        base: $line-height-base,\n        lg: $line-height-lg,\n      )\n    ),\n    \"text-align\": (\n      responsive: true,\n      property: text-align,\n      class: text,\n      values: (\n        start: left,\n        end: right,\n        center: center,\n      )\n    ),\n    \"text-decoration\": (\n      property: text-decoration,\n      values: none underline line-through\n    ),\n    \"text-transform\": (\n      property: text-transform,\n      class: text,\n      values: lowercase uppercase capitalize\n    ),\n    \"white-space\": (\n      property: white-space,\n      class: text,\n      values: (\n        wrap: normal,\n        nowrap: nowrap,\n      )\n    ),\n    \"word-wrap\": (\n      property: word-wrap word-break,\n      class: text,\n      values: (break: break-word),\n      rtl: false\n    ),\n    // scss-docs-end utils-text\n    // scss-docs-start utils-color\n    \"color\": (\n      property: color,\n      class: text,\n      local-vars: (\n        \"text-opacity\": 1\n      ),\n      values: map-merge(\n        $utilities-text-colors,\n        (\n          \"muted\": $text-muted,\n          \"black-50\": rgba($black, .5), // deprecated\n          \"white-50\": rgba($white, .5), // deprecated\n          \"reset\": inherit,\n        )\n      )\n    ),\n    \"text-opacity\": (\n      css-var: true,\n      class: text-opacity,\n      values: (\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1\n      )\n    ),\n    // scss-docs-end utils-color\n    // scss-docs-start utils-bg-color\n    \"background-color\": (\n      property: background-color,\n      class: bg,\n      local-vars: (\n        \"bg-opacity\": 1\n      ),\n      values: map-merge(\n        $utilities-bg-colors,\n        (\n          \"transparent\": transparent\n        )\n      )\n    ),\n    \"bg-opacity\": (\n      css-var: true,\n      class: bg-opacity,\n      values: (\n        10: .1,\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1\n      )\n    ),\n    // scss-docs-end utils-bg-color\n    \"gradient\": (\n      property: background-image,\n      class: bg,\n      values: (gradient: var(--#{$variable-prefix}gradient))\n    ),\n    // scss-docs-start utils-interaction\n    \"user-select\": (\n      property: user-select,\n      values: all auto none\n    ),\n    \"pointer-events\": (\n      property: pointer-events,\n      class: pe,\n      values: none auto,\n    ),\n    // scss-docs-end utils-interaction\n    // scss-docs-start utils-border-radius\n    \"rounded\": (\n      property: border-radius,\n      class: rounded,\n      values: (\n        null: $border-radius,\n        0: 0,\n        1: $border-radius-sm,\n        2: $border-radius,\n        3: $border-radius-lg,\n        circle: 50%,\n        pill: $border-radius-pill\n      )\n    ),\n    \"rounded-top\": (\n      property: border-top-left-radius border-top-right-radius,\n      class: rounded-top,\n      values: (null: $border-radius)\n    ),\n    \"rounded-end\": (\n      property: border-top-right-radius border-bottom-right-radius,\n      class: rounded-end,\n      values: (null: $border-radius)\n    ),\n    \"rounded-bottom\": (\n      property: border-bottom-right-radius border-bottom-left-radius,\n      class: rounded-bottom,\n      values: (null: $border-radius)\n    ),\n    \"rounded-start\": (\n      property: border-bottom-left-radius border-top-left-radius,\n      class: rounded-start,\n      values: (null: $border-radius)\n    ),\n    // scss-docs-end utils-border-radius\n    // scss-docs-start utils-visibility\n    \"visibility\": (\n      property: visibility,\n      class: null,\n      values: (\n        visible: visible,\n        invisible: hidden,\n      )\n    )\n    // scss-docs-end utils-visibility\n  ),\n  $utilities\n);\n"
  },
  {
    "path": "vendor/bootstrap/scss/_variables.scss",
    "content": "// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n// scss-docs-start gray-color-variables\n$white:    #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black:    #000 !default;\n// scss-docs-end gray-color-variables\n\n// fusv-disable\n// scss-docs-start gray-colors-map\n$grays: (\n  \"100\": $gray-100,\n  \"200\": $gray-200,\n  \"300\": $gray-300,\n  \"400\": $gray-400,\n  \"500\": $gray-500,\n  \"600\": $gray-600,\n  \"700\": $gray-700,\n  \"800\": $gray-800,\n  \"900\": $gray-900\n) !default;\n// scss-docs-end gray-colors-map\n// fusv-enable\n\n// scss-docs-start color-variables\n$blue:    #0d6efd !default;\n$indigo:  #6610f2 !default;\n$purple:  #6f42c1 !default;\n$pink:    #d63384 !default;\n$red:     #dc3545 !default;\n$orange:  #fd7e14 !default;\n$yellow:  #ffc107 !default;\n$green:   #198754 !default;\n$teal:    #20c997 !default;\n$cyan:    #0dcaf0 !default;\n// scss-docs-end color-variables\n\n// scss-docs-start colors-map\n$colors: (\n  \"blue\":       $blue,\n  \"indigo\":     $indigo,\n  \"purple\":     $purple,\n  \"pink\":       $pink,\n  \"red\":        $red,\n  \"orange\":     $orange,\n  \"yellow\":     $yellow,\n  \"green\":      $green,\n  \"teal\":       $teal,\n  \"cyan\":       $cyan,\n  \"white\":      $white,\n  \"gray\":       $gray-600,\n  \"gray-dark\":  $gray-800\n) !default;\n// scss-docs-end colors-map\n\n// scss-docs-start theme-color-variables\n$primary:       $blue !default;\n$secondary:     $gray-600 !default;\n$success:       $green !default;\n$info:          $cyan !default;\n$warning:       $yellow !default;\n$danger:        $red !default;\n$light:         $gray-100 !default;\n$dark:          $gray-900 !default;\n// scss-docs-end theme-color-variables\n\n// scss-docs-start theme-colors-map\n$theme-colors: (\n  \"primary\":    $primary,\n  \"secondary\":  $secondary,\n  \"success\":    $success,\n  \"info\":       $info,\n  \"warning\":    $warning,\n  \"danger\":     $danger,\n  \"light\":      $light,\n  \"dark\":       $dark\n) !default;\n// scss-docs-end theme-colors-map\n\n// scss-docs-start theme-colors-rgb\n$theme-colors-rgb: map-loop($theme-colors, to-rgb, \"$value\") !default;\n// scss-docs-end theme-colors-rgb\n\n// The contrast ratio to reach against white, to determine if color changes from \"light\" to \"dark\". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.\n// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast\n$min-contrast-ratio:   4.5 !default;\n\n// Customize the light and dark text colors for use in our color contrast function.\n$color-contrast-dark:      $black !default;\n$color-contrast-light:     $white !default;\n\n// fusv-disable\n$blue-100: tint-color($blue, 80%) !default;\n$blue-200: tint-color($blue, 60%) !default;\n$blue-300: tint-color($blue, 40%) !default;\n$blue-400: tint-color($blue, 20%) !default;\n$blue-500: $blue !default;\n$blue-600: shade-color($blue, 20%) !default;\n$blue-700: shade-color($blue, 40%) !default;\n$blue-800: shade-color($blue, 60%) !default;\n$blue-900: shade-color($blue, 80%) !default;\n\n$indigo-100: tint-color($indigo, 80%) !default;\n$indigo-200: tint-color($indigo, 60%) !default;\n$indigo-300: tint-color($indigo, 40%) !default;\n$indigo-400: tint-color($indigo, 20%) !default;\n$indigo-500: $indigo !default;\n$indigo-600: shade-color($indigo, 20%) !default;\n$indigo-700: shade-color($indigo, 40%) !default;\n$indigo-800: shade-color($indigo, 60%) !default;\n$indigo-900: shade-color($indigo, 80%) !default;\n\n$purple-100: tint-color($purple, 80%) !default;\n$purple-200: tint-color($purple, 60%) !default;\n$purple-300: tint-color($purple, 40%) !default;\n$purple-400: tint-color($purple, 20%) !default;\n$purple-500: $purple !default;\n$purple-600: shade-color($purple, 20%) !default;\n$purple-700: shade-color($purple, 40%) !default;\n$purple-800: shade-color($purple, 60%) !default;\n$purple-900: shade-color($purple, 80%) !default;\n\n$pink-100: tint-color($pink, 80%) !default;\n$pink-200: tint-color($pink, 60%) !default;\n$pink-300: tint-color($pink, 40%) !default;\n$pink-400: tint-color($pink, 20%) !default;\n$pink-500: $pink !default;\n$pink-600: shade-color($pink, 20%) !default;\n$pink-700: shade-color($pink, 40%) !default;\n$pink-800: shade-color($pink, 60%) !default;\n$pink-900: shade-color($pink, 80%) !default;\n\n$red-100: tint-color($red, 80%) !default;\n$red-200: tint-color($red, 60%) !default;\n$red-300: tint-color($red, 40%) !default;\n$red-400: tint-color($red, 20%) !default;\n$red-500: $red !default;\n$red-600: shade-color($red, 20%) !default;\n$red-700: shade-color($red, 40%) !default;\n$red-800: shade-color($red, 60%) !default;\n$red-900: shade-color($red, 80%) !default;\n\n$orange-100: tint-color($orange, 80%) !default;\n$orange-200: tint-color($orange, 60%) !default;\n$orange-300: tint-color($orange, 40%) !default;\n$orange-400: tint-color($orange, 20%) !default;\n$orange-500: $orange !default;\n$orange-600: shade-color($orange, 20%) !default;\n$orange-700: shade-color($orange, 40%) !default;\n$orange-800: shade-color($orange, 60%) !default;\n$orange-900: shade-color($orange, 80%) !default;\n\n$yellow-100: tint-color($yellow, 80%) !default;\n$yellow-200: tint-color($yellow, 60%) !default;\n$yellow-300: tint-color($yellow, 40%) !default;\n$yellow-400: tint-color($yellow, 20%) !default;\n$yellow-500: $yellow !default;\n$yellow-600: shade-color($yellow, 20%) !default;\n$yellow-700: shade-color($yellow, 40%) !default;\n$yellow-800: shade-color($yellow, 60%) !default;\n$yellow-900: shade-color($yellow, 80%) !default;\n\n$green-100: tint-color($green, 80%) !default;\n$green-200: tint-color($green, 60%) !default;\n$green-300: tint-color($green, 40%) !default;\n$green-400: tint-color($green, 20%) !default;\n$green-500: $green !default;\n$green-600: shade-color($green, 20%) !default;\n$green-700: shade-color($green, 40%) !default;\n$green-800: shade-color($green, 60%) !default;\n$green-900: shade-color($green, 80%) !default;\n\n$teal-100: tint-color($teal, 80%) !default;\n$teal-200: tint-color($teal, 60%) !default;\n$teal-300: tint-color($teal, 40%) !default;\n$teal-400: tint-color($teal, 20%) !default;\n$teal-500: $teal !default;\n$teal-600: shade-color($teal, 20%) !default;\n$teal-700: shade-color($teal, 40%) !default;\n$teal-800: shade-color($teal, 60%) !default;\n$teal-900: shade-color($teal, 80%) !default;\n\n$cyan-100: tint-color($cyan, 80%) !default;\n$cyan-200: tint-color($cyan, 60%) !default;\n$cyan-300: tint-color($cyan, 40%) !default;\n$cyan-400: tint-color($cyan, 20%) !default;\n$cyan-500: $cyan !default;\n$cyan-600: shade-color($cyan, 20%) !default;\n$cyan-700: shade-color($cyan, 40%) !default;\n$cyan-800: shade-color($cyan, 60%) !default;\n$cyan-900: shade-color($cyan, 80%) !default;\n\n$blues: (\n  \"blue-100\": $blue-100,\n  \"blue-200\": $blue-200,\n  \"blue-300\": $blue-300,\n  \"blue-400\": $blue-400,\n  \"blue-500\": $blue-500,\n  \"blue-600\": $blue-600,\n  \"blue-700\": $blue-700,\n  \"blue-800\": $blue-800,\n  \"blue-900\": $blue-900\n) !default;\n\n$indigos: (\n  \"indigo-100\": $indigo-100,\n  \"indigo-200\": $indigo-200,\n  \"indigo-300\": $indigo-300,\n  \"indigo-400\": $indigo-400,\n  \"indigo-500\": $indigo-500,\n  \"indigo-600\": $indigo-600,\n  \"indigo-700\": $indigo-700,\n  \"indigo-800\": $indigo-800,\n  \"indigo-900\": $indigo-900\n) !default;\n\n$purples: (\n  \"purple-100\": $purple-200,\n  \"purple-200\": $purple-100,\n  \"purple-300\": $purple-300,\n  \"purple-400\": $purple-400,\n  \"purple-500\": $purple-500,\n  \"purple-600\": $purple-600,\n  \"purple-700\": $purple-700,\n  \"purple-800\": $purple-800,\n  \"purple-900\": $purple-900\n) !default;\n\n$pinks: (\n  \"pink-100\": $pink-100,\n  \"pink-200\": $pink-200,\n  \"pink-300\": $pink-300,\n  \"pink-400\": $pink-400,\n  \"pink-500\": $pink-500,\n  \"pink-600\": $pink-600,\n  \"pink-700\": $pink-700,\n  \"pink-800\": $pink-800,\n  \"pink-900\": $pink-900\n) !default;\n\n$reds: (\n  \"red-100\": $red-100,\n  \"red-200\": $red-200,\n  \"red-300\": $red-300,\n  \"red-400\": $red-400,\n  \"red-500\": $red-500,\n  \"red-600\": $red-600,\n  \"red-700\": $red-700,\n  \"red-800\": $red-800,\n  \"red-900\": $red-900\n) !default;\n\n$oranges: (\n  \"orange-100\": $orange-100,\n  \"orange-200\": $orange-200,\n  \"orange-300\": $orange-300,\n  \"orange-400\": $orange-400,\n  \"orange-500\": $orange-500,\n  \"orange-600\": $orange-600,\n  \"orange-700\": $orange-700,\n  \"orange-800\": $orange-800,\n  \"orange-900\": $orange-900\n) !default;\n\n$yellows: (\n  \"yellow-100\": $yellow-100,\n  \"yellow-200\": $yellow-200,\n  \"yellow-300\": $yellow-300,\n  \"yellow-400\": $yellow-400,\n  \"yellow-500\": $yellow-500,\n  \"yellow-600\": $yellow-600,\n  \"yellow-700\": $yellow-700,\n  \"yellow-800\": $yellow-800,\n  \"yellow-900\": $yellow-900\n) !default;\n\n$greens: (\n  \"green-100\": $green-100,\n  \"green-200\": $green-200,\n  \"green-300\": $green-300,\n  \"green-400\": $green-400,\n  \"green-500\": $green-500,\n  \"green-600\": $green-600,\n  \"green-700\": $green-700,\n  \"green-800\": $green-800,\n  \"green-900\": $green-900\n) !default;\n\n$teals: (\n  \"teal-100\": $teal-100,\n  \"teal-200\": $teal-200,\n  \"teal-300\": $teal-300,\n  \"teal-400\": $teal-400,\n  \"teal-500\": $teal-500,\n  \"teal-600\": $teal-600,\n  \"teal-700\": $teal-700,\n  \"teal-800\": $teal-800,\n  \"teal-900\": $teal-900\n) !default;\n\n$cyans: (\n  \"cyan-100\": $cyan-100,\n  \"cyan-200\": $cyan-200,\n  \"cyan-300\": $cyan-300,\n  \"cyan-400\": $cyan-400,\n  \"cyan-500\": $cyan-500,\n  \"cyan-600\": $cyan-600,\n  \"cyan-700\": $cyan-700,\n  \"cyan-800\": $cyan-800,\n  \"cyan-900\": $cyan-900\n) !default;\n// fusv-enable\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n  (\"<\", \"%3c\"),\n  (\">\", \"%3e\"),\n  (\"#\", \"%23\"),\n  (\"(\", \"%28\"),\n  (\")\", \"%29\"),\n) !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret:                true !default;\n$enable-rounded:              true !default;\n$enable-shadows:              false !default;\n$enable-gradients:            false !default;\n$enable-transitions:          true !default;\n$enable-reduced-motion:       true !default;\n$enable-smooth-scroll:        true !default;\n$enable-grid-classes:         true !default;\n$enable-cssgrid:              false !default;\n$enable-button-pointers:      true !default;\n$enable-rfs:                  true !default;\n$enable-validation-icons:     true !default;\n$enable-negative-margins:     false !default;\n$enable-deprecation-messages: true !default;\n$enable-important-utilities:  true !default;\n\n// Prefix for :root CSS variables\n\n$variable-prefix:             bs- !default;\n\n// Gradient\n//\n// The gradient which is added to components if `$enable-gradients` is `true`\n// This gradient is also added to elements with `.bg-gradient`\n// scss-docs-start variable-gradient\n$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;\n// scss-docs-end variable-gradient\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n// scss-docs-start spacer-variables-maps\n$spacer: 1rem !default;\n$spacers: (\n  0: 0,\n  1: $spacer * .25,\n  2: $spacer * .5,\n  3: $spacer,\n  4: $spacer * 1.5,\n  5: $spacer * 3,\n) !default;\n\n$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;\n// scss-docs-end spacer-variables-maps\n\n// Position\n//\n// Define the edge positioning anchors of the position utilities.\n\n// scss-docs-start position-map\n$position-values: (\n  0: 0,\n  50: 50%,\n  100: 100%\n) !default;\n// scss-docs-end position-map\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg:                   $white !default;\n$body-color:                $gray-900 !default;\n$body-text-align:           null !default;\n\n// Utilities maps\n//\n// Extends the default `$theme-colors` maps to help create our utilities.\n\n// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign.\n// scss-docs-start utilities-colors\n$utilities-colors: $theme-colors-rgb !default;\n// scss-docs-end utilities-colors\n\n// scss-docs-start utilities-text-colors\n$utilities-text: map-merge(\n  $utilities-colors,\n  (\n    \"black\": to-rgb($black),\n    \"white\": to-rgb($white),\n    \"body\": to-rgb($body-color)\n  )\n) !default;\n$utilities-text-colors: map-loop($utilities-text, rgba-css-var, \"$key\", \"text\") !default;\n// scss-docs-end utilities-text-colors\n\n// scss-docs-start utilities-bg-colors\n$utilities-bg: map-merge(\n  $utilities-colors,\n  (\n    \"black\": to-rgb($black),\n    \"white\": to-rgb($white),\n    \"body\": to-rgb($body-bg)\n  )\n) !default;\n$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, \"$key\", \"bg\") !default;\n// scss-docs-end utilities-bg-colors\n\n// Links\n//\n// Style anchor elements.\n\n$link-color:                              $primary !default;\n$link-decoration:                         underline !default;\n$link-shade-percentage:                   20% !default;\n$link-hover-color:                        shift-color($link-color, $link-shade-percentage) !default;\n$link-hover-decoration:                   null !default;\n\n$stretched-link-pseudo-element:           after !default;\n$stretched-link-z-index:                  1 !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom:   1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n// scss-docs-start grid-breakpoints\n$grid-breakpoints: (\n  xs: 0,\n  sm: 576px,\n  md: 768px,\n  lg: 992px,\n  xl: 1200px,\n  xxl: 1400px\n) !default;\n// scss-docs-end grid-breakpoints\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n// scss-docs-start container-max-widths\n$container-max-widths: (\n  sm: 540px,\n  md: 720px,\n  lg: 960px,\n  xl: 1140px,\n  xxl: 1320px\n) !default;\n// scss-docs-end container-max-widths\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns:                12 !default;\n$grid-gutter-width:           1.5rem !default;\n$grid-row-columns:            6 !default;\n\n$gutters: $spacers !default;\n\n// Container padding\n\n$container-padding-x: $grid-gutter-width * .5 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n// scss-docs-start border-variables\n$border-width:                1px !default;\n$border-widths: (\n  1: 1px,\n  2: 2px,\n  3: 3px,\n  4: 4px,\n  5: 5px\n) !default;\n\n$border-color:                $gray-300 !default;\n// scss-docs-end border-variables\n\n// scss-docs-start border-radius-variables\n$border-radius:               .25rem !default;\n$border-radius-sm:            .2rem !default;\n$border-radius-lg:            .3rem !default;\n$border-radius-pill:          50rem !default;\n// scss-docs-end border-radius-variables\n\n// scss-docs-start box-shadow-variables\n$box-shadow:                  0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-sm:               0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow-lg:               0 1rem 3rem rgba($black, .175) !default;\n$box-shadow-inset:            inset 0 1px 2px rgba($black, .075) !default;\n// scss-docs-end box-shadow-variables\n\n$component-active-color:      $white !default;\n$component-active-bg:         $primary !default;\n\n// scss-docs-start caret-variables\n$caret-width:                 .3em !default;\n$caret-vertical-align:        $caret-width * .85 !default;\n$caret-spacing:               $caret-width * .85 !default;\n// scss-docs-end caret-variables\n\n$transition-base:             all .2s ease-in-out !default;\n$transition-fade:             opacity .15s linear !default;\n// scss-docs-start collapse-transition\n$transition-collapse:         height .35s ease !default;\n$transition-collapse-width:   width .35s ease !default;\n// scss-docs-end collapse-transition\n\n// stylelint-disable function-disallowed-list\n// scss-docs-start aspect-ratios\n$aspect-ratios: (\n  \"1x1\": 100%,\n  \"4x3\": calc(3 / 4 * 100%),\n  \"16x9\": calc(9 / 16 * 100%),\n  \"21x9\": calc(9 / 21 * 100%)\n) !default;\n// scss-docs-end aspect-ratios\n// stylelint-enable function-disallowed-list\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// scss-docs-start font-variables\n// stylelint-disable value-keyword-case\n$font-family-sans-serif:      system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace:       SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n// stylelint-enable value-keyword-case\n$font-family-base:            var(--#{$variable-prefix}font-sans-serif) !default;\n$font-family-code:            var(--#{$variable-prefix}font-monospace) !default;\n\n// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins\n// $font-size-base affects the font size of the body text\n$font-size-root:              null !default;\n$font-size-base:              1rem !default; // Assumes the browser default, typically `16px`\n$font-size-sm:                $font-size-base * .875 !default;\n$font-size-lg:                $font-size-base * 1.25 !default;\n\n$font-weight-lighter:         lighter !default;\n$font-weight-light:           300 !default;\n$font-weight-normal:          400 !default;\n$font-weight-bold:            700 !default;\n$font-weight-bolder:          bolder !default;\n\n$font-weight-base:            $font-weight-normal !default;\n\n$line-height-base:            1.5 !default;\n$line-height-sm:              1.25 !default;\n$line-height-lg:              2 !default;\n\n$h1-font-size:                $font-size-base * 2.5 !default;\n$h2-font-size:                $font-size-base * 2 !default;\n$h3-font-size:                $font-size-base * 1.75 !default;\n$h4-font-size:                $font-size-base * 1.5 !default;\n$h5-font-size:                $font-size-base * 1.25 !default;\n$h6-font-size:                $font-size-base !default;\n// scss-docs-end font-variables\n\n// scss-docs-start font-sizes\n$font-sizes: (\n  1: $h1-font-size,\n  2: $h2-font-size,\n  3: $h3-font-size,\n  4: $h4-font-size,\n  5: $h5-font-size,\n  6: $h6-font-size\n) !default;\n// scss-docs-end font-sizes\n\n// scss-docs-start headings-variables\n$headings-margin-bottom:      $spacer * .5 !default;\n$headings-font-family:        null !default;\n$headings-font-style:         null !default;\n$headings-font-weight:        500 !default;\n$headings-line-height:        1.2 !default;\n$headings-color:              null !default;\n// scss-docs-end headings-variables\n\n// scss-docs-start display-headings\n$display-font-sizes: (\n  1: 5rem,\n  2: 4.5rem,\n  3: 4rem,\n  4: 3.5rem,\n  5: 3rem,\n  6: 2.5rem\n) !default;\n\n$display-font-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n// scss-docs-end display-headings\n\n// scss-docs-start type-variables\n$lead-font-size:              $font-size-base * 1.25 !default;\n$lead-font-weight:            300 !default;\n\n$small-font-size:             .875em !default;\n\n$sub-sup-font-size:           .75em !default;\n\n$text-muted:                  $gray-600 !default;\n\n$initialism-font-size:        $small-font-size !default;\n\n$blockquote-margin-y:         $spacer !default;\n$blockquote-font-size:        $font-size-base * 1.25 !default;\n$blockquote-footer-color:     $gray-600 !default;\n$blockquote-footer-font-size: $small-font-size !default;\n\n$hr-margin-y:                 $spacer !default;\n$hr-color:                    inherit !default;\n$hr-height:                   $border-width !default;\n$hr-opacity:                  .25 !default;\n\n$legend-margin-bottom:        .5rem !default;\n$legend-font-size:            1.5rem !default;\n$legend-font-weight:          null !default;\n\n$mark-padding:                .2em !default;\n\n$dt-font-weight:              $font-weight-bold !default;\n\n$nested-kbd-font-weight:      $font-weight-bold !default;\n\n$list-inline-padding:         .5rem !default;\n\n$mark-bg:                     #fcf8e3 !default;\n// scss-docs-end type-variables\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n// scss-docs-start table-variables\n$table-cell-padding-y:        .5rem !default;\n$table-cell-padding-x:        .5rem !default;\n$table-cell-padding-y-sm:     .25rem !default;\n$table-cell-padding-x-sm:     .25rem !default;\n\n$table-cell-vertical-align:   top !default;\n\n$table-color:                 $body-color !default;\n$table-bg:                    transparent !default;\n$table-accent-bg:             transparent !default;\n\n$table-th-font-weight:        null !default;\n\n$table-striped-color:         $table-color !default;\n$table-striped-bg-factor:     .05 !default;\n$table-striped-bg:            rgba($black, $table-striped-bg-factor) !default;\n\n$table-active-color:          $table-color !default;\n$table-active-bg-factor:      .1 !default;\n$table-active-bg:             rgba($black, $table-active-bg-factor) !default;\n\n$table-hover-color:           $table-color !default;\n$table-hover-bg-factor:       .075 !default;\n$table-hover-bg:              rgba($black, $table-hover-bg-factor) !default;\n\n$table-border-factor:         .1 !default;\n$table-border-width:          $border-width !default;\n$table-border-color:          $border-color !default;\n\n$table-striped-order:         odd !default;\n\n$table-group-separator-color: currentColor !default;\n\n$table-caption-color:         $text-muted !default;\n\n$table-bg-scale:              -80% !default;\n// scss-docs-end table-variables\n\n// scss-docs-start table-loop\n$table-variants: (\n  \"primary\":    shift-color($primary, $table-bg-scale),\n  \"secondary\":  shift-color($secondary, $table-bg-scale),\n  \"success\":    shift-color($success, $table-bg-scale),\n  \"info\":       shift-color($info, $table-bg-scale),\n  \"warning\":    shift-color($warning, $table-bg-scale),\n  \"danger\":     shift-color($danger, $table-bg-scale),\n  \"light\":      $light,\n  \"dark\":       $dark,\n) !default;\n// scss-docs-end table-loop\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n// scss-docs-start input-btn-variables\n$input-btn-padding-y:         .375rem !default;\n$input-btn-padding-x:         .75rem !default;\n$input-btn-font-family:       null !default;\n$input-btn-font-size:         $font-size-base !default;\n$input-btn-line-height:       $line-height-base !default;\n\n$input-btn-focus-width:         .25rem !default;\n$input-btn-focus-color-opacity: .25 !default;\n$input-btn-focus-color:         rgba($component-active-bg, $input-btn-focus-color-opacity) !default;\n$input-btn-focus-blur:          0 !default;\n$input-btn-focus-box-shadow:    0 0 $input-btn-focus-blur $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm:      .25rem !default;\n$input-btn-padding-x-sm:      .5rem !default;\n$input-btn-font-size-sm:      $font-size-sm !default;\n\n$input-btn-padding-y-lg:      .5rem !default;\n$input-btn-padding-x-lg:      1rem !default;\n$input-btn-font-size-lg:      $font-size-lg !default;\n\n$input-btn-border-width:      $border-width !default;\n// scss-docs-end input-btn-variables\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n// scss-docs-start btn-variables\n$btn-padding-y:               $input-btn-padding-y !default;\n$btn-padding-x:               $input-btn-padding-x !default;\n$btn-font-family:             $input-btn-font-family !default;\n$btn-font-size:               $input-btn-font-size !default;\n$btn-line-height:             $input-btn-line-height !default;\n$btn-white-space:             null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm:            $input-btn-padding-y-sm !default;\n$btn-padding-x-sm:            $input-btn-padding-x-sm !default;\n$btn-font-size-sm:            $input-btn-font-size-sm !default;\n\n$btn-padding-y-lg:            $input-btn-padding-y-lg !default;\n$btn-padding-x-lg:            $input-btn-padding-x-lg !default;\n$btn-font-size-lg:            $input-btn-font-size-lg !default;\n\n$btn-border-width:            $input-btn-border-width !default;\n\n$btn-font-weight:             $font-weight-normal !default;\n$btn-box-shadow:              inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width:             $input-btn-focus-width !default;\n$btn-focus-box-shadow:        $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity:        .65 !default;\n$btn-active-box-shadow:       inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-color:              $link-color !default;\n$btn-link-hover-color:        $link-hover-color !default;\n$btn-link-disabled-color:     $gray-600 !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius:           $border-radius !default;\n$btn-border-radius-sm:        $border-radius-sm !default;\n$btn-border-radius-lg:        $border-radius-lg !default;\n\n$btn-transition:              color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$btn-hover-bg-shade-amount:       15% !default;\n$btn-hover-bg-tint-amount:        15% !default;\n$btn-hover-border-shade-amount:   20% !default;\n$btn-hover-border-tint-amount:    10% !default;\n$btn-active-bg-shade-amount:      20% !default;\n$btn-active-bg-tint-amount:       20% !default;\n$btn-active-border-shade-amount:  25% !default;\n$btn-active-border-tint-amount:   10% !default;\n// scss-docs-end btn-variables\n\n\n// Forms\n\n// scss-docs-start form-text-variables\n$form-text-margin-top:                  .25rem !default;\n$form-text-font-size:                   $small-font-size !default;\n$form-text-font-style:                  null !default;\n$form-text-font-weight:                 null !default;\n$form-text-color:                       $text-muted !default;\n// scss-docs-end form-text-variables\n\n// scss-docs-start form-label-variables\n$form-label-margin-bottom:              .5rem !default;\n$form-label-font-size:                  null !default;\n$form-label-font-style:                 null !default;\n$form-label-font-weight:                null !default;\n$form-label-color:                      null !default;\n// scss-docs-end form-label-variables\n\n// scss-docs-start form-input-variables\n$input-padding-y:                       $input-btn-padding-y !default;\n$input-padding-x:                       $input-btn-padding-x !default;\n$input-font-family:                     $input-btn-font-family !default;\n$input-font-size:                       $input-btn-font-size !default;\n$input-font-weight:                     $font-weight-base !default;\n$input-line-height:                     $input-btn-line-height !default;\n\n$input-padding-y-sm:                    $input-btn-padding-y-sm !default;\n$input-padding-x-sm:                    $input-btn-padding-x-sm !default;\n$input-font-size-sm:                    $input-btn-font-size-sm !default;\n\n$input-padding-y-lg:                    $input-btn-padding-y-lg !default;\n$input-padding-x-lg:                    $input-btn-padding-x-lg !default;\n$input-font-size-lg:                    $input-btn-font-size-lg !default;\n\n$input-bg:                              $body-bg !default;\n$input-disabled-bg:                     $gray-200 !default;\n$input-disabled-border-color:           null !default;\n\n$input-color:                           $body-color !default;\n$input-border-color:                    $gray-400 !default;\n$input-border-width:                    $input-btn-border-width !default;\n$input-box-shadow:                      $box-shadow-inset !default;\n\n$input-border-radius:                   $border-radius !default;\n$input-border-radius-sm:                $border-radius-sm !default;\n$input-border-radius-lg:                $border-radius-lg !default;\n\n$input-focus-bg:                        $input-bg !default;\n$input-focus-border-color:              tint-color($component-active-bg, 50%) !default;\n$input-focus-color:                     $input-color !default;\n$input-focus-width:                     $input-btn-focus-width !default;\n$input-focus-box-shadow:                $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color:               $gray-600 !default;\n$input-plaintext-color:                 $body-color !default;\n\n$input-height-border:                   $input-border-width * 2 !default;\n\n$input-height-inner:                    add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half:               add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter:            add($input-line-height * .25em, $input-padding-y * .5) !default;\n\n$input-height:                          add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm:                       add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg:                       add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition:                      border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-color-width:                      3rem !default;\n// scss-docs-end form-input-variables\n\n// scss-docs-start form-check-variables\n$form-check-input-width:                  1em !default;\n$form-check-min-height:                   $font-size-base * $line-height-base !default;\n$form-check-padding-start:                $form-check-input-width + .5em !default;\n$form-check-margin-bottom:                .125rem !default;\n$form-check-label-color:                  null !default;\n$form-check-label-cursor:                 null !default;\n$form-check-transition:                   null !default;\n\n$form-check-input-active-filter:          brightness(90%) !default;\n\n$form-check-input-bg:                     $input-bg !default;\n$form-check-input-border:                 1px solid rgba($black, .25) !default;\n$form-check-input-border-radius:          .25em !default;\n$form-check-radio-border-radius:          50% !default;\n$form-check-input-focus-border:           $input-focus-border-color !default;\n$form-check-input-focus-box-shadow:       $input-btn-focus-box-shadow !default;\n\n$form-check-input-checked-color:          $component-active-color !default;\n$form-check-input-checked-bg-color:       $component-active-bg !default;\n$form-check-input-checked-border-color:   $form-check-input-checked-bg-color !default;\n$form-check-input-checked-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-checked-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/></svg>\") !default;\n$form-check-radio-checked-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='2' fill='#{$form-check-input-checked-color}'/></svg>\") !default;\n\n$form-check-input-indeterminate-color:          $component-active-color !default;\n$form-check-input-indeterminate-bg-color:       $component-active-bg !default;\n$form-check-input-indeterminate-border-color:   $form-check-input-indeterminate-bg-color !default;\n$form-check-input-indeterminate-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-indeterminate-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/></svg>\") !default;\n\n$form-check-input-disabled-opacity:        .5 !default;\n$form-check-label-disabled-opacity:        $form-check-input-disabled-opacity !default;\n$form-check-btn-check-disabled-opacity:    $btn-disabled-opacity !default;\n\n$form-check-inline-margin-end:    1rem !default;\n// scss-docs-end form-check-variables\n\n// scss-docs-start form-switch-variables\n$form-switch-color:               rgba($black, .25) !default;\n$form-switch-width:               2em !default;\n$form-switch-padding-start:       $form-switch-width + .5em !default;\n$form-switch-bg-image:            url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>\") !default;\n$form-switch-border-radius:       $form-switch-width !default;\n$form-switch-transition:          background-position .15s ease-in-out !default;\n\n$form-switch-focus-color:         $input-focus-border-color !default;\n$form-switch-focus-bg-image:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>\") !default;\n\n$form-switch-checked-color:       $component-active-color !default;\n$form-switch-checked-bg-image:    url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>\") !default;\n$form-switch-checked-bg-position: right center !default;\n// scss-docs-end form-switch-variables\n\n// scss-docs-start input-group-variables\n$input-group-addon-padding-y:           $input-padding-y !default;\n$input-group-addon-padding-x:           $input-padding-x !default;\n$input-group-addon-font-weight:         $input-font-weight !default;\n$input-group-addon-color:               $input-color !default;\n$input-group-addon-bg:                  $gray-200 !default;\n$input-group-addon-border-color:        $input-border-color !default;\n// scss-docs-end input-group-variables\n\n// scss-docs-start form-select-variables\n$form-select-padding-y:             $input-padding-y !default;\n$form-select-padding-x:             $input-padding-x !default;\n$form-select-font-family:           $input-font-family !default;\n$form-select-font-size:             $input-font-size !default;\n$form-select-indicator-padding:     $form-select-padding-x * 3 !default; // Extra padding for background-image\n$form-select-font-weight:           $input-font-weight !default;\n$form-select-line-height:           $input-line-height !default;\n$form-select-color:                 $input-color !default;\n$form-select-bg:                    $input-bg !default;\n$form-select-disabled-color:        null !default;\n$form-select-disabled-bg:           $gray-200 !default;\n$form-select-disabled-border-color: $input-disabled-border-color !default;\n$form-select-bg-position:           right $form-select-padding-x center !default;\n$form-select-bg-size:               16px 12px !default; // In pixels because image dimensions\n$form-select-indicator-color:       $gray-800 !default;\n$form-select-indicator:             url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>\") !default;\n\n$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;\n$form-select-feedback-icon-position:    center right $form-select-indicator-padding !default;\n$form-select-feedback-icon-size:        $input-height-inner-half $input-height-inner-half !default;\n\n$form-select-border-width:        $input-border-width !default;\n$form-select-border-color:        $input-border-color !default;\n$form-select-border-radius:       $input-border-radius !default;\n$form-select-box-shadow:          $box-shadow-inset !default;\n\n$form-select-focus-border-color:  $input-focus-border-color !default;\n$form-select-focus-width:         $input-focus-width !default;\n$form-select-focus-box-shadow:    0 0 0 $form-select-focus-width $input-btn-focus-color !default;\n\n$form-select-padding-y-sm:        $input-padding-y-sm !default;\n$form-select-padding-x-sm:        $input-padding-x-sm !default;\n$form-select-font-size-sm:        $input-font-size-sm !default;\n$form-select-border-radius-sm:    $input-border-radius-sm !default;\n\n$form-select-padding-y-lg:        $input-padding-y-lg !default;\n$form-select-padding-x-lg:        $input-padding-x-lg !default;\n$form-select-font-size-lg:        $input-font-size-lg !default;\n$form-select-border-radius-lg:    $input-border-radius-lg !default;\n\n$form-select-transition:          $input-transition !default;\n// scss-docs-end form-select-variables\n\n// scss-docs-start form-range-variables\n$form-range-track-width:          100% !default;\n$form-range-track-height:         .5rem !default;\n$form-range-track-cursor:         pointer !default;\n$form-range-track-bg:             $gray-300 !default;\n$form-range-track-border-radius:  1rem !default;\n$form-range-track-box-shadow:     $box-shadow-inset !default;\n\n$form-range-thumb-width:                   1rem !default;\n$form-range-thumb-height:                  $form-range-thumb-width !default;\n$form-range-thumb-bg:                      $component-active-bg !default;\n$form-range-thumb-border:                  0 !default;\n$form-range-thumb-border-radius:           1rem !default;\n$form-range-thumb-box-shadow:              0 .1rem .25rem rgba($black, .1) !default;\n$form-range-thumb-focus-box-shadow:        0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$form-range-thumb-focus-box-shadow-width:  $input-focus-width !default; // For focus box shadow issue in Edge\n$form-range-thumb-active-bg:               tint-color($component-active-bg, 70%) !default;\n$form-range-thumb-disabled-bg:             $gray-500 !default;\n$form-range-thumb-transition:              background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n// scss-docs-end form-range-variables\n\n// scss-docs-start form-file-variables\n$form-file-button-color:          $input-color !default;\n$form-file-button-bg:             $input-group-addon-bg !default;\n$form-file-button-hover-bg:       shade-color($form-file-button-bg, 5%) !default;\n// scss-docs-end form-file-variables\n\n// scss-docs-start form-floating-variables\n$form-floating-height:            add(3.5rem, $input-height-border) !default;\n$form-floating-line-height:       1.25 !default;\n$form-floating-padding-x:         $input-padding-x !default;\n$form-floating-padding-y:         1rem !default;\n$form-floating-input-padding-t:   1.625rem !default;\n$form-floating-input-padding-b:   .625rem !default;\n$form-floating-label-opacity:     .65 !default;\n$form-floating-label-transform:   scale(.85) translateY(-.5rem) translateX(.15rem) !default;\n$form-floating-transition:        opacity .1s ease-in-out, transform .1s ease-in-out !default;\n// scss-docs-end form-floating-variables\n\n// Form validation\n\n// scss-docs-start form-feedback-variables\n$form-feedback-margin-top:          $form-text-margin-top !default;\n$form-feedback-font-size:           $form-text-font-size !default;\n$form-feedback-font-style:          $form-text-font-style !default;\n$form-feedback-valid-color:         $success !default;\n$form-feedback-invalid-color:       $danger !default;\n\n$form-feedback-icon-valid-color:    $form-feedback-valid-color !default;\n$form-feedback-icon-valid:          url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color:  $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid:        url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n// scss-docs-end form-feedback-variables\n\n// scss-docs-start form-validation-states\n$form-validation-states: (\n  \"valid\": (\n    \"color\": $form-feedback-valid-color,\n    \"icon\": $form-feedback-icon-valid\n  ),\n  \"invalid\": (\n    \"color\": $form-feedback-invalid-color,\n    \"icon\": $form-feedback-icon-invalid\n  )\n) !default;\n// scss-docs-end form-validation-states\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n// scss-docs-start zindex-stack\n$zindex-dropdown:                   1000 !default;\n$zindex-sticky:                     1020 !default;\n$zindex-fixed:                      1030 !default;\n$zindex-offcanvas-backdrop:         1040 !default;\n$zindex-offcanvas:                  1045 !default;\n$zindex-modal-backdrop:             1050 !default;\n$zindex-modal:                      1055 !default;\n$zindex-popover:                    1070 !default;\n$zindex-tooltip:                    1080 !default;\n// scss-docs-end zindex-stack\n\n\n// Navs\n\n// scss-docs-start nav-variables\n$nav-link-padding-y:                .5rem !default;\n$nav-link-padding-x:                1rem !default;\n$nav-link-font-size:                null !default;\n$nav-link-font-weight:              null !default;\n$nav-link-color:                    $link-color !default;\n$nav-link-hover-color:              $link-hover-color !default;\n$nav-link-transition:               color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;\n$nav-link-disabled-color:           $gray-600 !default;\n\n$nav-tabs-border-color:             $gray-300 !default;\n$nav-tabs-border-width:             $border-width !default;\n$nav-tabs-border-radius:            $border-radius !default;\n$nav-tabs-link-hover-border-color:  $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color:        $gray-700 !default;\n$nav-tabs-link-active-bg:           $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius:           $border-radius !default;\n$nav-pills-link-active-color:       $component-active-color !default;\n$nav-pills-link-active-bg:          $component-active-bg !default;\n// scss-docs-end nav-variables\n\n\n// Navbar\n\n// scss-docs-start navbar-variables\n$navbar-padding-y:                  $spacer * .5 !default;\n$navbar-padding-x:                  null !default;\n\n$navbar-nav-link-padding-x:         .5rem !default;\n\n$navbar-brand-font-size:            $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height:                   $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height:               $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y:            ($nav-link-height - $navbar-brand-height) * .5 !default;\n$navbar-brand-margin-end:           1rem !default;\n\n$navbar-toggler-padding-y:          .25rem !default;\n$navbar-toggler-padding-x:          .75rem !default;\n$navbar-toggler-font-size:          $font-size-lg !default;\n$navbar-toggler-border-radius:      $btn-border-radius !default;\n$navbar-toggler-focus-width:        $btn-focus-width !default;\n$navbar-toggler-transition:         box-shadow .15s ease-in-out !default;\n// scss-docs-end navbar-variables\n\n// scss-docs-start navbar-theme-variables\n$navbar-dark-color:                 rgba($white, .55) !default;\n$navbar-dark-hover-color:           rgba($white, .75) !default;\n$navbar-dark-active-color:          $white !default;\n$navbar-dark-disabled-color:        rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color:  rgba($white, .1) !default;\n\n$navbar-light-color:                rgba($black, .55) !default;\n$navbar-light-hover-color:          rgba($black, .7) !default;\n$navbar-light-active-color:         rgba($black, .9) !default;\n$navbar-light-disabled-color:       rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color:                $navbar-light-active-color !default;\n$navbar-light-brand-hover-color:          $navbar-light-active-color !default;\n$navbar-dark-brand-color:                 $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color:           $navbar-dark-active-color !default;\n// scss-docs-end navbar-theme-variables\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n// scss-docs-start dropdown-variables\n$dropdown-min-width:                10rem !default;\n$dropdown-padding-x:                0 !default;\n$dropdown-padding-y:                .5rem !default;\n$dropdown-spacer:                   .125rem !default;\n$dropdown-font-size:                $font-size-base !default;\n$dropdown-color:                    $body-color !default;\n$dropdown-bg:                       $white !default;\n$dropdown-border-color:             rgba($black, .15) !default;\n$dropdown-border-radius:            $border-radius !default;\n$dropdown-border-width:             $border-width !default;\n$dropdown-inner-border-radius:      subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg:               $dropdown-border-color !default;\n$dropdown-divider-margin-y:         $spacer * .5 !default;\n$dropdown-box-shadow:               $box-shadow !default;\n\n$dropdown-link-color:               $gray-900 !default;\n$dropdown-link-hover-color:         shade-color($dropdown-link-color, 10%) !default;\n$dropdown-link-hover-bg:            $gray-200 !default;\n\n$dropdown-link-active-color:        $component-active-color !default;\n$dropdown-link-active-bg:           $component-active-bg !default;\n\n$dropdown-link-disabled-color:      $gray-500 !default;\n\n$dropdown-item-padding-y:           $spacer * .25 !default;\n$dropdown-item-padding-x:           $spacer !default;\n\n$dropdown-header-color:             $gray-600 !default;\n$dropdown-header-padding:           $dropdown-padding-y $dropdown-item-padding-x !default;\n// scss-docs-end dropdown-variables\n\n// scss-docs-start dropdown-dark-variables\n$dropdown-dark-color:               $gray-300 !default;\n$dropdown-dark-bg:                  $gray-800 !default;\n$dropdown-dark-border-color:        $dropdown-border-color !default;\n$dropdown-dark-divider-bg:          $dropdown-divider-bg !default;\n$dropdown-dark-box-shadow:          null !default;\n$dropdown-dark-link-color:          $dropdown-dark-color !default;\n$dropdown-dark-link-hover-color:    $white !default;\n$dropdown-dark-link-hover-bg:       rgba($white, .15) !default;\n$dropdown-dark-link-active-color:   $dropdown-link-active-color !default;\n$dropdown-dark-link-active-bg:      $dropdown-link-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-500 !default;\n$dropdown-dark-header-color:        $gray-500 !default;\n// scss-docs-end dropdown-dark-variables\n\n\n// Pagination\n\n// scss-docs-start pagination-variables\n$pagination-padding-y:              .375rem !default;\n$pagination-padding-x:              .75rem !default;\n$pagination-padding-y-sm:           .25rem !default;\n$pagination-padding-x-sm:           .5rem !default;\n$pagination-padding-y-lg:           .75rem !default;\n$pagination-padding-x-lg:           1.5rem !default;\n\n$pagination-color:                  $link-color !default;\n$pagination-bg:                     $white !default;\n$pagination-border-width:           $border-width !default;\n$pagination-border-radius:          $border-radius !default;\n$pagination-margin-start:           -$pagination-border-width !default;\n$pagination-border-color:           $gray-300 !default;\n\n$pagination-focus-color:            $link-hover-color !default;\n$pagination-focus-bg:               $gray-200 !default;\n$pagination-focus-box-shadow:       $input-btn-focus-box-shadow !default;\n$pagination-focus-outline:          0 !default;\n\n$pagination-hover-color:            $link-hover-color !default;\n$pagination-hover-bg:               $gray-200 !default;\n$pagination-hover-border-color:     $gray-300 !default;\n\n$pagination-active-color:           $component-active-color !default;\n$pagination-active-bg:              $component-active-bg !default;\n$pagination-active-border-color:    $pagination-active-bg !default;\n\n$pagination-disabled-color:         $gray-600 !default;\n$pagination-disabled-bg:            $white !default;\n$pagination-disabled-border-color:  $gray-300 !default;\n\n$pagination-transition:              color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$pagination-border-radius-sm:       $border-radius-sm !default;\n$pagination-border-radius-lg:       $border-radius-lg !default;\n// scss-docs-end pagination-variables\n\n\n// Placeholders\n\n// scss-docs-start placeholders\n$placeholder-opacity-max:           .5 !default;\n$placeholder-opacity-min:           .2 !default;\n// scss-docs-end placeholders\n\n// Cards\n\n// scss-docs-start card-variables\n$card-spacer-y:                     $spacer !default;\n$card-spacer-x:                     $spacer !default;\n$card-title-spacer-y:               $spacer * .5 !default;\n$card-border-width:                 $border-width !default;\n$card-border-color:                 rgba($black, .125) !default;\n$card-border-radius:                $border-radius !default;\n$card-box-shadow:                   null !default;\n$card-inner-border-radius:          subtract($card-border-radius, $card-border-width) !default;\n$card-cap-padding-y:                $card-spacer-y * .5 !default;\n$card-cap-padding-x:                $card-spacer-x !default;\n$card-cap-bg:                       rgba($black, .03) !default;\n$card-cap-color:                    null !default;\n$card-height:                       null !default;\n$card-color:                        null !default;\n$card-bg:                           $white !default;\n$card-img-overlay-padding:          $spacer !default;\n$card-group-margin:                 $grid-gutter-width * .5 !default;\n// scss-docs-end card-variables\n\n// Accordion\n\n// scss-docs-start accordion-variables\n$accordion-padding-y:                     1rem !default;\n$accordion-padding-x:                     1.25rem !default;\n$accordion-color:                         $body-color !default;\n$accordion-bg:                            $body-bg !default;\n$accordion-border-width:                  $border-width !default;\n$accordion-border-color:                  rgba($black, .125) !default;\n$accordion-border-radius:                 $border-radius !default;\n$accordion-inner-border-radius:           subtract($accordion-border-radius, $accordion-border-width) !default;\n\n$accordion-body-padding-y:                $accordion-padding-y !default;\n$accordion-body-padding-x:                $accordion-padding-x !default;\n\n$accordion-button-padding-y:              $accordion-padding-y !default;\n$accordion-button-padding-x:              $accordion-padding-x !default;\n$accordion-button-color:                  $accordion-color !default;\n$accordion-button-bg:                     $accordion-bg !default;\n$accordion-transition:                    $btn-transition, border-radius .15s ease !default;\n$accordion-button-active-bg:              tint-color($component-active-bg, 90%) !default;\n$accordion-button-active-color:           shade-color($primary, 10%) !default;\n\n$accordion-button-focus-border-color:     $input-focus-border-color !default;\n$accordion-button-focus-box-shadow:       $btn-focus-box-shadow !default;\n\n$accordion-icon-width:                    1.25rem !default;\n$accordion-icon-color:                    $accordion-button-color !default;\n$accordion-icon-active-color:             $accordion-button-active-color !default;\n$accordion-icon-transition:               transform .2s ease-in-out !default;\n$accordion-icon-transform:                rotate(-180deg) !default;\n\n$accordion-button-icon:         url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n$accordion-button-active-icon:  url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n// scss-docs-end accordion-variables\n\n// Tooltips\n\n// scss-docs-start tooltip-variables\n$tooltip-font-size:                 $font-size-sm !default;\n$tooltip-max-width:                 200px !default;\n$tooltip-color:                     $white !default;\n$tooltip-bg:                        $black !default;\n$tooltip-border-radius:             $border-radius !default;\n$tooltip-opacity:                   .9 !default;\n$tooltip-padding-y:                 $spacer * .25 !default;\n$tooltip-padding-x:                 $spacer * .5 !default;\n$tooltip-margin:                    0 !default;\n\n$tooltip-arrow-width:               .8rem !default;\n$tooltip-arrow-height:              .4rem !default;\n$tooltip-arrow-color:               $tooltip-bg !default;\n// scss-docs-end tooltip-variables\n\n// Form tooltips must come after regular tooltips\n// scss-docs-start tooltip-feedback-variables\n$form-feedback-tooltip-padding-y:     $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x:     $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size:     $tooltip-font-size !default;\n$form-feedback-tooltip-line-height:   null !default;\n$form-feedback-tooltip-opacity:       $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n// scss-docs-end tooltip-feedback-variables\n\n\n// Popovers\n\n// scss-docs-start popover-variables\n$popover-font-size:                 $font-size-sm !default;\n$popover-bg:                        $white !default;\n$popover-max-width:                 276px !default;\n$popover-border-width:              $border-width !default;\n$popover-border-color:              rgba($black, .2) !default;\n$popover-border-radius:             $border-radius-lg !default;\n$popover-inner-border-radius:       subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow:                $box-shadow !default;\n\n$popover-header-bg:                 shade-color($popover-bg, 6%) !default;\n$popover-header-color:              $headings-color !default;\n$popover-header-padding-y:          .5rem !default;\n$popover-header-padding-x:          $spacer !default;\n\n$popover-body-color:                $body-color !default;\n$popover-body-padding-y:            $spacer !default;\n$popover-body-padding-x:            $spacer !default;\n\n$popover-arrow-width:               1rem !default;\n$popover-arrow-height:              .5rem !default;\n$popover-arrow-color:               $popover-bg !default;\n\n$popover-arrow-outer-color:         fade-in($popover-border-color, .05) !default;\n// scss-docs-end popover-variables\n\n\n// Toasts\n\n// scss-docs-start toast-variables\n$toast-max-width:                   350px !default;\n$toast-padding-x:                   .75rem !default;\n$toast-padding-y:                   .5rem !default;\n$toast-font-size:                   .875rem !default;\n$toast-color:                       null !default;\n$toast-background-color:            rgba($white, .85) !default;\n$toast-border-width:                1px !default;\n$toast-border-color:                rgba($black, .1) !default;\n$toast-border-radius:               $border-radius !default;\n$toast-box-shadow:                  $box-shadow !default;\n$toast-spacing:                     $container-padding-x !default;\n\n$toast-header-color:                $gray-600 !default;\n$toast-header-background-color:     rgba($white, .85) !default;\n$toast-header-border-color:         rgba($black, .05) !default;\n// scss-docs-end toast-variables\n\n\n// Badges\n\n// scss-docs-start badge-variables\n$badge-font-size:                   .75em !default;\n$badge-font-weight:                 $font-weight-bold !default;\n$badge-color:                       $white !default;\n$badge-padding-y:                   .35em !default;\n$badge-padding-x:                   .65em !default;\n$badge-border-radius:               $border-radius !default;\n// scss-docs-end badge-variables\n\n\n// Modals\n\n// scss-docs-start modal-variables\n$modal-inner-padding:               $spacer !default;\n\n$modal-footer-margin-between:       .5rem !default;\n\n$modal-dialog-margin:               .5rem !default;\n$modal-dialog-margin-y-sm-up:       1.75rem !default;\n\n$modal-title-line-height:           $line-height-base !default;\n\n$modal-content-color:               null !default;\n$modal-content-bg:                  $white !default;\n$modal-content-border-color:        rgba($black, .2) !default;\n$modal-content-border-width:        $border-width !default;\n$modal-content-border-radius:       $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs:       $box-shadow-sm !default;\n$modal-content-box-shadow-sm-up:    $box-shadow !default;\n\n$modal-backdrop-bg:                 $black !default;\n$modal-backdrop-opacity:            .5 !default;\n$modal-header-border-color:         $border-color !default;\n$modal-footer-border-color:         $modal-header-border-color !default;\n$modal-header-border-width:         $modal-content-border-width !default;\n$modal-footer-border-width:         $modal-header-border-width !default;\n$modal-header-padding-y:            $modal-inner-padding !default;\n$modal-header-padding-x:            $modal-inner-padding !default;\n$modal-header-padding:              $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-sm:                          300px !default;\n$modal-md:                          500px !default;\n$modal-lg:                          800px !default;\n$modal-xl:                          1140px !default;\n\n$modal-fade-transform:              translate(0, -50px) !default;\n$modal-show-transform:              none !default;\n$modal-transition:                  transform .3s ease-out !default;\n$modal-scale-transform:             scale(1.02) !default;\n// scss-docs-end modal-variables\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n// scss-docs-start alert-variables\n$alert-padding-y:               $spacer !default;\n$alert-padding-x:               $spacer !default;\n$alert-margin-bottom:           1rem !default;\n$alert-border-radius:           $border-radius !default;\n$alert-link-font-weight:        $font-weight-bold !default;\n$alert-border-width:            $border-width !default;\n$alert-bg-scale:                -80% !default;\n$alert-border-scale:            -70% !default;\n$alert-color-scale:             40% !default;\n$alert-dismissible-padding-r:   $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side\n// scss-docs-end alert-variables\n\n\n// Progress bars\n\n// scss-docs-start progress-variables\n$progress-height:                   1rem !default;\n$progress-font-size:                $font-size-base * .75 !default;\n$progress-bg:                       $gray-200 !default;\n$progress-border-radius:            $border-radius !default;\n$progress-box-shadow:               $box-shadow-inset !default;\n$progress-bar-color:                $white !default;\n$progress-bar-bg:                   $primary !default;\n$progress-bar-animation-timing:     1s linear infinite !default;\n$progress-bar-transition:           width .6s ease !default;\n// scss-docs-end progress-variables\n\n\n// List group\n\n// scss-docs-start list-group-variables\n$list-group-color:                  $gray-900 !default;\n$list-group-bg:                     $white !default;\n$list-group-border-color:           rgba($black, .125) !default;\n$list-group-border-width:           $border-width !default;\n$list-group-border-radius:          $border-radius !default;\n\n$list-group-item-padding-y:         $spacer * .5 !default;\n$list-group-item-padding-x:         $spacer !default;\n$list-group-item-bg-scale:          -80% !default;\n$list-group-item-color-scale:       40% !default;\n\n$list-group-hover-bg:               $gray-100 !default;\n$list-group-active-color:           $component-active-color !default;\n$list-group-active-bg:              $component-active-bg !default;\n$list-group-active-border-color:    $list-group-active-bg !default;\n\n$list-group-disabled-color:         $gray-600 !default;\n$list-group-disabled-bg:            $list-group-bg !default;\n\n$list-group-action-color:           $gray-700 !default;\n$list-group-action-hover-color:     $list-group-action-color !default;\n\n$list-group-action-active-color:    $body-color !default;\n$list-group-action-active-bg:       $gray-200 !default;\n// scss-docs-end list-group-variables\n\n\n// Image thumbnails\n\n// scss-docs-start thumbnail-variables\n$thumbnail-padding:                 .25rem !default;\n$thumbnail-bg:                      $body-bg !default;\n$thumbnail-border-width:            $border-width !default;\n$thumbnail-border-color:            $gray-300 !default;\n$thumbnail-border-radius:           $border-radius !default;\n$thumbnail-box-shadow:              $box-shadow-sm !default;\n// scss-docs-end thumbnail-variables\n\n\n// Figures\n\n// scss-docs-start figure-variables\n$figure-caption-font-size:          $small-font-size !default;\n$figure-caption-color:              $gray-600 !default;\n// scss-docs-end figure-variables\n\n\n// Breadcrumbs\n\n// scss-docs-start breadcrumb-variables\n$breadcrumb-font-size:              null !default;\n$breadcrumb-padding-y:              0 !default;\n$breadcrumb-padding-x:              0 !default;\n$breadcrumb-item-padding-x:         .5rem !default;\n$breadcrumb-margin-bottom:          1rem !default;\n$breadcrumb-bg:                     null !default;\n$breadcrumb-divider-color:          $gray-600 !default;\n$breadcrumb-active-color:           $gray-600 !default;\n$breadcrumb-divider:                quote(\"/\") !default;\n$breadcrumb-divider-flipped:        $breadcrumb-divider !default;\n$breadcrumb-border-radius:          null !default;\n// scss-docs-end breadcrumb-variables\n\n// Carousel\n\n// scss-docs-start carousel-variables\n$carousel-control-color:             $white !default;\n$carousel-control-width:             15% !default;\n$carousel-control-opacity:           .5 !default;\n$carousel-control-hover-opacity:     .9 !default;\n$carousel-control-transition:        opacity .15s ease !default;\n\n$carousel-indicator-width:           30px !default;\n$carousel-indicator-height:          3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer:          3px !default;\n$carousel-indicator-opacity:         .5 !default;\n$carousel-indicator-active-bg:       $white !default;\n$carousel-indicator-active-opacity:  1 !default;\n$carousel-indicator-transition:      opacity .6s ease !default;\n\n$carousel-caption-width:             70% !default;\n$carousel-caption-color:             $white !default;\n$carousel-caption-padding-y:         1.25rem !default;\n$carousel-caption-spacer:            1.25rem !default;\n\n$carousel-control-icon-width:        2rem !default;\n\n$carousel-control-prev-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n\n$carousel-transition-duration:       .6s !default;\n$carousel-transition:                transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n$carousel-dark-indicator-active-bg:  $black !default;\n$carousel-dark-caption-color:        $black !default;\n$carousel-dark-control-icon-filter:  invert(1) grayscale(100) !default;\n// scss-docs-end carousel-variables\n\n\n// Spinners\n\n// scss-docs-start spinner-variables\n$spinner-width:           2rem !default;\n$spinner-height:          $spinner-width !default;\n$spinner-vertical-align:  -.125em !default;\n$spinner-border-width:    .25em !default;\n$spinner-animation-speed: .75s !default;\n\n$spinner-width-sm:        1rem !default;\n$spinner-height-sm:       $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n// scss-docs-end spinner-variables\n\n\n// Close\n\n// scss-docs-start close-variables\n$btn-close-width:            1em !default;\n$btn-close-height:           $btn-close-width !default;\n$btn-close-padding-x:        .25em !default;\n$btn-close-padding-y:        $btn-close-padding-x !default;\n$btn-close-color:            $black !default;\n$btn-close-bg:               url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$btn-close-color}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>\") !default;\n$btn-close-focus-shadow:     $input-btn-focus-box-shadow !default;\n$btn-close-opacity:          .5 !default;\n$btn-close-hover-opacity:    .75 !default;\n$btn-close-focus-opacity:    1 !default;\n$btn-close-disabled-opacity: .25 !default;\n$btn-close-white-filter:     invert(1) grayscale(100%) brightness(200%) !default;\n// scss-docs-end close-variables\n\n\n// Offcanvas\n\n// scss-docs-start offcanvas-variables\n$offcanvas-padding-y:               $modal-inner-padding !default;\n$offcanvas-padding-x:               $modal-inner-padding !default;\n$offcanvas-horizontal-width:        400px !default;\n$offcanvas-vertical-height:         30vh !default;\n$offcanvas-transition-duration:     .3s !default;\n$offcanvas-border-color:            $modal-content-border-color !default;\n$offcanvas-border-width:            $modal-content-border-width !default;\n$offcanvas-title-line-height:       $modal-title-line-height !default;\n$offcanvas-bg-color:                $modal-content-bg !default;\n$offcanvas-color:                   $modal-content-color !default;\n$offcanvas-box-shadow:              $modal-content-box-shadow-xs !default;\n$offcanvas-backdrop-bg:             $modal-backdrop-bg !default;\n$offcanvas-backdrop-opacity:        $modal-backdrop-opacity !default;\n// scss-docs-end offcanvas-variables\n\n// Code\n\n$code-font-size:                    $small-font-size !default;\n$code-color:                        $pink !default;\n\n$kbd-padding-y:                     .2rem !default;\n$kbd-padding-x:                     .4rem !default;\n$kbd-font-size:                     $code-font-size !default;\n$kbd-color:                         $white !default;\n$kbd-bg:                            $gray-900 !default;\n\n$pre-color:                         null !default;\n"
  },
  {
    "path": "vendor/bootstrap/scss/bootstrap-grid.scss",
    "content": "/*!\n * Bootstrap Grid v5.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n$include-column-box-sizing: true !default;\n\n@import \"functions\";\n@import \"variables\";\n\n@import \"mixins/lists\";\n@import \"mixins/breakpoints\";\n@import \"mixins/container\";\n@import \"mixins/grid\";\n@import \"mixins/utilities\";\n\n@import \"vendor/rfs\";\n\n@import \"root\";\n\n@import \"containers\";\n@import \"grid\";\n\n@import \"utilities\";\n// Only use the utilities we need\n// stylelint-disable-next-line scss/dollar-variable-default\n$utilities: map-get-multiple(\n  $utilities,\n  (\n    \"display\",\n    \"order\",\n    \"flex\",\n    \"flex-direction\",\n    \"flex-grow\",\n    \"flex-shrink\",\n    \"flex-wrap\",\n    \"justify-content\",\n    \"align-items\",\n    \"align-content\",\n    \"align-self\",\n    \"margin\",\n    \"margin-x\",\n    \"margin-y\",\n    \"margin-top\",\n    \"margin-end\",\n    \"margin-bottom\",\n    \"margin-start\",\n    \"negative-margin\",\n    \"negative-margin-x\",\n    \"negative-margin-y\",\n    \"negative-margin-top\",\n    \"negative-margin-end\",\n    \"negative-margin-bottom\",\n    \"negative-margin-start\",\n    \"padding\",\n    \"padding-x\",\n    \"padding-y\",\n    \"padding-top\",\n    \"padding-end\",\n    \"padding-bottom\",\n    \"padding-start\",\n  )\n);\n\n@import \"utilities/api\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/bootstrap-reboot.scss",
    "content": "/*!\n * Bootstrap Reboot v5.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/bootstrap-utilities.scss",
    "content": "/*!\n * Bootstrap Utilities v5.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n"
  },
  {
    "path": "vendor/bootstrap/scss/bootstrap.scss",
    "content": "/*!\n * Bootstrap v5.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// scss-docs-start import-stack\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Layout & components\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"containers\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"accordion\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"alert\";\n@import \"progress\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"offcanvas\";\n@import \"placeholders\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n// scss-docs-end import-stack\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_floating-labels.scss",
    "content": ".form-floating {\n  position: relative;\n\n  > .form-control,\n  > .form-select {\n    height: $form-floating-height;\n    line-height: $form-floating-line-height;\n  }\n\n  > label {\n    position: absolute;\n    top: 0;\n    left: 0;\n    height: 100%; // allow textareas\n    padding: $form-floating-padding-y $form-floating-padding-x;\n    pointer-events: none;\n    border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model\n    transform-origin: 0 0;\n    @include transition($form-floating-transition);\n  }\n\n  // stylelint-disable no-duplicate-selectors\n  > .form-control {\n    padding: $form-floating-padding-y $form-floating-padding-x;\n\n    &::placeholder {\n      color: transparent;\n    }\n\n    &:focus,\n    &:not(:placeholder-shown) {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n    // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n    &:-webkit-autofill {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n  }\n\n  > .form-select {\n    padding-top: $form-floating-input-padding-t;\n    padding-bottom: $form-floating-input-padding-b;\n  }\n\n  > .form-control:focus,\n  > .form-control:not(:placeholder-shown),\n  > .form-select {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n  // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n  > .form-control:-webkit-autofill {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n  // stylelint-enable no-duplicate-selectors\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_form-check.scss",
    "content": "//\n// Check/radio\n//\n\n.form-check {\n  display: block;\n  min-height: $form-check-min-height;\n  padding-left: $form-check-padding-start;\n  margin-bottom: $form-check-margin-bottom;\n\n  .form-check-input {\n    float: left;\n    margin-left: $form-check-padding-start * -1;\n  }\n}\n\n.form-check-input {\n  width: $form-check-input-width;\n  height: $form-check-input-width;\n  margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height\n  vertical-align: top;\n  background-color: $form-check-input-bg;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: $form-check-input-border;\n  appearance: none;\n  color-adjust: exact; // Keep themed appearance for print\n  @include transition($form-check-transition);\n\n  &[type=\"checkbox\"] {\n    @include border-radius($form-check-input-border-radius);\n  }\n\n  &[type=\"radio\"] {\n    // stylelint-disable-next-line property-disallowed-list\n    border-radius: $form-check-radio-border-radius;\n  }\n\n  &:active {\n    filter: $form-check-input-active-filter;\n  }\n\n  &:focus {\n    border-color: $form-check-input-focus-border;\n    outline: 0;\n    box-shadow: $form-check-input-focus-box-shadow;\n  }\n\n  &:checked {\n    background-color: $form-check-input-checked-bg-color;\n    border-color: $form-check-input-checked-border-color;\n\n    &[type=\"checkbox\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-input-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-input-checked-bg-image);\n      }\n    }\n\n    &[type=\"radio\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-radio-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-radio-checked-bg-image);\n      }\n    }\n  }\n\n  &[type=\"checkbox\"]:indeterminate {\n    background-color: $form-check-input-indeterminate-bg-color;\n    border-color: $form-check-input-indeterminate-border-color;\n\n    @if $enable-gradients {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image), var(--#{$variable-prefix}gradient);\n    } @else {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image);\n    }\n  }\n\n  &:disabled {\n    pointer-events: none;\n    filter: none;\n    opacity: $form-check-input-disabled-opacity;\n  }\n\n  // Use disabled attribute in addition of :disabled pseudo-class\n  // See: https://github.com/twbs/bootstrap/issues/28247\n  &[disabled],\n  &:disabled {\n    ~ .form-check-label {\n      opacity: $form-check-label-disabled-opacity;\n    }\n  }\n}\n\n.form-check-label {\n  color: $form-check-label-color;\n  cursor: $form-check-label-cursor;\n}\n\n//\n// Switch\n//\n\n.form-switch {\n  padding-left: $form-switch-padding-start;\n\n  .form-check-input {\n    width: $form-switch-width;\n    margin-left: $form-switch-padding-start * -1;\n    background-image: escape-svg($form-switch-bg-image);\n    background-position: left center;\n    @include border-radius($form-switch-border-radius);\n    @include transition($form-switch-transition);\n\n    &:focus {\n      background-image: escape-svg($form-switch-focus-bg-image);\n    }\n\n    &:checked {\n      background-position: $form-switch-checked-bg-position;\n\n      @if $enable-gradients {\n        background-image: escape-svg($form-switch-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-switch-checked-bg-image);\n      }\n    }\n  }\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: $form-check-inline-margin-end;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n\n  &[disabled],\n  &:disabled {\n    + .btn {\n      pointer-events: none;\n      filter: none;\n      opacity: $form-check-btn-check-disabled-opacity;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_form-control.scss",
    "content": "//\n// General form controls (plus a few specific high-level interventions)\n//\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y $input-padding-x;\n  font-family: $input-font-family;\n  @include font-size($input-font-size);\n  font-weight: $input-font-weight;\n  line-height: $input-line-height;\n  color: $input-color;\n  background-color: $input-bg;\n  background-clip: padding-box;\n  border: $input-border-width solid $input-border-color;\n  appearance: none; // Fix appearance for date inputs in Safari\n\n  // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n  @include border-radius($input-border-radius, 0);\n\n  @include box-shadow($input-box-shadow);\n  @include transition($input-transition);\n\n  &[type=\"file\"] {\n    overflow: hidden; // prevent pseudo element button overlap\n\n    &:not(:disabled):not([readonly]) {\n      cursor: pointer;\n    }\n  }\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  &:focus {\n    color: $input-focus-color;\n    background-color: $input-focus-bg;\n    border-color: $input-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $input-focus-box-shadow;\n    }\n  }\n\n  // Add some height to date inputs on iOS\n  // https://github.com/twbs/bootstrap/issues/23307\n  // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved\n  &::-webkit-date-and-time-value {\n    // Multiply line-height by 1em if it has no unit\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n  }\n\n  // Placeholder\n  &::placeholder {\n    color: $input-placeholder-color;\n    // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n    opacity: 1;\n  }\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &:disabled,\n  &[readonly] {\n    background-color: $input-disabled-bg;\n    border-color: $input-disabled-border-color;\n    // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n    opacity: 1;\n  }\n\n  // File input buttons theming\n  &::file-selector-button {\n    padding: $input-padding-y $input-padding-x;\n    margin: (-$input-padding-y) (-$input-padding-x);\n    margin-inline-end: $input-padding-x;\n    color: $form-file-button-color;\n    @include gradient-bg($form-file-button-bg);\n    pointer-events: none;\n    border-color: inherit;\n    border-style: solid;\n    border-width: 0;\n    border-inline-end-width: $input-border-width;\n    border-radius: 0; // stylelint-disable-line property-disallowed-list\n    @include transition($btn-transition);\n  }\n\n  &:hover:not(:disabled):not([readonly])::file-selector-button {\n    background-color: $form-file-button-hover-bg;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y $input-padding-x;\n    margin: (-$input-padding-y) (-$input-padding-x);\n    margin-inline-end: $input-padding-x;\n    color: $form-file-button-color;\n    @include gradient-bg($form-file-button-bg);\n    pointer-events: none;\n    border-color: inherit;\n    border-style: solid;\n    border-width: 0;\n    border-inline-end-width: $input-border-width;\n    border-radius: 0; // stylelint-disable-line property-disallowed-list\n    @include transition($btn-transition);\n  }\n\n  &:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n    background-color: $form-file-button-hover-bg;\n  }\n}\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y 0;\n  margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n  line-height: $input-line-height;\n  color: $input-plaintext-color;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: $input-border-width 0;\n\n  &.form-control-sm,\n  &.form-control-lg {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n  min-height: $input-height-sm;\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n\n  &::file-selector-button {\n    padding: $input-padding-y-sm $input-padding-x-sm;\n    margin: (-$input-padding-y-sm) (-$input-padding-x-sm);\n    margin-inline-end: $input-padding-x-sm;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y-sm $input-padding-x-sm;\n    margin: (-$input-padding-y-sm) (-$input-padding-x-sm);\n    margin-inline-end: $input-padding-x-sm;\n  }\n}\n\n.form-control-lg {\n  min-height: $input-height-lg;\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n\n  &::file-selector-button {\n    padding: $input-padding-y-lg $input-padding-x-lg;\n    margin: (-$input-padding-y-lg) (-$input-padding-x-lg);\n    margin-inline-end: $input-padding-x-lg;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y-lg $input-padding-x-lg;\n    margin: (-$input-padding-y-lg) (-$input-padding-x-lg);\n    margin-inline-end: $input-padding-x-lg;\n  }\n}\n\n// Make sure textareas don't shrink too much when resized\n// https://github.com/twbs/bootstrap/pull/29124\n// stylelint-disable selector-no-qualifying-type\ntextarea {\n  &.form-control {\n    min-height: $input-height;\n  }\n\n  &.form-control-sm {\n    min-height: $input-height-sm;\n  }\n\n  &.form-control-lg {\n    min-height: $input-height-lg;\n  }\n}\n// stylelint-enable selector-no-qualifying-type\n\n.form-control-color {\n  width: $form-color-width;\n  height: auto; // Override fixed browser height\n  padding: $input-padding-y;\n\n  &:not(:disabled):not([readonly]) {\n    cursor: pointer;\n  }\n\n  &::-moz-color-swatch {\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n    @include border-radius($input-border-radius);\n  }\n\n  &::-webkit-color-swatch {\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n    @include border-radius($input-border-radius);\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_form-range.scss",
    "content": "// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.form-range {\n  width: 100%;\n  height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);\n  padding: 0; // Need to reset padding\n  background-color: transparent;\n  appearance: none;\n\n  &:focus {\n    outline: 0;\n\n    // Pseudo-elements must be split across multiple rulesets to have an effect.\n    // No box-shadow() mixin for focus accessibility.\n    &::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }\n    &::-moz-range-thumb     { box-shadow: $form-range-thumb-focus-box-shadow; }\n  }\n\n  &::-moz-focus-outer {\n    border: 0;\n  }\n\n  &::-webkit-slider-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-webkit-slider-runnable-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent; // Why?\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent;\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &::-moz-range-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-moz-range-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent;\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent; // Firefox specific?\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &:disabled {\n    pointer-events: none;\n\n    &::-webkit-slider-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n\n    &::-moz-range-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_form-select.scss",
    "content": "// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;\n  // stylelint-disable-next-line property-no-vendor-prefix\n  -moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636\n  font-family: $form-select-font-family;\n  @include font-size($form-select-font-size);\n  font-weight: $form-select-font-weight;\n  line-height: $form-select-line-height;\n  color: $form-select-color;\n  background-color: $form-select-bg;\n  background-image: escape-svg($form-select-indicator);\n  background-repeat: no-repeat;\n  background-position: $form-select-bg-position;\n  background-size: $form-select-bg-size;\n  border: $form-select-border-width solid $form-select-border-color;\n  @include border-radius($form-select-border-radius, 0);\n  @include box-shadow($form-select-box-shadow);\n  @include transition($form-select-transition);\n  appearance: none;\n\n  &:focus {\n    border-color: $form-select-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $form-select-focus-box-shadow;\n    }\n  }\n\n  &[multiple],\n  &[size]:not([size=\"1\"]) {\n    padding-right: $form-select-padding-x;\n    background-image: none;\n  }\n\n  &:disabled {\n    color: $form-select-disabled-color;\n    background-color: $form-select-disabled-bg;\n    border-color: $form-select-disabled-border-color;\n  }\n\n  // Remove outline from select box in FF\n  &:-moz-focusring {\n    color: transparent;\n    text-shadow: 0 0 0 $form-select-color;\n  }\n}\n\n.form-select-sm {\n  padding-top: $form-select-padding-y-sm;\n  padding-bottom: $form-select-padding-y-sm;\n  padding-left: $form-select-padding-x-sm;\n  @include font-size($form-select-font-size-sm);\n  @include border-radius($form-select-border-radius-sm);\n}\n\n.form-select-lg {\n  padding-top: $form-select-padding-y-lg;\n  padding-bottom: $form-select-padding-y-lg;\n  padding-left: $form-select-padding-x-lg;\n  @include font-size($form-select-font-size-lg);\n  @include border-radius($form-select-border-radius-lg);\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_form-text.scss",
    "content": "//\n// Form text\n//\n\n.form-text {\n  margin-top: $form-text-margin-top;\n  @include font-size($form-text-font-size);\n  font-style: $form-text-font-style;\n  font-weight: $form-text-font-weight;\n  color: $form-text-color;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_input-group.scss",
    "content": "//\n// Base styles\n//\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap; // For form validation feedback\n  align-items: stretch;\n  width: 100%;\n\n  > .form-control,\n  > .form-select {\n    position: relative; // For focus state's z-index\n    flex: 1 1 auto;\n    width: 1%;\n    min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n  }\n\n  // Bring the \"active\" form control to the top of surrounding elements\n  > .form-control:focus,\n  > .form-select:focus {\n    z-index: 3;\n  }\n\n  // Ensure buttons are always above inputs for more visually pleasing borders.\n  // This isn't needed for `.input-group-text` since it shares the same border-color\n  // as our inputs.\n  .btn {\n    position: relative;\n    z-index: 2;\n\n    &:focus {\n      z-index: 3;\n    }\n  }\n}\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: $input-group-addon-padding-y $input-group-addon-padding-x;\n  @include font-size($input-font-size); // Match inputs\n  font-weight: $input-group-addon-font-weight;\n  line-height: $input-line-height;\n  color: $input-group-addon-color;\n  text-align: center;\n  white-space: nowrap;\n  background-color: $input-group-addon-bg;\n  border: $input-border-width solid $input-group-addon-border-color;\n  @include border-radius($input-border-radius);\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: $form-select-padding-x + $form-select-indicator-padding;\n}\n\n\n// Rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.input-group {\n  &:not(.has-validation) {\n    > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),\n    > .dropdown-toggle:nth-last-child(n + 3) {\n      @include border-end-radius(0);\n    }\n  }\n\n  &.has-validation {\n    > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu),\n    > .dropdown-toggle:nth-last-child(n + 4) {\n      @include border-end-radius(0);\n    }\n  }\n\n  $validation-messages: \"\";\n  @each $state in map-keys($form-validation-states) {\n    $validation-messages: $validation-messages + \":not(.\" + unquote($state) + \"-tooltip)\" + \":not(.\" + unquote($state) + \"-feedback)\";\n  }\n\n  > :not(:first-child):not(.dropdown-menu)#{$validation-messages} {\n    margin-left: -$input-border-width;\n    @include border-start-radius(0);\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_labels.scss",
    "content": "//\n// Labels\n//\n\n.form-label {\n  margin-bottom: $form-label-margin-bottom;\n  @include font-size($form-label-font-size);\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  color: $form-label-color;\n}\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n  padding-top: add($input-padding-y, $input-border-width);\n  padding-bottom: add($input-padding-y, $input-border-width);\n  margin-bottom: 0; // Override the `<legend>` default\n  @include font-size(inherit); // Override the `<legend>` default\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  line-height: $input-line-height;\n  color: $form-label-color;\n}\n\n.col-form-label-lg {\n  padding-top: add($input-padding-y-lg, $input-border-width);\n  padding-bottom: add($input-padding-y-lg, $input-border-width);\n  @include font-size($input-font-size-lg);\n}\n\n.col-form-label-sm {\n  padding-top: add($input-padding-y-sm, $input-border-width);\n  padding-bottom: add($input-padding-y-sm, $input-border-width);\n  @include font-size($input-font-size-sm);\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/forms/_validation.scss",
    "content": "// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server-side validation.\n\n// scss-docs-start form-validation-states-loop\n@each $state, $data in $form-validation-states {\n  @include form-validation-state($state, $data...);\n}\n// scss-docs-end form-validation-states-loop\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_clearfix.scss",
    "content": ".clearfix {\n  @include clearfix();\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_colored-links.scss",
    "content": "@each $color, $value in $theme-colors {\n  .link-#{$color} {\n    color: $value;\n\n    @if $link-shade-percentage != 0 {\n      &:hover,\n      &:focus {\n        color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_position.scss",
    "content": "// Shorthand\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: $zindex-fixed;\n}\n\n// Responsive sticky top\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .sticky#{$infix}-top {\n      position: sticky;\n      top: 0;\n      z-index: $zindex-sticky;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_ratio.scss",
    "content": "// Credit: Nicolas Gallagher and SUIT CSS.\n\n.ratio {\n  position: relative;\n  width: 100%;\n\n  &::before {\n    display: block;\n    padding-top: var(--#{$variable-prefix}aspect-ratio);\n    content: \"\";\n  }\n\n  > * {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n  }\n}\n\n@each $key, $ratio in $aspect-ratios {\n  .ratio-#{$key} {\n    --#{$variable-prefix}aspect-ratio: #{$ratio};\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_stacks.scss",
    "content": "// scss-docs-start stacks\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n// scss-docs-end stacks\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_stretched-link.scss",
    "content": "//\n// Stretched link\n//\n\n.stretched-link {\n  &::#{$stretched-link-pseudo-element} {\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    z-index: $stretched-link-z-index;\n    content: \"\";\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_text-truncation.scss",
    "content": "//\n// Text truncation\n//\n\n.text-truncate {\n  @include text-truncate();\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_visually-hidden.scss",
    "content": "//\n// Visually hidden\n//\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  @include visually-hidden();\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/helpers/_vr.scss",
    "content": ".vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: $hr-opacity;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_alert.scss",
    "content": "// scss-docs-start alert-variant-mixin\n@mixin alert-variant($background, $border, $color) {\n  color: $color;\n  @include gradient-bg($background);\n  border-color: $border;\n\n  .alert-link {\n    color: shade-color($color, 20%);\n  }\n}\n// scss-docs-end alert-variant-mixin\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_backdrop.scss",
    "content": "// Shared between modals and offcanvases\n@mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $zindex;\n  width: 100vw;\n  height: 100vh;\n  background-color: $backdrop-bg;\n\n  // Fade for backdrop\n  &.fade { opacity: 0; }\n  &.show { opacity: $backdrop-opacity; }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_border-radius.scss",
    "content": "// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n  $return: ();\n  @each $value in $radius {\n    @if type-of($value) == number {\n      $return: append($return, max($value, 0));\n    } @else {\n      $return: append($return, $value);\n    }\n  }\n  @return $return;\n}\n\n// scss-docs-start border-radius-mixins\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n  @if $enable-rounded {\n    border-radius: valid-radius($radius);\n  }\n  @else if $fallback-border-radius != false {\n    border-radius: $fallback-border-radius;\n  }\n}\n\n@mixin border-top-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n// scss-docs-end border-radius-mixins\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_box-shadow.scss",
    "content": "@mixin box-shadow($shadow...) {\n  @if $enable-shadows {\n    $result: ();\n\n    @each $value in $shadow {\n      @if $value != null {\n        $result: append($result, $value, \"comma\");\n      }\n      @if $value == none and length($shadow) > 1 {\n        @warn \"The keyword 'none' must be used as a single argument.\";\n      }\n    }\n\n    @if (length($result) > 0) {\n      box-shadow: $result;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_breakpoints.scss",
    "content": "// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n//    (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n//    >> breakpoint-next(sm)\n//    md\n//    >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    md\n//    >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n//    md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n  $n: index($breakpoint-names, $name);\n  @if not $n {\n    @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n  }\n  @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n//    >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n  $min: map-get($breakpoints, $name);\n  @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n//    >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n  $max: map-get($breakpoints, $name);\n  @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n//    >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    \"\"  (Returns a blank string)\n//    >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n  @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($name, $breakpoints);\n  @if $min {\n    @media (min-width: $min) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n  $max: breakpoint-max($name, $breakpoints);\n  @if $max {\n    @media (max-width: $max) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($lower, $breakpoints);\n  $max: breakpoint-max($upper, $breakpoints);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($lower, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($upper, $breakpoints) {\n      @content;\n    }\n  }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n  $min:  breakpoint-min($name, $breakpoints);\n  $next: breakpoint-next($name, $breakpoints);\n  $max:  breakpoint-max($next);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($name, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($next, $breakpoints) {\n      @content;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_buttons.scss",
    "content": "// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n// scss-docs-start btn-variant-mixin\n@mixin button-variant(\n  $background,\n  $border,\n  $color: color-contrast($background),\n  $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),\n  $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),\n  $hover-color: color-contrast($hover-background),\n  $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),\n  $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),\n  $active-color: color-contrast($active-background),\n  $disabled-background: $background,\n  $disabled-border: $border,\n  $disabled-color: color-contrast($disabled-background)\n) {\n  color: $color;\n  @include gradient-bg($background);\n  border-color: $border;\n  @include box-shadow($btn-box-shadow);\n\n  &:hover {\n    color: $hover-color;\n    @include gradient-bg($hover-background);\n    border-color: $hover-border;\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    color: $hover-color;\n    @include gradient-bg($hover-background);\n    border-color: $hover-border;\n    @if $enable-shadows {\n      @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);\n    }\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active,\n  .show > &.dropdown-toggle {\n    color: $active-color;\n    background-color: $active-background;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n    border-color: $active-border;\n\n    &:focus {\n      @if $enable-shadows {\n        @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));\n      } @else {\n        // Avoid using mixin so we can pass custom focus shadow properly\n        box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);\n      }\n    }\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $disabled-color;\n    background-color: $disabled-background;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n    border-color: $disabled-border;\n  }\n}\n// scss-docs-end btn-variant-mixin\n\n// scss-docs-start btn-outline-variant-mixin\n@mixin button-outline-variant(\n  $color,\n  $color-hover: color-contrast($color),\n  $active-background: $color,\n  $active-border: $color,\n  $active-color: color-contrast($active-background)\n) {\n  color: $color;\n  border-color: $color;\n\n  &:hover {\n    color: $color-hover;\n    background-color: $active-background;\n    border-color: $active-border;\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active,\n  &.dropdown-toggle.show {\n    color: $active-color;\n    background-color: $active-background;\n    border-color: $active-border;\n\n    &:focus {\n      @if $enable-shadows {\n        @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n      } @else {\n        // Avoid using mixin so we can pass custom focus shadow properly\n        box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n      }\n    }\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $color;\n    background-color: transparent;\n  }\n}\n// scss-docs-end btn-outline-variant-mixin\n\n// scss-docs-start btn-size-mixin\n@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {\n  padding: $padding-y $padding-x;\n  @include font-size($font-size);\n  // Manually declare to provide an override to the browser default\n  @include border-radius($border-radius, 0);\n}\n// scss-docs-end btn-size-mixin\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_caret.scss",
    "content": "// scss-docs-start caret-mixins\n@mixin caret-down {\n  border-top: $caret-width solid;\n  border-right: $caret-width solid transparent;\n  border-bottom: 0;\n  border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up {\n  border-top: 0;\n  border-right: $caret-width solid transparent;\n  border-bottom: $caret-width solid;\n  border-left: $caret-width solid transparent;\n}\n\n@mixin caret-end {\n  border-top: $caret-width solid transparent;\n  border-right: 0;\n  border-bottom: $caret-width solid transparent;\n  border-left: $caret-width solid;\n}\n\n@mixin caret-start {\n  border-top: $caret-width solid transparent;\n  border-right: $caret-width solid;\n  border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n  @if $enable-caret {\n    &::after {\n      display: inline-block;\n      margin-left: $caret-spacing;\n      vertical-align: $caret-vertical-align;\n      content: \"\";\n      @if $direction == down {\n        @include caret-down();\n      } @else if $direction == up {\n        @include caret-up();\n      } @else if $direction == end {\n        @include caret-end();\n      }\n    }\n\n    @if $direction == start {\n      &::after {\n        display: none;\n      }\n\n      &::before {\n        display: inline-block;\n        margin-right: $caret-spacing;\n        vertical-align: $caret-vertical-align;\n        content: \"\";\n        @include caret-start();\n      }\n    }\n\n    &:empty::after {\n      margin-left: 0;\n    }\n  }\n}\n// scss-docs-end caret-mixins\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_clearfix.scss",
    "content": "// scss-docs-start clearfix\n@mixin clearfix() {\n  &::after {\n    display: block;\n    clear: both;\n    content: \"\";\n  }\n}\n// scss-docs-end clearfix\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_color-scheme.scss",
    "content": "// scss-docs-start mixin-color-scheme\n@mixin color-scheme($name) {\n  @media (prefers-color-scheme: #{$name}) {\n    @content;\n  }\n}\n// scss-docs-end mixin-color-scheme\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_container.scss",
    "content": "// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n  width: 100%;\n  padding-right: var(--#{$variable-prefix}gutter-x, #{$gutter});\n  padding-left: var(--#{$variable-prefix}gutter-x, #{$gutter});\n  margin-right: auto;\n  margin-left: auto;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_deprecate.scss",
    "content": "// Deprecate mixin\n//\n// This mixin can be used to deprecate mixins or functions.\n// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to\n// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)\n@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {\n  @if ($enable-deprecation-messages != false and $ignore-warning != true) {\n    @warn \"#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.\";\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_forms.scss",
    "content": "// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n\n// scss-docs-start form-validation-mixins\n@mixin form-validation-state-selector($state) {\n  @if ($state == \"valid\" or $state == \"invalid\") {\n    .was-validated #{if(&, \"&\", \"\")}:#{$state},\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  } @else {\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  }\n}\n\n@mixin form-validation-state(\n  $state,\n  $color,\n  $icon,\n  $tooltip-color: color-contrast($color),\n  $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),\n  $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)\n) {\n  .#{$state}-feedback {\n    display: none;\n    width: 100%;\n    margin-top: $form-feedback-margin-top;\n    @include font-size($form-feedback-font-size);\n    font-style: $form-feedback-font-style;\n    color: $color;\n  }\n\n  .#{$state}-tooltip {\n    position: absolute;\n    top: 100%;\n    z-index: 5;\n    display: none;\n    max-width: 100%; // Contain to parent when possible\n    padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n    margin-top: .1rem;\n    @include font-size($form-feedback-tooltip-font-size);\n    line-height: $form-feedback-tooltip-line-height;\n    color: $tooltip-color;\n    background-color: $tooltip-bg-color;\n    @include border-radius($form-feedback-tooltip-border-radius);\n  }\n\n  @include form-validation-state-selector($state) {\n    ~ .#{$state}-feedback,\n    ~ .#{$state}-tooltip {\n      display: block;\n    }\n  }\n\n  .form-control {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-image: escape-svg($icon);\n        background-repeat: no-repeat;\n        background-position: right $input-height-inner-quarter center;\n        background-size: $input-height-inner-half $input-height-inner-half;\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  // stylelint-disable-next-line selector-no-qualifying-type\n  textarea.form-control {\n    @include form-validation-state-selector($state) {\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n      }\n    }\n  }\n\n  .form-select {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        &:not([multiple]):not([size]),\n        &:not([multiple])[size=\"1\"] {\n          padding-right: $form-select-feedback-icon-padding-end;\n          background-image: escape-svg($form-select-indicator), escape-svg($icon);\n          background-position: $form-select-bg-position, $form-select-feedback-icon-position;\n          background-size: $form-select-bg-size, $form-select-feedback-icon-size;\n        }\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  .form-check-input {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      &:checked {\n        background-color: $color;\n      }\n\n      &:focus {\n        box-shadow: $focus-box-shadow;\n      }\n\n      ~ .form-check-label {\n        color: $color;\n      }\n    }\n  }\n  .form-check-inline .form-check-input {\n    ~ .#{$state}-feedback {\n      margin-left: .5em;\n    }\n  }\n\n  .input-group .form-control,\n  .input-group .form-select {\n    @include form-validation-state-selector($state) {\n      @if $state == \"valid\" {\n        z-index: 1;\n      } @else if $state == \"invalid\" {\n        z-index: 2;\n      }\n      &:focus {\n        z-index: 3;\n      }\n    }\n  }\n}\n// scss-docs-end form-validation-mixins\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_gradients.scss",
    "content": "// Gradients\n\n// scss-docs-start gradient-bg-mixin\n@mixin gradient-bg($color: null) {\n  background-color: $color;\n\n  @if $enable-gradients {\n    background-image: var(--#{$variable-prefix}gradient);\n  }\n}\n// scss-docs-end gradient-bg-mixin\n\n// scss-docs-start gradient-mixins\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n  background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) {\n  background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n  background-image: linear-gradient($deg, $start-color, $end-color);\n}\n\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n  background-image: radial-gradient(circle, $inner-color, $outer-color);\n}\n\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n  background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n// scss-docs-end gradient-mixins\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_grid.scss",
    "content": "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n  --#{$variable-prefix}gutter-x: #{$gutter};\n  --#{$variable-prefix}gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n  margin-top: calc(-1 * var(--#{$variable-prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n  margin-right: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n  margin-left: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n  // Add box sizing if only the grid is loaded\n  box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n  // Prevent columns from becoming too narrow when at smaller grid tiers by\n  // always setting `width: 100%;`. This works because we set the width\n  // later on to override this initial width.\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n  padding-right: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  padding-left: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  margin-top: var(--#{$variable-prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n  @if $size {\n    flex: 0 0 auto;\n    width: percentage(divide($size, $columns));\n\n  } @else {\n    flex: 1 1 0;\n    max-width: 100%;\n  }\n}\n\n@mixin make-col-auto() {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n  $num: divide($size, $columns);\n  margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n  > * {\n    flex: 0 0 auto;\n    width: divide(100%, $count);\n  }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n      .col#{$infix} {\n        flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n      }\n\n      .row-cols#{$infix}-auto > * {\n        @include make-col-auto();\n      }\n\n      @if $grid-row-columns > 0 {\n        @for $i from 1 through $grid-row-columns {\n          .row-cols#{$infix}-#{$i} {\n            @include row-cols($i);\n          }\n        }\n      }\n\n      .col#{$infix}-auto {\n        @include make-col-auto();\n      }\n\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .col#{$infix}-#{$i} {\n            @include make-col($i, $columns);\n          }\n        }\n\n        // `$columns - 1` because offsetting by the width of an entire row isn't possible\n        @for $i from 0 through ($columns - 1) {\n          @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n            .offset#{$infix}-#{$i} {\n              @include make-col-offset($i, $columns);\n            }\n          }\n        }\n      }\n\n      // Gutters\n      //\n      // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n      @each $key, $value in $gutters {\n        .g#{$infix}-#{$key},\n        .gx#{$infix}-#{$key} {\n          --#{$variable-prefix}gutter-x: #{$value};\n        }\n\n        .g#{$infix}-#{$key},\n        .gy#{$infix}-#{$key} {\n          --#{$variable-prefix}gutter-y: #{$value};\n        }\n      }\n    }\n  }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .g-col#{$infix}-#{$i} {\n            grid-column: auto / span $i;\n          }\n        }\n\n        // Start with `1` because `0` is and invalid value.\n        // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n        @for $i from 1 through ($columns - 1) {\n          .g-start#{$infix}-#{$i} {\n            grid-column-start: $i;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_image.scss",
    "content": "// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n  // Part 1: Set a maximum relative to the parent\n  max-width: 100%;\n  // Part 2: Override the height to auto, otherwise images will be stretched\n  // when setting a width and height attribute on the img element.\n  height: auto;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_list-group.scss",
    "content": "// List Groups\n\n// scss-docs-start list-group-mixin\n@mixin list-group-item-variant($state, $background, $color) {\n  .list-group-item-#{$state} {\n    color: $color;\n    background-color: $background;\n\n    &.list-group-item-action {\n      &:hover,\n      &:focus {\n        color: $color;\n        background-color: shade-color($background, 10%);\n      }\n\n      &.active {\n        color: $white;\n        background-color: $color;\n        border-color: $color;\n      }\n    }\n  }\n}\n// scss-docs-end list-group-mixin\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_lists.scss",
    "content": "// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_pagination.scss",
    "content": "// Pagination\n\n// scss-docs-start pagination-mixin\n@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) {\n  .page-link {\n    padding: $padding-y $padding-x;\n    @include font-size($font-size);\n  }\n\n  .page-item {\n    @if $pagination-margin-start == (-$pagination-border-width) {\n      &:first-child {\n        .page-link {\n          @include border-start-radius($border-radius);\n        }\n      }\n\n      &:last-child {\n        .page-link {\n          @include border-end-radius($border-radius);\n        }\n      }\n    } @else {\n      //Add border-radius to all pageLinks in case they have left margin\n      .page-link {\n        @include border-radius($border-radius);\n      }\n    }\n  }\n}\n// scss-docs-end pagination-mixin\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_reset-text.scss",
    "content": "@mixin reset-text {\n  font-family: $font-family-base;\n  // We deliberately do NOT reset font-size or overflow-wrap / word-wrap.\n  font-style: normal;\n  font-weight: $font-weight-normal;\n  line-height: $line-height-base;\n  text-align: left; // Fallback for where `start` is not supported\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_resize.scss",
    "content": "// Resize anything\n\n@mixin resizable($direction) {\n  overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`\n  resize: $direction; // Options: horizontal, vertical, both\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_table-variants.scss",
    "content": "// scss-docs-start table-variant\n@mixin table-variant($state, $background) {\n  .table-#{$state} {\n    $color: color-contrast(opaque($body-bg, $background));\n    $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));\n    $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));\n    $active-bg: mix($color, $background, percentage($table-active-bg-factor));\n\n    --#{$variable-prefix}table-bg: #{$background};\n    --#{$variable-prefix}table-striped-bg: #{$striped-bg};\n    --#{$variable-prefix}table-striped-color: #{color-contrast($striped-bg)};\n    --#{$variable-prefix}table-active-bg: #{$active-bg};\n    --#{$variable-prefix}table-active-color: #{color-contrast($active-bg)};\n    --#{$variable-prefix}table-hover-bg: #{$hover-bg};\n    --#{$variable-prefix}table-hover-color: #{color-contrast($hover-bg)};\n\n    color: $color;\n    border-color: mix($color, $background, percentage($table-border-factor));\n  }\n}\n// scss-docs-end table-variant\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_text-truncate.scss",
    "content": "// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_transition.scss",
    "content": "// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n  @if length($transition) == 0 {\n    $transition: $transition-base;\n  }\n\n  @if length($transition) > 1 {\n    @each $value in $transition {\n      @if $value == null or $value == none {\n        @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n      }\n    }\n  }\n\n  @if $enable-transitions {\n    @if nth($transition, 1) != null {\n      transition: $transition;\n    }\n\n    @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none {\n      @media (prefers-reduced-motion: reduce) {\n        transition: none;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_utilities.scss",
    "content": "// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix, $is-rfs-media-query: false) {\n  $values: map-get($utility, values);\n\n  // If the values are a list or string, convert it into a map\n  @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n    $values: zip($values, $values);\n  }\n\n  @each $key, $value in $values {\n    $properties: map-get($utility, property);\n\n    // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n    @if type-of($properties) == \"string\" {\n      $properties: append((), $properties);\n    }\n\n    // Use custom class if present\n    $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n    $property-class: if($property-class == null, \"\", $property-class);\n\n    // State params to generate pseudo-classes\n    $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n    $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n    // Don't prefix if value key is null (eg. with shadow class)\n    $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n    @if map-get($utility, rfs) {\n      // Inside the media query\n      @if $is-rfs-media-query {\n        $val: rfs-value($value);\n\n        // Do not render anything if fluid and non fluid values are the same\n        $value: if($val == rfs-fluid-value($value), null, $val);\n      }\n      @else {\n        $value: rfs-fluid-value($value);\n      }\n    }\n\n    $is-css-var: map-get($utility, css-var);\n    $is-local-vars: map-get($utility, local-vars);\n    $is-rtl: map-get($utility, rtl);\n\n    @if $value != null {\n      @if $is-rtl == false {\n        /* rtl:begin:remove */\n      }\n\n      @if $is-css-var {\n        .#{$property-class + $infix + $property-class-modifier} {\n          --#{$variable-prefix}#{$property-class}: #{$value};\n        }\n\n        @each $pseudo in $state {\n          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n            --#{$variable-prefix}#{$property-class}: #{$value};\n          }\n        }\n      } @else {\n        .#{$property-class + $infix + $property-class-modifier} {\n          @each $property in $properties {\n            @if $is-local-vars {\n              @each $local-var, $value in $is-local-vars {\n                --#{$variable-prefix}#{$local-var}: #{$value};\n              }\n            }\n            #{$property}: $value if($enable-important-utilities, !important, null);\n          }\n        }\n\n        @each $pseudo in $state {\n          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n            @each $property in $properties {\n              #{$property}: $value if($enable-important-utilities, !important, null);\n            }\n          }\n        }\n      }\n\n      @if $is-rtl == false {\n        /* rtl:end:remove */\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/mixins/_visually-hidden.scss",
    "content": "// stylelint-disable declaration-no-important\n\n// Hide content visually while keeping it accessible to assistive technologies\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin visually-hidden() {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n// Use to only display content when it's focused, or one of its child elements is focused\n// (i.e. when focus is within the element/container that the class was applied to)\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n\n@mixin visually-hidden-focusable() {\n  &:not(:focus):not(:focus-within) {\n    @include visually-hidden();\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/utilities/_api.scss",
    "content": "// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n  // Generate media query if needed\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    // Loop over each utility property\n    @each $key, $utility in $utilities {\n      // The utility can be disabled with `false`, thus check if the utility is a map first\n      // Only proceed if responsive media queries are enabled or if it's the base media query\n      @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n        @include generate-utility($utility, $infix);\n      }\n    }\n  }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n  @each $breakpoint in map-keys($grid-breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n      // Loop over each utility property\n      @each $key, $utility in $utilities {\n        // The utility can be disabled with `false`, thus check if the utility is a map first\n        // Only proceed if responsive media queries are enabled or if it's the base media query\n        @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n          @include generate-utility($utility, $infix, true);\n        }\n      }\n    }\n  }\n}\n\n\n// Print utilities\n@media print {\n  @each $key, $utility in $utilities {\n    // The utility can be disabled with `false`, thus check if the utility is a map first\n    // Then check if the utility needs print styles\n    @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n      @include generate-utility($utility, \"-print\");\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/bootstrap/scss/vendor/_rfs.scss",
    "content": "// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n  @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n  @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n  @error \"`#{$rfs-factor}` is not a valid  $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n  $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n  $dividend: abs($dividend);\n  $divisor: abs($divisor);\n  @if $dividend == 0 {\n    @return 0;\n  }\n  @if $divisor == 0 {\n    @error \"Cannot divide by 0\";\n  }\n  $remainder: $dividend;\n  $result: 0;\n  $factor: 10;\n  @while ($remainder > 0 and $precision >= 0) {\n    $quotient: 0;\n    @while ($remainder >= $divisor) {\n      $remainder: $remainder - $divisor;\n      $quotient: $quotient + 1;\n    }\n    $result: $result * 10 + $quotient;\n    $factor: $factor * .1;\n    $remainder: $remainder * 10;\n    $precision: $precision - 1;\n    @if ($precision < 0 and $remainder >= $divisor * 5) {\n      $result: $result + 1;\n    }\n  }\n  $result: $result * $factor * $sign;\n  $dividend-unit: unit($dividend);\n  $divisor-unit: unit($divisor);\n  $unit-map: (\n    \"px\": 1px,\n    \"rem\": 1rem,\n    \"em\": 1em,\n    \"%\": 1%\n  );\n  @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n    $result: $result * map-get($unit-map, $dividend-unit);\n  }\n  @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n  $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n  $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n  $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n  $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n  @if $rfs-two-dimensional {\n    @if $rfs-mode == max-media-query {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n    @else {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n  }\n  @else {\n    @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n      @content;\n    }\n  }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n  @if $rfs-class == disable and $rfs-mode == max-media-query {\n    // Adding an extra class increases specificity, which prevents the media query to override the property\n    &,\n    .disable-rfs &,\n    &.disable-rfs {\n      @content;\n    }\n  }\n  @else if $rfs-class == enable and $rfs-mode == min-media-query {\n    .enable-rfs &,\n    &.enable-rfs {\n      @content;\n    }\n  }\n  @else {\n    @content;\n  }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n  @if $rfs-class == enable {\n    @if $rfs-mode == min-media-query {\n      @content;\n    }\n\n    @include _rfs-media-query {\n      .enable-rfs &,\n      &.enable-rfs {\n        @content;\n      }\n    }\n  }\n  @else {\n    @if $rfs-class == disable and $rfs-mode == min-media-query {\n      .disable-rfs &,\n      &.disable-rfs {\n        @content;\n      }\n    }\n    @include _rfs-media-query {\n      @content;\n    }\n  }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      @if $unit == px {\n        // Convert to rem if needed\n        $val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n      }\n      @else if $unit == rem {\n        // Convert to px if needed\n        $val: $val + ' ' + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n      }\n      @else {\n        // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n        $val: $val + ' ' + $value;\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n      @if not $unit or $unit != px and $unit != rem {\n        $val: $val + ' ' + $value;\n      }\n\n      @else {\n        // Remove unit from $value for calculations\n        $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n        // Only add the media query if the value is greater than the minimum value\n        @if abs($value) <= $rfs-base-value or not $enable-rfs {\n          $val: $val + ' ' +  if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n        }\n        @else {\n          // Calculate the minimum value\n          $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n          // Calculate difference between $value and the minimum value\n          $value-diff: abs($value) - $value-min;\n\n          // Base value formatting\n          $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n          // Use negative value if needed\n          $min-width: if($value < 0, -$min-width, $min-width);\n\n          // Use `vmin` if two-dimensional is enabled\n          $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n          // Calculate the variable width between 0 and $rfs-breakpoint\n          $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n          // Return the calculated value\n          $val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')';\n        }\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n  @if $values != null {\n    $val: rfs-value($values);\n    $fluidVal: rfs-fluid-value($values);\n\n    // Do not print the media query if responsive & non-responsive values are the same\n    @if $val == $fluidVal {\n      #{$property}: $val;\n    }\n    @else {\n      @include _rfs-rule {\n        #{$property}: if($rfs-mode == max-media-query, $val, $fluidVal);\n\n        // Include safari iframe resize fix if needed\n        min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n      }\n\n      @include _rfs-media-query-rule {\n        #{$property}: if($rfs-mode == max-media-query, $fluidVal, $val);\n      }\n    }\n  }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n  @include rfs($value);\n}\n\n@mixin padding($value) {\n  @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n  @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n  @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n  @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n  @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n  @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n  @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n  @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n  @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n  @include rfs($value, margin-left);\n}\n"
  },
  {
    "path": "vendor/bootstrap.mask",
    "content": ".github\nbuild\ndist\nnuget\nsite\njs\n.babelrc.js\n.browserslistrc\n.bundlewatch.config.json\n.cspell.json\n.editorconfig\n.eslintignore\n.eslintrc.json\n.gitattributes\n.stylelintignore\n.stylelintrc\nCODE_OF_CONDUCT.md\nLICENSE\nREADME.md\nSECURITY.md\ncomposer.json\nconfig.yml\npackage-lock.json\npackage.js\npackage.json\n"
  },
  {
    "path": "vendor/core/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(core VERSION 0.0.0 LANGUAGES C CXX ASM_MASM DESCRIPTION \"Sourcemeta Core\")\nlist(APPEND CMAKE_MODULE_PATH \"${PROJECT_SOURCE_DIR}/cmake\")\n\n# Options\noption(SOURCEMETA_CORE_LANG_PREPROCESSOR \"Build the Sourcemeta Core language preprocessor library\" ON)\noption(SOURCEMETA_CORE_LANG_IO \"Build the Sourcemeta Core language I/O library\" ON)\noption(SOURCEMETA_CORE_LANG_PROCESS \"Build the Sourcemeta Core language Process library\" ON)\noption(SOURCEMETA_CORE_LANG_PARALLEL \"Build the Sourcemeta Core language parallel library\" ON)\noption(SOURCEMETA_CORE_LANG_NUMERIC \"Build the Sourcemeta Core language numeric library\" ON)\noption(SOURCEMETA_CORE_LANG_ERROR \"Build the Sourcemeta Core language error library\" ON)\noption(SOURCEMETA_CORE_LANG_OPTIONS \"Build the Sourcemeta Core Options library\" ON)\noption(SOURCEMETA_CORE_UNICODE \"Build the Sourcemeta Core Unicode library\" ON)\noption(SOURCEMETA_CORE_PUNYCODE \"Build the Sourcemeta Core Punycode library\" ON)\noption(SOURCEMETA_CORE_TIME \"Build the Sourcemeta Core time library\" ON)\noption(SOURCEMETA_CORE_CRYPTO \"Build the Sourcemeta Core Crypto library\" ON)\noption(SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL \"Use system OpenSSL for the Sourcemeta Core Crypto library\" OFF)\noption(SOURCEMETA_CORE_REGEX \"Build the Sourcemeta Core Regex library\" ON)\noption(SOURCEMETA_CORE_IP \"Build the Sourcemeta Core IP library\" ON)\noption(SOURCEMETA_CORE_DNS \"Build the Sourcemeta Core DNS library\" ON)\noption(SOURCEMETA_CORE_URI \"Build the Sourcemeta Core URI library\" ON)\noption(SOURCEMETA_CORE_URITEMPLATE \"Build the Sourcemeta Core URI Template library\" ON)\noption(SOURCEMETA_CORE_JSON \"Build the Sourcemeta Core JSON library\" ON)\noption(SOURCEMETA_CORE_JSONSCHEMA \"Build the Sourcemeta Core JSON Schema library\" ON)\noption(SOURCEMETA_CORE_JSONPOINTER \"Build the Sourcemeta Core JSON Pointer library\" ON)\noption(SOURCEMETA_CORE_JSONL \"Build the Sourcemeta Core JSONL library\" ON)\noption(SOURCEMETA_CORE_YAML \"Build the Sourcemeta Core YAML library\" ON)\noption(SOURCEMETA_CORE_SEMVER \"Build the Sourcemeta Core SemVer library\" ON)\noption(SOURCEMETA_CORE_GZIP \"Build the Sourcemeta Core GZIP library\" ON)\noption(SOURCEMETA_CORE_HTML \"Build the Sourcemeta Core HTML library\" ON)\noption(SOURCEMETA_CORE_MARKDOWN \"Build the Sourcemeta Core Markdown library\" ON)\noption(SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA \"Build the Sourcemeta Core EditorSchema library\" ON)\noption(SOURCEMETA_CORE_TESTS \"Build the Sourcemeta Core tests\" OFF)\noption(SOURCEMETA_CORE_BENCHMARK \"Build the Sourcemeta Core benchmarks\" OFF)\noption(SOURCEMETA_CORE_DOCS \"Build the Sourcemeta Core docs\" OFF)\noption(SOURCEMETA_CORE_INSTALL \"Install the Sourcemeta Core library\" ON)\noption(SOURCEMETA_CORE_ADDRESS_SANITIZER \"Build Sourcemeta Core with an address sanitizer\" OFF)\noption(SOURCEMETA_CORE_UNDEFINED_SANITIZER \"Build Sourcemeta Core with an undefined behavior sanitizer\" OFF)\noption(SOURCEMETA_CORE_CONTRIB_GOOGLETEST \"Build the GoogleTest library for downstream consumers\" OFF)\noption(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK \"Build the GoogleBenchmark library for downstream consumers\" OFF)\n\ninclude(Sourcemeta)\n\n# Don't force downstream consumers on this\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_enable_simd()\nendif()\n\n# TODO: Turn this into a re-usable utility CMake function\nif(SOURCEMETA_CORE_INSTALL)\n  include(GNUInstallDirs)\n  include(CMakePackageConfigHelpers)\n  configure_package_config_file(\n    config.cmake.in\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n  write_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    COMPATIBILITY SameMajorVersion)\n  install(FILES\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\"\n    COMPONENT sourcemeta_${PROJECT_NAME}_dev)\nendif()\n\nif(SOURCEMETA_CORE_LANG_PREPROCESSOR)\n  add_subdirectory(src/lang/preprocessor)\nendif()\n\nif(SOURCEMETA_CORE_LANG_IO)\n  add_subdirectory(src/lang/io)\nendif()\n\nif(SOURCEMETA_CORE_LANG_PROCESS)\n  add_subdirectory(src/lang/process)\nendif()\n\nif(SOURCEMETA_CORE_LANG_PARALLEL)\n  find_package(Threads REQUIRED)\n  add_subdirectory(src/lang/parallel)\nendif()\n\nif(SOURCEMETA_CORE_LANG_NUMERIC)\n  add_subdirectory(src/lang/numeric)\nendif()\n\nif(SOURCEMETA_CORE_LANG_ERROR)\n  add_subdirectory(src/lang/error)\nendif()\n\nif(SOURCEMETA_CORE_LANG_OPTIONS)\n  add_subdirectory(src/lang/options)\nendif()\n\nif(SOURCEMETA_CORE_UNICODE)\n  add_subdirectory(src/core/unicode)\nendif()\n\nif(SOURCEMETA_CORE_PUNYCODE)\n  add_subdirectory(src/core/punycode)\nendif()\n\nif(SOURCEMETA_CORE_TIME)\n  add_subdirectory(src/core/time)\nendif()\n\nif(SOURCEMETA_CORE_CRYPTO)\n  if(SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL)\n    find_package(OpenSSL REQUIRED)\n  endif()\n  add_subdirectory(src/core/crypto)\nendif()\n\nif(SOURCEMETA_CORE_REGEX)\n  find_package(PCRE2 REQUIRED)\n  add_subdirectory(src/core/regex)\nendif()\n\nif(SOURCEMETA_CORE_IP)\n  add_subdirectory(src/core/ip)\nendif()\n\nif(SOURCEMETA_CORE_DNS)\n  add_subdirectory(src/core/dns)\nendif()\n\nif(SOURCEMETA_CORE_URI)\n  add_subdirectory(src/core/uri)\nendif()\n\nif(SOURCEMETA_CORE_URITEMPLATE)\n  add_subdirectory(src/core/uritemplate)\nendif()\n\nif(SOURCEMETA_CORE_JSON)\n  add_subdirectory(src/core/json)\nendif()\n\nif(SOURCEMETA_CORE_JSONPOINTER)\n  add_subdirectory(src/core/jsonpointer)\nendif()\n\nif(SOURCEMETA_CORE_JSONSCHEMA)\n  add_subdirectory(src/core/jsonschema)\nendif()\n\nif(SOURCEMETA_CORE_GZIP)\n  find_package(LibDeflate REQUIRED)\n  find_package(ZLIB REQUIRED)\n  add_subdirectory(src/core/gzip)\nendif()\n\nif(SOURCEMETA_CORE_JSONL)\n  add_subdirectory(src/core/jsonl)\nendif()\n\nif(SOURCEMETA_CORE_YAML)\n  add_subdirectory(src/core/yaml)\nendif()\n\nif(SOURCEMETA_CORE_SEMVER)\n  add_subdirectory(src/core/semver)\nendif()\n\nif(SOURCEMETA_CORE_HTML)\n  add_subdirectory(src/core/html)\nendif()\n\nif(SOURCEMETA_CORE_MARKDOWN)\n  find_package(CMarkGFM REQUIRED)\n  add_subdirectory(src/core/markdown)\nendif()\n\nif(SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA)\n  add_subdirectory(src/extension/editorschema)\nendif()\n\nif(SOURCEMETA_CORE_ADDRESS_SANITIZER)\n  sourcemeta_sanitizer(TYPE address)\nelseif(SOURCEMETA_CORE_UNDEFINED_SANITIZER)\n  sourcemeta_sanitizer(TYPE undefined)\nendif()\n\nif(SOURCEMETA_CORE_DOCS)\n  sourcemeta_target_doxygen(CONFIG \"${PROJECT_SOURCE_DIR}/doxygen/Doxyfile.in\"\n    OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/website\")\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  sourcemeta_target_clang_format(SOURCES\n    src/*.h src/*.cc\n    benchmark/*.h benchmark/*.cc\n    test/*.h test/*.cc)\nendif()\n\n# Testing\n\nif(SOURCEMETA_CORE_CONTRIB_GOOGLETEST OR SOURCEMETA_CORE_TESTS)\n  find_package(GoogleTest REQUIRED)\nendif()\n\nif(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK OR SOURCEMETA_CORE_BENCHMARK)\n  find_package(GoogleBenchmark REQUIRED)\nendif()\n\nif(SOURCEMETA_CORE_TESTS)\n  enable_testing()\n\n  if(SOURCEMETA_CORE_LANG_IO)\n    add_subdirectory(test/io)\n  endif()\n\n  if(SOURCEMETA_CORE_LANG_PROCESS)\n    add_subdirectory(test/process)\n  endif()\n\n  if(SOURCEMETA_CORE_LANG_PARALLEL)\n    add_subdirectory(test/parallel)\n  endif()\n\n  if(SOURCEMETA_CORE_LANG_NUMERIC)\n    add_subdirectory(test/numeric)\n  endif()\n\n  if(SOURCEMETA_CORE_LANG_ERROR)\n    add_subdirectory(test/error)\n  endif()\n\n  if(SOURCEMETA_CORE_LANG_OPTIONS)\n    add_subdirectory(test/options)\n  endif()\n\n  if(SOURCEMETA_CORE_UNICODE)\n    add_subdirectory(test/unicode)\n  endif()\n\n  if(SOURCEMETA_CORE_PUNYCODE)\n    add_subdirectory(test/punycode)\n  endif()\n\n  if(SOURCEMETA_CORE_TIME)\n    add_subdirectory(test/time)\n  endif()\n\n  if(SOURCEMETA_CORE_CRYPTO)\n    add_subdirectory(test/crypto)\n  endif()\n\n  if(SOURCEMETA_CORE_REGEX)\n    add_subdirectory(test/regex)\n  endif()\n\n  if(SOURCEMETA_CORE_IP)\n    add_subdirectory(test/ip)\n  endif()\n\n  if(SOURCEMETA_CORE_DNS)\n    add_subdirectory(test/dns)\n  endif()\n\n  if(SOURCEMETA_CORE_URI)\n    add_subdirectory(test/uri)\n  endif()\n\n  if(SOURCEMETA_CORE_URITEMPLATE)\n    add_subdirectory(test/uritemplate)\n  endif()\n\n  if(SOURCEMETA_CORE_JSON)\n    add_subdirectory(test/json)\n  endif()\n\n  if(SOURCEMETA_CORE_JSONPOINTER)\n    add_subdirectory(test/jsonpointer)\n  endif()\n\n  if(SOURCEMETA_CORE_JSONSCHEMA)\n    add_subdirectory(test/jsonschema)\n  endif()\n\n  if(SOURCEMETA_CORE_GZIP)\n    add_subdirectory(test/gzip)\n  endif()\n\n  if(SOURCEMETA_CORE_JSONL)\n    add_subdirectory(test/jsonl)\n  endif()\n\n  if(SOURCEMETA_CORE_YAML)\n    add_subdirectory(test/yaml)\n  endif()\n\n  if(SOURCEMETA_CORE_SEMVER)\n    add_subdirectory(test/semver)\n  endif()\n\n  if(SOURCEMETA_CORE_HTML)\n    add_subdirectory(test/html)\n  endif()\n\n  if(SOURCEMETA_CORE_MARKDOWN)\n    add_subdirectory(test/markdown)\n  endif()\n\n  if(SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA)\n    add_subdirectory(test/editorschema)\n  endif()\n\n  if(PROJECT_IS_TOP_LEVEL)\n    # Otherwise we need the child project to link\n    # against the sanitizers too.\n    if(NOT SOURCEMETA_CORE_ADDRESS_SANITIZER AND NOT SOURCEMETA_CORE_UNDEFINED_SANITIZER)\n      add_subdirectory(test/packaging)\n    endif()\n  endif()\nendif()\n\nif(SOURCEMETA_CORE_BENCHMARK)\n  add_subdirectory(benchmark)\nendif()\n"
  },
  {
    "path": "vendor/core/DEPENDENCIES",
    "content": "vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02\njsontestsuite https://github.com/nst/JSONTestSuite d64aefb55228d9584d3e5b2433f720ea8fd00c82\nyaml-test-suite https://github.com/yaml/yaml-test-suite data-2022-01-17\ncmark-gfm https://github.com/github/cmark-gfm 587a12bb54d95ac37241377e6ddc93ea0e45439b\nzlib https://github.com/madler/zlib v1.3.2\njsonschema-2020-12 https://github.com/json-schema-org/json-schema-spec 769daad75a9553562333a8937a187741cb708c72\njsonschema-2019-09 https://github.com/json-schema-org/json-schema-spec 41014ea723120ce70b314d72f863c6929d9f3cfd\njsonschema-draft7 https://github.com/json-schema-org/json-schema-spec 567f768506aaa33a38e552c85bf0586029ef1b32\njsonschema-draft6 https://github.com/json-schema-org/json-schema-spec 59ed5f6fc6f6386e23ca51d7f31d7fe9cf696713\njsonschema-draft4 https://github.com/json-schema-org/json-schema-spec 955d185db846cfca84269d9d711b10f4f3353d38\njsonschema-draft3 https://github.com/json-schema-org/json-schema-spec 89912ad69fe15e006e8336a59e93bf7a1e46fa54\njsonschema-draft2 https://github.com/json-schema-org/json-schema-spec 707f65070d09fe5baa1315bce4d31a66ff124171\njsonschema-draft1 https://github.com/json-schema-org/json-schema-spec 2072feec9fc7a7ff0b2bb5b02c2d6742c554cc4a\njsonschema-draft0 https://github.com/json-schema-org/json-schema-spec 7ea575aef8d5c0183acbe6ff65b4c98ee9c236ec\nopenapi https://github.com/OAI/OpenAPI-Specification 74906beddddab9e555337031b2a8d8e9338c4972\nreferencing-suite https://github.com/python-jsonschema/referencing-suite 61c4cc202b1e96ed5adcaf4842a595f68d659212\nuritemplate-test https://github.com/uri-templates/uritemplate-test 1eb27ab4462b9e5819dc47db99044f5fd1fa9bc7\npyca-cryptography https://github.com/pyca/cryptography c4935a7021af37c38e0684b0546c1b4378518342\npcre2 https://github.com/PCRE2Project/pcre2 pcre2-10.47\ngoogletest https://github.com/google/googletest a7f443b80b105f940225332ed3c31f2790092f47\ngooglebenchmark https://github.com/google/benchmark 378fe693a1ef51500db21b11ff05a8018c5f0e55\nlibdeflate https://github.com/ebiggers/libdeflate v1.25\n"
  },
  {
    "path": "vendor/core/LICENSE",
    "content": "This software is dual-licensed: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version. For the terms of this license, see\n<http://www.gnu.org/licenses/>.\n\nYou are free to use this software under the terms of the GNU Affero General\nPublic License WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nAlternatively, you can use this software under a commercial license, as set out\nin <https://www.sourcemeta.com/licensing/>.\n"
  },
  {
    "path": "vendor/core/cmake/FindCMarkGFM.cmake",
    "content": "if(NOT CMarkGFM_FOUND)\n  set(CMARK_GFM_DIR \"${PROJECT_SOURCE_DIR}/vendor/cmark-gfm\")\n  set(CMARK_GFM_SOURCE_DIR \"${CMARK_GFM_DIR}/src\")\n  set(CMARK_GFM_EXTENSIONS_DIR \"${CMARK_GFM_DIR}/extensions\")\n  set(CMARK_GFM_BINARY_DIR \"${PROJECT_BINARY_DIR}/cmark-gfm\")\n\n  file(MAKE_DIRECTORY \"${CMARK_GFM_BINARY_DIR}/include\")\n\n  set(CMARK_GFM_VERSION_MAJOR 0)\n  set(CMARK_GFM_VERSION_MINOR 0)\n  set(CMARK_GFM_VERSION_PATCH 0)\n  set(CMARK_GFM_VERSION_GFM 0)\n\n  include(CheckIncludeFile)\n  include(CheckSymbolExists)\n  check_include_file(stdbool.h HAVE_STDBOOL_H)\n  check_symbol_exists(__builtin_expect \"\" HAVE___BUILTIN_EXPECT)\n\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    set(HAVE___ATTRIBUTE__ 1)\n  endif()\n\n  configure_file(\n    \"${CMARK_GFM_SOURCE_DIR}/config.h.in\"\n    \"${CMARK_GFM_BINARY_DIR}/include/config.h\")\n\n  set(_SAVED_PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})\n  set(_SAVED_PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR})\n  set(_SAVED_PROJECT_VERSION_PATCH ${PROJECT_VERSION_PATCH})\n  set(PROJECT_VERSION_MAJOR ${CMARK_GFM_VERSION_MAJOR})\n  set(PROJECT_VERSION_MINOR ${CMARK_GFM_VERSION_MINOR})\n  set(PROJECT_VERSION_PATCH ${CMARK_GFM_VERSION_PATCH})\n  set(PROJECT_VERSION_GFM ${CMARK_GFM_VERSION_GFM})\n  configure_file(\n    \"${CMARK_GFM_SOURCE_DIR}/cmark-gfm_version.h.in\"\n    \"${CMARK_GFM_BINARY_DIR}/include/cmark-gfm_version.h\")\n  set(PROJECT_VERSION_MAJOR ${_SAVED_PROJECT_VERSION_MAJOR})\n  set(PROJECT_VERSION_MINOR ${_SAVED_PROJECT_VERSION_MINOR})\n  set(PROJECT_VERSION_PATCH ${_SAVED_PROJECT_VERSION_PATCH})\n  unset(_SAVED_PROJECT_VERSION_MAJOR)\n  unset(_SAVED_PROJECT_VERSION_MINOR)\n  unset(_SAVED_PROJECT_VERSION_PATCH)\n\n  set(CMARK_GFM_CORE_SOURCES\n    \"${CMARK_GFM_SOURCE_DIR}/arena.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/blocks.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/buffer.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/cmark.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/cmark_ctype.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/commonmark.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/footnotes.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/houdini_href_e.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/houdini_html_e.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/houdini_html_u.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/html.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/inlines.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/iterator.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/latex.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/linked_list.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/man.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/map.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/node.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/plaintext.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/plugin.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/references.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/registry.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/render.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/scanners.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/syntax_extension.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/utf8.c\"\n    \"${CMARK_GFM_SOURCE_DIR}/xml.c\")\n\n  set(CMARK_GFM_EXTENSION_SOURCES\n    \"${CMARK_GFM_EXTENSIONS_DIR}/autolink.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/core-extensions.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/ext_scanners.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/strikethrough.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/table.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/tagfilter.c\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}/tasklist.c\")\n\n  add_library(cmark_gfm\n    ${CMARK_GFM_CORE_SOURCES} ${CMARK_GFM_EXTENSION_SOURCES})\n  sourcemeta_add_default_options(PRIVATE cmark_gfm)\n\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(cmark_gfm PRIVATE -Wno-sign-conversion)\n    target_compile_options(cmark_gfm PRIVATE -Wno-unused-parameter)\n  endif()\n\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(cmark_gfm PRIVATE /wd4100)\n    target_compile_definitions(cmark_gfm PRIVATE _CRT_SECURE_NO_WARNINGS)\n  endif()\n\n  target_include_directories(cmark_gfm PRIVATE\n    \"${CMARK_GFM_BINARY_DIR}/include\"\n    \"${CMARK_GFM_SOURCE_DIR}\"\n    \"${CMARK_GFM_EXTENSIONS_DIR}\")\n\n  target_include_directories(cmark_gfm PUBLIC\n    \"$<BUILD_INTERFACE:${CMARK_GFM_BINARY_DIR}/include>\"\n    \"$<BUILD_INTERFACE:${CMARK_GFM_SOURCE_DIR}>\"\n    \"$<BUILD_INTERFACE:${CMARK_GFM_EXTENSIONS_DIR}>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  target_compile_definitions(cmark_gfm PRIVATE HAVE_CONFIG_H)\n\n  include(GenerateExportHeader)\n  generate_export_header(cmark_gfm\n    BASE_NAME CMARK_GFM\n    EXPORT_FILE_NAME \"${CMARK_GFM_BINARY_DIR}/include/cmark-gfm_export.h\")\n\n  add_library(CMarkGFM::cmark_gfm ALIAS cmark_gfm)\n\n  set_target_properties(cmark_gfm\n    PROPERTIES\n      OUTPUT_NAME cmark_gfm\n      C_VISIBILITY_PRESET \"default\"\n      C_VISIBILITY_INLINES_HIDDEN FALSE\n      EXPORT_NAME cmark_gfm\n      WINDOWS_EXPORT_ALL_SYMBOLS OFF)\n\n  if(SOURCEMETA_CORE_INSTALL)\n    include(GNUInstallDirs)\n    install(TARGETS cmark_gfm\n      EXPORT cmark_gfm\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        COMPONENT sourcemeta_core\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core\n        NAMELINK_COMPONENT sourcemeta_core_dev\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core_dev)\n    install(EXPORT cmark_gfm\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/cmark_gfm\"\n      NAMESPACE CMarkGFM::\n      COMPONENT sourcemeta_core_dev)\n\n    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmark_gfm-config.cmake\n      \"include(\\\"\\${CMAKE_CURRENT_LIST_DIR}/cmark_gfm.cmake\\\")\\n\"\n      \"check_required_components(\\\"cmark_gfm\\\")\\n\")\n    install(FILES\n      \"${CMAKE_CURRENT_BINARY_DIR}/cmark_gfm-config.cmake\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/cmark_gfm\"\n      COMPONENT sourcemeta_core_dev)\n  endif()\n\n  set(CMarkGFM_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/FindGoogleBenchmark.cmake",
    "content": "if(NOT Benchmark_FOUND)\n  set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL \"enable testing of the benchmark library\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/googlebenchmark\")\n  set(Benchmark_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/FindGoogleTest.cmake",
    "content": "if(NOT GoogleTest_FOUND)\n  set(BUILD_GMOCK ON CACHE BOOL \"enable googlemock\")\n  set(INSTALL_GTEST OFF CACHE BOOL \"disable installation\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/googletest\")\n  set(GoogleTest_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/FindLibDeflate.cmake",
    "content": "if(NOT LibDeflate_FOUND)\n  set(LIBDEFLATE_DIR \"${PROJECT_SOURCE_DIR}/vendor/libdeflate\")\n  set(LIBDEFLATE_LIB_DIR \"${LIBDEFLATE_DIR}/lib\")\n  set(LIBDEFLATE_PUBLIC_HEADER \"${LIBDEFLATE_DIR}/libdeflate.h\")\n\n  set(LIBDEFLATE_SOURCES\n    \"${LIBDEFLATE_LIB_DIR}/utils.c\"\n    \"${LIBDEFLATE_LIB_DIR}/deflate_compress.c\"\n    \"${LIBDEFLATE_LIB_DIR}/deflate_decompress.c\"\n    \"${LIBDEFLATE_LIB_DIR}/gzip_compress.c\"\n    \"${LIBDEFLATE_LIB_DIR}/gzip_decompress.c\"\n    \"${LIBDEFLATE_LIB_DIR}/adler32.c\"\n    \"${LIBDEFLATE_LIB_DIR}/crc32.c\"\n    \"${LIBDEFLATE_LIB_DIR}/zlib_compress.c\"\n    \"${LIBDEFLATE_LIB_DIR}/zlib_decompress.c\")\n\n  # Platform-specific CPU feature detection\n  if(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|arm64|ARM64\")\n    list(APPEND LIBDEFLATE_SOURCES\n      \"${LIBDEFLATE_LIB_DIR}/arm/cpu_features.c\")\n  elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64|AMD64|amd64|x86|i[3-6]86\")\n    list(APPEND LIBDEFLATE_SOURCES\n      \"${LIBDEFLATE_LIB_DIR}/x86/cpu_features.c\")\n  endif()\n\n  add_library(libdeflate STATIC ${LIBDEFLATE_SOURCES})\n  sourcemeta_add_default_options(PRIVATE libdeflate)\n\n  # Check if the assembler supports ARM dot-product (udot) instructions.\n  if(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|arm64|ARM64\")\n    include(CheckCSourceCompiles)\n    if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\" AND\n        CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 14)\n      check_c_source_compiles(\"\n        #include <arm_neon.h>\n        __attribute__((target(\\\"+dotprod\\\")))\n        int test(void) {\n          uint32x4_t a = vdupq_n_u32(0);\n          uint8x16_t b = vdupq_n_u8(0);\n          uint8x16_t c = vdupq_n_u8(0);\n          a = vdotq_u32(a, b, c);\n          return (int)vgetq_lane_u32(a, 0);\n        }\n        int main(void) { return test(); }\n      \" LIBDEFLATE_HAS_DOTPROD_ASSEMBLER)\n    else()\n      set(LIBDEFLATE_SAVED_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n      set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} -march=armv8.2-a+dotprod\")\n      check_c_source_compiles(\"\n        #include <arm_neon.h>\n        int main(void) {\n          uint32x4_t a = vdupq_n_u32(0);\n          uint8x16_t b = vdupq_n_u8(0);\n          uint8x16_t c = vdupq_n_u8(0);\n          a = vdotq_u32(a, b, c);\n          return 0;\n        }\n      \" LIBDEFLATE_HAS_DOTPROD_ASSEMBLER)\n      set(CMAKE_REQUIRED_FLAGS \"${LIBDEFLATE_SAVED_CMAKE_REQUIRED_FLAGS}\")\n    endif()\n    if(NOT LIBDEFLATE_HAS_DOTPROD_ASSEMBLER)\n      target_compile_definitions(libdeflate PRIVATE\n        LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_DOTPROD)\n    endif()\n\n    if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\" AND\n        CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 14)\n      check_c_source_compiles(\"\n        #include <arm_neon.h>\n        __attribute__((target(\\\"+crypto,+crc,+sha3\\\")))\n        int test(void) {\n          uint8x16_t a = vdupq_n_u8(0);\n          uint8x16_t b = vdupq_n_u8(0);\n          uint8x16_t c = vdupq_n_u8(0);\n          a = veor3q_u8(a, b, c);\n          return (int)vgetq_lane_u8(a, 0);\n        }\n        int main(void) { return test(); }\n      \" LIBDEFLATE_HAS_SHA3_ASSEMBLER)\n    else()\n      set(LIBDEFLATE_SAVED_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n      set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} -march=armv8.2-a+crypto+crc+sha3\")\n      check_c_source_compiles(\"\n        #include <arm_neon.h>\n        int main(void) {\n          uint8x16_t a = vdupq_n_u8(0);\n          uint8x16_t b = vdupq_n_u8(0);\n          uint8x16_t c = vdupq_n_u8(0);\n          a = veor3q_u8(a, b, c);\n          return 0;\n        }\n      \" LIBDEFLATE_HAS_SHA3_ASSEMBLER)\n      set(CMAKE_REQUIRED_FLAGS \"${LIBDEFLATE_SAVED_CMAKE_REQUIRED_FLAGS}\")\n    endif()\n    if(NOT LIBDEFLATE_HAS_SHA3_ASSEMBLER)\n      target_compile_definitions(libdeflate PRIVATE\n        LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_SHA3)\n    endif()\n  endif()\n\n  target_include_directories(libdeflate PUBLIC\n    \"$<BUILD_INTERFACE:${LIBDEFLATE_DIR}>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  target_include_directories(libdeflate PRIVATE\n    \"${LIBDEFLATE_LIB_DIR}\")\n\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(libdeflate PRIVATE -Wno-conversion)\n    target_compile_options(libdeflate PRIVATE -Wno-sign-conversion)\n    target_compile_options(libdeflate PRIVATE -Wno-sign-compare)\n    target_compile_options(libdeflate PRIVATE -Wno-implicit-int-conversion)\n    target_compile_options(libdeflate PRIVATE -Wno-shorten-64-to-32)\n    target_compile_options(libdeflate PRIVATE -Wno-unused-parameter)\n  endif()\n\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(libdeflate PRIVATE /wd4113)\n    target_compile_options(libdeflate PRIVATE /wd4244)\n    target_compile_options(libdeflate PRIVATE /wd4267)\n  endif()\n\n  set_target_properties(libdeflate\n    PROPERTIES\n      OUTPUT_NAME deflate\n      PUBLIC_HEADER \"${LIBDEFLATE_PUBLIC_HEADER}\"\n      C_VISIBILITY_PRESET \"default\"\n      C_VISIBILITY_INLINES_HIDDEN FALSE\n      EXPORT_NAME LibDeflate)\n\n  add_library(LibDeflate::LibDeflate ALIAS libdeflate)\n\n  if(SOURCEMETA_CORE_INSTALL)\n    include(GNUInstallDirs)\n    install(TARGETS libdeflate\n      EXPORT libdeflate\n      PUBLIC_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\"\n        COMPONENT sourcemeta_core_dev\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        COMPONENT sourcemeta_core\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core\n        NAMELINK_COMPONENT sourcemeta_core_dev\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core_dev)\n    install(EXPORT libdeflate\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/libdeflate\"\n      NAMESPACE LibDeflate::\n      COMPONENT sourcemeta_core_dev)\n\n    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/libdeflate-config.cmake\n      \"include(\\\"\\${CMAKE_CURRENT_LIST_DIR}/libdeflate.cmake\\\")\\n\"\n      \"check_required_components(\\\"libdeflate\\\")\\n\")\n    install(FILES\n      \"${CMAKE_CURRENT_BINARY_DIR}/libdeflate-config.cmake\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/libdeflate\"\n      COMPONENT sourcemeta_core_dev)\n  endif()\n\n  set(LibDeflate_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/FindPCRE2.cmake",
    "content": "if(NOT PCRE2_FOUND)\n  set(PCRE2_DIR \"${PROJECT_SOURCE_DIR}/vendor/pcre2\")\n  set(PCRE2_SOURCE_DIR \"${PCRE2_DIR}/src\")\n  set(PCRE2_BINARY_DIR \"${PROJECT_BINARY_DIR}/pcre2\")\n\n  file(MAKE_DIRECTORY \"${PCRE2_BINARY_DIR}/interface\")\n  file(MAKE_DIRECTORY \"${PCRE2_BINARY_DIR}/src\")\n\n  set(HAVE_ASSERT_H 1)\n  set(HAVE_SYS_STAT_H 1)\n  set(HAVE_SYS_TYPES_H 1)\n\n  if(WIN32)\n    set(HAVE_WINDOWS_H 1)\n  else()\n    set(HAVE_DIRENT_H 1)\n    set(HAVE_UNISTD_H 1)\n  endif()\n\n  set(PCRE2_MAJOR 0)\n  set(PCRE2_MINOR 0)\n  set(PCRE2_PRERELEASE \"\")\n  set(PCRE2_DATE \"0000-00-00\")\n\n  set(PCRE2_LINK_SIZE 2)\n  set(PCRE2_PARENS_NEST_LIMIT 250)\n  set(PCRE2_HEAP_LIMIT 20000000)\n  set(PCRE2_MAX_VARLOOKBEHIND 255)\n  set(PCRE2_MATCH_LIMIT 10000000)\n  set(PCRE2_MATCH_LIMIT_DEPTH MATCH_LIMIT)\n  set(PCRE2GREP_BUFSIZE 20480)\n  set(PCRE2GREP_MAX_BUFSIZE 1048576)\n  set(NEWLINE_DEFAULT 2)\n\n  if(WIN32 AND BUILD_SHARED_LIBS)\n    set(PCRE2_EXPORT \"__declspec(dllexport)\")\n  else()\n    set(PCRE2_EXPORT)\n  endif()\n\n  set(SUPPORT_PCRE2_8 1)\n  set(SUPPORT_UNICODE 1)\n  set(SUPPORT_JIT 1)\n\n  configure_file(\n    \"${PCRE2_SOURCE_DIR}/pcre2.h.in\"\n    \"${PCRE2_BINARY_DIR}/interface/pcre2.h\"\n    @ONLY)\n\n  configure_file(\n    \"${PCRE2_SOURCE_DIR}/config-cmake.h.in\"\n    \"${PCRE2_BINARY_DIR}/src/config.h\"\n    @ONLY)\n\n  configure_file(\n    \"${PCRE2_SOURCE_DIR}/pcre2_chartables.c.dist\"\n    \"${PCRE2_BINARY_DIR}/src/pcre2_chartables.c\"\n    COPYONLY)\n\n  set(PCRE2_PUBLIC_HEADER \"${PCRE2_BINARY_DIR}/interface/pcre2.h\")\n\n  set(PCRE2_SOURCES\n    \"${PCRE2_SOURCE_DIR}/pcre2_auto_possess.c\"\n    \"${PCRE2_BINARY_DIR}/src/pcre2_chartables.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_chkdint.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_compile.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_compile_cgroup.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_compile_class.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_config.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_context.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_convert.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_dfa_match.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_error.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_extuni.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_find_bracket.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_jit_compile.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_maketables.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_match.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_match_data.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_match_next.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_newline.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_ord2utf.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_pattern_info.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_script_run.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_serialize.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_string_utils.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_study.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_substitute.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_substring.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_tables.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_ucd.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_valid_utf.c\"\n    \"${PCRE2_SOURCE_DIR}/pcre2_xclass.c\")\n\n  set(SLJIT_DIR \"${PCRE2_DIR}/deps/sljit/sljit_src\")\n  set(SLJIT_SOURCES \"${SLJIT_DIR}/sljitLir.c\")\n\n  add_library(sljit STATIC ${SLJIT_SOURCES})\n  sourcemeta_add_default_options(PRIVATE sljit)\n\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(sljit PRIVATE -Wno-double-promotion)\n    target_compile_options(sljit PRIVATE -Wno-conditional-uninitialized)\n  endif()\n\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(sljit PRIVATE /sdl-)\n    target_compile_options(sljit PRIVATE /wd4701)\n    target_compile_options(sljit PRIVATE /wd4702)\n    target_compile_options(sljit PRIVATE /wd4127)\n  endif()\n\n  target_include_directories(sljit PUBLIC\n    \"$<BUILD_INTERFACE:${SLJIT_DIR}>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  target_compile_definitions(sljit PRIVATE SLJIT_CONFIG_AUTO=1)\n\n  if(SOURCEMETA_OS_LINUX)\n    target_compile_definitions(sljit PRIVATE _GNU_SOURCE)\n  endif()\n\n  set_target_properties(sljit\n    PROPERTIES\n      OUTPUT_NAME sljit\n      C_VISIBILITY_PRESET \"default\"\n      C_VISIBILITY_INLINES_HIDDEN FALSE\n      EXPORT_NAME sljit)\n\n  add_library(pcre2 ${PCRE2_SOURCES})\n  sourcemeta_add_default_options(PRIVATE pcre2)\n\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(pcre2 PRIVATE -Wno-implicit-int-conversion)\n    target_compile_options(pcre2 PRIVATE -Wno-sign-conversion)\n    target_compile_options(pcre2 PRIVATE -Wno-comma)\n    target_compile_options(pcre2 PRIVATE -Wno-conditional-uninitialized)\n    target_compile_options(pcre2 PRIVATE -Wno-overlength-strings)\n    target_compile_options(pcre2 PRIVATE -Wno-conversion)\n    target_compile_options(pcre2 PRIVATE -Wno-type-limits)\n  endif()\n\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(pcre2 PRIVATE /sdl-)\n    target_compile_options(pcre2 PRIVATE /wd4127)\n    target_compile_options(pcre2 PRIVATE /wd4244)\n    target_compile_options(pcre2 PRIVATE /wd4389)\n    target_compile_options(pcre2 PRIVATE /wd4701)\n    target_compile_options(pcre2 PRIVATE /wd4702)\n  endif()\n\n  target_include_directories(pcre2 PRIVATE\n    \"${PCRE2_BINARY_DIR}/interface\"\n    \"${PCRE2_BINARY_DIR}/src\"\n    \"${PCRE2_SOURCE_DIR}\")\n\n  target_include_directories(pcre2 PUBLIC\n    \"$<BUILD_INTERFACE:${PCRE2_BINARY_DIR}/interface>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  target_compile_definitions(pcre2 PRIVATE HAVE_CONFIG_H)\n  target_compile_definitions(pcre2 PUBLIC PCRE2_CODE_UNIT_WIDTH=8)\n  target_compile_definitions(pcre2 PRIVATE SUPPORT_PCRE2_8=1)\n  target_compile_definitions(pcre2 PRIVATE SUPPORT_UNICODE=1)\n  target_compile_definitions(pcre2 PRIVATE SUPPORT_JIT=1)\n\n  if(NOT BUILD_SHARED_LIBS)\n    target_compile_definitions(pcre2 PUBLIC PCRE2_STATIC=1)\n  endif()\n\n  if(SOURCEMETA_OS_LINUX)\n    target_compile_definitions(pcre2 PRIVATE _GNU_SOURCE)\n  endif()\n\n  target_link_libraries(pcre2 PRIVATE sljit)\n\n  add_library(PCRE2::pcre2 ALIAS pcre2)\n\n  set_target_properties(pcre2\n    PROPERTIES\n      OUTPUT_NAME pcre2\n      PUBLIC_HEADER \"${PCRE2_PUBLIC_HEADER}\"\n      C_VISIBILITY_PRESET \"default\"\n      C_VISIBILITY_INLINES_HIDDEN FALSE\n      EXPORT_NAME pcre2\n      WINDOWS_EXPORT_ALL_SYMBOLS OFF)\n\n  if(SOURCEMETA_CORE_INSTALL)\n    include(GNUInstallDirs)\n    install(TARGETS sljit pcre2\n      EXPORT pcre2\n      PUBLIC_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\"\n        COMPONENT sourcemeta_core_dev\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        COMPONENT sourcemeta_core\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core\n        NAMELINK_COMPONENT sourcemeta_core_dev\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core_dev)\n    install(EXPORT pcre2\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/pcre2\"\n      NAMESPACE PCRE2::\n      COMPONENT sourcemeta_core_dev)\n\n    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pcre2-config.cmake\n      \"include(\\\"\\${CMAKE_CURRENT_LIST_DIR}/pcre2.cmake\\\")\\n\"\n      \"check_required_components(\\\"pcre2\\\")\\n\")\n    install(FILES\n      \"${CMAKE_CURRENT_BINARY_DIR}/pcre2-config.cmake\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/pcre2\"\n      COMPONENT sourcemeta_core_dev)\n  endif()\n\n  set(PCRE2_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/FindZLIB.cmake",
    "content": "if(NOT ZLIB_FOUND)\n  set(ZLIB_DIR \"${PROJECT_SOURCE_DIR}/vendor/zlib\")\n  set(ZLIB_PUBLIC_HEADER \"${ZLIB_DIR}/zlib.h\")\n  set(ZLIB_PRIVATE_HEADERS \"${ZLIB_DIR}/zconf.h\")\n\n  add_library(zlib\n    \"${ZLIB_PUBLIC_HEADER}\" ${ZLIB_PRIVATE_HEADERS}\n    \"${ZLIB_DIR}/adler32.c\"\n    \"${ZLIB_DIR}/compress.c\"\n    \"${ZLIB_DIR}/crc32.c\"\n    \"${ZLIB_DIR}/crc32.h\"\n    \"${ZLIB_DIR}/deflate.c\"\n    \"${ZLIB_DIR}/deflate.h\"\n    \"${ZLIB_DIR}/gzclose.c\"\n    \"${ZLIB_DIR}/gzguts.h\"\n    \"${ZLIB_DIR}/gzlib.c\"\n    \"${ZLIB_DIR}/gzread.c\"\n    \"${ZLIB_DIR}/gzwrite.c\"\n    \"${ZLIB_DIR}/infback.c\"\n    \"${ZLIB_DIR}/inffast.c\"\n    \"${ZLIB_DIR}/inffast.h\"\n    \"${ZLIB_DIR}/inffixed.h\"\n    \"${ZLIB_DIR}/inflate.c\"\n    \"${ZLIB_DIR}/inflate.h\"\n    \"${ZLIB_DIR}/inftrees.c\"\n    \"${ZLIB_DIR}/inftrees.h\"\n    \"${ZLIB_DIR}/trees.c\"\n    \"${ZLIB_DIR}/trees.h\"\n    \"${ZLIB_DIR}/uncompr.c\"\n    \"${ZLIB_DIR}/zutil.c\"\n    \"${ZLIB_DIR}/zutil.h\")\n\n  target_compile_definitions(zlib PUBLIC NO_FSEEKO)\n  target_compile_definitions(zlib PUBLIC _LARGEFILE64_SOURCE=1)\n\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(zlib PRIVATE /W3 /MP /wd4996)\n    target_compile_definitions(zlib PRIVATE _CRT_SECURE_NO_WARNINGS)\n  else()\n    target_compile_options(zlib PRIVATE\n      -Wall\n      -Wextra\n      -Wpedantic\n      -Werror\n      -Wdouble-promotion\n      -Wfloat-equal\n      -Wmissing-declarations\n      -Wshadow\n      -Wwrite-strings\n      -Wno-cast-align\n      -Wno-cast-qual\n      -Wno-format-nonliteral\n      -Wno-sign-conversion\n      -Wno-shorten-64-to-32\n      -Wno-implicit-int-conversion\n      -Wno-comma\n      -Wno-implicit-fallthrough)\n\n    if(NOT CMAKE_BUILD_TYPE STREQUAL \"Debug\")\n      target_compile_options(zlib PRIVATE\n        -funroll-loops\n        -fstrict-aliasing\n        -ftree-vectorize\n        -fno-math-errno\n        -fwrapv)\n    endif()\n\n    # Disable LTO for zlib to work around GCC LTO linker plugin not\n    # properly rescanning this archive for transitive dependencies\n    if(SOURCEMETA_COMPILER_GCC)\n      target_compile_options(zlib PRIVATE -fno-lto)\n    endif()\n  endif()\n\n  target_include_directories(zlib PUBLIC\n    \"$<BUILD_INTERFACE:${ZLIB_DIR}>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  add_library(ZLIB::ZLIB ALIAS zlib)\n\n  set_target_properties(zlib\n    PROPERTIES\n      OUTPUT_NAME zlib\n      PUBLIC_HEADER \"${ZLIB_PUBLIC_HEADER}\"\n      PRIVATE_HEADER \"${ZLIB_PRIVATE_HEADERS}\"\n      C_STANDARD 11\n      C_STANDARD_REQUIRED ON\n      C_EXTENSIONS OFF\n      POSITION_INDEPENDENT_CODE ON\n      C_VISIBILITY_PRESET \"default\"\n      C_VISIBILITY_INLINES_HIDDEN FALSE\n      VISIBILITY_INLINES_HIDDEN OFF\n      WINDOWS_EXPORT_ALL_SYMBOLS TRUE\n      EXPORT_NAME ZLIB)\n\n  if(SOURCEMETA_CORE_INSTALL)\n    include(GNUInstallDirs)\n    install(TARGETS zlib\n      EXPORT zlib\n      PUBLIC_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\"\n        COMPONENT sourcemeta_core_dev\n      PRIVATE_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\"\n        COMPONENT sourcemeta_core_dev\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        COMPONENT sourcemeta_core\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core\n        NAMELINK_COMPONENT sourcemeta_core_dev\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_core_dev)\n    install(EXPORT zlib\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/zlib\"\n      NAMESPACE ZLIB::\n      COMPONENT sourcemeta_core_dev)\n\n    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/zlib-config.cmake\n      \"include(\\\"\\${CMAKE_CURRENT_LIST_DIR}/zlib.cmake\\\")\\n\"\n      \"check_required_components(\\\"zlib\\\")\\n\")\n    install(FILES\n      \"${CMAKE_CURRENT_BINARY_DIR}/zlib-config.cmake\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/zlib\"\n      COMPONENT sourcemeta_core_dev)\n  endif()\n\n  set(ZLIB_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/Sourcemeta.cmake",
    "content": "set(SOURCEMETA_UTILITIES_DIRECTORY \"${CMAKE_CURRENT_LIST_DIR}/common\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/shim.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/variables.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/defaults.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/compiler/simd.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/compiler/sanitizer.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/compiler/options.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/options/enum.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/commands/copy-file.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/library.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/executable.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/clang-format.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/shellcheck.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/doxygen.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/googletest.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/targets/googlebenchmark.cmake\")\ninclude(\"${SOURCEMETA_UTILITIES_DIRECTORY}/clang-tidy.cmake\")\n\n# To let downstream projects directly include this file\nif(NOT PROJECT_IS_TOP_LEVEL)\n  set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\" PARENT_SCOPE)\nendif()\n\n# For debugging purposes\nif(PROJECT_IS_TOP_LEVEL)\n  message(STATUS \"CMAKE_VERSION: ${CMAKE_VERSION}\")\n  message(STATUS \"CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}\")\n  message(STATUS \"CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}\")\n  message(STATUS \"CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}\")\n  message(STATUS \"CMAKE_HOST_SYSTEM_PROCESSOR: ${CMAKE_HOST_SYSTEM_PROCESSOR}\")\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/common/clang-tidy.cmake",
    "content": "function(sourcemeta_clang_tidy_attempt_install)\n  cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL \"\" \"OUTPUT_DIRECTORY\" \"\" ${ARGN})\n  if(NOT SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY)\n    message(FATAL_ERROR \"You must pass the output directory in the OUTPUT_DIRECTORY option\")\n  endif()\n\n  # See https://pypi.org/project/clang-tidy/\n  set(CLANG_TIDY_BINARY_VERSION \"20.1.0\")\n  set(CLANG_TIDY_BINARY_Windows_AMD64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl\")\n  set(CLANG_TIDY_BINARY_MSYS_x86_64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl\")\n  set(CLANG_TIDY_BINARY_Darwin_arm64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_11_0_arm64.whl\")\n  set(CLANG_TIDY_BINARY_Darwin_x86_64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_10_9_x86_64.whl\")\n  set(CLANG_TIDY_BINARY_Linux_aarch64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\")\n  set(CLANG_TIDY_BINARY_Linux_x86_64 \"clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_Windows_AMD64 \"02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_MSYS_x86_64 \"02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_arm64 \"95/02/838baf08764b08327322096bda55e8d1e2344e4a13b9308e5642cfaafd8e\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_x86_64 \"6d/5b/dcfc84b895d8544e00186738ca85132bbd14db4d11dbe39502630ece5391\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_Linux_aarch64 \"be/61/9e1a0797639e81c41d38d7b8b2508a9be4b05b9a23baa9d64e7284d07238\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_Linux_x86_64 \"52/76/42c61be1c1fdf8bacdbb265f0cd3e11321fee7362f91fa840717a6a41ad6\")\n  set(CLANG_TIDY_BINARY_NAME_Windows_AMD64 \"clang-tidy.exe\")\n  set(CLANG_TIDY_BINARY_NAME_MSYS_x86_64 \"clang-tidy.exe\")\n  set(CLANG_TIDY_BINARY_NAME_Darwin_arm64 \"clang-tidy\")\n  set(CLANG_TIDY_BINARY_NAME_Darwin_x86_64 \"clang-tidy\")\n  set(CLANG_TIDY_BINARY_NAME_Linux_aarch64 \"clang-tidy\")\n  set(CLANG_TIDY_BINARY_NAME_Linux_x86_64 \"clang-tidy\")\n\n  # Determine the pre-built binary URL\n  string(REPLACE \".\" \"_\" CLANG_TIDY_BINARY_SYSTEM \"${CMAKE_SYSTEM_NAME}\")\n  string(REPLACE \".\" \"_\" CLANG_TIDY_BINARY_ARCH \"${CMAKE_SYSTEM_PROCESSOR}\")\n  set(CLANG_TIDY_BINARY_URL_VAR \"CLANG_TIDY_BINARY_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}\")\n  set(CLANG_TIDY_BINARY_CHECKSUM_VAR \"CLANG_TIDY_BINARY_CHECKSUM_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}\")\n  set(CLANG_TIDY_BINARY_NAME_VAR \"CLANG_TIDY_BINARY_NAME_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}\")\n  if(NOT DEFINED ${CLANG_TIDY_BINARY_URL_VAR} OR \"${${CLANG_TIDY_BINARY_URL_VAR}}\" STREQUAL \"\")\n    message(WARNING \"Skipping `clang-tidy` download. No known pre-build binary URL\")\n    return()\n  elseif(NOT DEFINED ${CLANG_TIDY_BINARY_CHECKSUM_VAR} OR \"${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}\" STREQUAL \"\")\n    message(FATAL_ERROR \"No known `clang-tidy` pre-build binary checksum\")\n  elseif(NOT DEFINED ${CLANG_TIDY_BINARY_NAME_VAR} OR \"${${CLANG_TIDY_BINARY_NAME_VAR}}\" STREQUAL \"\")\n    message(FATAL_ERROR \"No known `clang-tidy` pre-build binary name\")\n  endif()\n  set(CLANG_TIDY_BINARY_URL \"https://files.pythonhosted.org/packages/${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}/${${CLANG_TIDY_BINARY_URL_VAR}}\")\n\n  # Download and extract the pre-built binary ZIP if needed\n  set(CLANG_TIDY_BINARY_NAME \"${${CLANG_TIDY_BINARY_NAME_VAR}}\")\n  set(CLANG_TIDY_BINARY_OUTPUT \"${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}/${CLANG_TIDY_BINARY_NAME}\")\n  if(EXISTS \"${CLANG_TIDY_BINARY_OUTPUT}\")\n    message(STATUS \"Found existing `clang-tidy` pre-built binary at ${CLANG_TIDY_BINARY_OUTPUT}\")\n    return()\n  endif()\n  set(CLANG_TIDY_BINARY_DOWNLOAD_DIR \"${CMAKE_CURRENT_BINARY_DIR}/clang-tidy\")\n  file(REMOVE_RECURSE \"${CLANG_TIDY_BINARY_DOWNLOAD_DIR}\")\n  file(MAKE_DIRECTORY \"${CLANG_TIDY_BINARY_DOWNLOAD_DIR}\")\n  set(CLANG_TIDY_BINARY_WHEEL \"${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/clang-tidy.whl\")\n  message(STATUS \"Downloading `clang-tidy` pre-built binary from ${CLANG_TIDY_BINARY_URL}\")\n  file(DOWNLOAD \"${CLANG_TIDY_BINARY_URL}\" \"${CLANG_TIDY_BINARY_WHEEL}\"\n    STATUS CLANG_TIDY_BINARY_DOWNLOAD_STATUS SHOW_PROGRESS TLS_VERIFY ON\n    LOG CLANG_TIDY_BINARY_DOWNLOAD_LOG)\n  list(GET CLANG_TIDY_BINARY_DOWNLOAD_STATUS 0 _code)\n  if(NOT _code EQUAL 0)\n    message(WARNING \"Failed to download the `clang-tidy` pre-built binary\")\n    message(WARNING \"${CLANG_TIDY_BINARY_DOWNLOAD_LOG}\")\n    file(REMOVE_RECURSE \"${CLANG_TIDY_BINARY_DOWNLOAD_DIR}\")\n    return()\n  endif()\n  set(CLANG_TIDY_BINARY_EXTRACT_DIR \"${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/extracted\")\n  file(MAKE_DIRECTORY \"${CLANG_TIDY_BINARY_EXTRACT_DIR}\")\n  file(ARCHIVE_EXTRACT INPUT \"${CLANG_TIDY_BINARY_WHEEL}\" DESTINATION \"${CLANG_TIDY_BINARY_EXTRACT_DIR}\")\n\n  # Install the binary\n  file(MAKE_DIRECTORY \"${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}\")\n  file(COPY \"${CLANG_TIDY_BINARY_EXTRACT_DIR}/clang_tidy/data/bin/${CLANG_TIDY_BINARY_NAME}\"\n       DESTINATION \"${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}\")\n  file(CHMOD \"${CLANG_TIDY_BINARY_OUTPUT}\" PERMISSIONS\n       OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)\n  message(STATUS \"Installed `clang-tidy` pre-built binary to ${CLANG_TIDY_BINARY_OUTPUT}\")\nendfunction()\n\nfunction(sourcemeta_clang_tidy_attempt_enable)\n  cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_ENABLE \"\" \"TARGET\" \"\" ${ARGN})\n  if(NOT SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_ENABLE_TARGET)\n    message(FATAL_ERROR \"You must pass the target name using the TARGET option\")\n  endif()\n\n  # TODO: Support other platforms too, like Linux\n  if(APPLE AND SOURCEMETA_COMPILER_LLVM)\n    message(STATUS \"Enabling ClangTidy alongside compilation for target ${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_ENABLE_TARGET}\")\n  else()\n    return()\n  endif()\n\n  # We rely on this cache variable to not pre-compute the ClangTidy\n  # setup over and over again for every single target\n  if(NOT SOURCEMETA_CXX_CLANG_TIDY)\n    sourcemeta_clang_tidy_attempt_install(\n      OUTPUT_DIRECTORY \"${PROJECT_BINARY_DIR}/bin\")\n    find_program(CLANG_TIDY_BIN NAMES clang-tidy\n        NO_DEFAULT_PATH\n        PATHS \"${PROJECT_BINARY_DIR}/bin\"\n        REQUIRED)\n\n    set(CLANG_TIDY_CONFIG \"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.json\")\n    execute_process(COMMAND xcrun --show-sdk-path\n        OUTPUT_VARIABLE MACOSX_SDK_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)\n    execute_process(COMMAND \"${CMAKE_CXX_COMPILER}\" -print-resource-dir\n        OUTPUT_VARIABLE MACOSX_RESOURCE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)\n    set(SOURCEMETA_CXX_CLANG_TIDY\n        \"${CLANG_TIDY_BIN};--config-file=${CLANG_TIDY_CONFIG};-header-filter=${PROJECT_SOURCE_DIR}/src/*\"\n        \"--extra-arg=-isysroot\"\n        \"--extra-arg=${MACOSX_SDK_PATH}\"\n        \"--extra-arg=-resource-dir=${MACOSX_RESOURCE_PATH}\"\n        CACHE STRING \"CXX_CLANG_TIDY\")\n  endif()\n\n  set_target_properties(\"${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_ENABLE_TARGET}\"\n    PROPERTIES CXX_CLANG_TIDY \"${SOURCEMETA_CXX_CLANG_TIDY}\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/clang-tidy.json",
    "content": "{\n  \"Checks\": \"-*, bugprone-*, -bugprone-easily-swappable-parameters,-bugprone-unchecked-optional-access, concurrency-*,cppcoreguidelines-missing-std-forward,\n cppcoreguidelines-avoid-const-or-ref-data-members, modernize-*, performance-*, portability-*\",\n  \"WarningsAsErrors\": \"*\",\n  \"FormatStyle\": \"none\",\n  \"UseColor\": true\n}\n"
  },
  {
    "path": "vendor/core/cmake/common/commands/copy-file.cmake",
    "content": "function(sourcemeta_command_copy_file)\n  cmake_parse_arguments(SOURCEMETA_COMMAND_COPY_FILE \"\" \"FROM;TO\" \"\" ${ARGN})\n\n  if(NOT SOURCEMETA_COMMAND_COPY_FILE_FROM)\n    message(FATAL_ERROR \"You must pass the file to copy using the FROM option\")\n  endif()\n  if(NOT SOURCEMETA_COMMAND_COPY_FILE_TO)\n    message(FATAL_ERROR \"You must pass the destination to copy to using the TO option\")\n  endif()\n\n  add_custom_command(\n    OUTPUT \"${SOURCEMETA_COMMAND_COPY_FILE_TO}\"\n    COMMAND \"${CMAKE_COMMAND}\" -E copy \"${SOURCEMETA_COMMAND_COPY_FILE_FROM}\" \"${SOURCEMETA_COMMAND_COPY_FILE_TO}\"\n    MAIN_DEPENDENCY \"${SOURCEMETA_COMMAND_COPY_FILE_FROM}\"\n    DEPENDS \"${SOURCEMETA_COMMAND_COPY_FILE_FROM}\"\n    COMMENT \"Copying ${SOURCEMETA_COMMAND_COPY_FILE_FROM} ot ${SOURCEMETA_COMMAND_COPY_FILE_TO}\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/compiler/options.cmake",
    "content": "function(sourcemeta_add_default_options visibility target)\n  if(SOURCEMETA_COMPILER_MSVC)\n    # See https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category\n    target_compile_options(\"${target}\" ${visibility}\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/options:strict>\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/permissive->\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/W4>\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/WL>\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/MP>\n      $<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:/sdl>)\n  elseif(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(\"${target}\" ${visibility}\n      -Wall\n      -Wextra\n      -Wpedantic\n      -Wshadow\n      -Wdouble-promotion\n      -Wconversion\n      -Wunused-parameter\n      -Wtrigraphs\n      -Wunreachable-code\n      -Wmissing-braces\n      -Wparentheses\n      -Wswitch\n      -Wunused-function\n      -Wunused-label\n      -Wunused-parameter\n      -Wunused-variable\n      -Wunused-value\n      -Wempty-body\n      -Wuninitialized\n      -Wshadow\n      -Wconversion\n      -Wenum-conversion\n      -Wfloat-conversion\n      -Wimplicit-fallthrough\n      -Wsign-compare\n      -Wsign-conversion\n      -Wunknown-pragmas\n      $<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-Wnon-virtual-dtor>\n      $<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-Woverloaded-virtual>\n      $<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-Winvalid-offsetof>\n      -funroll-loops\n      -fstrict-aliasing\n      -ftree-vectorize\n\n      # To improve how much GCC/Clang will vectorize\n      -fno-math-errno\n      -fno-trapping-math\n      -fno-signed-zeros\n      -freciprocal-math\n      -fassociative-math\n\n      # Assume that signed arithmetic overflow of addition, subtraction and\n      # multiplication wraps around using twos-complement representation\n      # See https://users.cs.utah.edu/~regehr/papers/overflow12.pdf\n      # See https://www.postgresql.org/message-id/1689.1134422394@sss.pgh.pa.us\n      -fwrapv)\n  endif()\n\n  if(SOURCEMETA_COMPILER_LLVM)\n    target_compile_options(\"${target}\" ${visibility}\n      -Wbool-conversion\n      -Wint-conversion\n      -Wpointer-sign\n      -Wconditional-uninitialized\n      -Wconstant-conversion\n      -Wnon-literal-null-conversion\n      -Wshorten-64-to-32\n      -Wdeprecated-implementations\n      -Winfinite-recursion\n      -Wnewline-eof\n      -Wfour-char-constants\n      -Wselector\n      -Wundeclared-selector\n      -Wdocumentation\n      -Wmove\n      -Wc++11-extensions\n      -Wcomma\n      -Wno-exit-time-destructors\n      -Wrange-loop-analysis\n\n      # Enable loop vectorization for performance reasons\n      -fvectorize\n      # Enable vectorization of straight-line code for performance\n      -fslp-vectorize)\n  elseif(SOURCEMETA_COMPILER_GCC)\n    target_compile_options(\"${target}\" ${visibility}\n      # Newer versions of GCC (i.e. 14) seem to print a lot of false-positives here\n      $<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-Wno-dangling-reference>\n      # GCC seems to print a lot of false-positives here\n      -Wno-free-nonheap-object\n      # Disables runtime type information\n      $<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-fno-rtti>)\n  endif()\nendfunction()\n\n# For studying failed vectorization results\n# - On Clang , seems to only take effect on release shared builds\n# - On GCC, seems to only take effect on release shared builds\nfunction(sourcemeta_add_vectorization_diagnostics target)\n  if(SOURCEMETA_COMPILER_LLVM)\n    # See https://llvm.org/docs/Vectorizers.html#id6\n    target_compile_options(\"${target}\" PRIVATE\n      -Rpass-analysis=loop-vectorize\n      -Rpass-missed=loop-vectorize)\n  elseif(SOURCEMETA_COMPILER_GCC)\n    target_compile_options(\"${target}\" PRIVATE\n      -fopt-info-vec-missed\n      -fopt-info-loop-missed)\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/compiler/sanitizer.cmake",
    "content": "function(sourcemeta_sanitizer)\n  cmake_parse_arguments(SOURCEMETA_SANITIZER \"\" \"TYPE\" \"\" ${ARGN})\n\n  if(NOT SOURCEMETA_SANITIZER_TYPE)\n    message(FATAL_ERROR \"You must pass the intended sanitizer\")\n  endif()\n\n  if(SOURCEMETA_COMPILER_LLVM AND \"${SOURCEMETA_SANITIZER_TYPE}\" STREQUAL \"address\")\n    # See https://clang.llvm.org/docs/AddressSanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang AddressSanitizer\")\n    add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope)\n    add_link_options(-fsanitize=address)\n    # Get nicer stack traces with the Address sanitizer\n    add_compile_options(-fno-omit-frame-pointer -fno-optimize-sibling-calls)\n    add_compile_options(-O1)\n  elseif(SOURCEMETA_COMPILER_LLVM AND \"${SOURCEMETA_SANITIZER_TYPE}\" STREQUAL \"memory\")\n    if(APPLE)\n      message(FATAL_ERROR \"Clang MemorySanitizer is not available on Apple platforms\")\n    endif()\n\n    # See https://clang.llvm.org/docs/MemorySanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang MemorySanitizer\")\n    add_compile_options(-fsanitize=memory -fno-sanitize-memory-use-after-dtor)\n    add_link_options(-fsanitize=memory)\n    # Get nicer stack traces with the Memory sanitizer\n    add_compile_options(-fno-omit-frame-pointer -fno-optimize-sibling-calls)\n    add_compile_options(-O1)\n  elseif(SOURCEMETA_COMPILER_LLVM AND \"${SOURCEMETA_SANITIZER_TYPE}\" STREQUAL \"undefined\")\n    # See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang UndefinedBehaviorSanitizer\")\n    add_compile_options(-fsanitize=undefined,nullability,integer,implicit-conversion,local-bounds\n      -fno-sanitize=unsigned-integer-overflow)\n    add_link_options(-fsanitize=undefined,nullability,integer,implicit-conversion,local-bounds\n      -fno-sanitize=unsigned-integer-overflow)\n    # Exit after an error, otherwise this sanitizer only prints warnings\n    add_compile_options(-fno-sanitize-recover=all)\n  else()\n    message(FATAL_ERROR \"Unrecognized compiler and/or sanitizer combination\")\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/compiler/simd.cmake",
    "content": "macro(sourcemeta_enable_simd)\n  # Attempt to enable SIMD (SSE/AVX/NEON)\n  include(CheckCXXCompilerFlag)\n  if(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86|AMD64\")\n    if(MSVC)\n      check_cxx_compiler_flag(\"/arch:AVX2\" COMPILER_SUPPORTS_AVX2)\n      if(COMPILER_SUPPORTS_AVX2)\n        message(STATUS \"Enabling SIMD AVX2\")\n        set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /arch:AVX2\")\n      elseif(NOT CMAKE_CL_64)\n        message(STATUS \"Enabling SIMD SSE2\")\n        set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /arch:SSE2\")\n      endif()\n    else()\n      check_cxx_compiler_flag(\"-mavx2\" COMPILER_SUPPORTS_AVX2)\n      if(COMPILER_SUPPORTS_AVX2)\n        message(STATUS \"Enabling SIMD AVX2\")\n        set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -mavx2\")\n      else()\n        check_cxx_compiler_flag(\"-msse4.2\" COMPILER_SUPPORTS_SSE42)\n        if(COMPILER_SUPPORTS_SSE42)\n          message(STATUS \"Enabling SIMD SSE4.2\")\n          set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -msse4.2\")\n        else()\n          check_cxx_compiler_flag(\"-msse2\" COMPILER_SUPPORTS_SSE2)\n          if(COMPILER_SUPPORTS_SSE2)\n            message(STATUS \"Enabling SIMD SSE2\")\n            set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -msse2\")\n          endif()\n        endif()\n      endif()\n    endif()\n  elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"arm64|aarch64\" AND NOT MSVC)\n    check_cxx_compiler_flag(\"-march=armv8-a+fp+simd\" COMPILER_SUPPORTS_NEON)\n    if(COMPILER_SUPPORTS_NEON)\n      message(STATUS \"Enabling SIMD NEON\")\n      set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -march=armv8-a+fp+simd\")\n    endif()\n  endif()\nendmacro()\n"
  },
  {
    "path": "vendor/core/cmake/common/defaults.cmake",
    "content": "# Standards (sane modern defaults)\nif(\"CXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_CXX_STANDARD 23)\nendif()\nif(\"C\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_C_STANDARD 11)\nendif()\nif(\"OBJCXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_OBJCXX_STANDARD \"${CMAKE_CXX_STANDARD}\")\nendif()\n\n# Hide symbols from shared libraries by default\n# In certain compilers, like GCC and Clang,\n# symbols are visible by default.\nset(CMAKE_VISIBILITY_INLINES_HIDDEN YES)\nif(\"CXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_CXX_VISIBILITY_PRESET hidden)\nendif()\nif(\"C\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_C_VISIBILITY_PRESET hidden)\nendif()\nif(\"OBJCXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)\nendif()\n\n# By default, stay within ISO C++\nif(\"CXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_CXX_STANDARD_REQUIRED ON)\n  set(CMAKE_CXX_EXTENSIONS OFF)\nendif()\nif(\"C\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_C_STANDARD_REQUIRED ON)\n  set(CMAKE_C_EXTENSIONS OFF)\nendif()\nif(\"OBJCXX\" IN_LIST SOURCEMETA_LANGUAGES)\n  set(CMAKE_OBJCXX_STANDARD_REQUIRED ON)\n  set(CMAKE_OBJCXX_EXTENSIONS OFF)\nendif()\n\n# Export compile commands by default.\n# It is very useful for IDE integration, linting, etc\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n# Always prefer PIC, even on static libraries\n# See https://cmake.org/cmake/help/latest/prop_tgt/POSITION_INDEPENDENT_CODE.html\nset(CMAKE_POSITION_INDEPENDENT_CODE ON)\n\n# CMake typically defaults to -O2 for RelWithDebInfo, which can\n# result in slight differences when comparing to Release when\n# profiling or analysing the resulting assembly\n# See https://stackoverflow.com/a/59314670\nif(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n  set(CMAKE_C_FLAGS_RELWITHDEBINFO \"-O3 -g\" CACHE STRING \"Optimization level for RelWithDebInfo (C)\" FORCE)\n  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO \"-O3 -g\" CACHE STRING \"Optimization level for RelWithDebInfo (C++)\" FORCE)\n  set(CMAKE_OBJC_FLAGS_RELWITHDEBINFO \"-O3 -g\" CACHE STRING \"Optimization level for RelWithDebInfo (Objective-C)\" FORCE)\n  set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO \"-O3 -g\" CACHE STRING \"Optimization level for RelWithDebInfo (Objective-C++)\" FORCE)\nendif()\n\n# Prevent DT_RPATH/DT_RUNPATH problem\n# This problem is not present on Apple platforms.\n# See https://www.youtube.com/watch?v=m0DwB4OvDXk\nif(NOT APPLE)\n  set(CMAKE_INSTALL_RPATH $ORIGIN)\nendif()\n\n# Delay GoogleTest discovery until before running the tests\n# See https://discourse.cmake.org/t/default-value-for-new-discovery-mode-option-for-gtest-discover-tests/1422\nset(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE PRE_TEST)\n\n# Always use folders in IDE\n# See https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html\nset_property(GLOBAL PROPERTY USE_FOLDERS ON)\n\n# On Windows, during build, put executables and libraries in the same directory.\n# Otherwise, if there is any shared library being generated, the binaries\n# linking to it will not be able to find it and i.e. unit tests will fail.\n# Note that GoogleTest does this already to a non-configurable top-level\n# `bin` directory, so adopting that convention here.\n# See https://stackoverflow.com/q/39807664\n# See https://github.com/google/googletest/blob/e47544ad31cb3ceecd04cc13e8fe556f8df9fe0b/googletest/cmake/internal_utils.cmake#L173-L174\nif(WIN32)\n  # For EXE files\n  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\" CACHE STRING \"\")\n  # For DLL files\n  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\" CACHE STRING \"\")\nendif()\n\n# Enable IPO/LTO to help the compiler optimize across modules.\n# Only do so in release, given these optimizations can significantly\n# increase build times.\n\n# Note we don't use CheckIPOSupported and CMAKE_INTERPROCEDURAL_OPTIMIZATION,\n# as those CMake features can only enable thin LTO. For Fat LTO, see:\n# - https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html\n# - https://llvm.org/docs/FatLTO.html\n\n# Note we don't enable LTO on RelWithDebInfo, as it breaks debugging symbols\n# on at least AppleClang, making stepping through source code impossible.\n\n# LTO is applied globally because it is a whole-program optimization.\n# Every translation unit must be compiled with LTO flags for the linker\n# to perform cross-module optimization effectively.\nif(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n  if(SOURCEMETA_COMPILER_GCC AND NOT BUILD_SHARED_LIBS)\n    message(STATUS \"Enabling Fat LTO\")\n    add_compile_options(-flto -ffat-lto-objects)\n    add_link_options(-flto)\n  endif()\n\n  # TODO: Make this work on Linux on LLVM\n  if(SOURCEMETA_COMPILER_LLVM AND NOT BUILD_SHARED_LIBS AND APPLE)\n    message(STATUS \"Enabling Fat LTO\")\n    add_compile_options(-flto=full)\n    add_link_options(-flto=full)\n  endif()\nendif()\n\n# Turn on POSIX.1-2008 compatibility on MSYS2\n# At least GoogleTest does not seem to compile without this\nif(CMAKE_SYSTEM_NAME STREQUAL \"MSYS\")\n  add_compile_definitions(_POSIX_C_SOURCE=200809L)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/common/options/enum.cmake",
    "content": "function(sourcemeta_option_enum)\n  cmake_parse_arguments(SOURCEMETA_OPTION_ENUM \"\" \"NAME;DEFAULT;DESCRIPTION\" \"CHOICES\" ${ARGN})\n\n  if(NOT SOURCEMETA_OPTION_ENUM_NAME)\n    message(FATAL_ERROR \"You must pass the option name as NAME\")\n  endif()\n  if(NOT SOURCEMETA_OPTION_ENUM_DEFAULT)\n    message(FATAL_ERROR \"You must pass the option default value as DEFAULT\")\n  endif()\n  if(NOT \"${SOURCEMETA_OPTION_ENUM_DEFAULT}\" IN_LIST SOURCEMETA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"Default value of ${SOURCEMETA_OPTION_ENUM_NAME} must be one of these: ${SOURCEMETA_OPTION_ENUM_CHOICES}\")\n  endif()\n  if(NOT SOURCEMETA_OPTION_ENUM_DESCRIPTION)\n    message(FATAL_ERROR \"You must pass the option description as DESCRIPTION\")\n  endif()\n  if(NOT SOURCEMETA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"You must pass the option enum choices as CHOICES\")\n  endif()\n\n  # Declare the option\n  set(\"${SOURCEMETA_OPTION_ENUM_NAME}\" \"${SOURCEMETA_OPTION_ENUM_DEFAULT}\"\n    CACHE STRING \"${SOURCEMETA_OPTION_ENUM_DESCRIPTION}\")\n\n  # Display a nice set of options in `cmake-gui`\n  set_property(CACHE \"${SOURCEMETA_OPTION_ENUM_NAME}\"\n    PROPERTY STRINGS ${SOURCEMETA_OPTION_ENUM_CHOICES})\n\n  # Perform validation\n  if(NOT \"${${SOURCEMETA_OPTION_ENUM_NAME}}\" IN_LIST SOURCEMETA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"Value of ${SOURCEMETA_OPTION_ENUM_NAME} must be one of these: ${SOURCEMETA_OPTION_ENUM_CHOICES}\")\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/shim.cmake",
    "content": "# The PROJECT_IS_TOP_LEVEL handy variable is only\n# available on CMake >=3.21.\nif(NOT DEFINED PROJECT_IS_TOP_LEVEL AND \"${CMAKE_PROJECT_NAME}\" STREQUAL \"${PROJECT_NAME}\")\n  set(PROJECT_IS_TOP_LEVEL YES)\nendif()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/clang-format.cmake",
    "content": "function(sourcemeta_target_clang_format_attempt_install)\n  cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_FORMAT_ATTEMPT_INSTALL \"\" \"OUTPUT_DIRECTORY\" \"\" ${ARGN})\n  if(NOT SOURCEMETA_TARGET_CLANG_FORMAT_ATTEMPT_INSTALL_OUTPUT_DIRECTORY)\n    message(FATAL_ERROR \"You must pass the output directory in the OUTPUT_DIRECTORY option\")\n  endif()\n\n  # See https://pypi.org/project/clang-format/\n  set(CLANG_FORMAT_BINARY_VERSION \"20.1.6\")\n  set(CLANG_FORMAT_BINARY_Windows_AMD64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-win_amd64.whl\")\n  set(CLANG_FORMAT_BINARY_MSYS_x86_64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-win_amd64.whl\")\n  set(CLANG_FORMAT_BINARY_Darwin_arm64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-macosx_11_0_arm64.whl\")\n  set(CLANG_FORMAT_BINARY_Darwin_x86_64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-macosx_10_9_x86_64.whl\")\n  set(CLANG_FORMAT_BINARY_Linux_aarch64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\")\n  set(CLANG_FORMAT_BINARY_Linux_x86_64 \"clang_format-${CLANG_FORMAT_BINARY_VERSION}-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_Windows_AMD64 \"76/d0/2781f7699ce9ff1f5f9035d30cdb4c46f40b6acf191e0100543c289f46be\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_MSYS_x86_64 \"76/d0/2781f7699ce9ff1f5f9035d30cdb4c46f40b6acf191e0100543c289f46be\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_Darwin_arm64 \"fd/27/171dcef3288369bc0f7034307cebc6ea5d9a2b03d44e5cfa5a218f0e4f53\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_Darwin_x86_64 \"ac/f7/01502ff0869985df8b47ae62cdace425f02dfcd61b463a046f873ad5d2e2\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_Linux_aarch64 \"b1/51/2a0f401f5a5e27f97b8ebfed6ca9c4ccc2809cabafa2f97c7ac8e5b0d882\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_Linux_x86_64 \"b9/5e/7713e11945fa8018589e37a60052a1b1a2485be2292fcf382d154231eab6\")\n  set(CLANG_FORMAT_BINARY_NAME_Windows_AMD64 \"clang-format.exe\")\n  set(CLANG_FORMAT_BINARY_NAME_MSYS_x86_64 \"clang-format.exe\")\n  set(CLANG_FORMAT_BINARY_NAME_Darwin_arm64 \"clang-format\")\n  set(CLANG_FORMAT_BINARY_NAME_Darwin_x86_64 \"clang-format\")\n  set(CLANG_FORMAT_BINARY_NAME_Linux_aarch64 \"clang-format\")\n  set(CLANG_FORMAT_BINARY_NAME_Linux_x86_64 \"clang-format\")\n\n  # Determine the pre-built binary URL\n  string(REPLACE \".\" \"_\" CLANG_FORMAT_BINARY_SYSTEM \"${CMAKE_SYSTEM_NAME}\")\n  string(REPLACE \".\" \"_\" CLANG_FORMAT_BINARY_ARCH \"${CMAKE_SYSTEM_PROCESSOR}\")\n  set(CLANG_FORMAT_BINARY_URL_VAR \"CLANG_FORMAT_BINARY_${CLANG_FORMAT_BINARY_SYSTEM}_${CLANG_FORMAT_BINARY_ARCH}\")\n  set(CLANG_FORMAT_BINARY_CHECKSUM_VAR \"CLANG_FORMAT_BINARY_CHECKSUM_${CLANG_FORMAT_BINARY_SYSTEM}_${CLANG_FORMAT_BINARY_ARCH}\")\n  set(CLANG_FORMAT_BINARY_NAME_VAR \"CLANG_FORMAT_BINARY_NAME_${CLANG_FORMAT_BINARY_SYSTEM}_${CLANG_FORMAT_BINARY_ARCH}\")\n  if(NOT DEFINED ${CLANG_FORMAT_BINARY_URL_VAR} OR \"${${CLANG_FORMAT_BINARY_URL_VAR}}\" STREQUAL \"\")\n    message(WARNING \"Skipping `clang-format` download. No known pre-build binary URL\")\n    return()\n  elseif(NOT DEFINED ${CLANG_FORMAT_BINARY_CHECKSUM_VAR} OR \"${${CLANG_FORMAT_BINARY_CHECKSUM_VAR}}\" STREQUAL \"\")\n    message(FATAL_ERROR \"No known `clang-format` pre-build binary checksum\")\n  elseif(NOT DEFINED ${CLANG_FORMAT_BINARY_NAME_VAR} OR \"${${CLANG_FORMAT_BINARY_NAME_VAR}}\" STREQUAL \"\")\n    message(FATAL_ERROR \"No known `clang-format` pre-build binary name\")\n  endif()\n  set(CLANG_FORMAT_BINARY_URL \"https://files.pythonhosted.org/packages/${${CLANG_FORMAT_BINARY_CHECKSUM_VAR}}/${${CLANG_FORMAT_BINARY_URL_VAR}}\")\n\n  # Download and extract the pre-built binary ZIP if needed\n  set(CLANG_FORMAT_BINARY_NAME \"${${CLANG_FORMAT_BINARY_NAME_VAR}}\")\n  set(CLANG_FORMAT_BINARY_OUTPUT \"${SOURCEMETA_TARGET_CLANG_FORMAT_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}/${CLANG_FORMAT_BINARY_NAME}\")\n  if(EXISTS \"${CLANG_FORMAT_BINARY_OUTPUT}\")\n    message(STATUS \"Found existing `clang-format` pre-built binary at ${CLANG_FORMAT_BINARY_OUTPUT}\")\n    return()\n  endif()\n  set(CLANG_FORMAT_BINARY_DOWNLOAD_DIR \"${CMAKE_CURRENT_BINARY_DIR}/clang-format\")\n  file(REMOVE_RECURSE \"${CLANG_FORMAT_BINARY_DOWNLOAD_DIR}\")\n  file(MAKE_DIRECTORY \"${CLANG_FORMAT_BINARY_DOWNLOAD_DIR}\")\n  set(CLANG_FORMAT_BINARY_WHEEL \"${CLANG_FORMAT_BINARY_DOWNLOAD_DIR}/clang-format.whl\")\n  message(STATUS \"Downloading `clang-format` pre-built binary from ${CLANG_FORMAT_BINARY_URL}\")\n  file(DOWNLOAD \"${CLANG_FORMAT_BINARY_URL}\" \"${CLANG_FORMAT_BINARY_WHEEL}\"\n    STATUS CLANG_FORMAT_BINARY_DOWNLOAD_STATUS SHOW_PROGRESS TLS_VERIFY ON\n    LOG CLANG_FORMAT_BINARY_DOWNLOAD_LOG)\n  list(GET CLANG_FORMAT_BINARY_DOWNLOAD_STATUS 0 _code)\n  if(NOT _code EQUAL 0)\n    message(WARNING \"Failed to download the `clang-format` pre-built binary\")\n    message(WARNING \"${CLANG_FORMAT_BINARY_DOWNLOAD_LOG}\")\n    file(REMOVE_RECURSE \"${CLANG_FORMAT_BINARY_DOWNLOAD_DIR}\")\n    return()\n  endif()\n  set(CLANG_FORMAT_BINARY_EXTRACT_DIR \"${CLANG_FORMAT_BINARY_DOWNLOAD_DIR}/extracted\")\n  file(MAKE_DIRECTORY \"${CLANG_FORMAT_BINARY_EXTRACT_DIR}\")\n  file(ARCHIVE_EXTRACT INPUT \"${CLANG_FORMAT_BINARY_WHEEL}\" DESTINATION \"${CLANG_FORMAT_BINARY_EXTRACT_DIR}\")\n\n  # Install the binary\n  file(MAKE_DIRECTORY \"${SOURCEMETA_TARGET_CLANG_FORMAT_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}\")\n  file(COPY \"${CLANG_FORMAT_BINARY_EXTRACT_DIR}/clang_format/data/bin/${CLANG_FORMAT_BINARY_NAME}\"\n       DESTINATION \"${SOURCEMETA_TARGET_CLANG_FORMAT_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}\")\n  file(CHMOD \"${CLANG_FORMAT_BINARY_OUTPUT}\" PERMISSIONS\n       OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)\n  message(STATUS \"Installed `clang-format` pre-built binary to ${CLANG_FORMAT_BINARY_OUTPUT}\")\nendfunction()\n\nfunction(sourcemeta_target_clang_format)\n  cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_FORMAT \"REQUIRED\" \"\" \"SOURCES\" ${ARGN})\n  sourcemeta_target_clang_format_attempt_install(OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/bin\")\n\n  if(SOURCEMETA_TARGET_CLANG_FORMAT_REQUIRED)\n    find_program(CLANG_FORMAT_BIN NAMES clang-format NO_DEFAULT_PATH\n      PATHS \"${CMAKE_CURRENT_BINARY_DIR}/bin\")\n    if(NOT CLANG_FORMAT_BIN)\n      find_program(CLANG_FORMAT_BIN NAMES clang-format REQUIRED)\n    endif()\n  else()\n    find_program(CLANG_FORMAT_BIN NAMES clang-format NO_DEFAULT_PATH\n      PATHS \"${CMAKE_CURRENT_BINARY_DIR}/bin\")\n    if(NOT CLANG_FORMAT_BIN)\n      find_program(CLANG_FORMAT_BIN NAMES clang-format)\n    endif()\n  endif()\n\n  # This covers the empty list too\n  if(NOT SOURCEMETA_TARGET_CLANG_FORMAT_SOURCES)\n    message(FATAL_ERROR \"You must pass file globs to format in the SOURCES option\")\n  endif()\n  file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_FORMAT_FILES\n    ${SOURCEMETA_TARGET_CLANG_FORMAT_SOURCES})\n\n  set(CLANG_FORMAT_CONFIG \"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-format.json\")\n  if(CMAKE_SYSTEM_NAME STREQUAL \"MSYS\")\n    # Because `clang-format` is typically a Windows `.exe`, transform the path accordingly\n    execute_process(COMMAND cygpath -w \"${CLANG_FORMAT_CONFIG}\"\n      OUTPUT_VARIABLE CLANG_FORMAT_CONFIG OUTPUT_STRIP_TRAILING_WHITESPACE)\n  endif()\n\n  if(CLANG_FORMAT_BIN)\n    message(STATUS \"Using `clang-format` from ${CLANG_FORMAT_BIN}\")\n    add_custom_target(clang_format\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CLANG_FORMAT_BIN}\" \"--style=file:${CLANG_FORMAT_CONFIG}\"\n        -i ${SOURCEMETA_TARGET_CLANG_FORMAT_FILES}\n      COMMENT \"Formatting sources using ClangFormat\")\n    add_custom_target(clang_format_test\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CLANG_FORMAT_BIN}\" \"--style=file:${CLANG_FORMAT_CONFIG}\"\n        --dry-run -Werror\n        -i ${SOURCEMETA_TARGET_CLANG_FORMAT_FILES}\n      COMMENT \"Checking for ClangFormat compliance\")\n  else()\n    add_custom_target(clang_format\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ClangFormat\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n    add_custom_target(clang_format_test\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ClangFormat\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\n\n  set_target_properties(clang_format clang_format_test PROPERTIES FOLDER \"Formatting\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/clang-format.json",
    "content": "{\n  \"BasedOnStyle\": \"LLVM\",\n  \"IndentCaseLabels\": true\n}\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/doxygen.cmake",
    "content": "function(sourcemeta_target_doxygen)\n  cmake_parse_arguments(SOURCEMETA_TARGET_DOXYGEN \"\" \"CONFIG;OUTPUT\" \"\" ${ARGN})\n\n  if(NOT SOURCEMETA_TARGET_DOXYGEN_CONFIG)\n    message(FATAL_ERROR \"You must pass an input config file using the CONFIG option\")\n  endif()\n  if(NOT SOURCEMETA_TARGET_DOXYGEN_OUTPUT)\n    message(FATAL_ERROR \"You must pass an output directory using the OUTPUT option\")\n  endif()\n\n  find_package(Doxygen)\n  if(DOXYGEN_FOUND)\n    set(DOXYGEN_IN \"${SOURCEMETA_TARGET_DOXYGEN_CONFIG}\")\n    set(DOXYGEN_OUT \"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile\")\n    configure_file(\"${DOXYGEN_IN}\" \"${DOXYGEN_OUT}\" @ONLY)\n    add_custom_target(doxygen\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E make_directory \"${SOURCEMETA_TARGET_DOXYGEN_OUTPUT}\"\n      COMMAND \"${DOXYGEN_EXECUTABLE}\" \"${DOXYGEN_OUT}\")\n  else()\n    add_custom_target(doxygen VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate Doxygen\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/executable.cmake",
    "content": "function(sourcemeta_executable)\n  cmake_parse_arguments(SOURCEMETA_EXECUTABLE \"\"\n    \"NAMESPACE;PROJECT;NAME;VARIANT;OUTPUT\" \"SOURCES\" ${ARGN})\n\n  if(NOT SOURCEMETA_EXECUTABLE_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT SOURCEMETA_EXECUTABLE_NAME)\n    message(FATAL_ERROR \"You must pass the executable name using the NAME option\")\n  endif()\n  if(NOT SOURCEMETA_EXECUTABLE_SOURCES)\n    message(FATAL_ERROR \"You must pass the sources list using the SOURCES option\")\n  endif()\n\n  if(SOURCEMETA_EXECUTABLE_NAMESPACE)\n    set(TARGET_NAME \"${SOURCEMETA_EXECUTABLE_NAMESPACE}_${SOURCEMETA_EXECUTABLE_PROJECT}_${SOURCEMETA_EXECUTABLE_NAME}\")\n    set(FOLDER_NAME \"${SOURCEMETA_EXECUTABLE_NAMESPACE}/${SOURCEMETA_EXECUTABLE_PROJECT}/${SOURCEMETA_EXECUTABLE_NAME}\")\n  else()\n    set(TARGET_NAME \"${SOURCEMETA_EXECUTABLE_PROJECT}_${SOURCEMETA_EXECUTABLE_NAME}\")\n    set(FOLDER_NAME \"${SOURCEMETA_EXECUTABLE_PROJECT}/${SOURCEMETA_EXECUTABLE_NAME}\")\n  endif()\n\n  if(SOURCEMETA_EXECUTABLE_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${SOURCEMETA_EXECUTABLE_VARIANT}\")\n  endif()\n\n  if(SOURCEMETA_EXECUTABLE_OUTPUT)\n    set(\"${SOURCEMETA_EXECUTABLE_OUTPUT}\" \"${TARGET_NAME}\" PARENT_SCOPE)\n  endif()\n\n  add_executable(\"${TARGET_NAME}\" ${SOURCEMETA_EXECUTABLE_SOURCES})\n  sourcemeta_add_default_options(PRIVATE ${TARGET_NAME})\n\n  # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html\n  # Position Independent Executable (PIE) for ASLR support\n  if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)\n    target_compile_options(${TARGET_NAME} PRIVATE\n      $<$<CONFIG:Release>:-fPIE>\n      $<$<CONFIG:RelWithDebInfo>:-fPIE>\n      $<$<CONFIG:MinSizeRel>:-fPIE>)\n    target_link_options(${TARGET_NAME} PRIVATE\n      $<$<CONFIG:Release>:-pie>\n      $<$<CONFIG:RelWithDebInfo>:-pie>\n      $<$<CONFIG:MinSizeRel>:-pie>)\n  endif()\n\n  # See https://learn.microsoft.com/en-us/cpp/build/reference/guard-enable-control-flow-guard\n  # See https://learn.microsoft.com/en-us/cpp/build/reference/cetcompat\n  if(SOURCEMETA_COMPILER_MSVC)\n    target_compile_options(${TARGET_NAME} PRIVATE /guard:cf)\n    target_link_options(${TARGET_NAME} PRIVATE /guard:cf /CETCOMPAT)\n  endif()\n\n  # Linux-specific ELF linker hardening and compatibility options\n  if(SOURCEMETA_OS_LINUX AND (SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC))\n    # Maximize compatibility of pre-built binaries across Linux distros\n    if(NOT BUILD_SHARED_LIBS)\n      target_link_options(${TARGET_NAME} PRIVATE -static-libstdc++ -static-libgcc)\n    endif()\n    target_link_options(${TARGET_NAME} PRIVATE\n      \"LINKER:-z,nodlopen\"\n      \"LINKER:-z,noexecstack\"\n      \"LINKER:-z,relro\"\n      \"LINKER:-z,now\"\n      \"LINKER:--as-needed\")\n    if(CMAKE_VERSION VERSION_GREATER_EQUAL \"3.18\")\n      include(CheckLinkerFlag)\n      check_linker_flag(CXX \"LINKER:--no-copy-dt-needed-entries\"\n        SOURCEMETA_LINKER_NO_COPY_DT_NEEDED)\n      if(SOURCEMETA_LINKER_NO_COPY_DT_NEEDED)\n        target_link_options(${TARGET_NAME} PRIVATE\n          \"LINKER:--no-copy-dt-needed-entries\")\n      endif()\n    endif()\n  endif()\n\n  set_target_properties(\"${TARGET_NAME}\" PROPERTIES FOLDER \"${FOLDER_NAME}\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/googlebenchmark.cmake",
    "content": "function(sourcemeta_googlebenchmark)\n  cmake_parse_arguments(SOURCEMETA_GOOGLEBENCHMARK \"\"\n    \"NAMESPACE;PROJECT\" \"SOURCES\" ${ARGN})\n\n  if(NOT SOURCEMETA_GOOGLEBENCHMARK_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT SOURCEMETA_GOOGLEBENCHMARK_SOURCES)\n    message(FATAL_ERROR \"You must pass the sources list using the SOURCES option\")\n  endif()\n\n  if(SOURCEMETA_GOOGLEBENCHMARK_NAMESPACE)\n    set(TARGET_NAME \"${SOURCEMETA_GOOGLEBENCHMARK_NAMESPACE}_${SOURCEMETA_GOOGLEBENCHMARK_PROJECT}_benchmark\")\n    set(FOLDER_NAME \"${SOURCEMETA_GOOGLEBENCHMARK_NAMESPACE}/${SOURCEMETA_GOOGLEBENCHMARK_PROJECT}\")\n  else()\n    set(TARGET_NAME \"${SOURCEMETA_GOOGLEBENCHMARK_PROJECT}_benchmark\")\n    set(FOLDER_NAME \"${SOURCEMETA_GOOGLEBENCHMARK_PROJECT}\")\n  endif()\n\n  add_executable(\"${TARGET_NAME}\" ${SOURCEMETA_GOOGLEBENCHMARK_SOURCES})\n  sourcemeta_add_default_options(PRIVATE ${TARGET_NAME})\n  set_target_properties(\"${TARGET_NAME}\" PROPERTIES FOLDER \"${FOLDER_NAME}\")\n  target_link_libraries(\"${TARGET_NAME}\" PRIVATE benchmark::benchmark)\n  target_link_libraries(\"${TARGET_NAME}\" PRIVATE benchmark::benchmark_main)\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/googletest.cmake",
    "content": "function(sourcemeta_googletest)\n  cmake_parse_arguments(SOURCEMETA_GOOGLETEST \"\"\n    \"NAMESPACE;PROJECT;NAME;VARIANT\" \"SOURCES\" ${ARGN})\n\n  if(SOURCEMETA_GOOGLETEST_VARIANT)\n    set(TARGET_VARIANT \"${SOURCEMETA_GOOGLETEST_VARIANT}_unit\")\n  else()\n    set(TARGET_VARIANT \"unit\")\n  endif()\n\n  sourcemeta_executable(\n    NAMESPACE \"${SOURCEMETA_GOOGLETEST_NAMESPACE}\"\n    PROJECT \"${SOURCEMETA_GOOGLETEST_PROJECT}\"\n    NAME \"${SOURCEMETA_GOOGLETEST_NAME}\"\n    VARIANT \"${TARGET_VARIANT}\"\n    SOURCES \"${SOURCEMETA_GOOGLETEST_SOURCES}\"\n    OUTPUT TARGET_NAME)\n\n  target_link_libraries(\"${TARGET_NAME}\"\n    PRIVATE GTest::gtest GTest::gmock GTest::gtest_main)\n  add_test(NAME \"${SOURCEMETA_GOOGLETEST_PROJECT}.${SOURCEMETA_GOOGLETEST_NAME}\"\n    COMMAND \"${TARGET_NAME}\" --gtest_brief=1)\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/library.cmake",
    "content": "function(sourcemeta_library)\n  cmake_parse_arguments(SOURCEMETA_LIBRARY \"\"\n    \"NAMESPACE;PROJECT;NAME;VARIANT\" \"PRIVATE_HEADERS;SOURCES\" ${ARGN})\n\n  if(NOT SOURCEMETA_LIBRARY_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT SOURCEMETA_LIBRARY_NAME)\n    message(FATAL_ERROR \"You must pass the library name using the NAME option\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_NAMESPACE)\n    set(INCLUDE_PREFIX \"include/${SOURCEMETA_LIBRARY_NAMESPACE}/${SOURCEMETA_LIBRARY_PROJECT}\")\n  else()\n    set(INCLUDE_PREFIX \"include/${SOURCEMETA_LIBRARY_PROJECT}\")\n  endif()\n\n  set(EXPORT_HEADER_PATH \"${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_PREFIX}/${SOURCEMETA_LIBRARY_NAME}_export.h\")\n  if(NOT SOURCEMETA_LIBRARY_VARIANT)\n    set(PUBLIC_HEADER \"${INCLUDE_PREFIX}/${SOURCEMETA_LIBRARY_NAME}.h\")\n  else()\n    set(PUBLIC_HEADER \"../${INCLUDE_PREFIX}/${SOURCEMETA_LIBRARY_NAME}.h\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_SOURCES)\n    set(ABSOLUTE_PRIVATE_HEADERS \"${EXPORT_HEADER_PATH}\")\n  else()\n    set(ABSOLUTE_PRIVATE_HEADERS)\n  endif()\n\n  foreach(private_header IN LISTS SOURCEMETA_LIBRARY_PRIVATE_HEADERS)\n    if(SOURCEMETA_LIBRARY_VARIANT)\n      list(APPEND ABSOLUTE_PRIVATE_HEADERS \"../${INCLUDE_PREFIX}/${SOURCEMETA_LIBRARY_NAME}_${private_header}\")\n    else()\n      list(APPEND ABSOLUTE_PRIVATE_HEADERS \"${INCLUDE_PREFIX}/${SOURCEMETA_LIBRARY_NAME}_${private_header}\")\n    endif()\n  endforeach()\n\n  if(SOURCEMETA_LIBRARY_NAMESPACE)\n    set(TARGET_NAME \"${SOURCEMETA_LIBRARY_NAMESPACE}_${SOURCEMETA_LIBRARY_PROJECT}_${SOURCEMETA_LIBRARY_NAME}\")\n    set(ALIAS_NAME \"${SOURCEMETA_LIBRARY_NAMESPACE}::${SOURCEMETA_LIBRARY_PROJECT}::${SOURCEMETA_LIBRARY_NAME}\")\n    set(FOLDER_NAME \"${SOURCEMETA_LIBRARY_NAMESPACE}/${SOURCEMETA_LIBRARY_PROJECT}/${SOURCEMETA_LIBRARY_NAME}\")\n  else()\n    set(TARGET_NAME \"${SOURCEMETA_LIBRARY_PROJECT}_${SOURCEMETA_LIBRARY_NAME}\")\n    set(ALIAS_NAME \"${SOURCEMETA_LIBRARY_PROJECT}::${SOURCEMETA_LIBRARY_NAME}\")\n    set(FOLDER_NAME \"${SOURCEMETA_LIBRARY_PROJECT}/${SOURCEMETA_LIBRARY_NAME}\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${SOURCEMETA_LIBRARY_VARIANT}\")\n    set(ALIAS_NAME \"${ALIAS_NAME}::${SOURCEMETA_LIBRARY_VARIANT}\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_SOURCES)\n    add_library(${TARGET_NAME}\n      ${PUBLIC_HEADER} ${ABSOLUTE_PRIVATE_HEADERS} ${SOURCEMETA_LIBRARY_SOURCES})\n    sourcemeta_add_default_options(PRIVATE ${TARGET_NAME})\n  else()\n    add_library(${TARGET_NAME} INTERFACE\n      ${PUBLIC_HEADER} ${ABSOLUTE_PRIVATE_HEADERS})\n    sourcemeta_add_default_options(INTERFACE ${TARGET_NAME})\n  endif()\n\n  add_library(${ALIAS_NAME} ALIAS ${TARGET_NAME})\n\n  if(NOT SOURCEMETA_LIBRARY_VARIANT)\n    set(include_dir \"${CMAKE_CURRENT_SOURCE_DIR}/include\")\n  else()\n    set(include_dir \"${CMAKE_CURRENT_SOURCE_DIR}/../include\")\n  endif()\n  if(SOURCEMETA_LIBRARY_SOURCES)\n    target_include_directories(${TARGET_NAME} PUBLIC\n      \"$<BUILD_INTERFACE:${include_dir}>\"\n      \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n  else()\n    target_include_directories(${TARGET_NAME} INTERFACE\n      \"$<BUILD_INTERFACE:${include_dir}>\"\n      \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_VARIANT)\n    set(export_name \"${SOURCEMETA_LIBRARY_PROJECT}::${SOURCEMETA_LIBRARY_NAME}::${SOURCEMETA_LIBRARY_VARIANT}\")\n  else()\n    set(export_name \"${SOURCEMETA_LIBRARY_PROJECT}::${SOURCEMETA_LIBRARY_NAME}\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_SOURCES)\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        OUTPUT_NAME ${TARGET_NAME}\n        PUBLIC_HEADER \"${PUBLIC_HEADER}\"\n        PRIVATE_HEADER \"${ABSOLUTE_PRIVATE_HEADERS}\"\n        EXPORT_NAME \"${export_name}\"\n        FOLDER \"${FOLDER_NAME}\")\n  else()\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        OUTPUT_NAME ${TARGET_NAME}\n        PUBLIC_HEADER \"${PUBLIC_HEADER}\"\n        PRIVATE_HEADER \"${ABSOLUTE_PRIVATE_HEADERS}\"\n        EXPORT_NAME \"${export_name}\"\n        FOLDER \"${FOLDER_NAME}\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_SOURCES)\n    include(GenerateExportHeader)\n    generate_export_header(${TARGET_NAME}\n      EXPORT_FILE_NAME ${EXPORT_HEADER_PATH})\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        SOVERSION \"${PROJECT_VERSION_MAJOR}\"\n        VERSION \"${PROJECT_VERSION}\")\n\n    # To find the generated files\n    target_include_directories(${TARGET_NAME}\n      PUBLIC \"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>\")\n  endif()\n\n  # We don't want consumers to be bothered with this\n  if(PROJECT_IS_TOP_LEVEL)\n    sourcemeta_clang_tidy_attempt_enable(TARGET \"${TARGET_NAME}\")\n  endif()\nendfunction()\n\nfunction(sourcemeta_library_install)\n  cmake_parse_arguments(SOURCEMETA_LIBRARY \"\" \"NAMESPACE;PROJECT;NAME;VARIANT\" \"\" ${ARGN})\n\n  if(NOT SOURCEMETA_LIBRARY_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT SOURCEMETA_LIBRARY_NAME)\n    message(FATAL_ERROR \"You must pass the library name using the NAME option\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_NAMESPACE)\n    set(COMPONENT_NAME \"${SOURCEMETA_LIBRARY_NAMESPACE}_${SOURCEMETA_LIBRARY_PROJECT}\")\n    set(TARGET_NAME \"${SOURCEMETA_LIBRARY_NAMESPACE}_${SOURCEMETA_LIBRARY_PROJECT}_${SOURCEMETA_LIBRARY_NAME}\")\n    set(INCLUDE_PATH \"${CMAKE_INSTALL_INCLUDEDIR}/${SOURCEMETA_LIBRARY_NAMESPACE}/${SOURCEMETA_LIBRARY_PROJECT}\")\n    set(NAMESPACE_PREFIX \"${SOURCEMETA_LIBRARY_NAMESPACE}::\")\n  else()\n    set(COMPONENT_NAME \"${SOURCEMETA_LIBRARY_PROJECT}\")\n    set(TARGET_NAME \"${SOURCEMETA_LIBRARY_PROJECT}_${SOURCEMETA_LIBRARY_NAME}\")\n    set(INCLUDE_PATH \"${CMAKE_INSTALL_INCLUDEDIR}/${SOURCEMETA_LIBRARY_PROJECT}\")\n    set(NAMESPACE_PREFIX \"\")\n  endif()\n\n  if(SOURCEMETA_LIBRARY_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${SOURCEMETA_LIBRARY_VARIANT}\")\n  endif()\n\n  include(GNUInstallDirs)\n  install(TARGETS ${TARGET_NAME}\n    EXPORT ${TARGET_NAME}\n    PUBLIC_HEADER DESTINATION \"${INCLUDE_PATH}\"\n      COMPONENT ${COMPONENT_NAME}_dev\n    PRIVATE_HEADER DESTINATION \"${INCLUDE_PATH}\"\n      COMPONENT ${COMPONENT_NAME}_dev\n    RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n      COMPONENT ${COMPONENT_NAME}\n    LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n      COMPONENT ${COMPONENT_NAME}\n      NAMELINK_COMPONENT ${COMPONENT_NAME}_dev\n    ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n    COMPONENT ${COMPONENT_NAME}_dev)\n  install(EXPORT ${TARGET_NAME}\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${SOURCEMETA_LIBRARY_PROJECT}\"\n    NAMESPACE ${NAMESPACE_PREFIX}\n    COMPONENT ${COMPONENT_NAME}_dev)\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/targets/shellcheck.cmake",
    "content": "function(sourcemeta_target_shellcheck)\n  cmake_parse_arguments(SOURCEMETA_TARGET_SHELLCHECK \"REQUIRED\" \"\" \"SOURCES\" ${ARGN})\n\n  if(SOURCEMETA_TARGET_SHELLCHECK_REQUIRED)\n    find_program(SHELLCHECK_BIN NAMES shellcheck REQUIRED)\n  else()\n    find_program(SHELLCHECK_BIN NAMES shellcheck)\n  endif()\n\n  # This covers the empty list too\n  if(NOT SOURCEMETA_TARGET_SHELLCHECK_SOURCES)\n    message(FATAL_ERROR \"You must pass file globs to lint in the SOURCES option\")\n  endif()\n  file(GLOB_RECURSE SOURCEMETA_TARGET_SHELLCHECK_FILES\n    ${SOURCEMETA_TARGET_SHELLCHECK_SOURCES})\n\n  if(SHELLCHECK_BIN)\n    add_custom_target(shellcheck\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${SHELLCHECK_BIN}\" ${SOURCEMETA_TARGET_SHELLCHECK_FILES}\n      COMMENT \"Analyzing sources using ShellCheck\")\n  else()\n    add_custom_target(shellcheck\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ShellCheck\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\n\n  set_target_properties(shellcheck PROPERTIES FOLDER \"Linting\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/cmake/common/variables.cmake",
    "content": "# Get the list of languages defined in the project\nget_property(SOURCEMETA_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)\n\n# Compiler detection (C++)\n# TODO: Detect compilers on programming languages other than C++\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"AppleClang\")\n  set(SOURCEMETA_COMPILER_LLVM ON)\nelseif(CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")\n  set(SOURCEMETA_COMPILER_GCC ON)\nelseif(MSVC)\n  set(SOURCEMETA_COMPILER_MSVC ON)\nendif()\n\nif(CMAKE_SYSTEM_NAME STREQUAL \"Darwin\")\n  set(SOURCEMETA_OS_MACOS ON)\n# It seems that in some cases, `LINUX` is not set on GNU/Linux on WSL\nelseif(LINUX OR CMAKE_SYSTEM_NAME STREQUAL \"Linux\")\n  set(SOURCEMETA_OS_LINUX ON)\nelseif(WIN32)\n  set(SOURCEMETA_OS_WINDOWS ON)\nelseif(${CMAKE_SYSTEM_NAME} MATCHES \".*BSD\")\n  set(SOURCEMETA_OS_BSD ON)\nendif()\n"
  },
  {
    "path": "vendor/core/config.cmake.in",
    "content": "@PACKAGE_INIT@\n\n# Support both casing styles\nlist(APPEND SOURCEMETA_CORE_COMPONENTS ${Core_FIND_COMPONENTS})\nlist(APPEND SOURCEMETA_CORE_COMPONENTS ${core_FIND_COMPONENTS})\nif(NOT SOURCEMETA_CORE_COMPONENTS)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS preprocessor)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS io)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS process)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS parallel)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS numeric)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS unicode)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS punycode)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS time)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS crypto)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS regex)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS ip)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS dns)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS uri)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS uritemplate)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS json)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS jsonl)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS jsonpointer)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS jsonschema)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS yaml)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS semver)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS gzip)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS html)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS markdown)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS editorschema)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS error)\n  list(APPEND SOURCEMETA_CORE_COMPONENTS options)\nendif()\n\ninclude(CMakeFindDependencyMacro)\n\nforeach(component ${SOURCEMETA_CORE_COMPONENTS})\n  if(component STREQUAL \"preprocessor\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake\")\n  elseif(component STREQUAL \"io\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n  elseif(component STREQUAL \"process\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_process.cmake\")\n  elseif(component STREQUAL \"parallel\")\n    find_dependency(Threads)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_parallel.cmake\")\n  elseif(component STREQUAL \"numeric\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n  elseif(component STREQUAL \"unicode\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n  elseif(component STREQUAL \"punycode\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_punycode.cmake\")\n  elseif(component STREQUAL \"time\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_time.cmake\")\n  elseif(component STREQUAL \"crypto\")\n    if(@SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL@)\n      find_dependency(OpenSSL)\n    endif()\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_crypto.cmake\")\n  elseif(component STREQUAL \"regex\")\n    find_dependency(PCRE2 CONFIG)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_regex.cmake\")\n  elseif(component STREQUAL \"ip\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n  elseif(component STREQUAL \"dns\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_dns.cmake\")\n  elseif(component STREQUAL \"uri\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake\")\n  elseif(component STREQUAL \"uritemplate\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uritemplate.cmake\")\n  elseif(component STREQUAL \"json\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n  elseif(component STREQUAL \"jsonl\")\n    find_dependency(LibDeflate CONFIG)\n    find_dependency(ZLIB CONFIG)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_gzip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonl.cmake\")\n  elseif(component STREQUAL \"jsonpointer\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_regex.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake\")\n  elseif(component STREQUAL \"jsonschema\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonschema.cmake\")\n  elseif(component STREQUAL \"yaml\")\n    find_dependency(PCRE2 CONFIG)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_regex.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_yaml.cmake\")\n  elseif(component STREQUAL \"semver\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_semver.cmake\")\n  elseif(component STREQUAL \"gzip\")\n    find_dependency(LibDeflate CONFIG)\n    find_dependency(ZLIB CONFIG)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_gzip.cmake\")\n  elseif(component STREQUAL \"html\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_preprocessor.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_html.cmake\")\n  elseif(component STREQUAL \"markdown\")\n    find_dependency(cmark_gfm CONFIG)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_markdown.cmake\")\n  elseif(component STREQUAL \"editorschema\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_ip.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_uri.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_unicode.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_json.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonpointer.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_jsonschema.cmake\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_editorschema.cmake\")\n  elseif(component STREQUAL \"error\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_error.cmake\")\n  elseif(component STREQUAL \"options\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_options.cmake\")\n  else()\n    message(FATAL_ERROR \"Unknown Sourcemeta Core component: ${component}\")\n  endif()\nendforeach()\n\ncheck_required_components(\"@PROJECT_NAME@\")\n"
  },
  {
    "path": "vendor/core/src/core/crypto/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME crypto\n  PRIVATE_HEADERS sha256.h uuid.h\n  SOURCES crypto_sha256.cc crypto_uuid.cc)\n\nif(SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL)\n  target_compile_definitions(sourcemeta_core_crypto\n    PRIVATE SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL)\n  target_link_libraries(sourcemeta_core_crypto PRIVATE OpenSSL::Crypto)\nendif()\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME crypto)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/crypto/crypto_sha256.cc",
    "content": "#include <sourcemeta/core/crypto_sha256.h>\n\n#include <array>   // std::array\n#include <cstdint> // std::uint32_t, std::uint64_t\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n#include <openssl/evp.h> // EVP_MD_CTX_new, EVP_DigestInit_ex, EVP_sha256, EVP_DigestUpdate, EVP_DigestFinal_ex, EVP_MD_CTX_free\n#include <stdexcept>     // std::runtime_error\n#else\n#include <cstring> // std::memcpy\n#endif\n\nnamespace {\nconstexpr std::array<char, 17> HEX_DIGITS{{'0', '1', '2', '3', '4', '5', '6',\n                                           '7', '8', '9', 'a', 'b', 'c', 'd',\n                                           'e', 'f', '\\0'}};\n} // namespace\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n\nnamespace sourcemeta::core {\n\nauto sha256(const std::string_view input) -> std::string {\n  auto *context = EVP_MD_CTX_new();\n  if (context == nullptr) {\n    throw std::runtime_error(\"Could not allocate OpenSSL digest context\");\n  }\n\n  if (EVP_DigestInit_ex(context, EVP_sha256(), nullptr) != 1 ||\n      EVP_DigestUpdate(context, input.data(), input.size()) != 1) {\n    EVP_MD_CTX_free(context);\n    throw std::runtime_error(\"Could not compute SHA-256 digest\");\n  }\n\n  std::array<unsigned char, 32> digest{};\n  unsigned int length = 0;\n  if (EVP_DigestFinal_ex(context, digest.data(), &length) != 1) {\n    EVP_MD_CTX_free(context);\n    throw std::runtime_error(\"Could not finalize SHA-256 digest\");\n  }\n\n  EVP_MD_CTX_free(context);\n\n  std::string result;\n  result.reserve(64);\n  for (std::uint64_t index = 0; index < 32u; ++index) {\n    result.push_back(HEX_DIGITS[(digest[index] >> 4u) & 0x0fu]);\n    result.push_back(HEX_DIGITS[digest[index] & 0x0fu]);\n  }\n\n  return result;\n}\n\nauto sha256(const std::string_view input, std::ostream &output) -> void {\n  const auto result = sha256(input);\n  output.write(result.data(), static_cast<std::streamsize>(result.size()));\n}\n\n} // namespace sourcemeta::core\n\n#else\n\nnamespace {\n\ninline constexpr auto rotate_right(std::uint32_t value,\n                                   std::uint64_t count) noexcept\n    -> std::uint32_t {\n  return (value >> count) | (value << (32u - count));\n}\n\n// FIPS 180-4 Section 4.1.2 logical functions\ninline constexpr auto big_sigma_0(std::uint32_t value) noexcept\n    -> std::uint32_t {\n  return rotate_right(value, 2u) ^ rotate_right(value, 13u) ^\n         rotate_right(value, 22u);\n}\n\ninline constexpr auto big_sigma_1(std::uint32_t value) noexcept\n    -> std::uint32_t {\n  return rotate_right(value, 6u) ^ rotate_right(value, 11u) ^\n         rotate_right(value, 25u);\n}\n\ninline constexpr auto small_sigma_0(std::uint32_t value) noexcept\n    -> std::uint32_t {\n  return rotate_right(value, 7u) ^ rotate_right(value, 18u) ^ (value >> 3u);\n}\n\ninline constexpr auto small_sigma_1(std::uint32_t value) noexcept\n    -> std::uint32_t {\n  return rotate_right(value, 17u) ^ rotate_right(value, 19u) ^ (value >> 10u);\n}\n\n// Equivalent to (x & y) ^ (~x & z) but avoids a bitwise NOT\ninline constexpr auto choice(std::uint32_t x, std::uint32_t y,\n                             std::uint32_t z) noexcept -> std::uint32_t {\n  return z ^ (x & (y ^ z));\n}\n\ninline constexpr auto majority(std::uint32_t x, std::uint32_t y,\n                               std::uint32_t z) noexcept -> std::uint32_t {\n  return (x & y) ^ (x & z) ^ (y & z);\n}\n\ninline auto sha256_process_block(const unsigned char *block,\n                                 std::array<std::uint32_t, 8> &state) noexcept\n    -> void {\n  // First 32 bits of the fractional parts of the cube roots\n  // of the first 64 prime numbers (FIPS 180-4 Section 4.2.2)\n  static constexpr std::array<std::uint32_t, 64> round_constants = {\n      {0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,\n       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,\n       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,\n       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,\n       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,\n       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,\n       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,\n       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,\n       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,\n       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,\n       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,\n       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,\n       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U}};\n\n  // Decode 16 big-endian 32-bit words from the block\n  std::array<std::uint32_t, 64> schedule;\n  for (std::uint64_t word_index = 0; word_index < 16u; ++word_index) {\n    const std::uint64_t byte_index = word_index * 4u;\n    schedule[word_index] =\n        (static_cast<std::uint32_t>(block[byte_index]) << 24u) |\n        (static_cast<std::uint32_t>(block[byte_index + 1u]) << 16u) |\n        (static_cast<std::uint32_t>(block[byte_index + 2u]) << 8u) |\n        static_cast<std::uint32_t>(block[byte_index + 3u]);\n  }\n\n  // Extend the message schedule (FIPS 180-4 Section 6.2.2 step 1)\n  for (std::uint64_t index = 16u; index < 64u; ++index) {\n    schedule[index] =\n        small_sigma_1(schedule[index - 2u]) + schedule[index - 7u] +\n        small_sigma_0(schedule[index - 15u]) + schedule[index - 16u];\n  }\n\n  auto working = state;\n\n  // Compression function (FIPS 180-4 Section 6.2.2 step 3)\n  for (std::uint64_t round_index = 0u; round_index < 64u; ++round_index) {\n    const auto temporary_1 = working[7] + big_sigma_1(working[4]) +\n                             choice(working[4], working[5], working[6]) +\n                             round_constants[round_index] +\n                             schedule[round_index];\n    const auto temporary_2 =\n        big_sigma_0(working[0]) + majority(working[0], working[1], working[2]);\n\n    working[7] = working[6];\n    working[6] = working[5];\n    working[5] = working[4];\n    working[4] = working[3] + temporary_1;\n    working[3] = working[2];\n    working[2] = working[1];\n    working[1] = working[0];\n    working[0] = temporary_1 + temporary_2;\n  }\n\n  for (std::uint64_t index = 0u; index < 8u; ++index) {\n    state[index] += working[index];\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto sha256(const std::string_view input) -> std::string {\n  // Initial hash values: first 32 bits of the fractional parts of the\n  // square roots of the first 8 primes (FIPS 180-4 Section 5.3.3)\n  std::array<std::uint32_t, 8> state{};\n  state[0] = 0x6a09e667U;\n  state[1] = 0xbb67ae85U;\n  state[2] = 0x3c6ef372U;\n  state[3] = 0xa54ff53aU;\n  state[4] = 0x510e527fU;\n  state[5] = 0x9b05688cU;\n  state[6] = 0x1f83d9abU;\n  state[7] = 0x5be0cd19U;\n\n  const auto *const input_bytes =\n      reinterpret_cast<const unsigned char *>(input.data());\n  const std::size_t input_length = input.size();\n\n  // Process all full 64-byte blocks directly from the input (streaming)\n  std::size_t processed_bytes = 0u;\n  while (input_length - processed_bytes >= 64u) {\n    sha256_process_block(input_bytes + processed_bytes, state);\n    processed_bytes += 64u;\n  }\n\n  // Prepare the final block(s) (one or two 64-byte blocks)\n  std::array<unsigned char, 128> final_block{};\n  const std::size_t remaining_bytes = input_length - processed_bytes;\n  if (remaining_bytes > 0u) {\n    std::memcpy(final_block.data(), input_bytes + processed_bytes,\n                remaining_bytes);\n  }\n\n  // Append the 0x80 byte after the message data\n  final_block[remaining_bytes] = 0x80u;\n\n  // Append length in bits as big-endian 64-bit at the end of the padding\n  const std::uint64_t message_length_bits =\n      static_cast<std::uint64_t>(input_length) * 8ull;\n\n  if (remaining_bytes < 56u) {\n    for (std::uint64_t index = 0u; index < 8u; ++index) {\n      final_block[56u + index] = static_cast<unsigned char>(\n          (message_length_bits >> (8u * (7u - index))) & 0xffu);\n    }\n    sha256_process_block(final_block.data(), state);\n  } else {\n    for (std::uint64_t index = 0u; index < 8u; ++index) {\n      final_block[64u + 56u + index] = static_cast<unsigned char>(\n          (message_length_bits >> (8u * (7u - index))) & 0xffu);\n    }\n\n    sha256_process_block(final_block.data(), state);\n    sha256_process_block(final_block.data() + 64u, state);\n  }\n\n  std::string result;\n  result.reserve(64);\n  for (std::uint64_t state_index = 0u; state_index < 8u; ++state_index) {\n    const auto value = state[state_index];\n    for (std::uint64_t nibble = 0u; nibble < 8u; ++nibble) {\n      const auto shift = 28u - nibble * 4u;\n      result.push_back(HEX_DIGITS[(value >> shift) & 0x0fu]);\n    }\n  }\n\n  return result;\n}\n\nauto sha256(const std::string_view input, std::ostream &output) -> void {\n  const auto result = sha256(input);\n  output.write(result.data(), static_cast<std::streamsize>(result.size()));\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/crypto/crypto_uuid.cc",
    "content": "#include <sourcemeta/core/crypto_uuid.h>\n\n#include <array>       // std::array\n#include <cstddef>     // std::size_t\n#include <string_view> // std::string_view\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n#include <openssl/rand.h> // RAND_bytes\n#include <stdexcept>      // std::runtime_error\n#else\n#include <random> // std::random_device, std::mt19937, std::uniform_int_distribution\n#endif\n\nnamespace sourcemeta::core {\n\n// See RFC 9562 Section 5.4\n// Format: xxxxxxxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx\n// where 4 is the version and N is the variant (8, 9, a, or b)\nauto uuidv4() -> std::string {\n  static constexpr std::string_view digits = \"0123456789abcdef\";\n  static constexpr std::string_view variant_digits = \"89ab\";\n  static constexpr std::array<bool, 16> dash = {\n      {false, false, false, false, true, false, true, false, true, false, true,\n       false, false, false, false, false}};\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n  std::array<unsigned char, 16> random_bytes{};\n  if (RAND_bytes(random_bytes.data(), static_cast<int>(random_bytes.size())) !=\n      1) {\n    throw std::runtime_error(\"Could not generate random bytes with OpenSSL\");\n  }\n#else\n  static std::random_device device;\n  static std::mt19937 generator{device()};\n  std::uniform_int_distribution<decltype(digits)::size_type> distribution(0,\n                                                                          15);\n  std::uniform_int_distribution<decltype(variant_digits)::size_type>\n      variant_distribution(0, 3);\n#endif\n\n  std::string result;\n  result.reserve(36);\n  for (std::size_t index = 0; index < dash.size(); ++index) {\n    if (dash[index]) {\n      result += '-';\n    }\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n    const auto high_nibble = (random_bytes[index] >> 4u) & 0x0fu;\n    const auto low_nibble = random_bytes[index] & 0x0fu;\n#endif\n\n    // RFC 9562 Section 5.4: version bits (48-51) must be 0b0100\n    if (index == 6) {\n      result += '4';\n      // RFC 9562 Section 5.4: variant bits (64-65) must be 0b10\n    } else if (index == 8) {\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n      result += variant_digits[high_nibble & 0x03u];\n#else\n      result += variant_digits[variant_distribution(generator)];\n#endif\n    } else {\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n      result += digits[high_nibble];\n#else\n      result += digits[distribution(generator)];\n#endif\n    }\n\n#ifdef SOURCEMETA_CORE_CRYPTO_USE_SYSTEM_OPENSSL\n    result += digits[low_nibble];\n#else\n    result += digits[distribution(generator)];\n#endif\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/crypto/include/sourcemeta/core/crypto.h",
    "content": "#ifndef SOURCEMETA_CORE_CRYPTO_H_\n#define SOURCEMETA_CORE_CRYPTO_H_\n\n/// @defgroup crypto Crypto\n/// @brief Cryptographic hash functions and UUID generation.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/crypto.h>\n/// ```\n\n#include <sourcemeta/core/crypto_sha256.h>\n#include <sourcemeta/core/crypto_uuid.h>\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/crypto/include/sourcemeta/core/crypto_sha256.h",
    "content": "#ifndef SOURCEMETA_CORE_CRYPTO_SHA256_H_\n#define SOURCEMETA_CORE_CRYPTO_SHA256_H_\n\n#ifndef SOURCEMETA_CORE_CRYPTO_EXPORT\n#include <sourcemeta/core/crypto_export.h>\n#endif\n\n#include <ostream>     // std::ostream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup crypto\n/// Hash a string using SHA-256. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/crypto.h>\n/// #include <sstream>\n/// #include <iostream>\n///\n/// std::ostringstream result;\n/// sourcemeta::core::sha256(\"foo bar\", result);\n/// std::cout << result.str() << \"\\n\";\n/// ```\nauto SOURCEMETA_CORE_CRYPTO_EXPORT sha256(const std::string_view input,\n                                          std::ostream &output) -> void;\n\n/// @ingroup crypto\n/// Hash a string using SHA-256, returning the hex digest as a string.\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/crypto.h>\n/// #include <iostream>\n///\n/// std::cout << sourcemeta::core::sha256(\"foo bar\") << \"\\n\";\n/// ```\nauto SOURCEMETA_CORE_CRYPTO_EXPORT sha256(const std::string_view input)\n    -> std::string;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/crypto/include/sourcemeta/core/crypto_uuid.h",
    "content": "#ifndef SOURCEMETA_CORE_CRYPTO_UUID_H_\n#define SOURCEMETA_CORE_CRYPTO_UUID_H_\n\n#ifndef SOURCEMETA_CORE_CRYPTO_EXPORT\n#include <sourcemeta/core/crypto_export.h>\n#endif\n\n#include <string> // std::string\n\nnamespace sourcemeta::core {\n\n/// @ingroup crypto\n/// Generate a random UUID v4 string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/crypto.h>\n/// #include <iostream>\n///\n/// std::cout << sourcemeta::core::uuidv4() << \"\\n\";\n/// ```\n///\n/// See https://www.rfc-editor.org/rfc/rfc9562#name-uuid-version-4\nSOURCEMETA_CORE_CRYPTO_EXPORT auto uuidv4() -> std::string;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/dns/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME dns\n  SOURCES hostname.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME dns)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/dns/hostname.cc",
    "content": "#include <sourcemeta/core/dns.h>\n\nnamespace sourcemeta::core {\n\n// RFC 952 §B: let-dig = ALPHA / DIGIT\n// RFC 1123 §2.1: first character of a label is letter or digit\nstatic constexpr auto is_let_dig(const char character) -> bool {\n  return (character >= 'A' && character <= 'Z') ||\n         (character >= 'a' && character <= 'z') ||\n         (character >= '0' && character <= '9');\n}\n\n// RFC 952 §B: let-dig-hyp = ALPHA / DIGIT / \"-\"\nstatic constexpr auto is_let_dig_hyp(const char character) -> bool {\n  return is_let_dig(character) || character == '-';\n}\n\nauto is_hostname(const std::string_view value) -> bool {\n  // RFC 952 §B: <hname> requires at least one <name>\n  if (value.empty()) {\n    return false;\n  }\n\n  // RFC 1123 §2.1: SHOULD handle host names of up to 255 characters\n  if (value.size() > 255) {\n    return false;\n  }\n\n  std::string_view::size_type position{0};\n\n  while (position < value.size()) {\n    const auto label_start{position};\n\n    // RFC 1123 §2.1: first character is letter or digit\n    if (!is_let_dig(value[position])) {\n      return false;\n    }\n    position += 1;\n\n    while (position < value.size() && value[position] != '.') {\n      // RFC 952 §B: interior characters are let-dig-hyp\n      if (!is_let_dig_hyp(value[position])) {\n        return false;\n      }\n      position += 1;\n    }\n\n    const auto label_length{position - label_start};\n\n    // RFC 1123 §2.1: MUST handle host names of up to 63 characters (per label)\n    if (label_length > 63) {\n      return false;\n    }\n\n    // RFC 952 §B + ASSUMPTIONS: last character must not be a minus sign\n    if (value[position - 1] == '-') {\n      return false;\n    }\n\n    // If we stopped on a dot, there must be another label following it\n    if (position < value.size()) {\n      // value[position] == '.'\n      position += 1;\n      // Trailing dot: JSON Schema test suite requires rejection (TS d7+ #15)\n      if (position >= value.size()) {\n        return false;\n      }\n    }\n  }\n\n  return true;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/dns/include/sourcemeta/core/dns.h",
    "content": "#ifndef SOURCEMETA_CORE_DNS_H_\n#define SOURCEMETA_CORE_DNS_H_\n\n#ifndef SOURCEMETA_CORE_DNS_EXPORT\n#include <sourcemeta/core/dns_export.h>\n#endif\n\n#include <string_view> // std::string_view\n\n/// @defgroup dns DNS\n/// @brief DNS and hostname validation utilities.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/dns.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup dns\n/// Check whether the given string is a valid Internet host name per\n/// RFC 1123 Section 2.1, which relaxes the first-character rule of\n/// RFC 952 to allow either a letter or a digit. This matches the\n/// definition used by the JSON Schema `hostname` format. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/dns.h>\n///\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::is_hostname(\"www.example.com\"));\n/// assert(sourcemeta::core::is_hostname(\"1host\"));\n/// assert(!sourcemeta::core::is_hostname(\"-bad\"));\n/// assert(!sourcemeta::core::is_hostname(\"example.\"));\n/// ```\n///\n/// This function implements RFC 1123 §2.1 (ASCII only). It does not\n/// perform A-label or Punycode decoding. Those belong to the separate\n/// `idn-hostname` format.\nSOURCEMETA_CORE_DNS_EXPORT\nauto is_hostname(const std::string_view value) -> bool;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/gzip/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME gzip\n  PRIVATE_HEADERS error.h streambuf.h\n  SOURCES gzip.cc streambuf.cc)\n\n# Way faster for full buffer decompression\ntarget_link_libraries(sourcemeta_core_gzip PRIVATE LibDeflate::LibDeflate)\n# Supports streaming\ntarget_link_libraries(sourcemeta_core_gzip PRIVATE ZLIB::ZLIB)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME gzip)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/gzip/gzip.cc",
    "content": "#include <sourcemeta/core/gzip.h>\n\nextern \"C\" {\n#include <libdeflate.h>\n}\n\n#include <memory> // std::unique_ptr\n\nnamespace sourcemeta::core {\n\nauto gzip(const std::uint8_t *input, const std::size_t size) -> std::string {\n  std::unique_ptr<libdeflate_compressor, decltype(&libdeflate_free_compressor)>\n      compressor{libdeflate_alloc_compressor(1), libdeflate_free_compressor};\n  if (!compressor) {\n    throw GZIPError{\"Could not allocate compressor\"};\n  }\n\n  const auto max_size{libdeflate_gzip_compress_bound(compressor.get(), size)};\n  std::string output;\n  output.resize(max_size);\n\n  const auto actual_size{libdeflate_gzip_compress(\n      compressor.get(), input, size, output.data(), output.size())};\n\n  if (actual_size == 0) {\n    throw GZIPError{\"Could not compress input\"};\n  }\n\n  output.resize(actual_size);\n  return output;\n}\n\nauto gunzip(const std::uint8_t *input, const std::size_t size,\n            const std::size_t output_hint) -> std::string {\n  std::unique_ptr<libdeflate_decompressor,\n                  decltype(&libdeflate_free_decompressor)>\n      decompressor{libdeflate_alloc_decompressor(),\n                   libdeflate_free_decompressor};\n  if (!decompressor) {\n    throw GZIPError{\"Could not allocate decompressor\"};\n  }\n\n  std::string output;\n  auto capacity{output_hint > 0 ? output_hint : size * 4};\n\n  for (;;) {\n    output.resize(capacity);\n    std::size_t actual_size{0};\n    const auto result{libdeflate_gzip_decompress(decompressor.get(), input,\n                                                 size, output.data(),\n                                                 output.size(), &actual_size)};\n\n    if (result == LIBDEFLATE_SUCCESS) {\n      output.resize(actual_size);\n      return output;\n    }\n\n    if (result == LIBDEFLATE_INSUFFICIENT_SPACE) {\n      capacity *= 2;\n      continue;\n    }\n\n    throw GZIPError{\"Could not decompress input\"};\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/gzip/include/sourcemeta/core/gzip.h",
    "content": "#ifndef SOURCEMETA_CORE_GZIP_H_\n#define SOURCEMETA_CORE_GZIP_H_\n\n/// @defgroup gzip GZIP\n/// @brief GZIP compression and decompression as per IETF RFC 1952.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/gzip.h>\n/// ```\n\n#ifndef SOURCEMETA_CORE_GZIP_EXPORT\n#include <sourcemeta/core/gzip_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/gzip_error.h>\n#include <sourcemeta/core/gzip_streambuf.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cstddef> // std::size_t\n#include <cstdint> // std::uint8_t\n#include <string>  // std::string\n\nnamespace sourcemeta::core {\n\n/// @ingroup gzip\n/// Compress a byte buffer using the GZIP format (RFC 1952). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/gzip.h>\n///\n/// const std::string input{\"hello world\"};\n/// const auto compressed{sourcemeta::core::gzip(\n///     reinterpret_cast<const std::uint8_t *>(input.data()), input.size())};\n/// ```\nauto SOURCEMETA_CORE_GZIP_EXPORT gzip(const std::uint8_t *input,\n                                      std::size_t size) -> std::string;\n\n/// @ingroup gzip\n/// Decompress a GZIP compressed byte buffer (RFC 1952). An optional output\n/// size hint can be provided to avoid repeated buffer resizing. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/gzip.h>\n///\n/// const auto decompressed{sourcemeta::core::gunzip(\n///     reinterpret_cast<const std::uint8_t *>(compressed.data()),\n///     compressed.size())};\n/// ```\nauto SOURCEMETA_CORE_GZIP_EXPORT gunzip(const std::uint8_t *input,\n                                        std::size_t size,\n                                        std::size_t output_hint = 0)\n    -> std::string;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/gzip/include/sourcemeta/core/gzip_error.h",
    "content": "#ifndef SOURCEMETA_CORE_GZIP_ERROR_H_\n#define SOURCEMETA_CORE_GZIP_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_GZIP_EXPORT\n#include <sourcemeta/core/gzip_export.h>\n#endif\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup gzip\n/// An error that represents a GZIP compression or decompression failure\nclass SOURCEMETA_CORE_GZIP_EXPORT GZIPError : public std::exception {\npublic:\n  GZIPError(const char *message) : message_{message} {}\n  GZIPError(std::string message) = delete;\n  GZIPError(std::string &&message) = delete;\n  GZIPError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/gzip/include/sourcemeta/core/gzip_streambuf.h",
    "content": "#ifndef SOURCEMETA_CORE_GZIP_STREAMBUF_H_\n#define SOURCEMETA_CORE_GZIP_STREAMBUF_H_\n\n#ifndef SOURCEMETA_CORE_GZIP_EXPORT\n#include <sourcemeta/core/gzip_export.h>\n#endif\n\n#include <istream>   // std::istream\n#include <memory>    // std::unique_ptr\n#include <streambuf> // std::streambuf\n\nnamespace sourcemeta::core {\n\n/// @ingroup gzip\n/// A stream buffer that performs streaming GZIP decompression (RFC 1952) over\n/// an input stream.\nclass SOURCEMETA_CORE_GZIP_EXPORT GZIPStreamBuffer : public std::streambuf {\npublic:\n  GZIPStreamBuffer(std::istream &compressed_stream);\n  ~GZIPStreamBuffer() override;\n\n  GZIPStreamBuffer(const GZIPStreamBuffer &) = delete;\n  auto operator=(const GZIPStreamBuffer &) -> GZIPStreamBuffer & = delete;\n  GZIPStreamBuffer(GZIPStreamBuffer &&) = delete;\n  auto operator=(GZIPStreamBuffer &&) -> GZIPStreamBuffer & = delete;\n\nprotected:\n  auto underflow() -> int_type override;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  struct Internal;\n  std::unique_ptr<Internal> internal;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/gzip/streambuf.cc",
    "content": "#include <sourcemeta/core/gzip.h>\n\nextern \"C\" {\n#include <zlib.h>\n}\n\n#include <array>   // std::array\n#include <cstddef> // std::size_t\n#include <istream> // std::istream\n\nnamespace sourcemeta::core {\n\nstatic constexpr std::size_t GZIP_BUFFER_SIZE{16384};\n\nstruct GZIPStreamBuffer::Internal {\n  // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)\n  std::istream &stream;\n  z_stream zlib_stream;\n  bool stream_ended;\n  std::array<char, GZIP_BUFFER_SIZE> compressed_buffer;\n  std::array<char, GZIP_BUFFER_SIZE> decompressed_buffer;\n};\n\nGZIPStreamBuffer::GZIPStreamBuffer(std::istream &compressed_stream)\n    : internal{new Internal{.stream = compressed_stream,\n                            .zlib_stream = {},\n                            .stream_ended = false,\n                            .compressed_buffer = {},\n                            .decompressed_buffer = {}}} {\n  this->internal->zlib_stream.zalloc = Z_NULL;\n  this->internal->zlib_stream.zfree = Z_NULL;\n  this->internal->zlib_stream.opaque = Z_NULL;\n  this->internal->zlib_stream.avail_in = 0;\n  this->internal->zlib_stream.next_in = Z_NULL;\n\n  // MAX_WBITS + 16 selects gzip decoding per the zlib API\n  const auto result{inflateInit2(&this->internal->zlib_stream, MAX_WBITS + 16)};\n  if (result != Z_OK) {\n    throw GZIPError{\"Could not initialize gzip decompressor\"};\n  }\n}\n\nGZIPStreamBuffer::~GZIPStreamBuffer() {\n  inflateEnd(&this->internal->zlib_stream);\n}\n\nauto GZIPStreamBuffer::underflow() -> int_type {\n  if (this->gptr() && this->gptr() < this->egptr()) {\n    return traits_type::to_int_type(*this->gptr());\n  }\n\n  if (this->internal->stream_ended) {\n    return traits_type::eof();\n  }\n\n  if (this->internal->zlib_stream.avail_in == 0) {\n    this->internal->stream.read(\n        this->internal->compressed_buffer.data(),\n        static_cast<std::streamsize>(this->internal->compressed_buffer.size()));\n    const auto bytes_read{this->internal->stream.gcount()};\n    if (bytes_read > 0) {\n      this->internal->zlib_stream.next_in =\n          reinterpret_cast<Bytef *>(this->internal->compressed_buffer.data());\n      this->internal->zlib_stream.avail_in = static_cast<uInt>(bytes_read);\n    }\n  }\n\n  this->internal->zlib_stream.next_out =\n      reinterpret_cast<Bytef *>(this->internal->decompressed_buffer.data());\n  this->internal->zlib_stream.avail_out =\n      static_cast<uInt>(this->internal->decompressed_buffer.size());\n\n  const auto result{inflate(&this->internal->zlib_stream, Z_NO_FLUSH)};\n\n  if (result != Z_OK && result != Z_STREAM_END) {\n    throw GZIPError{\"Could not decompress gzip stream\"};\n  }\n\n  const auto bytes_produced{this->internal->decompressed_buffer.size() -\n                            this->internal->zlib_stream.avail_out};\n  if (bytes_produced == 0) {\n    this->internal->stream_ended = true;\n    return traits_type::eof();\n  }\n\n  if (result == Z_STREAM_END) {\n    this->internal->stream_ended = true;\n  }\n\n  auto *buffer_start{this->internal->decompressed_buffer.data()};\n  this->setg(buffer_start, buffer_start,\n             buffer_start + static_cast<std::ptrdiff_t>(bytes_produced));\n  return traits_type::to_int_type(*this->gptr());\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/html/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME html\n  PRIVATE_HEADERS buffer.h escape.h writer.h\n  SOURCES escape.cc writer.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME html)\nendif()\n\ntarget_link_libraries(sourcemeta_core_html PUBLIC sourcemeta::core::preprocessor)\n"
  },
  {
    "path": "vendor/core/src/core/html/escape.cc",
    "content": "#include <sourcemeta/core/html_escape.h>\n\n#include <string> // std::string\n\nnamespace sourcemeta::core {\n\nauto html_escape(std::string &text) -> void {\n  const std::size_t original_size{text.size()};\n\n  // First pass: count how much space we need\n  std::size_t required_size{0};\n  for (char character : text) {\n    switch (character) {\n      case '&':\n        required_size += 5; // &amp;\n        break;\n      case '<':\n      case '>':\n        required_size += 4; // &lt; or &gt;\n        break;\n      case '\"':\n        required_size += 6; // &quot;\n        break;\n      case '\\'':\n        required_size += 5; // &#39;\n        break;\n      default:\n        required_size += 1;\n    }\n  }\n\n  // If no escaping needed, return early\n  if (required_size == original_size) {\n    return;\n  }\n\n  // Write escaped characters backwards to avoid overwriting unprocessed data\n  text.resize_and_overwrite(required_size,\n                            [original_size](char *buffer, std::size_t count) {\n                              auto read_position = original_size;\n                              auto write_position = count;\n\n                              while (read_position > 0) {\n                                --read_position;\n                                const auto character = buffer[read_position];\n\n                                switch (character) {\n                                  case '&':\n                                    write_position -= 5;\n                                    buffer[write_position] = '&';\n                                    buffer[write_position + 1] = 'a';\n                                    buffer[write_position + 2] = 'm';\n                                    buffer[write_position + 3] = 'p';\n                                    buffer[write_position + 4] = ';';\n                                    break;\n                                  case '<':\n                                    write_position -= 4;\n                                    buffer[write_position] = '&';\n                                    buffer[write_position + 1] = 'l';\n                                    buffer[write_position + 2] = 't';\n                                    buffer[write_position + 3] = ';';\n                                    break;\n                                  case '>':\n                                    write_position -= 4;\n                                    buffer[write_position] = '&';\n                                    buffer[write_position + 1] = 'g';\n                                    buffer[write_position + 2] = 't';\n                                    buffer[write_position + 3] = ';';\n                                    break;\n                                  case '\"':\n                                    write_position -= 6;\n                                    buffer[write_position] = '&';\n                                    buffer[write_position + 1] = 'q';\n                                    buffer[write_position + 2] = 'u';\n                                    buffer[write_position + 3] = 'o';\n                                    buffer[write_position + 4] = 't';\n                                    buffer[write_position + 5] = ';';\n                                    break;\n                                  case '\\'':\n                                    write_position -= 5;\n                                    buffer[write_position] = '&';\n                                    buffer[write_position + 1] = '#';\n                                    buffer[write_position + 2] = '3';\n                                    buffer[write_position + 3] = '9';\n                                    buffer[write_position + 4] = ';';\n                                    break;\n                                  default:\n                                    --write_position;\n                                    buffer[write_position] = character;\n                                }\n                              }\n\n                              return count;\n                            });\n}\n\nstatic auto needs_escape(const std::string_view input) -> bool {\n  for (const char character : input) {\n    switch (character) {\n      case '&':\n      case '<':\n      case '>':\n      case '\"':\n      case '\\'':\n        return true;\n      default:\n        break;\n    }\n  }\n\n  return false;\n}\n\nauto html_escape_append(std::string &output, const std::string_view input)\n    -> void {\n  if (!needs_escape(input)) {\n    output += input;\n    return;\n  }\n\n  for (const char character : input) {\n    switch (character) {\n      case '&':\n        output += \"&amp;\";\n        break;\n      case '<':\n        output += \"&lt;\";\n        break;\n      case '>':\n        output += \"&gt;\";\n        break;\n      case '\"':\n        output += \"&quot;\";\n        break;\n      case '\\'':\n        output += \"&#39;\";\n        break;\n      default:\n        output += character;\n    }\n  }\n}\n\nauto html_escape_append(HTMLBuffer &output, const std::string_view input)\n    -> void {\n  if (!needs_escape(input)) {\n    output.append(input);\n    return;\n  }\n\n  for (const char character : input) {\n    switch (character) {\n      case '&':\n        output.append(\"&amp;\");\n        break;\n      case '<':\n        output.append(\"&lt;\");\n        break;\n      case '>':\n        output.append(\"&gt;\");\n        break;\n      case '\"':\n        output.append(\"&quot;\");\n        break;\n      case '\\'':\n        output.append(\"&#39;\");\n        break;\n      default:\n        output.append(character);\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/html/include/sourcemeta/core/html.h",
    "content": "#ifndef SOURCEMETA_CORE_HTML_H_\n#define SOURCEMETA_CORE_HTML_H_\n\n/// @defgroup html HTML\n/// @brief A growing implementation of HTML generation utilities per the HTML\n/// Living Standard.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/html.h>\n/// ```\n\n#include <sourcemeta/core/html_writer.h>\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/html/include/sourcemeta/core/html_buffer.h",
    "content": "#ifndef SOURCEMETA_CORE_HTML_BUFFER_H_\n#define SOURCEMETA_CORE_HTML_BUFFER_H_\n\n#ifndef SOURCEMETA_CORE_HTML_EXPORT\n#include <sourcemeta/core/html_export.h>\n#endif\n\n#include <sourcemeta/core/preprocessor.h>\n\n#include <cstring>     // std::memcpy\n#include <iostream>    // std::ostream\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup html\n/// A fast append-only string buffer\nclass SOURCEMETA_CORE_HTML_EXPORT HTMLBuffer {\npublic:\n  HTMLBuffer() = default;\n  HTMLBuffer(const HTMLBuffer &) = delete;\n  auto operator=(const HTMLBuffer &) -> HTMLBuffer & = delete;\n  HTMLBuffer(HTMLBuffer &&) = delete;\n  auto operator=(HTMLBuffer &&) -> HTMLBuffer & = delete;\n\n  SOURCEMETA_FORCEINLINE inline auto reserve(const std::size_t bytes) -> void {\n    this->buffer_.resize(bytes);\n    this->cursor_ = this->buffer_.data();\n    this->end_ = this->cursor_ + bytes;\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto append(const char character) -> void {\n    if (!this->cursor_ || this->cursor_ >= this->end_) [[unlikely]] {\n      this->grow(1);\n    }\n\n    *this->cursor_ = character;\n    ++this->cursor_;\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto append(const std::string_view data)\n      -> void {\n    const auto length{data.size()};\n    if (length == 0) {\n      return;\n    }\n\n    const auto remaining{\n        this->cursor_ ? static_cast<std::size_t>(this->end_ - this->cursor_)\n                      : 0uz};\n    if (remaining < length) [[unlikely]] {\n      this->grow(length);\n    }\n\n    std::memcpy(this->cursor_, data.data(), length);\n    this->cursor_ += length;\n  }\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto str()\n      -> const std::string & {\n    if (this->cursor_) {\n      this->buffer_.resize(\n          static_cast<std::size_t>(this->cursor_ - this->buffer_.data()));\n      this->cursor_ = nullptr;\n      this->end_ = nullptr;\n    }\n\n    return this->buffer_;\n  }\n\n  auto write(std::ostream &stream) -> void;\n\nprivate:\n  auto grow(std::size_t needed) -> void;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::string buffer_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n  char *cursor_{nullptr};\n  char *end_{nullptr};\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/html/include/sourcemeta/core/html_escape.h",
    "content": "#ifndef SOURCEMETA_CORE_HTML_ESCAPE_H_\n#define SOURCEMETA_CORE_HTML_ESCAPE_H_\n\n#ifndef SOURCEMETA_CORE_HTML_EXPORT\n#include <sourcemeta/core/html_export.h>\n#endif\n\n#include <sourcemeta/core/html_buffer.h>\n\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup html\n/// HTML character escaping implementation per HTML Living Standard.\n/// See: https://html.spec.whatwg.org/multipage/parsing.html#escapingString\n///\n/// This function escapes the five HTML special characters in-place:\n/// - `&` becomes `&amp;`\n/// - `<` becomes `&lt;`\n/// - `>` becomes `&gt;`\n/// - `\"` becomes `&quot;`\n/// - `'` becomes `&#39;`\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/html.h>\n/// #include <cassert>\n///\n/// std::string text{\"<script>alert('xss')</script>\"};\n/// sourcemeta::core::html_escape(text);\n/// assert(text == \"&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;\");\n/// ```\nSOURCEMETA_CORE_HTML_EXPORT\nauto html_escape(std::string &text) -> void;\n\n/// @ingroup html\n/// Append the HTML-escaped form of `input` directly to `output`,\n/// without allocating a temporary string.\nSOURCEMETA_CORE_HTML_EXPORT\nauto html_escape_append(std::string &output, std::string_view input) -> void;\n\n/// @ingroup html\n/// Append the HTML-escaped form of `input` directly to a buffer.\nSOURCEMETA_CORE_HTML_EXPORT\nauto html_escape_append(HTMLBuffer &output, std::string_view input) -> void;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/html/include/sourcemeta/core/html_writer.h",
    "content": "#ifndef SOURCEMETA_CORE_HTML_WRITER_H_\n#define SOURCEMETA_CORE_HTML_WRITER_H_\n\n#ifndef SOURCEMETA_CORE_HTML_EXPORT\n#include <sourcemeta/core/html_export.h>\n#endif\n\n#include <sourcemeta/core/html_buffer.h>\n#include <sourcemeta/core/html_escape.h>\n#include <sourcemeta/core/preprocessor.h>\n\n#include <cassert>     // assert\n#include <string_view> // std::string_view\n#include <vector>      // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup html\n/// A streaming HTML writer that renders directly to a string buffer.\n/// No intermediate DOM tree is built. Elements are serialized as methods\n/// are called.\n///\n/// ```cpp\n/// #include <sourcemeta/core/html.h>\n/// #include <cassert>\n///\n/// sourcemeta::core::HTMLWriter document;\n/// document.div().attribute(\"class\", \"greeting\");\n/// document.h1(\"Hello\");\n/// document.p(\"World\");\n/// document.close();\n/// ```\nclass SOURCEMETA_CORE_HTML_EXPORT HTMLWriter {\npublic:\n  /// Pre-allocate the output buffer\n  SOURCEMETA_FORCEINLINE inline auto reserve(std::size_t bytes) -> void {\n    this->buffer_.reserve(bytes);\n  }\n\n  /// Close the most recently opened element\n  SOURCEMETA_FORCEINLINE inline auto close() -> HTMLWriter & {\n    this->flush_open_tag();\n    assert(!this->tag_stack_.empty());\n    this->buffer_.append(\"</\");\n    this->buffer_.append(this->tag_stack_.back());\n    this->buffer_.append(\">\");\n    this->tag_stack_.pop_back();\n    return *this;\n  }\n\n  /// Add an attribute to the currently open tag. Must be called\n  /// immediately after an element method and before any content.\n  SOURCEMETA_FORCEINLINE inline auto attribute(std::string_view name,\n                                               std::string_view value)\n      -> HTMLWriter & {\n    assert(this->tag_open_);\n    this->buffer_.append(\" \");\n    this->buffer_.append(name);\n    this->buffer_.append(\"=\\\"\");\n    html_escape_append(this->buffer_, value);\n    this->buffer_.append(\"\\\"\");\n    return *this;\n  }\n\n  /// Write HTML-escaped text content\n  SOURCEMETA_FORCEINLINE inline auto text(std::string_view content)\n      -> HTMLWriter & {\n    this->flush_open_tag();\n    html_escape_append(this->buffer_, content);\n    return *this;\n  }\n\n  /// Write raw HTML content (not escaped)\n  SOURCEMETA_FORCEINLINE inline auto raw(std::string_view content)\n      -> HTMLWriter & {\n    this->flush_open_tag();\n    this->buffer_.append(content);\n    return *this;\n  }\n\n  /// Get the rendered HTML string\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto str()\n      -> const std::string & {\n    this->flush_open_tag();\n    return this->buffer_.str();\n  }\n\n  /// Write the rendered HTML to an output stream\n  auto write(std::ostream &stream) -> void;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n\n#ifndef DOXYGEN\n// Macro to generate container element methods.\n// Container elements write <tag> on open and </tag> on close().\n// Overloads:\n//   .tag()              open with no attributes\n//   .tag(text)          open, write escaped text, close (shorthand)\n#define HTML_WRITER_CONTAINER(name)                                            \\\n  SOURCEMETA_FORCEINLINE inline auto name() -> HTMLWriter & {                  \\\n    this->open_tag(#name);                                                     \\\n    return *this;                                                              \\\n  }                                                                            \\\n  /* NOLINTNEXTLINE(bugprone-macro-parentheses) */                             \\\n  SOURCEMETA_FORCEINLINE inline auto name(std::string_view text_content)       \\\n      -> HTMLWriter & {                                                        \\\n    this->open_tag(#name);                                                     \\\n    this->text(text_content);                                                  \\\n    this->close();                                                             \\\n    return *this;                                                              \\\n  }\n\n// Same as above but with a different C++ method name than the HTML tag\n#define HTML_WRITER_CONTAINER_NAMED(name, tag)                                 \\\n  SOURCEMETA_FORCEINLINE inline auto name() -> HTMLWriter & {                  \\\n    this->open_tag(#tag);                                                      \\\n    return *this;                                                              \\\n  }                                                                            \\\n  /* NOLINTNEXTLINE(bugprone-macro-parentheses) */                             \\\n  SOURCEMETA_FORCEINLINE inline auto name(std::string_view text_content)       \\\n      -> HTMLWriter & {                                                        \\\n    this->open_tag(#tag);                                                      \\\n    this->text(text_content);                                                  \\\n    this->close();                                                             \\\n    return *this;                                                              \\\n  }\n\n// Macro to generate void element methods.\n// Void elements are self-closing: <tag /> or <tag attr=\"val\" />\n#define HTML_WRITER_VOID(name)                                                 \\\n  /* NOLINTNEXTLINE(bugprone-macro-parentheses) */                             \\\n  SOURCEMETA_FORCEINLINE inline auto name() -> HTMLWriter & {                  \\\n    this->void_tag(#name);                                                     \\\n    return *this;                                                              \\\n  }\n#endif\n\n  // =========================================================================\n  // Document Structure Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(html)\n  /// @ingroup html\n  HTML_WRITER_VOID(base)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(head)\n  /// @ingroup html\n  HTML_WRITER_VOID(link)\n  /// @ingroup html\n  HTML_WRITER_VOID(meta)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(style)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(title)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(body)\n\n  // =========================================================================\n  // Content Sectioning Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(address)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(article)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(aside)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(footer)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(header)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h1)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h2)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h3)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h4)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h5)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(h6)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(hgroup)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(main)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(nav)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(section)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(search)\n\n  // =========================================================================\n  // Text Content Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(blockquote)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(dd)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(div)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(dl)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(dt)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(figcaption)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(figure)\n  /// @ingroup html\n  HTML_WRITER_VOID(hr)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(li)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(menu)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(ol)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(p)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(pre)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(ul)\n\n  // =========================================================================\n  // Inline Text Semantics Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(a)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(abbr)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(b)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(bdi)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(bdo)\n  /// @ingroup html\n  HTML_WRITER_VOID(br)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(cite)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(code)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(data)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(dfn)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(em)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(i)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(kbd)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(mark)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(q)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(rp)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(rt)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(ruby)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(s)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(samp)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(small)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(span)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(strong)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(sub)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(sup)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(time)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(u)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(var)\n  /// @ingroup html\n  HTML_WRITER_VOID(wbr)\n\n  // =========================================================================\n  // Image and Multimedia Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_VOID(area)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(audio)\n  /// @ingroup html\n  HTML_WRITER_VOID(img)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(map)\n  /// @ingroup html\n  HTML_WRITER_VOID(track)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(video)\n\n  // =========================================================================\n  // Embedded Content Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_VOID(embed)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(iframe)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(object)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(picture)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(portal)\n  /// @ingroup html\n  HTML_WRITER_VOID(source)\n\n  // =========================================================================\n  // Scripting Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(canvas)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(noscript)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(script)\n\n  // =========================================================================\n  // Demarcating Edits Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(del)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(ins)\n\n  // =========================================================================\n  // Table Content Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(caption)\n  /// @ingroup html\n  HTML_WRITER_VOID(col)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(colgroup)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(table)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(tbody)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(td)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(tfoot)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(th)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(thead)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(tr)\n\n  // =========================================================================\n  // Forms Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(button)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(datalist)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(fieldset)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(form)\n  /// @ingroup html\n  HTML_WRITER_VOID(input)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(label)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(legend)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(meter)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(optgroup)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(option)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(output)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(progress)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(select)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(textarea)\n\n  // =========================================================================\n  // Interactive Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(details)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(dialog)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(summary)\n\n  // =========================================================================\n  // Web Components Elements\n  // =========================================================================\n\n  /// @ingroup html\n  HTML_WRITER_CONTAINER(slot)\n  /// @ingroup html\n  HTML_WRITER_CONTAINER_NAMED(template_, template)\n\n#ifndef DOXYGEN\n#undef HTML_WRITER_CONTAINER\n#undef HTML_WRITER_CONTAINER_NAMED\n#undef HTML_WRITER_VOID\n#endif\n\nprivate:\n  SOURCEMETA_FORCEINLINE inline auto open_tag(std::string_view tag) -> void {\n    this->flush_open_tag();\n    this->buffer_.append(\"<\");\n    this->buffer_.append(tag);\n    this->tag_stack_.push_back(tag);\n    this->tag_open_ = true;\n    this->tag_open_is_void_ = false;\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto void_tag(std::string_view tag) -> void {\n    this->flush_open_tag();\n    this->buffer_.append(\"<\");\n    this->buffer_.append(tag);\n    this->tag_open_ = true;\n    this->tag_open_is_void_ = true;\n  }\n\n  auto flush_open_tag() -> void;\n\n  HTMLBuffer buffer_;\n  std::vector<std::string_view> tag_stack_;\n  bool tag_open_{false};\n  bool tag_open_is_void_{false};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/html/writer.cc",
    "content": "#include <sourcemeta/core/html_writer.h>\n\n#include <iostream> // std::ostream\n\nnamespace sourcemeta::core {\n\nauto HTMLBuffer::grow(const std::size_t needed) -> void {\n  const auto current_size{\n      this->cursor_\n          ? static_cast<std::size_t>(this->cursor_ - this->buffer_.data())\n          : 0};\n  auto new_capacity{this->buffer_.empty() ? 1024uz : this->buffer_.size() * 2};\n  while (new_capacity < current_size + needed) {\n    new_capacity *= 2;\n  }\n\n  this->buffer_.resize(new_capacity);\n  this->cursor_ = this->buffer_.data() + current_size;\n  this->end_ = this->buffer_.data() + new_capacity;\n}\n\nauto HTMLBuffer::write(std::ostream &stream) -> void {\n  if (this->cursor_) {\n    const auto size{\n        static_cast<std::size_t>(this->cursor_ - this->buffer_.data())};\n    stream.write(this->buffer_.data(), static_cast<std::streamsize>(size));\n  }\n}\n\nauto HTMLWriter::flush_open_tag() -> void {\n  if (this->tag_open_) {\n    if (this->tag_open_is_void_) {\n      this->buffer_.append(\" />\");\n    } else {\n      this->buffer_.append(\">\");\n    }\n\n    this->tag_open_ = false;\n    this->tag_open_is_void_ = false;\n  }\n}\n\nauto HTMLWriter::write(std::ostream &stream) -> void {\n  this->flush_open_tag();\n  this->buffer_.write(stream);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/ip/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME ip\n  SOURCES ipv4.cc ipv6.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME ip)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/ip/include/sourcemeta/core/ip.h",
    "content": "#ifndef SOURCEMETA_CORE_IP_H_\n#define SOURCEMETA_CORE_IP_H_\n\n#ifndef SOURCEMETA_CORE_IP_EXPORT\n#include <sourcemeta/core/ip_export.h>\n#endif\n\n#include <string_view> // std::string_view\n\n/// @defgroup ip IP\n/// @brief IPv4 (RFC 3986) and IPv6 (RFC 3986, RFC 4291) address validation.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/ip.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup ip\n/// Check whether the given string is a valid IPv4 address per RFC 3986\n/// Section 3.2.2. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/ip.h>\n///\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::is_ipv4(\"192.168.1.1\"));\n/// assert(!sourcemeta::core::is_ipv4(\"999.0.0.1\"));\n/// ```\nSOURCEMETA_CORE_IP_EXPORT\nauto is_ipv4(std::string_view address) -> bool;\n\n/// @ingroup ip\n/// Check whether the given string is a valid IPv6 address per RFC 3986\n/// Section 3.2.2 and RFC 4291 Section 2.2. The input must not include\n/// surrounding brackets. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/ip.h>\n///\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::is_ipv6(\"2001:db8::1\"));\n/// assert(!sourcemeta::core::is_ipv6(\"not an address\"));\n/// ```\nSOURCEMETA_CORE_IP_EXPORT\nauto is_ipv6(std::string_view address) -> bool;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/ip/ipv4.cc",
    "content": "#include <sourcemeta/core/ip.h>\n\nnamespace sourcemeta::core {\n\nstatic constexpr auto is_digit(const char character) -> bool {\n  return character >= '0' && character <= '9';\n}\n\nauto is_ipv4(const std::string_view address) -> bool {\n  if (address.empty()) {\n    return false;\n  }\n\n  std::string_view::size_type position{0};\n  unsigned int octet_count{0};\n\n  while (octet_count < 4) {\n    if (position >= address.size()) {\n      return false;\n    }\n\n    if (!is_digit(address[position])) {\n      return false;\n    }\n\n    const auto octet_start{position};\n    unsigned int value{0};\n    while (position < address.size() && is_digit(address[position])) {\n      value = value * 10 + static_cast<unsigned int>(address[position] - '0');\n      position += 1;\n    }\n\n    const auto octet_length{position - octet_start};\n\n    if (octet_length > 1 && address[octet_start] == '0') {\n      return false;\n    }\n\n    if (octet_length > 3 || value > 255) {\n      return false;\n    }\n\n    octet_count += 1;\n\n    if (octet_count < 4) {\n      if (position >= address.size() || address[position] != '.') {\n        return false;\n      }\n      position += 1;\n    }\n  }\n\n  return position == address.size();\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/ip/ipv6.cc",
    "content": "#include <sourcemeta/core/ip.h>\n\n#include <array>   // std::array\n#include <cstdint> // std::uint8_t\n\nnamespace sourcemeta::core {\n\nstatic constexpr auto make_hex_table() -> std::array<bool, 256> {\n  std::array<bool, 256> table{};\n  for (auto index{0u}; index < 256; index++) {\n    table[index] = (index >= '0' && index <= '9') ||\n                   (index >= 'a' && index <= 'f') ||\n                   (index >= 'A' && index <= 'F');\n  }\n  return table;\n}\n\nstatic constexpr auto HEX_TABLE{make_hex_table()};\n\nstatic constexpr auto is_hex_digit(const char character) -> bool {\n  return HEX_TABLE[static_cast<std::uint8_t>(character)];\n}\n\nauto is_ipv6(const std::string_view address) -> bool {\n  if (address.empty()) {\n    return false;\n  }\n\n  const auto size{address.size()};\n\n  if (address.front() == '[' || address.back() == ']') {\n    return false;\n  }\n\n  const auto double_colon{address.find(\"::\")};\n  const bool has_compression{double_colon != std::string_view::npos};\n\n  if (has_compression &&\n      address.find(\"::\", double_colon + 2) != std::string_view::npos) {\n    return false;\n  }\n\n  if (address.front() == ':' && (!has_compression || double_colon != 0)) {\n    return false;\n  }\n  if (address.back() == ':' &&\n      (!has_compression || double_colon + 1 != size - 1)) {\n    return false;\n  }\n\n  unsigned int group_count{0};\n  std::string_view::size_type position{0};\n\n  while (position < size) {\n    if (has_compression && position == double_colon) {\n      position += 2;\n      continue;\n    }\n\n    const auto group_start{position};\n    unsigned int hex_count{0};\n    bool found_dot{false};\n\n    while (position < size) {\n      const auto character{address[position]};\n      if (character == ':') {\n        break;\n      }\n      if (character == '.') {\n        found_dot = true;\n        break;\n      }\n      if (!is_hex_digit(character)) {\n        return false;\n      }\n      hex_count += 1;\n      position += 1;\n    }\n\n    if (found_dot) {\n      if (!is_ipv4(address.substr(group_start))) {\n        return false;\n      }\n      group_count += 2;\n      break;\n    }\n\n    if (hex_count == 0 || hex_count > 4) {\n      return false;\n    }\n\n    group_count += 1;\n\n    if (position < size && address[position] == ':') {\n      if (has_compression && position == double_colon) {\n        continue;\n      }\n      position += 1;\n      if (position >= size) {\n        return false;\n      }\n    }\n  }\n\n  if (has_compression) {\n    return group_count < 8;\n  }\n\n  return group_count == 8;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/json/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME json\n  PRIVATE_HEADERS array.h error.h object.h value.h hash.h auto.h\n  SOURCES grammar.h parser.h stringify.h json.cc json_value.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME json)\nendif()\n\ntarget_link_libraries(sourcemeta_core_json PRIVATE sourcemeta::core::io)\ntarget_link_libraries(sourcemeta_core_json PRIVATE sourcemeta::core::unicode)\ntarget_link_libraries(sourcemeta_core_json PUBLIC sourcemeta::core::numeric)\ntarget_link_libraries(sourcemeta_core_json PUBLIC sourcemeta::core::preprocessor)\n"
  },
  {
    "path": "vendor/core/src/core/json/construct.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_CONSTRUCT_H_\n#define SOURCEMETA_CORE_JSON_CONSTRUCT_H_\n\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/json_value.h>\n\n#include <sourcemeta/core/numeric.h>\n#include <sourcemeta/core/unicode.h>\n\n#include \"parser.h\"\n\n#include <cassert>    // assert\n#include <cstddef>    // std::size_t\n#include <cstdint>    // std::uint64_t, std::uint32_t\n#include <cstring>    // std::memchr\n#include <functional> // std::reference_wrapper\n#include <stdexcept>  // std::invalid_argument\n#include <utility>    // std::move\n#include <vector>     // std::vector\n\nnamespace sourcemeta::core {\n\nnamespace internal {\n\ninline auto unescape_string(const char *data, const std::uint32_t length) ->\n    typename JSON::String {\n  typename JSON::String result;\n  const char *cursor{data};\n  const char *string_end{data + length};\n\n  if (!std::memchr(data, '\\\\', length)) {\n    result.append(data, length);\n    return result;\n  }\n\n  result.reserve(length);\n  while (cursor < string_end) {\n    const char *scan{cursor};\n    while (scan < string_end && *scan != '\\\\') {\n      scan++;\n    }\n\n    if (scan > cursor) {\n      result.append(cursor, static_cast<std::size_t>(scan - cursor));\n      cursor = scan;\n    }\n\n    if (cursor >= string_end) {\n      break;\n    }\n\n    assert(*cursor == '\\\\');\n    cursor++;\n    assert(cursor < string_end);\n\n    switch (*cursor++) {\n      case '\"':\n        result.push_back('\"');\n        break;\n      case '\\\\':\n        result.push_back('\\\\');\n        break;\n      case '/':\n        result.push_back('/');\n        break;\n      case 'b':\n        result.push_back('\\b');\n        break;\n      case 'f':\n        result.push_back('\\f');\n        break;\n      case 'n':\n        result.push_back('\\n');\n        break;\n      case 'r':\n        result.push_back('\\r');\n        break;\n      case 't':\n        result.push_back('\\t');\n        break;\n      case 'u': {\n        auto parse_hex4 = [](const char *&position) -> unsigned long {\n          unsigned long value{0};\n          for (std::size_t index = 0; index < 4; index++) {\n            const char hex_char{*position++};\n            unsigned long digit;\n            if (hex_char >= '0' && hex_char <= '9') {\n              digit = static_cast<unsigned long>(hex_char - '0');\n            } else if (hex_char >= 'a' && hex_char <= 'f') {\n              digit = static_cast<unsigned long>(hex_char - 'a') + 10;\n            } else if (hex_char >= 'A' && hex_char <= 'F') {\n              digit = static_cast<unsigned long>(hex_char - 'A') + 10;\n            } else {\n              digit = 0;\n            }\n            value = (value << 4) | digit;\n          }\n          return value;\n        };\n\n        auto code_point{parse_hex4(cursor)};\n        if (code_point >= 0xD800 && code_point <= 0xDBFF) {\n          assert(cursor + 6 <= string_end);\n          cursor += 2;\n          const auto low{parse_hex4(cursor)};\n          code_point = 0x10000 + ((code_point - 0xD800) << 10) + (low - 0xDC00);\n        }\n\n        sourcemeta::core::codepoint_to_utf8(static_cast<char32_t>(code_point),\n                                            result);\n        break;\n      }\n      default:\n        break;\n    }\n  }\n\n  return result;\n}\n\ninline auto construct_number(const char *data, const std::uint32_t length)\n    -> JSON {\n  const bool has_dot{std::memchr(data, '.', length) != nullptr};\n  const bool has_exponent{std::memchr(data, 'e', length) != nullptr ||\n                          std::memchr(data, 'E', length) != nullptr};\n\n  if (has_exponent) {\n    try {\n      return JSON{Decimal{std::string_view{data, length}}};\n    } catch (const DecimalParseError &) {\n      throw JSONParseError(1, 1);\n    } catch (const std::invalid_argument &) {\n      throw JSONParseError(1, 1);\n    }\n  }\n\n  if (has_dot) {\n    std::size_t first_nonzero_position{JSON::String::npos};\n    const auto decimal_position{static_cast<std::size_t>(\n        static_cast<const char *>(std::memchr(data, '.', length)) - data)};\n    for (std::size_t index = 0; index < length; index++) {\n      if (index != decimal_position && data[index] != '0' &&\n          data[index] != '-') {\n        first_nonzero_position = index;\n        break;\n      }\n    }\n\n    if (first_nonzero_position == JSON::String::npos) {\n      first_nonzero_position = 0;\n    }\n\n    const auto decimal_after_first_nonzero{decimal_position >\n                                           first_nonzero_position};\n    const auto significant_digits{length - first_nonzero_position -\n                                  (decimal_after_first_nonzero ? 1 : 0)};\n    constexpr std::size_t MAX_SAFE_SIGNIFICANT_DIGITS{15};\n    if (significant_digits > MAX_SAFE_SIGNIFICANT_DIGITS) {\n      try {\n        return JSON{Decimal{std::string_view{data, length}}};\n      } catch (const DecimalParseError &) {\n        throw JSONParseError(1, 1);\n      } catch (const std::invalid_argument &) {\n        throw JSONParseError(1, 1);\n      }\n    }\n\n    const typename JSON::String string_value{data, length};\n    const auto double_result{sourcemeta::core::to_double(string_value)};\n    if (double_result.has_value()) {\n      return JSON{double_result.value()};\n    }\n    try {\n      return JSON{Decimal{string_value}};\n    } catch (const DecimalParseError &) {\n      throw JSONParseError(1, 1);\n    } catch (const std::invalid_argument &) {\n      throw JSONParseError(1, 1);\n    }\n  }\n\n  auto digit_length = length;\n  if (digit_length > 0 && data[0] == '-') {\n    digit_length--;\n  }\n\n  if (digit_length <= 19) {\n    const typename JSON::String string_value{data, length};\n    const auto int_result{sourcemeta::core::to_int64_t(string_value)};\n    if (int_result.has_value()) {\n      return JSON{int_result.value()};\n    }\n    try {\n      return JSON{Decimal{string_value}};\n    } catch (const DecimalParseError &) {\n      throw JSONParseError(1, 1);\n    } catch (const std::invalid_argument &) {\n      throw JSONParseError(1, 1);\n    }\n  }\n\n  try {\n    return JSON{Decimal{std::string_view{data, length}}};\n  } catch (const DecimalParseError &) {\n    throw JSONParseError(1, 1);\n  } catch (const std::invalid_argument &) {\n    throw JSONParseError(1, 1);\n  }\n}\n\ninline auto post_column_for(const TapeEntry &entry) -> std::uint64_t {\n  switch (entry.type) {\n    case TapeType::True:\n      return entry.column + 3;\n    case TapeType::False:\n      return entry.column + 4;\n    case TapeType::Null:\n      return entry.column + 3;\n    case TapeType::String:\n    case TapeType::Key:\n      return entry.column + entry.length + 1;\n    case TapeType::Number:\n      return entry.column + entry.length - 1;\n    default:\n      return entry.column;\n  }\n}\n\n} // namespace internal\n\n// NOLINTBEGIN(cppcoreguidelines-avoid-goto,bugprone-use-after-move)\n\n#define CALLBACK_PRE(value_type, entry_ref, context, index, property)          \\\n  if (callback) {                                                              \\\n    callback(JSON::ParsePhase::Pre, JSON::Type::value_type, (entry_ref).line,  \\\n             (entry_ref).column, context, index, property);                    \\\n  }\n\n#define CALLBACK_POST(value_type, post_line, post_column)                      \\\n  if (callback) {                                                              \\\n    callback(JSON::ParsePhase::Post, JSON::Type::value_type, post_line,        \\\n             post_column, JSON::ParseContext::Root, 0, empty_property);        \\\n  }\n\ninline auto construct_json(const char *buffer,\n                           const std::vector<TapeEntry> &tape,\n                           const JSON::ParseCallback &callback, JSON &output)\n    -> void {\n  using Result = JSON;\n  enum class Container : std::uint8_t { Array, Object };\n  std::vector<Container> levels;\n  std::vector<std::reference_wrapper<Result>> frames;\n  levels.reserve(32);\n  frames.reserve(32);\n  typename Result::String key;\n  typename Result::Object::hash_type key_hash;\n  std::uint64_t key_line{0};\n  std::uint64_t key_column{0};\n  std::size_t tape_index{0};\n  static const JSON::String empty_property;\n\n  if (tape.empty()) {\n    throw JSONParseError(1, 1);\n  }\n\n  const auto &entry{tape[tape_index]};\n  switch (entry.type) {\n    case TapeType::True:\n      CALLBACK_PRE(Boolean, entry, JSON::ParseContext::Root, 0, empty_property);\n      CALLBACK_POST(Boolean, entry.line, internal::post_column_for(entry));\n      output = JSON{true};\n      return;\n    case TapeType::False:\n      CALLBACK_PRE(Boolean, entry, JSON::ParseContext::Root, 0, empty_property);\n      CALLBACK_POST(Boolean, entry.line, internal::post_column_for(entry));\n      output = JSON{false};\n      return;\n    case TapeType::Null:\n      CALLBACK_PRE(Null, entry, JSON::ParseContext::Root, 0, empty_property);\n      CALLBACK_POST(Null, entry.line, internal::post_column_for(entry));\n      output = JSON{nullptr};\n      return;\n    case TapeType::String: {\n      CALLBACK_PRE(String, entry, JSON::ParseContext::Root, 0, empty_property);\n      auto value{Result{\n          internal::unescape_string(buffer + entry.offset, entry.length)}};\n      CALLBACK_POST(String, entry.line, internal::post_column_for(entry));\n      output = std::move(value);\n      return;\n    }\n    case TapeType::Number: {\n      auto value =\n          internal::construct_number(buffer + entry.offset, entry.length);\n      if (value.is_integer()) {\n        CALLBACK_PRE(Integer, entry, JSON::ParseContext::Root, 0,\n                     empty_property);\n        CALLBACK_POST(Integer, entry.line, internal::post_column_for(entry));\n      } else if (value.is_decimal()) {\n        CALLBACK_PRE(Decimal, entry, JSON::ParseContext::Root, 0,\n                     empty_property);\n        CALLBACK_POST(Decimal, entry.line, internal::post_column_for(entry));\n      } else {\n        CALLBACK_PRE(Real, entry, JSON::ParseContext::Root, 0, empty_property);\n        CALLBACK_POST(Real, entry.line, internal::post_column_for(entry));\n      }\n      output = std::move(value);\n      return;\n    }\n    case TapeType::ArrayStart:\n      CALLBACK_PRE(Array, entry, JSON::ParseContext::Root, 0, empty_property);\n      goto do_construct_array;\n    case TapeType::ObjectStart:\n      CALLBACK_PRE(Object, entry, JSON::ParseContext::Root, 0, empty_property);\n      goto do_construct_object;\n    default:\n      throw JSONParseError(1, 1);\n  }\n\n  /*\n   * Construct an array\n   */\n\ndo_construct_array: {\n  const auto &array_entry{tape[tape_index]};\n  assert(array_entry.type == TapeType::ArrayStart);\n  const auto child_count{array_entry.count};\n  tape_index++;\n\n  if (levels.empty()) {\n    levels.push_back(Container::Array);\n    output = Result::make_array();\n    frames.emplace_back(output);\n  } else if (levels.back() == Container::Array) {\n    levels.push_back(Container::Array);\n    frames.back().get().push_back(Result::make_array());\n    frames.emplace_back(frames.back().get().back());\n  } else if (levels.back() == Container::Object) {\n    levels.push_back(Container::Array);\n    frames.back().get().assign(key, Result::make_array());\n    if (callback) {\n      callback(JSON::ParsePhase::Pre, JSON::Type::Array, key_line, key_column,\n               JSON::ParseContext::Property, 0,\n               frames.back().get().as_object().back_key());\n    }\n    frames.emplace_back(frames.back().get().at(key));\n  }\n\n  frames.back().get().as_array().reserve(child_count);\n\n  if (child_count == 0) {\n    assert(tape[tape_index].type == TapeType::ArrayEnd);\n    const auto &end_entry{tape[tape_index]};\n    tape_index++;\n    CALLBACK_POST(Array, end_entry.line, end_entry.column);\n    goto do_construct_container_end;\n  }\n\n  goto do_construct_array_item;\n}\n\ndo_construct_array_item: {\n  assert(!levels.empty());\n  assert(levels.back() == Container::Array);\n  const auto &item_entry{tape[tape_index]};\n\n  switch (item_entry.type) {\n    case TapeType::ArrayStart:\n      CALLBACK_PRE(Array, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      goto do_construct_array;\n    case TapeType::ObjectStart:\n      CALLBACK_PRE(Object, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      goto do_construct_object;\n    case TapeType::True:\n      CALLBACK_PRE(Boolean, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      frames.back().get().push_back(JSON{true});\n      tape_index++;\n      CALLBACK_POST(Boolean, item_entry.line,\n                    internal::post_column_for(item_entry));\n      goto do_construct_array_item_separator;\n    case TapeType::False:\n      CALLBACK_PRE(Boolean, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      frames.back().get().push_back(JSON{false});\n      tape_index++;\n      CALLBACK_POST(Boolean, item_entry.line,\n                    internal::post_column_for(item_entry));\n      goto do_construct_array_item_separator;\n    case TapeType::Null:\n      CALLBACK_PRE(Null, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      frames.back().get().push_back(JSON{nullptr});\n      tape_index++;\n      CALLBACK_POST(Null, item_entry.line,\n                    internal::post_column_for(item_entry));\n      goto do_construct_array_item_separator;\n    case TapeType::String:\n      CALLBACK_PRE(String, item_entry, JSON::ParseContext::Index,\n                   frames.back().get().size(), empty_property);\n      frames.back().get().push_back(Result{internal::unescape_string(\n          buffer + item_entry.offset, item_entry.length)});\n      tape_index++;\n      CALLBACK_POST(String, item_entry.line,\n                    internal::post_column_for(item_entry));\n      goto do_construct_array_item_separator;\n    case TapeType::Number: {\n      const auto current_index{frames.back().get().size()};\n      auto value = internal::construct_number(buffer + item_entry.offset,\n                                              item_entry.length);\n      if (value.is_integer()) {\n        CALLBACK_PRE(Integer, item_entry, JSON::ParseContext::Index,\n                     current_index, empty_property);\n      } else if (value.is_decimal()) {\n        CALLBACK_PRE(Decimal, item_entry, JSON::ParseContext::Index,\n                     current_index, empty_property);\n      } else {\n        CALLBACK_PRE(Real, item_entry, JSON::ParseContext::Index, current_index,\n                     empty_property);\n      }\n      const auto value_type{value.type()};\n      frames.back().get().push_back(std::move(value));\n      tape_index++;\n      if (value_type == JSON::Type::Integer) {\n        CALLBACK_POST(Integer, item_entry.line,\n                      internal::post_column_for(item_entry));\n      } else if (value_type == JSON::Type::Decimal) {\n        CALLBACK_POST(Decimal, item_entry.line,\n                      internal::post_column_for(item_entry));\n      } else {\n        CALLBACK_POST(Real, item_entry.line,\n                      internal::post_column_for(item_entry));\n      }\n      goto do_construct_array_item_separator;\n    }\n    default:\n      throw JSONParseError(1, 1);\n  }\n}\n\ndo_construct_array_item_separator:\n  if (tape[tape_index].type == TapeType::ArrayEnd) {\n    const auto &end_entry{tape[tape_index]};\n    tape_index++;\n    CALLBACK_POST(Array, end_entry.line, end_entry.column);\n    goto do_construct_container_end;\n  }\n\n  goto do_construct_array_item;\n\n  /*\n   * Construct an object\n   */\n\ndo_construct_object: {\n  const auto &object_entry{tape[tape_index]};\n  assert(object_entry.type == TapeType::ObjectStart);\n  const auto property_count{object_entry.count};\n  tape_index++;\n\n  if (levels.empty()) {\n    levels.push_back(Container::Object);\n    output = Result::make_object();\n    frames.emplace_back(output);\n  } else if (levels.back() == Container::Array) {\n    levels.push_back(Container::Object);\n    frames.back().get().push_back(Result::make_object());\n    frames.emplace_back(frames.back().get().back());\n  } else if (levels.back() == Container::Object) {\n    levels.push_back(Container::Object);\n    frames.back().get().assign(key, Result::make_object());\n    if (callback) {\n      callback(JSON::ParsePhase::Pre, JSON::Type::Object, key_line, key_column,\n               JSON::ParseContext::Property, 0,\n               frames.back().get().as_object().back_key());\n    }\n    frames.emplace_back(frames.back().get().at(key));\n  }\n\n  frames.back().get().as_object().reserve(property_count);\n\n  if (property_count == 0) {\n    assert(tape[tape_index].type == TapeType::ObjectEnd);\n    const auto &end_entry{tape[tape_index]};\n    tape_index++;\n    CALLBACK_POST(Object, end_entry.line, end_entry.column);\n    goto do_construct_container_end;\n  }\n\n  goto do_construct_object_key;\n}\n\ndo_construct_object_key: {\n  assert(!levels.empty());\n  assert(levels.back() == Container::Object);\n  const auto &key_entry{tape[tape_index]};\n  assert(key_entry.type == TapeType::Key);\n  const char *key_data{buffer + key_entry.offset};\n  const auto key_length{key_entry.length};\n  if (std::memchr(key_data, '\\\\', key_length)) {\n    key = internal::unescape_string(key_data, key_length);\n    key_hash = frames.back().get().as_object().hash(key);\n  } else {\n    key.assign(key_data, key_length);\n    key_hash = frames.back().get().as_object().hash(key_data, key_length);\n  }\n  key_line = key_entry.line;\n  key_column = key_entry.column;\n  tape_index++;\n  goto do_construct_object_value;\n}\n\ndo_construct_object_value: {\n  const auto &value_entry{tape[tape_index]};\n\n  switch (value_entry.type) {\n    case TapeType::ArrayStart:\n      goto do_construct_array;\n    case TapeType::ObjectStart:\n      goto do_construct_object;\n    case TapeType::True:\n      frames.back().get().assign_assume_new(std::move(key), JSON{true},\n                                            key_hash);\n      if (callback) {\n        callback(JSON::ParsePhase::Pre, JSON::Type::Boolean, key_line,\n                 key_column, JSON::ParseContext::Property, 0,\n                 frames.back().get().as_object().back_key());\n      }\n      tape_index++;\n      CALLBACK_POST(Boolean, value_entry.line,\n                    internal::post_column_for(value_entry));\n      goto do_construct_object_property_end;\n    case TapeType::False:\n      frames.back().get().assign_assume_new(std::move(key), JSON{false},\n                                            key_hash);\n      if (callback) {\n        callback(JSON::ParsePhase::Pre, JSON::Type::Boolean, key_line,\n                 key_column, JSON::ParseContext::Property, 0,\n                 frames.back().get().as_object().back_key());\n      }\n      tape_index++;\n      CALLBACK_POST(Boolean, value_entry.line,\n                    internal::post_column_for(value_entry));\n      goto do_construct_object_property_end;\n    case TapeType::Null:\n      frames.back().get().assign_assume_new(std::move(key), JSON{nullptr},\n                                            key_hash);\n      if (callback) {\n        callback(JSON::ParsePhase::Pre, JSON::Type::Null, key_line, key_column,\n                 JSON::ParseContext::Property, 0,\n                 frames.back().get().as_object().back_key());\n      }\n      tape_index++;\n      CALLBACK_POST(Null, value_entry.line,\n                    internal::post_column_for(value_entry));\n      goto do_construct_object_property_end;\n    case TapeType::String:\n      frames.back().get().assign_assume_new(\n          std::move(key),\n          Result{internal::unescape_string(buffer + value_entry.offset,\n                                           value_entry.length)},\n          key_hash);\n      if (callback) {\n        callback(JSON::ParsePhase::Pre, JSON::Type::String, key_line,\n                 key_column, JSON::ParseContext::Property, 0,\n                 frames.back().get().as_object().back_key());\n      }\n      tape_index++;\n      CALLBACK_POST(String, value_entry.line,\n                    internal::post_column_for(value_entry));\n      goto do_construct_object_property_end;\n    case TapeType::Number: {\n      auto value = internal::construct_number(buffer + value_entry.offset,\n                                              value_entry.length);\n      const auto value_type{value.type()};\n      frames.back().get().assign_assume_new(std::move(key), std::move(value),\n                                            key_hash);\n      if (callback) {\n        if (value_type == JSON::Type::Integer) {\n          callback(JSON::ParsePhase::Pre, JSON::Type::Integer, key_line,\n                   key_column, JSON::ParseContext::Property, 0,\n                   frames.back().get().as_object().back_key());\n        } else if (value_type == JSON::Type::Decimal) {\n          callback(JSON::ParsePhase::Pre, JSON::Type::Decimal, key_line,\n                   key_column, JSON::ParseContext::Property, 0,\n                   frames.back().get().as_object().back_key());\n        } else {\n          callback(JSON::ParsePhase::Pre, JSON::Type::Real, key_line,\n                   key_column, JSON::ParseContext::Property, 0,\n                   frames.back().get().as_object().back_key());\n        }\n      }\n      tape_index++;\n      if (value_type == JSON::Type::Integer) {\n        CALLBACK_POST(Integer, value_entry.line,\n                      internal::post_column_for(value_entry));\n      } else if (value_type == JSON::Type::Decimal) {\n        CALLBACK_POST(Decimal, value_entry.line,\n                      internal::post_column_for(value_entry));\n      } else {\n        CALLBACK_POST(Real, value_entry.line,\n                      internal::post_column_for(value_entry));\n      }\n      goto do_construct_object_property_end;\n    }\n    default:\n      throw JSONParseError(1, 1);\n  }\n}\n\ndo_construct_object_property_end:\n  if (tape[tape_index].type == TapeType::ObjectEnd) {\n    const auto &end_entry{tape[tape_index]};\n    tape_index++;\n    CALLBACK_POST(Object, end_entry.line, end_entry.column);\n    goto do_construct_container_end;\n  }\n\n  goto do_construct_object_key;\n\n  /*\n   * Finish constructing a container\n   */\n\ndo_construct_container_end:\n  assert(!levels.empty());\n  if (levels.size() == 1) {\n    return;\n  }\n\n  frames.pop_back();\n  levels.pop_back();\n  if (levels.back() == Container::Array) {\n    goto do_construct_array_item_separator;\n  } else {\n    goto do_construct_object_property_end;\n  }\n}\n\n// NOLINTEND(cppcoreguidelines-avoid-goto,bugprone-use-after-move)\n\n#undef CALLBACK_PRE\n#undef CALLBACK_POST\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/grammar.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_GRAMMAR_H_\n#define SOURCEMETA_CORE_JSON_GRAMMAR_H_\n\n#include <string_view> // std::basic_string_view\n\nnamespace sourcemeta::core::internal {\n\n// The six structural tokens:\n// [ U+005B  left square bracket\n// { U+007B  left curly bracket\n// ] U+005D  right square bracket\n// } U+007D  right curly bracket\n// : U+003A  colon\n// , U+002C  comma\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\n\n// A string is a sequence of Unicode code points wrapped with quotation marks\n// (U+0022). All code points may be placed within the quotation marks except\n// for the code points that must be escaped: quotation mark (U+0022), reverse\n// solidus (U+005C), and the control characters U+0000 to U+001F.\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\ntemplate <typename CharT> static constexpr CharT token_string_quote{'\\u0022'};\ntemplate <typename CharT> static constexpr CharT token_string_escape{'\\u005C'};\ntemplate <typename CharT> static constexpr CharT token_string_solidus{'\\u002F'};\n\n// There are two-character escape sequence representations of some characters.\n//\n// \\\" represents the quotation mark character (U+0022).\n// \\\\ represents the reverse solidus character (U+005C).\n// \\/ represents the solidus character (U+002F).\n// \\b represents the backspace character (U+0008).\n// \\f represents the form feed character (U+000C).\n// \\n represents the line feed character (U+000A).\n// \\r represents the carriage return character (U+000D).\n// \\t represents the character tabulation character (U+0009).\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_backspace{'\\u0062'};\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_form_feed{'\\u0066'};\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_line_feed{'\\u006E'};\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_carriage_return{'\\u0072'};\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_tabulation{'\\u0074'};\ntemplate <typename CharT>\nstatic constexpr CharT token_string_escape_unicode{'\\u0075'};\n\n// Array\ntemplate <typename CharT> static constexpr CharT token_array_begin{'\\u005B'};\ntemplate <typename CharT> static constexpr CharT token_array_end{'\\u005D'};\ntemplate <typename CharT>\nstatic constexpr CharT token_array_delimiter{'\\u002C'};\n\n// Object\ntemplate <typename CharT> static constexpr CharT token_object_begin{'\\u007B'};\ntemplate <typename CharT> static constexpr CharT token_object_end{'\\u007D'};\ntemplate <typename CharT>\nstatic constexpr CharT token_object_key_delimiter{'\\u003A'};\ntemplate <typename CharT>\nstatic constexpr CharT token_object_delimiter{'\\u002C'};\n\n// These are the three literal name tokens:\n// true  U+0074 U+0072 U+0075 U+0065\n// false U+0066 U+0061 U+006C U+0073 U+0065\n// null  U+006E U+0075 U+006C U+006C\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\n\n// Boolean\ntemplate <typename CharT> static constexpr CharT token_true{'\\u0074'};\ntemplate <typename CharT, typename Traits>\nstatic constexpr std::basic_string_view<CharT, Traits> constant_true{\n    \"\\u0074\\u0072\\u0075\\u0065\"};\ntemplate <typename CharT> static constexpr CharT token_false{'\\u0066'};\ntemplate <typename CharT, typename Traits>\nstatic constexpr std::basic_string_view<CharT, Traits> constant_false{\n    \"\\u0066\\u0061\\u006C\\u0073\\u0065\"};\n\n// Null\ntemplate <typename CharT> static constexpr CharT token_null{'\\u006E'};\ntemplate <typename CharT, typename Traits>\nstatic constexpr std::basic_string_view<CharT, Traits> constant_null{\n    \"\\u006E\\u0075\\u006C\\u006C\"};\n\n// A number is a sequence of decimal digits with no superfluous leading zero.\n// It may have a preceding minus sign (U+002D). It may have a fractional part\n// prefixed by a decimal point (U+002E). It may have an exponent, prefixed by e\n// (U+0065) or E (U+0045) and optionally + (U+002B) or – (U+002D). The digits\n// are the code points U+0030 through U+0039.\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\ntemplate <typename CharT>\nstatic constexpr CharT token_number_decimal_point{'\\u002E'};\ntemplate <typename CharT>\nstatic constexpr CharT token_number_exponent_uppercase{'\\u0045'};\ntemplate <typename CharT>\nstatic constexpr CharT token_number_exponent_lowercase{'\\u0065'};\ntemplate <typename CharT> static constexpr CharT token_number_plus{'\\u002B'};\ntemplate <typename CharT> static constexpr CharT token_number_minus{'\\u002D'};\ntemplate <typename CharT> static constexpr CharT token_number_zero{'\\u0030'};\ntemplate <typename CharT> static constexpr CharT token_number_one{'\\u0031'};\ntemplate <typename CharT> static constexpr CharT token_number_two{'\\u0032'};\ntemplate <typename CharT> static constexpr CharT token_number_three{'\\u0033'};\ntemplate <typename CharT> static constexpr CharT token_number_four{'\\u0034'};\ntemplate <typename CharT> static constexpr CharT token_number_five{'\\u0035'};\ntemplate <typename CharT> static constexpr CharT token_number_six{'\\u0036'};\ntemplate <typename CharT> static constexpr CharT token_number_seven{'\\u0037'};\ntemplate <typename CharT> static constexpr CharT token_number_eight{'\\u0038'};\ntemplate <typename CharT> static constexpr CharT token_number_nine{'\\u0039'};\n\n// Whitespace is any sequence of one or more of the following code points:\n// character tabulation (U+0009), line feed (U+000A), carriage return (U+000D),\n// and space (U+0020).\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\ntemplate <typename CharT>\nstatic constexpr CharT token_whitespace_tabulation{'\\u0009'};\ntemplate <typename CharT>\nstatic constexpr CharT token_whitespace_line_feed{'\\u000A'};\ntemplate <typename CharT>\nstatic constexpr CharT token_whitespace_carriage_return{'\\u000D'};\ntemplate <typename CharT>\nstatic constexpr CharT token_whitespace_space{'\\u0020'};\n\n} // namespace sourcemeta::core::internal\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_H_\n#define SOURCEMETA_CORE_JSON_H_\n\n#ifndef SOURCEMETA_CORE_JSON_EXPORT\n#include <sourcemeta/core/json_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/json_auto.h>\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/json_value.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <sourcemeta/core/preprocessor.h>\n\n#include <cstdint>    // std::uint64_t\n#include <filesystem> // std::filesystem\n#include <format> // std::formatter, std::format_context, std::format_parse_context, std::format_to\n#include <fstream>          // std::basic_ifstream\n#include <initializer_list> // std::initializer_list\n#include <istream>          // std::basic_istream\n#include <ostream>          // std::basic_ostream\n#include <sstream>          // std::ostringstream\n#include <string>           // std::basic_string\n\n/// @defgroup json JSON\n/// @brief A full-blown ECMA-404 implementation with read, write, and iterators\n/// support.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\n///\n/// Create a JSON document from a C++ standard input stream. For example, a JSON\n/// document that represents an array can be parsed as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ 1, 2, 3 ]\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n/// assert(document.is_array());\n/// ```\n///\n/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream)\n    -> JSON;\n\n/// @ingroup json\n///\n/// Create a JSON document from a JSON string. For example, a JSON document that\n/// represents an array can be parsed as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n/// assert(document.is_array());\n/// ```\n///\n/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input) -> JSON;\n\n/// @ingroup json\n///\n/// Create a JSON document from a C++ standard input stream, passing your own\n/// `line` and `column` read/write position indicators. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ 1, 2, 3 ]\"};\n/// std::uint64_t line{1};\n/// std::uint64_t column{0};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream, line, column);\n/// assert(document.is_array());\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                std::uint64_t &line, std::uint64_t &column) -> JSON;\n\n/// @ingroup json\n///\n/// Create a JSON document from a JSON string, passing your own\n/// `line` and `column` read/write position indicators. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n///\n/// std::uint64_t line{1};\n/// std::uint64_t column{0};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\", line, column);\n/// assert(document.is_array());\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    std::uint64_t &line, std::uint64_t &column) -> JSON;\n\n/// @ingroup json\n///\n/// A convenience function to create a JSON document from a file. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::read_json(\"/tmp/foo.json\");\n/// sourcemeta::core::stringify(document, std::cout);\n/// std::cout << std::endl;\n/// ```\n///\n/// If parsing fails, sourcemeta::core::JSONFileParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto read_json(const std::filesystem::path &path) -> JSON;\n\n/// @ingroup json\n///\n/// Parse a JSON document from a C++ standard input stream into an existing\n/// JSON value, invoking the given callback during parsing. The result is\n/// constructed directly into the given reference rather than returned by value\n/// to ensure that references passed through the parse callback (such as object\n/// property names) remain valid after parsing completes.\n///\n/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                JSON &output, const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup json\n///\n/// Parse a JSON document from a JSON string into an existing JSON value,\n/// invoking the given callback during parsing. The result is constructed\n/// directly into the given reference rather than returned by value to ensure\n/// that references passed through the parse callback (such as object property\n/// names) remain valid after parsing completes.\n///\n/// If parsing fails, sourcemeta::core::JSONParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    JSON &output, const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup json\n///\n/// Parse a JSON document from a C++ standard input stream into an existing\n/// JSON value, passing your own `line` and `column` read/write position\n/// indicators and invoking the given callback during parsing. The result is\n/// constructed directly into the given reference rather than returned by value\n/// to ensure that references passed through the parse callback (such as object\n/// property names) remain valid after parsing completes.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                std::uint64_t &line, std::uint64_t &column, JSON &output,\n                const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup json\n///\n/// Parse a JSON document from a JSON string into an existing JSON value,\n/// passing your own `line` and `column` read/write position indicators and\n/// invoking the given callback during parsing. The result is constructed\n/// directly into the given reference rather than returned by value to ensure\n/// that references passed through the parse callback (such as object property\n/// names) remain valid after parsing completes.\nSOURCEMETA_CORE_JSON_EXPORT\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    std::uint64_t &line, std::uint64_t &column, JSON &output,\n    const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup json\n///\n/// A convenience function to parse a JSON document from a file into an existing\n/// JSON value, invoking the given callback during parsing. The result is\n/// constructed directly into the given reference rather than returned by value\n/// to ensure that references passed through the parse callback (such as object\n/// property names) remain valid after parsing completes.\n///\n/// If parsing fails, sourcemeta::core::JSONFileParseError will be thrown.\nSOURCEMETA_CORE_JSON_EXPORT\nauto read_json(const std::filesystem::path &path, JSON &output,\n               const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup json\n///\n/// Stringify the input JSON document into a given C++ standard output stream in\n/// compact mode. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n/// std::ostringstream stream;\n/// sourcemeta::core::stringify(document, stream);\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto stringify(const JSON &document,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void;\n\n/// @ingroup json\n///\n/// Stringify the input JSON document into a given C++ standard output stream in\n/// pretty mode. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n/// std::ostringstream stream;\n/// sourcemeta::core::prettify(document, stream);\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto prettify(const JSON &document,\n              std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n              const std::size_t spaces = 2) -> void;\n\n/// @ingroup json\n///\n/// Encode the input JSON document into a given standard output stream.\n/// The JSON document is stringified or prettified depending on the\n/// presence of the `NDEBUG` define (for debugging purposes). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n/// std::ostringstream stream;\n/// stream << document;\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto operator<<(std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                const JSON &document)\n    -> std::basic_ostream<JSON::Char, JSON::CharTraits> &;\n\n/// @ingroup json\n///\n/// Encode the input JSON type as a string into a given standard output stream.\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// std::ostringstream stream;\n/// stream << sourcemeta::core::JSON::Type::String;\n/// // Will print \"string\"\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSON_EXPORT\nauto operator<<(std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                const JSON::Type type)\n    -> std::basic_ostream<JSON::Char, JSON::CharTraits> &;\n\n/// @ingroup json\n///\n/// Create a JSON type set from an initializer list of types. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n///\n/// const auto types = sourcemeta::core::make_set(\n///     {sourcemeta::core::JSON::Type::Object,\n///      sourcemeta::core::JSON::Type::Array});\n/// ```\nSOURCEMETA_FORCEINLINE inline auto\nmake_set(std::initializer_list<JSON::Type> types) -> JSON::TypeSet {\n  JSON::TypeSet result;\n  for (const auto type : types) {\n    result.set(static_cast<std::size_t>(type));\n  }\n  return result;\n}\n\n} // namespace sourcemeta::core\n\ntemplate <> struct std::formatter<sourcemeta::core::JSON> {\n  constexpr auto parse(std::format_parse_context &context)\n      -> decltype(context.begin()) {\n    return context.begin();\n  }\n\n  auto format(const sourcemeta::core::JSON &value,\n              std::format_context &context) const -> decltype(context.out()) {\n    std::ostringstream stream;\n    stream << value;\n    return std::format_to(context.out(), \"{}\", stream.str());\n  }\n};\n\ntemplate <> struct std::formatter<sourcemeta::core::JSON::Type> {\n  constexpr auto parse(std::format_parse_context &context)\n      -> decltype(context.begin()) {\n    return context.begin();\n  }\n\n  auto format(const sourcemeta::core::JSON::Type value,\n              std::format_context &context) const -> decltype(context.out()) {\n    std::ostringstream stream;\n    stream << value;\n    return std::format_to(context.out(), \"{}\", stream.str());\n  }\n};\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_array.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_ARRAY_H_\n#define SOURCEMETA_CORE_JSON_ARRAY_H_\n\n#include <initializer_list> // std::initializer_list\n#include <vector>           // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\ntemplate <typename Value> class JSONArray {\npublic:\n  // Constructors\n  using Container =\n      std::vector<Value, typename Value::template Allocator<Value>>;\n  JSONArray() : data{} {}\n  JSONArray(std::initializer_list<Value> values) : data{values} {}\n\n  // Operators\n  // We cannot default given that this class references\n  // a JSON \"value\" as an incomplete type\n  auto operator<(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data < other.data;\n  }\n  auto operator<=(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data <= other.data;\n  }\n  auto operator>(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data > other.data;\n  }\n  auto operator>=(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data >= other.data;\n  }\n  auto operator==(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data == other.data;\n  }\n  auto operator!=(const JSONArray<Value> &other) const noexcept -> bool {\n    return this->data != other.data;\n  }\n\n  // Member types\n  using value_type = typename Container::value_type;\n  using allocator_type = typename Container::allocator_type;\n  using size_type = typename Container::size_type;\n  using difference_type = typename Container::difference_type;\n  using reference = typename Container::reference;\n  using const_reference = typename Container::const_reference;\n  using pointer = typename Container::pointer;\n  using const_pointer = typename Container::const_pointer;\n  using iterator = typename Container::iterator;\n  using const_iterator = typename Container::const_iterator;\n  using reverse_iterator = typename Container::reverse_iterator;\n  using const_reverse_iterator = typename Container::const_reverse_iterator;\n\n  /// Get a mutable begin iterator on the array\n  auto begin() noexcept -> iterator { return this->data.begin(); }\n  /// Get a mutable end iterator on the array\n  auto end() noexcept -> iterator { return this->data.end(); }\n  /// Get a constant begin iterator on the array\n  [[nodiscard]] auto begin() const noexcept -> const_iterator {\n    return this->data.begin();\n  }\n  /// Get a constant end iterator on the array\n  [[nodiscard]] auto end() const noexcept -> const_iterator {\n    return this->data.end();\n  }\n  /// Get a constant begin iterator on the array\n  [[nodiscard]] auto cbegin() const noexcept -> const_iterator {\n    return this->data.cbegin();\n  }\n  /// Get a constant end iterator on the array\n  [[nodiscard]] auto cend() const noexcept -> const_iterator {\n    return this->data.cend();\n  }\n  /// Get a mutable reverse begin iterator on the array\n  auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); }\n  /// Get a mutable reverse end iterator on the array\n  auto rend() noexcept -> reverse_iterator { return this->data.rend(); }\n  /// Get a constant reverse begin iterator on the array\n  [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator {\n    return this->data.rbegin();\n  }\n  /// Get a constant reverse end iterator on the array\n  [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator {\n    return this->data.rend();\n  }\n  /// Get a constant reverse begin iterator on the array\n  [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator {\n    return this->data.crbegin();\n  }\n  /// Get a constant reverse end iterator on the array\n  [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator {\n    return this->data.crend();\n  }\n\n  /// Get array size\n  [[nodiscard]] auto size() const noexcept -> size_type {\n    return this->data.size();\n  }\n\n  /// Reserve capacity for a given number of elements\n  auto reserve(const size_type capacity) -> void {\n    this->data.reserve(capacity);\n  }\n\nprivate:\n  friend Value;\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  Container data;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_auto.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_AUTO_H_\n#define SOURCEMETA_CORE_JSON_AUTO_H_\n\n#include <sourcemeta/core/json_value.h>\n\n#include <algorithm> // std::sort\n#include <bitset>    // std::bitset\n#include <cassert>   // assert\n#include <chrono>    // std::chrono\n#include <concepts> // std::same_as, std::constructible_from, std::invocable, std::invocable\n#include <filesystem> // std::filesystem\n#include <functional> // std::function\n#include <optional>   // std::optional, std::nullopt, std::bad_optional_access\n#include <tuple> // std::tuple, std::apply, std::tuple_element_t, std::tuple_size, std::tuple_size_v\n#include <type_traits> // std::false_type, std::true_type, std::is_enum_v, std::underlying_type_t, std::is_same_v, std::is_base_of_v, std::remove_cvref_t\n#include <utility> // std::pair, std:::make_index_sequence, std::index_sequence\n#include <variant> // std::variant, std::variant_size_v, std::variant_alternative_t, std::visit\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_has_mapped_type = requires { typename T::mapped_type; };\n\n/// @ingroup json\ntemplate <typename T> struct json_auto_is_basic_string : std::false_type {};\ntemplate <typename CharT, typename Traits, typename Alloc>\nstruct json_auto_is_basic_string<std::basic_string<CharT, Traits, Alloc>>\n    : std::true_type {};\n\n/// @ingroup json\ntemplate <typename T>\nstruct json_auto_is_basic_string_view : std::false_type {};\ntemplate <typename CharT, typename Traits>\nstruct json_auto_is_basic_string_view<std::basic_string_view<CharT, Traits>>\n    : std::true_type {};\n\n/// @ingroup json\ntemplate <typename T> struct json_auto_is_bitset : std::false_type {};\ntemplate <std::size_t N>\nstruct json_auto_is_bitset<std::bitset<N>> : std::true_type {};\n\n/// @ingroup json\ntemplate <typename T> struct json_auto_bitset_size;\ntemplate <std::size_t N>\nstruct json_auto_bitset_size<std::bitset<N>>\n    : std::integral_constant<std::size_t, N> {};\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_has_method_from = requires(const JSON &value) {\n  { T::from_json(value) } -> std::same_as<std::optional<T>>;\n};\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_has_method_to = requires(const T value) {\n  { value.to_json() } -> std::same_as<JSON>;\n};\n\n/// @ingroup json\n/// Container-like classes can opt-out from automatic JSON\n/// serialisation by setting `using json_auto = std::false_type;`\ntemplate <typename T>\nconcept json_auto_supports_auto = !requires {\n  typename T::json_auto;\n} || !std::is_same_v<typename T::json_auto, std::false_type>;\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_list_like =\n    requires(T type) {\n      typename T::value_type;\n      typename T::const_iterator;\n      { type.cbegin() } -> std::same_as<typename T::const_iterator>;\n      { type.cend() } -> std::same_as<typename T::const_iterator>;\n    } && json_auto_supports_auto<T> && !json_auto_has_mapped_type<T> &&\n    !json_auto_has_method_from<T> && !json_auto_has_method_to<T> &&\n    !json_auto_is_basic_string<T>::value &&\n    !json_auto_is_basic_string_view<T>::value;\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_map_like =\n    requires(T type) {\n      typename T::value_type;\n      typename T::const_iterator;\n      typename T::key_type;\n      { type.cbegin() } -> std::same_as<typename T::const_iterator>;\n      { type.cend() } -> std::same_as<typename T::const_iterator>;\n    } && json_auto_supports_auto<T> && json_auto_has_mapped_type<T> &&\n    !json_auto_has_method_from<T> && !json_auto_has_method_to<T> &&\n    std::is_same_v<typename T::key_type, JSON::String>;\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_has_reverse_iterator =\n    requires { typename T::reverse_iterator; };\n\n/// @ingroup json\ntemplate <typename T> struct json_auto_is_pair : std::false_type {};\n\n/// @ingroup json\ntemplate <typename U, typename V>\nstruct json_auto_is_pair<std::pair<U, V>> : std::true_type {};\n\n/// @ingroup json\ntemplate <typename T> struct json_auto_is_variant : std::false_type {};\n\n/// @ingroup json\ntemplate <typename... Ts>\nstruct json_auto_is_variant<std::variant<Ts...>> : std::true_type {};\n\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_tuple_mono = requires {\n  typename std::tuple_size<std::remove_cvref_t<T>>::type;\n} && (std::tuple_size_v<std::remove_cvref_t<T>> == 1);\n\n// We have to do this mess because MSVC seems confuses `std::pair`\n// of 2 elements with this overload\n/// @ingroup json\ntemplate <typename T>\nconcept json_auto_tuple_poly =\n    requires { typename std::tuple_size<std::remove_cvref_t<T>>::type; } &&\n    (std::tuple_size_v<std::remove_cvref_t<T>> >= 2) &&\n    (!std::is_base_of_v<\n        std::pair<std::tuple_element_t<0, std::remove_cvref_t<T>>,\n                  std::tuple_element_t<1, std::remove_cvref_t<T>>>,\n        std::remove_cvref_t<T>>);\n\n// Forward declarations for recursive type conversions\n#ifndef DOXYGEN\ntemplate <json_auto_list_like T> auto to_json(const T &value) -> JSON;\ntemplate <json_auto_map_like T> auto to_json(const T &value) -> JSON;\ntemplate <typename L, typename R>\nauto to_json(const std::pair<L, R> &value) -> JSON;\ntemplate <json_auto_tuple_mono T> auto to_json(const T &value) -> JSON;\ntemplate <json_auto_tuple_poly T> auto to_json(const T &value) -> JSON;\ntemplate <typename T>\n  requires json_auto_is_variant<T>::value\nauto to_json(const T &value) -> JSON;\n#endif\n\n/// @ingroup json\n/// If the value has a `.to_json()` method, always prefer that\ntemplate <typename T>\n  requires(json_auto_has_method_to<T>)\nauto to_json(const T &value) -> JSON {\n  return value.to_json();\n}\n\n/// @ingroup json\n/// If the value has a `.from_json()` static method, always prefer that\ntemplate <typename T>\n  requires(json_auto_has_method_from<T>)\nauto from_json(const JSON &value) -> std::optional<T> {\n  return T::from_json(value);\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, bool>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_boolean()) {\n    return value.to_boolean();\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires(std::is_integral_v<T> && !std::is_same_v<T, bool>)\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_integer()) {\n    return static_cast<T>(value.to_integer());\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, Decimal>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_decimal()) {\n    return value.to_decimal();\n  } else {\n    return std::nullopt;\n  }\n}\n\n// TODO: How can we keep this in the hash header that does not yet know about\n// JSON?\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, JSON::Object::hash_type>\nauto to_json(const T &hash) -> JSON {\n  auto result{JSON::make_array()};\n  result.push_back(JSON{static_cast<std::size_t>(hash.a >> 64)});\n  result.push_back(JSON{static_cast<std::size_t>(hash.a)});\n  result.push_back(JSON{static_cast<std::size_t>(hash.b >> 64)});\n  result.push_back(JSON{static_cast<std::size_t>(hash.b)});\n  return result;\n}\n\n// TODO: How can we keep this in the hash header that does not yet know about\n// JSON?\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, JSON::Object::hash_type>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array() || value.size() != 4 || !value.at(0).is_integer() ||\n      !value.at(1).is_integer() || !value.at(2).is_integer() ||\n      !value.at(3).is_integer()) {\n    return std::nullopt;\n  }\n\n  using uint128_type = JSON::Object::hash_type::type;\n  return T{(static_cast<uint128_type>(\n                static_cast<std::uint64_t>(value.at(0).to_integer()))\n            << 64) |\n               static_cast<uint128_type>(\n                   static_cast<std::uint64_t>(value.at(1).to_integer())),\n           (static_cast<uint128_type>(\n                static_cast<std::uint64_t>(value.at(2).to_integer()))\n            << 64) |\n               static_cast<uint128_type>(\n                   static_cast<std::uint64_t>(value.at(3).to_integer()))};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires(std::constructible_from<JSON, T> &&\n           // Otherwise MSVC gets confused\n           !std::is_same_v<T, unsigned long long>)\nauto to_json(const T &value) -> JSON {\n  return JSON{value};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, std::filesystem::file_time_type>\nauto to_json(const T value) -> JSON {\n  return JSON{static_cast<std::int64_t>(value.time_since_epoch().count())};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, std::filesystem::file_time_type>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_integer()) {\n    using file_time_type = std::filesystem::file_time_type;\n    return file_time_type{file_time_type::duration{\n        static_cast<file_time_type::duration::rep>(value.to_integer())}};\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires(std::is_same_v<T, std::filesystem::path> &&\n           // In at least Clang and GCC, paths are convertible to strings,\n           // resulting in ambiguous templated calls\n           !std::is_convertible_v<T, std::string>)\nauto to_json(const T value) -> JSON {\n  return JSON{value.string()};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, std::filesystem::path>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_string()) {\n    return value.to_string();\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_bitset<T>::value\nauto to_json(const T &bitset) -> JSON {\n  constexpr std::size_t N{json_auto_bitset_size<T>::value};\n  if constexpr (N <= 64) {\n    return JSON{static_cast<std::int64_t>(bitset.to_ullong())};\n  } else {\n    return JSON{bitset.to_string()};\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_bitset<T>::value\nauto from_json(const JSON &value) -> std::optional<T> {\n  constexpr std::size_t N{json_auto_bitset_size<T>::value};\n  if constexpr (N <= 64) {\n    if (value.is_integer()) {\n      return T{static_cast<unsigned long long>(value.to_integer())};\n    } else {\n      return std::nullopt;\n    }\n  } else {\n    if (value.is_string()) {\n      return T{value.to_string()};\n    } else {\n      return std::nullopt;\n    }\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, unsigned long long>\nauto to_json(const T value) -> JSON {\n  return JSON{static_cast<std::int64_t>(value)};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_same_v<T, JSON>\nauto from_json(const JSON &value) -> std::optional<T> {\n  return value;\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_basic_string<T>::value\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_string()) {\n    return value.to_string();\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_enum_v<T>\nauto to_json(const T value) -> JSON {\n  return to_json(static_cast<std::underlying_type_t<T>>(value));\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires std::is_enum_v<T>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_integer()) {\n    return static_cast<T>(value.to_integer());\n  } else {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T> auto to_json(const std::optional<T> &value) -> JSON {\n  return value.has_value() ? to_json(value.value()) : JSON{nullptr};\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires requires { typename T::value_type; } &&\n           std::is_same_v<T, std::optional<typename T::value_type>>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (value.is_null()) {\n    return std::optional<T>{\n        std::optional<typename T::value_type>{std::nullopt}};\n  } else {\n    auto result{from_json<typename T::value_type>(value)};\n    if (!result.has_value()) {\n      return std::nullopt;\n    }\n\n    return result;\n  }\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T>\nauto to_json(typename T::const_iterator begin, typename T::const_iterator end)\n    -> JSON {\n  // TODO: Extend `make_array` to optionally take iterators, etc\n  auto result{JSON::make_array()};\n  for (auto iterator = begin; iterator != end; ++iterator) {\n    result.push_back(to_json(*iterator));\n  }\n\n  // To guarantee ordering across implementations\n  if constexpr (!json_auto_has_reverse_iterator<T>) {\n    std::sort(result.as_array().begin(), result.as_array().end());\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T,\n          std::invocable<const typename T::value_type &> F>\nauto to_json(typename T::const_iterator begin, typename T::const_iterator end,\n             const F &callback) -> JSON {\n  // TODO: Extend `make_array` to optionally take iterators, etc\n  auto result{JSON::make_array()};\n  for (auto iterator = begin; iterator != end; ++iterator) {\n    result.push_back(callback(*iterator));\n  }\n\n  // To guarantee ordering across implementations\n  if constexpr (!json_auto_has_reverse_iterator<T>) {\n    std::sort(result.as_array().begin(), result.as_array().end());\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T> auto to_json(const T &value) -> JSON {\n  return to_json<T>(value.cbegin(), value.cend());\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T,\n          std::invocable<const typename T::value_type &> F>\nauto to_json(const T &value, const F &callback) -> JSON {\n  return to_json<T>(value.cbegin(), value.cend(), callback);\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array()) {\n    return std::nullopt;\n  }\n\n  T result;\n\n  if constexpr (requires { result.reserve(value.size()); }) {\n    result.reserve(value.size());\n  }\n\n  for (const auto &item : value.as_array()) {\n    auto subvalue{from_json<typename T::value_type>(item)};\n    if (!subvalue.has_value()) {\n      return std::nullopt;\n    }\n\n    if constexpr (requires { result.insert(subvalue.value()); }) {\n      result.insert(std::move(subvalue).value());\n    } else {\n      result.push_back(std::move(subvalue).value());\n    }\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_list_like T>\nauto from_json(\n    const JSON &value,\n    const std::function<std::optional<typename T::value_type>(const JSON &)>\n        &callback) -> std::optional<T> {\n  if (!value.is_array()) {\n    return std::nullopt;\n  }\n\n  T result;\n\n  if constexpr (requires { result.reserve(value.size()); }) {\n    result.reserve(value.size());\n  }\n\n  for (const auto &item : value.as_array()) {\n    auto subvalue{callback(item)};\n    if (!subvalue.has_value()) {\n      return std::nullopt;\n    }\n\n    if constexpr (requires { result.insert(subvalue.value()); }) {\n      result.insert(std::move(subvalue).value());\n    } else {\n      result.push_back(std::move(subvalue).value());\n    }\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T>\nauto to_json(typename T::const_iterator begin, typename T::const_iterator end)\n    -> JSON {\n  auto result{JSON::make_object()};\n  for (auto iterator = begin; iterator != end; ++iterator) {\n    result.assign(iterator->first, to_json(iterator->second));\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T> auto to_json(const T &value) -> JSON {\n  return to_json<T>(value.cbegin(), value.cend());\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T,\n          std::invocable<const typename T::mapped_type &> F>\nauto to_json(typename T::const_iterator begin, typename T::const_iterator end,\n             const F &callback) -> JSON {\n  auto result{JSON::make_object()};\n  for (auto iterator = begin; iterator != end; ++iterator) {\n    result.assign(iterator->first, callback(iterator->second));\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_object()) {\n    return std::nullopt;\n  }\n\n  T result;\n  for (const auto &item : value.as_object()) {\n    auto subvalue{from_json<typename T::mapped_type>(item.second)};\n    if (!subvalue.has_value()) {\n      return std::nullopt;\n    }\n\n    result.emplace(item.first, std::move(subvalue).value());\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T>\nauto from_json(\n    const JSON &value,\n    const std::function<std::optional<typename T::mapped_type>(const JSON &)>\n        &callback) -> std::optional<T> {\n  if (!value.is_object()) {\n    return std::nullopt;\n  }\n\n  T result;\n  for (const auto &item : value.as_object()) {\n    auto subvalue{callback(item.second)};\n    if (!subvalue.has_value()) {\n      return std::nullopt;\n    }\n\n    result.emplace(item.first, std::move(subvalue).value());\n  }\n\n  return result;\n}\n\n/// @ingroup json\ntemplate <json_auto_map_like T,\n          std::invocable<const typename T::mapped_type &> F>\nauto to_json(const T &value, const F &callback) -> JSON {\n  return to_json<T>(value.cbegin(), value.cend(), callback);\n}\n\n/// @ingroup json\ntemplate <typename L, typename R>\nauto to_json(const std::pair<L, R> &value) -> JSON {\n  auto tuple{JSON::make_array()};\n  tuple.push_back(to_json(value.first));\n  tuple.push_back(to_json(value.second));\n  return tuple;\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_pair<T>::value\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array() || value.size() != 2) {\n    return std::nullopt;\n  }\n\n  auto first{from_json<typename T::first_type>(value.at(0))};\n  auto second{from_json<typename T::second_type>(value.at(1))};\n  if (!first.has_value() || !second.has_value()) {\n    return std::nullopt;\n  }\n\n  return std::make_pair<typename T::first_type, typename T::second_type>(\n      std::move(first).value(), std::move(second).value());\n}\n\n// Handle 1-element tuples\n/// @ingroup json\ntemplate <json_auto_tuple_mono T> auto to_json(const T &value) -> JSON {\n  auto tuple = JSON::make_array();\n  std::apply([&](const auto &element) { tuple.push_back(to_json(element)); },\n             value);\n  return tuple;\n}\n\n/// @ingroup json\ntemplate <json_auto_tuple_mono T>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array() || value.size() != 1) {\n    return std::nullopt;\n  }\n\n  auto first{from_json<std::tuple_element_t<0, T>>(value.at(0))};\n  if (!first.has_value()) {\n    return std::nullopt;\n  }\n\n  return {std::move(first).value()};\n}\n\n/// @ingroup json\ntemplate <json_auto_tuple_poly T> auto to_json(const T &value) -> JSON {\n  auto tuple = JSON::make_array();\n  std::apply(\n      [&tuple](const auto &...elements) {\n        (tuple.push_back(to_json(elements)), ...);\n      },\n      value);\n  return tuple;\n}\n\n#ifndef DOXYGEN\ntemplate <typename T, std::size_t... Indices>\nauto from_json_tuple_poly(const JSON &value, std::index_sequence<Indices...>)\n    -> T {\n  return {from_json<std::tuple_element_t<Indices, T>>(value.at(Indices))\n              .value()...};\n}\n#endif\n\n/// @ingroup json\ntemplate <json_auto_tuple_poly T>\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array() || value.size() != std::tuple_size_v<T>) {\n    return std::nullopt;\n  }\n\n  try {\n    return from_json_tuple_poly<T>(\n        value, std::make_index_sequence<std::tuple_size_v<T>>{});\n    // TODO: Maybe there is a better way to catch this without using exceptions?\n  } catch (const std::bad_optional_access &) {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_variant<T>::value\nauto to_json(const T &value) -> JSON {\n  auto result{JSON::make_array()};\n  result.push_back(JSON{static_cast<std::int64_t>(value.index())});\n  std::visit(\n      [&result](const auto &alternative) {\n        result.push_back(to_json(alternative));\n      },\n      value);\n  return result;\n}\n\n#ifndef DOXYGEN\ntemplate <typename T, std::size_t Index = 0>\nauto from_json_variant_impl(const JSON &data, std::size_t index)\n    -> std::optional<T> {\n  if constexpr (Index >= std::variant_size_v<T>) {\n    return std::nullopt;\n  } else {\n    if (Index == index) {\n      auto result{from_json<std::variant_alternative_t<Index, T>>(data)};\n      if (result.has_value()) {\n        return T{std::in_place_index<Index>, std::move(result).value()};\n      }\n\n      return std::nullopt;\n    } else {\n      return from_json_variant_impl<T, Index + 1>(data, index);\n    }\n  }\n}\n#endif\n\n/// @ingroup json\ntemplate <typename T>\n  requires json_auto_is_variant<T>::value\nauto from_json(const JSON &value) -> std::optional<T> {\n  if (!value.is_array() || value.size() != 2 || !value.at(0).is_integer()) {\n    return std::nullopt;\n  }\n\n  const auto index{static_cast<std::size_t>(value.at(0).to_integer())};\n  if (index >= std::variant_size_v<T>) {\n    return std::nullopt;\n  } else {\n    return from_json_variant_impl<T>(value.at(1), index);\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_error.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_ERROR_H_\n#define SOURCEMETA_CORE_JSON_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_JSON_EXPORT\n#include <sourcemeta/core/json_export.h>\n#endif\n\n#include <cstdint>     // std::uint64_t\n#include <exception>   // std::exception\n#include <filesystem>  // std::filesystem::path\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup json\n/// This class represents a parsing error\nclass SOURCEMETA_CORE_JSON_EXPORT JSONParseError : public std::exception {\npublic:\n  /// Create a parsing error\n  JSONParseError(const std::uint64_t line, const std::uint64_t column)\n      : line_{line}, column_{column},\n        message_{\"Failed to parse the JSON document\"} {}\n\n  /// Create a parsing error with a custom error\n  JSONParseError(const std::uint64_t line, const std::uint64_t column,\n                 const char *message)\n      : line_{line}, column_{column}, message_{message} {}\n  JSONParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string message) = delete;\n  JSONParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string &&message) = delete;\n  JSONParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  /// Get the line number of the error\n  [[nodiscard]] auto line() const noexcept -> std::uint64_t {\n    return this->line_;\n  }\n\n  // Get the column number of the error\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  std::uint64_t line_;\n  std::uint64_t column_;\n  const char *message_;\n};\n\n/// @ingroup json\n/// This class represents a parsing error occurring from parsing a file\nclass SOURCEMETA_CORE_JSON_EXPORT JSONFileParseError : public JSONParseError {\npublic:\n  /// Create a file parsing error\n  JSONFileParseError(std::filesystem::path path, const std::uint64_t line,\n                     const std::uint64_t column, const char *message)\n      : JSONParseError{line, column, message}, path_{std::move(path)} {}\n  JSONFileParseError(std::filesystem::path path, const std::uint64_t line,\n                     const std::uint64_t column, std::string message) = delete;\n  JSONFileParseError(std::filesystem::path path, const std::uint64_t line,\n                     const std::uint64_t column,\n                     std::string &&message) = delete;\n  JSONFileParseError(std::filesystem::path path, const std::uint64_t line,\n                     const std::uint64_t column,\n                     std::string_view message) = delete;\n\n  /// Create a file parsing error from a parse error\n  JSONFileParseError(std::filesystem::path path, const JSONParseError &parent)\n      : JSONParseError{parent.line(), parent.column(), parent.what()},\n        path_{std::move(path)} {}\n\n  /// Get the file path of the error\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_hash.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_HASH_H_\n#define SOURCEMETA_CORE_JSON_HASH_H_\n\n#include <sourcemeta/core/numeric.h>\n\n#include <cassert>    // assert\n#include <cstring>    // std::memcpy\n#include <functional> // std::reference_wrapper\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\ntemplate <typename T> struct HashJSON {\n  using hash_type = std::uint64_t;\n\n  inline auto operator()(const T &value) const noexcept -> hash_type {\n    if constexpr (requires { value.get().fast_hash(); }) {\n      return value.get().fast_hash();\n    } else {\n      return value.fast_hash();\n    }\n  }\n\n  [[nodiscard]]\n  inline auto is_perfect(const hash_type) const noexcept -> bool {\n    return false;\n  }\n};\n\n/// @ingroup json\ntemplate <typename T> struct PropertyHashJSON {\n  struct hash_type {\n    using type = sourcemeta::core::uint128_t;\n    type a{0};\n    type b{0};\n\n    auto operator==(const hash_type &) const noexcept -> bool = default;\n  };\n\n  [[nodiscard]]\n  inline auto perfect(const char *data, const std::size_t size) const noexcept\n      -> hash_type {\n    hash_type result;\n    assert(size > 0);\n    std::memcpy(reinterpret_cast<char *>(&result) + 1, data, size);\n    return result;\n  }\n\n  // GCC does not optimise well across implicit type conversions such as\n  // std::string to std::string_view, so we provide separate overloads with\n  // duplicated logic instead of unifying on a single parameter type\n\n  inline auto operator()(const T &value) const noexcept -> hash_type {\n    const auto size{value.size()};\n    switch (size) {\n      case 0:\n        return {};\n      case 1:\n        return this->perfect(value.data(), 1);\n      case 2:\n        return this->perfect(value.data(), 2);\n      case 3:\n        return this->perfect(value.data(), 3);\n      case 4:\n        return this->perfect(value.data(), 4);\n      case 5:\n        return this->perfect(value.data(), 5);\n      case 6:\n        return this->perfect(value.data(), 6);\n      case 7:\n        return this->perfect(value.data(), 7);\n      case 8:\n        return this->perfect(value.data(), 8);\n      case 9:\n        return this->perfect(value.data(), 9);\n      case 10:\n        return this->perfect(value.data(), 10);\n      case 11:\n        return this->perfect(value.data(), 11);\n      case 12:\n        return this->perfect(value.data(), 12);\n      case 13:\n        return this->perfect(value.data(), 13);\n      case 14:\n        return this->perfect(value.data(), 14);\n      case 15:\n        return this->perfect(value.data(), 15);\n      case 16:\n        return this->perfect(value.data(), 16);\n      case 17:\n        return this->perfect(value.data(), 17);\n      case 18:\n        return this->perfect(value.data(), 18);\n      case 19:\n        return this->perfect(value.data(), 19);\n      case 20:\n        return this->perfect(value.data(), 20);\n      case 21:\n        return this->perfect(value.data(), 21);\n      case 22:\n        return this->perfect(value.data(), 22);\n      case 23:\n        return this->perfect(value.data(), 23);\n      case 24:\n        return this->perfect(value.data(), 24);\n      case 25:\n        return this->perfect(value.data(), 25);\n      case 26:\n        return this->perfect(value.data(), 26);\n      case 27:\n        return this->perfect(value.data(), 27);\n      case 28:\n        return this->perfect(value.data(), 28);\n      case 29:\n        return this->perfect(value.data(), 29);\n      case 30:\n        return this->perfect(value.data(), 30);\n      case 31:\n        return this->perfect(value.data(), 31);\n      default:\n        // This case is specifically designed to be constant with regards to\n        // string length, and to exploit the fact that most JSON objects don't\n        // have a lot of entries, so hash collision is not as common\n        auto hash = this->perfect(value.data(), 31);\n        hash.a |=\n            1 + (size + static_cast<typename hash_type::type>(value.front()) +\n                 static_cast<typename hash_type::type>(value.back())) %\n                    // Make sure the property hash can never exceed 8 bits\n                    255;\n        return hash;\n    }\n  }\n\n  inline auto operator()(const char *data,\n                         const std::size_t size) const noexcept -> hash_type {\n    switch (size) {\n      case 0:\n        return {};\n      case 1:\n        return this->perfect(data, 1);\n      case 2:\n        return this->perfect(data, 2);\n      case 3:\n        return this->perfect(data, 3);\n      case 4:\n        return this->perfect(data, 4);\n      case 5:\n        return this->perfect(data, 5);\n      case 6:\n        return this->perfect(data, 6);\n      case 7:\n        return this->perfect(data, 7);\n      case 8:\n        return this->perfect(data, 8);\n      case 9:\n        return this->perfect(data, 9);\n      case 10:\n        return this->perfect(data, 10);\n      case 11:\n        return this->perfect(data, 11);\n      case 12:\n        return this->perfect(data, 12);\n      case 13:\n        return this->perfect(data, 13);\n      case 14:\n        return this->perfect(data, 14);\n      case 15:\n        return this->perfect(data, 15);\n      case 16:\n        return this->perfect(data, 16);\n      case 17:\n        return this->perfect(data, 17);\n      case 18:\n        return this->perfect(data, 18);\n      case 19:\n        return this->perfect(data, 19);\n      case 20:\n        return this->perfect(data, 20);\n      case 21:\n        return this->perfect(data, 21);\n      case 22:\n        return this->perfect(data, 22);\n      case 23:\n        return this->perfect(data, 23);\n      case 24:\n        return this->perfect(data, 24);\n      case 25:\n        return this->perfect(data, 25);\n      case 26:\n        return this->perfect(data, 26);\n      case 27:\n        return this->perfect(data, 27);\n      case 28:\n        return this->perfect(data, 28);\n      case 29:\n        return this->perfect(data, 29);\n      case 30:\n        return this->perfect(data, 30);\n      case 31:\n        return this->perfect(data, 31);\n      default:\n        // This case is specifically designed to be constant with regards to\n        // string length, and to exploit the fact that most JSON objects don't\n        // have a lot of entries, so hash collision is not as common\n        auto hash = this->perfect(data, 31);\n        hash.a |= 1 + (size + static_cast<typename hash_type::type>(data[0]) +\n                       static_cast<typename hash_type::type>(data[size - 1])) %\n                          // Make sure the property hash can never exceed 8 bits\n                          255;\n        return hash;\n    }\n  }\n\n  [[nodiscard]]\n  inline auto is_perfect(const hash_type &hash) const noexcept -> bool {\n    // If there is anything written past the first byte,\n    // then it is a perfect hash\n    return (hash.a & 255) == 0;\n  }\n};\n\n/// @ingroup json\n/// Until C++26, `std::reference_wrapper` does not overload `operator==`,\n/// so we need custom comparisons for use in i.e. `unordered_set`\n/// See\n/// https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator_cmp.html\ntemplate <typename T> struct EqualJSON {\n  inline auto operator()(const T &left, const T &right) const -> bool {\n    if constexpr (requires { left.get() == right.get(); }) {\n      return left.get() == right.get();\n    } else {\n      return left == right;\n    }\n  }\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_object.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_OBJECT_H_\n#define SOURCEMETA_CORE_JSON_OBJECT_H_\n\n#include <algorithm>        // std::sort\n#include <cassert>          // assert\n#include <concepts>         // std::same_as\n#include <cstddef>          // std::size_t\n#include <initializer_list> // std::initializer_list\n#include <iterator>         // std::advance\n#include <string_view>      // std::basic_string_view\n#include <type_traits>      // std::remove_cvref_t\n#include <utility>          // std::pair, std::move, std::unreachable\n#include <vector>           // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\ntemplate <typename Key, typename Value, typename Hash> class JSONObject {\npublic:\n  JSONObject() = default;\n\n  using key_type = Key;\n  using mapped_type = Value;\n  using hash_type = typename Hash::hash_type;\n  using pair_value_type = std::pair<key_type, mapped_type>;\n  using KeyView = std::basic_string_view<typename Key::value_type,\n                                         typename Key::traits_type>;\n\n  JSONObject(std::initializer_list<pair_value_type> entries) : data{} {\n    this->data.reserve(entries.size());\n    for (auto &&entry : entries) {\n      this->emplace(std::move(entry.first), std::move(entry.second));\n    }\n  }\n\n  struct Entry {\n    key_type first;\n    mapped_type second;\n    hash_type hash;\n  };\n\n  using underlying_type = std::vector<Entry>;\n  using value_type = typename underlying_type::value_type;\n  using size_type = typename underlying_type::size_type;\n  using difference_type = typename underlying_type::difference_type;\n  using allocator_type = typename underlying_type::allocator_type;\n  using reference = typename underlying_type::reference;\n  using const_reference = typename underlying_type::const_reference;\n  using pointer = typename underlying_type::pointer;\n  using const_pointer = typename underlying_type::const_pointer;\n  using const_iterator = typename underlying_type::const_iterator;\n\n  // Operators\n  // We cannot default given that this class references\n  // a JSON \"value\" as an incomplete type\n\n  auto operator<(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool {\n    // The `std::unordered_map` container, by definition, does not provide\n    // ordering. However, we still want some level of ordering to allow\n    // arrays of objects to be sorted.\n\n    // First try a size comparison\n    if (this->data.size() != other.data.size()) {\n      return this->data.size() < other.data.size();\n    }\n\n    // Otherwise do value comparison for common properties\n    for (const auto &entry : *this) {\n      const auto other_entry{other.find(entry.first)};\n      if (other_entry != other.cend() && entry.second < other_entry->second) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  auto operator<=(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool {\n    return this->data <= other.data;\n  }\n  auto operator>(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool {\n    return this->data > other.data;\n  }\n  auto operator>=(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool {\n    return this->data >= other.data;\n  }\n\n  auto operator==(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool {\n    if (this->size() != other.size()) {\n      return false;\n    }\n\n    for (const auto &entry : this->data) {\n      const auto *result{other.try_at(entry.first, entry.hash)};\n      if (!result || *result != entry.second) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  auto operator!=(const JSONObject<Key, Value, Hash> &other) const noexcept\n      -> bool = default;\n\n  [[nodiscard]] inline auto begin() const noexcept -> const_iterator {\n    return this->data.begin();\n  }\n  /// Get a constant end iterator on the object\n  [[nodiscard]] inline auto end() const noexcept -> const_iterator {\n    return this->data.end();\n  }\n  /// Get a constant begin iterator on the object\n  [[nodiscard]] inline auto cbegin() const noexcept -> const_iterator {\n    return this->data.cbegin();\n  }\n  /// Get a constant end iterator on the object\n  [[nodiscard]] inline auto cend() const noexcept -> const_iterator {\n    return this->data.cend();\n  }\n\n  // GCC does not optimise well across implicit type conversions such as\n  // std::string to std::string_view, so we provide separate overloads with\n  // duplicated logic instead of unifying on a single parameter type. The\n  // `KeyView`-accepting overloads are constrained to actual `std::string_view`\n  // arguments only, so callers passing a string literal continue to bind to\n  // the `Key`-accepting overload as before.\n\n  /// Compute a hash for a key\n  [[nodiscard]] inline auto hash(const Key &key) const noexcept -> hash_type {\n    return this->hasher(key);\n  }\n\n  /// Compute a hash for a key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto hash(T key) const noexcept -> hash_type {\n    return this->hasher(key.data(), key.size());\n  }\n\n  /// Compute a hash from raw data\n  [[nodiscard]] inline auto hash(const char *raw_data,\n                                 const std::size_t raw_size) const noexcept\n      -> hash_type {\n    return hasher(raw_data, raw_size);\n  }\n\n  /// Attempt to find an entry by key\n  [[nodiscard]] inline auto find(const Key &key) const -> const_iterator {\n    const auto key_hash{this->hash(key)};\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    } else {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    }\n\n    return this->cend();\n  }\n\n  /// Attempt to find an entry by key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto find(T key) const -> const_iterator {\n    const auto key_hash{this->hash(key)};\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    } else {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    }\n\n    return this->cend();\n  }\n\n  /// Check if an entry with the given key exists\n  [[nodiscard]] inline auto defines(const Key &key, const hash_type hash) const\n      -> bool {\n    assert(this->hash(key) == hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(hash)) {\n      for (const auto &entry : *this) {\n        if (entry.hash == hash) {\n          return true;\n        }\n      }\n    } else {\n      for (const auto &entry : *this) {\n        if (entry.hash == hash && entry.first == key) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  /// Check if an entry with the given key exists\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto defines(T key, const hash_type hash) const -> bool {\n    assert(this->hash(key) == hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(hash)) {\n      for (const auto &entry : *this) {\n        if (entry.hash == hash) {\n          return true;\n        }\n      }\n    } else {\n      for (const auto &entry : *this) {\n        if (entry.hash == hash && entry.first == key) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  /// Check the size of the object\n  [[nodiscard]] inline auto size() const -> std::size_t {\n    return this->data.size();\n  }\n\n  /// Check if the object is empty\n  [[nodiscard]] inline auto empty() const -> bool { return this->data.empty(); }\n\n  /// Reserve capacity for a given number of entries\n  inline auto reserve(const size_type capacity) -> void {\n    this->data.reserve(capacity);\n  }\n\n  /// Access an object entry by its underlying positional index\n  [[nodiscard]] inline auto at(const size_type index) const -> const Entry & {\n    return this->data.at(index);\n  }\n\n  /// Access an object entry by its key name\n  [[nodiscard]] inline auto at(const Key &key, const hash_type key_hash) const\n      -> const mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (const auto &entry : *this) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (const auto &entry : *this) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n    std::unreachable();\n  }\n\n  /// Access an object entry by its key name\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto at(T key, const hash_type key_hash) const\n      -> const mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (const auto &entry : *this) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (const auto &entry : *this) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n    std::unreachable();\n  }\n\n  /// Access an object entry by its key name\n  inline auto at(const Key &key, const hash_type key_hash) -> mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n    std::unreachable();\n  }\n\n  /// Access an object entry by its key name\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  inline auto at(T key, const hash_type key_hash) -> mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n    std::unreachable();\n  }\n\n  /// Try to access an object entry by its underlying positional index\n  [[nodiscard]] inline auto try_at(const Key &key,\n                                   const hash_type key_hash) const\n      -> const mapped_type * {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash) {\n          return &this->data[index].second;\n        }\n      }\n    } else {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          return &this->data[index].second;\n        }\n      }\n    }\n\n    return nullptr;\n  }\n\n  /// Try to access an object entry by its underlying positional index\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto try_at(T key, const hash_type key_hash) const\n      -> const mapped_type * {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash) {\n          return &this->data[index].second;\n        }\n      }\n    } else {\n      for (size_type index = 0; index < this->size(); index++) {\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          return &this->data[index].second;\n        }\n      }\n    }\n\n    return nullptr;\n  }\n\n  /// Try to access an object entry, scanning from a caller-provided start\n  /// offset. On hit, advances `start` past the found index\n  [[nodiscard]] inline auto try_at(const Key &key, const hash_type key_hash,\n                                   size_type &start) const\n      -> const mapped_type * {\n    assert(this->hash(key) == key_hash);\n    const auto object_size{this->size()};\n    assert(start <= object_size);\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type count = 0; count < object_size; count++) {\n        const auto index{(start + count) % object_size};\n        if (this->data[index].hash == key_hash) {\n          start = index + 1;\n          return &this->data[index].second;\n        }\n      }\n    } else {\n      for (size_type count = 0; count < object_size; count++) {\n        const auto index{(start + count) % object_size};\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          start = index + 1;\n          return &this->data[index].second;\n        }\n      }\n    }\n\n    return nullptr;\n  }\n\n  /// Try to access an object entry, scanning from a caller-provided start\n  /// offset. On hit, advances `start` past the found index\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  [[nodiscard]] inline auto try_at(T key, const hash_type key_hash,\n                                   size_type &start) const\n      -> const mapped_type * {\n    assert(this->hash(key) == key_hash);\n    const auto object_size{this->size()};\n    assert(start <= object_size);\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type count = 0; count < object_size; count++) {\n        const auto index{(start + count) % object_size};\n        if (this->data[index].hash == key_hash) {\n          start = index + 1;\n          return &this->data[index].second;\n        }\n      }\n    } else {\n      for (size_type count = 0; count < object_size; count++) {\n        const auto index{(start + count) % object_size};\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          start = index + 1;\n          return &this->data[index].second;\n        }\n      }\n    }\n\n    return nullptr;\n  }\n\n  /// Try to emplace a property before another property\n  auto try_emplace_before(const Key &key, const mapped_type &value,\n                          const Key &suffix) -> hash_type {\n    const auto key_hash{this->hash(key)};\n    const auto suffix_hash{this->hash(suffix)};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash) {\n          iterator->second = value;\n          return key_hash;\n        } else if (iterator->hash == suffix_hash && iterator->first == suffix) {\n          this->data.insert(iterator, {key, value, key_hash});\n          return key_hash;\n        }\n      }\n    } else {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash && iterator->first == key) {\n          iterator->second = value;\n          return key_hash;\n        } else if (iterator->hash == suffix_hash && iterator->first == suffix) {\n          this->data.insert(iterator, {key, value, key_hash});\n          return key_hash;\n        }\n      }\n    }\n\n    this->data.push_back({key, value, key_hash});\n    return key_hash;\n  }\n\n  /// Emplace an object property\n  inline auto emplace(Key &&key, mapped_type &&value) -> hash_type {\n    const auto key_hash{this->hash(key)};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          entry.second = std::move(value);\n          return key_hash;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          entry.second = std::move(value);\n          return key_hash;\n        }\n      }\n    }\n\n    this->data.push_back({key, value, key_hash});\n    return key_hash;\n  }\n\n  /// Emplace an object property\n  inline auto emplace(const Key &key, const mapped_type &value) -> hash_type {\n    const auto key_hash{this->hash(key)};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          entry.second = value;\n          return key_hash;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          entry.second = value;\n          return key_hash;\n        }\n      }\n    }\n\n    this->data.push_back({key, value, key_hash});\n    return key_hash;\n  }\n\n  /// Emplace an object property assuming the key does not already exist\n  inline auto emplace_assume_new(Key &&key, mapped_type &&value) -> hash_type {\n    const auto key_hash{this->hash(key)};\n    this->data.push_back({std::move(key), std::move(value), key_hash});\n    return key_hash;\n  }\n\n  /// Emplace an object property assuming the key does not already exist\n  inline auto emplace_assume_new(const Key &key, mapped_type &&value)\n      -> hash_type {\n    const auto key_hash{this->hash(key)};\n    this->data.push_back({key, std::move(value), key_hash});\n    return key_hash;\n  }\n\n  /// Emplace an object property with a pre-computed hash\n  inline auto emplace_assume_new(Key &&key, mapped_type &&value,\n                                 const hash_type key_hash) -> void {\n    this->data.push_back({std::move(key), std::move(value), key_hash});\n  }\n\n  /// Emplace an object property with a pre-computed hash\n  inline auto emplace_assume_new(const Key &key, mapped_type &&value,\n                                 const hash_type key_hash) -> void {\n    this->data.push_back({key, std::move(value), key_hash});\n  }\n\n  /// Get the key of the last-inserted property\n  [[nodiscard]] inline auto back_key() const noexcept -> const Key & {\n    assert(!this->data.empty());\n    return this->data.back().first;\n  }\n\n  /// Remove every property in the object\n  inline auto clear() noexcept -> void { this->data.clear(); }\n\n  /// Rename an object property in place\n  auto rename(const Key &key, const hash_type key_hash, Key &&to,\n              const hash_type to_hash) -> void {\n    this->erase(to, to_hash);\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          entry.first = std::move(to);\n          entry.hash = to_hash;\n          break;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          entry.first = std::move(to);\n          entry.hash = to_hash;\n          break;\n        }\n      }\n    }\n  }\n\n  /// Erase an object property\n  auto erase(const Key &key, const hash_type key_hash) -> size_type {\n    const auto current_size{this->size()};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash) {\n          this->data.erase(iterator);\n          return current_size - 1;\n        }\n      }\n    } else {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash && iterator->first == key) {\n          this->data.erase(iterator);\n          return current_size - 1;\n        }\n      }\n    }\n\n    return current_size;\n  }\n\n  /// Erase an object property\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  auto erase(T key, const hash_type key_hash) -> size_type {\n    const auto current_size{this->size()};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash) {\n          this->data.erase(iterator);\n          return current_size - 1;\n        }\n      }\n    } else {\n      for (auto iterator = this->data.begin(); iterator != this->data.end();\n           ++iterator) {\n        if (iterator->hash == key_hash && iterator->first == key) {\n          this->data.erase(iterator);\n          return current_size - 1;\n        }\n      }\n    }\n\n    return current_size;\n  }\n\n  /// Erase an object property\n  inline auto erase(const Key &key) -> size_type {\n    return this->erase(key, this->hash(key));\n  }\n\n  /// Erase an object property\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, KeyView>\n  inline auto erase(T key) -> size_type {\n    return this->erase(key, this->hash(key));\n  }\n\n  /// Reorder object properties by keys according to a comparator function\n  template <typename Compare> auto reorder(const Compare &compare) -> void {\n    std::sort(this->data.begin(), this->data.end(),\n              [&compare](const auto &left, const auto &right) {\n                return compare(left.first, right.first);\n              });\n  }\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  static constexpr Hash hasher{};\n  underlying_type data;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/include/sourcemeta/core/json_value.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_VALUE_H_\n#define SOURCEMETA_CORE_JSON_VALUE_H_\n\n#ifndef SOURCEMETA_CORE_JSON_EXPORT\n#include <sourcemeta/core/json_export.h>\n#endif\n\n#include <sourcemeta/core/json_array.h>\n#include <sourcemeta/core/json_hash.h>\n#include <sourcemeta/core/json_object.h>\n\n#include <sourcemeta/core/numeric.h>\n#include <sourcemeta/core/preprocessor.h>\n\n#include <algorithm>        // std::any_of\n#include <bitset>           // std::bitset\n#include <cassert>          // assert\n#include <cmath>            // std::modf, std::trunc, std::isinf, std::isnan\n#include <concepts>         // std::same_as\n#include <cstddef>          // std::size_t\n#include <cstdint>          // std::int64_t, std::uint8_t\n#include <functional>       // std::less, std::reference_wrapper, std::function\n#include <initializer_list> // std::initializer_list\n#include <memory>           // std::allocator\n#include <set>              // std::set\n#include <sstream>          // std::basic_istringstream\n#include <string>           // std::basic_string, std::char_traits\n#include <string_view>      // std::basic_string_view\n#include <type_traits>      // std::is_same_v, std::remove_cvref_t\n#include <utility>          // std::pair\n\nnamespace sourcemeta::core {\n\n/// @ingroup json\nclass SOURCEMETA_CORE_JSON_EXPORT JSON {\npublic:\n  /// The character type used by the JSON document.\n  using Char = char;\n  /// The character traits used by the JSON document.\n  using CharTraits = std::char_traits<Char>;\n  /// The integer type used by the JSON document.\n  using Integer = std::int64_t;\n  /// The real type used by the JSON document.\n  using Real = double;\n  /// The allocator used by the JSON document.\n  template <typename T> using Allocator = std::allocator<T>;\n  /// The string type used by the JSON document.\n  using String = std::basic_string<Char, CharTraits, Allocator<Char>>;\n  /// The string view type used by the JSON document.\n  using StringView = std::basic_string_view<Char, CharTraits>;\n  /// The array type used by the JSON document.\n  using Array = JSONArray<JSON>;\n  /// The object type used by the JSON document.\n  using Object = JSONObject<String, JSON, PropertyHashJSON<JSON::String>>;\n  /// The parsing phase of a JSON document.\n  enum class ParsePhase : std::uint8_t { Pre, Post };\n\n  // The enumeration indexes must stay in sync with the internal variant\n  /// The different types of a JSON instance.\n  enum class Type : std::uint8_t {\n    Null = 0,\n    Boolean = 1,\n    Integer = 2,\n    Real = 3,\n    String = 4,\n    Array = 5,\n    Object = 6,\n    Decimal = 7\n  };\n\n  /// A set of types\n  using TypeSet = std::bitset<8>;\n\n  /// The context type for parse callbacks\n  enum class ParseContext : std::uint8_t { Root, Property, Index };\n\n  /// An optional callback that can be passed to parsing functions to obtain\n  /// metadata during the parsing process\n  using ParseCallback = std::function<void(\n      const ParsePhase phase, const Type type, const std::uint64_t line,\n      const std::uint64_t column, const ParseContext context,\n      const std::size_t index, const String &property)>;\n\n  /// A comparison function between object property keys.\n  /// See https://en.cppreference.com/w/cpp/named_req/Compare\n  using KeyComparison = std::function<bool(const String &, const String &)>;\n\n  /*\n    Constructors\n   */\n\n  /// This constructor creates a JSON document from an integer type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_integer{4};\n  /// ```\n  explicit JSON(const std::int64_t value);\n\n  /// This constructor creates a JSON document from an integer type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_integer{4};\n  /// ```\n  explicit JSON(const std::size_t value);\n\n  /// This constructor creates a JSON document from an integer type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_integer{4};\n  /// ```\n  explicit JSON(const int value);\n\n  // On some systems, `std::int64_t` might be equal to `long`\n  template <typename T = std::int64_t>\n  explicit JSON(const long value)\n    requires(!std::is_same_v<T, std::int64_t>)\n      : current_type{Type::Integer} {\n    this->data_integer = value;\n  }\n\n  /// This constructor creates a JSON document from an real number type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_real{3.14};\n  /// ```\n  explicit JSON(const double value);\n\n  /// This constructor creates a JSON document from an real number type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_real{3.14};\n  /// ```\n  explicit JSON(const float value);\n\n  /// This constructor creates a JSON document from a boolean type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_boolean{true};\n  /// ```\n  explicit JSON(const bool value);\n\n  /// This constructor creates a JSON document from a null type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_null{nullptr};\n  /// ```\n  explicit JSON(const std::nullptr_t);\n\n  /// This constructor creates a JSON document from a string type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_string{\"foo\"};\n  /// ```\n  explicit JSON(const String &value);\n\n  /// This constructor creates a JSON document from a string type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_string{\"foo\"};\n  /// ```\n  explicit JSON(const std::basic_string_view<Char, CharTraits> &value);\n\n  /// This constructor creates a JSON document from a string type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  ///\n  /// const sourcemeta::core::JSON my_string{\"foo\"};\n  /// ```\n  explicit JSON(const Char *const value);\n\n  /// This constructor creates a JSON array from a set of other JSON documents.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_array{\n  ///   sourcemeta::core::JSON{1},\n  ///   sourcemeta::core::JSON{2},\n  ///   sourcemeta::core::JSON{3}};\n  ///\n  /// assert(my_array.is_array());\n  /// ```\n  explicit JSON(std::initializer_list<JSON> values);\n\n  /// A copy constructor for the array type.\n  explicit JSON(const Array &value);\n\n  /// This constructor creates a JSON object from a pair of other JSON\n  /// documents. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object{\n  ///   {\"foo\", sourcemeta::core::JSON{1}},\n  ///   {\"bar\", sourcemeta::core::JSON{1}},\n  ///   {\"baz\", sourcemeta::core::JSON{1}}};\n  ///\n  /// assert(my_object.is_object());\n  /// ```\n  explicit JSON(std::initializer_list<typename Object::pair_value_type> values);\n\n  /// A copy constructor for the object type.\n  explicit JSON(const Object &value);\n\n  /// A copy constructor for the decimal type.\n  explicit JSON(const Decimal &value);\n\n  /// A move constructor for the decimal type.\n  explicit JSON(Decimal &&value);\n\n  /// Misc constructors\n  JSON(const JSON &);\n  JSON(JSON &&) noexcept;\n  auto operator=(const JSON &) -> JSON &;\n  auto operator=(JSON &&) noexcept -> JSON &;\n\n  /// Destructor\n  ~JSON();\n\n  /// This function creates an empty JSON array. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_array();\n  /// assert(document.is_array());\n  /// assert(document.empty());\n  /// ```\n  ///\n  /// This function is particularly handy for programatically constructing\n  /// arrays.\n  static auto make_array() -> JSON;\n\n  /// This function creates an empty JSON object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// assert(document.is_object());\n  /// assert(document.empty());\n  /// ```\n  ///\n  /// This function is particularly handy for programatically constructing\n  /// objects.\n  static auto make_object() -> JSON;\n\n  /// This function calculates the logical size of a string according to the\n  /// JSON specification. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON::String value{\"foo\"};\n  /// assert(sourcemeta::core::JSON::size(value) == 3);\n  /// ```\n  static auto size(const String &value) noexcept -> std::size_t;\n\n  /*\n   * Operators\n   */\n\n  auto operator<(const JSON &other) const noexcept -> bool;\n  auto operator<=(const JSON &other) const noexcept -> bool;\n  auto operator>(const JSON &other) const noexcept -> bool;\n  auto operator>=(const JSON &other) const noexcept -> bool;\n  auto operator==(const JSON &other) const noexcept -> bool;\n  auto operator!=(const JSON &) const noexcept -> bool = default;\n\n  /// Add two numeric JSON instances and get a new instance with the result. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON left{5};\n  /// const sourcemeta::core::JSON right{3};\n  /// const sourcemeta::core::JSON result{left + right};\n  /// assert(result.is_integer());\n  /// assert(document.to_integer() == 8);\n  /// ```\n  auto operator+(const JSON &other) const -> JSON;\n\n  /// Substract two numeric JSON instances and get a new instance with the\n  /// result. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON left{5};\n  /// const sourcemeta::core::JSON right{3};\n  /// const sourcemeta::core::JSON result{left - right};\n  /// assert(result.is_integer());\n  /// assert(document.to_integer() == 2);\n  /// ```\n  auto operator-(const JSON &other) const -> JSON;\n\n  /// This operator adds a numeric JSON instance to another numeric JSON\n  /// instance. For example, a numeric JSON instance 3.2 can be added to a\n  /// numeric JSON instance 5 as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document{5};\n  /// const sourcemeta::core::JSON additive{3.2};\n  /// document += additive;\n  /// assert(document.is_real());\n  /// assert(document.to_real() == 8.2);\n  /// ```\n  auto operator+=(const JSON &additive) -> JSON &;\n\n  /// This operator substracts a numeric JSON instance from another numeric JSON\n  /// instance. For example, a numeric JSON instance 3.2 can be substracted from\n  /// a numeric JSON instance 5 as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document{5};\n  /// const sourcemeta::core::JSON substractive{3.2};\n  /// document -= substractive;\n  /// assert(document.is_real());\n  /// assert(document.to_real() == 1.8);\n  /// ```\n  auto operator-=(const JSON &substractive) -> JSON &;\n\n  /*\n   * Type checking\n   */\n\n  /// Check if the input JSON document is a boolean. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{true};\n  /// assert(document.is_boolean());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_boolean() const noexcept\n      -> bool {\n    return this->current_type == Type::Boolean;\n  }\n\n  /// Check if the input JSON document is null. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{nullptr};\n  /// assert(document.is_null());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_null() const noexcept\n      -> bool {\n    return this->current_type == Type::Null;\n  }\n\n  /// Check if the input JSON document is an integer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{5};\n  /// assert(document.is_integer());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_integer() const noexcept\n      -> bool {\n    return this->current_type == Type::Integer;\n  }\n\n  /// Check if the input JSON document is a real type. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{3.14};\n  /// assert(document.is_real());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_real() const noexcept\n      -> bool {\n    return this->current_type == Type::Real;\n  }\n\n  /// Check if the input JSON document is an integer, a real number that\n  /// represents an integer, or an integer decimal. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{5.0};\n  /// assert(document.is_integral());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_integral() const noexcept\n      -> bool {\n    switch (this->type()) {\n      case Type::Integer:\n        return true;\n      case Type::Real: {\n        Real integral_part = 0.0;\n        return std::modf(this->to_real(), &integral_part) == 0.0;\n      }\n      case Type::Decimal:\n        return this->to_decimal().is_integral();\n      default:\n        return false;\n    }\n  }\n\n  /// Check if the input JSON document is either an integer or a real type. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON real{3.14};\n  /// const sourcemeta::core::JSON integer{5};\n  /// assert(real.is_number());\n  /// assert(integer.is_number());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_number() const noexcept\n      -> bool {\n    return this->is_integer() || this->is_real() || this->is_decimal();\n  }\n\n  /// Check if the input JSON document is either a positive integer or a\n  /// positive real number. Zero is considered to be positive. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON real{3.14};\n  /// const sourcemeta::core::JSON integer{-5};\n  /// assert(real.is_positive());\n  /// assert(!integer.is_positive());\n  /// ```\n  [[nodiscard]] auto is_positive() const noexcept -> bool;\n\n  /// Check if the input JSON document is a string. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\"foo\"};\n  /// assert(document.is_string());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_string() const noexcept\n      -> bool {\n    return this->current_type == Type::String;\n  }\n\n  /// Check if the input JSON document is an array. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON\n  /// document=sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.is_array());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_array() const noexcept\n      -> bool {\n    return this->current_type == Type::Array;\n  }\n\n  /// Check if the input JSON document is an object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON\n  /// document=sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// assert(document.is_object());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_object() const noexcept\n      -> bool {\n    return this->current_type == Type::Object;\n  }\n\n  /// Check if the input JSON document is an arbitrary precision decimal value.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Decimal value{1234567890};\n  /// const sourcemeta::core::JSON document{value};\n  /// assert(document.is_decimal());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_decimal() const noexcept\n      -> bool {\n    return this->current_type == Type::Decimal;\n  }\n\n  /// Get the type of the JSON document. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{true};\n  /// assert(document.type() == sourcemeta::core::JSON::Type::Boolean);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto type() const noexcept\n      -> Type {\n    return this->current_type;\n  }\n\n  /*\n   * Type conversion\n   */\n\n  /// Convert a JSON instance into a boolean value. The result of this method is\n  /// undefined unless the JSON instance holds a boolean value. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{true};\n  /// assert(document.is_boolean());\n  /// assert(document.to_boolean());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto to_boolean() const noexcept\n      -> bool {\n    assert(this->is_boolean());\n    return this->data_boolean;\n  }\n\n  /// Convert a JSON instance into a signed integer value. The result of this\n  /// method is undefined unless the JSON instance holds an integer value. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{5};\n  /// assert(document.is_integer());\n  /// assert(document.to_integer() == 5);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto to_integer() const noexcept\n      -> Integer {\n    assert(this->is_integer());\n    return this->data_integer;\n  }\n\n  /// Convert a JSON instance into an IEEE 64-bit floating-point value. The\n  /// result of this method is undefined unless the JSON instance holds a real\n  /// value. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{3.14};\n  /// assert(document.is_real());\n  /// assert(document.to_real() == 3.14);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto to_real() const noexcept\n      -> Real {\n    assert(this->is_real());\n    assert(!std::isinf(this->data_real));\n    assert(!std::isnan(this->data_real));\n    return this->data_real;\n  }\n\n  /// Convert a JSON instance into a decimal value. The result of this method\n  /// is undefined unless the JSON instance holds a decimal value. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Decimal value{1234567890};\n  /// const sourcemeta::core::JSON document{value};\n  /// assert(document.is_decimal());\n  /// assert(document.to_decimal().to_int64() == 1234567890);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto to_decimal() const noexcept\n      -> const Decimal & {\n    assert(this->is_decimal());\n    assert(this->data_decimal->is_finite());\n    assert(!this->data_decimal->is_nan());\n    return *this->data_decimal;\n  }\n\n  /// Convert a JSON instance into a standard string value. The result of this\n  /// method is undefined unless the JSON instance holds a string value. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\"foo\"};\n  /// assert(document.is_string());\n  /// assert(document.to_string() == \"foo\");\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto to_string() const noexcept\n      -> const String & {\n    assert(this->is_string());\n    return this->data_string;\n  }\n\n  /// Get a standard input string stream from a JSON string. The result of this\n  /// method is undefined unless the JSON instance holds a string value. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\"foo\"};\n  /// assert(document.is_string());\n  /// auto stream{document.to_stringstream()};\n  /// assert(stream.get() == 'f');\n  /// ```\n  [[nodiscard]] auto to_stringstream() const\n      -> std::basic_istringstream<Char, CharTraits, Allocator<Char>>;\n\n  /// Get the JSON document as an array instance. This is convenient\n  /// for using constant iterators on the array. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <algorithm>\n  /// #include <iostream>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// std::for_each(document.as_array().cbegin(),\n  ///               document.as_array().cend(),\n  ///               [](const auto &element) {\n  ///                 std::cout << \"Element: \"\n  ///                           << element.to_integer()\n  ///                           << \"\\n\";\n  ///               });\n  /// ```\n  // TODO: Merge const/non-const overloads of as_array, as_object, at, front,\n  // back using deducing this once Apple Clang supports it\n  // (__cpp_explicit_this_parameter)\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_array() const noexcept\n      -> const Array & {\n    assert(this->is_array());\n    return this->data_array;\n  }\n\n  /// Get the JSON document as an array instance. This is convenient\n  /// for using mutable iterators on the array. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <algorithm>\n  /// #include <iostream>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// std::sort(document.as_array().begin(), document.as_array().end());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_array() noexcept\n      -> Array & {\n    assert(this->is_array());\n    return this->data_array;\n  }\n\n  /// Get the JSON document as an object instance. This is convenient\n  /// for using constant iterators on the object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <algorithm>\n  /// #include <iostream>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{1});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{2});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{3});\n  ///\n  /// std::for_each(document.as_object().cbegin(),\n  ///               document.as_object().cend(),\n  ///               [](const auto &pair) {\n  ///                 std::cout << \"Value: \"\n  ///                           << pair.second.to_integer()\n  ///                           << \"\\n\";\n  ///               });\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_object() noexcept\n      -> Object & {\n    assert(this->is_object());\n    return this->data_object;\n  }\n\n  /// Get the JSON document as an object instance. This is convenient\n  /// for using mutable iterators on the object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <algorithm>\n  /// #include <iostream>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{1});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{2});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{3});\n  ///\n  /// for (auto &[key, value] : document.as_object()) {\n  ///   value += sourcemeta::core::JSON{1};\n  /// }\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_object() const noexcept\n      -> const Object & {\n    assert(this->is_object());\n    return this->data_object;\n  }\n\n  /// Get the JSON numeric document as a real number if it is not one already.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{5};\n  /// assert(document.as_real() == 5.0);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_real() const noexcept\n      -> Real {\n    assert(this->is_number());\n    return this->is_real() ? this->to_real()\n                           : static_cast<Real>(this->to_integer());\n  }\n\n  /// Get the JSON numeric document as an integer number if it is not one\n  /// already. If the number is a real number, truncation will take place. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{5.3};\n  /// assert(document.as_integer() == 5);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto as_integer() const noexcept\n      -> Integer {\n    assert(this->is_number());\n    if (this->is_integer()) {\n      return this->to_integer();\n    } else {\n      return static_cast<Integer>(std::trunc(this->to_real()));\n    }\n  }\n\n  /*\n   * Getters\n   */\n\n  /// This method retrieves a element by its index. If the input JSON instance\n  /// is an object, a property that corresponds to the stringified integer will\n  /// be accessed.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2 ]\");\n  /// assert(my_array.at(1).to_integer() == 2);\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"1\\\": \"foo\" }\");\n  /// assert(my_array.at(1).to_string() == \"foo\");\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(const typename Array::size_type index) const -> const JSON & {\n    assert(this->is_array());\n    assert(index < this->size());\n    return this->data_array.data.at(index);\n  }\n\n  /// This method retrieves a element by its index. If the input JSON instance\n  /// is an object, a property that corresponds to the stringified integer will\n  /// be accessed.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2 ]\");\n  /// assert(my_array.at(1).to_integer() == 2);\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"1\\\": \"foo\" }\");\n  /// assert(my_array.at(1).to_string() == \"foo\");\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(const typename Array::size_type index) -> JSON & {\n    assert(this->is_array());\n    assert(index < this->size());\n    return this->data_array.data.at(index);\n  }\n\n  /// This method retrieves an object element.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// assert(my_object.at(\"bar\").to_integer() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto at(const String &key) const\n      -> const JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    const auto &object{this->data_object};\n    return object.at(key, object.hash(key));\n  }\n\n  /// This method retrieves an object element by string view key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto at(T key) const\n      -> const JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    const auto &object{this->data_object};\n    return object.at(key, object.hash(key));\n  }\n\n  /// This method retrieves an object element given a pre-calculated property\n  /// hash.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// assert(my_object.at(\"bar\",\n  ///  my_object.as_object().hash(\"bar\")).to_integer() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(const String &key, const typename Object::hash_type hash) const\n      -> const JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    return this->data_object.at(key, hash);\n  }\n\n  /// This method retrieves an object element by string view key given a\n  /// pre-calculated property hash\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(T key, const typename Object::hash_type hash) const -> const JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    return this->data_object.at(key, hash);\n  }\n\n  /// This method retrieves an object element.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// assert(my_object.at(\"bar\").to_integer() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto at(const String &key)\n      -> JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    auto &object{this->data_object};\n    return object.at(key, object.hash(key));\n  }\n\n  /// This method retrieves an object element by string view key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto at(T key) -> JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    auto &object{this->data_object};\n    return object.at(key, object.hash(key));\n  }\n\n  /// This method retrieves an object element given a pre-calculated property\n  /// hash.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// assert(my_object.at(\"bar\",\n  ///   my_object.as_object().hash(\"bar\")).to_integer() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(const String &key, const typename Object::hash_type hash) -> JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    return this->data_object.at(key, hash);\n  }\n\n  /// This method retrieves an object element by string view key given a\n  /// pre-calculated property hash\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  at(T key, const typename Object::hash_type hash) -> JSON & {\n    assert(this->is_object());\n    assert(this->defines(key));\n    return this->data_object.at(key, hash);\n  }\n\n  /// This method retrieves an object property or a user provided value if such\n  /// property is not defined.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// const sourcemeta::core::JSON default_value{3};\n  /// assert(my_object.at_or(\"baz\", default_value).to_integer() == 3);\n  /// ```\n  [[nodiscard]] auto at_or(const String &key, const JSON &otherwise) const\n      -> const JSON &;\n\n  /// This method retrieves an object property given a pre-calculated property\n  /// hash, or a user provided value if such property is not defined.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// const sourcemeta::core::JSON default_value{3};\n  /// assert(my_object.at_or(\"foo\",\n  ///   my_object.as_object().hash(\"foo\"),\n  ///   default_value).to_integer() == 1);\n  /// ```\n  [[nodiscard]] auto at_or(const String &key,\n                           const typename Object::hash_type hash,\n                           const JSON &otherwise) const -> const JSON &;\n\n  // Constant reference parameters can accept xvalues which will be destructed\n  // after the call. When the function returns such a parameter also as constant\n  // reference, then the returned reference can be used after the object it\n  // refers to has been destroyed.\n  // https://clang.llvm.org/extra/clang-tidy/checks/bugprone/return-const-ref-from-parameter.html\n  // This overload avoids mis-uses of retuning const reference parameter as\n  // constant reference.\n  [[nodiscard]] auto at_or(const String &key,\n                           const typename Object::hash_type hash,\n                           JSON &&otherwise) const -> const JSON & = delete;\n\n  /// This method retrieves a reference to the first element of a JSON array.\n  /// This method is undefined if the input JSON instance is an empty array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.front().to_integer() == 1);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto front() -> JSON & {\n    assert(this->is_array());\n    assert(!this->empty());\n    return this->data_array.data.front();\n  }\n\n  /// This method retrieves a reference to the first element of a JSON array.\n  /// This method is undefined if the input JSON instance is an empty array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.front().to_integer() == 1);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto front() const\n      -> const JSON & {\n    assert(this->is_array());\n    assert(!this->empty());\n    return this->data_array.data.front();\n  }\n\n  /// This method retrieves a reference to the last element of a JSON array.\n  /// This method is undefined if the input JSON instance is an empty array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.back().to_integer() == 3);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto back() -> JSON & {\n    assert(this->is_array());\n    assert(!this->empty());\n    return this->data_array.data.back();\n  }\n\n  /// This method retrieves a reference to the last element of a JSON array.\n  /// This method is undefined if the input JSON instance is an empty array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.back().to_integer() == 3);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto back() const\n      -> const JSON & {\n    assert(this->is_array());\n    assert(!this->empty());\n    return this->data_array.data.back();\n  }\n\n  /*\n   * Read operations\n   */\n\n  /// If the input JSON instance is an object, return its number of pairs. If\n  /// the input JSON instance is an array, return its number of elements. If the\n  /// input JSON instance is a string, return its logical length.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// const sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2 ]\");\n  /// const sourcemeta::core::JSON my_string{\"foo\"};\n  ///\n  /// assert(my_object.size() == 1);\n  /// assert(my_array.size() == 2);\n  /// assert(my_string.size() == 3);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto size() const -> std::size_t {\n    if (this->is_object()) {\n      return this->object_size();\n    } else if (this->is_array()) {\n      return this->array_size();\n    } else {\n      return this->string_size();\n    }\n  }\n\n  /// If the input JSON instance is a string, return its logical length.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_string{\"foo\"};\n  /// assert(my_string.string_size() == 3);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto string_size() const\n      -> std::size_t {\n    assert(this->is_string());\n    return JSON::size(this->data_string);\n  }\n\n  /// If the input JSON instance is an array, return its number of elements.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2 ]\");\n  /// assert(my_array.array_size() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto array_size() const\n      -> std::size_t {\n    assert(this->is_array());\n    return this->data_array.data.size();\n  }\n\n  /// If the input JSON instance is an object, return its number of pairs.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// assert(my_object.object_size() == 1);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto object_size() const\n      -> std::size_t {\n    assert(this->is_object());\n    return this->data_object.size();\n  }\n\n  /// If the input JSON instance is string, input JSON instance is a string,\n  /// return its number of bytes. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_string{\n  ///   sourcemeta::core::parse_json(\"\\\"\\\\uD83D\\\\uDCA9\\\"\")};\n  /// assert(my_string.size() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto byte_size() const\n      -> std::size_t {\n    assert(this->is_string());\n    return this->data_string.size();\n  }\n\n  /// Estimate the byte size occupied by the given parsed JSON instance (not its\n  /// stringified representation). Keep in mind that as the method name implies,\n  /// this is just a rough estimate. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON value =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  ///\n  /// // Byte length of \"foo\" (3) + byte length of 1 (8)\n  /// assert(value.estimated_byte_size() == 11);\n  /// ```\n  [[nodiscard]] auto estimated_byte_size() const -> std::uint64_t;\n\n  /// Produce a simple hash for the JSON value. Note the hash is fast to produce\n  /// but might have a higher chance of collisions. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON value_1 =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  ///\n  /// const sourcemeta::core::JSON value_2 =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  ///\n  /// assert(value_1.fast_hash() == value_2.fast_hash());\n  /// ```\n  [[nodiscard]] auto fast_hash() const -> std::uint64_t;\n\n  /// Check whether a numeric instance is divisible by another numeric instance.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON dividend{6};\n  /// const sourcemeta::core::JSON divisor{1.5};\n  ///\n  /// assert(dividend.divisible_by(divisor));\n  /// ```\n  [[nodiscard]] auto divisible_by(const JSON &divisor) const -> bool;\n\n  /// A convenience method to check whether the input JSON document is an empty\n  /// object, empty array or empty string.\n  ///\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{}\");\n  /// const sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[]\");\n  /// const sourcemeta::core::JSON my_string{\"\"};\n  ///\n  /// assert(my_object.empty());\n  /// assert(my_array.empty());\n  /// assert(my_string.empty());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto empty() const -> bool {\n    if (this->is_object()) {\n      return this->data_object.empty();\n    } else if (this->is_array()) {\n      return this->data_array.data.empty();\n    } else {\n      return this->data_string.empty();\n    }\n  }\n\n  /// This method checks whether an input JSON object defines a specific key\n  /// and returns the value if it does. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// EXPECT_TRUE(document.is_object());\n  /// const auto result = document.try_at(\"foo\");\n  /// EXPECT_TRUE(result);\n  /// EXPECT_EQ(result->to_integer(), 1);\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  try_at(const String &key) const -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, object.hash(key));\n  }\n\n  /// This method tries to retrieve an object element by string view key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto try_at(T key) const\n      -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, object.hash(key));\n  }\n\n  /// This method checks, given a pre-calculated hash, whether an input JSON\n  /// object defines a specific key and returns the value if it does. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// EXPECT_TRUE(document.is_object());\n  /// const auto result = document.try_at(\"foo\",\n  ///   document.as_object().hash(\"foo\"));\n  /// EXPECT_TRUE(result);\n  /// EXPECT_EQ(result->to_integer(), 1);\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  try_at(const String &key, const typename Object::hash_type hash) const\n      -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, hash);\n  }\n\n  /// This method tries to retrieve an object element by string view key given a\n  /// pre-calculated property hash\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  try_at(T key, const typename Object::hash_type hash) const -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, hash);\n  }\n\n  /// Try to get a property, scanning from a caller-provided start offset.\n  /// On hit, advances `start` past the found index. When looking up multiple\n  /// keys in insertion order, each lookup hits on the first probe, making the\n  /// total work O(N) instead of O(N^2). For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1, \\\"bar\\\": 2 }\");\n  /// const auto &object{document.as_object()};\n  /// typename decltype(object)::size_type start{0};\n  ///\n  /// const auto hash_foo{object.hash(\"foo\")};\n  /// const auto *foo{document.try_at(\"foo\", hash_foo, start)};\n  /// assert(foo);\n  /// assert(foo->to_integer() == 1);\n  ///\n  /// const auto hash_bar{object.hash(\"bar\")};\n  /// const auto *bar{document.try_at(\"bar\", hash_bar, start)};\n  /// assert(bar);\n  /// assert(bar->to_integer() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  try_at(const String &key, const typename Object::hash_type hash,\n         typename Object::size_type &start) const -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, hash, start);\n  }\n\n  /// This method tries to retrieve an object element by string view key,\n  /// scanning from a caller-provided start offset\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  try_at(T key, const typename Object::hash_type hash,\n         typename Object::size_type &start) const -> const JSON * {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.try_at(key, hash, start);\n  }\n\n  /// This method checks whether an input JSON object defines a specific key.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// assert(document.defines(\"foo\"));\n  /// assert(!document.defines(\"bar\"));\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  defines(const String &key) const -> bool {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.defines(key, object.hash(key));\n  }\n\n  /// This method checks whether an input JSON object defines a specific\n  /// string view key\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto defines(T key) const\n      -> bool {\n    assert(this->is_object());\n    const auto &object{this->data_object};\n    return object.defines(key, object.hash(key));\n  }\n\n  /// This method checks whether an input JSON object defines a specific key\n  /// given a pre-calculated property hash. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": 1 }\");\n  /// assert(document.defines(\"foo\",\n  ///   document.as_object().hash(\"foo\")));\n  /// assert(document.defines(\"bar\",\n  ///   document.as_object().hash(\"bar\")));\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  defines(const String &key, const typename Object::hash_type hash) const\n      -> bool {\n    assert(this->is_object());\n    return this->data_object.defines(key, hash);\n  }\n\n  /// This method checks whether an input JSON object defines a specific\n  /// string view key given a pre-calculated property hash\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  defines(T key, const typename Object::hash_type hash) const -> bool {\n    assert(this->is_object());\n    return this->data_object.defines(key, hash);\n  }\n\n  /// This method checks whether an input JSON object defines a specific integer\n  /// key. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"0\\\": 1 }\");\n  /// assert(document.defines(0));\n  /// assert(!document.defines(1));\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto\n  defines(const typename Array::size_type index) const -> bool {\n    return this->defines(std::to_string(index));\n  }\n\n  /// This method checks whether an input JSON object defines at least one given\n  /// key.\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <string>\n  /// #include <vector>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true, \\\"bar\\\": false }\");\n  ///\n  /// const std::vector<std::string> keys{\"foo\", \"qux\"};\n  /// assert(document.defines_any(keys.cbegin(), keys.cend()));\n  /// ```\n  template <typename Iterator>\n  [[nodiscard]] auto defines_any(Iterator begin, Iterator end) const -> bool {\n    assert(this->is_object());\n    return std::any_of(begin, end,\n                       [this](const auto &key) { return this->defines(key); });\n  }\n\n  /// This method checks whether an input JSON object defines at least one given\n  /// key.\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true, \\\"bar\\\": false }\");\n  ///\n  /// assert(document.defines_any({ \"foo\", \"qux\" }));\n  /// ```\n  [[nodiscard]] auto defines_any(std::initializer_list<String> keys) const\n      -> bool;\n\n  /// This method checks if a JSON array contains a given JSON instance. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.contains(sourcemeta::core::JSON{2}));\n  /// assert(!document.contains(sourcemeta::core::JSON{4}));\n  /// ```\n  [[nodiscard]] auto contains(const JSON &element) const -> bool;\n\n  /// This method checks if a JSON array contains a given string. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(R\"JSON([ \"foo\", \"bar\", \"baz\" ])JSON\");\n  /// assert(document.contains(\"bar\"));\n  /// assert(!document.contains(\"qux\"));\n  /// ```\n  [[nodiscard]] auto contains(const StringView element) const -> bool;\n\n  /// This method checks if a JSON string includes a given substring. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\"foo bar baz\"};\n  /// assert(document.includes(\"bar\"));\n  /// assert(!document.includes(\"qux\"));\n  /// ```\n  [[nodiscard]] auto includes(const String &input) const -> bool;\n\n  /// This method checks if a JSON string includes a given character. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\"foo\"};\n  /// assert(document.includes('f'));\n  /// assert(!document.includes('b'));\n  /// ```\n  [[nodiscard]] auto includes(const String::value_type input) const -> bool;\n\n  /// This method checks if an JSON array does not contain duplicated items. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// assert(document.unique());\n  /// ```\n  [[nodiscard]] auto unique() const -> bool;\n\n  /*\n   * Write operations\n   */\n\n  /// This method inserts a new element to the end of the given array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// const sourcemeta::core::JSON value{4};\n  /// document.push_back(value);\n  /// assert(document.size() == 4);\n  /// assert(document.back().to_integer() == 4);\n  /// ```\n  auto push_back(const JSON &value) -> void;\n\n  /// This method inserts a new element to the end of the given array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// document.push_back(sourcemeta::core::JSON{4});\n  /// assert(document.size() == 4);\n  /// assert(document.back().to_integer() == 4);\n  /// ```\n  auto push_back(JSON &&value) -> void;\n\n  /// This method inserts a new element to the end of the given array if an\n  /// equal element is not already present in the array. The return value is a\n  /// pair consisting of a reference to the element in question and whether the\n  /// element was inserted or not. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// const sourcemeta::core::JSON new_element{3};\n  /// const auto result{document.push_back_if_unique(new_element)};\n  /// assert(result.first.get().to_integer() == 3);\n  /// assert(!result.second);\n  /// ```\n  auto push_back_if_unique(const JSON &value)\n      -> std::pair<std::reference_wrapper<const JSON>, bool>;\n\n  /// This method inserts a new element to the end of the given array if an\n  /// equal element is not already present in the array. The return value is a\n  /// pair consisting of a reference to the element in question and whether the\n  /// element was inserted or not. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <utility>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// sourcemeta::core::JSON new_element{3};\n  /// const auto result{document.push_back_if_unique(std::move(new_element)};\n  /// assert(result.first.get().to_integer() == 3);\n  /// assert(!result.second);\n  /// ```\n  auto push_back_if_unique(JSON &&value)\n      -> std::pair<std::reference_wrapper<const JSON>, bool>;\n\n  /// This method sets or updates an object key. For example, an object can be\n  /// updated to contain a new `bar` boolean member as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// const sourcemeta::core::JSON value{false};\n  /// document.assign(\"bar\", value);\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.defines(\"bar\"));\n  /// ```\n  auto assign(const String &key, const JSON &value) -> void;\n\n  /// This method sets or updates an object key by string view. The key is\n  /// copied into a stored string exactly once.\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  auto assign(T key, const JSON &value) -> void {\n    assert(this->is_object());\n    this->data_object.emplace(String{key}, value);\n  }\n\n  /// This method sets or updates an object key. For example, an object can be\n  /// updated to contain a new `bar` boolean member as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// document.assign(\"bar\", sourcemeta::core::JSON{false});\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.defines(\"bar\"));\n  /// ```\n  auto assign(const String &key, JSON &&value) -> void;\n\n  /// This method sets or updates an object key by string view. The key is\n  /// copied into a stored string exactly once.\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  auto assign(T key, JSON &&value) -> void {\n    assert(this->is_object());\n    this->data_object.emplace(String{key}, std::move(value));\n  }\n\n  /// This method sets or updates an object key. However, it will try to insert\n  /// the key _before_ the given one if possible.\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// const sourcemeta::core::JSON value{false};\n  /// document.try_assign_before(\"bar\", value, \"foo\");\n  /// assert(document.as_object().cbegin()->first == \"bar\");\n  /// ```\n  auto try_assign_before(const String &key, const JSON &value,\n                         const String &other) -> void;\n\n  /// This method sets an object key if it is not already defined. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  ///\n  /// const sourcemeta::core::JSON value_1{1};\n  /// const sourcemeta::core::JSON value_2{2};\n  ///\n  /// document.assign_if_missing(\"foo\", value_1);\n  /// document.assign_if_missing(\"bar\", value_2);\n  ///\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.at(\"foo\").is_boolean());\n  /// assert(document.defines(\"bar\"));\n  /// assert(document.at(\"bar\").is_integer());\n  /// ```\n  auto assign_if_missing(const String &key, const JSON &value) -> void;\n\n  /// This method sets an object key by string view if it is not already\n  /// defined.\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  auto assign_if_missing(T key, const JSON &value) -> void {\n    assert(this->is_object());\n    if (!this->defines(key)) {\n      this->assign(key, value);\n    }\n  }\n\n  /// This method sets an object key if it is not already defined. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  ///\n  /// document.assign_if_missing(\"foo\", sourcemeta::core::JSON{1});\n  /// document.assign_if_missing(\"bar\", sourcemeta::core::JSON{2});\n  ///\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.at(\"foo\").is_boolean());\n  /// assert(document.defines(\"bar\"));\n  /// assert(document.at(\"bar\").is_integer());\n  /// ```\n  auto assign_if_missing(const String &key, JSON &&value) -> void;\n\n  /// This method sets an object key by string view if it is not already\n  /// defined.\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  auto assign_if_missing(T key, JSON &&value) -> void {\n    assert(this->is_object());\n    if (!this->defines(key)) {\n      this->assign(key, std::move(value));\n    }\n  }\n\n  /// This method sets an object key, assuming the key does not already exist.\n  /// If the key already exists, behavior is undefined. This variant is faster\n  /// than `assign` when building objects with keys known to be unique. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document = sourcemeta::core::JSON::make_object();\n  /// document.assign_assume_new(\"foo\", sourcemeta::core::JSON{1});\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.at(\"foo\").to_integer() == 1);\n  /// ```\n  auto assign_assume_new(const String &key, JSON &&value) -> void;\n\n  /// This method sets an object key, assuming the key does not already exist.\n  /// If the key already exists, behavior is undefined. This variant is faster\n  /// than `assign` when building objects with keys known to be unique, and\n  /// allows moving the key. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document = sourcemeta::core::JSON::make_object();\n  /// std::string key{\"foo\"};\n  /// document.assign_assume_new(std::move(key), sourcemeta::core::JSON{1});\n  /// assert(document.defines(\"foo\"));\n  /// assert(document.at(\"foo\").to_integer() == 1);\n  /// ```\n  auto assign_assume_new(String &&key, JSON &&value) -> void;\n\n  /// This method sets an object key with a pre-computed hash\n  auto assign_assume_new(String &&key, JSON &&value, Object::hash_type hash)\n      -> void;\n\n  /// This method deletes an object key. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// document.erase(\"foo\");\n  /// assert(!document.defines(\"foo\"));\n  /// ```\n  auto erase(const String &key) -> typename Object::size_type;\n\n  /// This method deletes an object key by string view.\n  template <typename T>\n    requires std::same_as<std::remove_cvref_t<T>, StringView>\n  auto erase(T key) -> typename Object::size_type {\n    assert(this->is_object());\n    return this->data_object.erase(key);\n  }\n\n  /// This method deletes a set of object keys. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <string>\n  /// #include <vector>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{true});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{false});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{true});\n  ///\n  /// const std::vector<std::string> keys{\"foo\", \"bar\"};\n  /// document.erase_keys(keys.cbegin(), keys.cend());\n  ///\n  /// assert(!document.defines(\"foo\"));\n  /// assert(!document.defines(\"bar\"));\n  /// assert(document.defines(\"baz\"));\n  /// ```\n  template <typename Iterator>\n  auto erase_keys(Iterator first, Iterator last) -> void {\n    assert(this->is_object());\n    for (auto iterator = first; iterator != last; ++iterator) {\n      this->data_object.erase(*iterator);\n    }\n  }\n\n  /// This method deletes a set of object keys. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{true});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{false});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{true});\n  ///\n  /// document.erase_keys({ \"foo\", \"bar\" });\n  ///\n  /// assert(!document.defines(\"foo\"));\n  /// assert(!document.defines(\"bar\"));\n  /// assert(document.defines(\"baz\"));\n  /// ```\n  auto erase_keys(std::initializer_list<String> keys) -> void;\n\n  /// This method deletes an array element using an iterator. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <iterator>\n  ///\n  /// sourcemeta::core::JSON array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// array.erase(std::next(array.begin()));\n  /// assert(array.size(), 2);\n  /// assert(array.at(0), 1);\n  /// assert(array.at(1), 3);\n  /// ```\n  auto erase(typename Array::const_iterator position) ->\n      typename Array::iterator;\n\n  /// This method deletes a set of array elements using iterators. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <iterator>\n  ///\n  /// sourcemeta::core::JSON array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// array.erase(std::next(array.begin()), array.end());\n  /// assert(array.size(), 1);\n  /// assert(array.at(0), 1);\n  /// ```\n  auto erase(typename Array::const_iterator first,\n             typename Array::const_iterator last) -> typename Array::iterator;\n\n  /// This method deletes a set of array elements given a predicate. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// array.erase_if(array,\n  ///   [](const auto &item) { return item.to_integer() % 2 == 0; });\n  /// assert(array.size(), 2);\n  /// assert(array.at(0), 1);\n  /// assert(array.at(1), 3);\n  /// ```\n  auto erase_if(const std::function<bool(const JSON &)> &predicate) -> void;\n\n  /// This method deletes all members of an object or all elements of an array,\n  /// leaving them empty. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON my_object =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// sourcemeta::core::JSON my_array =\n  ///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n  /// my_object.clear();\n  /// my_array.clear();\n  /// assert(my_object.empty());\n  /// assert(my_array.empty());\n  /// ```\n  auto clear() -> void;\n\n  /// This method deletes all members of an object except for the JSON keys\n  /// declares as the second argument. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  /// #include <string>\n  /// #include <vector>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{true});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{false});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{true});\n  ///\n  /// const std::vector<std::string> keys{\"foo\"};\n  /// document.clear_except(keys.cbegin(), keys.cend());\n  ///\n  /// assert(document.defines(\"foo\"));\n  /// assert(!document.defines(\"bar\"));\n  /// assert(!document.defines(\"baz\"));\n  /// ```\n  template <typename Iterator>\n  auto clear_except(Iterator first, Iterator last) -> void {\n    assert(this->is_object());\n    std::set<String, std::less<>, Allocator<String>> whitelist;\n    for (auto iterator = first; iterator != last; ++iterator) {\n      whitelist.insert(*iterator);\n    }\n\n    std::set<String, std::less<>, Allocator<String>> blacklist;\n    for (const auto &pair : this->as_object()) {\n      if (!whitelist.contains(pair.first)) {\n        blacklist.insert(pair.first);\n      }\n    }\n\n    this->erase_keys(blacklist.cbegin(), blacklist.cend());\n  }\n\n  /// This method deletes all members of an object except for the JSON keys\n  /// declares as the second argument. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{true});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{false});\n  /// document.assign(\"baz\", sourcemeta::core::JSON{true});\n  ///\n  /// document.clear_except({ \"foo\" });\n  ///\n  /// assert(document.defines(\"foo\"));\n  /// assert(!document.defines(\"bar\"));\n  /// assert(!document.defines(\"baz\"));\n  /// ```\n  auto clear_except(std::initializer_list<String> keys) -> void;\n\n  /// This method assigns every property of another object into the current\n  /// object. Overriding existing properties if they are already defined. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"foo\", sourcemeta::core::JSON{1});\n  /// document.assign(\"bar\", sourcemeta::core::JSON{2});\n  ///\n  /// sourcemeta::core::JSON other =\n  ///   sourcemeta::core::JSON::make_object();\n  /// other.assign(\"bar\", sourcemeta::core::JSON{1});\n  /// other.assign(\"baz\", sourcemeta::core::JSON{2});\n  ///\n  /// document.merge(other.as_object());\n  ///\n  /// assert(document.size() == 3);\n  ///\n  /// assert(document.at(\"foo\").to_integer() == 1);\n  /// assert(document.at(\"bar\").to_integer() == 1);\n  /// assert(document.at(\"baz\").to_integer() == 2);\n  /// ```\n  auto merge(const JSON::Object &other) -> void;\n\n  /// Return a trimmed version of the string. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON document{\" \\r\\t  Hello World\\n\\v   \\f\"};\n  /// assert(document.trim() == \"Hello World\");\n  /// ```\n  [[nodiscard]] auto trim() const -> JSON::String;\n\n  /// Trim the string in-place. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document{\" \\r\\t  Hello World\\n\\v   \\f\"};\n  /// document.trim();\n  /// assert(document.to_string() == \"Hello World\");\n  /// ```\n  auto trim() -> const JSON::String &;\n\n  /// Check if the string has no leading or trailing whitespace. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::JSON trimmed{\"Hello World\"};\n  /// assert(trimmed.is_trimmed());\n  ///\n  /// const sourcemeta::core::JSON untrimmed{\" Hello World \"};\n  /// assert(!untrimmed.is_trimmed());\n  /// ```\n  [[nodiscard]] auto is_trimmed() const noexcept -> bool;\n\n  /// Reorder the properties of an object by sorting keys according to a\n  /// comparator function. The object is modified in-place. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::JSON::make_object();\n  /// document.assign(\"zebra\", sourcemeta::core::JSON{1});\n  /// document.assign(\"apple\", sourcemeta::core::JSON{2});\n  /// document.assign(\"banana\", sourcemeta::core::JSON{3});\n  ///\n  /// document.reorder([](const auto &left, const auto &right) {\n  ///   return left < right;\n  /// });\n  ///\n  /// auto iterator = document.as_object().cbegin();\n  /// assert(iterator->first == \"apple\");\n  /// ++iterator;\n  /// assert(iterator->first == \"banana\");\n  /// ++iterator;\n  /// assert(iterator->first == \"zebra\");\n  /// ```\n  auto reorder(const KeyComparison &compare) -> void;\n\n  /*\n   * Transform operations\n   */\n\n  /// This method moves a JSON property value from one property name to another,\n  /// potentially deleting the destination property name if it already exists.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// document.rename(\"foo\", \"bar\");\n  ///\n  /// assert(!document.defines(\"foo\"));\n  /// assert(document.defines(\"bar\"));\n  /// assert(document.at(\"bar\").is_boolean());\n  /// assert(document.at(\"bar\").to_boolean());\n  /// ```\n  auto rename(const JSON::String &key, JSON::String &&to) -> void;\n\n  /// This method sets a value to another JSON value by copying it. For example,\n  /// the member of a JSON document can be transformed from a boolean to an\n  /// integer as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// const sourcemeta::core::JSON value{2};\n  /// document.at(\"foo\").into(value);\n  /// assert(document.at(\"foo\").is_integer());\n  /// ```\n  auto into(const JSON &other) -> void;\n\n  /// This method sets a value to another JSON value. For example, the member of\n  /// a JSON document can be transformed from a boolean to an integer as\n  /// follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document =\n  ///   sourcemeta::core::parse_json(\"{ \\\"foo\\\": true }\");\n  /// document.at(\"foo\").into(sourcemeta::core::JSON{2});\n  /// assert(document.at(\"foo\").is_integer());\n  /// ```\n  auto into(JSON &&other) noexcept -> void;\n\n  /// This method converts an existing JSON instance into an empty array. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document{true};\n  /// assert(document.is_boolean());\n  /// document.into_array();\n  /// assert(document.is_array());\n  /// assert(document.empty());\n  /// ```\n  auto into_array() -> void;\n\n  /// This method converts an existing JSON instance into an empty object. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/json.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::JSON document{true};\n  /// assert(document.is_boolean());\n  /// document.into_object();\n  /// assert(document.is_object());\n  /// assert(document.empty());\n  /// ```\n  auto into_object() -> void;\n\nprivate:\n  Type current_type = Type::Null;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  union {\n    bool data_boolean;\n    Integer data_integer;\n    Real data_real;\n    String data_string;\n    Array data_array;\n    Object data_object;\n    // Move Decimal to the heap to reduce the size of the JSON class.\n    // Dealing with arbitrary precision numbers is not common, so we pay the\n    // indirection cost only when needed.\n    Decimal *data_decimal;\n  };\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n  auto maybe_destruct_union() -> void;\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/json.cc",
    "content": "#include <sourcemeta/core/io.h>\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/json_value.h>\n\n#include \"construct.h\"\n#include \"parser.h\"\n#include \"stringify.h\"\n\n#include <cassert>    // assert\n#include <cstdint>    // std::uint64_t\n#include <filesystem> // std::filesystem\n#include <istream>    // std::basic_istream\n#include <ostream>    // std::basic_ostream\n#include <vector>     // std::vector\n\nnamespace sourcemeta::core {\n\nstatic auto internal_parse_json(const char *&cursor, const char *end,\n                                std::uint64_t &line, std::uint64_t &column,\n                                const JSON::ParseCallback &callback,\n                                const bool track_positions, JSON &output)\n    -> void {\n  const char *buffer_start{cursor};\n  std::vector<TapeEntry> tape;\n  tape.reserve(static_cast<std::size_t>(end - cursor) / 8);\n  if (callback || track_positions) {\n    scan_json<true>(cursor, end, buffer_start, line, column, tape);\n  } else {\n    try {\n      scan_json<false>(cursor, end, buffer_start, line, column, tape);\n    } catch (const JSONParseError &) {\n      cursor = buffer_start;\n      tape.clear();\n      line = 1;\n      column = 0;\n      scan_json<true>(cursor, end, buffer_start, line, column, tape);\n    }\n  }\n  construct_json(buffer_start, tape, callback, output);\n}\n\nstatic auto internal_parse_json(const char *&cursor, const char *end,\n                                std::uint64_t &line, std::uint64_t &column,\n                                const bool track_positions) -> JSON {\n  JSON output{nullptr};\n  internal_parse_json(cursor, end, line, column, nullptr, track_positions,\n                      output);\n  return output;\n}\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                std::uint64_t &line, std::uint64_t &column) -> JSON {\n  const auto start_position{stream.tellg()};\n  const auto input{read_to_string(stream)};\n  const char *cursor{input.data()};\n  const char *end{input.data() + input.size()};\n  auto result{internal_parse_json(cursor, end, line, column, true)};\n  if (start_position != static_cast<std::streampos>(-1)) {\n    const auto consumed{static_cast<std::streamoff>(cursor - input.data())};\n    stream.clear();\n    stream.seekg(start_position + consumed);\n  }\n\n  return result;\n}\n\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    std::uint64_t &line, std::uint64_t &column) -> JSON {\n  const char *cursor{input.empty() ? \"\" : input.data()};\n  return internal_parse_json(cursor, cursor + input.size(), line, column, true);\n}\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream)\n    -> JSON {\n  const auto start_position{stream.tellg()};\n  const auto input{read_to_string(stream)};\n  const char *cursor{input.data()};\n  const char *end{input.data() + input.size()};\n  std::uint64_t line{1};\n  std::uint64_t column{0};\n  auto result{internal_parse_json(cursor, end, line, column, false)};\n  if (start_position != static_cast<std::streampos>(-1)) {\n    const auto consumed{static_cast<std::streamoff>(cursor - input.data())};\n    stream.clear();\n    stream.seekg(start_position + consumed);\n  }\n  return result;\n}\n\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input) -> JSON {\n  std::uint64_t line{1};\n  std::uint64_t column{0};\n  const char *cursor{input.empty() ? \"\" : input.data()};\n  return internal_parse_json(cursor, cursor + input.size(), line, column,\n                             false);\n}\n\nauto read_json(const std::filesystem::path &path) -> JSON {\n  try {\n    return parse_json(read_file_to_string(path));\n  } catch (const JSONParseError &error) {\n    // For producing better error messages\n    throw JSONFileParseError(path, error);\n  }\n}\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                std::uint64_t &line, std::uint64_t &column, JSON &output,\n                const JSON::ParseCallback &callback) -> void {\n  const auto start_position{stream.tellg()};\n  const auto input{read_to_string(stream)};\n  const char *cursor{input.data()};\n  const char *end{input.data() + input.size()};\n  internal_parse_json(cursor, end, line, column, callback, true, output);\n  if (start_position != static_cast<std::streampos>(-1)) {\n    const auto consumed{static_cast<std::streamoff>(cursor - input.data())};\n    stream.clear();\n    stream.seekg(start_position + consumed);\n  }\n}\n\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    std::uint64_t &line, std::uint64_t &column, JSON &output,\n    const JSON::ParseCallback &callback) -> void {\n  const char *cursor{input.empty() ? \"\" : input.data()};\n  internal_parse_json(cursor, cursor + input.size(), line, column, callback,\n                      true, output);\n}\n\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)\nauto parse_json(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                JSON &output, const JSON::ParseCallback &callback) -> void {\n  const auto start_position{stream.tellg()};\n  const auto input{read_to_string(stream)};\n  const char *cursor{input.data()};\n  const char *end{input.data() + input.size()};\n  std::uint64_t line{1};\n  std::uint64_t column{0};\n  internal_parse_json(cursor, end, line, column, callback, false, output);\n  if (start_position != static_cast<std::streampos>(-1)) {\n    const auto consumed{static_cast<std::streamoff>(cursor - input.data())};\n    stream.clear();\n    stream.seekg(start_position + consumed);\n  }\n}\n\nauto parse_json(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input,\n    JSON &output, const JSON::ParseCallback &callback) -> void {\n  std::uint64_t line{1};\n  std::uint64_t column{0};\n  const char *cursor{input.empty() ? \"\" : input.data()};\n  internal_parse_json(cursor, cursor + input.size(), line, column, callback,\n                      false, output);\n}\n\nauto read_json(const std::filesystem::path &path, JSON &output,\n               const JSON::ParseCallback &callback) -> void {\n  try {\n    parse_json(read_file_to_string(path), output, callback);\n  } catch (const JSONParseError &error) {\n    // For producing better error messages\n    throw JSONFileParseError(path, error);\n  }\n}\n\nauto stringify(const JSON &document,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void {\n  stringify<std::allocator>(document, stream);\n}\n\nauto prettify(const JSON &document,\n              std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n              const std::size_t spaces) -> void {\n  prettify<std::allocator>(document, stream, 0, spaces);\n}\n\nauto operator<<(std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                const JSON &document)\n    -> std::basic_ostream<JSON::Char, JSON::CharTraits> & {\n#ifdef NDEBUG\n  stringify(document, stream);\n#else\n  prettify(document, stream);\n#endif\n  return stream;\n}\n\nauto operator<<(std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                const JSON::Type type)\n    -> std::basic_ostream<JSON::Char, JSON::CharTraits> & {\n  switch (type) {\n    case sourcemeta::core::JSON::Type::Null:\n      return stream << \"null\";\n    case sourcemeta::core::JSON::Type::Boolean:\n      return stream << \"boolean\";\n    case sourcemeta::core::JSON::Type::Integer:\n      return stream << \"integer\";\n    case sourcemeta::core::JSON::Type::Real:\n      return stream << \"real\";\n    case sourcemeta::core::JSON::Type::Decimal:\n      return stream << \"decimal\";\n    case sourcemeta::core::JSON::Type::String:\n      return stream << \"string\";\n    case sourcemeta::core::JSON::Type::Array:\n      return stream << \"array\";\n    case sourcemeta::core::JSON::Type::Object:\n      return stream << \"object\";\n    default:\n      // Should never happen, but some compilers are not happy without this\n      assert(false);\n      return stream;\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/json/json_value.cc",
    "content": "#include <sourcemeta/core/json_array.h>\n#include <sourcemeta/core/json_value.h>\n\n#include <algorithm>        // std::ranges::contains, std::ranges::fold_left\n#include <cassert>          // assert\n#include <cmath>            // std::isinf, std::isnan, std::modf\n#include <cstddef>          // std::size_t\n#include <cstdint>          // std::int64_t\n#include <functional>       // std::reference_wrapper\n#include <initializer_list> // std::initializer_list\n#include <memory>           // std::construct_at\n#include <sstream>          // std::basic_istringstream\n#include <stdexcept>        // std::invalid_argument\n#include <string>           // std::to_string\n#include <string_view>      // std::basic_string_view\n#include <utility>          // std::exchange, std::move\n#include <vector>           // std::vector\n\nnamespace sourcemeta::core {\n\nstatic constexpr auto TRIM_WHITESPACE = \" \\t\\n\\r\\v\\f\";\n\nJSON::JSON(const std::int64_t value) : current_type{Type::Integer} {\n  this->data_integer = value;\n}\n\nJSON::JSON(const std::size_t value) : current_type{Type::Integer} {\n  this->data_integer = static_cast<Integer>(value);\n}\n\nJSON::JSON(const int value) : current_type{Type::Integer} {\n  this->data_integer = value;\n}\n\nJSON::JSON(const double value) : current_type{Type::Real} {\n  // Numeric values that cannot be represented as sequences of digits (such as\n  // Infinity and NaN) are not permitted. See\n  // https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\n  if (std::isinf(value) || std::isnan(value)) {\n    throw std::invalid_argument(\"JSON does not support Infinity or NaN\");\n  }\n\n  this->data_real = value;\n}\n\nJSON::JSON(const float value) : JSON(static_cast<Real>(value)) {}\n\nJSON::JSON(const bool value) : current_type{Type::Boolean} {\n  this->data_boolean = value;\n}\n\nJSON::JSON(const std::nullptr_t) {}\n\nJSON::JSON(const String &value) : current_type{Type::String} {\n  std::construct_at(&this->data_string, value);\n}\n\nJSON::JSON(const std::basic_string_view<Char, CharTraits> &value)\n    : current_type{Type::String} {\n  std::construct_at(&this->data_string, value);\n}\n\nJSON::JSON(const Char *const value) : current_type{Type::String} {\n  std::construct_at(&this->data_string, value);\n}\n\nJSON::JSON(std::initializer_list<JSON> values) : current_type{Type::Array} {\n// For direct-list-initialization (e.g. JSON x{other_json}), the C++ standard\n// mandates that initializer_list constructors are preferred over copy/move\n// constructors. GCC and MSVC follow this strictly, so a single-element brace\n// init ends up here instead of the copy constructor. Handle this case before\n// constructing the array to avoid an unnecessary heap allocation.\n#if defined(__GNUC__) || defined(_MSC_VER)\n  if (values.size() == 1) {\n    this->current_type = Type::Null;\n    this->operator=(*values.begin());\n    return;\n  }\n#endif\n  std::construct_at(&this->data_array, values);\n}\n\nJSON::JSON(const Array &value) : current_type{Type::Array} {\n  std::construct_at(&this->data_array, value);\n}\n\nJSON::JSON(std::initializer_list<typename Object::pair_value_type> values)\n    : current_type{Type::Object} {\n  std::construct_at(&this->data_object, values);\n}\n\nJSON::JSON(const Object &value) : current_type{Type::Object} {\n  std::construct_at(&this->data_object, value);\n}\n\nJSON::JSON(const Decimal &value) : current_type{Type::Decimal} {\n  if (value.is_nan() || value.is_infinite()) {\n    throw std::invalid_argument(\"JSON does not support Infinity or NaN\");\n  }\n\n  this->data_decimal = new Decimal{value};\n}\n\nJSON::JSON(Decimal &&value) : current_type{Type::Decimal} {\n  if (value.is_nan() || value.is_infinite()) {\n    throw std::invalid_argument(\"JSON does not support Infinity or NaN\");\n  }\n\n  this->data_decimal = new Decimal{std::move(value)};\n}\n\nJSON::JSON(const JSON &other) : current_type{other.current_type} {\n  switch (other.current_type) {\n    case Type::Boolean:\n      this->data_boolean = other.data_boolean;\n      break;\n    case Type::Integer:\n      this->data_integer = other.data_integer;\n      break;\n    case Type::Real:\n      this->data_real = other.data_real;\n      break;\n    case Type::String:\n      std::construct_at(&this->data_string, other.data_string);\n      break;\n    case Type::Array:\n      std::construct_at(&this->data_array, other.data_array);\n      break;\n    case Type::Object:\n      std::construct_at(&this->data_object, other.data_object);\n      break;\n    case Type::Decimal:\n      this->data_decimal = new Decimal{*other.data_decimal};\n      break;\n    default:\n      break;\n  }\n}\n\nJSON::JSON(JSON &&other) noexcept : current_type{other.current_type} {\n  switch (other.current_type) {\n    case Type::Boolean:\n      this->data_boolean = other.data_boolean;\n      break;\n    case Type::Integer:\n      this->data_integer = other.data_integer;\n      break;\n    case Type::Real:\n      this->data_real = other.data_real;\n      break;\n    case Type::String:\n      std::construct_at(&this->data_string, std::move(other.data_string));\n      other.current_type = Type::Null;\n      break;\n    case Type::Array:\n      std::construct_at(&this->data_array, std::move(other.data_array));\n      other.current_type = Type::Null;\n      break;\n    case Type::Object:\n      std::construct_at(&this->data_object, std::move(other.data_object));\n      other.current_type = Type::Null;\n      break;\n    case Type::Decimal:\n      this->data_decimal = std::exchange(other.data_decimal, nullptr);\n      other.current_type = Type::Null;\n      break;\n    default:\n      break;\n  }\n}\n\nauto JSON::operator=(const JSON &other) -> JSON & {\n  this->maybe_destruct_union();\n  this->current_type = other.current_type;\n  switch (other.current_type) {\n    case Type::Boolean:\n      this->data_boolean = other.data_boolean;\n      break;\n    case Type::Integer:\n      this->data_integer = other.data_integer;\n      break;\n    case Type::Real:\n      this->data_real = other.data_real;\n      break;\n    case Type::String:\n      std::construct_at(&this->data_string, other.data_string);\n      break;\n    case Type::Array:\n      std::construct_at(&this->data_array, other.data_array);\n      break;\n    case Type::Object:\n      std::construct_at(&this->data_object, other.data_object);\n      break;\n    case Type::Decimal:\n      this->data_decimal = new Decimal{*other.data_decimal};\n      break;\n    default:\n      break;\n  }\n\n  return *this;\n}\n\nauto JSON::operator=(JSON &&other) noexcept -> JSON & {\n  this->maybe_destruct_union();\n  this->current_type = other.current_type;\n  switch (other.current_type) {\n    case Type::Boolean:\n      this->data_boolean = other.data_boolean;\n      break;\n    case Type::Integer:\n      this->data_integer = other.data_integer;\n      break;\n    case Type::Real:\n      this->data_real = other.data_real;\n      break;\n    case Type::String:\n      std::construct_at(&this->data_string, std::move(other.data_string));\n      other.current_type = Type::Null;\n      break;\n    case Type::Array:\n      std::construct_at(&this->data_array, std::move(other.data_array));\n      other.current_type = Type::Null;\n      break;\n    case Type::Object:\n      std::construct_at(&this->data_object, std::move(other.data_object));\n      other.current_type = Type::Null;\n      break;\n    case Type::Decimal:\n      this->data_decimal = std::exchange(other.data_decimal, nullptr);\n      other.current_type = Type::Null;\n      break;\n    default:\n      break;\n  }\n\n  return *this;\n}\n\nJSON::~JSON() { this->maybe_destruct_union(); }\n\nauto JSON::make_array() -> JSON { return JSON{Array{}}; }\n\nauto JSON::make_object() -> JSON { return JSON{Object{}}; }\n\nauto JSON::size(const String &value) noexcept -> std::size_t {\n  std::size_t result{0};\n\n  // We want to count the number of logical characters,\n  // not the number of bytes\n  for (const auto character : value) {\n    // In UTF-8, continuation bytes (i.e. not the first) are\n    // encoded as `10xxxxxx`, so this means we are at the start\n    // of a code-point\n    // See https://en.wikipedia.org/wiki/UTF-8#Encoding\n    if ((character & 0b11000000) != 0b10000000) {\n      result += 1;\n    }\n  }\n\n  return result;\n}\n\nauto JSON::operator<(const JSON &other) const noexcept -> bool {\n  if ((this->type() == Type::Integer && other.type() == Type::Real) ||\n      (this->type() == Type::Real && other.type() == Type::Integer)) {\n    return this->as_real() < other.as_real();\n  }\n\n  if ((this->type() == Type::Decimal &&\n       (other.type() == Type::Integer || other.type() == Type::Real)) ||\n      ((this->type() == Type::Integer || this->type() == Type::Real) &&\n       other.type() == Type::Decimal)) {\n    const Decimal left = this->is_decimal()   ? this->to_decimal()\n                         : this->is_integer() ? Decimal{this->to_integer()}\n                                              : Decimal{this->to_real()};\n    const Decimal right = other.is_decimal()   ? other.to_decimal()\n                          : other.is_integer() ? Decimal{other.to_integer()}\n                                               : Decimal{other.to_real()};\n    return left < right;\n  }\n\n  if (this->type() != other.type()) {\n    return this->current_type < other.current_type;\n  }\n\n  switch (this->type()) {\n    case Type::Null:\n      return false;\n    case Type::Boolean:\n      return this->to_boolean() < other.to_boolean();\n    case Type::Integer:\n      return this->to_integer() < other.to_integer();\n    case Type::Real:\n      return this->to_real() < other.to_real();\n    case Type::Decimal:\n      return this->to_decimal() < other.to_decimal();\n    case Type::String:\n      return this->to_string() < other.to_string();\n    case Type::Array:\n      return this->as_array() < other.as_array();\n    case Type::Object:\n      return this->as_object() < other.as_object();\n    default:\n      return false;\n  }\n}\n\nauto JSON::operator<=(const JSON &other) const noexcept -> bool {\n  return *this < other || *this == other;\n}\n\nauto JSON::operator>(const JSON &other) const noexcept -> bool {\n  return !(*this < other) && *this != other;\n}\n\nauto JSON::operator>=(const JSON &other) const noexcept -> bool {\n  return *this > other || *this == other;\n}\n\nauto JSON::operator==(const JSON &other) const noexcept -> bool {\n  if ((this->type() == Type::Integer && other.type() == Type::Real) ||\n      (this->type() == Type::Real && other.type() == Type::Integer)) {\n    return this->as_real() == other.as_real();\n  }\n\n  if ((this->type() == Type::Decimal &&\n       (other.type() == Type::Integer || other.type() == Type::Real)) ||\n      ((this->type() == Type::Integer || this->type() == Type::Real) &&\n       other.type() == Type::Decimal)) {\n    const Decimal left = this->is_decimal()   ? this->to_decimal()\n                         : this->is_integer() ? Decimal{this->to_integer()}\n                                              : Decimal{this->to_real()};\n    const Decimal right = other.is_decimal()   ? other.to_decimal()\n                          : other.is_integer() ? Decimal{other.to_integer()}\n                                               : Decimal{other.to_real()};\n    return left == right;\n  }\n\n  if (this->current_type != other.current_type) {\n    return false;\n  }\n\n  switch (this->current_type) {\n    case Type::Boolean:\n      return this->data_boolean == other.data_boolean;\n    case Type::Integer:\n      return this->data_integer == other.data_integer;\n    case Type::Real:\n      return this->data_real == other.data_real;\n    case Type::Decimal:\n      return *this->data_decimal == *other.data_decimal;\n    case Type::String:\n      return this->data_string == other.data_string;\n    case Type::Array:\n      return this->data_array == other.data_array;\n    case Type::Object:\n      return this->data_object == other.data_object;\n    default:\n      return true;\n  }\n}\n\nauto JSON::operator+(const JSON &other) const -> JSON {\n  assert(this->is_number());\n  assert(other.is_number());\n\n  if (this->is_decimal() || other.is_decimal()) {\n    const Decimal left = this->is_decimal()   ? this->to_decimal()\n                         : this->is_integer() ? Decimal{this->to_integer()}\n                                              : Decimal{this->to_real()};\n    const Decimal right = other.is_decimal()   ? other.to_decimal()\n                          : other.is_integer() ? Decimal{other.to_integer()}\n                                               : Decimal{other.to_real()};\n    return JSON{left + right};\n  } else if (this->is_integer() && other.is_integer()) {\n    return JSON{this->to_integer() + other.to_integer()};\n  } else if (this->is_integer() && other.is_real()) {\n    return JSON{this->as_real() + other.to_real()};\n  } else if (this->is_real() && other.is_integer()) {\n    return JSON{this->to_real() + other.as_real()};\n  } else {\n    return JSON{this->to_real() + other.to_real()};\n  }\n}\n\nauto JSON::operator-(const JSON &other) const -> JSON {\n  assert(this->is_number());\n  assert(other.is_number());\n\n  if (this->is_decimal() || other.is_decimal()) {\n    const Decimal left = this->is_decimal()   ? this->to_decimal()\n                         : this->is_integer() ? Decimal{this->to_integer()}\n                                              : Decimal{this->to_real()};\n    const Decimal right = other.is_decimal()   ? other.to_decimal()\n                          : other.is_integer() ? Decimal{other.to_integer()}\n                                               : Decimal{other.to_real()};\n    return JSON{left - right};\n  } else if (this->is_integer() && other.is_integer()) {\n    return JSON{this->to_integer() - other.to_integer()};\n  } else if (this->is_integer() && other.is_real()) {\n    return JSON{this->as_real() - other.to_real()};\n  } else if (this->is_real() && other.is_integer()) {\n    return JSON{this->to_real() - other.as_real()};\n  } else {\n    return JSON{this->to_real() - other.to_real()};\n  }\n}\n\nauto JSON::operator+=(const JSON &additive) -> JSON & {\n  return *this = *this + additive;\n}\n\nauto JSON::operator-=(const JSON &substractive) -> JSON & {\n  return *this = *this - substractive;\n}\n\n[[nodiscard]] auto JSON::is_positive() const noexcept -> bool {\n  switch (this->type()) {\n    case Type::Integer:\n      return this->to_integer() >= 0;\n    case Type::Real:\n      return this->to_real() >= static_cast<Real>(0.0);\n    case Type::Decimal:\n      return this->to_decimal() >= Decimal{0};\n    default:\n      return false;\n  }\n}\n\n[[nodiscard]] auto JSON::to_stringstream() const\n    -> std::basic_istringstream<Char, CharTraits, Allocator<Char>> {\n  return std::basic_istringstream<Char, CharTraits, Allocator<Char>>{\n      this->data_string};\n}\n\n[[nodiscard]] auto JSON::at_or(const String &key,\n                               const typename Object::hash_type hash,\n                               const JSON &otherwise) const -> const JSON & {\n  assert(this->is_object());\n  const auto result{this->try_at(key, hash)};\n  return result ? *result : otherwise;\n}\n\n[[nodiscard]] auto JSON::at_or(const String &key, const JSON &otherwise) const\n    -> const JSON & {\n  assert(this->is_object());\n  return this->at_or(key, this->data_object.hash(key), otherwise);\n}\n\n[[nodiscard]] auto JSON::estimated_byte_size() const -> std::uint64_t {\n  // Of course, container have some overhead of their own\n  // which we are not taking into account here, as its typically\n  // implementation dependent. This function is just a rough estimate.\n  if (this->is_object()) {\n    return std::ranges::fold_left(this->as_object(),\n                                  static_cast<std::uint64_t>(0),\n                                  [](const std::uint64_t accumulator,\n                                     const typename Object::value_type &pair) {\n                                    return accumulator +\n                                           (pair.first.size() * sizeof(Char)) +\n                                           pair.second.estimated_byte_size();\n                                  });\n  } else if (this->is_array()) {\n    return std::ranges::fold_left(\n        this->as_array(), static_cast<std::uint64_t>(0),\n        [](const std::uint64_t accumulator, const JSON &item) {\n          return accumulator + item.estimated_byte_size();\n        });\n  } else if (this->is_string()) {\n    // Keep in mind that standard strings might reserve more\n    // space than what it is actually used by the string\n    return this->byte_size() * sizeof(Char);\n  } else if (this->is_integer()) {\n    return sizeof(Integer);\n  } else if (this->is_real()) {\n    return sizeof(Real);\n  } else if (this->is_boolean()) {\n    return sizeof(bool);\n  } else {\n    // The size of the union\n    return 8;\n  }\n}\n\n[[nodiscard]] auto JSON::fast_hash() const -> std::uint64_t {\n  switch (this->current_type) {\n    case Type::Null:\n      return 2;\n    case Type::Boolean:\n      return this->to_boolean() ? 1 : 0;\n    case Type::Integer:\n      return 4 + (static_cast<std::uint64_t>(this->to_integer()) % 256);\n    case Type::Real:\n      return 5;\n    case Type::String:\n      return 3 + this->byte_size();\n    case Type::Array:\n      return std::ranges::fold_left(\n          this->as_array(), static_cast<std::uint64_t>(6),\n          [](const std::uint64_t accumulator, const JSON &item) {\n            return accumulator + 1 + item.fast_hash();\n          });\n    case Type::Object:\n      return std::ranges::fold_left(\n          this->as_object(), static_cast<std::uint64_t>(7),\n          [](const std::uint64_t accumulator,\n             const typename Object::value_type &pair) {\n            return accumulator + 1 + pair.first.size() +\n                   pair.second.fast_hash();\n          });\n    case Type::Decimal:\n      return 8;\n    default:\n      assert(false);\n      return 0;\n  }\n}\n\n[[nodiscard]] auto JSON::divisible_by(const JSON &divisor) const -> bool {\n  assert(this->is_number());\n  assert(divisor.is_number());\n\n  if (this->is_integer() && divisor.is_integer()) {\n    const auto divisor_value{divisor.to_integer()};\n    return divisor_value != 0 && this->to_integer() % divisor_value == 0;\n  }\n\n  if (!this->is_decimal() && !divisor.is_decimal()) {\n    const auto divisor_value(divisor.as_real());\n    if (divisor_value == 0.0) {\n      return false;\n    }\n\n    const auto dividend_value{this->as_real()};\n\n    // Every real number that represents an integral is divisible by 0.5.\n    Real dividend_integral = 0;\n    if (std::modf(dividend_value, &dividend_integral) == 0.0 &&\n        divisor_value == 0.5) {\n      return true;\n    }\n\n    const auto division{dividend_value / divisor_value};\n    Real integral = 0;\n    if (!std::isinf(division) && !std::isnan(division) &&\n        std::modf(division, &integral) == 0.0) {\n      return true;\n    }\n\n    return Decimal::strict_from(dividend_value)\n        .divisible_by(Decimal::strict_from(divisor_value));\n  }\n\n  if (this->is_decimal() && divisor.is_decimal()) {\n    return this->to_decimal().divisible_by(divisor.to_decimal());\n  }\n\n  if (this->is_decimal()) {\n    if (divisor.is_integer()) {\n      const Decimal divisor_decimal{divisor.to_integer()};\n      return this->to_decimal().divisible_by(divisor_decimal);\n    }\n\n    return this->to_decimal().divisible_by(\n        Decimal::strict_from(divisor.to_real()));\n  }\n\n  if (this->is_integer()) {\n    const Decimal dividend_decimal{this->to_integer()};\n    return dividend_decimal.divisible_by(divisor.to_decimal());\n  }\n\n  return Decimal::strict_from(this->to_real())\n      .divisible_by(divisor.to_decimal());\n}\n\n[[nodiscard]] auto\nJSON::defines_any(std::initializer_list<JSON::String> keys) const -> bool {\n  return this->defines_any(keys.begin(), keys.end());\n}\n\n[[nodiscard]] auto JSON::contains(const JSON &element) const -> bool {\n  assert(this->is_array());\n  return std::ranges::contains(this->as_array(), element);\n}\n\n[[nodiscard]] auto JSON::contains(const JSON::StringView element) const\n    -> bool {\n  assert(this->is_array());\n  for (const auto &item : this->as_array()) {\n    if (item.is_string() && item.to_string() == element) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n[[nodiscard]] auto JSON::includes(const JSON::String &input) const -> bool {\n  assert(this->is_string());\n  return this->to_string().contains(input);\n}\n\n[[nodiscard]] auto JSON::includes(const JSON::String::value_type input) const\n    -> bool {\n  assert(this->is_string());\n  return this->to_string().contains(input);\n}\n\n[[nodiscard]] auto JSON::unique() const -> bool {\n  assert(this->is_array());\n  const auto &items{this->data_array.data};\n  const auto size{items.size()};\n\n  // Arrays of 0 or 1 item are unique by definition\n  if (size <= 1) {\n    return true;\n  }\n\n  // If we re-use the vector across threads, then we will segfault\n  thread_local std::vector<std::uint64_t> cache;\n  cache.clear();\n  cache.resize(size);\n\n  for (std::size_t index = 0; index < size; index++) {\n    cache[index] = items[index].fast_hash();\n  }\n\n  for (std::size_t index = 0; index < size; index++) {\n    for (std::size_t subindex = index + 1; subindex < size; subindex++) {\n      if (cache[index] == cache[subindex] && items[index] == items[subindex]) {\n        return false;\n      }\n    }\n  }\n\n  return true;\n}\n\nauto JSON::push_back(const JSON &value) -> void {\n  assert(this->is_array());\n  return this->data_array.data.push_back(value);\n}\n\nauto JSON::push_back(JSON &&value) -> void {\n  assert(this->is_array());\n  return this->data_array.data.push_back(std::move(value));\n}\n\nauto JSON::push_back_if_unique(const JSON &value)\n    -> std::pair<std::reference_wrapper<const JSON>, bool> {\n  assert(this->is_array());\n  auto &array_data{this->as_array().data};\n  if (!std::ranges::contains(array_data, value)) {\n    array_data.push_back(value);\n    return {array_data.back(), true};\n  } else {\n    return {*std::ranges::find(array_data, value), false};\n  }\n}\n\nauto JSON::push_back_if_unique(JSON &&value)\n    -> std::pair<std::reference_wrapper<const JSON>, bool> {\n  assert(this->is_array());\n  auto &array_data{this->as_array().data};\n  if (!std::ranges::contains(array_data, value)) {\n    array_data.push_back(std::move(value));\n    return {array_data.back(), true};\n  } else {\n    return {*std::ranges::find(array_data, value), false};\n  }\n}\n\nauto JSON::assign(const JSON::String &key, const JSON &value) -> void {\n  assert(this->is_object());\n  this->data_object.emplace(key, value);\n}\n\nauto JSON::assign(const JSON::String &key, JSON &&value) -> void {\n  assert(this->is_object());\n  this->data_object.emplace(key, value);\n}\n\nauto JSON::try_assign_before(const String &key, const JSON &value,\n                             const String &other) -> void {\n  assert(this->is_object());\n  this->data_object.try_emplace_before(key, value, other);\n}\n\nauto JSON::assign_if_missing(const JSON::String &key, const JSON &value)\n    -> void {\n  assert(this->is_object());\n  if (!this->defines(key)) {\n    this->assign(key, value);\n  }\n}\n\nauto JSON::assign_if_missing(const JSON::String &key, JSON &&value) -> void {\n  assert(this->is_object());\n  if (!this->defines(key)) {\n    this->assign(key, std::move(value));\n  }\n}\n\nauto JSON::assign_assume_new(const JSON::String &key, JSON &&value) -> void {\n  assert(this->is_object());\n  this->data_object.emplace_assume_new(key, std::move(value));\n}\n\nauto JSON::assign_assume_new(JSON::String &&key, JSON &&value) -> void {\n  assert(this->is_object());\n  this->data_object.emplace_assume_new(std::move(key), std::move(value));\n}\n\nauto JSON::assign_assume_new(JSON::String &&key, JSON &&value,\n                             Object::hash_type hash) -> void {\n  assert(this->is_object());\n  this->data_object.emplace_assume_new(std::move(key), std::move(value), hash);\n}\n\nauto JSON::erase(const JSON::String &key) -> typename Object::size_type {\n  assert(this->is_object());\n  return this->data_object.erase(key);\n}\n\nauto JSON::erase_keys(std::initializer_list<JSON::String> keys) -> void {\n  this->erase_keys(keys.begin(), keys.end());\n}\n\nauto JSON::erase(typename JSON::Array::const_iterator position) ->\n    typename JSON::Array::iterator {\n  assert(this->is_array());\n  return this->data_array.data.erase(position);\n}\n\nauto JSON::erase(typename JSON::Array::const_iterator first,\n                 typename JSON::Array::const_iterator last) ->\n    typename JSON::Array::iterator {\n  assert(this->is_array());\n  return this->data_array.data.erase(first, last);\n}\n\nauto JSON::erase_if(const std::function<bool(const JSON &)> &predicate)\n    -> void {\n  assert(this->is_array());\n  std::erase_if(this->data_array.data, predicate);\n}\n\nauto JSON::clear() -> void {\n  if (this->is_object()) {\n    this->data_object.clear();\n  } else {\n    this->data_array.data.clear();\n  }\n}\n\nauto JSON::clear_except(std::initializer_list<JSON::String> keys) -> void {\n  this->clear_except(keys.begin(), keys.end());\n}\n\nauto JSON::merge(const JSON::Object &other) -> void {\n  assert(this->is_object());\n  for (const auto &pair : other) {\n    const auto maybe_key{this->try_at(pair.first, pair.hash)};\n    if (maybe_key && maybe_key->is_object() && pair.second.is_object()) {\n      this->at(pair.first, pair.hash).merge(pair.second.as_object());\n    } else {\n      this->assign(pair.first, pair.second);\n    }\n  }\n}\n\n[[nodiscard]] auto JSON::trim() const -> JSON::String {\n  assert(this->is_string());\n  auto copy = *this;\n  copy.trim();\n  return copy.to_string();\n}\n\nauto JSON::trim() -> const JSON::String & {\n  assert(this->is_string());\n  this->data_string.erase(this->data_string.find_last_not_of(TRIM_WHITESPACE) +\n                          1);\n  this->data_string.erase(0,\n                          this->data_string.find_first_not_of(TRIM_WHITESPACE));\n  return this->to_string();\n}\n\n[[nodiscard]] auto JSON::is_trimmed() const noexcept -> bool {\n  assert(this->is_string());\n  const auto &value{this->data_string};\n  return value.empty() ||\n         (value.find_first_of(TRIM_WHITESPACE) != 0 &&\n          value.find_last_of(TRIM_WHITESPACE) != value.size() - 1);\n}\n\nauto JSON::reorder(const KeyComparison &compare) -> void {\n  assert(this->is_object());\n  this->data_object.reorder(compare);\n}\n\nauto JSON::rename(const JSON::String &key, JSON::String &&to) -> void {\n  assert(this->is_object());\n  auto &object{this->data_object};\n  object.rename(key, object.hash(key), std::move(to), object.hash(to));\n}\n\nauto JSON::into(const JSON &other) -> void { this->operator=(other); }\n\nauto JSON::into(JSON &&other) noexcept -> void {\n  this->operator=(std::move(other));\n}\n\nauto JSON::into_array() -> void { this->into(JSON::make_array()); }\n\nauto JSON::into_object() -> void { this->into(JSON::make_object()); }\n\nauto JSON::maybe_destruct_union() -> void {\n  switch (this->current_type) {\n    case Type::String:\n      this->data_string.~basic_string();\n      break;\n    case Type::Array:\n      this->data_array.~JSONArray();\n      break;\n    case Type::Object:\n      this->data_object.~JSONObject();\n      break;\n    case Type::Decimal:\n      delete this->data_decimal;\n      break;\n    default:\n      break;\n  }\n\n  this->current_type = Type::Null;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/json/parser.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_PARSER_H_\n#define SOURCEMETA_CORE_JSON_PARSER_H_\n\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/json_value.h>\n\n#include \"grammar.h\"\n\n#include <cassert> // assert\n#include <cstdint> // std::uint64_t, std::uint32_t\n#include <vector>  // std::vector\n\nnamespace sourcemeta::core {\n\nenum class TapeType : std::uint8_t {\n  ObjectStart,\n  ObjectEnd,\n  ArrayStart,\n  ArrayEnd,\n  Key,\n  String,\n  Number,\n  Null,\n  True,\n  False\n};\n\nstruct TapeEntry {\n  TapeType type;\n  std::uint32_t offset;\n  std::uint32_t length;\n  std::uint32_t count;\n  std::uint64_t line;\n  std::uint64_t column;\n};\n\nnamespace internal {\n\ntemplate <bool TrackPositions>\ninline auto skip_whitespace(const char *&cursor, const char *end,\n                            std::uint64_t &line, std::uint64_t &column)\n    -> void {\n  while (cursor < end) {\n    switch (*cursor) {\n      case internal::token_whitespace_space<typename JSON::Char>:\n      case internal::token_whitespace_tabulation<typename JSON::Char>:\n      case internal::token_whitespace_carriage_return<typename JSON::Char>:\n        if constexpr (TrackPositions) {\n          column += 1;\n        }\n        cursor++;\n        continue;\n      case internal::token_whitespace_line_feed<typename JSON::Char>:\n        if constexpr (TrackPositions) {\n          line += 1;\n          column = 0;\n        }\n        cursor++;\n        continue;\n      default:\n        return;\n    }\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_null(const std::uint64_t line, std::uint64_t &column,\n                      const char *&cursor, const char *end) -> void {\n  for (\n      const auto character :\n      internal::constant_null<typename JSON::Char, typename JSON::CharTraits>.substr(\n          1)) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    if (*cursor != character) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    cursor++;\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_true(const std::uint64_t line, std::uint64_t &column,\n                      const char *&cursor, const char *end) -> void {\n  for (\n      const auto character :\n      internal::constant_true<typename JSON::Char, typename JSON::CharTraits>.substr(\n          1)) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    if (*cursor != character) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    cursor++;\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_false(const std::uint64_t line, std::uint64_t &column,\n                       const char *&cursor, const char *end) -> void {\n  for (\n      const auto character :\n      internal::constant_false<typename JSON::Char, typename JSON::CharTraits>.substr(\n          1)) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    if (*cursor != character) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    cursor++;\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_string_unicode_code_point(const std::uint64_t line,\n                                           std::uint64_t &column,\n                                           const char *&cursor, const char *end)\n    -> unsigned long {\n  unsigned long result{0};\n  for (std::size_t index = 0; index < 4; index++) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    const char hex_char{*cursor++};\n    unsigned long digit;\n    if (hex_char >= '0' && hex_char <= '9') {\n      digit = static_cast<unsigned long>(hex_char - '0');\n    } else if (hex_char >= 'a' && hex_char <= 'f') {\n      digit = static_cast<unsigned long>(hex_char - 'a') + 10;\n    } else if (hex_char >= 'A' && hex_char <= 'F') {\n      digit = static_cast<unsigned long>(hex_char - 'A') + 10;\n    } else [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    result = (result << 4) | digit;\n  }\n\n  assert(result <= 0xFFFF);\n  return result;\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_string_unicode(const std::uint64_t line, std::uint64_t &column,\n                                const char *&cursor, const char *end) -> void {\n  auto code_point{scan_string_unicode_code_point<TrackPositions>(line, column,\n                                                                 cursor, end)};\n  using CharT = typename JSON::Char;\n\n  if (code_point >= 0xDC00 && code_point <= 0xDFFF) [[unlikely]] {\n    throw JSONParseError(line, column);\n  }\n\n  if (code_point >= 0xD800 && code_point <= 0xDBFF) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    if (*cursor != internal::token_string_escape<CharT>) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    cursor++;\n\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    if (cursor >= end) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    if (*cursor != internal::token_string_escape_unicode<CharT>) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n    cursor++;\n\n    const auto low_code_point{scan_string_unicode_code_point<TrackPositions>(\n        line, column, cursor, end)};\n\n    // See\n    // https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF\n    if (low_code_point < 0xDC00 || low_code_point > 0xDFFF) [[unlikely]] {\n      throw JSONParseError(line, column);\n    }\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_string_escape(const std::uint64_t line, std::uint64_t &column,\n                               const char *&cursor, const char *end) -> void {\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  if (cursor >= end) [[unlikely]] {\n    throw JSONParseError(line, column);\n  }\n  switch (*cursor++) {\n    case internal::token_string_quote<typename JSON::Char>:\n    case internal::token_string_escape<typename JSON::Char>:\n    case internal::token_string_solidus<typename JSON::Char>:\n    case internal::token_string_escape_backspace<typename JSON::Char>:\n    case internal::token_string_escape_form_feed<typename JSON::Char>:\n    case internal::token_string_escape_line_feed<typename JSON::Char>:\n    case internal::token_string_escape_carriage_return<typename JSON::Char>:\n    case internal::token_string_escape_tabulation<typename JSON::Char>:\n      return;\n    case internal::token_string_escape_unicode<typename JSON::Char>:\n      scan_string_unicode<TrackPositions>(line, column, cursor, end);\n      return;\n    default:\n      [[unlikely]] throw JSONParseError(line, column);\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_string(const std::uint64_t line, std::uint64_t &column,\n                        const char *&cursor, const char *end) -> void {\n  using CharT = typename JSON::Char;\n  while (cursor < end) {\n    const char *scan{cursor};\n    while (scan < end && *scan != internal::token_string_quote<CharT> &&\n           *scan != internal::token_string_escape<CharT> &&\n           static_cast<unsigned char>(*scan) >= 0x20) {\n      scan++;\n    }\n\n    if (scan > cursor) {\n      if constexpr (TrackPositions) {\n        column += static_cast<std::uint64_t>(scan - cursor);\n      }\n      cursor = scan;\n    }\n\n    if (cursor >= end) [[unlikely]] {\n      if constexpr (TrackPositions) {\n        column += 1;\n      }\n      throw JSONParseError(line, column);\n    }\n\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    const char character{*cursor++};\n\n    switch (character) {\n      case internal::token_string_quote<typename JSON::Char>:\n        return;\n      case internal::token_string_escape<typename JSON::Char>:\n        scan_string_escape<TrackPositions>(line, column, cursor, end);\n        break;\n      default:\n        [[unlikely]] throw JSONParseError(line, column);\n    }\n  }\n\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  throw JSONParseError(line, column);\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_digits(const std::uint64_t line, std::uint64_t &column,\n                        const char *&cursor, const char *end,\n                        const bool at_least_one) -> void {\n  using CharT = typename JSON::Char;\n  bool found{false};\n  while (cursor < end && *cursor >= internal::token_number_zero<CharT> &&\n         *cursor <= internal::token_number_nine<CharT>) {\n    found = true;\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n  }\n  if (at_least_one && !found) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n}\n\ntemplate <bool TrackPositions>\ninline auto scan_number(const std::uint64_t line, std::uint64_t &column,\n                        const char *&cursor, const char *end, const char first)\n    -> void {\n  using CharT = typename JSON::Char;\n  if (first == internal::token_number_minus<CharT>) {\n    if (cursor >= end || *cursor < internal::token_number_zero<CharT> ||\n        *cursor > internal::token_number_nine<CharT>) [[unlikely]] {\n      if constexpr (TrackPositions) {\n        column += 1;\n      }\n      throw JSONParseError(line, column);\n    }\n  }\n\n  const char int_start{first == internal::token_number_minus<CharT> ? *cursor\n                                                                    : first};\n  if (first == internal::token_number_minus<CharT>) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n  }\n\n  if (int_start == internal::token_number_zero<CharT>) {\n    if (cursor < end && *cursor >= internal::token_number_zero<CharT> &&\n        *cursor <= internal::token_number_nine<CharT>) [[unlikely]] {\n      if constexpr (TrackPositions) {\n        column += 1;\n      }\n      throw JSONParseError(line, column);\n    }\n  } else {\n    scan_digits<TrackPositions>(line, column, cursor, end, false);\n  }\n\n  if (cursor < end && *cursor == internal::token_number_decimal_point<CharT>) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n    scan_digits<TrackPositions>(line, column, cursor, end, true);\n  }\n\n  if (cursor < end &&\n      (*cursor == internal::token_number_exponent_lowercase<CharT> ||\n       *cursor == internal::token_number_exponent_uppercase<CharT>)) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n    if (cursor < end && (*cursor == internal::token_number_plus<CharT> ||\n                         *cursor == internal::token_number_minus<CharT>)) {\n      if constexpr (TrackPositions) {\n        column += 1;\n      }\n      cursor++;\n    }\n    scan_digits<TrackPositions>(line, column, cursor, end, true);\n  }\n}\n\n} // namespace internal\n\n// NOLINTBEGIN(cppcoreguidelines-avoid-goto)\n\ntemplate <bool TrackPositions>\ninline auto scan_json(const char *&cursor, const char *end,\n                      const char *buffer_start, std::uint64_t &line,\n                      std::uint64_t &column, std::vector<TapeEntry> &tape)\n    -> void {\n  struct ContainerFrame {\n    std::size_t tape_index;\n    std::uint32_t child_count;\n  };\n\n  using CharT = typename JSON::Char;\n  char character = 0;\n  std::vector<ContainerFrame> container_stack;\n  container_stack.reserve(32);\n\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n\n  {\n    const auto value_line{line};\n    const auto value_column{column};\n    switch (character) {\n      case internal::token_true<CharT>:\n        internal::scan_true<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column});\n        return;\n      case internal::token_false<CharT>:\n        internal::scan_false<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column});\n        return;\n      case internal::token_null<CharT>:\n        internal::scan_null<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column});\n        return;\n      case internal::token_string_quote<CharT>: {\n        const auto string_start{\n            static_cast<std::uint32_t>(cursor - buffer_start)};\n        internal::scan_string<TrackPositions>(line, column, cursor, end);\n        const auto string_length{static_cast<std::uint32_t>(\n            cursor - buffer_start - string_start - 1)};\n        tape.push_back({TapeType::String, string_start, string_length, 0,\n                        value_line, value_column});\n        return;\n      }\n      case internal::token_array_begin<CharT>:\n        goto do_scan_array;\n      case internal::token_object_begin<CharT>:\n        goto do_scan_object;\n      case internal::token_number_minus<CharT>:\n      case internal::token_number_zero<CharT>:\n      case internal::token_number_one<CharT>:\n      case internal::token_number_two<CharT>:\n      case internal::token_number_three<CharT>:\n      case internal::token_number_four<CharT>:\n      case internal::token_number_five<CharT>:\n      case internal::token_number_six<CharT>:\n      case internal::token_number_seven<CharT>:\n      case internal::token_number_eight<CharT>:\n      case internal::token_number_nine<CharT>: {\n        const auto number_start{\n            static_cast<std::uint32_t>(cursor - buffer_start - 1)};\n        internal::scan_number<TrackPositions>(line, column, cursor, end,\n                                              character);\n        const auto number_length{\n            static_cast<std::uint32_t>(cursor - buffer_start - number_start)};\n        tape.push_back({TapeType::Number, number_start, number_length, 0,\n                        value_line, value_column});\n        return;\n      }\n      default:\n        [[unlikely]] throw JSONParseError(line, column);\n    }\n  }\n\n  /*\n   * Scan an array\n   */\n\ndo_scan_array: {\n  const auto start_index{tape.size()};\n  tape.push_back({TapeType::ArrayStart, 0, 0, 0, line, column});\n  container_stack.push_back({start_index, 0});\n\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n\n  if (*cursor == internal::token_array_end<CharT>) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n    tape[start_index].count = 0;\n    tape.push_back({TapeType::ArrayEnd, 0, 0, 0, line, column});\n    container_stack.pop_back();\n    goto do_scan_container_end;\n  }\n\n  goto do_scan_array_item;\n}\n\ndo_scan_array_item:\n  assert(!container_stack.empty());\n  container_stack.back().child_count++;\n\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n\n  {\n    const auto value_line{line};\n    const auto value_column{column};\n    switch (character) {\n      case internal::token_array_begin<CharT>:\n        goto do_scan_array;\n      case internal::token_object_begin<CharT>:\n        goto do_scan_object;\n      case internal::token_true<CharT>:\n        internal::scan_true<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column});\n        goto do_scan_array_item_separator;\n      case internal::token_false<CharT>:\n        internal::scan_false<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column});\n        goto do_scan_array_item_separator;\n      case internal::token_null<CharT>:\n        internal::scan_null<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column});\n        goto do_scan_array_item_separator;\n      case internal::token_string_quote<CharT>: {\n        const auto string_start{\n            static_cast<std::uint32_t>(cursor - buffer_start)};\n        internal::scan_string<TrackPositions>(line, column, cursor, end);\n        const auto string_length{static_cast<std::uint32_t>(\n            cursor - buffer_start - string_start - 1)};\n        tape.push_back({TapeType::String, string_start, string_length, 0,\n                        value_line, value_column});\n        goto do_scan_array_item_separator;\n      }\n      case internal::token_number_minus<CharT>:\n      case internal::token_number_zero<CharT>:\n      case internal::token_number_one<CharT>:\n      case internal::token_number_two<CharT>:\n      case internal::token_number_three<CharT>:\n      case internal::token_number_four<CharT>:\n      case internal::token_number_five<CharT>:\n      case internal::token_number_six<CharT>:\n      case internal::token_number_seven<CharT>:\n      case internal::token_number_eight<CharT>:\n      case internal::token_number_nine<CharT>: {\n        const auto number_start{\n            static_cast<std::uint32_t>(cursor - buffer_start - 1)};\n        internal::scan_number<TrackPositions>(line, column, cursor, end,\n                                              character);\n        const auto number_length{\n            static_cast<std::uint32_t>(cursor - buffer_start - number_start)};\n        tape.push_back({TapeType::Number, number_start, number_length, 0,\n                        value_line, value_column});\n        goto do_scan_array_item_separator;\n      }\n      default:\n        [[unlikely]] throw JSONParseError(line, column);\n    }\n  }\n\ndo_scan_array_item_separator:\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n  switch (character) {\n    case internal::token_array_delimiter<CharT>:\n      goto do_scan_array_item;\n    case internal::token_array_end<CharT>: {\n      assert(!container_stack.empty());\n      auto &frame{container_stack.back()};\n      tape[frame.tape_index].count = frame.child_count;\n      tape.push_back({TapeType::ArrayEnd, 0, 0, 0, line, column});\n      container_stack.pop_back();\n      goto do_scan_container_end;\n    }\n    default:\n      [[unlikely]] throw JSONParseError(line, column);\n  }\n\n  /*\n   * Scan an object\n   */\n\ndo_scan_object: {\n  const auto start_index{tape.size()};\n  tape.push_back({TapeType::ObjectStart, 0, 0, 0, line, column});\n  container_stack.push_back({start_index, 0});\n\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n\n  if (*cursor == internal::token_object_end<CharT>) {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    cursor++;\n    tape[start_index].count = 0;\n    tape.push_back({TapeType::ObjectEnd, 0, 0, 0, line, column});\n    container_stack.pop_back();\n    goto do_scan_container_end;\n  }\n\n  goto do_scan_object_key;\n}\n\ndo_scan_object_key:\n  assert(!container_stack.empty());\n  container_stack.back().child_count++;\n\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n  switch (character) {\n    case internal::token_string_quote<CharT>: {\n      const auto key_start{static_cast<std::uint32_t>(cursor - buffer_start)};\n      const auto key_line{line};\n      const auto key_column{column};\n      internal::scan_string<TrackPositions>(line, column, cursor, end);\n      const auto key_length{\n          static_cast<std::uint32_t>(cursor - buffer_start - key_start - 1)};\n      tape.push_back(\n          {TapeType::Key, key_start, key_length, 0, key_line, key_column});\n      goto do_scan_object_separator;\n    }\n    default:\n      [[unlikely]] throw JSONParseError(line, column);\n  }\n\ndo_scan_object_separator:\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n  switch (character) {\n    case internal::token_object_key_delimiter<CharT>:\n      goto do_scan_object_value;\n    default:\n      [[unlikely]] throw JSONParseError(line, column);\n  }\n\ndo_scan_object_value:\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n\n  {\n    const auto value_line{line};\n    const auto value_column{column};\n    switch (character) {\n      case internal::token_array_begin<CharT>:\n        goto do_scan_array;\n      case internal::token_object_begin<CharT>:\n        goto do_scan_object;\n      case internal::token_true<CharT>:\n        internal::scan_true<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::True, 0, 0, 0, value_line, value_column});\n        goto do_scan_object_property_end;\n      case internal::token_false<CharT>:\n        internal::scan_false<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::False, 0, 0, 0, value_line, value_column});\n        goto do_scan_object_property_end;\n      case internal::token_null<CharT>:\n        internal::scan_null<TrackPositions>(line, column, cursor, end);\n        tape.push_back({TapeType::Null, 0, 0, 0, value_line, value_column});\n        goto do_scan_object_property_end;\n      case internal::token_string_quote<CharT>: {\n        const auto string_start{\n            static_cast<std::uint32_t>(cursor - buffer_start)};\n        internal::scan_string<TrackPositions>(line, column, cursor, end);\n        const auto string_length{static_cast<std::uint32_t>(\n            cursor - buffer_start - string_start - 1)};\n        tape.push_back({TapeType::String, string_start, string_length, 0,\n                        value_line, value_column});\n        goto do_scan_object_property_end;\n      }\n      case internal::token_number_minus<CharT>:\n      case internal::token_number_zero<CharT>:\n      case internal::token_number_one<CharT>:\n      case internal::token_number_two<CharT>:\n      case internal::token_number_three<CharT>:\n      case internal::token_number_four<CharT>:\n      case internal::token_number_five<CharT>:\n      case internal::token_number_six<CharT>:\n      case internal::token_number_seven<CharT>:\n      case internal::token_number_eight<CharT>:\n      case internal::token_number_nine<CharT>: {\n        const auto number_start{\n            static_cast<std::uint32_t>(cursor - buffer_start - 1)};\n        internal::scan_number<TrackPositions>(line, column, cursor, end,\n                                              character);\n        const auto number_length{\n            static_cast<std::uint32_t>(cursor - buffer_start - number_start)};\n        tape.push_back({TapeType::Number, number_start, number_length, 0,\n                        value_line, value_column});\n        goto do_scan_object_property_end;\n      }\n      default:\n        [[unlikely]] throw JSONParseError(line, column);\n    }\n  }\n\ndo_scan_object_property_end:\n  internal::skip_whitespace<TrackPositions>(cursor, end, line, column);\n  if (cursor >= end) [[unlikely]] {\n    if constexpr (TrackPositions) {\n      column += 1;\n    }\n    throw JSONParseError(line, column);\n  }\n  if constexpr (TrackPositions) {\n    column += 1;\n  }\n  character = *cursor++;\n  switch (character) {\n    case internal::token_object_delimiter<CharT>:\n      goto do_scan_object_key;\n    case internal::token_object_end<CharT>: {\n      assert(!container_stack.empty());\n      auto &frame{container_stack.back()};\n      tape[frame.tape_index].count = frame.child_count;\n      tape.push_back({TapeType::ObjectEnd, 0, 0, 0, line, column});\n      container_stack.pop_back();\n      goto do_scan_container_end;\n    }\n    default:\n      [[unlikely]] throw JSONParseError(line, column);\n  }\n\ndo_scan_container_end:\n  if (container_stack.empty()) {\n    return;\n  }\n\n  if (tape[container_stack.back().tape_index].type == TapeType::ArrayStart) {\n    goto do_scan_array_item_separator;\n  } else {\n    goto do_scan_object_property_end;\n  }\n}\n\n// NOLINTEND(cppcoreguidelines-avoid-goto)\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/json/stringify.h",
    "content": "#ifndef SOURCEMETA_CORE_JSON_STRINGIFY_H_\n#define SOURCEMETA_CORE_JSON_STRINGIFY_H_\n\n#include <sourcemeta/core/json_value.h>\n\n#include \"grammar.h\"\n\n#include <algorithm> // std::transform, std::sort\n#include <array>     // std::array\n#include <cassert>   // assert\n#include <charconv>  // std::to_chars\n#include <cstddef>   // std::size_t\n#include <cstdint>   // std::int64_t\n#include <iomanip>   // std::setprecision\n#include <ios>       // std::noshowpoint, std::fixed\n#include <iterator>  // std::next, std::cbegin, std::cend, std::back_inserter\n#include <ostream>   // std::basic_ostream\n#include <sstream>   // std::ostringstream\n#include <string>    // std::basic_string\n#include <vector>    // std::vector\n\nnamespace sourcemeta::core::internal {\nconstexpr auto LINE_WIDTH{80};\ntemplate <typename CharT, typename Traits>\nauto indent(std::basic_ostream<CharT, Traits> &stream,\n            const std::size_t indentation, const std::size_t indent_by)\n    -> void {\n  for (std::size_t index{0}; index < indentation * indent_by; index++) {\n    stream.put(internal::token_whitespace_space<CharT>);\n  }\n}\n} // namespace sourcemeta::core::internal\n\nnamespace sourcemeta::core {\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const std::nullptr_t,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  stream.write(\n      internal::constant_null<typename JSON::Char, typename JSON::CharTraits>.data(),\n      internal::constant_null<typename JSON::Char, typename JSON::CharTraits>.size());\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const bool value,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  if (value) {\n    stream.write(\n        internal::constant_true<typename JSON::Char, typename JSON::CharTraits>.data(),\n        internal::constant_true<typename JSON::Char, typename JSON::CharTraits>.size());\n  } else {\n    stream.write(\n        internal::constant_false<typename JSON::Char, typename JSON::CharTraits>.data(),\n        internal::constant_false<typename JSON::Char, typename JSON::CharTraits>.size());\n  }\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const std::int64_t value,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  std::array<char, 20> buffer{};\n  const auto [end_pointer, error_code] =\n      std::to_chars(buffer.data(), buffer.data() + buffer.size(), value);\n  stream.write(buffer.data(),\n               static_cast<typename std::basic_ostream<\n                   typename JSON::Char, typename JSON::CharTraits>::int_type>(\n                   end_pointer - buffer.data()));\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const double value, const bool is_integral,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  if (value == static_cast<double>(0.0)) {\n    stream.write(\"0.0\", 3);\n  } else if (is_integral) {\n    const auto flags{stream.flags()};\n    const auto precision{stream.precision()};\n    stream << std::fixed << std::setprecision(1) << value;\n    stream.flags(flags);\n    stream.precision(precision);\n  } else {\n    std::array<char, 64> buffer{};\n    const auto result{\n        std::to_chars(buffer.data(), buffer.data() + buffer.size(), value)};\n    // This can't realistically happen on production given the buffer size\n    assert(result.ec == std::errc{});\n    stream.write(buffer.data(), result.ptr - buffer.data());\n  }\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const typename JSON::String &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  stream.put(internal::token_string_quote<typename JSON::Char>);\n  for (const auto character : document) {\n    switch (character) {\n      case internal::token_string_escape<typename JSON::Char>:\n      case internal::token_string_quote<typename JSON::Char>:\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(character);\n        break;\n\n      // See https://www.asciitable.com\n      // See https://www.rfc-editor.org/rfc/rfc4627#section-2.5\n\n      // Null\n      case '\\u0000':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        break;\n      // Start of heading\n      case '\\u0001':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        break;\n      // Start of text\n      case '\\u0002':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('2');\n        break;\n      // End of text\n      case '\\u0003':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('3');\n        break;\n      // End of transmission\n      case '\\u0004':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('4');\n        break;\n      // Enquiry\n      case '\\u0005':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('5');\n        break;\n      // Acknowledge\n      case '\\u0006':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('6');\n        break;\n      // Bell\n      case '\\u0007':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('7');\n        break;\n      // Backspace\n      case '\\b':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(\n            internal::token_string_escape_backspace<typename JSON::Char>);\n        break;\n      // Horizontal tab\n      case '\\t':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(\n            internal::token_string_escape_tabulation<typename JSON::Char>);\n        break;\n      // Line feed\n      case '\\n':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(\n            internal::token_string_escape_line_feed<typename JSON::Char>);\n        break;\n      // Vertical tab\n      case '\\u000B':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('B');\n        break;\n      // Form feed\n      case '\\f':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(\n            internal::token_string_escape_form_feed<typename JSON::Char>);\n        break;\n      // Carriage return\n      case '\\r':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(\n            internal::token_string_escape_carriage_return<typename JSON::Char>);\n        break;\n      // Shift out\n      case '\\u000E':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('E');\n        break;\n      // Shift in\n      case '\\u000F':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('0');\n        stream.put('F');\n        break;\n      // Data link escape\n      case '\\u0010':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('0');\n        break;\n      // Device control 1\n      case '\\u0011':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('1');\n        break;\n      // Device control 2\n      case '\\u0012':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('2');\n        break;\n      // Device control 3\n      case '\\u0013':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('3');\n        break;\n      // Device control 4\n      case '\\u0014':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('4');\n        break;\n      // Negative acknowledge\n      case '\\u0015':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('5');\n        break;\n      // Synchronous idle\n      case '\\u0016':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('6');\n        break;\n      // End of transmission block\n      case '\\u0017':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('7');\n        break;\n      // Cancel\n      case '\\u0018':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('8');\n        break;\n      // End of medium\n      case '\\u0019':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('9');\n        break;\n      // Substitute\n      case '\\u001A':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('A');\n        break;\n      // Escape\n      case '\\u001B':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('B');\n        break;\n      // File separator\n      case '\\u001C':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('C');\n        break;\n      // Group separator\n      case '\\u001D':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('D');\n        break;\n      // Record separator\n      case '\\u001E':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('E');\n        break;\n      // Unit separator\n      case '\\u001F':\n        stream.put(internal::token_string_escape<typename JSON::Char>);\n        stream.put(internal::token_string_escape_unicode<typename JSON::Char>);\n        stream.put('0');\n        stream.put('0');\n        stream.put('1');\n        stream.put('F');\n        break;\n      default:\n        stream.put(character);\n    }\n  }\n\n  stream.put(internal::token_string_quote<typename JSON::Char>);\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const typename JSON::Array &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  stream.put(internal::token_array_begin<typename JSON::Char>);\n  const auto end{std::cend(document)};\n  for (auto iterator = std::cbegin(document); iterator != end; ++iterator) {\n    stringify<Allocator>(*iterator, stream);\n    if (std::next(iterator) != end) {\n      stream.put(internal::token_array_delimiter<typename JSON::Char>);\n    }\n  }\n\n  stream.put(internal::token_array_end<typename JSON::Char>);\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const typename JSON::Object &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  stream.put(internal::token_object_begin<typename JSON::Char>);\n\n  const auto end{std::cend(document)};\n  for (auto iterator = std::cbegin(document); iterator != end; ++iterator) {\n    stringify<Allocator>(iterator->first, stream);\n    stream.put(internal::token_object_key_delimiter<typename JSON::Char>);\n    stringify<Allocator>(iterator->second, stream);\n    if (std::next(iterator) != end) {\n      stream.put(internal::token_object_delimiter<typename JSON::Char>);\n    }\n  }\n\n  stream.put(internal::token_object_end<typename JSON::Char>);\n}\n\ntemplate <template <typename T> typename Allocator>\nauto prettify(\n    const typename JSON::Object &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream,\n    const std::size_t, const std::size_t) -> void;\n\ntemplate <template <typename T> typename Allocator>\nauto prettify(\n    const typename JSON::Array &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream,\n    const std::size_t indentation, const std::size_t indent_by,\n    const std::size_t property_size) -> void {\n  const auto end{std::cend(document)};\n  const auto effective_indentation{(indentation * indent_by) + property_size};\n\n  // Attempt to print arrays in a single line if possible\n\n  bool prettify_in_place{effective_indentation < internal::LINE_WIDTH};\n  std::ostringstream inplace;\n  inplace.put(internal::token_array_begin<typename JSON::Char>);\n  for (auto iterator = std::cbegin(document); iterator != end; ++iterator) {\n    if (iterator->is_object() || iterator->is_array()) {\n      prettify_in_place = false;\n      break;\n    }\n\n    inplace.put(internal::token_whitespace_space<typename JSON::Char>);\n    prettify<Allocator>(*iterator, inplace, indentation, indent_by);\n    if (std::next(iterator) == end) {\n      inplace.put(internal::token_whitespace_space<typename JSON::Char>);\n    } else {\n      inplace.put(internal::token_array_delimiter<typename JSON::Char>);\n    }\n\n    if (inplace.str().size() + effective_indentation >= internal::LINE_WIDTH) {\n      prettify_in_place = false;\n      break;\n    }\n  }\n\n  if (prettify_in_place) {\n    stream << inplace.str();\n    stream.put(internal::token_array_end<typename JSON::Char>);\n    return;\n  }\n\n  stream.put(internal::token_array_begin<typename JSON::Char>);\n  for (auto iterator = std::cbegin(document); iterator != end; ++iterator) {\n    stream.put(internal::token_whitespace_line_feed<typename JSON::Char>);\n    internal::indent(stream, indentation + 1, indent_by);\n    prettify<Allocator>(*iterator, stream, indentation + 1, indent_by);\n    if (std::next(iterator) == end) {\n      stream.put(internal::token_whitespace_line_feed<typename JSON::Char>);\n    } else {\n      stream.put(internal::token_array_delimiter<typename JSON::Char>);\n    }\n  }\n\n  if (std::cbegin(document) != end) {\n    internal::indent(stream, indentation, indent_by);\n  }\n\n  stream.put(internal::token_array_end<typename JSON::Char>);\n}\n\ntemplate <template <typename T> typename Allocator>\nauto prettify(\n    const typename JSON::Object &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream,\n    const std::size_t indentation, const std::size_t indent_by) -> void {\n  stream.put(internal::token_object_begin<typename JSON::Char>);\n\n  const auto end{std::cend(document)};\n  for (auto iterator = std::cbegin(document); iterator != end; ++iterator) {\n    stream.put(internal::token_whitespace_line_feed<typename JSON::Char>);\n    internal::indent(stream, indentation + 1, indent_by);\n    const auto current_position{stream.tellp()};\n    stringify<Allocator>(iterator->first, stream);\n    stream.put(internal::token_object_key_delimiter<typename JSON::Char>);\n    stream.put(internal::token_whitespace_space<typename JSON::Char>);\n    prettify<Allocator>(\n        iterator->second, stream, indentation + 1, indent_by,\n        // Pass the length of the property name as encoded in JSON\n        // to help determine the actual current column\n        static_cast<std::size_t>(stream.tellp() - current_position));\n    if (std::next(iterator) == end) {\n      stream.put(internal::token_whitespace_line_feed<typename JSON::Char>);\n    } else {\n      stream.put(internal::token_object_delimiter<typename JSON::Char>);\n    }\n  }\n\n  if (std::cbegin(document) != std::cend(document)) {\n    internal::indent(stream, indentation, indent_by);\n  }\n\n  stream.put(internal::token_object_end<typename JSON::Char>);\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify(\n    const JSON &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream)\n    -> void {\n  switch (document.type()) {\n    case JSON::Type::Null:\n      stringify<Allocator>(nullptr, stream);\n      break;\n    case JSON::Type::Boolean:\n      stringify<Allocator>(document.to_boolean(), stream);\n      break;\n    case JSON::Type::Integer:\n      stringify<Allocator>(document.to_integer(), stream);\n      break;\n    case JSON::Type::Real:\n      stringify<Allocator>(document.to_real(), document.is_integral(), stream);\n      break;\n    case JSON::Type::String:\n      stringify<Allocator>(document.to_string(), stream);\n      break;\n    case JSON::Type::Array:\n      stringify<Allocator>(document.as_array(), stream);\n      break;\n    case JSON::Type::Object:\n      stringify<Allocator>(document.as_object(), stream);\n      break;\n    case JSON::Type::Decimal:\n      // We ALWAYS parse numbers with exponents as decimal, so if we don't\n      // preserve the exponent, we might end up incorrectly treating the number\n      // when parsing it again\n      stream << document.to_decimal().to_scientific_string();\n      break;\n  }\n}\n\n// TODO: Get rid of unused Allocator templates in this file\n\ntemplate <template <typename T> typename Allocator>\nauto prettify(\n    const JSON &document,\n    std::basic_ostream<typename JSON::Char, typename JSON::CharTraits> &stream,\n    const std::size_t indentation = 0, const std::size_t indent_by = 2,\n    const std::size_t property_size = 0) -> void {\n  switch (document.type()) {\n    case JSON::Type::Null:\n      stringify<Allocator>(nullptr, stream);\n      break;\n    case JSON::Type::Boolean:\n      stringify<Allocator>(document.to_boolean(), stream);\n      break;\n    case JSON::Type::Integer:\n      stringify<Allocator>(document.to_integer(), stream);\n      break;\n    case JSON::Type::Real:\n      stringify<Allocator>(document.to_real(), document.is_integral(), stream);\n      break;\n    case JSON::Type::String:\n      stringify<Allocator>(document.to_string(), stream);\n      break;\n    case JSON::Type::Array:\n      prettify<Allocator>(document.as_array(), stream, indentation, indent_by,\n                          property_size);\n      break;\n    case JSON::Type::Object:\n      prettify<Allocator>(document.as_object(), stream, indentation, indent_by);\n      break;\n    case JSON::Type::Decimal:\n      // We ALWAYS parse numbers with exponents as decimal, so if we don't\n      // preserve the exponent, we might end up incorrectly treating the number\n      // when parsing it again\n      stream << document.to_decimal().to_scientific_string();\n      break;\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME jsonl\n  PRIVATE_HEADERS iterator.h\n  SOURCES jsonl.cc iterator.cc grammar.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME jsonl)\nendif()\n\ntarget_link_libraries(sourcemeta_core_jsonl PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_core_jsonl PRIVATE\n  sourcemeta::core::gzip)\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/grammar.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONL_GRAMMAR_H_\n#define SOURCEMETA_CORE_JSONL_GRAMMAR_H_\n\nnamespace sourcemeta::core::internal {\ntemplate <typename CharT>\nstatic constexpr CharT token_jsonl_line_feed{'\\u000A'};\n\n// Whitespace is any sequence of one or more of the following code points:\n// character tabulation (U+0009), line feed (U+000A), carriage return (U+000D),\n// and space (U+0020).\n// See\n// https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\ntemplate <typename CharT>\nstatic constexpr CharT token_jsonl_whitespace_tabulation{'\\u0009'};\ntemplate <typename CharT>\nstatic constexpr CharT token_jsonl_whitespace_carriage_return{'\\u000D'};\ntemplate <typename CharT>\nstatic constexpr CharT token_jsonl_whitespace_space{'\\u0020'};\n\n} // namespace sourcemeta::core::internal\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/include/sourcemeta/core/jsonl.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONL_H_\n#define SOURCEMETA_CORE_JSONL_H_\n\n#ifndef SOURCEMETA_CORE_JSONL_EXPORT\n#include <sourcemeta/core/jsonl_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/jsonl_iterator.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cstdint> // std::uint8_t\n#include <istream> // std::basic_istream\n#include <memory>  // std::unique_ptr\n\n/// @defgroup jsonl JSONL\n/// @brief A JSON Lines (https://jsonlines.org) implementation with iterator\n/// support. Each line in a JSONL stream must be a complete, valid JSON value.\n/// Lines are separated by newline characters (U+000A). Multi-line JSON values\n/// are not supported, as per the JSONL specification.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonl.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonl\nclass SOURCEMETA_CORE_JSONL_EXPORT JSONL {\npublic:\n  /// The mode of operation for the JSONL parser\n  enum class Mode : std::uint8_t {\n    /// The input stream contains raw JSONL text\n    Raw,\n    /// The input stream contains gzip-compressed JSONL data\n    GZIP\n  };\n\n  /// Parse a JSONL document from a C++ standard input stream using a standard\n  /// read-only C++ forward iterator interface. An optional mode parameter\n  /// controls whether the input is treated as raw text or gzip-compressed\n  /// data. For example, you can parse a JSONL document and prettify each of\n  /// its rows as follows:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonl.h>\n  /// #include <cassert>\n  /// #include <sstream>\n  /// #include <iostream>\n  ///\n  /// std::istringstream stream{\n  ///   \"{ \\\"foo\\\": 1 }\\n{ \\\"bar\\\": 2 }\\n{ \\\"baz\\\": 3 }\"};\n  ///\n  /// for (const auto &document : sourcemeta::core::JSONL{stream}) {\n  ///   assert(document.is_object());\n  ///   sourcemeta::core::prettify(document, std::cout);\n  ///   std::cout << '\\n';\n  /// }\n  /// ```\n  ///\n  /// If parsing fails, sourcemeta::core::JSONParseError will be thrown.\n  JSONL(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n        Mode mode = Mode::Raw);\n  ~JSONL();\n\n  JSONL(const JSONL &) = delete;\n  auto operator=(const JSONL &) -> JSONL & = delete;\n  JSONL(JSONL &&) = delete;\n  auto operator=(JSONL &&) -> JSONL & = delete;\n\n  using const_iterator = ConstJSONLIterator;\n  auto begin() -> const_iterator;\n  auto end() -> const_iterator;\n  auto cbegin() -> const_iterator;\n  auto cend() -> const_iterator;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::basic_istream<JSON::Char, JSON::CharTraits> *stream;\n  struct Internal;\n  std::unique_ptr<Internal> internal;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/include/sourcemeta/core/jsonl_iterator.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONL_ITERATOR_H_\n#define SOURCEMETA_CORE_JSONL_ITERATOR_H_\n\n#ifndef SOURCEMETA_CORE_JSONL_EXPORT\n#include <sourcemeta/core/jsonl_export.h>\n#endif\n\n#include <sourcemeta/core/json_value.h>\n\n#include <cstddef>  // std::ptrdiff_t\n#include <cstdint>  // std::uint64_t\n#include <istream>  // std::basic_istream\n#include <iterator> // std::forward_iterator_tag\n#include <memory>   // std::unique_ptr\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonl\n/// A forward iterator to parse JSON documents out of a JSON Lines stream.\nclass SOURCEMETA_CORE_JSONL_EXPORT ConstJSONLIterator {\npublic:\n  ConstJSONLIterator(std::basic_istream<JSON::Char, JSON::CharTraits> *stream);\n  ~ConstJSONLIterator();\n  using iterator_category = std::forward_iterator_tag;\n  using difference_type = std::ptrdiff_t;\n  using value_type = JSON;\n  using pointer = const value_type *;\n  using reference = const value_type &;\n\n  auto operator*() const -> reference;\n  auto operator->() const -> pointer;\n  auto operator++() -> ConstJSONLIterator &;\n\n  SOURCEMETA_CORE_JSONL_EXPORT friend auto\n  operator==(const ConstJSONLIterator &left, const ConstJSONLIterator &right)\n      -> bool;\n\nprivate:\n  std::uint64_t line{0};\n  std::uint64_t column{0};\n  auto parse_next() -> JSON;\n  std::basic_istream<JSON::Char, JSON::CharTraits> *data{};\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  // Use PIMPL idiom to hide internal details, mainly\n  // templated members, which are tricky to DLL-export.\n  struct Internal;\n  std::unique_ptr<Internal> internal{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/iterator.cc",
    "content": "#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/json_value.h>\n#include <sourcemeta/core/jsonl_iterator.h>\n\n#include \"grammar.h\"\n\n#include <cassert> // assert\n#include <istream> // std::basic_istream\n#include <string>  // std::basic_string\n\nnamespace sourcemeta::core {\n\nstruct ConstJSONLIterator::Internal {\n  sourcemeta::core::JSON current;\n};\n\n/*\n * Parsing\n */\n\nauto ConstJSONLIterator::parse_next() -> JSON {\n  // Each line in a JSONL stream is a complete JSON value.\n  // See https://jsonlines.org\n  std::basic_string<JSON::Char, JSON::CharTraits> row;\n  while (this->data && std::getline(*this->data, row)) {\n    this->line += 1;\n    this->column = 0;\n\n    // Strip trailing carriage return for \\r\\n line endings\n    if (!row.empty() &&\n        row.back() ==\n            internal::token_jsonl_whitespace_carriage_return<JSON::Char>) {\n      row.pop_back();\n    }\n\n    // Skip whitespace-only lines\n    bool has_content{false};\n    for (const auto character : row) {\n      if (character != internal::token_jsonl_whitespace_space<JSON::Char> &&\n          character !=\n              internal::token_jsonl_whitespace_tabulation<JSON::Char> &&\n          character !=\n              internal::token_jsonl_whitespace_carriage_return<JSON::Char>) {\n        has_content = true;\n        break;\n      }\n    }\n\n    if (!has_content) {\n      continue;\n    }\n\n    auto result{parse_json(row, this->line, this->column)};\n\n    // Verify that the remainder of the line is only whitespace\n    for (auto index{static_cast<std::size_t>(this->column)}; index < row.size();\n         ++index) {\n      if (row[index] != internal::token_jsonl_whitespace_space<JSON::Char> &&\n          row[index] !=\n              internal::token_jsonl_whitespace_tabulation<JSON::Char> &&\n          row[index] !=\n              internal::token_jsonl_whitespace_carriage_return<JSON::Char>) {\n        this->column = static_cast<std::uint64_t>(index) + 1;\n        throw JSONParseError(this->line, this->column);\n      }\n    }\n\n    return result;\n  }\n\n  this->data = nullptr;\n  return JSON{nullptr};\n}\n\nauto ConstJSONLIterator::operator++() -> ConstJSONLIterator & {\n  assert(this->data);\n  this->internal->current = this->parse_next();\n  return *this;\n}\n\n/*\n * Miscellaneous\n */\n\nConstJSONLIterator::ConstJSONLIterator(\n    std::basic_istream<JSON::Char, JSON::CharTraits> *stream)\n    : data{stream}, internal{new Internal({this->parse_next()})} {}\n\nConstJSONLIterator::~ConstJSONLIterator() = default;\n\nauto operator==(const ConstJSONLIterator &left, const ConstJSONLIterator &right)\n    -> bool {\n  return (!left.data && !right.data) ||\n         (left.data && right.data &&\n          left.internal->current == right.internal->current);\n};\n\nauto ConstJSONLIterator::operator*() const -> ConstJSONLIterator::reference {\n  assert(this->data);\n  return this->internal->current;\n}\n\nauto ConstJSONLIterator::operator->() const -> ConstJSONLIterator::pointer {\n  assert(this->data);\n  return &(this->internal->current);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonl/jsonl.cc",
    "content": "#include <sourcemeta/core/jsonl.h>\n\n#include <sourcemeta/core/gzip.h>\n\n#include <istream> // std::basic_istream, std::istream\n#include <memory>  // std::make_unique, std::unique_ptr\n\nnamespace sourcemeta::core {\n\nstruct JSONL::Internal {\n  std::unique_ptr<GZIPStreamBuffer> streambuf;\n  std::unique_ptr<std::istream> decompressed_stream;\n};\n\nJSONL::JSONL(std::basic_istream<JSON::Char, JSON::CharTraits> &input,\n             const Mode mode)\n    : stream{&input}, internal{std::make_unique<Internal>()} {\n  if (mode == Mode::GZIP) {\n    this->internal->streambuf = std::make_unique<GZIPStreamBuffer>(input);\n    this->internal->decompressed_stream =\n        std::make_unique<std::istream>(this->internal->streambuf.get());\n    this->internal->decompressed_stream->exceptions(std::istream::badbit);\n    this->stream = this->internal->decompressed_stream.get();\n  }\n}\n\nJSONL::~JSONL() = default;\n\nauto JSONL::begin() -> JSONL::const_iterator { return {this->stream}; }\nauto JSONL::end() -> JSONL::const_iterator { return {nullptr}; }\nauto JSONL::cbegin() -> JSONL::const_iterator { return {this->stream}; }\nauto JSONL::cend() -> JSONL::const_iterator { return {nullptr}; }\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME jsonpointer\n  PRIVATE_HEADERS pointer.h position.h error.h token.h\n    walker.h\n  SOURCES jsonpointer.cc stringify.h parser.h grammar.h position.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME jsonpointer)\nendif()\n\ntarget_link_libraries(sourcemeta_core_jsonpointer PUBLIC\n  sourcemeta::core::uri)\ntarget_link_libraries(sourcemeta_core_jsonpointer PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_core_jsonpointer PUBLIC\n  sourcemeta::core::regex)\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/grammar.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_GRAMMAR_H_\n#define SOURCEMETA_CORE_JSONPOINTER_GRAMMAR_H_\n\nnamespace sourcemeta::core::internal {\ntemplate <typename CharT> static constexpr CharT token_pointer_slash{'\\u002F'};\ntemplate <typename CharT> static constexpr CharT token_pointer_tilde{'\\u007E'};\ntemplate <typename CharT> static constexpr CharT token_pointer_zero{'\\u0030'};\ntemplate <typename CharT> static constexpr CharT token_pointer_one{'\\u0031'};\ntemplate <typename CharT> static constexpr CharT token_pointer_quote{'\\u0022'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_unicode{'\\u0075'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_backspace{'\\u0062'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_form_feed{'\\u0066'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_line_feed{'\\u006E'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_carriage_return{'\\u0072'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_escape_tab{'\\u0074'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_reverse_solidus{'\\u005C'};\n\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_zero{'\\u0030'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_one{'\\u0031'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_two{'\\u0032'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_three{'\\u0033'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_four{'\\u0034'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_five{'\\u0035'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_six{'\\u0036'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_seven{'\\u0037'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_eight{'\\u0038'};\ntemplate <typename CharT>\nstatic constexpr CharT token_pointer_number_nine{'\\u0039'};\n} // namespace sourcemeta::core::internal\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_H_\n#define SOURCEMETA_CORE_JSONPOINTER_H_\n\n#ifndef SOURCEMETA_CORE_JSONPOINTER_EXPORT\n#include <sourcemeta/core/jsonpointer_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/uri.h>\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/jsonpointer_error.h>\n#include <sourcemeta/core/jsonpointer_pointer.h>\n#include <sourcemeta/core/jsonpointer_position.h>\n#include <sourcemeta/core/jsonpointer_walker.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cassert>     // assert\n#include <functional>  // std::reference_wrapper\n#include <memory>      // std::allocator\n#include <ostream>     // std::basic_ostream\n#include <string>      // std::basic_string\n#include <string_view> // std::string_view\n\n/// @defgroup jsonpointer JSON Pointer\n/// @brief A growing implementation of RFC 6901 JSON Pointer.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\nusing Pointer = GenericPointer<JSON::String, PropertyHashJSON<JSON::String>>;\n\n/// @ingroup jsonpointer\nusing WeakPointer = GenericPointer<\n    // We use this instead of a string view as the latter occupies more memory\n    std::reference_wrapper<const std::string>, PropertyHashJSON<JSON::String>>;\n\n/// @ingroup jsonpointer\n/// A global constant instance of the empty JSON Pointer.\nconst Pointer empty_pointer;\n\n/// @ingroup jsonpointer\n/// A global constant instance of the empty JSON WeakPointer.\nconst WeakPointer empty_weak_pointer;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON Pointer (`const` overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// const sourcemeta::core::Pointer pointer{1, \"bar\"};\n/// const sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document, pointer)};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(const JSON &document, const Pointer &pointer) -> const JSON &;\n\n// Constant reference parameters can accept xvalues which will be destructed\n// after the call. When the function returns such a parameter also as constant\n// reference, then the returned reference can be used after the object it refers\n// to has been destroyed.\n// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/return-const-ref-from-parameter.html\n// This overload avoids mis-uses of retuning const reference parameter as\n// constant reference.\nauto get(JSON &&document, const Pointer &pointer) -> const JSON & = delete;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON WeakPointer (`const`\n/// overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// const std::string bar = \"bar\";\n/// const sourcemeta::core::WeakPointer pointer{1, std::cref(bar)};\n/// const sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document, pointer)};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(const JSON &document, const WeakPointer &pointer) -> const JSON &;\n\n// Constant reference parameters can accept xvalues which will be destructed\n// after the call. When the function returns such a parameter also as constant\n// reference, then the returned reference can be used after the object it refers\n// to has been destroyed.\n// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/return-const-ref-from-parameter.html\n// This overload avoids mis-uses of retuning const reference parameter as\n// constant reference.\nauto get(JSON &&document, const WeakPointer &pointer) -> const JSON & = delete;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON WeakPointer (non-`const`\n/// overload). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// auto document{sourcemeta::core::parse_json(stream)};\n/// const sourcemeta::core::Pointer pointer{1, \"bar\"};\n/// sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document,\n///   sourcemeta::core::to_weak_pointer(pointer))};\n/// value = sourcemeta::core::JSON{3};\n/// assert(document.at(1).at(\"bar\").to_integer() == 3);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(JSON &document, const WeakPointer &pointer) -> JSON &;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a Pointer, returning an optional that\n/// is not set if the path does not exist in the document. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// const auto document{sourcemeta::core::parse_json(stream)};\n/// const sourcemeta::core::Pointer pointer{1, \"bar\"};\n/// const auto result{sourcemeta::core::try_get(document, pointer)};\n/// assert(result);\n/// assert(*result == document.at(1).at(\"bar\"));\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto try_get(const JSON &document, const Pointer &pointer) -> const JSON *;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a WeakPointer, returning an optional\n/// that is not set if the path does not exist in the document. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// const auto document{sourcemeta::core::parse_json(stream)};\n/// const std::string bar = \"bar\";\n/// const sourcemeta::core::WeakPointer pointer{1, std::cref(bar)};\n/// const auto result{sourcemeta::core::try_get(document, pointer)};\n/// assert(result);\n/// assert(*result == document.at(1).at(\"bar\"));\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto try_get(const JSON &document, const WeakPointer &pointer) -> const JSON *;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON Pointer (non-`const`\n/// overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n/// assert(document.at(\"foo\").to_integer() == 1);\n///\n/// const sourcemeta::core::Pointer pointer{1, \"bar\"};\n/// sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document, pointer)};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(JSON &document, const Pointer &pointer) -> JSON &;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON Pointer token (`const`\n/// overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"{ \\\"foo\\\": 1 }\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// const sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document,\n///   sourcemeta::core::Pointer{\"foo\"})};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 1);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(const JSON &document, const Pointer::Token &token) -> const JSON &;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON WeakPointer token (`const`\n/// overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"{ \\\"foo\\\": 1 }\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// const std::string foo = \"foo\";\n/// const sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document,\n///   sourcemeta::core::WeakPointer{std::cref(foo)})};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 1);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(const JSON &document, const WeakPointer::Token &token) -> const JSON &;\n\n/// @ingroup jsonpointer\n/// Get a value from a JSON document using a JSON Pointer token (non-`const`\n/// overload).\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"{ \\\"foo\\\": 1 }\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// sourcemeta::core::JSON &value{\n///   sourcemeta::core::get(document, \"bar\")};\n/// assert(value.is_integer());\n/// assert(value.to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto get(JSON &document, const Pointer::Token &token) -> JSON &;\n\n/// @ingroup jsonpointer\n/// Set a value in a JSON document using a JSON Pointer (`const` overload).\n///\n/// If the last token of the JSON Pointer is the constant `-` and the tail\n/// instance is an array, then the operation is equivalent to\n/// `sourcemeta::core::JSON::push_back`.\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"{ \\\"foo\\\": 1 }\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n/// assert(document.at(\"foo\").to_integer() == 1);\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// const sourcemeta::core::JSON value{2};\n/// sourcemeta::core::set(document, pointer, value);\n/// assert(document.at(\"foo\").to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto set(JSON &document, const Pointer &pointer, const JSON &value) -> void;\n\n/// @ingroup jsonpointer\n/// Set a value in a JSON document using a JSON Pointer (non-`const` overload).\n///\n/// If the last token of the JSON Pointer is the constant `-` and the tail\n/// instance is an array, then the operation is equivalent to\n/// `sourcemeta::core::JSON::push_back`.\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"{ \\\"foo\\\": 1 }\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// sourcemeta::core::set(document, pointer,\n///   sourcemeta::core::JSON{2});\n/// assert(document.at(\"foo\").to_integer() == 2);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto set(JSON &document, const Pointer &pointer, JSON &&value) -> void;\n\n/// @ingroup jsonpointer\n/// Remove a value from a JSON document using a JSON Pointer.\n/// Returns true if a value is removed, false otherwise.\n///\n/// Removing an empty pointer `Pointer{}`, i.e. the root, is a noop.\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1, \\\"baz\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n/// assert(document.at(0).defines(\"foo\"));\n///\n/// const sourcemeta::core::Pointer pointer{0, \"foo\"};\n/// sourcemeta::core::remove(document, pointer);\n/// assert(!document.at(0).defines(\"foo\"));\n/// assert(document.at(0).defines(\"baz\"));\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto remove(JSON &document, const Pointer &pointer) -> bool;\n\n/// @ingroup jsonpointer\n/// Remove a value from a JSON document using a JSON WeakPointer.\n/// Returns true if a value is removed, false otherwise.\n///\n/// Removing an empty pointer `WeakPointer{}`, i.e. the root, is a noop.\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"[ { \\\"foo\\\": 1, \\\"baz\\\": 1 }, { \\\"bar\\\": 2 } ]\"};\n/// sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(stream);\n/// assert(document.at(0).defines(\"foo\"));\n///\n/// const std::string foo = \"foo\";\n/// const sourcemeta::core::WeakPointer pointer{0, std::cref(foo)};\n/// sourcemeta::core::remove(document, pointer);\n/// assert(!document.at(0).defines(\"foo\"));\n/// assert(document.at(0).defines(\"baz\"));\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto remove(JSON &document, const WeakPointer &pointer) -> bool;\n\n/// @ingroup jsonpointer\n/// Create a JSON Pointer from a JSON string value. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document{\"/foo/bar/0\"};\n/// assert(document.is_string());\n/// const sourcemeta::core::Pointer pointer =\n///   sourcemeta::core::to_pointer(document);\n/// assert(pointer.size() == 3);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_pointer(const JSON &document) -> Pointer;\n\n/// @ingroup jsonpointer\n/// Create a JSON Pointer from a standard C++ string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::Pointer pointer =\n///   sourcemeta::core::to_pointer(\"/foo/bar/0\");\n/// assert(pointer.size() == 3);\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_pointer(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input)\n    -> Pointer;\n\n/// @ingroup jsonpointer\n/// Convert a JSON WeakPointer into a JSON Pointer. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// const std::string foo = \"foo\";\n/// const sourcemeta::core::WeakPointer pointer{std::cref(foo)};\n/// const sourcemeta::core::Pointer result{\n///   sourcemeta::core::to_pointer(pointer)};\n/// assert(result.size() == 1);\n/// assert(result.at(0).is_property());\n/// assert(result.at(0).to_property() == \"foo\");\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_pointer(const WeakPointer &pointer) -> Pointer;\n\n/// @ingroup jsonpointer\n/// Check if the given string is a valid JSON Pointer per RFC 6901 without\n/// constructing a JSON Pointer object. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::is_pointer(\"/foo/bar/0\"));\n/// assert(sourcemeta::core::is_pointer(\"\"));\n/// assert(!sourcemeta::core::is_pointer(\"foo\"));\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto is_pointer(std::string_view input) noexcept -> bool;\n\n/// @ingroup jsonpointer\n/// Convert a JSON Pointer into a JSON WeakPointer. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n/// const auto result{sourcemeta::core::to_weak_pointer(pointer)};\n/// assert(result.size() == 3);\n/// assert(result.at(0).is_property());\n/// assert(result.at(0).to_property() == \"foo\");\n/// assert(result.at(1).is_property());\n/// assert(result.at(1).to_property() == \"bar\");\n/// assert(result.at(2).is_property());\n/// assert(result.at(2).to_property() == \"baz\");\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_weak_pointer(const Pointer &pointer) -> WeakPointer;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON Pointer into a given C++ standard output stream.\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// std::ostringstream stream;\n/// sourcemeta::core::stringify(pointer, stream);\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto stringify(const Pointer &pointer,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON WeakPointer into a given C++ standard output\n/// stream. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// const std::string foo = \"foo\";\n/// const sourcemeta::core::WeakPointer pointer{std::cref(foo)};\n/// std::ostringstream stream;\n/// sourcemeta::core::stringify(pointer, stream);\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto stringify(const WeakPointer &pointer,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON Pointer into a C++ standard string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <string>\n/// #include <iostream>\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// const std::string result{sourcemeta::core::to_string(pointer)};\n/// std::cout << result << std::endl;\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_string(const Pointer &pointer)\n    -> std::basic_string<JSON::Char, JSON::CharTraits,\n                         std::allocator<JSON::Char>>;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON WeakPointer into a C++ standard string. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <string>\n/// #include <iostream>\n///\n/// const std::string foo = \"foo\";\n/// const sourcemeta::core::WeakPointer pointer{foo};\n/// const std::string result{sourcemeta::core::to_string(pointer)};\n/// std::cout << result << std::endl;\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_string(const WeakPointer &pointer)\n    -> std::basic_string<JSON::Char, JSON::CharTraits,\n                         std::allocator<JSON::Char>>;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON Pointer into a properly escaped URI fragment. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/uri.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n///\n/// #include <assert>\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// const sourcemeta::core::URI fragment{\n///   sourcemeta::core::to_uri(pointer)};\n/// assert(fragment.recompose() == \"#/foo\");\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_uri(const Pointer &pointer) -> URI;\n\n/// @ingroup jsonpointer\n///\n/// Stringify the input JSON Pointer into a properly escaped URI fragment\n/// alongside a base URI. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/uri.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n///\n/// #include <assert>\n///\n/// const sourcemeta::core::Pointer pointer{\"foo\"};\n/// const sourcemeta::core::URI base{\"https://www.example.com\"};\n/// const sourcemeta::core::URI fragment{\n///   sourcemeta::core::to_uri(pointer, base)};\n/// assert(fragment.recompose() == \"https://example.com#/foo\");\n/// ```\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_uri(const Pointer &pointer, const URI &base) -> URI;\n\n/// @ingroup jsonpointer\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_uri(const WeakPointer &pointer) -> URI;\n\n/// @ingroup jsonpointer\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_uri(const WeakPointer &pointer, const URI &base) -> URI;\n\n/// @ingroup jsonpointer\nSOURCEMETA_CORE_JSONPOINTER_EXPORT\nauto to_uri(const WeakPointer &pointer, const std::string_view base) -> URI;\n\n/// @ingroup jsonpointer\n///\n/// Walk over every element of a JSON document, top-down, using weak pointers.\n/// Note that the resulting weak pointers hold references to strings in the JSON\n/// document, so the document must outlive the walker and any pointers obtained\n/// from it. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n/// #include <string>\n/// #include <vector>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(\"[ 1, 2, 3 ]\");\n/// std::vector<std::string> subpointers;\n///\n/// for (const auto &subpointer :\n///   sourcemeta::core::PointerWalker{document}) {\n///   subpointers.push_back(sourcemeta::core::to_string(subpointer));\n/// }\n///\n/// assert(subpointers.size() == 4);\n/// assert(subpointers.at(0) == \"\");\n/// assert(subpointers.at(1) == \"/0\");\n/// assert(subpointers.at(2) == \"/1\");\n/// assert(subpointers.at(3) == \"/2\");\n/// ```\nusing PointerWalker = GenericPointerWalker<WeakPointer>;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_error.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_ERROR_H_\n#define SOURCEMETA_CORE_JSONPOINTER_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_JSONPOINTER_EXPORT\n#include <sourcemeta/core/jsonpointer_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <cstdint> // std::uint64_t\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\n/// This class represents a parsing error.\nclass SOURCEMETA_CORE_JSONPOINTER_EXPORT PointerParseError\n    // TODO: It makes no sense for a JSON Pointer error to inherit from a JSON\n    // error. Make them independent\n    : public JSONParseError {\npublic:\n  /// Create a parsing error\n  PointerParseError(const std::uint64_t column) : JSONParseError{1, column} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The input is not a valid JSON Pointer\";\n  }\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_pointer.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_POINTER_H_\n#define SOURCEMETA_CORE_JSONPOINTER_POINTER_H_\n\n#include <sourcemeta/core/jsonpointer_token.h>\n\n#include <algorithm>        // std::move, std::equal\n#include <cassert>          // assert\n#include <cstddef>          // std::size_t\n#include <functional>       // std::reference_wrapper\n#include <initializer_list> // std::initializer_list\n#include <iterator>         // std::advance, std::back_inserter\n#include <optional>         // std::optional\n#include <ranges>           // std::ranges::subrange\n#include <type_traits>      // std::is_same_v, std::decay_t\n#include <utility>          // std::move\n#include <vector>           // std::vector\n\n#include <sourcemeta/core/preprocessor.h>\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\ntemplate <typename PropertyT, typename Hash> class GenericPointer {\npublic:\n  using Token = GenericToken<PropertyT, Hash>;\n  using Value = typename Token::Value;\n  using Container = std::vector<Token>;\n\n  /// This constructor creates an empty JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer;\n  /// assert(pointer.empty());\n  /// ```\n  GenericPointer() : data{} {}\n\n  /// This constructor is the preferred way of creating a pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// // Equivalent to /foo/bar/1\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", 1};\n  /// assert(pointer.size() == 3);\n  /// ```\n  GenericPointer(std::initializer_list<Token> tokens)\n      : data{std::move(tokens)} {}\n\n  // Member types\n  using value_type = typename Container::value_type;\n  using allocator_type = typename Container::allocator_type;\n  using size_type = typename Container::size_type;\n  using difference_type = typename Container::difference_type;\n  using reference = typename Container::reference;\n  using const_reference = typename Container::const_reference;\n  using pointer = typename Container::pointer;\n  using const_pointer = typename Container::const_pointer;\n  using iterator = typename Container::iterator;\n  using const_iterator = typename Container::const_iterator;\n  using reverse_iterator = typename Container::reverse_iterator;\n  using const_reverse_iterator = typename Container::const_reverse_iterator;\n\n  /// Get a mutable begin iterator on the pointer\n  auto begin() noexcept -> iterator { return this->data.begin(); }\n  /// Get a mutable end iterator on the pointer\n  auto end() noexcept -> iterator { return this->data.end(); }\n  /// Get a constant begin iterator on the pointer\n  [[nodiscard]] auto begin() const noexcept -> const_iterator {\n    return this->data.begin();\n  }\n  /// Get a constant end iterator on the pointer\n  [[nodiscard]] auto end() const noexcept -> const_iterator {\n    return this->data.end();\n  }\n  /// Get a constant begin iterator on the pointer\n  [[nodiscard]] auto cbegin() const noexcept -> const_iterator {\n    return this->data.cbegin();\n  }\n  /// Get a constant end iterator on the pointer\n  [[nodiscard]] auto cend() const noexcept -> const_iterator {\n    return this->data.cend();\n  }\n  /// Get a mutable reverse begin iterator on the pointer\n  auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); }\n  /// Get a mutable reverse end iterator on the pointer\n  auto rend() noexcept -> reverse_iterator { return this->data.rend(); }\n  /// Get a constant reverse begin iterator on the pointer\n  [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator {\n    return this->data.rbegin();\n  }\n  /// Get a constant reverse end iterator on the pointer\n  [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator {\n    return this->data.rend();\n  }\n  /// Get a constant reverse begin iterator on the pointer\n  [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator {\n    return this->data.crbegin();\n  }\n  /// Get a constant reverse end iterator on the pointer\n  [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator {\n    return this->data.crend();\n  }\n\n  /// Access a token in a JSON Pointer at a given index.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", 1};\n  /// assert(pointer.at(1).is_property());\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// ```\n  [[nodiscard]] auto at(const size_type index) const -> const_reference {\n    assert(this->size() > index);\n    return this->data[index];\n  }\n\n  /// Access the last token in a JSON Pointer\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", 1};\n  /// assert(pointer.back().is_property());\n  /// assert(pointer.back().to_property() == \"bar\");\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE auto back() const -> const_reference {\n    assert(!this->empty());\n    return this->data.back();\n  }\n\n  /// Get the number of tokens in a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\"};\n  /// assert(pointer.size() == 2);\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE auto size() const noexcept -> size_type {\n    return this->data.size();\n  }\n\n  /// Check if a JSON Pointer is the empty pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer empty_pointer;\n  /// const sourcemeta::core::Pointer non_empty_pointer{\"foo\", \"bar\"};\n  /// assert(empty_pointer.empty());\n  /// assert(!non_empty_pointer.empty());\n  /// ```\n  [[nodiscard]] SOURCEMETA_FORCEINLINE auto empty() const noexcept -> bool {\n    return this->data.empty();\n  }\n\n  /// Emplace a token into the back of a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer;\n  /// assert(pointer.empty());\n  /// auto &token{pointer.emplace_back(\"foo\")};\n  /// assert(!pointer.empty());\n  /// assert(token.is_property());\n  /// ```\n  template <class... Args>\n  SOURCEMETA_FORCEINLINE auto emplace_back(Args &&...args) -> reference {\n    return this->data.emplace_back(std::forward<Args>(args)...);\n  }\n\n  /// Reserve capacity for a JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  ///\n  /// sourcemeta::core::Pointer pointer;\n  /// pointer.reserve(1024);\n  /// ```\n  auto reserve(const typename Container::size_type capacity) -> void {\n    this->data.reserve(capacity);\n  }\n\n  /// Push a copy of a JSON Pointer into the back of a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\"};\n  /// const sourcemeta::core::Pointer other{\"bar\", \"baz\"};\n  /// pointer.push_back(other);\n  /// assert(pointer.size() == 3);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_property());\n  /// assert(pointer.at(2).is_property());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// assert(pointer.at(2).to_property() == \"baz\");\n  /// ```\n  SOURCEMETA_FORCEINLINE auto\n  push_back(const GenericPointer<PropertyT, Hash> &other) -> void {\n    if (other.empty()) {\n      return;\n    } else if (other.size() == 1) {\n      this->emplace_back(other.back());\n      return;\n    }\n\n    this->reserve(this->data.size() + other.size());\n// TODO: Remove once GitHub Actions ship proper C++23 support\n#if __cpp_lib_containers_ranges >= 202202L\n    this->data.append_range(other.data);\n#else\n    std::copy(other.data.cbegin(), other.data.cend(),\n              std::back_inserter(this->data));\n#endif\n  }\n\n  /// Move a JSON Pointer into the back of a JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  /// #include <utility>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\"};\n  /// sourcemeta::core::Pointer other{\"bar\", \"baz\"};\n  /// pointer.push_back(std::move(other));\n  /// assert(pointer.size() == 3);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_property());\n  /// assert(pointer.at(2).is_property());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// assert(pointer.at(2).to_property() == \"baz\");\n  /// ```\n  SOURCEMETA_FORCEINLINE auto push_back(GenericPointer<PropertyT, Hash> &&other)\n      -> void {\n    if (other.empty()) {\n      return;\n    } else if (other.size() == 1) {\n      this->emplace_back(std::move(other.back()));\n      return;\n    }\n\n    this->reserve(this->data.size() + other.size());\n    std::move(other.data.begin(), other.data.end(),\n              std::back_inserter(this->data));\n  }\n\n  /// Push a JSON Pointer into the back of a JSON WeakPointer. Make sure that\n  /// the pointer you are pushing remains alive for the duration of the\n  /// WeakPointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const std::string foo{\"foo\"};\n  /// sourcemeta::core::WeakPointer pointer{std::cref(foo)};\n  /// const sourcemeta::core::Pointer other{\"bar\", \"baz\"};\n  /// pointer.push_back(other);\n  /// assert(pointer.size() == 3);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_property());\n  /// assert(pointer.at(2).is_property());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// assert(pointer.at(2).to_property() == \"baz\");\n  /// ```\n  template <typename OtherT>\n  SOURCEMETA_FORCEINLINE auto\n  push_back(const GenericPointer<OtherT, Hash> &other) -> void\n    requires std::is_same_v<PropertyT, std::reference_wrapper<const OtherT>>\n  {\n    if (other.empty()) {\n      return;\n    } else if (other.size() == 1) {\n      const auto &token{other.back()};\n      if (token.is_property()) {\n        // We should make sure to re-use the existing hash\n        this->data.emplace_back(token.to_property(), token.property_hash());\n      } else {\n        this->data.emplace_back(token.to_index());\n      }\n    } else {\n      this->reserve(this->data.size() + other.size());\n      for (const auto &token : other) {\n        if (token.is_property()) {\n          // We should make sure to re-use the existing hash\n          this->data.emplace_back(token.to_property(), token.property_hash());\n        } else {\n          this->data.emplace_back(token.to_index());\n        }\n      }\n    }\n  }\n\n  /// Push a property token into the back of a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\"};\n  /// const sourcemeta::core::Pointer other{\"bar\"};\n  /// pointer.push_back(other.back().to_property());\n  /// assert(pointer.size() == 2);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_property());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// ```\n  SOURCEMETA_FORCEINLINE auto\n  push_back(const typename Token::Property &property) -> void {\n    this->data.emplace_back(property);\n  }\n\n  /// Move a property token into the back of a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\"};\n  /// pointer.push_back(\"bar\");\n  /// assert(pointer.size() == 2);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_property());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// ```\n  SOURCEMETA_FORCEINLINE auto push_back(typename Token::Property &&property)\n      -> void {\n    this->data.emplace_back(std::move(property));\n  }\n\n  /// Push an index token into the back of a JSON Pointer.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\"};\n  /// const sourcemeta::core::Pointer other{0};\n  /// pointer.push_back(other.back().to_index());\n  /// assert(pointer.size() == 2);\n  ///\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(1).is_index());\n  ///\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).to_index() == 0);\n  /// ```\n  SOURCEMETA_FORCEINLINE auto push_back(const typename Token::Index &index)\n      -> void {\n    this->data.emplace_back(index);\n  }\n\n  /// Remove the last token of a JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\", \"bar\"};\n  /// pointer.pop_back();\n  /// assert(pointer.size() == 1);\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// ```\n  auto pop_back() -> void {\n    assert(!this->empty());\n    this->data.pop_back();\n  }\n\n  /// Remove a number of tokens from the back of a JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// pointer.pop_back(2);\n  /// assert(pointer.size() == 1);\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// ```\n  auto pop_back(const size_type count) -> void {\n    assert(this->size() >= count);\n    for (std::size_t index = 0; index < count; index++) {\n      this->data.pop_back();\n    }\n  }\n\n  /// Get a copy of the JSON Pointer including every token except the last. This\n  /// method is undefined if the JSON Pointer is empty. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer result{pointer.initial()};\n  /// assert(pointer.size() == 2);\n  /// assert(pointer.at(0).is_property());\n  /// assert(pointer.at(0).to_property() == \"foo\");\n  /// assert(pointer.at(1).is_property());\n  /// assert(pointer.at(1).to_property() == \"bar\");\n  /// ```\n  [[nodiscard]] auto initial() const -> GenericPointer<PropertyT, Hash> {\n    assert(!this->empty());\n    GenericPointer<PropertyT, Hash> result{*this};\n    result.pop_back();\n    return result;\n  }\n\n  /// Get a copy of the JSON Pointer starting from a given token index. This\n  /// method is undefined if the index is greater than the pointer size. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer result{pointer.slice(1)};\n  /// assert(result.size() == 2);\n  /// assert(result.at(0).is_property());\n  /// assert(result.at(0).to_property() == \"bar\");\n  /// assert(result.at(1).is_property());\n  /// assert(result.at(1).to_property() == \"baz\");\n  /// ```\n  [[nodiscard]] auto slice(const std::size_t index) const\n      -> GenericPointer<PropertyT, Hash> {\n    assert(index <= this->size());\n    auto new_begin{this->data.cbegin()};\n    std::advance(new_begin, index);\n    GenericPointer<PropertyT, Hash> result;\n    result.reserve(this->size() - index);\n// TODO: Remove once GitHub Actions ship proper C++23 support\n#if __cpp_lib_containers_ranges >= 202202L\n    result.data.append_range(\n        std::ranges::subrange(new_begin, this->data.cend()));\n#else\n    std::copy(new_begin, this->data.cend(), std::back_inserter(result.data));\n#endif\n    return result;\n  }\n\n  /// Get a copy of the JSON Pointer starting from a given token index up to\n  /// (but not including) a given end index. This method is undefined if the\n  /// start index is greater than the end index or if the end index is greater\n  /// than the pointer size. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\", \"qux\"};\n  /// const sourcemeta::core::Pointer result{pointer.slice(1, 3)};\n  /// assert(result.size() == 2);\n  /// assert(result.at(0).is_property());\n  /// assert(result.at(0).to_property() == \"bar\");\n  /// assert(result.at(1).is_property());\n  /// assert(result.at(1).to_property() == \"baz\");\n  /// ```\n  [[nodiscard]] auto slice(const std::size_t start, const std::size_t end) const\n      -> GenericPointer<PropertyT, Hash> {\n    assert(start <= end);\n    assert(end <= this->size());\n    auto new_begin{this->data.cbegin()};\n    std::advance(new_begin, start);\n    auto new_end{this->data.cbegin()};\n    std::advance(new_end, end);\n    GenericPointer<PropertyT, Hash> result;\n    result.reserve(end - start);\n// TODO: Remove once GitHub Actions ship proper C++23 support\n#if __cpp_lib_containers_ranges >= 202202L\n    result.data.append_range(std::ranges::subrange(new_begin, new_end));\n#else\n    std::copy(new_begin, new_end, std::back_inserter(result.data));\n#endif\n    return result;\n  }\n\n  /// Concatenate a JSON Pointer with another JSON Pointer, getting a new\n  /// pointer as a result. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer left{\"foo\"};\n  /// const sourcemeta::core::Pointer right{\"bar\", \"baz\"};\n  /// assert(left.concat(right) ==\n  ///   sourcemeta::core::Pointer{\"foo\", \"bar\", \"baz\"});\n  /// ```\n  [[nodiscard]] auto concat(const GenericPointer<PropertyT, Hash> &other) const\n      -> GenericPointer<PropertyT, Hash> {\n    GenericPointer<PropertyT, Hash> result{*this};\n    result.push_back(other);\n    return result;\n  }\n\n  /// Check whether a JSON Pointer starts with another JSON Pointer. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\", \"bar\"};\n  /// assert(pointer.starts_with(prefix));\n  /// ```\n  [[nodiscard]] auto\n  starts_with(const GenericPointer<PropertyT, Hash> &other) const -> bool {\n    return other.data.size() <= this->data.size() &&\n           std::equal(other.data.cbegin(), other.data.cend(),\n                      this->data.cbegin());\n  }\n\n  /// Check whether a JSON Pointer plus a given tail starts with another JSON\n  /// Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\"};\n  /// const sourcemeta::core::Pointer::Token tail{\"baz\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\", \"bar\", \"baz\"};\n  /// assert(pointer.starts_with(prefix, tail));\n  /// ```\n  [[nodiscard]] auto starts_with(const GenericPointer<PropertyT, Hash> &other,\n                                 const Token &tail) const -> bool {\n    if (other.size() == this->size() + 1) {\n      assert(!other.empty());\n      return other.starts_with(*this) && other.back() == tail;\n    } else {\n      return this->starts_with(other);\n    }\n  }\n\n  /// Check whether a JSON Pointer starts with another JSON Pointer followed\n  /// by a property token. This is useful for checking container membership\n  /// without allocating a new pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"$defs\", \"bar\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\"};\n  /// assert(pointer.starts_with(prefix, \"$defs\"));\n  /// assert(!pointer.starts_with(prefix, \"other\"));\n  /// ```\n  template <typename StringT>\n    requires(!std::is_same_v<std::decay_t<StringT>, Token>)\n  [[nodiscard]] auto starts_with(const GenericPointer<PropertyT, Hash> &other,\n                                 const StringT &tail) const -> bool {\n    const auto prefix_size{other.size()};\n    return this->size() > prefix_size && this->starts_with(other) &&\n           this->data[prefix_size].is_property() &&\n           this->data[prefix_size].to_property() == tail;\n  }\n\n  /// Check whether a JSON Pointer starts with another JSON Pointer followed\n  /// by two property tokens. This is useful for checking nested container\n  /// membership without allocating a new pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"$defs\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\"};\n  /// assert(pointer.starts_with(prefix, \"$defs\", \"bar\"));\n  /// assert(!pointer.starts_with(prefix, \"$defs\", \"other\"));\n  /// ```\n  template <typename StringLeftT, typename StringRightT>\n    requires(!std::is_same_v<std::decay_t<StringLeftT>, Token> &&\n             !std::is_same_v<std::decay_t<StringRightT>, Token>)\n  [[nodiscard]] auto starts_with(const GenericPointer<PropertyT, Hash> &other,\n                                 const StringLeftT &tail_left,\n                                 const StringRightT &tail_right) const -> bool {\n    const auto prefix_size{other.size()};\n    return this->size() > prefix_size + 1 &&\n           this->starts_with(other, tail_left) &&\n           this->data[prefix_size + 1].is_property() &&\n           this->data[prefix_size + 1].to_property() == tail_right;\n  }\n\n  /// Check whether a JSON Pointer starts with the initial part of another JSON\n  /// Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\", \"bar\", \"qux\"};\n  /// assert(pointer.starts_with_initial(prefix));\n  /// ```\n  [[nodiscard]] auto\n  starts_with_initial(const GenericPointer<PropertyT, Hash> &other) const\n      -> bool {\n    const auto prefix_size{other.size()};\n    if (prefix_size == 0) {\n      return true;\n    } else if (this->size() < prefix_size - 1) {\n      return false;\n    }\n\n    for (std::size_t index = 0; index < prefix_size - 1; index++) {\n      if (this->data[index] != other.data[index]) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  /// Replace a base of a JSON Pointer with another JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\", \"baz\"};\n  /// const sourcemeta::core::Pointer prefix{\"foo\", \"bar\"};\n  /// const sourcemeta::core::Pointer replacement{\"qux\"};\n  ///\n  /// assert(pointer.rebase(prefix, replacement) ==\n  ///   sourcemeta::core::Pointer{\"qux\", \"baz\"});\n  /// ```\n  [[nodiscard]] auto\n  rebase(const GenericPointer<PropertyT, Hash> &prefix,\n         const GenericPointer<PropertyT, Hash> &replacement) const\n      -> GenericPointer<PropertyT, Hash> {\n    typename Container::size_type index{0};\n    while (index < prefix.size()) {\n      if (index >= this->size() || prefix.data[index] != this->data[index]) {\n        return *this;\n      } else {\n        index++;\n      }\n    }\n\n    assert(index == prefix.size());\n    assert(this->starts_with(prefix));\n    auto new_begin{this->data.cbegin()};\n    std::advance(new_begin, index);\n    GenericPointer<PropertyT, Hash> result{replacement};\n// TODO: Remove once GitHub Actions ship proper C++23 support\n#if __cpp_lib_containers_ranges >= 202202L\n    result.data.append_range(\n        std::ranges::subrange(new_begin, this->data.cend()));\n#else\n    std::copy(new_begin, this->data.cend(), std::back_inserter(result.data));\n#endif\n    return result;\n  }\n\n  /// Resolve a JSON Pointer relative to another JSON Pointer. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer pointer{\"foo\", \"bar\"};\n  /// const sourcemeta::core::Pointer base{\"foo\"};\n  /// assert(pointer.resolve_from(base) ==\n  ///   sourcemeta::core::Pointer{\"bar\"});\n  /// ```\n  ///\n  /// If the JSON Pointer is not relative to the base, a copy of the original\n  /// input pointer is returned.\n  [[nodiscard]] auto\n  resolve_from(const GenericPointer<PropertyT, Hash> &base) const\n      -> GenericPointer<PropertyT, Hash> {\n    if (base.empty()) {\n      return *this;\n    }\n\n    typename Container::size_type index{0};\n    while (index < base.size()) {\n      if (index >= this->size() || base.data[index] != this->data[index]) {\n        return *this;\n      } else {\n        index++;\n      }\n    }\n\n    // Make a pointer from the remaining tokens\n    auto new_begin{this->data.cbegin()};\n    std::advance(new_begin, index);\n    GenericPointer<PropertyT, Hash> result;\n    const auto remaining{static_cast<typename Container::size_type>(\n        this->data.cend() - new_begin)};\n    result.data.reserve(remaining);\n// TODO: Remove once GitHub Actions ship proper C++23 support\n#if __cpp_lib_containers_ranges >= 202202L\n    result.data.append_range(\n        std::ranges::subrange(new_begin, this->data.cend()));\n#else\n    std::copy(new_begin, this->data.cend(), std::back_inserter(result.data));\n#endif\n    return result;\n  }\n\n  /// Compare JSON Pointer instances\n  [[nodiscard]] auto\n  operator==(const GenericPointer<PropertyT, Hash> &other) const noexcept\n      -> bool {\n    return this->data == other.data;\n  }\n\n  /// Compare with a reference wrapper\n  [[nodiscard]] auto\n  operator==(const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n                 &other) const noexcept -> bool {\n    return this->data == other.get().data;\n  }\n\n  /// Overload to support ordering of JSON Pointers. Typically for sorting\n  /// reasons.\n  [[nodiscard]] auto\n  operator<(const GenericPointer<PropertyT, Hash> &other) const noexcept\n      -> bool {\n    return this->data < other.data;\n  }\n\n  /// Compare with a reference wrapper for ordering\n  [[nodiscard]] auto\n  operator<(const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n                &other) const noexcept -> bool {\n    return this->data < other.get().data;\n  }\n\n  /// Hash functor for use with containers\n  struct Hasher {\n    using is_transparent = void;\n\n    auto\n    operator()(const GenericPointer<PropertyT, Hash> &pointer) const noexcept\n        -> std::size_t {\n      const auto size{pointer.size()};\n      if (size == 0) {\n        return size;\n      }\n\n      const auto &first{pointer.at(0)};\n      const auto &middle{pointer.at(size / 2)};\n      const auto &last{pointer.at(size - 1)};\n\n      return size +\n             (first.is_property() ? property_hash(first.property_hash())\n                                  : first.to_index()) +\n             (middle.is_property() ? property_hash(middle.property_hash())\n                                   : middle.to_index()) +\n             (last.is_property() ? property_hash(last.property_hash())\n                                 : last.to_index());\n    }\n\n    auto operator()(\n        const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n            &reference) const noexcept -> std::size_t {\n      return (*this)(reference.get());\n    }\n\n  private:\n    // Intentionally only fold hash.a for performance, as the first\n    // 16 bytes already provide sufficient entropy for bucketing\n    static auto property_hash(const typename Hash::hash_type &hash) noexcept\n        -> std::size_t {\n      return static_cast<std::size_t>(hash.a) ^\n             static_cast<std::size_t>(hash.a >> 64);\n    }\n  };\n\n  /// Comparator for use with containers\n  struct Comparator {\n    using is_transparent = void;\n\n    auto operator()(const GenericPointer<PropertyT, Hash> &left,\n                    const GenericPointer<PropertyT, Hash> &right) const noexcept\n        -> bool {\n      return left == right;\n    }\n\n    auto operator()(\n        const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n            &left,\n        const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n            &right) const noexcept -> bool {\n      return left.get() == right.get();\n    }\n\n    auto operator()(\n        const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n            &left,\n        const GenericPointer<PropertyT, Hash> &right) const noexcept -> bool {\n      return left.get() == right;\n    }\n\n    auto operator()(\n        const GenericPointer<PropertyT, Hash> &left,\n        const std::reference_wrapper<const GenericPointer<PropertyT, Hash>>\n            &right) const noexcept -> bool {\n      return left == right.get();\n    }\n  };\n\n  /// Serialise a JSON Pointer as a JSON array of tokens\n  [[nodiscard]] auto to_json() const -> Value {\n    auto result{Value::make_array()};\n    for (const auto &token : this->data) {\n      result.push_back(token.to_json());\n    }\n\n    return result;\n  }\n\n  /// Deserialise a JSON Pointer from a JSON array of tokens\n  static auto from_json(const Value &value)\n      -> std::optional<GenericPointer<PropertyT, Hash>>\n    requires std::is_same_v<PropertyT, typename Value::String>\n  {\n    if (!value.is_array()) {\n      return std::nullopt;\n    }\n\n    GenericPointer<PropertyT, Hash> result;\n    for (const auto &element : value.as_array()) {\n      if (element.is_string()) {\n        result.emplace_back(element.to_string());\n      } else if (element.is_integer()) {\n        result.emplace_back(\n            static_cast<typename Token::Index>(element.to_integer()));\n      } else {\n        return std::nullopt;\n      }\n    }\n\n    return result;\n  }\n\nprivate:\n  Container data;\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_position.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_POSITION_H_\n#define SOURCEMETA_CORE_JSONPOINTER_POSITION_H_\n\n#ifndef SOURCEMETA_CORE_JSONPOINTER_EXPORT\n#include <sourcemeta/core/jsonpointer_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <sourcemeta/core/jsonpointer_pointer.h>\n\n#include <cstddef>       // std::size_t\n#include <cstdint>       // std::uint64_t\n#include <optional>      // std::optional\n#include <tuple>         // std::tuple\n#include <unordered_map> // std::unordered_map\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\n/// A convenient parsing callback to obtain JSON document line/column\n/// information using JSON Pointer. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonpointer.h>\n/// #include <cassert>\n///\n/// const auto input{\"{\\n  \\\"foo\\\": \\\"bar\\\"\\n}\"};;\n/// sourcemeta::core::PointerPositionTracker tracker;\n/// sourcemeta::core::JSON document{nullptr};\n/// sourcemeta::core::parse_json(input, document, std::ref(tracker));\n/// assert(tracker.size() == 2);\n/// const auto foo{tracker.get(sourcemeta::core::Pointer{\"foo\"})};\n/// assert(foo.has_value());\n///\n/// // Start line and column\n/// assert(std::get<0>(foo.value()) == 2);\n/// assert(std::get<1>(foo.value()) == 10);\n///\n/// // End line and column\n/// assert(std::get<3>(foo.value()) == 2);\n/// assert(std::get<4>(foo.value()) == 14);\n/// ```\nclass SOURCEMETA_CORE_JSONPOINTER_EXPORT PointerPositionTracker {\npublic:\n  using Pointer = GenericPointer<JSON::String, PropertyHashJSON<JSON::String>>;\n  using Position =\n      std::tuple<std::uint64_t, std::uint64_t, std::uint64_t, std::uint64_t>;\n  auto operator()(const JSON::ParsePhase phase, const JSON::Type,\n                  const std::uint64_t line, const std::uint64_t column,\n                  const JSON::ParseContext context, const std::size_t index,\n                  const JSON::String &property) -> void;\n  [[nodiscard]] auto get(const Pointer &pointer) const\n      -> std::optional<Position>;\n  [[nodiscard]] auto size() const -> std::size_t;\n  [[nodiscard]] auto to_json() const -> JSON;\n\nprivate:\n  struct Event {\n    JSON::ParsePhase phase;\n    JSON::ParseContext context;\n    std::size_t index;\n    const JSON::String *property;\n    std::uint64_t line;\n    std::uint64_t column;\n  };\n\n  struct TrieNode {\n    std::optional<Position> position;\n    std::unordered_map<std::size_t, std::size_t> index_children;\n    std::unordered_map<std::string_view, std::size_t> property_children;\n  };\n\n  auto ensure_index() const -> void;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::vector<Event> events;\n  mutable bool indexed{false};\n  mutable std::vector<TrieNode> trie;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_token.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_TOKEN_H_\n#define SOURCEMETA_CORE_JSONPOINTER_TOKEN_H_\n\n#include <sourcemeta/core/json.h>\n\n#include <cassert> // assert\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\ntemplate <typename PropertyT, typename Hash> class GenericToken {\npublic:\n  using Value = JSON;\n  using Property = PropertyT;\n  using Index = typename Value::Array::size_type;\n\n  /// This constructor creates an JSON Pointer token from a string given its\n  /// precomputed hash. This is advanced functionality that should be used with\n  /// care.\n  GenericToken(Property value, const typename Hash::hash_type property_hash)\n      : as_property{true}, property{std::move(value)}, hash{property_hash},\n        index{0} {}\n\n  /// This constructor creates an JSON Pointer token from a string. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// ```\n  GenericToken(const Property &value) : GenericToken{value, hasher(value)} {}\n\n  /// This constructor creates an JSON Pointer token from a string. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// ```\n  GenericToken(const JSON::Char *const value)\n      : GenericToken{value, hasher(value)} {}\n\n  /// This constructor creates an JSON Pointer token from a character. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{'a'};\n  /// ```\n  GenericToken(const JSON::Char value)\n      : GenericToken{Property{value}, hasher(Property{value})} {}\n\n  /// This constructor creates an JSON Pointer token from an item index. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{1};\n  /// ```\n  GenericToken(const Index value)\n      : as_property{false}, property{DEFAULT_PROPERTY}, hash{0}, index{value} {}\n\n  /// This constructor creates an JSON Pointer token from an item index. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{1};\n  /// ```\n  GenericToken(const int value)\n      : as_property{false}, property{DEFAULT_PROPERTY}, hash{0},\n        index{static_cast<Index>(value)} {}\n\n#if defined(_MSC_VER)\n  /// This constructor creates an JSON Pointer token from an item index. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{1};\n  /// ```\n  GenericToken(const unsigned long value)\n      : as_property{false}, property{DEFAULT_PROPERTY}, hash{0}, index{value} {}\n#endif\n\n  /// Check if a JSON Pointer token represents an object property.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// assert(token.is_property());\n  /// ```\n  [[nodiscard]] auto is_property() const noexcept -> bool {\n    return this->as_property;\n  }\n\n  /// Check if a JSON Pointer token represents the hyphen constant\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token_1{\"-\"};\n  /// const sourcemeta::core::Pointer::Token token_2{'-'};\n  /// assert(token_1.is_hyphen());\n  /// assert(token_2.is_hyphen());\n  /// ```\n  [[nodiscard]] auto is_hyphen() const noexcept -> bool {\n    return this->as_property && this->property.size() == 1 &&\n           this->property.front() == '\\u002D';\n  }\n\n  /// Check if a JSON Pointer token represents an array index.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{2};\n  /// assert(token.is_index());\n  /// ```\n  [[nodiscard]] auto is_index() const noexcept -> bool {\n    return !this->as_property;\n  }\n\n  /// Get the underlying value of a JSON Pointer object property token (`const`\n  /// overload). For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// assert(token.is_property());\n  /// assert(token.to_property() == \"foo\");\n  /// ```\n  [[nodiscard]] auto to_property() const noexcept -> const auto & {\n    assert(this->is_property());\n    if constexpr (requires { this->property.get(); }) {\n      return this->property.get();\n    } else {\n      return this->property;\n    }\n  }\n\n  /// If the JSON Pointer token is a property, get its pre-computed string hash.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// assert(token.is_property());\n  /// assert(token.property_hash() >= 0);\n  /// ```\n  [[nodiscard]] auto property_hash() const noexcept ->\n      typename Hash::hash_type {\n    assert(this->is_property());\n    return this->hash;\n  }\n\n  /// Get the underlying value of a JSON Pointer object property token\n  /// (non-`const` overload). For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::Pointer::Token token{\"foo\"};\n  /// assert(token.is_property());\n  /// assert(token.to_property() == \"foo\");\n  /// ```\n  auto to_property() noexcept -> auto & {\n    assert(this->is_property());\n    if constexpr (requires { this->property.get(); }) {\n      return this->property.get();\n    } else {\n      return this->property;\n    }\n  }\n\n  /// Get the underlying value of a JSON Pointer array index token\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token token{2};\n  /// assert(token.is_index());\n  /// assert(token.to_index() == 2);\n  /// ```\n  [[nodiscard]] auto to_index() const noexcept -> Index {\n    assert(this->is_index());\n    return this->index;\n  }\n\n  /// Convert a JSON Pointer token into a JSON document, whether it represents a\n  /// property or an index. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/jsonpointer.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::Pointer::Token index{1};\n  /// const sourcemeta::core::Pointer::Token property{\"foo\"};\n  ///\n  /// const sourcemeta::core::JSON json_index{index.to_json()};\n  /// const sourcemeta::core::JSON json_property{property.to_json()};\n  ///\n  /// assert(json_index.is_integer());\n  /// assert(json_property.is_string());\n  /// ```\n  [[nodiscard]] auto to_json() const -> JSON {\n    if (this->is_property()) {\n      return JSON{this->to_property()};\n    } else {\n      return JSON{this->to_index()};\n    }\n  }\n\n  /// Compare JSON Pointer tokens\n  auto operator==(const GenericToken<PropertyT, Hash> &other) const noexcept\n      -> bool {\n    if (this->as_property != other.as_property) {\n      return false;\n    } else if (this->as_property) {\n      if constexpr (requires { hasher.is_perfect(this->hash); }) {\n        if (hasher.is_perfect(this->hash) && hasher.is_perfect(other.hash)) {\n          return this->hash == other.hash;\n        }\n      }\n\n      return this->hash == other.hash &&\n             this->to_property() == other.to_property();\n    } else {\n      return this->index == other.index;\n    }\n  }\n\n  /// Overload to support ordering of JSON Pointer tokens. Typically for sorting\n  /// reasons.\n  auto operator<(const GenericToken<PropertyT, Hash> &other) const noexcept\n      -> bool {\n    if (this->as_property && !other.as_property) {\n      return true;\n    } else if (!this->as_property && other.as_property) {\n      return false;\n    } else if (this->as_property) {\n      return this->to_property() < other.to_property();\n    } else {\n      return this->index < other.index;\n    }\n  }\n\nprivate:\n  // We need this as a member for making WeakPointer work\n  inline static const Value::String DEFAULT_PROPERTY = \"\";\n  inline static const Hash hasher;\n\n  bool as_property;\n  Property property;\n  typename Hash::hash_type hash;\n  Index index;\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/include/sourcemeta/core/jsonpointer_walker.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_WALKER_H_\n#define SOURCEMETA_CORE_JSONPOINTER_WALKER_H_\n\n#include <sourcemeta/core/json.h>\n\n#include <cstddef> // std::size_t\n#include <vector>  // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonpointer\n/// A walker to get every JSON Pointer in a JSON document. Note that no specific\n/// ordering is guaranteed. If you expect any ordering, sort afterwards.\ntemplate <typename PointerT> class GenericPointerWalker {\nprivate:\n  using internal = typename std::vector<PointerT>;\n\npublic:\n  GenericPointerWalker(const JSON &document) { this->walk(document, {}); }\n\n  using const_iterator = typename internal::const_iterator;\n  [[nodiscard]] auto begin() const -> const_iterator {\n    return this->pointers.begin();\n  };\n  [[nodiscard]] auto end() const -> const_iterator {\n    return this->pointers.end();\n  };\n  [[nodiscard]] auto cbegin() const -> const_iterator {\n    return this->pointers.cbegin();\n  };\n  [[nodiscard]] auto cend() const -> const_iterator {\n    return this->pointers.cend();\n  };\n\nprivate:\n  auto walk(const JSON &document, const PointerT &pointer) -> void {\n    this->pointers.push_back(pointer);\n    if (document.is_array()) {\n      for (std::size_t index = 0; index < document.size(); index++) {\n        PointerT subpointer{pointer};\n        subpointer.emplace_back(index);\n        this->walk(document.at(index), subpointer);\n      }\n    } else if (document.is_object()) {\n      for (const auto &pair : document.as_object()) {\n        PointerT subpointer{pointer};\n        subpointer.emplace_back(pair.first);\n        this->walk(pair.second, subpointer);\n      }\n    }\n  }\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  internal pointers;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/jsonpointer.cc",
    "content": "#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/json_hash.h>\n#include <sourcemeta/core/json_value.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonpointer_pointer.h>\n#include <sourcemeta/core/uri.h>\n\n#include \"parser.h\"\n#include \"stringify.h\"\n\n#include <array>       // std::array\n#include <cassert>     // assert\n#include <charconv>    // std::to_chars\n#include <iterator>    // std::cbegin, std::cend, std::prev, std::advance\n#include <memory>      // std::allocator\n#include <ostream>     // std::basic_ostream\n#include <sstream>     // std::basic_ostringstream, std::basic_stringstream\n#include <string>      // std::basic_string\n#include <string_view> // std::string_view\n#include <type_traits> // std::is_same_v\n#include <utility>     // std::move\n\nnamespace {\n\ntemplate <template <typename T> typename Allocator, typename V,\n          typename PointerT = sourcemeta::core::GenericPointer<\n              typename V::String,\n              sourcemeta::core::PropertyHashJSON<typename V::String>>>\nauto traverse(V &document, typename PointerT::const_iterator begin,\n              typename PointerT::const_iterator end) -> V & {\n  // Make sure types match\n  static_assert(\n      std::is_same_v<typename PointerT::Value, std::remove_const_t<V>>);\n  V *current = &document;\n\n  // Evaluation of a JSON Pointer begins with a reference to the root\n  // value of a JSON document and completes with a reference to some value\n  // within the document.  Each reference token in the JSON Pointer is\n  // evaluated sequentially.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n  for (auto iterator = begin; iterator != end; ++iterator) {\n    if (iterator->is_property()) {\n      // If the currently referenced value is a JSON object, the new\n      // referenced value is the object member with the name identified by\n      // the reference token.  The member name is equal to the token if it\n      // has the same number of Unicode characters as the token and their\n      // code points are byte-by-byte equal.  No Unicode character\n      // normalization is performed.\n      // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n      current =\n          &current->at(iterator->to_property(), iterator->property_hash());\n    } else {\n      // If the currently referenced value is a JSON array, the reference\n      // token MUST contain [...] characters comprised of digits (see ABNF\n      // below; note that leading zeros are not allowed) that represent an\n      // unsigned base-10 integer value, making the new referenced value the\n      // array element with the zero-based index identified by the\n      // token.\n      // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n      if (current->is_object()) {\n        std::array<char, 20> buffer{};\n        const auto [end_pointer, error_code] = std::to_chars(\n            buffer.data(), buffer.data() + buffer.size(), iterator->to_index());\n        current = &current->at(std::string_view{buffer.data(), end_pointer});\n      } else {\n        current = &current->at(iterator->to_index());\n      }\n    }\n  }\n\n  return *current;\n}\n\n// A variant of the above function that assumes traversing of\n// the entire pointer and does not rely on iterators for performance reasons\ntemplate <template <typename T> typename Allocator, typename V,\n          typename PointerT = sourcemeta::core::GenericPointer<\n              typename V::String,\n              sourcemeta::core::PropertyHashJSON<typename V::String>>>\nauto traverse_all(V &document, const PointerT &pointer) -> V & {\n  // Make sure types match\n  static_assert(\n      std::is_same_v<typename PointerT::Value, std::remove_const_t<V>>);\n  V *current = &document;\n\n  for (const auto &token : pointer) {\n    if (token.is_property()) {\n      current = &current->at(token.to_property(), token.property_hash());\n    } else {\n      if (current->is_object()) {\n        std::array<char, 20> buffer{};\n        const auto [end_pointer, error_code] = std::to_chars(\n            buffer.data(), buffer.data() + buffer.size(), token.to_index());\n        current = &current->at(std::string_view{buffer.data(), end_pointer});\n      } else {\n        current = &current->at(token.to_index());\n      }\n    }\n  }\n\n  return *current;\n}\n\ntemplate <typename PointerT>\nauto try_traverse(const sourcemeta::core::JSON &document,\n                  const PointerT &pointer) -> const sourcemeta::core::JSON * {\n  const sourcemeta::core::JSON *current = &document;\n\n  for (const auto &token : pointer) {\n    const auto type{current->type()};\n    const auto is_object{type == sourcemeta::core::JSON::Type::Object};\n\n    if (token.is_property()) {\n      if (!is_object) {\n        return nullptr;\n      }\n\n      const auto &property{token.to_property()};\n      const auto *json_value{current->try_at(property, token.property_hash())};\n      if (json_value) {\n        current = json_value;\n      } else {\n        return nullptr;\n      }\n    } else if (type != sourcemeta::core::JSON::Type::Array && !is_object) {\n      return nullptr;\n    } else {\n      const auto index{token.to_index()};\n      if (index < current->size()) {\n        if (is_object) {\n          std::array<char, 20> buffer{};\n          const auto [end_pointer, error_code] = std::to_chars(\n              buffer.data(), buffer.data() + buffer.size(), index);\n          current = &current->at(std::string_view{buffer.data(), end_pointer});\n        } else {\n          current = &current->at(index);\n        }\n      } else {\n        return nullptr;\n      }\n    }\n  }\n\n  return current;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto get(const JSON &document, const Pointer &pointer) -> const JSON & {\n  if (pointer.empty()) {\n    return document;\n  }\n\n  return traverse_all<std::allocator, const JSON>(document, pointer);\n}\n\nauto get(const JSON &document, const WeakPointer &pointer) -> const JSON & {\n  if (pointer.empty()) {\n    return document;\n  }\n\n  return traverse_all<std::allocator, const JSON, WeakPointer>(document,\n                                                               pointer);\n}\n\nauto get(JSON &document, const Pointer &pointer) -> JSON & {\n  if (pointer.empty()) {\n    return document;\n  }\n\n  return traverse_all<std::allocator, JSON>(document, pointer);\n}\n\nauto get(JSON &document, const WeakPointer &pointer) -> JSON & {\n  if (pointer.empty()) {\n    return document;\n  }\n\n  return traverse_all<std::allocator, JSON>(document, pointer);\n}\n\nauto try_get(const JSON &document, const Pointer &pointer) -> const JSON * {\n  return pointer.empty() ? &document : try_traverse(document, pointer);\n}\n\nauto try_get(const JSON &document, const WeakPointer &pointer) -> const JSON * {\n  return pointer.empty() ? &document : try_traverse(document, pointer);\n}\n\nauto get(const JSON &document, const Pointer::Token &token) -> const JSON & {\n  if (token.is_property()) {\n    return document.at(token.to_property());\n  } else {\n    return document.at(token.to_index());\n  }\n}\n\nauto get(const JSON &document, const WeakPointer::Token &token)\n    -> const JSON & {\n  if (token.is_property()) {\n    return document.at(token.to_property());\n  } else {\n    return document.at(token.to_index());\n  }\n}\n\nauto get(JSON &document, const Pointer::Token &token) -> JSON & {\n  if (token.is_property()) {\n    return document.at(token.to_property());\n  } else {\n    return document.at(token.to_index());\n  }\n}\n\nauto set(JSON &document, const Pointer &pointer, const JSON &value) -> void {\n  if (pointer.empty()) {\n    document.into(value);\n    return;\n  }\n\n  JSON &current{traverse<std::allocator, JSON>(document, std::cbegin(pointer),\n                                               std::prev(std::cend(pointer)))};\n  const auto &last{pointer.back()};\n  // Handle the hyphen as a last constant\n  // If the currently referenced value is a JSON array, the reference\n  // token [can be ] the single character \"-\", making the new referenced value\n  // the (nonexistent) member after the last array element.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n  if (current.is_array() && last.is_hyphen()) {\n    current.push_back(value);\n  } else if (last.is_property()) {\n    current.at(last.to_property()).into(value);\n  } else {\n    if (current.is_object()) {\n      std::array<char, 20> buffer{};\n      const auto [end_pointer, error_code] = std::to_chars(\n          buffer.data(), buffer.data() + buffer.size(), last.to_index());\n      current.at(std::string_view{buffer.data(), end_pointer}).into(value);\n    } else {\n      current.at(last.to_index()).into(value);\n    }\n  }\n}\n\nauto set(JSON &document, const Pointer &pointer, JSON &&value) -> void {\n  if (pointer.empty()) {\n    document.into(value);\n    return;\n  }\n\n  JSON &current{traverse<std::allocator, JSON>(document, std::cbegin(pointer),\n                                               std::prev(std::cend(pointer)))};\n  const auto &last{pointer.back()};\n  // Handle the hyphen as a last constant\n  // If the currently referenced value is a JSON array, the reference\n  // token [can be ] the single character \"-\", making the new referenced value\n  // the (nonexistent) member after the last array element.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n  if (current.is_array() && last.is_hyphen()) {\n    current.push_back(value);\n  } else if (last.is_property()) {\n    current.at(last.to_property()).into(std::move(value));\n  } else {\n    current.at(last.to_index()).into(std::move(value));\n  }\n}\n\ntemplate <typename PointerT>\nauto remove_pointer(JSON &document, const PointerT &pointer) -> bool {\n  // Current implementation doesn't support removing an empty JSON pointer\n  // because we don't have a reference to the parent JSON object and there may\n  // be none (i.e. current object is the root JSON object). Here we are copying\n  // RapidJSON by making this a noop.\n  // https://github.com/Tencent/rapidjson/blob/24b5e7a8b27f42fa16b96fc70aade9106cf7102f/include/rapidjson/pointer.h#L835C9-L835C55\n  if (pointer.empty()) {\n    return false;\n  }\n\n  JSON &current{traverse<std::allocator, JSON, PointerT>(\n      document, std::cbegin(pointer), std::prev(std::cend(pointer)))};\n  const auto &last{pointer.back()};\n\n  if (last.is_property()) {\n    const auto current_size{current.size()};\n    return current.erase(last.to_property()) < current_size;\n  } else {\n    if (current.is_object()) {\n      std::array<char, 20> buffer{};\n      const auto [end_pointer, error_code] = std::to_chars(\n          buffer.data(), buffer.data() + buffer.size(), last.to_index());\n      const auto current_size{current.size()};\n      return current.erase(std::string_view{buffer.data(), end_pointer}) <\n             current_size;\n    } else {\n      const auto index{last.to_index()};\n      const auto &array{current.as_array()};\n\n      if (index >= array.size()) {\n        return false;\n      }\n\n      auto iterator{array.cbegin()};\n      std::advance(iterator, index);\n      current.erase(iterator);\n      return true;\n    }\n  }\n}\n\nauto remove(JSON &document, const Pointer &pointer) -> bool {\n  return remove_pointer(document, pointer);\n}\n\nauto remove(JSON &document, const WeakPointer &pointer) -> bool {\n  return remove_pointer(document, pointer);\n}\n\nauto to_pointer(const JSON &document) -> Pointer {\n  assert(document.is_string());\n  auto stream{document.to_stringstream()};\n  return parse_pointer<false>(stream);\n}\n\nauto to_pointer(\n    const std::basic_string_view<JSON::Char, JSON::CharTraits> input)\n    -> Pointer {\n  std::basic_istringstream<JSON::Char, JSON::CharTraits,\n                           std::allocator<JSON::Char>>\n      stream{std::basic_string<JSON::Char, JSON::CharTraits,\n                               std::allocator<JSON::Char>>{input}};\n  return parse_pointer<false>(stream);\n}\n\nauto to_pointer(const WeakPointer &pointer) -> Pointer {\n  Pointer result;\n  for (const auto &token : pointer) {\n    if (token.is_property()) {\n      result.push_back(token.to_property());\n    } else {\n      result.push_back(token.to_index());\n    }\n  }\n\n  return result;\n}\n\nauto to_weak_pointer(const Pointer &pointer) -> WeakPointer {\n  WeakPointer result;\n  for (const auto &token : pointer) {\n    if (token.is_property()) {\n      result.push_back(token.to_property());\n    } else {\n      result.push_back(token.to_index());\n    }\n  }\n\n  return result;\n}\n\nauto stringify(const Pointer &pointer,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void {\n  stringify<JSON::Char, JSON::CharTraits, std::allocator>(pointer, stream);\n}\n\nauto stringify(const WeakPointer &pointer,\n               std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void {\n  stringify<JSON::Char, JSON::CharTraits, std::allocator>(pointer, stream);\n}\n\nauto to_string(const Pointer &pointer)\n    -> std::basic_string<JSON::Char, JSON::CharTraits,\n                         std::allocator<JSON::Char>> {\n  std::basic_ostringstream<JSON::Char, JSON::CharTraits,\n                           std::allocator<JSON::Char>>\n      result;\n  stringify(pointer, result);\n  return result.str();\n}\n\nauto to_string(const WeakPointer &pointer)\n    -> std::basic_string<JSON::Char, JSON::CharTraits,\n                         std::allocator<JSON::Char>> {\n  std::basic_ostringstream<JSON::Char, JSON::CharTraits,\n                           std::allocator<JSON::Char>>\n      result;\n  stringify(pointer, result);\n  return result.str();\n}\n\nauto to_uri(const Pointer &pointer) -> URI {\n  std::basic_ostringstream<JSON::Char, JSON::CharTraits,\n                           std::allocator<JSON::Char>>\n      result;\n  stringify<JSON::Char, JSON::CharTraits, std::allocator>(pointer, result);\n  return URI::from_fragment(result.str());\n}\n\nauto to_uri(const Pointer &pointer, const URI &base) -> URI {\n  return to_uri(pointer).resolve_from(base).canonicalize();\n}\n\nauto to_uri(const WeakPointer &pointer) -> URI {\n  std::basic_ostringstream<JSON::Char, JSON::CharTraits,\n                           std::allocator<JSON::Char>>\n      result;\n  stringify(pointer, result);\n  return URI::from_fragment(result.str());\n}\n\nauto to_uri(const WeakPointer &pointer, const URI &base) -> URI {\n  return to_uri(pointer).resolve_from(base).canonicalize();\n}\n\nauto to_uri(const WeakPointer &pointer, const std::string_view base) -> URI {\n  if (base.empty()) {\n    return to_uri(pointer);\n  }\n\n  return to_uri(pointer).resolve_from(URI{base}).canonicalize();\n}\n\nauto is_pointer(const std::string_view input) noexcept -> bool {\n  try {\n    std::basic_istringstream<JSON::Char> stream{std::string{input}};\n    parse_pointer<true>(stream);\n    return true;\n  } catch (...) {\n    return false;\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/parser.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_PARSER_H_\n#define SOURCEMETA_CORE_JSONPOINTER_PARSER_H_\n\n#include \"grammar.h\"\n\n#include <sourcemeta/core/json_value.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonpointer_error.h>\n\n#include <charconv>     // std::from_chars\n#include <cstdint>      // std::uint64_t\n#include <istream>      // std::basic_istream\n#include <sstream>      // std::basic_stringstream\n#include <string>       // std::string\n#include <system_error> // std::errc\n#include <type_traits>  // std::conditional_t\n\nnamespace sourcemeta::core::internal {\ntemplate <typename CharT, typename Traits,\n          template <typename T> typename Allocator>\ninline auto\nreset(std::basic_stringstream<CharT, Traits, Allocator<CharT>> &stream)\n    -> void {\n  stream.str(\"\");\n  stream.clear();\n}\n\ntemplate <typename CharT, typename Traits,\n          template <typename T> typename Allocator>\ninline auto\nparse_index(std::basic_stringstream<CharT, Traits, Allocator<CharT>> &stream,\n            const std::uint64_t column) -> unsigned long {\n  const auto input = stream.str();\n  unsigned long index_value{};\n  const auto result =\n      std::from_chars(input.data(), input.data() + input.size(), index_value);\n  if (result.ec != std::errc{}) [[unlikely]] {\n    throw PointerParseError(column);\n  }\n\n  return index_value;\n}\n\n} // namespace sourcemeta::core::internal\n\n// We use \"goto\" for performance reasons\n// NOLINTBEGIN(cppcoreguidelines-avoid-goto)\n\nnamespace sourcemeta::core {\ntemplate <bool CheckOnly>\nauto parse_pointer(std::basic_istream<JSON::Char, JSON::CharTraits> &stream)\n    -> std::conditional_t<CheckOnly, void, Pointer> {\n  [[maybe_unused]] Pointer result;\n  JSON::Char character = 0;\n  [[maybe_unused]] std::basic_stringstream<JSON::Char> string;\n  std::uint64_t column{0};\n\nparse_token_begin:\n  character = static_cast<JSON::Char>(stream.get());\n  column += 1;\n  // A JSON Pointer is a Unicode string\n  // containing a sequence of zero or more reference tokens, each prefixed\n  // by a '/' (%x2F) character.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-3\n  switch (character) {\n    case internal::token_pointer_slash<JSON::Char>:\n      goto parse_token_content;\n    case static_cast<JSON::Char>(JSON::CharTraits::eof()):\n      goto done;\n    default:\n      throw PointerParseError(column);\n  }\n\nparse_token_content:\n  character = static_cast<JSON::Char>(stream.peek());\n  switch (character) {\n      // Note that leading zeros are not allowed\n      // See https://www.rfc-editor.org/rfc/rfc6901#section-4\n    case internal::token_pointer_number_zero<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      goto parse_token_index_end;\n    case internal::token_pointer_number_one<JSON::Char>:\n    case internal::token_pointer_number_two<JSON::Char>:\n    case internal::token_pointer_number_three<JSON::Char>:\n    case internal::token_pointer_number_four<JSON::Char>:\n    case internal::token_pointer_number_five<JSON::Char>:\n    case internal::token_pointer_number_six<JSON::Char>:\n    case internal::token_pointer_number_seven<JSON::Char>:\n    case internal::token_pointer_number_eight<JSON::Char>:\n    case internal::token_pointer_number_nine<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        string.put(character);\n      }\n      goto parse_token_index_rest_any;\n    case static_cast<JSON::Char>(JSON::CharTraits::eof()):\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        result.emplace_back(\"\");\n      }\n      goto done;\n    case internal::token_pointer_slash<JSON::Char>:\n      if constexpr (!CheckOnly) {\n        result.emplace_back(\"\");\n      }\n      goto parse_token_begin;\n    case internal::token_pointer_tilde<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      goto parse_token_escape_tilde;\n    default:\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        string.put(character);\n      }\n      goto parse_token_property_rest_any;\n  }\n\n  /*\n   * Indexes\n   */\n\nparse_token_index_end:\n  if constexpr (!CheckOnly) {\n    string.put(character);\n  }\n  character = static_cast<JSON::Char>(stream.peek());\n  switch (character) {\n    case internal::token_pointer_slash<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        result.emplace_back(internal::parse_index(string, column));\n        internal::reset(string);\n      }\n      goto parse_token_content;\n    case static_cast<JSON::Char>(JSON::CharTraits::eof()):\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        result.emplace_back(internal::parse_index(string, column));\n        internal::reset(string);\n      }\n      goto done;\n    default:\n      goto parse_token_property_rest_any;\n  }\n\nparse_token_index_rest_any:\n  character = static_cast<JSON::Char>(stream.peek());\n  switch (character) {\n    case internal::token_pointer_slash<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        result.emplace_back(internal::parse_index(string, column));\n        internal::reset(string);\n      }\n      goto parse_token_content;\n    case static_cast<JSON::Char>(JSON::CharTraits::eof()):\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        result.emplace_back(internal::parse_index(string, column));\n        internal::reset(string);\n      }\n      goto done;\n    case internal::token_pointer_number_zero<JSON::Char>:\n    case internal::token_pointer_number_one<JSON::Char>:\n    case internal::token_pointer_number_two<JSON::Char>:\n    case internal::token_pointer_number_three<JSON::Char>:\n    case internal::token_pointer_number_four<JSON::Char>:\n    case internal::token_pointer_number_five<JSON::Char>:\n    case internal::token_pointer_number_six<JSON::Char>:\n    case internal::token_pointer_number_seven<JSON::Char>:\n    case internal::token_pointer_number_eight<JSON::Char>:\n    case internal::token_pointer_number_nine<JSON::Char>:\n      column += 1;\n      stream.ignore();\n      if constexpr (!CheckOnly) {\n        string.put(character);\n      }\n      goto parse_token_index_rest_any;\n\n    default:\n      goto parse_token_property_rest_any;\n  }\n\n  /*\n   * Properties\n   */\n\nparse_token_property_rest_any:\n  character = static_cast<JSON::Char>(stream.get());\n  column += 1;\n  switch (character) {\n    case internal::token_pointer_slash<JSON::Char>:\n      if constexpr (!CheckOnly) {\n        result.emplace_back(string.str());\n        internal::reset(string);\n      }\n      goto parse_token_content;\n    case internal::token_pointer_tilde<JSON::Char>:\n      goto parse_token_escape_tilde;\n    case static_cast<JSON::Char>(JSON::CharTraits::eof()):\n      if constexpr (!CheckOnly) {\n        result.emplace_back(string.str());\n        internal::reset(string);\n      }\n      goto done;\n    default:\n      if constexpr (!CheckOnly) {\n        string.put(character);\n      }\n      goto parse_token_property_rest_any;\n  }\n\nparse_token_escape_tilde:\n  character = static_cast<JSON::Char>(stream.get());\n  column += 1;\n  // Because the characters '~' (%x7E) and '/' (%x2F) have special\n  // meanings in JSON Pointer, '~' needs to be encoded as '~0' and '/'\n  // needs to be encoded as '~1' when these characters appear in a\n  // reference token.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-3\n  switch (character) {\n    case internal::token_pointer_number_zero<JSON::Char>:\n      if constexpr (!CheckOnly) {\n        string.put(internal::token_pointer_tilde<JSON::Char>);\n      }\n      goto parse_token_property_rest_any;\n    case internal::token_pointer_number_one<JSON::Char>:\n      if constexpr (!CheckOnly) {\n        string.put(internal::token_pointer_slash<JSON::Char>);\n      }\n      goto parse_token_property_rest_any;\n    default:\n      throw PointerParseError(column);\n  }\n\ndone:\n  if constexpr (!CheckOnly) {\n    return result;\n  }\n}\n\n// NOLINTEND(cppcoreguidelines-avoid-goto)\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/position.cc",
    "content": "#include <sourcemeta/core/json_value.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <algorithm>   // std::count_if\n#include <cassert>     // assert\n#include <cstddef>     // std::size_t\n#include <cstdint>     // std::uint64_t\n#include <optional>    // std::optional\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\nauto PointerPositionTracker::ensure_index() const -> void {\n  if (this->indexed) {\n    return;\n  }\n\n  this->indexed = true;\n  this->trie.push_back({.position = std::nullopt,\n                        .index_children = {},\n                        .property_children = {}});\n\n  std::size_t current_node{0};\n  std::vector<std::pair<std::size_t, std::pair<std::uint64_t, std::uint64_t>>>\n      node_stack;\n\n  for (const auto &event : this->events) {\n    switch (event.phase) {\n      case JSON::ParsePhase::Pre:\n        node_stack.emplace_back(current_node,\n                                std::make_pair(event.line, event.column));\n\n        switch (event.context) {\n          case JSON::ParseContext::Property: {\n            assert(event.property != nullptr);\n            const std::string_view key{*event.property};\n            auto iterator{this->trie[current_node].property_children.find(key)};\n            if (iterator == this->trie[current_node].property_children.end()) {\n              const auto node_index{this->trie.size()};\n              this->trie.push_back({.position = std::nullopt,\n                                    .index_children = {},\n                                    .property_children = {}});\n              this->trie[current_node].property_children.emplace(key,\n                                                                 node_index);\n              current_node = node_index;\n            } else {\n              current_node = iterator->second;\n            }\n            break;\n          }\n          case JSON::ParseContext::Index: {\n            auto iterator{\n                this->trie[current_node].index_children.find(event.index)};\n            if (iterator == this->trie[current_node].index_children.end()) {\n              const auto node_index{this->trie.size()};\n              this->trie.push_back({.position = std::nullopt,\n                                    .index_children = {},\n                                    .property_children = {}});\n              this->trie[current_node].index_children.emplace(event.index,\n                                                              node_index);\n              current_node = node_index;\n            } else {\n              current_node = iterator->second;\n            }\n            break;\n          }\n          case JSON::ParseContext::Root:\n            break;\n        }\n\n        break;\n      case JSON::ParsePhase::Post:\n        assert(!node_stack.empty());\n        this->trie[current_node].position =\n            Position{node_stack.back().second.first,\n                     node_stack.back().second.second, event.line, event.column};\n        current_node = node_stack.back().first;\n        node_stack.pop_back();\n        break;\n      default:\n        assert(false);\n        break;\n    }\n  }\n}\n\nauto PointerPositionTracker::operator()(\n    const JSON::ParsePhase phase, const JSON::Type, const std::uint64_t line,\n    const std::uint64_t column, const JSON::ParseContext context,\n    const std::size_t index, const JSON::String &property) -> void {\n  this->events.push_back({.phase = phase,\n                          .context = context,\n                          .index = index,\n                          .property = context == JSON::ParseContext::Property\n                                          ? &property\n                                          : nullptr,\n                          .line = line,\n                          .column = column});\n}\n\nauto PointerPositionTracker::get(const Pointer &pointer) const\n    -> std::optional<Position> {\n  this->ensure_index();\n  std::size_t node{0};\n  for (const auto &token : pointer) {\n    if (token.is_property()) {\n      const auto &children{this->trie[node].property_children};\n      const auto iterator{children.find(std::string_view{token.to_property()})};\n      if (iterator == children.end()) {\n        return std::nullopt;\n      }\n      node = iterator->second;\n    } else {\n      const auto &children{this->trie[node].index_children};\n      const auto iterator{children.find(token.to_index())};\n      if (iterator == children.end()) {\n        return std::nullopt;\n      }\n      node = iterator->second;\n    }\n  }\n\n  return this->trie[node].position;\n}\n\nauto PointerPositionTracker::size() const -> std::size_t {\n  return static_cast<std::size_t>(std::count_if(\n      this->events.cbegin(), this->events.cend(), [](const Event &event) {\n        return event.phase == JSON::ParsePhase::Post;\n      }));\n}\n\nauto PointerPositionTracker::to_json() const -> JSON {\n  auto result{JSON::make_object()};\n  Pointer current;\n  std::vector<std::pair<std::uint64_t, std::uint64_t>> start_stack;\n\n  for (const auto &event : this->events) {\n    switch (event.phase) {\n      case JSON::ParsePhase::Pre:\n        start_stack.emplace_back(event.line, event.column);\n        switch (event.context) {\n          case JSON::ParseContext::Property:\n            assert(event.property != nullptr);\n            current.push_back(*event.property);\n            break;\n          case JSON::ParseContext::Index:\n            current.push_back(event.index);\n            break;\n          default:\n            break;\n        }\n\n        break;\n      case JSON::ParsePhase::Post:\n        assert(!start_stack.empty());\n        result.assign_assume_new(\n            to_string(current),\n            sourcemeta::core::to_json(Position{start_stack.back().first,\n                                               start_stack.back().second,\n                                               event.line, event.column}));\n        start_stack.pop_back();\n        if (!current.empty()) {\n          current.pop_back();\n        }\n\n        break;\n      default:\n        assert(false);\n        break;\n    }\n  }\n\n  assert(current.empty());\n  assert(start_stack.empty());\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonpointer/stringify.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONPOINTER_STRINGIFY_H_\n#define SOURCEMETA_CORE_JSONPOINTER_STRINGIFY_H_\n\n#include <sourcemeta/core/json_value.h>\n#include <sourcemeta/core/uri.h>\n\n#include \"grammar.h\"\n\n#include <array>    // std::array\n#include <cassert>  // assert\n#include <charconv> // std::to_chars\n#include <ios>      // std::basic_ostream\n#include <ostream>  // std::basic_ostream\n#include <sstream>  // std::basic_istringstream\n#include <string>   // std::basic_string\n#include <variant>  // std::holds_alternative\n\nnamespace sourcemeta::core::internal {\ninline auto\nwrite_character(std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                const JSON::Char character) -> void {\n  stream.put(character);\n}\n} // namespace sourcemeta::core::internal\n\nnamespace sourcemeta::core {\n\ntemplate <typename CharT, typename Traits,\n          template <typename T> typename Allocator, typename TokenT>\nauto stringify_token(const TokenT &token,\n                     std::basic_ostream<CharT, Traits> &stream) -> void {\n  // A JSON Pointer is a Unicode string (see [RFC4627], Section 3)\n  // containing a sequence of zero or more reference tokens, each prefixed\n  // by a '/' (%x2F) character.\n  // See https://www.rfc-editor.org/rfc/rfc6901#section-3\n  stream.put(internal::token_pointer_slash<CharT>);\n  if (token.is_property()) {\n    for (const auto &character : token.to_property()) {\n      switch (character) {\n        // Because the characters '~' (%x7E) and '/' (%x2F) have special\n        // meanings in JSON Pointer, '~' needs to be encoded as '~0' and '/'\n        // needs to be encoded as '~1' when these characters appear in a\n        // reference token.\n        // See https://www.rfc-editor.org/rfc/rfc6901#section-3\n        case internal::token_pointer_slash<CharT>:\n          stream.put(internal::token_pointer_tilde<CharT>);\n          stream.put(internal::token_pointer_one<CharT>);\n          break;\n        case internal::token_pointer_tilde<CharT>:\n          stream.put(internal::token_pointer_tilde<CharT>);\n          stream.put(internal::token_pointer_zero<CharT>);\n          break;\n\n        // All instances of quotation mark '\"' (%x22), reverse solidus '\\'\n        // (%x5C), and control (%x00-1F) characters MUST be escaped. See\n        // https://www.rfc-editor.org/rfc/rfc6901#section-5\n        case internal::token_pointer_quote<CharT>:\n          internal::write_character(stream,\n                                    internal::token_pointer_quote<CharT>);\n          break;\n        case internal::token_pointer_reverse_solidus<CharT>:\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          break;\n\n        // See https://www.asciitable.com\n        // See https://www.rfc-editor.org/rfc/rfc4627#section-2.5\n\n        // Null\n        case '\\u0000':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          break;\n        // Start of heading\n        case '\\u0001':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          break;\n        // Start of text\n        case '\\u0002':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('2');\n          break;\n        // End of text\n        case '\\u0003':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('3');\n          break;\n        // End of transmission\n        case '\\u0004':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('4');\n          break;\n        // Enquiry\n        case '\\u0005':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('5');\n          break;\n        // Acknowledge\n        case '\\u0006':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('6');\n          break;\n        // Bell\n        case '\\u0007':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('7');\n          break;\n        // Backspace\n        case '\\u0008':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_backspace<CharT>);\n          break;\n        // Horizontal tab\n        case '\\u0009':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_tab<CharT>);\n          break;\n        // Line feed\n        case '\\u000A':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_line_feed<CharT>);\n          break;\n        // Vertical tab\n        case '\\u000B':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('B');\n          break;\n        // Form feed\n        case '\\u000C':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_form_feed<CharT>);\n          break;\n        // Carriage return\n        case '\\u000D':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_carriage_return<CharT>);\n          break;\n        // Shift out\n        case '\\u000E':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('E');\n          break;\n        // Shift in\n        case '\\u000F':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('0');\n          stream.put('F');\n          break;\n        // Data link escape\n        case '\\u0010':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('0');\n          break;\n        // Device control 1\n        case '\\u0011':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('1');\n          break;\n        // Device control 2\n        case '\\u0012':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('2');\n          break;\n        // Device control 3\n        case '\\u0013':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('3');\n          break;\n        // Device control 4\n        case '\\u0014':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('4');\n          break;\n        // Negative acknowledge\n        case '\\u0015':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('5');\n          break;\n        // Synchronous idle\n        case '\\u0016':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('6');\n          break;\n        // End of transmission block\n        case '\\u0017':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('7');\n          break;\n        // Cancel\n        case '\\u0018':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('8');\n          break;\n        // End of medium\n        case '\\u0019':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('9');\n          break;\n        // Substitute\n        case '\\u001A':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('A');\n          break;\n        // Escape\n        case '\\u001B':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('B');\n          break;\n        // File separator\n        case '\\u001C':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('C');\n          break;\n        // Group separator\n        case '\\u001D':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('D');\n          break;\n        // Record separator\n        case '\\u001E':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('E');\n          break;\n        // Unit separator\n        case '\\u001F':\n          internal::write_character(\n              stream, internal::token_pointer_reverse_solidus<CharT>);\n          stream.put(internal::token_pointer_escape_unicode<CharT>);\n          stream.put('0');\n          stream.put('0');\n          stream.put('1');\n          stream.put('F');\n          break;\n        default:\n          internal::write_character(stream, character);\n      }\n    }\n  } else {\n    std::array<char, 20> buffer{};\n    const auto [end_pointer, error_code] = std::to_chars(\n        buffer.data(), buffer.data() + buffer.size(), token.to_index());\n    stream.write(\n        buffer.data(),\n        static_cast<typename std::basic_ostream<CharT, Traits>::int_type>(\n            end_pointer - buffer.data()));\n  }\n}\n\ntemplate <typename CharT, typename Traits,\n          template <typename T> typename Allocator, typename PointerT>\nauto stringify(const PointerT &pointer,\n               std::basic_ostream<CharT, Traits> &stream) -> void {\n  if constexpr (requires { typename PointerT::Wildcard; }) {\n    for (const auto &token : pointer) {\n      if (std::holds_alternative<typename PointerT::Wildcard>(token)) {\n        // Represent wildcards using an impossible JSON Pointer token\n        stream.put(internal::token_pointer_slash<CharT>);\n        stream.put(internal::token_pointer_tilde<CharT>);\n\n        switch (std::get<typename PointerT::Wildcard>(token)) {\n          case PointerT::Wildcard::Property:\n            stream.put('P');\n            break;\n          case PointerT::Wildcard::Item:\n            stream.put('I');\n            break;\n          case PointerT::Wildcard::Key:\n            stream.put('K');\n            break;\n          default:\n            assert(false);\n            break;\n        }\n\n        stream.put(internal::token_pointer_tilde<CharT>);\n      } else if (std::holds_alternative<typename PointerT::Regex>(token)) {\n        // Represent wildcards using an impossible JSON Pointer token\n        stream.put(internal::token_pointer_slash<CharT>);\n        stream.put(internal::token_pointer_tilde<CharT>);\n        stream.put('R');\n        const auto &value{std::get<typename PointerT::Regex>(token)};\n        stream.write(value.c_str(), static_cast<std::streamsize>(value.size()));\n        stream.put(internal::token_pointer_tilde<CharT>);\n      } else if (std::holds_alternative<typename PointerT::Condition>(token)) {\n        stream.put(internal::token_pointer_slash<CharT>);\n        stream.put(internal::token_pointer_tilde<CharT>);\n        stream.put('?');\n        const auto &value{std::get<typename PointerT::Condition>(token)};\n        if (value.suffix.has_value()) {\n          stream.write(value.suffix->c_str(),\n                       static_cast<std::streamsize>(value.suffix->size()));\n        }\n\n        stream.put(internal::token_pointer_tilde<CharT>);\n      } else if (std::holds_alternative<typename PointerT::Negation>(token)) {\n        stream.put(internal::token_pointer_slash<CharT>);\n        stream.put(internal::token_pointer_tilde<CharT>);\n        stream.put('!');\n        stream.put(internal::token_pointer_tilde<CharT>);\n      } else {\n        stringify_token<CharT, Traits, Allocator, typename PointerT::Token>(\n            std::get<typename PointerT::Token>(token), stream);\n      }\n    }\n  } else {\n    for (const auto &token : pointer) {\n      stringify_token<CharT, Traits, Allocator, typename PointerT::Token>(\n          token, stream);\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/CMakeLists.txt",
    "content": "set(KNOWN_RESOLVER_INPUT \"${CMAKE_CURRENT_SOURCE_DIR}/known_resolver.in.cc\")\nset(KNOWN_RESOLVER_OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/known_resolver.cc\")\ninclude(./known_resolver.cmake)\n\nsourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME jsonschema\n  PRIVATE_HEADERS bundle.h walker.h frame.h error.h\n                  types.h vocabularies.h\n  SOURCES jsonschema.cc vocabularies.cc known_walker.cc\n          frame.cc walker.cc bundle.cc format.cc helpers.h\n    \"${CMAKE_CURRENT_BINARY_DIR}/known_resolver.cc\")\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME jsonschema)\nendif()\n\ntarget_link_libraries(sourcemeta_core_jsonschema PUBLIC\n  sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_core_jsonschema PUBLIC\n  sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_core_jsonschema PRIVATE\n  sourcemeta::core::uri)\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/bundle.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include \"helpers.h\"\n\n#include <cassert>       // assert\n#include <functional>    // std::reference_wrapper\n#include <string>        // std::string\n#include <tuple>         // std::tuple\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::move\n#include <vector>        // std::vector\n\nnamespace {\n\nauto is_official_metaschema_reference(\n    const sourcemeta::core::WeakPointer &pointer,\n    const std::string &destination) -> bool {\n  assert(!pointer.empty());\n  assert(pointer.back().is_property());\n  return pointer.back().to_property() == \"$schema\" &&\n         sourcemeta::core::is_known_schema(destination);\n}\n\nauto dependencies_internal(const sourcemeta::core::JSON &schema,\n                           const sourcemeta::core::SchemaWalker &walker,\n                           const sourcemeta::core::SchemaResolver &resolver,\n                           const sourcemeta::core::DependencyCallback &callback,\n                           std::string_view default_dialect,\n                           std::string_view default_id,\n                           const sourcemeta::core::SchemaFrame::Paths &paths,\n                           std::unordered_set<std::string> &visited) -> void {\n  sourcemeta::core::SchemaFrame frame{\n      sourcemeta::core::SchemaFrame::Mode::References};\n  frame.analyse(schema, walker, resolver, default_dialect, default_id, paths);\n  const auto origin{sourcemeta::core::identify(schema, resolver,\n                                               default_dialect, default_id)};\n\n  std::vector<\n      std::tuple<sourcemeta::core::JSON, sourcemeta::core::JSON::String>>\n      found;\n\n  frame.for_each_unresolved_reference([&](const auto &pointer,\n                                          const auto &reference) {\n    // We don't want to report official schemas, as we can expect\n    // virtually all implementations to understand them out of the box\n    if (is_official_metaschema_reference(pointer, reference.destination)) {\n      return;\n    }\n\n    if (reference.base.empty()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          reference.destination, sourcemeta::core::to_pointer(pointer),\n          \"Could not resolve schema reference\");\n    }\n\n    // To not infinitely loop on circular references\n    if (visited.contains(std::string{reference.base})) {\n      return;\n    }\n\n    // If we can't find the destination but there is a base and we can\n    // find the base, then we are facing an unresolved fragment\n    if (frame.traverse(reference.base).has_value()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          reference.destination, sourcemeta::core::to_pointer(pointer),\n          \"Could not resolve schema reference\");\n    }\n\n    assert(!reference.base.empty());\n    const auto &identifier{reference.base};\n    auto remote{resolver(identifier)};\n    if (!remote.has_value()) {\n      throw sourcemeta::core::SchemaResolutionError(\n          identifier, \"Could not resolve the reference to an external schema\");\n    }\n\n    if (!sourcemeta::core::is_schema(remote.value())) {\n      throw sourcemeta::core::SchemaReferenceError(\n          identifier, sourcemeta::core::to_pointer(pointer),\n          \"The JSON document is not a valid JSON Schema\");\n    }\n\n    const auto remote_base_dialect{sourcemeta::core::base_dialect(\n        remote.value(), resolver, default_dialect)};\n    if (!remote_base_dialect.has_value()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          identifier, sourcemeta::core::to_pointer(pointer),\n          \"The JSON document is not a valid JSON Schema\");\n    }\n\n    callback(origin, pointer, identifier, remote.value());\n    found.emplace_back(std::move(remote).value(),\n                       sourcemeta::core::JSON::String{identifier});\n    visited.emplace(identifier);\n  });\n\n  for (const auto &entry : found) {\n    dependencies_internal(std::get<0>(entry), walker, resolver, callback,\n                          default_dialect, std::get<1>(entry),\n                          {sourcemeta::core::empty_weak_pointer}, visited);\n  }\n}\n\nauto embed_schema(sourcemeta::core::JSON &root,\n                  const sourcemeta::core::Pointer &container,\n                  const std::string_view identifier,\n                  sourcemeta::core::JSON &&target) -> void {\n  auto *current{&root};\n  for (const auto &token : container) {\n    if (token.is_property()) {\n      current->assign_if_missing(token.to_property(),\n                                 sourcemeta::core::JSON::make_object());\n      current = &current->at(token.to_property());\n    } else {\n      assert(current->is_array() && current->size() >= token.to_index());\n      current = &current->at(token.to_index());\n    }\n  }\n\n  if (!current->is_object()) {\n    throw sourcemeta::core::SchemaError(\n        \"Could not bundle to a container path that is not an object\");\n  }\n\n  std::string key{identifier};\n  // Ensure we get a definitions entry that does not exist\n  while (current->defines(key)) {\n    key += \"/x\";\n  }\n\n  current->assign(key, std::move(target));\n}\n\nauto elevate_embedded_resources(\n    sourcemeta::core::JSON &remote, sourcemeta::core::JSON &root,\n    const sourcemeta::core::Pointer &container,\n    const sourcemeta::core::SchemaBaseDialect remote_dialect,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect,\n    std::unordered_map<sourcemeta::core::JSON::String,\n                       sourcemeta::core::JSON::String> &bundled) -> void {\n  const auto keyword{sourcemeta::core::definitions_keyword(remote_dialect)};\n  const sourcemeta::core::JSON::String keyword_string{keyword};\n  if (keyword.empty() || !remote.is_object() ||\n      !remote.defines(keyword_string) ||\n      !remote.at(keyword_string).is_object()) {\n    return;\n  }\n\n  auto &defs{remote.at(keyword_string)};\n\n  // Navigate to the root container once, as it doesn't change per entry\n  const sourcemeta::core::JSON *root_container{&root};\n  bool container_exists{true};\n  for (const auto &token : container) {\n    if (!token.is_property() || !root_container->is_object() ||\n        !root_container->defines(token.to_property())) {\n      container_exists = false;\n      break;\n    }\n\n    root_container = &root_container->at(token.to_property());\n  }\n\n  std::vector<sourcemeta::core::JSON::String> to_extract;\n  std::vector<sourcemeta::core::JSON::String> to_remove;\n  for (const auto &entry : defs.as_object()) {\n    const auto &key{entry.first};\n    const auto &value{entry.second};\n    const auto entry_dialect{\n        sourcemeta::core::base_dialect(value, resolver, default_dialect)};\n    const auto effective_entry_dialect{entry_dialect.value_or(remote_dialect)};\n    const auto identifier{\n        sourcemeta::core::identify(value, effective_entry_dialect)};\n    if (identifier.empty() || identifier != key ||\n        !sourcemeta::core::URI{identifier}.is_absolute()) {\n      continue;\n    }\n\n    const sourcemeta::core::JSON::String identifier_string{identifier};\n    if (bundled.contains(identifier_string)) {\n      if (container_exists && root_container->is_object()) {\n        for (const auto &root_entry : root_container->as_object()) {\n          if (!root_entry.first.starts_with(identifier_string)) {\n            continue;\n          }\n\n          const auto stored_dialect{sourcemeta::core::base_dialect(\n              root_entry.second, resolver, default_dialect)};\n          const auto effective_stored_dialect{stored_dialect.has_value()\n                                                  ? stored_dialect.value()\n                                                  : remote_dialect};\n          const auto stored_id{sourcemeta::core::identify(\n              root_entry.second, effective_stored_dialect)};\n          if (stored_id != identifier_string) {\n            continue;\n          }\n\n          if (root_entry.second != value) {\n            throw sourcemeta::core::SchemaError(\n                \"Conflicting embedded resources with the same identifier\");\n          }\n\n          break;\n        }\n      }\n\n      to_remove.emplace_back(key);\n    } else {\n      to_extract.emplace_back(key);\n      bundled.emplace(identifier_string, identifier_string);\n    }\n  }\n\n  for (const auto &key : to_extract) {\n    auto value{std::move(defs.at(key))};\n    defs.erase(key);\n    embed_schema(root, container, key, std::move(value));\n  }\n\n  for (const auto &key : to_remove) {\n    defs.erase(key);\n  }\n\n  if (defs.empty()) {\n    remote.erase(sourcemeta::core::JSON::String{keyword});\n  }\n}\n\nauto bundle_schema(sourcemeta::core::JSON &root,\n                   const sourcemeta::core::Pointer &container,\n                   sourcemeta::core::JSON &subschema,\n                   const sourcemeta::core::SchemaWalker &walker,\n                   const sourcemeta::core::SchemaResolver &resolver,\n                   std::string_view default_dialect,\n                   std::string_view default_id,\n                   const sourcemeta::core::SchemaFrame::Paths &paths,\n                   std::unordered_map<sourcemeta::core::JSON::String,\n                                      sourcemeta::core::JSON::String> &bundled,\n                   const std::size_t depth = 0) -> void {\n  // Create a fresh frame for each schema we analyze to avoid key collisions\n  // between different schemas that have references at the same pointer paths\n  sourcemeta::core::SchemaFrame frame{\n      sourcemeta::core::SchemaFrame::Mode::References};\n  if (depth == 0) {\n    frame.analyse(\n        subschema, walker, resolver, default_dialect, default_id,\n        // We only want to frame in \"wrapper\" mode for the top level object\n        paths);\n  } else {\n    frame.analyse(subschema, walker, resolver, default_dialect, default_id);\n  }\n\n  std::vector<std::tuple<sourcemeta::core::JSON, sourcemeta::core::JSON::String,\n                         sourcemeta::core::SchemaBaseDialect>>\n      deferred;\n  std::vector<\n      std::pair<sourcemeta::core::Pointer, sourcemeta::core::JSON::String>>\n      ref_rewrites;\n\n  frame.for_each_unresolved_reference([&](const auto &pointer,\n                                          const auto &reference) {\n    // We don't want to bundle official schemas, as we can expect\n    // virtually all implementations to understand them out of the box\n    if (is_official_metaschema_reference(pointer, reference.destination)) {\n      return;\n    }\n\n    // If we can't find the destination but there is a base and we can\n    // find base, then we are facing an unresolved fragment\n    if (!reference.base.empty() && frame.traverse(reference.base).has_value()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          reference.destination, sourcemeta::core::to_pointer(pointer),\n          \"Could not resolve schema reference\");\n    }\n\n    if (reference.base.empty()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          reference.destination, sourcemeta::core::to_pointer(pointer),\n          \"Could not resolve schema reference\");\n    }\n\n    assert(!reference.base.empty());\n    const sourcemeta::core::JSON::String identifier{reference.base};\n\n    if (bundled.contains(identifier)) {\n      const auto &mapped_id{bundled.at(identifier)};\n      if (mapped_id != identifier) {\n        sourcemeta::core::URI rewrite_uri{mapped_id};\n        if (reference.fragment.has_value()) {\n          rewrite_uri.fragment(reference.fragment.value());\n        }\n\n        ref_rewrites.emplace_back(sourcemeta::core::to_pointer(pointer),\n                                  rewrite_uri.recompose());\n      }\n\n      return;\n    }\n\n    auto remote{resolver(identifier)};\n    if (!remote.has_value()) {\n      if (frame.traverse(identifier).has_value()) {\n        throw sourcemeta::core::SchemaReferenceError(\n            reference.destination, sourcemeta::core::to_pointer(pointer),\n            \"Could not resolve schema reference\");\n      }\n\n      throw sourcemeta::core::SchemaResolutionError(\n          identifier, \"Could not resolve the reference to an external schema\");\n    }\n\n    if (!sourcemeta::core::is_schema(remote.value())) {\n      throw sourcemeta::core::SchemaReferenceError(\n          identifier, sourcemeta::core::to_pointer(pointer),\n          \"The JSON document is not a valid JSON Schema\");\n    }\n\n    const auto remote_base_dialect{sourcemeta::core::base_dialect(\n        remote.value(), resolver, default_dialect)};\n    if (!remote_base_dialect.has_value()) {\n      throw sourcemeta::core::SchemaReferenceError(\n          identifier, sourcemeta::core::to_pointer(pointer),\n          \"The JSON document is not a valid JSON Schema\");\n    }\n\n    auto remote_id =\n        sourcemeta::core::identify(remote.value(), resolver, default_dialect);\n\n    // If the reference has a fragment, verify it exists in the remote\n    // schema\n    if (reference.fragment.has_value()) {\n      // TODO: The fact that we have to re-frame on each loop pass to check\n      // for this is probably insanely slow\n      sourcemeta::core::SchemaFrame remote_frame{\n          sourcemeta::core::SchemaFrame::Mode::Locations};\n      remote_frame.analyse(remote.value(), walker, resolver, default_dialect,\n                           identifier);\n      if (!remote_frame.traverse(reference.destination).has_value()) {\n        throw sourcemeta::core::SchemaReferenceError(\n            reference.destination, sourcemeta::core::to_pointer(pointer),\n            \"Could not resolve schema reference\");\n      }\n    }\n\n    sourcemeta::core::JSON::String effective_id{\n        remote_id.empty() ? sourcemeta::core::JSON::String{identifier}\n                          : sourcemeta::core::JSON::String{remote_id}};\n\n    if (remote.value().is_object()) {\n      sourcemeta::core::reidentify(remote.value(), effective_id,\n                                   remote_base_dialect.value());\n    }\n\n    if (effective_id != identifier) {\n      sourcemeta::core::URI rewrite_uri{effective_id};\n      if (reference.fragment.has_value()) {\n        rewrite_uri.fragment(reference.fragment.value());\n      }\n\n      ref_rewrites.emplace_back(sourcemeta::core::to_pointer(pointer),\n                                rewrite_uri.recompose());\n    }\n\n    bundled.emplace(identifier, effective_id);\n    bundled.emplace(effective_id, effective_id);\n    deferred.emplace_back(std::move(remote).value(), std::move(effective_id),\n                          remote_base_dialect.value());\n  });\n\n  for (auto &[rewrite_pointer, rewrite_value] : ref_rewrites) {\n    sourcemeta::core::set(subschema, rewrite_pointer,\n                          sourcemeta::core::JSON{rewrite_value});\n  }\n\n  for (auto &[remote, effective_id, remote_dialect] : deferred) {\n    bundle_schema(root, container, remote, walker, resolver, default_dialect,\n                  effective_id, paths, bundled, depth + 1);\n    elevate_embedded_resources(remote, root, container, remote_dialect,\n                               resolver, default_dialect, bundled);\n    embed_schema(root, container, effective_id, std::move(remote));\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto dependencies(const JSON &schema, const SchemaWalker &walker,\n                  const SchemaResolver &resolver,\n                  const DependencyCallback &callback,\n                  std::string_view default_dialect, std::string_view default_id,\n                  const SchemaFrame::Paths &paths) -> void {\n  std::unordered_set<std::string> visited;\n  dependencies_internal(schema, walker, resolver, callback, default_dialect,\n                        default_id, paths, visited);\n}\n\n// TODO: Refactor this function to internally rely on the `.dependencies()`\n// function\nauto bundle(JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver, std::string_view default_dialect,\n            std::string_view default_id,\n            const std::optional<Pointer> &default_container,\n            const SchemaFrame::Paths &paths) -> void {\n  // Pre-scan the schema to find any already-embedded schemas and mark them\n  // as bundled to avoid re-embedding them. This includes the root schema itself\n  // and any schemas already embedded within it\n  std::unordered_map<JSON::String, JSON::String> bundled;\n  SchemaFrame initial_frame{SchemaFrame::Mode::Locations};\n  initial_frame.analyse(schema, walker, resolver, default_dialect, default_id,\n                        paths);\n  initial_frame.for_each_resource_uri([&bundled](const auto &uri) {\n    bundled.emplace(JSON::String{uri}, JSON::String{uri});\n  });\n  if (default_container.has_value()) {\n    // This is undefined behavior\n    assert(!default_container.value().empty());\n    bundle_schema(schema, default_container.value(), schema, walker, resolver,\n                  default_dialect, default_id, paths, bundled);\n    return;\n  }\n\n  // If the schema identifier is implicit, add it to the top-level of the\n  // bundled schema. Otherwise, potential relative references based on this\n  // implicit base URI will likely not resolve unless end users happen to\n  // know that this implicit base URI is.\n  if (!default_id.empty() &&\n      identify(schema, resolver, default_dialect).empty()) {\n    reidentify(schema, default_id, resolver, default_dialect);\n  }\n\n  const auto schema_base_dialect{\n      base_dialect(schema, resolver, default_dialect)};\n  if (!schema_base_dialect.has_value()) {\n    throw SchemaError(\n        \"Could not determine how to perform bundling in this dialect\");\n  }\n\n  const auto container_keyword{\n      definitions_keyword(schema_base_dialect.value())};\n  if (container_keyword.empty()) {\n    SchemaFrame frame{SchemaFrame::Mode::References};\n    frame.analyse(schema, walker, resolver, default_dialect, default_id);\n    if (frame.standalone()) {\n      return;\n    }\n\n    throw SchemaError(\n        \"Could not determine how to perform bundling in this dialect\");\n  }\n\n  if (ref_overrides_adjacent_keywords(schema_base_dialect.value()) &&\n      schema.is_object() && schema.defines(\"$ref\")) {\n    if (schema.size() == 1) {\n      const auto is_draft3{schema_base_dialect.value() ==\n                               SchemaBaseDialect::JSON_Schema_Draft_3 ||\n                           schema_base_dialect.value() ==\n                               SchemaBaseDialect::JSON_Schema_Draft_3_Hyper};\n      auto branches{JSON::make_array()};\n      branches.push_back(schema);\n      schema.at(\"$ref\").into(std::move(branches));\n      schema.rename(\"$ref\", is_draft3 ? \"extends\" : \"allOf\");\n    } else {\n      throw SchemaError(\n          \"Cannot bundle a JSON Schema Draft 7 or older with a top-level \"\n          \"`$ref` (which overrides sibling keywords) without introducing \"\n          \"undefined behavior\");\n    }\n  }\n\n  bundle_schema(schema, {JSON::String{container_keyword}}, schema, walker,\n                resolver, default_dialect, default_id, paths, bundled);\n}\n\nauto bundle(const JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver, std::string_view default_dialect,\n            std::string_view default_id,\n            const std::optional<Pointer> &default_container,\n            const SchemaFrame::Paths &paths) -> JSON {\n  JSON copy = schema;\n  bundle(copy, walker, resolver, default_dialect, default_id, default_container,\n         paths);\n  return copy;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/format.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include <cstdint>       // std::uint64_t\n#include <limits>        // std::numeric_limits\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <vector>        // std::vector\n\nnamespace {\n\nauto keyword_rank(const sourcemeta::core::JSON::String &keyword,\n                  const std::uint64_t otherwise) -> std::uint64_t {\n  using Rank =\n      std::unordered_map<sourcemeta::core::JSON::String, std::uint64_t>;\n  static Rank rank{// Most core keywords tend to come first\n                   {\"$schema\", 0},\n                   {\"$id\", 1},\n                   {\"id\", 2},\n                   {\"$vocabulary\", 3},\n                   {\"$anchor\", 4},\n                   {\"$dynamicAnchor\", 5},\n                   {\"$recursiveAnchor\", 6},\n\n                   // Then important metadata about the schema\n                   {\"title\", 7},\n                   {\"description\", 8},\n                   {\"$comment\", 10},\n                   {\"examples\", 11},\n                   {\"deprecated\", 12},\n                   {\"readOnly\", 13},\n                   {\"writeOnly\", 14},\n                   {\"default\", 15},\n\n                   // This is a placeholder for \"x-\"-prefixed unknown keywords,\n                   // as they are almost always metadata\n                   {\"x-\", 16},\n\n                   // Then references\n                   {\"$ref\", 17},\n                   {\"$dynamicRef\", 18},\n                   {\"$recursiveRef\", 19},\n\n                   // Then keywords that apply to any type\n                   {\"type\", 20},\n                   {\"disallow\", 21},\n                   {\"extends\", 22},\n                   {\"const\", 23},\n                   {\"enum\", 24},\n                   {\"optional\", 25},\n                   {\"requires\", 26},\n                   {\"allOf\", 27},\n                   {\"anyOf\", 28},\n                   {\"oneOf\", 29},\n                   {\"not\", 30},\n                   {\"if\", 31},\n                   {\"then\", 32},\n                   {\"else\", 33},\n\n                   // Then keywords about numbers\n                   {\"exclusiveMaximum\", 34},\n                   {\"maximum\", 35},\n                   {\"maximumCanEqual\", 36},\n                   {\"exclusiveMinimum\", 37},\n                   {\"minimum\", 38},\n                   {\"minimumCanEqual\", 39},\n                   {\"multipleOf\", 40},\n                   {\"divisibleBy\", 41},\n                   {\"maxDecimal\", 42},\n\n                   // Then keywords about strings\n                   {\"pattern\", 43},\n                   {\"format\", 44},\n                   {\"maxLength\", 45},\n                   {\"minLength\", 46},\n                   {\"contentEncoding\", 47},\n                   {\"contentMediaType\", 48},\n                   {\"contentSchema\", 49},\n\n                   // Then keywords about arrays\n                   {\"maxItems\", 50},\n                   {\"minItems\", 51},\n                   {\"uniqueItems\", 52},\n                   {\"maxContains\", 53},\n                   {\"minContains\", 54},\n                   {\"contains\", 55},\n                   {\"prefixItems\", 56},\n                   {\"items\", 57},\n                   {\"additionalItems\", 58},\n                   {\"unevaluatedItems\", 59},\n\n                   // Object\n                   {\"required\", 60},\n                   {\"maxProperties\", 61},\n                   {\"minProperties\", 62},\n                   {\"propertyNames\", 63},\n                   {\"properties\", 64},\n                   {\"patternProperties\", 65},\n                   {\"additionalProperties\", 66},\n                   {\"unevaluatedProperties\", 67},\n                   {\"dependentRequired\", 68},\n                   {\"dependencies\", 69},\n                   {\"dependentSchemas\", 70},\n\n                   // Reusable utilities go last\n                   {\"$defs\", 71},\n                   {\"definitions\", 72}};\n\n  // Handle `x-` prefixed unknown keywords\n  if (keyword.starts_with(\"x-\")) {\n    const auto match{rank.find(\"x-\")};\n    assert(match != rank.cend());\n    return match->second;\n  }\n\n  const auto match{rank.find(keyword)};\n  if (match != rank.cend()) {\n    return match->second;\n  } else {\n    return otherwise;\n  }\n}\n\nauto keyword_compare(const sourcemeta::core::JSON::String &left,\n                     const sourcemeta::core::JSON::String &right) -> bool {\n  constexpr auto DEFAULT{std::numeric_limits<std::uint64_t>::max()};\n  const auto left_rank{keyword_rank(left, DEFAULT)};\n  const auto right_rank{keyword_rank(right, DEFAULT)};\n  if (left_rank == right_rank) {\n    return left < right;\n  } else {\n    return left_rank < right_rank;\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto format(JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver, std::string_view default_dialect)\n    -> void {\n  assert(is_schema(schema));\n  std::vector<Pointer> subschemas;\n\n  {\n    SchemaFrame frame{SchemaFrame::Mode::Locations};\n    frame.analyse(schema, walker, resolver, default_dialect);\n\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type != SchemaFrame::LocationType::Resource &&\n          entry.second.type != SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      subschemas.push_back(to_pointer(entry.second.pointer));\n    }\n  }\n\n  for (const auto &pointer : subschemas) {\n    auto &subschema{get(schema, pointer)};\n    if (subschema.is_object()) {\n      subschema.reorder(keyword_compare);\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/frame.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include \"helpers.h\"\n\n#include <algorithm> // std::ranges::all_of, std::ranges::contains, std::ranges::sort\n#include <cassert>       // assert\n#include <functional>    // std::less\n#include <map>           // std::map\n#include <optional>      // std::optional\n#include <sstream>       // std::ostringstream\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::pair, std::move\n#include <vector>        // std::vector\n\nenum class AnchorType : std::uint8_t { Static, Dynamic, All };\n\n// Static keyword strings for reference pointers\nstatic const std::string KEYWORD_SCHEMA{\"$schema\"};\nstatic const std::string KEYWORD_REF{\"$ref\"};\nstatic const std::string KEYWORD_RECURSIVE_REF{\"$recursiveRef\"};\nstatic const std::string KEYWORD_DYNAMIC_REF{\"$dynamicRef\"};\n\nnamespace {\n\nauto is_valid_anchor_2020_12(const std::string_view name) -> bool {\n  if (name.empty()) {\n    return false;\n  }\n\n  const auto first{name.front()};\n  if (!((first >= 'A' && first <= 'Z') || (first >= 'a' && first <= 'z') ||\n        first == '_')) {\n    return false;\n  }\n\n  for (std::size_t index{1}; index < name.size(); ++index) {\n    const auto character{name[index]};\n    if (!((character >= 'A' && character <= 'Z') ||\n          (character >= 'a' && character <= 'z') ||\n          (character >= '0' && character <= '9') || character == '-' ||\n          character == '_' || character == '.')) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nauto is_valid_anchor(const std::string_view name) -> bool {\n  if (name.empty()) {\n    return false;\n  }\n\n  const auto first{name.front()};\n  if (!((first >= 'A' && first <= 'Z') || (first >= 'a' && first <= 'z'))) {\n    return false;\n  }\n\n  for (std::size_t index{1}; index < name.size(); ++index) {\n    const auto character{name[index]};\n    if (!((character >= 'A' && character <= 'Z') ||\n          (character >= 'a' && character <= 'z') ||\n          (character >= '0' && character <= '9') || character == '-' ||\n          character == '_' || character == '.' || character == ':')) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nauto find_anchors(const sourcemeta::core::JSON &schema,\n                  const sourcemeta::core::Vocabularies &vocabularies)\n    -> std::vector<std::pair<std::string_view, AnchorType>> {\n  std::vector<std::pair<std::string_view, AnchorType>> result;\n\n  // 2020-12\n  if (schema.is_object() &&\n      vocabularies.contains(\n          sourcemeta::core::Vocabularies::Known::JSON_Schema_2020_12_Core)) {\n    const auto *dynamic_anchor{schema.try_at(\"$dynamicAnchor\")};\n    if (dynamic_anchor && dynamic_anchor->is_string()) {\n      const std::string_view dynamic_anchor_view{dynamic_anchor->to_string()};\n      if (!is_valid_anchor_2020_12(dynamic_anchor_view)) {\n        throw sourcemeta::core::SchemaKeywordError(\n            \"$dynamicAnchor\", dynamic_anchor_view,\n            \"Invalid dynamic anchor value\");\n      }\n\n      result.emplace_back(dynamic_anchor_view, AnchorType::Dynamic);\n    }\n\n    const auto *anchor_2020{schema.try_at(\"$anchor\")};\n    if (anchor_2020 && anchor_2020->is_string()) {\n      const std::string_view anchor_view{anchor_2020->to_string()};\n      if (!is_valid_anchor_2020_12(anchor_view)) {\n        throw sourcemeta::core::SchemaKeywordError(\"$anchor\", anchor_view,\n                                                   \"Invalid anchor value\");\n      }\n\n      bool found = false;\n      for (auto &entry : result) {\n        if (entry.first == anchor_view) {\n          entry.second = AnchorType::All;\n          found = true;\n          break;\n        }\n      }\n      if (!found) {\n        result.emplace_back(anchor_view, AnchorType::Static);\n      }\n    }\n  }\n\n  // 2019-09\n  if (schema.is_object() &&\n      vocabularies.contains(\n          sourcemeta::core::Vocabularies::Known::JSON_Schema_2019_09_Core)) {\n    const auto *recursive_anchor{schema.try_at(\"$recursiveAnchor\")};\n    if (recursive_anchor) {\n      if (recursive_anchor->is_boolean()) {\n        if (recursive_anchor->to_boolean()) {\n          // We store a 2019-09 recursive anchor as an empty anchor\n          result.emplace_back(std::string_view{}, AnchorType::Dynamic);\n        }\n      } else {\n        std::ostringstream value;\n        sourcemeta::core::stringify(*recursive_anchor, value);\n        throw sourcemeta::core::SchemaKeywordError(\n            \"$recursiveAnchor\", value.str(), \"Invalid recursive anchor value\");\n      }\n    }\n\n    const auto *anchor_2019{schema.try_at(\"$anchor\")};\n    if (anchor_2019 && anchor_2019->is_string()) {\n      const std::string_view anchor_view{anchor_2019->to_string()};\n      if (!is_valid_anchor(anchor_view)) {\n        throw sourcemeta::core::SchemaKeywordError(\"$anchor\", anchor_view,\n                                                   \"Invalid anchor value\");\n      }\n\n      bool found = false;\n      for (auto &entry : result) {\n        if (entry.first == anchor_view) {\n          entry.second = AnchorType::All;\n          found = true;\n          break;\n        }\n      }\n      if (!found) {\n        result.emplace_back(anchor_view, AnchorType::Static);\n      }\n    }\n  }\n\n  // Draft 7 and 6\n  // Old `$id` anchor form\n  if (schema.is_object() &&\n      (vocabularies.contains(\n           sourcemeta::core::Vocabularies::Known::JSON_Schema_Draft_7) ||\n       vocabularies.contains(\n           sourcemeta::core::Vocabularies::Known::JSON_Schema_Draft_6))) {\n    const auto *id_value{schema.try_at(\"$id\")};\n    if (id_value) {\n      assert(id_value->is_string());\n      const std::string_view id_view{id_value->to_string()};\n      // A bare \"#\" carries no anchor name, so we treat it as no anchor at\n      // all.\n      if (id_view.starts_with('#') && id_view.size() > 1) {\n        const std::string_view anchor_view{id_view.substr(1)};\n        // Per Draft 7 / 6 spec, the plain-name fragment in `$id` must\n        // begin with a letter `[A-Za-z]` followed by any number of\n        // letters, digits, hyphens, underscores, colons, or periods.\n        if (!is_valid_anchor(anchor_view)) {\n          throw sourcemeta::core::SchemaKeywordError(\"$id\", id_view,\n                                                     \"Invalid anchor value\");\n        }\n\n        result.emplace_back(anchor_view, AnchorType::Static);\n      }\n    }\n  }\n\n  // Draft 4\n  // Old `id` anchor form\n  if (schema.is_object() &&\n      vocabularies.contains(\n          sourcemeta::core::Vocabularies::Known::JSON_Schema_Draft_4)) {\n    const auto *id_value{schema.try_at(\"id\")};\n    if (id_value) {\n      assert(id_value->is_string());\n      const std::string_view id_view{id_value->to_string()};\n      // A bare \"#\" carries no anchor name, so we treat it as no anchor at\n      // all.\n      if (id_view.starts_with('#') && id_view.size() > 1) {\n        // Draft 4 imposes no plain-name pattern on the fragment, but the\n        // value must still be a valid URI reference per RFC 3986\n        if (!sourcemeta::core::URI::is_uri_reference(id_view)) {\n          throw sourcemeta::core::SchemaKeywordError(\n              \"id\", id_view, \"The identifier is not a valid URI\");\n        }\n\n        result.emplace_back(id_view.substr(1), AnchorType::Static);\n      }\n    }\n  }\n\n  return result;\n}\n\ntemplate <typename StringType, typename MapType>\nauto find_nearest_bases_ref(const MapType &bases,\n                            const sourcemeta::core::WeakPointer &pointer)\n    -> std::optional<\n        std::pair<std::reference_wrapper<const std::vector<StringType>>,\n                  sourcemeta::core::WeakPointer>> {\n  auto current_pointer{pointer};\n  while (true) {\n    const auto match{bases.find(current_pointer)};\n    if (match != bases.cend()) {\n      return std::make_pair(std::cref(match->second), current_pointer);\n    }\n\n    if (current_pointer.empty()) {\n      break;\n    }\n\n    current_pointer = current_pointer.initial();\n  }\n\n  return std::nullopt;\n}\n\ntemplate <typename StringType, typename MapType>\nauto find_nearest_bases(const MapType &bases,\n                        const sourcemeta::core::WeakPointer &pointer,\n                        const std::optional<std::string_view> &default_base)\n    -> std::pair<std::vector<StringType>, sourcemeta::core::WeakPointer> {\n  const auto result{find_nearest_bases_ref<StringType>(bases, pointer)};\n  if (result.has_value()) {\n    return {result->first.get(), result->second};\n  }\n\n  if (default_base.has_value()) {\n    return {{StringType{default_base.value()}},\n            sourcemeta::core::empty_weak_pointer};\n  }\n\n  return {{}, sourcemeta::core::empty_weak_pointer};\n}\n\nstruct DialectAtPointer {\n  std::vector<std::string_view> dialects;\n  sourcemeta::core::SchemaBaseDialect base_dialect;\n};\n\nstruct CombinedWalkResult {\n  std::optional<std::pair<std::reference_wrapper<const DialectAtPointer>,\n                          sourcemeta::core::WeakPointer>>\n      dialect_match;\n  std::vector<std::pair<std::string_view, sourcemeta::core::WeakPointer>>\n      every_base;\n};\n\ntemplate <typename DialectMapType, typename BaseMapType>\nauto find_dialect_and_all_bases(const DialectMapType &base_dialects,\n                                const BaseMapType &base_uris,\n                                const sourcemeta::core::WeakPointer &pointer)\n    -> CombinedWalkResult {\n  CombinedWalkResult result;\n\n  auto current_pointer{pointer};\n  while (true) {\n    if (!result.dialect_match.has_value()) {\n      const auto dialect_it{base_dialects.find(current_pointer)};\n      if (dialect_it != base_dialects.cend()) {\n        result.dialect_match =\n            std::make_pair(std::cref(dialect_it->second), current_pointer);\n      }\n    }\n\n    const auto base_it{base_uris.find(current_pointer)};\n    if (base_it != base_uris.cend()) {\n      for (const auto &base : base_it->second) {\n        result.every_base.emplace_back(std::string_view{base}, current_pointer);\n      }\n    }\n\n    if (current_pointer.empty()) {\n      break;\n    }\n\n    current_pointer = current_pointer.initial();\n  }\n\n  if (result.every_base.empty() ||\n      result.every_base.back().second != sourcemeta::core::empty_weak_pointer) {\n    result.every_base.emplace_back(std::string_view{},\n                                   sourcemeta::core::empty_weak_pointer);\n  }\n\n  return result;\n}\n\nauto supports_id_anchors(const sourcemeta::core::SchemaBaseDialect base_dialect)\n    -> bool {\n  using sourcemeta::core::SchemaBaseDialect;\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n      return true;\n    default:\n      return false;\n  }\n}\n\nauto set_base_and_fragment(\n    sourcemeta::core::SchemaFrame::ReferencesEntry &entry) -> void {\n  const std::string_view destination_view{entry.destination};\n  if (destination_view.empty()) {\n    entry.base = std::string_view{};\n    entry.fragment = std::nullopt;\n    return;\n  }\n\n  const auto hash_position{destination_view.find('#')};\n  if (hash_position != std::string::npos) {\n    // Has a fragment\n    if (hash_position == 0) {\n      // Starts with #, so no base\n      entry.base = std::string_view{};\n    } else {\n      entry.base = destination_view.substr(0, hash_position);\n    }\n    entry.fragment = destination_view.substr(hash_position + 1);\n  } else {\n    // No fragment\n    entry.base = destination_view;\n    entry.fragment = std::nullopt;\n  }\n}\n\n[[noreturn]]\nauto throw_already_exists(const sourcemeta::core::JSON::String &uri) -> void {\n  throw sourcemeta::core::SchemaFrameError(uri,\n                                           \"Schema identifier already exists\");\n}\n\nauto store(sourcemeta::core::SchemaFrame::Locations &frame,\n           const sourcemeta::core::SchemaReferenceType type,\n           const sourcemeta::core::SchemaFrame::LocationType entry_type,\n           sourcemeta::core::JSON::String uri, const std::string_view base,\n           const sourcemeta::core::WeakPointer &pointer_from_root,\n           const std::size_t relative_pointer_offset,\n           const std::string_view dialect,\n           const sourcemeta::core::SchemaBaseDialect base_dialect,\n           const std::optional<sourcemeta::core::WeakPointer> &parent,\n           const bool property_name, const bool orphan,\n           const bool ignore_if_present = false,\n           const bool already_canonical = false) -> void {\n  auto canonical{already_canonical ? std::move(uri)\n                                   : sourcemeta::core::URI::canonicalize(uri)};\n  auto [iterator, inserted] =\n      frame.insert({{type, std::move(canonical)},\n                    {.parent = parent,\n                     .type = entry_type,\n                     .base = base,\n                     .pointer = pointer_from_root,\n                     .relative_pointer = relative_pointer_offset,\n                     .dialect = dialect,\n                     .base_dialect = base_dialect,\n                     .property_name = property_name,\n                     .orphan = orphan}});\n  if (!ignore_if_present && !inserted) {\n    if (entry_type == sourcemeta::core::SchemaFrame::LocationType::Anchor) {\n      throw sourcemeta::core::SchemaAnchorCollisionError(\n          iterator->first.second,\n          sourcemeta::core::to_pointer(pointer_from_root),\n          sourcemeta::core::to_pointer(iterator->second.pointer));\n    }\n    throw_already_exists(iterator->first.second);\n  }\n\n  if (inserted && iterator->first.second == base) {\n    iterator->second.base = iterator->first.second;\n  }\n}\n\n// Check misunderstood struct to be a function\n// NOLINTNEXTLINE(bugprone-exception-escape)\nstruct InternalEntry {\n  sourcemeta::core::SchemaIteratorEntry common;\n  std::optional<sourcemeta::core::JSON::String> id;\n};\n\n// Check misunderstood struct to be a function\n// NOLINTNEXTLINE(bugprone-exception-escape)\nstruct CacheSubschema {\n  bool orphan{};\n  bool property_name{};\n  std::optional<sourcemeta::core::WeakPointer> parent{};\n};\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto to_json(const SchemaReferenceType value) -> JSON {\n  return JSON{value == SchemaReferenceType::Static ? \"static\" : \"dynamic\"};\n}\n\nauto to_json(const SchemaFrame::LocationType value) -> JSON {\n  switch (value) {\n    case SchemaFrame::LocationType::Resource:\n      return JSON{\"resource\"};\n    case SchemaFrame::LocationType::Anchor:\n      return JSON{\"anchor\"};\n    case SchemaFrame::LocationType::Pointer:\n      return JSON{\"pointer\"};\n    case SchemaFrame::LocationType::Subschema:\n      return JSON{\"subschema\"};\n    default:\n      assert(false);\n      return JSON{nullptr};\n  }\n}\n\nauto SchemaFrame::to_json(\n    const std::optional<PointerPositionTracker> &tracker) const -> JSON {\n  auto root{JSON::make_object()};\n\n  root.assign_assume_new(\"locations\", JSON::make_object());\n  root.at(\"locations\").assign_assume_new(\"static\", JSON::make_object());\n  root.at(\"locations\").assign_assume_new(\"dynamic\", JSON::make_object());\n  for (const auto &location : this->locations_) {\n    auto entry{JSON::make_object()};\n    entry.assign_assume_new(\"parent\", location.second.parent.has_value()\n                                          ? JSON{sourcemeta::core::to_string(\n                                                location.second.parent.value())}\n                                          : JSON{nullptr});\n    entry.assign_assume_new(\"type\",\n                            sourcemeta::core::to_json(location.second.type));\n    entry.assign_assume_new(\"root\", this->root_.empty() ? JSON{nullptr}\n                                                        : JSON{this->root_});\n    entry.assign_assume_new(\"base\", JSON{JSON::String{location.second.base}});\n    entry.assign_assume_new(\n        \"pointer\", JSON{sourcemeta::core::to_string(location.second.pointer)});\n    if (tracker.has_value()) {\n      entry.assign_assume_new(\"position\",\n                              sourcemeta::core::to_json(tracker.value().get(\n                                  to_pointer(location.second.pointer))));\n    } else {\n      entry.assign_assume_new(\"position\", sourcemeta::core::to_json(nullptr));\n    }\n\n    entry.assign_assume_new(\n        \"relativePointer\",\n        JSON{sourcemeta::core::to_string(\n            this->relative_instance_location(location.second))});\n    entry.assign_assume_new(\"dialect\",\n                            JSON{JSON::String{location.second.dialect}});\n    entry.assign_assume_new(\n        \"baseDialect\",\n        JSON{JSON::String{to_string(location.second.base_dialect)}});\n    entry.assign_assume_new(\"propertyName\",\n                            JSON{location.second.property_name});\n    entry.assign_assume_new(\"orphan\", JSON{location.second.orphan});\n\n    switch (location.first.first) {\n      case SchemaReferenceType::Static:\n        root.at(\"locations\")\n            .at(\"static\")\n            .assign_assume_new(location.first.second, std::move(entry));\n        break;\n      case SchemaReferenceType::Dynamic:\n        root.at(\"locations\")\n            .at(\"dynamic\")\n            .assign_assume_new(location.first.second, std::move(entry));\n        break;\n      default:\n        assert(false);\n    }\n  }\n\n  root.assign_assume_new(\"references\", JSON::make_array());\n  for (const auto &reference : this->references_) {\n    auto entry{JSON::make_object()};\n    entry.assign_assume_new(\"type\",\n                            sourcemeta::core::to_json(reference.first.first));\n    entry.assign_assume_new(\n        \"origin\", JSON{sourcemeta::core::to_string(reference.first.second)});\n\n    if (tracker.has_value()) {\n      entry.assign_assume_new(\"position\",\n                              sourcemeta::core::to_json(tracker.value().get(\n                                  to_pointer(reference.first.second))));\n    } else {\n      entry.assign_assume_new(\"position\", sourcemeta::core::to_json(nullptr));\n    }\n\n    entry.assign_assume_new(\n        \"destination\", sourcemeta::core::to_json(reference.second.destination));\n    entry.assign_assume_new(\n        \"base\",\n        !reference.second.base.empty()\n            ? sourcemeta::core::to_json(JSON::String{reference.second.base})\n            : sourcemeta::core::to_json(nullptr));\n    entry.assign_assume_new(\n        \"fragment\", reference.second.fragment.has_value()\n                        ? sourcemeta::core::to_json(\n                              JSON::String{reference.second.fragment.value()})\n                        : sourcemeta::core::to_json(nullptr));\n    root.at(\"references\").push_back(std::move(entry));\n  }\n\n  return root;\n}\n\nauto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,\n                          const SchemaResolver &resolver,\n                          std::string_view default_dialect,\n                          std::string_view default_id,\n                          const SchemaFrame::Paths &paths) -> void {\n  this->reset();\n  assert((std::unordered_set<WeakPointer, WeakPointer::Hasher>(paths.cbegin(),\n                                                               paths.cend())\n              .size() == paths.size()));\n  std::vector<InternalEntry> subschema_entries;\n  std::unordered_map<WeakPointer, CacheSubschema, WeakPointer::Hasher>\n      subschemas;\n  std::unordered_map<WeakPointer, std::vector<JSON::String>,\n                     WeakPointer::Hasher>\n      base_uris;\n  std::unordered_map<WeakPointer, DialectAtPointer, WeakPointer::Hasher>\n      base_dialects;\n\n  for (const auto &path : paths) {\n    // Passing paths that overlap is undefined behavior. No path should\n    // start with another one, else you are doing something wrong\n    assert(std::ranges::all_of(paths, [&path](const auto &other) {\n      return path == other || !path.starts_with(other);\n    }));\n\n    const auto &schema{get(root, path)};\n\n    const auto root_base_dialect{\n        sourcemeta::core::base_dialect(schema, resolver, default_dialect)};\n    if (!root_base_dialect.has_value()) {\n      throw SchemaUnknownBaseDialectError();\n    }\n\n    // If we are dealing with nested schemas, then by definition\n    // the root has no identifier\n    std::optional<JSON::String> root_id{std::nullopt};\n    if (path.empty()) {\n      const auto maybe_id{sourcemeta::core::identify(\n          schema, root_base_dialect.value(), default_id)};\n      if (!maybe_id.empty()) {\n        try {\n          root_id = URI::canonicalize(maybe_id);\n        } catch (const URIParseError &) {\n          throw SchemaKeywordError(\n              sourcemeta::core::id_keyword(root_base_dialect.value()), maybe_id,\n              \"The identifier is not a valid URI\");\n        }\n\n        this->root_ = root_id.value();\n      }\n    }\n\n    const std::string_view root_dialect{\n        sourcemeta::core::dialect(schema, default_dialect)};\n    assert(!root_dialect.empty());\n\n    // If the top-level schema has a specific identifier but the user\n    // passes a different default identifier, then the schema is by\n    // definition known by two names, and we should handle that accordingly\n    const bool has_explicit_different_id{root_id.has_value() &&\n                                         !default_id.empty() &&\n                                         root_id.value() != default_id};\n    if (has_explicit_different_id) {\n      const auto default_id_canonical{URI::canonicalize(default_id)};\n      // Use this->root_ as base - it contains root_id.value() and persists\n      store(this->locations_, SchemaReferenceType::Static,\n            SchemaFrame::LocationType::Resource, default_id_canonical,\n            this->root_, path, path.size(), root_dialect,\n            root_base_dialect.value(), std::nullopt, false, false);\n\n      base_uris.insert({path, {root_id.value(), default_id_canonical}});\n    }\n\n    std::vector<std::size_t> current_subschema_entries;\n    for (const auto &relative_entry : sourcemeta::core::SchemaIterator{\n             schema, walker, resolver, default_dialect}) {\n      // Rephrase the iterator entry as being for the current base\n      auto entry{relative_entry};\n      entry.pointer = path.concat(relative_entry.pointer);\n      if (entry.parent.has_value()) {\n        entry.parent = path.concat(relative_entry.parent.value());\n      }\n\n      // Dialect\n      assert(!entry.dialect.empty());\n      assert(entry.base_dialect.has_value());\n      base_dialects.insert(\n          {entry.pointer,\n           DialectAtPointer{.dialects = {entry.dialect},\n                            .base_dialect = entry.base_dialect.value()}});\n\n      // Schema identifier\n      // We need to store the default_id in a local variable to ensure\n      // it survives the identify() call, as identify() returns a string_view\n      const std::string default_id_for_entry{\n          entry.pointer.empty() && root_id.has_value() ? root_id.value()\n                                                       : std::string{}};\n      const auto maybe_id{sourcemeta::core::identify(entry.subschema.get(),\n                                                     entry.base_dialect.value(),\n                                                     default_id_for_entry)};\n      std::optional<JSON::String> id{\n          !maybe_id.empty() ? std::make_optional<JSON::String>(maybe_id)\n                            : std::nullopt};\n\n      // Store information\n      subschemas.emplace(entry.pointer,\n                         CacheSubschema{.orphan = entry.orphan,\n                                        .property_name = entry.property_name,\n                                        .parent = entry.parent});\n      subschema_entries.emplace_back(\n          InternalEntry{.common = std::move(entry), .id = std::move(id)});\n      current_subschema_entries.emplace_back(subschema_entries.size() - 1);\n    }\n\n    for (const auto &entry_index : current_subschema_entries) {\n      const auto &entry{subschema_entries[entry_index]};\n      const auto &common_pointer_weak{entry.common.pointer};\n      const auto &common_parent{entry.common.parent};\n      if (entry.id.has_value()) {\n        assert(entry.common.base_dialect.has_value());\n        const bool ref_overrides =\n            sourcemeta::core::ref_overrides_adjacent_keywords(\n                entry.common.base_dialect.value());\n        const bool is_pre_2019_09_location_independent_identifier =\n            supports_id_anchors(entry.common.base_dialect.value()) &&\n            entry.id.value().starts_with('#');\n\n        if ((!entry.common.subschema.get().defines(\"$ref\") || !ref_overrides) &&\n            // If we are dealing with a pre-2019-09 location independent\n            // identifier, we ignore it as a traditional identifier and take\n            // care of it as an anchor\n            !is_pre_2019_09_location_independent_identifier) {\n          const auto bases{find_nearest_bases<JSON::String>(\n              base_uris, common_pointer_weak,\n              entry.id ? std::optional<std::string_view>{*entry.id}\n                       : std::nullopt)};\n          for (const auto &base_string : bases.first) {\n            // Otherwise we end up pushing the top-level resource twice\n            if (entry_index == 0 && has_explicit_different_id &&\n                !default_id.empty() && default_id == base_string) {\n              continue;\n            }\n\n            sourcemeta::core::URI base;\n            sourcemeta::core::URI maybe_relative;\n            try {\n              base = sourcemeta::core::URI{base_string};\n              maybe_relative = sourcemeta::core::URI{entry.id.value()};\n            } catch (const sourcemeta::core::URIParseError &) {\n              throw sourcemeta::core::SchemaKeywordError(\n                  sourcemeta::core::id_keyword(\n                      entry.common.base_dialect.value()),\n                  entry.id.value(), \"The identifier is not a valid URI\");\n            }\n\n            const auto maybe_fragment{maybe_relative.fragment()};\n\n            // Both 2019-09 and 2020-12 state:\n            //\n            //   \"$id\" MUST NOT contain a non-empty fragment, and SHOULD NOT\n            //   contain an empty fragment.\n            //\n            // See\n            // https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.2\n            // See\n            // https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-8.2.1-5\n            if (maybe_fragment.has_value() && !maybe_fragment.value().empty()) {\n              throw SchemaFrameError(\n                  entry.id.value(),\n                  \"Identifiers must not contain non-empty fragments\");\n            }\n\n            const bool maybe_relative_is_absolute{maybe_relative.is_absolute()};\n            maybe_relative.resolve_from(base).canonicalize();\n            const JSON::String new_id{maybe_relative.recompose()};\n\n            const auto maybe_match{\n                this->locations_.find({SchemaReferenceType::Static, new_id})};\n            if (maybe_match != this->locations_.cend() &&\n                maybe_match->second.pointer != common_pointer_weak) {\n              throw_already_exists(new_id);\n            }\n\n            if (!maybe_relative_is_absolute ||\n                maybe_match == this->locations_.cend()) {\n              assert(entry.common.base_dialect.has_value());\n\n              store(this->locations_, SchemaReferenceType::Static,\n                    SchemaFrame::LocationType::Resource, new_id, new_id,\n                    common_pointer_weak, common_pointer_weak.size(),\n                    entry.common.dialect, entry.common.base_dialect.value(),\n                    common_parent, entry.common.property_name,\n                    entry.common.orphan);\n            }\n\n            auto base_uri_match{base_uris.find(common_pointer_weak)};\n            if (base_uri_match != base_uris.cend()) {\n              if (!std::ranges::contains(base_uri_match->second, new_id)) {\n                base_uri_match->second.push_back(new_id);\n              }\n            } else {\n              base_uris.insert({common_pointer_weak, {new_id}});\n            }\n          }\n        }\n      }\n\n      if (this->mode_ != SchemaFrame::Mode::Locations) {\n        // Handle metaschema references\n        const auto maybe_metaschema{\n            sourcemeta::core::dialect(entry.common.subschema.get(), {}, false)};\n        if (!maybe_metaschema.empty()) {\n          sourcemeta::core::URI metaschema;\n          try {\n            metaschema = sourcemeta::core::URI{maybe_metaschema};\n          } catch (const URIParseError &) {\n            throw SchemaKeywordError(\"$schema\", maybe_metaschema,\n                                     \"The dialect is not a valid URI\");\n          }\n\n          const auto nearest_bases{find_nearest_bases<JSON::String>(\n              base_uris, common_pointer_weak,\n              entry.id ? std::optional<std::string_view>{*entry.id}\n                       : std::nullopt)};\n          if (!nearest_bases.first.empty()) {\n            metaschema.resolve_from(nearest_bases.first.front());\n          }\n\n          metaschema.canonicalize();\n          assert(entry.common.subschema.get().defines(\"$schema\"));\n          auto schema_pointer{common_pointer_weak};\n          schema_pointer.push_back(std::cref(KEYWORD_SCHEMA));\n          const auto [it, inserted] = this->references_.insert_or_assign(\n              {SchemaReferenceType::Static, std::move(schema_pointer)},\n              SchemaFrame::ReferencesEntry{.original = maybe_metaschema,\n                                           .destination =\n                                               metaschema.recompose(),\n                                           .base = std::string_view{},\n                                           .fragment = std::nullopt});\n          set_base_and_fragment(it->second);\n        }\n      }\n\n      // Handle schema anchors\n      for (const auto &[name, type] : find_anchors(entry.common.subschema.get(),\n                                                   entry.common.vocabularies)) {\n        const auto bases{find_nearest_bases<JSON::String>(\n            base_uris, common_pointer_weak,\n            entry.id ? std::optional<std::string_view>{*entry.id}\n                     : std::nullopt)};\n\n        if (bases.first.empty()) {\n          const auto anchor_uri{sourcemeta::core::URI::from_fragment(name)};\n          const auto relative_anchor_uri{anchor_uri.recompose()};\n\n          if (type == AnchorType::Static || type == AnchorType::All) {\n            store(this->locations_, SchemaReferenceType::Static,\n                  SchemaFrame::LocationType::Anchor, relative_anchor_uri, \"\",\n                  common_pointer_weak, bases.second.size(),\n                  entry.common.dialect, entry.common.base_dialect.value(),\n                  common_parent, entry.common.property_name,\n                  entry.common.orphan);\n          }\n\n          if (type == AnchorType::Dynamic || type == AnchorType::All) {\n            store(this->locations_, SchemaReferenceType::Dynamic,\n                  SchemaFrame::LocationType::Anchor, relative_anchor_uri, \"\",\n                  common_pointer_weak, bases.second.size(),\n                  entry.common.dialect, entry.common.base_dialect.value(),\n                  common_parent, entry.common.property_name,\n                  entry.common.orphan);\n\n            // Register a dynamic anchor as a static anchor if possible too\n            if (entry.common.vocabularies.contains(\n                    Vocabularies::Known::JSON_Schema_2020_12_Core)) {\n              store(this->locations_, SchemaReferenceType::Static,\n                    SchemaFrame::LocationType::Anchor, relative_anchor_uri, \"\",\n                    common_pointer_weak, bases.second.size(),\n                    entry.common.dialect, entry.common.base_dialect.value(),\n                    common_parent, entry.common.property_name,\n                    entry.common.orphan, true);\n            }\n          }\n        } else {\n          bool is_first = true;\n          for (const auto &base_string : bases.first) {\n            sourcemeta::core::URI anchor_uri_builder{base_string};\n            anchor_uri_builder.fragment(name);\n            anchor_uri_builder.canonicalize();\n            const auto anchor_uri{anchor_uri_builder.recompose()};\n\n            if (!is_first && this->locations_.contains(\n                                 {SchemaReferenceType::Static, anchor_uri})) {\n              continue;\n            }\n\n            const auto base_entry{this->locations_.find(\n                {SchemaReferenceType::Static, base_string})};\n\n            const std::string_view base_view{\n                base_entry != this->locations_.cend()\n                    ? std::string_view{base_entry->first.second}\n                    : std::string_view{base_string}};\n\n            if (type == AnchorType::Static || type == AnchorType::All) {\n              store(this->locations_,\n                    sourcemeta::core::SchemaReferenceType::Static,\n                    SchemaFrame::LocationType::Anchor, anchor_uri, base_view,\n                    common_pointer_weak, bases.second.size(),\n                    entry.common.dialect, entry.common.base_dialect.value(),\n                    common_parent, entry.common.property_name,\n                    entry.common.orphan);\n            }\n\n            if (type == AnchorType::Dynamic || type == AnchorType::All) {\n              store(this->locations_,\n                    sourcemeta::core::SchemaReferenceType::Dynamic,\n                    SchemaFrame::LocationType::Anchor, anchor_uri, base_view,\n                    common_pointer_weak, bases.second.size(),\n                    entry.common.dialect, entry.common.base_dialect.value(),\n                    common_parent, entry.common.property_name,\n                    entry.common.orphan);\n\n              if (entry.common.vocabularies.contains(\n                      Vocabularies::Known::JSON_Schema_2020_12_Core)) {\n                store(this->locations_,\n                      sourcemeta::core::SchemaReferenceType::Static,\n                      SchemaFrame::LocationType::Anchor, anchor_uri, base_view,\n                      common_pointer_weak, bases.second.size(),\n                      entry.common.dialect, entry.common.base_dialect.value(),\n                      common_parent, entry.common.property_name,\n                      entry.common.orphan, true);\n              }\n            }\n\n            is_first = false;\n          }\n        }\n      }\n    }\n\n    // It is important for the loop that follows to assume a specific ordering\n    // where smaller pointers (by number of tokens) are scanned first.\n    std::vector<sourcemeta::core::WeakPointer> pointers;\n    for (const auto &weak_pointer : sourcemeta::core::PointerWalker{schema}) {\n      pointers.push_back(weak_pointer);\n    }\n\n    std::ranges::sort(pointers, std::less<>());\n\n    // Pre-compute every possible pointer to the schema\n    for (const auto &relative_pointer : pointers) {\n      const auto pointer_weak{path.concat(relative_pointer)};\n\n      const auto combined{\n          find_dialect_and_all_bases(base_dialects, base_uris, pointer_weak)};\n      const auto &dialect_for_pointer{\n          combined.dialect_match.has_value()\n              ? combined.dialect_match->first.get().dialects.front()\n              : root_dialect};\n      const auto base_dialect_for_pointer{\n          combined.dialect_match.has_value()\n              ? combined.dialect_match->first.get().base_dialect\n              : root_base_dialect.value()};\n      const auto &every_base_result{combined.every_base};\n\n      std::optional<std::pair<std::string_view, WeakPointer>> nearest_base_info;\n      for (const auto &entry : every_base_result) {\n        if (!entry.first.empty()) {\n          nearest_base_info = entry;\n          break;\n        }\n      }\n\n      const auto subschema_it{subschemas.find(pointer_weak)};\n      const bool is_subschema{subschema_it != subschemas.cend()};\n      const auto nearest_base_depth =\n          nearest_base_info.has_value() ? nearest_base_info->second.size() : 0;\n\n      std::string_view hoisted_base_view{};\n      if (nearest_base_info.has_value()) {\n        const JSON::String nearest_base_str{nearest_base_info->first};\n        const auto base_entry{this->locations_.find(\n            {SchemaReferenceType::Static, nearest_base_str})};\n        if (base_entry != this->locations_.cend()) {\n          hoisted_base_view = base_entry->first.second;\n        } else {\n          hoisted_base_view = nearest_base_info->first;\n        }\n      }\n\n      WeakPointer cached_base{};\n      for (const auto &base : every_base_result) {\n        const auto resolved{cached_base == base.second\n                                ? pointer_weak.resolve_from(cached_base)\n                                : pointer_weak.resolve_from(base.second)};\n        cached_base = base.second;\n\n        auto relative_pointer_uri{\n            base.first.empty()\n                ? sourcemeta::core::to_uri(resolved)\n                : sourcemeta::core::to_uri(resolved, base.first)};\n\n        relative_pointer_uri.canonicalize();\n        auto result{relative_pointer_uri.recompose()};\n\n        bool contains =\n            this->locations_.contains({SchemaReferenceType::Static, result});\n\n        if (!contains) {\n          std::string_view base_view;\n\n          if (nearest_base_info.has_value()) {\n            base_view = hoisted_base_view;\n          } else {\n            const JSON::String current_base{base.first};\n            const auto base_entry{this->locations_.find(\n                {SchemaReferenceType::Static, current_base})};\n            if (base_entry != this->locations_.cend()) {\n              base_view = base_entry->first.second;\n            } else {\n              base_view = base.first;\n            }\n          }\n\n          if (is_subschema) {\n            store(this->locations_, SchemaReferenceType::Static,\n                  SchemaFrame::LocationType::Subschema, std::move(result),\n                  base_view, pointer_weak, nearest_base_depth,\n                  dialect_for_pointer, base_dialect_for_pointer,\n                  subschema_it->second.parent,\n                  subschema_it->second.property_name,\n                  subschema_it->second.orphan, false, true);\n          } else {\n            const auto &parent_pointer{combined.dialect_match.has_value()\n                                           ? combined.dialect_match->second\n                                           : empty_weak_pointer};\n            const auto parent_subschema_it{subschemas.find(parent_pointer)};\n            const bool parent_property_name{\n                parent_subschema_it != subschemas.cend() &&\n                parent_subschema_it->second.property_name};\n            const bool parent_orphan{parent_subschema_it != subschemas.cend() &&\n                                     parent_subschema_it->second.orphan};\n\n            store(this->locations_, SchemaReferenceType::Static,\n                  SchemaFrame::LocationType::Pointer, std::move(result),\n                  base_view, pointer_weak, nearest_base_depth,\n                  dialect_for_pointer, base_dialect_for_pointer, parent_pointer,\n                  parent_property_name, parent_orphan, false, true);\n          }\n        }\n      }\n    }\n  }\n\n  if (this->mode_ == SchemaFrame::Mode::Locations) {\n    return;\n  }\n\n  // Resolve references after all framing was performed\n  for (const auto &entry : subschema_entries) {\n    const auto &common_pointer_weak{entry.common.pointer};\n    if (entry.common.subschema.get().is_object()) {\n      const auto nearest_bases{find_nearest_bases<JSON::String>(\n          base_uris, common_pointer_weak,\n          entry.id ? std::optional<std::string_view>{*entry.id}\n                   : std::nullopt)};\n      const auto *ref_value{entry.common.subschema.get().try_at(\"$ref\")};\n      if (ref_value) {\n        if (!ref_value->is_string()) {\n          std::ostringstream value;\n          sourcemeta::core::stringify(*ref_value, value);\n          throw sourcemeta::core::SchemaKeywordError(\"$ref\", value.str(),\n                                                     \"Invalid reference value\");\n        }\n\n        const auto &original{ref_value->to_string()};\n        sourcemeta::core::URI ref;\n        try {\n          ref = sourcemeta::core::URI{original};\n        } catch (const URIParseError &) {\n          throw sourcemeta::core::SchemaKeywordError(\n              \"$ref\", original, \"The reference is not a valid URI\");\n        }\n\n        if (!nearest_bases.first.empty()) {\n          ref.resolve_from(nearest_bases.first.front());\n        }\n\n        ref.canonicalize();\n        auto ref_pointer{common_pointer_weak};\n        ref_pointer.push_back(std::cref(KEYWORD_REF));\n        const auto [it, inserted] = this->references_.insert_or_assign(\n            {SchemaReferenceType::Static, std::move(ref_pointer)},\n            SchemaFrame::ReferencesEntry{.original = original,\n                                         .destination = ref.recompose(),\n                                         .base = std::string_view{},\n                                         .fragment = std::nullopt});\n        set_base_and_fragment(it->second);\n      }\n\n      const auto *recursive_ref_value{\n          entry.common.vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2019_09_Core)\n              ? entry.common.subschema.get().try_at(\"$recursiveRef\")\n              : nullptr};\n      if (recursive_ref_value) {\n        if (!recursive_ref_value->is_string()) {\n          std::ostringstream value;\n          sourcemeta::core::stringify(*recursive_ref_value, value);\n          throw sourcemeta::core::SchemaKeywordError(\n              \"$recursiveRef\", value.str(),\n              \"Invalid recursive reference value\");\n        }\n\n        const auto &ref{recursive_ref_value->to_string()};\n\n        // The behavior of this keyword is defined only for the value \"#\".\n        // Implementations MAY choose to consider other values to be errors.\n        // See\n        // https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.4.2.1\n        if (ref != \"#\") {\n          throw sourcemeta::core::SchemaReferenceError(\n              entry.id.value_or(\"\"),\n              to_pointer(common_pointer_weak).concat({\"$recursiveRef\"}),\n              \"Invalid recursive reference\");\n        }\n\n        auto anchor_uri_string{\n            nearest_bases.first.empty() ? \"\" : nearest_bases.first.front()};\n        const auto recursive_anchor{this->locations_.find(\n            {SchemaReferenceType::Dynamic, anchor_uri_string})};\n        const auto reference_type{recursive_anchor == this->locations_.end()\n                                      ? SchemaReferenceType::Static\n                                      : SchemaReferenceType::Dynamic};\n        const sourcemeta::core::URI anchor_uri{anchor_uri_string};\n        auto recursive_ref_pointer{common_pointer_weak};\n        recursive_ref_pointer.push_back(std::cref(KEYWORD_RECURSIVE_REF));\n        const auto [it, inserted] = this->references_.insert_or_assign(\n            {reference_type, std::move(recursive_ref_pointer)},\n            SchemaFrame::ReferencesEntry{.original = ref,\n                                         .destination = anchor_uri.recompose(),\n                                         .base = std::string_view{},\n                                         .fragment = std::nullopt});\n        set_base_and_fragment(it->second);\n      }\n\n      const auto *dynamic_ref_value{\n          entry.common.vocabularies.contains(\n              Vocabularies::Known::JSON_Schema_2020_12_Core)\n              ? entry.common.subschema.get().try_at(\"$dynamicRef\")\n              : nullptr};\n      if (dynamic_ref_value) {\n        if (!dynamic_ref_value->is_string()) {\n          std::ostringstream value;\n          sourcemeta::core::stringify(*dynamic_ref_value, value);\n          throw sourcemeta::core::SchemaKeywordError(\n              \"$dynamicRef\", value.str(), \"Invalid dynamic reference value\");\n        }\n\n        const auto &original{dynamic_ref_value->to_string()};\n        sourcemeta::core::URI ref;\n        try {\n          ref = sourcemeta::core::URI{original};\n        } catch (const URIParseError &) {\n          throw sourcemeta::core::SchemaKeywordError(\n              \"$dynamicRef\", original,\n              \"The dynamic reference is not a valid URI\");\n        }\n\n        if (!nearest_bases.first.empty()) {\n          ref.resolve_from(nearest_bases.first.front());\n        }\n\n        ref.canonicalize();\n        auto ref_string{ref.recompose()};\n\n        // Note that here we cannot enforce the bookending requirement,\n        // as the dynamic reference may point to a schema resource that\n        // is not part of or bundled within the schema we are analyzing here.\n\n        const auto has_fragment{ref.fragment().has_value()};\n        const auto maybe_static_frame{\n            this->locations_.find({SchemaReferenceType::Static, ref_string})};\n        const auto maybe_dynamic_frame{\n            this->locations_.find({SchemaReferenceType::Dynamic, ref_string})};\n        const auto behaves_as_static{\n            !has_fragment ||\n            (has_fragment && maybe_static_frame != this->locations_.end() &&\n             maybe_dynamic_frame == this->locations_.end())};\n        auto dynamic_ref_pointer{common_pointer_weak};\n        dynamic_ref_pointer.push_back(std::cref(KEYWORD_DYNAMIC_REF));\n        const auto [it, inserted] = this->references_.insert_or_assign(\n            {behaves_as_static ? SchemaReferenceType::Static\n                               : SchemaReferenceType::Dynamic,\n             std::move(dynamic_ref_pointer)},\n            SchemaFrame::ReferencesEntry{.original = original,\n                                         .destination = std::move(ref_string),\n                                         .base = std::string_view{},\n                                         .fragment = std::nullopt});\n        set_base_and_fragment(it->second);\n      }\n    }\n  }\n\n  // A schema is standalone if all references can be resolved within itself\n  this->standalone_ =\n      std::ranges::all_of(this->references_, [&](const auto &reference) {\n        assert(!reference.first.second.empty());\n        assert(reference.first.second.back().is_property());\n        // TODO: This check might need to be more elaborate given\n        // https://github.com/sourcemeta/core/issues/1390\n        return reference.first.second.back().to_property() == \"$schema\" ||\n               this->locations_.contains({SchemaReferenceType::Static,\n                                          reference.second.destination}) ||\n               this->locations_.contains({SchemaReferenceType::Dynamic,\n                                          reference.second.destination});\n      });\n\n  if (this->standalone_) {\n    // Find all dynamic anchors\n    // Values are pointers to full URIs in locations_\n    std::unordered_map<JSON::String, std::vector<const JSON::String *>>\n        dynamic_anchors;\n    for (const auto &entry : this->locations_) {\n      if (entry.first.first != SchemaReferenceType::Dynamic ||\n          entry.second.type != SchemaFrame::LocationType::Anchor) {\n        continue;\n      }\n\n      const URI anchor_uri{entry.first.second};\n      // Copy the fragment to avoid dangling string_view (anchor_uri is local)\n      const JSON::String fragment{anchor_uri.fragment().value_or(\"\")};\n      dynamic_anchors[fragment].push_back(&entry.first.second);\n    }\n\n    // If there is a dynamic reference that only has one possible\n    // dynamic anchor destination, then that dynamic reference\n    // is a static reference in disguise\n    std::vector<SchemaFrame::References::key_type> to_delete;\n    std::vector<SchemaFrame::References::value_type> to_insert;\n    for (const auto &reference : this->references_) {\n      if (reference.first.first != SchemaReferenceType::Dynamic ||\n          !reference.second.fragment.has_value()) {\n        continue;\n      }\n\n      const auto match{dynamic_anchors.find(\n          JSON::String{reference.second.fragment.value()})};\n      assert(match != dynamic_anchors.cend());\n      // Otherwise we can assume there is only one possible target for the\n      // dynamic reference\n      if (match->second.size() != 1) {\n        continue;\n      }\n\n      to_delete.push_back(reference.first);\n      to_insert.emplace_back(\n          SchemaFrame::References::key_type{SchemaReferenceType::Static,\n                                            reference.first.second},\n          SchemaFrame::References::mapped_type{\n              reference.second.original, *match->second.front(),\n              std::string_view{}, std::nullopt});\n    }\n\n    // Because we can't mutate a map as we are traversing it\n\n    for (const auto &key : to_delete) {\n      this->references_.erase(key);\n    }\n\n    for (auto &&entry : to_insert) {\n      const auto [it, inserted] = this->references_.emplace(std::move(entry));\n      set_base_and_fragment(it->second);\n    }\n  }\n}\n\nauto SchemaFrame::locations() const noexcept -> const Locations & {\n  return this->locations_;\n}\n\nauto SchemaFrame::references() const noexcept -> const References & {\n  return this->references_;\n}\n\nauto SchemaFrame::reference(const SchemaReferenceType type,\n                            const WeakPointer &pointer) const\n    -> std::optional<std::reference_wrapper<const ReferencesEntry>> {\n  const auto result{this->references_.find({type, pointer})};\n  if (result != this->references_.cend()) {\n    return result->second;\n  }\n\n  return std::nullopt;\n}\n\nauto SchemaFrame::standalone() const noexcept -> bool {\n  return this->standalone_;\n}\n\nauto SchemaFrame::root() const noexcept -> const JSON::String & {\n  return this->root_;\n}\n\nauto SchemaFrame::vocabularies(const Location &location,\n                               const SchemaResolver &resolver) const\n    -> Vocabularies {\n  return sourcemeta::core::vocabularies(resolver, location.base_dialect,\n                                        location.dialect);\n}\n\nauto SchemaFrame::uri(const Location &location,\n                      const WeakPointer &relative_schema_location) const\n    -> JSON::String {\n  return to_uri(this->relative_instance_location(location).concat(\n                    relative_schema_location),\n                location.base)\n      .recompose();\n}\n\nauto SchemaFrame::traverse(const Location &location,\n                           const WeakPointer &relative_schema_location) const\n    -> const Location & {\n  const auto new_uri{this->uri(location, relative_schema_location)};\n  const auto static_match{\n      this->locations_.find({SchemaReferenceType::Static, new_uri})};\n  if (static_match != this->locations_.cend()) {\n    return static_match->second;\n  }\n\n  const auto dynamic_match{\n      this->locations_.find({SchemaReferenceType::Dynamic, new_uri})};\n  assert(dynamic_match != this->locations_.cend());\n  return dynamic_match->second;\n}\n\nauto SchemaFrame::traverse(const std::string_view uri) const\n    -> std::optional<std::reference_wrapper<const Location>> {\n  const JSON::String uri_string{uri};\n  const auto static_result{\n      this->locations_.find({SchemaReferenceType::Static, uri_string})};\n  if (static_result != this->locations_.cend()) {\n    return static_result->second;\n  }\n\n  const auto dynamic_result{\n      this->locations_.find({SchemaReferenceType::Dynamic, uri_string})};\n  if (dynamic_result != this->locations_.cend()) {\n    return dynamic_result->second;\n  }\n\n  return std::nullopt;\n}\n\nauto SchemaFrame::traverse(const WeakPointer &pointer) const\n    -> std::optional<std::reference_wrapper<const Location>> {\n  this->populate_pointer_to_location();\n  const auto iterator{this->pointer_to_location_.find(std::cref(pointer))};\n  if (iterator == this->pointer_to_location_.cend() ||\n      iterator->second.empty()) {\n    return std::nullopt;\n  }\n\n  return *(iterator->second.front());\n}\n\nauto SchemaFrame::traverse(const WeakPointer &pointer,\n                           const LocationType type) const\n    -> std::optional<std::reference_wrapper<const Location>> {\n  this->populate_pointer_to_location();\n  const auto iterator{this->pointer_to_location_.find(std::cref(pointer))};\n  if (iterator == this->pointer_to_location_.cend()) {\n    return std::nullopt;\n  }\n\n  for (const auto *location : iterator->second) {\n    if (location->type == type) {\n      return *location;\n    }\n  }\n\n  return std::nullopt;\n}\n\nauto SchemaFrame::uri(const WeakPointer &pointer) const\n    -> std::optional<std::reference_wrapper<const JSON::String>> {\n  this->populate_pointer_to_location();\n  const auto iterator{this->pointer_to_location_.find(std::cref(pointer))};\n  if (iterator == this->pointer_to_location_.cend()) {\n    return std::nullopt;\n  }\n\n  const Location *best{nullptr};\n  for (const auto *location : iterator->second) {\n    if (best == nullptr || location->type < best->type) {\n      best = location;\n    }\n  }\n\n  if (best != nullptr) {\n    for (const auto &entry : this->locations_) {\n      if (&entry.second == best) {\n        return entry.first.second;\n      }\n    }\n  }\n\n  return std::nullopt;\n}\n\nauto SchemaFrame::dereference(const Location &location,\n                              const WeakPointer &relative_schema_location) const\n    -> std::pair<SchemaReferenceType,\n                 std::optional<std::reference_wrapper<const Location>>> {\n  const auto effective_location{\n      location.pointer.concat(relative_schema_location)};\n  const auto maybe_reference_entry{this->references_.find(\n      {SchemaReferenceType::Static, effective_location})};\n  if (maybe_reference_entry == this->references_.cend()) {\n    // If static dereferencing failed but we know the reference\n    // is dynamic, then report so, but without a location, as by\n    // definition we can't know the destination until at runtime\n    if (this->references_.contains(\n            {SchemaReferenceType::Dynamic, effective_location})) {\n      return {SchemaReferenceType::Dynamic, std::nullopt};\n    }\n\n    return {SchemaReferenceType::Static, std::nullopt};\n  }\n\n  const auto destination{\n      this->locations_.find({SchemaReferenceType::Static,\n                             maybe_reference_entry->second.destination})};\n  assert(destination != this->locations_.cend());\n  return {SchemaReferenceType::Static, destination->second};\n}\n\nauto SchemaFrame::has_references_to(const WeakPointer &pointer) const -> bool {\n  for (const auto &reference : this->references_) {\n    assert(!reference.first.second.empty());\n    assert(reference.first.second.back().is_property());\n\n    if (reference.first.first == SchemaReferenceType::Static) {\n      const auto match{this->locations_.find(\n          {reference.first.first, reference.second.destination})};\n      if (match != this->locations_.cend() &&\n          match->second.pointer == pointer) {\n        return true;\n      }\n    } else {\n      for (const auto &location : this->locations_) {\n        if (location.second.type == LocationType::Anchor &&\n            location.first.first == SchemaReferenceType::Dynamic &&\n            location.second.pointer == pointer) {\n          if (!reference.second.fragment.has_value() ||\n              URI{location.first.second}.fragment().value_or(\"\") ==\n                  reference.second.fragment.value()) {\n            return true;\n          }\n        }\n      }\n    }\n  }\n\n  return false;\n}\n\nauto SchemaFrame::has_references_through(const WeakPointer &pointer) const\n    -> bool {\n  for (const auto &reference : this->references_) {\n    assert(!reference.first.second.empty());\n    assert(reference.first.second.back().is_property());\n\n    if (reference.first.first == SchemaReferenceType::Static) {\n      const auto match{this->locations_.find(\n          {reference.first.first, reference.second.destination})};\n      if (match != this->locations_.cend() &&\n          match->second.pointer.starts_with(pointer)) {\n        return true;\n      }\n    } else {\n      for (const auto &location : this->locations_) {\n        if (location.second.type == LocationType::Anchor &&\n            location.first.first == SchemaReferenceType::Dynamic &&\n            location.second.pointer.starts_with(pointer)) {\n          if (!reference.second.fragment.has_value() ||\n              URI{location.first.second}.fragment().value_or(\"\") ==\n                  reference.second.fragment.value()) {\n            return true;\n          }\n        }\n      }\n    }\n  }\n\n  return false;\n}\n\nauto SchemaFrame::has_references_through(const WeakPointer &pointer,\n                                         const WeakPointer::Token &tail) const\n    -> bool {\n  for (const auto &reference : this->references_) {\n    assert(!reference.first.second.empty());\n    assert(reference.first.second.back().is_property());\n\n    if (reference.first.first == SchemaReferenceType::Static) {\n      const auto match{this->locations_.find(\n          {reference.first.first, reference.second.destination})};\n      if (match != this->locations_.cend() &&\n          match->second.pointer.starts_with(pointer, tail)) {\n        return true;\n      }\n    } else {\n      for (const auto &location : this->locations_) {\n        if (location.second.type == LocationType::Anchor &&\n            location.first.first == SchemaReferenceType::Dynamic &&\n            location.second.pointer.starts_with(pointer, tail)) {\n          if (!reference.second.fragment.has_value() ||\n              URI{location.first.second}.fragment().value_or(\"\") ==\n                  reference.second.fragment.value()) {\n            return true;\n          }\n        }\n      }\n    }\n  }\n\n  return false;\n}\n\nauto SchemaFrame::relative_instance_location(const Location &location) const\n    -> WeakPointer {\n  return location.pointer.slice(location.relative_pointer);\n}\n\nauto SchemaFrame::empty() const noexcept -> bool {\n  return this->locations_.empty() && this->references_.empty();\n}\n\nauto SchemaFrame::reset() -> void {\n  this->pointers_with_non_orphan_.clear();\n  this->pointer_to_location_.clear();\n  this->reachability_.clear();\n  this->references_by_destination_.clear();\n  this->location_members_children_.clear();\n  this->descendants_by_pointer_.clear();\n  this->potential_sources_by_location_.clear();\n  this->reachability_graph_.clear();\n  this->canonical_pointer_.clear();\n  this->location_to_canonical_.clear();\n  this->root_.clear();\n  this->locations_.clear();\n  this->references_.clear();\n  this->standalone_ = false;\n}\n\nauto SchemaFrame::populate_pointer_to_location() const -> void {\n  if (!this->pointer_to_location_.empty()) {\n    return;\n  }\n\n  this->pointer_to_location_.reserve(this->locations_.size());\n  for (const auto &entry : this->locations_) {\n    this->pointer_to_location_[std::cref(entry.second.pointer)].push_back(\n        &entry.second);\n  }\n}\n\nauto SchemaFrame::populate_location_members(\n    const SchemaWalker &walker, const SchemaResolver &resolver) const -> void {\n  if (!this->location_members_children_.empty()) {\n    return;\n  }\n\n  this->populate_pointer_to_location();\n\n  for (const auto &entry : this->locations_) {\n    if (entry.second.type != LocationType::Subschema) {\n      continue;\n    }\n    if (!entry.second.parent.has_value()) {\n      continue;\n    }\n    const auto &parent_pointer{entry.second.parent.value()};\n    const auto relative{entry.second.pointer.slice(parent_pointer.size())};\n    if (relative.empty() || !relative.at(0).is_property()) {\n      continue;\n    }\n    const auto parent_location{this->traverse(parent_pointer)};\n    if (!parent_location.has_value()) {\n      continue;\n    }\n    const auto vocabs{this->vocabularies(parent_location->get(), resolver)};\n    const auto &keyword_result{walker(relative.at(0).to_property(), vocabs)};\n    if (keyword_result.type == SchemaKeywordType::LocationMembers) {\n      this->location_members_children_.insert(std::cref(entry.second.pointer));\n    }\n  }\n}\n\nauto SchemaFrame::populate_descendants() const -> void {\n  if (!this->descendants_by_pointer_.empty()) {\n    return;\n  }\n\n  this->populate_pointer_to_location();\n\n  for (const auto &entry : this->locations_) {\n    if (entry.second.type == LocationType::Pointer) {\n      continue;\n    }\n\n    const auto &pointer{entry.second.pointer};\n    const auto *location{&entry.second};\n\n    WeakPointer prefix;\n    for (std::size_t index = 0; index <= pointer.size(); ++index) {\n      auto prefix_iter = this->pointer_to_location_.find(std::cref(prefix));\n      if (prefix_iter != this->pointer_to_location_.end() &&\n          !prefix_iter->second.empty()) {\n        const auto &key_pointer{prefix_iter->second.front()->pointer};\n        this->descendants_by_pointer_[std::cref(key_pointer)].push_back(\n            location);\n      }\n      if (index < pointer.size()) {\n        const auto &token{pointer.at(index)};\n        if (token.is_property()) {\n          prefix.emplace_back(token.to_property(), token.property_hash());\n        } else {\n          prefix.push_back(token.to_index());\n        }\n      }\n    }\n  }\n}\n\nauto SchemaFrame::populate_potential_sources(\n    const SchemaWalker &walker, const SchemaResolver &resolver) const -> void {\n  if (!this->potential_sources_by_location_.empty()) {\n    return;\n  }\n\n  this->populate_reference_graph();\n  this->populate_location_members(walker, resolver);\n\n  for (const auto &entry : this->locations_) {\n    if (entry.second.type == LocationType::Pointer) {\n      continue;\n    }\n\n    const auto &pointer{entry.second.pointer};\n    const auto *location{&entry.second};\n    std::vector<PotentialSource> sources;\n\n    WeakPointer ancestor = pointer;\n    bool first_iteration{true};\n    while (first_iteration || !ancestor.empty()) {\n      auto destination_iterator =\n          this->references_by_destination_.find(std::cref(ancestor));\n      if (destination_iterator != this->references_by_destination_.end()) {\n        bool crosses{false};\n        if (ancestor != pointer) {\n          for (const auto &boundary_ref : this->location_members_children_) {\n            const auto &boundary{boundary_ref.get()};\n            if (pointer.starts_with(boundary) &&\n                !ancestor.starts_with(boundary)) {\n              crosses = true;\n              break;\n            }\n          }\n        }\n\n        for (const auto *source_pointer : destination_iterator->second) {\n          sources.push_back(\n              PotentialSource{.source_pointer = source_pointer,\n                              .source_parent = source_pointer->initial(),\n                              .crosses = crosses});\n        }\n      }\n\n      if (ancestor.empty()) {\n        break;\n      }\n      ancestor = ancestor.initial();\n      first_iteration = false;\n    }\n\n    if (!sources.empty()) {\n      this->potential_sources_by_location_[location] = std::move(sources);\n    }\n  }\n}\n\nauto SchemaFrame::populate_reference_graph() const -> void {\n  if (!this->references_by_destination_.empty()) {\n    return;\n  }\n\n  std::unordered_map<std::string_view, std::vector<const WeakPointer *>>\n      dynamic_anchors_by_fragment;\n  for (const auto &location : this->locations_) {\n    if (location.first.first == SchemaReferenceType::Dynamic &&\n        location.second.type == LocationType::Anchor) {\n      const auto &uri{location.first.second};\n      const auto hash_pos{uri.rfind('#')};\n      if (hash_pos != std::string::npos) {\n        std::string_view fragment{uri.data() + hash_pos + 1,\n                                  uri.size() - hash_pos - 1};\n        dynamic_anchors_by_fragment[fragment].push_back(\n            &location.second.pointer);\n      }\n    }\n  }\n\n  std::vector<std::pair<const WeakPointer *, const WeakPointer *>>\n      reference_destinations;\n  reference_destinations.reserve(this->references_.size());\n\n  for (const auto &reference : this->references_) {\n    const auto &source_pointer{reference.first.second};\n    if (source_pointer.empty()) {\n      continue;\n    }\n\n    if (reference.first.first == SchemaReferenceType::Dynamic &&\n        reference.second.fragment.has_value()) {\n      const auto &fragment{reference.second.fragment.value()};\n      const auto match{dynamic_anchors_by_fragment.find(fragment)};\n      if (match != dynamic_anchors_by_fragment.cend()) {\n        for (const auto *destination_pointer : match->second) {\n          reference_destinations.emplace_back(&source_pointer,\n                                              destination_pointer);\n        }\n      }\n\n      continue;\n    }\n\n    const auto destination_location{this->locations_.find(\n        {SchemaReferenceType::Static, reference.second.destination})};\n    if (destination_location != this->locations_.cend()) {\n      reference_destinations.emplace_back(\n          &source_pointer, &destination_location->second.pointer);\n    }\n  }\n\n  for (const auto &[source, destination] : reference_destinations) {\n    this->references_by_destination_[std::cref(*destination)].push_back(source);\n  }\n}\n\nauto SchemaFrame::populate_reachability_graph(\n    const SchemaWalker &walker, const SchemaResolver &resolver) const -> void {\n  if (!this->reachability_graph_.empty()) {\n    return;\n  }\n\n  this->populate_pointer_to_location();\n  this->populate_location_members(walker, resolver);\n  this->populate_reference_graph();\n\n  for (const auto &entry : this->locations_) {\n    if (entry.second.pointer.empty()) {\n      continue;\n    }\n\n    const auto parent_pointer{entry.second.pointer.initial()};\n    auto parent_iterator =\n        this->pointer_to_location_.find(std::cref(parent_pointer));\n    if (parent_iterator == this->pointer_to_location_.end()) {\n      continue;\n    }\n\n    for (const Location *parent_location : parent_iterator->second) {\n      this->reachability_graph_[parent_location].push_back(\n          ReachabilityEdge{.target = &entry.second,\n                           .orphan_context_only = entry.second.orphan,\n                           .is_reference = false});\n    }\n  }\n\n  for (const auto &[destination_reference, sources] :\n       this->references_by_destination_) {\n    auto destination_locations_iterator =\n        this->pointer_to_location_.find(destination_reference);\n    if (destination_locations_iterator == this->pointer_to_location_.end()) {\n      continue;\n    }\n\n    const Location *destination_location{nullptr};\n    for (const auto *location : destination_locations_iterator->second) {\n      if (location->type != LocationType::Pointer) {\n        destination_location = location;\n        break;\n      }\n    }\n\n    if (!destination_location &&\n        !destination_locations_iterator->second.empty()) {\n      destination_location = destination_locations_iterator->second.front();\n    }\n\n    if (!destination_location) {\n      continue;\n    }\n\n    for (const auto *source_pointer : sources) {\n      if (source_pointer->empty()) {\n        continue;\n      }\n\n      const auto source_parent_pointer{source_pointer->initial()};\n      auto source_parent_iterator =\n          this->pointer_to_location_.find(std::cref(source_parent_pointer));\n      if (source_parent_iterator == this->pointer_to_location_.end()) {\n        continue;\n      }\n\n      for (const Location *source_parent_location :\n           source_parent_iterator->second) {\n        this->reachability_graph_[source_parent_location].push_back(\n            ReachabilityEdge{.target = destination_location,\n                             .orphan_context_only = false,\n                             .is_reference = true});\n      }\n    }\n  }\n\n  for (const auto &entry : this->locations_) {\n    auto result = this->canonical_pointer_.emplace(\n        std::cref(entry.second.pointer), &entry.second.pointer);\n    this->location_to_canonical_[&entry.second] =\n        result.second ? &entry.second.pointer : result.first->second;\n  }\n}\n\nauto SchemaFrame::populate_reachability(const Location &base,\n                                        const SchemaWalker &walker,\n                                        const SchemaResolver &resolver) const\n    -> const ReachabilityCache & {\n  const ReachabilityKey key{.pointer = &base.pointer, .orphan = base.orphan};\n  auto cache_iterator = this->reachability_.find(key);\n  if (cache_iterator != this->reachability_.end()) {\n    return cache_iterator->second;\n  }\n\n  auto &cache = this->reachability_[key];\n  this->populate_reachability_graph(walker, resolver);\n\n  const Location *base_location{&base};\n  std::vector<const Location *> queue;\n  std::unordered_set<const Location *> visited;\n\n  queue.push_back(base_location);\n  visited.insert(base_location);\n  auto base_canonical_iterator =\n      this->location_to_canonical_.find(base_location);\n  if (base_canonical_iterator != this->location_to_canonical_.end()) {\n    cache.emplace(base_canonical_iterator->second, true);\n  }\n\n  std::size_t queue_index{0};\n  while (queue_index < queue.size()) {\n    const Location *current = queue[queue_index++];\n\n    auto edges_iterator = this->reachability_graph_.find(current);\n    if (edges_iterator == this->reachability_graph_.end()) {\n      continue;\n    }\n\n    for (const auto &edge : edges_iterator->second) {\n      if (visited.contains(edge.target)) {\n        continue;\n      }\n\n      if (edge.orphan_context_only && !base.orphan && !current->orphan) {\n        continue;\n      }\n\n      if (!edge.is_reference && edge.orphan_context_only) {\n        auto target_iterator = this->location_members_children_.find(\n            std::cref(edge.target->pointer));\n        if (target_iterator != this->location_members_children_.end()) {\n          const auto keyword_path{edge.target->pointer.initial()};\n          if (keyword_path.starts_with(current->pointer)) {\n            continue;\n          }\n        }\n      }\n\n      visited.insert(edge.target);\n      queue.push_back(edge.target);\n\n      auto target_canonical_iterator =\n          this->location_to_canonical_.find(edge.target);\n      if (target_canonical_iterator != this->location_to_canonical_.end()) {\n        cache.emplace(target_canonical_iterator->second, true);\n      }\n    }\n  }\n\n  return cache;\n}\n\nauto SchemaFrame::is_reachable(const Location &base, const Location &location,\n                               const SchemaWalker &walker,\n                               const SchemaResolver &resolver) const -> bool {\n  assert(location.type != LocationType::Pointer);\n  const auto &cache{this->populate_reachability(base, walker, resolver)};\n  auto canonical_iterator = this->location_to_canonical_.find(&location);\n  if (canonical_iterator == this->location_to_canonical_.end()) {\n    return false;\n  }\n  const auto iterator{cache.find(canonical_iterator->second)};\n  return iterator != cache.end() && iterator->second;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/helpers.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_HELPERS_H\n#define SOURCEMETA_CORE_JSONSCHEMA_HELPERS_H\n\n#include <sourcemeta/core/jsonschema.h>\n\n#include <cassert>     // assert\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\ninline auto id_keyword(const SchemaBaseDialect base_dialect)\n    -> std::string_view {\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_2020_12:\n    case SchemaBaseDialect::JSON_Schema_2020_12_Hyper:\n    case SchemaBaseDialect::JSON_Schema_2019_09:\n    case SchemaBaseDialect::JSON_Schema_2019_09_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n      return \"$id\";\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_2_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_1_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_0_Hyper:\n      return \"id\";\n  }\n\n  assert(false);\n  return \"$id\";\n}\n\ninline auto definitions_keyword(const SchemaBaseDialect base_dialect)\n    -> std::string_view {\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_2020_12:\n    case SchemaBaseDialect::JSON_Schema_2020_12_Hyper:\n    case SchemaBaseDialect::JSON_Schema_2019_09:\n    case SchemaBaseDialect::JSON_Schema_2019_09_Hyper:\n      return \"$defs\";\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n      return \"definitions\";\n    case SchemaBaseDialect::JSON_Schema_Draft_2_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_1_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_0_Hyper:\n      return \"\";\n  }\n\n  assert(false);\n  return \"$defs\";\n}\n\n// In older drafts, the presence of `$ref` would override any sibling keywords\n// See\n// https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.8.3\ninline auto\nref_overrides_adjacent_keywords(const SchemaBaseDialect base_dialect) -> bool {\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n      return true;\n    default:\n      return false;\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_H_\n#define SOURCEMETA_CORE_JSONSCHEMA_H_\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/jsonschema_bundle.h>\n#include <sourcemeta/core/jsonschema_error.h>\n#include <sourcemeta/core/jsonschema_frame.h>\n#include <sourcemeta/core/jsonschema_types.h>\n#include <sourcemeta/core/jsonschema_walker.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cstdint>     // std::uint8_t\n#include <functional>  // std::function\n#include <optional>    // std::optional, std::nullopt\n#include <set>         // std::set\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\n/// @defgroup jsonschema JSON Schema\n/// @brief A set of JSON Schema utilities across draft versions.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/jsonschema.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonschema\n/// A default resolver that relies on built-in official schemas.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto schema_resolver(const std::string_view identifier) -> std::optional<JSON>;\n\n/// @ingroup jsonschema\n/// Check if a given identifier corresponds to a known built-in schema\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto is_known_schema(const std::string_view identifier) noexcept -> bool;\n\n/// @ingroup jsonschema\n/// A default schema walker with support for a wide range of drafts\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto schema_walker(const std::string_view keyword,\n                   const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult &;\n\n/// @ingroup jsonschema\n/// Stringify a base dialect to its URI\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto to_string(const SchemaBaseDialect base_dialect) -> std::string_view;\n\n/// @ingroup jsonschema\n/// Parse a base dialect URI to its enum representation\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto to_base_dialect(const std::string_view base_dialect)\n    -> std::optional<SchemaBaseDialect>;\n\n/// @ingroup jsonschema\n///\n/// Calculate the priority of a keyword that determines the ordering in which a\n/// JSON Schema implementation should evaluate keyword on a subschema. It does\n/// so based on the keyword dependencies expressed in the schema walker. The\n/// higher the priority, the more the evaluation of such keyword must be\n/// delayed.\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"prefixItems\": [ true, true ],\n///   \"items\": false\n/// })JSON\");\n///\n/// const auto vocabularies{\n///   sourcemeta::core::vocabularies(\n///     document, sourcemeta::core::schema_resolver)};\n///\n/// assert(sourcemeta::core::schema_keyword_priority(\n///   \"prefixItems\", vocabularies,\n///   sourcemeta::core::schema_walker) == 0);\n///\n/// // The \"items\" keyword must be evaluated after the \"prefixItems\" keyword\n/// assert(sourcemeta::core::schema_keyword_priority(\n///   \"items\", vocabularies,\n///   sourcemeta::core::schema_walker) == 1);\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto schema_keyword_priority(const std::string_view keyword,\n                             const Vocabularies &vocabularies,\n                             const SchemaWalker &walker) -> std::uint64_t;\n\n/// @ingroup jsonschema\n///\n/// This function returns true if the given JSON instance is of a\n/// schema-compatible type: an object or a boolean. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document{true};\n/// assert(sourcemeta::core::is_schema(document));\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto is_schema(const JSON &schema) -> bool;\n\n/// @ingroup jsonschema\n///\n/// This function returns true if the given JSON instance is a schema\n/// semantically equivalent to the empty schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document{true};\n/// assert(sourcemeta::core::is_empty_schema(document));\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto is_empty_schema(const JSON &schema) -> bool;\n\n/// @ingroup jsonschema\n///\n/// This function returns the URI identifier of the given schema, or an empty\n/// string view if the schema has no identifier. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"$id\": \"https://sourcemeta.com/example-schema\"\n/// })JSON\");\n///\n/// const auto id{sourcemeta::core::identify(\n///   document, sourcemeta::core::schema_resolver)};\n/// assert(!id.empty());\n/// assert(id == \"https://sourcemeta.com/example-schema\");\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto identify(const JSON &schema, const SchemaResolver &resolver,\n              std::string_view default_dialect = \"\",\n              std::string_view default_id = \"\",\n              bool allow_dialect_override = true) -> std::string_view;\n\n/// @ingroup jsonschema\n///\n/// A shortcut to sourcemeta::core::identify if you know the base dialect\n/// of the schema.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto identify(const JSON &schema, const SchemaBaseDialect base_dialect,\n              std::string_view default_id = \"\") -> std::string_view;\n\n/// @ingroup jsonschema\n///\n/// This function removes the top-level URI identifier of the given schema, if\n/// any, given you know its base dialect. It is the caller responsibility to\n/// ensure the schema doesn't perform relative references that might have\n/// depended on such top-level identifier. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"$id\": \"https://sourcemeta.com/example-schema\"\n/// })JSON\");\n///\n/// sourcemeta::core::anonymize(document,\n///   sourcemeta::core::SchemaBaseDialect::JSON_Schema_2020_12);\n///\n/// const auto id{sourcemeta::core::identify(\n///   document, sourcemeta::core::schema_resolver)};\n/// assert(id.empty());\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto anonymize(JSON &schema, const SchemaBaseDialect base_dialect) -> void;\n\n/// @ingroup jsonschema\n///\n/// This function sets the identifier of a schema, replacing the existing one,\n/// if any. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"$id\": \"https://sourcemeta.com/example-schema\"\n/// })JSON\");\n///\n/// sourcemeta::core::reidentify(document,\n///   \"https://example.com/my-new-id\",\n///   sourcemeta::core::schema_resolver);\n///\n/// const auto id{sourcemeta::core::identify(\n///   document, sourcemeta::core::schema_resolver)};\n/// assert(!id.empty());\n/// assert(id == \"https://example.com/my-new-id\");\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto reidentify(JSON &schema, std::string_view new_identifier,\n                const SchemaResolver &resolver,\n                std::string_view default_dialect = \"\") -> void;\n\n/// @ingroup jsonschema\n///\n/// A shortcut to sourcemeta::core::reidentify if you know the base\n/// dialect of the schema.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto reidentify(JSON &schema, std::string_view new_identifier,\n                const SchemaBaseDialect base_dialect) -> void;\n\n/// @ingroup jsonschema\n///\n/// Get the dialect URI that corresponds to a JSON Schema instance.\n/// The result is empty if the dialect cannot be determined. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\"\n/// })JSON\");\n///\n/// const auto dialect{sourcemeta::core::dialect(document)};\n/// assert(!dialect.empty());\n/// assert(dialect == \"https://json-schema.org/draft/2020-12/schema\");\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto dialect(const JSON &schema, std::string_view default_dialect = \"\",\n             bool allow_dialect_override = true) -> std::string_view;\n\n/// @ingroup jsonschema\n///\n/// Get the metaschema document that describes the given schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\"\n/// })JSON\");\n///\n/// const sourcemeta::core::JSON metaschema{\n///   sourcemeta::core::metaschema(\n///     document, sourcemeta::core::schema_resolver)};\n///\n/// sourcemeta::core::prettify(metaschema, std::cout);\n/// std::cout << std::endl;\n/// ```\n///\n/// This function will throw if the metaschema cannot be determined or resolved.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto metaschema(const JSON &schema, const SchemaResolver &resolver,\n                std::string_view default_dialect = \"\") -> JSON;\n\n/// @ingroup jsonschema\n///\n/// Get the base dialect that applies to the given schema. If you set\n/// a default dialect URI, this will be used if the given schema does not\n/// declare the `$schema` keyword. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\"\n/// })JSON\");\n///\n/// const auto base_dialect{\n///   sourcemeta::core::base_dialect(\n///     document, sourcemeta::core::schema_resolver)};\n///\n/// assert(base_dialect.has_value());\n/// assert(base_dialect.value() ==\n///   sourcemeta::core::SchemaBaseDialect::JSON_Schema_2020_12);\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto base_dialect(const JSON &schema, const SchemaResolver &resolver,\n                  std::string_view default_dialect = \"\",\n                  bool allow_dialect_override = true)\n    -> std::optional<SchemaBaseDialect>;\n\n/// @ingroup jsonschema\n///\n/// Parse the `$vocabulary` keyword from a given schema, if set. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"$vocabulary\": {\n///     \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n///     \"https://json-schema.org/draft/2020-12/vocab/applicator\": true\n///   }\n/// })JSON\");\n///\n/// const auto result{\n///   sourcemeta::core::parse_vocabularies(\n///     document, sourcemeta::core::schema_resolver)};\n///\n/// assert(result.has_value());\n/// assert(result->size() == 2);\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto parse_vocabularies(const JSON &schema, const SchemaResolver &resolver,\n                        std::string_view default_dialect = \"\")\n    -> std::optional<Vocabularies>;\n\n/// @ingroup jsonschema\n///\n/// A shortcut to sourcemeta::core::parse_vocabularies when the base dialect\n/// is already known.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto parse_vocabularies(const JSON &schema,\n                        const SchemaBaseDialect base_dialect)\n    -> std::optional<Vocabularies>;\n\n/// @ingroup jsonschema\n///\n/// List the vocabularies that a specific schema makes use of. If you set a\n/// default dialect URI, this will be used if the given schema does not\n/// declare the\n/// `$schema` keyword. The resulting map values are set to `true` or `false`\n/// depending on whether the corresponding vocabulary is required or optional,\n/// respectively. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\"\n/// })JSON\");\n///\n/// const auto vocabularies{\n///   sourcemeta::core::vocabularies(\n///     document, sourcemeta::core::schema_resolver)};\n///\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/core\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/applicator\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/unevaluated\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/validation\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/meta-data\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/format-annotation\"));\n/// assert(vocabularies.at(\"https://json-schema.org/draft/2020-12/vocab/content\"));\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto vocabularies(const JSON &schema, const SchemaResolver &resolver,\n                  std::string_view default_dialect = \"\") -> Vocabularies;\n\n/// @ingroup jsonschema\n///\n/// A shortcut to sourcemeta::core::vocabularies based on the base\n/// dialect and dialect URI.\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto vocabularies(const SchemaResolver &resolver,\n                  const SchemaBaseDialect base_dialect,\n                  std::string_view dialect) -> Vocabularies;\n\n/// @ingroup jsonschema\n///\n/// Format a JSON Schema document by reordering all object properties throughout\n/// the entire document according to an opinionated JSON Schema aware ordering.\n/// This function modifies the schema in-place. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n/// #include <sstream>\n///\n/// sourcemeta::core::JSON schema =\n///   sourcemeta::core::parse_json(\n///     \"{ \\\"type\\\": \\\"string\\\", \\\"minLength\\\": 3 }\");\n/// sourcemeta::core::format(schema, sourcemeta::core::schema_walker,\n///                          sourcemeta::core::schema_resolver);\n/// std::ostringstream stream;\n/// sourcemeta::core::prettify(schema, stream);\n/// std::cout << stream.str() << std::endl;\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto format(JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver,\n            std::string_view default_dialect = \"\") -> void;\n\n/// @ingroup jsonschema\n///\n/// Given a schema identifier, this function creates a JSON Schema wrapper that\n/// references such schema. This is useful when trying to validate an instance\n/// against a specific subset of a schema, as the wrapper allows you to make use\n/// of JSON Schema referencing to get there without reinventing the wheel. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON result =\n///   sourcemeta::core::wrap(\"https://www.example.com#/foo/bar\");\n///\n/// sourcemeta::core::prettify(result, std::cerr);\n/// std::cerr << \"\\n\";\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto wrap(std::string_view identifier) -> JSON;\n\n/// @ingroup jsonschema\n///\n/// Wrap a schema to only access one of its subschemas. This is useful if you\n/// want to perform validation on only a specific part of the schema without\n/// having to reinvent the wheel. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"type\": \"string\" }\n/// })JSON\");\n///\n/// sourcemeta::core::SchemaFrame frame{\n///     sourcemeta::core::SchemaFrame::Mode::References};\n/// frame.analyse(document, sourcemeta::core::schema_walker,\n///               sourcemeta::core::schema_resolver);\n///\n/// const auto location{frame.traverse(\n///     sourcemeta::core::WeakPointer{\"items\"},\n///     sourcemeta::core::SchemaFrame::LocationType::Subschema)};\n///\n/// sourcemeta::core::WeakPointer base;\n/// const sourcemeta::core::JSON result =\n///   sourcemeta::core::wrap(document, frame, location.value().get(),\n///     sourcemeta::core::schema_resolver, base);\n///\n/// sourcemeta::core::prettify(result, std::cerr);\n/// std::cerr << \"\\n\";\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto wrap(const JSON &schema, const SchemaFrame &frame,\n          const SchemaFrame::Location &location, const SchemaResolver &resolver,\n          WeakPointer &base) -> JSON;\n\n/// @ingroup jsonschema\n///\n/// Parse the value of a JSON Schema `type` keyword (which can be a string or\n/// an array of strings) into a set of native JSON types. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const auto type{sourcemeta::core::parse_json(R\"JSON([ \"string\", \"null\"\n/// ])JSON\")}; const auto types{sourcemeta::core::parse_schema_type(type)};\n/// assert(types.test(\n///     static_cast<std::size_t>(sourcemeta::core::JSON::Type::String)));\n/// assert(types.test(\n///     static_cast<std::size_t>(sourcemeta::core::JSON::Type::Null)));\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto parse_schema_type(const JSON &type) -> JSON::TypeSet;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_bundle.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_BUNDLE_H\n#define SOURCEMETA_CORE_JSONSCHEMA_BUNDLE_H\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/jsonschema_frame.h>\n#include <sourcemeta/core/jsonschema_types.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <functional>  // std::function\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonschema\n/// A callback to get dependency information\n/// - Origin URI (empty if none)\n/// - Pointer (reference keyword from the origin)\n/// - Target URI\n/// - Target schema\nusing DependencyCallback = std::function<void(\n    std::string_view, const WeakPointer &, std::string_view, const JSON &)>;\n\n/// @ingroup jsonschema\n///\n/// This function recursively traverses and reports the external references in a\n/// schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// // A custom resolver that knows about an additional schema\n/// static auto test_resolver(std::string_view identifier)\n///     -> std::optional<sourcemeta::core::JSON> {\n///   if (identifier == \"https://www.example.com/test\") {\n///     return sourcemeta::core::parse_json(R\"JSON({\n///       \"$id\": \"https://www.example.com/test\",\n///       \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///       \"type\": \"string\"\n///     })JSON\");\n///   } else {\n///     return sourcemeta::core::schema_resolver(identifier);\n///   }\n/// }\n///\n/// sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$ref\": \"https://www.example.com/test\" }\n/// })JSON\");\n///\n/// sourcemeta::core::dependencies(document,\n///   sourcemeta::core::schema_walker, test_resolver,\n///   [](const auto &origin,\n///      const auto &pointer,\n///      const auto &target,\n///      const auto &schema) {\n///     // Do something with the information\n///   });\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto dependencies(const JSON &schema, const SchemaWalker &walker,\n                  const SchemaResolver &resolver,\n                  const DependencyCallback &callback,\n                  std::string_view default_dialect = \"\",\n                  std::string_view default_id = \"\",\n                  const SchemaFrame::Paths &paths = {empty_weak_pointer})\n    -> void;\n\n/// @ingroup jsonschema\n///\n/// This function bundles a JSON Schema (starting from Draft 4) by embedding\n/// every remote reference into the top level schema resource, handling circular\n/// dependencies and more. This overload mutates the input schema.  For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// // A custom resolver that knows about an additional schema\n/// static auto test_resolver(std::string_view identifier)\n///     -> std::optional<sourcemeta::core::JSON> {\n///   if (identifier == \"https://www.example.com/test\") {\n///     return sourcemeta::core::parse_json(R\"JSON({\n///       \"$id\": \"https://www.example.com/test\",\n///       \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///       \"type\": \"string\"\n///     })JSON\");\n///   } else {\n///     return sourcemeta::core::schema_resolver(identifier);\n///   }\n/// }\n///\n/// sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$ref\": \"https://www.example.com/test\" }\n/// })JSON\");\n///\n/// sourcemeta::core::bundle(document,\n///   sourcemeta::core::schema_walker, test_resolver);\n///\n/// const sourcemeta::core::JSON expected =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$ref\": \"https://www.example.com/test\" },\n///   \"$defs\": {\n///     \"https://www.example.com/test\": {\n///       \"$id\": \"https://www.example.com/test\",\n///       \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///       \"type\": \"string\"\n///     }\n///   }\n/// })JSON\");\n///\n/// assert(document == expected);\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto bundle(JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver,\n            std::string_view default_dialect = \"\",\n            std::string_view default_id = \"\",\n            const std::optional<Pointer> &default_container = std::nullopt,\n            const SchemaFrame::Paths &paths = {empty_weak_pointer}) -> void;\n\n/// @ingroup jsonschema\n///\n/// This function bundles a JSON Schema (starting from Draft 4) by embedding\n/// every remote reference into the top level schema resource, handling circular\n/// dependencies and more. This overload returns a new schema, without mutating\n/// the input schema. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// // A custom resolver that knows about an additional schema\n/// static auto test_resolver(std::string_view identifier)\n///     -> std::optional<sourcemeta::core::JSON> {\n///   if (identifier == \"https://www.example.com/test\") {\n///     return sourcemeta::core::parse_json(R\"JSON({\n///       \"$id\": \"https://www.example.com/test\",\n///       \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///       \"type\": \"string\"\n///     })JSON\");\n///   } else {\n///     return sourcemeta::core::schema_resolver(identifier);\n///   }\n/// }\n///\n/// const sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$ref\": \"https://www.example.com/test\" }\n/// })JSON\");\n///\n/// const sourcemeta::core::JSON result =\n///   sourcemeta::core::bundle(document,\n///     sourcemeta::core::schema_walker, test_resolver);\n///\n/// const sourcemeta::core::JSON expected =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$ref\": \"https://www.example.com/test\" },\n///   \"$defs\": {\n///     \"https://www.example.com/test\": {\n///       \"$id\": \"https://www.example.com/test\",\n///       \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///       \"type\": \"string\"\n///     }\n///   }\n/// })JSON\");\n///\n/// assert(result == expected);\n/// ```\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT\nauto bundle(const JSON &schema, const SchemaWalker &walker,\n            const SchemaResolver &resolver,\n            std::string_view default_dialect = \"\",\n            std::string_view default_id = \"\",\n            const std::optional<Pointer> &default_container = std::nullopt,\n            const SchemaFrame::Paths &paths = {empty_weak_pointer}) -> JSON;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_error.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_ERROR_H\n#define SOURCEMETA_CORE_JSONSCHEMA_ERROR_H\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup jsonschema\n/// An error that represents a general schema error event\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaError : public std::exception {\npublic:\n  SchemaError(const char *message) : message_{message} {}\n  SchemaError(std::string message) = delete;\n  SchemaError(std::string &&message) = delete;\n  SchemaError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema resolution failure event\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaResolutionError\n    : public std::exception {\npublic:\n  SchemaResolutionError(const std::string_view identifier, const char *message)\n      : identifier_{identifier}, message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\nprivate:\n  std::string identifier_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a relative meta-schema resolution failure event\n/// Relative references to meta-schemas are invalid as per the specification\n/// See https://json-schema.org/draft/2020-12/json-schema-core#section-8.1.1-2\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaRelativeMetaschemaResolutionError\n    : public SchemaResolutionError {\npublic:\n  SchemaRelativeMetaschemaResolutionError(const std::string_view identifier)\n      : SchemaResolutionError{identifier,\n                              \"Relative meta-schema URIs are not valid \"\n                              \"according to the JSON Schema specification\"} {}\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema vocabulary error\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaVocabularyError\n    : public std::exception {\npublic:\n  SchemaVocabularyError(const std::string_view uri, const char *message)\n      : uri_{uri}, message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto uri() const noexcept -> std::string_view {\n    return this->uri_;\n  }\n\nprivate:\n  std::string uri_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema resolution failure event\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaReferenceError\n    : public std::exception {\npublic:\n  SchemaReferenceError(const std::string_view identifier,\n                       Pointer schema_location, const char *message)\n      : identifier_{identifier}, schema_location_{std::move(schema_location)},\n        message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\n  [[nodiscard]] auto location() const noexcept -> const Pointer & {\n    return this->schema_location_;\n  }\n\nprivate:\n  std::string identifier_;\n  Pointer schema_location_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents that the dialect of the schema could not determined\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaUnknownDialectError\n    : public std::exception {\npublic:\n  SchemaUnknownDialectError() = default;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Could not determine the dialect of the schema\";\n  }\n};\n\n/// @ingroup jsonschema\n/// An error that represents that the base dialect of the schema could not\n/// determined\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaUnknownBaseDialectError\n    : public std::exception {\npublic:\n  SchemaUnknownBaseDialectError() = default;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Could not determine the base dialect of the schema\";\n  }\n};\n\n/// @ingroup jsonschema\n/// In JSON Schema Draft 7 and older, a schema that defines `$ref` is a\n/// reference object where every other keywords are ignored\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaReferenceObjectResourceError\n    : public std::exception {\npublic:\n  SchemaReferenceObjectResourceError(const std::string_view identifier)\n      : identifier_{identifier} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"A schema with a top-level `$ref` in JSON Schema Draft 7 and older \"\n           \"dialects ignores every sibling keywords (like identifiers and \"\n           \"meta-schema declarations) and therefore many operations, like \"\n           \"bundling, are not possible without undefined behavior\";\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\nprivate:\n  std::string identifier_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents an unrecognized base dialect\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaBaseDialectError\n    : public std::exception {\npublic:\n  SchemaBaseDialectError(const std::string_view base_dialect)\n      : base_dialect_{base_dialect} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Unrecognized base dialect\";\n  }\n\n  [[nodiscard]] auto base_dialect() const noexcept -> std::string_view {\n    return this->base_dialect_;\n  }\n\nprivate:\n  std::string base_dialect_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema keyword error\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaKeywordError\n    : public std::exception {\npublic:\n  SchemaKeywordError(const std::string_view keyword,\n                     const std::string_view value, const char *message)\n      : keyword_{keyword}, value_{value}, message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto value() const noexcept -> std::string_view {\n    return this->value_;\n  }\n\n  [[nodiscard]] auto keyword() const noexcept -> std::string_view {\n    return this->keyword_;\n  }\n\nprivate:\n  std::string keyword_;\n  std::string value_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema frame error\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrameError\n    : public std::exception {\npublic:\n  SchemaFrameError(const std::string_view identifier, const char *message)\n      : identifier_{identifier}, message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\nprivate:\n  std::string identifier_;\n  const char *message_;\n};\n\n/// @ingroup jsonschema\n/// An error that represents a schema anchor collision error\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaAnchorCollisionError\n    : public std::exception {\npublic:\n  SchemaAnchorCollisionError(const std::string_view identifier,\n                             Pointer location, Pointer other)\n      : identifier_{identifier}, location_(std::move(location)),\n        other_(std::move(other)) {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Schema anchor already exists\";\n  }\n\n  [[nodiscard]] auto identifier() const noexcept -> std::string_view {\n    return this->identifier_;\n  }\n\n  [[nodiscard]] auto location() const noexcept -> const Pointer & {\n    return this->location_;\n  }\n\n  [[nodiscard]] auto other() const noexcept -> const Pointer & {\n    return this->other_;\n  }\n\nprivate:\n  std::string identifier_;\n  Pointer location_;\n  Pointer other_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_FRAME_H_\n#define SOURCEMETA_CORE_JSONSCHEMA_FRAME_H_\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <sourcemeta/core/jsonschema_types.h>\n#include <sourcemeta/core/jsonschema_walker.h>\n\n#include <concepts>      // std::invocable\n#include <cstdint>       // std::uint8_t\n#include <functional>    // std::reference_wrapper\n#include <map>           // std::map\n#include <optional>      // std::optional\n#include <set>           // std::set\n#include <tuple>         // std::tuple\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::pair\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonschema\n///\n/// This class performs a static analysis pass on the input schema, computing\n/// things such as the static identifiers and references of a schema.\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::JSON document =\n///     sourcemeta::core::parse_json(R\"JSON({\n///   \"$id\": \"https://www.example.com/schema\",\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"items\": { \"$id\": \"foo\", \"type\": \"string\" },\n///   \"properties\": {\n///     \"foo\": { \"$anchor\": \"test\", \"type\": \"number\" },\n///     \"bar\": { \"$ref\": \"#/properties/foo\" }\n///   }\n/// })JSON\");\n///\n/// sourcemeta::core::SchemaFrame\n///   frame{sourcemeta::core::SchemaFrame::Mode::References};\n///\n/// frame.analyse(document,\n///   sourcemeta::core::schema_walker,\n///   sourcemeta::core::schema_resolver);\n/// ```\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {\npublic:\n  /// The mode of framing. More extensive analysis can be compute and memory\n  /// intensive\n  enum class Mode : std::uint8_t { Locations, References };\n\n  SchemaFrame(const Mode mode) : mode_{mode} {}\n\n  // We rely on internal caches that would be dangling otherwise\n  SchemaFrame(const SchemaFrame &) = delete;\n  auto operator=(const SchemaFrame &) -> SchemaFrame & = delete;\n  SchemaFrame(SchemaFrame &&) = delete;\n  auto operator=(SchemaFrame &&) -> SchemaFrame & = delete;\n\n  // Query the current mode that the schema frame was configured with\n  [[nodiscard]] auto mode() const noexcept -> Mode { return this->mode_; }\n\n  /// A single entry in a JSON Schema reference map\n  struct ReferencesEntry {\n    std::string_view original;\n    // TODO: This one is tricky to turn into a view, as there is no\n    // location entry to point to if it is an external unresolved reference\n    JSON::String destination;\n    // Empty means no base\n    std::string_view base;\n    std::optional<std::string_view> fragment;\n  };\n\n  /// A JSON Schema reference map is a mapping of a JSON Pointer\n  /// of a subschema to a destination static reference URI.\n  /// For convenience, the value consists of the URI on its entirety,\n  /// but also broken down by its potential fragment component.\n  /// The reference type is part of the key as it is possible to\n  /// have a static and a dynamic reference to the same location\n  /// on the same schema object.\n  using References =\n      std::map<std::pair<SchemaReferenceType, WeakPointer>, ReferencesEntry>;\n\n#if defined(__GNUC__)\n#pragma GCC diagnostic push\n// GCC believes that a member of an enum class (which is namespaced by\n// definition), can shadow an alias defined even on a different namespace.\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n  /// @ingroup jsonschema\n  /// The type of a location frame\n  enum class LocationType : std::uint8_t {\n    Resource,\n    Anchor,\n    // TODO: Distinguish between a Pointer and a Keyword\n    Pointer,\n    Subschema\n  };\n#if defined(__GNUC__)\n#pragma GCC diagnostic pop\n#endif\n\n  /// A location entry\n  struct Location {\n    std::optional<WeakPointer> parent;\n    LocationType type;\n    std::string_view base;\n    WeakPointer pointer;\n    std::size_t relative_pointer;\n    std::string_view dialect;\n    SchemaBaseDialect base_dialect;\n    bool property_name;\n    bool orphan;\n  };\n\n  /// A JSON Schema reference frame is a mapping of URIs to schema identifiers,\n  /// JSON Pointers within the schema, and subschemas dialects. We call it\n  /// reference frame as this mapping is essential for resolving references.\n  // TODO: Consider replacing std::map with std::flat_map once libc++\n  // supports it (__cpp_lib_flat_map) for better cache locality\n  using Locations =\n      // While it might seem weird that we namespace the location URIs with a\n      // reference type, it is essential for distinguishing schema resource URIs\n      // from `$recursiveRef: true` on another place of the schema schema\n      // resource, as otherwise they would both have the exact same URI, but\n      // point to different places.\n      std::map<std::pair<SchemaReferenceType, JSON::String>, Location>;\n\n  /// A list of paths to frame within a schema wrapper\n  using Paths = std::vector<WeakPointer>;\n\n  /// Export the frame entries as JSON\n  [[nodiscard]] auto to_json(\n      const std::optional<PointerPositionTracker> &tracker = std::nullopt) const\n      -> JSON;\n\n  /// Analyse a schema or set of schemas from a given root. Passing\n  /// multiple paths that have any overlap is undefined behaviour\n  auto analyse(const JSON &root, const SchemaWalker &walker,\n               const SchemaResolver &resolver,\n               std::string_view default_dialect = \"\",\n               std::string_view default_id = \"\",\n               const Paths &paths = {empty_weak_pointer}) -> void;\n\n  /// Access the analysed schema locations\n  [[nodiscard]] auto locations() const noexcept -> const Locations &;\n\n  /// Access the analysed schema references\n  [[nodiscard]] auto references() const noexcept -> const References &;\n\n  /// Get a specific reference entry by type and pointer\n  [[nodiscard]] auto reference(const SchemaReferenceType type,\n                               const WeakPointer &pointer) const\n      -> std::optional<std::reference_wrapper<const ReferencesEntry>>;\n\n  /// Check whether the analysed schema has no external references\n  [[nodiscard]] auto standalone() const noexcept -> bool;\n\n  /// Get the root schema identifier (empty if none)\n  [[nodiscard]] auto root() const noexcept -> const JSON::String &;\n\n  /// Get the vocabularies associated with a location entry\n  [[nodiscard]] auto vocabularies(const Location &location,\n                                  const SchemaResolver &resolver) const\n      -> Vocabularies;\n\n  /// Get the URI associated with a location entry\n  [[nodiscard]] auto\n  uri(const Location &location,\n      const WeakPointer &relative_schema_location = empty_weak_pointer) const\n      -> JSON::String;\n\n  /// Get the location associated by traversing a pointer from another location\n  [[nodiscard]] auto traverse(const Location &location,\n                              const WeakPointer &relative_schema_location) const\n      -> const Location &;\n\n  /// Get the location associated with a given URI\n  [[nodiscard]] auto traverse(const std::string_view uri) const\n      -> std::optional<std::reference_wrapper<const Location>>;\n\n  /// Get the location associated with a given pointer\n  [[nodiscard]] auto traverse(const WeakPointer &pointer) const\n      -> std::optional<std::reference_wrapper<const Location>>;\n\n  /// Get the location of a specific type associated with a given pointer\n  [[nodiscard]] auto traverse(const WeakPointer &pointer,\n                              const LocationType type) const\n      -> std::optional<std::reference_wrapper<const Location>>;\n\n  /// Turn an absolute pointer into a location URI\n  [[nodiscard]] auto uri(const WeakPointer &pointer) const\n      -> std::optional<std::reference_wrapper<const JSON::String>>;\n\n  /// Try to dereference a reference location into its destination location\n  [[nodiscard]] auto dereference(\n      const Location &location,\n      const WeakPointer &relative_schema_location = empty_weak_pointer) const\n      -> std::pair<SchemaReferenceType,\n                   std::optional<std::reference_wrapper<const Location>>>;\n\n  /// Iterate over all resource URIs in the frame\n  template <std::invocable<std::string_view> F>\n  auto for_each_resource_uri(const F &callback) const -> void {\n    for (const auto &[key, location] : this->locations_) {\n      if (location.type == LocationType::Resource) {\n        callback(key.second);\n      }\n    }\n  }\n\n  /// Iterate over all unresolved references (where destination cannot be\n  /// traversed)\n  template <std::invocable<const WeakPointer &, const ReferencesEntry &> F>\n  auto for_each_unresolved_reference(const F &callback) const -> void {\n    for (const auto &[key, reference] : this->references_) {\n      if (!this->traverse(reference.destination).has_value()) {\n        callback(key.second, reference);\n      }\n    }\n  }\n\n  /// Check if there are any references to a given location pointer\n  [[nodiscard]] auto has_references_to(const WeakPointer &pointer) const\n      -> bool;\n\n  /// Check if there are any references that go through a given location pointer\n  [[nodiscard]] auto has_references_through(const WeakPointer &pointer) const\n      -> bool;\n  /// Check if there are any references that go through a given location pointer\n  /// with a tail token\n  [[nodiscard]] auto\n  has_references_through(const WeakPointer &pointer,\n                         const WeakPointer::Token &tail) const -> bool;\n\n  /// Get the relative instance location pointer for a given location entry\n  [[nodiscard]] auto relative_instance_location(const Location &location) const\n      -> WeakPointer;\n\n  /// Check if the frame has no analysed data\n  [[nodiscard]] auto empty() const noexcept -> bool;\n\n  /// Reset the frame, clearing all analysed data\n  auto reset() -> void;\n\n  /// Determines if a location could be evaluated during validation\n  [[nodiscard]] auto is_reachable(const Location &base,\n                                  const Location &location,\n                                  const SchemaWalker &walker,\n                                  const SchemaResolver &resolver) const -> bool;\n\nprivate:\n  Mode mode_;\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n  JSON::String root_;\n  Locations locations_;\n  References references_;\n  mutable std::unordered_map<std::reference_wrapper<const WeakPointer>,\n                             std::vector<const Location *>, WeakPointer::Hasher,\n                             WeakPointer::Comparator>\n      pointer_to_location_;\n  mutable std::unordered_set<std::reference_wrapper<const WeakPointer>,\n                             WeakPointer::Hasher, WeakPointer::Comparator>\n      pointers_with_non_orphan_;\n  using ReachabilityCache = std::unordered_map<const WeakPointer *, bool>;\n  struct ReachabilityKey {\n    const WeakPointer *pointer;\n    bool orphan;\n    auto operator==(const ReachabilityKey &other) const noexcept -> bool {\n      return this->pointer == other.pointer && this->orphan == other.orphan;\n    }\n  };\n  struct ReachabilityKeyHasher {\n    auto operator()(const ReachabilityKey &key) const noexcept -> std::size_t {\n      return std::hash<const void *>{}(key.pointer) ^\n             (std::hash<bool>{}(key.orphan) << 1);\n    }\n  };\n  mutable std::unordered_map<ReachabilityKey, ReachabilityCache,\n                             ReachabilityKeyHasher>\n      reachability_;\n  mutable std::unordered_map<std::reference_wrapper<const WeakPointer>,\n                             std::vector<const WeakPointer *>,\n                             WeakPointer::Hasher, WeakPointer::Comparator>\n      references_by_destination_;\n  mutable std::unordered_set<std::reference_wrapper<const WeakPointer>,\n                             WeakPointer::Hasher, WeakPointer::Comparator>\n      location_members_children_;\n  mutable std::unordered_map<std::reference_wrapper<const WeakPointer>,\n                             std::vector<const Location *>, WeakPointer::Hasher,\n                             WeakPointer::Comparator>\n      descendants_by_pointer_;\n  struct PotentialSource {\n    const WeakPointer *source_pointer;\n    WeakPointer source_parent;\n    bool crosses;\n  };\n  mutable std::unordered_map<const Location *, std::vector<PotentialSource>>\n      potential_sources_by_location_;\n  struct ReachabilityEdge {\n    const Location *target;\n    bool orphan_context_only;\n    bool is_reference;\n  };\n  mutable std::unordered_map<const Location *, std::vector<ReachabilityEdge>>\n      reachability_graph_;\n  mutable std::unordered_map<std::reference_wrapper<const WeakPointer>,\n                             const WeakPointer *, WeakPointer::Hasher,\n                             WeakPointer::Comparator>\n      canonical_pointer_;\n  mutable std::unordered_map<const Location *, const WeakPointer *>\n      location_to_canonical_;\n  bool standalone_{false};\n\n  auto populate_pointer_to_location() const -> void;\n  auto populate_reference_graph() const -> void;\n  auto populate_location_members(const SchemaWalker &walker,\n                                 const SchemaResolver &resolver) const -> void;\n  auto populate_descendants() const -> void;\n  auto populate_potential_sources(const SchemaWalker &walker,\n                                  const SchemaResolver &resolver) const -> void;\n  auto populate_reachability_graph(const SchemaWalker &walker,\n                                   const SchemaResolver &resolver) const\n      -> void;\n  auto populate_reachability(const Location &base, const SchemaWalker &walker,\n                             const SchemaResolver &resolver) const\n      -> const ReachabilityCache &;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_types.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_TYPES_H_\n#define SOURCEMETA_CORE_JSONSCHEMA_TYPES_H_\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/jsonschema_vocabularies.h>\n\n#include <cstdint>       // std::uint8_t\n#include <functional>    // std::function, std::reference_wrapper\n#include <optional>      // std::optional\n#include <string>        // std::string\n#include <string_view>   // std::string_view\n#include <unordered_set> // std::unordered_set\n\nnamespace sourcemeta::core {\n\n// Take a URI and get back a schema\n/// @ingroup jsonschema\n///\n/// Some functions need to reference other schemas by their URIs. To accomplish\n/// this in a generic and flexible way, these functions take resolver functions\n/// as arguments, of the type sourcemeta::core::SchemaResolver.\n///\n/// For convenience, we provide the following default resolvers:\n///\n/// - sourcemeta::core::schema_resolver\n///\n/// You can implement resolvers to read from a local storage, to send HTTP\n/// requests, or anything your application might require. Unless your resolver\n/// is trivial, it is recommended to create a callable object that implements\n/// the function interface.\nusing SchemaResolver = std::function<std::optional<JSON>(std::string_view)>;\n\n/// @ingroup jsonschema\n/// The reference type\nenum class SchemaReferenceType : std::uint8_t { Static, Dynamic };\n\n/// @ingroup jsonschema\n/// All the known JSON Schema base dialects\nenum class SchemaBaseDialect : std::uint8_t {\n  JSON_Schema_2020_12,\n  JSON_Schema_2020_12_Hyper,\n  JSON_Schema_2019_09,\n  JSON_Schema_2019_09_Hyper,\n  JSON_Schema_Draft_7,\n  JSON_Schema_Draft_7_Hyper,\n  JSON_Schema_Draft_6,\n  JSON_Schema_Draft_6_Hyper,\n  JSON_Schema_Draft_4,\n  JSON_Schema_Draft_4_Hyper,\n  JSON_Schema_Draft_3,\n  JSON_Schema_Draft_3_Hyper,\n  JSON_Schema_Draft_2_Hyper,\n  JSON_Schema_Draft_1_Hyper,\n  JSON_Schema_Draft_0_Hyper\n};\n\n#if defined(__GNUC__)\n#pragma GCC diagnostic push\n// For some strange reason, GCC on Debian 11 believes that a member of\n// an enum class (which is namespaced by definition), can shadow an\n// alias defined even on a different namespace.\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n/// @ingroup jsonschema\n/// Determines the type of a JSON Schema keyword\nenum class SchemaKeywordType : std::uint8_t {\n  /// The JSON Schema keyword is unknown\n  Unknown,\n  /// The JSON Schema keyword is a non-applicator assertion\n  Assertion,\n  /// The JSON Schema keyword is a non-applicator annotation\n  Annotation,\n  /// The JSON Schema keyword is a reference\n  Reference,\n  /// The JSON Schema keyword is known but doesn't match any other type\n  Other,\n  /// The JSON Schema keyword is considered to be a comment without any\n  /// additional meaning\n  Comment,\n  /// The JSON Schema keyword is a reserved location that potentially\n  /// takes an object as argument, whose values are potentially\n  /// JSON Schema definitions\n  LocationMembers,\n\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an object as argument, whose values are potentially\n  /// JSON Schema definitions.\n  /// The instance traverses based on the members as property names\n  ApplicatorMembersTraversePropertyStatic,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an object as argument, whose values are potentially\n  /// JSON Schema definitions.\n  /// The instance traverses based on the members as property regular\n  /// expressions\n  ApplicatorMembersTraversePropertyRegex,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument\n  /// The instance traverses to some of the properties\n  ApplicatorValueTraverseSomeProperty,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument\n  /// The instance traverses to any property key\n  ApplicatorValueTraverseAnyPropertyKey,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument\n  /// The instance traverses to any item\n  ApplicatorValueTraverseAnyItem,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument\n  /// The instance traverses to some of the items\n  ApplicatorValueTraverseSomeItem,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument\n  /// The instance traverses back to the parent\n  ApplicatorValueTraverseParent,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an array of potentially JSON Schema definitions\n  /// as an argument\n  /// The instance traverses based on the element indexes\n  ApplicatorElementsTraverseItem,\n  /// The JSON Schema keyword is an applicator that may take a JSON Schema\n  /// definition or an array of potentially JSON Schema definitions\n  /// as an argument\n  /// The instance traverses to any item or based on the element indexes\n  ApplicatorValueOrElementsTraverseAnyItemOrItem,\n  /// The JSON Schema keyword is an applicator that may take a JSON Schema\n  /// definition or an array of potentially JSON Schema definitions\n  /// as an argument without affecting the instance location.\n  /// The instance does not traverse\n  ApplicatorValueOrElementsInPlace,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an object as argument, whose values are potentially\n  /// JSON Schema definitions without affecting the instance location.\n  /// The instance does not traverse\n  ApplicatorMembersInPlaceSome,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an array of potentially JSON Schema definitions\n  /// as an argument without affecting the instance location.\n  /// The instance does not traverse\n  ApplicatorElementsInPlace,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an array of potentially JSON Schema definitions\n  /// as an argument without affecting the instance location\n  /// The instance does not traverse, and only some of the\n  /// elements apply.\n  ApplicatorElementsInPlaceSome,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes an array of potentially JSON Schema definitions\n  /// as an argument without affecting the instance location\n  /// The instance does not traverse, and only some of the\n  /// elements apply in negated form.\n  ApplicatorElementsInPlaceSomeNegate,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument without affecting the\n  /// instance location.\n  /// The instance does not traverse, and only applies some of the times.\n  ApplicatorValueInPlaceMaybe,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument but its evaluation follows\n  /// special rules.\n  /// The instance does not traverse\n  ApplicatorValueInPlaceOther,\n  /// The JSON Schema keyword is an applicator that potentially\n  /// takes a JSON Schema definition as an argument but the instance is expected\n  /// to not validate against it.\n  /// The instance does not traverse\n  ApplicatorValueInPlaceNegate,\n};\n#if defined(__GNUC__)\n#pragma GCC diagnostic pop\n#endif\n\n/// @ingroup jsonschema\n/// A structure that encapsulates the result of walker over a specific keyword\nstruct SchemaWalkerResult {\n  /// The walker strategy to continue traversing across the schema\n  SchemaKeywordType type;\n  /// The vocabulary associated with the keyword, if any\n  std::optional<Vocabularies::URI> vocabulary;\n  /// The keywords a given keyword depends on (if any) during the evaluation\n  /// process\n  std::unordered_set<std::string_view> dependencies;\n  /// The keywords a given keyword depends on for evaluation ordering purposes\n  /// only (not semantic dependencies)\n  std::unordered_set<std::string_view> order_dependencies;\n  /// The JSON instance types that this keyword applies to (empty means all)\n  JSON::TypeSet instances;\n\n  // Prevent accidental copies, as walker results are always returned by\n  // reference\n  SchemaWalkerResult(const SchemaWalkerResult &) = delete;\n  auto operator=(const SchemaWalkerResult &) -> SchemaWalkerResult & = delete;\n  SchemaWalkerResult(SchemaWalkerResult &&) = default;\n  auto operator=(SchemaWalkerResult &&) -> SchemaWalkerResult & = default;\n  ~SchemaWalkerResult() = default;\n\n  SchemaWalkerResult(SchemaKeywordType type_,\n                     std::optional<Vocabularies::URI> vocabulary_,\n                     std::unordered_set<std::string_view> dependencies_,\n                     std::unordered_set<std::string_view> order_dependencies_,\n                     JSON::TypeSet instances_)\n      : type{type_}, vocabulary{std::move(vocabulary_)},\n        dependencies{std::move(dependencies_)},\n        order_dependencies{std::move(order_dependencies_)},\n        instances{instances_} {}\n};\n\n/// @ingroup jsonschema\n///\n/// For walking purposes, some functions need to understand which JSON Schema\n/// keywords declare other JSON Schema definitions. To accomplish this in a\n/// generic and flexible way that does not assume the use any vocabulary other\n/// than `core`, these functions take a walker function as argument.\nusing SchemaWalker = std::function<const SchemaWalkerResult &(\n    std::string_view, const Vocabularies &)>;\n\n/// @ingroup jsonschema\n/// An entry of a schema iterator.\nstruct SchemaIteratorEntry {\n  std::optional<WeakPointer> parent;\n  WeakPointer pointer;\n  // TODO: Use \"known\" enum classes + strings for dialects\n  std::string_view dialect;\n  Vocabularies vocabularies;\n  std::optional<SchemaBaseDialect> base_dialect;\n  std::reference_wrapper<const JSON> subschema;\n  bool orphan;\n  bool property_name;\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_vocabularies.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_VOCABULARIES_H_\n#define SOURCEMETA_CORE_JSONSCHEMA_VOCABULARIES_H_\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <bitset>  // std::bitset\n#include <cassert> // assert\n#include <cstdint> // std::uint32_t, std::size_t\n#include <format> // std::formatter, std::format_context, std::format_parse_context, std::format_to\n#include <optional>      // std::optional\n#include <ostream>       // std::ostream\n#include <sstream>       // std::ostringstream\n#include <stdexcept>     // std::out_of_range\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::pair\n#include <variant>       // std::variant\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonschema\n/// Optimized vocabulary set using bitflags for known vocabularies\n/// and a fallback `std::unordered_map` for custom vocabularies.\nstruct SOURCEMETA_CORE_JSONSCHEMA_EXPORT Vocabularies {\n  enum class Known : std::uint8_t {\n    // Pre-vocabulary dialects (treated as vocabularies)\n    JSON_Schema_Draft_0 = 0,\n    JSON_Schema_Draft_0_Hyper = 1,\n    JSON_Schema_Draft_1 = 2,\n    JSON_Schema_Draft_1_Hyper = 3,\n    JSON_Schema_Draft_2 = 4,\n    JSON_Schema_Draft_2_Hyper = 5,\n    JSON_Schema_Draft_3 = 6,\n    JSON_Schema_Draft_3_Hyper = 7,\n    JSON_Schema_Draft_4 = 8,\n    JSON_Schema_Draft_4_Hyper = 9,\n    JSON_Schema_Draft_6 = 10,\n    JSON_Schema_Draft_6_Hyper = 11,\n    JSON_Schema_Draft_7 = 12,\n    JSON_Schema_Draft_7_Hyper = 13,\n    // 2019-09 vocabularies\n    JSON_Schema_2019_09_Core = 14,\n    JSON_Schema_2019_09_Applicator = 15,\n    JSON_Schema_2019_09_Validation = 16,\n    JSON_Schema_2019_09_Meta_Data = 17,\n    JSON_Schema_2019_09_Format = 18,\n    JSON_Schema_2019_09_Content = 19,\n    JSON_Schema_2019_09_Hyper_Schema = 20,\n    // 2020-12 vocabularies\n    JSON_Schema_2020_12_Core = 21,\n    JSON_Schema_2020_12_Applicator = 22,\n    JSON_Schema_2020_12_Unevaluated = 23,\n    JSON_Schema_2020_12_Validation = 24,\n    JSON_Schema_2020_12_Meta_Data = 25,\n    JSON_Schema_2020_12_Format_Annotation = 26,\n    JSON_Schema_2020_12_Format_Assertion = 27,\n    JSON_Schema_2020_12_Content = 28,\n    // OpenAPI\n    // https://spec.openapis.org/oas/v3.1.0.html#fixed-fields-19\n    OpenAPI_3_1_Base = 29,\n    // https://spec.openapis.org/oas/v3.2.0.html#base-vocabulary\n    OpenAPI_3_2_Base = 30\n  };\n\n  // NOTE: Must be kept in sync with the Known enum above\n  static constexpr std::size_t KNOWN_VOCABULARY_COUNT = 31;\n\n  /// A vocabulary URI type that can be either a known vocabulary enum or a\n  /// custom string URI\n  using URI = std::variant<Known, JSON::String>;\n\npublic:\n  Vocabularies() = default;\n  Vocabularies(const Vocabularies &) = default;\n  Vocabularies(Vocabularies &&) noexcept = default;\n  auto operator=(const Vocabularies &) -> Vocabularies & = default;\n  auto operator=(Vocabularies &&) noexcept -> Vocabularies & = default;\n  ~Vocabularies() = default;\n\n  /// Construct from initializer list\n  Vocabularies(std::initializer_list<std::pair<JSON::String, bool>> init);\n\n  /// Construct from initializer list using known vocabulary enums\n  Vocabularies(std::initializer_list<std::pair<Known, bool>> init);\n\n  /// Check if a vocabulary is enabled\n  [[nodiscard]] auto contains(const JSON::String &uri) const noexcept -> bool;\n\n  /// Check if a known vocabulary is enabled\n  [[nodiscard]] auto contains(Known vocabulary) const noexcept -> bool;\n\n  /// Check if any of the given known vocabularies are enabled\n  [[nodiscard]] auto\n  contains_any(std::initializer_list<Known> vocabularies) const noexcept\n      -> bool;\n\n  /// Insert a vocabulary with its required/optional status\n  auto insert(const JSON::String &uri, bool required) noexcept -> void;\n\n  /// Insert a known vocabulary with its required/optional status\n  auto insert(Known vocabulary, bool required) noexcept -> void;\n\n  /// Get vocabulary status by URI\n  [[nodiscard]] auto get(const JSON::String &uri) const noexcept\n      -> std::optional<bool>;\n\n  /// Get known vocabulary status\n  [[nodiscard]] auto get(Known vocabulary) const noexcept\n      -> std::optional<bool>;\n\n  /// Get the number of vocabularies (required + optional + custom)\n  [[nodiscard]] auto size() const noexcept -> std::size_t;\n\n  /// Check if there are no vocabularies\n  [[nodiscard]] auto empty() const noexcept -> bool;\n\n  /// Check if there are any unknown vocabularies\n  [[nodiscard]] auto has_unknown() const noexcept -> bool;\n\n  /// Throw if the current vocabularies have required ones outside the given\n  /// supported set\n  auto throw_if_any_unsupported(const std::unordered_set<URI> &supported,\n                                const char *message) const -> void;\n\n  /// Throw if any unknown vocabulary is required\n  auto throw_if_any_unknown_required(const char *message) const -> void;\n\nprivate:\n  // Invariant: required_known and optional_known must be mutually exclusive\n  // A vocabulary can be either required (true) OR optional (false), never both\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif\n  std::bitset<KNOWN_VOCABULARY_COUNT> required_known{};\n  std::bitset<KNOWN_VOCABULARY_COUNT> optional_known{};\n  // Lazily initialized only when unknown (non-official) vocabularies are used\n  std::optional<std::unordered_map<JSON::String, bool>> unknown{std::nullopt};\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n};\n\n/// Convert a known vocabulary enum to its URI string\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT auto\noperator<<(std::ostream &stream, Vocabularies::Known vocabulary)\n    -> std::ostream &;\n\n/// Convert a vocabulary URI to its string representation\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT auto\noperator<<(std::ostream &stream, const Vocabularies::URI &vocabulary)\n    -> std::ostream &;\n\n/// Stringify a known vocabulary to a string\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT auto to_string(Vocabularies::Known vocabulary)\n    -> std::string_view;\n\n/// Stringify a vocabulary URI to a string\nSOURCEMETA_CORE_JSONSCHEMA_EXPORT auto\nto_string(const Vocabularies::URI &vocabulary) -> std::string_view;\n\n} // namespace sourcemeta::core\n\ntemplate <> struct std::formatter<sourcemeta::core::Vocabularies::Known> {\n  constexpr auto parse(std::format_parse_context &context)\n      -> decltype(context.begin()) {\n    return context.begin();\n  }\n\n  auto format(const sourcemeta::core::Vocabularies::Known value,\n              std::format_context &context) const -> decltype(context.out()) {\n    std::ostringstream stream;\n    stream << value;\n    return std::format_to(context.out(), \"{}\", stream.str());\n  }\n};\n\ntemplate <> struct std::formatter<sourcemeta::core::Vocabularies::URI> {\n  constexpr auto parse(std::format_parse_context &context)\n      -> decltype(context.begin()) {\n    return context.begin();\n  }\n\n  auto format(const sourcemeta::core::Vocabularies::URI &value,\n              std::format_context &context) const -> decltype(context.out()) {\n    std::ostringstream stream;\n    stream << value;\n    return std::format_to(context.out(), \"{}\", stream.str());\n  }\n};\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/include/sourcemeta/core/jsonschema_walker.h",
    "content": "#ifndef SOURCEMETA_CORE_JSONSCHEMA_WALKER_H_\n#define SOURCEMETA_CORE_JSONSCHEMA_WALKER_H_\n\n#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT\n#include <sourcemeta/core/jsonschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n#include <sourcemeta/core/jsonschema_types.h>\n\n#include <cstdint>     // std::uint64_t\n#include <optional>    // std::optional\n#include <string_view> // std::string_view\n#include <vector>      // std::vector\n\nnamespace sourcemeta::core {\n\n/// @ingroup jsonschema\n///\n/// Return an iterator over the subschemas of a given JSON Schema definition\n/// according to the applicators understood by the provided walker function.\n/// This walker recursively traverses over every subschema of\n/// the JSON Schema definition, including the top-level schema, reporting back\n/// each subschema.\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\",\n///   \"properties\": {\n///     \"foo\": {\n///       \"type\": \"array\",\n///       \"items\": {\n///         \"type\": \"string\"\n///       }\n///     }\n///   }\n/// })JSON\");\n///\n/// for (const auto &entry :\n///          sourcemeta::core::SchemaIterator{\n///          document, sourcemeta::core::schema_walker,\n///          sourcemeta::core::schema_resolver}) {\n///   sourcemeta::core::prettify(\n///     sourcemeta::core::get(document, entry.pointer), std::cout);\n///   std::cout << \"\\n\";\n/// }\n/// ```\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaIterator {\nprivate:\n  using internal = typename std::vector<SchemaIteratorEntry>;\n\npublic:\n  using const_iterator = typename internal::const_iterator;\n  SchemaIterator(const JSON &input, const SchemaWalker &walker,\n                 const SchemaResolver &resolver,\n                 std::string_view default_dialect = \"\");\n  [[nodiscard]] auto begin() const -> const_iterator;\n  [[nodiscard]] auto end() const -> const_iterator;\n  [[nodiscard]] auto cbegin() const -> const_iterator;\n  [[nodiscard]] auto cend() const -> const_iterator;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  internal subschemas{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n/// @ingroup jsonschema\n///\n/// Return an iterator over the subschemas of a given JSON Schema definition\n/// according to the applicators understood by the provided walker function.\n/// This walker traverse over the first-level of subschemas of the JSON Schema\n/// definition, ignoring the top-level schema and reporting back each subschema.\n///\n/// Note that we don't promise any specific walking ordering.\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\",\n///   \"properties\": {\n///     \"foo\": {\n///       \"type\": \"array\",\n///       \"items\": {\n///         \"type\": \"string\"\n///       }\n///     }\n///   }\n/// })JSON\");\n///\n/// for (const auto &entry :\n///          sourcemeta::core::SchemaIteratorFlat{\n///          document, sourcemeta::core::schema_walker,\n///          sourcemeta::core::schema_resolver}) {\n///   sourcemeta::core::prettify(\n///     sourcemeta::core::get(document, entry.pointer), std::cout);\n///   std::cout << \"\\n\";\n/// }\n/// ```\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaIteratorFlat {\nprivate:\n  using internal = typename std::vector<SchemaIteratorEntry>;\n\npublic:\n  using const_iterator = typename internal::const_iterator;\n  SchemaIteratorFlat(const JSON &input, const SchemaWalker &walker,\n                     const SchemaResolver &resolver,\n                     std::string_view default_dialect = \"\");\n  [[nodiscard]] auto begin() const -> const_iterator;\n  [[nodiscard]] auto end() const -> const_iterator;\n  [[nodiscard]] auto cbegin() const -> const_iterator;\n  [[nodiscard]] auto cend() const -> const_iterator;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  internal subschemas{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n/// @ingroup jsonschema\n///\n/// Return an iterator over the top-level keywords of a given JSON Schema\n/// definition in the order in which an implementation must evaluate them.\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"type\": \"object\",\n///   \"properties\": {},\n///   \"additionalProperties\": true,\n///   \"patternProperties\": {}\n/// })JSON\");\n///\n/// for (const auto &entry :\n///          sourcemeta::core::SchemaKeywordIterator{\n///          document, sourcemeta::core::schema_walker,\n///          sourcemeta::core::schema_resolver}) {\n///   sourcemeta::core::stringify(entry.pointer, std::cout);\n///   std::cout << \"\\n\";\n/// }\n/// ```\nclass SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaKeywordIterator {\nprivate:\n  using internal = typename std::vector<SchemaIteratorEntry>;\n\npublic:\n  using const_iterator = typename internal::const_iterator;\n  SchemaKeywordIterator(const JSON &input, const SchemaWalker &walker,\n                        const SchemaResolver &resolver,\n                        std::string_view default_dialect = \"\");\n  [[nodiscard]] auto begin() const -> const_iterator;\n  [[nodiscard]] auto end() const -> const_iterator;\n  [[nodiscard]] auto cbegin() const -> const_iterator;\n  [[nodiscard]] auto cend() const -> const_iterator;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  internal entries{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/jsonschema.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include \"helpers.h\"\n\n#include <algorithm>     // std::max, std::ranges::fold_left\n#include <cassert>       // assert\n#include <cstdint>       // std::uint64_t\n#include <limits>        // std::numeric_limits\n#include <sstream>       // std::ostringstream\n#include <string_view>   // std::string_view\n#include <type_traits>   // std::remove_reference_t\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::move, std::to_underlying\n\nauto sourcemeta::core::is_schema(const sourcemeta::core::JSON &schema) -> bool {\n  return schema.is_object() || schema.is_boolean();\n}\n\n// TODO: Make this function detect schemas only using identifier/comment\n// keywords, etc\nauto sourcemeta::core::is_empty_schema(const sourcemeta::core::JSON &schema)\n    -> bool {\n  return (schema.is_boolean() && schema.to_boolean()) ||\n         (schema.is_object() && schema.empty());\n}\n\nauto sourcemeta::core::to_string(const SchemaBaseDialect base_dialect)\n    -> std::string_view {\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_2020_12:\n      return \"https://json-schema.org/draft/2020-12/schema\";\n    case SchemaBaseDialect::JSON_Schema_2020_12_Hyper:\n      return \"https://json-schema.org/draft/2020-12/hyper-schema\";\n    case SchemaBaseDialect::JSON_Schema_2019_09:\n      return \"https://json-schema.org/draft/2019-09/schema\";\n    case SchemaBaseDialect::JSON_Schema_2019_09_Hyper:\n      return \"https://json-schema.org/draft/2019-09/hyper-schema\";\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n      return \"http://json-schema.org/draft-07/schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n      return \"http://json-schema.org/draft-07/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n      return \"http://json-schema.org/draft-06/schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n      return \"http://json-schema.org/draft-06/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n      return \"http://json-schema.org/draft-04/schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n      return \"http://json-schema.org/draft-04/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n      return \"http://json-schema.org/draft-03/schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n      return \"http://json-schema.org/draft-03/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_2_Hyper:\n      return \"http://json-schema.org/draft-02/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_1_Hyper:\n      return \"http://json-schema.org/draft-01/hyper-schema#\";\n    case SchemaBaseDialect::JSON_Schema_Draft_0_Hyper:\n      return \"http://json-schema.org/draft-00/hyper-schema#\";\n  }\n\n  assert(false);\n  return {};\n}\n\nauto sourcemeta::core::to_base_dialect(const std::string_view base_dialect)\n    -> std::optional<SchemaBaseDialect> {\n  if (base_dialect == \"https://json-schema.org/draft/2020-12/schema\" ||\n      base_dialect == \"http://json-schema.org/draft/2020-12/schema\") {\n    return SchemaBaseDialect::JSON_Schema_2020_12;\n  } else if (base_dialect ==\n                 \"https://json-schema.org/draft/2020-12/hyper-schema\" ||\n             base_dialect ==\n                 \"http://json-schema.org/draft/2020-12/hyper-schema\") {\n    return SchemaBaseDialect::JSON_Schema_2020_12_Hyper;\n  } else if (base_dialect == \"https://json-schema.org/draft/2019-09/schema\" ||\n             base_dialect == \"http://json-schema.org/draft/2019-09/schema\") {\n    return SchemaBaseDialect::JSON_Schema_2019_09;\n  } else if (base_dialect ==\n                 \"https://json-schema.org/draft/2019-09/hyper-schema\" ||\n             base_dialect ==\n                 \"http://json-schema.org/draft/2019-09/hyper-schema\") {\n    return SchemaBaseDialect::JSON_Schema_2019_09_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-07/schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-07/schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_7;\n  } else if (base_dialect == \"http://json-schema.org/draft-07/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-07/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_7_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-06/schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-06/schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_6;\n  } else if (base_dialect == \"http://json-schema.org/draft-06/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-06/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_6_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-04/schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-04/schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_4;\n  } else if (base_dialect == \"http://json-schema.org/draft-04/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-04/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_4_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-03/schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-03/schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_3;\n  } else if (base_dialect == \"http://json-schema.org/draft-03/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-03/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_3_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-02/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-02/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_2_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-01/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-01/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_1_Hyper;\n  } else if (base_dialect == \"http://json-schema.org/draft-00/hyper-schema#\" ||\n             base_dialect == \"https://json-schema.org/draft-00/hyper-schema#\") {\n    return SchemaBaseDialect::JSON_Schema_Draft_0_Hyper;\n  }\n\n  return std::nullopt;\n}\n\nauto sourcemeta::core::identify(const sourcemeta::core::JSON &schema,\n                                const SchemaResolver &resolver,\n                                std::string_view default_dialect,\n                                std::string_view default_id,\n                                const bool allow_dialect_override)\n    -> std::string_view {\n  try {\n    const auto maybe_base_dialect{sourcemeta::core::base_dialect(\n        schema, resolver, default_dialect, allow_dialect_override)};\n    if (maybe_base_dialect.has_value()) {\n      return identify(schema, maybe_base_dialect.value(), default_id);\n    }\n    return default_id;\n  } catch (const SchemaResolutionError &) {\n    if (!default_id.empty()) {\n      return default_id;\n    }\n    throw;\n  }\n}\n\nauto sourcemeta::core::identify(const JSON &schema,\n                                const SchemaBaseDialect base_dialect,\n                                std::string_view default_id)\n    -> std::string_view {\n  if (!schema.is_object()) {\n    return default_id;\n  }\n\n  const std::string keyword{sourcemeta::core::id_keyword(base_dialect)};\n\n  if (!schema.defines(keyword)) {\n    return default_id;\n  }\n\n  const auto &identifier{schema.at(keyword)};\n  if (!identifier.is_string()) {\n    std::ostringstream value;\n    sourcemeta::core::stringify(identifier, value);\n    throw sourcemeta::core::SchemaKeywordError(\n        keyword, value.str(), \"The schema identifier is invalid\");\n  }\n\n  // In older drafts, the presence of `$ref` would override any sibling\n  // keywords. Note that `$ref` was first introduced in Draft 3, so we\n  // don't check for base dialects lower than that.\n  // See\n  // https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.8.3\n  if (schema.defines(\"$ref\") &&\n      (base_dialect == SchemaBaseDialect::JSON_Schema_Draft_7 ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_7_Hyper ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_6 ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_6_Hyper ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_4 ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_4_Hyper ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_3 ||\n       base_dialect == SchemaBaseDialect::JSON_Schema_Draft_3_Hyper)) {\n    return default_id;\n  }\n\n  // An empty string identifier and an identifier consisting solely of the\n  // empty-fragment marker \"#\" are both valid URI-references that resolve to\n  // the parent base, carrying no information. We treat them as if no\n  // identifier was declared at all (i.e. no new schema resource is\n  // introduced).\n  // See\n  // https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.2\n  // See\n  // https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-8.2.1-5\n  if (identifier.to_string().empty() || identifier.to_string() == \"#\") {\n    return default_id;\n  }\n\n  return identifier.to_string();\n}\n\nauto sourcemeta::core::anonymize(JSON &schema,\n                                 const SchemaBaseDialect base_dialect) -> void {\n  if (schema.is_object()) {\n    schema.erase(sourcemeta::core::id_keyword(base_dialect));\n  }\n}\n\nauto sourcemeta::core::reidentify(JSON &schema, std::string_view new_identifier,\n                                  const SchemaResolver &resolver,\n                                  std::string_view default_dialect) -> void {\n  const auto resolved_base_dialect{\n      sourcemeta::core::base_dialect(schema, resolver, default_dialect)};\n  if (!resolved_base_dialect.has_value()) {\n    throw sourcemeta::core::SchemaUnknownBaseDialectError();\n  }\n\n  reidentify(schema, new_identifier, resolved_base_dialect.value());\n}\n\nauto sourcemeta::core::reidentify(JSON &schema, std::string_view new_identifier,\n                                  const SchemaBaseDialect base_dialect)\n    -> void {\n  assert(is_schema(schema));\n  assert(schema.is_object());\n  schema.assign(sourcemeta::core::id_keyword(base_dialect),\n                JSON{new_identifier});\n\n  // If we reidentify, and the identifier is still not retrievable, then\n  // we are facing the Draft 7 `$ref` sibling edge case, and we cannot\n  // really continue\n  if (schema.defines(\"$ref\") && identify(schema, base_dialect).empty()) {\n    throw SchemaReferenceObjectResourceError(new_identifier);\n  }\n}\n\nauto sourcemeta::core::dialect(const sourcemeta::core::JSON &schema,\n                               std::string_view default_dialect,\n                               const bool allow_dialect_override)\n    -> std::string_view {\n  assert(sourcemeta::core::is_schema(schema));\n\n  if (allow_dialect_override && schema.is_object()) {\n    const auto *override_value{\n        schema.try_at(\"x-sourcemeta-dialect-override-subschema\")};\n    if (override_value && override_value->is_string() &&\n        !override_value->to_string().empty()) {\n      return override_value->to_string();\n    }\n  }\n\n  if (schema.is_boolean() || !schema.defines(\"$schema\")) {\n    return default_dialect;\n  }\n\n  const auto &dialect_value{schema.at(\"$schema\")};\n  if (!dialect_value.is_string()) {\n    std::ostringstream value;\n    sourcemeta::core::stringify(dialect_value, value);\n    throw sourcemeta::core::SchemaKeywordError(\"$schema\", value.str(),\n                                               \"The dialect value is invalid\");\n  }\n\n  return dialect_value.to_string();\n}\n\nauto sourcemeta::core::metaschema(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect) -> JSON {\n  const auto effective_dialect{\n      sourcemeta::core::dialect(schema, default_dialect)};\n  if (effective_dialect.empty()) {\n    throw sourcemeta::core::SchemaUnknownDialectError();\n  }\n\n  const auto maybe_metaschema{resolver(effective_dialect)};\n  if (!maybe_metaschema.has_value()) {\n    // Relative meta-schema references are invalid according to the\n    // JSON Schema specifications. They must be absolute ones\n    const URI effective_dialect_uri{effective_dialect};\n    if (effective_dialect_uri.is_relative()) {\n      throw sourcemeta::core::SchemaRelativeMetaschemaResolutionError(\n          effective_dialect);\n    } else {\n      throw sourcemeta::core::SchemaResolutionError(\n          effective_dialect, \"Could not resolve the metaschema of the schema\");\n    }\n  }\n\n  return maybe_metaschema.value();\n}\n\nstatic auto\nbase_dialect_with_visited(const sourcemeta::core::JSON &schema,\n                          const sourcemeta::core::SchemaResolver &resolver,\n                          std::string_view default_dialect,\n                          std::unordered_set<std::string_view> &visited,\n                          const bool allow_dialect_override)\n    -> std::optional<sourcemeta::core::SchemaBaseDialect> {\n  assert(sourcemeta::core::is_schema(schema));\n  const std::string_view effective_dialect{sourcemeta::core::dialect(\n      schema, default_dialect, allow_dialect_override)};\n\n  // There is no metaschema information whatsoever\n  // Nothing we can do at this point\n  if (effective_dialect.empty()) {\n    return std::nullopt;\n  }\n\n  // Check for known base dialects\n  const auto result{sourcemeta::core::to_base_dialect(effective_dialect)};\n  if (result.has_value()) {\n    return result;\n  }\n\n  // Detect cycles in the metaschema chain\n  if (!visited.emplace(effective_dialect).second) {\n    throw sourcemeta::core::SchemaUnknownBaseDialectError();\n  }\n\n  // Otherwise, traverse the metaschema hierarchy up\n  const std::optional<sourcemeta::core::JSON> metaschema{\n      resolver(effective_dialect)};\n  if (!metaschema.has_value()) {\n    sourcemeta::core::URI effective_dialect_uri;\n    try {\n      effective_dialect_uri = sourcemeta::core::URI{effective_dialect};\n    } catch (const sourcemeta::core::URIParseError &) {\n      throw sourcemeta::core::SchemaKeywordError(\n          \"$schema\", effective_dialect, \"The dialect is not a valid URI\");\n    }\n\n    // Relative meta-schema references are invalid according to the\n    // JSON Schema specifications. They must be absolute ones\n    if (effective_dialect_uri.is_relative()) {\n      throw sourcemeta::core::SchemaRelativeMetaschemaResolutionError(\n          effective_dialect);\n    } else {\n      throw sourcemeta::core::SchemaResolutionError(\n          effective_dialect, \"Could not resolve the metaschema of the schema\");\n    }\n  }\n\n  // If the metaschema declares the same dialect (self-descriptive), and it's\n  // not an official dialect, we cannot determine the base dialect\n  const std::string_view metaschema_dialect{sourcemeta::core::dialect(\n      metaschema.value(), effective_dialect, allow_dialect_override)};\n  if (metaschema_dialect == effective_dialect) {\n    throw sourcemeta::core::SchemaUnknownBaseDialectError();\n  }\n\n  return base_dialect_with_visited(metaschema.value(), resolver,\n                                   effective_dialect, visited,\n                                   allow_dialect_override);\n}\n\nauto sourcemeta::core::base_dialect(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect, const bool allow_dialect_override)\n    -> std::optional<SchemaBaseDialect> {\n  std::unordered_set<std::string_view> visited;\n  return base_dialect_with_visited(schema, resolver, default_dialect, visited,\n                                   allow_dialect_override);\n}\n\nnamespace {\nauto core_vocabulary_known(\n    const sourcemeta::core::SchemaBaseDialect base_dialect)\n    -> sourcemeta::core::Vocabularies::Known {\n  using sourcemeta::core::SchemaBaseDialect;\n  using sourcemeta::core::Vocabularies;\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_2020_12:\n    case SchemaBaseDialect::JSON_Schema_2020_12_Hyper:\n      return Vocabularies::Known::JSON_Schema_2020_12_Core;\n    case SchemaBaseDialect::JSON_Schema_2019_09:\n    case SchemaBaseDialect::JSON_Schema_2019_09_Hyper:\n      return Vocabularies::Known::JSON_Schema_2019_09_Core;\n    default:\n      assert(false);\n      return Vocabularies::Known::JSON_Schema_2020_12_Core;\n  }\n}\n\nauto dialect_to_known(const std::string_view dialect)\n    -> std::optional<sourcemeta::core::Vocabularies::Known> {\n  using sourcemeta::core::Vocabularies;\n  if (dialect == \"http://json-schema.org/draft-07/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_7;\n  }\n  if (dialect == \"http://json-schema.org/draft-07/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_7_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-06/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_6;\n  }\n  if (dialect == \"http://json-schema.org/draft-06/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_6_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-04/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_4;\n  }\n  if (dialect == \"http://json-schema.org/draft-04/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_4_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-03/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_3;\n  }\n  if (dialect == \"http://json-schema.org/draft-03/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_3_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-02/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_2;\n  }\n  if (dialect == \"http://json-schema.org/draft-02/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_2_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-01/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_1;\n  }\n  if (dialect == \"http://json-schema.org/draft-01/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_1_Hyper;\n  }\n  if (dialect == \"http://json-schema.org/draft-00/schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_0;\n  }\n  if (dialect == \"http://json-schema.org/draft-00/hyper-schema#\") {\n    return Vocabularies::Known::JSON_Schema_Draft_0_Hyper;\n  }\n  return std::nullopt;\n}\n\nauto base_dialect_to_known(const sourcemeta::core::SchemaBaseDialect dialect)\n    -> sourcemeta::core::Vocabularies::Known {\n  using sourcemeta::core::SchemaBaseDialect;\n  using sourcemeta::core::Vocabularies;\n  switch (dialect) {\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n      return Vocabularies::Known::JSON_Schema_Draft_7;\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_7_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n      return Vocabularies::Known::JSON_Schema_Draft_6;\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_6_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n      return Vocabularies::Known::JSON_Schema_Draft_4;\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_4_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n      return Vocabularies::Known::JSON_Schema_Draft_3;\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_3_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_2_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_2_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_1_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_1_Hyper;\n    case SchemaBaseDialect::JSON_Schema_Draft_0_Hyper:\n      return Vocabularies::Known::JSON_Schema_Draft_0_Hyper;\n    default:\n      assert(false);\n      return Vocabularies::Known::JSON_Schema_Draft_7;\n  }\n}\n\nauto is_pre_vocabulary_base_dialect(\n    const sourcemeta::core::SchemaBaseDialect base_dialect) -> bool {\n  using sourcemeta::core::SchemaBaseDialect;\n  switch (base_dialect) {\n    case SchemaBaseDialect::JSON_Schema_Draft_7:\n    case SchemaBaseDialect::JSON_Schema_Draft_7_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_6:\n    case SchemaBaseDialect::JSON_Schema_Draft_6_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_4:\n    case SchemaBaseDialect::JSON_Schema_Draft_4_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_3:\n    case SchemaBaseDialect::JSON_Schema_Draft_3_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_2_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_1_Hyper:\n    case SchemaBaseDialect::JSON_Schema_Draft_0_Hyper:\n      return true;\n    default:\n      return false;\n  }\n}\n} // namespace\n\nauto sourcemeta::core::parse_vocabularies(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaBaseDialect base_dialect)\n    -> std::optional<sourcemeta::core::Vocabularies> {\n  if (base_dialect !=\n          sourcemeta::core::SchemaBaseDialect::JSON_Schema_2020_12 &&\n      base_dialect !=\n          sourcemeta::core::SchemaBaseDialect::JSON_Schema_2020_12_Hyper &&\n      base_dialect !=\n          sourcemeta::core::SchemaBaseDialect::JSON_Schema_2019_09 &&\n      base_dialect !=\n          sourcemeta::core::SchemaBaseDialect::JSON_Schema_2019_09_Hyper) {\n    return std::nullopt;\n  }\n\n  if (!schema.is_object()) {\n    return std::nullopt;\n  }\n\n  const auto *vocabulary_entry{schema.try_at(\"$vocabulary\")};\n  if (!vocabulary_entry) {\n    return std::nullopt;\n  }\n\n  assert(vocabulary_entry->is_object());\n  sourcemeta::core::Vocabularies result;\n  for (const auto &entry : vocabulary_entry->as_object()) {\n    assert(entry.second.is_boolean());\n    result.insert(entry.first, entry.second.to_boolean());\n  }\n\n  return result;\n}\n\nauto sourcemeta::core::parse_vocabularies(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect)\n    -> std::optional<sourcemeta::core::Vocabularies> {\n  const auto schema_base_dialect{\n      sourcemeta::core::base_dialect(schema, resolver, default_dialect)};\n  if (schema_base_dialect.has_value()) {\n    return sourcemeta::core::parse_vocabularies(schema,\n                                                schema_base_dialect.value());\n  } else {\n    return std::nullopt;\n  }\n}\n\nauto sourcemeta::core::vocabularies(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect) -> sourcemeta::core::Vocabularies {\n  const auto resolved_base_dialect{\n      sourcemeta::core::base_dialect(schema, resolver, default_dialect)};\n  if (!resolved_base_dialect.has_value()) {\n    throw sourcemeta::core::SchemaUnknownBaseDialectError();\n  }\n\n  const std::string_view resolved_dialect{\n      sourcemeta::core::dialect(schema, default_dialect)};\n  if (resolved_dialect.empty()) {\n    // If the schema has no declared metaschema and the user didn't\n    // provide a explicit default, then we cannot do anything.\n    // Better to abort instead of trying to guess.\n    throw sourcemeta::core::SchemaUnknownDialectError();\n  }\n\n  return vocabularies(resolver, resolved_base_dialect.value(),\n                      resolved_dialect);\n}\n\nauto sourcemeta::core::vocabularies(const SchemaResolver &resolver,\n                                    const SchemaBaseDialect base_dialect,\n                                    std::string_view dialect)\n    -> sourcemeta::core::Vocabularies {\n  const auto base_dialect_string{to_string(base_dialect)};\n  // As a performance optimization shortcut\n  if (base_dialect_string == dialect ||\n      to_base_dialect(dialect) == base_dialect) {\n    if (base_dialect == SchemaBaseDialect::JSON_Schema_2020_12) {\n      return Vocabularies{\n          {Vocabularies::Known::JSON_Schema_2020_12_Core, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Applicator, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Validation, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Format_Annotation, true},\n          {Vocabularies::Known::JSON_Schema_2020_12_Content, true}};\n    } else if (base_dialect == SchemaBaseDialect::JSON_Schema_2019_09) {\n      return Vocabularies{\n          {Vocabularies::Known::JSON_Schema_2019_09_Core, true},\n          {Vocabularies::Known::JSON_Schema_2019_09_Applicator, true},\n          {Vocabularies::Known::JSON_Schema_2019_09_Validation, true},\n          {Vocabularies::Known::JSON_Schema_2019_09_Meta_Data, true},\n          {Vocabularies::Known::JSON_Schema_2019_09_Format, false},\n          {Vocabularies::Known::JSON_Schema_2019_09_Content, true}};\n    }\n  }\n\n  /*\n   * (1) If the dialect is pre-vocabularies, then the\n   * dialect itself is conceptually the only vocabulary\n   */\n\n  // This is an exhaustive list of all official dialects in the pre-vocabulary\n  // world\n  if (dialect == \"http://json-schema.org/draft-07/schema#\" ||\n      dialect == \"http://json-schema.org/draft-06/schema#\" ||\n      dialect == \"http://json-schema.org/draft-04/schema#\" ||\n      dialect == \"http://json-schema.org/draft-03/schema#\" ||\n      dialect == \"http://json-schema.org/draft-02/schema#\" ||\n      dialect == \"http://json-schema.org/draft-01/schema#\" ||\n      dialect == \"http://json-schema.org/draft-00/schema#\") {\n    const auto known = dialect_to_known(dialect);\n    if (known.has_value()) {\n      return Vocabularies{{known.value(), true}};\n    }\n    return Vocabularies{{std::string{dialect}, true}};\n  }\n\n  /*\n   * (2) If the base dialect is pre-vocabularies, then the\n   * base dialect itself is conceptually the only vocabulary\n   */\n\n  if (is_pre_vocabulary_base_dialect(base_dialect)) {\n    return Vocabularies{{base_dialect_to_known(base_dialect), true}};\n  }\n\n  /*\n   * (3) If the dialect is vocabulary aware, then fetch such dialect\n   */\n\n  const std::optional<sourcemeta::core::JSON> maybe_schema_dialect{\n      resolver(dialect)};\n  if (!maybe_schema_dialect.has_value()) {\n    throw sourcemeta::core::SchemaResolutionError(\n        dialect, \"Could not resolve the metaschema of the schema\");\n  }\n  const sourcemeta::core::JSON &schema_dialect{maybe_schema_dialect.value()};\n  // At this point we are sure that the dialect is vocabulary aware and the\n  // identifier keyword is indeed `$id`, so we can avoid the added\n  // complexity of the generic `id` function.\n  assert(schema_dialect.defines(\"$id\") && schema_dialect.at(\"$id\").is_string());\n\n  /*\n   * (4) Retrieve the vocabularies explicitly or implicitly declared by the\n   * dialect\n   */\n\n  const auto core{core_vocabulary_known(base_dialect)};\n  auto result{parse_vocabularies(schema_dialect, base_dialect)\n                  .value_or(Vocabularies{})};\n  if (result.empty()) {\n    result.insert(core, true);\n  }\n\n  // The specification recommends these checks\n  if (!result.contains(core)) {\n    throw sourcemeta::core::SchemaError(\n        \"The core vocabulary must always be present\");\n  } else {\n    const auto core_status{result.get(core)};\n    if (core_status.has_value() && !core_status.value()) {\n      throw sourcemeta::core::SchemaError(\n          \"The core vocabulary must always be required\");\n    }\n  }\n\n  return result;\n}\n\nauto sourcemeta::core::schema_keyword_priority(\n    std::string_view keyword,\n    const sourcemeta::core::Vocabularies &vocabularies,\n    const sourcemeta::core::SchemaWalker &walker) -> std::uint64_t {\n  const auto &result{walker(keyword, vocabularies)};\n  const auto priority_from_dependencies{std::ranges::fold_left(\n      result.dependencies, static_cast<std::uint64_t>(0),\n      [&vocabularies, &walker](const auto accumulator, const auto &dependency) {\n        return std::max(\n            accumulator,\n            schema_keyword_priority(dependency, vocabularies, walker) + 1);\n      })};\n  const auto priority_from_order_dependencies{std::ranges::fold_left(\n      result.order_dependencies, static_cast<std::uint64_t>(0),\n      [&vocabularies, &walker](const auto accumulator, const auto &dependency) {\n        return std::max(\n            accumulator,\n            schema_keyword_priority(dependency, vocabularies, walker) + 1);\n      })};\n  return std::max(priority_from_dependencies, priority_from_order_dependencies);\n}\n\nauto sourcemeta::core::wrap(const std::string_view identifier)\n    -> sourcemeta::core::JSON {\n  auto result{JSON::make_object()};\n  // JSON Schema 2020-12 is the first dialect that truly supports cross-dialect\n  // references In practice, others do, but we can play it safe here\n  result.assign_assume_new(\n      \"$schema\", JSON{\"https://json-schema.org/draft/2020-12/schema\"});\n  result.assign_assume_new(\"$ref\", JSON{identifier});\n  return result;\n}\n\nauto sourcemeta::core::wrap(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaFrame &frame,\n    const sourcemeta::core::SchemaFrame::Location &location,\n    const sourcemeta::core::SchemaResolver &resolver,\n    sourcemeta::core::WeakPointer &base) -> sourcemeta::core::JSON {\n  assert(frame.mode() == SchemaFrame::Mode::References);\n  assert(location.type != SchemaFrame::LocationType::Pointer);\n\n  const auto &pointer{location.pointer};\n  if (pointer.empty()) {\n    auto copy = schema;\n    if (copy.is_object()) {\n      copy.assign(\"$schema\", JSON{location.dialect});\n    }\n\n    return copy;\n  }\n\n  assert(try_get(schema, pointer));\n  const auto has_internal_references{\n      std::any_of(frame.references().cbegin(), frame.references().cend(),\n                  [&pointer](const auto &reference) {\n                    return reference.first.second.starts_with(pointer);\n                  })};\n\n  if (!has_internal_references) {\n    auto subschema{get(schema, pointer)};\n    if (subschema.is_object()) {\n      subschema.assign(\"$schema\", JSON{location.dialect});\n    }\n\n    return subschema;\n  }\n\n  auto copy = schema;\n  copy.assign(\"$schema\", JSON{location.dialect});\n\n  auto result{JSON::make_object()};\n  // JSON Schema 2020-12 is the first dialect that truly supports\n  // cross-dialect references In practice, others do, but we can\n  // play it safe here\n  result.assign_assume_new(\n      \"$schema\", JSON{\"https://json-schema.org/draft/2020-12/schema\"});\n  // We need to make sure the schema we are wrapping always has an identifier,\n  // at least an artificial one, otherwise a standalone instance of `$schema`\n  // outside of the root of a schema resource is not valid according to\n  // JSON Schema\n  // However, note that we use a relative URI so that references to\n  // other schemas whose top-level identifiers are relative URIs don't\n  // get affected. Otherwise, we would cause unintended base resolution.\n  constexpr std::string_view WRAPPER_IDENTIFIER{\"__sourcemeta-core-wrap__\"};\n  const auto maybe_id{identify(copy, resolver, location.dialect)};\n  const auto id{maybe_id.empty() ? WRAPPER_IDENTIFIER : maybe_id};\n\n  URI uri{id};\n\n  try {\n    reidentify(copy, id, resolver, location.dialect);\n\n    // Otherwise we will get an error with the `WRAPPER_IDENTIFIER`, which will\n    // be confusing to end users\n  } catch (const SchemaReferenceObjectResourceError &) {\n    throw SchemaError(\n        \"Cannot process a JSON Schema Draft 7 or older with a top-level \"\n        \"`$ref` (which overrides sibling keywords) without introducing \"\n        \"undefined behavior\");\n  }\n\n  result.assign_assume_new(\"$defs\", JSON::make_object());\n  result.at(\"$defs\").assign_assume_new(\"schema\", std::move(copy));\n\n  // Add a reference to the schema\n  if (!uri.fragment().has_value() || uri.fragment().value().empty()) {\n    uri.fragment(to_string(pointer));\n    result.assign_assume_new(\"$ref\", JSON{uri.recompose()});\n  } else {\n    static const JSON::String DEFS{\"$defs\"};\n    static const JSON::String SCHEMA{\"schema\"};\n    result.assign_assume_new(\n        \"$ref\",\n        JSON{to_uri(WeakPointer{std::cref(DEFS), std::cref(SCHEMA)}.concat(\n                        pointer))\n                 .recompose()});\n  }\n\n  static const JSON::String REF{\"$ref\"};\n  base.push_back(REF);\n  return result;\n}\n\nstatic auto parse_schema_type_string(const sourcemeta::core::JSON::String &type,\n                                     sourcemeta::core::JSON::TypeSet &result)\n    -> void {\n  if (type == \"null\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Null));\n  } else if (type == \"boolean\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Boolean));\n  } else if (type == \"object\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Object));\n  } else if (type == \"array\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Array));\n  } else if (type == \"number\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Real));\n  } else if (type == \"integer\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::Integer));\n  } else if (type == \"string\") {\n    result.set(std::to_underlying(sourcemeta::core::JSON::Type::String));\n  }\n}\n\nauto sourcemeta::core::parse_schema_type(const sourcemeta::core::JSON &type)\n    -> sourcemeta::core::JSON::TypeSet {\n  sourcemeta::core::JSON::TypeSet result;\n  if (type.is_string()) {\n    parse_schema_type_string(type.to_string(), result);\n  } else if (type.is_array()) {\n    for (const auto &item : type.as_array()) {\n      if (item.is_string()) {\n        parse_schema_type_string(item.to_string(), result);\n      }\n    }\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/known_resolver.cmake",
    "content": "# If PROJECT_SOURCE_DIR is not defined, exit\nif(NOT PROJECT_SOURCE_DIR)\n  message(FATAL_ERROR \"Missing PROJECT_SOURCE_DIR\")\nendif()\n\n# JSON Schema 2020-12\nset(JSON_SCHEMA_2020_12_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-2020-12\")\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_2020_12)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_2020_12)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/applicator.json\" METASCHEMA_JSONSCHEMA_2020_12_APPLICATOR)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/content.json\" METASCHEMA_JSONSCHEMA_2020_12_CONTENT)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/core.json\" METASCHEMA_JSONSCHEMA_2020_12_CORE)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/format-annotation.json\" METASCHEMA_JSONSCHEMA_2020_12_FORMAT_ANNOTATION)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/format-assertion.json\" METASCHEMA_JSONSCHEMA_2020_12_FORMAT_ASSERTION)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/hyper-schema.json\" METASCHEMA_JSONSCHEMA_2020_12_HYPER_SCHEMA)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/meta-data.json\" METASCHEMA_JSONSCHEMA_2020_12_META_DATA)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/unevaluated.json\" METASCHEMA_JSONSCHEMA_2020_12_UNEVALUATED)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/meta/validation.json\" METASCHEMA_JSONSCHEMA_2020_12_VALIDATION)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/links.json\" METASCHEMA_LINKS_2020_12)\nfile(READ \"${JSON_SCHEMA_2020_12_DIR}/output/schema.json\" METASCHEMA_JSONSCHEMA_2020_12_OUTPUT)\n\n# JSON Schema 2019-09\nset(JSON_SCHEMA_2019_09_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-2019-09\")\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_2019_09)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_2019_09)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/applicator.json\" METASCHEMA_JSONSCHEMA_2019_09_APPLICATOR)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/content.json\" METASCHEMA_JSONSCHEMA_2019_09_CONTENT)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/core.json\" METASCHEMA_JSONSCHEMA_2019_09_CORE)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/format.json\" METASCHEMA_JSONSCHEMA_2019_09_FORMAT)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/hyper-schema.json\" METASCHEMA_JSONSCHEMA_2019_09_HYPER_SCHEMA)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/meta-data.json\" METASCHEMA_JSONSCHEMA_2019_09_META_DATA)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/meta/validation.json\" METASCHEMA_JSONSCHEMA_2019_09_VALIDATION)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/links.json\" METASCHEMA_LINKS_2019_09)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/output/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_2019_09_OUTPUT)\nfile(READ \"${JSON_SCHEMA_2019_09_DIR}/output/schema.json\" METASCHEMA_JSONSCHEMA_2019_09_OUTPUT)\n\n# JSON Schema Draft7\nset(JSON_SCHEMA_DRAFT7_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft7\")\nfile(READ \"${JSON_SCHEMA_DRAFT7_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT7)\nfile(READ \"${JSON_SCHEMA_DRAFT7_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT7)\nfile(READ \"${JSON_SCHEMA_DRAFT7_DIR}/hyper-schema-output.json\" METASCHEMA_HYPERSCHEMA_DRAFT7_OUTPUT)\nfile(READ \"${JSON_SCHEMA_DRAFT7_DIR}/links.json\" METASCHEMA_LINKS_DRAFT7)\n\n# JSON Schema Draft6\nset(JSON_SCHEMA_DRAFT6_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft6\")\nfile(READ \"${JSON_SCHEMA_DRAFT6_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT6)\nfile(READ \"${JSON_SCHEMA_DRAFT6_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT6)\nfile(READ \"${JSON_SCHEMA_DRAFT6_DIR}/links.json\" METASCHEMA_LINKS_DRAFT6)\n\n# JSON Schema Draft4\nset(JSON_SCHEMA_DRAFT4_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft4\")\nfile(READ \"${JSON_SCHEMA_DRAFT4_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT4)\nfile(READ \"${JSON_SCHEMA_DRAFT4_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT4)\nfile(READ \"${JSON_SCHEMA_DRAFT4_DIR}/links.json\" METASCHEMA_LINKS_DRAFT4)\n\n# JSON Schema Draft3\nset(JSON_SCHEMA_DRAFT3_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft3\")\nfile(READ \"${JSON_SCHEMA_DRAFT3_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT3)\nfile(READ \"${JSON_SCHEMA_DRAFT3_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT3)\nfile(READ \"${JSON_SCHEMA_DRAFT3_DIR}/json-ref.json\" METASCHEMA_JSON_REF_DRAFT3)\nfile(READ \"${JSON_SCHEMA_DRAFT3_DIR}/links.json\" METASCHEMA_LINKS_DRAFT3)\n\n# JSON Schema Draft2\nset(JSON_SCHEMA_DRAFT2_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft2\")\nfile(READ \"${JSON_SCHEMA_DRAFT2_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT2)\nfile(READ \"${JSON_SCHEMA_DRAFT2_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT2)\nfile(READ \"${JSON_SCHEMA_DRAFT2_DIR}/json-ref.json\" METASCHEMA_JSON_REF_DRAFT2)\nfile(READ \"${JSON_SCHEMA_DRAFT2_DIR}/links.json\" METASCHEMA_LINKS_DRAFT2)\n\n# JSON Schema Draft1\nset(JSON_SCHEMA_DRAFT1_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft1\")\nfile(READ \"${JSON_SCHEMA_DRAFT1_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT1)\nfile(READ \"${JSON_SCHEMA_DRAFT1_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT1)\nfile(READ \"${JSON_SCHEMA_DRAFT1_DIR}/json-ref.json\" METASCHEMA_JSON_REF_DRAFT1)\nfile(READ \"${JSON_SCHEMA_DRAFT1_DIR}/links.json\" METASCHEMA_LINKS_DRAFT1)\n\n# JSON Schema Draft0\nset(JSON_SCHEMA_DRAFT0_DIR \"${PROJECT_SOURCE_DIR}/vendor/jsonschema-draft0\")\nfile(READ \"${JSON_SCHEMA_DRAFT0_DIR}/schema.json\" METASCHEMA_JSONSCHEMA_DRAFT0)\nfile(READ \"${JSON_SCHEMA_DRAFT0_DIR}/hyper-schema.json\" METASCHEMA_HYPERSCHEMA_DRAFT0)\nfile(READ \"${JSON_SCHEMA_DRAFT0_DIR}/json-ref.json\" METASCHEMA_JSON_REF_DRAFT0)\nfile(READ \"${JSON_SCHEMA_DRAFT0_DIR}/links.json\" METASCHEMA_LINKS_DRAFT0)\n\n# OpenAPI v3.2\nset(OPENAPI_3_2_DIR \"${PROJECT_SOURCE_DIR}/vendor/openapi/oas/3.2\")\nfile(READ \"${OPENAPI_3_2_DIR}/meta/2025-09-17\" OPENAPI_OAS_3_2_META_2025_09_17)\nfile(READ \"${OPENAPI_3_2_DIR}/dialect/2025-09-17\" OPENAPI_OAS_3_2_DIALECT_2025_09_17)\n\n# OpenAPI v3.1\nset(OPENAPI_3_1_DIR \"${PROJECT_SOURCE_DIR}/vendor/openapi/oas/3.1\")\nfile(READ \"${OPENAPI_3_1_DIR}/meta/base\" OPENAPI_OAS_3_1_META_BASE)\nfile(READ \"${OPENAPI_3_1_DIR}/dialect/base\" OPENAPI_OAS_3_1_DIALECT_BASE)\n\nif(NOT KNOWN_RESOLVER_INPUT)\n  message(FATAL_ERROR \"Missing KNOWN_RESOLVER_INPUT\")\nendif()\nif(NOT KNOWN_RESOLVER_OUTPUT)\n  message(FATAL_ERROR \"Missing KNOWN_RESOLVER_OUTPUT\")\nendif()\nconfigure_file(\"${KNOWN_RESOLVER_INPUT}\" \"${KNOWN_RESOLVER_OUTPUT}\" @ONLY)\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/known_resolver.in.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include <cstdint> // std::uint8_t\n\nenum class KnownSchema : std::uint8_t {\n  JSONSCHEMA_2020_12,\n  HYPERSCHEMA_2020_12,\n  JSONSCHEMA_2020_12_APPLICATOR,\n  JSONSCHEMA_2020_12_CONTENT,\n  JSONSCHEMA_2020_12_CORE,\n  JSONSCHEMA_2020_12_FORMAT_ANNOTATION,\n  JSONSCHEMA_2020_12_FORMAT_ASSERTION,\n  JSONSCHEMA_2020_12_HYPER_SCHEMA,\n  JSONSCHEMA_2020_12_META_DATA,\n  JSONSCHEMA_2020_12_UNEVALUATED,\n  JSONSCHEMA_2020_12_VALIDATION,\n  LINKS_2020_12,\n  JSONSCHEMA_2020_12_OUTPUT,\n\n  JSONSCHEMA_2019_09,\n  HYPERSCHEMA_2019_09,\n  JSONSCHEMA_2019_09_APPLICATOR,\n  JSONSCHEMA_2019_09_CONTENT,\n  JSONSCHEMA_2019_09_CORE,\n  JSONSCHEMA_2019_09_FORMAT,\n  JSONSCHEMA_2019_09_HYPER_SCHEMA,\n  JSONSCHEMA_2019_09_META_DATA,\n  JSONSCHEMA_2019_09_VALIDATION,\n  LINKS_2019_09,\n  JSONSCHEMA_2019_09_OUTPUT,\n  HYPERSCHEMA_2019_09_OUTPUT,\n\n  JSONSCHEMA_DRAFT7,\n  HYPERSCHEMA_DRAFT7,\n  LINKS_DRAFT7,\n  HYPERSCHEMA_DRAFT7_OUTPUT,\n\n  JSONSCHEMA_DRAFT6,\n  HYPERSCHEMA_DRAFT6,\n  LINKS_DRAFT6,\n\n  JSONSCHEMA_DRAFT4,\n  HYPERSCHEMA_DRAFT4,\n  LINKS_DRAFT4,\n\n  JSONSCHEMA_DRAFT3,\n  HYPERSCHEMA_DRAFT3,\n  LINKS_DRAFT3,\n  JSON_REF_DRAFT3,\n\n  JSONSCHEMA_DRAFT2,\n  HYPERSCHEMA_DRAFT2,\n  LINKS_DRAFT2,\n  JSON_REF_DRAFT2,\n\n  JSONSCHEMA_DRAFT1,\n  HYPERSCHEMA_DRAFT1,\n  LINKS_DRAFT1,\n  JSON_REF_DRAFT1,\n\n  JSONSCHEMA_DRAFT0,\n  HYPERSCHEMA_DRAFT0,\n  LINKS_DRAFT0,\n  JSON_REF_DRAFT0,\n\n  OAS_3_2_DIALECT_2025_09_17,\n  OAS_3_2_META_2025_09_17,\n\n  OAS_3_1_DIALECT_BASE,\n  OAS_3_1_META_BASE,\n\n  UNKNOWN\n};\n\nstatic auto parse_identifier(const std::string_view identifier) -> KnownSchema {\n  // JSON Schema 2020-12\n  if (identifier == \"https://json-schema.org/draft/2020-12/schema\" ||\n      identifier == \"https://json-schema.org/draft/2020-12/schema#\" ||\n      identifier == \"http://json-schema.org/draft/2020-12/schema\" ||\n      identifier == \"http://json-schema.org/draft/2020-12/schema#\") {\n    return KnownSchema::JSONSCHEMA_2020_12;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/hyper-schema\" ||\n             identifier ==\n                 \"https://json-schema.org/draft/2020-12/hyper-schema#\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/hyper-schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/hyper-schema#\") {\n    return KnownSchema::HYPERSCHEMA_2020_12;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/applicator\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/applicator\") {\n    return KnownSchema::JSONSCHEMA_2020_12_APPLICATOR;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/content\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/content\") {\n    return KnownSchema::JSONSCHEMA_2020_12_CONTENT;\n  } else if (identifier == \"https://json-schema.org/draft/2020-12/meta/core\" ||\n             identifier == \"http://json-schema.org/draft/2020-12/meta/core\") {\n    return KnownSchema::JSONSCHEMA_2020_12_CORE;\n  } else if (\n      identifier ==\n          \"https://json-schema.org/draft/2020-12/meta/format-annotation\" ||\n      identifier ==\n          \"http://json-schema.org/draft/2020-12/meta/format-annotation\") {\n    return KnownSchema::JSONSCHEMA_2020_12_FORMAT_ANNOTATION;\n  } else if (identifier == \"https://json-schema.org/draft/2020-12/meta/\"\n                           \"format-assertion\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/format-assertion\") {\n    return KnownSchema::JSONSCHEMA_2020_12_FORMAT_ASSERTION;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/hyper-schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/hyper-schema\") {\n    return KnownSchema::JSONSCHEMA_2020_12_HYPER_SCHEMA;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/meta-data\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/meta-data\") {\n    return KnownSchema::JSONSCHEMA_2020_12_META_DATA;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/unevaluated\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/unevaluated\") {\n    return KnownSchema::JSONSCHEMA_2020_12_UNEVALUATED;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/meta/validation\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/meta/validation\") {\n    return KnownSchema::JSONSCHEMA_2020_12_VALIDATION;\n  } else if (identifier == \"https://json-schema.org/draft/2020-12/links\" ||\n             identifier == \"http://json-schema.org/draft/2020-12/links\") {\n    return KnownSchema::LINKS_2020_12;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2020-12/output/schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2020-12/output/schema\") {\n    return KnownSchema::JSONSCHEMA_2020_12_OUTPUT;\n\n    // JSON Schema 2019-09\n  } else if (identifier == \"https://json-schema.org/draft/2019-09/schema\" ||\n             identifier == \"https://json-schema.org/draft/2019-09/schema#\" ||\n             identifier == \"http://json-schema.org/draft/2019-09/schema\" ||\n             identifier == \"http://json-schema.org/draft/2019-09/schema#\") {\n    return KnownSchema::JSONSCHEMA_2019_09;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/hyper-schema\" ||\n             identifier ==\n                 \"https://json-schema.org/draft/2019-09/hyper-schema#\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/hyper-schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/hyper-schema#\") {\n    return KnownSchema::HYPERSCHEMA_2019_09;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/applicator\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/meta/applicator\") {\n    return KnownSchema::JSONSCHEMA_2019_09_APPLICATOR;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/content\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/meta/content\") {\n    return KnownSchema::JSONSCHEMA_2019_09_CONTENT;\n  } else if (identifier == \"https://json-schema.org/draft/2019-09/meta/core\" ||\n             identifier == \"http://json-schema.org/draft/2019-09/meta/core\") {\n    return KnownSchema::JSONSCHEMA_2019_09_CORE;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/format\" ||\n             identifier == \"http://json-schema.org/draft/2019-09/meta/format\") {\n    return KnownSchema::JSONSCHEMA_2019_09_FORMAT;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/hyper-schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/meta/hyper-schema\") {\n    return KnownSchema::JSONSCHEMA_2019_09_HYPER_SCHEMA;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/meta-data\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/meta/meta-data\") {\n    return KnownSchema::JSONSCHEMA_2019_09_META_DATA;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/meta/validation\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/meta/validation\") {\n    return KnownSchema::JSONSCHEMA_2019_09_VALIDATION;\n  } else if (identifier == \"https://json-schema.org/draft/2019-09/links\" ||\n             identifier == \"http://json-schema.org/draft/2019-09/links\") {\n    return KnownSchema::LINKS_2019_09;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/output/schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/output/schema\") {\n    return KnownSchema::JSONSCHEMA_2019_09_OUTPUT;\n  } else if (identifier ==\n                 \"https://json-schema.org/draft/2019-09/output/hyper-schema\" ||\n             identifier ==\n                 \"http://json-schema.org/draft/2019-09/output/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_2019_09_OUTPUT;\n\n    // JSON Schema Draft7\n  } else if (identifier == \"http://json-schema.org/draft-07/schema#\" ||\n             identifier == \"http://json-schema.org/draft-07/schema\" ||\n             identifier == \"https://json-schema.org/draft-07/schema#\" ||\n             identifier == \"https://json-schema.org/draft-07/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT7;\n  } else if (identifier == \"http://json-schema.org/draft-07/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-07/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-07/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-07/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT7;\n  } else if (identifier == \"http://json-schema.org/draft-07/links#\" ||\n             identifier == \"http://json-schema.org/draft-07/links\" ||\n             identifier == \"https://json-schema.org/draft-07/links#\" ||\n             identifier == \"https://json-schema.org/draft-07/links\") {\n    return KnownSchema::LINKS_DRAFT7;\n  } else if (identifier ==\n                 \"http://json-schema.org/draft-07/hyper-schema-output\" ||\n             identifier ==\n                 \"https://json-schema.org/draft-07/hyper-schema-output\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT7_OUTPUT;\n\n    // JSON Schema Draft6\n  } else if (identifier == \"http://json-schema.org/draft-06/schema#\" ||\n             identifier == \"http://json-schema.org/draft-06/schema\" ||\n             identifier == \"https://json-schema.org/draft-06/schema#\" ||\n             identifier == \"https://json-schema.org/draft-06/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT6;\n  } else if (identifier == \"http://json-schema.org/draft-06/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-06/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-06/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-06/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT6;\n  } else if (identifier == \"http://json-schema.org/draft-06/links#\" ||\n             identifier == \"http://json-schema.org/draft-06/links\" ||\n             identifier == \"https://json-schema.org/draft-06/links#\" ||\n             identifier == \"https://json-schema.org/draft-06/links\") {\n    return KnownSchema::LINKS_DRAFT6;\n\n    // JSON Schema Draft4\n  } else if (identifier == \"http://json-schema.org/draft-04/schema#\" ||\n             identifier == \"http://json-schema.org/draft-04/schema\" ||\n             identifier == \"https://json-schema.org/draft-04/schema#\" ||\n             identifier == \"https://json-schema.org/draft-04/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT4;\n  } else if (identifier == \"http://json-schema.org/draft-04/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-04/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-04/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-04/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT4;\n  } else if (identifier == \"http://json-schema.org/draft-04/links#\" ||\n             identifier == \"http://json-schema.org/draft-04/links\" ||\n             identifier == \"https://json-schema.org/draft-04/links#\" ||\n             identifier == \"https://json-schema.org/draft-04/links\") {\n    return KnownSchema::LINKS_DRAFT4;\n\n    // JSON Schema Draft3\n  } else if (identifier == \"http://json-schema.org/draft-03/schema#\" ||\n             identifier == \"http://json-schema.org/draft-03/schema\" ||\n             identifier == \"https://json-schema.org/draft-03/schema#\" ||\n             identifier == \"https://json-schema.org/draft-03/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT3;\n  } else if (identifier == \"http://json-schema.org/draft-03/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-03/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-03/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-03/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT3;\n  } else if (identifier == \"http://json-schema.org/draft-03/links#\" ||\n             identifier == \"http://json-schema.org/draft-03/links\" ||\n             identifier == \"https://json-schema.org/draft-03/links#\" ||\n             identifier == \"https://json-schema.org/draft-03/links\") {\n    return KnownSchema::LINKS_DRAFT3;\n  } else if (identifier == \"http://json-schema.org/draft-03/json-ref#\" ||\n             identifier == \"http://json-schema.org/draft-03/json-ref\" ||\n             identifier == \"https://json-schema.org/draft-03/json-ref#\" ||\n             identifier == \"https://json-schema.org/draft-03/json-ref\") {\n    return KnownSchema::JSON_REF_DRAFT3;\n\n    // JSON Schema Draft2\n  } else if (identifier == \"http://json-schema.org/draft-02/schema#\" ||\n             identifier == \"http://json-schema.org/draft-02/schema\" ||\n             identifier == \"https://json-schema.org/draft-02/schema#\" ||\n             identifier == \"https://json-schema.org/draft-02/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT2;\n  } else if (identifier == \"http://json-schema.org/draft-02/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-02/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-02/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-02/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT2;\n  } else if (identifier == \"http://json-schema.org/draft-02/links#\" ||\n             identifier == \"http://json-schema.org/draft-02/links\" ||\n             identifier == \"https://json-schema.org/draft-02/links#\" ||\n             identifier == \"https://json-schema.org/draft-02/links\") {\n    return KnownSchema::LINKS_DRAFT2;\n  } else if (identifier == \"http://json-schema.org/draft-02/json-ref#\" ||\n             identifier == \"http://json-schema.org/draft-02/json-ref\" ||\n             identifier == \"https://json-schema.org/draft-02/json-ref#\" ||\n             identifier == \"https://json-schema.org/draft-02/json-ref\") {\n    return KnownSchema::JSON_REF_DRAFT2;\n\n    // JSON Schema Draft1\n  } else if (identifier == \"http://json-schema.org/draft-01/schema#\" ||\n             identifier == \"http://json-schema.org/draft-01/schema\" ||\n             identifier == \"https://json-schema.org/draft-01/schema#\" ||\n             identifier == \"https://json-schema.org/draft-01/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT1;\n  } else if (identifier == \"http://json-schema.org/draft-01/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-01/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-01/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-01/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT1;\n  } else if (identifier == \"http://json-schema.org/draft-01/links#\" ||\n             identifier == \"http://json-schema.org/draft-01/links\" ||\n             identifier == \"https://json-schema.org/draft-01/links#\" ||\n             identifier == \"https://json-schema.org/draft-01/links\") {\n    return KnownSchema::LINKS_DRAFT1;\n  } else if (identifier == \"http://json-schema.org/draft-01/json-ref#\" ||\n             identifier == \"http://json-schema.org/draft-01/json-ref\" ||\n             identifier == \"https://json-schema.org/draft-01/json-ref#\" ||\n             identifier == \"https://json-schema.org/draft-01/json-ref\") {\n    return KnownSchema::JSON_REF_DRAFT1;\n\n    // JSON Schema Draft0\n  } else if (identifier == \"http://json-schema.org/draft-00/schema#\" ||\n             identifier == \"http://json-schema.org/draft-00/schema\" ||\n             identifier == \"https://json-schema.org/draft-00/schema#\" ||\n             identifier == \"https://json-schema.org/draft-00/schema\") {\n    return KnownSchema::JSONSCHEMA_DRAFT0;\n  } else if (identifier == \"http://json-schema.org/draft-00/hyper-schema#\" ||\n             identifier == \"http://json-schema.org/draft-00/hyper-schema\" ||\n             identifier == \"https://json-schema.org/draft-00/hyper-schema#\" ||\n             identifier == \"https://json-schema.org/draft-00/hyper-schema\") {\n    return KnownSchema::HYPERSCHEMA_DRAFT0;\n  } else if (identifier == \"http://json-schema.org/draft-00/links#\" ||\n             identifier == \"http://json-schema.org/draft-00/links\" ||\n             identifier == \"https://json-schema.org/draft-00/links#\" ||\n             identifier == \"https://json-schema.org/draft-00/links\") {\n    return KnownSchema::LINKS_DRAFT0;\n  } else if (identifier == \"http://json-schema.org/draft-00/json-ref#\" ||\n             identifier == \"http://json-schema.org/draft-00/json-ref\" ||\n             identifier == \"https://json-schema.org/draft-00/json-ref#\" ||\n             identifier == \"https://json-schema.org/draft-00/json-ref\") {\n    return KnownSchema::JSON_REF_DRAFT0;\n\n    // OpenAPI v3.2\n  } else if (identifier ==\n             \"https://spec.openapis.org/oas/3.2/dialect/2025-09-17\") {\n    return KnownSchema::OAS_3_2_DIALECT_2025_09_17;\n  } else if (identifier ==\n             \"https://spec.openapis.org/oas/3.2/meta/2025-09-17\") {\n    return KnownSchema::OAS_3_2_META_2025_09_17;\n\n    // OpenAPI v3.1\n  } else if (identifier == \"https://spec.openapis.org/oas/3.1/dialect/base\") {\n    return KnownSchema::OAS_3_1_DIALECT_BASE;\n  } else if (identifier == \"https://spec.openapis.org/oas/3.1/meta/base\") {\n    return KnownSchema::OAS_3_1_META_BASE;\n  }\n\n  return KnownSchema::UNKNOWN;\n}\n\nauto sourcemeta::core::schema_resolver(const std::string_view identifier)\n    -> std::optional<sourcemeta::core::JSON> {\n  switch (parse_identifier(identifier)) {\n    case KnownSchema::JSONSCHEMA_2020_12:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12@)EOF\");\n    case KnownSchema::HYPERSCHEMA_2020_12:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_2020_12@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_APPLICATOR:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_APPLICATOR@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_CONTENT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_CONTENT@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_CORE:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_CORE@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_FORMAT_ANNOTATION:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_FORMAT_ANNOTATION@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_FORMAT_ASSERTION:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_FORMAT_ASSERTION@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_HYPER_SCHEMA:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_HYPER_SCHEMA@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_META_DATA:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_META_DATA@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_UNEVALUATED:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_UNEVALUATED@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_VALIDATION:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_VALIDATION@)EOF\");\n    case KnownSchema::LINKS_2020_12:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_LINKS_2020_12@)EOF\");\n    case KnownSchema::JSONSCHEMA_2020_12_OUTPUT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2020_12_OUTPUT@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09@)EOF\");\n    case KnownSchema::HYPERSCHEMA_2019_09:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_2019_09@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_APPLICATOR:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_APPLICATOR@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_CONTENT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_CONTENT@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_CORE:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_CORE@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_FORMAT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_FORMAT@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_HYPER_SCHEMA:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_HYPER_SCHEMA@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_META_DATA:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_META_DATA@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_VALIDATION:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_VALIDATION@)EOF\");\n    case KnownSchema::LINKS_2019_09:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_LINKS_2019_09@)EOF\");\n    case KnownSchema::JSONSCHEMA_2019_09_OUTPUT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_2019_09_OUTPUT@)EOF\");\n    case KnownSchema::HYPERSCHEMA_2019_09_OUTPUT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_2019_09_OUTPUT@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT7:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT7@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT7:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT7@)EOF\");\n    case KnownSchema::LINKS_DRAFT7:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT7@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT7_OUTPUT:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT7_OUTPUT@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT6:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT6@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT6:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT6@)EOF\");\n    case KnownSchema::LINKS_DRAFT6:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT6@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT4:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT4@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT4:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT4@)EOF\");\n    case KnownSchema::LINKS_DRAFT4:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT4@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT3:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT3@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT3:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT3@)EOF\");\n    case KnownSchema::LINKS_DRAFT3:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT3@)EOF\");\n    case KnownSchema::JSON_REF_DRAFT3:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSON_REF_DRAFT3@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT2:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT2@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT2:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT2@)EOF\");\n    case KnownSchema::LINKS_DRAFT2:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT2@)EOF\");\n    case KnownSchema::JSON_REF_DRAFT2:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSON_REF_DRAFT2@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT1:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT1@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT1:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT1@)EOF\");\n    case KnownSchema::LINKS_DRAFT1:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT1@)EOF\");\n    case KnownSchema::JSON_REF_DRAFT1:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSON_REF_DRAFT1@)EOF\");\n    case KnownSchema::JSONSCHEMA_DRAFT0:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSONSCHEMA_DRAFT0@)EOF\");\n    case KnownSchema::HYPERSCHEMA_DRAFT0:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_HYPERSCHEMA_DRAFT0@)EOF\");\n    case KnownSchema::LINKS_DRAFT0:\n      return sourcemeta::core::parse_json(R\"EOF(@METASCHEMA_LINKS_DRAFT0@)EOF\");\n    case KnownSchema::JSON_REF_DRAFT0:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@METASCHEMA_JSON_REF_DRAFT0@)EOF\");\n    case KnownSchema::OAS_3_2_DIALECT_2025_09_17:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@OPENAPI_OAS_3_2_DIALECT_2025_09_17@)EOF\");\n    case KnownSchema::OAS_3_2_META_2025_09_17:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@OPENAPI_OAS_3_2_META_2025_09_17@)EOF\");\n    case KnownSchema::OAS_3_1_DIALECT_BASE:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@OPENAPI_OAS_3_1_DIALECT_BASE@)EOF\");\n    case KnownSchema::OAS_3_1_META_BASE:\n      return sourcemeta::core::parse_json(\n          R\"EOF(@OPENAPI_OAS_3_1_META_BASE@)EOF\");\n    case KnownSchema::UNKNOWN:\n      return std::nullopt;\n  }\n\n  return std::nullopt;\n}\n\nauto sourcemeta::core::is_known_schema(\n    const std::string_view identifier) noexcept -> bool {\n  return parse_identifier(identifier) != KnownSchema::UNKNOWN;\n}\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/known_walker.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include <unordered_map> // std::unordered_map\n\nnamespace sourcemeta::core {\n\nnamespace {\n\nusing Known = Vocabularies::Known;\nusing KeywordHandler =\n    const SchemaWalkerResult &(*)(const Vocabularies &vocabularies);\n\nstatic const SchemaWalkerResult UNKNOWN_RESULT{\n    SchemaKeywordType::Unknown, std::nullopt, {}, {}, {}};\n\nstatic const SchemaWalkerResult UNKNOWN_WITH_REF_RESULT{\n    SchemaKeywordType::Unknown, std::nullopt, {\"$ref\"}, {}, {}};\n\nauto has_draft3_to_7(const Vocabularies &vocabularies) -> bool {\n  return vocabularies.contains(Known::JSON_Schema_Draft_7) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_7_Hyper) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_6) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_6_Hyper) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_4) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_4_Hyper) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n         vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper);\n}\n\n#define RETURN_WITH_DEPENDENCIES(_vocabulary, _types, _strategy, ...)          \\\n  {                                                                            \\\n    static const SchemaWalkerResult result{                                    \\\n        SchemaKeywordType::_strategy, _vocabulary, {__VA_ARGS__}, {}, _types}; \\\n    return result;                                                             \\\n  }\n\n#define RETURN_WITH_ORDER_DEPENDENCIES(_vocabulary, _types, _strategy, ...)    \\\n  {                                                                            \\\n    static const SchemaWalkerResult result{                                    \\\n        SchemaKeywordType::_strategy, _vocabulary, {}, {__VA_ARGS__}, _types}; \\\n    return result;                                                             \\\n  }\n\n#define RETURN(_vocabulary, _types, _strategy)                                 \\\n  {                                                                            \\\n    static const SchemaWalkerResult result{                                    \\\n        SchemaKeywordType::_strategy, _vocabulary, {}, {}, _types};            \\\n    return result;                                                             \\\n  }\n\n#define CHECK_VOCABULARY_WITH_DEPENDENCIES(_vocabulary, _types, _strategy,     \\\n                                           ...)                                \\\n  if (vocabularies.contains(_vocabulary)) {                                    \\\n    RETURN_WITH_DEPENDENCIES(_vocabulary, _types, _strategy, __VA_ARGS__)      \\\n  }\n\n#define CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(_vocabulary, _types,          \\\n                                                 _strategy, ...)               \\\n  if (vocabularies.contains(_vocabulary)) {                                    \\\n    RETURN_WITH_ORDER_DEPENDENCIES(_vocabulary, _types, _strategy,             \\\n                                   __VA_ARGS__)                                \\\n  }\n\n#define CHECK_VOCABULARY(_vocabulary, _types, _strategy)                       \\\n  if (vocabularies.contains(_vocabulary)) {                                    \\\n    RETURN(_vocabulary, _types, _strategy)                                     \\\n  }\n\nauto handle_dollar_id(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Other)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Other, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_schema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Other)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_ref(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Reference)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Reference)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_defs(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, LocationMembers)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, LocationMembers)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_definitions(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, LocationMembers)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, LocationMembers)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {},\n                                     LocationMembers, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     LocationMembers, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_comment(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Comment)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_anchor(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_vocabulary(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_dynamicRef(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Reference)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_dynamicAnchor(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Core, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_recursiveRef(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Reference)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dollar_recursiveAnchor(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Core, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_id(const Vocabularies &vocabularies) -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_oneOf(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_anyOf(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_allOf(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_if(const Vocabularies &vocabularies) -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator, {},\n                   ApplicatorValueInPlaceMaybe)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator, {},\n                   ApplicatorValueInPlaceMaybe)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorValueInPlaceMaybe, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorValueInPlaceMaybe, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_then(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_2020_12_Applicator, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_2019_09_Applicator, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_else(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_2020_12_Applicator, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_2019_09_Applicator, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorValueInPlaceMaybe, \"if\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_not(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator, {},\n                   ApplicatorValueInPlaceNegate)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator, {},\n                   ApplicatorValueInPlaceNegate)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     ApplicatorValueInPlaceNegate, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_properties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  if (vocabularies.contains(Known::JSON_Schema_2020_12_Applicator)) {\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Validation)) {\n      RETURN_WITH_ORDER_DEPENDENCIES(\n          Known::JSON_Schema_2020_12_Applicator, make_set({JSON::Type::Object}),\n          ApplicatorMembersTraversePropertyStatic, \"required\")\n    }\n    RETURN(Known::JSON_Schema_2020_12_Applicator,\n           make_set({JSON::Type::Object}),\n           ApplicatorMembersTraversePropertyStatic)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_2019_09_Applicator)) {\n    if (vocabularies.contains(Known::JSON_Schema_2019_09_Validation)) {\n      RETURN_WITH_ORDER_DEPENDENCIES(\n          Known::JSON_Schema_2019_09_Applicator, make_set({JSON::Type::Object}),\n          ApplicatorMembersTraversePropertyStatic, \"required\")\n    }\n    RETURN(Known::JSON_Schema_2019_09_Applicator,\n           make_set({JSON::Type::Object}),\n           ApplicatorMembersTraversePropertyStatic)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_7)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_7,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_7_Hyper)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_7_Hyper,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_6)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_6,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_6_Hyper)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_6_Hyper,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_4)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_4,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  if (vocabularies.contains(Known::JSON_Schema_Draft_4_Hyper)) {\n    static const SchemaWalkerResult result{\n        SchemaKeywordType::ApplicatorMembersTraversePropertyStatic,\n        Known::JSON_Schema_Draft_4_Hyper,\n        {\"$ref\"},\n        {\"required\"},\n        make_set({JSON::Type::Object})};\n    return result;\n  }\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyStatic, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyStatic, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyStatic)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_additionalProperties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_2020_12_Applicator, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_2019_09_Applicator, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\", \"patternProperties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_2, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_2_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_1, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_1_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_0, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_0_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseSomeProperty, \"properties\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_patternProperties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyRegex)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorMembersTraversePropertyRegex)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorMembersTraversePropertyRegex, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_propertyNames(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseAnyPropertyKey)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseAnyPropertyKey)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseAnyPropertyKey, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseAnyPropertyKey, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseAnyPropertyKey, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper, make_set({JSON::Type::Object}),\n      ApplicatorValueTraverseAnyPropertyKey, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dependentSchemas(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator,\n                   make_set({JSON::Type::Object}), ApplicatorMembersInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator,\n                   make_set({JSON::Type::Object}), ApplicatorMembersInPlaceSome)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dependencies(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Object}),\n                                     ApplicatorMembersInPlaceSome, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_contains(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  if (vocabularies.contains(Known::JSON_Schema_2020_12_Applicator)) {\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Validation)) {\n      RETURN_WITH_DEPENDENCIES(\n          Known::JSON_Schema_2020_12_Applicator, make_set({JSON::Type::Array}),\n          ApplicatorValueTraverseAnyItem, \"minContains\", \"maxContains\")\n    }\n    RETURN(Known::JSON_Schema_2020_12_Applicator, make_set({JSON::Type::Array}),\n           ApplicatorValueTraverseAnyItem)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_2019_09_Applicator)) {\n    if (vocabularies.contains(Known::JSON_Schema_2019_09_Validation)) {\n      RETURN_WITH_DEPENDENCIES(\n          Known::JSON_Schema_2019_09_Applicator, make_set({JSON::Type::Array}),\n          ApplicatorValueTraverseAnyItem, \"minContains\", \"maxContains\")\n    }\n    RETURN(Known::JSON_Schema_2019_09_Applicator, make_set({JSON::Type::Array}),\n           ApplicatorValueTraverseAnyItem)\n  }\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseAnyItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseAnyItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseAnyItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseAnyItem, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_items(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_2020_12_Applicator, make_set({JSON::Type::Array}),\n      ApplicatorValueTraverseSomeItem, \"prefixItems\")\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Applicator,\n                   make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper, make_set({JSON::Type::Array}),\n      ApplicatorValueOrElementsTraverseAnyItemOrItem, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Array}),\n                   ApplicatorValueOrElementsTraverseAnyItemOrItem)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_prefixItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Applicator,\n                   make_set({JSON::Type::Array}),\n                   ApplicatorElementsTraverseItem)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_additionalItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_2019_09_Applicator,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Array}),\n                                     ApplicatorValueTraverseSomeItem, \"items\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_unevaluatedProperties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  if (vocabularies.contains(Known::JSON_Schema_2020_12_Unevaluated)) {\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Applicator)) {\n      RETURN_WITH_DEPENDENCIES(\n          Known::JSON_Schema_2020_12_Unevaluated,\n          make_set({JSON::Type::Object}), ApplicatorValueTraverseSomeProperty,\n          \"properties\", \"patternProperties\", \"additionalProperties\")\n    }\n    RETURN(Known::JSON_Schema_2020_12_Unevaluated,\n           make_set({JSON::Type::Object}), ApplicatorValueTraverseSomeProperty)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_2019_09_Applicator)) {\n    RETURN_WITH_DEPENDENCIES(Known::JSON_Schema_2019_09_Applicator,\n                             make_set({JSON::Type::Object}),\n                             ApplicatorValueTraverseSomeProperty, \"properties\",\n                             \"patternProperties\", \"additionalProperties\")\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_unevaluatedItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  if (vocabularies.contains(Known::JSON_Schema_2020_12_Unevaluated)) {\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Applicator)) {\n      RETURN_WITH_DEPENDENCIES(\n          Known::JSON_Schema_2020_12_Unevaluated, make_set({JSON::Type::Array}),\n          ApplicatorValueTraverseSomeItem, \"prefixItems\", \"items\", \"contains\")\n    }\n    RETURN(Known::JSON_Schema_2020_12_Unevaluated,\n           make_set({JSON::Type::Array}), ApplicatorValueTraverseSomeItem)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_2019_09_Applicator)) {\n    RETURN_WITH_DEPENDENCIES(\n        Known::JSON_Schema_2019_09_Applicator, make_set({JSON::Type::Array}),\n        ApplicatorValueTraverseSomeItem, \"items\", \"additionalItems\")\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_type(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  if (vocabularies.contains(Known::JSON_Schema_2020_12_Validation)) {\n    if (vocabularies.contains(Known::JSON_Schema_2020_12_Applicator)) {\n      RETURN_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_2020_12_Validation, {},\n                                     Assertion, \"properties\")\n    }\n    RETURN(Known::JSON_Schema_2020_12_Validation, {}, Assertion)\n  }\n  if (vocabularies.contains(Known::JSON_Schema_2019_09_Validation)) {\n    if (vocabularies.contains(Known::JSON_Schema_2019_09_Applicator)) {\n      RETURN_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_2019_09_Validation, {},\n                                     Assertion, \"properties\")\n    }\n    RETURN(Known::JSON_Schema_2019_09_Validation, {}, Assertion)\n  }\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_7, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_6, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_4, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                           Assertion, \"properties\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     ApplicatorElementsInPlaceSome, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {},\n                   ApplicatorElementsInPlaceSome)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {},\n                   ApplicatorElementsInPlaceSome)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_enum(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation, {}, Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Assertion, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_const(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation, {}, Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Assertion, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_multipleOf(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maximum(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(\n      Known::JSON_Schema_2020_12_Validation,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"type\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(\n      Known::JSON_Schema_2019_09_Validation,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"type\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minimum(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(\n      Known::JSON_Schema_2020_12_Validation,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"type\")\n  CHECK_VOCABULARY_WITH_ORDER_DEPENDENCIES(\n      Known::JSON_Schema_2019_09_Validation,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"type\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_exclusiveMaximum(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_exclusiveMinimum(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_7_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_6_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_4_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maxLength(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minLength(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_pattern(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::String}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::String}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::String}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maxItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_uniqueItems(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Array}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Array}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Array}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maxProperties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minProperties(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_required(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::Object}), Assertion,\n                                     \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_dependentRequired(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Object}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minContains(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maxContains(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Validation,\n                   make_set({JSON::Type::Array}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_title(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Comment)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_description(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Comment)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_default(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Comment)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_deprecated(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_readOnly(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_writeOnly(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_examples(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Meta_Data, {}, Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Comment, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6, {}, Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Comment, \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_format(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Format_Assertion,\n                   make_set({JSON::Type::String}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Format_Annotation,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Format,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Other,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Other,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4,\n                                     make_set({JSON::Type::String}), Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper,\n                                     make_set({JSON::Type::String}), Other,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3,\n                                     make_set({JSON::Type::String}), Other,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper,\n                                     make_set({JSON::Type::String}), Other,\n                                     \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::String}),\n                   Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::String}), Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::String}),\n                   Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::String}), Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::String}),\n                   Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::String}), Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_contentSchema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Content,\n                   make_set({JSON::Type::String}), ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Content,\n                   make_set({JSON::Type::String}), ApplicatorValueInPlaceOther)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_contentMediaType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Content,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Content,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Comment,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Comment,\n                                     \"$ref\")\n  return UNKNOWN_RESULT;\n}\n\nauto handle_contentEncoding(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2020_12_Content,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Content,\n                   make_set({JSON::Type::String}), Annotation)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7,\n                                     make_set({JSON::Type::String}), Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper,\n                                     make_set({JSON::Type::String}), Comment,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6,\n                                     make_set({JSON::Type::String}), Comment,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper,\n                                     make_set({JSON::Type::String}), Comment,\n                                     \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  if (vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_4)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::String}),\n                   Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::String}), Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::String}),\n                   Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::String}), Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::String}),\n                   Comment)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::String}), Comment)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_extends(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {},\n                                     ApplicatorValueOrElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     ApplicatorValueOrElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {},\n                   ApplicatorValueOrElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {},\n                   ApplicatorValueOrElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {},\n                   ApplicatorValueOrElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {},\n                   ApplicatorValueOrElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {},\n                   ApplicatorValueOrElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {},\n                   ApplicatorValueOrElementsInPlace)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_disallow(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3, {},\n                                     ApplicatorElementsInPlaceSomeNegate,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     ApplicatorElementsInPlaceSomeNegate,\n                                     (\"$ref\"))\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, {}, Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_divisibleBy(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(\n      Known::JSON_Schema_Draft_3_Hyper,\n      make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maximumCanEqual(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_minimumCanEqual(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Integer, JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_requires(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Object}),\n                   ApplicatorValueTraverseParent)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_optional(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2, make_set({JSON::Type::Object}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Object}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Object}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Object}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Object}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_maxDecimal(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1, make_set({JSON::Type::Real}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper,\n                   make_set({JSON::Type::Real}), Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0, make_set({JSON::Type::Real}),\n                   Assertion)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper,\n                   make_set({JSON::Type::Real}), Assertion)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_links(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     ApplicatorElementsInPlace, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {},\n                   ApplicatorElementsInPlace)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_base(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_7_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Other, \"$ref\")\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_anchor(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_anchorPointer(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_rel(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_href(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_templatePointers(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_templateRequired(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_targetMediaType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_targetHints(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_submissionMediaType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_hrefSchema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_targetSchema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_headerSchema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_submissionSchema(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_2019_09_Hyper_Schema, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_7_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_media(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_6_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Other, \"$ref\")\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_fragmentResolution(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_root(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_readonly(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_pathStart(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_4_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_mediaType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Other)\n  CHECK_VOCABULARY_WITH_DEPENDENCIES(Known::JSON_Schema_Draft_3_Hyper, {},\n                                     Other, \"$ref\")\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_alternate(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {},\n                   ApplicatorElementsInPlace)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {},\n                   ApplicatorElementsInPlace)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_method(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_enctype(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_3_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_2_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_1_Hyper, {}, Other)\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_0_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_encType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_submissionEncType(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_6_Hyper, {}, Other)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\nauto handle_schema_hyper(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::JSON_Schema_Draft_4_Hyper, {},\n                   ApplicatorValueInPlaceOther)\n  if (has_draft3_to_7(vocabularies)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n  return UNKNOWN_RESULT;\n}\n\n// OpenAPI 3.1/3.2 Base Vocabulary\n// https://spec.openapis.org/oas/v3.1.0.html#fixed-fields-19\n// https://spec.openapis.org/oas/v3.2.0.html#fixed-fields-20\n\nauto handle_discriminator(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::OpenAPI_3_2_Base, {}, Other)\n  CHECK_VOCABULARY(Known::OpenAPI_3_1_Base, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_xml(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::OpenAPI_3_2_Base, {}, Other)\n  CHECK_VOCABULARY(Known::OpenAPI_3_1_Base, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_externalDocs(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::OpenAPI_3_2_Base, {}, Other)\n  CHECK_VOCABULARY(Known::OpenAPI_3_1_Base, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\nauto handle_example(const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  CHECK_VOCABULARY(Known::OpenAPI_3_2_Base, {}, Other)\n  CHECK_VOCABULARY(Known::OpenAPI_3_1_Base, {}, Other)\n  return UNKNOWN_RESULT;\n}\n\n#undef RETURN_WITH_DEPENDENCIES\n#undef RETURN\n#undef CHECK_VOCABULARY_WITH_DEPENDENCIES\n#undef CHECK_VOCABULARY\n\n} // anonymous namespace\n\nauto schema_walker(const std::string_view keyword,\n                   const Vocabularies &vocabularies)\n    -> const SchemaWalkerResult & {\n  // TODO: Make use of JSON key's perfect hashes, as we mostly run the walker by\n  // checking JSON property names\n  static const std::unordered_map<std::string_view, KeywordHandler> handlers{\n      {\"$id\", handle_dollar_id},\n      {\"$schema\", handle_dollar_schema},\n      {\"$ref\", handle_dollar_ref},\n      {\"$defs\", handle_dollar_defs},\n      {\"definitions\", handle_definitions},\n      {\"$comment\", handle_dollar_comment},\n      {\"$anchor\", handle_dollar_anchor},\n      {\"$vocabulary\", handle_dollar_vocabulary},\n      {\"$dynamicRef\", handle_dollar_dynamicRef},\n      {\"$dynamicAnchor\", handle_dollar_dynamicAnchor},\n      {\"$recursiveRef\", handle_dollar_recursiveRef},\n      {\"$recursiveAnchor\", handle_dollar_recursiveAnchor},\n      {\"id\", handle_id},\n      {\"oneOf\", handle_oneOf},\n      {\"anyOf\", handle_anyOf},\n      {\"allOf\", handle_allOf},\n      {\"if\", handle_if},\n      {\"then\", handle_then},\n      {\"else\", handle_else},\n      {\"not\", handle_not},\n      {\"properties\", handle_properties},\n      {\"additionalProperties\", handle_additionalProperties},\n      {\"patternProperties\", handle_patternProperties},\n      {\"propertyNames\", handle_propertyNames},\n      {\"dependentSchemas\", handle_dependentSchemas},\n      {\"dependencies\", handle_dependencies},\n      {\"contains\", handle_contains},\n      {\"items\", handle_items},\n      {\"prefixItems\", handle_prefixItems},\n      {\"additionalItems\", handle_additionalItems},\n      {\"unevaluatedProperties\", handle_unevaluatedProperties},\n      {\"unevaluatedItems\", handle_unevaluatedItems},\n      {\"type\", handle_type},\n      {\"enum\", handle_enum},\n      {\"const\", handle_const},\n      {\"multipleOf\", handle_multipleOf},\n      {\"maximum\", handle_maximum},\n      {\"minimum\", handle_minimum},\n      {\"exclusiveMaximum\", handle_exclusiveMaximum},\n      {\"exclusiveMinimum\", handle_exclusiveMinimum},\n      {\"maxLength\", handle_maxLength},\n      {\"minLength\", handle_minLength},\n      {\"pattern\", handle_pattern},\n      {\"maxItems\", handle_maxItems},\n      {\"minItems\", handle_minItems},\n      {\"uniqueItems\", handle_uniqueItems},\n      {\"maxProperties\", handle_maxProperties},\n      {\"minProperties\", handle_minProperties},\n      {\"required\", handle_required},\n      {\"dependentRequired\", handle_dependentRequired},\n      {\"minContains\", handle_minContains},\n      {\"maxContains\", handle_maxContains},\n      {\"title\", handle_title},\n      {\"description\", handle_description},\n      {\"default\", handle_default},\n      {\"deprecated\", handle_deprecated},\n      {\"readOnly\", handle_readOnly},\n      {\"writeOnly\", handle_writeOnly},\n      {\"examples\", handle_examples},\n      {\"format\", handle_format},\n      {\"contentSchema\", handle_contentSchema},\n      {\"contentMediaType\", handle_contentMediaType},\n      {\"contentEncoding\", handle_contentEncoding},\n      {\"extends\", handle_extends},\n      {\"disallow\", handle_disallow},\n      {\"divisibleBy\", handle_divisibleBy},\n      {\"maximumCanEqual\", handle_maximumCanEqual},\n      {\"minimumCanEqual\", handle_minimumCanEqual},\n      {\"requires\", handle_requires},\n      {\"optional\", handle_optional},\n      {\"maxDecimal\", handle_maxDecimal},\n      {\"links\", handle_links},\n      {\"base\", handle_base},\n      {\"anchor\", handle_anchor},\n      {\"anchorPointer\", handle_anchorPointer},\n      {\"rel\", handle_rel},\n      {\"href\", handle_href},\n      {\"templatePointers\", handle_templatePointers},\n      {\"templateRequired\", handle_templateRequired},\n      {\"targetMediaType\", handle_targetMediaType},\n      {\"targetHints\", handle_targetHints},\n      {\"submissionMediaType\", handle_submissionMediaType},\n      {\"hrefSchema\", handle_hrefSchema},\n      {\"targetSchema\", handle_targetSchema},\n      {\"headerSchema\", handle_headerSchema},\n      {\"submissionSchema\", handle_submissionSchema},\n      {\"media\", handle_media},\n      {\"fragmentResolution\", handle_fragmentResolution},\n      {\"root\", handle_root},\n      {\"readonly\", handle_readonly},\n      {\"pathStart\", handle_pathStart},\n      {\"mediaType\", handle_mediaType},\n      {\"alternate\", handle_alternate},\n      {\"method\", handle_method},\n      {\"enctype\", handle_enctype},\n      {\"encType\", handle_encType},\n      {\"submissionEncType\", handle_submissionEncType},\n      {\"schema\", handle_schema_hyper},\n      // OpenAPI\n      {\"discriminator\", handle_discriminator},\n      {\"xml\", handle_xml},\n      {\"externalDocs\", handle_externalDocs},\n      {\"example\", handle_example},\n  };\n\n  const auto iterator = handlers.find(keyword);\n  if (iterator != handlers.end()) {\n    return iterator->second(vocabularies);\n  }\n\n  if (vocabularies.contains(Known::JSON_Schema_Draft_7) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_7_Hyper) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_6) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_6_Hyper) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_4) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_4_Hyper) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_3) ||\n      vocabularies.contains(Known::JSON_Schema_Draft_3_Hyper)) {\n    return UNKNOWN_WITH_REF_RESULT;\n  }\n\n  return UNKNOWN_RESULT;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/vocabularies.cc",
    "content": "#include <sourcemeta/core/jsonschema_vocabularies.h>\n\n#include <sourcemeta/core/jsonschema_error.h>\n\n#include <cassert>  // assert\n#include <optional> // std::optional\n#include <sstream>  // std::ostringstream\n#include <string>   // std::string\n#include <utility>  // std::pair, std::to_underlying\n#include <vector>   // std::vector\n\n// X-macro defining all known vocabulary mappings (enum, URI)\n// Ordered from most recent/common to oldest for faster short-circuiting\n#define SOURCEMETA_VOCABULARIES_X(X)                                           \\\n  /* 2020-12 vocabularies (most recent/common) */                              \\\n  X(JSON_Schema_2020_12_Core,                                                  \\\n    \"https://json-schema.org/draft/2020-12/vocab/core\")                        \\\n  X(JSON_Schema_2020_12_Applicator,                                            \\\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\")                  \\\n  X(JSON_Schema_2020_12_Unevaluated,                                           \\\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\")                 \\\n  X(JSON_Schema_2020_12_Validation,                                            \\\n    \"https://json-schema.org/draft/2020-12/vocab/validation\")                  \\\n  X(JSON_Schema_2020_12_Meta_Data,                                             \\\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\")                   \\\n  X(JSON_Schema_2020_12_Format_Annotation,                                     \\\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\")           \\\n  X(JSON_Schema_2020_12_Format_Assertion,                                      \\\n    \"https://json-schema.org/draft/2020-12/vocab/format-assertion\")            \\\n  X(JSON_Schema_2020_12_Content,                                               \\\n    \"https://json-schema.org/draft/2020-12/vocab/content\")                     \\\n  /* 2019-09 vocabularies */                                                   \\\n  X(JSON_Schema_2019_09_Core,                                                  \\\n    \"https://json-schema.org/draft/2019-09/vocab/core\")                        \\\n  X(JSON_Schema_2019_09_Applicator,                                            \\\n    \"https://json-schema.org/draft/2019-09/vocab/applicator\")                  \\\n  X(JSON_Schema_2019_09_Validation,                                            \\\n    \"https://json-schema.org/draft/2019-09/vocab/validation\")                  \\\n  X(JSON_Schema_2019_09_Meta_Data,                                             \\\n    \"https://json-schema.org/draft/2019-09/vocab/meta-data\")                   \\\n  X(JSON_Schema_2019_09_Format,                                                \\\n    \"https://json-schema.org/draft/2019-09/vocab/format\")                      \\\n  X(JSON_Schema_2019_09_Content,                                               \\\n    \"https://json-schema.org/draft/2019-09/vocab/content\")                     \\\n  X(JSON_Schema_2019_09_Hyper_Schema,                                          \\\n    \"https://json-schema.org/draft/2019-09/vocab/hyper-schema\")                \\\n  /* Pre-vocabulary dialects (least common, checked last) */                   \\\n  X(JSON_Schema_Draft_7, \"http://json-schema.org/draft-07/schema#\")            \\\n  X(JSON_Schema_Draft_7_Hyper,                                                 \\\n    \"http://json-schema.org/draft-07/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_6, \"http://json-schema.org/draft-06/schema#\")            \\\n  X(JSON_Schema_Draft_6_Hyper,                                                 \\\n    \"http://json-schema.org/draft-06/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_4, \"http://json-schema.org/draft-04/schema#\")            \\\n  X(JSON_Schema_Draft_4_Hyper,                                                 \\\n    \"http://json-schema.org/draft-04/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_3, \"http://json-schema.org/draft-03/schema#\")            \\\n  X(JSON_Schema_Draft_3_Hyper,                                                 \\\n    \"http://json-schema.org/draft-03/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_2, \"http://json-schema.org/draft-02/schema#\")            \\\n  X(JSON_Schema_Draft_2_Hyper,                                                 \\\n    \"http://json-schema.org/draft-02/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_1, \"http://json-schema.org/draft-01/schema#\")            \\\n  X(JSON_Schema_Draft_1_Hyper,                                                 \\\n    \"http://json-schema.org/draft-01/hyper-schema#\")                           \\\n  X(JSON_Schema_Draft_0, \"http://json-schema.org/draft-00/schema#\")            \\\n  X(JSON_Schema_Draft_0_Hyper,                                                 \\\n    \"http://json-schema.org/draft-00/hyper-schema#\")                           \\\n  /* OpenAPI vocabularies */                                                   \\\n  X(OpenAPI_3_1_Base, \"https://spec.openapis.org/oas/3.1/vocab/base\")          \\\n  X(OpenAPI_3_2_Base, \"https://spec.openapis.org/oas/3.2/vocab/base\")\n\nnamespace {\nauto uri_to_known_vocabulary(const std::string_view uri)\n    -> std::optional<sourcemeta::core::Vocabularies::Known> {\n  using sourcemeta::core::Vocabularies;\n\n// NOLINTNEXTLINE(bugprone-macro-parentheses)\n#define X_URI_TO_ENUM(enumerator, uri_string)                                  \\\n  if (uri == (uri_string)) {                                                   \\\n    return Vocabularies::Known::enumerator;                                    \\\n  }\n\n  SOURCEMETA_VOCABULARIES_X(X_URI_TO_ENUM)\n\n#undef X_URI_TO_ENUM\n\n  return std::nullopt;\n}\n} // anonymous namespace\n\nsourcemeta::core::Vocabularies::Vocabularies(\n    std::initializer_list<std::pair<JSON::String, bool>> init) {\n  for (const auto &entry : init) {\n    this->insert(entry.first, entry.second);\n  }\n}\n\nsourcemeta::core::Vocabularies::Vocabularies(\n    std::initializer_list<std::pair<Known, bool>> init) {\n  for (const auto &entry : init) {\n    this->insert(entry.first, entry.second);\n  }\n}\n\nauto sourcemeta::core::Vocabularies::contains(\n    const JSON::String &uri) const noexcept -> bool {\n  if (this->unknown.has_value()) {\n    if (this->unknown->contains(uri)) {\n      return true;\n    }\n  }\n\n  const auto maybe_known{uri_to_known_vocabulary(uri)};\n  // As a debug build check: Going through this branch is slow. If it is a\n  // known vocabulary, the consumer should be making use of the enum overload\n  // of this method\n  assert(!maybe_known.has_value());\n  if (maybe_known.has_value()) {\n    return this->contains(maybe_known.value());\n  }\n\n  return false;\n}\n\nauto sourcemeta::core::Vocabularies::contains(Known vocabulary) const noexcept\n    -> bool {\n  const auto index = std::to_underlying(vocabulary);\n  // Use [] operator instead of test() to avoid exceptions in noexcept function\n  return this->required_known[index] || this->optional_known[index];\n}\n\nauto sourcemeta::core::Vocabularies::contains_any(\n    std::initializer_list<Known> vocabularies) const noexcept -> bool {\n  for (const auto &vocabulary : vocabularies) {\n    if (this->contains(vocabulary)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nauto sourcemeta::core::Vocabularies::insert(const JSON::String &uri,\n                                            bool required) noexcept -> void {\n  // We NEED to allow official vocabulary string URIs here, as that's how\n  // we construct the optimised version!\n  const auto maybe_known = uri_to_known_vocabulary(uri);\n  if (maybe_known.has_value()) {\n    this->insert(maybe_known.value(), required);\n  } else {\n    if (!this->unknown.has_value()) {\n      this->unknown.emplace();\n    }\n    this->unknown->insert({uri, required});\n  }\n}\n\nauto sourcemeta::core::Vocabularies::insert(Known vocabulary,\n                                            bool required) noexcept -> void {\n  const auto index = std::to_underlying(vocabulary);\n  if (required) {\n    this->required_known[index] = true;\n    this->optional_known[index] = false;\n  } else {\n    this->optional_known[index] = true;\n    this->required_known[index] = false;\n  }\n  // Verify invariant: vocabulary cannot be both required and optional\n  assert((this->required_known & this->optional_known).none());\n}\n\nauto sourcemeta::core::Vocabularies::get(const JSON::String &uri) const noexcept\n    -> std::optional<bool> {\n  if (this->unknown.has_value()) {\n    const auto iterator{this->unknown->find(uri)};\n    if (iterator != this->unknown->end()) {\n      return iterator->second;\n    }\n  }\n\n  const auto maybe_known{uri_to_known_vocabulary(uri)};\n  // As a debug build check: Going through this branch is slow. If it is a\n  // known vocabulary, the consumer should be making use of the enum overload\n  // of this method\n  assert(!maybe_known.has_value());\n  if (maybe_known.has_value()) {\n    return this->get(maybe_known.value());\n  }\n\n  return std::nullopt;\n}\n\nauto sourcemeta::core::Vocabularies::get(Known vocabulary) const noexcept\n    -> std::optional<bool> {\n  const auto index = std::to_underlying(vocabulary);\n  // Use [] operator instead of test() to avoid exceptions in noexcept function\n  assert(!this->required_known[index] || !this->optional_known[index]);\n  if (this->required_known[index]) {\n    return true;\n  }\n  if (this->optional_known[index]) {\n    return false;\n  }\n  return std::nullopt;\n}\n\nauto sourcemeta::core::Vocabularies::size() const noexcept -> std::size_t {\n  return (this->required_known | this->optional_known).count() +\n         (this->unknown.has_value() ? this->unknown->size() : 0);\n}\n\nauto sourcemeta::core::Vocabularies::empty() const noexcept -> bool {\n  return this->required_known.none() && this->optional_known.none() &&\n         !this->has_unknown();\n}\n\nauto sourcemeta::core::Vocabularies::has_unknown() const noexcept -> bool {\n  return this->unknown.has_value() && !this->unknown.value().empty();\n}\n\nauto sourcemeta::core::operator<<(std::ostream &stream,\n                                  Vocabularies::Known vocabulary)\n    -> std::ostream & {\n  switch (vocabulary) {\n// NOLINTNEXTLINE(bugprone-macro-parentheses)\n#define X_ENUM_TO_URI(enumerator, uri_string)                                  \\\n  case Vocabularies::Known::enumerator:                                        \\\n    return stream << (uri_string);\n\n    SOURCEMETA_VOCABULARIES_X(X_ENUM_TO_URI)\n\n#undef X_ENUM_TO_URI\n  }\n\n  assert(false);\n  return stream;\n}\n\nauto sourcemeta::core::to_string(Vocabularies::Known vocabulary)\n    -> std::string_view {\n  switch (vocabulary) {\n// NOLINTNEXTLINE(bugprone-macro-parentheses)\n#define X_ENUM_TO_URI(enumerator, uri_string)                                  \\\n  case Vocabularies::Known::enumerator:                                        \\\n    return (uri_string);\n\n    SOURCEMETA_VOCABULARIES_X(X_ENUM_TO_URI)\n\n#undef X_ENUM_TO_URI\n  }\n\n  assert(false);\n  return {};\n}\n\nauto sourcemeta::core::to_string(const Vocabularies::URI &vocabulary)\n    -> std::string_view {\n  const auto *known{std::get_if<Vocabularies::Known>(&vocabulary)};\n  if (known) {\n    return to_string(*known);\n  } else {\n    return *std::get_if<JSON::String>(&vocabulary);\n  }\n}\n\nauto sourcemeta::core::operator<<(std::ostream &stream,\n                                  const Vocabularies::URI &vocabulary)\n    -> std::ostream & {\n  return stream << to_string(vocabulary);\n}\n\nauto sourcemeta::core::Vocabularies::throw_if_any_unsupported(\n    const std::unordered_set<URI> &supported, const char *message) const\n    -> void {\n  for (std::size_t index = 0; index < KNOWN_VOCABULARY_COUNT; ++index) {\n    if (!this->required_known[index]) {\n      continue;\n    }\n\n    const auto vocabulary{static_cast<Known>(index)};\n    if (supported.contains(vocabulary)) {\n      continue;\n    }\n\n    // Slow fallback: convert to string URI and check if it was passed as string\n    std::ostringstream stream;\n    stream << vocabulary;\n    const auto &uri{stream.str()};\n\n    if (supported.contains(uri)) {\n      // As a debug build check: Going through this branch is slow. If it is a\n      // known vocabulary, the consumer should be passing it as an enum class\n      assert(false);\n      continue;\n    }\n\n    throw SchemaVocabularyError(uri, message);\n  }\n\n  if (this->unknown.has_value()) {\n    for (const auto &[uri, required] : *this->unknown) {\n      if (!required || supported.contains(uri)) {\n        continue;\n      }\n\n      // This case should never be possible, as an invariant of this class.\n      // i.e. we should never have an official vocabulary in the unknown map\n      assert(!uri_to_known_vocabulary(uri).has_value());\n\n      throw SchemaVocabularyError(uri, message);\n    }\n  }\n}\n\nauto sourcemeta::core::Vocabularies::throw_if_any_unknown_required(\n    const char *message) const -> void {\n  if (this->unknown.has_value()) {\n    for (const auto &[uri, required] : this->unknown.value()) {\n      if (required) {\n        throw SchemaVocabularyError(uri, message);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/src/core/jsonschema/walker.cc",
    "content": "#include <sourcemeta/core/jsonschema.h>\n\n#include \"helpers.h\"\n\n#include <algorithm> // std::max, std::sort\n#include <cassert>   // assert\n\nnamespace {\nenum class SchemaWalkerType_t : std::uint8_t { Deep, Flat };\n\nstruct DialectInfo {\n  std::string_view dialect;\n  sourcemeta::core::SchemaBaseDialect base_dialect;\n  bool override_active;\n};\n\nauto resolve_dialect_at(\n    const sourcemeta::core::JSON &subschema,\n    const std::string_view inherited_dialect,\n    const sourcemeta::core::SchemaBaseDialect inherited_base,\n    const sourcemeta::core::SchemaResolver &resolver, const std::size_t level,\n    const bool allow_dialect_override) -> DialectInfo {\n  auto local{sourcemeta::core::dialect(subschema, inherited_dialect,\n                                       allow_dialect_override)};\n  const auto override_active{\n      local != sourcemeta::core::dialect(subschema, inherited_dialect, false)};\n  auto id{sourcemeta::core::identify(subschema, resolver, local, \"\",\n                                     allow_dialect_override)};\n  if (id.empty() && local != inherited_dialect && !override_active) {\n    id = sourcemeta::core::identify(subschema, inherited_base);\n    if (!id.empty()) {\n      local = inherited_dialect;\n    }\n  }\n  if (!override_active && level > 0 && id.empty()) {\n    return {.dialect = inherited_dialect,\n            .base_dialect = inherited_base,\n            .override_active = false};\n  }\n  const auto resolved_base{\n      local != inherited_dialect\n          ? sourcemeta::core::base_dialect(subschema, resolver, local,\n                                           allow_dialect_override)\n                .value_or(inherited_base)\n          : inherited_base};\n  return {.dialect = local,\n          .base_dialect = resolved_base,\n          .override_active = override_active};\n}\n\nauto walk(const std::optional<sourcemeta::core::WeakPointer> &parent,\n          const sourcemeta::core::WeakPointer &pointer,\n          std::vector<sourcemeta::core::SchemaIteratorEntry> &subschemas,\n          const sourcemeta::core::JSON &subschema,\n          const sourcemeta::core::SchemaWalker &walker,\n          const sourcemeta::core::SchemaResolver &resolver,\n          const std::string_view dialect,\n          const sourcemeta::core::SchemaBaseDialect base_dialect,\n          const SchemaWalkerType_t type, const std::size_t level,\n          const bool orphan, const bool property_name) -> void {\n  if (!is_schema(subschema)) {\n    return;\n  }\n\n  // Recalculate the dialect and its vocabularies at every step.\n  // This is needed for correctly traversing through schemas that\n  // contains pointers that use different dialect/vocabularies.\n  // This is often the case for bundled schemas.\n\n  // However, we need to be careful with not considering `$schema` on subschemas\n  // that do not represent schema resources, as this is not allowed in JSON\n  // Schema. See\n  // https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.1.1\n  // To play it safe, in those cases, we will continue with the current dialect\n  // / base dialect and ignore the invalid standalone `$schema`. The caller has\n  // enough information to detect those cases and throw an error if they desire\n  // to be more strict.\n\n  const auto enclosing_ref_overrides{\n      subschema.is_object() && subschema.defines(\"$ref\") &&\n      sourcemeta::core::ref_overrides_adjacent_keywords(base_dialect)};\n\n  const auto entry{resolve_dialect_at(subschema, dialect, base_dialect,\n                                      resolver, level,\n                                      !enclosing_ref_overrides)};\n  const auto current_dialect{entry.dialect};\n  const auto current_base_dialect{entry.base_dialect};\n\n  const auto vocabularies{sourcemeta::core::vocabularies(\n      resolver, current_base_dialect, current_dialect)};\n\n  if (type == SchemaWalkerType_t::Deep || level > 0) {\n    sourcemeta::core::SchemaIteratorEntry iterator_entry{\n        .parent = parent,\n        .pointer = pointer,\n        .dialect = current_dialect,\n        .vocabularies = vocabularies,\n        .base_dialect = current_base_dialect,\n        .subschema = subschema,\n        .orphan = orphan,\n        .property_name = property_name};\n    subschemas.push_back(std::move(iterator_entry));\n  }\n\n  // We can't recurse any further\n  if (!subschema.is_object() ||\n      (type == SchemaWalkerType_t::Flat && level > 0)) {\n    return;\n  }\n\n  const auto child{entry.override_active\n                       ? resolve_dialect_at(subschema, dialect, base_dialect,\n                                            resolver, level, false)\n                       : entry};\n  const auto child_dialect{child.dialect};\n  const auto child_base_dialect{child.base_dialect};\n\n  const auto has_overriding_ref{\n      subschema.defines(\"$ref\") &&\n      sourcemeta::core::ref_overrides_adjacent_keywords(current_base_dialect)};\n  for (auto &pair : subschema.as_object()) {\n    const auto &keyword_info{walker(pair.first, vocabularies)};\n\n    // Ignore the current keyword sibling to `$ref in Draft 7 and older in EVERY\n    // case. Note that we purposely DO NOT try to add workarounds for the\n    // top-level, `$schema`, or anything else to be purely compliant and avoid\n    // lots of gray areas here\n    if (has_overriding_ref &&\n        keyword_info.type != sourcemeta::core::SchemaKeywordType::Reference) {\n      continue;\n    }\n\n    switch (keyword_info.type) {\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueTraverseSomeProperty: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan, false);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueTraverseAnyPropertyKey: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan, true);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueTraverseAnyItem: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan, false);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueTraverseSomeItem: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan, false);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorValueTraverseParent: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan, false);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlaceOther: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan,\n             property_name);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlaceNegate: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan,\n             property_name);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlaceMaybe: {\n        sourcemeta::core::WeakPointer new_pointer{pointer};\n        new_pointer.push_back(std::cref(pair.first));\n        walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n             child_dialect, child_base_dialect, type, level + 1, orphan,\n             property_name);\n      } break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsTraverseItem:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, false);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsInPlace:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, property_name);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorElementsInPlaceSome:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, property_name);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorElementsInPlaceSomeNegate:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, property_name);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorMembersTraversePropertyStatic:\n        if (pair.second.is_object()) {\n          for (auto &subpair : pair.second.as_object()) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.push_back(std::cref(subpair.first));\n            walk(pointer, new_pointer, subschemas, subpair.second, walker,\n                 resolver, child_dialect, child_base_dialect, type, level + 1,\n                 orphan, false);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorMembersTraversePropertyRegex:\n        if (pair.second.is_object()) {\n          for (auto &subpair : pair.second.as_object()) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.push_back(std::cref(subpair.first));\n            walk(pointer, new_pointer, subschemas, subpair.second, walker,\n                 resolver, child_dialect, child_base_dialect, type, level + 1,\n                 orphan, false);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::ApplicatorMembersInPlaceSome:\n        if (pair.second.is_object()) {\n          for (auto &subpair : pair.second.as_object()) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.push_back(std::cref(subpair.first));\n            walk(pointer, new_pointer, subschemas, subpair.second, walker,\n                 resolver, child_dialect, child_base_dialect, type, level + 1,\n                 orphan, property_name);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::LocationMembers:\n        if (pair.second.is_object()) {\n          for (auto &subpair : pair.second.as_object()) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.push_back(std::cref(subpair.first));\n            walk(pointer, new_pointer, subschemas, subpair.second, walker,\n                 resolver, child_dialect, child_base_dialect, type, level + 1,\n                 true, false);\n          }\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueOrElementsTraverseAnyItemOrItem:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, false);\n          }\n        } else {\n          sourcemeta::core::WeakPointer new_pointer{pointer};\n          new_pointer.push_back(std::cref(pair.first));\n          walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n               child_dialect, child_base_dialect, type, level + 1, orphan,\n               false);\n        }\n\n        break;\n\n      case sourcemeta::core::SchemaKeywordType::\n          ApplicatorValueOrElementsInPlace:\n        if (pair.second.is_array()) {\n          for (std::size_t index = 0; index < pair.second.size(); index++) {\n            sourcemeta::core::WeakPointer new_pointer{pointer};\n            new_pointer.push_back(std::cref(pair.first));\n            new_pointer.emplace_back(index);\n            walk(pointer, new_pointer, subschemas, pair.second.at(index),\n                 walker, resolver, child_dialect, child_base_dialect, type,\n                 level + 1, orphan, property_name);\n          }\n        } else {\n          sourcemeta::core::WeakPointer new_pointer{pointer};\n          new_pointer.push_back(std::cref(pair.first));\n          walk(pointer, new_pointer, subschemas, pair.second, walker, resolver,\n               child_dialect, child_base_dialect, type, level + 1, orphan,\n               property_name);\n        }\n\n        break;\n      case sourcemeta::core::SchemaKeywordType::Assertion:\n      case sourcemeta::core::SchemaKeywordType::Annotation:\n      case sourcemeta::core::SchemaKeywordType::Reference:\n      case sourcemeta::core::SchemaKeywordType::Other:\n      case sourcemeta::core::SchemaKeywordType::Comment:\n      case sourcemeta::core::SchemaKeywordType::Unknown:\n        break;\n    }\n  }\n}\n} // namespace\n\n// TODO: These iterators are not very efficient. They traverse once on\n// construction and then the client traverses again.\n\nsourcemeta::core::SchemaIterator::SchemaIterator(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver,\n    std::string_view default_dialect) {\n  const std::string_view resolved_dialect{\n      sourcemeta::core::dialect(schema, default_dialect)};\n\n  sourcemeta::core::WeakPointer pointer;\n  // If the given schema declares no dialect and the user didn't\n  // not pass a default, then there is nothing we can do. We know\n  // the current schema is a subschema, but cannot walk any further.\n  if (resolved_dialect.empty()) {\n    sourcemeta::core::SchemaIteratorEntry entry{.parent = std::nullopt,\n                                                .pointer = pointer,\n                                                .dialect = \"\",\n                                                .vocabularies = {},\n                                                .base_dialect = std::nullopt,\n                                                .subschema = schema,\n                                                .orphan = false,\n                                                .property_name = false};\n    this->subschemas.push_back(std::move(entry));\n  } else {\n    const auto resolved_base_dialect{\n        sourcemeta::core::base_dialect(schema, resolver, resolved_dialect)};\n    assert(resolved_base_dialect.has_value());\n    walk(std::nullopt, pointer, this->subschemas, schema, walker, resolver,\n         resolved_dialect, resolved_base_dialect.value(),\n         SchemaWalkerType_t::Deep, 0, false, false);\n  }\n}\n\nsourcemeta::core::SchemaIteratorFlat::SchemaIteratorFlat(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver,\n    const std::string_view default_dialect) {\n  const std::string_view resolved_dialect{\n      sourcemeta::core::dialect(schema, default_dialect)};\n  if (!resolved_dialect.empty()) {\n    sourcemeta::core::WeakPointer pointer;\n    const auto resolved_base_dialect{\n        sourcemeta::core::base_dialect(schema, resolver, resolved_dialect)};\n    assert(resolved_base_dialect.has_value());\n    walk(std::nullopt, pointer, this->subschemas, schema, walker, resolver,\n         resolved_dialect, resolved_base_dialect.value(),\n         SchemaWalkerType_t::Flat, 0, false, false);\n  }\n}\n\nsourcemeta::core::SchemaKeywordIterator::SchemaKeywordIterator(\n    const sourcemeta::core::JSON &schema,\n    const sourcemeta::core::SchemaWalker &walker,\n    const sourcemeta::core::SchemaResolver &resolver,\n    const std::string_view default_dialect) {\n  assert(is_schema(schema));\n  if (schema.is_boolean()) {\n    return;\n  }\n\n  const std::string_view resolved_dialect{\n      sourcemeta::core::dialect(schema, default_dialect)};\n  const auto maybe_base_dialect{\n      sourcemeta::core::base_dialect(schema, resolver, resolved_dialect)};\n\n  Vocabularies vocabularies{\n      maybe_base_dialect.has_value() && !resolved_dialect.empty()\n          ? sourcemeta::core::vocabularies(resolver, maybe_base_dialect.value(),\n                                           resolved_dialect)\n          : Vocabularies{}};\n\n  // TODO: Use std::ranges::to<std::vector>() once libc++ supports it\n  // (__cpp_lib_ranges_to_container)\n  for (const auto &entry : schema.as_object()) {\n    sourcemeta::core::WeakPointer entry_pointer;\n    entry_pointer.push_back(std::cref(entry.first));\n    sourcemeta::core::SchemaIteratorEntry subschema_entry{\n        .parent = std::nullopt,\n        .pointer = std::move(entry_pointer),\n        .dialect = resolved_dialect,\n        .vocabularies = vocabularies,\n        .base_dialect = maybe_base_dialect,\n        .subschema = entry.second,\n        .orphan = false,\n        .property_name = false};\n    this->entries.push_back(std::move(subschema_entry));\n  }\n\n  // Sort keywords based on priority for correct evaluation\n  std::ranges::sort(\n      this->entries,\n      [&vocabularies, &walker](const auto &left, const auto &right) -> bool {\n        // These cannot be empty or indexes, as we created\n        // the entries array from a JSON object\n        assert(!left.pointer.empty() && left.pointer.back().is_property());\n        assert(!right.pointer.empty() && right.pointer.back().is_property());\n\n        const auto left_priority = schema_keyword_priority(\n            left.pointer.back().to_property(), vocabularies, walker);\n        const auto right_priority = schema_keyword_priority(\n            right.pointer.back().to_property(), vocabularies, walker);\n\n        // Sort first on priority, second on actual keywords. The latter is to\n        // make sure different compilers with different STL implementations end\n        // up at the exact same result. Not really mandatory, but useful for\n        // writing tests on the iterator output.\n        if (left_priority != right_priority) {\n          return left_priority < right_priority;\n        } else {\n          return left.pointer < right.pointer;\n        }\n      });\n}\n\nauto sourcemeta::core::SchemaIterator::begin() const -> const_iterator {\n  return this->subschemas.begin();\n}\nauto sourcemeta::core::SchemaIterator::end() const -> const_iterator {\n  return this->subschemas.end();\n}\nauto sourcemeta::core::SchemaIterator::cbegin() const -> const_iterator {\n  return this->subschemas.cbegin();\n}\nauto sourcemeta::core::SchemaIterator::cend() const -> const_iterator {\n  return this->subschemas.cend();\n}\n\nauto sourcemeta::core::SchemaIteratorFlat::begin() const -> const_iterator {\n  return this->subschemas.begin();\n}\nauto sourcemeta::core::SchemaIteratorFlat::end() const -> const_iterator {\n  return this->subschemas.end();\n}\nauto sourcemeta::core::SchemaIteratorFlat::cbegin() const -> const_iterator {\n  return this->subschemas.cbegin();\n}\nauto sourcemeta::core::SchemaIteratorFlat::cend() const -> const_iterator {\n  return this->subschemas.cend();\n}\n\nauto sourcemeta::core::SchemaKeywordIterator::begin() const -> const_iterator {\n  return this->entries.begin();\n}\nauto sourcemeta::core::SchemaKeywordIterator::end() const -> const_iterator {\n  return this->entries.end();\n}\nauto sourcemeta::core::SchemaKeywordIterator::cbegin() const -> const_iterator {\n  return this->entries.cbegin();\n}\nauto sourcemeta::core::SchemaKeywordIterator::cend() const -> const_iterator {\n  return this->entries.cend();\n}\n"
  },
  {
    "path": "vendor/core/src/core/markdown/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME markdown\n  SOURCES markdown.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME markdown)\nendif()\n\ntarget_link_libraries(sourcemeta_core_markdown PRIVATE CMarkGFM::cmark_gfm)\n"
  },
  {
    "path": "vendor/core/src/core/markdown/include/sourcemeta/core/markdown.h",
    "content": "#ifndef SOURCEMETA_CORE_MARKDOWN_H_\n#define SOURCEMETA_CORE_MARKDOWN_H_\n\n#ifndef SOURCEMETA_CORE_MARKDOWN_EXPORT\n#include <sourcemeta/core/markdown_export.h>\n#endif\n\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\n/// @defgroup markdown Markdown\n/// @brief A growing implementation of Markdown-related utilities based on\n/// GitHub Flavored Markdown (GFM).\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/markdown.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup markdown\n/// Convert a Markdown string to an HTML fragment using GitHub Flavored\n/// Markdown (GFM) with all standard extensions enabled (tables, autolinks,\n/// strikethrough, tag filtering, and task lists). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/markdown.h>\n///\n/// #include <cassert>\n///\n/// const auto result{sourcemeta::core::markdown_to_html(\"Hello **world**\")};\n/// assert(result == \"<p>Hello <strong>world</strong></p>\\n\");\n/// ```\nSOURCEMETA_CORE_MARKDOWN_EXPORT\nauto markdown_to_html(const std::string_view input) -> std::string;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/markdown/markdown.cc",
    "content": "#include <sourcemeta/core/markdown.h>\n\n#include <cmark-gfm-core-extensions.h> // cmark_gfm_core_extensions_ensure_registered\n#include <cmark-gfm-extension_api.h> // cmark_find_syntax_extension, cmark_parser_attach_syntax_extension, cmark_parser_get_syntax_extensions\n#include <cmark-gfm.h> // cmark_parser_new, cmark_parser_feed, cmark_parser_finish, cmark_parser_free, cmark_render_html, cmark_node_free\n\n#include <array>   // std::array\n#include <cstdlib> // std::free\n#include <string>  // std::string\n\nnamespace {\nconst bool cmark_initialized =\n    (cmark_gfm_core_extensions_ensure_registered(), true);\n}\n\nnamespace sourcemeta::core {\n\nauto markdown_to_html(const std::string_view input) -> std::string {\n  static constexpr auto options{CMARK_OPT_VALIDATE_UTF8 | CMARK_OPT_FOOTNOTES |\n                                CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE |\n                                CMARK_OPT_GITHUB_PRE_LANG};\n\n  auto *parser{cmark_parser_new(options)};\n\n  static constexpr std::array<const char *, 5> extension_names{\n      {\"table\", \"autolink\", \"strikethrough\", \"tagfilter\", \"tasklist\"}};\n  for (const auto *name : extension_names) {\n    auto *extension{cmark_find_syntax_extension(name)};\n    if (extension != nullptr) {\n      cmark_parser_attach_syntax_extension(parser, extension);\n    }\n  }\n\n  cmark_parser_feed(parser, input.data(), input.size());\n  auto *document{cmark_parser_finish(parser)};\n  auto *result{cmark_render_html(document, options,\n                                 cmark_parser_get_syntax_extensions(parser))};\n\n  std::string output{result};\n  std::free(result);\n  cmark_node_free(document);\n  cmark_parser_free(parser);\n  return output;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/punycode/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME punycode\n  PRIVATE_HEADERS error.h\n  SOURCES punycode.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME punycode)\nendif()\n\ntarget_link_libraries(sourcemeta_core_punycode PRIVATE sourcemeta::core::unicode)\n"
  },
  {
    "path": "vendor/core/src/core/punycode/include/sourcemeta/core/punycode.h",
    "content": "#ifndef SOURCEMETA_CORE_PUNYCODE_H_\n#define SOURCEMETA_CORE_PUNYCODE_H_\n\n#ifndef SOURCEMETA_CORE_PUNYCODE_EXPORT\n#include <sourcemeta/core/punycode_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/punycode_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <istream>     // std::istream\n#include <ostream>     // std::ostream\n#include <string>      // std::string, std::u32string\n#include <string_view> // std::string_view, std::u32string_view\n\n/// @defgroup punycode Punycode\n/// @brief An implementation of RFC 3492 Punycode.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n// See https://www.rfc-editor.org/rfc/rfc3492\n\n/// @ingroup punycode\n/// Encode Unicode code points (UTF-32) to Punycode. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <cassert>\n///\n/// const std::u32string input{0x0048, 0x0065, 0x006C, 0x006C, 0x006F,\n///                            0x002D, 0x305D, 0x308C, 0x305E, 0x308C,\n///                            0x306E, 0x5834, 0x6240};\n/// assert(sourcemeta::core::utf32_to_punycode(input) ==\n///        \"Hello--fc4qua05auwb3674vfr0b\");\n/// ```\n///\n/// Note that stream-based overloads for UTF-32 are not provided\n/// because the C++ standard library does not define the required locale facets\n/// (`std::ctype<char32_t>`) for `std::basic_istream<char32_t>` and\n/// `std::basic_ostream<char32_t>` to function properly.\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto utf32_to_punycode(std::u32string_view input) -> std::string;\n\n/// @ingroup punycode\n/// Encode UTF-8 to Punycode using streams. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <sstream>\n/// #include <cassert>\n///\n/// std::istringstream input{\"M\\xC3\\xBCnchen\"};\n/// std::ostringstream output;\n/// sourcemeta::core::utf8_to_punycode(input, output);\n/// assert(output.str() == \"Mnchen-3ya\");\n/// ```\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto utf8_to_punycode(std::istream &input, std::ostream &output) -> void;\n\n/// @ingroup punycode\n/// Encode UTF-8 to Punycode. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::utf8_to_punycode(\"M\\xC3\\xBCnchen\") ==\n/// \"Mnchen-3ya\");\n/// ```\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto utf8_to_punycode(const std::string_view input) -> std::string;\n\n/// @ingroup punycode\n/// Decode Punycode to Unicode code points (UTF-32). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <cassert>\n///\n/// const std::u32string expected{0x0048, 0x0065, 0x006C, 0x006C, 0x006F,\n///                               0x002D, 0x305D, 0x308C, 0x305E, 0x308C,\n///                               0x306E, 0x5834, 0x6240};\n/// assert(sourcemeta::core::punycode_to_utf32(\"Hello--fc4qua05auwb3674vfr0b\")\n/// ==\n///        expected);\n/// ```\n///\n/// Note that stream-based overloads for UTF-32 are not provided\n/// because the C++ standard library does not define the required locale facets\n/// (`std::ctype<char32_t>`) for `std::basic_istream<char32_t>` and\n/// `std::basic_ostream<char32_t>` to function properly.\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto punycode_to_utf32(const std::string_view input) -> std::u32string;\n\n/// @ingroup punycode\n/// Decode Punycode to UTF-8 using streams. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <sstream>\n/// #include <cassert>\n///\n/// std::istringstream input{\"Mnchen-3ya\"};\n/// std::ostringstream output;\n/// sourcemeta::core::punycode_to_utf8(input, output);\n/// assert(output.str() == \"M\\xC3\\xBCnchen\");\n/// ```\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto punycode_to_utf8(std::istream &input, std::ostream &output) -> void;\n\n/// @ingroup punycode\n/// Decode Punycode to UTF-8. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/punycode.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::punycode_to_utf8(\"Mnchen-3ya\") ==\n/// \"M\\xC3\\xBCnchen\");\n/// ```\nSOURCEMETA_CORE_PUNYCODE_EXPORT\nauto punycode_to_utf8(const std::string_view input) -> std::string;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/punycode/include/sourcemeta/core/punycode_error.h",
    "content": "#ifndef SOURCEMETA_CORE_PUNYCODE_ERROR_H_\n#define SOURCEMETA_CORE_PUNYCODE_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_PUNYCODE_EXPORT\n#include <sourcemeta/core/punycode_error.h>\n#endif\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup punycode\nclass SOURCEMETA_CORE_PUNYCODE_EXPORT PunycodeError : public std::exception {\npublic:\n  PunycodeError(const char *message) : message_{message} {}\n  PunycodeError(std::string message) = delete;\n  PunycodeError(std::string &&message) = delete;\n  PunycodeError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/punycode/punycode.cc",
    "content": "#include <sourcemeta/core/punycode.h>\n#include <sourcemeta/core/punycode_error.h>\n#include <sourcemeta/core/unicode.h>\n\n#include <algorithm> // std::ranges::sort\n#include <cassert>   // assert\n#include <cstdint>   // std::uint32_t, std::uint64_t\n#include <limits>    // std::numeric_limits\n#include <sstream>   // std::ostringstream\n#include <vector>    // std::vector\n\nnamespace sourcemeta::core {\n\n// RFC 3492 Section 5: Bootstring parameters for Punycode\n// See https://www.rfc-editor.org/rfc/rfc3492#section-5\nstatic constexpr std::uint32_t BASE{36};\nstatic constexpr std::uint32_t TMIN{1};\nstatic constexpr std::uint32_t TMAX{26};\nstatic constexpr std::uint32_t SKEW{38};\nstatic constexpr std::uint32_t DAMP{700};\nstatic constexpr std::uint32_t INITIAL_BIAS{72};\nstatic constexpr std::uint32_t INITIAL_N{0x80};\nstatic constexpr char DELIMITER{'-'};\n\n// RFC 3492 Section 5: digit-value to code point\n// See https://www.rfc-editor.org/rfc/rfc3492#section-5\nstatic constexpr auto encode_digit(const std::uint32_t digit) -> char {\n  assert(digit < BASE);\n  if (digit < 26) {\n    return static_cast<char>('a' + digit);\n  }\n\n  return static_cast<char>('0' + digit - 26);\n}\n\n// RFC 3492 Section 5: code point to digit-value\n// See https://www.rfc-editor.org/rfc/rfc3492#section-5\nstatic auto decode_digit(const char code_point) -> std::uint32_t {\n  if (code_point >= 'a' && code_point <= 'z') {\n    return static_cast<std::uint32_t>(code_point - 'a');\n  } else if (code_point >= 'A' && code_point <= 'Z') {\n    return static_cast<std::uint32_t>(code_point - 'A');\n  } else if (code_point >= '0' && code_point <= '9') {\n    return static_cast<std::uint32_t>(code_point - '0' + 26);\n  }\n\n  throw PunycodeError(\"Invalid digit\");\n}\n\n// RFC 3492 Section 6.1: Bias adaptation function\n// See https://www.rfc-editor.org/rfc/rfc3492#section-6.1\nstatic auto adapt_bias(std::uint32_t delta,\n                       const std::uint32_t number_of_points,\n                       const bool first_time) -> std::uint32_t {\n  delta = first_time ? delta / DAMP : delta / 2;\n  delta += delta / number_of_points;\n  std::uint32_t result{0};\n  while (delta > ((BASE - TMIN) * TMAX) / 2) {\n    delta /= (BASE - TMIN);\n    result += BASE;\n  }\n\n  return result + (((BASE - TMIN + 1) * delta) / (delta + SKEW));\n}\n\nstatic constexpr auto compute_threshold(const std::uint32_t step,\n                                        const std::uint32_t bias)\n    -> std::uint32_t {\n  if (step <= bias) {\n    return TMIN;\n  } else if (step >= bias + TMAX) {\n    return TMAX;\n  }\n\n  return step - bias;\n}\n\nstatic constexpr auto is_basic(const char32_t code_point) -> bool {\n  return code_point < INITIAL_N;\n}\n\nstatic auto punycode_encode(const std::u32string_view codepoints,\n                            std::string &output) -> void {\n  std::vector<char32_t> non_basic_sorted;\n  non_basic_sorted.reserve(codepoints.size());\n\n  for (const auto code_point : codepoints) {\n    if (is_basic(code_point)) {\n      output.push_back(static_cast<char>(code_point));\n    } else {\n      non_basic_sorted.push_back(code_point);\n    }\n  }\n\n  const auto basic_count =\n      static_cast<std::uint32_t>(codepoints.size() - non_basic_sorted.size());\n\n  if (basic_count > 0) {\n    output.push_back(DELIMITER);\n  }\n\n  if (non_basic_sorted.empty()) {\n    return;\n  }\n\n  std::ranges::sort(non_basic_sorted);\n\n  std::uint32_t current_code_point{INITIAL_N};\n  std::uint32_t delta{0};\n  std::uint32_t bias{INITIAL_BIAS};\n  std::uint32_t handled_count{basic_count};\n  std::size_t sorted_index{0};\n\n  while (handled_count < codepoints.size()) {\n    const char32_t minimum = non_basic_sorted[sorted_index];\n\n    const auto delta_increment =\n        static_cast<std::uint64_t>(minimum - current_code_point) *\n        (handled_count + 1);\n    if (delta_increment > std::numeric_limits<std::uint32_t>::max() -\n                              static_cast<std::uint64_t>(delta)) {\n      throw PunycodeError(\"Encode overflow\");\n    }\n\n    delta += static_cast<std::uint32_t>(delta_increment);\n    current_code_point = minimum;\n\n    for (const auto code_point : codepoints) {\n      if (code_point < current_code_point) {\n        if (delta == std::numeric_limits<std::uint32_t>::max()) {\n          throw PunycodeError(\"Encode overflow\");\n        }\n\n        delta += 1;\n      } else if (code_point == current_code_point) {\n        std::uint32_t quotient{delta};\n\n        for (std::uint32_t step{BASE};; step += BASE) {\n          const std::uint32_t threshold = compute_threshold(step, bias);\n\n          if (quotient < threshold) {\n            break;\n          }\n\n          const std::uint32_t base_minus_threshold = BASE - threshold;\n          output.push_back(encode_digit(\n              threshold + ((quotient - threshold) % base_minus_threshold)));\n          quotient = (quotient - threshold) / base_minus_threshold;\n        }\n\n        output.push_back(encode_digit(quotient));\n        bias =\n            adapt_bias(delta, handled_count + 1, handled_count == basic_count);\n        delta = 0;\n        handled_count += 1;\n      }\n    }\n\n    while (sorted_index < non_basic_sorted.size() &&\n           non_basic_sorted[sorted_index] == current_code_point) {\n      sorted_index += 1;\n    }\n\n    delta += 1;\n    current_code_point += 1;\n  }\n}\n\nstatic auto punycode_decode(const std::string_view encoded,\n                            std::u32string &decoded) -> void {\n  std::uint32_t current_code_point{INITIAL_N};\n  std::uint32_t insertion_index{0};\n  std::uint32_t bias{INITIAL_BIAS};\n\n  const auto delimiter_position = encoded.rfind(DELIMITER);\n  std::size_t position{0};\n\n  if (delimiter_position != std::string_view::npos) {\n    decoded.reserve(encoded.size());\n    for (std::size_t index = 0; index < delimiter_position; index += 1) {\n      const auto code_point = static_cast<unsigned char>(encoded[index]);\n      if (!is_basic(code_point)) {\n        throw PunycodeError(\"Non-basic code point before delimiter\");\n      }\n\n      decoded.push_back(code_point);\n    }\n\n    position = delimiter_position + 1;\n  }\n\n  while (position < encoded.size()) {\n    const std::uint32_t previous_insertion_index{insertion_index};\n    std::uint32_t weight_factor{1};\n\n    for (std::uint32_t step{BASE};; step += BASE) {\n      if (position >= encoded.size()) {\n        throw PunycodeError(\"Unexpected end of input\");\n      }\n\n      const std::uint32_t digit = decode_digit(encoded[position]);\n      position += 1;\n\n      if (digit >\n          (std::numeric_limits<std::uint32_t>::max() - insertion_index) /\n              weight_factor) {\n        throw PunycodeError(\"Decode overflow\");\n      }\n\n      insertion_index += digit * weight_factor;\n      const std::uint32_t threshold = compute_threshold(step, bias);\n\n      if (digit < threshold) {\n        break;\n      }\n\n      const std::uint32_t base_minus_threshold = BASE - threshold;\n      if (weight_factor >\n          std::numeric_limits<std::uint32_t>::max() / base_minus_threshold) {\n        throw PunycodeError(\"Decode overflow\");\n      }\n\n      weight_factor *= base_minus_threshold;\n    }\n\n    const auto output_length = static_cast<std::uint32_t>(decoded.size()) + 1;\n    bias = adapt_bias(insertion_index - previous_insertion_index, output_length,\n                      previous_insertion_index == 0);\n\n    const std::uint32_t increment = insertion_index / output_length;\n    if (increment >\n        std::numeric_limits<std::uint32_t>::max() - current_code_point) {\n      throw PunycodeError(\"Decode overflow\");\n    }\n\n    current_code_point += increment;\n    insertion_index %= output_length;\n\n    if (current_code_point < INITIAL_N) {\n      throw PunycodeError(\"Decoded basic code point\");\n    }\n\n    if (current_code_point > 0x10FFFF ||\n        (current_code_point >= 0xD800 && current_code_point <= 0xDFFF)) {\n      throw PunycodeError(\"Invalid code point\");\n    }\n\n    decoded.insert(decoded.begin() +\n                       static_cast<std::ptrdiff_t>(insertion_index),\n                   static_cast<char32_t>(current_code_point));\n    insertion_index += 1;\n  }\n}\n\nauto utf32_to_punycode(std::u32string_view input) -> std::string {\n  std::string result;\n  punycode_encode(input, result);\n  return result;\n}\n\nauto punycode_to_utf32(const std::string_view input) -> std::u32string {\n  std::u32string result;\n  punycode_decode(input, result);\n  return result;\n}\n\nauto utf8_to_punycode(std::istream &input, std::ostream &output) -> void {\n  const auto codepoints = utf8_to_utf32(input);\n  if (!codepoints.has_value()) {\n    throw PunycodeError(\"Invalid UTF-8 input\");\n  }\n\n  std::string result;\n  punycode_encode(codepoints.value(), result);\n  output << result;\n}\n\nauto punycode_to_utf8(std::istream &input, std::ostream &output) -> void {\n  std::string encoded;\n  char character{0};\n  while (input.get(character)) {\n    encoded.push_back(character);\n  }\n\n  std::u32string decoded;\n  punycode_decode(encoded, decoded);\n  for (const auto code_point : decoded) {\n    codepoint_to_utf8(code_point, output);\n  }\n}\n\nauto utf8_to_punycode(const std::string_view input) -> std::string {\n  const auto codepoints = utf8_to_utf32(input);\n  if (!codepoints.has_value()) {\n    throw PunycodeError(\"Invalid UTF-8 input\");\n  }\n\n  std::string result;\n  punycode_encode(codepoints.value(), result);\n  return result;\n}\n\nauto punycode_to_utf8(const std::string_view input) -> std::string {\n  std::u32string decoded;\n  punycode_decode(input, decoded);\n  std::ostringstream output_stream;\n  for (const auto code_point : decoded) {\n    codepoint_to_utf8(code_point, output_stream);\n  }\n  return output_stream.str();\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/regex/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME regex\n  SOURCES regex.cc preprocess.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME regex)\nendif()\n\ntarget_link_libraries(sourcemeta_core_regex PRIVATE PCRE2::pcre2)\n"
  },
  {
    "path": "vendor/core/src/core/regex/include/sourcemeta/core/regex.h",
    "content": "#ifndef SOURCEMETA_CORE_REGEX_H_\n#define SOURCEMETA_CORE_REGEX_H_\n\n#ifndef SOURCEMETA_CORE_REGEX_EXPORT\n#include <sourcemeta/core/regex_export.h>\n#endif\n\n#include <cstdint>     // std::uint8_t, std::uint64_t\n#include <memory>      // std::shared_ptr\n#include <optional>    // std::optional\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n#include <variant>     // std::variant\n\n/// @defgroup regex Regex\n/// @brief An opinionated and permissive ECMA 262 + RFC 9485 (best effort) regex\n/// implementation for JSON Schema\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/regex.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup regex\nusing RegexTypePrefix = std::string;\n\n/// @ingroup regex\nstruct RegexTypeNonEmpty {\n  auto operator==(const RegexTypeNonEmpty &) const noexcept -> bool = default;\n};\n\n/// @ingroup regex\nusing RegexTypeRange = std::pair<std::uint64_t, std::uint64_t>;\n\n/// @ingroup regex\nstruct RegexTypePCRE2 {\n  std::shared_ptr<void> code;\n  auto operator==(const RegexTypePCRE2 &other) const noexcept -> bool {\n    return this->code == other.code;\n  }\n};\n\n/// @ingroup regex\nstruct RegexTypeNoop {\n  auto operator==(const RegexTypeNoop &) const noexcept -> bool = default;\n};\n\n/// @ingroup regex\nusing Regex = std::variant<RegexTypePrefix, RegexTypeNonEmpty, RegexTypeRange,\n                           RegexTypePCRE2, RegexTypeNoop>;\n#if !defined(DOXYGEN)\n// For fast internal dispatching. It must stay in sync with the variant above\nenum class RegexIndex : std::uint8_t {\n  Prefix = 0,\n  NonEmpty,\n  Range,\n  PCRE2,\n  Noop\n};\n#endif\n\n/// @ingroup regex\n///\n/// Compile a regular expression from a string. If the regular expression is\n/// invalid, no value is returned. In this function:\n///\n/// - Regexes are NOT automatically anchored\n/// - Regexes assume `DOTALL`\n/// - Regexes assume Unicode\n/// - Regexes are case sensitive\n/// - No matching happens (only boolean validation)\n///\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/regex.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::Regex regex{\n///   sourcemeta::core::to_regex(\"^foo\")};\n/// assert(regex.has_value());\n/// ```\nSOURCEMETA_CORE_REGEX_EXPORT\nauto to_regex(const std::string_view pattern) -> std::optional<Regex>;\n\n/// @ingroup regex\n///\n/// Validate a string against a regular expression. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/regex.h>\n/// #include <cassert>\n///\n/// const sourcemeta::core::Regex regex{\n///   sourcemeta::core::to_regex(\"^foo\")};\n/// assert(regex.has_value());\n/// assert(sourcemeta::core::matches(regex.value(), \"foo bar\"));\n/// ```\nSOURCEMETA_CORE_REGEX_EXPORT\nauto matches(const Regex &regex, const std::string_view value) -> bool;\n\n/// @ingroup regex\n///\n/// Validate a string against a regular expression pattern if the pattern\n/// represents a valid regular expression, compiling it along the way. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/regex.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::matches_if_valid(\"^foo\", \"foo bar\"));\n/// ```\nSOURCEMETA_CORE_REGEX_EXPORT\nauto matches_if_valid(const std::string_view pattern,\n                      const std::string_view value) -> bool;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/regex/preprocess.h",
    "content": "#ifndef SOURCEMETA_CORE_REGEX_PREPROCESS_H_\n#define SOURCEMETA_CORE_REGEX_PREPROCESS_H_\n\n#include <array>       // std::array\n#include <bitset>      // std::bitset\n#include <cstddef>     // std::size_t\n#include <optional>    // std::optional\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n\nnamespace sourcemeta::core {\n\nnamespace {\n\nconstexpr std::array<std::pair<std::string_view, std::string_view>, 42>\n    unicode_property_map{{{\"digit\", \"Nd\"},\n                          {\"Decimal_Number\", \"Nd\"},\n                          {\"space\", \"White_Space\"},\n                          {\"White_Space\", \"White_Space\"},\n                          {\"ASCII\", \"ASCII\"},\n                          {\"Hex_Digit\", \"Hex_Digit\"},\n                          {\"Alphabetic\", \"Alphabetic\"},\n                          {\"Letter\", \"L\"},\n                          {\"Uppercase_Letter\", \"Lu\"},\n                          {\"Lowercase_Letter\", \"Ll\"},\n                          {\"Titlecase_Letter\", \"Lt\"},\n                          {\"Modifier_Letter\", \"Lm\"},\n                          {\"Other_Letter\", \"Lo\"},\n                          {\"Mark\", \"M\"},\n                          {\"Nonspacing_Mark\", \"Mn\"},\n                          {\"Spacing_Mark\", \"Mc\"},\n                          {\"Enclosing_Mark\", \"Me\"},\n                          {\"Number\", \"N\"},\n                          {\"Letter_Number\", \"Nl\"},\n                          {\"Other_Number\", \"No\"},\n                          {\"Punctuation\", \"P\"},\n                          {\"Connector_Punctuation\", \"Pc\"},\n                          {\"Dash_Punctuation\", \"Pd\"},\n                          {\"Open_Punctuation\", \"Ps\"},\n                          {\"Close_Punctuation\", \"Pe\"},\n                          {\"Initial_Punctuation\", \"Pi\"},\n                          {\"Final_Punctuation\", \"Pf\"},\n                          {\"Other_Punctuation\", \"Po\"},\n                          {\"Symbol\", \"S\"},\n                          {\"Math_Symbol\", \"Sm\"},\n                          {\"Currency_Symbol\", \"Sc\"},\n                          {\"Modifier_Symbol\", \"Sk\"},\n                          {\"Other_Symbol\", \"So\"},\n                          {\"Separator\", \"Z\"},\n                          {\"Space_Separator\", \"Zs\"},\n                          {\"Line_Separator\", \"Zl\"},\n                          {\"Paragraph_Separator\", \"Zp\"},\n                          {\"Other\", \"C\"},\n                          {\"Control\", \"Cc\"},\n                          {\"Format\", \"Cf\"},\n                          {\"Unassigned\", \"Cn\"},\n                          {\"Private_Use\", \"Co\"}}};\n\nconstexpr std::string_view shorthand_chars{\"dDwWsS\"};\nconstexpr std::string_view simple_escapes{\"btnrfv0\"};\nconstexpr std::string_view simple_escape_values{\"\\b\\t\\n\\r\\f\\v\"};\nconstexpr std::string_view v_flag_syntax{\"-][(){}/'|!#%&*+,.:;<=>?@`~^$\"};\n\ninline auto hex_value(char character) -> int {\n  if (character >= '0' && character <= '9') {\n    return character - '0';\n  }\n\n  if (character >= 'a' && character <= 'f') {\n    return character - 'a' + 10;\n  }\n\n  if (character >= 'A' && character <= 'F') {\n    return character - 'A' + 10;\n  }\n\n  return -1;\n}\n\ninline auto all_hex(const std::string &content, std::size_t start,\n                    std::size_t count) -> bool {\n  for (std::size_t offset = 0; offset < count; ++offset) {\n    if (hex_value(content[start + offset]) < 0) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\ninline auto parse_hex_digits(const std::string &content, std::size_t start,\n                             std::size_t count) -> int {\n  int value = 0;\n  for (std::size_t offset = 0; offset < count; ++offset) {\n    value = (value << 4) | hex_value(content[start + offset]);\n  }\n\n  return value;\n}\n\nconstexpr auto make_digit_class() -> std::bitset<128> {\n  std::bitset<128> result;\n  for (int code = '0'; code <= '9'; ++code) {\n    result.set(static_cast<std::size_t>(code));\n  }\n\n  return result;\n}\n\nconstexpr auto make_word_class() -> std::bitset<128> {\n  std::bitset<128> result;\n  for (int code = 'a'; code <= 'z'; ++code) {\n    result.set(static_cast<std::size_t>(code));\n  }\n\n  for (int code = 'A'; code <= 'Z'; ++code) {\n    result.set(static_cast<std::size_t>(code));\n  }\n\n  for (int code = '0'; code <= '9'; ++code) {\n    result.set(static_cast<std::size_t>(code));\n  }\n\n  result.set('_');\n  return result;\n}\n\nconstexpr auto make_space_class() -> std::bitset<128> {\n  std::bitset<128> result;\n  result.set(' ');\n  result.set('\\t');\n  result.set('\\n');\n  result.set('\\r');\n  result.set('\\f');\n  result.set('\\v');\n  return result;\n}\n\nconstexpr auto negate_class(const std::bitset<128> &base) -> std::bitset<128> {\n  auto result = ~base;\n  result.reset(0);\n  return result;\n}\n\nconstexpr auto digit_class = make_digit_class();\nconstexpr auto word_class = make_word_class();\nconstexpr auto space_class = make_space_class();\nconstexpr auto non_digit_class = negate_class(digit_class);\nconstexpr auto non_word_class = negate_class(word_class);\nconstexpr auto non_space_class = negate_class(space_class);\n\ninline auto set_shorthand_class(std::bitset<128> &characters,\n                                const char shorthand) -> void {\n  switch (shorthand) {\n    case 'd':\n      characters |= digit_class;\n      return;\n    case 'D':\n      characters |= non_digit_class;\n      return;\n    case 'w':\n      characters |= word_class;\n      return;\n    case 'W':\n      characters |= non_word_class;\n      return;\n    case 's':\n      characters |= space_class;\n      return;\n    case 'S':\n      characters |= non_space_class;\n      return;\n    default:\n      return;\n  }\n}\n\ninline auto find_bracket_end(const std::string &content, std::size_t start,\n                             bool track_nested = true) -> std::size_t {\n  for (std::size_t depth = 1, position = start; position < content.size();\n       ++position) {\n    if (content[position] == '\\\\' && position + 1 < content.size()) {\n      ++position;\n    } else if (track_nested && content[position] == '[') {\n      ++depth;\n    } else if (content[position] == ']' && --depth == 0) {\n      return position + 1;\n    }\n  }\n\n  return content.size();\n}\n\ninline auto parse_escape(const std::string &content, std::size_t position,\n                         std::size_t &end, int &code_point) -> void {\n  if (position >= content.size()) {\n    end = position;\n    code_point = -1;\n    return;\n  }\n\n  if (content[position] != '\\\\' || position + 1 >= content.size()) {\n    end = position + 1;\n    code_point = static_cast<unsigned char>(content[position]);\n    return;\n  }\n\n  const char next = content[position + 1];\n  if (next == 'x' && position + 3 < content.size() &&\n      all_hex(content, position + 2, 2)) {\n    end = position + 4;\n    code_point = parse_hex_digits(content, position + 2, 2);\n    return;\n  }\n\n  if (next == 'u' && position + 2 < content.size()) {\n    if (content[position + 2] == '{') {\n      std::size_t brace_end = position + 3;\n      while (brace_end < content.size() && content[brace_end] != '}' &&\n             hex_value(content[brace_end]) >= 0) {\n        ++brace_end;\n      }\n\n      if (brace_end < content.size() && content[brace_end] == '}') {\n        const int value =\n            parse_hex_digits(content, position + 3, brace_end - position - 3);\n        if (value < 128) {\n          end = brace_end + 1;\n          code_point = value;\n          return;\n        }\n      }\n    } else if (position + 5 < content.size() &&\n               all_hex(content, position + 2, 4)) {\n      const int value = parse_hex_digits(content, position + 2, 4);\n      if (value < 128) {\n        end = position + 6;\n        code_point = value;\n        return;\n      }\n    }\n  }\n\n  if (next == 'c' && position + 2 < content.size()) {\n    const char control = content[position + 2];\n    if ((control >= 'A' && control <= 'Z') ||\n        (control >= 'a' && control <= 'z')) {\n      end = position + 3;\n      code_point = control % 32;\n      return;\n    }\n  }\n\n  end = position + 2;\n  const auto escape_index = simple_escapes.find(next);\n  if (escape_index < 6) {\n    code_point = static_cast<unsigned char>(simple_escape_values[escape_index]);\n  } else if (next == '0') {\n    code_point = 0;\n  } else if (shorthand_chars.contains(next)) {\n    code_point = -1;\n  } else {\n    code_point = static_cast<unsigned char>(next);\n  }\n}\n\ninline auto first_operator(const std::string &content, std::size_t start)\n    -> std::pair<std::size_t, char> {\n  for (std::size_t depth = 0, position = start; position + 1 < content.size();\n       ++position) {\n    const char current = content[position];\n    if (current == '\\\\') {\n      ++position;\n    } else if (current == '[') {\n      ++depth;\n    } else if (current == ']' && depth > 0) {\n      --depth;\n    } else if (depth == 0 && (current == '-' || current == '&') &&\n               content[position + 1] == current) {\n      return {position, current};\n    }\n  }\n\n  return {std::string::npos, '\\0'};\n}\n\ninline auto has_nested_brackets(const std::string &content) -> bool {\n  for (std::size_t position = 0; position < content.size(); ++position) {\n    if (content[position] == '\\\\') {\n      ++position;\n    } else if (content[position] == '[') {\n      // Found a potential nested bracket - check if it has a closing ]\n      // Skip past this [ and look for its matching ]\n      std::size_t inner_pos = position + 1;\n      while (inner_pos < content.size()) {\n        if (content[inner_pos] == '\\\\' && inner_pos + 1 < content.size()) {\n          inner_pos += 2;\n        } else if (content[inner_pos] == ']') {\n          // Found a matching ] - this is a proper nested bracket\n          return true;\n        } else {\n          ++inner_pos;\n        }\n      }\n      // No matching ] found for this [, so it's just a literal [\n      // Continue searching\n    }\n  }\n\n  return false;\n}\n\n// Forward declaration\ninline auto expand_set_ops(const std::string &content, std::bitset<128> &result)\n    -> bool;\n\ninline auto parse_class_to_bitset(const std::string &content, std::size_t start,\n                                  std::bitset<128> &characters) -> std::size_t {\n  std::size_t position = start;\n  bool negated = position < content.size() && content[position] == '^';\n  if (negated) {\n    ++position;\n  }\n\n  while (position < content.size() && content[position] != ']') {\n    if (content[position] == '\\\\' && position + 1 < content.size() &&\n        shorthand_chars.contains(content[position + 1])) {\n      set_shorthand_class(characters, content[position + 1]);\n      position += 2;\n      continue;\n    }\n\n    if (content[position] == '[') {\n      const auto nested_end = find_bracket_end(content, position + 1);\n      const auto nested =\n          content.substr(position + 1, nested_end - position - 2);\n      std::bitset<128> nested_chars;\n      if (first_operator(nested, 0).first != std::string::npos) {\n        expand_set_ops(nested, nested_chars);\n      } else {\n        parse_class_to_bitset(nested, 0, nested_chars);\n      }\n\n      characters |= nested_chars;\n      position = nested_end;\n      continue;\n    }\n\n    std::size_t end{0};\n    int first{0};\n    parse_escape(content, position, end, first);\n    if (first < 0) {\n      position = end;\n      continue;\n    }\n\n    if (end < content.size() && content[end] == '-' &&\n        end + 1 < content.size() && content[end + 1] != ']') {\n      std::size_t range_end{0};\n      int second{0};\n      parse_escape(content, end + 1, range_end, second);\n      if (second >= 0) {\n        for (int code = first; code <= second && code < 128; ++code) {\n          characters.set(static_cast<std::size_t>(code));\n        }\n\n        position = range_end;\n        continue;\n      }\n    }\n\n    if (first < 128) {\n      characters.set(static_cast<std::size_t>(first));\n    }\n\n    position = end;\n  }\n\n  if (negated) {\n    for (std::size_t code = 32; code < 128; ++code) {\n      characters.flip(code);\n    }\n  }\n\n  return position;\n}\n\ninline auto append_char(std::string &result, std::size_t value) -> void {\n  constexpr std::string_view hex{\"0123456789abcdef\"};\n  if (value < 32 || value == 127) {\n    result += \"\\\\x\";\n    result += hex[(value >> 4) & 0xF];\n    result += hex[value & 0xF];\n  } else {\n    if (std::string_view{\"-]\\\\^\"}.find(static_cast<char>(value)) !=\n        std::string_view::npos) {\n      result += '\\\\';\n    }\n\n    result += static_cast<char>(value);\n  }\n}\n\ninline auto bitset_to_class(const std::bitset<128> &characters) -> std::string {\n  std::string result{\"[\"};\n  for (std::size_t code = 0; code < 128; ++code) {\n    if (!characters.test(code)) {\n      continue;\n    }\n\n    const std::size_t range_start = code;\n    while (code + 1 < 128 && characters.test(code + 1)) {\n      ++code;\n    }\n\n    if (code - range_start >= 2) {\n      append_char(result, range_start);\n      result += '-';\n      append_char(result, code);\n    } else {\n      for (std::size_t character = range_start; character <= code;\n           ++character) {\n        append_char(result, character);\n      }\n    }\n  }\n\n  result += ']';\n  return result;\n}\n\ninline auto is_valid_escape(const std::string &content, std::size_t position)\n    -> bool {\n  if (position + 1 >= content.size()) {\n    return false;\n  }\n\n  const char next = content[position + 1];\n  if (std::string_view{\"dDwWsSnrtfvb0\\\\\"}.find(next) !=\n      std::string_view::npos) {\n    return true;\n  }\n\n  if (next == 'x') {\n    return position + 3 < content.size() && all_hex(content, position + 2, 2);\n  }\n\n  if (next == 'u' && position + 2 < content.size()) {\n    if (content[position + 2] == '{') {\n      for (auto end = position + 3; end < content.size(); ++end) {\n        if (content[end] == '}') {\n          return true;\n        } else if (hex_value(content[end]) < 0) {\n          return false;\n        }\n      }\n\n      return false;\n    }\n\n    return position + 5 < content.size() && all_hex(content, position + 2, 4);\n  }\n\n  if (next == 'c' && position + 2 < content.size()) {\n    const char ctrl = content[position + 2];\n    return (ctrl >= 'A' && ctrl <= 'Z') || (ctrl >= 'a' && ctrl <= 'z');\n  }\n\n  return v_flag_syntax.contains(next);\n}\n\ninline auto is_valid_operand(const std::string &operand) -> bool {\n  if (operand.empty()) {\n    return false;\n  }\n\n  if (operand.front() == '[') {\n    if (operand.size() >= 2 && operand.back() == ']') {\n      const auto inner = operand.substr(1, operand.size() - 2);\n      for (std::size_t position = 0; position < inner.size(); ++position) {\n        if (inner[position] == '\\\\' && position + 1 < inner.size()) {\n          if (!is_valid_escape(inner, position)) {\n            return false;\n          }\n\n          ++position;\n        } else if (inner[position] == '|' ||\n                   (inner[position] == '-' && (position == inner.size() - 1 ||\n                                               inner[position + 1] == ']'))) {\n          return false;\n        }\n      }\n    }\n\n    return true;\n  }\n\n  if (operand.size() == 2 && operand[0] == '\\\\' &&\n      shorthand_chars.contains(operand[1])) {\n    return true;\n  }\n\n  for (std::size_t position = 0; position < operand.size(); ++position) {\n    if (operand[position] == '\\\\' && position + 1 < operand.size()) {\n      ++position;\n    } else if (operand[position] == '-' && position > 0 &&\n               position + 1 < operand.size()) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\ninline auto parse_operand(const std::string &operand,\n                          std::bitset<128> &characters) -> bool {\n  if (!is_valid_operand(operand)) {\n    return false;\n  }\n\n  if (operand.size() >= 2 && operand.front() == '[' && operand.back() == ']') {\n    const auto inner = operand.substr(1, operand.size() - 2);\n    if (first_operator(inner, 0).first != std::string::npos) {\n      return expand_set_ops(inner, characters);\n    }\n  }\n\n  parse_class_to_bitset(operand, 0, characters);\n  return true;\n}\n\ninline auto expand_set_ops(const std::string &content, std::bitset<128> &result)\n    -> bool {\n  auto [op_pos, op_char] = first_operator(content, 0);\n  if (op_pos == std::string::npos) {\n    parse_class_to_bitset(content, 0, result);\n    return true;\n  }\n\n  if (auto [next_pos, next_op] = first_operator(content, op_pos + 2);\n      next_pos != std::string::npos && next_op != op_char) {\n    return false;\n  }\n\n  if (!parse_operand(content.substr(0, op_pos), result)) {\n    return false;\n  }\n\n  for (std::size_t position = op_pos; position + 1 < content.size() &&\n                                      content[position] == op_char &&\n                                      content[position + 1] == op_char;) {\n    auto [next, unused] = first_operator(content, position += 2);\n    std::bitset<128> operand_chars;\n    if (!parse_operand(next != std::string::npos\n                           ? content.substr(position, next - position)\n                           : content.substr(position),\n                       operand_chars)) {\n      return false;\n    }\n\n    result =\n        op_char == '-' ? (result & ~operand_chars) : (result & operand_chars);\n    position = next;\n  }\n\n  return true;\n}\n\ninline auto expand_char_class(const std::string &content)\n    -> std::optional<std::string> {\n  if (first_operator(content, 0).first == std::string::npos &&\n      !has_nested_brackets(content)) {\n    return \"[\" + content + \"]\";\n  }\n\n  std::bitset<128> result;\n  if (!expand_set_ops(content, result)) {\n    return std::nullopt;\n  }\n\n  return result.none() ? \"(?!)\" : bitset_to_class(result);\n}\n\ninline auto translate_property(const std::string_view name, const bool negated)\n    -> std::optional<std::string> {\n  for (const auto &[prop_name, pcre_name] : unicode_property_map) {\n    if (name == prop_name) {\n      return std::string(\"\\\\\") + (negated ? 'P' : 'p') + '{' +\n             std::string(pcre_name) + '}';\n    }\n  }\n\n  return std::nullopt;\n}\n\ninline auto is_escaped(const std::string &pattern, std::size_t index) -> bool {\n  std::size_t count = 0;\n  for (auto position = index; position > 0 && pattern[position - 1] == '\\\\';\n       --position) {\n    ++count;\n  }\n\n  return (count % 2) == 1;\n}\n\nstruct ShorthandExpansion {\n  char escape;\n  std::string_view inside_class;\n  std::string_view outside_class;\n};\n\n// clang-format off\nconstexpr std::array<ShorthandExpansion, 8> shorthand_expansions{{\n    {.escape = 'd', .inside_class = \"0-9\", .outside_class = \"[0-9]\"},\n    {.escape = 'D', .inside_class = \"\", .outside_class = \"[^0-9]\"},\n    {.escape = 'w', .inside_class = \"a-zA-Z0-9_\", .outside_class = \"[a-zA-Z0-9_]\"},\n    {.escape = 'W', .inside_class = \"\", .outside_class = \"[^a-zA-Z0-9_]\"},\n    {.escape = 's', .inside_class = R\"(\\t\\v\\f \\x{00A0}\\x{FEFF}\\p{Zs}\\n\\r\\x{2028}\\x{2029})\",\n     .outside_class = R\"([\\t\\v\\f \\x{00A0}\\x{FEFF}\\p{Zs}\\n\\r\\x{2028}\\x{2029}])\"},\n    {.escape = 'S', .inside_class = \"\", .outside_class = R\"([^\\t\\v\\f \\x{00A0}\\x{FEFF}\\p{Zs}\\n\\r\\x{2028}\\x{2029}])\"},\n    {.escape = 'b', .inside_class = \"\", .outside_class = R\"((?:(?<![a-zA-Z0-9_])(?=[a-zA-Z0-9_])|(?<=[a-zA-Z0-9_])(?![a-zA-Z0-9_])))\"},\n    {.escape = 'B', .inside_class = \"\", .outside_class = R\"((?:(?<=[a-zA-Z0-9_])(?=[a-zA-Z0-9_])|(?<![a-zA-Z0-9_])(?![a-zA-Z0-9_])))\"},\n}};\n// clang-format on\n\ninline auto find_shorthand(char escape) -> const ShorthandExpansion * {\n  for (const auto &expansion : shorthand_expansions) {\n    if (expansion.escape == escape) {\n      return &expansion;\n    }\n  }\n\n  return nullptr;\n}\n\n} // namespace\n\ninline auto preprocess_regex(const std::string &pattern)\n    -> std::optional<std::string> {\n  std::string result;\n  result.reserve(pattern.size() * 2);\n  bool in_class = false;\n\n  for (std::size_t position = 0; position < pattern.size(); ++position) {\n    const char current = pattern[position];\n    if (current == '[' && !is_escaped(pattern, position) && !in_class) {\n      // Find end both ways and check which applies\n      const auto simple_end = find_bracket_end(pattern, position + 1, false);\n      const auto nested_end = find_bracket_end(pattern, position + 1, true);\n\n      const auto nested_content =\n          pattern.substr(position + 1, nested_end - position - 2);\n\n      // Check for v-flag operators in nested content\n      const bool nested_has_ops =\n          nested_content.contains(\"--\") || nested_content.contains(\"&&\");\n\n      // Check if nested content starts with a nested bracket\n      // This indicates true v-flag nested class syntax like [[a-z]...]\n      const bool starts_with_nested =\n          !nested_content.empty() && nested_content[0] == '[';\n\n      // Check if the character after the simple bracket end continues\n      // the class with more v-flag syntax (another nested class or outer\n      // closing bracket). This distinguishes true v-flag nesting like\n      // [[a-z][A-Z]] from a literal [ inside a standard class like [[(]\n      const bool after_simple_continues_class =\n          simple_end < pattern.size() &&\n          (pattern[simple_end] == '[' || pattern[simple_end] == ']');\n\n      // Use v-flag mode if:\n      // 1. Nested content has v-flag operators (-- or &&), OR\n      // 2. Content starts with [ (indicating v-flag nested class syntax)\n      //    AND the ends differ AND the class continues after simple end\n      const bool use_v_flag =\n          nested_has_ops || (starts_with_nested && simple_end != nested_end &&\n                             after_simple_continues_class);\n\n      if (use_v_flag) {\n        const auto expanded = expand_char_class(nested_content);\n        if (!expanded) {\n          return std::nullopt;\n        }\n\n        result += *expanded;\n        position = nested_end - 1;\n        continue;\n      }\n\n      // No v-flag syntax - use standard mode\n      // This handles standard patterns like [^!*,;{}[\\]~\\n] where [ is literal\n      in_class = true;\n    } else if (current == ']' && !is_escaped(pattern, position)) {\n      in_class = false;\n    }\n\n    if (current != '\\\\' || position + 1 >= pattern.size()) {\n      result += current;\n      continue;\n    }\n\n    const char next = pattern[position + 1];\n    if (std::string_view{\"\\\\[]^$\"}.contains(next)) {\n      result += current;\n      result += next;\n      ++position;\n      continue;\n    }\n\n    if (next == 'u' && position + 2 < pattern.size()) {\n      if (pattern[position + 2] == '{') {\n        result += \"\\\\x{\";\n        for (position += 3;\n             position < pattern.size() && pattern[position] != '}';\n             ++position) {\n          result += pattern[position];\n        }\n\n        if (position < pattern.size()) {\n          result += '}';\n        }\n\n        continue;\n      }\n\n      if (position + 5 < pattern.size() && all_hex(pattern, position + 2, 4)) {\n        result += \"\\\\x{\" + pattern.substr(position + 2, 4) + '}';\n        position += 5;\n        continue;\n      }\n    }\n\n    if ((next == 'p' || next == 'P') && position + 2 < pattern.size() &&\n        pattern[position + 2] == '{') {\n      const auto start = position;\n      std::string name;\n      for (position += 3; position < pattern.size() && pattern[position] != '}';\n           ++position) {\n        name += pattern[position];\n      }\n\n      if (position < pattern.size()) {\n        if (auto translated = translate_property(name, next == 'P')) {\n          result += *translated;\n        } else {\n          result += pattern.substr(start, position - start + 1);\n        }\n      } else {\n        position = start;\n        result += current;\n      }\n\n      continue;\n    }\n\n    if (const auto *expansion = find_shorthand(next)) {\n      if (in_class && expansion->inside_class.empty()) {\n        result += std::string{current} + next;\n      } else {\n        result += in_class ? expansion->inside_class : expansion->outside_class;\n      }\n\n      ++position;\n    } else {\n      result += current;\n    }\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/regex/regex.cc",
    "content": "#include <sourcemeta/core/regex.h>\n\n#include <pcre2.h>\n\n#include \"preprocess.h\"\n\n#include <cassert>      // assert\n#include <charconv>     // std::from_chars\n#include <cstdint>      // std::uint64_t\n#include <regex>        // std::regex, std::smatch, std::regex_match\n#include <string>       // std::string\n#include <string_view>  // std::string_view\n#include <system_error> // std::errc\n#include <utility>      // std::unreachable\n\nnamespace sourcemeta::core {\n\nauto to_regex(const std::string_view pattern) -> std::optional<Regex> {\n  if (pattern == \".*\" || pattern == \"^.*$\" || pattern == \"^(.*)$\" ||\n      pattern == \"(.*)\" || pattern == \"[\\\\s\\\\S]*\" || pattern == \"^[\\\\s\\\\S]*$\") {\n    return RegexTypeNoop{};\n\n    // Note that the JSON Schema specification does not impose the use of any\n    // regular expression flag. Given popular adoption, we assume `.` matches\n    // new line characters (as in the `DOTALL`) option\n  } else if (pattern == \".+\" || pattern == \"^.+$\" || pattern == \"^(.+)$\" ||\n             pattern == \".\") {\n    return RegexTypeNonEmpty{};\n  }\n\n  const char *const pattern_data{pattern.empty() ? \"\" : pattern.data()};\n\n  const std::regex PREFIX_REGEX{R\"(^\\^([a-zA-Z0-9-_/@]+)(\\.\\*)?)\"};\n  std::cmatch matches_prefix;\n  if (std::regex_match(pattern_data, pattern_data + pattern.size(),\n                       matches_prefix, PREFIX_REGEX)) {\n    return RegexTypePrefix{matches_prefix[1].str()};\n  }\n\n  const std::regex RANGE_REGEX{R\"(^\\^\\.\\{(\\d+),(\\d+)\\}\\$$)\"};\n  std::cmatch matches_range;\n  if (std::regex_match(pattern_data, pattern_data + pattern.size(),\n                       matches_range, RANGE_REGEX)) {\n    const auto minimum_string = matches_range[1].str();\n    const auto maximum_string = matches_range[2].str();\n    std::uint64_t minimum{};\n    std::uint64_t maximum{};\n    const auto minimum_result =\n        std::from_chars(minimum_string.data(),\n                        minimum_string.data() + minimum_string.size(), minimum);\n    const auto maximum_result =\n        std::from_chars(maximum_string.data(),\n                        maximum_string.data() + maximum_string.size(), maximum);\n    if (minimum_result.ec != std::errc{} || maximum_result.ec != std::errc{}) {\n      return std::nullopt;\n    }\n\n    assert(minimum <= maximum);\n    return RegexTypeRange{minimum, maximum};\n  }\n\n  const auto pcre2_pattern{preprocess_regex(std::string{pattern})};\n  if (!pcre2_pattern.has_value()) {\n    return std::nullopt;\n  }\n\n  int pcre2_error_code{0};\n  PCRE2_SIZE pcre2_error_offset{0};\n  pcre2_code *pcre2_regex_raw{pcre2_compile(\n      reinterpret_cast<PCRE2_SPTR>(pcre2_pattern.value().c_str()),\n      pcre2_pattern.value().size(),\n      PCRE2_UTF | PCRE2_UCP | PCRE2_NO_AUTO_CAPTURE | PCRE2_DOTALL |\n          PCRE2_DOLLAR_ENDONLY | PCRE2_NEVER_BACKSLASH_C | PCRE2_NO_UTF_CHECK,\n      &pcre2_error_code, &pcre2_error_offset, nullptr)};\n\n  if (pcre2_regex_raw != nullptr) {\n    std::shared_ptr<pcre2_code> pcre2_regex{pcre2_regex_raw, pcre2_code_free};\n    pcre2_jit_compile(pcre2_regex.get(), PCRE2_JIT_COMPLETE);\n    return RegexTypePCRE2{std::shared_ptr<void>(pcre2_regex)};\n  }\n\n  return std::nullopt;\n}\n\nauto matches(const Regex &regex, const std::string_view value) -> bool {\n  switch (static_cast<RegexIndex>(regex.index())) {\n    case RegexIndex::Prefix:\n      return value.starts_with(*std::get_if<RegexTypePrefix>(&regex));\n    case RegexIndex::NonEmpty:\n      return !value.empty();\n    case RegexIndex::Range:\n      return value.size() >= std::get_if<RegexTypeRange>(&regex)->first &&\n             value.size() <= std::get_if<RegexTypeRange>(&regex)->second;\n    case RegexIndex::PCRE2: {\n      const RegexTypePCRE2 *pcre2_regex{std::get_if<RegexTypePCRE2>(&regex)};\n      auto *pcre2_code_ptr{static_cast<pcre2_code *>(pcre2_regex->code.get())};\n      // Re-use this to avoid creating and destroying the `struct`on every call\n      thread_local pcre2_match_data *match_data{\n          pcre2_match_data_create(1, nullptr)};\n      const int match_result{pcre2_match(\n          pcre2_code_ptr, reinterpret_cast<PCRE2_SPTR>(value.data()),\n          value.size(), 0, PCRE2_NO_UTF_CHECK, match_data, nullptr)};\n      return match_result >= 0;\n    }\n    case RegexIndex::Noop:\n      return true;\n  }\n\n  std::unreachable();\n}\n\nauto matches_if_valid(const std::string_view pattern,\n                      const std::string_view value) -> bool {\n  const auto regex{to_regex(pattern)};\n  return regex.has_value() && matches(regex.value(), value);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/semver/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME semver\n  PRIVATE_HEADERS error.h\n  SOURCES semver.cc)\ntarget_link_libraries(sourcemeta_core_semver\n  PUBLIC sourcemeta::core::preprocessor)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME semver)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/semver/include/sourcemeta/core/semver.h",
    "content": "#ifndef SOURCEMETA_CORE_SEMVER_H_\n#define SOURCEMETA_CORE_SEMVER_H_\n\n#ifndef SOURCEMETA_CORE_SEMVER_EXPORT\n#include <sourcemeta/core/semver_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/semver_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <sourcemeta/core/preprocessor.h>\n\n#include <cstdint>     // std::uint64_t\n#include <optional>    // std::optional\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\n/// @defgroup semver SemVer\n/// @brief An implementation of the Semantic Versioning 2.0.0 specification.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/semver.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup semver\n/// A non-owning view over a parsed SemVer 2.0.0 version string.\n/// The input string must outlive this object.\nclass SOURCEMETA_CORE_SEMVER_EXPORT SemVer {\npublic:\n  enum class Mode : std::uint8_t {\n    Strict,\n\n    // Permits the following deviations on the version core only:\n    // - Optional \"v\" or \"V\" prefix (e.g. \"v1.2.3\")\n    // - Missing patch, defaulting to 0 (e.g. \"1.2\")\n    // - Missing minor and patch, defaulting to 0 (e.g. \"1\")\n    // - Combinations of the above (e.g. \"v1\", \"v1.2\")\n    Loose\n  };\n\n  SemVer(std::string_view input, Mode mode = Mode::Strict);\n\n  [[nodiscard]] static auto from(std::string_view input,\n                                 Mode mode = Mode::Strict) noexcept\n      -> std::optional<SemVer>;\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto major() const noexcept\n      -> std::uint64_t {\n    return this->major_;\n  }\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto minor() const noexcept\n      -> std::uint64_t {\n    return this->minor_;\n  }\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto patch() const noexcept\n      -> std::uint64_t {\n    return this->patch_;\n  }\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto pre_release() const noexcept\n      -> std::string_view {\n    return this->pre_release_;\n  }\n\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto build() const noexcept\n      -> std::string_view {\n    return this->build_;\n  }\n\n  // Build metadata is included in equality because equality is not\n  // precedence. The spec says build metadata must be ignored when\n  // determining version *precedence*, but two versions with different build\n  // metadata are distinct versions.\n  // See https://semver.org/spec/v2.0.0.html#spec-item-10\n  SOURCEMETA_FORCEINLINE inline auto\n  operator==(const SemVer &other) const noexcept -> bool {\n    return this->major_ == other.major_ && this->minor_ == other.minor_ &&\n           this->patch_ == other.patch_ &&\n           this->pre_release_ == other.pre_release_ &&\n           this->build_ == other.build_;\n  }\n\n  auto operator<(const SemVer &other) const noexcept -> bool;\n\n  SOURCEMETA_FORCEINLINE inline auto\n  operator!=(const SemVer &other) const noexcept -> bool {\n    return !(*this == other);\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto\n  operator>(const SemVer &other) const noexcept -> bool {\n    return other < *this;\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto\n  operator<=(const SemVer &other) const noexcept -> bool {\n    return !(other < *this);\n  }\n\n  SOURCEMETA_FORCEINLINE inline auto\n  operator>=(const SemVer &other) const noexcept -> bool {\n    return !(*this < other);\n  }\n\n  [[nodiscard]] auto to_string() const -> std::string;\n\nprivate:\n  SemVer() = default;\n  std::uint64_t major_{0};\n  std::uint64_t minor_{0};\n  std::uint64_t patch_{0};\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::string_view pre_release_;\n  std::string_view build_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/semver/include/sourcemeta/core/semver_error.h",
    "content": "#ifndef SOURCEMETA_CORE_SEMVER_ERROR_H_\n#define SOURCEMETA_CORE_SEMVER_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_SEMVER_EXPORT\n#include <sourcemeta/core/semver_export.h>\n#endif\n\n#include <cstdint>   // std::uint64_t\n#include <exception> // std::exception\n\nnamespace sourcemeta::core {\n\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\nclass SOURCEMETA_CORE_SEMVER_EXPORT SemVerParseError : public std::exception {\npublic:\n  SemVerParseError(const std::uint64_t column) : column_{column} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The input is not a valid Semantic Version\";\n  }\n\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  std::uint64_t column_;\n};\n\nclass SOURCEMETA_CORE_SEMVER_EXPORT SemVerOverflowError\n    : public std::exception {\npublic:\n  SemVerOverflowError(const std::uint64_t column) : column_{column} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The numeric component of the Semantic Version overflows\";\n  }\n\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  std::uint64_t column_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/semver/semver.cc",
    "content": "#include <sourcemeta/core/semver.h>\n\n#include <array>    // std::array\n#include <charconv> // std::to_chars\n#include <limits>   // std::numeric_limits\n#include <optional> // std::optional, std::nullopt\n#include <string>   // std::string\n\nnamespace {\n\nauto is_digit(const char character) -> bool {\n  return character >= '0' && character <= '9';\n}\n\nauto is_letter(const char character) -> bool {\n  return (character >= 'A' && character <= 'Z') ||\n         (character >= 'a' && character <= 'z');\n}\n\nauto is_identifier_character(const char character) -> bool {\n  return is_digit(character) || is_letter(character) || character == '-';\n}\n\nconstexpr auto UINT64_MAX_VALUE = std::numeric_limits<std::uint64_t>::max();\nconstexpr auto UINT64_MAX_DIV_10 = UINT64_MAX_VALUE / 10;\nconstexpr auto UINT64_MAX_MOD_10 = UINT64_MAX_VALUE % 10;\n\nenum class NumericParseResult : std::uint8_t { success, invalid, overflow };\n\nauto parse_numeric_identifier(const std::string_view input,\n                              std::size_t &position, std::uint64_t &result)\n    -> NumericParseResult {\n  if (position >= input.size() || !is_digit(input[position])) {\n    return NumericParseResult::invalid;\n  }\n\n  if (input[position] == '0' && position + 1 < input.size() &&\n      is_digit(input[position + 1])) {\n    return NumericParseResult::invalid;\n  }\n\n  std::uint64_t value = 0;\n  while (position < input.size() && is_digit(input[position])) {\n    const auto digit = static_cast<std::uint64_t>(input[position] - '0');\n    if (value > UINT64_MAX_DIV_10 ||\n        (value == UINT64_MAX_DIV_10 && digit > UINT64_MAX_MOD_10)) {\n      return NumericParseResult::overflow;\n    }\n\n    value = value * 10 + digit;\n    ++position;\n  }\n\n  result = value;\n  return NumericParseResult::success;\n}\n\nauto validate_pre_release_identifier(const std::string_view identifier)\n    -> bool {\n  if (identifier.empty()) {\n    return false;\n  }\n\n  bool has_non_digit = false;\n  for (const auto character : identifier) {\n    if (!is_identifier_character(character)) {\n      return false;\n    }\n\n    if (!is_digit(character)) {\n      has_non_digit = true;\n    }\n  }\n\n  if (!has_non_digit && identifier.size() > 1 && identifier[0] == '0') {\n    return false;\n  }\n\n  return true;\n}\n\nauto validate_build_identifier(const std::string_view identifier) -> bool {\n  if (identifier.empty()) {\n    return false;\n  }\n\n  for (const auto character : identifier) {\n    if (!is_identifier_character(character)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\ntemplate <auto validator>\nauto validate_dot_separated(const std::string_view input) -> bool {\n  if (input.empty()) {\n    return false;\n  }\n\n  std::size_t start = 0;\n  while (start <= input.size()) {\n    auto dot_position = input.find('.', start);\n    if (dot_position == std::string_view::npos) {\n      dot_position = input.size();\n    }\n\n    if (!validator(input.substr(start, dot_position - start))) {\n      return false;\n    }\n\n    start = dot_position + 1;\n    if (dot_position == input.size()) {\n      break;\n    }\n  }\n\n  return true;\n}\n\nstruct IdentifierInfo {\n  bool is_numeric;\n  bool overflowed;\n  std::uint64_t numeric_value;\n};\n\nauto classify_identifier(const std::string_view identifier) noexcept\n    -> IdentifierInfo {\n  std::uint64_t value = 0;\n  for (const auto character : identifier) {\n    if (!is_digit(character)) {\n      return {.is_numeric = false, .overflowed = false, .numeric_value = 0};\n    }\n\n    const auto digit = static_cast<std::uint64_t>(character - '0');\n    if (value > UINT64_MAX_DIV_10 ||\n        (value == UINT64_MAX_DIV_10 && digit > UINT64_MAX_MOD_10)) {\n      return {.is_numeric = true, .overflowed = true, .numeric_value = 0};\n    }\n\n    value = value * 10 + digit;\n  }\n\n  return {.is_numeric = true, .overflowed = false, .numeric_value = value};\n}\n\nauto compare_pre_release(const std::string_view left,\n                         const std::string_view right) noexcept -> int {\n  if (left.empty() && right.empty()) {\n    return 0;\n  }\n\n  if (left.empty()) {\n    return 1;\n  }\n\n  if (right.empty()) {\n    return -1;\n  }\n\n  std::size_t left_position = 0;\n  std::size_t right_position = 0;\n\n  while (left_position <= left.size() && right_position <= right.size()) {\n    auto left_dot = left.find('.', left_position);\n    if (left_dot == std::string_view::npos) {\n      left_dot = left.size();\n    }\n\n    auto right_dot = right.find('.', right_position);\n    if (right_dot == std::string_view::npos) {\n      right_dot = right.size();\n    }\n\n    const std::string_view left_identifier{left.data() + left_position,\n                                           left_dot - left_position};\n    const std::string_view right_identifier{right.data() + right_position,\n                                            right_dot - right_position};\n\n    const auto left_info = classify_identifier(left_identifier);\n    const auto right_info = classify_identifier(right_identifier);\n\n    if (left_info.is_numeric && right_info.is_numeric) {\n      if (left_info.overflowed || right_info.overflowed) {\n        if (left_identifier.size() != right_identifier.size()) {\n          return left_identifier.size() < right_identifier.size() ? -1 : 1;\n        }\n\n        if (left_identifier < right_identifier) {\n          return -1;\n        }\n\n        if (left_identifier > right_identifier) {\n          return 1;\n        }\n      } else {\n        if (left_info.numeric_value < right_info.numeric_value) {\n          return -1;\n        }\n\n        if (left_info.numeric_value > right_info.numeric_value) {\n          return 1;\n        }\n      }\n    } else if (left_info.is_numeric && !right_info.is_numeric) {\n      return -1;\n    } else if (!left_info.is_numeric && right_info.is_numeric) {\n      return 1;\n    } else {\n      if (left_identifier < right_identifier) {\n        return -1;\n      }\n\n      if (left_identifier > right_identifier) {\n        return 1;\n      }\n    }\n\n    left_position = left_dot + 1;\n    right_position = right_dot + 1;\n\n    if (left_dot == left.size() && right_dot == right.size()) {\n      break;\n    }\n\n    if (left_dot == left.size()) {\n      return -1;\n    }\n\n    if (right_dot == right.size()) {\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\ntemplate <bool should_throw, bool loose>\nauto parse_semver(const std::string_view input, std::uint64_t &major,\n                  std::uint64_t &minor, std::uint64_t &patch,\n                  std::string_view &pre_release, std::string_view &build)\n    -> bool {\n  std::size_t position = 0;\n\n  if constexpr (loose) {\n    if (position < input.size() &&\n        (input[position] == 'v' || input[position] == 'V')) {\n      ++position;\n    }\n  }\n\n  const auto major_result = parse_numeric_identifier(input, position, major);\n  if (major_result == NumericParseResult::overflow) {\n    if constexpr (should_throw) {\n      throw sourcemeta::core::SemVerOverflowError(position + 1);\n    }\n\n    return false;\n  }\n\n  if (major_result == NumericParseResult::invalid) {\n    if constexpr (should_throw) {\n      throw sourcemeta::core::SemVerParseError(position + 1);\n    }\n\n    return false;\n  }\n\n  auto can_end_core = [&]() -> bool {\n    if (position >= input.size() || input[position] == '-' ||\n        input[position] == '+') {\n      return loose;\n    }\n\n    return input[position] == '.';\n  };\n\n  if (!can_end_core()) {\n    if constexpr (should_throw) {\n      throw sourcemeta::core::SemVerParseError(position + 1);\n    }\n\n    return false;\n  }\n\n  if (position < input.size() && input[position] == '.') {\n    ++position;\n\n    const auto minor_result = parse_numeric_identifier(input, position, minor);\n    if (minor_result == NumericParseResult::overflow) {\n      if constexpr (should_throw) {\n        throw sourcemeta::core::SemVerOverflowError(position + 1);\n      }\n\n      return false;\n    }\n\n    if (minor_result == NumericParseResult::invalid) {\n      if constexpr (should_throw) {\n        throw sourcemeta::core::SemVerParseError(position + 1);\n      }\n\n      return false;\n    }\n\n    if (!can_end_core()) {\n      if constexpr (should_throw) {\n        throw sourcemeta::core::SemVerParseError(position + 1);\n      }\n\n      return false;\n    }\n\n    if (position < input.size() && input[position] == '.') {\n      ++position;\n\n      const auto patch_result =\n          parse_numeric_identifier(input, position, patch);\n      if (patch_result == NumericParseResult::overflow) {\n        if constexpr (should_throw) {\n          throw sourcemeta::core::SemVerOverflowError(position + 1);\n        }\n\n        return false;\n      }\n\n      if (patch_result == NumericParseResult::invalid) {\n        if constexpr (should_throw) {\n          throw sourcemeta::core::SemVerParseError(position + 1);\n        }\n\n        return false;\n      }\n    }\n  }\n\n  if (position < input.size() && input[position] == '-') {\n    ++position;\n    const auto start = position;\n    while (position < input.size() && input[position] != '+') {\n      ++position;\n    }\n\n    pre_release = input.substr(start, position - start);\n    if (!validate_dot_separated<validate_pre_release_identifier>(pre_release)) {\n      if constexpr (should_throw) {\n        throw sourcemeta::core::SemVerParseError(start + 1);\n      }\n\n      return false;\n    }\n  }\n\n  if (position < input.size() && input[position] == '+') {\n    ++position;\n    const auto start = position;\n    position = input.size();\n\n    build = input.substr(start, position - start);\n    if (!validate_dot_separated<validate_build_identifier>(build)) {\n      if constexpr (should_throw) {\n        throw sourcemeta::core::SemVerParseError(start + 1);\n      }\n\n      return false;\n    }\n  }\n\n  if (position != input.size()) {\n    if constexpr (should_throw) {\n      throw sourcemeta::core::SemVerParseError(position + 1);\n    }\n\n    return false;\n  }\n\n  return true;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nSemVer::SemVer(const std::string_view input, const Mode mode) {\n  if (mode == Mode::Loose) {\n    parse_semver<true, true>(input, this->major_, this->minor_, this->patch_,\n                             this->pre_release_, this->build_);\n  } else {\n    parse_semver<true, false>(input, this->major_, this->minor_, this->patch_,\n                              this->pre_release_, this->build_);\n  }\n}\n\nauto SemVer::from(const std::string_view input, const Mode mode) noexcept\n    -> std::optional<SemVer> {\n  SemVer result;\n  bool success = false;\n\n  if (mode == Mode::Loose) {\n    success = parse_semver<false, true>(input, result.major_, result.minor_,\n                                        result.patch_, result.pre_release_,\n                                        result.build_);\n  } else {\n    success = parse_semver<false, false>(input, result.major_, result.minor_,\n                                         result.patch_, result.pre_release_,\n                                         result.build_);\n  }\n\n  if (success) {\n    return result;\n  }\n\n  return std::nullopt;\n}\n\nauto SemVer::operator<(const SemVer &other) const noexcept -> bool {\n  if (this->major_ != other.major_) {\n    return this->major_ < other.major_;\n  }\n\n  if (this->minor_ != other.minor_) {\n    return this->minor_ < other.minor_;\n  }\n\n  if (this->patch_ != other.patch_) {\n    return this->patch_ < other.patch_;\n  }\n\n  return compare_pre_release(this->pre_release_, other.pre_release_) < 0;\n}\n\nauto SemVer::to_string() const -> std::string {\n  std::array<char, 20> buffer{};\n\n  auto [major_end, major_error] =\n      std::to_chars(buffer.data(), buffer.data() + buffer.size(), this->major_);\n  std::string result{buffer.data(), major_end};\n  result += '.';\n\n  auto [minor_end, minor_error] =\n      std::to_chars(buffer.data(), buffer.data() + buffer.size(), this->minor_);\n  result.append(buffer.data(), minor_end);\n  result += '.';\n\n  auto [patch_end, patch_error] =\n      std::to_chars(buffer.data(), buffer.data() + buffer.size(), this->patch_);\n  result.append(buffer.data(), patch_end);\n  if (!this->pre_release_.empty()) {\n    result += '-';\n    result.append(this->pre_release_.data(), this->pre_release_.size());\n  }\n\n  if (!this->build_.empty()) {\n    result += '+';\n    result.append(this->build_.data(), this->build_.size());\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/time/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME time\n  SOURCES gmt.cc rfc3339_datetime.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME time)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/time/gmt.cc",
    "content": "#include <sourcemeta/core/time.h>\n\n#include <cassert>     // assert\n#include <ctime>       // std::time_t, std::tm, std::gmtime, std::mktime, timegm\n#include <iomanip>     // std::put_time, std::get_time\n#include <sstream>     // std::ostringstream, std::istringstream\n#include <stdexcept>   // std::invalid_argument, std::runtime_error\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\n#if defined(_MSC_VER)\n#include <errno.h>\n#endif\n\nnamespace {\nconstexpr auto FORMAT_GMT{\"%a, %d %b %Y %H:%M:%S GMT\"};\n}\n\nnamespace sourcemeta::core {\n\nauto to_gmt(const std::chrono::system_clock::time_point time) -> std::string {\n  const std::time_t ctime = std::chrono::system_clock::to_time_t(time);\n  std::tm buffer;\n#if defined(_MSC_VER)\n  if (gmtime_s(&buffer, &ctime) != 0) {\n    throw std::runtime_error(\"Could not convert time point to GMT\");\n  }\n#else\n  if (gmtime_r(&ctime, &buffer) == nullptr) {\n    throw std::runtime_error(\"Could not convert time point to GMT\");\n  }\n#endif\n  std::tm *parts = &buffer;\n  assert(parts);\n  std::ostringstream stream;\n  stream << std::put_time(parts, FORMAT_GMT);\n  return stream.str();\n}\n\nauto from_gmt(const std::string_view time)\n    -> std::chrono::system_clock::time_point {\n  std::istringstream stream{std::string{time}};\n  std::tm parts = {};\n  stream >> std::get_time(&parts, FORMAT_GMT);\n  if (stream.fail()) {\n    throw std::invalid_argument(\"Invalid GMT timestamp\");\n  }\n\n#if defined(_MSC_VER)\n  return std::chrono::system_clock::from_time_t(_mkgmtime(&parts));\n#else\n  return std::chrono::system_clock::from_time_t(timegm(&parts));\n#endif\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/time/include/sourcemeta/core/time.h",
    "content": "#ifndef SOURCEMETA_CORE_TIME_H_\n#define SOURCEMETA_CORE_TIME_H_\n\n#ifndef SOURCEMETA_CORE_TIME_EXPORT\n#include <sourcemeta/core/time_export.h>\n#endif\n\n#include <chrono>      // std::chrono::system_clock::time_point\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\n/// @defgroup time Time\n/// @brief A growing implementation of time-related utilities for standards\n/// such as RFC 7231 (GMT) and RFC 3339 (Internet Date/Time Format).\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/time.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup time\n/// Convert a time point into a GMT string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/time.h>\n///\n/// #include <chrono>\n/// #include <ctime>\n/// #include <cassert>\n///\n/// std::tm parts = {};\n/// parts.tm_year = 115;\n/// parts.tm_mon = 9;\n/// parts.tm_mday = 21;\n/// parts.tm_hour = 11;\n/// parts.tm_min = 28;\n/// parts.tm_sec = 0;\n/// parts.tm_isdst = 0;\n///\n/// const auto point{std::chrono::system_clock::from_time_t(timegm(&parts))};\n///\n/// assert(sourcemeta::core::to_gmt(point) ==\n///   \"Wed, 21 Oct 2015 11:28:00 GMT\");\n/// ```\n///\n/// On Windows, you might need to use `_mkgmtime` instead of `timegm`.\nSOURCEMETA_CORE_TIME_EXPORT\nauto to_gmt(const std::chrono::system_clock::time_point time) -> std::string;\n\n/// @ingroup time\n/// Parse a GMT string into a time point. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/time.h>\n///\n/// #include <chrono>\n/// #include <ctime>\n/// #include <cassert>\n///\n/// const auto point{\n///     sourcemeta::core::from_gmt(\"Wed, 21 Oct 2015 11:28:00 GMT\")};\n///\n/// std::tm parts = {};\n/// parts.tm_year = 115;\n/// parts.tm_mon = 9;\n/// parts.tm_mday = 21;\n/// parts.tm_hour = 11;\n/// parts.tm_min = 28;\n/// parts.tm_sec = 0;\n/// parts.tm_isdst = 0;\n/// const auto expected{std::chrono::system_clock::from_time_t(timegm(&parts))};\n///\n/// assert(point = expected);\n/// ```\n///\n/// On Windows, you might need to use `_mkgmtime` instead of `timegm`.\nSOURCEMETA_CORE_TIME_EXPORT\nauto from_gmt(const std::string_view time)\n    -> std::chrono::system_clock::time_point;\n\n/// @ingroup time\n/// Check whether the given string is a valid date-time value per RFC 3339\n/// Section 5.6 (Internet Date/Time Format). This implements the full\n/// `date-time` production rule:\n///\n/// ```\n/// date-time = full-date \"T\" full-time\n/// ```\n///\n/// where \"T\" may also be lowercase \"t\" (per RFC 3339 §5.6 NOTE). For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/time.h>\n///\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::is_rfc3339_datetime(\"1985-04-12T23:20:50.52Z\"));\n/// assert(sourcemeta::core::is_rfc3339_datetime(\"1996-12-19T16:39:57-08:00\"));\n/// assert(sourcemeta::core::is_rfc3339_datetime(\"1990-12-31T23:59:60Z\"));\n/// assert(!sourcemeta::core::is_rfc3339_datetime(\"2024-01-15T14:30:00\"));\n/// assert(!sourcemeta::core::is_rfc3339_datetime(\"2024-01-15 14:30:00Z\"));\n/// ```\nSOURCEMETA_CORE_TIME_EXPORT\nauto is_rfc3339_datetime(const std::string_view value) -> bool;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/time/rfc3339_datetime.cc",
    "content": "#include <sourcemeta/core/time.h>\n\n#include <array> // std::array\n\nnamespace sourcemeta::core {\n\nstatic constexpr auto is_digit(const char character) -> bool {\n  return character >= '0' && character <= '9';\n}\n\nstatic constexpr auto is_leap_year(const unsigned int year) -> bool {\n  return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);\n}\n\nstatic constexpr auto max_day_in_month(const unsigned int month,\n                                       const unsigned int year)\n    -> unsigned int {\n  constexpr std::array<unsigned int, 13> days{\n      {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};\n  if (month == 2 && is_leap_year(year)) {\n    return 29;\n  }\n  return days[month];\n}\n\nauto is_rfc3339_datetime(const std::string_view value) -> bool {\n  const auto size{value.size()};\n\n  // Minimum valid date-time: \"YYYY-MM-DDTHH:MM:SSZ\" = 20 characters\n  if (size < 20) {\n    return false;\n  }\n\n  std::string_view::size_type position{0};\n\n  // --- full-date: date-fullyear \"-\" date-month \"-\" date-mday ---\n\n  // date-fullyear = 4DIGIT\n  if (!is_digit(value[0]) || !is_digit(value[1]) || !is_digit(value[2]) ||\n      !is_digit(value[3])) {\n    return false;\n  }\n  const auto year{static_cast<unsigned int>(value[0] - '0') * 1000 +\n                  static_cast<unsigned int>(value[1] - '0') * 100 +\n                  static_cast<unsigned int>(value[2] - '0') * 10 +\n                  static_cast<unsigned int>(value[3] - '0')};\n  position = 4;\n\n  // \"-\"\n  if (value[position] != '-') {\n    return false;\n  }\n  position += 1;\n\n  // date-month = 2DIGIT ; 01-12\n  if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n    return false;\n  }\n  const auto month{static_cast<unsigned int>(value[position] - '0') * 10 +\n                   static_cast<unsigned int>(value[position + 1] - '0')};\n  if (month < 1 || month > 12) {\n    return false;\n  }\n  position += 2;\n\n  // \"-\"\n  if (value[position] != '-') {\n    return false;\n  }\n  position += 1;\n\n  // date-mday = 2DIGIT ; 01-28/29/30/31 based on month/year\n  if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n    return false;\n  }\n  const auto day{static_cast<unsigned int>(value[position] - '0') * 10 +\n                 static_cast<unsigned int>(value[position + 1] - '0')};\n  position += 2;\n\n  // --- \"T\" or \"t\" separator ---\n  if (value[position] != 'T' && value[position] != 't') {\n    return false;\n  }\n  position += 1;\n\n  // --- partial-time: time-hour \":\" time-minute \":\" time-second ---\n\n  // time-hour = 2DIGIT ; 00-23\n  if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n    return false;\n  }\n  const auto hour{static_cast<unsigned int>(value[position] - '0') * 10 +\n                  static_cast<unsigned int>(value[position + 1] - '0')};\n  if (hour > 23) {\n    return false;\n  }\n  position += 2;\n\n  // \":\"\n  if (value[position] != ':') {\n    return false;\n  }\n  position += 1;\n\n  // time-minute = 2DIGIT ; 00-59\n  if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n    return false;\n  }\n  const auto minute{static_cast<unsigned int>(value[position] - '0') * 10 +\n                    static_cast<unsigned int>(value[position + 1] - '0')};\n  if (minute > 59) {\n    return false;\n  }\n  position += 2;\n\n  // \":\"\n  if (value[position] != ':') {\n    return false;\n  }\n  position += 1;\n\n  // time-second = 2DIGIT ; 00-60 (60 = leap second per §5.7)\n  if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n    return false;\n  }\n  const auto second{static_cast<unsigned int>(value[position] - '0') * 10 +\n                    static_cast<unsigned int>(value[position + 1] - '0')};\n  if (second > 60) {\n    return false;\n  }\n  position += 2;\n\n  // --- [time-secfrac] = \".\" 1*DIGIT ---\n  if (position < size && value[position] == '.') {\n    position += 1;\n    if (position >= size || !is_digit(value[position])) {\n      // \".\" must be followed by at least 1 digit\n      return false;\n    }\n    while (position < size && is_digit(value[position])) {\n      position += 1;\n    }\n  }\n\n  // --- time-offset = \"Z\" / time-numoffset ---\n  if (position >= size) {\n    // No time offset present — invalid\n    return false;\n  }\n\n  if (value[position] == 'Z' || value[position] == 'z') {\n    position += 1;\n  } else if (value[position] == '+' || value[position] == '-') {\n    position += 1;\n\n    // time-numoffset = (\"+\" / \"-\") time-hour \":\" time-minute\n    if (position + 5 > size) {\n      return false;\n    }\n\n    // Offset time-hour = 2DIGIT ; 00-23\n    if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n      return false;\n    }\n    const auto offset_hour{\n        static_cast<unsigned int>(value[position] - '0') * 10 +\n        static_cast<unsigned int>(value[position + 1] - '0')};\n    if (offset_hour > 23) {\n      return false;\n    }\n    position += 2;\n\n    // \":\" — REQUIRED (colonless offsets like +0530 are invalid per §5.6)\n    if (value[position] != ':') {\n      return false;\n    }\n    position += 1;\n\n    // Offset time-minute = 2DIGIT ; 00-59\n    if (!is_digit(value[position]) || !is_digit(value[position + 1])) {\n      return false;\n    }\n    const auto offset_minute{\n        static_cast<unsigned int>(value[position] - '0') * 10 +\n        static_cast<unsigned int>(value[position + 1] - '0')};\n    if (offset_minute > 59) {\n      return false;\n    }\n    position += 2;\n  } else {\n    // Not Z, not +/-, invalid character for time-offset\n    return false;\n  }\n\n  // String must be fully consumed — no trailing characters\n  if (position != size) {\n    return false;\n  }\n\n  // --- Validate date-mday against month/year (§5.7) ---\n  if (day < 1 || day > max_day_in_month(month, year)) {\n    return false;\n  }\n\n  return true;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/unicode/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME unicode\n  SOURCES unicode.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME unicode)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/unicode/include/sourcemeta/core/unicode.h",
    "content": "#ifndef SOURCEMETA_CORE_UNICODE_H_\n#define SOURCEMETA_CORE_UNICODE_H_\n\n#ifndef SOURCEMETA_CORE_UNICODE_EXPORT\n#include <sourcemeta/core/unicode_export.h>\n#endif\n\n#include <istream>     // std::istream\n#include <optional>    // std::optional\n#include <ostream>     // std::ostream\n#include <string>      // std::string, std::u32string\n#include <string_view> // std::string_view\n\n/// @defgroup unicode Unicode\n/// @brief Unicode encoding utilities.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup unicode\n/// Encode a single Unicode codepoint as a UTF-8 string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::codepoint_to_utf8(0x41) == \"A\");\n/// ```\nSOURCEMETA_CORE_UNICODE_EXPORT\nauto codepoint_to_utf8(const char32_t codepoint) -> std::string;\n\n/// @ingroup unicode\n/// Encode a single Unicode codepoint as UTF-8 into an output stream.\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// #include <sstream>\n/// #include <cassert>\n///\n/// std::ostringstream output;\n/// sourcemeta::core::codepoint_to_utf8(0x41, output);\n/// assert(output.str() == \"A\");\n/// ```\nSOURCEMETA_CORE_UNICODE_EXPORT\nauto codepoint_to_utf8(const char32_t codepoint, std::ostream &output) -> void;\n\n/// @ingroup unicode\n/// Encode a single Unicode codepoint as UTF-8, appending to an existing string.\n/// For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// #include <cassert>\n///\n/// std::string output;\n/// sourcemeta::core::codepoint_to_utf8(0x41, output);\n/// assert(output == \"A\");\n/// ```\nSOURCEMETA_CORE_UNICODE_EXPORT\nauto codepoint_to_utf8(const char32_t codepoint, std::string &output) -> void;\n\n/// @ingroup unicode\n/// Decode a UTF-8 byte stream into a sequence of Unicode codepoints (UTF-32).\n/// Returns std::nullopt if the input contains invalid UTF-8. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// #include <sstream>\n/// #include <cassert>\n///\n/// std::istringstream input{\"A\"};\n/// const auto result{sourcemeta::core::utf8_to_utf32(input)};\n/// assert(result.has_value());\n/// assert(result.value() == std::u32string{0x41});\n/// ```\nSOURCEMETA_CORE_UNICODE_EXPORT\nauto utf8_to_utf32(std::istream &input) -> std::optional<std::u32string>;\n\n/// @ingroup unicode\n/// Decode a UTF-8 string into a sequence of Unicode codepoints (UTF-32).\n/// Returns std::nullopt if the input contains invalid UTF-8. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/unicode.h>\n/// #include <cassert>\n///\n/// const auto result{sourcemeta::core::utf8_to_utf32(\"A\")};\n/// assert(result.has_value());\n/// assert(result.value() == std::u32string{0x41});\n/// ```\nSOURCEMETA_CORE_UNICODE_EXPORT\nauto utf8_to_utf32(const std::string_view input)\n    -> std::optional<std::u32string>;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/unicode/unicode.cc",
    "content": "#include <sourcemeta/core/unicode.h>\n\n#include <cassert> // assert\n#include <cstdint> // std::uint8_t\n#include <sstream> // std::istringstream, std::ostringstream\n\nnamespace sourcemeta::core {\n\nauto codepoint_to_utf8(const char32_t codepoint, std::ostream &output) -> void {\n  assert(codepoint <= 0x10FFFF);\n  assert(codepoint < 0xD800 || codepoint > 0xDFFF);\n  if (codepoint < 0x80) {\n    output.put(static_cast<char>(codepoint));\n  } else if (codepoint < 0x800) {\n    output.put(static_cast<char>(0xC0 | (codepoint >> 6)));\n    output.put(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  } else if (codepoint < 0x10000) {\n    output.put(static_cast<char>(0xE0 | (codepoint >> 12)));\n    output.put(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));\n    output.put(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  } else {\n    output.put(static_cast<char>(0xF0 | (codepoint >> 18)));\n    output.put(static_cast<char>(0x80 | ((codepoint >> 12) & 0x3F)));\n    output.put(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));\n    output.put(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  }\n}\n\nauto codepoint_to_utf8(const char32_t codepoint, std::string &output) -> void {\n  assert(codepoint <= 0x10FFFF);\n  assert(codepoint < 0xD800 || codepoint > 0xDFFF);\n  if (codepoint < 0x80) {\n    output.push_back(static_cast<char>(codepoint));\n  } else if (codepoint < 0x800) {\n    output.push_back(static_cast<char>(0xC0 | (codepoint >> 6)));\n    output.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  } else if (codepoint < 0x10000) {\n    output.push_back(static_cast<char>(0xE0 | (codepoint >> 12)));\n    output.push_back(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));\n    output.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  } else {\n    output.push_back(static_cast<char>(0xF0 | (codepoint >> 18)));\n    output.push_back(static_cast<char>(0x80 | ((codepoint >> 12) & 0x3F)));\n    output.push_back(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));\n    output.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));\n  }\n}\n\nauto codepoint_to_utf8(const char32_t codepoint) -> std::string {\n  std::string output;\n  codepoint_to_utf8(codepoint, output);\n  return output;\n}\n\nauto utf8_to_utf32(std::istream &input) -> std::optional<std::u32string> {\n  std::u32string result;\n  std::uint8_t byte{0};\n\n  while (input.read(reinterpret_cast<char *>(&byte), 1)) {\n    char32_t code_point{0};\n    std::uint8_t continuation_count{0};\n    char32_t minimum{0};\n\n    if (byte < 0x80) {\n      result.push_back(byte);\n      continue;\n    } else if ((byte & 0xE0) == 0xC0) {\n      code_point = byte & 0x1F;\n      continuation_count = 1;\n      minimum = 0x80;\n    } else if ((byte & 0xF0) == 0xE0) {\n      code_point = byte & 0x0F;\n      continuation_count = 2;\n      minimum = 0x800;\n    } else if ((byte & 0xF8) == 0xF0) {\n      code_point = byte & 0x07;\n      continuation_count = 3;\n      minimum = 0x10000;\n    } else {\n      return std::nullopt;\n    }\n\n    for (std::uint8_t index = 0; index < continuation_count; ++index) {\n      std::uint8_t continuation{0};\n      if (!input.read(reinterpret_cast<char *>(&continuation), 1) ||\n          (continuation & 0xC0) != 0x80) {\n        return std::nullopt;\n      }\n\n      code_point = (code_point << 6) | (continuation & 0x3F);\n    }\n\n    if (code_point < minimum || code_point > 0x10FFFF ||\n        (code_point >= 0xD800 && code_point <= 0xDFFF)) {\n      return std::nullopt;\n    }\n\n    result.push_back(code_point);\n  }\n\n  if (!input.eof()) {\n    return std::nullopt;\n  }\n\n  return result;\n}\n\nauto utf8_to_utf32(const std::string_view input)\n    -> std::optional<std::u32string> {\n  // TODO: Replace std::istringstream with std::ispanstream once libc++\n  // supports it (__cpp_lib_spanstream), to avoid copying the input string\n  std::istringstream stream{std::string{input}};\n  return utf8_to_utf32(stream);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME uri\n  PRIVATE_HEADERS error.h\n  SOURCES uri.cc parse.cc accessors.cc setters.cc recompose.cc canonicalize.cc\n          resolution.cc filesystem.cc query.cc escaping.h normalize.h grammar.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME uri)\nendif()\n\ntarget_link_libraries(sourcemeta_core_uri\n  PRIVATE sourcemeta::core::io)\ntarget_link_libraries(sourcemeta_core_uri\n  PRIVATE sourcemeta::core::ip)\n"
  },
  {
    "path": "vendor/core/src/core/uri/accessors.cc",
    "content": "#include <sourcemeta/core/ip.h>\n#include <sourcemeta/core/uri.h>\n\n#include <cstdint>  // std::uint32_t\n#include <optional> // std::optional\n#include <string>   // std::string\n\nnamespace sourcemeta::core {\n\nauto URI::is_relative() const -> bool { return !this->scheme().has_value(); }\n\nauto URI::is_absolute() const noexcept -> bool {\n  return this->scheme_.has_value();\n}\n\nauto URI::is_urn() const -> bool {\n  const auto scheme{this->scheme()};\n  return scheme.has_value() && scheme.value() == \"urn\";\n}\n\nauto URI::is_tag() const -> bool {\n  const auto scheme{this->scheme()};\n  return scheme.has_value() && scheme.value() == \"tag\";\n}\n\nauto URI::is_mailto() const -> bool {\n  const auto scheme{this->scheme()};\n  return scheme.has_value() && scheme.value() == \"mailto\";\n}\n\nauto URI::is_file() const -> bool {\n  const auto scheme{this->scheme()};\n  return scheme.has_value() && scheme.value() == \"file\";\n}\n\nauto URI::is_ipv4() const -> bool {\n  return this->host_.has_value() &&\n         sourcemeta::core::is_ipv4(this->host_.value());\n}\n\nauto URI::is_ipv6() const -> bool {\n  return this->host_.has_value() &&\n         sourcemeta::core::is_ipv6(this->host_.value());\n}\n\nauto URI::is_fragment_only() const -> bool {\n  return !this->scheme().has_value() && !this->host().has_value() &&\n         !this->port().has_value() && !this->path().has_value() &&\n         this->fragment().has_value() && !this->query().has_value();\n}\n\nauto URI::empty() const -> bool {\n  return !this->path_.has_value() && !this->userinfo_.has_value() &&\n         !this->host_.has_value() && !this->port_.has_value() &&\n         !this->scheme_.has_value() && !this->fragment_.has_value() &&\n         !this->query_.has_value();\n}\n\nauto URI::scheme() const -> std::optional<std::string_view> {\n  return this->scheme_;\n}\n\nauto URI::host() const -> std::optional<std::string_view> {\n  return this->host_;\n}\n\nauto URI::port() const -> std::optional<std::uint32_t> { return this->port_; }\n\nauto URI::path() const -> std::optional<std::string> { return this->path_; }\n\nauto URI::fragment() const -> std::optional<std::string_view> {\n  return this->fragment_;\n}\n\nauto URI::userinfo() const -> std::optional<std::string_view> {\n  return this->userinfo_;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/canonicalize.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include \"escaping.h\"\n#include \"normalize.h\"\n\n#include <cctype>   // std::tolower\n#include <optional> // std::optional\n#include <string>   // std::string\n\nnamespace {\n\nauto to_lowercase(const std::string_view input) -> std::string {\n  std::string result;\n  result.reserve(input.size());\n  for (const auto character : input) {\n    result +=\n        static_cast<char>(std::tolower(static_cast<unsigned char>(character)));\n  }\n  return result;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto URI::canonicalize() -> URI & {\n  // Lowercase scheme (schemes are case-insensitive per RFC 3986)\n  if (this->scheme_.has_value()) {\n    this->scheme_ = to_lowercase(this->scheme_.value());\n  }\n\n  // Lowercase host (hostnames are case-insensitive per RFC 3986)\n  if (this->host_.has_value()) {\n    this->host_ = to_lowercase(this->host_.value());\n  }\n\n  // Canonicalize path by removing \".\" and \"..\" segments\n  if (this->path_.has_value() && !this->path_.value().empty()) {\n    auto &current_path{this->path_.value()};\n    normalize_path(current_path);\n    if (current_path.empty()) {\n      this->path_ = std::nullopt;\n    }\n  }\n\n  // Remove empty fragment (empty fragments are optional per RFC 3986)\n  if (this->fragment_.has_value() && this->fragment_.value().empty()) {\n    this->fragment_ = std::nullopt;\n  }\n\n  // pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  const auto is_pchar = [](char character) -> bool {\n    return uri_is_unreserved(character) || uri_is_sub_delim(character) ||\n           character == URI_COLON || character == URI_AT;\n  };\n\n  if (this->path_.has_value()) {\n    uri_normalize_percent_encoding_inplace(this->path_.value());\n    uri_unescape_if_inplace(this->path_.value(), is_pchar);\n  }\n\n  if (this->query_.has_value()) {\n    uri_normalize_percent_encoding_inplace(this->query_.value());\n    uri_unescape_if_inplace(this->query_.value(), [&](char character) {\n      return is_pchar(character) || character == URI_SLASH ||\n             character == URI_QUESTION;\n    });\n  }\n\n  if (this->fragment_.has_value()) {\n    uri_normalize_percent_encoding_inplace(this->fragment_.value());\n    uri_unescape_if_inplace(this->fragment_.value(), [&](char character) {\n      return is_pchar(character) || character == URI_SLASH ||\n             character == URI_QUESTION;\n    });\n  }\n\n  if (this->userinfo_.has_value()) {\n    uri_normalize_percent_encoding_inplace(this->userinfo_.value());\n    uri_unescape_if_inplace(this->userinfo_.value(), [&](char character) {\n      return uri_is_sub_delim(character) || character == URI_COLON;\n    });\n  }\n\n  if (this->host_.has_value()) {\n    uri_normalize_percent_encoding_inplace(this->host_.value());\n    uri_unescape_if_inplace(this->host_.value(), [](char character) {\n      return uri_is_sub_delim(character);\n    });\n  }\n\n  // Remove default ports (80 for http, 443 for https)\n  if (this->port_.has_value() && this->scheme_.has_value()) {\n    const auto port_value = this->port_.value();\n    const auto scheme_value = this->scheme_.value();\n\n    if ((scheme_value == \"http\" && port_value == 80) ||\n        (scheme_value == \"https\" && port_value == 443)) {\n      this->port_ = std::nullopt;\n    }\n  }\n\n  return *this;\n}\n\nauto URI::canonicalize(const std::string_view input) -> std::string {\n  return URI{input}.canonicalize().recompose();\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/escaping.h",
    "content": "#ifndef SOURCEMETA_CORE_URI_ESCAPING_H_\n#define SOURCEMETA_CORE_URI_ESCAPING_H_\n\n#include \"grammar.h\"\n\n#include <array>    // std::array\n#include <cctype>   // std::isalnum\n#include <charconv> // std::from_chars\n#include <cstdint>  // std::uint8_t\n#include <istream>  // std::istream\n#include <iterator> // std::istream_iterator\n#include <ostream>  // std::ostream\n#include <string>   // std::string\n\nnamespace sourcemeta::core {\n\nenum class URIEscapeMode : std::uint8_t {\n  // Escape every characted that is not in the URI \"unreserved\" ABNF category\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  SkipUnreserved,\n  // Escape every characted that is not in either the URI \"unreserved\" nor\n  // \"sub-delims\" ABNF categories\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  SkipSubDelims,\n  // pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n  // path  = *( pchar / \"/\" )\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  Path,\n  // pchar    = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n  // fragment = *( pchar / \"/\" / \"?\" )\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  Fragment,\n  // Like SkipSubDelims but also preserves \":\" for Windows filesystem paths\n  // (drive letters like C:)\n  Filesystem,\n  // userinfo = *( unreserved / pct-encoded / sub-delims / \":\" )\n  // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n  UserInfo\n};\n\ninline auto uri_escape(std::istream &input, std::ostream &output,\n                       const URIEscapeMode mode,\n                       const bool preserve_percent_sequences = true) -> void {\n  char character = 0;\n  while (input.get(character)) {\n    // Check if this is an already percent-encoded sequence (%HEXHEX)\n    // If so, preserve it as-is to avoid double-encoding\n    // (only when preserve_percent_sequences is true)\n    if (preserve_percent_sequences && character == URI_PERCENT) {\n      const auto position = input.tellg();\n      char next_1 = 0;\n      char next_2 = 0;\n\n      if (input.get(next_1) && input.get(next_2) &&\n          std::isxdigit(static_cast<unsigned char>(next_1)) &&\n          std::isxdigit(static_cast<unsigned char>(next_2))) {\n        // Valid percent-encoded sequence - preserve it\n        output << character << next_1 << next_2;\n        continue;\n      }\n\n      // Not a valid percent-encoded sequence - restore position and escape %\n      input.seekg(position);\n    }\n\n    // unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n    // See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n    if (uri_is_unreserved(character)) {\n      output << character;\n      continue;\n    }\n\n    if (mode == URIEscapeMode::SkipSubDelims || mode == URIEscapeMode::Path ||\n        mode == URIEscapeMode::Fragment || mode == URIEscapeMode::Filesystem ||\n        mode == URIEscapeMode::UserInfo) {\n      if (uri_is_sub_delim(character)) {\n        output << character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Path) {\n      if (character == URI_COLON || character == URI_AT ||\n          character == URI_SLASH) {\n        output << character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Fragment) {\n      if (character == URI_COLON || character == URI_AT ||\n          character == URI_SLASH || character == URI_QUESTION) {\n        output << character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Filesystem || mode == URIEscapeMode::UserInfo) {\n      if (character == URI_COLON) {\n        output << character;\n        continue;\n      }\n    }\n\n    const auto byte{static_cast<unsigned char>(character)};\n    const auto high{(byte >> 4) & 0x0F};\n    const auto low{byte & 0x0F};\n    output << URI_PERCENT;\n    output << static_cast<char>(high < 10 ? '0' + high : 'A' + high - 10);\n    output << static_cast<char>(low < 10 ? '0' + low : 'A' + low - 10);\n  }\n}\n\ninline auto uri_unescape(std::istream &input, std::ostream &output) -> void {\n  std::istream_iterator<char> iterator(input);\n  std::istream_iterator<char> end;\n  auto plus_1 = std::ranges::next(iterator, 1, end);\n  auto plus_2 = std::ranges::next(plus_1, 1, end);\n  const int hex_base = 16;\n\n  while (iterator != end) {\n    if (*iterator == URI_PERCENT && plus_1 != end && plus_2 != end &&\n        std::isxdigit(*(plus_1)) && std::isxdigit(*(plus_2))) {\n      const std::array<char, 2> hex{{*plus_1, *plus_2}};\n      int decoded_value{};\n      std::from_chars(hex.data(), hex.data() + hex.size(), decoded_value,\n                      hex_base);\n      output << static_cast<char>(decoded_value);\n\n      iterator = std::ranges::next(plus_2, 1, end);\n      plus_1 = std::ranges::next(iterator, 1, end);\n      plus_2 = std::ranges::next(plus_1, 1, end);\n    } else {\n      output << *iterator;\n      iterator = plus_1;\n      plus_1 = plus_2;\n      plus_2 = std::ranges::next(plus_1, 1, end);\n    }\n  }\n}\n\ninline auto uri_hex_to_int(char character) -> unsigned char {\n  if (character >= '0' && character <= '9') {\n    return static_cast<unsigned char>(character - '0');\n  }\n\n  if (character >= 'A' && character <= 'F') {\n    return static_cast<unsigned char>(character - 'A' + 10);\n  }\n\n  if (character >= 'a' && character <= 'f') {\n    return static_cast<unsigned char>(character - 'a' + 10);\n  }\n\n  return 0;\n}\n\ninline auto uri_is_percent_encoded(const std::string &input,\n                                   std::string::size_type position) -> bool {\n  return position < input.size() && input[position] == URI_PERCENT &&\n         position + 2 < input.size() &&\n         std::isxdigit(static_cast<unsigned char>(input[position + 1])) &&\n         std::isxdigit(static_cast<unsigned char>(input[position + 2]));\n}\n\ninline auto uri_unescape_all_inplace(std::string &input) -> void {\n  std::string::size_type write_position = 0;\n\n  for (std::string::size_type read_position = 0;\n       read_position < input.size();) {\n    if (uri_is_percent_encoded(input, read_position)) {\n      const auto value = static_cast<unsigned char>(\n          (uri_hex_to_int(input[read_position + 1]) << 4) |\n          uri_hex_to_int(input[read_position + 2]));\n      input[write_position++] = static_cast<char>(value);\n      read_position += 3;\n    } else {\n      input[write_position++] = input[read_position++];\n    }\n  }\n\n  input.resize(write_position);\n}\n\ninline auto uri_unescape_unreserved_inplace(std::string &input) -> void {\n  std::string::size_type write_position = 0;\n\n  for (std::string::size_type read_position = 0;\n       read_position < input.size();) {\n    if (uri_is_percent_encoded(input, read_position)) {\n      const auto value = static_cast<unsigned char>(\n          (uri_hex_to_int(input[read_position + 1]) << 4) |\n          uri_hex_to_int(input[read_position + 2]));\n      if (uri_is_unreserved(static_cast<char>(value))) {\n        input[write_position++] = static_cast<char>(value);\n      } else {\n        input[write_position++] = input[read_position];\n        input[write_position++] = input[read_position + 1];\n        input[write_position++] = input[read_position + 2];\n      }\n\n      read_position += 3;\n    } else {\n      input[write_position++] = input[read_position++];\n    }\n  }\n\n  input.resize(write_position);\n}\n\ninline auto uri_normalize_percent_encoding_inplace(std::string &input) -> void {\n  for (std::string::size_type position = 0; position < input.size();) {\n    if (uri_is_percent_encoded(input, position)) {\n      input[position + 1] = static_cast<char>(\n          std::toupper(static_cast<unsigned char>(input[position + 1])));\n      input[position + 2] = static_cast<char>(\n          std::toupper(static_cast<unsigned char>(input[position + 2])));\n      position += 3;\n    } else {\n      ++position;\n    }\n  }\n}\n\ntemplate <typename Predicate>\ninline auto uri_unescape_if_inplace(std::string &input, Predicate should_decode)\n    -> void {\n  std::string::size_type write_position = 0;\n\n  for (std::string::size_type read_position = 0;\n       read_position < input.size();) {\n    if (uri_is_percent_encoded(input, read_position)) {\n      const auto value = static_cast<unsigned char>(\n          (uri_hex_to_int(input[read_position + 1]) << 4) |\n          uri_hex_to_int(input[read_position + 2]));\n      const auto decoded = static_cast<char>(value);\n\n      if (should_decode(decoded)) {\n        input[write_position++] = decoded;\n      } else {\n        input[write_position++] = input[read_position];\n        input[write_position++] = input[read_position + 1];\n        input[write_position++] = input[read_position + 2];\n      }\n\n      read_position += 3;\n    } else {\n      input[write_position++] = input[read_position++];\n    }\n  }\n\n  input.resize(write_position);\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uri/filesystem.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include \"escaping.h\"\n\n#include <algorithm>  // std::ranges::replace\n#include <filesystem> // std::filesystem\n#include <iterator>   // std::advance, std::next\n#include <string>     // std::string\n\nnamespace sourcemeta::core {\n\nauto URI::to_path() const -> std::filesystem::path {\n  auto path = this->path().value_or(\"\");\n\n  // For non-file URIs, just return the path as-is\n  if (!this->is_file()) {\n    return path;\n  }\n\n  // Check for Windows absolute path (e.g., /C:/)\n  const auto is_windows_absolute =\n      path.size() >= 3 && path[0] == '/' && path[2] == ':';\n  if (is_windows_absolute) {\n    // Remove leading slash\n    path.erase(0, 1);\n    // Convert to Windows separators\n    std::ranges::replace(path, '/', '\\\\');\n  }\n\n  uri_unescape_all_inplace(path);\n  return path;\n}\n\nauto URI::from_path(const std::filesystem::path &path) -> URI {\n  auto normalized = path.lexically_normal().string();\n  const auto is_unc = normalized.starts_with(\"\\\\\\\\\");\n  const auto is_windows_absolute =\n      normalized.size() >= 2 && normalized[1] == ':';\n\n  // Convert backslashes to forward slashes\n  std::ranges::replace(normalized, '\\\\', '/');\n  const auto is_unix_absolute = normalized.starts_with(\"/\");\n\n  // Only absolute paths can be converted to file:// URIs\n  if (!is_unix_absolute && !is_windows_absolute && !is_unc) {\n    throw URIError(\n        \"It is not valid to construct a file:// URI out of a relative path\");\n  }\n\n  // Remove leading slashes for processing\n  normalized.erase(0, normalized.find_first_not_of('/'));\n  const std::filesystem::path final_path{normalized};\n\n  URI result{\"file://\"};\n  auto iterator = final_path.begin();\n\n  // For UNC paths, the first segment is the hostname\n  if (is_unc) {\n    result.host_ = iterator->string();\n    std::advance(iterator, 1);\n  }\n\n  // Process remaining path segments\n  for (; iterator != final_path.end(); ++iterator) {\n    if (iterator->empty()) {\n      result.append_path(\"/\");\n    } else if (*iterator == \"/\") {\n      if (std::next(iterator) == final_path.end()) {\n        result.append_path(\"/\");\n      }\n    } else {\n      // Store raw segment - escaping will happen during recompose()\n      const auto segment = iterator->string();\n\n      if (result.path_.has_value()) {\n        result.append_path(segment);\n      } else {\n        // First segment: file:// URIs need leading slash\n        result.path_ = \"/\" + segment;\n      }\n    }\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/grammar.h",
    "content": "#ifndef SOURCEMETA_CORE_URI_GRAMMAR_H_\n#define SOURCEMETA_CORE_URI_GRAMMAR_H_\n\n#include <cctype> // std::isalnum, std::isalpha, std::isdigit\n\nnamespace sourcemeta::core {\n\n// URI Grammar Constants\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.2\n// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A\n\n// gen-delims = \":\" / \"/\" / \"?\" / \"#\" / \"[\" / \"]\" / \"@\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.2\nconstexpr char URI_COLON = ':';\nconstexpr char URI_SLASH = '/';\nconstexpr char URI_QUESTION = '?';\nconstexpr char URI_HASH = '#';\nconstexpr char URI_AT = '@';\nconstexpr char URI_OPEN_BRACKET = '[';\nconstexpr char URI_CLOSE_BRACKET = ']';\n\n// sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\" / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.2\nconstexpr char URI_EXCLAMATION = '!';\nconstexpr char URI_DOLLAR = '$';\nconstexpr char URI_AMPERSAND = '&';\nconstexpr char URI_APOSTROPHE = '\\'';\nconstexpr char URI_OPEN_PAREN = '(';\nconstexpr char URI_CLOSE_PAREN = ')';\nconstexpr char URI_ASTERISK = '*';\nconstexpr char URI_PLUS = '+';\nconstexpr char URI_COMMA = ',';\nconstexpr char URI_SEMICOLON = ';';\nconstexpr char URI_EQUALS = '=';\n\n// unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.3\nconstexpr char URI_HYPHEN = '-';\nconstexpr char URI_DOT = '.';\nconstexpr char URI_UNDERSCORE = '_';\nconstexpr char URI_TILDE = '~';\n\n// pct-encoded = \"%\" HEXDIG HEXDIG\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.1\nconstexpr char URI_PERCENT = '%';\n\n// Character Classification Helper Functions\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2\n\n// unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.3\ninline auto uri_is_unreserved(const char character) -> bool {\n  if (std::isalnum(static_cast<unsigned char>(character))) {\n    return true;\n  }\n\n  switch (character) {\n    case URI_HYPHEN:\n    case URI_DOT:\n    case URI_UNDERSCORE:\n    case URI_TILDE:\n      return true;\n    default:\n      return false;\n  }\n}\n\n// sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\" / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-2.2\ninline auto uri_is_sub_delim(const char character) -> bool {\n  switch (character) {\n    case URI_EXCLAMATION:\n    case URI_DOLLAR:\n    case URI_AMPERSAND:\n    case URI_APOSTROPHE:\n    case URI_OPEN_PAREN:\n    case URI_CLOSE_PAREN:\n    case URI_ASTERISK:\n    case URI_PLUS:\n    case URI_COMMA:\n    case URI_SEMICOLON:\n    case URI_EQUALS:\n      return true;\n    default:\n      return false;\n  }\n}\n\n// Scheme characters: ALPHA / DIGIT / \"+\" / \"-\" / \".\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-3.1\ninline auto uri_is_scheme_char(const char character) -> bool {\n  if (std::isalnum(static_cast<unsigned char>(character))) {\n    return true;\n  }\n\n  switch (character) {\n    case URI_PLUS:\n    case URI_HYPHEN:\n    case URI_DOT:\n      return true;\n    default:\n      return false;\n  }\n}\n\n// pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n// See https://www.rfc-editor.org/rfc/rfc3986#section-3.3\ninline auto uri_is_pchar(const char character) -> bool {\n  if (uri_is_unreserved(character) || uri_is_sub_delim(character)) {\n    return true;\n  }\n\n  switch (character) {\n    case URI_COLON:\n    case URI_AT:\n    case URI_PERCENT:\n      return true;\n    default:\n      return false;\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uri/include/sourcemeta/core/uri.h",
    "content": "#ifndef SOURCEMETA_CORE_URI_H_\n#define SOURCEMETA_CORE_URI_H_\n\n#ifndef SOURCEMETA_CORE_URI_EXPORT\n#include <sourcemeta/core/uri_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/uri_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <concepts>    // std::convertible_to\n#include <cstddef>     // std::size_t, std::ptrdiff_t\n#include <cstdint>     // std::uint32_t\n#include <filesystem>  // std::filesystem\n#include <istream>     // std::istream\n#include <iterator>    // std::forward_iterator_tag\n#include <memory>      // std::unique_ptr\n#include <optional>    // std::optional\n#include <span>        // std::span\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <type_traits> // std::is_same_v\n#include <utility>     // std::pair\n#include <vector>      // std::vector\n\n/// @defgroup uri URI\n/// @brief A strict RFC 3986 URI implementation.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/uri.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup uri\nclass SOURCEMETA_CORE_URI_EXPORT URI {\npublic:\n  /// Default constructor creates an empty URI\n  URI() = default;\n\n  /// Copy constructor\n  URI(const URI &) = default;\n\n  /// Move constructor\n  URI(URI &&) noexcept = default;\n\n  /// Copy assignment operator\n  auto operator=(const URI &) -> URI & = default;\n\n  /// Move assignment operator\n  auto operator=(URI &&) noexcept -> URI & = default;\n\n  /// This constructor creates a URI from a string. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// ```\n  template <typename T>\n    requires std::convertible_to<T, std::string_view> &&\n             (!std::is_same_v<std::decay_t<T>, URI>)\n  URI(T &&input) {\n    this->parse(std::string_view{std::forward<T>(input)});\n  }\n\n  /// This constructor creates a URI from a C++ input stream. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <sstream>\n  ///\n  /// std::istringstream input{\"https://www.sourcemeta.com\"};\n  /// const sourcemeta::core::URI uri{input};\n  /// ```\n  URI(std::istream &input);\n\n  /// Check if the URI is absolute. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// assert(uri.is_absolute());\n  /// ```\n  [[nodiscard]] auto is_absolute() const noexcept -> bool;\n\n  /// Check if the URI is a URN. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"urn:example:schema\"};\n  /// assert(uri.is_urn());\n  /// ```\n  [[nodiscard]] auto is_urn() const -> bool;\n\n  /// Check if the URI is a tag as described by RFC 4151. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"tag:yaml.org,2002:int\"};\n  /// assert(uri.is_tag());\n  /// ```\n  [[nodiscard]] auto is_tag() const -> bool;\n\n  /// Check if the URI has the `mailto` scheme. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"mailto:joe@example.com\"};\n  /// assert(uri.is_mailto());\n  /// ```\n  [[nodiscard]] auto is_mailto() const -> bool;\n\n  /// Check if the URI is a file URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"file:///home/jviotti/foo.txt\"};\n  /// assert(uri.is_file());\n  /// ```\n  [[nodiscard]] auto is_file() const -> bool;\n\n  /// Check if the URI only consists of a fragment. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"#foo\"};\n  /// assert(uri.is_fragment_only());\n  /// ```\n  [[nodiscard]] auto is_fragment_only() const -> bool;\n\n  /// Check if the URI is relative. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"./foo\"};\n  /// assert(uri.is_relative());\n  /// ```\n  [[nodiscard]] auto is_relative() const -> bool;\n\n  /// Check if the host is an IPv4 address. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"http://192.168.1.1/index.html\"};\n  /// assert(uri.is_ipv4());\n  /// ```\n  [[nodiscard]] auto is_ipv4() const -> bool;\n\n  /// Check if the host is an IPv6 address. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"http://[::1]\"};\n  /// assert(uri.is_ipv6());\n  /// ```\n  [[nodiscard]] auto is_ipv6() const -> bool;\n\n  /// Check if the URI corresponds to the empty URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"\"};\n  /// assert(uri.empty());\n  /// ```\n  [[nodiscard]] auto empty() const -> bool;\n\n  /// Get the scheme part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// assert(uri.scheme().has_value());\n  /// assert(uri.scheme().value() == \"https\");\n  /// ```\n  [[nodiscard]] auto scheme() const -> std::optional<std::string_view>;\n\n  /// Get the host part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// assert(uri.host().has_value());\n  /// assert(uri.host().value() == \"sourcemeta.com\");\n  /// ```\n  [[nodiscard]] auto host() const -> std::optional<std::string_view>;\n\n  /// Get the port part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"http://localhost:8000\"};\n  /// assert(uri.port().has_value());\n  /// assert(uri.port().value() == 8000);\n  /// ```\n  [[nodiscard]] auto port() const -> std::optional<std::uint32_t>;\n\n  /// Get the path part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI\n  /// uri{\"https://www.sourcemeta.com/foo/bar\"};\n  /// assert(uri.path().has_value());\n  /// assert(uri.path().value() == \"/foo/bar\");\n  /// ```\n  [[nodiscard]] auto path() const -> std::optional<std::string>;\n\n  /// Set the path part of the URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// const std::string path{\"/foo/bar\"};\n  /// uri.path(path);\n  /// assert(uri.path().has_value());\n  /// assert(uri.path().value() == \"/foo/bar\");\n  /// ```\n  auto path(const std::string &path) -> URI &;\n\n  /// Set the path part of the URI with move semantics. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// std::string path{\"/foo/bar\"};\n  /// uri.path(std::move(path));\n  /// assert(uri.path().has_value());\n  /// assert(uri.path().value() == \"/foo/bar\");\n  auto path(std::string &&path) -> URI &;\n\n  /// Append a path to the existing URI path or set a path if such component\n  /// does not exist in the URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com/foo\"};\n  /// uri.append_path(\"bar/baz\");\n  /// assert(uri.recompose() == \"https://www.sourcemeta.com/foo/bar/baz\");\n  auto append_path(const std::string &path) -> URI &;\n\n  /// If the URI has a path, this method sets or replace the extension in the\n  /// path. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com/foo\"};\n  /// uri.extension(\"json\");\n  /// assert(uri.recompose() == \"https://www.sourcemeta.com/foo.json\");\n  auto extension(std::string &&extension) -> URI &;\n\n  /// Get the fragment part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://www.sourcemeta.com/#foo\"};\n  /// assert(uri.fragment().has_value());\n  /// assert(uri.fragment().value() == \"foo\");\n  /// ```\n  [[nodiscard]] auto fragment() const -> std::optional<std::string_view>;\n\n  /// Set the fragment part of the URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// const std::string fragment{\"foo\"};\n  /// uri.fragment(fragment);\n  /// assert(uri.fragment().has_value());\n  /// assert(uri.fragment().value() == \"foo\");\n  /// ```\n  auto fragment(const std::string_view fragment) -> URI &;\n\n  /// A non-owning, zero-copy view over the RFC 3986 query\n  /// component of a URI. Provides convenience access to query\n  /// parameters formatted as `name=value` pairs separated by `&`.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI\n  ///   uri{\"https://www.sourcemeta.com/?foo=bar\"};\n  /// const auto query{uri.query()};\n  /// assert(query.has_value());\n  /// assert(query.value().raw() == \"foo=bar\");\n  /// ```\n  class SOURCEMETA_CORE_URI_EXPORT Query {\n  public:\n    /// Get the raw RFC 3986 query string this view was constructed\n    /// from. For example:\n    ///\n    /// ```cpp\n    /// #include <sourcemeta/core/uri.h>\n    /// #include <cassert>\n    ///\n    /// const sourcemeta::core::URI\n    ///   uri{\"https://www.sourcemeta.com/?foo=bar&baz=qux\"};\n    /// assert(uri.query().value().raw() == \"foo=bar&baz=qux\");\n    /// ```\n    [[nodiscard]] auto raw() const -> std::string_view;\n\n    /// Look up the value of a query parameter by name. Returns\n    /// `std::nullopt` if no matching parameter exists. If multiple\n    /// parameters share the given name, the value of the first one\n    /// is returned. The returned value is not percent-decoded. For\n    /// example:\n    ///\n    /// ```cpp\n    /// #include <sourcemeta/core/uri.h>\n    /// #include <cassert>\n    ///\n    /// const sourcemeta::core::URI\n    ///   uri{\"https://www.sourcemeta.com/?foo=bar\"};\n    /// const auto query{uri.query()};\n    /// assert(query.has_value());\n    /// assert(query.value().at(\"foo\").value() == \"bar\");\n    /// ```\n    [[nodiscard]] auto at(const std::string_view name) const\n        -> std::optional<std::string_view>;\n\n    /// Forward iterator over the `(name, value)` pairs of this\n    /// query view. Names and values are returned exactly as they\n    /// appear in the raw query, without percent-decoding\n    class SOURCEMETA_CORE_URI_EXPORT const_iterator {\n    public:\n      using iterator_category = std::forward_iterator_tag;\n      using value_type = std::pair<std::string_view, std::string_view>;\n      using difference_type = std::ptrdiff_t;\n      using reference = const value_type &;\n      using pointer = const value_type *;\n\n      const_iterator() = default;\n      const_iterator(const std::string_view raw, const std::size_t pair_start);\n\n      [[nodiscard]] auto operator*() const -> reference;\n      [[nodiscard]] auto operator->() const -> pointer;\n      auto operator++() -> const_iterator &;\n      auto operator++(int) -> const_iterator;\n      [[nodiscard]] auto operator==(const const_iterator &other) const -> bool;\n      [[nodiscard]] auto operator!=(const const_iterator &other) const -> bool;\n\n    private:\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n      std::string_view raw_{};\n      std::size_t pair_start_{std::string_view::npos};\n      value_type current_{};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n    };\n\n    /// Iterator to the first `(name, value)` pair\n    [[nodiscard]] auto begin() const -> const_iterator;\n\n    /// Past-the-end iterator\n    [[nodiscard]] auto end() const -> const_iterator;\n\n  private:\n    friend class URI;\n    explicit Query(const std::string_view raw);\n\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n    std::string_view raw_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n  };\n\n  /// Get the query part of the URI as a navigable view, if any.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI\n  ///   uri{\"https://www.sourcemeta.com/?foo=bar\"};\n  /// assert(uri.query().has_value());\n  /// assert(uri.query().value().raw() == \"foo=bar\");\n  /// ```\n  [[nodiscard]] auto query() const -> std::optional<Query>;\n\n  /// Set the query part of the URI. A leading `?` in the input is stripped.\n  /// Passing an empty string clears the query. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://www.sourcemeta.com\"};\n  /// uri.query(\"foo=bar\");\n  /// assert(uri.query().has_value());\n  /// assert(uri.query().value().raw() == \"foo=bar\");\n  /// ```\n  auto query(const std::string_view query) -> URI &;\n\n  /// Recompose a URI as established by RFC 3986. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI\n  ///   uri{\"https://www.sourcemeta.com/foo/../bar\"};\n  /// assert(uri.recompose() == \"https://sourcemeta.com/bar\");\n  /// ```\n  [[nodiscard]] auto recompose() const -> std::string;\n\n  /// Recompose a URI as established by RFC 3986, but without including the\n  /// fragment component. The result is an optional to handle the case where the\n  /// input URI only consists of a fragment. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI\n  ///   uri{\"https://www.sourcemeta.com/foo#bar\"};\n  /// assert(uri.recompose_without_fragment().has_value());\n  /// assert(uri.recompose_without_fragment().value() ==\n  /// \"https://sourcemeta.com/foo\");\n  /// ```\n  [[nodiscard]] auto recompose_without_fragment() const\n      -> std::optional<std::string>;\n\n  /// Canonicalize a URI. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"hTtP://exAmpLe.com:80/TEST\"};\n  /// uri.canonicalize();\n  /// assert(uri.recompose() == \"http://example.com/TEST\");\n  /// ```\n  auto canonicalize() -> URI &;\n\n  /// Convert a URI into a filesystem path. If the URI is not under the `file`\n  /// scheme, get the URI path component as a filesystem path. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"file:///home/jviotti/foo.txt\"};\n  /// assert(uri.to_path() == \"/home/jviotti/foo.txt\");\n  /// ```\n  [[nodiscard]] auto to_path() const -> std::filesystem::path;\n\n  /// Resolve a relative URI against a base URI as established by RFC 3986. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI base{\"https://www.sourcemeta.com\"};\n  /// sourcemeta::core::URI result{\"foo\"};\n  /// result.resolve_from(base);\n  /// assert(result.recompose() == \"https://sourcemeta.com/foo\");\n  /// ```\n  auto resolve_from(const URI &base) -> URI &;\n\n  /// Attempt to resolve a URI relative to another URI. If the latter URI is not\n  /// a base for the former, leave the URI intact. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI base{\"https://www.sourcemeta.com\"};\n  /// sourcemeta::core::URI result{\"https://www.sourcemeta.com/foo\"};\n  /// result.relative_to(base);\n  /// assert(result.recompose() == \"foo\");\n  /// ```\n  auto relative_to(const URI &base) -> URI &;\n\n  /// Attempt to change the base of a URI . If the URI is not\n  /// relative to the former, leave the URI intact. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"https://example.com/foo/bar/baz\"};\n  /// const sourcemeta::core::URI base{\"https://example.com/foo\"};\n  /// const sourcemeta::core::URI new_base{\"/qux\"};\n  /// uri.rebase(base, new_base);\n  /// assert(uri.recompose() == \"/qux/bar/baz\");\n  /// ```\n  auto rebase(const URI &base, const URI &new_base) -> URI &;\n\n  /// Get the user information part of the URI, if any. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\"https://user:@host\"};\n  /// assert(uri.userinfo().has_value());\n  /// assert(uri.userinfo().value() == \"user:\");\n  /// ```\n  ///\n  /// As mentioned in RFC 3986, the format \"user:password\" is deprecated.\n  /// Applications should not render as clear text any data after the first\n  /// colon. See https://tools.ietf.org/html/rfc3986#section-3.2.1\n  [[nodiscard]] auto userinfo() const -> std::optional<std::string_view>;\n\n  /// Set the user information part of the URI. Passing an empty string clears\n  /// the user information. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// sourcemeta::core::URI uri{\"http://host/path\"};\n  /// uri.userinfo(\"user\");\n  /// assert(uri.userinfo().has_value());\n  /// assert(uri.userinfo().value() == \"user\");\n  /// ```\n  auto userinfo(const std::string_view userinfo) -> URI &;\n\n  /// To support equality of URIs\n  auto operator==(const URI &other) const noexcept -> bool = default;\n\n  /// To support ordering of URIs\n  auto operator<(const URI &other) const noexcept -> bool;\n\n  /// Create a URI from a fragment. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const sourcemeta::core::URI uri{\n  ///   sourcemeta::core::URI::from_fragment(\"foo\")};\n  /// assert(uri.recompose() == \"#foo\");\n  /// ```\n  static auto from_fragment(const std::string_view fragment) -> URI;\n\n  /// Create a URI from a file system path. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  /// #include <filesystem>\n  ///\n  /// const std::filesystem::path path{\"/foo/bar\"};\n  /// const sourcemeta::core::URI uri{sourcemeta::core::URI::from_path(path)};\n  /// assert(uri.recompose() == \"file:///foo/bar\");\n  /// ```\n  static auto from_path(const std::filesystem::path &path) -> URI;\n\n  /// A convenient method to canonicalize and recompose a URI from a string. For\n  /// example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// const auto result{\n  ///   sourcemeta::core::URI::canonicalize(\"hTtP://exAmpLe.com:80/TEST\")};\n  /// assert(result == \"http://example.com/TEST\");\n  /// ```\n  static auto canonicalize(std::string_view input) -> std::string;\n\n  /// Check if the given string is a valid absolute URI (has a scheme) per\n  /// RFC 3986 without constructing a full URI object. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// assert(sourcemeta::core::URI::is_uri(\"https://example.com/path\"));\n  /// assert(!sourcemeta::core::URI::is_uri(\"://bad\"));\n  /// assert(!sourcemeta::core::URI::is_uri(\"relative/path\"));\n  /// ```\n  [[nodiscard]] static auto is_uri(std::string_view input) noexcept -> bool;\n\n  /// Check if the given string is a valid URI reference per RFC 3986\n  /// (absolute or relative) without constructing a full URI object.\n  /// For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uri.h>\n  /// #include <cassert>\n  ///\n  /// assert(sourcemeta::core::URI::is_uri_reference(\"https://example.com\"));\n  /// assert(sourcemeta::core::URI::is_uri_reference(\"relative/path\"));\n  /// assert(!sourcemeta::core::URI::is_uri_reference(\"://bad\"));\n  /// ```\n  [[nodiscard]] static auto is_uri_reference(std::string_view input) noexcept\n      -> bool;\n\nprivate:\n  auto parse(std::string_view input) -> void;\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::optional<std::string> path_{};\n  std::optional<std::string> userinfo_{};\n  std::optional<std::string> host_{};\n  std::optional<std::uint32_t> port_{};\n  std::optional<std::string> scheme_{};\n  std::optional<std::string> fragment_{};\n  std::optional<std::string> query_{};\n  bool ip_literal_{false};\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uri/include/sourcemeta/core/uri_error.h",
    "content": "#ifndef SOURCEMETA_CORE_URI_ERROR_H_\n#define SOURCEMETA_CORE_URI_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_URI_EXPORT\n#include <sourcemeta/core/uri_export.h>\n#endif\n\n#include <cstdint>     // std::uint64_t\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup uri\n/// An error that represents a URI parsing failure\nclass SOURCEMETA_CORE_URI_EXPORT URIParseError : public std::exception {\npublic:\n  URIParseError(const std::uint64_t column) : column_{column} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The input is not a valid URI\";\n  }\n\n  /// Get the column number of the error\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return column_;\n  }\n\nprivate:\n  std::uint64_t column_;\n};\n\n/// @ingroup uri\n/// An error that represents a general URI error event\nclass SOURCEMETA_CORE_URI_EXPORT URIError : public std::exception {\npublic:\n  URIError(const char *message) : message_{message} {}\n  URIError(std::string message) = delete;\n  URIError(std::string &&message) = delete;\n  URIError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uri/normalize.h",
    "content": "#ifndef SOURCEMETA_CORE_URI_NORMALIZE_H_\n#define SOURCEMETA_CORE_URI_NORMALIZE_H_\n\n#include <string> // std::string\n\nnamespace sourcemeta::core {\n\n// Normalize a URI path by removing \".\" and \"..\" segments\n// Updates the path in-place according to RFC 3986 path segment normalization\n// Handles:\n// - Removal of \".\" segments\n// - Resolution of \"..\" segments with proper backtracking\n// - Preservation of leading \"..\" for relative paths\n// - Preservation of trailing slashes\n// - Preservation of empty segments (consecutive slashes)\ninline auto normalize_path(std::string &path) -> void {\n  if (path.empty() || path == \"/\") {\n    return;\n  }\n\n  std::string canonical_path;\n  const auto had_leading_slash = path.starts_with(\"/\");\n  const auto had_trailing_slash = path.ends_with('/') && path != \"/\";\n  bool last_segment_was_dot_or_dotdot{false};\n  canonical_path.reserve(path.size());\n  if (had_leading_slash) {\n    canonical_path = \"/\";\n  }\n\n  std::string::size_type minimum_position = had_leading_slash ? 1 : 0;\n  std::string::size_type read_position = had_leading_slash ? 1 : 0;\n  std::string::size_type segment_start = read_position;\n\n  if (!had_leading_slash && read_position < path.size() &&\n      path[read_position] == '.') {\n    if (read_position + 1 < path.size() && path[read_position + 1] == '/') {\n      read_position += 2;\n      segment_start = read_position;\n    }\n  }\n\n  while (read_position <= path.size()) {\n    if (read_position == path.size() || path[read_position] == '/') {\n      const auto segment_length = read_position - segment_start;\n      if (segment_length == 0 && read_position == path.size() &&\n          had_trailing_slash) {\n        break;\n      }\n\n      if (segment_length == 2 && path[segment_start] == '.' &&\n          path[segment_start + 1] == '.') {\n        last_segment_was_dot_or_dotdot = true;\n        if (canonical_path.size() > minimum_position) {\n          if (!canonical_path.empty() && canonical_path.back() == '/' &&\n              (canonical_path.size() < 2 ||\n               canonical_path[canonical_path.size() - 2] != '/')) {\n            canonical_path.pop_back();\n          }\n\n          while (canonical_path.size() > minimum_position &&\n                 canonical_path.back() != '/') {\n            canonical_path.pop_back();\n          }\n\n          if (!canonical_path.empty() && canonical_path.back() == '/' &&\n              canonical_path.size() > minimum_position) {\n            canonical_path.pop_back();\n          }\n        } else {\n          if (!had_leading_slash) {\n            if (canonical_path.size() > 0) {\n              canonical_path += '/';\n            }\n\n            canonical_path.append(\"..\");\n            minimum_position = canonical_path.size();\n          }\n        }\n      } else if (segment_length == 1 && path[segment_start] == '.') {\n        last_segment_was_dot_or_dotdot = true;\n      } else if (segment_length == 0) {\n        last_segment_was_dot_or_dotdot = false;\n        if (canonical_path.size() >= minimum_position) {\n          canonical_path += '/';\n        }\n      } else {\n        last_segment_was_dot_or_dotdot = false;\n        if (canonical_path.size() > 0 &&\n            (canonical_path.size() > minimum_position || !had_leading_slash)) {\n          canonical_path += '/';\n        }\n        canonical_path.append(path, segment_start, segment_length);\n      }\n\n      ++read_position;\n      segment_start = read_position;\n    } else {\n      ++read_position;\n    }\n  }\n\n  if ((had_trailing_slash || last_segment_was_dot_or_dotdot) &&\n      !canonical_path.empty() && canonical_path != \"/\" &&\n      !canonical_path.ends_with('/')) {\n    canonical_path += '/';\n  }\n\n  path = std::move(canonical_path);\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uri/parse.cc",
    "content": "#include <sourcemeta/core/ip.h>\n#include <sourcemeta/core/uri.h>\n\n#include \"escaping.h\"\n#include \"grammar.h\"\n\n#include <array>    // std::array\n#include <cassert>  // assert\n#include <cctype>   // std::isalnum, std::isxdigit, std::isalpha, std::isdigit\n#include <charconv> // std::from_chars\n#include <cstdint>  // std::uint64_t\n#include <limits>   // std::numeric_limits\n#include <optional> // std::optional\n#include <string>   // std::string\n#include <string_view>  // std::string_view\n#include <system_error> // std::errc\n#include <type_traits>  // std::conditional_t\n\nnamespace {\n\nusing namespace sourcemeta::core;\n\nauto validate_percent_encoded_utf8(const std::string_view input,\n                                   std::string_view::size_type position)\n    -> std::string_view::size_type {\n  assert(input[position] == URI_PERCENT);\n\n  if (position + 2 >= input.size()) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(position + 1)};\n  }\n\n  const auto first_hex = static_cast<unsigned char>(input[position + 1]);\n  const auto second_hex = static_cast<unsigned char>(input[position + 2]);\n\n  if (!std::isxdigit(first_hex) || !std::isxdigit(second_hex)) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(position + 1)};\n  }\n  return 3;\n}\n\ntemplate <bool CheckOnly>\nauto parse_scheme(const std::string_view input,\n                  std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<std::string>> {\n  if (position >= input.size() ||\n      !std::isalpha(static_cast<unsigned char>(input[position]))) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  const auto start = position;\n  position += 1;\n\n  while (position < input.size() && uri_is_scheme_char(input[position])) {\n    position += 1;\n  }\n\n  if (position < input.size() && input[position] == URI_COLON) {\n    if constexpr (CheckOnly) {\n      position += 1;\n      return true;\n    } else {\n      std::string scheme{input.substr(start, position - start)};\n      position += 1;\n      return scheme;\n    }\n  }\n\n  position = start;\n  if constexpr (CheckOnly) {\n    return false;\n  } else {\n    return std::nullopt;\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_port(const std::string_view input,\n                std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<unsigned long>> {\n  if (position >= input.size() ||\n      !std::isdigit(static_cast<unsigned char>(input[position]))) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  const auto start = position;\n  while (position < input.size() &&\n         std::isdigit(static_cast<unsigned char>(input[position]))) {\n    position += 1;\n  }\n\n  if constexpr (CheckOnly) {\n    return true;\n  } else {\n    const auto port_view = input.substr(start, position - start);\n    unsigned long port_value{};\n    const auto result = std::from_chars(\n        port_view.data(), port_view.data() + port_view.size(), port_value);\n    if (result.ec != std::errc{}) [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(start + 1)};\n    }\n\n    return port_value;\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_ipv6(const std::string_view input,\n                std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, void, std::string> {\n  assert(input[position] == URI_OPEN_BRACKET);\n\n  const auto start = position;\n  position += 1;\n  const bool is_ipvfuture = position < input.size() &&\n                            (input[position] == 'v' || input[position] == 'V');\n\n  // RFC 3986: IP-literal = \"[\" ( IPv6address / IPvFuture ) \"]\"\n  if (is_ipvfuture) {\n    // IPvFuture = \"v\" 1*HEXDIG \".\" 1*( unreserved / sub-delims / \":\" )\n    position += 1;\n\n    // Require 1*HEXDIG for the version\n    if (position >= input.size() || input[position] == URI_CLOSE_BRACKET ||\n        !std::isxdigit(static_cast<unsigned char>(input[position])))\n        [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n    while (position < input.size() && input[position] != URI_CLOSE_BRACKET &&\n           std::isxdigit(static_cast<unsigned char>(input[position]))) {\n      position += 1;\n    }\n\n    // Require \".\" separator\n    if (position >= input.size() || input[position] != URI_DOT) [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n    position += 1;\n\n    // Require 1*( unreserved / sub-delims / \":\" )\n    if (position >= input.size() || input[position] == URI_CLOSE_BRACKET)\n        [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n    while (position < input.size() && input[position] != URI_CLOSE_BRACKET) {\n      const auto current = input[position];\n      if (!uri_is_unreserved(current) && !uri_is_sub_delim(current) &&\n          current != URI_COLON) [[unlikely]] {\n        throw sourcemeta::core::URIParseError{\n            static_cast<std::uint64_t>(position + 1)};\n      }\n      position += 1;\n    }\n  } else {\n    // IPv6address: only HEXDIG, \":\", and \".\" are valid\n    while (position < input.size() && input[position] != URI_CLOSE_BRACKET) {\n      const auto current = input[position];\n      if (!std::isxdigit(static_cast<unsigned char>(current)) &&\n          current != URI_COLON && current != URI_DOT) [[unlikely]] {\n        throw sourcemeta::core::URIParseError{\n            static_cast<std::uint64_t>(position + 1)};\n      }\n      position += 1;\n    }\n  }\n\n  if (position >= input.size()) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(start + 1)};\n  }\n\n  const auto literal{input.substr(start + 1, position - start - 1)};\n  if (!is_ipvfuture && !sourcemeta::core::is_ipv6(literal)) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(start + 1)};\n  }\n\n  if constexpr (CheckOnly) {\n    position += 1;\n  } else {\n    std::string ipv6{literal};\n    position += 1;\n    return ipv6;\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_host(const std::string_view input,\n                std::string_view::size_type &position,\n                [[maybe_unused]] bool &ip_literal)\n    -> std::conditional_t<CheckOnly, void, std::string> {\n  if (position >= input.size()) {\n    if constexpr (!CheckOnly) {\n      return std::string{};\n    } else {\n      return;\n    }\n  }\n\n  if (input[position] == URI_OPEN_BRACKET) {\n    ip_literal = true;\n    if constexpr (CheckOnly) {\n      parse_ipv6<true>(input, position);\n      return;\n    } else {\n      return parse_ipv6<false>(input, position);\n    }\n  }\n\n  const auto start = position;\n  while (position < input.size()) {\n    const auto current = input[position];\n    if (current == URI_COLON || current == URI_SLASH ||\n        current == URI_QUESTION || current == URI_HASH || current == URI_AT) {\n      break;\n    }\n\n    if (current == URI_PERCENT) {\n      const auto skip = validate_percent_encoded_utf8(input, position);\n      position += skip;\n    } else if (uri_is_unreserved(current) || uri_is_sub_delim(current)) {\n      position += 1;\n    } else [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n  }\n\n  if constexpr (!CheckOnly) {\n    if (position == start) {\n      return std::string{};\n    }\n\n    return std::string{input.substr(start, position - start)};\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_userinfo(const std::string_view input,\n                    std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<std::string>> {\n  const auto start = position;\n  while (position < input.size()) {\n    const auto current = input[position];\n    if (current == URI_AT) {\n      if constexpr (CheckOnly) {\n        position += 1;\n        return true;\n      } else {\n        std::string userinfo{input.substr(start, position - start)};\n        position += 1;\n        return userinfo;\n      }\n    }\n\n    if (current == URI_PERCENT) {\n      const auto skip = validate_percent_encoded_utf8(input, position);\n      position += skip;\n    } else if (uri_is_unreserved(current) || uri_is_sub_delim(current) ||\n               current == URI_COLON) {\n      position += 1;\n    } else {\n      break;\n    }\n  }\n\n  position = start;\n  if constexpr (CheckOnly) {\n    return false;\n  } else {\n    return std::nullopt;\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_path(const std::string_view input,\n                std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<std::string>> {\n  if (position >= input.size()) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  const auto first_char = input[position];\n  if (first_char == URI_QUESTION || first_char == URI_HASH) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  const auto start = position;\n  while (position < input.size()) {\n    const auto current = input[position];\n    if (current == URI_QUESTION || current == URI_HASH) {\n      break;\n    }\n\n    if (current == URI_PERCENT) {\n      const auto skip = validate_percent_encoded_utf8(input, position);\n      position += skip;\n      continue;\n    }\n\n    if (uri_is_pchar(current) || current == URI_SLASH) {\n      position += 1;\n    } else [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n  }\n\n  if constexpr (CheckOnly) {\n    return true;\n  } else {\n    return std::string{input.substr(start, position - start)};\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_query(const std::string_view input,\n                 std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<std::string>> {\n  if (position >= input.size() || input[position] != URI_QUESTION) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  position += 1;\n  const auto start = position;\n\n  while (position < input.size()) {\n    const auto current = input[position];\n    if (current == URI_HASH) {\n      break;\n    }\n\n    if (current == URI_PERCENT) {\n      const auto skip = validate_percent_encoded_utf8(input, position);\n      position += skip;\n      continue;\n    }\n\n    if (uri_is_pchar(current) || current == URI_SLASH ||\n        current == URI_QUESTION) {\n      position += 1;\n    } else [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n  }\n\n  if constexpr (CheckOnly) {\n    return true;\n  } else {\n    return std::string{input.substr(start, position - start)};\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_fragment(const std::string_view input,\n                    std::string_view::size_type &position)\n    -> std::conditional_t<CheckOnly, bool, std::optional<std::string>> {\n  if (position >= input.size() || input[position] != URI_HASH) {\n    if constexpr (CheckOnly) {\n      return false;\n    } else {\n      return std::nullopt;\n    }\n  }\n\n  position += 1;\n  const auto start = position;\n\n  while (position < input.size()) {\n    const auto current = input[position];\n\n    if (current == URI_PERCENT) {\n      const auto skip = validate_percent_encoded_utf8(input, position);\n      position += skip;\n      continue;\n    }\n\n    if (uri_is_pchar(current) || current == URI_SLASH ||\n        current == URI_QUESTION) {\n      position += 1;\n    } else [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n  }\n\n  if constexpr (CheckOnly) {\n    return true;\n  } else {\n    return std::string{input.substr(start, position - start)};\n  }\n}\n\ntemplate <bool CheckOnly>\nauto parse_authority(const std::string_view input,\n                     std::string_view::size_type &position,\n                     [[maybe_unused]] std::optional<std::string> &userinfo,\n                     [[maybe_unused]] std::optional<std::string> &host,\n                     [[maybe_unused]] std::optional<std::uint32_t> &port,\n                     [[maybe_unused]] bool &ip_literal) -> void {\n  if constexpr (CheckOnly) {\n    parse_userinfo<true>(input, position);\n    parse_host<true>(input, position, ip_literal);\n  } else {\n    auto userinfo_raw = parse_userinfo<false>(input, position);\n    if (userinfo_raw.has_value()) {\n      uri_unescape_unreserved_inplace(userinfo_raw.value());\n      userinfo = std::move(userinfo_raw.value());\n    }\n\n    auto host_raw = parse_host<false>(input, position, ip_literal);\n    uri_unescape_unreserved_inplace(host_raw);\n    host = std::move(host_raw);\n  }\n\n  // RFC 3986: authority = [ userinfo \"@\" ] host [ \":\" port ]\n  // port = *DIGIT (empty port after colon is valid)\n  if (position < input.size() && input[position] == URI_COLON) {\n    position += 1;\n    if constexpr (CheckOnly) {\n      parse_port<true>(input, position);\n    } else {\n      const auto port_start = position;\n      const auto port_value = parse_port<false>(input, position);\n      if (port_value.has_value()) {\n        if (port_value.value() > std::numeric_limits<std::uint32_t>::max())\n            [[unlikely]] {\n          throw sourcemeta::core::URIParseError{\n              static_cast<std::uint64_t>(port_start + 1)};\n        }\n\n        port = static_cast<std::uint32_t>(port_value.value());\n      }\n    }\n  }\n\n  if (position < input.size() && input[position] == URI_AT) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(position + 1)};\n  }\n}\n\ntemplate <bool CheckOnly>\nauto do_parse(const std::string_view input,\n              [[maybe_unused]] std::optional<std::string> &scheme,\n              [[maybe_unused]] std::optional<std::string> &userinfo,\n              [[maybe_unused]] std::optional<std::string> &host,\n              [[maybe_unused]] std::optional<std::uint32_t> &port,\n              [[maybe_unused]] std::optional<std::string> &path,\n              [[maybe_unused]] std::optional<std::string> &query,\n              [[maybe_unused]] std::optional<std::string> &fragment,\n              [[maybe_unused]] bool &ip_literal) -> bool {\n  if (input.empty()) {\n    return false;\n  }\n\n  std::string_view::size_type position{0};\n\n  bool has_scheme;\n  if constexpr (CheckOnly) {\n    has_scheme = parse_scheme<true>(input, position);\n  } else {\n    scheme = parse_scheme<false>(input, position);\n    has_scheme = scheme.has_value();\n  }\n\n  const auto has_authority = position + 1 < input.size() &&\n                             input[position] == URI_SLASH &&\n                             input[position + 1] == URI_SLASH;\n\n  if (has_authority) {\n    position += 2;\n    parse_authority<CheckOnly>(input, position, userinfo, host, port,\n                               ip_literal);\n\n    // RFC 3986: hier-part = \"//\" authority path-abempty\n    // path-abempty = *( \"/\" segment ), so after authority the next character\n    // must be \"/\", \"?\", \"#\", or end-of-input\n    if (position < input.size() && input[position] != URI_SLASH &&\n        input[position] != URI_QUESTION && input[position] != URI_HASH)\n        [[unlikely]] {\n      throw sourcemeta::core::URIParseError{\n          static_cast<std::uint64_t>(position + 1)};\n    }\n  }\n\n  const auto path_start = position;\n  bool has_path;\n  if constexpr (CheckOnly) {\n    has_path = parse_path<true>(input, position);\n  } else {\n    auto parsed_path = parse_path<false>(input, position);\n    has_path = parsed_path.has_value();\n\n    if (has_path) {\n      // RFC 3986: relative-ref without authority uses path-noscheme,\n      // where the first segment must not contain a colon\n      if (!has_scheme && !has_authority) {\n        const auto &path_value = parsed_path.value();\n        if (!path_value.empty() && path_value[0] != URI_SLASH) {\n          const auto first_slash = path_value.find(URI_SLASH);\n          const auto colon_pos = path_value.find(URI_COLON);\n          if (colon_pos != std::string::npos &&\n              (first_slash == std::string::npos || colon_pos < first_slash))\n              [[unlikely]] {\n            throw sourcemeta::core::URIParseError{\n                static_cast<std::uint64_t>(colon_pos + 1)};\n          }\n        }\n      }\n\n      uri_unescape_unreserved_inplace(parsed_path.value());\n      path = std::move(parsed_path.value());\n    } else if (has_authority || has_scheme) {\n      if (input.ends_with(URI_SLASH) || input == \"/\") {\n        path = \"/\";\n      }\n    }\n  }\n\n  if constexpr (CheckOnly) {\n    if (has_path && !has_scheme && !has_authority) {\n      if (input[path_start] != URI_SLASH) {\n        const auto path_view = input.substr(path_start, position - path_start);\n        const auto first_slash = path_view.find(URI_SLASH);\n        const auto colon_pos = path_view.find(URI_COLON);\n        if (colon_pos != std::string_view::npos &&\n            (first_slash == std::string_view::npos || colon_pos < first_slash))\n            [[unlikely]] {\n          throw sourcemeta::core::URIParseError{\n              static_cast<std::uint64_t>(path_start + colon_pos + 1)};\n        }\n      }\n    }\n  }\n\n  if constexpr (CheckOnly) {\n    parse_query<true>(input, position);\n    parse_fragment<true>(input, position);\n  } else {\n    auto parsed_query = parse_query<false>(input, position);\n    if (parsed_query.has_value()) {\n      uri_unescape_unreserved_inplace(parsed_query.value());\n      query = std::move(parsed_query.value());\n    }\n\n    auto parsed_fragment = parse_fragment<false>(input, position);\n    if (parsed_fragment.has_value()) {\n      uri_unescape_unreserved_inplace(parsed_fragment.value());\n      fragment = std::move(parsed_fragment.value());\n    }\n  }\n\n  if (position < input.size()) [[unlikely]] {\n    throw sourcemeta::core::URIParseError{\n        static_cast<std::uint64_t>(position + 1)};\n  }\n\n  return has_scheme;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto URI::parse(const std::string_view input) -> void {\n  assert(!this->scheme_.has_value());\n  assert(!this->userinfo_.has_value());\n  assert(!this->host_.has_value());\n  assert(!this->port_.has_value());\n  assert(!this->path_.has_value());\n  assert(!this->query_.has_value());\n  assert(!this->fragment_.has_value());\n  do_parse<false>(input, this->scheme_, this->userinfo_, this->host_,\n                  this->port_, this->path_, this->query_, this->fragment_,\n                  this->ip_literal_);\n}\n\nauto URI::is_uri(const std::string_view input) noexcept -> bool {\n  try {\n    std::optional<std::string> scheme, userinfo, host, path, query, fragment;\n    std::optional<std::uint32_t> port;\n    bool ip_literal{false};\n    return do_parse<true>(input, scheme, userinfo, host, port, path, query,\n                          fragment, ip_literal);\n  } catch (...) {\n    return false;\n  }\n}\n\nauto URI::is_uri_reference(const std::string_view input) noexcept -> bool {\n  try {\n    std::optional<std::string> scheme, userinfo, host, path, query, fragment;\n    std::optional<std::uint32_t> port;\n    bool ip_literal{false};\n    do_parse<true>(input, scheme, userinfo, host, port, path, query, fragment,\n                   ip_literal);\n    return true;\n  } catch (...) {\n    return false;\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/query.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include <cstddef>     // std::size_t, std::string_view::npos\n#include <optional>    // std::optional\n#include <string_view> // std::string_view\n#include <utility>     // std::pair\n\nnamespace {\n\nauto parse_pair(const std::string_view raw, const std::size_t pair_start)\n    -> std::pair<std::string_view, std::string_view> {\n  const auto separator{raw.find('&', pair_start)};\n  const auto pair_end{separator == std::string_view::npos ? raw.size()\n                                                          : separator};\n  const auto pair_view{raw.substr(pair_start, pair_end - pair_start)};\n  const auto equals_index{pair_view.find('=')};\n  if (equals_index == std::string_view::npos) {\n    return {pair_view, std::string_view{}};\n  }\n  return {pair_view.substr(0, equals_index),\n          pair_view.substr(equals_index + 1)};\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nURI::Query::Query(const std::string_view raw) : raw_{raw} {}\n\nauto URI::Query::raw() const -> std::string_view { return this->raw_; }\n\nauto URI::query() const -> std::optional<URI::Query> {\n  if (!this->query_.has_value()) {\n    return std::nullopt;\n  }\n  return URI::Query{this->query_.value()};\n}\n\nURI::Query::const_iterator::const_iterator(const std::string_view raw,\n                                           const std::size_t pair_start)\n    : raw_{raw}, pair_start_{pair_start} {\n  if (this->pair_start_ != std::string_view::npos) {\n    this->current_ = parse_pair(this->raw_, this->pair_start_);\n  }\n}\n\nauto URI::Query::const_iterator::operator*() const -> reference {\n  return this->current_;\n}\n\nauto URI::Query::const_iterator::operator->() const -> pointer {\n  return &this->current_;\n}\n\nauto URI::Query::const_iterator::operator++() -> const_iterator & {\n  const auto separator{this->raw_.find('&', this->pair_start_)};\n  if (separator == std::string_view::npos) {\n    this->pair_start_ = std::string_view::npos;\n  } else {\n    this->pair_start_ = separator + 1;\n    this->current_ = parse_pair(this->raw_, this->pair_start_);\n  }\n  return *this;\n}\n\nauto URI::Query::const_iterator::operator++(int) -> const_iterator {\n  auto previous{*this};\n  ++(*this);\n  return previous;\n}\n\nauto URI::Query::const_iterator::operator==(const const_iterator &other) const\n    -> bool {\n  return this->pair_start_ == other.pair_start_;\n}\n\nauto URI::Query::const_iterator::operator!=(const const_iterator &other) const\n    -> bool {\n  return !(*this == other);\n}\n\nauto URI::Query::begin() const -> const_iterator {\n  if (this->raw_.empty()) {\n    return this->end();\n  }\n  return const_iterator{this->raw_, 0};\n}\n\nauto URI::Query::end() const -> const_iterator {\n  return const_iterator{this->raw_, std::string_view::npos};\n}\n\n// First-wins on duplicates, matching WHATWG `URLSearchParams.get()`\n// and most major URL libraries\nauto URI::Query::at(const std::string_view name) const\n    -> std::optional<std::string_view> {\n  for (const auto &pair : *this) {\n    if (pair.first == name) {\n      return pair.second;\n    }\n  }\n  return std::nullopt;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/recompose.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include \"escaping.h\"\n\n#include <array>    // std::array\n#include <cctype>   // std::isxdigit\n#include <charconv> // std::to_chars\n#include <cstdint>  // std::uint32_t\n#include <iomanip>  // std::hex, std::uppercase\n#include <optional> // std::optional\n#include <sstream>  // std::ostringstream\n#include <string>   // std::string\n\nnamespace sourcemeta::core {\n\nnamespace {\n\nauto escape_component_to_string(std::string &output, std::string_view input,\n                                const URIEscapeMode mode) -> void {\n  output.reserve(output.size() + input.size() * 3);\n\n  for (std::string_view::size_type index = 0; index < input.size(); ++index) {\n    const char character = input[index];\n\n    // Preserve existing percent-encoded sequences\n    if (character == URI_PERCENT && index + 2 < input.size() &&\n        std::isxdigit(static_cast<unsigned char>(input[index + 1])) &&\n        std::isxdigit(static_cast<unsigned char>(input[index + 2]))) {\n      output += input[index];\n      output += input[index + 1];\n      output += input[index + 2];\n      index += 2;\n      continue;\n    }\n\n    if (uri_is_unreserved(character)) {\n      output += character;\n      continue;\n    }\n\n    if (mode == URIEscapeMode::SkipSubDelims || mode == URIEscapeMode::Path ||\n        mode == URIEscapeMode::Fragment || mode == URIEscapeMode::Filesystem ||\n        mode == URIEscapeMode::UserInfo) {\n      if (uri_is_sub_delim(character)) {\n        output += character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Path) {\n      if (character == URI_COLON || character == URI_AT ||\n          character == URI_SLASH) {\n        output += character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Fragment) {\n      if (character == URI_COLON || character == URI_AT ||\n          character == URI_SLASH || character == URI_QUESTION) {\n        output += character;\n        continue;\n      }\n    }\n\n    if (mode == URIEscapeMode::Filesystem || mode == URIEscapeMode::UserInfo) {\n      if (character == URI_COLON) {\n        output += character;\n        continue;\n      }\n    }\n\n    output += URI_PERCENT;\n    const auto byte{static_cast<unsigned char>(character)};\n    const auto high{(byte >> 4) & 0x0F};\n    const auto low{byte & 0x0F};\n    output += static_cast<char>(high < 10 ? '0' + high : 'A' + high - 10);\n    output += static_cast<char>(low < 10 ? '0' + low : 'A' + low - 10);\n  }\n}\n\n} // namespace\n\nauto URI::recompose() const -> std::string {\n  auto uri{this->recompose_without_fragment()};\n\n  if (!this->fragment_.has_value()) {\n    return uri.value_or(\"\");\n  }\n\n  std::string result;\n  if (uri.has_value()) {\n    result = *std::move(uri);\n  }\n\n  result.reserve(result.size() + this->fragment_.value().size() * 3 + 1);\n  result += '#';\n  escape_component_to_string(result, this->fragment_.value(),\n                             URIEscapeMode::Fragment);\n\n  return result;\n}\n\nauto URI::recompose_without_fragment() const -> std::optional<std::string> {\n  std::string result;\n  result.reserve(256);\n\n  // Scheme\n  const auto result_scheme{this->scheme()};\n  if (result_scheme.has_value()) {\n    result += result_scheme.value();\n    result += ':';\n  }\n\n  // Authority\n  const auto user_info{this->userinfo()};\n  const auto result_host{this->host()};\n  const auto result_port{this->port()};\n  const bool has_authority{user_info.has_value() || result_host.has_value() ||\n                           result_port.has_value()};\n\n  // Add \"//\" prefix when we have authority (with or without scheme)\n  if (has_authority) {\n    result += \"//\";\n  }\n\n  if (user_info.has_value()) {\n    escape_component_to_string(result, user_info.value(),\n                               URIEscapeMode::UserInfo);\n    result += '@';\n  }\n\n  // Host\n  if (result_host.has_value()) {\n    if (this->ip_literal_) {\n      result += '[';\n      result += result_host.value();\n      result += ']';\n    } else {\n      escape_component_to_string(result, result_host.value(),\n                                 URIEscapeMode::SkipSubDelims);\n    }\n  }\n\n  // Port\n  if (result_port.has_value()) {\n    result += ':';\n    std::array<char, 20> port_buffer{};\n    const auto [end_pointer, error_code] = std::to_chars(\n        port_buffer.data(), port_buffer.data() + port_buffer.size(),\n        result_port.value());\n    result.append(port_buffer.data(), end_pointer);\n  }\n\n  // Path\n  const auto result_path = this->path();\n  if (result_path.has_value()) {\n    const auto &path_value = result_path.value();\n\n    escape_component_to_string(result, path_value, URIEscapeMode::Path);\n  }\n\n  // Query\n  const auto result_query{this->query()};\n  if (result_query.has_value()) {\n    result += '?';\n    escape_component_to_string(result, result_query.value().raw(),\n                               URIEscapeMode::Fragment);\n  }\n\n  if (result.empty()) {\n    return std::nullopt;\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/resolution.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include <cassert>  // assert\n#include <optional> // std::optional\n#include <string>   // std::string\n\nnamespace {\n\n// RFC 3986 Section 5.2.4: Remove Dot Segments\n// This algorithm removes the special \".\" and \"..\" segments from a path\nauto remove_dot_segments(const std::string &path) -> std::string {\n  std::string input = path;\n  std::string output;\n\n  while (!input.empty()) {\n    // A: If the input buffer begins with a prefix of \"../\" or \"./\"\n    if (input.starts_with(\"../\")) {\n      input = input.substr(3);\n    } else if (input.starts_with(\"./\")) {\n      input = input.substr(2);\n    }\n    // B: If the input buffer begins with a prefix of \"/./\" or \"/.\"\n    else if (input.starts_with(\"/./\")) {\n      input = \"/\" + input.substr(3);\n    } else if (input == \"/.\") {\n      input = \"/\";\n    }\n    // C: If the input buffer begins with a prefix of \"/../\" or \"/..\"\n    else if (input.starts_with(\"/../\")) {\n      input = \"/\" + input.substr(4);\n      // Remove the last segment from output\n      const auto last_slash = output.rfind('/');\n      if (last_slash != std::string::npos) {\n        output = output.substr(0, last_slash);\n      } else {\n        output.clear();\n      }\n    } else if (input == \"/..\") {\n      input = \"/\";\n      // Remove the last segment from output\n      const auto last_slash = output.rfind('/');\n      if (last_slash != std::string::npos) {\n        output = output.substr(0, last_slash);\n      } else {\n        output.clear();\n      }\n    }\n    // D: If the input buffer consists only of \".\" or \"..\"\n    else if (input == \".\" || input == \"..\") {\n      input.clear();\n    }\n    // E: Move the first path segment to the end of output\n    else {\n      std::string::size_type next_slash;\n      if (input.starts_with('/')) {\n        next_slash = input.find('/', 1);\n      } else {\n        next_slash = input.find('/');\n      }\n\n      if (next_slash == std::string::npos) {\n        output += input;\n        input.clear();\n      } else {\n        output += input.substr(0, next_slash);\n        input = input.substr(next_slash);\n      }\n    }\n  }\n\n  return output;\n}\n\n// Merge paths according to RFC 3986 Section 5.2.3\nauto merge_paths(const std::string &base_path, const std::string &ref_path,\n                 bool base_has_authority) -> std::string {\n  // If base has authority and empty path, prepend \"/\"\n  if (base_has_authority && base_path.empty()) {\n    return \"/\" + ref_path;\n  }\n\n  // Otherwise, merge by removing everything after the last \"/\" in base\n  const auto last_slash = base_path.rfind('/');\n  if (last_slash == std::string::npos) {\n    return ref_path;\n  }\n\n  return base_path.substr(0, last_slash + 1) + ref_path;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto URI::resolve_from(const URI &base) -> URI & {\n  // RFC 3986 Section 5.2.2: Transform References\n\n  // Check if this is a dot reference (\".\" or \"./\") before we modify the path\n  const bool was_dot_reference =\n      this->path_.has_value() &&\n      (this->path_.value() == \".\" || this->path_.value() == \"./\");\n\n  // Reference has a scheme - use as-is (already absolute)\n  if (this->scheme_.has_value()) {\n    if (this->path_.has_value()) {\n      this->path_ = remove_dot_segments(this->path_.value());\n    }\n    return *this;\n  }\n\n  // NON-STANDARD EXTENSION: Handle relative-to-relative resolution\n  // RFC 3986 requires base to be absolute, but we extend to support\n  // specific relative base cases\n  if (!base.is_absolute()) {\n    if (this->is_fragment_only()) {\n      // Fragment-only reference: add fragment to base\n      this->path_ = base.path_;\n      this->query_ = base.query_;\n      return *this;\n    }\n\n    // Simple relative-to-relative case: merge paths directly\n    // Example: \"foo/bar/baz\" + \"qux\" = \"foo/bar/qux\"\n    const auto base_path = base.path_.value_or(\"\");\n    if (!base_path.starts_with('/') && this->path_.has_value()) {\n      const auto &ref_path = this->path_.value();\n      if (!ref_path.starts_with('/') && !ref_path.contains('/')) {\n        auto merged = merge_paths(base_path, ref_path, false);\n        this->path_ = remove_dot_segments(merged);\n        return *this;\n      }\n    }\n\n    // Otherwise, leave unchanged\n    return *this;\n  }\n\n  // From here on, reference has no scheme and base is absolute\n\n  // Reference has authority - use reference authority and path\n  if (this->host_.has_value()) {\n    this->scheme_ = base.scheme_;\n    if (this->path_.has_value()) {\n      this->path_ = remove_dot_segments(this->path_.value());\n    }\n    return *this;\n  }\n\n  // From here on, reference has no authority, so use base authority\n  this->scheme_ = base.scheme_;\n  this->userinfo_ = base.userinfo_;\n  this->host_ = base.host_;\n  this->port_ = base.port_;\n\n  // Reference has empty path\n  if (!this->path_.has_value() || this->path_.value().empty()) {\n    // Special case: \".\" or \"./\" resolves to the containing directory\n    if (was_dot_reference) {\n      const auto base_path = base.path_.value_or(\"\");\n      const auto last_slash = base_path.rfind('/');\n      if (last_slash != std::string::npos) {\n        this->path_ = base_path.substr(0, last_slash + 1);\n      } else {\n        this->path_ = std::nullopt;\n      }\n      return *this;\n    }\n\n    // Empty path with query or fragment means use base path\n    this->path_ = base.path_;\n    if (!this->query_.has_value()) {\n      this->query_ = base.query_;\n    }\n    return *this;\n  }\n\n  // Reference path starts with \"/\" - use reference path as-is\n  if (this->path_.value().starts_with('/')) {\n    this->path_ = remove_dot_segments(this->path_.value());\n    return *this;\n  }\n\n  // Reference path is relative - merge with base path\n  const auto base_path = base.path_.value_or(\"\");\n  const bool base_has_authority = base.host_.has_value();\n  auto merged_path =\n      merge_paths(base_path, this->path_.value(), base_has_authority);\n  this->path_ = remove_dot_segments(merged_path);\n\n  return *this;\n}\n\nauto URI::relative_to(const URI &base) -> URI & {\n  // Only works if both URIs are absolute\n  if (!this->is_absolute() || !base.is_absolute()) {\n    return *this;\n  }\n\n  // Schemes must match\n  if (this->scheme_ != base.scheme_) {\n    return *this;\n  }\n\n  // The full authority must match (but components can be null for URNs)\n  if (this->userinfo_ != base.userinfo_) {\n    return *this;\n  }\n\n  if (this->host_ != base.host_) {\n    return *this;\n  }\n\n  if (this->port_ != base.port_) {\n    return *this;\n  }\n\n  // Special case: both URIs are exactly the same\n  if (this->path_ == base.path_ && this->query_ == base.query_ &&\n      this->fragment_ == base.fragment_) {\n    // Clear all components to make it empty relative URI\n    this->scheme_.reset();\n    this->userinfo_.reset();\n    this->host_.reset();\n    this->port_.reset();\n    this->path_.reset();\n    this->query_.reset();\n    this->fragment_.reset();\n    return *this;\n  }\n\n  // If this URI doesn't have a path, we can't make it relative\n  if (!this->path_.has_value()) {\n    return *this;\n  }\n\n  const auto &this_path = this->path_.value();\n\n  const auto &base_path = base.path_.value_or(\"\");\n\n  // Case 1: Check if this_path starts with base_path followed by \"/\"\n  // This handles: base=\"/foo\" and this=\"/foo/bar\" = \"bar\"\n  // But NOT: base=\"/spec\" and this=\"/spec/\" (different resources)\n  const std::string base_with_slash =\n      base_path.ends_with('/') ? base_path : base_path + \"/\";\n  if (this_path.starts_with(base_with_slash) &&\n      this_path.length() > base_with_slash.length()) {\n    auto relative_path = this_path.substr(base_with_slash.length());\n\n    this->scheme_.reset();\n    this->userinfo_.reset();\n    this->host_.reset();\n    this->port_.reset();\n    this->path_ = relative_path.empty()\n                      ? std::nullopt\n                      : std::optional<std::string>{relative_path};\n\n    return *this;\n  }\n\n  // Find last slash positions (needed for multiple cases below)\n  const auto base_last_slash = base_path.rfind('/');\n  const auto this_last_slash = this_path.rfind('/');\n\n  // Case 2: Check if both paths share the same parent directory (siblings)\n  // This handles: base=\"/test/bar.json\" and this=\"/test/foo.json\" =\n  // \"foo.json\"\n  if (base_last_slash != std::string::npos &&\n      this_last_slash != std::string::npos) {\n    const auto base_parent = base_path.substr(0, base_last_slash + 1);\n    const auto this_parent = this_path.substr(0, this_last_slash + 1);\n\n    if (base_parent == this_parent) {\n      auto relative_path = this_path.substr(this_last_slash + 1);\n\n      this->scheme_.reset();\n      this->userinfo_.reset();\n      this->host_.reset();\n      this->port_.reset();\n      this->path_ = relative_path.empty()\n                        ? std::nullopt\n                        : std::optional<std::string>{relative_path};\n\n      return *this;\n    }\n  }\n\n  // Case 3: Base has no path or empty path\n  // Examples: \"https://example.com\" or \"schema:\"\n  // Strip leading slash and make relative\n  if (base_path.empty()) {\n    auto relative_path = this_path;\n\n    if (relative_path.starts_with('/')) {\n      relative_path = relative_path.substr(1);\n    }\n\n    this->scheme_.reset();\n    this->userinfo_.reset();\n    this->host_.reset();\n    this->port_.reset();\n    this->path_ = relative_path.empty()\n                      ? std::nullopt\n                      : std::optional<std::string>{relative_path};\n\n    return *this;\n  }\n\n  // Case 4: General case - compute relative path using .. segments\n  // This handles cases like: base=\"/schemas/foo.json\" and this=\"/bundling/bar\"\n  // Result should be \"../bundling/bar\"\n  // Note: We don't make URIs relative if the target is just a shallow path\n  // like \"/foo\" (only one level deep) as that's not meaningfully navigable\n  const auto base_parent = base_last_slash != std::string::npos\n                               ? base_path.substr(0, base_last_slash + 1)\n                               : base_path;\n\n  std::string relative_path;\n  std::string current_base_parent{base_parent};\n\n  while (!current_base_parent.empty() && current_base_parent != \"/\") {\n    if (this_path.starts_with(current_base_parent)) {\n      const auto remainder{this_path.substr(current_base_parent.length())};\n      if (!remainder.empty()) {\n        // Check if the target is just the base path plus a trailing slash\n        // e.g., base=\"/foo/bar\" and target=\"/foo/bar/\"\n        // These should stay absolute as they represent different resources\n        if (current_base_parent == base_parent &&\n            this_path == base_path + \"/\") {\n          return *this;\n        }\n\n        relative_path += remainder;\n      }\n\n      this->scheme_.reset();\n      this->userinfo_.reset();\n      this->host_.reset();\n      this->port_.reset();\n      this->path_ = relative_path.empty()\n                        ? std::nullopt\n                        : std::optional<std::string>{relative_path};\n\n      return *this;\n    }\n\n    relative_path += \"../\";\n    const auto parent_slash{\n        current_base_parent.rfind('/', current_base_parent.length() - 2)};\n    if (parent_slash == std::string::npos) {\n      break;\n    }\n    current_base_parent = current_base_parent.substr(0, parent_slash + 1);\n  }\n\n  // If we reached the root, we can make it relative unless the target path\n  // is ambiguous (i.e., it's a prefix of the base parent directory)\n  // This handles: \"/a/b/c.json\" vs \"/d.json\" -> \"../../d.json\"\n  // And: \"/foo/bar\" vs \"/baz/qux\" -> \"../../baz/qux\"\n  // But NOT: \"/foo/bar\" vs \"/foo\" (ambiguous: is /foo a file or directory?)\n  if (current_base_parent == \"/\" && this_path.starts_with('/')) {\n    // Check if target path is a prefix of the original base parent\n    // If so, it's ambiguous and we should stay absolute\n    const bool is_prefix_of_base_parent =\n        base_parent.starts_with(this_path) &&\n        base_parent.length() > this_path.length() &&\n        (base_parent[this_path.length()] == '/');\n\n    if (!is_prefix_of_base_parent) {\n      relative_path += this_path.substr(1);\n\n      this->scheme_.reset();\n      this->userinfo_.reset();\n      this->host_.reset();\n      this->port_.reset();\n      this->path_ = relative_path.empty()\n                        ? std::nullopt\n                        : std::optional<std::string>{relative_path};\n\n      return *this;\n    }\n  }\n\n  // If we can't make it relative, return unchanged\n  return *this;\n}\n\nauto URI::rebase(const URI &base, const URI &new_base) -> URI & {\n  this->relative_to(base);\n  if (!this->is_relative()) {\n    return *this;\n  }\n\n  // Save the relative path before copying new_base components\n  auto saved_path = std::move(this->path_);\n  auto saved_fragment = std::move(this->fragment_);\n  auto saved_query = std::move(this->query_);\n\n  // Copy all components from new_base except path/query/fragment\n  this->scheme_ = new_base.scheme_;\n  this->userinfo_ = new_base.userinfo_;\n  this->host_ = new_base.host_;\n  this->port_ = new_base.port_;\n\n  if (new_base.path_.has_value() && saved_path.has_value()) {\n    const auto &base_path = new_base.path_.value();\n    const auto &relative_path = saved_path.value();\n    const auto base_ends_with_slash = base_path.ends_with('/');\n    const auto relative_starts_with_slash = relative_path.starts_with('/');\n    if (base_ends_with_slash && relative_starts_with_slash) {\n      this->path_ = base_path + relative_path.substr(1);\n    } else if (!base_ends_with_slash && !relative_starts_with_slash) {\n      this->path_ = base_path + '/' + relative_path;\n    } else {\n      this->path_ = base_path + relative_path;\n    }\n  } else if (new_base.path_.has_value()) {\n    this->path_ = new_base.path_;\n  } else {\n    this->path_ = std::move(saved_path);\n  }\n\n  // Restore fragment and query from the relative URI\n  this->fragment_ = std::move(saved_fragment);\n  this->query_ = std::move(saved_query);\n\n  return *this;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/setters.cc",
    "content": "#include <sourcemeta/core/uri.h>\n\n#include \"escaping.h\"\n\n#include <optional>    // std::optional\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace {\n\nauto apply_leading_slash_transform(std::optional<std::string> parsed_path,\n                                   const bool needs_leading_slash)\n    -> std::optional<std::string> {\n  if (!parsed_path.has_value()) {\n    return parsed_path;\n  }\n\n  const auto &path_value = parsed_path.value();\n\n  if (needs_leading_slash) {\n    if (path_value.empty() || !path_value.starts_with(\"/\")) {\n      return \"/\" + path_value;\n    }\n  }\n\n  return parsed_path;\n}\n\nauto normalize_fragment(const std::string_view input) -> std::string {\n  if (input.empty()) {\n    return \"\";\n  }\n\n  // Strip leading '#' and store raw value\n  return std::string{input.starts_with('#') ? input.substr(1) : input};\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto URI::path(const std::string &path) -> URI & {\n  if (path.empty()) {\n    this->path_ = std::nullopt;\n    return *this;\n  }\n\n  if (path.starts_with(\".\") && this->is_absolute()) {\n    throw URIError{\"You cannot set a relative path to an absolute URI\"};\n  }\n\n  // Parse the path string to extract its normalized value\n  const auto parsed_path = URI{path}.path_;\n\n  // Determine if this URI needs a leading slash\n  // (URIs with scheme/authority need leading slash, except URNs/tags/mailto)\n  const auto needs_leading_slash =\n      (!this->is_urn() && !this->is_tag() && !this->is_mailto() &&\n       this->scheme_.has_value()) ||\n      this->port_.has_value() || this->host_.has_value();\n\n  this->path_ = apply_leading_slash_transform(parsed_path, needs_leading_slash);\n  return *this;\n}\n\nauto URI::path(std::string &&path) -> URI & {\n  if (path.empty()) {\n    this->path_ = std::nullopt;\n    return *this;\n  }\n\n  if (path.starts_with(\".\") && this->is_absolute()) {\n    throw URIError{\"You cannot set a relative path to an absolute URI\"};\n  }\n\n  // Parse the path string to extract its normalized value\n  const auto parsed_path = URI{path}.path_;\n\n  // Determine if this URI needs a leading slash\n  // (URIs with scheme/authority need leading slash, except URNs/tags/mailto)\n  const auto needs_leading_slash =\n      (!this->is_urn() && !this->is_tag() && !this->is_mailto() &&\n       this->scheme_.has_value()) ||\n      this->port_.has_value() || this->host_.has_value();\n\n  this->path_ = apply_leading_slash_transform(parsed_path, needs_leading_slash);\n  return *this;\n}\n\nauto URI::append_path(const std::string &path) -> URI & {\n  if (path.empty()) {\n    return *this;\n  }\n\n  if (!this->path_.has_value()) {\n    return this->path(path);\n  }\n\n  auto &current_path = this->path_.value();\n  const auto current_ends_with_slash = current_path.ends_with('/');\n  const auto path_starts_with_slash = path.starts_with('/');\n\n  if (current_ends_with_slash && path_starts_with_slash) {\n    current_path += path.substr(1);\n  } else if (!current_ends_with_slash && !path_starts_with_slash) {\n    current_path += '/';\n    current_path += path;\n  } else {\n    current_path += path;\n  }\n\n  return *this;\n}\n\nauto URI::extension(std::string &&extension) -> URI & {\n  if (!this->path_.has_value()) {\n    return *this;\n  }\n\n  auto &path = this->path_.value();\n  if (path.empty() || path.ends_with('/')) {\n    return *this;\n  }\n\n  // Find the last dot after the last slash (if any)\n  const auto last_slash_pos = path.find_last_of('/');\n  const auto last_dot_pos = path.find_last_of('.');\n\n  // Only consider the dot if it's after the last slash (or there's no slash)\n  const auto has_extension =\n      last_dot_pos != std::string::npos &&\n      (last_slash_pos == std::string::npos || last_dot_pos > last_slash_pos);\n\n  // Remove existing extension if present\n  if (has_extension) {\n    path.erase(last_dot_pos);\n  }\n\n  // Add new extension if not empty\n  if (!extension.empty()) {\n    // Strip leading dot from extension if present\n    if (extension.starts_with('.')) {\n      path += extension;\n    } else {\n      path += '.';\n      path += extension;\n    }\n  }\n\n  return *this;\n}\n\nauto URI::fragment(const std::string_view fragment) -> URI & {\n  this->fragment_ = normalize_fragment(std::string{fragment});\n  return *this;\n}\n\nauto URI::query(const std::string_view query) -> URI & {\n  if (query.empty()) {\n    this->query_ = std::nullopt;\n    return *this;\n  }\n\n  std::string value{query.starts_with('?') ? query.substr(1) : query};\n  uri_unescape_unreserved_inplace(value);\n  this->query_ = std::move(value);\n  return *this;\n}\n\nauto URI::userinfo(const std::string_view userinfo) -> URI & {\n  if (userinfo.empty()) {\n    this->userinfo_ = std::nullopt;\n    return *this;\n  }\n\n  std::string value{userinfo};\n  uri_unescape_unreserved_inplace(value);\n  this->userinfo_ = std::move(value);\n  return *this;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uri/uri.cc",
    "content": "#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/uri.h>\n\n#include <tuple> // std::tie\n\nnamespace sourcemeta::core {\n\nURI::URI(std::istream &input) {\n  this->parse(sourcemeta::core::read_to_string(input));\n}\n\nauto URI::from_fragment(const std::string_view fragment) -> URI {\n  URI result;\n  result.fragment(fragment);\n  return result;\n}\n\nauto URI::operator<(const URI &other) const noexcept -> bool {\n  return std::tie(this->scheme_, this->userinfo_, this->host_, this->port_,\n                  this->path_, this->query_, this->fragment_) <\n         std::tie(other.scheme_, other.userinfo_, other.host_, other.port_,\n                  other.path_, other.query_, other.fragment_);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME uritemplate\n  PRIVATE_HEADERS error.h token.h router.h\n  SOURCES helpers.h uritemplate.cc uritemplate_router.cc uritemplate_router_view.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME uritemplate)\nendif()\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/helpers.h",
    "content": "#ifndef SOURCEMETA_CORE_URITEMPLATE_HELPERS_H_\n#define SOURCEMETA_CORE_URITEMPLATE_HELPERS_H_\n\n#include <sourcemeta/core/uritemplate.h>\n\n#include <array>       // std::array\n#include <cstddef>     // std::size_t\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <type_traits> // std::void_t\n\nnamespace sourcemeta::core {\n\n// Type traits to detect optional static members\ntemplate <typename T, typename = void> struct has_op : std::false_type {};\ntemplate <typename T>\nstruct has_op<T, std::void_t<decltype(T::op)>> : std::true_type {};\n\ntemplate <typename T, typename = void> struct has_prefix : std::false_type {};\ntemplate <typename T>\nstruct has_prefix<T, std::void_t<decltype(T::prefix)>> : std::true_type {};\n\ntemplate <typename T, typename = void>\nstruct has_empty_suffix : std::false_type {};\ntemplate <typename T>\nstruct has_empty_suffix<T, std::void_t<decltype(T::empty_suffix)>>\n    : std::true_type {};\n\ninline auto is_unreserved(const char character) -> bool {\n  return (character >= 'A' && character <= 'Z') ||\n         (character >= 'a' && character <= 'z') ||\n         (character >= '0' && character <= '9') || character == '-' ||\n         character == '.' || character == '_' || character == '~';\n}\n\ninline auto is_reserved(const char character) -> bool {\n  return character == ':' || character == '/' || character == '?' ||\n         character == '#' || character == '[' || character == ']' ||\n         character == '@' || character == '!' || character == '$' ||\n         character == '&' || character == '\\'' || character == '(' ||\n         character == ')' || character == '*' || character == '+' ||\n         character == ',' || character == ';' || character == '=';\n}\n\ninline auto is_hex(const char character) -> bool {\n  return (character >= '0' && character <= '9') ||\n         (character >= 'A' && character <= 'F') ||\n         (character >= 'a' && character <= 'f');\n}\n\nstatic constexpr std::array<char, 16> HEX_DIGITS = {\n    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',\n     'F'}};\n\ninline auto append_percent_encoded(std::string &output, const char character)\n    -> void {\n  const auto byte = static_cast<unsigned char>(character);\n  output += '%';\n  output += HEX_DIGITS[byte >> 4];\n  output += HEX_DIGITS[byte & 0x0F];\n}\n\ninline auto percent_encode(std::string &output, const std::string_view input)\n    -> void {\n  output.reserve(output.size() + input.size() * 3);\n  for (const char character : input) {\n    if (is_unreserved(character)) {\n      output += character;\n    } else {\n      append_percent_encoded(output, character);\n    }\n  }\n}\n\ninline auto percent_encode_reserved(std::string &output,\n                                    const std::string_view input) -> void {\n  output.reserve(output.size() + input.size() * 3);\n  for (std::size_t index = 0; index < input.size(); ++index) {\n    const char character = input[index];\n    if (is_unreserved(character) || is_reserved(character) ||\n        (character == '%' && index + 2 < input.size() &&\n         is_hex(input[index + 1]) && is_hex(input[index + 2]))) {\n      output += character;\n    } else {\n      append_percent_encoded(output, character);\n    }\n  }\n}\n\ntemplate <typename T>\ninline auto encode(std::string &output, const std::string_view input) -> void {\n  if constexpr (T::allow_reserved) {\n    percent_encode_reserved(output, input);\n  } else {\n    percent_encode(output, input);\n  }\n}\n\ntemplate <typename T>\ninline auto append_name(std::string &result, const std::string_view name,\n                        const bool value_empty, const bool has_more) -> void {\n  if constexpr (T::named) {\n    result += name;\n    if (value_empty && !has_more) {\n      if constexpr (has_empty_suffix<T>::value) {\n        result += T::empty_suffix;\n      }\n    } else {\n      result += '=';\n    }\n  }\n}\n\n// RFC 6570 Section 2.3: varchar = ALPHA / DIGIT / \"_\"\ninline auto is_varchar(const char character) noexcept -> bool {\n  return (character >= 'A' && character <= 'Z') ||\n         (character >= 'a' && character <= 'z') ||\n         (character >= '0' && character <= '9') || character == '_';\n}\n\n// Variable name character including dot for dotted names like \"foo.bar\"\ninline auto is_varname_char(const char character) noexcept -> bool {\n  return is_varchar(character) || character == '.';\n}\n\n// RFC 6570 Section 2.2: operator = op-level2 / op-level3 / op-reserve\ninline auto is_operator(const char character) noexcept -> bool {\n  return character == '+' || character == '#' || character == '.' ||\n         character == '/' || character == ';' || character == '?' ||\n         character == '&';\n}\n\n// RFC 6570 Section 2.2: op-reserve = \"=\" / \",\" / \"!\" / \"@\" / \"|\"\ninline auto is_reserved_operator(const char character) noexcept -> bool {\n  return character == '=' || character == ',' || character == '!' ||\n         character == '@' || character == '|';\n}\n\n// RFC 6570 Section 2.4: modifier = prefix / explode\ninline auto is_modifier(const char character) noexcept -> bool {\n  return character == ':' || character == '*';\n}\n\ninline auto parse_varname(const std::string_view input, std::size_t position)\n    -> std::size_t {\n  if (position >= input.size() ||\n      (!is_varchar(input[position]) && input[position] != '%')) {\n    throw URITemplateParseError(position + 1);\n  }\n\n  while (position < input.size() && input[position] != '}' &&\n         input[position] != ',' && input[position] != ':' &&\n         input[position] != '*') {\n    const char character = input[position];\n\n    if (is_varchar(character)) {\n      position++;\n    } else if (character == '.') {\n      position++;\n      if (position >= input.size() ||\n          (!is_varchar(input[position]) && input[position] != '%')) {\n        throw URITemplateParseError(position + 1);\n      }\n    } else if (character == '%') {\n      if (position + 2 >= input.size()) {\n        throw URITemplateParseError(position + 1);\n      }\n      if (!is_hex(input[position + 1]) || !is_hex(input[position + 2])) {\n        throw URITemplateParseError(position + 1);\n      }\n      position += 3;\n    } else {\n      throw URITemplateParseError(position + 1);\n    }\n  }\n\n  return position;\n}\n\ninline auto\nparse_variable_list(const std::string_view input, std::size_t position,\n                    std::vector<URITemplateVariableSpecification> &variables)\n    -> std::size_t {\n  while (true) {\n    const auto start = position;\n    position = parse_varname(input, position);\n\n    if (position == start) {\n      throw URITemplateParseError(position + 1);\n    }\n\n    const auto name = input.substr(start, position - start);\n    std::uint16_t length = 0;\n    bool explode = false;\n\n    if (position >= input.size()) {\n      throw URITemplateParseError(1);\n    }\n\n    if (input[position] == ':') {\n      position++;\n      if (position >= input.size() || input[position] < '1' ||\n          input[position] > '9') {\n        throw URITemplateParseError(position + 1);\n      }\n\n      const auto prefix_start = position;\n      while (position < input.size() && input[position] >= '0' &&\n             input[position] <= '9') {\n        position++;\n        if (position - prefix_start > 4) {\n          throw URITemplateParseError(position);\n        }\n      }\n\n      const auto prefix_str =\n          input.substr(prefix_start, position - prefix_start);\n      std::uint16_t value = 0;\n      for (const char character : prefix_str) {\n        value = static_cast<std::uint16_t>(\n            value * 10 + static_cast<std::uint16_t>(character - '0'));\n      }\n\n      if (value > 9999 || value == 0) {\n        throw URITemplateParseError(prefix_start + 1);\n      }\n\n      length = value;\n    } else if (input[position] == '*') {\n      explode = true;\n      position++;\n    }\n\n    variables.push_back(URITemplateVariableSpecification{\n        .name = name, .length = length, .explode = explode});\n\n    if (position >= input.size()) {\n      throw URITemplateParseError(1);\n    }\n\n    if (input[position] == '}') {\n      break;\n    }\n\n    if (input[position] == ',') {\n      position++;\n    }\n  }\n\n  return position;\n}\n\ntemplate <typename T>\nauto parse_expression(const std::string_view input) -> URITemplateParseResult {\n  if constexpr (std::is_same_v<T, URITemplateTokenLiteral>) {\n    if (input.empty() || input[0] == '{') {\n      return std::nullopt;\n    }\n\n    if (input[0] == '}') {\n      throw URITemplateParseError(1);\n    }\n\n    std::size_t position = 1;\n    while (position < input.size()) {\n      if (input[position] == '{') {\n        break;\n      }\n      if (input[position] == '}') {\n        throw URITemplateParseError(position + 1);\n      }\n      position++;\n    }\n\n    return std::make_pair(\n        URITemplateToken{URITemplateTokenLiteral{input.substr(0, position)}},\n        position);\n  } else {\n    if (input.empty() || input[0] != '{') {\n      return std::nullopt;\n    }\n\n    std::size_t var_start;\n    if constexpr (has_op<T>::value) {\n      if (input.size() < 3 || input[1] != T::op) {\n        return std::nullopt;\n      }\n      var_start = 2;\n    } else {\n      if (input.size() < 2) {\n        throw URITemplateParseError(1);\n      }\n      // Not a simple variable if it has an operator\n      if (is_operator(input[1])) {\n        return std::nullopt;\n      }\n      var_start = 1;\n    }\n\n    std::vector<URITemplateVariableSpecification> variables;\n    const auto end_position = parse_variable_list(input, var_start, variables);\n    return std::make_pair(URITemplateToken{T{std::move(variables)}},\n                          end_position + 1);\n  }\n}\n\ntemplate <typename T>\nauto expand_expression(\n    std::string &result,\n    const std::vector<URITemplateVariableSpecification> &variables,\n    const std::function<URITemplateValue(std::string_view)> &callback) -> void {\n  bool first_var = true;\n\n  for (const auto &variable : variables) {\n    auto response = callback(variable.name);\n    if (!response.has_value()) {\n      continue;\n    }\n\n    bool first_value = true;\n\n    while (true) {\n      const auto &[value, object_key, has_more] = response.value();\n\n      if (variable.length > 0 &&\n          (has_more || object_key.has_value() || !first_value)) {\n        throw URITemplateExpansionError{\n            \"Prefix modifier cannot be applied to composite values\"};\n      }\n\n      auto actual_value = value;\n      if (variable.length > 0) {\n        actual_value = actual_value.substr(0, variable.length);\n      }\n\n      if (variable.explode) {\n        if (first_var && first_value) {\n          if constexpr (has_prefix<T>::value) {\n            result += T::prefix;\n          }\n          first_var = false;\n        } else {\n          result += T::separator;\n        }\n\n        if (object_key.has_value()) {\n          encode<T>(result, object_key.value());\n          result += '=';\n          encode<T>(result, actual_value);\n        } else if constexpr (T::named) {\n          result += variable.name;\n          if (actual_value.empty()) {\n            if constexpr (has_empty_suffix<T>::value) {\n              result += T::empty_suffix;\n            }\n          } else {\n            result += '=';\n            encode<T>(result, actual_value);\n          }\n        } else {\n          encode<T>(result, actual_value);\n        }\n      } else {\n        if (first_var && first_value) {\n          if constexpr (has_prefix<T>::value) {\n            result += T::prefix;\n          }\n          first_var = false;\n          append_name<T>(result, variable.name, actual_value.empty(), has_more);\n        } else if (first_value) {\n          result += T::separator;\n          append_name<T>(result, variable.name, actual_value.empty(), has_more);\n        } else {\n          result += ',';\n        }\n\n        if (!first_value || !actual_value.empty() || has_more) {\n          if (object_key.has_value()) {\n            encode<T>(result, object_key.value());\n            result += ',';\n          }\n          encode<T>(result, actual_value);\n        }\n      }\n\n      first_value = false;\n\n      if (!has_more) {\n        break;\n      }\n\n      response = callback(variable.name);\n      if (!response.has_value()) {\n        break;\n      }\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/include/sourcemeta/core/uritemplate.h",
    "content": "#ifndef SOURCEMETA_CORE_URITEMPLATE_H_\n#define SOURCEMETA_CORE_URITEMPLATE_H_\n\n#ifndef SOURCEMETA_CORE_URITEMPLATE_EXPORT\n#include <sourcemeta/core/uritemplate_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/uritemplate_error.h>\n#include <sourcemeta/core/uritemplate_router.h>\n#include <sourcemeta/core/uritemplate_token.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cstddef>     // std::size_t\n#include <cstdint>     // std::uint64_t\n#include <functional>  // std::function\n#include <optional>    // std::optional\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <tuple>       // std::tuple\n#include <type_traits> // std::void_t\n#include <vector>      // std::vector\n\n/// @defgroup uritemplate URI Template\n/// @brief A strict RFC 6570 URI Template implementation.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/uritemplate.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup uritemplate\n/// The return type for URI Template variable callbacks (value, key?, has_more)\nusing URITemplateValue = std::optional<\n    std::tuple<std::string_view, std::optional<std::string_view>, bool>>;\n\n/// @ingroup uritemplate\n/// The result of parsing a token: the token and how many characters were\n/// consumed\nusing URITemplateParseResult =\n    std::optional<std::pair<URITemplateToken, std::size_t>>;\n\n/// @ingroup uritemplate\n/// A parsed URI Template per RFC 6570. This class behaves like a view. The\n/// source string must outlive the template\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplate {\npublic:\n  /// Parse a URI Template from a string view. For example:\n  ///\n  /// ```cpp\n  /// #include <sourcemeta/core/uritemplate.h>\n  ///\n  /// const std::string source{\"http://example.com/~{username}/\"};\n  /// const sourcemeta::core::URITemplate uri_template{source};\n  /// ```\n  URITemplate(const std::string_view source);\n\n  /// Get the number of tokens in the template\n  [[nodiscard]] auto size() const noexcept -> std::uint64_t;\n\n  /// Check if the template is empty\n  [[nodiscard]] auto empty() const noexcept -> bool;\n\n  /// Get the token at the given index\n  [[nodiscard]] auto at(std::size_t index) const & -> const URITemplateToken &;\n\n  /// Get the token at the given index (move overload)\n  [[nodiscard]] auto at(std::size_t index) && -> URITemplateToken;\n\n  /// Iterator to the beginning of the tokens\n  [[nodiscard]] auto begin() const noexcept\n      -> std::vector<URITemplateToken>::const_iterator;\n\n  /// Iterator to the end of the tokens\n  [[nodiscard]] auto end() const noexcept\n      -> std::vector<URITemplateToken>::const_iterator;\n\n  /// Expand the template by looking up variable values via a callback.\n  /// The callback is called repeatedly for composite values\n  [[nodiscard]] auto expand(\n      const std::function<URITemplateValue(std::string_view)> &callback) const\n      -> std::string;\n\n  /// Expand the template using an associative container (string values only)\n  template <typename Container,\n            typename = std::void_t<typename Container::key_type>>\n  [[nodiscard]] auto expand(const Container &variables) const -> std::string {\n    return this->expand([&variables](\n                            const std::string_view name) -> URITemplateValue {\n      const auto iterator{variables.find(typename Container::key_type{name})};\n      if (iterator == variables.end()) {\n        return std::nullopt;\n      } else {\n        return std::make_tuple(std::string_view{iterator->second}, std::nullopt,\n                               false);\n      }\n    });\n  }\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::vector<URITemplateToken> tokens_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/include/sourcemeta/core/uritemplate_error.h",
    "content": "#ifndef SOURCEMETA_CORE_URITEMPLATE_ERROR_H_\n#define SOURCEMETA_CORE_URITEMPLATE_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_URITEMPLATE_EXPORT\n#include <sourcemeta/core/uritemplate_export.h>\n#endif\n\n#include <cstdint>     // std::uint64_t\n#include <exception>   // std::exception\n#include <filesystem>  // std::filesystem::path\n#include <stdexcept>   // std::runtime_error\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup uritemplate\n/// An error that represents a URI Template parsing failure\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateParseError\n    : public std::exception {\npublic:\n  URITemplateParseError(const std::uint64_t column) : column_{column} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"The input is not a valid URI Template\";\n  }\n\n  /// Get the column number of the error\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  std::uint64_t column_;\n};\n\n/// @ingroup uritemplate\n/// An error that represents a URI Template expansion failure\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateExpansionError\n    : public std::runtime_error {\npublic:\n  URITemplateExpansionError(const std::string &message)\n      : std::runtime_error{message} {}\n};\n\n/// @ingroup uritemplate\n/// An error that represents a variable name mismatch when adding routes\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouterVariableMismatchError\n    : public std::exception {\npublic:\n  URITemplateRouterVariableMismatchError(const std::string_view left,\n                                         const std::string_view right)\n      : left_{left}, right_{right} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Variable name mismatch when adding route\";\n  }\n\n  /// Get the existing variable name\n  [[nodiscard]] auto left() const noexcept -> const std::string & {\n    return this->left_;\n  }\n\n  /// Get the conflicting variable name\n  [[nodiscard]] auto right() const noexcept -> const std::string & {\n    return this->right_;\n  }\n\nprivate:\n  std::string left_;\n  std::string right_;\n};\n\n/// @ingroup uritemplate\n/// An error for invalid segments when adding routes\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouterInvalidSegmentError\n    : public std::exception {\npublic:\n  URITemplateRouterInvalidSegmentError(const char *message,\n                                       const std::string_view segment)\n      : message_{message}, segment_{segment} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  /// Get the offending segment\n  [[nodiscard]] auto segment() const noexcept -> const std::string & {\n    return this->segment_;\n  }\n\nprivate:\n  const char *message_;\n  std::string segment_;\n};\n\n/// @ingroup uritemplate\n/// An error that represents a failure to save the router to disk\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouterSaveError\n    : public std::exception {\npublic:\n  URITemplateRouterSaveError(std::filesystem::path path, const char *message)\n      : path_{std::move(path)}, message_{message} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n  const char *message_;\n};\n\n/// @ingroup uritemplate\n/// An error that represents a failure to read the router from disk\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouterReadError\n    : public std::exception {\npublic:\n  URITemplateRouterReadError(std::filesystem::path path)\n      : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Failed to open router file for reading\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/include/sourcemeta/core/uritemplate_router.h",
    "content": "#ifndef SOURCEMETA_CORE_URITEMPLATE_ROUTER_H_\n#define SOURCEMETA_CORE_URITEMPLATE_ROUTER_H_\n\n#ifndef SOURCEMETA_CORE_URITEMPLATE_EXPORT\n#include <sourcemeta/core/uritemplate_export.h>\n#endif\n\n#include <cstddef> // std::size_t\n#include <cstdint> // std::uint16_t, std::uint32_t, std::uint8_t, std::int64_t\n#include <filesystem>  // std::filesystem::path\n#include <functional>  // std::function\n#include <memory>      // std::unique_ptr\n#include <span>        // std::span\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <tuple>       // std::tuple\n#include <utility>     // std::pair\n#include <variant>     // std::variant\n#include <vector>      // std::vector\n\nnamespace sourcemeta::core {\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif\n\n/// @ingroup uritemplate\n/// A URI Template path router. Keep in mind that the URI Template specification\n/// DOES NOT define expansion. So this is an opinionated non-standard adaptation\n/// of URI Template for path routing purposes\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouter {\n  friend class URITemplateRouterView;\n\npublic:\n  /// A handler identifier 0 means \"no handler\"\n  using Identifier = std::uint16_t;\n\n  /// The variable index type\n  using Index = std::uint8_t;\n\n  /// The match callback (index, name, value)\n  using Callback =\n      std::function<void(Index, std::string_view, std::string_view)>;\n\n  using ArgumentValue = std::variant<std::string_view, std::int64_t, bool>;\n  using Argument = std::pair<std::string_view, ArgumentValue>;\n  using ArgumentCallback =\n      std::function<void(std::string_view, const ArgumentValue &)>;\n\n  /// The type of a node in the router trie\n  enum class NodeType : std::uint8_t {\n    Root = 0,\n    Literal = 1,\n    Variable = 2,\n    Expansion = 3\n  };\n\n  /// A node in the router trie\n  struct Node {\n    Identifier identifier{0};\n    Identifier context{0};\n    NodeType type{NodeType::Root};\n    std::string_view value;\n\n    // This children distinction enforces that there can only be one non-literal\n    // child at the type level. Also allows us to more efficiently search on\n    // literals\n    std::vector<std::unique_ptr<Node>> literals;\n    std::unique_ptr<Node> variable;\n  };\n\n  /// Construct an empty router\n  URITemplateRouter() = default;\n\n  /// Construct a router with a base path prefix. During matching, the base\n  /// path is stripped from incoming request paths before matching\n  explicit URITemplateRouter(std::string_view base_path);\n\n  // To avoid mistakes\n  URITemplateRouter(const URITemplateRouter &) = delete;\n  URITemplateRouter(URITemplateRouter &&) = delete;\n  auto operator=(const URITemplateRouter &) -> URITemplateRouter & = delete;\n  auto operator=(URITemplateRouter &&) -> URITemplateRouter & = delete;\n\n  /// Add a route to the router. Make sure the string lifetime survives the\n  /// router\n  auto add(const std::string_view uri_template, const Identifier identifier,\n           const Identifier context = 0,\n           const std::span<const Argument> arguments = {}) -> void;\n\n  /// Register a fallback context and arguments to be returned when matching\n  /// a path that does not correspond to any registered route\n  auto otherwise(const Identifier context,\n                 const std::span<const Argument> arguments = {}) -> void;\n\n  /// Match a path against the router. Note the callback might fire for\n  /// initial matches even though the entire match might still fail\n  [[nodiscard]] auto match(const std::string_view path,\n                           const Callback &callback) const\n      -> std::pair<Identifier, Identifier>;\n\n  /// Access the root node of the trie\n  [[nodiscard]] auto root() const noexcept -> const Node &;\n\n  /// Access the stored arguments for a given route identifier\n  auto arguments(const Identifier identifier,\n                 const ArgumentCallback &callback) const -> void;\n\n  /// Access all stored route arguments\n  [[nodiscard]] auto arguments() const noexcept\n      -> const std::vector<std::pair<Identifier, std::vector<Argument>>> &;\n\n  /// Access the base path prefix\n  [[nodiscard]] auto base_path() const noexcept -> std::string_view;\n\n  /// Get the number of registered routes\n  [[nodiscard]] auto size() const noexcept -> std::size_t;\n\n  /// Get the identifier of the route at the given positional index\n  [[nodiscard]] auto at(const std::size_t index) const -> Identifier;\n\n  /// Get the context identifier associated with a registered route\n  /// identifier\n  [[nodiscard]] auto context(const Identifier identifier) const -> Identifier;\n\n  /// Reconstruct and return the URI Template path string originally registered\n  /// for the given identifier\n  [[nodiscard]] auto path(const Identifier identifier) const -> std::string;\n\nprivate:\n  Node root_;\n  Node otherwise_;\n  std::string base_path_;\n  std::vector<std::pair<Identifier, std::vector<Argument>>> arguments_;\n  std::vector<std::tuple<Identifier, Identifier, std::string_view>> entries_;\n};\n\n/// @ingroup uritemplate\n/// A read-only view of a serialized URI Template router\nclass SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateRouterView {\npublic:\n  /// Save a router to a binary file\n  static auto save(const URITemplateRouter &router,\n                   const std::filesystem::path &path) -> void;\n\n  URITemplateRouterView(const std::filesystem::path &path);\n  URITemplateRouterView(const std::uint8_t *data, std::size_t size);\n\n  // To avoid mistakes\n  URITemplateRouterView(const URITemplateRouterView &) = delete;\n  URITemplateRouterView(URITemplateRouterView &&) = delete;\n  auto operator=(const URITemplateRouterView &)\n      -> URITemplateRouterView & = delete;\n  auto operator=(URITemplateRouterView &&) -> URITemplateRouterView & = delete;\n\n  /// Match a path against the router. Note the callback might fire for\n  /// initial matches even though the entire match might still fail\n  [[nodiscard]] auto match(const std::string_view path,\n                           const URITemplateRouter::Callback &callback) const\n      -> std::pair<URITemplateRouter::Identifier,\n                   URITemplateRouter::Identifier>;\n\n  /// Access the stored arguments for a given route identifier\n  auto arguments(const URITemplateRouter::Identifier identifier,\n                 const URITemplateRouter::ArgumentCallback &callback) const\n      -> void;\n\n  /// Access the base path prefix\n  [[nodiscard]] auto base_path() const noexcept -> std::string_view;\n\n  /// Get the number of registered routes\n  [[nodiscard]] auto size() const noexcept -> std::size_t;\n\n  /// Get the identifier of the route at the given positional index\n  [[nodiscard]] auto at(const std::size_t index) const\n      -> URITemplateRouter::Identifier;\n\n  /// Get the context identifier associated with a registered route\n  /// identifier\n  [[nodiscard]] auto\n  context(const URITemplateRouter::Identifier identifier) const\n      -> URITemplateRouter::Identifier;\n\n  /// Reconstruct and return the URI Template path string originally registered\n  /// for the given identifier\n  [[nodiscard]] auto path(const URITemplateRouter::Identifier identifier) const\n      -> std::string;\n\nprivate:\n  std::vector<std::uint8_t> data_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/include/sourcemeta/core/uritemplate_token.h",
    "content": "#ifndef SOURCEMETA_CORE_URITEMPLATE_TOKEN_H_\n#define SOURCEMETA_CORE_URITEMPLATE_TOKEN_H_\n\n#ifndef SOURCEMETA_CORE_URITEMPLATE_EXPORT\n#include <sourcemeta/core/uritemplate_export.h>\n#endif\n\n#include <cstdint>     // std::uint16_t\n#include <string_view> // std::string_view\n#include <variant>     // std::variant\n#include <vector>      // std::vector\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif\n\n/// @ingroup uritemplate\n/// A literal string segment in a URI Template\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLiteral {\n  std::string_view value;\n};\n\n/// @ingroup uritemplate\n/// A variable specification within a URI Template expression\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateVariableSpecification {\n  std::string_view name;\n  // As per the RFC, the range is 1-9999. 0 means \"no prefix length\"\n  std::uint16_t length{0};\n  bool explode{false};\n};\n\n/// @ingroup uritemplate\n/// A simple string variable expansion {var} in a URI Template (Level 1)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenVariable {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char separator = ',';\n  static constexpr bool named = false;\n  static constexpr bool allow_reserved = false;\n};\n\n/// @ingroup uritemplate\n/// A reserved expansion {+var} in a URI Template (Level 2)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenReservedExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '+';\n  static constexpr char separator = ',';\n  static constexpr bool named = false;\n  static constexpr bool allow_reserved = true;\n};\n\n/// @ingroup uritemplate\n/// A fragment expansion {#var} in a URI Template (Level 2)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenFragmentExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '#';\n  static constexpr char separator = ',';\n  static constexpr char prefix = '#';\n  static constexpr bool named = false;\n  static constexpr bool allow_reserved = true;\n};\n\n/// @ingroup uritemplate\n/// A label expansion {.var} in a URI Template (Level 3)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLabelExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '.';\n  static constexpr char separator = '.';\n  static constexpr char prefix = '.';\n  static constexpr bool named = false;\n  static constexpr bool allow_reserved = false;\n};\n\n/// @ingroup uritemplate\n/// A path expansion {/var} in a URI Template (Level 3)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenPathExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '/';\n  static constexpr char separator = '/';\n  static constexpr char prefix = '/';\n  static constexpr bool named = false;\n  static constexpr bool allow_reserved = false;\n};\n\n/// @ingroup uritemplate\n/// A path parameter expansion {;var} in a URI Template (Level 3)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT\n    URITemplateTokenPathParameterExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = ';';\n  static constexpr char separator = ';';\n  static constexpr char prefix = ';';\n  static constexpr bool named = true;\n  static constexpr bool allow_reserved = false;\n};\n\n/// @ingroup uritemplate\n/// A query expansion {?var} in a URI Template (Level 3)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenQueryExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '?';\n  static constexpr char separator = '&';\n  static constexpr char prefix = '?';\n  static constexpr bool named = true;\n  static constexpr bool allow_reserved = false;\n  static constexpr char empty_suffix = '=';\n};\n\n/// @ingroup uritemplate\n/// A query continuation expansion {&var} in a URI Template (Level 3)\nstruct SOURCEMETA_CORE_URITEMPLATE_EXPORT\n    URITemplateTokenQueryContinuationExpansion {\n  std::vector<URITemplateVariableSpecification> variables;\n  static constexpr char op = '&';\n  static constexpr char separator = '&';\n  static constexpr char prefix = '&';\n  static constexpr bool named = true;\n  static constexpr bool allow_reserved = false;\n  static constexpr char empty_suffix = '=';\n};\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n/// @ingroup uritemplate\n/// A token in a parsed URI Template\nusing URITemplateToken = std::variant<\n    URITemplateTokenLiteral, URITemplateTokenVariable,\n    URITemplateTokenReservedExpansion, URITemplateTokenFragmentExpansion,\n    URITemplateTokenLabelExpansion, URITemplateTokenPathExpansion,\n    URITemplateTokenPathParameterExpansion, URITemplateTokenQueryExpansion,\n    URITemplateTokenQueryContinuationExpansion>;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/uritemplate.cc",
    "content": "#include <sourcemeta/core/uritemplate.h>\n\n#include \"helpers.h\"\n\n#include <cassert> // assert\n#include <utility> // std::pair\n#include <vector>  // std::vector\n\nnamespace sourcemeta::core {\n\ntemplate <typename T>\nstatic auto try_parse(std::string_view &remaining, std::size_t &offset,\n                      std::vector<URITemplateToken> &tokens) -> bool {\n  if (auto result = parse_expression<T>(remaining)) {\n    tokens.emplace_back(std::move(result->first));\n    remaining.remove_prefix(result->second);\n    offset += result->second;\n    return true;\n  }\n\n  return false;\n}\n\ntemplate <typename... Ts>\nstatic auto try_parse_any(std::string_view &remaining, std::size_t &offset,\n                          std::vector<URITemplateToken> &tokens) -> bool {\n  return (try_parse<Ts>(remaining, offset, tokens) || ...);\n}\n\nURITemplate::URITemplate(const std::string_view source) {\n  std::string_view remaining{source};\n  std::size_t offset = 0;\n\n  while (!remaining.empty()) {\n    try {\n      if (!try_parse_any<URITemplateTokenReservedExpansion,\n                         URITemplateTokenFragmentExpansion,\n                         URITemplateTokenLabelExpansion,\n                         URITemplateTokenPathExpansion,\n                         URITemplateTokenPathParameterExpansion,\n                         URITemplateTokenQueryExpansion,\n                         URITemplateTokenQueryContinuationExpansion,\n                         URITemplateTokenVariable, URITemplateTokenLiteral>(\n              remaining, offset, this->tokens_)) {\n        break;\n      }\n    } catch (URITemplateParseError &error) {\n      throw URITemplateParseError(offset + error.column());\n    }\n  }\n}\n\nauto URITemplate::size() const noexcept -> std::uint64_t {\n  return static_cast<std::uint64_t>(this->tokens_.size());\n}\n\nauto URITemplate::empty() const noexcept -> bool {\n  return this->tokens_.empty();\n}\n\nauto URITemplate::at(const std::size_t index) const & -> const\n    URITemplateToken & {\n  assert(index < this->tokens_.size());\n  return this->tokens_[index];\n}\n\nauto URITemplate::at(const std::size_t index) && -> URITemplateToken {\n  assert(index < this->tokens_.size());\n  return std::move(this->tokens_[index]);\n}\n\nauto URITemplate::begin() const noexcept\n    -> std::vector<URITemplateToken>::const_iterator {\n  return this->tokens_.cbegin();\n}\n\nauto URITemplate::end() const noexcept\n    -> std::vector<URITemplateToken>::const_iterator {\n  return this->tokens_.cend();\n}\n\nauto URITemplate::expand(\n    const std::function<URITemplateValue(std::string_view name)> &callback)\n    const -> std::string {\n  std::string result;\n\n  for (const auto &token : this->tokens_) {\n    std::visit(\n        [&result, &callback](const auto &expansion) {\n          using T = std::decay_t<decltype(expansion)>;\n          if constexpr (std::is_same_v<T, URITemplateTokenLiteral>) {\n            result += expansion.value;\n          } else {\n            expand_expression<T>(result, expansion.variables, callback);\n          }\n        },\n        token);\n  }\n\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/uritemplate_router.cc",
    "content": "#include <sourcemeta/core/uritemplate.h>\n\n#include \"helpers.h\"\n\n#include <algorithm> // std::ranges::lower_bound\n#include <cassert>   // assert\n#include <limits>    // std::numeric_limits\n#include <tuple>     // std::get, std::make_tuple\n\nnamespace sourcemeta::core {\n\nnamespace {\n\nusing Node = URITemplateRouter::Node;\nusing NodeType = URITemplateRouter::NodeType;\n\nconstexpr auto node_value =\n    [](const std::unique_ptr<Node> &child) -> decltype(auto) {\n  return child->value;\n};\n\nauto find_literal_child(const std::vector<std::unique_ptr<Node>> &literals,\n                        const std::string_view segment) -> Node * {\n  const auto iterator =\n      std::ranges::lower_bound(literals, segment, {}, node_value);\n  if (iterator != literals.end() && (*iterator)->value == segment) {\n    return iterator->get();\n  }\n  return nullptr;\n}\n\nauto find_or_create_literal_child(std::vector<std::unique_ptr<Node>> &literals,\n                                  const std::string_view value) -> Node & {\n  auto iterator = std::ranges::lower_bound(literals, value, {}, node_value);\n  if (iterator != literals.end() && (*iterator)->value == value) {\n    return **iterator;\n  }\n\n  auto child = std::make_unique<Node>();\n  child->type = NodeType::Literal;\n  child->value = value;\n  auto &result = *child;\n  literals.insert(iterator, std::move(child));\n  return result;\n}\n\nauto find_or_create_variable_child(std::unique_ptr<Node> &variable,\n                                   const std::string_view name,\n                                   const NodeType type) -> Node * {\n  if (!variable) {\n    variable = std::make_unique<Node>();\n    variable->type = type;\n    variable->value = name;\n    return variable.get();\n  }\n\n  if (variable->value != name) {\n    throw URITemplateRouterVariableMismatchError{variable->value, name};\n  }\n\n  if (type == NodeType::Expansion) {\n    if (variable->type == NodeType::Variable) {\n      variable->type = NodeType::Expansion;\n      return variable.get();\n    }\n  } else if (variable->type == NodeType::Expansion) {\n    return nullptr;\n  }\n\n  return variable.get();\n}\n\n// Find the end of a brace expression (including the closing brace)\ninline auto find_expression_end(const char *start, const char *end) -> const\n    char * {\n  const char *position = start + 1;\n  while (position < end && *position != '}') {\n    ++position;\n  }\n  if (position < end) {\n    ++position; // include the '}'\n  }\n  return position;\n}\n\n// Extract the current segment (from segment start to next / or end)\ninline auto extract_segment(const char *start, const char *end)\n    -> std::string_view {\n  const char *position = start;\n  while (position < end && *position != '/') {\n    ++position;\n  }\n  return {start, static_cast<std::size_t>(position - start)};\n}\n\ninline auto finalize_match(const Node &otherwise,\n                           const URITemplateRouter::Identifier identifier,\n                           const URITemplateRouter::Identifier context)\n    -> std::pair<URITemplateRouter::Identifier, URITemplateRouter::Identifier> {\n  if (identifier == 0) {\n    return {URITemplateRouter::Identifier{0}, otherwise.context};\n  }\n\n  return {identifier, context};\n}\n\n} // namespace\n\nURITemplateRouter::URITemplateRouter(const std::string_view base_path)\n    : base_path_{base_path} {\n  assert(this->base_path_.empty() || this->base_path_.front() == '/');\n  const auto last = this->base_path_.find_last_not_of('/');\n  if (last == std::string::npos) {\n    this->base_path_.clear();\n  } else {\n    this->base_path_.erase(last + 1);\n  }\n}\n\nauto URITemplateRouter::base_path() const noexcept -> std::string_view {\n  return this->base_path_;\n}\n\nauto URITemplateRouter::size() const noexcept -> std::size_t {\n  return this->entries_.size();\n}\n\nauto URITemplateRouter::at(const std::size_t index) const -> Identifier {\n  assert(index < this->entries_.size());\n  return std::get<0>(this->entries_[index]);\n}\n\nauto URITemplateRouter::context(const Identifier identifier) const\n    -> Identifier {\n  assert(identifier > 0);\n  const auto entry = std::ranges::find_if(\n      this->entries_, [&identifier](const auto &candidate) {\n        return std::get<0>(candidate) == identifier;\n      });\n  assert(entry != this->entries_.end());\n  return std::get<1>(*entry);\n}\n\nauto URITemplateRouter::path(const Identifier identifier) const -> std::string {\n  assert(identifier > 0);\n  const auto entry = std::ranges::find_if(\n      this->entries_, [&identifier](const auto &candidate) {\n        return std::get<0>(candidate) == identifier;\n      });\n  assert(entry != this->entries_.end());\n  return std::string{std::get<2>(*entry)};\n}\n\nauto URITemplateRouter::otherwise(const Identifier context,\n                                  const std::span<const Argument> arguments)\n    -> void {\n  this->otherwise_.context = context;\n\n  const auto existing = std::ranges::find_if(\n      this->arguments_, [](const auto &entry) { return entry.first == 0; });\n  if (existing == this->arguments_.end()) {\n    if (!arguments.empty()) {\n      this->arguments_.emplace_back(\n          Identifier{0},\n          std::vector<Argument>{arguments.begin(), arguments.end()});\n    }\n  } else {\n    if (arguments.empty()) {\n      this->arguments_.erase(existing);\n    } else {\n      existing->second.assign(arguments.begin(), arguments.end());\n    }\n  }\n}\n\nauto URITemplateRouter::add(const std::string_view uri_template,\n                            const Identifier identifier,\n                            const Identifier context,\n                            const std::span<const Argument> arguments) -> void {\n  assert(identifier > 0);\n\n  // Walk base path segments to establish the trie prefix\n  Node *current = nullptr;\n  if (!this->base_path_.empty()) {\n    const char *base_position = this->base_path_.data();\n    const char *const base_end = base_position + this->base_path_.size();\n    while (base_position < base_end) {\n      while (base_position < base_end && *base_position == '/') {\n        ++base_position;\n      }\n      if (base_position >= base_end) {\n        break;\n      }\n      const char *segment_start = base_position;\n      while (base_position < base_end && *base_position != '/') {\n        ++base_position;\n      }\n      const std::string_view segment{\n          segment_start,\n          static_cast<std::size_t>(base_position - segment_start)};\n      auto &literals = current ? current->literals : this->root_.literals;\n      current = &find_or_create_literal_child(literals, segment);\n    }\n  }\n\n  if (uri_template.empty()) {\n    auto &target = current ? *current : this->root_;\n    const auto previous_identifier = target.identifier;\n    if (previous_identifier == 0) {\n      this->entries_.emplace_back(identifier, context, uri_template);\n    } else {\n      const auto existing = std::ranges::find_if(\n          this->entries_, [&previous_identifier](const auto &candidate) {\n            return std::get<0>(candidate) == previous_identifier;\n          });\n      if (existing != this->entries_.end()) {\n        *existing = std::make_tuple(identifier, context, uri_template);\n      }\n    }\n    target.identifier = identifier;\n    target.context = context;\n    if (!arguments.empty()) {\n      assert(std::ranges::none_of(this->arguments_,\n                                  [&identifier](const auto &entry) {\n                                    return entry.first == identifier;\n                                  }));\n      this->arguments_.emplace_back(\n          identifier,\n          std::vector<Argument>{arguments.begin(), arguments.end()});\n    }\n\n    return;\n  }\n\n  Node *base_path_end = current;\n  bool absorbed = false;\n  const char *position = uri_template.data();\n  const char *const end = position + uri_template.size();\n\n  while (position < end && !absorbed) {\n    while (position < end && *position == '/') {\n      ++position;\n    }\n\n    if (position >= end) {\n      break;\n    }\n\n    const char *segment_start = position;\n\n    if (*position == '}') {\n      throw URITemplateRouterInvalidSegmentError{\n          \"Unmatched closing brace\", extract_segment(segment_start, end)};\n    }\n\n    if (*position == '{') {\n      const char *expression_start = position;\n      const char *expression_end = find_expression_end(position, end);\n      std::string_view expression{\n          expression_start,\n          static_cast<std::size_t>(expression_end - expression_start)};\n\n      ++position;\n\n      if (position >= end) {\n        throw URITemplateRouterInvalidSegmentError{\"Unclosed brace\",\n                                                   expression};\n      }\n\n      NodeType type = NodeType::Variable;\n      if (*position == '+') {\n        type = NodeType::Expansion;\n        ++position;\n        if (position >= end || *position == '}') {\n          throw URITemplateRouterInvalidSegmentError{\"Empty variable name\",\n                                                     expression};\n        }\n      } else if (is_operator(*position) && *position != '+') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Unsupported URI Template operator\", expression};\n      } else if (is_reserved_operator(*position)) {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Reserved URI Template operator\", expression};\n      } else if (*position == '{') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Nested opening brace\", extract_segment(expression_start, end)};\n      } else if (*position == ' ') {\n        throw URITemplateRouterInvalidSegmentError{\"Space before variable name\",\n                                                   expression};\n      } else if (*position == '}') {\n        throw URITemplateRouterInvalidSegmentError{\"Empty variable name\",\n                                                   expression};\n      }\n\n      const char *varname_start = position;\n      while (position < end && *position != '}' && *position != ' ' &&\n             !is_modifier(*position) && *position != ',') {\n        if (!is_varname_char(*position)) {\n          throw URITemplateRouterInvalidSegmentError{\n              \"Invalid character in variable name\", expression};\n        }\n        ++position;\n      }\n\n      if (position >= end) {\n        throw URITemplateRouterInvalidSegmentError{\"Unclosed brace\",\n                                                   expression};\n      }\n\n      if (*position == ' ') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Space in variable expression\", expression};\n      }\n\n      if (*position == ':') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Prefix modifier not supported\", expression};\n      }\n\n      if (*position == '*') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Explode modifier not supported\", expression};\n      }\n\n      if (*position == ',') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Multiple variables not supported\", expression};\n      }\n\n      const std::string_view varname{\n          varname_start, static_cast<std::size_t>(position - varname_start)};\n\n      ++position; // skip '}'\n\n      if (position < end && *position != '/') {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Path segment cannot mix literals and variables\",\n            extract_segment(expression_start, end)};\n      }\n\n      if (type == NodeType::Expansion && position < end) {\n        throw URITemplateRouterInvalidSegmentError{\n            \"Reserved expansion must be the last segment\", expression};\n      }\n\n      auto &variable = current ? current->variable : this->root_.variable;\n      auto *result = find_or_create_variable_child(variable, varname, type);\n      if (result == nullptr) {\n        absorbed = true;\n      } else {\n        current = result;\n      }\n    } else {\n      while (position < end && *position != '/' && *position != '{') {\n        if (*position == '}') {\n          throw URITemplateRouterInvalidSegmentError{\n              \"Unmatched closing brace\", extract_segment(segment_start, end)};\n        }\n        ++position;\n      }\n\n      if (position < end && *position == '{') {\n        const char *expr_end = find_expression_end(position, end);\n        const char *seg_end = expr_end;\n        while (seg_end < end && *seg_end != '/') {\n          ++seg_end;\n        }\n        throw URITemplateRouterInvalidSegmentError{\n            \"Path segment cannot mix literals and variables\",\n            std::string_view{segment_start, static_cast<std::size_t>(\n                                                seg_end - segment_start)}};\n      }\n\n      const std::string_view segment{\n          segment_start, static_cast<std::size_t>(position - segment_start)};\n\n      auto &literals = current ? current->literals : this->root_.literals;\n      current = &find_or_create_literal_child(literals, segment);\n    }\n  }\n\n  if (current == base_path_end && uri_template.size() == 1 &&\n      uri_template[0] == '/') {\n    auto &literals = current ? current->literals : this->root_.literals;\n    current = &find_or_create_literal_child(literals, \"\");\n  }\n\n  if (!absorbed && current != nullptr) {\n    const auto previous_identifier = current->identifier;\n    if (previous_identifier == 0) {\n      this->entries_.emplace_back(identifier, context, uri_template);\n    } else {\n      const auto existing = std::ranges::find_if(\n          this->entries_, [&previous_identifier](const auto &candidate) {\n            return std::get<0>(candidate) == previous_identifier;\n          });\n      if (existing != this->entries_.end()) {\n        *existing = std::make_tuple(identifier, context, uri_template);\n      }\n    }\n    current->identifier = identifier;\n    current->context = context;\n    if (!arguments.empty()) {\n      assert(std::ranges::none_of(this->arguments_,\n                                  [&identifier](const auto &entry) {\n                                    return entry.first == identifier;\n                                  }));\n      this->arguments_.emplace_back(\n          identifier,\n          std::vector<Argument>{arguments.begin(), arguments.end()});\n    }\n  }\n}\n\nauto URITemplateRouter::root() const noexcept -> const Node & {\n  return this->root_;\n}\n\nauto URITemplateRouter::arguments(const Identifier identifier,\n                                  const ArgumentCallback &callback) const\n    -> void {\n  for (const auto &entry : this->arguments_) {\n    if (entry.first == identifier) {\n      for (const auto &argument : entry.second) {\n        callback(argument.first, argument.second);\n      }\n\n      return;\n    }\n  }\n}\n\nauto URITemplateRouter::arguments() const noexcept\n    -> const std::vector<std::pair<Identifier, std::vector<Argument>>> & {\n  return this->arguments_;\n}\n\nauto URITemplateRouter::match(const std::string_view path,\n                              const Callback &callback) const\n    -> std::pair<Identifier, Identifier> {\n  if (path.empty()) {\n    return finalize_match(this->otherwise_, this->root_.identifier,\n                          this->root_.context);\n  }\n\n  if (path.size() == 1 && path[0] == '/') {\n    if (auto *child = find_literal_child(this->root_.literals, \"\")) {\n      return finalize_match(this->otherwise_, child->identifier,\n                            child->context);\n    }\n    return finalize_match(this->otherwise_, 0, 0);\n  }\n\n  const Node *current = nullptr;\n  const char *position = path.data();\n  const char *const path_end = position + path.size();\n\n  const std::vector<std::unique_ptr<Node>> *literal_children =\n      &this->root_.literals;\n  const std::unique_ptr<Node> *variable_child = &this->root_.variable;\n\n  std::size_t variable_index = 0;\n\n  // Skip leading slash\n  if (position < path_end && *position == '/') {\n    ++position;\n  }\n\n  while (true) {\n    const char *segment_start = position;\n    while (position < path_end && *position != '/') {\n      ++position;\n    }\n    const std::string_view segment{\n        segment_start, static_cast<std::size_t>(position - segment_start)};\n\n    // Empty segment (from double slash or trailing slash) doesn't match\n    if (segment.empty()) {\n      return finalize_match(this->otherwise_, 0, 0);\n    }\n\n    if (auto *literal_match = find_literal_child(*literal_children, segment)) {\n      current = literal_match;\n    } else if (*variable_child) {\n      assert(variable_index <=\n             std::numeric_limits<URITemplateRouter::Index>::max());\n      if ((*variable_child)->type == NodeType::Expansion) {\n        const std::string_view remaining{\n            segment_start, static_cast<std::size_t>(path_end - segment_start)};\n        callback(static_cast<URITemplateRouter::Index>(variable_index),\n                 (*variable_child)->value, remaining);\n        return finalize_match(this->otherwise_, (*variable_child)->identifier,\n                              (*variable_child)->context);\n      }\n      callback(static_cast<URITemplateRouter::Index>(variable_index),\n               (*variable_child)->value, segment);\n      ++variable_index;\n      current = variable_child->get();\n    } else {\n      return finalize_match(this->otherwise_, 0, 0);\n    }\n\n    literal_children = &current->literals;\n    variable_child = &current->variable;\n\n    // Check if there's more path\n    if (position >= path_end) {\n      break;\n    }\n\n    // Skip the slash and continue to next segment\n    ++position;\n  }\n\n  return current ? finalize_match(this->otherwise_, current->identifier,\n                                  current->context)\n                 : finalize_match(this->otherwise_, this->root_.identifier,\n                                  this->root_.context);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/uritemplate/uritemplate_router_view.cc",
    "content": "#include <sourcemeta/core/uritemplate.h>\n\n#include <array>         // std::array\n#include <cassert>       // assert\n#include <cstring>       // std::memcmp, std::memcpy\n#include <fstream>       // std::ofstream, std::ifstream\n#include <limits>        // std::numeric_limits\n#include <queue>         // std::queue\n#include <string>        // std::string\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <utility>       // std::pair\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core {\n\nnamespace {\n\nconstexpr std::uint32_t ROUTER_MAGIC = 0x52544552; // \"RTER\"\nconstexpr std::uint32_t ROUTER_VERSION = 5;\nconstexpr std::uint32_t NO_CHILD = std::numeric_limits<std::uint32_t>::max();\n\n// Type tags for argument value serialization\nconstexpr std::uint8_t ARGUMENT_TYPE_STRING = 0x00;\nconstexpr std::uint8_t ARGUMENT_TYPE_INTEGER = 0x01;\nconstexpr std::uint8_t ARGUMENT_TYPE_BOOLEAN = 0x02;\n\nstruct RouterHeader {\n  std::uint32_t magic;\n  std::uint32_t version;\n  std::uint32_t node_count;\n  std::uint32_t string_table_offset;\n  std::uint32_t arguments_offset;\n  std::uint32_t base_path_offset;\n  std::uint32_t base_path_length;\n  std::uint32_t otherwise_context;\n};\n\nstruct ArgumentEntryHeader {\n  std::uint16_t identifier;\n  std::uint32_t blob_offset;\n  std::uint32_t blob_length;\n};\n\nstruct alignas(8) SerializedNode {\n  std::uint32_t string_offset;\n  std::uint32_t string_length;\n  std::uint32_t first_literal_child;\n  std::uint32_t literal_child_count;\n  std::uint32_t variable_child;\n  URITemplateRouter::NodeType type;\n  std::uint8_t padding;\n  URITemplateRouter::Identifier identifier;\n  URITemplateRouter::Identifier context;\n  std::array<std::uint8_t, 6> padding2;\n};\n\ninline auto\nfinalize_match(const URITemplateRouter::Identifier otherwise_context,\n               const URITemplateRouter::Identifier identifier,\n               const URITemplateRouter::Identifier context)\n    -> std::pair<URITemplateRouter::Identifier, URITemplateRouter::Identifier> {\n  if (identifier == 0) {\n    return {URITemplateRouter::Identifier{0}, otherwise_context};\n  }\n\n  return {identifier, context};\n}\n\ninline auto count_base_path_segments(const std::string_view base_path) noexcept\n    -> std::uint32_t {\n  std::uint32_t count = 0;\n  std::size_t position = 0;\n  while (position < base_path.size()) {\n    while (position < base_path.size() && base_path[position] == '/') {\n      ++position;\n    }\n    if (position >= base_path.size()) {\n      break;\n    }\n    while (position < base_path.size() && base_path[position] != '/') {\n      ++position;\n    }\n    ++count;\n  }\n  return count;\n}\n\ninline auto reconstruct_path_recursive(\n    const SerializedNode *nodes, const std::uint32_t node_count,\n    const char *string_table, const std::size_t string_table_size,\n    const std::uint32_t node_index, const std::uint32_t depth,\n    const std::uint32_t base_path_depth,\n    const URITemplateRouter::Identifier target, std::string &accumulator)\n    -> bool {\n  if (node_index >= node_count) {\n    return false;\n  }\n\n  const auto &node = nodes[node_index];\n\n  if (node.string_offset > string_table_size ||\n      node.string_length > string_table_size - node.string_offset) {\n    return false;\n  }\n\n  const std::string_view value{string_table + node.string_offset,\n                               node.string_length};\n\n  if (depth > base_path_depth) {\n    switch (node.type) {\n      case URITemplateRouter::NodeType::Literal:\n        accumulator += '/';\n        accumulator.append(value.data(), value.size());\n        break;\n      case URITemplateRouter::NodeType::Variable:\n        accumulator += \"/{\";\n        accumulator.append(value.data(), value.size());\n        accumulator += '}';\n        break;\n      case URITemplateRouter::NodeType::Expansion:\n        accumulator += \"/{+\";\n        accumulator.append(value.data(), value.size());\n        accumulator += '}';\n        break;\n      default:\n        break;\n    }\n  }\n\n  if (node.identifier == target) {\n    return true;\n  }\n\n  const auto saved_length = accumulator.size();\n\n  if (node.first_literal_child != NO_CHILD &&\n      node.first_literal_child < node_count &&\n      node.literal_child_count <= node_count - node.first_literal_child) {\n    for (std::uint32_t offset = 0; offset < node.literal_child_count;\n         ++offset) {\n      if (reconstruct_path_recursive(\n              nodes, node_count, string_table, string_table_size,\n              node.first_literal_child + offset, depth + 1, base_path_depth,\n              target, accumulator)) {\n        return true;\n      }\n      accumulator.resize(saved_length);\n    }\n  }\n\n  if (node.variable_child != NO_CHILD && node.variable_child < node_count) {\n    if (reconstruct_path_recursive(nodes, node_count, string_table,\n                                   string_table_size, node.variable_child,\n                                   depth + 1, base_path_depth, target,\n                                   accumulator)) {\n      return true;\n    }\n    accumulator.resize(saved_length);\n  }\n\n  return false;\n}\n\n// Binary search for a literal child matching the given segment\ninline auto binary_search_literal_children(\n    const SerializedNode *nodes, const char *string_table,\n    const std::size_t string_table_size, const std::uint32_t first_child,\n    const std::uint32_t child_count, const char *segment,\n    const std::uint32_t segment_length) noexcept -> std::uint32_t {\n  std::uint32_t low = 0;\n  std::uint32_t high = child_count;\n\n  while (low < high) {\n    const auto middle = low + (high - low) / 2;\n    const auto child_index = first_child + middle;\n    const auto &child = nodes[child_index];\n\n    if (child.string_offset > string_table_size ||\n        child.string_length > string_table_size - child.string_offset) {\n      return NO_CHILD;\n    }\n\n    // Compare segments lexicographically (content first, then length)\n    const auto min_length = segment_length < child.string_length\n                                ? segment_length\n                                : child.string_length;\n    const auto content_comparison =\n        std::memcmp(segment, string_table + child.string_offset, min_length);\n    const auto comparison = content_comparison != 0\n                                ? content_comparison\n                                : static_cast<int>(segment_length) -\n                                      static_cast<int>(child.string_length);\n\n    if (comparison < 0) {\n      high = middle;\n    } else if (comparison > 0) {\n      low = middle + 1;\n    } else {\n      return child_index;\n    }\n  }\n\n  return NO_CHILD;\n}\n\n} // namespace\n\nauto URITemplateRouterView::save(const URITemplateRouter &router,\n                                 const std::filesystem::path &path) -> void {\n  std::vector<SerializedNode> nodes;\n  std::string string_table;\n  std::queue<const URITemplateRouter::Node *> queue;\n  std::unordered_map<const URITemplateRouter::Node *, std::uint32_t>\n      node_indices;\n\n  const auto &root = router.root();\n\n  SerializedNode root_serialized{};\n  root_serialized.string_offset = 0;\n  root_serialized.string_length = 0;\n  root_serialized.type = URITemplateRouter::NodeType::Root;\n  root_serialized.padding = 0;\n  root_serialized.identifier = root.identifier;\n  root_serialized.context = root.context;\n\n  if (root.literals.empty()) {\n    root_serialized.first_literal_child = NO_CHILD;\n    root_serialized.literal_child_count = 0;\n  } else {\n    root_serialized.first_literal_child = 1;\n    root_serialized.literal_child_count =\n        static_cast<std::uint32_t>(root.literals.size());\n    for (const auto &child : root.literals) {\n      node_indices[child.get()] = static_cast<std::uint32_t>(queue.size() + 1);\n      queue.push(child.get());\n    }\n  }\n\n  if (root.variable) {\n    root_serialized.variable_child =\n        static_cast<std::uint32_t>(queue.size() + 1);\n    node_indices[root.variable.get()] = root_serialized.variable_child;\n    queue.push(root.variable.get());\n  } else {\n    root_serialized.variable_child = NO_CHILD;\n  }\n\n  nodes.push_back(root_serialized);\n\n  while (!queue.empty()) {\n    const auto *node = queue.front();\n    queue.pop();\n\n    SerializedNode serialized{};\n    serialized.string_offset = static_cast<std::uint32_t>(string_table.size());\n    serialized.type = node->type;\n    serialized.string_length = static_cast<std::uint32_t>(node->value.size());\n    string_table += node->value;\n\n    serialized.padding = 0;\n    serialized.identifier = node->identifier;\n    serialized.context = node->context;\n\n    const auto first_child_index =\n        static_cast<std::uint32_t>(nodes.size() + queue.size() + 1);\n\n    if (!node->literals.empty()) {\n      serialized.first_literal_child = first_child_index;\n      serialized.literal_child_count =\n          static_cast<std::uint32_t>(node->literals.size());\n      for (const auto &child : node->literals) {\n        node_indices[child.get()] =\n            static_cast<std::uint32_t>(nodes.size() + queue.size() + 1);\n        queue.push(child.get());\n      }\n    } else {\n      serialized.first_literal_child = NO_CHILD;\n      serialized.literal_child_count = 0;\n    }\n\n    if (node->variable) {\n      serialized.variable_child =\n          static_cast<std::uint32_t>(nodes.size() + queue.size() + 1);\n      node_indices[node->variable.get()] = serialized.variable_child;\n      queue.push(node->variable.get());\n    } else {\n      serialized.variable_child = NO_CHILD;\n    }\n\n    nodes.push_back(serialized);\n  }\n\n  // Build the arguments section\n  const auto &route_arguments = router.arguments();\n  const auto entry_count = static_cast<std::uint16_t>(route_arguments.size());\n\n  // Build per-entry blobs\n  std::vector<ArgumentEntryHeader> argument_entries;\n  std::vector<std::uint8_t> argument_blob;\n  argument_entries.reserve(entry_count);\n\n  for (const auto &[identifier, arguments] : route_arguments) {\n    ArgumentEntryHeader entry{};\n    entry.identifier = identifier;\n    entry.blob_offset = static_cast<std::uint32_t>(argument_blob.size());\n\n    assert(arguments.size() <= std::numeric_limits<std::uint16_t>::max());\n    const auto arg_count = static_cast<std::uint16_t>(arguments.size());\n    argument_blob.push_back(static_cast<std::uint8_t>(arg_count & 0xFF));\n    argument_blob.push_back(static_cast<std::uint8_t>(arg_count >> 8));\n\n    for (const auto &[name, value] : arguments) {\n      // Write key_length + key_bytes\n      assert(name.size() <= std::numeric_limits<std::uint16_t>::max());\n      const auto key_length = static_cast<std::uint16_t>(name.size());\n      argument_blob.push_back(static_cast<std::uint8_t>(key_length & 0xFF));\n      argument_blob.push_back(static_cast<std::uint8_t>(key_length >> 8));\n      argument_blob.insert(argument_blob.end(), name.begin(), name.end());\n\n      // Write type_tag + value_length + value_bytes\n      if (std::holds_alternative<std::string_view>(value)) {\n        const auto string_value = std::get<std::string_view>(value);\n        assert(string_value.size() <=\n               std::numeric_limits<std::uint16_t>::max());\n        const auto value_length =\n            static_cast<std::uint16_t>(string_value.size());\n        argument_blob.push_back(ARGUMENT_TYPE_STRING);\n        argument_blob.push_back(static_cast<std::uint8_t>(value_length & 0xFF));\n        argument_blob.push_back(static_cast<std::uint8_t>(value_length >> 8));\n        argument_blob.insert(argument_blob.end(), string_value.begin(),\n                             string_value.end());\n      } else if (std::holds_alternative<std::int64_t>(value)) {\n        const auto integer_value = std::get<std::int64_t>(value);\n        argument_blob.push_back(ARGUMENT_TYPE_INTEGER);\n        argument_blob.push_back(8);\n        argument_blob.push_back(0);\n        const auto old_size = argument_blob.size();\n        argument_blob.resize(old_size + 8);\n        std::memcpy(argument_blob.data() + old_size, &integer_value, 8);\n      } else {\n        const auto boolean_value = std::get<bool>(value);\n        argument_blob.push_back(ARGUMENT_TYPE_BOOLEAN);\n        argument_blob.push_back(1);\n        argument_blob.push_back(0);\n        argument_blob.push_back(boolean_value ? 1 : 0);\n      }\n    }\n\n    entry.blob_length =\n        static_cast<std::uint32_t>(argument_blob.size()) - entry.blob_offset;\n    argument_entries.push_back(entry);\n  }\n\n  // Append the base path to the string table\n  const auto base_path_string_offset =\n      static_cast<std::uint32_t>(string_table.size());\n  const auto base_path_value = router.base_path();\n  string_table.append(base_path_value.data(), base_path_value.size());\n\n  RouterHeader header{};\n  header.magic = ROUTER_MAGIC;\n  header.version = ROUTER_VERSION;\n  header.node_count = static_cast<std::uint32_t>(nodes.size());\n  header.string_table_offset = static_cast<std::uint32_t>(\n      sizeof(RouterHeader) + nodes.size() * sizeof(SerializedNode));\n  header.arguments_offset = static_cast<std::uint32_t>(\n      header.string_table_offset + string_table.size());\n  header.base_path_offset = base_path_string_offset;\n  header.base_path_length = static_cast<std::uint32_t>(base_path_value.size());\n  header.otherwise_context = router.otherwise_.context;\n\n  std::ofstream file(path, std::ios::binary);\n  if (!file) {\n    throw URITemplateRouterSaveError{path, \"Failed to open file for writing\"};\n  }\n\n  file.write(reinterpret_cast<const char *>(&header), sizeof(header));\n  file.write(\n      reinterpret_cast<const char *>(nodes.data()),\n      static_cast<std::streamsize>(nodes.size() * sizeof(SerializedNode)));\n  file.write(string_table.data(),\n             static_cast<std::streamsize>(string_table.size()));\n\n  // Write arguments section\n  file.write(reinterpret_cast<const char *>(&entry_count), sizeof(entry_count));\n  for (const auto &entry : argument_entries) {\n    file.write(reinterpret_cast<const char *>(&entry.identifier),\n               sizeof(entry.identifier));\n    file.write(reinterpret_cast<const char *>(&entry.blob_offset),\n               sizeof(entry.blob_offset));\n    file.write(reinterpret_cast<const char *>(&entry.blob_length),\n               sizeof(entry.blob_length));\n  }\n\n  if (!argument_blob.empty()) {\n    file.write(reinterpret_cast<const char *>(argument_blob.data()),\n               static_cast<std::streamsize>(argument_blob.size()));\n  }\n\n  if (!file) {\n    throw URITemplateRouterSaveError{path,\n                                     \"Failed to write router data to file\"};\n  }\n}\n\nURITemplateRouterView::URITemplateRouterView(\n    const std::filesystem::path &path) {\n  std::ifstream file(path, std::ios::binary | std::ios::ate);\n  if (!file) {\n    throw URITemplateRouterReadError{path};\n  }\n\n  const auto position = file.tellg();\n  if (position < 0) {\n    throw URITemplateRouterReadError{path};\n  }\n\n  const auto size = static_cast<std::size_t>(position);\n  file.seekg(0, std::ios::beg);\n  this->data_.resize(size);\n  file.read(reinterpret_cast<char *>(this->data_.data()),\n            static_cast<std::streamsize>(size));\n  if (!file) {\n    throw URITemplateRouterReadError{path};\n  }\n}\n\nURITemplateRouterView::URITemplateRouterView(const std::uint8_t *data,\n                                             const std::size_t size)\n    : data_{data, data + size} {}\n\nauto URITemplateRouterView::match(\n    const std::string_view path,\n    const URITemplateRouter::Callback &callback) const\n    -> std::pair<URITemplateRouter::Identifier, URITemplateRouter::Identifier> {\n  if (this->data_.size() < sizeof(RouterHeader)) {\n    return {};\n  }\n\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  if (header->magic != ROUTER_MAGIC || header->version != ROUTER_VERSION) {\n    return {};\n  }\n\n  const auto otherwise_context =\n      static_cast<URITemplateRouter::Identifier>(header->otherwise_context);\n\n  if (header->node_count == 0 ||\n      header->node_count > (this->data_.size() - sizeof(RouterHeader)) /\n                               sizeof(SerializedNode)) {\n    return finalize_match(otherwise_context, 0, 0);\n  }\n\n  const auto *nodes = reinterpret_cast<const SerializedNode *>(\n      this->data_.data() + sizeof(RouterHeader));\n  const auto nodes_size =\n      static_cast<std::size_t>(header->node_count) * sizeof(SerializedNode);\n  const auto expected_string_table_offset = sizeof(RouterHeader) + nodes_size;\n  if (header->string_table_offset < expected_string_table_offset ||\n      header->string_table_offset > this->data_.size()) {\n    return finalize_match(otherwise_context, 0, 0);\n  }\n\n  if (header->arguments_offset < header->string_table_offset ||\n      header->arguments_offset > this->data_.size()) {\n    return finalize_match(otherwise_context, 0, 0);\n  }\n\n  const auto *string_table = reinterpret_cast<const char *>(\n      this->data_.data() + header->string_table_offset);\n  const auto string_table_size =\n      header->arguments_offset - header->string_table_offset;\n\n  // Empty path matches empty template\n  if (path.empty()) {\n    return finalize_match(otherwise_context, nodes[0].identifier,\n                          nodes[0].context);\n  }\n\n  // Root path \"/\" is stored as an empty literal segment\n  if (path.size() == 1 && path[0] == '/') {\n    const auto &root = nodes[0];\n    if (root.first_literal_child == NO_CHILD) {\n      return finalize_match(otherwise_context, 0, 0);\n    }\n\n    if (root.first_literal_child >= header->node_count ||\n        root.literal_child_count >\n            header->node_count - root.first_literal_child) {\n      return finalize_match(otherwise_context, 0, 0);\n    }\n\n    const auto match = binary_search_literal_children(\n        nodes, string_table, string_table_size, root.first_literal_child,\n        root.literal_child_count, \"\", 0);\n    if (match == NO_CHILD) {\n      return finalize_match(otherwise_context, 0, 0);\n    }\n    return finalize_match(otherwise_context, nodes[match].identifier,\n                          nodes[match].context);\n  }\n\n  // Walk the trie, matching each path segment\n  std::uint32_t current_node = 0;\n  const char *position = path.data();\n  const char *const path_end = position + path.size();\n\n  std::size_t variable_index = 0;\n\n  // Skip leading slash\n  if (position < path_end && *position == '/') {\n    ++position;\n  }\n\n  while (true) {\n    // Extract segment\n    const char *segment_start = position;\n    while (position < path_end && *position != '/') {\n      ++position;\n    }\n\n    const auto segment_length =\n        static_cast<std::uint32_t>(position - segment_start);\n\n    // Empty segment (from double slash or trailing slash) doesn't match\n    if (segment_length == 0) {\n      return finalize_match(otherwise_context, 0, 0);\n    }\n\n    const auto &node = nodes[current_node];\n    const auto node_count = header->node_count;\n\n    // Try literal children first\n    if (node.first_literal_child != NO_CHILD) {\n      if (node.first_literal_child >= node_count ||\n          node.literal_child_count > node_count - node.first_literal_child) {\n        return finalize_match(otherwise_context, 0, 0);\n      }\n\n      const auto literal_match = binary_search_literal_children(\n          nodes, string_table, string_table_size, node.first_literal_child,\n          node.literal_child_count, segment_start, segment_length);\n      if (literal_match != NO_CHILD) {\n        current_node = literal_match;\n        if (position >= path_end) {\n          break;\n        }\n        ++position;\n        continue;\n      }\n    }\n\n    // Fall back to variable child\n    if (node.variable_child != NO_CHILD) {\n      if (node.variable_child >= node_count ||\n          variable_index >\n              std::numeric_limits<URITemplateRouter::Index>::max()) {\n        return finalize_match(otherwise_context, 0, 0);\n      }\n\n      const auto &variable_node = nodes[node.variable_child];\n\n      if (variable_node.string_offset > string_table_size ||\n          variable_node.string_length >\n              string_table_size - variable_node.string_offset) {\n        return finalize_match(otherwise_context, 0, 0);\n      }\n\n      // Check if this is an expansion (catch-all)\n      if (variable_node.type == URITemplateRouter::NodeType::Expansion) {\n        const auto remaining_length =\n            static_cast<std::uint32_t>(path_end - segment_start);\n        callback(static_cast<URITemplateRouter::Index>(variable_index),\n                 {string_table + variable_node.string_offset,\n                  variable_node.string_length},\n                 {segment_start, remaining_length});\n        return finalize_match(otherwise_context, variable_node.identifier,\n                              variable_node.context);\n      }\n\n      // Regular variable - match single segment\n      callback(static_cast<URITemplateRouter::Index>(variable_index),\n               {string_table + variable_node.string_offset,\n                variable_node.string_length},\n               {segment_start, segment_length});\n      ++variable_index;\n      current_node = node.variable_child;\n      if (position >= path_end) {\n        break;\n      }\n      ++position;\n      continue;\n    }\n\n    // No match\n    return finalize_match(otherwise_context, 0, 0);\n  }\n\n  return finalize_match(otherwise_context, nodes[current_node].identifier,\n                        nodes[current_node].context);\n}\n\nauto URITemplateRouterView::arguments(\n    const URITemplateRouter::Identifier identifier,\n    const URITemplateRouter::ArgumentCallback &callback) const -> void {\n  if (this->data_.size() < sizeof(RouterHeader)) {\n    return;\n  }\n\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  if (header->magic != ROUTER_MAGIC || header->version != ROUTER_VERSION) {\n    return;\n  }\n\n  const auto arguments_start =\n      static_cast<std::size_t>(header->arguments_offset);\n  const auto data_size = this->data_.size();\n  if (arguments_start >= data_size) {\n    return;\n  }\n\n  const auto section_size = data_size - arguments_start;\n  if (section_size < sizeof(std::uint16_t)) {\n    return;\n  }\n\n  std::uint16_t entry_count = 0;\n  std::memcpy(&entry_count, this->data_.data() + arguments_start,\n              sizeof(entry_count));\n  if (entry_count == 0) {\n    return;\n  }\n\n  constexpr std::size_t ENTRY_SIZE =\n      sizeof(std::uint16_t) + sizeof(std::uint32_t) + sizeof(std::uint32_t);\n  const auto entries_offset = arguments_start + sizeof(entry_count);\n  const auto entries_size = static_cast<std::size_t>(entry_count) * ENTRY_SIZE;\n  if (entries_size > data_size - entries_offset) {\n    return;\n  }\n\n  const auto blob_area_offset = entries_offset + entries_size;\n\n  for (std::uint16_t index = 0; index < entry_count; ++index) {\n    const auto entry_offset = entries_offset + index * ENTRY_SIZE;\n\n    std::uint16_t entry_identifier = 0;\n    std::memcpy(&entry_identifier, this->data_.data() + entry_offset,\n                sizeof(entry_identifier));\n    if (entry_identifier != identifier) {\n      continue;\n    }\n\n    std::uint32_t blob_offset = 0;\n    std::uint32_t blob_length = 0;\n    std::memcpy(&blob_offset,\n                this->data_.data() + entry_offset + sizeof(std::uint16_t),\n                sizeof(blob_offset));\n    std::memcpy(&blob_length,\n                this->data_.data() + entry_offset + sizeof(std::uint16_t) +\n                    sizeof(std::uint32_t),\n                sizeof(blob_length));\n\n    const auto blob_abs_offset = blob_area_offset + blob_offset;\n    if (blob_offset > data_size - blob_area_offset ||\n        blob_length > data_size - blob_abs_offset ||\n        blob_length < sizeof(std::uint16_t)) {\n      return;\n    }\n\n    std::uint16_t arg_count = 0;\n    std::memcpy(&arg_count, this->data_.data() + blob_abs_offset,\n                sizeof(arg_count));\n    auto cursor = blob_abs_offset + sizeof(arg_count);\n    const auto blob_end = blob_abs_offset + blob_length;\n\n    for (std::uint16_t arg_index = 0; arg_index < arg_count; ++arg_index) {\n      if (cursor + sizeof(std::uint16_t) > blob_end) {\n        return;\n      }\n\n      std::uint16_t key_length = 0;\n      std::memcpy(&key_length, this->data_.data() + cursor, sizeof(key_length));\n      cursor += sizeof(key_length);\n      if (key_length > blob_end - cursor) {\n        return;\n      }\n\n      const std::string_view name{\n          reinterpret_cast<const char *>(this->data_.data() + cursor),\n          key_length};\n      cursor += key_length;\n\n      if (cursor + sizeof(std::uint8_t) + sizeof(std::uint16_t) > blob_end) {\n        return;\n      }\n\n      const auto type_tag = this->data_[cursor];\n      cursor += sizeof(std::uint8_t);\n      std::uint16_t value_length = 0;\n      std::memcpy(&value_length, this->data_.data() + cursor,\n                  sizeof(value_length));\n      cursor += sizeof(value_length);\n      if (value_length > blob_end - cursor) {\n        return;\n      }\n\n      switch (type_tag) {\n        case ARGUMENT_TYPE_STRING: {\n          const std::string_view string_value{\n              reinterpret_cast<const char *>(this->data_.data() + cursor),\n              value_length};\n          callback(name, string_value);\n          break;\n        }\n\n        case ARGUMENT_TYPE_INTEGER: {\n          if (value_length != 8) {\n            return;\n          }\n\n          std::int64_t integer_value = 0;\n          std::memcpy(&integer_value, this->data_.data() + cursor, 8);\n          callback(name, integer_value);\n          break;\n        }\n\n        case ARGUMENT_TYPE_BOOLEAN: {\n          if (value_length != 1) {\n            return;\n          }\n\n          callback(name, this->data_[cursor] != 0);\n          break;\n        }\n\n        default:\n          return;\n      }\n\n      cursor += value_length;\n    }\n\n    return;\n  }\n}\n\nauto URITemplateRouterView::base_path() const noexcept -> std::string_view {\n  if (this->data_.size() < sizeof(RouterHeader)) {\n    return {};\n  }\n\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  if (header->magic != ROUTER_MAGIC || header->version != ROUTER_VERSION) {\n    return {};\n  }\n\n  if (header->base_path_length == 0) {\n    return {};\n  }\n\n  if (header->string_table_offset > this->data_.size() ||\n      header->arguments_offset < header->string_table_offset ||\n      header->arguments_offset > this->data_.size()) {\n    return {};\n  }\n\n  const auto *string_table = reinterpret_cast<const char *>(\n      this->data_.data() + header->string_table_offset);\n  const auto string_table_size =\n      header->arguments_offset - header->string_table_offset;\n  if (header->base_path_offset > string_table_size ||\n      header->base_path_length > string_table_size - header->base_path_offset) {\n    return {};\n  }\n\n  return {string_table + header->base_path_offset, header->base_path_length};\n}\n\nauto URITemplateRouterView::size() const noexcept -> std::size_t {\n  if (this->data_.size() < sizeof(RouterHeader)) {\n    return 0;\n  }\n\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  if (header->magic != ROUTER_MAGIC || header->version != ROUTER_VERSION) {\n    return 0;\n  }\n\n  if (header->node_count == 0 ||\n      header->node_count > (this->data_.size() - sizeof(RouterHeader)) /\n                               sizeof(SerializedNode)) {\n    return 0;\n  }\n\n  const auto *nodes = reinterpret_cast<const SerializedNode *>(\n      this->data_.data() + sizeof(RouterHeader));\n\n  std::size_t count = 0;\n  for (std::uint32_t index = 0; index < header->node_count; ++index) {\n    if (nodes[index].identifier != 0) {\n      count += 1;\n    }\n  }\n\n  return count;\n}\n\nauto URITemplateRouterView::at(const std::size_t index) const\n    -> URITemplateRouter::Identifier {\n  assert(this->data_.size() >= sizeof(RouterHeader));\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  assert(header->magic == ROUTER_MAGIC && header->version == ROUTER_VERSION);\n  assert(header->node_count > 0 &&\n         header->node_count <= (this->data_.size() - sizeof(RouterHeader)) /\n                                   sizeof(SerializedNode));\n\n  const auto *nodes = reinterpret_cast<const SerializedNode *>(\n      this->data_.data() + sizeof(RouterHeader));\n\n  std::size_t count = 0;\n  for (std::uint32_t node_index = 0; node_index < header->node_count;\n       ++node_index) {\n    if (nodes[node_index].identifier != 0) {\n      if (count == index) {\n        return nodes[node_index].identifier;\n      }\n      ++count;\n    }\n  }\n\n  assert(false);\n  return 0;\n}\n\nauto URITemplateRouterView::context(\n    const URITemplateRouter::Identifier identifier) const\n    -> URITemplateRouter::Identifier {\n  assert(identifier > 0);\n  assert(this->data_.size() >= sizeof(RouterHeader));\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  assert(header->magic == ROUTER_MAGIC && header->version == ROUTER_VERSION);\n  assert(header->node_count > 0 &&\n         header->node_count <= (this->data_.size() - sizeof(RouterHeader)) /\n                                   sizeof(SerializedNode));\n\n  const auto *nodes = reinterpret_cast<const SerializedNode *>(\n      this->data_.data() + sizeof(RouterHeader));\n\n  for (std::uint32_t node_index = 0; node_index < header->node_count;\n       ++node_index) {\n    if (nodes[node_index].identifier == identifier) {\n      return nodes[node_index].context;\n    }\n  }\n\n  assert(false);\n  return 0;\n}\n\nauto URITemplateRouterView::path(\n    const URITemplateRouter::Identifier identifier) const -> std::string {\n  assert(identifier > 0);\n  assert(this->data_.size() >= sizeof(RouterHeader));\n  const auto *header =\n      reinterpret_cast<const RouterHeader *>(this->data_.data());\n  assert(header->magic == ROUTER_MAGIC && header->version == ROUTER_VERSION);\n  assert(header->node_count > 0 &&\n         header->node_count <= (this->data_.size() - sizeof(RouterHeader)) /\n                                   sizeof(SerializedNode));\n  assert(header->string_table_offset >=\n             sizeof(RouterHeader) +\n                 header->node_count * sizeof(SerializedNode) &&\n         header->string_table_offset <= this->data_.size());\n  assert(header->arguments_offset >= header->string_table_offset &&\n         header->arguments_offset <= this->data_.size());\n\n  const auto *nodes = reinterpret_cast<const SerializedNode *>(\n      this->data_.data() + sizeof(RouterHeader));\n  const auto *string_table = reinterpret_cast<const char *>(\n      this->data_.data() + header->string_table_offset);\n  const auto string_table_size =\n      header->arguments_offset - header->string_table_offset;\n\n  const auto base_path_depth = count_base_path_segments(this->base_path());\n\n  std::string accumulator;\n  [[maybe_unused]] const auto found = reconstruct_path_recursive(\n      nodes, header->node_count, string_table, string_table_size, 0, 0,\n      base_path_depth, identifier, accumulator);\n\n  assert(found);\n  return accumulator;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/core/yaml/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME yaml\n  PRIVATE_HEADERS error.h roundtrip.h\n  SOURCES yaml.cc lexer.h parser.h stringify.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME yaml)\nendif()\n\ntarget_link_libraries(sourcemeta_core_yaml PUBLIC sourcemeta::core::json)\ntarget_link_libraries(sourcemeta_core_yaml PUBLIC sourcemeta::core::jsonpointer)\ntarget_link_libraries(sourcemeta_core_yaml PRIVATE sourcemeta::core::io)\ntarget_link_libraries(sourcemeta_core_yaml PRIVATE sourcemeta::core::unicode)\n"
  },
  {
    "path": "vendor/core/src/core/yaml/include/sourcemeta/core/yaml.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_H_\n#define SOURCEMETA_CORE_YAML_H_\n\n#ifndef SOURCEMETA_CORE_YAML_EXPORT\n#include <sourcemeta/core/yaml_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/yaml_error.h>\n#include <sourcemeta/core/yaml_roundtrip.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <filesystem> // std::filesystem\n#include <istream>    // std::basic_istream\n#include <ostream>    // std::basic_ostream\n\n/// @defgroup yaml YAML\n/// @brief A YAML parser that converts YAML to JSON.\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/yaml.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup yaml\n///\n/// Create a JSON document from a C++ standard input stream that represents a\n/// YAML document. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <cassert>\n/// #include <sstream>\n///\n/// std::istringstream stream{\"foo: bar\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_yaml(stream);\n/// assert(document.is_object());\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(std::basic_istream<JSON::Char, JSON::CharTraits> &stream)\n    -> JSON;\n\n/// @ingroup yaml\n///\n/// Create a JSON document from a C++ standard input stream that represents a\n/// YAML document. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// #include <iostream>\n///\n/// const std::string input{\"hello: world\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_yaml(input);\n/// sourcemeta::core::prettify(document, std::cerr);\n/// std::cerr << \"\\n\";\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(const JSON::String &input) -> JSON;\n\n/// @ingroup yaml\n///\n/// Read a JSON document from a file location that represents a YAML file. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// #include <iostream>\n/// #include <filesystem>\n///\n/// const std::filesystem::path path{\"test.yaml\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::read_yaml(path);\n/// sourcemeta::core::prettify(document, std::cerr);\n/// std::cerr << \"\\n\";\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto read_yaml(const std::filesystem::path &path) -> JSON;\n\n/// @ingroup yaml\n///\n/// Parse a YAML document from a C++ standard input stream into an existing\n/// JSON value, invoking the given callback during parsing. The result is\n/// constructed directly into the given reference rather than returned by value\n/// to ensure that references passed through the parse callback remain valid\n/// after parsing completes.\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                JSON &output, const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup yaml\n///\n/// Parse a YAML string into an existing JSON value, invoking the given\n/// callback during parsing. The result is constructed directly into the given\n/// reference rather than returned by value to ensure that references passed\n/// through the parse callback remain valid after parsing completes.\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(const JSON::String &input, JSON &output,\n                const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup yaml\n///\n/// Read a YAML file into an existing JSON value, invoking the given callback\n/// during parsing. The result is constructed directly into the given reference\n/// rather than returned by value to ensure that references passed through the\n/// parse callback remain valid after parsing completes.\nSOURCEMETA_CORE_YAML_EXPORT\nauto read_yaml(const std::filesystem::path &path, JSON &output,\n               const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup yaml\n///\n/// Read a JSON document from a file location that represents a YAML file or a\n/// JSON file. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// #include <iostream>\n/// #include <filesystem>\n///\n/// const std::filesystem::path path{\"test.yaml\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::read_yaml_or_json(path);\n/// sourcemeta::core::prettify(document, std::cerr);\n/// std::cerr << \"\\n\";\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto read_yaml_or_json(const std::filesystem::path &path) -> JSON;\n\n/// @ingroup yaml\n///\n/// Read a JSON document from a file that represents YAML or JSON, constructing\n/// into the given reference and invoking the callback during parsing. The\n/// result is constructed directly into the given reference rather than returned\n/// by value to ensure that references passed through the parse callback (such\n/// as object property names) remain valid after parsing completes.\nSOURCEMETA_CORE_YAML_EXPORT\nauto read_yaml_or_json(const std::filesystem::path &path, JSON &output,\n                       const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup yaml\n///\n/// Create a JSON document from a YAML string, collecting round-trip metadata\n/// to reproduce the original formatting. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// sourcemeta::core::YAMLRoundTrip roundtrip;\n/// const std::string input{\"hello: world\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_yaml(input, roundtrip);\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(const JSON::String &input, YAMLRoundTrip &roundtrip) -> JSON;\n\n/// @ingroup yaml\n///\n/// Parse a YAML string with round-trip metadata into an existing JSON value,\n/// invoking the given callback during parsing. The result is constructed\n/// directly into the given reference rather than returned by value to ensure\n/// that references passed through the parse callback remain valid after\n/// parsing completes.\nSOURCEMETA_CORE_YAML_EXPORT\nauto parse_yaml(const JSON::String &input, YAMLRoundTrip &roundtrip,\n                JSON &output, const JSON::ParseCallback &callback) -> void;\n\n/// @ingroup yaml\n///\n/// Stringify a JSON document as YAML, using round-trip metadata collected\n/// during parsing to preserve the original formatting. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// #include <iostream>\n///\n/// sourcemeta::core::YAMLRoundTrip roundtrip;\n/// const std::string input{\"hello: world\"};\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_yaml(input, roundtrip);\n/// sourcemeta::core::stringify_yaml(document, std::cout, roundtrip);\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto stringify_yaml(const JSON &document,\n                    std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                    const YAMLRoundTrip &roundtrip) -> void;\n\n/// @ingroup yaml\n///\n/// Stringify a JSON document as YAML. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/yaml.h>\n///\n/// #include <iostream>\n///\n/// const sourcemeta::core::JSON document =\n///   sourcemeta::core::parse_json(R\"JSON({ \"foo\": \"bar\" })JSON\");\n/// sourcemeta::core::stringify_yaml(document, std::cout);\n/// ```\nSOURCEMETA_CORE_YAML_EXPORT\nauto stringify_yaml(const JSON &document,\n                    std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/include/sourcemeta/core/yaml_error.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_ERROR_H_\n#define SOURCEMETA_CORE_YAML_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_YAML_EXPORT\n#include <sourcemeta/core/yaml_export.h>\n#endif\n\n#include <cstdint>     // std::uint64_t\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup yaml\n/// An error that represents a general YAML error event\nclass SOURCEMETA_CORE_YAML_EXPORT YAMLError : public std::exception {\npublic:\n  YAMLError(const char *message) : message_{message} {}\n  YAMLError(std::string message) = delete;\n  YAMLError(std::string &&message) = delete;\n  YAMLError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n/// @ingroup yaml\n/// An error that represents a YAML parse error event\nclass SOURCEMETA_CORE_YAML_EXPORT YAMLParseError : public std::exception {\npublic:\n  YAMLParseError(const std::uint64_t line, const std::uint64_t column)\n      : line_{line}, column_{column},\n        message_{\"Failed to parse the YAML document\"} {}\n\n  YAMLParseError(const std::uint64_t line, const std::uint64_t column,\n                 const char *message)\n      : line_{line}, column_{column}, message_{message} {}\n  YAMLParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string message) = delete;\n  YAMLParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string &&message) = delete;\n  YAMLParseError(const std::uint64_t line, const std::uint64_t column,\n                 std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto line() const noexcept -> std::uint64_t {\n    return this->line_;\n  }\n\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    return this->column_;\n  }\n\nprivate:\n  std::uint64_t line_;\n  std::uint64_t column_;\n  const char *message_;\n};\n\n/// @ingroup yaml\n/// An error that represents an unknown anchor reference in YAML\nclass SOURCEMETA_CORE_YAML_EXPORT YAMLUnknownAnchorError\n    : public YAMLParseError {\npublic:\n  YAMLUnknownAnchorError(const std::string_view anchor_name,\n                         const std::uint64_t line, const std::uint64_t column)\n      : YAMLParseError{line, column, \"YAML alias references undefined anchor\"},\n        anchor_name_{anchor_name} {}\n\n  [[nodiscard]] auto anchor() const noexcept -> std::string_view {\n    return this->anchor_name_;\n  }\n\nprivate:\n  std::string anchor_name_;\n};\n\n/// @ingroup yaml\n/// An error that represents a duplicate key in a YAML mapping\n/// YAML 1.2.2 requires unique keys in mappings, unlike JSON where duplicate\n/// keys are undefined behavior. See https://yaml.org/spec/1.2.2/#mapping\nclass SOURCEMETA_CORE_YAML_EXPORT YAMLDuplicateKeyError\n    : public YAMLParseError {\npublic:\n  YAMLDuplicateKeyError(const std::string_view key_name,\n                        const std::uint64_t line, const std::uint64_t column)\n      : YAMLParseError{line, column, \"Duplicate key in YAML mapping\"},\n        key_name_{key_name} {}\n\n  [[nodiscard]] auto key() const noexcept -> std::string_view {\n    return this->key_name_;\n  }\n\nprivate:\n  std::string key_name_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/include/sourcemeta/core/yaml_roundtrip.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_ROUNDTRIP_H_\n#define SOURCEMETA_CORE_YAML_ROUNDTRIP_H_\n\n#ifndef SOURCEMETA_CORE_YAML_EXPORT\n#include <sourcemeta/core/yaml_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n\n#include <cstdint>       // std::uint8_t, std::size_t\n#include <optional>      // std::optional\n#include <string>        // std::string\n#include <unordered_map> // std::unordered_map\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup yaml\n/// Holds per-node metadata collected during YAML parsing to reproduce the\n/// original formatting\nclass SOURCEMETA_CORE_YAML_EXPORT YAMLRoundTrip {\npublic:\n  enum class ScalarStyle : std::uint8_t {\n    Plain,\n    SingleQuoted,\n    DoubleQuoted,\n    Literal,\n    Folded\n  };\n\n  enum class CollectionStyle : std::uint8_t { Block, Flow };\n\n  enum class Chomping : std::uint8_t { Clip, Strip, Keep };\n\n  struct NodeStyle {\n    std::optional<ScalarStyle> scalar;\n    std::optional<CollectionStyle> collection;\n    std::optional<Chomping> chomping;\n    std::size_t explicit_indent{0};\n    bool indent_before_chomping{false};\n    std::optional<std::string> block_content;\n    std::optional<std::string> plain_content;\n    std::optional<std::string> quoted_content;\n    std::optional<std::string> anchor;\n    std::vector<std::string> comments_before;\n    std::optional<std::string> comment_inline;\n    std::optional<std::string> comment_on_indicator;\n    bool compact_flow{false};\n  };\n\n  std::unordered_map<Pointer, NodeStyle, Pointer::Hasher> styles;\n  std::unordered_map<Pointer, std::string, Pointer::Hasher> aliases;\n  std::unordered_map<Pointer, ScalarStyle, Pointer::Hasher> key_styles;\n  std::unordered_map<Pointer, std::string, Pointer::Hasher> key_quoted_contents;\n  bool explicit_document_start{false};\n  bool explicit_document_end{false};\n  std::optional<std::string> document_start_comment;\n  std::optional<std::string> document_end_comment;\n  std::vector<std::string> leading_comments;\n  std::vector<std::string> post_start_comments;\n  std::vector<std::string> pre_end_comments;\n  std::vector<std::string> trailing_comments;\n  std::size_t indent_width{2};\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/lexer.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_LEXER_H_\n#define SOURCEMETA_CORE_YAML_LEXER_H_\n\n#include <sourcemeta/core/unicode.h>\n#include <sourcemeta/core/yaml_error.h>\n\n#include <charconv>     // std::from_chars\n#include <cstdint>      // std::uint8_t, std::uint64_t\n#include <deque>        // std::deque\n#include <optional>     // std::optional\n#include <string>       // std::string\n#include <string_view>  // std::string_view\n#include <system_error> // std::errc\n#include <vector>       // std::vector\n\nnamespace sourcemeta::core::yaml {\n\nenum class TokenType : std::uint8_t {\n  StreamStart,\n  StreamEnd,\n  DocumentStart,\n  DocumentEnd,\n  MappingStart,\n  MappingEnd,\n  SequenceStart,\n  SequenceEnd,\n  BlockMappingKey,\n  BlockMappingValue,\n  BlockSequenceEntry,\n  FlowEntry,\n  Scalar,\n  Anchor,\n  Alias,\n  Tag,\n  DirectiveYAML,\n  DirectiveTag,\n  DirectiveReserved\n};\n\nenum class ScalarStyle : std::uint8_t {\n  Plain,\n  SingleQuoted,\n  DoubleQuoted,\n  Literal,\n  Folded\n};\n\nenum class BlockChomping : std::uint8_t { Clip, Strip, Keep };\n\nstruct Token {\n  TokenType type;\n  std::string_view value;\n  std::uint64_t line;\n  std::uint64_t column;\n  std::size_t position{0};\n  ScalarStyle scalar_style{ScalarStyle::Plain};\n  BlockChomping chomping{BlockChomping::Clip};\n  bool multiline{false};\n  std::string_view block_original{};\n  std::string_view quoted_original{};\n  std::size_t explicit_indent{0};\n  bool indent_before_chomping{false};\n  bool compact_separator{false};\n};\n\nclass Lexer {\npublic:\n  Lexer(const std::string_view input, const bool roundtrip_mode = false)\n      : input_{input}, roundtrip_{roundtrip_mode} {}\n\n  auto next() -> std::optional<Token> {\n    if (this->roundtrip_) {\n      this->inline_comment_buffer_.reset();\n    }\n    this->skip_whitespace_and_comments();\n    if (this->roundtrip_) {\n      this->comment_reference_line_ = this->line_;\n    }\n\n    if (this->position_ >= this->input_.size()) {\n      if (!this->stream_started_) {\n        this->stream_started_ = true;\n        return Token{.type = TokenType::StreamStart,\n                     .value = {},\n                     .line = this->line_,\n                     .column = this->column_};\n      }\n      if (!this->stream_ended_) {\n        this->stream_ended_ = true;\n        const auto end_line{this->column_ > 0 ? this->line_ + 1 : this->line_};\n        const std::uint64_t end_column{0};\n        return Token{.type = TokenType::StreamEnd,\n                     .value = {},\n                     .line = end_line,\n                     .column = end_column};\n      }\n      return std::nullopt;\n    }\n\n    if (!this->stream_started_) {\n      this->stream_started_ = true;\n      return Token{.type = TokenType::StreamStart,\n                   .value = {},\n                   .line = this->line_,\n                   .column = this->column_};\n    }\n\n    const auto current_line{this->line_};\n    const auto current_column{this->column_};\n    const auto current_position{this->position_};\n\n    if (this->tab_at_line_start_) {\n      this->tab_at_line_start_ = false;\n      const char next_char{this->peek()};\n      if (next_char != '{' && next_char != '[') [[unlikely]] {\n        throw YAMLParseError{current_line, current_column,\n                             \"Tab characters cannot be used for indentation\"};\n      }\n    }\n\n    if (this->column_ == 1 && this->check_document_marker('-')) {\n      this->advance(3);\n      return Token{.type = TokenType::DocumentStart,\n                   .value = \"---\",\n                   .line = current_line,\n                   .column = current_column,\n                   .position = current_position};\n    }\n\n    if (this->column_ == 1 && this->check_document_marker('.')) {\n      this->advance(3);\n      this->validate_trailing_content();\n      return Token{.type = TokenType::DocumentEnd,\n                   .value = \"...\",\n                   .line = current_line,\n                   .column = current_column,\n                   .position = current_position};\n    }\n\n    const char current{this->peek()};\n\n    if (current == '{') {\n      this->advance(1);\n      this->flow_level_++;\n      return Token{.type = TokenType::MappingStart,\n                   .value = \"{\",\n                   .line = current_line,\n                   .column = current_column};\n    }\n\n    if (current == '[') {\n      this->advance(1);\n      this->flow_level_++;\n      return Token{.type = TokenType::SequenceStart,\n                   .value = \"[\",\n                   .line = current_line,\n                   .column = current_column};\n    }\n\n    if (this->flow_level_ > 0) {\n      if (current == '}') {\n        this->advance(1);\n        this->flow_level_--;\n        if (this->flow_level_ == 0) {\n          this->validate_trailing_content();\n        }\n        return Token{.type = TokenType::MappingEnd,\n                     .value = \"}\",\n                     .line = current_line,\n                     .column = current_column};\n      }\n      if (current == ']') {\n        this->advance(1);\n        this->flow_level_--;\n        if (this->flow_level_ == 0) {\n          this->validate_trailing_content();\n        }\n        return Token{.type = TokenType::SequenceEnd,\n                     .value = \"]\",\n                     .line = current_line,\n                     .column = current_column};\n      }\n      if (current == ',') {\n        this->advance(1);\n        const bool compact{this->roundtrip_ &&\n                           this->position_ < this->input_.size() &&\n                           this->peek() != ' ' && this->peek() != '\\n' &&\n                           this->peek() != '\\r'};\n        return Token{.type = TokenType::FlowEntry,\n                     .value = \",\",\n                     .line = current_line,\n                     .column = current_column,\n                     .compact_separator = compact};\n      }\n    } else if (current == '-' && this->is_followed_by_whitespace()) {\n      this->advance(1);\n      return Token{.type = TokenType::BlockSequenceEntry,\n                   .value = \"-\",\n                   .line = current_line,\n                   .column = current_column};\n    }\n\n    if (current == '?' && this->is_followed_by_whitespace()) {\n      this->advance(1);\n      return Token{.type = TokenType::BlockMappingKey,\n                   .value = \"?\",\n                   .line = current_line,\n                   .column = current_column};\n    }\n\n    if (current == ':' && this->is_value_indicator()) {\n      this->advance(1);\n      this->last_was_quoted_scalar_ = false;\n      return Token{.type = TokenType::BlockMappingValue,\n                   .value = \":\",\n                   .line = current_line,\n                   .column = current_column};\n    }\n\n    if (current == '&') {\n      return this->scan_anchor_or_alias(TokenType::Anchor);\n    }\n\n    if (current == '*') {\n      return this->scan_anchor_or_alias(TokenType::Alias);\n    }\n\n    if (current == '!') {\n      return this->scan_tag();\n    }\n\n    if (current == '%') {\n      return this->scan_directive();\n    }\n\n    if (current == '\\'') {\n      this->last_was_quoted_scalar_ = true;\n      return this->scan_single_quoted_scalar();\n    }\n\n    if (current == '\"') {\n      this->last_was_quoted_scalar_ = true;\n      return this->scan_double_quoted_scalar();\n    }\n\n    if (current == '|') {\n      this->last_was_quoted_scalar_ = false;\n      return this->scan_block_scalar(ScalarStyle::Literal);\n    }\n\n    if (current == '>') {\n      this->last_was_quoted_scalar_ = false;\n      return this->scan_block_scalar(ScalarStyle::Folded);\n    }\n\n    if (current == '#') [[unlikely]] {\n      throw YAMLParseError{current_line, current_column,\n                           \"Unexpected '#' character\"};\n    }\n\n    this->last_was_quoted_scalar_ = false;\n    return this->scan_plain_scalar();\n  }\n\npublic:\n  [[nodiscard]] auto line() const noexcept -> std::uint64_t {\n    if (this->position_ >= this->input_.size() && this->column_ > 1) {\n      return this->line_ + 1;\n    }\n    return this->line_;\n  }\n\n  [[nodiscard]] auto column() const noexcept -> std::uint64_t {\n    if (this->position_ >= this->input_.size()) {\n      return 0;\n    }\n    return this->column_;\n  }\n\n  [[nodiscard]] auto flow_level() const noexcept -> std::size_t {\n    return this->flow_level_;\n  }\n\n  auto set_block_indent(const std::size_t indent) noexcept -> void {\n    this->block_indent_ = indent;\n  }\n\n  [[nodiscard]] auto block_indent() const noexcept -> std::size_t {\n    return this->block_indent_;\n  }\n\n  [[nodiscard]] auto position() const noexcept -> std::size_t {\n    return this->position_;\n  }\n\n  auto take_inline_comment() -> std::optional<std::string> {\n    auto result{std::move(this->inline_comment_buffer_)};\n    this->inline_comment_buffer_.reset();\n    return result;\n  }\n\n  auto take_preceding_comments() -> std::vector<std::string> {\n    auto result{std::move(this->preceding_comments_buffer_)};\n    this->preceding_comments_buffer_.clear();\n    return result;\n  }\n\n  auto take_block_scalar_comment() -> std::optional<std::string> {\n    auto result{std::move(this->block_scalar_comment_)};\n    this->block_scalar_comment_.reset();\n    return result;\n  }\n\nprivate:\n  [[nodiscard]] static auto is_whitespace(const char character) noexcept\n      -> bool {\n    return character == ' ' || character == '\\t' || character == '\\n' ||\n           character == '\\r';\n  }\n\n  [[nodiscard]] static auto is_flow_indicator(const char character) noexcept\n      -> bool {\n    return character == ',' || character == '[' || character == ']' ||\n           character == '{' || character == '}';\n  }\n\n  [[nodiscard]] auto peek(const std::size_t offset = 0) const noexcept -> char {\n    const auto index{this->position_ + offset};\n    if (index >= this->input_.size()) {\n      return '\\0';\n    }\n    return this->input_[index];\n  }\n\n  auto advance(const std::size_t count) noexcept -> void {\n    for (std::size_t index = 0; index < count; ++index) {\n      if (this->position_ >= this->input_.size()) {\n        break;\n      }\n      if (this->input_[this->position_] == '\\n') {\n        this->line_++;\n        this->column_ = 1;\n      } else {\n        this->column_++;\n      }\n      this->position_++;\n    }\n  }\n\n  auto skip_whitespace_and_comments() -> void {\n    bool preceded_by_whitespace{\n        this->column_ == 1 ||\n        (this->position_ > 0 &&\n         is_whitespace(this->input_[this->position_ - 1]))};\n    bool at_line_start{this->column_ == 1};\n    bool blank_line{at_line_start};\n    this->tab_at_line_start_ = false;\n    while (this->position_ < this->input_.size()) {\n      const char current{this->peek()};\n\n      if (current == ' ') {\n        preceded_by_whitespace = true;\n        this->advance(1);\n        continue;\n      }\n\n      if (current == '\\t') {\n        if (this->flow_level_ == 0 && at_line_start) {\n          this->tab_at_line_start_ = true;\n        }\n        preceded_by_whitespace = true;\n        this->advance(1);\n        continue;\n      }\n\n      if (current == '\\n' || current == '\\r') {\n        if (this->roundtrip_ && blank_line) {\n          this->preceding_comments_buffer_.emplace_back();\n        }\n        this->advance(1);\n        if (current == '\\r' && this->peek() == '\\n') {\n          this->advance(1);\n        }\n        preceded_by_whitespace = true;\n        at_line_start = true;\n        blank_line = true;\n        this->tab_at_line_start_ = false;\n        continue;\n      }\n\n      if (current == '#' && preceded_by_whitespace) {\n        blank_line = false;\n        const auto comment_line{this->line_};\n        const auto comment_start{this->position_};\n        while (this->position_ < this->input_.size() && this->peek() != '\\n') {\n          this->advance(1);\n        }\n        if (this->roundtrip_) {\n          std::string text{this->input_.substr(\n              comment_start, this->position_ - comment_start)};\n          if (comment_line == this->comment_reference_line_ &&\n              this->comment_reference_line_ > 0 &&\n              !this->inline_comment_buffer_.has_value()) {\n            this->inline_comment_buffer_ = std::move(text);\n          } else {\n            this->preceding_comments_buffer_.push_back(std::move(text));\n          }\n        }\n        continue;\n      }\n\n      break;\n    }\n  }\n\n  [[nodiscard]] auto check_document_marker(const char marker) const noexcept\n      -> bool {\n    if (this->position_ + 2 >= this->input_.size()) {\n      return false;\n    }\n    if (this->input_[this->position_] != marker ||\n        this->input_[this->position_ + 1] != marker ||\n        this->input_[this->position_ + 2] != marker) {\n      return false;\n    }\n    if (this->position_ + 3 < this->input_.size()) {\n      const char after{this->input_[this->position_ + 3]};\n      return is_whitespace(after) || after == '\\0';\n    }\n    return true;\n  }\n\n  [[nodiscard]] auto is_followed_by_whitespace() const noexcept -> bool {\n    if (this->position_ + 1 >= this->input_.size()) {\n      return true;\n    }\n    return is_whitespace(this->input_[this->position_ + 1]);\n  }\n\n  [[nodiscard]] auto is_value_indicator() const noexcept -> bool {\n    if (this->flow_level_ > 0) {\n      if (this->last_was_quoted_scalar_) {\n        return true;\n      }\n      if (this->position_ + 1 >= this->input_.size()) {\n        return true;\n      }\n      const char after{this->input_[this->position_ + 1]};\n      return is_whitespace(after) || is_flow_indicator(after);\n    }\n    return this->is_followed_by_whitespace();\n  }\n\n  [[nodiscard]] auto line_contains_mapping_key() const noexcept -> bool {\n    auto scan_position{this->position_};\n    while (scan_position < this->input_.size()) {\n      const char character{this->input_[scan_position]};\n      if (character == '\\n' || character == '\\r') {\n        return false;\n      }\n      if (character == ':') {\n        if (scan_position + 1 >= this->input_.size()) {\n          return true;\n        }\n        const char after{this->input_[scan_position + 1]};\n        if (is_whitespace(after)) {\n          return true;\n        }\n      }\n      scan_position++;\n    }\n    return false;\n  }\n\n  auto scan_anchor_or_alias(const TokenType type) -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto start_position{this->position_};\n    this->advance(1);\n    while (this->position_ < this->input_.size()) {\n      const char current{this->peek()};\n      if (is_whitespace(current) || is_flow_indicator(current)) {\n        break;\n      }\n      this->advance(1);\n    }\n    const auto length{this->position_ - start_position};\n    return Token{.type = type,\n                 .value = this->input_.substr(start_position + 1, length - 1),\n                 .line = start_line,\n                 .column = start_column};\n  }\n\n  auto scan_tag() -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto start_position{this->position_};\n\n    this->advance(1);\n\n    if (this->peek() == '<') {\n      this->advance(1);\n      while (this->position_ < this->input_.size() && this->peek() != '>') {\n        this->advance(1);\n      }\n      if (this->peek() == '>') {\n        this->advance(1);\n      }\n    } else {\n      while (this->position_ < this->input_.size()) {\n        const char current{this->peek()};\n        if (is_whitespace(current) || is_flow_indicator(current)) {\n          break;\n        }\n        this->advance(1);\n      }\n    }\n\n    const auto length{this->position_ - start_position};\n\n    if (this->position_ < this->input_.size() && this->flow_level_ == 0) {\n      const char after_tag{this->peek()};\n      if (after_tag == ',') [[unlikely]] {\n        throw YAMLParseError{this->line_, this->column_,\n                             \"Invalid character after tag in block context\"};\n      }\n    }\n\n    return Token{.type = TokenType::Tag,\n                 .value = this->input_.substr(start_position, length),\n                 .line = start_line,\n                 .column = start_column};\n  }\n\n  auto scan_directive() -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto start_position{this->position_};\n\n    this->advance(1);\n\n    while (this->position_ < this->input_.size() && this->peek() != '\\n' &&\n           this->peek() != '\\r') {\n      this->advance(1);\n    }\n\n    const auto length{this->position_ - start_position};\n    const auto directive_content{this->input_.substr(start_position, length)};\n\n    TokenType token_type{TokenType::DirectiveReserved};\n    if (directive_content.starts_with(\"%YAML\")) {\n      token_type = TokenType::DirectiveYAML;\n    } else if (directive_content.starts_with(\"%TAG\")) {\n      token_type = TokenType::DirectiveTag;\n    }\n\n    return Token{.type = token_type,\n                 .value = directive_content,\n                 .line = start_line,\n                 .column = start_column};\n  }\n\n  auto scan_single_quoted_scalar() -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto quote_start{this->position_};\n\n    this->advance(1);\n\n    auto &buffer{this->get_buffer()};\n    std::string line_content;\n    bool first_line{true};\n    std::size_t pending_newlines{0};\n    bool found_closing_quote{false};\n\n    while (this->position_ < this->input_.size()) {\n      const char current{this->peek()};\n\n      if (current == '\\'') {\n        if (this->peek(1) == '\\'') {\n          line_content += '\\'';\n          this->advance(2);\n        } else {\n          this->flush_flow_line(buffer, line_content, pending_newlines,\n                                first_line, true);\n          this->advance(1);\n          found_closing_quote = true;\n          break;\n        }\n      } else if (current == '\\n' || current == '\\r') {\n        this->flush_flow_line(buffer, line_content, pending_newlines,\n                              first_line);\n        first_line = false;\n        this->skip_flow_scalar_line_break(current, pending_newlines);\n      } else {\n        line_content += current;\n        this->advance(1);\n      }\n    }\n\n    if (!found_closing_quote) [[unlikely]] {\n      throw YAMLParseError{start_line, start_column,\n                           \"Missing closing quote in single-quoted scalar\"};\n    }\n\n    this->validate_trailing_content();\n\n    const auto quoted_raw{\n        this->roundtrip_\n            ? this->input_.substr(quote_start + 1,\n                                  this->position_ - quote_start - 2)\n            : std::string_view{}};\n    return Token{.type = TokenType::Scalar,\n                 .value = buffer,\n                 .line = start_line,\n                 .column = start_column,\n                 .scalar_style = ScalarStyle::SingleQuoted,\n                 .multiline = !first_line,\n                 .quoted_original = quoted_raw};\n  }\n\n  auto flush_flow_line(std::string &buffer, std::string &line_content,\n                       std::size_t &pending_newlines, const bool first_line,\n                       const bool is_final = false) -> void {\n    if (!is_final) {\n      while (!line_content.empty() &&\n             (line_content.back() == ' ' || line_content.back() == '\\t')) {\n        line_content.pop_back();\n      }\n    }\n\n    if (pending_newlines > 0 && !first_line) {\n      if (pending_newlines == 1) {\n        buffer += ' ';\n      } else {\n        for (std::size_t count = 1; count < pending_newlines; ++count) {\n          buffer += '\\n';\n        }\n      }\n      pending_newlines = 0;\n    }\n\n    if (!line_content.empty()) {\n      buffer += line_content;\n    }\n    line_content.clear();\n  }\n\n  auto skip_flow_scalar_line_break(const char current,\n                                   std::size_t &pending_newlines) -> void {\n    this->advance(1);\n    if (current == '\\r' && this->peek() == '\\n') {\n      this->advance(1);\n    }\n    pending_newlines++;\n    while (this->position_ < this->input_.size()) {\n      const char character{this->peek()};\n      if (character == ' ' || character == '\\t') {\n        this->advance(1);\n      } else if (character == '\\n') {\n        pending_newlines++;\n        this->advance(1);\n      } else if (character == '\\r') {\n        pending_newlines++;\n        this->advance(1);\n        if (this->peek() == '\\n') {\n          this->advance(1);\n        }\n      } else {\n        break;\n      }\n    }\n    this->validate_flow_scalar_continuation();\n  }\n\n  auto validate_flow_scalar_continuation() -> void {\n    if (this->position_ >= this->input_.size()) {\n      return;\n    }\n    if (this->column_ == 1 && (this->check_document_marker('-') ||\n                               this->check_document_marker('.'))) [[unlikely]] {\n      throw YAMLParseError{this->line_, this->column_,\n                           \"Document marker inside flow scalar\"};\n    }\n    if (this->flow_level_ == 0 && this->block_indent_ != SIZE_MAX) {\n      const auto current_indent{static_cast<std::size_t>(this->column_ - 1)};\n      if (current_indent <= this->block_indent_) [[unlikely]] {\n        throw YAMLParseError{this->line_, this->column_,\n                             \"Insufficient indentation in flow scalar\"};\n      }\n    }\n  }\n\n  auto validate_trailing_content() -> void {\n    auto lookahead{this->position_};\n    bool seen_whitespace{false};\n    while (lookahead < this->input_.size()) {\n      const char character{this->input_[lookahead]};\n      if (character == ' ' || character == '\\t') {\n        seen_whitespace = true;\n        lookahead++;\n        continue;\n      }\n      if (character == '\\n' || character == '\\r') {\n        return;\n      }\n      if (character == '#') {\n        if (seen_whitespace) {\n          return;\n        }\n        throw YAMLParseError{this->line_, this->column_,\n                             \"Invalid trailing content\"};\n      }\n      if (character == ':') {\n        return;\n      }\n      if (this->flow_level_ > 0 && is_flow_indicator(character)) {\n        return;\n      }\n      throw YAMLParseError{this->line_, this->column_,\n                           \"Invalid trailing content\"};\n    }\n  }\n\n  auto scan_double_quoted_scalar() -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto quote_start{this->position_};\n\n    this->advance(1);\n\n    auto &buffer{this->get_buffer()};\n    std::string line_content;\n    bool first_line{true};\n    std::size_t pending_newlines{0};\n    bool found_closing_quote{false};\n\n    while (this->position_ < this->input_.size()) {\n      const char current{this->peek()};\n\n      if (current == '\"') {\n        this->flush_flow_line(buffer, line_content, pending_newlines,\n                              first_line, true);\n        this->advance(1);\n        found_closing_quote = true;\n        break;\n      }\n\n      if (current == '\\\\') {\n        this->advance(1);\n        if (this->position_ < this->input_.size()) {\n          const char escaped{this->peek()};\n          switch (escaped) {\n            case '0':\n              line_content += '\\0';\n              break;\n            case 'a':\n              line_content += '\\a';\n              break;\n            case 'b':\n              line_content += '\\b';\n              break;\n            case 't':\n            case '\\t':\n              line_content += '\\t';\n              break;\n            case 'n':\n              line_content += '\\n';\n              break;\n            case 'v':\n              line_content += '\\v';\n              break;\n            case 'f':\n              line_content += '\\f';\n              break;\n            case 'r':\n              line_content += '\\r';\n              break;\n            case 'e':\n              line_content += '\\x1b';\n              break;\n            case ' ':\n              line_content += ' ';\n              break;\n            case '\"':\n              line_content += '\"';\n              break;\n            case '/':\n              line_content += '/';\n              break;\n            case '\\\\':\n              line_content += '\\\\';\n              break;\n            case 'N':\n              line_content += \"\\xc2\\x85\";\n              break;\n            case '_':\n              line_content += \"\\xc2\\xa0\";\n              break;\n            case 'L':\n              line_content += \"\\xe2\\x80\\xa8\";\n              break;\n            case 'P':\n              line_content += \"\\xe2\\x80\\xa9\";\n              break;\n            case 'x':\n              this->advance(1);\n              line_content += this->parse_hex_escape(2);\n              continue;\n            case 'u':\n              this->advance(1);\n              line_content += this->parse_hex_escape(4);\n              continue;\n            case 'U':\n              this->advance(1);\n              line_content += this->parse_hex_escape(8);\n              continue;\n            case '\\n':\n            case '\\r':\n              if (escaped == '\\r' && this->peek(1) == '\\n') {\n                this->advance(1);\n              }\n              this->advance(1);\n              while (this->position_ < this->input_.size() &&\n                     (this->peek() == ' ' || this->peek() == '\\t')) {\n                this->advance(1);\n              }\n              continue;\n            default:\n              throw YAMLParseError{this->line_, this->column_,\n                                   \"Invalid escape sequence in \"\n                                   \"double-quoted scalar\"};\n          }\n          this->advance(1);\n        }\n      } else if (current == '\\n' || current == '\\r') {\n        this->flush_flow_line(buffer, line_content, pending_newlines,\n                              first_line);\n        first_line = false;\n        this->skip_flow_scalar_line_break(current, pending_newlines);\n      } else {\n        line_content += current;\n        this->advance(1);\n      }\n    }\n\n    if (!found_closing_quote) [[unlikely]] {\n      throw YAMLParseError{start_line, start_column,\n                           \"Missing closing quote in double-quoted scalar\"};\n    }\n\n    this->validate_trailing_content();\n\n    const auto quoted_raw{\n        this->roundtrip_\n            ? this->input_.substr(quote_start + 1,\n                                  this->position_ - quote_start - 2)\n            : std::string_view{}};\n    return Token{.type = TokenType::Scalar,\n                 .value = buffer,\n                 .line = start_line,\n                 .column = start_column,\n                 .scalar_style = ScalarStyle::DoubleQuoted,\n                 .multiline = !first_line,\n                 .quoted_original = quoted_raw};\n  }\n\n  auto parse_hex_escape(const std::size_t digits) -> std::string {\n    std::string hex;\n    for (std::size_t index = 0;\n         index < digits && this->position_ < this->input_.size(); ++index) {\n      hex += this->peek();\n      this->advance(1);\n    }\n\n    if (hex.size() != digits) [[unlikely]] {\n      throw YAMLParseError{this->line_, this->column_,\n                           \"Truncated hex escape sequence\"};\n    }\n\n    unsigned long codepoint{};\n    const auto result =\n        std::from_chars(hex.data(), hex.data() + hex.size(), codepoint, 16);\n    if (result.ec != std::errc{} || result.ptr != hex.data() + hex.size())\n        [[unlikely]] {\n      throw YAMLParseError{this->line_, this->column_,\n                           \"Invalid hex escape sequence\"};\n    }\n\n    return codepoint_to_utf8(static_cast<char32_t>(codepoint));\n  }\n\n  [[nodiscard]] auto calculate_parent_indentation(\n      const std::size_t indicator_position) const noexcept -> std::size_t {\n    std::size_t line_start{indicator_position};\n    while (line_start > 0 && this->input_[line_start - 1] != '\\n' &&\n           this->input_[line_start - 1] != '\\r') {\n      line_start--;\n    }\n\n    std::size_t leading_spaces{0};\n    std::size_t scan_position{line_start};\n    while (scan_position < this->input_.size() &&\n           this->input_[scan_position] == ' ') {\n      leading_spaces++;\n      scan_position++;\n    }\n\n    bool in_sequence_entry{false};\n    if (scan_position < this->input_.size() - 1 &&\n        this->input_[scan_position] == '-' &&\n        this->input_[scan_position + 1] == ' ') {\n      in_sequence_entry = true;\n    }\n\n    bool is_mapping_value_same_line{false};\n    for (std::size_t index = line_start; index < indicator_position; ++index) {\n      if (this->input_[index] == ':') {\n        is_mapping_value_same_line = true;\n        break;\n      }\n    }\n\n    if (in_sequence_entry && is_mapping_value_same_line) {\n      return leading_spaces + 2;\n    }\n\n    if (is_mapping_value_same_line) {\n      return leading_spaces;\n    }\n\n    return 0;\n  }\n\n  auto detect_block_scalar_indent(const std::size_t explicit_indent,\n                                  const std::size_t indicator_position,\n                                  const std::uint64_t start_line,\n                                  const std::uint64_t start_column)\n      -> std::size_t {\n    std::size_t content_indent{0};\n\n    if (explicit_indent > 0) {\n      const auto parent_indent{\n          this->calculate_parent_indentation(indicator_position)};\n      content_indent = parent_indent + explicit_indent;\n    } else {\n      const auto saved_position{this->position_};\n      const auto saved_line{this->line_};\n      const auto saved_column{this->column_};\n\n      std::size_t max_leading_empty_indent{0};\n      std::size_t current_empty_indent{0};\n      while (this->position_ < this->input_.size()) {\n        if (this->peek() == ' ') {\n          content_indent++;\n          current_empty_indent++;\n          this->advance(1);\n        } else if (this->peek() == '\\n' || this->peek() == '\\r') {\n          if (current_empty_indent > max_leading_empty_indent) {\n            max_leading_empty_indent = current_empty_indent;\n          }\n          content_indent = 0;\n          current_empty_indent = 0;\n          this->advance(1);\n        } else {\n          break;\n        }\n      }\n\n      this->position_ = saved_position;\n      this->line_ = saved_line;\n      this->column_ = saved_column;\n\n      if (max_leading_empty_indent > content_indent && content_indent > 0)\n          [[unlikely]] {\n        throw YAMLParseError{\n            start_line, start_column,\n            \"Leading empty line has more spaces than content indentation\"};\n      }\n    }\n\n    if (content_indent == 0 && start_column > 5) {\n      content_indent = 1;\n    }\n\n    return content_indent;\n  }\n\n  auto scan_block_scalar(const ScalarStyle style) -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto indicator_position{this->position_};\n\n    this->advance(1);\n\n    char chomping{'c'};\n    std::size_t explicit_indent{0};\n    bool indent_first{false};\n\n    bool seen_header_whitespace{false};\n    while (this->position_ < this->input_.size()) {\n      const char current{this->peek()};\n      if (current == '-') {\n        chomping = '-';\n        this->advance(1);\n      } else if (current == '+') {\n        chomping = '+';\n        this->advance(1);\n      } else if (current >= '1' && current <= '9') {\n        explicit_indent = static_cast<std::size_t>(current - '0');\n        if (chomping == 'c') {\n          indent_first = true;\n        }\n        this->advance(1);\n      } else if (current == ' ' || current == '\\t') {\n        seen_header_whitespace = true;\n        this->advance(1);\n      } else if (current == '#' && seen_header_whitespace) {\n        const auto comment_start{this->position_};\n        while (this->position_ < this->input_.size() && this->peek() != '\\n') {\n          this->advance(1);\n        }\n        if (this->roundtrip_) {\n          this->block_scalar_comment_ = std::string{this->input_.substr(\n              comment_start, this->position_ - comment_start)};\n        }\n      } else if (current == '\\n' || current == '\\r') {\n        break;\n      } else {\n        throw YAMLParseError{this->line_, this->column_,\n                             \"Invalid content in block scalar header\"};\n      }\n    }\n\n    if (this->peek() == '\\n' || this->peek() == '\\r') {\n      this->advance(1);\n      if (this->input_[this->position_ - 1] == '\\r' && this->peek() == '\\n') {\n        this->advance(1);\n      }\n    }\n\n    auto &buffer{this->get_buffer()};\n\n    // For folded scalars in roundtrip mode, build a parallel buffer that\n    // preserves original line breaks (literal-style) for round-trip output\n    const bool build_original{style == ScalarStyle::Folded && this->roundtrip_};\n    std::string *original{nullptr};\n    std::string original_trailing;\n    if (build_original) {\n      original = &this->get_buffer();\n    }\n\n    const auto content_indent{this->detect_block_scalar_indent(\n        explicit_indent, indicator_position, start_line, start_column)};\n\n    std::size_t blank_line_count{0};\n    bool previous_was_more_indented{false};\n    bool previous_started_with_whitespace{false};\n    bool had_line_break{false};\n    std::string trailing_newlines;\n\n    while (this->position_ < this->input_.size()) {\n      std::size_t line_indent{0};\n      while (this->position_ < this->input_.size() && this->peek() == ' ') {\n        line_indent++;\n        this->advance(1);\n      }\n\n      if (this->peek() == '\\n' || this->peek() == '\\r') {\n        if (style == ScalarStyle::Literal) {\n          if (line_indent > content_indent) {\n            buffer += trailing_newlines;\n            trailing_newlines.clear();\n            for (std::size_t index = content_indent; index < line_indent;\n                 ++index) {\n              buffer += ' ';\n            }\n          }\n          trailing_newlines += '\\n';\n        } else {\n          blank_line_count++;\n          if (original) {\n            if (line_indent > content_indent) {\n              *original += original_trailing;\n              original_trailing.clear();\n              for (std::size_t index = content_indent; index < line_indent;\n                   ++index) {\n                *original += ' ';\n              }\n            }\n            original_trailing += '\\n';\n          }\n        }\n        this->advance(1);\n        if (this->input_[this->position_ - 1] == '\\r' && this->peek() == '\\n') {\n          this->advance(1);\n        }\n        continue;\n      }\n\n      if (line_indent < content_indent) {\n        for (std::size_t index = 0; index < line_indent; ++index) {\n          this->position_--;\n          this->column_--;\n        }\n        break;\n      }\n\n      if (line_indent == 0 && this->position_ + 2 < this->input_.size()) {\n        if ((this->peek() == '-' && this->peek(1) == '-' &&\n             this->peek(2) == '-') ||\n            (this->peek() == '.' && this->peek(1) == '.' &&\n             this->peek(2) == '.')) {\n          break;\n        }\n      }\n\n      if (style == ScalarStyle::Literal) {\n        buffer += trailing_newlines;\n        trailing_newlines.clear();\n      } else {\n        const bool starts_with_whitespace{this->peek() == '\\t'};\n        if (had_line_break) {\n          const bool preserve_line_break{\n              previous_was_more_indented || previous_started_with_whitespace ||\n              line_indent > content_indent || starts_with_whitespace};\n          if (blank_line_count == 0 && !preserve_line_break) {\n            buffer += ' ';\n          } else {\n            if (preserve_line_break) {\n              buffer += '\\n';\n            }\n            for (std::size_t count = 0; count < blank_line_count; ++count) {\n              buffer += '\\n';\n            }\n          }\n        } else if (blank_line_count > 0) {\n          for (std::size_t count = 0; count < blank_line_count; ++count) {\n            buffer += '\\n';\n          }\n        }\n        blank_line_count = 0;\n        had_line_break = false;\n        previous_started_with_whitespace = starts_with_whitespace;\n\n        if (original) {\n          *original += original_trailing;\n          original_trailing.clear();\n        }\n      }\n\n      for (std::size_t index = content_indent; index < line_indent; ++index) {\n        buffer += ' ';\n        if (original) {\n          *original += ' ';\n        }\n      }\n\n      while (this->position_ < this->input_.size() && this->peek() != '\\n' &&\n             this->peek() != '\\r') {\n        const auto character{this->peek()};\n        buffer += character;\n        if (original) {\n          *original += character;\n        }\n        this->advance(1);\n      }\n\n      if (style == ScalarStyle::Folded) {\n        previous_was_more_indented = (line_indent > content_indent);\n      }\n\n      if (this->peek() == '\\n' || this->peek() == '\\r') {\n        if (style == ScalarStyle::Literal) {\n          trailing_newlines += '\\n';\n        } else {\n          had_line_break = true;\n          if (original) {\n            original_trailing += '\\n';\n          }\n        }\n        this->advance(1);\n        if (this->input_[this->position_ - 1] == '\\r' && this->peek() == '\\n') {\n          this->advance(1);\n        }\n      }\n    }\n\n    if (chomping == '+') {\n      if (style == ScalarStyle::Literal) {\n        buffer += trailing_newlines;\n      } else {\n        if (had_line_break) {\n          buffer += '\\n';\n        }\n        for (std::size_t count = 0; count < blank_line_count; ++count) {\n          buffer += '\\n';\n        }\n        if (original) {\n          *original += original_trailing;\n        }\n      }\n    } else if (chomping == 'c' && !buffer.empty()) {\n      if (style == ScalarStyle::Literal) {\n        if (!trailing_newlines.empty()) {\n          buffer += '\\n';\n        }\n      } else if (had_line_break || blank_line_count > 0) {\n        buffer += '\\n';\n        if (original && !original_trailing.empty()) {\n          *original += '\\n';\n        }\n      }\n    }\n\n    BlockChomping block_chomping{BlockChomping::Clip};\n    if (chomping == '-') {\n      block_chomping = BlockChomping::Strip;\n    } else if (chomping == '+') {\n      block_chomping = BlockChomping::Keep;\n    }\n\n    return Token{.type = TokenType::Scalar,\n                 .value = buffer,\n                 .line = start_line,\n                 .column = start_column,\n                 .scalar_style = style,\n                 .chomping = block_chomping,\n                 .block_original = original ? std::string_view{*original}\n                                            : std::string_view{},\n                 .explicit_indent = explicit_indent,\n                 .indent_before_chomping = indent_first};\n  }\n\n  auto scan_plain_scalar() -> Token {\n    const auto start_line{this->line_};\n    const auto start_column{this->column_};\n    const auto start_position{this->position_};\n    const bool in_flow{this->flow_level_ > 0};\n\n    if (in_flow) {\n      const char first{this->peek()};\n      if (first == '-' || first == '?' || first == ':') {\n        const char after{this->peek(1)};\n        if (after == '\\0' || is_whitespace(after) || is_flow_indicator(after))\n            [[unlikely]] {\n          throw YAMLParseError{start_line, start_column,\n                               \"Invalid plain scalar start in flow context\"};\n        }\n      }\n    }\n\n    const std::size_t min_indent{\n        in_flow\n            ? 0\n            : (this->block_indent_ == SIZE_MAX ? 0 : this->block_indent_ + 1)};\n    bool used_multiline{false};\n    std::string pending_whitespace;\n    std::string *buffer{nullptr};\n\n    while (this->position_ < this->input_.size()) {\n      const auto line_start{this->position_};\n\n      while (this->position_ < this->input_.size()) {\n        const char current{this->peek()};\n\n        if (current == ':') {\n          const char after{this->peek(1)};\n          if (after == '\\0' || is_whitespace(after)) {\n            break;\n          }\n          if (in_flow && is_flow_indicator(after)) {\n            break;\n          }\n        }\n\n        if (current == '#') {\n          if (this->position_ > line_start) {\n            const char before{this->input_[this->position_ - 1]};\n            if (before == ' ' || before == '\\t') {\n              break;\n            }\n          }\n        }\n\n        if (in_flow && is_flow_indicator(current)) {\n          break;\n        }\n\n        if (current == '\\n' || current == '\\r') {\n          break;\n        }\n\n        this->advance(1);\n      }\n\n      auto segment_end{this->position_};\n      while (segment_end > line_start &&\n             (this->input_[segment_end - 1] == ' ' ||\n              this->input_[segment_end - 1] == '\\t')) {\n        segment_end--;\n      }\n\n      const auto segment{\n          this->input_.substr(line_start, segment_end - line_start)};\n\n      if (!segment.empty()) {\n        if (used_multiline) {\n          *buffer += pending_whitespace;\n        }\n        if (buffer != nullptr) {\n          *buffer += segment;\n        }\n        pending_whitespace.clear();\n      }\n\n      if (this->position_ >= this->input_.size()) {\n        break;\n      }\n\n      const char current{this->peek()};\n      if (current != '\\n' && current != '\\r') {\n        break;\n      }\n\n      const auto saved_position{this->position_};\n      const auto saved_line{this->line_};\n      const auto saved_column{this->column_};\n\n      std::size_t newline_count{0};\n      std::size_t next_line_indent{0};\n\n      while (this->position_ < this->input_.size()) {\n        const char character{this->peek()};\n        if (character == '\\n') {\n          newline_count++;\n          this->advance(1);\n          next_line_indent = 0;\n        } else if (character == '\\r') {\n          newline_count++;\n          this->advance(1);\n          if (this->peek() == '\\n') {\n            this->advance(1);\n          }\n          next_line_indent = 0;\n        } else if (character == ' ' || character == '\\t') {\n          next_line_indent++;\n          this->advance(1);\n        } else {\n          break;\n        }\n      }\n\n      if (this->position_ >= this->input_.size()) {\n        this->position_ = saved_position;\n        this->line_ = saved_line;\n        this->column_ = saved_column;\n        break;\n      }\n\n      if (next_line_indent < min_indent) {\n        this->position_ = saved_position;\n        this->line_ = saved_line;\n        this->column_ = saved_column;\n        break;\n      }\n\n      const char next_char{this->peek()};\n\n      if (in_flow && is_flow_indicator(next_char)) {\n        this->position_ = saved_position;\n        this->line_ = saved_line;\n        this->column_ = saved_column;\n        break;\n      }\n\n      if (next_char == '-' || next_char == '?' || next_char == ':') {\n        const char after{this->peek(1)};\n        if (after == '\\0' || is_whitespace(after)) {\n          if (next_line_indent == 0 || start_column < 3 ||\n              next_line_indent <= start_column - 3) {\n            this->position_ = saved_position;\n            this->line_ = saved_line;\n            this->column_ = saved_column;\n            break;\n          }\n        }\n        if (in_flow && next_char == ':') {\n          if (is_flow_indicator(after)) {\n            this->position_ = saved_position;\n            this->line_ = saved_line;\n            this->column_ = saved_column;\n            break;\n          }\n        }\n      }\n\n      if (!in_flow && this->line_contains_mapping_key()) {\n        this->position_ = saved_position;\n        this->line_ = saved_line;\n        this->column_ = saved_column;\n        break;\n      }\n\n      if (next_line_indent == 0) {\n        if ((next_char == '-' && this->peek(1) == '-' &&\n             this->peek(2) == '-') ||\n            (next_char == '.' && this->peek(1) == '.' &&\n             this->peek(2) == '.')) {\n          this->position_ = saved_position;\n          this->line_ = saved_line;\n          this->column_ = saved_column;\n          break;\n        }\n      }\n\n      if (next_char == '#') {\n        this->position_ = saved_position;\n        this->line_ = saved_line;\n        this->column_ = saved_column;\n        break;\n      }\n\n      if (!used_multiline) {\n        buffer = &this->get_buffer();\n        *buffer =\n            this->input_.substr(start_position, segment_end - start_position);\n      }\n      used_multiline = true;\n      if (newline_count == 1) {\n        pending_whitespace = \" \";\n      } else {\n        pending_whitespace = std::string(newline_count - 1, '\\n');\n      }\n    }\n\n    if (used_multiline && buffer != nullptr) {\n      auto raw_end{this->position_};\n      while (raw_end > start_position && (this->input_[raw_end - 1] == ' ' ||\n                                          this->input_[raw_end - 1] == '\\t')) {\n        raw_end--;\n      }\n      return Token{.type = TokenType::Scalar,\n                   .value = *buffer,\n                   .line = start_line,\n                   .column = start_column,\n                   .scalar_style = ScalarStyle::Plain,\n                   .multiline = true,\n                   .block_original =\n                       this->roundtrip_\n                           ? this->input_.substr(start_position,\n                                                 raw_end - start_position)\n                           : std::string_view{}};\n    }\n\n    auto length{this->position_ - start_position};\n    while (length > 0 && (this->input_[start_position + length - 1] == ' ' ||\n                          this->input_[start_position + length - 1] == '\\t')) {\n      length--;\n    }\n\n    return Token{.type = TokenType::Scalar,\n                 .value = this->input_.substr(start_position, length),\n                 .line = start_line,\n                 .column = start_column,\n                 .scalar_style = ScalarStyle::Plain};\n  }\n\n  auto get_buffer() -> std::string & {\n    this->scalar_buffers_.emplace_back();\n    return this->scalar_buffers_.back();\n  }\n\n  std::string_view input_;\n  std::size_t position_{0};\n  std::uint64_t line_{1};\n  std::uint64_t column_{1};\n  std::size_t flow_level_{0};\n  bool stream_started_{false};\n  bool stream_ended_{false};\n  bool last_was_quoted_scalar_{false};\n  bool tab_at_line_start_{false};\n  bool roundtrip_{false};\n  std::uint64_t comment_reference_line_{0};\n  std::optional<std::string> inline_comment_buffer_;\n  std::optional<std::string> block_scalar_comment_;\n  std::vector<std::string> preceding_comments_buffer_;\n  // SIZE_MAX means \"not set\" (top-level), 0 means parent at indent 0\n  std::size_t block_indent_{SIZE_MAX};\n  std::deque<std::string> scalar_buffers_;\n};\n\n} // namespace sourcemeta::core::yaml\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/parser.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_PARSER_H_\n#define SOURCEMETA_CORE_YAML_PARSER_H_\n\n#include \"lexer.h\"\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/numeric.h>\n#include <sourcemeta/core/yaml_error.h>\n#include <sourcemeta/core/yaml_roundtrip.h>\n\n#include <cassert>       // assert\n#include <cstdint>       // std::uint64_t\n#include <optional>      // std::optional\n#include <sstream>       // std::ostringstream\n#include <string>        // std::string\n#include <string_view>   // std::string_view\n#include <unordered_map> // std::unordered_map\n#include <unordered_set> // std::unordered_set\n#include <utility>       // std::move\n#include <vector>        // std::vector\n\nnamespace sourcemeta::core::yaml {\n\nstruct CallbackRecord {\n  JSON::ParsePhase phase;\n  JSON::Type type;\n  std::uint64_t line;\n  std::uint64_t column;\n  JSON::ParseContext context;\n  std::size_t index;\n  std::string property;\n};\n\nstruct AnchoredValue {\n  JSON value;\n  std::vector<CallbackRecord> callbacks;\n};\n\nclass Parser {\npublic:\n  Parser(Lexer *lexer, const JSON::ParseCallback *callback,\n         YAMLRoundTrip *roundtrip = nullptr)\n      : lexer_{lexer}, callback_{callback}, roundtrip_{roundtrip} {}\n\n  auto parse() -> JSON {\n    std::optional<Token> token;\n\n    if (!this->pending_tokens_.empty()) {\n      token = this->pending_tokens_.front();\n      this->pending_tokens_.pop_front();\n      if (this->pending_tokens_.empty()) {\n        this->pending_token_position_.reset();\n      }\n    } else {\n      token = this->lexer_->next();\n      if (!token.has_value() || token->type != TokenType::StreamStart)\n          [[unlikely]] {\n        throw YAMLParseError{this->lexer_->line(), this->lexer_->column(),\n                             \"Expected stream start\"};\n      }\n      token = this->lexer_->next();\n    }\n\n    if (!token.has_value() || token->type == TokenType::StreamEnd)\n        [[unlikely]] {\n      throw YAMLParseError{1, 1, \"Empty YAML document\"};\n    }\n\n    if (token->type == TokenType::DirectiveYAML ||\n        token->type == TokenType::DirectiveTag ||\n        token->type == TokenType::DirectiveReserved) {\n      this->process_directives(token.value());\n    }\n\n    if (token->type == TokenType::DocumentStart) {\n      if (this->roundtrip_) {\n        this->roundtrip_->leading_comments =\n            this->lexer_->take_preceding_comments();\n        this->roundtrip_->explicit_document_start = true;\n      }\n      this->document_start_line_ = token->line;\n      const auto pos_before_next{this->lexer_->position()};\n      token = this->lexer_->next();\n      if (this->roundtrip_) {\n        this->roundtrip_->document_start_comment =\n            this->lexer_->take_inline_comment();\n      }\n\n      if (!token.has_value() || token->type == TokenType::StreamEnd ||\n          token->type == TokenType::DocumentEnd ||\n          token->type == TokenType::DocumentStart) {\n        if (token.has_value() && token->type == TokenType::DocumentStart) {\n          this->pending_tokens_.push_back(token.value());\n          this->pending_token_position_ = pos_before_next;\n        }\n        return JSON{nullptr};\n      }\n    } else if (!token.has_value() || token->type == TokenType::StreamEnd)\n        [[unlikely]] {\n      throw YAMLParseError{1, 1, \"Empty YAML document\"};\n    } else if (token->type == TokenType::DocumentEnd) {\n      while (token.has_value() && token->type == TokenType::DocumentEnd) {\n        token = this->lexer_->next();\n      }\n      if (!token.has_value() || token->type == TokenType::StreamEnd)\n          [[unlikely]] {\n        throw YAMLParseError{1, 1, \"Empty YAML document\"};\n      }\n      this->pending_tokens_.push_back(token.value());\n      return JSON{nullptr};\n    }\n\n    if (this->roundtrip_) {\n      auto comments{this->lexer_->take_preceding_comments()};\n      this->lexer_->take_inline_comment();\n      if (this->roundtrip_->explicit_document_start) {\n        this->roundtrip_->post_start_comments = std::move(comments);\n      } else {\n        this->roundtrip_->leading_comments = std::move(comments);\n      }\n    }\n\n    auto result{this->parse_value(token.value(), JSON::ParseContext::Root, 0,\n                                  empty_property_)};\n\n    auto pos_before_token{this->lexer_->position()};\n    token = this->next_token();\n    if (this->roundtrip_) {\n      auto root_inline{this->lexer_->take_inline_comment()};\n      if (root_inline.has_value()) {\n        this->roundtrip_->styles[this->pointer_stack_].comment_inline =\n            std::move(root_inline);\n      }\n    }\n    while (token.has_value() && token->type == TokenType::DocumentEnd) {\n      if (this->roundtrip_) {\n        this->roundtrip_->pre_end_comments =\n            this->lexer_->take_preceding_comments();\n        this->roundtrip_->explicit_document_end = true;\n      }\n      pos_before_token = this->lexer_->position();\n      token = this->next_token();\n      if (this->roundtrip_) {\n        this->roundtrip_->document_end_comment =\n            this->lexer_->take_inline_comment();\n      }\n    }\n\n    if (this->roundtrip_) {\n      auto trailing{this->lexer_->take_preceding_comments()};\n      if (!trailing.empty()) {\n        this->roundtrip_->trailing_comments = std::move(trailing);\n      }\n    }\n\n    if (token.has_value() && token->type != TokenType::StreamEnd) {\n      this->pending_tokens_.push_back(token.value());\n      if (token->type == TokenType::DocumentStart) {\n        this->pending_token_position_ = token->position;\n      } else {\n        this->pending_token_position_ = pos_before_token;\n      }\n    }\n\n    return result;\n  }\n\n  [[nodiscard]] auto position() const noexcept -> std::size_t {\n    if (this->pending_token_position_.has_value()) {\n      return *this->pending_token_position_;\n    }\n    return this->lexer_->position();\n  }\n\n  auto validate_end_of_stream() -> void {\n    auto token{this->next_token()};\n    bool saw_document_end{false};\n    while (token.has_value() && token->type == TokenType::DocumentEnd) {\n      saw_document_end = true;\n      token = this->next_token();\n    }\n    if (!token.has_value() || token->type == TokenType::StreamEnd) {\n      return;\n    }\n    while (token.has_value() && token->type != TokenType::StreamEnd) {\n      if (token->type == TokenType::DocumentStart) {\n        this->tag_directives_.clear();\n        token = this->next_token();\n        if (!token.has_value() || token->type == TokenType::StreamEnd) {\n          return;\n        }\n        if (token->type == TokenType::DocumentEnd ||\n            token->type == TokenType::DocumentStart) {\n          continue;\n        }\n      }\n      if (token->type == TokenType::DirectiveYAML ||\n          token->type == TokenType::DirectiveTag ||\n          token->type == TokenType::DirectiveReserved) {\n        if (!saw_document_end) [[unlikely]] {\n          throw YAMLParseError{token->line, token->column,\n                               \"Directive not allowed without preceding \"\n                               \"document end marker\"};\n        }\n        this->process_directives(token.value());\n        continue;\n      }\n      if (!saw_document_end && token->type != TokenType::DocumentStart)\n          [[unlikely]] {\n        throw YAMLParseError{token->line, token->column,\n                             \"Unexpected content after document\"};\n      }\n      this->parse_value(token.value(), JSON::ParseContext::Root, 0,\n                        empty_property_);\n      saw_document_end = false;\n      token = this->next_token();\n      while (token.has_value() && token->type == TokenType::DocumentEnd) {\n        saw_document_end = true;\n        token = this->next_token();\n      }\n    }\n  }\n\nprivate:\n  auto process_directives(Token &token) -> void {\n    bool seen_yaml_directive{false};\n    while (token.type == TokenType::DirectiveYAML ||\n           token.type == TokenType::DirectiveTag ||\n           token.type == TokenType::DirectiveReserved) {\n      if (token.type == TokenType::DirectiveYAML) {\n        if (seen_yaml_directive) [[unlikely]] {\n          throw YAMLParseError{token.line, token.column,\n                               \"Duplicate %YAML directive\"};\n        }\n        seen_yaml_directive = true;\n        const auto content{token.value};\n        auto cursor{5uz};\n        while (cursor < content.size() &&\n               (content[cursor] == ' ' || content[cursor] == '\\t')) {\n          cursor++;\n        }\n        while (cursor < content.size() && content[cursor] != ' ' &&\n               content[cursor] != '\\t' && content[cursor] != '#') {\n          cursor++;\n        }\n        while (cursor < content.size() &&\n               (content[cursor] == ' ' || content[cursor] == '\\t')) {\n          cursor++;\n        }\n        if (cursor < content.size() && content[cursor] != '#') [[unlikely]] {\n          throw YAMLParseError{token.line, token.column,\n                               \"Invalid content in %YAML directive\"};\n        }\n      } else if (token.type == TokenType::DirectiveTag) {\n        const auto content{token.value};\n        auto cursor{4uz};\n        while (cursor < content.size() &&\n               (content[cursor] == ' ' || content[cursor] == '\\t')) {\n          cursor++;\n        }\n        const auto handle_start{cursor};\n        while (cursor < content.size() && content[cursor] != ' ' &&\n               content[cursor] != '\\t') {\n          cursor++;\n        }\n        const auto handle{\n            std::string{content.substr(handle_start, cursor - handle_start)}};\n        while (cursor < content.size() &&\n               (content[cursor] == ' ' || content[cursor] == '\\t')) {\n          cursor++;\n        }\n        const auto prefix_start{cursor};\n        while (cursor < content.size() && content[cursor] != ' ' &&\n               content[cursor] != '\\t' && content[cursor] != '\\n' &&\n               content[cursor] != '\\r') {\n          cursor++;\n        }\n        const auto prefix{\n            std::string{content.substr(prefix_start, cursor - prefix_start)}};\n        if (!handle.empty() && !prefix.empty()) {\n          this->tag_directives_.insert_or_assign(handle, prefix);\n        }\n      }\n      auto next{this->lexer_->next()};\n      if (!next.has_value()) {\n        break;\n      }\n      token = next.value();\n    }\n  }\n\n  auto resolve_tag(const std::string_view raw_tag) -> std::string {\n    if (raw_tag.size() > 2 && raw_tag[0] == '!' && raw_tag[1] == '<' &&\n        raw_tag.back() == '>') {\n      return std::string{raw_tag.substr(2, raw_tag.size() - 3)};\n    }\n\n    if (raw_tag.starts_with(\"!!\")) {\n      const auto iterator{this->tag_directives_.find(\"!!\")};\n      if (iterator != this->tag_directives_.end()) {\n        return iterator->second + std::string{raw_tag.substr(2)};\n      }\n      return \"tag:yaml.org,2002:\" + std::string{raw_tag.substr(2)};\n    }\n\n    if (raw_tag.size() > 1 && raw_tag[0] == '!') {\n      const auto second_bang{raw_tag.find('!', 1)};\n      if (second_bang != std::string_view::npos &&\n          second_bang < raw_tag.size() - 1) {\n        const auto handle{std::string{raw_tag.substr(0, second_bang + 1)}};\n        const auto iterator{this->tag_directives_.find(handle)};\n        if (iterator != this->tag_directives_.end()) {\n          return iterator->second +\n                 std::string{raw_tag.substr(second_bang + 1)};\n        }\n      }\n    }\n\n    return std::string{raw_tag};\n  }\n\n  auto invoke_callback(const JSON::ParsePhase phase, const JSON::Type type,\n                       const std::uint64_t line, const std::uint64_t column,\n                       const JSON::ParseContext context,\n                       const std::size_t index, const std::string &property)\n      -> void {\n    if (this->callback_ && *this->callback_) {\n      (*this->callback_)(phase, type, line, column, context, index, property);\n    }\n\n    if (this->recording_anchor_) {\n      this->current_anchor_callbacks_.push_back(\n          {phase, type, line, column, context, index, std::string{property}});\n    }\n  }\n\n  [[nodiscard]] auto effective_line(const Token &token,\n                                    const JSON::ParseContext context,\n                                    const std::uint64_t key_line) const\n      -> std::uint64_t {\n    return (context == JSON::ParseContext::Property && key_line > 0)\n               ? key_line\n               : token.line;\n  }\n\n  [[nodiscard]] auto effective_column(const Token &token,\n                                      const JSON::ParseContext context,\n                                      const std::uint64_t key_column) const\n      -> std::uint64_t {\n    return (context == JSON::ParseContext::Property && key_column > 0)\n               ? key_column\n               : token.column;\n  }\n\n  [[nodiscard]] auto json_to_key_string(const JSON &value) const\n      -> std::string {\n    if (value.is_string()) {\n      return value.to_string();\n    }\n    if (value.is_null()) {\n      return \"\";\n    }\n    std::ostringstream stream;\n    stream << value;\n    return stream.str();\n  }\n\n  auto parse_value(const Token &token, const JSON::ParseContext context,\n                   const std::size_t index, const std::string &property,\n                   const std::uint64_t key_line = 0,\n                   const std::uint64_t key_column = 0) -> JSON {\n    if (this->roundtrip_) {\n      if (context == JSON::ParseContext::Property) {\n        this->pointer_stack_.push_back(std::string{property});\n      } else if (context == JSON::ParseContext::Index) {\n        this->pointer_stack_.push_back(index);\n      }\n    }\n\n    std::optional<std::string_view> anchor_name;\n    std::uint64_t anchor_line{0};\n    std::optional<std::string> tag;\n    std::size_t anchor_count{0};\n    std::optional<std::string> anchor_inline_comment;\n    Token current_token{token};\n    std::uint64_t node_start_column{token.column};\n    std::uint64_t prefix_line{token.line};\n\n    while (current_token.type == TokenType::Anchor ||\n           current_token.type == TokenType::Tag) {\n      if (this->lexer_->flow_level() == 0 &&\n          context == JSON::ParseContext::Property && key_line > 0 &&\n          current_token.line != key_line) {\n        const auto value_indent{\n            current_token.column > 0\n                ? static_cast<std::size_t>(current_token.column - 1)\n                : 0uz};\n        const auto parent_indent{this->lexer_->block_indent()};\n        if (parent_indent != SIZE_MAX && value_indent <= parent_indent)\n            [[unlikely]] {\n          throw YAMLParseError{current_token.line, current_token.column,\n                               \"Node property at wrong indentation level\"};\n        }\n      }\n      if (current_token.type == TokenType::Anchor) {\n        anchor_name = current_token.value;\n        anchor_line = current_token.line;\n        anchor_count++;\n      } else {\n        tag = this->resolve_tag(current_token.value);\n      }\n\n      auto next{this->lexer_->next()};\n      if (this->roundtrip_ && anchor_name.has_value()) {\n        anchor_inline_comment = this->lexer_->take_inline_comment();\n      }\n      if (!next.has_value() || next->type == TokenType::StreamEnd ||\n          next->type == TokenType::DocumentEnd ||\n          next->type == TokenType::DocumentStart) {\n        JSON empty_value{nullptr};\n        if (tag.has_value()) {\n          if (tag.value() == \"tag:yaml.org,2002:str\") {\n            empty_value = JSON{std::string{}};\n          }\n        }\n        if (next.has_value()) {\n          this->pending_tokens_.push_back(next.value());\n        }\n        if (this->roundtrip_ && anchor_name.has_value()) {\n          auto &style{this->roundtrip_->styles[this->pointer_stack_]};\n          style.anchor = std::string{anchor_name.value()};\n          if (anchor_inline_comment.has_value()) {\n            style.comment_inline = std::move(anchor_inline_comment);\n          }\n        }\n        if (this->roundtrip_ && context != JSON::ParseContext::Root) {\n          this->pointer_stack_.pop_back();\n        }\n        return empty_value;\n      }\n      current_token = next.value();\n\n      if (current_token.type == TokenType::Scalar &&\n          current_token.column <= key_column && key_column > 0) {\n        auto after{this->lexer_->next()};\n        if (after.has_value() && after->type == TokenType::BlockMappingValue) {\n          this->pending_tokens_.push_back(current_token);\n          this->pending_tokens_.push_back(after.value());\n          if (anchor_name.has_value()) {\n            this->register_anchored_null(anchor_name.value(), token, context,\n                                         index, property,\n                                         anchor_inline_comment);\n          }\n          if (this->roundtrip_ && context != JSON::ParseContext::Root) {\n            this->pointer_stack_.pop_back();\n          }\n          return JSON{nullptr};\n        }\n        if (after.has_value()) {\n          this->pending_tokens_.push_back(after.value());\n        }\n      }\n\n      if (anchor_name.has_value() && context == JSON::ParseContext::Index &&\n          current_token.type == TokenType::BlockSequenceEntry) {\n        const auto block_indent{this->lexer_->block_indent()};\n        const auto entry_indent{\n            current_token.column > 0\n                ? static_cast<std::size_t>(current_token.column - 1)\n                : 0uz};\n        if (block_indent != SIZE_MAX && entry_indent <= block_indent) {\n          this->pending_tokens_.push_back(current_token);\n          this->register_anchored_null(anchor_name.value(), token, context,\n                                       index, property, anchor_inline_comment);\n          if (this->roundtrip_ && context != JSON::ParseContext::Root) {\n            this->pointer_stack_.pop_back();\n          }\n          return JSON{nullptr};\n        }\n      }\n    }\n\n    if (tag.has_value() && (current_token.type == TokenType::FlowEntry ||\n                            current_token.type == TokenType::MappingEnd ||\n                            current_token.type == TokenType::SequenceEnd)) {\n      JSON empty_value{nullptr};\n      if (tag.value() == \"tag:yaml.org,2002:str\") {\n        empty_value = JSON{std::string{}};\n      }\n      this->pending_tokens_.push_back(current_token);\n      if (this->roundtrip_ && context != JSON::ParseContext::Root) {\n        this->pointer_stack_.pop_back();\n      }\n      return empty_value;\n    }\n\n    if (current_token.line != prefix_line) {\n      node_start_column = 0;\n    }\n\n    if ((anchor_name.has_value() || tag.has_value()) &&\n        this->lexer_->flow_level() == 0 && current_token.line == prefix_line &&\n        current_token.type == TokenType::BlockSequenceEntry) [[unlikely]] {\n      throw YAMLParseError{current_token.line, current_token.column,\n                           \"Block sequence after node property must start \"\n                           \"on a new line\"};\n    }\n\n    if (anchor_name.has_value()) {\n      this->recording_anchor_ = true;\n      this->current_anchor_callbacks_.clear();\n    }\n\n    JSON result{nullptr};\n\n    switch (current_token.type) {\n      case TokenType::Scalar: {\n        auto next{this->next_token()};\n        if (next.has_value() && next->type == TokenType::BlockMappingValue) {\n          if (current_token.multiline) [[unlikely]] {\n            throw YAMLParseError{current_token.line, current_token.column,\n                                 \"Multi-line implicit mapping key\"};\n          }\n          if (this->lexer_->flow_level() > 0 &&\n              next->line != current_token.line) [[unlikely]] {\n            throw YAMLParseError{next->line, next->column,\n                                 \"Implicit key and value indicator on \"\n                                 \"different lines in flow context\"};\n          }\n          if (this->lexer_->flow_level() == 0 &&\n              context == JSON::ParseContext::Property && key_line > 0 &&\n              current_token.line == key_line) [[unlikely]] {\n            throw YAMLParseError{current_token.line, current_token.column,\n                                 \"Implicit mapping key in block value on \"\n                                 \"same line as parent key\"};\n          }\n          if (this->lexer_->flow_level() == 0 &&\n              (anchor_name.has_value() || tag.has_value()) &&\n              this->document_start_line_ > 0 &&\n              current_token.line == this->document_start_line_) [[unlikely]] {\n            throw YAMLParseError{\n                current_token.line, current_token.column,\n                \"Node properties before implicit mapping key on \"\n                \"document start line\"};\n          }\n          if (anchor_name.has_value() && anchor_line == current_token.line) {\n            JSON key_value{current_token.value};\n            this->recording_anchor_ = false;\n            this->anchors_.insert_or_assign(\n                std::string{anchor_name.value()},\n                AnchoredValue{.value = key_value,\n                              .callbacks =\n                                  std::move(this->current_anchor_callbacks_)});\n            this->current_anchor_callbacks_.clear();\n            anchor_name.reset();\n          }\n          result = this->parse_block_mapping_from_first_key(\n              current_token, context, index, property, key_line, key_column,\n              node_start_column);\n        } else {\n          if (anchor_count > 1) [[unlikely]] {\n            throw YAMLParseError{current_token.line, current_token.column,\n                                 \"Multiple anchors on a scalar node\"};\n          }\n          result = this->parse_scalar(current_token, tag, context, index,\n                                      property, key_line, key_column);\n          if (next.has_value()) {\n            this->pending_tokens_.push_back(next.value());\n          }\n        }\n        break;\n      }\n      case TokenType::MappingStart:\n        result = this->parse_flow_mapping(current_token, context, index,\n                                          property, key_line, key_column);\n        this->record_collection_style(YAMLRoundTrip::CollectionStyle::Flow);\n        break;\n      case TokenType::SequenceStart:\n        result = this->parse_flow_sequence(current_token, context, index,\n                                           property, key_line, key_column);\n        this->record_collection_style(YAMLRoundTrip::CollectionStyle::Flow);\n        break;\n      case TokenType::BlockSequenceEntry:\n        result = this->parse_block_sequence(current_token, context, index,\n                                            property, key_line, key_column);\n        break;\n      case TokenType::BlockMappingKey:\n      case TokenType::BlockMappingValue:\n        result = this->parse_block_mapping(current_token, context, index,\n                                           property, key_line, key_column);\n        break;\n      case TokenType::Alias: {\n        auto next{this->next_token()};\n        if (next.has_value() && next->type == TokenType::BlockMappingValue) {\n          const std::string alias_name{current_token.value};\n          const auto iterator{this->anchors_.find(alias_name)};\n          if (iterator == this->anchors_.end()) [[unlikely]] {\n            throw YAMLUnknownAnchorError{alias_name, current_token.line,\n                                         current_token.column};\n          }\n          const auto key_string{\n              this->json_to_key_string(iterator->second.value)};\n          Token key_token{current_token};\n          key_token.type = TokenType::Scalar;\n          key_token.value = key_string;\n          result = this->parse_block_mapping_from_first_key(\n              key_token, context, index, property, key_line, key_column,\n              node_start_column);\n        } else {\n          if (anchor_name.has_value()) [[unlikely]] {\n            throw YAMLParseError{current_token.line, current_token.column,\n                                 \"Cannot anchor an alias node\"};\n          }\n          result = this->resolve_alias(current_token, context, index, property,\n                                       key_line, key_column);\n          if (this->roundtrip_) {\n            this->roundtrip_->aliases[this->pointer_stack_] =\n                std::string{current_token.value};\n          }\n          if (next.has_value()) {\n            this->pending_tokens_.push_back(next.value());\n          }\n        }\n        break;\n      }\n      default:\n        throw YAMLParseError{current_token.line, current_token.column,\n                             \"Unexpected token\"};\n    }\n\n    if (anchor_name.has_value()) {\n      this->recording_anchor_ = false;\n      this->anchors_.insert_or_assign(\n          std::string{anchor_name.value()},\n          AnchoredValue{.value = result,\n                        .callbacks =\n                            std::move(this->current_anchor_callbacks_)});\n      this->current_anchor_callbacks_.clear();\n\n      if (this->roundtrip_) {\n        auto &style{this->roundtrip_->styles[this->pointer_stack_]};\n        style.anchor = std::string{anchor_name.value()};\n        if (anchor_inline_comment.has_value()) {\n          style.comment_inline = std::move(anchor_inline_comment);\n        }\n      }\n    }\n\n    if (this->roundtrip_ && context != JSON::ParseContext::Root) {\n      this->pointer_stack_.pop_back();\n    }\n\n    return result;\n  }\n\n  auto parse_scalar(const Token &token, const std::optional<std::string> &tag,\n                    const JSON::ParseContext context, const std::size_t index,\n                    const std::string &property,\n                    const std::uint64_t key_line = 0,\n                    const std::uint64_t key_column = 0) -> JSON {\n    JSON result{this->interpret_scalar(token.value, token.scalar_style, tag)};\n    this->record_scalar_style(token);\n\n    this->invoke_callback(JSON::ParsePhase::Pre, result.type(),\n                          this->effective_line(token, context, key_line),\n                          this->effective_column(token, context, key_column),\n                          context, index, property);\n\n    auto end_column{token.column};\n    if (!token.value.empty()) {\n      end_column += static_cast<std::uint64_t>(token.value.size()) - 1;\n    }\n    if (token.scalar_style == ScalarStyle::SingleQuoted ||\n        token.scalar_style == ScalarStyle::DoubleQuoted) {\n      end_column += 2;\n    }\n\n    this->invoke_callback(JSON::ParsePhase::Post, result.type(), token.line,\n                          end_column, JSON::ParseContext::Root, 0,\n                          empty_property_);\n\n    return result;\n  }\n\n  auto interpret_scalar(const std::string_view value, const ScalarStyle style,\n                        const std::optional<std::string> &tag) -> JSON {\n    if (tag.has_value()) {\n      const auto &tag_value{tag.value()};\n      if (tag_value == \"!\" || tag_value == \"tag:yaml.org,2002:str\") {\n        return JSON{value};\n      }\n      if (tag_value == \"tag:yaml.org,2002:null\") {\n        return JSON{nullptr};\n      }\n      if (tag_value == \"tag:yaml.org,2002:bool\") {\n        if (value == \"true\" || value == \"True\" || value == \"TRUE\") {\n          return JSON{true};\n        }\n        return JSON{false};\n      }\n      if (tag_value == \"tag:yaml.org,2002:int\") {\n        return this->parse_integer(value);\n      }\n      if (tag_value == \"tag:yaml.org,2002:float\") {\n        return this->parse_float(value);\n      }\n      return JSON{value};\n    }\n\n    if (style != ScalarStyle::Plain) {\n      return JSON{value};\n    }\n\n    if (value.empty()) {\n      return JSON{nullptr};\n    }\n\n    if (value == \"null\" || value == \"Null\" || value == \"NULL\" || value == \"~\") {\n      return JSON{nullptr};\n    }\n\n    if (value == \"true\" || value == \"True\" || value == \"TRUE\") {\n      return JSON{true};\n    }\n\n    if (value == \"false\" || value == \"False\" || value == \"FALSE\") {\n      return JSON{false};\n    }\n\n    if (value == \".inf\" || value == \".Inf\" || value == \".INF\" ||\n        value == \"+.inf\" || value == \"+.Inf\" || value == \"+.INF\" ||\n        value == \"-.inf\" || value == \"-.Inf\" || value == \"-.INF\" ||\n        value == \".nan\" || value == \".NaN\" || value == \".NAN\") {\n      return JSON{value};\n    }\n\n    if (this->looks_like_number(value)) {\n      return this->parse_number(value);\n    }\n\n    return JSON{value};\n  }\n\n  [[nodiscard]] auto looks_like_number(const std::string_view value) const\n      -> bool {\n    if (value.empty()) {\n      return false;\n    }\n\n    std::size_t start{0};\n    if (value[0] == '-' || value[0] == '+') {\n      start = 1;\n      if (start >= value.size()) {\n        return false;\n      }\n    }\n\n    if (value.size() > start + 1 && value[start] == '0') {\n      if (value[start + 1] == 'x' || value[start + 1] == 'X') {\n        return true;\n      }\n      if (value[start + 1] == 'o' || value[start + 1] == 'O') {\n        return true;\n      }\n    }\n\n    bool has_digit{false};\n    bool has_dot{false};\n    bool has_exp{false};\n\n    for (std::size_t index = start; index < value.size(); ++index) {\n      const char current{value[index]};\n      if (current >= '0' && current <= '9') {\n        has_digit = true;\n      } else if (current == '.') {\n        if (has_dot || has_exp) {\n          return false;\n        }\n        has_dot = true;\n      } else if (current == 'e' || current == 'E') {\n        if (has_exp || !has_digit) {\n          return false;\n        }\n        has_exp = true;\n        if (index + 1 < value.size() &&\n            (value[index + 1] == '+' || value[index + 1] == '-')) {\n          ++index;\n        }\n      } else {\n        return false;\n      }\n    }\n\n    return has_digit;\n  }\n\n  auto parse_number(const std::string_view value) -> JSON {\n    const std::size_t prefix{(value[0] == '-' || value[0] == '+') ? 1u : 0u};\n    if (value.size() > prefix + 1 && value[prefix] == '0') {\n      const char indicator{value[prefix + 1]};\n      if (indicator == 'x' || indicator == 'X') {\n        return this->parse_base_integer(value, 16);\n      }\n      if (indicator == 'o' || indicator == 'O') {\n        return this->parse_base_integer(value, 8);\n      }\n    }\n\n    bool has_dot{false};\n    bool has_exp{false};\n    for (const char character : value) {\n      if (character == '.') {\n        has_dot = true;\n      }\n      if (character == 'e' || character == 'E') {\n        has_exp = true;\n      }\n    }\n\n    if (has_exp) {\n      return JSON{Decimal{value}};\n    }\n\n    if (has_dot) {\n      return this->parse_float(value);\n    }\n\n    return this->parse_integer(value);\n  }\n\n  auto parse_integer(const std::string_view value) -> JSON {\n    const auto result{to_int64_t(std::string{value})};\n    return result.has_value() ? JSON{result.value()} : JSON{Decimal{value}};\n  }\n\n  auto parse_base_integer(const std::string_view value, const int base)\n      -> JSON {\n    const bool negative{value[0] == '-'};\n    const std::size_t start{(value[0] == '-' || value[0] == '+') ? 3u : 2u};\n    const auto result{to_int64_t(std::string{value.substr(start)}, base)};\n    if (result.has_value()) {\n      return JSON{negative ? -result.value() : result.value()};\n    }\n    return JSON{value};\n  }\n\n  auto parse_float(const std::string_view value) -> JSON {\n    std::size_t significant_digits{0};\n    bool seen_nonzero{false};\n    for (const char character : value) {\n      if (character >= '0' && character <= '9') {\n        if (character != '0' || seen_nonzero) {\n          seen_nonzero = true;\n          significant_digits++;\n        }\n      }\n    }\n\n    constexpr std::size_t double_precision_limit{15};\n    if (significant_digits > double_precision_limit) {\n      return JSON{Decimal{value}};\n    }\n\n    const auto result{to_double(std::string{value})};\n    if (!result.has_value()) {\n      return JSON{Decimal{value}};\n    }\n\n    const auto as_integer{static_cast<std::int64_t>(result.value())};\n    if (result.value() == static_cast<double>(as_integer)) {\n      return JSON{as_integer};\n    }\n\n    return JSON{result.value()};\n  }\n\n  auto parse_flow_mapping(const Token &start_token,\n                          const JSON::ParseContext context,\n                          const std::size_t index, const std::string &property,\n                          const std::uint64_t key_line = 0,\n                          const std::uint64_t key_column = 0) -> JSON {\n    this->invoke_callback(\n        JSON::ParsePhase::Pre, JSON::Type::Object,\n        this->effective_line(start_token, context, key_line),\n        this->effective_column(start_token, context, key_column), context,\n        index, property);\n\n    JSON result{JSON::make_object()};\n    std::unordered_set<std::string> seen_keys;\n    bool found_compact_separator{false};\n\n    auto token{this->next_token()};\n\n    while (token.has_value() && token->type != TokenType::MappingEnd) {\n      if (token->type == TokenType::FlowEntry) {\n        if (token->compact_separator) {\n          found_compact_separator = true;\n        }\n        token = this->next_token();\n        continue;\n      }\n\n      auto key_token{token.value()};\n\n      std::optional<std::string> key_tag;\n      while (key_token.type == TokenType::Anchor ||\n             key_token.type == TokenType::Tag) {\n        if (key_token.type == TokenType::Tag) {\n          key_tag = this->resolve_tag(key_token.value);\n        }\n        token = this->next_token();\n        if (!token.has_value()) [[unlikely]] {\n          throw YAMLParseError{this->lexer_->line(), this->lexer_->column(),\n                               \"Unexpected end of input in flow mapping\"};\n        }\n        key_token = token.value();\n      }\n\n      std::string key;\n      if (key_token.type == TokenType::BlockMappingValue) {\n        if (key_tag.has_value() && key_tag.value() == \"tag:yaml.org,2002:str\") {\n          key = \"\";\n        }\n      } else if (key_token.type == TokenType::Scalar) {\n        key = std::string{key_token.value};\n        this->record_key_scalar_style(key, key_token.scalar_style,\n                                      key_token.quoted_original);\n      } else [[unlikely]] {\n        throw YAMLParseError{key_token.line, key_token.column,\n                             \"Expected scalar key in mapping\"};\n      }\n\n      if (seen_keys.contains(key)) [[unlikely]] {\n        throw YAMLDuplicateKeyError{key, key_token.line, key_token.column};\n      }\n      seen_keys.insert(key);\n\n      if (key_token.type != TokenType::BlockMappingValue) {\n        token = this->next_token();\n\n        if (!token.has_value()) [[unlikely]] {\n          throw YAMLParseError{this->lexer_->line(), this->lexer_->column(),\n                               \"Unexpected end of input in flow mapping\"};\n        }\n\n        if (token->type == TokenType::FlowEntry ||\n            token->type == TokenType::MappingEnd) {\n          if (token->type == TokenType::FlowEntry && token->compact_separator) {\n            found_compact_separator = true;\n          }\n          result.assign(key, JSON{nullptr});\n          continue;\n        }\n\n        if (token->type != TokenType::BlockMappingValue) [[unlikely]] {\n          const auto colon_column{key_token.column +\n                                  static_cast<std::uint64_t>(key.size())};\n          throw YAMLParseError{key_token.line, colon_column,\n                               \"Expected ':' after mapping key\"};\n        }\n      }\n\n      token = this->next_token();\n      if (!token.has_value()) [[unlikely]] {\n        throw YAMLParseError{this->lexer_->line(), this->lexer_->column(),\n                             \"Expected value after ':'\"};\n      }\n\n      if (token->type == TokenType::FlowEntry ||\n          token->type == TokenType::MappingEnd) {\n        if (token->type == TokenType::FlowEntry && token->compact_separator) {\n          found_compact_separator = true;\n        }\n        result.assign(key, JSON{nullptr});\n      } else {\n        auto value{this->parse_value(token.value(),\n                                     JSON::ParseContext::Property, 0, key,\n                                     key_token.line, key_token.column)};\n        result.assign(key, std::move(value));\n      }\n\n      if (token->type != TokenType::FlowEntry &&\n          token->type != TokenType::MappingEnd) {\n        token = this->next_token();\n        if (token.has_value() && token->type == TokenType::FlowEntry &&\n            token->compact_separator) {\n          found_compact_separator = true;\n        }\n        if (token.has_value() && token->type != TokenType::FlowEntry &&\n            token->type != TokenType::MappingEnd) [[unlikely]] {\n          throw YAMLParseError{token->line, token->column,\n                               \"Missing comma between flow mapping entries\"};\n        }\n      }\n    }\n\n    const auto end_line{token.has_value() ? token->line : this->lexer_->line()};\n    const auto end_column{token.has_value() ? token->column\n                                            : this->lexer_->column()};\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Object, end_line,\n                          end_column, JSON::ParseContext::Root, 0,\n                          empty_property_);\n\n    if (this->roundtrip_ && found_compact_separator) {\n      this->roundtrip_->styles[this->pointer_stack_].compact_flow = true;\n    }\n\n    return result;\n  }\n\n  auto parse_flow_sequence(const Token &start_token,\n                           const JSON::ParseContext context,\n                           const std::size_t index, const std::string &property,\n                           const std::uint64_t key_line = 0,\n                           const std::uint64_t key_column = 0) -> JSON {\n    this->invoke_callback(\n        JSON::ParsePhase::Pre, JSON::Type::Array,\n        this->effective_line(start_token, context, key_line),\n        this->effective_column(start_token, context, key_column), context,\n        index, property);\n\n    JSON result{JSON::make_array()};\n    const auto parent_block_indent{this->lexer_->block_indent()};\n    bool found_compact_separator{false};\n\n    auto token{this->next_token()};\n    std::size_t element_index{0};\n\n    while (token.has_value() && token->type != TokenType::SequenceEnd) {\n      if (parent_block_indent != SIZE_MAX && token->line != start_token.line) {\n        const auto token_indent{\n            token->column > 0 ? static_cast<std::size_t>(token->column - 1)\n                              : 0uz};\n        if (token_indent <= parent_block_indent) [[unlikely]] {\n          throw YAMLParseError{\n              token->line, token->column,\n              \"Flow content indented less than or equal to parent block level\"};\n        }\n      }\n      if (token->type == TokenType::FlowEntry) {\n        if (element_index == 0) [[unlikely]] {\n          throw YAMLParseError{token->line, token->column,\n                               \"Leading comma in flow sequence\"};\n        }\n        if (token->compact_separator) {\n          found_compact_separator = true;\n        }\n        token = this->next_token();\n        if (token.has_value() && token->type == TokenType::FlowEntry)\n            [[unlikely]] {\n          throw YAMLParseError{token->line, token->column,\n                               \"Empty entry in flow sequence\"};\n        }\n        continue;\n      }\n\n      if (token->type == TokenType::BlockMappingKey) {\n        auto mapping{JSON::make_object()};\n        token = this->next_token();\n        if (!token.has_value()) [[unlikely]] {\n          throw YAMLParseError{this->lexer_->line(), this->lexer_->column(),\n                               \"Unexpected end after explicit key in flow\"};\n        }\n\n        std::string key_string;\n        if (token->type == TokenType::Scalar) {\n          key_string = std::string{token->value};\n          token = this->next_token();\n        } else {\n          // For non-scalar keys, parse the value and stringify\n          auto key_value{this->parse_value(token.value(),\n                                           JSON::ParseContext::Index,\n                                           element_index, empty_property_)};\n          key_string = this->json_to_key_string(key_value);\n          token = this->next_token();\n        }\n\n        if (token.has_value() && token->type == TokenType::BlockMappingValue) {\n          token = this->next_token();\n          if (token.has_value() && token->type != TokenType::SequenceEnd &&\n              token->type != TokenType::FlowEntry) {\n            auto value{this->parse_value(\n                token.value(), JSON::ParseContext::Property, 0, key_string)};\n            mapping.assign(key_string, std::move(value));\n            token = this->next_token();\n          } else {\n            mapping.assign(key_string, JSON{nullptr});\n          }\n        } else {\n          mapping.assign(key_string, JSON{nullptr});\n        }\n        result.push_back(std::move(mapping));\n        element_index++;\n        continue;\n      }\n\n      auto value{this->parse_value(token.value(), JSON::ParseContext::Index,\n                                   element_index, empty_property_)};\n      result.push_back(std::move(value));\n      element_index++;\n\n      token = this->next_token();\n      if (token.has_value() && token->type == TokenType::FlowEntry &&\n          token->compact_separator) {\n        found_compact_separator = true;\n      }\n      if (token.has_value() && token->type != TokenType::FlowEntry &&\n          token->type != TokenType::SequenceEnd) [[unlikely]] {\n        throw YAMLParseError{token->line, token->column,\n                             \"Missing comma in flow sequence\"};\n      }\n    }\n\n    const auto end_line{token.has_value() ? token->line : this->lexer_->line()};\n    const auto end_column{token.has_value() ? token->column\n                                            : this->lexer_->column()};\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Array, end_line,\n                          end_column, JSON::ParseContext::Root, 0,\n                          empty_property_);\n\n    if (this->roundtrip_ && found_compact_separator) {\n      this->roundtrip_->styles[this->pointer_stack_].compact_flow = true;\n    }\n\n    return result;\n  }\n\n  auto parse_block_sequence(const Token &start_token,\n                            const JSON::ParseContext context,\n                            const std::size_t index,\n                            const std::string &property,\n                            const std::uint64_t key_line = 0,\n                            const std::uint64_t key_column = 0) -> JSON {\n    this->invoke_callback(\n        JSON::ParsePhase::Pre, JSON::Type::Array,\n        this->effective_line(start_token, context, key_line),\n        this->effective_column(start_token, context, key_column), context,\n        index, property);\n\n    JSON result{JSON::make_array()};\n    std::size_t element_index{0};\n    const auto base_column{start_token.column};\n    const auto sequence_indent{\n        base_column > 0 ? static_cast<std::size_t>(base_column - 1) : 0uz};\n    this->detect_indent_width(key_column, base_column);\n    this->lexer_->set_block_indent(sequence_indent);\n    this->record_preceding_comments_for_index(0);\n\n    auto token{this->next_token()};\n    if (token.has_value() && token->line != start_token.line) {\n      this->record_indicator_comment_for_index(element_index);\n    }\n\n    if (token.has_value() && token->type != TokenType::BlockSequenceEntry &&\n        token->type != TokenType::StreamEnd &&\n        token->type != TokenType::DocumentEnd &&\n        token->type != TokenType::DocumentStart) {\n      auto value{this->parse_value(token.value(), JSON::ParseContext::Index,\n                                   element_index, empty_property_)};\n      result.push_back(std::move(value));\n      element_index++;\n      token = this->next_token();\n    } else if (token.has_value() &&\n               token->type == TokenType::BlockSequenceEntry &&\n               token->column == base_column) {\n      result.push_back(JSON{nullptr});\n      element_index++;\n    }\n\n    while (token.has_value() && token->type == TokenType::BlockSequenceEntry &&\n           token->column >= base_column) {\n      if (element_index > 0) {\n        this->record_inline_comment_for_index(element_index - 1);\n      }\n      this->record_preceding_comments_for_index(element_index);\n      this->lexer_->set_block_indent(sequence_indent);\n\n      if (token->column > base_column) {\n        if (token->column < base_column + 2) [[unlikely]] {\n          throw YAMLParseError{token->line, token->column,\n                               \"Wrong indentation for sequence entry\"};\n        }\n        auto value{this->parse_value(token.value(), JSON::ParseContext::Index,\n                                     element_index, empty_property_)};\n        result.push_back(std::move(value));\n        element_index++;\n        token = this->next_token();\n        continue;\n      }\n\n      const auto dash_line{token->line};\n      token = this->next_token();\n      if (token.has_value() && token->line != dash_line) {\n        this->record_indicator_comment_for_index(element_index);\n      }\n\n      if (!token.has_value() ||\n          (token->type == TokenType::BlockSequenceEntry &&\n           token->column == base_column) ||\n          token->type == TokenType::StreamEnd ||\n          token->type == TokenType::DocumentEnd) {\n        result.push_back(JSON{nullptr});\n      } else {\n        auto value{this->parse_value(token.value(), JSON::ParseContext::Index,\n                                     element_index, empty_property_)};\n        result.push_back(std::move(value));\n        token = this->next_token();\n      }\n\n      element_index++;\n    }\n\n    if (element_index > 0) {\n      this->record_inline_comment_for_index(element_index - 1);\n    }\n\n    std::uint64_t end_line{this->lexer_->line()};\n    std::uint64_t end_column{this->lexer_->column()};\n\n    if (token.has_value()) {\n      this->pending_tokens_.push_back(token.value());\n      end_line = token->line;\n      end_column = 0;\n    }\n\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Array, end_line,\n                          end_column, JSON::ParseContext::Root, 0,\n                          empty_property_);\n\n    return result;\n  }\n\n  auto parse_block_mapping(const Token &start_token,\n                           const JSON::ParseContext context,\n                           const std::size_t index, const std::string &property,\n                           const std::uint64_t key_line = 0,\n                           const std::uint64_t key_column = 0) -> JSON {\n    this->invoke_callback(\n        JSON::ParsePhase::Pre, JSON::Type::Object,\n        this->effective_line(start_token, context, key_line),\n        this->effective_column(start_token, context, key_column), context,\n        index, property);\n\n    JSON result{JSON::make_object()};\n    std::unordered_set<std::string> seen_keys;\n\n    auto token{start_token};\n    const auto mapping_indent{\n        start_token.column > 0\n            ? static_cast<std::size_t>(start_token.column - 1)\n            : 0uz};\n\n    while (true) {\n      this->lexer_->set_block_indent(mapping_indent);\n\n      if (token.type == TokenType::BlockMappingKey) {\n        auto next{this->next_token()};\n        assert(next.has_value());\n        token = next.value();\n      }\n\n      while (token.type == TokenType::Tag || token.type == TokenType::Anchor) {\n        auto next{this->next_token()};\n        assert(next.has_value());\n        token = next.value();\n      }\n\n      if (token.type != TokenType::Scalar &&\n          token.type != TokenType::BlockMappingValue) {\n        if (token.type == TokenType::DocumentEnd ||\n            token.type == TokenType::DocumentStart) {\n          this->pending_tokens_.push_back(token);\n        }\n        break;\n      }\n\n      std::string key;\n      std::uint64_t current_key_line{0};\n      std::uint64_t current_key_column{0};\n\n      if (token.type == TokenType::Scalar) {\n        key = token.value;\n        current_key_line = token.line;\n        current_key_column = token.column;\n\n        if (seen_keys.contains(key)) [[unlikely]] {\n          throw YAMLDuplicateKeyError{key, token.line, token.column};\n        }\n        seen_keys.insert(key);\n\n        auto next{this->next_token()};\n        if (!next.has_value() || next->type != TokenType::BlockMappingValue) {\n          result.assign(key, JSON{nullptr});\n          if (!next.has_value()) {\n            break;\n          }\n          token = next.value();\n          continue;\n        }\n        token = next.value();\n      }\n\n      if (token.type == TokenType::BlockMappingValue) {\n        auto next{this->next_token()};\n\n        if (!next.has_value() || next->type == TokenType::StreamEnd ||\n            next->type == TokenType::DocumentEnd ||\n            next->type == TokenType::DocumentStart) {\n          result.assign(key, JSON{nullptr});\n          if (!next.has_value()) {\n            break;\n          }\n          token = next.value();\n          continue;\n        }\n\n        if (next->type == TokenType::BlockMappingValue ||\n            next->type == TokenType::BlockMappingKey) {\n          if (key.empty() && next->type == TokenType::BlockMappingKey) {\n            token = next.value();\n            continue;\n          }\n          result.assign(key, JSON{nullptr});\n          token = next.value();\n          continue;\n        }\n\n        if (key.empty() && next->type == TokenType::Scalar) {\n          key = next->value;\n          if (seen_keys.contains(key)) [[unlikely]] {\n            throw YAMLDuplicateKeyError{key, next->line, next->column};\n          }\n          seen_keys.insert(key);\n          result.assign(key, JSON{nullptr});\n          auto next_after_key{this->next_token()};\n          assert(next_after_key.has_value());\n          token = next_after_key.value();\n          continue;\n        }\n\n        auto value{this->parse_value(next.value(), JSON::ParseContext::Property,\n                                     0, key, current_key_line,\n                                     current_key_column)};\n        result.assign(key, std::move(value));\n\n        auto after{this->next_token()};\n        if (!after.has_value()) {\n          break;\n        }\n        token = after.value();\n      }\n    }\n\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Object,\n                          this->lexer_->line(), this->lexer_->column(),\n                          JSON::ParseContext::Root, 0, empty_property_);\n\n    return result;\n  }\n\n  auto resolve_alias(const Token &token, const JSON::ParseContext context,\n                     const std::size_t index, const std::string &property,\n                     const std::uint64_t key_line = 0,\n                     const std::uint64_t key_column = 0) -> JSON {\n    const std::string anchor_name{token.value};\n    const auto iterator{this->anchors_.find(anchor_name)};\n\n    if (iterator == this->anchors_.end()) [[unlikely]] {\n      throw YAMLUnknownAnchorError{anchor_name, token.line, token.column};\n    }\n\n    const auto &anchored{iterator->second};\n    const auto alias_end_column{token.column +\n                                static_cast<std::uint64_t>(token.value.size())};\n\n    bool is_first_pre{true};\n    bool is_last_post{false};\n    std::size_t callback_index{0};\n    for (const auto &record : anchored.callbacks) {\n      is_last_post = (callback_index == anchored.callbacks.size() - 1 &&\n                      record.phase == JSON::ParsePhase::Post);\n\n      std::uint64_t callback_line{record.line};\n      std::uint64_t callback_column{record.column};\n      auto callback_context{record.context};\n      auto callback_idx{record.index};\n      std::string callback_property{record.property};\n\n      if (is_first_pre && record.phase == JSON::ParsePhase::Pre) {\n        if (context == JSON::ParseContext::Property && key_line > 0) {\n          callback_line = key_line;\n          callback_column = key_column;\n        }\n        callback_context = context;\n        callback_idx = index;\n        callback_property = property;\n        is_first_pre = false;\n      }\n\n      if (is_last_post) {\n        callback_line = token.line;\n        callback_column = alias_end_column;\n        callback_context = JSON::ParseContext::Root;\n        callback_idx = 0;\n        callback_property.clear();\n      }\n\n      this->invoke_callback(record.phase, record.type, callback_line,\n                            callback_column, callback_context, callback_idx,\n                            callback_property);\n      callback_index++;\n    }\n\n    return anchored.value;\n  }\n\n  auto next_token() -> std::optional<Token> {\n    std::optional<Token> result;\n    if (!this->pending_tokens_.empty()) {\n      result = this->pending_tokens_.front();\n      this->pending_tokens_.pop_front();\n      if (this->pending_tokens_.empty()) {\n        this->pending_token_position_.reset();\n      }\n    } else {\n      result = this->lexer_->next();\n    }\n    return result;\n  }\n\n  auto parse_block_mapping_from_first_key(\n      const Token &key_token, const JSON::ParseContext context,\n      const std::size_t index, const std::string &property,\n      const std::uint64_t parent_key_line = 0,\n      const std::uint64_t parent_key_column = 0,\n      const std::uint64_t node_start_column = 0) -> JSON {\n    this->invoke_callback(\n        JSON::ParsePhase::Pre, JSON::Type::Object,\n        this->effective_line(key_token, context, parent_key_line),\n        this->effective_column(key_token, context, parent_key_column), context,\n        index, property);\n\n    JSON result{JSON::make_object()};\n    std::unordered_set<std::string> seen_keys;\n    const auto base_column{node_start_column > 0 ? node_start_column\n                                                 : key_token.column};\n\n    this->detect_indent_width(parent_key_column, base_column);\n\n    std::string key{key_token.value};\n    std::uint64_t key_line{key_token.line};\n    std::uint64_t key_column{key_token.column};\n    const auto first_key_line{key_token.line};\n    seen_keys.insert(key);\n    this->record_key_scalar_style(key, key_token.scalar_style,\n                                  key_token.quoted_original);\n    this->record_preceding_comments_for_key(key);\n\n    this->lexer_->set_block_indent(static_cast<std::size_t>(base_column - 1));\n    auto next{this->next_token()};\n\n    if (!next.has_value() || next->type == TokenType::Scalar ||\n        next->type == TokenType::StreamEnd ||\n        next->type == TokenType::DocumentEnd) {\n      if (next.has_value() && next->type == TokenType::Scalar &&\n          (next->line == key_line || next->column != base_column)) {\n        this->record_inline_comment_for_key(key, next->line != key_line);\n        auto value{this->parse_value(next.value(), JSON::ParseContext::Property,\n                                     0, key, key_line, key_column)};\n        result.assign(key, std::move(value));\n        this->record_inline_comment_for_key(key);\n        next = this->next_token();\n      } else if (next.has_value() && next->type == TokenType::Scalar) {\n        this->record_inline_comment_for_key(key);\n        result.assign(key, JSON{nullptr});\n      } else {\n        this->invoke_callback(JSON::ParsePhase::Pre, JSON::Type::Null, key_line,\n                              key_column, JSON::ParseContext::Property, 0, key);\n        const auto null_post_column{key_column +\n                                    static_cast<std::uint64_t>(key.size())};\n        this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Null,\n                              key_line, null_post_column,\n                              JSON::ParseContext::Root, 0, empty_property_);\n        result.assign(key, JSON{nullptr});\n      }\n    } else if (next->type == TokenType::MappingStart ||\n               next->type == TokenType::SequenceStart ||\n               next->type == TokenType::BlockSequenceEntry ||\n               next->type == TokenType::Anchor ||\n               next->type == TokenType::Tag || next->type == TokenType::Alias) {\n      if (next->type == TokenType::BlockSequenceEntry && next->line == key_line)\n          [[unlikely]] {\n        throw YAMLParseError{\n            next->line, next->column,\n            \"Block sequence entry on same line as mapping key\"};\n      }\n      this->record_inline_comment_for_key(key, next->line != key_line);\n      auto value{this->parse_value(next.value(), JSON::ParseContext::Property,\n                                   0, key, key_line, key_column)};\n      result.assign(key, std::move(value));\n      next = this->next_token();\n      this->record_inline_comment_for_key(key);\n    } else {\n      result.assign(key, JSON{nullptr});\n    }\n\n    while (next.has_value() &&\n           (next->type == TokenType::Scalar ||\n            next->type == TokenType::BlockMappingKey ||\n            next->type == TokenType::Anchor || next->type == TokenType::Tag ||\n            next->type == TokenType::Alias)) {\n      if (this->document_start_line_ > 0 &&\n          first_key_line == this->document_start_line_ &&\n          next->line != this->document_start_line_) [[unlikely]] {\n        throw YAMLParseError{next->line, next->column,\n                             \"Block mapping continuation after document \"\n                             \"start line\"};\n      }\n      this->lexer_->set_block_indent(static_cast<std::size_t>(base_column - 1));\n\n      if (next->type == TokenType::BlockMappingKey) {\n        if (next->column < base_column) {\n          break;\n        }\n        next = this->next_token();\n        if (!next.has_value() || next->type != TokenType::Scalar) {\n          result.assign(\"\", JSON{nullptr});\n          next = this->next_token();\n          continue;\n        }\n\n        key = next->value;\n        key_line = next->line;\n        key_column = next->column;\n        this->record_key_scalar_style(key, next->scalar_style,\n                                      next->quoted_original);\n\n        if (seen_keys.contains(key)) [[unlikely]] {\n          throw YAMLDuplicateKeyError{key, next->line, next->column};\n        }\n        seen_keys.insert(key);\n\n        auto colon{this->next_token()};\n        if (!colon.has_value() || colon->type != TokenType::BlockMappingValue) {\n          result.assign(key, JSON{nullptr});\n          if (colon.has_value()) {\n            this->pending_tokens_.push_back(colon.value());\n          }\n          next = this->next_token();\n          continue;\n        }\n\n        next = this->next_token();\n        if (!next.has_value() || next->type == TokenType::StreamEnd ||\n            next->type == TokenType::DocumentEnd ||\n            next->type == TokenType::DocumentStart) {\n          result.assign(key, JSON{nullptr});\n          if (next.has_value()) {\n            this->pending_tokens_.push_back(next.value());\n          }\n          break;\n        }\n        if (next->type == TokenType::BlockMappingValue ||\n            next->type == TokenType::BlockMappingKey) {\n          result.assign(key, JSON{nullptr});\n        } else {\n          this->record_inline_comment_for_key(key, next->line != key_line);\n          this->lexer_->set_block_indent(\n              static_cast<std::size_t>(base_column - 1));\n          auto value{this->parse_value(next.value(),\n                                       JSON::ParseContext::Property, 0, key,\n                                       key_line, key_column)};\n          result.assign(key, std::move(value));\n          next = this->next_token();\n        }\n        continue;\n      }\n\n      auto effective_column{next->column};\n\n      if (next->type == TokenType::Anchor) {\n        next = this->next_token();\n        if (!next.has_value() || next->type != TokenType::Scalar) {\n          continue;\n        }\n      }\n\n      if (next->type == TokenType::Tag) {\n        next = this->next_token();\n        if (!next.has_value() || next->type != TokenType::Scalar) {\n          continue;\n        }\n      }\n\n      if (next->type == TokenType::Alias) {\n        if (effective_column != base_column) {\n          break;\n        }\n        const std::string alias_name{next->value};\n        const auto iterator{this->anchors_.find(alias_name)};\n        if (iterator == this->anchors_.end()) [[unlikely]] {\n          throw YAMLUnknownAnchorError{alias_name, next->line, next->column};\n        }\n        key = this->json_to_key_string(iterator->second.value);\n        key_line = next->line;\n        key_column = next->column;\n\n        if (seen_keys.contains(key)) [[unlikely]] {\n          throw YAMLDuplicateKeyError{key, next->line, next->column};\n        }\n        seen_keys.insert(key);\n\n        auto colon{this->next_token()};\n        if (!colon.has_value() || colon->type != TokenType::BlockMappingValue) {\n          result.assign(key, JSON{nullptr});\n          if (colon.has_value()) {\n            this->pending_tokens_.push_back(colon.value());\n          }\n          next = this->next_token();\n          continue;\n        }\n\n        next = this->next_token();\n\n        if (!next.has_value() || next->type == TokenType::Scalar) {\n          if (next.has_value()) {\n            auto value{this->parse_value(next.value(),\n                                         JSON::ParseContext::Property, 0, key,\n                                         key_line, key_column)};\n            result.assign(key, std::move(value));\n            next = this->next_token();\n          } else {\n            result.assign(key, JSON{nullptr});\n          }\n        } else if (next->type == TokenType::StreamEnd ||\n                   next->type == TokenType::DocumentEnd ||\n                   next->type == TokenType::DocumentStart) {\n          result.assign(key, JSON{nullptr});\n          break;\n        } else {\n          auto value{this->parse_value(next.value(),\n                                       JSON::ParseContext::Property, 0, key,\n                                       key_line, key_column)};\n          result.assign(key, std::move(value));\n          next = this->next_token();\n        }\n        continue;\n      }\n\n      if (effective_column != base_column) {\n        break;\n      }\n\n      this->record_inline_comment_for_key(key);\n      key = next->value;\n      key_line = next->line;\n      key_column = next->column;\n      this->record_key_scalar_style(key, next->scalar_style,\n                                    next->quoted_original);\n      this->record_preceding_comments_for_key(key);\n\n      if (next->multiline) [[unlikely]] {\n        throw YAMLParseError{next->line, next->column,\n                             \"Multi-line implicit mapping key\"};\n      }\n\n      if (seen_keys.contains(key)) [[unlikely]] {\n        throw YAMLDuplicateKeyError{key, next->line, next->column};\n      }\n      seen_keys.insert(key);\n\n      auto colon{this->next_token()};\n      if (!colon.has_value() || colon->type != TokenType::BlockMappingValue) {\n        if (colon.has_value()) {\n          this->pending_tokens_.push_back(colon.value());\n        }\n        break;\n      }\n\n      next = this->next_token();\n\n      if (!next.has_value() || next->type == TokenType::Scalar) {\n        if (next.has_value() &&\n            (next->line == key_line || next->column != base_column)) {\n          this->record_inline_comment_for_key(key, next->line != key_line);\n          auto after{this->next_token()};\n          if (after.has_value()) {\n            this->pending_tokens_.push_back(after.value());\n          }\n          auto value{this->parse_value(next.value(),\n                                       JSON::ParseContext::Property, 0, key,\n                                       key_line, key_column)};\n          result.assign(key, std::move(value));\n          next = this->next_token();\n        } else if (next.has_value()) {\n          this->record_inline_comment_for_key(key);\n          result.assign(key, JSON{nullptr});\n        } else {\n          result.assign(key, JSON{nullptr});\n        }\n      } else if (next->type == TokenType::StreamEnd ||\n                 next->type == TokenType::DocumentEnd ||\n                 next->type == TokenType::DocumentStart) {\n        result.assign(key, JSON{nullptr});\n        break;\n      } else {\n        this->record_inline_comment_for_key(key, next->line != key_line);\n        auto value{this->parse_value(next.value(), JSON::ParseContext::Property,\n                                     0, key, key_line, key_column)};\n        result.assign(key, std::move(value));\n        next = this->next_token();\n      }\n    }\n\n    this->record_inline_comment_for_key(key);\n\n    if (next.has_value() && next->type != TokenType::StreamEnd) {\n      this->pending_tokens_.push_back(next.value());\n      if (next->type == TokenType::DocumentStart) {\n        this->pending_token_position_ = next->position;\n      }\n    }\n\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Object,\n                          this->lexer_->line(), this->lexer_->column(),\n                          JSON::ParseContext::Root, 0, empty_property_);\n\n    return result;\n  }\n\n  auto record_preceding_comments_for_key(const std::string &key) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    auto comments{this->lexer_->take_preceding_comments()};\n    if (comments.empty()) {\n      return;\n    }\n    this->pointer_stack_.push_back(key);\n    this->roundtrip_->styles[this->pointer_stack_].comments_before =\n        std::move(comments);\n    this->pointer_stack_.pop_back();\n  }\n\n  auto record_inline_comment_for_key(const std::string &key,\n                                     const bool on_indicator = false) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    auto comment{this->lexer_->take_inline_comment()};\n    if (!comment.has_value()) {\n      return;\n    }\n    this->pointer_stack_.push_back(key);\n    if (on_indicator) {\n      this->roundtrip_->styles[this->pointer_stack_].comment_on_indicator =\n          std::move(comment);\n    } else {\n      this->roundtrip_->styles[this->pointer_stack_].comment_inline =\n          std::move(comment);\n    }\n    this->pointer_stack_.pop_back();\n  }\n\n  auto record_preceding_comments_for_index(const std::size_t index) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    auto comments{this->lexer_->take_preceding_comments()};\n    if (comments.empty()) {\n      return;\n    }\n    this->pointer_stack_.push_back(index);\n    this->roundtrip_->styles[this->pointer_stack_].comments_before =\n        std::move(comments);\n    this->pointer_stack_.pop_back();\n  }\n\n  auto record_inline_comment_for_index(const std::size_t index) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    auto comment{this->lexer_->take_inline_comment()};\n    if (!comment.has_value()) {\n      return;\n    }\n    this->pointer_stack_.push_back(index);\n    this->roundtrip_->styles[this->pointer_stack_].comment_inline =\n        std::move(comment);\n    this->pointer_stack_.pop_back();\n  }\n\n  auto record_indicator_comment_for_index(const std::size_t index) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    this->pointer_stack_.push_back(index);\n    auto indicator_comment{this->lexer_->take_inline_comment()};\n    this->roundtrip_->styles[this->pointer_stack_].comment_on_indicator =\n        std::move(indicator_comment).value_or(std::string{});\n    this->pointer_stack_.pop_back();\n  }\n\n  auto\n  register_anchored_null(const std::string_view anchor_name, const Token &token,\n                         const JSON::ParseContext context,\n                         const std::size_t index, const std::string &property,\n                         std::optional<std::string> &inline_comment) -> void {\n    this->recording_anchor_ = true;\n    this->current_anchor_callbacks_.clear();\n    JSON null_value{nullptr};\n    this->invoke_callback(JSON::ParsePhase::Pre, JSON::Type::Null, token.line,\n                          token.column, context, index, property);\n    this->invoke_callback(JSON::ParsePhase::Post, JSON::Type::Null, token.line,\n                          token.column, JSON::ParseContext::Root, 0,\n                          empty_property_);\n    this->recording_anchor_ = false;\n    this->anchors_.insert_or_assign(\n        std::string{anchor_name},\n        AnchoredValue{.value = null_value,\n                      .callbacks = std::move(this->current_anchor_callbacks_)});\n    this->current_anchor_callbacks_.clear();\n    if (this->roundtrip_) {\n      auto &style{this->roundtrip_->styles[this->pointer_stack_]};\n      style.anchor = std::string{anchor_name};\n      if (inline_comment.has_value()) {\n        style.comment_inline = std::move(inline_comment);\n      }\n    }\n  }\n\n  auto record_collection_style(const YAMLRoundTrip::CollectionStyle style)\n      -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n\n    this->roundtrip_->styles[this->pointer_stack_].collection = style;\n  }\n\n  auto record_scalar_style(const Token &token) -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n\n    auto &node_style{this->roundtrip_->styles[this->pointer_stack_]};\n\n    switch (token.scalar_style) {\n      case ScalarStyle::Plain:\n        node_style.scalar = YAMLRoundTrip::ScalarStyle::Plain;\n        if (token.multiline && !token.block_original.empty()) {\n          node_style.plain_content = std::string{token.block_original};\n        } else {\n          node_style.plain_content = std::string{token.value};\n        }\n        break;\n      case ScalarStyle::SingleQuoted:\n        node_style.scalar = YAMLRoundTrip::ScalarStyle::SingleQuoted;\n        if (!token.quoted_original.empty()) {\n          node_style.quoted_content = std::string{token.quoted_original};\n        }\n        break;\n      case ScalarStyle::DoubleQuoted:\n        node_style.scalar = YAMLRoundTrip::ScalarStyle::DoubleQuoted;\n        if (!token.quoted_original.empty()) {\n          node_style.quoted_content = std::string{token.quoted_original};\n        }\n        break;\n      case ScalarStyle::Literal:\n        node_style.scalar = YAMLRoundTrip::ScalarStyle::Literal;\n        break;\n      case ScalarStyle::Folded:\n        node_style.scalar = YAMLRoundTrip::ScalarStyle::Folded;\n        break;\n    }\n\n    if (token.scalar_style == ScalarStyle::Literal ||\n        token.scalar_style == ScalarStyle::Folded) {\n      switch (token.chomping) {\n        case BlockChomping::Clip:\n          node_style.chomping = YAMLRoundTrip::Chomping::Clip;\n          break;\n        case BlockChomping::Strip:\n          node_style.chomping = YAMLRoundTrip::Chomping::Strip;\n          break;\n        case BlockChomping::Keep:\n          node_style.chomping = YAMLRoundTrip::Chomping::Keep;\n          break;\n      }\n\n      node_style.explicit_indent = token.explicit_indent;\n      node_style.indent_before_chomping = token.indent_before_chomping;\n\n      if (!token.block_original.empty()) {\n        node_style.block_content = std::string{token.block_original};\n      }\n\n      auto block_comment{this->lexer_->take_block_scalar_comment()};\n      if (block_comment.has_value()) {\n        node_style.comment_inline = std::move(block_comment);\n      }\n    }\n  }\n\n  auto record_key_scalar_style(const std::string &key, const ScalarStyle style,\n                               const std::string_view quoted_original = {})\n      -> void {\n    if (!this->roundtrip_) {\n      return;\n    }\n    this->pointer_stack_.push_back(key);\n    switch (style) {\n      case ScalarStyle::Plain:\n        this->roundtrip_->key_styles[this->pointer_stack_] =\n            YAMLRoundTrip::ScalarStyle::Plain;\n        break;\n      case ScalarStyle::SingleQuoted:\n        this->roundtrip_->key_styles[this->pointer_stack_] =\n            YAMLRoundTrip::ScalarStyle::SingleQuoted;\n        break;\n      case ScalarStyle::DoubleQuoted:\n        this->roundtrip_->key_styles[this->pointer_stack_] =\n            YAMLRoundTrip::ScalarStyle::DoubleQuoted;\n        break;\n      default:\n        break;\n    }\n    if (!quoted_original.empty()) {\n      this->roundtrip_->key_quoted_contents[this->pointer_stack_] =\n          std::string{quoted_original};\n    }\n    this->pointer_stack_.pop_back();\n  }\n\n  auto detect_indent_width(const std::uint64_t parent_column,\n                           const std::uint64_t child_column) -> void {\n    if (!this->roundtrip_ || this->indent_width_detected_) {\n      return;\n    }\n    if (parent_column > 0 && child_column > parent_column) {\n      this->roundtrip_->indent_width =\n          static_cast<std::size_t>(child_column - parent_column);\n      this->indent_width_detected_ = true;\n    }\n  }\n\n  inline static const std::string empty_property_{};\n  Lexer *lexer_;\n  const JSON::ParseCallback *callback_;\n  YAMLRoundTrip *roundtrip_{nullptr};\n  Pointer pointer_stack_;\n  std::unordered_map<std::string, AnchoredValue> anchors_;\n  bool recording_anchor_{false};\n  bool indent_width_detected_{false};\n  std::vector<CallbackRecord> current_anchor_callbacks_;\n  std::deque<Token> pending_tokens_;\n  std::optional<std::size_t> pending_token_position_;\n  std::unordered_map<std::string, std::string> tag_directives_;\n  std::uint64_t document_start_line_{0};\n};\n\n} // namespace sourcemeta::core::yaml\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/stringify.h",
    "content": "#ifndef SOURCEMETA_CORE_YAML_STRINGIFY_H_\n#define SOURCEMETA_CORE_YAML_STRINGIFY_H_\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonpointer.h>\n#include <sourcemeta/core/yaml_roundtrip.h>\n\n#include <array>    // std::array\n#include <cassert>  // assert\n#include <charconv> // std::to_chars\n#include <cmath>    // std::modf\n#include <cstddef>  // std::size_t\n#include <iomanip>  // std::setprecision\n#include <ios>      // std::noshowpoint, std::fixed\n#include <ostream>  // std::basic_ostream\n#include <string>   // std::string\n\nnamespace sourcemeta::core::yaml {\n\nusing OutputStream = std::basic_ostream<JSON::Char, JSON::CharTraits>;\n\nstatic constexpr std::size_t INDENT_WIDTH{2};\nstatic constexpr std::array<char, 16> HEX_DIGITS{{'0', '1', '2', '3', '4', '5',\n                                                  '6', '7', '8', '9', 'a', 'b',\n                                                  'c', 'd', 'e', 'f'}};\n\ninline auto write_indent(OutputStream &stream, const std::size_t indent,\n                         const std::size_t width = INDENT_WIDTH) -> void {\n  for (std::size_t index{0}; index < indent * width; ++index) {\n    stream.put(' ');\n  }\n}\n\ninline auto looks_like_number(const std::string &value) -> bool {\n  std::size_t start{0};\n  if (value[0] == '-' || value[0] == '+') {\n    start = 1;\n  }\n\n  if (start >= value.size()) {\n    return false;\n  }\n\n  if (value.size() > start + 1 && value[start] == '0') {\n    const char second{value[start + 1]};\n    if (second == 'x' || second == 'X' || second == 'o' || second == 'O') {\n      return true;\n    }\n  }\n\n  bool has_digit{false};\n  bool has_dot{false};\n  bool has_exponent{false};\n\n  for (std::size_t index{start}; index < value.size(); ++index) {\n    const char character{value[index]};\n    if (character >= '0' && character <= '9') {\n      has_digit = true;\n    } else if (character == '.' && !has_dot && !has_exponent) {\n      has_dot = true;\n    } else if ((character == 'e' || character == 'E') && !has_exponent &&\n               has_digit) {\n      has_exponent = true;\n      if (index + 1 < value.size() &&\n          (value[index + 1] == '+' || value[index + 1] == '-')) {\n        ++index;\n      }\n    } else {\n      return false;\n    }\n  }\n\n  return has_digit;\n}\n\ninline auto needs_quoting(const std::string &value) -> bool {\n  if (value.empty()) {\n    return true;\n  }\n\n  if (value == \"null\" || value == \"Null\" || value == \"NULL\" || value == \"~\" ||\n      value == \"true\" || value == \"True\" || value == \"TRUE\" ||\n      value == \"false\" || value == \"False\" || value == \"FALSE\") {\n    return true;\n  }\n\n  if (value == \".inf\" || value == \".Inf\" || value == \".INF\" ||\n      value == \"+.inf\" || value == \"+.Inf\" || value == \"+.INF\" ||\n      value == \"-.inf\" || value == \"-.Inf\" || value == \"-.INF\" ||\n      value == \".nan\" || value == \".NaN\" || value == \".NAN\") {\n    return true;\n  }\n\n  if (value.size() >= 3 &&\n      ((value[0] == '-' && value[1] == '-' && value[2] == '-') ||\n       (value[0] == '.' && value[1] == '.' && value[2] == '.')) &&\n      (value.size() == 3 || value[3] == ' ' || value[3] == '\\t')) {\n    return true;\n  }\n\n  if (looks_like_number(value)) {\n    return true;\n  }\n\n  const char first{value[0]};\n\n  if (first == ',' || first == '[' || first == ']' || first == '{' ||\n      first == '}' || first == '#' || first == '&' || first == '*' ||\n      first == '!' || first == '|' || first == '>' || first == '\\'' ||\n      first == '\"' || first == '%' || first == '@' || first == '`') {\n    return true;\n  }\n\n  if (first == '-' || first == '?' || first == ':') {\n    if (value.size() == 1 || value[1] == ' ') {\n      return true;\n    }\n  }\n\n  if (value.front() == ' ' || value.back() == ' ') {\n    return true;\n  }\n\n  for (std::size_t index{0}; index < value.size(); ++index) {\n    const char character{value[index]};\n    if (character < ' ') {\n      return true;\n    }\n\n    if (character == ':' &&\n        (index + 1 >= value.size() || value[index + 1] == ' ')) {\n      return true;\n    }\n\n    if (character == ' ' && index + 1 < value.size() &&\n        value[index + 1] == '#') {\n      return true;\n    }\n  }\n\n  return false;\n}\n\ninline auto can_single_quote(const std::string &value) -> bool {\n  for (const char character : value) {\n    if (character < ' ' && character != '\\t') {\n      return false;\n    }\n  }\n\n  return true;\n}\n\ninline auto write_double_quoted(OutputStream &stream, const std::string &value)\n    -> void {\n  stream.put('\"');\n  for (const char character : value) {\n    switch (character) {\n      case '\"':\n        stream.write(\"\\\\\\\"\", 2);\n        break;\n      case '\\\\':\n        stream.write(\"\\\\\\\\\", 2);\n        break;\n      case '\\n':\n        stream.write(\"\\\\n\", 2);\n        break;\n      case '\\r':\n        stream.write(\"\\\\r\", 2);\n        break;\n      case '\\t':\n        stream.write(\"\\\\t\", 2);\n        break;\n      case '\\0':\n        stream.write(\"\\\\0\", 2);\n        break;\n      default:\n        if (character >= '\\x01' && character < '\\x20') {\n          const auto byte{static_cast<unsigned char>(character)};\n          stream.write(\"\\\\x\", 2);\n          stream.put(HEX_DIGITS[byte >> 4u]);\n          stream.put(HEX_DIGITS[byte & 0x0Fu]);\n        } else {\n          stream.put(character);\n        }\n        break;\n    }\n  }\n  stream.put('\"');\n}\n\ninline auto write_single_quoted(OutputStream &stream, const std::string &value)\n    -> void {\n  stream.put('\\'');\n  for (const char character : value) {\n    if (character == '\\'') {\n      stream.write(\"''\", 2);\n    } else {\n      stream.put(character);\n    }\n  }\n  stream.put('\\'');\n}\n\ninline auto write_string(OutputStream &stream, const std::string &value)\n    -> void {\n  if (needs_quoting(value)) {\n    write_double_quoted(stream, value);\n  } else {\n    stream.write(value.data(), static_cast<std::streamsize>(value.size()));\n  }\n}\n\ninline auto write_block_scalar(\n    OutputStream &stream, const std::string &value, const std::size_t indent,\n    const YAMLRoundTrip::ScalarStyle style,\n    const YAMLRoundTrip::Chomping chomping,\n    const std::optional<std::string> &header_comment = std::nullopt,\n    const std::size_t indent_width = INDENT_WIDTH,\n    const std::size_t explicit_indent = 0,\n    const bool indent_before_chomping = false) -> void {\n  stream.put(style == YAMLRoundTrip::ScalarStyle::Literal ? '|' : '>');\n  if (indent_before_chomping && explicit_indent > 0) {\n    stream.put(static_cast<char>('0' + explicit_indent));\n  }\n  if (chomping == YAMLRoundTrip::Chomping::Strip) {\n    stream.put('-');\n  } else if (chomping == YAMLRoundTrip::Chomping::Keep) {\n    stream.put('+');\n  }\n  if (!indent_before_chomping && explicit_indent > 0) {\n    stream.put(static_cast<char>('0' + explicit_indent));\n  }\n  if (header_comment.has_value()) {\n    stream.put(' ');\n    const auto &comment{header_comment.value()};\n    stream.write(comment.data(), static_cast<std::streamsize>(comment.size()));\n  }\n  stream.put('\\n');\n\n  std::size_t position{0};\n  while (position < value.size()) {\n    auto line_end{value.find('\\n', position)};\n    if (line_end == std::string::npos) {\n      write_indent(stream, indent, indent_width);\n      stream.write(value.data() + position,\n                   static_cast<std::streamsize>(value.size() - position));\n      stream.put('\\n');\n      break;\n    }\n\n    if (line_end > position) {\n      write_indent(stream, indent, indent_width);\n    }\n    stream.write(value.data() + position,\n                 static_cast<std::streamsize>(line_end - position));\n    stream.put('\\n');\n    position = line_end + 1;\n  }\n}\n\ninline auto write_string_with_style(OutputStream &stream,\n                                    const std::string &value,\n                                    const YAMLRoundTrip *roundtrip,\n                                    const Pointer &pointer) -> void {\n  if (roundtrip) {\n    const auto match{roundtrip->styles.find(pointer)};\n    if (match != roundtrip->styles.end() && match->second.scalar.has_value()) {\n      if (match->second.quoted_content.has_value()) {\n        const auto &raw{match->second.quoted_content.value()};\n        const auto quote_char{match->second.scalar.value() ==\n                                      YAMLRoundTrip::ScalarStyle::SingleQuoted\n                                  ? '\\''\n                                  : '\"'};\n        stream.put(quote_char);\n        stream.write(raw.data(), static_cast<std::streamsize>(raw.size()));\n        stream.put(quote_char);\n        return;\n      }\n      switch (match->second.scalar.value()) {\n        case YAMLRoundTrip::ScalarStyle::SingleQuoted:\n          if (can_single_quote(value)) {\n            write_single_quoted(stream, value);\n            return;\n          }\n          break;\n        case YAMLRoundTrip::ScalarStyle::DoubleQuoted:\n          write_double_quoted(stream, value);\n          return;\n        default:\n          break;\n      }\n    }\n  }\n\n  write_string(stream, value);\n}\n\ninline auto write_key_string(OutputStream &stream, const std::string &key,\n                             const YAMLRoundTrip *roundtrip,\n                             const Pointer &pointer) -> void {\n  if (roundtrip) {\n    const auto quoted_match{roundtrip->key_quoted_contents.find(pointer)};\n    if (quoted_match != roundtrip->key_quoted_contents.end()) {\n      const auto style_match{roundtrip->key_styles.find(pointer)};\n      const auto quote_char{style_match != roundtrip->key_styles.end() &&\n                                    style_match->second ==\n                                        YAMLRoundTrip::ScalarStyle::SingleQuoted\n                                ? '\\''\n                                : '\"'};\n      stream.put(quote_char);\n      const auto &raw{quoted_match->second};\n      stream.write(raw.data(), static_cast<std::streamsize>(raw.size()));\n      stream.put(quote_char);\n      return;\n    }\n    const auto match{roundtrip->key_styles.find(pointer)};\n    if (match != roundtrip->key_styles.end()) {\n      switch (match->second) {\n        case YAMLRoundTrip::ScalarStyle::Plain:\n          stream.write(key.data(), static_cast<std::streamsize>(key.size()));\n          return;\n        case YAMLRoundTrip::ScalarStyle::SingleQuoted:\n          if (can_single_quote(key)) {\n            write_single_quoted(stream, key);\n            return;\n          }\n          break;\n        case YAMLRoundTrip::ScalarStyle::DoubleQuoted:\n          write_double_quoted(stream, key);\n          return;\n        default:\n          break;\n      }\n    }\n  }\n  write_string(stream, key);\n}\n\n// Forward declarations for recursive flow collection writing\ninline auto write_flow_mapping(OutputStream &stream, const JSON &value,\n                               const YAMLRoundTrip *roundtrip, Pointer &pointer)\n    -> void;\ninline auto write_flow_sequence(OutputStream &stream, const JSON &value,\n                                const YAMLRoundTrip *roundtrip,\n                                Pointer &pointer) -> void;\n\ninline auto write_inline_value(OutputStream &stream, const JSON &value,\n                               const YAMLRoundTrip *roundtrip, Pointer &pointer)\n    -> void {\n  if (roundtrip) {\n    const auto alias_match{roundtrip->aliases.find(pointer)};\n    if (alias_match != roundtrip->aliases.end()) {\n      stream.put('*');\n      const auto &name{alias_match->second};\n      stream.write(name.data(), static_cast<std::streamsize>(name.size()));\n      return;\n    }\n\n    const auto style_match{roundtrip->styles.find(pointer)};\n    if (style_match != roundtrip->styles.end() &&\n        style_match->second.scalar.has_value() &&\n        style_match->second.scalar.value() ==\n            YAMLRoundTrip::ScalarStyle::Plain &&\n        style_match->second.plain_content.has_value()) {\n      const auto &content{style_match->second.plain_content.value()};\n      stream.write(content.data(),\n                   static_cast<std::streamsize>(content.size()));\n      return;\n    }\n  }\n  switch (value.type()) {\n    case JSON::Type::Null:\n      stream.write(\"null\", 4);\n      break;\n    case JSON::Type::Boolean:\n      if (value.to_boolean()) {\n        stream.write(\"true\", 4);\n      } else {\n        stream.write(\"false\", 5);\n      }\n      break;\n    case JSON::Type::Integer: {\n      std::array<char, 20> buffer{};\n      const auto [end_pointer, error_code] = std::to_chars(\n          buffer.data(), buffer.data() + buffer.size(), value.to_integer());\n      stream.write(buffer.data(),\n                   static_cast<std::streamsize>(end_pointer - buffer.data()));\n    } break;\n    case JSON::Type::Real: {\n      const auto real{value.to_real()};\n      if (real == 0.0) {\n        stream.write(\"0.0\", 3);\n      } else {\n        const auto flags{stream.flags()};\n        const auto precision{stream.precision()};\n        double integer_part;\n        if (std::modf(real, &integer_part) == 0.0) {\n          stream << std::fixed << std::setprecision(1) << real;\n        } else {\n          stream << std::noshowpoint << real;\n        }\n        stream.flags(flags);\n        stream.precision(precision);\n      }\n    } break;\n    case JSON::Type::Decimal:\n      stream << value.to_decimal().to_scientific_string();\n      break;\n    case JSON::Type::String:\n      write_string_with_style(stream, value.to_string(), roundtrip, pointer);\n      break;\n    case JSON::Type::Object:\n      if (value.empty()) {\n        stream.write(\"{}\", 2);\n      } else {\n        write_flow_mapping(stream, value, roundtrip, pointer);\n      }\n      break;\n    case JSON::Type::Array:\n      if (value.empty()) {\n        stream.write(\"[]\", 2);\n      } else {\n        write_flow_sequence(stream, value, roundtrip, pointer);\n      }\n      break;\n  }\n}\n\ninline auto is_implicit_null(const JSON &value, const YAMLRoundTrip *roundtrip,\n                             const Pointer &pointer) -> bool {\n  if (!roundtrip || !value.is_null()) {\n    return false;\n  }\n  if (roundtrip->aliases.contains(pointer)) {\n    return false;\n  }\n  const auto match{roundtrip->styles.find(pointer)};\n  if (match == roundtrip->styles.end()) {\n    return true;\n  }\n  return !match->second.scalar.has_value();\n}\n\ninline auto write_flow_anchor(OutputStream &stream,\n                              const YAMLRoundTrip *roundtrip,\n                              const Pointer &pointer) -> void {\n  if (!roundtrip) {\n    return;\n  }\n  const auto match{roundtrip->styles.find(pointer)};\n  if (match != roundtrip->styles.end() && match->second.anchor.has_value()) {\n    stream.put('&');\n    const auto &anchor_name{match->second.anchor.value()};\n    stream.write(anchor_name.data(),\n                 static_cast<std::streamsize>(anchor_name.size()));\n    stream.put(' ');\n  }\n}\n\ninline auto write_flow_mapping(OutputStream &stream, const JSON &value,\n                               const YAMLRoundTrip *roundtrip, Pointer &pointer)\n    -> void {\n  bool compact{false};\n  if (roundtrip) {\n    const auto match{roundtrip->styles.find(pointer)};\n    if (match != roundtrip->styles.end()) {\n      compact = match->second.compact_flow;\n    }\n  }\n  stream.put('{');\n  bool first{true};\n  for (const auto &entry : value.as_object()) {\n    if (!first) {\n      if (compact) {\n        stream.put(',');\n      } else {\n        stream.write(\", \", 2);\n      }\n    }\n    first = false;\n    pointer.push_back(entry.first);\n    write_key_string(stream, entry.first, roundtrip, pointer);\n    stream.write(\": \", 2);\n    if (!is_implicit_null(entry.second, roundtrip, pointer)) {\n      write_flow_anchor(stream, roundtrip, pointer);\n      write_inline_value(stream, entry.second, roundtrip, pointer);\n    }\n    pointer.pop_back();\n  }\n  stream.put('}');\n}\n\ninline auto write_flow_sequence(OutputStream &stream, const JSON &value,\n                                const YAMLRoundTrip *roundtrip,\n                                Pointer &pointer) -> void {\n  bool compact{false};\n  if (roundtrip) {\n    const auto match{roundtrip->styles.find(pointer)};\n    if (match != roundtrip->styles.end()) {\n      compact = match->second.compact_flow;\n    }\n  }\n  stream.put('[');\n  bool first{true};\n  std::size_t item_index{0};\n  for (const auto &item : value.as_array()) {\n    if (!first) {\n      if (compact) {\n        stream.put(',');\n      } else {\n        stream.write(\", \", 2);\n      }\n    }\n    first = false;\n    pointer.push_back(item_index);\n    write_flow_anchor(stream, roundtrip, pointer);\n    write_inline_value(stream, item, roundtrip, pointer);\n    pointer.pop_back();\n    item_index++;\n  }\n  stream.put(']');\n}\n\ninline auto write_block_mapping(OutputStream &stream, const JSON &value,\n                                std::size_t indent, bool skip_first_indent,\n                                const YAMLRoundTrip *roundtrip,\n                                Pointer &pointer) -> void;\ninline auto write_block_sequence(OutputStream &stream, const JSON &value,\n                                 std::size_t indent, bool skip_first_indent,\n                                 const YAMLRoundTrip *roundtrip,\n                                 Pointer &pointer) -> void;\n\ninline auto emit_inline_comment(OutputStream &stream,\n                                const YAMLRoundTrip::NodeStyle *style) -> void {\n  if (style && style->comment_inline.has_value()) {\n    stream.put(' ');\n    const auto &comment{style->comment_inline.value()};\n    stream.write(comment.data(), static_cast<std::streamsize>(comment.size()));\n  }\n}\n\ninline auto write_node(OutputStream &stream, const JSON &value,\n                       const std::size_t indent, const bool skip_first_indent,\n                       const YAMLRoundTrip *roundtrip, Pointer &pointer)\n    -> void {\n  const YAMLRoundTrip::NodeStyle *node_style{nullptr};\n  if (roundtrip) {\n    const auto style_match{roundtrip->styles.find(pointer)};\n    if (style_match != roundtrip->styles.end()) {\n      node_style = &style_match->second;\n    }\n    const auto alias_match{roundtrip->aliases.find(pointer)};\n    if (alias_match != roundtrip->aliases.end()) {\n      stream.put('*');\n      const auto &name{alias_match->second};\n      stream.write(name.data(), static_cast<std::streamsize>(name.size()));\n      emit_inline_comment(stream, node_style);\n      stream.put('\\n');\n      return;\n    }\n  }\n\n  bool has_anchor{false};\n  if (node_style && node_style->anchor.has_value()) {\n    stream.put('&');\n    const auto &name{node_style->anchor.value()};\n    stream.write(name.data(), static_cast<std::streamsize>(name.size()));\n    has_anchor = true;\n  }\n\n  const bool flow{node_style && node_style->collection.has_value() &&\n                  node_style->collection.value() ==\n                      YAMLRoundTrip::CollectionStyle::Flow};\n\n  if (value.is_object() && !value.empty()) {\n    if (flow) {\n      if (has_anchor) {\n        stream.put(' ');\n      }\n      write_flow_mapping(stream, value, roundtrip, pointer);\n      emit_inline_comment(stream, node_style);\n      stream.put('\\n');\n    } else {\n      if (has_anchor) {\n        emit_inline_comment(stream, node_style);\n        stream.put('\\n');\n      }\n      write_block_mapping(stream, value, indent,\n                          has_anchor ? false : skip_first_indent, roundtrip,\n                          pointer);\n    }\n  } else if (value.is_array() && !value.empty()) {\n    if (flow) {\n      if (has_anchor) {\n        stream.put(' ');\n      }\n      write_flow_sequence(stream, value, roundtrip, pointer);\n      emit_inline_comment(stream, node_style);\n      stream.put('\\n');\n    } else {\n      if (has_anchor) {\n        emit_inline_comment(stream, node_style);\n        stream.put('\\n');\n      }\n      write_block_sequence(stream, value, indent,\n                           has_anchor ? false : skip_first_indent, roundtrip,\n                           pointer);\n    }\n  } else if (node_style && value.is_string() &&\n             node_style->scalar.has_value() &&\n             (node_style->scalar.value() ==\n                  YAMLRoundTrip::ScalarStyle::Literal ||\n              node_style->scalar.value() ==\n                  YAMLRoundTrip::ScalarStyle::Folded)) {\n    if (has_anchor) {\n      stream.put(' ');\n    }\n    const auto chomping{\n        node_style->chomping.value_or(YAMLRoundTrip::Chomping::Clip)};\n    const auto &content{node_style->block_content.has_value()\n                            ? node_style->block_content.value()\n                            : value.to_string()};\n    write_block_scalar(stream, content, indent, node_style->scalar.value(),\n                       chomping, node_style->comment_inline,\n                       roundtrip->indent_width, node_style->explicit_indent,\n                       node_style->indent_before_chomping);\n  } else {\n    if (has_anchor) {\n      stream.put(' ');\n    }\n    write_inline_value(stream, value, roundtrip, pointer);\n    emit_inline_comment(stream, node_style);\n    stream.put('\\n');\n  }\n}\n\ninline auto write_block_mapping(OutputStream &stream, const JSON &value,\n                                const std::size_t indent,\n                                const bool skip_first_indent,\n                                const YAMLRoundTrip *roundtrip,\n                                Pointer &pointer) -> void {\n  assert(value.is_object() && !value.empty());\n  const auto width{roundtrip ? roundtrip->indent_width : INDENT_WIDTH};\n  bool first{true};\n  for (const auto &entry : value.as_object()) {\n    pointer.push_back(entry.first);\n\n    const YAMLRoundTrip::NodeStyle *entry_style{nullptr};\n    bool entry_is_alias{false};\n    if (roundtrip) {\n      entry_is_alias = roundtrip->aliases.contains(pointer);\n      const auto style_match{roundtrip->styles.find(pointer)};\n      if (style_match != roundtrip->styles.end()) {\n        entry_style = &style_match->second;\n      }\n    }\n\n    if (!first || !skip_first_indent) {\n      if (entry_style && !entry_style->comments_before.empty()) {\n        for (const auto &comment : entry_style->comments_before) {\n          if (comment.empty()) {\n            stream.put('\\n');\n          } else {\n            write_indent(stream, indent, width);\n            stream.write(comment.data(),\n                         static_cast<std::streamsize>(comment.size()));\n            stream.put('\\n');\n          }\n        }\n      }\n      write_indent(stream, indent, width);\n    }\n    first = false;\n\n    write_key_string(stream, entry.first, roundtrip, pointer);\n    stream.put(':');\n\n    const bool implicit_null{\n        roundtrip && entry.second.is_null() && !entry_is_alias &&\n        (!entry_style || !entry_style->scalar.has_value())};\n    if (implicit_null) {\n      if (entry_style && entry_style->anchor.has_value()) {\n        stream.put(' ');\n        stream.put('&');\n        const auto &name{entry_style->anchor.value()};\n        stream.write(name.data(), static_cast<std::streamsize>(name.size()));\n      }\n      emit_inline_comment(stream, entry_style);\n      stream.put('\\n');\n    } else {\n      bool has_indicator_comment{false};\n      if (entry_style && entry_style->comment_on_indicator.has_value()) {\n        has_indicator_comment = true;\n        stream.put(' ');\n        const auto &comment{entry_style->comment_on_indicator.value()};\n        stream.write(comment.data(),\n                     static_cast<std::streamsize>(comment.size()));\n        stream.put('\\n');\n        write_indent(stream, indent + 1, width);\n      }\n      if (!has_indicator_comment) {\n        const bool has_prefix{entry_is_alias ||\n                              (entry_style && entry_style->anchor.has_value())};\n        const bool entry_flow{entry_style &&\n                              entry_style->collection.has_value() &&\n                              entry_style->collection.value() ==\n                                  YAMLRoundTrip::CollectionStyle::Flow};\n        const bool nested{\n            (entry.second.is_object() || entry.second.is_array()) &&\n            !entry.second.empty() && !entry_flow && !has_prefix};\n        if (nested) {\n          emit_inline_comment(stream, entry_style);\n          stream.put('\\n');\n        } else {\n          stream.put(' ');\n        }\n      }\n      write_node(stream, entry.second, indent + 1,\n                 has_indicator_comment ? true : false, roundtrip, pointer);\n    }\n\n    pointer.pop_back();\n  }\n}\n\ninline auto write_block_sequence(OutputStream &stream, const JSON &value,\n                                 const std::size_t indent,\n                                 const bool skip_first_indent,\n                                 const YAMLRoundTrip *roundtrip,\n                                 Pointer &pointer) -> void {\n  assert(value.is_array() && !value.empty());\n  const auto width{roundtrip ? roundtrip->indent_width : INDENT_WIDTH};\n  bool first{true};\n  std::size_t item_index{0};\n  for (const auto &item : value.as_array()) {\n    pointer.push_back(item_index);\n\n    // Single lookup for alias and style per item\n    const YAMLRoundTrip::NodeStyle *item_style{nullptr};\n    bool item_is_alias{false};\n    if (roundtrip) {\n      item_is_alias = roundtrip->aliases.contains(pointer);\n      const auto style_match{roundtrip->styles.find(pointer)};\n      if (style_match != roundtrip->styles.end()) {\n        item_style = &style_match->second;\n      }\n    }\n\n    if (!first || !skip_first_indent) {\n      if (item_style && !item_style->comments_before.empty()) {\n        for (const auto &comment : item_style->comments_before) {\n          if (comment.empty()) {\n            stream.put('\\n');\n          } else {\n            write_indent(stream, indent, width);\n            stream.write(comment.data(),\n                         static_cast<std::streamsize>(comment.size()));\n            stream.put('\\n');\n          }\n        }\n      }\n      write_indent(stream, indent, width);\n    }\n    first = false;\n\n    const bool implicit_null{roundtrip && item.is_null() && !item_is_alias &&\n                             (!item_style || !item_style->scalar.has_value())};\n    if (implicit_null) {\n      stream.put('-');\n      if (item_style) {\n        if (item_style->anchor.has_value()) {\n          stream.put(' ');\n          stream.put('&');\n          const auto &name{item_style->anchor.value()};\n          stream.write(name.data(), static_cast<std::streamsize>(name.size()));\n        }\n        if (item_style->comment_on_indicator.has_value() &&\n            !item_style->comment_on_indicator.value().empty()) {\n          stream.put(' ');\n          const auto &comment{item_style->comment_on_indicator.value()};\n          stream.write(comment.data(),\n                       static_cast<std::streamsize>(comment.size()));\n        }\n      }\n      emit_inline_comment(stream, item_style);\n      stream.put('\\n');\n    } else {\n      bool has_indicator{false};\n      if (item_style && item_style->comment_on_indicator.has_value()) {\n        has_indicator = true;\n        const auto &comment{item_style->comment_on_indicator.value()};\n        if (comment.empty()) {\n          stream.put('-');\n        } else {\n          stream.write(\"- \", 2);\n          stream.write(comment.data(),\n                       static_cast<std::streamsize>(comment.size()));\n        }\n        stream.put('\\n');\n        write_indent(stream, indent + 1, width);\n      }\n      if (!has_indicator) {\n        stream.write(\"- \", 2);\n      }\n      write_node(stream, item, indent + 1, true, roundtrip, pointer);\n    }\n\n    pointer.pop_back();\n    item_index++;\n  }\n}\n\ntemplate <template <typename T> typename Allocator>\nauto stringify_yaml(const JSON &document, OutputStream &stream,\n                    const YAMLRoundTrip *roundtrip = nullptr) -> void {\n  if (roundtrip) {\n    for (const auto &comment : roundtrip->leading_comments) {\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n      stream.put('\\n');\n    }\n  }\n\n  if (roundtrip && roundtrip->explicit_document_start) {\n    stream.write(\"---\", 3);\n    if (roundtrip->document_start_comment.has_value()) {\n      stream.put(' ');\n      const auto &comment{roundtrip->document_start_comment.value()};\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n    }\n    stream.put('\\n');\n    for (const auto &comment : roundtrip->post_start_comments) {\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n      stream.put('\\n');\n    }\n  }\n\n  Pointer pointer;\n  if (!is_implicit_null(document, roundtrip, pointer)) {\n    write_node(stream, document, 0, false, roundtrip, pointer);\n  }\n\n  if (roundtrip) {\n    for (const auto &comment : roundtrip->pre_end_comments) {\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n      stream.put('\\n');\n    }\n  }\n\n  if (roundtrip && roundtrip->explicit_document_end) {\n    stream.write(\"...\", 3);\n    if (roundtrip->document_end_comment.has_value()) {\n      stream.put(' ');\n      const auto &comment{roundtrip->document_end_comment.value()};\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n    }\n    stream.put('\\n');\n  }\n\n  if (roundtrip) {\n    for (const auto &comment : roundtrip->trailing_comments) {\n      stream.write(comment.data(),\n                   static_cast<std::streamsize>(comment.size()));\n      stream.put('\\n');\n    }\n  }\n}\n\n} // namespace sourcemeta::core::yaml\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/core/yaml/yaml.cc",
    "content": "#include \"lexer.h\"\n#include \"parser.h\"\n#include \"stringify.h\"\n\n#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/json_error.h>\n#include <sourcemeta/core/yaml.h>\n\nnamespace sourcemeta::core {\n\nauto parse_yaml(std::basic_istream<JSON::Char, JSON::CharTraits> &stream)\n    -> JSON {\n  const auto start_pos{stream.tellg()};\n  const auto input{read_to_string(stream)};\n\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, nullptr};\n  auto result{parser.parse()};\n\n  const auto consumed{static_cast<std::streamoff>(parser.position())};\n  stream.clear();\n  stream.seekg(start_pos + consumed);\n\n  return result;\n}\n\nauto parse_yaml(const JSON::String &input) -> JSON {\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, nullptr};\n  return parser.parse();\n}\n\nauto read_yaml(const std::filesystem::path &path) -> JSON {\n  const auto input{read_file_to_string(path)};\n\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, nullptr};\n  auto result{parser.parse()};\n\n  parser.validate_end_of_stream();\n\n  return result;\n}\n\nauto parse_yaml(std::basic_istream<JSON::Char, JSON::CharTraits> &stream,\n                JSON &output, const JSON::ParseCallback &callback) -> void {\n  const auto start_pos{stream.tellg()};\n  const auto input{read_to_string(stream)};\n\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, &callback};\n  output = parser.parse();\n\n  const auto consumed{static_cast<std::streamoff>(parser.position())};\n  stream.clear();\n  stream.seekg(start_pos + consumed);\n}\n\nauto parse_yaml(const JSON::String &input, JSON &output,\n                const JSON::ParseCallback &callback) -> void {\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, &callback};\n  output = parser.parse();\n}\n\nauto read_yaml(const std::filesystem::path &path, JSON &output,\n               const JSON::ParseCallback &callback) -> void {\n  const auto input{read_file_to_string(path)};\n\n  yaml::Lexer lexer{input};\n  yaml::Parser parser{&lexer, &callback};\n  output = parser.parse();\n\n  parser.validate_end_of_stream();\n}\n\nauto read_yaml_or_json(const std::filesystem::path &path) -> JSON {\n  const auto extension{path.extension()};\n  if (extension == \".yaml\" || extension == \".yml\") {\n    return read_yaml(path);\n  } else if (extension == \".json\") {\n    return read_json(path);\n  }\n\n  try {\n    return read_json(path);\n  } catch (const JSONParseError &) {\n    return read_yaml(path);\n  }\n}\n\nauto read_yaml_or_json(const std::filesystem::path &path, JSON &output,\n                       const JSON::ParseCallback &callback) -> void {\n  const auto extension{path.extension()};\n  if (extension == \".yaml\" || extension == \".yml\") {\n    read_yaml(path, output, callback);\n    return;\n  } else if (extension == \".json\") {\n    read_json(path, output, callback);\n    return;\n  }\n\n  try {\n    read_json(path, output, callback);\n  } catch (const JSONParseError &) {\n    read_yaml(path, output, callback);\n  }\n}\n\nauto parse_yaml(const JSON::String &input, YAMLRoundTrip &roundtrip) -> JSON {\n  roundtrip = {};\n  yaml::Lexer lexer{input, true};\n  yaml::Parser parser{&lexer, nullptr, &roundtrip};\n  return parser.parse();\n}\n\nauto parse_yaml(const JSON::String &input, YAMLRoundTrip &roundtrip,\n                JSON &output, const JSON::ParseCallback &callback) -> void {\n  roundtrip = {};\n  yaml::Lexer lexer{input, true};\n  yaml::Parser parser{&lexer, &callback, &roundtrip};\n  output = parser.parse();\n}\n\nauto stringify_yaml(const JSON &document,\n                    std::basic_ostream<JSON::Char, JSON::CharTraits> &stream)\n    -> void {\n  yaml::stringify_yaml<JSON::Allocator>(document, stream);\n}\n\nauto stringify_yaml(const JSON &document,\n                    std::basic_ostream<JSON::Char, JSON::CharTraits> &stream,\n                    const YAMLRoundTrip &roundtrip) -> void {\n  yaml::stringify_yaml<JSON::Allocator>(document, stream, &roundtrip);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/extension/editorschema/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME editorschema\n  SOURCES editorschema.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME editorschema)\nendif()\n\ntarget_link_libraries(sourcemeta_core_editorschema PUBLIC sourcemeta::core::jsonschema)\n"
  },
  {
    "path": "vendor/core/src/extension/editorschema/editorschema.cc",
    "content": "#include <sourcemeta/core/editorschema.h>\n\n#include <cassert> // assert\n#include <map>     // std::map\n\nnamespace {\n\n// Note that we don't take into account dynamic resources behind conditionals,\n// etc. We probably should, but the complexity of this transformation would\n// massively grow, plus such case is quite uncommon in practice.\n// See https://arxiv.org/abs/2503.11288 for an academic study of this topic\nauto top_dynamic_anchor_location(\n    const sourcemeta::core::SchemaFrame &frame,\n    const sourcemeta::core::WeakPointer &current,\n    const std::string_view fragment,\n    const sourcemeta::core::JSON::String &default_uri)\n    -> std::optional<\n        std::reference_wrapper<const sourcemeta::core::WeakPointer>> {\n  // Get the location object of where we are at the moment\n  const auto uri{frame.uri(current)};\n  assert(uri.has_value());\n  const auto match{frame.traverse(uri.value().get())};\n  assert(match.has_value());\n  const auto &location{match.value().get()};\n\n  // Try to locate an anchor with the given name on the current base\n  assert(!fragment.starts_with('#'));\n  sourcemeta::core::JSON::String anchor_uri{location.base};\n  anchor_uri += '#';\n  anchor_uri += fragment;\n  const auto anchor{frame.traverse(anchor_uri)};\n\n  if (location.parent.has_value()) {\n    // If there is a parent resource, keep looking there, but update the default\n    // if the current resource has the dynamic anchor we want\n    return top_dynamic_anchor_location(frame, location.parent.value(), fragment,\n                                       anchor.has_value() ? anchor_uri\n                                                          : default_uri);\n\n    // If we are at the top of the schema and it declares the dynamic anchor, we\n    // should use that\n  } else if (anchor.has_value()) {\n    return std::cref(anchor.value().get().pointer);\n\n    // Otherwise, if we are at the top and the dynamic anchor is not there, use\n    // the default we have so far\n  } else {\n    const auto default_location{frame.traverse(default_uri)};\n    assert(default_location.has_value());\n    return std::cref(default_location.value().get().pointer);\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\n// Collected information about a reference to modify\nstruct ReferenceChange {\n  Pointer pointer;\n  JSON::String new_value;\n  JSON::String keyword;\n  bool rename_to_ref;\n};\n\n// Collected information about a subschema to modify\nstruct SubschemaChange {\n  Pointer pointer;\n  SchemaBaseDialect base_dialect;\n  bool add_schema_declaration;\n  bool erase_2020_12_keywords;\n  bool erase_2019_09_keywords;\n};\n\nauto for_editor(JSON &schema, const SchemaWalker &walker,\n                const SchemaResolver &resolver,\n                std::string_view default_dialect) -> void {\n  // (1) Frame the schema and collect all changes we need to make\n  std::vector<ReferenceChange> reference_changes;\n  std::vector<SubschemaChange> subschema_changes;\n\n  {\n    SchemaFrame frame{SchemaFrame::Mode::References};\n    frame.analyse(schema, walker, resolver, default_dialect);\n\n    // Otherwise the input is not bundled\n    assert(frame.standalone());\n\n    // Note that `std::unordered_map` is slower here due to high collision rates\n    // from the simple pointer hashes\n    std::map<WeakPointer, std::reference_wrapper<const JSON::String>>\n        pointer_to_uri;\n    for (const auto &entry : frame.locations()) {\n      pointer_to_uri.emplace(entry.second.pointer,\n                             std::cref(entry.first.second));\n    }\n\n    // Collect reference changes\n    for (const auto &[key, reference] : frame.references()) {\n      assert(!key.second.empty());\n      assert(key.second.back().is_property());\n      const auto &keyword{key.second.back().to_property()};\n\n      if (key.first == SchemaReferenceType::Dynamic) {\n        if (reference.fragment.has_value()) {\n          const auto destination{top_dynamic_anchor_location(\n              frame, key.second, reference.fragment.value(),\n              reference.destination)};\n          if (!destination.has_value()) {\n            continue;\n          }\n\n          reference_changes.push_back(\n              {to_pointer(key.second),\n               to_uri(destination.value().get()).recompose(), keyword, true});\n        } else {\n          reference_changes.push_back(\n              {to_pointer(key.second), \"\", keyword, true});\n        }\n      } else {\n        if (keyword == \"$schema\") {\n          // Use pre-built index instead of O(n) frame.uri() scan\n          const auto uri_it{pointer_to_uri.find(key.second)};\n          assert(uri_it != pointer_to_uri.end());\n          const auto origin{frame.traverse(uri_it->second.get())};\n          assert(origin.has_value());\n          reference_changes.push_back(\n              {to_pointer(key.second),\n               JSON::String{to_string(origin.value().get().base_dialect)},\n               keyword, false});\n          continue;\n        }\n\n        const auto result{frame.traverse(reference.destination)};\n        if (result.has_value()) {\n          const bool should_rename =\n              keyword == \"$dynamicRef\" || keyword == \"$recursiveRef\";\n          reference_changes.push_back(\n              {to_pointer(key.second),\n               to_uri(result.value().get().pointer).recompose(), keyword,\n               should_rename});\n        } else {\n          reference_changes.push_back(\n              {to_pointer(key.second), reference.destination, keyword, false});\n        }\n      }\n    }\n\n    // Collect subschema changes\n    for (const auto &entry : frame.locations()) {\n      if (entry.second.type != SchemaFrame::LocationType::Resource &&\n          entry.second.type != SchemaFrame::LocationType::Subschema) {\n        continue;\n      }\n\n      const auto &subschema{get(schema, entry.second.pointer)};\n      if (subschema.is_boolean()) {\n        continue;\n      }\n\n      const bool add_schema =\n          entry.second.pointer.empty() && !subschema.defines(\"$schema\");\n      const auto vocabularies{frame.vocabularies(entry.second, resolver)};\n\n      subschema_changes.push_back(\n          {to_pointer(entry.second.pointer), entry.second.base_dialect,\n           add_schema,\n           vocabularies.contains(Vocabularies::Known::JSON_Schema_2020_12_Core),\n           vocabularies.contains(\n               Vocabularies::Known::JSON_Schema_2019_09_Core)});\n    }\n  }\n\n  // (2) Apply reference changes\n  for (const auto &change : reference_changes) {\n    if (!change.new_value.empty()) {\n      set(schema, change.pointer, JSON{change.new_value});\n    }\n    if (change.rename_to_ref) {\n      get(schema, change.pointer.initial()).rename(change.keyword, \"$ref\");\n    }\n  }\n\n  // (3) Apply subschema changes\n  for (const auto &change : subschema_changes) {\n    auto &subschema{get(schema, change.pointer)};\n\n    if (change.add_schema_declaration) {\n      subschema.assign_assume_new(\n          \"$schema\", JSON{JSON::String{to_string(change.base_dialect)}});\n    }\n\n    anonymize(subschema, change.base_dialect);\n\n    if (change.erase_2020_12_keywords) {\n      subschema.erase_keys({\"$vocabulary\", \"$anchor\", \"$dynamicAnchor\"});\n    } else if (change.erase_2019_09_keywords) {\n      subschema.erase_keys({\"$vocabulary\", \"$anchor\", \"$recursiveAnchor\"});\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/extension/editorschema/include/sourcemeta/core/editorschema.h",
    "content": "#ifndef SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA_H_\n#define SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA_H_\n\n/// @defgroup editorschema EditorSchema\n/// @brief A JSON Schema compatibility layer for code editors\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/editorschema.h>\n/// ```\n\n#ifndef SOURCEMETA_CORE_EDITORSCHEMA_EXPORT\n#include <sourcemeta/core/editorschema_export.h>\n#endif\n\n#include <sourcemeta/core/json.h>\n#include <sourcemeta/core/jsonschema.h>\n\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup editorschema\n///\n/// This function aims to transform the schema (in potentially non-strictly\n/// compliant manners) to workaround JSON Schema limitations of popular code\n/// editors.\n///\n/// Keep in mind that this is not a real solution, but a workaround, and there\n/// might be edge cases that we cannot cover. The real solution is for popular\n/// editors to fix their JSON Schema language support.\n///\n/// Note that the input schema is expected to be already bundled.\n///\n/// ```cpp\n/// #include <sourcemeta/core/json.h>\n/// #include <sourcemeta/core/jsonschema.h>\n///\n/// auto schema = sourcemeta::core::parse_json(R\"JSON({\n///   \"$id\": \"https://www.example.com/schema\",\n///   \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n///   \"$ref\": \"another\"\n/// })JSON\");\n///\n/// sourcemeta::core::bundle(schema,\n///   sourcemeta::core::schema_walker,\n///   sourcemeta::core::schema_resolver);\n/// sourcemeta::core::for_editor(schema,\n///   sourcemeta::core::schema_walker,\n///   sourcemeta::core::schema_resolver);\n/// ```\nSOURCEMETA_CORE_EDITORSCHEMA_EXPORT\nauto for_editor(JSON &schema, const SchemaWalker &walker,\n                const SchemaResolver &resolver,\n                std::string_view default_dialect = \"\") -> void;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/error/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME error\n  PRIVATE_HEADERS file.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME error)\nendif()\n"
  },
  {
    "path": "vendor/core/src/lang/error/include/sourcemeta/core/error.h",
    "content": "#ifndef SOURCEMETA_CORE_ERROR_H_\n#define SOURCEMETA_CORE_ERROR_H_\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/error_file.h>\n// NOLINTEND(misc-include-cleaner)\n\n/// @defgroup error Error\n/// @brief A growing collection of error utilities\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/error.h>\n/// ```\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/error/include/sourcemeta/core/error_file.h",
    "content": "#ifndef SOURCEMETA_CORE_ERROR_FILE_H_\n#define SOURCEMETA_CORE_ERROR_FILE_H_\n\n#include <cassert>    // assert\n#include <filesystem> // std::filesystem::path, std::filesystem::exists\n#include <utility>    // std::move, std::forward\n\nnamespace sourcemeta::core {\n\n/// @ingroup error\n/// A wrapper that decorates an arbitrary exception type with a file path.\n///\n/// ```cpp\n/// #include <sourcemeta/core/error.h>\n/// #include <stdexcept>\n///\n/// throw sourcemeta::core::FileError<std::runtime_error>(\n///     \"/tmp/foo.json\", \"something went wrong\");\n/// ```\ntemplate <typename T> class FileError : public T {\npublic:\n  template <typename... Args>\n  FileError(std::filesystem::path path, Args &&...args)\n      : T{std::forward<Args>(args)...}, path_{std::move(path)} {\n    assert(std::filesystem::exists(this->path_));\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME io\n  PRIVATE_HEADERS atomic.h binary.h error.h fileview.h temporary.h\n  SOURCES io.cc io_atomic.cc io_binary.cc io_fileview.cc io_temporary.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME io)\nendif()\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_H_\n#define SOURCEMETA_CORE_IO_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/io_atomic.h>\n#include <sourcemeta/core/io_binary.h>\n#include <sourcemeta/core/io_error.h>\n#include <sourcemeta/core/io_fileview.h>\n#include <sourcemeta/core/io_temporary.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <filesystem> // std::filesystem\n#include <fstream>    // std::basic_ifstream\n#include <iostream>   // std::cin\n#include <istream>    // std::basic_istream\n#include <sstream>    // std::basic_ostringstream\n#include <string>     // std::basic_string, std::char_traits, std::string\n\n/// @defgroup io I/O\n/// @brief A growing collection of I/O utilities\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup io\n///\n/// A safe variant of `std::filesystem::canonical` that takes into account\n/// platform-specific oddities like FIFO on GNU/Linux. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// const auto output{sourcemeta::core::canonical(\"/tmp/../foo.json\")};\n/// assert(output == \"/foo.json\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto canonical(const std::filesystem::path &path) -> std::filesystem::path;\n\n/// @ingroup io\n///\n/// A safe variant of `std::filesystem::weakly_canonical` that takes into\n/// account platform-specific oddities like FIFO on GNU/Linux. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// const auto output{sourcemeta::core::weakly_canonical(\"/tmp/../foo.json\")};\n/// assert(output == \"/foo.json\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto weakly_canonical(const std::filesystem::path &path)\n    -> std::filesystem::path;\n\n/// @ingroup io\n///\n/// Check if a file path starts with another path. This function assumes the\n/// paths are canonicalised. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// assert(sourcemeta::core::starts_with(\"/foo/bar\", \"/foo\"));\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto starts_with(const std::filesystem::path &path,\n                 const std::filesystem::path &prefix) -> bool;\n\n/// @ingroup io\n///\n/// A convenience function to open a stream from a file. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// auto stream{sourcemeta::core::read_file(\"/tmp/foo.json\")};\n/// assert(stream.is_open());\n/// ```\ntemplate <typename CharT = char, typename Traits = std::char_traits<CharT>>\nauto read_file(const std::filesystem::path &path)\n    -> std::basic_ifstream<CharT, Traits> {\n  if (std::filesystem::is_directory(path)) {\n    throw IOIsADirectoryError{path};\n  }\n\n  const auto canonical_path{sourcemeta::core::canonical(path)};\n  std::ifstream stream{canonical_path};\n  if (!stream.is_open()) {\n    throw IOFilePermissionError{canonical_path};\n  }\n\n  stream.exceptions(std::ifstream::badbit);\n  return stream;\n}\n\n/// @ingroup io\n///\n/// Drain an input stream into a string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <sstream>\n/// #include <cassert>\n///\n/// std::istringstream stream{\"hello\"};\n/// const auto contents{sourcemeta::core::read_to_string(stream)};\n/// assert(contents == \"hello\");\n/// ```\ntemplate <typename CharT = char, typename Traits = std::char_traits<CharT>>\nauto read_to_string(std::basic_istream<CharT, Traits> &stream)\n    -> std::basic_string<CharT, Traits> {\n  const auto start{stream.tellg()};\n  if (start != static_cast<std::streampos>(-1)) {\n    stream.seekg(0, std::ios::end);\n    const auto end{stream.tellg()};\n    stream.seekg(start);\n    if (end > start) {\n      std::basic_string<CharT, Traits> result;\n      result.resize(static_cast<std::size_t>(end - start));\n      stream.read(result.data(), static_cast<std::streamsize>(result.size()));\n      // Text-mode reads may return fewer characters than the byte count\n      // (i.e. CRLF collapses to LF on Windows), so trim to actual.\n      result.resize(static_cast<std::size_t>(stream.gcount()));\n      return result;\n    }\n  }\n\n  std::basic_ostringstream<CharT, Traits> buffer;\n  buffer << stream.rdbuf();\n  return buffer.str();\n}\n\n/// @ingroup io\n///\n/// Read an entire file into a string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// const auto contents{sourcemeta::core::read_file_to_string(\"/tmp/foo.json\")};\n/// assert(!contents.empty());\n/// ```\ntemplate <typename CharT = char, typename Traits = std::char_traits<CharT>>\nauto read_file_to_string(const std::filesystem::path &path)\n    -> std::basic_string<CharT, Traits> {\n  if (std::filesystem::is_directory(path)) {\n    throw IOIsADirectoryError{path};\n  }\n\n  const auto canonical_path{sourcemeta::core::canonical(path)};\n  std::basic_ifstream<CharT, Traits> stream{canonical_path};\n  if (!stream.is_open()) {\n    throw IOFilePermissionError{canonical_path};\n  }\n\n  stream.exceptions(std::basic_ifstream<CharT, Traits>::badbit);\n\n  std::basic_string<CharT, Traits> result;\n  result.resize(\n      static_cast<std::size_t>(std::filesystem::file_size(canonical_path)));\n  stream.read(result.data(), static_cast<std::streamsize>(result.size()));\n  // Text-mode reads may return fewer characters than the byte count\n  // (i.e. CRLF collapses to LF on Windows), so trim to actual.\n  result.resize(static_cast<std::size_t>(stream.gcount()));\n  return result;\n}\n\n/// @ingroup io\n///\n/// Drain `std::cin` fully into a string. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// const auto input{sourcemeta::core::read_stdin()};\n/// ```\ninline auto read_stdin() -> std::string { return read_to_string(std::cin); }\n\n/// @ingroup io\n///\n/// Recursively mirror a directory tree using hard links for regular files.\n/// Directories are created, regular files are hard-linked. Both paths must\n/// reside on the same filesystem. The destination must not be inside the\n/// source tree, as that would cause infinite recursion.\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// sourcemeta::core::hardlink_directory(\"/source\", \"/destination\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto hardlink_directory(const std::filesystem::path &source,\n                        const std::filesystem::path &destination) -> void;\n\n/// @ingroup io\n///\n/// Flush an existing file to disk, beyond just to the operating system. For\n/// example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// sourcemeta::core::flush(\"/foo/bar.txt\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto flush(const std::filesystem::path &path) -> void;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io_atomic.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_ATOMIC_H_\n#define SOURCEMETA_CORE_IO_ATOMIC_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n#include <cstddef>     // std::byte\n#include <filesystem>  // std::filesystem::path\n#include <functional>  // std::function\n#include <ostream>     // std::ostream\n#include <span>        // std::span\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup io\n///\n/// Atomically write `contents` to `path`. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// sourcemeta::core::atomic_write_file(\"/tmp/foo.json\", \"{\\\"a\\\":1}\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::string_view contents) -> void;\n\n/// @ingroup io\n///\n/// Atomically write a byte span to `path`. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <array>\n///\n/// constexpr std::array<std::byte, 3> bytes{\n///     std::byte{0x41}, std::byte{0x42}, std::byte{0x43}};\n/// sourcemeta::core::atomic_write_file(\"/tmp/foo.bin\", std::span{bytes});\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::span<const std::byte> contents) -> void;\n\n/// @ingroup io\n///\n/// Callback variant of `atomic_write_file`. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <sourcemeta/core/json.h>\n///\n/// sourcemeta::core::atomic_write_file(\"/tmp/foo.json\",\n///     [&](std::ostream &stream) {\n///       sourcemeta::core::prettify(document, stream);\n///       stream << \"\\n\";\n///     });\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::function<void(std::ostream &)> &writer)\n    -> void;\n\n/// @ingroup io\n///\n/// Atomically swap two directories. Both directories must reside on the same\n/// filesystem and the original path must not be a bare filename (it must have\n/// a parent component). After the call, the original path holds the contents\n/// of the replacement and the replacement path holds the former contents of\n/// the original. If the original does not exist, the replacement is simply\n/// renamed into place and the replacement path will no longer exist.\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// sourcemeta::core::atomic_directory_swap(\"/output\", \"/staging\");\n/// ```\nSOURCEMETA_CORE_IO_EXPORT\nauto atomic_directory_swap(const std::filesystem::path &original,\n                           const std::filesystem::path &replacement) -> void;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io_binary.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_BINARY_H_\n#define SOURCEMETA_CORE_IO_BINARY_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n#include <sourcemeta/core/io_fileview.h>\n\n#include <cstddef> // std::byte, std::size_t\n#include <cstdint> // std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t\n#include <istream> // std::istream\n#include <ostream> // std::ostream\n#include <type_traits> // std::is_trivially_copyable_v\n\nnamespace sourcemeta::core {\n\n/// @ingroup io\n///\n/// Typed wrapper over an output stream.\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <fstream>\n///\n/// std::ofstream raw{\"/tmp/out.bin\", std::ios::binary};\n/// sourcemeta::core::BinaryWriter writer{raw};\n/// writer.put_dword(0x12345678);\n/// ```\nclass SOURCEMETA_CORE_IO_EXPORT BinaryWriter {\npublic:\n  BinaryWriter(std::ostream &stream) noexcept;\n\n  // Prevent copying, as this class is tied to a stream resource\n  BinaryWriter(const BinaryWriter &) = delete;\n  BinaryWriter(BinaryWriter &&) = delete;\n  auto operator=(const BinaryWriter &) -> BinaryWriter & = delete;\n  auto operator=(BinaryWriter &&) -> BinaryWriter & = delete;\n\n  auto put_byte(const std::uint8_t value) -> void;\n  auto put_word(const std::uint16_t value) -> void;\n  auto put_dword(const std::uint32_t value) -> void;\n  auto put_qword(const std::uint64_t value) -> void;\n\n  auto put_bytes(const std::byte *data, const std::size_t size) -> void;\n\n  [[nodiscard]] auto position() const -> std::size_t;\n\nprivate:\n  template <typename T>\n    requires std::is_trivially_copyable_v<T>\n  auto put(const T &value) -> void {\n    this->put_bytes(reinterpret_cast<const std::byte *>(&value), sizeof(T));\n  }\n\n  std::ostream *stream_;\n};\n\n/// @ingroup io\n///\n/// Cursor-tracking reader over a `FileView` or an `std::istream`.\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n///\n/// sourcemeta::core::FileView view{\"/tmp/out.bin\"};\n/// sourcemeta::core::BinaryReader reader{view};\n/// const auto value{reader.get_dword()};\n/// ```\nclass SOURCEMETA_CORE_IO_EXPORT BinaryReader {\npublic:\n  BinaryReader(const FileView &view) noexcept;\n  BinaryReader(std::istream &stream) noexcept;\n\n  // Prevent copying, as this class is tied to an input resource\n  BinaryReader(const BinaryReader &) = delete;\n  BinaryReader(BinaryReader &&) = delete;\n  auto operator=(const BinaryReader &) -> BinaryReader & = delete;\n  auto operator=(BinaryReader &&) -> BinaryReader & = delete;\n\n  [[nodiscard]] auto get_byte() -> std::uint8_t;\n  [[nodiscard]] auto get_word() -> std::uint16_t;\n  [[nodiscard]] auto get_dword() -> std::uint32_t;\n  [[nodiscard]] auto get_qword() -> std::uint64_t;\n\n  auto get_bytes(std::byte *destination, const std::size_t size) -> void;\n\n  [[nodiscard]] auto position() const -> std::size_t;\n\n  /// Move the cursor to `position`.\n  auto seek(const std::size_t position) -> void;\n\n  /// Whether the source has unconsumed bytes at the current cursor.\n  [[nodiscard]] auto has_more_data() const -> bool;\n\nprivate:\n  template <typename T>\n    requires std::is_trivially_copyable_v<T>\n  [[nodiscard]] auto get() -> T {\n    T value;\n    this->get_bytes(reinterpret_cast<std::byte *>(&value), sizeof(T));\n    return value;\n  }\n\n  // Exactly one is non-null\n  const FileView *view_{nullptr};\n  std::istream *stream_{nullptr};\n  std::size_t offset_{0};\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io_error.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_ERROR_H_\n#define SOURCEMETA_CORE_IO_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n#include <exception>   // std::exception\n#include <filesystem>  // std::filesystem::path\n#include <string>      // std::string\n#include <string_view> // std::string_view\n#include <utility>     // std::move\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup io\n/// An error that represents a failure to memory-map a file\nclass SOURCEMETA_CORE_IO_EXPORT FileViewError : public std::exception {\npublic:\n  FileViewError(std::filesystem::path path, const char *message)\n      : path_{std::move(path)}, message_{message} {}\n  FileViewError(std::filesystem::path path, std::string message) = delete;\n  FileViewError(std::filesystem::path path, std::string &&message) = delete;\n  FileViewError(std::filesystem::path path, std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n  const char *message_;\n};\n\n/// @ingroup io\n/// The requested file does not exist.\nclass SOURCEMETA_CORE_IO_EXPORT IOFileNotFoundError : public std::exception {\npublic:\n  IOFileNotFoundError(std::filesystem::path path) : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"File not found\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n/// @ingroup io\n/// The current process lacks permission to access the requested path.\nclass SOURCEMETA_CORE_IO_EXPORT IOFilePermissionError : public std::exception {\npublic:\n  IOFilePermissionError(std::filesystem::path path) : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Permission denied\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n/// @ingroup io\n/// The path resolves to a directory where a regular file was expected.\nclass SOURCEMETA_CORE_IO_EXPORT IOIsADirectoryError : public std::exception {\npublic:\n  IOIsADirectoryError(std::filesystem::path path) : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Expected a file but got a directory\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n/// @ingroup io\n/// The path resolves to a regular file where a directory was expected.\nclass SOURCEMETA_CORE_IO_EXPORT IONotADirectoryError : public std::exception {\npublic:\n  IONotADirectoryError(std::filesystem::path path) : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Expected a directory but got a file\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n/// @ingroup io\n/// The destination path already exists and cannot be replaced.\nclass SOURCEMETA_CORE_IO_EXPORT IOFileAlreadyExistsError\n    : public std::exception {\npublic:\n  IOFileAlreadyExistsError(std::filesystem::path path)\n      : path_{std::move(path)} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"File already exists\";\n  }\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path & {\n    return this->path_;\n  }\n\nprivate:\n  std::filesystem::path path_;\n};\n\n/// @ingroup io\n/// A read attempted to access bytes outside the bounds of the underlying\n/// data.\nclass SOURCEMETA_CORE_IO_EXPORT IOReadOutOfBoundsError : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Read past the end of the underlying data\";\n  }\n};\n\n/// @ingroup io\n/// A write to the underlying stream failed.\nclass SOURCEMETA_CORE_IO_EXPORT IOStreamWriteError : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Failed to write to stream\";\n  }\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io_fileview.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_FILEVIEW_H_\n#define SOURCEMETA_CORE_IO_FILEVIEW_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n#include <cassert>    // assert\n#include <cstddef>    // std::size_t\n#include <cstdint>    // std::uint8_t\n#include <filesystem> // std::filesystem::path\n\nnamespace sourcemeta::core {\n\n/// @ingroup io\n/// A read-only memory-mapped file. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// struct Header {\n///   std::uint32_t magic;\n///   std::uint32_t version;\n/// };\n///\n/// sourcemeta::core::FileView view{\"/path/to/file.bin\"};\n/// const auto *header = view.as<Header>();\n/// assert(header->magic == 0x12345678);\n/// ```\nclass SOURCEMETA_CORE_IO_EXPORT FileView {\npublic:\n  FileView(const std::filesystem::path &path);\n  ~FileView();\n\n  // Disable copying and moving\n  FileView(const FileView &) = delete;\n  FileView(FileView &&) = delete;\n  auto operator=(const FileView &) -> FileView & = delete;\n  auto operator=(FileView &&) -> FileView & = delete;\n\n  /// The size of the memory-mapped data in bytes\n  [[nodiscard]] auto size() const noexcept -> std::size_t;\n\n  /// Interpret the memory-mapped data as a pointer to T at the given offset.\n  template <typename T>\n  [[nodiscard]] auto as(const std::size_t offset = 0) const noexcept\n      -> const T * {\n    assert(offset + sizeof(T) <= this->size_);\n    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n    return reinterpret_cast<const T *>(this->data_ + offset);\n  }\n\nprivate:\n  const std::uint8_t *data_{nullptr};\n  std::size_t size_{0};\n#if defined(_WIN32)\n  void *file_handle_{nullptr};\n  void *mapping_handle_{nullptr};\n#else\n  int file_descriptor_{-1};\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/include/sourcemeta/core/io_temporary.h",
    "content": "#ifndef SOURCEMETA_CORE_IO_TEMPORARY_H_\n#define SOURCEMETA_CORE_IO_TEMPORARY_H_\n\n#ifndef SOURCEMETA_CORE_IO_EXPORT\n#include <sourcemeta/core/io_export.h>\n#endif\n\n#include <filesystem>  // std::filesystem::path\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n/// @ingroup io\n/// An RAII class that creates a uniquely-named temporary directory on\n/// construction and removes it on destruction.\n///\n/// ```cpp\n/// #include <sourcemeta/core/io.h>\n/// #include <cassert>\n///\n/// sourcemeta::core::TemporaryDirectory staging{\"/tmp\", \".my-prefix-\"};\n/// assert(std::filesystem::exists(staging.path()));\n/// ```\nclass SOURCEMETA_CORE_IO_EXPORT TemporaryDirectory {\npublic:\n  TemporaryDirectory(const std::filesystem::path &parent,\n                     const std::string_view prefix);\n  ~TemporaryDirectory();\n\n  TemporaryDirectory(const TemporaryDirectory &) = delete;\n  auto operator=(const TemporaryDirectory &) -> TemporaryDirectory & = delete;\n  TemporaryDirectory(TemporaryDirectory &&) = delete;\n  auto operator=(TemporaryDirectory &&) -> TemporaryDirectory & = delete;\n\n  [[nodiscard]] auto path() const noexcept -> const std::filesystem::path &;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251)\n#endif\n  std::filesystem::path path_;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/io/io.cc",
    "content": "#include <sourcemeta/core/io.h>\n\n#include <system_error> // std::error_code, std::system_category, std::generic_category\n\n#if defined(_WIN32)\n#include <windows.h> // HANDLE, CreateFileW, FlushFileBuffers, CloseHandle\n#else\n#include <cerrno>   // errno (for error codes)\n#include <fcntl.h>  // open, O_RDWR, O_DIRECTORY, O_RDONLY\n#include <unistd.h> // close, fsync\n#endif\n\nnamespace sourcemeta::core {\n\nauto canonical(const std::filesystem::path &path) -> std::filesystem::path {\n  // On Linux, FIFO files (like /dev/fd/XX due to process substitution)\n  // cannot be made canonical\n  // See https://github.com/sourcemeta/jsonschema/issues/252\n  if (std::filesystem::is_fifo(path)) {\n    return path;\n  }\n\n  try {\n    return std::filesystem::canonical(path);\n  } catch (const std::filesystem::filesystem_error &error) {\n    if (error.code() == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{path};\n    }\n\n    throw;\n  }\n}\n\nauto weakly_canonical(const std::filesystem::path &path)\n    -> std::filesystem::path {\n  // On Linux, FIFO files (like /dev/fd/XX due to process substitution)\n  // cannot be made canonical\n  // See https://github.com/sourcemeta/jsonschema/issues/252\n  if (std::filesystem::is_fifo(path)) {\n    return path;\n  }\n\n  try {\n    return std::filesystem::weakly_canonical(path);\n  } catch (const std::filesystem::filesystem_error &error) {\n    if (error.code() == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{path};\n    }\n\n    throw;\n  }\n}\n\nauto starts_with(const std::filesystem::path &path,\n                 const std::filesystem::path &prefix) -> bool {\n  auto path_iterator = path.begin();\n  auto prefix_iterator = prefix.begin();\n\n  while (prefix_iterator != prefix.end()) {\n    if (path_iterator == path.end() || *path_iterator != *prefix_iterator) {\n      return false;\n    }\n\n    ++path_iterator;\n    ++prefix_iterator;\n  }\n\n  return true;\n}\n\nauto hardlink_directory(const std::filesystem::path &source,\n                        const std::filesystem::path &destination) -> void {\n  assert(std::filesystem::is_directory(source));\n  assert(!std::filesystem::exists(destination) ||\n         std::filesystem::is_directory(destination));\n  assert(!starts_with(destination, source));\n  std::filesystem::create_directories(destination);\n  for (const auto &entry :\n       std::filesystem::recursive_directory_iterator{source}) {\n    const auto target{destination /\n                      std::filesystem::relative(entry.path(), source)};\n    if (entry.is_directory()) {\n      std::filesystem::create_directories(target);\n    } else if (entry.is_regular_file()) {\n      std::filesystem::create_hard_link(entry.path(), target);\n    }\n  }\n}\n\nauto flush(const std::filesystem::path &path) -> void {\n#if defined(_WIN32)\n  HANDLE hFile =\n      CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr,\n                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);\n\n  if (hFile == INVALID_HANDLE_VALUE) {\n    const auto error_code = std::error_code{static_cast<int>(GetLastError()),\n                                            std::system_category()};\n    if (error_code == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{path};\n    }\n    if (error_code == std::errc::permission_denied) {\n      throw IOFilePermissionError{path};\n    }\n\n    throw std::filesystem::filesystem_error{\"failed to open file for flushing\",\n                                            path, error_code};\n  }\n\n  if (!FlushFileBuffers(hFile)) {\n    const auto error_code = std::error_code{static_cast<int>(GetLastError()),\n                                            std::system_category()};\n    CloseHandle(hFile);\n    throw std::filesystem::filesystem_error{\"failed to flush the file to disk\",\n                                            path, error_code};\n  }\n\n  CloseHandle(hFile);\n\n#else\n  auto fd = ::open(path.c_str(), O_RDWR);\n  if (fd == -1) {\n    const auto error_code = std::error_code{errno, std::generic_category()};\n    if (error_code == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{path};\n    }\n    if (error_code == std::errc::permission_denied) {\n      throw IOFilePermissionError{path};\n    }\n\n    throw std::filesystem::filesystem_error{\"failed to open file for flushing\",\n                                            path, error_code};\n  }\n\n  if (::fsync(fd) == -1) {\n    const auto error_code = std::error_code{errno, std::generic_category()};\n    ::close(fd);\n    throw std::filesystem::filesystem_error{\"failed to flush the file to disk\",\n                                            path, error_code};\n  }\n\n  ::close(fd);\n\n  // After syncing a file, we should also sync the directory to ensure\n  // durability\n  auto directory_fd =\n      ::open(path.parent_path().c_str(), O_DIRECTORY | O_RDONLY);\n  if (directory_fd != -1) {\n    if (::fsync(directory_fd) == -1) {\n      const auto error_code = std::error_code{errno, std::generic_category()};\n      ::close(directory_fd);\n      throw std::filesystem::filesystem_error{\n          \"failed to flush the parent directory to disk\", path, error_code};\n    }\n\n    ::close(directory_fd);\n  }\n#endif\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/io/io_atomic.cc",
    "content": "#include <sourcemeta/core/io.h>\n#include <sourcemeta/core/io_atomic.h>\n\n#include <cassert>      // assert\n#include <cerrno>       // EACCES, errno\n#include <filesystem>   // std::filesystem\n#include <fstream>      // std::ofstream\n#include <ios>          // std::ios::binary, std::ios::trunc\n#include <ostream>      // std::ostream\n#include <system_error> // std::error_code, std::generic_category\n\n#if defined(__linux__)\n#include <fcntl.h>       // AT_FDCWD\n#include <linux/fs.h>    // RENAME_EXCHANGE\n#include <sys/syscall.h> // SYS_renameat2\n#include <unistd.h>      // syscall\n#elif defined(__APPLE__)\n#include <fcntl.h>     // AT_FDCWD\n#include <sys/stdio.h> // renameatx_np, RENAME_SWAP\n#endif\n\nnamespace {\n\nclass AtomicFileWriter {\npublic:\n  AtomicFileWriter(const std::filesystem::path &destination)\n      : destination_{destination}, staging_{destination} {\n    // The staging file lives next to the destination so that\n    // `std::filesystem::rename` stays on a single filesystem and remains\n    // atomic. Using the system-wide temporary directory would risk `EXDEV`\n    // errors on cross-filesystem builds (CI containers, NFS mounts, etc.).\n    this->staging_ += \".tmp\";\n\n    if (this->destination_.has_parent_path()) {\n      std::filesystem::create_directories(this->destination_.parent_path());\n    }\n\n    this->stream_.exceptions(std::ofstream::failbit | std::ofstream::badbit);\n    try {\n      this->stream_.open(this->staging_, std::ios::binary | std::ios::trunc);\n    } catch (...) {\n      // Capture before any other syscall can clobber errno\n      const auto open_errno{errno};\n      std::error_code remove_error;\n      std::filesystem::remove(this->staging_, remove_error);\n      if (open_errno == EACCES) {\n        throw sourcemeta::core::IOFilePermissionError{this->destination_};\n      }\n\n      throw;\n    }\n  }\n\n  ~AtomicFileWriter() {\n    if (!this->committed_) {\n      if (this->stream_.is_open()) {\n        this->stream_.exceptions(std::ios::goodbit);\n        this->stream_.close();\n      }\n\n      std::error_code error;\n      std::filesystem::remove(this->staging_, error);\n    }\n  }\n\n  AtomicFileWriter(const AtomicFileWriter &) = delete;\n  AtomicFileWriter(AtomicFileWriter &&) = delete;\n  auto operator=(const AtomicFileWriter &) -> AtomicFileWriter & = delete;\n  auto operator=(AtomicFileWriter &&) -> AtomicFileWriter & = delete;\n\n  [[nodiscard]] auto stream() -> std::ostream & { return this->stream_; }\n\n  auto commit() -> void {\n    assert(!this->committed_);\n    this->stream_.flush();\n    this->stream_.close();\n    sourcemeta::core::flush(this->staging_);\n    std::filesystem::rename(this->staging_, this->destination_);\n    this->committed_ = true;\n  }\n\nprivate:\n  std::filesystem::path destination_;\n  std::filesystem::path staging_;\n  std::ofstream stream_;\n  bool committed_{false};\n};\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::string_view contents) -> void {\n  AtomicFileWriter file{path};\n  file.stream().write(contents.data(),\n                      static_cast<std::streamsize>(contents.size()));\n  file.commit();\n}\n\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::span<const std::byte> contents) -> void {\n  AtomicFileWriter file{path};\n  file.stream().write(reinterpret_cast<const char *>(contents.data()),\n                      static_cast<std::streamsize>(contents.size()));\n  file.commit();\n}\n\nauto atomic_write_file(const std::filesystem::path &path,\n                       const std::function<void(std::ostream &)> &writer)\n    -> void {\n  AtomicFileWriter file{path};\n  writer(file.stream());\n  file.commit();\n}\n\nauto atomic_directory_swap(const std::filesystem::path &original,\n                           const std::filesystem::path &replacement) -> void {\n  assert(std::filesystem::is_directory(replacement));\n  assert(!std::filesystem::exists(original) ||\n         std::filesystem::is_directory(original));\n  assert(!original.parent_path().empty());\n\n  if (!std::filesystem::exists(original)) {\n    std::filesystem::rename(replacement, original);\n    return;\n  }\n\n  // Atomic swap via renameat2 with RENAME_EXCHANGE\n#if defined(__linux__)\n  if (syscall(SYS_renameat2, AT_FDCWD, replacement.c_str(), AT_FDCWD,\n              original.c_str(), RENAME_EXCHANGE) != 0) {\n    const auto error_code = std::error_code{errno, std::generic_category()};\n    if (error_code == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{original};\n    }\n    if (error_code == std::errc::permission_denied) {\n      throw IOFilePermissionError{original};\n    }\n\n    throw std::filesystem::filesystem_error{\n        \"failed to atomically swap directories\", replacement, original,\n        error_code};\n  }\n\n  // Atomic swap via renameatx_np with RENAME_SWAP\n#elif defined(__APPLE__)\n  if (renameatx_np(AT_FDCWD, replacement.c_str(), AT_FDCWD, original.c_str(),\n                   RENAME_SWAP) != 0) {\n    const auto error_code = std::error_code{errno, std::generic_category()};\n    if (error_code == std::errc::no_such_file_or_directory) {\n      throw IOFileNotFoundError{original};\n    }\n    if (error_code == std::errc::permission_denied) {\n      throw IOFilePermissionError{original};\n    }\n\n    throw std::filesystem::filesystem_error{\n        \"failed to atomically swap directories\", replacement, original,\n        error_code};\n  }\n\n#else\n  // Non-atomic fallback: two-rename approach with rollback\n  //\n  // Note we cannot safely use the temporary directory of the system as it\n  // might be in another volume\n  TemporaryDirectory temporary{original.parent_path(), \".swap-\"};\n  std::filesystem::remove(temporary.path());\n  std::filesystem::rename(original, temporary.path());\n  try {\n    std::filesystem::rename(replacement, original);\n  } catch (...) {\n    std::filesystem::rename(temporary.path(), original);\n    throw;\n  }\n\n  std::filesystem::rename(temporary.path(), replacement);\n#endif\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/io/io_binary.cc",
    "content": "#include <sourcemeta/core/io_binary.h>\n#include <sourcemeta/core/io_error.h>\n\n#include <bit>       // std::endian, std::byteswap\n#include <cassert>   // assert\n#include <cstring>   // std::memcpy\n#include <ios>       // std::streamsize, std::streamoff\n#include <streambuf> // std::streambuf\n\nnamespace {\n\ntemplate <typename T> auto to_little_endian(const T value) -> T {\n  if constexpr (std::endian::native == std::endian::big) {\n    return std::byteswap(value);\n  } else {\n    return value;\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nBinaryWriter::BinaryWriter(std::ostream &stream) noexcept : stream_{&stream} {}\n\nauto BinaryWriter::put_byte(const std::uint8_t value) -> void {\n  this->put(value);\n}\n\nauto BinaryWriter::put_word(const std::uint16_t value) -> void {\n  this->put(to_little_endian(value));\n}\n\nauto BinaryWriter::put_dword(const std::uint32_t value) -> void {\n  this->put(to_little_endian(value));\n}\n\nauto BinaryWriter::put_qword(const std::uint64_t value) -> void {\n  this->put(to_little_endian(value));\n}\n\nauto BinaryWriter::put_bytes(const std::byte *data, const std::size_t size)\n    -> void {\n  if (size == 0) {\n    return;\n  }\n\n  this->stream_->write(reinterpret_cast<const char *>(data),\n                       static_cast<std::streamsize>(size));\n  if (this->stream_->fail()) {\n    throw IOStreamWriteError{};\n  }\n}\n\nauto BinaryWriter::position() const -> std::size_t {\n  const auto position{this->stream_->tellp()};\n  if (position == std::streampos{-1}) {\n    throw IOStreamWriteError{};\n  }\n\n  return static_cast<std::size_t>(position);\n}\n\nBinaryReader::BinaryReader(const FileView &view) noexcept : view_{&view} {}\n\nBinaryReader::BinaryReader(std::istream &stream) noexcept : stream_{&stream} {}\n\nauto BinaryReader::get_byte() -> std::uint8_t {\n  return this->get<std::uint8_t>();\n}\n\nauto BinaryReader::get_word() -> std::uint16_t {\n  return to_little_endian(this->get<std::uint16_t>());\n}\n\nauto BinaryReader::get_dword() -> std::uint32_t {\n  return to_little_endian(this->get<std::uint32_t>());\n}\n\nauto BinaryReader::get_qword() -> std::uint64_t {\n  return to_little_endian(this->get<std::uint64_t>());\n}\n\nauto BinaryReader::position() const -> std::size_t {\n  if (this->view_) {\n    return this->offset_;\n  }\n\n  assert(this->stream_);\n  const auto position{this->stream_->tellg()};\n  if (position == std::streampos{-1}) {\n    throw IOReadOutOfBoundsError{};\n  }\n\n  return static_cast<std::size_t>(position);\n}\n\nauto BinaryReader::seek(const std::size_t position) -> void {\n  if (this->view_) {\n    if (position > this->view_->size()) {\n      throw IOReadOutOfBoundsError{};\n    }\n\n    this->offset_ = position;\n    return;\n  }\n\n  assert(this->stream_);\n  this->stream_->seekg(static_cast<std::streamoff>(position));\n  if (this->stream_->fail()) {\n    throw IOReadOutOfBoundsError{};\n  }\n}\n\nauto BinaryReader::get_bytes(std::byte *destination, const std::size_t size)\n    -> void {\n  if (this->view_) {\n    if (size > this->view_->size() - this->offset_) {\n      throw IOReadOutOfBoundsError{};\n    }\n\n    if (size > 0) {\n      std::memcpy(destination, this->view_->as<std::byte>(this->offset_), size);\n      this->offset_ += size;\n    }\n\n    return;\n  }\n\n  assert(this->stream_);\n  this->stream_->read(reinterpret_cast<char *>(destination),\n                      static_cast<std::streamsize>(size));\n  const auto consumed{static_cast<std::size_t>(this->stream_->gcount())};\n  if (consumed != size) {\n    throw IOReadOutOfBoundsError{};\n  }\n}\n\nauto BinaryReader::has_more_data() const -> bool {\n  if (this->view_) {\n    return this->offset_ < this->view_->size();\n  }\n\n  assert(this->stream_);\n  auto *buffer{this->stream_->rdbuf()};\n  return buffer->in_avail() > 0 ||\n         buffer->sgetc() != std::char_traits<char>::eof();\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/io/io_fileview.cc",
    "content": "#include <sourcemeta/core/io_error.h>\n#include <sourcemeta/core/io_fileview.h>\n\n#if defined(_WIN32)\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#else\n#include <fcntl.h>    // open, O_RDONLY\n#include <sys/mman.h> // mmap, munmap\n#include <sys/stat.h> // fstat\n#include <unistd.h>   // close\n#endif\n\nnamespace sourcemeta::core {\n\n#if defined(_WIN32)\n\nFileView::FileView(const std::filesystem::path &path) {\n  this->file_handle_ =\n      CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,\n                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);\n  if (this->file_handle_ == INVALID_HANDLE_VALUE) {\n    throw FileViewError(path, \"Could not open the file\");\n  }\n\n  LARGE_INTEGER file_size;\n  if (GetFileSizeEx(this->file_handle_, &file_size) == 0) {\n    CloseHandle(this->file_handle_);\n    throw FileViewError(path, \"Could not determine the file size\");\n  }\n  this->size_ = static_cast<std::size_t>(file_size.QuadPart);\n\n  this->mapping_handle_ = CreateFileMappingW(this->file_handle_, nullptr,\n                                             PAGE_READONLY, 0, 0, nullptr);\n  if (this->mapping_handle_ == nullptr) {\n    CloseHandle(this->file_handle_);\n    throw FileViewError(path, \"Could not create a file mapping\");\n  }\n\n  this->data_ = static_cast<const std::uint8_t *>(\n      MapViewOfFile(this->mapping_handle_, FILE_MAP_READ, 0, 0, 0));\n  if (this->data_ == nullptr) {\n    CloseHandle(this->mapping_handle_);\n    CloseHandle(this->file_handle_);\n    throw FileViewError(path, \"Could not map the file into memory\");\n  }\n}\n\nFileView::~FileView() {\n  if (this->data_ != nullptr) {\n    UnmapViewOfFile(this->data_);\n  }\n\n  if (this->mapping_handle_ != nullptr) {\n    CloseHandle(this->mapping_handle_);\n  }\n\n  if (this->file_handle_ != nullptr &&\n      this->file_handle_ != INVALID_HANDLE_VALUE) {\n    CloseHandle(this->file_handle_);\n  }\n}\n\n#else\n\nFileView::FileView(const std::filesystem::path &path) {\n  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)\n  this->file_descriptor_ = open(path.c_str(), O_RDONLY);\n  if (this->file_descriptor_ == -1) {\n    throw FileViewError(path, \"Could not open the file\");\n  }\n\n  struct stat file_stat;\n  if (fstat(this->file_descriptor_, &file_stat) != 0) {\n    close(this->file_descriptor_);\n    throw FileViewError(path, \"Could not determine the file size\");\n  }\n  this->size_ = static_cast<std::size_t>(file_stat.st_size);\n\n  void *mapped = mmap(nullptr, this->size_, PROT_READ, MAP_PRIVATE,\n                      this->file_descriptor_, 0);\n  if (mapped == MAP_FAILED) {\n    close(this->file_descriptor_);\n    throw FileViewError(path, \"Could not map the file into memory\");\n  }\n\n  this->data_ = static_cast<const std::uint8_t *>(mapped);\n}\n\nFileView::~FileView() {\n  if (this->data_ != nullptr && this->size_ > 0) {\n    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)\n    munmap(const_cast<std::uint8_t *>(this->data_), this->size_);\n  }\n\n  if (this->file_descriptor_ != -1) {\n    close(this->file_descriptor_);\n  }\n}\n\n#endif\n\nauto FileView::size() const noexcept -> std::size_t { return this->size_; }\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/io/io_temporary.cc",
    "content": "#include <sourcemeta/core/io_error.h>\n#include <sourcemeta/core/io_temporary.h>\n\n#include <cassert>      // assert\n#include <filesystem>   // std::filesystem\n#include <string>       // std::string\n#include <system_error> // std::error_code, std::generic_category\n\n#if defined(_WIN32)\n#include <io.h> // _mktemp_s\n#else\n#include <cerrno>   // errno\n#include <unistd.h> // mkdtemp\n#endif\n\nnamespace sourcemeta::core {\n\nTemporaryDirectory::TemporaryDirectory(const std::filesystem::path &parent,\n                                       const std::string_view prefix) {\n  assert(!prefix.empty());\n  assert(!prefix.contains('/'));\n  assert(!prefix.contains('\\\\'));\n  if (std::filesystem::exists(parent) &&\n      !std::filesystem::is_directory(parent)) {\n    throw IONotADirectoryError{parent};\n  }\n\n  std::filesystem::create_directories(parent);\n  auto name{(parent / std::string{prefix}).string() + \"XXXXXX\"};\n\n#if defined(_WIN32)\n  const auto error{_mktemp_s(name.data(), name.size() + 1)};\n  if (error != 0) {\n    throw std::filesystem::filesystem_error{\n        \"failed to create temporary directory\", parent,\n        std::error_code{error, std::generic_category()}};\n  }\n\n  if (!std::filesystem::create_directory(name)) {\n    throw IOFileAlreadyExistsError{std::filesystem::path{name}};\n  }\n#else\n  if (mkdtemp(name.data()) == nullptr) {\n    throw std::filesystem::filesystem_error{\n        \"failed to create temporary directory\", parent,\n        std::error_code{errno, std::generic_category()}};\n  }\n#endif\n\n  this->path_ = std::filesystem::path{name};\n}\n\nTemporaryDirectory::~TemporaryDirectory() {\n  std::error_code error;\n  std::filesystem::remove_all(this->path_, error);\n}\n\nauto TemporaryDirectory::path() const noexcept\n    -> const std::filesystem::path & {\n  return this->path_;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME numeric\n  PRIVATE_HEADERS error.h decimal.h parse.h uint128.h util.h zigzag.h\n  SOURCES decimal.cc parse.cc big_coefficient.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME numeric)\nendif()\n\ntarget_link_libraries(sourcemeta_core_numeric PUBLIC sourcemeta::core::preprocessor)\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/big_coefficient.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_BIG_COEFFICIENT_H_\n#define SOURCEMETA_CORE_NUMERIC_BIG_COEFFICIENT_H_\n\n#include <algorithm> // std::max, std::copy, std::fill\n#include <array>     // std::array\n#include <cstdint>   // std::int32_t, std::int64_t, std::uint32_t,\n                     // std::uint64_t, std::uintptr_t, std::uint8_t\n#include <cstring>   // std::memcpy\n#include <string>    // std::string, std::to_string\n#include <utility>   // std::pair, std::move\n\n#include <sourcemeta/core/numeric_uint128.h>\n\nnamespace {\n\nconstexpr std::uint8_t FLAG_SIGN = 0x01;\nconstexpr std::uint8_t FLAG_NAN = 0x02;\nconstexpr std::uint8_t FLAG_SNAN = 0x04;\nconstexpr std::uint8_t FLAG_INFINITE = 0x08;\nconstexpr std::uint8_t FLAG_BIG = 0x10;\nconstexpr std::uint8_t FLAG_HEAP = 0x20;\nconstexpr std::uint8_t FLAG_INTEGER_LITERAL = 0x40;\n\nconstexpr std::uint8_t SPECIAL_MASK =\n    FLAG_NAN | FLAG_SNAN | FLAG_INFINITE | FLAG_BIG;\n\nconstexpr std::array<std::uint64_t, 20> POWERS_OF_10 = {{\n    1ULL,                    // 10^0\n    10ULL,                   // 10^1\n    100ULL,                  // 10^2\n    1000ULL,                 // 10^3\n    10000ULL,                // 10^4\n    100000ULL,               // 10^5\n    1000000ULL,              // 10^6\n    10000000ULL,             // 10^7\n    100000000ULL,            // 10^8\n    1000000000ULL,           // 10^9\n    10000000000ULL,          // 10^10\n    100000000000ULL,         // 10^11\n    1000000000000ULL,        // 10^12\n    10000000000000ULL,       // 10^13\n    100000000000000ULL,      // 10^14\n    1000000000000000ULL,     // 10^15\n    10000000000000000ULL,    // 10^16\n    100000000000000000ULL,   // 10^17\n    1000000000000000000ULL,  // 10^18\n    10000000000000000000ULL, // 10^19\n}};\n\nconstexpr std::uint64_t BASE = 1000000000000000000ULL; // 10^18\nconstexpr std::int32_t BASE_DIGITS = 18;\nconstexpr std::int64_t COMPACT_MAX =\n    static_cast<std::int64_t>(BASE - 1); // 999999999999999999\n\nclass BigCoefficient {\n  static constexpr std::uint32_t INLINE_CAPACITY = 4;\n  std::array<std::uint64_t, INLINE_CAPACITY> inline_words;\n\n  [[nodiscard]] auto is_inline() const -> bool {\n    return this->capacity <= INLINE_CAPACITY;\n  }\n\npublic:\n  std::uint64_t *words{nullptr};\n  std::uint32_t length{0};\n  std::uint32_t capacity;\n\n  explicit BigCoefficient(std::uint32_t requested_capacity) {\n    if (requested_capacity <= INLINE_CAPACITY) {\n      this->words = this->inline_words.data();\n      this->capacity = INLINE_CAPACITY;\n      this->inline_words.fill(0);\n    } else {\n      this->words = new std::uint64_t[requested_capacity]();\n      this->capacity = requested_capacity;\n    }\n  }\n\n  ~BigCoefficient() {\n    if (!this->is_inline()) {\n      delete[] this->words;\n    }\n  }\n\n  BigCoefficient(BigCoefficient &&other) noexcept\n      : length{other.length}, capacity{other.capacity} {\n    if (other.is_inline()) {\n      std::copy(other.inline_words.data(),\n                other.inline_words.data() + other.length,\n                this->inline_words.data());\n      this->words = this->inline_words.data();\n    } else {\n      this->words = other.words;\n      other.words = other.inline_words.data();\n    }\n\n    other.length = 0;\n    other.capacity = INLINE_CAPACITY;\n  }\n\n  auto operator=(BigCoefficient &&other) noexcept -> BigCoefficient & {\n    if (this != &other) {\n      if (!this->is_inline()) {\n        delete[] this->words;\n      }\n\n      this->length = other.length;\n      this->capacity = other.capacity;\n      if (other.is_inline()) {\n        std::copy(other.inline_words.data(),\n                  other.inline_words.data() + other.length,\n                  this->inline_words.data());\n        this->words = this->inline_words.data();\n      } else {\n        this->words = other.words;\n        other.words = other.inline_words.data();\n      }\n\n      other.length = 0;\n      other.capacity = INLINE_CAPACITY;\n    }\n\n    return *this;\n  }\n\n  BigCoefficient(const BigCoefficient &) = delete;\n  auto operator=(const BigCoefficient &) -> BigCoefficient & = delete;\n\n  [[nodiscard]] auto clone() const -> BigCoefficient {\n    BigCoefficient result{this->length};\n    result.length = this->length;\n    std::copy(this->words, this->words + this->length, result.words);\n    return result;\n  }\n\n  auto trim() -> void {\n    while (this->length > 1 && this->words[this->length - 1] == 0) {\n      this->length--;\n    }\n  }\n\n  [[nodiscard]] auto is_zero() const -> bool {\n    return this->length == 0 || (this->length == 1 && this->words[0] == 0);\n  }\n\n  [[nodiscard]] auto digit_count() const -> std::uint64_t {\n    if (this->is_zero()) {\n      return 1;\n    }\n\n    auto top_word = this->words[this->length - 1];\n    std::uint64_t top_digits = 0;\n    while (top_word > 0) {\n      top_word /= 10;\n      top_digits++;\n    }\n    return top_digits +\n           static_cast<std::uint64_t>(this->length - 1) * BASE_DIGITS;\n  }\n\n  [[nodiscard]] auto to_string() const -> std::string {\n    if (this->is_zero()) {\n      return \"0\";\n    }\n\n    std::string result;\n    auto top = this->words[this->length - 1];\n    result += std::to_string(top);\n\n    for (auto index = this->length - 1; index > 0; index--) {\n      auto word_string = std::to_string(this->words[index - 1]);\n      result.append(static_cast<std::size_t>(BASE_DIGITS) - word_string.size(),\n                    '0');\n      result += word_string;\n    }\n\n    return result;\n  }\n\n  auto strip_trailing_zeros() -> std::int32_t {\n    if (this->is_zero()) {\n      return 0;\n    }\n\n    std::int32_t total_stripped = 0;\n\n    std::uint32_t zero_words = 0;\n    while (zero_words < this->length && this->words[zero_words] == 0) {\n      zero_words++;\n    }\n\n    if (zero_words > 0 && zero_words < this->length) {\n      std::copy(this->words + zero_words, this->words + this->length,\n                this->words);\n      this->length -= zero_words;\n      total_stripped += static_cast<std::int32_t>(zero_words) * BASE_DIGITS;\n    }\n\n    if (this->words[0] != 0) {\n      while (this->words[0] % 10 == 0) {\n        this->words[0] /= 10;\n        total_stripped++;\n      }\n    }\n\n    return total_stripped;\n  }\n\n  [[nodiscard]] auto compare(const BigCoefficient &other) const -> int {\n    if (this->length != other.length) {\n      return this->length < other.length ? -1 : 1;\n    }\n\n    for (auto index = this->length; index > 0; index--) {\n      if (this->words[index - 1] != other.words[index - 1]) {\n        return this->words[index - 1] < other.words[index - 1] ? -1 : 1;\n      }\n    }\n\n    return 0;\n  }\n\n  [[nodiscard]] auto add(const BigCoefficient &other) const -> BigCoefficient {\n    auto max_length = std::max(this->length, other.length);\n    BigCoefficient result{max_length + 1};\n    std::uint64_t carry = 0;\n    for (std::uint32_t index = 0; index < max_length; index++) {\n      sourcemeta::core::uint128_t sum = carry;\n      if (index < this->length) {\n        sum += this->words[index];\n      }\n\n      if (index < other.length) {\n        sum += other.words[index];\n      }\n\n      result.words[index] = static_cast<std::uint64_t>(sum % BASE);\n      carry = static_cast<std::uint64_t>(sum / BASE);\n    }\n\n    result.length = max_length;\n    if (carry > 0) {\n      result.words[result.length] = carry;\n      result.length++;\n    }\n\n    result.trim();\n    return result;\n  }\n\n  [[nodiscard]] auto subtract(const BigCoefficient &other) const\n      -> BigCoefficient {\n    BigCoefficient result{this->length};\n    std::int64_t borrow = 0;\n    for (std::uint32_t index = 0; index < this->length; index++) {\n      auto left_word = static_cast<std::int64_t>(this->words[index]);\n      std::int64_t right_word = 0;\n      if (index < other.length) {\n        right_word = static_cast<std::int64_t>(other.words[index]);\n      }\n\n      auto difference = left_word - right_word - borrow;\n      if (difference < 0) {\n        difference += static_cast<std::int64_t>(BASE);\n        borrow = 1;\n      } else {\n        borrow = 0;\n      }\n\n      result.words[index] = static_cast<std::uint64_t>(difference);\n    }\n\n    result.length = this->length;\n    result.trim();\n    return result;\n  }\n\n  [[nodiscard]] auto multiply(const BigCoefficient &other) const\n      -> BigCoefficient {\n    auto result_length = this->length + other.length;\n    BigCoefficient result{result_length};\n    result.length = result_length;\n    std::fill(result.words, result.words + result_length, 0ULL);\n\n    for (std::uint32_t index_left = 0; index_left < this->length;\n         index_left++) {\n      sourcemeta::core::uint128_t carry = 0;\n      for (std::uint32_t index_right = 0; index_right < other.length;\n           index_right++) {\n        auto position = index_left + index_right;\n        auto product =\n            static_cast<sourcemeta::core::uint128_t>(this->words[index_left]) *\n                other.words[index_right] +\n            result.words[position] + carry;\n        result.words[position] = static_cast<std::uint64_t>(product % BASE);\n        carry = product / BASE;\n      }\n\n      if (carry > 0) {\n        result.words[index_left + other.length] +=\n            static_cast<std::uint64_t>(carry);\n      }\n    }\n\n    result.trim();\n    return result;\n  }\n\n  [[nodiscard]] auto multiply_pow10(std::uint32_t power) const\n      -> BigCoefficient {\n    if (power == 0) {\n      return this->clone();\n    }\n\n    auto full_words = power / BASE_DIGITS;\n    auto residual = power % BASE_DIGITS;\n    BigCoefficient result{this->length + full_words + 1};\n\n    std::fill(result.words, result.words + full_words, 0ULL);\n    std::copy(this->words, this->words + this->length,\n              result.words + full_words);\n    result.length = this->length + full_words;\n\n    if (residual > 0) {\n      auto multiplier = POWERS_OF_10[static_cast<std::uint32_t>(residual)];\n      sourcemeta::core::uint128_t carry = 0;\n      for (std::uint32_t index = full_words; index < result.length; index++) {\n        auto product =\n            static_cast<sourcemeta::core::uint128_t>(result.words[index]) *\n                multiplier +\n            carry;\n        result.words[index] = static_cast<std::uint64_t>(product % BASE);\n        carry = product / BASE;\n      }\n\n      if (carry > 0) {\n        result.words[result.length] = static_cast<std::uint64_t>(carry);\n        result.length++;\n      }\n    }\n\n    result.trim();\n    return result;\n  }\n\n  [[nodiscard]] auto divide_modulo(const BigCoefficient &divisor) const\n      -> std::pair<BigCoefficient, BigCoefficient> {\n    auto compare_result = this->compare(divisor);\n    if (compare_result < 0) {\n      BigCoefficient quotient{1};\n      quotient.words[0] = 0;\n      quotient.length = 1;\n      return {std::move(quotient), this->clone()};\n    }\n\n    if (compare_result == 0) {\n      BigCoefficient quotient{1};\n      quotient.words[0] = 1;\n      quotient.length = 1;\n      BigCoefficient remainder{1};\n      remainder.words[0] = 0;\n      remainder.length = 1;\n      return {std::move(quotient), std::move(remainder)};\n    }\n\n    if (divisor.length == 1) {\n      BigCoefficient quotient{this->length};\n      quotient.length = this->length;\n      sourcemeta::core::uint128_t remainder = 0;\n      for (auto index = this->length; index > 0; index--) {\n        auto current = remainder * BASE + this->words[index - 1];\n        quotient.words[index - 1] =\n            static_cast<std::uint64_t>(current / divisor.words[0]);\n        remainder = current % divisor.words[0];\n      }\n\n      quotient.trim();\n      BigCoefficient remainder_big{1};\n      remainder_big.words[0] = static_cast<std::uint64_t>(remainder);\n      remainder_big.length = 1;\n      return {std::move(quotient), std::move(remainder_big)};\n    }\n\n    auto remainder = this->clone();\n    BigCoefficient quotient{this->length};\n    quotient.length = this->length;\n    std::fill(quotient.words, quotient.words + quotient.length, 0ULL);\n\n    while (remainder.compare(divisor) >= 0) {\n      auto remainder_top = static_cast<sourcemeta::core::uint128_t>(\n          remainder.words[remainder.length - 1]);\n      if (remainder.length > divisor.length) {\n        auto shift = remainder.length - divisor.length;\n        auto divisor_top = divisor.words[divisor.length - 1];\n        auto estimate =\n            static_cast<std::uint64_t>(remainder_top / (divisor_top + 1));\n        if (estimate == 0) {\n          estimate = 1;\n        }\n\n        BigCoefficient estimate_big{1};\n        estimate_big.words[0] = estimate;\n        estimate_big.length = 1;\n\n        auto scaled = estimate_big.multiply_pow10(shift * BASE_DIGITS);\n        auto product = scaled.multiply(divisor);\n\n        if (product.compare(remainder) > 0) {\n          remainder = remainder.subtract(divisor);\n          quotient.words[0]++;\n        } else {\n          remainder = remainder.subtract(product);\n          BigCoefficient estimated_quotient{shift + 1};\n          std::fill(estimated_quotient.words, estimated_quotient.words + shift,\n                    0ULL);\n          estimated_quotient.words[shift] = estimate;\n          estimated_quotient.length = shift + 1;\n          quotient = quotient.add(estimated_quotient);\n        }\n\n      } else {\n        remainder = remainder.subtract(divisor);\n        quotient.words[0]++;\n      }\n    }\n\n    quotient.trim();\n    remainder.trim();\n    return {std::move(quotient), std::move(remainder)};\n  }\n\n  [[nodiscard]] static auto from_uint64(std::uint64_t value) -> BigCoefficient {\n    if (value < BASE) {\n      BigCoefficient result{1};\n      result.words[0] = value;\n      result.length = 1;\n      return result;\n    }\n\n    BigCoefficient result{2};\n    result.words[0] = value % BASE;\n    result.words[1] = value / BASE;\n    result.length = 2;\n    return result;\n  }\n\n  [[nodiscard]] static auto from_digits(const char *digits, std::uint32_t count)\n      -> BigCoefficient {\n    auto word_count = (count + BASE_DIGITS - 1) / BASE_DIGITS;\n    BigCoefficient result{word_count};\n    result.length = word_count;\n\n    for (std::uint32_t word_index = 0; word_index < word_count; word_index++) {\n      std::uint64_t word = 0;\n      auto end_position = count - word_index * BASE_DIGITS;\n      auto start_position =\n          end_position > static_cast<std::uint32_t>(BASE_DIGITS)\n              ? end_position - static_cast<std::uint32_t>(BASE_DIGITS)\n              : 0U;\n      for (auto position = start_position; position < end_position;\n           position++) {\n        word = word * 10 + static_cast<std::uint64_t>(digits[position] - '0');\n      }\n      result.words[word_index] = word;\n    }\n\n    result.trim();\n    return result;\n  }\n\n  [[nodiscard]] auto to_uint128(std::int32_t exponent) const\n      -> sourcemeta::core::uint128_t {\n    sourcemeta::core::uint128_t value = 0;\n    for (auto index = this->length; index > 0; index--) {\n      value = value * BASE + this->words[index - 1];\n    }\n\n    while (exponent > 0) {\n      value *= 10;\n      exponent--;\n    }\n\n    return value;\n  }\n\n  struct AddSignedResult;\n\n  [[nodiscard]] static auto add_signed(const BigCoefficient &left,\n                                       const BigCoefficient &right,\n                                       bool left_negative, bool right_negative)\n      -> AddSignedResult;\n\n  static auto align_exponents(BigCoefficient &left, BigCoefficient &right,\n                              std::int32_t left_exponent,\n                              std::int32_t right_exponent) -> void;\n};\n\nstruct BigCoefficient::AddSignedResult {\n  BigCoefficient coefficient;\n  bool is_negative;\n};\n\nauto BigCoefficient::add_signed(const BigCoefficient &left,\n                                const BigCoefficient &right, bool left_negative,\n                                bool right_negative)\n    -> BigCoefficient::AddSignedResult {\n  if (left_negative == right_negative) {\n    return {.coefficient = left.add(right), .is_negative = left_negative};\n  }\n\n  auto comparison = left.compare(right);\n  if (comparison >= 0) {\n    return {.coefficient = left.subtract(right), .is_negative = left_negative};\n  }\n\n  return {.coefficient = right.subtract(left), .is_negative = right_negative};\n}\n\nauto BigCoefficient::align_exponents(BigCoefficient &left,\n                                     BigCoefficient &right,\n                                     std::int32_t left_exponent,\n                                     std::int32_t right_exponent) -> void {\n  if (left_exponent > right_exponent) {\n    left = left.multiply_pow10(\n        static_cast<std::uint32_t>(left_exponent - right_exponent));\n  } else if (right_exponent > left_exponent) {\n    right = right.multiply_pow10(\n        static_cast<std::uint32_t>(right_exponent - left_exponent));\n  }\n}\n\n// Lemire, \"Computing the number of digits of an integer even faster\" (2021)\nauto digit_count(std::uint64_t value) -> std::uint32_t {\n  if (value == 0) {\n    return 1;\n  }\n\n#if defined(_MSC_VER)\n  unsigned long bit_index;\n  _BitScanReverse64(&bit_index, value);\n  auto const bits = static_cast<std::uint32_t>(bit_index);\n#else\n  auto const bits = static_cast<std::uint32_t>(63 - __builtin_clzll(value));\n#endif\n  auto approximation = 1 + ((bits * 77) >> 8);\n  if (approximation <= 19 && value >= POWERS_OF_10[approximation]) {\n    approximation++;\n  }\n\n  return approximation;\n}\n\nauto store_big_pointer(std::int64_t &coefficient, BigCoefficient &&big)\n    -> void {\n  auto *heap_big = new BigCoefficient{std::move(big)};\n  // NOLINTNEXTLINE(performance-no-int-to-ptr)\n  auto as_integer = reinterpret_cast<std::uintptr_t>(heap_big);\n  std::memcpy(&coefficient, &as_integer, sizeof(coefficient));\n}\n\nauto load_big_pointer(std::int64_t coefficient) -> BigCoefficient * {\n  std::uintptr_t as_integer;\n  std::memcpy(&as_integer, &coefficient, sizeof(as_integer));\n  // NOLINTNEXTLINE(performance-no-int-to-ptr)\n  return reinterpret_cast<BigCoefficient *>(as_integer);\n}\n\nauto coefficient_to_digit_string(std::int64_t coefficient,\n                                 std::uint64_t coefficient_high,\n                                 std::uint8_t flags) -> std::string {\n  if (flags & FLAG_HEAP) {\n    return load_big_pointer(coefficient)->to_string();\n  }\n\n  if (flags & FLAG_BIG) {\n    auto high_string = std::to_string(coefficient_high);\n    auto low_string = std::to_string(static_cast<std::uint64_t>(coefficient));\n    std::string result = high_string;\n    result.append(static_cast<std::size_t>(BASE_DIGITS) - low_string.size(),\n                  '0');\n    result += low_string;\n    return result;\n  }\n\n  return std::to_string(coefficient);\n}\n\nauto modular_pow10(std::uint32_t exponent, std::uint64_t modulus)\n    -> std::uint64_t {\n  if (modulus == 1) {\n    return 0;\n  }\n\n  if (exponent == 0) {\n    return 1;\n  }\n\n  if (exponent <= 19) {\n    return POWERS_OF_10[exponent] % modulus;\n  }\n\n  std::uint64_t result = 1;\n  std::uint64_t base = 10 % modulus;\n  auto remaining = exponent;\n  while (remaining > 0) {\n    if (remaining & 1) {\n      result = static_cast<std::uint64_t>(\n          static_cast<sourcemeta::core::uint128_t>(result) * base % modulus);\n    }\n\n    base = static_cast<std::uint64_t>(\n        static_cast<sourcemeta::core::uint128_t>(base) * base % modulus);\n    remaining >>= 1;\n  }\n\n  return result;\n}\n\n// Round-half-even (banker's rounding) to WORKING_PRECISION significant digits\nconstexpr std::int32_t WORKING_PRECISION = 16;\n\nauto round_to_precision(std::int64_t &coefficient,\n                        std::uint64_t &coefficient_high, std::int32_t &exponent,\n                        std::uint8_t &flags) -> void {\n  if (flags & (FLAG_NAN | FLAG_SNAN | FLAG_INFINITE)) {\n    return;\n  }\n\n  if (flags & FLAG_BIG) {\n    auto digit_string =\n        coefficient_to_digit_string(coefficient, coefficient_high, flags);\n    auto total_digits = static_cast<std::int32_t>(digit_string.size());\n    if (total_digits <= WORKING_PRECISION) {\n      return;\n    }\n\n    auto excess = total_digits - WORKING_PRECISION;\n\n    auto kept =\n        digit_string.substr(0, static_cast<std::size_t>(WORKING_PRECISION));\n    auto dropped =\n        digit_string.substr(static_cast<std::size_t>(WORKING_PRECISION));\n\n    bool round_up = false;\n    if (!dropped.empty()) {\n      if (dropped[0] > '5') {\n        round_up = true;\n      } else if (dropped[0] == '5') {\n        bool has_trailing = false;\n        for (std::size_t index = 1; index < dropped.size(); index++) {\n          if (dropped[index] != '0') {\n            has_trailing = true;\n            break;\n          }\n        }\n\n        if (has_trailing) {\n          round_up = true;\n        } else {\n          round_up = (kept.back() - '0') % 2 != 0;\n        }\n      }\n    }\n\n    if (flags & FLAG_HEAP) {\n      delete load_big_pointer(coefficient);\n    }\n\n    std::int64_t new_coefficient = 0;\n    for (auto character : kept) {\n      new_coefficient = new_coefficient * 10 + (character - '0');\n    }\n    if (round_up) {\n      new_coefficient++;\n    }\n\n    coefficient = new_coefficient;\n    coefficient_high = 0;\n    exponent += excess;\n    flags = static_cast<std::uint8_t>(flags & ~(FLAG_BIG | FLAG_HEAP));\n    return;\n  }\n\n  auto digits = digit_count(static_cast<std::uint64_t>(coefficient));\n  if (static_cast<std::int32_t>(digits) <= WORKING_PRECISION) {\n    return;\n  }\n\n  auto excess = static_cast<std::int32_t>(digits) - WORKING_PRECISION;\n  std::int64_t divisor = 1;\n  for (std::int32_t index = 0; index < excess; index++) {\n    divisor *= 10;\n  }\n\n  auto quotient = coefficient / divisor;\n  auto remainder = coefficient % divisor;\n  auto half = divisor / 2;\n\n  if (remainder > half || (remainder == half && quotient % 2 != 0)) {\n    quotient++;\n  }\n\n  coefficient = quotient;\n  coefficient_high = 0;\n  exponent += excess;\n}\n\nvoid free_big_coefficient(std::int64_t coefficient, std::uint8_t flags) {\n  if (flags & FLAG_HEAP) {\n    delete load_big_pointer(coefficient);\n  }\n}\n\nauto coefficient_as_big(std::int64_t coefficient,\n                        std::uint64_t coefficient_high, std::uint8_t flags)\n    -> BigCoefficient {\n  if (flags & FLAG_HEAP) {\n    return load_big_pointer(coefficient)->clone();\n  }\n\n  if (flags & FLAG_BIG) {\n    BigCoefficient result{2};\n    result.words[0] = static_cast<std::uint64_t>(coefficient);\n    result.words[1] = coefficient_high;\n    result.length = coefficient_high > 0 ? 2 : 1;\n    return result;\n  }\n\n  return BigCoefficient::from_uint64(static_cast<std::uint64_t>(coefficient));\n}\n\nvoid store_big_result(std::int64_t &coefficient,\n                      std::uint64_t &coefficient_high, std::uint8_t &flags,\n                      BigCoefficient result_big, bool result_negative) {\n  if (result_big.length <= 1 &&\n      result_big.words[0] <= static_cast<std::uint64_t>(COMPACT_MAX)) {\n    coefficient = static_cast<std::int64_t>(result_big.words[0]);\n    coefficient_high = 0;\n    flags = result_negative ? FLAG_SIGN : 0;\n  } else if (result_big.length <= 2) {\n    coefficient = static_cast<std::int64_t>(result_big.words[0]);\n    coefficient_high = result_big.length > 1 ? result_big.words[1] : 0;\n    flags =\n        static_cast<std::uint8_t>(FLAG_BIG | (result_negative ? FLAG_SIGN : 0));\n  } else {\n    store_big_pointer(coefficient, std::move(result_big));\n    coefficient_high = 0;\n    flags = static_cast<std::uint8_t>(FLAG_BIG | FLAG_HEAP |\n                                      (result_negative ? FLAG_SIGN : 0));\n  }\n}\n\n} // namespace\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/decimal.cc",
    "content": "#include <sourcemeta/core/numeric_decimal.h>\n#include <sourcemeta/core/numeric_error.h>\n\n#include \"big_coefficient.h\"\n\n#include <array>     // std::array\n#include <cassert>   // assert\n#include <charconv>  // std::to_chars\n#include <cmath>     // std::isfinite\n#include <cstddef>   // std::size_t\n#include <cstring>   // std::strlen\n#include <iomanip>   // std::setprecision\n#include <limits>    // std::numeric_limits\n#include <sstream>   // std::ostringstream\n#include <stdexcept> // std::out_of_range\n#include <string>    // std::string, std::stof, std::stod\n\nnamespace {\n\nauto strip_trailing_zeros(std::int64_t &coefficient, std::int32_t &exponent)\n    -> void {\n  if (coefficient == 0) {\n    return;\n  }\n\n  constexpr std::int64_t POWER_OF_10_16 = 10000000000000000LL;\n  if (coefficient % POWER_OF_10_16 == 0) {\n    coefficient /= POWER_OF_10_16;\n    exponent += 16;\n  }\n\n  if (coefficient % 100000000 == 0) {\n    coefficient /= 100000000;\n    exponent += 8;\n  }\n\n  if (coefficient % 10000 == 0) {\n    coefficient /= 10000;\n    exponent += 4;\n  }\n\n  if (coefficient % 100 == 0) {\n    coefficient /= 100;\n    exponent += 2;\n  }\n\n  if (coefficient % 10 == 0) {\n    coefficient /= 10;\n    exponent += 1;\n  }\n}\n\ntemplate <typename FloatingPointType>\n  requires std::is_floating_point_v<FloatingPointType>\nauto floating_point_to_string(const FloatingPointType value) -> std::string {\n  std::ostringstream stream;\n  stream << std::setprecision(\n                std::numeric_limits<FloatingPointType>::max_digits10)\n         << value;\n  return stream.str();\n}\n\nstruct ParsedDecimal {\n  std::int64_t coefficient;\n  std::uint64_t coefficient_high;\n  std::int32_t exponent;\n  std::uint8_t flags;\n};\n\nauto parse_digit_payload(const char *cursor, std::size_t count)\n    -> std::int64_t {\n  std::int64_t payload = 0;\n  for (std::size_t index = 0; index < count; index++) {\n    payload = payload * 10 + (cursor[index] - '0');\n  }\n\n  return payload;\n}\n\nauto parse_special(const char *input, std::size_t length) -> ParsedDecimal * {\n  static ParsedDecimal result;\n  const char *cursor = input;\n  std::uint8_t sign_flag = 0;\n\n  if (length > 0 && (*cursor == '-' || *cursor == '+')) {\n    if (*cursor == '-') {\n      sign_flag = FLAG_SIGN;\n    }\n\n    cursor++;\n  }\n\n  auto remaining = length - static_cast<std::size_t>(cursor - input);\n\n  if (remaining >= 3 && (cursor[0] == 'N' || cursor[0] == 'n') &&\n      (cursor[1] == 'a' || cursor[1] == 'A') &&\n      (cursor[2] == 'N' || cursor[2] == 'n')) {\n    result.flags = FLAG_NAN | sign_flag;\n    result.exponent = 0;\n    result.coefficient_high = 0;\n    result.coefficient = parse_digit_payload(cursor + 3, remaining - 3);\n    return &result;\n  }\n\n  if (remaining >= 4 && (cursor[0] == 's' || cursor[0] == 'S') &&\n      (cursor[1] == 'N' || cursor[1] == 'n') &&\n      (cursor[2] == 'a' || cursor[2] == 'A') &&\n      (cursor[3] == 'N' || cursor[3] == 'n')) {\n    result.flags = FLAG_NAN | FLAG_SNAN | sign_flag;\n    result.exponent = 0;\n    result.coefficient_high = 0;\n    result.coefficient = parse_digit_payload(cursor + 4, remaining - 4);\n    return &result;\n  }\n\n  if (remaining >= 3 && (cursor[0] == 'I' || cursor[0] == 'i') &&\n      (cursor[1] == 'n' || cursor[1] == 'N') &&\n      (cursor[2] == 'f' || cursor[2] == 'F') &&\n      (remaining == 3 ||\n       (remaining == 8 && (cursor[3] == 'i' || cursor[3] == 'I') &&\n        (cursor[4] == 'n' || cursor[4] == 'N') &&\n        (cursor[5] == 'i' || cursor[5] == 'I') &&\n        (cursor[6] == 't' || cursor[6] == 'T') &&\n        (cursor[7] == 'y' || cursor[7] == 'Y')))) {\n    result.flags = FLAG_INFINITE | sign_flag;\n    result.coefficient = 0;\n    result.exponent = 0;\n    result.coefficient_high = 0;\n    return &result;\n  }\n\n  return nullptr;\n}\n\nauto parse_decimal_string(const char *input, std::size_t length)\n    -> ParsedDecimal {\n  auto *special = parse_special(input, length);\n  if (special) {\n    return *special;\n  }\n\n  ParsedDecimal result{\n      .coefficient = 0, .coefficient_high = 0, .exponent = 0, .flags = 0};\n  const char *cursor = input;\n  const char *end = input + length;\n\n  if (cursor < end && *cursor == '-') {\n    result.flags = FLAG_SIGN;\n    cursor++;\n  } else if (cursor < end && *cursor == '+') {\n    cursor++;\n  }\n\n  if (cursor >= end) {\n    throw sourcemeta::core::DecimalParseError{};\n  }\n\n  std::array<char, 1024> digit_buffer{};\n  std::uint32_t digit_count_total = 0;\n  std::int32_t decimal_offset = -1;\n  bool has_digit = false;\n\n  while (cursor < end) {\n    if (*cursor >= '0' && *cursor <= '9') {\n      if (digit_count_total < digit_buffer.size()) {\n        digit_buffer[digit_count_total] = *cursor;\n      }\n\n      digit_count_total++;\n      has_digit = true;\n    } else if (*cursor == '.') {\n      if (decimal_offset >= 0) {\n        throw sourcemeta::core::DecimalParseError{};\n      }\n\n      decimal_offset = static_cast<std::int32_t>(digit_count_total);\n    } else if (*cursor == 'e' || *cursor == 'E') {\n      cursor++;\n      break;\n    } else {\n      throw sourcemeta::core::DecimalParseError{};\n    }\n\n    cursor++;\n  }\n\n  if (!has_digit) {\n    throw sourcemeta::core::DecimalParseError{};\n  }\n\n  std::int64_t exponent_suffix_64 = 0;\n  bool has_exponent_marker =\n      cursor > input && (*(cursor - 1) == 'e' || *(cursor - 1) == 'E');\n  if (decimal_offset < 0 && !has_exponent_marker) {\n    result.flags |= FLAG_INTEGER_LITERAL;\n  }\n  if (cursor < end) {\n    bool is_exponent_negative = false;\n    if (*cursor == '-') {\n      is_exponent_negative = true;\n      cursor++;\n    } else if (*cursor == '+') {\n      cursor++;\n    }\n\n    bool has_exponent_digit = false;\n    while (cursor < end && *cursor >= '0' && *cursor <= '9') {\n      exponent_suffix_64 = exponent_suffix_64 * 10 + (*cursor - '0');\n      has_exponent_digit = true;\n      cursor++;\n      if (exponent_suffix_64 > 4000000000LL) {\n        while (cursor < end && *cursor >= '0' && *cursor <= '9') {\n          cursor++;\n        }\n\n        break;\n      }\n    }\n\n    if (!has_exponent_digit) {\n      throw sourcemeta::core::DecimalParseError{};\n    }\n\n    if (cursor < end) {\n      throw sourcemeta::core::DecimalParseError{};\n    }\n\n    if (is_exponent_negative) {\n      exponent_suffix_64 = -exponent_suffix_64;\n    }\n\n  } else if (has_exponent_marker) {\n    throw sourcemeta::core::DecimalParseError{};\n  }\n\n  auto exponent_suffix = static_cast<std::int32_t>(std::min(\n      std::max(\n          exponent_suffix_64,\n          static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::min())),\n      static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::max())));\n\n  if (decimal_offset >= 0) {\n    result.exponent =\n        exponent_suffix -\n        (static_cast<std::int32_t>(digit_count_total) - decimal_offset);\n  } else {\n    result.exponent = exponent_suffix;\n  }\n\n  std::uint32_t leading_zeros = 0;\n  while (leading_zeros < digit_count_total - 1 &&\n         digit_buffer[leading_zeros] == '0') {\n    leading_zeros++;\n  }\n\n  auto significant_digits = digit_count_total - leading_zeros;\n\n  if (significant_digits <= 18) {\n    std::int64_t coefficient = 0;\n    for (std::uint32_t index = leading_zeros; index < digit_count_total;\n         index++) {\n      coefficient = coefficient * 10 + (digit_buffer[index] - '0');\n    }\n\n    result.coefficient = coefficient;\n  } else if (significant_digits <= 36) {\n    auto low_start = leading_zeros + significant_digits -\n                     static_cast<std::uint32_t>(BASE_DIGITS);\n    std::uint64_t low_word = 0;\n    for (std::uint32_t index = low_start;\n         index < leading_zeros + significant_digits; index++) {\n      low_word =\n          low_word * 10 + static_cast<std::uint64_t>(digit_buffer[index] - '0');\n    }\n\n    std::uint64_t high_word = 0;\n    for (std::uint32_t index = leading_zeros; index < low_start; index++) {\n      high_word = high_word * 10 +\n                  static_cast<std::uint64_t>(digit_buffer[index] - '0');\n    }\n\n    result.coefficient = static_cast<std::int64_t>(low_word);\n    result.coefficient_high = high_word;\n    result.flags |= FLAG_BIG;\n  } else {\n    auto big = BigCoefficient::from_digits(digit_buffer.data() + leading_zeros,\n                                           significant_digits);\n    store_big_pointer(result.coefficient, std::move(big));\n    result.coefficient_high = 0;\n    result.flags |= static_cast<std::uint8_t>(FLAG_BIG | FLAG_HEAP);\n  }\n\n  return result;\n}\n\ntemplate <typename FloatingPointType>\nauto is_representable_as_floating_point(\n    const sourcemeta::core::Decimal &decimal) -> bool {\n  if (decimal.is_nan() || decimal.is_infinite()) {\n    return true;\n  }\n\n  if (!decimal.is_finite()) {\n    return false;\n  }\n\n  const std::string decimal_string{decimal.to_scientific_string()};\n  FloatingPointType converted_value;\n  try {\n    if constexpr (std::is_same_v<FloatingPointType, float>) {\n      converted_value = std::stof(decimal_string);\n    } else if constexpr (std::is_same_v<FloatingPointType, double>) {\n      converted_value = std::stod(decimal_string);\n    }\n\n  } catch (const std::out_of_range &) {\n    return false;\n  }\n\n  if (!std::isfinite(converted_value)) {\n    return false;\n  }\n\n  std::ostringstream stream;\n  stream << std::setprecision(\n                std::numeric_limits<FloatingPointType>::max_digits10)\n         << converted_value;\n  const sourcemeta::core::Decimal roundtrip{stream.str()};\n  return decimal == roundtrip;\n}\n\nvoid check_exponent_overflow(std::int32_t left_exponent,\n                             std::int32_t right_exponent) {\n  if (left_exponent == std::numeric_limits<std::int32_t>::max() ||\n      left_exponent == std::numeric_limits<std::int32_t>::min() ||\n      right_exponent == std::numeric_limits<std::int32_t>::max() ||\n      right_exponent == std::numeric_limits<std::int32_t>::min()) {\n    throw sourcemeta::core::NumericOverflowError{};\n  }\n}\n\nauto format_special_value(std::string &result, std::uint8_t flags,\n                          std::int64_t coefficient) -> bool {\n  if (flags & FLAG_NAN) {\n    if (flags & FLAG_SIGN) {\n      result += '-';\n    }\n\n    if (flags & FLAG_SNAN) {\n      result += \"sNaN\";\n    } else {\n      result += \"NaN\";\n    }\n\n    if (coefficient > 0) {\n      result += std::to_string(coefficient);\n    }\n\n    return true;\n  }\n\n  if (flags & FLAG_INFINITE) {\n    if (flags & FLAG_SIGN) {\n      result += '-';\n    }\n\n    result += \"Infinity\";\n    return true;\n  }\n\n  return false;\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nDecimal::Decimal() noexcept = default;\n\nDecimal::~Decimal() { free_big_coefficient(this->coefficient_, this->flags_); }\n\nDecimal::Decimal(const Decimal &other)\n    : coefficient_{other.coefficient_},\n      coefficient_high_{other.coefficient_high_}, exponent_{other.exponent_},\n      flags_{other.flags_} {\n  if (other.flags_ & FLAG_HEAP) {\n    store_big_pointer(this->coefficient_,\n                      load_big_pointer(other.coefficient_)->clone());\n  }\n}\n\nDecimal::Decimal(Decimal &&other) noexcept\n    : coefficient_{other.coefficient_},\n      coefficient_high_{other.coefficient_high_}, exponent_{other.exponent_},\n      flags_{other.flags_} {\n  other.coefficient_ = 0;\n  other.coefficient_high_ = 0;\n  other.exponent_ = 0;\n  other.flags_ = 0;\n}\n\nauto Decimal::operator=(const Decimal &other) -> Decimal & {\n  if (this != &other) {\n    free_big_coefficient(this->coefficient_, this->flags_);\n    this->coefficient_ = other.coefficient_;\n    this->coefficient_high_ = other.coefficient_high_;\n    this->exponent_ = other.exponent_;\n    this->flags_ = other.flags_;\n    if (other.flags_ & FLAG_HEAP) {\n      store_big_pointer(this->coefficient_,\n                        load_big_pointer(other.coefficient_)->clone());\n    }\n  }\n\n  return *this;\n}\n\nauto Decimal::operator=(Decimal &&other) noexcept -> Decimal & {\n  if (this != &other) {\n    free_big_coefficient(this->coefficient_, this->flags_);\n    this->coefficient_ = other.coefficient_;\n    this->coefficient_high_ = other.coefficient_high_;\n    this->exponent_ = other.exponent_;\n    this->flags_ = other.flags_;\n    other.coefficient_ = 0;\n    other.coefficient_high_ = 0;\n    other.exponent_ = 0;\n    other.flags_ = 0;\n  }\n\n  return *this;\n}\n\nDecimal::Decimal(const std::int64_t value) {\n  if (value == std::numeric_limits<std::int64_t>::min()) {\n    auto absolute_value = static_cast<std::uint64_t>(-(value + 1)) + 1;\n    this->coefficient_ = static_cast<std::int64_t>(absolute_value % BASE);\n    this->coefficient_high_ = absolute_value / BASE;\n    this->flags_ = FLAG_BIG | FLAG_SIGN | FLAG_INTEGER_LITERAL;\n  } else if (value < 0) {\n    this->coefficient_ = -value;\n    this->flags_ = FLAG_SIGN | FLAG_INTEGER_LITERAL;\n  } else {\n    this->coefficient_ = value;\n    this->flags_ = FLAG_INTEGER_LITERAL;\n  }\n}\n\nDecimal::Decimal(const std::uint64_t value) {\n  if (value > static_cast<std::uint64_t>(COMPACT_MAX)) {\n    this->coefficient_ = static_cast<std::int64_t>(value % BASE);\n    this->coefficient_high_ = value / BASE;\n    this->flags_ = FLAG_BIG | FLAG_INTEGER_LITERAL;\n  } else {\n    this->coefficient_ = static_cast<std::int64_t>(value);\n    this->flags_ = FLAG_INTEGER_LITERAL;\n  }\n}\n\nDecimal::Decimal(const float value) : Decimal{floating_point_to_string(value)} {\n  this->flags_ =\n      static_cast<std::uint8_t>(this->flags_ & ~FLAG_INTEGER_LITERAL);\n}\n\nDecimal::Decimal(const double value)\n    : Decimal{floating_point_to_string(value)} {\n  this->flags_ =\n      static_cast<std::uint8_t>(this->flags_ & ~FLAG_INTEGER_LITERAL);\n}\n\nDecimal::Decimal(const char *const value) {\n  auto parsed = parse_decimal_string(value, std::strlen(value));\n  this->coefficient_ = parsed.coefficient;\n  this->coefficient_high_ = parsed.coefficient_high;\n  this->exponent_ = parsed.exponent;\n  this->flags_ = parsed.flags;\n}\n\nDecimal::Decimal(const std::string &value) {\n  auto parsed = parse_decimal_string(value.c_str(), value.size());\n  this->coefficient_ = parsed.coefficient;\n  this->coefficient_high_ = parsed.coefficient_high;\n  this->exponent_ = parsed.exponent;\n  this->flags_ = parsed.flags;\n}\n\nDecimal::Decimal(const std::string_view value) {\n  auto parsed = parse_decimal_string(value.data(), value.size());\n  this->coefficient_ = parsed.coefficient;\n  this->coefficient_high_ = parsed.coefficient_high;\n  this->exponent_ = parsed.exponent;\n  this->flags_ = parsed.flags;\n}\n\nauto Decimal::nan(const std::uint64_t payload) -> Decimal {\n  Decimal result;\n  result.flags_ = FLAG_NAN;\n  result.coefficient_ = static_cast<std::int64_t>(payload);\n  return result;\n}\n\nauto Decimal::snan(const std::uint64_t payload) -> Decimal {\n  Decimal result;\n  result.flags_ = FLAG_NAN | FLAG_SNAN;\n  result.coefficient_ = static_cast<std::int64_t>(payload);\n  return result;\n}\n\nauto Decimal::infinity() -> Decimal {\n  Decimal result;\n  result.flags_ = FLAG_INFINITE;\n  return result;\n}\n\nauto Decimal::negative_infinity() -> Decimal {\n  Decimal result;\n  result.flags_ = FLAG_INFINITE | FLAG_SIGN;\n  return result;\n}\n\nauto Decimal::strict_from(const double value) -> Decimal {\n  std::array<char, 64> buffer{};\n  const auto result{\n      std::to_chars(buffer.data(), buffer.data() + buffer.size(), value)};\n  assert(result.ec == std::errc{});\n  Decimal output{std::string_view{\n      buffer.data(), static_cast<std::size_t>(result.ptr - buffer.data())}};\n  output.flags_ =\n      static_cast<std::uint8_t>(output.flags_ & ~FLAG_INTEGER_LITERAL);\n  return output;\n}\n\nauto Decimal::to_scientific_string() const -> std::string {\n  std::string result;\n\n  if (format_special_value(result, this->flags_, this->coefficient_)) {\n    return result;\n  }\n\n  auto digit_string = coefficient_to_digit_string(\n      this->coefficient_, this->coefficient_high_, this->flags_);\n  auto number_of_digits = static_cast<std::int32_t>(digit_string.size());\n  auto adjusted_exponent = this->exponent_ + number_of_digits - 1;\n\n  if (this->flags_ & FLAG_SIGN) {\n    result += '-';\n  }\n\n  if (number_of_digits == 1) {\n    result += digit_string;\n  } else {\n    result += digit_string[0];\n    result += '.';\n    result += digit_string.substr(1);\n  }\n\n  result += 'e';\n  if (adjusted_exponent >= 0) {\n    result += '+';\n  }\n\n  result += std::to_string(adjusted_exponent);\n\n  return result;\n}\n\n// General Decimal Arithmetic spec, to-engineering-string\nauto Decimal::to_string() const -> std::string {\n  std::string result;\n\n  if (format_special_value(result, this->flags_, this->coefficient_)) {\n    return result;\n  }\n\n  auto digit_string = coefficient_to_digit_string(\n      this->coefficient_, this->coefficient_high_, this->flags_);\n  auto number_of_digits = static_cast<std::int32_t>(digit_string.size());\n  auto integer_digit_count = number_of_digits + this->exponent_;\n\n  std::int32_t decimal_place;\n  if (this->exponent_ <= 0 && integer_digit_count > -6) {\n    decimal_place = integer_digit_count;\n  } else if (this->coefficient_ == 0 && !(this->flags_ & FLAG_BIG)) {\n    decimal_place = -1 + ((this->exponent_ + 2) % 3 + 3) % 3;\n  } else {\n    decimal_place = integer_digit_count +\n                    ((integer_digit_count - 1) % 3 + 3) % 3 -\n                    ((integer_digit_count - 1) % 3 + 3) % 3;\n    auto adjusted = integer_digit_count - 1;\n    auto remainder = ((adjusted % 3) + 3) % 3;\n    decimal_place = 1 + remainder;\n  }\n\n  if (this->flags_ & FLAG_SIGN) {\n    result += '-';\n  }\n\n  if (decimal_place <= 0) {\n    result += \"0.\";\n    for (std::int32_t index = 0; index < -decimal_place; index++) {\n      result += '0';\n    }\n\n    result += digit_string;\n  } else if (decimal_place >= number_of_digits) {\n    result += digit_string;\n    for (std::int32_t index = 0; index < decimal_place - number_of_digits;\n         index++) {\n      result += '0';\n    }\n\n  } else {\n    result += digit_string.substr(0, static_cast<std::size_t>(decimal_place));\n    result += '.';\n    result += digit_string.substr(static_cast<std::size_t>(decimal_place));\n  }\n\n  if (integer_digit_count != decimal_place) {\n    result += 'e';\n    auto engineering_exponent = integer_digit_count - decimal_place;\n    if (engineering_exponent >= 0) {\n      result += '+';\n    }\n\n    result += std::to_string(engineering_exponent);\n  }\n\n  return result;\n}\n\nauto Decimal::to_int64() const -> std::int64_t {\n  assert(this->is_int64());\n\n  if (this->flags_ & FLAG_BIG) {\n    auto big = coefficient_as_big(this->coefficient_, this->coefficient_high_,\n                                  this->flags_);\n    auto value = big.to_uint128(this->exponent_);\n    if (this->flags_ & FLAG_SIGN) {\n      return -static_cast<std::int64_t>(value);\n    }\n\n    return static_cast<std::int64_t>(value);\n  }\n\n  auto coefficient = this->coefficient_;\n  auto exponent = this->exponent_;\n  while (exponent > 0) {\n    coefficient *= 10;\n    exponent--;\n  }\n\n  return (this->flags_ & FLAG_SIGN) ? -coefficient : coefficient;\n}\n\nauto Decimal::to_int32() const -> std::int32_t {\n  assert(this->is_int32());\n  return static_cast<std::int32_t>(this->to_int64());\n}\n\nauto Decimal::to_uint64() const -> std::uint64_t {\n  assert(this->is_uint64());\n\n  if (this->flags_ & FLAG_BIG) {\n    auto big = coefficient_as_big(this->coefficient_, this->coefficient_high_,\n                                  this->flags_);\n    auto value = static_cast<std::uint64_t>(big.to_uint128(this->exponent_));\n    return value;\n  }\n\n  auto coefficient = this->coefficient_;\n  auto exponent = this->exponent_;\n\n  auto result = static_cast<std::uint64_t>(coefficient);\n  while (exponent > 0) {\n    result *= 10;\n    exponent--;\n  }\n\n  return result;\n}\n\nauto Decimal::to_uint32() const -> std::uint32_t {\n  assert(this->is_uint32());\n  return static_cast<std::uint32_t>(this->to_uint64());\n}\n\nauto Decimal::to_float() const -> float {\n  return std::stof(this->to_scientific_string());\n}\n\nauto Decimal::to_double() const -> double {\n  return std::stod(this->to_scientific_string());\n}\n\nauto Decimal::is_zero() const -> bool {\n  if (this->flags_ & SPECIAL_MASK) {\n    if (this->flags_ & FLAG_HEAP) {\n      return load_big_pointer(this->coefficient_)->is_zero();\n    }\n\n    if (this->flags_ & FLAG_BIG) {\n      return this->coefficient_ == 0 && this->coefficient_high_ == 0;\n    }\n\n    return false;\n  }\n\n  return this->coefficient_ == 0;\n}\n\nauto Decimal::is_integral() const -> bool {\n  if (this->flags_ & (FLAG_NAN | FLAG_SNAN | FLAG_INFINITE)) {\n    return false;\n  }\n\n  if (this->exponent_ >= 0) {\n    return true;\n  }\n\n  if (this->is_zero()) {\n    return true;\n  }\n\n  if (this->flags_ & FLAG_BIG) {\n    auto big = coefficient_as_big(this->coefficient_, this->coefficient_high_,\n                                  this->flags_);\n    auto stripped = big.strip_trailing_zeros();\n    return stripped >= -this->exponent_;\n  }\n\n  auto coefficient = this->coefficient_;\n  auto exponent = this->exponent_;\n  while (exponent < 0 && coefficient != 0 && coefficient % 10 == 0) {\n    coefficient /= 10;\n    exponent++;\n  }\n\n  return exponent >= 0;\n}\n\nauto Decimal::is_float() const -> bool {\n  return is_representable_as_floating_point<float>(*this);\n}\n\nauto Decimal::is_double() const -> bool {\n  return is_representable_as_floating_point<double>(*this);\n}\n\nauto Decimal::is_int32() const -> bool {\n  assert(this->is_integral());\n  return *this >= Decimal{std::numeric_limits<std::int32_t>::min()} &&\n         *this <= Decimal{std::numeric_limits<std::int32_t>::max()};\n}\n\nauto Decimal::is_int64() const -> bool {\n  assert(this->is_integral());\n  return *this >= Decimal{std::numeric_limits<std::int64_t>::min()} &&\n         *this <= Decimal{std::numeric_limits<std::int64_t>::max()};\n}\n\nauto Decimal::is_uint32() const -> bool {\n  assert(this->is_integral());\n  return *this >= Decimal{0} &&\n         *this <= Decimal{std::numeric_limits<std::uint32_t>::max()};\n}\n\nauto Decimal::is_uint64() const -> bool {\n  assert(this->is_integral());\n  return *this >= Decimal{0} &&\n         *this <= Decimal{std::numeric_limits<std::uint64_t>::max()};\n}\n\nauto Decimal::to_integral() const -> Decimal {\n  if (!this->is_finite()) {\n    return *this;\n  }\n\n  if (this->exponent_ >= 0) {\n    return *this;\n  }\n\n  if (this->flags_ & FLAG_BIG) {\n    auto digit_string = coefficient_to_digit_string(\n        this->coefficient_, this->coefficient_high_, this->flags_);\n    auto number_of_digits = static_cast<std::int32_t>(digit_string.size());\n    auto digits_to_remove = -this->exponent_;\n\n    if (digits_to_remove >= number_of_digits) {\n      Decimal result;\n      return result;\n    }\n\n    auto integer_string = digit_string.substr(\n        0, static_cast<std::size_t>(number_of_digits - digits_to_remove));\n    Decimal result{integer_string};\n    if (this->flags_ & FLAG_SIGN) {\n      result.flags_ |= FLAG_SIGN;\n    }\n\n    return result;\n  }\n\n  auto coefficient = this->coefficient_;\n  auto digits_to_remove = -this->exponent_;\n\n  if (static_cast<std::uint32_t>(digits_to_remove) >=\n      digit_count(static_cast<std::uint64_t>(coefficient))) {\n    return Decimal{};\n  }\n\n  std::int64_t divisor = 1;\n  for (std::int32_t index = 0; index < digits_to_remove; index++) {\n    divisor *= 10;\n  }\n\n  auto quotient = coefficient / divisor;\n  auto remainder = coefficient % divisor;\n  auto half = divisor / 2;\n\n  if (remainder > half || (remainder == half && quotient % 2 != 0)) {\n    quotient++;\n  }\n\n  Decimal result;\n  result.coefficient_ = quotient;\n  result.exponent_ = 0;\n  if (this->flags_ & FLAG_SIGN) {\n    result.flags_ = FLAG_SIGN;\n  }\n\n  return result;\n}\n\nauto Decimal::divisible_by(const Decimal &divisor) const -> bool {\n  if (divisor.is_zero()) {\n    return false;\n  }\n\n  if (this->is_zero()) {\n    return true;\n  }\n\n  if (!this->is_finite() || !divisor.is_finite()) {\n    return false;\n  }\n\n  if (!(divisor.flags_ & FLAG_BIG) && !(this->flags_ & FLAG_HEAP)) {\n    auto divisor_value = static_cast<std::uint64_t>(divisor.coefficient_);\n\n    std::uint64_t dividend_mod;\n    if (this->flags_ & FLAG_BIG) {\n      auto hi_mod = this->coefficient_high_ % divisor_value;\n      auto base_mod = BASE % divisor_value;\n      auto lo_mod =\n          static_cast<std::uint64_t>(this->coefficient_) % divisor_value;\n      dividend_mod = static_cast<std::uint64_t>(\n          (static_cast<sourcemeta::core::uint128_t>(hi_mod) * base_mod +\n           lo_mod) %\n          divisor_value);\n    } else {\n      dividend_mod =\n          static_cast<std::uint64_t>(this->coefficient_) % divisor_value;\n    }\n\n    if (this->exponent_ >= divisor.exponent_) {\n      auto difference =\n          static_cast<std::uint32_t>(this->exponent_ - divisor.exponent_);\n      auto pow_mod = modular_pow10(difference, divisor_value);\n      return static_cast<std::uint64_t>(\n                 static_cast<sourcemeta::core::uint128_t>(dividend_mod) *\n                 pow_mod % divisor_value) == 0;\n    }\n\n    auto difference =\n        static_cast<std::uint32_t>(divisor.exponent_ - this->exponent_);\n    if (difference > 36) {\n      return false;\n    }\n\n    sourcemeta::core::uint128_t remaining;\n    if (this->flags_ & FLAG_BIG) {\n      remaining =\n          static_cast<sourcemeta::core::uint128_t>(this->coefficient_high_) *\n              BASE +\n          static_cast<std::uint64_t>(this->coefficient_);\n    } else {\n      remaining = static_cast<sourcemeta::core::uint128_t>(\n          static_cast<std::uint64_t>(this->coefficient_));\n    }\n\n    auto diff_left = difference;\n    while (diff_left > 0) {\n      auto chunk = std::min(diff_left, static_cast<std::uint32_t>(19));\n      auto power = POWERS_OF_10[chunk];\n      if (static_cast<std::uint64_t>(remaining % power) != 0) {\n        return false;\n      }\n\n      remaining = remaining / power;\n      diff_left -= chunk;\n    }\n\n    return static_cast<std::uint64_t>(remaining % divisor_value) == 0;\n  }\n\n  auto dividend_big = coefficient_as_big(this->coefficient_,\n                                         this->coefficient_high_, this->flags_);\n  auto divisor_big = coefficient_as_big(\n      divisor.coefficient_, divisor.coefficient_high_, divisor.flags_);\n\n  BigCoefficient::align_exponents(dividend_big, divisor_big, this->exponent_,\n                                  divisor.exponent_);\n\n  auto [quotient, remainder] = dividend_big.divide_modulo(divisor_big);\n\n  return remainder.is_zero();\n}\n\nauto Decimal::same_quantum(const Decimal &other) const -> bool {\n  if (this->is_nan() && other.is_nan()) {\n    return true;\n  }\n\n  if (this->is_infinite() && other.is_infinite()) {\n    return true;\n  }\n\n  if (this->is_nan() || other.is_nan() || this->is_infinite() ||\n      other.is_infinite()) {\n    return false;\n  }\n\n  return this->exponent_ == other.exponent_;\n}\n\nauto Decimal::reduce() const -> Decimal {\n  if (!this->is_finite()) {\n    return *this;\n  }\n\n  if (this->is_zero()) {\n    Decimal result;\n    if (this->flags_ & FLAG_SIGN) {\n      result.flags_ = FLAG_SIGN;\n    }\n\n    return result;\n  }\n\n  if (this->flags_ & FLAG_BIG) {\n    auto big = coefficient_as_big(this->coefficient_, this->coefficient_high_,\n                                  this->flags_);\n    auto stripped_count = big.strip_trailing_zeros();\n    auto new_exponent =\n        static_cast<std::int64_t>(this->exponent_) + stripped_count;\n    if (new_exponent > std::numeric_limits<std::int32_t>::max() ||\n        new_exponent < std::numeric_limits<std::int32_t>::min()) {\n      throw NumericOverflowError{};\n    }\n\n    Decimal result;\n    bool result_negative = (this->flags_ & FLAG_SIGN) != 0;\n    store_big_result(result.coefficient_, result.coefficient_high_,\n                     result.flags_, std::move(big), result_negative);\n    result.exponent_ = static_cast<std::int32_t>(new_exponent);\n    return result;\n  }\n\n  auto coefficient = this->coefficient_;\n  auto exponent = this->exponent_;\n  strip_trailing_zeros(coefficient, exponent);\n\n  Decimal result;\n  result.coefficient_ = coefficient;\n  result.exponent_ = exponent;\n  if (this->flags_ & FLAG_SIGN) {\n    result.flags_ = FLAG_SIGN;\n  }\n\n  return result;\n}\n\nauto Decimal::logb() const -> Decimal {\n  if (this->is_nan()) {\n    return *this;\n  }\n\n  if (this->is_infinite()) {\n    return Decimal::infinity();\n  }\n\n  if (this->is_zero()) {\n    throw NumericDivisionByZeroError{};\n  }\n\n  std::int64_t digits;\n  if (this->flags_ & FLAG_BIG) {\n    auto big = coefficient_as_big(this->coefficient_, this->coefficient_high_,\n                                  this->flags_);\n    digits = static_cast<std::int64_t>(big.digit_count());\n  } else {\n    digits = static_cast<std::int64_t>(\n        digit_count(static_cast<std::uint64_t>(this->coefficient_)));\n  }\n\n  auto adjusted = digits + this->exponent_ - 1;\n  return Decimal{adjusted};\n}\n\nauto Decimal::scale_by(const Decimal &scale) const -> Decimal {\n  if (this->is_snan()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (scale.is_snan()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (this->is_qnan()) {\n    return *this;\n  }\n\n  if (scale.is_qnan()) {\n    return scale;\n  }\n\n  if (!scale.is_finite() || scale.exponent_ != 0) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (this->is_infinite()) {\n    return *this;\n  }\n\n  if (!scale.is_int64()) {\n    throw NumericOverflowError{};\n  }\n\n  auto scale_value = scale.to_int64();\n  auto new_exponent = static_cast<std::int64_t>(this->exponent_) + scale_value;\n  if (new_exponent > std::numeric_limits<std::int32_t>::max() ||\n      new_exponent < std::numeric_limits<std::int32_t>::min()) {\n    throw NumericOverflowError{};\n  }\n\n  Decimal result{*this};\n  result.exponent_ = static_cast<std::int32_t>(new_exponent);\n  return result;\n}\n\nauto Decimal::compare_total(const Decimal &other) const -> Decimal {\n  auto classify = [](const Decimal &value) -> int {\n    if (value.is_qnan()) {\n      return value.is_signed() ? -6 : 6;\n    }\n\n    if (value.is_snan()) {\n      return value.is_signed() ? -5 : 5;\n    }\n\n    if (value.is_infinite()) {\n      return value.is_signed() ? -4 : 4;\n    }\n\n    if (value.is_zero()) {\n      return value.is_signed() ? -2 : 2;\n    }\n\n    return value.is_signed() ? -3 : 3;\n  };\n\n  auto left_class = classify(*this);\n  auto right_class = classify(other);\n\n  if (left_class != right_class) {\n    if (left_class < right_class) {\n      return Decimal{-1};\n    }\n\n    return Decimal{1};\n  }\n\n  bool is_negative = left_class < 0;\n\n  if (this->is_nan()) {\n    auto left_payload = this->nan_payload();\n    auto right_payload = other.nan_payload();\n    if (left_payload != right_payload) {\n      bool left_less = left_payload < right_payload;\n      if (is_negative) {\n        left_less = !left_less;\n      }\n\n      return left_less ? Decimal{-1} : Decimal{1};\n    }\n\n    return Decimal{0};\n  }\n\n  if (this->is_infinite()) {\n    return Decimal{0};\n  }\n\n  if (this->is_zero()) {\n    if (this->exponent_ != other.exponent_) {\n      bool left_less = this->exponent_ < other.exponent_;\n      if (is_negative) {\n        left_less = !left_less;\n      }\n\n      return left_less ? Decimal{-1} : Decimal{1};\n    }\n\n    return Decimal{0};\n  }\n\n  int magnitude_compare;\n  if ((this->flags_ & FLAG_BIG) || (other.flags_ & FLAG_BIG)) {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n    auto left_digit_count = static_cast<std::int64_t>(left_big.digit_count());\n    auto right_digit_count = static_cast<std::int64_t>(right_big.digit_count());\n    auto left_adjusted = this->exponent_ + left_digit_count - 1;\n    auto right_adjusted = other.exponent_ + right_digit_count - 1;\n\n    if (left_adjusted != right_adjusted) {\n      magnitude_compare = left_adjusted < right_adjusted ? -1 : 1;\n    } else {\n      BigCoefficient::align_exponents(left_big, right_big, this->exponent_,\n                                      other.exponent_);\n      magnitude_compare = left_big.compare(right_big);\n    }\n  } else {\n    if (this->exponent_ == other.exponent_) {\n      if (this->coefficient_ < other.coefficient_) {\n        magnitude_compare = -1;\n      } else if (this->coefficient_ > other.coefficient_) {\n        magnitude_compare = 1;\n      } else {\n        magnitude_compare = 0;\n      }\n    } else {\n      auto left_digits =\n          digit_count(static_cast<std::uint64_t>(this->coefficient_));\n      auto right_digits =\n          digit_count(static_cast<std::uint64_t>(other.coefficient_));\n      auto left_adjusted =\n          this->exponent_ + static_cast<std::int32_t>(left_digits) - 1;\n      auto right_adjusted =\n          other.exponent_ + static_cast<std::int32_t>(right_digits) - 1;\n\n      if (left_adjusted != right_adjusted) {\n        magnitude_compare = left_adjusted < right_adjusted ? -1 : 1;\n      } else {\n        auto exponent_difference = this->exponent_ - other.exponent_;\n        if (exponent_difference > 0) {\n          if (exponent_difference <= 18) {\n            auto multiplier =\n                POWERS_OF_10[static_cast<std::uint32_t>(exponent_difference)];\n            auto product =\n                static_cast<sourcemeta::core::uint128_t>(this->coefficient_) *\n                multiplier;\n            auto right_128 =\n                static_cast<sourcemeta::core::uint128_t>(other.coefficient_);\n            if (product < right_128) {\n              magnitude_compare = -1;\n            } else if (product > right_128) {\n              magnitude_compare = 1;\n            } else {\n              magnitude_compare = 0;\n            }\n          } else {\n            magnitude_compare = 1;\n          }\n        } else {\n          auto difference = static_cast<std::uint32_t>(-exponent_difference);\n          if (difference <= 18) {\n            auto multiplier = POWERS_OF_10[difference];\n            auto product =\n                static_cast<sourcemeta::core::uint128_t>(other.coefficient_) *\n                multiplier;\n            auto left_128 =\n                static_cast<sourcemeta::core::uint128_t>(this->coefficient_);\n            if (left_128 < product) {\n              magnitude_compare = -1;\n            } else if (left_128 > product) {\n              magnitude_compare = 1;\n            } else {\n              magnitude_compare = 0;\n            }\n          } else {\n            magnitude_compare = -1;\n          }\n        }\n      }\n    }\n  }\n\n  if (magnitude_compare != 0) {\n    if (is_negative) {\n      magnitude_compare = -magnitude_compare;\n    }\n\n    return magnitude_compare < 0 ? Decimal{-1} : Decimal{1};\n  }\n\n  if (this->exponent_ != other.exponent_) {\n    bool left_less = this->exponent_ < other.exponent_;\n    if (is_negative) {\n      left_less = !left_less;\n    }\n\n    return left_less ? Decimal{-1} : Decimal{1};\n  }\n\n  return Decimal{0};\n}\n\nauto Decimal::divide_integer(const Decimal &other) const -> Decimal {\n  if (this->is_snan() || other.is_snan()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (this->is_nan()) {\n    return Decimal::nan(this->nan_payload());\n  }\n\n  if (other.is_nan()) {\n    return Decimal::nan(other.nan_payload());\n  }\n\n  if (this->is_infinite() && other.is_infinite()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  bool result_negative = ((this->flags_ ^ other.flags_) & FLAG_SIGN) != 0;\n\n  if (this->is_infinite()) {\n    Decimal result =\n        result_negative ? Decimal::negative_infinity() : Decimal::infinity();\n    return result;\n  }\n\n  if (other.is_zero()) {\n    if (this->is_zero()) {\n      throw NumericInvalidOperationError{};\n    }\n\n    throw NumericDivisionByZeroError{};\n  }\n\n  if (other.is_infinite()) {\n    Decimal result;\n    if (result_negative) {\n      result.flags_ = FLAG_SIGN;\n    }\n\n    return result;\n  }\n\n  if (this->is_zero()) {\n    Decimal result;\n    if (result_negative) {\n      result.flags_ = FLAG_SIGN;\n    }\n\n    return result;\n  }\n\n  auto dividend_big = coefficient_as_big(this->coefficient_,\n                                         this->coefficient_high_, this->flags_);\n  auto divisor_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n\n  BigCoefficient::align_exponents(dividend_big, divisor_big, this->exponent_,\n                                  other.exponent_);\n\n  auto [quotient, remainder] = dividend_big.divide_modulo(divisor_big);\n\n  Decimal result;\n  store_big_result(result.coefficient_, result.coefficient_high_, result.flags_,\n                   std::move(quotient), result_negative);\n  if (result.is_zero()) {\n    result.flags_ = result_negative ? FLAG_SIGN : 0;\n  }\n\n  result.exponent_ = 0;\n  return result;\n}\n\nauto Decimal::operator==(const Decimal &other) const -> bool {\n  if (this->is_nan() || other.is_nan()) {\n    return false;\n  }\n\n  if (this->is_infinite() && other.is_infinite()) {\n    return (this->flags_ & FLAG_SIGN) == (other.flags_ & FLAG_SIGN);\n  }\n\n  if (this->is_infinite() || other.is_infinite()) {\n    return false;\n  }\n\n  if (this->is_zero() && other.is_zero()) {\n    return true;\n  }\n\n  if ((this->flags_ & FLAG_SIGN) != (other.flags_ & FLAG_SIGN)) {\n    return false;\n  }\n\n  auto left_coefficient = this->coefficient_;\n  auto left_exponent = this->exponent_;\n  auto right_coefficient = other.coefficient_;\n  auto right_exponent = other.exponent_;\n\n  if ((this->flags_ & FLAG_BIG) || (other.flags_ & FLAG_BIG)) {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n    BigCoefficient::align_exponents(left_big, right_big, left_exponent,\n                                    right_exponent);\n    return left_big.compare(right_big) == 0;\n  }\n\n  strip_trailing_zeros(left_coefficient, left_exponent);\n  strip_trailing_zeros(right_coefficient, right_exponent);\n  return left_coefficient == right_coefficient &&\n         left_exponent == right_exponent;\n}\n\nauto Decimal::operator!=(const Decimal &other) const -> bool {\n  return !(*this == other);\n}\n\nauto Decimal::operator<(const Decimal &other) const -> bool {\n  if (this->is_nan() || other.is_nan()) {\n    return false;\n  }\n\n  if (this->is_infinite()) {\n    if (this->flags_ & FLAG_SIGN) {\n      return !other.is_infinite() || !(other.flags_ & FLAG_SIGN);\n    }\n\n    return false;\n  }\n\n  if (other.is_infinite()) {\n    if (other.flags_ & FLAG_SIGN) {\n      return false;\n    }\n\n    return true;\n  }\n\n  bool left_negative = (this->flags_ & FLAG_SIGN) != 0;\n  bool right_negative = (other.flags_ & FLAG_SIGN) != 0;\n  bool left_zero = this->is_zero();\n  bool right_zero = other.is_zero();\n\n  if (left_zero && right_zero) {\n    return false;\n  }\n\n  if (left_zero) {\n    return !right_negative;\n  }\n\n  if (right_zero) {\n    return left_negative;\n  }\n\n  if (left_negative && !right_negative) {\n    return true;\n  }\n\n  if (!left_negative && right_negative) {\n    return false;\n  }\n\n  int magnitude_compare;\n\n  if ((this->flags_ & FLAG_BIG) || (other.flags_ & FLAG_BIG)) {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n\n    auto left_digit_count = static_cast<std::int64_t>(left_big.digit_count());\n    auto right_digit_count = static_cast<std::int64_t>(right_big.digit_count());\n    auto left_adjusted = this->exponent_ + left_digit_count - 1;\n    auto right_adjusted = other.exponent_ + right_digit_count - 1;\n\n    if (left_adjusted != right_adjusted) {\n      magnitude_compare = left_adjusted < right_adjusted ? -1 : 1;\n    } else {\n      BigCoefficient::align_exponents(left_big, right_big, this->exponent_,\n                                      other.exponent_);\n      magnitude_compare = left_big.compare(right_big);\n    }\n\n  } else {\n    if (this->exponent_ == other.exponent_) {\n      if (this->coefficient_ < other.coefficient_) {\n        magnitude_compare = -1;\n      } else if (this->coefficient_ > other.coefficient_) {\n        magnitude_compare = 1;\n      } else {\n        magnitude_compare = 0;\n      }\n\n    } else {\n      auto left_digits =\n          digit_count(static_cast<std::uint64_t>(this->coefficient_));\n      auto right_digits =\n          digit_count(static_cast<std::uint64_t>(other.coefficient_));\n      auto left_adjusted =\n          this->exponent_ + static_cast<std::int32_t>(left_digits) - 1;\n      auto right_adjusted =\n          other.exponent_ + static_cast<std::int32_t>(right_digits) - 1;\n\n      if (left_adjusted != right_adjusted) {\n        magnitude_compare = left_adjusted < right_adjusted ? -1 : 1;\n      } else {\n        auto exponent_difference = this->exponent_ - other.exponent_;\n        if (exponent_difference > 0) {\n          if (exponent_difference <= 18) {\n            auto multiplier =\n                POWERS_OF_10[static_cast<std::uint32_t>(exponent_difference)];\n            auto product =\n                static_cast<sourcemeta::core::uint128_t>(this->coefficient_) *\n                multiplier;\n            auto right_128 =\n                static_cast<sourcemeta::core::uint128_t>(other.coefficient_);\n            if (product < right_128) {\n              magnitude_compare = -1;\n            } else if (product > right_128) {\n              magnitude_compare = 1;\n            } else {\n              magnitude_compare = 0;\n            }\n\n          } else {\n            magnitude_compare = 1;\n          }\n\n        } else {\n          auto difference = static_cast<std::uint32_t>(-exponent_difference);\n          if (difference <= 18) {\n            auto multiplier = POWERS_OF_10[difference];\n            auto product =\n                static_cast<sourcemeta::core::uint128_t>(other.coefficient_) *\n                multiplier;\n            auto left_128 =\n                static_cast<sourcemeta::core::uint128_t>(this->coefficient_);\n            if (left_128 < product) {\n              magnitude_compare = -1;\n            } else if (left_128 > product) {\n              magnitude_compare = 1;\n            } else {\n              magnitude_compare = 0;\n            }\n\n          } else {\n            magnitude_compare = -1;\n          }\n        }\n      }\n    }\n  }\n\n  return left_negative ? magnitude_compare > 0 : magnitude_compare < 0;\n}\n\nauto Decimal::operator<=(const Decimal &other) const -> bool {\n  if (this->is_nan() || other.is_nan()) {\n    return false;\n  }\n\n  return !(other < *this);\n}\n\nauto Decimal::operator>(const Decimal &other) const -> bool {\n  return other < *this;\n}\n\nauto Decimal::operator>=(const Decimal &other) const -> bool {\n  if (this->is_nan() || other.is_nan()) {\n    return false;\n  }\n\n  return !(*this < other);\n}\n\nauto Decimal::operator+=(const Decimal &other) -> Decimal & {\n  if (!this->is_finite() || !other.is_finite()) {\n    if (this->is_nan() || other.is_nan()) {\n      *this = Decimal::nan();\n      return *this;\n    }\n\n    if (this->is_infinite() && other.is_infinite()) {\n      if ((this->flags_ & FLAG_SIGN) != (other.flags_ & FLAG_SIGN)) {\n        *this = Decimal::nan();\n      }\n\n      return *this;\n    }\n\n    if (other.is_infinite()) {\n      *this = other;\n    }\n\n    return *this;\n  }\n\n  check_exponent_overflow(this->exponent_, other.exponent_);\n\n  if (other.is_zero()) {\n    return *this;\n  }\n\n  if (this->is_zero()) {\n    *this = other;\n    return *this;\n  }\n\n  bool left_negative = (this->flags_ & FLAG_SIGN) != 0;\n  bool right_negative = (other.flags_ & FLAG_SIGN) != 0;\n\n  bool needs_big = (this->flags_ & FLAG_BIG) || (other.flags_ & FLAG_BIG);\n  auto left_coefficient = this->coefficient_;\n  auto right_coefficient = other.coefficient_;\n  auto result_exponent = std::min(this->exponent_, other.exponent_);\n\n  if (!needs_big) {\n    if (this->exponent_ < other.exponent_) {\n      auto difference =\n          static_cast<std::uint32_t>(other.exponent_ - this->exponent_);\n      if (difference <= 18) {\n        auto scaled =\n            static_cast<sourcemeta::core::uint128_t>(right_coefficient) *\n            POWERS_OF_10[difference];\n        if (scaled <= static_cast<sourcemeta::core::uint128_t>(COMPACT_MAX)) {\n          right_coefficient = static_cast<std::int64_t>(scaled);\n        } else {\n          needs_big = true;\n        }\n\n      } else {\n        needs_big = true;\n      }\n\n    } else if (other.exponent_ < this->exponent_) {\n      auto difference =\n          static_cast<std::uint32_t>(this->exponent_ - other.exponent_);\n      if (difference <= 18) {\n        auto scaled =\n            static_cast<sourcemeta::core::uint128_t>(left_coefficient) *\n            POWERS_OF_10[difference];\n        if (scaled <= static_cast<sourcemeta::core::uint128_t>(COMPACT_MAX)) {\n          left_coefficient = static_cast<std::int64_t>(scaled);\n        } else {\n          needs_big = true;\n        }\n\n      } else {\n        needs_big = true;\n      }\n    }\n  }\n\n  if (needs_big) {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n    BigCoefficient::align_exponents(left_big, right_big, this->exponent_,\n                                    other.exponent_);\n    auto [result_big, result_negative] = BigCoefficient::add_signed(\n        left_big, right_big, left_negative, right_negative);\n    if (result_big.is_zero()) {\n      result_negative = false;\n    }\n\n    free_big_coefficient(this->coefficient_, this->flags_);\n    store_big_result(this->coefficient_, this->coefficient_high_, this->flags_,\n                     std::move(result_big), result_negative);\n    this->exponent_ = result_exponent;\n    round_to_precision(this->coefficient_, this->coefficient_high_,\n                       this->exponent_, this->flags_);\n    return *this;\n  }\n\n  auto left_signed = left_negative ? -left_coefficient : left_coefficient;\n  auto right_signed = right_negative ? -right_coefficient : right_coefficient;\n  auto sum = left_signed + right_signed;\n\n  std::int64_t result_coefficient;\n  bool result_negative;\n  if (sum < 0) {\n    result_coefficient = -sum;\n    result_negative = true;\n  } else {\n    result_coefficient = sum;\n    result_negative = false;\n  }\n\n  if (result_coefficient == 0) {\n    result_negative = false;\n  }\n\n  this->coefficient_ = result_coefficient;\n  this->exponent_ = result_exponent;\n  this->flags_ = result_negative ? FLAG_SIGN : 0;\n\n  return *this;\n}\n\nauto Decimal::operator-=(const Decimal &other) -> Decimal & {\n  return *this += (-other);\n}\n\nauto Decimal::operator*=(const Decimal &other) -> Decimal & {\n  if (!this->is_finite() || !other.is_finite()) {\n    if (this->is_nan() || other.is_nan()) {\n      *this = Decimal::nan();\n      return *this;\n    }\n\n    if (this->is_infinite()) {\n      if (other.is_zero()) {\n        *this = Decimal::nan();\n        return *this;\n      }\n\n      if ((other.flags_ & FLAG_SIGN) != 0) {\n        this->flags_ ^= FLAG_SIGN;\n      }\n\n      return *this;\n    }\n\n    if (other.is_infinite()) {\n      if (this->is_zero()) {\n        *this = Decimal::nan();\n        return *this;\n      }\n\n      auto sign = ((this->flags_ ^ other.flags_) & FLAG_SIGN);\n      *this = other;\n      this->flags_ =\n          static_cast<std::uint8_t>((this->flags_ & ~FLAG_SIGN) | sign);\n      return *this;\n    }\n\n    return *this;\n  }\n\n  check_exponent_overflow(this->exponent_, other.exponent_);\n\n  bool result_negative = ((this->flags_ ^ other.flags_) & FLAG_SIGN) != 0;\n  auto result_exponent_64 =\n      static_cast<std::int64_t>(this->exponent_) + other.exponent_;\n  if (result_exponent_64 > std::numeric_limits<std::int32_t>::max() ||\n      result_exponent_64 < std::numeric_limits<std::int32_t>::min()) {\n    throw NumericOverflowError{};\n  }\n\n  auto result_exponent = static_cast<std::int32_t>(result_exponent_64);\n\n  if ((this->flags_ & FLAG_BIG) || (other.flags_ & FLAG_BIG)) {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n    auto product = left_big.multiply(right_big);\n    free_big_coefficient(this->coefficient_, this->flags_);\n    store_big_result(this->coefficient_, this->coefficient_high_, this->flags_,\n                     std::move(product), result_negative);\n    this->exponent_ = result_exponent;\n    round_to_precision(this->coefficient_, this->coefficient_high_,\n                       this->exponent_, this->flags_);\n    return *this;\n  }\n\n  auto product = static_cast<sourcemeta::core::uint128_t>(this->coefficient_) *\n                 static_cast<sourcemeta::core::uint128_t>(other.coefficient_);\n\n  if (product <= static_cast<sourcemeta::core::uint128_t>(COMPACT_MAX)) {\n    this->coefficient_ = static_cast<std::int64_t>(product);\n    this->exponent_ = result_exponent;\n    this->flags_ = result_negative ? FLAG_SIGN : 0;\n    if (this->coefficient_ == 0) {\n      this->flags_ = 0;\n    }\n\n  } else {\n    auto left_big = coefficient_as_big(this->coefficient_,\n                                       this->coefficient_high_, this->flags_);\n    auto right_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n    auto result = left_big.multiply(right_big);\n    store_big_result(this->coefficient_, this->coefficient_high_, this->flags_,\n                     std::move(result), result_negative);\n    this->exponent_ = result_exponent;\n  }\n\n  round_to_precision(this->coefficient_, this->coefficient_high_,\n                     this->exponent_, this->flags_);\n  return *this;\n}\n\nauto Decimal::operator/=(const Decimal &other) -> Decimal & {\n  if (this->is_nan() || other.is_nan()) {\n    *this = Decimal::nan();\n    return *this;\n  }\n\n  if (this->is_infinite() && other.is_infinite()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (this->is_infinite()) {\n    if ((other.flags_ & FLAG_SIGN) != 0) {\n      this->flags_ ^= FLAG_SIGN;\n    }\n\n    return *this;\n  }\n\n  if (other.is_zero()) {\n    if (this->is_zero()) {\n      throw NumericInvalidOperationError{};\n    }\n\n    throw NumericDivisionByZeroError{};\n  }\n\n  if (other.is_infinite()) {\n    bool result_negative = ((this->flags_ ^ other.flags_) & FLAG_SIGN) != 0;\n    free_big_coefficient(this->coefficient_, this->flags_);\n    this->coefficient_ = 0;\n    this->exponent_ = 0;\n    this->flags_ = result_negative ? FLAG_SIGN : 0;\n    return *this;\n  }\n\n  bool result_negative = ((this->flags_ ^ other.flags_) & FLAG_SIGN) != 0;\n\n  auto dividend_big = coefficient_as_big(this->coefficient_,\n                                         this->coefficient_high_, this->flags_);\n  auto divisor_big = coefficient_as_big(other.coefficient_,\n                                        other.coefficient_high_, other.flags_);\n\n  auto scaled = dividend_big.multiply_pow10(WORKING_PRECISION);\n  auto [quotient, remainder] = scaled.divide_modulo(divisor_big);\n\n  free_big_coefficient(this->coefficient_, this->flags_);\n  store_big_result(this->coefficient_, this->coefficient_high_, this->flags_,\n                   std::move(quotient), result_negative);\n  if (this->coefficient_ == 0 && !(this->flags_ & FLAG_BIG)) {\n    this->flags_ = 0;\n  }\n\n  this->exponent_ = this->exponent_ - other.exponent_ - WORKING_PRECISION;\n\n  round_to_precision(this->coefficient_, this->coefficient_high_,\n                     this->exponent_, this->flags_);\n  return *this;\n}\n\nauto Decimal::operator%=(const Decimal &other) -> Decimal & {\n  if (this->is_nan() || other.is_nan()) {\n    *this = Decimal::nan();\n    return *this;\n  }\n\n  if (other.is_zero()) {\n    throw NumericInvalidOperationError{};\n  }\n\n  if (this->is_infinite()) {\n    *this = Decimal::nan();\n    return *this;\n  }\n\n  if (other.is_infinite()) {\n    return *this;\n  }\n\n  Decimal quotient{*this};\n  quotient /= other;\n\n  if (quotient.is_finite() && !quotient.is_zero()) {\n    if (quotient.exponent_ < 0) {\n      if (quotient.flags_ & FLAG_BIG) {\n        auto digit_string = coefficient_to_digit_string(\n            quotient.coefficient_, quotient.coefficient_high_, quotient.flags_);\n        auto number_of_digits = static_cast<std::int32_t>(digit_string.size());\n        auto digits_to_remove = -quotient.exponent_;\n        if (digits_to_remove >= number_of_digits) {\n          quotient = Decimal{};\n        } else {\n          auto integer_string = digit_string.substr(\n              0, static_cast<std::size_t>(number_of_digits - digits_to_remove));\n          auto old_sign =\n              static_cast<std::uint8_t>(quotient.flags_ & FLAG_SIGN);\n          free_big_coefficient(quotient.coefficient_, quotient.flags_);\n          quotient = Decimal{integer_string};\n          quotient.flags_ =\n              static_cast<std::uint8_t>(quotient.flags_ | old_sign);\n        }\n\n      } else {\n        auto coefficient = quotient.coefficient_;\n        auto exponent = quotient.exponent_;\n        while (exponent < 0 && coefficient > 0) {\n          coefficient /= 10;\n          exponent++;\n        }\n\n        if (exponent < 0) {\n          quotient = Decimal{};\n        } else {\n          quotient.coefficient_ = coefficient;\n          quotient.exponent_ = exponent;\n        }\n      }\n    }\n  }\n\n  Decimal product{quotient};\n  product *= other;\n  *this -= product;\n\n  return *this;\n}\n\nauto Decimal::operator+(const Decimal &other) const -> Decimal {\n  Decimal result{*this};\n  result += other;\n  return result;\n}\n\nauto Decimal::operator-(const Decimal &other) const -> Decimal {\n  Decimal result{*this};\n  result -= other;\n  return result;\n}\n\nauto Decimal::operator*(const Decimal &other) const -> Decimal {\n  Decimal result{*this};\n  result *= other;\n  return result;\n}\n\nauto Decimal::operator/(const Decimal &other) const -> Decimal {\n  Decimal result{*this};\n  result /= other;\n  return result;\n}\n\nauto Decimal::operator%(const Decimal &other) const -> Decimal {\n  Decimal result{*this};\n  result %= other;\n  return result;\n}\n\nauto Decimal::operator-() const -> Decimal {\n  Decimal result{*this};\n  result.flags_ ^= FLAG_SIGN;\n  return result;\n}\n\nauto Decimal::operator+() const -> Decimal { return *this; }\n\nauto Decimal::operator++() -> Decimal & {\n  *this += Decimal{1};\n  return *this;\n}\n\nauto Decimal::operator++(int) -> Decimal {\n  Decimal result{*this};\n  ++(*this);\n  return result;\n}\n\nauto Decimal::operator--() -> Decimal & {\n  *this -= Decimal{1};\n  return *this;\n}\n\nauto Decimal::operator--(int) -> Decimal {\n  Decimal result{*this};\n  --(*this);\n  return result;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_H_\n#define SOURCEMETA_CORE_NUMERIC_H_\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/numeric_decimal.h>\n#include <sourcemeta/core/numeric_error.h>\n#include <sourcemeta/core/numeric_parse.h>\n#include <sourcemeta/core/numeric_uint128.h>\n#include <sourcemeta/core/numeric_util.h>\n#include <sourcemeta/core/numeric_zigzag.h>\n// NOLINTEND(misc-include-cleaner)\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_decimal.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_DECIMAL_H_\n#define SOURCEMETA_CORE_NUMERIC_DECIMAL_H_\n\n#ifndef SOURCEMETA_CORE_NUMERIC_EXPORT\n#include <sourcemeta/core/numeric_export.h>\n#endif\n\n#include <sourcemeta/core/preprocessor.h>\n\n#include <cassert>  // assert\n#include <concepts> // std::integral\n#include <cstdint>  // std::int32_t, std::int64_t, std::uint32_t, std::uint64_t\n#include <string>   // std::string\n#include <string_view> // std::string_view\n#include <type_traits> // std::is_signed_v\n\nnamespace sourcemeta::core {\n\n/// @ingroup numeric\n/// Represents an arbitrary-precision decimal number.\nclass SOURCEMETA_CORE_NUMERIC_EXPORT Decimal {\npublic:\n  /// Construct a decimal number initialized to zero\n  Decimal() noexcept;\n\n  /// Destructor\n  ~Decimal();\n\n  /// Copy constructor\n  Decimal(const Decimal &other);\n\n  /// Move constructor\n  Decimal(Decimal &&other) noexcept;\n\n  /// Construct a decimal number from a signed integral type\n  template <typename T>\n    requires std::integral<T> && std::is_signed_v<T> &&\n             (!std::same_as<T, std::int64_t>)\n  Decimal(const T value) : Decimal{static_cast<std::int64_t>(value)} {}\n\n  /// Construct a decimal number from a 64-bit signed integer\n  Decimal(std::int64_t value);\n\n  /// Construct a decimal number from an unsigned integral type\n  template <typename T>\n    requires std::integral<T> && std::is_unsigned_v<T> &&\n             (!std::same_as<T, std::uint64_t>)\n  Decimal(const T value) : Decimal{static_cast<std::uint64_t>(value)} {}\n\n  /// Construct a decimal number from a 64-bit unsigned integer\n  Decimal(std::uint64_t value);\n\n  /// Construct a decimal number from a 32-bit float\n  explicit Decimal(float value);\n\n  /// Construct a decimal number from a 64-bit double\n  explicit Decimal(double value);\n\n  /// Construct a decimal number from a C-string\n  explicit Decimal(const char *const value);\n\n  /// Construct a decimal number from a C++ string\n  explicit Decimal(const std::string &value);\n\n  /// Construct a decimal number from a string view\n  explicit Decimal(const std::string_view value);\n\n  /// Copy assignment operator\n  auto operator=(const Decimal &other) -> Decimal &;\n\n  /// Move assignment operator\n  auto operator=(Decimal &&other) noexcept -> Decimal &;\n\n  /// Create a quiet NaN (Not a Number) value with an optional payload\n  [[nodiscard]] static auto nan(std::uint64_t payload = 0) -> Decimal;\n\n  /// Create a signaling NaN value with an optional payload\n  [[nodiscard]] static auto snan(std::uint64_t payload = 0) -> Decimal;\n\n  /// Create a decimal from a double by converting through its shortest\n  /// round-trip string representation, avoiding IEEE 754 precision artifacts\n  [[nodiscard]] static auto strict_from(double value) -> Decimal;\n\n  /// Create a positive infinity value\n  [[nodiscard]] static auto infinity() -> Decimal;\n\n  /// Create a negative infinity value\n  [[nodiscard]] static auto negative_infinity() -> Decimal;\n\n  /// Convert the decimal number to scientific notation string\n  [[nodiscard]] auto to_scientific_string() const -> std::string;\n\n  /// Convert the decimal number to a plain string representation\n  [[nodiscard]] auto to_string() const -> std::string;\n\n  /// Convert the decimal number to a 64-bit signed integer\n  [[nodiscard]] auto to_int64() const -> std::int64_t;\n\n  /// Convert the decimal number to a 32-bit signed integer\n  [[nodiscard]] auto to_int32() const -> std::int32_t;\n\n  /// Convert the decimal number to a 64-bit unsigned integer\n  [[nodiscard]] auto to_uint64() const -> std::uint64_t;\n\n  /// Convert the decimal number to a 32-bit unsigned integer\n  [[nodiscard]] auto to_uint32() const -> std::uint32_t;\n\n  /// Convert the decimal number to a 32-bit float\n  [[nodiscard]] auto to_float() const -> float;\n\n  /// Convert the decimal number to a 64-bit double\n  [[nodiscard]] auto to_double() const -> double;\n\n  /// Check if the decimal number is zero\n  [[nodiscard]] auto is_zero() const -> bool;\n\n  /// Check if the decimal number represents an integer value, which includes a\n  /// number like `3.0`. This is a value-level check: returns `true` whenever\n  /// the number mathematically equals an integer, regardless of how it was\n  /// originally written.\n  [[nodiscard]] auto is_integral() const -> bool;\n\n  /// Check if the decimal number originated as an integer literal. Returns\n  /// `true` iff the value was constructed from an integer-typed constructor or\n  /// from a string source consisting of an optional sign followed by one or\n  /// more digits, with no fractional part and no exponent part. Returns\n  /// `false` for values constructed from floating-point primitives, from\n  /// strings with a fractional or exponent part, or as the result of\n  /// arithmetic operations.\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_integer() const -> bool {\n    return (this->flags_ & FLAG_INTEGER_LITERAL) != 0;\n  }\n\n  /// Check if the decimal number is finite\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_finite() const -> bool {\n    return !(this->flags_ & (FLAG_NAN | FLAG_SNAN | FLAG_INFINITE));\n  }\n\n  /// Check if the decimal number is a real number (finite and not NaN)\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_real() const -> bool {\n    return this->is_finite() && !this->is_integral();\n  }\n\n  /// Check if the decimal number can be represented as a 32-bit float without\n  /// precision loss\n  [[nodiscard]] auto is_float() const -> bool;\n\n  /// Check if the decimal number can be represented as a 64-bit double without\n  /// precision loss\n  [[nodiscard]] auto is_double() const -> bool;\n\n  /// Check if the decimal number fits in a 32-bit signed integer\n  [[nodiscard]] auto is_int32() const -> bool;\n\n  /// Check if the decimal number fits in a 64-bit signed integer\n  [[nodiscard]] auto is_int64() const -> bool;\n\n  /// Check if the decimal number fits in a 32-bit unsigned integer\n  [[nodiscard]] auto is_uint32() const -> bool;\n\n  /// Check if the decimal number fits in a 64-bit unsigned integer\n  [[nodiscard]] auto is_uint64() const -> bool;\n\n  /// Check if the decimal number is NaN (Not a Number), either quiet or\n  /// signaling\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_nan() const -> bool {\n    return (this->flags_ & FLAG_NAN) != 0;\n  }\n\n  /// Check if the decimal number is a signaling NaN\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_snan() const -> bool {\n    return (this->flags_ & FLAG_SNAN) != 0;\n  }\n\n  /// Check if the decimal number is a quiet NaN\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_qnan() const -> bool {\n    return (this->flags_ & FLAG_NAN) != 0 && !(this->flags_ & FLAG_SNAN);\n  }\n\n  /// Get the payload of a NaN value (0 if no payload)\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto nan_payload() const\n      -> std::uint64_t {\n    assert(this->is_nan());\n    return static_cast<std::uint64_t>(this->coefficient_);\n  }\n\n  /// Check if the decimal number is infinite\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_infinite() const -> bool {\n    return (this->flags_ & FLAG_INFINITE) != 0;\n  }\n\n  /// Check if the decimal number is signed (negative, including -0)\n  [[nodiscard]] SOURCEMETA_FORCEINLINE inline auto is_signed() const -> bool {\n    return (this->flags_ & FLAG_SIGN) != 0;\n  }\n\n  /// Round the decimal number to an integral value\n  [[nodiscard]] auto to_integral() const -> Decimal;\n\n  /// Check if this decimal number is divisible by another\n  [[nodiscard]] auto divisible_by(const Decimal &divisor) const -> bool;\n\n  /// Strip trailing zeros from the coefficient\n  [[nodiscard]] auto reduce() const -> Decimal;\n\n  /// Return the adjusted exponent (floor of base-10 logarithm)\n  [[nodiscard]] auto logb() const -> Decimal;\n\n  /// Scale the number by a power of 10\n  [[nodiscard]] auto scale_by(const Decimal &scale) const -> Decimal;\n\n  /// Check if two numbers have the same quantum (exponent)\n  [[nodiscard]] auto same_quantum(const Decimal &other) const -> bool;\n\n  /// IEEE 754 total ordering comparison returning -1, 0, or 1\n  [[nodiscard]] auto compare_total(const Decimal &other) const -> Decimal;\n\n  /// Integer division (truncate toward zero)\n  [[nodiscard]] auto divide_integer(const Decimal &other) const -> Decimal;\n\n  /// Add another decimal number to this one\n  auto operator+=(const Decimal &other) -> Decimal &;\n\n  /// Subtract another decimal number from this one\n  auto operator-=(const Decimal &other) -> Decimal &;\n\n  /// Multiply this decimal number by another\n  auto operator*=(const Decimal &other) -> Decimal &;\n\n  /// Divide this decimal number by another\n  auto operator/=(const Decimal &other) -> Decimal &;\n\n  /// Compute the modulo of this decimal number with another\n  auto operator%=(const Decimal &other) -> Decimal &;\n\n  /// Add two decimal numbers\n  [[nodiscard]] auto operator+(const Decimal &other) const -> Decimal;\n\n  /// Subtract two decimal numbers\n  [[nodiscard]] auto operator-(const Decimal &other) const -> Decimal;\n\n  /// Multiply two decimal numbers\n  [[nodiscard]] auto operator*(const Decimal &other) const -> Decimal;\n\n  /// Divide two decimal numbers\n  [[nodiscard]] auto operator/(const Decimal &other) const -> Decimal;\n\n  /// Compute the modulo of two decimal numbers\n  [[nodiscard]] auto operator%(const Decimal &other) const -> Decimal;\n\n  /// Unary negation operator\n  [[nodiscard]] auto operator-() const -> Decimal;\n\n  /// Unary plus operator\n  [[nodiscard]] auto operator+() const -> Decimal;\n\n  /// Prefix increment operator\n  auto operator++() -> Decimal &;\n\n  /// Postfix increment operator\n  auto operator++(int) -> Decimal;\n\n  /// Prefix decrement operator\n  auto operator--() -> Decimal &;\n\n  /// Postfix decrement operator\n  auto operator--(int) -> Decimal;\n\n  /// Check if two decimal numbers are equal\n  [[nodiscard]] auto operator==(const Decimal &other) const -> bool;\n\n  /// Check if two decimal numbers are not equal\n  [[nodiscard]] auto operator!=(const Decimal &other) const -> bool;\n\n  /// Check if this decimal number is less than another\n  [[nodiscard]] auto operator<(const Decimal &other) const -> bool;\n\n  /// Check if this decimal number is less than or equal to another\n  [[nodiscard]] auto operator<=(const Decimal &other) const -> bool;\n\n  /// Check if this decimal number is greater than another\n  [[nodiscard]] auto operator>(const Decimal &other) const -> bool;\n\n  /// Check if this decimal number is greater than or equal to another\n  [[nodiscard]] auto operator>=(const Decimal &other) const -> bool;\n\nprivate:\n  static constexpr std::uint8_t FLAG_SIGN = 0x01;\n  static constexpr std::uint8_t FLAG_NAN = 0x02;\n  static constexpr std::uint8_t FLAG_SNAN = 0x04;\n  static constexpr std::uint8_t FLAG_INFINITE = 0x08;\n  static constexpr std::uint8_t FLAG_INTEGER_LITERAL = 0x40;\n\n  std::int64_t coefficient_{0};\n  std::uint64_t coefficient_high_{0};\n  std::int32_t exponent_{0};\n  std::uint8_t flags_{0};\n};\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator+(const T left, const Decimal &right) -> Decimal {\n  return Decimal{left} + right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator-(const T left, const Decimal &right) -> Decimal {\n  return Decimal{left} - right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator*(const T left, const Decimal &right) -> Decimal {\n  return Decimal{left} * right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator/(const T left, const Decimal &right) -> Decimal {\n  return Decimal{left} / right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator%(const T left, const Decimal &right) -> Decimal {\n  return Decimal{left} % right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator==(const T left, const Decimal &right) -> bool {\n  return Decimal{left} == right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator!=(const T left, const Decimal &right) -> bool {\n  return Decimal{left} != right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator<(const T left, const Decimal &right) -> bool {\n  return Decimal{left} < right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator<=(const T left, const Decimal &right) -> bool {\n  return Decimal{left} <= right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator>(const T left, const Decimal &right) -> bool {\n  return Decimal{left} > right;\n}\n\ntemplate <typename T>\n  requires std::integral<T>\ninline auto operator>=(const T left, const Decimal &right) -> bool {\n  return Decimal{left} >= right;\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_error.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_ERROR_H\n#define SOURCEMETA_CORE_NUMERIC_ERROR_H\n\n#ifndef SOURCEMETA_CORE_NUMERIC_EXPORT\n#include <sourcemeta/core/numeric_export.h>\n#endif\n\n#include <exception> // std::exception\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup numeric\n/// This class represents a decimal parse error\nclass SOURCEMETA_CORE_NUMERIC_EXPORT DecimalParseError : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Invalid decimal string format\";\n  }\n};\n\n/// @ingroup numeric\n/// This class represents a numeric division by zero error\nclass SOURCEMETA_CORE_NUMERIC_EXPORT NumericDivisionByZeroError\n    : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Division by zero\";\n  }\n};\n\n/// @ingroup numeric\n/// This class represents a numeric invalid operation error\nclass SOURCEMETA_CORE_NUMERIC_EXPORT NumericInvalidOperationError\n    : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Invalid numeric operation\";\n  }\n};\n\n/// @ingroup numeric\n/// This class represents a numeric overflow error\nclass SOURCEMETA_CORE_NUMERIC_EXPORT NumericOverflowError\n    : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Numeric overflow\";\n  }\n};\n\n/// @ingroup numeric\n/// This class represents a numeric out of memory error\nclass SOURCEMETA_CORE_NUMERIC_EXPORT NumericOutOfMemoryError\n    : public std::exception {\npublic:\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Out of memory\";\n  }\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_parse.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_PARSE_H\n#define SOURCEMETA_CORE_NUMERIC_PARSE_H\n\n#ifndef SOURCEMETA_CORE_NUMERIC_EXPORT\n#include <sourcemeta/core/numeric_export.h>\n#endif\n\n#include <cstdint>  // std::int64_t\n#include <optional> // std::optional\n#include <string>   // std::string\n\nnamespace sourcemeta::core {\n\n/// @ingroup numeric\n/// Attempt to parse a string as a double\nSOURCEMETA_CORE_NUMERIC_EXPORT\nauto to_double(const std::string &input) noexcept -> std::optional<double>;\n\n/// @ingroup numeric\n/// Attempt to parse a string as a signed 64-bit integer\nSOURCEMETA_CORE_NUMERIC_EXPORT\nauto to_int64_t(const std::string &input) noexcept\n    -> std::optional<std::int64_t>;\n\n/// @ingroup numeric\n/// Attempt to parse a string as a signed 64-bit integer in a given base\nSOURCEMETA_CORE_NUMERIC_EXPORT\nauto to_int64_t(const std::string &input, const int base) noexcept\n    -> std::optional<std::int64_t>;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_uint128.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_UINT128_H_\n#define SOURCEMETA_CORE_NUMERIC_UINT128_H_\n\n#ifndef SOURCEMETA_CORE_NUMERIC_EXPORT\n#include <sourcemeta/core/numeric_export.h>\n#endif\n\n#include <cassert> // assert\n#include <climits> // UINT64_MAX\n#include <cstdint> // std::uint64_t, std::int64_t\n\n#if defined(_MSC_VER)\n#include <intrin.h> // _umul128, _udiv128\n#endif\n\nnamespace sourcemeta::core {\n\n/// @ingroup numeric\n/// Cross-platform 128-bit unsigned integer type.\n#if defined(__SIZEOF_INT128__) || defined(__clang__)\nusing uint128_t = __uint128_t;\n#else\n// We keep the full implementation header-only to allow the compiler to better\n// inline\nstruct uint128_t {\n  std::uint64_t low;\n  std::uint64_t high;\n\n  uint128_t() noexcept : low{0}, high{0} {}\n  uint128_t(int value) noexcept\n      : low{static_cast<std::uint64_t>(value)},\n        high{value < 0 ? UINT64_MAX : 0} {}\n  uint128_t(unsigned int value) noexcept\n      : low{static_cast<std::uint64_t>(value)}, high{0} {}\n  uint128_t(std::uint64_t value) noexcept : low{value}, high{0} {}\n  uint128_t(std::int64_t value) noexcept\n      : low{static_cast<std::uint64_t>(value)},\n        high{value < 0 ? UINT64_MAX : 0} {}\n  uint128_t(std::uint64_t high_part, std::uint64_t low_part) noexcept\n      : low{low_part}, high{high_part} {}\n\n  explicit operator std::uint64_t() const noexcept { return this->low; }\n  explicit operator std::int64_t() const noexcept {\n    return static_cast<std::int64_t>(this->low);\n  }\n\n  explicit operator bool() const noexcept {\n    return this->low != 0 || this->high != 0;\n  }\n\n  auto operator+=(const uint128_t &other) noexcept -> uint128_t & {\n    auto old_low = this->low;\n    this->low += other.low;\n    this->high += other.high + (this->low < old_low ? 1 : 0);\n    return *this;\n  }\n\n  auto operator*=(const uint128_t &other) noexcept -> uint128_t & {\n    *this = *this * other;\n    return *this;\n  }\n\n  friend auto operator+(uint128_t left, const uint128_t &right) noexcept\n      -> uint128_t {\n    left += right;\n    return left;\n  }\n\n  friend auto operator*(const uint128_t &left, const uint128_t &right) noexcept\n      -> uint128_t {\n    std::uint64_t result_high;\n#if defined(_MSC_VER)\n    auto result_low = _umul128(left.low, right.low, &result_high);\n#else\n    const std::uint64_t left_low{left.low & 0xFFFFFFFF};\n    const std::uint64_t left_high{left.low >> 32};\n    const std::uint64_t right_low{right.low & 0xFFFFFFFF};\n    const std::uint64_t right_high{right.low >> 32};\n    const std::uint64_t cross_1{left_high * right_low};\n    const std::uint64_t cross_2{left_low * right_high};\n    const std::uint64_t mid{cross_1 + (left_low * right_low >> 32)};\n    const std::uint64_t mid_2{(mid & 0xFFFFFFFF) + cross_2};\n    result_high = left_high * right_high + (mid >> 32) + (mid_2 >> 32);\n    auto result_low = (mid_2 << 32) | ((left_low * right_low) & 0xFFFFFFFF);\n#endif\n    result_high += left.low * right.high + left.high * right.low;\n    return {result_high, result_low};\n  }\n\n  friend auto operator/(const uint128_t &dividend,\n                        std::uint64_t divisor) noexcept -> uint128_t {\n    if (dividend.high == 0) {\n      return {0, dividend.low / divisor};\n    }\n\n    auto quotient_high = dividend.high / divisor;\n    auto remainder_high = dividend.high % divisor;\n    std::uint64_t quotient_low;\n    std::uint64_t remainder;\n#if defined(_MSC_VER)\n    quotient_low = _udiv128(remainder_high, dividend.low, divisor, &remainder);\n#else\n    quotient_low = 0;\n    auto current_remainder = remainder_high;\n    for (int bit = 63; bit >= 0; --bit) {\n      const auto carry = current_remainder >> 63;\n      current_remainder =\n          (current_remainder << 1) | ((dividend.low >> bit) & 1);\n      if (carry || current_remainder >= divisor) {\n        current_remainder -= divisor;\n        quotient_low |= static_cast<std::uint64_t>(1) << bit;\n      }\n    }\n#endif\n    return {quotient_high, quotient_low};\n  }\n\n  friend auto operator/(const uint128_t &dividend,\n                        const uint128_t &divisor) noexcept -> uint128_t {\n    assert(divisor.high == 0);\n    return dividend / divisor.low;\n  }\n\n  friend auto operator%(const uint128_t &dividend,\n                        std::uint64_t divisor) noexcept -> uint128_t {\n    if (dividend.high == 0) {\n      return {0, dividend.low % divisor};\n    }\n\n    auto remainder_high = dividend.high % divisor;\n    std::uint64_t remainder;\n#if defined(_MSC_VER)\n    _udiv128(remainder_high, dividend.low, divisor, &remainder);\n#else\n    remainder = remainder_high;\n    for (int bit = 63; bit >= 0; --bit) {\n      const auto carry = remainder >> 63;\n      remainder = (remainder << 1) | ((dividend.low >> bit) & 1);\n      if (carry || remainder >= divisor) {\n        remainder -= divisor;\n      }\n    }\n#endif\n    return {0, remainder};\n  }\n\n  friend auto operator%(const uint128_t &dividend,\n                        const uint128_t &divisor) noexcept -> uint128_t {\n    assert(divisor.high == 0);\n    return dividend % divisor.low;\n  }\n\n  friend auto operator<(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return left.high < right.high ||\n           (left.high == right.high && left.low < right.low);\n  }\n\n  friend auto operator>(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return right < left;\n  }\n\n  friend auto operator<=(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return !(right < left);\n  }\n\n  friend auto operator>=(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return !(left < right);\n  }\n\n  friend auto operator==(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return left.high == right.high && left.low == right.low;\n  }\n\n  friend auto operator!=(const uint128_t &left, const uint128_t &right) noexcept\n      -> bool {\n    return !(left == right);\n  }\n\n  friend auto operator<<(const uint128_t &value, int shift) noexcept\n      -> uint128_t {\n    if (shift == 0) {\n      return value;\n    } else if (shift >= 128) {\n      return {0, 0};\n    } else if (shift >= 64) {\n      return {value.low << (shift - 64), 0};\n    } else {\n      return {(value.high << shift) | (value.low >> (64 - shift)),\n              value.low << shift};\n    }\n  }\n\n  friend auto operator>>(const uint128_t &value, int shift) noexcept\n      -> uint128_t {\n    if (shift == 0) {\n      return value;\n    } else if (shift >= 128) {\n      return {0, 0};\n    } else if (shift >= 64) {\n      return {0, value.high >> (shift - 64)};\n    } else {\n      return {value.high >> shift,\n              (value.low >> shift) | (value.high << (64 - shift))};\n    }\n  }\n\n  friend auto operator|(const uint128_t &left, const uint128_t &right) noexcept\n      -> uint128_t {\n    return {left.high | right.high, left.low | right.low};\n  }\n\n  auto operator|=(const uint128_t &other) noexcept -> uint128_t & {\n    this->high |= other.high;\n    this->low |= other.low;\n    return *this;\n  }\n\n  friend auto operator&(const uint128_t &left, const uint128_t &right) noexcept\n      -> uint128_t {\n    return {left.high & right.high, left.low & right.low};\n  }\n};\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_util.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_UTIL_H_\n#define SOURCEMETA_CORE_NUMERIC_UTIL_H_\n\n#include <sourcemeta/core/numeric_decimal.h>\n\n#include <cassert>  // assert\n#include <cmath>    // std::modf, std::floor, std::isfinite\n#include <concepts> // std::floating_point, std::integral, std::same_as\n#include <cstdint>  // std::uint8_t, std::int64_t, std::uint64_t\n#include <limits>   // std::numeric_limits\n\nnamespace sourcemeta::core {\n\n/// @ingroup numeric\n/// Convert a value to a Decimal, returning a copy if it is already one\ntemplate <typename T> auto to_decimal(const T &value) -> Decimal {\n  if constexpr (std::same_as<T, Decimal>) {\n    return value;\n  } else {\n    return Decimal{value};\n  }\n}\n\n/// @ingroup numeric\n/// A type that is either a Decimal or a built-in integral type\ntemplate <typename T>\nconcept decimal_or_integral = std::same_as<T, Decimal> || std::integral<T>;\n\n/// @ingroup numeric\n/// True when at least one of the given types is a Decimal\ntemplate <typename... Ts>\nconcept any_decimal = (std::same_as<Ts, Decimal> || ...);\n\n/// @ingroup numeric\n/// Check whether a value fits in an unsigned 8-bit byte\ntemplate <typename T> constexpr auto is_byte(const T &value) -> bool {\n  if constexpr (std::same_as<T, Decimal>) {\n    return value.is_finite() && value.is_integral() && value >= Decimal{0} &&\n           value <= Decimal{255};\n  } else {\n    return value >= 0 && value <= std::numeric_limits<std::uint8_t>::max();\n  }\n}\n\n/// @ingroup numeric\n/// Compute the floor of the division of two integral values. Supports\n/// primitive integers, Decimal operands, and mixed combinations.\ntemplate <typename Dividend, typename Divisor>\n  requires decimal_or_integral<Dividend> && decimal_or_integral<Divisor>\nauto divide_floor(const Dividend &dividend, const Divisor &divisor) {\n  if constexpr (any_decimal<Dividend, Divisor>) {\n    Decimal decimal_dividend{to_decimal(dividend)};\n    const Decimal decimal_divisor{to_decimal(divisor)};\n    assert(decimal_dividend.is_integral());\n    assert(decimal_divisor.is_integral());\n    assert(decimal_divisor > Decimal{0});\n    if (decimal_divisor == Decimal{1}) {\n      return decimal_dividend;\n    } else if (decimal_dividend >= Decimal{0}) {\n      return decimal_dividend.divide_integer(decimal_divisor);\n    } else {\n      const Decimal absolute_dividend{\n          decimal_dividend.is_signed() ? -decimal_dividend : decimal_dividend};\n      const Decimal quotient{absolute_dividend.divide_integer(decimal_divisor)};\n      if (absolute_dividend % decimal_divisor == Decimal{0}) {\n        return -quotient;\n      } else {\n        return -(quotient + Decimal{1});\n      }\n    }\n  } else {\n    const auto signed_dividend{static_cast<std::int64_t>(dividend)};\n    const auto unsigned_divisor{static_cast<std::uint64_t>(divisor)};\n    assert(unsigned_divisor > 0);\n    if (unsigned_divisor == 1) {\n      return signed_dividend;\n    } else if (signed_dividend >= 0) {\n      return static_cast<std::int64_t>(\n          static_cast<std::uint64_t>(signed_dividend) / unsigned_divisor);\n    } else {\n      // Negate in unsigned to avoid UB for INT64_MIN\n      const std::uint64_t absolute_dividend{\n          static_cast<std::uint64_t>(0) -\n          static_cast<std::uint64_t>(signed_dividend)};\n      return -(static_cast<std::int64_t>(\n          1 + ((absolute_dividend - 1) / unsigned_divisor)));\n    }\n  }\n}\n\n/// @ingroup numeric\n/// Compute the ceiling of the division of two integral values. Supports\n/// primitive integers, Decimal operands, and mixed combinations.\ntemplate <typename Dividend, typename Divisor>\n  requires decimal_or_integral<Dividend> && decimal_or_integral<Divisor>\nauto divide_ceil(const Dividend &dividend, const Divisor &divisor) {\n  if constexpr (any_decimal<Dividend, Divisor>) {\n    Decimal decimal_dividend{to_decimal(dividend)};\n    const Decimal decimal_divisor{to_decimal(divisor)};\n    assert(decimal_dividend.is_integral());\n    assert(decimal_divisor.is_integral());\n    assert(decimal_divisor > Decimal{0});\n    if (decimal_divisor == Decimal{1}) {\n      return decimal_dividend;\n    } else if (decimal_dividend >= Decimal{0}) {\n      const Decimal quotient{decimal_dividend.divide_integer(decimal_divisor)};\n      if (decimal_dividend % decimal_divisor == Decimal{0}) {\n        return quotient;\n      } else {\n        return quotient + Decimal{1};\n      }\n    } else {\n      const Decimal absolute_dividend{\n          decimal_dividend.is_signed() ? -decimal_dividend : decimal_dividend};\n      return -(absolute_dividend.divide_integer(decimal_divisor));\n    }\n  } else {\n    const auto signed_dividend{static_cast<std::int64_t>(dividend)};\n    const auto unsigned_divisor{static_cast<std::uint64_t>(divisor)};\n    assert(unsigned_divisor > 0);\n    if (unsigned_divisor == 1) {\n      return signed_dividend;\n    } else if (signed_dividend >= 0) {\n      if (static_cast<std::uint64_t>(signed_dividend) + unsigned_divisor <\n          unsigned_divisor) {\n        return static_cast<std::int64_t>(\n            (static_cast<std::uint64_t>(signed_dividend) / unsigned_divisor) +\n            1 - (1 / unsigned_divisor));\n      } else {\n        return static_cast<std::int64_t>(\n            (static_cast<std::uint64_t>(signed_dividend) + unsigned_divisor -\n             1) /\n            unsigned_divisor);\n      }\n    } else {\n      // Negate in unsigned to avoid UB for INT64_MIN\n      return -(static_cast<std::int64_t>(\n          (static_cast<std::uint64_t>(0) -\n           static_cast<std::uint64_t>(signed_dividend)) /\n          unsigned_divisor));\n    }\n  }\n}\n\n/// @ingroup numeric\n/// Count the number of multiples of a given multiplier that fall within\n/// the closed range [minimum, maximum]. Supports primitive integers,\n/// Decimal operands, and mixed combinations.\ntemplate <typename Minimum, typename Maximum, typename Multiplier>\n  requires decimal_or_integral<Minimum> && decimal_or_integral<Maximum> &&\n           decimal_or_integral<Multiplier>\nauto count_multiples(const Minimum &minimum, const Maximum &maximum,\n                     const Multiplier &multiplier) {\n  if constexpr (any_decimal<Minimum, Maximum, Multiplier>) {\n    const Decimal decimal_minimum{to_decimal(minimum)};\n    const Decimal decimal_maximum{to_decimal(maximum)};\n    const Decimal decimal_multiplier{to_decimal(multiplier)};\n    assert(decimal_minimum.is_integral());\n    assert(decimal_maximum.is_integral());\n    assert(decimal_multiplier.is_integral());\n    assert(decimal_minimum <= decimal_maximum);\n    assert(decimal_multiplier > Decimal{0});\n    return divide_floor(decimal_maximum, decimal_multiplier) -\n           divide_floor(decimal_minimum - Decimal{1}, decimal_multiplier);\n  } else {\n    const auto signed_minimum{static_cast<std::int64_t>(minimum)};\n    const auto signed_maximum{static_cast<std::int64_t>(maximum)};\n    const auto signed_multiplier{static_cast<std::int64_t>(multiplier)};\n    assert(signed_minimum <= signed_maximum);\n    assert(signed_multiplier > 0);\n    return static_cast<std::uint64_t>(\n        divide_floor(signed_maximum,\n                     static_cast<std::uint64_t>(signed_multiplier)) -\n        divide_floor(signed_minimum - 1,\n                     static_cast<std::uint64_t>(signed_multiplier)));\n  }\n}\n\n/// @ingroup numeric\n/// The maximum value representable by an unsigned integer of T bits\ntemplate <unsigned int T>\nconstexpr auto uint_max = [] {\n  static_assert(T > 0 && T < 64, \"uint_max<T> requires 0 < T < 64\");\n  return (std::uint64_t{1} << T) - 1;\n}();\n\n/// @ingroup numeric\n/// Check whether a value falls within the closed range [lower, higher]\n/// using signed 64-bit bounds\ntemplate <typename T>\nconstexpr auto is_within(const T &value, const std::int64_t lower,\n                         const std::int64_t higher) noexcept -> bool {\n  return value >= lower && value <= higher;\n}\n\n/// @ingroup numeric\n/// Check whether a value falls within the closed range [lower, higher]\n/// using unsigned 64-bit bounds\ntemplate <typename T>\nconstexpr auto is_within(const T &value, const std::uint64_t lower,\n                         const std::uint64_t higher) noexcept -> bool {\n  if (value >= 0) {\n    return static_cast<std::uint64_t>(value) >= lower &&\n           static_cast<std::uint64_t>(value) <= higher;\n  } else {\n    return false;\n  }\n}\n\n/// @ingroup numeric\n/// Check whether a Decimal value falls within the closed range\n/// [lower, higher]\ninline auto is_within(const Decimal &value, const Decimal &lower,\n                      const Decimal &higher) -> bool {\n  return value >= lower && value <= higher;\n}\n\n/// @ingroup numeric\n/// Compute the absolute value of an integer or Decimal\ntemplate <typename T> auto abs(const T &value) {\n  if constexpr (std::same_as<T, Decimal>) {\n    return value.is_signed() ? -value : value;\n  } else {\n    if (value < 0) {\n      // Negate in unsigned to avoid UB for INT64_MIN\n      return static_cast<std::uint64_t>(0) - static_cast<std::uint64_t>(value);\n    } else {\n      return static_cast<std::uint64_t>(value);\n    }\n  }\n}\n\n/// @ingroup numeric\n/// Find the smallest exponent in [exponent_start, exponent_end] such that\n/// base raised to the next power exceeds the given value, i.e.\n/// `(base ^ exponent) <= value < (base ^ (exponent + 1))`\nconstexpr auto closest_smallest_exponent(const std::uint64_t value,\n                                         const std::uint8_t base,\n                                         const std::uint8_t exponent_start,\n                                         const std::uint8_t exponent_end)\n    -> std::uint8_t {\n  assert(exponent_start <= exponent_end);\n  std::uint64_t result{base};\n  for (std::uint8_t exponent{1}; exponent < exponent_end; exponent++) {\n    const std::uint64_t next{result * base};\n    if (next > value && exponent >= exponent_start) {\n      return exponent;\n    } else {\n      result = next;\n    }\n  }\n\n  assert(result <= value);\n  return exponent_end;\n}\n\n/// @ingroup numeric\n/// Correct IEEE 754 floating-point imprecision by rounding values that\n/// are extremely close to the nearest integer\ntemplate <std::floating_point Real>\nconstexpr auto correct_ieee754(const Real value) -> Real {\n  assert(std::isfinite(value));\n  const Real threshold{static_cast<Real>(0.000000001)};\n  const Real base{std::floor(value)};\n  const Real next{base + 1};\n  if (next - value <= threshold) {\n    return next;\n  } else if (value - base <= threshold) {\n    return base;\n  } else {\n    return value;\n  }\n}\n\n/// @ingroup numeric\n/// Extract the integer digits and decimal point position from a\n/// floating-point value. The point_position output indicates how many\n/// digits from the right the decimal point sits.\ntemplate <std::integral Integer, std::floating_point Real>\nconstexpr auto real_digits(Real value, std::uint64_t &point_position)\n    -> Integer {\n  assert(std::isfinite(value));\n  Real integral_part;\n  std::uint64_t shifts{0};\n\n  Real fractional_part{std::modf(value, &integral_part)};\n  while (fractional_part != 0.0) {\n    value *= 10;\n    shifts += 1;\n    fractional_part = std::modf(correct_ieee754(value), &integral_part);\n  }\n\n  point_position = shifts;\n  return static_cast<Integer>(std::floor(integral_part));\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/include/sourcemeta/core/numeric_zigzag.h",
    "content": "#ifndef SOURCEMETA_CORE_NUMERIC_ZIGZAG_H_\n#define SOURCEMETA_CORE_NUMERIC_ZIGZAG_H_\n\n#include <sourcemeta/core/numeric_decimal.h>\n\n#include <cassert>  // assert\n#include <concepts> // std::same_as\n#include <cstdint>  // std::uint64_t, std::int64_t\n\nnamespace sourcemeta::core {\n\n/// @ingroup numeric\n/// Encode a signed integer into an unsigned integer using zigzag encoding,\n/// where the sign information is stored in the least significant bit\ntemplate <typename T> auto zigzag_encode(const T &value) {\n  if constexpr (std::same_as<T, Decimal>) {\n    assert(value.is_integral());\n    if (value >= Decimal{0}) {\n      return value * Decimal{2};\n    }\n    const Decimal absolute{value.is_signed() ? -value : value};\n    return (absolute * Decimal{2}) - Decimal{1};\n  } else {\n    const auto signed_value{static_cast<std::int64_t>(value)};\n    if (signed_value >= 0) {\n      return static_cast<std::uint64_t>(signed_value) * 2;\n    }\n    // Negate in unsigned to avoid UB for INT64_MIN\n    return (static_cast<std::uint64_t>(0) -\n            static_cast<std::uint64_t>(signed_value)) *\n               2 -\n           1;\n  }\n}\n\n/// @ingroup numeric\n/// Decode a zigzag-encoded unsigned integer back into a signed integer\ntemplate <typename T> auto zigzag_decode(const T &value) {\n  if constexpr (std::same_as<T, Decimal>) {\n    assert(value.is_integral());\n    assert(value >= Decimal{0});\n    if (value % Decimal{2} == Decimal{0}) {\n      return value.divide_integer(Decimal{2});\n    }\n    return -((value + Decimal{1}).divide_integer(Decimal{2}));\n  } else {\n    const auto unsigned_value{static_cast<std::uint64_t>(value)};\n    if (unsigned_value % 2 == 0) {\n      return static_cast<std::int64_t>(unsigned_value / 2);\n    }\n    // Use bitwise complement to avoid overflow for UINT64_MAX\n    // `~(x / 2)` == `-(x / 2 + 1)` in two's complement\n    return static_cast<std::int64_t>(~(unsigned_value / 2));\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/numeric/parse.cc",
    "content": "#include <sourcemeta/core/numeric_parse.h>\n\n#include <charconv>     // std::from_chars\n#include <stdexcept>    // std::invalid_argument, std::out_of_range\n#include <system_error> // std::errc\n\nnamespace sourcemeta::core {\n\nauto to_double(const std::string &input) noexcept -> std::optional<double> {\n  try {\n    return std::stod(input);\n  } catch (const std::invalid_argument &) {\n    return std::nullopt;\n  } catch (const std::out_of_range &) {\n    return std::nullopt;\n  }\n}\n\nauto to_int64_t(const std::string &input) noexcept\n    -> std::optional<std::int64_t> {\n  return to_int64_t(input, 10);\n}\n\nauto to_int64_t(const std::string &input, const int base) noexcept\n    -> std::optional<std::int64_t> {\n  std::int64_t value{};\n  const auto result =\n      std::from_chars(input.data(), input.data() + input.size(), value, base);\n  if (result.ec != std::errc{}) {\n    return std::nullopt;\n  }\n\n  return value;\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/options/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME options\n  PRIVATE_HEADERS error.h SOURCES options.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME options)\nendif()\n"
  },
  {
    "path": "vendor/core/src/lang/options/include/sourcemeta/core/options.h",
    "content": "#ifndef SOURCEMETA_CORE_OPTIONS_H_\n#define SOURCEMETA_CORE_OPTIONS_H_\n\n#ifndef SOURCEMETA_CORE_OPTIONS_EXPORT\n#include <sourcemeta/core/options_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/options_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <cstddef>          // std::size_t\n#include <initializer_list> // std::initializer_list\n#include <memory>           // std::unique_ptr\n#include <string>           // std::string\n#include <string_view>      // std::string_view\n#include <unordered_map>    // std::unordered_map\n#include <unordered_set>    // std::unordered_set\n#include <vector>           // std::vector\n\n/// @defgroup options Options\n/// @brief A simple and minimalistic UNIX-style command-line parsing library\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/options.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup options\n/// Command-line option parsing modifiers\nstruct OptionsModifiers {\n  /// Ignore the first N command-line arguments\n  std::size_t skip{0};\n};\n\n/// @ingroup options\n///\n/// This class performs basic command-line argument parsing based on options,\n/// flags, and aliases. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/core/options.h>\n/// #include <cstdlib>\n/// #include <iostream>\n///\n/// auto main(int argc, char *argv[]) -> int {\n///   sourcemeta::core::Options app;\n///   app.option(\"name\", {\"n\"});\n///   app.flag(\"shout\", {\"s\"});\n///   app.parse(argc, argv);\n///\n///   if (!app.contains(\"name\")) {\n///     std::cerr << \"Missing name\\n\";\n///     return EXIT_FAILURE;\n///   }\n///\n///   std::cerr << \"Hello, \" << app.at(\"name\").front();\n///   if (app.contains(\"shout\")) {\n///     std::cerr << \"!\\n\";\n///   } else {\n///     std::cerr << \"\\n\";\n///   }\n///\n///   return EXIT_SUCCESS;\n/// }\n/// ```\nclass SOURCEMETA_CORE_OPTIONS_EXPORT Options {\npublic:\n  Options() = default;\n  // Disallow copies given the unique pointers\n  Options(const Options &) = delete;\n  auto operator=(const Options &) -> Options & = delete;\n  Options(Options &&) noexcept = default;\n  auto operator=(Options &&) noexcept -> Options & = default;\n\n  /// Declare a new option, which must take a value\n  auto option(std::string &&name, std::initializer_list<std::string> aliases)\n      -> void;\n\n  /// Declare a new flag, which must not take a value\n  auto flag(std::string &&name, std::initializer_list<std::string> aliases)\n      -> void;\n\n  /// Access the values (if any) set for an option or flag, by its main name\n  [[nodiscard]] auto at(const std::string_view name) const\n      -> const std::vector<std::string_view> &;\n\n  /// Check if an option or flag was set, by its main name\n  [[nodiscard]] auto contains(const std::string_view name) const -> bool;\n\n  /// Access the positional arguments, if any\n  [[nodiscard]] auto positional() const\n      -> const std::vector<std::string_view> &;\n\n  /// Parse program arguments given the declared options and flags\n  auto parse(const int argc,\n             // We want to be compatible with `main`s `argv`\n             // NOLINTNEXTLINE(modernize-avoid-c-arrays)\n             const char *const argv[], const OptionsModifiers options = {})\n      -> void;\n\nprivate:\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n  static constexpr std::string_view POSITIONAL_ARGUMENT_NAME{\"\"};\n  static const std::vector<std::string_view> EMPTY;\n\n  std::vector<std::unique_ptr<std::string>> storage;\n  std::unordered_map<std::string_view, std::string_view> aliases_;\n  std::unordered_map<std::string_view, std::vector<std::string_view>> options_;\n  std::unordered_set<std::string_view> flags;\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n};\n\n} // namespace sourcemeta::core\n\n#endif // SOURCEMETA_CORE_OPTIONS_H_\n"
  },
  {
    "path": "vendor/core/src/lang/options/include/sourcemeta/core/options_error.h",
    "content": "#ifndef SOURCEMETA_CORE_OPTIONS_ERROR_H_\n#define SOURCEMETA_CORE_OPTIONS_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_OPTIONS_EXPORT\n#include <sourcemeta/core/options_export.h>\n#endif\n\n#include <exception>   // std::exception\n#include <string>      // std::string\n#include <string_view> // std::string_view\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup options\n/// This class represents a general options error\nclass SOURCEMETA_CORE_OPTIONS_EXPORT OptionsError : public std::exception {\npublic:\n  explicit OptionsError(const char *message) : message_{message} {}\n  explicit OptionsError(std::string message) = delete;\n  explicit OptionsError(std::string &&message) = delete;\n  explicit OptionsError(std::string_view message) = delete;\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return this->message_;\n  }\n\nprivate:\n  const char *message_;\n};\n\n/// @ingroup options\n/// This class represents a unknown option error\nstruct SOURCEMETA_CORE_OPTIONS_EXPORT OptionsUnknownOptionError\n    : public OptionsError {\n  explicit OptionsUnknownOptionError(const std::string_view option)\n      : OptionsError{\"Unknown option\"}, option_{option} {}\n  [[nodiscard]] auto option() const noexcept -> std::string_view {\n    return this->option_;\n  }\n\nprivate:\n  std::string option_;\n};\n\n/// @ingroup options\n/// This class represents a value being passed to a flag\nstruct SOURCEMETA_CORE_OPTIONS_EXPORT OptionsUnexpectedValueFlagError\n    : public OptionsError {\n  explicit OptionsUnexpectedValueFlagError(const std::string_view option)\n      : OptionsError{\"This flag cannot take a value\"}, option_{option} {}\n  [[nodiscard]] auto option() const noexcept -> std::string_view {\n    return this->option_;\n  }\n\nprivate:\n  std::string option_;\n};\n\n/// @ingroup options\n/// This class represents a missing value from an option\nstruct SOURCEMETA_CORE_OPTIONS_EXPORT OptionsMissingOptionValueError\n    : public OptionsError {\n  explicit OptionsMissingOptionValueError(const std::string_view option)\n      : OptionsError{\"This option must take a value\"}, option_{option} {}\n  [[nodiscard]] auto option() const noexcept -> std::string_view {\n    return this->option_;\n  }\n\nprivate:\n  std::string option_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/options/options.cc",
    "content": "#include <sourcemeta/core/options.h>\n\n#include <cassert> // assert\n#include <utility> // std::forward\n\nnamespace {\n\ntemplate <typename T, typename V>\nauto emplace_back_unique(T &container, V &&element) -> const auto & {\n  return *(container.emplace_back(\n      std::make_unique<typename T::value_type::element_type>(\n          std::forward<V>(element))));\n}\n\ntemplate <typename T>\nauto find_canonical_name(const T &aliases, const typename T::key_type &alias)\n    -> const typename T::mapped_type & {\n  const auto iterator{aliases.find(alias)};\n  if (iterator == aliases.cend()) {\n    throw sourcemeta::core::OptionsUnknownOptionError(alias);\n  } else {\n    return iterator->second;\n  }\n}\n\n} // namespace\n\nnamespace sourcemeta::core {\n\nconst std::vector<std::string_view> Options::EMPTY = {};\n\nauto Options::option(std::string &&name,\n                     std::initializer_list<std::string> aliases) -> void {\n  assert(!name.empty());\n  const std::string_view view{emplace_back_unique(this->storage, name)};\n  this->aliases_.try_emplace(view, view);\n  for (const auto &alias : aliases) {\n    assert(!alias.empty());\n    const std::string_view alias_view{\n        emplace_back_unique(this->storage, alias)};\n    this->aliases_.try_emplace(alias_view, view);\n  }\n}\n\nauto Options::flag(std::string &&name,\n                   std::initializer_list<std::string> aliases) -> void {\n  assert(!name.empty());\n  const std::string_view view{emplace_back_unique(this->storage, name)};\n  this->aliases_.try_emplace(view, view);\n  for (const auto &alias : aliases) {\n    assert(!alias.empty());\n    const std::string_view alias_view{\n        emplace_back_unique(this->storage, alias)};\n    this->aliases_.try_emplace(alias_view, view);\n  }\n\n  this->flags.emplace(view);\n}\n\nauto Options::at(const std::string_view name) const\n    -> const std::vector<std::string_view> & {\n  assert(!name.empty());\n  const auto iterator{this->options_.find(name)};\n  return iterator == this->options_.cend() ? Options::EMPTY : iterator->second;\n}\n\nauto Options::contains(const std::string_view name) const -> bool {\n  return this->options_.contains(name);\n}\n\nauto Options::positional() const -> const std::vector<std::string_view> & {\n  const auto iterator{this->options_.find(POSITIONAL_ARGUMENT_NAME)};\n  return iterator == this->options_.cend() ? Options::EMPTY : iterator->second;\n}\n\nauto Options::parse(const int argc,\n                    // NOLINTNEXTLINE(modernize-avoid-c-arrays)\n                    const char *const argv[], const OptionsModifiers options)\n    -> void {\n  bool end_of_options{false};\n  // We assume that the first argument is the program name\n  for (auto index = static_cast<int>(options.skip + 1); index < argc; index++) {\n    const std::string_view token{argv[index]};\n\n    if (end_of_options) {\n      this->options_[POSITIONAL_ARGUMENT_NAME].emplace_back(token);\n      continue;\n    } else if (token == \"--\") {\n      end_of_options = true;\n      continue;\n    }\n\n    const auto *const next{(index + 1) < argc ? argv[index + 1] : nullptr};\n\n    // Parse long options\n    if (token.size() >= 3 && token[0] == '-' && token[1] == '-') {\n      const auto eq{token.find('=')};\n      const auto name{(eq == std::string_view::npos) ? token.substr(2)\n                                                     : token.substr(2, eq - 2)};\n      const auto &canonical{find_canonical_name(this->aliases_, name)};\n      const auto is_flag{this->flags.contains(canonical)};\n\n      if (is_flag) {\n        if (eq == std::string_view::npos) {\n          this->options_[canonical].push_back(token.substr(2));\n        } else {\n          throw OptionsUnexpectedValueFlagError(name);\n        }\n      } else if (eq != std::string_view::npos) {\n        this->options_[canonical].push_back(token.substr(eq + 1));\n      } else if (next) {\n        this->options_[canonical].emplace_back(next);\n        index += 1;\n      } else {\n        throw OptionsMissingOptionValueError(name);\n      }\n\n      // Parse short options\n    } else if (token.size() >= 2 && token[0] == '-' && token[1] != '-') {\n      for (std::size_t flag = 1; flag < token.size(); flag++) {\n        const auto name{token.substr(flag, 1)};\n        const auto &canonical{find_canonical_name(this->aliases_, name)};\n        const auto is_flag{this->flags.contains(canonical)};\n\n        if (is_flag) {\n          this->options_[canonical].emplace_back();\n        } else if (flag + 1 < token.size()) {\n          this->options_[canonical].push_back(token.substr(flag + 1));\n          break;\n        } else if (next) {\n          this->options_[canonical].emplace_back(next);\n          index += 1;\n          break;\n        } else {\n          throw OptionsMissingOptionValueError(name);\n        }\n      }\n\n      // Otherwise parse as positional\n    } else {\n      this->options_[POSITIONAL_ARGUMENT_NAME].emplace_back(token);\n    }\n  }\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/src/lang/parallel/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME parallel\n  PRIVATE_HEADERS for_each.h)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME parallel)\nendif()\n\ntarget_link_libraries(sourcemeta_core_parallel INTERFACE Threads::Threads)\n"
  },
  {
    "path": "vendor/core/src/lang/parallel/include/sourcemeta/core/parallel.h",
    "content": "#ifndef SOURCEMETA_CORE_PARALLEL_H_\n#define SOURCEMETA_CORE_PARALLEL_H_\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/parallel_for_each.h>\n// NOLINTEND(misc-include-cleaner)\n\n/// @defgroup parallel Parallel\n/// @brief Growing collection of utilities for parallel computing\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/parallel.h>\n/// ```\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/parallel/include/sourcemeta/core/parallel_for_each.h",
    "content": "#ifndef SOURCEMETA_CORE_PARALLEL_FOR_EACH_H_\n#define SOURCEMETA_CORE_PARALLEL_FOR_EACH_H_\n\n#include <algorithm> // std::max\n#include <concepts>  // std::copyable, std::invocable\n#include <exception> // std::exception_ptr, std::current_exception, std::rethrow_exception\n#include <functional> // std::function\n#include <iterator>   // std::input_iterator, std::iter_reference_t\n#include <mutex>      // std::mutex, std::lock_guard\n#include <queue>      // std::queue\n#include <stdexcept>  // std::runtime_error\n#include <thread>     // std::thread\n#include <utility>    // std::forward\n#include <vector>     // std::vector\n\n#if defined(_WIN32)\n#include <process.h> // _beginthreadex\n#define NOMINMAX\n#include <windows.h>\n#else\n#include <pthread.h>\n#endif\n\nnamespace sourcemeta::core {\n\n#ifndef DOXYGEN\n#if defined(_WIN32)\n// See\n// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170\ninline unsigned __stdcall parallel_for_each_windows_thread_start(\n    void *argument) {\n  auto *function_ptr = static_cast<std::function<void()> *>(argument);\n  (*function_ptr)();\n  delete function_ptr;\n  return 0;\n}\n#endif\n#endif\n\n/// @ingroup parallel\n///\n/// Process a collection in parallel. If the parallelism is set to zero, the\n/// function will run using the available number of cores. If the stack size is\n/// set to zero, the platform default applies. For example:\n///\n/// ```c++\n/// #include <sourcemeta/core/parallel.h>\n/// #include <vector>\n/// #include <mutex>\n/// #include <iostream>\n///\n/// std::vector<std::size_t> input;\n/// for (std::size_t index = 0; index < 20; index++) {\n///   input.push_back(index);\n/// }\n///\n/// std::mutex mutex;\n/// std::vector<std::size_t> result;\n///\n/// sourcemeta::core::parallel_for_each(\n///     input.cbegin(), input.cend(),\n///     [&mutex, &result](const auto value,\n///                       const auto parallelism,\n///                       const auto cursor) {\n///       std::lock_guard<std::mutex> lock{mutex};\n///       result.push_back(value);\n///       std::cerr << \"Processing \" << cursor\n///                 << \" with parallelism \" << parallelism << \"\\n\";\n///     });\n/// ```\ntemplate <typename Iterator, typename Callback>\n  requires std::input_iterator<Iterator> && std::copyable<Iterator> &&\n           std::invocable<Callback, std::iter_reference_t<Iterator>,\n                          std::size_t, std::size_t>\nauto parallel_for_each(\n    Iterator first, Iterator last, Callback &&callback,\n    const std::size_t parallelism = std::thread::hardware_concurrency(),\n    const std::size_t stack_size_bytes = 0) -> void {\n  const auto effective_parallelism{std::max(parallelism, 1uz)};\n\n  // Empty list\n  if (first == last) {\n    return;\n  }\n\n  // If it is a single element or there is no parallelism,\n  // just do a normal loop without dealing with threads\n  if (effective_parallelism == 1 || std::next(first) == last) {\n    std::size_t cursor{1};\n    for (auto iterator = first; iterator != last; ++iterator, ++cursor) {\n      callback(*iterator, effective_parallelism, cursor);\n    }\n\n    return;\n  }\n\n  std::queue<Iterator> tasks;\n  for (auto iterator = first; iterator != last; ++iterator) {\n    tasks.push(iterator);\n  }\n\n  std::mutex queue_mutex;\n  std::mutex exception_mutex;\n\n  auto effective_callback = std::forward<Callback>(callback);\n\n  std::exception_ptr exception = nullptr;\n  auto handle_exception = [&exception_mutex,\n                           &exception](std::exception_ptr pointer) {\n    std::lock_guard<std::mutex> lock{exception_mutex};\n    if (!exception) {\n      exception = pointer;\n    }\n  };\n\n  std::vector<std::thread> workers;\n  workers.reserve(effective_parallelism);\n\n  const auto total{tasks.size()};\n\n  // Worker function that runs the actual per-item work and captures the\n  // environment by reference. It will be heap-copied into the native thread\n  // API.\n  auto worker_callable = [&tasks, &queue_mutex, &effective_callback,\n                          &handle_exception, effective_parallelism, total] {\n    try {\n      while (true) {\n        Iterator iterator;\n        std::size_t cursor{0};\n        {\n          std::lock_guard<std::mutex> lock{queue_mutex};\n          if (tasks.empty()) {\n            return;\n          }\n          iterator = tasks.front();\n          cursor = total - tasks.size() + 1;\n          tasks.pop();\n        }\n        effective_callback(*iterator, effective_parallelism, cursor);\n      }\n    } catch (...) {\n      handle_exception(std::current_exception());\n    }\n  };\n\n  // TODO: Replace std::function with std::move_only_function once\n  // Apple Clang ships libc++ 19+ (__cpp_lib_move_only_function)\n#if defined(_WIN32)\n  for (std::size_t index = 0; index < effective_parallelism; ++index) {\n    auto *heap_function = new std::function<void()>(worker_callable);\n    if (stack_size_bytes > static_cast<std::size_t>(UINT_MAX)) {\n      delete heap_function;\n      throw std::runtime_error(\n          \"The requested stack size is too large for this platform\");\n    }\n\n    auto raw_handle = _beginthreadex(\n        nullptr, static_cast<unsigned>(stack_size_bytes),\n        &parallel_for_each_windows_thread_start, heap_function, 0, nullptr);\n    if (raw_handle == 0) {\n      delete heap_function;\n      throw std::runtime_error(\"Could not create thread\");\n    }\n\n    HANDLE thread_handle = reinterpret_cast<HANDLE>(raw_handle);\n    workers.emplace_back([thread_handle] {\n      WaitForSingleObject(thread_handle, INFINITE);\n      CloseHandle(thread_handle);\n    });\n  }\n#else\n  for (std::size_t index = 0; index < effective_parallelism; ++index) {\n    // We can't use std::thread, as it doesn't let us tweak the thread stack\n    // size\n    pthread_attr_t attr;\n    pthread_attr_init(&attr);\n    if (stack_size_bytes > 0) {\n      pthread_attr_setstacksize(&attr, stack_size_bytes);\n    }\n\n    auto *heap_function = new std::function<void()>(worker_callable);\n    pthread_t pthread_handle;\n    auto raw_handle = pthread_create(\n        &pthread_handle, &attr,\n        [](void *arg) -> void * {\n          auto *function_ptr = static_cast<std::function<void()> *>(arg);\n          (*function_ptr)();\n          delete function_ptr;\n          return nullptr;\n        },\n        heap_function);\n    if (raw_handle != 0) {\n      pthread_attr_destroy(&attr);\n      delete heap_function;\n      throw std::runtime_error(\"Could not create thread\");\n    }\n    workers.emplace_back(\n        [pthread_handle] { pthread_join(pthread_handle, nullptr); });\n    pthread_attr_destroy(&attr);\n  }\n#endif\n\n  for (auto &worker_thread : workers) {\n    worker_thread.join();\n  }\n\n  if (exception) {\n    std::rethrow_exception(exception);\n  }\n}\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/preprocessor/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME preprocessor)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME preprocessor)\nendif()\n"
  },
  {
    "path": "vendor/core/src/lang/preprocessor/include/sourcemeta/core/preprocessor.h",
    "content": "#ifndef SOURCEMETA_CORE_PREPROCESSOR_H_\n#define SOURCEMETA_CORE_PREPROCESSOR_H_\n\n#if defined(__GNUC__) || defined(__clang__)\n#define SOURCEMETA_FORCEINLINE [[gnu::always_inline]]\n#elif defined(_MSC_VER)\n#define SOURCEMETA_FORCEINLINE [[msvc::forceinline]]\n#else\n#define SOURCEMETA_FORCEINLINE\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/process/CMakeLists.txt",
    "content": "sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME process\n  PRIVATE_HEADERS error.h\n  SOURCES spawn.cc)\n\nif(SOURCEMETA_CORE_INSTALL)\n  sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME process)\nendif()\n"
  },
  {
    "path": "vendor/core/src/lang/process/include/sourcemeta/core/process.h",
    "content": "#ifndef SOURCEMETA_CORE_PROCESS_H_\n#define SOURCEMETA_CORE_PROCESS_H_\n\n#ifndef SOURCEMETA_CORE_PROCESS_EXPORT\n#include <sourcemeta/core/process_export.h>\n#endif\n\n// NOLINTBEGIN(misc-include-cleaner)\n#include <sourcemeta/core/process_error.h>\n// NOLINTEND(misc-include-cleaner)\n\n#include <filesystem>       // std::filesystem\n#include <initializer_list> // std::initializer_list\n#include <span>             // std::span\n#include <string_view>      // std::string_view\n\n/// @defgroup process Process\n/// @brief Process related utilities\n///\n/// This functionality is included as follows:\n///\n/// ```cpp\n/// #include <sourcemeta/core/process.h>\n/// ```\n\nnamespace sourcemeta::core {\n\n/// @ingroup process\n///\n/// Spawn a program piping its output to the current stdio configuration.\n/// The directory parameter specifies the working directory for the spawned\n/// process. It must be an absolute path to an existing directory.\n///\n/// ```cpp\n/// #include <sourcemeta/core/process.h>\n/// #include <cassert>\n///\n/// const auto exit_code{sourcemeta::core::spawn(\"echo\", {\"foo\"})};\n/// assert(exit_code == 0);\n/// ```\nSOURCEMETA_CORE_PROCESS_EXPORT\nauto spawn(const std::string &program,\n           std::initializer_list<std::string_view> arguments,\n           const std::filesystem::path &directory =\n               std::filesystem::current_path()) -> int;\n\n/// @ingroup process\n///\n/// Spawn a program piping its output to the current stdio configuration.\n/// This overload accepts a span for dynamic argument lists.\n/// The directory parameter specifies the working directory for the spawned\n/// process. It must be an absolute path to an existing directory.\n///\n/// ```cpp\n/// #include <sourcemeta/core/process.h>\n/// #include <vector>\n/// #include <string_view>\n/// #include <cassert>\n///\n/// std::vector<std::string_view> arguments{\"foo\", \"bar\"};\n/// const auto exit_code{sourcemeta::core::spawn(\"echo\", arguments)};\n/// assert(exit_code == 0);\n/// ```\nSOURCEMETA_CORE_PROCESS_EXPORT\nauto spawn(\n    const std::string &program, std::span<const std::string_view> arguments,\n    const std::filesystem::path &directory = std::filesystem::current_path())\n    -> int;\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/process/include/sourcemeta/core/process_error.h",
    "content": "#ifndef SOURCEMETA_CORE_PROCESS_ERROR_H_\n#define SOURCEMETA_CORE_PROCESS_ERROR_H_\n\n#ifndef SOURCEMETA_CORE_PROCESS_EXPORT\n#include <sourcemeta/core/process_export.h>\n#endif\n\n#include <exception>        // std::exception\n#include <initializer_list> // std::initializer_list\n#include <span>             // std::span\n#include <string>           // std::string\n#include <string_view>      // std::string_view\n#include <utility>          // std::move\n#include <vector>           // std::vector\n\nnamespace sourcemeta::core {\n\n// Exporting symbols that depends on the standard C++ library is considered\n// safe.\n// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN\n#if defined(_MSC_VER)\n#pragma warning(disable : 4251 4275)\n#endif\n\n/// @ingroup process\n/// An executable program could not be found\nclass SOURCEMETA_CORE_PROCESS_EXPORT ProcessProgramNotFoundError\n    : public std::exception {\npublic:\n  ProcessProgramNotFoundError(const std::string_view program)\n      : program_{program} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Could not locate the requested program\";\n  }\n\n  [[nodiscard]] auto program() const noexcept -> std::string_view {\n    return this->program_;\n  }\n\nprivate:\n  std::string program_;\n};\n\n/// @ingroup process\n/// A spawned process terminated abnormally\nclass SOURCEMETA_CORE_PROCESS_EXPORT ProcessSpawnError : public std::exception {\npublic:\n  ProcessSpawnError(const std::string_view program,\n                    std::initializer_list<std::string_view> arguments)\n      : program_{program}, arguments_{arguments.begin(), arguments.end()} {}\n\n  ProcessSpawnError(const std::string_view program,\n                    std::span<const std::string_view> arguments)\n      : program_{program}, arguments_{arguments.begin(), arguments.end()} {}\n\n  [[nodiscard]] auto what() const noexcept -> const char * override {\n    return \"Process terminated abnormally\";\n  }\n\n  [[nodiscard]] auto program() const noexcept -> std::string_view {\n    return this->program_;\n  }\n\n  [[nodiscard]] auto arguments() const noexcept\n      -> const std::vector<std::string> & {\n    return this->arguments_;\n  }\n\nprivate:\n  std::string program_;\n  std::vector<std::string> arguments_;\n};\n\n#if defined(_MSC_VER)\n#pragma warning(default : 4251 4275)\n#endif\n\n} // namespace sourcemeta::core\n\n#endif\n"
  },
  {
    "path": "vendor/core/src/lang/process/spawn.cc",
    "content": "#include <sourcemeta/core/process.h>\n\n#include <cassert>          // assert\n#include <cerrno>           // ENOENT\n#include <filesystem>       // std::filesystem\n#include <initializer_list> // std::initializer_list\n#include <span>             // std::span\n#include <vector>           // std::vector\n\n#if defined(_WIN32) && !defined(__MSYS__) && !defined(__CYGWIN__) &&           \\\n    !defined(__MINGW32__) && !defined(__MINGW64__)\n#define WIN32_LEAN_AND_MEAN\n#include <sstream>   // std::ostringstream\n#include <windows.h> // CreateProcess, PROCESS_INFORMATION, STARTUPINFO, WaitForSingleObject, GetExitCodeProcess\n#else\n#include <spawn.h> // posix_spawnp, posix_spawnattr_t, posix_spawnattr_init, posix_spawnattr_destroy, posix_spawn_file_actions_t, posix_spawn_file_actions_init, posix_spawn_file_actions_destroy, pid_t\n#include <sys/wait.h> // waitpid, WIFEXITED, WEXITSTATUS\n\n#if defined(__MSYS__) || defined(__CYGWIN__) || defined(__MINGW32__) ||        \\\n    defined(__MINGW64__)\n#include <unistd.h> // chdir\n#endif\n\nextern char **environ;\n#endif\n\nnamespace sourcemeta::core {\n\nauto spawn(const std::string &program,\n           std::span<const std::string_view> arguments,\n           const std::filesystem::path &directory) -> int {\n  assert(directory.is_absolute());\n  assert(std::filesystem::exists(directory));\n  assert(std::filesystem::is_directory(directory));\n\n#if defined(_WIN32) && !defined(__MSYS__) && !defined(__CYGWIN__) &&           \\\n    !defined(__MINGW32__) && !defined(__MINGW64__)\n  std::ostringstream command_line;\n  command_line << program;\n\n  for (const auto &argument : arguments) {\n    command_line << \" \";\n    // Quote arguments that contain spaces\n    const std::string arg_str{argument};\n    if (arg_str.contains(' ')) {\n      command_line << \"\\\"\" << arg_str << \"\\\"\";\n    } else {\n      command_line << arg_str;\n    }\n  }\n\n  std::string cmd_line_str = command_line.str();\n  std::vector<char> cmd_line(cmd_line_str.begin(), cmd_line_str.end());\n  cmd_line.push_back('\\0');\n\n  STARTUPINFOA startup_info{};\n  startup_info.cb = sizeof(startup_info);\n  PROCESS_INFORMATION process_info{};\n  const std::string working_dir = directory.string();\n  const BOOL success =\n      CreateProcessA(nullptr,             // lpApplicationName\n                     cmd_line.data(),     // lpCommandLine (modifiable)\n                     nullptr,             // lpProcessAttributes\n                     nullptr,             // lpThreadAttributes\n                     TRUE,                // bInheritHandles\n                     0,                   // dwCreationFlags\n                     nullptr,             // lpEnvironment\n                     working_dir.c_str(), // lpCurrentDirectory\n                     &startup_info,       // lpStartupInfo\n                     &process_info        // lpProcessInformation\n      );\n\n  if (!success) {\n    const DWORD error_code{GetLastError()};\n    if (error_code == ERROR_FILE_NOT_FOUND ||\n        error_code == ERROR_PATH_NOT_FOUND) {\n      throw ProcessProgramNotFoundError{program};\n    }\n\n    throw ProcessSpawnError{program, arguments};\n  }\n\n  WaitForSingleObject(process_info.hProcess, INFINITE);\n\n  DWORD exit_code;\n  if (!GetExitCodeProcess(process_info.hProcess, &exit_code)) {\n    CloseHandle(process_info.hProcess);\n    CloseHandle(process_info.hThread);\n    throw ProcessSpawnError{program, arguments};\n  }\n\n  CloseHandle(process_info.hProcess);\n  CloseHandle(process_info.hThread);\n\n  return static_cast<int>(exit_code);\n#else\n  std::vector<const char *> argv;\n  argv.reserve(arguments.size() + 2);\n  argv.push_back(program.c_str());\n\n  for (const auto &argument : arguments) {\n    argv.push_back(argument.data());\n  }\n\n  argv.push_back(nullptr);\n\n  posix_spawnattr_t attributes;\n  posix_spawnattr_init(&attributes);\n\n  posix_spawn_file_actions_t file_actions;\n  posix_spawn_file_actions_init(&file_actions);\n\n#if defined(__MSYS__) || defined(__CYGWIN__) || defined(__MINGW32__) ||        \\\n    defined(__MINGW64__)\n  const std::filesystem::path original_directory{\n      std::filesystem::current_path()};\n  std::filesystem::current_path(directory);\n#else\n  posix_spawn_file_actions_addchdir_np(&file_actions, directory.c_str());\n#endif\n\n  pid_t process_id;\n  const int spawn_result{\n      posix_spawnp(&process_id, program.c_str(), &file_actions, &attributes,\n                   const_cast<char *const *>(argv.data()), environ)};\n\n  posix_spawn_file_actions_destroy(&file_actions);\n  posix_spawnattr_destroy(&attributes);\n\n#if defined(__MSYS__) || defined(__CYGWIN__) || defined(__MINGW32__) ||        \\\n    defined(__MINGW64__)\n  std::filesystem::current_path(original_directory);\n#endif\n\n  if (spawn_result != 0) {\n    if (spawn_result == ENOENT) {\n      throw ProcessProgramNotFoundError{program};\n    }\n\n    throw ProcessSpawnError{program, arguments};\n  }\n\n  int status;\n  waitpid(process_id, &status, 0);\n\n  if (WIFEXITED(status)) {\n    return WEXITSTATUS(status);\n  }\n\n  throw ProcessSpawnError{program, arguments};\n#endif\n}\n\nauto spawn(const std::string &program,\n           std::initializer_list<std::string_view> arguments,\n           const std::filesystem::path &directory) -> int {\n  return spawn(\n      program,\n      std::span<const std::string_view>{arguments.begin(), arguments.size()},\n      directory);\n}\n\n} // namespace sourcemeta::core\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/COPYING",
    "content": "Copyright (c) 2014, John MacFarlane\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above\n      copyright notice, this list of conditions and the following\n      disclaimer in the documentation and/or other materials provided\n      with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-----\n\nhoudini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c\n\nderive from https://github.com/vmg/houdini (with some modifications)\n\nCopyright (C) 2012 Vicent Martí\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n-----\n\nbuffer.h, buffer.c, chunk.h\n\nare derived from code (C) 2012 Github, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n-----\n\nutf8.c and utf8.c\n\nare derived from utf8proc\n(<http://www.public-software-group.org/utf8proc>),\n(C) 2009 Public Software Group e. V., Berlin, Germany.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n\n-----\n\nThe normalization code in normalize.py was derived from the\nmarkdowntest project, Copyright 2013 Karl Dubost:\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Karl Dubost\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n-----\n\nThe CommonMark spec (test/spec.txt) is\n\nCopyright (C) 2014-15 John MacFarlane\n\nReleased under the Creative Commons CC-BY-SA 4.0 license:\n<http://creativecommons.org/licenses/by-sa/4.0/>.\n\n-----\n\nThe test software in test/ is\n\nCopyright (c) 2014, John MacFarlane\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above\n      copyright notice, this list of conditions and the following\n      disclaimer in the documentation and/or other materials provided\n      with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/autolink.c",
    "content": "#include \"autolink.h\"\n#include <parser.h>\n#include <string.h>\n#include <utf8.h>\n#include <stddef.h>\n\n#if defined(_WIN32)\n#define strncasecmp _strnicmp\n#else\n#include <strings.h>\n#endif\n\nstatic int is_valid_hostchar(const uint8_t *link, size_t link_len) {\n  int32_t ch;\n  int r = cmark_utf8proc_iterate(link, (bufsize_t)link_len, &ch);\n  if (r < 0)\n    return 0;\n  return !cmark_utf8proc_is_space(ch) && !cmark_utf8proc_is_punctuation(ch);\n}\n\nstatic int sd_autolink_issafe(const uint8_t *link, size_t link_len) {\n  static const size_t valid_uris_count = 3;\n  static const char *valid_uris[] = {\"http://\", \"https://\", \"ftp://\"};\n\n  size_t i;\n\n  for (i = 0; i < valid_uris_count; ++i) {\n    size_t len = strlen(valid_uris[i]);\n\n    if (link_len > len && strncasecmp((char *)link, valid_uris[i], len) == 0 &&\n        is_valid_hostchar(link + len, link_len - len))\n      return 1;\n  }\n\n  return 0;\n}\n\nstatic size_t autolink_delim(uint8_t *data, size_t link_end) {\n  size_t i;\n  size_t closing = 0;\n  size_t opening = 0;\n\n  for (i = 0; i < link_end; ++i) {\n    const uint8_t c = data[i];\n    if (c == '<') {\n      link_end = i;\n      break;\n    } else if (c == '(') {\n      opening++;\n    } else if (c == ')') {\n      closing++;\n    }\n  }\n\n  while (link_end > 0) {\n    switch (data[link_end - 1]) {\n    case ')':\n      /* Allow any number of matching brackets (as recognised in copen/cclose)\n       * at the end of the URL.  If there is a greater number of closing\n       * brackets than opening ones, we remove one character from the end of\n       * the link.\n       *\n       * Examples (input text => output linked portion):\n       *\n       *        http://www.pokemon.com/Pikachu_(Electric)\n       *                => http://www.pokemon.com/Pikachu_(Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_((Electric)\n       *                => http://www.pokemon.com/Pikachu_((Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_(Electric))\n       *                => http://www.pokemon.com/Pikachu_(Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_((Electric))\n       *                => http://www.pokemon.com/Pikachu_((Electric))\n       */\n      if (closing <= opening) {\n        return link_end;\n      }\n      closing--;\n      link_end--;\n      break;\n    case '?':\n    case '!':\n    case '.':\n    case ',':\n    case ':':\n    case '*':\n    case '_':\n    case '~':\n    case '\\'':\n    case '\"':\n      link_end--;\n      break;\n    case ';': {\n      size_t new_end = link_end - 2;\n\n      while (new_end > 0 && cmark_isalpha(data[new_end]))\n        new_end--;\n\n      if (new_end < link_end - 2 && data[new_end] == '&')\n        link_end = new_end;\n      else\n        link_end--;\n      break;\n    }\n\n    default:\n      return link_end;\n    }\n  }\n\n  return link_end;\n}\n\nstatic size_t check_domain(uint8_t *data, size_t size, int allow_short) {\n  size_t i, np = 0, uscore1 = 0, uscore2 = 0;\n\n  /* The purpose of this code is to reject urls that contain an underscore\n   * in one of the last two segments. Examples:\n   *\n   *   www.xxx.yyy.zzz     autolinked\n   *   www.xxx.yyy._zzz    not autolinked\n   *   www.xxx._yyy.zzz    not autolinked\n   *   www._xxx.yyy.zzz    autolinked\n   *\n   * The reason is that domain names are allowed to include underscores,\n   * but host names are not. See: https://stackoverflow.com/a/2183140\n   */\n  for (i = 1; i < size - 1; i++) {\n    if (data[i] == '\\\\' && i < size - 2)\n      i++;\n    if (data[i] == '_')\n      uscore2++;\n    else if (data[i] == '.') {\n      uscore1 = uscore2;\n      uscore2 = 0;\n      np++;\n    } else if (!is_valid_hostchar(data + i, size - i) && data[i] != '-')\n      break;\n  }\n\n  if (uscore1 > 0 || uscore2 > 0) {\n    /* If the url is very long then accept it despite the underscores,\n     * to avoid quadratic behavior causing a denial of service. See:\n     * https://github.com/github/cmark-gfm/security/advisories/GHSA-29g3-96g3-jg6c\n     * Reasonable urls are unlikely to have more than 10 segments, so\n     * this extra condition shouldn't have any impact on normal usage.\n     */\n    if (np <= 10) {\n      return 0;\n    }\n  }\n\n  if (allow_short) {\n    /* We don't need a valid domain in the strict sense (with\n     * least one dot; so just make sure it's composed of valid\n     * domain characters and return the length of the the valid\n     * sequence. */\n    return i;\n  } else {\n    /* a valid domain needs to have at least a dot.\n     * that's as far as we get */\n    return np ? i : 0;\n  }\n}\n\nstatic cmark_node *www_match(cmark_parser *parser, cmark_node *parent,\n                             cmark_inline_parser *inline_parser) {\n  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n  size_t max_rewind = cmark_inline_parser_get_offset(inline_parser);\n  uint8_t *data = chunk->data + max_rewind;\n  size_t size = chunk->len - max_rewind;\n  int start = cmark_inline_parser_get_column(inline_parser);\n\n  size_t link_end;\n\n  if (max_rewind > 0 && strchr(\"*_~(\", data[-1]) == NULL &&\n      !cmark_isspace(data[-1]))\n    return 0;\n\n  if (size < 4 || memcmp(data, \"www.\", strlen(\"www.\")) != 0)\n    return 0;\n\n  link_end = check_domain(data, size, 0);\n\n  if (link_end == 0)\n    return NULL;\n\n  while (link_end < size && !cmark_isspace(data[link_end]) && data[link_end] != '<')\n    link_end++;\n\n  link_end = autolink_delim(data, link_end);\n\n  if (link_end == 0)\n    return NULL;\n\n  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));\n\n  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n\n  cmark_strbuf buf;\n  cmark_strbuf_init(parser->mem, &buf, 10);\n  cmark_strbuf_puts(&buf, \"http://\");\n  cmark_strbuf_put(&buf, data, (bufsize_t)link_end);\n  node->as.link.url = cmark_chunk_buf_detach(&buf);\n\n  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  text->as.literal =\n      cmark_chunk_dup(chunk, (bufsize_t)max_rewind, (bufsize_t)link_end);\n  cmark_node_append_child(node, text);\n\n  node->start_line = text->start_line =\n    node->end_line = text->end_line =\n    cmark_inline_parser_get_line(inline_parser);\n\n  node->start_column = text->start_column = start - 1;\n  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;\n\n  return node;\n}\n\nstatic cmark_node *url_match(cmark_parser *parser, cmark_node *parent,\n                             cmark_inline_parser *inline_parser) {\n  size_t link_end, domain_len;\n  int rewind = 0;\n\n  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n  int max_rewind = cmark_inline_parser_get_offset(inline_parser);\n  uint8_t *data = chunk->data + max_rewind;\n  size_t size = chunk->len - max_rewind;\n\n  if (size < 4 || data[1] != '/' || data[2] != '/')\n    return 0;\n\n  while (rewind < max_rewind && cmark_isalpha(data[-rewind - 1]))\n    rewind++;\n\n  if (!sd_autolink_issafe(data - rewind, size + rewind))\n    return 0;\n\n  link_end = strlen(\"://\");\n\n  domain_len = check_domain(data + link_end, size - link_end, 1);\n\n  if (domain_len == 0)\n    return 0;\n\n  link_end += domain_len;\n  while (link_end < size && !cmark_isspace(data[link_end]) && data[link_end] != '<')\n    link_end++;\n\n  link_end = autolink_delim(data, link_end);\n\n  if (link_end == 0)\n    return NULL;\n\n  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));\n  cmark_node_unput(parent, rewind);\n\n  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n\n  cmark_chunk url = cmark_chunk_dup(chunk, max_rewind - rewind,\n                                    (bufsize_t)(link_end + rewind));\n  node->as.link.url = url;\n\n  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  text->as.literal = url;\n  cmark_node_append_child(node, text);\n  \n  node->start_line = text->start_line = node->end_line = text->end_line = cmark_inline_parser_get_line(inline_parser);\n\n  node->start_column = text->start_column = max_rewind - rewind;\n  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;\n\n  return node;\n}\n\nstatic cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,\n                         cmark_node *parent, unsigned char c,\n                         cmark_inline_parser *inline_parser) {\n  if (cmark_inline_parser_in_bracket(inline_parser, false) ||\n      cmark_inline_parser_in_bracket(inline_parser, true))\n    return NULL;\n\n  if (c == ':')\n    return url_match(parser, parent, inline_parser);\n\n  if (c == 'w')\n    return www_match(parser, parent, inline_parser);\n\n  return NULL;\n\n  // note that we could end up re-consuming something already a\n  // part of an inline, because we don't track when the last\n  // inline was finished in inlines.c.\n}\n\nstatic bool validate_protocol(const char protocol[], uint8_t *data, size_t rewind, size_t max_rewind) {\n  size_t len = strlen(protocol);\n\n  if (len > (max_rewind - rewind)) {\n    return false;\n  }\n\n  // Check that the protocol matches\n  if (memcmp(data - rewind - len, protocol, len) != 0) {\n    return false;\n  }\n\n  if (len == (max_rewind - rewind)) {\n    return true;\n  }\n\n  char prev_char = data[-((ptrdiff_t)rewind) - len - 1];\n\n  // Make sure the character before the protocol is non-alphanumeric\n  return !cmark_isalnum(prev_char);\n}\n\nstatic void postprocess_text(cmark_parser *parser, cmark_node *text) {\n  size_t start = 0;\n  size_t offset = 0;\n  // `text` is going to be split into a list of nodes containing shorter segments\n  // of text, so we detach the memory buffer from text and use `cmark_chunk_dup` to\n  // create references to it. Later, `cmark_chunk_to_cstr` is used to convert\n  // the references into allocated buffers. The detached buffer is freed before we\n  // return.\n  cmark_chunk detached_chunk = text->as.literal;\n  text->as.literal = cmark_chunk_dup(&detached_chunk, 0, detached_chunk.len);\n\n  uint8_t *data = text->as.literal.data;\n  size_t remaining = text->as.literal.len;\n\n  while (true) {\n    size_t link_end;\n    uint8_t *at;\n    bool auto_mailto = true;\n    bool is_xmpp = false;\n    size_t rewind;\n    size_t max_rewind;\n    size_t np = 0;\n\n    if (offset >= remaining)\n      break;\n\n    at = (uint8_t *)memchr(data + start + offset, '@', remaining - offset);\n    if (!at)\n      break;\n\n    max_rewind = at - (data + start + offset);\n\nfound_at:\n    for (rewind = 0; rewind < max_rewind; ++rewind) {\n      uint8_t c = data[start + offset + max_rewind - rewind - 1];\n\n      if (cmark_isalnum(c))\n        continue;\n\n      if (strchr(\".+-_\", c) != NULL)\n        continue;\n\n      if (strchr(\":\", c) != NULL) {\n        if (validate_protocol(\"mailto:\", data + start + offset + max_rewind, rewind, max_rewind)) {\n          auto_mailto = false;\n          continue;\n        }\n\n        if (validate_protocol(\"xmpp:\", data + start + offset + max_rewind, rewind, max_rewind)) {\n          auto_mailto = false;\n          is_xmpp = true;\n          continue;\n        }\n      }\n\n      break;\n    }\n\n    if (rewind == 0) {\n      offset += max_rewind + 1;\n      continue;\n    }\n\n    assert(data[start + offset + max_rewind] == '@');\n    for (link_end = 1; link_end < remaining - offset - max_rewind; ++link_end) {\n      uint8_t c = data[start + offset + max_rewind + link_end];\n\n      if (cmark_isalnum(c))\n        continue;\n\n      if (c == '@') {\n        // Found another '@', so go back and try again with an updated offset and max_rewind.\n        offset += max_rewind + 1;\n        max_rewind = link_end - 1;\n        goto found_at;\n      } else if (c == '.' && link_end < remaining - offset - max_rewind - 1 &&\n               cmark_isalnum(data[start + offset + max_rewind + link_end + 1]))\n        np++;\n      else if (c == '/' && is_xmpp)\n        continue;\n      else if (c != '-' && c != '_')\n        break;\n    }\n\n    if (link_end < 2 || np == 0 ||\n        (!cmark_isalpha(data[start + offset + max_rewind + link_end - 1]) &&\n         data[start + offset + max_rewind + link_end - 1] != '.')) {\n      offset += max_rewind + link_end;\n      continue;\n    }\n\n    link_end = autolink_delim(data + start + offset + max_rewind, link_end);\n\n    if (link_end == 0) {\n      offset += max_rewind + 1;\n      continue;\n    }\n\n    cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n    cmark_strbuf buf;\n    cmark_strbuf_init(parser->mem, &buf, 10);\n    if (auto_mailto)\n      cmark_strbuf_puts(&buf, \"mailto:\");\n    cmark_strbuf_put(&buf, data + start + offset + max_rewind - rewind, (bufsize_t)(link_end + rewind));\n    link_node->as.link.url = cmark_chunk_buf_detach(&buf);\n\n    cmark_node *link_text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n    cmark_chunk email = cmark_chunk_dup(\n      &detached_chunk,\n      (bufsize_t)(start + offset + max_rewind - rewind),\n      (bufsize_t)(link_end + rewind));\n    cmark_chunk_to_cstr(parser->mem, &email);\n    link_text->as.literal = email;\n    cmark_node_append_child(link_node, link_text);\n\n    cmark_node_insert_after(text, link_node);\n\n    cmark_node *post = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n    post->as.literal = cmark_chunk_dup(&detached_chunk,\n                                       (bufsize_t)(start + offset + max_rewind + link_end),\n                                       (bufsize_t)(remaining - offset - max_rewind - link_end));\n\n    cmark_node_insert_after(link_node, post);\n\n    text->as.literal = cmark_chunk_dup(&detached_chunk, (bufsize_t)start, (bufsize_t)(offset + max_rewind - rewind));\n    cmark_chunk_to_cstr(parser->mem, &text->as.literal);\n\n    text = post;\n    start += offset + max_rewind + link_end;\n    remaining -= offset + max_rewind + link_end;\n    offset = 0;\n  }\n\n  // Convert the reference to allocated memory.\n  assert(!text->as.literal.alloc);\n  cmark_chunk_to_cstr(parser->mem, &text->as.literal);\n\n  // Free the detached buffer.\n  cmark_chunk_free(parser->mem, &detached_chunk);\n}\n\nstatic cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {\n  cmark_iter *iter;\n  cmark_event_type ev;\n  cmark_node *node;\n  bool in_link = false;\n\n  cmark_consolidate_text_nodes(root);\n  iter = cmark_iter_new(root);\n\n  while ((ev = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    node = cmark_iter_get_node(iter);\n    if (in_link) {\n      if (ev == CMARK_EVENT_EXIT && node->type == CMARK_NODE_LINK) {\n        in_link = false;\n      }\n      continue;\n    }\n\n    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_LINK) {\n      in_link = true;\n      continue;\n    }\n\n    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {\n      postprocess_text(parser, node);\n    }\n  }\n\n  cmark_iter_free(iter);\n\n  return root;\n}\n\ncmark_syntax_extension *create_autolink_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"autolink\");\n  cmark_llist *special_chars = NULL;\n\n  cmark_syntax_extension_set_match_inline_func(ext, match);\n  cmark_syntax_extension_set_postprocess_func(ext, postprocess);\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n  special_chars = cmark_llist_append(mem, special_chars, (void *)':');\n  special_chars = cmark_llist_append(mem, special_chars, (void *)'w');\n  cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n\n  return ext;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/autolink.h",
    "content": "#ifndef CMARK_GFM_AUTOLINK_H\n#define CMARK_GFM_AUTOLINK_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\ncmark_syntax_extension *create_autolink_extension(void);\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/cmark-gfm-core-extensions.h",
    "content": "#ifndef CMARK_GFM_CORE_EXTENSIONS_H\n#define CMARK_GFM_CORE_EXTENSIONS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm-extension_api.h\"\n#include \"cmark-gfm_export.h\"\n#include <stdbool.h>\n#include <stdint.h>\n\nCMARK_GFM_EXPORT\nvoid cmark_gfm_core_extensions_ensure_registered(void);\n\nCMARK_GFM_EXPORT\nuint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);\n\n/** Sets the number of columns for the table, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns);\n\nCMARK_GFM_EXPORT\nuint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);\n\n/** Sets the alignments for the table, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments);\n\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);\n\n/** Sets whether the node is a table header row, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header);\n\nCMARK_GFM_EXPORT\nbool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node);\n/* For backwards compatibility */\n#define cmark_gfm_extensions_tasklist_is_checked cmark_gfm_extensions_get_tasklist_item_checked\n\n/** Sets whether a tasklist item is \"checked\" (completed), returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/core-extensions.c",
    "content": "#include \"cmark-gfm-core-extensions.h\"\n#include \"autolink.h\"\n#include \"strikethrough.h\"\n#include \"table.h\"\n#include \"tagfilter.h\"\n#include \"tasklist.h\"\n#include \"registry.h\"\n#include \"plugin.h\"\n\nstatic int core_extensions_registration(cmark_plugin *plugin) {\n  cmark_plugin_register_syntax_extension(plugin, create_table_extension());\n  cmark_plugin_register_syntax_extension(plugin,\n                                         create_strikethrough_extension());\n  cmark_plugin_register_syntax_extension(plugin, create_autolink_extension());\n  cmark_plugin_register_syntax_extension(plugin, create_tagfilter_extension());\n  cmark_plugin_register_syntax_extension(plugin, create_tasklist_extension());\n  return 1;\n}\n\nvoid cmark_gfm_core_extensions_ensure_registered(void) {\n  static int registered = 0;\n\n  if (!registered) {\n    cmark_register_plugin(core_extensions_registration);\n    registered = 1;\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/ext_scanners.c",
    "content": "/* Generated by re2c 1.3 */\n\n#include \"ext_scanners.h\"\n#include <stdlib.h>\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *),\n                       unsigned char *ptr, int len, bufsize_t offset) {\n  bufsize_t res;\n\n  if (ptr == NULL || offset >= len) {\n    return 0;\n  } else {\n    unsigned char lim = ptr[len];\n\n    ptr[len] = '\\0';\n    res = scanner(ptr + offset);\n    ptr[len] = lim;\n  }\n\n  return res;\n}\n\nbufsize_t _scan_table_start(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 64, 0,  64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  64, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 128, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= ' ') {\n      if (yych <= '\\n') {\n        if (yych == '\\t')\n          goto yy4;\n      } else {\n        if (yych <= '\\f')\n          goto yy4;\n        if (yych >= ' ')\n          goto yy4;\n      }\n    } else {\n      if (yych <= '9') {\n        if (yych == '-')\n          goto yy5;\n      } else {\n        if (yych <= ':')\n          goto yy6;\n        if (yych == '|')\n          goto yy4;\n      }\n    }\n    ++p;\n  yy3 : { return 0; }\n  yy4:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy7;\n    }\n    if (yych == '-')\n      goto yy10;\n    if (yych == ':')\n      goto yy12;\n    goto yy3;\n  yy5:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy10;\n    }\n    if (yych <= ' ') {\n      if (yych <= 0x08)\n        goto yy3;\n      if (yych <= '\\r')\n        goto yy14;\n      if (yych <= 0x1F)\n        goto yy3;\n      goto yy14;\n    } else {\n      if (yych <= ':') {\n        if (yych <= '9')\n          goto yy3;\n        goto yy13;\n      } else {\n        if (yych == '|')\n          goto yy14;\n        goto yy3;\n      }\n    }\n  yy6:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy10;\n    }\n    goto yy3;\n  yy7:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy7;\n    }\n    if (yych == '-')\n      goto yy10;\n    if (yych == ':')\n      goto yy12;\n  yy9:\n    p = marker;\n    goto yy3;\n  yy10:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy10;\n    }\n    if (yych <= 0x1F) {\n      if (yych <= '\\n') {\n        if (yych <= 0x08)\n          goto yy9;\n        if (yych <= '\\t')\n          goto yy13;\n        goto yy15;\n      } else {\n        if (yych <= '\\f')\n          goto yy13;\n        if (yych <= '\\r')\n          goto yy17;\n        goto yy9;\n      }\n    } else {\n      if (yych <= ':') {\n        if (yych <= ' ')\n          goto yy13;\n        if (yych <= '9')\n          goto yy9;\n        goto yy13;\n      } else {\n        if (yych == '|')\n          goto yy18;\n        goto yy9;\n      }\n    }\n  yy12:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy10;\n    }\n    goto yy9;\n  yy13:\n    yych = *++p;\n  yy14:\n    if (yych <= '\\r') {\n      if (yych <= '\\t') {\n        if (yych <= 0x08)\n          goto yy9;\n        goto yy13;\n      } else {\n        if (yych <= '\\n')\n          goto yy15;\n        if (yych <= '\\f')\n          goto yy13;\n        goto yy17;\n      }\n    } else {\n      if (yych <= ' ') {\n        if (yych <= 0x1F)\n          goto yy9;\n        goto yy13;\n      } else {\n        if (yych == '|')\n          goto yy18;\n        goto yy9;\n      }\n    }\n  yy15:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy17:\n    yych = *++p;\n    if (yych == '\\n')\n      goto yy15;\n    goto yy9;\n  yy18:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy10;\n    }\n    if (yych <= '\\r') {\n      if (yych <= '\\t') {\n        if (yych <= 0x08)\n          goto yy9;\n        goto yy18;\n      } else {\n        if (yych <= '\\n')\n          goto yy15;\n        if (yych <= '\\f')\n          goto yy18;\n        goto yy17;\n      }\n    } else {\n      if (yych <= ' ') {\n        if (yych <= 0x1F)\n          goto yy9;\n        goto yy18;\n      } else {\n        if (yych == ':')\n          goto yy12;\n        goto yy9;\n      }\n    }\n  }\n}\n\nbufsize_t _scan_table_cell(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 0,  64, 64, 0,  64, 64, 64, 64,\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0,  64,\n        64, 64, 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,   0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 64) {\n      goto yy22;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\r')\n          goto yy25;\n        if (yych <= '\\\\')\n          goto yy27;\n        goto yy25;\n      } else {\n        if (yych <= 0xDF)\n          goto yy29;\n        if (yych <= 0xE0)\n          goto yy30;\n        goto yy31;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy32;\n        if (yych <= 0xEF)\n          goto yy31;\n        goto yy33;\n      } else {\n        if (yych <= 0xF3)\n          goto yy34;\n        if (yych <= 0xF4)\n          goto yy35;\n        goto yy25;\n      }\n    }\n  yy22:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy22;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\r')\n          goto yy24;\n        if (yych <= '\\\\')\n          goto yy27;\n      } else {\n        if (yych <= 0xDF)\n          goto yy36;\n        if (yych <= 0xE0)\n          goto yy38;\n        goto yy39;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy40;\n        if (yych <= 0xEF)\n          goto yy39;\n        goto yy41;\n      } else {\n        if (yych <= 0xF3)\n          goto yy42;\n        if (yych <= 0xF4)\n          goto yy43;\n      }\n    }\n  yy24 : { return (bufsize_t)(p - start); }\n  yy25:\n    ++p;\n  yy26 : { return 0; }\n  yy27:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy27;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '\\f') {\n        if (yych == '\\n')\n          goto yy24;\n        goto yy22;\n      } else {\n        if (yych <= '\\r')\n          goto yy24;\n        if (yych <= 0x7F)\n          goto yy22;\n        if (yych <= 0xC1)\n          goto yy24;\n        goto yy36;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy38;\n        if (yych == 0xED)\n          goto yy40;\n        goto yy39;\n      } else {\n        if (yych <= 0xF0)\n          goto yy41;\n        if (yych <= 0xF3)\n          goto yy42;\n        if (yych <= 0xF4)\n          goto yy43;\n        goto yy24;\n      }\n    }\n  yy29:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy26;\n    if (yych <= 0xBF)\n      goto yy22;\n    goto yy26;\n  yy30:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy26;\n    if (yych <= 0xBF)\n      goto yy36;\n    goto yy26;\n  yy31:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy26;\n    if (yych <= 0xBF)\n      goto yy36;\n    goto yy26;\n  yy32:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy26;\n    if (yych <= 0x9F)\n      goto yy36;\n    goto yy26;\n  yy33:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy26;\n    if (yych <= 0xBF)\n      goto yy39;\n    goto yy26;\n  yy34:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy26;\n    if (yych <= 0xBF)\n      goto yy39;\n    goto yy26;\n  yy35:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy26;\n    if (yych <= 0x8F)\n      goto yy39;\n    goto yy26;\n  yy36:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy37;\n    if (yych <= 0xBF)\n      goto yy22;\n  yy37:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy24;\n    } else {\n      goto yy26;\n    }\n  yy38:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy37;\n    if (yych <= 0xBF)\n      goto yy36;\n    goto yy37;\n  yy39:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy37;\n    if (yych <= 0xBF)\n      goto yy36;\n    goto yy37;\n  yy40:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy37;\n    if (yych <= 0x9F)\n      goto yy36;\n    goto yy37;\n  yy41:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy37;\n    if (yych <= 0xBF)\n      goto yy39;\n    goto yy37;\n  yy42:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy37;\n    if (yych <= 0xBF)\n      goto yy39;\n    goto yy37;\n  yy43:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy37;\n    if (yych <= 0x8F)\n      goto yy39;\n    goto yy37;\n  }\n}\n\nbufsize_t _scan_table_cell_end(const unsigned char *p) {\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   128, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '|')\n      goto yy48;\n    ++p;\n    { return 0; }\n  yy48:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy48;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n\nbufsize_t _scan_table_row_end(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   128, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy53;\n      if (yych == '\\n')\n        goto yy56;\n      goto yy55;\n    } else {\n      if (yych <= '\\r')\n        goto yy58;\n      if (yych == ' ')\n        goto yy55;\n    }\n  yy53:\n    ++p;\n  yy54 : { return 0; }\n  yy55:\n    yych = *(marker = ++p);\n    if (yych <= 0x08)\n      goto yy54;\n    if (yych <= '\\r')\n      goto yy60;\n    if (yych == ' ')\n      goto yy60;\n    goto yy54;\n  yy56:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy58:\n    yych = *++p;\n    if (yych == '\\n')\n      goto yy56;\n    goto yy54;\n  yy59:\n    yych = *++p;\n  yy60:\n    if (yybm[0 + yych] & 128) {\n      goto yy59;\n    }\n    if (yych <= 0x08)\n      goto yy61;\n    if (yych <= '\\n')\n      goto yy56;\n    if (yych <= '\\r')\n      goto yy62;\n  yy61:\n    p = marker;\n    goto yy54;\n  yy62:\n    yych = *++p;\n    if (yych == '\\n')\n      goto yy56;\n    goto yy61;\n  }\n}\n\nbufsize_t _scan_tasklist(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   64,  0, 64, 64, 0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0,  0,  0, 0, 0,\n    };\n    yych = *p;\n    if (yych <= ' ') {\n      if (yych <= '\\n') {\n        if (yych == '\\t')\n          goto yy67;\n      } else {\n        if (yych <= '\\f')\n          goto yy67;\n        if (yych >= ' ')\n          goto yy67;\n      }\n    } else {\n      if (yych <= ',') {\n        if (yych <= ')')\n          goto yy65;\n        if (yych <= '+')\n          goto yy68;\n      } else {\n        if (yych <= '-')\n          goto yy68;\n        if (yych <= '/')\n          goto yy65;\n        if (yych <= '9')\n          goto yy69;\n      }\n    }\n  yy65:\n    ++p;\n  yy66 : { return 0; }\n  yy67:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy70;\n    }\n    if (yych <= ',') {\n      if (yych <= ')')\n        goto yy66;\n      if (yych <= '+')\n        goto yy73;\n      goto yy66;\n    } else {\n      if (yych <= '-')\n        goto yy73;\n      if (yych <= '/')\n        goto yy66;\n      if (yych <= '9')\n        goto yy74;\n      goto yy66;\n    }\n  yy68:\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych == '\\t')\n        goto yy75;\n      goto yy66;\n    } else {\n      if (yych <= '\\f')\n        goto yy75;\n      if (yych == ' ')\n        goto yy75;\n      goto yy66;\n    }\n  yy69:\n    yych = *(marker = ++p);\n    if (yych <= 0x1F) {\n      if (yych <= '\\t') {\n        if (yych <= 0x08)\n          goto yy78;\n        goto yy73;\n      } else {\n        if (yych <= '\\n')\n          goto yy66;\n        if (yych <= '\\f')\n          goto yy73;\n        goto yy78;\n      }\n    } else {\n      if (yych <= 0x7F) {\n        if (yych <= ' ')\n          goto yy73;\n        goto yy78;\n      } else {\n        if (yych <= 0xC1)\n          goto yy66;\n        if (yych <= 0xF4)\n          goto yy78;\n        goto yy66;\n      }\n    }\n  yy70:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy70;\n    }\n    if (yych <= ',') {\n      if (yych <= ')')\n        goto yy72;\n      if (yych <= '+')\n        goto yy73;\n    } else {\n      if (yych <= '-')\n        goto yy73;\n      if (yych <= '/')\n        goto yy72;\n      if (yych <= '9')\n        goto yy74;\n    }\n  yy72:\n    p = marker;\n    goto yy66;\n  yy73:\n    yych = *++p;\n    if (yych == '[')\n      goto yy72;\n    goto yy76;\n  yy74:\n    yych = *++p;\n    if (yych <= '\\n') {\n      if (yych == '\\t')\n        goto yy73;\n      goto yy78;\n    } else {\n      if (yych <= '\\f')\n        goto yy73;\n      if (yych == ' ')\n        goto yy73;\n      goto yy78;\n    }\n  yy75:\n    yych = *++p;\n  yy76:\n    if (yych <= '\\f') {\n      if (yych == '\\t')\n        goto yy75;\n      if (yych <= '\\n')\n        goto yy72;\n      goto yy75;\n    } else {\n      if (yych <= ' ') {\n        if (yych <= 0x1F)\n          goto yy72;\n        goto yy75;\n      } else {\n        if (yych == '[')\n          goto yy86;\n        goto yy72;\n      }\n    }\n  yy77:\n    yych = *++p;\n  yy78:\n    if (yybm[0 + yych] & 128) {\n      goto yy77;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= '\\f') {\n        if (yych <= 0x08)\n          goto yy73;\n        if (yych == '\\n')\n          goto yy72;\n        goto yy75;\n      } else {\n        if (yych == ' ')\n          goto yy75;\n        if (yych <= 0x7F)\n          goto yy73;\n        goto yy72;\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy79;\n        if (yych <= 0xE0)\n          goto yy80;\n        if (yych <= 0xEC)\n          goto yy81;\n        goto yy82;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy81;\n          goto yy83;\n        } else {\n          if (yych <= 0xF3)\n            goto yy84;\n          if (yych <= 0xF4)\n            goto yy85;\n          goto yy72;\n        }\n      }\n    }\n  yy79:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy72;\n    if (yych <= 0xBF)\n      goto yy73;\n    goto yy72;\n  yy80:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy72;\n    if (yych <= 0xBF)\n      goto yy79;\n    goto yy72;\n  yy81:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy72;\n    if (yych <= 0xBF)\n      goto yy79;\n    goto yy72;\n  yy82:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy72;\n    if (yych <= 0x9F)\n      goto yy79;\n    goto yy72;\n  yy83:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy72;\n    if (yych <= 0xBF)\n      goto yy81;\n    goto yy72;\n  yy84:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy72;\n    if (yych <= 0xBF)\n      goto yy81;\n    goto yy72;\n  yy85:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy72;\n    if (yych <= 0x8F)\n      goto yy81;\n    goto yy72;\n  yy86:\n    yych = *++p;\n    if (yych <= 'W') {\n      if (yych != ' ')\n        goto yy72;\n    } else {\n      if (yych <= 'X')\n        goto yy87;\n      if (yych != 'x')\n        goto yy72;\n    }\n  yy87:\n    yych = *++p;\n    if (yych != ']')\n      goto yy72;\n    yych = *++p;\n    if (yych <= '\\n') {\n      if (yych != '\\t')\n        goto yy72;\n    } else {\n      if (yych <= '\\f')\n        goto yy89;\n      if (yych != ' ')\n        goto yy72;\n    }\n  yy89:\n    yych = *++p;\n    if (yych <= '\\n') {\n      if (yych == '\\t')\n        goto yy89;\n    } else {\n      if (yych <= '\\f')\n        goto yy89;\n      if (yych == ' ')\n        goto yy89;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/ext_scanners.h",
    "content": "#include \"chunk.h\"\n#include \"cmark-gfm.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *),\n                       unsigned char *ptr, int len, bufsize_t offset);\nbufsize_t _scan_table_start(const unsigned char *p);\nbufsize_t _scan_table_cell(const unsigned char *p);\nbufsize_t _scan_table_cell_end(const unsigned char *p);\nbufsize_t _scan_table_row_end(const unsigned char *p);\nbufsize_t _scan_tasklist(const unsigned char *p);\n\n#define scan_table_start(c, l, n) _ext_scan_at(&_scan_table_start, c, l, n)\n#define scan_table_cell(c, l, n) _ext_scan_at(&_scan_table_cell, c, l, n)\n#define scan_table_cell_end(c, l, n) _ext_scan_at(&_scan_table_cell_end, c, l, n)\n#define scan_table_row_end(c, l, n) _ext_scan_at(&_scan_table_row_end, c, l, n)\n#define scan_tasklist(c, l, n) _ext_scan_at(&_scan_tasklist, c, l, n)\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/ext_scanners.re",
    "content": "/*!re2c re2c:flags:no-debug-info = 1; */\n/*!re2c re2c:indent:string = '  '; */\n\n#include <stdlib.h>\n#include \"ext_scanners.h\"\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), unsigned char *ptr, int len, bufsize_t offset)\n{\n\tbufsize_t res;\n\n        if (ptr == NULL || offset >= len) {\n          return 0;\n        } else {\n\t  unsigned char lim = ptr[len];\n\n\t  ptr[len] = '\\0';\n\t  res = scanner(ptr + offset);\n\t  ptr[len] = lim;\n        }\n\n\treturn res;\n}\n\n/*!re2c\n  re2c:define:YYCTYPE  = \"unsigned char\";\n  re2c:define:YYCURSOR = p;\n  re2c:define:YYMARKER = marker;\n  re2c:yyfill:enable = 0;\n\n  spacechar = [ \\t\\v\\f];\n  newline = [\\r]?[\\n];\n  escaped_char = [\\\\][|!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{}~-];\n\n  table_marker = (spacechar*[:]?[-]+[:]?spacechar*);\n  table_cell = (escaped_char|[^|\\r\\n])+;\n\n  tasklist = spacechar*(\"-\"|\"+\"|\"*\"|[0-9]+.)spacechar+(\"[ ]\"|\"[x]\")spacechar+;\n*/\n\nbufsize_t _scan_table_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    [|]? table_marker ([|] table_marker)* [|]? spacechar* newline {\n      return (bufsize_t)(p - start);\n    }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_cell(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    // In fact, `table_cell` matches non-empty table cells only. The empty\n    // string is also a valid table cell, but is handled by the default rule.\n    // This approach prevents re2c's match-empty-string warning.\n    table_cell { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_cell_end(const unsigned char *p)\n{\n  const unsigned char *start = p;\n  /*!re2c\n    [|] spacechar* { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_row_end(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    spacechar* newline { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_tasklist(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    tasklist { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/strikethrough.c",
    "content": "#include \"strikethrough.h\"\n#include <parser.h>\n#include <render.h>\n\ncmark_node_type CMARK_NODE_STRIKETHROUGH;\n\nstatic cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_node *parent, unsigned char character,\n                         cmark_inline_parser *inline_parser) {\n  cmark_node *res = NULL;\n  int left_flanking, right_flanking, punct_before, punct_after, delims;\n  char buffer[101];\n\n  if (character != '~')\n    return NULL;\n\n  delims = cmark_inline_parser_scan_delimiters(\n      inline_parser, sizeof(buffer) - 1, '~',\n      &left_flanking,\n      &right_flanking, &punct_before, &punct_after);\n\n  memset(buffer, '~', delims);\n  buffer[delims] = 0;\n\n  res = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  cmark_node_set_literal(res, buffer);\n  res->start_line = res->end_line = cmark_inline_parser_get_line(inline_parser);\n  res->start_column = cmark_inline_parser_get_column(inline_parser) - delims;\n\n  if ((left_flanking || right_flanking) &&\n      (delims == 2 || (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) && delims == 1))) {\n    cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking,\n                                       right_flanking, res);\n  }\n\n  return res;\n}\n\nstatic delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_inline_parser *inline_parser, delimiter *opener,\n                         delimiter *closer) {\n  cmark_node *strikethrough;\n  cmark_node *tmp, *next;\n  delimiter *delim, *tmp_delim;\n  delimiter *res = closer->next;\n\n  strikethrough = opener->inl_text;\n\n  if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)\n    goto done;\n\n  if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))\n    goto done;\n\n  cmark_node_set_syntax_extension(strikethrough, self);\n\n  tmp = cmark_node_next(opener->inl_text);\n\n  while (tmp) {\n    if (tmp == closer->inl_text)\n      break;\n    next = cmark_node_next(tmp);\n    cmark_node_append_child(strikethrough, tmp);\n    tmp = next;\n  }\n\n  strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;\n  cmark_node_free(closer->inl_text);\n\ndone:\n  delim = closer;\n  while (delim != NULL && delim != opener) {\n    tmp_delim = delim->previous;\n    cmark_inline_parser_remove_delimiter(inline_parser, delim);\n    delim = tmp_delim;\n  }\n\n  cmark_inline_parser_remove_delimiter(inline_parser, opener);\n\n  return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *extension,\n                                   cmark_node *node) {\n  return node->type == CMARK_NODE_STRIKETHROUGH ? \"strikethrough\" : \"<unknown>\";\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  if (node->type != CMARK_NODE_STRIKETHROUGH)\n    return false;\n\n  return CMARK_NODE_TYPE_INLINE_P(child_type);\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  renderer->out(renderer, node, \"~~\", false, LITERAL);\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  // requires \\usepackage{ulem}\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->out(renderer, node, \"\\\\sout{\", false, LITERAL);\n  } else {\n    renderer->out(renderer, node, \"}\", false, LITERAL);\n  }\n}\n\nstatic void man_render(cmark_syntax_extension *extension,\n                       cmark_renderer *renderer, cmark_node *node,\n                       cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->cr(renderer);\n    renderer->out(renderer, node, \".ST \\\"\", false, LITERAL);\n  } else {\n    renderer->out(renderer, node, \"\\\"\", false, LITERAL);\n    renderer->cr(renderer);\n  }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    cmark_strbuf_puts(renderer->html, \"<del>\");\n  } else {\n    cmark_strbuf_puts(renderer->html, \"</del>\");\n  }\n}\n\nstatic void plaintext_render(cmark_syntax_extension *extension,\n                             cmark_renderer *renderer, cmark_node *node,\n                             cmark_event_type ev_type, int options) {\n  renderer->out(renderer, node, \"~\", false, LITERAL);\n}\n\ncmark_syntax_extension *create_strikethrough_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"strikethrough\");\n  cmark_llist *special_chars = NULL;\n\n  cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n  cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n  cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_latex_render_func(ext, latex_render);\n  cmark_syntax_extension_set_man_render_func(ext, man_render);\n  cmark_syntax_extension_set_html_render_func(ext, html_render);\n  cmark_syntax_extension_set_plaintext_render_func(ext, plaintext_render);\n  CMARK_NODE_STRIKETHROUGH = cmark_syntax_extension_add_node(1);\n\n  cmark_syntax_extension_set_match_inline_func(ext, match);\n  cmark_syntax_extension_set_inline_from_delim_func(ext, insert);\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n  special_chars = cmark_llist_append(mem, special_chars, (void *)'~');\n  cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n\n  cmark_syntax_extension_set_emphasis(ext, 1);\n\n  return ext;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/strikethrough.h",
    "content": "#ifndef CMARK_GFM_STRIKETHROUGH_H\n#define CMARK_GFM_STRIKETHROUGH_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nextern cmark_node_type CMARK_NODE_STRIKETHROUGH;\ncmark_syntax_extension *create_strikethrough_extension(void);\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/table.c",
    "content": "#include <cmark-gfm-extension_api.h>\n#include <html.h>\n#include <inlines.h>\n#include <parser.h>\n#include <references.h>\n#include <string.h>\n#include <render.h>\n\n#include \"ext_scanners.h\"\n#include \"strikethrough.h\"\n#include \"table.h\"\n#include \"cmark-gfm-core-extensions.h\"\n\n// Limit to prevent a malicious input from causing a denial of service.\n#define MAX_AUTOCOMPLETED_CELLS 0x80000\n\n// Custom node flag, initialized in `create_table_extension`.\nstatic cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;\n\ncmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,\n    CMARK_NODE_TABLE_CELL;\n\ntypedef struct {\n  cmark_strbuf *buf;\n  int start_offset, end_offset, internal_offset;\n} node_cell;\n\ntypedef struct {\n  uint16_t n_columns;\n  int paragraph_offset;\n  node_cell *cells;\n} table_row;\n\ntypedef struct {\n  uint16_t n_columns;\n  uint8_t *alignments;\n  int n_rows;\n  int n_nonempty_cells;\n} node_table;\n\ntypedef struct {\n  bool is_header;\n} node_table_row;\n\nstatic void free_table_cell(cmark_mem *mem, node_cell *cell) {\n  cmark_strbuf_free((cmark_strbuf *)cell->buf);\n  mem->free(cell->buf);\n}\n\nstatic void free_row_cells(cmark_mem *mem, table_row *row) {\n  while (row->n_columns > 0) {\n    free_table_cell(mem, &row->cells[--row->n_columns]);\n  }\n  mem->free(row->cells);\n  row->cells = NULL;\n}\n\nstatic void free_table_row(cmark_mem *mem, table_row *row) {\n  if (!row)\n    return;\n\n  free_row_cells(mem, row);\n  mem->free(row);\n}\n\nstatic void free_node_table(cmark_mem *mem, void *ptr) {\n  node_table *t = (node_table *)ptr;\n  mem->free(t->alignments);\n  mem->free(t);\n}\n\nstatic void free_node_table_row(cmark_mem *mem, void *ptr) {\n  mem->free(ptr);\n}\n\nstatic int get_n_table_columns(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return -1;\n\n  return (int)((node_table *)node->as.opaque)->n_columns;\n}\n\nstatic int set_n_table_columns(cmark_node *node, uint16_t n_columns) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  ((node_table *)node->as.opaque)->n_columns = n_columns;\n  return 1;\n}\n\n// Increment the number of rows in the table. Also update n_nonempty_cells,\n// which keeps track of the number of cells which were parsed from the\n// input file. (If one of the rows is too short, then the trailing cells\n// are autocompleted. Autocompleted cells are not counted in n_nonempty_cells.)\n// The purpose of this is to prevent a malicious input from generating a very\n// large number of autocompleted cells, which could cause a denial of service\n// vulnerability.\nstatic int incr_table_row_count(cmark_node *node, int i) {\n  if (!node || node->type != CMARK_NODE_TABLE) {\n    return 0;\n  }\n\n  ((node_table *)node->as.opaque)->n_rows++;\n  ((node_table *)node->as.opaque)->n_nonempty_cells += i;\n  return 1;\n}\n\n// Calculate the number of autocompleted cells.\nstatic int get_n_autocompleted_cells(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE) {\n    return 0;\n  }\n\n  const node_table *nt = (node_table *)node->as.opaque;\n  return (nt->n_columns * nt->n_rows) - nt->n_nonempty_cells;\n}\n\nstatic uint8_t *get_table_alignments(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->alignments;\n}\n\nstatic int set_table_alignments(cmark_node *node, uint8_t *alignments) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  ((node_table *)node->as.opaque)->alignments = alignments;\n  return 1;\n}\n\nstatic uint8_t get_cell_alignment(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE_CELL)\n    return 0;\n\n  const uint8_t *alignments = get_table_alignments(node->parent->parent);\n  int i = node->as.cell_index;\n  return alignments[i];\n}\n\nstatic int set_cell_index(cmark_node *node, int i) {\n  if (!node || node->type != CMARK_NODE_TABLE_CELL)\n    return 0;\n\n  node->as.cell_index = i;\n  return 1;\n}\n\nstatic cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsize_t len)\n{\n  cmark_strbuf *res = (cmark_strbuf *)mem->calloc(1, sizeof(cmark_strbuf));\n  bufsize_t r, w;\n\n  cmark_strbuf_init(mem, res, len + 1);\n  cmark_strbuf_put(res, string, len);\n  cmark_strbuf_putc(res, '\\0');\n\n  for (r = 0, w = 0; r < len; ++r) {\n    if (res->ptr[r] == '\\\\' && res->ptr[r + 1] == '|')\n      r++;\n\n    res->ptr[w++] = res->ptr[r];\n  }\n\n  cmark_strbuf_truncate(res, w);\n\n  return res;\n}\n\n// Adds a new cell to the end of the row. A pointer to the new cell is returned\n// for the caller to initialize.\nstatic node_cell* append_row_cell(cmark_mem *mem, table_row *row) {\n  const uint32_t n_columns = row->n_columns + 1;\n  // realloc when n_columns is a power of 2\n  if ((n_columns & (n_columns-1)) == 0) {\n    // make sure we never wrap row->n_columns\n    // offset will != len and our exit will clean up as intended\n    if (n_columns > UINT16_MAX) {\n      return NULL;\n    }\n    // Use realloc to double the size of the buffer.\n    row->cells = (node_cell *)mem->realloc(row->cells, (2 * n_columns - 1) * sizeof(node_cell));\n  }\n  row->n_columns = (uint16_t)n_columns;\n  return &row->cells[n_columns-1];\n}\n\nstatic table_row *row_from_string(cmark_syntax_extension *self,\n                                  cmark_parser *parser, unsigned char *string,\n                                  int len) {\n  // Parses a single table row. It has the following form:\n  // `delim? table_cell (delim table_cell)* delim? newline`\n  // Note that cells are allowed to be empty.\n  //\n  // From the GitHub-flavored Markdown specification:\n  //\n  // > Each row consists of cells containing arbitrary text, in which inlines\n  // > are parsed, separated by pipes (|). A leading and trailing pipe is also\n  // > recommended for clarity of reading, and if there’s otherwise parsing\n  // > ambiguity.\n\n  table_row *row = NULL;\n  bufsize_t cell_matched = 1, pipe_matched = 1, offset;\n  int expect_more_cells = 1;\n  int row_end_offset = 0;\n  int int_overflow_abort = 0;\n\n  row = (table_row *)parser->mem->calloc(1, sizeof(table_row));\n  row->n_columns = 0;\n  row->cells = NULL;\n\n  // Scan past the (optional) leading pipe.\n  offset = scan_table_cell_end(string, len, 0);\n\n  // Parse the cells of the row. Stop if we reach the end of the input, or if we\n  // cannot detect any more cells.\n  while (offset < len && expect_more_cells) {\n    cell_matched = scan_table_cell(string, len, offset);\n    pipe_matched = scan_table_cell_end(string, len, offset + cell_matched);\n\n    if (cell_matched || pipe_matched) {\n      // We are guaranteed to have a cell, since (1) either we found some\n      // content and cell_matched, or (2) we found an empty cell followed by a\n      // pipe.\n      cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,\n          cell_matched);\n      cmark_strbuf_trim(cell_buf);\n\n      node_cell *cell = append_row_cell(parser->mem, row);\n      if (!cell) {\n        int_overflow_abort = 1;\n        cmark_strbuf_free(cell_buf);\n        parser->mem->free(cell_buf);\n        break;\n      }\n      cell->buf = cell_buf;\n      cell->start_offset = offset;\n      cell->end_offset = offset + cell_matched - 1;\n      cell->internal_offset = 0;\n\n      while (cell->start_offset > row->paragraph_offset && string[cell->start_offset - 1] != '|') {\n        --cell->start_offset;\n        ++cell->internal_offset;\n      }\n    }\n\n    offset += cell_matched + pipe_matched;\n\n    if (pipe_matched) {\n      expect_more_cells = 1;\n    } else {\n      // We've scanned the last cell. Check if we have reached the end of the row\n      row_end_offset = scan_table_row_end(string, len, offset);\n      offset += row_end_offset;\n\n      // If the end of the row is not the end of the input,\n      // the row is not a real row but potentially part of the paragraph\n      // preceding the table.\n      if (row_end_offset && offset != len) {\n        row->paragraph_offset = offset;\n\n        free_row_cells(parser->mem, row);\n\n        // Scan past the (optional) leading pipe.\n        offset += scan_table_cell_end(string, len, offset);\n\n        expect_more_cells = 1;\n      } else {\n        expect_more_cells = 0;\n      }\n    }\n  }\n\n  if (offset != len || row->n_columns == 0 || int_overflow_abort) {\n    free_table_row(parser->mem, row);\n    row = NULL;\n  }\n\n  return row;\n}\n\nstatic void try_inserting_table_header_paragraph(cmark_parser *parser,\n                                                 cmark_node *parent_container,\n                                                 unsigned char *parent_string,\n                                                 int paragraph_offset) {\n  cmark_node *paragraph;\n  cmark_strbuf *paragraph_content;\n\n  paragraph = cmark_node_new_with_mem(CMARK_NODE_PARAGRAPH, parser->mem);\n\n  paragraph_content = unescape_pipes(parser->mem, parent_string, paragraph_offset);\n  cmark_strbuf_trim(paragraph_content);\n  cmark_node_set_string_content(paragraph, (char *) paragraph_content->ptr);\n  cmark_strbuf_free(paragraph_content);\n  parser->mem->free(paragraph_content);\n\n  if (!cmark_node_insert_before(parent_container, paragraph)) {\n    parser->mem->free(paragraph);\n  }\n}\n\nstatic cmark_node *try_opening_table_header(cmark_syntax_extension *self,\n                                            cmark_parser *parser,\n                                            cmark_node *parent_container,\n                                            unsigned char *input, int len) {\n  cmark_node *table_header;\n  table_row *header_row = NULL;\n  table_row *delimiter_row = NULL;\n  node_table_row *ntr;\n  const char *parent_string;\n  uint16_t i;\n\n  if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {\n    return parent_container;\n  }\n\n  if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {\n    return parent_container;\n  }\n\n  // Since scan_table_start was successful, we must have a delimiter row.\n  delimiter_row = row_from_string(\n    self, parser, input + cmark_parser_get_first_nonspace(parser),\n    len - cmark_parser_get_first_nonspace(parser));\n  // assert may be optimized out, don't rely on it for security boundaries\n  if (!delimiter_row) {\n      return parent_container;\n  }\n\n  assert(delimiter_row);\n\n  cmark_arena_push();\n\n  // Check for a matching header row. We call `row_from_string` with the entire\n  // (potentially long) parent container as input, but this should be safe since\n  // `row_from_string` bails out early if it does not find a row.\n  parent_string = cmark_node_get_string_content(parent_container);\n  header_row = row_from_string(self, parser, (unsigned char *)parent_string,\n                               (int)strlen(parent_string));\n  if (!header_row || header_row->n_columns != delimiter_row->n_columns) {\n    free_table_row(parser->mem, delimiter_row);\n    free_table_row(parser->mem, header_row);\n    cmark_arena_pop();\n    parent_container->flags |= CMARK_NODE__TABLE_VISITED;\n    return parent_container;\n  }\n\n  if (cmark_arena_pop()) {\n    delimiter_row = row_from_string(\n        self, parser, input + cmark_parser_get_first_nonspace(parser),\n        len - cmark_parser_get_first_nonspace(parser));\n    header_row = row_from_string(self, parser, (unsigned char *)parent_string,\n                                 (int)strlen(parent_string));\n    // row_from_string can return NULL, add additional check to ensure n_columns match\n    if (!delimiter_row || !header_row || header_row->n_columns != delimiter_row->n_columns) {\n        free_table_row(parser->mem, delimiter_row);\n        free_table_row(parser->mem, header_row);\n        return parent_container;\n    }\n  }\n\n  if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {\n    free_table_row(parser->mem, header_row);\n    free_table_row(parser->mem, delimiter_row);\n    return parent_container;\n  }\n\n  if (header_row->paragraph_offset) {\n    try_inserting_table_header_paragraph(parser, parent_container, (unsigned char *)parent_string,\n                                         header_row->paragraph_offset);\n  }\n\n  cmark_node_set_syntax_extension(parent_container, self);\n  parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));\n  set_n_table_columns(parent_container, header_row->n_columns);\n\n  // allocate alignments based on delimiter_row->n_columns\n  // since we populate the alignments array based on delimiter_row->cells\n  uint8_t *alignments =\n      (uint8_t *)parser->mem->calloc(delimiter_row->n_columns, sizeof(uint8_t));\n  for (i = 0; i < delimiter_row->n_columns; ++i) {\n    node_cell *node = &delimiter_row->cells[i];\n    bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';\n\n    if (left && right)\n      alignments[i] = 'c';\n    else if (left)\n      alignments[i] = 'l';\n    else if (right)\n      alignments[i] = 'r';\n  }\n  set_table_alignments(parent_container, alignments);\n\n  table_header =\n      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,\n                             parent_container->start_column);\n  cmark_node_set_syntax_extension(table_header, self);\n  table_header->end_column = parent_container->start_column + (int)strlen(parent_string) - 2;\n  table_header->start_line = table_header->end_line = parent_container->start_line;\n\n  table_header->as.opaque = ntr = (node_table_row *)parser->mem->calloc(1, sizeof(node_table_row));\n  ntr->is_header = true;\n\n  for (i = 0; i < header_row->n_columns; ++i) {\n    node_cell *cell = &header_row->cells[i];\n    cmark_node *header_cell = cmark_parser_add_child(parser, table_header,\n                                                     CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);\n    header_cell->start_line = header_cell->end_line = parent_container->start_line;\n    header_cell->internal_offset = cell->internal_offset;\n    header_cell->end_column = parent_container->start_column + cell->end_offset;\n    cmark_node_set_string_content(header_cell, (char *) cell->buf->ptr);\n    cmark_node_set_syntax_extension(header_cell, self);\n    set_cell_index(header_cell, i);\n  }\n\n  incr_table_row_count(parent_container, i);\n\n  cmark_parser_advance_offset(\n      parser, (char *)input,\n      (int)strlen((char *)input) - 1 - cmark_parser_get_offset(parser), false);\n\n  free_table_row(parser->mem, header_row);\n  free_table_row(parser->mem, delimiter_row);\n  return parent_container;\n}\n\nstatic cmark_node *try_opening_table_row(cmark_syntax_extension *self,\n                                         cmark_parser *parser,\n                                         cmark_node *parent_container,\n                                         unsigned char *input, int len) {\n  cmark_node *table_row_block;\n  table_row *row;\n\n  if (cmark_parser_is_blank(parser))\n    return NULL;\n\n  if (get_n_autocompleted_cells(parent_container) > MAX_AUTOCOMPLETED_CELLS) {\n    return NULL;\n  }\n\n  table_row_block =\n      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,\n                             parent_container->start_column);\n  cmark_node_set_syntax_extension(table_row_block, self);\n  table_row_block->end_column = parent_container->end_column;\n  table_row_block->as.opaque = parser->mem->calloc(1, sizeof(node_table_row));\n\n  row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),\n      len - cmark_parser_get_first_nonspace(parser));\n\n  if (!row) {\n      // clean up the dangling node\n      cmark_node_free(table_row_block);\n      return NULL;\n  }\n\n  {\n    int i, table_columns = get_n_table_columns(parent_container);\n\n    for (i = 0; i < row->n_columns && i < table_columns; ++i) {\n      node_cell *cell = &row->cells[i];\n      cmark_node *node = cmark_parser_add_child(parser, table_row_block,\n          CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);\n      node->internal_offset = cell->internal_offset;\n      node->end_column = parent_container->start_column + cell->end_offset;\n      cmark_node_set_string_content(node, (char *) cell->buf->ptr);\n      cmark_node_set_syntax_extension(node, self);\n      set_cell_index(node, i);\n    }\n\n    incr_table_row_count(parent_container, i);\n\n    for (; i < table_columns; ++i) {\n      cmark_node *node = cmark_parser_add_child(\n          parser, table_row_block, CMARK_NODE_TABLE_CELL, 0);\n      cmark_node_set_syntax_extension(node, self);\n      set_cell_index(node, i);\n    }\n  }\n\n  free_table_row(parser->mem, row);\n\n  cmark_parser_advance_offset(parser, (char *)input,\n                              len - 1 - cmark_parser_get_offset(parser), false);\n\n  return table_row_block;\n}\n\nstatic cmark_node *try_opening_table_block(cmark_syntax_extension *self,\n                                           int indented, cmark_parser *parser,\n                                           cmark_node *parent_container,\n                                           unsigned char *input, int len) {\n  cmark_node_type parent_type = cmark_node_get_type(parent_container);\n\n  if (!indented && parent_type == CMARK_NODE_PARAGRAPH) {\n    return try_opening_table_header(self, parser, parent_container, input, len);\n  } else if (!indented && parent_type == CMARK_NODE_TABLE) {\n    return try_opening_table_row(self, parser, parent_container, input, len);\n  }\n\n  return NULL;\n}\n\nstatic int matches(cmark_syntax_extension *self, cmark_parser *parser,\n                   unsigned char *input, int len,\n                   cmark_node *parent_container) {\n  int res = 0;\n\n  if (cmark_node_get_type(parent_container) == CMARK_NODE_TABLE) {\n    cmark_arena_push();\n    table_row *new_row = row_from_string(\n        self, parser, input + cmark_parser_get_first_nonspace(parser),\n        len - cmark_parser_get_first_nonspace(parser));\n    if (new_row && new_row->n_columns)\n      res = 1;\n    free_table_row(parser->mem, new_row);\n    cmark_arena_pop();\n  }\n\n  return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *self,\n                                   cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    return \"table\";\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (((node_table_row *)node->as.opaque)->is_header)\n      return \"table_header\";\n    else\n      return \"table_row\";\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    return \"table_cell\";\n  }\n\n  return \"<unknown>\";\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  if (node->type == CMARK_NODE_TABLE) {\n    return child_type == CMARK_NODE_TABLE_ROW;\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    return child_type == CMARK_NODE_TABLE_CELL;\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    return child_type == CMARK_NODE_TEXT || child_type == CMARK_NODE_CODE ||\n           child_type == CMARK_NODE_EMPH || child_type == CMARK_NODE_STRONG ||\n           child_type == CMARK_NODE_LINK || child_type == CMARK_NODE_IMAGE ||\n           child_type == CMARK_NODE_STRIKETHROUGH ||\n           child_type == CMARK_NODE_HTML_INLINE ||\n           child_type == CMARK_NODE_FOOTNOTE_REFERENCE;\n  }\n  return false;\n}\n\nstatic int contains_inlines(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  return node->type == CMARK_NODE_TABLE_CELL;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    renderer->blankline(renderer);\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (entering) {\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"|\", false, LITERAL);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (entering) {\n      renderer->out(renderer, node, \" \", false, LITERAL);\n    } else {\n      renderer->out(renderer, node, \" |\", false, LITERAL);\n      if (((node_table_row *)node->parent->as.opaque)->is_header &&\n          !node->next) {\n        int i;\n        uint8_t *alignments = get_table_alignments(node->parent->parent);\n        uint16_t n_cols =\n            ((node_table *)node->parent->parent->as.opaque)->n_columns;\n        renderer->cr(renderer);\n        renderer->out(renderer, node, \"|\", false, LITERAL);\n        for (i = 0; i < n_cols; i++) {\n          switch (alignments[i]) {\n          case 0:   renderer->out(renderer, node, \" --- |\", false, LITERAL); break;\n          case 'l': renderer->out(renderer, node, \" :-- |\", false, LITERAL); break;\n          case 'c': renderer->out(renderer, node, \" :-: |\", false, LITERAL); break;\n          case 'r': renderer->out(renderer, node, \" --: |\", false, LITERAL); break;\n          }\n        }\n        renderer->cr(renderer);\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      int i;\n      uint16_t n_cols;\n      uint8_t *alignments = get_table_alignments(node);\n\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\begin{table}\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\begin{tabular}{\", false, LITERAL);\n\n      n_cols = ((node_table *)node->as.opaque)->n_columns;\n      for (i = 0; i < n_cols; i++) {\n        switch(alignments[i]) {\n        case 0:\n        case 'l':\n          renderer->out(renderer, node, \"l\", false, LITERAL);\n          break;\n        case 'c':\n          renderer->out(renderer, node, \"c\", false, LITERAL);\n          break;\n        case 'r':\n          renderer->out(renderer, node, \"r\", false, LITERAL);\n          break;\n        }\n      }\n      renderer->out(renderer, node, \"}\", false, LITERAL);\n      renderer->cr(renderer);\n    } else {\n      renderer->out(renderer, node, \"\\\\end{tabular}\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\end{table}\", false, LITERAL);\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (!entering) {\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (!entering) {\n      if (node->next) {\n        renderer->out(renderer, node, \" & \", false, LITERAL);\n      } else {\n        renderer->out(renderer, node, \" \\\\\\\\\", false, LITERAL);\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic const char *xml_attr(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {\n      switch (get_cell_alignment(node)) {\n      case 'l': return \" align=\\\"left\\\"\";\n      case 'c': return \" align=\\\"center\\\"\";\n      case 'r': return \" align=\\\"right\\\"\";\n      }\n    }\n  }\n\n  return NULL;\n}\n\nstatic void man_render(cmark_syntax_extension *extension,\n                       cmark_renderer *renderer, cmark_node *node,\n                       cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      int i;\n      uint16_t n_cols;\n      uint8_t *alignments = get_table_alignments(node);\n\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \".TS\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"tab(@);\", false, LITERAL);\n      renderer->cr(renderer);\n\n      n_cols = ((node_table *)node->as.opaque)->n_columns;\n\n      for (i = 0; i < n_cols; i++) {\n        switch (alignments[i]) {\n        case 'l':\n          renderer->out(renderer, node, \"l\", false, LITERAL);\n          break;\n        case 0:\n        case 'c':\n          renderer->out(renderer, node, \"c\", false, LITERAL);\n          break;\n        case 'r':\n          renderer->out(renderer, node, \"r\", false, LITERAL);\n          break;\n        }\n      }\n\n      if (n_cols) {\n        renderer->out(renderer, node, \".\", false, LITERAL);\n        renderer->cr(renderer);\n      }\n    } else {\n      renderer->out(renderer, node, \".TE\", false, LITERAL);\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (!entering) {\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (!entering && node->next) {\n      renderer->out(renderer, node, \"@\", false, LITERAL);\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void html_table_add_align(cmark_strbuf* html, const char* align, int options) {\n  if (options & CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES) {\n    cmark_strbuf_puts(html, \" style=\\\"text-align: \");\n    cmark_strbuf_puts(html, align);\n    cmark_strbuf_puts(html, \"\\\"\");\n  } else {\n    cmark_strbuf_puts(html, \" align=\\\"\");\n    cmark_strbuf_puts(html, align);\n    cmark_strbuf_puts(html, \"\\\"\");\n  }\n}\n\nstruct html_table_state {\n  unsigned need_closing_table_body : 1;\n  unsigned in_table_header : 1;\n};\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  cmark_strbuf *html = renderer->html;\n\n  // XXX: we just monopolise renderer->opaque.\n  struct html_table_state *table_state =\n      (struct html_table_state *)&renderer->opaque;\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<table\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n      table_state->need_closing_table_body = false;\n    } else {\n      if (table_state->need_closing_table_body) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"</tbody>\");\n        cmark_html_render_cr(html);\n      }\n      table_state->need_closing_table_body = false;\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</table>\");\n      cmark_html_render_cr(html);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (((node_table_row *)node->as.opaque)->is_header) {\n        table_state->in_table_header = 1;\n        cmark_strbuf_puts(html, \"<thead>\");\n        cmark_html_render_cr(html);\n      } else if (!table_state->need_closing_table_body) {\n        cmark_strbuf_puts(html, \"<tbody>\");\n        cmark_html_render_cr(html);\n        table_state->need_closing_table_body = 1;\n      }\n      cmark_strbuf_puts(html, \"<tr\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</tr>\");\n      if (((node_table_row *)node->as.opaque)->is_header) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"</thead>\");\n        table_state->in_table_header = false;\n      }\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (table_state->in_table_header) {\n        cmark_strbuf_puts(html, \"<th\");\n      } else {\n        cmark_strbuf_puts(html, \"<td\");\n      }\n\n      switch (get_cell_alignment(node)) {\n      case 'l': html_table_add_align(html, \"left\", options); break;\n      case 'c': html_table_add_align(html, \"center\", options); break;\n      case 'r': html_table_add_align(html, \"right\", options); break;\n      }\n\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      if (table_state->in_table_header) {\n        cmark_strbuf_puts(html, \"</th>\");\n      } else {\n        cmark_strbuf_puts(html, \"</td>\");\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void opaque_alloc(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    node->as.opaque = mem->calloc(1, sizeof(node_table));\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    node->as.opaque = mem->calloc(1, sizeof(node_table_row));\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    node->as.opaque = mem->calloc(1, sizeof(node_cell));\n  }\n}\n\nstatic void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    free_node_table(mem, node->as.opaque);\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    free_node_table_row(mem, node->as.opaque);\n  }\n}\n\nstatic int escape(cmark_syntax_extension *self, cmark_node *node, int c) {\n  return\n    node->type != CMARK_NODE_TABLE &&\n    node->type != CMARK_NODE_TABLE_ROW &&\n    node->type != CMARK_NODE_TABLE_CELL &&\n    c == '|';\n}\n\ncmark_syntax_extension *create_table_extension(void) {\n  cmark_syntax_extension *self = cmark_syntax_extension_new(\"table\");\n\n  cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);\n  cmark_syntax_extension_set_match_block_func(self, matches);\n  cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);\n  cmark_syntax_extension_set_get_type_string_func(self, get_type_string);\n  cmark_syntax_extension_set_can_contain_func(self, can_contain);\n  cmark_syntax_extension_set_contains_inlines_func(self, contains_inlines);\n  cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);\n  cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);\n  cmark_syntax_extension_set_latex_render_func(self, latex_render);\n  cmark_syntax_extension_set_xml_attr_func(self, xml_attr);\n  cmark_syntax_extension_set_man_render_func(self, man_render);\n  cmark_syntax_extension_set_html_render_func(self, html_render);\n  cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc);\n  cmark_syntax_extension_set_opaque_free_func(self, opaque_free);\n  cmark_syntax_extension_set_commonmark_escape_func(self, escape);\n  CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);\n  CMARK_NODE_TABLE_ROW = cmark_syntax_extension_add_node(0);\n  CMARK_NODE_TABLE_CELL = cmark_syntax_extension_add_node(0);\n\n  return self;\n}\n\nuint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node) {\n  if (node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->n_columns;\n}\n\nuint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node) {\n  if (node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->alignments;\n}\n\nint cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns) {\n  return set_n_table_columns(node, n_columns);\n}\n\nint cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments) {\n  uint8_t *a = (uint8_t *)cmark_node_mem(node)->calloc(1, ncols);\n  memcpy(a, alignments, ncols);\n  return set_table_alignments(node, a);\n}\n\nint cmark_gfm_extensions_get_table_row_is_header(cmark_node *node)\n{\n  if (!node || node->type != CMARK_NODE_TABLE_ROW)\n    return 0;\n\n  return ((node_table_row *)node->as.opaque)->is_header;\n}\n\nint cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header)\n{\n  if (!node || node->type != CMARK_NODE_TABLE_ROW)\n    return 0;\n\n  ((node_table_row *)node->as.opaque)->is_header = (is_header != 0);\n  return 1;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/table.h",
    "content": "#ifndef CMARK_GFM_TABLE_H\n#define CMARK_GFM_TABLE_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\n\nextern cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,\n    CMARK_NODE_TABLE_CELL;\n\ncmark_syntax_extension *create_table_extension(void);\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/tagfilter.c",
    "content": "#include \"tagfilter.h\"\n#include <parser.h>\n#include <ctype.h>\n\nstatic const char *blacklist[] = {\n    \"title\",   \"textarea\", \"style\",  \"xmp\",       \"iframe\",\n    \"noembed\", \"noframes\", \"script\", \"plaintext\", NULL,\n};\n\nstatic int is_tag(const unsigned char *tag_data, size_t tag_size,\n                  const char *tagname) {\n  size_t i;\n\n  if (tag_size < 3 || tag_data[0] != '<')\n    return 0;\n\n  i = 1;\n\n  if (tag_data[i] == '/') {\n    i++;\n  }\n\n  for (; i < tag_size; ++i, ++tagname) {\n    if (*tagname == 0)\n      break;\n\n    if (tolower(tag_data[i]) != *tagname)\n      return 0;\n  }\n\n  if (i == tag_size)\n    return 0;\n\n  if (cmark_isspace(tag_data[i]) || tag_data[i] == '>')\n    return 1;\n\n  if (tag_data[i] == '/' && tag_size >= i + 2 && tag_data[i + 1] == '>')\n    return 1;\n\n  return 0;\n}\n\nstatic int filter(cmark_syntax_extension *ext, const unsigned char *tag,\n                  size_t tag_len) {\n  const char **it;\n\n  for (it = blacklist; *it; ++it) {\n    if (is_tag(tag, tag_len, *it)) {\n      return 0;\n    }\n  }\n\n  return 1;\n}\n\ncmark_syntax_extension *create_tagfilter_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"tagfilter\");\n  cmark_syntax_extension_set_html_filter_func(ext, filter);\n  return ext;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/tagfilter.h",
    "content": "#ifndef CMARK_GFM_TAGFILTER_H\n#define CMARK_GFM_TAGFILTER_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\ncmark_syntax_extension *create_tagfilter_extension(void);\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/tasklist.c",
    "content": "#include \"tasklist.h\"\n#include <parser.h>\n#include <render.h>\n#include <html.h>\n#include \"ext_scanners.h\"\n\ntypedef enum {\n  CMARK_TASKLIST_NOCHECKED,\n  CMARK_TASKLIST_CHECKED,\n} cmark_tasklist_type;\n\n// Local constants\nstatic const char *TYPE_STRING = \"tasklist\";\n\nstatic const char *get_type_string(cmark_syntax_extension *extension, cmark_node *node) {\n  return TYPE_STRING;\n}\n\n\n// Return 1 if state was set, 0 otherwise\nint cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked) {\n  // The node has to exist, and be an extension, and actually be the right type in order to get the value.\n  if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))\n    return 0;\n\n  node->as.list.checked = is_checked;\n  return 1;\n}\n\nbool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node) {\n  if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))\n    return false;\n\n  if (node->as.list.checked) {\n    return true;\n  }\n  else {\n    return false;\n  }\n}\n\nstatic bool parse_node_item_prefix(cmark_parser *parser, const char *input,\n                                   cmark_node *container) {\n  bool res = false;\n\n  if (parser->indent >=\n      container->as.list.marker_offset + container->as.list.padding) {\n    cmark_parser_advance_offset(parser, input, container->as.list.marker_offset +\n                                        container->as.list.padding,\n                     true);\n    res = true;\n  } else if (parser->blank && container->first_child != NULL) {\n    // if container->first_child is NULL, then the opening line\n    // of the list item was blank after the list marker; in this\n    // case, we are done with the list item.\n    cmark_parser_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                     false);\n    res = true;\n  }\n  return res;\n}\n\nstatic int matches(cmark_syntax_extension *self, cmark_parser *parser,\n                   unsigned char *input, int len,\n                   cmark_node *parent_container) {\n  return parse_node_item_prefix(parser, (const char*)input, parent_container);\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  return (node->type == CMARK_NODE_ITEM) ? 1 : 0;\n}\n\nstatic cmark_node *open_tasklist_item(cmark_syntax_extension *self,\n                                      int indented, cmark_parser *parser,\n                                      cmark_node *parent_container,\n                                      unsigned char *input, int len) {\n  cmark_node_type node_type = cmark_node_get_type(parent_container);\n  if (node_type != CMARK_NODE_ITEM) {\n    return NULL;\n  }\n\n  bufsize_t matched = scan_tasklist(input, len, 0);\n  if (!matched) {\n    return NULL;\n  }\n\n  cmark_node_set_syntax_extension(parent_container, self);\n  cmark_parser_advance_offset(parser, (char *)input, 3, false);\n\n  // Either an upper or lower case X means the task is completed.\n  parent_container->as.list.checked = (strstr((char*)input, \"[x]\") || strstr((char*)input, \"[X]\"));\n\n  return NULL;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->cr(renderer);\n    if (node->as.list.checked) {\n      renderer->out(renderer, node, \"- [x] \", false, LITERAL);\n    } else {\n      renderer->out(renderer, node, \"- [ ] \", false, LITERAL);\n    }\n    cmark_strbuf_puts(renderer->prefix, \"  \");\n  } else {\n    cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);\n    renderer->cr(renderer);\n  }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    cmark_html_render_cr(renderer->html);\n    cmark_strbuf_puts(renderer->html, \"<li\");\n    cmark_html_render_sourcepos(node, renderer->html, options);\n    cmark_strbuf_putc(renderer->html, '>');\n    if (node->as.list.checked) {\n      cmark_strbuf_puts(renderer->html, \"<input type=\\\"checkbox\\\" checked=\\\"\\\" disabled=\\\"\\\" /> \");\n    } else {\n      cmark_strbuf_puts(renderer->html, \"<input type=\\\"checkbox\\\" disabled=\\\"\\\" /> \");\n    }\n  } else {\n    cmark_strbuf_puts(renderer->html, \"</li>\\n\");\n  }\n}\n\nstatic const char *xml_attr(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  if (node->as.list.checked) {\n    return \" completed=\\\"true\\\"\";\n  } else {\n    return \" completed=\\\"false\\\"\";\n  }\n}\n\ncmark_syntax_extension *create_tasklist_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"tasklist\");\n\n  cmark_syntax_extension_set_match_block_func(ext, matches);\n  cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n  cmark_syntax_extension_set_open_block_func(ext, open_tasklist_item);\n  cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n  cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_plaintext_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_html_render_func(ext, html_render);\n  cmark_syntax_extension_set_xml_attr_func(ext, xml_attr);\n\n  return ext;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/extensions/tasklist.h",
    "content": "#ifndef TASKLIST_H\n#define TASKLIST_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\ncmark_syntax_extension *create_tasklist_extension(void);\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/arena.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n\nstatic struct arena_chunk {\n  size_t sz, used;\n  uint8_t push_point;\n  void *ptr;\n  struct arena_chunk *prev;\n} *A = NULL;\n\nstatic struct arena_chunk *alloc_arena_chunk(size_t sz, struct arena_chunk *prev) {\n  struct arena_chunk *c = (struct arena_chunk *)calloc(1, sizeof(*c));\n  if (!c)\n    abort();\n  c->sz = sz;\n  c->ptr = calloc(1, sz);\n  if (!c->ptr)\n    abort();\n  c->prev = prev;\n  return c;\n}\n\nvoid cmark_arena_push(void) {\n  if (!A)\n    return;\n  A->push_point = 1;\n  A = alloc_arena_chunk(10240, A);\n}\n\nint cmark_arena_pop(void) {\n  if (!A)\n    return 0;\n  while (A && !A->push_point) {\n    free(A->ptr);\n    struct arena_chunk *n = A->prev;\n    free(A);\n    A = n;\n  }\n  if (A)\n    A->push_point = 0;\n  return 1;\n}\n\nstatic void init_arena(void) {\n  A = alloc_arena_chunk(4 * 1048576, NULL);\n}\n\nvoid cmark_arena_reset(void) {\n  while (A) {\n    free(A->ptr);\n    struct arena_chunk *n = A->prev;\n    free(A);\n    A = n;\n  }\n}\n\nstatic void *arena_calloc(size_t nmem, size_t size) {\n  if (!A)\n    init_arena();\n\n  size_t sz = nmem * size + sizeof(size_t);\n\n  // Round allocation sizes to largest integer size to\n  // ensure returned memory is correctly aligned\n  const size_t align = sizeof(size_t) - 1;\n  sz = (sz + align) & ~align;\n\n  struct arena_chunk *chunk;\n  if (sz > A->sz) {\n    A->prev = chunk = alloc_arena_chunk(sz, A->prev);\n  } else if (sz > A->sz - A->used) {\n    A = chunk = alloc_arena_chunk(A->sz + A->sz / 2, A);\n  } else {\n    chunk = A;\n  }\n  void *ptr = (uint8_t *) chunk->ptr + chunk->used;\n  chunk->used += sz;\n  *((size_t *) ptr) = sz - sizeof(size_t);\n  return (uint8_t *) ptr + sizeof(size_t);\n}\n\nstatic void *arena_realloc(void *ptr, size_t size) {\n  if (!A)\n    init_arena();\n\n  void *new_ptr = arena_calloc(1, size);\n  if (ptr)\n    memcpy(new_ptr, ptr, ((size_t *) ptr)[-1]);\n  return new_ptr;\n}\n\nstatic void arena_free(void *ptr) {\n  (void) ptr;\n  /* no-op */\n}\n\ncmark_mem CMARK_ARENA_MEM_ALLOCATOR = {arena_calloc, arena_realloc, arena_free};\n\ncmark_mem *cmark_get_arena_mem_allocator(void) {\n  return &CMARK_ARENA_MEM_ALLOCATOR;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/blocks.c",
    "content": "/**\n * Block parsing implementation.\n *\n * For a high-level overview of the block parsing process,\n * see http://spec.commonmark.org/0.24/#phase-1-block-structure\n */\n\n#include <stdlib.h>\n#include <assert.h>\n#include <stdio.h>\n#include <limits.h>\n\n#include \"cmark_ctype.h\"\n#include \"syntax_extension.h\"\n#include \"config.h\"\n#include \"parser.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"references.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"inlines.h\"\n#include \"houdini.h\"\n#include \"buffer.h\"\n#include \"footnotes.h\"\n\n#define CODE_INDENT 4\n#define TAB_STOP 4\n\n/**\n * Very deeply nested lists can cause quadratic performance issues.\n * This constant is used in open_new_blocks() to limit the nesting\n * depth. It is unlikely that a non-contrived markdown document will\n * be nested this deeply.\n */\n#define MAX_LIST_DEPTH 100\n\n#ifndef MIN\n#define MIN(x, y) ((x < y) ? x : y)\n#endif\n\n#define peek_at(i, n) (i)->data[n]\n\nstatic bool S_last_line_blank(const cmark_node *node) {\n  return (node->flags & CMARK_NODE__LAST_LINE_BLANK) != 0;\n}\n\nstatic bool S_last_line_checked(const cmark_node *node) {\n  return (node->flags & CMARK_NODE__LAST_LINE_CHECKED) != 0;\n}\n\nstatic CMARK_INLINE cmark_node_type S_type(const cmark_node *node) {\n  return (cmark_node_type)node->type;\n}\n\nstatic void S_set_last_line_blank(cmark_node *node, bool is_blank) {\n  if (is_blank)\n    node->flags |= CMARK_NODE__LAST_LINE_BLANK;\n  else\n    node->flags &= ~CMARK_NODE__LAST_LINE_BLANK;\n}\n\nstatic void S_set_last_line_checked(cmark_node *node) {\n  node->flags |= CMARK_NODE__LAST_LINE_CHECKED;\n}\n\nstatic CMARK_INLINE bool S_is_line_end_char(char c) {\n  return (c == '\\n' || c == '\\r');\n}\n\nstatic CMARK_INLINE bool S_is_space_or_tab(char c) {\n  return (c == ' ' || c == '\\t');\n}\n\nstatic void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,\n                          size_t len, bool eof);\n\nstatic void S_process_line(cmark_parser *parser, const unsigned char *buffer,\n                           bufsize_t bytes);\n\nstatic cmark_node *make_block(cmark_mem *mem, cmark_node_type tag,\n                              int start_line, int start_column) {\n  cmark_node *e;\n\n  e = (cmark_node *)mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(mem, &e->content, 32);\n  e->type = (uint16_t)tag;\n  e->flags = CMARK_NODE__OPEN;\n  e->start_line = start_line;\n  e->start_column = start_column;\n  e->end_line = start_line;\n\n  return e;\n}\n\n// Create a root document node.\nstatic cmark_node *make_document(cmark_mem *mem) {\n  cmark_node *e = make_block(mem, CMARK_NODE_DOCUMENT, 1, 1);\n  return e;\n}\n\nint cmark_parser_attach_syntax_extension(cmark_parser *parser,\n                                         cmark_syntax_extension *extension) {\n  parser->syntax_extensions = cmark_llist_append(parser->mem, parser->syntax_extensions, extension);\n  if (extension->match_inline || extension->insert_inline_from_delim) {\n    parser->inline_syntax_extensions = cmark_llist_append(\n      parser->mem, parser->inline_syntax_extensions, extension);\n  }\n\n  return 1;\n}\n\nstatic void cmark_parser_dispose(cmark_parser *parser) {\n  if (parser->root)\n    cmark_node_free(parser->root);\n\n  if (parser->refmap)\n    cmark_map_free(parser->refmap);\n}\n\nstatic void cmark_parser_reset(cmark_parser *parser) {\n  cmark_llist *saved_exts = parser->syntax_extensions;\n  cmark_llist *saved_inline_exts = parser->inline_syntax_extensions;\n  int saved_options = parser->options;\n  cmark_mem *saved_mem = parser->mem;\n\n  cmark_parser_dispose(parser);\n\n  memset(parser, 0, sizeof(cmark_parser));\n  parser->mem = saved_mem;\n\n  cmark_strbuf_init(parser->mem, &parser->curline, 256);\n  cmark_strbuf_init(parser->mem, &parser->linebuf, 0);\n\n  cmark_node *document = make_document(parser->mem);\n\n  parser->refmap = cmark_reference_map_new(parser->mem);\n  parser->root = document;\n  parser->current = document;\n\n  parser->syntax_extensions = saved_exts;\n  parser->inline_syntax_extensions = saved_inline_exts;\n  parser->options = saved_options;\n}\n\ncmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem) {\n  cmark_parser *parser = (cmark_parser *)mem->calloc(1, sizeof(cmark_parser));\n  parser->mem = mem;\n  parser->options = options;\n  cmark_parser_reset(parser);\n  return parser;\n}\n\ncmark_parser *cmark_parser_new(int options) {\n  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n  return cmark_parser_new_with_mem(options, &CMARK_DEFAULT_MEM_ALLOCATOR);\n}\n\nvoid cmark_parser_free(cmark_parser *parser) {\n  cmark_mem *mem = parser->mem;\n  cmark_parser_dispose(parser);\n  cmark_strbuf_free(&parser->curline);\n  cmark_strbuf_free(&parser->linebuf);\n  cmark_llist_free(parser->mem, parser->syntax_extensions);\n  cmark_llist_free(parser->mem, parser->inline_syntax_extensions);\n  mem->free(parser);\n}\n\nstatic cmark_node *finalize(cmark_parser *parser, cmark_node *b);\n\n// Returns true if line has only space characters, else false.\nstatic bool is_blank(cmark_strbuf *s, bufsize_t offset) {\n  while (offset < s->size) {\n    switch (s->ptr[offset]) {\n    case '\\r':\n    case '\\n':\n      return true;\n    case ' ':\n      offset++;\n      break;\n    case '\\t':\n      offset++;\n      break;\n    default:\n      return false;\n    }\n  }\n\n  return true;\n}\n\nstatic CMARK_INLINE bool accepts_lines(cmark_node_type block_type) {\n  return (block_type == CMARK_NODE_PARAGRAPH ||\n          block_type == CMARK_NODE_HEADING ||\n          block_type == CMARK_NODE_CODE_BLOCK);\n}\n\nstatic CMARK_INLINE bool contains_inlines(cmark_node *node) {\n  if (node->extension && node->extension->contains_inlines_func) {\n    return node->extension->contains_inlines_func(node->extension, node) != 0;\n  }\n\n  return (node->type == CMARK_NODE_PARAGRAPH ||\n          node->type == CMARK_NODE_HEADING);\n}\n\nstatic void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {\n  int chars_to_tab;\n  int i;\n  assert(node->flags & CMARK_NODE__OPEN);\n  if (parser->partially_consumed_tab) {\n    parser->offset += 1; // skip over tab\n    // add space characters:\n    chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n    for (i = 0; i < chars_to_tab; i++) {\n      cmark_strbuf_putc(&node->content, ' ');\n    }\n  }\n  cmark_strbuf_put(&node->content, ch->data + parser->offset,\n                   ch->len - parser->offset);\n}\n\nstatic void remove_trailing_blank_lines(cmark_strbuf *ln) {\n  bufsize_t i;\n  unsigned char c;\n\n  for (i = ln->size - 1; i >= 0; --i) {\n    c = ln->ptr[i];\n\n    if (c != ' ' && c != '\\t' && !S_is_line_end_char(c))\n      break;\n  }\n\n  if (i < 0) {\n    cmark_strbuf_clear(ln);\n    return;\n  }\n\n  for (; i < ln->size; ++i) {\n    c = ln->ptr[i];\n\n    if (!S_is_line_end_char(c))\n      continue;\n\n    cmark_strbuf_truncate(ln, i);\n    break;\n  }\n}\n\n// Check to see if a node ends with a blank line, descending\n// if needed into lists and sublists.\nstatic bool S_ends_with_blank_line(cmark_node *node) {\n  if (S_last_line_checked(node)) {\n    return(S_last_line_blank(node));\n  } else if ((S_type(node) == CMARK_NODE_LIST ||\n              S_type(node) == CMARK_NODE_ITEM) && node->last_child) {\n    S_set_last_line_checked(node);\n    return(S_ends_with_blank_line(node->last_child));\n  } else {\n    S_set_last_line_checked(node);\n    return (S_last_line_blank(node));\n  }\n}\n\n// returns true if content remains after link defs are resolved.\nstatic bool resolve_reference_link_definitions(\n\t\tcmark_parser *parser,\n                cmark_node *b) {\n  bufsize_t pos;\n  cmark_strbuf *node_content = &b->content;\n  cmark_chunk chunk = {node_content->ptr, node_content->size, 0};\n  while (chunk.len && chunk.data[0] == '[' &&\n         (pos = cmark_parse_reference_inline(parser->mem, &chunk,\n\t\t\t\t\t     parser->refmap))) {\n\n    chunk.data += pos;\n    chunk.len -= pos;\n  }\n  cmark_strbuf_drop(node_content, (node_content->size - chunk.len));\n  return !is_blank(&b->content, 0);\n}\n\nstatic cmark_node *finalize(cmark_parser *parser, cmark_node *b) {\n  bufsize_t pos;\n  cmark_node *item;\n  cmark_node *subitem;\n  cmark_node *parent;\n  bool has_content;\n\n  parent = b->parent;\n  assert(b->flags &\n         CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks\n  b->flags &= ~CMARK_NODE__OPEN;\n\n  if (parser->curline.size == 0) {\n    // end of input - line number has not been incremented\n    b->end_line = parser->line_number;\n    b->end_column = parser->last_line_length;\n  } else if (S_type(b) == CMARK_NODE_DOCUMENT ||\n             (S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) ||\n             (S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext)) {\n    b->end_line = parser->line_number;\n    b->end_column = parser->curline.size;\n    if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\\n')\n      b->end_column -= 1;\n    if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\\r')\n      b->end_column -= 1;\n  } else {\n    b->end_line = parser->line_number - 1;\n    b->end_column = parser->last_line_length;\n  }\n\n  cmark_strbuf *node_content = &b->content;\n\n  switch (S_type(b)) {\n  case CMARK_NODE_PARAGRAPH:\n  {\n    has_content = resolve_reference_link_definitions(parser, b);\n    if (!has_content) {\n      // remove blank node (former reference def)\n      cmark_node_free(b);\n    }\n    break;\n  }\n\n  case CMARK_NODE_CODE_BLOCK:\n    if (!b->as.code.fenced) { // indented code\n      remove_trailing_blank_lines(node_content);\n      cmark_strbuf_putc(node_content, '\\n');\n    } else {\n      // first line of contents becomes info\n      for (pos = 0; pos < node_content->size; ++pos) {\n        if (S_is_line_end_char(node_content->ptr[pos]))\n          break;\n      }\n      assert(pos < node_content->size);\n\n      cmark_strbuf tmp = CMARK_BUF_INIT(parser->mem);\n      houdini_unescape_html_f(&tmp, node_content->ptr, pos);\n      cmark_strbuf_trim(&tmp);\n      cmark_strbuf_unescape(&tmp);\n      b->as.code.info = cmark_chunk_buf_detach(&tmp);\n\n      if (node_content->ptr[pos] == '\\r')\n        pos += 1;\n      if (node_content->ptr[pos] == '\\n')\n        pos += 1;\n      cmark_strbuf_drop(node_content, pos);\n    }\n    b->as.code.literal = cmark_chunk_buf_detach(node_content);\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    b->as.literal = cmark_chunk_buf_detach(node_content);\n    break;\n\n  case CMARK_NODE_LIST:      // determine tight/loose status\n    b->as.list.tight = true; // tight by default\n    item = b->first_child;\n\n    while (item) {\n      // check for non-final non-empty list item ending with blank line:\n      if (S_last_line_blank(item) && item->next) {\n        b->as.list.tight = false;\n        break;\n      }\n      // recurse into children of list item, to see if there are\n      // spaces between them:\n      subitem = item->first_child;\n      while (subitem) {\n        if ((item->next || subitem->next) &&\n            S_ends_with_blank_line(subitem)) {\n          b->as.list.tight = false;\n          break;\n        }\n        subitem = subitem->next;\n      }\n      if (!(b->as.list.tight)) {\n        break;\n      }\n      item = item->next;\n    }\n\n    break;\n\n  default:\n    break;\n  }\n\n  return parent;\n}\n\n// Add a node as child of another.  Return pointer to child.\nstatic cmark_node *add_child(cmark_parser *parser, cmark_node *parent,\n                             cmark_node_type block_type, int start_column) {\n  assert(parent);\n\n  // if 'parent' isn't the kind of node that can accept this child,\n  // then back up til we hit a node that can.\n  while (!cmark_node_can_contain_type(parent, block_type)) {\n    parent = finalize(parser, parent);\n  }\n\n  cmark_node *child =\n      make_block(parser->mem, block_type, parser->line_number, start_column);\n  child->parent = parent;\n\n  if (parent->last_child) {\n    parent->last_child->next = child;\n    child->prev = parent->last_child;\n  } else {\n    parent->first_child = child;\n    child->prev = NULL;\n  }\n  parent->last_child = child;\n  return child;\n}\n\nvoid cmark_manage_extensions_special_characters(cmark_parser *parser, int add) {\n  cmark_llist *tmp_ext;\n\n  for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;\n    cmark_llist *tmp_char;\n    for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {\n      unsigned char c = (unsigned char)(size_t)tmp_char->data;\n      if (add)\n        cmark_inlines_add_special_character(c, ext->emphasis);\n      else\n        cmark_inlines_remove_special_character(c, ext->emphasis);\n    }\n  }\n}\n\n// Walk through node and all children, recursively, parsing\n// string content into inline content where appropriate.\nstatic void process_inlines(cmark_parser *parser,\n                            cmark_map *refmap, int options) {\n  cmark_iter *iter = cmark_iter_new(parser->root);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n\n  cmark_manage_extensions_special_characters(parser, true);\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER) {\n      if (contains_inlines(cur)) {\n        cmark_parse_inlines(parser, cur, refmap, options);\n      }\n    }\n  }\n\n  cmark_manage_extensions_special_characters(parser, false);\n\n  cmark_iter_free(iter);\n}\n\nstatic int sort_footnote_by_ix(const void *_a, const void *_b) {\n  cmark_footnote *a = *(cmark_footnote **)_a;\n  cmark_footnote *b = *(cmark_footnote **)_b;\n  return (int)a->ix - (int)b->ix;\n}\n\nstatic void process_footnotes(cmark_parser *parser) {\n  // * Collect definitions in a map.\n  // * Iterate the references in the document in order, assigning indices to\n  //   definitions in the order they're seen.\n  // * Write out the footnotes at the bottom of the document in index order.\n\n  cmark_map *map = cmark_footnote_map_new(parser->mem);\n\n  cmark_iter *iter = cmark_iter_new(parser->root);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_DEFINITION) {\n      cmark_footnote_create(map, cur);\n    }\n  }\n\n  cmark_iter_free(iter);\n  iter = cmark_iter_new(parser->root);\n  unsigned int ix = 0;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_REFERENCE) {\n      cmark_footnote *footnote = (cmark_footnote *)cmark_map_lookup(map, &cur->as.literal);\n      if (footnote) {\n        if (!footnote->ix)\n          footnote->ix = ++ix;\n\n        // store a reference to this footnote reference's footnote definition\n        // this is used by renderers when generating label ids\n        cur->parent_footnote_def = footnote->node;\n\n        // keep track of a) count of how many times this footnote def has been\n        // referenced, and b) which reference index this footnote ref is at.\n        // this is used by renderers when generating links and backreferences.\n        cur->footnote.ref_ix = ++footnote->node->footnote.def_count;\n\n        char n[32];\n        snprintf(n, sizeof(n), \"%d\", footnote->ix);\n        cmark_chunk_free(parser->mem, &cur->as.literal);\n        cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);\n        cmark_strbuf_puts(&buf, n);\n\n        cur->as.literal = cmark_chunk_buf_detach(&buf);\n      } else {\n        cmark_node *text = (cmark_node *)parser->mem->calloc(1, sizeof(*text));\n        cmark_strbuf_init(parser->mem, &text->content, 0);\n        text->type = (uint16_t) CMARK_NODE_TEXT;\n\n        cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);\n        cmark_strbuf_puts(&buf, \"[^\");\n        cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);\n        cmark_strbuf_putc(&buf, ']');\n\n        text->as.literal = cmark_chunk_buf_detach(&buf);\n        cmark_node_insert_after(cur, text);\n        cmark_node_free(cur);\n      }\n    }\n  }\n\n  cmark_iter_free(iter);\n\n  if (map->sorted) {\n    qsort(map->sorted, map->size, sizeof(cmark_map_entry *), sort_footnote_by_ix);\n    for (unsigned int i = 0; i < map->size; ++i) {\n      cmark_footnote *footnote = (cmark_footnote *)map->sorted[i];\n      if (!footnote->ix) {\n        cmark_node_unlink(footnote->node);\n        continue;\n      }\n      cmark_node_append_child(parser->root, footnote->node);\n      footnote->node = NULL;\n    }\n  }\n\n  cmark_unlink_footnotes_map(map);\n  cmark_map_free(map);\n}\n\n// Attempts to parse a list item marker (bullet or enumerated).\n// On success, returns length of the marker, and populates\n// data with the details.  On failure, returns 0.\nstatic bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input,\n                                   bufsize_t pos, bool interrupts_paragraph,\n                                   cmark_list **dataptr) {\n  unsigned char c;\n  bufsize_t startpos;\n  cmark_list *data;\n  bufsize_t i;\n\n  startpos = pos;\n  c = peek_at(input, pos);\n\n  if (c == '*' || c == '-' || c == '+') {\n    pos++;\n    if (!cmark_isspace(peek_at(input, pos))) {\n      return 0;\n    }\n\n    if (interrupts_paragraph) {\n      i = pos;\n      // require non-blank content after list marker:\n      while (S_is_space_or_tab(peek_at(input, i))) {\n        i++;\n      }\n      if (peek_at(input, i) == '\\n') {\n        return 0;\n      }\n    }\n\n    data = (cmark_list *)mem->calloc(1, sizeof(*data));\n    data->marker_offset = 0; // will be adjusted later\n    data->list_type = CMARK_BULLET_LIST;\n    data->bullet_char = c;\n    data->start = 0;\n    data->delimiter = CMARK_NO_DELIM;\n    data->tight = false;\n  } else if (cmark_isdigit(c)) {\n    int start = 0;\n    int digits = 0;\n\n    do {\n      start = (10 * start) + (peek_at(input, pos) - '0');\n      pos++;\n      digits++;\n      // We limit to 9 digits to avoid overflow,\n      // assuming max int is 2^31 - 1\n      // This also seems to be the limit for 'start' in some browsers.\n    } while (digits < 9 && cmark_isdigit(peek_at(input, pos)));\n\n    if (interrupts_paragraph && start != 1) {\n      return 0;\n    }\n    c = peek_at(input, pos);\n    if (c == '.' || c == ')') {\n      pos++;\n      if (!cmark_isspace(peek_at(input, pos))) {\n        return 0;\n      }\n      if (interrupts_paragraph) {\n        // require non-blank content after list marker:\n        i = pos;\n        while (S_is_space_or_tab(peek_at(input, i))) {\n          i++;\n        }\n        if (S_is_line_end_char(peek_at(input, i))) {\n          return 0;\n        }\n      }\n\n      data = (cmark_list *)mem->calloc(1, sizeof(*data));\n      data->marker_offset = 0; // will be adjusted later\n      data->list_type = CMARK_ORDERED_LIST;\n      data->bullet_char = 0;\n      data->start = start;\n      data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM);\n      data->tight = false;\n    } else {\n      return 0;\n    }\n  } else {\n    return 0;\n  }\n\n  *dataptr = data;\n  return (pos - startpos);\n}\n\n// Return 1 if list item belongs in list, else 0.\nstatic int lists_match(cmark_list *list_data, cmark_list *item_data) {\n  return (list_data->list_type == item_data->list_type &&\n          list_data->delimiter == item_data->delimiter &&\n          // list_data->marker_offset == item_data.marker_offset &&\n          list_data->bullet_char == item_data->bullet_char);\n}\n\nstatic cmark_node *finalize_document(cmark_parser *parser) {\n  while (parser->current != parser->root) {\n    parser->current = finalize(parser, parser->current);\n  }\n\n  finalize(parser, parser->root);\n\n  // Limit total size of extra content created from reference links to\n  // document size to avoid superlinear growth. Always allow 100KB.\n  if (parser->total_size > 100000)\n    parser->refmap->max_ref_size = parser->total_size;\n  else\n    parser->refmap->max_ref_size = 100000;\n\n  process_inlines(parser, parser->refmap, parser->options);\n  if (parser->options & CMARK_OPT_FOOTNOTES)\n    process_footnotes(parser);\n\n  return parser->root;\n}\n\ncmark_node *cmark_parse_file(FILE *f, int options) {\n  unsigned char buffer[4096];\n  cmark_parser *parser = cmark_parser_new(options);\n  size_t bytes;\n  cmark_node *document;\n\n  while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) {\n    bool eof = bytes < sizeof(buffer);\n    S_parser_feed(parser, buffer, bytes, eof);\n    if (eof) {\n      break;\n    }\n  }\n\n  document = cmark_parser_finish(parser);\n  cmark_parser_free(parser);\n  return document;\n}\n\ncmark_node *cmark_parse_document(const char *buffer, size_t len, int options) {\n  cmark_parser *parser = cmark_parser_new(options);\n  cmark_node *document;\n\n  S_parser_feed(parser, (const unsigned char *)buffer, len, true);\n\n  document = cmark_parser_finish(parser);\n  cmark_parser_free(parser);\n  return document;\n}\n\nvoid cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {\n  S_parser_feed(parser, (const unsigned char *)buffer, len, false);\n}\n\nvoid cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len) {\n  cmark_strbuf saved_linebuf;\n\n  cmark_strbuf_init(parser->mem, &saved_linebuf, 0);\n  cmark_strbuf_puts(&saved_linebuf, cmark_strbuf_cstr(&parser->linebuf));\n  cmark_strbuf_clear(&parser->linebuf);\n\n  S_parser_feed(parser, (const unsigned char *)buffer, len, true);\n\n  cmark_strbuf_sets(&parser->linebuf, cmark_strbuf_cstr(&saved_linebuf));\n  cmark_strbuf_free(&saved_linebuf);\n}\n\nstatic void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,\n                          size_t len, bool eof) {\n  const unsigned char *end = buffer + len;\n  static const uint8_t repl[] = {239, 191, 189};\n\n  if (len > UINT_MAX - parser->total_size)\n    parser->total_size = UINT_MAX;\n  else\n    parser->total_size += len;\n\n  if (parser->last_buffer_ended_with_cr && *buffer == '\\n') {\n    // skip NL if last buffer ended with CR ; see #117\n    buffer++;\n  }\n  parser->last_buffer_ended_with_cr = false;\n  while (buffer < end) {\n    const unsigned char *eol;\n    bufsize_t chunk_len;\n    bool process = false;\n    for (eol = buffer; eol < end; ++eol) {\n      if (S_is_line_end_char(*eol)) {\n        process = true;\n        break;\n      }\n      if (*eol == '\\0' && eol < end) {\n        break;\n      }\n    }\n    if (eol >= end && eof) {\n      process = true;\n    }\n\n    chunk_len = (bufsize_t)(eol - buffer);\n    if (process) {\n      if (parser->linebuf.size > 0) {\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n        S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);\n        cmark_strbuf_clear(&parser->linebuf);\n      } else {\n        S_process_line(parser, buffer, chunk_len);\n      }\n    } else {\n      if (eol < end && *eol == '\\0') {\n        // omit NULL byte\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n        // add replacement character\n        cmark_strbuf_put(&parser->linebuf, repl, 3);\n      } else {\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n      }\n    }\n\n    buffer += chunk_len;\n    if (buffer < end) {\n      if (*buffer == '\\0') {\n        // skip over NULL\n        buffer++;\n      } else {\n        // skip over line ending characters\n        if (*buffer == '\\r') {\n          buffer++;\n          if (buffer == end)\n            parser->last_buffer_ended_with_cr = true;\n        }\n        if (buffer < end && *buffer == '\\n')\n          buffer++;\n      }\n    }\n  }\n}\n\nstatic void chop_trailing_hashtags(cmark_chunk *ch) {\n  bufsize_t n, orig_n;\n\n  cmark_chunk_rtrim(ch);\n  orig_n = n = ch->len - 1;\n\n  // if string ends in space followed by #s, remove these:\n  while (n >= 0 && peek_at(ch, n) == '#')\n    n--;\n\n  // Check for a space before the final #s:\n  if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) {\n    ch->len = n;\n    cmark_chunk_rtrim(ch);\n  }\n}\n\n// Check for thematic break.  On failure, return 0 and update\n// thematic_break_kill_pos with the index at which the\n// parse fails.  On success, return length of match.\n// \"...three or more hyphens, asterisks,\n// or underscores on a line by themselves. If you wish, you may use\n// spaces between the hyphens or asterisks.\"\nstatic int S_scan_thematic_break(cmark_parser *parser, cmark_chunk *input,\n                                 bufsize_t offset) {\n  bufsize_t i;\n  char c;\n  char nextc = '\\0';\n  int count;\n  i = offset;\n  c = peek_at(input, i);\n  if (!(c == '*' || c == '_' || c == '-')) {\n    parser->thematic_break_kill_pos = i;\n    return 0;\n  }\n  count = 1;\n  while ((nextc = peek_at(input, ++i))) {\n    if (nextc == c) {\n      count++;\n    } else if (nextc != ' ' && nextc != '\\t') {\n      break;\n    }\n  }\n  if (count >= 3 && (nextc == '\\r' || nextc == '\\n')) {\n    return (i - offset) + 1;\n  } else {\n    parser->thematic_break_kill_pos = i;\n    return 0;\n  }\n}\n\n// Find first nonspace character from current offset, setting\n// parser->first_nonspace, parser->first_nonspace_column,\n// parser->indent, and parser->blank. Does not advance parser->offset.\nstatic void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {\n  char c;\n  int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n\n  if (parser->first_nonspace <= parser->offset) {\n    parser->first_nonspace = parser->offset;\n    parser->first_nonspace_column = parser->column;\n    while ((c = peek_at(input, parser->first_nonspace))) {\n      if (c == ' ') {\n        parser->first_nonspace += 1;\n        parser->first_nonspace_column += 1;\n        chars_to_tab = chars_to_tab - 1;\n        if (chars_to_tab == 0) {\n          chars_to_tab = TAB_STOP;\n        }\n      } else if (c == '\\t') {\n        parser->first_nonspace += 1;\n        parser->first_nonspace_column += chars_to_tab;\n        chars_to_tab = TAB_STOP;\n      } else {\n        break;\n      }\n    }\n  }\n\n  parser->indent = parser->first_nonspace_column - parser->column;\n  parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));\n}\n\n// Advance parser->offset and parser->column.  parser->offset is the\n// byte position in input; parser->column is a virtual column number\n// that takes into account tabs. (Multibyte characters are not taken\n// into account, because the Markdown line prefixes we are interested in\n// analyzing are entirely ASCII.)  The count parameter indicates\n// how far to advance the offset.  If columns is true, then count\n// indicates a number of columns; otherwise, a number of bytes.\n// If advancing a certain number of columns partially consumes\n// a tab character, parser->partially_consumed_tab is set to true.\nstatic void S_advance_offset(cmark_parser *parser, cmark_chunk *input,\n                             bufsize_t count, bool columns) {\n  char c;\n  int chars_to_tab;\n  int chars_to_advance;\n  while (count > 0 && (c = peek_at(input, parser->offset))) {\n    if (c == '\\t') {\n      chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n      if (columns) {\n        parser->partially_consumed_tab = chars_to_tab > count;\n        chars_to_advance = MIN(count, chars_to_tab);\n        parser->column += chars_to_advance;\n        parser->offset += (parser->partially_consumed_tab ? 0 : 1);\n        count -= chars_to_advance;\n      } else {\n        parser->partially_consumed_tab = false;\n        parser->column += chars_to_tab;\n        parser->offset += 1;\n        count -= 1;\n      }\n    } else {\n      parser->partially_consumed_tab = false;\n      parser->offset += 1;\n      parser->column += 1; // assume ascii; block starts are ascii\n      count -= 1;\n    }\n  }\n}\n\nstatic bool S_last_child_is_open(cmark_node *container) {\n  return container->last_child &&\n         (container->last_child->flags & CMARK_NODE__OPEN);\n}\n\nstatic bool parse_block_quote_prefix(cmark_parser *parser, cmark_chunk *input) {\n  bool res = false;\n  bufsize_t matched = 0;\n\n  matched =\n      parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>';\n  if (matched) {\n\n    S_advance_offset(parser, input, parser->indent + 1, true);\n\n    if (S_is_space_or_tab(peek_at(input, parser->offset))) {\n      S_advance_offset(parser, input, 1, true);\n    }\n\n    res = true;\n  }\n  return res;\n}\n\nstatic bool parse_footnote_definition_block_prefix(cmark_parser *parser, cmark_chunk *input,\n                                                   cmark_node *container) {\n  if (parser->indent >= 4) {\n    S_advance_offset(parser, input, 4, true);\n    return true;\n  } else if (input->len > 0 && (input->data[0] == '\\n' || (input->data[0] == '\\r' && input->data[1] == '\\n'))) {\n    return true;\n  }\n\n  return false;\n}\n\nstatic bool parse_node_item_prefix(cmark_parser *parser, cmark_chunk *input,\n                                   cmark_node *container) {\n  bool res = false;\n\n  if (parser->indent >=\n      container->as.list.marker_offset + container->as.list.padding) {\n    S_advance_offset(parser, input, container->as.list.marker_offset +\n                                        container->as.list.padding,\n                     true);\n    res = true;\n  } else if (parser->blank && container->first_child != NULL) {\n    // if container->first_child is NULL, then the opening line\n    // of the list item was blank after the list marker; in this\n    // case, we are done with the list item.\n    S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                     false);\n    res = true;\n  }\n  return res;\n}\n\nstatic bool parse_code_block_prefix(cmark_parser *parser, cmark_chunk *input,\n                                    cmark_node *container,\n                                    bool *should_continue) {\n  bool res = false;\n\n  if (!container->as.code.fenced) { // indented\n    if (parser->indent >= CODE_INDENT) {\n      S_advance_offset(parser, input, CODE_INDENT, true);\n      res = true;\n    } else if (parser->blank) {\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      res = true;\n    }\n  } else { // fenced\n    bufsize_t matched = 0;\n\n    if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) ==\n                                container->as.code.fence_char)) {\n      matched = scan_close_code_fence(input, parser->first_nonspace);\n    }\n\n    if (matched >= container->as.code.fence_length) {\n      // closing fence - and since we're at\n      // the end of a line, we can stop processing it:\n      *should_continue = false;\n      S_advance_offset(parser, input, matched, false);\n      parser->current = finalize(parser, container);\n    } else {\n      // skip opt. spaces of fence parser->offset\n      int i = container->as.code.fence_offset;\n\n      while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n        i--;\n      }\n      res = true;\n    }\n  }\n\n  return res;\n}\n\nstatic bool parse_html_block_prefix(cmark_parser *parser,\n                                    cmark_node *container) {\n  bool res = false;\n  int html_block_type = container->as.html_block_type;\n\n  assert(html_block_type >= 1 && html_block_type <= 7);\n  switch (html_block_type) {\n  case 1:\n  case 2:\n  case 3:\n  case 4:\n  case 5:\n    // these types of blocks can accept blanks\n    res = true;\n    break;\n  case 6:\n  case 7:\n    res = !parser->blank;\n    break;\n  }\n\n  return res;\n}\n\nstatic bool parse_extension_block(cmark_parser *parser,\n                                  cmark_node *container,\n                                  cmark_chunk *input)\n{\n  bool res = false;\n\n  if (container->extension->last_block_matches) {\n    if (container->extension->last_block_matches(\n        container->extension, parser, input->data, input->len, container))\n      res = true;\n  }\n\n  return res;\n}\n\n/**\n * For each containing node, try to parse the associated line start.\n *\n * Will not close unmatched blocks, as we may have a lazy continuation\n * line -> http://spec.commonmark.org/0.24/#lazy-continuation-line\n *\n * Returns: The last matching node, or NULL\n */\nstatic cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,\n                                     bool *all_matched) {\n  bool should_continue = true;\n  *all_matched = false;\n  cmark_node *container = parser->root;\n  cmark_node_type cont_type;\n\n  while (S_last_child_is_open(container)) {\n    container = container->last_child;\n    cont_type = S_type(container);\n\n    S_find_first_nonspace(parser, input);\n\n    if (container->extension) {\n      if (!parse_extension_block(parser, container, input))\n        goto done;\n      continue;\n    }\n\n    switch (cont_type) {\n    case CMARK_NODE_BLOCK_QUOTE:\n      if (!parse_block_quote_prefix(parser, input))\n        goto done;\n      break;\n    case CMARK_NODE_ITEM:\n      if (!parse_node_item_prefix(parser, input, container))\n        goto done;\n      break;\n    case CMARK_NODE_CODE_BLOCK:\n      if (!parse_code_block_prefix(parser, input, container, &should_continue))\n        goto done;\n      break;\n    case CMARK_NODE_HEADING:\n      // a heading can never contain more than one line\n      goto done;\n    case CMARK_NODE_HTML_BLOCK:\n      if (!parse_html_block_prefix(parser, container))\n        goto done;\n      break;\n    case CMARK_NODE_PARAGRAPH:\n      if (parser->blank)\n        goto done;\n      break;\n\t\tcase CMARK_NODE_FOOTNOTE_DEFINITION:\n\t\t\tif (!parse_footnote_definition_block_prefix(parser, input, container))\n\t\t\t\tgoto done;\n\t\t\tbreak;\n    default:\n      break;\n    }\n  }\n\n  *all_matched = true;\n\ndone:\n  if (!*all_matched) {\n    container = container->parent; // back up to last matching node\n  }\n\n  if (!should_continue) {\n    container = NULL;\n  }\n\n  return container;\n}\n\nstatic void open_new_blocks(cmark_parser *parser, cmark_node **container,\n                            cmark_chunk *input, bool all_matched) {\n  bool indented;\n  cmark_list *data = NULL;\n  bool maybe_lazy = S_type(parser->current) == CMARK_NODE_PARAGRAPH;\n  cmark_node_type cont_type = S_type(*container);\n  bufsize_t matched = 0;\n  int lev = 0;\n  bool save_partially_consumed_tab;\n  bool has_content;\n  int save_offset;\n  int save_column;\n  size_t depth = 0;\n\n  while (cont_type != CMARK_NODE_CODE_BLOCK &&\n         cont_type != CMARK_NODE_HTML_BLOCK) {\n    depth++;\n    S_find_first_nonspace(parser, input);\n    indented = parser->indent >= CODE_INDENT;\n\n    if (!indented && peek_at(input, parser->first_nonspace) == '>') {\n\n      bufsize_t blockquote_startpos = parser->first_nonspace;\n\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + 1 - parser->offset, false);\n      // optional following character\n      if (S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n      }\n      *container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE,\n                             blockquote_startpos + 1);\n\n    } else if (!indented && (matched = scan_atx_heading_start(\n                                 input, parser->first_nonspace))) {\n      bufsize_t hashpos;\n      int level = 0;\n      bufsize_t heading_startpos = parser->first_nonspace;\n\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n      *container = add_child(parser, *container, CMARK_NODE_HEADING,\n                             heading_startpos + 1);\n\n      hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace);\n\n      while (peek_at(input, hashpos) == '#') {\n        level++;\n        hashpos++;\n      }\n\n      (*container)->as.heading.level = level;\n      (*container)->as.heading.setext = false;\n      (*container)->internal_offset = matched;\n\n    } else if (!indented && (matched = scan_open_code_fence(\n                                 input, parser->first_nonspace))) {\n      *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,\n                             parser->first_nonspace + 1);\n      (*container)->as.code.fenced = true;\n      (*container)->as.code.fence_char = peek_at(input, parser->first_nonspace);\n      (*container)->as.code.fence_length = (matched > 255) ? 255 : (uint8_t)matched;\n      (*container)->as.code.fence_offset =\n          (int8_t)(parser->first_nonspace - parser->offset);\n      (*container)->as.code.info = cmark_chunk_literal(\"\");\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n\n    } else if (!indented && ((matched = scan_html_block_start(\n                                  input, parser->first_nonspace)) ||\n                             (cont_type != CMARK_NODE_PARAGRAPH &&\n                              (matched = scan_html_block_start_7(\n                                   input, parser->first_nonspace))))) {\n      *container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK,\n                             parser->first_nonspace + 1);\n      (*container)->as.html_block_type = matched;\n      // note, we don't adjust parser->offset because the tag is part of the\n      // text\n    } else if (!indented && cont_type == CMARK_NODE_PARAGRAPH &&\n               (lev =\n                    scan_setext_heading_line(input, parser->first_nonspace))) {\n      // finalize paragraph, resolving reference links\n      has_content = resolve_reference_link_definitions(parser, *container);\n\n      if (has_content) {\n\n        (*container)->type = (uint16_t)CMARK_NODE_HEADING;\n        (*container)->as.heading.level = lev;\n        (*container)->as.heading.setext = true;\n        S_advance_offset(parser, input, input->len - 1 - parser->offset, false);\n      }\n    } else if (!indented &&\n               !(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) &&\n\t       (parser->thematic_break_kill_pos <= parser->first_nonspace) &&\n               (matched = S_scan_thematic_break(parser, input, parser->first_nonspace))) {\n      // it's only now that we know the line is not part of a setext heading:\n      *container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK,\n                             parser->first_nonspace + 1);\n      S_advance_offset(parser, input, input->len - 1 - parser->offset, false);\n    } else if (!indented &&\n               (parser->options & CMARK_OPT_FOOTNOTES) &&\n               depth < MAX_LIST_DEPTH &&\n               (matched = scan_footnote_definition(input, parser->first_nonspace))) {\n      cmark_chunk c = cmark_chunk_dup(input, parser->first_nonspace + 2, matched - 2);\n\n      while (c.data[c.len - 1] != ']')\n        --c.len;\n      --c.len;\n\n      cmark_chunk_to_cstr(parser->mem, &c);\n\n      S_advance_offset(parser, input, parser->first_nonspace + matched - parser->offset, false);\n      *container = add_child(parser, *container, CMARK_NODE_FOOTNOTE_DEFINITION, parser->first_nonspace + matched + 1);\n      (*container)->as.literal = c;\n\n      (*container)->internal_offset = matched;\n    } else if ((!indented || cont_type == CMARK_NODE_LIST) &&\n\t       parser->indent < 4 &&\n               depth < MAX_LIST_DEPTH &&\n               (matched = parse_list_marker(\n                    parser->mem, input, parser->first_nonspace,\n                    (*container)->type == CMARK_NODE_PARAGRAPH, &data))) {\n\n      // Note that we can have new list items starting with >= 4\n      // spaces indent, as long as the list container is still open.\n      int i = 0;\n\n      // compute padding:\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n\n      save_partially_consumed_tab = parser->partially_consumed_tab;\n      save_offset = parser->offset;\n      save_column = parser->column;\n\n      while (parser->column - save_column <= 5 &&\n             S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n      }\n\n      i = parser->column - save_column;\n      if (i >= 5 || i < 1 ||\n          // only spaces after list marker:\n          S_is_line_end_char(peek_at(input, parser->offset))) {\n        data->padding = matched + 1;\n        parser->offset = save_offset;\n        parser->column = save_column;\n        parser->partially_consumed_tab = save_partially_consumed_tab;\n        if (i > 0) {\n          S_advance_offset(parser, input, 1, true);\n        }\n      } else {\n        data->padding = matched + i;\n      }\n\n      // check container; if it's a list, see if this list item\n      // can continue the list; otherwise, create a list container.\n\n      data->marker_offset = parser->indent;\n\n      if (cont_type != CMARK_NODE_LIST ||\n          !lists_match(&((*container)->as.list), data)) {\n        *container = add_child(parser, *container, CMARK_NODE_LIST,\n                               parser->first_nonspace + 1);\n\n        memcpy(&((*container)->as.list), data, sizeof(*data));\n      }\n\n      // add the list item\n      *container = add_child(parser, *container, CMARK_NODE_ITEM,\n                             parser->first_nonspace + 1);\n      /* TODO: static */\n      memcpy(&((*container)->as.list), data, sizeof(*data));\n      parser->mem->free(data);\n    } else if (indented && !maybe_lazy && !parser->blank) {\n      S_advance_offset(parser, input, CODE_INDENT, true);\n      *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,\n                             parser->offset + 1);\n      (*container)->as.code.fenced = false;\n      (*container)->as.code.fence_char = 0;\n      (*container)->as.code.fence_length = 0;\n      (*container)->as.code.fence_offset = 0;\n      (*container)->as.code.info = cmark_chunk_literal(\"\");\n    } else {\n      cmark_llist *tmp;\n      cmark_node *new_container = NULL;\n\n      for (tmp = parser->syntax_extensions; tmp; tmp=tmp->next) {\n        cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n\n        if (ext->try_opening_block) {\n          new_container = ext->try_opening_block(\n              ext, indented, parser, *container, input->data, input->len);\n\n          if (new_container) {\n            *container = new_container;\n            break;\n          }\n        }\n      }\n\n      if (!new_container) {\n        break;\n      }\n    }\n\n    if (accepts_lines(S_type(*container))) {\n      // if it's a line container, it can't contain other containers\n      break;\n    }\n\n    cont_type = S_type(*container);\n    maybe_lazy = false;\n  }\n}\n\nstatic void add_text_to_container(cmark_parser *parser, cmark_node *container,\n                                  cmark_node *last_matched_container,\n                                  cmark_chunk *input) {\n  cmark_node *tmp;\n  // what remains at parser->offset is a text line.  add the text to the\n  // appropriate container.\n\n  S_find_first_nonspace(parser, input);\n\n  if (parser->blank && container->last_child)\n    S_set_last_line_blank(container->last_child, true);\n\n  // block quote lines are never blank as they start with >\n  // and we don't count blanks in fenced code for purposes of tight/loose\n  // lists or breaking out of lists.  we also don't set last_line_blank\n  // on an empty list item.\n  const cmark_node_type ctype = S_type(container);\n  const bool last_line_blank =\n      (parser->blank && ctype != CMARK_NODE_BLOCK_QUOTE &&\n       ctype != CMARK_NODE_HEADING && ctype != CMARK_NODE_THEMATIC_BREAK &&\n       !(ctype == CMARK_NODE_CODE_BLOCK && container->as.code.fenced) &&\n       !(ctype == CMARK_NODE_ITEM && container->first_child == NULL &&\n         container->start_line == parser->line_number));\n\n  S_set_last_line_blank(container, last_line_blank);\n\n  tmp = container;\n  while (tmp->parent) {\n    S_set_last_line_blank(tmp->parent, false);\n    tmp = tmp->parent;\n  }\n\n  // If the last line processed belonged to a paragraph node,\n  // and we didn't match all of the line prefixes for the open containers,\n  // and we didn't start any new containers,\n  // and the line isn't blank,\n  // then treat this as a \"lazy continuation line\" and add it to\n  // the open paragraph.\n  if (parser->current != last_matched_container &&\n      container == last_matched_container && !parser->blank &&\n      S_type(parser->current) == CMARK_NODE_PARAGRAPH) {\n    add_line(parser->current, input, parser);\n  } else { // not a lazy continuation\n    // Finalize any blocks that were not matched and set cur to container:\n    while (parser->current != last_matched_container) {\n      parser->current = finalize(parser, parser->current);\n      assert(parser->current != NULL);\n    }\n\n    if (S_type(container) == CMARK_NODE_CODE_BLOCK) {\n      add_line(container, input, parser);\n    } else if (S_type(container) == CMARK_NODE_HTML_BLOCK) {\n      add_line(container, input, parser);\n\n      int matches_end_condition;\n      switch (container->as.html_block_type) {\n      case 1:\n        // </script>, </style>, </pre>\n        matches_end_condition =\n            scan_html_block_end_1(input, parser->first_nonspace);\n        break;\n      case 2:\n        // -->\n        matches_end_condition =\n            scan_html_block_end_2(input, parser->first_nonspace);\n        break;\n      case 3:\n        // ?>\n        matches_end_condition =\n            scan_html_block_end_3(input, parser->first_nonspace);\n        break;\n      case 4:\n        // >\n        matches_end_condition =\n            scan_html_block_end_4(input, parser->first_nonspace);\n        break;\n      case 5:\n        // ]]>\n        matches_end_condition =\n            scan_html_block_end_5(input, parser->first_nonspace);\n        break;\n      default:\n        matches_end_condition = 0;\n        break;\n      }\n\n      if (matches_end_condition) {\n        container = finalize(parser, container);\n        assert(parser->current != NULL);\n      }\n    } else if (parser->blank) {\n      // ??? do nothing\n    } else if (accepts_lines(S_type(container))) {\n      if (S_type(container) == CMARK_NODE_HEADING &&\n          container->as.heading.setext == false) {\n        chop_trailing_hashtags(input);\n      }\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      add_line(container, input, parser);\n    } else {\n      // create paragraph container for line\n      container = add_child(parser, container, CMARK_NODE_PARAGRAPH,\n                            parser->first_nonspace + 1);\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      add_line(container, input, parser);\n    }\n\n    parser->current = container;\n  }\n}\n\n/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */\nstatic void S_process_line(cmark_parser *parser, const unsigned char *buffer,\n                           bufsize_t bytes) {\n  cmark_node *last_matched_container;\n  bool all_matched = true;\n  cmark_node *container;\n  cmark_chunk input;\n  cmark_node *current;\n\n  cmark_strbuf_clear(&parser->curline);\n\n  if (parser->options & CMARK_OPT_VALIDATE_UTF8)\n    cmark_utf8proc_check(&parser->curline, buffer, bytes);\n  else\n    cmark_strbuf_put(&parser->curline, buffer, bytes);\n\n  bytes = parser->curline.size;\n\n  // ensure line ends with a newline:\n  if (bytes == 0 || !S_is_line_end_char(parser->curline.ptr[bytes - 1]))\n    cmark_strbuf_putc(&parser->curline, '\\n');\n\n  parser->offset = 0;\n  parser->column = 0;\n  parser->first_nonspace = 0;\n  parser->first_nonspace_column = 0;\n  parser->thematic_break_kill_pos = 0;\n  parser->indent = 0;\n  parser->blank = false;\n  parser->partially_consumed_tab = false;\n\n  input.data = parser->curline.ptr;\n  input.len = parser->curline.size;\n  input.alloc = 0;\n\n  // Skip UTF-8 BOM.\n  if (parser->line_number == 0 &&\n      input.len >= 3 &&\n      memcmp(input.data, \"\\xef\\xbb\\xbf\", 3) == 0)\n    parser->offset += 3;\n\n  parser->line_number++;\n\n  last_matched_container = check_open_blocks(parser, &input, &all_matched);\n\n  if (!last_matched_container)\n    goto finished;\n\n  container = last_matched_container;\n\n  current = parser->current;\n\n  open_new_blocks(parser, &container, &input, all_matched);\n\n  /* parser->current might have changed if feed_reentrant was called */\n  if (current == parser->current)\n  add_text_to_container(parser, container, last_matched_container, &input);\n\nfinished:\n  parser->last_line_length = input.len;\n  if (parser->last_line_length &&\n      input.data[parser->last_line_length - 1] == '\\n')\n    parser->last_line_length -= 1;\n  if (parser->last_line_length &&\n      input.data[parser->last_line_length - 1] == '\\r')\n    parser->last_line_length -= 1;\n\n  cmark_strbuf_clear(&parser->curline);\n}\n\ncmark_node *cmark_parser_finish(cmark_parser *parser) {\n  cmark_node *res;\n  cmark_llist *extensions;\n\n  /* Parser was already finished once */\n  if (parser->root == NULL)\n    return NULL;\n\n  if (parser->linebuf.size) {\n    S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);\n    cmark_strbuf_clear(&parser->linebuf);\n  }\n\n  finalize_document(parser);\n\n  cmark_consolidate_text_nodes(parser->root);\n\n  cmark_strbuf_free(&parser->curline);\n  cmark_strbuf_free(&parser->linebuf);\n\n#if CMARK_DEBUG_NODES\n  if (cmark_node_check(parser->root, stderr)) {\n    abort();\n  }\n#endif\n\n  for (extensions = parser->syntax_extensions; extensions; extensions = extensions->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) extensions->data;\n    if (ext->postprocess_func) {\n      cmark_node *processed = ext->postprocess_func(ext, parser, parser->root);\n      if (processed)\n        parser->root = processed;\n    }\n  }\n\n  res = parser->root;\n  parser->root = NULL;\n\n  cmark_parser_reset(parser);\n\n  return res;\n}\n\nint cmark_parser_get_line_number(cmark_parser *parser) {\n  return parser->line_number;\n}\n\nbufsize_t cmark_parser_get_offset(cmark_parser *parser) {\n  return parser->offset;\n}\n\nbufsize_t cmark_parser_get_column(cmark_parser *parser) {\n  return parser->column;\n}\n\nint cmark_parser_get_first_nonspace(cmark_parser *parser) {\n  return parser->first_nonspace;\n}\n\nint cmark_parser_get_first_nonspace_column(cmark_parser *parser) {\n  return parser->first_nonspace_column;\n}\n\nint cmark_parser_get_indent(cmark_parser *parser) {\n  return parser->indent;\n}\n\nint cmark_parser_is_blank(cmark_parser *parser) {\n  return parser->blank;\n}\n\nint cmark_parser_has_partially_consumed_tab(cmark_parser *parser) {\n  return parser->partially_consumed_tab;\n}\n\nint cmark_parser_get_last_line_length(cmark_parser *parser) {\n  return parser->last_line_length;\n}\n\ncmark_node *cmark_parser_add_child(cmark_parser *parser,\n                                   cmark_node   *parent,\n                                   cmark_node_type block_type,\n                                   int start_column) {\n  return add_child(parser, parent, block_type, start_column);\n}\n\nvoid cmark_parser_advance_offset(cmark_parser *parser,\n                                 const char *input,\n                                 int count,\n                                 int columns) {\n  cmark_chunk input_chunk = cmark_chunk_literal(input);\n\n  S_advance_offset(parser, &input_chunk, count, columns != 0);\n}\n\nvoid cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,\n                                             cmark_ispunct_func func) {\n  parser->backslash_ispunct = func;\n}\n\ncmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser) {\n  return parser->syntax_extensions;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/buffer.c",
    "content": "#include <stdarg.h>\n#include <string.h>\n#include <assert.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n\n#include \"config.h\"\n#include \"cmark_ctype.h\"\n#include \"buffer.h\"\n\n/* Used as default value for cmark_strbuf->ptr so that people can always\n * assume ptr is non-NULL and zero terminated even for new cmark_strbufs.\n */\nunsigned char cmark_strbuf__initbuf[1];\n\n#ifndef MIN\n#define MIN(x, y) ((x < y) ? x : y)\n#endif\n\nvoid cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,\n                       bufsize_t initial_size) {\n  buf->mem = mem;\n  buf->asize = 0;\n  buf->size = 0;\n  buf->ptr = cmark_strbuf__initbuf;\n\n  if (initial_size > 0)\n    cmark_strbuf_grow(buf, initial_size);\n}\n\nstatic CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) {\n  cmark_strbuf_grow(buf, buf->size + add);\n}\n\nvoid cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) {\n  assert(target_size > 0);\n\n  if (target_size < buf->asize)\n    return;\n\n  if (target_size > (bufsize_t)(INT32_MAX / 2)) {\n    fprintf(stderr,\n      \"[cmark] cmark_strbuf_grow requests buffer with size > %d, aborting\\n\",\n         (INT32_MAX / 2));\n    abort();\n  }\n\n  /* Oversize the buffer by 50% to guarantee amortized linear time\n   * complexity on append operations. */\n  bufsize_t new_size = target_size + target_size / 2;\n  new_size += 1;\n  new_size = (new_size + 7) & ~7;\n\n  buf->ptr = (unsigned char *)buf->mem->realloc(buf->asize ? buf->ptr : NULL,\n                                                new_size);\n  buf->asize = new_size;\n}\n\nbufsize_t cmark_strbuf_len(const cmark_strbuf *buf) { return buf->size; }\n\nvoid cmark_strbuf_free(cmark_strbuf *buf) {\n  if (!buf)\n    return;\n\n  if (buf->ptr != cmark_strbuf__initbuf)\n    buf->mem->free(buf->ptr);\n\n  cmark_strbuf_init(buf->mem, buf, 0);\n}\n\nvoid cmark_strbuf_clear(cmark_strbuf *buf) {\n  buf->size = 0;\n\n  if (buf->asize > 0)\n    buf->ptr[0] = '\\0';\n}\n\nvoid cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len) {\n  if (len <= 0 || data == NULL) {\n    cmark_strbuf_clear(buf);\n  } else {\n    if (data != buf->ptr) {\n      if (len >= buf->asize)\n        cmark_strbuf_grow(buf, len);\n      memmove(buf->ptr, data, len);\n    }\n    buf->size = len;\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_sets(cmark_strbuf *buf, const char *string) {\n  cmark_strbuf_set(buf, (const unsigned char *)string,\n                   string ? (bufsize_t)strlen(string) : 0);\n}\n\nvoid cmark_strbuf_putc(cmark_strbuf *buf, int c) {\n  S_strbuf_grow_by(buf, 1);\n  buf->ptr[buf->size++] = (unsigned char)(c & 0xFF);\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len) {\n  if (len <= 0)\n    return;\n\n  S_strbuf_grow_by(buf, len);\n  memmove(buf->ptr + buf->size, data, len);\n  buf->size += len;\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_puts(cmark_strbuf *buf, const char *string) {\n  cmark_strbuf_put(buf, (const unsigned char *)string, (bufsize_t)strlen(string));\n}\n\nvoid cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,\n                            const cmark_strbuf *buf) {\n  bufsize_t copylen;\n\n  assert(buf);\n  if (!data || datasize <= 0)\n    return;\n\n  data[0] = '\\0';\n\n  if (buf->size == 0 || buf->asize <= 0)\n    return;\n\n  copylen = buf->size;\n  if (copylen > datasize - 1)\n    copylen = datasize - 1;\n  memmove(data, buf->ptr, copylen);\n  data[copylen] = '\\0';\n}\n\nvoid cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b) {\n  cmark_strbuf t = *buf_a;\n  *buf_a = *buf_b;\n  *buf_b = t;\n}\n\nunsigned char *cmark_strbuf_detach(cmark_strbuf *buf) {\n  unsigned char *data = buf->ptr;\n\n  if (buf->asize == 0) {\n    /* return an empty string */\n    return (unsigned char *)buf->mem->calloc(1, 1);\n  }\n\n  cmark_strbuf_init(buf->mem, buf, 0);\n  return data;\n}\n\nint cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b) {\n  int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size));\n  return (result != 0) ? result\n                       : (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;\n}\n\nbufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos) {\n  if (pos >= buf->size)\n    return -1;\n  if (pos < 0)\n    pos = 0;\n\n  const unsigned char *p =\n      (unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos);\n  if (!p)\n    return -1;\n\n  return (bufsize_t)(p - (const unsigned char *)buf->ptr);\n}\n\nbufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos) {\n  if (pos < 0 || buf->size == 0)\n    return -1;\n  if (pos >= buf->size)\n    pos = buf->size - 1;\n\n  bufsize_t i;\n  for (i = pos; i >= 0; i--) {\n    if (buf->ptr[i] == (unsigned char)c)\n      return i;\n  }\n\n  return -1;\n}\n\nvoid cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len) {\n  if (len < 0)\n    len = 0;\n\n  if (len < buf->size) {\n    buf->size = len;\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n) {\n  if (n > 0) {\n    if (n > buf->size)\n      n = buf->size;\n    buf->size = buf->size - n;\n    if (buf->size)\n      memmove(buf->ptr, buf->ptr + n, buf->size);\n\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_rtrim(cmark_strbuf *buf) {\n  if (!buf->size)\n    return;\n\n  while (buf->size > 0) {\n    if (!cmark_isspace(buf->ptr[buf->size - 1]))\n      break;\n\n    buf->size--;\n  }\n\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_trim(cmark_strbuf *buf) {\n  bufsize_t i = 0;\n\n  if (!buf->size)\n    return;\n\n  while (i < buf->size && cmark_isspace(buf->ptr[i]))\n    i++;\n\n  cmark_strbuf_drop(buf, i);\n\n  cmark_strbuf_rtrim(buf);\n}\n\n// Destructively modify string, collapsing consecutive\n// space and newline characters into a single space.\nvoid cmark_strbuf_normalize_whitespace(cmark_strbuf *s) {\n  bool last_char_was_space = false;\n  bufsize_t r, w;\n\n  for (r = 0, w = 0; r < s->size; ++r) {\n    if (cmark_isspace(s->ptr[r])) {\n      if (!last_char_was_space) {\n        s->ptr[w++] = ' ';\n        last_char_was_space = true;\n      }\n    } else {\n      s->ptr[w++] = s->ptr[r];\n      last_char_was_space = false;\n    }\n  }\n\n  cmark_strbuf_truncate(s, w);\n}\n\n// Destructively unescape a string: remove backslashes before punctuation chars.\nextern void cmark_strbuf_unescape(cmark_strbuf *buf) {\n  bufsize_t r, w;\n\n  for (r = 0, w = 0; r < buf->size; ++r) {\n    if (buf->ptr[r] == '\\\\' && cmark_ispunct(buf->ptr[r + 1]))\n      r++;\n\n    buf->ptr[w++] = buf->ptr[r];\n  }\n\n  cmark_strbuf_truncate(buf, w);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/buffer.h",
    "content": "#ifndef CMARK_BUFFER_H\n#define CMARK_BUFFER_H\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <limits.h>\n#include <stdint.h>\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct {\n  cmark_mem *mem;\n  unsigned char *ptr;\n  bufsize_t asize, size;\n} cmark_strbuf;\n\nextern unsigned char cmark_strbuf__initbuf[];\n\n#define CMARK_BUF_INIT(mem)                                                    \\\n  { mem, cmark_strbuf__initbuf, 0, 0 }\n\n/**\n * Initialize a cmark_strbuf structure.\n *\n * For the cases where CMARK_BUF_INIT cannot be used to do static\n * initialization.\n */\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,\n                       bufsize_t initial_size);\n\n/**\n * Grow the buffer to hold at least `target_size` bytes.\n */\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_free(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_len(const cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nint cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b);\n\nCMARK_GFM_EXPORT\nunsigned char *cmark_strbuf_detach(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,\n                            const cmark_strbuf *buf);\n\nstatic CMARK_INLINE const char *cmark_strbuf_cstr(const cmark_strbuf *buf) {\n  return (char *)buf->ptr;\n}\n\n#define cmark_strbuf_at(buf, n) ((buf)->ptr[n])\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_sets(cmark_strbuf *buf, const char *string);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_putc(cmark_strbuf *buf, int c);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_puts(cmark_strbuf *buf, const char *string);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_clear(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_rtrim(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_trim(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_normalize_whitespace(cmark_strbuf *s);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_unescape(cmark_strbuf *s);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/case_fold_switch.inc",
    "content": "    switch (c) {\n      case 0x0041:\n        bufpush(0x0061);\n        break;\n      case 0x0042:\n        bufpush(0x0062);\n        break;\n      case 0x0043:\n        bufpush(0x0063);\n        break;\n      case 0x0044:\n        bufpush(0x0064);\n        break;\n      case 0x0045:\n        bufpush(0x0065);\n        break;\n      case 0x0046:\n        bufpush(0x0066);\n        break;\n      case 0x0047:\n        bufpush(0x0067);\n        break;\n      case 0x0048:\n        bufpush(0x0068);\n        break;\n      case 0x0049:\n        bufpush(0x0069);\n        break;\n      case 0x004A:\n        bufpush(0x006A);\n        break;\n      case 0x004B:\n        bufpush(0x006B);\n        break;\n      case 0x004C:\n        bufpush(0x006C);\n        break;\n      case 0x004D:\n        bufpush(0x006D);\n        break;\n      case 0x004E:\n        bufpush(0x006E);\n        break;\n      case 0x004F:\n        bufpush(0x006F);\n        break;\n      case 0x0050:\n        bufpush(0x0070);\n        break;\n      case 0x0051:\n        bufpush(0x0071);\n        break;\n      case 0x0052:\n        bufpush(0x0072);\n        break;\n      case 0x0053:\n        bufpush(0x0073);\n        break;\n      case 0x0054:\n        bufpush(0x0074);\n        break;\n      case 0x0055:\n        bufpush(0x0075);\n        break;\n      case 0x0056:\n        bufpush(0x0076);\n        break;\n      case 0x0057:\n        bufpush(0x0077);\n        break;\n      case 0x0058:\n        bufpush(0x0078);\n        break;\n      case 0x0059:\n        bufpush(0x0079);\n        break;\n      case 0x005A:\n        bufpush(0x007A);\n        break;\n      case 0x00B5:\n        bufpush(0x03BC);\n        break;\n      case 0x00C0:\n        bufpush(0x00E0);\n        break;\n      case 0x00C1:\n        bufpush(0x00E1);\n        break;\n      case 0x00C2:\n        bufpush(0x00E2);\n        break;\n      case 0x00C3:\n        bufpush(0x00E3);\n        break;\n      case 0x00C4:\n        bufpush(0x00E4);\n        break;\n      case 0x00C5:\n        bufpush(0x00E5);\n        break;\n      case 0x00C6:\n        bufpush(0x00E6);\n        break;\n      case 0x00C7:\n        bufpush(0x00E7);\n        break;\n      case 0x00C8:\n        bufpush(0x00E8);\n        break;\n      case 0x00C9:\n        bufpush(0x00E9);\n        break;\n      case 0x00CA:\n        bufpush(0x00EA);\n        break;\n      case 0x00CB:\n        bufpush(0x00EB);\n        break;\n      case 0x00CC:\n        bufpush(0x00EC);\n        break;\n      case 0x00CD:\n        bufpush(0x00ED);\n        break;\n      case 0x00CE:\n        bufpush(0x00EE);\n        break;\n      case 0x00CF:\n        bufpush(0x00EF);\n        break;\n      case 0x00D0:\n        bufpush(0x00F0);\n        break;\n      case 0x00D1:\n        bufpush(0x00F1);\n        break;\n      case 0x00D2:\n        bufpush(0x00F2);\n        break;\n      case 0x00D3:\n        bufpush(0x00F3);\n        break;\n      case 0x00D4:\n        bufpush(0x00F4);\n        break;\n      case 0x00D5:\n        bufpush(0x00F5);\n        break;\n      case 0x00D6:\n        bufpush(0x00F6);\n        break;\n      case 0x00D8:\n        bufpush(0x00F8);\n        break;\n      case 0x00D9:\n        bufpush(0x00F9);\n        break;\n      case 0x00DA:\n        bufpush(0x00FA);\n        break;\n      case 0x00DB:\n        bufpush(0x00FB);\n        break;\n      case 0x00DC:\n        bufpush(0x00FC);\n        break;\n      case 0x00DD:\n        bufpush(0x00FD);\n        break;\n      case 0x00DE:\n        bufpush(0x00FE);\n        break;\n      case 0x00DF:\n        bufpush(0x0073);\n        bufpush(0x0073);\n        break;\n      case 0x0100:\n        bufpush(0x0101);\n        break;\n      case 0x0102:\n        bufpush(0x0103);\n        break;\n      case 0x0104:\n        bufpush(0x0105);\n        break;\n      case 0x0106:\n        bufpush(0x0107);\n        break;\n      case 0x0108:\n        bufpush(0x0109);\n        break;\n      case 0x010A:\n        bufpush(0x010B);\n        break;\n      case 0x010C:\n        bufpush(0x010D);\n        break;\n      case 0x010E:\n        bufpush(0x010F);\n        break;\n      case 0x0110:\n        bufpush(0x0111);\n        break;\n      case 0x0112:\n        bufpush(0x0113);\n        break;\n      case 0x0114:\n        bufpush(0x0115);\n        break;\n      case 0x0116:\n        bufpush(0x0117);\n        break;\n      case 0x0118:\n        bufpush(0x0119);\n        break;\n      case 0x011A:\n        bufpush(0x011B);\n        break;\n      case 0x011C:\n        bufpush(0x011D);\n        break;\n      case 0x011E:\n        bufpush(0x011F);\n        break;\n      case 0x0120:\n        bufpush(0x0121);\n        break;\n      case 0x0122:\n        bufpush(0x0123);\n        break;\n      case 0x0124:\n        bufpush(0x0125);\n        break;\n      case 0x0126:\n        bufpush(0x0127);\n        break;\n      case 0x0128:\n        bufpush(0x0129);\n        break;\n      case 0x012A:\n        bufpush(0x012B);\n        break;\n      case 0x012C:\n        bufpush(0x012D);\n        break;\n      case 0x012E:\n        bufpush(0x012F);\n        break;\n      case 0x0130:\n        bufpush(0x0069);\n        bufpush(0x0307);\n        break;\n      case 0x0132:\n        bufpush(0x0133);\n        break;\n      case 0x0134:\n        bufpush(0x0135);\n        break;\n      case 0x0136:\n        bufpush(0x0137);\n        break;\n      case 0x0139:\n        bufpush(0x013A);\n        break;\n      case 0x013B:\n        bufpush(0x013C);\n        break;\n      case 0x013D:\n        bufpush(0x013E);\n        break;\n      case 0x013F:\n        bufpush(0x0140);\n        break;\n      case 0x0141:\n        bufpush(0x0142);\n        break;\n      case 0x0143:\n        bufpush(0x0144);\n        break;\n      case 0x0145:\n        bufpush(0x0146);\n        break;\n      case 0x0147:\n        bufpush(0x0148);\n        break;\n      case 0x0149:\n        bufpush(0x02BC);\n        bufpush(0x006E);\n        break;\n      case 0x014A:\n        bufpush(0x014B);\n        break;\n      case 0x014C:\n        bufpush(0x014D);\n        break;\n      case 0x014E:\n        bufpush(0x014F);\n        break;\n      case 0x0150:\n        bufpush(0x0151);\n        break;\n      case 0x0152:\n        bufpush(0x0153);\n        break;\n      case 0x0154:\n        bufpush(0x0155);\n        break;\n      case 0x0156:\n        bufpush(0x0157);\n        break;\n      case 0x0158:\n        bufpush(0x0159);\n        break;\n      case 0x015A:\n        bufpush(0x015B);\n        break;\n      case 0x015C:\n        bufpush(0x015D);\n        break;\n      case 0x015E:\n        bufpush(0x015F);\n        break;\n      case 0x0160:\n        bufpush(0x0161);\n        break;\n      case 0x0162:\n        bufpush(0x0163);\n        break;\n      case 0x0164:\n        bufpush(0x0165);\n        break;\n      case 0x0166:\n        bufpush(0x0167);\n        break;\n      case 0x0168:\n        bufpush(0x0169);\n        break;\n      case 0x016A:\n        bufpush(0x016B);\n        break;\n      case 0x016C:\n        bufpush(0x016D);\n        break;\n      case 0x016E:\n        bufpush(0x016F);\n        break;\n      case 0x0170:\n        bufpush(0x0171);\n        break;\n      case 0x0172:\n        bufpush(0x0173);\n        break;\n      case 0x0174:\n        bufpush(0x0175);\n        break;\n      case 0x0176:\n        bufpush(0x0177);\n        break;\n      case 0x0178:\n        bufpush(0x00FF);\n        break;\n      case 0x0179:\n        bufpush(0x017A);\n        break;\n      case 0x017B:\n        bufpush(0x017C);\n        break;\n      case 0x017D:\n        bufpush(0x017E);\n        break;\n      case 0x017F:\n        bufpush(0x0073);\n        break;\n      case 0x0181:\n        bufpush(0x0253);\n        break;\n      case 0x0182:\n        bufpush(0x0183);\n        break;\n      case 0x0184:\n        bufpush(0x0185);\n        break;\n      case 0x0186:\n        bufpush(0x0254);\n        break;\n      case 0x0187:\n        bufpush(0x0188);\n        break;\n      case 0x0189:\n        bufpush(0x0256);\n        break;\n      case 0x018A:\n        bufpush(0x0257);\n        break;\n      case 0x018B:\n        bufpush(0x018C);\n        break;\n      case 0x018E:\n        bufpush(0x01DD);\n        break;\n      case 0x018F:\n        bufpush(0x0259);\n        break;\n      case 0x0190:\n        bufpush(0x025B);\n        break;\n      case 0x0191:\n        bufpush(0x0192);\n        break;\n      case 0x0193:\n        bufpush(0x0260);\n        break;\n      case 0x0194:\n        bufpush(0x0263);\n        break;\n      case 0x0196:\n        bufpush(0x0269);\n        break;\n      case 0x0197:\n        bufpush(0x0268);\n        break;\n      case 0x0198:\n        bufpush(0x0199);\n        break;\n      case 0x019C:\n        bufpush(0x026F);\n        break;\n      case 0x019D:\n        bufpush(0x0272);\n        break;\n      case 0x019F:\n        bufpush(0x0275);\n        break;\n      case 0x01A0:\n        bufpush(0x01A1);\n        break;\n      case 0x01A2:\n        bufpush(0x01A3);\n        break;\n      case 0x01A4:\n        bufpush(0x01A5);\n        break;\n      case 0x01A6:\n        bufpush(0x0280);\n        break;\n      case 0x01A7:\n        bufpush(0x01A8);\n        break;\n      case 0x01A9:\n        bufpush(0x0283);\n        break;\n      case 0x01AC:\n        bufpush(0x01AD);\n        break;\n      case 0x01AE:\n        bufpush(0x0288);\n        break;\n      case 0x01AF:\n        bufpush(0x01B0);\n        break;\n      case 0x01B1:\n        bufpush(0x028A);\n        break;\n      case 0x01B2:\n        bufpush(0x028B);\n        break;\n      case 0x01B3:\n        bufpush(0x01B4);\n        break;\n      case 0x01B5:\n        bufpush(0x01B6);\n        break;\n      case 0x01B7:\n        bufpush(0x0292);\n        break;\n      case 0x01B8:\n        bufpush(0x01B9);\n        break;\n      case 0x01BC:\n        bufpush(0x01BD);\n        break;\n      case 0x01C4:\n        bufpush(0x01C6);\n        break;\n      case 0x01C5:\n        bufpush(0x01C6);\n        break;\n      case 0x01C7:\n        bufpush(0x01C9);\n        break;\n      case 0x01C8:\n        bufpush(0x01C9);\n        break;\n      case 0x01CA:\n        bufpush(0x01CC);\n        break;\n      case 0x01CB:\n        bufpush(0x01CC);\n        break;\n      case 0x01CD:\n        bufpush(0x01CE);\n        break;\n      case 0x01CF:\n        bufpush(0x01D0);\n        break;\n      case 0x01D1:\n        bufpush(0x01D2);\n        break;\n      case 0x01D3:\n        bufpush(0x01D4);\n        break;\n      case 0x01D5:\n        bufpush(0x01D6);\n        break;\n      case 0x01D7:\n        bufpush(0x01D8);\n        break;\n      case 0x01D9:\n        bufpush(0x01DA);\n        break;\n      case 0x01DB:\n        bufpush(0x01DC);\n        break;\n      case 0x01DE:\n        bufpush(0x01DF);\n        break;\n      case 0x01E0:\n        bufpush(0x01E1);\n        break;\n      case 0x01E2:\n        bufpush(0x01E3);\n        break;\n      case 0x01E4:\n        bufpush(0x01E5);\n        break;\n      case 0x01E6:\n        bufpush(0x01E7);\n        break;\n      case 0x01E8:\n        bufpush(0x01E9);\n        break;\n      case 0x01EA:\n        bufpush(0x01EB);\n        break;\n      case 0x01EC:\n        bufpush(0x01ED);\n        break;\n      case 0x01EE:\n        bufpush(0x01EF);\n        break;\n      case 0x01F0:\n        bufpush(0x006A);\n        bufpush(0x030C);\n        break;\n      case 0x01F1:\n        bufpush(0x01F3);\n        break;\n      case 0x01F2:\n        bufpush(0x01F3);\n        break;\n      case 0x01F4:\n        bufpush(0x01F5);\n        break;\n      case 0x01F6:\n        bufpush(0x0195);\n        break;\n      case 0x01F7:\n        bufpush(0x01BF);\n        break;\n      case 0x01F8:\n        bufpush(0x01F9);\n        break;\n      case 0x01FA:\n        bufpush(0x01FB);\n        break;\n      case 0x01FC:\n        bufpush(0x01FD);\n        break;\n      case 0x01FE:\n        bufpush(0x01FF);\n        break;\n      case 0x0200:\n        bufpush(0x0201);\n        break;\n      case 0x0202:\n        bufpush(0x0203);\n        break;\n      case 0x0204:\n        bufpush(0x0205);\n        break;\n      case 0x0206:\n        bufpush(0x0207);\n        break;\n      case 0x0208:\n        bufpush(0x0209);\n        break;\n      case 0x020A:\n        bufpush(0x020B);\n        break;\n      case 0x020C:\n        bufpush(0x020D);\n        break;\n      case 0x020E:\n        bufpush(0x020F);\n        break;\n      case 0x0210:\n        bufpush(0x0211);\n        break;\n      case 0x0212:\n        bufpush(0x0213);\n        break;\n      case 0x0214:\n        bufpush(0x0215);\n        break;\n      case 0x0216:\n        bufpush(0x0217);\n        break;\n      case 0x0218:\n        bufpush(0x0219);\n        break;\n      case 0x021A:\n        bufpush(0x021B);\n        break;\n      case 0x021C:\n        bufpush(0x021D);\n        break;\n      case 0x021E:\n        bufpush(0x021F);\n        break;\n      case 0x0220:\n        bufpush(0x019E);\n        break;\n      case 0x0222:\n        bufpush(0x0223);\n        break;\n      case 0x0224:\n        bufpush(0x0225);\n        break;\n      case 0x0226:\n        bufpush(0x0227);\n        break;\n      case 0x0228:\n        bufpush(0x0229);\n        break;\n      case 0x022A:\n        bufpush(0x022B);\n        break;\n      case 0x022C:\n        bufpush(0x022D);\n        break;\n      case 0x022E:\n        bufpush(0x022F);\n        break;\n      case 0x0230:\n        bufpush(0x0231);\n        break;\n      case 0x0232:\n        bufpush(0x0233);\n        break;\n      case 0x023A:\n        bufpush(0x2C65);\n        break;\n      case 0x023B:\n        bufpush(0x023C);\n        break;\n      case 0x023D:\n        bufpush(0x019A);\n        break;\n      case 0x023E:\n        bufpush(0x2C66);\n        break;\n      case 0x0241:\n        bufpush(0x0242);\n        break;\n      case 0x0243:\n        bufpush(0x0180);\n        break;\n      case 0x0244:\n        bufpush(0x0289);\n        break;\n      case 0x0245:\n        bufpush(0x028C);\n        break;\n      case 0x0246:\n        bufpush(0x0247);\n        break;\n      case 0x0248:\n        bufpush(0x0249);\n        break;\n      case 0x024A:\n        bufpush(0x024B);\n        break;\n      case 0x024C:\n        bufpush(0x024D);\n        break;\n      case 0x024E:\n        bufpush(0x024F);\n        break;\n      case 0x0345:\n        bufpush(0x03B9);\n        break;\n      case 0x0370:\n        bufpush(0x0371);\n        break;\n      case 0x0372:\n        bufpush(0x0373);\n        break;\n      case 0x0376:\n        bufpush(0x0377);\n        break;\n      case 0x037F:\n        bufpush(0x03F3);\n        break;\n      case 0x0386:\n        bufpush(0x03AC);\n        break;\n      case 0x0388:\n        bufpush(0x03AD);\n        break;\n      case 0x0389:\n        bufpush(0x03AE);\n        break;\n      case 0x038A:\n        bufpush(0x03AF);\n        break;\n      case 0x038C:\n        bufpush(0x03CC);\n        break;\n      case 0x038E:\n        bufpush(0x03CD);\n        break;\n      case 0x038F:\n        bufpush(0x03CE);\n        break;\n      case 0x0390:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x0391:\n        bufpush(0x03B1);\n        break;\n      case 0x0392:\n        bufpush(0x03B2);\n        break;\n      case 0x0393:\n        bufpush(0x03B3);\n        break;\n      case 0x0394:\n        bufpush(0x03B4);\n        break;\n      case 0x0395:\n        bufpush(0x03B5);\n        break;\n      case 0x0396:\n        bufpush(0x03B6);\n        break;\n      case 0x0397:\n        bufpush(0x03B7);\n        break;\n      case 0x0398:\n        bufpush(0x03B8);\n        break;\n      case 0x0399:\n        bufpush(0x03B9);\n        break;\n      case 0x039A:\n        bufpush(0x03BA);\n        break;\n      case 0x039B:\n        bufpush(0x03BB);\n        break;\n      case 0x039C:\n        bufpush(0x03BC);\n        break;\n      case 0x039D:\n        bufpush(0x03BD);\n        break;\n      case 0x039E:\n        bufpush(0x03BE);\n        break;\n      case 0x039F:\n        bufpush(0x03BF);\n        break;\n      case 0x03A0:\n        bufpush(0x03C0);\n        break;\n      case 0x03A1:\n        bufpush(0x03C1);\n        break;\n      case 0x03A3:\n        bufpush(0x03C3);\n        break;\n      case 0x03A4:\n        bufpush(0x03C4);\n        break;\n      case 0x03A5:\n        bufpush(0x03C5);\n        break;\n      case 0x03A6:\n        bufpush(0x03C6);\n        break;\n      case 0x03A7:\n        bufpush(0x03C7);\n        break;\n      case 0x03A8:\n        bufpush(0x03C8);\n        break;\n      case 0x03A9:\n        bufpush(0x03C9);\n        break;\n      case 0x03AA:\n        bufpush(0x03CA);\n        break;\n      case 0x03AB:\n        bufpush(0x03CB);\n        break;\n      case 0x03B0:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x03C2:\n        bufpush(0x03C3);\n        break;\n      case 0x03CF:\n        bufpush(0x03D7);\n        break;\n      case 0x03D0:\n        bufpush(0x03B2);\n        break;\n      case 0x03D1:\n        bufpush(0x03B8);\n        break;\n      case 0x03D5:\n        bufpush(0x03C6);\n        break;\n      case 0x03D6:\n        bufpush(0x03C0);\n        break;\n      case 0x03D8:\n        bufpush(0x03D9);\n        break;\n      case 0x03DA:\n        bufpush(0x03DB);\n        break;\n      case 0x03DC:\n        bufpush(0x03DD);\n        break;\n      case 0x03DE:\n        bufpush(0x03DF);\n        break;\n      case 0x03E0:\n        bufpush(0x03E1);\n        break;\n      case 0x03E2:\n        bufpush(0x03E3);\n        break;\n      case 0x03E4:\n        bufpush(0x03E5);\n        break;\n      case 0x03E6:\n        bufpush(0x03E7);\n        break;\n      case 0x03E8:\n        bufpush(0x03E9);\n        break;\n      case 0x03EA:\n        bufpush(0x03EB);\n        break;\n      case 0x03EC:\n        bufpush(0x03ED);\n        break;\n      case 0x03EE:\n        bufpush(0x03EF);\n        break;\n      case 0x03F0:\n        bufpush(0x03BA);\n        break;\n      case 0x03F1:\n        bufpush(0x03C1);\n        break;\n      case 0x03F4:\n        bufpush(0x03B8);\n        break;\n      case 0x03F5:\n        bufpush(0x03B5);\n        break;\n      case 0x03F7:\n        bufpush(0x03F8);\n        break;\n      case 0x03F9:\n        bufpush(0x03F2);\n        break;\n      case 0x03FA:\n        bufpush(0x03FB);\n        break;\n      case 0x03FD:\n        bufpush(0x037B);\n        break;\n      case 0x03FE:\n        bufpush(0x037C);\n        break;\n      case 0x03FF:\n        bufpush(0x037D);\n        break;\n      case 0x0400:\n        bufpush(0x0450);\n        break;\n      case 0x0401:\n        bufpush(0x0451);\n        break;\n      case 0x0402:\n        bufpush(0x0452);\n        break;\n      case 0x0403:\n        bufpush(0x0453);\n        break;\n      case 0x0404:\n        bufpush(0x0454);\n        break;\n      case 0x0405:\n        bufpush(0x0455);\n        break;\n      case 0x0406:\n        bufpush(0x0456);\n        break;\n      case 0x0407:\n        bufpush(0x0457);\n        break;\n      case 0x0408:\n        bufpush(0x0458);\n        break;\n      case 0x0409:\n        bufpush(0x0459);\n        break;\n      case 0x040A:\n        bufpush(0x045A);\n        break;\n      case 0x040B:\n        bufpush(0x045B);\n        break;\n      case 0x040C:\n        bufpush(0x045C);\n        break;\n      case 0x040D:\n        bufpush(0x045D);\n        break;\n      case 0x040E:\n        bufpush(0x045E);\n        break;\n      case 0x040F:\n        bufpush(0x045F);\n        break;\n      case 0x0410:\n        bufpush(0x0430);\n        break;\n      case 0x0411:\n        bufpush(0x0431);\n        break;\n      case 0x0412:\n        bufpush(0x0432);\n        break;\n      case 0x0413:\n        bufpush(0x0433);\n        break;\n      case 0x0414:\n        bufpush(0x0434);\n        break;\n      case 0x0415:\n        bufpush(0x0435);\n        break;\n      case 0x0416:\n        bufpush(0x0436);\n        break;\n      case 0x0417:\n        bufpush(0x0437);\n        break;\n      case 0x0418:\n        bufpush(0x0438);\n        break;\n      case 0x0419:\n        bufpush(0x0439);\n        break;\n      case 0x041A:\n        bufpush(0x043A);\n        break;\n      case 0x041B:\n        bufpush(0x043B);\n        break;\n      case 0x041C:\n        bufpush(0x043C);\n        break;\n      case 0x041D:\n        bufpush(0x043D);\n        break;\n      case 0x041E:\n        bufpush(0x043E);\n        break;\n      case 0x041F:\n        bufpush(0x043F);\n        break;\n      case 0x0420:\n        bufpush(0x0440);\n        break;\n      case 0x0421:\n        bufpush(0x0441);\n        break;\n      case 0x0422:\n        bufpush(0x0442);\n        break;\n      case 0x0423:\n        bufpush(0x0443);\n        break;\n      case 0x0424:\n        bufpush(0x0444);\n        break;\n      case 0x0425:\n        bufpush(0x0445);\n        break;\n      case 0x0426:\n        bufpush(0x0446);\n        break;\n      case 0x0427:\n        bufpush(0x0447);\n        break;\n      case 0x0428:\n        bufpush(0x0448);\n        break;\n      case 0x0429:\n        bufpush(0x0449);\n        break;\n      case 0x042A:\n        bufpush(0x044A);\n        break;\n      case 0x042B:\n        bufpush(0x044B);\n        break;\n      case 0x042C:\n        bufpush(0x044C);\n        break;\n      case 0x042D:\n        bufpush(0x044D);\n        break;\n      case 0x042E:\n        bufpush(0x044E);\n        break;\n      case 0x042F:\n        bufpush(0x044F);\n        break;\n      case 0x0460:\n        bufpush(0x0461);\n        break;\n      case 0x0462:\n        bufpush(0x0463);\n        break;\n      case 0x0464:\n        bufpush(0x0465);\n        break;\n      case 0x0466:\n        bufpush(0x0467);\n        break;\n      case 0x0468:\n        bufpush(0x0469);\n        break;\n      case 0x046A:\n        bufpush(0x046B);\n        break;\n      case 0x046C:\n        bufpush(0x046D);\n        break;\n      case 0x046E:\n        bufpush(0x046F);\n        break;\n      case 0x0470:\n        bufpush(0x0471);\n        break;\n      case 0x0472:\n        bufpush(0x0473);\n        break;\n      case 0x0474:\n        bufpush(0x0475);\n        break;\n      case 0x0476:\n        bufpush(0x0477);\n        break;\n      case 0x0478:\n        bufpush(0x0479);\n        break;\n      case 0x047A:\n        bufpush(0x047B);\n        break;\n      case 0x047C:\n        bufpush(0x047D);\n        break;\n      case 0x047E:\n        bufpush(0x047F);\n        break;\n      case 0x0480:\n        bufpush(0x0481);\n        break;\n      case 0x048A:\n        bufpush(0x048B);\n        break;\n      case 0x048C:\n        bufpush(0x048D);\n        break;\n      case 0x048E:\n        bufpush(0x048F);\n        break;\n      case 0x0490:\n        bufpush(0x0491);\n        break;\n      case 0x0492:\n        bufpush(0x0493);\n        break;\n      case 0x0494:\n        bufpush(0x0495);\n        break;\n      case 0x0496:\n        bufpush(0x0497);\n        break;\n      case 0x0498:\n        bufpush(0x0499);\n        break;\n      case 0x049A:\n        bufpush(0x049B);\n        break;\n      case 0x049C:\n        bufpush(0x049D);\n        break;\n      case 0x049E:\n        bufpush(0x049F);\n        break;\n      case 0x04A0:\n        bufpush(0x04A1);\n        break;\n      case 0x04A2:\n        bufpush(0x04A3);\n        break;\n      case 0x04A4:\n        bufpush(0x04A5);\n        break;\n      case 0x04A6:\n        bufpush(0x04A7);\n        break;\n      case 0x04A8:\n        bufpush(0x04A9);\n        break;\n      case 0x04AA:\n        bufpush(0x04AB);\n        break;\n      case 0x04AC:\n        bufpush(0x04AD);\n        break;\n      case 0x04AE:\n        bufpush(0x04AF);\n        break;\n      case 0x04B0:\n        bufpush(0x04B1);\n        break;\n      case 0x04B2:\n        bufpush(0x04B3);\n        break;\n      case 0x04B4:\n        bufpush(0x04B5);\n        break;\n      case 0x04B6:\n        bufpush(0x04B7);\n        break;\n      case 0x04B8:\n        bufpush(0x04B9);\n        break;\n      case 0x04BA:\n        bufpush(0x04BB);\n        break;\n      case 0x04BC:\n        bufpush(0x04BD);\n        break;\n      case 0x04BE:\n        bufpush(0x04BF);\n        break;\n      case 0x04C0:\n        bufpush(0x04CF);\n        break;\n      case 0x04C1:\n        bufpush(0x04C2);\n        break;\n      case 0x04C3:\n        bufpush(0x04C4);\n        break;\n      case 0x04C5:\n        bufpush(0x04C6);\n        break;\n      case 0x04C7:\n        bufpush(0x04C8);\n        break;\n      case 0x04C9:\n        bufpush(0x04CA);\n        break;\n      case 0x04CB:\n        bufpush(0x04CC);\n        break;\n      case 0x04CD:\n        bufpush(0x04CE);\n        break;\n      case 0x04D0:\n        bufpush(0x04D1);\n        break;\n      case 0x04D2:\n        bufpush(0x04D3);\n        break;\n      case 0x04D4:\n        bufpush(0x04D5);\n        break;\n      case 0x04D6:\n        bufpush(0x04D7);\n        break;\n      case 0x04D8:\n        bufpush(0x04D9);\n        break;\n      case 0x04DA:\n        bufpush(0x04DB);\n        break;\n      case 0x04DC:\n        bufpush(0x04DD);\n        break;\n      case 0x04DE:\n        bufpush(0x04DF);\n        break;\n      case 0x04E0:\n        bufpush(0x04E1);\n        break;\n      case 0x04E2:\n        bufpush(0x04E3);\n        break;\n      case 0x04E4:\n        bufpush(0x04E5);\n        break;\n      case 0x04E6:\n        bufpush(0x04E7);\n        break;\n      case 0x04E8:\n        bufpush(0x04E9);\n        break;\n      case 0x04EA:\n        bufpush(0x04EB);\n        break;\n      case 0x04EC:\n        bufpush(0x04ED);\n        break;\n      case 0x04EE:\n        bufpush(0x04EF);\n        break;\n      case 0x04F0:\n        bufpush(0x04F1);\n        break;\n      case 0x04F2:\n        bufpush(0x04F3);\n        break;\n      case 0x04F4:\n        bufpush(0x04F5);\n        break;\n      case 0x04F6:\n        bufpush(0x04F7);\n        break;\n      case 0x04F8:\n        bufpush(0x04F9);\n        break;\n      case 0x04FA:\n        bufpush(0x04FB);\n        break;\n      case 0x04FC:\n        bufpush(0x04FD);\n        break;\n      case 0x04FE:\n        bufpush(0x04FF);\n        break;\n      case 0x0500:\n        bufpush(0x0501);\n        break;\n      case 0x0502:\n        bufpush(0x0503);\n        break;\n      case 0x0504:\n        bufpush(0x0505);\n        break;\n      case 0x0506:\n        bufpush(0x0507);\n        break;\n      case 0x0508:\n        bufpush(0x0509);\n        break;\n      case 0x050A:\n        bufpush(0x050B);\n        break;\n      case 0x050C:\n        bufpush(0x050D);\n        break;\n      case 0x050E:\n        bufpush(0x050F);\n        break;\n      case 0x0510:\n        bufpush(0x0511);\n        break;\n      case 0x0512:\n        bufpush(0x0513);\n        break;\n      case 0x0514:\n        bufpush(0x0515);\n        break;\n      case 0x0516:\n        bufpush(0x0517);\n        break;\n      case 0x0518:\n        bufpush(0x0519);\n        break;\n      case 0x051A:\n        bufpush(0x051B);\n        break;\n      case 0x051C:\n        bufpush(0x051D);\n        break;\n      case 0x051E:\n        bufpush(0x051F);\n        break;\n      case 0x0520:\n        bufpush(0x0521);\n        break;\n      case 0x0522:\n        bufpush(0x0523);\n        break;\n      case 0x0524:\n        bufpush(0x0525);\n        break;\n      case 0x0526:\n        bufpush(0x0527);\n        break;\n      case 0x0528:\n        bufpush(0x0529);\n        break;\n      case 0x052A:\n        bufpush(0x052B);\n        break;\n      case 0x052C:\n        bufpush(0x052D);\n        break;\n      case 0x052E:\n        bufpush(0x052F);\n        break;\n      case 0x0531:\n        bufpush(0x0561);\n        break;\n      case 0x0532:\n        bufpush(0x0562);\n        break;\n      case 0x0533:\n        bufpush(0x0563);\n        break;\n      case 0x0534:\n        bufpush(0x0564);\n        break;\n      case 0x0535:\n        bufpush(0x0565);\n        break;\n      case 0x0536:\n        bufpush(0x0566);\n        break;\n      case 0x0537:\n        bufpush(0x0567);\n        break;\n      case 0x0538:\n        bufpush(0x0568);\n        break;\n      case 0x0539:\n        bufpush(0x0569);\n        break;\n      case 0x053A:\n        bufpush(0x056A);\n        break;\n      case 0x053B:\n        bufpush(0x056B);\n        break;\n      case 0x053C:\n        bufpush(0x056C);\n        break;\n      case 0x053D:\n        bufpush(0x056D);\n        break;\n      case 0x053E:\n        bufpush(0x056E);\n        break;\n      case 0x053F:\n        bufpush(0x056F);\n        break;\n      case 0x0540:\n        bufpush(0x0570);\n        break;\n      case 0x0541:\n        bufpush(0x0571);\n        break;\n      case 0x0542:\n        bufpush(0x0572);\n        break;\n      case 0x0543:\n        bufpush(0x0573);\n        break;\n      case 0x0544:\n        bufpush(0x0574);\n        break;\n      case 0x0545:\n        bufpush(0x0575);\n        break;\n      case 0x0546:\n        bufpush(0x0576);\n        break;\n      case 0x0547:\n        bufpush(0x0577);\n        break;\n      case 0x0548:\n        bufpush(0x0578);\n        break;\n      case 0x0549:\n        bufpush(0x0579);\n        break;\n      case 0x054A:\n        bufpush(0x057A);\n        break;\n      case 0x054B:\n        bufpush(0x057B);\n        break;\n      case 0x054C:\n        bufpush(0x057C);\n        break;\n      case 0x054D:\n        bufpush(0x057D);\n        break;\n      case 0x054E:\n        bufpush(0x057E);\n        break;\n      case 0x054F:\n        bufpush(0x057F);\n        break;\n      case 0x0550:\n        bufpush(0x0580);\n        break;\n      case 0x0551:\n        bufpush(0x0581);\n        break;\n      case 0x0552:\n        bufpush(0x0582);\n        break;\n      case 0x0553:\n        bufpush(0x0583);\n        break;\n      case 0x0554:\n        bufpush(0x0584);\n        break;\n      case 0x0555:\n        bufpush(0x0585);\n        break;\n      case 0x0556:\n        bufpush(0x0586);\n        break;\n      case 0x0587:\n        bufpush(0x0565);\n        bufpush(0x0582);\n        break;\n      case 0x10A0:\n        bufpush(0x2D00);\n        break;\n      case 0x10A1:\n        bufpush(0x2D01);\n        break;\n      case 0x10A2:\n        bufpush(0x2D02);\n        break;\n      case 0x10A3:\n        bufpush(0x2D03);\n        break;\n      case 0x10A4:\n        bufpush(0x2D04);\n        break;\n      case 0x10A5:\n        bufpush(0x2D05);\n        break;\n      case 0x10A6:\n        bufpush(0x2D06);\n        break;\n      case 0x10A7:\n        bufpush(0x2D07);\n        break;\n      case 0x10A8:\n        bufpush(0x2D08);\n        break;\n      case 0x10A9:\n        bufpush(0x2D09);\n        break;\n      case 0x10AA:\n        bufpush(0x2D0A);\n        break;\n      case 0x10AB:\n        bufpush(0x2D0B);\n        break;\n      case 0x10AC:\n        bufpush(0x2D0C);\n        break;\n      case 0x10AD:\n        bufpush(0x2D0D);\n        break;\n      case 0x10AE:\n        bufpush(0x2D0E);\n        break;\n      case 0x10AF:\n        bufpush(0x2D0F);\n        break;\n      case 0x10B0:\n        bufpush(0x2D10);\n        break;\n      case 0x10B1:\n        bufpush(0x2D11);\n        break;\n      case 0x10B2:\n        bufpush(0x2D12);\n        break;\n      case 0x10B3:\n        bufpush(0x2D13);\n        break;\n      case 0x10B4:\n        bufpush(0x2D14);\n        break;\n      case 0x10B5:\n        bufpush(0x2D15);\n        break;\n      case 0x10B6:\n        bufpush(0x2D16);\n        break;\n      case 0x10B7:\n        bufpush(0x2D17);\n        break;\n      case 0x10B8:\n        bufpush(0x2D18);\n        break;\n      case 0x10B9:\n        bufpush(0x2D19);\n        break;\n      case 0x10BA:\n        bufpush(0x2D1A);\n        break;\n      case 0x10BB:\n        bufpush(0x2D1B);\n        break;\n      case 0x10BC:\n        bufpush(0x2D1C);\n        break;\n      case 0x10BD:\n        bufpush(0x2D1D);\n        break;\n      case 0x10BE:\n        bufpush(0x2D1E);\n        break;\n      case 0x10BF:\n        bufpush(0x2D1F);\n        break;\n      case 0x10C0:\n        bufpush(0x2D20);\n        break;\n      case 0x10C1:\n        bufpush(0x2D21);\n        break;\n      case 0x10C2:\n        bufpush(0x2D22);\n        break;\n      case 0x10C3:\n        bufpush(0x2D23);\n        break;\n      case 0x10C4:\n        bufpush(0x2D24);\n        break;\n      case 0x10C5:\n        bufpush(0x2D25);\n        break;\n      case 0x10C7:\n        bufpush(0x2D27);\n        break;\n      case 0x10CD:\n        bufpush(0x2D2D);\n        break;\n      case 0x13F8:\n        bufpush(0x13F0);\n        break;\n      case 0x13F9:\n        bufpush(0x13F1);\n        break;\n      case 0x13FA:\n        bufpush(0x13F2);\n        break;\n      case 0x13FB:\n        bufpush(0x13F3);\n        break;\n      case 0x13FC:\n        bufpush(0x13F4);\n        break;\n      case 0x13FD:\n        bufpush(0x13F5);\n        break;\n      case 0x1C80:\n        bufpush(0x0432);\n        break;\n      case 0x1C81:\n        bufpush(0x0434);\n        break;\n      case 0x1C82:\n        bufpush(0x043E);\n        break;\n      case 0x1C83:\n        bufpush(0x0441);\n        break;\n      case 0x1C84:\n        bufpush(0x0442);\n        break;\n      case 0x1C85:\n        bufpush(0x0442);\n        break;\n      case 0x1C86:\n        bufpush(0x044A);\n        break;\n      case 0x1C87:\n        bufpush(0x0463);\n        break;\n      case 0x1C88:\n        bufpush(0xA64B);\n        break;\n      case 0x1E00:\n        bufpush(0x1E01);\n        break;\n      case 0x1E02:\n        bufpush(0x1E03);\n        break;\n      case 0x1E04:\n        bufpush(0x1E05);\n        break;\n      case 0x1E06:\n        bufpush(0x1E07);\n        break;\n      case 0x1E08:\n        bufpush(0x1E09);\n        break;\n      case 0x1E0A:\n        bufpush(0x1E0B);\n        break;\n      case 0x1E0C:\n        bufpush(0x1E0D);\n        break;\n      case 0x1E0E:\n        bufpush(0x1E0F);\n        break;\n      case 0x1E10:\n        bufpush(0x1E11);\n        break;\n      case 0x1E12:\n        bufpush(0x1E13);\n        break;\n      case 0x1E14:\n        bufpush(0x1E15);\n        break;\n      case 0x1E16:\n        bufpush(0x1E17);\n        break;\n      case 0x1E18:\n        bufpush(0x1E19);\n        break;\n      case 0x1E1A:\n        bufpush(0x1E1B);\n        break;\n      case 0x1E1C:\n        bufpush(0x1E1D);\n        break;\n      case 0x1E1E:\n        bufpush(0x1E1F);\n        break;\n      case 0x1E20:\n        bufpush(0x1E21);\n        break;\n      case 0x1E22:\n        bufpush(0x1E23);\n        break;\n      case 0x1E24:\n        bufpush(0x1E25);\n        break;\n      case 0x1E26:\n        bufpush(0x1E27);\n        break;\n      case 0x1E28:\n        bufpush(0x1E29);\n        break;\n      case 0x1E2A:\n        bufpush(0x1E2B);\n        break;\n      case 0x1E2C:\n        bufpush(0x1E2D);\n        break;\n      case 0x1E2E:\n        bufpush(0x1E2F);\n        break;\n      case 0x1E30:\n        bufpush(0x1E31);\n        break;\n      case 0x1E32:\n        bufpush(0x1E33);\n        break;\n      case 0x1E34:\n        bufpush(0x1E35);\n        break;\n      case 0x1E36:\n        bufpush(0x1E37);\n        break;\n      case 0x1E38:\n        bufpush(0x1E39);\n        break;\n      case 0x1E3A:\n        bufpush(0x1E3B);\n        break;\n      case 0x1E3C:\n        bufpush(0x1E3D);\n        break;\n      case 0x1E3E:\n        bufpush(0x1E3F);\n        break;\n      case 0x1E40:\n        bufpush(0x1E41);\n        break;\n      case 0x1E42:\n        bufpush(0x1E43);\n        break;\n      case 0x1E44:\n        bufpush(0x1E45);\n        break;\n      case 0x1E46:\n        bufpush(0x1E47);\n        break;\n      case 0x1E48:\n        bufpush(0x1E49);\n        break;\n      case 0x1E4A:\n        bufpush(0x1E4B);\n        break;\n      case 0x1E4C:\n        bufpush(0x1E4D);\n        break;\n      case 0x1E4E:\n        bufpush(0x1E4F);\n        break;\n      case 0x1E50:\n        bufpush(0x1E51);\n        break;\n      case 0x1E52:\n        bufpush(0x1E53);\n        break;\n      case 0x1E54:\n        bufpush(0x1E55);\n        break;\n      case 0x1E56:\n        bufpush(0x1E57);\n        break;\n      case 0x1E58:\n        bufpush(0x1E59);\n        break;\n      case 0x1E5A:\n        bufpush(0x1E5B);\n        break;\n      case 0x1E5C:\n        bufpush(0x1E5D);\n        break;\n      case 0x1E5E:\n        bufpush(0x1E5F);\n        break;\n      case 0x1E60:\n        bufpush(0x1E61);\n        break;\n      case 0x1E62:\n        bufpush(0x1E63);\n        break;\n      case 0x1E64:\n        bufpush(0x1E65);\n        break;\n      case 0x1E66:\n        bufpush(0x1E67);\n        break;\n      case 0x1E68:\n        bufpush(0x1E69);\n        break;\n      case 0x1E6A:\n        bufpush(0x1E6B);\n        break;\n      case 0x1E6C:\n        bufpush(0x1E6D);\n        break;\n      case 0x1E6E:\n        bufpush(0x1E6F);\n        break;\n      case 0x1E70:\n        bufpush(0x1E71);\n        break;\n      case 0x1E72:\n        bufpush(0x1E73);\n        break;\n      case 0x1E74:\n        bufpush(0x1E75);\n        break;\n      case 0x1E76:\n        bufpush(0x1E77);\n        break;\n      case 0x1E78:\n        bufpush(0x1E79);\n        break;\n      case 0x1E7A:\n        bufpush(0x1E7B);\n        break;\n      case 0x1E7C:\n        bufpush(0x1E7D);\n        break;\n      case 0x1E7E:\n        bufpush(0x1E7F);\n        break;\n      case 0x1E80:\n        bufpush(0x1E81);\n        break;\n      case 0x1E82:\n        bufpush(0x1E83);\n        break;\n      case 0x1E84:\n        bufpush(0x1E85);\n        break;\n      case 0x1E86:\n        bufpush(0x1E87);\n        break;\n      case 0x1E88:\n        bufpush(0x1E89);\n        break;\n      case 0x1E8A:\n        bufpush(0x1E8B);\n        break;\n      case 0x1E8C:\n        bufpush(0x1E8D);\n        break;\n      case 0x1E8E:\n        bufpush(0x1E8F);\n        break;\n      case 0x1E90:\n        bufpush(0x1E91);\n        break;\n      case 0x1E92:\n        bufpush(0x1E93);\n        break;\n      case 0x1E94:\n        bufpush(0x1E95);\n        break;\n      case 0x1E96:\n        bufpush(0x0068);\n        bufpush(0x0331);\n        break;\n      case 0x1E97:\n        bufpush(0x0074);\n        bufpush(0x0308);\n        break;\n      case 0x1E98:\n        bufpush(0x0077);\n        bufpush(0x030A);\n        break;\n      case 0x1E99:\n        bufpush(0x0079);\n        bufpush(0x030A);\n        break;\n      case 0x1E9A:\n        bufpush(0x0061);\n        bufpush(0x02BE);\n        break;\n      case 0x1E9B:\n        bufpush(0x1E61);\n        break;\n      case 0x1E9E:\n        bufpush(0x0073);\n        bufpush(0x0073);\n        break;\n      case 0x1EA0:\n        bufpush(0x1EA1);\n        break;\n      case 0x1EA2:\n        bufpush(0x1EA3);\n        break;\n      case 0x1EA4:\n        bufpush(0x1EA5);\n        break;\n      case 0x1EA6:\n        bufpush(0x1EA7);\n        break;\n      case 0x1EA8:\n        bufpush(0x1EA9);\n        break;\n      case 0x1EAA:\n        bufpush(0x1EAB);\n        break;\n      case 0x1EAC:\n        bufpush(0x1EAD);\n        break;\n      case 0x1EAE:\n        bufpush(0x1EAF);\n        break;\n      case 0x1EB0:\n        bufpush(0x1EB1);\n        break;\n      case 0x1EB2:\n        bufpush(0x1EB3);\n        break;\n      case 0x1EB4:\n        bufpush(0x1EB5);\n        break;\n      case 0x1EB6:\n        bufpush(0x1EB7);\n        break;\n      case 0x1EB8:\n        bufpush(0x1EB9);\n        break;\n      case 0x1EBA:\n        bufpush(0x1EBB);\n        break;\n      case 0x1EBC:\n        bufpush(0x1EBD);\n        break;\n      case 0x1EBE:\n        bufpush(0x1EBF);\n        break;\n      case 0x1EC0:\n        bufpush(0x1EC1);\n        break;\n      case 0x1EC2:\n        bufpush(0x1EC3);\n        break;\n      case 0x1EC4:\n        bufpush(0x1EC5);\n        break;\n      case 0x1EC6:\n        bufpush(0x1EC7);\n        break;\n      case 0x1EC8:\n        bufpush(0x1EC9);\n        break;\n      case 0x1ECA:\n        bufpush(0x1ECB);\n        break;\n      case 0x1ECC:\n        bufpush(0x1ECD);\n        break;\n      case 0x1ECE:\n        bufpush(0x1ECF);\n        break;\n      case 0x1ED0:\n        bufpush(0x1ED1);\n        break;\n      case 0x1ED2:\n        bufpush(0x1ED3);\n        break;\n      case 0x1ED4:\n        bufpush(0x1ED5);\n        break;\n      case 0x1ED6:\n        bufpush(0x1ED7);\n        break;\n      case 0x1ED8:\n        bufpush(0x1ED9);\n        break;\n      case 0x1EDA:\n        bufpush(0x1EDB);\n        break;\n      case 0x1EDC:\n        bufpush(0x1EDD);\n        break;\n      case 0x1EDE:\n        bufpush(0x1EDF);\n        break;\n      case 0x1EE0:\n        bufpush(0x1EE1);\n        break;\n      case 0x1EE2:\n        bufpush(0x1EE3);\n        break;\n      case 0x1EE4:\n        bufpush(0x1EE5);\n        break;\n      case 0x1EE6:\n        bufpush(0x1EE7);\n        break;\n      case 0x1EE8:\n        bufpush(0x1EE9);\n        break;\n      case 0x1EEA:\n        bufpush(0x1EEB);\n        break;\n      case 0x1EEC:\n        bufpush(0x1EED);\n        break;\n      case 0x1EEE:\n        bufpush(0x1EEF);\n        break;\n      case 0x1EF0:\n        bufpush(0x1EF1);\n        break;\n      case 0x1EF2:\n        bufpush(0x1EF3);\n        break;\n      case 0x1EF4:\n        bufpush(0x1EF5);\n        break;\n      case 0x1EF6:\n        bufpush(0x1EF7);\n        break;\n      case 0x1EF8:\n        bufpush(0x1EF9);\n        break;\n      case 0x1EFA:\n        bufpush(0x1EFB);\n        break;\n      case 0x1EFC:\n        bufpush(0x1EFD);\n        break;\n      case 0x1EFE:\n        bufpush(0x1EFF);\n        break;\n      case 0x1F08:\n        bufpush(0x1F00);\n        break;\n      case 0x1F09:\n        bufpush(0x1F01);\n        break;\n      case 0x1F0A:\n        bufpush(0x1F02);\n        break;\n      case 0x1F0B:\n        bufpush(0x1F03);\n        break;\n      case 0x1F0C:\n        bufpush(0x1F04);\n        break;\n      case 0x1F0D:\n        bufpush(0x1F05);\n        break;\n      case 0x1F0E:\n        bufpush(0x1F06);\n        break;\n      case 0x1F0F:\n        bufpush(0x1F07);\n        break;\n      case 0x1F18:\n        bufpush(0x1F10);\n        break;\n      case 0x1F19:\n        bufpush(0x1F11);\n        break;\n      case 0x1F1A:\n        bufpush(0x1F12);\n        break;\n      case 0x1F1B:\n        bufpush(0x1F13);\n        break;\n      case 0x1F1C:\n        bufpush(0x1F14);\n        break;\n      case 0x1F1D:\n        bufpush(0x1F15);\n        break;\n      case 0x1F28:\n        bufpush(0x1F20);\n        break;\n      case 0x1F29:\n        bufpush(0x1F21);\n        break;\n      case 0x1F2A:\n        bufpush(0x1F22);\n        break;\n      case 0x1F2B:\n        bufpush(0x1F23);\n        break;\n      case 0x1F2C:\n        bufpush(0x1F24);\n        break;\n      case 0x1F2D:\n        bufpush(0x1F25);\n        break;\n      case 0x1F2E:\n        bufpush(0x1F26);\n        break;\n      case 0x1F2F:\n        bufpush(0x1F27);\n        break;\n      case 0x1F38:\n        bufpush(0x1F30);\n        break;\n      case 0x1F39:\n        bufpush(0x1F31);\n        break;\n      case 0x1F3A:\n        bufpush(0x1F32);\n        break;\n      case 0x1F3B:\n        bufpush(0x1F33);\n        break;\n      case 0x1F3C:\n        bufpush(0x1F34);\n        break;\n      case 0x1F3D:\n        bufpush(0x1F35);\n        break;\n      case 0x1F3E:\n        bufpush(0x1F36);\n        break;\n      case 0x1F3F:\n        bufpush(0x1F37);\n        break;\n      case 0x1F48:\n        bufpush(0x1F40);\n        break;\n      case 0x1F49:\n        bufpush(0x1F41);\n        break;\n      case 0x1F4A:\n        bufpush(0x1F42);\n        break;\n      case 0x1F4B:\n        bufpush(0x1F43);\n        break;\n      case 0x1F4C:\n        bufpush(0x1F44);\n        break;\n      case 0x1F4D:\n        bufpush(0x1F45);\n        break;\n      case 0x1F50:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        break;\n      case 0x1F52:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0300);\n        break;\n      case 0x1F54:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0301);\n        break;\n      case 0x1F56:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0342);\n        break;\n      case 0x1F59:\n        bufpush(0x1F51);\n        break;\n      case 0x1F5B:\n        bufpush(0x1F53);\n        break;\n      case 0x1F5D:\n        bufpush(0x1F55);\n        break;\n      case 0x1F5F:\n        bufpush(0x1F57);\n        break;\n      case 0x1F68:\n        bufpush(0x1F60);\n        break;\n      case 0x1F69:\n        bufpush(0x1F61);\n        break;\n      case 0x1F6A:\n        bufpush(0x1F62);\n        break;\n      case 0x1F6B:\n        bufpush(0x1F63);\n        break;\n      case 0x1F6C:\n        bufpush(0x1F64);\n        break;\n      case 0x1F6D:\n        bufpush(0x1F65);\n        break;\n      case 0x1F6E:\n        bufpush(0x1F66);\n        break;\n      case 0x1F6F:\n        bufpush(0x1F67);\n        break;\n      case 0x1F80:\n        bufpush(0x1F00);\n        bufpush(0x03B9);\n        break;\n      case 0x1F81:\n        bufpush(0x1F01);\n        bufpush(0x03B9);\n        break;\n      case 0x1F82:\n        bufpush(0x1F02);\n        bufpush(0x03B9);\n        break;\n      case 0x1F83:\n        bufpush(0x1F03);\n        bufpush(0x03B9);\n        break;\n      case 0x1F84:\n        bufpush(0x1F04);\n        bufpush(0x03B9);\n        break;\n      case 0x1F85:\n        bufpush(0x1F05);\n        bufpush(0x03B9);\n        break;\n      case 0x1F86:\n        bufpush(0x1F06);\n        bufpush(0x03B9);\n        break;\n      case 0x1F87:\n        bufpush(0x1F07);\n        bufpush(0x03B9);\n        break;\n      case 0x1F88:\n        bufpush(0x1F00);\n        bufpush(0x03B9);\n        break;\n      case 0x1F89:\n        bufpush(0x1F01);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8A:\n        bufpush(0x1F02);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8B:\n        bufpush(0x1F03);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8C:\n        bufpush(0x1F04);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8D:\n        bufpush(0x1F05);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8E:\n        bufpush(0x1F06);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8F:\n        bufpush(0x1F07);\n        bufpush(0x03B9);\n        break;\n      case 0x1F90:\n        bufpush(0x1F20);\n        bufpush(0x03B9);\n        break;\n      case 0x1F91:\n        bufpush(0x1F21);\n        bufpush(0x03B9);\n        break;\n      case 0x1F92:\n        bufpush(0x1F22);\n        bufpush(0x03B9);\n        break;\n      case 0x1F93:\n        bufpush(0x1F23);\n        bufpush(0x03B9);\n        break;\n      case 0x1F94:\n        bufpush(0x1F24);\n        bufpush(0x03B9);\n        break;\n      case 0x1F95:\n        bufpush(0x1F25);\n        bufpush(0x03B9);\n        break;\n      case 0x1F96:\n        bufpush(0x1F26);\n        bufpush(0x03B9);\n        break;\n      case 0x1F97:\n        bufpush(0x1F27);\n        bufpush(0x03B9);\n        break;\n      case 0x1F98:\n        bufpush(0x1F20);\n        bufpush(0x03B9);\n        break;\n      case 0x1F99:\n        bufpush(0x1F21);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9A:\n        bufpush(0x1F22);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9B:\n        bufpush(0x1F23);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9C:\n        bufpush(0x1F24);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9D:\n        bufpush(0x1F25);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9E:\n        bufpush(0x1F26);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9F:\n        bufpush(0x1F27);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA0:\n        bufpush(0x1F60);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA1:\n        bufpush(0x1F61);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA2:\n        bufpush(0x1F62);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA3:\n        bufpush(0x1F63);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA4:\n        bufpush(0x1F64);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA5:\n        bufpush(0x1F65);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA6:\n        bufpush(0x1F66);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA7:\n        bufpush(0x1F67);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA8:\n        bufpush(0x1F60);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA9:\n        bufpush(0x1F61);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAA:\n        bufpush(0x1F62);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAB:\n        bufpush(0x1F63);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAC:\n        bufpush(0x1F64);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAD:\n        bufpush(0x1F65);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAE:\n        bufpush(0x1F66);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAF:\n        bufpush(0x1F67);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB2:\n        bufpush(0x1F70);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB3:\n        bufpush(0x03B1);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB4:\n        bufpush(0x03AC);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB6:\n        bufpush(0x03B1);\n        bufpush(0x0342);\n        break;\n      case 0x1FB7:\n        bufpush(0x03B1);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB8:\n        bufpush(0x1FB0);\n        break;\n      case 0x1FB9:\n        bufpush(0x1FB1);\n        break;\n      case 0x1FBA:\n        bufpush(0x1F70);\n        break;\n      case 0x1FBB:\n        bufpush(0x1F71);\n        break;\n      case 0x1FBC:\n        bufpush(0x03B1);\n        bufpush(0x03B9);\n        break;\n      case 0x1FBE:\n        bufpush(0x03B9);\n        break;\n      case 0x1FC2:\n        bufpush(0x1F74);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC3:\n        bufpush(0x03B7);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC4:\n        bufpush(0x03AE);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC6:\n        bufpush(0x03B7);\n        bufpush(0x0342);\n        break;\n      case 0x1FC7:\n        bufpush(0x03B7);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC8:\n        bufpush(0x1F72);\n        break;\n      case 0x1FC9:\n        bufpush(0x1F73);\n        break;\n      case 0x1FCA:\n        bufpush(0x1F74);\n        break;\n      case 0x1FCB:\n        bufpush(0x1F75);\n        break;\n      case 0x1FCC:\n        bufpush(0x03B7);\n        bufpush(0x03B9);\n        break;\n      case 0x1FD2:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0300);\n        break;\n      case 0x1FD3:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x1FD6:\n        bufpush(0x03B9);\n        bufpush(0x0342);\n        break;\n      case 0x1FD7:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0342);\n        break;\n      case 0x1FD8:\n        bufpush(0x1FD0);\n        break;\n      case 0x1FD9:\n        bufpush(0x1FD1);\n        break;\n      case 0x1FDA:\n        bufpush(0x1F76);\n        break;\n      case 0x1FDB:\n        bufpush(0x1F77);\n        break;\n      case 0x1FE2:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0300);\n        break;\n      case 0x1FE3:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x1FE4:\n        bufpush(0x03C1);\n        bufpush(0x0313);\n        break;\n      case 0x1FE6:\n        bufpush(0x03C5);\n        bufpush(0x0342);\n        break;\n      case 0x1FE7:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0342);\n        break;\n      case 0x1FE8:\n        bufpush(0x1FE0);\n        break;\n      case 0x1FE9:\n        bufpush(0x1FE1);\n        break;\n      case 0x1FEA:\n        bufpush(0x1F7A);\n        break;\n      case 0x1FEB:\n        bufpush(0x1F7B);\n        break;\n      case 0x1FEC:\n        bufpush(0x1FE5);\n        break;\n      case 0x1FF2:\n        bufpush(0x1F7C);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF3:\n        bufpush(0x03C9);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF4:\n        bufpush(0x03CE);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF6:\n        bufpush(0x03C9);\n        bufpush(0x0342);\n        break;\n      case 0x1FF7:\n        bufpush(0x03C9);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF8:\n        bufpush(0x1F78);\n        break;\n      case 0x1FF9:\n        bufpush(0x1F79);\n        break;\n      case 0x1FFA:\n        bufpush(0x1F7C);\n        break;\n      case 0x1FFB:\n        bufpush(0x1F7D);\n        break;\n      case 0x1FFC:\n        bufpush(0x03C9);\n        bufpush(0x03B9);\n        break;\n      case 0x2126:\n        bufpush(0x03C9);\n        break;\n      case 0x212A:\n        bufpush(0x006B);\n        break;\n      case 0x212B:\n        bufpush(0x00E5);\n        break;\n      case 0x2132:\n        bufpush(0x214E);\n        break;\n      case 0x2160:\n        bufpush(0x2170);\n        break;\n      case 0x2161:\n        bufpush(0x2171);\n        break;\n      case 0x2162:\n        bufpush(0x2172);\n        break;\n      case 0x2163:\n        bufpush(0x2173);\n        break;\n      case 0x2164:\n        bufpush(0x2174);\n        break;\n      case 0x2165:\n        bufpush(0x2175);\n        break;\n      case 0x2166:\n        bufpush(0x2176);\n        break;\n      case 0x2167:\n        bufpush(0x2177);\n        break;\n      case 0x2168:\n        bufpush(0x2178);\n        break;\n      case 0x2169:\n        bufpush(0x2179);\n        break;\n      case 0x216A:\n        bufpush(0x217A);\n        break;\n      case 0x216B:\n        bufpush(0x217B);\n        break;\n      case 0x216C:\n        bufpush(0x217C);\n        break;\n      case 0x216D:\n        bufpush(0x217D);\n        break;\n      case 0x216E:\n        bufpush(0x217E);\n        break;\n      case 0x216F:\n        bufpush(0x217F);\n        break;\n      case 0x2183:\n        bufpush(0x2184);\n        break;\n      case 0x24B6:\n        bufpush(0x24D0);\n        break;\n      case 0x24B7:\n        bufpush(0x24D1);\n        break;\n      case 0x24B8:\n        bufpush(0x24D2);\n        break;\n      case 0x24B9:\n        bufpush(0x24D3);\n        break;\n      case 0x24BA:\n        bufpush(0x24D4);\n        break;\n      case 0x24BB:\n        bufpush(0x24D5);\n        break;\n      case 0x24BC:\n        bufpush(0x24D6);\n        break;\n      case 0x24BD:\n        bufpush(0x24D7);\n        break;\n      case 0x24BE:\n        bufpush(0x24D8);\n        break;\n      case 0x24BF:\n        bufpush(0x24D9);\n        break;\n      case 0x24C0:\n        bufpush(0x24DA);\n        break;\n      case 0x24C1:\n        bufpush(0x24DB);\n        break;\n      case 0x24C2:\n        bufpush(0x24DC);\n        break;\n      case 0x24C3:\n        bufpush(0x24DD);\n        break;\n      case 0x24C4:\n        bufpush(0x24DE);\n        break;\n      case 0x24C5:\n        bufpush(0x24DF);\n        break;\n      case 0x24C6:\n        bufpush(0x24E0);\n        break;\n      case 0x24C7:\n        bufpush(0x24E1);\n        break;\n      case 0x24C8:\n        bufpush(0x24E2);\n        break;\n      case 0x24C9:\n        bufpush(0x24E3);\n        break;\n      case 0x24CA:\n        bufpush(0x24E4);\n        break;\n      case 0x24CB:\n        bufpush(0x24E5);\n        break;\n      case 0x24CC:\n        bufpush(0x24E6);\n        break;\n      case 0x24CD:\n        bufpush(0x24E7);\n        break;\n      case 0x24CE:\n        bufpush(0x24E8);\n        break;\n      case 0x24CF:\n        bufpush(0x24E9);\n        break;\n      case 0x2C00:\n        bufpush(0x2C30);\n        break;\n      case 0x2C01:\n        bufpush(0x2C31);\n        break;\n      case 0x2C02:\n        bufpush(0x2C32);\n        break;\n      case 0x2C03:\n        bufpush(0x2C33);\n        break;\n      case 0x2C04:\n        bufpush(0x2C34);\n        break;\n      case 0x2C05:\n        bufpush(0x2C35);\n        break;\n      case 0x2C06:\n        bufpush(0x2C36);\n        break;\n      case 0x2C07:\n        bufpush(0x2C37);\n        break;\n      case 0x2C08:\n        bufpush(0x2C38);\n        break;\n      case 0x2C09:\n        bufpush(0x2C39);\n        break;\n      case 0x2C0A:\n        bufpush(0x2C3A);\n        break;\n      case 0x2C0B:\n        bufpush(0x2C3B);\n        break;\n      case 0x2C0C:\n        bufpush(0x2C3C);\n        break;\n      case 0x2C0D:\n        bufpush(0x2C3D);\n        break;\n      case 0x2C0E:\n        bufpush(0x2C3E);\n        break;\n      case 0x2C0F:\n        bufpush(0x2C3F);\n        break;\n      case 0x2C10:\n        bufpush(0x2C40);\n        break;\n      case 0x2C11:\n        bufpush(0x2C41);\n        break;\n      case 0x2C12:\n        bufpush(0x2C42);\n        break;\n      case 0x2C13:\n        bufpush(0x2C43);\n        break;\n      case 0x2C14:\n        bufpush(0x2C44);\n        break;\n      case 0x2C15:\n        bufpush(0x2C45);\n        break;\n      case 0x2C16:\n        bufpush(0x2C46);\n        break;\n      case 0x2C17:\n        bufpush(0x2C47);\n        break;\n      case 0x2C18:\n        bufpush(0x2C48);\n        break;\n      case 0x2C19:\n        bufpush(0x2C49);\n        break;\n      case 0x2C1A:\n        bufpush(0x2C4A);\n        break;\n      case 0x2C1B:\n        bufpush(0x2C4B);\n        break;\n      case 0x2C1C:\n        bufpush(0x2C4C);\n        break;\n      case 0x2C1D:\n        bufpush(0x2C4D);\n        break;\n      case 0x2C1E:\n        bufpush(0x2C4E);\n        break;\n      case 0x2C1F:\n        bufpush(0x2C4F);\n        break;\n      case 0x2C20:\n        bufpush(0x2C50);\n        break;\n      case 0x2C21:\n        bufpush(0x2C51);\n        break;\n      case 0x2C22:\n        bufpush(0x2C52);\n        break;\n      case 0x2C23:\n        bufpush(0x2C53);\n        break;\n      case 0x2C24:\n        bufpush(0x2C54);\n        break;\n      case 0x2C25:\n        bufpush(0x2C55);\n        break;\n      case 0x2C26:\n        bufpush(0x2C56);\n        break;\n      case 0x2C27:\n        bufpush(0x2C57);\n        break;\n      case 0x2C28:\n        bufpush(0x2C58);\n        break;\n      case 0x2C29:\n        bufpush(0x2C59);\n        break;\n      case 0x2C2A:\n        bufpush(0x2C5A);\n        break;\n      case 0x2C2B:\n        bufpush(0x2C5B);\n        break;\n      case 0x2C2C:\n        bufpush(0x2C5C);\n        break;\n      case 0x2C2D:\n        bufpush(0x2C5D);\n        break;\n      case 0x2C2E:\n        bufpush(0x2C5E);\n        break;\n      case 0x2C60:\n        bufpush(0x2C61);\n        break;\n      case 0x2C62:\n        bufpush(0x026B);\n        break;\n      case 0x2C63:\n        bufpush(0x1D7D);\n        break;\n      case 0x2C64:\n        bufpush(0x027D);\n        break;\n      case 0x2C67:\n        bufpush(0x2C68);\n        break;\n      case 0x2C69:\n        bufpush(0x2C6A);\n        break;\n      case 0x2C6B:\n        bufpush(0x2C6C);\n        break;\n      case 0x2C6D:\n        bufpush(0x0251);\n        break;\n      case 0x2C6E:\n        bufpush(0x0271);\n        break;\n      case 0x2C6F:\n        bufpush(0x0250);\n        break;\n      case 0x2C70:\n        bufpush(0x0252);\n        break;\n      case 0x2C72:\n        bufpush(0x2C73);\n        break;\n      case 0x2C75:\n        bufpush(0x2C76);\n        break;\n      case 0x2C7E:\n        bufpush(0x023F);\n        break;\n      case 0x2C7F:\n        bufpush(0x0240);\n        break;\n      case 0x2C80:\n        bufpush(0x2C81);\n        break;\n      case 0x2C82:\n        bufpush(0x2C83);\n        break;\n      case 0x2C84:\n        bufpush(0x2C85);\n        break;\n      case 0x2C86:\n        bufpush(0x2C87);\n        break;\n      case 0x2C88:\n        bufpush(0x2C89);\n        break;\n      case 0x2C8A:\n        bufpush(0x2C8B);\n        break;\n      case 0x2C8C:\n        bufpush(0x2C8D);\n        break;\n      case 0x2C8E:\n        bufpush(0x2C8F);\n        break;\n      case 0x2C90:\n        bufpush(0x2C91);\n        break;\n      case 0x2C92:\n        bufpush(0x2C93);\n        break;\n      case 0x2C94:\n        bufpush(0x2C95);\n        break;\n      case 0x2C96:\n        bufpush(0x2C97);\n        break;\n      case 0x2C98:\n        bufpush(0x2C99);\n        break;\n      case 0x2C9A:\n        bufpush(0x2C9B);\n        break;\n      case 0x2C9C:\n        bufpush(0x2C9D);\n        break;\n      case 0x2C9E:\n        bufpush(0x2C9F);\n        break;\n      case 0x2CA0:\n        bufpush(0x2CA1);\n        break;\n      case 0x2CA2:\n        bufpush(0x2CA3);\n        break;\n      case 0x2CA4:\n        bufpush(0x2CA5);\n        break;\n      case 0x2CA6:\n        bufpush(0x2CA7);\n        break;\n      case 0x2CA8:\n        bufpush(0x2CA9);\n        break;\n      case 0x2CAA:\n        bufpush(0x2CAB);\n        break;\n      case 0x2CAC:\n        bufpush(0x2CAD);\n        break;\n      case 0x2CAE:\n        bufpush(0x2CAF);\n        break;\n      case 0x2CB0:\n        bufpush(0x2CB1);\n        break;\n      case 0x2CB2:\n        bufpush(0x2CB3);\n        break;\n      case 0x2CB4:\n        bufpush(0x2CB5);\n        break;\n      case 0x2CB6:\n        bufpush(0x2CB7);\n        break;\n      case 0x2CB8:\n        bufpush(0x2CB9);\n        break;\n      case 0x2CBA:\n        bufpush(0x2CBB);\n        break;\n      case 0x2CBC:\n        bufpush(0x2CBD);\n        break;\n      case 0x2CBE:\n        bufpush(0x2CBF);\n        break;\n      case 0x2CC0:\n        bufpush(0x2CC1);\n        break;\n      case 0x2CC2:\n        bufpush(0x2CC3);\n        break;\n      case 0x2CC4:\n        bufpush(0x2CC5);\n        break;\n      case 0x2CC6:\n        bufpush(0x2CC7);\n        break;\n      case 0x2CC8:\n        bufpush(0x2CC9);\n        break;\n      case 0x2CCA:\n        bufpush(0x2CCB);\n        break;\n      case 0x2CCC:\n        bufpush(0x2CCD);\n        break;\n      case 0x2CCE:\n        bufpush(0x2CCF);\n        break;\n      case 0x2CD0:\n        bufpush(0x2CD1);\n        break;\n      case 0x2CD2:\n        bufpush(0x2CD3);\n        break;\n      case 0x2CD4:\n        bufpush(0x2CD5);\n        break;\n      case 0x2CD6:\n        bufpush(0x2CD7);\n        break;\n      case 0x2CD8:\n        bufpush(0x2CD9);\n        break;\n      case 0x2CDA:\n        bufpush(0x2CDB);\n        break;\n      case 0x2CDC:\n        bufpush(0x2CDD);\n        break;\n      case 0x2CDE:\n        bufpush(0x2CDF);\n        break;\n      case 0x2CE0:\n        bufpush(0x2CE1);\n        break;\n      case 0x2CE2:\n        bufpush(0x2CE3);\n        break;\n      case 0x2CEB:\n        bufpush(0x2CEC);\n        break;\n      case 0x2CED:\n        bufpush(0x2CEE);\n        break;\n      case 0x2CF2:\n        bufpush(0x2CF3);\n        break;\n      case 0xA640:\n        bufpush(0xA641);\n        break;\n      case 0xA642:\n        bufpush(0xA643);\n        break;\n      case 0xA644:\n        bufpush(0xA645);\n        break;\n      case 0xA646:\n        bufpush(0xA647);\n        break;\n      case 0xA648:\n        bufpush(0xA649);\n        break;\n      case 0xA64A:\n        bufpush(0xA64B);\n        break;\n      case 0xA64C:\n        bufpush(0xA64D);\n        break;\n      case 0xA64E:\n        bufpush(0xA64F);\n        break;\n      case 0xA650:\n        bufpush(0xA651);\n        break;\n      case 0xA652:\n        bufpush(0xA653);\n        break;\n      case 0xA654:\n        bufpush(0xA655);\n        break;\n      case 0xA656:\n        bufpush(0xA657);\n        break;\n      case 0xA658:\n        bufpush(0xA659);\n        break;\n      case 0xA65A:\n        bufpush(0xA65B);\n        break;\n      case 0xA65C:\n        bufpush(0xA65D);\n        break;\n      case 0xA65E:\n        bufpush(0xA65F);\n        break;\n      case 0xA660:\n        bufpush(0xA661);\n        break;\n      case 0xA662:\n        bufpush(0xA663);\n        break;\n      case 0xA664:\n        bufpush(0xA665);\n        break;\n      case 0xA666:\n        bufpush(0xA667);\n        break;\n      case 0xA668:\n        bufpush(0xA669);\n        break;\n      case 0xA66A:\n        bufpush(0xA66B);\n        break;\n      case 0xA66C:\n        bufpush(0xA66D);\n        break;\n      case 0xA680:\n        bufpush(0xA681);\n        break;\n      case 0xA682:\n        bufpush(0xA683);\n        break;\n      case 0xA684:\n        bufpush(0xA685);\n        break;\n      case 0xA686:\n        bufpush(0xA687);\n        break;\n      case 0xA688:\n        bufpush(0xA689);\n        break;\n      case 0xA68A:\n        bufpush(0xA68B);\n        break;\n      case 0xA68C:\n        bufpush(0xA68D);\n        break;\n      case 0xA68E:\n        bufpush(0xA68F);\n        break;\n      case 0xA690:\n        bufpush(0xA691);\n        break;\n      case 0xA692:\n        bufpush(0xA693);\n        break;\n      case 0xA694:\n        bufpush(0xA695);\n        break;\n      case 0xA696:\n        bufpush(0xA697);\n        break;\n      case 0xA698:\n        bufpush(0xA699);\n        break;\n      case 0xA69A:\n        bufpush(0xA69B);\n        break;\n      case 0xA722:\n        bufpush(0xA723);\n        break;\n      case 0xA724:\n        bufpush(0xA725);\n        break;\n      case 0xA726:\n        bufpush(0xA727);\n        break;\n      case 0xA728:\n        bufpush(0xA729);\n        break;\n      case 0xA72A:\n        bufpush(0xA72B);\n        break;\n      case 0xA72C:\n        bufpush(0xA72D);\n        break;\n      case 0xA72E:\n        bufpush(0xA72F);\n        break;\n      case 0xA732:\n        bufpush(0xA733);\n        break;\n      case 0xA734:\n        bufpush(0xA735);\n        break;\n      case 0xA736:\n        bufpush(0xA737);\n        break;\n      case 0xA738:\n        bufpush(0xA739);\n        break;\n      case 0xA73A:\n        bufpush(0xA73B);\n        break;\n      case 0xA73C:\n        bufpush(0xA73D);\n        break;\n      case 0xA73E:\n        bufpush(0xA73F);\n        break;\n      case 0xA740:\n        bufpush(0xA741);\n        break;\n      case 0xA742:\n        bufpush(0xA743);\n        break;\n      case 0xA744:\n        bufpush(0xA745);\n        break;\n      case 0xA746:\n        bufpush(0xA747);\n        break;\n      case 0xA748:\n        bufpush(0xA749);\n        break;\n      case 0xA74A:\n        bufpush(0xA74B);\n        break;\n      case 0xA74C:\n        bufpush(0xA74D);\n        break;\n      case 0xA74E:\n        bufpush(0xA74F);\n        break;\n      case 0xA750:\n        bufpush(0xA751);\n        break;\n      case 0xA752:\n        bufpush(0xA753);\n        break;\n      case 0xA754:\n        bufpush(0xA755);\n        break;\n      case 0xA756:\n        bufpush(0xA757);\n        break;\n      case 0xA758:\n        bufpush(0xA759);\n        break;\n      case 0xA75A:\n        bufpush(0xA75B);\n        break;\n      case 0xA75C:\n        bufpush(0xA75D);\n        break;\n      case 0xA75E:\n        bufpush(0xA75F);\n        break;\n      case 0xA760:\n        bufpush(0xA761);\n        break;\n      case 0xA762:\n        bufpush(0xA763);\n        break;\n      case 0xA764:\n        bufpush(0xA765);\n        break;\n      case 0xA766:\n        bufpush(0xA767);\n        break;\n      case 0xA768:\n        bufpush(0xA769);\n        break;\n      case 0xA76A:\n        bufpush(0xA76B);\n        break;\n      case 0xA76C:\n        bufpush(0xA76D);\n        break;\n      case 0xA76E:\n        bufpush(0xA76F);\n        break;\n      case 0xA779:\n        bufpush(0xA77A);\n        break;\n      case 0xA77B:\n        bufpush(0xA77C);\n        break;\n      case 0xA77D:\n        bufpush(0x1D79);\n        break;\n      case 0xA77E:\n        bufpush(0xA77F);\n        break;\n      case 0xA780:\n        bufpush(0xA781);\n        break;\n      case 0xA782:\n        bufpush(0xA783);\n        break;\n      case 0xA784:\n        bufpush(0xA785);\n        break;\n      case 0xA786:\n        bufpush(0xA787);\n        break;\n      case 0xA78B:\n        bufpush(0xA78C);\n        break;\n      case 0xA78D:\n        bufpush(0x0265);\n        break;\n      case 0xA790:\n        bufpush(0xA791);\n        break;\n      case 0xA792:\n        bufpush(0xA793);\n        break;\n      case 0xA796:\n        bufpush(0xA797);\n        break;\n      case 0xA798:\n        bufpush(0xA799);\n        break;\n      case 0xA79A:\n        bufpush(0xA79B);\n        break;\n      case 0xA79C:\n        bufpush(0xA79D);\n        break;\n      case 0xA79E:\n        bufpush(0xA79F);\n        break;\n      case 0xA7A0:\n        bufpush(0xA7A1);\n        break;\n      case 0xA7A2:\n        bufpush(0xA7A3);\n        break;\n      case 0xA7A4:\n        bufpush(0xA7A5);\n        break;\n      case 0xA7A6:\n        bufpush(0xA7A7);\n        break;\n      case 0xA7A8:\n        bufpush(0xA7A9);\n        break;\n      case 0xA7AA:\n        bufpush(0x0266);\n        break;\n      case 0xA7AB:\n        bufpush(0x025C);\n        break;\n      case 0xA7AC:\n        bufpush(0x0261);\n        break;\n      case 0xA7AD:\n        bufpush(0x026C);\n        break;\n      case 0xA7AE:\n        bufpush(0x026A);\n        break;\n      case 0xA7B0:\n        bufpush(0x029E);\n        break;\n      case 0xA7B1:\n        bufpush(0x0287);\n        break;\n      case 0xA7B2:\n        bufpush(0x029D);\n        break;\n      case 0xA7B3:\n        bufpush(0xAB53);\n        break;\n      case 0xA7B4:\n        bufpush(0xA7B5);\n        break;\n      case 0xA7B6:\n        bufpush(0xA7B7);\n        break;\n      case 0xAB70:\n        bufpush(0x13A0);\n        break;\n      case 0xAB71:\n        bufpush(0x13A1);\n        break;\n      case 0xAB72:\n        bufpush(0x13A2);\n        break;\n      case 0xAB73:\n        bufpush(0x13A3);\n        break;\n      case 0xAB74:\n        bufpush(0x13A4);\n        break;\n      case 0xAB75:\n        bufpush(0x13A5);\n        break;\n      case 0xAB76:\n        bufpush(0x13A6);\n        break;\n      case 0xAB77:\n        bufpush(0x13A7);\n        break;\n      case 0xAB78:\n        bufpush(0x13A8);\n        break;\n      case 0xAB79:\n        bufpush(0x13A9);\n        break;\n      case 0xAB7A:\n        bufpush(0x13AA);\n        break;\n      case 0xAB7B:\n        bufpush(0x13AB);\n        break;\n      case 0xAB7C:\n        bufpush(0x13AC);\n        break;\n      case 0xAB7D:\n        bufpush(0x13AD);\n        break;\n      case 0xAB7E:\n        bufpush(0x13AE);\n        break;\n      case 0xAB7F:\n        bufpush(0x13AF);\n        break;\n      case 0xAB80:\n        bufpush(0x13B0);\n        break;\n      case 0xAB81:\n        bufpush(0x13B1);\n        break;\n      case 0xAB82:\n        bufpush(0x13B2);\n        break;\n      case 0xAB83:\n        bufpush(0x13B3);\n        break;\n      case 0xAB84:\n        bufpush(0x13B4);\n        break;\n      case 0xAB85:\n        bufpush(0x13B5);\n        break;\n      case 0xAB86:\n        bufpush(0x13B6);\n        break;\n      case 0xAB87:\n        bufpush(0x13B7);\n        break;\n      case 0xAB88:\n        bufpush(0x13B8);\n        break;\n      case 0xAB89:\n        bufpush(0x13B9);\n        break;\n      case 0xAB8A:\n        bufpush(0x13BA);\n        break;\n      case 0xAB8B:\n        bufpush(0x13BB);\n        break;\n      case 0xAB8C:\n        bufpush(0x13BC);\n        break;\n      case 0xAB8D:\n        bufpush(0x13BD);\n        break;\n      case 0xAB8E:\n        bufpush(0x13BE);\n        break;\n      case 0xAB8F:\n        bufpush(0x13BF);\n        break;\n      case 0xAB90:\n        bufpush(0x13C0);\n        break;\n      case 0xAB91:\n        bufpush(0x13C1);\n        break;\n      case 0xAB92:\n        bufpush(0x13C2);\n        break;\n      case 0xAB93:\n        bufpush(0x13C3);\n        break;\n      case 0xAB94:\n        bufpush(0x13C4);\n        break;\n      case 0xAB95:\n        bufpush(0x13C5);\n        break;\n      case 0xAB96:\n        bufpush(0x13C6);\n        break;\n      case 0xAB97:\n        bufpush(0x13C7);\n        break;\n      case 0xAB98:\n        bufpush(0x13C8);\n        break;\n      case 0xAB99:\n        bufpush(0x13C9);\n        break;\n      case 0xAB9A:\n        bufpush(0x13CA);\n        break;\n      case 0xAB9B:\n        bufpush(0x13CB);\n        break;\n      case 0xAB9C:\n        bufpush(0x13CC);\n        break;\n      case 0xAB9D:\n        bufpush(0x13CD);\n        break;\n      case 0xAB9E:\n        bufpush(0x13CE);\n        break;\n      case 0xAB9F:\n        bufpush(0x13CF);\n        break;\n      case 0xABA0:\n        bufpush(0x13D0);\n        break;\n      case 0xABA1:\n        bufpush(0x13D1);\n        break;\n      case 0xABA2:\n        bufpush(0x13D2);\n        break;\n      case 0xABA3:\n        bufpush(0x13D3);\n        break;\n      case 0xABA4:\n        bufpush(0x13D4);\n        break;\n      case 0xABA5:\n        bufpush(0x13D5);\n        break;\n      case 0xABA6:\n        bufpush(0x13D6);\n        break;\n      case 0xABA7:\n        bufpush(0x13D7);\n        break;\n      case 0xABA8:\n        bufpush(0x13D8);\n        break;\n      case 0xABA9:\n        bufpush(0x13D9);\n        break;\n      case 0xABAA:\n        bufpush(0x13DA);\n        break;\n      case 0xABAB:\n        bufpush(0x13DB);\n        break;\n      case 0xABAC:\n        bufpush(0x13DC);\n        break;\n      case 0xABAD:\n        bufpush(0x13DD);\n        break;\n      case 0xABAE:\n        bufpush(0x13DE);\n        break;\n      case 0xABAF:\n        bufpush(0x13DF);\n        break;\n      case 0xABB0:\n        bufpush(0x13E0);\n        break;\n      case 0xABB1:\n        bufpush(0x13E1);\n        break;\n      case 0xABB2:\n        bufpush(0x13E2);\n        break;\n      case 0xABB3:\n        bufpush(0x13E3);\n        break;\n      case 0xABB4:\n        bufpush(0x13E4);\n        break;\n      case 0xABB5:\n        bufpush(0x13E5);\n        break;\n      case 0xABB6:\n        bufpush(0x13E6);\n        break;\n      case 0xABB7:\n        bufpush(0x13E7);\n        break;\n      case 0xABB8:\n        bufpush(0x13E8);\n        break;\n      case 0xABB9:\n        bufpush(0x13E9);\n        break;\n      case 0xABBA:\n        bufpush(0x13EA);\n        break;\n      case 0xABBB:\n        bufpush(0x13EB);\n        break;\n      case 0xABBC:\n        bufpush(0x13EC);\n        break;\n      case 0xABBD:\n        bufpush(0x13ED);\n        break;\n      case 0xABBE:\n        bufpush(0x13EE);\n        break;\n      case 0xABBF:\n        bufpush(0x13EF);\n        break;\n      case 0xFB00:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        break;\n      case 0xFB01:\n        bufpush(0x0066);\n        bufpush(0x0069);\n        break;\n      case 0xFB02:\n        bufpush(0x0066);\n        bufpush(0x006C);\n        break;\n      case 0xFB03:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        bufpush(0x0069);\n        break;\n      case 0xFB04:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        bufpush(0x006C);\n        break;\n      case 0xFB05:\n        bufpush(0x0073);\n        bufpush(0x0074);\n        break;\n      case 0xFB06:\n        bufpush(0x0073);\n        bufpush(0x0074);\n        break;\n      case 0xFB13:\n        bufpush(0x0574);\n        bufpush(0x0576);\n        break;\n      case 0xFB14:\n        bufpush(0x0574);\n        bufpush(0x0565);\n        break;\n      case 0xFB15:\n        bufpush(0x0574);\n        bufpush(0x056B);\n        break;\n      case 0xFB16:\n        bufpush(0x057E);\n        bufpush(0x0576);\n        break;\n      case 0xFB17:\n        bufpush(0x0574);\n        bufpush(0x056D);\n        break;\n      case 0xFF21:\n        bufpush(0xFF41);\n        break;\n      case 0xFF22:\n        bufpush(0xFF42);\n        break;\n      case 0xFF23:\n        bufpush(0xFF43);\n        break;\n      case 0xFF24:\n        bufpush(0xFF44);\n        break;\n      case 0xFF25:\n        bufpush(0xFF45);\n        break;\n      case 0xFF26:\n        bufpush(0xFF46);\n        break;\n      case 0xFF27:\n        bufpush(0xFF47);\n        break;\n      case 0xFF28:\n        bufpush(0xFF48);\n        break;\n      case 0xFF29:\n        bufpush(0xFF49);\n        break;\n      case 0xFF2A:\n        bufpush(0xFF4A);\n        break;\n      case 0xFF2B:\n        bufpush(0xFF4B);\n        break;\n      case 0xFF2C:\n        bufpush(0xFF4C);\n        break;\n      case 0xFF2D:\n        bufpush(0xFF4D);\n        break;\n      case 0xFF2E:\n        bufpush(0xFF4E);\n        break;\n      case 0xFF2F:\n        bufpush(0xFF4F);\n        break;\n      case 0xFF30:\n        bufpush(0xFF50);\n        break;\n      case 0xFF31:\n        bufpush(0xFF51);\n        break;\n      case 0xFF32:\n        bufpush(0xFF52);\n        break;\n      case 0xFF33:\n        bufpush(0xFF53);\n        break;\n      case 0xFF34:\n        bufpush(0xFF54);\n        break;\n      case 0xFF35:\n        bufpush(0xFF55);\n        break;\n      case 0xFF36:\n        bufpush(0xFF56);\n        break;\n      case 0xFF37:\n        bufpush(0xFF57);\n        break;\n      case 0xFF38:\n        bufpush(0xFF58);\n        break;\n      case 0xFF39:\n        bufpush(0xFF59);\n        break;\n      case 0xFF3A:\n        bufpush(0xFF5A);\n        break;\n      case 0x10400:\n        bufpush(0x10428);\n        break;\n      case 0x10401:\n        bufpush(0x10429);\n        break;\n      case 0x10402:\n        bufpush(0x1042A);\n        break;\n      case 0x10403:\n        bufpush(0x1042B);\n        break;\n      case 0x10404:\n        bufpush(0x1042C);\n        break;\n      case 0x10405:\n        bufpush(0x1042D);\n        break;\n      case 0x10406:\n        bufpush(0x1042E);\n        break;\n      case 0x10407:\n        bufpush(0x1042F);\n        break;\n      case 0x10408:\n        bufpush(0x10430);\n        break;\n      case 0x10409:\n        bufpush(0x10431);\n        break;\n      case 0x1040A:\n        bufpush(0x10432);\n        break;\n      case 0x1040B:\n        bufpush(0x10433);\n        break;\n      case 0x1040C:\n        bufpush(0x10434);\n        break;\n      case 0x1040D:\n        bufpush(0x10435);\n        break;\n      case 0x1040E:\n        bufpush(0x10436);\n        break;\n      case 0x1040F:\n        bufpush(0x10437);\n        break;\n      case 0x10410:\n        bufpush(0x10438);\n        break;\n      case 0x10411:\n        bufpush(0x10439);\n        break;\n      case 0x10412:\n        bufpush(0x1043A);\n        break;\n      case 0x10413:\n        bufpush(0x1043B);\n        break;\n      case 0x10414:\n        bufpush(0x1043C);\n        break;\n      case 0x10415:\n        bufpush(0x1043D);\n        break;\n      case 0x10416:\n        bufpush(0x1043E);\n        break;\n      case 0x10417:\n        bufpush(0x1043F);\n        break;\n      case 0x10418:\n        bufpush(0x10440);\n        break;\n      case 0x10419:\n        bufpush(0x10441);\n        break;\n      case 0x1041A:\n        bufpush(0x10442);\n        break;\n      case 0x1041B:\n        bufpush(0x10443);\n        break;\n      case 0x1041C:\n        bufpush(0x10444);\n        break;\n      case 0x1041D:\n        bufpush(0x10445);\n        break;\n      case 0x1041E:\n        bufpush(0x10446);\n        break;\n      case 0x1041F:\n        bufpush(0x10447);\n        break;\n      case 0x10420:\n        bufpush(0x10448);\n        break;\n      case 0x10421:\n        bufpush(0x10449);\n        break;\n      case 0x10422:\n        bufpush(0x1044A);\n        break;\n      case 0x10423:\n        bufpush(0x1044B);\n        break;\n      case 0x10424:\n        bufpush(0x1044C);\n        break;\n      case 0x10425:\n        bufpush(0x1044D);\n        break;\n      case 0x10426:\n        bufpush(0x1044E);\n        break;\n      case 0x10427:\n        bufpush(0x1044F);\n        break;\n      case 0x104B0:\n        bufpush(0x104D8);\n        break;\n      case 0x104B1:\n        bufpush(0x104D9);\n        break;\n      case 0x104B2:\n        bufpush(0x104DA);\n        break;\n      case 0x104B3:\n        bufpush(0x104DB);\n        break;\n      case 0x104B4:\n        bufpush(0x104DC);\n        break;\n      case 0x104B5:\n        bufpush(0x104DD);\n        break;\n      case 0x104B6:\n        bufpush(0x104DE);\n        break;\n      case 0x104B7:\n        bufpush(0x104DF);\n        break;\n      case 0x104B8:\n        bufpush(0x104E0);\n        break;\n      case 0x104B9:\n        bufpush(0x104E1);\n        break;\n      case 0x104BA:\n        bufpush(0x104E2);\n        break;\n      case 0x104BB:\n        bufpush(0x104E3);\n        break;\n      case 0x104BC:\n        bufpush(0x104E4);\n        break;\n      case 0x104BD:\n        bufpush(0x104E5);\n        break;\n      case 0x104BE:\n        bufpush(0x104E6);\n        break;\n      case 0x104BF:\n        bufpush(0x104E7);\n        break;\n      case 0x104C0:\n        bufpush(0x104E8);\n        break;\n      case 0x104C1:\n        bufpush(0x104E9);\n        break;\n      case 0x104C2:\n        bufpush(0x104EA);\n        break;\n      case 0x104C3:\n        bufpush(0x104EB);\n        break;\n      case 0x104C4:\n        bufpush(0x104EC);\n        break;\n      case 0x104C5:\n        bufpush(0x104ED);\n        break;\n      case 0x104C6:\n        bufpush(0x104EE);\n        break;\n      case 0x104C7:\n        bufpush(0x104EF);\n        break;\n      case 0x104C8:\n        bufpush(0x104F0);\n        break;\n      case 0x104C9:\n        bufpush(0x104F1);\n        break;\n      case 0x104CA:\n        bufpush(0x104F2);\n        break;\n      case 0x104CB:\n        bufpush(0x104F3);\n        break;\n      case 0x104CC:\n        bufpush(0x104F4);\n        break;\n      case 0x104CD:\n        bufpush(0x104F5);\n        break;\n      case 0x104CE:\n        bufpush(0x104F6);\n        break;\n      case 0x104CF:\n        bufpush(0x104F7);\n        break;\n      case 0x104D0:\n        bufpush(0x104F8);\n        break;\n      case 0x104D1:\n        bufpush(0x104F9);\n        break;\n      case 0x104D2:\n        bufpush(0x104FA);\n        break;\n      case 0x104D3:\n        bufpush(0x104FB);\n        break;\n      case 0x10C80:\n        bufpush(0x10CC0);\n        break;\n      case 0x10C81:\n        bufpush(0x10CC1);\n        break;\n      case 0x10C82:\n        bufpush(0x10CC2);\n        break;\n      case 0x10C83:\n        bufpush(0x10CC3);\n        break;\n      case 0x10C84:\n        bufpush(0x10CC4);\n        break;\n      case 0x10C85:\n        bufpush(0x10CC5);\n        break;\n      case 0x10C86:\n        bufpush(0x10CC6);\n        break;\n      case 0x10C87:\n        bufpush(0x10CC7);\n        break;\n      case 0x10C88:\n        bufpush(0x10CC8);\n        break;\n      case 0x10C89:\n        bufpush(0x10CC9);\n        break;\n      case 0x10C8A:\n        bufpush(0x10CCA);\n        break;\n      case 0x10C8B:\n        bufpush(0x10CCB);\n        break;\n      case 0x10C8C:\n        bufpush(0x10CCC);\n        break;\n      case 0x10C8D:\n        bufpush(0x10CCD);\n        break;\n      case 0x10C8E:\n        bufpush(0x10CCE);\n        break;\n      case 0x10C8F:\n        bufpush(0x10CCF);\n        break;\n      case 0x10C90:\n        bufpush(0x10CD0);\n        break;\n      case 0x10C91:\n        bufpush(0x10CD1);\n        break;\n      case 0x10C92:\n        bufpush(0x10CD2);\n        break;\n      case 0x10C93:\n        bufpush(0x10CD3);\n        break;\n      case 0x10C94:\n        bufpush(0x10CD4);\n        break;\n      case 0x10C95:\n        bufpush(0x10CD5);\n        break;\n      case 0x10C96:\n        bufpush(0x10CD6);\n        break;\n      case 0x10C97:\n        bufpush(0x10CD7);\n        break;\n      case 0x10C98:\n        bufpush(0x10CD8);\n        break;\n      case 0x10C99:\n        bufpush(0x10CD9);\n        break;\n      case 0x10C9A:\n        bufpush(0x10CDA);\n        break;\n      case 0x10C9B:\n        bufpush(0x10CDB);\n        break;\n      case 0x10C9C:\n        bufpush(0x10CDC);\n        break;\n      case 0x10C9D:\n        bufpush(0x10CDD);\n        break;\n      case 0x10C9E:\n        bufpush(0x10CDE);\n        break;\n      case 0x10C9F:\n        bufpush(0x10CDF);\n        break;\n      case 0x10CA0:\n        bufpush(0x10CE0);\n        break;\n      case 0x10CA1:\n        bufpush(0x10CE1);\n        break;\n      case 0x10CA2:\n        bufpush(0x10CE2);\n        break;\n      case 0x10CA3:\n        bufpush(0x10CE3);\n        break;\n      case 0x10CA4:\n        bufpush(0x10CE4);\n        break;\n      case 0x10CA5:\n        bufpush(0x10CE5);\n        break;\n      case 0x10CA6:\n        bufpush(0x10CE6);\n        break;\n      case 0x10CA7:\n        bufpush(0x10CE7);\n        break;\n      case 0x10CA8:\n        bufpush(0x10CE8);\n        break;\n      case 0x10CA9:\n        bufpush(0x10CE9);\n        break;\n      case 0x10CAA:\n        bufpush(0x10CEA);\n        break;\n      case 0x10CAB:\n        bufpush(0x10CEB);\n        break;\n      case 0x10CAC:\n        bufpush(0x10CEC);\n        break;\n      case 0x10CAD:\n        bufpush(0x10CED);\n        break;\n      case 0x10CAE:\n        bufpush(0x10CEE);\n        break;\n      case 0x10CAF:\n        bufpush(0x10CEF);\n        break;\n      case 0x10CB0:\n        bufpush(0x10CF0);\n        break;\n      case 0x10CB1:\n        bufpush(0x10CF1);\n        break;\n      case 0x10CB2:\n        bufpush(0x10CF2);\n        break;\n      case 0x118A0:\n        bufpush(0x118C0);\n        break;\n      case 0x118A1:\n        bufpush(0x118C1);\n        break;\n      case 0x118A2:\n        bufpush(0x118C2);\n        break;\n      case 0x118A3:\n        bufpush(0x118C3);\n        break;\n      case 0x118A4:\n        bufpush(0x118C4);\n        break;\n      case 0x118A5:\n        bufpush(0x118C5);\n        break;\n      case 0x118A6:\n        bufpush(0x118C6);\n        break;\n      case 0x118A7:\n        bufpush(0x118C7);\n        break;\n      case 0x118A8:\n        bufpush(0x118C8);\n        break;\n      case 0x118A9:\n        bufpush(0x118C9);\n        break;\n      case 0x118AA:\n        bufpush(0x118CA);\n        break;\n      case 0x118AB:\n        bufpush(0x118CB);\n        break;\n      case 0x118AC:\n        bufpush(0x118CC);\n        break;\n      case 0x118AD:\n        bufpush(0x118CD);\n        break;\n      case 0x118AE:\n        bufpush(0x118CE);\n        break;\n      case 0x118AF:\n        bufpush(0x118CF);\n        break;\n      case 0x118B0:\n        bufpush(0x118D0);\n        break;\n      case 0x118B1:\n        bufpush(0x118D1);\n        break;\n      case 0x118B2:\n        bufpush(0x118D2);\n        break;\n      case 0x118B3:\n        bufpush(0x118D3);\n        break;\n      case 0x118B4:\n        bufpush(0x118D4);\n        break;\n      case 0x118B5:\n        bufpush(0x118D5);\n        break;\n      case 0x118B6:\n        bufpush(0x118D6);\n        break;\n      case 0x118B7:\n        bufpush(0x118D7);\n        break;\n      case 0x118B8:\n        bufpush(0x118D8);\n        break;\n      case 0x118B9:\n        bufpush(0x118D9);\n        break;\n      case 0x118BA:\n        bufpush(0x118DA);\n        break;\n      case 0x118BB:\n        bufpush(0x118DB);\n        break;\n      case 0x118BC:\n        bufpush(0x118DC);\n        break;\n      case 0x118BD:\n        bufpush(0x118DD);\n        break;\n      case 0x118BE:\n        bufpush(0x118DE);\n        break;\n      case 0x118BF:\n        bufpush(0x118DF);\n        break;\n      case 0x1E900:\n        bufpush(0x1E922);\n        break;\n      case 0x1E901:\n        bufpush(0x1E923);\n        break;\n      case 0x1E902:\n        bufpush(0x1E924);\n        break;\n      case 0x1E903:\n        bufpush(0x1E925);\n        break;\n      case 0x1E904:\n        bufpush(0x1E926);\n        break;\n      case 0x1E905:\n        bufpush(0x1E927);\n        break;\n      case 0x1E906:\n        bufpush(0x1E928);\n        break;\n      case 0x1E907:\n        bufpush(0x1E929);\n        break;\n      case 0x1E908:\n        bufpush(0x1E92A);\n        break;\n      case 0x1E909:\n        bufpush(0x1E92B);\n        break;\n      case 0x1E90A:\n        bufpush(0x1E92C);\n        break;\n      case 0x1E90B:\n        bufpush(0x1E92D);\n        break;\n      case 0x1E90C:\n        bufpush(0x1E92E);\n        break;\n      case 0x1E90D:\n        bufpush(0x1E92F);\n        break;\n      case 0x1E90E:\n        bufpush(0x1E930);\n        break;\n      case 0x1E90F:\n        bufpush(0x1E931);\n        break;\n      case 0x1E910:\n        bufpush(0x1E932);\n        break;\n      case 0x1E911:\n        bufpush(0x1E933);\n        break;\n      case 0x1E912:\n        bufpush(0x1E934);\n        break;\n      case 0x1E913:\n        bufpush(0x1E935);\n        break;\n      case 0x1E914:\n        bufpush(0x1E936);\n        break;\n      case 0x1E915:\n        bufpush(0x1E937);\n        break;\n      case 0x1E916:\n        bufpush(0x1E938);\n        break;\n      case 0x1E917:\n        bufpush(0x1E939);\n        break;\n      case 0x1E918:\n        bufpush(0x1E93A);\n        break;\n      case 0x1E919:\n        bufpush(0x1E93B);\n        break;\n      case 0x1E91A:\n        bufpush(0x1E93C);\n        break;\n      case 0x1E91B:\n        bufpush(0x1E93D);\n        break;\n      case 0x1E91C:\n        bufpush(0x1E93E);\n        break;\n      case 0x1E91D:\n        bufpush(0x1E93F);\n        break;\n      case 0x1E91E:\n        bufpush(0x1E940);\n        break;\n      case 0x1E91F:\n        bufpush(0x1E941);\n        break;\n      case 0x1E920:\n        bufpush(0x1E942);\n        break;\n      case 0x1E921:\n        bufpush(0x1E943);\n        break;\n      default:\n        bufpush(c);\n    }\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/chunk.h",
    "content": "#ifndef CMARK_CHUNK_H\n#define CMARK_CHUNK_H\n\n#include <string.h>\n#include <stdlib.h>\n#include <assert.h>\n#include \"cmark-gfm.h\"\n#include \"buffer.h\"\n#include \"cmark_ctype.h\"\n\n#define CMARK_CHUNK_EMPTY                                                      \\\n  { NULL, 0, 0 }\n\ntypedef struct cmark_chunk {\n  unsigned char *data;\n  bufsize_t len;\n  bufsize_t alloc; // also implies a NULL-terminated string\n} cmark_chunk;\n\nstatic CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) {\n  if (c->alloc)\n    mem->free(c->data);\n\n  c->data = NULL;\n  c->alloc = 0;\n  c->len = 0;\n}\n\nstatic CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {\n  assert(!c->alloc);\n\n  while (c->len && cmark_isspace(c->data[0])) {\n    c->data++;\n    c->len--;\n  }\n}\n\nstatic CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) {\n  assert(!c->alloc);\n\n  while (c->len > 0) {\n    if (!cmark_isspace(c->data[c->len - 1]))\n      break;\n\n    c->len--;\n  }\n}\n\nstatic CMARK_INLINE void cmark_chunk_trim(cmark_chunk *c) {\n  cmark_chunk_ltrim(c);\n  cmark_chunk_rtrim(c);\n}\n\nstatic CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,\n                                                 bufsize_t offset) {\n  const unsigned char *p =\n      (unsigned char *)memchr(ch->data + offset, c, ch->len - offset);\n  return p ? (bufsize_t)(p - ch->data) : ch->len;\n}\n\nstatic CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem,\n                                                    cmark_chunk *c) {\n  unsigned char *str;\n\n  if (c->alloc) {\n    return (char *)c->data;\n  }\n  str = (unsigned char *)mem->calloc(c->len + 1, 1);\n  if (c->len > 0) {\n    memcpy(str, c->data, c->len);\n  }\n  str[c->len] = 0;\n  c->data = str;\n  c->alloc = 1;\n\n  return (char *)str;\n}\n\nstatic CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c,\n                                              const char *str) {\n  unsigned char *old = c->alloc ? c->data : NULL;\n  if (str == NULL) {\n    c->len = 0;\n    c->data = NULL;\n    c->alloc = 0;\n  } else {\n    c->len = (bufsize_t)strlen(str);\n    c->data = (unsigned char *)mem->calloc(c->len + 1, 1);\n    c->alloc = 1;\n    memcpy(c->data, str, c->len + 1);\n  }\n  if (old != NULL) {\n    mem->free(old);\n  }\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) {\n  bufsize_t len = data ? (bufsize_t)strlen(data) : 0;\n  cmark_chunk c = {(unsigned char *)data, len, 0};\n  return c;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch,\n                                                bufsize_t pos, bufsize_t len) {\n  cmark_chunk c = {ch->data + pos, len, 0};\n  return c;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) {\n  cmark_chunk c;\n\n  c.len = buf->size;\n  c.data = cmark_strbuf_detach(buf);\n  c.alloc = 1;\n\n  return c;\n}\n\n/* trim_new variants are to be used when the source chunk may or may not be\n * allocated; forces a newly allocated chunk. */\nstatic CMARK_INLINE cmark_chunk cmark_chunk_ltrim_new(cmark_mem *mem, cmark_chunk *c) {\n  cmark_chunk r = cmark_chunk_dup(c, 0, c->len);\n  cmark_chunk_ltrim(&r);\n  cmark_chunk_to_cstr(mem, &r);\n  return r;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_rtrim_new(cmark_mem *mem, cmark_chunk *c) {\n  cmark_chunk r = cmark_chunk_dup(c, 0, c->len);\n  cmark_chunk_rtrim(&r);\n  cmark_chunk_to_cstr(mem, &r);\n  return r;\n}\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark-gfm-extension_api.h",
    "content": "#ifndef CMARK_GFM_EXTENSION_API_H\n#define CMARK_GFM_EXTENSION_API_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n\nstruct cmark_renderer;\nstruct cmark_html_renderer;\nstruct cmark_chunk;\n\n/**\n * ## Extension Support\n *\n * While the \"core\" of libcmark is strictly compliant with the\n * specification, an API is provided for extension writers to\n * hook into the parsing process.\n *\n * It should be noted that the cmark_node API already offers\n * room for customization, with methods offered to traverse and\n * modify the AST, and even define custom blocks.\n * When the desired customization is achievable in an error-proof\n * way using that API, it should be the preferred method.\n *\n * The following API requires a more in-depth understanding\n * of libcmark's parsing strategy, which is exposed\n * [here](http://spec.commonmark.org/0.24/#appendix-a-parsing-strategy).\n *\n * It should be used when \"a posteriori\" modification of the AST\n * proves to be too difficult / impossible to implement correctly.\n *\n * It can also serve as an intermediary step before extending\n * the specification, as an extension implemented using this API\n * will be trivially integrated in the core if it proves to be\n * desirable.\n */\n\ntypedef struct cmark_plugin cmark_plugin;\n\n/** A syntax extension that can be attached to a cmark_parser\n * with cmark_parser_attach_syntax_extension().\n *\n * Extension writers should assign functions matching\n * the signature of the following 'virtual methods' to\n * implement new functionality.\n *\n * Their calling order and expected behaviour match the procedure outlined\n * at <http://spec.commonmark.org/0.24/#phase-1-block-structure>:\n *\n * During step 1, cmark will call the function provided through\n * 'cmark_syntax_extension_set_match_block_func' when it\n * iterates over an open block created by this extension,\n * to determine  whether it could contain the new line.\n * If no function was provided, cmark will close the block.\n *\n * During step 2, if and only if the new line doesn't match any\n * of the standard syntax rules, cmark will call the function\n * provided through 'cmark_syntax_extension_set_open_block_func'\n * to let the extension determine whether that new line matches\n * one of its syntax rules.\n * It is the responsibility of the parser to create and add the\n * new block with cmark_parser_make_block and cmark_parser_add_child.\n * If no function was provided is NULL, the extension will have\n * no effect at all on the final block structure of the AST.\n *\n * #### Inline parsing phase hooks\n *\n * For each character provided by the extension through\n * 'cmark_syntax_extension_set_special_inline_chars',\n * the function provided by the extension through\n * 'cmark_syntax_extension_set_match_inline_func'\n * will get called, it is the responsibility of the extension\n * to scan the characters located at the current inline parsing offset\n * with the cmark_inline_parser API.\n *\n * Depending on the type of the extension, it can either:\n *\n * * Scan forward, determine that the syntax matches and return\n *   a newly-created inline node with the appropriate type.\n *   This is the technique that would be used if inline code\n *   (with backticks) was implemented as an extension.\n * * Scan only the character(s) that its syntax rules require\n *   for opening and closing nodes, push a delimiter on the\n *   delimiter stack, and return a simple text node with its\n *   contents set to the character(s) consumed.\n *   This is the technique that would be used if emphasis\n *   inlines were implemented as an extension.\n *\n * When an extension has pushed delimiters on the stack,\n * the function provided through\n * 'cmark_syntax_extension_set_inline_from_delim_func'\n * will get called in a latter phase,\n * when the inline parser has matched opener and closer delimiters\n * created by the extension together.\n *\n * It is then the responsibility of the extension to modify\n * and populate the opener inline text node, and to remove\n * the necessary delimiters from the delimiter stack.\n *\n * Finally, the extension should return NULL if its scan didn't\n * match its syntax rules.\n *\n * The extension can store whatever private data it might need\n * with 'cmark_syntax_extension_set_private',\n * and optionally define a free function for this data.\n */\ntypedef struct subject cmark_inline_parser;\n\n/** Exposed raw for now */\n\ntypedef struct delimiter {\n  struct delimiter *previous;\n  struct delimiter *next;\n  cmark_node *inl_text;\n  bufsize_t position;\n  bufsize_t length;\n  unsigned char delim_char;\n  int can_open;\n  int can_close;\n} delimiter;\n\n/**\n * ### Plugin API.\n *\n * Extensions should be distributed as dynamic libraries,\n * with a single exported function named after the distributed\n * filename.\n *\n * When discovering extensions (see cmark_init), cmark will\n * try to load a symbol named \"init_{{filename}}\" in all the\n * dynamic libraries it encounters.\n *\n * For example, given a dynamic library named myextension.so\n * (or myextension.dll), cmark will try to load the symbol\n * named \"init_myextension\". This means that the filename\n * must lend itself to forming a valid C identifier, with\n * the notable exception of dashes, which will be translated\n * to underscores, which means cmark will look for a function\n * named \"init_my_extension\" if it encounters a dynamic library\n * named \"my-extension.so\".\n *\n * See the 'cmark_plugin_init_func' typedef for the exact prototype\n * this function should follow.\n *\n * For now the extensibility of cmark is not complete, as\n * it only offers API to hook into the block parsing phase\n * (<http://spec.commonmark.org/0.24/#phase-1-block-structure>).\n *\n * See 'cmark_plugin_register_syntax_extension' for more information.\n */\n\n/** The prototype plugins' init function should follow.\n */\ntypedef int (*cmark_plugin_init_func)(cmark_plugin *plugin);\n\n/** Register a syntax 'extension' with the 'plugin', it will be made\n * available as an extension and, if attached to a cmark_parser\n * with 'cmark_parser_attach_syntax_extension', it will contribute\n * to the block parsing process.\n *\n * See the documentation for 'cmark_syntax_extension' for information\n * on how to implement one.\n *\n * This function will typically be called from the init function\n * of external modules.\n *\n * This takes ownership of 'extension', one should not call\n * 'cmark_syntax_extension_free' on a registered extension.\n */\nCMARK_GFM_EXPORT\nint cmark_plugin_register_syntax_extension(cmark_plugin *plugin,\n                                            cmark_syntax_extension *extension);\n\n/** This will search for the syntax extension named 'name' among the\n *  registered syntax extensions.\n *\n *  It can then be attached to a cmark_parser\n *  with the cmark_parser_attach_syntax_extension method.\n */\nCMARK_GFM_EXPORT\ncmark_syntax_extension *cmark_find_syntax_extension(const char *name);\n\n/** Should create and add a new open block to 'parent_container' if\n * 'input' matches a syntax rule for that block type. It is allowed\n * to modify the type of 'parent_container'.\n *\n * Should return the newly created block if there is one, or\n * 'parent_container' if its type was modified, or NULL.\n */\ntypedef cmark_node * (*cmark_open_block_func) (cmark_syntax_extension *extension,\n                                       int indented,\n                                       cmark_parser *parser,\n                                       cmark_node *parent_container,\n                                       unsigned char *input,\n                                       int len);\n\ntypedef cmark_node *(*cmark_match_inline_func)(cmark_syntax_extension *extension,\n                                       cmark_parser *parser,\n                                       cmark_node *parent,\n                                       unsigned char character,\n                                       cmark_inline_parser *inline_parser);\n\ntypedef delimiter *(*cmark_inline_from_delim_func)(cmark_syntax_extension *extension,\n                                           cmark_parser *parser,\n                                           cmark_inline_parser *inline_parser,\n                                           delimiter *opener,\n                                           delimiter *closer);\n\n/** Should return 'true' if 'input' can be contained in 'container',\n *  'false' otherwise.\n */\ntypedef int (*cmark_match_block_func)        (cmark_syntax_extension *extension,\n                                       cmark_parser *parser,\n                                       unsigned char *input,\n                                       int len,\n                                       cmark_node *container);\n\ntypedef const char *(*cmark_get_type_string_func) (cmark_syntax_extension *extension,\n                                                   cmark_node *node);\n\ntypedef int (*cmark_can_contain_func) (cmark_syntax_extension *extension,\n                                       cmark_node *node,\n                                       cmark_node_type child);\n\ntypedef int (*cmark_contains_inlines_func) (cmark_syntax_extension *extension,\n                                            cmark_node *node);\n\ntypedef void (*cmark_common_render_func) (cmark_syntax_extension *extension,\n                                          struct cmark_renderer *renderer,\n                                          cmark_node *node,\n                                          cmark_event_type ev_type,\n                                          int options);\n\ntypedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,\n                                              cmark_node *node,\n                                              int c);\n\ntypedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension,\n                                            cmark_node *node);\n\ntypedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,\n                                        struct cmark_html_renderer *renderer,\n                                        cmark_node *node,\n                                        cmark_event_type ev_type,\n                                        int options);\n\ntypedef int (*cmark_html_filter_func) (cmark_syntax_extension *extension,\n                                       const unsigned char *tag,\n                                       size_t tag_len);\n\ntypedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension,\n                                               cmark_parser *parser,\n                                               cmark_node *root);\n\ntypedef int (*cmark_ispunct_func) (char c);\n\ntypedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension,\n                                         cmark_mem *mem,\n                                         cmark_node *node);\n\ntypedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension,\n                                        cmark_mem *mem,\n                                        cmark_node *node);\n\n/** Free a cmark_syntax_extension.\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_free               (cmark_mem *mem, cmark_syntax_extension *extension);\n\n/** Return a newly-constructed cmark_syntax_extension, named 'name'.\n */\nCMARK_GFM_EXPORT\ncmark_syntax_extension *cmark_syntax_extension_new (const char *name);\n\nCMARK_GFM_EXPORT\ncmark_node_type cmark_syntax_extension_add_node(int is_inline);\n\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension, int emphasis);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,\n                                                cmark_open_block_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,\n                                                 cmark_match_block_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,\n                                                  cmark_match_inline_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,\n                                                       cmark_inline_from_delim_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,\n                                                     cmark_llist *special_chars);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,\n                                                     cmark_get_type_string_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,\n                                                 cmark_can_contain_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,\n                                                      cmark_contains_inlines_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,\n                                                       cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,\n                                                      cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,\n                                                  cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,\n                                              cmark_xml_attr_func func);\n\n  /** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,\n                                                cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,\n                                                 cmark_html_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,\n                                                 cmark_html_filter_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,\n                                                       cmark_commonmark_escape_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_private(cmark_syntax_extension *extension,\n                                        void *priv,\n                                        cmark_free_func free_func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid *cmark_syntax_extension_get_private(cmark_syntax_extension *extension);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,\n                                                 cmark_postprocess_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,\n                                                  cmark_opaque_alloc_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,\n                                                 cmark_opaque_free_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,\n                                             cmark_ispunct_func func);\n\n/** Return the index of the line currently being parsed, starting with 1.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_line_number(cmark_parser *parser);\n\n/** Return the offset in bytes in the line being processed.\n *\n * Example:\n *\n * ### foo\n *\n * Here, offset will first be 0, then 5 (the index of the 'f' character).\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_offset(cmark_parser *parser);\n\n/**\n * Return the offset in 'columns' in the line being processed.\n *\n * This value may differ from the value returned by\n * cmark_parser_get_offset() in that it accounts for tabs,\n * and as such should not be used as an index in the current line's\n * buffer.\n *\n * Example:\n *\n * cmark_parser_advance_offset() can be called to advance the\n * offset by a number of columns, instead of a number of bytes.\n *\n * In that case, if offset falls \"in the middle\" of a tab\n * character, 'column' and offset will differ.\n *\n * ```\n * foo                 \\t bar\n * ^                   ^^\n * offset (0)          20\n * ```\n *\n * If cmark_parser_advance_offset is called here with 'columns'\n * set to 'true' and 'offset' set to 22, cmark_parser_get_offset()\n * will return 20, whereas cmark_parser_get_column() will return\n * 22.\n *\n * Additionally, as tabs expand to the next multiple of 4 column,\n * cmark_parser_has_partially_consumed_tab() will now return\n * 'true'.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_column(cmark_parser *parser);\n\n/** Return the absolute index in bytes of the first nonspace\n * character coming after the offset as returned by\n * cmark_parser_get_offset() in the line currently being processed.\n *\n * Example:\n *\n * ```\n *   foo        bar            baz  \\n\n * ^               ^           ^\n * 0            offset (16) first_nonspace (28)\n * ```\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_first_nonspace(cmark_parser *parser);\n\n/** Return the absolute index of the first nonspace column coming after 'offset'\n * in the line currently being processed, counting tabs as multiple\n * columns as appropriate.\n *\n * See the documentation for cmark_parser_get_first_nonspace() and\n * cmark_parser_get_column() for more information.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_first_nonspace_column(cmark_parser *parser);\n\n/** Return the difference between the values returned by\n * cmark_parser_get_first_nonspace_column() and\n * cmark_parser_get_column().\n *\n * This is not a byte offset, as it can count one tab as multiple\n * characters.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_indent(cmark_parser *parser);\n\n/** Return 'true' if the line currently being processed has been entirely\n * consumed, 'false' otherwise.\n *\n * Example:\n *\n * ```\n *   foo        bar            baz  \\n\n * ^\n * offset\n * ```\n *\n * This function will return 'false' here.\n *\n * ```\n *   foo        bar            baz  \\n\n *                 ^\n *              offset\n * ```\n * This function will still return 'false'.\n *\n * ```\n *   foo        bar            baz  \\n\n *                                ^\n *                             offset\n * ```\n *\n * At this point, this function will now return 'true'.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_is_blank(cmark_parser *parser);\n\n/** Return 'true' if the value returned by cmark_parser_get_offset()\n * is 'inside' an expanded tab.\n *\n * See the documentation for cmark_parser_get_column() for more\n * information.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_has_partially_consumed_tab(cmark_parser *parser);\n\n/** Return the length in bytes of the previously processed line, excluding potential\n * newline (\\n) and carriage return (\\r) trailing characters.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_last_line_length(cmark_parser *parser);\n\n/** Add a child to 'parent' during the parsing process.\n *\n * If 'parent' isn't the kind of node that can accept this child,\n * this function will back up till it hits a node that can, closing\n * blocks as appropriate.\n */\nCMARK_GFM_EXPORT\ncmark_node*cmark_parser_add_child(cmark_parser *parser,\n                                  cmark_node *parent,\n                                  cmark_node_type block_type,\n                                  int start_column);\n\n/** Advance the 'offset' of the parser in the current line.\n *\n * See the documentation of cmark_parser_get_offset() and\n * cmark_parser_get_column() for more information.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_advance_offset(cmark_parser *parser,\n                                 const char *input,\n                                 int count,\n                                 int columns);\n\n\nCMARK_GFM_EXPORT\nvoid cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len);\n\n/** Attach the syntax 'extension' to the 'parser', to provide extra syntax\n *  rules.\n *  See the documentation for cmark_syntax_extension for more information.\n *\n *  Returns 'true' if the 'extension' was successfully attached,\n *  'false' otherwise.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_attach_syntax_extension(cmark_parser *parser, cmark_syntax_extension *extension);\n\n/** Change the type of 'node'.\n *\n * Return 0 if the type could be changed, 1 otherwise.\n */\nCMARK_GFM_EXPORT int cmark_node_set_type(cmark_node *node, cmark_node_type type);\n\n/** Return the string content for all types of 'node'.\n *  The pointer stays valid as long as 'node' isn't freed.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_string_content(cmark_node *node);\n\n/** Set the string 'content' for all types of 'node'.\n *  Copies 'content'.\n */\nCMARK_GFM_EXPORT int cmark_node_set_string_content(cmark_node *node, const char *content);\n\n/** Get the syntax extension responsible for the creation of 'node'.\n *  Return NULL if 'node' was created because it matched standard syntax rules.\n */\nCMARK_GFM_EXPORT cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node);\n\n/** Set the syntax extension responsible for creating 'node'.\n */\nCMARK_GFM_EXPORT int cmark_node_set_syntax_extension(cmark_node *node,\n                                                  cmark_syntax_extension *extension);\n\n/**\n * ## Inline syntax extension helpers\n *\n * The inline parsing process is described in detail at\n * <http://spec.commonmark.org/0.24/#phase-2-inline-structure>\n */\n\n/** Should return 'true' if the predicate matches 'c', 'false' otherwise\n */\ntypedef int (*cmark_inline_predicate)(int c);\n\n/** Advance the current inline parsing offset */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_advance_offset(cmark_inline_parser *parser);\n\n/** Get the current inline parsing offset */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_offset(cmark_inline_parser *parser);\n\n/** Set the offset in bytes in the chunk being processed by the given inline parser.\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset);\n\n/** Gets the cmark_chunk being operated on by the given inline parser.\n * Use cmark_inline_parser_get_offset to get our current position in the chunk.\n */\nCMARK_GFM_EXPORT\nstruct cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser);\n\n/** Returns 1 if the inline parser is currently in a bracket; pass 1 for 'image'\n * if you want to know about an image-type bracket, 0 for link-type. */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image);\n\n/** Remove the last n characters from the last child of the given node.\n * This only works where all n characters are in the single last child, and the last\n * child is CMARK_NODE_TEXT.\n */\nCMARK_GFM_EXPORT\nvoid cmark_node_unput(cmark_node *node, int n);\n\n\n/** Get the character located at the current inline parsing offset\n */\nCMARK_GFM_EXPORT\nunsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser);\n\n/** Get the character located 'pos' bytes in the current line.\n */\nCMARK_GFM_EXPORT\nunsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, int pos);\n\n/** Whether the inline parser has reached the end of the current line\n */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_is_eof(cmark_inline_parser *parser);\n\n/** Get the characters located after the current inline parsing offset\n * while 'pred' matches. Free after usage.\n */\nCMARK_GFM_EXPORT\nchar *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred);\n\n/** Push a delimiter on the delimiter stack.\n * See <<http://spec.commonmark.org/0.24/#phase-2-inline-structure> for\n * more information on the parameters\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,\n                                  unsigned char c,\n                                  int can_open,\n                                  int can_close,\n                                  cmark_node *inl_text);\n\n/** Remove 'delim' from the delimiter stack\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim);\n\nCMARK_GFM_EXPORT\ndelimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_line(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_column(cmark_inline_parser *parser);\n\n/** Convenience function to scan a given delimiter.\n *\n * 'left_flanking' and 'right_flanking' will be set to true if they\n * respectively precede and follow a non-space, non-punctuation\n * character.\n *\n * Additionally, 'punct_before' and 'punct_after' will respectively be set\n * if the preceding or following character is a punctuation character.\n *\n * Note that 'left_flanking' and 'right_flanking' can both be 'true'.\n *\n * Returns the number of delimiters encountered, in the limit\n * of 'max_delims', and advances the inline parsing offset.\n */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,\n                                  int max_delims,\n                                  unsigned char c,\n                                  int *left_flanking,\n                                  int *right_flanking,\n                                  int *punct_before,\n                                  int *punct_after);\n\nCMARK_GFM_EXPORT\nvoid cmark_manage_extensions_special_characters(cmark_parser *parser, int add);\n\nCMARK_GFM_EXPORT\ncmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser);\n\nCMARK_GFM_EXPORT\nvoid cmark_arena_push(void);\n\nCMARK_GFM_EXPORT\nint cmark_arena_pop(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark-gfm.h",
    "content": "#ifndef CMARK_GFM_H\n#define CMARK_GFM_H\n\n#include <stdio.h>\n#include <stdint.h>\n#include \"cmark-gfm_export.h\"\n#include \"cmark-gfm_version.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** # NAME\n *\n * **cmark-gfm** - CommonMark parsing, manipulating, and rendering\n */\n\n/** # DESCRIPTION\n *\n * ## Simple Interface\n */\n\n/** Convert 'text' (assumed to be a UTF-8 encoded string with length\n * 'len') from CommonMark Markdown to HTML, returning a null-terminated,\n * UTF-8-encoded string. It is the caller's responsibility\n * to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_markdown_to_html(const char *text, size_t len, int options);\n\n/** ## Node Structure\n */\n\n#define CMARK_NODE_TYPE_PRESENT (0x8000)\n#define CMARK_NODE_TYPE_BLOCK (CMARK_NODE_TYPE_PRESENT | 0x0000)\n#define CMARK_NODE_TYPE_INLINE (CMARK_NODE_TYPE_PRESENT | 0x4000)\n#define CMARK_NODE_TYPE_MASK (0xc000)\n#define CMARK_NODE_VALUE_MASK (0x3fff)\n\ntypedef enum {\n  /* Error status */\n  CMARK_NODE_NONE = 0x0000,\n\n  /* Block */\n  CMARK_NODE_DOCUMENT       = CMARK_NODE_TYPE_BLOCK | 0x0001,\n  CMARK_NODE_BLOCK_QUOTE    = CMARK_NODE_TYPE_BLOCK | 0x0002,\n  CMARK_NODE_LIST           = CMARK_NODE_TYPE_BLOCK | 0x0003,\n  CMARK_NODE_ITEM           = CMARK_NODE_TYPE_BLOCK | 0x0004,\n  CMARK_NODE_CODE_BLOCK     = CMARK_NODE_TYPE_BLOCK | 0x0005,\n  CMARK_NODE_HTML_BLOCK     = CMARK_NODE_TYPE_BLOCK | 0x0006,\n  CMARK_NODE_CUSTOM_BLOCK   = CMARK_NODE_TYPE_BLOCK | 0x0007,\n  CMARK_NODE_PARAGRAPH      = CMARK_NODE_TYPE_BLOCK | 0x0008,\n  CMARK_NODE_HEADING        = CMARK_NODE_TYPE_BLOCK | 0x0009,\n  CMARK_NODE_THEMATIC_BREAK = CMARK_NODE_TYPE_BLOCK | 0x000a,\n  CMARK_NODE_FOOTNOTE_DEFINITION = CMARK_NODE_TYPE_BLOCK | 0x000b,\n\n  /* Inline */\n  CMARK_NODE_TEXT          = CMARK_NODE_TYPE_INLINE | 0x0001,\n  CMARK_NODE_SOFTBREAK     = CMARK_NODE_TYPE_INLINE | 0x0002,\n  CMARK_NODE_LINEBREAK     = CMARK_NODE_TYPE_INLINE | 0x0003,\n  CMARK_NODE_CODE          = CMARK_NODE_TYPE_INLINE | 0x0004,\n  CMARK_NODE_HTML_INLINE   = CMARK_NODE_TYPE_INLINE | 0x0005,\n  CMARK_NODE_CUSTOM_INLINE = CMARK_NODE_TYPE_INLINE | 0x0006,\n  CMARK_NODE_EMPH          = CMARK_NODE_TYPE_INLINE | 0x0007,\n  CMARK_NODE_STRONG        = CMARK_NODE_TYPE_INLINE | 0x0008,\n  CMARK_NODE_LINK          = CMARK_NODE_TYPE_INLINE | 0x0009,\n  CMARK_NODE_IMAGE         = CMARK_NODE_TYPE_INLINE | 0x000a,\n  CMARK_NODE_FOOTNOTE_REFERENCE = CMARK_NODE_TYPE_INLINE | 0x000b,\n} cmark_node_type;\n\nextern cmark_node_type CMARK_NODE_LAST_BLOCK;\nextern cmark_node_type CMARK_NODE_LAST_INLINE;\n\n/* For backwards compatibility: */\n#define CMARK_NODE_HEADER CMARK_NODE_HEADING\n#define CMARK_NODE_HRULE CMARK_NODE_THEMATIC_BREAK\n#define CMARK_NODE_HTML CMARK_NODE_HTML_BLOCK\n#define CMARK_NODE_INLINE_HTML CMARK_NODE_HTML_INLINE\n\ntypedef enum {\n  CMARK_NO_LIST,\n  CMARK_BULLET_LIST,\n  CMARK_ORDERED_LIST\n} cmark_list_type;\n\ntypedef enum {\n  CMARK_NO_DELIM,\n  CMARK_PERIOD_DELIM,\n  CMARK_PAREN_DELIM\n} cmark_delim_type;\n\ntypedef struct cmark_node cmark_node;\ntypedef struct cmark_parser cmark_parser;\ntypedef struct cmark_iter cmark_iter;\ntypedef struct cmark_syntax_extension cmark_syntax_extension;\n\n/**\n * ## Custom memory allocator support\n */\n\n/** Defines the memory allocation functions to be used by CMark\n * when parsing and allocating a document tree\n */\ntypedef struct cmark_mem {\n  void *(*calloc)(size_t, size_t);\n  void *(*realloc)(void *, size_t);\n  void (*free)(void *);\n} cmark_mem;\n\n/** The default memory allocator; uses the system's calloc,\n * realloc and free.\n */\nCMARK_GFM_EXPORT\ncmark_mem *cmark_get_default_mem_allocator(void);\n\n/** An arena allocator; uses system calloc to allocate large\n * slabs of memory.  Memory in these slabs is not reused at all.\n */\nCMARK_GFM_EXPORT\ncmark_mem *cmark_get_arena_mem_allocator(void);\n\n/** Resets the arena allocator, quickly returning all used memory\n * to the operating system.\n */\nCMARK_GFM_EXPORT\nvoid cmark_arena_reset(void);\n\n/** Callback for freeing user data with a 'cmark_mem' context.\n */\ntypedef void (*cmark_free_func) (cmark_mem *mem, void *user_data);\n\n\n/*\n * ## Basic data structures\n *\n * To keep dependencies to the strict minimum, libcmark implements\n * its own versions of \"classic\" data structures.\n */\n\n/**\n * ### Linked list\n */\n\n/** A generic singly linked list.\n */\ntypedef struct _cmark_llist\n{\n  struct _cmark_llist *next;\n  void         *data;\n} cmark_llist;\n\n/** Append an element to the linked list, return the possibly modified\n * head of the list.\n */\nCMARK_GFM_EXPORT\ncmark_llist * cmark_llist_append    (cmark_mem         * mem,\n                                     cmark_llist       * head,\n                                     void              * data);\n\n/** Free the list starting with 'head', calling 'free_func' with the\n *  data pointer of each of its elements\n */\nCMARK_GFM_EXPORT\nvoid          cmark_llist_free_full (cmark_mem         * mem,\n                                     cmark_llist       * head,\n                                     cmark_free_func     free_func);\n\n/** Free the list starting with 'head'\n */\nCMARK_GFM_EXPORT\nvoid          cmark_llist_free      (cmark_mem         * mem,\n                                     cmark_llist       * head);\n\n/**\n * ## Creating and Destroying Nodes\n */\n\n/** Creates a new node of type 'type'.  Note that the node may have\n * other required properties, which it is the caller's responsibility\n * to assign.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_new(cmark_node_type type);\n\n/** Same as `cmark_node_new`, but explicitly listing the memory\n * allocator used to allocate the node.  Note:  be sure to use the same\n * allocator for every node in a tree, or bad things can happen.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type,\n                                                 cmark_mem *mem);\n\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_ext(cmark_node_type type,\n                                                cmark_syntax_extension *extension);\n\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type,\n                                                cmark_mem *mem,\n                                                cmark_syntax_extension *extension);\n\n/** Frees the memory allocated for a node and any children.\n */\nCMARK_GFM_EXPORT void cmark_node_free(cmark_node *node);\n\n/**\n * ## Tree Traversal\n */\n\n/** Returns the next node in the sequence after 'node', or NULL if\n * there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_next(cmark_node *node);\n\n/** Returns the previous node in the sequence after 'node', or NULL if\n * there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_previous(cmark_node *node);\n\n/** Returns the parent of 'node', or NULL if there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_parent(cmark_node *node);\n\n/** Returns the first child of 'node', or NULL if 'node' has no children.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_first_child(cmark_node *node);\n\n/** Returns the last child of 'node', or NULL if 'node' has no children.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);\n\n/** Returns the footnote reference of 'node', or NULL if 'node' doesn't have a\n * footnote reference.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_parent_footnote_def(cmark_node *node);\n\n/**\n * ## Iterator\n *\n * An iterator will walk through a tree of nodes, starting from a root\n * node, returning one node at a time, together with information about\n * whether the node is being entered or exited.  The iterator will\n * first descend to a child node, if there is one.  When there is no\n * child, the iterator will go to the next sibling.  When there is no\n * next sibling, the iterator will return to the parent (but with\n * a 'cmark_event_type' of `CMARK_EVENT_EXIT`).  The iterator will\n * return `CMARK_EVENT_DONE` when it reaches the root node again.\n * One natural application is an HTML renderer, where an `ENTER` event\n * outputs an open tag and an `EXIT` event outputs a close tag.\n * An iterator might also be used to transform an AST in some systematic\n * way, for example, turning all level-3 headings into regular paragraphs.\n *\n *     void\n *     usage_example(cmark_node *root) {\n *         cmark_event_type ev_type;\n *         cmark_iter *iter = cmark_iter_new(root);\n *\n *         while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n *             cmark_node *cur = cmark_iter_get_node(iter);\n *             // Do something with `cur` and `ev_type`\n *         }\n *\n *         cmark_iter_free(iter);\n *     }\n *\n * Iterators will never return `EXIT` events for leaf nodes, which are nodes\n * of type:\n *\n * * CMARK_NODE_HTML_BLOCK\n * * CMARK_NODE_THEMATIC_BREAK\n * * CMARK_NODE_CODE_BLOCK\n * * CMARK_NODE_TEXT\n * * CMARK_NODE_SOFTBREAK\n * * CMARK_NODE_LINEBREAK\n * * CMARK_NODE_CODE\n * * CMARK_NODE_HTML_INLINE\n *\n * Nodes must only be modified after an `EXIT` event, or an `ENTER` event for\n * leaf nodes.\n */\n\ntypedef enum {\n  CMARK_EVENT_NONE,\n  CMARK_EVENT_DONE,\n  CMARK_EVENT_ENTER,\n  CMARK_EVENT_EXIT\n} cmark_event_type;\n\n/** Creates a new iterator starting at 'root'.  The current node and event\n * type are undefined until 'cmark_iter_next' is called for the first time.\n * The memory allocated for the iterator should be released using\n * 'cmark_iter_free' when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_iter *cmark_iter_new(cmark_node *root);\n\n/** Frees the memory allocated for an iterator.\n */\nCMARK_GFM_EXPORT\nvoid cmark_iter_free(cmark_iter *iter);\n\n/** Advances to the next node and returns the event type (`CMARK_EVENT_ENTER`,\n * `CMARK_EVENT_EXIT` or `CMARK_EVENT_DONE`).\n */\nCMARK_GFM_EXPORT\ncmark_event_type cmark_iter_next(cmark_iter *iter);\n\n/** Returns the current node.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_iter_get_node(cmark_iter *iter);\n\n/** Returns the current event type.\n */\nCMARK_GFM_EXPORT\ncmark_event_type cmark_iter_get_event_type(cmark_iter *iter);\n\n/** Returns the root node.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_iter_get_root(cmark_iter *iter);\n\n/** Resets the iterator so that the current node is 'current' and\n * the event type is 'event_type'.  The new current node must be a\n * descendant of the root node or the root node itself.\n */\nCMARK_GFM_EXPORT\nvoid cmark_iter_reset(cmark_iter *iter, cmark_node *current,\n                      cmark_event_type event_type);\n\n/**\n * ## Accessors\n */\n\n/** Returns the user data of 'node'.\n */\nCMARK_GFM_EXPORT void *cmark_node_get_user_data(cmark_node *node);\n\n/** Sets arbitrary user data for 'node'.  Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_user_data(cmark_node *node, void *user_data);\n\n/** Set free function for user data */\nCMARK_GFM_EXPORT\nint cmark_node_set_user_data_free_func(cmark_node *node,\n                                        cmark_free_func free_func);\n\n/** Returns the type of 'node', or `CMARK_NODE_NONE` on error.\n */\nCMARK_GFM_EXPORT cmark_node_type cmark_node_get_type(cmark_node *node);\n\n/** Like 'cmark_node_get_type', but returns a string representation\n    of the type, or `\"<unknown>\"`.\n */\nCMARK_GFM_EXPORT\nconst char *cmark_node_get_type_string(cmark_node *node);\n\n/** Returns the string contents of 'node', or an empty\n    string if none is set.  Returns NULL if called on a\n    node that does not have string content.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_literal(cmark_node *node);\n\n/** Sets the string contents of 'node'.  Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_literal(cmark_node *node, const char *content);\n\n/** Returns the heading level of 'node', or 0 if 'node' is not a heading.\n */\nCMARK_GFM_EXPORT int cmark_node_get_heading_level(cmark_node *node);\n\n/* For backwards compatibility */\n#define cmark_node_get_header_level cmark_node_get_heading_level\n#define cmark_node_set_header_level cmark_node_set_heading_level\n\n/** Sets the heading level of 'node', returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_heading_level(cmark_node *node, int level);\n\n/** Returns the list type of 'node', or `CMARK_NO_LIST` if 'node'\n * is not a list.\n */\nCMARK_GFM_EXPORT cmark_list_type cmark_node_get_list_type(cmark_node *node);\n\n/** Sets the list type of 'node', returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_type(cmark_node *node,\n                                          cmark_list_type type);\n\n/** Returns the list delimiter type of 'node', or `CMARK_NO_DELIM` if 'node'\n * is not a list.\n */\nCMARK_GFM_EXPORT cmark_delim_type cmark_node_get_list_delim(cmark_node *node);\n\n/** Sets the list delimiter type of 'node', returning 1 on success and 0\n * on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_delim(cmark_node *node,\n                                           cmark_delim_type delim);\n\n/** Returns starting number of 'node', if it is an ordered list, otherwise 0.\n */\nCMARK_GFM_EXPORT int cmark_node_get_list_start(cmark_node *node);\n\n/** Sets starting number of 'node', if it is an ordered list. Returns 1\n * on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_start(cmark_node *node, int start);\n\n/** Returns 1 if 'node' is a tight list, 0 otherwise.\n */\nCMARK_GFM_EXPORT int cmark_node_get_list_tight(cmark_node *node);\n\n/** Sets the \"tightness\" of a list.  Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight);\n\n/**\n * Returns item index of 'node'. This is only used when rendering output\n * formats such as commonmark, which need to output the index. It is not\n * required for formats such as html or latex.\n */\nCMARK_GFM_EXPORT int cmark_node_get_item_index(cmark_node *node);\n\n/** Sets item index of 'node'. Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_item_index(cmark_node *node, int idx);\n\n/** Returns the info string from a fenced code block.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);\n\n/** Sets the info string in a fenced code block, returning 1 on\n * success and 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_fence_info(cmark_node *node, const char *info);\n\n/** Sets code blocks fencing details\n */\nCMARK_GFM_EXPORT int cmark_node_set_fenced(cmark_node * node, int fenced,\n    int length, int offset, char character);\n\n/** Returns code blocks fencing details\n */\nCMARK_GFM_EXPORT int cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character);\n\n/** Returns the URL of a link or image 'node', or an empty string\n    if no URL is set.  Returns NULL if called on a node that is\n    not a link or image.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_url(cmark_node *node);\n\n/** Sets the URL of a link or image 'node'. Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_url(cmark_node *node, const char *url);\n\n/** Returns the title of a link or image 'node', or an empty\n    string if no title is set.  Returns NULL if called on a node\n    that is not a link or image.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_title(cmark_node *node);\n\n/** Sets the title of a link or image 'node'. Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_title(cmark_node *node, const char *title);\n\n/** Returns the literal \"on enter\" text for a custom 'node', or\n    an empty string if no on_enter is set.  Returns NULL if called\n    on a non-custom node.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_on_enter(cmark_node *node);\n\n/** Sets the literal text to render \"on enter\" for a custom 'node'.\n    Any children of the node will be rendered after this text.\n    Returns 1 on success 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_on_enter(cmark_node *node,\n                                         const char *on_enter);\n\n/** Returns the literal \"on exit\" text for a custom 'node', or\n    an empty string if no on_exit is set.  Returns NULL if\n    called on a non-custom node.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_on_exit(cmark_node *node);\n\n/** Sets the literal text to render \"on exit\" for a custom 'node'.\n    Any children of the node will be rendered before this text.\n    Returns 1 on success 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_on_exit(cmark_node *node, const char *on_exit);\n\n/** Returns the line on which 'node' begins.\n */\nCMARK_GFM_EXPORT int cmark_node_get_start_line(cmark_node *node);\n\n/** Returns the column at which 'node' begins.\n */\nCMARK_GFM_EXPORT int cmark_node_get_start_column(cmark_node *node);\n\n/** Returns the line on which 'node' ends.\n */\nCMARK_GFM_EXPORT int cmark_node_get_end_line(cmark_node *node);\n\n/** Returns the column at which 'node' ends.\n */\nCMARK_GFM_EXPORT int cmark_node_get_end_column(cmark_node *node);\n\n/**\n * ## Tree Manipulation\n */\n\n/** Unlinks a 'node', removing it from the tree, but not freeing its\n * memory.  (Use 'cmark_node_free' for that.)\n */\nCMARK_GFM_EXPORT void cmark_node_unlink(cmark_node *node);\n\n/** Inserts 'sibling' before 'node'.  Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_insert_before(cmark_node *node,\n                                          cmark_node *sibling);\n\n/** Inserts 'sibling' after 'node'. Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_insert_after(cmark_node *node, cmark_node *sibling);\n\n/** Replaces 'oldnode' with 'newnode' and unlinks 'oldnode' (but does\n * not free its memory).\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_replace(cmark_node *oldnode, cmark_node *newnode);\n\n/** Adds 'child' to the beginning of the children of 'node'.\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_prepend_child(cmark_node *node, cmark_node *child);\n\n/** Adds 'child' to the end of the children of 'node'.\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_append_child(cmark_node *node, cmark_node *child);\n\n/** Consolidates adjacent text nodes.\n */\nCMARK_GFM_EXPORT void cmark_consolidate_text_nodes(cmark_node *root);\n\n/** Ensures a node and all its children own their own chunk memory.\n */\nCMARK_GFM_EXPORT void cmark_node_own(cmark_node *root);\n\n/**\n * ## Parsing\n *\n * Simple interface:\n *\n *     cmark_node *document = cmark_parse_document(\"Hello *world*\", 13,\n *                                                 CMARK_OPT_DEFAULT);\n *\n * Streaming interface:\n *\n *     cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT);\n *     FILE *fp = fopen(\"myfile.md\", \"rb\");\n *     while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {\n *     \t   cmark_parser_feed(parser, buffer, bytes);\n *     \t   if (bytes < sizeof(buffer)) {\n *     \t       break;\n *     \t   }\n *     }\n *     document = cmark_parser_finish(parser);\n *     cmark_parser_free(parser);\n */\n\n/** Creates a new parser object.\n */\nCMARK_GFM_EXPORT\ncmark_parser *cmark_parser_new(int options);\n\n/** Creates a new parser object with the given memory allocator\n */\nCMARK_GFM_EXPORT\ncmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem);\n\n/** Frees memory allocated for a parser object.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_free(cmark_parser *parser);\n\n/** Feeds a string of length 'len' to 'parser'.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len);\n\n/** Finish parsing and return a pointer to a tree of nodes.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parser_finish(cmark_parser *parser);\n\n/** Parse a CommonMark document in 'buffer' of length 'len'.\n * Returns a pointer to a tree of nodes.  The memory allocated for\n * the node tree should be released using 'cmark_node_free'\n * when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parse_document(const char *buffer, size_t len, int options);\n\n/** Parse a CommonMark document in file 'f', returning a pointer to\n * a tree of nodes.  The memory allocated for the node tree should be\n * released using 'cmark_node_free' when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parse_file(FILE *f, int options);\n\n/**\n * ## Rendering\n */\n\n/** Render a 'node' tree as XML.  It is the caller's responsibility\n * to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_xml(cmark_node *root, int options);\n\n/** As for 'cmark_render_xml', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem);\n\n/** Render a 'node' tree as an HTML fragment.  It is up to the user\n * to add an appropriate header and footer. It is the caller's\n * responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions);\n\n/** As for 'cmark_render_html', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem);\n\n/** Render a 'node' tree as a groff man page, without the header.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_man(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_man', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a commonmark document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_commonmark(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_commonmark', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a plain text document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_plaintext(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_plaintext', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a LaTeX document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_latex(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_latex', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/**\n * ## Options\n */\n\n/** Default options.\n */\n#define CMARK_OPT_DEFAULT 0\n\n/**\n * ### Options affecting rendering\n */\n\n/** Include a `data-sourcepos` attribute on all block elements.\n */\n#define CMARK_OPT_SOURCEPOS (1 << 1)\n\n/** Render `softbreak` elements as hard line breaks.\n */\n#define CMARK_OPT_HARDBREAKS (1 << 2)\n\n/** `CMARK_OPT_SAFE` is defined here for API compatibility,\n    but it no longer has any effect. \"Safe\" mode is now the default:\n    set `CMARK_OPT_UNSAFE` to disable it.\n */\n#define CMARK_OPT_SAFE (1 << 3)\n\n/** Render raw HTML and unsafe links (`javascript:`, `vbscript:`,\n * `file:`, and `data:`, except for `image/png`, `image/gif`,\n * `image/jpeg`, or `image/webp` mime types).  By default,\n * raw HTML is replaced by a placeholder HTML comment. Unsafe\n * links are replaced by empty strings.\n */\n#define CMARK_OPT_UNSAFE (1 << 17)\n\n/** Render `softbreak` elements as spaces.\n */\n#define CMARK_OPT_NOBREAKS (1 << 4)\n\n/**\n * ### Options affecting parsing\n */\n\n/** Legacy option (no effect).\n */\n#define CMARK_OPT_NORMALIZE (1 << 8)\n\n/** Validate UTF-8 in the input before parsing, replacing illegal\n * sequences with the replacement character U+FFFD.\n */\n#define CMARK_OPT_VALIDATE_UTF8 (1 << 9)\n\n/** Convert straight quotes to curly, --- to em dashes, -- to en dashes.\n */\n#define CMARK_OPT_SMART (1 << 10)\n\n/** Use GitHub-style <pre lang=\"x\"> tags for code blocks instead of <pre><code\n * class=\"language-x\">.\n */\n#define CMARK_OPT_GITHUB_PRE_LANG (1 << 11)\n\n/** Be liberal in interpreting inline HTML tags.\n */\n#define CMARK_OPT_LIBERAL_HTML_TAG (1 << 12)\n\n/** Parse footnotes.\n */\n#define CMARK_OPT_FOOTNOTES (1 << 13)\n\n/** Only parse strikethroughs if surrounded by exactly 2 tildes.\n * Gives some compatibility with redcarpet.\n */\n#define CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE (1 << 14)\n\n/** Use style attributes to align table cells instead of align attributes.\n */\n#define CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES (1 << 15)\n\n/** Include the remainder of the info string in code blocks in\n * a separate attribute.\n */\n#define CMARK_OPT_FULL_INFO_STRING (1 << 16)\n\n/**\n * ## Version information\n */\n\n/** The library version as integer for runtime checks. Also available as\n * macro CMARK_VERSION for compile time checks.\n *\n * * Bits 16-23 contain the major version.\n * * Bits 8-15 contain the minor version.\n * * Bits 0-7 contain the patchlevel.\n *\n * In hexadecimal format, the number 0x010203 represents version 1.2.3.\n */\nCMARK_GFM_EXPORT\nint cmark_version(void);\n\n/** The library version string for runtime checks. Also available as\n * macro CMARK_VERSION_STRING for compile time checks.\n */\nCMARK_GFM_EXPORT\nconst char *cmark_version_string(void);\n\n/** # AUTHORS\n *\n * John MacFarlane, Vicent Marti,  Kārlis Gaņģis, Nick Wellnhofer.\n */\n\n#ifndef CMARK_NO_SHORT_NAMES\n#define NODE_DOCUMENT CMARK_NODE_DOCUMENT\n#define NODE_BLOCK_QUOTE CMARK_NODE_BLOCK_QUOTE\n#define NODE_LIST CMARK_NODE_LIST\n#define NODE_ITEM CMARK_NODE_ITEM\n#define NODE_CODE_BLOCK CMARK_NODE_CODE_BLOCK\n#define NODE_HTML_BLOCK CMARK_NODE_HTML_BLOCK\n#define NODE_CUSTOM_BLOCK CMARK_NODE_CUSTOM_BLOCK\n#define NODE_PARAGRAPH CMARK_NODE_PARAGRAPH\n#define NODE_HEADING CMARK_NODE_HEADING\n#define NODE_HEADER CMARK_NODE_HEADER\n#define NODE_THEMATIC_BREAK CMARK_NODE_THEMATIC_BREAK\n#define NODE_HRULE CMARK_NODE_HRULE\n#define NODE_TEXT CMARK_NODE_TEXT\n#define NODE_SOFTBREAK CMARK_NODE_SOFTBREAK\n#define NODE_LINEBREAK CMARK_NODE_LINEBREAK\n#define NODE_CODE CMARK_NODE_CODE\n#define NODE_HTML_INLINE CMARK_NODE_HTML_INLINE\n#define NODE_CUSTOM_INLINE CMARK_NODE_CUSTOM_INLINE\n#define NODE_EMPH CMARK_NODE_EMPH\n#define NODE_STRONG CMARK_NODE_STRONG\n#define NODE_LINK CMARK_NODE_LINK\n#define NODE_IMAGE CMARK_NODE_IMAGE\n#define BULLET_LIST CMARK_BULLET_LIST\n#define ORDERED_LIST CMARK_ORDERED_LIST\n#define PERIOD_DELIM CMARK_PERIOD_DELIM\n#define PAREN_DELIM CMARK_PAREN_DELIM\n#endif\n\ntypedef int32_t bufsize_t;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark-gfm_version.h.in",
    "content": "#ifndef CMARK_GFM_VERSION_H\n#define CMARK_GFM_VERSION_H\n\n#define CMARK_GFM_VERSION ((@PROJECT_VERSION_MAJOR@ << 24) | (@PROJECT_VERSION_MINOR@ << 16) | (@PROJECT_VERSION_PATCH@ << 8) | @PROJECT_VERSION_GFM@)\n#define CMARK_GFM_VERSION_STRING \"@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.gfm.@PROJECT_VERSION_GFM@\"\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark.c",
    "content": "#include <stdlib.h>\n#include <assert.h>\n#include <stdio.h>\n#include \"registry.h\"\n#include \"node.h\"\n#include \"houdini.h\"\n#include \"cmark-gfm.h\"\n#include \"buffer.h\"\n\ncmark_node_type CMARK_NODE_LAST_BLOCK = CMARK_NODE_FOOTNOTE_DEFINITION;\ncmark_node_type CMARK_NODE_LAST_INLINE = CMARK_NODE_FOOTNOTE_REFERENCE;\n\nint cmark_version(void) { return CMARK_GFM_VERSION; }\n\nconst char *cmark_version_string(void) { return CMARK_GFM_VERSION_STRING; }\n\nstatic void *xcalloc(size_t nmem, size_t size) {\n  void *ptr = calloc(nmem, size);\n  if (!ptr) {\n    fprintf(stderr, \"[cmark] calloc returned null pointer, aborting\\n\");\n    abort();\n  }\n  return ptr;\n}\n\nstatic void *xrealloc(void *ptr, size_t size) {\n  void *new_ptr = realloc(ptr, size);\n  if (!new_ptr) {\n    fprintf(stderr, \"[cmark] realloc returned null pointer, aborting\\n\");\n    abort();\n  }\n  return new_ptr;\n}\n\nstatic void xfree(void *ptr) {\n  free(ptr);\n}\n\ncmark_mem CMARK_DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, xfree};\n\ncmark_mem *cmark_get_default_mem_allocator(void) {\n  return &CMARK_DEFAULT_MEM_ALLOCATOR;\n}\n\nchar *cmark_markdown_to_html(const char *text, size_t len, int options) {\n  cmark_node *doc;\n  char *result;\n\n  doc = cmark_parse_document(text, len, options);\n\n  result = cmark_render_html(doc, options, NULL);\n  cmark_node_free(doc);\n\n  return result;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark_ctype.c",
    "content": "#include <stdint.h>\n\n#include \"cmark_ctype.h\"\n\n/** 1 = space, 2 = punct, 3 = digit, 4 = alpha, 0 = other\n */\nstatic const uint8_t cmark_ctype_class[256] = {\n    /*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */\n    /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,\n    /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* 2 */ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    /* 3 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,\n    /* 4 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n    /* 5 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,\n    /* 6 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n    /* 7 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0,\n    /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\n/**\n * Returns 1 if c is a \"whitespace\" character as defined by the spec.\n */\nint cmark_isspace(char c) { return cmark_ctype_class[(uint8_t)c] == 1; }\n\n/**\n * Returns 1 if c is an ascii punctuation character.\n */\nint cmark_ispunct(char c) { return cmark_ctype_class[(uint8_t)c] == 2; }\n\nint cmark_isalnum(char c) {\n  uint8_t result;\n  result = cmark_ctype_class[(uint8_t)c];\n  return (result == 3 || result == 4);\n}\n\nint cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; }\n\nint cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; }\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/cmark_ctype.h",
    "content": "#ifndef CMARK_CMARK_CTYPE_H\n#define CMARK_CMARK_CTYPE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm_export.h\"\n\n/** Locale-independent versions of functions from ctype.h.\n * We want cmark to behave the same no matter what the system locale.\n */\n\nCMARK_GFM_EXPORT\nint cmark_isspace(char c);\n\nCMARK_GFM_EXPORT\nint cmark_ispunct(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isalnum(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isdigit(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isalpha(char c);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/commonmark.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdint.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define ENCODED_SIZE 20\n#define LISTMARKER_SIZE 20\n\n// Functions to convert cmark_nodes to commonmark strings.\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, \n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  bool needs_escaping = false;\n  bool follows_digit =\n      renderer->buffer->size > 0 &&\n      cmark_isdigit(renderer->buffer->ptr[renderer->buffer->size - 1]);\n  char encoded[ENCODED_SIZE];\n\n  needs_escaping =\n      c < 0x80 && escape != LITERAL &&\n      ((escape == NORMAL &&\n        (c < 0x20 ||\n\t c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||\n         c == '>' || c == '\\\\' || c == '`' || c == '~' || c == '!' ||\n         (c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||\n         (renderer->begin_content && (c == '-' || c == '+' || c == '=') &&\n          // begin_content doesn't get set to false til we've passed digits\n          // at the beginning of line, so...\n          !follows_digit) ||\n         (renderer->begin_content && (c == '.' || c == ')') && follows_digit &&\n          (nextc == 0 || cmark_isspace(nextc))))) ||\n       (escape == URL &&\n        (c == '`' || c == '<' || c == '>' || cmark_isspace((char)c) || c == '\\\\' ||\n         c == ')' || c == '(')) ||\n       (escape == TITLE &&\n        (c == '`' || c == '<' || c == '>' || c == '\"' || c == '\\\\')));\n\n  if (needs_escaping) {\n    if (escape == URL && cmark_isspace((char)c)) {\n      // use percent encoding for spaces\n      snprintf(encoded, ENCODED_SIZE, \"%%%2X\", c);\n      cmark_strbuf_puts(renderer->buffer, encoded);\n      renderer->column += 3;\n    } else if (cmark_ispunct((char)c)) {\n      cmark_render_ascii(renderer, \"\\\\\");\n      cmark_render_code_point(renderer, c);\n    } else { // render as entity\n      snprintf(encoded, ENCODED_SIZE, \"&#%d;\", c);\n      cmark_strbuf_puts(renderer->buffer, encoded);\n      renderer->column += (int)strlen(encoded);\n    }\n  } else {\n    cmark_render_code_point(renderer, c);\n  }\n}\n\nstatic int longest_backtick_sequence(const char *code) {\n  int longest = 0;\n  int current = 0;\n  size_t i = 0;\n  size_t code_len = strlen(code);\n  while (i <= code_len) {\n    if (code[i] == '`') {\n      current++;\n    } else {\n      if (current > longest) {\n        longest = current;\n      }\n      current = 0;\n    }\n    i++;\n  }\n  return longest;\n}\n\nstatic int shortest_unused_backtick_sequence(const char *code) {\n  // note: if the shortest sequence is >= 32, this returns 32\n  // so as not to overflow the bit array.\n  uint32_t used = 1;\n  int current = 0;\n  size_t i = 0;\n  size_t code_len = strlen(code);\n  while (i <= code_len) {\n    if (code[i] == '`') {\n      current++;\n    } else {\n      if (current > 0 && current < 32) {\n        used |= (1U << current);\n      }\n      current = 0;\n    }\n    i++;\n  }\n  // return number of first bit that is 0:\n  i = 0;\n  while (i < 32 && used & 1) {\n    used = used >> 1;\n    i++;\n  }\n  return (int)i;\n}\n\nstatic bool is_autolink(cmark_node *node) {\n  cmark_chunk *title;\n  cmark_chunk *url;\n  cmark_node *link_text;\n  char *realurl;\n  int realurllen;\n\n  if (node->type != CMARK_NODE_LINK) {\n    return false;\n  }\n\n  url = &node->as.link.url;\n  if (url->len == 0 || scan_scheme(url, 0) == 0) {\n    return false;\n  }\n\n  title = &node->as.link.title;\n  // if it has a title, we can't treat it as an autolink:\n  if (title->len > 0) {\n    return false;\n  }\n\n  link_text = node->first_child;\n  if (link_text == NULL) {\n    return false;\n  }\n  cmark_consolidate_text_nodes(link_text);\n  realurl = (char *)url->data;\n  realurllen = url->len;\n  if (strncmp(realurl, \"mailto:\", 7) == 0) {\n    realurl += 7;\n    realurllen -= 7;\n  }\n  return (realurllen == link_text->as.literal.len &&\n          strncmp(realurl, (char *)link_text->as.literal.data,\n                  link_text->as.literal.len) == 0);\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  cmark_delim_type list_delim;\n  int numticks;\n  bool extra_spaces;\n  int i;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  const char *info, *code, *title;\n  char fencechar[2] = {'\\0', '\\0'};\n  size_t info_len, code_len;\n  char listmarker[LISTMARKER_SIZE];\n  const char *emph_delim;\n  bool first_in_list_item;\n  bufsize_t marker_width;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&\n                    !(CMARK_OPT_HARDBREAKS & options);\n\n  // Don't adjust tight list status til we've started the list.\n  // Otherwise we loose the blank line between a paragraph and\n  // a following list.\n  if (entering) {\n    if (node->parent && node->parent->type == CMARK_NODE_ITEM) {\n      renderer->in_tight_list_item = node->parent->parent->as.list.tight;\n    }\n  } else {\n    if (node->type == CMARK_NODE_LIST) {\n      renderer->in_tight_list_item =\n        node->parent &&\n        node->parent->type == CMARK_NODE_ITEM &&\n        node->parent->parent->as.list.tight;\n    }\n  }\n\n  if (node->extension && node->extension->commonmark_render_func) {\n    node->extension->commonmark_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      LIT(\"> \");\n      renderer->begin_content = true;\n      cmark_strbuf_puts(renderer->prefix, \"> \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||\n                                    node->next->type == CMARK_NODE_LIST)) {\n      // this ensures that a following indented code block or list will be\n      // inteprereted correctly.\n      CR();\n      LIT(\"<!-- end list -->\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n      marker_width = 4;\n    } else {\n      list_number = cmark_node_get_item_index(node);\n      list_delim = cmark_node_get_list_delim(node->parent);\n      // we ensure a width of at least 4 so\n      // we get nice transition from single digits\n      // to double\n      snprintf(listmarker, LISTMARKER_SIZE, \"%d%s%s\", list_number,\n               list_delim == CMARK_PAREN_DELIM ? \")\" : \".\",\n               list_number < 10 ? \"  \" : \" \");\n      marker_width = (bufsize_t)strlen(listmarker);\n    }\n    if (entering) {\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"  - \");\n        renderer->begin_content = true;\n      } else {\n        LIT(listmarker);\n        renderer->begin_content = true;\n      }\n      for (i = marker_width; i--;) {\n        cmark_strbuf_putc(renderer->prefix, ' ');\n      }\n    } else {\n      cmark_strbuf_truncate(renderer->prefix,\n                            renderer->prefix->size - marker_width);\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      for (i = cmark_node_get_heading_level(node); i > 0; i--) {\n        LIT(\"#\");\n      }\n      LIT(\" \");\n      renderer->begin_content = true;\n      renderer->no_linebreaks = true;\n    } else {\n      renderer->no_linebreaks = false;\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    first_in_list_item = node->prev == NULL && node->parent &&\n                         node->parent->type == CMARK_NODE_ITEM;\n\n    if (!first_in_list_item) {\n      BLANKLINE();\n    }\n    info = cmark_node_get_fence_info(node);\n    info_len = strlen(info);\n    fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';\n    code = cmark_node_get_literal(node);\n    code_len = strlen(code);\n    // use indented form if no info, and code doesn't\n    // begin or end with a blank line, and code isn't\n    // first thing in a list item\n    if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&\n                          !(cmark_isspace(code[code_len - 1]) &&\n                            cmark_isspace(code[code_len - 2]))) &&\n        !first_in_list_item) {\n      LIT(\"    \");\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n      OUT(cmark_node_get_literal(node), false, LITERAL);\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    } else {\n      numticks = longest_backtick_sequence(code) + 1;\n      if (numticks < 3) {\n        numticks = 3;\n      }\n      for (i = 0; i < numticks; i++) {\n        LIT(fencechar);\n      }\n      LIT(\" \");\n      OUT(info, false, LITERAL);\n      CR();\n      OUT(cmark_node_get_literal(node), false, LITERAL);\n      CR();\n      for (i = 0; i < numticks; i++) {\n        LIT(fencechar);\n      }\n    }\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    BLANKLINE();\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    BLANKLINE();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    LIT(\"-----\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    if (!(CMARK_OPT_HARDBREAKS & options)) {\n      LIT(\"  \");\n    }\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (CMARK_OPT_HARDBREAKS & options) {\n      LIT(\"  \");\n      CR();\n    } else if (!renderer->no_linebreaks && renderer->width == 0 &&\n               !(CMARK_OPT_HARDBREAKS & options) &&\n               !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    code = cmark_node_get_literal(node);\n    code_len = strlen(code);\n    numticks = shortest_unused_backtick_sequence(code);\n    extra_spaces = code_len == 0 ||\n\t    code[0] == '`' || code[code_len - 1] == '`' ||\n\t    code[0] == ' ' || code[code_len - 1] == ' ';\n    for (i = 0; i < numticks; i++) {\n      LIT(\"`\");\n    }\n    if (extra_spaces) {\n      LIT(\" \");\n    }\n    OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);\n    if (extra_spaces) {\n      LIT(\" \");\n    }\n    for (i = 0; i < numticks; i++) {\n      LIT(\"`\");\n    }\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"**\");\n      } else {\n        LIT(\"**\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    // If we have EMPH(EMPH(x)), we need to use *_x_*\n    // because **x** is STRONG(x):\n    if (node->parent && node->parent->type == CMARK_NODE_EMPH &&\n        node->next == NULL && node->prev == NULL) {\n      emph_delim = \"_\";\n    } else {\n      emph_delim = \"*\";\n    }\n    if (entering) {\n      LIT(emph_delim);\n    } else {\n      LIT(emph_delim);\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (is_autolink(node)) {\n      if (entering) {\n        LIT(\"<\");\n        if (strncmp(cmark_node_get_url(node), \"mailto:\", 7) == 0) {\n          LIT((const char *)cmark_node_get_url(node) + 7);\n        } else {\n          LIT((const char *)cmark_node_get_url(node));\n        }\n        LIT(\">\");\n        // return signal to skip contents of node...\n        return 0;\n      }\n    } else {\n      if (entering) {\n        LIT(\"[\");\n      } else {\n        LIT(\"](\");\n        OUT(cmark_node_get_url(node), false, URL);\n        title = cmark_node_get_title(node);\n        if (strlen(title) > 0) {\n          LIT(\" \\\"\");\n          OUT(title, false, TITLE);\n          LIT(\"\\\"\");\n        }\n        LIT(\")\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"![\");\n    } else {\n      LIT(\"](\");\n      OUT(cmark_node_get_url(node), false, URL);\n      title = cmark_node_get_title(node);\n      if (strlen(title) > 0) {\n        OUT(\" \\\"\", allow_wrap, LITERAL);\n        OUT(title, false, TITLE);\n        LIT(\"\\\"\");\n      }\n      LIT(\")\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      LIT(\"[^\");\n\n      char *footnote_label = renderer->mem->calloc(node->parent_footnote_def->as.literal.len + 1, sizeof(char));\n      memmove(footnote_label, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n\n      OUT(footnote_label, false, LITERAL);\n      renderer->mem->free(footnote_label);\n\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      renderer->footnote_ix += 1;\n      LIT(\"[^\");\n\n      char *footnote_label = renderer->mem->calloc(node->as.literal.len + 1, sizeof(char));\n      memmove(footnote_label, node->as.literal.data, node->as.literal.len);\n\n      OUT(footnote_label, false, LITERAL);\n      renderer->mem->free(footnote_label);\n\n      LIT(\"]:\\n\");\n\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    }\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_commonmark(cmark_node *root, int options, int width) {\n  return cmark_render_commonmark_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  if (options & CMARK_OPT_HARDBREAKS) {\n    // disable breaking on width, since it has\n    // a different meaning with OPT_HARDBREAKS\n    width = 0;\n  }\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/config.h.in",
    "content": "#ifndef CMARK_CONFIG_H\n#define CMARK_CONFIG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#cmakedefine HAVE_STDBOOL_H\n\n#ifdef HAVE_STDBOOL_H\n  #include <stdbool.h>\n#elif !defined(__cplusplus)\n  typedef char bool;\n#endif\n\n#cmakedefine HAVE___BUILTIN_EXPECT\n\n#cmakedefine HAVE___ATTRIBUTE__\n\n#ifdef HAVE___ATTRIBUTE__\n  #define CMARK_ATTRIBUTE(list) __attribute__ (list)\n#else\n  #define CMARK_ATTRIBUTE(list)\n#endif\n\n#ifndef CMARK_INLINE\n  #if defined(_MSC_VER) && !defined(__cplusplus)\n    #define CMARK_INLINE __inline\n  #else\n    #define CMARK_INLINE inline\n  #endif\n#endif\n\n/* snprintf and vsnprintf fallbacks for MSVC before 2015,\n   due to Valentin Milea http://stackoverflow.com/questions/2915672/\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1900\n\n#include <stdio.h>\n#include <stdarg.h>\n\n#define snprintf c99_snprintf\n#define vsnprintf c99_vsnprintf\n\nCMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)\n{\n    int count = -1;\n\n    if (size != 0)\n        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);\n    if (count == -1)\n        count = _vscprintf(format, ap);\n\n    return count;\n}\n\nCMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...)\n{\n    int count;\n    va_list ap;\n\n    va_start(ap, format);\n    count = c99_vsnprintf(outBuf, size, format, ap);\n    va_end(ap);\n\n    return count;\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/entities.inc",
    "content": "/* Autogenerated by tools/make_headers_inc.py */\n\nstruct cmark_entity_node {\n\tunsigned char *entity;\n        unsigned char bytes[8];\n};\n\n#define CMARK_ENTITY_MIN_LENGTH 2\n#define CMARK_ENTITY_MAX_LENGTH 32\n#define CMARK_NUM_ENTITIES 2125\n\nstatic const struct cmark_entity_node cmark_entities[] = {\n{(unsigned char*)\"AElig\", {195, 134, 0}},\n{(unsigned char*)\"AMP\", {38, 0}},\n{(unsigned char*)\"Aacute\", {195, 129, 0}},\n{(unsigned char*)\"Abreve\", {196, 130, 0}},\n{(unsigned char*)\"Acirc\", {195, 130, 0}},\n{(unsigned char*)\"Acy\", {208, 144, 0}},\n{(unsigned char*)\"Afr\", {240, 157, 148, 132, 0}},\n{(unsigned char*)\"Agrave\", {195, 128, 0}},\n{(unsigned char*)\"Alpha\", {206, 145, 0}},\n{(unsigned char*)\"Amacr\", {196, 128, 0}},\n{(unsigned char*)\"And\", {226, 169, 147, 0}},\n{(unsigned char*)\"Aogon\", {196, 132, 0}},\n{(unsigned char*)\"Aopf\", {240, 157, 148, 184, 0}},\n{(unsigned char*)\"ApplyFunction\", {226, 129, 161, 0}},\n{(unsigned char*)\"Aring\", {195, 133, 0}},\n{(unsigned char*)\"Ascr\", {240, 157, 146, 156, 0}},\n{(unsigned char*)\"Assign\", {226, 137, 148, 0}},\n{(unsigned char*)\"Atilde\", {195, 131, 0}},\n{(unsigned char*)\"Auml\", {195, 132, 0}},\n{(unsigned char*)\"Backslash\", {226, 136, 150, 0}},\n{(unsigned char*)\"Barv\", {226, 171, 167, 0}},\n{(unsigned char*)\"Barwed\", {226, 140, 134, 0}},\n{(unsigned char*)\"Bcy\", {208, 145, 0}},\n{(unsigned char*)\"Because\", {226, 136, 181, 0}},\n{(unsigned char*)\"Bernoullis\", {226, 132, 172, 0}},\n{(unsigned char*)\"Beta\", {206, 146, 0}},\n{(unsigned char*)\"Bfr\", {240, 157, 148, 133, 0}},\n{(unsigned char*)\"Bopf\", {240, 157, 148, 185, 0}},\n{(unsigned char*)\"Breve\", {203, 152, 0}},\n{(unsigned char*)\"Bscr\", {226, 132, 172, 0}},\n{(unsigned char*)\"Bumpeq\", {226, 137, 142, 0}},\n{(unsigned char*)\"CHcy\", {208, 167, 0}},\n{(unsigned char*)\"COPY\", {194, 169, 0}},\n{(unsigned char*)\"Cacute\", {196, 134, 0}},\n{(unsigned char*)\"Cap\", {226, 139, 146, 0}},\n{(unsigned char*)\"CapitalDifferentialD\", {226, 133, 133, 0}},\n{(unsigned char*)\"Cayleys\", {226, 132, 173, 0}},\n{(unsigned char*)\"Ccaron\", {196, 140, 0}},\n{(unsigned char*)\"Ccedil\", {195, 135, 0}},\n{(unsigned char*)\"Ccirc\", {196, 136, 0}},\n{(unsigned char*)\"Cconint\", {226, 136, 176, 0}},\n{(unsigned char*)\"Cdot\", {196, 138, 0}},\n{(unsigned char*)\"Cedilla\", {194, 184, 0}},\n{(unsigned char*)\"CenterDot\", {194, 183, 0}},\n{(unsigned char*)\"Cfr\", {226, 132, 173, 0}},\n{(unsigned char*)\"Chi\", {206, 167, 0}},\n{(unsigned char*)\"CircleDot\", {226, 138, 153, 0}},\n{(unsigned char*)\"CircleMinus\", {226, 138, 150, 0}},\n{(unsigned char*)\"CirclePlus\", {226, 138, 149, 0}},\n{(unsigned char*)\"CircleTimes\", {226, 138, 151, 0}},\n{(unsigned char*)\"ClockwiseContourIntegral\", {226, 136, 178, 0}},\n{(unsigned char*)\"CloseCurlyDoubleQuote\", {226, 128, 157, 0}},\n{(unsigned char*)\"CloseCurlyQuote\", {226, 128, 153, 0}},\n{(unsigned char*)\"Colon\", {226, 136, 183, 0}},\n{(unsigned char*)\"Colone\", {226, 169, 180, 0}},\n{(unsigned char*)\"Congruent\", {226, 137, 161, 0}},\n{(unsigned char*)\"Conint\", {226, 136, 175, 0}},\n{(unsigned char*)\"ContourIntegral\", {226, 136, 174, 0}},\n{(unsigned char*)\"Copf\", {226, 132, 130, 0}},\n{(unsigned char*)\"Coproduct\", {226, 136, 144, 0}},\n{(unsigned char*)\"CounterClockwiseContourIntegral\", {226, 136, 179, 0}},\n{(unsigned char*)\"Cross\", {226, 168, 175, 0}},\n{(unsigned char*)\"Cscr\", {240, 157, 146, 158, 0}},\n{(unsigned char*)\"Cup\", {226, 139, 147, 0}},\n{(unsigned char*)\"CupCap\", {226, 137, 141, 0}},\n{(unsigned char*)\"DD\", {226, 133, 133, 0}},\n{(unsigned char*)\"DDotrahd\", {226, 164, 145, 0}},\n{(unsigned char*)\"DJcy\", {208, 130, 0}},\n{(unsigned char*)\"DScy\", {208, 133, 0}},\n{(unsigned char*)\"DZcy\", {208, 143, 0}},\n{(unsigned char*)\"Dagger\", {226, 128, 161, 0}},\n{(unsigned char*)\"Darr\", {226, 134, 161, 0}},\n{(unsigned char*)\"Dashv\", {226, 171, 164, 0}},\n{(unsigned char*)\"Dcaron\", {196, 142, 0}},\n{(unsigned char*)\"Dcy\", {208, 148, 0}},\n{(unsigned char*)\"Del\", {226, 136, 135, 0}},\n{(unsigned char*)\"Delta\", {206, 148, 0}},\n{(unsigned char*)\"Dfr\", {240, 157, 148, 135, 0}},\n{(unsigned char*)\"DiacriticalAcute\", {194, 180, 0}},\n{(unsigned char*)\"DiacriticalDot\", {203, 153, 0}},\n{(unsigned char*)\"DiacriticalDoubleAcute\", {203, 157, 0}},\n{(unsigned char*)\"DiacriticalGrave\", {96, 0}},\n{(unsigned char*)\"DiacriticalTilde\", {203, 156, 0}},\n{(unsigned char*)\"Diamond\", {226, 139, 132, 0}},\n{(unsigned char*)\"DifferentialD\", {226, 133, 134, 0}},\n{(unsigned char*)\"Dopf\", {240, 157, 148, 187, 0}},\n{(unsigned char*)\"Dot\", {194, 168, 0}},\n{(unsigned char*)\"DotDot\", {226, 131, 156, 0}},\n{(unsigned char*)\"DotEqual\", {226, 137, 144, 0}},\n{(unsigned char*)\"DoubleContourIntegral\", {226, 136, 175, 0}},\n{(unsigned char*)\"DoubleDot\", {194, 168, 0}},\n{(unsigned char*)\"DoubleDownArrow\", {226, 135, 147, 0}},\n{(unsigned char*)\"DoubleLeftArrow\", {226, 135, 144, 0}},\n{(unsigned char*)\"DoubleLeftRightArrow\", {226, 135, 148, 0}},\n{(unsigned char*)\"DoubleLeftTee\", {226, 171, 164, 0}},\n{(unsigned char*)\"DoubleLongLeftArrow\", {226, 159, 184, 0}},\n{(unsigned char*)\"DoubleLongLeftRightArrow\", {226, 159, 186, 0}},\n{(unsigned char*)\"DoubleLongRightArrow\", {226, 159, 185, 0}},\n{(unsigned char*)\"DoubleRightArrow\", {226, 135, 146, 0}},\n{(unsigned char*)\"DoubleRightTee\", {226, 138, 168, 0}},\n{(unsigned char*)\"DoubleUpArrow\", {226, 135, 145, 0}},\n{(unsigned char*)\"DoubleUpDownArrow\", {226, 135, 149, 0}},\n{(unsigned char*)\"DoubleVerticalBar\", {226, 136, 165, 0}},\n{(unsigned char*)\"DownArrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"DownArrowBar\", {226, 164, 147, 0}},\n{(unsigned char*)\"DownArrowUpArrow\", {226, 135, 181, 0}},\n{(unsigned char*)\"DownBreve\", {204, 145, 0}},\n{(unsigned char*)\"DownLeftRightVector\", {226, 165, 144, 0}},\n{(unsigned char*)\"DownLeftTeeVector\", {226, 165, 158, 0}},\n{(unsigned char*)\"DownLeftVector\", {226, 134, 189, 0}},\n{(unsigned char*)\"DownLeftVectorBar\", {226, 165, 150, 0}},\n{(unsigned char*)\"DownRightTeeVector\", {226, 165, 159, 0}},\n{(unsigned char*)\"DownRightVector\", {226, 135, 129, 0}},\n{(unsigned char*)\"DownRightVectorBar\", {226, 165, 151, 0}},\n{(unsigned char*)\"DownTee\", {226, 138, 164, 0}},\n{(unsigned char*)\"DownTeeArrow\", {226, 134, 167, 0}},\n{(unsigned char*)\"Downarrow\", {226, 135, 147, 0}},\n{(unsigned char*)\"Dscr\", {240, 157, 146, 159, 0}},\n{(unsigned char*)\"Dstrok\", {196, 144, 0}},\n{(unsigned char*)\"ENG\", {197, 138, 0}},\n{(unsigned char*)\"ETH\", {195, 144, 0}},\n{(unsigned char*)\"Eacute\", {195, 137, 0}},\n{(unsigned char*)\"Ecaron\", {196, 154, 0}},\n{(unsigned char*)\"Ecirc\", {195, 138, 0}},\n{(unsigned char*)\"Ecy\", {208, 173, 0}},\n{(unsigned char*)\"Edot\", {196, 150, 0}},\n{(unsigned char*)\"Efr\", {240, 157, 148, 136, 0}},\n{(unsigned char*)\"Egrave\", {195, 136, 0}},\n{(unsigned char*)\"Element\", {226, 136, 136, 0}},\n{(unsigned char*)\"Emacr\", {196, 146, 0}},\n{(unsigned char*)\"EmptySmallSquare\", {226, 151, 187, 0}},\n{(unsigned char*)\"EmptyVerySmallSquare\", {226, 150, 171, 0}},\n{(unsigned char*)\"Eogon\", {196, 152, 0}},\n{(unsigned char*)\"Eopf\", {240, 157, 148, 188, 0}},\n{(unsigned char*)\"Epsilon\", {206, 149, 0}},\n{(unsigned char*)\"Equal\", {226, 169, 181, 0}},\n{(unsigned char*)\"EqualTilde\", {226, 137, 130, 0}},\n{(unsigned char*)\"Equilibrium\", {226, 135, 140, 0}},\n{(unsigned char*)\"Escr\", {226, 132, 176, 0}},\n{(unsigned char*)\"Esim\", {226, 169, 179, 0}},\n{(unsigned char*)\"Eta\", {206, 151, 0}},\n{(unsigned char*)\"Euml\", {195, 139, 0}},\n{(unsigned char*)\"Exists\", {226, 136, 131, 0}},\n{(unsigned char*)\"ExponentialE\", {226, 133, 135, 0}},\n{(unsigned char*)\"Fcy\", {208, 164, 0}},\n{(unsigned char*)\"Ffr\", {240, 157, 148, 137, 0}},\n{(unsigned char*)\"FilledSmallSquare\", {226, 151, 188, 0}},\n{(unsigned char*)\"FilledVerySmallSquare\", {226, 150, 170, 0}},\n{(unsigned char*)\"Fopf\", {240, 157, 148, 189, 0}},\n{(unsigned char*)\"ForAll\", {226, 136, 128, 0}},\n{(unsigned char*)\"Fouriertrf\", {226, 132, 177, 0}},\n{(unsigned char*)\"Fscr\", {226, 132, 177, 0}},\n{(unsigned char*)\"GJcy\", {208, 131, 0}},\n{(unsigned char*)\"GT\", {62, 0}},\n{(unsigned char*)\"Gamma\", {206, 147, 0}},\n{(unsigned char*)\"Gammad\", {207, 156, 0}},\n{(unsigned char*)\"Gbreve\", {196, 158, 0}},\n{(unsigned char*)\"Gcedil\", {196, 162, 0}},\n{(unsigned char*)\"Gcirc\", {196, 156, 0}},\n{(unsigned char*)\"Gcy\", {208, 147, 0}},\n{(unsigned char*)\"Gdot\", {196, 160, 0}},\n{(unsigned char*)\"Gfr\", {240, 157, 148, 138, 0}},\n{(unsigned char*)\"Gg\", {226, 139, 153, 0}},\n{(unsigned char*)\"Gopf\", {240, 157, 148, 190, 0}},\n{(unsigned char*)\"GreaterEqual\", {226, 137, 165, 0}},\n{(unsigned char*)\"GreaterEqualLess\", {226, 139, 155, 0}},\n{(unsigned char*)\"GreaterFullEqual\", {226, 137, 167, 0}},\n{(unsigned char*)\"GreaterGreater\", {226, 170, 162, 0}},\n{(unsigned char*)\"GreaterLess\", {226, 137, 183, 0}},\n{(unsigned char*)\"GreaterSlantEqual\", {226, 169, 190, 0}},\n{(unsigned char*)\"GreaterTilde\", {226, 137, 179, 0}},\n{(unsigned char*)\"Gscr\", {240, 157, 146, 162, 0}},\n{(unsigned char*)\"Gt\", {226, 137, 171, 0}},\n{(unsigned char*)\"HARDcy\", {208, 170, 0}},\n{(unsigned char*)\"Hacek\", {203, 135, 0}},\n{(unsigned char*)\"Hat\", {94, 0}},\n{(unsigned char*)\"Hcirc\", {196, 164, 0}},\n{(unsigned char*)\"Hfr\", {226, 132, 140, 0}},\n{(unsigned char*)\"HilbertSpace\", {226, 132, 139, 0}},\n{(unsigned char*)\"Hopf\", {226, 132, 141, 0}},\n{(unsigned char*)\"HorizontalLine\", {226, 148, 128, 0}},\n{(unsigned char*)\"Hscr\", {226, 132, 139, 0}},\n{(unsigned char*)\"Hstrok\", {196, 166, 0}},\n{(unsigned char*)\"HumpDownHump\", {226, 137, 142, 0}},\n{(unsigned char*)\"HumpEqual\", {226, 137, 143, 0}},\n{(unsigned char*)\"IEcy\", {208, 149, 0}},\n{(unsigned char*)\"IJlig\", {196, 178, 0}},\n{(unsigned char*)\"IOcy\", {208, 129, 0}},\n{(unsigned char*)\"Iacute\", {195, 141, 0}},\n{(unsigned char*)\"Icirc\", {195, 142, 0}},\n{(unsigned char*)\"Icy\", {208, 152, 0}},\n{(unsigned char*)\"Idot\", {196, 176, 0}},\n{(unsigned char*)\"Ifr\", {226, 132, 145, 0}},\n{(unsigned char*)\"Igrave\", {195, 140, 0}},\n{(unsigned char*)\"Im\", {226, 132, 145, 0}},\n{(unsigned char*)\"Imacr\", {196, 170, 0}},\n{(unsigned char*)\"ImaginaryI\", {226, 133, 136, 0}},\n{(unsigned char*)\"Implies\", {226, 135, 146, 0}},\n{(unsigned char*)\"Int\", {226, 136, 172, 0}},\n{(unsigned char*)\"Integral\", {226, 136, 171, 0}},\n{(unsigned char*)\"Intersection\", {226, 139, 130, 0}},\n{(unsigned char*)\"InvisibleComma\", {226, 129, 163, 0}},\n{(unsigned char*)\"InvisibleTimes\", {226, 129, 162, 0}},\n{(unsigned char*)\"Iogon\", {196, 174, 0}},\n{(unsigned char*)\"Iopf\", {240, 157, 149, 128, 0}},\n{(unsigned char*)\"Iota\", {206, 153, 0}},\n{(unsigned char*)\"Iscr\", {226, 132, 144, 0}},\n{(unsigned char*)\"Itilde\", {196, 168, 0}},\n{(unsigned char*)\"Iukcy\", {208, 134, 0}},\n{(unsigned char*)\"Iuml\", {195, 143, 0}},\n{(unsigned char*)\"Jcirc\", {196, 180, 0}},\n{(unsigned char*)\"Jcy\", {208, 153, 0}},\n{(unsigned char*)\"Jfr\", {240, 157, 148, 141, 0}},\n{(unsigned char*)\"Jopf\", {240, 157, 149, 129, 0}},\n{(unsigned char*)\"Jscr\", {240, 157, 146, 165, 0}},\n{(unsigned char*)\"Jsercy\", {208, 136, 0}},\n{(unsigned char*)\"Jukcy\", {208, 132, 0}},\n{(unsigned char*)\"KHcy\", {208, 165, 0}},\n{(unsigned char*)\"KJcy\", {208, 140, 0}},\n{(unsigned char*)\"Kappa\", {206, 154, 0}},\n{(unsigned char*)\"Kcedil\", {196, 182, 0}},\n{(unsigned char*)\"Kcy\", {208, 154, 0}},\n{(unsigned char*)\"Kfr\", {240, 157, 148, 142, 0}},\n{(unsigned char*)\"Kopf\", {240, 157, 149, 130, 0}},\n{(unsigned char*)\"Kscr\", {240, 157, 146, 166, 0}},\n{(unsigned char*)\"LJcy\", {208, 137, 0}},\n{(unsigned char*)\"LT\", {60, 0}},\n{(unsigned char*)\"Lacute\", {196, 185, 0}},\n{(unsigned char*)\"Lambda\", {206, 155, 0}},\n{(unsigned char*)\"Lang\", {226, 159, 170, 0}},\n{(unsigned char*)\"Laplacetrf\", {226, 132, 146, 0}},\n{(unsigned char*)\"Larr\", {226, 134, 158, 0}},\n{(unsigned char*)\"Lcaron\", {196, 189, 0}},\n{(unsigned char*)\"Lcedil\", {196, 187, 0}},\n{(unsigned char*)\"Lcy\", {208, 155, 0}},\n{(unsigned char*)\"LeftAngleBracket\", {226, 159, 168, 0}},\n{(unsigned char*)\"LeftArrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"LeftArrowBar\", {226, 135, 164, 0}},\n{(unsigned char*)\"LeftArrowRightArrow\", {226, 135, 134, 0}},\n{(unsigned char*)\"LeftCeiling\", {226, 140, 136, 0}},\n{(unsigned char*)\"LeftDoubleBracket\", {226, 159, 166, 0}},\n{(unsigned char*)\"LeftDownTeeVector\", {226, 165, 161, 0}},\n{(unsigned char*)\"LeftDownVector\", {226, 135, 131, 0}},\n{(unsigned char*)\"LeftDownVectorBar\", {226, 165, 153, 0}},\n{(unsigned char*)\"LeftFloor\", {226, 140, 138, 0}},\n{(unsigned char*)\"LeftRightArrow\", {226, 134, 148, 0}},\n{(unsigned char*)\"LeftRightVector\", {226, 165, 142, 0}},\n{(unsigned char*)\"LeftTee\", {226, 138, 163, 0}},\n{(unsigned char*)\"LeftTeeArrow\", {226, 134, 164, 0}},\n{(unsigned char*)\"LeftTeeVector\", {226, 165, 154, 0}},\n{(unsigned char*)\"LeftTriangle\", {226, 138, 178, 0}},\n{(unsigned char*)\"LeftTriangleBar\", {226, 167, 143, 0}},\n{(unsigned char*)\"LeftTriangleEqual\", {226, 138, 180, 0}},\n{(unsigned char*)\"LeftUpDownVector\", {226, 165, 145, 0}},\n{(unsigned char*)\"LeftUpTeeVector\", {226, 165, 160, 0}},\n{(unsigned char*)\"LeftUpVector\", {226, 134, 191, 0}},\n{(unsigned char*)\"LeftUpVectorBar\", {226, 165, 152, 0}},\n{(unsigned char*)\"LeftVector\", {226, 134, 188, 0}},\n{(unsigned char*)\"LeftVectorBar\", {226, 165, 146, 0}},\n{(unsigned char*)\"Leftarrow\", {226, 135, 144, 0}},\n{(unsigned char*)\"Leftrightarrow\", {226, 135, 148, 0}},\n{(unsigned char*)\"LessEqualGreater\", {226, 139, 154, 0}},\n{(unsigned char*)\"LessFullEqual\", {226, 137, 166, 0}},\n{(unsigned char*)\"LessGreater\", {226, 137, 182, 0}},\n{(unsigned char*)\"LessLess\", {226, 170, 161, 0}},\n{(unsigned char*)\"LessSlantEqual\", {226, 169, 189, 0}},\n{(unsigned char*)\"LessTilde\", {226, 137, 178, 0}},\n{(unsigned char*)\"Lfr\", {240, 157, 148, 143, 0}},\n{(unsigned char*)\"Ll\", {226, 139, 152, 0}},\n{(unsigned char*)\"Lleftarrow\", {226, 135, 154, 0}},\n{(unsigned char*)\"Lmidot\", {196, 191, 0}},\n{(unsigned char*)\"LongLeftArrow\", {226, 159, 181, 0}},\n{(unsigned char*)\"LongLeftRightArrow\", {226, 159, 183, 0}},\n{(unsigned char*)\"LongRightArrow\", {226, 159, 182, 0}},\n{(unsigned char*)\"Longleftarrow\", {226, 159, 184, 0}},\n{(unsigned char*)\"Longleftrightarrow\", {226, 159, 186, 0}},\n{(unsigned char*)\"Longrightarrow\", {226, 159, 185, 0}},\n{(unsigned char*)\"Lopf\", {240, 157, 149, 131, 0}},\n{(unsigned char*)\"LowerLeftArrow\", {226, 134, 153, 0}},\n{(unsigned char*)\"LowerRightArrow\", {226, 134, 152, 0}},\n{(unsigned char*)\"Lscr\", {226, 132, 146, 0}},\n{(unsigned char*)\"Lsh\", {226, 134, 176, 0}},\n{(unsigned char*)\"Lstrok\", {197, 129, 0}},\n{(unsigned char*)\"Lt\", {226, 137, 170, 0}},\n{(unsigned char*)\"Map\", {226, 164, 133, 0}},\n{(unsigned char*)\"Mcy\", {208, 156, 0}},\n{(unsigned char*)\"MediumSpace\", {226, 129, 159, 0}},\n{(unsigned char*)\"Mellintrf\", {226, 132, 179, 0}},\n{(unsigned char*)\"Mfr\", {240, 157, 148, 144, 0}},\n{(unsigned char*)\"MinusPlus\", {226, 136, 147, 0}},\n{(unsigned char*)\"Mopf\", {240, 157, 149, 132, 0}},\n{(unsigned char*)\"Mscr\", {226, 132, 179, 0}},\n{(unsigned char*)\"Mu\", {206, 156, 0}},\n{(unsigned char*)\"NJcy\", {208, 138, 0}},\n{(unsigned char*)\"Nacute\", {197, 131, 0}},\n{(unsigned char*)\"Ncaron\", {197, 135, 0}},\n{(unsigned char*)\"Ncedil\", {197, 133, 0}},\n{(unsigned char*)\"Ncy\", {208, 157, 0}},\n{(unsigned char*)\"NegativeMediumSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeThickSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeThinSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeVeryThinSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NestedGreaterGreater\", {226, 137, 171, 0}},\n{(unsigned char*)\"NestedLessLess\", {226, 137, 170, 0}},\n{(unsigned char*)\"NewLine\", {10, 0}},\n{(unsigned char*)\"Nfr\", {240, 157, 148, 145, 0}},\n{(unsigned char*)\"NoBreak\", {226, 129, 160, 0}},\n{(unsigned char*)\"NonBreakingSpace\", {194, 160, 0}},\n{(unsigned char*)\"Nopf\", {226, 132, 149, 0}},\n{(unsigned char*)\"Not\", {226, 171, 172, 0}},\n{(unsigned char*)\"NotCongruent\", {226, 137, 162, 0}},\n{(unsigned char*)\"NotCupCap\", {226, 137, 173, 0}},\n{(unsigned char*)\"NotDoubleVerticalBar\", {226, 136, 166, 0}},\n{(unsigned char*)\"NotElement\", {226, 136, 137, 0}},\n{(unsigned char*)\"NotEqual\", {226, 137, 160, 0}},\n{(unsigned char*)\"NotEqualTilde\", {226, 137, 130, 204, 184, 0}},\n{(unsigned char*)\"NotExists\", {226, 136, 132, 0}},\n{(unsigned char*)\"NotGreater\", {226, 137, 175, 0}},\n{(unsigned char*)\"NotGreaterEqual\", {226, 137, 177, 0}},\n{(unsigned char*)\"NotGreaterFullEqual\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterGreater\", {226, 137, 171, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterLess\", {226, 137, 185, 0}},\n{(unsigned char*)\"NotGreaterSlantEqual\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterTilde\", {226, 137, 181, 0}},\n{(unsigned char*)\"NotHumpDownHump\", {226, 137, 142, 204, 184, 0}},\n{(unsigned char*)\"NotHumpEqual\", {226, 137, 143, 204, 184, 0}},\n{(unsigned char*)\"NotLeftTriangle\", {226, 139, 170, 0}},\n{(unsigned char*)\"NotLeftTriangleBar\", {226, 167, 143, 204, 184, 0}},\n{(unsigned char*)\"NotLeftTriangleEqual\", {226, 139, 172, 0}},\n{(unsigned char*)\"NotLess\", {226, 137, 174, 0}},\n{(unsigned char*)\"NotLessEqual\", {226, 137, 176, 0}},\n{(unsigned char*)\"NotLessGreater\", {226, 137, 184, 0}},\n{(unsigned char*)\"NotLessLess\", {226, 137, 170, 204, 184, 0}},\n{(unsigned char*)\"NotLessSlantEqual\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"NotLessTilde\", {226, 137, 180, 0}},\n{(unsigned char*)\"NotNestedGreaterGreater\", {226, 170, 162, 204, 184, 0}},\n{(unsigned char*)\"NotNestedLessLess\", {226, 170, 161, 204, 184, 0}},\n{(unsigned char*)\"NotPrecedes\", {226, 138, 128, 0}},\n{(unsigned char*)\"NotPrecedesEqual\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"NotPrecedesSlantEqual\", {226, 139, 160, 0}},\n{(unsigned char*)\"NotReverseElement\", {226, 136, 140, 0}},\n{(unsigned char*)\"NotRightTriangle\", {226, 139, 171, 0}},\n{(unsigned char*)\"NotRightTriangleBar\", {226, 167, 144, 204, 184, 0}},\n{(unsigned char*)\"NotRightTriangleEqual\", {226, 139, 173, 0}},\n{(unsigned char*)\"NotSquareSubset\", {226, 138, 143, 204, 184, 0}},\n{(unsigned char*)\"NotSquareSubsetEqual\", {226, 139, 162, 0}},\n{(unsigned char*)\"NotSquareSuperset\", {226, 138, 144, 204, 184, 0}},\n{(unsigned char*)\"NotSquareSupersetEqual\", {226, 139, 163, 0}},\n{(unsigned char*)\"NotSubset\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"NotSubsetEqual\", {226, 138, 136, 0}},\n{(unsigned char*)\"NotSucceeds\", {226, 138, 129, 0}},\n{(unsigned char*)\"NotSucceedsEqual\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"NotSucceedsSlantEqual\", {226, 139, 161, 0}},\n{(unsigned char*)\"NotSucceedsTilde\", {226, 137, 191, 204, 184, 0}},\n{(unsigned char*)\"NotSuperset\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"NotSupersetEqual\", {226, 138, 137, 0}},\n{(unsigned char*)\"NotTilde\", {226, 137, 129, 0}},\n{(unsigned char*)\"NotTildeEqual\", {226, 137, 132, 0}},\n{(unsigned char*)\"NotTildeFullEqual\", {226, 137, 135, 0}},\n{(unsigned char*)\"NotTildeTilde\", {226, 137, 137, 0}},\n{(unsigned char*)\"NotVerticalBar\", {226, 136, 164, 0}},\n{(unsigned char*)\"Nscr\", {240, 157, 146, 169, 0}},\n{(unsigned char*)\"Ntilde\", {195, 145, 0}},\n{(unsigned char*)\"Nu\", {206, 157, 0}},\n{(unsigned char*)\"OElig\", {197, 146, 0}},\n{(unsigned char*)\"Oacute\", {195, 147, 0}},\n{(unsigned char*)\"Ocirc\", {195, 148, 0}},\n{(unsigned char*)\"Ocy\", {208, 158, 0}},\n{(unsigned char*)\"Odblac\", {197, 144, 0}},\n{(unsigned char*)\"Ofr\", {240, 157, 148, 146, 0}},\n{(unsigned char*)\"Ograve\", {195, 146, 0}},\n{(unsigned char*)\"Omacr\", {197, 140, 0}},\n{(unsigned char*)\"Omega\", {206, 169, 0}},\n{(unsigned char*)\"Omicron\", {206, 159, 0}},\n{(unsigned char*)\"Oopf\", {240, 157, 149, 134, 0}},\n{(unsigned char*)\"OpenCurlyDoubleQuote\", {226, 128, 156, 0}},\n{(unsigned char*)\"OpenCurlyQuote\", {226, 128, 152, 0}},\n{(unsigned char*)\"Or\", {226, 169, 148, 0}},\n{(unsigned char*)\"Oscr\", {240, 157, 146, 170, 0}},\n{(unsigned char*)\"Oslash\", {195, 152, 0}},\n{(unsigned char*)\"Otilde\", {195, 149, 0}},\n{(unsigned char*)\"Otimes\", {226, 168, 183, 0}},\n{(unsigned char*)\"Ouml\", {195, 150, 0}},\n{(unsigned char*)\"OverBar\", {226, 128, 190, 0}},\n{(unsigned char*)\"OverBrace\", {226, 143, 158, 0}},\n{(unsigned char*)\"OverBracket\", {226, 142, 180, 0}},\n{(unsigned char*)\"OverParenthesis\", {226, 143, 156, 0}},\n{(unsigned char*)\"PartialD\", {226, 136, 130, 0}},\n{(unsigned char*)\"Pcy\", {208, 159, 0}},\n{(unsigned char*)\"Pfr\", {240, 157, 148, 147, 0}},\n{(unsigned char*)\"Phi\", {206, 166, 0}},\n{(unsigned char*)\"Pi\", {206, 160, 0}},\n{(unsigned char*)\"PlusMinus\", {194, 177, 0}},\n{(unsigned char*)\"Poincareplane\", {226, 132, 140, 0}},\n{(unsigned char*)\"Popf\", {226, 132, 153, 0}},\n{(unsigned char*)\"Pr\", {226, 170, 187, 0}},\n{(unsigned char*)\"Precedes\", {226, 137, 186, 0}},\n{(unsigned char*)\"PrecedesEqual\", {226, 170, 175, 0}},\n{(unsigned char*)\"PrecedesSlantEqual\", {226, 137, 188, 0}},\n{(unsigned char*)\"PrecedesTilde\", {226, 137, 190, 0}},\n{(unsigned char*)\"Prime\", {226, 128, 179, 0}},\n{(unsigned char*)\"Product\", {226, 136, 143, 0}},\n{(unsigned char*)\"Proportion\", {226, 136, 183, 0}},\n{(unsigned char*)\"Proportional\", {226, 136, 157, 0}},\n{(unsigned char*)\"Pscr\", {240, 157, 146, 171, 0}},\n{(unsigned char*)\"Psi\", {206, 168, 0}},\n{(unsigned char*)\"QUOT\", {34, 0}},\n{(unsigned char*)\"Qfr\", {240, 157, 148, 148, 0}},\n{(unsigned char*)\"Qopf\", {226, 132, 154, 0}},\n{(unsigned char*)\"Qscr\", {240, 157, 146, 172, 0}},\n{(unsigned char*)\"RBarr\", {226, 164, 144, 0}},\n{(unsigned char*)\"REG\", {194, 174, 0}},\n{(unsigned char*)\"Racute\", {197, 148, 0}},\n{(unsigned char*)\"Rang\", {226, 159, 171, 0}},\n{(unsigned char*)\"Rarr\", {226, 134, 160, 0}},\n{(unsigned char*)\"Rarrtl\", {226, 164, 150, 0}},\n{(unsigned char*)\"Rcaron\", {197, 152, 0}},\n{(unsigned char*)\"Rcedil\", {197, 150, 0}},\n{(unsigned char*)\"Rcy\", {208, 160, 0}},\n{(unsigned char*)\"Re\", {226, 132, 156, 0}},\n{(unsigned char*)\"ReverseElement\", {226, 136, 139, 0}},\n{(unsigned char*)\"ReverseEquilibrium\", {226, 135, 139, 0}},\n{(unsigned char*)\"ReverseUpEquilibrium\", {226, 165, 175, 0}},\n{(unsigned char*)\"Rfr\", {226, 132, 156, 0}},\n{(unsigned char*)\"Rho\", {206, 161, 0}},\n{(unsigned char*)\"RightAngleBracket\", {226, 159, 169, 0}},\n{(unsigned char*)\"RightArrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"RightArrowBar\", {226, 135, 165, 0}},\n{(unsigned char*)\"RightArrowLeftArrow\", {226, 135, 132, 0}},\n{(unsigned char*)\"RightCeiling\", {226, 140, 137, 0}},\n{(unsigned char*)\"RightDoubleBracket\", {226, 159, 167, 0}},\n{(unsigned char*)\"RightDownTeeVector\", {226, 165, 157, 0}},\n{(unsigned char*)\"RightDownVector\", {226, 135, 130, 0}},\n{(unsigned char*)\"RightDownVectorBar\", {226, 165, 149, 0}},\n{(unsigned char*)\"RightFloor\", {226, 140, 139, 0}},\n{(unsigned char*)\"RightTee\", {226, 138, 162, 0}},\n{(unsigned char*)\"RightTeeArrow\", {226, 134, 166, 0}},\n{(unsigned char*)\"RightTeeVector\", {226, 165, 155, 0}},\n{(unsigned char*)\"RightTriangle\", {226, 138, 179, 0}},\n{(unsigned char*)\"RightTriangleBar\", {226, 167, 144, 0}},\n{(unsigned char*)\"RightTriangleEqual\", {226, 138, 181, 0}},\n{(unsigned char*)\"RightUpDownVector\", {226, 165, 143, 0}},\n{(unsigned char*)\"RightUpTeeVector\", {226, 165, 156, 0}},\n{(unsigned char*)\"RightUpVector\", {226, 134, 190, 0}},\n{(unsigned char*)\"RightUpVectorBar\", {226, 165, 148, 0}},\n{(unsigned char*)\"RightVector\", {226, 135, 128, 0}},\n{(unsigned char*)\"RightVectorBar\", {226, 165, 147, 0}},\n{(unsigned char*)\"Rightarrow\", {226, 135, 146, 0}},\n{(unsigned char*)\"Ropf\", {226, 132, 157, 0}},\n{(unsigned char*)\"RoundImplies\", {226, 165, 176, 0}},\n{(unsigned char*)\"Rrightarrow\", {226, 135, 155, 0}},\n{(unsigned char*)\"Rscr\", {226, 132, 155, 0}},\n{(unsigned char*)\"Rsh\", {226, 134, 177, 0}},\n{(unsigned char*)\"RuleDelayed\", {226, 167, 180, 0}},\n{(unsigned char*)\"SHCHcy\", {208, 169, 0}},\n{(unsigned char*)\"SHcy\", {208, 168, 0}},\n{(unsigned char*)\"SOFTcy\", {208, 172, 0}},\n{(unsigned char*)\"Sacute\", {197, 154, 0}},\n{(unsigned char*)\"Sc\", {226, 170, 188, 0}},\n{(unsigned char*)\"Scaron\", {197, 160, 0}},\n{(unsigned char*)\"Scedil\", {197, 158, 0}},\n{(unsigned char*)\"Scirc\", {197, 156, 0}},\n{(unsigned char*)\"Scy\", {208, 161, 0}},\n{(unsigned char*)\"Sfr\", {240, 157, 148, 150, 0}},\n{(unsigned char*)\"ShortDownArrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"ShortLeftArrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"ShortRightArrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"ShortUpArrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"Sigma\", {206, 163, 0}},\n{(unsigned char*)\"SmallCircle\", {226, 136, 152, 0}},\n{(unsigned char*)\"Sopf\", {240, 157, 149, 138, 0}},\n{(unsigned char*)\"Sqrt\", {226, 136, 154, 0}},\n{(unsigned char*)\"Square\", {226, 150, 161, 0}},\n{(unsigned char*)\"SquareIntersection\", {226, 138, 147, 0}},\n{(unsigned char*)\"SquareSubset\", {226, 138, 143, 0}},\n{(unsigned char*)\"SquareSubsetEqual\", {226, 138, 145, 0}},\n{(unsigned char*)\"SquareSuperset\", {226, 138, 144, 0}},\n{(unsigned char*)\"SquareSupersetEqual\", {226, 138, 146, 0}},\n{(unsigned char*)\"SquareUnion\", {226, 138, 148, 0}},\n{(unsigned char*)\"Sscr\", {240, 157, 146, 174, 0}},\n{(unsigned char*)\"Star\", {226, 139, 134, 0}},\n{(unsigned char*)\"Sub\", {226, 139, 144, 0}},\n{(unsigned char*)\"Subset\", {226, 139, 144, 0}},\n{(unsigned char*)\"SubsetEqual\", {226, 138, 134, 0}},\n{(unsigned char*)\"Succeeds\", {226, 137, 187, 0}},\n{(unsigned char*)\"SucceedsEqual\", {226, 170, 176, 0}},\n{(unsigned char*)\"SucceedsSlantEqual\", {226, 137, 189, 0}},\n{(unsigned char*)\"SucceedsTilde\", {226, 137, 191, 0}},\n{(unsigned char*)\"SuchThat\", {226, 136, 139, 0}},\n{(unsigned char*)\"Sum\", {226, 136, 145, 0}},\n{(unsigned char*)\"Sup\", {226, 139, 145, 0}},\n{(unsigned char*)\"Superset\", {226, 138, 131, 0}},\n{(unsigned char*)\"SupersetEqual\", {226, 138, 135, 0}},\n{(unsigned char*)\"Supset\", {226, 139, 145, 0}},\n{(unsigned char*)\"THORN\", {195, 158, 0}},\n{(unsigned char*)\"TRADE\", {226, 132, 162, 0}},\n{(unsigned char*)\"TSHcy\", {208, 139, 0}},\n{(unsigned char*)\"TScy\", {208, 166, 0}},\n{(unsigned char*)\"Tab\", {9, 0}},\n{(unsigned char*)\"Tau\", {206, 164, 0}},\n{(unsigned char*)\"Tcaron\", {197, 164, 0}},\n{(unsigned char*)\"Tcedil\", {197, 162, 0}},\n{(unsigned char*)\"Tcy\", {208, 162, 0}},\n{(unsigned char*)\"Tfr\", {240, 157, 148, 151, 0}},\n{(unsigned char*)\"Therefore\", {226, 136, 180, 0}},\n{(unsigned char*)\"Theta\", {206, 152, 0}},\n{(unsigned char*)\"ThickSpace\", {226, 129, 159, 226, 128, 138, 0}},\n{(unsigned char*)\"ThinSpace\", {226, 128, 137, 0}},\n{(unsigned char*)\"Tilde\", {226, 136, 188, 0}},\n{(unsigned char*)\"TildeEqual\", {226, 137, 131, 0}},\n{(unsigned char*)\"TildeFullEqual\", {226, 137, 133, 0}},\n{(unsigned char*)\"TildeTilde\", {226, 137, 136, 0}},\n{(unsigned char*)\"Topf\", {240, 157, 149, 139, 0}},\n{(unsigned char*)\"TripleDot\", {226, 131, 155, 0}},\n{(unsigned char*)\"Tscr\", {240, 157, 146, 175, 0}},\n{(unsigned char*)\"Tstrok\", {197, 166, 0}},\n{(unsigned char*)\"Uacute\", {195, 154, 0}},\n{(unsigned char*)\"Uarr\", {226, 134, 159, 0}},\n{(unsigned char*)\"Uarrocir\", {226, 165, 137, 0}},\n{(unsigned char*)\"Ubrcy\", {208, 142, 0}},\n{(unsigned char*)\"Ubreve\", {197, 172, 0}},\n{(unsigned char*)\"Ucirc\", {195, 155, 0}},\n{(unsigned char*)\"Ucy\", {208, 163, 0}},\n{(unsigned char*)\"Udblac\", {197, 176, 0}},\n{(unsigned char*)\"Ufr\", {240, 157, 148, 152, 0}},\n{(unsigned char*)\"Ugrave\", {195, 153, 0}},\n{(unsigned char*)\"Umacr\", {197, 170, 0}},\n{(unsigned char*)\"UnderBar\", {95, 0}},\n{(unsigned char*)\"UnderBrace\", {226, 143, 159, 0}},\n{(unsigned char*)\"UnderBracket\", {226, 142, 181, 0}},\n{(unsigned char*)\"UnderParenthesis\", {226, 143, 157, 0}},\n{(unsigned char*)\"Union\", {226, 139, 131, 0}},\n{(unsigned char*)\"UnionPlus\", {226, 138, 142, 0}},\n{(unsigned char*)\"Uogon\", {197, 178, 0}},\n{(unsigned char*)\"Uopf\", {240, 157, 149, 140, 0}},\n{(unsigned char*)\"UpArrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"UpArrowBar\", {226, 164, 146, 0}},\n{(unsigned char*)\"UpArrowDownArrow\", {226, 135, 133, 0}},\n{(unsigned char*)\"UpDownArrow\", {226, 134, 149, 0}},\n{(unsigned char*)\"UpEquilibrium\", {226, 165, 174, 0}},\n{(unsigned char*)\"UpTee\", {226, 138, 165, 0}},\n{(unsigned char*)\"UpTeeArrow\", {226, 134, 165, 0}},\n{(unsigned char*)\"Uparrow\", {226, 135, 145, 0}},\n{(unsigned char*)\"Updownarrow\", {226, 135, 149, 0}},\n{(unsigned char*)\"UpperLeftArrow\", {226, 134, 150, 0}},\n{(unsigned char*)\"UpperRightArrow\", {226, 134, 151, 0}},\n{(unsigned char*)\"Upsi\", {207, 146, 0}},\n{(unsigned char*)\"Upsilon\", {206, 165, 0}},\n{(unsigned char*)\"Uring\", {197, 174, 0}},\n{(unsigned char*)\"Uscr\", {240, 157, 146, 176, 0}},\n{(unsigned char*)\"Utilde\", {197, 168, 0}},\n{(unsigned char*)\"Uuml\", {195, 156, 0}},\n{(unsigned char*)\"VDash\", {226, 138, 171, 0}},\n{(unsigned char*)\"Vbar\", {226, 171, 171, 0}},\n{(unsigned char*)\"Vcy\", {208, 146, 0}},\n{(unsigned char*)\"Vdash\", {226, 138, 169, 0}},\n{(unsigned char*)\"Vdashl\", {226, 171, 166, 0}},\n{(unsigned char*)\"Vee\", {226, 139, 129, 0}},\n{(unsigned char*)\"Verbar\", {226, 128, 150, 0}},\n{(unsigned char*)\"Vert\", {226, 128, 150, 0}},\n{(unsigned char*)\"VerticalBar\", {226, 136, 163, 0}},\n{(unsigned char*)\"VerticalLine\", {124, 0}},\n{(unsigned char*)\"VerticalSeparator\", {226, 157, 152, 0}},\n{(unsigned char*)\"VerticalTilde\", {226, 137, 128, 0}},\n{(unsigned char*)\"VeryThinSpace\", {226, 128, 138, 0}},\n{(unsigned char*)\"Vfr\", {240, 157, 148, 153, 0}},\n{(unsigned char*)\"Vopf\", {240, 157, 149, 141, 0}},\n{(unsigned char*)\"Vscr\", {240, 157, 146, 177, 0}},\n{(unsigned char*)\"Vvdash\", {226, 138, 170, 0}},\n{(unsigned char*)\"Wcirc\", {197, 180, 0}},\n{(unsigned char*)\"Wedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"Wfr\", {240, 157, 148, 154, 0}},\n{(unsigned char*)\"Wopf\", {240, 157, 149, 142, 0}},\n{(unsigned char*)\"Wscr\", {240, 157, 146, 178, 0}},\n{(unsigned char*)\"Xfr\", {240, 157, 148, 155, 0}},\n{(unsigned char*)\"Xi\", {206, 158, 0}},\n{(unsigned char*)\"Xopf\", {240, 157, 149, 143, 0}},\n{(unsigned char*)\"Xscr\", {240, 157, 146, 179, 0}},\n{(unsigned char*)\"YAcy\", {208, 175, 0}},\n{(unsigned char*)\"YIcy\", {208, 135, 0}},\n{(unsigned char*)\"YUcy\", {208, 174, 0}},\n{(unsigned char*)\"Yacute\", {195, 157, 0}},\n{(unsigned char*)\"Ycirc\", {197, 182, 0}},\n{(unsigned char*)\"Ycy\", {208, 171, 0}},\n{(unsigned char*)\"Yfr\", {240, 157, 148, 156, 0}},\n{(unsigned char*)\"Yopf\", {240, 157, 149, 144, 0}},\n{(unsigned char*)\"Yscr\", {240, 157, 146, 180, 0}},\n{(unsigned char*)\"Yuml\", {197, 184, 0}},\n{(unsigned char*)\"ZHcy\", {208, 150, 0}},\n{(unsigned char*)\"Zacute\", {197, 185, 0}},\n{(unsigned char*)\"Zcaron\", {197, 189, 0}},\n{(unsigned char*)\"Zcy\", {208, 151, 0}},\n{(unsigned char*)\"Zdot\", {197, 187, 0}},\n{(unsigned char*)\"ZeroWidthSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"Zeta\", {206, 150, 0}},\n{(unsigned char*)\"Zfr\", {226, 132, 168, 0}},\n{(unsigned char*)\"Zopf\", {226, 132, 164, 0}},\n{(unsigned char*)\"Zscr\", {240, 157, 146, 181, 0}},\n{(unsigned char*)\"aacute\", {195, 161, 0}},\n{(unsigned char*)\"abreve\", {196, 131, 0}},\n{(unsigned char*)\"ac\", {226, 136, 190, 0}},\n{(unsigned char*)\"acE\", {226, 136, 190, 204, 179, 0}},\n{(unsigned char*)\"acd\", {226, 136, 191, 0}},\n{(unsigned char*)\"acirc\", {195, 162, 0}},\n{(unsigned char*)\"acute\", {194, 180, 0}},\n{(unsigned char*)\"acy\", {208, 176, 0}},\n{(unsigned char*)\"aelig\", {195, 166, 0}},\n{(unsigned char*)\"af\", {226, 129, 161, 0}},\n{(unsigned char*)\"afr\", {240, 157, 148, 158, 0}},\n{(unsigned char*)\"agrave\", {195, 160, 0}},\n{(unsigned char*)\"alefsym\", {226, 132, 181, 0}},\n{(unsigned char*)\"aleph\", {226, 132, 181, 0}},\n{(unsigned char*)\"alpha\", {206, 177, 0}},\n{(unsigned char*)\"amacr\", {196, 129, 0}},\n{(unsigned char*)\"amalg\", {226, 168, 191, 0}},\n{(unsigned char*)\"amp\", {38, 0}},\n{(unsigned char*)\"and\", {226, 136, 167, 0}},\n{(unsigned char*)\"andand\", {226, 169, 149, 0}},\n{(unsigned char*)\"andd\", {226, 169, 156, 0}},\n{(unsigned char*)\"andslope\", {226, 169, 152, 0}},\n{(unsigned char*)\"andv\", {226, 169, 154, 0}},\n{(unsigned char*)\"ang\", {226, 136, 160, 0}},\n{(unsigned char*)\"ange\", {226, 166, 164, 0}},\n{(unsigned char*)\"angle\", {226, 136, 160, 0}},\n{(unsigned char*)\"angmsd\", {226, 136, 161, 0}},\n{(unsigned char*)\"angmsdaa\", {226, 166, 168, 0}},\n{(unsigned char*)\"angmsdab\", {226, 166, 169, 0}},\n{(unsigned char*)\"angmsdac\", {226, 166, 170, 0}},\n{(unsigned char*)\"angmsdad\", {226, 166, 171, 0}},\n{(unsigned char*)\"angmsdae\", {226, 166, 172, 0}},\n{(unsigned char*)\"angmsdaf\", {226, 166, 173, 0}},\n{(unsigned char*)\"angmsdag\", {226, 166, 174, 0}},\n{(unsigned char*)\"angmsdah\", {226, 166, 175, 0}},\n{(unsigned char*)\"angrt\", {226, 136, 159, 0}},\n{(unsigned char*)\"angrtvb\", {226, 138, 190, 0}},\n{(unsigned char*)\"angrtvbd\", {226, 166, 157, 0}},\n{(unsigned char*)\"angsph\", {226, 136, 162, 0}},\n{(unsigned char*)\"angst\", {195, 133, 0}},\n{(unsigned char*)\"angzarr\", {226, 141, 188, 0}},\n{(unsigned char*)\"aogon\", {196, 133, 0}},\n{(unsigned char*)\"aopf\", {240, 157, 149, 146, 0}},\n{(unsigned char*)\"ap\", {226, 137, 136, 0}},\n{(unsigned char*)\"apE\", {226, 169, 176, 0}},\n{(unsigned char*)\"apacir\", {226, 169, 175, 0}},\n{(unsigned char*)\"ape\", {226, 137, 138, 0}},\n{(unsigned char*)\"apid\", {226, 137, 139, 0}},\n{(unsigned char*)\"apos\", {39, 0}},\n{(unsigned char*)\"approx\", {226, 137, 136, 0}},\n{(unsigned char*)\"approxeq\", {226, 137, 138, 0}},\n{(unsigned char*)\"aring\", {195, 165, 0}},\n{(unsigned char*)\"ascr\", {240, 157, 146, 182, 0}},\n{(unsigned char*)\"ast\", {42, 0}},\n{(unsigned char*)\"asymp\", {226, 137, 136, 0}},\n{(unsigned char*)\"asympeq\", {226, 137, 141, 0}},\n{(unsigned char*)\"atilde\", {195, 163, 0}},\n{(unsigned char*)\"auml\", {195, 164, 0}},\n{(unsigned char*)\"awconint\", {226, 136, 179, 0}},\n{(unsigned char*)\"awint\", {226, 168, 145, 0}},\n{(unsigned char*)\"bNot\", {226, 171, 173, 0}},\n{(unsigned char*)\"backcong\", {226, 137, 140, 0}},\n{(unsigned char*)\"backepsilon\", {207, 182, 0}},\n{(unsigned char*)\"backprime\", {226, 128, 181, 0}},\n{(unsigned char*)\"backsim\", {226, 136, 189, 0}},\n{(unsigned char*)\"backsimeq\", {226, 139, 141, 0}},\n{(unsigned char*)\"barvee\", {226, 138, 189, 0}},\n{(unsigned char*)\"barwed\", {226, 140, 133, 0}},\n{(unsigned char*)\"barwedge\", {226, 140, 133, 0}},\n{(unsigned char*)\"bbrk\", {226, 142, 181, 0}},\n{(unsigned char*)\"bbrktbrk\", {226, 142, 182, 0}},\n{(unsigned char*)\"bcong\", {226, 137, 140, 0}},\n{(unsigned char*)\"bcy\", {208, 177, 0}},\n{(unsigned char*)\"bdquo\", {226, 128, 158, 0}},\n{(unsigned char*)\"becaus\", {226, 136, 181, 0}},\n{(unsigned char*)\"because\", {226, 136, 181, 0}},\n{(unsigned char*)\"bemptyv\", {226, 166, 176, 0}},\n{(unsigned char*)\"bepsi\", {207, 182, 0}},\n{(unsigned char*)\"bernou\", {226, 132, 172, 0}},\n{(unsigned char*)\"beta\", {206, 178, 0}},\n{(unsigned char*)\"beth\", {226, 132, 182, 0}},\n{(unsigned char*)\"between\", {226, 137, 172, 0}},\n{(unsigned char*)\"bfr\", {240, 157, 148, 159, 0}},\n{(unsigned char*)\"bigcap\", {226, 139, 130, 0}},\n{(unsigned char*)\"bigcirc\", {226, 151, 175, 0}},\n{(unsigned char*)\"bigcup\", {226, 139, 131, 0}},\n{(unsigned char*)\"bigodot\", {226, 168, 128, 0}},\n{(unsigned char*)\"bigoplus\", {226, 168, 129, 0}},\n{(unsigned char*)\"bigotimes\", {226, 168, 130, 0}},\n{(unsigned char*)\"bigsqcup\", {226, 168, 134, 0}},\n{(unsigned char*)\"bigstar\", {226, 152, 133, 0}},\n{(unsigned char*)\"bigtriangledown\", {226, 150, 189, 0}},\n{(unsigned char*)\"bigtriangleup\", {226, 150, 179, 0}},\n{(unsigned char*)\"biguplus\", {226, 168, 132, 0}},\n{(unsigned char*)\"bigvee\", {226, 139, 129, 0}},\n{(unsigned char*)\"bigwedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"bkarow\", {226, 164, 141, 0}},\n{(unsigned char*)\"blacklozenge\", {226, 167, 171, 0}},\n{(unsigned char*)\"blacksquare\", {226, 150, 170, 0}},\n{(unsigned char*)\"blacktriangle\", {226, 150, 180, 0}},\n{(unsigned char*)\"blacktriangledown\", {226, 150, 190, 0}},\n{(unsigned char*)\"blacktriangleleft\", {226, 151, 130, 0}},\n{(unsigned char*)\"blacktriangleright\", {226, 150, 184, 0}},\n{(unsigned char*)\"blank\", {226, 144, 163, 0}},\n{(unsigned char*)\"blk12\", {226, 150, 146, 0}},\n{(unsigned char*)\"blk14\", {226, 150, 145, 0}},\n{(unsigned char*)\"blk34\", {226, 150, 147, 0}},\n{(unsigned char*)\"block\", {226, 150, 136, 0}},\n{(unsigned char*)\"bne\", {61, 226, 131, 165, 0}},\n{(unsigned char*)\"bnequiv\", {226, 137, 161, 226, 131, 165, 0}},\n{(unsigned char*)\"bnot\", {226, 140, 144, 0}},\n{(unsigned char*)\"bopf\", {240, 157, 149, 147, 0}},\n{(unsigned char*)\"bot\", {226, 138, 165, 0}},\n{(unsigned char*)\"bottom\", {226, 138, 165, 0}},\n{(unsigned char*)\"bowtie\", {226, 139, 136, 0}},\n{(unsigned char*)\"boxDL\", {226, 149, 151, 0}},\n{(unsigned char*)\"boxDR\", {226, 149, 148, 0}},\n{(unsigned char*)\"boxDl\", {226, 149, 150, 0}},\n{(unsigned char*)\"boxDr\", {226, 149, 147, 0}},\n{(unsigned char*)\"boxH\", {226, 149, 144, 0}},\n{(unsigned char*)\"boxHD\", {226, 149, 166, 0}},\n{(unsigned char*)\"boxHU\", {226, 149, 169, 0}},\n{(unsigned char*)\"boxHd\", {226, 149, 164, 0}},\n{(unsigned char*)\"boxHu\", {226, 149, 167, 0}},\n{(unsigned char*)\"boxUL\", {226, 149, 157, 0}},\n{(unsigned char*)\"boxUR\", {226, 149, 154, 0}},\n{(unsigned char*)\"boxUl\", {226, 149, 156, 0}},\n{(unsigned char*)\"boxUr\", {226, 149, 153, 0}},\n{(unsigned char*)\"boxV\", {226, 149, 145, 0}},\n{(unsigned char*)\"boxVH\", {226, 149, 172, 0}},\n{(unsigned char*)\"boxVL\", {226, 149, 163, 0}},\n{(unsigned char*)\"boxVR\", {226, 149, 160, 0}},\n{(unsigned char*)\"boxVh\", {226, 149, 171, 0}},\n{(unsigned char*)\"boxVl\", {226, 149, 162, 0}},\n{(unsigned char*)\"boxVr\", {226, 149, 159, 0}},\n{(unsigned char*)\"boxbox\", {226, 167, 137, 0}},\n{(unsigned char*)\"boxdL\", {226, 149, 149, 0}},\n{(unsigned char*)\"boxdR\", {226, 149, 146, 0}},\n{(unsigned char*)\"boxdl\", {226, 148, 144, 0}},\n{(unsigned char*)\"boxdr\", {226, 148, 140, 0}},\n{(unsigned char*)\"boxh\", {226, 148, 128, 0}},\n{(unsigned char*)\"boxhD\", {226, 149, 165, 0}},\n{(unsigned char*)\"boxhU\", {226, 149, 168, 0}},\n{(unsigned char*)\"boxhd\", {226, 148, 172, 0}},\n{(unsigned char*)\"boxhu\", {226, 148, 180, 0}},\n{(unsigned char*)\"boxminus\", {226, 138, 159, 0}},\n{(unsigned char*)\"boxplus\", {226, 138, 158, 0}},\n{(unsigned char*)\"boxtimes\", {226, 138, 160, 0}},\n{(unsigned char*)\"boxuL\", {226, 149, 155, 0}},\n{(unsigned char*)\"boxuR\", {226, 149, 152, 0}},\n{(unsigned char*)\"boxul\", {226, 148, 152, 0}},\n{(unsigned char*)\"boxur\", {226, 148, 148, 0}},\n{(unsigned char*)\"boxv\", {226, 148, 130, 0}},\n{(unsigned char*)\"boxvH\", {226, 149, 170, 0}},\n{(unsigned char*)\"boxvL\", {226, 149, 161, 0}},\n{(unsigned char*)\"boxvR\", {226, 149, 158, 0}},\n{(unsigned char*)\"boxvh\", {226, 148, 188, 0}},\n{(unsigned char*)\"boxvl\", {226, 148, 164, 0}},\n{(unsigned char*)\"boxvr\", {226, 148, 156, 0}},\n{(unsigned char*)\"bprime\", {226, 128, 181, 0}},\n{(unsigned char*)\"breve\", {203, 152, 0}},\n{(unsigned char*)\"brvbar\", {194, 166, 0}},\n{(unsigned char*)\"bscr\", {240, 157, 146, 183, 0}},\n{(unsigned char*)\"bsemi\", {226, 129, 143, 0}},\n{(unsigned char*)\"bsim\", {226, 136, 189, 0}},\n{(unsigned char*)\"bsime\", {226, 139, 141, 0}},\n{(unsigned char*)\"bsol\", {92, 0}},\n{(unsigned char*)\"bsolb\", {226, 167, 133, 0}},\n{(unsigned char*)\"bsolhsub\", {226, 159, 136, 0}},\n{(unsigned char*)\"bull\", {226, 128, 162, 0}},\n{(unsigned char*)\"bullet\", {226, 128, 162, 0}},\n{(unsigned char*)\"bump\", {226, 137, 142, 0}},\n{(unsigned char*)\"bumpE\", {226, 170, 174, 0}},\n{(unsigned char*)\"bumpe\", {226, 137, 143, 0}},\n{(unsigned char*)\"bumpeq\", {226, 137, 143, 0}},\n{(unsigned char*)\"cacute\", {196, 135, 0}},\n{(unsigned char*)\"cap\", {226, 136, 169, 0}},\n{(unsigned char*)\"capand\", {226, 169, 132, 0}},\n{(unsigned char*)\"capbrcup\", {226, 169, 137, 0}},\n{(unsigned char*)\"capcap\", {226, 169, 139, 0}},\n{(unsigned char*)\"capcup\", {226, 169, 135, 0}},\n{(unsigned char*)\"capdot\", {226, 169, 128, 0}},\n{(unsigned char*)\"caps\", {226, 136, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"caret\", {226, 129, 129, 0}},\n{(unsigned char*)\"caron\", {203, 135, 0}},\n{(unsigned char*)\"ccaps\", {226, 169, 141, 0}},\n{(unsigned char*)\"ccaron\", {196, 141, 0}},\n{(unsigned char*)\"ccedil\", {195, 167, 0}},\n{(unsigned char*)\"ccirc\", {196, 137, 0}},\n{(unsigned char*)\"ccups\", {226, 169, 140, 0}},\n{(unsigned char*)\"ccupssm\", {226, 169, 144, 0}},\n{(unsigned char*)\"cdot\", {196, 139, 0}},\n{(unsigned char*)\"cedil\", {194, 184, 0}},\n{(unsigned char*)\"cemptyv\", {226, 166, 178, 0}},\n{(unsigned char*)\"cent\", {194, 162, 0}},\n{(unsigned char*)\"centerdot\", {194, 183, 0}},\n{(unsigned char*)\"cfr\", {240, 157, 148, 160, 0}},\n{(unsigned char*)\"chcy\", {209, 135, 0}},\n{(unsigned char*)\"check\", {226, 156, 147, 0}},\n{(unsigned char*)\"checkmark\", {226, 156, 147, 0}},\n{(unsigned char*)\"chi\", {207, 135, 0}},\n{(unsigned char*)\"cir\", {226, 151, 139, 0}},\n{(unsigned char*)\"cirE\", {226, 167, 131, 0}},\n{(unsigned char*)\"circ\", {203, 134, 0}},\n{(unsigned char*)\"circeq\", {226, 137, 151, 0}},\n{(unsigned char*)\"circlearrowleft\", {226, 134, 186, 0}},\n{(unsigned char*)\"circlearrowright\", {226, 134, 187, 0}},\n{(unsigned char*)\"circledR\", {194, 174, 0}},\n{(unsigned char*)\"circledS\", {226, 147, 136, 0}},\n{(unsigned char*)\"circledast\", {226, 138, 155, 0}},\n{(unsigned char*)\"circledcirc\", {226, 138, 154, 0}},\n{(unsigned char*)\"circleddash\", {226, 138, 157, 0}},\n{(unsigned char*)\"cire\", {226, 137, 151, 0}},\n{(unsigned char*)\"cirfnint\", {226, 168, 144, 0}},\n{(unsigned char*)\"cirmid\", {226, 171, 175, 0}},\n{(unsigned char*)\"cirscir\", {226, 167, 130, 0}},\n{(unsigned char*)\"clubs\", {226, 153, 163, 0}},\n{(unsigned char*)\"clubsuit\", {226, 153, 163, 0}},\n{(unsigned char*)\"colon\", {58, 0}},\n{(unsigned char*)\"colone\", {226, 137, 148, 0}},\n{(unsigned char*)\"coloneq\", {226, 137, 148, 0}},\n{(unsigned char*)\"comma\", {44, 0}},\n{(unsigned char*)\"commat\", {64, 0}},\n{(unsigned char*)\"comp\", {226, 136, 129, 0}},\n{(unsigned char*)\"compfn\", {226, 136, 152, 0}},\n{(unsigned char*)\"complement\", {226, 136, 129, 0}},\n{(unsigned char*)\"complexes\", {226, 132, 130, 0}},\n{(unsigned char*)\"cong\", {226, 137, 133, 0}},\n{(unsigned char*)\"congdot\", {226, 169, 173, 0}},\n{(unsigned char*)\"conint\", {226, 136, 174, 0}},\n{(unsigned char*)\"copf\", {240, 157, 149, 148, 0}},\n{(unsigned char*)\"coprod\", {226, 136, 144, 0}},\n{(unsigned char*)\"copy\", {194, 169, 0}},\n{(unsigned char*)\"copysr\", {226, 132, 151, 0}},\n{(unsigned char*)\"crarr\", {226, 134, 181, 0}},\n{(unsigned char*)\"cross\", {226, 156, 151, 0}},\n{(unsigned char*)\"cscr\", {240, 157, 146, 184, 0}},\n{(unsigned char*)\"csub\", {226, 171, 143, 0}},\n{(unsigned char*)\"csube\", {226, 171, 145, 0}},\n{(unsigned char*)\"csup\", {226, 171, 144, 0}},\n{(unsigned char*)\"csupe\", {226, 171, 146, 0}},\n{(unsigned char*)\"ctdot\", {226, 139, 175, 0}},\n{(unsigned char*)\"cudarrl\", {226, 164, 184, 0}},\n{(unsigned char*)\"cudarrr\", {226, 164, 181, 0}},\n{(unsigned char*)\"cuepr\", {226, 139, 158, 0}},\n{(unsigned char*)\"cuesc\", {226, 139, 159, 0}},\n{(unsigned char*)\"cularr\", {226, 134, 182, 0}},\n{(unsigned char*)\"cularrp\", {226, 164, 189, 0}},\n{(unsigned char*)\"cup\", {226, 136, 170, 0}},\n{(unsigned char*)\"cupbrcap\", {226, 169, 136, 0}},\n{(unsigned char*)\"cupcap\", {226, 169, 134, 0}},\n{(unsigned char*)\"cupcup\", {226, 169, 138, 0}},\n{(unsigned char*)\"cupdot\", {226, 138, 141, 0}},\n{(unsigned char*)\"cupor\", {226, 169, 133, 0}},\n{(unsigned char*)\"cups\", {226, 136, 170, 239, 184, 128, 0}},\n{(unsigned char*)\"curarr\", {226, 134, 183, 0}},\n{(unsigned char*)\"curarrm\", {226, 164, 188, 0}},\n{(unsigned char*)\"curlyeqprec\", {226, 139, 158, 0}},\n{(unsigned char*)\"curlyeqsucc\", {226, 139, 159, 0}},\n{(unsigned char*)\"curlyvee\", {226, 139, 142, 0}},\n{(unsigned char*)\"curlywedge\", {226, 139, 143, 0}},\n{(unsigned char*)\"curren\", {194, 164, 0}},\n{(unsigned char*)\"curvearrowleft\", {226, 134, 182, 0}},\n{(unsigned char*)\"curvearrowright\", {226, 134, 183, 0}},\n{(unsigned char*)\"cuvee\", {226, 139, 142, 0}},\n{(unsigned char*)\"cuwed\", {226, 139, 143, 0}},\n{(unsigned char*)\"cwconint\", {226, 136, 178, 0}},\n{(unsigned char*)\"cwint\", {226, 136, 177, 0}},\n{(unsigned char*)\"cylcty\", {226, 140, 173, 0}},\n{(unsigned char*)\"dArr\", {226, 135, 147, 0}},\n{(unsigned char*)\"dHar\", {226, 165, 165, 0}},\n{(unsigned char*)\"dagger\", {226, 128, 160, 0}},\n{(unsigned char*)\"daleth\", {226, 132, 184, 0}},\n{(unsigned char*)\"darr\", {226, 134, 147, 0}},\n{(unsigned char*)\"dash\", {226, 128, 144, 0}},\n{(unsigned char*)\"dashv\", {226, 138, 163, 0}},\n{(unsigned char*)\"dbkarow\", {226, 164, 143, 0}},\n{(unsigned char*)\"dblac\", {203, 157, 0}},\n{(unsigned char*)\"dcaron\", {196, 143, 0}},\n{(unsigned char*)\"dcy\", {208, 180, 0}},\n{(unsigned char*)\"dd\", {226, 133, 134, 0}},\n{(unsigned char*)\"ddagger\", {226, 128, 161, 0}},\n{(unsigned char*)\"ddarr\", {226, 135, 138, 0}},\n{(unsigned char*)\"ddotseq\", {226, 169, 183, 0}},\n{(unsigned char*)\"deg\", {194, 176, 0}},\n{(unsigned char*)\"delta\", {206, 180, 0}},\n{(unsigned char*)\"demptyv\", {226, 166, 177, 0}},\n{(unsigned char*)\"dfisht\", {226, 165, 191, 0}},\n{(unsigned char*)\"dfr\", {240, 157, 148, 161, 0}},\n{(unsigned char*)\"dharl\", {226, 135, 131, 0}},\n{(unsigned char*)\"dharr\", {226, 135, 130, 0}},\n{(unsigned char*)\"diam\", {226, 139, 132, 0}},\n{(unsigned char*)\"diamond\", {226, 139, 132, 0}},\n{(unsigned char*)\"diamondsuit\", {226, 153, 166, 0}},\n{(unsigned char*)\"diams\", {226, 153, 166, 0}},\n{(unsigned char*)\"die\", {194, 168, 0}},\n{(unsigned char*)\"digamma\", {207, 157, 0}},\n{(unsigned char*)\"disin\", {226, 139, 178, 0}},\n{(unsigned char*)\"div\", {195, 183, 0}},\n{(unsigned char*)\"divide\", {195, 183, 0}},\n{(unsigned char*)\"divideontimes\", {226, 139, 135, 0}},\n{(unsigned char*)\"divonx\", {226, 139, 135, 0}},\n{(unsigned char*)\"djcy\", {209, 146, 0}},\n{(unsigned char*)\"dlcorn\", {226, 140, 158, 0}},\n{(unsigned char*)\"dlcrop\", {226, 140, 141, 0}},\n{(unsigned char*)\"dollar\", {36, 0}},\n{(unsigned char*)\"dopf\", {240, 157, 149, 149, 0}},\n{(unsigned char*)\"dot\", {203, 153, 0}},\n{(unsigned char*)\"doteq\", {226, 137, 144, 0}},\n{(unsigned char*)\"doteqdot\", {226, 137, 145, 0}},\n{(unsigned char*)\"dotminus\", {226, 136, 184, 0}},\n{(unsigned char*)\"dotplus\", {226, 136, 148, 0}},\n{(unsigned char*)\"dotsquare\", {226, 138, 161, 0}},\n{(unsigned char*)\"doublebarwedge\", {226, 140, 134, 0}},\n{(unsigned char*)\"downarrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"downdownarrows\", {226, 135, 138, 0}},\n{(unsigned char*)\"downharpoonleft\", {226, 135, 131, 0}},\n{(unsigned char*)\"downharpoonright\", {226, 135, 130, 0}},\n{(unsigned char*)\"drbkarow\", {226, 164, 144, 0}},\n{(unsigned char*)\"drcorn\", {226, 140, 159, 0}},\n{(unsigned char*)\"drcrop\", {226, 140, 140, 0}},\n{(unsigned char*)\"dscr\", {240, 157, 146, 185, 0}},\n{(unsigned char*)\"dscy\", {209, 149, 0}},\n{(unsigned char*)\"dsol\", {226, 167, 182, 0}},\n{(unsigned char*)\"dstrok\", {196, 145, 0}},\n{(unsigned char*)\"dtdot\", {226, 139, 177, 0}},\n{(unsigned char*)\"dtri\", {226, 150, 191, 0}},\n{(unsigned char*)\"dtrif\", {226, 150, 190, 0}},\n{(unsigned char*)\"duarr\", {226, 135, 181, 0}},\n{(unsigned char*)\"duhar\", {226, 165, 175, 0}},\n{(unsigned char*)\"dwangle\", {226, 166, 166, 0}},\n{(unsigned char*)\"dzcy\", {209, 159, 0}},\n{(unsigned char*)\"dzigrarr\", {226, 159, 191, 0}},\n{(unsigned char*)\"eDDot\", {226, 169, 183, 0}},\n{(unsigned char*)\"eDot\", {226, 137, 145, 0}},\n{(unsigned char*)\"eacute\", {195, 169, 0}},\n{(unsigned char*)\"easter\", {226, 169, 174, 0}},\n{(unsigned char*)\"ecaron\", {196, 155, 0}},\n{(unsigned char*)\"ecir\", {226, 137, 150, 0}},\n{(unsigned char*)\"ecirc\", {195, 170, 0}},\n{(unsigned char*)\"ecolon\", {226, 137, 149, 0}},\n{(unsigned char*)\"ecy\", {209, 141, 0}},\n{(unsigned char*)\"edot\", {196, 151, 0}},\n{(unsigned char*)\"ee\", {226, 133, 135, 0}},\n{(unsigned char*)\"efDot\", {226, 137, 146, 0}},\n{(unsigned char*)\"efr\", {240, 157, 148, 162, 0}},\n{(unsigned char*)\"eg\", {226, 170, 154, 0}},\n{(unsigned char*)\"egrave\", {195, 168, 0}},\n{(unsigned char*)\"egs\", {226, 170, 150, 0}},\n{(unsigned char*)\"egsdot\", {226, 170, 152, 0}},\n{(unsigned char*)\"el\", {226, 170, 153, 0}},\n{(unsigned char*)\"elinters\", {226, 143, 167, 0}},\n{(unsigned char*)\"ell\", {226, 132, 147, 0}},\n{(unsigned char*)\"els\", {226, 170, 149, 0}},\n{(unsigned char*)\"elsdot\", {226, 170, 151, 0}},\n{(unsigned char*)\"emacr\", {196, 147, 0}},\n{(unsigned char*)\"empty\", {226, 136, 133, 0}},\n{(unsigned char*)\"emptyset\", {226, 136, 133, 0}},\n{(unsigned char*)\"emptyv\", {226, 136, 133, 0}},\n{(unsigned char*)\"emsp\", {226, 128, 131, 0}},\n{(unsigned char*)\"emsp13\", {226, 128, 132, 0}},\n{(unsigned char*)\"emsp14\", {226, 128, 133, 0}},\n{(unsigned char*)\"eng\", {197, 139, 0}},\n{(unsigned char*)\"ensp\", {226, 128, 130, 0}},\n{(unsigned char*)\"eogon\", {196, 153, 0}},\n{(unsigned char*)\"eopf\", {240, 157, 149, 150, 0}},\n{(unsigned char*)\"epar\", {226, 139, 149, 0}},\n{(unsigned char*)\"eparsl\", {226, 167, 163, 0}},\n{(unsigned char*)\"eplus\", {226, 169, 177, 0}},\n{(unsigned char*)\"epsi\", {206, 181, 0}},\n{(unsigned char*)\"epsilon\", {206, 181, 0}},\n{(unsigned char*)\"epsiv\", {207, 181, 0}},\n{(unsigned char*)\"eqcirc\", {226, 137, 150, 0}},\n{(unsigned char*)\"eqcolon\", {226, 137, 149, 0}},\n{(unsigned char*)\"eqsim\", {226, 137, 130, 0}},\n{(unsigned char*)\"eqslantgtr\", {226, 170, 150, 0}},\n{(unsigned char*)\"eqslantless\", {226, 170, 149, 0}},\n{(unsigned char*)\"equals\", {61, 0}},\n{(unsigned char*)\"equest\", {226, 137, 159, 0}},\n{(unsigned char*)\"equiv\", {226, 137, 161, 0}},\n{(unsigned char*)\"equivDD\", {226, 169, 184, 0}},\n{(unsigned char*)\"eqvparsl\", {226, 167, 165, 0}},\n{(unsigned char*)\"erDot\", {226, 137, 147, 0}},\n{(unsigned char*)\"erarr\", {226, 165, 177, 0}},\n{(unsigned char*)\"escr\", {226, 132, 175, 0}},\n{(unsigned char*)\"esdot\", {226, 137, 144, 0}},\n{(unsigned char*)\"esim\", {226, 137, 130, 0}},\n{(unsigned char*)\"eta\", {206, 183, 0}},\n{(unsigned char*)\"eth\", {195, 176, 0}},\n{(unsigned char*)\"euml\", {195, 171, 0}},\n{(unsigned char*)\"euro\", {226, 130, 172, 0}},\n{(unsigned char*)\"excl\", {33, 0}},\n{(unsigned char*)\"exist\", {226, 136, 131, 0}},\n{(unsigned char*)\"expectation\", {226, 132, 176, 0}},\n{(unsigned char*)\"exponentiale\", {226, 133, 135, 0}},\n{(unsigned char*)\"fallingdotseq\", {226, 137, 146, 0}},\n{(unsigned char*)\"fcy\", {209, 132, 0}},\n{(unsigned char*)\"female\", {226, 153, 128, 0}},\n{(unsigned char*)\"ffilig\", {239, 172, 131, 0}},\n{(unsigned char*)\"fflig\", {239, 172, 128, 0}},\n{(unsigned char*)\"ffllig\", {239, 172, 132, 0}},\n{(unsigned char*)\"ffr\", {240, 157, 148, 163, 0}},\n{(unsigned char*)\"filig\", {239, 172, 129, 0}},\n{(unsigned char*)\"fjlig\", {102, 106, 0}},\n{(unsigned char*)\"flat\", {226, 153, 173, 0}},\n{(unsigned char*)\"fllig\", {239, 172, 130, 0}},\n{(unsigned char*)\"fltns\", {226, 150, 177, 0}},\n{(unsigned char*)\"fnof\", {198, 146, 0}},\n{(unsigned char*)\"fopf\", {240, 157, 149, 151, 0}},\n{(unsigned char*)\"forall\", {226, 136, 128, 0}},\n{(unsigned char*)\"fork\", {226, 139, 148, 0}},\n{(unsigned char*)\"forkv\", {226, 171, 153, 0}},\n{(unsigned char*)\"fpartint\", {226, 168, 141, 0}},\n{(unsigned char*)\"frac12\", {194, 189, 0}},\n{(unsigned char*)\"frac13\", {226, 133, 147, 0}},\n{(unsigned char*)\"frac14\", {194, 188, 0}},\n{(unsigned char*)\"frac15\", {226, 133, 149, 0}},\n{(unsigned char*)\"frac16\", {226, 133, 153, 0}},\n{(unsigned char*)\"frac18\", {226, 133, 155, 0}},\n{(unsigned char*)\"frac23\", {226, 133, 148, 0}},\n{(unsigned char*)\"frac25\", {226, 133, 150, 0}},\n{(unsigned char*)\"frac34\", {194, 190, 0}},\n{(unsigned char*)\"frac35\", {226, 133, 151, 0}},\n{(unsigned char*)\"frac38\", {226, 133, 156, 0}},\n{(unsigned char*)\"frac45\", {226, 133, 152, 0}},\n{(unsigned char*)\"frac56\", {226, 133, 154, 0}},\n{(unsigned char*)\"frac58\", {226, 133, 157, 0}},\n{(unsigned char*)\"frac78\", {226, 133, 158, 0}},\n{(unsigned char*)\"frasl\", {226, 129, 132, 0}},\n{(unsigned char*)\"frown\", {226, 140, 162, 0}},\n{(unsigned char*)\"fscr\", {240, 157, 146, 187, 0}},\n{(unsigned char*)\"gE\", {226, 137, 167, 0}},\n{(unsigned char*)\"gEl\", {226, 170, 140, 0}},\n{(unsigned char*)\"gacute\", {199, 181, 0}},\n{(unsigned char*)\"gamma\", {206, 179, 0}},\n{(unsigned char*)\"gammad\", {207, 157, 0}},\n{(unsigned char*)\"gap\", {226, 170, 134, 0}},\n{(unsigned char*)\"gbreve\", {196, 159, 0}},\n{(unsigned char*)\"gcirc\", {196, 157, 0}},\n{(unsigned char*)\"gcy\", {208, 179, 0}},\n{(unsigned char*)\"gdot\", {196, 161, 0}},\n{(unsigned char*)\"ge\", {226, 137, 165, 0}},\n{(unsigned char*)\"gel\", {226, 139, 155, 0}},\n{(unsigned char*)\"geq\", {226, 137, 165, 0}},\n{(unsigned char*)\"geqq\", {226, 137, 167, 0}},\n{(unsigned char*)\"geqslant\", {226, 169, 190, 0}},\n{(unsigned char*)\"ges\", {226, 169, 190, 0}},\n{(unsigned char*)\"gescc\", {226, 170, 169, 0}},\n{(unsigned char*)\"gesdot\", {226, 170, 128, 0}},\n{(unsigned char*)\"gesdoto\", {226, 170, 130, 0}},\n{(unsigned char*)\"gesdotol\", {226, 170, 132, 0}},\n{(unsigned char*)\"gesl\", {226, 139, 155, 239, 184, 128, 0}},\n{(unsigned char*)\"gesles\", {226, 170, 148, 0}},\n{(unsigned char*)\"gfr\", {240, 157, 148, 164, 0}},\n{(unsigned char*)\"gg\", {226, 137, 171, 0}},\n{(unsigned char*)\"ggg\", {226, 139, 153, 0}},\n{(unsigned char*)\"gimel\", {226, 132, 183, 0}},\n{(unsigned char*)\"gjcy\", {209, 147, 0}},\n{(unsigned char*)\"gl\", {226, 137, 183, 0}},\n{(unsigned char*)\"glE\", {226, 170, 146, 0}},\n{(unsigned char*)\"gla\", {226, 170, 165, 0}},\n{(unsigned char*)\"glj\", {226, 170, 164, 0}},\n{(unsigned char*)\"gnE\", {226, 137, 169, 0}},\n{(unsigned char*)\"gnap\", {226, 170, 138, 0}},\n{(unsigned char*)\"gnapprox\", {226, 170, 138, 0}},\n{(unsigned char*)\"gne\", {226, 170, 136, 0}},\n{(unsigned char*)\"gneq\", {226, 170, 136, 0}},\n{(unsigned char*)\"gneqq\", {226, 137, 169, 0}},\n{(unsigned char*)\"gnsim\", {226, 139, 167, 0}},\n{(unsigned char*)\"gopf\", {240, 157, 149, 152, 0}},\n{(unsigned char*)\"grave\", {96, 0}},\n{(unsigned char*)\"gscr\", {226, 132, 138, 0}},\n{(unsigned char*)\"gsim\", {226, 137, 179, 0}},\n{(unsigned char*)\"gsime\", {226, 170, 142, 0}},\n{(unsigned char*)\"gsiml\", {226, 170, 144, 0}},\n{(unsigned char*)\"gt\", {62, 0}},\n{(unsigned char*)\"gtcc\", {226, 170, 167, 0}},\n{(unsigned char*)\"gtcir\", {226, 169, 186, 0}},\n{(unsigned char*)\"gtdot\", {226, 139, 151, 0}},\n{(unsigned char*)\"gtlPar\", {226, 166, 149, 0}},\n{(unsigned char*)\"gtquest\", {226, 169, 188, 0}},\n{(unsigned char*)\"gtrapprox\", {226, 170, 134, 0}},\n{(unsigned char*)\"gtrarr\", {226, 165, 184, 0}},\n{(unsigned char*)\"gtrdot\", {226, 139, 151, 0}},\n{(unsigned char*)\"gtreqless\", {226, 139, 155, 0}},\n{(unsigned char*)\"gtreqqless\", {226, 170, 140, 0}},\n{(unsigned char*)\"gtrless\", {226, 137, 183, 0}},\n{(unsigned char*)\"gtrsim\", {226, 137, 179, 0}},\n{(unsigned char*)\"gvertneqq\", {226, 137, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"gvnE\", {226, 137, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"hArr\", {226, 135, 148, 0}},\n{(unsigned char*)\"hairsp\", {226, 128, 138, 0}},\n{(unsigned char*)\"half\", {194, 189, 0}},\n{(unsigned char*)\"hamilt\", {226, 132, 139, 0}},\n{(unsigned char*)\"hardcy\", {209, 138, 0}},\n{(unsigned char*)\"harr\", {226, 134, 148, 0}},\n{(unsigned char*)\"harrcir\", {226, 165, 136, 0}},\n{(unsigned char*)\"harrw\", {226, 134, 173, 0}},\n{(unsigned char*)\"hbar\", {226, 132, 143, 0}},\n{(unsigned char*)\"hcirc\", {196, 165, 0}},\n{(unsigned char*)\"hearts\", {226, 153, 165, 0}},\n{(unsigned char*)\"heartsuit\", {226, 153, 165, 0}},\n{(unsigned char*)\"hellip\", {226, 128, 166, 0}},\n{(unsigned char*)\"hercon\", {226, 138, 185, 0}},\n{(unsigned char*)\"hfr\", {240, 157, 148, 165, 0}},\n{(unsigned char*)\"hksearow\", {226, 164, 165, 0}},\n{(unsigned char*)\"hkswarow\", {226, 164, 166, 0}},\n{(unsigned char*)\"hoarr\", {226, 135, 191, 0}},\n{(unsigned char*)\"homtht\", {226, 136, 187, 0}},\n{(unsigned char*)\"hookleftarrow\", {226, 134, 169, 0}},\n{(unsigned char*)\"hookrightarrow\", {226, 134, 170, 0}},\n{(unsigned char*)\"hopf\", {240, 157, 149, 153, 0}},\n{(unsigned char*)\"horbar\", {226, 128, 149, 0}},\n{(unsigned char*)\"hscr\", {240, 157, 146, 189, 0}},\n{(unsigned char*)\"hslash\", {226, 132, 143, 0}},\n{(unsigned char*)\"hstrok\", {196, 167, 0}},\n{(unsigned char*)\"hybull\", {226, 129, 131, 0}},\n{(unsigned char*)\"hyphen\", {226, 128, 144, 0}},\n{(unsigned char*)\"iacute\", {195, 173, 0}},\n{(unsigned char*)\"ic\", {226, 129, 163, 0}},\n{(unsigned char*)\"icirc\", {195, 174, 0}},\n{(unsigned char*)\"icy\", {208, 184, 0}},\n{(unsigned char*)\"iecy\", {208, 181, 0}},\n{(unsigned char*)\"iexcl\", {194, 161, 0}},\n{(unsigned char*)\"iff\", {226, 135, 148, 0}},\n{(unsigned char*)\"ifr\", {240, 157, 148, 166, 0}},\n{(unsigned char*)\"igrave\", {195, 172, 0}},\n{(unsigned char*)\"ii\", {226, 133, 136, 0}},\n{(unsigned char*)\"iiiint\", {226, 168, 140, 0}},\n{(unsigned char*)\"iiint\", {226, 136, 173, 0}},\n{(unsigned char*)\"iinfin\", {226, 167, 156, 0}},\n{(unsigned char*)\"iiota\", {226, 132, 169, 0}},\n{(unsigned char*)\"ijlig\", {196, 179, 0}},\n{(unsigned char*)\"imacr\", {196, 171, 0}},\n{(unsigned char*)\"image\", {226, 132, 145, 0}},\n{(unsigned char*)\"imagline\", {226, 132, 144, 0}},\n{(unsigned char*)\"imagpart\", {226, 132, 145, 0}},\n{(unsigned char*)\"imath\", {196, 177, 0}},\n{(unsigned char*)\"imof\", {226, 138, 183, 0}},\n{(unsigned char*)\"imped\", {198, 181, 0}},\n{(unsigned char*)\"in\", {226, 136, 136, 0}},\n{(unsigned char*)\"incare\", {226, 132, 133, 0}},\n{(unsigned char*)\"infin\", {226, 136, 158, 0}},\n{(unsigned char*)\"infintie\", {226, 167, 157, 0}},\n{(unsigned char*)\"inodot\", {196, 177, 0}},\n{(unsigned char*)\"int\", {226, 136, 171, 0}},\n{(unsigned char*)\"intcal\", {226, 138, 186, 0}},\n{(unsigned char*)\"integers\", {226, 132, 164, 0}},\n{(unsigned char*)\"intercal\", {226, 138, 186, 0}},\n{(unsigned char*)\"intlarhk\", {226, 168, 151, 0}},\n{(unsigned char*)\"intprod\", {226, 168, 188, 0}},\n{(unsigned char*)\"iocy\", {209, 145, 0}},\n{(unsigned char*)\"iogon\", {196, 175, 0}},\n{(unsigned char*)\"iopf\", {240, 157, 149, 154, 0}},\n{(unsigned char*)\"iota\", {206, 185, 0}},\n{(unsigned char*)\"iprod\", {226, 168, 188, 0}},\n{(unsigned char*)\"iquest\", {194, 191, 0}},\n{(unsigned char*)\"iscr\", {240, 157, 146, 190, 0}},\n{(unsigned char*)\"isin\", {226, 136, 136, 0}},\n{(unsigned char*)\"isinE\", {226, 139, 185, 0}},\n{(unsigned char*)\"isindot\", {226, 139, 181, 0}},\n{(unsigned char*)\"isins\", {226, 139, 180, 0}},\n{(unsigned char*)\"isinsv\", {226, 139, 179, 0}},\n{(unsigned char*)\"isinv\", {226, 136, 136, 0}},\n{(unsigned char*)\"it\", {226, 129, 162, 0}},\n{(unsigned char*)\"itilde\", {196, 169, 0}},\n{(unsigned char*)\"iukcy\", {209, 150, 0}},\n{(unsigned char*)\"iuml\", {195, 175, 0}},\n{(unsigned char*)\"jcirc\", {196, 181, 0}},\n{(unsigned char*)\"jcy\", {208, 185, 0}},\n{(unsigned char*)\"jfr\", {240, 157, 148, 167, 0}},\n{(unsigned char*)\"jmath\", {200, 183, 0}},\n{(unsigned char*)\"jopf\", {240, 157, 149, 155, 0}},\n{(unsigned char*)\"jscr\", {240, 157, 146, 191, 0}},\n{(unsigned char*)\"jsercy\", {209, 152, 0}},\n{(unsigned char*)\"jukcy\", {209, 148, 0}},\n{(unsigned char*)\"kappa\", {206, 186, 0}},\n{(unsigned char*)\"kappav\", {207, 176, 0}},\n{(unsigned char*)\"kcedil\", {196, 183, 0}},\n{(unsigned char*)\"kcy\", {208, 186, 0}},\n{(unsigned char*)\"kfr\", {240, 157, 148, 168, 0}},\n{(unsigned char*)\"kgreen\", {196, 184, 0}},\n{(unsigned char*)\"khcy\", {209, 133, 0}},\n{(unsigned char*)\"kjcy\", {209, 156, 0}},\n{(unsigned char*)\"kopf\", {240, 157, 149, 156, 0}},\n{(unsigned char*)\"kscr\", {240, 157, 147, 128, 0}},\n{(unsigned char*)\"lAarr\", {226, 135, 154, 0}},\n{(unsigned char*)\"lArr\", {226, 135, 144, 0}},\n{(unsigned char*)\"lAtail\", {226, 164, 155, 0}},\n{(unsigned char*)\"lBarr\", {226, 164, 142, 0}},\n{(unsigned char*)\"lE\", {226, 137, 166, 0}},\n{(unsigned char*)\"lEg\", {226, 170, 139, 0}},\n{(unsigned char*)\"lHar\", {226, 165, 162, 0}},\n{(unsigned char*)\"lacute\", {196, 186, 0}},\n{(unsigned char*)\"laemptyv\", {226, 166, 180, 0}},\n{(unsigned char*)\"lagran\", {226, 132, 146, 0}},\n{(unsigned char*)\"lambda\", {206, 187, 0}},\n{(unsigned char*)\"lang\", {226, 159, 168, 0}},\n{(unsigned char*)\"langd\", {226, 166, 145, 0}},\n{(unsigned char*)\"langle\", {226, 159, 168, 0}},\n{(unsigned char*)\"lap\", {226, 170, 133, 0}},\n{(unsigned char*)\"laquo\", {194, 171, 0}},\n{(unsigned char*)\"larr\", {226, 134, 144, 0}},\n{(unsigned char*)\"larrb\", {226, 135, 164, 0}},\n{(unsigned char*)\"larrbfs\", {226, 164, 159, 0}},\n{(unsigned char*)\"larrfs\", {226, 164, 157, 0}},\n{(unsigned char*)\"larrhk\", {226, 134, 169, 0}},\n{(unsigned char*)\"larrlp\", {226, 134, 171, 0}},\n{(unsigned char*)\"larrpl\", {226, 164, 185, 0}},\n{(unsigned char*)\"larrsim\", {226, 165, 179, 0}},\n{(unsigned char*)\"larrtl\", {226, 134, 162, 0}},\n{(unsigned char*)\"lat\", {226, 170, 171, 0}},\n{(unsigned char*)\"latail\", {226, 164, 153, 0}},\n{(unsigned char*)\"late\", {226, 170, 173, 0}},\n{(unsigned char*)\"lates\", {226, 170, 173, 239, 184, 128, 0}},\n{(unsigned char*)\"lbarr\", {226, 164, 140, 0}},\n{(unsigned char*)\"lbbrk\", {226, 157, 178, 0}},\n{(unsigned char*)\"lbrace\", {123, 0}},\n{(unsigned char*)\"lbrack\", {91, 0}},\n{(unsigned char*)\"lbrke\", {226, 166, 139, 0}},\n{(unsigned char*)\"lbrksld\", {226, 166, 143, 0}},\n{(unsigned char*)\"lbrkslu\", {226, 166, 141, 0}},\n{(unsigned char*)\"lcaron\", {196, 190, 0}},\n{(unsigned char*)\"lcedil\", {196, 188, 0}},\n{(unsigned char*)\"lceil\", {226, 140, 136, 0}},\n{(unsigned char*)\"lcub\", {123, 0}},\n{(unsigned char*)\"lcy\", {208, 187, 0}},\n{(unsigned char*)\"ldca\", {226, 164, 182, 0}},\n{(unsigned char*)\"ldquo\", {226, 128, 156, 0}},\n{(unsigned char*)\"ldquor\", {226, 128, 158, 0}},\n{(unsigned char*)\"ldrdhar\", {226, 165, 167, 0}},\n{(unsigned char*)\"ldrushar\", {226, 165, 139, 0}},\n{(unsigned char*)\"ldsh\", {226, 134, 178, 0}},\n{(unsigned char*)\"le\", {226, 137, 164, 0}},\n{(unsigned char*)\"leftarrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"leftarrowtail\", {226, 134, 162, 0}},\n{(unsigned char*)\"leftharpoondown\", {226, 134, 189, 0}},\n{(unsigned char*)\"leftharpoonup\", {226, 134, 188, 0}},\n{(unsigned char*)\"leftleftarrows\", {226, 135, 135, 0}},\n{(unsigned char*)\"leftrightarrow\", {226, 134, 148, 0}},\n{(unsigned char*)\"leftrightarrows\", {226, 135, 134, 0}},\n{(unsigned char*)\"leftrightharpoons\", {226, 135, 139, 0}},\n{(unsigned char*)\"leftrightsquigarrow\", {226, 134, 173, 0}},\n{(unsigned char*)\"leftthreetimes\", {226, 139, 139, 0}},\n{(unsigned char*)\"leg\", {226, 139, 154, 0}},\n{(unsigned char*)\"leq\", {226, 137, 164, 0}},\n{(unsigned char*)\"leqq\", {226, 137, 166, 0}},\n{(unsigned char*)\"leqslant\", {226, 169, 189, 0}},\n{(unsigned char*)\"les\", {226, 169, 189, 0}},\n{(unsigned char*)\"lescc\", {226, 170, 168, 0}},\n{(unsigned char*)\"lesdot\", {226, 169, 191, 0}},\n{(unsigned char*)\"lesdoto\", {226, 170, 129, 0}},\n{(unsigned char*)\"lesdotor\", {226, 170, 131, 0}},\n{(unsigned char*)\"lesg\", {226, 139, 154, 239, 184, 128, 0}},\n{(unsigned char*)\"lesges\", {226, 170, 147, 0}},\n{(unsigned char*)\"lessapprox\", {226, 170, 133, 0}},\n{(unsigned char*)\"lessdot\", {226, 139, 150, 0}},\n{(unsigned char*)\"lesseqgtr\", {226, 139, 154, 0}},\n{(unsigned char*)\"lesseqqgtr\", {226, 170, 139, 0}},\n{(unsigned char*)\"lessgtr\", {226, 137, 182, 0}},\n{(unsigned char*)\"lesssim\", {226, 137, 178, 0}},\n{(unsigned char*)\"lfisht\", {226, 165, 188, 0}},\n{(unsigned char*)\"lfloor\", {226, 140, 138, 0}},\n{(unsigned char*)\"lfr\", {240, 157, 148, 169, 0}},\n{(unsigned char*)\"lg\", {226, 137, 182, 0}},\n{(unsigned char*)\"lgE\", {226, 170, 145, 0}},\n{(unsigned char*)\"lhard\", {226, 134, 189, 0}},\n{(unsigned char*)\"lharu\", {226, 134, 188, 0}},\n{(unsigned char*)\"lharul\", {226, 165, 170, 0}},\n{(unsigned char*)\"lhblk\", {226, 150, 132, 0}},\n{(unsigned char*)\"ljcy\", {209, 153, 0}},\n{(unsigned char*)\"ll\", {226, 137, 170, 0}},\n{(unsigned char*)\"llarr\", {226, 135, 135, 0}},\n{(unsigned char*)\"llcorner\", {226, 140, 158, 0}},\n{(unsigned char*)\"llhard\", {226, 165, 171, 0}},\n{(unsigned char*)\"lltri\", {226, 151, 186, 0}},\n{(unsigned char*)\"lmidot\", {197, 128, 0}},\n{(unsigned char*)\"lmoust\", {226, 142, 176, 0}},\n{(unsigned char*)\"lmoustache\", {226, 142, 176, 0}},\n{(unsigned char*)\"lnE\", {226, 137, 168, 0}},\n{(unsigned char*)\"lnap\", {226, 170, 137, 0}},\n{(unsigned char*)\"lnapprox\", {226, 170, 137, 0}},\n{(unsigned char*)\"lne\", {226, 170, 135, 0}},\n{(unsigned char*)\"lneq\", {226, 170, 135, 0}},\n{(unsigned char*)\"lneqq\", {226, 137, 168, 0}},\n{(unsigned char*)\"lnsim\", {226, 139, 166, 0}},\n{(unsigned char*)\"loang\", {226, 159, 172, 0}},\n{(unsigned char*)\"loarr\", {226, 135, 189, 0}},\n{(unsigned char*)\"lobrk\", {226, 159, 166, 0}},\n{(unsigned char*)\"longleftarrow\", {226, 159, 181, 0}},\n{(unsigned char*)\"longleftrightarrow\", {226, 159, 183, 0}},\n{(unsigned char*)\"longmapsto\", {226, 159, 188, 0}},\n{(unsigned char*)\"longrightarrow\", {226, 159, 182, 0}},\n{(unsigned char*)\"looparrowleft\", {226, 134, 171, 0}},\n{(unsigned char*)\"looparrowright\", {226, 134, 172, 0}},\n{(unsigned char*)\"lopar\", {226, 166, 133, 0}},\n{(unsigned char*)\"lopf\", {240, 157, 149, 157, 0}},\n{(unsigned char*)\"loplus\", {226, 168, 173, 0}},\n{(unsigned char*)\"lotimes\", {226, 168, 180, 0}},\n{(unsigned char*)\"lowast\", {226, 136, 151, 0}},\n{(unsigned char*)\"lowbar\", {95, 0}},\n{(unsigned char*)\"loz\", {226, 151, 138, 0}},\n{(unsigned char*)\"lozenge\", {226, 151, 138, 0}},\n{(unsigned char*)\"lozf\", {226, 167, 171, 0}},\n{(unsigned char*)\"lpar\", {40, 0}},\n{(unsigned char*)\"lparlt\", {226, 166, 147, 0}},\n{(unsigned char*)\"lrarr\", {226, 135, 134, 0}},\n{(unsigned char*)\"lrcorner\", {226, 140, 159, 0}},\n{(unsigned char*)\"lrhar\", {226, 135, 139, 0}},\n{(unsigned char*)\"lrhard\", {226, 165, 173, 0}},\n{(unsigned char*)\"lrm\", {226, 128, 142, 0}},\n{(unsigned char*)\"lrtri\", {226, 138, 191, 0}},\n{(unsigned char*)\"lsaquo\", {226, 128, 185, 0}},\n{(unsigned char*)\"lscr\", {240, 157, 147, 129, 0}},\n{(unsigned char*)\"lsh\", {226, 134, 176, 0}},\n{(unsigned char*)\"lsim\", {226, 137, 178, 0}},\n{(unsigned char*)\"lsime\", {226, 170, 141, 0}},\n{(unsigned char*)\"lsimg\", {226, 170, 143, 0}},\n{(unsigned char*)\"lsqb\", {91, 0}},\n{(unsigned char*)\"lsquo\", {226, 128, 152, 0}},\n{(unsigned char*)\"lsquor\", {226, 128, 154, 0}},\n{(unsigned char*)\"lstrok\", {197, 130, 0}},\n{(unsigned char*)\"lt\", {60, 0}},\n{(unsigned char*)\"ltcc\", {226, 170, 166, 0}},\n{(unsigned char*)\"ltcir\", {226, 169, 185, 0}},\n{(unsigned char*)\"ltdot\", {226, 139, 150, 0}},\n{(unsigned char*)\"lthree\", {226, 139, 139, 0}},\n{(unsigned char*)\"ltimes\", {226, 139, 137, 0}},\n{(unsigned char*)\"ltlarr\", {226, 165, 182, 0}},\n{(unsigned char*)\"ltquest\", {226, 169, 187, 0}},\n{(unsigned char*)\"ltrPar\", {226, 166, 150, 0}},\n{(unsigned char*)\"ltri\", {226, 151, 131, 0}},\n{(unsigned char*)\"ltrie\", {226, 138, 180, 0}},\n{(unsigned char*)\"ltrif\", {226, 151, 130, 0}},\n{(unsigned char*)\"lurdshar\", {226, 165, 138, 0}},\n{(unsigned char*)\"luruhar\", {226, 165, 166, 0}},\n{(unsigned char*)\"lvertneqq\", {226, 137, 168, 239, 184, 128, 0}},\n{(unsigned char*)\"lvnE\", {226, 137, 168, 239, 184, 128, 0}},\n{(unsigned char*)\"mDDot\", {226, 136, 186, 0}},\n{(unsigned char*)\"macr\", {194, 175, 0}},\n{(unsigned char*)\"male\", {226, 153, 130, 0}},\n{(unsigned char*)\"malt\", {226, 156, 160, 0}},\n{(unsigned char*)\"maltese\", {226, 156, 160, 0}},\n{(unsigned char*)\"map\", {226, 134, 166, 0}},\n{(unsigned char*)\"mapsto\", {226, 134, 166, 0}},\n{(unsigned char*)\"mapstodown\", {226, 134, 167, 0}},\n{(unsigned char*)\"mapstoleft\", {226, 134, 164, 0}},\n{(unsigned char*)\"mapstoup\", {226, 134, 165, 0}},\n{(unsigned char*)\"marker\", {226, 150, 174, 0}},\n{(unsigned char*)\"mcomma\", {226, 168, 169, 0}},\n{(unsigned char*)\"mcy\", {208, 188, 0}},\n{(unsigned char*)\"mdash\", {226, 128, 148, 0}},\n{(unsigned char*)\"measuredangle\", {226, 136, 161, 0}},\n{(unsigned char*)\"mfr\", {240, 157, 148, 170, 0}},\n{(unsigned char*)\"mho\", {226, 132, 167, 0}},\n{(unsigned char*)\"micro\", {194, 181, 0}},\n{(unsigned char*)\"mid\", {226, 136, 163, 0}},\n{(unsigned char*)\"midast\", {42, 0}},\n{(unsigned char*)\"midcir\", {226, 171, 176, 0}},\n{(unsigned char*)\"middot\", {194, 183, 0}},\n{(unsigned char*)\"minus\", {226, 136, 146, 0}},\n{(unsigned char*)\"minusb\", {226, 138, 159, 0}},\n{(unsigned char*)\"minusd\", {226, 136, 184, 0}},\n{(unsigned char*)\"minusdu\", {226, 168, 170, 0}},\n{(unsigned char*)\"mlcp\", {226, 171, 155, 0}},\n{(unsigned char*)\"mldr\", {226, 128, 166, 0}},\n{(unsigned char*)\"mnplus\", {226, 136, 147, 0}},\n{(unsigned char*)\"models\", {226, 138, 167, 0}},\n{(unsigned char*)\"mopf\", {240, 157, 149, 158, 0}},\n{(unsigned char*)\"mp\", {226, 136, 147, 0}},\n{(unsigned char*)\"mscr\", {240, 157, 147, 130, 0}},\n{(unsigned char*)\"mstpos\", {226, 136, 190, 0}},\n{(unsigned char*)\"mu\", {206, 188, 0}},\n{(unsigned char*)\"multimap\", {226, 138, 184, 0}},\n{(unsigned char*)\"mumap\", {226, 138, 184, 0}},\n{(unsigned char*)\"nGg\", {226, 139, 153, 204, 184, 0}},\n{(unsigned char*)\"nGt\", {226, 137, 171, 226, 131, 146, 0}},\n{(unsigned char*)\"nGtv\", {226, 137, 171, 204, 184, 0}},\n{(unsigned char*)\"nLeftarrow\", {226, 135, 141, 0}},\n{(unsigned char*)\"nLeftrightarrow\", {226, 135, 142, 0}},\n{(unsigned char*)\"nLl\", {226, 139, 152, 204, 184, 0}},\n{(unsigned char*)\"nLt\", {226, 137, 170, 226, 131, 146, 0}},\n{(unsigned char*)\"nLtv\", {226, 137, 170, 204, 184, 0}},\n{(unsigned char*)\"nRightarrow\", {226, 135, 143, 0}},\n{(unsigned char*)\"nVDash\", {226, 138, 175, 0}},\n{(unsigned char*)\"nVdash\", {226, 138, 174, 0}},\n{(unsigned char*)\"nabla\", {226, 136, 135, 0}},\n{(unsigned char*)\"nacute\", {197, 132, 0}},\n{(unsigned char*)\"nang\", {226, 136, 160, 226, 131, 146, 0}},\n{(unsigned char*)\"nap\", {226, 137, 137, 0}},\n{(unsigned char*)\"napE\", {226, 169, 176, 204, 184, 0}},\n{(unsigned char*)\"napid\", {226, 137, 139, 204, 184, 0}},\n{(unsigned char*)\"napos\", {197, 137, 0}},\n{(unsigned char*)\"napprox\", {226, 137, 137, 0}},\n{(unsigned char*)\"natur\", {226, 153, 174, 0}},\n{(unsigned char*)\"natural\", {226, 153, 174, 0}},\n{(unsigned char*)\"naturals\", {226, 132, 149, 0}},\n{(unsigned char*)\"nbsp\", {194, 160, 0}},\n{(unsigned char*)\"nbump\", {226, 137, 142, 204, 184, 0}},\n{(unsigned char*)\"nbumpe\", {226, 137, 143, 204, 184, 0}},\n{(unsigned char*)\"ncap\", {226, 169, 131, 0}},\n{(unsigned char*)\"ncaron\", {197, 136, 0}},\n{(unsigned char*)\"ncedil\", {197, 134, 0}},\n{(unsigned char*)\"ncong\", {226, 137, 135, 0}},\n{(unsigned char*)\"ncongdot\", {226, 169, 173, 204, 184, 0}},\n{(unsigned char*)\"ncup\", {226, 169, 130, 0}},\n{(unsigned char*)\"ncy\", {208, 189, 0}},\n{(unsigned char*)\"ndash\", {226, 128, 147, 0}},\n{(unsigned char*)\"ne\", {226, 137, 160, 0}},\n{(unsigned char*)\"neArr\", {226, 135, 151, 0}},\n{(unsigned char*)\"nearhk\", {226, 164, 164, 0}},\n{(unsigned char*)\"nearr\", {226, 134, 151, 0}},\n{(unsigned char*)\"nearrow\", {226, 134, 151, 0}},\n{(unsigned char*)\"nedot\", {226, 137, 144, 204, 184, 0}},\n{(unsigned char*)\"nequiv\", {226, 137, 162, 0}},\n{(unsigned char*)\"nesear\", {226, 164, 168, 0}},\n{(unsigned char*)\"nesim\", {226, 137, 130, 204, 184, 0}},\n{(unsigned char*)\"nexist\", {226, 136, 132, 0}},\n{(unsigned char*)\"nexists\", {226, 136, 132, 0}},\n{(unsigned char*)\"nfr\", {240, 157, 148, 171, 0}},\n{(unsigned char*)\"ngE\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"nge\", {226, 137, 177, 0}},\n{(unsigned char*)\"ngeq\", {226, 137, 177, 0}},\n{(unsigned char*)\"ngeqq\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"ngeqslant\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"nges\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"ngsim\", {226, 137, 181, 0}},\n{(unsigned char*)\"ngt\", {226, 137, 175, 0}},\n{(unsigned char*)\"ngtr\", {226, 137, 175, 0}},\n{(unsigned char*)\"nhArr\", {226, 135, 142, 0}},\n{(unsigned char*)\"nharr\", {226, 134, 174, 0}},\n{(unsigned char*)\"nhpar\", {226, 171, 178, 0}},\n{(unsigned char*)\"ni\", {226, 136, 139, 0}},\n{(unsigned char*)\"nis\", {226, 139, 188, 0}},\n{(unsigned char*)\"nisd\", {226, 139, 186, 0}},\n{(unsigned char*)\"niv\", {226, 136, 139, 0}},\n{(unsigned char*)\"njcy\", {209, 154, 0}},\n{(unsigned char*)\"nlArr\", {226, 135, 141, 0}},\n{(unsigned char*)\"nlE\", {226, 137, 166, 204, 184, 0}},\n{(unsigned char*)\"nlarr\", {226, 134, 154, 0}},\n{(unsigned char*)\"nldr\", {226, 128, 165, 0}},\n{(unsigned char*)\"nle\", {226, 137, 176, 0}},\n{(unsigned char*)\"nleftarrow\", {226, 134, 154, 0}},\n{(unsigned char*)\"nleftrightarrow\", {226, 134, 174, 0}},\n{(unsigned char*)\"nleq\", {226, 137, 176, 0}},\n{(unsigned char*)\"nleqq\", {226, 137, 166, 204, 184, 0}},\n{(unsigned char*)\"nleqslant\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"nles\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"nless\", {226, 137, 174, 0}},\n{(unsigned char*)\"nlsim\", {226, 137, 180, 0}},\n{(unsigned char*)\"nlt\", {226, 137, 174, 0}},\n{(unsigned char*)\"nltri\", {226, 139, 170, 0}},\n{(unsigned char*)\"nltrie\", {226, 139, 172, 0}},\n{(unsigned char*)\"nmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nopf\", {240, 157, 149, 159, 0}},\n{(unsigned char*)\"not\", {194, 172, 0}},\n{(unsigned char*)\"notin\", {226, 136, 137, 0}},\n{(unsigned char*)\"notinE\", {226, 139, 185, 204, 184, 0}},\n{(unsigned char*)\"notindot\", {226, 139, 181, 204, 184, 0}},\n{(unsigned char*)\"notinva\", {226, 136, 137, 0}},\n{(unsigned char*)\"notinvb\", {226, 139, 183, 0}},\n{(unsigned char*)\"notinvc\", {226, 139, 182, 0}},\n{(unsigned char*)\"notni\", {226, 136, 140, 0}},\n{(unsigned char*)\"notniva\", {226, 136, 140, 0}},\n{(unsigned char*)\"notnivb\", {226, 139, 190, 0}},\n{(unsigned char*)\"notnivc\", {226, 139, 189, 0}},\n{(unsigned char*)\"npar\", {226, 136, 166, 0}},\n{(unsigned char*)\"nparallel\", {226, 136, 166, 0}},\n{(unsigned char*)\"nparsl\", {226, 171, 189, 226, 131, 165, 0}},\n{(unsigned char*)\"npart\", {226, 136, 130, 204, 184, 0}},\n{(unsigned char*)\"npolint\", {226, 168, 148, 0}},\n{(unsigned char*)\"npr\", {226, 138, 128, 0}},\n{(unsigned char*)\"nprcue\", {226, 139, 160, 0}},\n{(unsigned char*)\"npre\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"nprec\", {226, 138, 128, 0}},\n{(unsigned char*)\"npreceq\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"nrArr\", {226, 135, 143, 0}},\n{(unsigned char*)\"nrarr\", {226, 134, 155, 0}},\n{(unsigned char*)\"nrarrc\", {226, 164, 179, 204, 184, 0}},\n{(unsigned char*)\"nrarrw\", {226, 134, 157, 204, 184, 0}},\n{(unsigned char*)\"nrightarrow\", {226, 134, 155, 0}},\n{(unsigned char*)\"nrtri\", {226, 139, 171, 0}},\n{(unsigned char*)\"nrtrie\", {226, 139, 173, 0}},\n{(unsigned char*)\"nsc\", {226, 138, 129, 0}},\n{(unsigned char*)\"nsccue\", {226, 139, 161, 0}},\n{(unsigned char*)\"nsce\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"nscr\", {240, 157, 147, 131, 0}},\n{(unsigned char*)\"nshortmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nshortparallel\", {226, 136, 166, 0}},\n{(unsigned char*)\"nsim\", {226, 137, 129, 0}},\n{(unsigned char*)\"nsime\", {226, 137, 132, 0}},\n{(unsigned char*)\"nsimeq\", {226, 137, 132, 0}},\n{(unsigned char*)\"nsmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nspar\", {226, 136, 166, 0}},\n{(unsigned char*)\"nsqsube\", {226, 139, 162, 0}},\n{(unsigned char*)\"nsqsupe\", {226, 139, 163, 0}},\n{(unsigned char*)\"nsub\", {226, 138, 132, 0}},\n{(unsigned char*)\"nsubE\", {226, 171, 133, 204, 184, 0}},\n{(unsigned char*)\"nsube\", {226, 138, 136, 0}},\n{(unsigned char*)\"nsubset\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"nsubseteq\", {226, 138, 136, 0}},\n{(unsigned char*)\"nsubseteqq\", {226, 171, 133, 204, 184, 0}},\n{(unsigned char*)\"nsucc\", {226, 138, 129, 0}},\n{(unsigned char*)\"nsucceq\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"nsup\", {226, 138, 133, 0}},\n{(unsigned char*)\"nsupE\", {226, 171, 134, 204, 184, 0}},\n{(unsigned char*)\"nsupe\", {226, 138, 137, 0}},\n{(unsigned char*)\"nsupset\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"nsupseteq\", {226, 138, 137, 0}},\n{(unsigned char*)\"nsupseteqq\", {226, 171, 134, 204, 184, 0}},\n{(unsigned char*)\"ntgl\", {226, 137, 185, 0}},\n{(unsigned char*)\"ntilde\", {195, 177, 0}},\n{(unsigned char*)\"ntlg\", {226, 137, 184, 0}},\n{(unsigned char*)\"ntriangleleft\", {226, 139, 170, 0}},\n{(unsigned char*)\"ntrianglelefteq\", {226, 139, 172, 0}},\n{(unsigned char*)\"ntriangleright\", {226, 139, 171, 0}},\n{(unsigned char*)\"ntrianglerighteq\", {226, 139, 173, 0}},\n{(unsigned char*)\"nu\", {206, 189, 0}},\n{(unsigned char*)\"num\", {35, 0}},\n{(unsigned char*)\"numero\", {226, 132, 150, 0}},\n{(unsigned char*)\"numsp\", {226, 128, 135, 0}},\n{(unsigned char*)\"nvDash\", {226, 138, 173, 0}},\n{(unsigned char*)\"nvHarr\", {226, 164, 132, 0}},\n{(unsigned char*)\"nvap\", {226, 137, 141, 226, 131, 146, 0}},\n{(unsigned char*)\"nvdash\", {226, 138, 172, 0}},\n{(unsigned char*)\"nvge\", {226, 137, 165, 226, 131, 146, 0}},\n{(unsigned char*)\"nvgt\", {62, 226, 131, 146, 0}},\n{(unsigned char*)\"nvinfin\", {226, 167, 158, 0}},\n{(unsigned char*)\"nvlArr\", {226, 164, 130, 0}},\n{(unsigned char*)\"nvle\", {226, 137, 164, 226, 131, 146, 0}},\n{(unsigned char*)\"nvlt\", {60, 226, 131, 146, 0}},\n{(unsigned char*)\"nvltrie\", {226, 138, 180, 226, 131, 146, 0}},\n{(unsigned char*)\"nvrArr\", {226, 164, 131, 0}},\n{(unsigned char*)\"nvrtrie\", {226, 138, 181, 226, 131, 146, 0}},\n{(unsigned char*)\"nvsim\", {226, 136, 188, 226, 131, 146, 0}},\n{(unsigned char*)\"nwArr\", {226, 135, 150, 0}},\n{(unsigned char*)\"nwarhk\", {226, 164, 163, 0}},\n{(unsigned char*)\"nwarr\", {226, 134, 150, 0}},\n{(unsigned char*)\"nwarrow\", {226, 134, 150, 0}},\n{(unsigned char*)\"nwnear\", {226, 164, 167, 0}},\n{(unsigned char*)\"oS\", {226, 147, 136, 0}},\n{(unsigned char*)\"oacute\", {195, 179, 0}},\n{(unsigned char*)\"oast\", {226, 138, 155, 0}},\n{(unsigned char*)\"ocir\", {226, 138, 154, 0}},\n{(unsigned char*)\"ocirc\", {195, 180, 0}},\n{(unsigned char*)\"ocy\", {208, 190, 0}},\n{(unsigned char*)\"odash\", {226, 138, 157, 0}},\n{(unsigned char*)\"odblac\", {197, 145, 0}},\n{(unsigned char*)\"odiv\", {226, 168, 184, 0}},\n{(unsigned char*)\"odot\", {226, 138, 153, 0}},\n{(unsigned char*)\"odsold\", {226, 166, 188, 0}},\n{(unsigned char*)\"oelig\", {197, 147, 0}},\n{(unsigned char*)\"ofcir\", {226, 166, 191, 0}},\n{(unsigned char*)\"ofr\", {240, 157, 148, 172, 0}},\n{(unsigned char*)\"ogon\", {203, 155, 0}},\n{(unsigned char*)\"ograve\", {195, 178, 0}},\n{(unsigned char*)\"ogt\", {226, 167, 129, 0}},\n{(unsigned char*)\"ohbar\", {226, 166, 181, 0}},\n{(unsigned char*)\"ohm\", {206, 169, 0}},\n{(unsigned char*)\"oint\", {226, 136, 174, 0}},\n{(unsigned char*)\"olarr\", {226, 134, 186, 0}},\n{(unsigned char*)\"olcir\", {226, 166, 190, 0}},\n{(unsigned char*)\"olcross\", {226, 166, 187, 0}},\n{(unsigned char*)\"oline\", {226, 128, 190, 0}},\n{(unsigned char*)\"olt\", {226, 167, 128, 0}},\n{(unsigned char*)\"omacr\", {197, 141, 0}},\n{(unsigned char*)\"omega\", {207, 137, 0}},\n{(unsigned char*)\"omicron\", {206, 191, 0}},\n{(unsigned char*)\"omid\", {226, 166, 182, 0}},\n{(unsigned char*)\"ominus\", {226, 138, 150, 0}},\n{(unsigned char*)\"oopf\", {240, 157, 149, 160, 0}},\n{(unsigned char*)\"opar\", {226, 166, 183, 0}},\n{(unsigned char*)\"operp\", {226, 166, 185, 0}},\n{(unsigned char*)\"oplus\", {226, 138, 149, 0}},\n{(unsigned char*)\"or\", {226, 136, 168, 0}},\n{(unsigned char*)\"orarr\", {226, 134, 187, 0}},\n{(unsigned char*)\"ord\", {226, 169, 157, 0}},\n{(unsigned char*)\"order\", {226, 132, 180, 0}},\n{(unsigned char*)\"orderof\", {226, 132, 180, 0}},\n{(unsigned char*)\"ordf\", {194, 170, 0}},\n{(unsigned char*)\"ordm\", {194, 186, 0}},\n{(unsigned char*)\"origof\", {226, 138, 182, 0}},\n{(unsigned char*)\"oror\", {226, 169, 150, 0}},\n{(unsigned char*)\"orslope\", {226, 169, 151, 0}},\n{(unsigned char*)\"orv\", {226, 169, 155, 0}},\n{(unsigned char*)\"oscr\", {226, 132, 180, 0}},\n{(unsigned char*)\"oslash\", {195, 184, 0}},\n{(unsigned char*)\"osol\", {226, 138, 152, 0}},\n{(unsigned char*)\"otilde\", {195, 181, 0}},\n{(unsigned char*)\"otimes\", {226, 138, 151, 0}},\n{(unsigned char*)\"otimesas\", {226, 168, 182, 0}},\n{(unsigned char*)\"ouml\", {195, 182, 0}},\n{(unsigned char*)\"ovbar\", {226, 140, 189, 0}},\n{(unsigned char*)\"par\", {226, 136, 165, 0}},\n{(unsigned char*)\"para\", {194, 182, 0}},\n{(unsigned char*)\"parallel\", {226, 136, 165, 0}},\n{(unsigned char*)\"parsim\", {226, 171, 179, 0}},\n{(unsigned char*)\"parsl\", {226, 171, 189, 0}},\n{(unsigned char*)\"part\", {226, 136, 130, 0}},\n{(unsigned char*)\"pcy\", {208, 191, 0}},\n{(unsigned char*)\"percnt\", {37, 0}},\n{(unsigned char*)\"period\", {46, 0}},\n{(unsigned char*)\"permil\", {226, 128, 176, 0}},\n{(unsigned char*)\"perp\", {226, 138, 165, 0}},\n{(unsigned char*)\"pertenk\", {226, 128, 177, 0}},\n{(unsigned char*)\"pfr\", {240, 157, 148, 173, 0}},\n{(unsigned char*)\"phi\", {207, 134, 0}},\n{(unsigned char*)\"phiv\", {207, 149, 0}},\n{(unsigned char*)\"phmmat\", {226, 132, 179, 0}},\n{(unsigned char*)\"phone\", {226, 152, 142, 0}},\n{(unsigned char*)\"pi\", {207, 128, 0}},\n{(unsigned char*)\"pitchfork\", {226, 139, 148, 0}},\n{(unsigned char*)\"piv\", {207, 150, 0}},\n{(unsigned char*)\"planck\", {226, 132, 143, 0}},\n{(unsigned char*)\"planckh\", {226, 132, 142, 0}},\n{(unsigned char*)\"plankv\", {226, 132, 143, 0}},\n{(unsigned char*)\"plus\", {43, 0}},\n{(unsigned char*)\"plusacir\", {226, 168, 163, 0}},\n{(unsigned char*)\"plusb\", {226, 138, 158, 0}},\n{(unsigned char*)\"pluscir\", {226, 168, 162, 0}},\n{(unsigned char*)\"plusdo\", {226, 136, 148, 0}},\n{(unsigned char*)\"plusdu\", {226, 168, 165, 0}},\n{(unsigned char*)\"pluse\", {226, 169, 178, 0}},\n{(unsigned char*)\"plusmn\", {194, 177, 0}},\n{(unsigned char*)\"plussim\", {226, 168, 166, 0}},\n{(unsigned char*)\"plustwo\", {226, 168, 167, 0}},\n{(unsigned char*)\"pm\", {194, 177, 0}},\n{(unsigned char*)\"pointint\", {226, 168, 149, 0}},\n{(unsigned char*)\"popf\", {240, 157, 149, 161, 0}},\n{(unsigned char*)\"pound\", {194, 163, 0}},\n{(unsigned char*)\"pr\", {226, 137, 186, 0}},\n{(unsigned char*)\"prE\", {226, 170, 179, 0}},\n{(unsigned char*)\"prap\", {226, 170, 183, 0}},\n{(unsigned char*)\"prcue\", {226, 137, 188, 0}},\n{(unsigned char*)\"pre\", {226, 170, 175, 0}},\n{(unsigned char*)\"prec\", {226, 137, 186, 0}},\n{(unsigned char*)\"precapprox\", {226, 170, 183, 0}},\n{(unsigned char*)\"preccurlyeq\", {226, 137, 188, 0}},\n{(unsigned char*)\"preceq\", {226, 170, 175, 0}},\n{(unsigned char*)\"precnapprox\", {226, 170, 185, 0}},\n{(unsigned char*)\"precneqq\", {226, 170, 181, 0}},\n{(unsigned char*)\"precnsim\", {226, 139, 168, 0}},\n{(unsigned char*)\"precsim\", {226, 137, 190, 0}},\n{(unsigned char*)\"prime\", {226, 128, 178, 0}},\n{(unsigned char*)\"primes\", {226, 132, 153, 0}},\n{(unsigned char*)\"prnE\", {226, 170, 181, 0}},\n{(unsigned char*)\"prnap\", {226, 170, 185, 0}},\n{(unsigned char*)\"prnsim\", {226, 139, 168, 0}},\n{(unsigned char*)\"prod\", {226, 136, 143, 0}},\n{(unsigned char*)\"profalar\", {226, 140, 174, 0}},\n{(unsigned char*)\"profline\", {226, 140, 146, 0}},\n{(unsigned char*)\"profsurf\", {226, 140, 147, 0}},\n{(unsigned char*)\"prop\", {226, 136, 157, 0}},\n{(unsigned char*)\"propto\", {226, 136, 157, 0}},\n{(unsigned char*)\"prsim\", {226, 137, 190, 0}},\n{(unsigned char*)\"prurel\", {226, 138, 176, 0}},\n{(unsigned char*)\"pscr\", {240, 157, 147, 133, 0}},\n{(unsigned char*)\"psi\", {207, 136, 0}},\n{(unsigned char*)\"puncsp\", {226, 128, 136, 0}},\n{(unsigned char*)\"qfr\", {240, 157, 148, 174, 0}},\n{(unsigned char*)\"qint\", {226, 168, 140, 0}},\n{(unsigned char*)\"qopf\", {240, 157, 149, 162, 0}},\n{(unsigned char*)\"qprime\", {226, 129, 151, 0}},\n{(unsigned char*)\"qscr\", {240, 157, 147, 134, 0}},\n{(unsigned char*)\"quaternions\", {226, 132, 141, 0}},\n{(unsigned char*)\"quatint\", {226, 168, 150, 0}},\n{(unsigned char*)\"quest\", {63, 0}},\n{(unsigned char*)\"questeq\", {226, 137, 159, 0}},\n{(unsigned char*)\"quot\", {34, 0}},\n{(unsigned char*)\"rAarr\", {226, 135, 155, 0}},\n{(unsigned char*)\"rArr\", {226, 135, 146, 0}},\n{(unsigned char*)\"rAtail\", {226, 164, 156, 0}},\n{(unsigned char*)\"rBarr\", {226, 164, 143, 0}},\n{(unsigned char*)\"rHar\", {226, 165, 164, 0}},\n{(unsigned char*)\"race\", {226, 136, 189, 204, 177, 0}},\n{(unsigned char*)\"racute\", {197, 149, 0}},\n{(unsigned char*)\"radic\", {226, 136, 154, 0}},\n{(unsigned char*)\"raemptyv\", {226, 166, 179, 0}},\n{(unsigned char*)\"rang\", {226, 159, 169, 0}},\n{(unsigned char*)\"rangd\", {226, 166, 146, 0}},\n{(unsigned char*)\"range\", {226, 166, 165, 0}},\n{(unsigned char*)\"rangle\", {226, 159, 169, 0}},\n{(unsigned char*)\"raquo\", {194, 187, 0}},\n{(unsigned char*)\"rarr\", {226, 134, 146, 0}},\n{(unsigned char*)\"rarrap\", {226, 165, 181, 0}},\n{(unsigned char*)\"rarrb\", {226, 135, 165, 0}},\n{(unsigned char*)\"rarrbfs\", {226, 164, 160, 0}},\n{(unsigned char*)\"rarrc\", {226, 164, 179, 0}},\n{(unsigned char*)\"rarrfs\", {226, 164, 158, 0}},\n{(unsigned char*)\"rarrhk\", {226, 134, 170, 0}},\n{(unsigned char*)\"rarrlp\", {226, 134, 172, 0}},\n{(unsigned char*)\"rarrpl\", {226, 165, 133, 0}},\n{(unsigned char*)\"rarrsim\", {226, 165, 180, 0}},\n{(unsigned char*)\"rarrtl\", {226, 134, 163, 0}},\n{(unsigned char*)\"rarrw\", {226, 134, 157, 0}},\n{(unsigned char*)\"ratail\", {226, 164, 154, 0}},\n{(unsigned char*)\"ratio\", {226, 136, 182, 0}},\n{(unsigned char*)\"rationals\", {226, 132, 154, 0}},\n{(unsigned char*)\"rbarr\", {226, 164, 141, 0}},\n{(unsigned char*)\"rbbrk\", {226, 157, 179, 0}},\n{(unsigned char*)\"rbrace\", {125, 0}},\n{(unsigned char*)\"rbrack\", {93, 0}},\n{(unsigned char*)\"rbrke\", {226, 166, 140, 0}},\n{(unsigned char*)\"rbrksld\", {226, 166, 142, 0}},\n{(unsigned char*)\"rbrkslu\", {226, 166, 144, 0}},\n{(unsigned char*)\"rcaron\", {197, 153, 0}},\n{(unsigned char*)\"rcedil\", {197, 151, 0}},\n{(unsigned char*)\"rceil\", {226, 140, 137, 0}},\n{(unsigned char*)\"rcub\", {125, 0}},\n{(unsigned char*)\"rcy\", {209, 128, 0}},\n{(unsigned char*)\"rdca\", {226, 164, 183, 0}},\n{(unsigned char*)\"rdldhar\", {226, 165, 169, 0}},\n{(unsigned char*)\"rdquo\", {226, 128, 157, 0}},\n{(unsigned char*)\"rdquor\", {226, 128, 157, 0}},\n{(unsigned char*)\"rdsh\", {226, 134, 179, 0}},\n{(unsigned char*)\"real\", {226, 132, 156, 0}},\n{(unsigned char*)\"realine\", {226, 132, 155, 0}},\n{(unsigned char*)\"realpart\", {226, 132, 156, 0}},\n{(unsigned char*)\"reals\", {226, 132, 157, 0}},\n{(unsigned char*)\"rect\", {226, 150, 173, 0}},\n{(unsigned char*)\"reg\", {194, 174, 0}},\n{(unsigned char*)\"rfisht\", {226, 165, 189, 0}},\n{(unsigned char*)\"rfloor\", {226, 140, 139, 0}},\n{(unsigned char*)\"rfr\", {240, 157, 148, 175, 0}},\n{(unsigned char*)\"rhard\", {226, 135, 129, 0}},\n{(unsigned char*)\"rharu\", {226, 135, 128, 0}},\n{(unsigned char*)\"rharul\", {226, 165, 172, 0}},\n{(unsigned char*)\"rho\", {207, 129, 0}},\n{(unsigned char*)\"rhov\", {207, 177, 0}},\n{(unsigned char*)\"rightarrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"rightarrowtail\", {226, 134, 163, 0}},\n{(unsigned char*)\"rightharpoondown\", {226, 135, 129, 0}},\n{(unsigned char*)\"rightharpoonup\", {226, 135, 128, 0}},\n{(unsigned char*)\"rightleftarrows\", {226, 135, 132, 0}},\n{(unsigned char*)\"rightleftharpoons\", {226, 135, 140, 0}},\n{(unsigned char*)\"rightrightarrows\", {226, 135, 137, 0}},\n{(unsigned char*)\"rightsquigarrow\", {226, 134, 157, 0}},\n{(unsigned char*)\"rightthreetimes\", {226, 139, 140, 0}},\n{(unsigned char*)\"ring\", {203, 154, 0}},\n{(unsigned char*)\"risingdotseq\", {226, 137, 147, 0}},\n{(unsigned char*)\"rlarr\", {226, 135, 132, 0}},\n{(unsigned char*)\"rlhar\", {226, 135, 140, 0}},\n{(unsigned char*)\"rlm\", {226, 128, 143, 0}},\n{(unsigned char*)\"rmoust\", {226, 142, 177, 0}},\n{(unsigned char*)\"rmoustache\", {226, 142, 177, 0}},\n{(unsigned char*)\"rnmid\", {226, 171, 174, 0}},\n{(unsigned char*)\"roang\", {226, 159, 173, 0}},\n{(unsigned char*)\"roarr\", {226, 135, 190, 0}},\n{(unsigned char*)\"robrk\", {226, 159, 167, 0}},\n{(unsigned char*)\"ropar\", {226, 166, 134, 0}},\n{(unsigned char*)\"ropf\", {240, 157, 149, 163, 0}},\n{(unsigned char*)\"roplus\", {226, 168, 174, 0}},\n{(unsigned char*)\"rotimes\", {226, 168, 181, 0}},\n{(unsigned char*)\"rpar\", {41, 0}},\n{(unsigned char*)\"rpargt\", {226, 166, 148, 0}},\n{(unsigned char*)\"rppolint\", {226, 168, 146, 0}},\n{(unsigned char*)\"rrarr\", {226, 135, 137, 0}},\n{(unsigned char*)\"rsaquo\", {226, 128, 186, 0}},\n{(unsigned char*)\"rscr\", {240, 157, 147, 135, 0}},\n{(unsigned char*)\"rsh\", {226, 134, 177, 0}},\n{(unsigned char*)\"rsqb\", {93, 0}},\n{(unsigned char*)\"rsquo\", {226, 128, 153, 0}},\n{(unsigned char*)\"rsquor\", {226, 128, 153, 0}},\n{(unsigned char*)\"rthree\", {226, 139, 140, 0}},\n{(unsigned char*)\"rtimes\", {226, 139, 138, 0}},\n{(unsigned char*)\"rtri\", {226, 150, 185, 0}},\n{(unsigned char*)\"rtrie\", {226, 138, 181, 0}},\n{(unsigned char*)\"rtrif\", {226, 150, 184, 0}},\n{(unsigned char*)\"rtriltri\", {226, 167, 142, 0}},\n{(unsigned char*)\"ruluhar\", {226, 165, 168, 0}},\n{(unsigned char*)\"rx\", {226, 132, 158, 0}},\n{(unsigned char*)\"sacute\", {197, 155, 0}},\n{(unsigned char*)\"sbquo\", {226, 128, 154, 0}},\n{(unsigned char*)\"sc\", {226, 137, 187, 0}},\n{(unsigned char*)\"scE\", {226, 170, 180, 0}},\n{(unsigned char*)\"scap\", {226, 170, 184, 0}},\n{(unsigned char*)\"scaron\", {197, 161, 0}},\n{(unsigned char*)\"sccue\", {226, 137, 189, 0}},\n{(unsigned char*)\"sce\", {226, 170, 176, 0}},\n{(unsigned char*)\"scedil\", {197, 159, 0}},\n{(unsigned char*)\"scirc\", {197, 157, 0}},\n{(unsigned char*)\"scnE\", {226, 170, 182, 0}},\n{(unsigned char*)\"scnap\", {226, 170, 186, 0}},\n{(unsigned char*)\"scnsim\", {226, 139, 169, 0}},\n{(unsigned char*)\"scpolint\", {226, 168, 147, 0}},\n{(unsigned char*)\"scsim\", {226, 137, 191, 0}},\n{(unsigned char*)\"scy\", {209, 129, 0}},\n{(unsigned char*)\"sdot\", {226, 139, 133, 0}},\n{(unsigned char*)\"sdotb\", {226, 138, 161, 0}},\n{(unsigned char*)\"sdote\", {226, 169, 166, 0}},\n{(unsigned char*)\"seArr\", {226, 135, 152, 0}},\n{(unsigned char*)\"searhk\", {226, 164, 165, 0}},\n{(unsigned char*)\"searr\", {226, 134, 152, 0}},\n{(unsigned char*)\"searrow\", {226, 134, 152, 0}},\n{(unsigned char*)\"sect\", {194, 167, 0}},\n{(unsigned char*)\"semi\", {59, 0}},\n{(unsigned char*)\"seswar\", {226, 164, 169, 0}},\n{(unsigned char*)\"setminus\", {226, 136, 150, 0}},\n{(unsigned char*)\"setmn\", {226, 136, 150, 0}},\n{(unsigned char*)\"sext\", {226, 156, 182, 0}},\n{(unsigned char*)\"sfr\", {240, 157, 148, 176, 0}},\n{(unsigned char*)\"sfrown\", {226, 140, 162, 0}},\n{(unsigned char*)\"sharp\", {226, 153, 175, 0}},\n{(unsigned char*)\"shchcy\", {209, 137, 0}},\n{(unsigned char*)\"shcy\", {209, 136, 0}},\n{(unsigned char*)\"shortmid\", {226, 136, 163, 0}},\n{(unsigned char*)\"shortparallel\", {226, 136, 165, 0}},\n{(unsigned char*)\"shy\", {194, 173, 0}},\n{(unsigned char*)\"sigma\", {207, 131, 0}},\n{(unsigned char*)\"sigmaf\", {207, 130, 0}},\n{(unsigned char*)\"sigmav\", {207, 130, 0}},\n{(unsigned char*)\"sim\", {226, 136, 188, 0}},\n{(unsigned char*)\"simdot\", {226, 169, 170, 0}},\n{(unsigned char*)\"sime\", {226, 137, 131, 0}},\n{(unsigned char*)\"simeq\", {226, 137, 131, 0}},\n{(unsigned char*)\"simg\", {226, 170, 158, 0}},\n{(unsigned char*)\"simgE\", {226, 170, 160, 0}},\n{(unsigned char*)\"siml\", {226, 170, 157, 0}},\n{(unsigned char*)\"simlE\", {226, 170, 159, 0}},\n{(unsigned char*)\"simne\", {226, 137, 134, 0}},\n{(unsigned char*)\"simplus\", {226, 168, 164, 0}},\n{(unsigned char*)\"simrarr\", {226, 165, 178, 0}},\n{(unsigned char*)\"slarr\", {226, 134, 144, 0}},\n{(unsigned char*)\"smallsetminus\", {226, 136, 150, 0}},\n{(unsigned char*)\"smashp\", {226, 168, 179, 0}},\n{(unsigned char*)\"smeparsl\", {226, 167, 164, 0}},\n{(unsigned char*)\"smid\", {226, 136, 163, 0}},\n{(unsigned char*)\"smile\", {226, 140, 163, 0}},\n{(unsigned char*)\"smt\", {226, 170, 170, 0}},\n{(unsigned char*)\"smte\", {226, 170, 172, 0}},\n{(unsigned char*)\"smtes\", {226, 170, 172, 239, 184, 128, 0}},\n{(unsigned char*)\"softcy\", {209, 140, 0}},\n{(unsigned char*)\"sol\", {47, 0}},\n{(unsigned char*)\"solb\", {226, 167, 132, 0}},\n{(unsigned char*)\"solbar\", {226, 140, 191, 0}},\n{(unsigned char*)\"sopf\", {240, 157, 149, 164, 0}},\n{(unsigned char*)\"spades\", {226, 153, 160, 0}},\n{(unsigned char*)\"spadesuit\", {226, 153, 160, 0}},\n{(unsigned char*)\"spar\", {226, 136, 165, 0}},\n{(unsigned char*)\"sqcap\", {226, 138, 147, 0}},\n{(unsigned char*)\"sqcaps\", {226, 138, 147, 239, 184, 128, 0}},\n{(unsigned char*)\"sqcup\", {226, 138, 148, 0}},\n{(unsigned char*)\"sqcups\", {226, 138, 148, 239, 184, 128, 0}},\n{(unsigned char*)\"sqsub\", {226, 138, 143, 0}},\n{(unsigned char*)\"sqsube\", {226, 138, 145, 0}},\n{(unsigned char*)\"sqsubset\", {226, 138, 143, 0}},\n{(unsigned char*)\"sqsubseteq\", {226, 138, 145, 0}},\n{(unsigned char*)\"sqsup\", {226, 138, 144, 0}},\n{(unsigned char*)\"sqsupe\", {226, 138, 146, 0}},\n{(unsigned char*)\"sqsupset\", {226, 138, 144, 0}},\n{(unsigned char*)\"sqsupseteq\", {226, 138, 146, 0}},\n{(unsigned char*)\"squ\", {226, 150, 161, 0}},\n{(unsigned char*)\"square\", {226, 150, 161, 0}},\n{(unsigned char*)\"squarf\", {226, 150, 170, 0}},\n{(unsigned char*)\"squf\", {226, 150, 170, 0}},\n{(unsigned char*)\"srarr\", {226, 134, 146, 0}},\n{(unsigned char*)\"sscr\", {240, 157, 147, 136, 0}},\n{(unsigned char*)\"ssetmn\", {226, 136, 150, 0}},\n{(unsigned char*)\"ssmile\", {226, 140, 163, 0}},\n{(unsigned char*)\"sstarf\", {226, 139, 134, 0}},\n{(unsigned char*)\"star\", {226, 152, 134, 0}},\n{(unsigned char*)\"starf\", {226, 152, 133, 0}},\n{(unsigned char*)\"straightepsilon\", {207, 181, 0}},\n{(unsigned char*)\"straightphi\", {207, 149, 0}},\n{(unsigned char*)\"strns\", {194, 175, 0}},\n{(unsigned char*)\"sub\", {226, 138, 130, 0}},\n{(unsigned char*)\"subE\", {226, 171, 133, 0}},\n{(unsigned char*)\"subdot\", {226, 170, 189, 0}},\n{(unsigned char*)\"sube\", {226, 138, 134, 0}},\n{(unsigned char*)\"subedot\", {226, 171, 131, 0}},\n{(unsigned char*)\"submult\", {226, 171, 129, 0}},\n{(unsigned char*)\"subnE\", {226, 171, 139, 0}},\n{(unsigned char*)\"subne\", {226, 138, 138, 0}},\n{(unsigned char*)\"subplus\", {226, 170, 191, 0}},\n{(unsigned char*)\"subrarr\", {226, 165, 185, 0}},\n{(unsigned char*)\"subset\", {226, 138, 130, 0}},\n{(unsigned char*)\"subseteq\", {226, 138, 134, 0}},\n{(unsigned char*)\"subseteqq\", {226, 171, 133, 0}},\n{(unsigned char*)\"subsetneq\", {226, 138, 138, 0}},\n{(unsigned char*)\"subsetneqq\", {226, 171, 139, 0}},\n{(unsigned char*)\"subsim\", {226, 171, 135, 0}},\n{(unsigned char*)\"subsub\", {226, 171, 149, 0}},\n{(unsigned char*)\"subsup\", {226, 171, 147, 0}},\n{(unsigned char*)\"succ\", {226, 137, 187, 0}},\n{(unsigned char*)\"succapprox\", {226, 170, 184, 0}},\n{(unsigned char*)\"succcurlyeq\", {226, 137, 189, 0}},\n{(unsigned char*)\"succeq\", {226, 170, 176, 0}},\n{(unsigned char*)\"succnapprox\", {226, 170, 186, 0}},\n{(unsigned char*)\"succneqq\", {226, 170, 182, 0}},\n{(unsigned char*)\"succnsim\", {226, 139, 169, 0}},\n{(unsigned char*)\"succsim\", {226, 137, 191, 0}},\n{(unsigned char*)\"sum\", {226, 136, 145, 0}},\n{(unsigned char*)\"sung\", {226, 153, 170, 0}},\n{(unsigned char*)\"sup\", {226, 138, 131, 0}},\n{(unsigned char*)\"sup1\", {194, 185, 0}},\n{(unsigned char*)\"sup2\", {194, 178, 0}},\n{(unsigned char*)\"sup3\", {194, 179, 0}},\n{(unsigned char*)\"supE\", {226, 171, 134, 0}},\n{(unsigned char*)\"supdot\", {226, 170, 190, 0}},\n{(unsigned char*)\"supdsub\", {226, 171, 152, 0}},\n{(unsigned char*)\"supe\", {226, 138, 135, 0}},\n{(unsigned char*)\"supedot\", {226, 171, 132, 0}},\n{(unsigned char*)\"suphsol\", {226, 159, 137, 0}},\n{(unsigned char*)\"suphsub\", {226, 171, 151, 0}},\n{(unsigned char*)\"suplarr\", {226, 165, 187, 0}},\n{(unsigned char*)\"supmult\", {226, 171, 130, 0}},\n{(unsigned char*)\"supnE\", {226, 171, 140, 0}},\n{(unsigned char*)\"supne\", {226, 138, 139, 0}},\n{(unsigned char*)\"supplus\", {226, 171, 128, 0}},\n{(unsigned char*)\"supset\", {226, 138, 131, 0}},\n{(unsigned char*)\"supseteq\", {226, 138, 135, 0}},\n{(unsigned char*)\"supseteqq\", {226, 171, 134, 0}},\n{(unsigned char*)\"supsetneq\", {226, 138, 139, 0}},\n{(unsigned char*)\"supsetneqq\", {226, 171, 140, 0}},\n{(unsigned char*)\"supsim\", {226, 171, 136, 0}},\n{(unsigned char*)\"supsub\", {226, 171, 148, 0}},\n{(unsigned char*)\"supsup\", {226, 171, 150, 0}},\n{(unsigned char*)\"swArr\", {226, 135, 153, 0}},\n{(unsigned char*)\"swarhk\", {226, 164, 166, 0}},\n{(unsigned char*)\"swarr\", {226, 134, 153, 0}},\n{(unsigned char*)\"swarrow\", {226, 134, 153, 0}},\n{(unsigned char*)\"swnwar\", {226, 164, 170, 0}},\n{(unsigned char*)\"szlig\", {195, 159, 0}},\n{(unsigned char*)\"target\", {226, 140, 150, 0}},\n{(unsigned char*)\"tau\", {207, 132, 0}},\n{(unsigned char*)\"tbrk\", {226, 142, 180, 0}},\n{(unsigned char*)\"tcaron\", {197, 165, 0}},\n{(unsigned char*)\"tcedil\", {197, 163, 0}},\n{(unsigned char*)\"tcy\", {209, 130, 0}},\n{(unsigned char*)\"tdot\", {226, 131, 155, 0}},\n{(unsigned char*)\"telrec\", {226, 140, 149, 0}},\n{(unsigned char*)\"tfr\", {240, 157, 148, 177, 0}},\n{(unsigned char*)\"there4\", {226, 136, 180, 0}},\n{(unsigned char*)\"therefore\", {226, 136, 180, 0}},\n{(unsigned char*)\"theta\", {206, 184, 0}},\n{(unsigned char*)\"thetasym\", {207, 145, 0}},\n{(unsigned char*)\"thetav\", {207, 145, 0}},\n{(unsigned char*)\"thickapprox\", {226, 137, 136, 0}},\n{(unsigned char*)\"thicksim\", {226, 136, 188, 0}},\n{(unsigned char*)\"thinsp\", {226, 128, 137, 0}},\n{(unsigned char*)\"thkap\", {226, 137, 136, 0}},\n{(unsigned char*)\"thksim\", {226, 136, 188, 0}},\n{(unsigned char*)\"thorn\", {195, 190, 0}},\n{(unsigned char*)\"tilde\", {203, 156, 0}},\n{(unsigned char*)\"times\", {195, 151, 0}},\n{(unsigned char*)\"timesb\", {226, 138, 160, 0}},\n{(unsigned char*)\"timesbar\", {226, 168, 177, 0}},\n{(unsigned char*)\"timesd\", {226, 168, 176, 0}},\n{(unsigned char*)\"tint\", {226, 136, 173, 0}},\n{(unsigned char*)\"toea\", {226, 164, 168, 0}},\n{(unsigned char*)\"top\", {226, 138, 164, 0}},\n{(unsigned char*)\"topbot\", {226, 140, 182, 0}},\n{(unsigned char*)\"topcir\", {226, 171, 177, 0}},\n{(unsigned char*)\"topf\", {240, 157, 149, 165, 0}},\n{(unsigned char*)\"topfork\", {226, 171, 154, 0}},\n{(unsigned char*)\"tosa\", {226, 164, 169, 0}},\n{(unsigned char*)\"tprime\", {226, 128, 180, 0}},\n{(unsigned char*)\"trade\", {226, 132, 162, 0}},\n{(unsigned char*)\"triangle\", {226, 150, 181, 0}},\n{(unsigned char*)\"triangledown\", {226, 150, 191, 0}},\n{(unsigned char*)\"triangleleft\", {226, 151, 131, 0}},\n{(unsigned char*)\"trianglelefteq\", {226, 138, 180, 0}},\n{(unsigned char*)\"triangleq\", {226, 137, 156, 0}},\n{(unsigned char*)\"triangleright\", {226, 150, 185, 0}},\n{(unsigned char*)\"trianglerighteq\", {226, 138, 181, 0}},\n{(unsigned char*)\"tridot\", {226, 151, 172, 0}},\n{(unsigned char*)\"trie\", {226, 137, 156, 0}},\n{(unsigned char*)\"triminus\", {226, 168, 186, 0}},\n{(unsigned char*)\"triplus\", {226, 168, 185, 0}},\n{(unsigned char*)\"trisb\", {226, 167, 141, 0}},\n{(unsigned char*)\"tritime\", {226, 168, 187, 0}},\n{(unsigned char*)\"trpezium\", {226, 143, 162, 0}},\n{(unsigned char*)\"tscr\", {240, 157, 147, 137, 0}},\n{(unsigned char*)\"tscy\", {209, 134, 0}},\n{(unsigned char*)\"tshcy\", {209, 155, 0}},\n{(unsigned char*)\"tstrok\", {197, 167, 0}},\n{(unsigned char*)\"twixt\", {226, 137, 172, 0}},\n{(unsigned char*)\"twoheadleftarrow\", {226, 134, 158, 0}},\n{(unsigned char*)\"twoheadrightarrow\", {226, 134, 160, 0}},\n{(unsigned char*)\"uArr\", {226, 135, 145, 0}},\n{(unsigned char*)\"uHar\", {226, 165, 163, 0}},\n{(unsigned char*)\"uacute\", {195, 186, 0}},\n{(unsigned char*)\"uarr\", {226, 134, 145, 0}},\n{(unsigned char*)\"ubrcy\", {209, 158, 0}},\n{(unsigned char*)\"ubreve\", {197, 173, 0}},\n{(unsigned char*)\"ucirc\", {195, 187, 0}},\n{(unsigned char*)\"ucy\", {209, 131, 0}},\n{(unsigned char*)\"udarr\", {226, 135, 133, 0}},\n{(unsigned char*)\"udblac\", {197, 177, 0}},\n{(unsigned char*)\"udhar\", {226, 165, 174, 0}},\n{(unsigned char*)\"ufisht\", {226, 165, 190, 0}},\n{(unsigned char*)\"ufr\", {240, 157, 148, 178, 0}},\n{(unsigned char*)\"ugrave\", {195, 185, 0}},\n{(unsigned char*)\"uharl\", {226, 134, 191, 0}},\n{(unsigned char*)\"uharr\", {226, 134, 190, 0}},\n{(unsigned char*)\"uhblk\", {226, 150, 128, 0}},\n{(unsigned char*)\"ulcorn\", {226, 140, 156, 0}},\n{(unsigned char*)\"ulcorner\", {226, 140, 156, 0}},\n{(unsigned char*)\"ulcrop\", {226, 140, 143, 0}},\n{(unsigned char*)\"ultri\", {226, 151, 184, 0}},\n{(unsigned char*)\"umacr\", {197, 171, 0}},\n{(unsigned char*)\"uml\", {194, 168, 0}},\n{(unsigned char*)\"uogon\", {197, 179, 0}},\n{(unsigned char*)\"uopf\", {240, 157, 149, 166, 0}},\n{(unsigned char*)\"uparrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"updownarrow\", {226, 134, 149, 0}},\n{(unsigned char*)\"upharpoonleft\", {226, 134, 191, 0}},\n{(unsigned char*)\"upharpoonright\", {226, 134, 190, 0}},\n{(unsigned char*)\"uplus\", {226, 138, 142, 0}},\n{(unsigned char*)\"upsi\", {207, 133, 0}},\n{(unsigned char*)\"upsih\", {207, 146, 0}},\n{(unsigned char*)\"upsilon\", {207, 133, 0}},\n{(unsigned char*)\"upuparrows\", {226, 135, 136, 0}},\n{(unsigned char*)\"urcorn\", {226, 140, 157, 0}},\n{(unsigned char*)\"urcorner\", {226, 140, 157, 0}},\n{(unsigned char*)\"urcrop\", {226, 140, 142, 0}},\n{(unsigned char*)\"uring\", {197, 175, 0}},\n{(unsigned char*)\"urtri\", {226, 151, 185, 0}},\n{(unsigned char*)\"uscr\", {240, 157, 147, 138, 0}},\n{(unsigned char*)\"utdot\", {226, 139, 176, 0}},\n{(unsigned char*)\"utilde\", {197, 169, 0}},\n{(unsigned char*)\"utri\", {226, 150, 181, 0}},\n{(unsigned char*)\"utrif\", {226, 150, 180, 0}},\n{(unsigned char*)\"uuarr\", {226, 135, 136, 0}},\n{(unsigned char*)\"uuml\", {195, 188, 0}},\n{(unsigned char*)\"uwangle\", {226, 166, 167, 0}},\n{(unsigned char*)\"vArr\", {226, 135, 149, 0}},\n{(unsigned char*)\"vBar\", {226, 171, 168, 0}},\n{(unsigned char*)\"vBarv\", {226, 171, 169, 0}},\n{(unsigned char*)\"vDash\", {226, 138, 168, 0}},\n{(unsigned char*)\"vangrt\", {226, 166, 156, 0}},\n{(unsigned char*)\"varepsilon\", {207, 181, 0}},\n{(unsigned char*)\"varkappa\", {207, 176, 0}},\n{(unsigned char*)\"varnothing\", {226, 136, 133, 0}},\n{(unsigned char*)\"varphi\", {207, 149, 0}},\n{(unsigned char*)\"varpi\", {207, 150, 0}},\n{(unsigned char*)\"varpropto\", {226, 136, 157, 0}},\n{(unsigned char*)\"varr\", {226, 134, 149, 0}},\n{(unsigned char*)\"varrho\", {207, 177, 0}},\n{(unsigned char*)\"varsigma\", {207, 130, 0}},\n{(unsigned char*)\"varsubsetneq\", {226, 138, 138, 239, 184, 128, 0}},\n{(unsigned char*)\"varsubsetneqq\", {226, 171, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"varsupsetneq\", {226, 138, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"varsupsetneqq\", {226, 171, 140, 239, 184, 128, 0}},\n{(unsigned char*)\"vartheta\", {207, 145, 0}},\n{(unsigned char*)\"vartriangleleft\", {226, 138, 178, 0}},\n{(unsigned char*)\"vartriangleright\", {226, 138, 179, 0}},\n{(unsigned char*)\"vcy\", {208, 178, 0}},\n{(unsigned char*)\"vdash\", {226, 138, 162, 0}},\n{(unsigned char*)\"vee\", {226, 136, 168, 0}},\n{(unsigned char*)\"veebar\", {226, 138, 187, 0}},\n{(unsigned char*)\"veeeq\", {226, 137, 154, 0}},\n{(unsigned char*)\"vellip\", {226, 139, 174, 0}},\n{(unsigned char*)\"verbar\", {124, 0}},\n{(unsigned char*)\"vert\", {124, 0}},\n{(unsigned char*)\"vfr\", {240, 157, 148, 179, 0}},\n{(unsigned char*)\"vltri\", {226, 138, 178, 0}},\n{(unsigned char*)\"vnsub\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"vnsup\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"vopf\", {240, 157, 149, 167, 0}},\n{(unsigned char*)\"vprop\", {226, 136, 157, 0}},\n{(unsigned char*)\"vrtri\", {226, 138, 179, 0}},\n{(unsigned char*)\"vscr\", {240, 157, 147, 139, 0}},\n{(unsigned char*)\"vsubnE\", {226, 171, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"vsubne\", {226, 138, 138, 239, 184, 128, 0}},\n{(unsigned char*)\"vsupnE\", {226, 171, 140, 239, 184, 128, 0}},\n{(unsigned char*)\"vsupne\", {226, 138, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"vzigzag\", {226, 166, 154, 0}},\n{(unsigned char*)\"wcirc\", {197, 181, 0}},\n{(unsigned char*)\"wedbar\", {226, 169, 159, 0}},\n{(unsigned char*)\"wedge\", {226, 136, 167, 0}},\n{(unsigned char*)\"wedgeq\", {226, 137, 153, 0}},\n{(unsigned char*)\"weierp\", {226, 132, 152, 0}},\n{(unsigned char*)\"wfr\", {240, 157, 148, 180, 0}},\n{(unsigned char*)\"wopf\", {240, 157, 149, 168, 0}},\n{(unsigned char*)\"wp\", {226, 132, 152, 0}},\n{(unsigned char*)\"wr\", {226, 137, 128, 0}},\n{(unsigned char*)\"wreath\", {226, 137, 128, 0}},\n{(unsigned char*)\"wscr\", {240, 157, 147, 140, 0}},\n{(unsigned char*)\"xcap\", {226, 139, 130, 0}},\n{(unsigned char*)\"xcirc\", {226, 151, 175, 0}},\n{(unsigned char*)\"xcup\", {226, 139, 131, 0}},\n{(unsigned char*)\"xdtri\", {226, 150, 189, 0}},\n{(unsigned char*)\"xfr\", {240, 157, 148, 181, 0}},\n{(unsigned char*)\"xhArr\", {226, 159, 186, 0}},\n{(unsigned char*)\"xharr\", {226, 159, 183, 0}},\n{(unsigned char*)\"xi\", {206, 190, 0}},\n{(unsigned char*)\"xlArr\", {226, 159, 184, 0}},\n{(unsigned char*)\"xlarr\", {226, 159, 181, 0}},\n{(unsigned char*)\"xmap\", {226, 159, 188, 0}},\n{(unsigned char*)\"xnis\", {226, 139, 187, 0}},\n{(unsigned char*)\"xodot\", {226, 168, 128, 0}},\n{(unsigned char*)\"xopf\", {240, 157, 149, 169, 0}},\n{(unsigned char*)\"xoplus\", {226, 168, 129, 0}},\n{(unsigned char*)\"xotime\", {226, 168, 130, 0}},\n{(unsigned char*)\"xrArr\", {226, 159, 185, 0}},\n{(unsigned char*)\"xrarr\", {226, 159, 182, 0}},\n{(unsigned char*)\"xscr\", {240, 157, 147, 141, 0}},\n{(unsigned char*)\"xsqcup\", {226, 168, 134, 0}},\n{(unsigned char*)\"xuplus\", {226, 168, 132, 0}},\n{(unsigned char*)\"xutri\", {226, 150, 179, 0}},\n{(unsigned char*)\"xvee\", {226, 139, 129, 0}},\n{(unsigned char*)\"xwedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"yacute\", {195, 189, 0}},\n{(unsigned char*)\"yacy\", {209, 143, 0}},\n{(unsigned char*)\"ycirc\", {197, 183, 0}},\n{(unsigned char*)\"ycy\", {209, 139, 0}},\n{(unsigned char*)\"yen\", {194, 165, 0}},\n{(unsigned char*)\"yfr\", {240, 157, 148, 182, 0}},\n{(unsigned char*)\"yicy\", {209, 151, 0}},\n{(unsigned char*)\"yopf\", {240, 157, 149, 170, 0}},\n{(unsigned char*)\"yscr\", {240, 157, 147, 142, 0}},\n{(unsigned char*)\"yucy\", {209, 142, 0}},\n{(unsigned char*)\"yuml\", {195, 191, 0}},\n{(unsigned char*)\"zacute\", {197, 186, 0}},\n{(unsigned char*)\"zcaron\", {197, 190, 0}},\n{(unsigned char*)\"zcy\", {208, 183, 0}},\n{(unsigned char*)\"zdot\", {197, 188, 0}},\n{(unsigned char*)\"zeetrf\", {226, 132, 168, 0}},\n{(unsigned char*)\"zeta\", {206, 182, 0}},\n{(unsigned char*)\"zfr\", {240, 157, 148, 183, 0}},\n{(unsigned char*)\"zhcy\", {208, 182, 0}},\n{(unsigned char*)\"zigrarr\", {226, 135, 157, 0}},\n{(unsigned char*)\"zopf\", {240, 157, 149, 171, 0}},\n{(unsigned char*)\"zscr\", {240, 157, 147, 143, 0}},\n{(unsigned char*)\"zwj\", {226, 128, 141, 0}},\n{(unsigned char*)\"zwnj\", {226, 128, 140, 0}},\n};\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/footnotes.c",
    "content": "#include \"cmark-gfm.h\"\n#include \"parser.h\"\n#include \"footnotes.h\"\n#include \"inlines.h\"\n#include \"chunk.h\"\n\nstatic void footnote_free(cmark_map *map, cmark_map_entry *_ref) {\n  cmark_footnote *ref = (cmark_footnote *)_ref;\n  cmark_mem *mem = map->mem;\n  if (ref != NULL) {\n    mem->free(ref->entry.label);\n    if (ref->node)\n      cmark_node_free(ref->node);\n    mem->free(ref);\n  }\n}\n\nvoid cmark_footnote_create(cmark_map *map, cmark_node *node) {\n  cmark_footnote *ref;\n  unsigned char *reflabel = normalize_map_label(map->mem, &node->as.literal);\n\n  /* empty footnote name, or composed from only whitespace */\n  if (reflabel == NULL)\n    return;\n\n  assert(map->sorted == NULL);\n\n  ref = (cmark_footnote *)map->mem->calloc(1, sizeof(*ref));\n  ref->entry.label = reflabel;\n  ref->node = node;\n  ref->entry.age = map->size;\n  ref->entry.next = map->refs;\n\n  map->refs = (cmark_map_entry *)ref;\n  map->size++;\n}\n\ncmark_map *cmark_footnote_map_new(cmark_mem *mem) {\n  return cmark_map_new(mem, footnote_free);\n}\n\n// Before calling `cmark_map_free` on a map with `cmark_footnotes`, first\n// unlink all of the footnote nodes before freeing their memory.\n//\n// Sometimes, two (unused) footnote nodes can end up referencing each other,\n// which as they get freed up by calling `cmark_map_free` -> `footnote_free` ->\n// etc, can lead to a use-after-free error.\n//\n// Better to `unlink` every footnote node first, setting their next, prev, and\n// parent pointers to NULL, and only then walk thru & free them up.\nvoid cmark_unlink_footnotes_map(cmark_map *map) {\n  cmark_map_entry *ref;\n  cmark_map_entry *next;\n\n  ref = map->refs;\n  while(ref) {\n    next = ref->next;\n    if (((cmark_footnote *)ref)->node) {\n      cmark_node_unlink(((cmark_footnote *)ref)->node);\n    }\n    ref = next;\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/footnotes.h",
    "content": "#ifndef CMARK_FOOTNOTES_H\n#define CMARK_FOOTNOTES_H\n\n#include \"map.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_footnote {\n  cmark_map_entry entry;\n  cmark_node *node;\n  unsigned int ix;\n};\n\ntypedef struct cmark_footnote cmark_footnote;\n\nvoid cmark_footnote_create(cmark_map *map, cmark_node *node);\ncmark_map *cmark_footnote_map_new(cmark_mem *mem);\n\nvoid cmark_unlink_footnotes_map(cmark_map *map);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/houdini.h",
    "content": "#ifndef CMARK_HOUDINI_H\n#define CMARK_HOUDINI_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include \"config.h\"\n#include \"buffer.h\"\n\n#ifdef HAVE___BUILTIN_EXPECT\n#define likely(x) __builtin_expect((x), 1)\n#define unlikely(x) __builtin_expect((x), 0)\n#else\n#define likely(x) (x)\n#define unlikely(x) (x)\n#endif\n\n#ifdef HOUDINI_USE_LOCALE\n#define _isxdigit(c) isxdigit(c)\n#define _isdigit(c) isdigit(c)\n#else\n/*\n * Helper _isdigit methods -- do not trust the current locale\n * */\n#define _isxdigit(c) (strchr(\"0123456789ABCDEFabcdef\", (c)) != NULL)\n#define _isdigit(c) ((c) >= '0' && (c) <= '9')\n#endif\n\n#define HOUDINI_ESCAPED_SIZE(x) (((x)*12) / 10)\n#define HOUDINI_UNESCAPED_SIZE(x) (x)\n\nCMARK_GFM_EXPORT\nbufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,\n                                      bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,\n                                bufsize_t size, int secure);\nCMARK_GFM_EXPORT\nint houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,\n                                 bufsize_t size);\nCMARK_GFM_EXPORT\nvoid houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,\n                                    bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/houdini_href_e.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"houdini.h\"\n\n/*\n * The following characters will not be escaped:\n *\n *\t\t-_.+!*'(),%#@?=;:/,+&$~ alphanum\n *\n * Note that this character set is the addition of:\n *\n *\t- The characters which are safe to be in an URL\n *\t- The characters which are *not* safe to be in\n *\tan URL because they are RESERVED characters.\n *\n * We assume (lazily) that any RESERVED char that\n * appears inside an URL is actually meant to\n * have its native function (i.e. as an URL\n * component/separator) and hence needs no escaping.\n *\n * There are two exceptions: the chacters & (amp)\n * and ' (single quote) do not appear in the table.\n * They are meant to appear in the URL as components,\n * yet they require special HTML-entity escaping\n * to generate valid HTML markup.\n *\n * All other characters will be escaped to %XX.\n *\n */\nstatic const char HREF_SAFE[] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,\n    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nint houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {\n  static const uint8_t hex_chars[] = \"0123456789ABCDEF\";\n  bufsize_t i = 0, org;\n  uint8_t hex_str[3];\n\n  hex_str[0] = '%';\n\n  while (i < size) {\n    org = i;\n    while (i < size && HREF_SAFE[src[i]] != 0)\n      i++;\n\n    if (likely(i > org))\n      cmark_strbuf_put(ob, src + org, i - org);\n\n    /* escaping */\n    if (i >= size)\n      break;\n\n    switch (src[i]) {\n    /* amp appears all the time in URLs, but needs\n     * HTML-entity escaping to be inside an href */\n    case '&':\n      cmark_strbuf_puts(ob, \"&amp;\");\n      break;\n\n    /* the single quote is a valid URL character\n     * according to the standard; it needs HTML\n     * entity escaping too */\n    case '\\'':\n      cmark_strbuf_puts(ob, \"&#x27;\");\n      break;\n\n/* the space can be escaped to %20 or a plus\n * sign. we're going with the generic escape\n * for now. the plus thing is more commonly seen\n * when building GET strings */\n#if 0\n\t\tcase ' ':\n\t\t\tcmark_strbuf_putc(ob, '+');\n\t\t\tbreak;\n#endif\n\n    /* every other character goes with a %XX escaping */\n    default:\n      hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];\n      hex_str[2] = hex_chars[src[i] & 0xF];\n      cmark_strbuf_put(ob, hex_str, 3);\n    }\n\n    i++;\n  }\n\n  return 1;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/houdini_html_e.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"houdini.h\"\n\n/**\n * According to the OWASP rules:\n *\n * & --> &amp;\n * < --> &lt;\n * > --> &gt;\n * \" --> &quot;\n * ' --> &#x27;     &apos; is not recommended\n * / --> &#x2F;     forward slash is included as it helps end an HTML entity\n *\n */\nstatic const char HTML_ESCAPE_TABLE[] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nstatic const char *HTML_ESCAPES[] = {\"\",      \"&quot;\", \"&amp;\", \"&#39;\",\n                                     \"&#47;\", \"&lt;\",   \"&gt;\"};\n\nint houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,\n                         int secure) {\n  bufsize_t i = 0, org, esc = 0;\n\n  while (i < size) {\n    org = i;\n    while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)\n      i++;\n\n    if (i > org)\n      cmark_strbuf_put(ob, src + org, i - org);\n\n    /* escaping */\n    if (unlikely(i >= size))\n      break;\n\n    /* The forward slash and single quote are only escaped in secure mode */\n    if ((src[i] == '/' || src[i] == '\\'') && !secure) {\n      cmark_strbuf_putc(ob, src[i]);\n    } else {\n      cmark_strbuf_puts(ob, HTML_ESCAPES[esc]);\n    }\n\n    i++;\n  }\n\n  return 1;\n}\n\nint houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {\n  return houdini_escape_html0(ob, src, size, 1);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/houdini_html_u.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"buffer.h\"\n#include \"houdini.h\"\n#include \"utf8.h\"\n#include \"entities.inc\"\n\n/* Binary tree lookup code for entities added by JGM */\n\nstatic const unsigned char *S_lookup(int i, int low, int hi,\n                                     const unsigned char *s, int len) {\n  int j;\n  int cmp =\n      strncmp((const char *)s, (const char *)cmark_entities[i].entity, len);\n  if (cmp == 0 && cmark_entities[i].entity[len] == 0) {\n    return (const unsigned char *)cmark_entities[i].bytes;\n  } else if (cmp <= 0 && i > low) {\n    j = i - ((i - low) / 2);\n    if (j == i)\n      j -= 1;\n    return S_lookup(j, low, i - 1, s, len);\n  } else if (cmp > 0 && i < hi) {\n    j = i + ((hi - i) / 2);\n    if (j == i)\n      j += 1;\n    return S_lookup(j, i + 1, hi, s, len);\n  } else {\n    return NULL;\n  }\n}\n\nstatic const unsigned char *S_lookup_entity(const unsigned char *s, int len) {\n  return S_lookup(CMARK_NUM_ENTITIES / 2, 0, CMARK_NUM_ENTITIES - 1, s, len);\n}\n\nbufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size) {\n  bufsize_t i = 0;\n\n  if (size >= 3 && src[0] == '#') {\n    int codepoint = 0;\n    int num_digits = 0;\n\n    if (_isdigit(src[1])) {\n      for (i = 1; i < size && _isdigit(src[i]); ++i) {\n        codepoint = (codepoint * 10) + (src[i] - '0');\n\n        if (codepoint >= 0x110000) {\n          // Keep counting digits but\n          // avoid integer overflow.\n          codepoint = 0x110000;\n        }\n      }\n\n      num_digits = i - 1;\n    }\n\n    else if (src[1] == 'x' || src[1] == 'X') {\n      for (i = 2; i < size && _isxdigit(src[i]); ++i) {\n        codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9);\n\n        if (codepoint >= 0x110000) {\n          // Keep counting digits but\n          // avoid integer overflow.\n          codepoint = 0x110000;\n        }\n      }\n\n      num_digits = i - 2;\n    }\n\n    if (num_digits >= 1 && num_digits <= 8 && i < size && src[i] == ';') {\n      if (codepoint == 0 || (codepoint >= 0xD800 && codepoint < 0xE000) ||\n          codepoint >= 0x110000) {\n        codepoint = 0xFFFD;\n      }\n      cmark_utf8proc_encode_char(codepoint, ob);\n      return i + 1;\n    }\n  }\n\n  else {\n    if (size > CMARK_ENTITY_MAX_LENGTH)\n      size = CMARK_ENTITY_MAX_LENGTH;\n\n    for (i = CMARK_ENTITY_MIN_LENGTH; i < size; ++i) {\n      if (src[i] == ' ')\n        break;\n\n      if (src[i] == ';') {\n        const unsigned char *entity = S_lookup_entity(src, i);\n\n        if (entity != NULL) {\n          cmark_strbuf_puts(ob, (const char *)entity);\n          return i + 1;\n        }\n\n        break;\n      }\n    }\n  }\n\n  return 0;\n}\n\nint houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,\n                          bufsize_t size) {\n  bufsize_t i = 0, org, ent;\n\n  while (i < size) {\n    org = i;\n    while (i < size && src[i] != '&')\n      i++;\n\n    if (likely(i > org)) {\n      if (unlikely(org == 0)) {\n        if (i >= size)\n          return 0;\n\n        cmark_strbuf_grow(ob, HOUDINI_UNESCAPED_SIZE(size));\n      }\n\n      cmark_strbuf_put(ob, src + org, i - org);\n    }\n\n    /* escaping */\n    if (i >= size)\n      break;\n\n    i++;\n\n    ent = houdini_unescape_ent(ob, src + i, size - i);\n    i += ent;\n\n    /* not really an entity */\n    if (ent == 0)\n      cmark_strbuf_putc(ob, '&');\n  }\n\n  return 1;\n}\n\nvoid houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,\n                             bufsize_t size) {\n  if (!houdini_unescape_html(ob, src, size))\n    cmark_strbuf_put(ob, src, size);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/html.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n#include \"cmark_ctype.h\"\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"houdini.h\"\n#include \"scanners.h\"\n#include \"syntax_extension.h\"\n#include \"html.h\"\n#include \"render.h\"\n\n// Functions to convert cmark_nodes to HTML strings.\n\nstatic void escape_html(cmark_strbuf *dest, const unsigned char *source,\n                        bufsize_t length) {\n  houdini_escape_html0(dest, source, length, 0);\n}\n\nstatic void filter_html_block(cmark_html_renderer *renderer, uint8_t *data, size_t len) {\n  cmark_strbuf *html = renderer->html;\n  cmark_llist *it;\n  cmark_syntax_extension *ext;\n  bool filtered;\n  uint8_t *match;\n\n  while (len) {\n    match = (uint8_t *) memchr(data, '<', len);\n    if (!match)\n      break;\n\n    if (match != data) {\n      cmark_strbuf_put(html, data, (bufsize_t)(match - data));\n      len -= (match - data);\n      data = match;\n    }\n\n    filtered = false;\n    for (it = renderer->filter_extensions; it; it = it->next) {\n      ext = ((cmark_syntax_extension *) it->data);\n      if (!ext->html_filter_func(ext, data, len)) {\n        filtered = true;\n        break;\n      }\n    }\n\n    if (!filtered) {\n      cmark_strbuf_putc(html, '<');\n    } else {\n      cmark_strbuf_puts(html, \"&lt;\");\n    }\n\n    ++data;\n    --len;\n  }\n\n  if (len)\n    cmark_strbuf_put(html, data, (bufsize_t)len);\n}\n\nstatic bool S_put_footnote_backref(cmark_html_renderer *renderer, cmark_strbuf *html, cmark_node *node) {\n  if (renderer->written_footnote_ix >= renderer->footnote_ix)\n    return false;\n  renderer->written_footnote_ix = renderer->footnote_ix;\n  char m[32];\n  snprintf(m, sizeof(m), \"%d\", renderer->written_footnote_ix);\n\n  cmark_strbuf_puts(html, \"<a href=\\\"#fnref-\");\n  houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n  cmark_strbuf_puts(html, \"\\\" class=\\\"footnote-backref\\\" data-footnote-backref data-footnote-backref-idx=\\\"\");\n  cmark_strbuf_puts(html, m);\n  cmark_strbuf_puts(html, \"\\\" aria-label=\\\"Back to reference \");\n  cmark_strbuf_puts(html, m);\n  cmark_strbuf_puts(html, \"\\\">↩</a>\");\n\n  if (node->footnote.def_count > 1)\n  {\n    for(int i = 2; i <= node->footnote.def_count; i++) {\n      char n[32];\n      snprintf(n, sizeof(n), \"%d\", i);\n\n      cmark_strbuf_puts(html, \" <a href=\\\"#fnref-\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\" class=\\\"footnote-backref\\\" data-footnote-backref data-footnote-backref-idx=\\\"\");\n      cmark_strbuf_puts(html, m);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\" aria-label=\\\"Back to reference \");\n      cmark_strbuf_puts(html, m);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\">↩<sup class=\\\"footnote-ref\\\">\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"</sup></a>\");\n    }\n  }\n\n  return true;\n}\n\nstatic int S_render_node(cmark_html_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  cmark_node *parent;\n  cmark_node *grandparent;\n  cmark_strbuf *html = renderer->html;\n  cmark_llist *it;\n  cmark_syntax_extension *ext;\n  char start_heading[] = \"<h0\";\n  char end_heading[] = \"</h0\";\n  bool tight;\n  bool filtered;\n  char buffer[BUFFER_SIZE];\n\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (renderer->plain == node) { // back at original node\n    renderer->plain = NULL;\n  }\n\n  if (renderer->plain != NULL) {\n    switch (node->type) {\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_INLINE:\n      escape_html(html, node->as.literal.data, node->as.literal.len);\n      break;\n\n    case CMARK_NODE_LINEBREAK:\n    case CMARK_NODE_SOFTBREAK:\n      cmark_strbuf_putc(html, ' ');\n      break;\n\n    default:\n      break;\n    }\n    return 1;\n  }\n\n  if (node->extension && node->extension->html_render_func) {\n    node->extension->html_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<blockquote\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_puts(html, \">\\n\");\n    } else {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</blockquote>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_LIST: {\n    cmark_list_type list_type = node->as.list.list_type;\n    int start = node->as.list.start;\n\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (list_type == CMARK_BULLET_LIST) {\n        cmark_strbuf_puts(html, \"<ul\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      } else if (start == 1) {\n        cmark_strbuf_puts(html, \"<ol\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      } else {\n        snprintf(buffer, BUFFER_SIZE, \"<ol start=\\\"%d\\\"\", start);\n        cmark_strbuf_puts(html, buffer);\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      }\n    } else {\n      cmark_strbuf_puts(html,\n                        list_type == CMARK_BULLET_LIST ? \"</ul>\\n\" : \"</ol>\\n\");\n    }\n    break;\n  }\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<li\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      cmark_strbuf_puts(html, \"</li>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      cmark_html_render_cr(html);\n      start_heading[2] = (char)('0' + node->as.heading.level);\n      cmark_strbuf_puts(html, start_heading);\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      end_heading[3] = (char)('0' + node->as.heading.level);\n      cmark_strbuf_puts(html, end_heading);\n      cmark_strbuf_puts(html, \">\\n\");\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    cmark_html_render_cr(html);\n\n    if (node->as.code.info.len == 0) {\n      cmark_strbuf_puts(html, \"<pre\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_puts(html, \"><code>\");\n    } else {\n      bufsize_t first_tag = 0;\n      while (first_tag < node->as.code.info.len &&\n             !cmark_isspace(node->as.code.info.data[first_tag])) {\n        first_tag += 1;\n      }\n\n      if (options & CMARK_OPT_GITHUB_PRE_LANG) {\n        cmark_strbuf_puts(html, \"<pre\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \" lang=\\\"\");\n        escape_html(html, node->as.code.info.data, first_tag);\n        if (first_tag < node->as.code.info.len && (options & CMARK_OPT_FULL_INFO_STRING)) {\n          cmark_strbuf_puts(html, \"\\\" data-meta=\\\"\");\n          escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);\n        }\n        cmark_strbuf_puts(html, \"\\\"><code>\");\n      } else {\n        cmark_strbuf_puts(html, \"<pre\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \"><code class=\\\"language-\");\n        escape_html(html, node->as.code.info.data, first_tag);\n        if (first_tag < node->as.code.info.len && (options & CMARK_OPT_FULL_INFO_STRING)) {\n          cmark_strbuf_puts(html, \"\\\" data-meta=\\\"\");\n          escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);\n        }\n        cmark_strbuf_puts(html, \"\\\">\");\n      }\n    }\n\n    escape_html(html, node->as.code.literal.data, node->as.code.literal.len);\n    cmark_strbuf_puts(html, \"</code></pre>\\n\");\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    cmark_html_render_cr(html);\n    if (!(options & CMARK_OPT_UNSAFE)) {\n      cmark_strbuf_puts(html, \"<!-- raw HTML omitted -->\");\n    } else if (renderer->filter_extensions) {\n      filter_html_block(renderer, node->as.literal.data, node->as.literal.len);\n    } else {\n      cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);\n    }\n    cmark_html_render_cr(html);\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_html_render_cr(html);\n    if (entering) {\n      cmark_strbuf_put(html, node->as.custom.on_enter.data,\n                       node->as.custom.on_enter.len);\n    } else {\n      cmark_strbuf_put(html, node->as.custom.on_exit.data,\n                       node->as.custom.on_exit.len);\n    }\n    cmark_html_render_cr(html);\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    cmark_html_render_cr(html);\n    cmark_strbuf_puts(html, \"<hr\");\n    cmark_html_render_sourcepos(node, html, options);\n    cmark_strbuf_puts(html, \" />\\n\");\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    parent = cmark_node_parent(node);\n    grandparent = cmark_node_parent(parent);\n    if (grandparent != NULL && grandparent->type == CMARK_NODE_LIST) {\n      tight = grandparent->as.list.tight;\n    } else {\n      tight = false;\n    }\n    if (!tight) {\n      if (entering) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"<p\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_putc(html, '>');\n      } else {\n        if (parent->type == CMARK_NODE_FOOTNOTE_DEFINITION && node->next == NULL) {\n          cmark_strbuf_putc(html, ' ');\n          S_put_footnote_backref(renderer, html, parent);\n        }\n        cmark_strbuf_puts(html, \"</p>\\n\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    escape_html(html, node->as.literal.data, node->as.literal.len);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    cmark_strbuf_puts(html, \"<br />\\n\");\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      cmark_strbuf_puts(html, \"<br />\\n\");\n    } else if (options & CMARK_OPT_NOBREAKS) {\n      cmark_strbuf_putc(html, ' ');\n    } else {\n      cmark_strbuf_putc(html, '\\n');\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    cmark_strbuf_puts(html, \"<code>\");\n    escape_html(html, node->as.literal.data, node->as.literal.len);\n    cmark_strbuf_puts(html, \"</code>\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    if (!(options & CMARK_OPT_UNSAFE)) {\n      cmark_strbuf_puts(html, \"<!-- raw HTML omitted -->\");\n    } else {\n      filtered = false;\n      for (it = renderer->filter_extensions; it; it = it->next) {\n        ext = (cmark_syntax_extension *) it->data;\n        if (!ext->html_filter_func(ext, node->as.literal.data, node->as.literal.len)) {\n          filtered = true;\n          break;\n        }\n      }\n      if (!filtered) {\n        cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);\n      } else {\n        cmark_strbuf_puts(html, \"&lt;\");\n        cmark_strbuf_put(html, node->as.literal.data + 1, node->as.literal.len - 1);\n      }\n    }\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    if (entering) {\n      cmark_strbuf_put(html, node->as.custom.on_enter.data,\n                       node->as.custom.on_enter.len);\n    } else {\n      cmark_strbuf_put(html, node->as.custom.on_exit.data,\n                       node->as.custom.on_exit.len);\n    }\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        cmark_strbuf_puts(html, \"<strong>\");\n      } else {\n        cmark_strbuf_puts(html, \"</strong>\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<em>\");\n    } else {\n      cmark_strbuf_puts(html, \"</em>\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<a href=\\\"\");\n      if ((options & CMARK_OPT_UNSAFE) ||\n            !(scan_dangerous_url(&node->as.link.url, 0))) {\n        houdini_escape_href(html, node->as.link.url.data,\n                            node->as.link.url.len);\n      }\n      if (node->as.link.title.len) {\n        cmark_strbuf_puts(html, \"\\\" title=\\\"\");\n        escape_html(html, node->as.link.title.data, node->as.link.title.len);\n      }\n      cmark_strbuf_puts(html, \"\\\">\");\n    } else {\n      cmark_strbuf_puts(html, \"</a>\");\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<img src=\\\"\");\n      if ((options & CMARK_OPT_UNSAFE) ||\n            !(scan_dangerous_url(&node->as.link.url, 0))) {\n        houdini_escape_href(html, node->as.link.url.data,\n                            node->as.link.url.len);\n      }\n      cmark_strbuf_puts(html, \"\\\" alt=\\\"\");\n      renderer->plain = node;\n    } else {\n      if (node->as.link.title.len) {\n        cmark_strbuf_puts(html, \"\\\" title=\\\"\");\n        escape_html(html, node->as.link.title.data, node->as.link.title.len);\n      }\n\n      cmark_strbuf_puts(html, \"\\\" />\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      if (renderer->footnote_ix == 0) {\n        cmark_strbuf_puts(html, \"<section class=\\\"footnotes\\\" data-footnotes>\\n<ol>\\n\");\n      }\n      ++renderer->footnote_ix;\n\n      cmark_strbuf_puts(html, \"<li id=\\\"fn-\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"\\\">\\n\");\n    } else {\n      if (S_put_footnote_backref(renderer, html, node)) {\n        cmark_strbuf_putc(html, '\\n');\n      }\n      cmark_strbuf_puts(html, \"</li>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<sup class=\\\"footnote-ref\\\"><a href=\\\"#fn-\");\n      houdini_escape_href(html, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n      cmark_strbuf_puts(html, \"\\\" id=\\\"fnref-\");\n      houdini_escape_href(html, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n\n      if (node->footnote.ref_ix > 1) {\n        char n[32];\n        snprintf(n, sizeof(n), \"%d\", node->footnote.ref_ix);\n        cmark_strbuf_puts(html, \"-\");\n        cmark_strbuf_puts(html, n);\n      }\n\n      cmark_strbuf_puts(html, \"\\\" data-footnote-ref>\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"</a></sup>\");\n    }\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions) {\n  return cmark_render_html_with_mem(root, options, extensions, cmark_node_mem(root));\n}\n\nchar *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem) {\n  char *result;\n  cmark_strbuf html = CMARK_BUF_INIT(mem);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n  cmark_html_renderer renderer = {&html, NULL, NULL, 0, 0, NULL};\n  cmark_iter *iter = cmark_iter_new(root);\n\n  for (; extensions; extensions = extensions->next)\n    if (((cmark_syntax_extension *) extensions->data)->html_filter_func)\n      renderer.filter_extensions = cmark_llist_append(\n          mem,\n          renderer.filter_extensions,\n          (cmark_syntax_extension *) extensions->data);\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    S_render_node(&renderer, cur, ev_type, options);\n  }\n\n  if (renderer.footnote_ix) {\n    cmark_strbuf_puts(&html, \"</ol>\\n</section>\\n\");\n  }\n\n  result = (char *)cmark_strbuf_detach(&html);\n\n  cmark_llist_free(mem, renderer.filter_extensions);\n\n  cmark_iter_free(iter);\n  return result;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/html.h",
    "content": "#ifndef CMARK_HTML_H\n#define CMARK_HTML_H\n\n#include \"buffer.h\"\n#include \"node.h\"\n\nCMARK_INLINE\nstatic void cmark_html_render_cr(cmark_strbuf *html) {\n  if (html->size && html->ptr[html->size - 1] != '\\n')\n    cmark_strbuf_putc(html, '\\n');\n}\n\n#define BUFFER_SIZE 100\n\nCMARK_INLINE \nstatic void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) {\n  char buffer[BUFFER_SIZE];\n  if (CMARK_OPT_SOURCEPOS & options) {\n    snprintf(buffer, BUFFER_SIZE, \" data-sourcepos=\\\"%d:%d-%d:%d\\\"\",\n             cmark_node_get_start_line(node), cmark_node_get_start_column(node),\n             cmark_node_get_end_line(node), cmark_node_get_end_column(node));\n    cmark_strbuf_puts(html, buffer);\n  }\n}\n\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/inlines.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"cmark_ctype.h\"\n#include \"config.h\"\n#include \"node.h\"\n#include \"parser.h\"\n#include \"references.h\"\n#include \"cmark-gfm.h\"\n#include \"houdini.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"inlines.h\"\n#include \"syntax_extension.h\"\n\nstatic const char *EMDASH = \"\\xE2\\x80\\x94\";\nstatic const char *ENDASH = \"\\xE2\\x80\\x93\";\nstatic const char *ELLIPSES = \"\\xE2\\x80\\xA6\";\nstatic const char *LEFTDOUBLEQUOTE = \"\\xE2\\x80\\x9C\";\nstatic const char *RIGHTDOUBLEQUOTE = \"\\xE2\\x80\\x9D\";\nstatic const char *LEFTSINGLEQUOTE = \"\\xE2\\x80\\x98\";\nstatic const char *RIGHTSINGLEQUOTE = \"\\xE2\\x80\\x99\";\n\n// Macros for creating various kinds of simple.\n#define make_str(subj, sc, ec, s) make_literal(subj, CMARK_NODE_TEXT, sc, ec, s)\n#define make_code(subj, sc, ec, s) make_literal(subj, CMARK_NODE_CODE, sc, ec, s)\n#define make_raw_html(subj, sc, ec, s) make_literal(subj, CMARK_NODE_HTML_INLINE, sc, ec, s)\n#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)\n#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)\n#define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)\n#define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)\n\n#define MAXBACKTICKS 80\n\ntypedef struct bracket {\n  struct bracket *previous;\n  cmark_node *inl_text;\n  bufsize_t position;\n  bool image;\n  bool active;\n  bool bracket_after;\n  bool in_bracket_image0;\n  bool in_bracket_image1;\n} bracket;\n\n#define FLAG_SKIP_HTML_CDATA        (1u << 0)\n#define FLAG_SKIP_HTML_DECLARATION  (1u << 1)\n#define FLAG_SKIP_HTML_PI           (1u << 2)\n#define FLAG_SKIP_HTML_COMMENT      (1u << 3)\n\ntypedef struct subject{\n  cmark_mem *mem;\n  cmark_chunk input;\n  unsigned flags;\n  int line;\n  bufsize_t pos;\n  int block_offset;\n  int column_offset;\n  cmark_map *refmap;\n  delimiter *last_delim;\n  bracket *last_bracket;\n  bufsize_t backticks[MAXBACKTICKS + 1];\n  bool scanned_for_backticks;\n  bool no_link_openers;\n} subject;\n\n// Extensions may populate this.\nstatic int8_t SKIP_CHARS[256];\n\nstatic CMARK_INLINE bool S_is_line_end_char(char c) {\n  return (c == '\\n' || c == '\\r');\n}\n\nstatic delimiter *S_insert_emph(subject *subj, delimiter *opener,\n                                delimiter *closer);\n\nstatic int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options);\n\nstatic void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,\n                             cmark_chunk *buffer, cmark_map *refmap);\nstatic bufsize_t subject_find_special_char(subject *subj, int options);\n\n// Create an inline with a literal string value.\nstatic CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,\n                                             int start_column, int end_column,\n                                             cmark_chunk s) {\n  cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(subj->mem, &e->content, 0);\n  e->type = (uint16_t)t;\n  e->as.literal = s;\n  e->start_line = e->end_line = subj->line;\n  // columns are 1 based.\n  e->start_column = start_column + 1 + subj->column_offset + subj->block_offset;\n  e->end_column = end_column + 1 + subj->column_offset + subj->block_offset;\n  return e;\n}\n\n// Create an inline with no value.\nstatic CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {\n  cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(mem, &e->content, 0);\n  e->type = (uint16_t)t;\n  return e;\n}\n\n// Like make_str, but parses entities.\nstatic cmark_node *make_str_with_entities(subject *subj,\n                                          int start_column, int end_column,\n                                          cmark_chunk *content) {\n  cmark_strbuf unescaped = CMARK_BUF_INIT(subj->mem);\n\n  if (houdini_unescape_html(&unescaped, content->data, content->len)) {\n    return make_str(subj, start_column, end_column, cmark_chunk_buf_detach(&unescaped));\n  } else {\n    return make_str(subj, start_column, end_column, *content);\n  }\n}\n\n// Like cmark_node_append_child but without costly sanity checks.\n// Assumes that child was newly created.\nstatic void append_child(cmark_node *node, cmark_node *child) {\n  cmark_node *old_last_child = node->last_child;\n\n  child->next = NULL;\n  child->prev = old_last_child;\n  child->parent = node;\n  node->last_child = child;\n\n  if (old_last_child) {\n    old_last_child->next = child;\n  } else {\n    // Also set first_child if node previously had no children.\n    node->first_child = child;\n  }\n}\n\n// Duplicate a chunk by creating a copy of the buffer not by reusing the\n// buffer like cmark_chunk_dup does.\nstatic cmark_chunk chunk_clone(cmark_mem *mem, cmark_chunk *src) {\n  cmark_chunk c;\n  bufsize_t len = src->len;\n\n  c.len = len;\n  c.data = (unsigned char *)mem->calloc(len + 1, 1);\n  c.alloc = 1;\n  if (len)\n    memcpy(c.data, src->data, len);\n  c.data[len] = '\\0';\n\n  return c;\n}\n\nstatic cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url,\n                                        int is_email) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n\n  cmark_chunk_trim(url);\n\n  if (url->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  if (is_email)\n    cmark_strbuf_puts(&buf, \"mailto:\");\n\n  houdini_unescape_html_f(&buf, url->data, url->len);\n  return cmark_chunk_buf_detach(&buf);\n}\n\nstatic CMARK_INLINE cmark_node *make_autolink(subject *subj,\n                                              int start_column, int end_column,\n                                              cmark_chunk url, int is_email) {\n  cmark_node *link = make_simple(subj->mem, CMARK_NODE_LINK);\n  link->as.link.url = cmark_clean_autolink(subj->mem, &url, is_email);\n  link->as.link.title = cmark_chunk_literal(\"\");\n  link->start_line = link->end_line = subj->line;\n  link->start_column = start_column + 1;\n  link->end_column = end_column + 1;\n  append_child(link, make_str_with_entities(subj, start_column + 1, end_column - 1, &url));\n  return link;\n}\n\nstatic void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,\n                             cmark_chunk *chunk, cmark_map *refmap) {\n  int i;\n  e->mem = mem;\n  e->input = *chunk;\n  e->flags = 0;\n  e->line = line_number;\n  e->pos = 0;\n  e->block_offset = block_offset;\n  e->column_offset = 0;\n  e->refmap = refmap;\n  e->last_delim = NULL;\n  e->last_bracket = NULL;\n  for (i = 0; i <= MAXBACKTICKS; i++) {\n    e->backticks[i] = 0;\n  }\n  e->scanned_for_backticks = false;\n  e->no_link_openers = true;\n}\n\nstatic CMARK_INLINE int isbacktick(int c) { return (c == '`'); }\n\nstatic CMARK_INLINE unsigned char peek_char_n(subject *subj, bufsize_t n) {\n  // NULL bytes should have been stripped out by now.  If they're\n  // present, it's a programming error:\n  assert(!(subj->pos + n < subj->input.len && subj->input.data[subj->pos + n] == 0));\n  return (subj->pos + n < subj->input.len) ? subj->input.data[subj->pos + n] : 0;\n}\n\nstatic CMARK_INLINE unsigned char peek_char(subject *subj) {\n  return peek_char_n(subj, 0);\n}\n\nstatic CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) {\n  return subj->input.data[pos];\n}\n\n// Return true if there are more characters in the subject.\nstatic CMARK_INLINE int is_eof(subject *subj) {\n  return (subj->pos >= subj->input.len);\n}\n\n// Advance the subject.  Doesn't check for eof.\n#define advance(subj) (subj)->pos += 1\n\nstatic CMARK_INLINE bool skip_spaces(subject *subj) {\n  bool skipped = false;\n  while (peek_char(subj) == ' ' || peek_char(subj) == '\\t') {\n    advance(subj);\n    skipped = true;\n  }\n  return skipped;\n}\n\nstatic CMARK_INLINE bool skip_line_end(subject *subj) {\n  bool seen_line_end_char = false;\n  if (peek_char(subj) == '\\r') {\n    advance(subj);\n    seen_line_end_char = true;\n  }\n  if (peek_char(subj) == '\\n') {\n    advance(subj);\n    seen_line_end_char = true;\n  }\n  return seen_line_end_char || is_eof(subj);\n}\n\n// Take characters while a predicate holds, and return a string.\nstatic CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) {\n  unsigned char c;\n  bufsize_t startpos = subj->pos;\n  bufsize_t len = 0;\n\n  while ((c = peek_char(subj)) && (*f)(c)) {\n    advance(subj);\n    len++;\n  }\n\n  return cmark_chunk_dup(&subj->input, startpos, len);\n}\n\n// Return the number of newlines in a given span of text in a subject.  If\n// the number is greater than zero, also return the number of characters\n// between the last newline and the end of the span in `since_newline`.\nstatic int count_newlines(subject *subj, bufsize_t from, bufsize_t len, int *since_newline) {\n  int nls = 0;\n  int since_nl = 0;\n\n  while (len--) {\n    if (subj->input.data[from++] == '\\n') {\n      ++nls;\n      since_nl = 0;\n    } else {\n      ++since_nl;\n    }\n  }\n\n  if (!nls)\n    return 0;\n\n  *since_newline = since_nl;\n  return nls;\n}\n\n// Adjust `node`'s `end_line`, `end_column`, and `subj`'s `line` and\n// `column_offset` according to the number of newlines in a just-matched span\n// of text in `subj`.\nstatic void adjust_subj_node_newlines(subject *subj, cmark_node *node, int matchlen, int extra, int options) {\n  if (!(options & CMARK_OPT_SOURCEPOS)) {\n    return;\n  }\n\n  int since_newline;\n  int newlines = count_newlines(subj, subj->pos - matchlen - extra, matchlen, &since_newline);\n  if (newlines) {\n    subj->line += newlines;\n    node->end_line += newlines;\n    node->end_column = since_newline;\n    subj->column_offset = -subj->pos + since_newline + extra;\n  }\n}\n\n// Try to process a backtick code span that began with a\n// span of ticks of length openticklength length (already\n// parsed).  Return 0 if you don't find matching closing\n// backticks, otherwise return the position in the subject\n// after the closing backticks.\nstatic bufsize_t scan_to_closing_backticks(subject *subj,\n                                           bufsize_t openticklength) {\n\n  bool found = false;\n  if (openticklength > MAXBACKTICKS) {\n    // we limit backtick string length because of the array subj->backticks:\n    return 0;\n  }\n  if (subj->scanned_for_backticks &&\n      subj->backticks[openticklength] <= subj->pos) {\n    // return if we already know there's no closer\n    return 0;\n  }\n  while (!found) {\n    // read non backticks\n    unsigned char c;\n    while ((c = peek_char(subj)) && c != '`') {\n      advance(subj);\n    }\n    if (is_eof(subj)) {\n      break;\n    }\n    bufsize_t numticks = 0;\n    while (peek_char(subj) == '`') {\n      advance(subj);\n      numticks++;\n    }\n    // store position of ender\n    if (numticks <= MAXBACKTICKS) {\n      subj->backticks[numticks] = subj->pos - numticks;\n    }\n    if (numticks == openticklength) {\n      return (subj->pos);\n    }\n  }\n  // got through whole input without finding closer\n  subj->scanned_for_backticks = true;\n  return 0;\n}\n\n// Destructively modify string, converting newlines to\n// spaces, then removing a single leading + trailing space,\n// unless the code span consists entirely of space characters.\nstatic void S_normalize_code(cmark_strbuf *s) {\n  bufsize_t r, w;\n  bool contains_nonspace = false;\n\n  for (r = 0, w = 0; r < s->size; ++r) {\n    switch (s->ptr[r]) {\n    case '\\r':\n      if (s->ptr[r + 1] != '\\n') {\n\ts->ptr[w++] = ' ';\n      }\n      break;\n    case '\\n':\n      s->ptr[w++] = ' ';\n      break;\n    default:\n      s->ptr[w++] = s->ptr[r];\n    }\n    if (s->ptr[r] != ' ') {\n      contains_nonspace = true;\n    }\n  }\n\n  // begins and ends with space?\n  if (contains_nonspace &&\n      s->ptr[0] == ' ' && s->ptr[w - 1] == ' ') {\n    cmark_strbuf_drop(s, 1);\n    cmark_strbuf_truncate(s, w - 2);\n  } else {\n    cmark_strbuf_truncate(s, w);\n  }\n\n}\n\n\n// Parse backtick code section or raw backticks, return an inline.\n// Assumes that the subject has a backtick at the current position.\nstatic cmark_node *handle_backticks(subject *subj, int options) {\n  cmark_chunk openticks = take_while(subj, isbacktick);\n  bufsize_t startpos = subj->pos;\n  bufsize_t endpos = scan_to_closing_backticks(subj, openticks.len);\n\n  if (endpos == 0) {      // not found\n    subj->pos = startpos; // rewind\n    return make_str(subj, subj->pos, subj->pos, openticks);\n  } else {\n    cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);\n\n    cmark_strbuf_set(&buf, subj->input.data + startpos,\n                     endpos - startpos - openticks.len);\n    S_normalize_code(&buf);\n\n    cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));\n    adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);\n    return node;\n  }\n}\n\n\n// Scan ***, **, or * and return number scanned, or 0.\n// Advances position.\nstatic int scan_delims(subject *subj, unsigned char c, bool *can_open,\n                       bool *can_close) {\n  int numdelims = 0;\n  bufsize_t before_char_pos, after_char_pos;\n  int32_t after_char = 0;\n  int32_t before_char = 0;\n  int len;\n  bool left_flanking, right_flanking;\n\n  if (subj->pos == 0) {\n    before_char = 10;\n  } else {\n    before_char_pos = subj->pos - 1;\n    // walk back to the beginning of the UTF_8 sequence:\n    while ((peek_at(subj, before_char_pos) >> 6 == 2 || SKIP_CHARS[peek_at(subj, before_char_pos)]) && before_char_pos > 0) {\n      before_char_pos -= 1;\n    }\n    len = cmark_utf8proc_iterate(subj->input.data + before_char_pos,\n                                 subj->pos - before_char_pos, &before_char);\n    if (len == -1 || (before_char < 256 && SKIP_CHARS[(unsigned char) before_char])) {\n      before_char = 10;\n    }\n  }\n\n  if (c == '\\'' || c == '\"') {\n    numdelims++;\n    advance(subj); // limit to 1 delim for quotes\n  } else {\n    while (peek_char(subj) == c) {\n      numdelims++;\n      advance(subj);\n    }\n  }\n\n  if (subj->pos == subj->input.len) {\n    after_char = 10;\n  } else {\n    after_char_pos = subj->pos;\n    while (SKIP_CHARS[peek_at(subj, after_char_pos)] && after_char_pos < subj->input.len) {\n      after_char_pos += 1;\n    }\n    len = cmark_utf8proc_iterate(subj->input.data + after_char_pos,\n                                 subj->input.len - after_char_pos, &after_char);\n    if (len == -1 || (after_char < 256 && SKIP_CHARS[(unsigned char) after_char])) {\n    after_char = 10;\n  }\n  }\n\n  left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&\n                  (!cmark_utf8proc_is_punctuation(after_char) ||\n                   cmark_utf8proc_is_space(before_char) ||\n                   cmark_utf8proc_is_punctuation(before_char));\n  right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&\n                   (!cmark_utf8proc_is_punctuation(before_char) ||\n                    cmark_utf8proc_is_space(after_char) ||\n                    cmark_utf8proc_is_punctuation(after_char));\n  if (c == '_') {\n    *can_open = left_flanking &&\n                (!right_flanking || cmark_utf8proc_is_punctuation(before_char));\n    *can_close = right_flanking &&\n                 (!left_flanking || cmark_utf8proc_is_punctuation(after_char));\n  } else if (c == '\\'' || c == '\"') {\n    *can_open = left_flanking && !right_flanking &&\n\t         before_char != ']' && before_char != ')';\n    *can_close = right_flanking;\n  } else {\n    *can_open = left_flanking;\n    *can_close = right_flanking;\n  }\n  return numdelims;\n}\n\n/*\nstatic void print_delimiters(subject *subj)\n{\n        delimiter *delim;\n        delim = subj->last_delim;\n        while (delim != NULL) {\n                printf(\"Item at stack pos %p: %d %d %d next(%p) prev(%p)\\n\",\n                       (void*)delim, delim->delim_char,\n                       delim->can_open, delim->can_close,\n                       (void*)delim->next, (void*)delim->previous);\n                delim = delim->previous;\n        }\n}\n*/\n\nstatic void remove_delimiter(subject *subj, delimiter *delim) {\n  if (delim == NULL)\n    return;\n  if (delim->next == NULL) {\n    // end of list:\n    assert(delim == subj->last_delim);\n    subj->last_delim = delim->previous;\n  } else {\n    delim->next->previous = delim->previous;\n  }\n  if (delim->previous != NULL) {\n    delim->previous->next = delim->next;\n  }\n  subj->mem->free(delim);\n}\n\nstatic void pop_bracket(subject *subj) {\n  bracket *b;\n  if (subj->last_bracket == NULL)\n    return;\n  b = subj->last_bracket;\n  subj->last_bracket = subj->last_bracket->previous;\n  subj->mem->free(b);\n}\n\nstatic void push_delimiter(subject *subj, unsigned char c, bool can_open,\n                           bool can_close, cmark_node *inl_text) {\n  delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter));\n  delim->delim_char = c;\n  delim->can_open = can_open;\n  delim->can_close = can_close;\n  delim->inl_text = inl_text;\n  delim->position = subj->pos;\n  delim->length = inl_text->as.literal.len;\n  delim->previous = subj->last_delim;\n  delim->next = NULL;\n  if (delim->previous != NULL) {\n    delim->previous->next = delim;\n  }\n  subj->last_delim = delim;\n}\n\nstatic void push_bracket(subject *subj, bool image, cmark_node *inl_text) {\n  bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));\n  if (subj->last_bracket != NULL) {\n    subj->last_bracket->bracket_after = true;\n    b->in_bracket_image0 = subj->last_bracket->in_bracket_image0;\n    b->in_bracket_image1 = subj->last_bracket->in_bracket_image1;\n  }\n  b->image = image;\n  b->active = true;\n  b->inl_text = inl_text;\n  b->previous = subj->last_bracket;\n  b->position = subj->pos;\n  b->bracket_after = false;\n  if (image) {\n    b->in_bracket_image1 = true;\n  } else {\n    b->in_bracket_image0 = true;\n  }\n  subj->last_bracket = b;\n  if (!image) {\n    subj->no_link_openers = false;\n  }\n}\n\n// Assumes the subject has a c at the current position.\nstatic cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {\n  bufsize_t numdelims;\n  cmark_node *inl_text;\n  bool can_open, can_close;\n  cmark_chunk contents;\n\n  numdelims = scan_delims(subj, c, &can_open, &can_close);\n\n  if (c == '\\'' && smart) {\n    contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);\n  } else if (c == '\"' && smart) {\n    contents =\n        cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);\n  } else {\n    contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);\n  }\n\n  inl_text = make_str(subj, subj->pos - numdelims, subj->pos - 1, contents);\n\n  if ((can_open || can_close) && (!(c == '\\'' || c == '\"') || smart)) {\n    push_delimiter(subj, c, can_open, can_close, inl_text);\n  }\n\n  return inl_text;\n}\n\n// Assumes we have a hyphen at the current position.\nstatic cmark_node *handle_hyphen(subject *subj, bool smart) {\n  int startpos = subj->pos;\n\n  advance(subj);\n\n  if (!smart || peek_char(subj) != '-') {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"-\"));\n  }\n\n  while (smart && peek_char(subj) == '-') {\n    advance(subj);\n  }\n\n  int numhyphens = subj->pos - startpos;\n  int en_count = 0;\n  int em_count = 0;\n  int i;\n  cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);\n\n  if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes\n    em_count = numhyphens / 3;\n  } else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes\n    en_count = numhyphens / 2;\n  } else if (numhyphens % 3 == 2) { // use one en dash at end\n    en_count = 1;\n    em_count = (numhyphens - 2) / 3;\n  } else { // use two en dashes at the end\n    en_count = 2;\n    em_count = (numhyphens - 4) / 3;\n  }\n\n  for (i = em_count; i > 0; i--) {\n    cmark_strbuf_puts(&buf, EMDASH);\n  }\n\n  for (i = en_count; i > 0; i--) {\n    cmark_strbuf_puts(&buf, ENDASH);\n  }\n\n  return make_str(subj, startpos, subj->pos - 1, cmark_chunk_buf_detach(&buf));\n}\n\n// Assumes we have a period at the current position.\nstatic cmark_node *handle_period(subject *subj, bool smart) {\n  advance(subj);\n  if (smart && peek_char(subj) == '.') {\n    advance(subj);\n    if (peek_char(subj) == '.') {\n      advance(subj);\n      return make_str(subj, subj->pos - 3, subj->pos - 1, cmark_chunk_literal(ELLIPSES));\n    } else {\n      return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(\"..\"));\n    }\n  } else {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\".\"));\n  }\n}\n\nstatic cmark_syntax_extension *get_extension_for_special_char(cmark_parser *parser, unsigned char c) {\n  cmark_llist *tmp_ext;\n\n  for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;\n    cmark_llist *tmp_char;\n    for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {\n      unsigned char tmp_c = (unsigned char)(size_t)tmp_char->data;\n\n      if (tmp_c == c) {\n        return ext;\n      }\n    }\n  }\n\n  return NULL;\n}\n\nstatic void process_emphasis(cmark_parser *parser, subject *subj, bufsize_t stack_bottom) {\n  delimiter *candidate;\n  delimiter *closer = NULL;\n  delimiter *opener;\n  delimiter *old_closer;\n  bool opener_found;\n  bufsize_t openers_bottom[3][128];\n  int i;\n\n  // initialize openers_bottom:\n  memset(&openers_bottom, 0, sizeof(openers_bottom));\n  for (i=0; i < 3; i++) {\n    openers_bottom[i]['*'] = stack_bottom;\n    openers_bottom[i]['_'] = stack_bottom;\n    openers_bottom[i]['\\''] = stack_bottom;\n    openers_bottom[i]['\"'] = stack_bottom;\n  }\n\n  // move back to first relevant delim.\n  candidate = subj->last_delim;\n  while (candidate != NULL && candidate->position >= stack_bottom) {\n    closer = candidate;\n    candidate = candidate->previous;\n  }\n\n  // now move forward, looking for closers, and handling each\n  while (closer != NULL) {\n    cmark_syntax_extension *extension = get_extension_for_special_char(parser, closer->delim_char);\n    if (closer->can_close) {\n      // Now look backwards for first matching opener:\n      opener = closer->previous;\n      opener_found = false;\n      while (opener != NULL && opener->position >= stack_bottom &&\n             opener->position >= openers_bottom[closer->length % 3][closer->delim_char]) {\n        if (opener->can_open && opener->delim_char == closer->delim_char) {\n          // interior closer of size 2 can't match opener of size 1\n          // or of size 1 can't match 2\n          if (!(closer->can_open || opener->can_close) ||\n\t      closer->length % 3 == 0 ||\n              (opener->length + closer->length) % 3 != 0) {\n            opener_found = true;\n            break;\n          }\n        }\n        opener = opener->previous;\n      }\n      old_closer = closer;\n\n      if (extension) {\n        if (opener_found)\n          closer = extension->insert_inline_from_delim(extension, parser, subj, opener, closer);\n        else\n          closer = closer->next;\n      } else if (closer->delim_char == '*' || closer->delim_char == '_') {\n        if (opener_found) {\n          closer = S_insert_emph(subj, opener, closer);\n        } else {\n          closer = closer->next;\n        }\n      } else if (closer->delim_char == '\\'' || closer->delim_char == '\"') {\n        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);\n        if (closer->delim_char == '\\'') {\n          closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);\n        } else {\n          closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);\n        }\n        closer = closer->next;\n        if (opener_found) {\n          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);\n          if (old_closer->delim_char == '\\'') {\n            opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);\n          } else {\n            opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);\n          }\n          remove_delimiter(subj, opener);\n          remove_delimiter(subj, old_closer);\n        }\n      }\n      if (!opener_found) {\n        // set lower bound for future searches for openers\n        openers_bottom[old_closer->length % 3][old_closer->delim_char] =\n\t\told_closer->position;\n        if (!old_closer->can_open) {\n          // we can remove a closer that can't be an\n          // opener, once we've seen there's no\n          // matching opener:\n          remove_delimiter(subj, old_closer);\n        }\n      }\n    } else {\n      closer = closer->next;\n    }\n  }\n  // free all delimiters in list until stack_bottom:\n  while (subj->last_delim != NULL &&\n         subj->last_delim->position >= stack_bottom) {\n    remove_delimiter(subj, subj->last_delim);\n  }\n}\n\nstatic delimiter *S_insert_emph(subject *subj, delimiter *opener,\n                                delimiter *closer) {\n  delimiter *delim, *tmp_delim;\n  bufsize_t use_delims;\n  cmark_node *opener_inl = opener->inl_text;\n  cmark_node *closer_inl = closer->inl_text;\n  bufsize_t opener_num_chars = opener_inl->as.literal.len;\n  bufsize_t closer_num_chars = closer_inl->as.literal.len;\n  cmark_node *tmp, *tmpnext, *emph;\n\n  // calculate the actual number of characters used from this closer\n  use_delims = (closer_num_chars >= 2 && opener_num_chars >= 2) ? 2 : 1;\n\n  // remove used characters from associated inlines.\n  opener_num_chars -= use_delims;\n  closer_num_chars -= use_delims;\n  opener_inl->as.literal.len = opener_num_chars;\n  closer_inl->as.literal.len = closer_num_chars;\n\n  // free delimiters between opener and closer\n  delim = closer->previous;\n  while (delim != NULL && delim != opener) {\n    tmp_delim = delim->previous;\n    remove_delimiter(subj, delim);\n    delim = tmp_delim;\n  }\n\n  // create new emph or strong, and splice it in to our inlines\n  // between the opener and closer\n  emph = use_delims == 1 ? make_emph(subj->mem) : make_strong(subj->mem);\n\n  tmp = opener_inl->next;\n  while (tmp && tmp != closer_inl) {\n    tmpnext = tmp->next;\n    cmark_node_unlink(tmp);\n    append_child(emph, tmp);\n    tmp = tmpnext;\n  }\n  cmark_node_insert_after(opener_inl, emph);\n\n  emph->start_line = opener_inl->start_line;\n  emph->end_line = closer_inl->end_line;\n  emph->start_column = opener_inl->start_column;\n  emph->end_column = closer_inl->end_column;\n\n  // if opener has 0 characters, remove it and its associated inline\n  if (opener_num_chars == 0) {\n    cmark_node_free(opener_inl);\n    remove_delimiter(subj, opener);\n  }\n\n  // if closer has 0 characters, remove it and its associated inline\n  if (closer_num_chars == 0) {\n    // remove empty closer inline\n    cmark_node_free(closer_inl);\n    // remove closer from list\n    tmp_delim = closer->next;\n    remove_delimiter(subj, closer);\n    closer = tmp_delim;\n  }\n\n  return closer;\n}\n\n// Parse backslash-escape or just a backslash, returning an inline.\nstatic cmark_node *handle_backslash(cmark_parser *parser, subject *subj) {\n  advance(subj);\n  unsigned char nextchar = peek_char(subj);\n  if ((parser->backslash_ispunct ? parser->backslash_ispunct : cmark_ispunct)(nextchar)) {\n    // only ascii symbols and newline can be escaped\n    advance(subj);\n    return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));\n  } else if (!is_eof(subj) && skip_line_end(subj)) {\n    return make_linebreak(subj->mem);\n  } else {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"\\\\\"));\n  }\n}\n\n// Parse an entity or a regular \"&\" string.\n// Assumes the subject has an '&' character at the current position.\nstatic cmark_node *handle_entity(subject *subj) {\n  cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);\n  bufsize_t len;\n\n  advance(subj);\n\n  len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,\n                             subj->input.len - subj->pos);\n\n  if (len == 0)\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"&\"));\n\n  subj->pos += len;\n  return make_str(subj, subj->pos - 1 - len, subj->pos - 1, cmark_chunk_buf_detach(&ent));\n}\n\n// Clean a URL: remove surrounding whitespace, and remove \\ that escape\n// punctuation.\ncmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n\n  cmark_chunk_trim(url);\n\n  if (url->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  houdini_unescape_html_f(&buf, url->data, url->len);\n\n  cmark_strbuf_unescape(&buf);\n  return cmark_chunk_buf_detach(&buf);\n}\n\ncmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n  unsigned char first, last;\n\n  if (title->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  first = title->data[0];\n  last = title->data[title->len - 1];\n\n  // remove surrounding quotes if any:\n  if ((first == '\\'' && last == '\\'') || (first == '(' && last == ')') ||\n      (first == '\"' && last == '\"')) {\n    houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);\n  } else {\n    houdini_unescape_html_f(&buf, title->data, title->len);\n  }\n\n  cmark_strbuf_unescape(&buf);\n  return cmark_chunk_buf_detach(&buf);\n}\n\n// Parse an autolink or HTML tag.\n// Assumes the subject has a '<' character at the current position.\nstatic cmark_node *handle_pointy_brace(subject *subj, int options) {\n  bufsize_t matchlen = 0;\n  cmark_chunk contents;\n\n  advance(subj); // advance past first <\n\n  // first try to match a URL autolink\n  matchlen = scan_autolink_uri(&subj->input, subj->pos);\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);\n    subj->pos += matchlen;\n\n    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 0);\n  }\n\n  // next try to match an email autolink\n  matchlen = scan_autolink_email(&subj->input, subj->pos);\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);\n    subj->pos += matchlen;\n\n    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 1);\n  }\n\n  // finally, try to match an html tag\n  if (subj->pos + 2 <= subj->input.len) {\n    int c = subj->input.data[subj->pos];\n    if (c == '!' && (subj->flags & FLAG_SKIP_HTML_COMMENT) == 0) {\n      c = subj->input.data[subj->pos+1];\n      if (c == '-' && subj->input.data[subj->pos+2] == '-') {\n        if (subj->input.data[subj->pos+3] == '>') {\n          matchlen = 4;\n        } else if (subj->input.data[subj->pos+3] == '-' &&\n                   subj->input.data[subj->pos+4] == '>') {\n          matchlen = 5;\n        } else {\n          matchlen = scan_html_comment(&subj->input, subj->pos + 1);\n          if (matchlen > 0) {\n            matchlen += 1; // prefix \"<\"\n          } else { // no match through end of input: set a flag so\n                   // we don't reparse looking for -->:\n            subj->flags |= FLAG_SKIP_HTML_COMMENT;\n          }\n        }\n      } else if (c == '[') {\n        if ((subj->flags & FLAG_SKIP_HTML_CDATA) == 0) {\n          matchlen = scan_html_cdata(&subj->input, subj->pos + 2);\n          if (matchlen > 0) {\n            // The regex doesn't require the final \"]]>\". But if we're not at\n            // the end of input, it must come after the match. Otherwise,\n            // disable subsequent scans to avoid quadratic behavior.\n            matchlen += 5; // prefix \"![\", suffix \"]]>\"\n            if (subj->pos + matchlen > subj->input.len) {\n              subj->flags |= FLAG_SKIP_HTML_CDATA;\n              matchlen = 0;\n            }\n          }\n        }\n      } else if ((subj->flags & FLAG_SKIP_HTML_DECLARATION) == 0) {\n        matchlen = scan_html_declaration(&subj->input, subj->pos + 1);\n        if (matchlen > 0) {\n          matchlen += 2; // prefix \"!\", suffix \">\"\n          if (subj->pos + matchlen > subj->input.len) {\n            subj->flags |= FLAG_SKIP_HTML_DECLARATION;\n            matchlen = 0;\n          }\n        }\n      }\n    } else if (c == '?') {\n      if ((subj->flags & FLAG_SKIP_HTML_PI) == 0) {\n        // Note that we allow an empty match.\n        matchlen = scan_html_pi(&subj->input, subj->pos + 1);\n        matchlen += 3; // prefix \"?\", suffix \"?>\"\n        if (subj->pos + matchlen > subj->input.len) {\n          subj->flags |= FLAG_SKIP_HTML_PI;\n          matchlen = 0;\n        }\n      }\n    } else {\n      matchlen = scan_html_tag(&subj->input, subj->pos);\n    }\n  }\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);\n    subj->pos += matchlen;\n    cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);\n    adjust_subj_node_newlines(subj, node, matchlen, 1, options);\n    return node;\n  }\n\n  if (options & CMARK_OPT_LIBERAL_HTML_TAG) {\n    matchlen = scan_liberal_html_tag(&subj->input, subj->pos);\n    if (matchlen > 0) {\n      contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);\n      subj->pos += matchlen;\n      cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);\n      adjust_subj_node_newlines(subj, node, matchlen, 1, options);\n      return node;\n    }\n  }\n\n  // if nothing matches, just return the opening <:\n  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"<\"));\n}\n\n// Parse a link label.  Returns 1 if successful.\n// Note:  unescaped brackets are not allowed in labels.\n// The label begins with `[` and ends with the first `]` character\n// encountered.  Backticks in labels do not start code spans.\nstatic int link_label(subject *subj, cmark_chunk *raw_label) {\n  bufsize_t startpos = subj->pos;\n  int length = 0;\n  unsigned char c;\n\n  // advance past [\n  if (peek_char(subj) == '[') {\n    advance(subj);\n  } else {\n    return 0;\n  }\n\n  while ((c = peek_char(subj)) && c != '[' && c != ']') {\n    if (c == '\\\\') {\n      advance(subj);\n      length++;\n      if (cmark_ispunct(peek_char(subj))) {\n        advance(subj);\n        length++;\n      }\n    } else {\n      advance(subj);\n      length++;\n    }\n    if (length > MAX_LINK_LABEL_LENGTH) {\n      goto noMatch;\n    }\n  }\n\n  if (c == ']') { // match found\n    *raw_label =\n        cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));\n    cmark_chunk_trim(raw_label);\n    advance(subj); // advance past ]\n    return 1;\n  }\n\nnoMatch:\n  subj->pos = startpos; // rewind\n  return 0;\n}\n\nstatic bufsize_t manual_scan_link_url_2(cmark_chunk *input, bufsize_t offset,\n                                        cmark_chunk *output) {\n  bufsize_t i = offset;\n  size_t nb_p = 0;\n\n  while (i < input->len) {\n    if (input->data[i] == '\\\\' &&\n        i + 1 < input-> len &&\n        cmark_ispunct(input->data[i+1]))\n      i += 2;\n    else if (input->data[i] == '(') {\n      ++nb_p;\n      ++i;\n      if (nb_p > 32)\n        return -1;\n    } else if (input->data[i] == ')') {\n      if (nb_p == 0)\n        break;\n      --nb_p;\n      ++i;\n    } else if (cmark_isspace(input->data[i])) {\n      if (i == offset) {\n        return -1;\n      }\n      break;\n    } else {\n      ++i;\n    }\n  }\n\n  if (i >= input->len)\n    return -1;\n\n  {\n    cmark_chunk result = {input->data + offset, i - offset, 0};\n    *output = result;\n  }\n  return i - offset;\n}\n\nstatic bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset,\n                                      cmark_chunk *output) {\n  bufsize_t i = offset;\n\n  if (i < input->len && input->data[i] == '<') {\n    ++i;\n    while (i < input->len) {\n      if (input->data[i] == '>') {\n        ++i;\n        break;\n      } else if (input->data[i] == '\\\\')\n        i += 2;\n      else if (input->data[i] == '\\n' || input->data[i] == '<')\n        return -1;\n      else\n        ++i;\n    }\n  } else {\n    return manual_scan_link_url_2(input, offset, output);\n  }\n\n  if (i >= input->len)\n    return -1;\n\n  {\n    cmark_chunk result = {input->data + offset + 1, i - 2 - offset, 0};\n    *output = result;\n  }\n  return i - offset;\n}\n\n// Return a link, an image, or a literal close bracket.\nstatic cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {\n  bufsize_t initial_pos, after_link_text_pos;\n  bufsize_t endurl, starttitle, endtitle, endall;\n  bufsize_t sps, n;\n  cmark_reference *ref = NULL;\n  cmark_chunk url_chunk, title_chunk;\n  cmark_chunk url, title;\n  bracket *opener;\n  cmark_node *inl;\n  cmark_chunk raw_label;\n  int found_label;\n  cmark_node *tmp, *tmpnext;\n  bool is_image;\n\n  advance(subj); // advance past ]\n  initial_pos = subj->pos;\n\n  // get last [ or ![\n  opener = subj->last_bracket;\n\n  if (opener == NULL) {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n  }\n\n  // If we got here, we matched a potential link/image text.\n  // Now we check to see if it's a link/image.\n  is_image = opener->image;\n\n  if (!is_image && subj->no_link_openers) {\n    // take delimiter off stack\n    pop_bracket(subj);\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n  }\n\n  after_link_text_pos = subj->pos;\n\n  // First, look for an inline link.\n  if (peek_char(subj) == '(' &&\n      ((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) &&\n      ((n = manual_scan_link_url(&subj->input, subj->pos + 1 + sps,\n                                 &url_chunk)) > -1)) {\n\n    // try to parse an explicit link:\n    endurl = subj->pos + 1 + sps + n;\n    starttitle = endurl + scan_spacechars(&subj->input, endurl);\n\n    // ensure there are spaces btw url and title\n    endtitle = (starttitle == endurl)\n                   ? starttitle\n                   : starttitle + scan_link_title(&subj->input, starttitle);\n\n    endall = endtitle + scan_spacechars(&subj->input, endtitle);\n\n    if (peek_at(subj, endall) == ')') {\n      subj->pos = endall + 1;\n\n      title_chunk =\n          cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);\n      url = cmark_clean_url(subj->mem, &url_chunk);\n      title = cmark_clean_title(subj->mem, &title_chunk);\n      cmark_chunk_free(subj->mem, &url_chunk);\n      cmark_chunk_free(subj->mem, &title_chunk);\n      goto match;\n\n    } else {\n      // it could still be a shortcut reference link\n      subj->pos = after_link_text_pos;\n    }\n  }\n\n  // Next, look for a following [link label] that matches in refmap.\n  // skip spaces\n  raw_label = cmark_chunk_literal(\"\");\n  found_label = link_label(subj, &raw_label);\n  if (!found_label) {\n    // If we have a shortcut reference link, back up\n    // to before the spacse we skipped.\n    subj->pos = initial_pos;\n  }\n\n  if ((!found_label || raw_label.len == 0) && !opener->bracket_after) {\n    cmark_chunk_free(subj->mem, &raw_label);\n    raw_label = cmark_chunk_dup(&subj->input, opener->position,\n                                initial_pos - opener->position - 1);\n    found_label = true;\n  }\n\n  if (found_label) {\n    ref = (cmark_reference *)cmark_map_lookup(subj->refmap, &raw_label);\n    cmark_chunk_free(subj->mem, &raw_label);\n  }\n\n  if (ref != NULL) { // found\n    url = chunk_clone(subj->mem, &ref->url);\n    title = chunk_clone(subj->mem, &ref->title);\n    goto match;\n  } else {\n    goto noMatch;\n  }\n\nnoMatch:\n  // If we fall through to here, it means we didn't match a link.\n  // What if we're a footnote link?\n  if (parser->options & CMARK_OPT_FOOTNOTES &&\n      opener->inl_text->next &&\n      opener->inl_text->next->type == CMARK_NODE_TEXT) {\n\n    cmark_chunk *literal = &opener->inl_text->next->as.literal;\n\n    // look back to the opening '[', and skip ahead to the next character\n    // if we're looking at a '[^' sequence, and there is other text or nodes\n    // after the ^, let's call it a footnote reference.\n    if ((literal->len > 0 && literal->data[0] == '^') && (literal->len > 1 || opener->inl_text->next->next)) {\n\n      // Before we got this far, the `handle_close_bracket` function may have\n      // advanced the current state beyond our footnote's actual closing\n      // bracket, ie if it went looking for a `link_label`.\n      // Let's just rewind the subject's position:\n      subj->pos = initial_pos;\n\n      cmark_node *fnref = make_simple(subj->mem, CMARK_NODE_FOOTNOTE_REFERENCE);\n\n      // the start and end of the footnote ref is the opening and closing brace\n      // i.e. the subject's current position, and the opener's start_column\n      int fnref_end_column = subj->pos + subj->column_offset + subj->block_offset;\n      int fnref_start_column = opener->inl_text->start_column;\n\n      // any given node delineates a substring of the line being processed,\n      // with the remainder of the line being pointed to thru its 'literal'\n      // struct member.\n      // here, we copy the literal's pointer, moving it past the '^' character\n      // for a length equal to the size of footnote reference text.\n      // i.e. end_col minus start_col, minus the [ and the ^ characters\n      //\n      // this copies the footnote reference string, even if between the\n      // `opener` and the subject's current position there are other nodes\n      //\n      // (first, check for underflows)\n      if ((fnref_start_column + 2) <= fnref_end_column) {\n        fnref->as.literal = cmark_chunk_dup(literal, 1, (fnref_end_column - fnref_start_column) - 2);\n      } else {\n        fnref->as.literal = cmark_chunk_dup(literal, 1, 0);\n      }\n\n      fnref->start_line = fnref->end_line = subj->line;\n      fnref->start_column = fnref_start_column;\n      fnref->end_column = fnref_end_column;\n\n      // we then replace the opener with this new fnref node, the net effect\n      // being replacing the opening '[' text node with a `^footnote-ref]` node.\n      cmark_node_insert_before(opener->inl_text, fnref);\n\n      process_emphasis(parser, subj, opener->position);\n      // sometimes, the footnote reference text gets parsed into multiple nodes\n      // i.e. '[^example]' parsed into '[', '^exam', 'ple]'.\n      // this happens for ex with the autolink extension. when the autolinker\n      // finds the 'w' character, it will split the text into multiple nodes\n      // in hopes of being able to match a 'www.' substring.\n      //\n      // because this function is called one character at a time via the\n      // `parse_inlines` function, and the current subj->pos is pointing at the\n      // closing ] brace, and because we copy all the text between the [ ]\n      // braces, we should be able to safely ignore and delete any nodes after\n      // the opener->inl_text->next.\n      //\n      // therefore, here we walk thru the list and free them all up\n      cmark_node *next_node;\n      cmark_node *current_node = opener->inl_text->next;\n      while(current_node) {\n        next_node = current_node->next;\n        cmark_node_free(current_node);\n        current_node = next_node;\n      }\n\n      cmark_node_free(opener->inl_text);\n\n      pop_bracket(subj);\n      return NULL;\n    }\n  }\n\n  pop_bracket(subj); // remove this opener from delimiter list\n  subj->pos = initial_pos;\n  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n\nmatch:\n  inl = make_simple(subj->mem, is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK);\n  inl->as.link.url = url;\n  inl->as.link.title = title;\n  inl->start_line = inl->end_line = subj->line;\n  inl->start_column = opener->inl_text->start_column;\n  inl->end_column = subj->pos + subj->column_offset + subj->block_offset;\n  cmark_node_insert_before(opener->inl_text, inl);\n  // Add link text:\n  tmp = opener->inl_text->next;\n  while (tmp) {\n    tmpnext = tmp->next;\n    cmark_node_unlink(tmp);\n    append_child(inl, tmp);\n    tmp = tmpnext;\n  }\n\n  // Free the bracket [:\n  cmark_node_free(opener->inl_text);\n\n  process_emphasis(parser, subj, opener->position);\n  pop_bracket(subj);\n\n  // Now, if we have a link, we also want to deactivate links until\n  // we get a new opener. (This code can be removed if we decide to allow links\n  // inside links.)\n  if (!is_image) {\n    subj->no_link_openers = true;\n  }\n\n  return NULL;\n}\n\n// Parse a hard or soft linebreak, returning an inline.\n// Assumes the subject has a cr or newline at the current position.\nstatic cmark_node *handle_newline(subject *subj) {\n  bufsize_t nlpos = subj->pos;\n  // skip over cr, crlf, or lf:\n  if (peek_at(subj, subj->pos) == '\\r') {\n    advance(subj);\n  }\n  if (peek_at(subj, subj->pos) == '\\n') {\n    advance(subj);\n  }\n  ++subj->line;\n  subj->column_offset = -subj->pos;\n  // skip spaces at beginning of line\n  skip_spaces(subj);\n  if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&\n      peek_at(subj, nlpos - 2) == ' ') {\n    return make_linebreak(subj->mem);\n  } else {\n    return make_softbreak(subj->mem);\n  }\n}\n\n// \"\\r\\n\\\\`&_*[]<!\"\nstatic int8_t SPECIAL_CHARS[256] = {\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,\n      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\n// \" ' . -\nstatic char SMART_PUNCT_CHARS[] = {\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nstatic bufsize_t subject_find_special_char(subject *subj, int options) {\n  bufsize_t n = subj->pos + 1;\n\n  while (n < subj->input.len) {\n    if (SPECIAL_CHARS[subj->input.data[n]])\n      return n;\n    if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS[subj->input.data[n]])\n      return n;\n    n++;\n  }\n\n  return subj->input.len;\n}\n\nvoid cmark_inlines_add_special_character(unsigned char c, bool emphasis) {\n  SPECIAL_CHARS[c] = 1;\n  if (emphasis)\n    SKIP_CHARS[c] = 1;\n}\n\nvoid cmark_inlines_remove_special_character(unsigned char c, bool emphasis) {\n  SPECIAL_CHARS[c] = 0;\n  if (emphasis)\n    SKIP_CHARS[c] = 0;\n}\n\nstatic cmark_node *try_extensions(cmark_parser *parser,\n                                  cmark_node *parent,\n                                  unsigned char c,\n                                  subject *subj) {\n  cmark_node *res = NULL;\n  cmark_llist *tmp;\n\n  for (tmp = parser->inline_syntax_extensions; tmp; tmp = tmp->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n    res = ext->match_inline(ext, parser, parent, c, subj);\n\n    if (res)\n      break;\n  }\n\n  return res;\n}\n\n// Parse an inline, advancing subject, and add it as a child of parent.\n// Return 0 if no inline can be parsed, 1 otherwise.\nstatic int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options) {\n  cmark_node *new_inl = NULL;\n  cmark_chunk contents;\n  unsigned char c;\n  bufsize_t startpos, endpos;\n  c = peek_char(subj);\n  if (c == 0) {\n    return 0;\n  }\n  switch (c) {\n  case '\\r':\n  case '\\n':\n    new_inl = handle_newline(subj);\n    break;\n  case '`':\n    new_inl = handle_backticks(subj, options);\n    break;\n  case '\\\\':\n    new_inl = handle_backslash(parser, subj);\n    break;\n  case '&':\n    new_inl = handle_entity(subj);\n    break;\n  case '<':\n    new_inl = handle_pointy_brace(subj, options);\n    break;\n  case '*':\n  case '_':\n  case '\\'':\n  case '\"':\n    new_inl = handle_delim(subj, c, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '-':\n    new_inl = handle_hyphen(subj, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '.':\n    new_inl = handle_period(subj, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '[':\n    advance(subj);\n    new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"[\"));\n    push_bracket(subj, false, new_inl);\n    break;\n  case ']':\n    new_inl = handle_close_bracket(parser, subj);\n    break;\n  case '!':\n    advance(subj);\n    if (peek_char(subj) == '[' && peek_char_n(subj, 1) != '^') {\n      advance(subj);\n      new_inl = make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(\"![\"));\n      push_bracket(subj, true, new_inl);\n    } else {\n      new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"!\"));\n    }\n    break;\n  default:\n    new_inl = try_extensions(parser, parent, c, subj);\n    if (new_inl != NULL)\n      break;\n\n    endpos = subject_find_special_char(subj, options);\n    contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);\n    startpos = subj->pos;\n    subj->pos = endpos;\n\n    // if we're at a newline, strip trailing spaces.\n    if (S_is_line_end_char(peek_char(subj))) {\n      cmark_chunk_rtrim(&contents);\n    }\n\n    new_inl = make_str(subj, startpos, endpos - 1, contents);\n  }\n  if (new_inl != NULL) {\n    append_child(parent, new_inl);\n  }\n\n  return 1;\n}\n\n// Parse inlines from parent's string_content, adding as children of parent.\nvoid cmark_parse_inlines(cmark_parser *parser,\n                         cmark_node *parent,\n                         cmark_map *refmap,\n                         int options) {\n  subject subj;\n  cmark_chunk content = {parent->content.ptr, parent->content.size, 0};\n  subject_from_buf(parser->mem, parent->start_line, parent->start_column - 1 + parent->internal_offset, &subj, &content, refmap);\n  cmark_chunk_rtrim(&subj.input);\n\n  while (!is_eof(&subj) && parse_inline(parser, &subj, parent, options))\n    ;\n\n  process_emphasis(parser, &subj, 0);\n  // free bracket and delim stack\n  while (subj.last_delim) {\n    remove_delimiter(&subj, subj.last_delim);\n  }\n  while (subj.last_bracket) {\n    pop_bracket(&subj);\n  }\n}\n\n// Parse zero or more space characters, including at most one newline.\nstatic void spnl(subject *subj) {\n  skip_spaces(subj);\n  if (skip_line_end(subj)) {\n    skip_spaces(subj);\n  }\n}\n\n// Parse reference.  Assumes string begins with '[' character.\n// Modify refmap if a reference is encountered.\n// Return 0 if no reference found, otherwise position of subject\n// after reference is parsed.\nbufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,\n                                       cmark_map *refmap) {\n  subject subj;\n\n  cmark_chunk lab;\n  cmark_chunk url;\n  cmark_chunk title;\n\n  bufsize_t matchlen = 0;\n  bufsize_t beforetitle;\n\n  subject_from_buf(mem, -1, 0, &subj, input, NULL);\n\n  // parse label:\n  if (!link_label(&subj, &lab) || lab.len == 0)\n    return 0;\n\n  // colon:\n  if (peek_char(&subj) == ':') {\n    advance(&subj);\n  } else {\n    return 0;\n  }\n\n  // parse link url:\n  spnl(&subj);\n  if ((matchlen = manual_scan_link_url(&subj.input, subj.pos, &url)) > -1) {\n    subj.pos += matchlen;\n  } else {\n    return 0;\n  }\n\n  // parse optional link_title\n  beforetitle = subj.pos;\n  spnl(&subj);\n  matchlen = subj.pos == beforetitle ? 0 : scan_link_title(&subj.input, subj.pos);\n  if (matchlen) {\n    title = cmark_chunk_dup(&subj.input, subj.pos, matchlen);\n    subj.pos += matchlen;\n  } else {\n    subj.pos = beforetitle;\n    title = cmark_chunk_literal(\"\");\n  }\n\n  // parse final spaces and newline:\n  skip_spaces(&subj);\n  if (!skip_line_end(&subj)) {\n    if (matchlen) { // try rewinding before title\n      subj.pos = beforetitle;\n      skip_spaces(&subj);\n      if (!skip_line_end(&subj)) {\n        return 0;\n      }\n    } else {\n      return 0;\n    }\n  }\n  // insert reference into refmap\n  cmark_reference_create(refmap, &lab, &url, &title);\n  return subj.pos;\n}\n\nunsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser) {\n  return peek_char(parser);\n}\n\nunsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, bufsize_t pos) {\n  return peek_at(parser, pos);\n}\n\nint cmark_inline_parser_is_eof(cmark_inline_parser *parser) {\n  return is_eof(parser);\n}\n\nstatic char *\nmy_strndup (const char *s, size_t n)\n{\n  char *result;\n  size_t len = strlen (s);\n\n  if (n < len)\n    len = n;\n\n  result = (char *) malloc (len + 1);\n  if (!result)\n    return 0;\n\n  result[len] = '\\0';\n  return (char *) memcpy (result, s, len);\n}\n\nchar *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred) {\n  unsigned char c;\n  bufsize_t startpos = parser->pos;\n  bufsize_t len = 0;\n\n  while ((c = peek_char(parser)) && (*pred)(c)) {\n    advance(parser);\n    len++;\n  }\n\n  return my_strndup((const char *) parser->input.data + startpos, len);\n}\n\nvoid cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,\n                                  unsigned char c,\n                                  int can_open,\n                                  int can_close,\n                                  cmark_node *inl_text) {\n  push_delimiter(parser, c, can_open != 0, can_close != 0, inl_text);\n}\n\nvoid cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim) {\n  remove_delimiter(parser, delim);\n}\n\nint cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,\n                                  int max_delims,\n                                  unsigned char c,\n                                  int *left_flanking,\n                                  int *right_flanking,\n                                  int *punct_before,\n                                  int *punct_after) {\n  int numdelims = 0;\n  bufsize_t before_char_pos;\n  int32_t after_char = 0;\n  int32_t before_char = 0;\n  int len;\n  bool space_before, space_after;\n\n  if (parser->pos == 0) {\n    before_char = 10;\n  } else {\n    before_char_pos = parser->pos - 1;\n    // walk back to the beginning of the UTF_8 sequence:\n    while (peek_at(parser, before_char_pos) >> 6 == 2 && before_char_pos > 0) {\n      before_char_pos -= 1;\n    }\n    len = cmark_utf8proc_iterate(parser->input.data + before_char_pos,\n                                 parser->pos - before_char_pos, &before_char);\n    if (len == -1) {\n      before_char = 10;\n    }\n  }\n\n  while (peek_char(parser) == c && numdelims < max_delims) {\n    numdelims++;\n    advance(parser);\n  }\n\n  len = cmark_utf8proc_iterate(parser->input.data + parser->pos,\n                               parser->input.len - parser->pos, &after_char);\n  if (len == -1) {\n    after_char = 10;\n  }\n\n  *punct_before = cmark_utf8proc_is_punctuation(before_char);\n  *punct_after = cmark_utf8proc_is_punctuation(after_char);\n  space_before = cmark_utf8proc_is_space(before_char) != 0;\n  space_after = cmark_utf8proc_is_space(after_char) != 0;\n\n  *left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&\n                  !(*punct_after && !space_before && !*punct_before);\n  *right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&\n                  !(*punct_before && !space_after && !*punct_after);\n\n  return numdelims;\n}\n\nvoid cmark_inline_parser_advance_offset(cmark_inline_parser *parser) {\n  advance(parser);\n}\n\nint cmark_inline_parser_get_offset(cmark_inline_parser *parser) {\n  return parser->pos;\n}\n\nvoid cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset) {\n  parser->pos = offset;\n}\n\nint cmark_inline_parser_get_column(cmark_inline_parser *parser) {\n  return parser->pos + 1 + parser->column_offset + parser->block_offset;\n}\n\ncmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {\n  return &parser->input;\n}\n\nint cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {\n  bracket *b = parser->last_bracket;\n  if (!b) {\n    return 0;\n  }\n  if (image != 0) {\n    return b->in_bracket_image1;\n  } else {\n    return b->in_bracket_image0;\n  }\n}\n\nvoid cmark_node_unput(cmark_node *node, int n) {\n\tnode = node->last_child;\n\twhile (n > 0 && node && node->type == CMARK_NODE_TEXT) {\n\t\tif (node->as.literal.len < n) {\n\t\t\tn -= node->as.literal.len;\n\t\t\tnode->as.literal.len = 0;\n\t\t} else {\n\t\t\tnode->as.literal.len -= n;\n\t\t\tn = 0;\n\t\t}\n\t\tnode = node->prev;\n\t}\n}\n\ndelimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser) {\n  return parser->last_delim;\n}\n\nint cmark_inline_parser_get_line(cmark_inline_parser *parser) {\n  return parser->line;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/inlines.h",
    "content": "#ifndef CMARK_INLINES_H\n#define CMARK_INLINES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"references.h\"\n\ncmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url);\ncmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title);\n\nCMARK_GFM_EXPORT\nvoid cmark_parse_inlines(cmark_parser *parser,\n                         cmark_node *parent,\n                         cmark_map *refmap,\n                         int options);\n\nbufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,\n                                       cmark_map *refmap);\n\nvoid cmark_inlines_add_special_character(unsigned char c, bool emphasis);\nvoid cmark_inlines_remove_special_character(unsigned char c, bool emphasis);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/iterator.c",
    "content": "#include <assert.h>\n#include <stdlib.h>\n\n#include \"config.h\"\n#include \"node.h\"\n#include \"cmark-gfm.h\"\n#include \"iterator.h\"\n\ncmark_iter *cmark_iter_new(cmark_node *root) {\n  if (root == NULL) {\n    return NULL;\n  }\n  cmark_mem *mem = root->content.mem;\n  cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter));\n  iter->mem = mem;\n  iter->root = root;\n  iter->cur.ev_type = CMARK_EVENT_NONE;\n  iter->cur.node = NULL;\n  iter->next.ev_type = CMARK_EVENT_ENTER;\n  iter->next.node = root;\n  return iter;\n}\n\nvoid cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); }\n\nstatic bool S_is_leaf(cmark_node *node) {\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_THEMATIC_BREAK:\n  case CMARK_NODE_CODE_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_SOFTBREAK:\n  case CMARK_NODE_LINEBREAK:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_HTML_INLINE:\n    return 1;\n  }\n  return 0;\n}\n\ncmark_event_type cmark_iter_next(cmark_iter *iter) {\n  cmark_event_type ev_type = iter->next.ev_type;\n  cmark_node *node = iter->next.node;\n\n  iter->cur.ev_type = ev_type;\n  iter->cur.node = node;\n\n  if (ev_type == CMARK_EVENT_DONE) {\n    return ev_type;\n  }\n\n  /* roll forward to next item, setting both fields */\n  if (ev_type == CMARK_EVENT_ENTER && !S_is_leaf(node)) {\n    if (node->first_child == NULL) {\n      /* stay on this node but exit */\n      iter->next.ev_type = CMARK_EVENT_EXIT;\n    } else {\n      iter->next.ev_type = CMARK_EVENT_ENTER;\n      iter->next.node = node->first_child;\n    }\n  } else if (node == iter->root) {\n    /* don't move past root */\n    iter->next.ev_type = CMARK_EVENT_DONE;\n    iter->next.node = NULL;\n  } else if (node->next) {\n    iter->next.ev_type = CMARK_EVENT_ENTER;\n    iter->next.node = node->next;\n  } else if (node->parent) {\n    iter->next.ev_type = CMARK_EVENT_EXIT;\n    iter->next.node = node->parent;\n  } else {\n    assert(false);\n    iter->next.ev_type = CMARK_EVENT_DONE;\n    iter->next.node = NULL;\n  }\n\n  return ev_type;\n}\n\nvoid cmark_iter_reset(cmark_iter *iter, cmark_node *current,\n                      cmark_event_type event_type) {\n  iter->next.ev_type = event_type;\n  iter->next.node = current;\n  cmark_iter_next(iter);\n}\n\ncmark_node *cmark_iter_get_node(cmark_iter *iter) { return iter->cur.node; }\n\ncmark_event_type cmark_iter_get_event_type(cmark_iter *iter) {\n  return iter->cur.ev_type;\n}\n\ncmark_node *cmark_iter_get_root(cmark_iter *iter) { return iter->root; }\n\nvoid cmark_consolidate_text_nodes(cmark_node *root) {\n  if (root == NULL) {\n    return;\n  }\n  cmark_iter *iter = cmark_iter_new(root);\n  cmark_strbuf buf = CMARK_BUF_INIT(iter->mem);\n  cmark_event_type ev_type;\n  cmark_node *cur, *tmp, *next;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT &&\n        cur->next && cur->next->type == CMARK_NODE_TEXT) {\n      cmark_strbuf_clear(&buf);\n      cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);\n      tmp = cur->next;\n      while (tmp && tmp->type == CMARK_NODE_TEXT) {\n        cmark_iter_next(iter); // advance pointer\n        cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len);\n        cur->end_column = tmp->end_column;\n        next = tmp->next;\n        cmark_node_free(tmp);\n        tmp = next;\n      }\n      cmark_chunk_free(iter->mem, &cur->as.literal);\n      cur->as.literal = cmark_chunk_buf_detach(&buf);\n    }\n  }\n\n  cmark_strbuf_free(&buf);\n  cmark_iter_free(iter);\n}\n\nvoid cmark_node_own(cmark_node *root) {\n  if (root == NULL) {\n    return;\n  }\n  cmark_iter *iter = cmark_iter_new(root);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER) {\n      switch (cur->type) {\n      case CMARK_NODE_TEXT:\n      case CMARK_NODE_HTML_INLINE:\n      case CMARK_NODE_CODE:\n      case CMARK_NODE_HTML_BLOCK:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.literal);\n        break;\n      case CMARK_NODE_LINK:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.link.url);\n        cmark_chunk_to_cstr(iter->mem, &cur->as.link.title);\n        break;\n      case CMARK_NODE_CUSTOM_INLINE:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_enter);\n        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_exit);\n        break;\n      }\n    }\n  }\n\n  cmark_iter_free(iter);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/iterator.h",
    "content": "#ifndef CMARK_ITERATOR_H\n#define CMARK_ITERATOR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n\ntypedef struct {\n  cmark_event_type ev_type;\n  cmark_node *node;\n} cmark_iter_state;\n\nstruct cmark_iter {\n  cmark_mem *mem;\n  cmark_node *root;\n  cmark_iter_state cur;\n  cmark_iter_state next;\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/latex.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LIST_NUMBER_STRING_SIZE 20\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,\n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  if (escape == LITERAL) {\n    cmark_render_code_point(renderer, c);\n    return;\n  }\n\n  switch (c) {\n  case 123: // '{'\n  case 125: // '}'\n  case 35:  // '#'\n  case 37:  // '%'\n  case 38:  // '&'\n    cmark_render_ascii(renderer, \"\\\\\");\n    cmark_render_code_point(renderer, c);\n    break;\n  case 36: // '$'\n  case 95: // '_'\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\\\\");\n    }\n    cmark_render_code_point(renderer, c);\n    break;\n  case 45:             // '-'\n    if (nextc == 45) { // prevent ligature\n      cmark_render_ascii(renderer, \"-{}\");\n    } else {\n      cmark_render_ascii(renderer, \"-\");\n    }\n    break;\n  case 126: // '~'\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\\\textasciitilde{}\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 94: // '^'\n    cmark_render_ascii(renderer, \"\\\\^{}\");\n    break;\n  case 92: // '\\\\'\n    if (escape == URL) {\n      // / acts as path sep even on windows:\n      cmark_render_ascii(renderer, \"/\");\n    } else {\n      cmark_render_ascii(renderer, \"\\\\textbackslash{}\");\n    }\n    break;\n  case 124: // '|'\n    cmark_render_ascii(renderer, \"\\\\textbar{}\");\n    break;\n  case 60: // '<'\n    cmark_render_ascii(renderer, \"\\\\textless{}\");\n    break;\n  case 62: // '>'\n    cmark_render_ascii(renderer, \"\\\\textgreater{}\");\n    break;\n  case 91: // '['\n  case 93: // ']'\n    cmark_render_ascii(renderer, \"{\");\n    cmark_render_code_point(renderer, c);\n    cmark_render_ascii(renderer, \"}\");\n    break;\n  case 34: // '\"'\n    cmark_render_ascii(renderer, \"\\\\textquotedbl{}\");\n    // requires \\usepackage[T1]{fontenc}\n    break;\n  case 39: // '\\''\n    cmark_render_ascii(renderer, \"\\\\textquotesingle{}\");\n    // requires \\usepackage{textcomp}\n    break;\n  case 160: // nbsp\n    cmark_render_ascii(renderer, \"~\");\n    break;\n  case 8230: // hellip\n    cmark_render_ascii(renderer, \"\\\\ldots{}\");\n    break;\n  case 8216: // lsquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"`\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8217: // rsquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\'\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8220: // ldquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"``\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8221: // rdquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"''\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8212: // emdash\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"---\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8211: // endash\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"--\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  default:\n    cmark_render_code_point(renderer, c);\n  }\n}\n\ntypedef enum {\n  NO_LINK,\n  URL_AUTOLINK,\n  EMAIL_AUTOLINK,\n  NORMAL_LINK,\n  INTERNAL_LINK\n} link_type;\n\nstatic link_type get_link_type(cmark_node *node) {\n  size_t title_len, url_len;\n  cmark_node *link_text;\n  char *realurl;\n  int realurllen;\n  bool isemail = false;\n\n  if (node->type != CMARK_NODE_LINK) {\n    return NO_LINK;\n  }\n\n  const char *url = cmark_node_get_url(node);\n  cmark_chunk url_chunk = cmark_chunk_literal(url);\n\n  if (url && *url == '#') {\n    return INTERNAL_LINK;\n  }\n\n  url_len = strlen(url);\n  if (url_len == 0 || scan_scheme(&url_chunk, 0) == 0) {\n    return NO_LINK;\n  }\n\n  const char *title = cmark_node_get_title(node);\n  title_len = strlen(title);\n  // if it has a title, we can't treat it as an autolink:\n  if (title_len == 0) {\n\n    link_text = node->first_child;\n    cmark_consolidate_text_nodes(link_text);\n\n    if (!link_text)\n      return NO_LINK;\n\n    realurl = (char *)url;\n    realurllen = (int)url_len;\n    if (strncmp(realurl, \"mailto:\", 7) == 0) {\n      realurl += 7;\n      realurllen -= 7;\n      isemail = true;\n    }\n    if (realurllen == link_text->as.literal.len &&\n        strncmp(realurl, (char *)link_text->as.literal.data,\n                link_text->as.literal.len) == 0) {\n      if (isemail) {\n        return EMAIL_AUTOLINK;\n      } else {\n        return URL_AUTOLINK;\n      }\n    }\n  }\n\n  return NORMAL_LINK;\n}\n\nstatic int S_get_enumlevel(cmark_node *node) {\n  int enumlevel = 0;\n  cmark_node *tmp = node;\n  while (tmp) {\n    if (tmp->type == CMARK_NODE_LIST &&\n        cmark_node_get_list_type(node) == CMARK_ORDERED_LIST) {\n      enumlevel++;\n    }\n    tmp = tmp->parent;\n  }\n  return enumlevel;\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  int enumlevel;\n  char list_number_string[LIST_NUMBER_STRING_SIZE];\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  cmark_list_type list_type;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);\n\n  if (node->extension && node->extension->latex_render_func) {\n    node->extension->latex_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      LIT(\"\\\\begin{quote}\");\n      CR();\n    } else {\n      LIT(\"\\\\end{quote}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    list_type = cmark_node_get_list_type(node);\n    if (entering) {\n      LIT(\"\\\\begin{\");\n      LIT(list_type == CMARK_ORDERED_LIST ? \"enumerate\" : \"itemize\");\n      LIT(\"}\");\n      CR();\n      list_number = cmark_node_get_list_start(node);\n      if (list_number > 1) {\n        enumlevel = S_get_enumlevel(node);\n        // latex normally supports only five levels\n        if (enumlevel >= 1 && enumlevel <= 5) {\n          snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, \"%d\",\n                   list_number);\n          LIT(\"\\\\setcounter{enum\");\n          switch (enumlevel) {\n          case 1: LIT(\"i\"); break;\n          case 2: LIT(\"ii\"); break;\n          case 3: LIT(\"iii\"); break;\n          case 4: LIT(\"iv\"); break;\n          case 5: LIT(\"v\"); break;\n          default: LIT(\"i\"); break;\n\t  }\n          LIT(\"}{\");\n          OUT(list_number_string, false, NORMAL);\n          LIT(\"}\");\n        }\n        CR();\n      }\n    } else {\n      LIT(\"\\\\end{\");\n      LIT(list_type == CMARK_ORDERED_LIST ? \"enumerate\" : \"itemize\");\n      LIT(\"}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      LIT(\"\\\\item \");\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      switch (cmark_node_get_heading_level(node)) {\n      case 1:\n        LIT(\"\\\\section\");\n        break;\n      case 2:\n        LIT(\"\\\\subsection\");\n        break;\n      case 3:\n        LIT(\"\\\\subsubsection\");\n        break;\n      case 4:\n        LIT(\"\\\\paragraph\");\n        break;\n      case 5:\n        LIT(\"\\\\subparagraph\");\n        break;\n      }\n      LIT(\"{\");\n    } else {\n      LIT(\"}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    CR();\n    LIT(\"\\\\begin{verbatim}\");\n    CR();\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    CR();\n    LIT(\"\\\\end{verbatim}\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    CR();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    CR();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    LIT(\"\\\\begin{center}\\\\rule{0.5\\\\linewidth}{\\\\linethickness}\\\\end{center}\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    LIT(\"\\\\\\\\\");\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      LIT(\"\\\\\\\\\");\n      CR();\n    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, NORMAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    LIT(\"\\\\texttt{\");\n    OUT(cmark_node_get_literal(node), false, NORMAL);\n    LIT(\"}\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"\\\\textbf{\");\n      } else {\n        LIT(\"}\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      LIT(\"\\\\emph{\");\n    } else {\n      LIT(\"}\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (entering) {\n      const char *url = cmark_node_get_url(node);\n      // requires \\usepackage{hyperref}\n      switch (get_link_type(node)) {\n      case URL_AUTOLINK:\n        LIT(\"\\\\url{\");\n        OUT(url, false, URL);\n        LIT(\"}\");\n        return 0; // Don't process further nodes to avoid double-rendering artefacts\n      case EMAIL_AUTOLINK:\n        LIT(\"\\\\href{\");\n        OUT(url, false, URL);\n        LIT(\"}\\\\nolinkurl{\");\n        break;\n      case NORMAL_LINK:\n        LIT(\"\\\\href{\");\n        OUT(url, false, URL);\n        LIT(\"}{\");\n        break;\n      case INTERNAL_LINK:\n        LIT(\"\\\\protect\\\\hyperlink{\");\n        OUT(url + 1, false, URL);\n        LIT(\"}{\");\n        break;\n      case NO_LINK:\n        LIT(\"{\"); // error?\n      }\n    } else {\n      LIT(\"}\");\n    }\n\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"\\\\protect\\\\includegraphics{\");\n      // requires \\include{graphicx}\n      OUT(cmark_node_get_url(node), false, URL);\n      LIT(\"}\");\n      return 0;\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    // TODO\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_latex(cmark_node *root, int options, int width) {\n  return cmark_render_latex_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/linked_list.c",
    "content": "#include <stdlib.h>\n\n#include \"cmark-gfm.h\"\n\ncmark_llist *cmark_llist_append(cmark_mem *mem, cmark_llist *head, void *data) {\n  cmark_llist *tmp;\n  cmark_llist *new_node = (cmark_llist *) mem->calloc(1, sizeof(cmark_llist));\n\n  new_node->data = data;\n  new_node->next = NULL;\n\n  if (!head)\n    return new_node;\n\n  for (tmp = head; tmp->next; tmp=tmp->next);\n\n  tmp->next = new_node;\n\n  return head;\n}\n\nvoid cmark_llist_free_full(cmark_mem *mem, cmark_llist *head, cmark_free_func free_func) {\n  cmark_llist *tmp, *prev;\n\n  for (tmp = head; tmp;) {\n    if (free_func)\n      free_func(mem, tmp->data);\n\n    prev = tmp;\n    tmp = tmp->next;\n    mem->free(prev);\n  }\n}\n\nvoid cmark_llist_free(cmark_mem *mem, cmark_llist *head) {\n  cmark_llist_free_full(mem, head, NULL);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/main.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"cmark-gfm-extension_api.h\"\n#include \"syntax_extension.h\"\n#include \"parser.h\"\n#include \"registry.h\"\n\n#include \"../extensions/cmark-gfm-core-extensions.h\"\n\n#if defined(__OpenBSD__)\n#  include <sys/param.h>\n#  if OpenBSD >= 201605\n#    define USE_PLEDGE\n#    include <unistd.h>\n#  endif\n#endif\n\n#if defined(__OpenBSD__)\n#  include <sys/param.h>\n#  if OpenBSD >= 201605\n#    define USE_PLEDGE\n#    include <unistd.h>\n#  endif\n#endif\n\n#if defined(_WIN32) && !defined(__CYGWIN__)\n#include <io.h>\n#include <fcntl.h>\n#endif\n\ntypedef enum {\n  FORMAT_NONE,\n  FORMAT_HTML,\n  FORMAT_XML,\n  FORMAT_MAN,\n  FORMAT_COMMONMARK,\n  FORMAT_PLAINTEXT,\n  FORMAT_LATEX\n} writer_format;\n\nvoid print_usage() {\n  printf(\"Usage:   cmark-gfm [FILE*]\\n\");\n  printf(\"Options:\\n\");\n  printf(\"  --to, -t FORMAT   Specify output format (html, xml, man, \"\n         \"commonmark, plaintext, latex)\\n\");\n  printf(\"  --width WIDTH     Specify wrap width (default 0 = nowrap)\\n\");\n  printf(\"  --sourcepos       Include source position attribute\\n\");\n  printf(\"  --hardbreaks      Treat newlines as hard line breaks\\n\");\n  printf(\"  --nobreaks        Render soft line breaks as spaces\\n\");\n  printf(\"  --unsafe          Render raw HTML and dangerous URLs\\n\");\n  printf(\"  --smart           Use smart punctuation\\n\");\n  printf(\"  --validate-utf8   Replace UTF-8 invalid sequences with U+FFFD\\n\");\n  printf(\"  --github-pre-lang Use GitHub-style <pre lang> for code blocks\\n\");\n  printf(\"  --extension, -e EXTENSION_NAME  Specify an extension name to use\\n\");\n  printf(\"  --list-extensions               List available extensions and quit\\n\");\n  printf(\"  --strikethrough-double-tilde    Only parse strikethrough (if enabled)\\n\");\n  printf(\"                                  with two tildes\\n\");\n  printf(\"  --table-prefer-style-attributes Use style attributes to align table cells\\n\"\n         \"                                  instead of align attributes.\\n\");\n  printf(\"  --full-info-string              Include remainder of code block info\\n\"\n         \"                                  string in a separate attribute.\\n\");\n  printf(\"  --help, -h       Print usage information\\n\");\n  printf(\"  --version        Print version\\n\");\n}\n\nstatic bool print_document(cmark_node *document, writer_format writer,\n                           int options, int width, cmark_parser *parser) {\n  char *result;\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n\n  switch (writer) {\n  case FORMAT_HTML:\n    result = cmark_render_html_with_mem(document, options, parser->syntax_extensions, mem);\n    break;\n  case FORMAT_XML:\n    result = cmark_render_xml_with_mem(document, options, mem);\n    break;\n  case FORMAT_MAN:\n    result = cmark_render_man_with_mem(document, options, width, mem);\n    break;\n  case FORMAT_COMMONMARK:\n    result = cmark_render_commonmark_with_mem(document, options, width, mem);\n    break;\n  case FORMAT_PLAINTEXT:\n    result = cmark_render_plaintext_with_mem(document, options, width, mem);\n    break;\n  case FORMAT_LATEX:\n    result = cmark_render_latex_with_mem(document, options, width, mem);\n    break;\n  default:\n    fprintf(stderr, \"Unknown format %d\\n\", writer);\n    return false;\n  }\n  printf(\"%s\", result);\n  mem->free(result);\n\n  return true;\n}\n\nstatic void print_extensions(void) {\n  cmark_llist *syntax_extensions;\n  cmark_llist *tmp;\n\n  printf (\"Available extensions:\\nfootnotes\\n\");\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n  syntax_extensions = cmark_list_syntax_extensions(mem);\n  for (tmp = syntax_extensions; tmp; tmp=tmp->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n    printf(\"%s\\n\", ext->name);\n  }\n\n  cmark_llist_free(mem, syntax_extensions);\n}\n\nint main(int argc, char *argv[]) {\n  int i, numfps = 0;\n  int *files;\n  char buffer[4096];\n  cmark_parser *parser = NULL;\n  size_t bytes;\n  cmark_node *document = NULL;\n  int width = 0;\n  char *unparsed;\n  writer_format writer = FORMAT_HTML;\n  int options = CMARK_OPT_DEFAULT;\n  int res = 1;\n\n#ifdef USE_PLEDGE\n  if (pledge(\"stdio rpath\", NULL) != 0) {\n    perror(\"pledge\");\n    return 1;\n  }\n#endif\n\n  cmark_gfm_core_extensions_ensure_registered();\n\n#ifdef USE_PLEDGE\n  if (pledge(\"stdio rpath\", NULL) != 0) {\n    perror(\"pledge\");\n    return 1;\n  }\n#endif\n\n#if defined(_WIN32) && !defined(__CYGWIN__)\n  _setmode(_fileno(stdin), _O_BINARY);\n  _setmode(_fileno(stdout), _O_BINARY);\n#endif\n\n  files = (int *)calloc(argc, sizeof(*files));\n\n  for (i = 1; i < argc; i++) {\n    if (strcmp(argv[i], \"--version\") == 0) {\n      printf(\"cmark-gfm %s\", CMARK_GFM_VERSION_STRING);\n      printf(\" - CommonMark with GitHub Flavored Markdown converter\\n(C) 2014-2016 John MacFarlane\\n\");\n      goto success;\n    } else if (strcmp(argv[i], \"--list-extensions\") == 0) {\n      print_extensions();\n      goto success;\n    } else if (strcmp(argv[i], \"--full-info-string\") == 0) {\n      options |= CMARK_OPT_FULL_INFO_STRING;\n    } else if (strcmp(argv[i], \"--table-prefer-style-attributes\") == 0) {\n      options |= CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES;\n    } else if (strcmp(argv[i], \"--strikethrough-double-tilde\") == 0) {\n      options |= CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE;\n    } else if (strcmp(argv[i], \"--sourcepos\") == 0) {\n      options |= CMARK_OPT_SOURCEPOS;\n    } else if (strcmp(argv[i], \"--hardbreaks\") == 0) {\n      options |= CMARK_OPT_HARDBREAKS;\n    } else if (strcmp(argv[i], \"--nobreaks\") == 0) {\n      options |= CMARK_OPT_NOBREAKS;\n    } else if (strcmp(argv[i], \"--smart\") == 0) {\n      options |= CMARK_OPT_SMART;\n    } else if (strcmp(argv[i], \"--github-pre-lang\") == 0) {\n      options |= CMARK_OPT_GITHUB_PRE_LANG;\n    } else if (strcmp(argv[i], \"--unsafe\") == 0) {\n      options |= CMARK_OPT_UNSAFE;\n    } else if (strcmp(argv[i], \"--validate-utf8\") == 0) {\n      options |= CMARK_OPT_VALIDATE_UTF8;\n    } else if (strcmp(argv[i], \"--liberal-html-tag\") == 0) {\n      options |= CMARK_OPT_LIBERAL_HTML_TAG;\n    } else if ((strcmp(argv[i], \"--help\") == 0) ||\n               (strcmp(argv[i], \"-h\") == 0)) {\n      print_usage();\n      goto success;\n    } else if (strcmp(argv[i], \"--width\") == 0) {\n      i += 1;\n      if (i < argc) {\n        width = (int)strtol(argv[i], &unparsed, 10);\n        if (unparsed && strlen(unparsed) > 0) {\n          fprintf(stderr, \"failed parsing width '%s' at '%s'\\n\", argv[i],\n                  unparsed);\n          goto failure;\n        }\n      } else {\n        fprintf(stderr, \"--width requires an argument\\n\");\n        goto failure;\n      }\n    } else if ((strcmp(argv[i], \"-t\") == 0) || (strcmp(argv[i], \"--to\") == 0)) {\n      i += 1;\n      if (i < argc) {\n        if (strcmp(argv[i], \"man\") == 0) {\n          writer = FORMAT_MAN;\n        } else if (strcmp(argv[i], \"html\") == 0) {\n          writer = FORMAT_HTML;\n        } else if (strcmp(argv[i], \"xml\") == 0) {\n          writer = FORMAT_XML;\n        } else if (strcmp(argv[i], \"commonmark\") == 0) {\n          writer = FORMAT_COMMONMARK;\n        } else if (strcmp(argv[i], \"plaintext\") == 0) {\n          writer = FORMAT_PLAINTEXT;\n        } else if (strcmp(argv[i], \"latex\") == 0) {\n          writer = FORMAT_LATEX;\n        } else {\n          fprintf(stderr, \"Unknown format %s\\n\", argv[i]);\n          goto failure;\n        }\n      } else {\n        fprintf(stderr, \"No argument provided for %s\\n\", argv[i - 1]);\n        goto failure;\n      }\n    } else if ((strcmp(argv[i], \"-e\") == 0) || (strcmp(argv[i], \"--extension\") == 0)) {\n      i += 1; // Simpler to handle extensions in a second pass, as we can directly register\n              // them with the parser.\n\n      if (i < argc && strcmp(argv[i], \"footnotes\") == 0) {\n        options |= CMARK_OPT_FOOTNOTES;\n      }\n    } else if (*argv[i] == '-') {\n      print_usage();\n      goto failure;\n    } else { // treat as file argument\n      files[numfps++] = i;\n    }\n  }\n\n#if DEBUG\n  parser = cmark_parser_new(options);\n#else\n  parser = cmark_parser_new_with_mem(options, cmark_get_arena_mem_allocator());\n#endif\n\n  for (i = 1; i < argc; i++) {\n    if ((strcmp(argv[i], \"-e\") == 0) || (strcmp(argv[i], \"--extension\") == 0)) {\n      i += 1;\n      if (i < argc) {\n        if (strcmp(argv[i], \"footnotes\") == 0) {\n          continue;\n        }\n        cmark_syntax_extension *syntax_extension = cmark_find_syntax_extension(argv[i]);\n        if (!syntax_extension) {\n          fprintf(stderr, \"Unknown extension %s\\n\", argv[i]);\n          goto failure;\n        }\n        cmark_parser_attach_syntax_extension(parser, syntax_extension);\n      } else {\n        fprintf(stderr, \"No argument provided for %s\\n\", argv[i - 1]);\n        goto failure;\n      }\n    }\n  }\n\n  for (i = 0; i < numfps; i++) {\n    FILE *fp = fopen(argv[files[i]], \"rb\");\n    if (fp == NULL) {\n      fprintf(stderr, \"Error opening file %s: %s\\n\", argv[files[i]],\n              strerror(errno));\n      goto failure;\n    }\n\n    while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {\n      cmark_parser_feed(parser, buffer, bytes);\n      if (bytes < sizeof(buffer)) {\n        break;\n      }\n    }\n\n    fclose(fp);\n  }\n\n  if (numfps == 0) {\n    while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) {\n      cmark_parser_feed(parser, buffer, bytes);\n      if (bytes < sizeof(buffer)) {\n        break;\n      }\n    }\n  }\n\n#ifdef USE_PLEDGE\n  if (pledge(\"stdio\", NULL) != 0) {\n    perror(\"pledge\");\n    return 1;\n  }\n#endif\n\n  document = cmark_parser_finish(parser);\n\n  if (!document || !print_document(document, writer, options, width, parser))\n    goto failure;\n\nsuccess:\n  res = 0;\n\nfailure:\n\n#if DEBUG\n  if (parser)\n  cmark_parser_free(parser);\n\n  if (document)\n    cmark_node_free(document);\n#else\n  cmark_arena_reset();\n#endif\n\n  cmark_release_plugins();\n\n  free(files);\n\n  return res;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/man.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LIST_NUMBER_SIZE 20\n\n// Functions to convert cmark_nodes to groff man strings.\nstatic void S_outc(cmark_renderer *renderer, cmark_node *node, \n                   cmark_escaping escape, int32_t c,\n                   unsigned char nextc) {\n  (void)(nextc);\n\n  if (escape == LITERAL) {\n    cmark_render_code_point(renderer, c);\n    return;\n  }\n\n  switch (c) {\n  case 46:\n    if (renderer->begin_line) {\n      cmark_render_ascii(renderer, \"\\\\&.\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 39:\n    if (renderer->begin_line) {\n      cmark_render_ascii(renderer, \"\\\\&'\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 45:\n    cmark_render_ascii(renderer, \"\\\\-\");\n    break;\n  case 92:\n    cmark_render_ascii(renderer, \"\\\\e\");\n    break;\n  case 8216: // left single quote\n    cmark_render_ascii(renderer, \"\\\\[oq]\");\n    break;\n  case 8217: // right single quote\n    cmark_render_ascii(renderer, \"\\\\[cq]\");\n    break;\n  case 8220: // left double quote\n    cmark_render_ascii(renderer, \"\\\\[lq]\");\n    break;\n  case 8221: // right double quote\n    cmark_render_ascii(renderer, \"\\\\[rq]\");\n    break;\n  case 8212: // em dash\n    cmark_render_ascii(renderer, \"\\\\[em]\");\n    break;\n  case 8211: // en dash\n    cmark_render_ascii(renderer, \"\\\\[en]\");\n    break;\n  default:\n    cmark_render_code_point(renderer, c);\n  }\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);\n\n  if (node->extension && node->extension->man_render_func) {\n    node->extension->man_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    if (entering) {\n      /* Define a strikethrough macro */\n      /* Commenting out because this makes tests fail\n      LIT(\".de ST\");\n      CR();\n      LIT(\".nr ww \\\\w'\\\\\\\\$1'\");\n      CR();\n      LIT(\"\\\\Z@\\\\v'-.25m'\\\\l'\\\\\\\\n[ww]u'@\\\\\\\\$1\");\n      CR();\n      LIT(\"..\");\n      CR();\n      */\n    }\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      CR();\n      LIT(\".RS\");\n      CR();\n    } else {\n      CR();\n      LIT(\".RE\");\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      CR();\n      LIT(\".IP \");\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"\\\\[bu] 2\");\n      } else {\n        list_number = cmark_node_get_item_index(node);\n        char list_number_s[LIST_NUMBER_SIZE];\n        snprintf(list_number_s, LIST_NUMBER_SIZE, \"\\\"%d.\\\" 4\", list_number);\n        LIT(list_number_s);\n      }\n      CR();\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      CR();\n      LIT(cmark_node_get_heading_level(node) == 1 ? \".SH\" : \".SS\");\n      CR();\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    CR();\n    LIT(\".IP\\n.nf\\n\\\\f[C]\\n\");\n    OUT(cmark_node_get_literal(node), false, NORMAL);\n    CR();\n    LIT(\"\\\\f[]\\n.fi\");\n    CR();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    CR();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    CR();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    CR();\n    LIT(\".PP\\n  *  *  *  *  *\");\n    CR();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (entering) {\n      // no blank line if first paragraph in list:\n      if (node->parent && node->parent->type == CMARK_NODE_ITEM &&\n          node->prev == NULL) {\n        // no blank line or .PP\n      } else {\n        CR();\n        LIT(\".PP\");\n        CR();\n      }\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    LIT(\".PD 0\\n.P\\n.PD\");\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      LIT(\".PD 0\\n.P\\n.PD\");\n      CR();\n    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    LIT(\"\\\\f[C]\");\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    LIT(\"\\\\f[]\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"\\\\f[B]\");\n      } else {\n        LIT(\"\\\\f[]\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      LIT(\"\\\\f[I]\");\n    } else {\n      LIT(\"\\\\f[]\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (!entering) {\n      LIT(\" (\");\n      OUT(cmark_node_get_url(node), allow_wrap, URL);\n      LIT(\")\");\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"[IMAGE: \");\n    } else {\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    // TODO\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_man(cmark_node *root, int options, int width) {\n  return cmark_render_man_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  return cmark_render(mem, root, options, width, S_outc, S_render_node);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/map.c",
    "content": "#include \"map.h\"\n#include \"utf8.h\"\n#include \"parser.h\"\n\n// normalize map label:  collapse internal whitespace to single space,\n// remove leading/trailing whitespace, case fold\n// Return NULL if the label is actually empty (i.e. composed solely from\n// whitespace)\nunsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref) {\n  cmark_strbuf normalized = CMARK_BUF_INIT(mem);\n  unsigned char *result;\n\n  if (ref == NULL)\n    return NULL;\n\n  if (ref->len == 0)\n    return NULL;\n\n  cmark_utf8proc_case_fold(&normalized, ref->data, ref->len);\n  cmark_strbuf_trim(&normalized);\n  cmark_strbuf_normalize_whitespace(&normalized);\n\n  result = cmark_strbuf_detach(&normalized);\n  assert(result);\n\n  if (result[0] == '\\0') {\n    mem->free(result);\n    return NULL;\n  }\n\n  return result;\n}\n\nstatic int\nlabelcmp(const unsigned char *a, const unsigned char *b) {\n  return strcmp((const char *)a, (const char *)b);\n}\n\nstatic int\nrefcmp(const void *p1, const void *p2) {\n  cmark_map_entry *r1 = *(cmark_map_entry **)p1;\n  cmark_map_entry *r2 = *(cmark_map_entry **)p2;\n  int res = labelcmp(r1->label, r2->label);\n  return res ? res : ((int)r1->age - (int)r2->age);\n}\n\nstatic int\nrefsearch(const void *label, const void *p2) {\n  cmark_map_entry *ref = *(cmark_map_entry **)p2;\n  return labelcmp((const unsigned char *)label, ref->label);\n}\n\nstatic void sort_map(cmark_map *map) {\n  size_t i = 0, last = 0, size = map->size;\n  cmark_map_entry *r = map->refs, **sorted = NULL;\n\n  sorted = (cmark_map_entry **)map->mem->calloc(size, sizeof(cmark_map_entry *));\n  while (r) {\n    sorted[i++] = r;\n    r = r->next;\n  }\n\n  qsort(sorted, size, sizeof(cmark_map_entry *), refcmp);\n\n  for (i = 1; i < size; i++) {\n    if (labelcmp(sorted[i]->label, sorted[last]->label) != 0)\n      sorted[++last] = sorted[i];\n  }\n\n  map->sorted = sorted;\n  map->size = last + 1;\n}\n\ncmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label) {\n  cmark_map_entry **ref = NULL;\n  cmark_map_entry *r = NULL;\n  unsigned char *norm;\n\n  if (label->len < 1 || label->len > MAX_LINK_LABEL_LENGTH)\n    return NULL;\n\n  if (map == NULL || !map->size)\n    return NULL;\n\n  norm = normalize_map_label(map->mem, label);\n  if (norm == NULL)\n    return NULL;\n\n  if (!map->sorted)\n    sort_map(map);\n\n  ref = (cmark_map_entry **)bsearch(norm, map->sorted, map->size, sizeof(cmark_map_entry *), refsearch);\n  map->mem->free(norm);\n\n  if (ref != NULL) {\n    r = ref[0];\n    /* Check for expansion limit */\n    if (r->size > map->max_ref_size - map->ref_size)\n      return NULL;\n    map->ref_size += r->size;\n  }\n\n  return r;\n}\n\nvoid cmark_map_free(cmark_map *map) {\n  cmark_map_entry *ref;\n\n  if (map == NULL)\n    return;\n\n  ref = map->refs;\n  while (ref) {\n    cmark_map_entry *next = ref->next;\n    map->free(map, ref);\n    ref = next;\n  }\n\n  map->mem->free(map->sorted);\n  map->mem->free(map);\n}\n\ncmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free) {\n  cmark_map *map = (cmark_map *)mem->calloc(1, sizeof(cmark_map));\n  map->mem = mem;\n  map->free = free;\n  map->max_ref_size = UINT_MAX;\n  return map;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/map.h",
    "content": "#ifndef CMARK_MAP_H\n#define CMARK_MAP_H\n\n#include \"chunk.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_map_entry {\n  struct cmark_map_entry *next;\n  unsigned char *label;\n  size_t age;\n  size_t size;\n};\n\ntypedef struct cmark_map_entry cmark_map_entry;\n\nstruct cmark_map;\n\ntypedef void (*cmark_map_free_f)(struct cmark_map *, cmark_map_entry *);\n\nstruct cmark_map {\n  cmark_mem *mem;\n  cmark_map_entry *refs;\n  cmark_map_entry **sorted;\n  size_t size;\n  size_t ref_size;\n  size_t max_ref_size;\n  cmark_map_free_f free;\n};\n\ntypedef struct cmark_map cmark_map;\n\nunsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref);\ncmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free);\nvoid cmark_map_free(cmark_map *map);\ncmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/node.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"node.h\"\n#include \"syntax_extension.h\"\n\n/**\n * Expensive safety checks are off by default, but can be enabled\n * by calling cmark_enable_safety_checks().\n */\nstatic bool enable_safety_checks = false;\n\nvoid cmark_enable_safety_checks(bool enable) {\n  enable_safety_checks = enable;\n}\n\nstatic void S_node_unlink(cmark_node *node);\n\n#define NODE_MEM(node) cmark_node_mem(node)\n\nvoid cmark_register_node_flag(cmark_node_internal_flags *flags) {\n  static cmark_node_internal_flags nextflag = CMARK_NODE__REGISTER_FIRST;\n\n  // flags should be a pointer to a global variable and this function\n  // should only be called once to initialize its value.\n  if (*flags) {\n    fprintf(stderr, \"flag initialization error in cmark_register_node_flag\\n\");\n    abort();\n  }\n\n  // Check that we haven't run out of bits.\n  if (nextflag == 0) {\n    fprintf(stderr, \"too many flags in cmark_register_node_flag\\n\");\n    abort();\n  }\n\n  *flags = nextflag;\n  nextflag <<= 1;\n}\n\nvoid cmark_init_standard_node_flags(void) {}\n\nbool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {\n  if (child_type == CMARK_NODE_DOCUMENT) {\n      return false;\n    }\n\n  if (node->extension && node->extension->can_contain_func) {\n    return node->extension->can_contain_func(node->extension, node, child_type) != 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n  case CMARK_NODE_BLOCK_QUOTE:\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_ITEM:\n    return CMARK_NODE_TYPE_BLOCK_P(child_type) && child_type != CMARK_NODE_ITEM;\n\n  case CMARK_NODE_LIST:\n    return child_type == CMARK_NODE_ITEM;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return true;\n\n  case CMARK_NODE_PARAGRAPH:\n  case CMARK_NODE_HEADING:\n  case CMARK_NODE_EMPH:\n  case CMARK_NODE_STRONG:\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n  case CMARK_NODE_CUSTOM_INLINE:\n    return CMARK_NODE_TYPE_INLINE_P(child_type);\n\n  default:\n    break;\n  }\n\n  return false;\n}\n\nstatic bool S_can_contain(cmark_node *node, cmark_node *child) {\n  if (node == NULL || child == NULL) {\n    return false;\n  }\n  if (NODE_MEM(node) != NODE_MEM(child)) {\n    return 0;\n  }\n\n  if (enable_safety_checks) {\n    // Verify that child is not an ancestor of node or equal to node.\n    cmark_node *cur = node;\n    do {\n      if (cur == child) {\n        return false;\n      }\n      cur = cur->parent;\n    } while (cur != NULL);\n  }\n\n  return cmark_node_can_contain_type(node, (cmark_node_type) child->type);\n}\n\ncmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type, cmark_mem *mem, cmark_syntax_extension *extension) {\n  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));\n  cmark_strbuf_init(mem, &node->content, 0);\n  node->type = (uint16_t)type;\n  node->extension = extension;\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    node->as.heading.level = 1;\n    break;\n\n  case CMARK_NODE_LIST: {\n    cmark_list *list = &node->as.list;\n    list->list_type = CMARK_BULLET_LIST;\n    list->start = 0;\n    list->tight = false;\n    break;\n  }\n\n  default:\n    break;\n  }\n\n  if (node->extension && node->extension->opaque_alloc_func) {\n    node->extension->opaque_alloc_func(node->extension, mem, node);\n  }\n\n  return node;\n}\n\ncmark_node *cmark_node_new_with_ext(cmark_node_type type, cmark_syntax_extension *extension) {\n  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n  return cmark_node_new_with_mem_and_ext(type, &CMARK_DEFAULT_MEM_ALLOCATOR, extension);\n}\n\ncmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem)\n{\n  return cmark_node_new_with_mem_and_ext(type, mem, NULL);\n}\n\ncmark_node *cmark_node_new(cmark_node_type type) {\n  return cmark_node_new_with_ext(type, NULL);\n}\n\nstatic void free_node_as(cmark_node *node) {\n  switch (node->type) {\n    case CMARK_NODE_CODE_BLOCK:\n    cmark_chunk_free(NODE_MEM(node), &node->as.code.info);\n    cmark_chunk_free(NODE_MEM(node), &node->as.code.literal);\n      break;\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_HTML_INLINE:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_BLOCK:\n    case CMARK_NODE_FOOTNOTE_REFERENCE:\n    case CMARK_NODE_FOOTNOTE_DEFINITION:\n    cmark_chunk_free(NODE_MEM(node), &node->as.literal);\n      break;\n    case CMARK_NODE_LINK:\n    case CMARK_NODE_IMAGE:\n    cmark_chunk_free(NODE_MEM(node), &node->as.link.url);\n    cmark_chunk_free(NODE_MEM(node), &node->as.link.title);\n      break;\n    case CMARK_NODE_CUSTOM_BLOCK:\n    case CMARK_NODE_CUSTOM_INLINE:\n    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_enter);\n    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_exit);\n      break;\n    default:\n      break;\n    }\n}\n\n// Free a cmark_node list and any children.\nstatic void S_free_nodes(cmark_node *e) {\n  cmark_node *next;\n  while (e != NULL) {\n    cmark_strbuf_free(&e->content);\n\n    if (e->user_data && e->user_data_free_func)\n      e->user_data_free_func(NODE_MEM(e), e->user_data);\n\n    if (e->as.opaque && e->extension && e->extension->opaque_free_func)\n      e->extension->opaque_free_func(e->extension, NODE_MEM(e), e);\n\n    free_node_as(e);\n\n    if (e->last_child) {\n      // Splice children into list\n      e->last_child->next = e->next;\n      e->next = e->first_child;\n    }\n    next = e->next;\n    NODE_MEM(e)->free(e);\n    e = next;\n  }\n}\n\nvoid cmark_node_free(cmark_node *node) {\n  S_node_unlink(node);\n  node->next = NULL;\n  S_free_nodes(node);\n}\n\ncmark_node_type cmark_node_get_type(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NODE_NONE;\n  } else {\n    return (cmark_node_type)node->type;\n  }\n}\n\nint cmark_node_set_type(cmark_node * node, cmark_node_type type) {\n  cmark_node_type initial_type;\n\n  if (type == node->type)\n    return 1;\n\n  initial_type = (cmark_node_type) node->type;\n  node->type = (uint16_t)type;\n\n  if (!S_can_contain(node->parent, node)) {\n    node->type = (uint16_t)initial_type;\n    return 0;\n  }\n\n  /* We rollback the type to free the union members appropriately */\n  node->type = (uint16_t)initial_type;\n  free_node_as(node);\n\n  node->type = (uint16_t)type;\n\n  return 1;\n}\n\nconst char *cmark_node_get_type_string(cmark_node *node) {\n  if (node == NULL) {\n    return \"NONE\";\n  }\n\n  if (node->extension && node->extension->get_type_string_func) {\n    return node->extension->get_type_string_func(node->extension, node);\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_NONE:\n    return \"none\";\n  case CMARK_NODE_DOCUMENT:\n    return \"document\";\n  case CMARK_NODE_BLOCK_QUOTE:\n    return \"block_quote\";\n  case CMARK_NODE_LIST:\n    return \"list\";\n  case CMARK_NODE_ITEM:\n    return \"item\";\n  case CMARK_NODE_CODE_BLOCK:\n    return \"code_block\";\n  case CMARK_NODE_HTML_BLOCK:\n    return \"html_block\";\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return \"custom_block\";\n  case CMARK_NODE_PARAGRAPH:\n    return \"paragraph\";\n  case CMARK_NODE_HEADING:\n    return \"heading\";\n  case CMARK_NODE_THEMATIC_BREAK:\n    return \"thematic_break\";\n  case CMARK_NODE_TEXT:\n    return \"text\";\n  case CMARK_NODE_SOFTBREAK:\n    return \"softbreak\";\n  case CMARK_NODE_LINEBREAK:\n    return \"linebreak\";\n  case CMARK_NODE_CODE:\n    return \"code\";\n  case CMARK_NODE_HTML_INLINE:\n    return \"html_inline\";\n  case CMARK_NODE_CUSTOM_INLINE:\n    return \"custom_inline\";\n  case CMARK_NODE_EMPH:\n    return \"emph\";\n  case CMARK_NODE_STRONG:\n    return \"strong\";\n  case CMARK_NODE_LINK:\n    return \"link\";\n  case CMARK_NODE_IMAGE:\n    return \"image\";\n  }\n\n  return \"<unknown>\";\n}\n\ncmark_node *cmark_node_next(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->next;\n  }\n}\n\ncmark_node *cmark_node_previous(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->prev;\n  }\n}\n\ncmark_node *cmark_node_parent(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->parent;\n  }\n}\n\ncmark_node *cmark_node_first_child(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->first_child;\n  }\n}\n\ncmark_node *cmark_node_last_child(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->last_child;\n  }\n}\n\ncmark_node *cmark_node_parent_footnote_def(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->parent_footnote_def;\n  }\n}\n\nvoid *cmark_node_get_user_data(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->user_data;\n  }\n}\n\nint cmark_node_set_user_data(cmark_node *node, void *user_data) {\n  if (node == NULL) {\n    return 0;\n  }\n  node->user_data = user_data;\n  return 1;\n}\n\nint cmark_node_set_user_data_free_func(cmark_node *node,\n                                        cmark_free_func free_func) {\n  if (node == NULL) {\n    return 0;\n  }\n  node->user_data_free_func = free_func;\n  return 1;\n}\n\nconst char *cmark_node_get_literal(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_HTML_INLINE:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.literal);\n\n  case CMARK_NODE_CODE_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.literal);\n\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_literal(cmark_node *node, const char *content) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_HTML_INLINE:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.literal, content);\n    return 1;\n\n  case CMARK_NODE_CODE_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.literal, content);\n    return 1;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_string_content(cmark_node *node) {\n  return (char *) node->content.ptr;\n}\n\nint cmark_node_set_string_content(cmark_node *node, const char *content) {\n  cmark_strbuf_sets(&node->content, content);\n  return true;\n}\n\nint cmark_node_get_heading_level(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    return node->as.heading.level;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nint cmark_node_set_heading_level(cmark_node *node, int level) {\n  if (node == NULL || level < 1 || level > 6) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    node->as.heading.level = level;\n    return 1;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\ncmark_list_type cmark_node_get_list_type(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NO_LIST;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.list_type;\n  } else {\n    return CMARK_NO_LIST;\n  }\n}\n\nint cmark_node_set_list_type(cmark_node *node, cmark_list_type type) {\n  if (!(type == CMARK_BULLET_LIST || type == CMARK_ORDERED_LIST)) {\n    return 0;\n  }\n\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.list_type = type;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\ncmark_delim_type cmark_node_get_list_delim(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NO_DELIM;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.delimiter;\n  } else {\n    return CMARK_NO_DELIM;\n  }\n}\n\nint cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim) {\n  if (!(delim == CMARK_PERIOD_DELIM || delim == CMARK_PAREN_DELIM)) {\n    return 0;\n  }\n\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.delimiter = delim;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_list_start(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.start;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_list_start(cmark_node *node, int start) {\n  if (node == NULL || start < 0) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.start = start;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_list_tight(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.tight;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_list_tight(cmark_node *node, int tight) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.tight = tight == 1;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_item_index(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_ITEM) {\n    return node->as.list.start;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_item_index(cmark_node *node, int idx) {\n  if (node == NULL || idx < 0) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_ITEM) {\n    node->as.list.start = idx;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nconst char *cmark_node_get_fence_info(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.info);\n  } else {\n    return NULL;\n  }\n}\n\nint cmark_node_set_fence_info(cmark_node *node, const char *info) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.info, info);\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    *length = node->as.code.fence_length;\n    *offset = node->as.code.fence_offset;\n    *character = node->as.code.fence_char;\n    return node->as.code.fenced;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_fenced(cmark_node * node, int fenced,\n    int length, int offset, char character) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    node->as.code.fenced = (int8_t)fenced;\n    node->as.code.fence_length = (uint8_t)length;\n    node->as.code.fence_offset = (uint8_t)offset;\n    node->as.code.fence_char = character;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nconst char *cmark_node_get_url(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.url);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_url(cmark_node *node, const char *url) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.url, url);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_title(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.title);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_title(cmark_node *node, const char *title) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.title, title);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_on_enter(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_enter);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_enter, on_enter);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_on_exit(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_exit);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\ncmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  return node->extension;\n}\n\nint cmark_node_set_syntax_extension(cmark_node *node, cmark_syntax_extension *extension) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  node->extension = extension;\n  return 1;\n}\n\nint cmark_node_get_start_line(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->start_line;\n}\n\nint cmark_node_get_start_column(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->start_column;\n}\n\nint cmark_node_get_end_line(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->end_line;\n}\n\nint cmark_node_get_end_column(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->end_column;\n}\n\n// Unlink a node without adjusting its next, prev, and parent pointers.\nstatic void S_node_unlink(cmark_node *node) {\n  if (node == NULL) {\n    return;\n  }\n\n  if (node->prev) {\n    node->prev->next = node->next;\n  }\n  if (node->next) {\n    node->next->prev = node->prev;\n  }\n\n  // Adjust first_child and last_child of parent.\n  cmark_node *parent = node->parent;\n  if (parent) {\n    if (parent->first_child == node) {\n      parent->first_child = node->next;\n    }\n    if (parent->last_child == node) {\n      parent->last_child = node->prev;\n    }\n  }\n}\n\nvoid cmark_node_unlink(cmark_node *node) {\n  S_node_unlink(node);\n\n  node->next = NULL;\n  node->prev = NULL;\n  node->parent = NULL;\n}\n\nint cmark_node_insert_before(cmark_node *node, cmark_node *sibling) {\n  if (node == NULL || sibling == NULL) {\n    return 0;\n  }\n\n  if (!node->parent || !S_can_contain(node->parent, sibling)) {\n    return 0;\n  }\n\n  S_node_unlink(sibling);\n\n  cmark_node *old_prev = node->prev;\n\n  // Insert 'sibling' between 'old_prev' and 'node'.\n  if (old_prev) {\n    old_prev->next = sibling;\n  }\n  sibling->prev = old_prev;\n  sibling->next = node;\n  node->prev = sibling;\n\n  // Set new parent.\n  cmark_node *parent = node->parent;\n  sibling->parent = parent;\n\n  // Adjust first_child of parent if inserted as first child.\n  if (parent && !old_prev) {\n    parent->first_child = sibling;\n  }\n\n  return 1;\n}\n\nint cmark_node_insert_after(cmark_node *node, cmark_node *sibling) {\n  if (node == NULL || sibling == NULL) {\n    return 0;\n  }\n\n  if (!node->parent || !S_can_contain(node->parent, sibling)) {\n    return 0;\n  }\n\n  S_node_unlink(sibling);\n\n  cmark_node *old_next = node->next;\n\n  // Insert 'sibling' between 'node' and 'old_next'.\n  if (old_next) {\n    old_next->prev = sibling;\n  }\n  sibling->next = old_next;\n  sibling->prev = node;\n  node->next = sibling;\n\n  // Set new parent.\n  cmark_node *parent = node->parent;\n  sibling->parent = parent;\n\n  // Adjust last_child of parent if inserted as last child.\n  if (parent && !old_next) {\n    parent->last_child = sibling;\n  }\n\n  return 1;\n}\n\nint cmark_node_replace(cmark_node *oldnode, cmark_node *newnode) {\n  if (!cmark_node_insert_before(oldnode, newnode)) {\n    return 0;\n  }\n  cmark_node_unlink(oldnode);\n  return 1;\n}\n\nint cmark_node_prepend_child(cmark_node *node, cmark_node *child) {\n  if (!S_can_contain(node, child)) {\n    return 0;\n  }\n\n  S_node_unlink(child);\n\n  cmark_node *old_first_child = node->first_child;\n\n  child->next = old_first_child;\n  child->prev = NULL;\n  child->parent = node;\n  node->first_child = child;\n\n  if (old_first_child) {\n    old_first_child->prev = child;\n  } else {\n    // Also set last_child if node previously had no children.\n    node->last_child = child;\n  }\n\n  return 1;\n}\n\nint cmark_node_append_child(cmark_node *node, cmark_node *child) {\n  if (!S_can_contain(node, child)) {\n    return 0;\n  }\n\n  S_node_unlink(child);\n\n  cmark_node *old_last_child = node->last_child;\n\n  child->next = NULL;\n  child->prev = old_last_child;\n  child->parent = node;\n  node->last_child = child;\n\n  if (old_last_child) {\n    old_last_child->next = child;\n  } else {\n    // Also set first_child if node previously had no children.\n    node->first_child = child;\n  }\n\n  return 1;\n}\n\nstatic void S_print_error(FILE *out, cmark_node *node, const char *elem) {\n  if (out == NULL) {\n    return;\n  }\n  fprintf(out, \"Invalid '%s' in node type %s at %d:%d\\n\", elem,\n          cmark_node_get_type_string(node), node->start_line,\n          node->start_column);\n}\n\nint cmark_node_check(cmark_node *node, FILE *out) {\n  cmark_node *cur;\n  int errors = 0;\n\n  if (!node) {\n    return 0;\n  }\n\n  cur = node;\n  for (;;) {\n    if (cur->first_child) {\n      if (cur->first_child->prev != NULL) {\n        S_print_error(out, cur->first_child, \"prev\");\n        cur->first_child->prev = NULL;\n        ++errors;\n      }\n      if (cur->first_child->parent != cur) {\n        S_print_error(out, cur->first_child, \"parent\");\n        cur->first_child->parent = cur;\n        ++errors;\n      }\n      cur = cur->first_child;\n      continue;\n    }\n\n  next_sibling:\n    if (cur == node) {\n      break;\n    }\n    if (cur->next) {\n      if (cur->next->prev != cur) {\n        S_print_error(out, cur->next, \"prev\");\n        cur->next->prev = cur;\n        ++errors;\n      }\n      if (cur->next->parent != cur->parent) {\n        S_print_error(out, cur->next, \"parent\");\n        cur->next->parent = cur->parent;\n        ++errors;\n      }\n      cur = cur->next;\n      continue;\n    }\n\n    if (cur->parent->last_child != cur) {\n      S_print_error(out, cur->parent, \"last_child\");\n      cur->parent->last_child = cur;\n      ++errors;\n    }\n    cur = cur->parent;\n    goto next_sibling;\n  }\n\n  return errors;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/node.h",
    "content": "#ifndef CMARK_NODE_H\n#define CMARK_NODE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdio.h>\n#include <stdint.h>\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n#include \"buffer.h\"\n#include \"chunk.h\"\n\ntypedef struct {\n  cmark_list_type list_type;\n  int marker_offset;\n  int padding;\n  int start;\n  cmark_delim_type delimiter;\n  unsigned char bullet_char;\n  bool tight;\n  bool checked; // For task list extension\n} cmark_list;\n\ntypedef struct {\n  cmark_chunk info;\n  cmark_chunk literal;\n  uint8_t fence_length;\n  uint8_t fence_offset;\n  unsigned char fence_char;\n  int8_t fenced;\n} cmark_code;\n\ntypedef struct {\n  int level;\n  bool setext;\n} cmark_heading;\n\ntypedef struct {\n  cmark_chunk url;\n  cmark_chunk title;\n} cmark_link;\n\ntypedef struct {\n  cmark_chunk on_enter;\n  cmark_chunk on_exit;\n} cmark_custom;\n\nenum cmark_node__internal_flags {\n  CMARK_NODE__OPEN = (1 << 0),\n  CMARK_NODE__LAST_LINE_BLANK = (1 << 1),\n  CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),\n\n  // Extensions can register custom flags by calling `cmark_register_node_flag`.\n  // This is the starting value for the custom flags.\n  CMARK_NODE__REGISTER_FIRST = (1 << 3),\n};\n\ntypedef uint16_t cmark_node_internal_flags;\n\nstruct cmark_node {\n  cmark_strbuf content;\n\n  struct cmark_node *next;\n  struct cmark_node *prev;\n  struct cmark_node *parent;\n  struct cmark_node *first_child;\n  struct cmark_node *last_child;\n\n  void *user_data;\n  cmark_free_func user_data_free_func;\n\n  int start_line;\n  int start_column;\n  int end_line;\n  int end_column;\n  int internal_offset;\n  uint16_t type;\n  cmark_node_internal_flags flags;\n\n  cmark_syntax_extension *extension;\n\n  /**\n   * Used during cmark_render() to cache the most recent non-NULL\n   * extension, if you go up the parent chain like this:\n   *\n   * node->parent->...parent->extension\n   */\n  cmark_syntax_extension *ancestor_extension;\n\n  union {\n    int ref_ix;\n    int def_count;\n  } footnote;\n\n  cmark_node *parent_footnote_def;\n\n  union {\n    cmark_chunk literal;\n    cmark_list list;\n    cmark_code code;\n    cmark_heading heading;\n    cmark_link link;\n    cmark_custom custom;\n    int html_block_type;\n    int cell_index; // For keeping track of TABLE_CELL table alignments\n    void *opaque;\n  } as;\n};\n\n/**\n * Syntax extensions can use this function to register a custom node\n * flag. The flags are stored in the `flags` field of the `cmark_node`\n * struct. The `flags` parameter should be the address of a global variable\n * which will store the flag value.\n */\nCMARK_GFM_EXPORT\nvoid cmark_register_node_flag(cmark_node_internal_flags *flags);\n\n/**\n * DEPRECATED.\n *\n * This function was added in cmark-gfm version 0.29.0.gfm.7, and was\n * required to be called at program start time, which caused\n * backwards-compatibility issues in applications that use cmark-gfm as a\n * library. It is now a no-op.\n */\nCMARK_GFM_EXPORT\nvoid cmark_init_standard_node_flags(void);\n\nstatic CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {\n  return node->content.mem;\n}\nCMARK_GFM_EXPORT int cmark_node_check(cmark_node *node, FILE *out);\n\nstatic CMARK_INLINE bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) {\n\treturn (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_BLOCK;\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_BLOCK_P(cmark_node *node) {\n\treturn node != NULL && CMARK_NODE_TYPE_BLOCK_P((cmark_node_type) node->type);\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) {\n\treturn (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_INLINE;\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {\n\treturn node != NULL && CMARK_NODE_TYPE_INLINE_P((cmark_node_type) node->type);\n}\n\nCMARK_GFM_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);\n\n/**\n * Enable (or disable) extra safety checks. These extra checks cause\n * extra performance overhead (in some cases quadratic), so they are only\n * intended to be used during testing.\n */\nCMARK_GFM_EXPORT void cmark_enable_safety_checks(bool enable);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/parser.h",
    "content": "#ifndef CMARK_PARSER_H\n#define CMARK_PARSER_H\n\n#include <stdio.h>\n#include \"references.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define MAX_LINK_LABEL_LENGTH 1000\n\nstruct cmark_parser {\n  struct cmark_mem *mem;\n  /* A hashtable of urls in the current document for cross-references */\n  struct cmark_map *refmap;\n  /* The root node of the parser, always a CMARK_NODE_DOCUMENT */\n  struct cmark_node *root;\n  /* The last open block after a line is fully processed */\n  struct cmark_node *current;\n  /* See the documentation for cmark_parser_get_line_number() in cmark.h */\n  int line_number;\n  /* See the documentation for cmark_parser_get_offset() in cmark.h */\n  bufsize_t offset;\n  /* See the documentation for cmark_parser_get_column() in cmark.h */\n  bufsize_t column;\n  /* See the documentation for cmark_parser_get_first_nonspace() in cmark.h */\n  bufsize_t first_nonspace;\n  /* See the documentation for cmark_parser_get_first_nonspace_column() in cmark.h */\n  bufsize_t first_nonspace_column;\n  bufsize_t thematic_break_kill_pos;\n  /* See the documentation for cmark_parser_get_indent() in cmark.h */\n  int indent;\n  /* See the documentation for cmark_parser_is_blank() in cmark.h */\n  bool blank;\n  /* See the documentation for cmark_parser_has_partially_consumed_tab() in cmark.h */\n  bool partially_consumed_tab;\n  /* Contains the currently processed line */\n  cmark_strbuf curline;\n  /* See the documentation for cmark_parser_get_last_line_length() in cmark.h */\n  bufsize_t last_line_length;\n  /* FIXME: not sure about the difference with curline */\n  cmark_strbuf linebuf;\n  /* Options set by the user, see the Options section in cmark.h */\n  int options;\n  bool last_buffer_ended_with_cr;\n  size_t total_size;\n  cmark_llist *syntax_extensions;\n  cmark_llist *inline_syntax_extensions;\n  cmark_ispunct_func backslash_ispunct;\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/plaintext.c",
    "content": "#include \"node.h\"\n#include \"syntax_extension.h\"\n#include \"render.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LISTMARKER_SIZE 20\n\n// Functions to convert cmark_nodes to plain text strings.\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, \n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  cmark_render_code_point(renderer, c);\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  cmark_delim_type list_delim;\n  int i;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  char listmarker[LISTMARKER_SIZE];\n  bool first_in_list_item;\n  bufsize_t marker_width;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&\n                    !(CMARK_OPT_HARDBREAKS & options);\n\n  // Don't adjust tight list status til we've started the list.\n  // Otherwise we loose the blank line between a paragraph and\n  // a following list.\n  if (entering) {\n    if (node->parent && node->parent->type == CMARK_NODE_ITEM) {\n      renderer->in_tight_list_item = node->parent->parent->as.list.tight;\n    }\n  } else {\n    if (node->type == CMARK_NODE_LIST) {\n      renderer->in_tight_list_item =\n        node->parent &&\n        node->parent->type == CMARK_NODE_ITEM &&\n        node->parent->parent->as.list.tight;\n    }\n  }\n\n  if (node->extension && node->extension->plaintext_render_func) {\n    node->extension->plaintext_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    break;\n\n  case CMARK_NODE_LIST:\n    if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||\n                                    node->next->type == CMARK_NODE_LIST)) {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n      marker_width = 4;\n    } else {\n      list_number = cmark_node_get_item_index(node);\n      list_delim = cmark_node_get_list_delim(node->parent);\n      // we ensure a width of at least 4 so\n      // we get nice transition from single digits\n      // to double\n      snprintf(listmarker, LISTMARKER_SIZE, \"%d%s%s\", list_number,\n               list_delim == CMARK_PAREN_DELIM ? \")\" : \".\",\n               list_number < 10 ? \"  \" : \" \");\n      marker_width = (bufsize_t)strlen(listmarker);\n    }\n    if (entering) {\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"  - \");\n        renderer->begin_content = true;\n      } else {\n        LIT(listmarker);\n        renderer->begin_content = true;\n      }\n      for (i = marker_width; i--;) {\n        cmark_strbuf_putc(renderer->prefix, ' ');\n      }\n    } else {\n      cmark_strbuf_truncate(renderer->prefix,\n                            renderer->prefix->size - marker_width);\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      renderer->begin_content = true;\n      renderer->no_linebreaks = true;\n    } else {\n      renderer->no_linebreaks = false;\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    first_in_list_item = node->prev == NULL && node->parent &&\n                         node->parent->type == CMARK_NODE_ITEM;\n\n    if (!first_in_list_item) {\n      BLANKLINE();\n    }\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (CMARK_OPT_HARDBREAKS & options) {\n      CR();\n    } else if (!renderer->no_linebreaks && renderer->width == 0 &&\n               !(CMARK_OPT_HARDBREAKS & options) &&\n               !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    break;\n\n  case CMARK_NODE_STRONG:\n    break;\n\n  case CMARK_NODE_EMPH:\n    break;\n\n  case CMARK_NODE_LINK:\n    break;\n\n  case CMARK_NODE_IMAGE:\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      LIT(\"[^\");\n      OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL);\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      renderer->footnote_ix += 1;\n      LIT(\"[^\");\n      char n[32];\n      snprintf(n, sizeof(n), \"%d\", renderer->footnote_ix);\n      OUT(n, false, LITERAL);\n      LIT(\"]: \");\n\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    }\n    break;\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_plaintext(cmark_node *root, int options, int width) {\n  return cmark_render_plaintext_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  if (options & CMARK_OPT_HARDBREAKS) {\n    // disable breaking on width, since it has\n    // a different meaning with OPT_HARDBREAKS\n    width = 0;\n  }\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/plugin.c",
    "content": "#include <stdlib.h>\n\n#include \"plugin.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nint cmark_plugin_register_syntax_extension(cmark_plugin    * plugin,\n                                        cmark_syntax_extension * extension) {\n  plugin->syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, plugin->syntax_extensions, extension);\n  return 1;\n}\n\ncmark_plugin *\ncmark_plugin_new(void) {\n  cmark_plugin *res = (cmark_plugin *) CMARK_DEFAULT_MEM_ALLOCATOR.calloc(1, sizeof(cmark_plugin));\n\n  res->syntax_extensions = NULL;\n\n  return res;\n}\n\nvoid\ncmark_plugin_free(cmark_plugin *plugin) {\n  cmark_llist_free_full(&CMARK_DEFAULT_MEM_ALLOCATOR,\n                        plugin->syntax_extensions,\n                        (cmark_free_func) cmark_syntax_extension_free);\n  CMARK_DEFAULT_MEM_ALLOCATOR.free(plugin);\n}\n\ncmark_llist *\ncmark_plugin_steal_syntax_extensions(cmark_plugin *plugin) {\n  cmark_llist *res = plugin->syntax_extensions;\n\n  plugin->syntax_extensions = NULL;\n  return res;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/plugin.h",
    "content": "#ifndef CMARK_PLUGIN_H\n#define CMARK_PLUGIN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n\n/**\n * cmark_plugin:\n *\n * A plugin structure, which should be filled by plugin's\n * init functions.\n */\nstruct cmark_plugin {\n  cmark_llist *syntax_extensions;\n};\n\ncmark_llist *\ncmark_plugin_steal_syntax_extensions(cmark_plugin *plugin);\n\ncmark_plugin *\ncmark_plugin_new(void);\n\nvoid\ncmark_plugin_free(cmark_plugin *plugin);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/references.c",
    "content": "#include \"cmark-gfm.h\"\n#include \"parser.h\"\n#include \"references.h\"\n#include \"inlines.h\"\n#include \"chunk.h\"\n\nstatic void reference_free(cmark_map *map, cmark_map_entry *_ref) {\n  cmark_reference *ref = (cmark_reference *)_ref;\n  cmark_mem *mem = map->mem;\n  if (ref != NULL) {\n    mem->free(ref->entry.label);\n    cmark_chunk_free(mem, &ref->url);\n    cmark_chunk_free(mem, &ref->title);\n    mem->free(ref);\n  }\n}\n\nvoid cmark_reference_create(cmark_map *map, cmark_chunk *label,\n                            cmark_chunk *url, cmark_chunk *title) {\n  cmark_reference *ref;\n  unsigned char *reflabel = normalize_map_label(map->mem, label);\n\n  /* empty reference name, or composed from only whitespace */\n  if (reflabel == NULL)\n    return;\n\n  assert(map->sorted == NULL);\n\n  ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref));\n  ref->entry.label = reflabel;\n  ref->url = cmark_clean_url(map->mem, url);\n  ref->title = cmark_clean_title(map->mem, title);\n  ref->entry.age = map->size;\n  ref->entry.next = map->refs;\n  ref->entry.size = ref->url.len + ref->title.len;\n\n  map->refs = (cmark_map_entry *)ref;\n  map->size++;\n}\n\ncmark_map *cmark_reference_map_new(cmark_mem *mem) {\n  return cmark_map_new(mem, reference_free);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/references.h",
    "content": "#ifndef CMARK_REFERENCES_H\n#define CMARK_REFERENCES_H\n\n#include \"map.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_reference {\n  cmark_map_entry entry;\n  cmark_chunk url;\n  cmark_chunk title;\n};\n\ntypedef struct cmark_reference cmark_reference;\n\nvoid cmark_reference_create(cmark_map *map, cmark_chunk *label,\n                            cmark_chunk *url, cmark_chunk *title);\ncmark_map *cmark_reference_map_new(cmark_mem *mem);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/registry.c",
    "content": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"syntax_extension.h\"\n#include \"registry.h\"\n#include \"plugin.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nstatic cmark_llist *syntax_extensions = NULL;\n\nvoid cmark_register_plugin(cmark_plugin_init_func reg_fn) {\n  cmark_plugin *plugin = cmark_plugin_new();\n\n  if (!reg_fn(plugin)) {\n    cmark_plugin_free(plugin);\n    return;\n  }\n\n  cmark_llist *syntax_extensions_list = cmark_plugin_steal_syntax_extensions(plugin),\n              *it;\n\n  for (it = syntax_extensions_list; it; it = it->next) {\n    syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions, it->data);\n  }\n\n  cmark_llist_free(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions_list);\n  cmark_plugin_free(plugin);\n}\n\nvoid cmark_release_plugins(void) {\n  if (syntax_extensions) {\n    cmark_llist_free_full(\n        &CMARK_DEFAULT_MEM_ALLOCATOR,\n        syntax_extensions,\n        (cmark_free_func) cmark_syntax_extension_free);\n    syntax_extensions = NULL;\n  }\n}\n\ncmark_llist *cmark_list_syntax_extensions(cmark_mem *mem) {\n  cmark_llist *it;\n  cmark_llist *res = NULL;\n\n  for (it = syntax_extensions; it; it = it->next) {\n    res = cmark_llist_append(mem, res, it->data);\n  }\n  return res;\n}\n\ncmark_syntax_extension *cmark_find_syntax_extension(const char *name) {\n  cmark_llist *tmp;\n\n  for (tmp = syntax_extensions; tmp; tmp = tmp->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n    if (!strcmp(ext->name, name))\n      return ext;\n  }\n  return NULL;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/registry.h",
    "content": "#ifndef CMARK_REGISTRY_H\n#define CMARK_REGISTRY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n#include \"plugin.h\"\n\nCMARK_GFM_EXPORT\nvoid cmark_register_plugin(cmark_plugin_init_func reg_fn);\n\nCMARK_GFM_EXPORT\nvoid cmark_release_plugins(void);\n\nCMARK_GFM_EXPORT\ncmark_llist *cmark_list_syntax_extensions(cmark_mem *mem);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/render.c",
    "content": "#include <stdlib.h>\n#include \"buffer.h\"\n#include \"chunk.h\"\n#include \"cmark-gfm.h\"\n#include \"utf8.h\"\n#include \"render.h\"\n#include \"node.h\"\n#include \"syntax_extension.h\"\n\nstatic CMARK_INLINE void S_cr(cmark_renderer *renderer) {\n  if (renderer->need_cr < 1) {\n    renderer->need_cr = 1;\n  }\n}\n\nstatic CMARK_INLINE void S_blankline(cmark_renderer *renderer) {\n  if (renderer->need_cr < 2) {\n    renderer->need_cr = 2;\n  }\n}\n\nstatic void S_out(cmark_renderer *renderer, cmark_node *node,\n                  const char *source, bool wrap,\n                  cmark_escaping escape) {\n  int length = (int)strlen(source);\n  unsigned char nextc;\n  int32_t c;\n  int i = 0;\n  int last_nonspace;\n  int len;\n  cmark_chunk remainder = cmark_chunk_literal(\"\");\n  int k = renderer->buffer->size - 1;\n\n  cmark_syntax_extension *ext = node->ancestor_extension;\n  if (ext && !ext->commonmark_escape_func)\n    ext = NULL;\n\n  wrap = wrap && !renderer->no_linebreaks;\n\n  if (renderer->in_tight_list_item && renderer->need_cr > 1) {\n    renderer->need_cr = 1;\n  }\n  while (renderer->need_cr) {\n    if (k < 0 || renderer->buffer->ptr[k] == '\\n') {\n      k -= 1;\n    } else {\n      cmark_strbuf_putc(renderer->buffer, '\\n');\n      if (renderer->need_cr > 1) {\n        cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                         renderer->prefix->size);\n      }\n    }\n    renderer->column = 0;\n    renderer->last_breakable = 0;\n    renderer->begin_line = true;\n    renderer->begin_content = true;\n    renderer->need_cr -= 1;\n  }\n\n  while (i < length) {\n    if (renderer->begin_line) {\n      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                       renderer->prefix->size);\n      // note: this assumes prefix is ascii:\n      renderer->column = renderer->prefix->size;\n    }\n\n    len = cmark_utf8proc_iterate((const uint8_t *)source + i, length - i, &c);\n    if (len == -1) { // error condition\n      return;        // return without rendering rest of string\n    }\n\n    if (ext && ext->commonmark_escape_func(ext, node, c))\n      cmark_strbuf_putc(renderer->buffer, '\\\\');\n\n    nextc = source[i + len];\n    if (c == 32 && wrap) {\n      if (!renderer->begin_line) {\n        last_nonspace = renderer->buffer->size;\n        cmark_strbuf_putc(renderer->buffer, ' ');\n        renderer->column += 1;\n        renderer->begin_line = false;\n        renderer->begin_content = false;\n        // skip following spaces\n        while (source[i + 1] == ' ') {\n          i++;\n        }\n        // We don't allow breaks that make a digit the first character\n        // because this causes problems with commonmark output.\n        if (!cmark_isdigit(source[i + 1])) {\n          renderer->last_breakable = last_nonspace;\n        }\n      }\n\n    } else if (escape == LITERAL) {\n      if (c == 10) {\n        cmark_strbuf_putc(renderer->buffer, '\\n');\n        renderer->column = 0;\n        renderer->begin_line = true;\n        renderer->begin_content = true;\n        renderer->last_breakable = 0;\n      } else {\n        cmark_render_code_point(renderer, c);\n        renderer->begin_line = false;\n        // we don't set 'begin_content' to false til we've\n        // finished parsing a digit.  Reason:  in commonmark\n        // we need to escape a potential list marker after\n        // a digit:\n        renderer->begin_content =\n            renderer->begin_content && cmark_isdigit((char)c) == 1;\n      }\n    } else {\n      (renderer->outc)(renderer, node, escape, c, nextc);\n      renderer->begin_line = false;\n      renderer->begin_content =\n          renderer->begin_content && cmark_isdigit((char)c) == 1;\n    }\n\n    // If adding the character went beyond width, look for an\n    // earlier place where the line could be broken:\n    if (renderer->width > 0 && renderer->column > renderer->width &&\n        !renderer->begin_line && renderer->last_breakable > 0) {\n\n      // copy from last_breakable to remainder\n      cmark_chunk_set_cstr(renderer->mem, &remainder,\n                           (char *)renderer->buffer->ptr +\n                               renderer->last_breakable + 1);\n      // truncate at last_breakable\n      cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);\n      // add newline, prefix, and remainder\n      cmark_strbuf_putc(renderer->buffer, '\\n');\n      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                       renderer->prefix->size);\n      cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);\n      renderer->column = renderer->prefix->size + remainder.len;\n      cmark_chunk_free(renderer->mem, &remainder);\n      renderer->last_breakable = 0;\n      renderer->begin_line = false;\n      renderer->begin_content = false;\n    }\n\n    i += len;\n  }\n}\n\n// Assumes no newlines, assumes ascii content:\nvoid cmark_render_ascii(cmark_renderer *renderer, const char *s) {\n  int origsize = renderer->buffer->size;\n  cmark_strbuf_puts(renderer->buffer, s);\n  renderer->column += renderer->buffer->size - origsize;\n}\n\nvoid cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {\n  cmark_utf8proc_encode_char(c, renderer->buffer);\n  renderer->column += 1;\n}\n\nchar *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,\n                   void (*outc)(cmark_renderer *, cmark_node *,\n                                cmark_escaping, int32_t,\n                                unsigned char),\n                   int (*render_node)(cmark_renderer *renderer,\n                                      cmark_node *node,\n                                      cmark_event_type ev_type, int options)) {\n  cmark_strbuf pref = CMARK_BUF_INIT(mem);\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n  char *result;\n  cmark_iter *iter = cmark_iter_new(root);\n\n  cmark_renderer renderer = {mem,   &buf, &pref, 0,           width,\n                             0,     0,    true,  true,        false,\n                             false, outc, S_cr,  S_blankline, S_out,\n                             0};\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (cur->extension) {\n      cur->ancestor_extension = cur->extension;\n    } else if (cur->parent) {\n      cur->ancestor_extension = cur->parent->ancestor_extension;\n    }\n    if (cur->type == CMARK_NODE_ITEM) {\n      // Calculate the list item's index, for the benefit of output formats\n      // like commonmark and plaintext.\n      if (cur->prev) {\n        cmark_node_set_item_index(cur, 1 + cmark_node_get_item_index(cur->prev));\n      } else {\n        cmark_node_set_item_index(cur, cmark_node_get_list_start(cur->parent));\n      }\n    }\n    if (!render_node(&renderer, cur, ev_type, options)) {\n      // a false value causes us to skip processing\n      // the node's contents.  this is used for\n      // autolinks.\n      cmark_iter_reset(iter, cur, CMARK_EVENT_EXIT);\n    }\n  }\n\n  // ensure final newline\n  if (renderer.buffer->size == 0 || renderer.buffer->ptr[renderer.buffer->size - 1] != '\\n') {\n    cmark_strbuf_putc(renderer.buffer, '\\n');\n  }\n\n  result = (char *)cmark_strbuf_detach(renderer.buffer);\n\n  cmark_iter_free(iter);\n  cmark_strbuf_free(renderer.prefix);\n  cmark_strbuf_free(renderer.buffer);\n\n  return result;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/render.h",
    "content": "#ifndef CMARK_RENDER_H\n#define CMARK_RENDER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdlib.h>\n#include \"buffer.h\"\n#include \"chunk.h\"\n\ntypedef enum { LITERAL, NORMAL, TITLE, URL } cmark_escaping;\n\nstruct cmark_renderer {\n  cmark_mem *mem;\n  cmark_strbuf *buffer;\n  cmark_strbuf *prefix;\n  int column;\n  int width;\n  int need_cr;\n  bufsize_t last_breakable;\n  bool begin_line;\n  bool begin_content;\n  bool no_linebreaks;\n  bool in_tight_list_item;\n  void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);\n  void (*cr)(struct cmark_renderer *);\n  void (*blankline)(struct cmark_renderer *);\n  void (*out)(struct cmark_renderer *, cmark_node *, const char *, bool, cmark_escaping);\n  unsigned int footnote_ix;\n};\n\ntypedef struct cmark_renderer cmark_renderer;\n\nstruct cmark_html_renderer {\n  cmark_strbuf *html;\n  cmark_node *plain;\n  cmark_llist *filter_extensions;\n  unsigned int footnote_ix;\n  unsigned int written_footnote_ix;\n  void *opaque;\n};\n\ntypedef struct cmark_html_renderer cmark_html_renderer;\n\nvoid cmark_render_ascii(cmark_renderer *renderer, const char *s);\n\nvoid cmark_render_code_point(cmark_renderer *renderer, uint32_t c);\n\nchar *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,\n                   void (*outc)(cmark_renderer *, cmark_node *,\n                                cmark_escaping, int32_t,\n                                unsigned char),\n                   int (*render_node)(cmark_renderer *renderer,\n                                      cmark_node *node,\n                                      cmark_event_type ev_type, int options));\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/scanners.c",
    "content": "/* Generated by re2c 3.0 */\n#include \"scanners.h\"\n#include \"chunk.h\"\n#include <stdlib.h>\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,\n                   bufsize_t offset) {\n  bufsize_t res;\n  unsigned char *ptr = (unsigned char *)c->data;\n\n  if (ptr == NULL || offset > c->len) {\n    return 0;\n  } else {\n    unsigned char lim = ptr[c->len];\n\n    ptr[c->len] = '\\0';\n    res = scanner(ptr + offset);\n    ptr[c->len] = lim;\n  }\n\n  return res;\n}\n\n// Try to match a scheme including colon.\nbufsize_t _scan_scheme(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych <= '@')\n      goto yy1;\n    if (yych <= 'Z')\n      goto yy3;\n    if (yych <= '`')\n      goto yy1;\n    if (yych <= 'z')\n      goto yy3;\n  yy1:\n    ++p;\n  yy2 : { return 0; }\n  yy3:\n    yych = *(marker = ++p);\n    if (yych <= '/') {\n      if (yych <= '+') {\n        if (yych <= '*')\n          goto yy2;\n      } else {\n        if (yych <= ',')\n          goto yy2;\n        if (yych >= '/')\n          goto yy2;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '9')\n          goto yy4;\n        if (yych <= '@')\n          goto yy2;\n      } else {\n        if (yych <= '`')\n          goto yy2;\n        if (yych >= '{')\n          goto yy2;\n      }\n    }\n  yy4:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy6;\n      } else {\n        if (yych != '/')\n          goto yy6;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych >= 'A')\n          goto yy6;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych <= 'z')\n          goto yy6;\n      }\n    }\n  yy5:\n    p = marker;\n    goto yy2;\n  yy6:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy8;\n        goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n        goto yy8;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n        goto yy8;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych <= 'z')\n          goto yy8;\n        goto yy5;\n      }\n    }\n  yy7:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy8:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych == ':')\n      goto yy7;\n    goto yy5;\n  }\n}\n\n// Try to match URI autolink after first <, returning number of chars matched.\nbufsize_t _scan_autolink_uri(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 0,   128, 0,   128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@')\n      goto yy10;\n    if (yych <= 'Z')\n      goto yy12;\n    if (yych <= '`')\n      goto yy10;\n    if (yych <= 'z')\n      goto yy12;\n  yy10:\n    ++p;\n  yy11 : { return 0; }\n  yy12:\n    yych = *(marker = ++p);\n    if (yych <= '/') {\n      if (yych <= '+') {\n        if (yych <= '*')\n          goto yy11;\n      } else {\n        if (yych <= ',')\n          goto yy11;\n        if (yych >= '/')\n          goto yy11;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '9')\n          goto yy13;\n        if (yych <= '@')\n          goto yy11;\n      } else {\n        if (yych <= '`')\n          goto yy11;\n        if (yych >= '{')\n          goto yy11;\n      }\n    }\n  yy13:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy15;\n      } else {\n        if (yych != '/')\n          goto yy15;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych >= 'A')\n          goto yy15;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy15;\n      }\n    }\n  yy14:\n    p = marker;\n    goto yy11;\n  yy15:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy17;\n        goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n        goto yy17;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n        goto yy17;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy17;\n        goto yy14;\n      }\n    }\n  yy16:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy16;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '<')\n          goto yy14;\n        if (yych <= '>')\n          goto yy18;\n        goto yy14;\n      } else {\n        if (yych <= 0xDF)\n          goto yy19;\n        if (yych <= 0xE0)\n          goto yy20;\n        goto yy21;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy22;\n        if (yych <= 0xEF)\n          goto yy21;\n        goto yy23;\n      } else {\n        if (yych <= 0xF3)\n          goto yy24;\n        if (yych <= 0xF4)\n          goto yy25;\n        goto yy14;\n      }\n    }\n  yy17:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy26;\n        goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n        goto yy26;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n        goto yy26;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy26;\n        goto yy14;\n      }\n    }\n  yy18:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy19:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy16;\n    goto yy14;\n  yy20:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy19;\n    goto yy14;\n  yy21:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy19;\n    goto yy14;\n  yy22:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0x9F)\n      goto yy19;\n    goto yy14;\n  yy23:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy21;\n    goto yy14;\n  yy24:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy21;\n    goto yy14;\n  yy25:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0x8F)\n      goto yy21;\n    goto yy14;\n  yy26:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych == ':')\n      goto yy16;\n    goto yy14;\n  }\n}\n\n// Try to match email autolink after first <, returning num of chars matched.\nbufsize_t _scan_autolink_email(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   128, 0,   128, 128, 128, 128, 128, 0,   0,\n        128, 128, 0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   128, 0,   128, 0,   128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 0,   0,   0,   128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '9') {\n      if (yych <= '\\'') {\n        if (yych == '!')\n          goto yy30;\n        if (yych >= '#')\n          goto yy30;\n      } else {\n        if (yych <= ')')\n          goto yy28;\n        if (yych != ',')\n          goto yy30;\n      }\n    } else {\n      if (yych <= '?') {\n        if (yych == '=')\n          goto yy30;\n        if (yych >= '?')\n          goto yy30;\n      } else {\n        if (yych <= 'Z') {\n          if (yych >= 'A')\n            goto yy30;\n        } else {\n          if (yych <= ']')\n            goto yy28;\n          if (yych <= '~')\n            goto yy30;\n        }\n      }\n    }\n  yy28:\n    ++p;\n  yy29 : { return 0; }\n  yy30:\n    yych = *(marker = ++p);\n    if (yych <= ',') {\n      if (yych <= '\"') {\n        if (yych == '!')\n          goto yy32;\n        goto yy29;\n      } else {\n        if (yych <= '\\'')\n          goto yy32;\n        if (yych <= ')')\n          goto yy29;\n        if (yych <= '+')\n          goto yy32;\n        goto yy29;\n      }\n    } else {\n      if (yych <= '>') {\n        if (yych <= '9')\n          goto yy32;\n        if (yych == '=')\n          goto yy32;\n        goto yy29;\n      } else {\n        if (yych <= 'Z')\n          goto yy32;\n        if (yych <= ']')\n          goto yy29;\n        if (yych <= '~')\n          goto yy32;\n        goto yy29;\n      }\n    }\n  yy31:\n    yych = *++p;\n  yy32:\n    if (yybm[0 + yych] & 128) {\n      goto yy31;\n    }\n    if (yych <= '>')\n      goto yy33;\n    if (yych <= '@')\n      goto yy34;\n  yy33:\n    p = marker;\n    goto yy29;\n  yy34:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy33;\n      if (yych >= ':')\n        goto yy33;\n    } else {\n      if (yych <= 'Z')\n        goto yy35;\n      if (yych <= '`')\n        goto yy33;\n      if (yych >= '{')\n        goto yy33;\n    }\n  yy35:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy36;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy36;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy36;\n        goto yy33;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy38;\n      if (yych <= '/')\n        goto yy33;\n      goto yy39;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy39;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy39;\n        goto yy33;\n      }\n    }\n  yy36:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych <= '-')\n          goto yy38;\n        goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy39;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy39;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy39;\n        goto yy33;\n      }\n    }\n  yy37:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy38:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy40;\n      if (yych <= '/')\n        goto yy33;\n      goto yy41;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy41;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy41;\n        goto yy33;\n      }\n    }\n  yy39:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy41;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy41;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy41;\n        goto yy33;\n      }\n    }\n  yy40:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy42;\n      if (yych <= '/')\n        goto yy33;\n      goto yy43;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy43;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy43;\n        goto yy33;\n      }\n    }\n  yy41:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy43;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy43;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy43;\n        goto yy33;\n      }\n    }\n  yy42:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy44;\n      if (yych <= '/')\n        goto yy33;\n      goto yy45;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy45;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy45;\n        goto yy33;\n      }\n    }\n  yy43:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy45;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy45;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy45;\n        goto yy33;\n      }\n    }\n  yy44:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy46;\n      if (yych <= '/')\n        goto yy33;\n      goto yy47;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy47;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy47;\n        goto yy33;\n      }\n    }\n  yy45:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy47;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy47;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy47;\n        goto yy33;\n      }\n    }\n  yy46:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy48;\n      if (yych <= '/')\n        goto yy33;\n      goto yy49;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy49;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy49;\n        goto yy33;\n      }\n    }\n  yy47:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy49;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy49;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy49;\n        goto yy33;\n      }\n    }\n  yy48:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy50;\n      if (yych <= '/')\n        goto yy33;\n      goto yy51;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy51;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy51;\n        goto yy33;\n      }\n    }\n  yy49:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy51;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy51;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy51;\n        goto yy33;\n      }\n    }\n  yy50:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy52;\n      if (yych <= '/')\n        goto yy33;\n      goto yy53;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy53;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy53;\n        goto yy33;\n      }\n    }\n  yy51:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy53;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy53;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy53;\n        goto yy33;\n      }\n    }\n  yy52:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy54;\n      if (yych <= '/')\n        goto yy33;\n      goto yy55;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy55;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy55;\n        goto yy33;\n      }\n    }\n  yy53:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy55;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy55;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy55;\n        goto yy33;\n      }\n    }\n  yy54:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy56;\n      if (yych <= '/')\n        goto yy33;\n      goto yy57;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy57;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy57;\n        goto yy33;\n      }\n    }\n  yy55:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy57;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy57;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy57;\n        goto yy33;\n      }\n    }\n  yy56:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy58;\n      if (yych <= '/')\n        goto yy33;\n      goto yy59;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy59;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy59;\n        goto yy33;\n      }\n    }\n  yy57:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy59;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy59;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy59;\n        goto yy33;\n      }\n    }\n  yy58:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy60;\n      if (yych <= '/')\n        goto yy33;\n      goto yy61;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy61;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy61;\n        goto yy33;\n      }\n    }\n  yy59:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy61;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy61;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy61;\n        goto yy33;\n      }\n    }\n  yy60:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy62;\n      if (yych <= '/')\n        goto yy33;\n      goto yy63;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy63;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy63;\n        goto yy33;\n      }\n    }\n  yy61:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy63;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy63;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy63;\n        goto yy33;\n      }\n    }\n  yy62:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy64;\n      if (yych <= '/')\n        goto yy33;\n      goto yy65;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy65;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy65;\n        goto yy33;\n      }\n    }\n  yy63:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy65;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy65;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy65;\n        goto yy33;\n      }\n    }\n  yy64:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy66;\n      if (yych <= '/')\n        goto yy33;\n      goto yy67;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy67;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy67;\n        goto yy33;\n      }\n    }\n  yy65:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy67;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy67;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy67;\n        goto yy33;\n      }\n    }\n  yy66:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy68;\n      if (yych <= '/')\n        goto yy33;\n      goto yy69;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy69;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy69;\n        goto yy33;\n      }\n    }\n  yy67:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy69;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy69;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy69;\n        goto yy33;\n      }\n    }\n  yy68:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy70;\n      if (yych <= '/')\n        goto yy33;\n      goto yy71;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy71;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy71;\n        goto yy33;\n      }\n    }\n  yy69:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy71;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy71;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy71;\n        goto yy33;\n      }\n    }\n  yy70:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy72;\n      if (yych <= '/')\n        goto yy33;\n      goto yy73;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy73;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy73;\n        goto yy33;\n      }\n    }\n  yy71:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy73;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy73;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy73;\n        goto yy33;\n      }\n    }\n  yy72:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy74;\n      if (yych <= '/')\n        goto yy33;\n      goto yy75;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy75;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy75;\n        goto yy33;\n      }\n    }\n  yy73:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy75;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy75;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy75;\n        goto yy33;\n      }\n    }\n  yy74:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy76;\n      if (yych <= '/')\n        goto yy33;\n      goto yy77;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy77;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy77;\n        goto yy33;\n      }\n    }\n  yy75:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy77;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy77;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy77;\n        goto yy33;\n      }\n    }\n  yy76:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy78;\n      if (yych <= '/')\n        goto yy33;\n      goto yy79;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy79;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy79;\n        goto yy33;\n      }\n    }\n  yy77:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy79;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy79;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy79;\n        goto yy33;\n      }\n    }\n  yy78:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy80;\n      if (yych <= '/')\n        goto yy33;\n      goto yy81;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy81;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy81;\n        goto yy33;\n      }\n    }\n  yy79:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy81;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy81;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy81;\n        goto yy33;\n      }\n    }\n  yy80:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy82;\n      if (yych <= '/')\n        goto yy33;\n      goto yy83;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy83;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy83;\n        goto yy33;\n      }\n    }\n  yy81:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy83;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy83;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy83;\n        goto yy33;\n      }\n    }\n  yy82:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy84;\n      if (yych <= '/')\n        goto yy33;\n      goto yy85;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy85;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy85;\n        goto yy33;\n      }\n    }\n  yy83:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy85;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy85;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy85;\n        goto yy33;\n      }\n    }\n  yy84:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy86;\n      if (yych <= '/')\n        goto yy33;\n      goto yy87;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy87;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy87;\n        goto yy33;\n      }\n    }\n  yy85:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy87;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy87;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy87;\n        goto yy33;\n      }\n    }\n  yy86:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy88;\n      if (yych <= '/')\n        goto yy33;\n      goto yy89;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy89;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy89;\n        goto yy33;\n      }\n    }\n  yy87:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy89;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy89;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy89;\n        goto yy33;\n      }\n    }\n  yy88:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy90;\n      if (yych <= '/')\n        goto yy33;\n      goto yy91;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy91;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy91;\n        goto yy33;\n      }\n    }\n  yy89:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy91;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy91;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy91;\n        goto yy33;\n      }\n    }\n  yy90:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy92;\n      if (yych <= '/')\n        goto yy33;\n      goto yy93;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy93;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy93;\n        goto yy33;\n      }\n    }\n  yy91:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy93;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy93;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy93;\n        goto yy33;\n      }\n    }\n  yy92:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy94;\n      if (yych <= '/')\n        goto yy33;\n      goto yy95;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy95;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy95;\n        goto yy33;\n      }\n    }\n  yy93:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy95;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy95;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy95;\n        goto yy33;\n      }\n    }\n  yy94:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy96;\n      if (yych <= '/')\n        goto yy33;\n      goto yy97;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy97;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy97;\n        goto yy33;\n      }\n    }\n  yy95:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy97;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy97;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy97;\n        goto yy33;\n      }\n    }\n  yy96:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy98;\n      if (yych <= '/')\n        goto yy33;\n      goto yy99;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy99;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy99;\n        goto yy33;\n      }\n    }\n  yy97:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy99;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy99;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy99;\n        goto yy33;\n      }\n    }\n  yy98:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy100;\n      if (yych <= '/')\n        goto yy33;\n      goto yy101;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy101;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy101;\n        goto yy33;\n      }\n    }\n  yy99:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy101;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy101;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy101;\n        goto yy33;\n      }\n    }\n  yy100:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy102;\n      if (yych <= '/')\n        goto yy33;\n      goto yy103;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy103;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy103;\n        goto yy33;\n      }\n    }\n  yy101:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy103;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy103;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy103;\n        goto yy33;\n      }\n    }\n  yy102:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy104;\n      if (yych <= '/')\n        goto yy33;\n      goto yy105;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy105;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy105;\n        goto yy33;\n      }\n    }\n  yy103:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy105;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy105;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy105;\n        goto yy33;\n      }\n    }\n  yy104:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy106;\n      if (yych <= '/')\n        goto yy33;\n      goto yy107;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy107;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy107;\n        goto yy33;\n      }\n    }\n  yy105:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy107;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy107;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy107;\n        goto yy33;\n      }\n    }\n  yy106:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy108;\n      if (yych <= '/')\n        goto yy33;\n      goto yy109;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy109;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy109;\n        goto yy33;\n      }\n    }\n  yy107:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy109;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy109;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy109;\n        goto yy33;\n      }\n    }\n  yy108:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy110;\n      if (yych <= '/')\n        goto yy33;\n      goto yy111;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy111;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy111;\n        goto yy33;\n      }\n    }\n  yy109:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy111;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy111;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy111;\n        goto yy33;\n      }\n    }\n  yy110:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy112;\n      if (yych <= '/')\n        goto yy33;\n      goto yy113;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy113;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy113;\n        goto yy33;\n      }\n    }\n  yy111:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy113;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy113;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy113;\n        goto yy33;\n      }\n    }\n  yy112:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy114;\n      if (yych <= '/')\n        goto yy33;\n      goto yy115;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy115;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy115;\n        goto yy33;\n      }\n    }\n  yy113:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy115;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy115;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy115;\n        goto yy33;\n      }\n    }\n  yy114:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy116;\n      if (yych <= '/')\n        goto yy33;\n      goto yy117;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy117;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy117;\n        goto yy33;\n      }\n    }\n  yy115:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy117;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy117;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy117;\n        goto yy33;\n      }\n    }\n  yy116:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy118;\n      if (yych <= '/')\n        goto yy33;\n      goto yy119;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy119;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy119;\n        goto yy33;\n      }\n    }\n  yy117:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy119;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy119;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy119;\n        goto yy33;\n      }\n    }\n  yy118:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy120;\n      if (yych <= '/')\n        goto yy33;\n      goto yy121;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy121;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy121;\n        goto yy33;\n      }\n    }\n  yy119:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy121;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy121;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy121;\n        goto yy33;\n      }\n    }\n  yy120:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy122;\n      if (yych <= '/')\n        goto yy33;\n      goto yy123;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy123;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy123;\n        goto yy33;\n      }\n    }\n  yy121:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy123;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy123;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy123;\n        goto yy33;\n      }\n    }\n  yy122:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy124;\n      if (yych <= '/')\n        goto yy33;\n      goto yy125;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy125;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy125;\n        goto yy33;\n      }\n    }\n  yy123:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy125;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy125;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy125;\n        goto yy33;\n      }\n    }\n  yy124:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy126;\n      if (yych <= '/')\n        goto yy33;\n      goto yy127;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy127;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy127;\n        goto yy33;\n      }\n    }\n  yy125:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy127;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy127;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy127;\n        goto yy33;\n      }\n    }\n  yy126:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy128;\n      if (yych <= '/')\n        goto yy33;\n      goto yy129;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy129;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy129;\n        goto yy33;\n      }\n    }\n  yy127:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy129;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy129;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy129;\n        goto yy33;\n      }\n    }\n  yy128:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy130;\n      if (yych <= '/')\n        goto yy33;\n      goto yy131;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy131;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy131;\n        goto yy33;\n      }\n    }\n  yy129:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy131;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy131;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy131;\n        goto yy33;\n      }\n    }\n  yy130:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy132;\n      if (yych <= '/')\n        goto yy33;\n      goto yy133;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy133;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy133;\n        goto yy33;\n      }\n    }\n  yy131:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy133;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy133;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy133;\n        goto yy33;\n      }\n    }\n  yy132:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy134;\n      if (yych <= '/')\n        goto yy33;\n      goto yy135;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy135;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy135;\n        goto yy33;\n      }\n    }\n  yy133:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy135;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy135;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy135;\n        goto yy33;\n      }\n    }\n  yy134:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy136;\n      if (yych <= '/')\n        goto yy33;\n      goto yy137;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy137;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy137;\n        goto yy33;\n      }\n    }\n  yy135:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy137;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy137;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy137;\n        goto yy33;\n      }\n    }\n  yy136:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy138;\n      if (yych <= '/')\n        goto yy33;\n      goto yy139;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy139;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy139;\n        goto yy33;\n      }\n    }\n  yy137:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy139;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy139;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy139;\n        goto yy33;\n      }\n    }\n  yy138:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy140;\n      if (yych <= '/')\n        goto yy33;\n      goto yy141;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy141;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy141;\n        goto yy33;\n      }\n    }\n  yy139:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy141;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy141;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy141;\n        goto yy33;\n      }\n    }\n  yy140:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy142;\n      if (yych <= '/')\n        goto yy33;\n      goto yy143;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy143;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy143;\n        goto yy33;\n      }\n    }\n  yy141:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy143;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy143;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy143;\n        goto yy33;\n      }\n    }\n  yy142:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy144;\n      if (yych <= '/')\n        goto yy33;\n      goto yy145;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy145;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy145;\n        goto yy33;\n      }\n    }\n  yy143:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy145;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy145;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy145;\n        goto yy33;\n      }\n    }\n  yy144:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy146;\n      if (yych <= '/')\n        goto yy33;\n      goto yy147;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy147;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy147;\n        goto yy33;\n      }\n    }\n  yy145:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy147;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy147;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy147;\n        goto yy33;\n      }\n    }\n  yy146:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy148;\n      if (yych <= '/')\n        goto yy33;\n      goto yy149;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy149;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy149;\n        goto yy33;\n      }\n    }\n  yy147:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy149;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy149;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy149;\n        goto yy33;\n      }\n    }\n  yy148:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy150;\n      if (yych <= '/')\n        goto yy33;\n      goto yy151;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy151;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy151;\n        goto yy33;\n      }\n    }\n  yy149:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy151;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy151;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy151;\n        goto yy33;\n      }\n    }\n  yy150:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy152;\n      if (yych <= '/')\n        goto yy33;\n      goto yy153;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy153;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy153;\n        goto yy33;\n      }\n    }\n  yy151:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy153;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy153;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy153;\n        goto yy33;\n      }\n    }\n  yy152:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy154;\n      if (yych <= '/')\n        goto yy33;\n      goto yy155;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy155;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy155;\n        goto yy33;\n      }\n    }\n  yy153:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy155;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy155;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy155;\n        goto yy33;\n      }\n    }\n  yy154:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy156;\n      if (yych <= '/')\n        goto yy33;\n      goto yy157;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy157;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy157;\n        goto yy33;\n      }\n    }\n  yy155:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy157;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy157;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy157;\n        goto yy33;\n      }\n    }\n  yy156:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy33;\n      if (yych <= '9')\n        goto yy158;\n      goto yy33;\n    } else {\n      if (yych <= 'Z')\n        goto yy158;\n      if (yych <= '`')\n        goto yy33;\n      if (yych <= 'z')\n        goto yy158;\n      goto yy33;\n    }\n  yy157:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= '-')\n          goto yy33;\n        goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych >= ':')\n          goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych >= '{')\n          goto yy33;\n      }\n    }\n  yy158:\n    yych = *++p;\n    if (yych == '.')\n      goto yy34;\n    if (yych == '>')\n      goto yy37;\n    goto yy33;\n  }\n}\n\n// Try to match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_html_tag(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   224, 224, 224, 224, 224, 224, 224, 224, 200, 200, 200, 200, 200,\n        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,\n        224, 224, 224, 224, 200, 224, 128, 224, 224, 224, 224, 64,  224, 224,\n        224, 224, 224, 244, 240, 224, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 240, 224, 192, 192, 192, 224, 224, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 224, 224, 224, 224, 240, 192, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 224, 224, 224,\n        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@') {\n      if (yych == '/')\n        goto yy162;\n    } else {\n      if (yych <= 'Z')\n        goto yy163;\n      if (yych <= '`')\n        goto yy160;\n      if (yych <= 'z')\n        goto yy163;\n    }\n  yy160:\n    ++p;\n  yy161 : { return 0; }\n  yy162:\n    yych = *(marker = ++p);\n    if (yych <= '@')\n      goto yy161;\n    if (yych <= 'Z')\n      goto yy164;\n    if (yych <= '`')\n      goto yy161;\n    if (yych <= 'z')\n      goto yy164;\n    goto yy161;\n  yy163:\n    yych = *(marker = ++p);\n    if (yych <= '.') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy161;\n        if (yych <= '\\r')\n          goto yy168;\n        goto yy161;\n      } else {\n        if (yych <= ' ')\n          goto yy168;\n        if (yych == '-')\n          goto yy168;\n        goto yy161;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych <= '9')\n          goto yy168;\n        if (yych == '>')\n          goto yy168;\n        goto yy161;\n      } else {\n        if (yych <= 'Z')\n          goto yy168;\n        if (yych <= '`')\n          goto yy161;\n        if (yych <= 'z')\n          goto yy168;\n        goto yy161;\n      }\n    }\n  yy164:\n    yych = *++p;\n    if (yybm[0 + yych] & 4) {\n      goto yy164;\n    }\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy165;\n      if (yych <= '\\r')\n        goto yy171;\n    } else {\n      if (yych <= ' ')\n        goto yy171;\n      if (yych == '>')\n        goto yy170;\n    }\n  yy165:\n    p = marker;\n    goto yy161;\n  yy166:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych <= '>') {\n      if (yych <= '9') {\n        if (yych == '/')\n          goto yy169;\n        goto yy165;\n      } else {\n        if (yych <= ':')\n          goto yy172;\n        if (yych <= '=')\n          goto yy165;\n        goto yy170;\n      }\n    } else {\n      if (yych <= '^') {\n        if (yych <= '@')\n          goto yy165;\n        if (yych <= 'Z')\n          goto yy172;\n        goto yy165;\n      } else {\n        if (yych == '`')\n          goto yy165;\n        if (yych <= 'z')\n          goto yy172;\n        goto yy165;\n      }\n    }\n  yy167:\n    yych = *++p;\n  yy168:\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych == '-')\n          goto yy167;\n        goto yy165;\n      } else {\n        if (yych <= '/')\n          goto yy169;\n        if (yych <= '9')\n          goto yy167;\n        goto yy165;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= '@')\n          goto yy165;\n        goto yy167;\n      } else {\n        if (yych <= '`')\n          goto yy165;\n        if (yych <= 'z')\n          goto yy167;\n        goto yy165;\n      }\n    }\n  yy169:\n    yych = *++p;\n    if (yych != '>')\n      goto yy165;\n  yy170:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy171:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy165;\n      if (yych <= '\\r')\n        goto yy171;\n      goto yy165;\n    } else {\n      if (yych <= ' ')\n        goto yy171;\n      if (yych == '>')\n        goto yy170;\n      goto yy165;\n    }\n  yy172:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy172;\n    }\n    if (yych <= ',') {\n      if (yych <= '\\r') {\n        if (yych <= 0x08)\n          goto yy165;\n      } else {\n        if (yych != ' ')\n          goto yy165;\n      }\n    } else {\n      if (yych <= '<') {\n        if (yych <= '/')\n          goto yy169;\n        goto yy165;\n      } else {\n        if (yych <= '=')\n          goto yy174;\n        if (yych <= '>')\n          goto yy170;\n        goto yy165;\n      }\n    }\n  yy173:\n    yych = *++p;\n    if (yych <= '<') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy165;\n        if (yych <= '\\r')\n          goto yy173;\n        if (yych <= 0x1F)\n          goto yy165;\n        goto yy173;\n      } else {\n        if (yych <= '/') {\n          if (yych <= '.')\n            goto yy165;\n          goto yy169;\n        } else {\n          if (yych == ':')\n            goto yy172;\n          goto yy165;\n        }\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '=')\n          goto yy174;\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= '@')\n          goto yy165;\n        goto yy172;\n      } else {\n        if (yych <= '_') {\n          if (yych <= '^')\n            goto yy165;\n          goto yy172;\n        } else {\n          if (yych <= '`')\n            goto yy165;\n          if (yych <= 'z')\n            goto yy172;\n          goto yy165;\n        }\n      }\n    }\n  yy174:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy175;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\"') {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= ' ')\n          goto yy174;\n        goto yy176;\n      } else {\n        if (yych <= '\\'')\n          goto yy177;\n        if (yych <= 0xC1)\n          goto yy165;\n        if (yych <= 0xDF)\n          goto yy178;\n        goto yy179;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy181;\n        goto yy180;\n      } else {\n        if (yych <= 0xF0)\n          goto yy182;\n        if (yych <= 0xF3)\n          goto yy183;\n        if (yych <= 0xF4)\n          goto yy184;\n        goto yy165;\n      }\n    }\n  yy175:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy175;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= ' ')\n          goto yy166;\n        goto yy165;\n      } else {\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= 0xC1)\n          goto yy165;\n        if (yych <= 0xDF)\n          goto yy178;\n        goto yy179;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy181;\n        goto yy180;\n      } else {\n        if (yych <= 0xF0)\n          goto yy182;\n        if (yych <= 0xF3)\n          goto yy183;\n        if (yych <= 0xF4)\n          goto yy184;\n        goto yy165;\n      }\n    }\n  yy176:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy176;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= '\"')\n          goto yy185;\n        goto yy165;\n      } else {\n        if (yych <= 0xDF)\n          goto yy186;\n        if (yych <= 0xE0)\n          goto yy187;\n        goto yy188;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy189;\n        if (yych <= 0xEF)\n          goto yy188;\n        goto yy190;\n      } else {\n        if (yych <= 0xF3)\n          goto yy191;\n        if (yych <= 0xF4)\n          goto yy192;\n        goto yy165;\n      }\n    }\n  yy177:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy177;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= '\\'')\n          goto yy185;\n        goto yy165;\n      } else {\n        if (yych <= 0xDF)\n          goto yy193;\n        if (yych <= 0xE0)\n          goto yy194;\n        goto yy195;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy196;\n        if (yych <= 0xEF)\n          goto yy195;\n        goto yy197;\n      } else {\n        if (yych <= 0xF3)\n          goto yy198;\n        if (yych <= 0xF4)\n          goto yy199;\n        goto yy165;\n      }\n    }\n  yy178:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy175;\n    goto yy165;\n  yy179:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy178;\n    goto yy165;\n  yy180:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy178;\n    goto yy165;\n  yy181:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy178;\n    goto yy165;\n  yy182:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy180;\n    goto yy165;\n  yy183:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy180;\n    goto yy165;\n  yy184:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy180;\n    goto yy165;\n  yy185:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych == '/')\n      goto yy169;\n    if (yych == '>')\n      goto yy170;\n    goto yy165;\n  yy186:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy176;\n    goto yy165;\n  yy187:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy186;\n    goto yy165;\n  yy188:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy186;\n    goto yy165;\n  yy189:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy186;\n    goto yy165;\n  yy190:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy188;\n    goto yy165;\n  yy191:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy188;\n    goto yy165;\n  yy192:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy188;\n    goto yy165;\n  yy193:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy177;\n    goto yy165;\n  yy194:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy193;\n    goto yy165;\n  yy195:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy193;\n    goto yy165;\n  yy196:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy193;\n    goto yy165;\n  yy197:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy195;\n    goto yy165;\n  yy198:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy195;\n    goto yy165;\n  yy199:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy195;\n    goto yy165;\n  }\n}\n\n// Try to (liberally) match an HTML tag after first <, returning num of chars\n// matched.\nbufsize_t _scan_liberal_html_tag(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64,  64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xE0) {\n      if (yych <= '\\n') {\n        if (yych <= 0x00)\n          goto yy201;\n        if (yych <= '\\t')\n          goto yy203;\n      } else {\n        if (yych <= 0x7F)\n          goto yy203;\n        if (yych <= 0xC1)\n          goto yy201;\n        if (yych <= 0xDF)\n          goto yy204;\n        goto yy205;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy207;\n        goto yy206;\n      } else {\n        if (yych <= 0xF0)\n          goto yy208;\n        if (yych <= 0xF3)\n          goto yy209;\n        if (yych <= 0xF4)\n          goto yy210;\n      }\n    }\n  yy201:\n    ++p;\n  yy202 : { return 0; }\n  yy203:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy202;\n      if (yych <= '\\t')\n        goto yy212;\n      goto yy202;\n    } else {\n      if (yych <= 0x7F)\n        goto yy212;\n      if (yych <= 0xC1)\n        goto yy202;\n      if (yych <= 0xF4)\n        goto yy212;\n      goto yy202;\n    }\n  yy204:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy211;\n    goto yy202;\n  yy205:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy202;\n  yy206:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy202;\n  yy207:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0x9F)\n      goto yy216;\n    goto yy202;\n  yy208:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy202;\n  yy209:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy202;\n  yy210:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0x8F)\n      goto yy218;\n    goto yy202;\n  yy211:\n    yych = *++p;\n  yy212:\n    if (yybm[0 + yych] & 64) {\n      goto yy211;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy213;\n        if (yych <= '>')\n          goto yy214;\n      } else {\n        if (yych <= 0xDF)\n          goto yy216;\n        if (yych <= 0xE0)\n          goto yy217;\n        goto yy218;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy219;\n        if (yych <= 0xEF)\n          goto yy218;\n        goto yy220;\n      } else {\n        if (yych <= 0xF3)\n          goto yy221;\n        if (yych <= 0xF4)\n          goto yy222;\n      }\n    }\n  yy213:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy202;\n    } else {\n      goto yy215;\n    }\n  yy214:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy211;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy215;\n        if (yych <= '>')\n          goto yy214;\n      } else {\n        if (yych <= 0xDF)\n          goto yy216;\n        if (yych <= 0xE0)\n          goto yy217;\n        goto yy218;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy219;\n        if (yych <= 0xEF)\n          goto yy218;\n        goto yy220;\n      } else {\n        if (yych <= 0xF3)\n          goto yy221;\n        if (yych <= 0xF4)\n          goto yy222;\n      }\n    }\n  yy215 : { return (bufsize_t)(p - start); }\n  yy216:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy211;\n    goto yy213;\n  yy217:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy213;\n  yy218:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy213;\n  yy219:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0x9F)\n      goto yy216;\n    goto yy213;\n  yy220:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy213;\n  yy221:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy213;\n  yy222:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0x8F)\n      goto yy218;\n    goto yy213;\n  }\n}\n\nbufsize_t _scan_html_comment(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '-')\n      goto yy225;\n    ++p;\n  yy224 : { return 0; }\n  yy225:\n    yych = *(marker = ++p);\n    if (yych != '-')\n      goto yy224;\n  yy226:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy226;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '-')\n          goto yy228;\n      } else {\n        if (yych <= 0xDF)\n          goto yy229;\n        if (yych <= 0xE0)\n          goto yy230;\n        goto yy231;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy232;\n        if (yych <= 0xEF)\n          goto yy231;\n        goto yy233;\n      } else {\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n      }\n    }\n  yy227:\n    p = marker;\n    goto yy224;\n  yy228:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy226;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '-')\n          goto yy236;\n        goto yy227;\n      } else {\n        if (yych <= 0xDF)\n          goto yy229;\n        if (yych <= 0xE0)\n          goto yy230;\n        goto yy231;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy232;\n        if (yych <= 0xEF)\n          goto yy231;\n        goto yy233;\n      } else {\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n        goto yy227;\n      }\n    }\n  yy229:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy226;\n    goto yy227;\n  yy230:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy229;\n    goto yy227;\n  yy231:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy229;\n    goto yy227;\n  yy232:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0x9F)\n      goto yy229;\n    goto yy227;\n  yy233:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy231;\n    goto yy227;\n  yy234:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy231;\n    goto yy227;\n  yy235:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0x8F)\n      goto yy231;\n    goto yy227;\n  yy236:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '=')\n          goto yy226;\n      } else {\n        if (yych <= 0x7F)\n          goto yy226;\n        if (yych <= 0xC1)\n          goto yy227;\n        if (yych <= 0xDF)\n          goto yy229;\n        goto yy230;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy232;\n        goto yy231;\n      } else {\n        if (yych <= 0xF0)\n          goto yy233;\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n        goto yy227;\n      }\n    }\n    ++p;\n    { return (bufsize_t)(p - start); }\n  }\n}\n\nbufsize_t _scan_html_pi(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 128) {\n      goto yy240;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy238;\n        if (yych <= '?')\n          goto yy243;\n      } else {\n        if (yych <= 0xDF)\n          goto yy244;\n        if (yych <= 0xE0)\n          goto yy245;\n        goto yy246;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy247;\n        if (yych <= 0xEF)\n          goto yy246;\n        goto yy248;\n      } else {\n        if (yych <= 0xF3)\n          goto yy249;\n        if (yych <= 0xF4)\n          goto yy250;\n      }\n    }\n  yy238:\n    ++p;\n  yy239 : { return 0; }\n  yy240:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n  yy241:\n    if (yybm[0 + yych] & 128) {\n      goto yy240;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy242;\n        if (yych <= '?')\n          goto yy251;\n      } else {\n        if (yych <= 0xDF)\n          goto yy253;\n        if (yych <= 0xE0)\n          goto yy254;\n        goto yy255;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy256;\n        if (yych <= 0xEF)\n          goto yy255;\n        goto yy257;\n      } else {\n        if (yych <= 0xF3)\n          goto yy258;\n        if (yych <= 0xF4)\n          goto yy259;\n      }\n    }\n  yy242 : { return (bufsize_t)(p - start); }\n  yy243:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= '?') {\n      if (yych <= 0x00)\n        goto yy239;\n      if (yych <= '=')\n        goto yy241;\n      if (yych <= '>')\n        goto yy239;\n      goto yy240;\n    } else {\n      if (yych <= 0x7F)\n        goto yy241;\n      if (yych <= 0xC1)\n        goto yy239;\n      if (yych <= 0xF4)\n        goto yy241;\n      goto yy239;\n    }\n  yy244:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy240;\n    goto yy239;\n  yy245:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy239;\n  yy246:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy239;\n  yy247:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0x9F)\n      goto yy253;\n    goto yy239;\n  yy248:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy239;\n  yy249:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy239;\n  yy250:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0x8F)\n      goto yy255;\n    goto yy239;\n  yy251:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy252;\n        if (yych <= '=')\n          goto yy240;\n      } else {\n        if (yych <= 0x7F)\n          goto yy240;\n        if (yych <= 0xC1)\n          goto yy252;\n        if (yych <= 0xDF)\n          goto yy253;\n        goto yy254;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy256;\n        goto yy255;\n      } else {\n        if (yych <= 0xF0)\n          goto yy257;\n        if (yych <= 0xF3)\n          goto yy258;\n        if (yych <= 0xF4)\n          goto yy259;\n      }\n    }\n  yy252:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy242;\n    } else {\n      goto yy239;\n    }\n  yy253:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy240;\n    goto yy252;\n  yy254:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy252;\n  yy255:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy252;\n  yy256:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0x9F)\n      goto yy253;\n    goto yy252;\n  yy257:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy252;\n  yy258:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy252;\n  yy259:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0x8F)\n      goto yy255;\n    goto yy252;\n  }\n}\n\nbufsize_t _scan_html_declaration(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  0,   64,  64,  192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@')\n      goto yy261;\n    if (yych <= 'Z')\n      goto yy263;\n  yy261:\n    ++p;\n  yy262 : { return 0; }\n  yy263:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy266;\n    }\n    if (yych <= 0x08)\n      goto yy262;\n    if (yych <= '\\r')\n      goto yy264;\n    if (yych != ' ')\n      goto yy262;\n  yy264:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy264;\n    }\n    if (yych <= 0xED) {\n      if (yych <= 0xDF) {\n        if (yych >= 0xC2)\n          goto yy268;\n      } else {\n        if (yych <= 0xE0)\n          goto yy269;\n        if (yych <= 0xEC)\n          goto yy270;\n        goto yy271;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xEF)\n          goto yy270;\n        goto yy272;\n      } else {\n        if (yych <= 0xF3)\n          goto yy273;\n        if (yych <= 0xF4)\n          goto yy274;\n      }\n    }\n  yy265 : { return (bufsize_t)(p - start); }\n  yy266:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy266;\n    }\n    if (yych <= 0x08)\n      goto yy267;\n    if (yych <= '\\r')\n      goto yy264;\n    if (yych == ' ')\n      goto yy264;\n  yy267:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy262;\n    } else {\n      goto yy265;\n    }\n  yy268:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy264;\n    goto yy267;\n  yy269:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy268;\n    goto yy267;\n  yy270:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy268;\n    goto yy267;\n  yy271:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0x9F)\n      goto yy268;\n    goto yy267;\n  yy272:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy270;\n    goto yy267;\n  yy273:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy270;\n    goto yy267;\n  yy274:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0x8F)\n      goto yy270;\n    goto yy267;\n  }\n}\n\nbufsize_t _scan_html_cdata(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == 'C')\n      goto yy277;\n    if (yych == 'c')\n      goto yy277;\n    ++p;\n  yy276 : { return 0; }\n  yy277:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'D')\n      goto yy278;\n    if (yych != 'd')\n      goto yy276;\n  yy278:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy280;\n    if (yych == 'a')\n      goto yy280;\n  yy279:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy276;\n    } else {\n      goto yy284;\n    }\n  yy280:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy281;\n    if (yych != 't')\n      goto yy279;\n  yy281:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy282;\n    if (yych != 'a')\n      goto yy279;\n  yy282:\n    yych = *++p;\n    if (yych != '[')\n      goto yy279;\n  yy283:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy283;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy284;\n        if (yych <= ']')\n          goto yy285;\n      } else {\n        if (yych <= 0xDF)\n          goto yy286;\n        if (yych <= 0xE0)\n          goto yy287;\n        goto yy288;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy289;\n        if (yych <= 0xEF)\n          goto yy288;\n        goto yy290;\n      } else {\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n      }\n    }\n  yy284 : { return (bufsize_t)(p - start); }\n  yy285:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy283;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy279;\n        if (yych <= ']')\n          goto yy293;\n        goto yy279;\n      } else {\n        if (yych <= 0xDF)\n          goto yy286;\n        if (yych <= 0xE0)\n          goto yy287;\n        goto yy288;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy289;\n        if (yych <= 0xEF)\n          goto yy288;\n        goto yy290;\n      } else {\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n        goto yy279;\n      }\n    }\n  yy286:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy283;\n    goto yy279;\n  yy287:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy286;\n    goto yy279;\n  yy288:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy286;\n    goto yy279;\n  yy289:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0x9F)\n      goto yy286;\n    goto yy279;\n  yy290:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy288;\n    goto yy279;\n  yy291:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy288;\n    goto yy279;\n  yy292:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0x8F)\n      goto yy288;\n    goto yy279;\n  yy293:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy279;\n        if (yych <= '=')\n          goto yy283;\n        goto yy279;\n      } else {\n        if (yych <= 0x7F)\n          goto yy283;\n        if (yych <= 0xC1)\n          goto yy279;\n        if (yych <= 0xDF)\n          goto yy286;\n        goto yy287;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy289;\n        goto yy288;\n      } else {\n        if (yych <= 0xF0)\n          goto yy290;\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n        goto yy279;\n      }\n    }\n  }\n}\n\n// Try to match an HTML block tag start line, returning\n// an integer code for the type of block (1-6, matching the spec).\n// #7 is handled by a separate function, below.\nbufsize_t _scan_html_block_start(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych == '<')\n      goto yy296;\n    ++p;\n  yy295 : { return 0; }\n  yy296:\n    yych = *(marker = ++p);\n    switch (yych) {\n    case '!':\n      goto yy297;\n    case '/':\n      goto yy299;\n    case '?':\n      goto yy300;\n    case 'A':\n    case 'a':\n      goto yy301;\n    case 'B':\n    case 'b':\n      goto yy302;\n    case 'C':\n    case 'c':\n      goto yy303;\n    case 'D':\n    case 'd':\n      goto yy304;\n    case 'F':\n    case 'f':\n      goto yy305;\n    case 'H':\n    case 'h':\n      goto yy306;\n    case 'I':\n    case 'i':\n      goto yy307;\n    case 'L':\n    case 'l':\n      goto yy308;\n    case 'M':\n    case 'm':\n      goto yy309;\n    case 'N':\n    case 'n':\n      goto yy310;\n    case 'O':\n    case 'o':\n      goto yy311;\n    case 'P':\n    case 'p':\n      goto yy312;\n    case 'S':\n    case 's':\n      goto yy313;\n    case 'T':\n    case 't':\n      goto yy314;\n    case 'U':\n    case 'u':\n      goto yy315;\n    default:\n      goto yy295;\n    }\n  yy297:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych == '-')\n        goto yy316;\n    } else {\n      if (yych <= 'Z')\n        goto yy317;\n      if (yych <= '[')\n        goto yy318;\n    }\n  yy298:\n    p = marker;\n    goto yy295;\n  yy299:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy301;\n    case 'B':\n    case 'b':\n      goto yy302;\n    case 'C':\n    case 'c':\n      goto yy303;\n    case 'D':\n    case 'd':\n      goto yy304;\n    case 'F':\n    case 'f':\n      goto yy305;\n    case 'H':\n    case 'h':\n      goto yy306;\n    case 'I':\n    case 'i':\n      goto yy307;\n    case 'L':\n    case 'l':\n      goto yy308;\n    case 'M':\n    case 'm':\n      goto yy309;\n    case 'N':\n    case 'n':\n      goto yy310;\n    case 'O':\n    case 'o':\n      goto yy311;\n    case 'P':\n    case 'p':\n      goto yy319;\n    case 'S':\n    case 's':\n      goto yy320;\n    case 'T':\n    case 't':\n      goto yy321;\n    case 'U':\n    case 'u':\n      goto yy315;\n    default:\n      goto yy298;\n    }\n  yy300:\n    ++p;\n    { return 3; }\n  yy301:\n    yych = *++p;\n    if (yych <= 'S') {\n      if (yych <= 'D') {\n        if (yych <= 'C')\n          goto yy298;\n        goto yy322;\n      } else {\n        if (yych <= 'Q')\n          goto yy298;\n        if (yych <= 'R')\n          goto yy323;\n        goto yy324;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych == 'd')\n          goto yy322;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy323;\n        if (yych <= 's')\n          goto yy324;\n        goto yy298;\n      }\n    }\n  yy302:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych <= 'K') {\n        if (yych == 'A')\n          goto yy325;\n        goto yy298;\n      } else {\n        if (yych <= 'L')\n          goto yy326;\n        if (yych <= 'N')\n          goto yy298;\n        goto yy327;\n      }\n    } else {\n      if (yych <= 'k') {\n        if (yych == 'a')\n          goto yy325;\n        goto yy298;\n      } else {\n        if (yych <= 'l')\n          goto yy326;\n        if (yych == 'o')\n          goto yy327;\n        goto yy298;\n      }\n    }\n  yy303:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych <= 'D') {\n        if (yych == 'A')\n          goto yy328;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy329;\n        if (yych <= 'N')\n          goto yy298;\n        goto yy330;\n      }\n    } else {\n      if (yych <= 'd') {\n        if (yych == 'a')\n          goto yy328;\n        goto yy298;\n      } else {\n        if (yych <= 'e')\n          goto yy329;\n        if (yych == 'o')\n          goto yy330;\n        goto yy298;\n      }\n    }\n  yy304:\n    yych = *++p;\n    switch (yych) {\n    case 'D':\n    case 'L':\n    case 'T':\n    case 'd':\n    case 'l':\n    case 't':\n      goto yy331;\n    case 'E':\n    case 'e':\n      goto yy332;\n    case 'I':\n    case 'i':\n      goto yy333;\n    default:\n      goto yy298;\n    }\n  yy305:\n    yych = *++p;\n    if (yych <= 'R') {\n      if (yych <= 'N') {\n        if (yych == 'I')\n          goto yy334;\n        goto yy298;\n      } else {\n        if (yych <= 'O')\n          goto yy335;\n        if (yych <= 'Q')\n          goto yy298;\n        goto yy336;\n      }\n    } else {\n      if (yych <= 'n') {\n        if (yych == 'i')\n          goto yy334;\n        goto yy298;\n      } else {\n        if (yych <= 'o')\n          goto yy335;\n        if (yych == 'r')\n          goto yy336;\n        goto yy298;\n      }\n    }\n  yy306:\n    yych = *++p;\n    if (yych <= 'S') {\n      if (yych <= 'D') {\n        if (yych <= '0')\n          goto yy298;\n        if (yych <= '6')\n          goto yy331;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy337;\n        if (yych == 'R')\n          goto yy331;\n        goto yy298;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych <= 'T')\n          goto yy338;\n        if (yych == 'e')\n          goto yy337;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy331;\n        if (yych == 't')\n          goto yy338;\n        goto yy298;\n      }\n    }\n  yy307:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy339;\n    if (yych == 'f')\n      goto yy339;\n    goto yy298;\n  yy308:\n    yych = *++p;\n    if (yych <= 'I') {\n      if (yych == 'E')\n        goto yy340;\n      if (yych <= 'H')\n        goto yy298;\n      goto yy341;\n    } else {\n      if (yych <= 'e') {\n        if (yych <= 'd')\n          goto yy298;\n        goto yy340;\n      } else {\n        if (yych == 'i')\n          goto yy341;\n        goto yy298;\n      }\n    }\n  yy309:\n    yych = *++p;\n    if (yych <= 'E') {\n      if (yych == 'A')\n        goto yy342;\n      if (yych <= 'D')\n        goto yy298;\n      goto yy343;\n    } else {\n      if (yych <= 'a') {\n        if (yych <= '`')\n          goto yy298;\n        goto yy342;\n      } else {\n        if (yych == 'e')\n          goto yy343;\n        goto yy298;\n      }\n    }\n  yy310:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych == 'A')\n        goto yy344;\n      if (yych <= 'N')\n        goto yy298;\n      goto yy345;\n    } else {\n      if (yych <= 'a') {\n        if (yych <= '`')\n          goto yy298;\n        goto yy344;\n      } else {\n        if (yych == 'o')\n          goto yy345;\n        goto yy298;\n      }\n    }\n  yy311:\n    yych = *++p;\n    if (yych <= 'P') {\n      if (yych == 'L')\n        goto yy331;\n      if (yych <= 'O')\n        goto yy298;\n      goto yy346;\n    } else {\n      if (yych <= 'l') {\n        if (yych <= 'k')\n          goto yy298;\n        goto yy331;\n      } else {\n        if (yych == 'p')\n          goto yy346;\n        goto yy298;\n      }\n    }\n  yy312:\n    yych = *++p;\n    if (yych <= '>') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        if (yych <= 0x1F)\n          goto yy298;\n        goto yy347;\n      } else {\n        if (yych == '/')\n          goto yy348;\n        if (yych <= '=')\n          goto yy298;\n        goto yy347;\n      }\n    } else {\n      if (yych <= 'R') {\n        if (yych == 'A')\n          goto yy349;\n        if (yych <= 'Q')\n          goto yy298;\n        goto yy350;\n      } else {\n        if (yych <= 'a') {\n          if (yych <= '`')\n            goto yy298;\n          goto yy349;\n        } else {\n          if (yych == 'r')\n            goto yy350;\n          goto yy298;\n        }\n      }\n    }\n  yy313:\n    yych = *++p;\n    switch (yych) {\n    case 'C':\n    case 'c':\n      goto yy351;\n    case 'E':\n    case 'e':\n      goto yy352;\n    case 'O':\n    case 'o':\n      goto yy353;\n    case 'T':\n    case 't':\n      goto yy354;\n    case 'U':\n    case 'u':\n      goto yy355;\n    default:\n      goto yy298;\n    }\n  yy314:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy356;\n    case 'B':\n    case 'b':\n      goto yy357;\n    case 'D':\n    case 'd':\n      goto yy331;\n    case 'E':\n    case 'e':\n      goto yy358;\n    case 'F':\n    case 'f':\n      goto yy359;\n    case 'H':\n    case 'h':\n      goto yy360;\n    case 'I':\n    case 'i':\n      goto yy361;\n    case 'R':\n    case 'r':\n      goto yy362;\n    default:\n      goto yy298;\n    }\n  yy315:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy331;\n    if (yych == 'l')\n      goto yy331;\n    goto yy298;\n  yy316:\n    yych = *++p;\n    if (yych == '-')\n      goto yy363;\n    goto yy298;\n  yy317:\n    ++p;\n    { return 4; }\n  yy318:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy364;\n    if (yych == 'c')\n      goto yy364;\n    goto yy298;\n  yy319:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'A')\n          goto yy349;\n        if (yych == 'a')\n          goto yy349;\n        goto yy298;\n      }\n    }\n  yy320:\n    yych = *++p;\n    if (yych <= 'U') {\n      if (yych <= 'N') {\n        if (yych == 'E')\n          goto yy352;\n        goto yy298;\n      } else {\n        if (yych <= 'O')\n          goto yy353;\n        if (yych <= 'T')\n          goto yy298;\n        goto yy355;\n      }\n    } else {\n      if (yych <= 'n') {\n        if (yych == 'e')\n          goto yy352;\n        goto yy298;\n      } else {\n        if (yych <= 'o')\n          goto yy353;\n        if (yych == 'u')\n          goto yy355;\n        goto yy298;\n      }\n    }\n  yy321:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy356;\n    case 'B':\n    case 'b':\n      goto yy357;\n    case 'D':\n    case 'd':\n      goto yy331;\n    case 'F':\n    case 'f':\n      goto yy359;\n    case 'H':\n    case 'h':\n      goto yy360;\n    case 'I':\n    case 'i':\n      goto yy361;\n    case 'R':\n    case 'r':\n      goto yy362;\n    default:\n      goto yy298;\n    }\n  yy322:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy365;\n    if (yych == 'd')\n      goto yy365;\n    goto yy298;\n  yy323:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy366;\n    if (yych == 't')\n      goto yy366;\n    goto yy298;\n  yy324:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy367;\n    if (yych == 'i')\n      goto yy367;\n    goto yy298;\n  yy325:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy368;\n    if (yych == 's')\n      goto yy368;\n    goto yy298;\n  yy326:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy369;\n    if (yych == 'o')\n      goto yy369;\n    goto yy298;\n  yy327:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy370;\n    if (yych == 'd')\n      goto yy370;\n    goto yy298;\n  yy328:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy371;\n    if (yych == 'p')\n      goto yy371;\n    goto yy298;\n  yy329:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy372;\n    if (yych == 'n')\n      goto yy372;\n    goto yy298;\n  yy330:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy373;\n    if (yych == 'l')\n      goto yy373;\n    goto yy298;\n  yy331:\n    yych = *++p;\n    if (yych <= ' ') {\n      if (yych <= 0x08)\n        goto yy298;\n      if (yych <= '\\r')\n        goto yy347;\n      if (yych <= 0x1F)\n        goto yy298;\n      goto yy347;\n    } else {\n      if (yych <= '/') {\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      } else {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      }\n    }\n  yy332:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy374;\n    if (yych == 't')\n      goto yy374;\n    goto yy298;\n  yy333:\n    yych = *++p;\n    if (yych <= 'V') {\n      if (yych <= 'Q') {\n        if (yych == 'A')\n          goto yy375;\n        goto yy298;\n      } else {\n        if (yych <= 'R')\n          goto yy331;\n        if (yych <= 'U')\n          goto yy298;\n        goto yy331;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych == 'a')\n          goto yy375;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy331;\n        if (yych == 'v')\n          goto yy331;\n        goto yy298;\n      }\n    }\n  yy334:\n    yych = *++p;\n    if (yych <= 'G') {\n      if (yych == 'E')\n        goto yy376;\n      if (yych <= 'F')\n        goto yy298;\n      goto yy377;\n    } else {\n      if (yych <= 'e') {\n        if (yych <= 'd')\n          goto yy298;\n        goto yy376;\n      } else {\n        if (yych == 'g')\n          goto yy377;\n        goto yy298;\n      }\n    }\n  yy335:\n    yych = *++p;\n    if (yych <= 'R') {\n      if (yych == 'O')\n        goto yy372;\n      if (yych <= 'Q')\n        goto yy298;\n      goto yy378;\n    } else {\n      if (yych <= 'o') {\n        if (yych <= 'n')\n          goto yy298;\n        goto yy372;\n      } else {\n        if (yych == 'r')\n          goto yy378;\n        goto yy298;\n      }\n    }\n  yy336:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy379;\n    if (yych == 'a')\n      goto yy379;\n    goto yy298;\n  yy337:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy380;\n    if (yych == 'a')\n      goto yy380;\n    goto yy298;\n  yy338:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy315;\n    if (yych == 'm')\n      goto yy315;\n    goto yy298;\n  yy339:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy381;\n    if (yych == 'r')\n      goto yy381;\n    goto yy298;\n  yy340:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy382;\n    if (yych == 'g')\n      goto yy382;\n    goto yy298;\n  yy341:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'M') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'N')\n          goto yy383;\n        if (yych == 'n')\n          goto yy383;\n        goto yy298;\n      }\n    }\n  yy342:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy384;\n    if (yych == 'i')\n      goto yy384;\n    goto yy298;\n  yy343:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy385;\n    if (yych == 'n')\n      goto yy385;\n    goto yy298;\n  yy344:\n    yych = *++p;\n    if (yych == 'V')\n      goto yy331;\n    if (yych == 'v')\n      goto yy331;\n    goto yy298;\n  yy345:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy386;\n    if (yych == 'f')\n      goto yy386;\n    goto yy298;\n  yy346:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy387;\n    if (yych == 't')\n      goto yy387;\n    goto yy298;\n  yy347:\n    ++p;\n    { return 6; }\n  yy348:\n    yych = *++p;\n    if (yych == '>')\n      goto yy347;\n    goto yy298;\n  yy349:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy388;\n    if (yych == 'r')\n      goto yy388;\n    goto yy298;\n  yy350:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy389;\n    if (yych == 'e')\n      goto yy389;\n    goto yy298;\n  yy351:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy390;\n    if (yych == 'r')\n      goto yy390;\n    goto yy298;\n  yy352:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy371;\n    if (yych == 'c')\n      goto yy371;\n    goto yy298;\n  yy353:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy391;\n    if (yych == 'u')\n      goto yy391;\n    goto yy298;\n  yy354:\n    yych = *++p;\n    if (yych == 'Y')\n      goto yy392;\n    if (yych == 'y')\n      goto yy392;\n    goto yy298;\n  yy355:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy393;\n    if (yych == 'm')\n      goto yy393;\n    goto yy298;\n  yy356:\n    yych = *++p;\n    if (yych == 'B')\n      goto yy394;\n    if (yych == 'b')\n      goto yy394;\n    goto yy298;\n  yy357:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy327;\n    if (yych == 'o')\n      goto yy327;\n    goto yy298;\n  yy358:\n    yych = *++p;\n    if (yych == 'X')\n      goto yy395;\n    if (yych == 'x')\n      goto yy395;\n    goto yy298;\n  yy359:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy396;\n    if (yych == 'o')\n      goto yy396;\n    goto yy298;\n  yy360:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'D') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy397;\n        if (yych == 'e')\n          goto yy397;\n        goto yy298;\n      }\n    }\n  yy361:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy394;\n    if (yych == 't')\n      goto yy394;\n    goto yy298;\n  yy362:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'A')\n          goto yy398;\n        if (yych == 'a')\n          goto yy398;\n        goto yy298;\n      }\n    }\n  yy363:\n    ++p;\n    { return 2; }\n  yy364:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy399;\n    if (yych == 'd')\n      goto yy399;\n    goto yy298;\n  yy365:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy400;\n    if (yych == 'r')\n      goto yy400;\n    goto yy298;\n  yy366:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy401;\n    if (yych == 'i')\n      goto yy401;\n    goto yy298;\n  yy367:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy402;\n    if (yych == 'd')\n      goto yy402;\n    goto yy298;\n  yy368:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy403;\n    if (yych == 'e')\n      goto yy403;\n    goto yy298;\n  yy369:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy404;\n    if (yych == 'c')\n      goto yy404;\n    goto yy298;\n  yy370:\n    yych = *++p;\n    if (yych == 'Y')\n      goto yy331;\n    if (yych == 'y')\n      goto yy331;\n    goto yy298;\n  yy371:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy405;\n    if (yych == 't')\n      goto yy405;\n    goto yy298;\n  yy372:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy406;\n    if (yych == 't')\n      goto yy406;\n    goto yy298;\n  yy373:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'F') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'G')\n          goto yy407;\n        if (yych == 'g')\n          goto yy407;\n        goto yy298;\n      }\n    }\n  yy374:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy408;\n    if (yych == 'a')\n      goto yy408;\n    goto yy298;\n  yy375:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy409;\n    if (yych == 'l')\n      goto yy409;\n    goto yy298;\n  yy376:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy410;\n    if (yych == 'l')\n      goto yy410;\n    goto yy298;\n  yy377:\n    yych = *++p;\n    if (yych <= 'U') {\n      if (yych == 'C')\n        goto yy411;\n      if (yych <= 'T')\n        goto yy298;\n      goto yy412;\n    } else {\n      if (yych <= 'c') {\n        if (yych <= 'b')\n          goto yy298;\n        goto yy411;\n      } else {\n        if (yych == 'u')\n          goto yy412;\n        goto yy298;\n      }\n    }\n  yy378:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy331;\n    if (yych == 'm')\n      goto yy331;\n    goto yy298;\n  yy379:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy413;\n    if (yych == 'm')\n      goto yy413;\n    goto yy298;\n  yy380:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy414;\n    if (yych == 'd')\n      goto yy414;\n    goto yy298;\n  yy381:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy415;\n    if (yych == 'a')\n      goto yy415;\n    goto yy298;\n  yy382:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy416;\n    if (yych == 'e')\n      goto yy416;\n    goto yy298;\n  yy383:\n    yych = *++p;\n    if (yych == 'K')\n      goto yy331;\n    if (yych == 'k')\n      goto yy331;\n    goto yy298;\n  yy384:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy331;\n    if (yych == 'n')\n      goto yy331;\n    goto yy298;\n  yy385:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy417;\n    if (yych == 'u')\n      goto yy417;\n    goto yy298;\n  yy386:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy418;\n    if (yych == 'r')\n      goto yy418;\n    goto yy298;\n  yy387:\n    yych = *++p;\n    if (yych <= 'I') {\n      if (yych == 'G')\n        goto yy407;\n      if (yych <= 'H')\n        goto yy298;\n      goto yy419;\n    } else {\n      if (yych <= 'g') {\n        if (yych <= 'f')\n          goto yy298;\n        goto yy407;\n      } else {\n        if (yych == 'i')\n          goto yy419;\n        goto yy298;\n      }\n    }\n  yy388:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy378;\n    if (yych == 'a')\n      goto yy378;\n    goto yy298;\n  yy389:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy298;\n      if (yych <= '\\r')\n        goto yy420;\n      goto yy298;\n    } else {\n      if (yych <= ' ')\n        goto yy420;\n      if (yych == '>')\n        goto yy420;\n      goto yy298;\n    }\n  yy390:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy421;\n    if (yych == 'i')\n      goto yy421;\n    goto yy298;\n  yy391:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy422;\n    if (yych == 'r')\n      goto yy422;\n    goto yy298;\n  yy392:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy350;\n    if (yych == 'l')\n      goto yy350;\n    goto yy298;\n  yy393:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy423;\n    if (yych == 'm')\n      goto yy423;\n    goto yy298;\n  yy394:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy402;\n    if (yych == 'l')\n      goto yy402;\n    goto yy298;\n  yy395:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy424;\n    if (yych == 't')\n      goto yy424;\n    goto yy298;\n  yy396:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy425;\n    if (yych == 'o')\n      goto yy425;\n    goto yy298;\n  yy397:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy426;\n    if (yych == 'a')\n      goto yy426;\n    goto yy298;\n  yy398:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy383;\n    if (yych == 'c')\n      goto yy383;\n    goto yy298;\n  yy399:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy427;\n    if (yych == 'a')\n      goto yy427;\n    goto yy298;\n  yy400:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy428;\n    if (yych == 'e')\n      goto yy428;\n    goto yy298;\n  yy401:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy394;\n    if (yych == 'c')\n      goto yy394;\n    goto yy298;\n  yy402:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy331;\n    if (yych == 'e')\n      goto yy331;\n    goto yy298;\n  yy403:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'E') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'F')\n          goto yy429;\n        if (yych == 'f')\n          goto yy429;\n        goto yy298;\n      }\n    }\n  yy404:\n    yych = *++p;\n    if (yych == 'K')\n      goto yy430;\n    if (yych == 'k')\n      goto yy430;\n    goto yy298;\n  yy405:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy419;\n    if (yych == 'i')\n      goto yy419;\n    goto yy298;\n  yy406:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy431;\n    if (yych == 'e')\n      goto yy431;\n    goto yy298;\n  yy407:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy432;\n    if (yych == 'r')\n      goto yy432;\n    goto yy298;\n  yy408:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy433;\n    if (yych == 'i')\n      goto yy433;\n    goto yy298;\n  yy409:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy434;\n    if (yych == 'o')\n      goto yy434;\n    goto yy298;\n  yy410:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy435;\n    if (yych == 'd')\n      goto yy435;\n    goto yy298;\n  yy411:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy328;\n    if (yych == 'a')\n      goto yy328;\n    goto yy298;\n  yy412:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy402;\n    if (yych == 'r')\n      goto yy402;\n    goto yy298;\n  yy413:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy436;\n    if (yych == 'e')\n      goto yy436;\n    goto yy298;\n  yy414:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'D') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy431;\n        if (yych == 'e')\n          goto yy431;\n        goto yy298;\n      }\n    }\n  yy415:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy402;\n    if (yych == 'm')\n      goto yy402;\n    goto yy298;\n  yy416:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy426;\n    if (yych == 'n')\n      goto yy426;\n    goto yy298;\n  yy417:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'H') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'I')\n          goto yy437;\n        if (yych == 'i')\n          goto yy437;\n        goto yy298;\n      }\n    }\n  yy418:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy438;\n    if (yych == 'a')\n      goto yy438;\n    goto yy298;\n  yy419:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy384;\n    if (yych == 'o')\n      goto yy384;\n    goto yy298;\n  yy420:\n    ++p;\n    { return 1; }\n  yy421:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy439;\n    if (yych == 'p')\n      goto yy439;\n    goto yy298;\n  yy422:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy402;\n    if (yych == 'c')\n      goto yy402;\n    goto yy298;\n  yy423:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy440;\n    if (yych == 'a')\n      goto yy440;\n    goto yy298;\n  yy424:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy441;\n    if (yych == 'a')\n      goto yy441;\n    goto yy298;\n  yy425:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy331;\n    if (yych == 't')\n      goto yy331;\n    goto yy298;\n  yy426:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy331;\n    if (yych == 'd')\n      goto yy331;\n    goto yy298;\n  yy427:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy442;\n    if (yych == 't')\n      goto yy442;\n    goto yy298;\n  yy428:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy443;\n    if (yych == 's')\n      goto yy443;\n    goto yy298;\n  yy429:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy444;\n    if (yych == 'o')\n      goto yy444;\n    goto yy298;\n  yy430:\n    yych = *++p;\n    if (yych == 'Q')\n      goto yy445;\n    if (yych == 'q')\n      goto yy445;\n    goto yy298;\n  yy431:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy331;\n    if (yych == 'r')\n      goto yy331;\n    goto yy298;\n  yy432:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy446;\n    if (yych == 'o')\n      goto yy446;\n    goto yy298;\n  yy433:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy443;\n    if (yych == 'l')\n      goto yy443;\n    goto yy298;\n  yy434:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy331;\n    if (yych == 'g')\n      goto yy331;\n    goto yy298;\n  yy435:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy447;\n    if (yych == 's')\n      goto yy447;\n    goto yy298;\n  yy436:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'R') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'S')\n          goto yy447;\n        if (yych == 's')\n          goto yy447;\n        goto yy298;\n      }\n    }\n  yy437:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy448;\n    if (yych == 't')\n      goto yy448;\n    goto yy298;\n  yy438:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy449;\n    if (yych == 'm')\n      goto yy449;\n    goto yy298;\n  yy439:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy389;\n    if (yych == 't')\n      goto yy389;\n    goto yy298;\n  yy440:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy370;\n    if (yych == 'r')\n      goto yy370;\n    goto yy298;\n  yy441:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy450;\n    if (yych == 'r')\n      goto yy450;\n    goto yy298;\n  yy442:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy451;\n    if (yych == 'a')\n      goto yy451;\n    goto yy298;\n  yy443:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy331;\n    if (yych == 's')\n      goto yy331;\n    goto yy298;\n  yy444:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy425;\n    if (yych == 'n')\n      goto yy425;\n    goto yy298;\n  yy445:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy452;\n    if (yych == 'u')\n      goto yy452;\n    goto yy298;\n  yy446:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy453;\n    if (yych == 'u')\n      goto yy453;\n    goto yy298;\n  yy447:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy425;\n    if (yych == 'e')\n      goto yy425;\n    goto yy298;\n  yy448:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy378;\n    if (yych == 'e')\n      goto yy378;\n    goto yy298;\n  yy449:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy443;\n    if (yych == 'e')\n      goto yy443;\n    goto yy298;\n  yy450:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy454;\n    if (yych == 'e')\n      goto yy454;\n    goto yy298;\n  yy451:\n    yych = *++p;\n    if (yych == '[')\n      goto yy455;\n    goto yy298;\n  yy452:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy456;\n    if (yych == 'o')\n      goto yy456;\n    goto yy298;\n  yy453:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy331;\n    if (yych == 'p')\n      goto yy331;\n    goto yy298;\n  yy454:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy389;\n    if (yych == 'a')\n      goto yy389;\n    goto yy298;\n  yy455:\n    ++p;\n    { return 5; }\n  yy456:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy402;\n    if (yych == 't')\n      goto yy402;\n    goto yy298;\n  }\n}\n\n// Try to match an HTML block tag start line of type 7, returning\n// 7 if successful, 0 if not.\nbufsize_t _scan_html_block_start_7(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   224, 224, 224, 224, 224, 224, 224, 224, 198, 210, 194, 198, 194,\n        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,\n        224, 224, 224, 224, 198, 224, 128, 224, 224, 224, 224, 64,  224, 224,\n        224, 224, 224, 233, 232, 224, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 232, 224, 192, 192, 192, 224, 224, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 224, 224, 224, 224, 232, 192, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 224, 224, 224,\n        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '<')\n      goto yy459;\n    ++p;\n  yy458 : { return 0; }\n  yy459:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '@') {\n      if (yych != '/')\n        goto yy458;\n    } else {\n      if (yych <= 'Z')\n        goto yy461;\n      if (yych <= '`')\n        goto yy458;\n      if (yych <= 'z')\n        goto yy461;\n      goto yy458;\n    }\n    yych = *++p;\n    if (yych <= '@')\n      goto yy460;\n    if (yych <= 'Z')\n      goto yy462;\n    if (yych <= '`')\n      goto yy460;\n    if (yych <= 'z')\n      goto yy462;\n  yy460:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy458;\n    } else {\n      goto yy469;\n    }\n  yy461:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych == '-')\n          goto yy461;\n        goto yy460;\n      } else {\n        if (yych <= '/')\n          goto yy464;\n        if (yych <= '9')\n          goto yy461;\n        goto yy460;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= '@')\n          goto yy460;\n        goto yy461;\n      } else {\n        if (yych <= '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy461;\n        goto yy460;\n      }\n    }\n  yy462:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy460;\n        if (yych <= '\\r')\n          goto yy466;\n        goto yy460;\n      } else {\n        if (yych <= ' ')\n          goto yy466;\n        if (yych == '-')\n          goto yy462;\n        goto yy460;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych <= '9')\n          goto yy462;\n        if (yych == '>')\n          goto yy465;\n        goto yy460;\n      } else {\n        if (yych <= 'Z')\n          goto yy462;\n        if (yych <= '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy462;\n        goto yy460;\n      }\n    }\n  yy463:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych <= '>') {\n      if (yych <= '9') {\n        if (yych != '/')\n          goto yy460;\n      } else {\n        if (yych <= ':')\n          goto yy467;\n        if (yych <= '=')\n          goto yy460;\n        goto yy465;\n      }\n    } else {\n      if (yych <= '^') {\n        if (yych <= '@')\n          goto yy460;\n        if (yych <= 'Z')\n          goto yy467;\n        goto yy460;\n      } else {\n        if (yych == '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy467;\n        goto yy460;\n      }\n    }\n  yy464:\n    yych = *++p;\n    if (yych != '>')\n      goto yy460;\n  yy465:\n    yych = *++p;\n    if (yybm[0 + yych] & 4) {\n      goto yy465;\n    }\n    if (yych <= 0x08)\n      goto yy460;\n    if (yych <= '\\n')\n      goto yy468;\n    if (yych <= '\\v')\n      goto yy460;\n    if (yych <= '\\r')\n      goto yy470;\n    goto yy460;\n  yy466:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy460;\n      if (yych <= '\\r')\n        goto yy466;\n      goto yy460;\n    } else {\n      if (yych <= ' ')\n        goto yy466;\n      if (yych == '>')\n        goto yy465;\n      goto yy460;\n    }\n  yy467:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy467;\n    }\n    if (yych <= ',') {\n      if (yych <= '\\r') {\n        if (yych <= 0x08)\n          goto yy460;\n        goto yy471;\n      } else {\n        if (yych == ' ')\n          goto yy471;\n        goto yy460;\n      }\n    } else {\n      if (yych <= '<') {\n        if (yych <= '/')\n          goto yy464;\n        goto yy460;\n      } else {\n        if (yych <= '=')\n          goto yy472;\n        if (yych <= '>')\n          goto yy465;\n        goto yy460;\n      }\n    }\n  yy468:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 4) {\n      goto yy465;\n    }\n    if (yych <= 0x08)\n      goto yy469;\n    if (yych <= '\\n')\n      goto yy468;\n    if (yych <= '\\v')\n      goto yy469;\n    if (yych <= '\\r')\n      goto yy470;\n  yy469 : { return 7; }\n  yy470:\n    ++p;\n    goto yy469;\n  yy471:\n    yych = *++p;\n    if (yych <= '<') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy460;\n        if (yych <= '\\r')\n          goto yy471;\n        if (yych <= 0x1F)\n          goto yy460;\n        goto yy471;\n      } else {\n        if (yych <= '/') {\n          if (yych <= '.')\n            goto yy460;\n          goto yy464;\n        } else {\n          if (yych == ':')\n            goto yy467;\n          goto yy460;\n        }\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '=')\n          goto yy472;\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= '@')\n          goto yy460;\n        goto yy467;\n      } else {\n        if (yych <= '_') {\n          if (yych <= '^')\n            goto yy460;\n          goto yy467;\n        } else {\n          if (yych <= '`')\n            goto yy460;\n          if (yych <= 'z')\n            goto yy467;\n          goto yy460;\n        }\n      }\n    }\n  yy472:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy473;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\"') {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= ' ')\n          goto yy472;\n        goto yy474;\n      } else {\n        if (yych <= '\\'')\n          goto yy475;\n        if (yych <= 0xC1)\n          goto yy460;\n        if (yych <= 0xDF)\n          goto yy476;\n        goto yy477;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy479;\n        goto yy478;\n      } else {\n        if (yych <= 0xF0)\n          goto yy480;\n        if (yych <= 0xF3)\n          goto yy481;\n        if (yych <= 0xF4)\n          goto yy482;\n        goto yy460;\n      }\n    }\n  yy473:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy473;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= ' ')\n          goto yy463;\n        goto yy460;\n      } else {\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= 0xC1)\n          goto yy460;\n        if (yych <= 0xDF)\n          goto yy476;\n        goto yy477;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy479;\n        goto yy478;\n      } else {\n        if (yych <= 0xF0)\n          goto yy480;\n        if (yych <= 0xF3)\n          goto yy481;\n        if (yych <= 0xF4)\n          goto yy482;\n        goto yy460;\n      }\n    }\n  yy474:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy474;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= '\"')\n          goto yy483;\n        goto yy460;\n      } else {\n        if (yych <= 0xDF)\n          goto yy484;\n        if (yych <= 0xE0)\n          goto yy485;\n        goto yy486;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy487;\n        if (yych <= 0xEF)\n          goto yy486;\n        goto yy488;\n      } else {\n        if (yych <= 0xF3)\n          goto yy489;\n        if (yych <= 0xF4)\n          goto yy490;\n        goto yy460;\n      }\n    }\n  yy475:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy475;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= '\\'')\n          goto yy483;\n        goto yy460;\n      } else {\n        if (yych <= 0xDF)\n          goto yy491;\n        if (yych <= 0xE0)\n          goto yy492;\n        goto yy493;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy494;\n        if (yych <= 0xEF)\n          goto yy493;\n        goto yy495;\n      } else {\n        if (yych <= 0xF3)\n          goto yy496;\n        if (yych <= 0xF4)\n          goto yy497;\n        goto yy460;\n      }\n    }\n  yy476:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy473;\n    goto yy460;\n  yy477:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy476;\n    goto yy460;\n  yy478:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy476;\n    goto yy460;\n  yy479:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy476;\n    goto yy460;\n  yy480:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy478;\n    goto yy460;\n  yy481:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy478;\n    goto yy460;\n  yy482:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy478;\n    goto yy460;\n  yy483:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych == '/')\n      goto yy464;\n    if (yych == '>')\n      goto yy465;\n    goto yy460;\n  yy484:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy474;\n    goto yy460;\n  yy485:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy484;\n    goto yy460;\n  yy486:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy484;\n    goto yy460;\n  yy487:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy484;\n    goto yy460;\n  yy488:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy486;\n    goto yy460;\n  yy489:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy486;\n    goto yy460;\n  yy490:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy486;\n    goto yy460;\n  yy491:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy475;\n    goto yy460;\n  yy492:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy491;\n    goto yy460;\n  yy493:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy491;\n    goto yy460;\n  yy494:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy491;\n    goto yy460;\n  yy495:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy493;\n    goto yy460;\n  yy496:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy493;\n    goto yy460;\n  yy497:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy493;\n    goto yy460;\n  }\n}\n\n// Try to match an HTML block end line of type 1\nbufsize_t _scan_html_block_end_1(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= ';') {\n        if (yych <= 0x00)\n          goto yy499;\n        if (yych != '\\n')\n          goto yy501;\n      } else {\n        if (yych <= '<')\n          goto yy502;\n        if (yych <= 0x7F)\n          goto yy501;\n        if (yych >= 0xC2)\n          goto yy503;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy504;\n        if (yych == 0xED)\n          goto yy506;\n        goto yy505;\n      } else {\n        if (yych <= 0xF0)\n          goto yy507;\n        if (yych <= 0xF3)\n          goto yy508;\n        if (yych <= 0xF4)\n          goto yy509;\n      }\n    }\n  yy499:\n    ++p;\n  yy500 : { return 0; }\n  yy501:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy500;\n      if (yych <= '\\t')\n        goto yy511;\n      goto yy500;\n    } else {\n      if (yych <= 0x7F)\n        goto yy511;\n      if (yych <= 0xC1)\n        goto yy500;\n      if (yych <= 0xF4)\n        goto yy511;\n      goto yy500;\n    }\n  yy502:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '.') {\n      if (yych <= 0x00)\n        goto yy500;\n      if (yych == '\\n')\n        goto yy500;\n      goto yy511;\n    } else {\n      if (yych <= 0x7F) {\n        if (yych <= '/')\n          goto yy521;\n        goto yy511;\n      } else {\n        if (yych <= 0xC1)\n          goto yy500;\n        if (yych <= 0xF4)\n          goto yy511;\n        goto yy500;\n      }\n    }\n  yy503:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy510;\n    goto yy500;\n  yy504:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy500;\n  yy505:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy500;\n  yy506:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0x9F)\n      goto yy514;\n    goto yy500;\n  yy507:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy500;\n  yy508:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy500;\n  yy509:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0x8F)\n      goto yy516;\n    goto yy500;\n  yy510:\n    yych = *++p;\n  yy511:\n    if (yybm[0 + yych] & 64) {\n      goto yy510;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy512;\n        if (yych <= '<')\n          goto yy513;\n      } else {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        goto yy516;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy517;\n        if (yych <= 0xEF)\n          goto yy516;\n        goto yy518;\n      } else {\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n      }\n    }\n  yy512:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy500;\n    } else {\n      goto yy534;\n    }\n  yy513:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '.') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '/')\n          goto yy521;\n        if (yych <= 0x7F)\n          goto yy510;\n        if (yych <= 0xC1)\n          goto yy512;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych == 0xED)\n          goto yy517;\n        goto yy516;\n      } else {\n        if (yych <= 0xF0)\n          goto yy518;\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n        goto yy512;\n      }\n    }\n  yy514:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy510;\n    goto yy512;\n  yy515:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy512;\n  yy516:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy512;\n  yy517:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0x9F)\n      goto yy514;\n    goto yy512;\n  yy518:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy512;\n  yy519:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy512;\n  yy520:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0x8F)\n      goto yy516;\n    goto yy512;\n  yy521:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 's') {\n      if (yych <= 'R') {\n        if (yych <= '\\n') {\n          if (yych <= 0x00)\n            goto yy512;\n          if (yych <= '\\t')\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych != 'P')\n            goto yy510;\n        }\n      } else {\n        if (yych <= 'o') {\n          if (yych <= 'S')\n            goto yy523;\n          if (yych <= 'T')\n            goto yy524;\n          goto yy510;\n        } else {\n          if (yych <= 'p')\n            goto yy522;\n          if (yych <= 'r')\n            goto yy510;\n          goto yy523;\n        }\n      }\n    } else {\n      if (yych <= 0xEC) {\n        if (yych <= 0xC1) {\n          if (yych <= 't')\n            goto yy524;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych <= 0xDF)\n            goto yy514;\n          if (yych <= 0xE0)\n            goto yy515;\n          goto yy516;\n        }\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xED)\n            goto yy517;\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy522:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych <= 'R')\n            goto yy525;\n          goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy525;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy523:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 't') {\n      if (yych <= 'C') {\n        if (yych <= '\\t') {\n          if (yych <= 0x00)\n            goto yy512;\n          goto yy510;\n        } else {\n          if (yych <= '\\n')\n            goto yy512;\n          if (yych <= 'B')\n            goto yy510;\n          goto yy526;\n        }\n      } else {\n        if (yych <= 'b') {\n          if (yych == 'T')\n            goto yy527;\n          goto yy510;\n        } else {\n          if (yych <= 'c')\n            goto yy526;\n          if (yych <= 's')\n            goto yy510;\n          goto yy527;\n        }\n      }\n    } else {\n      if (yych <= 0xEC) {\n        if (yych <= 0xC1) {\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych <= 0xDF)\n            goto yy514;\n          if (yych <= 0xE0)\n            goto yy515;\n          goto yy516;\n        }\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xED)\n            goto yy517;\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy524:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych <= 'E')\n            goto yy528;\n          goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy528;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy525:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych <= 'E')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy526:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych <= 'R')\n            goto yy530;\n          goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy530;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy527:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'X') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'x') {\n          if (yych <= 'Y')\n            goto yy531;\n          goto yy510;\n        } else {\n          if (yych <= 'y')\n            goto yy531;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy528:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'W') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'w') {\n          if (yych <= 'X')\n            goto yy532;\n          goto yy510;\n        } else {\n          if (yych <= 'x')\n            goto yy532;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy529:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '>')\n          goto yy533;\n        if (yych <= 0x7F)\n          goto yy510;\n        if (yych <= 0xC1)\n          goto yy512;\n        goto yy514;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych == 0xED)\n          goto yy517;\n        goto yy516;\n      } else {\n        if (yych <= 0xF0)\n          goto yy518;\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n        goto yy512;\n      }\n    }\n  yy530:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'H') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'h') {\n          if (yych <= 'I')\n            goto yy535;\n          goto yy510;\n        } else {\n          if (yych <= 'i')\n            goto yy535;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy531:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'K') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'k') {\n          if (yych <= 'L')\n            goto yy525;\n          goto yy510;\n        } else {\n          if (yych <= 'l')\n            goto yy525;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy532:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'S') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 's') {\n          if (yych <= 'T')\n            goto yy536;\n          goto yy510;\n        } else {\n          if (yych <= 't')\n            goto yy536;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy533:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy510;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy534;\n        if (yych <= '<')\n          goto yy513;\n      } else {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        goto yy516;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy517;\n        if (yych <= 0xEF)\n          goto yy516;\n        goto yy518;\n      } else {\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n      }\n    }\n  yy534 : { return (bufsize_t)(p - start); }\n  yy535:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'O') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'o') {\n          if (yych <= 'P')\n            goto yy537;\n          goto yy510;\n        } else {\n          if (yych <= 'p')\n            goto yy537;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy536:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= '@') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '`') {\n          if (yych <= 'A')\n            goto yy538;\n          goto yy510;\n        } else {\n          if (yych <= 'a')\n            goto yy538;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy537:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'S') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 's') {\n          if (yych <= 'T')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 't')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy538:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych >= 'S')\n            goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy539;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy539:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych >= 'F')\n            goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy540;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy540:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= '@') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '`') {\n          if (yych <= 'A')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 'a')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  }\n}\n\n// Try to match an HTML block end line of type 2\nbufsize_t _scan_html_block_end_2(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= ',') {\n        if (yych <= 0x00)\n          goto yy542;\n        if (yych != '\\n')\n          goto yy544;\n      } else {\n        if (yych <= '-')\n          goto yy545;\n        if (yych <= 0x7F)\n          goto yy544;\n        if (yych >= 0xC2)\n          goto yy546;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy547;\n        if (yych == 0xED)\n          goto yy549;\n        goto yy548;\n      } else {\n        if (yych <= 0xF0)\n          goto yy550;\n        if (yych <= 0xF3)\n          goto yy551;\n        if (yych <= 0xF4)\n          goto yy552;\n      }\n    }\n  yy542:\n    ++p;\n  yy543 : { return 0; }\n  yy544:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy543;\n      if (yych <= '\\t')\n        goto yy554;\n      goto yy543;\n    } else {\n      if (yych <= 0x7F)\n        goto yy554;\n      if (yych <= 0xC1)\n        goto yy543;\n      if (yych <= 0xF4)\n        goto yy554;\n      goto yy543;\n    }\n  yy545:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy564;\n    }\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy543;\n      if (yych <= '\\t')\n        goto yy554;\n      goto yy543;\n    } else {\n      if (yych <= 0x7F)\n        goto yy554;\n      if (yych <= 0xC1)\n        goto yy543;\n      if (yych <= 0xF4)\n        goto yy554;\n      goto yy543;\n    }\n  yy546:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy553;\n    goto yy543;\n  yy547:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy543;\n  yy548:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy543;\n  yy549:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0x9F)\n      goto yy557;\n    goto yy543;\n  yy550:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy543;\n  yy551:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy543;\n  yy552:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0x8F)\n      goto yy559;\n    goto yy543;\n  yy553:\n    yych = *++p;\n  yy554:\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy555;\n        if (yych <= '-')\n          goto yy556;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n      }\n    }\n  yy555:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy543;\n    } else {\n      goto yy566;\n    }\n  yy556:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy555;\n        if (yych <= '-')\n          goto yy564;\n        goto yy555;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n        goto yy555;\n      }\n    }\n  yy557:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy553;\n    goto yy555;\n  yy558:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy555;\n  yy559:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy555;\n  yy560:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0x9F)\n      goto yy557;\n    goto yy555;\n  yy561:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy555;\n  yy562:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy555;\n  yy563:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0x8F)\n      goto yy559;\n    goto yy555;\n  yy564:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy564;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy555;\n        if (yych == '\\n')\n          goto yy555;\n        goto yy553;\n      } else {\n        if (yych <= '>')\n          goto yy565;\n        if (yych <= 0x7F)\n          goto yy553;\n        if (yych <= 0xC1)\n          goto yy555;\n        goto yy557;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy558;\n        if (yych == 0xED)\n          goto yy560;\n        goto yy559;\n      } else {\n        if (yych <= 0xF0)\n          goto yy561;\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n        goto yy555;\n      }\n    }\n  yy565:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy566;\n        if (yych <= '-')\n          goto yy556;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n      }\n    }\n  yy566 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match an HTML block end line of type 3\nbufsize_t _scan_html_block_end_3(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy568;\n        if (yych != '\\n')\n          goto yy570;\n      } else {\n        if (yych <= '?')\n          goto yy571;\n        if (yych <= 0x7F)\n          goto yy570;\n        if (yych >= 0xC2)\n          goto yy572;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy573;\n        if (yych == 0xED)\n          goto yy575;\n        goto yy574;\n      } else {\n        if (yych <= 0xF0)\n          goto yy576;\n        if (yych <= 0xF3)\n          goto yy577;\n        if (yych <= 0xF4)\n          goto yy578;\n      }\n    }\n  yy568:\n    ++p;\n  yy569 : { return 0; }\n  yy570:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy569;\n      if (yych <= '\\t')\n        goto yy580;\n      goto yy569;\n    } else {\n      if (yych <= 0x7F)\n        goto yy580;\n      if (yych <= 0xC1)\n        goto yy569;\n      if (yych <= 0xF4)\n        goto yy580;\n      goto yy569;\n    }\n  yy571:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '=') {\n      if (yych <= 0x00)\n        goto yy569;\n      if (yych == '\\n')\n        goto yy569;\n      goto yy580;\n    } else {\n      if (yych <= 0x7F) {\n        if (yych <= '>')\n          goto yy590;\n        goto yy580;\n      } else {\n        if (yych <= 0xC1)\n          goto yy569;\n        if (yych <= 0xF4)\n          goto yy580;\n        goto yy569;\n      }\n    }\n  yy572:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy579;\n    goto yy569;\n  yy573:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy569;\n  yy574:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy569;\n  yy575:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0x9F)\n      goto yy583;\n    goto yy569;\n  yy576:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy569;\n  yy577:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy569;\n  yy578:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0x8F)\n      goto yy585;\n    goto yy569;\n  yy579:\n    yych = *++p;\n  yy580:\n    if (yybm[0 + yych] & 64) {\n      goto yy579;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy581;\n        if (yych <= '?')\n          goto yy582;\n      } else {\n        if (yych <= 0xDF)\n          goto yy583;\n        if (yych <= 0xE0)\n          goto yy584;\n        goto yy585;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy586;\n        if (yych <= 0xEF)\n          goto yy585;\n        goto yy587;\n      } else {\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n      }\n    }\n  yy581:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy569;\n    } else {\n      goto yy591;\n    }\n  yy582:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy582;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy581;\n        if (yych == '\\n')\n          goto yy581;\n        goto yy579;\n      } else {\n        if (yych <= '>')\n          goto yy590;\n        if (yych <= 0x7F)\n          goto yy579;\n        if (yych <= 0xC1)\n          goto yy581;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy584;\n        if (yych == 0xED)\n          goto yy586;\n        goto yy585;\n      } else {\n        if (yych <= 0xF0)\n          goto yy587;\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n        goto yy581;\n      }\n    }\n  yy583:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy579;\n    goto yy581;\n  yy584:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy581;\n  yy585:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy581;\n  yy586:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0x9F)\n      goto yy583;\n    goto yy581;\n  yy587:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy581;\n  yy588:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy581;\n  yy589:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0x8F)\n      goto yy585;\n    goto yy581;\n  yy590:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy579;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy591;\n        if (yych <= '?')\n          goto yy582;\n      } else {\n        if (yych <= 0xDF)\n          goto yy583;\n        if (yych <= 0xE0)\n          goto yy584;\n        goto yy585;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy586;\n        if (yych <= 0xEF)\n          goto yy585;\n        goto yy587;\n      } else {\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n      }\n    }\n  yy591 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match an HTML block end line of type 4\nbufsize_t _scan_html_block_end_4(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 64,  128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 64) {\n      goto yy596;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\n') {\n        if (yych <= 0x00)\n          goto yy593;\n        if (yych <= '\\t')\n          goto yy595;\n      } else {\n        if (yych <= 0x7F)\n          goto yy595;\n        if (yych <= 0xC1)\n          goto yy593;\n        if (yych <= 0xDF)\n          goto yy598;\n        goto yy599;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy601;\n        goto yy600;\n      } else {\n        if (yych <= 0xF0)\n          goto yy602;\n        if (yych <= 0xF3)\n          goto yy603;\n        if (yych <= 0xF4)\n          goto yy604;\n      }\n    }\n  yy593:\n    ++p;\n  yy594 : { return 0; }\n  yy595:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy594;\n      if (yych <= '\\t')\n        goto yy606;\n      goto yy594;\n    } else {\n      if (yych <= 0x7F)\n        goto yy606;\n      if (yych <= 0xC1)\n        goto yy594;\n      if (yych <= 0xF4)\n        goto yy606;\n      goto yy594;\n    }\n  yy596:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy605;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy597;\n        if (yych <= '>')\n          goto yy596;\n      } else {\n        if (yych <= 0xDF)\n          goto yy608;\n        if (yych <= 0xE0)\n          goto yy609;\n        goto yy610;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy611;\n        if (yych <= 0xEF)\n          goto yy610;\n        goto yy612;\n      } else {\n        if (yych <= 0xF3)\n          goto yy613;\n        if (yych <= 0xF4)\n          goto yy614;\n      }\n    }\n  yy597 : { return (bufsize_t)(p - start); }\n  yy598:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy605;\n    goto yy594;\n  yy599:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy594;\n  yy600:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy594;\n  yy601:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0x9F)\n      goto yy608;\n    goto yy594;\n  yy602:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy594;\n  yy603:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy594;\n  yy604:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0x8F)\n      goto yy610;\n    goto yy594;\n  yy605:\n    yych = *++p;\n  yy606:\n    if (yybm[0 + yych] & 128) {\n      goto yy605;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy607;\n        if (yych <= '>')\n          goto yy596;\n      } else {\n        if (yych <= 0xDF)\n          goto yy608;\n        if (yych <= 0xE0)\n          goto yy609;\n        goto yy610;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy611;\n        if (yych <= 0xEF)\n          goto yy610;\n        goto yy612;\n      } else {\n        if (yych <= 0xF3)\n          goto yy613;\n        if (yych <= 0xF4)\n          goto yy614;\n      }\n    }\n  yy607:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy594;\n    } else {\n      goto yy597;\n    }\n  yy608:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy605;\n    goto yy607;\n  yy609:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy607;\n  yy610:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy607;\n  yy611:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0x9F)\n      goto yy608;\n    goto yy607;\n  yy612:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy607;\n  yy613:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy607;\n  yy614:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0x8F)\n      goto yy610;\n    goto yy607;\n  }\n}\n\n// Try to match an HTML block end line of type 5\nbufsize_t _scan_html_block_end_5(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64,  64, 64, 64, 64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy616;\n        if (yych != '\\n')\n          goto yy618;\n      } else {\n        if (yych <= ']')\n          goto yy619;\n        if (yych <= 0x7F)\n          goto yy618;\n        if (yych >= 0xC2)\n          goto yy620;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy621;\n        if (yych == 0xED)\n          goto yy623;\n        goto yy622;\n      } else {\n        if (yych <= 0xF0)\n          goto yy624;\n        if (yych <= 0xF3)\n          goto yy625;\n        if (yych <= 0xF4)\n          goto yy626;\n      }\n    }\n  yy616:\n    ++p;\n  yy617 : { return 0; }\n  yy618:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy617;\n      if (yych <= '\\t')\n        goto yy628;\n      goto yy617;\n    } else {\n      if (yych <= 0x7F)\n        goto yy628;\n      if (yych <= 0xC1)\n        goto yy617;\n      if (yych <= 0xF4)\n        goto yy628;\n      goto yy617;\n    }\n  yy619:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy638;\n    }\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy617;\n      if (yych <= '\\t')\n        goto yy628;\n      goto yy617;\n    } else {\n      if (yych <= 0x7F)\n        goto yy628;\n      if (yych <= 0xC1)\n        goto yy617;\n      if (yych <= 0xF4)\n        goto yy628;\n      goto yy617;\n    }\n  yy620:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy627;\n    goto yy617;\n  yy621:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy617;\n  yy622:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy617;\n  yy623:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0x9F)\n      goto yy631;\n    goto yy617;\n  yy624:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy617;\n  yy625:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy617;\n  yy626:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0x8F)\n      goto yy633;\n    goto yy617;\n  yy627:\n    yych = *++p;\n  yy628:\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy629;\n        if (yych <= ']')\n          goto yy630;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n      }\n    }\n  yy629:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy617;\n    } else {\n      goto yy640;\n    }\n  yy630:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy629;\n        if (yych <= ']')\n          goto yy638;\n        goto yy629;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n        goto yy629;\n      }\n    }\n  yy631:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy627;\n    goto yy629;\n  yy632:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy629;\n  yy633:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy629;\n  yy634:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0x9F)\n      goto yy631;\n    goto yy629;\n  yy635:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy629;\n  yy636:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy629;\n  yy637:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0x8F)\n      goto yy633;\n    goto yy629;\n  yy638:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy638;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy629;\n        if (yych == '\\n')\n          goto yy629;\n        goto yy627;\n      } else {\n        if (yych <= '>')\n          goto yy639;\n        if (yych <= 0x7F)\n          goto yy627;\n        if (yych <= 0xC1)\n          goto yy629;\n        goto yy631;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy632;\n        if (yych == 0xED)\n          goto yy634;\n        goto yy633;\n      } else {\n        if (yych <= 0xF0)\n          goto yy635;\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n        goto yy629;\n      }\n    }\n  yy639:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy640;\n        if (yych <= ']')\n          goto yy630;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n      }\n    }\n  yy640 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match a link title (in single quotes, in double quotes, or\n// in parentheses), returning number of chars matched.  Allow one\n// level of internal nesting (quotes within quotes).\nbufsize_t _scan_link_title(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 192, 208, 208, 208, 208, 144, 80,  80,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 32,  208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '&') {\n      if (yych == '\"')\n        goto yy643;\n    } else {\n      if (yych <= '\\'')\n        goto yy644;\n      if (yych <= '(')\n        goto yy645;\n    }\n    ++p;\n  yy642 : { return 0; }\n  yy643:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x00)\n      goto yy642;\n    if (yych <= 0x7F)\n      goto yy647;\n    if (yych <= 0xC1)\n      goto yy642;\n    if (yych <= 0xF4)\n      goto yy647;\n    goto yy642;\n  yy644:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x00)\n      goto yy642;\n    if (yych <= 0x7F)\n      goto yy660;\n    if (yych <= 0xC1)\n      goto yy642;\n    if (yych <= 0xF4)\n      goto yy660;\n    goto yy642;\n  yy645:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '(') {\n      if (yych <= 0x00)\n        goto yy642;\n      if (yych <= '\\'')\n        goto yy672;\n      goto yy642;\n    } else {\n      if (yych <= 0x7F)\n        goto yy672;\n      if (yych <= 0xC1)\n        goto yy642;\n      if (yych <= 0xF4)\n        goto yy672;\n      goto yy642;\n    }\n  yy646:\n    yych = *++p;\n  yy647:\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\"')\n          goto yy649;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy652;\n        goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n      }\n    }\n  yy648:\n    p = marker;\n    if (yyaccept <= 1) {\n      if (yyaccept == 0) {\n        goto yy642;\n      } else {\n        goto yy650;\n      }\n    } else {\n      if (yyaccept == 2) {\n        goto yy662;\n      } else {\n        goto yy674;\n      }\n    }\n  yy649:\n    ++p;\n  yy650 : { return (bufsize_t)(p - start); }\n  yy651:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\"')\n          goto yy683;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych >= 0xE0)\n          goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n        goto yy648;\n      }\n    }\n  yy652:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy646;\n    goto yy648;\n  yy653:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy652;\n    goto yy648;\n  yy654:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy652;\n    goto yy648;\n  yy655:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy652;\n    goto yy648;\n  yy656:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy654;\n    goto yy648;\n  yy657:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy654;\n    goto yy648;\n  yy658:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy654;\n    goto yy648;\n  yy659:\n    yych = *++p;\n  yy660:\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych >= '(')\n          goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy664;\n        goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy648;\n      }\n    }\n  yy661:\n    ++p;\n  yy662 : { return (bufsize_t)(p - start); }\n  yy663:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\\'')\n          goto yy684;\n        goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych >= 0xE0)\n          goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy648;\n      }\n    }\n  yy664:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy659;\n    goto yy648;\n  yy665:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy664;\n    goto yy648;\n  yy666:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy664;\n    goto yy648;\n  yy667:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy664;\n    goto yy648;\n  yy668:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy666;\n    goto yy648;\n  yy669:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy666;\n    goto yy648;\n  yy670:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy666;\n    goto yy648;\n  yy671:\n    yych = *++p;\n  yy672:\n    if (yybm[0 + yych] & 128) {\n      goto yy671;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= '(')\n          goto yy648;\n        if (yych >= '*')\n          goto yy675;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy676;\n        goto yy677;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy648;\n      }\n    }\n  yy673:\n    ++p;\n  yy674 : { return (bufsize_t)(p - start); }\n  yy675:\n    yych = *++p;\n    if (yych <= 0xDF) {\n      if (yych <= '[') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych == ')')\n          goto yy685;\n        goto yy671;\n      } else {\n        if (yych <= '\\\\')\n          goto yy675;\n        if (yych <= 0x7F)\n          goto yy671;\n        if (yych <= 0xC1)\n          goto yy648;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy677;\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy648;\n      }\n    }\n  yy676:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy671;\n    goto yy648;\n  yy677:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy676;\n    goto yy648;\n  yy678:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy676;\n    goto yy648;\n  yy679:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy676;\n    goto yy648;\n  yy680:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy678;\n    goto yy648;\n  yy681:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy678;\n    goto yy648;\n  yy682:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy678;\n    goto yy648;\n  yy683:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy650;\n        if (yych <= '\"')\n          goto yy649;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy650;\n        if (yych <= 0xDF)\n          goto yy652;\n        goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n        goto yy650;\n      }\n    }\n  yy684:\n    yyaccept = 2;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy662;\n        if (yych <= '\\'')\n          goto yy661;\n        goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy662;\n        if (yych <= 0xDF)\n          goto yy664;\n        goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy662;\n      }\n    }\n  yy685:\n    yyaccept = 3;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy671;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= '(')\n          goto yy674;\n        if (yych <= ')')\n          goto yy673;\n        goto yy675;\n      } else {\n        if (yych <= 0xC1)\n          goto yy674;\n        if (yych <= 0xDF)\n          goto yy676;\n        goto yy677;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy674;\n      }\n    }\n  }\n}\n\n// Match space characters, including newlines.\nbufsize_t _scan_spacechars(const unsigned char *p) {\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   128, 0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 128) {\n      goto yy687;\n    }\n    ++p;\n    { return 0; }\n  yy687:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy687;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n\n// Match ATX heading start.\nbufsize_t _scan_atx_heading_start(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '#')\n      goto yy690;\n    ++p;\n  yy689 : { return 0; }\n  yy690:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy689;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy689;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych == '#')\n        goto yy694;\n      goto yy689;\n    }\n  yy691:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n  yy692 : { return (bufsize_t)(p - start); }\n  yy693:\n    ++p;\n    goto yy692;\n  yy694:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych == '#')\n        goto yy696;\n    }\n  yy695:\n    p = marker;\n    goto yy689;\n  yy696:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= 0x08)\n      goto yy695;\n    if (yych <= '\\n')\n      goto yy693;\n    if (yych == '\\r')\n      goto yy693;\n    goto yy695;\n  }\n}\n\n// Match setext heading line.  Return 1 for level-1 heading,\n// 2 for level-2, 0 for no match.\nbufsize_t _scan_setext_heading_line(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 32, 0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  32, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 64, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '-')\n      goto yy699;\n    if (yych == '=')\n      goto yy700;\n    ++p;\n  yy698 : { return 0; }\n  yy699:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy705;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy698;\n      if (yych <= '\\n')\n        goto yy702;\n      goto yy698;\n    } else {\n      if (yych <= '\\r')\n        goto yy702;\n      if (yych == ' ')\n        goto yy702;\n      goto yy698;\n    }\n  yy700:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy709;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy698;\n      if (yych <= '\\n')\n        goto yy707;\n      goto yy698;\n    } else {\n      if (yych <= '\\r')\n        goto yy707;\n      if (yych == ' ')\n        goto yy707;\n      goto yy698;\n    }\n  yy701:\n    yych = *++p;\n  yy702:\n    if (yybm[0 + yych] & 32) {\n      goto yy701;\n    }\n    if (yych <= 0x08)\n      goto yy703;\n    if (yych <= '\\n')\n      goto yy704;\n    if (yych == '\\r')\n      goto yy704;\n  yy703:\n    p = marker;\n    goto yy698;\n  yy704:\n    ++p;\n    { return 2; }\n  yy705:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy701;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\n')\n        goto yy704;\n      goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy704;\n      if (yych == '-')\n        goto yy705;\n      goto yy703;\n    }\n  yy706:\n    yych = *++p;\n  yy707:\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\t')\n        goto yy706;\n      if (yych >= '\\v')\n        goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy708;\n      if (yych == ' ')\n        goto yy706;\n      goto yy703;\n    }\n  yy708:\n    ++p;\n    { return 1; }\n  yy709:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy709;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\t')\n        goto yy706;\n      if (yych <= '\\n')\n        goto yy708;\n      goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy708;\n      if (yych == ' ')\n        goto yy706;\n      goto yy703;\n    }\n  }\n}\n\n// Scan an opening code fence.\nbufsize_t _scan_open_code_fence(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   192, 192, 192, 192, 192, 192, 192, 192, 192, 0,   192, 192, 0,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 144, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        224, 192, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '`')\n      goto yy712;\n    if (yych == '~')\n      goto yy713;\n    ++p;\n  yy711 : { return 0; }\n  yy712:\n    yych = *(marker = ++p);\n    if (yych == '`')\n      goto yy714;\n    goto yy711;\n  yy713:\n    yych = *(marker = ++p);\n    if (yych == '~')\n      goto yy716;\n    goto yy711;\n  yy714:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy717;\n    }\n  yy715:\n    p = marker;\n    goto yy711;\n  yy716:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy718;\n    }\n    goto yy715;\n  yy717:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy717;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '\\f') {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych == '\\n') {\n          marker = p;\n          goto yy720;\n        }\n        marker = p;\n        goto yy719;\n      } else {\n        if (yych <= '\\r') {\n          marker = p;\n          goto yy720;\n        }\n        if (yych <= 0x7F) {\n          marker = p;\n          goto yy719;\n        }\n        if (yych <= 0xC1)\n          goto yy715;\n        marker = p;\n        goto yy721;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0) {\n          marker = p;\n          goto yy722;\n        }\n        if (yych == 0xED) {\n          marker = p;\n          goto yy724;\n        }\n        marker = p;\n        goto yy723;\n      } else {\n        if (yych <= 0xF0) {\n          marker = p;\n          goto yy725;\n        }\n        if (yych <= 0xF3) {\n          marker = p;\n          goto yy726;\n        }\n        if (yych <= 0xF4) {\n          marker = p;\n          goto yy727;\n        }\n        goto yy715;\n      }\n    }\n  yy718:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy718;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '\\f') {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych == '\\n') {\n          marker = p;\n          goto yy729;\n        }\n        marker = p;\n        goto yy728;\n      } else {\n        if (yych <= '\\r') {\n          marker = p;\n          goto yy729;\n        }\n        if (yych <= 0x7F) {\n          marker = p;\n          goto yy728;\n        }\n        if (yych <= 0xC1)\n          goto yy715;\n        marker = p;\n        goto yy730;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0) {\n          marker = p;\n          goto yy731;\n        }\n        if (yych == 0xED) {\n          marker = p;\n          goto yy733;\n        }\n        marker = p;\n        goto yy732;\n      } else {\n        if (yych <= 0xF0) {\n          marker = p;\n          goto yy734;\n        }\n        if (yych <= 0xF3) {\n          marker = p;\n          goto yy735;\n        }\n        if (yych <= 0xF4) {\n          marker = p;\n          goto yy736;\n        }\n        goto yy715;\n      }\n    }\n  yy719:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy719;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych >= 0x0E)\n          goto yy715;\n      } else {\n        if (yych <= 0xDF)\n          goto yy721;\n        if (yych <= 0xE0)\n          goto yy722;\n        goto yy723;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy724;\n        if (yych <= 0xEF)\n          goto yy723;\n        goto yy725;\n      } else {\n        if (yych <= 0xF3)\n          goto yy726;\n        if (yych <= 0xF4)\n          goto yy727;\n        goto yy715;\n      }\n    }\n  yy720:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy721:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy719;\n    goto yy715;\n  yy722:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy721;\n    goto yy715;\n  yy723:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy721;\n    goto yy715;\n  yy724:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x9F)\n      goto yy721;\n    goto yy715;\n  yy725:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy723;\n    goto yy715;\n  yy726:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy723;\n    goto yy715;\n  yy727:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x8F)\n      goto yy723;\n    goto yy715;\n  yy728:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy728;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych >= 0x0E)\n          goto yy715;\n      } else {\n        if (yych <= 0xDF)\n          goto yy730;\n        if (yych <= 0xE0)\n          goto yy731;\n        goto yy732;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy733;\n        if (yych <= 0xEF)\n          goto yy732;\n        goto yy734;\n      } else {\n        if (yych <= 0xF3)\n          goto yy735;\n        if (yych <= 0xF4)\n          goto yy736;\n        goto yy715;\n      }\n    }\n  yy729:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy730:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy728;\n    goto yy715;\n  yy731:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy730;\n    goto yy715;\n  yy732:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy730;\n    goto yy715;\n  yy733:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x9F)\n      goto yy730;\n    goto yy715;\n  yy734:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy732;\n    goto yy715;\n  yy735:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy732;\n    goto yy715;\n  yy736:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x8F)\n      goto yy732;\n    goto yy715;\n  }\n}\n\n// Scan a closing code fence with length at least len.\nbufsize_t _scan_close_code_fence(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  128, 0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   128, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 32, 0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '`')\n      goto yy739;\n    if (yych == '~')\n      goto yy740;\n    ++p;\n  yy738 : { return 0; }\n  yy739:\n    yych = *(marker = ++p);\n    if (yych == '`')\n      goto yy741;\n    goto yy738;\n  yy740:\n    yych = *(marker = ++p);\n    if (yych == '~')\n      goto yy743;\n    goto yy738;\n  yy741:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy744;\n    }\n  yy742:\n    p = marker;\n    goto yy738;\n  yy743:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy745;\n    }\n    goto yy742;\n  yy744:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy744;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t') {\n        marker = p;\n        goto yy746;\n      }\n      if (yych <= '\\n') {\n        marker = p;\n        goto yy747;\n      }\n      goto yy742;\n    } else {\n      if (yych <= '\\r') {\n        marker = p;\n        goto yy747;\n      }\n      if (yych == ' ') {\n        marker = p;\n        goto yy746;\n      }\n      goto yy742;\n    }\n  yy745:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy745;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t') {\n        marker = p;\n        goto yy748;\n      }\n      if (yych <= '\\n') {\n        marker = p;\n        goto yy749;\n      }\n      goto yy742;\n    } else {\n      if (yych <= '\\r') {\n        marker = p;\n        goto yy749;\n      }\n      if (yych == ' ') {\n        marker = p;\n        goto yy748;\n      }\n      goto yy742;\n    }\n  yy746:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy746;\n    }\n    if (yych <= 0x08)\n      goto yy742;\n    if (yych <= '\\n')\n      goto yy747;\n    if (yych != '\\r')\n      goto yy742;\n  yy747:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy748:\n    yych = *++p;\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t')\n        goto yy748;\n      if (yych >= '\\v')\n        goto yy742;\n    } else {\n      if (yych <= '\\r')\n        goto yy749;\n      if (yych == ' ')\n        goto yy748;\n      goto yy742;\n    }\n  yy749:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  }\n}\n\n// Scans an entity.\n// Returns number of chars matched.\nbufsize_t _scan_entity(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych == '&')\n      goto yy752;\n    ++p;\n  yy751 : { return 0; }\n  yy752:\n    yych = *(marker = ++p);\n    if (yych <= '@') {\n      if (yych != '#')\n        goto yy751;\n    } else {\n      if (yych <= 'Z')\n        goto yy754;\n      if (yych <= '`')\n        goto yy751;\n      if (yych <= 'z')\n        goto yy754;\n      goto yy751;\n    }\n    yych = *++p;\n    if (yych <= 'W') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy755;\n    } else {\n      if (yych <= 'X')\n        goto yy756;\n      if (yych == 'x')\n        goto yy756;\n    }\n  yy753:\n    p = marker;\n    goto yy751;\n  yy754:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy757;\n      goto yy753;\n    } else {\n      if (yych <= 'Z')\n        goto yy757;\n      if (yych <= '`')\n        goto yy753;\n      if (yych <= 'z')\n        goto yy757;\n      goto yy753;\n    }\n  yy755:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy758;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy756:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy760;\n      goto yy753;\n    } else {\n      if (yych <= 'F')\n        goto yy760;\n      if (yych <= '`')\n        goto yy753;\n      if (yych <= 'f')\n        goto yy760;\n      goto yy753;\n    }\n  yy757:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy761;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy761;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy761;\n        goto yy753;\n      }\n    }\n  yy758:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy762;\n    if (yych != ';')\n      goto yy753;\n  yy759:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy760:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy763;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy763;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy763;\n        goto yy753;\n      }\n    }\n  yy761:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy764;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy764;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy764;\n        goto yy753;\n      }\n    }\n  yy762:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy765;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy763:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy766;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy766;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy766;\n        goto yy753;\n      }\n    }\n  yy764:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy767;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy767;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy767;\n        goto yy753;\n      }\n    }\n  yy765:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy768;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy766:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy769;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy769;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy769;\n        goto yy753;\n      }\n    }\n  yy767:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy770;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy770;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy770;\n        goto yy753;\n      }\n    }\n  yy768:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy771;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy769:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy772;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy772;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy772;\n        goto yy753;\n      }\n    }\n  yy770:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy773;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy773;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy773;\n        goto yy753;\n      }\n    }\n  yy771:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy774;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy772:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy774;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy774;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy774;\n        goto yy753;\n      }\n    }\n  yy773:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy775;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy775;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy775;\n        goto yy753;\n      }\n    }\n  yy774:\n    yych = *++p;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy775:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy776;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy776:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy777;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy777:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy778;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy778:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy779;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy779:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy780;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy780:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy781;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy781:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy782;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy782:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy783;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy783:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy784;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy784:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy785;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy785:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy786;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy786:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy787;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy787:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy788;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy788:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy789;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy789:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy790;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy790:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy791;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy791:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy792;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy792:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy793;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy793:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy794;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy794:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy795;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy795:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy796;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy796:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy797;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy797:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy798;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy798:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy774;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy774;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy774;\n        goto yy753;\n      }\n    }\n  }\n}\n\n// Returns positive value if a URL begins in a way that is potentially\n// dangerous, with javascript:, vbscript:, file:, or data:, otherwise 0.\nbufsize_t _scan_dangerous_url(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    yych = *p;\n    if (yych <= 'V') {\n      if (yych <= 'F') {\n        if (yych == 'D')\n          goto yy801;\n        if (yych >= 'F')\n          goto yy802;\n      } else {\n        if (yych == 'J')\n          goto yy803;\n        if (yych >= 'V')\n          goto yy804;\n      }\n    } else {\n      if (yych <= 'f') {\n        if (yych == 'd')\n          goto yy801;\n        if (yych >= 'f')\n          goto yy802;\n      } else {\n        if (yych <= 'j') {\n          if (yych >= 'j')\n            goto yy803;\n        } else {\n          if (yych == 'v')\n            goto yy804;\n        }\n      }\n    }\n    ++p;\n  yy800 : { return 0; }\n  yy801:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'A')\n      goto yy805;\n    if (yych == 'a')\n      goto yy805;\n    goto yy800;\n  yy802:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'I')\n      goto yy807;\n    if (yych == 'i')\n      goto yy807;\n    goto yy800;\n  yy803:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'A')\n      goto yy808;\n    if (yych == 'a')\n      goto yy808;\n    goto yy800;\n  yy804:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'B')\n      goto yy809;\n    if (yych == 'b')\n      goto yy809;\n    goto yy800;\n  yy805:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy810;\n    if (yych == 't')\n      goto yy810;\n  yy806:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy800;\n    } else {\n      goto yy818;\n    }\n  yy807:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy811;\n    if (yych == 'l')\n      goto yy811;\n    goto yy806;\n  yy808:\n    yych = *++p;\n    if (yych == 'V')\n      goto yy812;\n    if (yych == 'v')\n      goto yy812;\n    goto yy806;\n  yy809:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy813;\n    if (yych == 's')\n      goto yy813;\n    goto yy806;\n  yy810:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy814;\n    if (yych == 'a')\n      goto yy814;\n    goto yy806;\n  yy811:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy815;\n    if (yych == 'e')\n      goto yy815;\n    goto yy806;\n  yy812:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy809;\n    if (yych == 'a')\n      goto yy809;\n    goto yy806;\n  yy813:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy816;\n    if (yych == 'c')\n      goto yy816;\n    goto yy806;\n  yy814:\n    yych = *++p;\n    if (yych == ':')\n      goto yy817;\n    goto yy806;\n  yy815:\n    yych = *++p;\n    if (yych == ':')\n      goto yy819;\n    goto yy806;\n  yy816:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy820;\n    if (yych == 'r')\n      goto yy820;\n    goto yy806;\n  yy817:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych == 'I')\n      goto yy821;\n    if (yych == 'i')\n      goto yy821;\n  yy818 : { return (bufsize_t)(p - start); }\n  yy819:\n    ++p;\n    goto yy818;\n  yy820:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy822;\n    if (yych == 'i')\n      goto yy822;\n    goto yy806;\n  yy821:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy823;\n    if (yych == 'm')\n      goto yy823;\n    goto yy806;\n  yy822:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy824;\n    if (yych == 'p')\n      goto yy824;\n    goto yy806;\n  yy823:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy825;\n    if (yych == 'a')\n      goto yy825;\n    goto yy806;\n  yy824:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy815;\n    if (yych == 't')\n      goto yy815;\n    goto yy806;\n  yy825:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy826;\n    if (yych != 'g')\n      goto yy806;\n  yy826:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy827;\n    if (yych != 'e')\n      goto yy806;\n  yy827:\n    yych = *++p;\n    if (yych != '/')\n      goto yy806;\n    yych = *++p;\n    if (yych <= 'W') {\n      if (yych <= 'J') {\n        if (yych == 'G')\n          goto yy828;\n        if (yych <= 'I')\n          goto yy806;\n        goto yy829;\n      } else {\n        if (yych == 'P')\n          goto yy830;\n        if (yych <= 'V')\n          goto yy806;\n        goto yy831;\n      }\n    } else {\n      if (yych <= 'j') {\n        if (yych == 'g')\n          goto yy828;\n        if (yych <= 'i')\n          goto yy806;\n        goto yy829;\n      } else {\n        if (yych <= 'p') {\n          if (yych <= 'o')\n            goto yy806;\n          goto yy830;\n        } else {\n          if (yych == 'w')\n            goto yy831;\n          goto yy806;\n        }\n      }\n    }\n  yy828:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy832;\n    if (yych == 'i')\n      goto yy832;\n    goto yy806;\n  yy829:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy833;\n    if (yych == 'p')\n      goto yy833;\n    goto yy806;\n  yy830:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy834;\n    if (yych == 'n')\n      goto yy834;\n    goto yy806;\n  yy831:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy835;\n    if (yych == 'e')\n      goto yy835;\n    goto yy806;\n  yy832:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy836;\n    if (yych == 'f')\n      goto yy836;\n    goto yy806;\n  yy833:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy834;\n    if (yych != 'e')\n      goto yy806;\n  yy834:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy836;\n    if (yych == 'g')\n      goto yy836;\n    goto yy806;\n  yy835:\n    yych = *++p;\n    if (yych == 'B')\n      goto yy837;\n    if (yych == 'b')\n      goto yy837;\n    goto yy806;\n  yy836:\n    ++p;\n    { return 0; }\n  yy837:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy836;\n    if (yych == 'p')\n      goto yy836;\n    goto yy806;\n  }\n}\n\n// Scans a footnote definition opening.\nbufsize_t _scan_footnote_definition(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   64, 64, 64, 64, 64, 64, 64, 64, 128, 0,  64, 64, 0,  64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        128, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych == '[')\n      goto yy840;\n    ++p;\n  yy839 : { return 0; }\n  yy840:\n    yych = *(marker = ++p);\n    if (yych != '^')\n      goto yy839;\n    yych = *++p;\n    if (yych != ']')\n      goto yy843;\n  yy841:\n    p = marker;\n    goto yy839;\n  yy842:\n    yych = *++p;\n  yy843:\n    if (yybm[0 + yych] & 64) {\n      goto yy842;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= ' ')\n          goto yy841;\n        if (yych <= ']')\n          goto yy851;\n        goto yy841;\n      } else {\n        if (yych <= 0xDF)\n          goto yy844;\n        if (yych <= 0xE0)\n          goto yy845;\n        goto yy846;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy847;\n        if (yych <= 0xEF)\n          goto yy846;\n        goto yy848;\n      } else {\n        if (yych <= 0xF3)\n          goto yy849;\n        if (yych <= 0xF4)\n          goto yy850;\n        goto yy841;\n      }\n    }\n  yy844:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy842;\n    goto yy841;\n  yy845:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy844;\n    goto yy841;\n  yy846:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy844;\n    goto yy841;\n  yy847:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0x9F)\n      goto yy844;\n    goto yy841;\n  yy848:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy846;\n    goto yy841;\n  yy849:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy846;\n    goto yy841;\n  yy850:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0x8F)\n      goto yy846;\n    goto yy841;\n  yy851:\n    yych = *++p;\n    if (yych != ':')\n      goto yy841;\n  yy852:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy852;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/scanners.h",
    "content": "#ifndef CMARK_SCANNERS_H\n#define CMARK_SCANNERS_H\n\n#include \"cmark-gfm.h\"\n#include \"chunk.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,\n                   bufsize_t offset);\nbufsize_t _scan_scheme(const unsigned char *p);\nbufsize_t _scan_autolink_uri(const unsigned char *p);\nbufsize_t _scan_autolink_email(const unsigned char *p);\nbufsize_t _scan_html_tag(const unsigned char *p);\nbufsize_t _scan_liberal_html_tag(const unsigned char *p);\nbufsize_t _scan_html_comment(const unsigned char *p);\nbufsize_t _scan_html_pi(const unsigned char *p);\nbufsize_t _scan_html_declaration(const unsigned char *p);\nbufsize_t _scan_html_cdata(const unsigned char *p);\nbufsize_t _scan_html_block_start(const unsigned char *p);\nbufsize_t _scan_html_block_start_7(const unsigned char *p);\nbufsize_t _scan_html_block_end_1(const unsigned char *p);\nbufsize_t _scan_html_block_end_2(const unsigned char *p);\nbufsize_t _scan_html_block_end_3(const unsigned char *p);\nbufsize_t _scan_html_block_end_4(const unsigned char *p);\nbufsize_t _scan_html_block_end_5(const unsigned char *p);\nbufsize_t _scan_link_title(const unsigned char *p);\nbufsize_t _scan_spacechars(const unsigned char *p);\nbufsize_t _scan_atx_heading_start(const unsigned char *p);\nbufsize_t _scan_setext_heading_line(const unsigned char *p);\nbufsize_t _scan_open_code_fence(const unsigned char *p);\nbufsize_t _scan_close_code_fence(const unsigned char *p);\nbufsize_t _scan_entity(const unsigned char *p);\nbufsize_t _scan_dangerous_url(const unsigned char *p);\nbufsize_t _scan_footnote_definition(const unsigned char *p);\n\n#define scan_scheme(c, n) _scan_at(&_scan_scheme, c, n)\n#define scan_autolink_uri(c, n) _scan_at(&_scan_autolink_uri, c, n)\n#define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)\n#define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)\n#define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)\n#define scan_html_comment(c, n) _scan_at(&_scan_html_comment, c, n)\n#define scan_html_pi(c, n) _scan_at(&_scan_html_pi, c, n)\n#define scan_html_declaration(c, n) _scan_at(&_scan_html_declaration, c, n)\n#define scan_html_cdata(c, n) _scan_at(&_scan_html_cdata, c, n)\n#define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)\n#define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)\n#define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)\n#define scan_html_block_end_2(c, n) _scan_at(&_scan_html_block_end_2, c, n)\n#define scan_html_block_end_3(c, n) _scan_at(&_scan_html_block_end_3, c, n)\n#define scan_html_block_end_4(c, n) _scan_at(&_scan_html_block_end_4, c, n)\n#define scan_html_block_end_5(c, n) _scan_at(&_scan_html_block_end_5, c, n)\n#define scan_link_title(c, n) _scan_at(&_scan_link_title, c, n)\n#define scan_spacechars(c, n) _scan_at(&_scan_spacechars, c, n)\n#define scan_atx_heading_start(c, n) _scan_at(&_scan_atx_heading_start, c, n)\n#define scan_setext_heading_line(c, n)                                         \\\n  _scan_at(&_scan_setext_heading_line, c, n)\n#define scan_open_code_fence(c, n) _scan_at(&_scan_open_code_fence, c, n)\n#define scan_close_code_fence(c, n) _scan_at(&_scan_close_code_fence, c, n)\n#define scan_entity(c, n) _scan_at(&_scan_entity, c, n)\n#define scan_dangerous_url(c, n) _scan_at(&_scan_dangerous_url, c, n)\n#define scan_footnote_definition(c, n) _scan_at(&_scan_footnote_definition, c, n)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/scanners.re",
    "content": "#include <stdlib.h>\n#include \"chunk.h\"\n#include \"scanners.h\"\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c, bufsize_t offset)\n{\n\tbufsize_t res;\n\tunsigned char *ptr = (unsigned char *)c->data;\n\n        if (ptr == NULL || offset > c->len) {\n          return 0;\n        } else {\n\t  unsigned char lim = ptr[c->len];\n\n\t  ptr[c->len] = '\\0';\n\t  res = scanner(ptr + offset);\n\t  ptr[c->len] = lim;\n        }\n\n\treturn res;\n}\n\n/*!re2c\n  re2c:define:YYCTYPE  = \"unsigned char\";\n  re2c:define:YYCURSOR = p;\n  re2c:define:YYMARKER = marker;\n  re2c:define:YYCTXMARKER = marker;\n  re2c:yyfill:enable = 0;\n\n  wordchar = [^\\x00-\\x20];\n\n  spacechar = [ \\t\\v\\f\\r\\n];\n\n  reg_char     = [^\\\\()\\x00-\\x20];\n\n  escaped_char = [\\\\][!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-];\n\n  tagname = [A-Za-z][A-Za-z0-9-]*;\n\n  blocktagname = 'address'|'article'|'aside'|'base'|'basefont'|'blockquote'|'body'|'caption'|'center'|'col'|'colgroup'|'dd'|'details'|'dialog'|'dir'|'div'|'dl'|'dt'|'fieldset'|'figcaption'|'figure'|'footer'|'form'|'frame'|'frameset'|'h1'|'h2'|'h3'|'h4'|'h5'|'h6'|'head'|'header'|'hr'|'html'|'iframe'|'legend'|'li'|'link'|'main'|'menu'|'menuitem'|'nav'|'noframes'|'ol'|'optgroup'|'option'|'p'|'param'|'section'|'source'|'title'|'summary'|'table'|'tbody'|'td'|'tfoot'|'th'|'thead'|'title'|'tr'|'track'|'ul';\n\n  attributename = [a-zA-Z_:][a-zA-Z0-9:._-]*;\n\n  unquotedvalue = [^ \\t\\r\\n\\v\\f\"'=<>`\\x00]+;\n  singlequotedvalue = ['][^'\\x00]*['];\n  doublequotedvalue = [\"][^\"\\x00]*[\"];\n\n  attributevalue = unquotedvalue | singlequotedvalue | doublequotedvalue;\n\n  attributevaluespec = spacechar* [=] spacechar* attributevalue;\n\n  attribute = spacechar+ attributename attributevaluespec?;\n\n  opentag = tagname attribute* spacechar* [/]? [>];\n  closetag = [/] tagname spacechar* [>];\n\n  htmlcomment = \"--\" ([^\\x00-]+ | \"-\" [^\\x00-] | \"--\" [^\\x00>])* \"-->\";\n\n  processinginstruction = ([^?>\\x00]+ | [?][^>\\x00] | [>])+;\n\n  declaration = [A-Z]+ spacechar+ [^>\\x00]*;\n\n  cdata = \"CDATA[\" ([^\\]\\x00]+ | \"]\" [^\\]\\x00] | \"]]\" [^>\\x00])*;\n\n  htmltag = opentag | closetag;\n\n  in_parens_nosp   = [(] (reg_char|escaped_char|[\\\\])* [)];\n\n  in_double_quotes = [\"] (escaped_char|[^\"\\x00])* [\"];\n  in_single_quotes = ['] (escaped_char|[^'\\x00])* ['];\n  in_parens        = [(] (escaped_char|[^)\\x00])* [)];\n\n  scheme           = [A-Za-z][A-Za-z0-9.+-]{1,31};\n*/\n\n// Try to match a scheme including colon.\nbufsize_t _scan_scheme(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  scheme [:] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match URI autolink after first <, returning number of chars matched.\nbufsize_t _scan_autolink_uri(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  scheme [:][^\\x00-\\x20<>]*[>]  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match email autolink after first <, returning num of chars matched.\nbufsize_t _scan_autolink_email(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\n    [@]\n    [a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\n    ([.][a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\n    [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_html_tag(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  htmltag { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to (liberally) match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_liberal_html_tag(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]+ [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_comment(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  htmlcomment { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_pi(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  processinginstruction { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_declaration(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  declaration { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_cdata(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  cdata { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block tag start line, returning\n// an integer code for the type of block (1-6, matching the spec).\n// #7 is handled by a separate function, below.\nbufsize_t _scan_html_block_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [<] ('script'|'pre'|'textarea'|'style') (spacechar | [>]) { return 1; }\n  '<!--' { return 2; }\n  '<?' { return 3; }\n  '<!' [A-Z] { return 4; }\n  '<![CDATA[' { return 5; }\n  [<] [/]? blocktagname (spacechar | [/]? [>])  { return 6; }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block tag start line of type 7, returning\n// 7 if successful, 0 if not.\nbufsize_t _scan_html_block_start_7(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [<] (opentag | closetag) [\\t\\n\\f ]* [\\r\\n] { return 7; }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 1\nbufsize_t _scan_html_block_end_1(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* [<] [/] ('script'|'pre'|'textarea'|'style') [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 2\nbufsize_t _scan_html_block_end_2(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '-->' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 3\nbufsize_t _scan_html_block_end_3(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '?>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 4\nbufsize_t _scan_html_block_end_4(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 5\nbufsize_t _scan_html_block_end_5(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* ']]>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match a link title (in single quotes, in double quotes, or\n// in parentheses), returning number of chars matched.  Allow one\n// level of internal nesting (quotes within quotes).\nbufsize_t _scan_link_title(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [\"] (escaped_char|[^\"\\x00])* [\"]   { return (bufsize_t)(p - start); }\n  ['] (escaped_char|[^'\\x00])* ['] { return (bufsize_t)(p - start); }\n  [(] (escaped_char|[^()\\x00])* [)]  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match space characters, including newlines.\nbufsize_t _scan_spacechars(const unsigned char *p)\n{\n  const unsigned char *start = p; \\\n/*!re2c\n  [ \\t\\v\\f\\r\\n]+ { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match ATX heading start.\nbufsize_t _scan_atx_heading_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [#]{1,6} ([ \\t]+|[\\r\\n])  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match setext heading line.  Return 1 for level-1 heading,\n// 2 for level-2, 0 for no match.\nbufsize_t _scan_setext_heading_line(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [=]+ [ \\t]* [\\r\\n] { return 1; }\n  [-]+ [ \\t]* [\\r\\n] { return 2; }\n  * { return 0; }\n*/\n}\n\n// Scan an opening code fence.\nbufsize_t _scan_open_code_fence(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [`]{3,} / [^`\\r\\n\\x00]*[\\r\\n] { return (bufsize_t)(p - start); }\n  [~]{3,} / [^\\r\\n\\x00]*[\\r\\n] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scan a closing code fence with length at least len.\nbufsize_t _scan_close_code_fence(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [`]{3,} / [ \\t]*[\\r\\n] { return (bufsize_t)(p - start); }\n  [~]{3,} / [ \\t]*[\\r\\n] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scans an entity.\n// Returns number of chars matched.\nbufsize_t _scan_entity(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [&] ([#] ([Xx][A-Fa-f0-9]{1,6}|[0-9]{1,7}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]\n     { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Returns positive value if a URL begins in a way that is potentially\n// dangerous, with javascript:, vbscript:, file:, or data:, otherwise 0.\nbufsize_t _scan_dangerous_url(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  'data:image/' ('png'|'gif'|'jpeg'|'webp') { return 0; }\n  'javascript:' | 'vbscript:' | 'file:' | 'data:' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scans a footnote definition opening.\nbufsize_t _scan_footnote_definition(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  '[^' ([^\\] \\r\\n\\x00\\t]+) ']:' [ \\t]* { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/syntax_extension.c",
    "content": "#include <stdlib.h>\n#include <assert.h>\n\n#include \"cmark-gfm.h\"\n#include \"syntax_extension.h\"\n#include \"buffer.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nstatic cmark_mem *_mem = &CMARK_DEFAULT_MEM_ALLOCATOR;\n\nvoid cmark_syntax_extension_free(cmark_mem *mem, cmark_syntax_extension *extension) {\n  if (extension->free_function && extension->priv) {\n    extension->free_function(mem, extension->priv);\n  }\n\n  cmark_llist_free(mem, extension->special_inline_chars);\n  mem->free(extension->name);\n  mem->free(extension);\n}\n\ncmark_syntax_extension *cmark_syntax_extension_new(const char *name) {\n  cmark_syntax_extension *res = (cmark_syntax_extension *) _mem->calloc(1, sizeof(cmark_syntax_extension));\n  res->name = (char *) _mem->calloc(1, sizeof(char) * (strlen(name)) + 1);\n  strcpy(res->name, name);\n  return res;\n}\n\ncmark_node_type cmark_syntax_extension_add_node(int is_inline) {\n  cmark_node_type *ref = !is_inline ? &CMARK_NODE_LAST_BLOCK : &CMARK_NODE_LAST_INLINE;\n\n  if ((*ref & CMARK_NODE_VALUE_MASK) == CMARK_NODE_VALUE_MASK) {\n    assert(false);\n    return (cmark_node_type) 0;\n  }\n\n  return *ref = (cmark_node_type) ((int) *ref + 1);\n}\n\nvoid cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension,\n                                         int emphasis) {\n  extension->emphasis = emphasis == 1;\n}\n\nvoid cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,\n                                                cmark_open_block_func func) {\n  extension->try_opening_block = func;\n}\n\nvoid cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,\n                                                 cmark_match_block_func func) {\n  extension->last_block_matches = func;\n}\n\nvoid cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,\n                                                  cmark_match_inline_func func) {\n  extension->match_inline = func;\n}\n\nvoid cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,\n                                                       cmark_inline_from_delim_func func) {\n  extension->insert_inline_from_delim = func;\n}\n\nvoid cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,\n                                                     cmark_llist *special_chars) {\n  extension->special_inline_chars = special_chars;\n}\n\nvoid cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,\n                                                     cmark_get_type_string_func func) {\n  extension->get_type_string_func = func;\n}\n\nvoid cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,\n                                                 cmark_can_contain_func func) {\n  extension->can_contain_func = func;\n}\n\nvoid cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,\n                                                      cmark_contains_inlines_func func) {\n  extension->contains_inlines_func = func;\n}\n\nvoid cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,\n                                                       cmark_common_render_func func) {\n  extension->commonmark_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,\n                                                      cmark_common_render_func func) {\n  extension->plaintext_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,\n                                                  cmark_common_render_func func) {\n  extension->latex_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,\n                                              cmark_xml_attr_func func) {\n  extension->xml_attr_func = func;\n}\n\nvoid cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,\n                                                cmark_common_render_func func) {\n  extension->man_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,\n                                                 cmark_html_render_func func) {\n  extension->html_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,\n                                                 cmark_html_filter_func func) {\n  extension->html_filter_func = func;\n}\n\nvoid cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,\n                                                 cmark_postprocess_func func) {\n  extension->postprocess_func = func;\n}\n\nvoid cmark_syntax_extension_set_private(cmark_syntax_extension *extension,\n                                        void *priv,\n                                        cmark_free_func free_func) {\n  extension->priv = priv;\n  extension->free_function = free_func;\n}\n\nvoid *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) {\n    return extension->priv;\n}\n\nvoid cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,\n                                                  cmark_opaque_alloc_func func) {\n  extension->opaque_alloc_func = func;\n}\n\nvoid cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,\n                                                 cmark_opaque_free_func func) {\n  extension->opaque_free_func = func;\n}\n\nvoid cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,\n                                                       cmark_commonmark_escape_func func) {\n  extension->commonmark_escape_func = func;\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/syntax_extension.h",
    "content": "#ifndef CMARK_SYNTAX_EXTENSION_H\n#define CMARK_SYNTAX_EXTENSION_H\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n#include \"config.h\"\n\nstruct cmark_syntax_extension {\n  cmark_match_block_func          last_block_matches;\n  cmark_open_block_func           try_opening_block;\n  cmark_match_inline_func         match_inline;\n  cmark_inline_from_delim_func    insert_inline_from_delim;\n  cmark_llist                   * special_inline_chars;\n  char                          * name;\n  void                          * priv;\n  bool                            emphasis;\n  cmark_free_func                 free_function;\n  cmark_get_type_string_func      get_type_string_func;\n  cmark_can_contain_func          can_contain_func;\n  cmark_contains_inlines_func     contains_inlines_func;\n  cmark_common_render_func        commonmark_render_func;\n  cmark_common_render_func        plaintext_render_func;\n  cmark_common_render_func        latex_render_func;\n  cmark_xml_attr_func             xml_attr_func;\n  cmark_common_render_func        man_render_func;\n  cmark_html_render_func          html_render_func;\n  cmark_html_filter_func          html_filter_func;\n  cmark_postprocess_func          postprocess_func;\n  cmark_opaque_alloc_func         opaque_alloc_func;\n  cmark_opaque_free_func          opaque_free_func;\n  cmark_commonmark_escape_func    commonmark_escape_func;\n};\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/utf8.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <assert.h>\n\n#include \"cmark_ctype.h\"\n#include \"utf8.h\"\n\nstatic const int8_t utf8proc_utf8class[256] = {\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0};\n\nstatic void encode_unknown(cmark_strbuf *buf) {\n  static const uint8_t repl[] = {239, 191, 189};\n  cmark_strbuf_put(buf, repl, 3);\n}\n\nstatic int utf8proc_charlen(const uint8_t *str, bufsize_t str_len) {\n  int length, i;\n\n  if (!str_len)\n    return 0;\n\n  length = utf8proc_utf8class[str[0]];\n\n  if (!length)\n    return -1;\n\n  if (str_len >= 0 && (bufsize_t)length > str_len)\n    return -str_len;\n\n  for (i = 1; i < length; i++) {\n    if ((str[i] & 0xC0) != 0x80)\n      return -i;\n  }\n\n  return length;\n}\n\n// Validate a single UTF-8 character according to RFC 3629.\nstatic int utf8proc_valid(const uint8_t *str, bufsize_t str_len) {\n  int length = utf8proc_utf8class[str[0]];\n\n  if (!length)\n    return -1;\n\n  if ((bufsize_t)length > str_len)\n    return -str_len;\n\n  switch (length) {\n  case 2:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if (str[0] < 0xC2) {\n      // Overlong\n      return -length;\n    }\n    break;\n\n  case 3:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if ((str[2] & 0xC0) != 0x80)\n      return -2;\n    if (str[0] == 0xE0) {\n      if (str[1] < 0xA0) {\n        // Overlong\n        return -length;\n      }\n    } else if (str[0] == 0xED) {\n      if (str[1] >= 0xA0) {\n        // Surrogate\n        return -length;\n      }\n    }\n    break;\n\n  case 4:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if ((str[2] & 0xC0) != 0x80)\n      return -2;\n    if ((str[3] & 0xC0) != 0x80)\n      return -3;\n    if (str[0] == 0xF0) {\n      if (str[1] < 0x90) {\n        // Overlong\n        return -length;\n      }\n    } else if (str[0] >= 0xF4) {\n      if (str[0] > 0xF4 || str[1] >= 0x90) {\n        // Above 0x10FFFF\n        return -length;\n      }\n    }\n    break;\n  }\n\n  return length;\n}\n\nvoid cmark_utf8proc_check(cmark_strbuf *ob, const uint8_t *line,\n                          bufsize_t size) {\n  bufsize_t i = 0;\n\n  while (i < size) {\n    bufsize_t org = i;\n    int charlen = 0;\n\n    while (i < size) {\n      if (line[i] < 0x80 && line[i] != 0) {\n        i++;\n      } else if (line[i] >= 0x80) {\n        charlen = utf8proc_valid(line + i, size - i);\n        if (charlen < 0) {\n          charlen = -charlen;\n          break;\n        }\n        i += charlen;\n      } else if (line[i] == 0) {\n        // ASCII NUL is technically valid but rejected\n        // for security reasons.\n        charlen = 1;\n        break;\n      }\n    }\n\n    if (i > org) {\n      cmark_strbuf_put(ob, line + org, i - org);\n    }\n\n    if (i >= size) {\n      break;\n    } else {\n      // Invalid UTF-8\n      encode_unknown(ob);\n      i += charlen;\n    }\n  }\n}\n\nint cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len,\n                           int32_t *dst) {\n  int length;\n  int32_t uc = -1;\n\n  *dst = -1;\n  length = utf8proc_charlen(str, str_len);\n  if (length < 0)\n    return -1;\n\n  switch (length) {\n  case 1:\n    uc = str[0];\n    break;\n  case 2:\n    uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);\n    if (uc < 0x80)\n      uc = -1;\n    break;\n  case 3:\n    uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) + (str[2] & 0x3F);\n    if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000))\n      uc = -1;\n    break;\n  case 4:\n    uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) +\n         ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);\n    if (uc < 0x10000 || uc >= 0x110000)\n      uc = -1;\n    break;\n  }\n\n  if (uc < 0)\n    return -1;\n\n  *dst = uc;\n  return length;\n}\n\nvoid cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf) {\n  uint8_t dst[4];\n  bufsize_t len = 0;\n\n  assert(uc >= 0);\n\n  if (uc < 0x80) {\n    dst[0] = (uint8_t)(uc);\n    len = 1;\n  } else if (uc < 0x800) {\n    dst[0] = (uint8_t)(0xC0 + (uc >> 6));\n    dst[1] = 0x80 + (uc & 0x3F);\n    len = 2;\n  } else if (uc == 0xFFFF) {\n    dst[0] = 0xFF;\n    len = 1;\n  } else if (uc == 0xFFFE) {\n    dst[0] = 0xFE;\n    len = 1;\n  } else if (uc < 0x10000) {\n    dst[0] = (uint8_t)(0xE0 + (uc >> 12));\n    dst[1] = 0x80 + ((uc >> 6) & 0x3F);\n    dst[2] = 0x80 + (uc & 0x3F);\n    len = 3;\n  } else if (uc < 0x110000) {\n    dst[0] = (uint8_t)(0xF0 + (uc >> 18));\n    dst[1] = 0x80 + ((uc >> 12) & 0x3F);\n    dst[2] = 0x80 + ((uc >> 6) & 0x3F);\n    dst[3] = 0x80 + (uc & 0x3F);\n    len = 4;\n  } else {\n    encode_unknown(buf);\n    return;\n  }\n\n  cmark_strbuf_put(buf, dst, len);\n}\n\nvoid cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,\n                              bufsize_t len) {\n  int32_t c;\n\n#define bufpush(x) cmark_utf8proc_encode_char(x, dest)\n\n  while (len > 0) {\n    bufsize_t char_len = cmark_utf8proc_iterate(str, len, &c);\n\n    if (char_len >= 0) {\n#include \"case_fold_switch.inc\"\n    } else {\n      encode_unknown(dest);\n      char_len = -char_len;\n    }\n\n    str += char_len;\n    len -= char_len;\n  }\n}\n\n// matches anything in the Zs class, plus LF, CR, TAB, FF.\nint cmark_utf8proc_is_space(int32_t uc) {\n  return (uc == 9 || uc == 10 || uc == 12 || uc == 13 || uc == 32 ||\n          uc == 160 || uc == 5760 || (uc >= 8192 && uc <= 8202) || uc == 8239 ||\n          uc == 8287 || uc == 12288);\n}\n\n// matches anything in the P[cdefios] classes.\nint cmark_utf8proc_is_punctuation(int32_t uc) {\n  return (\n      (uc < 128 && cmark_ispunct((char)uc)) || uc == 161 || uc == 167 ||\n      uc == 171 || uc == 182 || uc == 183 || uc == 187 || uc == 191 ||\n      uc == 894 || uc == 903 || (uc >= 1370 && uc <= 1375) || uc == 1417 ||\n      uc == 1418 || uc == 1470 || uc == 1472 || uc == 1475 || uc == 1478 ||\n      uc == 1523 || uc == 1524 || uc == 1545 || uc == 1546 || uc == 1548 ||\n      uc == 1549 || uc == 1563 || uc == 1566 || uc == 1567 ||\n      (uc >= 1642 && uc <= 1645) || uc == 1748 || (uc >= 1792 && uc <= 1805) ||\n      (uc >= 2039 && uc <= 2041) || (uc >= 2096 && uc <= 2110) || uc == 2142 ||\n      uc == 2404 || uc == 2405 || uc == 2416 || uc == 2800 || uc == 3572 ||\n      uc == 3663 || uc == 3674 || uc == 3675 || (uc >= 3844 && uc <= 3858) ||\n      uc == 3860 || (uc >= 3898 && uc <= 3901) || uc == 3973 ||\n      (uc >= 4048 && uc <= 4052) || uc == 4057 || uc == 4058 ||\n      (uc >= 4170 && uc <= 4175) || uc == 4347 || (uc >= 4960 && uc <= 4968) ||\n      uc == 5120 || uc == 5741 || uc == 5742 || uc == 5787 || uc == 5788 ||\n      (uc >= 5867 && uc <= 5869) || uc == 5941 || uc == 5942 ||\n      (uc >= 6100 && uc <= 6102) || (uc >= 6104 && uc <= 6106) ||\n      (uc >= 6144 && uc <= 6154) || uc == 6468 || uc == 6469 || uc == 6686 ||\n      uc == 6687 || (uc >= 6816 && uc <= 6822) || (uc >= 6824 && uc <= 6829) ||\n      (uc >= 7002 && uc <= 7008) || (uc >= 7164 && uc <= 7167) ||\n      (uc >= 7227 && uc <= 7231) || uc == 7294 || uc == 7295 ||\n      (uc >= 7360 && uc <= 7367) || uc == 7379 || (uc >= 8208 && uc <= 8231) ||\n      (uc >= 8240 && uc <= 8259) || (uc >= 8261 && uc <= 8273) ||\n      (uc >= 8275 && uc <= 8286) || uc == 8317 || uc == 8318 || uc == 8333 ||\n      uc == 8334 || (uc >= 8968 && uc <= 8971) || uc == 9001 || uc == 9002 ||\n      (uc >= 10088 && uc <= 10101) || uc == 10181 || uc == 10182 ||\n      (uc >= 10214 && uc <= 10223) || (uc >= 10627 && uc <= 10648) ||\n      (uc >= 10712 && uc <= 10715) || uc == 10748 || uc == 10749 ||\n      (uc >= 11513 && uc <= 11516) || uc == 11518 || uc == 11519 ||\n      uc == 11632 || (uc >= 11776 && uc <= 11822) ||\n      (uc >= 11824 && uc <= 11842) || (uc >= 12289 && uc <= 12291) ||\n      (uc >= 12296 && uc <= 12305) || (uc >= 12308 && uc <= 12319) ||\n      uc == 12336 || uc == 12349 || uc == 12448 || uc == 12539 || uc == 42238 ||\n      uc == 42239 || (uc >= 42509 && uc <= 42511) || uc == 42611 ||\n      uc == 42622 || (uc >= 42738 && uc <= 42743) ||\n      (uc >= 43124 && uc <= 43127) || uc == 43214 || uc == 43215 ||\n      (uc >= 43256 && uc <= 43258) || uc == 43310 || uc == 43311 ||\n      uc == 43359 || (uc >= 43457 && uc <= 43469) || uc == 43486 ||\n      uc == 43487 || (uc >= 43612 && uc <= 43615) || uc == 43742 ||\n      uc == 43743 || uc == 43760 || uc == 43761 || uc == 44011 || uc == 64830 ||\n      uc == 64831 || (uc >= 65040 && uc <= 65049) ||\n      (uc >= 65072 && uc <= 65106) || (uc >= 65108 && uc <= 65121) ||\n      uc == 65123 || uc == 65128 || uc == 65130 || uc == 65131 ||\n      (uc >= 65281 && uc <= 65283) || (uc >= 65285 && uc <= 65290) ||\n      (uc >= 65292 && uc <= 65295) || uc == 65306 || uc == 65307 ||\n      uc == 65311 || uc == 65312 || (uc >= 65339 && uc <= 65341) ||\n      uc == 65343 || uc == 65371 || uc == 65373 ||\n      (uc >= 65375 && uc <= 65381) || (uc >= 65792 && uc <= 65794) ||\n      uc == 66463 || uc == 66512 || uc == 66927 || uc == 67671 || uc == 67871 ||\n      uc == 67903 || (uc >= 68176 && uc <= 68184) || uc == 68223 ||\n      (uc >= 68336 && uc <= 68342) || (uc >= 68409 && uc <= 68415) ||\n      (uc >= 68505 && uc <= 68508) || (uc >= 69703 && uc <= 69709) ||\n      uc == 69819 || uc == 69820 || (uc >= 69822 && uc <= 69825) ||\n      (uc >= 69952 && uc <= 69955) || uc == 70004 || uc == 70005 ||\n      (uc >= 70085 && uc <= 70088) || uc == 70093 ||\n      (uc >= 70200 && uc <= 70205) || uc == 70854 ||\n      (uc >= 71105 && uc <= 71113) || (uc >= 71233 && uc <= 71235) ||\n      (uc >= 74864 && uc <= 74868) || uc == 92782 || uc == 92783 ||\n      uc == 92917 || (uc >= 92983 && uc <= 92987) || uc == 92996 ||\n      uc == 113823);\n}\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/utf8.h",
    "content": "#ifndef CMARK_UTF8_H\n#define CMARK_UTF8_H\n\n#include <stdint.h>\n#include \"buffer.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,\n                              bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst);\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_check(cmark_strbuf *dest, const uint8_t *line,\n                          bufsize_t size);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_is_space(int32_t uc);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_is_punctuation(int32_t uc);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/cmark-gfm/src/xml.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"houdini.h\"\n#include \"syntax_extension.h\"\n\n#define BUFFER_SIZE 100\n#define MAX_INDENT 40\n\n// Functions to convert cmark_nodes to XML strings.\n\nstatic void escape_xml(cmark_strbuf *dest, const unsigned char *source,\n                       bufsize_t length) {\n  houdini_escape_html0(dest, source, length, 0);\n}\n\nstruct render_state {\n  cmark_strbuf *xml;\n  int indent;\n};\n\nstatic CMARK_INLINE void indent(struct render_state *state) {\n  int i;\n  for (i = 0; i < state->indent && i < MAX_INDENT; i++) {\n    cmark_strbuf_putc(state->xml, ' ');\n  }\n}\n\nstatic int S_render_node(cmark_node *node, cmark_event_type ev_type,\n                         struct render_state *state, int options) {\n  cmark_strbuf *xml = state->xml;\n  bool literal = false;\n  cmark_delim_type delim;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  char buffer[BUFFER_SIZE];\n\n  if (entering) {\n    indent(state);\n    cmark_strbuf_putc(xml, '<');\n    cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n\n    if (options & CMARK_OPT_SOURCEPOS && node->start_line != 0) {\n      snprintf(buffer, BUFFER_SIZE, \" sourcepos=\\\"%d:%d-%d:%d\\\"\",\n               node->start_line, node->start_column, node->end_line,\n               node->end_column);\n      cmark_strbuf_puts(xml, buffer);\n    }\n\n    if (node->extension && node->extension->xml_attr_func) {\n      const char* r = node->extension->xml_attr_func(node->extension, node);\n      if (r != NULL)\n        cmark_strbuf_puts(xml, r);\n    }\n\n    literal = false;\n\n    switch (node->type) {\n    case CMARK_NODE_DOCUMENT:\n      cmark_strbuf_puts(xml, \" xmlns=\\\"http://commonmark.org/xml/1.0\\\"\");\n      break;\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_BLOCK:\n    case CMARK_NODE_HTML_INLINE:\n      cmark_strbuf_puts(xml, \" xml:space=\\\"preserve\\\">\");\n      escape_xml(xml, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(xml, \"</\");\n      cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n      literal = true;\n      break;\n    case CMARK_NODE_LIST:\n      switch (cmark_node_get_list_type(node)) {\n      case CMARK_ORDERED_LIST:\n        cmark_strbuf_puts(xml, \" type=\\\"ordered\\\"\");\n        snprintf(buffer, BUFFER_SIZE, \" start=\\\"%d\\\"\",\n                 cmark_node_get_list_start(node));\n        cmark_strbuf_puts(xml, buffer);\n        delim = cmark_node_get_list_delim(node);\n        if (delim == CMARK_PAREN_DELIM) {\n          cmark_strbuf_puts(xml, \" delim=\\\"paren\\\"\");\n        } else if (delim == CMARK_PERIOD_DELIM) {\n          cmark_strbuf_puts(xml, \" delim=\\\"period\\\"\");\n        }\n        break;\n      case CMARK_BULLET_LIST:\n        cmark_strbuf_puts(xml, \" type=\\\"bullet\\\"\");\n        break;\n      default:\n        break;\n      }\n      snprintf(buffer, BUFFER_SIZE, \" tight=\\\"%s\\\"\",\n               (cmark_node_get_list_tight(node) ? \"true\" : \"false\"));\n      cmark_strbuf_puts(xml, buffer);\n      break;\n    case CMARK_NODE_HEADING:\n      snprintf(buffer, BUFFER_SIZE, \" level=\\\"%d\\\"\", node->as.heading.level);\n      cmark_strbuf_puts(xml, buffer);\n      break;\n    case CMARK_NODE_CODE_BLOCK:\n      if (node->as.code.info.len > 0) {\n        cmark_strbuf_puts(xml, \" info=\\\"\");\n        escape_xml(xml, node->as.code.info.data, node->as.code.info.len);\n        cmark_strbuf_putc(xml, '\"');\n      }\n      cmark_strbuf_puts(xml, \" xml:space=\\\"preserve\\\">\");\n      escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);\n      cmark_strbuf_puts(xml, \"</\");\n      cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n      literal = true;\n      break;\n    case CMARK_NODE_CUSTOM_BLOCK:\n    case CMARK_NODE_CUSTOM_INLINE:\n      cmark_strbuf_puts(xml, \" on_enter=\\\"\");\n      escape_xml(xml, node->as.custom.on_enter.data,\n                 node->as.custom.on_enter.len);\n      cmark_strbuf_putc(xml, '\"');\n      cmark_strbuf_puts(xml, \" on_exit=\\\"\");\n      escape_xml(xml, node->as.custom.on_exit.data,\n                 node->as.custom.on_exit.len);\n      cmark_strbuf_putc(xml, '\"');\n      break;\n    case CMARK_NODE_LINK:\n    case CMARK_NODE_IMAGE:\n      cmark_strbuf_puts(xml, \" destination=\\\"\");\n      escape_xml(xml, node->as.link.url.data, node->as.link.url.len);\n      cmark_strbuf_putc(xml, '\"');\n      cmark_strbuf_puts(xml, \" title=\\\"\");\n      escape_xml(xml, node->as.link.title.data, node->as.link.title.len);\n      cmark_strbuf_putc(xml, '\"');\n      break;\n    default:\n      break;\n    }\n    if (node->first_child) {\n      state->indent += 2;\n    } else if (!literal) {\n      cmark_strbuf_puts(xml, \" /\");\n    }\n    cmark_strbuf_puts(xml, \">\\n\");\n\n  } else if (node->first_child) {\n    state->indent -= 2;\n    indent(state);\n    cmark_strbuf_puts(xml, \"</\");\n    cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n    cmark_strbuf_puts(xml, \">\\n\");\n  }\n\n  return 1;\n}\n\nchar *cmark_render_xml(cmark_node *root, int options) {\n  return cmark_render_xml_with_mem(root, options, cmark_node_mem(root));\n}\n\nchar *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem) {\n  char *result;\n  cmark_strbuf xml = CMARK_BUF_INIT(mem);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n  struct render_state state = {&xml, 0};\n\n  cmark_iter *iter = cmark_iter_new(root);\n\n  cmark_strbuf_puts(state.xml, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n  cmark_strbuf_puts(state.xml,\n                    \"<!DOCTYPE document SYSTEM \\\"CommonMark.dtd\\\">\\n\");\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    S_render_node(cur, ev_type, &state, options);\n  }\n  result = (char *)cmark_strbuf_detach(&xml);\n\n  cmark_iter_free(iter);\n  return result;\n}\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/CMakeLists.txt",
    "content": "# Require CMake 3.10. If available, use the policies up to CMake 3.22.\ncmake_minimum_required (VERSION 3.10...3.22)\n\nproject (benchmark VERSION 1.8.5 LANGUAGES CXX)\n\noption(BENCHMARK_ENABLE_TESTING \"Enable testing of the benchmark library.\" ON)\noption(BENCHMARK_ENABLE_EXCEPTIONS \"Enable the use of exceptions in the benchmark library.\" ON)\noption(BENCHMARK_ENABLE_LTO \"Enable link time optimisation of the benchmark library.\" OFF)\noption(BENCHMARK_USE_LIBCXX \"Build and test using libc++ as the standard library.\" OFF)\noption(BENCHMARK_ENABLE_WERROR \"Build Release candidates with -Werror.\" ON)\noption(BENCHMARK_FORCE_WERROR \"Build Release candidates with -Werror regardless of compiler issues.\" OFF)\n\nif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"PGI\")\n  # PGC++ maybe reporting false positives.\n  set(BENCHMARK_ENABLE_WERROR OFF)\nendif()\nif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"NVHPC\")\n  set(BENCHMARK_ENABLE_WERROR OFF)\nendif()\nif(BENCHMARK_FORCE_WERROR)\n  set(BENCHMARK_ENABLE_WERROR ON)\nendif(BENCHMARK_FORCE_WERROR)\n\nif(NOT (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL \"MSVC\"))\n  option(BENCHMARK_BUILD_32_BITS \"Build a 32 bit version of the library.\" OFF)\nelse()\n  set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL \"Build a 32 bit version of the library - unsupported when using MSVC)\" FORCE)\nendif()\noption(BENCHMARK_ENABLE_INSTALL \"Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)\" ON)\noption(BENCHMARK_ENABLE_DOXYGEN \"Build documentation with Doxygen.\" OFF)\noption(BENCHMARK_INSTALL_DOCS \"Enable installation of documentation.\" ON)\n\n# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which\n# may require downloading the source code.\noption(BENCHMARK_DOWNLOAD_DEPENDENCIES \"Allow the downloading and in-tree building of unmet dependencies\" OFF)\n\n# This option can be used to disable building and running unit tests which depend on gtest\n# in cases where it is not possible to build or find a valid version of gtest.\noption(BENCHMARK_ENABLE_GTEST_TESTS \"Enable building the unit tests which depend on gtest\" ON)\noption(BENCHMARK_USE_BUNDLED_GTEST \"Use bundled GoogleTest. If disabled, the find_package(GTest) will be used.\" ON)\n\noption(BENCHMARK_ENABLE_LIBPFM \"Enable performance counters provided by libpfm\" OFF)\n\n# Export only public symbols\nset(CMAKE_CXX_VISIBILITY_PRESET hidden)\nset(CMAKE_VISIBILITY_INLINES_HIDDEN ON)\n\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n    # As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and\n    # cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the\n    # undocumented, but working variable.\n    # See https://gitlab.kitware.com/cmake/cmake/-/issues/15170\n    set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID})\n    if(${CMAKE_SYSTEM_PROCESSOR} MATCHES \"ARM\")\n      set(CMAKE_CROSSCOMPILING TRUE)\n    endif()\nendif()\n\nset(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)\nfunction(should_enable_assembly_tests)\n  if(CMAKE_BUILD_TYPE)\n    string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)\n    if (${CMAKE_BUILD_TYPE_LOWER} MATCHES \"coverage\")\n      # FIXME: The --coverage flag needs to be removed when building assembly\n      # tests for this to work.\n      return()\n    endif()\n  endif()\n  if (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL \"MSVC\")\n    return()\n  elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64\")\n    return()\n  elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)\n    # FIXME: Make these work on 32 bit builds\n    return()\n  elseif(BENCHMARK_BUILD_32_BITS)\n     # FIXME: Make these work on 32 bit builds\n    return()\n  endif()\n  find_program(LLVM_FILECHECK_EXE FileCheck)\n  if (LLVM_FILECHECK_EXE)\n    set(LLVM_FILECHECK_EXE \"${LLVM_FILECHECK_EXE}\" CACHE PATH \"llvm filecheck\" FORCE)\n    message(STATUS \"LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}\")\n  else()\n    message(STATUS \"Failed to find LLVM FileCheck\")\n    return()\n  endif()\n  set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)\nendfunction()\nshould_enable_assembly_tests()\n\n# This option disables the building and running of the assembly verification tests\noption(BENCHMARK_ENABLE_ASSEMBLY_TESTS \"Enable building and running the assembly tests\"\n    ${ENABLE_ASSEMBLY_TESTS_DEFAULT})\n\n# Make sure we can import out CMake functions\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules\")\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\")\n\n\n# Read the git tags to determine the project version\ninclude(GetGitVersion)\nget_git_version(GIT_VERSION)\n\n# If no git version can be determined, use the version\n# from the project() command\nif (\"${GIT_VERSION}\" STREQUAL \"v0.0.0\")\n  set(VERSION \"v${benchmark_VERSION}\")\nelse()\n  set(VERSION \"${GIT_VERSION}\")\nendif()\n\n# Normalize version: drop \"v\" prefix, replace first \"-\" with \".\",\n# drop everything after second \"-\" (including said \"-\").\nstring(STRIP ${VERSION} VERSION)\nif(VERSION MATCHES v[^-]*-)\n   string(REGEX REPLACE \"v([^-]*)-([0-9]+)-.*\" \"\\\\1.\\\\2\"  NORMALIZED_VERSION ${VERSION})\nelse()\n   string(REGEX REPLACE \"v(.*)\" \"\\\\1\" NORMALIZED_VERSION ${VERSION})\nendif()\n\n# Tell the user what versions we are using\nmessage(STATUS \"Google Benchmark version: ${VERSION}, normalized to ${NORMALIZED_VERSION}\")\n\n# The version of the libraries\nset(GENERIC_LIB_VERSION ${NORMALIZED_VERSION})\nstring(SUBSTRING ${NORMALIZED_VERSION} 0 1 GENERIC_LIB_SOVERSION)\n\n# Import our CMake modules\ninclude(AddCXXCompilerFlag)\ninclude(CheckCXXCompilerFlag)\ninclude(CheckLibraryExists)\ninclude(CXXFeatureCheck)\n\ncheck_library_exists(rt shm_open \"\" HAVE_LIB_RT)\n\nif (BENCHMARK_BUILD_32_BITS)\n  add_required_cxx_compiler_flag(-m32)\nendif()\n\nset(BENCHMARK_CXX_STANDARD 14)\n\nset(CMAKE_CXX_STANDARD ${BENCHMARK_CXX_STANDARD})\nset(CMAKE_CXX_STANDARD_REQUIRED YES)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nif (MSVC)\n  # Turn compiler warnings up to 11\n  string(REGEX REPLACE \"[-/]W[1-4]\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /W4\")\n  add_definitions(-D_CRT_SECURE_NO_WARNINGS)\n\n  if (NOT BENCHMARK_ENABLE_EXCEPTIONS)\n    add_cxx_compiler_flag(-EHs-)\n    add_cxx_compiler_flag(-EHa-)\n    add_definitions(-D_HAS_EXCEPTIONS=0)\n  endif()\n  # Link time optimisation\n  if (BENCHMARK_ENABLE_LTO)\n    set(CMAKE_CXX_FLAGS_RELEASE \"${CMAKE_CXX_FLAGS_RELEASE} /GL\")\n    set(CMAKE_STATIC_LINKER_FLAGS_RELEASE \"${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG\")\n    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE \"${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG\")\n    set(CMAKE_EXE_LINKER_FLAGS_RELEASE \"${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG\")\n\n    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO \"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n\n    set(CMAKE_CXX_FLAGS_MINSIZEREL \"${CMAKE_CXX_FLAGS_MINSIZEREL} /GL\")\n    set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL \"${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n    set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL \"${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n    set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL \"${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n  endif()\nelse()\n  # Turn on Large-file Support\n  add_definitions(-D_FILE_OFFSET_BITS=64)\n  add_definitions(-D_LARGEFILE64_SOURCE)\n  add_definitions(-D_LARGEFILE_SOURCE)\n  # Turn compiler warnings up to 11\n  add_cxx_compiler_flag(-Wall)\n  add_cxx_compiler_flag(-Wextra)\n  add_cxx_compiler_flag(-Wshadow)\n  add_cxx_compiler_flag(-Wfloat-equal)\n  add_cxx_compiler_flag(-Wold-style-cast)\n  add_cxx_compiler_flag(-Wconversion)\n  if(BENCHMARK_ENABLE_WERROR)\n      add_cxx_compiler_flag(-Werror)\n  endif()\n  if (NOT BENCHMARK_ENABLE_TESTING)\n    # Disable warning when compiling tests as gtest does not use 'override'.\n    add_cxx_compiler_flag(-Wsuggest-override)\n  endif()\n  add_cxx_compiler_flag(-pedantic)\n  add_cxx_compiler_flag(-pedantic-errors)\n  add_cxx_compiler_flag(-Wshorten-64-to-32)\n  add_cxx_compiler_flag(-fstrict-aliasing)\n  # Disable warnings regarding deprecated parts of the library while building\n  # and testing those parts of the library.\n  add_cxx_compiler_flag(-Wno-deprecated-declarations)\n  if (CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n    # Intel silently ignores '-Wno-deprecated-declarations',\n    # warning no. 1786 must be explicitly disabled.\n    # See #631 for rationale.\n    add_cxx_compiler_flag(-wd1786)\n    add_cxx_compiler_flag(-fno-finite-math-only)\n  endif()\n  # Disable deprecation warnings for release builds (when -Werror is enabled).\n  if(BENCHMARK_ENABLE_WERROR)\n      add_cxx_compiler_flag(-Wno-deprecated)\n  endif()\n  if (NOT BENCHMARK_ENABLE_EXCEPTIONS)\n    add_cxx_compiler_flag(-fno-exceptions)\n  endif()\n\n  if (HAVE_CXX_FLAG_FSTRICT_ALIASING)\n    if (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\") #ICC17u2: Many false positives for Wstrict-aliasing\n      add_cxx_compiler_flag(-Wstrict-aliasing)\n    endif()\n  endif()\n  # ICC17u2: overloaded virtual function \"benchmark::Fixture::SetUp\" is only partially overridden\n  # (because of deprecated overload)\n  add_cxx_compiler_flag(-wd654)\n  add_cxx_compiler_flag(-Wthread-safety)\n  if (HAVE_CXX_FLAG_WTHREAD_SAFETY)\n    cxx_feature_check(THREAD_SAFETY_ATTRIBUTES \"-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include\")\n  endif()\n\n  # On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a\n  # predefined macro, which turns on all of the wonderful libc extensions.\n  # However g++ doesn't do this in Cygwin so we have to define it ourselves\n  # since we depend on GNU/POSIX/BSD extensions.\n  if (CYGWIN)\n    add_definitions(-D_GNU_SOURCE=1)\n  endif()\n\n  if (QNXNTO)\n    add_definitions(-D_QNX_SOURCE)\n  endif()\n\n  # Link time optimisation\n  if (BENCHMARK_ENABLE_LTO)\n    add_cxx_compiler_flag(-flto)\n    add_cxx_compiler_flag(-Wno-lto-type-mismatch)\n    if (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\")\n      find_program(GCC_AR gcc-ar)\n      if (GCC_AR)\n        set(CMAKE_AR ${GCC_AR})\n      endif()\n      find_program(GCC_RANLIB gcc-ranlib)\n      if (GCC_RANLIB)\n        set(CMAKE_RANLIB ${GCC_RANLIB})\n      endif()\n    elseif(\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n      include(llvm-toolchain)\n    endif()\n  endif()\n\n  # Coverage build type\n  set(BENCHMARK_CXX_FLAGS_COVERAGE \"${CMAKE_CXX_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used by the C++ compiler during coverage builds.\"\n    FORCE)\n  set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE \"${CMAKE_EXE_LINKER_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used for linking binaries during coverage builds.\"\n    FORCE)\n  set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE \"${CMAKE_SHARED_LINKER_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used by the shared libraries linker during coverage builds.\"\n    FORCE)\n  mark_as_advanced(\n    BENCHMARK_CXX_FLAGS_COVERAGE\n    BENCHMARK_EXE_LINKER_FLAGS_COVERAGE\n    BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE)\n  set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\" CACHE STRING\n    \"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.\")\n  add_cxx_compiler_flag(--coverage COVERAGE)\nendif()\n\nif (BENCHMARK_USE_LIBCXX)\n  if (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n    add_cxx_compiler_flag(-stdlib=libc++)\n  elseif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\" OR\n          \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Intel\" OR\n          \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"IntelLLVM\")\n    add_cxx_compiler_flag(-nostdinc++)\n    message(WARNING \"libc++ header path must be manually specified using CMAKE_CXX_FLAGS\")\n    # Adding -nodefaultlibs directly to CMAKE_<TYPE>_LINKER_FLAGS will break\n    # configuration checks such as 'find_package(Threads)'\n    list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)\n    # -lc++ cannot be added directly to CMAKE_<TYPE>_LINKER_FLAGS because\n    # linker flags appear before all linker inputs and -lc++ must appear after.\n    list(APPEND BENCHMARK_CXX_LIBRARIES c++)\n  else()\n    message(FATAL_ERROR \"-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler\")\n  endif()\nendif(BENCHMARK_USE_LIBCXX)\n\nset(EXTRA_CXX_FLAGS \"\")\nif (WIN32 AND \"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n  # Clang on Windows fails to compile the regex feature check under C++11\n  set(EXTRA_CXX_FLAGS \"-DCMAKE_CXX_STANDARD=14\")\nendif()\n\n# C++ feature checks\n# Determine the correct regular expression engine to use\ncxx_feature_check(STD_REGEX ${EXTRA_CXX_FLAGS})\ncxx_feature_check(GNU_POSIX_REGEX ${EXTRA_CXX_FLAGS})\ncxx_feature_check(POSIX_REGEX ${EXTRA_CXX_FLAGS})\nif(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)\n  message(FATAL_ERROR \"Failed to determine the source files for the regular expression backend\")\nendif()\nif (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX\n        AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)\n  message(WARNING \"Using std::regex with exceptions disabled is not fully supported\")\nendif()\n\ncxx_feature_check(STEADY_CLOCK)\n# Ensure we have pthreads\nset(THREADS_PREFER_PTHREAD_FLAG ON)\nfind_package(Threads REQUIRED)\ncxx_feature_check(PTHREAD_AFFINITY)\n\nif (BENCHMARK_ENABLE_LIBPFM)\n  find_package(PFM REQUIRED)\nendif()\n\n# Set up directories\ninclude_directories(${PROJECT_SOURCE_DIR}/include)\n\n# Build the targets\nadd_subdirectory(src)\n\nif (BENCHMARK_ENABLE_TESTING)\n  enable_testing()\n  if (BENCHMARK_ENABLE_GTEST_TESTS AND\n      NOT (TARGET gtest AND TARGET gtest_main AND\n           TARGET gmock AND TARGET gmock_main))\n    if (BENCHMARK_USE_BUNDLED_GTEST)\n      include(GoogleTest)\n    else()\n      find_package(GTest CONFIG REQUIRED)\n      add_library(gtest ALIAS GTest::gtest)\n      add_library(gtest_main ALIAS GTest::gtest_main)\n      add_library(gmock ALIAS GTest::gmock)\n      add_library(gmock_main ALIAS GTest::gmock_main)\n    endif()\n  endif()\n  add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/AddCXXCompilerFlag.cmake",
    "content": "# - Adds a compiler flag if it is supported by the compiler\n#\n# This function checks that the supplied compiler flag is supported and then\n# adds it to the corresponding compiler flags\n#\n#  add_cxx_compiler_flag(<FLAG> [<VARIANT>])\n#\n# - Example\n#\n# include(AddCXXCompilerFlag)\n# add_cxx_compiler_flag(-Wall)\n# add_cxx_compiler_flag(-no-strict-aliasing RELEASE)\n# Requires CMake 2.6+\n\nif(__add_cxx_compiler_flag)\n  return()\nendif()\nset(__add_cxx_compiler_flag INCLUDED)\n\ninclude(CheckCXXCompilerFlag)\n\nfunction(mangle_compiler_flag FLAG OUTPUT)\n  string(TOUPPER \"HAVE_CXX_FLAG_${FLAG}\" SANITIZED_FLAG)\n  string(REPLACE \"+\" \"X\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  string(REGEX REPLACE \"[^A-Za-z_0-9]\" \"_\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  string(REGEX REPLACE \"_+\" \"_\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  set(${OUTPUT} \"${SANITIZED_FLAG}\" PARENT_SCOPE)\nendfunction(mangle_compiler_flag)\n\nfunction(add_cxx_compiler_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\n  if(${MANGLED_FLAG})\n    if(ARGC GREATER 1)\n      set(VARIANT ${ARGV1})\n      string(TOUPPER \"_${VARIANT}\" VARIANT)\n    else()\n      set(VARIANT \"\")\n    endif()\n    set(CMAKE_CXX_FLAGS${VARIANT} \"${CMAKE_CXX_FLAGS${VARIANT}} ${BENCHMARK_CXX_FLAGS${VARIANT}} ${FLAG}\" PARENT_SCOPE)\n  endif()\nendfunction()\n\nfunction(add_required_cxx_compiler_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\n  if(${MANGLED_FLAG})\n    if(ARGC GREATER 1)\n      set(VARIANT ${ARGV1})\n      string(TOUPPER \"_${VARIANT}\" VARIANT)\n    else()\n      set(VARIANT \"\")\n    endif()\n    set(CMAKE_CXX_FLAGS${VARIANT} \"${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_MODULE_LINKER_FLAGS \"${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\" PARENT_SCOPE)\n  else()\n    message(FATAL_ERROR \"Required flag '${FLAG}' is not supported by the compiler\")\n  endif()\nendfunction()\n\nfunction(check_cxx_warning_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  # Add -Werror to ensure the compiler generates an error if the warning flag\n  # doesn't exist.\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\nendfunction()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/CXXFeatureCheck.cmake",
    "content": "# - Compile and run code to check for C++ features\n#\n# This functions compiles a source file under the `cmake` folder\n# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake\n# environment\n#\n#  cxx_feature_check(<FLAG> [<VARIANT>])\n#\n# - Example\n#\n# include(CXXFeatureCheck)\n# cxx_feature_check(STD_REGEX)\n# Requires CMake 2.8.12+\n\nif(__cxx_feature_check)\n  return()\nendif()\nset(__cxx_feature_check INCLUDED)\n\noption(CXXFEATURECHECK_DEBUG OFF)\n\nfunction(cxx_feature_check FILE)\n  string(TOLOWER ${FILE} FILE)\n  string(TOUPPER ${FILE} VAR)\n  string(TOUPPER \"HAVE_${VAR}\" FEATURE)\n  if (DEFINED HAVE_${VAR})\n    set(HAVE_${VAR} 1 PARENT_SCOPE)\n    add_definitions(-DHAVE_${VAR})\n    return()\n  endif()\n\n  set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\n  if (ARGC GREATER 1)\n    message(STATUS \"Enabling additional flags: ${ARGV1}\")\n    list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})\n  endif()\n\n  if (NOT DEFINED COMPILE_${FEATURE})\n    if(CMAKE_CROSSCOMPILING)\n      message(STATUS \"Cross-compiling to test ${FEATURE}\")\n      try_compile(COMPILE_${FEATURE}\n              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp\n              CXX_STANDARD 11\n              CXX_STANDARD_REQUIRED ON\n              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}\n              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}\n              OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)\n      if(COMPILE_${FEATURE})\n        message(WARNING\n              \"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0\")\n        set(RUN_${FEATURE} 0 CACHE INTERNAL \"\")\n      else()\n        set(RUN_${FEATURE} 1 CACHE INTERNAL \"\")\n      endif()\n    else()\n      message(STATUS \"Compiling and running to test ${FEATURE}\")\n      try_run(RUN_${FEATURE} COMPILE_${FEATURE}\n              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp\n              CXX_STANDARD 11\n              CXX_STANDARD_REQUIRED ON\n              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}\n              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}\n              COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)\n    endif()\n  endif()\n\n  if(RUN_${FEATURE} EQUAL 0)\n    message(STATUS \"Performing Test ${FEATURE} -- success\")\n    set(HAVE_${VAR} 1 PARENT_SCOPE)\n    add_definitions(-DHAVE_${VAR})\n  else()\n    if(NOT COMPILE_${FEATURE})\n      if(CXXFEATURECHECK_DEBUG)\n        message(STATUS \"Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}\")\n      else()\n        message(STATUS \"Performing Test ${FEATURE} -- failed to compile\")\n      endif()\n    else()\n      message(STATUS \"Performing Test ${FEATURE} -- compiled but failed to run\")\n    endif()\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/Config.cmake.in",
    "content": "@PACKAGE_INIT@\n\ninclude (CMakeFindDependencyMacro)\n\nfind_dependency (Threads)\n\nif (@BENCHMARK_ENABLE_LIBPFM@)\n    find_dependency (PFM)\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake\")\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/GetGitVersion.cmake",
    "content": "# - Returns a version string from Git tags\n#\n# This function inspects the annotated git tags for the project and returns a string\n# into a CMake variable\n#\n#  get_git_version(<var>)\n#\n# - Example\n#\n# include(GetGitVersion)\n# get_git_version(GIT_VERSION)\n#\n# Requires CMake 2.8.11+\nfind_package(Git)\n\nif(__get_git_version)\n  return()\nendif()\nset(__get_git_version INCLUDED)\n\nfunction(get_git_version var)\n  if(GIT_EXECUTABLE)\n      execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match \"v[0-9]*.[0-9]*.[0-9]*\" --abbrev=8 --dirty\n          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n          RESULT_VARIABLE status\n          OUTPUT_VARIABLE GIT_VERSION\n          ERROR_QUIET)\n      if(status)\n          set(GIT_VERSION \"v0.0.0\")\n      endif()\n  else()\n      set(GIT_VERSION \"v0.0.0\")\n  endif()\n\n  set(${var} ${GIT_VERSION} PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/GoogleTest.cmake",
    "content": "# Download and unpack googletest at configure time\nset(GOOGLETEST_PREFIX \"${benchmark_BINARY_DIR}/third_party/googletest\")\nconfigure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY)\n\nset(GOOGLETEST_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/googletest\" CACHE PATH \"\") # Mind the quotes\nexecute_process(COMMAND ${CMAKE_COMMAND} -G \"${CMAKE_GENERATOR}\"\n  -DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH=${GOOGLETEST_PATH} .\n  RESULT_VARIABLE result\n  WORKING_DIRECTORY ${GOOGLETEST_PREFIX}\n)\n\nif(result)\n  message(FATAL_ERROR \"CMake step for googletest failed: ${result}\")\nendif()\n\nexecute_process(\n  COMMAND ${CMAKE_COMMAND} --build .\n  RESULT_VARIABLE result\n  WORKING_DIRECTORY ${GOOGLETEST_PREFIX}\n)\n\nif(result)\n  message(FATAL_ERROR \"Build step for googletest failed: ${result}\")\nendif()\n\n# Prevent overriding the parent project's compiler/linker\n# settings on Windows\nset(gtest_force_shared_crt ON CACHE BOOL \"\" FORCE)\n\ninclude(${GOOGLETEST_PREFIX}/googletest-paths.cmake)\n\n# Add googletest directly to our build. This defines\n# the gtest and gtest_main targets.\nadd_subdirectory(${GOOGLETEST_SOURCE_DIR}\n                 ${GOOGLETEST_BINARY_DIR}\n                 EXCLUDE_FROM_ALL)\n\n# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.\nif (MSVC)\n  target_compile_options(gtest PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gtest_main PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gmock PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gmock_main PRIVATE \"/wd4244\" \"/wd4722\")\nelse()\n  target_compile_options(gtest PRIVATE \"-w\")\n  target_compile_options(gtest_main PRIVATE \"-w\")\n  target_compile_options(gmock PRIVATE \"-w\")\n  target_compile_options(gmock_main PRIVATE \"-w\")\nendif()\n\nif(NOT DEFINED GTEST_COMPILE_COMMANDS)\n    set(GTEST_COMPILE_COMMANDS ON)\nendif()\n\nset_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/GoogleTest.cmake.in",
    "content": "cmake_minimum_required(VERSION 2.8.12)\n\nproject(googletest-download NONE)\n\n# Enable ExternalProject CMake module\ninclude(ExternalProject)\n\noption(ALLOW_DOWNLOADING_GOOGLETEST \"If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet\" OFF)\nset(GOOGLETEST_PATH \"/usr/src/googletest\" CACHE PATH\n                    \"Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs\")\n\n# Download and install GoogleTest\n\nmessage(STATUS \"Looking for Google Test sources\")\nmessage(STATUS \"Looking for Google Test sources in ${GOOGLETEST_PATH}\")\nif(EXISTS \"${GOOGLETEST_PATH}\"            AND IS_DIRECTORY \"${GOOGLETEST_PATH}\"            AND EXISTS \"${GOOGLETEST_PATH}/CMakeLists.txt\" AND\n   EXISTS \"${GOOGLETEST_PATH}/googletest\" AND IS_DIRECTORY \"${GOOGLETEST_PATH}/googletest\" AND EXISTS \"${GOOGLETEST_PATH}/googletest/CMakeLists.txt\" AND\n   EXISTS \"${GOOGLETEST_PATH}/googlemock\" AND IS_DIRECTORY \"${GOOGLETEST_PATH}/googlemock\" AND EXISTS \"${GOOGLETEST_PATH}/googlemock/CMakeLists.txt\")\n  message(STATUS \"Found Google Test in ${GOOGLETEST_PATH}\")\n\n  ExternalProject_Add(\n    googletest\n    PREFIX            \"${CMAKE_BINARY_DIR}\"\n    DOWNLOAD_DIR      \"${CMAKE_BINARY_DIR}/download\"\n    SOURCE_DIR        \"${GOOGLETEST_PATH}\" # use existing src dir.\n    BINARY_DIR        \"${CMAKE_BINARY_DIR}/build\"\n    CONFIGURE_COMMAND \"\"\n    BUILD_COMMAND     \"\"\n    INSTALL_COMMAND   \"\"\n    TEST_COMMAND      \"\"\n  )\nelse()\n  if(NOT ALLOW_DOWNLOADING_GOOGLETEST)\n    message(SEND_ERROR \"Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable BENCHMARK_DOWNLOAD_DEPENDENCIES, or disable BENCHMARK_USE_BUNDLED_GTEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.\")\n    return()\n  else()\n    message(WARNING \"Did not find Google Test sources! Fetching from web...\")\n    ExternalProject_Add(\n      googletest\n      GIT_REPOSITORY    https://github.com/google/googletest.git\n      GIT_TAG           \"release-1.11.0\"\n      PREFIX            \"${CMAKE_BINARY_DIR}\"\n      STAMP_DIR         \"${CMAKE_BINARY_DIR}/stamp\"\n      DOWNLOAD_DIR      \"${CMAKE_BINARY_DIR}/download\"\n      SOURCE_DIR        \"${CMAKE_BINARY_DIR}/src\"\n      BINARY_DIR        \"${CMAKE_BINARY_DIR}/build\"\n      CONFIGURE_COMMAND \"\"\n      BUILD_COMMAND     \"\"\n      INSTALL_COMMAND   \"\"\n      TEST_COMMAND      \"\"\n    )\n  endif()\nendif()\n\nExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR)\nfile(WRITE googletest-paths.cmake\n\"set(GOOGLETEST_SOURCE_DIR \\\"${SOURCE_DIR}\\\")\nset(GOOGLETEST_BINARY_DIR \\\"${BINARY_DIR}\\\")\n\")\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/Modules/FindLLVMAr.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMAR_EXECUTABLE\n  NAMES llvm-ar\n  DOC \"The llvm-ar executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMAr\n  DEFAULT_MSG\n  LLVMAR_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMAr PROPERTIES\n  URL https://llvm.org/docs/CommandGuide/llvm-ar.html\n  DESCRIPTION \"create, modify, and extract from archives\"\n)\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/Modules/FindLLVMNm.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMNM_EXECUTABLE\n  NAMES llvm-nm\n  DOC \"The llvm-nm executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMNm\n  DEFAULT_MSG\n  LLVMNM_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMNm PROPERTIES\n  URL https://llvm.org/docs/CommandGuide/llvm-nm.html\n  DESCRIPTION \"list LLVM bitcode and object file’s symbol table\"\n)\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/Modules/FindLLVMRanLib.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMRANLIB_EXECUTABLE\n  NAMES llvm-ranlib\n  DOC \"The llvm-ranlib executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMRanLib\n  DEFAULT_MSG\n  LLVMRANLIB_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMRanLib PROPERTIES\n  DESCRIPTION \"generate index for LLVM archive\"\n)\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/Modules/FindPFM.cmake",
    "content": "# If successful, the following variables will be defined:\n# PFM_FOUND.\n# PFM_LIBRARIES\n# PFM_INCLUDE_DIRS\n# the following target will be defined:\n# PFM::libpfm\n\ninclude(FeatureSummary)\ninclude(FindPackageHandleStandardArgs)\n\nset_package_properties(PFM PROPERTIES\n                       URL http://perfmon2.sourceforge.net/\n                       DESCRIPTION \"A helper library to develop monitoring tools\"\n                       PURPOSE \"Used to program specific performance monitoring events\")\n\nfind_library(PFM_LIBRARY NAMES pfm)\nfind_path(PFM_INCLUDE_DIR NAMES perfmon/pfmlib.h)\n\nfind_package_handle_standard_args(PFM REQUIRED_VARS PFM_LIBRARY PFM_INCLUDE_DIR)\n\nif (PFM_FOUND AND NOT TARGET PFM::libpfm)\n    add_library(PFM::libpfm UNKNOWN IMPORTED)\n    set_target_properties(PFM::libpfm PROPERTIES\n        IMPORTED_LOCATION \"${PFM_LIBRARY}\"\n        INTERFACE_INCLUDE_DIRECTORIES \"${PFM_INCLUDE_DIR}\")\nendif()\n\nmark_as_advanced(PFM_LIBRARY PFM_INCLUDE_DIR)\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/benchmark.pc.in",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=${prefix}\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: @PROJECT_NAME@\nDescription: Google microbenchmark framework\nVersion: @VERSION@\n\nLibs: -L${libdir} -lbenchmark\nLibs.private: -lpthread @BENCHMARK_PRIVATE_LINK_LIBRARIES@\nCflags: -I${includedir}\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/benchmark_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\n\nName: @PROJECT_NAME@\nDescription: Google microbenchmark framework (with main() function)\nVersion: @VERSION@\nRequires: benchmark\nLibs: -L${libdir} -lbenchmark_main\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/gnu_posix_regex.cpp",
    "content": "#include <gnuregex.h>\n#include <string>\nint main() {\n  std::string str = \"test0159\";\n  regex_t re;\n  int ec = regcomp(&re, \"^[a-z]+[0-9]+$\", REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    return ec;\n  }\n  return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;\n}\n\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/llvm-toolchain.cmake",
    "content": "find_package(LLVMAr REQUIRED)\nset(CMAKE_AR \"${LLVMAR_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n\nfind_package(LLVMNm REQUIRED)\nset(CMAKE_NM \"${LLVMNM_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n\nfind_package(LLVMRanLib REQUIRED)\nset(CMAKE_RANLIB \"${LLVMRANLIB_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/posix_regex.cpp",
    "content": "#include <regex.h>\n#include <string>\nint main() {\n  std::string str = \"test0159\";\n  regex_t re;\n  int ec = regcomp(&re, \"^[a-z]+[0-9]+$\", REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    return ec;\n  }\n  int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;\n  regfree(&re);\n  return ret;\n}\n\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/pthread_affinity.cpp",
    "content": "#include <pthread.h>\nint main() {\n  cpu_set_t set;\n  CPU_ZERO(&set);\n  for (int i = 0; i < CPU_SETSIZE; ++i) {\n    CPU_SET(i, &set);\n    CPU_CLR(i, &set);\n  }\n  pthread_t self = pthread_self();\n  int ret;\n  ret = pthread_getaffinity_np(self, sizeof(set), &set);\n  if (ret != 0) return ret;\n  ret = pthread_setaffinity_np(self, sizeof(set), &set);\n  if (ret != 0) return ret;\n  return 0;\n}\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/split_list.cmake",
    "content": "macro(split_list listname)\n  string(REPLACE \";\" \" \" ${listname} \"${${listname}}\")\nendmacro()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/std_regex.cpp",
    "content": "#include <regex>\n#include <string>\nint main() {\n  const std::string str = \"test0159\";\n  std::regex re;\n  re = std::regex(\"^[a-z]+[0-9]+$\",\n       std::regex_constants::extended | std::regex_constants::nosubs);\n  return std::regex_search(str, re) ? 0 : -1;\n}\n\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/steady_clock.cpp",
    "content": "#include <chrono>\n\nint main() {\n    typedef std::chrono::steady_clock Clock;\n    Clock::time_point tp = Clock::now();\n    ((void)tp);\n}\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/cmake/thread_safety_attributes.cpp",
    "content": "#define HAVE_THREAD_SAFETY_ATTRIBUTES\n#include \"../src/mutex.h\"\n\nint main() {}\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/include/benchmark/benchmark.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Support for registering benchmarks for functions.\n\n/* Example usage:\n// Define a function that executes the code to be measured a\n// specified number of times:\nstatic void BM_StringCreation(benchmark::State& state) {\n  for (auto _ : state)\n    std::string empty_string;\n}\n\n// Register the function as a benchmark\nBENCHMARK(BM_StringCreation);\n\n// Define another benchmark\nstatic void BM_StringCopy(benchmark::State& state) {\n  std::string x = \"hello\";\n  for (auto _ : state)\n    std::string copy(x);\n}\nBENCHMARK(BM_StringCopy);\n\n// Augment the main() program to invoke benchmarks if specified\n// via the --benchmark_filter command line flag.  E.g.,\n//       my_unittest --benchmark_filter=all\n//       my_unittest --benchmark_filter=BM_StringCreation\n//       my_unittest --benchmark_filter=String\n//       my_unittest --benchmark_filter='Copy|Creation'\nint main(int argc, char** argv) {\n  benchmark::Initialize(&argc, argv);\n  benchmark::RunSpecifiedBenchmarks();\n  benchmark::Shutdown();\n  return 0;\n}\n\n// Sometimes a family of microbenchmarks can be implemented with\n// just one routine that takes an extra argument to specify which\n// one of the family of benchmarks to run.  For example, the following\n// code defines a family of microbenchmarks for measuring the speed\n// of memcpy() calls of different lengths:\n\nstatic void BM_memcpy(benchmark::State& state) {\n  char* src = new char[state.range(0)]; char* dst = new char[state.range(0)];\n  memset(src, 'x', state.range(0));\n  for (auto _ : state)\n    memcpy(dst, src, state.range(0));\n  state.SetBytesProcessed(state.iterations() * state.range(0));\n  delete[] src; delete[] dst;\n}\nBENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);\n\n// The preceding code is quite repetitive, and can be replaced with the\n// following short-hand.  The following invocation will pick a few\n// appropriate arguments in the specified range and will generate a\n// microbenchmark for each such argument.\nBENCHMARK(BM_memcpy)->Range(8, 8<<10);\n\n// You might have a microbenchmark that depends on two inputs.  For\n// example, the following code defines a family of microbenchmarks for\n// measuring the speed of set insertion.\nstatic void BM_SetInsert(benchmark::State& state) {\n  set<int> data;\n  for (auto _ : state) {\n    state.PauseTiming();\n    data = ConstructRandomSet(state.range(0));\n    state.ResumeTiming();\n    for (int j = 0; j < state.range(1); ++j)\n      data.insert(RandomNumber());\n  }\n}\nBENCHMARK(BM_SetInsert)\n   ->Args({1<<10, 128})\n   ->Args({2<<10, 128})\n   ->Args({4<<10, 128})\n   ->Args({8<<10, 128})\n   ->Args({1<<10, 512})\n   ->Args({2<<10, 512})\n   ->Args({4<<10, 512})\n   ->Args({8<<10, 512});\n\n// The preceding code is quite repetitive, and can be replaced with\n// the following short-hand.  The following macro will pick a few\n// appropriate arguments in the product of the two specified ranges\n// and will generate a microbenchmark for each such pair.\nBENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});\n\n// For more complex patterns of inputs, passing a custom function\n// to Apply allows programmatic specification of an\n// arbitrary set of arguments to run the microbenchmark on.\n// The following example enumerates a dense range on\n// one parameter, and a sparse range on the second.\nstatic void CustomArguments(benchmark::internal::Benchmark* b) {\n  for (int i = 0; i <= 10; ++i)\n    for (int j = 32; j <= 1024*1024; j *= 8)\n      b->Args({i, j});\n}\nBENCHMARK(BM_SetInsert)->Apply(CustomArguments);\n\n// Templated microbenchmarks work the same way:\n// Produce then consume 'size' messages 'iters' times\n// Measures throughput in the absence of multiprogramming.\ntemplate <class Q> int BM_Sequential(benchmark::State& state) {\n  Q q;\n  typename Q::value_type v;\n  for (auto _ : state) {\n    for (int i = state.range(0); i--; )\n      q.push(v);\n    for (int e = state.range(0); e--; )\n      q.Wait(&v);\n  }\n  // actually messages, not bytes:\n  state.SetBytesProcessed(state.iterations() * state.range(0));\n}\nBENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);\n\nUse `Benchmark::MinTime(double t)` to set the minimum time used to run the\nbenchmark. This option overrides the `benchmark_min_time` flag.\n\nvoid BM_test(benchmark::State& state) {\n ... body ...\n}\nBENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.\n\nIn a multithreaded test, it is guaranteed that none of the threads will start\nuntil all have reached the loop start, and all will have finished before any\nthread exits the loop body. As such, any global setup or teardown you want to\ndo can be wrapped in a check against the thread index:\n\nstatic void BM_MultiThreaded(benchmark::State& state) {\n  if (state.thread_index() == 0) {\n    // Setup code here.\n  }\n  for (auto _ : state) {\n    // Run the test as normal.\n  }\n  if (state.thread_index() == 0) {\n    // Teardown code here.\n  }\n}\nBENCHMARK(BM_MultiThreaded)->Threads(4);\n\n\nIf a benchmark runs a few milliseconds it may be hard to visually compare the\nmeasured times, since the output data is given in nanoseconds per default. In\norder to manually set the time unit, you can specify it manually:\n\nBENCHMARK(BM_test)->Unit(benchmark::kMillisecond);\n*/\n\n#ifndef BENCHMARK_BENCHMARK_H_\n#define BENCHMARK_BENCHMARK_H_\n\n// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.\n#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)\n#define BENCHMARK_HAS_CXX11\n#endif\n\n// This _MSC_VER check should detect VS 2017 v15.3 and newer.\n#if __cplusplus >= 201703L || \\\n    (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)\n#define BENCHMARK_HAS_CXX17\n#endif\n\n#include <stdint.h>\n\n#include <algorithm>\n#include <cassert>\n#include <cstddef>\n#include <iosfwd>\n#include <limits>\n#include <map>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"benchmark/export.h\"\n\n#if defined(BENCHMARK_HAS_CXX11)\n#include <atomic>\n#include <initializer_list>\n#include <type_traits>\n#include <utility>\n#endif\n\n#if defined(_MSC_VER)\n#include <intrin.h>  // for _ReadWriteBarrier\n#endif\n\n#ifndef BENCHMARK_HAS_CXX11\n#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);                         \\\n  TypeName& operator=(const TypeName&)\n#else\n#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&) = delete;                \\\n  TypeName& operator=(const TypeName&) = delete\n#endif\n\n#ifdef BENCHMARK_HAS_CXX17\n#define BENCHMARK_UNUSED [[maybe_unused]]\n#elif defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_UNUSED __attribute__((unused))\n#else\n#define BENCHMARK_UNUSED\n#endif\n\n// Used to annotate functions, methods and classes so they\n// are not optimized by the compiler. Useful for tests\n// where you expect loops to stay in place churning cycles\n#if defined(__clang__)\n#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))\n#elif defined(__GNUC__) || defined(__GNUG__)\n#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))\n#else\n// MSVC & Intel do not have a no-optimize attribute, only line pragmas\n#define BENCHMARK_DONT_OPTIMIZE\n#endif\n\n#if defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))\n#elif defined(_MSC_VER) && !defined(__clang__)\n#define BENCHMARK_ALWAYS_INLINE __forceinline\n#define __func__ __FUNCTION__\n#else\n#define BENCHMARK_ALWAYS_INLINE\n#endif\n\n#define BENCHMARK_INTERNAL_TOSTRING2(x) #x\n#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)\n\n// clang-format off\n#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)\n#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)\n#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING \\\n  _Pragma(\"GCC diagnostic push\")             \\\n  _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma(\"GCC diagnostic pop\")\n#elif defined(__NVCOMPILER)\n#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)\n#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING \\\n  _Pragma(\"diagnostic push\") \\\n  _Pragma(\"diag_suppress deprecated_entity_with_custom_message\")\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma(\"diagnostic pop\")\n#else\n#define BENCHMARK_BUILTIN_EXPECT(x, y) x\n#define BENCHMARK_DEPRECATED_MSG(msg)\n#define BENCHMARK_WARNING_MSG(msg)                           \\\n  __pragma(message(__FILE__ \"(\" BENCHMARK_INTERNAL_TOSTRING( \\\n      __LINE__) \") : warning note: \" msg))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING\n#endif\n// clang-format on\n\n#if defined(__GNUC__) && !defined(__clang__)\n#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n#endif\n\n#ifndef __has_builtin\n#define __has_builtin(x) 0\n#endif\n\n#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)\n#define BENCHMARK_UNREACHABLE() __builtin_unreachable()\n#elif defined(_MSC_VER)\n#define BENCHMARK_UNREACHABLE() __assume(false)\n#else\n#define BENCHMARK_UNREACHABLE() ((void)0)\n#endif\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_OVERRIDE override\n#else\n#define BENCHMARK_OVERRIDE\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n// C4251: <symbol> needs to have dll-interface to be used by clients of class\n#pragma warning(disable : 4251)\n#endif\n\nnamespace benchmark {\nclass BenchmarkReporter;\n\n// Default number of minimum benchmark running time in seconds.\nconst char kDefaultMinTimeStr[] = \"0.5s\";\n\n// Returns the version of the library.\nBENCHMARK_EXPORT std::string GetBenchmarkVersion();\n\nBENCHMARK_EXPORT void PrintDefaultHelp();\n\nBENCHMARK_EXPORT void Initialize(int* argc, char** argv,\n                                 void (*HelperPrinterf)() = PrintDefaultHelp);\nBENCHMARK_EXPORT void Shutdown();\n\n// Report to stdout all arguments in 'argv' as unrecognized except the first.\n// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).\nBENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);\n\n// Returns the current value of --benchmark_filter.\nBENCHMARK_EXPORT std::string GetBenchmarkFilter();\n\n// Sets a new value to --benchmark_filter. (This will override this flag's\n// current value).\n// Should be called after `benchmark::Initialize()`, as\n// `benchmark::Initialize()` will override the flag's value.\nBENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);\n\n// Returns the current value of --v (command line value for verbosity).\nBENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();\n\n// Creates a default display reporter. Used by the library when no display\n// reporter is provided, but also made available for external use in case a\n// custom reporter should respect the `--benchmark_format` flag as a fallback\nBENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();\n\n// Generate a list of benchmarks matching the specified --benchmark_filter flag\n// and if --benchmark_list_tests is specified return after printing the name\n// of each matching benchmark. Otherwise run each matching benchmark and\n// report the results.\n//\n// spec : Specify the benchmarks to run. If users do not specify this arg,\n//        then the value of FLAGS_benchmark_filter\n//        will be used.\n//\n// The second and third overload use the specified 'display_reporter' and\n//  'file_reporter' respectively. 'file_reporter' will write to the file\n//  specified\n//   by '--benchmark_out'. If '--benchmark_out' is not given the\n//  'file_reporter' is ignored.\n//\n// RETURNS: The number of matching benchmarks.\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);\n\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);\n\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(\n    BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                       BenchmarkReporter* file_reporter, std::string spec);\n\n// TimeUnit is passed to a benchmark in order to specify the order of magnitude\n// for the measured time.\nenum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };\n\nBENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();\n\n// Sets the default time unit the benchmarks use\n// Has to be called before the benchmark loop to take effect\nBENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);\n\n// If a MemoryManager is registered (via RegisterMemoryManager()),\n// it can be used to collect and report allocation metrics for a run of the\n// benchmark.\nclass MemoryManager {\n public:\n  static const int64_t TombstoneValue;\n\n  struct Result {\n    Result()\n        : num_allocs(0),\n          max_bytes_used(0),\n          total_allocated_bytes(TombstoneValue),\n          net_heap_growth(TombstoneValue) {}\n\n    // The number of allocations made in total between Start and Stop.\n    int64_t num_allocs;\n\n    // The peak memory use between Start and Stop.\n    int64_t max_bytes_used;\n\n    // The total memory allocated, in bytes, between Start and Stop.\n    // Init'ed to TombstoneValue if metric not available.\n    int64_t total_allocated_bytes;\n\n    // The net changes in memory, in bytes, between Start and Stop.\n    // ie., total_allocated_bytes - total_deallocated_bytes.\n    // Init'ed to TombstoneValue if metric not available.\n    int64_t net_heap_growth;\n  };\n\n  virtual ~MemoryManager() {}\n\n  // Implement this to start recording allocation information.\n  virtual void Start() = 0;\n\n  // Implement this to stop recording and fill out the given Result structure.\n  virtual void Stop(Result& result) = 0;\n};\n\n// Register a MemoryManager instance that will be used to collect and report\n// allocation measurements for benchmark runs.\nBENCHMARK_EXPORT\nvoid RegisterMemoryManager(MemoryManager* memory_manager);\n\n// If a ProfilerManager is registered (via RegisterProfilerManager()), the\n// benchmark will be run an additional time under the profiler to collect and\n// report profile metrics for the run of the benchmark.\nclass ProfilerManager {\n public:\n  virtual ~ProfilerManager() {}\n\n  // This is called after `Setup()` code and right before the benchmark is run.\n  virtual void AfterSetupStart() = 0;\n\n  // This is called before `Teardown()` code and right after the benchmark\n  // completes.\n  virtual void BeforeTeardownStop() = 0;\n};\n\n// Register a ProfilerManager instance that will be used to collect and report\n// profile measurements for benchmark runs.\nBENCHMARK_EXPORT\nvoid RegisterProfilerManager(ProfilerManager* profiler_manager);\n\n// Add a key-value pair to output as part of the context stanza in the report.\nBENCHMARK_EXPORT\nvoid AddCustomContext(const std::string& key, const std::string& value);\n\nnamespace internal {\nclass Benchmark;\nclass BenchmarkImp;\nclass BenchmarkFamilies;\n\nBENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();\n\nBENCHMARK_EXPORT\nvoid UseCharPointer(char const volatile*);\n\n// Take ownership of the pointer and register the benchmark. Return the\n// registered benchmark.\nBENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);\n\n// Ensure that the standard streams are properly initialized in every TU.\nBENCHMARK_EXPORT int InitializeStreams();\nBENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();\n\n}  // namespace internal\n\n#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \\\n    defined(__EMSCRIPTEN__)\n#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY\n#endif\n\n// Force the compiler to flush pending writes to global memory. Acts as an\n// effective read/write barrier\n#ifdef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {\n  std::atomic_signal_fence(std::memory_order_acq_rel);\n}\n#endif\n\n// The DoNotOptimize(...) function can be used to prevent a value or\n// expression from being optimized away by the compiler. This function is\n// intended to add little to no overhead.\n// See: https://youtu.be/nXaxk27zwlk?t=2441\n#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY\n#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"r,m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n#if defined(__clang__)\n  asm volatile(\"\" : \"+r,m\"(value) : : \"memory\");\n#else\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n#endif\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n#if defined(__clang__)\n  asm volatile(\"\" : \"+r,m\"(value) : : \"memory\");\n#else\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n#endif\n}\n#endif\n#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)\n// Workaround for a bug with full argument copy overhead with GCC.\n// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"r,m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\n#else\n// Fallback for GCC < 5. Can add some overhead because the compiler is forced\n// to use memory operations instead of operations with registers.\n// TODO: Remove if GCC < 5 will be unsupported.\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n#endif\n#endif\n\n#ifndef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {\n  asm volatile(\"\" : : : \"memory\");\n}\n#endif\n#elif defined(_MSC_VER)\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n  _ReadWriteBarrier();\n}\n\n#ifndef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }\n#endif\n#else\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n#else\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n#endif\n// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11.\n#endif\n\n// This class is used for user-defined counters.\nclass Counter {\n public:\n  enum Flags {\n    kDefaults = 0,\n    // Mark the counter as a rate. It will be presented divided\n    // by the duration of the benchmark.\n    kIsRate = 1 << 0,\n    // Mark the counter as a thread-average quantity. It will be\n    // presented divided by the number of threads.\n    kAvgThreads = 1 << 1,\n    // Mark the counter as a thread-average rate. See above.\n    kAvgThreadsRate = kIsRate | kAvgThreads,\n    // Mark the counter as a constant value, valid/same for *every* iteration.\n    // When reporting, it will be *multiplied* by the iteration count.\n    kIsIterationInvariant = 1 << 2,\n    // Mark the counter as a constant rate.\n    // When reporting, it will be *multiplied* by the iteration count\n    // and then divided by the duration of the benchmark.\n    kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,\n    // Mark the counter as a iteration-average quantity.\n    // It will be presented divided by the number of iterations.\n    kAvgIterations = 1 << 3,\n    // Mark the counter as a iteration-average rate. See above.\n    kAvgIterationsRate = kIsRate | kAvgIterations,\n\n    // In the end, invert the result. This is always done last!\n    kInvert = 1 << 31\n  };\n\n  enum OneK {\n    // 1'000 items per 1k\n    kIs1000 = 1000,\n    // 1'024 items per 1k\n    kIs1024 = 1024\n  };\n\n  double value;\n  Flags flags;\n  OneK oneK;\n\n  BENCHMARK_ALWAYS_INLINE\n  Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)\n      : value(v), flags(f), oneK(k) {}\n\n  BENCHMARK_ALWAYS_INLINE operator double const &() const { return value; }\n  BENCHMARK_ALWAYS_INLINE operator double&() { return value; }\n};\n\n// A helper for user code to create unforeseen combinations of Flags, without\n// having to do this cast manually each time, or providing this operator.\nCounter::Flags inline operator|(const Counter::Flags& LHS,\n                                const Counter::Flags& RHS) {\n  return static_cast<Counter::Flags>(static_cast<int>(LHS) |\n                                     static_cast<int>(RHS));\n}\n\n// This is the container for the user-defined counters.\ntypedef std::map<std::string, Counter> UserCounters;\n\n// BigO is passed to a benchmark in order to specify the asymptotic\n// computational\n// complexity for the benchmark. In case oAuto is selected, complexity will be\n// calculated automatically to the best fit.\nenum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };\n\ntypedef int64_t ComplexityN;\n\ntypedef int64_t IterationCount;\n\nenum StatisticUnit { kTime, kPercentage };\n\n// BigOFunc is passed to a benchmark in order to specify the asymptotic\n// computational complexity for the benchmark.\ntypedef double(BigOFunc)(ComplexityN);\n\n// StatisticsFunc is passed to a benchmark in order to compute some descriptive\n// statistics over all the measurements of some type\ntypedef double(StatisticsFunc)(const std::vector<double>&);\n\nnamespace internal {\nstruct Statistics {\n  std::string name_;\n  StatisticsFunc* compute_;\n  StatisticUnit unit_;\n\n  Statistics(const std::string& name, StatisticsFunc* compute,\n             StatisticUnit unit = kTime)\n      : name_(name), compute_(compute), unit_(unit) {}\n};\n\nclass BenchmarkInstance;\nclass ThreadTimer;\nclass ThreadManager;\nclass PerfCountersMeasurement;\n\nenum AggregationReportMode\n#if defined(BENCHMARK_HAS_CXX11)\n    : unsigned\n#else\n#endif\n{\n  // The mode has not been manually specified\n  ARM_Unspecified = 0,\n  // The mode is user-specified.\n  // This may or may not be set when the following bit-flags are set.\n  ARM_Default = 1U << 0U,\n  // File reporter should only output aggregates.\n  ARM_FileReportAggregatesOnly = 1U << 1U,\n  // Display reporter should only output aggregates\n  ARM_DisplayReportAggregatesOnly = 1U << 2U,\n  // Both reporters should only display aggregates.\n  ARM_ReportAggregatesOnly =\n      ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly\n};\n\nenum Skipped\n#if defined(BENCHMARK_HAS_CXX11)\n    : unsigned\n#endif\n{\n  NotSkipped = 0,\n  SkippedWithMessage,\n  SkippedWithError\n};\n\n}  // namespace internal\n\n// State is passed to a running Benchmark and contains state for the\n// benchmark to use.\nclass BENCHMARK_EXPORT State {\n public:\n  struct StateIterator;\n  friend struct StateIterator;\n\n  // Returns iterators used to run each iteration of a benchmark using a\n  // C++11 ranged-based for loop. These functions should not be called directly.\n  //\n  // REQUIRES: The benchmark has not started running yet. Neither begin nor end\n  // have been called previously.\n  //\n  // NOTE: KeepRunning may not be used after calling either of these functions.\n  inline BENCHMARK_ALWAYS_INLINE StateIterator begin();\n  inline BENCHMARK_ALWAYS_INLINE StateIterator end();\n\n  // Returns true if the benchmark should continue through another iteration.\n  // NOTE: A benchmark may not return from the test until KeepRunning() has\n  // returned false.\n  inline bool KeepRunning();\n\n  // Returns true iff the benchmark should run n more iterations.\n  // REQUIRES: 'n' > 0.\n  // NOTE: A benchmark must not return from the test until KeepRunningBatch()\n  // has returned false.\n  // NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.\n  //\n  // Intended usage:\n  //   while (state.KeepRunningBatch(1000)) {\n  //     // process 1000 elements\n  //   }\n  inline bool KeepRunningBatch(IterationCount n);\n\n  // REQUIRES: timer is running and 'SkipWithMessage(...)' or\n  //   'SkipWithError(...)' has not been called by the current thread.\n  // Stop the benchmark timer.  If not called, the timer will be\n  // automatically stopped after the last iteration of the benchmark loop.\n  //\n  // For threaded benchmarks the PauseTiming() function only pauses the timing\n  // for the current thread.\n  //\n  // NOTE: The \"real time\" measurement is per-thread. If different threads\n  // report different measurements the largest one is reported.\n  //\n  // NOTE: PauseTiming()/ResumeTiming() are relatively\n  // heavyweight, and so their use should generally be avoided\n  // within each benchmark iteration, if possible.\n  void PauseTiming();\n\n  // REQUIRES: timer is not running and 'SkipWithMessage(...)' or\n  //   'SkipWithError(...)' has not been called by the current thread.\n  // Start the benchmark timer.  The timer is NOT running on entrance to the\n  // benchmark function. It begins running after control flow enters the\n  // benchmark loop.\n  //\n  // NOTE: PauseTiming()/ResumeTiming() are relatively\n  // heavyweight, and so their use should generally be avoided\n  // within each benchmark iteration, if possible.\n  void ResumeTiming();\n\n  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been\n  //            called previously by the current thread.\n  // Report the benchmark as resulting in being skipped with the specified\n  // 'msg'.\n  // After this call the user may explicitly 'return' from the benchmark.\n  //\n  // If the ranged-for style of benchmark loop is used, the user must explicitly\n  // break from the loop, otherwise all future iterations will be run.\n  // If the 'KeepRunning()' loop is used the current thread will automatically\n  // exit the loop at the end of the current iteration.\n  //\n  // For threaded benchmarks only the current thread stops executing and future\n  // calls to `KeepRunning()` will block until all threads have completed\n  // the `KeepRunning()` loop. If multiple threads report being skipped only the\n  // first skip message is used.\n  //\n  // NOTE: Calling 'SkipWithMessage(...)' does not cause the benchmark to exit\n  // the current scope immediately. If the function is called from within\n  // the 'KeepRunning()' loop the current iteration will finish. It is the users\n  // responsibility to exit the scope as needed.\n  void SkipWithMessage(const std::string& msg);\n\n  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been\n  //            called previously by the current thread.\n  // Report the benchmark as resulting in an error with the specified 'msg'.\n  // After this call the user may explicitly 'return' from the benchmark.\n  //\n  // If the ranged-for style of benchmark loop is used, the user must explicitly\n  // break from the loop, otherwise all future iterations will be run.\n  // If the 'KeepRunning()' loop is used the current thread will automatically\n  // exit the loop at the end of the current iteration.\n  //\n  // For threaded benchmarks only the current thread stops executing and future\n  // calls to `KeepRunning()` will block until all threads have completed\n  // the `KeepRunning()` loop. If multiple threads report an error only the\n  // first error message is used.\n  //\n  // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit\n  // the current scope immediately. If the function is called from within\n  // the 'KeepRunning()' loop the current iteration will finish. It is the users\n  // responsibility to exit the scope as needed.\n  void SkipWithError(const std::string& msg);\n\n  // Returns true if 'SkipWithMessage(...)' or 'SkipWithError(...)' was called.\n  bool skipped() const { return internal::NotSkipped != skipped_; }\n\n  // Returns true if an error has been reported with 'SkipWithError(...)'.\n  bool error_occurred() const { return internal::SkippedWithError == skipped_; }\n\n  // REQUIRES: called exactly once per iteration of the benchmarking loop.\n  // Set the manually measured time for this benchmark iteration, which\n  // is used instead of automatically measured time if UseManualTime() was\n  // specified.\n  //\n  // For threaded benchmarks the final value will be set to the largest\n  // reported values.\n  void SetIterationTime(double seconds);\n\n  // Set the number of bytes processed by the current benchmark\n  // execution.  This routine is typically called once at the end of a\n  // throughput oriented benchmark.\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  BENCHMARK_ALWAYS_INLINE\n  void SetBytesProcessed(int64_t bytes) {\n    counters[\"bytes_per_second\"] =\n        Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  int64_t bytes_processed() const {\n    if (counters.find(\"bytes_per_second\") != counters.end())\n      return static_cast<int64_t>(counters.at(\"bytes_per_second\"));\n    return 0;\n  }\n\n  // If this routine is called with complexity_n > 0 and complexity report is\n  // requested for the\n  // family benchmark, then current benchmark will be part of the computation\n  // and complexity_n will\n  // represent the length of N.\n  BENCHMARK_ALWAYS_INLINE\n  void SetComplexityN(ComplexityN complexity_n) {\n    complexity_n_ = complexity_n;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  ComplexityN complexity_length_n() const { return complexity_n_; }\n\n  // If this routine is called with items > 0, then an items/s\n  // label is printed on the benchmark report line for the currently\n  // executing benchmark. It is typically called at the end of a processing\n  // benchmark where a processing items/second output is desired.\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  BENCHMARK_ALWAYS_INLINE\n  void SetItemsProcessed(int64_t items) {\n    counters[\"items_per_second\"] =\n        Counter(static_cast<double>(items), benchmark::Counter::kIsRate);\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  int64_t items_processed() const {\n    if (counters.find(\"items_per_second\") != counters.end())\n      return static_cast<int64_t>(counters.at(\"items_per_second\"));\n    return 0;\n  }\n\n  // If this routine is called, the specified label is printed at the\n  // end of the benchmark report line for the currently executing\n  // benchmark.  Example:\n  //  static void BM_Compress(benchmark::State& state) {\n  //    ...\n  //    double compress = input_size / output_size;\n  //    state.SetLabel(StrFormat(\"compress:%.1f%%\", 100.0*compression));\n  //  }\n  // Produces output that looks like:\n  //  BM_Compress   50         50   14115038  compress:27.3%\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  void SetLabel(const std::string& label);\n\n  // Range arguments for this run. CHECKs if the argument has been set.\n  BENCHMARK_ALWAYS_INLINE\n  int64_t range(std::size_t pos = 0) const {\n    assert(range_.size() > pos);\n    return range_[pos];\n  }\n\n  BENCHMARK_DEPRECATED_MSG(\"use 'range(0)' instead\")\n  int64_t range_x() const { return range(0); }\n\n  BENCHMARK_DEPRECATED_MSG(\"use 'range(1)' instead\")\n  int64_t range_y() const { return range(1); }\n\n  // Number of threads concurrently executing the benchmark.\n  BENCHMARK_ALWAYS_INLINE\n  int threads() const { return threads_; }\n\n  // Index of the executing thread. Values from [0, threads).\n  BENCHMARK_ALWAYS_INLINE\n  int thread_index() const { return thread_index_; }\n\n  BENCHMARK_ALWAYS_INLINE\n  IterationCount iterations() const {\n    if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {\n      return 0;\n    }\n    return max_iterations - total_iterations_ + batch_leftover_;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  std::string name() const { return name_; }\n\n private:\n  // items we expect on the first cache line (ie 64 bytes of the struct)\n  // When total_iterations_ is 0, KeepRunning() and friends will return false.\n  // May be larger than max_iterations.\n  IterationCount total_iterations_;\n\n  // When using KeepRunningBatch(), batch_leftover_ holds the number of\n  // iterations beyond max_iters that were run. Used to track\n  // completed_iterations_ accurately.\n  IterationCount batch_leftover_;\n\n public:\n  const IterationCount max_iterations;\n\n private:\n  bool started_;\n  bool finished_;\n  internal::Skipped skipped_;\n\n  // items we don't need on the first cache line\n  std::vector<int64_t> range_;\n\n  ComplexityN complexity_n_;\n\n public:\n  // Container for user-defined counters.\n  UserCounters counters;\n\n private:\n  State(std::string name, IterationCount max_iters,\n        const std::vector<int64_t>& ranges, int thread_i, int n_threads,\n        internal::ThreadTimer* timer, internal::ThreadManager* manager,\n        internal::PerfCountersMeasurement* perf_counters_measurement);\n\n  void StartKeepRunning();\n  // Implementation of KeepRunning() and KeepRunningBatch().\n  // is_batch must be true unless n is 1.\n  inline bool KeepRunningInternal(IterationCount n, bool is_batch);\n  void FinishKeepRunning();\n\n  const std::string name_;\n  const int thread_index_;\n  const int threads_;\n\n  internal::ThreadTimer* const timer_;\n  internal::ThreadManager* const manager_;\n  internal::PerfCountersMeasurement* const perf_counters_measurement_;\n\n  friend class internal::BenchmarkInstance;\n};\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {\n  return KeepRunningInternal(1, /*is_batch=*/false);\n}\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {\n  return KeepRunningInternal(n, /*is_batch=*/true);\n}\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,\n                                                               bool is_batch) {\n  // total_iterations_ is set to 0 by the constructor, and always set to a\n  // nonzero value by StartKepRunning().\n  assert(n > 0);\n  // n must be 1 unless is_batch is true.\n  assert(is_batch || n == 1);\n  if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {\n    total_iterations_ -= n;\n    return true;\n  }\n  if (!started_) {\n    StartKeepRunning();\n    if (!skipped() && total_iterations_ >= n) {\n      total_iterations_ -= n;\n      return true;\n    }\n  }\n  // For non-batch runs, total_iterations_ must be 0 by now.\n  if (is_batch && total_iterations_ != 0) {\n    batch_leftover_ = n - total_iterations_;\n    total_iterations_ = 0;\n    return true;\n  }\n  FinishKeepRunning();\n  return false;\n}\n\nstruct State::StateIterator {\n  struct BENCHMARK_UNUSED Value {};\n  typedef std::forward_iterator_tag iterator_category;\n  typedef Value value_type;\n  typedef Value reference;\n  typedef Value pointer;\n  typedef std::ptrdiff_t difference_type;\n\n private:\n  friend class State;\n  BENCHMARK_ALWAYS_INLINE\n  StateIterator() : cached_(0), parent_() {}\n\n  BENCHMARK_ALWAYS_INLINE\n  explicit StateIterator(State* st)\n      : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}\n\n public:\n  BENCHMARK_ALWAYS_INLINE\n  Value operator*() const { return Value(); }\n\n  BENCHMARK_ALWAYS_INLINE\n  StateIterator& operator++() {\n    assert(cached_ > 0);\n    --cached_;\n    return *this;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  bool operator!=(StateIterator const&) const {\n    if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;\n    parent_->FinishKeepRunning();\n    return false;\n  }\n\n private:\n  IterationCount cached_;\n  State* const parent_;\n};\n\ninline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {\n  return StateIterator(this);\n}\ninline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {\n  StartKeepRunning();\n  return StateIterator();\n}\n\nnamespace internal {\n\ntypedef void(Function)(State&);\n\n// ------------------------------------------------------\n// Benchmark registration object.  The BENCHMARK() macro expands\n// into an internal::Benchmark* object.  Various methods can\n// be called on this object to change the properties of the benchmark.\n// Each method returns \"this\" so that multiple method calls can\n// chained into one expression.\nclass BENCHMARK_EXPORT Benchmark {\n public:\n  virtual ~Benchmark();\n\n  // Note: the following methods all return \"this\" so that multiple\n  // method calls can be chained together in one expression.\n\n  // Specify the name of the benchmark\n  Benchmark* Name(const std::string& name);\n\n  // Run this benchmark once with \"x\" as the extra argument passed\n  // to the function.\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* Arg(int64_t x);\n\n  // Run this benchmark with the given time unit for the generated output report\n  Benchmark* Unit(TimeUnit unit);\n\n  // Run this benchmark once for a number of values picked from the\n  // range [start..limit].  (start and limit are always picked.)\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* Range(int64_t start, int64_t limit);\n\n  // Run this benchmark once for all values in the range [start..limit] with\n  // specific step\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);\n\n  // Run this benchmark once with \"args\" as the extra arguments passed\n  // to the function.\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* Args(const std::vector<int64_t>& args);\n\n  // Equivalent to Args({x, y})\n  // NOTE: This is a legacy C++03 interface provided for compatibility only.\n  //   New code should use 'Args'.\n  Benchmark* ArgPair(int64_t x, int64_t y) {\n    std::vector<int64_t> args;\n    args.push_back(x);\n    args.push_back(y);\n    return Args(args);\n  }\n\n  // Run this benchmark once for a number of values picked from the\n  // ranges [start..limit].  (starts and limits are always picked.)\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t> >& ranges);\n\n  // Run this benchmark once for each combination of values in the (cartesian)\n  // product of the supplied argument lists.\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* ArgsProduct(const std::vector<std::vector<int64_t> >& arglists);\n\n  // Equivalent to ArgNames({name})\n  Benchmark* ArgName(const std::string& name);\n\n  // Set the argument names to display in the benchmark name. If not called,\n  // only argument values will be shown.\n  Benchmark* ArgNames(const std::vector<std::string>& names);\n\n  // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).\n  // NOTE: This is a legacy C++03 interface provided for compatibility only.\n  //   New code should use 'Ranges'.\n  Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {\n    std::vector<std::pair<int64_t, int64_t> > ranges;\n    ranges.push_back(std::make_pair(lo1, hi1));\n    ranges.push_back(std::make_pair(lo2, hi2));\n    return Ranges(ranges);\n  }\n\n  // Have \"setup\" and/or \"teardown\" invoked once for every benchmark run.\n  // If the benchmark is multi-threaded (will run in k threads concurrently),\n  // the setup callback will be be invoked exactly once (not k times) before\n  // each run with k threads. Time allowing (e.g. for a short benchmark), there\n  // may be multiple such runs per benchmark, each run with its own\n  // \"setup\"/\"teardown\".\n  //\n  // If the benchmark uses different size groups of threads (e.g. via\n  // ThreadRange), the above will be true for each size group.\n  //\n  // The callback will be passed a State object, which includes the number\n  // of threads, thread-index, benchmark arguments, etc.\n  //\n  // The callback must not be NULL or self-deleting.\n  Benchmark* Setup(void (*setup)(const benchmark::State&));\n  Benchmark* Teardown(void (*teardown)(const benchmark::State&));\n\n  // Pass this benchmark object to *func, which can customize\n  // the benchmark by calling various methods like Arg, Args,\n  // Threads, etc.\n  Benchmark* Apply(void (*func)(Benchmark* benchmark));\n\n  // Set the range multiplier for non-dense range. If not called, the range\n  // multiplier kRangeMultiplier will be used.\n  Benchmark* RangeMultiplier(int multiplier);\n\n  // Set the minimum amount of time to use when running this benchmark. This\n  // option overrides the `benchmark_min_time` flag.\n  // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark.\n  Benchmark* MinTime(double t);\n\n  // Set the minimum amount of time to run the benchmark before taking runtimes\n  // of this benchmark into account. This\n  // option overrides the `benchmark_min_warmup_time` flag.\n  // REQUIRES: `t >= 0` and `Iterations` has not been called on this benchmark.\n  Benchmark* MinWarmUpTime(double t);\n\n  // Specify the amount of iterations that should be run by this benchmark.\n  // This option overrides the `benchmark_min_time` flag.\n  // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark.\n  //\n  // NOTE: This function should only be used when *exact* iteration control is\n  //   needed and never to control or limit how long a benchmark runs, where\n  // `--benchmark_min_time=<N>s` or `MinTime(...)` should be used instead.\n  Benchmark* Iterations(IterationCount n);\n\n  // Specify the amount of times to repeat this benchmark. This option overrides\n  // the `benchmark_repetitions` flag.\n  // REQUIRES: `n > 0`\n  Benchmark* Repetitions(int n);\n\n  // Specify if each repetition of the benchmark should be reported separately\n  // or if only the final statistics should be reported. If the benchmark\n  // is not repeated then the single result is always reported.\n  // Applies to *ALL* reporters (display and file).\n  Benchmark* ReportAggregatesOnly(bool value = true);\n\n  // Same as ReportAggregatesOnly(), but applies to display reporter only.\n  Benchmark* DisplayAggregatesOnly(bool value = true);\n\n  // By default, the CPU time is measured only for the main thread, which may\n  // be unrepresentative if the benchmark uses threads internally. If called,\n  // the total CPU time spent by all the threads will be measured instead.\n  // By default, only the main thread CPU time will be measured.\n  Benchmark* MeasureProcessCPUTime();\n\n  // If a particular benchmark should use the Wall clock instead of the CPU time\n  // (be it either the CPU time of the main thread only (default), or the\n  // total CPU usage of the benchmark), call this method. If called, the elapsed\n  // (wall) time will be used to control how many iterations are run, and in the\n  // printing of items/second or MB/seconds values.\n  // If not called, the CPU time used by the benchmark will be used.\n  Benchmark* UseRealTime();\n\n  // If a benchmark must measure time manually (e.g. if GPU execution time is\n  // being\n  // measured), call this method. If called, each benchmark iteration should\n  // call\n  // SetIterationTime(seconds) to report the measured time, which will be used\n  // to control how many iterations are run, and in the printing of items/second\n  // or MB/second values.\n  Benchmark* UseManualTime();\n\n  // Set the asymptotic computational complexity for the benchmark. If called\n  // the asymptotic computational complexity will be shown on the output.\n  Benchmark* Complexity(BigO complexity = benchmark::oAuto);\n\n  // Set the asymptotic computational complexity for the benchmark. If called\n  // the asymptotic computational complexity will be shown on the output.\n  Benchmark* Complexity(BigOFunc* complexity);\n\n  // Add this statistics to be computed over all the values of benchmark run\n  Benchmark* ComputeStatistics(const std::string& name,\n                               StatisticsFunc* statistics,\n                               StatisticUnit unit = kTime);\n\n  // Support for running multiple copies of the same benchmark concurrently\n  // in multiple threads.  This may be useful when measuring the scaling\n  // of some piece of code.\n\n  // Run one instance of this benchmark concurrently in t threads.\n  Benchmark* Threads(int t);\n\n  // Pick a set of values T from [min_threads,max_threads].\n  // min_threads and max_threads are always included in T.  Run this\n  // benchmark once for each value in T.  The benchmark run for a\n  // particular value t consists of t threads running the benchmark\n  // function concurrently.  For example, consider:\n  //    BENCHMARK(Foo)->ThreadRange(1,16);\n  // This will run the following benchmarks:\n  //    Foo in 1 thread\n  //    Foo in 2 threads\n  //    Foo in 4 threads\n  //    Foo in 8 threads\n  //    Foo in 16 threads\n  Benchmark* ThreadRange(int min_threads, int max_threads);\n\n  // For each value n in the range, run this benchmark once using n threads.\n  // min_threads and max_threads are always included in the range.\n  // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts\n  // a benchmark with 1, 4, 7 and 8 threads.\n  Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);\n\n  // Equivalent to ThreadRange(NumCPUs(), NumCPUs())\n  Benchmark* ThreadPerCpu();\n\n  virtual void Run(State& state) = 0;\n\n  TimeUnit GetTimeUnit() const;\n\n protected:\n  explicit Benchmark(const std::string& name);\n  void SetName(const std::string& name);\n\n public:\n  const char* GetName() const;\n  int ArgsCnt() const;\n  const char* GetArgName(int arg) const;\n\n private:\n  friend class BenchmarkFamilies;\n  friend class BenchmarkInstance;\n\n  std::string name_;\n  AggregationReportMode aggregation_report_mode_;\n  std::vector<std::string> arg_names_;       // Args for all benchmark runs\n  std::vector<std::vector<int64_t> > args_;  // Args for all benchmark runs\n\n  TimeUnit time_unit_;\n  bool use_default_time_unit_;\n\n  int range_multiplier_;\n  double min_time_;\n  double min_warmup_time_;\n  IterationCount iterations_;\n  int repetitions_;\n  bool measure_process_cpu_time_;\n  bool use_real_time_;\n  bool use_manual_time_;\n  BigO complexity_;\n  BigOFunc* complexity_lambda_;\n  std::vector<Statistics> statistics_;\n  std::vector<int> thread_counts_;\n\n  typedef void (*callback_function)(const benchmark::State&);\n  callback_function setup_;\n  callback_function teardown_;\n\n  Benchmark(Benchmark const&)\n#if defined(BENCHMARK_HAS_CXX11)\n      = delete\n#endif\n      ;\n\n  Benchmark& operator=(Benchmark const&)\n#if defined(BENCHMARK_HAS_CXX11)\n      = delete\n#endif\n      ;\n};\n\n}  // namespace internal\n\n// Create and register a benchmark with the specified 'name' that invokes\n// the specified functor 'fn'.\n//\n// RETURNS: A pointer to the registered benchmark.\ninternal::Benchmark* RegisterBenchmark(const std::string& name,\n                                       internal::Function* fn);\n\n#if defined(BENCHMARK_HAS_CXX11)\ntemplate <class Lambda>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);\n#endif\n\n// Remove all registered benchmarks. All pointers to previously registered\n// benchmarks are invalidated.\nBENCHMARK_EXPORT void ClearRegisteredBenchmarks();\n\nnamespace internal {\n// The class used to hold all Benchmarks created from static function.\n// (ie those created using the BENCHMARK(...) macros.\nclass BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {\n public:\n  FunctionBenchmark(const std::string& name, Function* func)\n      : Benchmark(name), func_(func) {}\n\n  void Run(State& st) BENCHMARK_OVERRIDE;\n\n private:\n  Function* func_;\n};\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Lambda>\nclass LambdaBenchmark : public Benchmark {\n public:\n  void Run(State& st) BENCHMARK_OVERRIDE { lambda_(st); }\n\n private:\n  template <class OLambda>\n  LambdaBenchmark(const std::string& name, OLambda&& lam)\n      : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}\n\n  LambdaBenchmark(LambdaBenchmark const&) = delete;\n\n  template <class Lam>  // NOLINTNEXTLINE(readability-redundant-declaration)\n  friend Benchmark* ::benchmark::RegisterBenchmark(const std::string&, Lam&&);\n\n  Lambda lambda_;\n};\n#endif\n}  // namespace internal\n\ninline internal::Benchmark* RegisterBenchmark(const std::string& name,\n                                              internal::Function* fn) {\n  // FIXME: this should be a `std::make_unique<>()` but we don't have C++14.\n  // codechecker_intentional [cplusplus.NewDeleteLeaks]\n  return internal::RegisterBenchmarkInternal(\n      ::new internal::FunctionBenchmark(name, fn));\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Lambda>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {\n  using BenchType =\n      internal::LambdaBenchmark<typename std::decay<Lambda>::type>;\n  // FIXME: this should be a `std::make_unique<>()` but we don't have C++14.\n  // codechecker_intentional [cplusplus.NewDeleteLeaks]\n  return internal::RegisterBenchmarkInternal(\n      ::new BenchType(name, std::forward<Lambda>(fn)));\n}\n#endif\n\n#if defined(BENCHMARK_HAS_CXX11) && \\\n    (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)\ntemplate <class Lambda, class... Args>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,\n                                       Args&&... args) {\n  return benchmark::RegisterBenchmark(\n      name, [=](benchmark::State& st) { fn(st, args...); });\n}\n#else\n#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK\n#endif\n\n// The base class for all fixture tests.\nclass Fixture : public internal::Benchmark {\n public:\n  Fixture() : internal::Benchmark(\"\") {}\n\n  void Run(State& st) BENCHMARK_OVERRIDE {\n    this->SetUp(st);\n    this->BenchmarkCase(st);\n    this->TearDown(st);\n  }\n\n  // These will be deprecated ...\n  virtual void SetUp(const State&) {}\n  virtual void TearDown(const State&) {}\n  // ... In favor of these.\n  virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }\n  virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }\n\n protected:\n  virtual void BenchmarkCase(State&) = 0;\n};\n}  // namespace benchmark\n\n// ------------------------------------------------------\n// Macro to register benchmarks\n\n// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1\n// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be\n// empty. If X is empty the expression becomes (+1 == +0).\n#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)\n#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__\n#else\n#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__\n#endif\n\n// Helpers for generating unique variable names\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_PRIVATE_NAME(...)                                      \\\n  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \\\n                           __VA_ARGS__)\n#else\n#define BENCHMARK_PRIVATE_NAME(n) \\\n  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)\n#endif  // BENCHMARK_HAS_CXX11\n\n#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)\n#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c\n// Helper for concatenation with macro name expansion\n#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \\\n  BaseClass##_##Method##_Benchmark\n\n#define BENCHMARK_PRIVATE_DECLARE(n)                                 \\\n  static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \\\n      BENCHMARK_UNUSED\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK(...)                                               \\\n  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =                           \\\n      (::benchmark::internal::RegisterBenchmarkInternal(             \\\n          new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \\\n                                                       __VA_ARGS__)))\n#else\n#define BENCHMARK(n)                                     \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(#n, n)))\n#endif  // BENCHMARK_HAS_CXX11\n\n// Old-style macros\n#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))\n#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})\n#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))\n#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))\n#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \\\n  BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})\n\n#ifdef BENCHMARK_HAS_CXX11\n\n// Register a benchmark which invokes the function specified by `func`\n// with the additional arguments specified by `...`.\n//\n// For example:\n//\n// template <class ...ExtraArgs>`\n// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {\n//  [...]\n//}\n// /* Registers a benchmark named \"BM_takes_args/int_string_test` */\n// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string(\"abc\"));\n#define BENCHMARK_CAPTURE(func, test_case_name, ...)     \\\n  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(  \\\n              #func \"/\" #test_case_name,                 \\\n              [](::benchmark::State& st) { func(st, __VA_ARGS__); })))\n\n#endif  // BENCHMARK_HAS_CXX11\n\n// This will register a benchmark for a templatized function.  For example:\n//\n// template<int arg>\n// void BM_Foo(int iters);\n//\n// BENCHMARK_TEMPLATE(BM_Foo, 1);\n//\n// will register BM_Foo<1> as a benchmark.\n#define BENCHMARK_TEMPLATE1(n, a)                        \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(#n \"<\" #a \">\", n<a>)))\n\n#define BENCHMARK_TEMPLATE2(n, a, b)                                         \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                                             \\\n      (::benchmark::internal::RegisterBenchmarkInternal(                     \\\n          new ::benchmark::internal::FunctionBenchmark(#n \"<\" #a \",\" #b \">\", \\\n                                                       n<a, b>)))\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE(n, ...)                       \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(  \\\n              #n \"<\" #__VA_ARGS__ \">\", n<__VA_ARGS__>)))\n#else\n#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)\n#endif\n\n#ifdef BENCHMARK_HAS_CXX11\n// This will register a benchmark for a templatized function,\n// with the additional arguments specified by `...`.\n//\n// For example:\n//\n// template <typename T, class ...ExtraArgs>`\n// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {\n//  [...]\n//}\n// /* Registers a benchmark named \"BM_takes_args<void>/int_string_test` */\n// BENCHMARK_TEMPLATE1_CAPTURE(BM_takes_args, void, int_string_test, 42,\n//                             std::string(\"abc\"));\n#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \\\n  BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)\n\n#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \\\n  BENCHMARK_PRIVATE_DECLARE(func) =                                  \\\n      (::benchmark::internal::RegisterBenchmarkInternal(             \\\n          new ::benchmark::internal::FunctionBenchmark(              \\\n              #func \"<\" #a \",\" #b \">\"                                \\\n                    \"/\" #test_case_name,                             \\\n              [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))\n#endif  // BENCHMARK_HAS_CXX11\n\n#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method)          \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass {   \\\n   public:                                                      \\\n    BaseClass##_##Method##_Benchmark() {                        \\\n      this->SetName(#BaseClass \"/\" #Method);                    \\\n    }                                                           \\\n                                                                \\\n   protected:                                                   \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \\\n  };\n\n#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<a> {    \\\n   public:                                                          \\\n    BaseClass##_##Method##_Benchmark() {                            \\\n      this->SetName(#BaseClass \"<\" #a \">/\" #Method);                \\\n    }                                                               \\\n                                                                    \\\n   protected:                                                       \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;     \\\n  };\n\n#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> {    \\\n   public:                                                             \\\n    BaseClass##_##Method##_Benchmark() {                               \\\n      this->SetName(#BaseClass \"<\" #a \",\" #b \">/\" #Method);            \\\n    }                                                                  \\\n                                                                       \\\n   protected:                                                          \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;        \\\n  };\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...)       \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \\\n   public:                                                                 \\\n    BaseClass##_##Method##_Benchmark() {                                   \\\n      this->SetName(#BaseClass \"<\" #__VA_ARGS__ \">/\" #Method);             \\\n    }                                                                      \\\n                                                                           \\\n   protected:                                                              \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;            \\\n  };\n#else\n#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)\n#endif\n\n#define BENCHMARK_DEFINE_F(BaseClass, Method)    \\\n  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)    \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b)    \\\n  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...)            \\\n  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n#else\n#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \\\n  BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)\n#endif\n\n#define BENCHMARK_REGISTER_F(BaseClass, Method) \\\n  BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))\n\n#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \\\n  BENCHMARK_PRIVATE_DECLARE(TestName) =        \\\n      (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))\n\n// This macro will define and register a benchmark within a fixture class.\n#define BENCHMARK_F(BaseClass, Method)           \\\n  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);       \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)           \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                    \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b)           \\\n  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                       \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...)                   \\\n  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                             \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n#else\n#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \\\n  BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)\n#endif\n\n// Helper macro to create a main routine in a test that runs the benchmarks\n// Note the workaround for Hexagon simulator passing argc != 0, argv = NULL.\n#define BENCHMARK_MAIN()                                                \\\n  int main(int argc, char** argv) {                                     \\\n    char arg0_default[] = \"benchmark\";                                  \\\n    char* args_default = arg0_default;                                  \\\n    if (!argv) {                                                        \\\n      argc = 1;                                                         \\\n      argv = &args_default;                                             \\\n    }                                                                   \\\n    ::benchmark::Initialize(&argc, argv);                               \\\n    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \\\n    ::benchmark::RunSpecifiedBenchmarks();                              \\\n    ::benchmark::Shutdown();                                            \\\n    return 0;                                                           \\\n  }                                                                     \\\n  int main(int, char**)\n\n// ------------------------------------------------------\n// Benchmark Reporters\n\nnamespace benchmark {\n\nstruct BENCHMARK_EXPORT CPUInfo {\n  struct CacheInfo {\n    std::string type;\n    int level;\n    int size;\n    int num_sharing;\n  };\n\n  enum Scaling { UNKNOWN, ENABLED, DISABLED };\n\n  int num_cpus;\n  Scaling scaling;\n  double cycles_per_second;\n  std::vector<CacheInfo> caches;\n  std::vector<double> load_avg;\n\n  static const CPUInfo& Get();\n\n private:\n  CPUInfo();\n  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);\n};\n\n// Adding Struct for System Information\nstruct BENCHMARK_EXPORT SystemInfo {\n  std::string name;\n  static const SystemInfo& Get();\n\n private:\n  SystemInfo();\n  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);\n};\n\n// BenchmarkName contains the components of the Benchmark's name\n// which allows individual fields to be modified or cleared before\n// building the final name using 'str()'.\nstruct BENCHMARK_EXPORT BenchmarkName {\n  std::string function_name;\n  std::string args;\n  std::string min_time;\n  std::string min_warmup_time;\n  std::string iterations;\n  std::string repetitions;\n  std::string time_type;\n  std::string threads;\n\n  // Return the full name of the benchmark with each non-empty\n  // field separated by a '/'\n  std::string str() const;\n};\n\n// Interface for custom benchmark result printers.\n// By default, benchmark reports are printed to stdout. However an application\n// can control the destination of the reports by calling\n// RunSpecifiedBenchmarks and passing it a custom reporter object.\n// The reporter object must implement the following interface.\nclass BENCHMARK_EXPORT BenchmarkReporter {\n public:\n  struct Context {\n    CPUInfo const& cpu_info;\n    SystemInfo const& sys_info;\n    // The number of chars in the longest benchmark name.\n    size_t name_field_width;\n    static const char* executable_name;\n    Context();\n  };\n\n  struct BENCHMARK_EXPORT Run {\n    static const int64_t no_repetition_index = -1;\n    enum RunType { RT_Iteration, RT_Aggregate };\n\n    Run()\n        : run_type(RT_Iteration),\n          aggregate_unit(kTime),\n          skipped(internal::NotSkipped),\n          iterations(1),\n          threads(1),\n          time_unit(GetDefaultTimeUnit()),\n          real_accumulated_time(0),\n          cpu_accumulated_time(0),\n          max_heapbytes_used(0),\n          use_real_time_for_initial_big_o(false),\n          complexity(oNone),\n          complexity_lambda(),\n          complexity_n(0),\n          report_big_o(false),\n          report_rms(false),\n          memory_result(NULL),\n          allocs_per_iter(0.0) {}\n\n    std::string benchmark_name() const;\n    BenchmarkName run_name;\n    int64_t family_index;\n    int64_t per_family_instance_index;\n    RunType run_type;\n    std::string aggregate_name;\n    StatisticUnit aggregate_unit;\n    std::string report_label;  // Empty if not set by benchmark.\n    internal::Skipped skipped;\n    std::string skip_message;\n\n    IterationCount iterations;\n    int64_t threads;\n    int64_t repetition_index;\n    int64_t repetitions;\n    TimeUnit time_unit;\n    double real_accumulated_time;\n    double cpu_accumulated_time;\n\n    // Return a value representing the real time per iteration in the unit\n    // specified by 'time_unit'.\n    // NOTE: If 'iterations' is zero the returned value represents the\n    // accumulated time.\n    double GetAdjustedRealTime() const;\n\n    // Return a value representing the cpu time per iteration in the unit\n    // specified by 'time_unit'.\n    // NOTE: If 'iterations' is zero the returned value represents the\n    // accumulated time.\n    double GetAdjustedCPUTime() const;\n\n    // This is set to 0.0 if memory tracing is not enabled.\n    double max_heapbytes_used;\n\n    // By default Big-O is computed for CPU time, but that is not what you want\n    // to happen when manual time was requested, which is stored as real time.\n    bool use_real_time_for_initial_big_o;\n\n    // Keep track of arguments to compute asymptotic complexity\n    BigO complexity;\n    BigOFunc* complexity_lambda;\n    ComplexityN complexity_n;\n\n    // what statistics to compute from the measurements\n    const std::vector<internal::Statistics>* statistics;\n\n    // Inform print function whether the current run is a complexity report\n    bool report_big_o;\n    bool report_rms;\n\n    UserCounters counters;\n\n    // Memory metrics.\n    const MemoryManager::Result* memory_result;\n    double allocs_per_iter;\n  };\n\n  struct PerFamilyRunReports {\n    PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}\n\n    // How many runs will all instances of this benchmark perform?\n    int num_runs_total;\n\n    // How many runs have happened already?\n    int num_runs_done;\n\n    // The reports about (non-errneous!) runs of this family.\n    std::vector<BenchmarkReporter::Run> Runs;\n  };\n\n  // Construct a BenchmarkReporter with the output stream set to 'std::cout'\n  // and the error stream set to 'std::cerr'\n  BenchmarkReporter();\n\n  // Called once for every suite of benchmarks run.\n  // The parameter \"context\" contains information that the\n  // reporter may wish to use when generating its report, for example the\n  // platform under which the benchmarks are running. The benchmark run is\n  // never started if this function returns false, allowing the reporter\n  // to skip runs based on the context information.\n  virtual bool ReportContext(const Context& context) = 0;\n\n  // Called once for each group of benchmark runs, gives information about\n  // the configurations of the runs.\n  virtual void ReportRunsConfig(double /*min_time*/,\n                                bool /*has_explicit_iters*/,\n                                IterationCount /*iters*/) {}\n\n  // Called once for each group of benchmark runs, gives information about\n  // cpu-time and heap memory usage during the benchmark run. If the group\n  // of runs contained more than two entries then 'report' contains additional\n  // elements representing the mean and standard deviation of those runs.\n  // Additionally if this group of runs was the last in a family of benchmarks\n  // 'reports' contains additional entries representing the asymptotic\n  // complexity and RMS of that benchmark family.\n  virtual void ReportRuns(const std::vector<Run>& report) = 0;\n\n  // Called once and only once after ever group of benchmarks is run and\n  // reported.\n  virtual void Finalize() {}\n\n  // REQUIRES: The object referenced by 'out' is valid for the lifetime\n  // of the reporter.\n  void SetOutputStream(std::ostream* out) {\n    assert(out);\n    output_stream_ = out;\n  }\n\n  // REQUIRES: The object referenced by 'err' is valid for the lifetime\n  // of the reporter.\n  void SetErrorStream(std::ostream* err) {\n    assert(err);\n    error_stream_ = err;\n  }\n\n  std::ostream& GetOutputStream() const { return *output_stream_; }\n\n  std::ostream& GetErrorStream() const { return *error_stream_; }\n\n  virtual ~BenchmarkReporter();\n\n  // Write a human readable string to 'out' representing the specified\n  // 'context'.\n  // REQUIRES: 'out' is non-null.\n  static void PrintBasicContext(std::ostream* out, Context const& context);\n\n private:\n  std::ostream* output_stream_;\n  std::ostream* error_stream_;\n};\n\n// Simple reporter that outputs benchmark data to the console. This is the\n// default reporter used by RunSpecifiedBenchmarks().\nclass BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {\n public:\n  enum OutputOptions {\n    OO_None = 0,\n    OO_Color = 1,\n    OO_Tabular = 2,\n    OO_ColorTabular = OO_Color | OO_Tabular,\n    OO_Defaults = OO_ColorTabular\n  };\n  explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)\n      : output_options_(opts_), name_field_width_(0), printed_header_(false) {}\n\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n\n protected:\n  virtual void PrintRunData(const Run& report);\n  virtual void PrintHeader(const Run& report);\n\n  OutputOptions output_options_;\n  size_t name_field_width_;\n  UserCounters prev_counters_;\n  bool printed_header_;\n};\n\nclass BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {\n public:\n  JSONReporter() : first_report_(true) {}\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n  void Finalize() BENCHMARK_OVERRIDE;\n\n private:\n  void PrintRunData(const Run& report);\n\n  bool first_report_;\n};\n\nclass BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(\n    \"The CSV Reporter will be removed in a future release\") CSVReporter\n    : public BenchmarkReporter {\n public:\n  CSVReporter() : printed_header_(false) {}\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n\n private:\n  void PrintRunData(const Run& report);\n\n  bool printed_header_;\n  std::set<std::string> user_counter_names_;\n};\n\ninline const char* GetTimeUnitString(TimeUnit unit) {\n  switch (unit) {\n    case kSecond:\n      return \"s\";\n    case kMillisecond:\n      return \"ms\";\n    case kMicrosecond:\n      return \"us\";\n    case kNanosecond:\n      return \"ns\";\n  }\n  BENCHMARK_UNREACHABLE();\n}\n\ninline double GetTimeUnitMultiplier(TimeUnit unit) {\n  switch (unit) {\n    case kSecond:\n      return 1;\n    case kMillisecond:\n      return 1e3;\n    case kMicrosecond:\n      return 1e6;\n    case kNanosecond:\n      return 1e9;\n  }\n  BENCHMARK_UNREACHABLE();\n}\n\n// Creates a list of integer values for the given range and multiplier.\n// This can be used together with ArgsProduct() to allow multiple ranges\n// with different multipliers.\n// Example:\n// ArgsProduct({\n//   CreateRange(0, 1024, /*multi=*/32),\n//   CreateRange(0, 100, /*multi=*/4),\n//   CreateDenseRange(0, 4, /*step=*/1),\n// });\nBENCHMARK_EXPORT\nstd::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);\n\n// Creates a list of integer values for the given range and step.\nBENCHMARK_EXPORT\nstd::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);\n\n}  // namespace benchmark\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#endif  // BENCHMARK_BENCHMARK_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/include/benchmark/export.h",
    "content": "#ifndef BENCHMARK_EXPORT_H\n#define BENCHMARK_EXPORT_H\n\n#if defined(_WIN32)\n#define EXPORT_ATTR __declspec(dllexport)\n#define IMPORT_ATTR __declspec(dllimport)\n#define NO_EXPORT_ATTR\n#define DEPRECATED_ATTR __declspec(deprecated)\n#else  // _WIN32\n#define EXPORT_ATTR __attribute__((visibility(\"default\")))\n#define IMPORT_ATTR __attribute__((visibility(\"default\")))\n#define NO_EXPORT_ATTR __attribute__((visibility(\"hidden\")))\n#define DEPRECATE_ATTR __attribute__((__deprecated__))\n#endif  // _WIN32\n\n#ifdef BENCHMARK_STATIC_DEFINE\n#define BENCHMARK_EXPORT\n#define BENCHMARK_NO_EXPORT\n#else  // BENCHMARK_STATIC_DEFINE\n#ifndef BENCHMARK_EXPORT\n#ifdef benchmark_EXPORTS\n/* We are building this library */\n#define BENCHMARK_EXPORT EXPORT_ATTR\n#else  // benchmark_EXPORTS\n/* We are using this library */\n#define BENCHMARK_EXPORT IMPORT_ATTR\n#endif  // benchmark_EXPORTS\n#endif  // !BENCHMARK_EXPORT\n\n#ifndef BENCHMARK_NO_EXPORT\n#define BENCHMARK_NO_EXPORT NO_EXPORT_ATTR\n#endif  // !BENCHMARK_NO_EXPORT\n#endif  // BENCHMARK_STATIC_DEFINE\n\n#ifndef BENCHMARK_DEPRECATED\n#define BENCHMARK_DEPRECATED DEPRECATE_ATTR\n#endif  // BENCHMARK_DEPRECATED\n\n#ifndef BENCHMARK_DEPRECATED_EXPORT\n#define BENCHMARK_DEPRECATED_EXPORT BENCHMARK_EXPORT BENCHMARK_DEPRECATED\n#endif  // BENCHMARK_DEPRECATED_EXPORT\n\n#ifndef BENCHMARK_DEPRECATED_NO_EXPORT\n#define BENCHMARK_DEPRECATED_NO_EXPORT BENCHMARK_NO_EXPORT BENCHMARK_DEPRECATED\n#endif  // BENCHMARK_DEPRECATED_EXPORT\n\n#endif /* BENCHMARK_EXPORT_H */\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/CMakeLists.txt",
    "content": "#Allow the source files to find headers in src /\ninclude(GNUInstallDirs)\ninclude_directories(${PROJECT_SOURCE_DIR}/src)\n\nif (DEFINED BENCHMARK_CXX_LINKER_FLAGS)\n  list(APPEND CMAKE_SHARED_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\n  list(APPEND CMAKE_MODULE_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\nendif()\n\nfile(GLOB\n  SOURCE_FILES\n    *.cc\n    ${PROJECT_SOURCE_DIR}/include/benchmark/*.h\n    ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\nfile(GLOB BENCHMARK_MAIN \"benchmark_main.cc\")\nforeach(item ${BENCHMARK_MAIN})\n  list(REMOVE_ITEM SOURCE_FILES \"${item}\")\nendforeach()\n\nadd_library(benchmark ${SOURCE_FILES})\nadd_library(benchmark::benchmark ALIAS benchmark)\nset_target_properties(benchmark PROPERTIES\n  OUTPUT_NAME \"benchmark\"\n  VERSION ${GENERIC_LIB_VERSION}\n  SOVERSION ${GENERIC_LIB_SOVERSION}\n)\ntarget_include_directories(benchmark PUBLIC\n  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>\n)\n\nset_property(\n  SOURCE benchmark.cc\n  APPEND\n  PROPERTY COMPILE_DEFINITIONS\n  BENCHMARK_VERSION=\"${VERSION}\"\n)\n\n# libpfm, if available\nif (PFM_FOUND)\n  target_link_libraries(benchmark PRIVATE PFM::libpfm)\n  target_compile_definitions(benchmark PRIVATE -DHAVE_LIBPFM)\nendif()\n\n# pthread affinity, if available\nif(HAVE_PTHREAD_AFFINITY)\n  target_compile_definitions(benchmark PRIVATE -DBENCHMARK_HAS_PTHREAD_AFFINITY)\nendif()\n\n# Link threads.\ntarget_link_libraries(benchmark PRIVATE Threads::Threads)\n\ntarget_link_libraries(benchmark PRIVATE ${BENCHMARK_CXX_LIBRARIES})\n\nif(HAVE_LIB_RT)\n  target_link_libraries(benchmark PRIVATE rt)\nendif(HAVE_LIB_RT)\n\n\n# We need extra libraries on Windows\nif(${CMAKE_SYSTEM_NAME} MATCHES \"Windows\")\n  target_link_libraries(benchmark PRIVATE shlwapi)\nendif()\n\n# We need extra libraries on Solaris\nif(${CMAKE_SYSTEM_NAME} MATCHES \"SunOS\")\n  target_link_libraries(benchmark PRIVATE kstat)\n  set(BENCHMARK_PRIVATE_LINK_LIBRARIES -lkstat)\nendif()\n\nif (NOT BUILD_SHARED_LIBS)\n  target_compile_definitions(benchmark PUBLIC -DBENCHMARK_STATIC_DEFINE)\nendif()\n\n# Benchmark main library\nadd_library(benchmark_main \"benchmark_main.cc\")\nadd_library(benchmark::benchmark_main ALIAS benchmark_main)\nset_target_properties(benchmark_main PROPERTIES\n  OUTPUT_NAME \"benchmark_main\"\n  VERSION ${GENERIC_LIB_VERSION}\n  SOVERSION ${GENERIC_LIB_SOVERSION}\n  DEFINE_SYMBOL benchmark_EXPORTS\n)\ntarget_link_libraries(benchmark_main PUBLIC benchmark::benchmark)\n\nset(generated_dir \"${PROJECT_BINARY_DIR}\")\n\nset(version_config \"${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake\")\nset(project_config \"${generated_dir}/${PROJECT_NAME}Config.cmake\")\nset(pkg_config \"${generated_dir}/${PROJECT_NAME}.pc\")\nset(pkg_config_main \"${generated_dir}/${PROJECT_NAME}_main.pc\")\nset(targets_to_export benchmark benchmark_main)\nset(targets_export_name \"${PROJECT_NAME}Targets\")\n\nset(namespace \"${PROJECT_NAME}::\")\n\ninclude(CMakePackageConfigHelpers)\n\nconfigure_package_config_file (\n  ${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in\n  ${project_config}\n  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\n  NO_SET_AND_CHECK_MACRO\n  NO_CHECK_REQUIRED_COMPONENTS_MACRO\n)\nwrite_basic_package_version_file(\n  \"${version_config}\" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion\n)\n\nconfigure_file(\"${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in\" \"${pkg_config}\" @ONLY)\nconfigure_file(\"${PROJECT_SOURCE_DIR}/cmake/benchmark_main.pc.in\" \"${pkg_config_main}\" @ONLY)\n\nexport (\n  TARGETS ${targets_to_export}\n  NAMESPACE \"${namespace}\"\n  FILE ${generated_dir}/${targets_export_name}.cmake\n)\n\nif (BENCHMARK_ENABLE_INSTALL)\n  # Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)\n  install(\n    TARGETS ${targets_to_export}\n    EXPORT ${targets_export_name}\n    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}\n    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})\n\n  install(\n    DIRECTORY \"${PROJECT_SOURCE_DIR}/include/benchmark\"\n              \"${PROJECT_BINARY_DIR}/include/benchmark\"\n    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}\n    FILES_MATCHING PATTERN \"*.*h\")\n\n  install(\n      FILES \"${project_config}\" \"${version_config}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n\n  install(\n      FILES \"${pkg_config}\" \"${pkg_config_main}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n\n  install(\n      EXPORT \"${targets_export_name}\"\n      NAMESPACE \"${namespace}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\nendif()\n\nif (BENCHMARK_ENABLE_DOXYGEN)\n  find_package(Doxygen REQUIRED)\n  set(DOXYGEN_QUIET YES)\n  set(DOXYGEN_RECURSIVE YES)\n  set(DOXYGEN_GENERATE_HTML YES)\n  set(DOXYGEN_GENERATE_MAN NO)\n  set(DOXYGEN_MARKDOWN_SUPPORT YES)\n  set(DOXYGEN_BUILTIN_STL_SUPPORT YES)\n  set(DOXYGEN_EXTRACT_PACKAGE YES)\n  set(DOXYGEN_EXTRACT_STATIC YES)\n  set(DOXYGEN_SHOW_INCLUDE_FILES YES)\n  set(DOXYGEN_BINARY_TOC YES)\n  set(DOXYGEN_TOC_EXPAND YES)\n  set(DOXYGEN_USE_MDFILE_AS_MAINPAGE \"index.md\")\n  doxygen_add_docs(benchmark_doxygen\n    docs\n    include\n    src\n    ALL\n    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n    COMMENT \"Building documentation with Doxygen.\")\n  if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_DOCS)\n    install(\n      DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/html/\"\n      DESTINATION ${CMAKE_INSTALL_DOCDIR})\n  endif()\nelse()\n  if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_DOCS)\n    install(\n      DIRECTORY \"${PROJECT_SOURCE_DIR}/docs/\"\n      DESTINATION ${CMAKE_INSTALL_DOCDIR})\n  endif()\nendif()\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/arraysize.h",
    "content": "#ifndef BENCHMARK_ARRAYSIZE_H_\n#define BENCHMARK_ARRAYSIZE_H_\n\n#include \"internal_macros.h\"\n\nnamespace benchmark {\nnamespace internal {\n// The arraysize(arr) macro returns the # of elements in an array arr.\n// The expression is a compile-time constant, and therefore can be\n// used in defining new arrays, for example.  If you use arraysize on\n// a pointer by mistake, you will get a compile-time error.\n//\n\n// This template function declaration is used in defining arraysize.\n// Note that the function doesn't need an implementation, as we only\n// use its type.\ntemplate <typename T, size_t N>\nchar (&ArraySizeHelper(T (&array)[N]))[N];\n\n// That gcc wants both of these prototypes seems mysterious. VC, for\n// its part, can't decide which to use (another mystery). Matching of\n// template overloads: the final frontier.\n#ifndef COMPILER_MSVC\ntemplate <typename T, size_t N>\nchar (&ArraySizeHelper(const T (&array)[N]))[N];\n#endif\n\n#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array)))\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_ARRAYSIZE_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark/benchmark.h\"\n\n#include \"benchmark_api_internal.h\"\n#include \"benchmark_runner.h\"\n#include \"internal_macros.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <fstream>\n#include <iostream>\n#include <limits>\n#include <map>\n#include <memory>\n#include <random>\n#include <string>\n#include <thread>\n#include <utility>\n\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"perf_counters.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"thread_manager.h\"\n#include \"thread_timer.h\"\n\nnamespace benchmark {\n// Print a list of benchmarks. This option overrides all other options.\nBM_DEFINE_bool(benchmark_list_tests, false);\n\n// A regular expression that specifies the set of benchmarks to execute.  If\n// this flag is empty, or if this flag is the string \\\"all\\\", all benchmarks\n// linked into the binary are run.\nBM_DEFINE_string(benchmark_filter, \"\");\n\n// Specification of how long to run the benchmark.\n//\n// It can be either an exact number of iterations (specified as `<integer>x`),\n// or a minimum number of seconds (specified as `<float>s`). If the latter\n// format (ie., min seconds) is used, the system may run the benchmark longer\n// until the results are considered significant.\n//\n// For backward compatibility, the `s` suffix may be omitted, in which case,\n// the specified number is interpreted as the number of seconds.\n//\n// For cpu-time based tests, this is the lower bound\n// on the total cpu time used by all threads that make up the test.  For\n// real-time based tests, this is the lower bound on the elapsed time of the\n// benchmark execution, regardless of number of threads.\nBM_DEFINE_string(benchmark_min_time, kDefaultMinTimeStr);\n\n// Minimum number of seconds a benchmark should be run before results should be\n// taken into account. This e.g can be necessary for benchmarks of code which\n// needs to fill some form of cache before performance is of interest.\n// Note: results gathered within this period are discarded and not used for\n// reported result.\nBM_DEFINE_double(benchmark_min_warmup_time, 0.0);\n\n// The number of runs of each benchmark. If greater than 1, the mean and\n// standard deviation of the runs will be reported.\nBM_DEFINE_int32(benchmark_repetitions, 1);\n\n// If set, enable random interleaving of repetitions of all benchmarks.\n// See http://github.com/google/benchmark/issues/1051 for details.\nBM_DEFINE_bool(benchmark_enable_random_interleaving, false);\n\n// Report the result of each benchmark repetitions. When 'true' is specified\n// only the mean, standard deviation, and other statistics are reported for\n// repeated benchmarks. Affects all reporters.\nBM_DEFINE_bool(benchmark_report_aggregates_only, false);\n\n// Display the result of each benchmark repetitions. When 'true' is specified\n// only the mean, standard deviation, and other statistics are displayed for\n// repeated benchmarks. Unlike benchmark_report_aggregates_only, only affects\n// the display reporter, but  *NOT* file reporter, which will still contain\n// all the output.\nBM_DEFINE_bool(benchmark_display_aggregates_only, false);\n\n// The format to use for console output.\n// Valid values are 'console', 'json', or 'csv'.\nBM_DEFINE_string(benchmark_format, \"console\");\n\n// The format to use for file output.\n// Valid values are 'console', 'json', or 'csv'.\nBM_DEFINE_string(benchmark_out_format, \"json\");\n\n// The file to write additional output to.\nBM_DEFINE_string(benchmark_out, \"\");\n\n// Whether to use colors in the output.  Valid values:\n// 'true'/'yes'/1, 'false'/'no'/0, and 'auto'. 'auto' means to use colors if\n// the output is being sent to a terminal and the TERM environment variable is\n// set to a terminal type that supports colors.\nBM_DEFINE_string(benchmark_color, \"auto\");\n\n// Whether to use tabular format when printing user counters to the console.\n// Valid values: 'true'/'yes'/1, 'false'/'no'/0.  Defaults to false.\nBM_DEFINE_bool(benchmark_counters_tabular, false);\n\n// List of additional perf counters to collect, in libpfm format. For more\n// information about libpfm: https://man7.org/linux/man-pages/man3/libpfm.3.html\nBM_DEFINE_string(benchmark_perf_counters, \"\");\n\n// Extra context to include in the output formatted as comma-separated key-value\n// pairs. Kept internal as it's only used for parsing from env/command line.\nBM_DEFINE_kvpairs(benchmark_context, {});\n\n// Set the default time unit to use for reports\n// Valid values are 'ns', 'us', 'ms' or 's'\nBM_DEFINE_string(benchmark_time_unit, \"\");\n\n// The level of verbose logging to output\nBM_DEFINE_int32(v, 0);\n\nnamespace internal {\n\nstd::map<std::string, std::string>* global_context = nullptr;\n\nBENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext() {\n  return global_context;\n}\n\nstatic void const volatile* volatile global_force_escape_pointer;\n\n// FIXME: Verify if LTO still messes this up?\nvoid UseCharPointer(char const volatile* const v) {\n  // We want to escape the pointer `v` so that the compiler can not eliminate\n  // computations that produced it. To do that, we escape the pointer by storing\n  // it into a volatile variable, since generally, volatile store, is not\n  // something the compiler is allowed to elide.\n  global_force_escape_pointer = reinterpret_cast<void const volatile*>(v);\n}\n\n}  // namespace internal\n\nState::State(std::string name, IterationCount max_iters,\n             const std::vector<int64_t>& ranges, int thread_i, int n_threads,\n             internal::ThreadTimer* timer, internal::ThreadManager* manager,\n             internal::PerfCountersMeasurement* perf_counters_measurement)\n    : total_iterations_(0),\n      batch_leftover_(0),\n      max_iterations(max_iters),\n      started_(false),\n      finished_(false),\n      skipped_(internal::NotSkipped),\n      range_(ranges),\n      complexity_n_(0),\n      name_(std::move(name)),\n      thread_index_(thread_i),\n      threads_(n_threads),\n      timer_(timer),\n      manager_(manager),\n      perf_counters_measurement_(perf_counters_measurement) {\n  BM_CHECK(max_iterations != 0) << \"At least one iteration must be run\";\n  BM_CHECK_LT(thread_index_, threads_)\n      << \"thread_index must be less than threads\";\n\n  // Add counters with correct flag now.  If added with `counters[name]` in\n  // `PauseTiming`, a new `Counter` will be inserted the first time, which\n  // won't have the flag.  Inserting them now also reduces the allocations\n  // during the benchmark.\n  if (perf_counters_measurement_) {\n    for (const std::string& counter_name :\n         perf_counters_measurement_->names()) {\n      counters[counter_name] = Counter(0.0, Counter::kAvgIterations);\n    }\n  }\n\n  // Note: The use of offsetof below is technically undefined until C++17\n  // because State is not a standard layout type. However, all compilers\n  // currently provide well-defined behavior as an extension (which is\n  // demonstrated since constexpr evaluation must diagnose all undefined\n  // behavior). However, GCC and Clang also warn about this use of offsetof,\n  // which must be suppressed.\n#if defined(__INTEL_COMPILER)\n#pragma warning push\n#pragma warning(disable : 1875)\n#elif defined(__GNUC__) || defined(__clang__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Winvalid-offsetof\"\n#endif\n#if defined(__NVCC__)\n#pragma nv_diagnostic push\n#pragma nv_diag_suppress 1427\n#endif\n#if defined(__NVCOMPILER)\n#pragma diagnostic push\n#pragma diag_suppress offset_in_non_POD_nonstandard\n#endif\n  // Offset tests to ensure commonly accessed data is on the first cache line.\n  const int cache_line_size = 64;\n  static_assert(\n      offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), \"\");\n#if defined(__INTEL_COMPILER)\n#pragma warning pop\n#elif defined(__GNUC__) || defined(__clang__)\n#pragma GCC diagnostic pop\n#endif\n#if defined(__NVCC__)\n#pragma nv_diagnostic pop\n#endif\n#if defined(__NVCOMPILER)\n#pragma diagnostic pop\n#endif\n}\n\nvoid State::PauseTiming() {\n  // Add in time accumulated so far\n  BM_CHECK(started_ && !finished_ && !skipped());\n  timer_->StopTimer();\n  if (perf_counters_measurement_) {\n    std::vector<std::pair<std::string, double>> measurements;\n    if (!perf_counters_measurement_->Stop(measurements)) {\n      BM_CHECK(false) << \"Perf counters read the value failed.\";\n    }\n    for (const auto& name_and_measurement : measurements) {\n      const std::string& name = name_and_measurement.first;\n      const double measurement = name_and_measurement.second;\n      // Counter was inserted with `kAvgIterations` flag by the constructor.\n      assert(counters.find(name) != counters.end());\n      counters[name].value += measurement;\n    }\n  }\n}\n\nvoid State::ResumeTiming() {\n  BM_CHECK(started_ && !finished_ && !skipped());\n  timer_->StartTimer();\n  if (perf_counters_measurement_) {\n    perf_counters_measurement_->Start();\n  }\n}\n\nvoid State::SkipWithMessage(const std::string& msg) {\n  skipped_ = internal::SkippedWithMessage;\n  {\n    MutexLock l(manager_->GetBenchmarkMutex());\n    if (internal::NotSkipped == manager_->results.skipped_) {\n      manager_->results.skip_message_ = msg;\n      manager_->results.skipped_ = skipped_;\n    }\n  }\n  total_iterations_ = 0;\n  if (timer_->running()) timer_->StopTimer();\n}\n\nvoid State::SkipWithError(const std::string& msg) {\n  skipped_ = internal::SkippedWithError;\n  {\n    MutexLock l(manager_->GetBenchmarkMutex());\n    if (internal::NotSkipped == manager_->results.skipped_) {\n      manager_->results.skip_message_ = msg;\n      manager_->results.skipped_ = skipped_;\n    }\n  }\n  total_iterations_ = 0;\n  if (timer_->running()) timer_->StopTimer();\n}\n\nvoid State::SetIterationTime(double seconds) {\n  timer_->SetIterationTime(seconds);\n}\n\nvoid State::SetLabel(const std::string& label) {\n  MutexLock l(manager_->GetBenchmarkMutex());\n  manager_->results.report_label_ = label;\n}\n\nvoid State::StartKeepRunning() {\n  BM_CHECK(!started_ && !finished_);\n  started_ = true;\n  total_iterations_ = skipped() ? 0 : max_iterations;\n  manager_->StartStopBarrier();\n  if (!skipped()) ResumeTiming();\n}\n\nvoid State::FinishKeepRunning() {\n  BM_CHECK(started_ && (!finished_ || skipped()));\n  if (!skipped()) {\n    PauseTiming();\n  }\n  // Total iterations has now wrapped around past 0. Fix this.\n  total_iterations_ = 0;\n  finished_ = true;\n  manager_->StartStopBarrier();\n}\n\nnamespace internal {\nnamespace {\n\n// Flushes streams after invoking reporter methods that write to them. This\n// ensures users get timely updates even when streams are not line-buffered.\nvoid FlushStreams(BenchmarkReporter* reporter) {\n  if (!reporter) return;\n  std::flush(reporter->GetOutputStream());\n  std::flush(reporter->GetErrorStream());\n}\n\n// Reports in both display and file reporters.\nvoid Report(BenchmarkReporter* display_reporter,\n            BenchmarkReporter* file_reporter, const RunResults& run_results) {\n  auto report_one = [](BenchmarkReporter* reporter, bool aggregates_only,\n                       const RunResults& results) {\n    assert(reporter);\n    // If there are no aggregates, do output non-aggregates.\n    aggregates_only &= !results.aggregates_only.empty();\n    if (!aggregates_only) reporter->ReportRuns(results.non_aggregates);\n    if (!results.aggregates_only.empty())\n      reporter->ReportRuns(results.aggregates_only);\n  };\n\n  report_one(display_reporter, run_results.display_report_aggregates_only,\n             run_results);\n  if (file_reporter)\n    report_one(file_reporter, run_results.file_report_aggregates_only,\n               run_results);\n\n  FlushStreams(display_reporter);\n  FlushStreams(file_reporter);\n}\n\nvoid RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,\n                   BenchmarkReporter* display_reporter,\n                   BenchmarkReporter* file_reporter) {\n  // Note the file_reporter can be null.\n  BM_CHECK(display_reporter != nullptr);\n\n  // Determine the width of the name field using a minimum width of 10.\n  bool might_have_aggregates = FLAGS_benchmark_repetitions > 1;\n  size_t name_field_width = 10;\n  size_t stat_field_width = 0;\n  for (const BenchmarkInstance& benchmark : benchmarks) {\n    name_field_width =\n        std::max<size_t>(name_field_width, benchmark.name().str().size());\n    might_have_aggregates |= benchmark.repetitions() > 1;\n\n    for (const auto& Stat : benchmark.statistics())\n      stat_field_width = std::max<size_t>(stat_field_width, Stat.name_.size());\n  }\n  if (might_have_aggregates) name_field_width += 1 + stat_field_width;\n\n  // Print header here\n  BenchmarkReporter::Context context;\n  context.name_field_width = name_field_width;\n\n  // Keep track of running times of all instances of each benchmark family.\n  std::map<int /*family_index*/, BenchmarkReporter::PerFamilyRunReports>\n      per_family_reports;\n\n  if (display_reporter->ReportContext(context) &&\n      (!file_reporter || file_reporter->ReportContext(context))) {\n    FlushStreams(display_reporter);\n    FlushStreams(file_reporter);\n\n    size_t num_repetitions_total = 0;\n\n    // This perfcounters object needs to be created before the runners vector\n    // below so it outlasts their lifetime.\n    PerfCountersMeasurement perfcounters(\n        StrSplit(FLAGS_benchmark_perf_counters, ','));\n\n    // Vector of benchmarks to run\n    std::vector<internal::BenchmarkRunner> runners;\n    runners.reserve(benchmarks.size());\n\n    // Count the number of benchmarks with threads to warn the user in case\n    // performance counters are used.\n    int benchmarks_with_threads = 0;\n\n    // Loop through all benchmarks\n    for (const BenchmarkInstance& benchmark : benchmarks) {\n      BenchmarkReporter::PerFamilyRunReports* reports_for_family = nullptr;\n      if (benchmark.complexity() != oNone)\n        reports_for_family = &per_family_reports[benchmark.family_index()];\n      benchmarks_with_threads += (benchmark.threads() > 1);\n      runners.emplace_back(benchmark, &perfcounters, reports_for_family);\n      int num_repeats_of_this_instance = runners.back().GetNumRepeats();\n      num_repetitions_total +=\n          static_cast<size_t>(num_repeats_of_this_instance);\n      if (reports_for_family)\n        reports_for_family->num_runs_total += num_repeats_of_this_instance;\n    }\n    assert(runners.size() == benchmarks.size() && \"Unexpected runner count.\");\n\n    // The use of performance counters with threads would be unintuitive for\n    // the average user so we need to warn them about this case\n    if ((benchmarks_with_threads > 0) && (perfcounters.num_counters() > 0)) {\n      GetErrorLogInstance()\n          << \"***WARNING*** There are \" << benchmarks_with_threads\n          << \" benchmarks with threads and \" << perfcounters.num_counters()\n          << \" performance counters were requested. Beware counters will \"\n             \"reflect the combined usage across all \"\n             \"threads.\\n\";\n    }\n\n    std::vector<size_t> repetition_indices;\n    repetition_indices.reserve(num_repetitions_total);\n    for (size_t runner_index = 0, num_runners = runners.size();\n         runner_index != num_runners; ++runner_index) {\n      const internal::BenchmarkRunner& runner = runners[runner_index];\n      std::fill_n(std::back_inserter(repetition_indices),\n                  runner.GetNumRepeats(), runner_index);\n    }\n    assert(repetition_indices.size() == num_repetitions_total &&\n           \"Unexpected number of repetition indexes.\");\n\n    if (FLAGS_benchmark_enable_random_interleaving) {\n      std::random_device rd;\n      std::mt19937 g(rd());\n      std::shuffle(repetition_indices.begin(), repetition_indices.end(), g);\n    }\n\n    for (size_t repetition_index : repetition_indices) {\n      internal::BenchmarkRunner& runner = runners[repetition_index];\n      runner.DoOneRepetition();\n      if (runner.HasRepeatsRemaining()) continue;\n      // FIXME: report each repetition separately, not all of them in bulk.\n\n      display_reporter->ReportRunsConfig(\n          runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());\n      if (file_reporter)\n        file_reporter->ReportRunsConfig(\n            runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());\n\n      RunResults run_results = runner.GetResults();\n\n      // Maybe calculate complexity report\n      if (const auto* reports_for_family = runner.GetReportsForFamily()) {\n        if (reports_for_family->num_runs_done ==\n            reports_for_family->num_runs_total) {\n          auto additional_run_stats = ComputeBigO(reports_for_family->Runs);\n          run_results.aggregates_only.insert(run_results.aggregates_only.end(),\n                                             additional_run_stats.begin(),\n                                             additional_run_stats.end());\n          per_family_reports.erase(\n              static_cast<int>(reports_for_family->Runs.front().family_index));\n        }\n      }\n\n      Report(display_reporter, file_reporter, run_results);\n    }\n  }\n  display_reporter->Finalize();\n  if (file_reporter) file_reporter->Finalize();\n  FlushStreams(display_reporter);\n  FlushStreams(file_reporter);\n}\n\n// Disable deprecated warnings temporarily because we need to reference\n// CSVReporter but don't want to trigger -Werror=-Wdeprecated-declarations\nBENCHMARK_DISABLE_DEPRECATED_WARNING\n\nstd::unique_ptr<BenchmarkReporter> CreateReporter(\n    std::string const& name, ConsoleReporter::OutputOptions output_opts) {\n  typedef std::unique_ptr<BenchmarkReporter> PtrType;\n  if (name == \"console\") {\n    return PtrType(new ConsoleReporter(output_opts));\n  }\n  if (name == \"json\") {\n    return PtrType(new JSONReporter());\n  }\n  if (name == \"csv\") {\n    return PtrType(new CSVReporter());\n  }\n  std::cerr << \"Unexpected format: '\" << name << \"'\\n\";\n  std::exit(1);\n}\n\nBENCHMARK_RESTORE_DEPRECATED_WARNING\n\n}  // end namespace\n\nbool IsZero(double n) {\n  return std::abs(n) < std::numeric_limits<double>::epsilon();\n}\n\nConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {\n  int output_opts = ConsoleReporter::OO_Defaults;\n  auto is_benchmark_color = [force_no_color]() -> bool {\n    if (force_no_color) {\n      return false;\n    }\n    if (FLAGS_benchmark_color == \"auto\") {\n      return IsColorTerminal();\n    }\n    return IsTruthyFlagValue(FLAGS_benchmark_color);\n  };\n  if (is_benchmark_color()) {\n    output_opts |= ConsoleReporter::OO_Color;\n  } else {\n    output_opts &= ~ConsoleReporter::OO_Color;\n  }\n  if (FLAGS_benchmark_counters_tabular) {\n    output_opts |= ConsoleReporter::OO_Tabular;\n  } else {\n    output_opts &= ~ConsoleReporter::OO_Tabular;\n  }\n  return static_cast<ConsoleReporter::OutputOptions>(output_opts);\n}\n\n}  // end namespace internal\n\nBenchmarkReporter* CreateDefaultDisplayReporter() {\n  static auto default_display_reporter =\n      internal::CreateReporter(FLAGS_benchmark_format,\n                               internal::GetOutputOptions())\n          .release();\n  return default_display_reporter;\n}\n\nsize_t RunSpecifiedBenchmarks() {\n  return RunSpecifiedBenchmarks(nullptr, nullptr, FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(std::string spec) {\n  return RunSpecifiedBenchmarks(nullptr, nullptr, std::move(spec));\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) {\n  return RunSpecifiedBenchmarks(display_reporter, nullptr,\n                                FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              std::string spec) {\n  return RunSpecifiedBenchmarks(display_reporter, nullptr, std::move(spec));\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              BenchmarkReporter* file_reporter) {\n  return RunSpecifiedBenchmarks(display_reporter, file_reporter,\n                                FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              BenchmarkReporter* file_reporter,\n                              std::string spec) {\n  if (spec.empty() || spec == \"all\")\n    spec = \".\";  // Regexp that matches all benchmarks\n\n  // Setup the reporters\n  std::ofstream output_file;\n  std::unique_ptr<BenchmarkReporter> default_display_reporter;\n  std::unique_ptr<BenchmarkReporter> default_file_reporter;\n  if (!display_reporter) {\n    default_display_reporter.reset(CreateDefaultDisplayReporter());\n    display_reporter = default_display_reporter.get();\n  }\n  auto& Out = display_reporter->GetOutputStream();\n  auto& Err = display_reporter->GetErrorStream();\n\n  std::string const& fname = FLAGS_benchmark_out;\n  if (fname.empty() && file_reporter) {\n    Err << \"A custom file reporter was provided but \"\n           \"--benchmark_out=<file> was not specified.\"\n        << std::endl;\n    Out.flush();\n    Err.flush();\n    std::exit(1);\n  }\n  if (!fname.empty()) {\n    output_file.open(fname);\n    if (!output_file.is_open()) {\n      Err << \"invalid file name: '\" << fname << \"'\" << std::endl;\n      Out.flush();\n      Err.flush();\n      std::exit(1);\n    }\n    if (!file_reporter) {\n      default_file_reporter = internal::CreateReporter(\n          FLAGS_benchmark_out_format, FLAGS_benchmark_counters_tabular\n                                          ? ConsoleReporter::OO_Tabular\n                                          : ConsoleReporter::OO_None);\n      file_reporter = default_file_reporter.get();\n    }\n    file_reporter->SetOutputStream(&output_file);\n    file_reporter->SetErrorStream(&output_file);\n  }\n\n  std::vector<internal::BenchmarkInstance> benchmarks;\n  if (!FindBenchmarksInternal(spec, &benchmarks, &Err)) {\n    Out.flush();\n    Err.flush();\n    return 0;\n  }\n\n  if (benchmarks.empty()) {\n    Err << \"Failed to match any benchmarks against regex: \" << spec << \"\\n\";\n    Out.flush();\n    Err.flush();\n    return 0;\n  }\n\n  if (FLAGS_benchmark_list_tests) {\n    for (auto const& benchmark : benchmarks)\n      Out << benchmark.name().str() << \"\\n\";\n  } else {\n    internal::RunBenchmarks(benchmarks, display_reporter, file_reporter);\n  }\n\n  Out.flush();\n  Err.flush();\n  return benchmarks.size();\n}\n\nnamespace {\n// stores the time unit benchmarks use by default\nTimeUnit default_time_unit = kNanosecond;\n}  // namespace\n\nTimeUnit GetDefaultTimeUnit() { return default_time_unit; }\n\nvoid SetDefaultTimeUnit(TimeUnit unit) { default_time_unit = unit; }\n\nstd::string GetBenchmarkFilter() { return FLAGS_benchmark_filter; }\n\nvoid SetBenchmarkFilter(std::string value) {\n  FLAGS_benchmark_filter = std::move(value);\n}\n\nint32_t GetBenchmarkVerbosity() { return FLAGS_v; }\n\nvoid RegisterMemoryManager(MemoryManager* manager) {\n  internal::memory_manager = manager;\n}\n\nvoid RegisterProfilerManager(ProfilerManager* manager) {\n  internal::profiler_manager = manager;\n}\n\nvoid AddCustomContext(const std::string& key, const std::string& value) {\n  if (internal::global_context == nullptr) {\n    internal::global_context = new std::map<std::string, std::string>();\n  }\n  if (!internal::global_context->emplace(key, value).second) {\n    std::cerr << \"Failed to add custom context \\\"\" << key << \"\\\" as it already \"\n              << \"exists with value \\\"\" << value << \"\\\"\\n\";\n  }\n}\n\nnamespace internal {\n\nvoid (*HelperPrintf)();\n\nvoid PrintUsageAndExit() {\n  HelperPrintf();\n  exit(0);\n}\n\nvoid SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {\n  if (time_unit_flag == \"s\") {\n    return SetDefaultTimeUnit(kSecond);\n  }\n  if (time_unit_flag == \"ms\") {\n    return SetDefaultTimeUnit(kMillisecond);\n  }\n  if (time_unit_flag == \"us\") {\n    return SetDefaultTimeUnit(kMicrosecond);\n  }\n  if (time_unit_flag == \"ns\") {\n    return SetDefaultTimeUnit(kNanosecond);\n  }\n  if (!time_unit_flag.empty()) {\n    PrintUsageAndExit();\n  }\n}\n\nvoid ParseCommandLineFlags(int* argc, char** argv) {\n  using namespace benchmark;\n  BenchmarkReporter::Context::executable_name =\n      (argc && *argc > 0) ? argv[0] : \"unknown\";\n  for (int i = 1; argc && i < *argc; ++i) {\n    if (ParseBoolFlag(argv[i], \"benchmark_list_tests\",\n                      &FLAGS_benchmark_list_tests) ||\n        ParseStringFlag(argv[i], \"benchmark_filter\", &FLAGS_benchmark_filter) ||\n        ParseStringFlag(argv[i], \"benchmark_min_time\",\n                        &FLAGS_benchmark_min_time) ||\n        ParseDoubleFlag(argv[i], \"benchmark_min_warmup_time\",\n                        &FLAGS_benchmark_min_warmup_time) ||\n        ParseInt32Flag(argv[i], \"benchmark_repetitions\",\n                       &FLAGS_benchmark_repetitions) ||\n        ParseBoolFlag(argv[i], \"benchmark_enable_random_interleaving\",\n                      &FLAGS_benchmark_enable_random_interleaving) ||\n        ParseBoolFlag(argv[i], \"benchmark_report_aggregates_only\",\n                      &FLAGS_benchmark_report_aggregates_only) ||\n        ParseBoolFlag(argv[i], \"benchmark_display_aggregates_only\",\n                      &FLAGS_benchmark_display_aggregates_only) ||\n        ParseStringFlag(argv[i], \"benchmark_format\", &FLAGS_benchmark_format) ||\n        ParseStringFlag(argv[i], \"benchmark_out\", &FLAGS_benchmark_out) ||\n        ParseStringFlag(argv[i], \"benchmark_out_format\",\n                        &FLAGS_benchmark_out_format) ||\n        ParseStringFlag(argv[i], \"benchmark_color\", &FLAGS_benchmark_color) ||\n        ParseBoolFlag(argv[i], \"benchmark_counters_tabular\",\n                      &FLAGS_benchmark_counters_tabular) ||\n        ParseStringFlag(argv[i], \"benchmark_perf_counters\",\n                        &FLAGS_benchmark_perf_counters) ||\n        ParseKeyValueFlag(argv[i], \"benchmark_context\",\n                          &FLAGS_benchmark_context) ||\n        ParseStringFlag(argv[i], \"benchmark_time_unit\",\n                        &FLAGS_benchmark_time_unit) ||\n        ParseInt32Flag(argv[i], \"v\", &FLAGS_v)) {\n      for (int j = i; j != *argc - 1; ++j) argv[j] = argv[j + 1];\n\n      --(*argc);\n      --i;\n    } else if (IsFlag(argv[i], \"help\")) {\n      PrintUsageAndExit();\n    }\n  }\n  for (auto const* flag :\n       {&FLAGS_benchmark_format, &FLAGS_benchmark_out_format}) {\n    if (*flag != \"console\" && *flag != \"json\" && *flag != \"csv\") {\n      PrintUsageAndExit();\n    }\n  }\n  SetDefaultTimeUnitFromFlag(FLAGS_benchmark_time_unit);\n  if (FLAGS_benchmark_color.empty()) {\n    PrintUsageAndExit();\n  }\n  for (const auto& kv : FLAGS_benchmark_context) {\n    AddCustomContext(kv.first, kv.second);\n  }\n}\n\nint InitializeStreams() {\n  static std::ios_base::Init init;\n  return 0;\n}\n\n}  // end namespace internal\n\nstd::string GetBenchmarkVersion() {\n#ifdef BENCHMARK_VERSION\n  return {BENCHMARK_VERSION};\n#else\n  return {\"\"};\n#endif\n}\n\nvoid PrintDefaultHelp() {\n  fprintf(stdout,\n          \"benchmark\"\n          \" [--benchmark_list_tests={true|false}]\\n\"\n          \"          [--benchmark_filter=<regex>]\\n\"\n          \"          [--benchmark_min_time=`<integer>x` OR `<float>s` ]\\n\"\n          \"          [--benchmark_min_warmup_time=<min_warmup_time>]\\n\"\n          \"          [--benchmark_repetitions=<num_repetitions>]\\n\"\n          \"          [--benchmark_enable_random_interleaving={true|false}]\\n\"\n          \"          [--benchmark_report_aggregates_only={true|false}]\\n\"\n          \"          [--benchmark_display_aggregates_only={true|false}]\\n\"\n          \"          [--benchmark_format=<console|json|csv>]\\n\"\n          \"          [--benchmark_out=<filename>]\\n\"\n          \"          [--benchmark_out_format=<json|console|csv>]\\n\"\n          \"          [--benchmark_color={auto|true|false}]\\n\"\n          \"          [--benchmark_counters_tabular={true|false}]\\n\"\n#if defined HAVE_LIBPFM\n          \"          [--benchmark_perf_counters=<counter>,...]\\n\"\n#endif\n          \"          [--benchmark_context=<key>=<value>,...]\\n\"\n          \"          [--benchmark_time_unit={ns|us|ms|s}]\\n\"\n          \"          [--v=<verbosity>]\\n\");\n}\n\nvoid Initialize(int* argc, char** argv, void (*HelperPrintf)()) {\n  internal::HelperPrintf = HelperPrintf;\n  internal::ParseCommandLineFlags(argc, argv);\n  internal::LogLevel() = FLAGS_v;\n}\n\nvoid Shutdown() { delete internal::global_context; }\n\nbool ReportUnrecognizedArguments(int argc, char** argv) {\n  for (int i = 1; i < argc; ++i) {\n    fprintf(stderr, \"%s: error: unrecognized command-line flag: %s\\n\", argv[0],\n            argv[i]);\n  }\n  return argc > 1;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_api_internal.cc",
    "content": "#include \"benchmark_api_internal.h\"\n\n#include <cinttypes>\n\n#include \"string_util.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nBenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,\n                                     int per_family_instance_idx,\n                                     const std::vector<int64_t>& args,\n                                     int thread_count)\n    : benchmark_(*benchmark),\n      family_index_(family_idx),\n      per_family_instance_index_(per_family_instance_idx),\n      aggregation_report_mode_(benchmark_.aggregation_report_mode_),\n      args_(args),\n      time_unit_(benchmark_.GetTimeUnit()),\n      measure_process_cpu_time_(benchmark_.measure_process_cpu_time_),\n      use_real_time_(benchmark_.use_real_time_),\n      use_manual_time_(benchmark_.use_manual_time_),\n      complexity_(benchmark_.complexity_),\n      complexity_lambda_(benchmark_.complexity_lambda_),\n      statistics_(benchmark_.statistics_),\n      repetitions_(benchmark_.repetitions_),\n      min_time_(benchmark_.min_time_),\n      min_warmup_time_(benchmark_.min_warmup_time_),\n      iterations_(benchmark_.iterations_),\n      threads_(thread_count) {\n  name_.function_name = benchmark_.name_;\n\n  size_t arg_i = 0;\n  for (const auto& arg : args) {\n    if (!name_.args.empty()) {\n      name_.args += '/';\n    }\n\n    if (arg_i < benchmark->arg_names_.size()) {\n      const auto& arg_name = benchmark_.arg_names_[arg_i];\n      if (!arg_name.empty()) {\n        name_.args += StrFormat(\"%s:\", arg_name.c_str());\n      }\n    }\n\n    name_.args += StrFormat(\"%\" PRId64, arg);\n    ++arg_i;\n  }\n\n  if (!IsZero(benchmark->min_time_)) {\n    name_.min_time = StrFormat(\"min_time:%0.3f\", benchmark_.min_time_);\n  }\n\n  if (!IsZero(benchmark->min_warmup_time_)) {\n    name_.min_warmup_time =\n        StrFormat(\"min_warmup_time:%0.3f\", benchmark_.min_warmup_time_);\n  }\n\n  if (benchmark_.iterations_ != 0) {\n    name_.iterations = StrFormat(\n        \"iterations:%lu\", static_cast<unsigned long>(benchmark_.iterations_));\n  }\n\n  if (benchmark_.repetitions_ != 0) {\n    name_.repetitions = StrFormat(\"repeats:%d\", benchmark_.repetitions_);\n  }\n\n  if (benchmark_.measure_process_cpu_time_) {\n    name_.time_type = \"process_time\";\n  }\n\n  if (benchmark_.use_manual_time_) {\n    if (!name_.time_type.empty()) {\n      name_.time_type += '/';\n    }\n    name_.time_type += \"manual_time\";\n  } else if (benchmark_.use_real_time_) {\n    if (!name_.time_type.empty()) {\n      name_.time_type += '/';\n    }\n    name_.time_type += \"real_time\";\n  }\n\n  if (!benchmark_.thread_counts_.empty()) {\n    name_.threads = StrFormat(\"threads:%d\", threads_);\n  }\n\n  setup_ = benchmark_.setup_;\n  teardown_ = benchmark_.teardown_;\n}\n\nState BenchmarkInstance::Run(\n    IterationCount iters, int thread_id, internal::ThreadTimer* timer,\n    internal::ThreadManager* manager,\n    internal::PerfCountersMeasurement* perf_counters_measurement) const {\n  State st(name_.function_name, iters, args_, thread_id, threads_, timer,\n           manager, perf_counters_measurement);\n  benchmark_.Run(st);\n  return st;\n}\n\nvoid BenchmarkInstance::Setup() const {\n  if (setup_) {\n    State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,\n             nullptr, nullptr, nullptr);\n    setup_(st);\n  }\n}\n\nvoid BenchmarkInstance::Teardown() const {\n  if (teardown_) {\n    State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,\n             nullptr, nullptr, nullptr);\n    teardown_(st);\n  }\n}\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_api_internal.h",
    "content": "#ifndef BENCHMARK_API_INTERNAL_H\n#define BENCHMARK_API_INTERNAL_H\n\n#include <cmath>\n#include <iosfwd>\n#include <limits>\n#include <memory>\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"commandlineflags.h\"\n\nnamespace benchmark {\nnamespace internal {\n\n// Information kept per benchmark we may want to run\nclass BenchmarkInstance {\n public:\n  BenchmarkInstance(Benchmark* benchmark, int family_index,\n                    int per_family_instance_index,\n                    const std::vector<int64_t>& args, int threads);\n\n  const BenchmarkName& name() const { return name_; }\n  int family_index() const { return family_index_; }\n  int per_family_instance_index() const { return per_family_instance_index_; }\n  AggregationReportMode aggregation_report_mode() const {\n    return aggregation_report_mode_;\n  }\n  TimeUnit time_unit() const { return time_unit_; }\n  bool measure_process_cpu_time() const { return measure_process_cpu_time_; }\n  bool use_real_time() const { return use_real_time_; }\n  bool use_manual_time() const { return use_manual_time_; }\n  BigO complexity() const { return complexity_; }\n  BigOFunc* complexity_lambda() const { return complexity_lambda_; }\n  const std::vector<Statistics>& statistics() const { return statistics_; }\n  int repetitions() const { return repetitions_; }\n  double min_time() const { return min_time_; }\n  double min_warmup_time() const { return min_warmup_time_; }\n  IterationCount iterations() const { return iterations_; }\n  int threads() const { return threads_; }\n  void Setup() const;\n  void Teardown() const;\n\n  State Run(IterationCount iters, int thread_id, internal::ThreadTimer* timer,\n            internal::ThreadManager* manager,\n            internal::PerfCountersMeasurement* perf_counters_measurement) const;\n\n private:\n  BenchmarkName name_;\n  Benchmark& benchmark_;\n  const int family_index_;\n  const int per_family_instance_index_;\n  AggregationReportMode aggregation_report_mode_;\n  const std::vector<int64_t>& args_;\n  TimeUnit time_unit_;\n  bool measure_process_cpu_time_;\n  bool use_real_time_;\n  bool use_manual_time_;\n  BigO complexity_;\n  BigOFunc* complexity_lambda_;\n  UserCounters counters_;\n  const std::vector<Statistics>& statistics_;\n  int repetitions_;\n  double min_time_;\n  double min_warmup_time_;\n  IterationCount iterations_;\n  int threads_;  // Number of concurrent threads to us\n\n  typedef void (*callback_function)(const benchmark::State&);\n  callback_function setup_ = nullptr;\n  callback_function teardown_ = nullptr;\n};\n\nbool FindBenchmarksInternal(const std::string& re,\n                            std::vector<BenchmarkInstance>* benchmarks,\n                            std::ostream* Err);\n\nbool IsZero(double n);\n\nBENCHMARK_EXPORT\nConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false);\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_API_INTERNAL_H\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_main.cc",
    "content": "// Copyright 2018 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark/benchmark.h\"\n\nBENCHMARK_EXPORT int main(int, char**);\nBENCHMARK_MAIN();\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_name.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <benchmark/benchmark.h>\n\nnamespace benchmark {\n\nnamespace {\n\n// Compute the total size of a pack of std::strings\nsize_t size_impl() { return 0; }\n\ntemplate <typename Head, typename... Tail>\nsize_t size_impl(const Head& head, const Tail&... tail) {\n  return head.size() + size_impl(tail...);\n}\n\n// Join a pack of std::strings using a delimiter\n// TODO: use absl::StrJoin\nvoid join_impl(std::string&, char) {}\n\ntemplate <typename Head, typename... Tail>\nvoid join_impl(std::string& s, const char delimiter, const Head& head,\n               const Tail&... tail) {\n  if (!s.empty() && !head.empty()) {\n    s += delimiter;\n  }\n\n  s += head;\n\n  join_impl(s, delimiter, tail...);\n}\n\ntemplate <typename... Ts>\nstd::string join(char delimiter, const Ts&... ts) {\n  std::string s;\n  s.reserve(sizeof...(Ts) + size_impl(ts...));\n  join_impl(s, delimiter, ts...);\n  return s;\n}\n}  // namespace\n\nBENCHMARK_EXPORT\nstd::string BenchmarkName::str() const {\n  return join('/', function_name, args, min_time, min_warmup_time, iterations,\n              repetitions, time_type, threads);\n}\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_register.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark_register.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <cinttypes>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <memory>\n#include <numeric>\n#include <sstream>\n#include <thread>\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark_api_internal.h\"\n#include \"check.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nnamespace {\n// For non-dense Range, intermediate values are powers of kRangeMultiplier.\nstatic constexpr int kRangeMultiplier = 8;\n\n// The size of a benchmark family determines is the number of inputs to repeat\n// the benchmark on. If this is \"large\" then warn the user during configuration.\nstatic constexpr size_t kMaxFamilySize = 100;\n\nstatic constexpr char kDisabledPrefix[] = \"DISABLED_\";\n}  // end namespace\n\nnamespace internal {\n\n//=============================================================================//\n//                         BenchmarkFamilies\n//=============================================================================//\n\n// Class for managing registered benchmarks.  Note that each registered\n// benchmark identifies a family of related benchmarks to run.\nclass BenchmarkFamilies {\n public:\n  static BenchmarkFamilies* GetInstance();\n\n  // Registers a benchmark family and returns the index assigned to it.\n  size_t AddBenchmark(std::unique_ptr<Benchmark> family);\n\n  // Clear all registered benchmark families.\n  void ClearBenchmarks();\n\n  // Extract the list of benchmark instances that match the specified\n  // regular expression.\n  bool FindBenchmarks(std::string re,\n                      std::vector<BenchmarkInstance>* benchmarks,\n                      std::ostream* Err);\n\n private:\n  BenchmarkFamilies() {}\n\n  std::vector<std::unique_ptr<Benchmark>> families_;\n  Mutex mutex_;\n};\n\nBenchmarkFamilies* BenchmarkFamilies::GetInstance() {\n  static BenchmarkFamilies instance;\n  return &instance;\n}\n\nsize_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {\n  MutexLock l(mutex_);\n  size_t index = families_.size();\n  families_.push_back(std::move(family));\n  return index;\n}\n\nvoid BenchmarkFamilies::ClearBenchmarks() {\n  MutexLock l(mutex_);\n  families_.clear();\n  families_.shrink_to_fit();\n}\n\nbool BenchmarkFamilies::FindBenchmarks(\n    std::string spec, std::vector<BenchmarkInstance>* benchmarks,\n    std::ostream* ErrStream) {\n  BM_CHECK(ErrStream);\n  auto& Err = *ErrStream;\n  // Make regular expression out of command-line flag\n  std::string error_msg;\n  Regex re;\n  bool is_negative_filter = false;\n  if (spec[0] == '-') {\n    spec.replace(0, 1, \"\");\n    is_negative_filter = true;\n  }\n  if (!re.Init(spec, &error_msg)) {\n    Err << \"Could not compile benchmark re: \" << error_msg << std::endl;\n    return false;\n  }\n\n  // Special list of thread counts to use when none are specified\n  const std::vector<int> one_thread = {1};\n\n  int next_family_index = 0;\n\n  MutexLock l(mutex_);\n  for (std::unique_ptr<Benchmark>& family : families_) {\n    int family_index = next_family_index;\n    int per_family_instance_index = 0;\n\n    // Family was deleted or benchmark doesn't match\n    if (!family) continue;\n\n    if (family->ArgsCnt() == -1) {\n      family->Args({});\n    }\n    const std::vector<int>* thread_counts =\n        (family->thread_counts_.empty()\n             ? &one_thread\n             : &static_cast<const std::vector<int>&>(family->thread_counts_));\n    const size_t family_size = family->args_.size() * thread_counts->size();\n    // The benchmark will be run at least 'family_size' different inputs.\n    // If 'family_size' is very large warn the user.\n    if (family_size > kMaxFamilySize) {\n      Err << \"The number of inputs is very large. \" << family->name_\n          << \" will be repeated at least \" << family_size << \" times.\\n\";\n    }\n    // reserve in the special case the regex \".\", since we know the final\n    // family size.  this doesn't take into account any disabled benchmarks\n    // so worst case we reserve more than we need.\n    if (spec == \".\") benchmarks->reserve(benchmarks->size() + family_size);\n\n    for (auto const& args : family->args_) {\n      for (int num_threads : *thread_counts) {\n        BenchmarkInstance instance(family.get(), family_index,\n                                   per_family_instance_index, args,\n                                   num_threads);\n\n        const auto full_name = instance.name().str();\n        if (full_name.rfind(kDisabledPrefix, 0) != 0 &&\n            ((re.Match(full_name) && !is_negative_filter) ||\n             (!re.Match(full_name) && is_negative_filter))) {\n          benchmarks->push_back(std::move(instance));\n\n          ++per_family_instance_index;\n\n          // Only bump the next family index once we've estabilished that\n          // at least one instance of this family will be run.\n          if (next_family_index == family_index) ++next_family_index;\n        }\n      }\n    }\n  }\n  return true;\n}\n\nBenchmark* RegisterBenchmarkInternal(Benchmark* bench) {\n  std::unique_ptr<Benchmark> bench_ptr(bench);\n  BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();\n  families->AddBenchmark(std::move(bench_ptr));\n  return bench;\n}\n\n// FIXME: This function is a hack so that benchmark.cc can access\n// `BenchmarkFamilies`\nbool FindBenchmarksInternal(const std::string& re,\n                            std::vector<BenchmarkInstance>* benchmarks,\n                            std::ostream* Err) {\n  return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);\n}\n\n//=============================================================================//\n//                               Benchmark\n//=============================================================================//\n\nBenchmark::Benchmark(const std::string& name)\n    : name_(name),\n      aggregation_report_mode_(ARM_Unspecified),\n      time_unit_(GetDefaultTimeUnit()),\n      use_default_time_unit_(true),\n      range_multiplier_(kRangeMultiplier),\n      min_time_(0),\n      min_warmup_time_(0),\n      iterations_(0),\n      repetitions_(0),\n      measure_process_cpu_time_(false),\n      use_real_time_(false),\n      use_manual_time_(false),\n      complexity_(oNone),\n      complexity_lambda_(nullptr),\n      setup_(nullptr),\n      teardown_(nullptr) {\n  ComputeStatistics(\"mean\", StatisticsMean);\n  ComputeStatistics(\"median\", StatisticsMedian);\n  ComputeStatistics(\"stddev\", StatisticsStdDev);\n  ComputeStatistics(\"cv\", StatisticsCV, kPercentage);\n}\n\nBenchmark::~Benchmark() {}\n\nBenchmark* Benchmark::Name(const std::string& name) {\n  SetName(name);\n  return this;\n}\n\nBenchmark* Benchmark::Arg(int64_t x) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  args_.push_back({x});\n  return this;\n}\n\nBenchmark* Benchmark::Unit(TimeUnit unit) {\n  time_unit_ = unit;\n  use_default_time_unit_ = false;\n  return this;\n}\n\nBenchmark* Benchmark::Range(int64_t start, int64_t limit) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  std::vector<int64_t> arglist;\n  AddRange(&arglist, start, limit, range_multiplier_);\n\n  for (int64_t i : arglist) {\n    args_.push_back({i});\n  }\n  return this;\n}\n\nBenchmark* Benchmark::Ranges(\n    const std::vector<std::pair<int64_t, int64_t>>& ranges) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));\n  std::vector<std::vector<int64_t>> arglists(ranges.size());\n  for (std::size_t i = 0; i < ranges.size(); i++) {\n    AddRange(&arglists[i], ranges[i].first, ranges[i].second,\n             range_multiplier_);\n  }\n\n  ArgsProduct(arglists);\n\n  return this;\n}\n\nBenchmark* Benchmark::ArgsProduct(\n    const std::vector<std::vector<int64_t>>& arglists) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(arglists.size()));\n\n  std::vector<std::size_t> indices(arglists.size());\n  const std::size_t total = std::accumulate(\n      std::begin(arglists), std::end(arglists), std::size_t{1},\n      [](const std::size_t res, const std::vector<int64_t>& arglist) {\n        return res * arglist.size();\n      });\n  std::vector<int64_t> args;\n  args.reserve(arglists.size());\n  for (std::size_t i = 0; i < total; i++) {\n    for (std::size_t arg = 0; arg < arglists.size(); arg++) {\n      args.push_back(arglists[arg][indices[arg]]);\n    }\n    args_.push_back(args);\n    args.clear();\n\n    std::size_t arg = 0;\n    do {\n      indices[arg] = (indices[arg] + 1) % arglists[arg].size();\n    } while (indices[arg++] == 0 && arg < arglists.size());\n  }\n\n  return this;\n}\n\nBenchmark* Benchmark::ArgName(const std::string& name) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  arg_names_ = {name};\n  return this;\n}\n\nBenchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(names.size()));\n  arg_names_ = names;\n  return this;\n}\n\nBenchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  BM_CHECK_LE(start, limit);\n  for (int64_t arg = start; arg <= limit; arg += step) {\n    args_.push_back({arg});\n  }\n  return this;\n}\n\nBenchmark* Benchmark::Args(const std::vector<int64_t>& args) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(args.size()));\n  args_.push_back(args);\n  return this;\n}\n\nBenchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {\n  custom_arguments(this);\n  return this;\n}\n\nBenchmark* Benchmark::Setup(void (*setup)(const benchmark::State&)) {\n  BM_CHECK(setup != nullptr);\n  setup_ = setup;\n  return this;\n}\n\nBenchmark* Benchmark::Teardown(void (*teardown)(const benchmark::State&)) {\n  BM_CHECK(teardown != nullptr);\n  teardown_ = teardown;\n  return this;\n}\n\nBenchmark* Benchmark::RangeMultiplier(int multiplier) {\n  BM_CHECK(multiplier > 1);\n  range_multiplier_ = multiplier;\n  return this;\n}\n\nBenchmark* Benchmark::MinTime(double t) {\n  BM_CHECK(t > 0.0);\n  BM_CHECK(iterations_ == 0);\n  min_time_ = t;\n  return this;\n}\n\nBenchmark* Benchmark::MinWarmUpTime(double t) {\n  BM_CHECK(t >= 0.0);\n  BM_CHECK(iterations_ == 0);\n  min_warmup_time_ = t;\n  return this;\n}\n\nBenchmark* Benchmark::Iterations(IterationCount n) {\n  BM_CHECK(n > 0);\n  BM_CHECK(IsZero(min_time_));\n  BM_CHECK(IsZero(min_warmup_time_));\n  iterations_ = n;\n  return this;\n}\n\nBenchmark* Benchmark::Repetitions(int n) {\n  BM_CHECK(n > 0);\n  repetitions_ = n;\n  return this;\n}\n\nBenchmark* Benchmark::ReportAggregatesOnly(bool value) {\n  aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;\n  return this;\n}\n\nBenchmark* Benchmark::DisplayAggregatesOnly(bool value) {\n  // If we were called, the report mode is no longer 'unspecified', in any case.\n  aggregation_report_mode_ = static_cast<AggregationReportMode>(\n      aggregation_report_mode_ | ARM_Default);\n\n  if (value) {\n    aggregation_report_mode_ = static_cast<AggregationReportMode>(\n        aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);\n  } else {\n    aggregation_report_mode_ = static_cast<AggregationReportMode>(\n        aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);\n  }\n\n  return this;\n}\n\nBenchmark* Benchmark::MeasureProcessCPUTime() {\n  // Can be used together with UseRealTime() / UseManualTime().\n  measure_process_cpu_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::UseRealTime() {\n  BM_CHECK(!use_manual_time_)\n      << \"Cannot set UseRealTime and UseManualTime simultaneously.\";\n  use_real_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::UseManualTime() {\n  BM_CHECK(!use_real_time_)\n      << \"Cannot set UseRealTime and UseManualTime simultaneously.\";\n  use_manual_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::Complexity(BigO complexity) {\n  complexity_ = complexity;\n  return this;\n}\n\nBenchmark* Benchmark::Complexity(BigOFunc* complexity) {\n  complexity_lambda_ = complexity;\n  complexity_ = oLambda;\n  return this;\n}\n\nBenchmark* Benchmark::ComputeStatistics(const std::string& name,\n                                        StatisticsFunc* statistics,\n                                        StatisticUnit unit) {\n  statistics_.emplace_back(name, statistics, unit);\n  return this;\n}\n\nBenchmark* Benchmark::Threads(int t) {\n  BM_CHECK_GT(t, 0);\n  thread_counts_.push_back(t);\n  return this;\n}\n\nBenchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {\n  BM_CHECK_GT(min_threads, 0);\n  BM_CHECK_GE(max_threads, min_threads);\n\n  AddRange(&thread_counts_, min_threads, max_threads, 2);\n  return this;\n}\n\nBenchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads,\n                                       int stride) {\n  BM_CHECK_GT(min_threads, 0);\n  BM_CHECK_GE(max_threads, min_threads);\n  BM_CHECK_GE(stride, 1);\n\n  for (auto i = min_threads; i < max_threads; i += stride) {\n    thread_counts_.push_back(i);\n  }\n  thread_counts_.push_back(max_threads);\n  return this;\n}\n\nBenchmark* Benchmark::ThreadPerCpu() {\n  thread_counts_.push_back(CPUInfo::Get().num_cpus);\n  return this;\n}\n\nvoid Benchmark::SetName(const std::string& name) { name_ = name; }\n\nconst char* Benchmark::GetName() const { return name_.c_str(); }\n\nint Benchmark::ArgsCnt() const {\n  if (args_.empty()) {\n    if (arg_names_.empty()) return -1;\n    return static_cast<int>(arg_names_.size());\n  }\n  return static_cast<int>(args_.front().size());\n}\n\nconst char* Benchmark::GetArgName(int arg) const {\n  BM_CHECK_GE(arg, 0);\n  size_t uarg = static_cast<size_t>(arg);\n  BM_CHECK_LT(uarg, arg_names_.size());\n  return arg_names_[uarg].c_str();\n}\n\nTimeUnit Benchmark::GetTimeUnit() const {\n  return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;\n}\n\n//=============================================================================//\n//                            FunctionBenchmark\n//=============================================================================//\n\nvoid FunctionBenchmark::Run(State& st) { func_(st); }\n\n}  // end namespace internal\n\nvoid ClearRegisteredBenchmarks() {\n  internal::BenchmarkFamilies::GetInstance()->ClearBenchmarks();\n}\n\nstd::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi) {\n  std::vector<int64_t> args;\n  internal::AddRange(&args, lo, hi, multi);\n  return args;\n}\n\nstd::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step) {\n  BM_CHECK_LE(start, limit);\n  std::vector<int64_t> args;\n  for (int64_t arg = start; arg <= limit; arg += step) {\n    args.push_back(arg);\n  }\n  return args;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_register.h",
    "content": "#ifndef BENCHMARK_REGISTER_H\n#define BENCHMARK_REGISTER_H\n\n#include <algorithm>\n#include <limits>\n#include <vector>\n\n#include \"check.h\"\n\nnamespace benchmark {\nnamespace internal {\n\n// Append the powers of 'mult' in the closed interval [lo, hi].\n// Returns iterator to the start of the inserted range.\ntemplate <typename T>\ntypename std::vector<T>::iterator AddPowers(std::vector<T>* dst, T lo, T hi,\n                                            int mult) {\n  BM_CHECK_GE(lo, 0);\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_GE(mult, 2);\n\n  const size_t start_offset = dst->size();\n\n  static const T kmax = std::numeric_limits<T>::max();\n\n  // Space out the values in multiples of \"mult\"\n  for (T i = static_cast<T>(1); i <= hi; i = static_cast<T>(i * mult)) {\n    if (i >= lo) {\n      dst->push_back(i);\n    }\n    // Break the loop here since multiplying by\n    // 'mult' would move outside of the range of T\n    if (i > kmax / mult) break;\n  }\n\n  return dst->begin() + static_cast<int>(start_offset);\n}\n\ntemplate <typename T>\nvoid AddNegatedPowers(std::vector<T>* dst, T lo, T hi, int mult) {\n  // We negate lo and hi so we require that they cannot be equal to 'min'.\n  BM_CHECK_GT(lo, std::numeric_limits<T>::min());\n  BM_CHECK_GT(hi, std::numeric_limits<T>::min());\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_LE(hi, 0);\n\n  // Add positive powers, then negate and reverse.\n  // Casts necessary since small integers get promoted\n  // to 'int' when negating.\n  const auto lo_complement = static_cast<T>(-lo);\n  const auto hi_complement = static_cast<T>(-hi);\n\n  const auto it = AddPowers(dst, hi_complement, lo_complement, mult);\n\n  std::for_each(it, dst->end(), [](T& t) { t = static_cast<T>(t * -1); });\n  std::reverse(it, dst->end());\n}\n\ntemplate <typename T>\nvoid AddRange(std::vector<T>* dst, T lo, T hi, int mult) {\n  static_assert(std::is_integral<T>::value && std::is_signed<T>::value,\n                \"Args type must be a signed integer\");\n\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_GE(mult, 2);\n\n  // Add \"lo\"\n  dst->push_back(lo);\n\n  // Handle lo == hi as a special case, so we then know\n  // lo < hi and so it is safe to add 1 to lo and subtract 1\n  // from hi without falling outside of the range of T.\n  if (lo == hi) return;\n\n  // Ensure that lo_inner <= hi_inner below.\n  if (lo + 1 == hi) {\n    dst->push_back(hi);\n    return;\n  }\n\n  // Add all powers of 'mult' in the range [lo+1, hi-1] (inclusive).\n  const auto lo_inner = static_cast<T>(lo + 1);\n  const auto hi_inner = static_cast<T>(hi - 1);\n\n  // Insert negative values\n  if (lo_inner < 0) {\n    AddNegatedPowers(dst, lo_inner, std::min(hi_inner, T{-1}), mult);\n  }\n\n  // Treat 0 as a special case (see discussion on #762).\n  if (lo < 0 && hi >= 0) {\n    dst->push_back(0);\n  }\n\n  // Insert positive values\n  if (hi_inner > 0) {\n    AddPowers(dst, std::max(lo_inner, T{1}), hi_inner, mult);\n  }\n\n  // Add \"hi\" (if different from last value).\n  if (hi != dst->back()) {\n    dst->push_back(hi);\n  }\n}\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_REGISTER_H\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_runner.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark_runner.h\"\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark_api_internal.h\"\n#include \"internal_macros.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <climits>\n#include <cmath>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <fstream>\n#include <iostream>\n#include <limits>\n#include <memory>\n#include <string>\n#include <thread>\n#include <utility>\n\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"perf_counters.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"thread_manager.h\"\n#include \"thread_timer.h\"\n\nnamespace benchmark {\n\nnamespace internal {\n\nMemoryManager* memory_manager = nullptr;\n\nProfilerManager* profiler_manager = nullptr;\n\nnamespace {\n\nstatic constexpr IterationCount kMaxIterations = 1000000000000;\nconst double kDefaultMinTime =\n    std::strtod(::benchmark::kDefaultMinTimeStr, /*p_end*/ nullptr);\n\nBenchmarkReporter::Run CreateRunReport(\n    const benchmark::internal::BenchmarkInstance& b,\n    const internal::ThreadManager::Result& results,\n    IterationCount memory_iterations,\n    const MemoryManager::Result* memory_result, double seconds,\n    int64_t repetition_index, int64_t repeats) {\n  // Create report about this benchmark run.\n  BenchmarkReporter::Run report;\n\n  report.run_name = b.name();\n  report.family_index = b.family_index();\n  report.per_family_instance_index = b.per_family_instance_index();\n  report.skipped = results.skipped_;\n  report.skip_message = results.skip_message_;\n  report.report_label = results.report_label_;\n  // This is the total iterations across all threads.\n  report.iterations = results.iterations;\n  report.time_unit = b.time_unit();\n  report.threads = b.threads();\n  report.repetition_index = repetition_index;\n  report.repetitions = repeats;\n\n  if (!report.skipped) {\n    if (b.use_manual_time()) {\n      report.real_accumulated_time = results.manual_time_used;\n    } else {\n      report.real_accumulated_time = results.real_time_used;\n    }\n    report.use_real_time_for_initial_big_o = b.use_manual_time();\n    report.cpu_accumulated_time = results.cpu_time_used;\n    report.complexity_n = results.complexity_n;\n    report.complexity = b.complexity();\n    report.complexity_lambda = b.complexity_lambda();\n    report.statistics = &b.statistics();\n    report.counters = results.counters;\n\n    if (memory_iterations > 0) {\n      assert(memory_result != nullptr);\n      report.memory_result = memory_result;\n      report.allocs_per_iter =\n          memory_iterations ? static_cast<double>(memory_result->num_allocs) /\n                                  static_cast<double>(memory_iterations)\n                            : 0;\n    }\n\n    internal::Finish(&report.counters, results.iterations, seconds,\n                     b.threads());\n  }\n  return report;\n}\n\n// Execute one thread of benchmark b for the specified number of iterations.\n// Adds the stats collected for the thread into manager->results.\nvoid RunInThread(const BenchmarkInstance* b, IterationCount iters,\n                 int thread_id, ThreadManager* manager,\n                 PerfCountersMeasurement* perf_counters_measurement) {\n  internal::ThreadTimer timer(\n      b->measure_process_cpu_time()\n          ? internal::ThreadTimer::CreateProcessCpuTime()\n          : internal::ThreadTimer::Create());\n\n  State st =\n      b->Run(iters, thread_id, &timer, manager, perf_counters_measurement);\n  BM_CHECK(st.skipped() || st.iterations() >= st.max_iterations)\n      << \"Benchmark returned before State::KeepRunning() returned false!\";\n  {\n    MutexLock l(manager->GetBenchmarkMutex());\n    internal::ThreadManager::Result& results = manager->results;\n    results.iterations += st.iterations();\n    results.cpu_time_used += timer.cpu_time_used();\n    results.real_time_used += timer.real_time_used();\n    results.manual_time_used += timer.manual_time_used();\n    results.complexity_n += st.complexity_length_n();\n    internal::Increment(&results.counters, st.counters);\n  }\n  manager->NotifyThreadComplete();\n}\n\ndouble ComputeMinTime(const benchmark::internal::BenchmarkInstance& b,\n                      const BenchTimeType& iters_or_time) {\n  if (!IsZero(b.min_time())) return b.min_time();\n  // If the flag was used to specify number of iters, then return the default\n  // min_time.\n  if (iters_or_time.tag == BenchTimeType::ITERS) return kDefaultMinTime;\n\n  return iters_or_time.time;\n}\n\nIterationCount ComputeIters(const benchmark::internal::BenchmarkInstance& b,\n                            const BenchTimeType& iters_or_time) {\n  if (b.iterations() != 0) return b.iterations();\n\n  // We've already concluded that this flag is currently used to pass\n  // iters but do a check here again anyway.\n  BM_CHECK(iters_or_time.tag == BenchTimeType::ITERS);\n  return iters_or_time.iters;\n}\n\n}  // end namespace\n\nBenchTimeType ParseBenchMinTime(const std::string& value) {\n  BenchTimeType ret;\n\n  if (value.empty()) {\n    ret.tag = BenchTimeType::TIME;\n    ret.time = 0.0;\n    return ret;\n  }\n\n  if (value.back() == 'x') {\n    char* p_end;\n    // Reset errno before it's changed by strtol.\n    errno = 0;\n    IterationCount num_iters = std::strtol(value.c_str(), &p_end, 10);\n\n    // After a valid parse, p_end should have been set to\n    // point to the 'x' suffix.\n    BM_CHECK(errno == 0 && p_end != nullptr && *p_end == 'x')\n        << \"Malformed iters value passed to --benchmark_min_time: `\" << value\n        << \"`. Expected --benchmark_min_time=<integer>x.\";\n\n    ret.tag = BenchTimeType::ITERS;\n    ret.iters = num_iters;\n    return ret;\n  }\n\n  bool has_suffix = value.back() == 's';\n  if (!has_suffix) {\n    BM_VLOG(0) << \"Value passed to --benchmark_min_time should have a suffix. \"\n                  \"Eg., `30s` for 30-seconds.\";\n  }\n\n  char* p_end;\n  // Reset errno before it's changed by strtod.\n  errno = 0;\n  double min_time = std::strtod(value.c_str(), &p_end);\n\n  // After a successful parse, p_end should point to the suffix 's',\n  // or the end of the string if the suffix was omitted.\n  BM_CHECK(errno == 0 && p_end != nullptr &&\n           ((has_suffix && *p_end == 's') || *p_end == '\\0'))\n      << \"Malformed seconds value passed to --benchmark_min_time: `\" << value\n      << \"`. Expected --benchmark_min_time=<float>x.\";\n\n  ret.tag = BenchTimeType::TIME;\n  ret.time = min_time;\n\n  return ret;\n}\n\nBenchmarkRunner::BenchmarkRunner(\n    const benchmark::internal::BenchmarkInstance& b_,\n    PerfCountersMeasurement* pcm_,\n    BenchmarkReporter::PerFamilyRunReports* reports_for_family_)\n    : b(b_),\n      reports_for_family(reports_for_family_),\n      parsed_benchtime_flag(ParseBenchMinTime(FLAGS_benchmark_min_time)),\n      min_time(ComputeMinTime(b_, parsed_benchtime_flag)),\n      min_warmup_time((!IsZero(b.min_time()) && b.min_warmup_time() > 0.0)\n                          ? b.min_warmup_time()\n                          : FLAGS_benchmark_min_warmup_time),\n      warmup_done(!(min_warmup_time > 0.0)),\n      repeats(b.repetitions() != 0 ? b.repetitions()\n                                   : FLAGS_benchmark_repetitions),\n      has_explicit_iteration_count(b.iterations() != 0 ||\n                                   parsed_benchtime_flag.tag ==\n                                       BenchTimeType::ITERS),\n      pool(static_cast<size_t>(b.threads() - 1)),\n      iters(has_explicit_iteration_count\n                ? ComputeIters(b_, parsed_benchtime_flag)\n                : 1),\n      perf_counters_measurement_ptr(pcm_) {\n  run_results.display_report_aggregates_only =\n      (FLAGS_benchmark_report_aggregates_only ||\n       FLAGS_benchmark_display_aggregates_only);\n  run_results.file_report_aggregates_only =\n      FLAGS_benchmark_report_aggregates_only;\n  if (b.aggregation_report_mode() != internal::ARM_Unspecified) {\n    run_results.display_report_aggregates_only =\n        (b.aggregation_report_mode() &\n         internal::ARM_DisplayReportAggregatesOnly);\n    run_results.file_report_aggregates_only =\n        (b.aggregation_report_mode() & internal::ARM_FileReportAggregatesOnly);\n    BM_CHECK(FLAGS_benchmark_perf_counters.empty() ||\n             (perf_counters_measurement_ptr->num_counters() == 0))\n        << \"Perf counters were requested but could not be set up.\";\n  }\n}\n\nBenchmarkRunner::IterationResults BenchmarkRunner::DoNIterations() {\n  BM_VLOG(2) << \"Running \" << b.name().str() << \" for \" << iters << \"\\n\";\n\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(b.threads()));\n\n  // Run all but one thread in separate threads\n  for (std::size_t ti = 0; ti < pool.size(); ++ti) {\n    pool[ti] = std::thread(&RunInThread, &b, iters, static_cast<int>(ti + 1),\n                           manager.get(), perf_counters_measurement_ptr);\n  }\n  // And run one thread here directly.\n  // (If we were asked to run just one thread, we don't create new threads.)\n  // Yes, we need to do this here *after* we start the separate threads.\n  RunInThread(&b, iters, 0, manager.get(), perf_counters_measurement_ptr);\n\n  // The main thread has finished. Now let's wait for the other threads.\n  manager->WaitForAllThreads();\n  for (std::thread& thread : pool) thread.join();\n\n  IterationResults i;\n  // Acquire the measurements/counters from the manager, UNDER THE LOCK!\n  {\n    MutexLock l(manager->GetBenchmarkMutex());\n    i.results = manager->results;\n  }\n\n  // And get rid of the manager.\n  manager.reset();\n\n  // Adjust real/manual time stats since they were reported per thread.\n  i.results.real_time_used /= b.threads();\n  i.results.manual_time_used /= b.threads();\n  // If we were measuring whole-process CPU usage, adjust the CPU time too.\n  if (b.measure_process_cpu_time()) i.results.cpu_time_used /= b.threads();\n\n  BM_VLOG(2) << \"Ran in \" << i.results.cpu_time_used << \"/\"\n             << i.results.real_time_used << \"\\n\";\n\n  // By using KeepRunningBatch a benchmark can iterate more times than\n  // requested, so take the iteration count from i.results.\n  i.iters = i.results.iterations / b.threads();\n\n  // Base decisions off of real time if requested by this benchmark.\n  i.seconds = i.results.cpu_time_used;\n  if (b.use_manual_time()) {\n    i.seconds = i.results.manual_time_used;\n  } else if (b.use_real_time()) {\n    i.seconds = i.results.real_time_used;\n  }\n\n  return i;\n}\n\nIterationCount BenchmarkRunner::PredictNumItersNeeded(\n    const IterationResults& i) const {\n  // See how much iterations should be increased by.\n  // Note: Avoid division by zero with max(seconds, 1ns).\n  double multiplier = GetMinTimeToApply() * 1.4 / std::max(i.seconds, 1e-9);\n  // If our last run was at least 10% of FLAGS_benchmark_min_time then we\n  // use the multiplier directly.\n  // Otherwise we use at most 10 times expansion.\n  // NOTE: When the last run was at least 10% of the min time the max\n  // expansion should be 14x.\n  const bool is_significant = (i.seconds / GetMinTimeToApply()) > 0.1;\n  multiplier = is_significant ? multiplier : 10.0;\n\n  // So what seems to be the sufficiently-large iteration count? Round up.\n  const IterationCount max_next_iters = static_cast<IterationCount>(\n      std::llround(std::max(multiplier * static_cast<double>(i.iters),\n                            static_cast<double>(i.iters) + 1.0)));\n  // But we do have *some* limits though..\n  const IterationCount next_iters = std::min(max_next_iters, kMaxIterations);\n\n  BM_VLOG(3) << \"Next iters: \" << next_iters << \", \" << multiplier << \"\\n\";\n  return next_iters;  // round up before conversion to integer.\n}\n\nbool BenchmarkRunner::ShouldReportIterationResults(\n    const IterationResults& i) const {\n  // Determine if this run should be reported;\n  // Either it has run for a sufficient amount of time\n  // or because an error was reported.\n  return i.results.skipped_ ||\n         i.iters >= kMaxIterations ||  // Too many iterations already.\n         i.seconds >=\n             GetMinTimeToApply() ||  // The elapsed time is large enough.\n         // CPU time is specified but the elapsed real time greatly exceeds\n         // the minimum time.\n         // Note that user provided timers are except from this test.\n         ((i.results.real_time_used >= 5 * GetMinTimeToApply()) &&\n          !b.use_manual_time());\n}\n\ndouble BenchmarkRunner::GetMinTimeToApply() const {\n  // In order to re-use functionality to run and measure benchmarks for running\n  // a warmup phase of the benchmark, we need a way of telling whether to apply\n  // min_time or min_warmup_time. This function will figure out if we are in the\n  // warmup phase and therefore need to apply min_warmup_time or if we already\n  // in the benchmarking phase and min_time needs to be applied.\n  return warmup_done ? min_time : min_warmup_time;\n}\n\nvoid BenchmarkRunner::FinishWarmUp(const IterationCount& i) {\n  warmup_done = true;\n  iters = i;\n}\n\nvoid BenchmarkRunner::RunWarmUp() {\n  // Use the same mechanisms for warming up the benchmark as used for actually\n  // running and measuring the benchmark.\n  IterationResults i_warmup;\n  // Dont use the iterations determined in the warmup phase for the actual\n  // measured benchmark phase. While this may be a good starting point for the\n  // benchmark and it would therefore get rid of the need to figure out how many\n  // iterations are needed if min_time is set again, this may also be a complete\n  // wrong guess since the warmup loops might be considerably slower (e.g\n  // because of caching effects).\n  const IterationCount i_backup = iters;\n\n  for (;;) {\n    b.Setup();\n    i_warmup = DoNIterations();\n    b.Teardown();\n\n    const bool finish = ShouldReportIterationResults(i_warmup);\n\n    if (finish) {\n      FinishWarmUp(i_backup);\n      break;\n    }\n\n    // Although we are running \"only\" a warmup phase where running enough\n    // iterations at once without measuring time isn't as important as it is for\n    // the benchmarking phase, we still do it the same way as otherwise it is\n    // very confusing for the user to know how to choose a proper value for\n    // min_warmup_time if a different approach on running it is used.\n    iters = PredictNumItersNeeded(i_warmup);\n    assert(iters > i_warmup.iters &&\n           \"if we did more iterations than we want to do the next time, \"\n           \"then we should have accepted the current iteration run.\");\n  }\n}\n\nMemoryManager::Result* BenchmarkRunner::RunMemoryManager(\n    IterationCount memory_iterations) {\n  // TODO(vyng): Consider making BenchmarkReporter::Run::memory_result an\n  // optional so we don't have to own the Result here.\n  // Can't do it now due to cxx03.\n  memory_results.push_back(MemoryManager::Result());\n  MemoryManager::Result* memory_result = &memory_results.back();\n  memory_manager->Start();\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(1));\n  b.Setup();\n  RunInThread(&b, memory_iterations, 0, manager.get(),\n              perf_counters_measurement_ptr);\n  manager->WaitForAllThreads();\n  manager.reset();\n  b.Teardown();\n  memory_manager->Stop(*memory_result);\n  return memory_result;\n}\n\nvoid BenchmarkRunner::RunProfilerManager() {\n  // TODO: Provide a way to specify the number of iterations.\n  IterationCount profile_iterations = 1;\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(1));\n  b.Setup();\n  profiler_manager->AfterSetupStart();\n  RunInThread(&b, profile_iterations, 0, manager.get(),\n              /*perf_counters_measurement_ptr=*/nullptr);\n  manager->WaitForAllThreads();\n  profiler_manager->BeforeTeardownStop();\n  manager.reset();\n  b.Teardown();\n}\n\nvoid BenchmarkRunner::DoOneRepetition() {\n  assert(HasRepeatsRemaining() && \"Already done all repetitions?\");\n\n  const bool is_the_first_repetition = num_repetitions_done == 0;\n\n  // In case a warmup phase is requested by the benchmark, run it now.\n  // After running the warmup phase the BenchmarkRunner should be in a state as\n  // this warmup never happened except the fact that warmup_done is set. Every\n  // other manipulation of the BenchmarkRunner instance would be a bug! Please\n  // fix it.\n  if (!warmup_done) RunWarmUp();\n\n  IterationResults i;\n  // We *may* be gradually increasing the length (iteration count)\n  // of the benchmark until we decide the results are significant.\n  // And once we do, we report those last results and exit.\n  // Please do note that the if there are repetitions, the iteration count\n  // is *only* calculated for the *first* repetition, and other repetitions\n  // simply use that precomputed iteration count.\n  for (;;) {\n    b.Setup();\n    i = DoNIterations();\n    b.Teardown();\n\n    // Do we consider the results to be significant?\n    // If we are doing repetitions, and the first repetition was already done,\n    // it has calculated the correct iteration time, so we have run that very\n    // iteration count just now. No need to calculate anything. Just report.\n    // Else, the normal rules apply.\n    const bool results_are_significant = !is_the_first_repetition ||\n                                         has_explicit_iteration_count ||\n                                         ShouldReportIterationResults(i);\n\n    if (results_are_significant) break;  // Good, let's report them!\n\n    // Nope, bad iteration. Let's re-estimate the hopefully-sufficient\n    // iteration count, and run the benchmark again...\n\n    iters = PredictNumItersNeeded(i);\n    assert(iters > i.iters &&\n           \"if we did more iterations than we want to do the next time, \"\n           \"then we should have accepted the current iteration run.\");\n  }\n\n  // Produce memory measurements if requested.\n  MemoryManager::Result* memory_result = nullptr;\n  IterationCount memory_iterations = 0;\n  if (memory_manager != nullptr) {\n    // Only run a few iterations to reduce the impact of one-time\n    // allocations in benchmarks that are not properly managed.\n    memory_iterations = std::min<IterationCount>(16, iters);\n    memory_result = RunMemoryManager(memory_iterations);\n  }\n\n  if (profiler_manager != nullptr) {\n    RunProfilerManager();\n  }\n\n  // Ok, now actually report.\n  BenchmarkReporter::Run report =\n      CreateRunReport(b, i.results, memory_iterations, memory_result, i.seconds,\n                      num_repetitions_done, repeats);\n\n  if (reports_for_family) {\n    ++reports_for_family->num_runs_done;\n    if (!report.skipped) reports_for_family->Runs.push_back(report);\n  }\n\n  run_results.non_aggregates.push_back(report);\n\n  ++num_repetitions_done;\n}\n\nRunResults&& BenchmarkRunner::GetResults() {\n  assert(!HasRepeatsRemaining() && \"Did not run all repetitions yet?\");\n\n  // Calculate additional statistics over the repetitions of this instance.\n  run_results.aggregates_only = ComputeStats(run_results.non_aggregates);\n\n  return std::move(run_results);\n}\n\n}  // end namespace internal\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/benchmark_runner.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_RUNNER_H_\n#define BENCHMARK_RUNNER_H_\n\n#include <thread>\n#include <vector>\n\n#include \"benchmark_api_internal.h\"\n#include \"internal_macros.h\"\n#include \"perf_counters.h\"\n#include \"thread_manager.h\"\n\nnamespace benchmark {\n\nBM_DECLARE_string(benchmark_min_time);\nBM_DECLARE_double(benchmark_min_warmup_time);\nBM_DECLARE_int32(benchmark_repetitions);\nBM_DECLARE_bool(benchmark_report_aggregates_only);\nBM_DECLARE_bool(benchmark_display_aggregates_only);\nBM_DECLARE_string(benchmark_perf_counters);\n\nnamespace internal {\n\nextern MemoryManager* memory_manager;\nextern ProfilerManager* profiler_manager;\n\nstruct RunResults {\n  std::vector<BenchmarkReporter::Run> non_aggregates;\n  std::vector<BenchmarkReporter::Run> aggregates_only;\n\n  bool display_report_aggregates_only = false;\n  bool file_report_aggregates_only = false;\n};\n\nstruct BENCHMARK_EXPORT BenchTimeType {\n  enum { ITERS, TIME } tag;\n  union {\n    IterationCount iters;\n    double time;\n  };\n};\n\nBENCHMARK_EXPORT\nBenchTimeType ParseBenchMinTime(const std::string& value);\n\nclass BenchmarkRunner {\n public:\n  BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_,\n                  benchmark::internal::PerfCountersMeasurement* pmc_,\n                  BenchmarkReporter::PerFamilyRunReports* reports_for_family);\n\n  int GetNumRepeats() const { return repeats; }\n\n  bool HasRepeatsRemaining() const {\n    return GetNumRepeats() != num_repetitions_done;\n  }\n\n  void DoOneRepetition();\n\n  RunResults&& GetResults();\n\n  BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const {\n    return reports_for_family;\n  }\n\n  double GetMinTime() const { return min_time; }\n\n  bool HasExplicitIters() const { return has_explicit_iteration_count; }\n\n  IterationCount GetIters() const { return iters; }\n\n private:\n  RunResults run_results;\n\n  const benchmark::internal::BenchmarkInstance& b;\n  BenchmarkReporter::PerFamilyRunReports* reports_for_family;\n\n  BenchTimeType parsed_benchtime_flag;\n  const double min_time;\n  const double min_warmup_time;\n  bool warmup_done;\n  const int repeats;\n  const bool has_explicit_iteration_count;\n\n  int num_repetitions_done = 0;\n\n  std::vector<std::thread> pool;\n\n  std::vector<MemoryManager::Result> memory_results;\n\n  IterationCount iters;  // preserved between repetitions!\n  // So only the first repetition has to find/calculate it,\n  // the other repetitions will just use that precomputed iteration count.\n\n  PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr;\n\n  struct IterationResults {\n    internal::ThreadManager::Result results;\n    IterationCount iters;\n    double seconds;\n  };\n  IterationResults DoNIterations();\n\n  MemoryManager::Result* RunMemoryManager(IterationCount memory_iterations);\n\n  void RunProfilerManager();\n\n  IterationCount PredictNumItersNeeded(const IterationResults& i) const;\n\n  bool ShouldReportIterationResults(const IterationResults& i) const;\n\n  double GetMinTimeToApply() const;\n\n  void FinishWarmUp(const IterationCount& i);\n\n  void RunWarmUp();\n};\n\n}  // namespace internal\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_RUNNER_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/check.cc",
    "content": "#include \"check.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nstatic AbortHandlerT* handler = &std::abort;\n\nBENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; }\n\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/check.h",
    "content": "#ifndef CHECK_H_\n#define CHECK_H_\n\n#include <cmath>\n#include <cstdlib>\n#include <ostream>\n\n#include \"benchmark/export.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n\n#if defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_NOEXCEPT noexcept\n#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)\n#elif defined(_MSC_VER) && !defined(__clang__)\n#if _MSC_VER >= 1900\n#define BENCHMARK_NOEXCEPT noexcept\n#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)\n#else\n#define BENCHMARK_NOEXCEPT\n#define BENCHMARK_NOEXCEPT_OP(x)\n#endif\n#define __func__ __FUNCTION__\n#else\n#define BENCHMARK_NOEXCEPT\n#define BENCHMARK_NOEXCEPT_OP(x)\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\ntypedef void(AbortHandlerT)();\n\nBENCHMARK_EXPORT\nAbortHandlerT*& GetAbortHandler();\n\nBENCHMARK_NORETURN inline void CallAbortHandler() {\n  GetAbortHandler()();\n  std::abort();  // fallback to enforce noreturn\n}\n\n// CheckHandler is the class constructed by failing BM_CHECK macros.\n// CheckHandler will log information about the failures and abort when it is\n// destructed.\nclass CheckHandler {\n public:\n  CheckHandler(const char* check, const char* file, const char* func, int line)\n      : log_(GetErrorLogInstance()) {\n    log_ << file << \":\" << line << \": \" << func << \": Check `\" << check\n         << \"' failed. \";\n  }\n\n  LogType& GetLog() { return log_; }\n\n#if defined(COMPILER_MSVC)\n#pragma warning(push)\n#pragma warning(disable : 4722)\n#endif\n  BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {\n    log_ << std::endl;\n    CallAbortHandler();\n  }\n#if defined(COMPILER_MSVC)\n#pragma warning(pop)\n#endif\n\n  CheckHandler& operator=(const CheckHandler&) = delete;\n  CheckHandler(const CheckHandler&) = delete;\n  CheckHandler() = delete;\n\n private:\n  LogType& log_;\n};\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n// The BM_CHECK macro returns a std::ostream object that can have extra\n// information written to it.\n#ifndef NDEBUG\n#define BM_CHECK(b)                                                          \\\n  (b ? ::benchmark::internal::GetNullLogInstance()                           \\\n     : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \\\n           .GetLog())\n#else\n#define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()\n#endif\n\n// clang-format off\n// preserve whitespacing between operators for alignment\n#define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))\n#define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))\n#define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))\n#define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))\n#define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))\n#define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))\n\n#define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) <  (eps))\n#define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))\n#define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))\n#define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))\n#define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) >  (eps))\n#define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) >  (eps))\n//clang-format on\n\n#endif  // CHECK_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/colorprint.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"colorprint.h\"\n\n#include <cstdarg>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <memory>\n#include <string>\n\n#include \"check.h\"\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#include <io.h>\n#include <windows.h>\n#else\n#include <unistd.h>\n#endif  // BENCHMARK_OS_WINDOWS\n\nnamespace benchmark {\nnamespace {\n#ifdef BENCHMARK_OS_WINDOWS\ntypedef WORD PlatformColorCode;\n#else\ntypedef const char* PlatformColorCode;\n#endif\n\nPlatformColorCode GetPlatformColorCode(LogColor color) {\n#ifdef BENCHMARK_OS_WINDOWS\n  switch (color) {\n    case COLOR_RED:\n      return FOREGROUND_RED;\n    case COLOR_GREEN:\n      return FOREGROUND_GREEN;\n    case COLOR_YELLOW:\n      return FOREGROUND_RED | FOREGROUND_GREEN;\n    case COLOR_BLUE:\n      return FOREGROUND_BLUE;\n    case COLOR_MAGENTA:\n      return FOREGROUND_BLUE | FOREGROUND_RED;\n    case COLOR_CYAN:\n      return FOREGROUND_BLUE | FOREGROUND_GREEN;\n    case COLOR_WHITE:  // fall through to default\n    default:\n      return 0;\n  }\n#else\n  switch (color) {\n    case COLOR_RED:\n      return \"1\";\n    case COLOR_GREEN:\n      return \"2\";\n    case COLOR_YELLOW:\n      return \"3\";\n    case COLOR_BLUE:\n      return \"4\";\n    case COLOR_MAGENTA:\n      return \"5\";\n    case COLOR_CYAN:\n      return \"6\";\n    case COLOR_WHITE:\n      return \"7\";\n    default:\n      return nullptr;\n  };\n#endif\n}\n\n}  // end namespace\n\nstd::string FormatString(const char* msg, va_list args) {\n  // we might need a second shot at this, so pre-emptivly make a copy\n  va_list args_cp;\n  va_copy(args_cp, args);\n\n  std::size_t size = 256;\n  char local_buff[256];\n  auto ret = vsnprintf(local_buff, size, msg, args_cp);\n\n  va_end(args_cp);\n\n  // currently there is no error handling for failure, so this is hack.\n  BM_CHECK(ret >= 0);\n\n  if (ret == 0) {  // handle empty expansion\n    return {};\n  }\n  if (static_cast<size_t>(ret) < size) {\n    return local_buff;\n  }\n  // we did not provide a long enough buffer on our first attempt.\n  size = static_cast<size_t>(ret) + 1;  // + 1 for the null byte\n  std::unique_ptr<char[]> buff(new char[size]);\n  ret = vsnprintf(buff.get(), size, msg, args);\n  BM_CHECK(ret > 0 && (static_cast<size_t>(ret)) < size);\n  return buff.get();\n}\n\nstd::string FormatString(const char* msg, ...) {\n  va_list args;\n  va_start(args, msg);\n  auto tmp = FormatString(msg, args);\n  va_end(args);\n  return tmp;\n}\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  ColorPrintf(out, color, fmt, args);\n  va_end(args);\n}\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt,\n                 va_list args) {\n#ifdef BENCHMARK_OS_WINDOWS\n  ((void)out);  // suppress unused warning\n\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\n\n  // Gets the current text color.\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\n  const WORD old_color_attrs = buffer_info.wAttributes;\n\n  // We need to flush the stream buffers into the console before each\n  // SetConsoleTextAttribute call lest it affect the text that is already\n  // printed but has not yet reached the console.\n  out.flush();\n  SetConsoleTextAttribute(stdout_handle,\n                          GetPlatformColorCode(color) | FOREGROUND_INTENSITY);\n  out << FormatString(fmt, args);\n\n  out.flush();\n  // Restores the text color.\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\n#else\n  const char* color_code = GetPlatformColorCode(color);\n  if (color_code) out << FormatString(\"\\033[0;3%sm\", color_code);\n  out << FormatString(fmt, args) << \"\\033[m\";\n#endif\n}\n\nbool IsColorTerminal() {\n#if BENCHMARK_OS_WINDOWS\n  // On Windows the TERM variable is usually not set, but the\n  // console there does support colors.\n  return 0 != _isatty(_fileno(stdout));\n#else\n  // On non-Windows platforms, we rely on the TERM variable. This list of\n  // supported TERM values is copied from Google Test:\n  // <https://github.com/google/googletest/blob/v1.13.0/googletest/src/gtest.cc#L3225-L3259>.\n  const char* const SUPPORTED_TERM_VALUES[] = {\n      \"xterm\",\n      \"xterm-color\",\n      \"xterm-256color\",\n      \"screen\",\n      \"screen-256color\",\n      \"tmux\",\n      \"tmux-256color\",\n      \"rxvt-unicode\",\n      \"rxvt-unicode-256color\",\n      \"linux\",\n      \"cygwin\",\n      \"xterm-kitty\",\n      \"alacritty\",\n      \"foot\",\n      \"foot-extra\",\n      \"wezterm\",\n  };\n\n  const char* const term = getenv(\"TERM\");\n\n  bool term_supports_color = false;\n  for (const char* candidate : SUPPORTED_TERM_VALUES) {\n    if (term && 0 == strcmp(term, candidate)) {\n      term_supports_color = true;\n      break;\n    }\n  }\n\n  return 0 != isatty(fileno(stdout)) && term_supports_color;\n#endif  // BENCHMARK_OS_WINDOWS\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/colorprint.h",
    "content": "#ifndef BENCHMARK_COLORPRINT_H_\n#define BENCHMARK_COLORPRINT_H_\n\n#include <cstdarg>\n#include <iostream>\n#include <string>\n\nnamespace benchmark {\nenum LogColor {\n  COLOR_DEFAULT,\n  COLOR_RED,\n  COLOR_GREEN,\n  COLOR_YELLOW,\n  COLOR_BLUE,\n  COLOR_MAGENTA,\n  COLOR_CYAN,\n  COLOR_WHITE\n};\n\nstd::string FormatString(const char* msg, va_list args);\nstd::string FormatString(const char* msg, ...);\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt,\n                 va_list args);\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);\n\n// Returns true if stdout appears to be a terminal that supports colored\n// output, false otherwise.\nbool IsColorTerminal();\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COLORPRINT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/commandlineflags.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"commandlineflags.h\"\n\n#include <algorithm>\n#include <cctype>\n#include <cstdlib>\n#include <cstring>\n#include <iostream>\n#include <limits>\n#include <map>\n#include <utility>\n\n#include \"../src/string_util.h\"\n\nnamespace benchmark {\nnamespace {\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\n// the result to *value and returns true; otherwise leaves *value\n// unchanged and returns false.\nbool ParseInt32(const std::string& src_text, const char* str, int32_t* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const long long_value = strtol(str, &end, 10);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    std::cerr << src_text << \" is expected to be a 32-bit integer, \"\n              << \"but actually has value \\\"\" << str << \"\\\".\\n\";\n    return false;\n  }\n\n  // Is the parsed value in the range of an Int32?\n  const int32_t result = static_cast<int32_t>(long_value);\n  if (long_value == std::numeric_limits<long>::max() ||\n      long_value == std::numeric_limits<long>::min() ||\n      // The parsed value overflows as a long.  (strtol() returns\n      // LONG_MAX or LONG_MIN when the input overflows.)\n      result != long_value\n      // The parsed value overflows as an Int32.\n  ) {\n    std::cerr << src_text << \" is expected to be a 32-bit integer, \"\n              << \"but actually has value \\\"\" << str << \"\\\", \"\n              << \"which overflows.\\n\";\n    return false;\n  }\n\n  *value = result;\n  return true;\n}\n\n// Parses 'str' for a double.  If successful, writes the result to *value and\n// returns true; otherwise leaves *value unchanged and returns false.\nbool ParseDouble(const std::string& src_text, const char* str, double* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const double double_value = strtod(str, &end);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    std::cerr << src_text << \" is expected to be a double, \"\n              << \"but actually has value \\\"\" << str << \"\\\".\\n\";\n    return false;\n  }\n\n  *value = double_value;\n  return true;\n}\n\n// Parses 'str' into KV pairs. If successful, writes the result to *value and\n// returns true; otherwise leaves *value unchanged and returns false.\nbool ParseKvPairs(const std::string& src_text, const char* str,\n                  std::map<std::string, std::string>* value) {\n  std::map<std::string, std::string> kvs;\n  for (const auto& kvpair : StrSplit(str, ',')) {\n    const auto kv = StrSplit(kvpair, '=');\n    if (kv.size() != 2) {\n      std::cerr << src_text << \" is expected to be a comma-separated list of \"\n                << \"<key>=<value> strings, but actually has value \\\"\" << str\n                << \"\\\".\\n\";\n      return false;\n    }\n    if (!kvs.emplace(kv[0], kv[1]).second) {\n      std::cerr << src_text << \" is expected to contain unique keys but key \\\"\"\n                << kv[0] << \"\\\" was repeated.\\n\";\n      return false;\n    }\n  }\n\n  *value = kvs;\n  return true;\n}\n\n// Returns the name of the environment variable corresponding to the\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\n// \"BENCHMARK_FOO\" in the open-source version.\nstatic std::string FlagToEnvVar(const char* flag) {\n  const std::string flag_str(flag);\n\n  std::string env_var;\n  for (size_t i = 0; i != flag_str.length(); ++i)\n    env_var += static_cast<char>(::toupper(flag_str.c_str()[i]));\n\n  return env_var;\n}\n\n}  // namespace\n\nBENCHMARK_EXPORT\nbool BoolFromEnv(const char* flag, bool default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  return value_str == nullptr ? default_val : IsTruthyFlagValue(value_str);\n}\n\nBENCHMARK_EXPORT\nint32_t Int32FromEnv(const char* flag, int32_t default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  int32_t value = default_val;\n  if (value_str == nullptr ||\n      !ParseInt32(std::string(\"Environment variable \") + env_var, value_str,\n                  &value)) {\n    return default_val;\n  }\n  return value;\n}\n\nBENCHMARK_EXPORT\ndouble DoubleFromEnv(const char* flag, double default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  double value = default_val;\n  if (value_str == nullptr ||\n      !ParseDouble(std::string(\"Environment variable \") + env_var, value_str,\n                   &value)) {\n    return default_val;\n  }\n  return value;\n}\n\nBENCHMARK_EXPORT\nconst char* StringFromEnv(const char* flag, const char* default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value = getenv(env_var.c_str());\n  return value == nullptr ? default_val : value;\n}\n\nBENCHMARK_EXPORT\nstd::map<std::string, std::string> KvPairsFromEnv(\n    const char* flag, std::map<std::string, std::string> default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n\n  if (value_str == nullptr) return default_val;\n\n  std::map<std::string, std::string> value;\n  if (!ParseKvPairs(\"Environment variable \" + env_var, value_str, &value)) {\n    return default_val;\n  }\n  return value;\n}\n\n// Parses a string as a command line flag.  The string should have\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\n// part can be omitted.\n//\n// Returns the value of the flag, or nullptr if the parsing failed.\nconst char* ParseFlagValue(const char* str, const char* flag,\n                           bool def_optional) {\n  // str and flag must not be nullptr.\n  if (str == nullptr || flag == nullptr) return nullptr;\n\n  // The flag must start with \"--\".\n  const std::string flag_str = std::string(\"--\") + std::string(flag);\n  const size_t flag_len = flag_str.length();\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) return flag_end;\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\nBENCHMARK_EXPORT\nbool ParseBoolFlag(const char* str, const char* flag, bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = IsTruthyFlagValue(value_str);\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(std::string(\"The value of flag --\") + flag, value_str,\n                    value);\n}\n\nBENCHMARK_EXPORT\nbool ParseDoubleFlag(const char* str, const char* flag, double* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseDouble(std::string(\"The value of flag --\") + flag, value_str,\n                     value);\n}\n\nBENCHMARK_EXPORT\nbool ParseStringFlag(const char* str, const char* flag, std::string* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  *value = value_str;\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool ParseKeyValueFlag(const char* str, const char* flag,\n                       std::map<std::string, std::string>* value) {\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  if (value_str == nullptr) return false;\n\n  for (const auto& kvpair : StrSplit(value_str, ',')) {\n    const auto kv = StrSplit(kvpair, '=');\n    if (kv.size() != 2) return false;\n    value->emplace(kv[0], kv[1]);\n  }\n\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool IsFlag(const char* str, const char* flag) {\n  return (ParseFlagValue(str, flag, true) != nullptr);\n}\n\nBENCHMARK_EXPORT\nbool IsTruthyFlagValue(const std::string& value) {\n  if (value.size() == 1) {\n    char v = value[0];\n    return isalnum(v) &&\n           !(v == '0' || v == 'f' || v == 'F' || v == 'n' || v == 'N');\n  }\n  if (!value.empty()) {\n    std::string value_lower(value);\n    std::transform(value_lower.begin(), value_lower.end(), value_lower.begin(),\n                   [](char c) { return static_cast<char>(::tolower(c)); });\n    return !(value_lower == \"false\" || value_lower == \"no\" ||\n             value_lower == \"off\");\n  }\n  return true;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/commandlineflags.h",
    "content": "#ifndef BENCHMARK_COMMANDLINEFLAGS_H_\n#define BENCHMARK_COMMANDLINEFLAGS_H_\n\n#include <cstdint>\n#include <map>\n#include <string>\n\n#include \"benchmark/export.h\"\n\n// Macro for referencing flags.\n#define FLAG(name) FLAGS_##name\n\n// Macros for declaring flags.\n#define BM_DECLARE_bool(name) BENCHMARK_EXPORT extern bool FLAG(name)\n#define BM_DECLARE_int32(name) BENCHMARK_EXPORT extern int32_t FLAG(name)\n#define BM_DECLARE_double(name) BENCHMARK_EXPORT extern double FLAG(name)\n#define BM_DECLARE_string(name) BENCHMARK_EXPORT extern std::string FLAG(name)\n#define BM_DECLARE_kvpairs(name) \\\n  BENCHMARK_EXPORT extern std::map<std::string, std::string> FLAG(name)\n\n// Macros for defining flags.\n#define BM_DEFINE_bool(name, default_val) \\\n  BENCHMARK_EXPORT bool FLAG(name) = benchmark::BoolFromEnv(#name, default_val)\n#define BM_DEFINE_int32(name, default_val) \\\n  BENCHMARK_EXPORT int32_t FLAG(name) =    \\\n      benchmark::Int32FromEnv(#name, default_val)\n#define BM_DEFINE_double(name, default_val) \\\n  BENCHMARK_EXPORT double FLAG(name) =      \\\n      benchmark::DoubleFromEnv(#name, default_val)\n#define BM_DEFINE_string(name, default_val) \\\n  BENCHMARK_EXPORT std::string FLAG(name) = \\\n      benchmark::StringFromEnv(#name, default_val)\n#define BM_DEFINE_kvpairs(name, default_val)                       \\\n  BENCHMARK_EXPORT std::map<std::string, std::string> FLAG(name) = \\\n      benchmark::KvPairsFromEnv(#name, default_val)\n\nnamespace benchmark {\n\n// Parses a bool from the environment variable corresponding to the given flag.\n//\n// If the variable exists, returns IsTruthyFlagValue() value;  if not,\n// returns the given default value.\nBENCHMARK_EXPORT\nbool BoolFromEnv(const char* flag, bool default_val);\n\n// Parses an Int32 from the environment variable corresponding to the given\n// flag.\n//\n// If the variable exists, returns ParseInt32() value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nint32_t Int32FromEnv(const char* flag, int32_t default_val);\n\n// Parses an Double from the environment variable corresponding to the given\n// flag.\n//\n// If the variable exists, returns ParseDouble();  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\ndouble DoubleFromEnv(const char* flag, double default_val);\n\n// Parses a string from the environment variable corresponding to the given\n// flag.\n//\n// If variable exists, returns its value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nconst char* StringFromEnv(const char* flag, const char* default_val);\n\n// Parses a set of kvpairs from the environment variable corresponding to the\n// given flag.\n//\n// If variable exists, returns its value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nstd::map<std::string, std::string> KvPairsFromEnv(\n    const char* flag, std::map<std::string, std::string> default_val);\n\n// Parses a string for a bool flag, in the form of either\n// \"--flag=value\" or \"--flag\".\n//\n// In the former case, the value is taken as true if it passes IsTruthyValue().\n//\n// In the latter case, the value is taken as true.\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseBoolFlag(const char* str, const char* flag, bool* value);\n\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseInt32Flag(const char* str, const char* flag, int32_t* value);\n\n// Parses a string for a Double flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseDoubleFlag(const char* str, const char* flag, double* value);\n\n// Parses a string for a string flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseStringFlag(const char* str, const char* flag, std::string* value);\n\n// Parses a string for a kvpairs flag in the form \"--flag=key=value,key=value\"\n//\n// On success, stores the value of the flag in *value and returns true. On\n// failure returns false, though *value may have been mutated.\nBENCHMARK_EXPORT\nbool ParseKeyValueFlag(const char* str, const char* flag,\n                       std::map<std::string, std::string>* value);\n\n// Returns true if the string matches the flag.\nBENCHMARK_EXPORT\nbool IsFlag(const char* str, const char* flag);\n\n// Returns true unless value starts with one of: '0', 'f', 'F', 'n' or 'N', or\n// some non-alphanumeric character. Also returns false if the value matches\n// one of 'no', 'false', 'off' (case-insensitive). As a special case, also\n// returns true if value is the empty string.\nBENCHMARK_EXPORT\nbool IsTruthyFlagValue(const std::string& value);\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COMMANDLINEFLAGS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/complexity.cc",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Source project : https://github.com/ismaelJimenez/cpp.leastsq\n// Adapted to be used with google benchmark\n\n#include \"complexity.h\"\n\n#include <algorithm>\n#include <cmath>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n\nnamespace benchmark {\n\n// Internal function to calculate the different scalability forms\nBigOFunc* FittingCurve(BigO complexity) {\n  switch (complexity) {\n    case oN:\n      return [](IterationCount n) -> double { return static_cast<double>(n); };\n    case oNSquared:\n      return [](IterationCount n) -> double { return std::pow(n, 2); };\n    case oNCubed:\n      return [](IterationCount n) -> double { return std::pow(n, 3); };\n    case oLogN:\n      return [](IterationCount n) -> double {\n        return std::log2(static_cast<double>(n));\n      };\n    case oNLogN:\n      return [](IterationCount n) -> double {\n        return static_cast<double>(n) * std::log2(static_cast<double>(n));\n      };\n    case o1:\n    default:\n      return [](IterationCount) { return 1.0; };\n  }\n}\n\n// Function to return an string for the calculated complexity\nstd::string GetBigOString(BigO complexity) {\n  switch (complexity) {\n    case oN:\n      return \"N\";\n    case oNSquared:\n      return \"N^2\";\n    case oNCubed:\n      return \"N^3\";\n    case oLogN:\n      return \"lgN\";\n    case oNLogN:\n      return \"NlgN\";\n    case o1:\n      return \"(1)\";\n    default:\n      return \"f(N)\";\n  }\n}\n\n// Find the coefficient for the high-order term in the running time, by\n// minimizing the sum of squares of relative error, for the fitting curve\n// given by the lambda expression.\n//   - n             : Vector containing the size of the benchmark tests.\n//   - time          : Vector containing the times for the benchmark tests.\n//   - fitting_curve : lambda expression (e.g. [](ComplexityN n) {return n; };).\n\n// For a deeper explanation on the algorithm logic, please refer to\n// https://en.wikipedia.org/wiki/Least_squares#Least_squares,_regression_analysis_and_statistics\n\nLeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,\n                       const std::vector<double>& time,\n                       BigOFunc* fitting_curve) {\n  double sigma_gn_squared = 0.0;\n  double sigma_time = 0.0;\n  double sigma_time_gn = 0.0;\n\n  // Calculate least square fitting parameter\n  for (size_t i = 0; i < n.size(); ++i) {\n    double gn_i = fitting_curve(n[i]);\n    sigma_gn_squared += gn_i * gn_i;\n    sigma_time += time[i];\n    sigma_time_gn += time[i] * gn_i;\n  }\n\n  LeastSq result;\n  result.complexity = oLambda;\n\n  // Calculate complexity.\n  result.coef = sigma_time_gn / sigma_gn_squared;\n\n  // Calculate RMS\n  double rms = 0.0;\n  for (size_t i = 0; i < n.size(); ++i) {\n    double fit = result.coef * fitting_curve(n[i]);\n    rms += std::pow((time[i] - fit), 2);\n  }\n\n  // Normalized RMS by the mean of the observed values\n  double mean = sigma_time / static_cast<double>(n.size());\n  result.rms = std::sqrt(rms / static_cast<double>(n.size())) / mean;\n\n  return result;\n}\n\n// Find the coefficient for the high-order term in the running time, by\n// minimizing the sum of squares of relative error.\n//   - n          : Vector containing the size of the benchmark tests.\n//   - time       : Vector containing the times for the benchmark tests.\n//   - complexity : If different than oAuto, the fitting curve will stick to\n//                  this one. If it is oAuto, it will be calculated the best\n//                  fitting curve.\nLeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,\n                       const std::vector<double>& time, const BigO complexity) {\n  BM_CHECK_EQ(n.size(), time.size());\n  BM_CHECK_GE(n.size(), 2);  // Do not compute fitting curve is less than two\n                             // benchmark runs are given\n  BM_CHECK_NE(complexity, oNone);\n\n  LeastSq best_fit;\n\n  if (complexity == oAuto) {\n    std::vector<BigO> fit_curves = {oLogN, oN, oNLogN, oNSquared, oNCubed};\n\n    // Take o1 as default best fitting curve\n    best_fit = MinimalLeastSq(n, time, FittingCurve(o1));\n    best_fit.complexity = o1;\n\n    // Compute all possible fitting curves and stick to the best one\n    for (const auto& fit : fit_curves) {\n      LeastSq current_fit = MinimalLeastSq(n, time, FittingCurve(fit));\n      if (current_fit.rms < best_fit.rms) {\n        best_fit = current_fit;\n        best_fit.complexity = fit;\n      }\n    }\n  } else {\n    best_fit = MinimalLeastSq(n, time, FittingCurve(complexity));\n    best_fit.complexity = complexity;\n  }\n\n  return best_fit;\n}\n\nstd::vector<BenchmarkReporter::Run> ComputeBigO(\n    const std::vector<BenchmarkReporter::Run>& reports) {\n  typedef BenchmarkReporter::Run Run;\n  std::vector<Run> results;\n\n  if (reports.size() < 2) return results;\n\n  // Accumulators.\n  std::vector<ComplexityN> n;\n  std::vector<double> real_time;\n  std::vector<double> cpu_time;\n\n  // Populate the accumulators.\n  for (const Run& run : reports) {\n    BM_CHECK_GT(run.complexity_n, 0)\n        << \"Did you forget to call SetComplexityN?\";\n    n.push_back(run.complexity_n);\n    real_time.push_back(run.real_accumulated_time /\n                        static_cast<double>(run.iterations));\n    cpu_time.push_back(run.cpu_accumulated_time /\n                       static_cast<double>(run.iterations));\n  }\n\n  LeastSq result_cpu;\n  LeastSq result_real;\n\n  if (reports[0].complexity == oLambda) {\n    result_cpu = MinimalLeastSq(n, cpu_time, reports[0].complexity_lambda);\n    result_real = MinimalLeastSq(n, real_time, reports[0].complexity_lambda);\n  } else {\n    const BigO* InitialBigO = &reports[0].complexity;\n    const bool use_real_time_for_initial_big_o =\n        reports[0].use_real_time_for_initial_big_o;\n    if (use_real_time_for_initial_big_o) {\n      result_real = MinimalLeastSq(n, real_time, *InitialBigO);\n      InitialBigO = &result_real.complexity;\n      // The Big-O complexity for CPU time must have the same Big-O function!\n    }\n    result_cpu = MinimalLeastSq(n, cpu_time, *InitialBigO);\n    InitialBigO = &result_cpu.complexity;\n    if (!use_real_time_for_initial_big_o) {\n      result_real = MinimalLeastSq(n, real_time, *InitialBigO);\n    }\n  }\n\n  // Drop the 'args' when reporting complexity.\n  auto run_name = reports[0].run_name;\n  run_name.args.clear();\n\n  // Get the data from the accumulator to BenchmarkReporter::Run's.\n  Run big_o;\n  big_o.run_name = run_name;\n  big_o.family_index = reports[0].family_index;\n  big_o.per_family_instance_index = reports[0].per_family_instance_index;\n  big_o.run_type = BenchmarkReporter::Run::RT_Aggregate;\n  big_o.repetitions = reports[0].repetitions;\n  big_o.repetition_index = Run::no_repetition_index;\n  big_o.threads = reports[0].threads;\n  big_o.aggregate_name = \"BigO\";\n  big_o.aggregate_unit = StatisticUnit::kTime;\n  big_o.report_label = reports[0].report_label;\n  big_o.iterations = 0;\n  big_o.real_accumulated_time = result_real.coef;\n  big_o.cpu_accumulated_time = result_cpu.coef;\n  big_o.report_big_o = true;\n  big_o.complexity = result_cpu.complexity;\n\n  // All the time results are reported after being multiplied by the\n  // time unit multiplier. But since RMS is a relative quantity it\n  // should not be multiplied at all. So, here, we _divide_ it by the\n  // multiplier so that when it is multiplied later the result is the\n  // correct one.\n  double multiplier = GetTimeUnitMultiplier(reports[0].time_unit);\n\n  // Only add label to mean/stddev if it is same for all runs\n  Run rms;\n  rms.run_name = run_name;\n  rms.family_index = reports[0].family_index;\n  rms.per_family_instance_index = reports[0].per_family_instance_index;\n  rms.run_type = BenchmarkReporter::Run::RT_Aggregate;\n  rms.aggregate_name = \"RMS\";\n  rms.aggregate_unit = StatisticUnit::kPercentage;\n  rms.report_label = big_o.report_label;\n  rms.iterations = 0;\n  rms.repetition_index = Run::no_repetition_index;\n  rms.repetitions = reports[0].repetitions;\n  rms.threads = reports[0].threads;\n  rms.real_accumulated_time = result_real.rms / multiplier;\n  rms.cpu_accumulated_time = result_cpu.rms / multiplier;\n  rms.report_rms = true;\n  rms.complexity = result_cpu.complexity;\n  // don't forget to keep the time unit, or we won't be able to\n  // recover the correct value.\n  rms.time_unit = reports[0].time_unit;\n\n  results.push_back(big_o);\n  results.push_back(rms);\n  return results;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/complexity.h",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Source project : https://github.com/ismaelJimenez/cpp.leastsq\n// Adapted to be used with google benchmark\n\n#ifndef COMPLEXITY_H_\n#define COMPLEXITY_H_\n\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// Return a vector containing the bigO and RMS information for the specified\n// list of reports. If 'reports.size() < 2' an empty vector is returned.\nstd::vector<BenchmarkReporter::Run> ComputeBigO(\n    const std::vector<BenchmarkReporter::Run>& reports);\n\n// This data structure will contain the result returned by MinimalLeastSq\n//   - coef        : Estimated coefficient for the high-order term as\n//                   interpolated from data.\n//   - rms         : Normalized Root Mean Squared Error.\n//   - complexity  : Scalability form (e.g. oN, oNLogN). In case a scalability\n//                   form has been provided to MinimalLeastSq this will return\n//                   the same value. In case BigO::oAuto has been selected, this\n//                   parameter will return the best fitting curve detected.\n\nstruct LeastSq {\n  LeastSq() : coef(0.0), rms(0.0), complexity(oNone) {}\n\n  double coef;\n  double rms;\n  BigO complexity;\n};\n\n// Function to return an string for the calculated complexity\nstd::string GetBigOString(BigO complexity);\n\n}  // end namespace benchmark\n\n#endif  // COMPLEXITY_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/console_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cstdint>\n#include <cstdio>\n#include <cstring>\n#include <iostream>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nBENCHMARK_EXPORT\nbool ConsoleReporter::ReportContext(const Context& context) {\n  name_field_width_ = context.name_field_width;\n  printed_header_ = false;\n  prev_counters_.clear();\n\n  PrintBasicContext(&GetErrorStream(), context);\n\n#ifdef BENCHMARK_OS_WINDOWS\n  if ((output_options_ & OO_Color)) {\n    auto stdOutBuf = std::cout.rdbuf();\n    auto outStreamBuf = GetOutputStream().rdbuf();\n    if (stdOutBuf != outStreamBuf) {\n      GetErrorStream()\n          << \"Color printing is only supported for stdout on windows.\"\n             \" Disabling color printing\\n\";\n      output_options_ = static_cast<OutputOptions>(output_options_ & ~OO_Color);\n    }\n  }\n#endif\n\n  return true;\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::PrintHeader(const Run& run) {\n  std::string str =\n      FormatString(\"%-*s %13s %15s %12s\", static_cast<int>(name_field_width_),\n                   \"Benchmark\", \"Time\", \"CPU\", \"Iterations\");\n  if (!run.counters.empty()) {\n    if (output_options_ & OO_Tabular) {\n      for (auto const& c : run.counters) {\n        str += FormatString(\" %10s\", c.first.c_str());\n      }\n    } else {\n      str += \" UserCounters...\";\n    }\n  }\n  std::string line = std::string(str.length(), '-');\n  GetOutputStream() << line << \"\\n\" << str << \"\\n\" << line << \"\\n\";\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {\n  for (const auto& run : reports) {\n    // print the header:\n    // --- if none was printed yet\n    bool print_header = !printed_header_;\n    // --- or if the format is tabular and this run\n    //     has different fields from the prev header\n    print_header |= (output_options_ & OO_Tabular) &&\n                    (!internal::SameNames(run.counters, prev_counters_));\n    if (print_header) {\n      printed_header_ = true;\n      prev_counters_ = run.counters;\n      PrintHeader(run);\n    }\n    // As an alternative to printing the headers like this, we could sort\n    // the benchmarks by header and then print. But this would require\n    // waiting for the full results before printing, or printing twice.\n    PrintRunData(run);\n  }\n}\n\nstatic void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt,\n                             ...) {\n  va_list args;\n  va_start(args, fmt);\n  out << FormatString(fmt, args);\n  va_end(args);\n}\n\nstatic std::string FormatTime(double time) {\n  // For the time columns of the console printer 13 digits are reserved. One of\n  // them is a space and max two of them are the time unit (e.g ns). That puts\n  // us at 10 digits usable for the number.\n  // Align decimal places...\n  if (time < 1.0) {\n    return FormatString(\"%10.3f\", time);\n  }\n  if (time < 10.0) {\n    return FormatString(\"%10.2f\", time);\n  }\n  if (time < 100.0) {\n    return FormatString(\"%10.1f\", time);\n  }\n  // Assuming the time is at max 9.9999e+99 and we have 10 digits for the\n  // number, we get 10-1(.)-1(e)-1(sign)-2(exponent) = 5 digits to print.\n  if (time > 9999999999 /*max 10 digit number*/) {\n    return FormatString(\"%1.4e\", time);\n  }\n  return FormatString(\"%10.0f\", time);\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::PrintRunData(const Run& result) {\n  typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...);\n  auto& Out = GetOutputStream();\n  PrinterFn* printer = (output_options_ & OO_Color)\n                           ? static_cast<PrinterFn*>(ColorPrintf)\n                           : IgnoreColorPrint;\n  auto name_color =\n      (result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN;\n  printer(Out, name_color, \"%-*s \", name_field_width_,\n          result.benchmark_name().c_str());\n\n  if (internal::SkippedWithError == result.skipped) {\n    printer(Out, COLOR_RED, \"ERROR OCCURRED: \\'%s\\'\",\n            result.skip_message.c_str());\n    printer(Out, COLOR_DEFAULT, \"\\n\");\n    return;\n  } else if (internal::SkippedWithMessage == result.skipped) {\n    printer(Out, COLOR_WHITE, \"SKIPPED: \\'%s\\'\", result.skip_message.c_str());\n    printer(Out, COLOR_DEFAULT, \"\\n\");\n    return;\n  }\n\n  const double real_time = result.GetAdjustedRealTime();\n  const double cpu_time = result.GetAdjustedCPUTime();\n  const std::string real_time_str = FormatTime(real_time);\n  const std::string cpu_time_str = FormatTime(cpu_time);\n\n  if (result.report_big_o) {\n    std::string big_o = GetBigOString(result.complexity);\n    printer(Out, COLOR_YELLOW, \"%10.2f %-4s %10.2f %-4s \", real_time,\n            big_o.c_str(), cpu_time, big_o.c_str());\n  } else if (result.report_rms) {\n    printer(Out, COLOR_YELLOW, \"%10.0f %-4s %10.0f %-4s \", real_time * 100, \"%\",\n            cpu_time * 100, \"%\");\n  } else if (result.run_type != Run::RT_Aggregate ||\n             result.aggregate_unit == StatisticUnit::kTime) {\n    const char* timeLabel = GetTimeUnitString(result.time_unit);\n    printer(Out, COLOR_YELLOW, \"%s %-4s %s %-4s \", real_time_str.c_str(),\n            timeLabel, cpu_time_str.c_str(), timeLabel);\n  } else {\n    assert(result.aggregate_unit == StatisticUnit::kPercentage);\n    printer(Out, COLOR_YELLOW, \"%10.2f %-4s %10.2f %-4s \",\n            (100. * result.real_accumulated_time), \"%\",\n            (100. * result.cpu_accumulated_time), \"%\");\n  }\n\n  if (!result.report_big_o && !result.report_rms) {\n    printer(Out, COLOR_CYAN, \"%10lld\", result.iterations);\n  }\n\n  for (auto& c : result.counters) {\n    const std::size_t cNameLen =\n        std::max(std::string::size_type(10), c.first.length());\n    std::string s;\n    const char* unit = \"\";\n    if (result.run_type == Run::RT_Aggregate &&\n        result.aggregate_unit == StatisticUnit::kPercentage) {\n      s = StrFormat(\"%.2f\", 100. * c.second.value);\n      unit = \"%\";\n    } else {\n      s = HumanReadableNumber(c.second.value, c.second.oneK);\n      if (c.second.flags & Counter::kIsRate)\n        unit = (c.second.flags & Counter::kInvert) ? \"s\" : \"/s\";\n    }\n    if (output_options_ & OO_Tabular) {\n      printer(Out, COLOR_DEFAULT, \" %*s%s\", cNameLen - strlen(unit), s.c_str(),\n              unit);\n    } else {\n      printer(Out, COLOR_DEFAULT, \" %s=%s%s\", c.first.c_str(), s.c_str(), unit);\n    }\n  }\n\n  if (!result.report_label.empty()) {\n    printer(Out, COLOR_DEFAULT, \" %s\", result.report_label.c_str());\n  }\n\n  printer(Out, COLOR_DEFAULT, \"\\n\");\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/counter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"counter.h\"\n\nnamespace benchmark {\nnamespace internal {\n\ndouble Finish(Counter const& c, IterationCount iterations, double cpu_time,\n              double num_threads) {\n  double v = c.value;\n  if (c.flags & Counter::kIsRate) {\n    v /= cpu_time;\n  }\n  if (c.flags & Counter::kAvgThreads) {\n    v /= num_threads;\n  }\n  if (c.flags & Counter::kIsIterationInvariant) {\n    v *= static_cast<double>(iterations);\n  }\n  if (c.flags & Counter::kAvgIterations) {\n    v /= static_cast<double>(iterations);\n  }\n\n  if (c.flags & Counter::kInvert) {  // Invert is *always* last.\n    v = 1.0 / v;\n  }\n  return v;\n}\n\nvoid Finish(UserCounters* l, IterationCount iterations, double cpu_time,\n            double num_threads) {\n  for (auto& c : *l) {\n    c.second.value = Finish(c.second, iterations, cpu_time, num_threads);\n  }\n}\n\nvoid Increment(UserCounters* l, UserCounters const& r) {\n  // add counters present in both or just in *l\n  for (auto& c : *l) {\n    auto it = r.find(c.first);\n    if (it != r.end()) {\n      c.second.value = c.second + it->second;\n    }\n  }\n  // add counters present in r, but not in *l\n  for (auto const& tc : r) {\n    auto it = l->find(tc.first);\n    if (it == l->end()) {\n      (*l)[tc.first] = tc.second;\n    }\n  }\n}\n\nbool SameNames(UserCounters const& l, UserCounters const& r) {\n  if (&l == &r) return true;\n  if (l.size() != r.size()) {\n    return false;\n  }\n  for (auto const& c : l) {\n    if (r.find(c.first) == r.end()) {\n      return false;\n    }\n  }\n  return true;\n}\n\n}  // end namespace internal\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/counter.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_COUNTER_H_\n#define BENCHMARK_COUNTER_H_\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// these counter-related functions are hidden to reduce API surface.\nnamespace internal {\nvoid Finish(UserCounters* l, IterationCount iterations, double time,\n            double num_threads);\nvoid Increment(UserCounters* l, UserCounters const& r);\nbool SameNames(UserCounters const& l, UserCounters const& r);\n}  // end namespace internal\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COUNTER_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/csv_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"complexity.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\n// File format reference: http://edoceo.com/utilitas/csv-file-format.\n\nnamespace benchmark {\n\nnamespace {\nstd::vector<std::string> elements = {\n    \"name\",           \"iterations\",       \"real_time\",        \"cpu_time\",\n    \"time_unit\",      \"bytes_per_second\", \"items_per_second\", \"label\",\n    \"error_occurred\", \"error_message\"};\n}  // namespace\n\nstd::string CsvEscape(const std::string& s) {\n  std::string tmp;\n  tmp.reserve(s.size() + 2);\n  for (char c : s) {\n    switch (c) {\n      case '\"':\n        tmp += \"\\\"\\\"\";\n        break;\n      default:\n        tmp += c;\n        break;\n    }\n  }\n  return '\"' + tmp + '\"';\n}\n\nBENCHMARK_EXPORT\nbool CSVReporter::ReportContext(const Context& context) {\n  PrintBasicContext(&GetErrorStream(), context);\n  return true;\n}\n\nBENCHMARK_EXPORT\nvoid CSVReporter::ReportRuns(const std::vector<Run>& reports) {\n  std::ostream& Out = GetOutputStream();\n\n  if (!printed_header_) {\n    // save the names of all the user counters\n    for (const auto& run : reports) {\n      for (const auto& cnt : run.counters) {\n        if (cnt.first == \"bytes_per_second\" || cnt.first == \"items_per_second\")\n          continue;\n        user_counter_names_.insert(cnt.first);\n      }\n    }\n\n    // print the header\n    for (auto B = elements.begin(); B != elements.end();) {\n      Out << *B++;\n      if (B != elements.end()) Out << \",\";\n    }\n    for (auto B = user_counter_names_.begin();\n         B != user_counter_names_.end();) {\n      Out << \",\\\"\" << *B++ << \"\\\"\";\n    }\n    Out << \"\\n\";\n\n    printed_header_ = true;\n  } else {\n    // check that all the current counters are saved in the name set\n    for (const auto& run : reports) {\n      for (const auto& cnt : run.counters) {\n        if (cnt.first == \"bytes_per_second\" || cnt.first == \"items_per_second\")\n          continue;\n        BM_CHECK(user_counter_names_.find(cnt.first) !=\n                 user_counter_names_.end())\n            << \"All counters must be present in each run. \"\n            << \"Counter named \\\"\" << cnt.first\n            << \"\\\" was not in a run after being added to the header\";\n      }\n    }\n  }\n\n  // print results for each run\n  for (const auto& run : reports) {\n    PrintRunData(run);\n  }\n}\n\nBENCHMARK_EXPORT\nvoid CSVReporter::PrintRunData(const Run& run) {\n  std::ostream& Out = GetOutputStream();\n  Out << CsvEscape(run.benchmark_name()) << \",\";\n  if (run.skipped) {\n    Out << std::string(elements.size() - 3, ',');\n    Out << std::boolalpha << (internal::SkippedWithError == run.skipped) << \",\";\n    Out << CsvEscape(run.skip_message) << \"\\n\";\n    return;\n  }\n\n  // Do not print iteration on bigO and RMS report\n  if (!run.report_big_o && !run.report_rms) {\n    Out << run.iterations;\n  }\n  Out << \",\";\n\n  if (run.run_type != Run::RT_Aggregate ||\n      run.aggregate_unit == StatisticUnit::kTime) {\n    Out << run.GetAdjustedRealTime() << \",\";\n    Out << run.GetAdjustedCPUTime() << \",\";\n  } else {\n    assert(run.aggregate_unit == StatisticUnit::kPercentage);\n    Out << run.real_accumulated_time << \",\";\n    Out << run.cpu_accumulated_time << \",\";\n  }\n\n  // Do not print timeLabel on bigO and RMS report\n  if (run.report_big_o) {\n    Out << GetBigOString(run.complexity);\n  } else if (!run.report_rms &&\n             run.aggregate_unit != StatisticUnit::kPercentage) {\n    Out << GetTimeUnitString(run.time_unit);\n  }\n  Out << \",\";\n\n  if (run.counters.find(\"bytes_per_second\") != run.counters.end()) {\n    Out << run.counters.at(\"bytes_per_second\");\n  }\n  Out << \",\";\n  if (run.counters.find(\"items_per_second\") != run.counters.end()) {\n    Out << run.counters.at(\"items_per_second\");\n  }\n  Out << \",\";\n  if (!run.report_label.empty()) {\n    Out << CsvEscape(run.report_label);\n  }\n  Out << \",,\";  // for error_occurred and error_message\n\n  // Print user counters\n  for (const auto& ucn : user_counter_names_) {\n    auto it = run.counters.find(ucn);\n    if (it == run.counters.end()) {\n      Out << \",\";\n    } else {\n      Out << \",\" << it->second;\n    }\n  }\n  Out << '\\n';\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/cycleclock.h",
    "content": "// ----------------------------------------------------------------------\n// CycleClock\n//    A CycleClock tells you the current time in Cycles.  The \"time\"\n//    is actually time since power-on.  This is like time() but doesn't\n//    involve a system call and is much more precise.\n//\n// NOTE: Not all cpu/platform/kernel combinations guarantee that this\n// clock increments at a constant rate or is synchronized across all logical\n// cpus in a system.\n//\n// If you need the above guarantees, please consider using a different\n// API. There are efforts to provide an interface which provides a millisecond\n// granularity and implemented as a memory read. A memory read is generally\n// cheaper than the CycleClock for many architectures.\n//\n// Also, in some out of order CPU implementations, the CycleClock is not\n// serializing. So if you're trying to count at cycles granularity, your\n// data might be inaccurate due to out of order instruction execution.\n// ----------------------------------------------------------------------\n\n#ifndef BENCHMARK_CYCLECLOCK_H_\n#define BENCHMARK_CYCLECLOCK_H_\n\n#include <cstdint>\n\n#include \"benchmark/benchmark.h\"\n#include \"internal_macros.h\"\n\n#if defined(BENCHMARK_OS_MACOSX)\n#include <mach/mach_time.h>\n#endif\n// For MSVC, we want to use '_asm rdtsc' when possible (since it works\n// with even ancient MSVC compilers), and when not possible the\n// __rdtsc intrinsic, declared in <intrin.h>.  Unfortunately, in some\n// environments, <windows.h> and <intrin.h> have conflicting\n// declarations of some other intrinsics, breaking compilation.\n// Therefore, we simply declare __rdtsc ourselves. See also\n// http://connect.microsoft.com/VisualStudio/feedback/details/262047\n#if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \\\n    !defined(_M_ARM64EC)\nextern \"C\" uint64_t __rdtsc();\n#pragma intrinsic(__rdtsc)\n#endif\n\n#if !defined(BENCHMARK_OS_WINDOWS) || defined(BENCHMARK_OS_MINGW)\n#include <sys/time.h>\n#include <time.h>\n#endif\n\n#ifdef BENCHMARK_OS_EMSCRIPTEN\n#include <emscripten.h>\n#endif\n\nnamespace benchmark {\n// NOTE: only i386 and x86_64 have been well tested.\n// PPC, sparc, alpha, and ia64 are based on\n//    http://peter.kuscsik.com/wordpress/?p=14\n// with modifications by m3b.  See also\n//    https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h\nnamespace cycleclock {\n// This should return the number of cycles since power-on.  Thread-safe.\ninline BENCHMARK_ALWAYS_INLINE int64_t Now() {\n#if defined(BENCHMARK_OS_MACOSX)\n  // this goes at the top because we need ALL Macs, regardless of\n  // architecture, to return the number of \"mach time units\" that\n  // have passed since startup.  See sysinfo.cc where\n  // InitializeSystemInfo() sets the supposed cpu clock frequency of\n  // macs to the number of mach time units per second, not actual\n  // CPU clock frequency (which can change in the face of CPU\n  // frequency scaling).  Also note that when the Mac sleeps, this\n  // counter pauses; it does not continue counting, nor does it\n  // reset to zero.\n  return static_cast<int64_t>(mach_absolute_time());\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // this goes above x86-specific code because old versions of Emscripten\n  // define __x86_64__, although they have nothing to do with it.\n  return static_cast<int64_t>(emscripten_get_now() * 1e+6);\n#elif defined(__i386__)\n  int64_t ret;\n  __asm__ volatile(\"rdtsc\" : \"=A\"(ret));\n  return ret;\n#elif defined(__x86_64__) || defined(__amd64__)\n  uint64_t low, high;\n  __asm__ volatile(\"rdtsc\" : \"=a\"(low), \"=d\"(high));\n  return static_cast<int64_t>((high << 32) | low);\n#elif defined(__powerpc__) || defined(__ppc__)\n  // This returns a time-base, which is not always precisely a cycle-count.\n#if defined(__powerpc64__) || defined(__ppc64__)\n  int64_t tb;\n  asm volatile(\"mfspr %0, 268\" : \"=r\"(tb));\n  return tb;\n#else\n  uint32_t tbl, tbu0, tbu1;\n  asm volatile(\n      \"mftbu %0\\n\"\n      \"mftb %1\\n\"\n      \"mftbu %2\"\n      : \"=r\"(tbu0), \"=r\"(tbl), \"=r\"(tbu1));\n  tbl &= -static_cast<int32_t>(tbu0 == tbu1);\n  // high 32 bits in tbu1; low 32 bits in tbl  (tbu0 is no longer needed)\n  return (static_cast<uint64_t>(tbu1) << 32) | tbl;\n#endif\n#elif defined(__sparc__)\n  int64_t tick;\n  asm(\".byte 0x83, 0x41, 0x00, 0x00\");\n  asm(\"mov   %%g1, %0\" : \"=r\"(tick));\n  return tick;\n#elif defined(__ia64__)\n  int64_t itc;\n  asm(\"mov %0 = ar.itc\" : \"=r\"(itc));\n  return itc;\n#elif defined(COMPILER_MSVC) && defined(_M_IX86)\n  // Older MSVC compilers (like 7.x) don't seem to support the\n  // __rdtsc intrinsic properly, so I prefer to use _asm instead\n  // when I know it will work.  Otherwise, I'll use __rdtsc and hope\n  // the code is being compiled with a non-ancient compiler.\n  _asm rdtsc\n#elif defined(COMPILER_MSVC) && (defined(_M_ARM64) || defined(_M_ARM64EC))\n  // See // https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics\n  // and https://reviews.llvm.org/D53115\n  int64_t virtual_timer_value;\n  virtual_timer_value = _ReadStatusReg(ARM64_CNTVCT);\n  return virtual_timer_value;\n#elif defined(COMPILER_MSVC)\n  return __rdtsc();\n#elif defined(BENCHMARK_OS_NACL)\n  // Native Client validator on x86/x86-64 allows RDTSC instructions,\n  // and this case is handled above. Native Client validator on ARM\n  // rejects MRC instructions (used in the ARM-specific sequence below),\n  // so we handle it here. Portable Native Client compiles to\n  // architecture-agnostic bytecode, which doesn't provide any\n  // cycle counter access mnemonics.\n\n  // Native Client does not provide any API to access cycle counter.\n  // Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday\n  // because is provides nanosecond resolution (which is noticeable at\n  // least for PNaCl modules running on x86 Mac & Linux).\n  // Initialize to always return 0 if clock_gettime fails.\n  struct timespec ts = {0, 0};\n  clock_gettime(CLOCK_MONOTONIC, &ts);\n  return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;\n#elif defined(__aarch64__)\n  // System timer of ARMv8 runs at a different frequency than the CPU's.\n  // The frequency is fixed, typically in the range 1-50MHz.  It can be\n  // read at CNTFRQ special register.  We assume the OS has set up\n  // the virtual timer properly.\n  int64_t virtual_timer_value;\n  asm volatile(\"mrs %0, cntvct_el0\" : \"=r\"(virtual_timer_value));\n  return virtual_timer_value;\n#elif defined(__ARM_ARCH)\n  // V6 is the earliest arch that has a standard cyclecount\n  // Native Client validator doesn't allow MRC instructions.\n#if (__ARM_ARCH >= 6)\n  uint32_t pmccntr;\n  uint32_t pmuseren;\n  uint32_t pmcntenset;\n  // Read the user mode perf monitor counter access permissions.\n  asm volatile(\"mrc p15, 0, %0, c9, c14, 0\" : \"=r\"(pmuseren));\n  if (pmuseren & 1) {  // Allows reading perfmon counters for user mode code.\n    asm volatile(\"mrc p15, 0, %0, c9, c12, 1\" : \"=r\"(pmcntenset));\n    if (pmcntenset & 0x80000000ul) {  // Is it counting?\n      asm volatile(\"mrc p15, 0, %0, c9, c13, 0\" : \"=r\"(pmccntr));\n      // The counter is set up to count every 64th cycle\n      return static_cast<int64_t>(pmccntr) * 64;  // Should optimize to << 6\n    }\n  }\n#endif\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__mips__) || defined(__m68k__)\n  // mips apparently only allows rdtsc for superusers, so we fall\n  // back to gettimeofday.  It's possible clock_gettime would be better.\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__loongarch__) || defined(__csky__)\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__s390__)  // Covers both s390 and s390x.\n  // Return the CPU clock.\n  uint64_t tsc;\n#if defined(BENCHMARK_OS_ZOS)\n  // z/OS HLASM syntax.\n  asm(\" stck %0\" : \"=m\"(tsc) : : \"cc\");\n#else\n  // Linux on Z syntax.\n  asm(\"stck %0\" : \"=Q\"(tsc) : : \"cc\");\n#endif\n  return tsc;\n#elif defined(__riscv)  // RISC-V\n  // Use RDTIME (and RDTIMEH on riscv32).\n  // RDCYCLE is a privileged instruction since Linux 6.6.\n#if __riscv_xlen == 32\n  uint32_t cycles_lo, cycles_hi0, cycles_hi1;\n  // This asm also includes the PowerPC overflow handling strategy, as above.\n  // Implemented in assembly because Clang insisted on branching.\n  asm volatile(\n      \"rdtimeh %0\\n\"\n      \"rdtime %1\\n\"\n      \"rdtimeh %2\\n\"\n      \"sub %0, %0, %2\\n\"\n      \"seqz %0, %0\\n\"\n      \"sub %0, zero, %0\\n\"\n      \"and %1, %1, %0\\n\"\n      : \"=r\"(cycles_hi0), \"=r\"(cycles_lo), \"=r\"(cycles_hi1));\n  return static_cast<int64_t>((static_cast<uint64_t>(cycles_hi1) << 32) |\n                              cycles_lo);\n#else\n  uint64_t cycles;\n  asm volatile(\"rdtime %0\" : \"=r\"(cycles));\n  return static_cast<int64_t>(cycles);\n#endif\n#elif defined(__e2k__) || defined(__elbrus__)\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__hexagon__)\n  uint64_t pcycle;\n  asm volatile(\"%0 = C15:14\" : \"=r\"(pcycle));\n  return static_cast<double>(pcycle);\n#elif defined(__alpha__)\n  // Alpha has a cycle counter, the PCC register, but it is an unsigned 32-bit\n  // integer and thus wraps every ~4s, making using it for tick counts\n  // unreliable beyond this time range.  The real-time clock is low-precision,\n  // roughtly ~1ms, but it is the only option that can reasonable count\n  // indefinitely.\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#else\n  // The soft failover to a generic implementation is automatic only for ARM.\n  // For other platforms the developer is expected to make an attempt to create\n  // a fast implementation and use generic version if nothing better is\n  // available.\n#error You need to define CycleTimer for your OS and CPU\n#endif\n}\n}  // end namespace cycleclock\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_CYCLECLOCK_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/internal_macros.h",
    "content": "#ifndef BENCHMARK_INTERNAL_MACROS_H_\n#define BENCHMARK_INTERNAL_MACROS_H_\n\n/* Needed to detect STL */\n#include <cstdlib>\n\n// clang-format off\n\n#ifndef __has_feature\n#define __has_feature(x) 0\n#endif\n\n#if defined(__clang__)\n  #if !defined(COMPILER_CLANG)\n    #define COMPILER_CLANG\n  #endif\n#elif defined(_MSC_VER)\n  #if !defined(COMPILER_MSVC)\n    #define COMPILER_MSVC\n  #endif\n#elif defined(__GNUC__)\n  #if !defined(COMPILER_GCC)\n    #define COMPILER_GCC\n  #endif\n#endif\n\n#if __has_feature(cxx_attributes)\n  #define BENCHMARK_NORETURN [[noreturn]]\n#elif defined(__GNUC__)\n  #define BENCHMARK_NORETURN __attribute__((noreturn))\n#elif defined(COMPILER_MSVC)\n  #define BENCHMARK_NORETURN __declspec(noreturn)\n#else\n  #define BENCHMARK_NORETURN\n#endif\n\n#if defined(__CYGWIN__)\n  #define BENCHMARK_OS_CYGWIN 1\n#elif defined(_WIN32)\n  #define BENCHMARK_OS_WINDOWS 1\n  // WINAPI_FAMILY_PARTITION is defined in winapifamily.h.\n  // We include windows.h which implicitly includes winapifamily.h for compatibility.\n  #ifndef NOMINMAX\n    #define NOMINMAX\n  #endif\n  #include <windows.h>\n  #if defined(WINAPI_FAMILY_PARTITION)\n    #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)\n      #define BENCHMARK_OS_WINDOWS_WIN32 1\n    #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)\n      #define BENCHMARK_OS_WINDOWS_RT 1\n    #endif\n  #endif\n  #if defined(__MINGW32__)\n    #define BENCHMARK_OS_MINGW 1\n  #endif\n#elif defined(__APPLE__)\n  #define BENCHMARK_OS_APPLE 1\n  #include \"TargetConditionals.h\"\n  #if defined(TARGET_OS_MAC)\n    #define BENCHMARK_OS_MACOSX 1\n    #if defined(TARGET_OS_IPHONE)\n      #define BENCHMARK_OS_IOS 1\n    #endif\n  #endif\n#elif defined(__FreeBSD__)\n  #define BENCHMARK_OS_FREEBSD 1\n#elif defined(__NetBSD__)\n  #define BENCHMARK_OS_NETBSD 1\n#elif defined(__OpenBSD__)\n  #define BENCHMARK_OS_OPENBSD 1\n#elif defined(__DragonFly__)\n  #define BENCHMARK_OS_DRAGONFLY 1\n#elif defined(__linux__)\n  #define BENCHMARK_OS_LINUX 1\n#elif defined(__native_client__)\n  #define BENCHMARK_OS_NACL 1\n#elif defined(__EMSCRIPTEN__)\n  #define BENCHMARK_OS_EMSCRIPTEN 1\n#elif defined(__rtems__)\n  #define BENCHMARK_OS_RTEMS 1\n#elif defined(__Fuchsia__)\n#define BENCHMARK_OS_FUCHSIA 1\n#elif defined (__SVR4) && defined (__sun)\n#define BENCHMARK_OS_SOLARIS 1\n#elif defined(__QNX__)\n#define BENCHMARK_OS_QNX 1\n#elif defined(__MVS__)\n#define BENCHMARK_OS_ZOS 1\n#elif defined(__hexagon__)\n#define BENCHMARK_OS_QURT 1\n#endif\n\n#if defined(__ANDROID__) && defined(__GLIBCXX__)\n#define BENCHMARK_STL_ANDROID_GNUSTL 1\n#endif\n\n#if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \\\n     && !defined(__EXCEPTIONS)\n  #define BENCHMARK_HAS_NO_EXCEPTIONS\n#endif\n\n#if defined(COMPILER_CLANG) || defined(COMPILER_GCC)\n  #define BENCHMARK_MAYBE_UNUSED __attribute__((unused))\n#else\n  #define BENCHMARK_MAYBE_UNUSED\n#endif\n\n// clang-format on\n\n#endif  // BENCHMARK_INTERNAL_MACROS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/json_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n#include <iomanip>  // for setprecision\n#include <iostream>\n#include <limits>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"complexity.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace {\n\nstd::string StrEscape(const std::string& s) {\n  std::string tmp;\n  tmp.reserve(s.size());\n  for (char c : s) {\n    switch (c) {\n      case '\\b':\n        tmp += \"\\\\b\";\n        break;\n      case '\\f':\n        tmp += \"\\\\f\";\n        break;\n      case '\\n':\n        tmp += \"\\\\n\";\n        break;\n      case '\\r':\n        tmp += \"\\\\r\";\n        break;\n      case '\\t':\n        tmp += \"\\\\t\";\n        break;\n      case '\\\\':\n        tmp += \"\\\\\\\\\";\n        break;\n      case '\"':\n        tmp += \"\\\\\\\"\";\n        break;\n      default:\n        tmp += c;\n        break;\n    }\n  }\n  return tmp;\n}\n\nstd::string FormatKV(std::string const& key, std::string const& value) {\n  return StrFormat(\"\\\"%s\\\": \\\"%s\\\"\", StrEscape(key).c_str(),\n                   StrEscape(value).c_str());\n}\n\nstd::string FormatKV(std::string const& key, const char* value) {\n  return StrFormat(\"\\\"%s\\\": \\\"%s\\\"\", StrEscape(key).c_str(),\n                   StrEscape(value).c_str());\n}\n\nstd::string FormatKV(std::string const& key, bool value) {\n  return StrFormat(\"\\\"%s\\\": %s\", StrEscape(key).c_str(),\n                   value ? \"true\" : \"false\");\n}\n\nstd::string FormatKV(std::string const& key, int64_t value) {\n  std::stringstream ss;\n  ss << '\"' << StrEscape(key) << \"\\\": \" << value;\n  return ss.str();\n}\n\nstd::string FormatKV(std::string const& key, double value) {\n  std::stringstream ss;\n  ss << '\"' << StrEscape(key) << \"\\\": \";\n\n  if (std::isnan(value))\n    ss << (value < 0 ? \"-\" : \"\") << \"NaN\";\n  else if (std::isinf(value))\n    ss << (value < 0 ? \"-\" : \"\") << \"Infinity\";\n  else {\n    const auto max_digits10 =\n        std::numeric_limits<decltype(value)>::max_digits10;\n    const auto max_fractional_digits10 = max_digits10 - 1;\n    ss << std::scientific << std::setprecision(max_fractional_digits10)\n       << value;\n  }\n  return ss.str();\n}\n\nint64_t RoundDouble(double v) { return std::lround(v); }\n\n}  // end namespace\n\nbool JSONReporter::ReportContext(const Context& context) {\n  std::ostream& out = GetOutputStream();\n\n  out << \"{\\n\";\n  std::string inner_indent(2, ' ');\n\n  // Open context block and print context information.\n  out << inner_indent << \"\\\"context\\\": {\\n\";\n  std::string indent(4, ' ');\n\n  std::string walltime_value = LocalDateTimeString();\n  out << indent << FormatKV(\"date\", walltime_value) << \",\\n\";\n\n  out << indent << FormatKV(\"host_name\", context.sys_info.name) << \",\\n\";\n\n  if (Context::executable_name) {\n    out << indent << FormatKV(\"executable\", Context::executable_name) << \",\\n\";\n  }\n\n  CPUInfo const& info = context.cpu_info;\n  out << indent << FormatKV(\"num_cpus\", static_cast<int64_t>(info.num_cpus))\n      << \",\\n\";\n  out << indent\n      << FormatKV(\"mhz_per_cpu\",\n                  RoundDouble(info.cycles_per_second / 1000000.0))\n      << \",\\n\";\n  if (CPUInfo::Scaling::UNKNOWN != info.scaling) {\n    out << indent\n        << FormatKV(\"cpu_scaling_enabled\",\n                    info.scaling == CPUInfo::Scaling::ENABLED ? true : false)\n        << \",\\n\";\n  }\n\n  out << indent << \"\\\"caches\\\": [\\n\";\n  indent = std::string(6, ' ');\n  std::string cache_indent(8, ' ');\n  for (size_t i = 0; i < info.caches.size(); ++i) {\n    auto& CI = info.caches[i];\n    out << indent << \"{\\n\";\n    out << cache_indent << FormatKV(\"type\", CI.type) << \",\\n\";\n    out << cache_indent << FormatKV(\"level\", static_cast<int64_t>(CI.level))\n        << \",\\n\";\n    out << cache_indent << FormatKV(\"size\", static_cast<int64_t>(CI.size))\n        << \",\\n\";\n    out << cache_indent\n        << FormatKV(\"num_sharing\", static_cast<int64_t>(CI.num_sharing))\n        << \"\\n\";\n    out << indent << \"}\";\n    if (i != info.caches.size() - 1) out << \",\";\n    out << \"\\n\";\n  }\n  indent = std::string(4, ' ');\n  out << indent << \"],\\n\";\n  out << indent << \"\\\"load_avg\\\": [\";\n  for (auto it = info.load_avg.begin(); it != info.load_avg.end();) {\n    out << *it++;\n    if (it != info.load_avg.end()) out << \",\";\n  }\n  out << \"],\\n\";\n\n  out << indent << FormatKV(\"library_version\", GetBenchmarkVersion());\n  out << \",\\n\";\n\n#if defined(NDEBUG)\n  const char build_type[] = \"release\";\n#else\n  const char build_type[] = \"debug\";\n#endif\n  out << indent << FormatKV(\"library_build_type\", build_type);\n  out << \",\\n\";\n\n  // NOTE: our json schema is not strictly tied to the library version!\n  out << indent << FormatKV(\"json_schema_version\", int64_t(1));\n\n  std::map<std::string, std::string>* global_context =\n      internal::GetGlobalContext();\n\n  if (global_context != nullptr) {\n    for (const auto& kv : *global_context) {\n      out << \",\\n\";\n      out << indent << FormatKV(kv.first, kv.second);\n    }\n  }\n  out << \"\\n\";\n\n  // Close context block and open the list of benchmarks.\n  out << inner_indent << \"},\\n\";\n  out << inner_indent << \"\\\"benchmarks\\\": [\\n\";\n  return true;\n}\n\nvoid JSONReporter::ReportRuns(std::vector<Run> const& reports) {\n  if (reports.empty()) {\n    return;\n  }\n  std::string indent(4, ' ');\n  std::ostream& out = GetOutputStream();\n  if (!first_report_) {\n    out << \",\\n\";\n  }\n  first_report_ = false;\n\n  for (auto it = reports.begin(); it != reports.end(); ++it) {\n    out << indent << \"{\\n\";\n    PrintRunData(*it);\n    out << indent << '}';\n    auto it_cp = it;\n    if (++it_cp != reports.end()) {\n      out << \",\\n\";\n    }\n  }\n}\n\nvoid JSONReporter::Finalize() {\n  // Close the list of benchmarks and the top level object.\n  GetOutputStream() << \"\\n  ]\\n}\\n\";\n}\n\nvoid JSONReporter::PrintRunData(Run const& run) {\n  std::string indent(6, ' ');\n  std::ostream& out = GetOutputStream();\n  out << indent << FormatKV(\"name\", run.benchmark_name()) << \",\\n\";\n  out << indent << FormatKV(\"family_index\", run.family_index) << \",\\n\";\n  out << indent\n      << FormatKV(\"per_family_instance_index\", run.per_family_instance_index)\n      << \",\\n\";\n  out << indent << FormatKV(\"run_name\", run.run_name.str()) << \",\\n\";\n  out << indent << FormatKV(\"run_type\", [&run]() -> const char* {\n    switch (run.run_type) {\n      case BenchmarkReporter::Run::RT_Iteration:\n        return \"iteration\";\n      case BenchmarkReporter::Run::RT_Aggregate:\n        return \"aggregate\";\n    }\n    BENCHMARK_UNREACHABLE();\n  }()) << \",\\n\";\n  out << indent << FormatKV(\"repetitions\", run.repetitions) << \",\\n\";\n  if (run.run_type != BenchmarkReporter::Run::RT_Aggregate) {\n    out << indent << FormatKV(\"repetition_index\", run.repetition_index)\n        << \",\\n\";\n  }\n  out << indent << FormatKV(\"threads\", run.threads) << \",\\n\";\n  if (run.run_type == BenchmarkReporter::Run::RT_Aggregate) {\n    out << indent << FormatKV(\"aggregate_name\", run.aggregate_name) << \",\\n\";\n    out << indent << FormatKV(\"aggregate_unit\", [&run]() -> const char* {\n      switch (run.aggregate_unit) {\n        case StatisticUnit::kTime:\n          return \"time\";\n        case StatisticUnit::kPercentage:\n          return \"percentage\";\n      }\n      BENCHMARK_UNREACHABLE();\n    }()) << \",\\n\";\n  }\n  if (internal::SkippedWithError == run.skipped) {\n    out << indent << FormatKV(\"error_occurred\", true) << \",\\n\";\n    out << indent << FormatKV(\"error_message\", run.skip_message) << \",\\n\";\n  } else if (internal::SkippedWithMessage == run.skipped) {\n    out << indent << FormatKV(\"skipped\", true) << \",\\n\";\n    out << indent << FormatKV(\"skip_message\", run.skip_message) << \",\\n\";\n  }\n  if (!run.report_big_o && !run.report_rms) {\n    out << indent << FormatKV(\"iterations\", run.iterations) << \",\\n\";\n    if (run.run_type != Run::RT_Aggregate ||\n        run.aggregate_unit == StatisticUnit::kTime) {\n      out << indent << FormatKV(\"real_time\", run.GetAdjustedRealTime())\n          << \",\\n\";\n      out << indent << FormatKV(\"cpu_time\", run.GetAdjustedCPUTime());\n    } else {\n      assert(run.aggregate_unit == StatisticUnit::kPercentage);\n      out << indent << FormatKV(\"real_time\", run.real_accumulated_time)\n          << \",\\n\";\n      out << indent << FormatKV(\"cpu_time\", run.cpu_accumulated_time);\n    }\n    out << \",\\n\"\n        << indent << FormatKV(\"time_unit\", GetTimeUnitString(run.time_unit));\n  } else if (run.report_big_o) {\n    out << indent << FormatKV(\"cpu_coefficient\", run.GetAdjustedCPUTime())\n        << \",\\n\";\n    out << indent << FormatKV(\"real_coefficient\", run.GetAdjustedRealTime())\n        << \",\\n\";\n    out << indent << FormatKV(\"big_o\", GetBigOString(run.complexity)) << \",\\n\";\n    out << indent << FormatKV(\"time_unit\", GetTimeUnitString(run.time_unit));\n  } else if (run.report_rms) {\n    out << indent << FormatKV(\"rms\", run.GetAdjustedCPUTime());\n  }\n\n  for (auto& c : run.counters) {\n    out << \",\\n\" << indent << FormatKV(c.first, c.second);\n  }\n\n  if (run.memory_result) {\n    const MemoryManager::Result memory_result = *run.memory_result;\n    out << \",\\n\" << indent << FormatKV(\"allocs_per_iter\", run.allocs_per_iter);\n    out << \",\\n\"\n        << indent << FormatKV(\"max_bytes_used\", memory_result.max_bytes_used);\n\n    auto report_if_present = [&out, &indent](const std::string& label,\n                                             int64_t val) {\n      if (val != MemoryManager::TombstoneValue)\n        out << \",\\n\" << indent << FormatKV(label, val);\n    };\n\n    report_if_present(\"total_allocated_bytes\",\n                      memory_result.total_allocated_bytes);\n    report_if_present(\"net_heap_growth\", memory_result.net_heap_growth);\n  }\n\n  if (!run.report_label.empty()) {\n    out << \",\\n\" << indent << FormatKV(\"label\", run.report_label);\n  }\n  out << '\\n';\n}\n\nconst int64_t MemoryManager::TombstoneValue =\n    std::numeric_limits<int64_t>::max();\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/log.h",
    "content": "#ifndef BENCHMARK_LOG_H_\n#define BENCHMARK_LOG_H_\n\n#include <iostream>\n#include <ostream>\n\n// NOTE: this is also defined in benchmark.h but we're trying to avoid a\n// dependency.\n// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.\n#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)\n#define BENCHMARK_HAS_CXX11\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\ntypedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);\n\nclass LogType {\n  friend LogType& GetNullLogInstance();\n  friend LogType& GetErrorLogInstance();\n\n  // FIXME: Add locking to output.\n  template <class Tp>\n  friend LogType& operator<<(LogType&, Tp const&);\n  friend LogType& operator<<(LogType&, EndLType*);\n\n private:\n  LogType(std::ostream* out) : out_(out) {}\n  std::ostream* out_;\n\n  // NOTE: we could use BENCHMARK_DISALLOW_COPY_AND_ASSIGN but we shouldn't have\n  // a dependency on benchmark.h from here.\n#ifndef BENCHMARK_HAS_CXX11\n  LogType(const LogType&);\n  LogType& operator=(const LogType&);\n#else\n  LogType(const LogType&) = delete;\n  LogType& operator=(const LogType&) = delete;\n#endif\n};\n\ntemplate <class Tp>\nLogType& operator<<(LogType& log, Tp const& value) {\n  if (log.out_) {\n    *log.out_ << value;\n  }\n  return log;\n}\n\ninline LogType& operator<<(LogType& log, EndLType* m) {\n  if (log.out_) {\n    *log.out_ << m;\n  }\n  return log;\n}\n\ninline int& LogLevel() {\n  static int log_level = 0;\n  return log_level;\n}\n\ninline LogType& GetNullLogInstance() {\n  static LogType null_log(static_cast<std::ostream*>(nullptr));\n  return null_log;\n}\n\ninline LogType& GetErrorLogInstance() {\n  static LogType error_log(&std::clog);\n  return error_log;\n}\n\ninline LogType& GetLogInstanceForLevel(int level) {\n  if (level <= LogLevel()) {\n    return GetErrorLogInstance();\n  }\n  return GetNullLogInstance();\n}\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n// clang-format off\n#define BM_VLOG(x)                                                               \\\n  (::benchmark::internal::GetLogInstanceForLevel(x) << \"-- LOG(\" << x << \"):\" \\\n                                                                         \" \")\n// clang-format on\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/mutex.h",
    "content": "#ifndef BENCHMARK_MUTEX_H_\n#define BENCHMARK_MUTEX_H_\n\n#include <condition_variable>\n#include <mutex>\n\n#include \"check.h\"\n\n// Enable thread safety attributes only with clang.\n// The attributes can be safely erased when compiling with other compilers.\n#if defined(HAVE_THREAD_SAFETY_ATTRIBUTES)\n#define THREAD_ANNOTATION_ATTRIBUTE_(x) __attribute__((x))\n#else\n#define THREAD_ANNOTATION_ATTRIBUTE_(x)  // no-op\n#endif\n\n#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(capability(x))\n\n#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE_(scoped_lockable)\n\n#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE_(guarded_by(x))\n\n#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE_(pt_guarded_by(x))\n\n#define ACQUIRED_BEFORE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquired_before(__VA_ARGS__))\n\n#define ACQUIRED_AFTER(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquired_after(__VA_ARGS__))\n\n#define REQUIRES(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(requires_capability(__VA_ARGS__))\n\n#define REQUIRES_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(requires_shared_capability(__VA_ARGS__))\n\n#define ACQUIRE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquire_capability(__VA_ARGS__))\n\n#define ACQUIRE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquire_shared_capability(__VA_ARGS__))\n\n#define RELEASE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(release_capability(__VA_ARGS__))\n\n#define RELEASE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(release_shared_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(try_acquire_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(try_acquire_shared_capability(__VA_ARGS__))\n\n#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE_(locks_excluded(__VA_ARGS__))\n\n#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(assert_capability(x))\n\n#define ASSERT_SHARED_CAPABILITY(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(assert_shared_capability(x))\n\n#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(lock_returned(x))\n\n#define NO_THREAD_SAFETY_ANALYSIS \\\n  THREAD_ANNOTATION_ATTRIBUTE_(no_thread_safety_analysis)\n\nnamespace benchmark {\n\ntypedef std::condition_variable Condition;\n\n// NOTE: Wrappers for std::mutex and std::unique_lock are provided so that\n// we can annotate them with thread safety attributes and use the\n// -Wthread-safety warning with clang. The standard library types cannot be\n// used directly because they do not provide the required annotations.\nclass CAPABILITY(\"mutex\") Mutex {\n public:\n  Mutex() {}\n\n  void lock() ACQUIRE() { mut_.lock(); }\n  void unlock() RELEASE() { mut_.unlock(); }\n  std::mutex& native_handle() { return mut_; }\n\n private:\n  std::mutex mut_;\n};\n\nclass SCOPED_CAPABILITY MutexLock {\n  typedef std::unique_lock<std::mutex> MutexLockImp;\n\n public:\n  MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) {}\n  ~MutexLock() RELEASE() {}\n  MutexLockImp& native_handle() { return ml_; }\n\n private:\n  MutexLockImp ml_;\n};\n\nclass Barrier {\n public:\n  Barrier(int num_threads) : running_threads_(num_threads) {}\n\n  // Called by each thread\n  bool wait() EXCLUDES(lock_) {\n    bool last_thread = false;\n    {\n      MutexLock ml(lock_);\n      last_thread = createBarrier(ml);\n    }\n    if (last_thread) phase_condition_.notify_all();\n    return last_thread;\n  }\n\n  void removeThread() EXCLUDES(lock_) {\n    MutexLock ml(lock_);\n    --running_threads_;\n    if (entered_ != 0) phase_condition_.notify_all();\n  }\n\n private:\n  Mutex lock_;\n  Condition phase_condition_;\n  int running_threads_;\n\n  // State for barrier management\n  int phase_number_ = 0;\n  int entered_ = 0;  // Number of threads that have entered this barrier\n\n  // Enter the barrier and wait until all other threads have also\n  // entered the barrier.  Returns iff this is the last thread to\n  // enter the barrier.\n  bool createBarrier(MutexLock& ml) REQUIRES(lock_) {\n    BM_CHECK_LT(entered_, running_threads_);\n    entered_++;\n    if (entered_ < running_threads_) {\n      // Wait for all threads to enter\n      int phase_number_cp = phase_number_;\n      auto cb = [this, phase_number_cp]() {\n        return this->phase_number_ > phase_number_cp ||\n               entered_ == running_threads_;  // A thread has aborted in error\n      };\n      phase_condition_.wait(ml.native_handle(), cb);\n      if (phase_number_ > phase_number_cp) return false;\n      // else (running_threads_ == entered_) and we are the last thread.\n    }\n    // Last thread has reached the barrier\n    phase_number_++;\n    entered_ = 0;\n    return true;\n  }\n};\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_MUTEX_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/perf_counters.cc",
    "content": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"perf_counters.h\"\n\n#include <cstring>\n#include <memory>\n#include <vector>\n\n#if defined HAVE_LIBPFM\n#include \"perfmon/pfmlib.h\"\n#include \"perfmon/pfmlib_perf_event.h\"\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\nconstexpr size_t PerfCounterValues::kMaxCounters;\n\n#if defined HAVE_LIBPFM\n\nsize_t PerfCounterValues::Read(const std::vector<int>& leaders) {\n  // Create a pointer for multiple reads\n  const size_t bufsize = values_.size() * sizeof(values_[0]);\n  char* ptr = reinterpret_cast<char*>(values_.data());\n  size_t size = bufsize;\n  for (int lead : leaders) {\n    auto read_bytes = ::read(lead, ptr, size);\n    if (read_bytes >= ssize_t(sizeof(uint64_t))) {\n      // Actual data bytes are all bytes minus initial padding\n      std::size_t data_bytes =\n          static_cast<std::size_t>(read_bytes) - sizeof(uint64_t);\n      // This should be very cheap since it's in hot cache\n      std::memmove(ptr, ptr + sizeof(uint64_t), data_bytes);\n      // Increment our counters\n      ptr += data_bytes;\n      size -= data_bytes;\n    } else {\n      int err = errno;\n      GetErrorLogInstance() << \"Error reading lead \" << lead << \" errno:\" << err\n                            << \" \" << ::strerror(err) << \"\\n\";\n      return 0;\n    }\n  }\n  return (bufsize - size) / sizeof(uint64_t);\n}\n\nconst bool PerfCounters::kSupported = true;\n\n// Initializes libpfm only on the first call.  Returns whether that single\n// initialization was successful.\nbool PerfCounters::Initialize() {\n  // Function-scope static gets initialized only once on first call.\n  static const bool success = []() {\n    return pfm_initialize() == PFM_SUCCESS;\n  }();\n  return success;\n}\n\nbool PerfCounters::IsCounterSupported(const std::string& name) {\n  Initialize();\n  perf_event_attr_t attr;\n  std::memset(&attr, 0, sizeof(attr));\n  pfm_perf_encode_arg_t arg;\n  std::memset(&arg, 0, sizeof(arg));\n  arg.attr = &attr;\n  const int mode = PFM_PLM3;  // user mode only\n  int ret = pfm_get_os_event_encoding(name.c_str(), mode, PFM_OS_PERF_EVENT_EXT,\n                                      &arg);\n  return (ret == PFM_SUCCESS);\n}\n\nPerfCounters PerfCounters::Create(\n    const std::vector<std::string>& counter_names) {\n  if (!counter_names.empty()) {\n    Initialize();\n  }\n\n  // Valid counters will populate these arrays but we start empty\n  std::vector<std::string> valid_names;\n  std::vector<int> counter_ids;\n  std::vector<int> leader_ids;\n\n  // Resize to the maximum possible\n  valid_names.reserve(counter_names.size());\n  counter_ids.reserve(counter_names.size());\n\n  const int kCounterMode = PFM_PLM3;  // user mode only\n\n  // Group leads will be assigned on demand. The idea is that once we cannot\n  // create a counter descriptor, the reason is that this group has maxed out\n  // so we set the group_id again to -1 and retry - giving the algorithm a\n  // chance to create a new group leader to hold the next set of counters.\n  int group_id = -1;\n\n  // Loop through all performance counters\n  for (size_t i = 0; i < counter_names.size(); ++i) {\n    // we are about to push into the valid names vector\n    // check if we did not reach the maximum\n    if (valid_names.size() == PerfCounterValues::kMaxCounters) {\n      // Log a message if we maxed out and stop adding\n      GetErrorLogInstance()\n          << counter_names.size() << \" counters were requested. The maximum is \"\n          << PerfCounterValues::kMaxCounters << \" and \" << valid_names.size()\n          << \" were already added. All remaining counters will be ignored\\n\";\n      // stop the loop and return what we have already\n      break;\n    }\n\n    // Check if this name is empty\n    const auto& name = counter_names[i];\n    if (name.empty()) {\n      GetErrorLogInstance()\n          << \"A performance counter name was the empty string\\n\";\n      continue;\n    }\n\n    // Here first means first in group, ie the group leader\n    const bool is_first = (group_id < 0);\n\n    // This struct will be populated by libpfm from the counter string\n    // and then fed into the syscall perf_event_open\n    struct perf_event_attr attr {};\n    attr.size = sizeof(attr);\n\n    // This is the input struct to libpfm.\n    pfm_perf_encode_arg_t arg{};\n    arg.attr = &attr;\n    const int pfm_get = pfm_get_os_event_encoding(name.c_str(), kCounterMode,\n                                                  PFM_OS_PERF_EVENT, &arg);\n    if (pfm_get != PFM_SUCCESS) {\n      GetErrorLogInstance()\n          << \"Unknown performance counter name: \" << name << \"\\n\";\n      continue;\n    }\n\n    // We then proceed to populate the remaining fields in our attribute struct\n    // Note: the man page for perf_event_create suggests inherit = true and\n    // read_format = PERF_FORMAT_GROUP don't work together, but that's not the\n    // case.\n    attr.disabled = is_first;\n    attr.inherit = true;\n    attr.pinned = is_first;\n    attr.exclude_kernel = true;\n    attr.exclude_user = false;\n    attr.exclude_hv = true;\n\n    // Read all counters in a group in one read.\n    attr.read_format = PERF_FORMAT_GROUP;  //| PERF_FORMAT_TOTAL_TIME_ENABLED |\n                                           // PERF_FORMAT_TOTAL_TIME_RUNNING;\n\n    int id = -1;\n    while (id < 0) {\n      static constexpr size_t kNrOfSyscallRetries = 5;\n      // Retry syscall as it was interrupted often (b/64774091).\n      for (size_t num_retries = 0; num_retries < kNrOfSyscallRetries;\n           ++num_retries) {\n        id = perf_event_open(&attr, 0, -1, group_id, 0);\n        if (id >= 0 || errno != EINTR) {\n          break;\n        }\n      }\n      if (id < 0) {\n        // If the file descriptor is negative we might have reached a limit\n        // in the current group. Set the group_id to -1 and retry\n        if (group_id >= 0) {\n          // Create a new group\n          group_id = -1;\n        } else {\n          // At this point we have already retried to set a new group id and\n          // failed. We then give up.\n          break;\n        }\n      }\n    }\n\n    // We failed to get a new file descriptor. We might have reached a hard\n    // hardware limit that cannot be resolved even with group multiplexing\n    if (id < 0) {\n      GetErrorLogInstance() << \"***WARNING** Failed to get a file descriptor \"\n                               \"for performance counter \"\n                            << name << \". Ignoring\\n\";\n\n      // We give up on this counter but try to keep going\n      // as the others would be fine\n      continue;\n    }\n    if (group_id < 0) {\n      // This is a leader, store and assign it to the current file descriptor\n      leader_ids.push_back(id);\n      group_id = id;\n    }\n    // This is a valid counter, add it to our descriptor's list\n    counter_ids.push_back(id);\n    valid_names.push_back(name);\n  }\n\n  // Loop through all group leaders activating them\n  // There is another option of starting ALL counters in a process but\n  // that would be far reaching an intrusion. If the user is using PMCs\n  // by themselves then this would have a side effect on them. It is\n  // friendlier to loop through all groups individually.\n  for (int lead : leader_ids) {\n    if (ioctl(lead, PERF_EVENT_IOC_ENABLE) != 0) {\n      // This should never happen but if it does, we give up on the\n      // entire batch as recovery would be a mess.\n      GetErrorLogInstance() << \"***WARNING*** Failed to start counters. \"\n                               \"Claring out all counters.\\n\";\n\n      // Close all peformance counters\n      for (int id : counter_ids) {\n        ::close(id);\n      }\n\n      // Return an empty object so our internal state is still good and\n      // the process can continue normally without impact\n      return NoCounters();\n    }\n  }\n\n  return PerfCounters(std::move(valid_names), std::move(counter_ids),\n                      std::move(leader_ids));\n}\n\nvoid PerfCounters::CloseCounters() const {\n  if (counter_ids_.empty()) {\n    return;\n  }\n  for (int lead : leader_ids_) {\n    ioctl(lead, PERF_EVENT_IOC_DISABLE);\n  }\n  for (int fd : counter_ids_) {\n    close(fd);\n  }\n}\n#else   // defined HAVE_LIBPFM\nsize_t PerfCounterValues::Read(const std::vector<int>&) { return 0; }\n\nconst bool PerfCounters::kSupported = false;\n\nbool PerfCounters::Initialize() { return false; }\n\nbool PerfCounters::IsCounterSupported(const std::string&) { return false; }\n\nPerfCounters PerfCounters::Create(\n    const std::vector<std::string>& counter_names) {\n  if (!counter_names.empty()) {\n    GetErrorLogInstance() << \"Performance counters not supported.\\n\";\n  }\n  return NoCounters();\n}\n\nvoid PerfCounters::CloseCounters() const {}\n#endif  // defined HAVE_LIBPFM\n\nPerfCountersMeasurement::PerfCountersMeasurement(\n    const std::vector<std::string>& counter_names)\n    : start_values_(counter_names.size()), end_values_(counter_names.size()) {\n  counters_ = PerfCounters::Create(counter_names);\n}\n\nPerfCounters& PerfCounters::operator=(PerfCounters&& other) noexcept {\n  if (this != &other) {\n    CloseCounters();\n\n    counter_ids_ = std::move(other.counter_ids_);\n    leader_ids_ = std::move(other.leader_ids_);\n    counter_names_ = std::move(other.counter_names_);\n  }\n  return *this;\n}\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/perf_counters.h",
    "content": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_PERF_COUNTERS_H\n#define BENCHMARK_PERF_COUNTERS_H\n\n#include <array>\n#include <cstdint>\n#include <cstring>\n#include <memory>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#include <unistd.h>\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n// C4251: <symbol> needs to have dll-interface to be used by clients of class\n#pragma warning(disable : 4251)\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\n// Typically, we can only read a small number of counters. There is also a\n// padding preceding counter values, when reading multiple counters with one\n// syscall (which is desirable). PerfCounterValues abstracts these details.\n// The implementation ensures the storage is inlined, and allows 0-based\n// indexing into the counter values.\n// The object is used in conjunction with a PerfCounters object, by passing it\n// to Snapshot(). The Read() method relocates individual reads, discarding\n// the initial padding from each group leader in the values buffer such that\n// all user accesses through the [] operator are correct.\nclass BENCHMARK_EXPORT PerfCounterValues {\n public:\n  explicit PerfCounterValues(size_t nr_counters) : nr_counters_(nr_counters) {\n    BM_CHECK_LE(nr_counters_, kMaxCounters);\n  }\n\n  // We are reading correctly now so the values don't need to skip padding\n  uint64_t operator[](size_t pos) const { return values_[pos]; }\n\n  // Increased the maximum to 32 only since the buffer\n  // is std::array<> backed\n  static constexpr size_t kMaxCounters = 32;\n\n private:\n  friend class PerfCounters;\n  // Get the byte buffer in which perf counters can be captured.\n  // This is used by PerfCounters::Read\n  std::pair<char*, size_t> get_data_buffer() {\n    return {reinterpret_cast<char*>(values_.data()),\n            sizeof(uint64_t) * (kPadding + nr_counters_)};\n  }\n\n  // This reading is complex and as the goal of this class is to\n  // abstract away the intrincacies of the reading process, this is\n  // a better place for it\n  size_t Read(const std::vector<int>& leaders);\n\n  // Move the padding to 2 due to the reading algorithm (1st padding plus a\n  // current read padding)\n  static constexpr size_t kPadding = 2;\n  std::array<uint64_t, kPadding + kMaxCounters> values_;\n  const size_t nr_counters_;\n};\n\n// Collect PMU counters. The object, once constructed, is ready to be used by\n// calling read(). PMU counter collection is enabled from the time create() is\n// called, to obtain the object, until the object's destructor is called.\nclass BENCHMARK_EXPORT PerfCounters final {\n public:\n  // True iff this platform supports performance counters.\n  static const bool kSupported;\n\n  // Returns an empty object\n  static PerfCounters NoCounters() { return PerfCounters(); }\n\n  ~PerfCounters() { CloseCounters(); }\n  PerfCounters() = default;\n  PerfCounters(PerfCounters&&) = default;\n  PerfCounters(const PerfCounters&) = delete;\n  PerfCounters& operator=(PerfCounters&&) noexcept;\n  PerfCounters& operator=(const PerfCounters&) = delete;\n\n  // Platform-specific implementations may choose to do some library\n  // initialization here.\n  static bool Initialize();\n\n  // Check if the given counter is supported, if the app wants to\n  // check before passing\n  static bool IsCounterSupported(const std::string& name);\n\n  // Return a PerfCounters object ready to read the counters with the names\n  // specified. The values are user-mode only. The counter name format is\n  // implementation and OS specific.\n  // In case of failure, this method will in the worst case return an\n  // empty object whose state will still be valid.\n  static PerfCounters Create(const std::vector<std::string>& counter_names);\n\n  // Take a snapshot of the current value of the counters into the provided\n  // valid PerfCounterValues storage. The values are populated such that:\n  // names()[i]'s value is (*values)[i]\n  BENCHMARK_ALWAYS_INLINE bool Snapshot(PerfCounterValues* values) const {\n#ifndef BENCHMARK_OS_WINDOWS\n    assert(values != nullptr);\n    return values->Read(leader_ids_) == counter_ids_.size();\n#else\n    (void)values;\n    return false;\n#endif\n  }\n\n  const std::vector<std::string>& names() const { return counter_names_; }\n  size_t num_counters() const { return counter_names_.size(); }\n\n private:\n  PerfCounters(const std::vector<std::string>& counter_names,\n               std::vector<int>&& counter_ids, std::vector<int>&& leader_ids)\n      : counter_ids_(std::move(counter_ids)),\n        leader_ids_(std::move(leader_ids)),\n        counter_names_(counter_names) {}\n\n  void CloseCounters() const;\n\n  std::vector<int> counter_ids_;\n  std::vector<int> leader_ids_;\n  std::vector<std::string> counter_names_;\n};\n\n// Typical usage of the above primitives.\nclass BENCHMARK_EXPORT PerfCountersMeasurement final {\n public:\n  PerfCountersMeasurement(const std::vector<std::string>& counter_names);\n\n  size_t num_counters() const { return counters_.num_counters(); }\n\n  std::vector<std::string> names() const { return counters_.names(); }\n\n  BENCHMARK_ALWAYS_INLINE bool Start() {\n    if (num_counters() == 0) return true;\n    // Tell the compiler to not move instructions above/below where we take\n    // the snapshot.\n    ClobberMemory();\n    valid_read_ &= counters_.Snapshot(&start_values_);\n    ClobberMemory();\n\n    return valid_read_;\n  }\n\n  BENCHMARK_ALWAYS_INLINE bool Stop(\n      std::vector<std::pair<std::string, double>>& measurements) {\n    if (num_counters() == 0) return true;\n    // Tell the compiler to not move instructions above/below where we take\n    // the snapshot.\n    ClobberMemory();\n    valid_read_ &= counters_.Snapshot(&end_values_);\n    ClobberMemory();\n\n    for (size_t i = 0; i < counters_.names().size(); ++i) {\n      double measurement = static_cast<double>(end_values_[i]) -\n                           static_cast<double>(start_values_[i]);\n      measurements.push_back({counters_.names()[i], measurement});\n    }\n\n    return valid_read_;\n  }\n\n private:\n  PerfCounters counters_;\n  bool valid_read_ = true;\n  PerfCounterValues start_values_;\n  PerfCounterValues end_values_;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#endif  // BENCHMARK_PERF_COUNTERS_H\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/re.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_RE_H_\n#define BENCHMARK_RE_H_\n\n#include \"internal_macros.h\"\n\n// clang-format off\n\n#if !defined(HAVE_STD_REGEX) && \\\n    !defined(HAVE_GNU_POSIX_REGEX) && \\\n    !defined(HAVE_POSIX_REGEX)\n  // No explicit regex selection; detect based on builtin hints.\n  #if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)\n    #define HAVE_POSIX_REGEX 1\n  #elif __cplusplus >= 199711L\n    #define HAVE_STD_REGEX 1\n  #endif\n#endif\n\n// Prefer C regex libraries when compiling w/o exceptions so that we can\n// correctly report errors.\n#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \\\n    defined(HAVE_STD_REGEX) && \\\n    (defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))\n  #undef HAVE_STD_REGEX\n#endif\n\n#if defined(HAVE_STD_REGEX)\n  #include <regex>\n#elif defined(HAVE_GNU_POSIX_REGEX)\n  #include <gnuregex.h>\n#elif defined(HAVE_POSIX_REGEX)\n  #include <regex.h>\n#else\n#error No regular expression backend was found!\n#endif\n\n// clang-format on\n\n#include <string>\n\n#include \"check.h\"\n\nnamespace benchmark {\n\n// A wrapper around the POSIX regular expression API that provides automatic\n// cleanup\nclass Regex {\n public:\n  Regex() : init_(false) {}\n\n  ~Regex();\n\n  // Compile a regular expression matcher from spec.  Returns true on success.\n  //\n  // On failure (and if error is not nullptr), error is populated with a human\n  // readable error message if an error occurs.\n  bool Init(const std::string& spec, std::string* error);\n\n  // Returns whether str matches the compiled regular expression.\n  bool Match(const std::string& str);\n\n private:\n  bool init_;\n// Underlying regular expression object\n#if defined(HAVE_STD_REGEX)\n  std::regex re_;\n#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)\n  regex_t re_;\n#else\n#error No regular expression backend implementation available\n#endif\n};\n\n#if defined(HAVE_STD_REGEX)\n\ninline bool Regex::Init(const std::string& spec, std::string* error) {\n#ifdef BENCHMARK_HAS_NO_EXCEPTIONS\n  ((void)error);  // suppress unused warning\n#else\n  try {\n#endif\n  re_ = std::regex(spec, std::regex_constants::extended);\n  init_ = true;\n#ifndef BENCHMARK_HAS_NO_EXCEPTIONS\n}\ncatch (const std::regex_error& e) {\n  if (error) {\n    *error = e.what();\n  }\n}\n#endif\nreturn init_;\n}\n\ninline Regex::~Regex() {}\n\ninline bool Regex::Match(const std::string& str) {\n  if (!init_) {\n    return false;\n  }\n  return std::regex_search(str, re_);\n}\n\n#else\ninline bool Regex::Init(const std::string& spec, std::string* error) {\n  int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    if (error) {\n      size_t needed = regerror(ec, &re_, nullptr, 0);\n      char* errbuf = new char[needed];\n      regerror(ec, &re_, errbuf, needed);\n\n      // regerror returns the number of bytes necessary to null terminate\n      // the string, so we move that when assigning to error.\n      BM_CHECK_NE(needed, 0);\n      error->assign(errbuf, needed - 1);\n\n      delete[] errbuf;\n    }\n\n    return false;\n  }\n\n  init_ = true;\n  return true;\n}\n\ninline Regex::~Regex() {\n  if (init_) {\n    regfree(&re_);\n  }\n}\n\ninline bool Regex::Match(const std::string& str) {\n  if (!init_) {\n    return false;\n  }\n  return regexec(&re_, str.c_str(), 0, nullptr, 0) == 0;\n}\n#endif\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_RE_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <cstdlib>\n#include <iostream>\n#include <map>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nBenchmarkReporter::BenchmarkReporter()\n    : output_stream_(&std::cout), error_stream_(&std::cerr) {}\n\nBenchmarkReporter::~BenchmarkReporter() {}\n\nvoid BenchmarkReporter::PrintBasicContext(std::ostream *out,\n                                          Context const &context) {\n  BM_CHECK(out) << \"cannot be null\";\n  auto &Out = *out;\n\n#ifndef BENCHMARK_OS_QURT\n  // Date/time information is not available on QuRT.\n  // Attempting to get it via this call cause the binary to crash.\n  Out << LocalDateTimeString() << \"\\n\";\n#endif\n\n  if (context.executable_name)\n    Out << \"Running \" << context.executable_name << \"\\n\";\n\n  const CPUInfo &info = context.cpu_info;\n  Out << \"Run on (\" << info.num_cpus << \" X \"\n      << (info.cycles_per_second / 1000000.0) << \" MHz CPU \"\n      << ((info.num_cpus > 1) ? \"s\" : \"\") << \")\\n\";\n  if (info.caches.size() != 0) {\n    Out << \"CPU Caches:\\n\";\n    for (auto &CInfo : info.caches) {\n      Out << \"  L\" << CInfo.level << \" \" << CInfo.type << \" \"\n          << (CInfo.size / 1024) << \" KiB\";\n      if (CInfo.num_sharing != 0)\n        Out << \" (x\" << (info.num_cpus / CInfo.num_sharing) << \")\";\n      Out << \"\\n\";\n    }\n  }\n  if (!info.load_avg.empty()) {\n    Out << \"Load Average: \";\n    for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {\n      Out << StrFormat(\"%.2f\", *It++);\n      if (It != info.load_avg.end()) Out << \", \";\n    }\n    Out << \"\\n\";\n  }\n\n  std::map<std::string, std::string> *global_context =\n      internal::GetGlobalContext();\n\n  if (global_context != nullptr) {\n    for (const auto &kv : *global_context) {\n      Out << kv.first << \": \" << kv.second << \"\\n\";\n    }\n  }\n\n  if (CPUInfo::Scaling::ENABLED == info.scaling) {\n    Out << \"***WARNING*** CPU scaling is enabled, the benchmark \"\n           \"real time measurements may be noisy and will incur extra \"\n           \"overhead.\\n\";\n  }\n\n#ifndef NDEBUG\n  Out << \"***WARNING*** Library was built as DEBUG. Timings may be \"\n         \"affected.\\n\";\n#endif\n}\n\n// No initializer because it's already initialized to NULL.\nconst char *BenchmarkReporter::Context::executable_name;\n\nBenchmarkReporter::Context::Context()\n    : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}\n\nstd::string BenchmarkReporter::Run::benchmark_name() const {\n  std::string name = run_name.str();\n  if (run_type == RT_Aggregate) {\n    name += \"_\" + aggregate_name;\n  }\n  return name;\n}\n\ndouble BenchmarkReporter::Run::GetAdjustedRealTime() const {\n  double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);\n  if (iterations != 0) new_time /= static_cast<double>(iterations);\n  return new_time;\n}\n\ndouble BenchmarkReporter::Run::GetAdjustedCPUTime() const {\n  double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit);\n  if (iterations != 0) new_time /= static_cast<double>(iterations);\n  return new_time;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/statistics.cc",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"statistics.h\"\n\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n\nnamespace benchmark {\n\nauto StatisticsSum = [](const std::vector<double>& v) {\n  return std::accumulate(v.begin(), v.end(), 0.0);\n};\n\ndouble StatisticsMean(const std::vector<double>& v) {\n  if (v.empty()) return 0.0;\n  return StatisticsSum(v) * (1.0 / static_cast<double>(v.size()));\n}\n\ndouble StatisticsMedian(const std::vector<double>& v) {\n  if (v.size() < 3) return StatisticsMean(v);\n  std::vector<double> copy(v);\n\n  auto center = copy.begin() + v.size() / 2;\n  std::nth_element(copy.begin(), center, copy.end());\n\n  // Did we have an odd number of samples?  If yes, then center is the median.\n  // If not, then we are looking for the average between center and the value\n  // before.  Instead of resorting, we just look for the max value before it,\n  // which is not necessarily the element immediately preceding `center` Since\n  // `copy` is only partially sorted by `nth_element`.\n  if (v.size() % 2 == 1) return *center;\n  auto center2 = std::max_element(copy.begin(), center);\n  return (*center + *center2) / 2.0;\n}\n\n// Return the sum of the squares of this sample set\nauto SumSquares = [](const std::vector<double>& v) {\n  return std::inner_product(v.begin(), v.end(), v.begin(), 0.0);\n};\n\nauto Sqr = [](const double dat) { return dat * dat; };\nauto Sqrt = [](const double dat) {\n  // Avoid NaN due to imprecision in the calculations\n  if (dat < 0.0) return 0.0;\n  return std::sqrt(dat);\n};\n\ndouble StatisticsStdDev(const std::vector<double>& v) {\n  const auto mean = StatisticsMean(v);\n  if (v.empty()) return mean;\n\n  // Sample standard deviation is undefined for n = 1\n  if (v.size() == 1) return 0.0;\n\n  const double avg_squares =\n      SumSquares(v) * (1.0 / static_cast<double>(v.size()));\n  return Sqrt(static_cast<double>(v.size()) /\n              (static_cast<double>(v.size()) - 1.0) *\n              (avg_squares - Sqr(mean)));\n}\n\ndouble StatisticsCV(const std::vector<double>& v) {\n  if (v.size() < 2) return 0.0;\n\n  const auto stddev = StatisticsStdDev(v);\n  const auto mean = StatisticsMean(v);\n\n  if (std::fpclassify(mean) == FP_ZERO) return 0.0;\n\n  return stddev / mean;\n}\n\nstd::vector<BenchmarkReporter::Run> ComputeStats(\n    const std::vector<BenchmarkReporter::Run>& reports) {\n  typedef BenchmarkReporter::Run Run;\n  std::vector<Run> results;\n\n  auto error_count = std::count_if(reports.begin(), reports.end(),\n                                   [](Run const& run) { return run.skipped; });\n\n  if (reports.size() - static_cast<size_t>(error_count) < 2) {\n    // We don't report aggregated data if there was a single run.\n    return results;\n  }\n\n  // Accumulators.\n  std::vector<double> real_accumulated_time_stat;\n  std::vector<double> cpu_accumulated_time_stat;\n\n  real_accumulated_time_stat.reserve(reports.size());\n  cpu_accumulated_time_stat.reserve(reports.size());\n\n  // All repetitions should be run with the same number of iterations so we\n  // can take this information from the first benchmark.\n  const IterationCount run_iterations = reports.front().iterations;\n  // create stats for user counters\n  struct CounterStat {\n    Counter c;\n    std::vector<double> s;\n  };\n  std::map<std::string, CounterStat> counter_stats;\n  for (Run const& r : reports) {\n    for (auto const& cnt : r.counters) {\n      auto it = counter_stats.find(cnt.first);\n      if (it == counter_stats.end()) {\n        it = counter_stats\n                 .emplace(cnt.first,\n                          CounterStat{cnt.second, std::vector<double>{}})\n                 .first;\n        it->second.s.reserve(reports.size());\n      } else {\n        BM_CHECK_EQ(it->second.c.flags, cnt.second.flags);\n      }\n    }\n  }\n\n  // Populate the accumulators.\n  for (Run const& run : reports) {\n    BM_CHECK_EQ(reports[0].benchmark_name(), run.benchmark_name());\n    BM_CHECK_EQ(run_iterations, run.iterations);\n    if (run.skipped) continue;\n    real_accumulated_time_stat.emplace_back(run.real_accumulated_time);\n    cpu_accumulated_time_stat.emplace_back(run.cpu_accumulated_time);\n    // user counters\n    for (auto const& cnt : run.counters) {\n      auto it = counter_stats.find(cnt.first);\n      BM_CHECK_NE(it, counter_stats.end());\n      it->second.s.emplace_back(cnt.second);\n    }\n  }\n\n  // Only add label if it is same for all runs\n  std::string report_label = reports[0].report_label;\n  for (std::size_t i = 1; i < reports.size(); i++) {\n    if (reports[i].report_label != report_label) {\n      report_label = \"\";\n      break;\n    }\n  }\n\n  const double iteration_rescale_factor =\n      double(reports.size()) / double(run_iterations);\n\n  for (const auto& Stat : *reports[0].statistics) {\n    // Get the data from the accumulator to BenchmarkReporter::Run's.\n    Run data;\n    data.run_name = reports[0].run_name;\n    data.family_index = reports[0].family_index;\n    data.per_family_instance_index = reports[0].per_family_instance_index;\n    data.run_type = BenchmarkReporter::Run::RT_Aggregate;\n    data.threads = reports[0].threads;\n    data.repetitions = reports[0].repetitions;\n    data.repetition_index = Run::no_repetition_index;\n    data.aggregate_name = Stat.name_;\n    data.aggregate_unit = Stat.unit_;\n    data.report_label = report_label;\n\n    // It is incorrect to say that an aggregate is computed over\n    // run's iterations, because those iterations already got averaged.\n    // Similarly, if there are N repetitions with 1 iterations each,\n    // an aggregate will be computed over N measurements, not 1.\n    // Thus it is best to simply use the count of separate reports.\n    data.iterations = static_cast<IterationCount>(reports.size());\n\n    data.real_accumulated_time = Stat.compute_(real_accumulated_time_stat);\n    data.cpu_accumulated_time = Stat.compute_(cpu_accumulated_time_stat);\n\n    if (data.aggregate_unit == StatisticUnit::kTime) {\n      // We will divide these times by data.iterations when reporting, but the\n      // data.iterations is not necessarily the scale of these measurements,\n      // because in each repetition, these timers are sum over all the iters.\n      // And if we want to say that the stats are over N repetitions and not\n      // M iterations, we need to multiply these by (N/M).\n      data.real_accumulated_time *= iteration_rescale_factor;\n      data.cpu_accumulated_time *= iteration_rescale_factor;\n    }\n\n    data.time_unit = reports[0].time_unit;\n\n    // user counters\n    for (auto const& kv : counter_stats) {\n      // Do *NOT* rescale the custom counters. They are already properly scaled.\n      const auto uc_stat = Stat.compute_(kv.second.s);\n      auto c = Counter(uc_stat, counter_stats[kv.first].c.flags,\n                       counter_stats[kv.first].c.oneK);\n      data.counters[kv.first] = c;\n    }\n\n    results.push_back(data);\n  }\n\n  return results;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/statistics.h",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef STATISTICS_H_\n#define STATISTICS_H_\n\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// Return a vector containing the mean, median and standard deviation\n// information (and any user-specified info) for the specified list of reports.\n// If 'reports' contains less than two non-errored runs an empty vector is\n// returned\nBENCHMARK_EXPORT\nstd::vector<BenchmarkReporter::Run> ComputeStats(\n    const std::vector<BenchmarkReporter::Run>& reports);\n\nBENCHMARK_EXPORT\ndouble StatisticsMean(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsMedian(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsStdDev(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsCV(const std::vector<double>& v);\n\n}  // end namespace benchmark\n\n#endif  // STATISTICS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/string_util.cc",
    "content": "#include \"string_util.h\"\n\n#include <array>\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n#include <cerrno>\n#endif\n#include <cmath>\n#include <cstdarg>\n#include <cstdio>\n#include <memory>\n#include <sstream>\n\n#include \"arraysize.h\"\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\nnamespace {\n// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.\nconst char* const kBigSIUnits[] = {\"k\", \"M\", \"G\", \"T\", \"P\", \"E\", \"Z\", \"Y\"};\n// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.\nconst char* const kBigIECUnits[] = {\"Ki\", \"Mi\", \"Gi\", \"Ti\",\n                                    \"Pi\", \"Ei\", \"Zi\", \"Yi\"};\n// milli, micro, nano, pico, femto, atto, zepto, yocto.\nconst char* const kSmallSIUnits[] = {\"m\", \"u\", \"n\", \"p\", \"f\", \"a\", \"z\", \"y\"};\n\n// We require that all three arrays have the same size.\nstatic_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),\n              \"SI and IEC unit arrays must be the same size\");\nstatic_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),\n              \"Small SI and Big SI unit arrays must be the same size\");\n\nstatic const int64_t kUnitsSize = arraysize(kBigSIUnits);\n\nvoid ToExponentAndMantissa(double val, int precision, double one_k,\n                           std::string* mantissa, int64_t* exponent) {\n  std::stringstream mantissa_stream;\n\n  if (val < 0) {\n    mantissa_stream << \"-\";\n    val = -val;\n  }\n\n  // Adjust threshold so that it never excludes things which can't be rendered\n  // in 'precision' digits.\n  const double adjusted_threshold =\n      std::max(1.0, 1.0 / std::pow(10.0, precision));\n  const double big_threshold = (adjusted_threshold * one_k) - 1;\n  const double small_threshold = adjusted_threshold;\n  // Values in ]simple_threshold,small_threshold[ will be printed as-is\n  const double simple_threshold = 0.01;\n\n  if (val > big_threshold) {\n    // Positive powers\n    double scaled = val;\n    for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {\n      scaled /= one_k;\n      if (scaled <= big_threshold) {\n        mantissa_stream << scaled;\n        *exponent = static_cast<int64_t>(i + 1);\n        *mantissa = mantissa_stream.str();\n        return;\n      }\n    }\n    mantissa_stream << val;\n    *exponent = 0;\n  } else if (val < small_threshold) {\n    // Negative powers\n    if (val < simple_threshold) {\n      double scaled = val;\n      for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {\n        scaled *= one_k;\n        if (scaled >= small_threshold) {\n          mantissa_stream << scaled;\n          *exponent = -static_cast<int64_t>(i + 1);\n          *mantissa = mantissa_stream.str();\n          return;\n        }\n      }\n    }\n    mantissa_stream << val;\n    *exponent = 0;\n  } else {\n    mantissa_stream << val;\n    *exponent = 0;\n  }\n  *mantissa = mantissa_stream.str();\n}\n\nstd::string ExponentToPrefix(int64_t exponent, bool iec) {\n  if (exponent == 0) return \"\";\n\n  const int64_t index = (exponent > 0 ? exponent - 1 : -exponent - 1);\n  if (index >= kUnitsSize) return \"\";\n\n  const char* const* array =\n      (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);\n\n  return std::string(array[index]);\n}\n\nstd::string ToBinaryStringFullySpecified(double value, int precision,\n                                         Counter::OneK one_k) {\n  std::string mantissa;\n  int64_t exponent;\n  ToExponentAndMantissa(value, precision,\n                        one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa,\n                        &exponent);\n  return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);\n}\n\nstd::string StrFormatImp(const char* msg, va_list args) {\n  // we might need a second shot at this, so pre-emptivly make a copy\n  va_list args_cp;\n  va_copy(args_cp, args);\n\n  // TODO(ericwf): use std::array for first attempt to avoid one memory\n  // allocation guess what the size might be\n  std::array<char, 256> local_buff;\n\n  // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation\n  // in the android-ndk\n  auto ret = vsnprintf(local_buff.data(), local_buff.size(), msg, args_cp);\n\n  va_end(args_cp);\n\n  // handle empty expansion\n  if (ret == 0) return std::string{};\n  if (static_cast<std::size_t>(ret) < local_buff.size())\n    return std::string(local_buff.data());\n\n  // we did not provide a long enough buffer on our first attempt.\n  // add 1 to size to account for null-byte in size cast to prevent overflow\n  std::size_t size = static_cast<std::size_t>(ret) + 1;\n  auto buff_ptr = std::unique_ptr<char[]>(new char[size]);\n  // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation\n  // in the android-ndk\n  vsnprintf(buff_ptr.get(), size, msg, args);\n  return std::string(buff_ptr.get());\n}\n\n}  // end namespace\n\nstd::string HumanReadableNumber(double n, Counter::OneK one_k) {\n  return ToBinaryStringFullySpecified(n, 1, one_k);\n}\n\nstd::string StrFormat(const char* format, ...) {\n  va_list args;\n  va_start(args, format);\n  std::string tmp = StrFormatImp(format, args);\n  va_end(args);\n  return tmp;\n}\n\nstd::vector<std::string> StrSplit(const std::string& str, char delim) {\n  if (str.empty()) return {};\n  std::vector<std::string> ret;\n  size_t first = 0;\n  size_t next = str.find(delim);\n  for (; next != std::string::npos;\n       first = next + 1, next = str.find(delim, first)) {\n    ret.push_back(str.substr(first, next - first));\n  }\n  ret.push_back(str.substr(first));\n  return ret;\n}\n\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n/*\n * GNU STL in Android NDK lacks support for some C++11 functions, including\n * stoul, stoi, stod. We reimplement them here using C functions strtoul,\n * strtol, strtod. Note that reimplemented functions are in benchmark::\n * namespace, not std:: namespace.\n */\nunsigned long stoul(const std::string& str, size_t* pos, int base) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const unsigned long result = strtoul(strStart, &strEnd, base);\n\n  const int strtoulErrno = errno;\n  /* Restore previous errno */\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtoulErrno == ERANGE) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of unsigned long\");\n  } else if (strEnd == strStart || strtoulErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return result;\n}\n\nint stoi(const std::string& str, size_t* pos, int base) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const long result = strtol(strStart, &strEnd, base);\n\n  const int strtolErrno = errno;\n  /* Restore previous errno */\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtolErrno == ERANGE || long(int(result)) != result) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of int\");\n  } else if (strEnd == strStart || strtolErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return int(result);\n}\n\ndouble stod(const std::string& str, size_t* pos) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const double result = strtod(strStart, &strEnd);\n\n  /* Restore previous errno */\n  const int strtodErrno = errno;\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtodErrno == ERANGE) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of int\");\n  } else if (strEnd == strStart || strtodErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return result;\n}\n#endif\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/string_util.h",
    "content": "#ifndef BENCHMARK_STRING_UTIL_H_\n#define BENCHMARK_STRING_UTIL_H_\n\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark/export.h\"\n#include \"check.h\"\n#include \"internal_macros.h\"\n\nnamespace benchmark {\n\nBENCHMARK_EXPORT\nstd::string HumanReadableNumber(double n, Counter::OneK one_k);\n\nBENCHMARK_EXPORT\n#if defined(__MINGW32__)\n__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2)))\n#elif defined(__GNUC__)\n__attribute__((format(printf, 1, 2)))\n#endif\nstd::string\nStrFormat(const char* format, ...);\n\ninline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {\n  return out;\n}\n\ntemplate <class First, class... Rest>\ninline std::ostream& StrCatImp(std::ostream& out, First&& f, Rest&&... rest) {\n  out << std::forward<First>(f);\n  return StrCatImp(out, std::forward<Rest>(rest)...);\n}\n\ntemplate <class... Args>\ninline std::string StrCat(Args&&... args) {\n  std::ostringstream ss;\n  StrCatImp(ss, std::forward<Args>(args)...);\n  return ss.str();\n}\n\nBENCHMARK_EXPORT\nstd::vector<std::string> StrSplit(const std::string& str, char delim);\n\n// Disable lint checking for this block since it re-implements C functions.\n// NOLINTBEGIN\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n/*\n * GNU STL in Android NDK lacks support for some C++11 functions, including\n * stoul, stoi, stod. We reimplement them here using C functions strtoul,\n * strtol, strtod. Note that reimplemented functions are in benchmark::\n * namespace, not std:: namespace.\n */\nunsigned long stoul(const std::string& str, size_t* pos = nullptr,\n                    int base = 10);\nint stoi(const std::string& str, size_t* pos = nullptr, int base = 10);\ndouble stod(const std::string& str, size_t* pos = nullptr);\n#else\nusing std::stod;   // NOLINT(misc-unused-using-decls)\nusing std::stoi;   // NOLINT(misc-unused-using-decls)\nusing std::stoul;  // NOLINT(misc-unused-using-decls)\n#endif\n// NOLINTEND\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_STRING_UTIL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/sysinfo.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#if !defined(WINVER) || WINVER < 0x0600\n#undef WINVER\n#define WINVER 0x0600\n#endif  // WINVER handling\n#include <shlwapi.h>\n#undef StrCat  // Don't let StrCat in string_util.h be renamed to lstrcatA\n#include <versionhelpers.h>\n#include <windows.h>\n\n#include <codecvt>\n#else\n#include <fcntl.h>\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <sys/types.h>  // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD\n#include <unistd.h>\n#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX || \\\n    defined BENCHMARK_OS_NETBSD || defined BENCHMARK_OS_OPENBSD || \\\n    defined BENCHMARK_OS_DRAGONFLY\n#define BENCHMARK_HAS_SYSCTL\n#include <sys/sysctl.h>\n#endif\n#endif\n#if defined(BENCHMARK_OS_SOLARIS)\n#include <kstat.h>\n#include <netdb.h>\n#endif\n#if defined(BENCHMARK_OS_QNX)\n#include <sys/syspage.h>\n#endif\n#if defined(BENCHMARK_OS_QURT)\n#include <qurt.h>\n#endif\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n#include <pthread.h>\n#endif\n\n#include <algorithm>\n#include <array>\n#include <bitset>\n#include <cerrno>\n#include <climits>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <iterator>\n#include <limits>\n#include <locale>\n#include <memory>\n#include <random>\n#include <sstream>\n#include <utility>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"cycleclock.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace {\n\nvoid PrintImp(std::ostream& out) { out << std::endl; }\n\ntemplate <class First, class... Rest>\nvoid PrintImp(std::ostream& out, First&& f, Rest&&... rest) {\n  out << std::forward<First>(f);\n  PrintImp(out, std::forward<Rest>(rest)...);\n}\n\ntemplate <class... Args>\nBENCHMARK_NORETURN void PrintErrorAndDie(Args&&... args) {\n  PrintImp(std::cerr, std::forward<Args>(args)...);\n  std::exit(EXIT_FAILURE);\n}\n\n#ifdef BENCHMARK_HAS_SYSCTL\n\n/// ValueUnion - A type used to correctly alias the byte-for-byte output of\n/// `sysctl` with the result type it's to be interpreted as.\nstruct ValueUnion {\n  union DataT {\n    int32_t int32_value;\n    int64_t int64_value;\n    // For correct aliasing of union members from bytes.\n    char bytes[8];\n  };\n  using DataPtr = std::unique_ptr<DataT, decltype(&std::free)>;\n\n  // The size of the data union member + its trailing array size.\n  std::size_t size;\n  DataPtr buff;\n\n public:\n  ValueUnion() : size(0), buff(nullptr, &std::free) {}\n\n  explicit ValueUnion(std::size_t buff_size)\n      : size(sizeof(DataT) + buff_size),\n        buff(::new (std::malloc(size)) DataT(), &std::free) {}\n\n  ValueUnion(ValueUnion&& other) = default;\n\n  explicit operator bool() const { return bool(buff); }\n\n  char* data() const { return buff->bytes; }\n\n  std::string GetAsString() const { return std::string(data()); }\n\n  int64_t GetAsInteger() const {\n    if (size == sizeof(buff->int32_value))\n      return buff->int32_value;\n    else if (size == sizeof(buff->int64_value))\n      return buff->int64_value;\n    BENCHMARK_UNREACHABLE();\n  }\n\n  template <class T, int N>\n  std::array<T, N> GetAsArray() {\n    const int arr_size = sizeof(T) * N;\n    BM_CHECK_LE(arr_size, size);\n    std::array<T, N> arr;\n    std::memcpy(arr.data(), data(), arr_size);\n    return arr;\n  }\n};\n\nValueUnion GetSysctlImp(std::string const& name) {\n#if defined BENCHMARK_OS_OPENBSD\n  int mib[2];\n\n  mib[0] = CTL_HW;\n  if ((name == \"hw.ncpu\") || (name == \"hw.cpuspeed\")) {\n    ValueUnion buff(sizeof(int));\n\n    if (name == \"hw.ncpu\") {\n      mib[1] = HW_NCPU;\n    } else {\n      mib[1] = HW_CPUSPEED;\n    }\n\n    if (sysctl(mib, 2, buff.data(), &buff.size, nullptr, 0) == -1) {\n      return ValueUnion();\n    }\n    return buff;\n  }\n  return ValueUnion();\n#else\n  std::size_t cur_buff_size = 0;\n  if (sysctlbyname(name.c_str(), nullptr, &cur_buff_size, nullptr, 0) == -1)\n    return ValueUnion();\n\n  ValueUnion buff(cur_buff_size);\n  if (sysctlbyname(name.c_str(), buff.data(), &buff.size, nullptr, 0) == 0)\n    return buff;\n  return ValueUnion();\n#endif\n}\n\nBENCHMARK_MAYBE_UNUSED\nbool GetSysctl(std::string const& name, std::string* out) {\n  out->clear();\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  out->assign(buff.data());\n  return true;\n}\n\ntemplate <class Tp,\n          class = typename std::enable_if<std::is_integral<Tp>::value>::type>\nbool GetSysctl(std::string const& name, Tp* out) {\n  *out = 0;\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  *out = static_cast<Tp>(buff.GetAsInteger());\n  return true;\n}\n\ntemplate <class Tp, size_t N>\nbool GetSysctl(std::string const& name, std::array<Tp, N>* out) {\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  *out = buff.GetAsArray<Tp, N>();\n  return true;\n}\n#endif\n\ntemplate <class ArgT>\nbool ReadFromFile(std::string const& fname, ArgT* arg) {\n  *arg = ArgT();\n  std::ifstream f(fname.c_str());\n  if (!f.is_open()) return false;\n  f >> *arg;\n  return f.good();\n}\n\nCPUInfo::Scaling CpuScaling(int num_cpus) {\n  // We don't have a valid CPU count, so don't even bother.\n  if (num_cpus <= 0) return CPUInfo::Scaling::UNKNOWN;\n#if defined(BENCHMARK_OS_QNX)\n  return CPUInfo::Scaling::UNKNOWN;\n#elif !defined(BENCHMARK_OS_WINDOWS)\n  // On Linux, the CPUfreq subsystem exposes CPU information as files on the\n  // local file system. If reading the exported files fails, then we may not be\n  // running on Linux, so we silently ignore all the read errors.\n  std::string res;\n  for (int cpu = 0; cpu < num_cpus; ++cpu) {\n    std::string governor_file =\n        StrCat(\"/sys/devices/system/cpu/cpu\", cpu, \"/cpufreq/scaling_governor\");\n    if (ReadFromFile(governor_file, &res) && res != \"performance\")\n      return CPUInfo::Scaling::ENABLED;\n  }\n  return CPUInfo::Scaling::DISABLED;\n#else\n  return CPUInfo::Scaling::UNKNOWN;\n#endif\n}\n\nint CountSetBitsInCPUMap(std::string val) {\n  auto CountBits = [](std::string part) {\n    using CPUMask = std::bitset<sizeof(std::uintptr_t) * CHAR_BIT>;\n    part = \"0x\" + part;\n    CPUMask mask(benchmark::stoul(part, nullptr, 16));\n    return static_cast<int>(mask.count());\n  };\n  std::size_t pos;\n  int total = 0;\n  while ((pos = val.find(',')) != std::string::npos) {\n    total += CountBits(val.substr(0, pos));\n    val = val.substr(pos + 1);\n  }\n  if (!val.empty()) {\n    total += CountBits(val);\n  }\n  return total;\n}\n\nBENCHMARK_MAYBE_UNUSED\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesFromKVFS() {\n  std::vector<CPUInfo::CacheInfo> res;\n  std::string dir = \"/sys/devices/system/cpu/cpu0/cache/\";\n  int idx = 0;\n  while (true) {\n    CPUInfo::CacheInfo info;\n    std::string fpath = StrCat(dir, \"index\", idx++, \"/\");\n    std::ifstream f(StrCat(fpath, \"size\").c_str());\n    if (!f.is_open()) break;\n    std::string suffix;\n    f >> info.size;\n    if (f.fail())\n      PrintErrorAndDie(\"Failed while reading file '\", fpath, \"size'\");\n    if (f.good()) {\n      f >> suffix;\n      if (f.bad())\n        PrintErrorAndDie(\n            \"Invalid cache size format: failed to read size suffix\");\n      else if (f && suffix != \"K\")\n        PrintErrorAndDie(\"Invalid cache size format: Expected bytes \", suffix);\n      else if (suffix == \"K\")\n        info.size *= 1024;\n    }\n    if (!ReadFromFile(StrCat(fpath, \"type\"), &info.type))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"type\");\n    if (!ReadFromFile(StrCat(fpath, \"level\"), &info.level))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"level\");\n    std::string map_str;\n    if (!ReadFromFile(StrCat(fpath, \"shared_cpu_map\"), &map_str))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"shared_cpu_map\");\n    info.num_sharing = CountSetBitsInCPUMap(map_str);\n    res.push_back(info);\n  }\n\n  return res;\n}\n\n#ifdef BENCHMARK_OS_MACOSX\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesMacOSX() {\n  std::vector<CPUInfo::CacheInfo> res;\n  std::array<int, 4> cache_counts{{0, 0, 0, 0}};\n  GetSysctl(\"hw.cacheconfig\", &cache_counts);\n\n  struct {\n    std::string name;\n    std::string type;\n    int level;\n    int num_sharing;\n  } cases[] = {{\"hw.l1dcachesize\", \"Data\", 1, cache_counts[1]},\n               {\"hw.l1icachesize\", \"Instruction\", 1, cache_counts[1]},\n               {\"hw.l2cachesize\", \"Unified\", 2, cache_counts[2]},\n               {\"hw.l3cachesize\", \"Unified\", 3, cache_counts[3]}};\n  for (auto& c : cases) {\n    int val;\n    if (!GetSysctl(c.name, &val)) continue;\n    CPUInfo::CacheInfo info;\n    info.type = c.type;\n    info.level = c.level;\n    info.size = val;\n    info.num_sharing = c.num_sharing;\n    res.push_back(std::move(info));\n  }\n  return res;\n}\n#elif defined(BENCHMARK_OS_WINDOWS)\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {\n  std::vector<CPUInfo::CacheInfo> res;\n  DWORD buffer_size = 0;\n  using PInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION;\n  using CInfo = CACHE_DESCRIPTOR;\n\n  using UPtr = std::unique_ptr<PInfo, decltype(&std::free)>;\n  GetLogicalProcessorInformation(nullptr, &buffer_size);\n  UPtr buff(static_cast<PInfo*>(std::malloc(buffer_size)), &std::free);\n  if (!GetLogicalProcessorInformation(buff.get(), &buffer_size))\n    PrintErrorAndDie(\"Failed during call to GetLogicalProcessorInformation: \",\n                     GetLastError());\n\n  PInfo* it = buff.get();\n  PInfo* end = buff.get() + (buffer_size / sizeof(PInfo));\n\n  for (; it != end; ++it) {\n    if (it->Relationship != RelationCache) continue;\n    using BitSet = std::bitset<sizeof(ULONG_PTR) * CHAR_BIT>;\n    BitSet b(it->ProcessorMask);\n    // To prevent duplicates, only consider caches where CPU 0 is specified\n    if (!b.test(0)) continue;\n    const CInfo& cache = it->Cache;\n    CPUInfo::CacheInfo C;\n    C.num_sharing = static_cast<int>(b.count());\n    C.level = cache.Level;\n    C.size = static_cast<int>(cache.Size);\n    C.type = \"Unknown\";\n    switch (cache.Type) {\n      case CacheUnified:\n        C.type = \"Unified\";\n        break;\n      case CacheInstruction:\n        C.type = \"Instruction\";\n        break;\n      case CacheData:\n        C.type = \"Data\";\n        break;\n      case CacheTrace:\n        C.type = \"Trace\";\n        break;\n    }\n    res.push_back(C);\n  }\n  return res;\n}\n#elif BENCHMARK_OS_QNX\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesQNX() {\n  std::vector<CPUInfo::CacheInfo> res;\n  struct cacheattr_entry* cache = SYSPAGE_ENTRY(cacheattr);\n  uint32_t const elsize = SYSPAGE_ELEMENT_SIZE(cacheattr);\n  int num = SYSPAGE_ENTRY_SIZE(cacheattr) / elsize;\n  for (int i = 0; i < num; ++i) {\n    CPUInfo::CacheInfo info;\n    switch (cache->flags) {\n      case CACHE_FLAG_INSTR:\n        info.type = \"Instruction\";\n        info.level = 1;\n        break;\n      case CACHE_FLAG_DATA:\n        info.type = \"Data\";\n        info.level = 1;\n        break;\n      case CACHE_FLAG_UNIFIED:\n        info.type = \"Unified\";\n        info.level = 2;\n        break;\n      case CACHE_FLAG_SHARED:\n        info.type = \"Shared\";\n        info.level = 3;\n        break;\n      default:\n        continue;\n        break;\n    }\n    info.size = cache->line_size * cache->num_lines;\n    info.num_sharing = 0;\n    res.push_back(std::move(info));\n    cache = SYSPAGE_ARRAY_ADJ_OFFSET(cacheattr, cache, elsize);\n  }\n  return res;\n}\n#endif\n\nstd::vector<CPUInfo::CacheInfo> GetCacheSizes() {\n#ifdef BENCHMARK_OS_MACOSX\n  return GetCacheSizesMacOSX();\n#elif defined(BENCHMARK_OS_WINDOWS)\n  return GetCacheSizesWindows();\n#elif defined(BENCHMARK_OS_QNX)\n  return GetCacheSizesQNX();\n#elif defined(BENCHMARK_OS_QURT)\n  return std::vector<CPUInfo::CacheInfo>();\n#else\n  return GetCacheSizesFromKVFS();\n#endif\n}\n\nstd::string GetSystemName() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  std::string str;\n  static constexpr int COUNT = MAX_COMPUTERNAME_LENGTH + 1;\n  TCHAR hostname[COUNT] = {'\\0'};\n  DWORD DWCOUNT = COUNT;\n  if (!GetComputerName(hostname, &DWCOUNT)) return std::string(\"\");\n#ifndef UNICODE\n  str = std::string(hostname, DWCOUNT);\n#else\n  // `WideCharToMultiByte` returns `0` when conversion fails.\n  int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname,\n                                DWCOUNT, NULL, 0, NULL, NULL);\n  str.resize(len);\n  WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],\n                      str.size(), NULL, NULL);\n#endif\n  return str;\n#elif defined(BENCHMARK_OS_QURT)\n  std::string str = \"Hexagon DSP\";\n  qurt_arch_version_t arch_version_struct;\n  if (qurt_sysenv_get_arch_version(&arch_version_struct) == QURT_EOK) {\n    str += \" v\";\n    str += std::to_string(arch_version_struct.arch_version);\n  }\n  return str;\n#else\n#ifndef HOST_NAME_MAX\n#ifdef BENCHMARK_HAS_SYSCTL  // BSD/Mac doesn't have HOST_NAME_MAX defined\n#define HOST_NAME_MAX 64\n#elif defined(BENCHMARK_OS_NACL)\n#define HOST_NAME_MAX 64\n#elif defined(BENCHMARK_OS_QNX)\n#define HOST_NAME_MAX 154\n#elif defined(BENCHMARK_OS_RTEMS)\n#define HOST_NAME_MAX 256\n#elif defined(BENCHMARK_OS_SOLARIS)\n#define HOST_NAME_MAX MAXHOSTNAMELEN\n#elif defined(BENCHMARK_OS_ZOS)\n#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX\n#else\n#pragma message(\"HOST_NAME_MAX not defined. using 64\")\n#define HOST_NAME_MAX 64\n#endif\n#endif  // def HOST_NAME_MAX\n  char hostname[HOST_NAME_MAX];\n  int retVal = gethostname(hostname, HOST_NAME_MAX);\n  if (retVal != 0) return std::string(\"\");\n  return std::string(hostname);\n#endif  // Catch-all POSIX block.\n}\n\nint GetNumCPUsImpl() {\n#ifdef BENCHMARK_HAS_SYSCTL\n  int num_cpu = -1;\n  if (GetSysctl(\"hw.ncpu\", &num_cpu)) return num_cpu;\n  PrintErrorAndDie(\"Err: \", strerror(errno));\n#elif defined(BENCHMARK_OS_WINDOWS)\n  SYSTEM_INFO sysinfo;\n  // Use memset as opposed to = {} to avoid GCC missing initializer false\n  // positives.\n  std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO));\n  GetSystemInfo(&sysinfo);\n  // number of logical processors in the current group\n  return static_cast<int>(sysinfo.dwNumberOfProcessors);\n#elif defined(BENCHMARK_OS_SOLARIS)\n  // Returns -1 in case of a failure.\n  long num_cpu = sysconf(_SC_NPROCESSORS_ONLN);\n  if (num_cpu < 0) {\n    PrintErrorAndDie(\"sysconf(_SC_NPROCESSORS_ONLN) failed with error: \",\n                     strerror(errno));\n  }\n  return (int)num_cpu;\n#elif defined(BENCHMARK_OS_QNX)\n  return static_cast<int>(_syspage_ptr->num_cpu);\n#elif defined(BENCHMARK_OS_QURT)\n  qurt_sysenv_max_hthreads_t hardware_threads;\n  if (qurt_sysenv_get_max_hw_threads(&hardware_threads) != QURT_EOK) {\n    hardware_threads.max_hthreads = 1;\n  }\n  return hardware_threads.max_hthreads;\n#else\n  int num_cpus = 0;\n  int max_id = -1;\n  std::ifstream f(\"/proc/cpuinfo\");\n  if (!f.is_open()) {\n    std::cerr << \"Failed to open /proc/cpuinfo\\n\";\n    return -1;\n  }\n#if defined(__alpha__)\n  const std::string Key = \"cpus detected\";\n#else\n  const std::string Key = \"processor\";\n#endif\n  std::string ln;\n  while (std::getline(f, ln)) {\n    if (ln.empty()) continue;\n    std::size_t split_idx = ln.find(':');\n    std::string value;\n#if defined(__s390__)\n    // s390 has another format in /proc/cpuinfo\n    // it needs to be parsed differently\n    if (split_idx != std::string::npos)\n      value = ln.substr(Key.size() + 1, split_idx - Key.size() - 1);\n#else\n    if (split_idx != std::string::npos) value = ln.substr(split_idx + 1);\n#endif\n    if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) {\n      num_cpus++;\n      if (!value.empty()) {\n        const int cur_id = benchmark::stoi(value);\n        max_id = std::max(cur_id, max_id);\n      }\n    }\n  }\n  if (f.bad()) {\n    PrintErrorAndDie(\"Failure reading /proc/cpuinfo\");\n  }\n  if (!f.eof()) {\n    PrintErrorAndDie(\"Failed to read to end of /proc/cpuinfo\");\n  }\n  f.close();\n\n  if ((max_id + 1) != num_cpus) {\n    fprintf(stderr,\n            \"CPU ID assignments in /proc/cpuinfo seem messed up.\"\n            \" This is usually caused by a bad BIOS.\\n\");\n  }\n  return num_cpus;\n#endif\n  BENCHMARK_UNREACHABLE();\n}\n\nint GetNumCPUs() {\n  const int num_cpus = GetNumCPUsImpl();\n  if (num_cpus < 1) {\n    std::cerr << \"Unable to extract number of CPUs.  If your platform uses \"\n                 \"/proc/cpuinfo, custom support may need to be added.\\n\";\n  }\n  return num_cpus;\n}\n\nclass ThreadAffinityGuard final {\n public:\n  ThreadAffinityGuard() : reset_affinity(SetAffinity()) {\n    if (!reset_affinity)\n      std::cerr << \"***WARNING*** Failed to set thread affinity. Estimated CPU \"\n                   \"frequency may be incorrect.\"\n                << std::endl;\n  }\n\n  ~ThreadAffinityGuard() {\n    if (!reset_affinity) return;\n\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n    int ret = pthread_setaffinity_np(self, sizeof(previous_affinity),\n                                     &previous_affinity);\n    if (ret == 0) return;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n    DWORD_PTR ret = SetThreadAffinityMask(self, previous_affinity);\n    if (ret != 0) return;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n    PrintErrorAndDie(\"Failed to reset thread affinity\");\n  }\n\n  ThreadAffinityGuard(ThreadAffinityGuard&&) = delete;\n  ThreadAffinityGuard(const ThreadAffinityGuard&) = delete;\n  ThreadAffinityGuard& operator=(ThreadAffinityGuard&&) = delete;\n  ThreadAffinityGuard& operator=(const ThreadAffinityGuard&) = delete;\n\n private:\n  bool SetAffinity() {\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n    int ret;\n    self = pthread_self();\n    ret = pthread_getaffinity_np(self, sizeof(previous_affinity),\n                                 &previous_affinity);\n    if (ret != 0) return false;\n\n    cpu_set_t affinity;\n    memcpy(&affinity, &previous_affinity, sizeof(affinity));\n\n    bool is_first_cpu = true;\n\n    for (int i = 0; i < CPU_SETSIZE; ++i)\n      if (CPU_ISSET(i, &affinity)) {\n        if (is_first_cpu)\n          is_first_cpu = false;\n        else\n          CPU_CLR(i, &affinity);\n      }\n\n    if (is_first_cpu) return false;\n\n    ret = pthread_setaffinity_np(self, sizeof(affinity), &affinity);\n    return ret == 0;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n    self = GetCurrentThread();\n    DWORD_PTR mask = static_cast<DWORD_PTR>(1) << GetCurrentProcessorNumber();\n    previous_affinity = SetThreadAffinityMask(self, mask);\n    return previous_affinity != 0;\n#else\n    return false;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n  }\n\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n  pthread_t self;\n  cpu_set_t previous_affinity;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n  HANDLE self;\n  DWORD_PTR previous_affinity;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n  bool reset_affinity;\n};\n\ndouble GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) {\n  // Currently, scaling is only used on linux path here,\n  // suppress diagnostics about it being unused on other paths.\n  (void)scaling;\n\n#if defined BENCHMARK_OS_LINUX || defined BENCHMARK_OS_CYGWIN\n  long freq;\n\n  // If the kernel is exporting the tsc frequency use that. There are issues\n  // where cpuinfo_max_freq cannot be relied on because the BIOS may be\n  // exporintg an invalid p-state (on x86) or p-states may be used to put the\n  // processor in a new mode (turbo mode). Essentially, those frequencies\n  // cannot always be relied upon. The same reasons apply to /proc/cpuinfo as\n  // well.\n  if (ReadFromFile(\"/sys/devices/system/cpu/cpu0/tsc_freq_khz\", &freq)\n      // If CPU scaling is disabled, use the *current* frequency.\n      // Note that we specifically don't want to read cpuinfo_cur_freq,\n      // because it is only readable by root.\n      || (scaling == CPUInfo::Scaling::DISABLED &&\n          ReadFromFile(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq\",\n                       &freq))\n      // Otherwise, if CPU scaling may be in effect, we want to use\n      // the *maximum* frequency, not whatever CPU speed some random processor\n      // happens to be using now.\n      || ReadFromFile(\"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\",\n                      &freq)) {\n    // The value is in kHz (as the file name suggests).  For example, on a\n    // 2GHz warpstation, the file contains the value \"2000000\".\n    return static_cast<double>(freq) * 1000.0;\n  }\n\n  const double error_value = -1;\n  double bogo_clock = error_value;\n\n  std::ifstream f(\"/proc/cpuinfo\");\n  if (!f.is_open()) {\n    std::cerr << \"failed to open /proc/cpuinfo\\n\";\n    return error_value;\n  }\n\n  auto StartsWithKey = [](std::string const& Value, std::string const& Key) {\n    if (Key.size() > Value.size()) return false;\n    auto Cmp = [&](char X, char Y) {\n      return std::tolower(X) == std::tolower(Y);\n    };\n    return std::equal(Key.begin(), Key.end(), Value.begin(), Cmp);\n  };\n\n  std::string ln;\n  while (std::getline(f, ln)) {\n    if (ln.empty()) continue;\n    std::size_t split_idx = ln.find(':');\n    std::string value;\n    if (split_idx != std::string::npos) value = ln.substr(split_idx + 1);\n    // When parsing the \"cpu MHz\" and \"bogomips\" (fallback) entries, we only\n    // accept positive values. Some environments (virtual machines) report zero,\n    // which would cause infinite looping in WallTime_Init.\n    if (StartsWithKey(ln, \"cpu MHz\")) {\n      if (!value.empty()) {\n        double cycles_per_second = benchmark::stod(value) * 1000000.0;\n        if (cycles_per_second > 0) return cycles_per_second;\n      }\n    } else if (StartsWithKey(ln, \"bogomips\")) {\n      if (!value.empty()) {\n        bogo_clock = benchmark::stod(value) * 1000000.0;\n        if (bogo_clock < 0.0) bogo_clock = error_value;\n      }\n    }\n  }\n  if (f.bad()) {\n    std::cerr << \"Failure reading /proc/cpuinfo\\n\";\n    return error_value;\n  }\n  if (!f.eof()) {\n    std::cerr << \"Failed to read to end of /proc/cpuinfo\\n\";\n    return error_value;\n  }\n  f.close();\n  // If we found the bogomips clock, but nothing better, we'll use it (but\n  // we're not happy about it); otherwise, fallback to the rough estimation\n  // below.\n  if (bogo_clock >= 0.0) return bogo_clock;\n\n#elif defined BENCHMARK_HAS_SYSCTL\n  constexpr auto* freqStr =\n#if defined(BENCHMARK_OS_FREEBSD) || defined(BENCHMARK_OS_NETBSD)\n      \"machdep.tsc_freq\";\n#elif defined BENCHMARK_OS_OPENBSD\n      \"hw.cpuspeed\";\n#elif defined BENCHMARK_OS_DRAGONFLY\n      \"hw.tsc_frequency\";\n#else\n      \"hw.cpufrequency\";\n#endif\n  unsigned long long hz = 0;\n#if defined BENCHMARK_OS_OPENBSD\n  if (GetSysctl(freqStr, &hz)) return static_cast<double>(hz * 1000000);\n#else\n  if (GetSysctl(freqStr, &hz)) return static_cast<double>(hz);\n#endif\n  fprintf(stderr, \"Unable to determine clock rate from sysctl: %s: %s\\n\",\n          freqStr, strerror(errno));\n  fprintf(stderr,\n          \"This does not affect benchmark measurements, only the \"\n          \"metadata output.\\n\");\n\n#elif defined BENCHMARK_OS_WINDOWS_WIN32\n  // In NT, read MHz from the registry. If we fail to do so or we're in win9x\n  // then make a crude estimate.\n  DWORD data, data_size = sizeof(data);\n  if (IsWindowsXPOrGreater() &&\n      SUCCEEDED(\n          SHGetValueA(HKEY_LOCAL_MACHINE,\n                      \"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n                      \"~MHz\", nullptr, &data, &data_size)))\n    return static_cast<double>(static_cast<int64_t>(data) *\n                               static_cast<int64_t>(1000 * 1000));  // was mhz\n#elif defined(BENCHMARK_OS_SOLARIS)\n  kstat_ctl_t* kc = kstat_open();\n  if (!kc) {\n    std::cerr << \"failed to open /dev/kstat\\n\";\n    return -1;\n  }\n  kstat_t* ksp = kstat_lookup(kc, const_cast<char*>(\"cpu_info\"), -1,\n                              const_cast<char*>(\"cpu_info0\"));\n  if (!ksp) {\n    std::cerr << \"failed to lookup in /dev/kstat\\n\";\n    return -1;\n  }\n  if (kstat_read(kc, ksp, NULL) < 0) {\n    std::cerr << \"failed to read from /dev/kstat\\n\";\n    return -1;\n  }\n  kstat_named_t* knp = (kstat_named_t*)kstat_data_lookup(\n      ksp, const_cast<char*>(\"current_clock_Hz\"));\n  if (!knp) {\n    std::cerr << \"failed to lookup data in /dev/kstat\\n\";\n    return -1;\n  }\n  if (knp->data_type != KSTAT_DATA_UINT64) {\n    std::cerr << \"current_clock_Hz is of unexpected data type: \"\n              << knp->data_type << \"\\n\";\n    return -1;\n  }\n  double clock_hz = knp->value.ui64;\n  kstat_close(kc);\n  return clock_hz;\n#elif defined(BENCHMARK_OS_QNX)\n  return static_cast<double>(\n      static_cast<int64_t>(SYSPAGE_ENTRY(cpuinfo)->speed) *\n      static_cast<int64_t>(1000 * 1000));\n#elif defined(BENCHMARK_OS_QURT)\n  // QuRT doesn't provide any API to query Hexagon frequency.\n  return 1000000000;\n#endif\n  // If we've fallen through, attempt to roughly estimate the CPU clock rate.\n\n  // Make sure to use the same cycle counter when starting and stopping the\n  // cycle timer. We just pin the current thread to a cpu in the previous\n  // affinity set.\n  ThreadAffinityGuard affinity_guard;\n\n  static constexpr double estimate_time_s = 1.0;\n  const double start_time = ChronoClockNow();\n  const auto start_ticks = cycleclock::Now();\n\n  // Impose load instead of calling sleep() to make sure the cycle counter\n  // works.\n  using PRNG = std::minstd_rand;\n  using Result = PRNG::result_type;\n  PRNG rng(static_cast<Result>(start_ticks));\n\n  Result state = 0;\n\n  do {\n    static constexpr size_t batch_size = 10000;\n    rng.discard(batch_size);\n    state += rng();\n\n  } while (ChronoClockNow() - start_time < estimate_time_s);\n\n  DoNotOptimize(state);\n\n  const auto end_ticks = cycleclock::Now();\n  const double end_time = ChronoClockNow();\n\n  return static_cast<double>(end_ticks - start_ticks) / (end_time - start_time);\n  // Reset the affinity of current thread when the lifetime of affinity_guard\n  // ends.\n}\n\nstd::vector<double> GetLoadAvg() {\n#if (defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) ||     \\\n     defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD ||      \\\n     defined BENCHMARK_OS_OPENBSD || defined BENCHMARK_OS_DRAGONFLY) && \\\n    !(defined(__ANDROID__) && __ANDROID_API__ < 29)\n  static constexpr int kMaxSamples = 3;\n  std::vector<double> res(kMaxSamples, 0.0);\n  const size_t nelem = static_cast<size_t>(getloadavg(res.data(), kMaxSamples));\n  if (nelem < 1) {\n    res.clear();\n  } else {\n    res.resize(nelem);\n  }\n  return res;\n#else\n  return {};\n#endif\n}\n\n}  // end namespace\n\nconst CPUInfo& CPUInfo::Get() {\n  static const CPUInfo* info = new CPUInfo();\n  return *info;\n}\n\nCPUInfo::CPUInfo()\n    : num_cpus(GetNumCPUs()),\n      scaling(CpuScaling(num_cpus)),\n      cycles_per_second(GetCPUCyclesPerSecond(scaling)),\n      caches(GetCacheSizes()),\n      load_avg(GetLoadAvg()) {}\n\nconst SystemInfo& SystemInfo::Get() {\n  static const SystemInfo* info = new SystemInfo();\n  return *info;\n}\n\nSystemInfo::SystemInfo() : name(GetSystemName()) {}\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/thread_manager.h",
    "content": "#ifndef BENCHMARK_THREAD_MANAGER_H\n#define BENCHMARK_THREAD_MANAGER_H\n\n#include <atomic>\n\n#include \"benchmark/benchmark.h\"\n#include \"mutex.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nclass ThreadManager {\n public:\n  explicit ThreadManager(int num_threads)\n      : alive_threads_(num_threads), start_stop_barrier_(num_threads) {}\n\n  Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {\n    return benchmark_mutex_;\n  }\n\n  bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {\n    return start_stop_barrier_.wait();\n  }\n\n  void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {\n    start_stop_barrier_.removeThread();\n    if (--alive_threads_ == 0) {\n      MutexLock lock(end_cond_mutex_);\n      end_condition_.notify_all();\n    }\n  }\n\n  void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {\n    MutexLock lock(end_cond_mutex_);\n    end_condition_.wait(lock.native_handle(),\n                        [this]() { return alive_threads_ == 0; });\n  }\n\n  struct Result {\n    IterationCount iterations = 0;\n    double real_time_used = 0;\n    double cpu_time_used = 0;\n    double manual_time_used = 0;\n    int64_t complexity_n = 0;\n    std::string report_label_;\n    std::string skip_message_;\n    internal::Skipped skipped_ = internal::NotSkipped;\n    UserCounters counters;\n  };\n  GUARDED_BY(GetBenchmarkMutex()) Result results;\n\n private:\n  mutable Mutex benchmark_mutex_;\n  std::atomic<int> alive_threads_;\n  Barrier start_stop_barrier_;\n  Mutex end_cond_mutex_;\n  Condition end_condition_;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_THREAD_MANAGER_H\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/thread_timer.h",
    "content": "#ifndef BENCHMARK_THREAD_TIMER_H\n#define BENCHMARK_THREAD_TIMER_H\n\n#include \"check.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nclass ThreadTimer {\n  explicit ThreadTimer(bool measure_process_cpu_time_)\n      : measure_process_cpu_time(measure_process_cpu_time_) {}\n\n public:\n  static ThreadTimer Create() {\n    return ThreadTimer(/*measure_process_cpu_time_=*/false);\n  }\n  static ThreadTimer CreateProcessCpuTime() {\n    return ThreadTimer(/*measure_process_cpu_time_=*/true);\n  }\n\n  // Called by each thread\n  void StartTimer() {\n    running_ = true;\n    start_real_time_ = ChronoClockNow();\n    start_cpu_time_ = ReadCpuTimerOfChoice();\n  }\n\n  // Called by each thread\n  void StopTimer() {\n    BM_CHECK(running_);\n    running_ = false;\n    real_time_used_ += ChronoClockNow() - start_real_time_;\n    // Floating point error can result in the subtraction producing a negative\n    // time. Guard against that.\n    cpu_time_used_ +=\n        std::max<double>(ReadCpuTimerOfChoice() - start_cpu_time_, 0);\n  }\n\n  // Called by each thread\n  void SetIterationTime(double seconds) { manual_time_used_ += seconds; }\n\n  bool running() const { return running_; }\n\n  // REQUIRES: timer is not running\n  double real_time_used() const {\n    BM_CHECK(!running_);\n    return real_time_used_;\n  }\n\n  // REQUIRES: timer is not running\n  double cpu_time_used() const {\n    BM_CHECK(!running_);\n    return cpu_time_used_;\n  }\n\n  // REQUIRES: timer is not running\n  double manual_time_used() const {\n    BM_CHECK(!running_);\n    return manual_time_used_;\n  }\n\n private:\n  double ReadCpuTimerOfChoice() const {\n    if (measure_process_cpu_time) return ProcessCPUUsage();\n    return ThreadCPUUsage();\n  }\n\n  // should the thread, or the process, time be measured?\n  const bool measure_process_cpu_time;\n\n  bool running_ = false;        // Is the timer running\n  double start_real_time_ = 0;  // If running_\n  double start_cpu_time_ = 0;   // If running_\n\n  // Accumulated time so far (does not contain current slice if running_)\n  double real_time_used_ = 0;\n  double cpu_time_used_ = 0;\n  // Manually set iteration time. User sets this with SetIterationTime(seconds).\n  double manual_time_used_ = 0;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_THREAD_TIMER_H\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/timers.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"timers.h\"\n\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#include <shlwapi.h>\n#undef StrCat  // Don't let StrCat in string_util.h be renamed to lstrcatA\n#include <versionhelpers.h>\n#include <windows.h>\n#else\n#include <fcntl.h>\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <sys/types.h>  // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD\n#include <unistd.h>\n#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_DRAGONFLY || \\\n    defined BENCHMARK_OS_MACOSX\n#include <sys/sysctl.h>\n#endif\n#if defined(BENCHMARK_OS_MACOSX)\n#include <mach/mach_init.h>\n#include <mach/mach_port.h>\n#include <mach/thread_act.h>\n#endif\n#if defined(BENCHMARK_OS_QURT)\n#include <qurt.h>\n#endif\n#endif\n\n#ifdef BENCHMARK_OS_EMSCRIPTEN\n#include <emscripten.h>\n#endif\n\n#include <cerrno>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <ctime>\n#include <iostream>\n#include <limits>\n#include <mutex>\n\n#include \"check.h\"\n#include \"log.h\"\n#include \"string_util.h\"\n\nnamespace benchmark {\n\n// Suppress unused warnings on helper functions.\n#if defined(__GNUC__)\n#pragma GCC diagnostic ignored \"-Wunused-function\"\n#endif\n#if defined(__NVCOMPILER)\n#pragma diag_suppress declared_but_not_referenced\n#endif\n\nnamespace {\n#if defined(BENCHMARK_OS_WINDOWS)\ndouble MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {\n  ULARGE_INTEGER kernel;\n  ULARGE_INTEGER user;\n  kernel.HighPart = kernel_time.dwHighDateTime;\n  kernel.LowPart = kernel_time.dwLowDateTime;\n  user.HighPart = user_time.dwHighDateTime;\n  user.LowPart = user_time.dwLowDateTime;\n  return (static_cast<double>(kernel.QuadPart) +\n          static_cast<double>(user.QuadPart)) *\n         1e-7;\n}\n#elif !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\ndouble MakeTime(struct rusage const& ru) {\n  return (static_cast<double>(ru.ru_utime.tv_sec) +\n          static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +\n          static_cast<double>(ru.ru_stime.tv_sec) +\n          static_cast<double>(ru.ru_stime.tv_usec) * 1e-6);\n}\n#endif\n#if defined(BENCHMARK_OS_MACOSX)\ndouble MakeTime(thread_basic_info_data_t const& info) {\n  return (static_cast<double>(info.user_time.seconds) +\n          static_cast<double>(info.user_time.microseconds) * 1e-6 +\n          static_cast<double>(info.system_time.seconds) +\n          static_cast<double>(info.system_time.microseconds) * 1e-6);\n}\n#endif\n#if defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_THREAD_CPUTIME_ID)\ndouble MakeTime(struct timespec const& ts) {\n  return static_cast<double>(ts.tv_sec) +\n         (static_cast<double>(ts.tv_nsec) * 1e-9);\n}\n#endif\n\nBENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) {\n  std::cerr << \"ERROR: \" << msg << std::endl;\n  std::exit(EXIT_FAILURE);\n}\n\n}  // end namespace\n\ndouble ProcessCPUUsage() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  HANDLE proc = GetCurrentProcess();\n  FILETIME creation_time;\n  FILETIME exit_time;\n  FILETIME kernel_time;\n  FILETIME user_time;\n  if (GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time,\n                      &user_time))\n    return MakeTime(kernel_time, user_time);\n  DiagnoseAndExit(\"GetProccessTimes() failed\");\n#elif defined(BENCHMARK_OS_QURT)\n  // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,\n  // and doesn't appear to work on at least some devices (eg Samsung S22),\n  // so let's use the actually-documented and apparently-equivalent\n  // qurt_sysclock_get_hw_ticks() call instead.\n  return static_cast<double>(\n             qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *\n         1.0e-6;\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten.\n  // Use Emscripten-specific API. Reported CPU time would be exactly the\n  // same as total time, but this is ok because there aren't long-latency\n  // synchronous system calls in Emscripten.\n  return emscripten_get_now() * 1e-3;\n#elif defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX)\n  // FIXME We want to use clock_gettime, but its not available in MacOS 10.11.\n  // See https://github.com/google/benchmark/pull/292\n  struct timespec spec;\n  if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0)\n    return MakeTime(spec);\n  DiagnoseAndExit(\"clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed\");\n#else\n  struct rusage ru;\n  if (getrusage(RUSAGE_SELF, &ru) == 0) return MakeTime(ru);\n  DiagnoseAndExit(\"getrusage(RUSAGE_SELF, ...) failed\");\n#endif\n}\n\ndouble ThreadCPUUsage() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  HANDLE this_thread = GetCurrentThread();\n  FILETIME creation_time;\n  FILETIME exit_time;\n  FILETIME kernel_time;\n  FILETIME user_time;\n  GetThreadTimes(this_thread, &creation_time, &exit_time, &kernel_time,\n                 &user_time);\n  return MakeTime(kernel_time, user_time);\n#elif defined(BENCHMARK_OS_QURT)\n  // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,\n  // and doesn't appear to work on at least some devices (eg Samsung S22),\n  // so let's use the actually-documented and apparently-equivalent\n  // qurt_sysclock_get_hw_ticks() call instead.\n  return static_cast<double>(\n             qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *\n         1.0e-6;\n#elif defined(BENCHMARK_OS_MACOSX)\n  // FIXME We want to use clock_gettime, but its not available in MacOS 10.11.\n  // See https://github.com/google/benchmark/pull/292\n  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;\n  thread_basic_info_data_t info;\n  mach_port_t thread = pthread_mach_thread_np(pthread_self());\n  if (thread_info(thread, THREAD_BASIC_INFO,\n                  reinterpret_cast<thread_info_t>(&info),\n                  &count) == KERN_SUCCESS) {\n    return MakeTime(info);\n  }\n  DiagnoseAndExit(\"ThreadCPUUsage() failed when evaluating thread_info\");\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // Emscripten doesn't support traditional threads\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_RTEMS)\n  // RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See\n  // https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_ZOS)\n  // z/OS doesn't support CLOCK_THREAD_CPUTIME_ID.\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_SOLARIS)\n  struct rusage ru;\n  if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru);\n  DiagnoseAndExit(\"getrusage(RUSAGE_LWP, ...) failed\");\n#elif defined(CLOCK_THREAD_CPUTIME_ID)\n  struct timespec ts;\n  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);\n  DiagnoseAndExit(\"clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed\");\n#else\n#error Per-thread timing is not available on your system.\n#endif\n}\n\nstd::string LocalDateTimeString() {\n  // Write the local time in RFC3339 format yyyy-mm-ddTHH:MM:SS+/-HH:MM.\n  typedef std::chrono::system_clock Clock;\n  std::time_t now = Clock::to_time_t(Clock::now());\n  const std::size_t kTzOffsetLen = 6;\n  const std::size_t kTimestampLen = 19;\n\n  std::size_t tz_len;\n  std::size_t timestamp_len;\n  long int offset_minutes;\n  char tz_offset_sign = '+';\n  // tz_offset is set in one of three ways:\n  // * strftime with %z - This either returns empty or the ISO 8601 time.  The\n  // maximum length an\n  //   ISO 8601 string can be is 7 (e.g. -03:30, plus trailing zero).\n  // * snprintf with %c%02li:%02li - The maximum length is 41 (one for %c, up to\n  // 19 for %02li,\n  //   one for :, up to 19 %02li, plus trailing zero).\n  // * A fixed string of \"-00:00\".  The maximum length is 7 (-00:00, plus\n  // trailing zero).\n  //\n  // Thus, the maximum size this needs to be is 41.\n  char tz_offset[41];\n  // Long enough buffer to avoid format-overflow warnings\n  char storage[128];\n\n#if defined(BENCHMARK_OS_WINDOWS)\n  std::tm* timeinfo_p = ::localtime(&now);\n#else\n  std::tm timeinfo;\n  std::tm* timeinfo_p = &timeinfo;\n  ::localtime_r(&now, &timeinfo);\n#endif\n\n  tz_len = std::strftime(tz_offset, sizeof(tz_offset), \"%z\", timeinfo_p);\n\n  if (tz_len < kTzOffsetLen && tz_len > 1) {\n    // Timezone offset was written. strftime writes offset as +HHMM or -HHMM,\n    // RFC3339 specifies an offset as +HH:MM or -HH:MM. To convert, we parse\n    // the offset as an integer, then reprint it to a string.\n\n    offset_minutes = ::strtol(tz_offset, NULL, 10);\n    if (offset_minutes < 0) {\n      offset_minutes *= -1;\n      tz_offset_sign = '-';\n    }\n\n    tz_len = static_cast<size_t>(\n        ::snprintf(tz_offset, sizeof(tz_offset), \"%c%02li:%02li\",\n                   tz_offset_sign, offset_minutes / 100, offset_minutes % 100));\n    BM_CHECK(tz_len == kTzOffsetLen);\n    ((void)tz_len);  // Prevent unused variable warning in optimized build.\n  } else {\n    // Unknown offset. RFC3339 specifies that unknown local offsets should be\n    // written as UTC time with -00:00 timezone.\n#if defined(BENCHMARK_OS_WINDOWS)\n    // Potential race condition if another thread calls localtime or gmtime.\n    timeinfo_p = ::gmtime(&now);\n#else\n    ::gmtime_r(&now, &timeinfo);\n#endif\n\n    strncpy(tz_offset, \"-00:00\", kTzOffsetLen + 1);\n  }\n\n  timestamp_len =\n      std::strftime(storage, sizeof(storage), \"%Y-%m-%dT%H:%M:%S\", timeinfo_p);\n  BM_CHECK(timestamp_len == kTimestampLen);\n  // Prevent unused variable warning in optimized build.\n  ((void)kTimestampLen);\n\n  std::strncat(storage, tz_offset, sizeof(storage) - timestamp_len - 1);\n  return std::string(storage);\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/core/vendor/googlebenchmark/src/timers.h",
    "content": "#ifndef BENCHMARK_TIMERS_H\n#define BENCHMARK_TIMERS_H\n\n#include <chrono>\n#include <string>\n\nnamespace benchmark {\n\n// Return the CPU usage of the current process\ndouble ProcessCPUUsage();\n\n// Return the CPU usage of the children of the current process\ndouble ChildrenCPUUsage();\n\n// Return the CPU usage of the current thread\ndouble ThreadCPUUsage();\n\n#if defined(BENCHMARK_OS_QURT)\n\n// std::chrono::now() can return 0 on some Hexagon devices;\n// this reads the value of a 56-bit, 19.2MHz hardware counter\n// and converts it to seconds. Unlike std::chrono, this doesn't\n// return an absolute time, but since ChronoClockNow() is only used\n// to compute elapsed time, this shouldn't matter.\nstruct QuRTClock {\n  typedef uint64_t rep;\n  typedef std::ratio<1, 19200000> period;\n  typedef std::chrono::duration<rep, period> duration;\n  typedef std::chrono::time_point<QuRTClock> time_point;\n  static const bool is_steady = false;\n\n  static time_point now() {\n    unsigned long long count;\n    asm volatile(\" %0 = c31:30 \" : \"=r\"(count));\n    return time_point(static_cast<duration>(count));\n  }\n};\n\n#else\n\n#if defined(HAVE_STEADY_CLOCK)\ntemplate <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>\nstruct ChooseSteadyClock {\n  typedef std::chrono::high_resolution_clock type;\n};\n\ntemplate <>\nstruct ChooseSteadyClock<false> {\n  typedef std::chrono::steady_clock type;\n};\n#endif  // HAVE_STEADY_CLOCK\n\n#endif\n\nstruct ChooseClockType {\n#if defined(BENCHMARK_OS_QURT)\n  typedef QuRTClock type;\n#elif defined(HAVE_STEADY_CLOCK)\n  typedef ChooseSteadyClock<>::type type;\n#else\n  typedef std::chrono::high_resolution_clock type;\n#endif\n};\n\ninline double ChronoClockNow() {\n  typedef ChooseClockType::type ClockType;\n  using FpSeconds = std::chrono::duration<double, std::chrono::seconds::period>;\n  return FpSeconds(ClockType::now().time_since_epoch()).count();\n}\n\nstd::string LocalDateTimeString();\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_TIMERS_H\n"
  },
  {
    "path": "vendor/core/vendor/googletest/CMakeLists.txt",
    "content": "# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n\ncmake_minimum_required(VERSION 3.13)\n\nproject(googletest-distribution)\nset(GOOGLETEST_VERSION 1.14.0)\n\nif(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)\n  set(CMAKE_CXX_EXTENSIONS OFF)\nendif()\n\nenable_testing()\n\ninclude(CMakeDependentOption)\ninclude(GNUInstallDirs)\n\n# Note that googlemock target already builds googletest.\noption(BUILD_GMOCK \"Builds the googlemock subproject\" ON)\noption(INSTALL_GTEST \"Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)\" ON)\noption(GTEST_HAS_ABSL \"Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build.\" OFF)\n\nif(GTEST_HAS_ABSL)\n  if(NOT TARGET absl::base)\n    find_package(absl REQUIRED)\n  endif()\n  if(NOT TARGET re2::re2)\n    find_package(re2 REQUIRED)\n  endif()\nendif()\n\nif(BUILD_GMOCK)\n  add_subdirectory( googlemock )\nelse()\n  add_subdirectory( googletest )\nendif()\n"
  },
  {
    "path": "vendor/core/vendor/googletest/LICENSE",
    "content": "Copyright 2008, Google Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n    * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/CMakeLists.txt",
    "content": "########################################################################\n# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n#\n# CMake build script for Google Mock.\n#\n# To run the tests for Google Mock itself on Linux, use 'make test' or\n# ctest. You can select which tests to run using 'ctest -R regex'.\n# For more options, run 'ctest --help'.\n\noption(gmock_build_tests \"Build all of Google Mock's own tests.\" OFF)\n\n# A directory to find Google Test sources.\nif (EXISTS \"${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt\")\n  set(gtest_dir gtest)\nelse()\n  set(gtest_dir ../googletest)\nendif()\n\n# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().\ninclude(\"${gtest_dir}/cmake/hermetic_build.cmake\" OPTIONAL)\n\nif (COMMAND pre_project_set_up_hermetic_build)\n  # Google Test also calls hermetic setup functions from add_subdirectory,\n  # although its changes will not affect things at the current scope.\n  pre_project_set_up_hermetic_build()\nendif()\n\n########################################################################\n#\n# Project-wide settings\n\n# Name of the project.\n#\n# CMake files in this project can refer to the root source directory\n# as ${gmock_SOURCE_DIR} and to the root binary directory as\n# ${gmock_BINARY_DIR}.\n# Language \"C\" is required for find_package(Threads).\ncmake_minimum_required(VERSION 3.13)\nproject(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)\n\nif (COMMAND set_up_hermetic_build)\n  set_up_hermetic_build()\nendif()\n\n# Instructs CMake to process Google Test's CMakeLists.txt and add its\n# targets to the current scope. We are placing Google Test's binary\n# directory in a subdirectory of our own as VC compilation may break\n# if they are the same (the default).\nadd_subdirectory(\"${gtest_dir}\" \"${gmock_BINARY_DIR}/${gtest_dir}\")\n\n\n# These commands only run if this is the main project\nif(CMAKE_PROJECT_NAME STREQUAL \"gmock\" OR CMAKE_PROJECT_NAME STREQUAL \"googletest-distribution\")\n  # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to\n  # make it prominent in the GUI.\n  option(BUILD_SHARED_LIBS \"Build shared libraries (DLLs).\" OFF)\nelse()\n  mark_as_advanced(gmock_build_tests)\nendif()\n\n# Although Google Test's CMakeLists.txt calls this function, the\n# changes there don't affect the current scope. Therefore we have to\n# call it again here.\nconfig_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake\n\n# Adds Google Mock's and Google Test's header directories to the search path.\n# Get Google Test's include dirs from the target, gtest_SOURCE_DIR is broken\n# when using fetch-content with the name \"GTest\".\nget_target_property(gtest_include_dirs gtest INCLUDE_DIRECTORIES)\nset(gmock_build_include_dirs\n  \"${gmock_SOURCE_DIR}/include\"\n  \"${gmock_SOURCE_DIR}\"\n  \"${gtest_include_dirs}\")\ninclude_directories(${gmock_build_include_dirs})\n\n########################################################################\n#\n# Defines the gmock & gmock_main libraries. User tests should link\n# with one of them.\n\n# Google Mock libraries. We build them using more strict warnings than what\n# are used for other targets, to ensure that Google Mock can be compiled by\n# a user aggressive about warnings.\nif (MSVC)\n  cxx_library(gmock\n              \"${cxx_strict}\"\n              \"${gtest_dir}/src/gtest-all.cc\"\n              src/gmock-all.cc)\n\n  cxx_library(gmock_main\n              \"${cxx_strict}\"\n              \"${gtest_dir}/src/gtest-all.cc\"\n              src/gmock-all.cc\n              src/gmock_main.cc)\nelse()\n  cxx_library(gmock \"${cxx_strict}\" src/gmock-all.cc)\n  target_link_libraries(gmock PUBLIC gtest)\n  set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION})\n  cxx_library(gmock_main \"${cxx_strict}\" src/gmock_main.cc)\n  target_link_libraries(gmock_main PUBLIC gmock)\n  set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})\nendif()\n\nstring(REPLACE \";\" \"$<SEMICOLON>\" dirs \"${gmock_build_include_dirs}\")\ntarget_include_directories(gmock SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\ntarget_include_directories(gmock_main SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n########################################################################\n#\n# Install rules.\ninstall_project(gmock gmock_main)\n\n########################################################################\n#\n# Google Mock's own tests.\n#\n# You can skip this section if you aren't interested in testing\n# Google Mock itself.\n#\n# The tests are not built by default. To build them, set the\n# gmock_build_tests option to ON. You can do it by running ccmake\n# or specifying the -Dgmock_build_tests=ON flag when running cmake.\n\nif (gmock_build_tests)\n  # This must be set in the root directory for the tests to be run by\n  # 'make test' or ctest.\n  enable_testing()\n\n  if (MINGW OR CYGWIN)\n    add_compile_options(\"-Wa,-mbig-obj\")\n  endif()\n\n  ############################################################\n  # C++ tests built with standard compiler flags.\n\n  cxx_test(gmock-actions_test gmock_main)\n  cxx_test(gmock-cardinalities_test gmock_main)\n  cxx_test(gmock_ex_test gmock_main)\n  cxx_test(gmock-function-mocker_test gmock_main)\n  cxx_test(gmock-internal-utils_test gmock_main)\n  cxx_test(gmock-matchers-arithmetic_test gmock_main)\n  cxx_test(gmock-matchers-comparisons_test gmock_main)\n  cxx_test(gmock-matchers-containers_test gmock_main)\n  cxx_test(gmock-matchers-misc_test gmock_main)\n  cxx_test(gmock-more-actions_test gmock_main)\n  cxx_test(gmock-nice-strict_test gmock_main)\n  cxx_test(gmock-port_test gmock_main)\n  cxx_test(gmock-spec-builders_test gmock_main)\n  cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc)\n  cxx_test(gmock_test gmock_main)\n\n  if (DEFINED GTEST_HAS_PTHREAD)\n    cxx_test(gmock_stress_test gmock)\n  endif()\n\n  # gmock_all_test is commented to save time building and running tests.\n  # Uncomment if necessary.\n  # cxx_test(gmock_all_test gmock_main)\n\n  ############################################################\n  # C++ tests built with non-standard compiler flags.\n\n  if (MSVC)\n    cxx_library(gmock_main_no_exception \"${cxx_no_exception}\"\n      \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n    cxx_library(gmock_main_no_rtti \"${cxx_no_rtti}\"\n      \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n  else()\n    cxx_library(gmock_main_no_exception \"${cxx_no_exception}\" src/gmock_main.cc)\n    target_link_libraries(gmock_main_no_exception PUBLIC gmock)\n\n    cxx_library(gmock_main_no_rtti \"${cxx_no_rtti}\" src/gmock_main.cc)\n    target_link_libraries(gmock_main_no_rtti PUBLIC gmock)\n  endif()\n  cxx_test_with_flags(gmock-more-actions_no_exception_test \"${cxx_no_exception}\"\n    gmock_main_no_exception test/gmock-more-actions_test.cc)\n\n  cxx_test_with_flags(gmock_no_rtti_test \"${cxx_no_rtti}\"\n    gmock_main_no_rtti test/gmock-spec-builders_test.cc)\n\n  cxx_shared_library(shared_gmock_main \"${cxx_default}\"\n    \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n  # Tests that a binary can be built with Google Mock as a shared library. On\n  # some system configurations, it may not possible to run the binary without\n  # knowing more details about the system configurations. We do not try to run\n  # this binary. To get a more robust shared library coverage, configure with\n  # -DBUILD_SHARED_LIBS=ON.\n  cxx_executable_with_flags(shared_gmock_test_ \"${cxx_default}\"\n    shared_gmock_main test/gmock-spec-builders_test.cc)\n  set_target_properties(shared_gmock_test_\n    PROPERTIES\n    COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n\n  ############################################################\n  # Python tests.\n\n  cxx_executable(gmock_leak_test_ test gmock_main)\n  py_test(gmock_leak_test)\n\n  cxx_executable(gmock_output_test_ test gmock)\n  py_test(gmock_output_test)\nendif()\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/cmake/gmock.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gmock\nDescription: GoogleMock (without main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gtest = @PROJECT_VERSION@\nLibs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/cmake/gmock_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gmock_main\nDescription: GoogleMock (with main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gmock = @PROJECT_VERSION@\nLibs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-actions.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// The ACTION* family of macros can be used in a namespace scope to\n// define custom actions easily.  The syntax:\n//\n//   ACTION(name) { statements; }\n//\n// will define an action with the given name that executes the\n// statements.  The value returned by the statements will be used as\n// the return value of the action.  Inside the statements, you can\n// refer to the K-th (0-based) argument of the mock function by\n// 'argK', and refer to its type by 'argK_type'.  For example:\n//\n//   ACTION(IncrementArg1) {\n//     arg1_type temp = arg1;\n//     return ++(*temp);\n//   }\n//\n// allows you to write\n//\n//   ...WillOnce(IncrementArg1());\n//\n// You can also refer to the entire argument tuple and its type by\n// 'args' and 'args_type', and refer to the mock function type and its\n// return type by 'function_type' and 'return_type'.\n//\n// Note that you don't need to specify the types of the mock function\n// arguments.  However rest assured that your code is still type-safe:\n// you'll get a compiler error if *arg1 doesn't support the ++\n// operator, or if the type of ++(*arg1) isn't compatible with the\n// mock function's return type, for example.\n//\n// Sometimes you'll want to parameterize the action.   For that you can use\n// another macro:\n//\n//   ACTION_P(name, param_name) { statements; }\n//\n// For example:\n//\n//   ACTION_P(Add, n) { return arg0 + n; }\n//\n// will allow you to write:\n//\n//   ...WillOnce(Add(5));\n//\n// Note that you don't need to provide the type of the parameter\n// either.  If you need to reference the type of a parameter named\n// 'foo', you can write 'foo_type'.  For example, in the body of\n// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type\n// of 'n'.\n//\n// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support\n// multi-parameter actions.\n//\n// For the purpose of typing, you can view\n//\n//   ACTION_Pk(Foo, p1, ..., pk) { ... }\n//\n// as shorthand for\n//\n//   template <typename p1_type, ..., typename pk_type>\n//   FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }\n//\n// In particular, you can provide the template type arguments\n// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);\n// although usually you can rely on the compiler to infer the types\n// for you automatically.  You can assign the result of expression\n// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,\n// pk_type>.  This can be useful when composing actions.\n//\n// You can also overload actions with different numbers of parameters:\n//\n//   ACTION_P(Plus, a) { ... }\n//   ACTION_P2(Plus, a, b) { ... }\n//\n// While it's tempting to always use the ACTION* macros when defining\n// a new action, you should also consider implementing ActionInterface\n// or using MakePolymorphicAction() instead, especially if you need to\n// use the action a lot.  While these approaches require more work,\n// they give you more control on the types of the mock function\n// arguments and the action parameters, which in general leads to\n// better compiler error messages that pay off in the long run.  They\n// also allow overloading actions based on parameter types (as opposed\n// to just based on the number of parameters).\n//\n// CAVEAT:\n//\n// ACTION*() can only be used in a namespace scope as templates cannot be\n// declared inside of a local class.\n// Users can, however, define any local functors (e.g. a lambda) that\n// can be used as actions.\n//\n// MORE INFORMATION:\n//\n// To learn more about using these macros, please search for 'ACTION' on\n// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n\n#ifndef _WIN32_WCE\n#include <errno.h>\n#endif\n\n#include <algorithm>\n#include <exception>\n#include <functional>\n#include <memory>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <utility>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gmock/internal/gmock-pp.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\nnamespace testing {\n\n// To implement an action Foo, define:\n//   1. a class FooAction that implements the ActionInterface interface, and\n//   2. a factory function that creates an Action object from a\n//      const FooAction*.\n//\n// The two-level delegation design follows that of Matcher, providing\n// consistency for extension developers.  It also eases ownership\n// management as Action objects can now be copied like plain values.\n\nnamespace internal {\n\n// BuiltInDefaultValueGetter<T, true>::Get() returns a\n// default-constructed T value.  BuiltInDefaultValueGetter<T,\n// false>::Get() crashes with an error.\n//\n// This primary template is used when kDefaultConstructible is true.\ntemplate <typename T, bool kDefaultConstructible>\nstruct BuiltInDefaultValueGetter {\n  static T Get() { return T(); }\n};\ntemplate <typename T>\nstruct BuiltInDefaultValueGetter<T, false> {\n  static T Get() {\n    Assert(false, __FILE__, __LINE__,\n           \"Default action undefined for the function return type.\");\n#if defined(__GNUC__) || defined(__clang__)\n    __builtin_unreachable();\n#elif defined(_MSC_VER)\n    __assume(0);\n#else\n    return Invalid<T>();\n    // The above statement will never be reached, but is required in\n    // order for this function to compile.\n#endif\n  }\n};\n\n// BuiltInDefaultValue<T>::Get() returns the \"built-in\" default value\n// for type T, which is NULL when T is a raw pointer type, 0 when T is\n// a numeric type, false when T is bool, or \"\" when T is string or\n// std::string.  In addition, in C++11 and above, it turns a\n// default-constructed T value if T is default constructible.  For any\n// other type T, the built-in default T value is undefined, and the\n// function will abort the process.\ntemplate <typename T>\nclass BuiltInDefaultValue {\n public:\n  // This function returns true if and only if type T has a built-in default\n  // value.\n  static bool Exists() { return ::std::is_default_constructible<T>::value; }\n\n  static T Get() {\n    return BuiltInDefaultValueGetter<\n        T, ::std::is_default_constructible<T>::value>::Get();\n  }\n};\n\n// This partial specialization says that we use the same built-in\n// default value for T and const T.\ntemplate <typename T>\nclass BuiltInDefaultValue<const T> {\n public:\n  static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }\n  static T Get() { return BuiltInDefaultValue<T>::Get(); }\n};\n\n// This partial specialization defines the default values for pointer\n// types.\ntemplate <typename T>\nclass BuiltInDefaultValue<T*> {\n public:\n  static bool Exists() { return true; }\n  static T* Get() { return nullptr; }\n};\n\n// The following specializations define the default values for\n// specific types we care about.\n#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \\\n  template <>                                                     \\\n  class BuiltInDefaultValue<type> {                               \\\n   public:                                                        \\\n    static bool Exists() { return true; }                         \\\n    static type Get() { return value; }                           \\\n  }\n\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, );  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, \"\");\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\\0');\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\\0');\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\\0');\n\n// There's no need for a default action for signed wchar_t, as that\n// type is the same as wchar_t for gcc, and invalid for MSVC.\n//\n// There's also no need for a default action for unsigned wchar_t, as\n// that type is the same as unsigned int for gcc, and invalid for\n// MSVC.\n#if GMOCK_WCHAR_T_IS_NATIVE_\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U);  // NOLINT\n#endif\n\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U);  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0);     // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL);     // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L);        // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0);  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0);    // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);\n\n#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_\n\n// Partial implementations of metaprogramming types from the standard library\n// not available in C++11.\n\ntemplate <typename P>\nstruct negation\n    // NOLINTNEXTLINE\n    : std::integral_constant<bool, bool(!P::value)> {};\n\n// Base case: with zero predicates the answer is always true.\ntemplate <typename...>\nstruct conjunction : std::true_type {};\n\n// With a single predicate, the answer is that predicate.\ntemplate <typename P1>\nstruct conjunction<P1> : P1 {};\n\n// With multiple predicates the answer is the first predicate if that is false,\n// and we recurse otherwise.\ntemplate <typename P1, typename... Ps>\nstruct conjunction<P1, Ps...>\n    : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {};\n\ntemplate <typename...>\nstruct disjunction : std::false_type {};\n\ntemplate <typename P1>\nstruct disjunction<P1> : P1 {};\n\ntemplate <typename P1, typename... Ps>\nstruct disjunction<P1, Ps...>\n    // NOLINTNEXTLINE\n    : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {};\n\ntemplate <typename...>\nusing void_t = void;\n\n// Detects whether an expression of type `From` can be implicitly converted to\n// `To` according to [conv]. In C++17, [conv]/3 defines this as follows:\n//\n//     An expression e can be implicitly converted to a type T if and only if\n//     the declaration T t=e; is well-formed, for some invented temporary\n//     variable t ([dcl.init]).\n//\n// [conv]/2 implies we can use function argument passing to detect whether this\n// initialization is valid.\n//\n// Note that this is distinct from is_convertible, which requires this be valid:\n//\n//     To test() {\n//       return declval<From>();\n//     }\n//\n// In particular, is_convertible doesn't give the correct answer when `To` and\n// `From` are the same non-moveable type since `declval<From>` will be an rvalue\n// reference, defeating the guaranteed copy elision that would otherwise make\n// this function work.\n//\n// REQUIRES: `From` is not cv void.\ntemplate <typename From, typename To>\nstruct is_implicitly_convertible {\n private:\n  // A function that accepts a parameter of type T. This can be called with type\n  // U successfully only if U is implicitly convertible to T.\n  template <typename T>\n  static void Accept(T);\n\n  // A function that creates a value of type T.\n  template <typename T>\n  static T Make();\n\n  // An overload be selected when implicit conversion from T to To is possible.\n  template <typename T, typename = decltype(Accept<To>(Make<T>()))>\n  static std::true_type TestImplicitConversion(int);\n\n  // A fallback overload selected in all other cases.\n  template <typename T>\n  static std::false_type TestImplicitConversion(...);\n\n public:\n  using type = decltype(TestImplicitConversion<From>(0));\n  static constexpr bool value = type::value;\n};\n\n// Like std::invoke_result_t from C++17, but works only for objects with call\n// operators (not e.g. member function pointers, which we don't need specific\n// support for in OnceAction because std::function deals with them).\ntemplate <typename F, typename... Args>\nusing call_result_t = decltype(std::declval<F>()(std::declval<Args>()...));\n\ntemplate <typename Void, typename R, typename F, typename... Args>\nstruct is_callable_r_impl : std::false_type {};\n\n// Specialize the struct for those template arguments where call_result_t is\n// well-formed. When it's not, the generic template above is chosen, resulting\n// in std::false_type.\ntemplate <typename R, typename F, typename... Args>\nstruct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>\n    : std::conditional<\n          std::is_void<R>::value,  //\n          std::true_type,          //\n          is_implicitly_convertible<call_result_t<F, Args...>, R>>::type {};\n\n// Like std::is_invocable_r from C++17, but works only for objects with call\n// operators. See the note on call_result_t.\ntemplate <typename R, typename F, typename... Args>\nusing is_callable_r = is_callable_r_impl<void, R, F, Args...>;\n\n// Like std::as_const from C++17.\ntemplate <typename T>\ntypename std::add_const<T>::type& as_const(T& t) {\n  return t;\n}\n\n}  // namespace internal\n\n// Specialized for function types below.\ntemplate <typename F>\nclass OnceAction;\n\n// An action that can only be used once.\n//\n// This is accepted by WillOnce, which doesn't require the underlying action to\n// be copy-constructible (only move-constructible), and promises to invoke it as\n// an rvalue reference. This allows the action to work with move-only types like\n// std::move_only_function in a type-safe manner.\n//\n// For example:\n//\n//     // Assume we have some API that needs to accept a unique pointer to some\n//     // non-copyable object Foo.\n//     void AcceptUniquePointer(std::unique_ptr<Foo> foo);\n//\n//     // We can define an action that provides a Foo to that API. Because It\n//     // has to give away its unique pointer, it must not be called more than\n//     // once, so its call operator is &&-qualified.\n//     struct ProvideFoo {\n//       std::unique_ptr<Foo> foo;\n//\n//       void operator()() && {\n//         AcceptUniquePointer(std::move(Foo));\n//       }\n//     };\n//\n//     // This action can be used with WillOnce.\n//     EXPECT_CALL(mock, Call)\n//         .WillOnce(ProvideFoo{std::make_unique<Foo>(...)});\n//\n//     // But a call to WillRepeatedly will fail to compile. This is correct,\n//     // since the action cannot correctly be used repeatedly.\n//     EXPECT_CALL(mock, Call)\n//         .WillRepeatedly(ProvideFoo{std::make_unique<Foo>(...)});\n//\n// A less-contrived example would be an action that returns an arbitrary type,\n// whose &&-qualified call operator is capable of dealing with move-only types.\ntemplate <typename Result, typename... Args>\nclass OnceAction<Result(Args...)> final {\n private:\n  // True iff we can use the given callable type (or lvalue reference) directly\n  // via StdFunctionAdaptor.\n  template <typename Callable>\n  using IsDirectlyCompatible = internal::conjunction<\n      // It must be possible to capture the callable in StdFunctionAdaptor.\n      std::is_constructible<typename std::decay<Callable>::type, Callable>,\n      // The callable must be compatible with our signature.\n      internal::is_callable_r<Result, typename std::decay<Callable>::type,\n                              Args...>>;\n\n  // True iff we can use the given callable type via StdFunctionAdaptor once we\n  // ignore incoming arguments.\n  template <typename Callable>\n  using IsCompatibleAfterIgnoringArguments = internal::conjunction<\n      // It must be possible to capture the callable in a lambda.\n      std::is_constructible<typename std::decay<Callable>::type, Callable>,\n      // The callable must be invocable with zero arguments, returning something\n      // convertible to Result.\n      internal::is_callable_r<Result, typename std::decay<Callable>::type>>;\n\n public:\n  // Construct from a callable that is directly compatible with our mocked\n  // signature: it accepts our function type's arguments and returns something\n  // convertible to our result type.\n  template <typename Callable,\n            typename std::enable_if<\n                internal::conjunction<\n                    // Teach clang on macOS that we're not talking about a\n                    // copy/move constructor here. Otherwise it gets confused\n                    // when checking the is_constructible requirement of our\n                    // traits above.\n                    internal::negation<std::is_same<\n                        OnceAction, typename std::decay<Callable>::type>>,\n                    IsDirectlyCompatible<Callable>>  //\n                ::value,\n                int>::type = 0>\n  OnceAction(Callable&& callable)  // NOLINT\n      : function_(StdFunctionAdaptor<typename std::decay<Callable>::type>(\n            {}, std::forward<Callable>(callable))) {}\n\n  // As above, but for a callable that ignores the mocked function's arguments.\n  template <typename Callable,\n            typename std::enable_if<\n                internal::conjunction<\n                    // Teach clang on macOS that we're not talking about a\n                    // copy/move constructor here. Otherwise it gets confused\n                    // when checking the is_constructible requirement of our\n                    // traits above.\n                    internal::negation<std::is_same<\n                        OnceAction, typename std::decay<Callable>::type>>,\n                    // Exclude callables for which the overload above works.\n                    // We'd rather provide the arguments if possible.\n                    internal::negation<IsDirectlyCompatible<Callable>>,\n                    IsCompatibleAfterIgnoringArguments<Callable>>::value,\n                int>::type = 0>\n  OnceAction(Callable&& callable)  // NOLINT\n                                   // Call the constructor above with a callable\n                                   // that ignores the input arguments.\n      : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{\n            std::forward<Callable>(callable)}) {}\n\n  // We are naturally copyable because we store only an std::function, but\n  // semantically we should not be copyable.\n  OnceAction(const OnceAction&) = delete;\n  OnceAction& operator=(const OnceAction&) = delete;\n  OnceAction(OnceAction&&) = default;\n\n  // Invoke the underlying action callable with which we were constructed,\n  // handing it the supplied arguments.\n  Result Call(Args... args) && {\n    return function_(std::forward<Args>(args)...);\n  }\n\n private:\n  // An adaptor that wraps a callable that is compatible with our signature and\n  // being invoked as an rvalue reference so that it can be used as an\n  // StdFunctionAdaptor. This throws away type safety, but that's fine because\n  // this is only used by WillOnce, which we know calls at most once.\n  //\n  // Once we have something like std::move_only_function from C++23, we can do\n  // away with this.\n  template <typename Callable>\n  class StdFunctionAdaptor final {\n   public:\n    // A tag indicating that the (otherwise universal) constructor is accepting\n    // the callable itself, instead of e.g. stealing calls for the move\n    // constructor.\n    struct CallableTag final {};\n\n    template <typename F>\n    explicit StdFunctionAdaptor(CallableTag, F&& callable)\n        : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {}\n\n    // Rather than explicitly returning Result, we return whatever the wrapped\n    // callable returns. This allows for compatibility with existing uses like\n    // the following, when the mocked function returns void:\n    //\n    //     EXPECT_CALL(mock_fn_, Call)\n    //         .WillOnce([&] {\n    //            [...]\n    //            return 0;\n    //         });\n    //\n    // Such a callable can be turned into std::function<void()>. If we use an\n    // explicit return type of Result here then it *doesn't* work with\n    // std::function, because we'll get a \"void function should not return a\n    // value\" error.\n    //\n    // We need not worry about incompatible result types because the SFINAE on\n    // OnceAction already checks this for us. std::is_invocable_r_v itself makes\n    // the same allowance for void result types.\n    template <typename... ArgRefs>\n    internal::call_result_t<Callable, ArgRefs...> operator()(\n        ArgRefs&&... args) const {\n      return std::move(*callable_)(std::forward<ArgRefs>(args)...);\n    }\n\n   private:\n    // We must put the callable on the heap so that we are copyable, which\n    // std::function needs.\n    std::shared_ptr<Callable> callable_;\n  };\n\n  // An adaptor that makes a callable that accepts zero arguments callable with\n  // our mocked arguments.\n  template <typename Callable>\n  struct IgnoreIncomingArguments {\n    internal::call_result_t<Callable> operator()(Args&&...) {\n      return std::move(callable)();\n    }\n\n    Callable callable;\n  };\n\n  std::function<Result(Args...)> function_;\n};\n\n// When an unexpected function call is encountered, Google Mock will\n// let it return a default value if the user has specified one for its\n// return type, or if the return type has a built-in default value;\n// otherwise Google Mock won't know what value to return and will have\n// to abort the process.\n//\n// The DefaultValue<T> class allows a user to specify the\n// default value for a type T that is both copyable and publicly\n// destructible (i.e. anything that can be used as a function return\n// type).  The usage is:\n//\n//   // Sets the default value for type T to be foo.\n//   DefaultValue<T>::Set(foo);\ntemplate <typename T>\nclass DefaultValue {\n public:\n  // Sets the default value for type T; requires T to be\n  // copy-constructable and have a public destructor.\n  static void Set(T x) {\n    delete producer_;\n    producer_ = new FixedValueProducer(x);\n  }\n\n  // Provides a factory function to be called to generate the default value.\n  // This method can be used even if T is only move-constructible, but it is not\n  // limited to that case.\n  typedef T (*FactoryFunction)();\n  static void SetFactory(FactoryFunction factory) {\n    delete producer_;\n    producer_ = new FactoryValueProducer(factory);\n  }\n\n  // Unsets the default value for type T.\n  static void Clear() {\n    delete producer_;\n    producer_ = nullptr;\n  }\n\n  // Returns true if and only if the user has set the default value for type T.\n  static bool IsSet() { return producer_ != nullptr; }\n\n  // Returns true if T has a default return value set by the user or there\n  // exists a built-in default value.\n  static bool Exists() {\n    return IsSet() || internal::BuiltInDefaultValue<T>::Exists();\n  }\n\n  // Returns the default value for type T if the user has set one;\n  // otherwise returns the built-in default value. Requires that Exists()\n  // is true, which ensures that the return value is well-defined.\n  static T Get() {\n    return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()\n                                : producer_->Produce();\n  }\n\n private:\n  class ValueProducer {\n   public:\n    virtual ~ValueProducer() = default;\n    virtual T Produce() = 0;\n  };\n\n  class FixedValueProducer : public ValueProducer {\n   public:\n    explicit FixedValueProducer(T value) : value_(value) {}\n    T Produce() override { return value_; }\n\n   private:\n    const T value_;\n    FixedValueProducer(const FixedValueProducer&) = delete;\n    FixedValueProducer& operator=(const FixedValueProducer&) = delete;\n  };\n\n  class FactoryValueProducer : public ValueProducer {\n   public:\n    explicit FactoryValueProducer(FactoryFunction factory)\n        : factory_(factory) {}\n    T Produce() override { return factory_(); }\n\n   private:\n    const FactoryFunction factory_;\n    FactoryValueProducer(const FactoryValueProducer&) = delete;\n    FactoryValueProducer& operator=(const FactoryValueProducer&) = delete;\n  };\n\n  static ValueProducer* producer_;\n};\n\n// This partial specialization allows a user to set default values for\n// reference types.\ntemplate <typename T>\nclass DefaultValue<T&> {\n public:\n  // Sets the default value for type T&.\n  static void Set(T& x) {  // NOLINT\n    address_ = &x;\n  }\n\n  // Unsets the default value for type T&.\n  static void Clear() { address_ = nullptr; }\n\n  // Returns true if and only if the user has set the default value for type T&.\n  static bool IsSet() { return address_ != nullptr; }\n\n  // Returns true if T has a default return value set by the user or there\n  // exists a built-in default value.\n  static bool Exists() {\n    return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();\n  }\n\n  // Returns the default value for type T& if the user has set one;\n  // otherwise returns the built-in default value if there is one;\n  // otherwise aborts the process.\n  static T& Get() {\n    return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()\n                               : *address_;\n  }\n\n private:\n  static T* address_;\n};\n\n// This specialization allows DefaultValue<void>::Get() to\n// compile.\ntemplate <>\nclass DefaultValue<void> {\n public:\n  static bool Exists() { return true; }\n  static void Get() {}\n};\n\n// Points to the user-set default value for type T.\ntemplate <typename T>\ntypename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;\n\n// Points to the user-set default value for type T&.\ntemplate <typename T>\nT* DefaultValue<T&>::address_ = nullptr;\n\n// Implement this interface to define an action for function type F.\ntemplate <typename F>\nclass ActionInterface {\n public:\n  typedef typename internal::Function<F>::Result Result;\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n  ActionInterface() = default;\n  virtual ~ActionInterface() = default;\n\n  // Performs the action.  This method is not const, as in general an\n  // action can have side effects and be stateful.  For example, a\n  // get-the-next-element-from-the-collection action will need to\n  // remember the current element.\n  virtual Result Perform(const ArgumentTuple& args) = 0;\n\n private:\n  ActionInterface(const ActionInterface&) = delete;\n  ActionInterface& operator=(const ActionInterface&) = delete;\n};\n\ntemplate <typename F>\nclass Action;\n\n// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)\n// object that represents an action to be taken when a mock function of type\n// R(Args...) is called. The implementation of Action<T> is just a\n// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! You\n// can view an object implementing ActionInterface<F> as a concrete action\n// (including its current state), and an Action<F> object as a handle to it.\ntemplate <typename R, typename... Args>\nclass Action<R(Args...)> {\n private:\n  using F = R(Args...);\n\n  // Adapter class to allow constructing Action from a legacy ActionInterface.\n  // New code should create Actions from functors instead.\n  struct ActionAdapter {\n    // Adapter must be copyable to satisfy std::function requirements.\n    ::std::shared_ptr<ActionInterface<F>> impl_;\n\n    template <typename... InArgs>\n    typename internal::Function<F>::Result operator()(InArgs&&... args) {\n      return impl_->Perform(\n          ::std::forward_as_tuple(::std::forward<InArgs>(args)...));\n    }\n  };\n\n  template <typename G>\n  using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;\n\n public:\n  typedef typename internal::Function<F>::Result Result;\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n  // Constructs a null Action.  Needed for storing Action objects in\n  // STL containers.\n  Action() = default;\n\n  // Construct an Action from a specified callable.\n  // This cannot take std::function directly, because then Action would not be\n  // directly constructible from lambda (it would require two conversions).\n  template <\n      typename G,\n      typename = typename std::enable_if<internal::disjunction<\n          IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>,\n                                                        G>>::value>::type>\n  Action(G&& fun) {  // NOLINT\n    Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());\n  }\n\n  // Constructs an Action from its implementation.\n  explicit Action(ActionInterface<F>* impl)\n      : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}\n\n  // This constructor allows us to turn an Action<Func> object into an\n  // Action<F>, as long as F's arguments can be implicitly converted\n  // to Func's and Func's return type can be implicitly converted to F's.\n  template <typename Func>\n  Action(const Action<Func>& action)  // NOLINT\n      : fun_(action.fun_) {}\n\n  // Returns true if and only if this is the DoDefault() action.\n  bool IsDoDefault() const { return fun_ == nullptr; }\n\n  // Performs the action.  Note that this method is const even though\n  // the corresponding method in ActionInterface is not.  The reason\n  // is that a const Action<F> means that it cannot be re-bound to\n  // another concrete action, not that the concrete action it binds to\n  // cannot change state.  (Think of the difference between a const\n  // pointer and a pointer to const.)\n  Result Perform(ArgumentTuple args) const {\n    if (IsDoDefault()) {\n      internal::IllegalDoDefault(__FILE__, __LINE__);\n    }\n    return internal::Apply(fun_, ::std::move(args));\n  }\n\n  // An action can be used as a OnceAction, since it's obviously safe to call it\n  // once.\n  operator OnceAction<F>() const {  // NOLINT\n    // Return a OnceAction-compatible callable that calls Perform with the\n    // arguments it is provided. We could instead just return fun_, but then\n    // we'd need to handle the IsDoDefault() case separately.\n    struct OA {\n      Action<F> action;\n\n      R operator()(Args... args) && {\n        return action.Perform(\n            std::forward_as_tuple(std::forward<Args>(args)...));\n      }\n    };\n\n    return OA{*this};\n  }\n\n private:\n  template <typename G>\n  friend class Action;\n\n  template <typename G>\n  void Init(G&& g, ::std::true_type) {\n    fun_ = ::std::forward<G>(g);\n  }\n\n  template <typename G>\n  void Init(G&& g, ::std::false_type) {\n    fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};\n  }\n\n  template <typename FunctionImpl>\n  struct IgnoreArgs {\n    template <typename... InArgs>\n    Result operator()(const InArgs&...) const {\n      return function_impl();\n    }\n\n    FunctionImpl function_impl;\n  };\n\n  // fun_ is an empty function if and only if this is the DoDefault() action.\n  ::std::function<F> fun_;\n};\n\n// The PolymorphicAction class template makes it easy to implement a\n// polymorphic action (i.e. an action that can be used in mock\n// functions of than one type, e.g. Return()).\n//\n// To define a polymorphic action, a user first provides a COPYABLE\n// implementation class that has a Perform() method template:\n//\n//   class FooAction {\n//    public:\n//     template <typename Result, typename ArgumentTuple>\n//     Result Perform(const ArgumentTuple& args) const {\n//       // Processes the arguments and returns a result, using\n//       // std::get<N>(args) to get the N-th (0-based) argument in the tuple.\n//     }\n//     ...\n//   };\n//\n// Then the user creates the polymorphic action using\n// MakePolymorphicAction(object) where object has type FooAction.  See\n// the definition of Return(void) and SetArgumentPointee<N>(value) for\n// complete examples.\ntemplate <typename Impl>\nclass PolymorphicAction {\n public:\n  explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}\n\n  template <typename F>\n  operator Action<F>() const {\n    return Action<F>(new MonomorphicImpl<F>(impl_));\n  }\n\n private:\n  template <typename F>\n  class MonomorphicImpl : public ActionInterface<F> {\n   public:\n    typedef typename internal::Function<F>::Result Result;\n    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}\n\n    Result Perform(const ArgumentTuple& args) override {\n      return impl_.template Perform<Result>(args);\n    }\n\n   private:\n    Impl impl_;\n  };\n\n  Impl impl_;\n};\n\n// Creates an Action from its implementation and returns it.  The\n// created Action object owns the implementation.\ntemplate <typename F>\nAction<F> MakeAction(ActionInterface<F>* impl) {\n  return Action<F>(impl);\n}\n\n// Creates a polymorphic action from its implementation.  This is\n// easier to use than the PolymorphicAction<Impl> constructor as it\n// doesn't require you to explicitly write the template argument, e.g.\n//\n//   MakePolymorphicAction(foo);\n// vs\n//   PolymorphicAction<TypeOfFoo>(foo);\ntemplate <typename Impl>\ninline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {\n  return PolymorphicAction<Impl>(impl);\n}\n\nnamespace internal {\n\n// Helper struct to specialize ReturnAction to execute a move instead of a copy\n// on return. Useful for move-only types, but could be used on any type.\ntemplate <typename T>\nstruct ByMoveWrapper {\n  explicit ByMoveWrapper(T value) : payload(std::move(value)) {}\n  T payload;\n};\n\n// The general implementation of Return(R). Specializations follow below.\ntemplate <typename R>\nclass ReturnAction final {\n public:\n  explicit ReturnAction(R value) : value_(std::move(value)) {}\n\n  template <typename U, typename... Args,\n            typename = typename std::enable_if<conjunction<\n                // See the requirements documented on Return.\n                negation<std::is_same<void, U>>,  //\n                negation<std::is_reference<U>>,   //\n                std::is_convertible<R, U>,        //\n                std::is_move_constructible<U>>::value>::type>\n  operator OnceAction<U(Args...)>() && {  // NOLINT\n    return Impl<U>(std::move(value_));\n  }\n\n  template <typename U, typename... Args,\n            typename = typename std::enable_if<conjunction<\n                // See the requirements documented on Return.\n                negation<std::is_same<void, U>>,   //\n                negation<std::is_reference<U>>,    //\n                std::is_convertible<const R&, U>,  //\n                std::is_copy_constructible<U>>::value>::type>\n  operator Action<U(Args...)>() const {  // NOLINT\n    return Impl<U>(value_);\n  }\n\n private:\n  // Implements the Return(x) action for a mock function that returns type U.\n  template <typename U>\n  class Impl final {\n   public:\n    // The constructor used when the return value is allowed to move from the\n    // input value (i.e. we are converting to OnceAction).\n    explicit Impl(R&& input_value)\n        : state_(new State(std::move(input_value))) {}\n\n    // The constructor used when the return value is not allowed to move from\n    // the input value (i.e. we are converting to Action).\n    explicit Impl(const R& input_value) : state_(new State(input_value)) {}\n\n    U operator()() && { return std::move(state_->value); }\n    U operator()() const& { return state_->value; }\n\n   private:\n    // We put our state on the heap so that the compiler-generated copy/move\n    // constructors work correctly even when U is a reference-like type. This is\n    // necessary only because we eagerly create State::value (see the note on\n    // that symbol for details). If we instead had only the input value as a\n    // member then the default constructors would work fine.\n    //\n    // For example, when R is std::string and U is std::string_view, value is a\n    // reference to the string backed by input_value. The copy constructor would\n    // copy both, so that we wind up with a new input_value object (with the\n    // same contents) and a reference to the *old* input_value object rather\n    // than the new one.\n    struct State {\n      explicit State(const R& input_value_in)\n          : input_value(input_value_in),\n            // Make an implicit conversion to Result before initializing the U\n            // object we store, avoiding calling any explicit constructor of U\n            // from R.\n            //\n            // This simulates the language rules: a function with return type U\n            // that does `return R()` requires R to be implicitly convertible to\n            // U, and uses that path for the conversion, even U Result has an\n            // explicit constructor from R.\n            value(ImplicitCast_<U>(internal::as_const(input_value))) {}\n\n      // As above, but for the case where we're moving from the ReturnAction\n      // object because it's being used as a OnceAction.\n      explicit State(R&& input_value_in)\n          : input_value(std::move(input_value_in)),\n            // For the same reason as above we make an implicit conversion to U\n            // before initializing the value.\n            //\n            // Unlike above we provide the input value as an rvalue to the\n            // implicit conversion because this is a OnceAction: it's fine if it\n            // wants to consume the input value.\n            value(ImplicitCast_<U>(std::move(input_value))) {}\n\n      // A copy of the value originally provided by the user. We retain this in\n      // addition to the value of the mock function's result type below in case\n      // the latter is a reference-like type. See the std::string_view example\n      // in the documentation on Return.\n      R input_value;\n\n      // The value we actually return, as the type returned by the mock function\n      // itself.\n      //\n      // We eagerly initialize this here, rather than lazily doing the implicit\n      // conversion automatically each time Perform is called, for historical\n      // reasons: in 2009-11, commit a070cbd91c (Google changelist 13540126)\n      // made the Action<U()> conversion operator eagerly convert the R value to\n      // U, but without keeping the R alive. This broke the use case discussed\n      // in the documentation for Return, making reference-like types such as\n      // std::string_view not safe to use as U where the input type R is a\n      // value-like type such as std::string.\n      //\n      // The example the commit gave was not very clear, nor was the issue\n      // thread (https://github.com/google/googlemock/issues/86), but it seems\n      // the worry was about reference-like input types R that flatten to a\n      // value-like type U when being implicitly converted. An example of this\n      // is std::vector<bool>::reference, which is often a proxy type with an\n      // reference to the underlying vector:\n      //\n      //     // Helper method: have the mock function return bools according\n      //     // to the supplied script.\n      //     void SetActions(MockFunction<bool(size_t)>& mock,\n      //                     const std::vector<bool>& script) {\n      //       for (size_t i = 0; i < script.size(); ++i) {\n      //         EXPECT_CALL(mock, Call(i)).WillOnce(Return(script[i]));\n      //       }\n      //     }\n      //\n      //     TEST(Foo, Bar) {\n      //       // Set actions using a temporary vector, whose operator[]\n      //       // returns proxy objects that references that will be\n      //       // dangling once the call to SetActions finishes and the\n      //       // vector is destroyed.\n      //       MockFunction<bool(size_t)> mock;\n      //       SetActions(mock, {false, true});\n      //\n      //       EXPECT_FALSE(mock.AsStdFunction()(0));\n      //       EXPECT_TRUE(mock.AsStdFunction()(1));\n      //     }\n      //\n      // This eager conversion helps with a simple case like this, but doesn't\n      // fully make these types work in general. For example the following still\n      // uses a dangling reference:\n      //\n      //     TEST(Foo, Baz) {\n      //       MockFunction<std::vector<std::string>()> mock;\n      //\n      //       // Return the same vector twice, and then the empty vector\n      //       // thereafter.\n      //       auto action = Return(std::initializer_list<std::string>{\n      //           \"taco\", \"burrito\",\n      //       });\n      //\n      //       EXPECT_CALL(mock, Call)\n      //           .WillOnce(action)\n      //           .WillOnce(action)\n      //           .WillRepeatedly(Return(std::vector<std::string>{}));\n      //\n      //       EXPECT_THAT(mock.AsStdFunction()(),\n      //                   ElementsAre(\"taco\", \"burrito\"));\n      //       EXPECT_THAT(mock.AsStdFunction()(),\n      //                   ElementsAre(\"taco\", \"burrito\"));\n      //       EXPECT_THAT(mock.AsStdFunction()(), IsEmpty());\n      //     }\n      //\n      U value;\n    };\n\n    const std::shared_ptr<State> state_;\n  };\n\n  R value_;\n};\n\n// A specialization of ReturnAction<R> when R is ByMoveWrapper<T> for some T.\n//\n// This version applies the type system-defeating hack of moving from T even in\n// the const call operator, checking at runtime that it isn't called more than\n// once, since the user has declared their intent to do so by using ByMove.\ntemplate <typename T>\nclass ReturnAction<ByMoveWrapper<T>> final {\n public:\n  explicit ReturnAction(ByMoveWrapper<T> wrapper)\n      : state_(new State(std::move(wrapper.payload))) {}\n\n  T operator()() const {\n    GTEST_CHECK_(!state_->called)\n        << \"A ByMove() action must be performed at most once.\";\n\n    state_->called = true;\n    return std::move(state_->value);\n  }\n\n private:\n  // We store our state on the heap so that we are copyable as required by\n  // Action, despite the fact that we are stateful and T may not be copyable.\n  struct State {\n    explicit State(T&& value_in) : value(std::move(value_in)) {}\n\n    T value;\n    bool called = false;\n  };\n\n  const std::shared_ptr<State> state_;\n};\n\n// Implements the ReturnNull() action.\nclass ReturnNullAction {\n public:\n  // Allows ReturnNull() to be used in any pointer-returning function. In C++11\n  // this is enforced by returning nullptr, and in non-C++11 by asserting a\n  // pointer type on compile time.\n  template <typename Result, typename ArgumentTuple>\n  static Result Perform(const ArgumentTuple&) {\n    return nullptr;\n  }\n};\n\n// Implements the Return() action.\nclass ReturnVoidAction {\n public:\n  // Allows Return() to be used in any void-returning function.\n  template <typename Result, typename ArgumentTuple>\n  static void Perform(const ArgumentTuple&) {\n    static_assert(std::is_void<Result>::value, \"Result should be void.\");\n  }\n};\n\n// Implements the polymorphic ReturnRef(x) action, which can be used\n// in any function that returns a reference to the type of x,\n// regardless of the argument types.\ntemplate <typename T>\nclass ReturnRefAction {\n public:\n  // Constructs a ReturnRefAction object from the reference to be returned.\n  explicit ReturnRefAction(T& ref) : ref_(ref) {}  // NOLINT\n\n  // This template type conversion operator allows ReturnRef(x) to be\n  // used in ANY function that returns a reference to x's type.\n  template <typename F>\n  operator Action<F>() const {\n    typedef typename Function<F>::Result Result;\n    // Asserts that the function return type is a reference.  This\n    // catches the user error of using ReturnRef(x) when Return(x)\n    // should be used, and generates some helpful error message.\n    static_assert(std::is_reference<Result>::value,\n                  \"use Return instead of ReturnRef to return a value\");\n    return Action<F>(new Impl<F>(ref_));\n  }\n\n private:\n  // Implements the ReturnRef(x) action for a particular function type F.\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename Function<F>::Result Result;\n    typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(T& ref) : ref_(ref) {}  // NOLINT\n\n    Result Perform(const ArgumentTuple&) override { return ref_; }\n\n   private:\n    T& ref_;\n  };\n\n  T& ref_;\n};\n\n// Implements the polymorphic ReturnRefOfCopy(x) action, which can be\n// used in any function that returns a reference to the type of x,\n// regardless of the argument types.\ntemplate <typename T>\nclass ReturnRefOfCopyAction {\n public:\n  // Constructs a ReturnRefOfCopyAction object from the reference to\n  // be returned.\n  explicit ReturnRefOfCopyAction(const T& value) : value_(value) {}  // NOLINT\n\n  // This template type conversion operator allows ReturnRefOfCopy(x) to be\n  // used in ANY function that returns a reference to x's type.\n  template <typename F>\n  operator Action<F>() const {\n    typedef typename Function<F>::Result Result;\n    // Asserts that the function return type is a reference.  This\n    // catches the user error of using ReturnRefOfCopy(x) when Return(x)\n    // should be used, and generates some helpful error message.\n    static_assert(std::is_reference<Result>::value,\n                  \"use Return instead of ReturnRefOfCopy to return a value\");\n    return Action<F>(new Impl<F>(value_));\n  }\n\n private:\n  // Implements the ReturnRefOfCopy(x) action for a particular function type F.\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename Function<F>::Result Result;\n    typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(const T& value) : value_(value) {}  // NOLINT\n\n    Result Perform(const ArgumentTuple&) override { return value_; }\n\n   private:\n    T value_;\n  };\n\n  const T value_;\n};\n\n// Implements the polymorphic ReturnRoundRobin(v) action, which can be\n// used in any function that returns the element_type of v.\ntemplate <typename T>\nclass ReturnRoundRobinAction {\n public:\n  explicit ReturnRoundRobinAction(std::vector<T> values) {\n    GTEST_CHECK_(!values.empty())\n        << \"ReturnRoundRobin requires at least one element.\";\n    state_->values = std::move(values);\n  }\n\n  template <typename... Args>\n  T operator()(Args&&...) const {\n    return state_->Next();\n  }\n\n private:\n  struct State {\n    T Next() {\n      T ret_val = values[i++];\n      if (i == values.size()) i = 0;\n      return ret_val;\n    }\n\n    std::vector<T> values;\n    size_t i = 0;\n  };\n  std::shared_ptr<State> state_ = std::make_shared<State>();\n};\n\n// Implements the polymorphic DoDefault() action.\nclass DoDefaultAction {\n public:\n  // This template type conversion operator allows DoDefault() to be\n  // used in any function.\n  template <typename F>\n  operator Action<F>() const {\n    return Action<F>();\n  }  // NOLINT\n};\n\n// Implements the Assign action to set a given pointer referent to a\n// particular value.\ntemplate <typename T1, typename T2>\nclass AssignAction {\n public:\n  AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}\n\n  template <typename Result, typename ArgumentTuple>\n  void Perform(const ArgumentTuple& /* args */) const {\n    *ptr_ = value_;\n  }\n\n private:\n  T1* const ptr_;\n  const T2 value_;\n};\n\n#ifndef GTEST_OS_WINDOWS_MOBILE\n\n// Implements the SetErrnoAndReturn action to simulate return from\n// various system calls and libc functions.\ntemplate <typename T>\nclass SetErrnoAndReturnAction {\n public:\n  SetErrnoAndReturnAction(int errno_value, T result)\n      : errno_(errno_value), result_(result) {}\n  template <typename Result, typename ArgumentTuple>\n  Result Perform(const ArgumentTuple& /* args */) const {\n    errno = errno_;\n    return result_;\n  }\n\n private:\n  const int errno_;\n  const T result_;\n};\n\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n// Implements the SetArgumentPointee<N>(x) action for any function\n// whose N-th argument (0-based) is a pointer to x's type.\ntemplate <size_t N, typename A, typename = void>\nstruct SetArgumentPointeeAction {\n  A value;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *::std::get<N>(std::tie(args...)) = value;\n  }\n};\n\n// Implements the Invoke(object_ptr, &Class::Method) action.\ntemplate <class Class, typename MethodPtr>\nstruct InvokeMethodAction {\n  Class* const obj_ptr;\n  const MethodPtr method_ptr;\n\n  template <typename... Args>\n  auto operator()(Args&&... args) const\n      -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {\n    return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);\n  }\n};\n\n// Implements the InvokeWithoutArgs(f) action.  The template argument\n// FunctionImpl is the implementation type of f, which can be either a\n// function pointer or a functor.  InvokeWithoutArgs(f) can be used as an\n// Action<F> as long as f's type is compatible with F.\ntemplate <typename FunctionImpl>\nstruct InvokeWithoutArgsAction {\n  FunctionImpl function_impl;\n\n  // Allows InvokeWithoutArgs(f) to be used as any action whose type is\n  // compatible with f.\n  template <typename... Args>\n  auto operator()(const Args&...) -> decltype(function_impl()) {\n    return function_impl();\n  }\n};\n\n// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.\ntemplate <class Class, typename MethodPtr>\nstruct InvokeMethodWithoutArgsAction {\n  Class* const obj_ptr;\n  const MethodPtr method_ptr;\n\n  using ReturnType =\n      decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());\n\n  template <typename... Args>\n  ReturnType operator()(const Args&...) const {\n    return (obj_ptr->*method_ptr)();\n  }\n};\n\n// Implements the IgnoreResult(action) action.\ntemplate <typename A>\nclass IgnoreResultAction {\n public:\n  explicit IgnoreResultAction(const A& action) : action_(action) {}\n\n  template <typename F>\n  operator Action<F>() const {\n    // Assert statement belongs here because this is the best place to verify\n    // conditions on F. It produces the clearest error messages\n    // in most compilers.\n    // Impl really belongs in this scope as a local class but can't\n    // because MSVC produces duplicate symbols in different translation units\n    // in this case. Until MS fixes that bug we put Impl into the class scope\n    // and put the typedef both here (for use in assert statement) and\n    // in the Impl class. But both definitions must be the same.\n    typedef typename internal::Function<F>::Result Result;\n\n    // Asserts at compile time that F returns void.\n    static_assert(std::is_void<Result>::value, \"Result type should be void.\");\n\n    return Action<F>(new Impl<F>(action_));\n  }\n\n private:\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename internal::Function<F>::Result Result;\n    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(const A& action) : action_(action) {}\n\n    void Perform(const ArgumentTuple& args) override {\n      // Performs the action and ignores its result.\n      action_.Perform(args);\n    }\n\n   private:\n    // Type OriginalFunction is the same as F except that its return\n    // type is IgnoredValue.\n    typedef\n        typename internal::Function<F>::MakeResultIgnoredValue OriginalFunction;\n\n    const Action<OriginalFunction> action_;\n  };\n\n  const A action_;\n};\n\ntemplate <typename InnerAction, size_t... I>\nstruct WithArgsAction {\n  InnerAction inner_action;\n\n  // The signature of the function as seen by the inner action, given an out\n  // action with the given result and argument types.\n  template <typename R, typename... Args>\n  using InnerSignature =\n      R(typename std::tuple_element<I, std::tuple<Args...>>::type...);\n\n  // Rather than a call operator, we must define conversion operators to\n  // particular action types. This is necessary for embedded actions like\n  // DoDefault(), which rely on an action conversion operators rather than\n  // providing a call operator because even with a particular set of arguments\n  // they don't have a fixed return type.\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<InnerAction,\n                              // Unfortunately we can't use the InnerSignature\n                              // alias here; MSVC complains about the I\n                              // parameter pack not being expanded (error C3520)\n                              // despite it being expanded in the type alias.\n                              // TupleElement is also an MSVC workaround.\n                              // See its definition for details.\n                              OnceAction<R(internal::TupleElement<\n                                           I, std::tuple<Args...>>...)>>::value,\n          int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    struct OA {\n      OnceAction<InnerSignature<R, Args...>> inner_action;\n\n      R operator()(Args&&... args) && {\n        return std::move(inner_action)\n            .Call(std::get<I>(\n                std::forward_as_tuple(std::forward<Args>(args)...))...);\n      }\n    };\n\n    return OA{std::move(inner_action)};\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<const InnerAction&,\n                              // Unfortunately we can't use the InnerSignature\n                              // alias here; MSVC complains about the I\n                              // parameter pack not being expanded (error C3520)\n                              // despite it being expanded in the type alias.\n                              // TupleElement is also an MSVC workaround.\n                              // See its definition for details.\n                              Action<R(internal::TupleElement<\n                                       I, std::tuple<Args...>>...)>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    Action<InnerSignature<R, Args...>> converted(inner_action);\n\n    return [converted](Args&&... args) -> R {\n      return converted.Perform(std::forward_as_tuple(\n          std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));\n    };\n  }\n};\n\ntemplate <typename... Actions>\nclass DoAllAction;\n\n// Base case: only a single action.\ntemplate <typename FinalAction>\nclass DoAllAction<FinalAction> {\n public:\n  struct UserConstructorTag {};\n\n  template <typename T>\n  explicit DoAllAction(UserConstructorTag, T&& action)\n      : final_action_(std::forward<T>(action)) {}\n\n  // Rather than a call operator, we must define conversion operators to\n  // particular action types. This is necessary for embedded actions like\n  // DoDefault(), which rely on an action conversion operators rather than\n  // providing a call operator because even with a particular set of arguments\n  // they don't have a fixed return type.\n\n  template <typename R, typename... Args,\n            typename std::enable_if<\n                std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,\n                int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    return std::move(final_action_);\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<const FinalAction&, Action<R(Args...)>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    return final_action_;\n  }\n\n private:\n  FinalAction final_action_;\n};\n\n// Recursive case: support N actions by calling the initial action and then\n// calling through to the base class containing N-1 actions.\ntemplate <typename InitialAction, typename... OtherActions>\nclass DoAllAction<InitialAction, OtherActions...>\n    : private DoAllAction<OtherActions...> {\n private:\n  using Base = DoAllAction<OtherActions...>;\n\n  // The type of reference that should be provided to an initial action for a\n  // mocked function parameter of type T.\n  //\n  // There are two quirks here:\n  //\n  //  *  Unlike most forwarding functions, we pass scalars through by value.\n  //     This isn't strictly necessary because an lvalue reference would work\n  //     fine too and be consistent with other non-reference types, but it's\n  //     perhaps less surprising.\n  //\n  //     For example if the mocked function has signature void(int), then it\n  //     might seem surprising for the user's initial action to need to be\n  //     convertible to Action<void(const int&)>. This is perhaps less\n  //     surprising for a non-scalar type where there may be a performance\n  //     impact, or it might even be impossible, to pass by value.\n  //\n  //  *  More surprisingly, `const T&` is often not a const reference type.\n  //     By the reference collapsing rules in C++17 [dcl.ref]/6, if T refers to\n  //     U& or U&& for some non-scalar type U, then InitialActionArgType<T> is\n  //     U&. In other words, we may hand over a non-const reference.\n  //\n  //     So for example, given some non-scalar type Obj we have the following\n  //     mappings:\n  //\n  //            T               InitialActionArgType<T>\n  //         -------            -----------------------\n  //         Obj                const Obj&\n  //         Obj&               Obj&\n  //         Obj&&              Obj&\n  //         const Obj          const Obj&\n  //         const Obj&         const Obj&\n  //         const Obj&&        const Obj&\n  //\n  //     In other words, the initial actions get a mutable view of an non-scalar\n  //     argument if and only if the mock function itself accepts a non-const\n  //     reference type. They are never given an rvalue reference to an\n  //     non-scalar type.\n  //\n  //     This situation makes sense if you imagine use with a matcher that is\n  //     designed to write through a reference. For example, if the caller wants\n  //     to fill in a reference argument and then return a canned value:\n  //\n  //         EXPECT_CALL(mock, Call)\n  //             .WillOnce(DoAll(SetArgReferee<0>(17), Return(19)));\n  //\n  template <typename T>\n  using InitialActionArgType =\n      typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;\n\n public:\n  struct UserConstructorTag {};\n\n  template <typename T, typename... U>\n  explicit DoAllAction(UserConstructorTag, T&& initial_action,\n                       U&&... other_actions)\n      : Base({}, std::forward<U>(other_actions)...),\n        initial_action_(std::forward<T>(initial_action)) {}\n\n  template <typename R, typename... Args,\n            typename std::enable_if<\n                conjunction<\n                    // Both the initial action and the rest must support\n                    // conversion to OnceAction.\n                    std::is_convertible<\n                        InitialAction,\n                        OnceAction<void(InitialActionArgType<Args>...)>>,\n                    std::is_convertible<Base, OnceAction<R(Args...)>>>::value,\n                int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    // Return an action that first calls the initial action with arguments\n    // filtered through InitialActionArgType, then forwards arguments directly\n    // to the base class to deal with the remaining actions.\n    struct OA {\n      OnceAction<void(InitialActionArgType<Args>...)> initial_action;\n      OnceAction<R(Args...)> remaining_actions;\n\n      R operator()(Args... args) && {\n        std::move(initial_action)\n            .Call(static_cast<InitialActionArgType<Args>>(args)...);\n\n        return std::move(remaining_actions).Call(std::forward<Args>(args)...);\n      }\n    };\n\n    return OA{\n        std::move(initial_action_),\n        std::move(static_cast<Base&>(*this)),\n    };\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          conjunction<\n              // Both the initial action and the rest must support conversion to\n              // Action.\n              std::is_convertible<const InitialAction&,\n                                  Action<void(InitialActionArgType<Args>...)>>,\n              std::is_convertible<const Base&, Action<R(Args...)>>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    // Return an action that first calls the initial action with arguments\n    // filtered through InitialActionArgType, then forwards arguments directly\n    // to the base class to deal with the remaining actions.\n    struct OA {\n      Action<void(InitialActionArgType<Args>...)> initial_action;\n      Action<R(Args...)> remaining_actions;\n\n      R operator()(Args... args) const {\n        initial_action.Perform(std::forward_as_tuple(\n            static_cast<InitialActionArgType<Args>>(args)...));\n\n        return remaining_actions.Perform(\n            std::forward_as_tuple(std::forward<Args>(args)...));\n      }\n    };\n\n    return OA{\n        initial_action_,\n        static_cast<const Base&>(*this),\n    };\n  }\n\n private:\n  InitialAction initial_action_;\n};\n\ntemplate <typename T, typename... Params>\nstruct ReturnNewAction {\n  T* operator()() const {\n    return internal::Apply(\n        [](const Params&... unpacked_params) {\n          return new T(unpacked_params...);\n        },\n        params);\n  }\n  std::tuple<Params...> params;\n};\n\ntemplate <size_t k>\nstruct ReturnArgAction {\n  template <typename... Args,\n            typename = typename std::enable_if<(k < sizeof...(Args))>::type>\n  auto operator()(Args&&... args) const -> decltype(std::get<k>(\n      std::forward_as_tuple(std::forward<Args>(args)...))) {\n    return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));\n  }\n};\n\ntemplate <size_t k, typename Ptr>\nstruct SaveArgAction {\n  Ptr pointer;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *pointer = std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <size_t k, typename Ptr>\nstruct SaveArgPointeeAction {\n  Ptr pointer;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *pointer = *std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <size_t k, typename T>\nstruct SetArgRefereeAction {\n  T value;\n\n  template <typename... Args>\n  void operator()(Args&&... args) const {\n    using argk_type =\n        typename ::std::tuple_element<k, std::tuple<Args...>>::type;\n    static_assert(std::is_lvalue_reference<argk_type>::value,\n                  \"Argument must be a reference type.\");\n    std::get<k>(std::tie(args...)) = value;\n  }\n};\n\ntemplate <size_t k, typename I1, typename I2>\nstruct SetArrayArgumentAction {\n  I1 first;\n  I2 last;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    auto value = std::get<k>(std::tie(args...));\n    for (auto it = first; it != last; ++it, (void)++value) {\n      *value = *it;\n    }\n  }\n};\n\ntemplate <size_t k>\nstruct DeleteArgAction {\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    delete std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <typename Ptr>\nstruct ReturnPointeeAction {\n  Ptr pointer;\n  template <typename... Args>\n  auto operator()(const Args&...) const -> decltype(*pointer) {\n    return *pointer;\n  }\n};\n\n#if GTEST_HAS_EXCEPTIONS\ntemplate <typename T>\nstruct ThrowAction {\n  T exception;\n  // We use a conversion operator to adapt to any return type.\n  template <typename R, typename... Args>\n  operator Action<R(Args...)>() const {  // NOLINT\n    T copy = exception;\n    return [copy](Args...) -> R { throw copy; };\n  }\n};\nstruct RethrowAction {\n  std::exception_ptr exception;\n  template <typename R, typename... Args>\n  operator Action<R(Args...)>() const {  // NOLINT\n    return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };\n  }\n};\n#endif  // GTEST_HAS_EXCEPTIONS\n\n}  // namespace internal\n\n// An Unused object can be implicitly constructed from ANY value.\n// This is handy when defining actions that ignore some or all of the\n// mock function arguments.  For example, given\n//\n//   MOCK_METHOD3(Foo, double(const string& label, double x, double y));\n//   MOCK_METHOD3(Bar, double(int index, double x, double y));\n//\n// instead of\n//\n//   double DistanceToOriginWithLabel(const string& label, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   double DistanceToOriginWithIndex(int index, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   ...\n//   EXPECT_CALL(mock, Foo(\"abc\", _, _))\n//       .WillOnce(Invoke(DistanceToOriginWithLabel));\n//   EXPECT_CALL(mock, Bar(5, _, _))\n//       .WillOnce(Invoke(DistanceToOriginWithIndex));\n//\n// you could write\n//\n//   // We can declare any uninteresting argument as Unused.\n//   double DistanceToOrigin(Unused, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   ...\n//   EXPECT_CALL(mock, Foo(\"abc\", _, _)).WillOnce(Invoke(DistanceToOrigin));\n//   EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));\ntypedef internal::IgnoredValue Unused;\n\n// Creates an action that does actions a1, a2, ..., sequentially in\n// each invocation. All but the last action will have a readonly view of the\n// arguments.\ntemplate <typename... Action>\ninternal::DoAllAction<typename std::decay<Action>::type...> DoAll(\n    Action&&... action) {\n  return internal::DoAllAction<typename std::decay<Action>::type...>(\n      {}, std::forward<Action>(action)...);\n}\n\n// WithArg<k>(an_action) creates an action that passes the k-th\n// (0-based) argument of the mock function to an_action and performs\n// it.  It adapts an action accepting one argument to one that accepts\n// multiple arguments.  For convenience, we also provide\n// WithArgs<k>(an_action) (defined below) as a synonym.\ntemplate <size_t k, typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type, k> WithArg(\n    InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes\n// the selected arguments of the mock function to an_action and\n// performs it.  It serves as an adaptor between actions with\n// different argument lists.\ntemplate <size_t k, size_t... ks, typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>\nWithArgs(InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// WithoutArgs(inner_action) can be used in a mock function with a\n// non-empty argument list to perform inner_action, which takes no\n// argument.  In other words, it adapts an action accepting no\n// argument to one that accepts (and ignores) arguments.\ntemplate <typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type> WithoutArgs(\n    InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// Creates an action that returns a value.\n//\n// The returned type can be used with a mock function returning a non-void,\n// non-reference type U as follows:\n//\n//  *  If R is convertible to U and U is move-constructible, then the action can\n//     be used with WillOnce.\n//\n//  *  If const R& is convertible to U and U is copy-constructible, then the\n//     action can be used with both WillOnce and WillRepeatedly.\n//\n// The mock expectation contains the R value from which the U return value is\n// constructed (a move/copy of the argument to Return). This means that the R\n// value will survive at least until the mock object's expectations are cleared\n// or the mock object is destroyed, meaning that U can safely be a\n// reference-like type such as std::string_view:\n//\n//     // The mock function returns a view of a copy of the string fed to\n//     // Return. The view is valid even after the action is performed.\n//     MockFunction<std::string_view()> mock;\n//     EXPECT_CALL(mock, Call).WillOnce(Return(std::string(\"taco\")));\n//     const std::string_view result = mock.AsStdFunction()();\n//     EXPECT_EQ(\"taco\", result);\n//\ntemplate <typename R>\ninternal::ReturnAction<R> Return(R value) {\n  return internal::ReturnAction<R>(std::move(value));\n}\n\n// Creates an action that returns NULL.\ninline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {\n  return MakePolymorphicAction(internal::ReturnNullAction());\n}\n\n// Creates an action that returns from a void function.\ninline PolymorphicAction<internal::ReturnVoidAction> Return() {\n  return MakePolymorphicAction(internal::ReturnVoidAction());\n}\n\n// Creates an action that returns the reference to a variable.\ntemplate <typename R>\ninline internal::ReturnRefAction<R> ReturnRef(R& x) {  // NOLINT\n  return internal::ReturnRefAction<R>(x);\n}\n\n// Prevent using ReturnRef on reference to temporary.\ntemplate <typename R, R* = nullptr>\ninternal::ReturnRefAction<R> ReturnRef(R&&) = delete;\n\n// Creates an action that returns the reference to a copy of the\n// argument.  The copy is created when the action is constructed and\n// lives as long as the action.\ntemplate <typename R>\ninline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {\n  return internal::ReturnRefOfCopyAction<R>(x);\n}\n\n// DEPRECATED: use Return(x) directly with WillOnce.\n//\n// Modifies the parent action (a Return() action) to perform a move of the\n// argument instead of a copy.\n// Return(ByMove()) actions can only be executed once and will assert this\n// invariant.\ntemplate <typename R>\ninternal::ByMoveWrapper<R> ByMove(R x) {\n  return internal::ByMoveWrapper<R>(std::move(x));\n}\n\n// Creates an action that returns an element of `vals`. Calling this action will\n// repeatedly return the next value from `vals` until it reaches the end and\n// will restart from the beginning.\ntemplate <typename T>\ninternal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {\n  return internal::ReturnRoundRobinAction<T>(std::move(vals));\n}\n\n// Creates an action that returns an element of `vals`. Calling this action will\n// repeatedly return the next value from `vals` until it reaches the end and\n// will restart from the beginning.\ntemplate <typename T>\ninternal::ReturnRoundRobinAction<T> ReturnRoundRobin(\n    std::initializer_list<T> vals) {\n  return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));\n}\n\n// Creates an action that does the default action for the give mock function.\ninline internal::DoDefaultAction DoDefault() {\n  return internal::DoDefaultAction();\n}\n\n// Creates an action that sets the variable pointed by the N-th\n// (0-based) function argument to 'value'.\ntemplate <size_t N, typename T>\ninternal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {\n  return {std::move(value)};\n}\n\n// The following version is DEPRECATED.\ntemplate <size_t N, typename T>\ninternal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {\n  return {std::move(value)};\n}\n\n// Creates an action that sets a pointer referent to a given value.\ntemplate <typename T1, typename T2>\nPolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {\n  return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));\n}\n\n#ifndef GTEST_OS_WINDOWS_MOBILE\n\n// Creates an action that sets errno and returns the appropriate error.\ntemplate <typename T>\nPolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(\n    int errval, T result) {\n  return MakePolymorphicAction(\n      internal::SetErrnoAndReturnAction<T>(errval, result));\n}\n\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n// Various overloads for Invoke().\n\n// Legacy function.\n// Actions can now be implicitly constructed from callables. No need to create\n// wrapper objects.\n// This function exists for backwards compatibility.\ntemplate <typename FunctionImpl>\ntypename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {\n  return std::forward<FunctionImpl>(function_impl);\n}\n\n// Creates an action that invokes the given method on the given object\n// with the mock function's arguments.\ntemplate <class Class, typename MethodPtr>\ninternal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,\n                                                      MethodPtr method_ptr) {\n  return {obj_ptr, method_ptr};\n}\n\n// Creates an action that invokes 'function_impl' with no argument.\ntemplate <typename FunctionImpl>\ninternal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>\nInvokeWithoutArgs(FunctionImpl function_impl) {\n  return {std::move(function_impl)};\n}\n\n// Creates an action that invokes the given method on the given object\n// with no argument.\ntemplate <class Class, typename MethodPtr>\ninternal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(\n    Class* obj_ptr, MethodPtr method_ptr) {\n  return {obj_ptr, method_ptr};\n}\n\n// Creates an action that performs an_action and throws away its\n// result.  In other words, it changes the return type of an_action to\n// void.  an_action MUST NOT return void, or the code won't compile.\ntemplate <typename A>\ninline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {\n  return internal::IgnoreResultAction<A>(an_action);\n}\n\n// Creates a reference wrapper for the given L-value.  If necessary,\n// you can explicitly specify the type of the reference.  For example,\n// suppose 'derived' is an object of type Derived, ByRef(derived)\n// would wrap a Derived&.  If you want to wrap a const Base& instead,\n// where Base is a base class of Derived, just write:\n//\n//   ByRef<const Base>(derived)\n//\n// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.\n// However, it may still be used for consistency with ByMove().\ntemplate <typename T>\ninline ::std::reference_wrapper<T> ByRef(T& l_value) {  // NOLINT\n  return ::std::reference_wrapper<T>(l_value);\n}\n\n// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new\n// instance of type T, constructed on the heap with constructor arguments\n// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.\ntemplate <typename T, typename... Params>\ninternal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew(\n    Params&&... params) {\n  return {std::forward_as_tuple(std::forward<Params>(params)...)};\n}\n\n// Action ReturnArg<k>() returns the k-th argument of the mock function.\ntemplate <size_t k>\ninternal::ReturnArgAction<k> ReturnArg() {\n  return {};\n}\n\n// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the\n// mock function to *pointer.\ntemplate <size_t k, typename Ptr>\ninternal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {\n  return {pointer};\n}\n\n// Action SaveArgPointee<k>(pointer) saves the value pointed to\n// by the k-th (0-based) argument of the mock function to *pointer.\ntemplate <size_t k, typename Ptr>\ninternal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) {\n  return {pointer};\n}\n\n// Action SetArgReferee<k>(value) assigns 'value' to the variable\n// referenced by the k-th (0-based) argument of the mock function.\ntemplate <size_t k, typename T>\ninternal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee(\n    T&& value) {\n  return {std::forward<T>(value)};\n}\n\n// Action SetArrayArgument<k>(first, last) copies the elements in\n// source range [first, last) to the array pointed to by the k-th\n// (0-based) argument, which can be either a pointer or an\n// iterator. The action does not take ownership of the elements in the\n// source range.\ntemplate <size_t k, typename I1, typename I2>\ninternal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first,\n                                                             I2 last) {\n  return {first, last};\n}\n\n// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock\n// function.\ntemplate <size_t k>\ninternal::DeleteArgAction<k> DeleteArg() {\n  return {};\n}\n\n// This action returns the value pointed to by 'pointer'.\ntemplate <typename Ptr>\ninternal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {\n  return {pointer};\n}\n\n#if GTEST_HAS_EXCEPTIONS\n// Action Throw(exception) can be used in a mock function of any type\n// to throw the given exception.  Any copyable value can be thrown,\n// except for std::exception_ptr, which is likely a mistake if\n// thrown directly.\ntemplate <typename T>\ntypename std::enable_if<\n    !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,\n    internal::ThrowAction<typename std::decay<T>::type>>::type\nThrow(T&& exception) {\n  return {std::forward<T>(exception)};\n}\n// Action Rethrow(exception_ptr) can be used in a mock function of any type\n// to rethrow any exception_ptr. Note that the same object is thrown each time.\ninline internal::RethrowAction Rethrow(std::exception_ptr exception) {\n  return {std::move(exception)};\n}\n#endif  // GTEST_HAS_EXCEPTIONS\n\nnamespace internal {\n\n// A macro from the ACTION* family (defined later in gmock-generated-actions.h)\n// defines an action that can be used in a mock function.  Typically,\n// these actions only care about a subset of the arguments of the mock\n// function.  For example, if such an action only uses the second\n// argument, it can be used in any mock function that takes >= 2\n// arguments where the type of the second argument is compatible.\n//\n// Therefore, the action implementation must be prepared to take more\n// arguments than it needs.  The ExcessiveArg type is used to\n// represent those excessive arguments.  In order to keep the compiler\n// error messages tractable, we define it in the testing namespace\n// instead of testing::internal.  However, this is an INTERNAL TYPE\n// and subject to change without notice, so a user MUST NOT USE THIS\n// TYPE DIRECTLY.\nstruct ExcessiveArg {};\n\n// Builds an implementation of an Action<> for some particular signature, using\n// a class defined by an ACTION* macro.\ntemplate <typename F, typename Impl>\nstruct ActionImpl;\n\ntemplate <typename Impl>\nstruct ImplBase {\n  struct Holder {\n    // Allows each copy of the Action<> to get to the Impl.\n    explicit operator const Impl&() const { return *ptr; }\n    std::shared_ptr<Impl> ptr;\n  };\n  using type = typename std::conditional<std::is_constructible<Impl>::value,\n                                         Impl, Holder>::type;\n};\n\ntemplate <typename R, typename... Args, typename Impl>\nstruct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {\n  using Base = typename ImplBase<Impl>::type;\n  using function_type = R(Args...);\n  using args_type = std::tuple<Args...>;\n\n  ActionImpl() = default;  // Only defined if appropriate for Base.\n  explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} {}\n\n  R operator()(Args&&... arg) const {\n    static constexpr size_t kMaxArgs =\n        sizeof...(Args) <= 10 ? sizeof...(Args) : 10;\n    return Apply(std::make_index_sequence<kMaxArgs>{},\n                 std::make_index_sequence<10 - kMaxArgs>{},\n                 args_type{std::forward<Args>(arg)...});\n  }\n\n  template <std::size_t... arg_id, std::size_t... excess_id>\n  R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,\n          const args_type& args) const {\n    // Impl need not be specific to the signature of action being implemented;\n    // only the implementing function body needs to have all of the specific\n    // types instantiated.  Up to 10 of the args that are provided by the\n    // args_type get passed, followed by a dummy of unspecified type for the\n    // remainder up to 10 explicit args.\n    static constexpr ExcessiveArg kExcessArg{};\n    return static_cast<const Impl&>(*this)\n        .template gmock_PerformImpl<\n            /*function_type=*/function_type, /*return_type=*/R,\n            /*args_type=*/args_type,\n            /*argN_type=*/\n            typename std::tuple_element<arg_id, args_type>::type...>(\n            /*args=*/args, std::get<arg_id>(args)...,\n            ((void)excess_id, kExcessArg)...);\n  }\n};\n\n// Stores a default-constructed Impl as part of the Action<>'s\n// std::function<>. The Impl should be trivial to copy.\ntemplate <typename F, typename Impl>\n::testing::Action<F> MakeAction() {\n  return ::testing::Action<F>(ActionImpl<F, Impl>());\n}\n\n// Stores just the one given instance of Impl.\ntemplate <typename F, typename Impl>\n::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {\n  return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));\n}\n\n#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \\\n  , GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i\n#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                               \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \\\n      GMOCK_INTERNAL_ARG_UNUSED, , 10)\n\n#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i\n#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \\\n  const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10)\n\n#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type\n#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \\\n  GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10))\n\n#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type\n#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params))\n\n#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type\n#define GMOCK_ACTION_TYPE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params))\n\n#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \\\n  , param##_type gmock_p##i\n#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params))\n\n#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \\\n  , std::forward<param##_type>(gmock_p##i)\n#define GMOCK_ACTION_GVALUE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params))\n\n#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \\\n  , param(::std::forward<param##_type>(gmock_p##i))\n#define GMOCK_ACTION_INIT_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params))\n\n#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param;\n#define GMOCK_ACTION_FIELD_PARAMS_(params) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params)\n\n#define GMOCK_INTERNAL_ACTION(name, full_name, params)                         \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  class full_name {                                                            \\\n   public:                                                                     \\\n    explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))               \\\n        : impl_(std::make_shared<gmock_Impl>(                                  \\\n              GMOCK_ACTION_GVALUE_PARAMS_(params))) {}                         \\\n    full_name(const full_name&) = default;                                     \\\n    full_name(full_name&&) noexcept = default;                                 \\\n    template <typename F>                                                      \\\n    operator ::testing::Action<F>() const {                                    \\\n      return ::testing::internal::MakeAction<F>(impl_);                        \\\n    }                                                                          \\\n                                                                               \\\n   private:                                                                    \\\n    class gmock_Impl {                                                         \\\n     public:                                                                   \\\n      explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))            \\\n          : GMOCK_ACTION_INIT_PARAMS_(params) {}                               \\\n      template <typename function_type, typename return_type,                  \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \\\n      GMOCK_ACTION_FIELD_PARAMS_(params)                                       \\\n    };                                                                         \\\n    std::shared_ptr<const gmock_Impl> impl_;                                   \\\n  };                                                                           \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \\\n      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_;        \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \\\n      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) {                              \\\n    return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>(                       \\\n        GMOCK_ACTION_GVALUE_PARAMS_(params));                                  \\\n  }                                                                            \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  template <typename function_type, typename return_type, typename args_type,  \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \\\n  return_type                                                                  \\\n  full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl::gmock_PerformImpl( \\\n      GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const\n\n}  // namespace internal\n\n// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.\n#define ACTION(name)                                                          \\\n  class name##Action {                                                        \\\n   public:                                                                    \\\n    explicit name##Action() noexcept {}                                       \\\n    name##Action(const name##Action&) noexcept {}                             \\\n    template <typename F>                                                     \\\n    operator ::testing::Action<F>() const {                                   \\\n      return ::testing::internal::MakeAction<F, gmock_Impl>();                \\\n    }                                                                         \\\n                                                                              \\\n   private:                                                                   \\\n    class gmock_Impl {                                                        \\\n     public:                                                                  \\\n      template <typename function_type, typename return_type,                 \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>        \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \\\n    };                                                                        \\\n  };                                                                          \\\n  inline name##Action name() GTEST_MUST_USE_RESULT_;                          \\\n  inline name##Action name() { return name##Action(); }                       \\\n  template <typename function_type, typename return_type, typename args_type, \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                \\\n  return_type name##Action::gmock_Impl::gmock_PerformImpl(                    \\\n      GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const\n\n#define ACTION_P(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))\n\n#define ACTION_P2(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))\n\n#define ACTION_P3(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))\n\n#define ACTION_P4(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))\n\n#define ACTION_P5(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))\n\n#define ACTION_P6(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))\n\n#define ACTION_P7(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))\n\n#define ACTION_P8(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))\n\n#define ACTION_P9(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))\n\n#define ACTION_P10(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-cardinalities.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some commonly used cardinalities.  More\n// cardinalities can be defined by the user implementing the\n// CardinalityInterface interface if necessary.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n\n#include <limits.h>\n\n#include <memory>\n#include <ostream>  // NOLINT\n\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// To implement a cardinality Foo, define:\n//   1. a class FooCardinality that implements the\n//      CardinalityInterface interface, and\n//   2. a factory function that creates a Cardinality object from a\n//      const FooCardinality*.\n//\n// The two-level delegation design follows that of Matcher, providing\n// consistency for extension developers.  It also eases ownership\n// management as Cardinality objects can now be copied like plain values.\n\n// The implementation of a cardinality.\nclass CardinalityInterface {\n public:\n  virtual ~CardinalityInterface() = default;\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  virtual int ConservativeLowerBound() const { return 0; }\n  virtual int ConservativeUpperBound() const { return INT_MAX; }\n\n  // Returns true if and only if call_count calls will satisfy this\n  // cardinality.\n  virtual bool IsSatisfiedByCallCount(int call_count) const = 0;\n\n  // Returns true if and only if call_count calls will saturate this\n  // cardinality.\n  virtual bool IsSaturatedByCallCount(int call_count) const = 0;\n\n  // Describes self to an ostream.\n  virtual void DescribeTo(::std::ostream* os) const = 0;\n};\n\n// A Cardinality is a copyable and IMMUTABLE (except by assignment)\n// object that specifies how many times a mock function is expected to\n// be called.  The implementation of Cardinality is just a std::shared_ptr\n// to const CardinalityInterface. Don't inherit from Cardinality!\nclass GTEST_API_ Cardinality {\n public:\n  // Constructs a null cardinality.  Needed for storing Cardinality\n  // objects in STL containers.\n  Cardinality() = default;\n\n  // Constructs a Cardinality from its implementation.\n  explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }\n  int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }\n\n  // Returns true if and only if call_count calls will satisfy this\n  // cardinality.\n  bool IsSatisfiedByCallCount(int call_count) const {\n    return impl_->IsSatisfiedByCallCount(call_count);\n  }\n\n  // Returns true if and only if call_count calls will saturate this\n  // cardinality.\n  bool IsSaturatedByCallCount(int call_count) const {\n    return impl_->IsSaturatedByCallCount(call_count);\n  }\n\n  // Returns true if and only if call_count calls will over-saturate this\n  // cardinality, i.e. exceed the maximum number of allowed calls.\n  bool IsOverSaturatedByCallCount(int call_count) const {\n    return impl_->IsSaturatedByCallCount(call_count) &&\n           !impl_->IsSatisfiedByCallCount(call_count);\n  }\n\n  // Describes self to an ostream\n  void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }\n\n  // Describes the given actual call count to an ostream.\n  static void DescribeActualCallCountTo(int actual_call_count,\n                                        ::std::ostream* os);\n\n private:\n  std::shared_ptr<const CardinalityInterface> impl_;\n};\n\n// Creates a cardinality that allows at least n calls.\nGTEST_API_ Cardinality AtLeast(int n);\n\n// Creates a cardinality that allows at most n calls.\nGTEST_API_ Cardinality AtMost(int n);\n\n// Creates a cardinality that allows any number of calls.\nGTEST_API_ Cardinality AnyNumber();\n\n// Creates a cardinality that allows between min and max calls.\nGTEST_API_ Cardinality Between(int min, int max);\n\n// Creates a cardinality that allows exactly n calls.\nGTEST_API_ Cardinality Exactly(int n);\n\n// Creates a cardinality from its implementation.\ninline Cardinality MakeCardinality(const CardinalityInterface* c) {\n  return Cardinality(c);\n}\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-function-mocker.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements MOCK_METHOD.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n\n#include <cstddef>\n#include <type_traits>  // IWYU pragma: keep\n#include <utility>      // IWYU pragma: keep\n\n#include \"gmock/gmock-spec-builders.h\"\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-pp.h\"\n\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing identity_t = T;\n\ntemplate <typename Pattern>\nstruct ThisRefAdjuster {\n  template <typename T>\n  using AdjustT = typename std::conditional<\n      std::is_const<typename std::remove_reference<Pattern>::type>::value,\n      typename std::conditional<std::is_lvalue_reference<Pattern>::value,\n                                const T&, const T&&>::type,\n      typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&,\n                                T&&>::type>::type;\n\n  template <typename MockType>\n  static AdjustT<MockType> Adjust(const MockType& mock) {\n    return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock));\n  }\n};\n\nconstexpr bool PrefixOf(const char* a, const char* b) {\n  return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {\n  return N <= M && internal::PrefixOf(prefix, str);\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {\n  return N <= M && internal::PrefixOf(suffix, str + M - N);\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool Equals(const char (&a)[N], const char (&b)[M]) {\n  return N == M && internal::PrefixOf(a, b);\n}\n\ntemplate <size_t N>\nconstexpr bool ValidateSpec(const char (&spec)[N]) {\n  return internal::Equals(\"const\", spec) ||\n         internal::Equals(\"override\", spec) ||\n         internal::Equals(\"final\", spec) ||\n         internal::Equals(\"noexcept\", spec) ||\n         (internal::StartsWith(\"noexcept(\", spec) &&\n          internal::EndsWith(\")\", spec)) ||\n         internal::Equals(\"ref(&)\", spec) ||\n         internal::Equals(\"ref(&&)\", spec) ||\n         (internal::StartsWith(\"Calltype(\", spec) &&\n          internal::EndsWith(\")\", spec));\n}\n\n}  // namespace internal\n\n// The style guide prohibits \"using\" statements in a namespace scope\n// inside a header file.  However, the FunctionMocker class template\n// is meant to be defined in the ::testing namespace.  The following\n// line is just a trick for working around a bug in MSVC 8.0, which\n// cannot handle it if we define FunctionMocker in ::testing.\nusing internal::FunctionMocker;\n}  // namespace testing\n\n#define MOCK_METHOD(...)                                               \\\n  GMOCK_INTERNAL_WARNING_PUSH()                                        \\\n  GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-member-function\")    \\\n  GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \\\n  GMOCK_INTERNAL_WARNING_POP()\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \\\n  GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec)  \\\n  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args);                                \\\n  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec);                                \\\n  GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(                                   \\\n      GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args));        \\\n  GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec)                                  \\\n  GMOCK_INTERNAL_MOCK_METHOD_IMPL(                                         \\\n      GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec),  \\\n      GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \\\n      GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec),                             \\\n      GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec),                             \\\n      GMOCK_INTERNAL_GET_REF_SPEC(_Spec),                                  \\\n      (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_WRONG_ARITY(...)                                      \\\n  static_assert(                                                             \\\n      false,                                                                 \\\n      \"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, \"             \\\n      \"_MethodName, _Args and optionally _Spec. _Args and _Spec must be \"    \\\n      \"enclosed in parentheses. If _Ret is a type with unprotected commas, \" \\\n      \"it must also be enclosed in parentheses.\")\n\n#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \\\n  static_assert(                                  \\\n      GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple),        \\\n      GMOCK_PP_STRINGIZE(_Tuple) \" should be enclosed in parentheses.\")\n\n#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...)                 \\\n  static_assert(                                                       \\\n      std::is_function<__VA_ARGS__>::value,                            \\\n      \"Signature must be a function type, maybe return type contains \" \\\n      \"unprotected comma.\");                                           \\\n  static_assert(                                                       \\\n      ::testing::tuple_size<typename ::testing::internal::Function<    \\\n              __VA_ARGS__>::ArgumentTuple>::value == _N,               \\\n      \"This method does not take \" GMOCK_PP_STRINGIZE(                 \\\n          _N) \" arguments. Parenthesize all types with unprotected commas.\")\n\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness,           \\\n                                        _Override, _Final, _NoexceptSpec,      \\\n                                        _CallType, _RefSpec, _Signature)       \\\n  typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS(               \\\n      _Signature)>::Result                                                     \\\n  GMOCK_INTERNAL_EXPAND(_CallType)                                             \\\n      _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N))   \\\n          GMOCK_PP_IF(_Constness, const, )                                     \\\n              _RefSpec _NoexceptSpec GMOCK_PP_IF(_Override, override, )        \\\n                  GMOCK_PP_IF(_Final, final, ) {                               \\\n    GMOCK_MOCKER_(_N, _Constness, _MethodName)                                 \\\n        .SetOwnerAndName(this, #_MethodName);                                  \\\n    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \\\n        .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N));  \\\n  }                                                                            \\\n  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \\\n      GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N))       \\\n      GMOCK_PP_IF(_Constness, const, ) _RefSpec {                              \\\n    GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this);            \\\n    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \\\n        .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N));         \\\n  }                                                                            \\\n  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \\\n      const ::testing::internal::WithoutMatchers&,                             \\\n      GMOCK_PP_IF(_Constness, const, )::testing::internal::Function<           \\\n          GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \\\n    return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF(                   \\\n        _Constness, const, ) int _RefSpec>::Adjust(*this)                      \\\n        .gmock_##_MethodName(GMOCK_PP_REPEAT(                                  \\\n            GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N));               \\\n  }                                                                            \\\n  mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)>        \\\n  GMOCK_MOCKER_(_N, _Constness, _MethodName)\n\n#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__\n\n// Valid modifiers.\n#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))\n\n#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(                       \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))\n\n#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))\n\n#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple)\n\n#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem)          \\\n  GMOCK_PP_IF(                                                          \\\n      GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \\\n      _elem, )\n\n#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple)\n\n#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem)          \\\n  GMOCK_PP_IF(                                                          \\\n      GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \\\n      GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )\n\n#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)\n\n#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem)                       \\\n  GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \\\n              GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )\n\n#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \\\n  static_assert(                                                     \\\n      ::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)),  \\\n      \"Token \\'\" GMOCK_PP_STRINGIZE(                                 \\\n          _elem) \"\\' cannot be recognized as a valid specification \" \\\n                 \"modifier. Is a ',' missing?\");\n#else\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem)                 \\\n  static_assert(                                                               \\\n      (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) +         \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) +      \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) +         \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) +      \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) +           \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \\\n      GMOCK_PP_STRINGIZE(                                                      \\\n          _elem) \" cannot be recognized as a valid specification modifier.\");\n#endif  // GMOCK_INTERNAL_STRICT_SPEC_ASSERT\n\n// Modifiers implementation.\n#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_CONST_I_const ,\n\n#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,\n\n#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,\n\n#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,\n\n#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_REF_I_ref ,\n\n#define GMOCK_INTERNAL_UNPACK_ref(x) x\n\n#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,\n\n#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__\n\n// Note: The use of `identity_t` here allows _Ret to represent return types that\n// would normally need to be specified in a different way. For example, a method\n// returning a function pointer must be written as\n//\n// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)\n//\n// But we only support placing the return type at the beginning. To handle this,\n// we wrap all calls in identity_t, so that a declaration will be expanded to\n//\n// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)\n//\n// This allows us to work around the syntactic oddities of function/method\n// types.\n#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)                                 \\\n  ::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \\\n                                              GMOCK_PP_REMOVE_PARENS,         \\\n                                              GMOCK_PP_IDENTITY)(_Ret)>(      \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))\n\n#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem)                          \\\n  GMOCK_PP_COMMA_IF(_i)                                                \\\n  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \\\n              GMOCK_PP_IDENTITY)                                       \\\n  (_elem)\n\n#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _)            \\\n  GMOCK_PP_COMMA_IF(_i)                                        \\\n  GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \\\n  GMOCK_PP_COMMA_IF(_i)                               \\\n  ::std::forward<GMOCK_INTERNAL_ARG_O(                \\\n      _i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)\n\n#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _)        \\\n  GMOCK_PP_COMMA_IF(_i)                                            \\\n  GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \\\n  GMOCK_PP_COMMA_IF(_i)                             \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \\\n  GMOCK_PP_COMMA_IF(_i)                                      \\\n  ::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()\n\n#define GMOCK_INTERNAL_ARG_O(_i, ...) \\\n  typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type\n\n#define GMOCK_INTERNAL_MATCHER_O(_i, ...)                          \\\n  const ::testing::Matcher<typename ::testing::internal::Function< \\\n      __VA_ARGS__>::template Arg<_i>::type>&\n\n#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__)\n#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__)\n#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__)\n#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__)\n#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__)\n#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__)\n#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__)\n#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__)\n#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__)\n#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__)\n#define MOCK_METHOD10(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__)\n#define MOCK_CONST_METHOD1(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__)\n#define MOCK_CONST_METHOD2(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__)\n#define MOCK_CONST_METHOD3(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__)\n#define MOCK_CONST_METHOD4(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__)\n#define MOCK_CONST_METHOD5(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__)\n#define MOCK_CONST_METHOD6(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__)\n#define MOCK_CONST_METHOD7(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__)\n#define MOCK_CONST_METHOD8(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__)\n#define MOCK_CONST_METHOD9(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__)\n#define MOCK_CONST_METHOD10(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__)\n\n#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__)\n#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__)\n#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__)\n#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__)\n#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__)\n#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__)\n#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__)\n#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__)\n#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__)\n#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__)\n#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__)\n\n#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__)\n#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__)\n#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__)\n#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__)\n#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__)\n#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__)\n#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__)\n#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__)\n#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__)\n#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__)\n#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__)\n\n#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \\\n  GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(                                  \\\n      args_num, ::testing::internal::identity_t<__VA_ARGS__>);            \\\n  GMOCK_INTERNAL_MOCK_METHOD_IMPL(                                        \\\n      args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, ,          \\\n      (::testing::internal::identity_t<__VA_ARGS__>))\n\n#define GMOCK_MOCKER_(arity, constness, Method) \\\n  GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-matchers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// The MATCHER* family of macros can be used in a namespace scope to\n// define custom matchers easily.\n//\n// Basic Usage\n// ===========\n//\n// The syntax\n//\n//   MATCHER(name, description_string) { statements; }\n//\n// defines a matcher with the given name that executes the statements,\n// which must return a bool to indicate if the match succeeds.  Inside\n// the statements, you can refer to the value being matched by 'arg',\n// and refer to its type by 'arg_type'.\n//\n// The description string documents what the matcher does, and is used\n// to generate the failure message when the match fails.  Since a\n// MATCHER() is usually defined in a header file shared by multiple\n// C++ source files, we require the description to be a C-string\n// literal to avoid possible side effects.  It can be empty, in which\n// case we'll use the sequence of words in the matcher name as the\n// description.\n//\n// For example:\n//\n//   MATCHER(IsEven, \"\") { return (arg % 2) == 0; }\n//\n// allows you to write\n//\n//   // Expects mock_foo.Bar(n) to be called where n is even.\n//   EXPECT_CALL(mock_foo, Bar(IsEven()));\n//\n// or,\n//\n//   // Verifies that the value of some_expression is even.\n//   EXPECT_THAT(some_expression, IsEven());\n//\n// If the above assertion fails, it will print something like:\n//\n//   Value of: some_expression\n//   Expected: is even\n//     Actual: 7\n//\n// where the description \"is even\" is automatically calculated from the\n// matcher name IsEven.\n//\n// Argument Type\n// =============\n//\n// Note that the type of the value being matched (arg_type) is\n// determined by the context in which you use the matcher and is\n// supplied to you by the compiler, so you don't need to worry about\n// declaring it (nor can you).  This allows the matcher to be\n// polymorphic.  For example, IsEven() can be used to match any type\n// where the value of \"(arg % 2) == 0\" can be implicitly converted to\n// a bool.  In the \"Bar(IsEven())\" example above, if method Bar()\n// takes an int, 'arg_type' will be int; if it takes an unsigned long,\n// 'arg_type' will be unsigned long; and so on.\n//\n// Parameterizing Matchers\n// =======================\n//\n// Sometimes you'll want to parameterize the matcher.  For that you\n// can use another macro:\n//\n//   MATCHER_P(name, param_name, description_string) { statements; }\n//\n// For example:\n//\n//   MATCHER_P(HasAbsoluteValue, value, \"\") { return abs(arg) == value; }\n//\n// will allow you to write:\n//\n//   EXPECT_THAT(Blah(\"a\"), HasAbsoluteValue(n));\n//\n// which may lead to this message (assuming n is 10):\n//\n//   Value of: Blah(\"a\")\n//   Expected: has absolute value 10\n//     Actual: -9\n//\n// Note that both the matcher description and its parameter are\n// printed, making the message human-friendly.\n//\n// In the matcher definition body, you can write 'foo_type' to\n// reference the type of a parameter named 'foo'.  For example, in the\n// body of MATCHER_P(HasAbsoluteValue, value) above, you can write\n// 'value_type' to refer to the type of 'value'.\n//\n// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to\n// support multi-parameter matchers.\n//\n// Describing Parameterized Matchers\n// =================================\n//\n// The last argument to MATCHER*() is a string-typed expression.  The\n// expression can reference all of the matcher's parameters and a\n// special bool-typed variable named 'negation'.  When 'negation' is\n// false, the expression should evaluate to the matcher's description;\n// otherwise it should evaluate to the description of the negation of\n// the matcher.  For example,\n//\n//   using testing::PrintToString;\n//\n//   MATCHER_P2(InClosedRange, low, hi,\n//       std::string(negation ? \"is not\" : \"is\") + \" in range [\" +\n//       PrintToString(low) + \", \" + PrintToString(hi) + \"]\") {\n//     return low <= arg && arg <= hi;\n//   }\n//   ...\n//   EXPECT_THAT(3, InClosedRange(4, 6));\n//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));\n//\n// would generate two failures that contain the text:\n//\n//   Expected: is in range [4, 6]\n//   ...\n//   Expected: is not in range [2, 4]\n//\n// If you specify \"\" as the description, the failure message will\n// contain the sequence of words in the matcher name followed by the\n// parameter values printed as a tuple.  For example,\n//\n//   MATCHER_P2(InClosedRange, low, hi, \"\") { ... }\n//   ...\n//   EXPECT_THAT(3, InClosedRange(4, 6));\n//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));\n//\n// would generate two failures that contain the text:\n//\n//   Expected: in closed range (4, 6)\n//   ...\n//   Expected: not (in closed range (2, 4))\n//\n// Types of Matcher Parameters\n// ===========================\n//\n// For the purpose of typing, you can view\n//\n//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }\n//\n// as shorthand for\n//\n//   template <typename p1_type, ..., typename pk_type>\n//   FooMatcherPk<p1_type, ..., pk_type>\n//   Foo(p1_type p1, ..., pk_type pk) { ... }\n//\n// When you write Foo(v1, ..., vk), the compiler infers the types of\n// the parameters v1, ..., and vk for you.  If you are not happy with\n// the result of the type inference, you can specify the types by\n// explicitly instantiating the template, as in Foo<long, bool>(5,\n// false).  As said earlier, you don't get to (or need to) specify\n// 'arg_type' as that's determined by the context in which the matcher\n// is used.  You can assign the result of expression Foo(p1, ..., pk)\n// to a variable of type FooMatcherPk<p1_type, ..., pk_type>.  This\n// can be useful when composing matchers.\n//\n// While you can instantiate a matcher template with reference types,\n// passing the parameters by pointer usually makes your code more\n// readable.  If, however, you still want to pass a parameter by\n// reference, be aware that in the failure message generated by the\n// matcher you will see the value of the referenced object but not its\n// address.\n//\n// Explaining Match Results\n// ========================\n//\n// Sometimes the matcher description alone isn't enough to explain why\n// the match has failed or succeeded.  For example, when expecting a\n// long string, it can be very helpful to also print the diff between\n// the expected string and the actual one.  To achieve that, you can\n// optionally stream additional information to a special variable\n// named result_listener, whose type is a pointer to class\n// MatchResultListener:\n//\n//   MATCHER_P(EqualsLongString, str, \"\") {\n//     if (arg == str) return true;\n//\n//     *result_listener << \"the difference: \"\n///                     << DiffStrings(str, arg);\n//     return false;\n//   }\n//\n// Overloading Matchers\n// ====================\n//\n// You can overload matchers with different numbers of parameters:\n//\n//   MATCHER_P(Blah, a, description_string1) { ... }\n//   MATCHER_P2(Blah, a, b, description_string2) { ... }\n//\n// Caveats\n// =======\n//\n// When defining a new matcher, you should also consider implementing\n// MatcherInterface or using MakePolymorphicMatcher().  These\n// approaches require more work than the MATCHER* macros, but also\n// give you more control on the types of the value being matched and\n// the matcher parameters, which may leads to better compiler error\n// messages when the matcher is used wrong.  They also allow\n// overloading matchers based on parameter types (as opposed to just\n// based on the number of parameters).\n//\n// MATCHER*() can only be used in a namespace scope as templates cannot be\n// declared inside of a local class.\n//\n// More Information\n// ================\n//\n// To learn more about using these macros, please search for 'MATCHER'\n// on\n// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md\n//\n// This file also implements some commonly used argument matchers.  More\n// matchers can be defined by the user implementing the\n// MatcherInterface<T> interface if necessary.\n//\n// See googletest/include/gtest/gtest-matchers.h for the definition of class\n// Matcher, class MatcherInterface, and others.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n\n#include <algorithm>\n#include <cmath>\n#include <exception>\n#include <functional>\n#include <initializer_list>\n#include <ios>\n#include <iterator>\n#include <limits>\n#include <memory>\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gmock/internal/gmock-pp.h\"\n#include \"gtest/gtest.h\"\n\n// MSVC warning C5046 is new as of VS2017 version 15.8.\n#if defined(_MSC_VER) && _MSC_VER >= 1915\n#define GMOCK_MAYBE_5046_ 5046\n#else\n#define GMOCK_MAYBE_5046_\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by\n                              clients of class B */\n    /* Symbol involving type with internal linkage not defined */)\n\nnamespace testing {\n\n// To implement a matcher Foo for type T, define:\n//   1. a class FooMatcherImpl that implements the\n//      MatcherInterface<T> interface, and\n//   2. a factory function that creates a Matcher<T> object from a\n//      FooMatcherImpl*.\n//\n// The two-level delegation design makes it possible to allow a user\n// to write \"v\" instead of \"Eq(v)\" where a Matcher is expected, which\n// is impossible if we pass matchers by pointers.  It also eases\n// ownership management as Matcher objects can now be copied like\n// plain values.\n\n// A match result listener that stores the explanation in a string.\nclass StringMatchResultListener : public MatchResultListener {\n public:\n  StringMatchResultListener() : MatchResultListener(&ss_) {}\n\n  // Returns the explanation accumulated so far.\n  std::string str() const { return ss_.str(); }\n\n  // Clears the explanation accumulated so far.\n  void Clear() { ss_.str(\"\"); }\n\n private:\n  ::std::stringstream ss_;\n\n  StringMatchResultListener(const StringMatchResultListener&) = delete;\n  StringMatchResultListener& operator=(const StringMatchResultListener&) =\n      delete;\n};\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// The MatcherCastImpl class template is a helper for implementing\n// MatcherCast().  We need this helper in order to partially\n// specialize the implementation of MatcherCast() (C++ allows\n// class/struct templates to be partially specialized, but not\n// function templates.).\n\n// This general version is used when MatcherCast()'s argument is a\n// polymorphic matcher (i.e. something that can be converted to a\n// Matcher but is not one yet; for example, Eq(value)) or a value (for\n// example, \"hello\").\ntemplate <typename T, typename M>\nclass MatcherCastImpl {\n public:\n  static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {\n    // M can be a polymorphic matcher, in which case we want to use\n    // its conversion operator to create Matcher<T>.  Or it can be a value\n    // that should be passed to the Matcher<T>'s constructor.\n    //\n    // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a\n    // polymorphic matcher because it'll be ambiguous if T has an implicit\n    // constructor from M (this usually happens when T has an implicit\n    // constructor from any type).\n    //\n    // It won't work to unconditionally implicit_cast\n    // polymorphic_matcher_or_value to Matcher<T> because it won't trigger\n    // a user-defined conversion from M to T if one exists (assuming M is\n    // a value).\n    return CastImpl(polymorphic_matcher_or_value,\n                    std::is_convertible<M, Matcher<T>>{},\n                    std::is_convertible<M, T>{});\n  }\n\n private:\n  template <bool Ignore>\n  static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,\n                             std::true_type /* convertible_to_matcher */,\n                             std::integral_constant<bool, Ignore>) {\n    // M is implicitly convertible to Matcher<T>, which means that either\n    // M is a polymorphic matcher or Matcher<T> has an implicit constructor\n    // from M.  In both cases using the implicit conversion will produce a\n    // matcher.\n    //\n    // Even if T has an implicit constructor from M, it won't be called because\n    // creating Matcher<T> would require a chain of two user-defined conversions\n    // (first to create T from M and then to create Matcher<T> from T).\n    return polymorphic_matcher_or_value;\n  }\n\n  // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic\n  // matcher. It's a value of a type implicitly convertible to T. Use direct\n  // initialization to create a matcher.\n  static Matcher<T> CastImpl(const M& value,\n                             std::false_type /* convertible_to_matcher */,\n                             std::true_type /* convertible_to_T */) {\n    return Matcher<T>(ImplicitCast_<T>(value));\n  }\n\n  // M can't be implicitly converted to either Matcher<T> or T. Attempt to use\n  // polymorphic matcher Eq(value) in this case.\n  //\n  // Note that we first attempt to perform an implicit cast on the value and\n  // only fall back to the polymorphic Eq() matcher afterwards because the\n  // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end\n  // which might be undefined even when Rhs is implicitly convertible to Lhs\n  // (e.g. std::pair<const int, int> vs. std::pair<int, int>).\n  //\n  // We don't define this method inline as we need the declaration of Eq().\n  static Matcher<T> CastImpl(const M& value,\n                             std::false_type /* convertible_to_matcher */,\n                             std::false_type /* convertible_to_T */);\n};\n\n// This more specialized version is used when MatcherCast()'s argument\n// is already a Matcher.  This only compiles when type T can be\n// statically converted to type U.\ntemplate <typename T, typename U>\nclass MatcherCastImpl<T, Matcher<U>> {\n public:\n  static Matcher<T> Cast(const Matcher<U>& source_matcher) {\n    return Matcher<T>(new Impl(source_matcher));\n  }\n\n private:\n  class Impl : public MatcherInterface<T> {\n   public:\n    explicit Impl(const Matcher<U>& source_matcher)\n        : source_matcher_(source_matcher) {}\n\n    // We delegate the matching logic to the source matcher.\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      using FromType = typename std::remove_cv<typename std::remove_pointer<\n          typename std::remove_reference<T>::type>::type>::type;\n      using ToType = typename std::remove_cv<typename std::remove_pointer<\n          typename std::remove_reference<U>::type>::type>::type;\n      // Do not allow implicitly converting base*/& to derived*/&.\n      static_assert(\n          // Do not trigger if only one of them is a pointer. That implies a\n          // regular conversion and not a down_cast.\n          (std::is_pointer<typename std::remove_reference<T>::type>::value !=\n           std::is_pointer<typename std::remove_reference<U>::type>::value) ||\n              std::is_same<FromType, ToType>::value ||\n              !std::is_base_of<FromType, ToType>::value,\n          \"Can't implicitly convert from <base> to <derived>\");\n\n      // Do the cast to `U` explicitly if necessary.\n      // Otherwise, let implicit conversions do the trick.\n      using CastType =\n          typename std::conditional<std::is_convertible<T&, const U&>::value,\n                                    T&, U>::type;\n\n      return source_matcher_.MatchAndExplain(static_cast<CastType>(x),\n                                             listener);\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      source_matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      source_matcher_.DescribeNegationTo(os);\n    }\n\n   private:\n    const Matcher<U> source_matcher_;\n  };\n};\n\n// This even more specialized version is used for efficiently casting\n// a matcher to its own type.\ntemplate <typename T>\nclass MatcherCastImpl<T, Matcher<T>> {\n public:\n  static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }\n};\n\n// Template specialization for parameterless Matcher.\ntemplate <typename Derived>\nclass MatcherBaseImpl {\n public:\n  MatcherBaseImpl() = default;\n\n  template <typename T>\n  operator ::testing::Matcher<T>() const {  // NOLINT(runtime/explicit)\n    return ::testing::Matcher<T>(new\n                                 typename Derived::template gmock_Impl<T>());\n  }\n};\n\n// Template specialization for Matcher with parameters.\ntemplate <template <typename...> class Derived, typename... Ts>\nclass MatcherBaseImpl<Derived<Ts...>> {\n public:\n  // Mark the constructor explicit for single argument T to avoid implicit\n  // conversions.\n  template <typename E = std::enable_if<sizeof...(Ts) == 1>,\n            typename E::type* = nullptr>\n  explicit MatcherBaseImpl(Ts... params)\n      : params_(std::forward<Ts>(params)...) {}\n  template <typename E = std::enable_if<sizeof...(Ts) != 1>,\n            typename = typename E::type>\n  MatcherBaseImpl(Ts... params)  // NOLINT\n      : params_(std::forward<Ts>(params)...) {}\n\n  template <typename F>\n  operator ::testing::Matcher<F>() const {  // NOLINT(runtime/explicit)\n    return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{});\n  }\n\n private:\n  template <typename F, std::size_t... tuple_ids>\n  ::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const {\n    return ::testing::Matcher<F>(\n        new typename Derived<Ts...>::template gmock_Impl<F>(\n            std::get<tuple_ids>(params_)...));\n  }\n\n  const std::tuple<Ts...> params_;\n};\n\n}  // namespace internal\n\n// In order to be safe and clear, casting between different matcher\n// types is done explicitly via MatcherCast<T>(m), which takes a\n// matcher m and returns a Matcher<T>.  It compiles only when T can be\n// statically converted to the argument type of m.\ntemplate <typename T, typename M>\ninline Matcher<T> MatcherCast(const M& matcher) {\n  return internal::MatcherCastImpl<T, M>::Cast(matcher);\n}\n\n// This overload handles polymorphic matchers and values only since\n// monomorphic matchers are handled by the next one.\ntemplate <typename T, typename M>\ninline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {\n  return MatcherCast<T>(polymorphic_matcher_or_value);\n}\n\n// This overload handles monomorphic matchers.\n//\n// In general, if type T can be implicitly converted to type U, we can\n// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is\n// contravariant): just keep a copy of the original Matcher<U>, convert the\n// argument from type T to U, and then pass it to the underlying Matcher<U>.\n// The only exception is when U is a reference and T is not, as the\n// underlying Matcher<U> may be interested in the argument's address, which\n// is not preserved in the conversion from T to U.\ntemplate <typename T, typename U>\ninline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {\n  // Enforce that T can be implicitly converted to U.\n  static_assert(std::is_convertible<const T&, const U&>::value,\n                \"T must be implicitly convertible to U\");\n  // Enforce that we are not converting a non-reference type T to a reference\n  // type U.\n  static_assert(std::is_reference<T>::value || !std::is_reference<U>::value,\n                \"cannot convert non reference arg to reference\");\n  // In case both T and U are arithmetic types, enforce that the\n  // conversion is not lossy.\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;\n  constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;\n  constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;\n  static_assert(\n      kTIsOther || kUIsOther ||\n          (internal::LosslessArithmeticConvertible<RawT, RawU>::value),\n      \"conversion of arithmetic types must be lossless\");\n  return MatcherCast<T>(matcher);\n}\n\n// A<T>() returns a matcher that matches any value of type T.\ntemplate <typename T>\nMatcher<T> A();\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// If the explanation is not empty, prints it to the ostream.\ninline void PrintIfNotEmpty(const std::string& explanation,\n                            ::std::ostream* os) {\n  if (!explanation.empty() && os != nullptr) {\n    *os << \", \" << explanation;\n  }\n}\n\n// Returns true if the given type name is easy to read by a human.\n// This is used to decide whether printing the type of a value might\n// be helpful.\ninline bool IsReadableTypeName(const std::string& type_name) {\n  // We consider a type name readable if it's short or doesn't contain\n  // a template or function type.\n  return (type_name.length() <= 20 ||\n          type_name.find_first_of(\"<(\") == std::string::npos);\n}\n\n// Matches the value against the given matcher, prints the value and explains\n// the match result to the listener. Returns the match result.\n// 'listener' must not be NULL.\n// Value cannot be passed by const reference, because some matchers take a\n// non-const argument.\ntemplate <typename Value, typename T>\nbool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,\n                          MatchResultListener* listener) {\n  if (!listener->IsInterested()) {\n    // If the listener is not interested, we do not need to construct the\n    // inner explanation.\n    return matcher.Matches(value);\n  }\n\n  StringMatchResultListener inner_listener;\n  const bool match = matcher.MatchAndExplain(value, &inner_listener);\n\n  UniversalPrint(value, listener->stream());\n#if GTEST_HAS_RTTI\n  const std::string& type_name = GetTypeName<Value>();\n  if (IsReadableTypeName(type_name))\n    *listener->stream() << \" (of type \" << type_name << \")\";\n#endif\n  PrintIfNotEmpty(inner_listener.str(), listener->stream());\n\n  return match;\n}\n\n// An internal helper class for doing compile-time loop on a tuple's\n// fields.\ntemplate <size_t N>\nclass TuplePrefix {\n public:\n  // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true\n  // if and only if the first N fields of matcher_tuple matches\n  // the first N fields of value_tuple, respectively.\n  template <typename MatcherTuple, typename ValueTuple>\n  static bool Matches(const MatcherTuple& matcher_tuple,\n                      const ValueTuple& value_tuple) {\n    return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) &&\n           std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple));\n  }\n\n  // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os)\n  // describes failures in matching the first N fields of matchers\n  // against the first N fields of values.  If there is no failure,\n  // nothing will be streamed to os.\n  template <typename MatcherTuple, typename ValueTuple>\n  static void ExplainMatchFailuresTo(const MatcherTuple& matchers,\n                                     const ValueTuple& values,\n                                     ::std::ostream* os) {\n    // First, describes failures in the first N - 1 fields.\n    TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);\n\n    // Then describes the failure (if any) in the (N - 1)-th (0-based)\n    // field.\n    typename std::tuple_element<N - 1, MatcherTuple>::type matcher =\n        std::get<N - 1>(matchers);\n    typedef typename std::tuple_element<N - 1, ValueTuple>::type Value;\n    const Value& value = std::get<N - 1>(values);\n    StringMatchResultListener listener;\n    if (!matcher.MatchAndExplain(value, &listener)) {\n      *os << \"  Expected arg #\" << N - 1 << \": \";\n      std::get<N - 1>(matchers).DescribeTo(os);\n      *os << \"\\n           Actual: \";\n      // We remove the reference in type Value to prevent the\n      // universal printer from printing the address of value, which\n      // isn't interesting to the user most of the time.  The\n      // matcher's MatchAndExplain() method handles the case when\n      // the address is interesting.\n      internal::UniversalPrint(value, os);\n      PrintIfNotEmpty(listener.str(), os);\n      *os << \"\\n\";\n    }\n  }\n};\n\n// The base case.\ntemplate <>\nclass TuplePrefix<0> {\n public:\n  template <typename MatcherTuple, typename ValueTuple>\n  static bool Matches(const MatcherTuple& /* matcher_tuple */,\n                      const ValueTuple& /* value_tuple */) {\n    return true;\n  }\n\n  template <typename MatcherTuple, typename ValueTuple>\n  static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */,\n                                     const ValueTuple& /* values */,\n                                     ::std::ostream* /* os */) {}\n};\n\n// TupleMatches(matcher_tuple, value_tuple) returns true if and only if\n// all matchers in matcher_tuple match the corresponding fields in\n// value_tuple.  It is a compiler error if matcher_tuple and\n// value_tuple have different number of fields or incompatible field\n// types.\ntemplate <typename MatcherTuple, typename ValueTuple>\nbool TupleMatches(const MatcherTuple& matcher_tuple,\n                  const ValueTuple& value_tuple) {\n  // Makes sure that matcher_tuple and value_tuple have the same\n  // number of fields.\n  static_assert(std::tuple_size<MatcherTuple>::value ==\n                    std::tuple_size<ValueTuple>::value,\n                \"matcher and value have different numbers of fields\");\n  return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple,\n                                                                  value_tuple);\n}\n\n// Describes failures in matching matchers against values.  If there\n// is no failure, nothing will be streamed to os.\ntemplate <typename MatcherTuple, typename ValueTuple>\nvoid ExplainMatchFailureTupleTo(const MatcherTuple& matchers,\n                                const ValueTuple& values, ::std::ostream* os) {\n  TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(\n      matchers, values, os);\n}\n\n// TransformTupleValues and its helper.\n//\n// TransformTupleValuesHelper hides the internal machinery that\n// TransformTupleValues uses to implement a tuple traversal.\ntemplate <typename Tuple, typename Func, typename OutIter>\nclass TransformTupleValuesHelper {\n private:\n  typedef ::std::tuple_size<Tuple> TupleSize;\n\n public:\n  // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'.\n  // Returns the final value of 'out' in case the caller needs it.\n  static OutIter Run(Func f, const Tuple& t, OutIter out) {\n    return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out);\n  }\n\n private:\n  template <typename Tup, size_t kRemainingSize>\n  struct IterateOverTuple {\n    OutIter operator()(Func f, const Tup& t, OutIter out) const {\n      *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t));\n      return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);\n    }\n  };\n  template <typename Tup>\n  struct IterateOverTuple<Tup, 0> {\n    OutIter operator()(Func /* f */, const Tup& /* t */, OutIter out) const {\n      return out;\n    }\n  };\n};\n\n// Successively invokes 'f(element)' on each element of the tuple 't',\n// appending each result to the 'out' iterator. Returns the final value\n// of 'out'.\ntemplate <typename Tuple, typename Func, typename OutIter>\nOutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {\n  return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);\n}\n\n// Implements _, a matcher that matches any value of any\n// type.  This is a polymorphic matcher, so we need a template type\n// conversion operator to make it appearing as a Matcher<T> for any\n// type T.\nclass AnythingMatcher {\n public:\n  using is_gtest_matcher = void;\n\n  template <typename T>\n  bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {\n    return true;\n  }\n  void DescribeTo(std::ostream* os) const { *os << \"is anything\"; }\n  void DescribeNegationTo(::std::ostream* os) const {\n    // This is mostly for completeness' sake, as it's not very useful\n    // to write Not(A<bool>()).  However we cannot completely rule out\n    // such a possibility, and it doesn't hurt to be prepared.\n    *os << \"never matches\";\n  }\n};\n\n// Implements the polymorphic IsNull() matcher, which matches any raw or smart\n// pointer that is NULL.\nclass IsNullMatcher {\n public:\n  template <typename Pointer>\n  bool MatchAndExplain(const Pointer& p,\n                       MatchResultListener* /* listener */) const {\n    return p == nullptr;\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"is NULL\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"isn't NULL\"; }\n};\n\n// Implements the polymorphic NotNull() matcher, which matches any raw or smart\n// pointer that is not NULL.\nclass NotNullMatcher {\n public:\n  template <typename Pointer>\n  bool MatchAndExplain(const Pointer& p,\n                       MatchResultListener* /* listener */) const {\n    return p != nullptr;\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"isn't NULL\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"is NULL\"; }\n};\n\n// Ref(variable) matches any argument that is a reference to\n// 'variable'.  This matcher is polymorphic as it can match any\n// super type of the type of 'variable'.\n//\n// The RefMatcher template class implements Ref(variable).  It can\n// only be instantiated with a reference type.  This prevents a user\n// from mistakenly using Ref(x) to match a non-reference function\n// argument.  For example, the following will righteously cause a\n// compiler error:\n//\n//   int n;\n//   Matcher<int> m1 = Ref(n);   // This won't compile.\n//   Matcher<int&> m2 = Ref(n);  // This will compile.\ntemplate <typename T>\nclass RefMatcher;\n\ntemplate <typename T>\nclass RefMatcher<T&> {\n  // Google Mock is a generic framework and thus needs to support\n  // mocking any function types, including those that take non-const\n  // reference arguments.  Therefore the template parameter T (and\n  // Super below) can be instantiated to either a const type or a\n  // non-const type.\n public:\n  // RefMatcher() takes a T& instead of const T&, as we want the\n  // compiler to catch using Ref(const_value) as a matcher for a\n  // non-const reference.\n  explicit RefMatcher(T& x) : object_(x) {}  // NOLINT\n\n  template <typename Super>\n  operator Matcher<Super&>() const {\n    // By passing object_ (type T&) to Impl(), which expects a Super&,\n    // we make sure that Super is a super type of T.  In particular,\n    // this catches using Ref(const_value) as a matcher for a\n    // non-const reference, as you cannot implicitly convert a const\n    // reference to a non-const reference.\n    return MakeMatcher(new Impl<Super>(object_));\n  }\n\n private:\n  template <typename Super>\n  class Impl : public MatcherInterface<Super&> {\n   public:\n    explicit Impl(Super& x) : object_(x) {}  // NOLINT\n\n    // MatchAndExplain() takes a Super& (as opposed to const Super&)\n    // in order to match the interface MatcherInterface<Super&>.\n    bool MatchAndExplain(Super& x,\n                         MatchResultListener* listener) const override {\n      *listener << \"which is located @\" << static_cast<const void*>(&x);\n      return &x == &object_;\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"references the variable \";\n      UniversalPrinter<Super&>::Print(object_, os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not reference the variable \";\n      UniversalPrinter<Super&>::Print(object_, os);\n    }\n\n   private:\n    const Super& object_;\n  };\n\n  T& object_;\n};\n\n// Polymorphic helper functions for narrow and wide string matchers.\ninline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {\n  return String::CaseInsensitiveCStringEquals(lhs, rhs);\n}\n\ninline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,\n                                         const wchar_t* rhs) {\n  return String::CaseInsensitiveWideCStringEquals(lhs, rhs);\n}\n\n// String comparison for narrow or wide strings that can have embedded NUL\n// characters.\ntemplate <typename StringType>\nbool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) {\n  // Are the heads equal?\n  if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {\n    return false;\n  }\n\n  // Skip the equal heads.\n  const typename StringType::value_type nul = 0;\n  const size_t i1 = s1.find(nul), i2 = s2.find(nul);\n\n  // Are we at the end of either s1 or s2?\n  if (i1 == StringType::npos || i2 == StringType::npos) {\n    return i1 == i2;\n  }\n\n  // Are the tails equal?\n  return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));\n}\n\n// String matchers.\n\n// Implements equality-based string matchers like StrEq, StrCaseNe, and etc.\ntemplate <typename StringType>\nclass StrEqualityMatcher {\n public:\n  StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)\n      : string_(std::move(str)),\n        expect_eq_(expect_eq),\n        case_sensitive_(case_sensitive) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    if (s == nullptr) {\n      return !expect_eq_;\n    }\n    return MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    const bool eq = case_sensitive_ ? s2 == string_\n                                    : CaseInsensitiveStringEquals(s2, string_);\n    return expect_eq_ == eq;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    DescribeToHelper(expect_eq_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    DescribeToHelper(!expect_eq_, os);\n  }\n\n private:\n  void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {\n    *os << (expect_eq ? \"is \" : \"isn't \");\n    *os << \"equal to \";\n    if (!case_sensitive_) {\n      *os << \"(ignoring case) \";\n    }\n    UniversalPrint(string_, os);\n  }\n\n  const StringType string_;\n  const bool expect_eq_;\n  const bool case_sensitive_;\n};\n\n// Implements the polymorphic HasSubstr(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass HasSubstrMatcher {\n public:\n  explicit HasSubstrMatcher(const StringType& substring)\n      : substring_(substring) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    return StringType(s).find(substring_) != StringType::npos;\n  }\n\n  // Describes what this matcher matches.\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"has substring \";\n    UniversalPrint(substring_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"has no substring \";\n    UniversalPrint(substring_, os);\n  }\n\n private:\n  const StringType substring_;\n};\n\n// Implements the polymorphic StartsWith(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass StartsWithMatcher {\n public:\n  explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    return s2.length() >= prefix_.length() &&\n           s2.substr(0, prefix_.length()) == prefix_;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"starts with \";\n    UniversalPrint(prefix_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't start with \";\n    UniversalPrint(prefix_, os);\n  }\n\n private:\n  const StringType prefix_;\n};\n\n// Implements the polymorphic EndsWith(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass EndsWithMatcher {\n public:\n  explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    return s2.length() >= suffix_.length() &&\n           s2.substr(s2.length() - suffix_.length()) == suffix_;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"ends with \";\n    UniversalPrint(suffix_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't end with \";\n    UniversalPrint(suffix_, os);\n  }\n\n private:\n  const StringType suffix_;\n};\n\n// Implements the polymorphic WhenBase64Unescaped(matcher) matcher, which can be\n// used as a Matcher<T> as long as T can be converted to a string.\nclass WhenBase64UnescapedMatcher {\n public:\n  using is_gtest_matcher = void;\n\n  explicit WhenBase64UnescapedMatcher(\n      const Matcher<const std::string&>& internal_matcher)\n      : internal_matcher_(internal_matcher) {}\n\n  // Matches anything that can convert to std::string.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* listener) const {\n    const std::string s2(s);  // NOLINT (needed for working with string_view).\n    std::string unescaped;\n    if (!internal::Base64Unescape(s2, &unescaped)) {\n      if (listener != nullptr) {\n        *listener << \"is not a valid base64 escaped string\";\n      }\n      return false;\n    }\n    return MatchPrintAndExplain(unescaped, internal_matcher_, listener);\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"matches after Base64Unescape \";\n    internal_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"does not match after Base64Unescape \";\n    internal_matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<const std::string&> internal_matcher_;\n};\n\n// Implements a matcher that compares the two fields of a 2-tuple\n// using one of the ==, <=, <, etc, operators.  The two fields being\n// compared don't have to have the same type.\n//\n// The matcher defined here is polymorphic (for example, Eq() can be\n// used to match a std::tuple<int, short>, a std::tuple<const long&, double>,\n// etc).  Therefore we use a template type conversion operator in the\n// implementation.\ntemplate <typename D, typename Op>\nclass PairMatchBase {\n public:\n  template <typename T1, typename T2>\n  operator Matcher<::std::tuple<T1, T2>>() const {\n    return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);\n  }\n  template <typename T1, typename T2>\n  operator Matcher<const ::std::tuple<T1, T2>&>() const {\n    return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>);\n  }\n\n private:\n  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT\n    return os << D::Desc();\n  }\n\n  template <typename Tuple>\n  class Impl : public MatcherInterface<Tuple> {\n   public:\n    bool MatchAndExplain(Tuple args,\n                         MatchResultListener* /* listener */) const override {\n      return Op()(::std::get<0>(args), ::std::get<1>(args));\n    }\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"are \" << GetDesc;\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"aren't \" << GetDesc;\n    }\n  };\n};\n\nclass Eq2Matcher : public PairMatchBase<Eq2Matcher, std::equal_to<>> {\n public:\n  static const char* Desc() { return \"an equal pair\"; }\n};\nclass Ne2Matcher : public PairMatchBase<Ne2Matcher, std::not_equal_to<>> {\n public:\n  static const char* Desc() { return \"an unequal pair\"; }\n};\nclass Lt2Matcher : public PairMatchBase<Lt2Matcher, std::less<>> {\n public:\n  static const char* Desc() { return \"a pair where the first < the second\"; }\n};\nclass Gt2Matcher : public PairMatchBase<Gt2Matcher, std::greater<>> {\n public:\n  static const char* Desc() { return \"a pair where the first > the second\"; }\n};\nclass Le2Matcher : public PairMatchBase<Le2Matcher, std::less_equal<>> {\n public:\n  static const char* Desc() { return \"a pair where the first <= the second\"; }\n};\nclass Ge2Matcher : public PairMatchBase<Ge2Matcher, std::greater_equal<>> {\n public:\n  static const char* Desc() { return \"a pair where the first >= the second\"; }\n};\n\n// Implements the Not(...) matcher for a particular argument type T.\n// We do not nest it inside the NotMatcher class template, as that\n// will prevent different instantiations of NotMatcher from sharing\n// the same NotMatcherImpl<T> class.\ntemplate <typename T>\nclass NotMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {}\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    return !matcher_.MatchAndExplain(x, listener);\n  }\n\n  void DescribeTo(::std::ostream* os) const override {\n    matcher_.DescribeNegationTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<T> matcher_;\n};\n\n// Implements the Not(m) matcher, which matches a value that doesn't\n// match matcher m.\ntemplate <typename InnerMatcher>\nclass NotMatcher {\n public:\n  explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}\n\n  // This template type conversion operator allows Not(m) to be used\n  // to match any type m can match.\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));\n  }\n\n private:\n  InnerMatcher matcher_;\n};\n\n// Implements the AllOf(m1, m2) matcher for a particular argument type\n// T. We do not nest it inside the BothOfMatcher class template, as\n// that will prevent different instantiations of BothOfMatcher from\n// sharing the same BothOfMatcherImpl<T> class.\ntemplate <typename T>\nclass AllOfMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit AllOfMatcherImpl(std::vector<Matcher<T>> matchers)\n      : matchers_(std::move(matchers)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") and (\";\n      matchers_[i].DescribeTo(os);\n    }\n    *os << \")\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") or (\";\n      matchers_[i].DescribeNegationTo(os);\n    }\n    *os << \")\";\n  }\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    // If either matcher1_ or matcher2_ doesn't match x, we only need\n    // to explain why one of them fails.\n    std::string all_match_result;\n\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      StringMatchResultListener slistener;\n      if (matchers_[i].MatchAndExplain(x, &slistener)) {\n        if (all_match_result.empty()) {\n          all_match_result = slistener.str();\n        } else {\n          std::string result = slistener.str();\n          if (!result.empty()) {\n            all_match_result += \", and \";\n            all_match_result += result;\n          }\n        }\n      } else {\n        *listener << slistener.str();\n        return false;\n      }\n    }\n\n    // Otherwise we need to explain why *both* of them match.\n    *listener << all_match_result;\n    return true;\n  }\n\n private:\n  const std::vector<Matcher<T>> matchers_;\n};\n\n// VariadicMatcher is used for the variadic implementation of\n// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).\n// CombiningMatcher<T> is used to recursively combine the provided matchers\n// (of type Args...).\ntemplate <template <typename T> class CombiningMatcher, typename... Args>\nclass VariadicMatcher {\n public:\n  VariadicMatcher(const Args&... matchers)  // NOLINT\n      : matchers_(matchers...) {\n    static_assert(sizeof...(Args) > 0, \"Must have at least one matcher.\");\n  }\n\n  VariadicMatcher(const VariadicMatcher&) = default;\n  VariadicMatcher& operator=(const VariadicMatcher&) = delete;\n\n  // This template type conversion operator allows an\n  // VariadicMatcher<Matcher1, Matcher2...> object to match any type that\n  // all of the provided matchers (Matcher1, Matcher2, ...) can match.\n  template <typename T>\n  operator Matcher<T>() const {\n    std::vector<Matcher<T>> values;\n    CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());\n    return Matcher<T>(new CombiningMatcher<T>(std::move(values)));\n  }\n\n private:\n  template <typename T, size_t I>\n  void CreateVariadicMatcher(std::vector<Matcher<T>>* values,\n                             std::integral_constant<size_t, I>) const {\n    values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));\n    CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());\n  }\n\n  template <typename T>\n  void CreateVariadicMatcher(\n      std::vector<Matcher<T>>*,\n      std::integral_constant<size_t, sizeof...(Args)>) const {}\n\n  std::tuple<Args...> matchers_;\n};\n\ntemplate <typename... Args>\nusing AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;\n\n// Implements the AnyOf(m1, m2) matcher for a particular argument type\n// T.  We do not nest it inside the AnyOfMatcher class template, as\n// that will prevent different instantiations of AnyOfMatcher from\n// sharing the same EitherOfMatcherImpl<T> class.\ntemplate <typename T>\nclass AnyOfMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit AnyOfMatcherImpl(std::vector<Matcher<T>> matchers)\n      : matchers_(std::move(matchers)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") or (\";\n      matchers_[i].DescribeTo(os);\n    }\n    *os << \")\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") and (\";\n      matchers_[i].DescribeNegationTo(os);\n    }\n    *os << \")\";\n  }\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    std::string no_match_result;\n\n    // If either matcher1_ or matcher2_ matches x, we just need to\n    // explain why *one* of them matches.\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      StringMatchResultListener slistener;\n      if (matchers_[i].MatchAndExplain(x, &slistener)) {\n        *listener << slistener.str();\n        return true;\n      } else {\n        if (no_match_result.empty()) {\n          no_match_result = slistener.str();\n        } else {\n          std::string result = slistener.str();\n          if (!result.empty()) {\n            no_match_result += \", and \";\n            no_match_result += result;\n          }\n        }\n      }\n    }\n\n    // Otherwise we need to explain why *both* of them fail.\n    *listener << no_match_result;\n    return false;\n  }\n\n private:\n  const std::vector<Matcher<T>> matchers_;\n};\n\n// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).\ntemplate <typename... Args>\nusing AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;\n\n// ConditionalMatcher is the implementation of Conditional(cond, m1, m2)\ntemplate <typename MatcherTrue, typename MatcherFalse>\nclass ConditionalMatcher {\n public:\n  ConditionalMatcher(bool condition, MatcherTrue matcher_true,\n                     MatcherFalse matcher_false)\n      : condition_(condition),\n        matcher_true_(std::move(matcher_true)),\n        matcher_false_(std::move(matcher_false)) {}\n\n  template <typename T>\n  operator Matcher<T>() const {  // NOLINT(runtime/explicit)\n    return condition_ ? SafeMatcherCast<T>(matcher_true_)\n                      : SafeMatcherCast<T>(matcher_false_);\n  }\n\n private:\n  bool condition_;\n  MatcherTrue matcher_true_;\n  MatcherFalse matcher_false_;\n};\n\n// Wrapper for implementation of Any/AllOfArray().\ntemplate <template <class> class MatcherImpl, typename T>\nclass SomeOfArrayMatcher {\n public:\n  // Constructs the matcher from a sequence of element values or\n  // element matchers.\n  template <typename Iter>\n  SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}\n\n  template <typename U>\n  operator Matcher<U>() const {  // NOLINT\n    using RawU = typename std::decay<U>::type;\n    std::vector<Matcher<RawU>> matchers;\n    matchers.reserve(matchers_.size());\n    for (const auto& matcher : matchers_) {\n      matchers.push_back(MatcherCast<RawU>(matcher));\n    }\n    return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));\n  }\n\n private:\n  const ::std::vector<T> matchers_;\n};\n\ntemplate <typename T>\nusing AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;\n\ntemplate <typename T>\nusing AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;\n\n// Used for implementing Truly(pred), which turns a predicate into a\n// matcher.\ntemplate <typename Predicate>\nclass TrulyMatcher {\n public:\n  explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}\n\n  // This method template allows Truly(pred) to be used as a matcher\n  // for type T where T is the argument type of predicate 'pred'.  The\n  // argument is passed by reference as the predicate may be\n  // interested in the address of the argument.\n  template <typename T>\n  bool MatchAndExplain(T& x,  // NOLINT\n                       MatchResultListener* listener) const {\n    // Without the if-statement, MSVC sometimes warns about converting\n    // a value to bool (warning 4800).\n    //\n    // We cannot write 'return !!predicate_(x);' as that doesn't work\n    // when predicate_(x) returns a class convertible to bool but\n    // having no operator!().\n    if (predicate_(x)) return true;\n    *listener << \"didn't satisfy the given predicate\";\n    return false;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"satisfies the given predicate\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't satisfy the given predicate\";\n  }\n\n private:\n  Predicate predicate_;\n};\n\n// Used for implementing Matches(matcher), which turns a matcher into\n// a predicate.\ntemplate <typename M>\nclass MatcherAsPredicate {\n public:\n  explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}\n\n  // This template operator() allows Matches(m) to be used as a\n  // predicate on type T where m is a matcher on type T.\n  //\n  // The argument x is passed by reference instead of by value, as\n  // some matcher may be interested in its address (e.g. as in\n  // Matches(Ref(n))(x)).\n  template <typename T>\n  bool operator()(const T& x) const {\n    // We let matcher_ commit to a particular type here instead of\n    // when the MatcherAsPredicate object was constructed.  This\n    // allows us to write Matches(m) where m is a polymorphic matcher\n    // (e.g. Eq(5)).\n    //\n    // If we write Matcher<T>(matcher_).Matches(x) here, it won't\n    // compile when matcher_ has type Matcher<const T&>; if we write\n    // Matcher<const T&>(matcher_).Matches(x) here, it won't compile\n    // when matcher_ has type Matcher<T>; if we just write\n    // matcher_.Matches(x), it won't compile when matcher_ is\n    // polymorphic, e.g. Eq(5).\n    //\n    // MatcherCast<const T&>() is necessary for making the code work\n    // in all of the above situations.\n    return MatcherCast<const T&>(matcher_).Matches(x);\n  }\n\n private:\n  M matcher_;\n};\n\n// For implementing ASSERT_THAT() and EXPECT_THAT().  The template\n// argument M must be a type that can be converted to a matcher.\ntemplate <typename M>\nclass PredicateFormatterFromMatcher {\n public:\n  explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}\n\n  // This template () operator allows a PredicateFormatterFromMatcher\n  // object to act as a predicate-formatter suitable for using with\n  // Google Test's EXPECT_PRED_FORMAT1() macro.\n  template <typename T>\n  AssertionResult operator()(const char* value_text, const T& x) const {\n    // We convert matcher_ to a Matcher<const T&> *now* instead of\n    // when the PredicateFormatterFromMatcher object was constructed,\n    // as matcher_ may be polymorphic (e.g. NotNull()) and we won't\n    // know which type to instantiate it to until we actually see the\n    // type of x here.\n    //\n    // We write SafeMatcherCast<const T&>(matcher_) instead of\n    // Matcher<const T&>(matcher_), as the latter won't compile when\n    // matcher_ has type Matcher<T> (e.g. An<int>()).\n    // We don't write MatcherCast<const T&> either, as that allows\n    // potentially unsafe downcasting of the matcher argument.\n    const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);\n\n    // The expected path here is that the matcher should match (i.e. that most\n    // tests pass) so optimize for this case.\n    if (matcher.Matches(x)) {\n      return AssertionSuccess();\n    }\n\n    ::std::stringstream ss;\n    ss << \"Value of: \" << value_text << \"\\n\"\n       << \"Expected: \";\n    matcher.DescribeTo(&ss);\n\n    // Rerun the matcher to \"PrintAndExplain\" the failure.\n    StringMatchResultListener listener;\n    if (MatchPrintAndExplain(x, matcher, &listener)) {\n      ss << \"\\n  The matcher failed on the initial attempt; but passed when \"\n            \"rerun to generate the explanation.\";\n    }\n    ss << \"\\n  Actual: \" << listener.str();\n    return AssertionFailure() << ss.str();\n  }\n\n private:\n  const M matcher_;\n};\n\n// A helper function for converting a matcher to a predicate-formatter\n// without the user needing to explicitly write the type.  This is\n// used for implementing ASSERT_THAT() and EXPECT_THAT().\n// Implementation detail: 'matcher' is received by-value to force decaying.\ntemplate <typename M>\ninline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher(\n    M matcher) {\n  return PredicateFormatterFromMatcher<M>(std::move(matcher));\n}\n\n// Implements the polymorphic IsNan() matcher, which matches any floating type\n// value that is Nan.\nclass IsNanMatcher {\n public:\n  template <typename FloatType>\n  bool MatchAndExplain(const FloatType& f,\n                       MatchResultListener* /* listener */) const {\n    return (::std::isnan)(f);\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"is NaN\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"isn't NaN\"; }\n};\n\n// Implements the polymorphic floating point equality matcher, which matches\n// two float values using ULP-based approximation or, optionally, a\n// user-specified epsilon.  The template is meant to be instantiated with\n// FloatType being either float or double.\ntemplate <typename FloatType>\nclass FloatingEqMatcher {\n public:\n  // Constructor for FloatingEqMatcher.\n  // The matcher's input will be compared with expected.  The matcher treats two\n  // NANs as equal if nan_eq_nan is true.  Otherwise, under IEEE standards,\n  // equality comparisons between NANs will always return false.  We specify a\n  // negative max_abs_error_ term to indicate that ULP-based approximation will\n  // be used for comparison.\n  FloatingEqMatcher(FloatType expected, bool nan_eq_nan)\n      : expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {}\n\n  // Constructor that supports a user-specified max_abs_error that will be used\n  // for comparison instead of ULP-based approximation.  The max absolute\n  // should be non-negative.\n  FloatingEqMatcher(FloatType expected, bool nan_eq_nan,\n                    FloatType max_abs_error)\n      : expected_(expected),\n        nan_eq_nan_(nan_eq_nan),\n        max_abs_error_(max_abs_error) {\n    GTEST_CHECK_(max_abs_error >= 0)\n        << \", where max_abs_error is\" << max_abs_error;\n  }\n\n  // Implements floating point equality matcher as a Matcher<T>.\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n   public:\n    Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error)\n        : expected_(expected),\n          nan_eq_nan_(nan_eq_nan),\n          max_abs_error_(max_abs_error) {}\n\n    bool MatchAndExplain(T value,\n                         MatchResultListener* listener) const override {\n      const FloatingPoint<FloatType> actual(value), expected(expected_);\n\n      // Compares NaNs first, if nan_eq_nan_ is true.\n      if (actual.is_nan() || expected.is_nan()) {\n        if (actual.is_nan() && expected.is_nan()) {\n          return nan_eq_nan_;\n        }\n        // One is nan; the other is not nan.\n        return false;\n      }\n      if (HasMaxAbsError()) {\n        // We perform an equality check so that inf will match inf, regardless\n        // of error bounds.  If the result of value - expected_ would result in\n        // overflow or if either value is inf, the default result is infinity,\n        // which should only match if max_abs_error_ is also infinity.\n        if (value == expected_) {\n          return true;\n        }\n\n        const FloatType diff = value - expected_;\n        if (::std::fabs(diff) <= max_abs_error_) {\n          return true;\n        }\n\n        if (listener->IsInterested()) {\n          *listener << \"which is \" << diff << \" from \" << expected_;\n        }\n        return false;\n      } else {\n        return actual.AlmostEquals(expected);\n      }\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      // os->precision() returns the previously set precision, which we\n      // store to restore the ostream to its original configuration\n      // after outputting.\n      const ::std::streamsize old_precision =\n          os->precision(::std::numeric_limits<FloatType>::digits10 + 2);\n      if (FloatingPoint<FloatType>(expected_).is_nan()) {\n        if (nan_eq_nan_) {\n          *os << \"is NaN\";\n        } else {\n          *os << \"never matches\";\n        }\n      } else {\n        *os << \"is approximately \" << expected_;\n        if (HasMaxAbsError()) {\n          *os << \" (absolute error <= \" << max_abs_error_ << \")\";\n        }\n      }\n      os->precision(old_precision);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      // As before, get original precision.\n      const ::std::streamsize old_precision =\n          os->precision(::std::numeric_limits<FloatType>::digits10 + 2);\n      if (FloatingPoint<FloatType>(expected_).is_nan()) {\n        if (nan_eq_nan_) {\n          *os << \"isn't NaN\";\n        } else {\n          *os << \"is anything\";\n        }\n      } else {\n        *os << \"isn't approximately \" << expected_;\n        if (HasMaxAbsError()) {\n          *os << \" (absolute error > \" << max_abs_error_ << \")\";\n        }\n      }\n      // Restore original precision.\n      os->precision(old_precision);\n    }\n\n   private:\n    bool HasMaxAbsError() const { return max_abs_error_ >= 0; }\n\n    const FloatType expected_;\n    const bool nan_eq_nan_;\n    // max_abs_error will be used for value comparison when >= 0.\n    const FloatType max_abs_error_;\n  };\n\n  // The following 3 type conversion operators allow FloatEq(expected) and\n  // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a\n  // Matcher<const float&>, or a Matcher<float&>, but nothing else.\n  operator Matcher<FloatType>() const {\n    return MakeMatcher(\n        new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n  operator Matcher<const FloatType&>() const {\n    return MakeMatcher(\n        new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n  operator Matcher<FloatType&>() const {\n    return MakeMatcher(\n        new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n private:\n  const FloatType expected_;\n  const bool nan_eq_nan_;\n  // max_abs_error will be used for value comparison when >= 0.\n  const FloatType max_abs_error_;\n};\n\n// A 2-tuple (\"binary\") wrapper around FloatingEqMatcher:\n// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)\n// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)\n// against y. The former implements \"Eq\", the latter \"Near\". At present, there\n// is no version that compares NaNs as equal.\ntemplate <typename FloatType>\nclass FloatingEq2Matcher {\n public:\n  FloatingEq2Matcher() { Init(-1, false); }\n\n  explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }\n\n  explicit FloatingEq2Matcher(FloatType max_abs_error) {\n    Init(max_abs_error, false);\n  }\n\n  FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {\n    Init(max_abs_error, nan_eq_nan);\n  }\n\n  template <typename T1, typename T2>\n  operator Matcher<::std::tuple<T1, T2>>() const {\n    return MakeMatcher(\n        new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_));\n  }\n  template <typename T1, typename T2>\n  operator Matcher<const ::std::tuple<T1, T2>&>() const {\n    return MakeMatcher(\n        new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));\n  }\n\n private:\n  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT\n    return os << \"an almost-equal pair\";\n  }\n\n  template <typename Tuple>\n  class Impl : public MatcherInterface<Tuple> {\n   public:\n    Impl(FloatType max_abs_error, bool nan_eq_nan)\n        : max_abs_error_(max_abs_error), nan_eq_nan_(nan_eq_nan) {}\n\n    bool MatchAndExplain(Tuple args,\n                         MatchResultListener* listener) const override {\n      if (max_abs_error_ == -1) {\n        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_);\n        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(\n            ::std::get<1>(args), listener);\n      } else {\n        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_,\n                                        max_abs_error_);\n        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(\n            ::std::get<1>(args), listener);\n      }\n    }\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"are \" << GetDesc;\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"aren't \" << GetDesc;\n    }\n\n   private:\n    FloatType max_abs_error_;\n    const bool nan_eq_nan_;\n  };\n\n  void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {\n    max_abs_error_ = max_abs_error_val;\n    nan_eq_nan_ = nan_eq_nan_val;\n  }\n  FloatType max_abs_error_;\n  bool nan_eq_nan_;\n};\n\n// Implements the Pointee(m) matcher for matching a pointer whose\n// pointee matches matcher m.  The pointer can be either raw or smart.\ntemplate <typename InnerMatcher>\nclass PointeeMatcher {\n public:\n  explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}\n\n  // This type conversion operator template allows Pointee(m) to be\n  // used as a matcher for any pointer type whose pointee type is\n  // compatible with the inner matcher, where type Pointer can be\n  // either a raw pointer or a smart pointer.\n  //\n  // The reason we do this instead of relying on\n  // MakePolymorphicMatcher() is that the latter is not flexible\n  // enough for implementing the DescribeTo() method of Pointee().\n  template <typename Pointer>\n  operator Matcher<Pointer>() const {\n    return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular pointer type.\n  template <typename Pointer>\n  class Impl : public MatcherInterface<Pointer> {\n   public:\n    using Pointee =\n        typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(\n            Pointer)>::element_type;\n\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<const Pointee&>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"points to a value that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not point to a value that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(Pointer pointer,\n                         MatchResultListener* listener) const override {\n      if (GetRawPointer(pointer) == nullptr) return false;\n\n      *listener << \"which points to \";\n      return MatchPrintAndExplain(*pointer, matcher_, listener);\n    }\n\n   private:\n    const Matcher<const Pointee&> matcher_;\n  };\n\n  const InnerMatcher matcher_;\n};\n\n// Implements the Pointer(m) matcher\n// Implements the Pointer(m) matcher for matching a pointer that matches matcher\n// m.  The pointer can be either raw or smart, and will match `m` against the\n// raw pointer.\ntemplate <typename InnerMatcher>\nclass PointerMatcher {\n public:\n  explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}\n\n  // This type conversion operator template allows Pointer(m) to be\n  // used as a matcher for any pointer type whose pointer type is\n  // compatible with the inner matcher, where type PointerType can be\n  // either a raw pointer or a smart pointer.\n  //\n  // The reason we do this instead of relying on\n  // MakePolymorphicMatcher() is that the latter is not flexible\n  // enough for implementing the DescribeTo() method of Pointer().\n  template <typename PointerType>\n  operator Matcher<PointerType>() const {  // NOLINT\n    return Matcher<PointerType>(new Impl<const PointerType&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular pointer type.\n  template <typename PointerType>\n  class Impl : public MatcherInterface<PointerType> {\n   public:\n    using Pointer =\n        const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(\n            PointerType)>::element_type*;\n\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<Pointer>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"is a pointer that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"is not a pointer that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(PointerType pointer,\n                         MatchResultListener* listener) const override {\n      *listener << \"which is a pointer that \";\n      Pointer p = GetRawPointer(pointer);\n      return MatchPrintAndExplain(p, matcher_, listener);\n    }\n\n   private:\n    Matcher<Pointer> matcher_;\n  };\n\n  const InnerMatcher matcher_;\n};\n\n#if GTEST_HAS_RTTI\n// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or\n// reference that matches inner_matcher when dynamic_cast<T> is applied.\n// The result of dynamic_cast<To> is forwarded to the inner matcher.\n// If To is a pointer and the cast fails, the inner matcher will receive NULL.\n// If To is a reference and the cast fails, this matcher returns false\n// immediately.\ntemplate <typename To>\nclass WhenDynamicCastToMatcherBase {\n public:\n  explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)\n      : matcher_(matcher) {}\n\n  void DescribeTo(::std::ostream* os) const {\n    GetCastTypeDescription(os);\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    GetCastTypeDescription(os);\n    matcher_.DescribeNegationTo(os);\n  }\n\n protected:\n  const Matcher<To> matcher_;\n\n  static std::string GetToName() { return GetTypeName<To>(); }\n\n private:\n  static void GetCastTypeDescription(::std::ostream* os) {\n    *os << \"when dynamic_cast to \" << GetToName() << \", \";\n  }\n};\n\n// Primary template.\n// To is a pointer. Cast and forward the result.\ntemplate <typename To>\nclass WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {\n public:\n  explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)\n      : WhenDynamicCastToMatcherBase<To>(matcher) {}\n\n  template <typename From>\n  bool MatchAndExplain(From from, MatchResultListener* listener) const {\n    To to = dynamic_cast<To>(from);\n    return MatchPrintAndExplain(to, this->matcher_, listener);\n  }\n};\n\n// Specialize for references.\n// In this case we return false if the dynamic_cast fails.\ntemplate <typename To>\nclass WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {\n public:\n  explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)\n      : WhenDynamicCastToMatcherBase<To&>(matcher) {}\n\n  template <typename From>\n  bool MatchAndExplain(From& from, MatchResultListener* listener) const {\n    // We don't want an std::bad_cast here, so do the cast with pointers.\n    To* to = dynamic_cast<To*>(&from);\n    if (to == nullptr) {\n      *listener << \"which cannot be dynamic_cast to \" << this->GetToName();\n      return false;\n    }\n    return MatchPrintAndExplain(*to, this->matcher_, listener);\n  }\n};\n#endif  // GTEST_HAS_RTTI\n\n// Implements the Field() matcher for matching a field (i.e. member\n// variable) of an object.\ntemplate <typename Class, typename FieldType>\nclass FieldMatcher {\n public:\n  FieldMatcher(FieldType Class::*field,\n               const Matcher<const FieldType&>& matcher)\n      : field_(field), matcher_(matcher), whose_field_(\"whose given field \") {}\n\n  FieldMatcher(const std::string& field_name, FieldType Class::*field,\n               const Matcher<const FieldType&>& matcher)\n      : field_(field),\n        matcher_(matcher),\n        whose_field_(\"whose field `\" + field_name + \"` \") {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_field_;\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_field_;\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {\n    // FIXME: The dispatch on std::is_pointer was introduced as a workaround for\n    // a compiler bug, and can now be removed.\n    return MatchAndExplainImpl(\n        typename std::is_pointer<typename std::remove_const<T>::type>::type(),\n        value, listener);\n  }\n\n private:\n  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,\n                           const Class& obj,\n                           MatchResultListener* listener) const {\n    *listener << whose_field_ << \"is \";\n    return MatchPrintAndExplain(obj.*field_, matcher_, listener);\n  }\n\n  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,\n                           MatchResultListener* listener) const {\n    if (p == nullptr) return false;\n\n    *listener << \"which points to an object \";\n    // Since *p has a field, it must be a class/struct/union type and\n    // thus cannot be a pointer.  Therefore we pass false_type() as\n    // the first argument.\n    return MatchAndExplainImpl(std::false_type(), *p, listener);\n  }\n\n  const FieldType Class::*field_;\n  const Matcher<const FieldType&> matcher_;\n\n  // Contains either \"whose given field \" if the name of the field is unknown\n  // or \"whose field `name_of_field` \" if the name is known.\n  const std::string whose_field_;\n};\n\n// Implements the Property() matcher for matching a property\n// (i.e. return value of a getter method) of an object.\n//\n// Property is a const-qualified member function of Class returning\n// PropertyType.\ntemplate <typename Class, typename PropertyType, typename Property>\nclass PropertyMatcher {\n public:\n  typedef const PropertyType& RefToConstProperty;\n\n  PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)\n      : property_(property),\n        matcher_(matcher),\n        whose_property_(\"whose given property \") {}\n\n  PropertyMatcher(const std::string& property_name, Property property,\n                  const Matcher<RefToConstProperty>& matcher)\n      : property_(property),\n        matcher_(matcher),\n        whose_property_(\"whose property `\" + property_name + \"` \") {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_property_;\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_property_;\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {\n    return MatchAndExplainImpl(\n        typename std::is_pointer<typename std::remove_const<T>::type>::type(),\n        value, listener);\n  }\n\n private:\n  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,\n                           const Class& obj,\n                           MatchResultListener* listener) const {\n    *listener << whose_property_ << \"is \";\n    // Cannot pass the return value (for example, int) to MatchPrintAndExplain,\n    // which takes a non-const reference as argument.\n    RefToConstProperty result = (obj.*property_)();\n    return MatchPrintAndExplain(result, matcher_, listener);\n  }\n\n  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,\n                           MatchResultListener* listener) const {\n    if (p == nullptr) return false;\n\n    *listener << \"which points to an object \";\n    // Since *p has a property method, it must be a class/struct/union\n    // type and thus cannot be a pointer.  Therefore we pass\n    // false_type() as the first argument.\n    return MatchAndExplainImpl(std::false_type(), *p, listener);\n  }\n\n  Property property_;\n  const Matcher<RefToConstProperty> matcher_;\n\n  // Contains either \"whose given property \" if the name of the property is\n  // unknown or \"whose property `name_of_property` \" if the name is known.\n  const std::string whose_property_;\n};\n\n// Type traits specifying various features of different functors for ResultOf.\n// The default template specifies features for functor objects.\ntemplate <typename Functor>\nstruct CallableTraits {\n  typedef Functor StorageType;\n\n  static void CheckIsValid(Functor /* functor */) {}\n\n  template <typename T>\n  static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) {\n    return f(arg);\n  }\n};\n\n// Specialization for function pointers.\ntemplate <typename ArgType, typename ResType>\nstruct CallableTraits<ResType (*)(ArgType)> {\n  typedef ResType ResultType;\n  typedef ResType (*StorageType)(ArgType);\n\n  static void CheckIsValid(ResType (*f)(ArgType)) {\n    GTEST_CHECK_(f != nullptr)\n        << \"NULL function pointer is passed into ResultOf().\";\n  }\n  template <typename T>\n  static ResType Invoke(ResType (*f)(ArgType), T arg) {\n    return (*f)(arg);\n  }\n};\n\n// Implements the ResultOf() matcher for matching a return value of a\n// unary function of an object.\ntemplate <typename Callable, typename InnerMatcher>\nclass ResultOfMatcher {\n public:\n  ResultOfMatcher(Callable callable, InnerMatcher matcher)\n      : ResultOfMatcher(/*result_description=*/\"\", std::move(callable),\n                        std::move(matcher)) {}\n\n  ResultOfMatcher(const std::string& result_description, Callable callable,\n                  InnerMatcher matcher)\n      : result_description_(result_description),\n        callable_(std::move(callable)),\n        matcher_(std::move(matcher)) {\n    CallableTraits<Callable>::CheckIsValid(callable_);\n  }\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(\n        new Impl<const T&>(result_description_, callable_, matcher_));\n  }\n\n private:\n  typedef typename CallableTraits<Callable>::StorageType CallableStorageType;\n\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n    using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>(\n        std::declval<CallableStorageType>(), std::declval<T>()));\n\n   public:\n    template <typename M>\n    Impl(const std::string& result_description,\n         const CallableStorageType& callable, const M& matcher)\n        : result_description_(result_description),\n          callable_(callable),\n          matcher_(MatcherCast<ResultType>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      if (result_description_.empty()) {\n        *os << \"is mapped by the given callable to a value that \";\n      } else {\n        *os << \"whose \" << result_description_ << \" \";\n      }\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      if (result_description_.empty()) {\n        *os << \"is mapped by the given callable to a value that \";\n      } else {\n        *os << \"whose \" << result_description_ << \" \";\n      }\n      matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(T obj, MatchResultListener* listener) const override {\n      if (result_description_.empty()) {\n        *listener << \"which is mapped by the given callable to \";\n      } else {\n        *listener << \"whose \" << result_description_ << \" is \";\n      }\n      // Cannot pass the return value directly to MatchPrintAndExplain, which\n      // takes a non-const reference as argument.\n      // Also, specifying template argument explicitly is needed because T could\n      // be a non-const reference (e.g. Matcher<Uncopyable&>).\n      ResultType result =\n          CallableTraits<Callable>::template Invoke<T>(callable_, obj);\n      return MatchPrintAndExplain(result, matcher_, listener);\n    }\n\n   private:\n    const std::string result_description_;\n    // Functors often define operator() as non-const method even though\n    // they are actually stateless. But we need to use them even when\n    // 'this' is a const pointer. It's the user's responsibility not to\n    // use stateful callables with ResultOf(), which doesn't guarantee\n    // how many times the callable will be invoked.\n    mutable CallableStorageType callable_;\n    const Matcher<ResultType> matcher_;\n  };  // class Impl\n\n  const std::string result_description_;\n  const CallableStorageType callable_;\n  const InnerMatcher matcher_;\n};\n\n// Implements a matcher that checks the size of an STL-style container.\ntemplate <typename SizeMatcher>\nclass SizeIsMatcher {\n public:\n  explicit SizeIsMatcher(const SizeMatcher& size_matcher)\n      : size_matcher_(size_matcher) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(new Impl<const Container&>(size_matcher_));\n  }\n\n  template <typename Container>\n  class Impl : public MatcherInterface<Container> {\n   public:\n    using SizeType = decltype(std::declval<Container>().size());\n    explicit Impl(const SizeMatcher& size_matcher)\n        : size_matcher_(MatcherCast<SizeType>(size_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"has a size that \";\n      size_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"has a size that \";\n      size_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Container container,\n                         MatchResultListener* listener) const override {\n      SizeType size = container.size();\n      StringMatchResultListener size_listener;\n      const bool result = size_matcher_.MatchAndExplain(size, &size_listener);\n      *listener << \"whose size \" << size\n                << (result ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(size_listener.str(), listener->stream());\n      return result;\n    }\n\n   private:\n    const Matcher<SizeType> size_matcher_;\n  };\n\n private:\n  const SizeMatcher size_matcher_;\n};\n\n// Implements a matcher that checks the begin()..end() distance of an STL-style\n// container.\ntemplate <typename DistanceMatcher>\nclass BeginEndDistanceIsMatcher {\n public:\n  explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)\n      : distance_matcher_(distance_matcher) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(new Impl<const Container&>(distance_matcher_));\n  }\n\n  template <typename Container>\n  class Impl : public MatcherInterface<Container> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        Container)>\n        ContainerView;\n    typedef typename std::iterator_traits<\n        typename ContainerView::type::const_iterator>::difference_type\n        DistanceType;\n    explicit Impl(const DistanceMatcher& distance_matcher)\n        : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"distance between begin() and end() \";\n      distance_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"distance between begin() and end() \";\n      distance_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Container container,\n                         MatchResultListener* listener) const override {\n      using std::begin;\n      using std::end;\n      DistanceType distance = std::distance(begin(container), end(container));\n      StringMatchResultListener distance_listener;\n      const bool result =\n          distance_matcher_.MatchAndExplain(distance, &distance_listener);\n      *listener << \"whose distance between begin() and end() \" << distance\n                << (result ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(distance_listener.str(), listener->stream());\n      return result;\n    }\n\n   private:\n    const Matcher<DistanceType> distance_matcher_;\n  };\n\n private:\n  const DistanceMatcher distance_matcher_;\n};\n\n// Implements an equality matcher for any STL-style container whose elements\n// support ==. This matcher is like Eq(), but its failure explanations provide\n// more detailed information that is useful when the container is used as a set.\n// The failure message reports elements that are in one of the operands but not\n// the other. The failure messages do not report duplicate or out-of-order\n// elements in the containers (which don't properly matter to sets, but can\n// occur if the containers are vectors or lists, for example).\n//\n// Uses the container's const_iterator, value_type, operator ==,\n// begin(), and end().\ntemplate <typename Container>\nclass ContainerEqMatcher {\n public:\n  typedef internal::StlContainerView<Container> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n\n  static_assert(!std::is_const<Container>::value,\n                \"Container type must not be const\");\n  static_assert(!std::is_reference<Container>::value,\n                \"Container type must not be a reference\");\n\n  // We make a copy of expected in case the elements in it are modified\n  // after this matcher is created.\n  explicit ContainerEqMatcher(const Container& expected)\n      : expected_(View::Copy(expected)) {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"equals \";\n    UniversalPrint(expected_, os);\n  }\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"does not equal \";\n    UniversalPrint(expected_, os);\n  }\n\n  template <typename LhsContainer>\n  bool MatchAndExplain(const LhsContainer& lhs,\n                       MatchResultListener* listener) const {\n    typedef internal::StlContainerView<\n        typename std::remove_const<LhsContainer>::type>\n        LhsView;\n    StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n    if (lhs_stl_container == expected_) return true;\n\n    ::std::ostream* const os = listener->stream();\n    if (os != nullptr) {\n      // Something is different. Check for extra values first.\n      bool printed_header = false;\n      for (auto it = lhs_stl_container.begin(); it != lhs_stl_container.end();\n           ++it) {\n        if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==\n            expected_.end()) {\n          if (printed_header) {\n            *os << \", \";\n          } else {\n            *os << \"which has these unexpected elements: \";\n            printed_header = true;\n          }\n          UniversalPrint(*it, os);\n        }\n      }\n\n      // Now check for missing values.\n      bool printed_header2 = false;\n      for (auto it = expected_.begin(); it != expected_.end(); ++it) {\n        if (internal::ArrayAwareFind(lhs_stl_container.begin(),\n                                     lhs_stl_container.end(),\n                                     *it) == lhs_stl_container.end()) {\n          if (printed_header2) {\n            *os << \", \";\n          } else {\n            *os << (printed_header ? \",\\nand\" : \"which\")\n                << \" doesn't have these expected elements: \";\n            printed_header2 = true;\n          }\n          UniversalPrint(*it, os);\n        }\n      }\n    }\n\n    return false;\n  }\n\n private:\n  const StlContainer expected_;\n};\n\n// A comparator functor that uses the < operator to compare two values.\nstruct LessComparator {\n  template <typename T, typename U>\n  bool operator()(const T& lhs, const U& rhs) const {\n    return lhs < rhs;\n  }\n};\n\n// Implements WhenSortedBy(comparator, container_matcher).\ntemplate <typename Comparator, typename ContainerMatcher>\nclass WhenSortedByMatcher {\n public:\n  WhenSortedByMatcher(const Comparator& comparator,\n                      const ContainerMatcher& matcher)\n      : comparator_(comparator), matcher_(matcher) {}\n\n  template <typename LhsContainer>\n  operator Matcher<LhsContainer>() const {\n    return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_));\n  }\n\n  template <typename LhsContainer>\n  class Impl : public MatcherInterface<LhsContainer> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        LhsContainer)>\n        LhsView;\n    typedef typename LhsView::type LhsStlContainer;\n    typedef typename LhsView::const_reference LhsStlContainerReference;\n    // Transforms std::pair<const Key, Value> into std::pair<Key, Value>\n    // so that we can match associative containers.\n    typedef\n        typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type\n            LhsValue;\n\n    Impl(const Comparator& comparator, const ContainerMatcher& matcher)\n        : comparator_(comparator), matcher_(matcher) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"(when sorted) \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"(when sorted) \";\n      matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(LhsContainer lhs,\n                         MatchResultListener* listener) const override {\n      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n      ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),\n                                               lhs_stl_container.end());\n      ::std::sort(sorted_container.begin(), sorted_container.end(),\n                  comparator_);\n\n      if (!listener->IsInterested()) {\n        // If the listener is not interested, we do not need to\n        // construct the inner explanation.\n        return matcher_.Matches(sorted_container);\n      }\n\n      *listener << \"which is \";\n      UniversalPrint(sorted_container, listener->stream());\n      *listener << \" when sorted\";\n\n      StringMatchResultListener inner_listener;\n      const bool match =\n          matcher_.MatchAndExplain(sorted_container, &inner_listener);\n      PrintIfNotEmpty(inner_listener.str(), listener->stream());\n      return match;\n    }\n\n   private:\n    const Comparator comparator_;\n    const Matcher<const ::std::vector<LhsValue>&> matcher_;\n\n    Impl(const Impl&) = delete;\n    Impl& operator=(const Impl&) = delete;\n  };\n\n private:\n  const Comparator comparator_;\n  const ContainerMatcher matcher_;\n};\n\n// Implements Pointwise(tuple_matcher, rhs_container).  tuple_matcher\n// must be able to be safely cast to Matcher<std::tuple<const T1&, const\n// T2&> >, where T1 and T2 are the types of elements in the LHS\n// container and the RHS container respectively.\ntemplate <typename TupleMatcher, typename RhsContainer>\nclass PointwiseMatcher {\n  static_assert(\n      !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,\n      \"use UnorderedPointwise with hash tables\");\n\n public:\n  typedef internal::StlContainerView<RhsContainer> RhsView;\n  typedef typename RhsView::type RhsStlContainer;\n  typedef typename RhsStlContainer::value_type RhsValue;\n\n  static_assert(!std::is_const<RhsContainer>::value,\n                \"RhsContainer type must not be const\");\n  static_assert(!std::is_reference<RhsContainer>::value,\n                \"RhsContainer type must not be a reference\");\n\n  // Like ContainerEq, we make a copy of rhs in case the elements in\n  // it are modified after this matcher is created.\n  PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)\n      : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {}\n\n  template <typename LhsContainer>\n  operator Matcher<LhsContainer>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,\n        \"use UnorderedPointwise with hash tables\");\n\n    return Matcher<LhsContainer>(\n        new Impl<const LhsContainer&>(tuple_matcher_, rhs_));\n  }\n\n  template <typename LhsContainer>\n  class Impl : public MatcherInterface<LhsContainer> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        LhsContainer)>\n        LhsView;\n    typedef typename LhsView::type LhsStlContainer;\n    typedef typename LhsView::const_reference LhsStlContainerReference;\n    typedef typename LhsStlContainer::value_type LhsValue;\n    // We pass the LHS value and the RHS value to the inner matcher by\n    // reference, as they may be expensive to copy.  We must use tuple\n    // instead of pair here, as a pair cannot hold references (C++ 98,\n    // 20.2.2 [lib.pairs]).\n    typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;\n\n    Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)\n        // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.\n        : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),\n          rhs_(rhs) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"contains \" << rhs_.size()\n          << \" values, where each value and its corresponding value in \";\n      UniversalPrinter<RhsStlContainer>::Print(rhs_, os);\n      *os << \" \";\n      mono_tuple_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"doesn't contain exactly \" << rhs_.size()\n          << \" values, or contains a value x at some index i\"\n          << \" where x and the i-th value of \";\n      UniversalPrint(rhs_, os);\n      *os << \" \";\n      mono_tuple_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(LhsContainer lhs,\n                         MatchResultListener* listener) const override {\n      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n      const size_t actual_size = lhs_stl_container.size();\n      if (actual_size != rhs_.size()) {\n        *listener << \"which contains \" << actual_size << \" values\";\n        return false;\n      }\n\n      auto left = lhs_stl_container.begin();\n      auto right = rhs_.begin();\n      for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {\n        if (listener->IsInterested()) {\n          StringMatchResultListener inner_listener;\n          // Create InnerMatcherArg as a temporarily object to avoid it outlives\n          // *left and *right. Dereference or the conversion to `const T&` may\n          // return temp objects, e.g. for vector<bool>.\n          if (!mono_tuple_matcher_.MatchAndExplain(\n                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),\n                                  ImplicitCast_<const RhsValue&>(*right)),\n                  &inner_listener)) {\n            *listener << \"where the value pair (\";\n            UniversalPrint(*left, listener->stream());\n            *listener << \", \";\n            UniversalPrint(*right, listener->stream());\n            *listener << \") at index #\" << i << \" don't match\";\n            PrintIfNotEmpty(inner_listener.str(), listener->stream());\n            return false;\n          }\n        } else {\n          if (!mono_tuple_matcher_.Matches(\n                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),\n                                  ImplicitCast_<const RhsValue&>(*right))))\n            return false;\n        }\n      }\n\n      return true;\n    }\n\n   private:\n    const Matcher<InnerMatcherArg> mono_tuple_matcher_;\n    const RhsStlContainer rhs_;\n  };\n\n private:\n  const TupleMatcher tuple_matcher_;\n  const RhsStlContainer rhs_;\n};\n\n// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.\ntemplate <typename Container>\nclass QuantifierMatcherImpl : public MatcherInterface<Container> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  template <typename InnerMatcher>\n  explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)\n      : inner_matcher_(\n            testing::SafeMatcherCast<const Element&>(inner_matcher)) {}\n\n  // Checks whether:\n  // * All elements in the container match, if all_elements_should_match.\n  // * Any element in the container matches, if !all_elements_should_match.\n  bool MatchAndExplainImpl(bool all_elements_should_match, Container container,\n                           MatchResultListener* listener) const {\n    StlContainerReference stl_container = View::ConstReference(container);\n    size_t i = 0;\n    for (auto it = stl_container.begin(); it != stl_container.end();\n         ++it, ++i) {\n      StringMatchResultListener inner_listener;\n      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);\n\n      if (matches != all_elements_should_match) {\n        *listener << \"whose element #\" << i\n                  << (matches ? \" matches\" : \" doesn't match\");\n        PrintIfNotEmpty(inner_listener.str(), listener->stream());\n        return !all_elements_should_match;\n      }\n    }\n    return all_elements_should_match;\n  }\n\n  bool MatchAndExplainImpl(const Matcher<size_t>& count_matcher,\n                           Container container,\n                           MatchResultListener* listener) const {\n    StlContainerReference stl_container = View::ConstReference(container);\n    size_t i = 0;\n    std::vector<size_t> match_elements;\n    for (auto it = stl_container.begin(); it != stl_container.end();\n         ++it, ++i) {\n      StringMatchResultListener inner_listener;\n      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);\n      if (matches) {\n        match_elements.push_back(i);\n      }\n    }\n    if (listener->IsInterested()) {\n      if (match_elements.empty()) {\n        *listener << \"has no element that matches\";\n      } else if (match_elements.size() == 1) {\n        *listener << \"whose element #\" << match_elements[0] << \" matches\";\n      } else {\n        *listener << \"whose elements (\";\n        std::string sep = \"\";\n        for (size_t e : match_elements) {\n          *listener << sep << e;\n          sep = \", \";\n        }\n        *listener << \") match\";\n      }\n    }\n    StringMatchResultListener count_listener;\n    if (count_matcher.MatchAndExplain(match_elements.size(), &count_listener)) {\n      *listener << \" and whose match quantity of \" << match_elements.size()\n                << \" matches\";\n      PrintIfNotEmpty(count_listener.str(), listener->stream());\n      return true;\n    } else {\n      if (match_elements.empty()) {\n        *listener << \" and\";\n      } else {\n        *listener << \" but\";\n      }\n      *listener << \" whose match quantity of \" << match_elements.size()\n                << \" does not match\";\n      PrintIfNotEmpty(count_listener.str(), listener->stream());\n      return false;\n    }\n  }\n\n protected:\n  const Matcher<const Element&> inner_matcher_;\n};\n\n// Implements Contains(element_matcher) for the given argument type Container.\n// Symmetric to EachMatcherImpl.\ntemplate <typename Container>\nclass ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit ContainsMatcherImpl(InnerMatcher inner_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"contains at least one element that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"doesn't contain any element that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(false, container, listener);\n  }\n};\n\n// Implements Each(element_matcher) for the given argument type Container.\n// Symmetric to ContainsMatcherImpl.\ntemplate <typename Container>\nclass EachMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit EachMatcherImpl(InnerMatcher inner_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"only contains elements that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"contains some element that \";\n    this->inner_matcher_.DescribeNegationTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(true, container, listener);\n  }\n};\n\n// Implements Contains(element_matcher).Times(n) for the given argument type\n// Container.\ntemplate <typename Container>\nclass ContainsTimesMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit ContainsTimesMatcherImpl(InnerMatcher inner_matcher,\n                                    Matcher<size_t> count_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher),\n        count_matcher_(std::move(count_matcher)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"quantity of elements that match \";\n    this->inner_matcher_.DescribeTo(os);\n    *os << \" \";\n    count_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"quantity of elements that match \";\n    this->inner_matcher_.DescribeTo(os);\n    *os << \" \";\n    count_matcher_.DescribeNegationTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(count_matcher_, container, listener);\n  }\n\n private:\n  const Matcher<size_t> count_matcher_;\n};\n\n// Implements polymorphic Contains(element_matcher).Times(n).\ntemplate <typename M>\nclass ContainsTimesMatcher {\n public:\n  explicit ContainsTimesMatcher(M m, Matcher<size_t> count_matcher)\n      : inner_matcher_(m), count_matcher_(std::move(count_matcher)) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(new ContainsTimesMatcherImpl<const Container&>(\n        inner_matcher_, count_matcher_));\n  }\n\n private:\n  const M inner_matcher_;\n  const Matcher<size_t> count_matcher_;\n};\n\n// Implements polymorphic Contains(element_matcher).\ntemplate <typename M>\nclass ContainsMatcher {\n public:\n  explicit ContainsMatcher(M m) : inner_matcher_(m) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(\n        new ContainsMatcherImpl<const Container&>(inner_matcher_));\n  }\n\n  ContainsTimesMatcher<M> Times(Matcher<size_t> count_matcher) const {\n    return ContainsTimesMatcher<M>(inner_matcher_, std::move(count_matcher));\n  }\n\n private:\n  const M inner_matcher_;\n};\n\n// Implements polymorphic Each(element_matcher).\ntemplate <typename M>\nclass EachMatcher {\n public:\n  explicit EachMatcher(M m) : inner_matcher_(m) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(\n        new EachMatcherImpl<const Container&>(inner_matcher_));\n  }\n\n private:\n  const M inner_matcher_;\n};\n\n// Use go/ranked-overloads for dispatching.\nstruct Rank0 {};\nstruct Rank1 : Rank0 {};\n\nnamespace pair_getters {\nusing std::get;\ntemplate <typename T>\nauto First(T& x, Rank0) -> decltype(get<0>(x)) {  // NOLINT\n  return get<0>(x);\n}\ntemplate <typename T>\nauto First(T& x, Rank1) -> decltype((x.first)) {  // NOLINT\n  return x.first;\n}\n\ntemplate <typename T>\nauto Second(T& x, Rank0) -> decltype(get<1>(x)) {  // NOLINT\n  return get<1>(x);\n}\ntemplate <typename T>\nauto Second(T& x, Rank1) -> decltype((x.second)) {  // NOLINT\n  return x.second;\n}\n}  // namespace pair_getters\n\n// Implements Key(inner_matcher) for the given argument pair type.\n// Key(inner_matcher) matches an std::pair whose 'first' field matches\n// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an\n// std::map that contains at least one element whose key is >= 5.\ntemplate <typename PairType>\nclass KeyMatcherImpl : public MatcherInterface<PairType> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;\n  typedef typename RawPairType::first_type KeyType;\n\n  template <typename InnerMatcher>\n  explicit KeyMatcherImpl(InnerMatcher inner_matcher)\n      : inner_matcher_(\n            testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {}\n\n  // Returns true if and only if 'key_value.first' (the key) matches the inner\n  // matcher.\n  bool MatchAndExplain(PairType key_value,\n                       MatchResultListener* listener) const override {\n    StringMatchResultListener inner_listener;\n    const bool match = inner_matcher_.MatchAndExplain(\n        pair_getters::First(key_value, Rank1()), &inner_listener);\n    const std::string explanation = inner_listener.str();\n    if (!explanation.empty()) {\n      *listener << \"whose first field is a value \" << explanation;\n    }\n    return match;\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"has a key that \";\n    inner_matcher_.DescribeTo(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"doesn't have a key that \";\n    inner_matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<const KeyType&> inner_matcher_;\n};\n\n// Implements polymorphic Key(matcher_for_key).\ntemplate <typename M>\nclass KeyMatcher {\n public:\n  explicit KeyMatcher(M m) : matcher_for_key_(m) {}\n\n  template <typename PairType>\n  operator Matcher<PairType>() const {\n    return Matcher<PairType>(\n        new KeyMatcherImpl<const PairType&>(matcher_for_key_));\n  }\n\n private:\n  const M matcher_for_key_;\n};\n\n// Implements polymorphic Address(matcher_for_address).\ntemplate <typename InnerMatcher>\nclass AddressMatcher {\n public:\n  explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}\n\n  template <typename Type>\n  operator Matcher<Type>() const {  // NOLINT\n    return Matcher<Type>(new Impl<const Type&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular object type.\n  template <typename Type>\n  class Impl : public MatcherInterface<Type> {\n   public:\n    using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<Address>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"has address that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not have address that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(Type object,\n                         MatchResultListener* listener) const override {\n      *listener << \"which has address \";\n      Address address = std::addressof(object);\n      return MatchPrintAndExplain(address, matcher_, listener);\n    }\n\n   private:\n    const Matcher<Address> matcher_;\n  };\n  const InnerMatcher matcher_;\n};\n\n// Implements Pair(first_matcher, second_matcher) for the given argument pair\n// type with its two matchers. See Pair() function below.\ntemplate <typename PairType>\nclass PairMatcherImpl : public MatcherInterface<PairType> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;\n  typedef typename RawPairType::first_type FirstType;\n  typedef typename RawPairType::second_type SecondType;\n\n  template <typename FirstMatcher, typename SecondMatcher>\n  PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)\n      : first_matcher_(\n            testing::SafeMatcherCast<const FirstType&>(first_matcher)),\n        second_matcher_(\n            testing::SafeMatcherCast<const SecondType&>(second_matcher)) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"has a first field that \";\n    first_matcher_.DescribeTo(os);\n    *os << \", and has a second field that \";\n    second_matcher_.DescribeTo(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"has a first field that \";\n    first_matcher_.DescribeNegationTo(os);\n    *os << \", or has a second field that \";\n    second_matcher_.DescribeNegationTo(os);\n  }\n\n  // Returns true if and only if 'a_pair.first' matches first_matcher and\n  // 'a_pair.second' matches second_matcher.\n  bool MatchAndExplain(PairType a_pair,\n                       MatchResultListener* listener) const override {\n    if (!listener->IsInterested()) {\n      // If the listener is not interested, we don't need to construct the\n      // explanation.\n      return first_matcher_.Matches(pair_getters::First(a_pair, Rank1())) &&\n             second_matcher_.Matches(pair_getters::Second(a_pair, Rank1()));\n    }\n    StringMatchResultListener first_inner_listener;\n    if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank1()),\n                                        &first_inner_listener)) {\n      *listener << \"whose first field does not match\";\n      PrintIfNotEmpty(first_inner_listener.str(), listener->stream());\n      return false;\n    }\n    StringMatchResultListener second_inner_listener;\n    if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank1()),\n                                         &second_inner_listener)) {\n      *listener << \"whose second field does not match\";\n      PrintIfNotEmpty(second_inner_listener.str(), listener->stream());\n      return false;\n    }\n    ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),\n                   listener);\n    return true;\n  }\n\n private:\n  void ExplainSuccess(const std::string& first_explanation,\n                      const std::string& second_explanation,\n                      MatchResultListener* listener) const {\n    *listener << \"whose both fields match\";\n    if (!first_explanation.empty()) {\n      *listener << \", where the first field is a value \" << first_explanation;\n    }\n    if (!second_explanation.empty()) {\n      *listener << \", \";\n      if (!first_explanation.empty()) {\n        *listener << \"and \";\n      } else {\n        *listener << \"where \";\n      }\n      *listener << \"the second field is a value \" << second_explanation;\n    }\n  }\n\n  const Matcher<const FirstType&> first_matcher_;\n  const Matcher<const SecondType&> second_matcher_;\n};\n\n// Implements polymorphic Pair(first_matcher, second_matcher).\ntemplate <typename FirstMatcher, typename SecondMatcher>\nclass PairMatcher {\n public:\n  PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)\n      : first_matcher_(first_matcher), second_matcher_(second_matcher) {}\n\n  template <typename PairType>\n  operator Matcher<PairType>() const {\n    return Matcher<PairType>(\n        new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));\n  }\n\n private:\n  const FirstMatcher first_matcher_;\n  const SecondMatcher second_matcher_;\n};\n\ntemplate <typename T, size_t... I>\nauto UnpackStructImpl(const T& t, std::index_sequence<I...>,\n                      int) -> decltype(std::tie(get<I>(t)...)) {\n  static_assert(std::tuple_size<T>::value == sizeof...(I),\n                \"Number of arguments doesn't match the number of fields.\");\n  return std::tie(get<I>(t)...);\n}\n\n#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) {\n  const auto& [a] = t;\n  return std::tie(a);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) {\n  const auto& [a, b] = t;\n  return std::tie(a, b);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) {\n  const auto& [a, b, c] = t;\n  return std::tie(a, b, c);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) {\n  const auto& [a, b, c, d] = t;\n  return std::tie(a, b, c, d);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) {\n  const auto& [a, b, c, d, e] = t;\n  return std::tie(a, b, c, d, e);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) {\n  const auto& [a, b, c, d, e, f] = t;\n  return std::tie(a, b, c, d, e, f);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) {\n  const auto& [a, b, c, d, e, f, g] = t;\n  return std::tie(a, b, c, d, e, f, g);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) {\n  const auto& [a, b, c, d, e, f, g, h] = t;\n  return std::tie(a, b, c, d, e, f, g, h);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);\n}\n#endif  // defined(__cpp_structured_bindings)\n\ntemplate <size_t I, typename T>\nauto UnpackStruct(const T& t)\n    -> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) {\n  return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0);\n}\n\n// Helper function to do comma folding in C++11.\n// The array ensures left-to-right order of evaluation.\n// Usage: VariadicExpand({expr...});\ntemplate <typename T, size_t N>\nvoid VariadicExpand(const T (&)[N]) {}\n\ntemplate <typename Struct, typename StructSize>\nclass FieldsAreMatcherImpl;\n\ntemplate <typename Struct, size_t... I>\nclass FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>\n    : public MatcherInterface<Struct> {\n  using UnpackedType =\n      decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));\n  using MatchersType = std::tuple<\n      Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>;\n\n public:\n  template <typename Inner>\n  explicit FieldsAreMatcherImpl(const Inner& matchers)\n      : matchers_(testing::SafeMatcherCast<\n                  const typename std::tuple_element<I, UnpackedType>::type&>(\n            std::get<I>(matchers))...) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    const char* separator = \"\";\n    VariadicExpand(\n        {(*os << separator << \"has field #\" << I << \" that \",\n          std::get<I>(matchers_).DescribeTo(os), separator = \", and \")...});\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    const char* separator = \"\";\n    VariadicExpand({(*os << separator << \"has field #\" << I << \" that \",\n                     std::get<I>(matchers_).DescribeNegationTo(os),\n                     separator = \", or \")...});\n  }\n\n  bool MatchAndExplain(Struct t, MatchResultListener* listener) const override {\n    return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener);\n  }\n\n private:\n  bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const {\n    if (!listener->IsInterested()) {\n      // If the listener is not interested, we don't need to construct the\n      // explanation.\n      bool good = true;\n      VariadicExpand({good = good && std::get<I>(matchers_).Matches(\n                                         std::get<I>(tuple))...});\n      return good;\n    }\n\n    size_t failed_pos = ~size_t{};\n\n    std::vector<StringMatchResultListener> inner_listener(sizeof...(I));\n\n    VariadicExpand(\n        {failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(\n                                        std::get<I>(tuple), &inner_listener[I])\n             ? failed_pos = I\n             : 0 ...});\n    if (failed_pos != ~size_t{}) {\n      *listener << \"whose field #\" << failed_pos << \" does not match\";\n      PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream());\n      return false;\n    }\n\n    *listener << \"whose all elements match\";\n    const char* separator = \", where\";\n    for (size_t index = 0; index < sizeof...(I); ++index) {\n      const std::string str = inner_listener[index].str();\n      if (!str.empty()) {\n        *listener << separator << \" field #\" << index << \" is a value \" << str;\n        separator = \", and\";\n      }\n    }\n\n    return true;\n  }\n\n  MatchersType matchers_;\n};\n\ntemplate <typename... Inner>\nclass FieldsAreMatcher {\n public:\n  explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {}\n\n  template <typename Struct>\n  operator Matcher<Struct>() const {  // NOLINT\n    return Matcher<Struct>(\n        new FieldsAreMatcherImpl<const Struct&,\n                                 std::index_sequence_for<Inner...>>(matchers_));\n  }\n\n private:\n  std::tuple<Inner...> matchers_;\n};\n\n// Implements ElementsAre() and ElementsAreArray().\ntemplate <typename Container>\nclass ElementsAreMatcherImpl : public MatcherInterface<Container> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef internal::StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  // Constructs the matcher from a sequence of element values or\n  // element matchers.\n  template <typename InputIter>\n  ElementsAreMatcherImpl(InputIter first, InputIter last) {\n    while (first != last) {\n      matchers_.push_back(MatcherCast<const Element&>(*first++));\n    }\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    if (count() == 0) {\n      *os << \"is empty\";\n    } else if (count() == 1) {\n      *os << \"has 1 element that \";\n      matchers_[0].DescribeTo(os);\n    } else {\n      *os << \"has \" << Elements(count()) << \" where\\n\";\n      for (size_t i = 0; i != count(); ++i) {\n        *os << \"element #\" << i << \" \";\n        matchers_[i].DescribeTo(os);\n        if (i + 1 < count()) {\n          *os << \",\\n\";\n        }\n      }\n    }\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    if (count() == 0) {\n      *os << \"isn't empty\";\n      return;\n    }\n\n    *os << \"doesn't have \" << Elements(count()) << \", or\\n\";\n    for (size_t i = 0; i != count(); ++i) {\n      *os << \"element #\" << i << \" \";\n      matchers_[i].DescribeNegationTo(os);\n      if (i + 1 < count()) {\n        *os << \", or\\n\";\n      }\n    }\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    // To work with stream-like \"containers\", we must only walk\n    // through the elements in one pass.\n\n    const bool listener_interested = listener->IsInterested();\n\n    // explanations[i] is the explanation of the element at index i.\n    ::std::vector<std::string> explanations(count());\n    StlContainerReference stl_container = View::ConstReference(container);\n    auto it = stl_container.begin();\n    size_t exam_pos = 0;\n    bool mismatch_found = false;  // Have we found a mismatched element yet?\n\n    // Go through the elements and matchers in pairs, until we reach\n    // the end of either the elements or the matchers, or until we find a\n    // mismatch.\n    for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) {\n      bool match;  // Does the current element match the current matcher?\n      if (listener_interested) {\n        StringMatchResultListener s;\n        match = matchers_[exam_pos].MatchAndExplain(*it, &s);\n        explanations[exam_pos] = s.str();\n      } else {\n        match = matchers_[exam_pos].Matches(*it);\n      }\n\n      if (!match) {\n        mismatch_found = true;\n        break;\n      }\n    }\n    // If mismatch_found is true, 'exam_pos' is the index of the mismatch.\n\n    // Find how many elements the actual container has.  We avoid\n    // calling size() s.t. this code works for stream-like \"containers\"\n    // that don't define size().\n    size_t actual_count = exam_pos;\n    for (; it != stl_container.end(); ++it) {\n      ++actual_count;\n    }\n\n    if (actual_count != count()) {\n      // The element count doesn't match.  If the container is empty,\n      // there's no need to explain anything as Google Mock already\n      // prints the empty container.  Otherwise we just need to show\n      // how many elements there actually are.\n      if (listener_interested && (actual_count != 0)) {\n        *listener << \"which has \" << Elements(actual_count);\n      }\n      return false;\n    }\n\n    if (mismatch_found) {\n      // The element count matches, but the exam_pos-th element doesn't match.\n      if (listener_interested) {\n        *listener << \"whose element #\" << exam_pos << \" doesn't match\";\n        PrintIfNotEmpty(explanations[exam_pos], listener->stream());\n      }\n      return false;\n    }\n\n    // Every element matches its expectation.  We need to explain why\n    // (the obvious ones can be skipped).\n    if (listener_interested) {\n      bool reason_printed = false;\n      for (size_t i = 0; i != count(); ++i) {\n        const std::string& s = explanations[i];\n        if (!s.empty()) {\n          if (reason_printed) {\n            *listener << \",\\nand \";\n          }\n          *listener << \"whose element #\" << i << \" matches, \" << s;\n          reason_printed = true;\n        }\n      }\n    }\n    return true;\n  }\n\n private:\n  static Message Elements(size_t count) {\n    return Message() << count << (count == 1 ? \" element\" : \" elements\");\n  }\n\n  size_t count() const { return matchers_.size(); }\n\n  ::std::vector<Matcher<const Element&>> matchers_;\n};\n\n// Connectivity matrix of (elements X matchers), in element-major order.\n// Initially, there are no edges.\n// Use NextGraph() to iterate over all possible edge configurations.\n// Use Randomize() to generate a random edge configuration.\nclass GTEST_API_ MatchMatrix {\n public:\n  MatchMatrix(size_t num_elements, size_t num_matchers)\n      : num_elements_(num_elements),\n        num_matchers_(num_matchers),\n        matched_(num_elements_ * num_matchers_, 0) {}\n\n  size_t LhsSize() const { return num_elements_; }\n  size_t RhsSize() const { return num_matchers_; }\n  bool HasEdge(size_t ilhs, size_t irhs) const {\n    return matched_[SpaceIndex(ilhs, irhs)] == 1;\n  }\n  void SetEdge(size_t ilhs, size_t irhs, bool b) {\n    matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0;\n  }\n\n  // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number,\n  // adds 1 to that number; returns false if incrementing the graph left it\n  // empty.\n  bool NextGraph();\n\n  void Randomize();\n\n  std::string DebugString() const;\n\n private:\n  size_t SpaceIndex(size_t ilhs, size_t irhs) const {\n    return ilhs * num_matchers_ + irhs;\n  }\n\n  size_t num_elements_;\n  size_t num_matchers_;\n\n  // Each element is a char interpreted as bool. They are stored as a\n  // flattened array in lhs-major order, use 'SpaceIndex()' to translate\n  // a (ilhs, irhs) matrix coordinate into an offset.\n  ::std::vector<char> matched_;\n};\n\ntypedef ::std::pair<size_t, size_t> ElementMatcherPair;\ntypedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;\n\n// Returns a maximum bipartite matching for the specified graph 'g'.\n// The matching is represented as a vector of {element, matcher} pairs.\nGTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g);\n\nstruct UnorderedMatcherRequire {\n  enum Flags {\n    Superset = 1 << 0,\n    Subset = 1 << 1,\n    ExactMatch = Superset | Subset,\n  };\n};\n\n// Untyped base class for implementing UnorderedElementsAre.  By\n// putting logic that's not specific to the element type here, we\n// reduce binary bloat and increase compilation speed.\nclass GTEST_API_ UnorderedElementsAreMatcherImplBase {\n protected:\n  explicit UnorderedElementsAreMatcherImplBase(\n      UnorderedMatcherRequire::Flags matcher_flags)\n      : match_flags_(matcher_flags) {}\n\n  // A vector of matcher describers, one for each element matcher.\n  // Does not own the describers (and thus can be used only when the\n  // element matchers are alive).\n  typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec;\n\n  // Describes this UnorderedElementsAre matcher.\n  void DescribeToImpl(::std::ostream* os) const;\n\n  // Describes the negation of this UnorderedElementsAre matcher.\n  void DescribeNegationToImpl(::std::ostream* os) const;\n\n  bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,\n                         const MatchMatrix& matrix,\n                         MatchResultListener* listener) const;\n\n  bool FindPairing(const MatchMatrix& matrix,\n                   MatchResultListener* listener) const;\n\n  MatcherDescriberVec& matcher_describers() { return matcher_describers_; }\n\n  static Message Elements(size_t n) {\n    return Message() << n << \" element\" << (n == 1 ? \"\" : \"s\");\n  }\n\n  UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }\n\n private:\n  UnorderedMatcherRequire::Flags match_flags_;\n  MatcherDescriberVec matcher_describers_;\n};\n\n// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and\n// IsSupersetOf.\ntemplate <typename Container>\nclass UnorderedElementsAreMatcherImpl\n    : public MatcherInterface<Container>,\n      public UnorderedElementsAreMatcherImplBase {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef internal::StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  template <typename InputIter>\n  UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,\n                                  InputIter first, InputIter last)\n      : UnorderedElementsAreMatcherImplBase(matcher_flags) {\n    for (; first != last; ++first) {\n      matchers_.push_back(MatcherCast<const Element&>(*first));\n    }\n    for (const auto& m : matchers_) {\n      matcher_describers().push_back(m.GetDescriber());\n    }\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    StlContainerReference stl_container = View::ConstReference(container);\n    ::std::vector<std::string> element_printouts;\n    MatchMatrix matrix =\n        AnalyzeElements(stl_container.begin(), stl_container.end(),\n                        &element_printouts, listener);\n\n    return VerifyMatchMatrix(element_printouts, matrix, listener) &&\n           FindPairing(matrix, listener);\n  }\n\n private:\n  template <typename ElementIter>\n  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,\n                              ::std::vector<std::string>* element_printouts,\n                              MatchResultListener* listener) const {\n    element_printouts->clear();\n    ::std::vector<char> did_match;\n    size_t num_elements = 0;\n    DummyMatchResultListener dummy;\n    for (; elem_first != elem_last; ++num_elements, ++elem_first) {\n      if (listener->IsInterested()) {\n        element_printouts->push_back(PrintToString(*elem_first));\n      }\n      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {\n        did_match.push_back(\n            matchers_[irhs].MatchAndExplain(*elem_first, &dummy));\n      }\n    }\n\n    MatchMatrix matrix(num_elements, matchers_.size());\n    ::std::vector<char>::const_iterator did_match_iter = did_match.begin();\n    for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {\n      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {\n        matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);\n      }\n    }\n    return matrix;\n  }\n\n  ::std::vector<Matcher<const Element&>> matchers_;\n};\n\n// Functor for use in TransformTuple.\n// Performs MatcherCast<Target> on an input argument of any type.\ntemplate <typename Target>\nstruct CastAndAppendTransform {\n  template <typename Arg>\n  Matcher<Target> operator()(const Arg& a) const {\n    return MatcherCast<Target>(a);\n  }\n};\n\n// Implements UnorderedElementsAre.\ntemplate <typename MatcherTuple>\nclass UnorderedElementsAreMatcher {\n public:\n  explicit UnorderedElementsAreMatcher(const MatcherTuple& args)\n      : matchers_(args) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n    typedef typename internal::StlContainerView<RawContainer>::type View;\n    typedef typename View::value_type Element;\n    typedef ::std::vector<Matcher<const Element&>> MatcherVec;\n    MatcherVec matchers;\n    matchers.reserve(::std::tuple_size<MatcherTuple>::value);\n    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,\n                         ::std::back_inserter(matchers));\n    return Matcher<Container>(\n        new UnorderedElementsAreMatcherImpl<const Container&>(\n            UnorderedMatcherRequire::ExactMatch, matchers.begin(),\n            matchers.end()));\n  }\n\n private:\n  const MatcherTuple matchers_;\n};\n\n// Implements ElementsAre.\ntemplate <typename MatcherTuple>\nclass ElementsAreMatcher {\n public:\n  explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||\n            ::std::tuple_size<MatcherTuple>::value < 2,\n        \"use UnorderedElementsAre with hash tables\");\n\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n    typedef typename internal::StlContainerView<RawContainer>::type View;\n    typedef typename View::value_type Element;\n    typedef ::std::vector<Matcher<const Element&>> MatcherVec;\n    MatcherVec matchers;\n    matchers.reserve(::std::tuple_size<MatcherTuple>::value);\n    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,\n                         ::std::back_inserter(matchers));\n    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(\n        matchers.begin(), matchers.end()));\n  }\n\n private:\n  const MatcherTuple matchers_;\n};\n\n// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().\ntemplate <typename T>\nclass UnorderedElementsAreArrayMatcher {\n public:\n  template <typename Iter>\n  UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,\n                                   Iter first, Iter last)\n      : match_flags_(match_flags), matchers_(first, last) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(\n        new UnorderedElementsAreMatcherImpl<const Container&>(\n            match_flags_, matchers_.begin(), matchers_.end()));\n  }\n\n private:\n  UnorderedMatcherRequire::Flags match_flags_;\n  ::std::vector<T> matchers_;\n};\n\n// Implements ElementsAreArray().\ntemplate <typename T>\nclass ElementsAreArrayMatcher {\n public:\n  template <typename Iter>\n  ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,\n        \"use UnorderedElementsAreArray with hash tables\");\n\n    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(\n        matchers_.begin(), matchers_.end()));\n  }\n\n private:\n  const ::std::vector<T> matchers_;\n};\n\n// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second\n// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,\n// second) is a polymorphic matcher that matches a value x if and only if\n// tm matches tuple (x, second).  Useful for implementing\n// UnorderedPointwise() in terms of UnorderedElementsAreArray().\n//\n// BoundSecondMatcher is copyable and assignable, as we need to put\n// instances of this class in a vector when implementing\n// UnorderedPointwise().\ntemplate <typename Tuple2Matcher, typename Second>\nclass BoundSecondMatcher {\n public:\n  BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)\n      : tuple2_matcher_(tm), second_value_(second) {}\n\n  BoundSecondMatcher(const BoundSecondMatcher& other) = default;\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));\n  }\n\n  // We have to define this for UnorderedPointwise() to compile in\n  // C++98 mode, as it puts BoundSecondMatcher instances in a vector,\n  // which requires the elements to be assignable in C++98.  The\n  // compiler cannot generate the operator= for us, as Tuple2Matcher\n  // and Second may not be assignable.\n  //\n  // However, this should never be called, so the implementation just\n  // need to assert.\n  void operator=(const BoundSecondMatcher& /*rhs*/) {\n    GTEST_LOG_(FATAL) << \"BoundSecondMatcher should never be assigned.\";\n  }\n\n private:\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n   public:\n    typedef ::std::tuple<T, Second> ArgTuple;\n\n    Impl(const Tuple2Matcher& tm, const Second& second)\n        : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),\n          second_value_(second) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"and \";\n      UniversalPrint(second_value_, os);\n      *os << \" \";\n      mono_tuple2_matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),\n                                                  listener);\n    }\n\n   private:\n    const Matcher<const ArgTuple&> mono_tuple2_matcher_;\n    const Second second_value_;\n  };\n\n  const Tuple2Matcher tuple2_matcher_;\n  const Second second_value_;\n};\n\n// Given a 2-tuple matcher tm and a value second,\n// MatcherBindSecond(tm, second) returns a matcher that matches a\n// value x if and only if tm matches tuple (x, second).  Useful for\n// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray().\ntemplate <typename Tuple2Matcher, typename Second>\nBoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(\n    const Tuple2Matcher& tm, const Second& second) {\n  return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);\n}\n\n// Returns the description for a matcher defined using the MATCHER*()\n// macro where the user-supplied description string is \"\", if\n// 'negation' is false; otherwise returns the description of the\n// negation of the matcher.  'param_values' contains a list of strings\n// that are the print-out of the matcher's parameters.\nGTEST_API_ std::string FormatMatcherDescription(\n    bool negation, const char* matcher_name,\n    const std::vector<const char*>& param_names, const Strings& param_values);\n\n// Implements a matcher that checks the value of a optional<> type variable.\ntemplate <typename ValueMatcher>\nclass OptionalMatcher {\n public:\n  explicit OptionalMatcher(const ValueMatcher& value_matcher)\n      : value_matcher_(value_matcher) {}\n\n  template <typename Optional>\n  operator Matcher<Optional>() const {\n    return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));\n  }\n\n  template <typename Optional>\n  class Impl : public MatcherInterface<Optional> {\n   public:\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;\n    typedef typename OptionalView::value_type ValueType;\n    explicit Impl(const ValueMatcher& value_matcher)\n        : value_matcher_(MatcherCast<ValueType>(value_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"value \";\n      value_matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"value \";\n      value_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Optional optional,\n                         MatchResultListener* listener) const override {\n      if (!optional) {\n        *listener << \"which is not engaged\";\n        return false;\n      }\n      const ValueType& value = *optional;\n      StringMatchResultListener value_listener;\n      const bool match = value_matcher_.MatchAndExplain(value, &value_listener);\n      *listener << \"whose value \" << PrintToString(value)\n                << (match ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(value_listener.str(), listener->stream());\n      return match;\n    }\n\n   private:\n    const Matcher<ValueType> value_matcher_;\n  };\n\n private:\n  const ValueMatcher value_matcher_;\n};\n\nnamespace variant_matcher {\n// Overloads to allow VariantMatcher to do proper ADL lookup.\ntemplate <typename T>\nvoid holds_alternative() {}\ntemplate <typename T>\nvoid get() {}\n\n// Implements a matcher that checks the value of a variant<> type variable.\ntemplate <typename T>\nclass VariantMatcher {\n public:\n  explicit VariantMatcher(::testing::Matcher<const T&> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  template <typename Variant>\n  bool MatchAndExplain(const Variant& value,\n                       ::testing::MatchResultListener* listener) const {\n    using std::get;\n    if (!listener->IsInterested()) {\n      return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));\n    }\n\n    if (!holds_alternative<T>(value)) {\n      *listener << \"whose value is not of type '\" << GetTypeName() << \"'\";\n      return false;\n    }\n\n    const T& elem = get<T>(value);\n    StringMatchResultListener elem_listener;\n    const bool match = matcher_.MatchAndExplain(elem, &elem_listener);\n    *listener << \"whose value \" << PrintToString(elem)\n              << (match ? \" matches\" : \" doesn't match\");\n    PrintIfNotEmpty(elem_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"is a variant<> with value of type '\" << GetTypeName()\n        << \"' and the value \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"is a variant<> with value of type other than '\" << GetTypeName()\n        << \"' or the value \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  static std::string GetTypeName() {\n#if GTEST_HAS_RTTI\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(\n        return internal::GetTypeName<T>());\n#endif\n    return \"the element type\";\n  }\n\n  const ::testing::Matcher<const T&> matcher_;\n};\n\n}  // namespace variant_matcher\n\nnamespace any_cast_matcher {\n\n// Overloads to allow AnyCastMatcher to do proper ADL lookup.\ntemplate <typename T>\nvoid any_cast() {}\n\n// Implements a matcher that any_casts the value.\ntemplate <typename T>\nclass AnyCastMatcher {\n public:\n  explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)\n      : matcher_(matcher) {}\n\n  template <typename AnyType>\n  bool MatchAndExplain(const AnyType& value,\n                       ::testing::MatchResultListener* listener) const {\n    if (!listener->IsInterested()) {\n      const T* ptr = any_cast<T>(&value);\n      return ptr != nullptr && matcher_.Matches(*ptr);\n    }\n\n    const T* elem = any_cast<T>(&value);\n    if (elem == nullptr) {\n      *listener << \"whose value is not of type '\" << GetTypeName() << \"'\";\n      return false;\n    }\n\n    StringMatchResultListener elem_listener;\n    const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);\n    *listener << \"whose value \" << PrintToString(*elem)\n              << (match ? \" matches\" : \" doesn't match\");\n    PrintIfNotEmpty(elem_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"is an 'any' type with value of type '\" << GetTypeName()\n        << \"' and the value \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"is an 'any' type with value of type other than '\" << GetTypeName()\n        << \"' or the value \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  static std::string GetTypeName() {\n#if GTEST_HAS_RTTI\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(\n        return internal::GetTypeName<T>());\n#endif\n    return \"the element type\";\n  }\n\n  const ::testing::Matcher<const T&> matcher_;\n};\n\n}  // namespace any_cast_matcher\n\n// Implements the Args() matcher.\ntemplate <class ArgsTuple, size_t... k>\nclass ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {\n public:\n  using RawArgsTuple = typename std::decay<ArgsTuple>::type;\n  using SelectedArgs =\n      std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>;\n  using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>;\n\n  template <typename InnerMatcher>\n  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)\n      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}\n\n  bool MatchAndExplain(ArgsTuple args,\n                       MatchResultListener* listener) const override {\n    // Workaround spurious C4100 on MSVC<=15.7 when k is empty.\n    (void)args;\n    const SelectedArgs& selected_args =\n        std::forward_as_tuple(std::get<k>(args)...);\n    if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args);\n\n    PrintIndices(listener->stream());\n    *listener << \"are \" << PrintToString(selected_args);\n\n    StringMatchResultListener inner_listener;\n    const bool match =\n        inner_matcher_.MatchAndExplain(selected_args, &inner_listener);\n    PrintIfNotEmpty(inner_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"are a tuple \";\n    PrintIndices(os);\n    inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"are a tuple \";\n    PrintIndices(os);\n    inner_matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  // Prints the indices of the selected fields.\n  static void PrintIndices(::std::ostream* os) {\n    *os << \"whose fields (\";\n    const char* sep = \"\";\n    // Workaround spurious C4189 on MSVC<=15.7 when k is empty.\n    (void)sep;\n    // The static_cast to void is needed to silence Clang's -Wcomma warning.\n    // This pattern looks suspiciously like we may have mismatched parentheses\n    // and may have been trying to use the first operation of the comma operator\n    // as a member of the array, so Clang warns that we may have made a mistake.\n    const char* dummy[] = {\n        \"\", (static_cast<void>(*os << sep << \"#\" << k), sep = \", \")...};\n    (void)dummy;\n    *os << \") \";\n  }\n\n  MonomorphicInnerMatcher inner_matcher_;\n};\n\ntemplate <class InnerMatcher, size_t... k>\nclass ArgsMatcher {\n public:\n  explicit ArgsMatcher(InnerMatcher inner_matcher)\n      : inner_matcher_(std::move(inner_matcher)) {}\n\n  template <typename ArgsTuple>\n  operator Matcher<ArgsTuple>() const {  // NOLINT\n    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_));\n  }\n\n private:\n  InnerMatcher inner_matcher_;\n};\n\n}  // namespace internal\n\n// ElementsAreArray(iterator_first, iterator_last)\n// ElementsAreArray(pointer, count)\n// ElementsAreArray(array)\n// ElementsAreArray(container)\n// ElementsAreArray({ e1, e2, ..., en })\n//\n// The ElementsAreArray() functions are like ElementsAre(...), except\n// that they are given a homogeneous sequence rather than taking each\n// element as a function argument. The sequence can be specified as an\n// array, a pointer and count, a vector, an initializer list, or an\n// STL iterator range. In each of these cases, the underlying sequence\n// can be either a sequence of values or a sequence of matchers.\n//\n// All forms of ElementsAreArray() make a copy of the input matcher sequence.\n\ntemplate <typename Iter>\ninline internal::ElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nElementsAreArray(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::ElementsAreArrayMatcher<T>(first, last);\n}\n\ntemplate <typename T>\ninline auto ElementsAreArray(const T* pointer, size_t count)\n    -> decltype(ElementsAreArray(pointer, pointer + count)) {\n  return ElementsAreArray(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline auto ElementsAreArray(const T (&array)[N])\n    -> decltype(ElementsAreArray(array, N)) {\n  return ElementsAreArray(array, N);\n}\n\ntemplate <typename Container>\ninline auto ElementsAreArray(const Container& container)\n    -> decltype(ElementsAreArray(container.begin(), container.end())) {\n  return ElementsAreArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline auto ElementsAreArray(::std::initializer_list<T> xs)\n    -> decltype(ElementsAreArray(xs.begin(), xs.end())) {\n  return ElementsAreArray(xs.begin(), xs.end());\n}\n\n// UnorderedElementsAreArray(iterator_first, iterator_last)\n// UnorderedElementsAreArray(pointer, count)\n// UnorderedElementsAreArray(array)\n// UnorderedElementsAreArray(container)\n// UnorderedElementsAreArray({ e1, e2, ..., en })\n//\n// UnorderedElementsAreArray() verifies that a bijective mapping onto a\n// collection of matchers exists.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nUnorderedElementsAreArray(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::ExactMatch, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    const T* pointer, size_t count) {\n  return UnorderedElementsAreArray(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    const T (&array)[N]) {\n  return UnorderedElementsAreArray(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nUnorderedElementsAreArray(const Container& container) {\n  return UnorderedElementsAreArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    ::std::initializer_list<T> xs) {\n  return UnorderedElementsAreArray(xs.begin(), xs.end());\n}\n\n// _ is a matcher that matches anything of any type.\n//\n// This definition is fine as:\n//\n//   1. The C++ standard permits using the name _ in a namespace that\n//      is not the global namespace or ::std.\n//   2. The AnythingMatcher class has no data member or constructor,\n//      so it's OK to create global variables of this type.\n//   3. c-style has approved of using _ in this case.\nconst internal::AnythingMatcher _ = {};\n// Creates a matcher that matches any value of the given type T.\ntemplate <typename T>\ninline Matcher<T> A() {\n  return _;\n}\n\n// Creates a matcher that matches any value of the given type T.\ntemplate <typename T>\ninline Matcher<T> An() {\n  return _;\n}\n\ntemplate <typename T, typename M>\nMatcher<T> internal::MatcherCastImpl<T, M>::CastImpl(\n    const M& value, std::false_type /* convertible_to_matcher */,\n    std::false_type /* convertible_to_T */) {\n  return Eq(value);\n}\n\n// Creates a polymorphic matcher that matches any NULL pointer.\ninline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {\n  return MakePolymorphicMatcher(internal::IsNullMatcher());\n}\n\n// Creates a polymorphic matcher that matches any non-NULL pointer.\n// This is convenient as Not(NULL) doesn't compile (the compiler\n// thinks that that expression is comparing a pointer with an integer).\ninline PolymorphicMatcher<internal::NotNullMatcher> NotNull() {\n  return MakePolymorphicMatcher(internal::NotNullMatcher());\n}\n\n// Creates a polymorphic matcher that matches any argument that\n// references variable x.\ntemplate <typename T>\ninline internal::RefMatcher<T&> Ref(T& x) {  // NOLINT\n  return internal::RefMatcher<T&>(x);\n}\n\n// Creates a polymorphic matcher that matches any NaN floating point.\ninline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {\n  return MakePolymorphicMatcher(internal::IsNanMatcher());\n}\n\n// Creates a matcher that matches any double argument approximately\n// equal to rhs, where two NANs are considered unequal.\ninline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {\n  return internal::FloatingEqMatcher<double>(rhs, false);\n}\n\n// Creates a matcher that matches any double argument approximately\n// equal to rhs, including NaN values when rhs is NaN.\ninline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {\n  return internal::FloatingEqMatcher<double>(rhs, true);\n}\n\n// Creates a matcher that matches any double argument approximately equal to\n// rhs, up to the specified max absolute error bound, where two NANs are\n// considered unequal.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<double> DoubleNear(double rhs,\n                                                      double max_abs_error) {\n  return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);\n}\n\n// Creates a matcher that matches any double argument approximately equal to\n// rhs, up to the specified max absolute error bound, including NaN values when\n// rhs is NaN.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear(\n    double rhs, double max_abs_error) {\n  return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error);\n}\n\n// Creates a matcher that matches any float argument approximately\n// equal to rhs, where two NANs are considered unequal.\ninline internal::FloatingEqMatcher<float> FloatEq(float rhs) {\n  return internal::FloatingEqMatcher<float>(rhs, false);\n}\n\n// Creates a matcher that matches any float argument approximately\n// equal to rhs, including NaN values when rhs is NaN.\ninline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {\n  return internal::FloatingEqMatcher<float>(rhs, true);\n}\n\n// Creates a matcher that matches any float argument approximately equal to\n// rhs, up to the specified max absolute error bound, where two NANs are\n// considered unequal.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<float> FloatNear(float rhs,\n                                                    float max_abs_error) {\n  return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error);\n}\n\n// Creates a matcher that matches any float argument approximately equal to\n// rhs, up to the specified max absolute error bound, including NaN values when\n// rhs is NaN.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<float> NanSensitiveFloatNear(\n    float rhs, float max_abs_error) {\n  return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error);\n}\n\n// Creates a matcher that matches a pointer (raw or smart) that points\n// to a value that matches inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::PointeeMatcher<InnerMatcher> Pointee(\n    const InnerMatcher& inner_matcher) {\n  return internal::PointeeMatcher<InnerMatcher>(inner_matcher);\n}\n\n#if GTEST_HAS_RTTI\n// Creates a matcher that matches a pointer or reference that matches\n// inner_matcher when dynamic_cast<To> is applied.\n// The result of dynamic_cast<To> is forwarded to the inner matcher.\n// If To is a pointer and the cast fails, the inner matcher will receive NULL.\n// If To is a reference and the cast fails, this matcher returns false\n// immediately.\ntemplate <typename To>\ninline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To>>\nWhenDynamicCastTo(const Matcher<To>& inner_matcher) {\n  return MakePolymorphicMatcher(\n      internal::WhenDynamicCastToMatcher<To>(inner_matcher));\n}\n#endif  // GTEST_HAS_RTTI\n\n// Creates a matcher that matches an object whose given field matches\n// 'matcher'.  For example,\n//   Field(&Foo::number, Ge(5))\n// matches a Foo object x if and only if x.number >= 5.\ntemplate <typename Class, typename FieldType, typename FieldMatcher>\ninline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(\n    FieldType Class::*field, const FieldMatcher& matcher) {\n  return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(\n      field, MatcherCast<const FieldType&>(matcher)));\n  // The call to MatcherCast() is required for supporting inner\n  // matchers of compatible types.  For example, it allows\n  //   Field(&Foo::bar, m)\n  // to compile where bar is an int32 and m is a matcher for int64.\n}\n\n// Same as Field() but also takes the name of the field to provide better error\n// messages.\ntemplate <typename Class, typename FieldType, typename FieldMatcher>\ninline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(\n    const std::string& field_name, FieldType Class::*field,\n    const FieldMatcher& matcher) {\n  return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(\n      field_name, field, MatcherCast<const FieldType&>(matcher)));\n}\n\n// Creates a matcher that matches an object whose given property\n// matches 'matcher'.  For example,\n//   Property(&Foo::str, StartsWith(\"hi\"))\n// matches a Foo object x if and only if x.str() starts with \"hi\".\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const>>\nProperty(PropertyType (Class::*property)() const,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const>(\n          property, MatcherCast<const PropertyType&>(matcher)));\n  // The call to MatcherCast() is required for supporting inner\n  // matchers of compatible types.  For example, it allows\n  //   Property(&Foo::bar, m)\n  // to compile where bar() returns an int32 and m is a matcher for int64.\n}\n\n// Same as Property() above, but also takes the name of the property to provide\n// better error messages.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const>>\nProperty(const std::string& property_name,\n         PropertyType (Class::*property)() const,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const>(\n          property_name, property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// The same as above but for reference-qualified member functions.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const&>>\nProperty(PropertyType (Class::*property)() const&,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const&>(\n          property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// Three-argument form for reference-qualified member functions.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const&>>\nProperty(const std::string& property_name,\n         PropertyType (Class::*property)() const&,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const&>(\n          property_name, property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// Creates a matcher that matches an object if and only if the result of\n// applying a callable to x matches 'matcher'. For example,\n//   ResultOf(f, StartsWith(\"hi\"))\n// matches a Foo object x if and only if f(x) starts with \"hi\".\n// `callable` parameter can be a function, function pointer, or a functor. It is\n// required to keep no state affecting the results of the calls on it and make\n// no assumptions about how many calls will be made. Any state it keeps must be\n// protected from the concurrent access.\ntemplate <typename Callable, typename InnerMatcher>\ninternal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(\n    Callable callable, InnerMatcher matcher) {\n  return internal::ResultOfMatcher<Callable, InnerMatcher>(std::move(callable),\n                                                           std::move(matcher));\n}\n\n// Same as ResultOf() above, but also takes a description of the `callable`\n// result to provide better error messages.\ntemplate <typename Callable, typename InnerMatcher>\ninternal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(\n    const std::string& result_description, Callable callable,\n    InnerMatcher matcher) {\n  return internal::ResultOfMatcher<Callable, InnerMatcher>(\n      result_description, std::move(callable), std::move(matcher));\n}\n\n// String matchers.\n\n// Matches a string equal to str.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrEq(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), true, true));\n}\n\n// Matches a string not equal to str.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrNe(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), false, true));\n}\n\n// Matches a string equal to str, ignoring case.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseEq(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), true, false));\n}\n\n// Matches a string not equal to str, ignoring case.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseNe(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>(\n      std::string(str), false, false));\n}\n\n// Creates a matcher that matches any string, std::string, or C string\n// that contains the given substring.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::HasSubstrMatcher<std::string>> HasSubstr(\n    const internal::StringLike<T>& substring) {\n  return MakePolymorphicMatcher(\n      internal::HasSubstrMatcher<std::string>(std::string(substring)));\n}\n\n// Matches a string that starts with 'prefix' (case-sensitive).\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StartsWithMatcher<std::string>> StartsWith(\n    const internal::StringLike<T>& prefix) {\n  return MakePolymorphicMatcher(\n      internal::StartsWithMatcher<std::string>(std::string(prefix)));\n}\n\n// Matches a string that ends with 'suffix' (case-sensitive).\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::EndsWithMatcher<std::string>> EndsWith(\n    const internal::StringLike<T>& suffix) {\n  return MakePolymorphicMatcher(\n      internal::EndsWithMatcher<std::string>(std::string(suffix)));\n}\n\n#if GTEST_HAS_STD_WSTRING\n// Wide string matchers.\n\n// Matches a string equal to str.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrEq(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, true, true));\n}\n\n// Matches a string not equal to str.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrNe(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, false, true));\n}\n\n// Matches a string equal to str, ignoring case.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseEq(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, true, false));\n}\n\n// Matches a string not equal to str, ignoring case.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseNe(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, false, false));\n}\n\n// Creates a matcher that matches any ::wstring, std::wstring, or C wide string\n// that contains the given substring.\ninline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring>> HasSubstr(\n    const std::wstring& substring) {\n  return MakePolymorphicMatcher(\n      internal::HasSubstrMatcher<std::wstring>(substring));\n}\n\n// Matches a string that starts with 'prefix' (case-sensitive).\ninline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring>> StartsWith(\n    const std::wstring& prefix) {\n  return MakePolymorphicMatcher(\n      internal::StartsWithMatcher<std::wstring>(prefix));\n}\n\n// Matches a string that ends with 'suffix' (case-sensitive).\ninline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring>> EndsWith(\n    const std::wstring& suffix) {\n  return MakePolymorphicMatcher(\n      internal::EndsWithMatcher<std::wstring>(suffix));\n}\n\n#endif  // GTEST_HAS_STD_WSTRING\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field == the second field.\ninline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field >= the second field.\ninline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field > the second field.\ninline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field <= the second field.\ninline internal::Le2Matcher Le() { return internal::Le2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field < the second field.\ninline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field != the second field.\ninline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatEq(first field) matches the second field.\ninline internal::FloatingEq2Matcher<float> FloatEq() {\n  return internal::FloatingEq2Matcher<float>();\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleEq(first field) matches the second field.\ninline internal::FloatingEq2Matcher<double> DoubleEq() {\n  return internal::FloatingEq2Matcher<double>();\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatEq(first field) matches the second field with NaN equality.\ninline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {\n  return internal::FloatingEq2Matcher<float>(true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleEq(first field) matches the second field with NaN equality.\ninline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {\n  return internal::FloatingEq2Matcher<double>(true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatNear(first field, max_abs_error) matches the second field.\ninline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {\n  return internal::FloatingEq2Matcher<float>(max_abs_error);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleNear(first field, max_abs_error) matches the second field.\ninline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {\n  return internal::FloatingEq2Matcher<double>(max_abs_error);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatNear(first field, max_abs_error) matches the second field with NaN\n// equality.\ninline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(\n    float max_abs_error) {\n  return internal::FloatingEq2Matcher<float>(max_abs_error, true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleNear(first field, max_abs_error) matches the second field with NaN\n// equality.\ninline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(\n    double max_abs_error) {\n  return internal::FloatingEq2Matcher<double>(max_abs_error, true);\n}\n\n// Creates a matcher that matches any value of type T that m doesn't\n// match.\ntemplate <typename InnerMatcher>\ninline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {\n  return internal::NotMatcher<InnerMatcher>(m);\n}\n\n// Returns a matcher that matches anything that satisfies the given\n// predicate.  The predicate can be any unary function or functor\n// whose return type can be implicitly converted to bool.\ntemplate <typename Predicate>\ninline PolymorphicMatcher<internal::TrulyMatcher<Predicate>> Truly(\n    Predicate pred) {\n  return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));\n}\n\n// Returns a matcher that matches the container size. The container must\n// support both size() and size_type which all STL-like containers provide.\n// Note that the parameter 'size' can be a value of type size_type as well as\n// matcher. For instance:\n//   EXPECT_THAT(container, SizeIs(2));     // Checks container has 2 elements.\n//   EXPECT_THAT(container, SizeIs(Le(2));  // Checks container has at most 2.\ntemplate <typename SizeMatcher>\ninline internal::SizeIsMatcher<SizeMatcher> SizeIs(\n    const SizeMatcher& size_matcher) {\n  return internal::SizeIsMatcher<SizeMatcher>(size_matcher);\n}\n\n// Returns a matcher that matches the distance between the container's begin()\n// iterator and its end() iterator, i.e. the size of the container. This matcher\n// can be used instead of SizeIs with containers such as std::forward_list which\n// do not implement size(). The container must provide const_iterator (with\n// valid iterator_traits), begin() and end().\ntemplate <typename DistanceMatcher>\ninline internal::BeginEndDistanceIsMatcher<DistanceMatcher> BeginEndDistanceIs(\n    const DistanceMatcher& distance_matcher) {\n  return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);\n}\n\n// Returns a matcher that matches an equal container.\n// This matcher behaves like Eq(), but in the event of mismatch lists the\n// values that are included in one container but not the other. (Duplicate\n// values and order differences are not explained.)\ntemplate <typename Container>\ninline PolymorphicMatcher<\n    internal::ContainerEqMatcher<typename std::remove_const<Container>::type>>\nContainerEq(const Container& rhs) {\n  return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));\n}\n\n// Returns a matcher that matches a container that, when sorted using\n// the given comparator, matches container_matcher.\ntemplate <typename Comparator, typename ContainerMatcher>\ninline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> WhenSortedBy(\n    const Comparator& comparator, const ContainerMatcher& container_matcher) {\n  return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(\n      comparator, container_matcher);\n}\n\n// Returns a matcher that matches a container that, when sorted using\n// the < operator, matches container_matcher.\ntemplate <typename ContainerMatcher>\ninline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>\nWhenSorted(const ContainerMatcher& container_matcher) {\n  return internal::WhenSortedByMatcher<internal::LessComparator,\n                                       ContainerMatcher>(\n      internal::LessComparator(), container_matcher);\n}\n\n// Matches an STL-style container or a native array that contains the\n// same number of elements as in rhs, where its i-th element and rhs's\n// i-th element (as a pair) satisfy the given pair matcher, for all i.\n// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const\n// T1&, const T2&> >, where T1 and T2 are the types of elements in the\n// LHS container and the RHS container respectively.\ntemplate <typename TupleMatcher, typename Container>\ninline internal::PointwiseMatcher<TupleMatcher,\n                                  typename std::remove_const<Container>::type>\nPointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {\n  return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,\n                                                             rhs);\n}\n\n// Supports the Pointwise(m, {a, b, c}) syntax.\ntemplate <typename TupleMatcher, typename T>\ninline internal::PointwiseMatcher<TupleMatcher, std::vector<T>> Pointwise(\n    const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {\n  return Pointwise(tuple_matcher, std::vector<T>(rhs));\n}\n\n// UnorderedPointwise(pair_matcher, rhs) matches an STL-style\n// container or a native array that contains the same number of\n// elements as in rhs, where in some permutation of the container, its\n// i-th element and rhs's i-th element (as a pair) satisfy the given\n// pair matcher, for all i.  Tuple2Matcher must be able to be safely\n// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are\n// the types of elements in the LHS container and the RHS container\n// respectively.\n//\n// This is like Pointwise(pair_matcher, rhs), except that the element\n// order doesn't matter.\ntemplate <typename Tuple2Matcher, typename RhsContainer>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename internal::BoundSecondMatcher<\n        Tuple2Matcher,\n        typename internal::StlContainerView<\n            typename std::remove_const<RhsContainer>::type>::type::value_type>>\nUnorderedPointwise(const Tuple2Matcher& tuple2_matcher,\n                   const RhsContainer& rhs_container) {\n  // RhsView allows the same code to handle RhsContainer being a\n  // STL-style container and it being a native C-style array.\n  typedef typename internal::StlContainerView<RhsContainer> RhsView;\n  typedef typename RhsView::type RhsStlContainer;\n  typedef typename RhsStlContainer::value_type Second;\n  const RhsStlContainer& rhs_stl_container =\n      RhsView::ConstReference(rhs_container);\n\n  // Create a matcher for each element in rhs_container.\n  ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second>> matchers;\n  for (auto it = rhs_stl_container.begin(); it != rhs_stl_container.end();\n       ++it) {\n    matchers.push_back(internal::MatcherBindSecond(tuple2_matcher, *it));\n  }\n\n  // Delegate the work to UnorderedElementsAreArray().\n  return UnorderedElementsAreArray(matchers);\n}\n\n// Supports the UnorderedPointwise(m, {a, b, c}) syntax.\ntemplate <typename Tuple2Matcher, typename T>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename internal::BoundSecondMatcher<Tuple2Matcher, T>>\nUnorderedPointwise(const Tuple2Matcher& tuple2_matcher,\n                   std::initializer_list<T> rhs) {\n  return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));\n}\n\n// Matches an STL-style container or a native array that contains at\n// least one element matching the given value or matcher.\n//\n// Examples:\n//   ::std::set<int> page_ids;\n//   page_ids.insert(3);\n//   page_ids.insert(1);\n//   EXPECT_THAT(page_ids, Contains(1));\n//   EXPECT_THAT(page_ids, Contains(Gt(2)));\n//   EXPECT_THAT(page_ids, Not(Contains(4)));  // See below for Times(0)\n//\n//   ::std::map<int, size_t> page_lengths;\n//   page_lengths[1] = 100;\n//   EXPECT_THAT(page_lengths,\n//               Contains(::std::pair<const int, size_t>(1, 100)));\n//\n//   const char* user_ids[] = { \"joe\", \"mike\", \"tom\" };\n//   EXPECT_THAT(user_ids, Contains(Eq(::std::string(\"tom\"))));\n//\n// The matcher supports a modifier `Times` that allows to check for arbitrary\n// occurrences including testing for absence with Times(0).\n//\n// Examples:\n//   ::std::vector<int> ids;\n//   ids.insert(1);\n//   ids.insert(1);\n//   ids.insert(3);\n//   EXPECT_THAT(ids, Contains(1).Times(2));      // 1 occurs 2 times\n//   EXPECT_THAT(ids, Contains(2).Times(0));      // 2 is not present\n//   EXPECT_THAT(ids, Contains(3).Times(Ge(1)));  // 3 occurs at least once\n\ntemplate <typename M>\ninline internal::ContainsMatcher<M> Contains(M matcher) {\n  return internal::ContainsMatcher<M>(matcher);\n}\n\n// IsSupersetOf(iterator_first, iterator_last)\n// IsSupersetOf(pointer, count)\n// IsSupersetOf(array)\n// IsSupersetOf(container)\n// IsSupersetOf({e1, e2, ..., en})\n//\n// IsSupersetOf() verifies that a surjective partial mapping onto a collection\n// of matchers exists. In other words, a container matches\n// IsSupersetOf({e1, ..., en}) if and only if there is a permutation\n// {y1, ..., yn} of some of the container's elements where y1 matches e1,\n// ..., and yn matches en. Obviously, the size of the container must be >= n\n// in order to have a match. Examples:\n//\n// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and\n//   1 matches Ne(0).\n// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches\n//   both Eq(1) and Lt(2). The reason is that different matchers must be used\n//   for elements in different slots of the container.\n// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches\n//   Eq(1) and (the second) 1 matches Lt(2).\n// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)\n//   Gt(1) and 3 matches (the second) Gt(1).\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nIsSupersetOf(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::Superset, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    const T* pointer, size_t count) {\n  return IsSupersetOf(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    const T (&array)[N]) {\n  return IsSupersetOf(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nIsSupersetOf(const Container& container) {\n  return IsSupersetOf(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    ::std::initializer_list<T> xs) {\n  return IsSupersetOf(xs.begin(), xs.end());\n}\n\n// IsSubsetOf(iterator_first, iterator_last)\n// IsSubsetOf(pointer, count)\n// IsSubsetOf(array)\n// IsSubsetOf(container)\n// IsSubsetOf({e1, e2, ..., en})\n//\n// IsSubsetOf() verifies that an injective mapping onto a collection of matchers\n// exists.  In other words, a container matches IsSubsetOf({e1, ..., en}) if and\n// only if there is a subset of matchers {m1, ..., mk} which would match the\n// container using UnorderedElementsAre.  Obviously, the size of the container\n// must be <= n in order to have a match. Examples:\n//\n// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).\n// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1\n//   matches Lt(0).\n// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both\n//   match Gt(0). The reason is that different matchers must be used for\n//   elements in different slots of the container.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nIsSubsetOf(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::Subset, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    const T* pointer, size_t count) {\n  return IsSubsetOf(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    const T (&array)[N]) {\n  return IsSubsetOf(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nIsSubsetOf(const Container& container) {\n  return IsSubsetOf(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    ::std::initializer_list<T> xs) {\n  return IsSubsetOf(xs.begin(), xs.end());\n}\n\n// Matches an STL-style container or a native array that contains only\n// elements matching the given value or matcher.\n//\n// Each(m) is semantically equivalent to `Not(Contains(Not(m)))`. Only\n// the messages are different.\n//\n// Examples:\n//   ::std::set<int> page_ids;\n//   // Each(m) matches an empty container, regardless of what m is.\n//   EXPECT_THAT(page_ids, Each(Eq(1)));\n//   EXPECT_THAT(page_ids, Each(Eq(77)));\n//\n//   page_ids.insert(3);\n//   EXPECT_THAT(page_ids, Each(Gt(0)));\n//   EXPECT_THAT(page_ids, Not(Each(Gt(4))));\n//   page_ids.insert(1);\n//   EXPECT_THAT(page_ids, Not(Each(Lt(2))));\n//\n//   ::std::map<int, size_t> page_lengths;\n//   page_lengths[1] = 100;\n//   page_lengths[2] = 200;\n//   page_lengths[3] = 300;\n//   EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));\n//   EXPECT_THAT(page_lengths, Each(Key(Le(3))));\n//\n//   const char* user_ids[] = { \"joe\", \"mike\", \"tom\" };\n//   EXPECT_THAT(user_ids, Not(Each(Eq(::std::string(\"tom\")))));\ntemplate <typename M>\ninline internal::EachMatcher<M> Each(M matcher) {\n  return internal::EachMatcher<M>(matcher);\n}\n\n// Key(inner_matcher) matches an std::pair whose 'first' field matches\n// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an\n// std::map that contains at least one element whose key is >= 5.\ntemplate <typename M>\ninline internal::KeyMatcher<M> Key(M inner_matcher) {\n  return internal::KeyMatcher<M>(inner_matcher);\n}\n\n// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field\n// matches first_matcher and whose 'second' field matches second_matcher.  For\n// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), \"foo\"))) can be used\n// to match a std::map<int, string> that contains exactly one element whose key\n// is >= 5 and whose value equals \"foo\".\ntemplate <typename FirstMatcher, typename SecondMatcher>\ninline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair(\n    FirstMatcher first_matcher, SecondMatcher second_matcher) {\n  return internal::PairMatcher<FirstMatcher, SecondMatcher>(first_matcher,\n                                                            second_matcher);\n}\n\nnamespace no_adl {\n// Conditional() creates a matcher that conditionally uses either the first or\n// second matcher provided. For example, we could create an `equal if, and only\n// if' matcher using the Conditional wrapper as follows:\n//\n//   EXPECT_THAT(result, Conditional(condition, Eq(expected), Ne(expected)));\ntemplate <typename MatcherTrue, typename MatcherFalse>\ninternal::ConditionalMatcher<MatcherTrue, MatcherFalse> Conditional(\n    bool condition, MatcherTrue matcher_true, MatcherFalse matcher_false) {\n  return internal::ConditionalMatcher<MatcherTrue, MatcherFalse>(\n      condition, std::move(matcher_true), std::move(matcher_false));\n}\n\n// FieldsAre(matchers...) matches piecewise the fields of compatible structs.\n// These include those that support `get<I>(obj)`, and when structured bindings\n// are enabled any class that supports them.\n// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types.\ntemplate <typename... M>\ninternal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre(\n    M&&... matchers) {\n  return internal::FieldsAreMatcher<typename std::decay<M>::type...>(\n      std::forward<M>(matchers)...);\n}\n\n// Creates a matcher that matches a pointer (raw or smart) that matches\n// inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::PointerMatcher<InnerMatcher> Pointer(\n    const InnerMatcher& inner_matcher) {\n  return internal::PointerMatcher<InnerMatcher>(inner_matcher);\n}\n\n// Creates a matcher that matches an object that has an address that matches\n// inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::AddressMatcher<InnerMatcher> Address(\n    const InnerMatcher& inner_matcher) {\n  return internal::AddressMatcher<InnerMatcher>(inner_matcher);\n}\n\n// Matches a base64 escaped string, when the unescaped string matches the\n// internal matcher.\ntemplate <typename MatcherType>\ninternal::WhenBase64UnescapedMatcher WhenBase64Unescaped(\n    const MatcherType& internal_matcher) {\n  return internal::WhenBase64UnescapedMatcher(internal_matcher);\n}\n}  // namespace no_adl\n\n// Returns a predicate that is satisfied by anything that matches the\n// given matcher.\ntemplate <typename M>\ninline internal::MatcherAsPredicate<M> Matches(M matcher) {\n  return internal::MatcherAsPredicate<M>(matcher);\n}\n\n// Returns true if and only if the value matches the matcher.\ntemplate <typename T, typename M>\ninline bool Value(const T& value, M matcher) {\n  return testing::Matches(matcher)(value);\n}\n\n// Matches the value against the given matcher and explains the match\n// result to listener.\ntemplate <typename T, typename M>\ninline bool ExplainMatchResult(M matcher, const T& value,\n                               MatchResultListener* listener) {\n  return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);\n}\n\n// Returns a string representation of the given matcher.  Useful for description\n// strings of matchers defined using MATCHER_P* macros that accept matchers as\n// their arguments.  For example:\n//\n// MATCHER_P(XAndYThat, matcher,\n//           \"X that \" + DescribeMatcher<int>(matcher, negation) +\n//               (negation ? \" or\" : \" and\") + \" Y that \" +\n//               DescribeMatcher<double>(matcher, negation)) {\n//   return ExplainMatchResult(matcher, arg.x(), result_listener) &&\n//          ExplainMatchResult(matcher, arg.y(), result_listener);\n// }\ntemplate <typename T, typename M>\nstd::string DescribeMatcher(const M& matcher, bool negation = false) {\n  ::std::stringstream ss;\n  Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);\n  if (negation) {\n    monomorphic_matcher.DescribeNegationTo(&ss);\n  } else {\n    monomorphic_matcher.DescribeTo(&ss);\n  }\n  return ss.str();\n}\n\ntemplate <typename... Args>\ninternal::ElementsAreMatcher<\n    std::tuple<typename std::decay<const Args&>::type...>>\nElementsAre(const Args&... matchers) {\n  return internal::ElementsAreMatcher<\n      std::tuple<typename std::decay<const Args&>::type...>>(\n      std::make_tuple(matchers...));\n}\n\ntemplate <typename... Args>\ninternal::UnorderedElementsAreMatcher<\n    std::tuple<typename std::decay<const Args&>::type...>>\nUnorderedElementsAre(const Args&... matchers) {\n  return internal::UnorderedElementsAreMatcher<\n      std::tuple<typename std::decay<const Args&>::type...>>(\n      std::make_tuple(matchers...));\n}\n\n// Define variadic matcher versions.\ntemplate <typename... Args>\ninternal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(\n    const Args&... matchers) {\n  return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(\n      matchers...);\n}\n\ntemplate <typename... Args>\ninternal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(\n    const Args&... matchers) {\n  return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(\n      matchers...);\n}\n\n// AnyOfArray(array)\n// AnyOfArray(pointer, count)\n// AnyOfArray(container)\n// AnyOfArray({ e1, e2, ..., en })\n// AnyOfArray(iterator_first, iterator_last)\n//\n// AnyOfArray() verifies whether a given value matches any member of a\n// collection of matchers.\n//\n// AllOfArray(array)\n// AllOfArray(pointer, count)\n// AllOfArray(container)\n// AllOfArray({ e1, e2, ..., en })\n// AllOfArray(iterator_first, iterator_last)\n//\n// AllOfArray() verifies whether a given value matches all members of a\n// collection of matchers.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::AnyOfArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nAnyOfArray(Iter first, Iter last) {\n  return internal::AnyOfArrayMatcher<\n      typename ::std::iterator_traits<Iter>::value_type>(first, last);\n}\n\ntemplate <typename Iter>\ninline internal::AllOfArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nAllOfArray(Iter first, Iter last) {\n  return internal::AllOfArrayMatcher<\n      typename ::std::iterator_traits<Iter>::value_type>(first, last);\n}\n\ntemplate <typename T>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) {\n  return AnyOfArray(ptr, ptr + count);\n}\n\ntemplate <typename T>\ninline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) {\n  return AllOfArray(ptr, ptr + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) {\n  return AnyOfArray(array, N);\n}\n\ntemplate <typename T, size_t N>\ninline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) {\n  return AllOfArray(array, N);\n}\n\ntemplate <typename Container>\ninline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray(\n    const Container& container) {\n  return AnyOfArray(container.begin(), container.end());\n}\n\ntemplate <typename Container>\ninline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray(\n    const Container& container) {\n  return AllOfArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(\n    ::std::initializer_list<T> xs) {\n  return AnyOfArray(xs.begin(), xs.end());\n}\n\ntemplate <typename T>\ninline internal::AllOfArrayMatcher<T> AllOfArray(\n    ::std::initializer_list<T> xs) {\n  return AllOfArray(xs.begin(), xs.end());\n}\n\n// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected\n// fields of it matches a_matcher.  C++ doesn't support default\n// arguments for function templates, so we have to overload it.\ntemplate <size_t... k, typename InnerMatcher>\ninternal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args(\n    InnerMatcher&& matcher) {\n  return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>(\n      std::forward<InnerMatcher>(matcher));\n}\n\n// AllArgs(m) is a synonym of m.  This is useful in\n//\n//   EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));\n//\n// which is easier to read than\n//\n//   EXPECT_CALL(foo, Bar(_, _)).With(Eq());\ntemplate <typename InnerMatcher>\ninline InnerMatcher AllArgs(const InnerMatcher& matcher) {\n  return matcher;\n}\n\n// Returns a matcher that matches the value of an optional<> type variable.\n// The matcher implementation only uses '!arg' and requires that the optional<>\n// type has a 'value_type' member type and that '*arg' is of type 'value_type'\n// and is printable using 'PrintToString'. It is compatible with\n// std::optional/std::experimental::optional.\n// Note that to compare an optional type variable against nullopt you should\n// use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the\n// optional value contains an optional itself.\ntemplate <typename ValueMatcher>\ninline internal::OptionalMatcher<ValueMatcher> Optional(\n    const ValueMatcher& value_matcher) {\n  return internal::OptionalMatcher<ValueMatcher>(value_matcher);\n}\n\n// Returns a matcher that matches the value of a absl::any type variable.\ntemplate <typename T>\nPolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T>> AnyWith(\n    const Matcher<const T&>& matcher) {\n  return MakePolymorphicMatcher(\n      internal::any_cast_matcher::AnyCastMatcher<T>(matcher));\n}\n\n// Returns a matcher that matches the value of a variant<> type variable.\n// The matcher implementation uses ADL to find the holds_alternative and get\n// functions.\n// It is compatible with std::variant.\ntemplate <typename T>\nPolymorphicMatcher<internal::variant_matcher::VariantMatcher<T>> VariantWith(\n    const Matcher<const T&>& matcher) {\n  return MakePolymorphicMatcher(\n      internal::variant_matcher::VariantMatcher<T>(matcher));\n}\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Anything inside the `internal` namespace is internal to the implementation\n// and must not be used in user code!\nnamespace internal {\n\nclass WithWhatMatcherImpl {\n public:\n  WithWhatMatcherImpl(Matcher<std::string> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"contains .what() that \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"contains .what() that does not \";\n    matcher_.DescribeTo(os);\n  }\n\n  template <typename Err>\n  bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {\n    *listener << \"which contains .what() (of value = \" << err.what()\n              << \") that \";\n    return matcher_.MatchAndExplain(err.what(), listener);\n  }\n\n private:\n  const Matcher<std::string> matcher_;\n};\n\ninline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(\n    Matcher<std::string> m) {\n  return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));\n}\n\ntemplate <typename Err>\nclass ExceptionMatcherImpl {\n  class NeverThrown {\n   public:\n    const char* what() const noexcept {\n      return \"this exception should never be thrown\";\n    }\n  };\n\n  // If the matchee raises an exception of a wrong type, we'd like to\n  // catch it and print its message and type. To do that, we add an additional\n  // catch clause:\n  //\n  //     try { ... }\n  //     catch (const Err&) { /* an expected exception */ }\n  //     catch (const std::exception&) { /* exception of a wrong type */ }\n  //\n  // However, if the `Err` itself is `std::exception`, we'd end up with two\n  // identical `catch` clauses:\n  //\n  //     try { ... }\n  //     catch (const std::exception&) { /* an expected exception */ }\n  //     catch (const std::exception&) { /* exception of a wrong type */ }\n  //\n  // This can cause a warning or an error in some compilers. To resolve\n  // the issue, we use a fake error type whenever `Err` is `std::exception`:\n  //\n  //     try { ... }\n  //     catch (const std::exception&) { /* an expected exception */ }\n  //     catch (const NeverThrown&) { /* exception of a wrong type */ }\n  using DefaultExceptionType = typename std::conditional<\n      std::is_same<typename std::remove_cv<\n                       typename std::remove_reference<Err>::type>::type,\n                   std::exception>::value,\n      const NeverThrown&, const std::exception&>::type;\n\n public:\n  ExceptionMatcherImpl(Matcher<const Err&> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"throws an exception which is a \" << GetTypeName<Err>();\n    *os << \" which \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"throws an exception which is not a \" << GetTypeName<Err>();\n    *os << \" which \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(T&& x, MatchResultListener* listener) const {\n    try {\n      (void)(std::forward<T>(x)());\n    } catch (const Err& err) {\n      *listener << \"throws an exception which is a \" << GetTypeName<Err>();\n      *listener << \" \";\n      return matcher_.MatchAndExplain(err, listener);\n    } catch (DefaultExceptionType err) {\n#if GTEST_HAS_RTTI\n      *listener << \"throws an exception of type \" << GetTypeName(typeid(err));\n      *listener << \" \";\n#else\n      *listener << \"throws an std::exception-derived type \";\n#endif\n      *listener << \"with description \\\"\" << err.what() << \"\\\"\";\n      return false;\n    } catch (...) {\n      *listener << \"throws an exception of an unknown type\";\n      return false;\n    }\n\n    *listener << \"does not throw any exception\";\n    return false;\n  }\n\n private:\n  const Matcher<const Err&> matcher_;\n};\n\n}  // namespace internal\n\n// Throws()\n// Throws(exceptionMatcher)\n// ThrowsMessage(messageMatcher)\n//\n// This matcher accepts a callable and verifies that when invoked, it throws\n// an exception with the given type and properties.\n//\n// Examples:\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       Throws<std::runtime_error>());\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       ThrowsMessage<std::runtime_error>(HasSubstr(\"message\")));\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       Throws<std::runtime_error>(\n//           Property(&std::runtime_error::what, HasSubstr(\"message\"))));\n\ntemplate <typename Err>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {\n  return MakePolymorphicMatcher(\n      internal::ExceptionMatcherImpl<Err>(A<const Err&>()));\n}\n\ntemplate <typename Err, typename ExceptionMatcher>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(\n    const ExceptionMatcher& exception_matcher) {\n  // Using matcher cast allows users to pass a matcher of a more broad type.\n  // For example user may want to pass Matcher<std::exception>\n  // to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.\n  return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(\n      SafeMatcherCast<const Err&>(exception_matcher)));\n}\n\ntemplate <typename Err, typename MessageMatcher>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(\n    MessageMatcher&& message_matcher) {\n  static_assert(std::is_base_of<std::exception, Err>::value,\n                \"expected an std::exception-derived type\");\n  return Throws<Err>(internal::WithWhat(\n      MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));\n}\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// These macros allow using matchers to check values in Google Test\n// tests.  ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)\n// succeed if and only if the value matches the matcher.  If the assertion\n// fails, the value and the description of the matcher will be printed.\n#define ASSERT_THAT(value, matcher) \\\n  ASSERT_PRED_FORMAT1(              \\\n      ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)\n#define EXPECT_THAT(value, matcher) \\\n  EXPECT_PRED_FORMAT1(              \\\n      ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)\n\n// MATCHER* macros itself are listed below.\n#define MATCHER(name, description)                                            \\\n  class name##Matcher                                                         \\\n      : public ::testing::internal::MatcherBaseImpl<name##Matcher> {          \\\n   public:                                                                    \\\n    template <typename arg_type>                                              \\\n    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {  \\\n     public:                                                                  \\\n      gmock_Impl() {}                                                         \\\n      bool MatchAndExplain(                                                   \\\n          const arg_type& arg,                                                \\\n          ::testing::MatchResultListener* result_listener) const override;    \\\n      void DescribeTo(::std::ostream* gmock_os) const override {              \\\n        *gmock_os << FormatDescription(false);                                \\\n      }                                                                       \\\n      void DescribeNegationTo(::std::ostream* gmock_os) const override {      \\\n        *gmock_os << FormatDescription(true);                                 \\\n      }                                                                       \\\n                                                                              \\\n     private:                                                                 \\\n      ::std::string FormatDescription(bool negation) const {                  \\\n        /* NOLINTNEXTLINE readability-redundant-string-init */                \\\n        ::std::string gmock_description = (description);                      \\\n        if (!gmock_description.empty()) {                                     \\\n          return gmock_description;                                           \\\n        }                                                                     \\\n        return ::testing::internal::FormatMatcherDescription(negation, #name, \\\n                                                             {}, {});         \\\n      }                                                                       \\\n    };                                                                        \\\n  };                                                                          \\\n  inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH()                          \\\n      GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-function\")              \\\n          GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-member-function\")   \\\n              name GMOCK_INTERNAL_WARNING_POP()() {                           \\\n    return {};                                                                \\\n  }                                                                           \\\n  template <typename arg_type>                                                \\\n  bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(                  \\\n      const arg_type& arg,                                                    \\\n      GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener*   \\\n          result_listener) const\n\n#define MATCHER_P(name, p0, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))\n#define MATCHER_P2(name, p0, p1, description)                            \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (#p0, #p1), \\\n                         (p0, p1))\n#define MATCHER_P3(name, p0, p1, p2, description)                             \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (#p0, #p1, #p2), \\\n                         (p0, p1, p2))\n#define MATCHER_P4(name, p0, p1, p2, p3, description)        \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, \\\n                         (#p0, #p1, #p2, #p3), (p0, p1, p2, p3))\n#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)    \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \\\n                         (#p0, #p1, #p2, #p3, #p4), (p0, p1, p2, p3, p4))\n#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description,  \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5),      \\\n                         (p0, p1, p2, p3, p4, p5))\n#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description,      \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6),     \\\n                         (p0, p1, p2, p3, p4, p5, p6))\n#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description,          \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7),    \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7))\n#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description,              \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8),   \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7, p8))\n#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description,                  \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8, #p9),   \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))\n\n#define GMOCK_INTERNAL_MATCHER(name, full_name, description, arg_names, args)  \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  class full_name : public ::testing::internal::MatcherBaseImpl<               \\\n                        full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \\\n   public:                                                                     \\\n    using full_name::MatcherBaseImpl::MatcherBaseImpl;                         \\\n    template <typename arg_type>                                               \\\n    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {   \\\n     public:                                                                   \\\n      explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args))          \\\n          : GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {}                       \\\n      bool MatchAndExplain(                                                    \\\n          const arg_type& arg,                                                 \\\n          ::testing::MatchResultListener* result_listener) const override;     \\\n      void DescribeTo(::std::ostream* gmock_os) const override {               \\\n        *gmock_os << FormatDescription(false);                                 \\\n      }                                                                        \\\n      void DescribeNegationTo(::std::ostream* gmock_os) const override {       \\\n        *gmock_os << FormatDescription(true);                                  \\\n      }                                                                        \\\n      GMOCK_INTERNAL_MATCHER_MEMBERS(args)                                     \\\n                                                                               \\\n     private:                                                                  \\\n      ::std::string FormatDescription(bool negation) const {                   \\\n        ::std::string gmock_description;                                       \\\n        gmock_description = (description);                                     \\\n        if (!gmock_description.empty()) {                                      \\\n          return gmock_description;                                            \\\n        }                                                                      \\\n        return ::testing::internal::FormatMatcherDescription(                  \\\n            negation, #name, {GMOCK_PP_REMOVE_PARENS(arg_names)},              \\\n            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(      \\\n                ::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>(        \\\n                    GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args))));             \\\n      }                                                                        \\\n    };                                                                         \\\n  };                                                                           \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name(             \\\n      GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) {                            \\\n    return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>(                \\\n        GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args));                              \\\n  }                                                                            \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  template <typename arg_type>                                                 \\\n  bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::                   \\\n      gmock_Impl<arg_type>::MatchAndExplain(                                   \\\n          const arg_type& arg,                                                 \\\n          GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::                    \\\n              MatchResultListener* result_listener) const\n\n#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \\\n  GMOCK_PP_TAIL(                                     \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args))\n#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \\\n  , typename arg##_type\n\n#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args))\n#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \\\n  , arg##_type\n\n#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \\\n  GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH(     \\\n      GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args))\n#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \\\n  , arg##_type gmock_p##i\n\n#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args))\n#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \\\n  , arg(::std::forward<arg##_type>(gmock_p##i))\n\n#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args)\n#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \\\n  const arg##_type arg;\n\n#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args))\n#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg\n\n#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))\n#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg) \\\n  , ::std::forward<arg##_type>(gmock_p##i)\n\n// To prevent ADL on certain functions we put them on a separate namespace.\nusing namespace no_adl;  // NOLINT\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046\n\n// Include any custom callback matchers added by the local installation.\n// We must include this header at the end to make sure it can use the\n// declarations from this file.\n#include \"gmock/internal/custom/gmock-matchers.h\"\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-more-actions.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some commonly used variadic actions.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n\n#include <memory>\n#include <utility>\n\n#include \"gmock/gmock-actions.h\"\n#include \"gmock/internal/gmock-port.h\"\n\n// Include any custom callback actions added by the local installation.\n#include \"gmock/internal/custom/gmock-generated-actions.h\"\n\n// Sometimes you want to give an action explicit template parameters\n// that cannot be inferred from its value parameters.  ACTION() and\n// ACTION_P*() don't support that.  ACTION_TEMPLATE() remedies that\n// and can be viewed as an extension to ACTION() and ACTION_P*().\n//\n// The syntax:\n//\n//   ACTION_TEMPLATE(ActionName,\n//                   HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),\n//                   AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }\n//\n// defines an action template that takes m explicit template\n// parameters and n value parameters.  name_i is the name of the i-th\n// template parameter, and kind_i specifies whether it's a typename,\n// an integral constant, or a template.  p_i is the name of the i-th\n// value parameter.\n//\n// Example:\n//\n//   // DuplicateArg<k, T>(output) converts the k-th argument of the mock\n//   // function to type T and copies it to *output.\n//   ACTION_TEMPLATE(DuplicateArg,\n//                   HAS_2_TEMPLATE_PARAMS(int, k, typename, T),\n//                   AND_1_VALUE_PARAMS(output)) {\n//     *output = T(::std::get<k>(args));\n//   }\n//   ...\n//     int n;\n//     EXPECT_CALL(mock, Foo(_, _))\n//         .WillOnce(DuplicateArg<1, unsigned char>(&n));\n//\n// To create an instance of an action template, write:\n//\n//   ActionName<t1, ..., t_m>(v1, ..., v_n)\n//\n// where the ts are the template arguments and the vs are the value\n// arguments.  The value argument types are inferred by the compiler.\n// If you want to explicitly specify the value argument types, you can\n// provide additional template arguments:\n//\n//   ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)\n//\n// where u_i is the desired type of v_i.\n//\n// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the\n// number of value parameters, but not on the number of template\n// parameters.  Without the restriction, the meaning of the following\n// is unclear:\n//\n//   OverloadedAction<int, bool>(x);\n//\n// Are we using a single-template-parameter action where 'bool' refers\n// to the type of x, or are we using a two-template-parameter action\n// where the compiler is asked to infer the type of x?\n//\n// Implementation notes:\n//\n// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and\n// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for\n// implementing ACTION_TEMPLATE.  The main trick we use is to create\n// new macro invocations when expanding a macro.  For example, we have\n//\n//   #define ACTION_TEMPLATE(name, template_params, value_params)\n//       ... GMOCK_INTERNAL_DECL_##template_params ...\n//\n// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)\n// to expand to\n//\n//       ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...\n//\n// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the\n// preprocessor will continue to expand it to\n//\n//       ... typename T ...\n//\n// This technique conforms to the C++ standard and is portable.  It\n// allows us to implement action templates using O(N) code, where N is\n// the maximum number of template/value parameters supported.  Without\n// using it, we'd have to devote O(N^2) amount of code to implement all\n// combinations of m and n.\n\n// Declares the template parameters.\n#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0\n#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \\\n  kind0 name0, kind1 name1\n#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2)               \\\n  kind0 name0, kind1 name1, kind2 name2\n#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3\n#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4\n#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3, \\\n                                                  kind4, name4, kind5, name5) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5\n#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6)                                           \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6\n#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7)                             \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7\n#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8)               \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7, kind8 name8\n#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(                       \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7, kind8 name8, kind9 name9\n\n// Lists the template parameters.\n#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0\n#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \\\n  name0, name1\n#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2)               \\\n  name0, name1, name2\n#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3) \\\n  name0, name1, name2, name3\n#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \\\n  name0, name1, name2, name3, name4\n#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3, \\\n                                                  kind4, name4, kind5, name5) \\\n  name0, name1, name2, name3, name4, name5\n#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6)                                           \\\n  name0, name1, name2, name3, name4, name5, name6\n#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7)                             \\\n  name0, name1, name2, name3, name4, name5, name6, name7\n#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8)               \\\n  name0, name1, name2, name3, name4, name5, name6, name7, name8\n#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(                       \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \\\n  name0, name1, name2, name3, name4, name5, name6, name7, name8, name9\n\n// Declares the types of value parameters.\n#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) \\\n  , typename p0##_type, typename p1##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,     \\\n      typename p3##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,         \\\n      typename p3##_type, typename p4##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6)                     \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7)                 \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type, typename p7##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7, p8)             \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type, typename p7##_type, typename p8##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                     p6, p7, p8, p9)         \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,              \\\n      typename p3##_type, typename p4##_type, typename p5##_type,            \\\n      typename p6##_type, typename p7##_type, typename p8##_type,            \\\n      typename p9##_type\n\n// Initializes the value parameters.\n#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS() ()\n#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0) \\\n  (p0##_type gmock_p0) : p0(::std::move(gmock_p0))\n#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1)             \\\n      : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1))\n#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)     \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2) \\\n      : p0(::std::move(gmock_p0)),                             \\\n        p1(::std::move(gmock_p1)),                             \\\n        p2(::std::move(gmock_p2))\n#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \\\n   p3##_type gmock_p3)                                         \\\n      : p0(::std::move(gmock_p0)),                             \\\n        p1(::std::move(gmock_p1)),                             \\\n        p2(::std::move(gmock_p2)),                             \\\n        p3(::std::move(gmock_p3))\n#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,     \\\n   p3##_type gmock_p3, p4##_type gmock_p4)                         \\\n      : p0(::std::move(gmock_p0)),                                 \\\n        p1(::std::move(gmock_p1)),                                 \\\n        p2(::std::move(gmock_p2)),                                 \\\n        p3(::std::move(gmock_p3)),                                 \\\n        p4(::std::move(gmock_p4))\n#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,         \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)         \\\n      : p0(::std::move(gmock_p0)),                                     \\\n        p1(::std::move(gmock_p1)),                                     \\\n        p2(::std::move(gmock_p2)),                                     \\\n        p3(::std::move(gmock_p3)),                                     \\\n        p4(::std::move(gmock_p4)),                                     \\\n        p5(::std::move(gmock_p5))\n#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,             \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,             \\\n   p6##_type gmock_p6)                                                     \\\n      : p0(::std::move(gmock_p0)),                                         \\\n        p1(::std::move(gmock_p1)),                                         \\\n        p2(::std::move(gmock_p2)),                                         \\\n        p3(::std::move(gmock_p3)),                                         \\\n        p4(::std::move(gmock_p4)),                                         \\\n        p5(::std::move(gmock_p5)),                                         \\\n        p6(::std::move(gmock_p6))\n#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,                 \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,                 \\\n   p6##_type gmock_p6, p7##_type gmock_p7)                                     \\\n      : p0(::std::move(gmock_p0)),                                             \\\n        p1(::std::move(gmock_p1)),                                             \\\n        p2(::std::move(gmock_p2)),                                             \\\n        p3(::std::move(gmock_p3)),                                             \\\n        p4(::std::move(gmock_p4)),                                             \\\n        p5(::std::move(gmock_p5)),                                             \\\n        p6(::std::move(gmock_p6)),                                             \\\n        p7(::std::move(gmock_p7))\n#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,                 \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,                 \\\n   p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)                 \\\n      : p0(::std::move(gmock_p0)),                                             \\\n        p1(::std::move(gmock_p1)),                                             \\\n        p2(::std::move(gmock_p2)),                                             \\\n        p3(::std::move(gmock_p3)),                                             \\\n        p4(::std::move(gmock_p4)),                                             \\\n        p5(::std::move(gmock_p5)),                                             \\\n        p6(::std::move(gmock_p6)),                                             \\\n        p7(::std::move(gmock_p7)),                                             \\\n        p8(::std::move(gmock_p8))\n#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,              \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,              \\\n   p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8,              \\\n   p9##_type gmock_p9)                                                      \\\n      : p0(::std::move(gmock_p0)),                                          \\\n        p1(::std::move(gmock_p1)),                                          \\\n        p2(::std::move(gmock_p2)),                                          \\\n        p3(::std::move(gmock_p3)),                                          \\\n        p4(::std::move(gmock_p4)),                                          \\\n        p5(::std::move(gmock_p5)),                                          \\\n        p6(::std::move(gmock_p6)),                                          \\\n        p7(::std::move(gmock_p7)),                                          \\\n        p8(::std::move(gmock_p8)),                                          \\\n        p9(::std::move(gmock_p9))\n\n// Defines the copy constructor\n#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \\\n  {}  // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134\n#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default;\n\n// Declares the fields for storing the value parameters.\n#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;\n#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) \\\n  p0##_type p0;                                        \\\n  p1##_type p1;\n#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  p0##_type p0;                                            \\\n  p1##_type p1;                                            \\\n  p2##_type p2;\n#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  p0##_type p0;                                                \\\n  p1##_type p1;                                                \\\n  p2##_type p2;                                                \\\n  p3##_type p3;\n#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0##_type p0;                                                    \\\n  p1##_type p1;                                                    \\\n  p2##_type p2;                                                    \\\n  p3##_type p3;                                                    \\\n  p4##_type p4;\n#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  p0##_type p0;                                                        \\\n  p1##_type p1;                                                        \\\n  p2##_type p2;                                                        \\\n  p3##_type p3;                                                        \\\n  p4##_type p4;                                                        \\\n  p5##_type p5;\n#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0##_type p0;                                                            \\\n  p1##_type p1;                                                            \\\n  p2##_type p2;                                                            \\\n  p3##_type p3;                                                            \\\n  p4##_type p4;                                                            \\\n  p5##_type p5;                                                            \\\n  p6##_type p6;\n#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0##_type p0;                                                                \\\n  p1##_type p1;                                                                \\\n  p2##_type p2;                                                                \\\n  p3##_type p3;                                                                \\\n  p4##_type p4;                                                                \\\n  p5##_type p5;                                                                \\\n  p6##_type p6;                                                                \\\n  p7##_type p7;\n#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0##_type p0;                                                                \\\n  p1##_type p1;                                                                \\\n  p2##_type p2;                                                                \\\n  p3##_type p3;                                                                \\\n  p4##_type p4;                                                                \\\n  p5##_type p5;                                                                \\\n  p6##_type p6;                                                                \\\n  p7##_type p7;                                                                \\\n  p8##_type p8;\n#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0##_type p0;                                                             \\\n  p1##_type p1;                                                             \\\n  p2##_type p2;                                                             \\\n  p3##_type p3;                                                             \\\n  p4##_type p4;                                                             \\\n  p5##_type p5;                                                             \\\n  p6##_type p6;                                                             \\\n  p7##_type p7;                                                             \\\n  p8##_type p8;                                                             \\\n  p9##_type p9;\n\n// Lists the value parameters.\n#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0\n#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1\n#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2\n#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3\n#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0, p1, p2, p3, p4\n#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  p0, p1, p2, p3, p4, p5\n#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0, p1, p2, p3, p4, p5, p6\n#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0, p1, p2, p3, p4, p5, p6, p7\n#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0, p1, p2, p3, p4, p5, p6, p7, p8\n#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0, p1, p2, p3, p4, p5, p6, p7, p8, p9\n\n// Lists the value parameter types.\n#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) \\\n  , p0##_type, p1##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  , p0##_type, p1##_type, p2##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6)                     \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, p6##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7)                 \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,       \\\n      p6##_type, p7##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7, p8)             \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,       \\\n      p6##_type, p7##_type, p8##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                     p6, p7, p8, p9)         \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,        \\\n      p6##_type, p7##_type, p8##_type, p9##_type\n\n// Declares the value parameters.\n#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0\n#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) \\\n  p0##_type p0, p1##_type p1\n#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  p0##_type p0, p1##_type p1, p2##_type p2\n#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3\n#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4\n#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)  \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \\\n      p5##_type p5\n#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,    \\\n      p5##_type p5, p6##_type p6\n#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,        \\\n      p5##_type p5, p6##_type p6, p7##_type p7\n#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,        \\\n      p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8\n#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,     \\\n      p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, p9##_type p9\n\n// The suffix of the class template implementing the action template.\n#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P\n#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2\n#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3\n#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4\n#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5\n#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6\n#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7\n#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7)                         \\\n  P8\n#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8)                     \\\n  P9\n#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                 p7, p8, p9)                 \\\n  P10\n\n// The name of the class template implementing the action template.\n#define GMOCK_ACTION_CLASS_(name, value_params) \\\n  GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)\n\n#define ACTION_TEMPLATE(name, template_params, value_params)                   \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  class GMOCK_ACTION_CLASS_(name, value_params) {                              \\\n   public:                                                                     \\\n    explicit GMOCK_ACTION_CLASS_(name, value_params)(                          \\\n        GMOCK_INTERNAL_DECL_##value_params)                                    \\\n        GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),    \\\n                    = default;                                                 \\\n                    ,                                                          \\\n                    : impl_(std::make_shared<gmock_Impl>(                      \\\n                        GMOCK_INTERNAL_LIST_##value_params)){})                \\\n            GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \\\n                name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_      \\\n        ##value_params                                                         \\\n        GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_(           \\\n            name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_         \\\n        ##value_params template <typename F>                                   \\\n        operator ::testing::Action<F>() const {                                \\\n      return GMOCK_PP_IF(                                                      \\\n          GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),              \\\n          (::testing::internal::MakeAction<F, gmock_Impl>()),                  \\\n          (::testing::internal::MakeAction<F>(impl_)));                        \\\n    }                                                                          \\\n                                                                               \\\n   private:                                                                    \\\n    class gmock_Impl {                                                         \\\n     public:                                                                   \\\n      explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}                \\\n      template <typename function_type, typename return_type,                  \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \\\n      GMOCK_INTERNAL_DEFN_##value_params                                       \\\n    };                                                                         \\\n    GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), ,      \\\n                std::shared_ptr<const gmock_Impl> impl_;)                      \\\n  };                                                                           \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  GMOCK_ACTION_CLASS_(                                                         \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \\\n      name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;         \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  inline GMOCK_ACTION_CLASS_(                                                  \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \\\n  name(GMOCK_INTERNAL_DECL_##value_params) {                                   \\\n    return GMOCK_ACTION_CLASS_(                                                \\\n        name, value_params)<GMOCK_INTERNAL_LIST_##template_params              \\\n                                GMOCK_INTERNAL_LIST_TYPE_##value_params>(      \\\n        GMOCK_INTERNAL_LIST_##value_params);                                   \\\n  }                                                                            \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  template <typename function_type, typename return_type, typename args_type,  \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \\\n  return_type GMOCK_ACTION_CLASS_(                                             \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>::       \\\n      gmock_Impl::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_)  \\\n          const\n\nnamespace testing {\n\n// The ACTION*() macros trigger warning C4100 (unreferenced formal\n// parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in\n// the macro definition, as the warnings are generated when the macro\n// is expanded and macro expansion cannot contain #pragma.  Therefore\n// we suppress them here.\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\nnamespace internal {\n\n// internal::InvokeArgument - a helper for InvokeArgument action.\n// The basic overloads are provided here for generic functors.\n// Overloads for other custom-callables are provided in the\n// internal/custom/gmock-generated-actions.h header.\ntemplate <typename F, typename... Args>\nauto InvokeArgument(F &&f,\n                    Args... args) -> decltype(std::forward<F>(f)(args...)) {\n  return std::forward<F>(f)(args...);\n}\n\ntemplate <std::size_t index, typename... Params>\nstruct InvokeArgumentAction {\n  template <typename... Args,\n            typename = typename std::enable_if<(index < sizeof...(Args))>::type>\n  auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(\n      std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),\n      std::declval<const Params &>()...)) {\n    internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},\n                                               std::forward<Args>(args)...);\n    return params.Apply([&](const Params &...unpacked_params) {\n      auto &&callable = std::move(args_tuple.template Get<index>());\n      return internal::InvokeArgument(\n          std::forward<decltype(callable)>(callable), unpacked_params...);\n    });\n  }\n\n  internal::FlatTuple<Params...> params;\n};\n\n}  // namespace internal\n\n// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th\n// (0-based) argument, which must be a k-ary callable, of the mock\n// function, with arguments a1, a2, ..., a_k.\n//\n// Notes:\n//\n//   1. The arguments are passed by value by default.  If you need to\n//   pass an argument by reference, wrap it inside std::ref().  For\n//   example,\n//\n//     InvokeArgument<1>(5, string(\"Hello\"), std::ref(foo))\n//\n//   passes 5 and string(\"Hello\") by value, and passes foo by\n//   reference.\n//\n//   2. If the callable takes an argument by reference but std::ref() is\n//   not used, it will receive the reference to a copy of the value,\n//   instead of the original value.  For example, when the 0-th\n//   argument of the mock function takes a const string&, the action\n//\n//     InvokeArgument<0>(string(\"Hello\"))\n//\n//   makes a copy of the temporary string(\"Hello\") object and passes a\n//   reference of the copy, instead of the original temporary object,\n//   to the callable.  This makes it easy for a user to define an\n//   InvokeArgument action from temporary values and have it performed\n//   later.\ntemplate <std::size_t index, typename... Params>\ninternal::InvokeArgumentAction<index, typename std::decay<Params>::type...>\nInvokeArgument(Params &&...params) {\n  return {internal::FlatTuple<typename std::decay<Params>::type...>(\n      internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};\n}\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-more-matchers.h",
    "content": "// Copyright 2013, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some matchers that depend on gmock-matchers.h.\n//\n// Note that tests are implemented in gmock-matchers_test.cc rather than\n// gmock-more-matchers-test.cc.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n\n#include <ostream>\n#include <string>\n\n#include \"gmock/gmock-matchers.h\"\n\nnamespace testing {\n\n// Silence C4100 (unreferenced formal\n// parameter) for MSVC\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\n// and silence C4800 (C4800: 'int *const ': forcing value\n// to bool 'true' or 'false') for MSVC 14\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)\n#endif\n\nnamespace internal {\n\n// Implements the polymorphic IsEmpty matcher, which\n// can be used as a Matcher<T> as long as T is either a container that defines\n// empty() and size() (e.g. std::vector or std::string), or a C-style string.\nclass IsEmptyMatcher {\n public:\n  // Matches anything that defines empty() and size().\n  template <typename MatcheeContainerType>\n  bool MatchAndExplain(const MatcheeContainerType& c,\n                       MatchResultListener* listener) const {\n    if (c.empty()) {\n      return true;\n    }\n    *listener << \"whose size is \" << c.size();\n    return false;\n  }\n\n  // Matches C-style strings.\n  bool MatchAndExplain(const char* s, MatchResultListener* listener) const {\n    return MatchAndExplain(std::string(s), listener);\n  }\n\n  // Describes what this matcher matches.\n  void DescribeTo(std::ostream* os) const { *os << \"is empty\"; }\n\n  void DescribeNegationTo(std::ostream* os) const { *os << \"isn't empty\"; }\n};\n\n}  // namespace internal\n\n// Creates a polymorphic matcher that matches an empty container or C-style\n// string. The container must support both size() and empty(), which all\n// STL-like containers provide.\ninline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() {\n  return MakePolymorphicMatcher(internal::IsEmptyMatcher());\n}\n\n// Define a matcher that matches a value that evaluates in boolean\n// context to true.  Useful for types that define \"explicit operator\n// bool\" operators and so can't be compared for equality with true\n// and false.\nMATCHER(IsTrue, negation ? \"is false\" : \"is true\") {\n  return static_cast<bool>(arg);\n}\n\n// Define a matcher that matches a value that evaluates in boolean\n// context to false.  Useful for types that define \"explicit operator\n// bool\" operators and so can't be compared for equality with true\n// and false.\nMATCHER(IsFalse, negation ? \"is true\" : \"is false\") {\n  return !static_cast<bool>(arg);\n}\n\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4800\n#endif\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-nice-strict.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Implements class templates NiceMock, NaggyMock, and StrictMock.\n//\n// Given a mock class MockFoo that is created using Google Mock,\n// NiceMock<MockFoo> is a subclass of MockFoo that allows\n// uninteresting calls (i.e. calls to mock methods that have no\n// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo\n// that prints a warning when an uninteresting call occurs, and\n// StrictMock<MockFoo> is a subclass of MockFoo that treats all\n// uninteresting calls as errors.\n//\n// Currently a mock is naggy by default, so MockFoo and\n// NaggyMock<MockFoo> behave like the same.  However, we will soon\n// switch the default behavior of mocks to be nice, as that in general\n// leads to more maintainable tests.  When that happens, MockFoo will\n// stop behaving like NaggyMock<MockFoo> and start behaving like\n// NiceMock<MockFoo>.\n//\n// NiceMock, NaggyMock, and StrictMock \"inherit\" the constructors of\n// their respective base class.  Therefore you can write\n// NiceMock<MockFoo>(5, \"a\") to construct a nice mock where MockFoo\n// has a constructor that accepts (int, const char*), for example.\n//\n// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,\n// and StrictMock<MockFoo> only works for mock methods defined using\n// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.\n// If a mock method is defined in a base class of MockFoo, the \"nice\"\n// or \"strict\" modifier may not affect it, depending on the compiler.\n// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT\n// supported.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n\n#include <cstdint>\n#include <type_traits>\n\n#include \"gmock/gmock-spec-builders.h\"\n#include \"gmock/internal/gmock-port.h\"\n\nnamespace testing {\ntemplate <class MockClass>\nclass NiceMock;\ntemplate <class MockClass>\nclass NaggyMock;\ntemplate <class MockClass>\nclass StrictMock;\n\nnamespace internal {\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const NiceMock<T>&);\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const NaggyMock<T>&);\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const StrictMock<T>&);\nstd::false_type StrictnessModifierProbe(...);\n\ntemplate <typename T>\nconstexpr bool HasStrictnessModifier() {\n  return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;\n}\n\n// Base classes that register and deregister with testing::Mock to alter the\n// default behavior around uninteresting calls. Inheriting from one of these\n// classes first and then MockClass ensures the MockClass constructor is run\n// after registration, and that the MockClass destructor runs before\n// deregistration. This guarantees that MockClass's constructor and destructor\n// run with the same level of strictness as its instance methods.\n\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \\\n    (defined(_MSC_VER) || defined(__clang__))\n// We need to mark these classes with this declspec to ensure that\n// the empty base class optimization is performed.\n#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)\n#else\n#define GTEST_INTERNAL_EMPTY_BASE_CLASS\n#endif\n\ntemplate <typename Base>\nclass NiceMockImpl {\n public:\n  NiceMockImpl() {\n    ::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~NiceMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\ntemplate <typename Base>\nclass NaggyMockImpl {\n public:\n  NaggyMockImpl() {\n    ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~NaggyMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\ntemplate <typename Base>\nclass StrictMockImpl {\n public:\n  StrictMockImpl() {\n    ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~StrictMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\n}  // namespace internal\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock\n    : private internal::NiceMockImpl<MockClass>,\n      public MockClass {\n public:\n  static_assert(!internal::HasStrictnessModifier<MockClass>(),\n                \"Can't apply NiceMock to a class hierarchy that already has a \"\n                \"strictness modifier. See \"\n                \"https://google.github.io/googletest/\"\n                \"gmock_cook_book.html#NiceStrictNaggy\");\n  NiceMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  NiceMock(const NiceMock&) = delete;\n  NiceMock& operator=(const NiceMock&) = delete;\n};\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock\n    : private internal::NaggyMockImpl<MockClass>,\n      public MockClass {\n  static_assert(!internal::HasStrictnessModifier<MockClass>(),\n                \"Can't apply NaggyMock to a class hierarchy that already has a \"\n                \"strictness modifier. See \"\n                \"https://google.github.io/googletest/\"\n                \"gmock_cook_book.html#NiceStrictNaggy\");\n\n public:\n  NaggyMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  NaggyMock(const NaggyMock&) = delete;\n  NaggyMock& operator=(const NaggyMock&) = delete;\n};\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock\n    : private internal::StrictMockImpl<MockClass>,\n      public MockClass {\n public:\n  static_assert(\n      !internal::HasStrictnessModifier<MockClass>(),\n      \"Can't apply StrictMock to a class hierarchy that already has a \"\n      \"strictness modifier. See \"\n      \"https://google.github.io/googletest/\"\n      \"gmock_cook_book.html#NiceStrictNaggy\");\n  StrictMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  StrictMock(const StrictMock&) = delete;\n  StrictMock& operator=(const StrictMock&) = delete;\n};\n\n#undef GTEST_INTERNAL_EMPTY_BASE_CLASS\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock-spec-builders.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements the ON_CALL() and EXPECT_CALL() macros.\n//\n// A user can use the ON_CALL() macro to specify the default action of\n// a mock method.  The syntax is:\n//\n//   ON_CALL(mock_object, Method(argument-matchers))\n//       .With(multi-argument-matcher)\n//       .WillByDefault(action);\n//\n//  where the .With() clause is optional.\n//\n// A user can use the EXPECT_CALL() macro to specify an expectation on\n// a mock method.  The syntax is:\n//\n//   EXPECT_CALL(mock_object, Method(argument-matchers))\n//       .With(multi-argument-matchers)\n//       .Times(cardinality)\n//       .InSequence(sequences)\n//       .After(expectations)\n//       .WillOnce(action)\n//       .WillRepeatedly(action)\n//       .RetiresOnSaturation();\n//\n// where all clauses are optional, and .InSequence()/.After()/\n// .WillOnce() can appear any number of times.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n\n#include <cstdint>\n#include <functional>\n#include <map>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/gmock-actions.h\"\n#include \"gmock/gmock-cardinalities.h\"\n#include \"gmock/gmock-matchers.h\"\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>  // NOLINT\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// An abstract handle of an expectation.\nclass Expectation;\n\n// A set of expectation handles.\nclass ExpectationSet;\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// Implements a mock function.\ntemplate <typename F>\nclass FunctionMocker;\n\n// Base class for expectations.\nclass ExpectationBase;\n\n// Implements an expectation.\ntemplate <typename F>\nclass TypedExpectation;\n\n// Helper class for testing the Expectation class template.\nclass ExpectationTester;\n\n// Helper classes for implementing NiceMock, StrictMock, and NaggyMock.\ntemplate <typename MockClass>\nclass NiceMockImpl;\ntemplate <typename MockClass>\nclass StrictMockImpl;\ntemplate <typename MockClass>\nclass NaggyMockImpl;\n\n// Protects the mock object registry (in class Mock), all function\n// mockers, and all expectations.\n//\n// The reason we don't use more fine-grained protection is: when a\n// mock function Foo() is called, it needs to consult its expectations\n// to see which one should be picked.  If another thread is allowed to\n// call a mock function (either Foo() or a different one) at the same\n// time, it could affect the \"retired\" attributes of Foo()'s\n// expectations when InSequence() is used, and thus affect which\n// expectation gets picked.  Therefore, we sequence all mock function\n// calls to ensure the integrity of the mock objects' states.\nGTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);\n\n// Abstract base class of FunctionMocker.  This is the\n// type-agnostic part of the function mocker interface.  Its pure\n// virtual methods are implemented by FunctionMocker.\nclass GTEST_API_ UntypedFunctionMockerBase {\n public:\n  UntypedFunctionMockerBase();\n  virtual ~UntypedFunctionMockerBase();\n\n  // Verifies that all expectations on this mock function have been\n  // satisfied.  Reports one or more Google Test non-fatal failures\n  // and returns false if not.\n  bool VerifyAndClearExpectationsLocked()\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Clears the ON_CALL()s set on this mock function.\n  virtual void ClearDefaultActionsLocked()\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0;\n\n  // In all of the following Untyped* functions, it's the caller's\n  // responsibility to guarantee the correctness of the arguments'\n  // types.\n\n  // Writes a message that the call is uninteresting (i.e. neither\n  // explicitly expected nor explicitly unexpected) to the given\n  // ostream.\n  virtual void UntypedDescribeUninterestingCall(const void* untyped_args,\n                                                ::std::ostream* os) const\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;\n\n  // Returns the expectation that matches the given function arguments\n  // (or NULL is there's no match); when a match is found,\n  // untyped_action is set to point to the action that should be\n  // performed (or NULL if the action is \"do default\"), and\n  // is_excessive is modified to indicate whether the call exceeds the\n  // expected number.\n  virtual const ExpectationBase* UntypedFindMatchingExpectation(\n      const void* untyped_args, const void** untyped_action, bool* is_excessive,\n      ::std::ostream* what, ::std::ostream* why)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;\n\n  // Prints the given function arguments to the ostream.\n  virtual void UntypedPrintArgs(const void* untyped_args,\n                                ::std::ostream* os) const = 0;\n\n  // Sets the mock object this mock method belongs to, and registers\n  // this information in the global mock registry.  Will be called\n  // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock\n  // method.\n  void RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Sets the mock object this mock method belongs to, and sets the\n  // name of the mock function.  Will be called upon each invocation\n  // of this mock function.\n  void SetOwnerAndName(const void* mock_obj, const char* name)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Returns the mock object this mock method belongs to.  Must be\n  // called after RegisterOwner() or SetOwnerAndName() has been\n  // called.\n  const void* MockObject() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Returns the name of this mock method.  Must be called after\n  // SetOwnerAndName() has been called.\n  const char* Name() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n protected:\n  typedef std::vector<const void*> UntypedOnCallSpecs;\n\n  using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;\n\n  struct UninterestingCallCleanupHandler;\n  struct FailureCleanupHandler;\n\n  // Returns an Expectation object that references and co-owns exp,\n  // which must be an expectation on this mock function.\n  Expectation GetHandleOf(ExpectationBase* exp);\n\n  // Address of the mock object this mock method belongs to.  Only\n  // valid after this mock method has been called or\n  // ON_CALL/EXPECT_CALL has been invoked on it.\n  const void* mock_obj_;  // Protected by g_gmock_mutex.\n\n  // Name of the function being mocked.  Only valid after this mock\n  // method has been called.\n  const char* name_;  // Protected by g_gmock_mutex.\n\n  // All default action specs for this function mocker.\n  UntypedOnCallSpecs untyped_on_call_specs_;\n\n  // All expectations for this function mocker.\n  //\n  // It's undefined behavior to interleave expectations (EXPECT_CALLs\n  // or ON_CALLs) and mock function calls.  Also, the order of\n  // expectations is important.  Therefore it's a logic race condition\n  // to read/write untyped_expectations_ concurrently.  In order for\n  // tools like tsan to catch concurrent read/write accesses to\n  // untyped_expectations, we deliberately leave accesses to it\n  // unprotected.\n  UntypedExpectations untyped_expectations_;\n};  // class UntypedFunctionMockerBase\n\n// Untyped base class for OnCallSpec<F>.\nclass UntypedOnCallSpecBase {\n public:\n  // The arguments are the location of the ON_CALL() statement.\n  UntypedOnCallSpecBase(const char* a_file, int a_line)\n      : file_(a_file), line_(a_line), last_clause_(kNone) {}\n\n  // Where in the source file was the default action spec defined?\n  const char* file() const { return file_; }\n  int line() const { return line_; }\n\n protected:\n  // Gives each clause in the ON_CALL() statement a name.\n  enum Clause {\n    // Do not change the order of the enum members!  The run-time\n    // syntax checking relies on it.\n    kNone,\n    kWith,\n    kWillByDefault\n  };\n\n  // Asserts that the ON_CALL() statement has a certain property.\n  void AssertSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Assert(property, file_, line_, failure_message);\n  }\n\n  // Expects that the ON_CALL() statement has a certain property.\n  void ExpectSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Expect(property, file_, line_, failure_message);\n  }\n\n  const char* file_;\n  int line_;\n\n  // The last clause in the ON_CALL() statement as seen so far.\n  // Initially kNone and changes as the statement is parsed.\n  Clause last_clause_;\n};  // class UntypedOnCallSpecBase\n\n// This template class implements an ON_CALL spec.\ntemplate <typename F>\nclass OnCallSpec : public UntypedOnCallSpecBase {\n public:\n  typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n\n  // Constructs an OnCallSpec object from the information inside\n  // the parenthesis of an ON_CALL() statement.\n  OnCallSpec(const char* a_file, int a_line,\n             const ArgumentMatcherTuple& matchers)\n      : UntypedOnCallSpecBase(a_file, a_line),\n        matchers_(matchers),\n        // By default, extra_matcher_ should match anything.  However,\n        // we cannot initialize it with _ as that causes ambiguity between\n        // Matcher's copy and move constructor for some argument types.\n        extra_matcher_(A<const ArgumentTuple&>()) {}\n\n  // Implements the .With() clause.\n  OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {\n    // Makes sure this is called at most once.\n    ExpectSpecProperty(last_clause_ < kWith,\n                       \".With() cannot appear \"\n                       \"more than once in an ON_CALL().\");\n    last_clause_ = kWith;\n\n    extra_matcher_ = m;\n    return *this;\n  }\n\n  // Implements the .WillByDefault() clause.\n  OnCallSpec& WillByDefault(const Action<F>& action) {\n    ExpectSpecProperty(last_clause_ < kWillByDefault,\n                       \".WillByDefault() must appear \"\n                       \"exactly once in an ON_CALL().\");\n    last_clause_ = kWillByDefault;\n\n    ExpectSpecProperty(!action.IsDoDefault(),\n                       \"DoDefault() cannot be used in ON_CALL().\");\n    action_ = action;\n    return *this;\n  }\n\n  // Returns true if and only if the given arguments match the matchers.\n  bool Matches(const ArgumentTuple& args) const {\n    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);\n  }\n\n  // Returns the action specified by the user.\n  const Action<F>& GetAction() const {\n    AssertSpecProperty(last_clause_ == kWillByDefault,\n                       \".WillByDefault() must appear exactly \"\n                       \"once in an ON_CALL().\");\n    return action_;\n  }\n\n private:\n  // The information in statement\n  //\n  //   ON_CALL(mock_object, Method(matchers))\n  //       .With(multi-argument-matcher)\n  //       .WillByDefault(action);\n  //\n  // is recorded in the data members like this:\n  //\n  //   source file that contains the statement => file_\n  //   line number of the statement            => line_\n  //   matchers                                => matchers_\n  //   multi-argument-matcher                  => extra_matcher_\n  //   action                                  => action_\n  ArgumentMatcherTuple matchers_;\n  Matcher<const ArgumentTuple&> extra_matcher_;\n  Action<F> action_;\n};  // class OnCallSpec\n\n// Possible reactions on uninteresting calls.\nenum CallReaction {\n  kAllow,\n  kWarn,\n  kFail,\n};\n\n}  // namespace internal\n\n// Utilities for manipulating mock objects.\nclass GTEST_API_ Mock {\n public:\n  // The following public methods can be called concurrently.\n\n  // Tells Google Mock to ignore mock_obj when checking for leaked\n  // mock objects.\n  static void AllowLeak(const void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies and clears all expectations on the given mock object.\n  // If the expectations aren't satisfied, generates one or more\n  // Google Test non-fatal failures and returns false.\n  static bool VerifyAndClearExpectations(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies all expectations on the given mock object and clears its\n  // default actions and expectations.  Returns true if and only if the\n  // verification was successful.\n  static bool VerifyAndClear(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Returns whether the mock was created as a naggy mock (default)\n  static bool IsNaggy(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n  // Returns whether the mock was created as a nice mock\n  static bool IsNice(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n  // Returns whether the mock was created as a strict mock\n  static bool IsStrict(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n private:\n  friend class internal::UntypedFunctionMockerBase;\n\n  // Needed for a function mocker to register itself (so that we know\n  // how to clear a mock object).\n  template <typename F>\n  friend class internal::FunctionMocker;\n\n  template <typename MockClass>\n  friend class internal::NiceMockImpl;\n  template <typename MockClass>\n  friend class internal::NaggyMockImpl;\n  template <typename MockClass>\n  friend class internal::StrictMockImpl;\n\n  // Tells Google Mock to allow uninteresting calls on the given mock\n  // object.\n  static void AllowUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock to warn the user about uninteresting calls on\n  // the given mock object.\n  static void WarnUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock to fail uninteresting calls on the given mock\n  // object.\n  static void FailUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock the given mock object is being destroyed and\n  // its entry in the call-reaction table should be removed.\n  static void UnregisterCallReaction(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Returns the reaction Google Mock will have on uninteresting calls\n  // made on the given mock object.\n  static internal::CallReaction GetReactionOnUninterestingCalls(\n      const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies that all expectations on the given mock object have been\n  // satisfied.  Reports one or more Google Test non-fatal failures\n  // and returns false if not.\n  static bool VerifyAndClearExpectationsLocked(void* mock_obj)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n\n  // Clears all ON_CALL()s set on the given mock object.\n  static void ClearDefaultActionsLocked(void* mock_obj)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n\n  // Registers a mock object and a mock method it owns.\n  static void Register(const void* mock_obj,\n                       internal::UntypedFunctionMockerBase* mocker)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock where in the source code mock_obj is used in an\n  // ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this\n  // information helps the user identify which object it is.\n  static void RegisterUseByOnCallOrExpectCall(const void* mock_obj,\n                                              const char* file, int line)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Unregisters a mock method; removes the owning mock object from\n  // the registry when the last mock method associated with it has\n  // been unregistered.  This is called only in the destructor of\n  // FunctionMocker.\n  static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n};  // class Mock\n\n// An abstract handle of an expectation.  Useful in the .After()\n// clause of EXPECT_CALL() for setting the (partial) order of\n// expectations.  The syntax:\n//\n//   Expectation e1 = EXPECT_CALL(...)...;\n//   EXPECT_CALL(...).After(e1)...;\n//\n// sets two expectations where the latter can only be matched after\n// the former has been satisfied.\n//\n// Notes:\n//   - This class is copyable and has value semantics.\n//   - Constness is shallow: a const Expectation object itself cannot\n//     be modified, but the mutable methods of the ExpectationBase\n//     object it references can be called via expectation_base().\n\nclass GTEST_API_ Expectation {\n public:\n  // Constructs a null object that doesn't reference any expectation.\n  Expectation();\n  Expectation(Expectation&&) = default;\n  Expectation(const Expectation&) = default;\n  Expectation& operator=(Expectation&&) = default;\n  Expectation& operator=(const Expectation&) = default;\n  ~Expectation();\n\n  // This single-argument ctor must not be explicit, in order to support the\n  //   Expectation e = EXPECT_CALL(...);\n  // syntax.\n  //\n  // A TypedExpectation object stores its pre-requisites as\n  // Expectation objects, and needs to call the non-const Retire()\n  // method on the ExpectationBase objects they reference.  Therefore\n  // Expectation must receive a *non-const* reference to the\n  // ExpectationBase object.\n  Expectation(internal::ExpectationBase& exp);  // NOLINT\n\n  // The compiler-generated copy ctor and operator= work exactly as\n  // intended, so we don't need to define our own.\n\n  // Returns true if and only if rhs references the same expectation as this\n  // object does.\n  bool operator==(const Expectation& rhs) const {\n    return expectation_base_ == rhs.expectation_base_;\n  }\n\n  bool operator!=(const Expectation& rhs) const { return !(*this == rhs); }\n\n private:\n  friend class ExpectationSet;\n  friend class Sequence;\n  friend class ::testing::internal::ExpectationBase;\n  friend class ::testing::internal::UntypedFunctionMockerBase;\n\n  template <typename F>\n  friend class ::testing::internal::FunctionMocker;\n\n  template <typename F>\n  friend class ::testing::internal::TypedExpectation;\n\n  // This comparator is needed for putting Expectation objects into a set.\n  class Less {\n   public:\n    bool operator()(const Expectation& lhs, const Expectation& rhs) const {\n      return lhs.expectation_base_.get() < rhs.expectation_base_.get();\n    }\n  };\n\n  typedef ::std::set<Expectation, Less> Set;\n\n  Expectation(\n      const std::shared_ptr<internal::ExpectationBase>& expectation_base);\n\n  // Returns the expectation this object references.\n  const std::shared_ptr<internal::ExpectationBase>& expectation_base() const {\n    return expectation_base_;\n  }\n\n  // A shared_ptr that co-owns the expectation this handle references.\n  std::shared_ptr<internal::ExpectationBase> expectation_base_;\n};\n\n// A set of expectation handles.  Useful in the .After() clause of\n// EXPECT_CALL() for setting the (partial) order of expectations.  The\n// syntax:\n//\n//   ExpectationSet es;\n//   es += EXPECT_CALL(...)...;\n//   es += EXPECT_CALL(...)...;\n//   EXPECT_CALL(...).After(es)...;\n//\n// sets three expectations where the last one can only be matched\n// after the first two have both been satisfied.\n//\n// This class is copyable and has value semantics.\nclass ExpectationSet {\n public:\n  // A bidirectional iterator that can read a const element in the set.\n  typedef Expectation::Set::const_iterator const_iterator;\n\n  // An object stored in the set.  This is an alias of Expectation.\n  typedef Expectation::Set::value_type value_type;\n\n  // Constructs an empty set.\n  ExpectationSet() = default;\n\n  // This single-argument ctor must not be explicit, in order to support the\n  //   ExpectationSet es = EXPECT_CALL(...);\n  // syntax.\n  ExpectationSet(internal::ExpectationBase& exp) {  // NOLINT\n    *this += Expectation(exp);\n  }\n\n  // This single-argument ctor implements implicit conversion from\n  // Expectation and thus must not be explicit.  This allows either an\n  // Expectation or an ExpectationSet to be used in .After().\n  ExpectationSet(const Expectation& e) {  // NOLINT\n    *this += e;\n  }\n\n  // The compiler-generator ctor and operator= works exactly as\n  // intended, so we don't need to define our own.\n\n  // Returns true if and only if rhs contains the same set of Expectation\n  // objects as this does.\n  bool operator==(const ExpectationSet& rhs) const {\n    return expectations_ == rhs.expectations_;\n  }\n\n  bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); }\n\n  // Implements the syntax\n  //   expectation_set += EXPECT_CALL(...);\n  ExpectationSet& operator+=(const Expectation& e) {\n    expectations_.insert(e);\n    return *this;\n  }\n\n  int size() const { return static_cast<int>(expectations_.size()); }\n\n  const_iterator begin() const { return expectations_.begin(); }\n  const_iterator end() const { return expectations_.end(); }\n\n private:\n  Expectation::Set expectations_;\n};\n\n// Sequence objects are used by a user to specify the relative order\n// in which the expectations should match.  They are copyable (we rely\n// on the compiler-defined copy constructor and assignment operator).\nclass GTEST_API_ Sequence {\n public:\n  // Constructs an empty sequence.\n  Sequence() : last_expectation_(new Expectation) {}\n\n  // Adds an expectation to this sequence.  The caller must ensure\n  // that no other thread is accessing this Sequence object.\n  void AddExpectation(const Expectation& expectation) const;\n\n private:\n  // The last expectation in this sequence.\n  std::shared_ptr<Expectation> last_expectation_;\n};  // class Sequence\n\n// An object of this type causes all EXPECT_CALL() statements\n// encountered in its scope to be put in an anonymous sequence.  The\n// work is done in the constructor and destructor.  You should only\n// create an InSequence object on the stack.\n//\n// The sole purpose for this class is to support easy definition of\n// sequential expectations, e.g.\n//\n//   {\n//     InSequence dummy;  // The name of the object doesn't matter.\n//\n//     // The following expectations must match in the order they appear.\n//     EXPECT_CALL(a, Bar())...;\n//     EXPECT_CALL(a, Baz())...;\n//     ...\n//     EXPECT_CALL(b, Xyz())...;\n//   }\n//\n// You can create InSequence objects in multiple threads, as long as\n// they are used to affect different mock objects.  The idea is that\n// each thread can create and set up its own mocks as if it's the only\n// thread.  However, for clarity of your tests we recommend you to set\n// up mocks in the main thread unless you have a good reason not to do\n// so.\nclass GTEST_API_ InSequence {\n public:\n  InSequence();\n  ~InSequence();\n\n private:\n  bool sequence_created_;\n\n  InSequence(const InSequence&) = delete;\n  InSequence& operator=(const InSequence&) = delete;\n};\n\nnamespace internal {\n\n// Points to the implicit sequence introduced by a living InSequence\n// object (if any) in the current thread or NULL.\nGTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;\n\n// Base class for implementing expectations.\n//\n// There are two reasons for having a type-agnostic base class for\n// Expectation:\n//\n//   1. We need to store collections of expectations of different\n//   types (e.g. all pre-requisites of a particular expectation, all\n//   expectations in a sequence).  Therefore these expectation objects\n//   must share a common base class.\n//\n//   2. We can avoid binary code bloat by moving methods not depending\n//   on the template argument of Expectation to the base class.\n//\n// This class is internal and mustn't be used by user code directly.\nclass GTEST_API_ ExpectationBase {\n public:\n  // source_text is the EXPECT_CALL(...) source that created this Expectation.\n  ExpectationBase(const char* file, int line, const std::string& source_text);\n\n  virtual ~ExpectationBase();\n\n  // Where in the source file was the expectation spec defined?\n  const char* file() const { return file_; }\n  int line() const { return line_; }\n  const char* source_text() const { return source_text_.c_str(); }\n  // Returns the cardinality specified in the expectation spec.\n  const Cardinality& cardinality() const { return cardinality_; }\n\n  // Describes the source file location of this expectation.\n  void DescribeLocationTo(::std::ostream* os) const {\n    *os << FormatFileLocation(file(), line()) << \" \";\n  }\n\n  // Describes how many times a function call matching this\n  // expectation has occurred.\n  void DescribeCallCountTo(::std::ostream* os) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // If this mock method has an extra matcher (i.e. .With(matcher)),\n  // describes it to the ostream.\n  virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;\n\n  // Do not rely on this for correctness.\n  // This is only for making human-readable test output easier to understand.\n  void UntypedDescription(std::string description) {\n    description_ = std::move(description);\n  }\n\n protected:\n  friend class ::testing::Expectation;\n  friend class UntypedFunctionMockerBase;\n\n  enum Clause {\n    // Don't change the order of the enum members!\n    kNone,\n    kWith,\n    kTimes,\n    kInSequence,\n    kAfter,\n    kWillOnce,\n    kWillRepeatedly,\n    kRetiresOnSaturation\n  };\n\n  typedef std::vector<const void*> UntypedActions;\n\n  // Returns an Expectation object that references and co-owns this\n  // expectation.\n  virtual Expectation GetHandle() = 0;\n\n  // Asserts that the EXPECT_CALL() statement has the given property.\n  void AssertSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Assert(property, file_, line_, failure_message);\n  }\n\n  // Expects that the EXPECT_CALL() statement has the given property.\n  void ExpectSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Expect(property, file_, line_, failure_message);\n  }\n\n  // Explicitly specifies the cardinality of this expectation.  Used\n  // by the subclasses to implement the .Times() clause.\n  void SpecifyCardinality(const Cardinality& cardinality);\n\n  // Returns true if and only if the user specified the cardinality\n  // explicitly using a .Times().\n  bool cardinality_specified() const { return cardinality_specified_; }\n\n  // Sets the cardinality of this expectation spec.\n  void set_cardinality(const Cardinality& a_cardinality) {\n    cardinality_ = a_cardinality;\n  }\n\n  // The following group of methods should only be called after the\n  // EXPECT_CALL() statement, and only when g_gmock_mutex is held by\n  // the current thread.\n\n  // Retires all pre-requisites of this expectation.\n  void RetireAllPreRequisites() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Returns true if and only if this expectation is retired.\n  bool is_retired() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return retired_;\n  }\n\n  // Retires this expectation.\n  void Retire() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    retired_ = true;\n  }\n\n  // Returns a human-readable description of this expectation.\n  // Do not rely on this for correctness. It is only for human readability.\n  const std::string& GetDescription() const { return description_; }\n\n  // Returns true if and only if this expectation is satisfied.\n  bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsSatisfiedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if this expectation is saturated.\n  bool IsSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsSaturatedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if this expectation is over-saturated.\n  bool IsOverSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsOverSaturatedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if all pre-requisites of this expectation are\n  // satisfied.\n  bool AllPrerequisitesAreSatisfied() const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Adds unsatisfied pre-requisites of this expectation to 'result'.\n  void FindUnsatisfiedPrerequisites(ExpectationSet* result) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Returns the number this expectation has been invoked.\n  int call_count() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return call_count_;\n  }\n\n  // Increments the number this expectation has been invoked.\n  void IncrementCallCount() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    call_count_++;\n  }\n\n  // Checks the action count (i.e. the number of WillOnce() and\n  // WillRepeatedly() clauses) against the cardinality if this hasn't\n  // been done before.  Prints a warning if there are too many or too\n  // few actions.\n  void CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n  friend class ::testing::Sequence;\n  friend class ::testing::internal::ExpectationTester;\n\n  template <typename Function>\n  friend class TypedExpectation;\n\n  // Implements the .Times() clause.\n  void UntypedTimes(const Cardinality& a_cardinality);\n\n  // This group of fields are part of the spec and won't change after\n  // an EXPECT_CALL() statement finishes.\n  const char* file_;               // The file that contains the expectation.\n  int line_;                       // The line number of the expectation.\n  const std::string source_text_;  // The EXPECT_CALL(...) source text.\n  std::string description_;        // User-readable name for the expectation.\n  // True if and only if the cardinality is specified explicitly.\n  bool cardinality_specified_;\n  Cardinality cardinality_;  // The cardinality of the expectation.\n  // The immediate pre-requisites (i.e. expectations that must be\n  // satisfied before this expectation can be matched) of this\n  // expectation.  We use std::shared_ptr in the set because we want an\n  // Expectation object to be co-owned by its FunctionMocker and its\n  // successors.  This allows multiple mock objects to be deleted at\n  // different times.\n  ExpectationSet immediate_prerequisites_;\n\n  // This group of fields are the current state of the expectation,\n  // and can change as the mock function is called.\n  int call_count_;  // How many times this expectation has been invoked.\n  bool retired_;    // True if and only if this expectation has retired.\n  UntypedActions untyped_actions_;\n  bool extra_matcher_specified_;\n  bool repeated_action_specified_;  // True if a WillRepeatedly() was specified.\n  bool retires_on_saturation_;\n  Clause last_clause_;\n  mutable bool action_count_checked_;  // Under mutex_.\n  mutable Mutex mutex_;                // Protects action_count_checked_.\n};                                     // class ExpectationBase\n\ntemplate <typename F>\nclass TypedExpectation;\n\n// Implements an expectation for the given function type.\ntemplate <typename R, typename... Args>\nclass TypedExpectation<R(Args...)> : public ExpectationBase {\n private:\n  using F = R(Args...);\n\n public:\n  typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n  typedef typename Function<F>::Result Result;\n\n  TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,\n                   const std::string& a_source_text,\n                   const ArgumentMatcherTuple& m)\n      : ExpectationBase(a_file, a_line, a_source_text),\n        owner_(owner),\n        matchers_(m),\n        // By default, extra_matcher_ should match anything.  However,\n        // we cannot initialize it with _ as that causes ambiguity between\n        // Matcher's copy and move constructor for some argument types.\n        extra_matcher_(A<const ArgumentTuple&>()),\n        repeated_action_(DoDefault()) {}\n\n  ~TypedExpectation() override {\n    // Check the validity of the action count if it hasn't been done\n    // yet (for example, if the expectation was never used).\n    CheckActionCountIfNotDone();\n    for (UntypedActions::const_iterator it = untyped_actions_.begin();\n         it != untyped_actions_.end(); ++it) {\n      delete static_cast<const Action<F>*>(*it);\n    }\n  }\n\n  // Implements the .With() clause.\n  TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) {\n    if (last_clause_ == kWith) {\n      ExpectSpecProperty(false,\n                         \".With() cannot appear \"\n                         \"more than once in an EXPECT_CALL().\");\n    } else {\n      ExpectSpecProperty(last_clause_ < kWith,\n                         \".With() must be the first \"\n                         \"clause in an EXPECT_CALL().\");\n    }\n    last_clause_ = kWith;\n\n    extra_matcher_ = m;\n    extra_matcher_specified_ = true;\n    return *this;\n  }\n\n  // Do not rely on this for correctness.\n  // This is only for making human-readable test output easier to understand.\n  TypedExpectation& Description(std::string name) {\n    ExpectationBase::UntypedDescription(std::move(name));\n    return *this;\n  }\n\n  // Implements the .Times() clause.\n  TypedExpectation& Times(const Cardinality& a_cardinality) {\n    ExpectationBase::UntypedTimes(a_cardinality);\n    return *this;\n  }\n\n  // Implements the .Times() clause.\n  TypedExpectation& Times(int n) { return Times(Exactly(n)); }\n\n  // Implements the .InSequence() clause.\n  TypedExpectation& InSequence(const Sequence& s) {\n    ExpectSpecProperty(last_clause_ <= kInSequence,\n                       \".InSequence() cannot appear after .After(),\"\n                       \" .WillOnce(), .WillRepeatedly(), or \"\n                       \".RetiresOnSaturation().\");\n    last_clause_ = kInSequence;\n\n    s.AddExpectation(GetHandle());\n    return *this;\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) {\n    return InSequence(s1).InSequence(s2);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3) {\n    return InSequence(s1, s2).InSequence(s3);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3, const Sequence& s4) {\n    return InSequence(s1, s2, s3).InSequence(s4);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3, const Sequence& s4,\n                               const Sequence& s5) {\n    return InSequence(s1, s2, s3, s4).InSequence(s5);\n  }\n\n  // Implements that .After() clause.\n  TypedExpectation& After(const ExpectationSet& s) {\n    ExpectSpecProperty(last_clause_ <= kAfter,\n                       \".After() cannot appear after .WillOnce(),\"\n                       \" .WillRepeatedly(), or \"\n                       \".RetiresOnSaturation().\");\n    last_clause_ = kAfter;\n\n    for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) {\n      immediate_prerequisites_ += *it;\n    }\n    return *this;\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) {\n    return After(s1).After(s2);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3) {\n    return After(s1, s2).After(s3);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3, const ExpectationSet& s4) {\n    return After(s1, s2, s3).After(s4);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3, const ExpectationSet& s4,\n                          const ExpectationSet& s5) {\n    return After(s1, s2, s3, s4).After(s5);\n  }\n\n  // Preferred, type-safe overload: consume anything that can be directly\n  // converted to a OnceAction, except for Action<F> objects themselves.\n  TypedExpectation& WillOnce(OnceAction<F> once_action) {\n    // Call the overload below, smuggling the OnceAction as a copyable callable.\n    // We know this is safe because a WillOnce action will not be called more\n    // than once.\n    return WillOnce(Action<F>(ActionAdaptor{\n        std::make_shared<OnceAction<F>>(std::move(once_action)),\n    }));\n  }\n\n  // Fallback overload: accept Action<F> objects and those actions that define\n  // `operator Action<F>` but not `operator OnceAction<F>`.\n  //\n  // This is templated in order to cause the overload above to be preferred\n  // when the input is convertible to either type.\n  template <int&... ExplicitArgumentBarrier, typename = void>\n  TypedExpectation& WillOnce(Action<F> action) {\n    ExpectSpecProperty(last_clause_ <= kWillOnce,\n                       \".WillOnce() cannot appear after \"\n                       \".WillRepeatedly() or .RetiresOnSaturation().\");\n    last_clause_ = kWillOnce;\n\n    untyped_actions_.push_back(new Action<F>(std::move(action)));\n\n    if (!cardinality_specified()) {\n      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));\n    }\n    return *this;\n  }\n\n  // Implements the .WillRepeatedly() clause.\n  TypedExpectation& WillRepeatedly(const Action<F>& action) {\n    if (last_clause_ == kWillRepeatedly) {\n      ExpectSpecProperty(false,\n                         \".WillRepeatedly() cannot appear \"\n                         \"more than once in an EXPECT_CALL().\");\n    } else {\n      ExpectSpecProperty(last_clause_ < kWillRepeatedly,\n                         \".WillRepeatedly() cannot appear \"\n                         \"after .RetiresOnSaturation().\");\n    }\n    last_clause_ = kWillRepeatedly;\n    repeated_action_specified_ = true;\n\n    repeated_action_ = action;\n    if (!cardinality_specified()) {\n      set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size())));\n    }\n\n    // Now that no more action clauses can be specified, we check\n    // whether their count makes sense.\n    CheckActionCountIfNotDone();\n    return *this;\n  }\n\n  // Implements the .RetiresOnSaturation() clause.\n  TypedExpectation& RetiresOnSaturation() {\n    ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,\n                       \".RetiresOnSaturation() cannot appear \"\n                       \"more than once.\");\n    last_clause_ = kRetiresOnSaturation;\n    retires_on_saturation_ = true;\n\n    // Now that no more action clauses can be specified, we check\n    // whether their count makes sense.\n    CheckActionCountIfNotDone();\n    return *this;\n  }\n\n  // Returns the matchers for the arguments as specified inside the\n  // EXPECT_CALL() macro.\n  const ArgumentMatcherTuple& matchers() const { return matchers_; }\n\n  // Returns the matcher specified by the .With() clause.\n  const Matcher<const ArgumentTuple&>& extra_matcher() const {\n    return extra_matcher_;\n  }\n\n  // Returns the action specified by the .WillRepeatedly() clause.\n  const Action<F>& repeated_action() const { return repeated_action_; }\n\n  // If this mock method has an extra matcher (i.e. .With(matcher)),\n  // describes it to the ostream.\n  void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {\n    if (extra_matcher_specified_) {\n      *os << \"    Expected args: \";\n      extra_matcher_.DescribeTo(os);\n      *os << \"\\n\";\n    }\n  }\n\n private:\n  template <typename Function>\n  friend class FunctionMocker;\n\n  // An adaptor that turns a OneAction<F> into something compatible with\n  // Action<F>. Must be called at most once.\n  struct ActionAdaptor {\n    std::shared_ptr<OnceAction<R(Args...)>> once_action;\n\n    R operator()(Args&&... args) const {\n      return std::move(*once_action).Call(std::forward<Args>(args)...);\n    }\n  };\n\n  // Returns an Expectation object that references and co-owns this\n  // expectation.\n  Expectation GetHandle() override { return owner_->GetHandleOf(this); }\n\n  // The following methods will be called only after the EXPECT_CALL()\n  // statement finishes and when the current thread holds\n  // g_gmock_mutex.\n\n  // Returns true if and only if this expectation matches the given arguments.\n  bool Matches(const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);\n  }\n\n  // Returns true if and only if this expectation should handle the given\n  // arguments.\n  bool ShouldHandleArguments(const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    // In case the action count wasn't checked when the expectation\n    // was defined (e.g. if this expectation has no WillRepeatedly()\n    // or RetiresOnSaturation() clause), we check it when the\n    // expectation is used for the first time.\n    CheckActionCountIfNotDone();\n    return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args);\n  }\n\n  // Describes the result of matching the arguments against this\n  // expectation to the given ostream.\n  void ExplainMatchResultTo(const ArgumentTuple& args, ::std::ostream* os) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    if (is_retired()) {\n      *os << \"         Expected: the expectation is active\\n\"\n          << \"           Actual: it is retired\\n\";\n    } else if (!Matches(args)) {\n      if (!TupleMatches(matchers_, args)) {\n        ExplainMatchFailureTupleTo(matchers_, args, os);\n      }\n      StringMatchResultListener listener;\n      if (!extra_matcher_.MatchAndExplain(args, &listener)) {\n        *os << \"    Expected args: \";\n        extra_matcher_.DescribeTo(os);\n        *os << \"\\n           Actual: don't match\";\n\n        internal::PrintIfNotEmpty(listener.str(), os);\n        *os << \"\\n\";\n      }\n    } else if (!AllPrerequisitesAreSatisfied()) {\n      *os << \"         Expected: all pre-requisites are satisfied\\n\"\n          << \"           Actual: the following immediate pre-requisites \"\n          << \"are not satisfied:\\n\";\n      ExpectationSet unsatisfied_prereqs;\n      FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);\n      int i = 0;\n      for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();\n           it != unsatisfied_prereqs.end(); ++it) {\n        it->expectation_base()->DescribeLocationTo(os);\n        *os << \"pre-requisite #\" << i++ << \"\\n\";\n      }\n      *os << \"                   (end of pre-requisites)\\n\";\n    } else {\n      // This line is here just for completeness' sake.  It will never\n      // be executed as currently the ExplainMatchResultTo() function\n      // is called only when the mock function call does NOT match the\n      // expectation.\n      *os << \"The call matches the expectation.\\n\";\n    }\n  }\n\n  // Returns the action that should be taken for the current invocation.\n  const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,\n                                    const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const int count = call_count();\n    Assert(count >= 1, __FILE__, __LINE__,\n           \"call_count() is <= 0 when GetCurrentAction() is \"\n           \"called - this should never happen.\");\n\n    const int action_count = static_cast<int>(untyped_actions_.size());\n    if (action_count > 0 && !repeated_action_specified_ &&\n        count > action_count) {\n      // If there is at least one WillOnce() and no WillRepeatedly(),\n      // we warn the user when the WillOnce() clauses ran out.\n      ::std::stringstream ss;\n      DescribeLocationTo(&ss);\n      ss << \"Actions ran out in \" << source_text() << \"...\\n\"\n         << \"Called \" << count << \" times, but only \" << action_count\n         << \" WillOnce()\" << (action_count == 1 ? \" is\" : \"s are\")\n         << \" specified - \";\n      mocker->DescribeDefaultActionTo(args, &ss);\n      Log(kWarning, ss.str(), 1);\n    }\n\n    return count <= action_count\n               ? *static_cast<const Action<F>*>(\n                     untyped_actions_[static_cast<size_t>(count - 1)])\n               : repeated_action();\n  }\n\n  // Given the arguments of a mock function call, if the call will\n  // over-saturate this expectation, returns the default action;\n  // otherwise, returns the next action in this expectation.  Also\n  // describes *what* happened to 'what', and explains *why* Google\n  // Mock does it to 'why'.  This method is not const as it calls\n  // IncrementCallCount().  A return value of NULL means the default\n  // action.\n  const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,\n                                         const ArgumentTuple& args,\n                                         ::std::ostream* what,\n                                         ::std::ostream* why)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const ::std::string& expectation_description = GetDescription();\n    if (IsSaturated()) {\n      // We have an excessive call.\n      IncrementCallCount();\n      *what << \"Mock function \";\n      if (!expectation_description.empty()) {\n        *what << \"\\\"\" << expectation_description << \"\\\" \";\n      }\n      *what << \"called more times than expected - \";\n      mocker->DescribeDefaultActionTo(args, what);\n      DescribeCallCountTo(why);\n\n      return nullptr;\n    }\n\n    IncrementCallCount();\n    RetireAllPreRequisites();\n\n    if (retires_on_saturation_ && IsSaturated()) {\n      Retire();\n    }\n\n    // Must be done after IncrementCount()!\n    *what << \"Mock function \";\n    if (!expectation_description.empty()) {\n      *what << \"\\\"\" << expectation_description << \"\\\" \";\n    }\n    *what << \"call matches \" << source_text() << \"...\\n\";\n    return &(GetCurrentAction(mocker, args));\n  }\n\n  // All the fields below won't change once the EXPECT_CALL()\n  // statement finishes.\n  FunctionMocker<F>* const owner_;\n  ArgumentMatcherTuple matchers_;\n  Matcher<const ArgumentTuple&> extra_matcher_;\n  Action<F> repeated_action_;\n\n  TypedExpectation(const TypedExpectation&) = delete;\n  TypedExpectation& operator=(const TypedExpectation&) = delete;\n};  // class TypedExpectation\n\n// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for\n// specifying the default behavior of, or expectation on, a mock\n// function.\n\n// Note: class MockSpec really belongs to the ::testing namespace.\n// However if we define it in ::testing, MSVC will complain when\n// classes in ::testing::internal declare it as a friend class\n// template.  To workaround this compiler bug, we define MockSpec in\n// ::testing::internal and import it into ::testing.\n\n// Logs a message including file and line number information.\nGTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,\n                                const char* file, int line,\n                                const std::string& message);\n\ntemplate <typename F>\nclass MockSpec {\n public:\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n  typedef\n      typename internal::Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n\n  // Constructs a MockSpec object, given the function mocker object\n  // that the spec is associated with.\n  MockSpec(internal::FunctionMocker<F>* function_mocker,\n           const ArgumentMatcherTuple& matchers)\n      : function_mocker_(function_mocker), matchers_(matchers) {}\n\n  // Adds a new default action spec to the function mocker and returns\n  // the newly created spec.\n  internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,\n                                                      int line, const char* obj,\n                                                      const char* call) {\n    LogWithLocation(internal::kInfo, file, line,\n                    std::string(\"ON_CALL(\") + obj + \", \" + call + \") invoked\");\n    return function_mocker_->AddNewOnCallSpec(file, line, matchers_);\n  }\n\n  // Adds a new expectation spec to the function mocker and returns\n  // the newly created spec.\n  internal::TypedExpectation<F>& InternalExpectedAt(const char* file, int line,\n                                                    const char* obj,\n                                                    const char* call) {\n    const std::string source_text(std::string(\"EXPECT_CALL(\") + obj + \", \" +\n                                  call + \")\");\n    LogWithLocation(internal::kInfo, file, line, source_text + \" invoked\");\n    return function_mocker_->AddNewExpectation(file, line, source_text,\n                                               matchers_);\n  }\n\n  // This operator overload is used to swallow the superfluous parameter list\n  // introduced by the ON/EXPECT_CALL macros. See the macro comments for more\n  // explanation.\n  MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {\n    return *this;\n  }\n\n private:\n  template <typename Function>\n  friend class internal::FunctionMocker;\n\n  // The function mocker that owns this spec.\n  internal::FunctionMocker<F>* const function_mocker_;\n  // The argument matchers specified in the spec.\n  ArgumentMatcherTuple matchers_;\n};  // class MockSpec\n\n// Wrapper type for generically holding an ordinary value or lvalue reference.\n// If T is not a reference type, it must be copyable or movable.\n// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless\n// T is a move-only value type (which means that it will always be copyable\n// if the current platform does not support move semantics).\n//\n// The primary template defines handling for values, but function header\n// comments describe the contract for the whole template (including\n// specializations).\ntemplate <typename T>\nclass ReferenceOrValueWrapper {\n public:\n  // Constructs a wrapper from the given value/reference.\n  explicit ReferenceOrValueWrapper(T value) : value_(std::move(value)) {}\n\n  // Unwraps and returns the underlying value/reference, exactly as\n  // originally passed. The behavior of calling this more than once on\n  // the same object is unspecified.\n  T Unwrap() { return std::move(value_); }\n\n  // Provides nondestructive access to the underlying value/reference.\n  // Always returns a const reference (more precisely,\n  // const std::add_lvalue_reference<T>::type). The behavior of calling this\n  // after calling Unwrap on the same object is unspecified.\n  const T& Peek() const { return value_; }\n\n private:\n  T value_;\n};\n\n// Specialization for lvalue reference types. See primary template\n// for documentation.\ntemplate <typename T>\nclass ReferenceOrValueWrapper<T&> {\n public:\n  // Workaround for debatable pass-by-reference lint warning (c-library-team\n  // policy precludes NOLINT in this context)\n  typedef T& reference;\n  explicit ReferenceOrValueWrapper(reference ref) : value_ptr_(&ref) {}\n  T& Unwrap() { return *value_ptr_; }\n  const T& Peek() const { return *value_ptr_; }\n\n private:\n  T* value_ptr_;\n};\n\n// Prints the held value as an action's result to os.\ntemplate <typename T>\nvoid PrintAsActionResult(const T& result, std::ostream& os) {\n  os << \"\\n          Returns: \";\n  // T may be a reference type, so we don't use UniversalPrint().\n  UniversalPrinter<T>::Print(result, &os);\n}\n\n// Reports an uninteresting call (whose description is in msg) in the\n// manner specified by 'reaction'.\nGTEST_API_ void ReportUninterestingCall(CallReaction reaction,\n                                        const std::string& msg);\n\n// A generic RAII type that runs a user-provided function in its destructor.\nclass Cleanup final {\n public:\n  explicit Cleanup(std::function<void()> f) : f_(std::move(f)) {}\n  ~Cleanup() { f_(); }\n\n private:\n  std::function<void()> f_;\n};\n\nstruct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {\n  CallReaction reaction;\n  std::stringstream& ss;\n\n  ~UninterestingCallCleanupHandler() {\n    ReportUninterestingCall(reaction, ss.str());\n  }\n};\n\nstruct UntypedFunctionMockerBase::FailureCleanupHandler {\n  std::stringstream& ss;\n  std::stringstream& why;\n  std::stringstream& loc;\n  const ExpectationBase* untyped_expectation;\n  bool found;\n  bool is_excessive;\n\n  ~FailureCleanupHandler() {\n    ss << \"\\n\" << why.str();\n\n    if (!found) {\n      // No expectation matches this call - reports a failure.\n      Expect(false, nullptr, -1, ss.str());\n    } else if (is_excessive) {\n      // We had an upper-bound violation and the failure message is in ss.\n      Expect(false, untyped_expectation->file(), untyped_expectation->line(),\n             ss.str());\n    } else {\n      // We had an expected call and the matching expectation is\n      // described in ss.\n      Log(kInfo, loc.str() + ss.str(), 2);\n    }\n  }\n};\n\ntemplate <typename F>\nclass FunctionMocker;\n\ntemplate <typename R, typename... Args>\nclass FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {\n  using F = R(Args...);\n\n public:\n  using Result = R;\n  using ArgumentTuple = std::tuple<Args...>;\n  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;\n\n  FunctionMocker() = default;\n\n  // There is no generally useful and implementable semantics of\n  // copying a mock object, so copying a mock is usually a user error.\n  // Thus we disallow copying function mockers.  If the user really\n  // wants to copy a mock object, they should implement their own copy\n  // operation, for example:\n  //\n  //   class MockFoo : public Foo {\n  //    public:\n  //     // Defines a copy constructor explicitly.\n  //     MockFoo(const MockFoo& src) {}\n  //     ...\n  //   };\n  FunctionMocker(const FunctionMocker&) = delete;\n  FunctionMocker& operator=(const FunctionMocker&) = delete;\n\n  // The destructor verifies that all expectations on this mock\n  // function have been satisfied.  If not, it will report Google Test\n  // non-fatal failures for the violations.\n  ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    MutexLock l(&g_gmock_mutex);\n    VerifyAndClearExpectationsLocked();\n    Mock::UnregisterLocked(this);\n    ClearDefaultActionsLocked();\n  }\n\n  // Returns the ON_CALL spec that matches this mock function with the\n  // given arguments; returns NULL if no matching ON_CALL is found.\n  // L = *\n  const OnCallSpec<F>* FindOnCallSpec(const ArgumentTuple& args) const {\n    for (UntypedOnCallSpecs::const_reverse_iterator it =\n             untyped_on_call_specs_.rbegin();\n         it != untyped_on_call_specs_.rend(); ++it) {\n      const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);\n      if (spec->Matches(args)) return spec;\n    }\n\n    return nullptr;\n  }\n\n  // Performs the default action of this mock function on the given\n  // arguments and returns the result. Asserts (or throws if\n  // exceptions are enabled) with a helpful call description if there\n  // is no valid return value. This method doesn't depend on the\n  // mutable state of this object, and thus can be called concurrently\n  // without locking.\n  // L = *\n  Result PerformDefaultAction(ArgumentTuple&& args,\n                              const std::string& call_description) const {\n    const OnCallSpec<F>* const spec = this->FindOnCallSpec(args);\n    if (spec != nullptr) {\n      return spec->GetAction().Perform(std::move(args));\n    }\n    const std::string message =\n        call_description +\n        \"\\n    The mock function has no default action \"\n        \"set, and its return type has no default value set.\";\n#if GTEST_HAS_EXCEPTIONS\n    if (!DefaultValue<Result>::Exists()) {\n      throw std::runtime_error(message);\n    }\n#else\n    Assert(DefaultValue<Result>::Exists(), \"\", -1, message);\n#endif\n    return DefaultValue<Result>::Get();\n  }\n\n  // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():\n  // clears the ON_CALL()s set on this mock function.\n  void ClearDefaultActionsLocked() override\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    // Deleting our default actions may trigger other mock objects to be\n    // deleted, for example if an action contains a reference counted smart\n    // pointer to that mock object, and that is the last reference. So if we\n    // delete our actions within the context of the global mutex we may deadlock\n    // when this method is called again. Instead, make a copy of the set of\n    // actions to delete, clear our set within the mutex, and then delete the\n    // actions outside of the mutex.\n    UntypedOnCallSpecs specs_to_delete;\n    untyped_on_call_specs_.swap(specs_to_delete);\n\n    g_gmock_mutex.Unlock();\n    for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();\n         it != specs_to_delete.end(); ++it) {\n      delete static_cast<const OnCallSpec<F>*>(*it);\n    }\n\n    // Lock the mutex again, since the caller expects it to be locked when we\n    // return.\n    g_gmock_mutex.Lock();\n  }\n\n  // Returns the result of invoking this mock function with the given\n  // arguments.  This function can be safely called from multiple\n  // threads concurrently.\n  Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    return InvokeWith(ArgumentTuple(std::forward<Args>(args)...));\n  }\n\n  MockSpec<F> With(Matcher<Args>... m) {\n    return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));\n  }\n\n protected:\n  template <typename Function>\n  friend class MockSpec;\n\n  // Adds and returns a default action spec for this mock function.\n  OnCallSpec<F>& AddNewOnCallSpec(const char* file, int line,\n                                  const ArgumentMatcherTuple& m)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);\n    OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);\n    untyped_on_call_specs_.push_back(on_call_spec);\n    return *on_call_spec;\n  }\n\n  // Adds and returns an expectation spec for this mock function.\n  TypedExpectation<F>& AddNewExpectation(const char* file, int line,\n                                         const std::string& source_text,\n                                         const ArgumentMatcherTuple& m)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);\n    TypedExpectation<F>* const expectation =\n        new TypedExpectation<F>(this, file, line, source_text, m);\n    const std::shared_ptr<ExpectationBase> untyped_expectation(expectation);\n    // See the definition of untyped_expectations_ for why access to\n    // it is unprotected here.\n    untyped_expectations_.push_back(untyped_expectation);\n\n    // Adds this expectation into the implicit sequence if there is one.\n    Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();\n    if (implicit_sequence != nullptr) {\n      implicit_sequence->AddExpectation(Expectation(untyped_expectation));\n    }\n\n    return *expectation;\n  }\n\n private:\n  template <typename Func>\n  friend class TypedExpectation;\n\n  // Some utilities needed for implementing UntypedInvokeWith().\n\n  // Describes what default action will be performed for the given\n  // arguments.\n  // L = *\n  void DescribeDefaultActionTo(const ArgumentTuple& args,\n                               ::std::ostream* os) const {\n    const OnCallSpec<F>* const spec = FindOnCallSpec(args);\n\n    if (spec == nullptr) {\n      *os << (std::is_void<Result>::value ? \"returning directly.\\n\"\n                                          : \"returning default value.\\n\");\n    } else {\n      *os << \"taking default action specified at:\\n\"\n          << FormatFileLocation(spec->file(), spec->line()) << \"\\n\";\n    }\n  }\n\n  // Writes a message that the call is uninteresting (i.e. neither\n  // explicitly expected nor explicitly unexpected) to the given\n  // ostream.\n  void UntypedDescribeUninterestingCall(const void* untyped_args,\n                                        ::std::ostream* os) const override\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    *os << \"Uninteresting mock function call - \";\n    DescribeDefaultActionTo(args, os);\n    *os << \"    Function call: \" << Name();\n    UniversalPrint(args, os);\n  }\n\n  // Returns the expectation that matches the given function arguments\n  // (or NULL is there's no match); when a match is found,\n  // untyped_action is set to point to the action that should be\n  // performed (or NULL if the action is \"do default\"), and\n  // is_excessive is modified to indicate whether the call exceeds the\n  // expected number.\n  //\n  // Critical section: We must find the matching expectation and the\n  // corresponding action that needs to be taken in an ATOMIC\n  // transaction.  Otherwise another thread may call this mock\n  // method in the middle and mess up the state.\n  //\n  // However, performing the action has to be left out of the critical\n  // section.  The reason is that we have no control on what the\n  // action does (it can invoke an arbitrary user function or even a\n  // mock function) and excessive locking could cause a dead lock.\n  const ExpectationBase* UntypedFindMatchingExpectation(\n      const void* untyped_args, const void** untyped_action, bool* is_excessive,\n      ::std::ostream* what, ::std::ostream* why) override\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    MutexLock l(&g_gmock_mutex);\n    TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);\n    if (exp == nullptr) {  // A match wasn't found.\n      this->FormatUnexpectedCallMessageLocked(args, what, why);\n      return nullptr;\n    }\n\n    // This line must be done before calling GetActionForArguments(),\n    // which will increment the call count for *exp and thus affect\n    // its saturation status.\n    *is_excessive = exp->IsSaturated();\n    const Action<F>* action = exp->GetActionForArguments(this, args, what, why);\n    if (action != nullptr && action->IsDoDefault())\n      action = nullptr;  // Normalize \"do default\" to NULL.\n    *untyped_action = action;\n    return exp;\n  }\n\n  // Prints the given function arguments to the ostream.\n  void UntypedPrintArgs(const void* untyped_args,\n                        ::std::ostream* os) const override {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    UniversalPrint(args, os);\n  }\n\n  // Returns the expectation that matches the arguments, or NULL if no\n  // expectation matches them.\n  TypedExpectation<F>* FindMatchingExpectationLocked(const ArgumentTuple& args)\n      const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    // See the definition of untyped_expectations_ for why access to\n    // it is unprotected here.\n    for (typename UntypedExpectations::const_reverse_iterator it =\n             untyped_expectations_.rbegin();\n         it != untyped_expectations_.rend(); ++it) {\n      TypedExpectation<F>* const exp =\n          static_cast<TypedExpectation<F>*>(it->get());\n      if (exp->ShouldHandleArguments(args)) {\n        return exp;\n      }\n    }\n    return nullptr;\n  }\n\n  // Returns a message that the arguments don't match any expectation.\n  void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args,\n                                         ::std::ostream* os,\n                                         ::std::ostream* why) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    *os << \"\\nUnexpected mock function call - \";\n    DescribeDefaultActionTo(args, os);\n    PrintTriedExpectationsLocked(args, why);\n  }\n\n  // Prints a list of expectations that have been tried against the\n  // current mock function call.\n  void PrintTriedExpectationsLocked(const ArgumentTuple& args,\n                                    ::std::ostream* why) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const size_t count = untyped_expectations_.size();\n    *why << \"Google Mock tried the following \" << count << \" \"\n         << (count == 1 ? \"expectation, but it didn't match\"\n                        : \"expectations, but none matched\")\n         << \":\\n\";\n    for (size_t i = 0; i < count; i++) {\n      TypedExpectation<F>* const expectation =\n          static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());\n      *why << \"\\n\";\n      expectation->DescribeLocationTo(why);\n      if (count > 1) {\n        *why << \"tried expectation #\" << i << \": \";\n      }\n      *why << expectation->source_text() << \"...\\n\";\n      expectation->ExplainMatchResultTo(args, why);\n      expectation->DescribeCallCountTo(why);\n    }\n  }\n\n  // Performs the given action (or the default if it's null) with the given\n  // arguments and returns the action's result.\n  // L = *\n  R PerformAction(const void* untyped_action, ArgumentTuple&& args,\n                  const std::string& call_description) const {\n    if (untyped_action == nullptr) {\n      return PerformDefaultAction(std::move(args), call_description);\n    }\n\n    // Make a copy of the action before performing it, in case the\n    // action deletes the mock object (and thus deletes itself).\n    const Action<F> action = *static_cast<const Action<F>*>(untyped_action);\n    return action.Perform(std::move(args));\n  }\n\n  // Is it possible to store an object of the supplied type in a local variable\n  // for the sake of printing it, then return it on to the caller?\n  template <typename T>\n  using can_print_result = internal::conjunction<\n      // void can't be stored as an object (and we also don't need to print it).\n      internal::negation<std::is_void<T>>,\n      // Non-moveable types can't be returned on to the user, so there's no way\n      // for us to intercept and print them.\n      std::is_move_constructible<T>>;\n\n  // Perform the supplied action, printing the result to os.\n  template <typename T = R,\n            typename std::enable_if<can_print_result<T>::value, int>::type = 0>\n  R PerformActionAndPrintResult(const void* const untyped_action,\n                                ArgumentTuple&& args,\n                                const std::string& call_description,\n                                std::ostream& os) {\n    R result = PerformAction(untyped_action, std::move(args), call_description);\n\n    PrintAsActionResult(result, os);\n    return std::forward<R>(result);\n  }\n\n  // An overload for when it's not possible to print the result. In this case we\n  // simply perform the action.\n  template <typename T = R,\n            typename std::enable_if<\n                internal::negation<can_print_result<T>>::value, int>::type = 0>\n  R PerformActionAndPrintResult(const void* const untyped_action,\n                                ArgumentTuple&& args,\n                                const std::string& call_description,\n                                std::ostream&) {\n    return PerformAction(untyped_action, std::move(args), call_description);\n  }\n\n  // Returns the result of invoking this mock function with the given\n  // arguments. This function can be safely called from multiple\n  // threads concurrently.\n  R InvokeWith(ArgumentTuple&& args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n};  // class FunctionMocker\n\n// Calculates the result of invoking this mock function with the given\n// arguments, prints it, and returns it.\ntemplate <typename R, typename... Args>\nR FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  // See the definition of untyped_expectations_ for why access to it\n  // is unprotected here.\n  if (untyped_expectations_.size() == 0) {\n    // No expectation is set on this mock method - we have an\n    // uninteresting call.\n\n    // We must get Google Mock's reaction on uninteresting calls\n    // made on this mock object BEFORE performing the action,\n    // because the action may DELETE the mock object and make the\n    // following expression meaningless.\n    const CallReaction reaction =\n        Mock::GetReactionOnUninterestingCalls(MockObject());\n\n    // True if and only if we need to print this call's arguments and return\n    // value.  This definition must be kept in sync with\n    // the behavior of ReportUninterestingCall().\n    const bool need_to_report_uninteresting_call =\n        // If the user allows this uninteresting call, we print it\n        // only when they want informational messages.\n        reaction == kAllow ? LogIsVisible(kInfo) :\n                           // If the user wants this to be a warning, we print\n                           // it only when they want to see warnings.\n            reaction == kWarn\n            ? LogIsVisible(kWarning)\n            :\n            // Otherwise, the user wants this to be an error, and we\n            // should always print detailed information in the error.\n            true;\n\n    if (!need_to_report_uninteresting_call) {\n      // Perform the action without printing the call information.\n      return this->PerformDefaultAction(\n          std::move(args), \"Function call: \" + std::string(Name()));\n    }\n\n    // Warns about the uninteresting call.\n    ::std::stringstream ss;\n    this->UntypedDescribeUninterestingCall(&args, &ss);\n\n    // Perform the action, print the result, and then report the uninteresting\n    // call.\n    //\n    // We use RAII to do the latter in case R is void or a non-moveable type. In\n    // either case we can't assign it to a local variable.\n    //\n    // Note that std::bind() is essential here.\n    // We *don't* use any local callback types (like lambdas).\n    // Doing so slows down compilation dramatically because the *constructor* of\n    // std::function<T> is re-instantiated with different template\n    // parameters each time.\n    const UninterestingCallCleanupHandler report_uninteresting_call = {\n        reaction, ss\n    };\n\n    return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);\n  }\n\n  bool is_excessive = false;\n  ::std::stringstream ss;\n  ::std::stringstream why;\n  ::std::stringstream loc;\n  const void* untyped_action = nullptr;\n\n  // The UntypedFindMatchingExpectation() function acquires and\n  // releases g_gmock_mutex.\n\n  const ExpectationBase* const untyped_expectation =\n      this->UntypedFindMatchingExpectation(&args, &untyped_action,\n                                           &is_excessive, &ss, &why);\n  const bool found = untyped_expectation != nullptr;\n\n  // True if and only if we need to print the call's arguments\n  // and return value.\n  // This definition must be kept in sync with the uses of Expect()\n  // and Log() in this function.\n  const bool need_to_report_call =\n      !found || is_excessive || LogIsVisible(kInfo);\n  if (!need_to_report_call) {\n    // Perform the action without printing the call information.\n    return PerformAction(untyped_action, std::move(args), \"\");\n  }\n\n  ss << \"    Function call: \" << Name();\n  this->UntypedPrintArgs(&args, &ss);\n\n  // In case the action deletes a piece of the expectation, we\n  // generate the message beforehand.\n  if (found && !is_excessive) {\n    untyped_expectation->DescribeLocationTo(&loc);\n  }\n\n  // Perform the action, print the result, and then fail or log in whatever way\n  // is appropriate.\n  //\n  // We use RAII to do the latter in case R is void or a non-moveable type. In\n  // either case we can't assign it to a local variable.\n  //\n  // Note that we *don't* use any local callback types (like lambdas) here.\n  // Doing so slows down compilation dramatically because the *constructor* of\n  // std::function<T> is re-instantiated with different template\n  // parameters each time.\n  const FailureCleanupHandler handle_failures = {\n      ss, why, loc, untyped_expectation, found, is_excessive\n  };\n\n  return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),\n                                     ss);\n}\n\n}  // namespace internal\n\nnamespace internal {\n\ntemplate <typename F>\nclass MockFunction;\n\ntemplate <typename R, typename... Args>\nclass MockFunction<R(Args...)> {\n public:\n  MockFunction(const MockFunction&) = delete;\n  MockFunction& operator=(const MockFunction&) = delete;\n\n  std::function<R(Args...)> AsStdFunction() {\n    return [this](Args... args) -> R {\n      return this->Call(std::forward<Args>(args)...);\n    };\n  }\n\n  // Implementation detail: the expansion of the MOCK_METHOD macro.\n  R Call(Args... args) {\n    mock_.SetOwnerAndName(this, \"Call\");\n    return mock_.Invoke(std::forward<Args>(args)...);\n  }\n\n  MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {\n    mock_.RegisterOwner(this);\n    return mock_.With(std::move(m)...);\n  }\n\n  MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {\n    return this->gmock_Call(::testing::A<Args>()...);\n  }\n\n protected:\n  MockFunction() = default;\n  ~MockFunction() = default;\n\n private:\n  FunctionMocker<R(Args...)> mock_;\n};\n\n/*\nThe SignatureOf<F> struct is a meta-function returning function signature\ncorresponding to the provided F argument.\n\nIt makes use of MockFunction easier by allowing it to accept more F arguments\nthan just function signatures.\n\nSpecializations provided here cover a signature type itself and any template\nthat can be parameterized with a signature, including std::function and\nboost::function.\n*/\n\ntemplate <typename F, typename = void>\nstruct SignatureOf;\n\ntemplate <typename R, typename... Args>\nstruct SignatureOf<R(Args...)> {\n  using type = R(Args...);\n};\n\ntemplate <template <typename> class C, typename F>\nstruct SignatureOf<C<F>,\n                   typename std::enable_if<std::is_function<F>::value>::type>\n    : SignatureOf<F> {};\n\ntemplate <typename F>\nusing SignatureOfT = typename SignatureOf<F>::type;\n\n}  // namespace internal\n\n// A MockFunction<F> type has one mock method whose type is\n// internal::SignatureOfT<F>.  It is useful when you just want your\n// test code to emit some messages and have Google Mock verify the\n// right messages are sent (and perhaps at the right times).  For\n// example, if you are exercising code:\n//\n//   Foo(1);\n//   Foo(2);\n//   Foo(3);\n//\n// and want to verify that Foo(1) and Foo(3) both invoke\n// mock.Bar(\"a\"), but Foo(2) doesn't invoke anything, you can write:\n//\n// TEST(FooTest, InvokesBarCorrectly) {\n//   MyMock mock;\n//   MockFunction<void(string check_point_name)> check;\n//   {\n//     InSequence s;\n//\n//     EXPECT_CALL(mock, Bar(\"a\"));\n//     EXPECT_CALL(check, Call(\"1\"));\n//     EXPECT_CALL(check, Call(\"2\"));\n//     EXPECT_CALL(mock, Bar(\"a\"));\n//   }\n//   Foo(1);\n//   check.Call(\"1\");\n//   Foo(2);\n//   check.Call(\"2\");\n//   Foo(3);\n// }\n//\n// The expectation spec says that the first Bar(\"a\") must happen\n// before check point \"1\", the second Bar(\"a\") must happen after check\n// point \"2\", and nothing should happen between the two check\n// points. The explicit check points make it easy to tell which\n// Bar(\"a\") is called by which call to Foo().\n//\n// MockFunction<F> can also be used to exercise code that accepts\n// std::function<internal::SignatureOfT<F>> callbacks. To do so, use\n// AsStdFunction() method to create std::function proxy forwarding to\n// original object's Call. Example:\n//\n// TEST(FooTest, RunsCallbackWithBarArgument) {\n//   MockFunction<int(string)> callback;\n//   EXPECT_CALL(callback, Call(\"bar\")).WillOnce(Return(1));\n//   Foo(callback.AsStdFunction());\n// }\n//\n// The internal::SignatureOfT<F> indirection allows to use other types\n// than just function signature type. This is typically useful when\n// providing a mock for a predefined std::function type. Example:\n//\n// using FilterPredicate = std::function<bool(string)>;\n// void MyFilterAlgorithm(FilterPredicate predicate);\n//\n// TEST(FooTest, FilterPredicateAlwaysAccepts) {\n//   MockFunction<FilterPredicate> predicateMock;\n//   EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));\n//   MyFilterAlgorithm(predicateMock.AsStdFunction());\n// }\ntemplate <typename F>\nclass MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> {\n  using Base = internal::MockFunction<internal::SignatureOfT<F>>;\n\n public:\n  using Base::Base;\n};\n\n// The style guide prohibits \"using\" statements in a namespace scope\n// inside a header file.  However, the MockSpec class template is\n// meant to be defined in the ::testing namespace.  The following line\n// is just a trick for working around a bug in MSVC 8.0, which cannot\n// handle it if we define MockSpec in ::testing.\nusing internal::MockSpec;\n\n// Const(x) is a convenient function for obtaining a const reference\n// to x.  This is useful for setting expectations on an overloaded\n// const mock method, e.g.\n//\n//   class MockFoo : public FooInterface {\n//    public:\n//     MOCK_METHOD0(Bar, int());\n//     MOCK_CONST_METHOD0(Bar, int&());\n//   };\n//\n//   MockFoo foo;\n//   // Expects a call to non-const MockFoo::Bar().\n//   EXPECT_CALL(foo, Bar());\n//   // Expects a call to const MockFoo::Bar().\n//   EXPECT_CALL(Const(foo), Bar());\ntemplate <typename T>\ninline const T& Const(const T& x) {\n  return x;\n}\n\n// Constructs an Expectation object that references and co-owns exp.\ninline Expectation::Expectation(internal::ExpectationBase& exp)  // NOLINT\n    : expectation_base_(exp.GetHandle().expectation_base()) {}\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is\n// required to avoid compile errors when the name of the method used in call is\n// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro\n// tests in internal/gmock-spec-builders_test.cc for more details.\n//\n// This macro supports statements both with and without parameter matchers. If\n// the parameter list is omitted, gMock will accept any parameters, which allows\n// tests to be written that don't need to encode the number of method\n// parameter. This technique may only be used for non-overloaded methods.\n//\n//   // These are the same:\n//   ON_CALL(mock, NoArgsMethod()).WillByDefault(...);\n//   ON_CALL(mock, NoArgsMethod).WillByDefault(...);\n//\n//   // As are these:\n//   ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...);\n//   ON_CALL(mock, TwoArgsMethod).WillByDefault(...);\n//\n//   // Can also specify args if you want, of course:\n//   ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...);\n//\n//   // Overloads work as long as you specify parameters:\n//   ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...);\n//   ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...);\n//\n//   // Oops! Which overload did you want?\n//   ON_CALL(mock, OverloadedMethod).WillByDefault(...);\n//     => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous\n//\n// How this works: The mock class uses two overloads of the gmock_Method\n// expectation setter method plus an operator() overload on the MockSpec object.\n// In the matcher list form, the macro expands to:\n//\n//   // This statement:\n//   ON_CALL(mock, TwoArgsMethod(_, 45))...\n//\n//   // ...expands to:\n//   mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)...\n//   |-------------v---------------||------------v-------------|\n//       invokes first overload        swallowed by operator()\n//\n//   // ...which is essentially:\n//   mock.gmock_TwoArgsMethod(_, 45)...\n//\n// Whereas the form without a matcher list:\n//\n//   // This statement:\n//   ON_CALL(mock, TwoArgsMethod)...\n//\n//   // ...expands to:\n//   mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)...\n//   |-----------------------v--------------------------|\n//                 invokes second overload\n//\n//   // ...which is essentially:\n//   mock.gmock_TwoArgsMethod(_, _)...\n//\n// The WithoutMatchers() argument is used to disambiguate overloads and to\n// block the caller from accidentally invoking the second overload directly. The\n// second argument is an internal type derived from the method signature. The\n// failure to disambiguate two overloads of this method in the ON_CALL statement\n// is how we block callers from setting expectations on overloaded methods.\n#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call)                    \\\n  ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \\\n                             nullptr)                                   \\\n      .Setter(__FILE__, __LINE__, #mock_expr, #call)\n\n#define ON_CALL(obj, call) \\\n  GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)\n\n#define EXPECT_CALL(obj, call) \\\n  GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/gmock.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This is the main header file a user should include.\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n\n// This file implements the following syntax:\n//\n//   ON_CALL(mock_object, Method(...))\n//     .With(...) ?\n//     .WillByDefault(...);\n//\n// where With() is optional and WillByDefault() must appear exactly\n// once.\n//\n//   EXPECT_CALL(mock_object, Method(...))\n//     .With(...) ?\n//     .Times(...) ?\n//     .InSequence(...) *\n//     .WillOnce(...) *\n//     .WillRepeatedly(...) ?\n//     .RetiresOnSaturation() ? ;\n//\n// where all clauses are optional and WillOnce() can be repeated.\n\n#include \"gmock/gmock-actions.h\"  // IWYU pragma: export\n#include \"gmock/gmock-cardinalities.h\"  // IWYU pragma: export\n#include \"gmock/gmock-function-mocker.h\"  // IWYU pragma: export\n#include \"gmock/gmock-matchers.h\"  // IWYU pragma: export\n#include \"gmock/gmock-more-actions.h\"  // IWYU pragma: export\n#include \"gmock/gmock-more-matchers.h\"  // IWYU pragma: export\n#include \"gmock/gmock-nice-strict.h\"  // IWYU pragma: export\n#include \"gmock/gmock-spec-builders.h\"  // IWYU pragma: export\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n\n// Declares Google Mock flags that we want a user to use programmatically.\nGMOCK_DECLARE_bool_(catch_leaked_mocks);\nGMOCK_DECLARE_string_(verbose);\nGMOCK_DECLARE_int32_(default_mock_behavior);\n\nnamespace testing {\n\n// Initializes Google Mock.  This must be called before running the\n// tests.  In particular, it parses the command line for the flags\n// that Google Mock recognizes.  Whenever a Google Mock flag is seen,\n// it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Mock flag variables are\n// updated.\n//\n// Since Google Test is needed for Google Mock to work, this function\n// also initializes Google Test and parses its flags, if that hasn't\n// been done.\nGTEST_API_ void InitGoogleMock(int* argc, char** argv);\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleMock();\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/custom/README.md",
    "content": "# Customization Points\n\nThe custom directory is an injection point for custom user configurations.\n\n## Header `gmock-port.h`\n\nThe following macros can be defined:\n\n### Flag related macros:\n\n*   `GMOCK_DECLARE_bool_(name)`\n*   `GMOCK_DECLARE_int32_(name)`\n*   `GMOCK_DECLARE_string_(name)`\n*   `GMOCK_DEFINE_bool_(name, default_val, doc)`\n*   `GMOCK_DEFINE_int32_(name, default_val, doc)`\n*   `GMOCK_DEFINE_string_(name, default_val, doc)`\n*   `GMOCK_FLAG_GET(flag_name)`\n*   `GMOCK_FLAG_SET(flag_name, value)`\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h",
    "content": "// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Injection point for custom user configurations. See README for details\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-port.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file defines some utilities useful for implementing Google\n// Mock.  They are subject to change without notice, so please DO NOT\n// USE THEM IN USER CODE.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n\n#include <stdio.h>\n\n#include <ostream>  // NOLINT\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\n\ntemplate <typename>\nclass Matcher;\n\nnamespace internal {\n\n// Silence MSVC C4100 (unreferenced formal parameter) and\n// C4805('==': unsafe mix of type 'const int' and type 'const bool')\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)\n\n// Joins a vector of strings as if they are fields of a tuple; returns\n// the joined string.\nGTEST_API_ std::string JoinAsKeyValueTuple(\n    const std::vector<const char*>& names, const Strings& values);\n\n// Converts an identifier name to a space-separated list of lower-case\n// words.  Each maximum substring of the form [A-Za-z][a-z]*|\\d+ is\n// treated as one word.  For example, both \"FooBar123\" and\n// \"foo_bar_123\" are converted to \"foo bar 123\".\nGTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);\n\n// GetRawPointer(p) returns the raw pointer underlying p when p is a\n// smart pointer, or returns p itself when p is already a raw pointer.\n// The following default implementation is for the smart pointer case.\ntemplate <typename Pointer>\ninline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {\n  return p.get();\n}\n// This overload version is for std::reference_wrapper, which does not work with\n// the overload above, as it does not have an `element_type`.\ntemplate <typename Element>\ninline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {\n  return &r.get();\n}\n\n// This overloaded version is for the raw pointer case.\ntemplate <typename Element>\ninline Element* GetRawPointer(Element* p) {\n  return p;\n}\n\n// Default definitions for all compilers.\n// NOTE: If you implement support for other compilers, make sure to avoid\n// unexpected overlaps.\n// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)\n#define GMOCK_INTERNAL_WARNING_PUSH()\n#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)\n#define GMOCK_INTERNAL_WARNING_POP()\n\n#if defined(__clang__)\n#undef GMOCK_INTERNAL_WARNING_PUSH\n#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma(\"clang diagnostic push\")\n#undef GMOCK_INTERNAL_WARNING_CLANG\n#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \\\n  _Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))\n#undef GMOCK_INTERNAL_WARNING_POP\n#define GMOCK_INTERNAL_WARNING_POP() _Pragma(\"clang diagnostic pop\")\n#endif\n\n// MSVC treats wchar_t as a native type usually, but treats it as the\n// same as unsigned short when the compiler option /Zc:wchar_t- is\n// specified.  It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t\n// is a native type.\n#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)\n// wchar_t is a typedef.\n#else\n#define GMOCK_WCHAR_T_IS_NATIVE_ 1\n#endif\n\n// In what follows, we use the term \"kind\" to indicate whether a type\n// is bool, an integer type (excluding bool), a floating-point type,\n// or none of them.  This categorization is useful for determining\n// when a matcher argument type can be safely converted to another\n// type in the implementation of SafeMatcherCast.\nenum TypeKind { kBool, kInteger, kFloatingPoint, kOther };\n\n// KindOf<T>::value is the kind of type T.\ntemplate <typename T>\nstruct KindOf {\n  enum { value = kOther };  // The default kind.\n};\n\n// This macro declares that the kind of 'type' is 'kind'.\n#define GMOCK_DECLARE_KIND_(type, kind) \\\n  template <>                           \\\n  struct KindOf<type> {                 \\\n    enum { value = kind };              \\\n  }\n\nGMOCK_DECLARE_KIND_(bool, kBool);\n\n// All standard integer types.\nGMOCK_DECLARE_KIND_(char, kInteger);\nGMOCK_DECLARE_KIND_(signed char, kInteger);\nGMOCK_DECLARE_KIND_(unsigned char, kInteger);\nGMOCK_DECLARE_KIND_(short, kInteger);           // NOLINT\nGMOCK_DECLARE_KIND_(unsigned short, kInteger);  // NOLINT\nGMOCK_DECLARE_KIND_(int, kInteger);\nGMOCK_DECLARE_KIND_(unsigned int, kInteger);\nGMOCK_DECLARE_KIND_(long, kInteger);                // NOLINT\nGMOCK_DECLARE_KIND_(unsigned long, kInteger);       // NOLINT\nGMOCK_DECLARE_KIND_(long long, kInteger);           // NOLINT\nGMOCK_DECLARE_KIND_(unsigned long long, kInteger);  // NOLINT\n\n#if GMOCK_WCHAR_T_IS_NATIVE_\nGMOCK_DECLARE_KIND_(wchar_t, kInteger);\n#endif\n\n// All standard floating-point types.\nGMOCK_DECLARE_KIND_(float, kFloatingPoint);\nGMOCK_DECLARE_KIND_(double, kFloatingPoint);\nGMOCK_DECLARE_KIND_(long double, kFloatingPoint);\n\n#undef GMOCK_DECLARE_KIND_\n\n// Evaluates to the kind of 'type'.\n#define GMOCK_KIND_OF_(type)                   \\\n  static_cast< ::testing::internal::TypeKind>( \\\n      ::testing::internal::KindOf<type>::value)\n\n// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value\n// is true if and only if arithmetic type From can be losslessly converted to\n// arithmetic type To.\n//\n// It's the user's responsibility to ensure that both From and To are\n// raw (i.e. has no CV modifier, is not a pointer, and is not a\n// reference) built-in arithmetic types, kFromKind is the kind of\n// From, and kToKind is the kind of To; the value is\n// implementation-defined when the above pre-condition is violated.\ntemplate <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>\nusing LosslessArithmeticConvertibleImpl = std::integral_constant<\n    bool,\n    // clang-format off\n      // Converting from bool is always lossless\n      (kFromKind == kBool) ? true\n      // Converting between any other type kinds will be lossy if the type\n      // kinds are not the same.\n    : (kFromKind != kToKind) ? false\n    : (kFromKind == kInteger &&\n       // Converting between integers of different widths is allowed so long\n       // as the conversion does not go from signed to unsigned.\n      (((sizeof(From) < sizeof(To)) &&\n        !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||\n       // Converting between integers of the same width only requires the\n       // two types to have the same signedness.\n       ((sizeof(From) == sizeof(To)) &&\n        (std::is_signed<From>::value == std::is_signed<To>::value)))\n       ) ? true\n      // Floating point conversions are lossless if and only if `To` is at least\n      // as wide as `From`.\n    : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true\n    : false\n    // clang-format on\n    >;\n\n// LosslessArithmeticConvertible<From, To>::value is true if and only if\n// arithmetic type From can be losslessly converted to arithmetic type To.\n//\n// It's the user's responsibility to ensure that both From and To are\n// raw (i.e. has no CV modifier, is not a pointer, and is not a\n// reference) built-in arithmetic types; the value is\n// implementation-defined when the above pre-condition is violated.\ntemplate <typename From, typename To>\nusing LosslessArithmeticConvertible =\n    LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,\n                                      GMOCK_KIND_OF_(To), To>;\n\n// This interface knows how to report a Google Mock failure (either\n// non-fatal or fatal).\nclass FailureReporterInterface {\n public:\n  // The type of a failure (either non-fatal or fatal).\n  enum FailureType { kNonfatal, kFatal };\n\n  virtual ~FailureReporterInterface() = default;\n\n  // Reports a failure that occurred at the given source file location.\n  virtual void ReportFailure(FailureType type, const char* file, int line,\n                             const std::string& message) = 0;\n};\n\n// Returns the failure reporter used by Google Mock.\nGTEST_API_ FailureReporterInterface* GetFailureReporter();\n\n// Asserts that condition is true; aborts the process with the given\n// message if condition is false.  We cannot use LOG(FATAL) or CHECK()\n// as Google Mock might be used to mock the log sink itself.  We\n// inline this function to prevent it from showing up in the stack\n// trace.\ninline void Assert(bool condition, const char* file, int line,\n                   const std::string& msg) {\n  if (!condition) {\n    GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,\n                                        line, msg);\n  }\n}\ninline void Assert(bool condition, const char* file, int line) {\n  Assert(condition, file, line, \"Assertion failed.\");\n}\n\n// Verifies that condition is true; generates a non-fatal failure if\n// condition is false.\ninline void Expect(bool condition, const char* file, int line,\n                   const std::string& msg) {\n  if (!condition) {\n    GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,\n                                        file, line, msg);\n  }\n}\ninline void Expect(bool condition, const char* file, int line) {\n  Expect(condition, file, line, \"Expectation failed.\");\n}\n\n// Severity level of a log.\nenum LogSeverity { kInfo = 0, kWarning = 1 };\n\n// Valid values for the --gmock_verbose flag.\n\n// All logs (informational and warnings) are printed.\nconst char kInfoVerbosity[] = \"info\";\n// Only warnings are printed.\nconst char kWarningVerbosity[] = \"warning\";\n// No logs are printed.\nconst char kErrorVerbosity[] = \"error\";\n\n// Returns true if and only if a log with the given severity is visible\n// according to the --gmock_verbose flag.\nGTEST_API_ bool LogIsVisible(LogSeverity severity);\n\n// Prints the given message to stdout if and only if 'severity' >= the level\n// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=\n// 0, also prints the stack trace excluding the top\n// stack_frames_to_skip frames.  In opt mode, any positive\n// stack_frames_to_skip is treated as 0, since we don't know which\n// function calls will be inlined by the compiler and need to be\n// conservative.\nGTEST_API_ void Log(LogSeverity severity, const std::string& message,\n                    int stack_frames_to_skip);\n\n// A marker class that is used to resolve parameterless expectations to the\n// correct overload. This must not be instantiable, to prevent client code from\n// accidentally resolving to the overload; for example:\n//\n//    ON_CALL(mock, Method({}, nullptr))...\n//\nclass WithoutMatchers {\n private:\n  WithoutMatchers() {}\n  friend GTEST_API_ WithoutMatchers GetWithoutMatchers();\n};\n\n// Internal use only: access the singleton instance of WithoutMatchers.\nGTEST_API_ WithoutMatchers GetWithoutMatchers();\n\n// Invalid<T>() is usable as an expression of type T, but will terminate\n// the program with an assertion failure if actually run.  This is useful\n// when a value of type T is needed for compilation, but the statement\n// will not really be executed (or we don't care if the statement\n// crashes).\ntemplate <typename T>\ninline T Invalid() {\n  Assert(/*condition=*/false, /*file=*/\"\", /*line=*/-1,\n         \"Internal error: attempt to return invalid value\");\n#if defined(__GNUC__) || defined(__clang__)\n  __builtin_unreachable();\n#elif defined(_MSC_VER)\n  __assume(0);\n#else\n  return Invalid<T>();\n#endif\n}\n\n// Given a raw type (i.e. having no top-level reference or const\n// modifier) RawContainer that's either an STL-style container or a\n// native array, class StlContainerView<RawContainer> has the\n// following members:\n//\n//   - type is a type that provides an STL-style container view to\n//     (i.e. implements the STL container concept for) RawContainer;\n//   - const_reference is a type that provides a reference to a const\n//     RawContainer;\n//   - ConstReference(raw_container) returns a const reference to an STL-style\n//     container view to raw_container, which is a RawContainer.\n//   - Copy(raw_container) returns an STL-style container view of a\n//     copy of raw_container, which is a RawContainer.\n//\n// This generic version is used when RawContainer itself is already an\n// STL-style container.\ntemplate <class RawContainer>\nclass StlContainerView {\n public:\n  typedef RawContainer type;\n  typedef const type& const_reference;\n\n  static const_reference ConstReference(const RawContainer& container) {\n    static_assert(!std::is_const<RawContainer>::value,\n                  \"RawContainer type must not be const\");\n    return container;\n  }\n  static type Copy(const RawContainer& container) { return container; }\n};\n\n// This specialization is used when RawContainer is a native array type.\ntemplate <typename Element, size_t N>\nclass StlContainerView<Element[N]> {\n public:\n  typedef typename std::remove_const<Element>::type RawElement;\n  typedef internal::NativeArray<RawElement> type;\n  // NativeArray<T> can represent a native array either by value or by\n  // reference (selected by a constructor argument), so 'const type'\n  // can be used to reference a const native array.  We cannot\n  // 'typedef const type& const_reference' here, as that would mean\n  // ConstReference() has to return a reference to a local variable.\n  typedef const type const_reference;\n\n  static const_reference ConstReference(const Element (&array)[N]) {\n    static_assert(std::is_same<Element, RawElement>::value,\n                  \"Element type must not be const\");\n    return type(array, N, RelationToSourceReference());\n  }\n  static type Copy(const Element (&array)[N]) {\n    return type(array, N, RelationToSourceCopy());\n  }\n};\n\n// This specialization is used when RawContainer is a native array\n// represented as a (pointer, size) tuple.\ntemplate <typename ElementPointer, typename Size>\nclass StlContainerView< ::std::tuple<ElementPointer, Size> > {\n public:\n  typedef typename std::remove_const<\n      typename std::pointer_traits<ElementPointer>::element_type>::type\n      RawElement;\n  typedef internal::NativeArray<RawElement> type;\n  typedef const type const_reference;\n\n  static const_reference ConstReference(\n      const ::std::tuple<ElementPointer, Size>& array) {\n    return type(std::get<0>(array), std::get<1>(array),\n                RelationToSourceReference());\n  }\n  static type Copy(const ::std::tuple<ElementPointer, Size>& array) {\n    return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());\n  }\n};\n\n// The following specialization prevents the user from instantiating\n// StlContainer with a reference type.\ntemplate <typename T>\nclass StlContainerView<T&>;\n\n// A type transform to remove constness from the first part of a pair.\n// Pairs like that are used as the value_type of associative containers,\n// and this transform produces a similar but assignable pair.\ntemplate <typename T>\nstruct RemoveConstFromKey {\n  typedef T type;\n};\n\n// Partially specialized to remove constness from std::pair<const K, V>.\ntemplate <typename K, typename V>\nstruct RemoveConstFromKey<std::pair<const K, V> > {\n  typedef std::pair<K, V> type;\n};\n\n// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to\n// reduce code size.\nGTEST_API_ void IllegalDoDefault(const char* file, int line);\n\ntemplate <typename F, typename Tuple, size_t... Idx>\nauto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)\n    -> decltype(std::forward<F>(f)(\n        std::get<Idx>(std::forward<Tuple>(args))...)) {\n  return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);\n}\n\n// Apply the function to a tuple of arguments.\ntemplate <typename F, typename Tuple>\nauto Apply(F&& f, Tuple&& args)\n    -> decltype(ApplyImpl(\n        std::forward<F>(f), std::forward<Tuple>(args),\n        std::make_index_sequence<std::tuple_size<\n            typename std::remove_reference<Tuple>::type>::value>())) {\n  return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),\n                   std::make_index_sequence<std::tuple_size<\n                       typename std::remove_reference<Tuple>::type>::value>());\n}\n\n// Template struct Function<F>, where F must be a function type, contains\n// the following typedefs:\n//\n//   Result:               the function's return type.\n//   Arg<N>:               the type of the N-th argument, where N starts with 0.\n//   ArgumentTuple:        the tuple type consisting of all parameters of F.\n//   ArgumentMatcherTuple: the tuple type consisting of Matchers for all\n//                         parameters of F.\n//   MakeResultVoid:       the function type obtained by substituting void\n//                         for the return type of F.\n//   MakeResultIgnoredValue:\n//                         the function type obtained by substituting Something\n//                         for the return type of F.\ntemplate <typename T>\nstruct Function;\n\ntemplate <typename R, typename... Args>\nstruct Function<R(Args...)> {\n  using Result = R;\n  static constexpr size_t ArgumentCount = sizeof...(Args);\n  template <size_t I>\n  using Arg = ElemFromList<I, Args...>;\n  using ArgumentTuple = std::tuple<Args...>;\n  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;\n  using MakeResultVoid = void(Args...);\n  using MakeResultIgnoredValue = IgnoredValue(Args...);\n};\n\n#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL\ntemplate <typename R, typename... Args>\nconstexpr size_t Function<R(Args...)>::ArgumentCount;\n#endif\n\n// Workaround for MSVC error C2039: 'type': is not a member of 'std'\n// when std::tuple_element is used.\n// See: https://github.com/google/googletest/issues/3931\n// Can be replaced with std::tuple_element_t in C++14.\ntemplate <size_t I, typename T>\nusing TupleElement = typename std::tuple_element<I, T>::type;\n\nbool Base64Unescape(const std::string& encoded, std::string* decoded);\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100 4805\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/gmock-port.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Low-level types and utilities for porting Google Mock to various\n// platforms.  All macros ending with _ and symbols defined in an\n// internal namespace are subject to change without notice.  Code\n// outside Google Mock MUST NOT USE THEM DIRECTLY.  Macros that don't\n// end with _ are part of Google Mock's public API and can be used by\n// code outside Google Mock.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n\n#include <assert.h>\n#include <stdlib.h>\n#include <cstdint>\n#include <iostream>\n\n// Most of the utilities needed for porting Google Mock are also\n// required for Google Test and are defined in gtest-port.h.\n//\n// Note to maintainers: to reduce code duplication, prefer adding\n// portability utilities to Google Test's gtest-port.h instead of\n// here, as Google Mock depends on Google Test.  Only add a utility\n// here if it's truly specific to Google Mock.\n\n#include \"gmock/internal/custom/gmock-port.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#include \"absl/flags/declare.h\"\n#include \"absl/flags/flag.h\"\n#endif\n\n// For MS Visual C++, check the compiler version. At least VS 2015 is\n// required to compile Google Mock.\n#if defined(_MSC_VER) && _MSC_VER < 1900\n#error \"At least Visual C++ 2015 (14.0) is required to compile Google Mock.\"\n#endif\n\n// Macro for referencing flags.  This is public as we want the user to\n// use this syntax to reference Google Mock flags.\n#define GMOCK_FLAG_NAME_(name) gmock_##name\n#define GMOCK_FLAG(name) FLAGS_gmock_##name\n\n// Pick a command line flags implementation.\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n// Macros for defining flags.\n#define GMOCK_DEFINE_bool_(name, default_val, doc) \\\n  ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc)\n#define GMOCK_DEFINE_int32_(name, default_val, doc) \\\n  ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc)\n#define GMOCK_DEFINE_string_(name, default_val, doc) \\\n  ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc)\n\n// Macros for declaring flags.\n#define GMOCK_DECLARE_bool_(name) \\\n  ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))\n#define GMOCK_DECLARE_int32_(name) \\\n  ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))\n#define GMOCK_DECLARE_string_(name) \\\n  ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))\n\n#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))\n#define GMOCK_FLAG_SET(name, value) \\\n  (void)(::absl::SetFlag(&GMOCK_FLAG(name), value))\n\n#else  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n// Macros for defining flags.\n#define GMOCK_DEFINE_bool_(name, default_val, doc)  \\\n  namespace testing {                               \\\n  GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DEFINE_int32_(name, default_val, doc)    \\\n  namespace testing {                                  \\\n  GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \\\n  }                                                    \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DEFINE_string_(name, default_val, doc)         \\\n  namespace testing {                                        \\\n  GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \\\n  }                                                          \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n// Macros for declaring flags.\n#define GMOCK_DECLARE_bool_(name)          \\\n  namespace testing {                      \\\n  GTEST_API_ extern bool GMOCK_FLAG(name); \\\n  }                                        \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DECLARE_int32_(name)            \\\n  namespace testing {                         \\\n  GTEST_API_ extern int32_t GMOCK_FLAG(name); \\\n  }                                           \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DECLARE_string_(name)                 \\\n  namespace testing {                               \\\n  GTEST_API_ extern ::std::string GMOCK_FLAG(name); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)\n#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)\n\n#endif  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/include/gmock/internal/gmock-pp.h",
    "content": "#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n\n// Expands and concatenates the arguments. Constructed macros reevaluate.\n#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)\n\n// Expands and stringifies the only argument.\n#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)\n\n// Returns empty. Given a variadic number of arguments.\n#define GMOCK_PP_EMPTY(...)\n\n// Returns a comma. Given a variadic number of arguments.\n#define GMOCK_PP_COMMA(...) ,\n\n// Returns the only argument.\n#define GMOCK_PP_IDENTITY(_1) _1\n\n// Evaluates to the number of arguments after expansion.\n//\n//   #define PAIR x, y\n//\n//   GMOCK_PP_NARG() => 1\n//   GMOCK_PP_NARG(x) => 1\n//   GMOCK_PP_NARG(x, y) => 2\n//   GMOCK_PP_NARG(PAIR) => 2\n//\n// Requires: the number of arguments after expansion is at most 15.\n#define GMOCK_PP_NARG(...) \\\n  GMOCK_PP_INTERNAL_16TH(  \\\n      (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))\n\n// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise\n// returns 0. Requires no more than 15 unprotected commas.\n#define GMOCK_PP_HAS_COMMA(...) \\\n  GMOCK_PP_INTERNAL_16TH(       \\\n      (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))\n\n// Returns the first argument.\n#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))\n\n// Returns the tail. A variadic list of all arguments minus the first. Requires\n// at least one argument.\n#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))\n\n// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)\n#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \\\n  GMOCK_PP_IDENTITY(                        \\\n      GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))\n\n// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise\n// evaluates to `0`.\n//\n// Requires: * the number of arguments after expansion is at most 15.\n//           * If the argument is a macro, it must be able to be called with one\n//             argument.\n//\n// Implementation details:\n//\n// There is one case when it generates a compile error: if the argument is macro\n// that cannot be called with one argument.\n//\n//   #define M(a, b)  // it doesn't matter what it expands to\n//\n//   // Expected: expands to `0`.\n//   // Actual: compile error.\n//   GMOCK_PP_IS_EMPTY(M)\n//\n// There are 4 cases tested:\n//\n// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.\n// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.\n// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.\n//   Expected 0\n// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in\n//   parenthesis, or is a macro that ()-evaluates to comma. Expected 1.\n//\n// We trigger detection on '0001', i.e. on empty.\n#define GMOCK_PP_IS_EMPTY(...)                                               \\\n  GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__),                \\\n                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \\\n                             GMOCK_PP_HAS_COMMA(__VA_ARGS__()),              \\\n                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))\n\n// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.\n#define GMOCK_PP_IF(_Cond, _Then, _Else) \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)\n\n// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.\n//\n// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c\n// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f\n//\n#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \\\n  GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))\n\n// Evaluates to the number of arguments after expansion. Identifies 'empty' as\n// 0.\n//\n//   #define PAIR x, y\n//\n//   GMOCK_PP_NARG0() => 0\n//   GMOCK_PP_NARG0(x) => 1\n//   GMOCK_PP_NARG0(x, y) => 2\n//   GMOCK_PP_NARG0(PAIR) => 2\n//\n// Requires: * the number of arguments after expansion is at most 15.\n//           * If the argument is a macro, it must be able to be called with one\n//             argument.\n#define GMOCK_PP_NARG0(...) \\\n  GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))\n\n// Expands to 1 if the first argument starts with something in parentheses,\n// otherwise to 0.\n#define GMOCK_PP_IS_BEGIN_PARENS(...)                              \\\n  GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \\\n                             GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))\n\n// Expands to 1 is there is only one argument and it is enclosed in parentheses.\n#define GMOCK_PP_IS_ENCLOSED_PARENS(...)             \\\n  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \\\n              GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)\n\n// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.\n#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__\n\n// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,\n// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.\n// Requires: * |_Macro| can be called with 3 arguments.\n//           * |_Tuple| expansion has no more than 15 elements.\n#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple)                        \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \\\n  (0, _Macro, _Data, _Tuple)\n\n// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )\n// Empty if _K = 0.\n// Requires: * |_Macro| can be called with 3 arguments.\n//           * |_K| literal between 0 and 15\n#define GMOCK_PP_REPEAT(_Macro, _Data, _N)           \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \\\n  (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)\n\n// Increments the argument, requires the argument to be between 0 and 15.\n#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)\n\n// Returns comma if _i != 0. Requires _i to be between 0 and 15.\n#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)\n\n// Internal details follow. Do not use any of these symbols outside of this\n// file or we will break your code.\n#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )\n#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2\n#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__\n#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5\n#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4)                             \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \\\n                                             _1, _2, _3, _4))\n#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,\n#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then\n#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else\n\n// Because of MSVC treating a token with a comma in it as a single token when\n// passed to another macro, we need to force it to evaluate it as multiple\n// tokens. We do that by using a \"IDENTITY(MACRO PARENTHESIZED_ARGS)\" macro. We\n// define one per possible macro that relies on this behavior. Note \"_Args\" must\n// be parenthesized.\n#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \\\n                                        _10, _11, _12, _13, _14, _15, _16,  \\\n                                        ...)                                \\\n  _16\n#define GMOCK_PP_INTERNAL_16TH(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)\n#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1\n#define GMOCK_PP_INTERNAL_HEAD(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)\n#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__\n#define GMOCK_PP_INTERNAL_TAIL(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)\n\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \\\n  0,\n#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__\n#define GMOCK_PP_INTERNAL_INC_0 1\n#define GMOCK_PP_INTERNAL_INC_1 2\n#define GMOCK_PP_INTERNAL_INC_2 3\n#define GMOCK_PP_INTERNAL_INC_3 4\n#define GMOCK_PP_INTERNAL_INC_4 5\n#define GMOCK_PP_INTERNAL_INC_5 6\n#define GMOCK_PP_INTERNAL_INC_6 7\n#define GMOCK_PP_INTERNAL_INC_7 8\n#define GMOCK_PP_INTERNAL_INC_8 9\n#define GMOCK_PP_INTERNAL_INC_9 10\n#define GMOCK_PP_INTERNAL_INC_10 11\n#define GMOCK_PP_INTERNAL_INC_11 12\n#define GMOCK_PP_INTERNAL_INC_12 13\n#define GMOCK_PP_INTERNAL_INC_13 14\n#define GMOCK_PP_INTERNAL_INC_14 15\n#define GMOCK_PP_INTERNAL_INC_15 16\n#define GMOCK_PP_INTERNAL_COMMA_IF_0\n#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,\n#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \\\n  _Macro(_i, _Data, _element)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock-all.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// Google C++ Mocking Framework (Google Mock)\n//\n// This file #includes all Google Mock implementation .cc files.  The\n// purpose is to allow a user to build Google Mock by compiling this\n// file alone.\n\n// This line ensures that gmock.h can be compiled on its own, even\n// when it's fused.\n#include \"gmock/gmock.h\"\n\n// The following lines pull in the real gmock *.cc files.\n#include \"src/gmock-cardinalities.cc\"\n#include \"src/gmock-internal-utils.cc\"\n#include \"src/gmock-matchers.cc\"\n#include \"src/gmock-spec-builders.cc\"\n#include \"src/gmock.cc\"\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock-cardinalities.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements cardinalities.\n\n#include \"gmock/gmock-cardinalities.h\"\n\n#include <limits.h>\n\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\n\nnamespace {\n\n// Implements the Between(m, n) cardinality.\nclass BetweenCardinalityImpl : public CardinalityInterface {\n public:\n  BetweenCardinalityImpl(int min, int max)\n      : min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {\n    std::stringstream ss;\n    if (min < 0) {\n      ss << \"The invocation lower bound must be >= 0, \"\n         << \"but is actually \" << min << \".\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    } else if (max < 0) {\n      ss << \"The invocation upper bound must be >= 0, \"\n         << \"but is actually \" << max << \".\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    } else if (min > max) {\n      ss << \"The invocation upper bound (\" << max\n         << \") must be >= the invocation lower bound (\" << min << \").\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    }\n  }\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  int ConservativeLowerBound() const override { return min_; }\n  int ConservativeUpperBound() const override { return max_; }\n\n  bool IsSatisfiedByCallCount(int call_count) const override {\n    return min_ <= call_count && call_count <= max_;\n  }\n\n  bool IsSaturatedByCallCount(int call_count) const override {\n    return call_count >= max_;\n  }\n\n  void DescribeTo(::std::ostream* os) const override;\n\n private:\n  const int min_;\n  const int max_;\n\n  BetweenCardinalityImpl(const BetweenCardinalityImpl&) = delete;\n  BetweenCardinalityImpl& operator=(const BetweenCardinalityImpl&) = delete;\n};\n\n// Formats \"n times\" in a human-friendly way.\ninline std::string FormatTimes(int n) {\n  if (n == 1) {\n    return \"once\";\n  } else if (n == 2) {\n    return \"twice\";\n  } else {\n    std::stringstream ss;\n    ss << n << \" times\";\n    return ss.str();\n  }\n}\n\n// Describes the Between(m, n) cardinality in human-friendly text.\nvoid BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {\n  if (min_ == 0) {\n    if (max_ == 0) {\n      *os << \"never called\";\n    } else if (max_ == INT_MAX) {\n      *os << \"called any number of times\";\n    } else {\n      *os << \"called at most \" << FormatTimes(max_);\n    }\n  } else if (min_ == max_) {\n    *os << \"called \" << FormatTimes(min_);\n  } else if (max_ == INT_MAX) {\n    *os << \"called at least \" << FormatTimes(min_);\n  } else {\n    // 0 < min_ < max_ < INT_MAX\n    *os << \"called between \" << min_ << \" and \" << max_ << \" times\";\n  }\n}\n\n}  // Unnamed namespace\n\n// Describes the given call count to an ostream.\nvoid Cardinality::DescribeActualCallCountTo(int actual_call_count,\n                                            ::std::ostream* os) {\n  if (actual_call_count > 0) {\n    *os << \"called \" << FormatTimes(actual_call_count);\n  } else {\n    *os << \"never called\";\n  }\n}\n\n// Creates a cardinality that allows at least n calls.\nGTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }\n\n// Creates a cardinality that allows at most n calls.\nGTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }\n\n// Creates a cardinality that allows any number of calls.\nGTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }\n\n// Creates a cardinality that allows between min and max calls.\nGTEST_API_ Cardinality Between(int min, int max) {\n  return Cardinality(new BetweenCardinalityImpl(min, max));\n}\n\n// Creates a cardinality that allows exactly n calls.\nGTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock-internal-utils.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file defines some utilities useful for implementing Google\n// Mock.  They are subject to change without notice, so please DO NOT\n// USE THEM IN USER CODE.\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n\n#include <ctype.h>\n\n#include <array>\n#include <cctype>\n#include <cstdint>\n#include <cstring>\n#include <iostream>\n#include <ostream>  // NOLINT\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"gmock/gmock.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\nnamespace internal {\n\n// Joins a vector of strings as if they are fields of a tuple; returns\n// the joined string.\nGTEST_API_ std::string JoinAsKeyValueTuple(\n    const std::vector<const char*>& names, const Strings& values) {\n  GTEST_CHECK_(names.size() == values.size());\n  if (values.empty()) {\n    return \"\";\n  }\n  const auto build_one = [&](const size_t i) {\n    return std::string(names[i]) + \": \" + values[i];\n  };\n  std::string result = \"(\" + build_one(0);\n  for (size_t i = 1; i < values.size(); i++) {\n    result += \", \";\n    result += build_one(i);\n  }\n  result += \")\";\n  return result;\n}\n\n// Converts an identifier name to a space-separated list of lower-case\n// words.  Each maximum substring of the form [A-Za-z][a-z]*|\\d+ is\n// treated as one word.  For example, both \"FooBar123\" and\n// \"foo_bar_123\" are converted to \"foo bar 123\".\nGTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {\n  std::string result;\n  char prev_char = '\\0';\n  for (const char* p = id_name; *p != '\\0'; prev_char = *(p++)) {\n    // We don't care about the current locale as the input is\n    // guaranteed to be a valid C++ identifier name.\n    const bool starts_new_word = IsUpper(*p) ||\n                                 (!IsAlpha(prev_char) && IsLower(*p)) ||\n                                 (!IsDigit(prev_char) && IsDigit(*p));\n\n    if (IsAlNum(*p)) {\n      if (starts_new_word && !result.empty()) result += ' ';\n      result += ToLower(*p);\n    }\n  }\n  return result;\n}\n\n// This class reports Google Mock failures as Google Test failures.  A\n// user can define another class in a similar fashion if they intend to\n// use Google Mock with a testing framework other than Google Test.\nclass GoogleTestFailureReporter : public FailureReporterInterface {\n public:\n  void ReportFailure(FailureType type, const char* file, int line,\n                     const std::string& message) override {\n    AssertHelper(type == kFatal ? TestPartResult::kFatalFailure\n                                : TestPartResult::kNonFatalFailure,\n                 file, line, message.c_str()) = Message();\n    if (type == kFatal) {\n      posix::Abort();\n    }\n  }\n};\n\n// Returns the global failure reporter.  Will create a\n// GoogleTestFailureReporter and return it the first time called.\nGTEST_API_ FailureReporterInterface* GetFailureReporter() {\n  // Points to the global failure reporter used by Google Mock.  gcc\n  // guarantees that the following use of failure_reporter is\n  // thread-safe.  We may need to add additional synchronization to\n  // protect failure_reporter if we port Google Mock to other\n  // compilers.\n  static FailureReporterInterface* const failure_reporter =\n      new GoogleTestFailureReporter();\n  return failure_reporter;\n}\n\n// Protects global resources (stdout in particular) used by Log().\nstatic GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);\n\n// Returns true if and only if a log with the given severity is visible\n// according to the --gmock_verbose flag.\nGTEST_API_ bool LogIsVisible(LogSeverity severity) {\n  if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {\n    // Always show the log if --gmock_verbose=info.\n    return true;\n  } else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {\n    // Always hide it if --gmock_verbose=error.\n    return false;\n  } else {\n    // If --gmock_verbose is neither \"info\" nor \"error\", we treat it\n    // as \"warning\" (its default value).\n    return severity == kWarning;\n  }\n}\n\n// Prints the given message to stdout if and only if 'severity' >= the level\n// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=\n// 0, also prints the stack trace excluding the top\n// stack_frames_to_skip frames.  In opt mode, any positive\n// stack_frames_to_skip is treated as 0, since we don't know which\n// function calls will be inlined by the compiler and need to be\n// conservative.\nGTEST_API_ void Log(LogSeverity severity, const std::string& message,\n                    int stack_frames_to_skip) {\n  if (!LogIsVisible(severity)) return;\n\n  // Ensures that logs from different threads don't interleave.\n  MutexLock l(&g_log_mutex);\n\n  if (severity == kWarning) {\n    // Prints a GMOCK WARNING marker to make the warnings easily searchable.\n    std::cout << \"\\nGMOCK WARNING:\";\n  }\n  // Pre-pends a new-line to message if it doesn't start with one.\n  if (message.empty() || message[0] != '\\n') {\n    std::cout << \"\\n\";\n  }\n  std::cout << message;\n  if (stack_frames_to_skip >= 0) {\n#ifdef NDEBUG\n    // In opt mode, we have to be conservative and skip no stack frame.\n    const int actual_to_skip = 0;\n#else\n    // In dbg mode, we can do what the caller tell us to do (plus one\n    // for skipping this function's stack frame).\n    const int actual_to_skip = stack_frames_to_skip + 1;\n#endif  // NDEBUG\n\n    // Appends a new-line to message if it doesn't end with one.\n    if (!message.empty() && *message.rbegin() != '\\n') {\n      std::cout << \"\\n\";\n    }\n    std::cout << \"Stack trace:\\n\"\n              << ::testing::internal::GetCurrentOsStackTraceExceptTop(\n                     actual_to_skip);\n  }\n  std::cout << ::std::flush;\n}\n\nGTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }\n\nGTEST_API_ void IllegalDoDefault(const char* file, int line) {\n  internal::Assert(\n      false, file, line,\n      \"You are using DoDefault() inside a composite action like \"\n      \"DoAll() or WithArgs().  This is not supported for technical \"\n      \"reasons.  Please instead spell out the default action, or \"\n      \"assign the default action to an Action variable and use \"\n      \"the variable in various places.\");\n}\n\nconstexpr char UndoWebSafeEncoding(char c) {\n  return c == '-' ? '+' : c == '_' ? '/' : c;\n}\n\nconstexpr char UnBase64Impl(char c, const char* const base64, char carry) {\n  return *base64 == 0 ? static_cast<char>(65)\n         : *base64 == c\n             ? carry\n             : UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1));\n}\n\ntemplate <size_t... I>\nconstexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,\n                                             const char* const base64) {\n  return {\n      {UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};\n}\n\nconstexpr std::array<char, 256> UnBase64(const char* const base64) {\n  return UnBase64Impl(std::make_index_sequence<256>{}, base64);\n}\n\nstatic constexpr char kBase64[] =\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nstatic constexpr std::array<char, 256> kUnBase64 = UnBase64(kBase64);\n\nbool Base64Unescape(const std::string& encoded, std::string* decoded) {\n  decoded->clear();\n  size_t encoded_len = encoded.size();\n  decoded->reserve(3 * (encoded_len / 4) + (encoded_len % 4));\n  int bit_pos = 0;\n  char dst = 0;\n  for (int src : encoded) {\n    if (std::isspace(src) || src == '=') {\n      continue;\n    }\n    char src_bin = kUnBase64[static_cast<size_t>(src)];\n    if (src_bin >= 64) {\n      decoded->clear();\n      return false;\n    }\n    if (bit_pos == 0) {\n      dst |= static_cast<char>(src_bin << 2);\n      bit_pos = 6;\n    } else {\n      dst |= static_cast<char>(src_bin >> (bit_pos - 2));\n      decoded->push_back(dst);\n      dst = static_cast<char>(src_bin << (10 - bit_pos));\n      bit_pos = (bit_pos + 6) % 8;\n    }\n  }\n  return true;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock-matchers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements Matcher<const string&>, Matcher<string>, and\n// utilities for defining matchers.\n\n#include \"gmock/gmock-matchers.h\"\n\n#include <string.h>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n\nnamespace testing {\nnamespace internal {\n\n// Returns the description for a matcher defined using the MATCHER*()\n// macro where the user-supplied description string is \"\", if\n// 'negation' is false; otherwise returns the description of the\n// negation of the matcher.  'param_values' contains a list of strings\n// that are the print-out of the matcher's parameters.\nGTEST_API_ std::string FormatMatcherDescription(\n    bool negation, const char* matcher_name,\n    const std::vector<const char*>& param_names, const Strings& param_values) {\n  std::string result = ConvertIdentifierNameToWords(matcher_name);\n  if (!param_values.empty()) {\n    result += \" \" + JoinAsKeyValueTuple(param_names, param_values);\n  }\n  return negation ? \"not (\" + result + \")\" : result;\n}\n\n// FindMaxBipartiteMatching and its helper class.\n//\n// Uses the well-known Ford-Fulkerson max flow method to find a maximum\n// bipartite matching. Flow is considered to be from left to right.\n// There is an implicit source node that is connected to all of the left\n// nodes, and an implicit sink node that is connected to all of the\n// right nodes. All edges have unit capacity.\n//\n// Neither the flow graph nor the residual flow graph are represented\n// explicitly. Instead, they are implied by the information in 'graph' and\n// a vector<int> called 'left_' whose elements are initialized to the\n// value kUnused. This represents the initial state of the algorithm,\n// where the flow graph is empty, and the residual flow graph has the\n// following edges:\n//   - An edge from source to each left_ node\n//   - An edge from each right_ node to sink\n//   - An edge from each left_ node to each right_ node, if the\n//     corresponding edge exists in 'graph'.\n//\n// When the TryAugment() method adds a flow, it sets left_[l] = r for some\n// nodes l and r. This induces the following changes:\n//   - The edges (source, l), (l, r), and (r, sink) are added to the\n//     flow graph.\n//   - The same three edges are removed from the residual flow graph.\n//   - The reverse edges (l, source), (r, l), and (sink, r) are added\n//     to the residual flow graph, which is a directional graph\n//     representing unused flow capacity.\n//\n// When the method augments a flow (moving left_[l] from some r1 to some\n// other r2), this can be thought of as \"undoing\" the above steps with\n// respect to r1 and \"redoing\" them with respect to r2.\n//\n// It bears repeating that the flow graph and residual flow graph are\n// never represented explicitly, but can be derived by looking at the\n// information in 'graph' and in left_.\n//\n// As an optimization, there is a second vector<int> called right_ which\n// does not provide any new information. Instead, it enables more\n// efficient queries about edges entering or leaving the right-side nodes\n// of the flow or residual flow graphs. The following invariants are\n// maintained:\n//\n// left[l] == kUnused or right[left[l]] == l\n// right[r] == kUnused or left[right[r]] == r\n//\n// . [ source ]                                        .\n// .   |||                                             .\n// .   |||                                             .\n// .   ||\\--> left[0]=1  ---\\    right[0]=-1 ----\\     .\n// .   ||                   |                    |     .\n// .   |\\---> left[1]=-1    \\--> right[1]=0  ---\\|     .\n// .   |                                        ||     .\n// .   \\----> left[2]=2  ------> right[2]=2  --\\||     .\n// .                                           |||     .\n// .         elements           matchers       vvv     .\n// .                                         [ sink ]  .\n//\n// See Also:\n//   [1] Cormen, et al (2001). \"Section 26.2: The Ford-Fulkerson method\".\n//       \"Introduction to Algorithms (Second ed.)\", pp. 651-664.\n//   [2] \"Ford-Fulkerson algorithm\", Wikipedia,\n//       'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'\nclass MaxBipartiteMatchState {\n public:\n  explicit MaxBipartiteMatchState(const MatchMatrix& graph)\n      : graph_(&graph),\n        left_(graph_->LhsSize(), kUnused),\n        right_(graph_->RhsSize(), kUnused) {}\n\n  // Returns the edges of a maximal match, each in the form {left, right}.\n  ElementMatcherPairs Compute() {\n    // 'seen' is used for path finding { 0: unseen, 1: seen }.\n    ::std::vector<char> seen;\n    // Searches the residual flow graph for a path from each left node to\n    // the sink in the residual flow graph, and if one is found, add flow\n    // to the graph. It's okay to search through the left nodes once. The\n    // edge from the implicit source node to each previously-visited left\n    // node will have flow if that left node has any path to the sink\n    // whatsoever. Subsequent augmentations can only add flow to the\n    // network, and cannot take away that previous flow unit from the source.\n    // Since the source-to-left edge can only carry one flow unit (or,\n    // each element can be matched to only one matcher), there is no need\n    // to visit the left nodes more than once looking for augmented paths.\n    // The flow is known to be possible or impossible by looking at the\n    // node once.\n    for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {\n      // Reset the path-marking vector and try to find a path from\n      // source to sink starting at the left_[ilhs] node.\n      GTEST_CHECK_(left_[ilhs] == kUnused)\n          << \"ilhs: \" << ilhs << \", left_[ilhs]: \" << left_[ilhs];\n      // 'seen' initialized to 'graph_->RhsSize()' copies of 0.\n      seen.assign(graph_->RhsSize(), 0);\n      TryAugment(ilhs, &seen);\n    }\n    ElementMatcherPairs result;\n    for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {\n      size_t irhs = left_[ilhs];\n      if (irhs == kUnused) continue;\n      result.push_back(ElementMatcherPair(ilhs, irhs));\n    }\n    return result;\n  }\n\n private:\n  static const size_t kUnused = static_cast<size_t>(-1);\n\n  // Perform a depth-first search from left node ilhs to the sink.  If a\n  // path is found, flow is added to the network by linking the left and\n  // right vector elements corresponding each segment of the path.\n  // Returns true if a path to sink was found, which means that a unit of\n  // flow was added to the network. The 'seen' vector elements correspond\n  // to right nodes and are marked to eliminate cycles from the search.\n  //\n  // Left nodes will only be explored at most once because they\n  // are accessible from at most one right node in the residual flow\n  // graph.\n  //\n  // Note that left_[ilhs] is the only element of left_ that TryAugment will\n  // potentially transition from kUnused to another value. Any other\n  // left_ element holding kUnused before TryAugment will be holding it\n  // when TryAugment returns.\n  //\n  bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {\n    for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {\n      if ((*seen)[irhs]) continue;\n      if (!graph_->HasEdge(ilhs, irhs)) continue;\n      // There's an available edge from ilhs to irhs.\n      (*seen)[irhs] = 1;\n      // Next a search is performed to determine whether\n      // this edge is a dead end or leads to the sink.\n      //\n      // right_[irhs] == kUnused means that there is residual flow from\n      // right node irhs to the sink, so we can use that to finish this\n      // flow path and return success.\n      //\n      // Otherwise there is residual flow to some ilhs. We push flow\n      // along that path and call ourselves recursively to see if this\n      // ultimately leads to sink.\n      if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {\n        // Add flow from left_[ilhs] to right_[irhs].\n        left_[ilhs] = irhs;\n        right_[irhs] = ilhs;\n        return true;\n      }\n    }\n    return false;\n  }\n\n  const MatchMatrix* graph_;  // not owned\n  // Each element of the left_ vector represents a left hand side node\n  // (i.e. an element) and each element of right_ is a right hand side\n  // node (i.e. a matcher). The values in the left_ vector indicate\n  // outflow from that node to a node on the right_ side. The values\n  // in the right_ indicate inflow, and specify which left_ node is\n  // feeding that right_ node, if any. For example, left_[3] == 1 means\n  // there's a flow from element #3 to matcher #1. Such a flow would also\n  // be redundantly represented in the right_ vector as right_[1] == 3.\n  // Elements of left_ and right_ are either kUnused or mutually\n  // referent. Mutually referent means that left_[right_[i]] = i and\n  // right_[left_[i]] = i.\n  ::std::vector<size_t> left_;\n  ::std::vector<size_t> right_;\n};\n\nconst size_t MaxBipartiteMatchState::kUnused;\n\nGTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {\n  return MaxBipartiteMatchState(g).Compute();\n}\n\nstatic void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,\n                                     ::std::ostream* stream) {\n  typedef ElementMatcherPairs::const_iterator Iter;\n  ::std::ostream& os = *stream;\n  os << \"{\";\n  const char* sep = \"\";\n  for (Iter it = pairs.begin(); it != pairs.end(); ++it) {\n    os << sep << \"\\n  (\" << \"element #\" << it->first << \", \" << \"matcher #\"\n       << it->second << \")\";\n    sep = \",\";\n  }\n  os << \"\\n}\";\n}\n\nbool MatchMatrix::NextGraph() {\n  for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {\n    for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {\n      char& b = matched_[SpaceIndex(ilhs, irhs)];\n      if (!b) {\n        b = 1;\n        return true;\n      }\n      b = 0;\n    }\n  }\n  return false;\n}\n\nvoid MatchMatrix::Randomize() {\n  for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {\n    for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {\n      char& b = matched_[SpaceIndex(ilhs, irhs)];\n      b = static_cast<char>(rand() & 1);  // NOLINT\n    }\n  }\n}\n\nstd::string MatchMatrix::DebugString() const {\n  ::std::stringstream ss;\n  const char* sep = \"\";\n  for (size_t i = 0; i < LhsSize(); ++i) {\n    ss << sep;\n    for (size_t j = 0; j < RhsSize(); ++j) {\n      ss << HasEdge(i, j);\n    }\n    sep = \";\";\n  }\n  return ss.str();\n}\n\nvoid UnorderedElementsAreMatcherImplBase::DescribeToImpl(\n    ::std::ostream* os) const {\n  switch (match_flags()) {\n    case UnorderedMatcherRequire::ExactMatch:\n      if (matcher_describers_.empty()) {\n        *os << \"is empty\";\n        return;\n      }\n      if (matcher_describers_.size() == 1) {\n        *os << \"has \" << Elements(1) << \" and that element \";\n        matcher_describers_[0]->DescribeTo(os);\n        return;\n      }\n      *os << \"has \" << Elements(matcher_describers_.size())\n          << \" and there exists some permutation of elements such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Superset:\n      *os << \"a surjection from elements to requirements exists such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Subset:\n      *os << \"an injection from elements to requirements exists such that:\\n\";\n      break;\n  }\n\n  const char* sep = \"\";\n  for (size_t i = 0; i != matcher_describers_.size(); ++i) {\n    *os << sep;\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      *os << \" - element #\" << i << \" \";\n    } else {\n      *os << \" - an element \";\n    }\n    matcher_describers_[i]->DescribeTo(os);\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      sep = \", and\\n\";\n    } else {\n      sep = \"\\n\";\n    }\n  }\n}\n\nvoid UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(\n    ::std::ostream* os) const {\n  switch (match_flags()) {\n    case UnorderedMatcherRequire::ExactMatch:\n      if (matcher_describers_.empty()) {\n        *os << \"isn't empty\";\n        return;\n      }\n      if (matcher_describers_.size() == 1) {\n        *os << \"doesn't have \" << Elements(1) << \", or has \" << Elements(1)\n            << \" that \";\n        matcher_describers_[0]->DescribeNegationTo(os);\n        return;\n      }\n      *os << \"doesn't have \" << Elements(matcher_describers_.size())\n          << \", or there exists no permutation of elements such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Superset:\n      *os << \"no surjection from elements to requirements exists such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Subset:\n      *os << \"no injection from elements to requirements exists such that:\\n\";\n      break;\n  }\n  const char* sep = \"\";\n  for (size_t i = 0; i != matcher_describers_.size(); ++i) {\n    *os << sep;\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      *os << \" - element #\" << i << \" \";\n    } else {\n      *os << \" - an element \";\n    }\n    matcher_describers_[i]->DescribeTo(os);\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      sep = \", and\\n\";\n    } else {\n      sep = \"\\n\";\n    }\n  }\n}\n\n// Checks that all matchers match at least one element, and that all\n// elements match at least one matcher. This enables faster matching\n// and better error reporting.\n// Returns false, writing an explanation to 'listener', if and only\n// if the success criteria are not met.\nbool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(\n    const ::std::vector<std::string>& element_printouts,\n    const MatchMatrix& matrix, MatchResultListener* listener) const {\n  if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {\n    return true;\n  }\n\n  const bool is_exact_match_with_size_discrepency =\n      match_flags() == UnorderedMatcherRequire::ExactMatch &&\n      matrix.LhsSize() != matrix.RhsSize();\n  if (is_exact_match_with_size_discrepency) {\n    // The element count doesn't match.  If the container is empty,\n    // there's no need to explain anything as Google Mock already\n    // prints the empty container. Otherwise we just need to show\n    // how many elements there actually are.\n    if (matrix.LhsSize() != 0 && listener->IsInterested()) {\n      *listener << \"which has \" << Elements(matrix.LhsSize()) << \"\\n\";\n    }\n  }\n\n  bool result = !is_exact_match_with_size_discrepency;\n  ::std::vector<char> element_matched(matrix.LhsSize(), 0);\n  ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);\n\n  for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {\n    for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {\n      char matched = matrix.HasEdge(ilhs, irhs);\n      element_matched[ilhs] |= matched;\n      matcher_matched[irhs] |= matched;\n    }\n  }\n\n  if (match_flags() & UnorderedMatcherRequire::Superset) {\n    const char* sep =\n        \"where the following matchers don't match any elements:\\n\";\n    for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {\n      if (matcher_matched[mi]) continue;\n      result = false;\n      if (listener->IsInterested()) {\n        *listener << sep << \"matcher #\" << mi << \": \";\n        matcher_describers_[mi]->DescribeTo(listener->stream());\n        sep = \",\\n\";\n      }\n    }\n  }\n\n  if (match_flags() & UnorderedMatcherRequire::Subset) {\n    const char* sep =\n        \"where the following elements don't match any matchers:\\n\";\n    const char* outer_sep = \"\";\n    if (!result) {\n      outer_sep = \"\\nand \";\n    }\n    for (size_t ei = 0; ei < element_matched.size(); ++ei) {\n      if (element_matched[ei]) continue;\n      result = false;\n      if (listener->IsInterested()) {\n        *listener << outer_sep << sep << \"element #\" << ei << \": \"\n                  << element_printouts[ei];\n        sep = \",\\n\";\n        outer_sep = \"\";\n      }\n    }\n  }\n  return result;\n}\n\nbool UnorderedElementsAreMatcherImplBase::FindPairing(\n    const MatchMatrix& matrix, MatchResultListener* listener) const {\n  ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);\n\n  size_t max_flow = matches.size();\n  if ((match_flags() & UnorderedMatcherRequire::Superset) &&\n      max_flow < matrix.RhsSize()) {\n    if (listener->IsInterested()) {\n      *listener << \"where no permutation of the elements can satisfy all \"\n                   \"matchers, and the closest match is \"\n                << max_flow << \" of \" << matrix.RhsSize()\n                << \" matchers with the pairings:\\n\";\n      LogElementMatcherPairVec(matches, listener->stream());\n    }\n    return false;\n  }\n  if ((match_flags() & UnorderedMatcherRequire::Subset) &&\n      max_flow < matrix.LhsSize()) {\n    if (listener->IsInterested()) {\n      *listener\n          << \"where not all elements can be matched, and the closest match is \"\n          << max_flow << \" of \" << matrix.RhsSize()\n          << \" matchers with the pairings:\\n\";\n      LogElementMatcherPairVec(matches, listener->stream());\n    }\n    return false;\n  }\n\n  if (matches.size() > 1) {\n    if (listener->IsInterested()) {\n      const char* sep = \"where:\\n\";\n      for (size_t mi = 0; mi < matches.size(); ++mi) {\n        *listener << sep << \" - element #\" << matches[mi].first\n                  << \" is matched by matcher #\" << matches[mi].second;\n        sep = \",\\n\";\n      }\n    }\n  }\n  return true;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock-spec-builders.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements the spec builder syntax (ON_CALL and\n// EXPECT_CALL).\n\n#include \"gmock/gmock-spec-builders.h\"\n\n#include <stdlib.h>\n\n#include <iostream>  // NOLINT\n#include <map>\n#include <memory>\n#include <set>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\n#include \"gmock/gmock.h\"\n#include \"gtest/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)\n#include <unistd.h>  // NOLINT\n#endif\n#ifdef GTEST_OS_QURT\n#include <qurt_event.h>\n#endif\n\n// Silence C4800 (C4800: 'int *const ': forcing value\n// to bool 'true' or 'false') for MSVC 15\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)\n#endif\n\nnamespace testing {\nnamespace internal {\n\n// Protects the mock object registry (in class Mock), all function\n// mockers, and all expectations.\nGTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);\n\n// Logs a message including file and line number information.\nGTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,\n                                const char* file, int line,\n                                const std::string& message) {\n  ::std::ostringstream s;\n  s << internal::FormatFileLocation(file, line) << \" \" << message\n    << ::std::endl;\n  Log(severity, s.str(), 0);\n}\n\n// Constructs an ExpectationBase object.\nExpectationBase::ExpectationBase(const char* a_file, int a_line,\n                                 const std::string& a_source_text)\n    : file_(a_file),\n      line_(a_line),\n      source_text_(a_source_text),\n      cardinality_specified_(false),\n      cardinality_(Exactly(1)),\n      call_count_(0),\n      retired_(false),\n      extra_matcher_specified_(false),\n      repeated_action_specified_(false),\n      retires_on_saturation_(false),\n      last_clause_(kNone),\n      action_count_checked_(false) {}\n\n// Destructs an ExpectationBase object.\nExpectationBase::~ExpectationBase() = default;\n\n// Explicitly specifies the cardinality of this expectation.  Used by\n// the subclasses to implement the .Times() clause.\nvoid ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {\n  cardinality_specified_ = true;\n  cardinality_ = a_cardinality;\n}\n\n// Retires all pre-requisites of this expectation.\nvoid ExpectationBase::RetireAllPreRequisites()\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  if (is_retired()) {\n    // We can take this short-cut as we never retire an expectation\n    // until we have retired all its pre-requisites.\n    return;\n  }\n\n  ::std::vector<ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      ExpectationBase* next = it->expectation_base().get();\n      if (!next->is_retired()) {\n        next->Retire();\n        expectations.push_back(next);\n      }\n    }\n  }\n}\n\n// Returns true if and only if all pre-requisites of this expectation\n// have been satisfied.\nbool ExpectationBase::AllPrerequisitesAreSatisfied() const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  ::std::vector<const ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    const ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      const ExpectationBase* next = it->expectation_base().get();\n      if (!next->IsSatisfied()) return false;\n      expectations.push_back(next);\n    }\n  }\n  return true;\n}\n\n// Adds unsatisfied pre-requisites of this expectation to 'result'.\nvoid ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  ::std::vector<const ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    const ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      const ExpectationBase* next = it->expectation_base().get();\n\n      if (next->IsSatisfied()) {\n        // If *it is satisfied and has a call count of 0, some of its\n        // pre-requisites may not be satisfied yet.\n        if (next->call_count_ == 0) {\n          expectations.push_back(next);\n        }\n      } else {\n        // Now that we know next is unsatisfied, we are not so interested\n        // in whether its pre-requisites are satisfied.  Therefore we\n        // don't iterate into it here.\n        *result += *it;\n      }\n    }\n  }\n}\n\n// Describes how many times a function call matching this\n// expectation has occurred.\nvoid ExpectationBase::DescribeCallCountTo(::std::ostream* os) const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n\n  // Describes how many times the function is expected to be called.\n  *os << \"         Expected: to be \";\n  cardinality().DescribeTo(os);\n  *os << \"\\n           Actual: \";\n  Cardinality::DescribeActualCallCountTo(call_count(), os);\n\n  // Describes the state of the expectation (e.g. is it satisfied?\n  // is it active?).\n  *os << \" - \"\n      << (IsOverSaturated() ? \"over-saturated\"\n          : IsSaturated()   ? \"saturated\"\n          : IsSatisfied()   ? \"satisfied\"\n                            : \"unsatisfied\")\n      << \" and \" << (is_retired() ? \"retired\" : \"active\");\n}\n\n// Checks the action count (i.e. the number of WillOnce() and\n// WillRepeatedly() clauses) against the cardinality if this hasn't\n// been done before.  Prints a warning if there are too many or too\n// few actions.\nvoid ExpectationBase::CheckActionCountIfNotDone() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  bool should_check = false;\n  {\n    MutexLock l(&mutex_);\n    if (!action_count_checked_) {\n      action_count_checked_ = true;\n      should_check = true;\n    }\n  }\n\n  if (should_check) {\n    if (!cardinality_specified_) {\n      // The cardinality was inferred - no need to check the action\n      // count against it.\n      return;\n    }\n\n    // The cardinality was explicitly specified.\n    const int action_count = static_cast<int>(untyped_actions_.size());\n    const int upper_bound = cardinality().ConservativeUpperBound();\n    const int lower_bound = cardinality().ConservativeLowerBound();\n    bool too_many;  // True if there are too many actions, or false\n    // if there are too few.\n    if (action_count > upper_bound ||\n        (action_count == upper_bound && repeated_action_specified_)) {\n      too_many = true;\n    } else if (0 < action_count && action_count < lower_bound &&\n               !repeated_action_specified_) {\n      too_many = false;\n    } else {\n      return;\n    }\n\n    ::std::stringstream ss;\n    DescribeLocationTo(&ss);\n    ss << \"Too \" << (too_many ? \"many\" : \"few\") << \" actions specified in \"\n       << source_text() << \"...\\n\"\n       << \"Expected to be \";\n    cardinality().DescribeTo(&ss);\n    ss << \", but has \" << (too_many ? \"\" : \"only \") << action_count\n       << \" WillOnce()\" << (action_count == 1 ? \"\" : \"s\");\n    if (repeated_action_specified_) {\n      ss << \" and a WillRepeatedly()\";\n    }\n    ss << \".\";\n    Log(kWarning, ss.str(), -1);  // -1 means \"don't print stack trace\".\n  }\n}\n\n// Implements the .Times() clause.\nvoid ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {\n  if (last_clause_ == kTimes) {\n    ExpectSpecProperty(false,\n                       \".Times() cannot appear \"\n                       \"more than once in an EXPECT_CALL().\");\n  } else {\n    ExpectSpecProperty(\n        last_clause_ < kTimes,\n        \".Times() may only appear *before* .InSequence(), .WillOnce(), \"\n        \".WillRepeatedly(), or .RetiresOnSaturation(), not after.\");\n  }\n  last_clause_ = kTimes;\n\n  SpecifyCardinality(a_cardinality);\n}\n\n// Points to the implicit sequence introduced by a living InSequence\n// object (if any) in the current thread or NULL.\nGTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;\n\n// Reports an uninteresting call (whose description is in msg) in the\n// manner specified by 'reaction'.\nvoid ReportUninterestingCall(CallReaction reaction, const std::string& msg) {\n  // Include a stack trace only if --gmock_verbose=info is specified.\n  const int stack_frames_to_skip =\n      GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;\n  switch (reaction) {\n    case kAllow:\n      Log(kInfo, msg, stack_frames_to_skip);\n      break;\n    case kWarn:\n      Log(kWarning,\n          msg +\n              \"\\nNOTE: You can safely ignore the above warning unless this \"\n              \"call should not happen.  Do not suppress it by blindly adding \"\n              \"an EXPECT_CALL() if you don't mean to enforce the call.  \"\n              \"See \"\n              \"https://github.com/google/googletest/blob/main/docs/\"\n              \"gmock_cook_book.md#\"\n              \"knowing-when-to-expect-useoncall for details.\\n\",\n          stack_frames_to_skip);\n      break;\n    default:  // FAIL\n      Expect(false, nullptr, -1, msg);\n  }\n}\n\nUntypedFunctionMockerBase::UntypedFunctionMockerBase()\n    : mock_obj_(nullptr), name_(\"\") {}\n\nUntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;\n\n// Sets the mock object this mock method belongs to, and registers\n// this information in the global mock registry.  Will be called\n// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock\n// method.\nvoid UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  {\n    MutexLock l(&g_gmock_mutex);\n    mock_obj_ = mock_obj;\n  }\n  Mock::Register(mock_obj, this);\n}\n\n// Sets the mock object this mock method belongs to, and sets the name\n// of the mock function.  Will be called upon each invocation of this\n// mock function.\nvoid UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,\n                                                const char* name)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  // We protect name_ under g_gmock_mutex in case this mock function\n  // is called from two threads concurrently.\n  MutexLock l(&g_gmock_mutex);\n  mock_obj_ = mock_obj;\n  name_ = name;\n}\n\n// Returns the name of the function being mocked.  Must be called\n// after RegisterOwner() or SetOwnerAndName() has been called.\nconst void* UntypedFunctionMockerBase::MockObject() const\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  const void* mock_obj;\n  {\n    // We protect mock_obj_ under g_gmock_mutex in case this mock\n    // function is called from two threads concurrently.\n    MutexLock l(&g_gmock_mutex);\n    Assert(mock_obj_ != nullptr, __FILE__, __LINE__,\n           \"MockObject() must not be called before RegisterOwner() or \"\n           \"SetOwnerAndName() has been called.\");\n    mock_obj = mock_obj_;\n  }\n  return mock_obj;\n}\n\n// Returns the name of this mock method.  Must be called after\n// SetOwnerAndName() has been called.\nconst char* UntypedFunctionMockerBase::Name() const\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  const char* name;\n  {\n    // We protect name_ under g_gmock_mutex in case this mock\n    // function is called from two threads concurrently.\n    MutexLock l(&g_gmock_mutex);\n    Assert(name_ != nullptr, __FILE__, __LINE__,\n           \"Name() must not be called before SetOwnerAndName() has \"\n           \"been called.\");\n    name = name_;\n  }\n  return name;\n}\n\n// Returns an Expectation object that references and co-owns exp,\n// which must be an expectation on this mock function.\nExpectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {\n  // See the definition of untyped_expectations_ for why access to it\n  // is unprotected here.\n  for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();\n       it != untyped_expectations_.end(); ++it) {\n    if (it->get() == exp) {\n      return Expectation(*it);\n    }\n  }\n\n  Assert(false, __FILE__, __LINE__, \"Cannot find expectation.\");\n  return Expectation();\n  // The above statement is just to make the code compile, and will\n  // never be executed.\n}\n\n// Verifies that all expectations on this mock function have been\n// satisfied.  Reports one or more Google Test non-fatal failures\n// and returns false if not.\nbool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  bool expectations_met = true;\n  for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();\n       it != untyped_expectations_.end(); ++it) {\n    ExpectationBase* const untyped_expectation = it->get();\n    if (untyped_expectation->IsOverSaturated()) {\n      // There was an upper-bound violation.  Since the error was\n      // already reported when it occurred, there is no need to do\n      // anything here.\n      expectations_met = false;\n    } else if (!untyped_expectation->IsSatisfied()) {\n      expectations_met = false;\n      ::std::stringstream ss;\n\n      const ::std::string& expectation_name =\n          untyped_expectation->GetDescription();\n      ss << \"Actual function \";\n      if (!expectation_name.empty()) {\n        ss << \"\\\"\" << expectation_name << \"\\\" \";\n      }\n      ss << \"call count doesn't match \" << untyped_expectation->source_text()\n         << \"...\\n\";\n      // No need to show the source file location of the expectation\n      // in the description, as the Expect() call that follows already\n      // takes care of it.\n      untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);\n      untyped_expectation->DescribeCallCountTo(&ss);\n      Expect(false, untyped_expectation->file(), untyped_expectation->line(),\n             ss.str());\n    }\n  }\n\n  // Deleting our expectations may trigger other mock objects to be deleted, for\n  // example if an action contains a reference counted smart pointer to that\n  // mock object, and that is the last reference. So if we delete our\n  // expectations within the context of the global mutex we may deadlock when\n  // this method is called again. Instead, make a copy of the set of\n  // expectations to delete, clear our set within the mutex, and then clear the\n  // copied set outside of it.\n  UntypedExpectations expectations_to_delete;\n  untyped_expectations_.swap(expectations_to_delete);\n\n  g_gmock_mutex.Unlock();\n  expectations_to_delete.clear();\n  g_gmock_mutex.Lock();\n\n  return expectations_met;\n}\n\nstatic CallReaction intToCallReaction(int mock_behavior) {\n  if (mock_behavior >= kAllow && mock_behavior <= kFail) {\n    return static_cast<internal::CallReaction>(mock_behavior);\n  }\n  return kWarn;\n}\n\n}  // namespace internal\n\n// Class Mock.\n\nnamespace {\n\ntypedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;\n\n// The current state of a mock object.  Such information is needed for\n// detecting leaked mock objects and explicitly verifying a mock's\n// expectations.\nstruct MockObjectState {\n  MockObjectState()\n      : first_used_file(nullptr), first_used_line(-1), leakable(false) {}\n\n  // Where in the source file an ON_CALL or EXPECT_CALL is first\n  // invoked on this mock object.\n  const char* first_used_file;\n  int first_used_line;\n  ::std::string first_used_test_suite;\n  ::std::string first_used_test;\n  bool leakable;  // true if and only if it's OK to leak the object.\n  FunctionMockers function_mockers;  // All registered methods of the object.\n};\n\n// A global registry holding the state of all mock objects that are\n// alive.  A mock object is added to this registry the first time\n// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it.  It\n// is removed from the registry in the mock object's destructor.\nclass MockObjectRegistry {\n public:\n  // Maps a mock object (identified by its address) to its state.\n  typedef std::map<const void*, MockObjectState> StateMap;\n\n  // This destructor will be called when a program exits, after all\n  // tests in it have been run.  By then, there should be no mock\n  // object alive.  Therefore we report any living object as test\n  // failure, unless the user explicitly asked us to ignore it.\n  ~MockObjectRegistry() {\n    if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;\n    internal::MutexLock l(&internal::g_gmock_mutex);\n\n    int leaked_count = 0;\n    for (StateMap::const_iterator it = states_.begin(); it != states_.end();\n         ++it) {\n      if (it->second.leakable)  // The user said it's fine to leak this object.\n        continue;\n\n      // FIXME: Print the type of the leaked object.\n      // This can help the user identify the leaked object.\n      std::cout << \"\\n\";\n      const MockObjectState& state = it->second;\n      std::cout << internal::FormatFileLocation(state.first_used_file,\n                                                state.first_used_line);\n      std::cout << \" ERROR: this mock object\";\n      if (!state.first_used_test.empty()) {\n        std::cout << \" (used in test \" << state.first_used_test_suite << \".\"\n                  << state.first_used_test << \")\";\n      }\n      std::cout << \" should be deleted but never is. Its address is @\"\n                << it->first << \".\";\n      leaked_count++;\n    }\n    if (leaked_count > 0) {\n      std::cout << \"\\nERROR: \" << leaked_count << \" leaked mock \"\n                << (leaked_count == 1 ? \"object\" : \"objects\")\n                << \" found at program exit. Expectations on a mock object are \"\n                   \"verified when the object is destructed. Leaking a mock \"\n                   \"means that its expectations aren't verified, which is \"\n                   \"usually a test bug. If you really intend to leak a mock, \"\n                   \"you can suppress this error using \"\n                   \"testing::Mock::AllowLeak(mock_object), or you may use a \"\n                   \"fake or stub instead of a mock.\\n\";\n      std::cout.flush();\n      ::std::cerr.flush();\n      // RUN_ALL_TESTS() has already returned when this destructor is\n      // called.  Therefore we cannot use the normal Google Test\n      // failure reporting mechanism.\n#ifdef GTEST_OS_QURT\n      qurt_exception_raise_fatal();\n#else\n      _Exit(1);  // We cannot call exit() as it is not reentrant and\n                 // may already have been called.\n#endif\n    }\n  }\n\n  StateMap& states() { return states_; }\n\n private:\n  StateMap states_;\n};\n\n// Protected by g_gmock_mutex.\nMockObjectRegistry g_mock_object_registry;\n\n// Maps a mock object to the reaction Google Mock should have when an\n// uninteresting method is called.  Protected by g_gmock_mutex.\nstd::unordered_map<uintptr_t, internal::CallReaction>&\nUninterestingCallReactionMap() {\n  static auto* map = new std::unordered_map<uintptr_t, internal::CallReaction>;\n  return *map;\n}\n\n// Sets the reaction Google Mock should have when an uninteresting\n// method of the given mock object is called.\nvoid SetReactionOnUninterestingCalls(uintptr_t mock_obj,\n                                     internal::CallReaction reaction)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  UninterestingCallReactionMap()[mock_obj] = reaction;\n}\n\n}  // namespace\n\n// Tells Google Mock to allow uninteresting calls on the given mock\n// object.\nvoid Mock::AllowUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);\n}\n\n// Tells Google Mock to warn the user about uninteresting calls on the\n// given mock object.\nvoid Mock::WarnUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);\n}\n\n// Tells Google Mock to fail uninteresting calls on the given mock\n// object.\nvoid Mock::FailUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kFail);\n}\n\n// Tells Google Mock the given mock object is being destroyed and its\n// entry in the call-reaction table should be removed.\nvoid Mock::UnregisterCallReaction(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));\n}\n\n// Returns the reaction Google Mock will have on uninteresting calls\n// made on the given mock object.\ninternal::CallReaction Mock::GetReactionOnUninterestingCalls(\n    const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  return (UninterestingCallReactionMap().count(\n              reinterpret_cast<uintptr_t>(mock_obj)) == 0)\n             ? internal::intToCallReaction(\n                   GMOCK_FLAG_GET(default_mock_behavior))\n             : UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>(\n                   mock_obj)];\n}\n\n// Tells Google Mock to ignore mock_obj when checking for leaked mock\n// objects.\nvoid Mock::AllowLeak(const void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  g_mock_object_registry.states()[mock_obj].leakable = true;\n}\n\n// Verifies and clears all expectations on the given mock object.  If\n// the expectations aren't satisfied, generates one or more Google\n// Test non-fatal failures and returns false.\nbool Mock::VerifyAndClearExpectations(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  return VerifyAndClearExpectationsLocked(mock_obj);\n}\n\n// Verifies all expectations on the given mock object and clears its\n// default actions and expectations.  Returns true if and only if the\n// verification was successful.\nbool Mock::VerifyAndClear(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  ClearDefaultActionsLocked(mock_obj);\n  return VerifyAndClearExpectationsLocked(mock_obj);\n}\n\n// Verifies and clears all expectations on the given mock object.  If\n// the expectations aren't satisfied, generates one or more Google\n// Test non-fatal failures and returns false.\nbool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n  if (g_mock_object_registry.states().count(mock_obj) == 0) {\n    // No EXPECT_CALL() was set on the given mock object.\n    return true;\n  }\n\n  // Verifies and clears the expectations on each mock method in the\n  // given mock object.\n  bool expectations_met = true;\n  FunctionMockers& mockers =\n      g_mock_object_registry.states()[mock_obj].function_mockers;\n  for (FunctionMockers::const_iterator it = mockers.begin();\n       it != mockers.end(); ++it) {\n    if (!(*it)->VerifyAndClearExpectationsLocked()) {\n      expectations_met = false;\n    }\n  }\n\n  // We don't clear the content of mockers, as they may still be\n  // needed by ClearDefaultActionsLocked().\n  return expectations_met;\n}\n\nbool Mock::IsNaggy(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;\n}\nbool Mock::IsNice(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;\n}\nbool Mock::IsStrict(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;\n}\n\n// Registers a mock object and a mock method it owns.\nvoid Mock::Register(const void* mock_obj,\n                    internal::UntypedFunctionMockerBase* mocker)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);\n}\n\n// Tells Google Mock where in the source code mock_obj is used in an\n// ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this\n// information helps the user identify which object it is.\nvoid Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,\n                                           const char* file, int line)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  MockObjectState& state = g_mock_object_registry.states()[mock_obj];\n  if (state.first_used_file == nullptr) {\n    state.first_used_file = file;\n    state.first_used_line = line;\n    const TestInfo* const test_info =\n        UnitTest::GetInstance()->current_test_info();\n    if (test_info != nullptr) {\n      state.first_used_test_suite = test_info->test_suite_name();\n      state.first_used_test = test_info->name();\n    }\n  }\n}\n\n// Unregisters a mock method; removes the owning mock object from the\n// registry when the last mock method associated with it has been\n// unregistered.  This is called only in the destructor of\n// FunctionMockerBase.\nvoid Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n  for (MockObjectRegistry::StateMap::iterator it =\n           g_mock_object_registry.states().begin();\n       it != g_mock_object_registry.states().end(); ++it) {\n    FunctionMockers& mockers = it->second.function_mockers;\n    if (mockers.erase(mocker) > 0) {\n      // mocker was in mockers and has been just removed.\n      if (mockers.empty()) {\n        g_mock_object_registry.states().erase(it);\n      }\n      return;\n    }\n  }\n}\n\n// Clears all ON_CALL()s set on the given mock object.\nvoid Mock::ClearDefaultActionsLocked(void* mock_obj)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n\n  if (g_mock_object_registry.states().count(mock_obj) == 0) {\n    // No ON_CALL() was set on the given mock object.\n    return;\n  }\n\n  // Clears the default actions for each mock method in the given mock\n  // object.\n  FunctionMockers& mockers =\n      g_mock_object_registry.states()[mock_obj].function_mockers;\n  for (FunctionMockers::const_iterator it = mockers.begin();\n       it != mockers.end(); ++it) {\n    (*it)->ClearDefaultActionsLocked();\n  }\n\n  // We don't clear the content of mockers, as they may still be\n  // needed by VerifyAndClearExpectationsLocked().\n}\n\nExpectation::Expectation() = default;\n\nExpectation::Expectation(\n    const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)\n    : expectation_base_(an_expectation_base) {}\n\nExpectation::~Expectation() = default;\n\n// Adds an expectation to a sequence.\nvoid Sequence::AddExpectation(const Expectation& expectation) const {\n  if (*last_expectation_ != expectation) {\n    if (last_expectation_->expectation_base() != nullptr) {\n      expectation.expectation_base()->immediate_prerequisites_ +=\n          *last_expectation_;\n    }\n    *last_expectation_ = expectation;\n  }\n}\n\n// Creates the implicit sequence if there isn't one.\nInSequence::InSequence() {\n  if (internal::g_gmock_implicit_sequence.get() == nullptr) {\n    internal::g_gmock_implicit_sequence.set(new Sequence);\n    sequence_created_ = true;\n  } else {\n    sequence_created_ = false;\n  }\n}\n\n// Deletes the implicit sequence if it was created by the constructor\n// of this object.\nInSequence::~InSequence() {\n  if (sequence_created_) {\n    delete internal::g_gmock_implicit_sequence.get();\n    internal::g_gmock_implicit_sequence.set(nullptr);\n  }\n}\n\n}  // namespace testing\n\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4800\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gmock/gmock.h\"\n\n#include <string>\n\n#include \"gmock/internal/gmock-port.h\"\n\nGMOCK_DEFINE_bool_(catch_leaked_mocks, true,\n                   \"true if and only if Google Mock should report leaked \"\n                   \"mock objects as failures.\");\n\nGMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,\n                     \"Controls how verbose Google Mock's output is.\"\n                     \"  Valid values:\\n\"\n                     \"  info    - prints all messages.\\n\"\n                     \"  warning - prints warnings and errors.\\n\"\n                     \"  error   - prints errors only.\");\n\nGMOCK_DEFINE_int32_(default_mock_behavior, 1,\n                    \"Controls the default behavior of mocks.\"\n                    \"  Valid values:\\n\"\n                    \"  0 - by default, mocks act as NiceMocks.\\n\"\n                    \"  1 - by default, mocks act as NaggyMocks.\\n\"\n                    \"  2 - by default, mocks act as StrictMocks.\");\n\nnamespace testing {\nnamespace internal {\n\n// Parses a string as a command line flag.  The string should have the\n// format \"--gmock_flag=value\".  When def_optional is true, the\n// \"=value\" part can be omitted.\n//\n// Returns the value of the flag, or NULL if the parsing failed.\nstatic const char* ParseGoogleMockFlagValue(const char* str,\n                                            const char* flag_name,\n                                            bool def_optional) {\n  // str and flag must not be NULL.\n  if (str == nullptr || flag_name == nullptr) return nullptr;\n\n  // The flag must start with \"--gmock_\".\n  const std::string flag_name_str = std::string(\"--gmock_\") + flag_name;\n  const size_t flag_name_len = flag_name_str.length();\n  if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_name_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) {\n    return flag_end;\n  }\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\n// Parses a string for a Google Mock bool flag, in the form of\n// \"--gmock_flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\n  return true;\n}\n\n// Parses a string for a Google Mock string flag, in the form of\n// \"--gmock_flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\ntemplate <typename String>\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                String* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  *value = value_str;\n  return true;\n}\n\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(Message() << \"The value of flag --\" << flag_name, value_str,\n                    value);\n}\n\n// The internal implementation of InitGoogleMock().\n//\n// The type parameter CharType can be instantiated to either char or\n// wchar_t.\ntemplate <typename CharType>\nvoid InitGoogleMockImpl(int* argc, CharType** argv) {\n  // Makes sure Google Test is initialized.  InitGoogleTest() is\n  // idempotent, so it's fine if the user has already called it.\n  InitGoogleTest(argc, argv);\n  if (*argc <= 0) return;\n\n  for (int i = 1; i != *argc; i++) {\n    const std::string arg_string = StreamableToString(argv[i]);\n    const char* const arg = arg_string.c_str();\n\n    // Do we see a Google Mock flag?\n    bool found_gmock_flag = false;\n\n#define GMOCK_INTERNAL_PARSE_FLAG(flag_name)            \\\n  if (!found_gmock_flag) {                              \\\n    auto value = GMOCK_FLAG_GET(flag_name);             \\\n    if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \\\n      GMOCK_FLAG_SET(flag_name, value);                 \\\n      found_gmock_flag = true;                          \\\n    }                                                   \\\n  }\n\n    GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks)\n    GMOCK_INTERNAL_PARSE_FLAG(verbose)\n    GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior)\n\n    if (found_gmock_flag) {\n      // Yes.  Shift the remainder of the argv list left by one.  Note\n      // that argv has (*argc + 1) elements, the last one always being\n      // NULL.  The following loop moves the trailing NULL element as\n      // well.\n      for (int j = i; j != *argc; j++) {\n        argv[j] = argv[j + 1];\n      }\n\n      // Decrements the argument count.\n      (*argc)--;\n\n      // We also need to decrement the iterator as we just removed\n      // an element.\n      i--;\n    }\n  }\n}\n\n}  // namespace internal\n\n// Initializes Google Mock.  This must be called before running the\n// tests.  In particular, it parses a command line for the flags that\n// Google Mock recognizes.  Whenever a Google Mock flag is seen, it is\n// removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Mock flag variables are\n// updated.\n//\n// Since Google Test is needed for Google Mock to work, this function\n// also initializes Google Test and parses its flags, if that hasn't\n// been done.\nGTEST_API_ void InitGoogleMock(int* argc, char** argv) {\n  internal::InitGoogleMockImpl(argc, argv);\n}\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {\n  internal::InitGoogleMockImpl(argc, argv);\n}\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleMock() {\n  // Since Arduino doesn't have a command line, fake out the argc/argv arguments\n  int argc = 1;\n  const auto arg0 = \"dummy\";\n  char* argv0 = const_cast<char*>(arg0);\n  char** argv = &argv0;\n\n  internal::InitGoogleMockImpl(&argc, argv);\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googlemock/src/gmock_main.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include <iostream>\n\n#include \"gmock/gmock.h\"\n#include \"gtest/gtest.h\"\n\n#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \\\n    (defined(GTEST_OS_NRF52) && defined(ARDUINO))\n#ifdef GTEST_OS_ESP8266\nextern \"C\" {\n#endif\nvoid setup() {\n  // Since Google Mock depends on Google Test, InitGoogleMock() is\n  // also responsible for initializing Google Test.  Therefore there's\n  // no need for calling testing::InitGoogleTest() separately.\n  testing::InitGoogleMock();\n}\nvoid loop() { RUN_ALL_TESTS(); }\n#ifdef GTEST_OS_ESP8266\n}\n#endif\n\n#else\n\n// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which\n// causes a link error when _tmain is defined in a static library and UNICODE\n// is enabled. For this reason instead of _tmain, main function is used on\n// Windows. See the following link to track the current status of this bug:\n// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library\n// // NOLINT\n#ifdef GTEST_OS_WINDOWS_MOBILE\n#include <tchar.h>  // NOLINT\n\nGTEST_API_ int _tmain(int argc, TCHAR** argv) {\n#else\nGTEST_API_ int main(int argc, char** argv) {\n#endif  // GTEST_OS_WINDOWS_MOBILE\n  std::cout << \"Running main() from gmock_main.cc\\n\";\n  // Since Google Mock depends on Google Test, InitGoogleMock() is\n  // also responsible for initializing Google Test.  Therefore there's\n  // no need for calling testing::InitGoogleTest() separately.\n  testing::InitGoogleMock(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/CMakeLists.txt",
    "content": "########################################################################\n# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n#\n# CMake build script for Google Test.\n#\n# To run the tests for Google Test itself on Linux, use 'make test' or\n# ctest. You can select which tests to run using 'ctest -R regex'.\n# For more options, run 'ctest --help'.\n\n# When other libraries are using a shared version of runtime libraries,\n# Google Test also has to use one.\noption(\n  gtest_force_shared_crt\n  \"Use shared (DLL) run-time lib even when Google Test is built as static lib.\"\n  OFF)\n\noption(gtest_build_tests \"Build all of gtest's own tests.\" OFF)\n\noption(gtest_build_samples \"Build gtest's sample programs.\" OFF)\n\noption(gtest_disable_pthreads \"Disable uses of pthreads in gtest.\" OFF)\n\noption(\n  gtest_hide_internal_symbols\n  \"Build gtest with internal symbols hidden in shared libraries.\"\n  OFF)\n\n# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().\ninclude(cmake/hermetic_build.cmake OPTIONAL)\n\nif (COMMAND pre_project_set_up_hermetic_build)\n  pre_project_set_up_hermetic_build()\nendif()\n\n########################################################################\n#\n# Project-wide settings.\n\n# Name of the project.\n#\n# CMake files in this project can refer to the root source directory\n# as ${gtest_SOURCE_DIR} and to the root binary directory as\n# ${gtest_BINARY_DIR}.\n# Language \"C\" is required for find_package(Threads).\n\n# Project version.\n\ncmake_minimum_required(VERSION 3.13)\nproject(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)\n\nif (COMMAND set_up_hermetic_build)\n  set_up_hermetic_build()\nendif()\n\n# These commands only run if this is the main project.\nif(CMAKE_PROJECT_NAME STREQUAL \"gtest\" OR CMAKE_PROJECT_NAME STREQUAL \"googletest-distribution\")\n\n  # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to\n  # make it prominent in the GUI.\n  option(BUILD_SHARED_LIBS \"Build shared libraries (DLLs).\" OFF)\n\nelse()\n\n  mark_as_advanced(\n    gtest_force_shared_crt\n    gtest_build_tests\n    gtest_build_samples\n    gtest_disable_pthreads\n    gtest_hide_internal_symbols)\n\nendif()\n\n\nif (gtest_hide_internal_symbols)\n  set(CMAKE_CXX_VISIBILITY_PRESET hidden)\n  set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)\nendif()\n\n# Define helper functions and macros used by Google Test.\ninclude(cmake/internal_utils.cmake)\n\nconfig_compiler_and_linker()  # Defined in internal_utils.cmake.\n\n# Needed to set the namespace for both the export targets and the\n# alias libraries.\nset(cmake_package_name GTest CACHE INTERNAL \"\")\n\n# Create the CMake package file descriptors.\nif (INSTALL_GTEST)\n  include(CMakePackageConfigHelpers)\n  set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL \"\")\n  set(generated_dir \"${CMAKE_CURRENT_BINARY_DIR}/generated\" CACHE INTERNAL \"\")\n  set(cmake_files_install_dir \"${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}\")\n  set(version_file \"${generated_dir}/${cmake_package_name}ConfigVersion.cmake\")\n  write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion)\n  install(EXPORT ${targets_export_name}\n    COMPONENT \"${PROJECT_NAME}\"\n    NAMESPACE ${cmake_package_name}::\n    DESTINATION ${cmake_files_install_dir})\n  set(config_file \"${generated_dir}/${cmake_package_name}Config.cmake\")\n  configure_package_config_file(\"${gtest_SOURCE_DIR}/cmake/Config.cmake.in\"\n    \"${config_file}\" INSTALL_DESTINATION ${cmake_files_install_dir})\n  install(FILES ${version_file} ${config_file}\n    COMPONENT \"${PROJECT_NAME}\"\n    DESTINATION ${cmake_files_install_dir})\nendif()\n\n# Where Google Test's .h files can be found.\nset(gtest_build_include_dirs\n  \"${gtest_SOURCE_DIR}/include\"\n  \"${gtest_SOURCE_DIR}\")\ninclude_directories(${gtest_build_include_dirs})\n\n########################################################################\n#\n# Defines the gtest & gtest_main libraries. User tests should link\n# with one of them.\n\n# Google Test libraries. We build them using more strict warnings than what\n# are used for other targets, to ensure that gtest can be compiled by a user\n# aggressive about warnings.\ncxx_library(gtest \"${cxx_strict}\" src/gtest-all.cc)\nset_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})\nif(GTEST_HAS_ABSL)\n  target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1)\n  target_link_libraries(gtest PUBLIC\n    absl::failure_signal_handler\n    absl::stacktrace\n    absl::symbolize\n    absl::flags_parse\n    absl::flags_reflection\n    absl::flags_usage\n    absl::strings\n    absl::any\n    absl::optional\n    absl::variant\n    re2::re2\n  )\nendif()\ncxx_library(gtest_main \"${cxx_strict}\" src/gtest_main.cc)\nset_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})\nstring(REPLACE \";\" \"$<SEMICOLON>\" dirs \"${gtest_build_include_dirs}\")\ntarget_include_directories(gtest SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\ntarget_include_directories(gtest_main SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\nif(CMAKE_SYSTEM_NAME MATCHES \"QNX\" AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 7.1)\n  target_link_libraries(gtest PUBLIC regex)\nendif()\ntarget_link_libraries(gtest_main PUBLIC gtest)\n\n########################################################################\n#\n# Install rules.\ninstall_project(gtest gtest_main)\n\n########################################################################\n#\n# Samples on how to link user tests with gtest or gtest_main.\n#\n# They are not built by default. To build them, set the\n# gtest_build_samples option to ON. You can do it by running ccmake\n# or specifying the -Dgtest_build_samples=ON flag when running cmake.\n\nif (gtest_build_samples)\n  cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)\n  cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)\n  cxx_executable(sample3_unittest samples gtest_main)\n  cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)\n  cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)\n  cxx_executable(sample6_unittest samples gtest_main)\n  cxx_executable(sample7_unittest samples gtest_main)\n  cxx_executable(sample8_unittest samples gtest_main)\n  cxx_executable(sample9_unittest samples gtest)\n  cxx_executable(sample10_unittest samples gtest)\nendif()\n\n########################################################################\n#\n# Google Test's own tests.\n#\n# You can skip this section if you aren't interested in testing\n# Google Test itself.\n#\n# The tests are not built by default. To build them, set the\n# gtest_build_tests option to ON. You can do it by running ccmake\n# or specifying the -Dgtest_build_tests=ON flag when running cmake.\n\nif (gtest_build_tests)\n  # This must be set in the root directory for the tests to be run by\n  # 'make test' or ctest.\n  enable_testing()\n\n  ############################################################\n  # C++ tests built with standard compiler flags.\n\n  cxx_test(googletest-death-test-test gtest_main)\n  cxx_test(gtest_environment_test gtest)\n  cxx_test(googletest-filepath-test gtest_main)\n  cxx_test(googletest-listener-test gtest_main)\n  cxx_test(gtest_main_unittest gtest_main)\n  cxx_test(googletest-message-test gtest_main)\n  cxx_test(gtest_no_test_unittest gtest)\n  cxx_test(googletest-options-test gtest_main)\n  cxx_test(googletest-param-test-test gtest\n    test/googletest-param-test2-test.cc)\n  cxx_test(googletest-port-test gtest_main)\n  cxx_test(gtest_pred_impl_unittest gtest_main)\n  cxx_test(gtest_premature_exit_test gtest\n    test/gtest_premature_exit_test.cc)\n  cxx_test(googletest-printers-test gtest_main)\n  cxx_test(gtest_prod_test gtest_main\n    test/production.cc)\n  cxx_test(gtest_repeat_test gtest)\n  cxx_test(gtest_sole_header_test gtest_main)\n  cxx_test(gtest_stress_test gtest)\n  cxx_test(googletest-test-part-test gtest_main)\n  cxx_test(gtest_throw_on_failure_ex_test gtest)\n  cxx_test(gtest-typed-test_test gtest_main\n    test/gtest-typed-test2_test.cc)\n  cxx_test(gtest_unittest gtest_main)\n  cxx_test(gtest-unittest-api_test gtest)\n  cxx_test(gtest_skip_in_environment_setup_test gtest_main)\n  cxx_test(gtest_skip_test gtest_main)\n\n  ############################################################\n  # C++ tests built with non-standard compiler flags.\n\n  # MSVC 7.1 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310)\n    cxx_library(gtest_no_exception \"${cxx_no_exception}\"\n      src/gtest-all.cc)\n    cxx_library(gtest_main_no_exception \"${cxx_no_exception}\"\n      src/gtest-all.cc src/gtest_main.cc)\n  endif()\n  cxx_library(gtest_main_no_rtti \"${cxx_no_rtti}\"\n    src/gtest-all.cc src/gtest_main.cc)\n\n  cxx_test_with_flags(gtest-death-test_ex_nocatch_test\n    \"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0\"\n    gtest test/googletest-death-test_ex_test.cc)\n  cxx_test_with_flags(gtest-death-test_ex_catch_test\n    \"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1\"\n    gtest test/googletest-death-test_ex_test.cc)\n\n  cxx_test_with_flags(gtest_no_rtti_unittest \"${cxx_no_rtti}\"\n    gtest_main_no_rtti test/gtest_unittest.cc)\n\n  cxx_shared_library(gtest_dll \"${cxx_default}\"\n    src/gtest-all.cc src/gtest_main.cc)\n\n  cxx_executable_with_flags(gtest_dll_test_ \"${cxx_default}\"\n    gtest_dll test/gtest_all_test.cc)\n  set_target_properties(gtest_dll_test_\n                        PROPERTIES\n                        COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n\n  ############################################################\n  # Python tests.\n\n  cxx_executable(googletest-break-on-failure-unittest_ test gtest)\n  py_test(googletest-break-on-failure-unittest)\n\n  py_test(gtest_skip_check_output_test)\n  py_test(gtest_skip_environment_check_output_test)\n\n  # Visual Studio .NET 2003 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003\n    cxx_executable_with_flags(\n      googletest-catch-exceptions-no-ex-test_\n      \"${cxx_no_exception}\"\n      gtest_main_no_exception\n      test/googletest-catch-exceptions-test_.cc)\n  endif()\n\n  cxx_executable_with_flags(\n    googletest-catch-exceptions-ex-test_\n    \"${cxx_exception}\"\n    gtest_main\n    test/googletest-catch-exceptions-test_.cc)\n  py_test(googletest-catch-exceptions-test)\n\n  cxx_executable(googletest-color-test_ test gtest)\n  py_test(googletest-color-test)\n\n  cxx_executable(googletest-env-var-test_ test gtest)\n  py_test(googletest-env-var-test)\n\n  cxx_executable(googletest-filter-unittest_ test gtest)\n  py_test(googletest-filter-unittest)\n\n  cxx_executable(gtest_help_test_ test gtest_main)\n  py_test(gtest_help_test)\n\n  cxx_executable(googletest-list-tests-unittest_ test gtest)\n  py_test(googletest-list-tests-unittest)\n\n  cxx_executable(googletest-output-test_ test gtest)\n  py_test(googletest-output-test --no_stacktrace_support)\n\n  cxx_executable(googletest-shuffle-test_ test gtest)\n  py_test(googletest-shuffle-test)\n\n  # MSVC 7.1 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310)\n    cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)\n    set_target_properties(googletest-throw-on-failure-test_\n      PROPERTIES\n      COMPILE_FLAGS \"${cxx_no_exception}\")\n    py_test(googletest-throw-on-failure-test)\n  endif()\n\n  cxx_executable(googletest-uninitialized-test_ test gtest)\n  py_test(googletest-uninitialized-test)\n\n  cxx_executable(gtest_list_output_unittest_ test gtest)\n  py_test(gtest_list_output_unittest)\n\n  cxx_executable(gtest_xml_outfile1_test_ test gtest_main)\n  cxx_executable(gtest_xml_outfile2_test_ test gtest_main)\n  py_test(gtest_xml_outfiles_test)\n  py_test(googletest-json-outfiles-test)\n\n  cxx_executable(gtest_xml_output_unittest_ test gtest)\n  py_test(gtest_xml_output_unittest --no_stacktrace_support)\n  py_test(googletest-json-output-unittest --no_stacktrace_support)\nendif()\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/cmake/Config.cmake.in",
    "content": "@PACKAGE_INIT@\ninclude(CMakeFindDependencyMacro)\nif (@GTEST_HAS_PTHREAD@)\n  set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)\n  find_dependency(Threads)\nendif()\nif (@GTEST_HAS_ABSL@)\n  find_dependency(absl)\n  find_dependency(re2)\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake\")\ncheck_required_components(\"@project_name@\")\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/cmake/gtest.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gtest\nDescription: GoogleTest (without main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nLibs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/cmake/gtest_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gtest_main\nDescription: GoogleTest (with main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gtest = @PROJECT_VERSION@\nLibs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/cmake/internal_utils.cmake",
    "content": "# Defines functions and macros useful for building Google Test and\n# Google Mock.\n#\n# Note:\n#\n# - This file will be run twice when building Google Mock (once via\n#   Google Test's CMakeLists.txt, and once via Google Mock's).\n#   Therefore it shouldn't have any side effects other than defining\n#   the functions and macros.\n#\n# - The functions/macros defined in this file may depend on Google\n#   Test and Google Mock's option() definitions, and thus must be\n#   called *after* the options have been defined.\n\n# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.\n#\n# This must be a macro(), as inside a function string() can only\n# update variables in the function scope.\nmacro(fix_default_compiler_settings_)\n  if (CMAKE_CXX_COMPILER_ID MATCHES \"MSVC|Clang\")\n    # For MSVC and Clang, CMake sets certain flags to defaults we want to\n    # override.\n    # This replacement code is taken from sample in the CMake Wiki at\n    # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.\n    foreach (flag_var\n             CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE\n             CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO\n             CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE\n             CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)\n      if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)\n        # When Google Test is built as a shared library, it should also use\n        # shared runtime libraries. Otherwise, it may end up with multiple\n        # copies of runtime library data in different modules, resulting in\n        # hard-to-find crashes. When it is built as a static library, it is\n        # preferable to use CRT as static libraries, as we don't have to rely\n        # on CRT DLLs being available. CMake always defaults to using shared\n        # CRT libraries, so we override that default here.\n        string(REPLACE \"/MD\" \"-MT\" ${flag_var} \"${${flag_var}}\")\n\n        # When using Ninja with Clang, static builds pass -D_DLL on Windows.\n        # This is incorrect and should not happen, so we fix that here.\n        string(REPLACE \"-D_DLL\" \"\" ${flag_var} \"${${flag_var}}\")\n      endif()\n\n      # We prefer more strict warning checking for building Google Test.\n      # Replaces /W3 with /W4 in defaults.\n      string(REPLACE \"/W3\" \"/W4\" ${flag_var} \"${${flag_var}}\")\n\n      # Prevent D9025 warning for targets that have exception handling\n      # turned off (/EHs-c- flag). Where required, exceptions are explicitly\n      # re-enabled using the cxx_exception_flags variable.\n      string(REPLACE \"/EHsc\" \"\" ${flag_var} \"${${flag_var}}\")\n    endforeach()\n  endif()\nendmacro()\n\n# Defines the compiler/linker flags used to build Google Test and\n# Google Mock. You can tweak these definitions to suit your need. A\n# variable's value is empty before it's explicitly assigned to.\nmacro(config_compiler_and_linker)\n  # Note: pthreads on MinGW is not supported, even if available\n  # instead, we use windows threading primitives.\n  unset(GTEST_HAS_PTHREAD)\n  if (NOT gtest_disable_pthreads AND NOT MINGW)\n    # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.\n    find_package(Threads)\n    if (CMAKE_USE_PTHREADS_INIT)\n      set(GTEST_HAS_PTHREAD ON)\n    endif()\n  endif()\n\n  fix_default_compiler_settings_()\n  if (MSVC)\n    # Newlines inside flags variables break CMake's NMake generator.\n    # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.\n    set(cxx_base_flags \"-GS -W4 -WX -wd4251 -wd4275 -nologo -J\")\n    set(cxx_base_flags \"${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32\")\n    set(cxx_base_flags \"${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN\")\n    set(cxx_exception_flags \"-EHsc -D_HAS_EXCEPTIONS=1\")\n    set(cxx_no_exception_flags \"-EHs-c- -D_HAS_EXCEPTIONS=0\")\n    set(cxx_no_rtti_flags \"-GR-\")\n    # Suppress \"unreachable code\" warning,\n    # https://stackoverflow.com/questions/3232669 explains the issue.\n    set(cxx_base_flags \"${cxx_base_flags} -wd4702\")\n    # Ensure MSVC treats source files as UTF-8 encoded.\n    if(CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n      set(cxx_base_flags \"${cxx_base_flags} -utf-8\")\n    endif()\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n      set(cxx_base_flags \"${cxx_base_flags} /fp:precise -Wno-inconsistent-missing-override -Wno-microsoft-exception-spec -Wno-unused-function -Wno-unused-but-set-variable\")\n    endif()\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" OR\n      CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n    set(cxx_base_flags \"-Wall -Wshadow -Wconversion -Wundef\")\n    set(cxx_exception_flags \"-fexceptions\")\n    set(cxx_no_exception_flags \"-fno-exceptions\")\n    set(cxx_strict_flags \"-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Winline -Wredundant-decls\")\n    set(cxx_no_rtti_flags \"-fno-rtti\")\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\")\n      set(cxx_strict_flags \"${cxx_strict_flags} -Wchar-subscripts\")\n    endif()\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n      set(cxx_base_flags \"${cxx_base_flags} -Wno-implicit-float-size-conversion -ffp-model=precise\")\n    endif()\n  elseif (CMAKE_COMPILER_IS_GNUCXX)\n    set(cxx_base_flags \"-Wall -Wshadow -Wundef\")\n    if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)\n      set(cxx_base_flags \"${cxx_base_flags} -Wno-error=dangling-else\")\n    endif()\n    set(cxx_exception_flags \"-fexceptions\")\n    set(cxx_no_exception_flags \"-fno-exceptions\")\n    # Until version 4.3.2, GCC doesn't define a macro to indicate\n    # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI\n    # explicitly.\n    set(cxx_no_rtti_flags \"-fno-rtti -DGTEST_HAS_RTTI=0\")\n    set(cxx_strict_flags\n      \"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"SunPro\")\n    set(cxx_exception_flags \"-features=except\")\n    # Sun Pro doesn't provide macros to indicate whether exceptions and\n    # RTTI are enabled, so we define GTEST_HAS_* explicitly.\n    set(cxx_no_exception_flags \"-features=no%except -DGTEST_HAS_EXCEPTIONS=0\")\n    set(cxx_no_rtti_flags \"-features=no%rtti -DGTEST_HAS_RTTI=0\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"VisualAge\" OR\n      CMAKE_CXX_COMPILER_ID STREQUAL \"XL\")\n    # CMake 2.8 changes Visual Age's compiler ID to \"XL\".\n    set(cxx_exception_flags \"-qeh\")\n    set(cxx_no_exception_flags \"-qnoeh\")\n    # Until version 9.0, Visual Age doesn't define a macro to indicate\n    # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI\n    # explicitly.\n    set(cxx_no_rtti_flags \"-qnortti -DGTEST_HAS_RTTI=0\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"HP\")\n    set(cxx_base_flags \"-AA -mt\")\n    set(cxx_exception_flags \"-DGTEST_HAS_EXCEPTIONS=1\")\n    set(cxx_no_exception_flags \"+noeh -DGTEST_HAS_EXCEPTIONS=0\")\n    # RTTI can not be disabled in HP aCC compiler.\n    set(cxx_no_rtti_flags \"\")\n  endif()\n\n  # The pthreads library is available and allowed?\n  if (DEFINED GTEST_HAS_PTHREAD)\n    set(GTEST_HAS_PTHREAD_MACRO \"-DGTEST_HAS_PTHREAD=1\")\n  else()\n    set(GTEST_HAS_PTHREAD_MACRO \"-DGTEST_HAS_PTHREAD=0\")\n  endif()\n  set(cxx_base_flags \"${cxx_base_flags} ${GTEST_HAS_PTHREAD_MACRO}\")\n\n  # For building gtest's own tests and samples.\n  set(cxx_exception \"${cxx_base_flags} ${cxx_exception_flags}\")\n  set(cxx_no_exception\n    \"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}\")\n  set(cxx_default \"${cxx_exception}\")\n  set(cxx_no_rtti \"${cxx_default} ${cxx_no_rtti_flags}\")\n\n  # For building the gtest libraries.\n  set(cxx_strict \"${cxx_default} ${cxx_strict_flags}\")\nendmacro()\n\n# Defines the gtest & gtest_main libraries. User tests should link\n# with one of them.\nfunction(cxx_library_with_type name type cxx_flags)\n  # type can be either STATIC or SHARED to denote a static or shared library.\n  # ARGN refers to additional arguments after 'cxx_flags'.\n  add_library(${name} ${type} ${ARGN})\n  add_library(${cmake_package_name}::${name} ALIAS ${name})\n  set_target_properties(${name}\n    PROPERTIES\n    COMPILE_FLAGS \"${cxx_flags}\")\n  # Set the output directory for build artifacts.\n  set_target_properties(${name}\n    PROPERTIES\n    RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\"\n    LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\"\n    ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\"\n    PDB_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\"\n    COMPILE_PDB_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\n  # Make PDBs match library name.\n  get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)\n  set_target_properties(${name}\n    PROPERTIES\n    PDB_NAME \"${name}\"\n    PDB_NAME_DEBUG \"${name}${pdb_debug_postfix}\"\n    COMPILE_PDB_NAME \"${name}\"\n    COMPILE_PDB_NAME_DEBUG \"${name}${pdb_debug_postfix}\")\n\n  if (BUILD_SHARED_LIBS OR type STREQUAL \"SHARED\")\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_DEFINITIONS \"GTEST_CREATE_SHARED_LIBRARY=1\")\n    target_compile_definitions(${name} INTERFACE\n      $<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)\n  endif()\n  if (DEFINED GTEST_HAS_PTHREAD)\n    target_link_libraries(${name} PUBLIC Threads::Threads)\n  endif()\n\n  target_compile_features(${name} PUBLIC cxx_std_14)\nendfunction()\n\n########################################################################\n#\n# Helper functions for creating build targets.\n\nfunction(cxx_shared_library name cxx_flags)\n  cxx_library_with_type(${name} SHARED \"${cxx_flags}\" ${ARGN})\nendfunction()\n\nfunction(cxx_library name cxx_flags)\n  cxx_library_with_type(${name} \"\" \"${cxx_flags}\" ${ARGN})\nendfunction()\n\n# cxx_executable_with_flags(name cxx_flags libs srcs...)\n#\n# Creates a named C++ executable that depends on the given libraries and\n# is built from the given source files with the given compiler flags.\nfunction(cxx_executable_with_flags name cxx_flags libs)\n  add_executable(${name} ${ARGN})\n  if (MSVC)\n    # BigObj required for tests.\n    set(cxx_flags \"${cxx_flags} -bigobj\")\n  endif()\n  if (cxx_flags)\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_FLAGS \"${cxx_flags}\")\n  endif()\n  if (BUILD_SHARED_LIBS)\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n  endif()\n  # To support mixing linking in static and dynamic libraries, link each\n  # library in with an extra call to target_link_libraries.\n  foreach (lib \"${libs}\")\n    target_link_libraries(${name} ${lib})\n  endforeach()\nendfunction()\n\n# cxx_executable(name dir lib srcs...)\n#\n# Creates a named target that depends on the given libs and is built\n# from the given source files. dir/name.cc is implicitly included in\n# the source file list.\nfunction(cxx_executable name dir libs)\n  cxx_executable_with_flags(\n    ${name} \"${cxx_default}\" \"${libs}\" \"${dir}/${name}.cc\" ${ARGN})\nendfunction()\n\nif(gtest_build_tests)\n  find_package(Python3)\nendif()\n\n# cxx_test_with_flags(name cxx_flags libs srcs...)\n#\n# Creates a named C++ test that depends on the given libs and is built\n# from the given source files with the given compiler flags.\nfunction(cxx_test_with_flags name cxx_flags libs)\n  cxx_executable_with_flags(${name} \"${cxx_flags}\" \"${libs}\" ${ARGN})\n    add_test(NAME ${name} COMMAND \"$<TARGET_FILE:${name}>\")\nendfunction()\n\n# cxx_test(name libs srcs...)\n#\n# Creates a named test target that depends on the given libs and is\n# built from the given source files. Unlike cxx_test_with_flags,\n# test/name.cc is already implicitly included in the source file list.\nfunction(cxx_test name libs)\n  cxx_test_with_flags(\"${name}\" \"${cxx_default}\" \"${libs}\"\n    \"test/${name}.cc\" ${ARGN})\nendfunction()\n\n# py_test(name)\n#\n# Creates a Python test with the given name whose main module is in\n# test/name.py. It does nothing if Python is not installed.\nfunction(py_test name)\n  if (NOT Python3_Interpreter_FOUND)\n    return()\n  endif()\n\n  get_cmake_property(is_multi \"GENERATOR_IS_MULTI_CONFIG\")\n  set(build_dir \"${CMAKE_CURRENT_BINARY_DIR}\")\n  if (is_multi)\n    set(build_dir \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>\")\n  endif()\n\n  add_test(NAME ${name}\n      COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py\n          --build_dir=${build_dir} ${ARGN})\n\n  # Make the Python import path consistent between Bazel and CMake.\n  set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})\nendfunction()\n\n# install_project(targets...)\n#\n# Installs the specified targets and configures the associated pkgconfig files.\nfunction(install_project)\n  if(INSTALL_GTEST)\n    install(DIRECTORY \"${PROJECT_SOURCE_DIR}/include/\"\n      COMPONENT \"${PROJECT_NAME}\"\n      DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\")\n    # Install the project targets.\n    install(TARGETS ${ARGN}\n      EXPORT ${targets_export_name}\n      COMPONENT \"${PROJECT_NAME}\"\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\")\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"MSVC\")\n      # Install PDBs.\n      foreach(t ${ARGN})\n        get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)\n        get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)\n        get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)\n        install(FILES\n          \"${t_pdb_output_directory}/\\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb\"\n          COMPONENT \"${PROJECT_NAME}\"\n          DESTINATION ${CMAKE_INSTALL_LIBDIR}\n          OPTIONAL)\n      endforeach()\n    endif()\n    # Configure and install pkgconfig files.\n    foreach(t ${ARGN})\n      set(configured_pc \"${generated_dir}/${t}.pc\")\n      configure_file(\"${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in\"\n        \"${configured_pc}\" @ONLY)\n      install(FILES \"${configured_pc}\"\n        COMPONENT \"${PROJECT_NAME}\"\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n    endforeach()\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/cmake/libgtest.la.in",
    "content": "# libgtest.la - a libtool library file\n# Generated by libtool (GNU libtool) 2.4.6\n\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# Names of this library.\nlibrary_names='libgtest.so'\n\n# Is this an already installed library?\ninstalled=yes\n\n# Should we warn about portability when linking against -modules?\nshouldnotlink=no\n\n# Files to dlopen/dlpreopen\ndlopen=''\ndlpreopen=''\n\n# Directory that this library needs to be installed in:\nlibdir='@CMAKE_INSTALL_FULL_LIBDIR@'\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-assertion-result.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements the AssertionResult type.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n\n#include <memory>\n#include <ostream>\n#include <string>\n#include <type_traits>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251                                   \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// A class for indicating whether an assertion was successful.  When\n// the assertion wasn't successful, the AssertionResult object\n// remembers a non-empty message that describes how it failed.\n//\n// To create an instance of this class, use one of the factory functions\n// (AssertionSuccess() and AssertionFailure()).\n//\n// This class is useful for two purposes:\n//   1. Defining predicate functions to be used with Boolean test assertions\n//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts\n//   2. Defining predicate-format functions to be\n//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).\n//\n// For example, if you define IsEven predicate:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))\n// will print the message\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false (5 is odd)\n//   Expected: true\n//\n// instead of a more opaque\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false\n//   Expected: true\n//\n// in case IsEven is a simple Boolean predicate.\n//\n// If you expect your predicate to be reused and want to support informative\n// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up\n// about half as often as positive ones in our tests), supply messages for\n// both success and failure cases:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess() << n << \" is even\";\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print\n//\n//   Value of: IsEven(Fib(6))\n//     Actual: true (8 is even)\n//   Expected: false\n//\n// NB: Predicates that support negative Boolean assertions have reduced\n// performance in positive ones so be careful not to use them in tests\n// that have lots (tens of thousands) of positive Boolean assertions.\n//\n// To use this class with EXPECT_PRED_FORMAT assertions such as:\n//\n//   // Verifies that Foo() returns an even number.\n//   EXPECT_PRED_FORMAT1(IsEven, Foo());\n//\n// you need to define:\n//\n//   testing::AssertionResult IsEven(const char* expr, int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure()\n//         << \"Expected: \" << expr << \" is even\\n  Actual: it's \" << n;\n//   }\n//\n// If Foo() returns 5, you will see the following message:\n//\n//   Expected: Foo() is even\n//     Actual: it's 5\n\nclass GTEST_API_ AssertionResult {\n public:\n  // Copy constructor.\n  // Used in EXPECT_TRUE/FALSE(assertion_result).\n  AssertionResult(const AssertionResult& other);\n\n// C4800 is a level 3 warning in Visual Studio 2015 and earlier.\n// This warning is not emitted in Visual Studio 2017.\n// This warning is off by default starting in Visual Studio 2019 but can be\n// enabled with command-line options.\n#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)\n#endif\n\n  // Used in the EXPECT_TRUE/FALSE(bool_expression).\n  //\n  // T must be contextually convertible to bool.\n  //\n  // The second parameter prevents this overload from being considered if\n  // the argument is implicitly convertible to AssertionResult. In that case\n  // we want AssertionResult's copy constructor to be used.\n  template <typename T>\n  explicit AssertionResult(\n      const T& success,\n      typename std::enable_if<\n          !std::is_convertible<T, AssertionResult>::value>::type*\n      /*enabler*/\n      = nullptr)\n      : success_(success) {}\n\n#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n  // Assignment operator.\n  AssertionResult& operator=(AssertionResult other) {\n    swap(other);\n    return *this;\n  }\n\n  // Returns true if and only if the assertion succeeded.\n  operator bool() const { return success_; }  // NOLINT\n\n  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\n  AssertionResult operator!() const;\n\n  // Returns the text streamed into this AssertionResult. Test assertions\n  // use it when they fail (i.e., the predicate's outcome doesn't match the\n  // assertion's expectation). When nothing has been streamed into the\n  // object, returns an empty string.\n  const char* message() const {\n    return message_ != nullptr ? message_->c_str() : \"\";\n  }\n  // Deprecated; please use message() instead.\n  const char* failure_message() const { return message(); }\n\n  // Streams a custom failure message into this object.\n  template <typename T>\n  AssertionResult& operator<<(const T& value) {\n    AppendMessage(Message() << value);\n    return *this;\n  }\n\n  // Allows streaming basic output manipulators such as endl or flush into\n  // this object.\n  AssertionResult& operator<<(\n      ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {\n    AppendMessage(Message() << basic_manipulator);\n    return *this;\n  }\n\n private:\n  // Appends the contents of message to message_.\n  void AppendMessage(const Message& a_message) {\n    if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();\n    message_->append(a_message.GetString().c_str());\n  }\n\n  // Swap the contents of this AssertionResult with other.\n  void swap(AssertionResult& other);\n\n  // Stores result of the assertion predicate.\n  bool success_;\n  // Stores the message describing the condition in case the expectation\n  // construct is not satisfied with the predicate's outcome.\n  // Referenced via a pointer to avoid taking too much stack frame space\n  // with test assertions.\n  std::unique_ptr< ::std::string> message_;\n};\n\n// Makes a successful assertion result.\nGTEST_API_ AssertionResult AssertionSuccess();\n\n// Makes a failed assertion result.\nGTEST_API_ AssertionResult AssertionFailure();\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << msg.\nGTEST_API_ AssertionResult AssertionFailure(const Message& msg);\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-death-test.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the public API for death tests.  It is\n// #included by gtest.h so a user doesn't need to include this\n// directly.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n\n#include \"gtest/internal/gtest-death-test-internal.h\"\n\n// This flag controls the style of death tests.  Valid values are \"threadsafe\",\n// meaning that the death test child process will re-execute the test binary\n// from the start, running only a single death test, or \"fast\",\n// meaning that the child process will execute the test logic immediately\n// after forking.\nGTEST_DECLARE_string_(death_test_style);\n\nnamespace testing {\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nnamespace internal {\n\n// Returns a Boolean value indicating whether the caller is currently\n// executing in the context of the death test child process.  Tools such as\n// Valgrind heap checkers may need this to modify their behavior in death\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\n// implementation of death tests.  User code MUST NOT use it.\nGTEST_API_ bool InDeathTestChild();\n\n}  // namespace internal\n\n// The following macros are useful for writing death tests.\n\n// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is\n// executed:\n//\n//   1. It generates a warning if there is more than one active\n//   thread.  This is because it's safe to fork() or clone() only\n//   when there is a single thread.\n//\n//   2. The parent process clone()s a sub-process and runs the death\n//   test in it; the sub-process exits with code 0 at the end of the\n//   death test, if it hasn't exited already.\n//\n//   3. The parent process waits for the sub-process to terminate.\n//\n//   4. The parent process checks the exit code and error message of\n//   the sub-process.\n//\n// Examples:\n//\n//   ASSERT_DEATH(server.SendMessage(56, \"Hello\"), \"Invalid port number\");\n//   for (int i = 0; i < 5; i++) {\n//     EXPECT_DEATH(server.ProcessRequest(i),\n//                  \"Invalid request .* in ProcessRequest()\")\n//                  << \"Failed to die on request \" << i;\n//   }\n//\n//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), \"Exiting\");\n//\n//   bool KilledBySIGHUP(int exit_code) {\n//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;\n//   }\n//\n//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, \"Hanging up!\");\n//\n// The final parameter to each of these macros is a matcher applied to any data\n// the sub-process wrote to stderr.  For compatibility with existing tests, a\n// bare string is interpreted as a regular expression matcher.\n//\n// On the regular expressions used in death tests:\n//\n//   On POSIX-compliant systems (*nix), we use the <regex.h> library,\n//   which uses the POSIX extended regex syntax.\n//\n//   On other platforms (e.g. Windows or Mac), we only support a simple regex\n//   syntax implemented as part of Google Test.  This limited\n//   implementation should be enough most of the time when writing\n//   death tests; though it lacks many features you can find in PCRE\n//   or POSIX extended regex syntax.  For example, we don't support\n//   union (\"x|y\"), grouping (\"(xy)\"), brackets (\"[xy]\"), and\n//   repetition count (\"x{5,7}\"), among others.\n//\n//   Below is the syntax that we do support.  We chose it to be a\n//   subset of both PCRE and POSIX extended regex, so it's easy to\n//   learn wherever you come from.  In the following: 'A' denotes a\n//   literal character, period (.), or a single \\\\ escape sequence;\n//   'x' and 'y' denote regular expressions; 'm' and 'n' are for\n//   natural numbers.\n//\n//     c     matches any literal character c\n//     \\\\d   matches any decimal digit\n//     \\\\D   matches any character that's not a decimal digit\n//     \\\\f   matches \\f\n//     \\\\n   matches \\n\n//     \\\\r   matches \\r\n//     \\\\s   matches any ASCII whitespace, including \\n\n//     \\\\S   matches any character that's not a whitespace\n//     \\\\t   matches \\t\n//     \\\\v   matches \\v\n//     \\\\w   matches any letter, _, or decimal digit\n//     \\\\W   matches any character that \\\\w doesn't match\n//     \\\\c   matches any literal character c, which must be a punctuation\n//     .     matches any single character except \\n\n//     A?    matches 0 or 1 occurrences of A\n//     A*    matches 0 or many occurrences of A\n//     A+    matches 1 or many occurrences of A\n//     ^     matches the beginning of a string (not that of each line)\n//     $     matches the end of a string (not that of each line)\n//     xy    matches x followed by y\n//\n//   If you accidentally use PCRE or POSIX extended regex features\n//   not implemented by us, you will get a run-time failure.  In that\n//   case, please try to rewrite your regular expression within the\n//   above syntax.\n//\n//   This implementation is *not* meant to be as highly tuned or robust\n//   as a compiled regex library, but should perform well enough for a\n//   death test, which already incurs significant overhead by launching\n//   a child process.\n//\n// Known caveats:\n//\n//   A \"threadsafe\" style death test obtains the path to the test\n//   program from argv[0] and re-executes it in the sub-process.  For\n//   simplicity, the current implementation doesn't search the PATH\n//   when launching the sub-process.  This means that the user must\n//   invoke the test program via a path that contains at least one\n//   path separator (e.g. path/to/foo_test and\n//   /absolute/path/to/bar_test are fine, but foo_test is not).  This\n//   is rarely a problem as people usually don't put the test binary\n//   directory in PATH.\n//\n\n// Asserts that a given `statement` causes the program to exit, with an\n// integer exit status that satisfies `predicate`, and emitting error output\n// that matches `matcher`.\n#define ASSERT_EXIT(statement, predicate, matcher) \\\n  GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)\n\n// Like `ASSERT_EXIT`, but continues on to successive tests in the\n// test suite, if any:\n#define EXPECT_EXIT(statement, predicate, matcher) \\\n  GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)\n\n// Asserts that a given `statement` causes the program to exit, either by\n// explicitly exiting with a nonzero exit code or being killed by a\n// signal, and emitting error output that matches `matcher`.\n#define ASSERT_DEATH(statement, matcher) \\\n  ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)\n\n// Like `ASSERT_DEATH`, but continues on to successive tests in the\n// test suite, if any:\n#define EXPECT_DEATH(statement, matcher) \\\n  EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)\n\n// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:\n\n// Tests that an exit code describes a normal exit with a given exit code.\nclass GTEST_API_ ExitedWithCode {\n public:\n  explicit ExitedWithCode(int exit_code);\n  ExitedWithCode(const ExitedWithCode&) = default;\n  void operator=(const ExitedWithCode& other) = delete;\n  bool operator()(int exit_status) const;\n\n private:\n  const int exit_code_;\n};\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// Tests that an exit code describes an exit due to termination by a\n// given signal.\nclass GTEST_API_ KilledBySignal {\n public:\n  explicit KilledBySignal(int signum);\n  bool operator()(int exit_status) const;\n\n private:\n  const int signum_;\n};\n#endif  // !GTEST_OS_WINDOWS\n\n// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.\n// The death testing framework causes this to have interesting semantics,\n// since the sideeffects of the call are only visible in opt mode, and not\n// in debug mode.\n//\n// In practice, this can be used to test functions that utilize the\n// LOG(DFATAL) macro using the following style:\n//\n// int DieInDebugOr12(int* sideeffect) {\n//   if (sideeffect) {\n//     *sideeffect = 12;\n//   }\n//   LOG(DFATAL) << \"death\";\n//   return 12;\n// }\n//\n// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {\n//   int sideeffect = 0;\n//   // Only asserts in dbg.\n//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), \"death\");\n//\n// #ifdef NDEBUG\n//   // opt-mode has sideeffect visible.\n//   EXPECT_EQ(12, sideeffect);\n// #else\n//   // dbg-mode no visible sideeffect.\n//   EXPECT_EQ(0, sideeffect);\n// #endif\n// }\n//\n// This will assert that DieInDebugReturn12InOpt() crashes in debug\n// mode, usually due to a DCHECK or LOG(DFATAL), but returns the\n// appropriate fallback value (12 in this case) in opt mode. If you\n// need to test that a function has appropriate side-effects in opt\n// mode, include assertions against the side-effects.  A general\n// pattern for this is:\n//\n// EXPECT_DEBUG_DEATH({\n//   // Side-effects here will have an effect after this statement in\n//   // opt mode, but none in debug mode.\n//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));\n// }, \"death\");\n//\n#ifdef NDEBUG\n\n#define EXPECT_DEBUG_DEATH(statement, regex) \\\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\n\n#define ASSERT_DEBUG_DEATH(statement, regex) \\\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\n\n#else\n\n#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)\n\n#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)\n\n#endif  // NDEBUG for EXPECT_DEBUG_DEATH\n#endif  // GTEST_HAS_DEATH_TEST\n\n// This macro is used for implementing macros such as\n// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where\n// death tests are not supported. Those macros must compile on such systems\n// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters\n// on systems that support death tests. This allows one to write such a macro on\n// a system that does not support death tests and be sure that it will compile\n// on a death-test supporting system. It is exposed publicly so that systems\n// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST\n// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and\n// ASSERT_DEATH_IF_SUPPORTED.\n//\n// Parameters:\n//   statement -  A statement that a macro such as EXPECT_DEATH would test\n//                for program termination. This macro has to make sure this\n//                statement is compiled but not executed, to ensure that\n//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain\n//                parameter if and only if EXPECT_DEATH compiles with it.\n//   regex_or_matcher -  A regex that a macro such as EXPECT_DEATH would use\n//                to test the output of statement.  This parameter has to be\n//                compiled but not evaluated by this macro, to ensure that\n//                this macro only accepts expressions that a macro such as\n//                EXPECT_DEATH would accept.\n//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED\n//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.\n//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not\n//                compile inside functions where ASSERT_DEATH doesn't\n//                compile.\n//\n//  The branch that has an always false condition is used to ensure that\n//  statement and regex are compiled (and thus syntactically correct) but\n//  never executed. The unreachable code macro protects the terminator\n//  statement from generating an 'unreachable code' warning in case\n//  statement unconditionally returns or throws. The Message constructor at\n//  the end allows the syntax of streaming additional messages into the\n//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.\n#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator)  \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                \\\n  if (::testing::internal::AlwaysTrue()) {                                     \\\n    GTEST_LOG_(WARNING) << \"Death tests are not supported on this platform.\\n\" \\\n                        << \"Statement '\" #statement \"' cannot be verified.\";   \\\n  } else if (::testing::internal::AlwaysFalse()) {                             \\\n    ::testing::internal::MakeDeathTestMatcher(regex_or_matcher);               \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);                 \\\n    terminator;                                                                \\\n  } else                                                                       \\\n    ::testing::Message()\n\n// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and\n// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if\n// death tests are supported; otherwise they just issue a warning.  This is\n// useful when you are combining death test assertions with normal test\n// assertions in one test.\n#ifdef GTEST_HAS_DEATH_TEST\n#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n  EXPECT_DEATH(statement, regex)\n#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n  ASSERT_DEATH(statement, regex)\n#else\n#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n  GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )\n#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n  GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)\n#endif\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-matchers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements just enough of the matcher interface to allow\n// EXPECT_DEATH and friends to accept a matcher argument.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n\n#include <atomic>\n#include <functional>\n#include <memory>\n#include <ostream>\n#include <string>\n#include <type_traits>\n\n#include \"gtest/gtest-printers.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n// MSVC warning C5046 is new as of VS2017 version 15.8.\n#if defined(_MSC_VER) && _MSC_VER >= 1915\n#define GTEST_MAYBE_5046_ 5046\n#else\n#define GTEST_MAYBE_5046_\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by\n                              clients of class B */\n    /* Symbol involving type with internal linkage not defined */)\n\nnamespace testing {\n\n// To implement a matcher Foo for type T, define:\n//   1. a class FooMatcherMatcher that implements the matcher interface:\n//     using is_gtest_matcher = void;\n//     bool MatchAndExplain(const T&, std::ostream*);\n//       (MatchResultListener* can also be used instead of std::ostream*)\n//     void DescribeTo(std::ostream*);\n//     void DescribeNegationTo(std::ostream*);\n//\n//   2. a factory function that creates a Matcher<T> object from a\n//      FooMatcherMatcher.\n\nclass MatchResultListener {\n public:\n  // Creates a listener object with the given underlying ostream.  The\n  // listener does not own the ostream, and does not dereference it\n  // in the constructor or destructor.\n  explicit MatchResultListener(::std::ostream* os) : stream_(os) {}\n  virtual ~MatchResultListener() = 0;  // Makes this class abstract.\n\n  // Streams x to the underlying ostream; does nothing if the ostream\n  // is NULL.\n  template <typename T>\n  MatchResultListener& operator<<(const T& x) {\n    if (stream_ != nullptr) *stream_ << x;\n    return *this;\n  }\n\n  // Returns the underlying ostream.\n  ::std::ostream* stream() { return stream_; }\n\n  // Returns true if and only if the listener is interested in an explanation\n  // of the match result.  A matcher's MatchAndExplain() method can use\n  // this information to avoid generating the explanation when no one\n  // intends to hear it.\n  bool IsInterested() const { return stream_ != nullptr; }\n\n private:\n  ::std::ostream* const stream_;\n\n  MatchResultListener(const MatchResultListener&) = delete;\n  MatchResultListener& operator=(const MatchResultListener&) = delete;\n};\n\ninline MatchResultListener::~MatchResultListener() = default;\n\n// An instance of a subclass of this knows how to describe itself as a\n// matcher.\nclass GTEST_API_ MatcherDescriberInterface {\n public:\n  virtual ~MatcherDescriberInterface() = default;\n\n  // Describes this matcher to an ostream.  The function should print\n  // a verb phrase that describes the property a value matching this\n  // matcher should have.  The subject of the verb phrase is the value\n  // being matched.  For example, the DescribeTo() method of the Gt(7)\n  // matcher prints \"is greater than 7\".\n  virtual void DescribeTo(::std::ostream* os) const = 0;\n\n  // Describes the negation of this matcher to an ostream.  For\n  // example, if the description of this matcher is \"is greater than\n  // 7\", the negated description could be \"is not greater than 7\".\n  // You are not required to override this when implementing\n  // MatcherInterface, but it is highly advised so that your matcher\n  // can produce good error messages.\n  virtual void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"not (\";\n    DescribeTo(os);\n    *os << \")\";\n  }\n};\n\n// The implementation of a matcher.\ntemplate <typename T>\nclass MatcherInterface : public MatcherDescriberInterface {\n public:\n  // Returns true if and only if the matcher matches x; also explains the\n  // match result to 'listener' if necessary (see the next paragraph), in\n  // the form of a non-restrictive relative clause (\"which ...\",\n  // \"whose ...\", etc) that describes x.  For example, the\n  // MatchAndExplain() method of the Pointee(...) matcher should\n  // generate an explanation like \"which points to ...\".\n  //\n  // Implementations of MatchAndExplain() should add an explanation of\n  // the match result *if and only if* they can provide additional\n  // information that's not already present (or not obvious) in the\n  // print-out of x and the matcher's description.  Whether the match\n  // succeeds is not a factor in deciding whether an explanation is\n  // needed, as sometimes the caller needs to print a failure message\n  // when the match succeeds (e.g. when the matcher is used inside\n  // Not()).\n  //\n  // For example, a \"has at least 10 elements\" matcher should explain\n  // what the actual element count is, regardless of the match result,\n  // as it is useful information to the reader; on the other hand, an\n  // \"is empty\" matcher probably only needs to explain what the actual\n  // size is when the match fails, as it's redundant to say that the\n  // size is 0 when the value is already known to be empty.\n  //\n  // You should override this method when defining a new matcher.\n  //\n  // It's the responsibility of the caller (Google Test) to guarantee\n  // that 'listener' is not NULL.  This helps to simplify a matcher's\n  // implementation when it doesn't care about the performance, as it\n  // can talk to 'listener' without checking its validity first.\n  // However, in order to implement dummy listeners efficiently,\n  // listener->stream() may be NULL.\n  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;\n\n  // Inherits these methods from MatcherDescriberInterface:\n  //   virtual void DescribeTo(::std::ostream* os) const = 0;\n  //   virtual void DescribeNegationTo(::std::ostream* os) const;\n};\n\nnamespace internal {\n\n// A match result listener that ignores the explanation.\nclass DummyMatchResultListener : public MatchResultListener {\n public:\n  DummyMatchResultListener() : MatchResultListener(nullptr) {}\n\n private:\n  DummyMatchResultListener(const DummyMatchResultListener&) = delete;\n  DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;\n};\n\n// A match result listener that forwards the explanation to a given\n// ostream.  The difference between this and MatchResultListener is\n// that the former is concrete.\nclass StreamMatchResultListener : public MatchResultListener {\n public:\n  explicit StreamMatchResultListener(::std::ostream* os)\n      : MatchResultListener(os) {}\n\n private:\n  StreamMatchResultListener(const StreamMatchResultListener&) = delete;\n  StreamMatchResultListener& operator=(const StreamMatchResultListener&) =\n      delete;\n};\n\nstruct SharedPayloadBase {\n  std::atomic<int> ref{1};\n  void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }\n  bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }\n};\n\ntemplate <typename T>\nstruct SharedPayload : SharedPayloadBase {\n  explicit SharedPayload(const T& v) : value(v) {}\n  explicit SharedPayload(T&& v) : value(std::move(v)) {}\n\n  static void Destroy(SharedPayloadBase* shared) {\n    delete static_cast<SharedPayload*>(shared);\n  }\n\n  T value;\n};\n\n// An internal class for implementing Matcher<T>, which will derive\n// from it.  We put functionalities common to all Matcher<T>\n// specializations here to avoid code duplication.\ntemplate <typename T>\nclass MatcherBase : private MatcherDescriberInterface {\n public:\n  // Returns true if and only if the matcher matches x; also explains the\n  // match result to 'listener'.\n  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {\n    GTEST_CHECK_(vtable_ != nullptr);\n    return vtable_->match_and_explain(*this, x, listener);\n  }\n\n  // Returns true if and only if this matcher matches x.\n  bool Matches(const T& x) const {\n    DummyMatchResultListener dummy;\n    return MatchAndExplain(x, &dummy);\n  }\n\n  // Describes this matcher to an ostream.\n  void DescribeTo(::std::ostream* os) const final {\n    GTEST_CHECK_(vtable_ != nullptr);\n    vtable_->describe(*this, os, false);\n  }\n\n  // Describes the negation of this matcher to an ostream.\n  void DescribeNegationTo(::std::ostream* os) const final {\n    GTEST_CHECK_(vtable_ != nullptr);\n    vtable_->describe(*this, os, true);\n  }\n\n  // Explains why x matches, or doesn't match, the matcher.\n  void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {\n    StreamMatchResultListener listener(os);\n    MatchAndExplain(x, &listener);\n  }\n\n  // Returns the describer for this matcher object; retains ownership\n  // of the describer, which is only guaranteed to be alive when\n  // this matcher object is alive.\n  const MatcherDescriberInterface* GetDescriber() const {\n    if (vtable_ == nullptr) return nullptr;\n    return vtable_->get_describer(*this);\n  }\n\n protected:\n  MatcherBase() : vtable_(nullptr), buffer_() {}\n\n  // Constructs a matcher from its implementation.\n  template <typename U>\n  explicit MatcherBase(const MatcherInterface<U>* impl)\n      : vtable_(nullptr), buffer_() {\n    Init(impl);\n  }\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  MatcherBase(M&& m) : vtable_(nullptr), buffer_() {  // NOLINT\n    Init(std::forward<M>(m));\n  }\n\n  MatcherBase(const MatcherBase& other)\n      : vtable_(other.vtable_), buffer_(other.buffer_) {\n    if (IsShared()) buffer_.shared->Ref();\n  }\n\n  MatcherBase& operator=(const MatcherBase& other) {\n    if (this == &other) return *this;\n    Destroy();\n    vtable_ = other.vtable_;\n    buffer_ = other.buffer_;\n    if (IsShared()) buffer_.shared->Ref();\n    return *this;\n  }\n\n  MatcherBase(MatcherBase&& other)\n      : vtable_(other.vtable_), buffer_(other.buffer_) {\n    other.vtable_ = nullptr;\n  }\n\n  MatcherBase& operator=(MatcherBase&& other) {\n    if (this == &other) return *this;\n    Destroy();\n    vtable_ = other.vtable_;\n    buffer_ = other.buffer_;\n    other.vtable_ = nullptr;\n    return *this;\n  }\n\n  ~MatcherBase() override { Destroy(); }\n\n private:\n  struct VTable {\n    bool (*match_and_explain)(const MatcherBase&, const T&,\n                              MatchResultListener*);\n    void (*describe)(const MatcherBase&, std::ostream*, bool negation);\n    // Returns the captured object if it implements the interface, otherwise\n    // returns the MatcherBase itself.\n    const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);\n    // Called on shared instances when the reference count reaches 0.\n    void (*shared_destroy)(SharedPayloadBase*);\n  };\n\n  bool IsShared() const {\n    return vtable_ != nullptr && vtable_->shared_destroy != nullptr;\n  }\n\n  // If the implementation uses a listener, call that.\n  template <typename P>\n  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,\n                                  MatchResultListener* listener)\n      -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {\n    return P::Get(m).MatchAndExplain(value, listener->stream());\n  }\n\n  template <typename P>\n  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,\n                                  MatchResultListener* listener)\n      -> decltype(P::Get(m).MatchAndExplain(value, listener)) {\n    return P::Get(m).MatchAndExplain(value, listener);\n  }\n\n  template <typename P>\n  static void DescribeImpl(const MatcherBase& m, std::ostream* os,\n                           bool negation) {\n    if (negation) {\n      P::Get(m).DescribeNegationTo(os);\n    } else {\n      P::Get(m).DescribeTo(os);\n    }\n  }\n\n  template <typename P>\n  static const MatcherDescriberInterface* GetDescriberImpl(\n      const MatcherBase& m) {\n    // If the impl is a MatcherDescriberInterface, then return it.\n    // Otherwise use MatcherBase itself.\n    // This allows us to implement the GetDescriber() function without support\n    // from the impl, but some users really want to get their impl back when\n    // they call GetDescriber().\n    // We use std::get on a tuple as a workaround of not having `if constexpr`.\n    return std::get<(\n        std::is_convertible<decltype(&P::Get(m)),\n                            const MatcherDescriberInterface*>::value\n            ? 1\n            : 0)>(std::make_tuple(&m, &P::Get(m)));\n  }\n\n  template <typename P>\n  const VTable* GetVTable() {\n    static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,\n                                       &DescribeImpl<P>, &GetDescriberImpl<P>,\n                                       P::shared_destroy};\n    return &kVTable;\n  }\n\n  union Buffer {\n    // Add some types to give Buffer some common alignment/size use cases.\n    void* ptr;\n    double d;\n    int64_t i;\n    // And add one for the out-of-line cases.\n    SharedPayloadBase* shared;\n  };\n\n  void Destroy() {\n    if (IsShared() && buffer_.shared->Unref()) {\n      vtable_->shared_destroy(buffer_.shared);\n    }\n  }\n\n  template <typename M>\n  static constexpr bool IsInlined() {\n    return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&\n           std::is_trivially_copy_constructible<M>::value &&\n           std::is_trivially_destructible<M>::value;\n  }\n\n  template <typename M, bool = MatcherBase::IsInlined<M>()>\n  struct ValuePolicy {\n    static const M& Get(const MatcherBase& m) {\n      // When inlined along with Init, need to be explicit to avoid violating\n      // strict aliasing rules.\n      const M* ptr =\n          static_cast<const M*>(static_cast<const void*>(&m.buffer_));\n      return *ptr;\n    }\n    static void Init(MatcherBase& m, M impl) {\n      ::new (static_cast<void*>(&m.buffer_)) M(impl);\n    }\n    static constexpr auto shared_destroy = nullptr;\n  };\n\n  template <typename M>\n  struct ValuePolicy<M, false> {\n    using Shared = SharedPayload<M>;\n    static const M& Get(const MatcherBase& m) {\n      return static_cast<Shared*>(m.buffer_.shared)->value;\n    }\n    template <typename Arg>\n    static void Init(MatcherBase& m, Arg&& arg) {\n      m.buffer_.shared = new Shared(std::forward<Arg>(arg));\n    }\n    static constexpr auto shared_destroy = &Shared::Destroy;\n  };\n\n  template <typename U, bool B>\n  struct ValuePolicy<const MatcherInterface<U>*, B> {\n    using M = const MatcherInterface<U>;\n    using Shared = SharedPayload<std::unique_ptr<M>>;\n    static const M& Get(const MatcherBase& m) {\n      return *static_cast<Shared*>(m.buffer_.shared)->value;\n    }\n    static void Init(MatcherBase& m, M* impl) {\n      m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));\n    }\n\n    static constexpr auto shared_destroy = &Shared::Destroy;\n  };\n\n  template <typename M>\n  void Init(M&& m) {\n    using MM = typename std::decay<M>::type;\n    using Policy = ValuePolicy<MM>;\n    vtable_ = GetVTable<Policy>();\n    Policy::Init(*this, std::forward<M>(m));\n  }\n\n  const VTable* vtable_;\n  Buffer buffer_;\n};\n\n}  // namespace internal\n\n// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)\n// object that can check whether a value of type T matches.  The\n// implementation of Matcher<T> is just a std::shared_ptr to const\n// MatcherInterface<T>.  Don't inherit from Matcher!\ntemplate <typename T>\nclass Matcher : public internal::MatcherBase<T> {\n public:\n  // Constructs a null matcher.  Needed for storing Matcher objects in STL\n  // containers.  A default-constructed matcher is not yet initialized.  You\n  // cannot use it until a valid value has been assigned to it.\n  explicit Matcher() {}  // NOLINT\n\n  // Constructs a matcher from its implementation.\n  explicit Matcher(const MatcherInterface<const T&>* impl)\n      : internal::MatcherBase<T>(impl) {}\n\n  template <typename U>\n  explicit Matcher(\n      const MatcherInterface<U>* impl,\n      typename std::enable_if<!std::is_same<U, const U&>::value>::type* =\n          nullptr)\n      : internal::MatcherBase<T>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}  // NOLINT\n\n  // Implicit constructor here allows people to write\n  // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes\n  Matcher(T value);  // NOLINT\n};\n\n// The following two specializations allow the user to write str\n// instead of Eq(str) and \"foo\" instead of Eq(\"foo\") when a std::string\n// matcher is expected.\ntemplate <>\nclass GTEST_API_ Matcher<const std::string&>\n    : public internal::MatcherBase<const std::string&> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const std::string&>* impl)\n      : internal::MatcherBase<const std::string&>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n};\n\ntemplate <>\nclass GTEST_API_ Matcher<std::string>\n    : public internal::MatcherBase<std::string> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const std::string&>* impl)\n      : internal::MatcherBase<std::string>(impl) {}\n  explicit Matcher(const MatcherInterface<std::string>* impl)\n      : internal::MatcherBase<std::string>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<std::string>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n};\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// The following two specializations allow the user to write str\n// instead of Eq(str) and \"foo\" instead of Eq(\"foo\") when a absl::string_view\n// matcher is expected.\ntemplate <>\nclass GTEST_API_ Matcher<const internal::StringView&>\n    : public internal::MatcherBase<const internal::StringView&> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)\n      : internal::MatcherBase<const internal::StringView&>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {\n  }\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n\n  // Allows the user to pass absl::string_views or std::string_views directly.\n  Matcher(internal::StringView s);  // NOLINT\n};\n\ntemplate <>\nclass GTEST_API_ Matcher<internal::StringView>\n    : public internal::MatcherBase<internal::StringView> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)\n      : internal::MatcherBase<internal::StringView>(impl) {}\n  explicit Matcher(const MatcherInterface<internal::StringView>* impl)\n      : internal::MatcherBase<internal::StringView>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n\n  // Allows the user to pass absl::string_views or std::string_views directly.\n  Matcher(internal::StringView s);  // NOLINT\n};\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n// Prints a matcher in a human-readable format.\ntemplate <typename T>\nstd::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {\n  matcher.DescribeTo(&os);\n  return os;\n}\n\n// The PolymorphicMatcher class template makes it easy to implement a\n// polymorphic matcher (i.e. a matcher that can match values of more\n// than one type, e.g. Eq(n) and NotNull()).\n//\n// To define a polymorphic matcher, a user should provide an Impl\n// class that has a DescribeTo() method and a DescribeNegationTo()\n// method, and define a member function (or member function template)\n//\n//   bool MatchAndExplain(const Value& value,\n//                        MatchResultListener* listener) const;\n//\n// See the definition of NotNull() for a complete example.\ntemplate <class Impl>\nclass PolymorphicMatcher {\n public:\n  explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}\n\n  // Returns a mutable reference to the underlying matcher\n  // implementation object.\n  Impl& mutable_impl() { return impl_; }\n\n  // Returns an immutable reference to the underlying matcher\n  // implementation object.\n  const Impl& impl() const { return impl_; }\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(new MonomorphicImpl<const T&>(impl_));\n  }\n\n private:\n  template <typename T>\n  class MonomorphicImpl : public MatcherInterface<T> {\n   public:\n    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}\n\n    void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      impl_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      return impl_.MatchAndExplain(x, listener);\n    }\n\n   private:\n    const Impl impl_;\n  };\n\n  Impl impl_;\n};\n\n// Creates a matcher from its implementation.\n// DEPRECATED: Especially in the generic code, prefer:\n//   Matcher<T>(new MyMatcherImpl<const T&>(...));\n//\n// MakeMatcher may create a Matcher that accepts its argument by value, which\n// leads to unnecessary copies & lack of support for non-copyable types.\ntemplate <typename T>\ninline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {\n  return Matcher<T>(impl);\n}\n\n// Creates a polymorphic matcher from its implementation.  This is\n// easier to use than the PolymorphicMatcher<Impl> constructor as it\n// doesn't require you to explicitly write the template argument, e.g.\n//\n//   MakePolymorphicMatcher(foo);\n// vs\n//   PolymorphicMatcher<TypeOfFoo>(foo);\ntemplate <class Impl>\ninline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {\n  return PolymorphicMatcher<Impl>(impl);\n}\n\nnamespace internal {\n// Implements a matcher that compares a given value with a\n// pre-supplied value using one of the ==, <=, <, etc, operators.  The\n// two values being compared don't have to have the same type.\n//\n// The matcher defined here is polymorphic (for example, Eq(5) can be\n// used to match an int, a short, a double, etc).  Therefore we use\n// a template type conversion operator in the implementation.\n//\n// The following template definition assumes that the Rhs parameter is\n// a \"bare\" type (i.e. neither 'const T' nor 'T&').\ntemplate <typename D, typename Rhs, typename Op>\nclass ComparisonBase {\n public:\n  explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}\n\n  using is_gtest_matcher = void;\n\n  template <typename Lhs>\n  bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {\n    return Op()(lhs, Unwrap(rhs_));\n  }\n  void DescribeTo(std::ostream* os) const {\n    *os << D::Desc() << \" \";\n    UniversalPrint(Unwrap(rhs_), os);\n  }\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << D::NegatedDesc() << \" \";\n    UniversalPrint(Unwrap(rhs_), os);\n  }\n\n private:\n  template <typename T>\n  static const T& Unwrap(const T& v) {\n    return v;\n  }\n  template <typename T>\n  static const T& Unwrap(std::reference_wrapper<T> v) {\n    return v;\n  }\n\n  Rhs rhs_;\n};\n\ntemplate <typename Rhs>\nclass EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {\n public:\n  explicit EqMatcher(const Rhs& rhs)\n      : ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}\n  static const char* Desc() { return \"is equal to\"; }\n  static const char* NegatedDesc() { return \"isn't equal to\"; }\n};\ntemplate <typename Rhs>\nclass NeMatcher\n    : public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {\n public:\n  explicit NeMatcher(const Rhs& rhs)\n      : ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}\n  static const char* Desc() { return \"isn't equal to\"; }\n  static const char* NegatedDesc() { return \"is equal to\"; }\n};\ntemplate <typename Rhs>\nclass LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {\n public:\n  explicit LtMatcher(const Rhs& rhs)\n      : ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}\n  static const char* Desc() { return \"is <\"; }\n  static const char* NegatedDesc() { return \"isn't <\"; }\n};\ntemplate <typename Rhs>\nclass GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {\n public:\n  explicit GtMatcher(const Rhs& rhs)\n      : ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}\n  static const char* Desc() { return \"is >\"; }\n  static const char* NegatedDesc() { return \"isn't >\"; }\n};\ntemplate <typename Rhs>\nclass LeMatcher\n    : public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {\n public:\n  explicit LeMatcher(const Rhs& rhs)\n      : ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}\n  static const char* Desc() { return \"is <=\"; }\n  static const char* NegatedDesc() { return \"isn't <=\"; }\n};\ntemplate <typename Rhs>\nclass GeMatcher\n    : public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {\n public:\n  explicit GeMatcher(const Rhs& rhs)\n      : ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}\n  static const char* Desc() { return \"is >=\"; }\n  static const char* NegatedDesc() { return \"isn't >=\"; }\n};\n\ntemplate <typename T, typename = typename std::enable_if<\n                          std::is_constructible<std::string, T>::value>::type>\nusing StringLike = T;\n\n// Implements polymorphic matchers MatchesRegex(regex) and\n// ContainsRegex(regex), which can be used as a Matcher<T> as long as\n// T can be converted to a string.\nclass MatchesRegexMatcher {\n public:\n  MatchesRegexMatcher(const RE* regex, bool full_match)\n      : regex_(regex), full_match_(full_match) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    return MatchAndExplain(std::string(s), listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(std::string(s), listener);\n  }\n\n  // Matches anything that can convert to std::string.\n  //\n  // This is a template, not just a plain function with const std::string&,\n  // because absl::string_view has some interfering non-explicit constructors.\n  template <class MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const std::string s2(s);\n    return full_match_ ? RE::FullMatch(s2, *regex_)\n                       : RE::PartialMatch(s2, *regex_);\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << (full_match_ ? \"matches\" : \"contains\") << \" regular expression \";\n    UniversalPrinter<std::string>::Print(regex_->pattern(), os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't \" << (full_match_ ? \"match\" : \"contain\")\n        << \" regular expression \";\n    UniversalPrinter<std::string>::Print(regex_->pattern(), os);\n  }\n\n private:\n  const std::shared_ptr<const RE> regex_;\n  const bool full_match_;\n};\n}  // namespace internal\n\n// Matches a string that fully matches regular expression 'regex'.\n// The matcher takes ownership of 'regex'.\ninline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(\n    const internal::RE* regex) {\n  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));\n}\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(\n    const internal::StringLike<T>& regex) {\n  return MatchesRegex(new internal::RE(std::string(regex)));\n}\n\n// Matches a string that contains regular expression 'regex'.\n// The matcher takes ownership of 'regex'.\ninline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(\n    const internal::RE* regex) {\n  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));\n}\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(\n    const internal::StringLike<T>& regex) {\n  return ContainsRegex(new internal::RE(std::string(regex)));\n}\n\n// Creates a polymorphic matcher that matches anything equal to x.\n// Note: if the parameter of Eq() were declared as const T&, Eq(\"foo\")\n// wouldn't compile.\ntemplate <typename T>\ninline internal::EqMatcher<T> Eq(T x) {\n  return internal::EqMatcher<T>(x);\n}\n\n// Constructs a Matcher<T> from a 'value' of type T.  The constructed\n// matcher matches any value that's equal to 'value'.\ntemplate <typename T>\nMatcher<T>::Matcher(T value) {\n  *this = Eq(value);\n}\n\n// Creates a monomorphic matcher that matches anything with type Lhs\n// and equal to rhs.  A user may need to use this instead of Eq(...)\n// in order to resolve an overloading ambiguity.\n//\n// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))\n// or Matcher<T>(x), but more readable than the latter.\n//\n// We could define similar monomorphic matchers for other comparison\n// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do\n// it yet as those are used much less than Eq() in practice.  A user\n// can always write Matcher<T>(Lt(5)) to be explicit about the type,\n// for example.\ntemplate <typename Lhs, typename Rhs>\ninline Matcher<Lhs> TypedEq(const Rhs& rhs) {\n  return Eq(rhs);\n}\n\n// Creates a polymorphic matcher that matches anything >= x.\ntemplate <typename Rhs>\ninline internal::GeMatcher<Rhs> Ge(Rhs x) {\n  return internal::GeMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything > x.\ntemplate <typename Rhs>\ninline internal::GtMatcher<Rhs> Gt(Rhs x) {\n  return internal::GtMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything <= x.\ntemplate <typename Rhs>\ninline internal::LeMatcher<Rhs> Le(Rhs x) {\n  return internal::LeMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything < x.\ntemplate <typename Rhs>\ninline internal::LtMatcher<Rhs> Lt(Rhs x) {\n  return internal::LtMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything != x.\ntemplate <typename Rhs>\ninline internal::NeMatcher<Rhs> Ne(Rhs x) {\n  return internal::NeMatcher<Rhs>(x);\n}\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-message.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the Message class.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n\n#include <limits>\n#include <memory>\n#include <ostream>\n#include <sstream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_HAS_ABSL\n#include <type_traits>\n\n#include \"absl/strings/has_absl_stringify.h\"\n#include \"absl/strings/str_cat.h\"\n#endif  // GTEST_HAS_ABSL\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Ensures that there is at least one operator<< in the global namespace.\n// See Message& operator<<(...) below for why.\nvoid operator<<(const testing::internal::Secret&, int);\n\nnamespace testing {\n\n// The Message class works like an ostream repeater.\n//\n// Typical usage:\n//\n//   1. You stream a bunch of values to a Message object.\n//      It will remember the text in a stringstream.\n//   2. Then you stream the Message object to an ostream.\n//      This causes the text in the Message to be streamed\n//      to the ostream.\n//\n// For example;\n//\n//   testing::Message foo;\n//   foo << 1 << \" != \" << 2;\n//   std::cout << foo;\n//\n// will print \"1 != 2\".\n//\n// Message is not intended to be inherited from.  In particular, its\n// destructor is not virtual.\n//\n// Note that stringstream behaves differently in gcc and in MSVC.  You\n// can stream a NULL char pointer to it in the former, but not in the\n// latter (it causes an access violation if you do).  The Message\n// class hides this difference by treating a NULL char pointer as\n// \"(null)\".\nclass GTEST_API_ Message {\n private:\n  // The type of basic IO manipulators (endl, ends, and flush) for\n  // narrow streams.\n  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);\n\n public:\n  // Constructs an empty Message.\n  Message();\n\n  // Copy constructor.\n  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT\n    *ss_ << msg.GetString();\n  }\n\n  // Constructs a Message from a C-string.\n  explicit Message(const char* str) : ss_(new ::std::stringstream) {\n    *ss_ << str;\n  }\n\n  // Streams a non-pointer value to this object. If building a version of\n  // GoogleTest with ABSL, this overload is only enabled if the value does not\n  // have an AbslStringify definition.\n  template <\n      typename T\n#ifdef GTEST_HAS_ABSL\n      ,\n      typename std::enable_if<!absl::HasAbslStringify<T>::value,  // NOLINT\n                              int>::type = 0\n#endif  // GTEST_HAS_ABSL\n      >\n  inline Message& operator<<(const T& val) {\n        // Some libraries overload << for STL containers.  These\n    // overloads are defined in the global namespace instead of ::std.\n    //\n    // C++'s symbol lookup rule (i.e. Koenig lookup) says that these\n    // overloads are visible in either the std namespace or the global\n    // namespace, but not other namespaces, including the testing\n    // namespace which Google Test's Message class is in.\n    //\n    // To allow STL containers (and other types that has a << operator\n    // defined in the global namespace) to be used in Google Test\n    // assertions, testing::Message must access the custom << operator\n    // from the global namespace.  With this using declaration,\n    // overloads of << defined in the global namespace and those\n    // visible via Koenig lookup are both exposed in this function.\n    using ::operator<<;\n    *ss_ << val;\n    return *this;\n  }\n\n#ifdef GTEST_HAS_ABSL\n  // Streams a non-pointer value with an AbslStringify definition to this\n  // object.\n  template <typename T,\n            typename std::enable_if<absl::HasAbslStringify<T>::value,  // NOLINT\n                                    int>::type = 0>\n  inline Message& operator<<(const T& val) {\n    // ::operator<< is needed here for a similar reason as with the non-Abseil\n    // version above\n    using ::operator<<;\n    *ss_ << absl::StrCat(val);\n    return *this;\n  }\n#endif  // GTEST_HAS_ABSL\n\n  // Streams a pointer value to this object.\n  //\n  // This function is an overload of the previous one.  When you\n  // stream a pointer to a Message, this definition will be used as it\n  // is more specialized.  (The C++ Standard, section\n  // [temp.func.order].)  If you stream a non-pointer, then the\n  // previous definition will be used.\n  //\n  // The reason for this overload is that streaming a NULL pointer to\n  // ostream is undefined behavior.  Depending on the compiler, you\n  // may get \"0\", \"(nil)\", \"(null)\", or an access violation.  To\n  // ensure consistent result across compilers, we always treat NULL\n  // as \"(null)\".\n  template <typename T>\n  inline Message& operator<<(T* const& pointer) {  // NOLINT\n    if (pointer == nullptr) {\n      *ss_ << \"(null)\";\n    } else {\n      *ss_ << pointer;\n    }\n    return *this;\n  }\n\n  // Since the basic IO manipulators are overloaded for both narrow\n  // and wide streams, we have to provide this specialized definition\n  // of operator <<, even though its body is the same as the\n  // templatized version above.  Without this definition, streaming\n  // endl or other basic IO manipulators to Message will confuse the\n  // compiler.\n  Message& operator<<(BasicNarrowIoManip val) {\n    *ss_ << val;\n    return *this;\n  }\n\n  // Instead of 1/0, we want to see true/false for bool values.\n  Message& operator<<(bool b) { return *this << (b ? \"true\" : \"false\"); }\n\n  // These two overloads allow streaming a wide C string to a Message\n  // using the UTF-8 encoding.\n  Message& operator<<(const wchar_t* wide_c_str);\n  Message& operator<<(wchar_t* wide_c_str);\n\n#if GTEST_HAS_STD_WSTRING\n  // Converts the given wide string to a narrow string using the UTF-8\n  // encoding, and streams the result to this Message object.\n  Message& operator<<(const ::std::wstring& wstr);\n#endif  // GTEST_HAS_STD_WSTRING\n\n  // Gets the text streamed to this object so far as an std::string.\n  // Each '\\0' character in the buffer is replaced with \"\\\\0\".\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  std::string GetString() const;\n\n private:\n  // We'll hold the text streamed to this object here.\n  const std::unique_ptr< ::std::stringstream> ss_;\n\n  // We declare (but don't implement) this to prevent the compiler\n  // from implementing the assignment operator.\n  void operator=(const Message&);\n};\n\n// Streams a Message to an ostream.\ninline std::ostream& operator<<(std::ostream& os, const Message& sb) {\n  return os << sb.GetString();\n}\n\nnamespace internal {\n\n// Converts a streamable value to an std::string.  A NULL pointer is\n// converted to \"(null)\".  When the input value is a ::string,\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\n// character in it is replaced with \"\\\\0\".\ntemplate <typename T>\nstd::string StreamableToString(const T& streamable) {\n  return (Message() << streamable).GetString();\n}\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-param-test.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Macros and functions for implementing parameterized tests\n// in Google C++ Testing and Mocking Framework (Google Test)\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n\n// Value-parameterized tests allow you to test your code with different\n// parameters without writing multiple copies of the same test.\n//\n// Here is how you use value-parameterized tests:\n\n#if 0\n\n// To write value-parameterized tests, first you should define a fixture\n// class. It is usually derived from testing::TestWithParam<T> (see below for\n// another inheritance scheme that's sometimes useful in more complicated\n// class hierarchies), where the type of your parameter values.\n// TestWithParam<T> is itself derived from testing::Test. T can be any\n// copyable type. If it's a raw pointer, you are responsible for managing the\n// lifespan of the pointed values.\n\nclass FooTest : public ::testing::TestWithParam<const char*> {\n  // You can implement all the usual class fixture members here.\n};\n\n// Then, use the TEST_P macro to define as many parameterized tests\n// for this fixture as you want. The _P suffix is for \"parameterized\"\n// or \"pattern\", whichever you prefer to think.\n\nTEST_P(FooTest, DoesBlah) {\n  // Inside a test, access the test parameter with the GetParam() method\n  // of the TestWithParam<T> class:\n  EXPECT_TRUE(foo.Blah(GetParam()));\n  ...\n}\n\nTEST_P(FooTest, HasBlahBlah) {\n  ...\n}\n\n// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test\n// case with any set of parameters you want. Google Test defines a number\n// of functions for generating test parameters. They return what we call\n// (surprise!) parameter generators. Here is a summary of them, which\n// are all in the testing namespace:\n//\n//\n//  Range(begin, end [, step]) - Yields values {begin, begin+step,\n//                               begin+step+step, ...}. The values do not\n//                               include end. step defaults to 1.\n//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.\n//  ValuesIn(container)        - Yields values from a C-style array, an STL\n//  ValuesIn(begin,end)          container, or an iterator range [begin, end).\n//  Bool()                     - Yields sequence {false, true}.\n//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product\n//                               for the math savvy) of the values generated\n//                               by the N generators.\n//\n// For more details, see comments at the definitions of these functions below\n// in this file.\n//\n// The following statement will instantiate tests from the FooTest test suite\n// each with parameter values \"meeny\", \"miny\", and \"moe\".\n\nINSTANTIATE_TEST_SUITE_P(InstantiationName,\n                         FooTest,\n                         Values(\"meeny\", \"miny\", \"moe\"));\n\n// To distinguish different instances of the pattern, (yes, you\n// can instantiate it more than once) the first argument to the\n// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the\n// actual test suite name. Remember to pick unique prefixes for different\n// instantiations. The tests from the instantiation above will have\n// these names:\n//\n//    * InstantiationName/FooTest.DoesBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.DoesBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.DoesBlah/2 for \"moe\"\n//    * InstantiationName/FooTest.HasBlahBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.HasBlahBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.HasBlahBlah/2 for \"moe\"\n//\n// You can use these names in --gtest_filter.\n//\n// This statement will instantiate all tests from FooTest again, each\n// with parameter values \"cat\" and \"dog\":\n\nconst char* pets[] = {\"cat\", \"dog\"};\nINSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));\n\n// The tests from the instantiation above will have these names:\n//\n//    * AnotherInstantiationName/FooTest.DoesBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.DoesBlah/1 for \"dog\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for \"dog\"\n//\n// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests\n// in the given test suite, whether their definitions come before or\n// AFTER the INSTANTIATE_TEST_SUITE_P statement.\n//\n// Please also note that generator expressions (including parameters to the\n// generators) are evaluated in InitGoogleTest(), after main() has started.\n// This allows the user on one hand, to adjust generator parameters in order\n// to dynamically determine a set of tests to run and on the other hand,\n// give the user a chance to inspect the generated tests with Google Test\n// reflection API before RUN_ALL_TESTS() is executed.\n//\n// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc\n// for more examples.\n//\n// In the future, we plan to publish the API for defining new parameter\n// generators. But for now this interface remains part of the internal\n// implementation and is subject to change.\n//\n//\n// A parameterized test fixture must be derived from testing::Test and from\n// testing::WithParamInterface<T>, where T is the type of the parameter\n// values. Inheriting from TestWithParam<T> satisfies that requirement because\n// TestWithParam<T> inherits from both Test and WithParamInterface. In more\n// complicated hierarchies, however, it is occasionally useful to inherit\n// separately from Test and WithParamInterface. For example:\n\nclass BaseTest : public ::testing::Test {\n  // You can inherit all the usual members for a non-parameterized test\n  // fixture here.\n};\n\nclass DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {\n  // The usual test fixture members go here too.\n};\n\nTEST_F(BaseTest, HasFoo) {\n  // This is an ordinary non-parameterized test.\n}\n\nTEST_P(DerivedTest, DoesBlah) {\n  // GetParam works just the same here as if you inherit from TestWithParam.\n  EXPECT_TRUE(foo.Blah(GetParam()));\n}\n\n#endif  // 0\n\n#include <iterator>\n#include <utility>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-param-util.h\"  // IWYU pragma: export\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// Functions producing parameter generators.\n//\n// Google Test uses these generators to produce parameters for value-\n// parameterized tests. When a parameterized test suite is instantiated\n// with a particular generator, Google Test creates and runs tests\n// for each element in the sequence produced by the generator.\n//\n// In the following sample, tests from test suite FooTest are instantiated\n// each three times with parameter values 3, 5, and 8:\n//\n// class FooTest : public TestWithParam<int> { ... };\n//\n// TEST_P(FooTest, TestThis) {\n// }\n// TEST_P(FooTest, TestThat) {\n// }\n// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));\n//\n\n// Range() returns generators providing sequences of values in a range.\n//\n// Synopsis:\n// Range(start, end)\n//   - returns a generator producing a sequence of values {start, start+1,\n//     start+2, ..., }.\n// Range(start, end, step)\n//   - returns a generator producing a sequence of values {start, start+step,\n//     start+step+step, ..., }.\n// Notes:\n//   * The generated sequences never include end. For example, Range(1, 5)\n//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)\n//     returns a generator producing {1, 3, 5, 7}.\n//   * start and end must have the same type. That type may be any integral or\n//     floating-point type or a user defined type satisfying these conditions:\n//     * It must be assignable (have operator=() defined).\n//     * It must have operator+() (operator+(int-compatible type) for\n//       two-operand version).\n//     * It must have operator<() defined.\n//     Elements in the resulting sequences will also have that type.\n//   * Condition start < end must be satisfied in order for resulting sequences\n//     to contain any elements.\n//\ntemplate <typename T, typename IncrementT>\ninternal::ParamGenerator<T> Range(T start, T end, IncrementT step) {\n  return internal::ParamGenerator<T>(\n      new internal::RangeGenerator<T, IncrementT>(start, end, step));\n}\n\ntemplate <typename T>\ninternal::ParamGenerator<T> Range(T start, T end) {\n  return Range(start, end, 1);\n}\n\n// ValuesIn() function allows generation of tests with parameters coming from\n// a container.\n//\n// Synopsis:\n// ValuesIn(const T (&array)[N])\n//   - returns a generator producing sequences with elements from\n//     a C-style array.\n// ValuesIn(const Container& container)\n//   - returns a generator producing sequences with elements from\n//     an STL-style container.\n// ValuesIn(Iterator begin, Iterator end)\n//   - returns a generator producing sequences with elements from\n//     a range [begin, end) defined by a pair of STL-style iterators. These\n//     iterators can also be plain C pointers.\n//\n// Please note that ValuesIn copies the values from the containers\n// passed in and keeps them to generate tests in RUN_ALL_TESTS().\n//\n// Examples:\n//\n// This instantiates tests from test suite StringTest\n// each with C-string values of \"foo\", \"bar\", and \"baz\":\n//\n// const char* strings[] = {\"foo\", \"bar\", \"baz\"};\n// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));\n//\n// This instantiates tests from test suite StlStringTest\n// each with STL strings with values \"a\" and \"b\":\n//\n// ::std::vector< ::std::string> GetParameterStrings() {\n//   ::std::vector< ::std::string> v;\n//   v.push_back(\"a\");\n//   v.push_back(\"b\");\n//   return v;\n// }\n//\n// INSTANTIATE_TEST_SUITE_P(CharSequence,\n//                          StlStringTest,\n//                          ValuesIn(GetParameterStrings()));\n//\n//\n// This will also instantiate tests from CharTest\n// each with parameter values 'a' and 'b':\n//\n// ::std::list<char> GetParameterChars() {\n//   ::std::list<char> list;\n//   list.push_back('a');\n//   list.push_back('b');\n//   return list;\n// }\n// ::std::list<char> l = GetParameterChars();\n// INSTANTIATE_TEST_SUITE_P(CharSequence2,\n//                          CharTest,\n//                          ValuesIn(l.begin(), l.end()));\n//\ntemplate <typename ForwardIterator>\ninternal::ParamGenerator<\n    typename std::iterator_traits<ForwardIterator>::value_type>\nValuesIn(ForwardIterator begin, ForwardIterator end) {\n  typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;\n  return internal::ParamGenerator<ParamType>(\n      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));\n}\n\ntemplate <typename T, size_t N>\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {\n  return ValuesIn(array, array + N);\n}\n\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container) {\n  return ValuesIn(container.begin(), container.end());\n}\n\n// Values() allows generating tests from explicitly specified list of\n// parameters.\n//\n// Synopsis:\n// Values(T v1, T v2, ..., T vN)\n//   - returns a generator producing sequences with elements v1, v2, ..., vN.\n//\n// For example, this instantiates tests from test suite BarTest each\n// with values \"one\", \"two\", and \"three\":\n//\n// INSTANTIATE_TEST_SUITE_P(NumSequence,\n//                          BarTest,\n//                          Values(\"one\", \"two\", \"three\"));\n//\n// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.\n// The exact type of values will depend on the type of parameter in BazTest.\n//\n// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));\n//\n//\ntemplate <typename... T>\ninternal::ValueArray<T...> Values(T... v) {\n  return internal::ValueArray<T...>(std::move(v)...);\n}\n\n// Bool() allows generating tests with parameters in a set of (false, true).\n//\n// Synopsis:\n// Bool()\n//   - returns a generator producing sequences with elements {false, true}.\n//\n// It is useful when testing code that depends on Boolean flags. Combinations\n// of multiple flags can be tested when several Bool()'s are combined using\n// Combine() function.\n//\n// In the following example all tests in the test suite FlagDependentTest\n// will be instantiated twice with parameters false and true.\n//\n// class FlagDependentTest : public testing::TestWithParam<bool> {\n//   virtual void SetUp() {\n//     external_flag = GetParam();\n//   }\n// }\n// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());\n//\ninline internal::ParamGenerator<bool> Bool() { return Values(false, true); }\n\n// Combine() allows the user to combine two or more sequences to produce\n// values of a Cartesian product of those sequences' elements.\n//\n// Synopsis:\n// Combine(gen1, gen2, ..., genN)\n//   - returns a generator producing sequences with elements coming from\n//     the Cartesian product of elements from the sequences generated by\n//     gen1, gen2, ..., genN. The sequence elements will have a type of\n//     std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types\n//     of elements from sequences produces by gen1, gen2, ..., genN.\n//\n// Example:\n//\n// This will instantiate tests in test suite AnimalTest each one with\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\n//\n// enum Color { BLACK, GRAY, WHITE };\n// class AnimalTest\n//     : public testing::TestWithParam<std::tuple<const char*, Color> > {...};\n//\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\n//\n// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,\n//                          Combine(Values(\"cat\", \"dog\"),\n//                                  Values(BLACK, WHITE)));\n//\n// This will instantiate tests in FlagDependentTest with all variations of two\n// Boolean flags:\n//\n// class FlagDependentTest\n//     : public testing::TestWithParam<std::tuple<bool, bool> > {\n//   virtual void SetUp() {\n//     // Assigns external_flag_1 and external_flag_2 values from the tuple.\n//     std::tie(external_flag_1, external_flag_2) = GetParam();\n//   }\n// };\n//\n// TEST_P(FlagDependentTest, TestFeature1) {\n//   // Test your code using external_flag_1 and external_flag_2 here.\n// }\n// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,\n//                          Combine(Bool(), Bool()));\n//\ntemplate <typename... Generator>\ninternal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {\n  return internal::CartesianProductHolder<Generator...>(g...);\n}\n\n// ConvertGenerator() wraps a parameter generator in order to cast each produced\n// value through a known type before supplying it to the test suite\n//\n// Synopsis:\n// ConvertGenerator<T>(gen)\n//   - returns a generator producing the same elements as generated by gen, but\n//     each element is static_cast to type T before being returned\n//\n// It is useful when using the Combine() function to get the generated\n// parameters in a custom type instead of std::tuple\n//\n// Example:\n//\n// This will instantiate tests in test suite AnimalTest each one with\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\n//\n// enum Color { BLACK, GRAY, WHITE };\n// struct ParamType {\n//   using TupleT = std::tuple<const char*, Color>;\n//   std::string animal;\n//   Color color;\n//   ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}\n// };\n// class AnimalTest\n//     : public testing::TestWithParam<ParamType> {...};\n//\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\n//\n// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,\n//                          ConvertGenerator<ParamType::TupleT>(\n//                              Combine(Values(\"cat\", \"dog\"),\n//                                      Values(BLACK, WHITE))));\n//\ntemplate <typename T>\ninternal::ParamConverterGenerator<T> ConvertGenerator(\n    internal::ParamGenerator<T> gen) {\n  return internal::ParamConverterGenerator<T>(gen);\n}\n\n#define TEST_P(test_suite_name, test_name)                                     \\\n  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \\\n      : public test_suite_name,                                                \\\n        private ::testing::internal::GTestNonCopyable {                        \\\n   public:                                                                     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {}                    \\\n    void TestBody() override;                                                  \\\n                                                                               \\\n   private:                                                                    \\\n    static int AddToRegistry() {                                               \\\n      ::testing::UnitTest::GetInstance()                                       \\\n          ->parameterized_test_registry()                                      \\\n          .GetTestSuitePatternHolder<test_suite_name>(                         \\\n              GTEST_STRINGIFY_(test_suite_name),                               \\\n              ::testing::internal::CodeLocation(__FILE__, __LINE__))           \\\n          ->AddTestPattern(                                                    \\\n              GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name),  \\\n              new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \\\n                  test_suite_name, test_name)>(),                              \\\n              ::testing::internal::CodeLocation(__FILE__, __LINE__));          \\\n      return 0;                                                                \\\n    }                                                                          \\\n    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \\\n  };                                                                           \\\n  int GTEST_TEST_CLASS_NAME_(test_suite_name,                                  \\\n                             test_name)::gtest_registering_dummy_ =            \\\n      GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry();     \\\n  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()\n\n// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify\n// generator and an optional function or functor that generates custom test name\n// suffixes based on the test parameters. Such a function or functor should\n// accept one argument of type testing::TestParamInfo<class ParamType>, and\n// return std::string.\n//\n// testing::PrintToStringParamName is a builtin test suffix generator that\n// returns the value of testing::PrintToString(GetParam()).\n//\n// Note: test names must be non-empty, unique, and may only contain ASCII\n// alphanumeric characters or underscore. Because PrintToString adds quotes\n// to std::string and C strings, it won't work for these types.\n\n#define GTEST_EXPAND_(arg) arg\n#define GTEST_GET_FIRST_(first, ...) first\n#define GTEST_GET_SECOND_(first, second, ...) second\n\n#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...)               \\\n  static ::testing::internal::ParamGenerator<test_suite_name::ParamType>     \\\n      gtest_##prefix##test_suite_name##_EvalGenerator_() {                   \\\n    return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_));       \\\n  }                                                                          \\\n  static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_(  \\\n      const ::testing::TestParamInfo<test_suite_name::ParamType>& info) {    \\\n    if (::testing::internal::AlwaysFalse()) {                                \\\n      ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_(     \\\n          __VA_ARGS__,                                                       \\\n          ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \\\n          DUMMY_PARAM_)));                                                   \\\n      auto t = std::make_tuple(__VA_ARGS__);                                 \\\n      static_assert(std::tuple_size<decltype(t)>::value <= 2,                \\\n                    \"Too Many Args!\");                                       \\\n    }                                                                        \\\n    return ((GTEST_EXPAND_(GTEST_GET_SECOND_(                                \\\n        __VA_ARGS__,                                                         \\\n        ::testing::internal::DefaultParamName<test_suite_name::ParamType>,   \\\n        DUMMY_PARAM_))))(info);                                              \\\n  }                                                                          \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int                           \\\n      gtest_##prefix##test_suite_name##_dummy_ =                             \\\n          ::testing::UnitTest::GetInstance()                                 \\\n              ->parameterized_test_registry()                                \\\n              .GetTestSuitePatternHolder<test_suite_name>(                   \\\n                  GTEST_STRINGIFY_(test_suite_name),                         \\\n                  ::testing::internal::CodeLocation(__FILE__, __LINE__))     \\\n              ->AddTestSuiteInstantiation(                                   \\\n                  GTEST_STRINGIFY_(prefix),                                  \\\n                  &gtest_##prefix##test_suite_name##_EvalGenerator_,         \\\n                  &gtest_##prefix##test_suite_name##_EvalGenerateName_,      \\\n                  __FILE__, __LINE__)\n\n// Allow Marking a Parameterized test class as not needing to be instantiated.\n#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T)                  \\\n  namespace gtest_do_not_use_outside_namespace_scope {}                   \\\n  static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \\\n      GTEST_STRINGIFY_(T))\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define INSTANTIATE_TEST_CASE_P                                            \\\n  static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \\\n                \"\");                                                       \\\n  INSTANTIATE_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-printers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test - The Google C++ Testing and Mocking Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// A user can teach this function how to print a class type T by\n// defining either operator<<() or PrintTo() in the namespace that\n// defines T.  More specifically, the FIRST defined function in the\n// following list will be used (assuming T is defined in namespace\n// foo):\n//\n//   1. foo::PrintTo(const T&, ostream*)\n//   2. operator<<(ostream&, const T&) defined in either foo or the\n//      global namespace.\n// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.\n// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an\n//   alternative presentation in test results is of interest.\n//\n// However if T is an STL-style container then it is printed element-wise\n// unless foo::PrintTo(const T&, ostream*) is defined. Note that\n// operator<<() is ignored for container types.\n//\n// If none of the above is defined, it will print the debug string of\n// the value if it is a protocol buffer, or print the raw bytes in the\n// value otherwise.\n//\n// To aid debugging: when T is a reference type, the address of the\n// value is also printed; when T is a (const) char pointer, both the\n// pointer value and the NUL-terminated string it points to are\n// printed.\n//\n// We also provide some convenient wrappers:\n//\n//   // Prints a value to a string.  For a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   std::string ::testing::PrintToString(const T& value);\n//\n//   // Prints a value tersely: for a reference type, the referenced\n//   // value (but not the address) is printed; for a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);\n//\n//   // Prints value using the type inferred by the compiler.  The difference\n//   // from UniversalTersePrint() is that this function prints both the\n//   // pointer and the NUL-terminated string for a (const or not) char pointer.\n//   void ::testing::internal::UniversalPrint(const T& value, ostream*);\n//\n//   // Prints the fields of a tuple tersely to a string vector, one\n//   // element for each field. Tuple support must be enabled in\n//   // gtest-port.h.\n//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(\n//       const Tuple& value);\n//\n// Known limitation:\n//\n// The print primitives print the elements of an STL-style container\n// using the compiler-inferred type of *iter where iter is a\n// const_iterator of the container.  When const_iterator is an input\n// iterator but not a forward iterator, this inferred type may not\n// match value_type, and the print output may be incorrect.  In\n// practice, this is rarely a problem as for most containers\n// const_iterator is a forward iterator.  We'll fix this if there's an\n// actual need for it.  Note that this fix cannot rely on value_type\n// being defined as many user-defined container types don't have\n// value_type.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n\n#include <functional>\n#include <memory>\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <typeinfo>\n#include <utility>\n#include <vector>\n\n#ifdef GTEST_HAS_ABSL\n#include \"absl/strings/has_absl_stringify.h\"\n#include \"absl/strings/str_cat.h\"\n#endif  // GTEST_HAS_ABSL\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if GTEST_INTERNAL_HAS_STD_SPAN\n#include <span>  // NOLINT\n#endif           // GTEST_INTERNAL_HAS_STD_SPAN\n\nnamespace testing {\n\n// Definitions in the internal* namespaces are subject to change without notice.\n// DO NOT USE THEM IN USER CODE!\nnamespace internal {\n\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os);\n\ntemplate <typename T>\nstruct IsStdSpan {\n  static constexpr bool value = false;\n};\n\n#if GTEST_INTERNAL_HAS_STD_SPAN\ntemplate <typename E>\nstruct IsStdSpan<std::span<E>> {\n  static constexpr bool value = true;\n};\n#endif  // GTEST_INTERNAL_HAS_STD_SPAN\n\n// Used to print an STL-style container when the user doesn't define\n// a PrintTo() for it.\n//\n// NOTE: Since std::span does not have const_iterator until C++23, it would\n// fail IsContainerTest before C++23. However, IsContainerTest only uses\n// the presence of const_iterator to avoid treating iterators as containers\n// because of iterator::iterator. Which means std::span satisfies the *intended*\n// condition of IsContainerTest.\nstruct ContainerPrinter {\n  template <typename T,\n            typename = typename std::enable_if<\n                ((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&\n                 !IsRecursiveContainer<T>::value) ||\n                IsStdSpan<T>::value>::type>\n  static void PrintValue(const T& container, std::ostream* os) {\n    const size_t kMaxCount = 32;  // The maximum number of elements to print.\n    *os << '{';\n    size_t count = 0;\n    for (auto&& elem : container) {\n      if (count > 0) {\n        *os << ',';\n        if (count == kMaxCount) {  // Enough has been printed.\n          *os << \" ...\";\n          break;\n        }\n      }\n      *os << ' ';\n      // We cannot call PrintTo(elem, os) here as PrintTo() doesn't\n      // handle `elem` being a native array.\n      internal::UniversalPrint(elem, os);\n      ++count;\n    }\n\n    if (count > 0) {\n      *os << ' ';\n    }\n    *os << '}';\n  }\n};\n\n// Used to print a pointer that is neither a char pointer nor a member\n// pointer, when the user doesn't define PrintTo() for it.  (A member\n// variable pointer or member function pointer doesn't really point to\n// a location in the address space.  Their representation is\n// implementation-defined.  Therefore they will be printed as raw\n// bytes.)\nstruct FunctionPointerPrinter {\n  template <typename T, typename = typename std::enable_if<\n                            std::is_function<T>::value>::type>\n  static void PrintValue(T* p, ::std::ostream* os) {\n    if (p == nullptr) {\n      *os << \"NULL\";\n    } else {\n      // T is a function type, so '*os << p' doesn't do what we want\n      // (it just prints p as bool).  We want to print p as a const\n      // void*.\n      *os << reinterpret_cast<const void*>(p);\n    }\n  }\n};\n\nstruct PointerPrinter {\n  template <typename T>\n  static void PrintValue(T* p, ::std::ostream* os) {\n    if (p == nullptr) {\n      *os << \"NULL\";\n    } else {\n      // T is not a function type.  We just call << to print p,\n      // relying on ADL to pick up user-defined << for their pointer\n      // types, if any.\n      *os << p;\n    }\n  }\n};\n\nnamespace internal_stream_operator_without_lexical_name_lookup {\n\n// The presence of an operator<< here will terminate lexical scope lookup\n// straight away (even though it cannot be a match because of its argument\n// types). Thus, the two operator<< calls in StreamPrinter will find only ADL\n// candidates.\nstruct LookupBlocker {};\nvoid operator<<(LookupBlocker, LookupBlocker);\n\nstruct StreamPrinter {\n  template <typename T,\n            // Don't accept member pointers here. We'd print them via implicit\n            // conversion to bool, which isn't useful.\n            typename = typename std::enable_if<\n                !std::is_member_pointer<T>::value>::type>\n  // Only accept types for which we can find a streaming operator via\n  // ADL (possibly involving implicit conversions).\n  // (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name\n  // lookup properly when we do it in the template parameter list.)\n  static auto PrintValue(const T& value,\n                         ::std::ostream* os) -> decltype((void)(*os << value)) {\n    // Call streaming operator found by ADL, possibly with implicit conversions\n    // of the arguments.\n    *os << value;\n  }\n};\n\n}  // namespace internal_stream_operator_without_lexical_name_lookup\n\nstruct ProtobufPrinter {\n  // We print a protobuf using its ShortDebugString() when the string\n  // doesn't exceed this many characters; otherwise we print it using\n  // DebugString() for better readability.\n  static const size_t kProtobufOneLinerMaxLength = 50;\n\n  template <typename T,\n            typename = typename std::enable_if<\n                internal::HasDebugStringAndShortDebugString<T>::value>::type>\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    std::string pretty_str = value.ShortDebugString();\n    if (pretty_str.length() > kProtobufOneLinerMaxLength) {\n      pretty_str = \"\\n\" + value.DebugString();\n    }\n    *os << (\"<\" + pretty_str + \">\");\n  }\n};\n\nstruct ConvertibleToIntegerPrinter {\n  // Since T has no << operator or PrintTo() but can be implicitly\n  // converted to BiggestInt, we print it as a BiggestInt.\n  //\n  // Most likely T is an enum type (either named or unnamed), in which\n  // case printing it as an integer is the desired behavior.  In case\n  // T is not an enum, printing it as an integer is the best we can do\n  // given that it has no user-defined printer.\n  static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {\n    *os << value;\n  }\n};\n\nstruct ConvertibleToStringViewPrinter {\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  static void PrintValue(internal::StringView value, ::std::ostream* os) {\n    internal::UniversalPrint(value, os);\n  }\n#endif\n};\n\n#ifdef GTEST_HAS_ABSL\nstruct ConvertibleToAbslStringifyPrinter {\n  template <typename T,\n            typename = typename std::enable_if<\n                absl::HasAbslStringify<T>::value>::type>  // NOLINT\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    *os << absl::StrCat(value);\n  }\n};\n#endif  // GTEST_HAS_ABSL\n\n// Prints the given number of bytes in the given object to the given\n// ostream.\nGTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,\n                                     size_t count, ::std::ostream* os);\nstruct RawBytesPrinter {\n  // SFINAE on `sizeof` to make sure we have a complete type.\n  template <typename T, size_t = sizeof(T)>\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    PrintBytesInObjectTo(\n        static_cast<const unsigned char*>(\n            // Load bearing cast to void* to support iOS\n            reinterpret_cast<const void*>(std::addressof(value))),\n        sizeof(value), os);\n  }\n};\n\nstruct FallbackPrinter {\n  template <typename T>\n  static void PrintValue(const T&, ::std::ostream* os) {\n    *os << \"(incomplete type)\";\n  }\n};\n\n// Try every printer in order and return the first one that works.\ntemplate <typename T, typename E, typename Printer, typename... Printers>\nstruct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};\n\ntemplate <typename T, typename Printer, typename... Printers>\nstruct FindFirstPrinter<\n    T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),\n    Printer, Printers...> {\n  using type = Printer;\n};\n\n// Select the best printer in the following order:\n//  - Print containers (they have begin/end/etc).\n//  - Print function pointers.\n//  - Print object pointers.\n//  - Print protocol buffers.\n//  - Use the stream operator, if available.\n//  - Print types convertible to BiggestInt.\n//  - Print types convertible to StringView, if available.\n//  - Fallback to printing the raw bytes of the object.\ntemplate <typename T>\nvoid PrintWithFallback(const T& value, ::std::ostream* os) {\n  using Printer = typename FindFirstPrinter<\n      T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,\n      ProtobufPrinter,\n#ifdef GTEST_HAS_ABSL\n      ConvertibleToAbslStringifyPrinter,\n#endif  // GTEST_HAS_ABSL\n      internal_stream_operator_without_lexical_name_lookup::StreamPrinter,\n      ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,\n      RawBytesPrinter, FallbackPrinter>::type;\n  Printer::PrintValue(value, os);\n}\n\n// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a\n// value of type ToPrint that is an operand of a comparison assertion\n// (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in\n// the comparison, and is used to help determine the best way to\n// format the value.  In particular, when the value is a C string\n// (char pointer) and the other operand is an STL string object, we\n// want to format the C string as a string, since we know it is\n// compared by value with the string object.  If the value is a char\n// pointer but the other operand is not an STL string object, we don't\n// know whether the pointer is supposed to point to a NUL-terminated\n// string, and thus want to print it as a pointer to be safe.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n// The default case.\ntemplate <typename ToPrint, typename OtherOperand>\nclass FormatForComparison {\n public:\n  static ::std::string Format(const ToPrint& value) {\n    return ::testing::PrintToString(value);\n  }\n};\n\n// Array.\ntemplate <typename ToPrint, size_t N, typename OtherOperand>\nclass FormatForComparison<ToPrint[N], OtherOperand> {\n public:\n  static ::std::string Format(const ToPrint* value) {\n    return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);\n  }\n};\n\n// By default, print C string as pointers to be safe, as we don't know\n// whether they actually point to a NUL-terminated string.\n\n#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \\\n  template <typename OtherOperand>                                      \\\n  class FormatForComparison<CharType*, OtherOperand> {                  \\\n   public:                                                              \\\n    static ::std::string Format(CharType* value) {                      \\\n      return ::testing::PrintToString(static_cast<const void*>(value)); \\\n    }                                                                   \\\n  }\n\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);\n#ifdef __cpp_lib_char8_t\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);\n#endif\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);\n\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_\n\n// If a C string is compared with an STL string object, we know it's meant\n// to point to a NUL-terminated string, and thus can print it as a string.\n\n#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \\\n  template <>                                                            \\\n  class FormatForComparison<CharType*, OtherStringType> {                \\\n   public:                                                               \\\n    static ::std::string Format(CharType* value) {                       \\\n      return ::testing::PrintToString(value);                            \\\n    }                                                                    \\\n  }\n\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);\n#ifdef __cpp_lib_char8_t\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);\n#endif\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);\n#endif\n\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_\n\n// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)\n// operand to be used in a failure message.  The type (but not value)\n// of the other operand may affect the format.  This allows us to\n// print a char* as a raw pointer when it is compared against another\n// char* or void*, and print it as a C string when it is compared\n// against an std::string object, for example.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename T1, typename T2>\nstd::string FormatForComparisonFailureMessage(const T1& value,\n                                              const T2& /* other_operand */) {\n  return FormatForComparison<T1, T2>::Format(value);\n}\n\n// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given\n// value to the given ostream.  The caller must ensure that\n// 'ostream_ptr' is not NULL, or the behavior is undefined.\n//\n// We define UniversalPrinter as a class template (as opposed to a\n// function template), as we need to partially specialize it for\n// reference types, which cannot be done with function templates.\ntemplate <typename T>\nclass UniversalPrinter;\n\n// Prints the given value using the << operator if it has one;\n// otherwise prints the bytes in it.  This is what\n// UniversalPrinter<T>::Print() does when PrintTo() is not specialized\n// or overloaded for type T.\n//\n// A user can override this behavior for a class type Foo by defining\n// an overload of PrintTo() in the namespace where Foo is defined.  We\n// give the user this option as sometimes defining a << operator for\n// Foo is not desirable (e.g. the coding style may prevent doing it,\n// or there is already a << operator but it doesn't do what the user\n// wants).\ntemplate <typename T>\nvoid PrintTo(const T& value, ::std::ostream* os) {\n  internal::PrintWithFallback(value, os);\n}\n\n// The following list of PrintTo() overloads tells\n// UniversalPrinter<T>::Print() how to print standard types (built-in\n// types, strings, plain arrays, and pointers).\n\n// Overloads for various char types.\nGTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);\nGTEST_API_ void PrintTo(signed char c, ::std::ostream* os);\ninline void PrintTo(char c, ::std::ostream* os) {\n  // When printing a plain char, we always treat it as unsigned.  This\n  // way, the output won't be affected by whether the compiler thinks\n  // char is signed or not.\n  PrintTo(static_cast<unsigned char>(c), os);\n}\n\n// Overloads for other simple built-in types.\ninline void PrintTo(bool x, ::std::ostream* os) {\n  *os << (x ? \"true\" : \"false\");\n}\n\n// Overload for wchar_t type.\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its decimal code (except for L'\\0').\n// The L'\\0' char is printed as \"L'\\\\0'\". The decimal code is printed\n// as signed integer when wchar_t is implemented by the compiler\n// as a signed type and is printed as an unsigned integer when wchar_t\n// is implemented as an unsigned type.\nGTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);\n\nGTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);\ninline void PrintTo(char16_t c, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<char32_t>(c), os);\n}\n#ifdef __cpp_lib_char8_t\ninline void PrintTo(char8_t c, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<char32_t>(c), os);\n}\n#endif\n\n// gcc/clang __{u,}int128_t\n#if defined(__SIZEOF_INT128__)\nGTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);\nGTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);\n#endif  // __SIZEOF_INT128__\n\n// The default resolution used to print floating-point values uses only\n// 6 digits, which can be confusing if a test compares two values whose\n// difference lies in the 7th digit.  So we'd like to print out numbers\n// in full precision.\n// However if the value is something simple like 1.1, full will print a\n// long string like 1.100000001 due to floating-point numbers not using\n// a base of 10.  This routiune returns an appropriate resolution for a\n// given floating-point number, that is, 6 if it will be accurate, or a\n// max_digits10 value (full precision) if it won't,  for values between\n// 0.0001 and one million.\n// It does this by computing what those digits would be (by multiplying\n// by an appropriate power of 10), then dividing by that power again to\n// see if gets the original value back.\n// A similar algorithm applies for values larger than one million; note\n// that for those values, we must divide to get a six-digit number, and\n// then multiply to possibly get the original value again.\ntemplate <typename FloatType>\nint AppropriateResolution(FloatType val) {\n  int full = std::numeric_limits<FloatType>::max_digits10;\n  if (val < 0) val = -val;\n\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n  if (val < 1000000) {\n    FloatType mulfor6 = 1e10;\n    // Without these static casts, the template instantiation for float would\n    // fail to compile when -Wdouble-promotion is enabled, as the arithmetic and\n    // comparison logic would promote floats to doubles.\n    if (val >= static_cast<FloatType>(100000.0)) {  // 100,000 to 999,999\n      mulfor6 = 1.0;\n    } else if (val >= static_cast<FloatType>(10000.0)) {\n      mulfor6 = 1e1;\n    } else if (val >= static_cast<FloatType>(1000.0)) {\n      mulfor6 = 1e2;\n    } else if (val >= static_cast<FloatType>(100.0)) {\n      mulfor6 = 1e3;\n    } else if (val >= static_cast<FloatType>(10.0)) {\n      mulfor6 = 1e4;\n    } else if (val >= static_cast<FloatType>(1.0)) {\n      mulfor6 = 1e5;\n    } else if (val >= static_cast<FloatType>(0.1)) {\n      mulfor6 = 1e6;\n    } else if (val >= static_cast<FloatType>(0.01)) {\n      mulfor6 = 1e7;\n    } else if (val >= static_cast<FloatType>(0.001)) {\n      mulfor6 = 1e8;\n    } else if (val >= static_cast<FloatType>(0.0001)) {\n      mulfor6 = 1e9;\n    }\n    if (static_cast<FloatType>(static_cast<int32_t>(\n            val * mulfor6 + (static_cast<FloatType>(0.5)))) /\n            mulfor6 ==\n        val)\n      return 6;\n  } else if (val < static_cast<FloatType>(1e10)) {\n    FloatType divfor6 = static_cast<FloatType>(1.0);\n    if (val >= static_cast<FloatType>(1e9)) {  // 1,000,000,000 to 9,999,999,999\n      divfor6 = 10000;\n    } else if (val >=\n               static_cast<FloatType>(1e8)) {  // 100,000,000 to 999,999,999\n      divfor6 = 1000;\n    } else if (val >=\n               static_cast<FloatType>(1e7)) {  // 10,000,000 to 99,999,999\n      divfor6 = 100;\n    } else if (val >= static_cast<FloatType>(1e6)) {  // 1,000,000 to 9,999,999\n      divfor6 = 10;\n    }\n    if (static_cast<FloatType>(static_cast<int32_t>(\n            val / divfor6 + (static_cast<FloatType>(0.5)))) *\n            divfor6 ==\n        val)\n      return 6;\n  }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n  return full;\n}\n\ninline void PrintTo(float f, ::std::ostream* os) {\n  auto old_precision = os->precision();\n  os->precision(AppropriateResolution(f));\n  *os << f;\n  os->precision(old_precision);\n}\n\ninline void PrintTo(double d, ::std::ostream* os) {\n  auto old_precision = os->precision();\n  os->precision(AppropriateResolution(d));\n  *os << d;\n  os->precision(old_precision);\n}\n\n// Overloads for C strings.\nGTEST_API_ void PrintTo(const char* s, ::std::ostream* os);\ninline void PrintTo(char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char*>(s), os);\n}\n\n// signed/unsigned char is often used for representing binary data, so\n// we print pointers to it as void* to be safe.\ninline void PrintTo(const signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(const unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\n#ifdef __cpp_lib_char8_t\n// Overloads for u8 strings.\nGTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);\ninline void PrintTo(char8_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char8_t*>(s), os);\n}\n#endif\n// Overloads for u16 strings.\nGTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);\ninline void PrintTo(char16_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char16_t*>(s), os);\n}\n// Overloads for u32 strings.\nGTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);\ninline void PrintTo(char32_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char32_t*>(s), os);\n}\n\n// MSVC can be configured to define wchar_t as a typedef of unsigned\n// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native\n// type.  When wchar_t is a typedef, defining an overload for const\n// wchar_t* would cause unsigned short* be printed as a wide string,\n// possibly causing invalid memory accesses.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Overloads for wide C strings\nGTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);\ninline void PrintTo(wchar_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const wchar_t*>(s), os);\n}\n#endif\n\n// Overload for C arrays.  Multi-dimensional arrays are printed\n// properly.\n\n// Prints the given number of elements in an array, without printing\n// the curly braces.\ntemplate <typename T>\nvoid PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {\n  UniversalPrint(a[0], os);\n  for (size_t i = 1; i != count; i++) {\n    *os << \", \";\n    UniversalPrint(a[i], os);\n  }\n}\n\n// Overloads for ::std::string.\nGTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::string& s, ::std::ostream* os) {\n  PrintStringTo(s, os);\n}\n\n// Overloads for ::std::u8string\n#ifdef __cpp_lib_char8_t\nGTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {\n  PrintU8StringTo(s, os);\n}\n#endif\n\n// Overloads for ::std::u16string\nGTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {\n  PrintU16StringTo(s, os);\n}\n\n// Overloads for ::std::u32string\nGTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {\n  PrintU32StringTo(s, os);\n}\n\n// Overloads for ::std::wstring.\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);\ninline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {\n  PrintWideStringTo(s, os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// Overload for internal::StringView.\ninline void PrintTo(internal::StringView sp, ::std::ostream* os) {\n  PrintTo(::std::string(sp), os);\n}\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\ninline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << \"(nullptr)\"; }\n\n#if GTEST_HAS_RTTI\ninline void PrintTo(const std::type_info& info, std::ostream* os) {\n  *os << internal::GetTypeName(info);\n}\n#endif  // GTEST_HAS_RTTI\n\ntemplate <typename T>\nvoid PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {\n  UniversalPrinter<T&>::Print(ref.get(), os);\n}\n\ninline const void* VoidifyPointer(const void* p) { return p; }\ninline const void* VoidifyPointer(volatile const void* p) {\n  return const_cast<const void*>(p);\n}\n\ntemplate <typename T, typename Ptr>\nvoid PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {\n  if (ptr == nullptr) {\n    *os << \"(nullptr)\";\n  } else {\n    // We can't print the value. Just print the pointer..\n    *os << \"(\" << (VoidifyPointer)(ptr.get()) << \")\";\n  }\n}\ntemplate <typename T, typename Ptr,\n          typename = typename std::enable_if<!std::is_void<T>::value &&\n                                             !std::is_array<T>::value>::type>\nvoid PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {\n  if (ptr == nullptr) {\n    *os << \"(nullptr)\";\n  } else {\n    *os << \"(ptr = \" << (VoidifyPointer)(ptr.get()) << \", value = \";\n    UniversalPrinter<T>::Print(*ptr, os);\n    *os << \")\";\n  }\n}\n\ntemplate <typename T, typename D>\nvoid PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {\n  (PrintSmartPointer<T>)(ptr, os, 0);\n}\n\ntemplate <typename T>\nvoid PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {\n  (PrintSmartPointer<T>)(ptr, os, 0);\n}\n\n// Helper function for printing a tuple.  T must be instantiated with\n// a tuple type.\ntemplate <typename T>\nvoid PrintTupleTo(const T&, std::integral_constant<size_t, 0>,\n                  ::std::ostream*) {}\n\ntemplate <typename T, size_t I>\nvoid PrintTupleTo(const T& t, std::integral_constant<size_t, I>,\n                  ::std::ostream* os) {\n  PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);\n  GTEST_INTENTIONAL_CONST_COND_PUSH_()\n  if (I > 1) {\n    GTEST_INTENTIONAL_CONST_COND_POP_()\n    *os << \", \";\n  }\n  UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(\n      std::get<I - 1>(t), os);\n}\n\ntemplate <typename... Types>\nvoid PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {\n  *os << \"(\";\n  PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);\n  *os << \")\";\n}\n\n// Overload for std::pair.\ntemplate <typename T1, typename T2>\nvoid PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {\n  *os << '(';\n  // We cannot use UniversalPrint(value.first, os) here, as T1 may be\n  // a reference type.  The same for printing value.second.\n  UniversalPrinter<T1>::Print(value.first, os);\n  *os << \", \";\n  UniversalPrinter<T2>::Print(value.second, os);\n  *os << ')';\n}\n\n// Implements printing a non-reference type T by letting the compiler\n// pick the right overload of PrintTo() for T.\ntemplate <typename T>\nclass UniversalPrinter {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)\n\n  // Note: we deliberately don't call this PrintTo(), as that name\n  // conflicts with ::testing::internal::PrintTo in the body of the\n  // function.\n  static void Print(const T& value, ::std::ostream* os) {\n    // By default, ::testing::internal::PrintTo() is used for printing\n    // the value.\n    //\n    // Thanks to Koenig look-up, if T is a class and has its own\n    // PrintTo() function defined in its namespace, that function will\n    // be visible here.  Since it is more specific than the generic ones\n    // in ::testing::internal, it will be picked by the compiler in the\n    // following statement - exactly what we want.\n    PrintTo(value, os);\n  }\n\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n};\n\n// Remove any const-qualifiers before passing a type to UniversalPrinter.\ntemplate <typename T>\nclass UniversalPrinter<const T> : public UniversalPrinter<T> {};\n\n#if GTEST_INTERNAL_HAS_ANY\n\n// Printer for std::any / absl::any\n\ntemplate <>\nclass UniversalPrinter<Any> {\n public:\n  static void Print(const Any& value, ::std::ostream* os) {\n    if (value.has_value()) {\n      *os << \"value of type \" << GetTypeName(value);\n    } else {\n      *os << \"no value\";\n    }\n  }\n\n private:\n  static std::string GetTypeName(const Any& value) {\n#if GTEST_HAS_RTTI\n    return internal::GetTypeName(value.type());\n#else\n    static_cast<void>(value);  // possibly unused\n    return \"<unknown_type>\";\n#endif  // GTEST_HAS_RTTI\n  }\n};\n\n#endif  // GTEST_INTERNAL_HAS_ANY\n\n#if GTEST_INTERNAL_HAS_OPTIONAL\n\n// Printer for std::optional / absl::optional\n\ntemplate <typename T>\nclass UniversalPrinter<Optional<T>> {\n public:\n  static void Print(const Optional<T>& value, ::std::ostream* os) {\n    *os << '(';\n    if (!value) {\n      *os << \"nullopt\";\n    } else {\n      UniversalPrint(*value, os);\n    }\n    *os << ')';\n  }\n};\n\ntemplate <>\nclass UniversalPrinter<decltype(Nullopt())> {\n public:\n  static void Print(decltype(Nullopt()), ::std::ostream* os) {\n    *os << \"(nullopt)\";\n  }\n};\n\n#endif  // GTEST_INTERNAL_HAS_OPTIONAL\n\n#if GTEST_INTERNAL_HAS_VARIANT\n\n// Printer for std::variant / absl::variant\n\ntemplate <typename... T>\nclass UniversalPrinter<Variant<T...>> {\n public:\n  static void Print(const Variant<T...>& value, ::std::ostream* os) {\n    *os << '(';\n#ifdef GTEST_HAS_ABSL\n    absl::visit(Visitor{os, value.index()}, value);\n#else\n    std::visit(Visitor{os, value.index()}, value);\n#endif  // GTEST_HAS_ABSL\n    *os << ')';\n  }\n\n private:\n  struct Visitor {\n    template <typename U>\n    void operator()(const U& u) const {\n      *os << \"'\" << GetTypeName<U>() << \"(index = \" << index\n          << \")' with value \";\n      UniversalPrint(u, os);\n    }\n    ::std::ostream* os;\n    std::size_t index;\n  };\n};\n\n#endif  // GTEST_INTERNAL_HAS_VARIANT\n\n// UniversalPrintArray(begin, len, os) prints an array of 'len'\n// elements, starting at address 'begin'.\ntemplate <typename T>\nvoid UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {\n  if (len == 0) {\n    *os << \"{}\";\n  } else {\n    *os << \"{ \";\n    const size_t kThreshold = 18;\n    const size_t kChunkSize = 8;\n    // If the array has more than kThreshold elements, we'll have to\n    // omit some details by printing only the first and the last\n    // kChunkSize elements.\n    if (len <= kThreshold) {\n      PrintRawArrayTo(begin, len, os);\n    } else {\n      PrintRawArrayTo(begin, kChunkSize, os);\n      *os << \", ..., \";\n      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);\n    }\n    *os << \" }\";\n  }\n}\n// This overload prints a (const) char array compactly.\nGTEST_API_ void UniversalPrintArray(const char* begin, size_t len,\n                                    ::std::ostream* os);\n\n#ifdef __cpp_lib_char8_t\n// This overload prints a (const) char8_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,\n                                    ::std::ostream* os);\n#endif\n\n// This overload prints a (const) char16_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// This overload prints a (const) char32_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// This overload prints a (const) wchar_t array compactly.\nGTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// Implements printing an array type T[N].\ntemplate <typename T, size_t N>\nclass UniversalPrinter<T[N]> {\n public:\n  // Prints the given array, omitting some elements when there are too\n  // many.\n  static void Print(const T (&a)[N], ::std::ostream* os) {\n    UniversalPrintArray(a, N, os);\n  }\n};\n\n// Implements printing a reference type T&.\ntemplate <typename T>\nclass UniversalPrinter<T&> {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)\n\n  static void Print(const T& value, ::std::ostream* os) {\n    // Prints the address of the value.  We use reinterpret_cast here\n    // as static_cast doesn't compile when T is a function type.\n    *os << \"@\" << reinterpret_cast<const void*>(&value) << \" \";\n\n    // Then prints the value itself.\n    UniversalPrint(value, os);\n  }\n\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n};\n\n// Prints a value tersely: for a reference type, the referenced value\n// (but not the address) is printed; for a (const) char pointer, the\n// NUL-terminated string (but not the pointer) is printed.\n\ntemplate <typename T>\nclass UniversalTersePrinter {\n public:\n  static void Print(const T& value, ::std::ostream* os) {\n    UniversalPrint(value, os);\n  }\n};\ntemplate <typename T>\nclass UniversalTersePrinter<T&> {\n public:\n  static void Print(const T& value, ::std::ostream* os) {\n    UniversalPrint(value, os);\n  }\n};\ntemplate <typename T>\nclass UniversalTersePrinter<std::reference_wrapper<T>> {\n public:\n  static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {\n    UniversalTersePrinter<T>::Print(value.get(), os);\n  }\n};\ntemplate <typename T, size_t N>\nclass UniversalTersePrinter<T[N]> {\n public:\n  static void Print(const T (&value)[N], ::std::ostream* os) {\n    UniversalPrinter<T[N]>::Print(value, os);\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<const char*> {\n public:\n  static void Print(const char* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(std::string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {\n};\n\n#ifdef __cpp_lib_char8_t\ntemplate <>\nclass UniversalTersePrinter<const char8_t*> {\n public:\n  static void Print(const char8_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u8string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char8_t*>\n    : public UniversalTersePrinter<const char8_t*> {};\n#endif\n\ntemplate <>\nclass UniversalTersePrinter<const char16_t*> {\n public:\n  static void Print(const char16_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u16string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char16_t*>\n    : public UniversalTersePrinter<const char16_t*> {};\n\ntemplate <>\nclass UniversalTersePrinter<const char32_t*> {\n public:\n  static void Print(const char32_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u32string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char32_t*>\n    : public UniversalTersePrinter<const char32_t*> {};\n\n#if GTEST_HAS_STD_WSTRING\ntemplate <>\nclass UniversalTersePrinter<const wchar_t*> {\n public:\n  static void Print(const wchar_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::wstring(str), os);\n    }\n  }\n};\n#endif\n\ntemplate <>\nclass UniversalTersePrinter<wchar_t*> {\n public:\n  static void Print(wchar_t* str, ::std::ostream* os) {\n    UniversalTersePrinter<const wchar_t*>::Print(str, os);\n  }\n};\n\ntemplate <typename T>\nvoid UniversalTersePrint(const T& value, ::std::ostream* os) {\n  UniversalTersePrinter<T>::Print(value, os);\n}\n\n// Prints a value using the type inferred by the compiler.  The\n// difference between this and UniversalTersePrint() is that for a\n// (const) char pointer, this prints both the pointer and the\n// NUL-terminated string.\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os) {\n  // A workarond for the bug in VC++ 7.1 that prevents us from instantiating\n  // UniversalPrinter with T directly.\n  typedef T T1;\n  UniversalPrinter<T1>::Print(value, os);\n}\n\ntypedef ::std::vector<::std::string> Strings;\n\n// Tersely prints the first N fields of a tuple to a string vector,\n// one element for each field.\ntemplate <typename Tuple>\nvoid TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,\n                               Strings*) {}\ntemplate <typename Tuple, size_t I>\nvoid TersePrintPrefixToStrings(const Tuple& t,\n                               std::integral_constant<size_t, I>,\n                               Strings* strings) {\n  TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),\n                            strings);\n  ::std::stringstream ss;\n  UniversalTersePrint(std::get<I - 1>(t), &ss);\n  strings->push_back(ss.str());\n}\n\n// Prints the fields of a tuple tersely to a string vector, one\n// element for each field.  See the comment before\n// UniversalTersePrint() for how we define \"tersely\".\ntemplate <typename Tuple>\nStrings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {\n  Strings result;\n  TersePrintPrefixToStrings(\n      value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),\n      &result);\n  return result;\n}\n\n}  // namespace internal\n\ntemplate <typename T>\n::std::string PrintToString(const T& value) {\n  ::std::stringstream ss;\n  internal::UniversalTersePrinter<T>::Print(value, &ss);\n  return ss.str();\n}\n\n}  // namespace testing\n\n// Include any custom printer added by the local installation.\n// We must include this header at the end to make sure it can use the\n// declarations from this file.\n#include \"gtest/internal/custom/gtest-printers.h\"\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-spi.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Utilities for testing Google Test itself and code that uses Google Test\n// (e.g. frameworks built on top of Google Test).\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n\n#include <string>\n\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// This helper class can be used to mock out Google Test failure reporting\n// so that we can test Google Test or code that builds on Google Test.\n//\n// An object of this class appends a TestPartResult object to the\n// TestPartResultArray object given in the constructor whenever a Google Test\n// failure is reported. It can either intercept only failures that are\n// generated in the same thread that created this object or it can intercept\n// all generated failures. The scope of this mock object can be controlled with\n// the second argument to the two arguments constructor.\nclass GTEST_API_ ScopedFakeTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  // The two possible mocking modes of this object.\n  enum InterceptMode {\n    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.\n    INTERCEPT_ALL_THREADS           // Intercepts all failures.\n  };\n\n  // The c'tor sets this object as the test part result reporter used\n  // by Google Test.  The 'result' parameter specifies where to report the\n  // results. This reporter will only catch failures generated in the current\n  // thread. DEPRECATED\n  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);\n\n  // Same as above, but you can choose the interception scope of this object.\n  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,\n                                   TestPartResultArray* result);\n\n  // The d'tor restores the previous test part result reporter.\n  ~ScopedFakeTestPartResultReporter() override;\n\n  // Appends the TestPartResult object to the TestPartResultArray\n  // received in the constructor.\n  //\n  // This method is from the TestPartResultReporterInterface\n  // interface.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  void Init();\n\n  const InterceptMode intercept_mode_;\n  TestPartResultReporterInterface* old_reporter_;\n  TestPartResultArray* const result_;\n\n  ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =\n      delete;\n  ScopedFakeTestPartResultReporter& operator=(\n      const ScopedFakeTestPartResultReporter&) = delete;\n};\n\nnamespace internal {\n\n// A helper class for implementing EXPECT_FATAL_FAILURE() and\n// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nclass GTEST_API_ SingleFailureChecker {\n public:\n  // The constructor remembers the arguments.\n  SingleFailureChecker(const TestPartResultArray* results,\n                       TestPartResult::Type type, const std::string& substr);\n  ~SingleFailureChecker();\n\n private:\n  const TestPartResultArray* const results_;\n  const TestPartResult::Type type_;\n  const std::string substr_;\n\n  SingleFailureChecker(const SingleFailureChecker&) = delete;\n  SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// A set of macros for testing Google Test assertions or code that's expected\n// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but\n// not a non-fatal failure, as from EXPECT_EQ).  It verifies that the given\n// statement will cause exactly one fatal Google Test failure with 'substr'\n// being part of the failure message.\n//\n// There are two different versions of this macro. EXPECT_FATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - 'statement' cannot reference local non-static variables or\n//     non-static members of the current object.\n//   - 'statement' cannot return a value.\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in\n// gtest_unittest.cc will fail to compile if we do that.\n#define EXPECT_FATAL_FAILURE(statement, substr)                               \\\n  do {                                                                        \\\n    class GTestExpectFatalFailureHelper {                                     \\\n     public:                                                                  \\\n      static void Execute() { statement; }                                    \\\n    };                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::                       \\\n              INTERCEPT_ONLY_CURRENT_THREAD,                                  \\\n          &gtest_failures);                                                   \\\n      GTestExpectFatalFailureHelper::Execute();                               \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr)                \\\n  do {                                                                        \\\n    class GTestExpectFatalFailureHelper {                                     \\\n     public:                                                                  \\\n      static void Execute() { statement; }                                    \\\n    };                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \\\n          &gtest_failures);                                                   \\\n      GTestExpectFatalFailureHelper::Execute();                               \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n// A macro for testing Google Test assertions or code that's expected to\n// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,\n// but not from an ASSERT_EQ). It asserts that the given statement will cause\n// exactly one non-fatal Google Test failure with 'substr' being part of the\n// failure message.\n//\n// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// 'statement' is allowed to reference local variables and members of\n// the current object.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  If we do that, the code won't compile when the user gives\n// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that\n// expands to code containing an unprotected comma.  The\n// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc\n// catches that.\n//\n// For the same reason, we have to write\n//   if (::testing::internal::AlwaysTrue()) { statement; }\n// instead of\n//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n// to avoid an MSVC warning on unreachable code.\n#define EXPECT_NONFATAL_FAILURE(statement, substr)                    \\\n  do {                                                                \\\n    ::testing::TestPartResultArray gtest_failures;                    \\\n    ::testing::internal::SingleFailureChecker gtest_checker(          \\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\n        (substr));                                                    \\\n    {                                                                 \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(     \\\n          ::testing::ScopedFakeTestPartResultReporter::               \\\n              INTERCEPT_ONLY_CURRENT_THREAD,                          \\\n          &gtest_failures);                                           \\\n      if (::testing::internal::AlwaysTrue()) {                        \\\n        statement;                                                    \\\n      }                                                               \\\n    }                                                                 \\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr)             \\\n  do {                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure,         \\\n        (substr));                                                            \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \\\n          &gtest_failures);                                                   \\\n      if (::testing::internal::AlwaysTrue()) {                                \\\n        statement;                                                            \\\n      }                                                                       \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-test-part.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n\n#include <iosfwd>\n#include <ostream>\n#include <string>\n#include <vector>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// A copyable object representing the result of a test part (i.e. an\n// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).\n//\n// Don't inherit from TestPartResult as its destructor is not virtual.\nclass GTEST_API_ TestPartResult {\n public:\n  // The possible outcomes of a test part (i.e. an assertion or an\n  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).\n  enum Type {\n    kSuccess,          // Succeeded.\n    kNonFatalFailure,  // Failed but the test can continue.\n    kFatalFailure,     // Failed and the test should be terminated.\n    kSkip              // Skipped.\n  };\n\n  // C'tor.  TestPartResult does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestPartResult object.\n  TestPartResult(Type a_type, const char* a_file_name, int a_line_number,\n                 const char* a_message)\n      : type_(a_type),\n        file_name_(a_file_name == nullptr ? \"\" : a_file_name),\n        line_number_(a_line_number),\n        summary_(ExtractSummary(a_message)),\n        message_(a_message) {}\n\n  // Gets the outcome of the test part.\n  Type type() const { return type_; }\n\n  // Gets the name of the source file where the test part took place, or\n  // NULL if it's unknown.\n  const char* file_name() const {\n    return file_name_.empty() ? nullptr : file_name_.c_str();\n  }\n\n  // Gets the line in the source file where the test part took place,\n  // or -1 if it's unknown.\n  int line_number() const { return line_number_; }\n\n  // Gets the summary of the failure message.\n  const char* summary() const { return summary_.c_str(); }\n\n  // Gets the message associated with the test part.\n  const char* message() const { return message_.c_str(); }\n\n  // Returns true if and only if the test part was skipped.\n  bool skipped() const { return type_ == kSkip; }\n\n  // Returns true if and only if the test part passed.\n  bool passed() const { return type_ == kSuccess; }\n\n  // Returns true if and only if the test part non-fatally failed.\n  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }\n\n  // Returns true if and only if the test part fatally failed.\n  bool fatally_failed() const { return type_ == kFatalFailure; }\n\n  // Returns true if and only if the test part failed.\n  bool failed() const { return fatally_failed() || nonfatally_failed(); }\n\n private:\n  Type type_;\n\n  // Gets the summary of the failure message by omitting the stack\n  // trace in it.\n  static std::string ExtractSummary(const char* message);\n\n  // The name of the source file where the test part took place, or\n  // \"\" if the source file is unknown.\n  std::string file_name_;\n  // The line in the source file where the test part took place, or -1\n  // if the line number is unknown.\n  int line_number_;\n  std::string summary_;  // The test failure summary.\n  std::string message_;  // The test failure message.\n};\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result);\n\n// An array of TestPartResult objects.\n//\n// Don't inherit from TestPartResultArray as its destructor is not\n// virtual.\nclass GTEST_API_ TestPartResultArray {\n public:\n  TestPartResultArray() = default;\n\n  // Appends the given TestPartResult to the array.\n  void Append(const TestPartResult& result);\n\n  // Returns the TestPartResult at the given index (0-based).\n  const TestPartResult& GetTestPartResult(int index) const;\n\n  // Returns the number of TestPartResult objects in the array.\n  int size() const;\n\n private:\n  std::vector<TestPartResult> array_;\n\n  TestPartResultArray(const TestPartResultArray&) = delete;\n  TestPartResultArray& operator=(const TestPartResultArray&) = delete;\n};\n\n// This interface knows how to report a test part result.\nclass GTEST_API_ TestPartResultReporterInterface {\n public:\n  virtual ~TestPartResultReporterInterface() = default;\n\n  virtual void ReportTestPartResult(const TestPartResult& result) = 0;\n};\n\nnamespace internal {\n\n// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a\n// statement generates new fatal failures. To do so it registers itself as the\n// current test part result reporter. Besides checking if fatal failures were\n// reported, it only delegates the reporting to the former result reporter.\n// The original result reporter is restored in the destructor.\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nclass GTEST_API_ HasNewFatalFailureHelper\n    : public TestPartResultReporterInterface {\n public:\n  HasNewFatalFailureHelper();\n  ~HasNewFatalFailureHelper() override;\n  void ReportTestPartResult(const TestPartResult& result) override;\n  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }\n\n private:\n  bool has_new_fatal_failure_;\n  TestPartResultReporterInterface* original_reporter_;\n\n  HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;\n  HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest-typed-test.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n\n// This header implements typed tests and type-parameterized tests.\n\n// Typed (aka type-driven) tests repeat the same test for types in a\n// list.  You must know which types you want to test with when writing\n// typed tests. Here's how you do it:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n public:\n  ...\n  typedef std::list<T> List;\n  static T shared_;\n  T value_;\n};\n\n// Next, associate a list of types with the test suite, which will be\n// repeated for each type in the list.  The typedef is necessary for\n// the macro to parse correctly.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nTYPED_TEST_SUITE(FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   TYPED_TEST_SUITE(FooTest, int);\n\n// Then, use TYPED_TEST() instead of TEST_F() to define as many typed\n// tests for this test suite as you want.\nTYPED_TEST(FooTest, DoesBlah) {\n  // Inside a test, refer to the special name TypeParam to get the type\n  // parameter.  Since we are inside a derived class template, C++ requires\n  // us to visit the members of FooTest via 'this'.\n  TypeParam n = this->value_;\n\n  // To visit static members of the fixture, add the TestFixture::\n  // prefix.\n  n += TestFixture::shared_;\n\n  // To refer to typedefs in the fixture, add the \"typename\n  // TestFixture::\" prefix.\n  typename TestFixture::List values;\n  values.push_back(n);\n  ...\n}\n\nTYPED_TEST(FooTest, HasPropertyA) { ... }\n\n// TYPED_TEST_SUITE takes an optional third argument which allows to specify a\n// class that generates custom test name suffixes based on the type. This should\n// be a class which has a static template function GetName(int index) returning\n// a string for each type. The provided integer index equals the index of the\n// type in the provided type list. In many cases the index can be ignored.\n//\n// For example:\n//   class MyTypeNames {\n//    public:\n//     template <typename T>\n//     static std::string GetName(int) {\n//       if (std::is_same<T, char>()) return \"char\";\n//       if (std::is_same<T, int>()) return \"int\";\n//       if (std::is_same<T, unsigned int>()) return \"unsignedInt\";\n//     }\n//   };\n//   TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);\n\n#endif  // 0\n\n// Type-parameterized tests are abstract test patterns parameterized\n// by a type.  Compared with typed tests, type-parameterized tests\n// allow you to define the test pattern without knowing what the type\n// parameters are.  The defined pattern can be instantiated with\n// different types any number of times, in any number of translation\n// units.\n//\n// If you are designing an interface or concept, you can define a\n// suite of type-parameterized tests to verify properties that any\n// valid implementation of the interface/concept should have.  Then,\n// each implementation can easily instantiate the test suite to verify\n// that it conforms to the requirements, without having to write\n// similar tests repeatedly.  Here's an example:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n  ...\n};\n\n// Next, declare that you will define a type-parameterized test suite\n// (the _P suffix is for \"parameterized\" or \"pattern\", whichever you\n// prefer):\nTYPED_TEST_SUITE_P(FooTest);\n\n// Then, use TYPED_TEST_P() to define as many type-parameterized tests\n// for this type-parameterized test suite as you want.\nTYPED_TEST_P(FooTest, DoesBlah) {\n  // Inside a test, refer to TypeParam to get the type parameter.\n  TypeParam n = 0;\n  ...\n}\n\nTYPED_TEST_P(FooTest, HasPropertyA) { ... }\n\n// Now the tricky part: you need to register all test patterns before\n// you can instantiate them.  The first argument of the macro is the\n// test suite name; the rest are the names of the tests in this test\n// case.\nREGISTER_TYPED_TEST_SUITE_P(FooTest,\n                            DoesBlah, HasPropertyA);\n\n// Finally, you are free to instantiate the pattern with the types you\n// want.  If you put the above code in a header file, you can #include\n// it in multiple C++ source files and instantiate it multiple times.\n//\n// To distinguish different instances of the pattern, the first\n// argument to the INSTANTIATE_* macro is a prefix that will be added\n// to the actual test suite name.  Remember to pick unique prefixes for\n// different instances.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nINSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);\n//\n// Similar to the optional argument of TYPED_TEST_SUITE above,\n// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to\n// generate custom names.\n//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);\n\n#endif  // 0\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n#include \"gtest/internal/gtest-type-util.h\"\n\n// Implements typed tests.\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the typedef for the type parameters of the\n// given test suite.\n#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_\n\n// Expands to the name of the typedef for the NameGenerator, responsible for\n// creating the suffixes of the name.\n#define GTEST_NAME_GENERATOR_(TestSuiteName) \\\n  gtest_type_params_##TestSuiteName##_NameGenerator\n\n#define TYPED_TEST_SUITE(CaseName, Types, ...)                          \\\n  typedef ::testing::internal::GenerateTypeList<Types>::type            \\\n      GTEST_TYPE_PARAMS_(CaseName);                                     \\\n  typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \\\n  GTEST_NAME_GENERATOR_(CaseName)\n\n#define TYPED_TEST(CaseName, TestName)                                       \\\n  static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1,                      \\\n                \"test-name must not be empty\");                              \\\n  template <typename gtest_TypeParam_>                                       \\\n  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                           \\\n      : public CaseName<gtest_TypeParam_> {                                  \\\n   private:                                                                  \\\n    typedef CaseName<gtest_TypeParam_> TestFixture;                          \\\n    typedef gtest_TypeParam_ TypeParam;                                      \\\n    void TestBody() override;                                                \\\n  };                                                                         \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \\\n      gtest_##CaseName##_##TestName##_registered_ =                          \\\n          ::testing::internal::TypeParameterizedTest<                        \\\n              CaseName,                                                      \\\n              ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(       \\\n                  CaseName, TestName)>,                                      \\\n              GTEST_TYPE_PARAMS_(                                            \\\n                  CaseName)>::Register(\"\",                                   \\\n                                       ::testing::internal::CodeLocation(    \\\n                                           __FILE__, __LINE__),              \\\n                                       GTEST_STRINGIFY_(CaseName),           \\\n                                       GTEST_STRINGIFY_(TestName), 0,        \\\n                                       ::testing::internal::GenerateNames<   \\\n                                           GTEST_NAME_GENERATOR_(CaseName),  \\\n                                           GTEST_TYPE_PARAMS_(CaseName)>()); \\\n  template <typename gtest_TypeParam_>                                       \\\n  void GTEST_TEST_CLASS_NAME_(CaseName,                                      \\\n                              TestName)<gtest_TypeParam_>::TestBody()\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define TYPED_TEST_CASE                                                \\\n  static_assert(::testing::internal::TypedTestCaseIsDeprecated(), \"\"); \\\n  TYPED_TEST_SUITE\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Implements type-parameterized tests.\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the namespace name that the type-parameterized tests for\n// the given type-parameterized test suite are defined in.  The exact\n// name of the namespace is subject to change without notice.\n#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the variable used to remember the names of\n// the defined tests in the given test suite.\n#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \\\n  gtest_typed_test_suite_p_state_##TestSuiteName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.\n//\n// Expands to the name of the variable used to remember the names of\n// the registered tests in the given test suite.\n#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \\\n  gtest_registered_test_names_##TestSuiteName##_\n\n// The variables defined in the type-parameterized test macros are\n// static as typically these macros are used in a .h file that can be\n// #included in multiple translation units linked together.\n#define TYPED_TEST_SUITE_P(SuiteName)              \\\n  static ::testing::internal::TypedTestSuitePState \\\n  GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define TYPED_TEST_CASE_P                                                 \\\n  static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), \"\"); \\\n  TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#define TYPED_TEST_P(SuiteName, TestName)                         \\\n  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                   \\\n  template <typename gtest_TypeParam_>                            \\\n  class TestName : public SuiteName<gtest_TypeParam_> {           \\\n   private:                                                       \\\n    typedef SuiteName<gtest_TypeParam_> TestFixture;              \\\n    typedef gtest_TypeParam_ TypeParam;                           \\\n    void TestBody() override;                                     \\\n  };                                                              \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool               \\\n      gtest_##TestName##_defined_ =                               \\\n          GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \\\n              __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName),    \\\n              GTEST_STRINGIFY_(TestName));                        \\\n  }                                                               \\\n  template <typename gtest_TypeParam_>                            \\\n  void GTEST_SUITE_NAMESPACE_(                                    \\\n      SuiteName)::TestName<gtest_TypeParam_>::TestBody()\n\n// Note: this won't work correctly if the trailing arguments are macros.\n#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...)                         \\\n  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                             \\\n  typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_;      \\\n  }                                                                         \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const            \\\n  GTEST_REGISTERED_TEST_NAMES_(SuiteName) =                                 \\\n      GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \\\n          GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define REGISTER_TYPED_TEST_CASE_P                                           \\\n  static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \\\n                \"\");                                                         \\\n  REGISTER_TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)        \\\n  static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1,                        \\\n                \"test-suit-prefix must not be empty\");                       \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \\\n      gtest_##Prefix##_##SuiteName =                                         \\\n          ::testing::internal::TypeParameterizedTestSuite<                   \\\n              SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \\\n              ::testing::internal::GenerateTypeList<Types>::type>::          \\\n              Register(                                                      \\\n                  GTEST_STRINGIFY_(Prefix),                                  \\\n                  ::testing::internal::CodeLocation(__FILE__, __LINE__),     \\\n                  &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName),               \\\n                  GTEST_STRINGIFY_(SuiteName),                               \\\n                  GTEST_REGISTERED_TEST_NAMES_(SuiteName),                   \\\n                  ::testing::internal::GenerateNames<                        \\\n                      ::testing::internal::NameGeneratorSelector<            \\\n                          __VA_ARGS__>::type,                                \\\n                      ::testing::internal::GenerateTypeList<Types>::type>())\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define INSTANTIATE_TYPED_TEST_CASE_P                                      \\\n  static_assert(                                                           \\\n      ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), \"\"); \\\n  INSTANTIATE_TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the public API for Google Test.  It should be\n// included by any test program that uses Google Test.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n//\n// Acknowledgment: Google Test borrowed the idea of automatic test\n// registration from Barthelemy Dagenais' (barthelemy@prologique.com)\n// easyUnit framework.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n\n#include <cstddef>\n#include <cstdint>\n#include <limits>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <vector>\n\n#include \"gtest/gtest-assertion-result.h\"  // IWYU pragma: export\n#include \"gtest/gtest-death-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest-matchers.h\"  // IWYU pragma: export\n#include \"gtest/gtest-message.h\"  // IWYU pragma: export\n#include \"gtest/gtest-param-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest-printers.h\"  // IWYU pragma: export\n#include \"gtest/gtest-test-part.h\"  // IWYU pragma: export\n#include \"gtest/gtest-typed-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest_pred_impl.h\"  // IWYU pragma: export\n#include \"gtest/gtest_prod.h\"  // IWYU pragma: export\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Declares the flags.\n\n// This flag temporary enables the disabled tests.\nGTEST_DECLARE_bool_(also_run_disabled_tests);\n\n// This flag brings the debugger on an assertion failure.\nGTEST_DECLARE_bool_(break_on_failure);\n\n// This flag controls whether Google Test catches all test-thrown exceptions\n// and logs them as failures.\nGTEST_DECLARE_bool_(catch_exceptions);\n\n// This flag enables using colors in terminal output. Available values are\n// \"yes\" to enable colors, \"no\" (disable colors), or \"auto\" (the default)\n// to let Google Test decide.\nGTEST_DECLARE_string_(color);\n\n// This flag controls whether the test runner should continue execution past\n// first failure.\nGTEST_DECLARE_bool_(fail_fast);\n\n// This flag sets up the filter to select by name using a glob pattern\n// the tests to run. If the filter is not given all tests are executed.\nGTEST_DECLARE_string_(filter);\n\n// This flag controls whether Google Test installs a signal handler that dumps\n// debugging information when fatal signals are raised.\nGTEST_DECLARE_bool_(install_failure_signal_handler);\n\n// This flag causes the Google Test to list tests. None of the tests listed\n// are actually run if the flag is provided.\nGTEST_DECLARE_bool_(list_tests);\n\n// This flag controls whether Google Test emits a detailed XML report to a file\n// in addition to its normal textual output.\nGTEST_DECLARE_string_(output);\n\n// This flags control whether Google Test prints only test failures.\nGTEST_DECLARE_bool_(brief);\n\n// This flags control whether Google Test prints the elapsed time for each\n// test.\nGTEST_DECLARE_bool_(print_time);\n\n// This flags control whether Google Test prints UTF8 characters as text.\nGTEST_DECLARE_bool_(print_utf8);\n\n// This flag specifies the random number seed.\nGTEST_DECLARE_int32_(random_seed);\n\n// This flag sets how many times the tests are repeated. The default value\n// is 1. If the value is -1 the tests are repeating forever.\nGTEST_DECLARE_int32_(repeat);\n\n// This flag controls whether Google Test Environments are recreated for each\n// repeat of the tests. The default value is true. If set to false the global\n// test Environment objects are only set up once, for the first iteration, and\n// only torn down once, for the last.\nGTEST_DECLARE_bool_(recreate_environments_when_repeating);\n\n// This flag controls whether Google Test includes Google Test internal\n// stack frames in failure stack traces.\nGTEST_DECLARE_bool_(show_internal_stack_frames);\n\n// When this flag is specified, tests' order is randomized on every iteration.\nGTEST_DECLARE_bool_(shuffle);\n\n// This flag specifies the maximum number of stack frames to be\n// printed in a failure message.\nGTEST_DECLARE_int32_(stack_trace_depth);\n\n// When this flag is specified, a failed assertion will throw an\n// exception if exceptions are enabled, or exit the program with a\n// non-zero code otherwise. For use with an external test framework.\nGTEST_DECLARE_bool_(throw_on_failure);\n\n// When this flag is set with a \"host:port\" string, on supported\n// platforms test results are streamed to the specified port on\n// the specified host machine.\nGTEST_DECLARE_string_(stream_result_to);\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_\nGTEST_DECLARE_string_(flagfile);\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_\n\nnamespace testing {\n\n// Silence C4100 (unreferenced formal parameter) and 4805\n// unsafe mix of type 'const int' and type 'const bool'\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4805 4100)\n\n// The upper limit for valid stack trace depths.\nconst int kMaxStackTraceDepth = 100;\n\nnamespace internal {\n\nclass AssertHelper;\nclass DefaultGlobalTestPartResultReporter;\nclass ExecDeathTest;\nclass NoExecDeathTest;\nclass FinalSuccessChecker;\nclass GTestFlagSaver;\nclass StreamingListenerTest;\nclass TestResultAccessor;\nclass TestEventListenersAccessor;\nclass TestEventRepeater;\nclass UnitTestRecordPropertyTestHelper;\nclass WindowsDeathTest;\nclass FuchsiaDeathTest;\nclass UnitTestImpl* GetUnitTestImpl();\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const std::string& message);\nstd::set<std::string>* GetIgnoredParameterizedTestSuites();\n\n// A base class that prevents subclasses from being copyable.\n// We do this instead of using '= delete' so as to avoid triggering warnings\n// inside user code regarding any of our declarations.\nclass GTestNonCopyable {\n public:\n  GTestNonCopyable() = default;\n  GTestNonCopyable(const GTestNonCopyable&) = delete;\n  GTestNonCopyable& operator=(const GTestNonCopyable&) = delete;\n  ~GTestNonCopyable() = default;\n};\n\n}  // namespace internal\n\n// The friend relationship of some of these classes is cyclic.\n// If we don't forward declare them the compiler might confuse the classes\n// in friendship clauses with same named classes on the scope.\nclass Test;\nclass TestSuite;\n\n// Old API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nusing TestCase = TestSuite;\n#endif\nclass TestInfo;\nclass UnitTest;\n\n// The abstract class that all tests inherit from.\n//\n// In Google Test, a unit test program contains one or many TestSuites, and\n// each TestSuite contains one or many Tests.\n//\n// When you define a test using the TEST macro, you don't need to\n// explicitly derive from Test - the TEST macro automatically does\n// this for you.\n//\n// The only time you derive from Test is when defining a test fixture\n// to be used in a TEST_F.  For example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     void SetUp() override { ... }\n//     void TearDown() override { ... }\n//     ...\n//   };\n//\n//   TEST_F(FooTest, Bar) { ... }\n//   TEST_F(FooTest, Baz) { ... }\n//\n// Test is not copyable.\nclass GTEST_API_ Test {\n public:\n  friend class TestInfo;\n\n  // The d'tor is virtual as we intend to inherit from Test.\n  virtual ~Test();\n\n  // Sets up the stuff shared by all tests in this test suite.\n  //\n  // Google Test will call Foo::SetUpTestSuite() before running the first\n  // test in test suite Foo.  Hence a sub-class can define its own\n  // SetUpTestSuite() method to shadow the one defined in the super\n  // class.\n  static void SetUpTestSuite() {}\n\n  // Tears down the stuff shared by all tests in this test suite.\n  //\n  // Google Test will call Foo::TearDownTestSuite() after running the last\n  // test in test suite Foo.  Hence a sub-class can define its own\n  // TearDownTestSuite() method to shadow the one defined in the super\n  // class.\n  static void TearDownTestSuite() {}\n\n  // Legacy API is deprecated but still available. Use SetUpTestSuite and\n  // TearDownTestSuite instead.\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  static void TearDownTestCase() {}\n  static void SetUpTestCase() {}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns true if and only if the current test has a fatal failure.\n  static bool HasFatalFailure();\n\n  // Returns true if and only if the current test has a non-fatal failure.\n  static bool HasNonfatalFailure();\n\n  // Returns true if and only if the current test was skipped.\n  static bool IsSkipped();\n\n  // Returns true if and only if the current test has a (either fatal or\n  // non-fatal) failure.\n  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }\n\n  // Logs a property for the current test, test suite, or for the entire\n  // invocation of the test program when used outside of the context of a\n  // test suite.  Only the last value for a given key is remembered.  These\n  // are public static so they can be called from utility functions that are\n  // not members of the test fixture.  Calls to RecordProperty made during\n  // lifespan of the test (from the moment its constructor starts to the\n  // moment its destructor finishes) will be output in XML as attributes of\n  // the <testcase> element.  Properties recorded from fixture's\n  // SetUpTestSuite or TearDownTestSuite are logged as attributes of the\n  // corresponding <testsuite> element.  Calls to RecordProperty made in the\n  // global context (before or after invocation of RUN_ALL_TESTS and from\n  // SetUp/TearDown method of Environment objects registered with Google\n  // Test) will be output as attributes of the <testsuites> element.\n  static void RecordProperty(const std::string& key, const std::string& value);\n  // We do not define a custom serialization except for values that can be\n  // converted to int64_t, but other values could be logged in this way.\n  template <typename T, std::enable_if_t<std::is_convertible<T, int64_t>::value,\n                                         bool> = true>\n  static void RecordProperty(const std::string& key, const T& value) {\n    RecordProperty(key, (Message() << value).GetString());\n  }\n\n protected:\n  // Creates a Test object.\n  Test();\n\n  // Sets up the test fixture.\n  virtual void SetUp();\n\n  // Tears down the test fixture.\n  virtual void TearDown();\n\n private:\n  // Returns true if and only if the current test has the same fixture class\n  // as the first test in the current test suite.\n  static bool HasSameFixtureClass();\n\n  // Runs the test after the test fixture has been set up.\n  //\n  // A sub-class must implement this to define the test logic.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.\n  // Instead, use the TEST or TEST_F macro.\n  virtual void TestBody() = 0;\n\n  // Sets up, executes, and tears down the test.\n  void Run();\n\n  // Deletes self.  We deliberately pick an unusual name for this\n  // internal method to avoid clashing with names used in user TESTs.\n  void DeleteSelf_() { delete this; }\n\n  const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;\n\n  // Often a user misspells SetUp() as Setup() and spends a long time\n  // wondering why it is never called by Google Test.  The declaration of\n  // the following method is solely for catching such an error at\n  // compile time:\n  //\n  //   - The return type is deliberately chosen to be not void, so it\n  //   will be a conflict if void Setup() is declared in the user's\n  //   test fixture.\n  //\n  //   - This method is private, so it will be another compiler error\n  //   if the method is called from the user's test fixture.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION.\n  //\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }\n\n  // We disallow copying Tests.\n  Test(const Test&) = delete;\n  Test& operator=(const Test&) = delete;\n};\n\ntypedef internal::TimeInMillis TimeInMillis;\n\n// A copyable object representing a user specified test property which can be\n// output as a key/value string pair.\n//\n// Don't inherit from TestProperty as its destructor is not virtual.\nclass TestProperty {\n public:\n  // C'tor.  TestProperty does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestProperty object.\n  TestProperty(const std::string& a_key, const std::string& a_value)\n      : key_(a_key), value_(a_value) {}\n\n  // Gets the user supplied key.\n  const char* key() const { return key_.c_str(); }\n\n  // Gets the user supplied value.\n  const char* value() const { return value_.c_str(); }\n\n  // Sets a new value, overriding the one supplied in the constructor.\n  void SetValue(const std::string& new_value) { value_ = new_value; }\n\n private:\n  // The key supplied by the user.\n  std::string key_;\n  // The value supplied by the user.\n  std::string value_;\n};\n\n// The result of a single Test.  This includes a list of\n// TestPartResults, a list of TestProperties, a count of how many\n// death tests there are in the Test, and how much time it took to run\n// the Test.\n//\n// TestResult is not copyable.\nclass GTEST_API_ TestResult {\n public:\n  // Creates an empty TestResult.\n  TestResult();\n\n  // D'tor.  Do not inherit from TestResult.\n  ~TestResult();\n\n  // Gets the number of all test parts.  This is the sum of the number\n  // of successful test parts and the number of failed test parts.\n  int total_part_count() const;\n\n  // Returns the number of the test properties.\n  int test_property_count() const;\n\n  // Returns true if and only if the test passed (i.e. no test part failed).\n  bool Passed() const { return !Skipped() && !Failed(); }\n\n  // Returns true if and only if the test was skipped.\n  bool Skipped() const;\n\n  // Returns true if and only if the test failed.\n  bool Failed() const;\n\n  // Returns true if and only if the test fatally failed.\n  bool HasFatalFailure() const;\n\n  // Returns true if and only if the test has a non-fatal failure.\n  bool HasNonfatalFailure() const;\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Gets the time of the test case start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Returns the i-th test part result among all the results. i can range from 0\n  // to total_part_count() - 1. If i is not in that range, aborts the program.\n  const TestPartResult& GetTestPartResult(int i) const;\n\n  // Returns the i-th test property. i can range from 0 to\n  // test_property_count() - 1. If i is not in that range, aborts the\n  // program.\n  const TestProperty& GetTestProperty(int i) const;\n\n private:\n  friend class TestInfo;\n  friend class TestSuite;\n  friend class UnitTest;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::ExecDeathTest;\n  friend class internal::TestResultAccessor;\n  friend class internal::UnitTestImpl;\n  friend class internal::WindowsDeathTest;\n  friend class internal::FuchsiaDeathTest;\n\n  // Gets the vector of TestPartResults.\n  const std::vector<TestPartResult>& test_part_results() const {\n    return test_part_results_;\n  }\n\n  // Gets the vector of TestProperties.\n  const std::vector<TestProperty>& test_properties() const {\n    return test_properties_;\n  }\n\n  // Sets the start time.\n  void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }\n\n  // Sets the elapsed time.\n  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }\n\n  // Adds a test property to the list. The property is validated and may add\n  // a non-fatal failure if invalid (e.g., if it conflicts with reserved\n  // key names). If a property is already recorded for the same key, the\n  // value will be updated, rather than storing multiple values for the same\n  // key.  xml_element specifies the element for which the property is being\n  // recorded and is used for validation.\n  void RecordProperty(const std::string& xml_element,\n                      const TestProperty& test_property);\n\n  // Adds a failure if the key is a reserved attribute of Google Test\n  // testsuite tags.  Returns true if the property is valid.\n  // FIXME: Validate attribute names are legal and human readable.\n  static bool ValidateTestProperty(const std::string& xml_element,\n                                   const TestProperty& test_property);\n\n  // Adds a test part result to the list.\n  void AddTestPartResult(const TestPartResult& test_part_result);\n\n  // Returns the death test count.\n  int death_test_count() const { return death_test_count_; }\n\n  // Increments the death test count, returning the new count.\n  int increment_death_test_count() { return ++death_test_count_; }\n\n  // Clears the test part results.\n  void ClearTestPartResults();\n\n  // Clears the object.\n  void Clear();\n\n  // Protects mutable state of the property vector and of owned\n  // properties, whose values may be updated.\n  internal::Mutex test_properties_mutex_;\n\n  // The vector of TestPartResults\n  std::vector<TestPartResult> test_part_results_;\n  // The vector of TestProperties\n  std::vector<TestProperty> test_properties_;\n  // Running count of death tests.\n  int death_test_count_;\n  // The start time, in milliseconds since UNIX Epoch.\n  TimeInMillis start_timestamp_;\n  // The elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n  // We disallow copying TestResult.\n  TestResult(const TestResult&) = delete;\n  TestResult& operator=(const TestResult&) = delete;\n};  // class TestResult\n\n// A TestInfo object stores the following information about a test:\n//\n//   Test suite name\n//   Test name\n//   Whether the test should be run\n//   A function pointer that creates the test object when invoked\n//   Test result\n//\n// The constructor of TestInfo registers itself with the UnitTest\n// singleton such that the RUN_ALL_TESTS() macro knows which tests to\n// run.\nclass GTEST_API_ TestInfo {\n public:\n  // Destructs a TestInfo object.  This function is not virtual, so\n  // don't inherit from TestInfo.\n  ~TestInfo();\n\n  // Returns the test suite name.\n  const char* test_suite_name() const { return test_suite_name_.c_str(); }\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const char* test_case_name() const { return test_suite_name(); }\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns the test name.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a typed\n  // or a type-parameterized test.\n  const char* type_param() const {\n    if (type_param_ != nullptr) return type_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns the text representation of the value parameter, or NULL if this\n  // is not a value-parameterized test.\n  const char* value_param() const {\n    if (value_param_ != nullptr) return value_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns the file name where this test is defined.\n  const char* file() const { return location_.file.c_str(); }\n\n  // Returns the line where this test is defined.\n  int line() const { return location_.line; }\n\n  // Return true if this test should not be run because it's in another shard.\n  bool is_in_another_shard() const { return is_in_another_shard_; }\n\n  // Returns true if this test should run, that is if the test is not\n  // disabled (or it is disabled but the also_run_disabled_tests flag has\n  // been specified) and its full name matches the user-specified filter.\n  //\n  // Google Test allows the user to filter the tests by their full names.\n  // The full name of a test Bar in test suite Foo is defined as\n  // \"Foo.Bar\".  Only the tests that match the filter will run.\n  //\n  // A filter is a colon-separated list of glob (not regex) patterns,\n  // optionally followed by a '-' and a colon-separated list of\n  // negative patterns (tests to exclude).  A test is run if it\n  // matches one of the positive patterns and does not match any of\n  // the negative patterns.\n  //\n  // For example, *A*:Foo.* is a filter that matches any string that\n  // contains the character 'A' or starts with \"Foo.\".\n  bool should_run() const { return should_run_; }\n\n  // Returns true if and only if this test will appear in the XML report.\n  bool is_reportable() const {\n    // The XML report includes tests matching the filter, excluding those\n    // run in other shards.\n    return matches_filter_ && !is_in_another_shard_;\n  }\n\n  // Returns the result of the test.\n  const TestResult* result() const { return &result_; }\n\n private:\n#ifdef GTEST_HAS_DEATH_TEST\n  friend class internal::DefaultDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n  friend class Test;\n  friend class TestSuite;\n  friend class internal::UnitTestImpl;\n  friend class internal::StreamingListenerTest;\n  friend TestInfo* internal::MakeAndRegisterTestInfo(\n      std::string test_suite_name, const char* name, const char* type_param,\n      const char* value_param, internal::CodeLocation code_location,\n      internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,\n      internal::TearDownTestSuiteFunc tear_down_tc,\n      internal::TestFactoryBase* factory);\n\n  // Constructs a TestInfo object. The newly constructed instance assumes\n  // ownership of the factory object.\n  TestInfo(std::string test_suite_name, std::string name,\n           const char* a_type_param,   // NULL if not a type-parameterized test\n           const char* a_value_param,  // NULL if not a value-parameterized test\n           internal::CodeLocation a_code_location,\n           internal::TypeId fixture_class_id,\n           internal::TestFactoryBase* factory);\n\n  // Increments the number of death tests encountered in this test so\n  // far.\n  int increment_death_test_count() {\n    return result_.increment_death_test_count();\n  }\n\n  // Creates the test object, runs it, records its result, and then\n  // deletes it.\n  void Run();\n\n  // Skip and records the test result for this object.\n  void Skip();\n\n  static void ClearTestResult(TestInfo* test_info) {\n    test_info->result_.Clear();\n  }\n\n  // These fields are immutable properties of the test.\n  const std::string test_suite_name_;  // test suite name\n  const std::string name_;             // Test name\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const std::unique_ptr<const ::std::string> type_param_;\n  // Text representation of the value parameter, or NULL if this is not a\n  // value-parameterized test.\n  const std::unique_ptr<const ::std::string> value_param_;\n  internal::CodeLocation location_;\n  const internal::TypeId fixture_class_id_;  // ID of the test fixture class\n  bool should_run_;           // True if and only if this test should run\n  bool is_disabled_;          // True if and only if this test is disabled\n  bool matches_filter_;       // True if this test matches the\n                              // user-specified filter.\n  bool is_in_another_shard_;  // Will be run in another shard.\n  internal::TestFactoryBase* const factory_;  // The factory that creates\n                                              // the test object\n\n  // This field is mutable and needs to be reset before running the\n  // test for the second time.\n  TestResult result_;\n\n  TestInfo(const TestInfo&) = delete;\n  TestInfo& operator=(const TestInfo&) = delete;\n};\n\n// A test suite, which consists of a vector of TestInfos.\n//\n// TestSuite is not copyable.\nclass GTEST_API_ TestSuite {\n public:\n  // Creates a TestSuite with the given name.\n  //\n  // TestSuite does NOT have a default constructor.  Always use this\n  // constructor to create a TestSuite object.\n  //\n  // Arguments:\n  //\n  //   name:         name of the test suite\n  //   a_type_param: the name of the test's type parameter, or NULL if\n  //                 this is not a type-parameterized test.\n  //   set_up_tc:    pointer to the function that sets up the test suite\n  //   tear_down_tc: pointer to the function that tears down the test suite\n  TestSuite(const std::string& name, const char* a_type_param,\n            internal::SetUpTestSuiteFunc set_up_tc,\n            internal::TearDownTestSuiteFunc tear_down_tc);\n\n  // Destructor of TestSuite.\n  virtual ~TestSuite();\n\n  // Gets the name of the TestSuite.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a\n  // type-parameterized test suite.\n  const char* type_param() const {\n    if (type_param_ != nullptr) return type_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns true if any test in this test suite should run.\n  bool should_run() const { return should_run_; }\n\n  // Gets the number of successful tests in this test suite.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests in this test suite.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests in this test suite.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests in this test suite.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Get the number of tests in this test suite that should run.\n  int test_to_run_count() const;\n\n  // Gets the number of all tests in this test suite.\n  int total_test_count() const;\n\n  // Returns true if and only if the test suite passed.\n  bool Passed() const { return !Failed(); }\n\n  // Returns true if and only if the test suite failed.\n  bool Failed() const {\n    return failed_test_count() > 0 || ad_hoc_test_result().Failed();\n  }\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Gets the time of the test suite start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  const TestInfo* GetTestInfo(int i) const;\n\n  // Returns the TestResult that holds test properties recorded during\n  // execution of SetUpTestSuite and TearDownTestSuite.\n  const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }\n\n private:\n  friend class Test;\n  friend class internal::UnitTestImpl;\n\n  // Gets the (mutable) vector of TestInfos in this TestSuite.\n  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }\n\n  // Gets the (immutable) vector of TestInfos in this TestSuite.\n  const std::vector<TestInfo*>& test_info_list() const {\n    return test_info_list_;\n  }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  TestInfo* GetMutableTestInfo(int i);\n\n  // Sets the should_run member.\n  void set_should_run(bool should) { should_run_ = should; }\n\n  // Adds a TestInfo to this test suite.  Will delete the TestInfo upon\n  // destruction of the TestSuite object.\n  void AddTestInfo(TestInfo* test_info);\n\n  // Clears the results of all tests in this test suite.\n  void ClearResult();\n\n  // Clears the results of all tests in the given test suite.\n  static void ClearTestSuiteResult(TestSuite* test_suite) {\n    test_suite->ClearResult();\n  }\n\n  // Runs every test in this TestSuite.\n  void Run();\n\n  // Skips the execution of tests under this TestSuite\n  void Skip();\n\n  // Runs SetUpTestSuite() for this TestSuite.  This wrapper is needed\n  // for catching exceptions thrown from SetUpTestSuite().\n  void RunSetUpTestSuite() {\n    if (set_up_tc_ != nullptr) {\n      (*set_up_tc_)();\n    }\n  }\n\n  // Runs TearDownTestSuite() for this TestSuite.  This wrapper is\n  // needed for catching exceptions thrown from TearDownTestSuite().\n  void RunTearDownTestSuite() {\n    if (tear_down_tc_ != nullptr) {\n      (*tear_down_tc_)();\n    }\n  }\n\n  // Returns true if and only if test passed.\n  static bool TestPassed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Passed();\n  }\n\n  // Returns true if and only if test skipped.\n  static bool TestSkipped(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Skipped();\n  }\n\n  // Returns true if and only if test failed.\n  static bool TestFailed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Failed();\n  }\n\n  // Returns true if and only if the test is disabled and will be reported in\n  // the XML report.\n  static bool TestReportableDisabled(const TestInfo* test_info) {\n    return test_info->is_reportable() && test_info->is_disabled_;\n  }\n\n  // Returns true if and only if test is disabled.\n  static bool TestDisabled(const TestInfo* test_info) {\n    return test_info->is_disabled_;\n  }\n\n  // Returns true if and only if this test will appear in the XML report.\n  static bool TestReportable(const TestInfo* test_info) {\n    return test_info->is_reportable();\n  }\n\n  // Returns true if the given test should run.\n  static bool ShouldRunTest(const TestInfo* test_info) {\n    return test_info->should_run();\n  }\n\n  // Shuffles the tests in this test suite.\n  void ShuffleTests(internal::Random* random);\n\n  // Restores the test order to before the first shuffle.\n  void UnshuffleTests();\n\n  // Name of the test suite.\n  std::string name_;\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const std::unique_ptr<const ::std::string> type_param_;\n  // The vector of TestInfos in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestInfo*> test_info_list_;\n  // Provides a level of indirection for the test list to allow easy\n  // shuffling and restoring the test order.  The i-th element in this\n  // vector is the index of the i-th test in the shuffled test list.\n  std::vector<int> test_indices_;\n  // Pointer to the function that sets up the test suite.\n  internal::SetUpTestSuiteFunc set_up_tc_;\n  // Pointer to the function that tears down the test suite.\n  internal::TearDownTestSuiteFunc tear_down_tc_;\n  // True if and only if any test in this test suite should run.\n  bool should_run_;\n  // The start time, in milliseconds since UNIX Epoch.\n  TimeInMillis start_timestamp_;\n  // Elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n  // Holds test properties recorded during execution of SetUpTestSuite and\n  // TearDownTestSuite.\n  TestResult ad_hoc_test_result_;\n\n  // We disallow copying TestSuites.\n  TestSuite(const TestSuite&) = delete;\n  TestSuite& operator=(const TestSuite&) = delete;\n};\n\n// An Environment object is capable of setting up and tearing down an\n// environment.  You should subclass this to define your own\n// environment(s).\n//\n// An Environment object does the set-up and tear-down in virtual\n// methods SetUp() and TearDown() instead of the constructor and the\n// destructor, as:\n//\n//   1. You cannot safely throw from a destructor.  This is a problem\n//      as in some cases Google Test is used where exceptions are enabled, and\n//      we may want to implement ASSERT_* using exceptions where they are\n//      available.\n//   2. You cannot use ASSERT_* directly in a constructor or\n//      destructor.\nclass Environment {\n public:\n  // The d'tor is virtual as we need to subclass Environment.\n  virtual ~Environment() = default;\n\n  // Override this to define how to set up the environment.\n  virtual void SetUp() {}\n\n  // Override this to define how to tear down the environment.\n  virtual void TearDown() {}\n\n private:\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }\n};\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Exception which can be thrown from TestEventListener::OnTestPartResult.\nclass GTEST_API_ AssertionException\n    : public internal::GoogleTestFailureException {\n public:\n  explicit AssertionException(const TestPartResult& result)\n      : GoogleTestFailureException(result) {}\n};\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// The interface for tracing execution of tests. The methods are organized in\n// the order the corresponding events are fired.\nclass TestEventListener {\n public:\n  virtual ~TestEventListener() = default;\n\n  // Fired before any test activity starts.\n  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;\n\n  // Fired before each iteration of tests starts.  There may be more than\n  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration\n  // index, starting from 0.\n  virtual void OnTestIterationStart(const UnitTest& unit_test,\n                                    int iteration) = 0;\n\n  // Fired before environment set-up for each iteration of tests starts.\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment set-up for each iteration of tests ends.\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;\n\n  // Fired before the test suite starts.\n  virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Fired before the test starts.\n  virtual void OnTestStart(const TestInfo& test_info) = 0;\n\n  // Fired when a test is disabled\n  virtual void OnTestDisabled(const TestInfo& /*test_info*/) {}\n\n  // Fired after a failed assertion or a SUCCEED() invocation.\n  // If you want to throw an exception from this function to skip to the next\n  // TEST, it must be AssertionException defined above, or inherited from it.\n  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;\n\n  // Fired after the test ends.\n  virtual void OnTestEnd(const TestInfo& test_info) = 0;\n\n  // Fired after the test suite ends.\n  virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Fired before environment tear-down for each iteration of tests starts.\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment tear-down for each iteration of tests ends.\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;\n\n  // Fired after each iteration of tests finishes.\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0;\n\n  // Fired after all test activities have ended.\n  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;\n};\n\n// The convenience class for users who need to override just one or two\n// methods and are not concerned that a possible change to a signature of\n// the methods they override will not be caught during the build.  For\n// comments about each method please see the definition of TestEventListener\n// above.\nclass EmptyTestEventListener : public TestEventListener {\n public:\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& /*unit_test*/,\n                            int /*iteration*/) override {}\n  void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& /*test_case*/) override {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnTestStart(const TestInfo& /*test_info*/) override {}\n  void OnTestDisabled(const TestInfo& /*test_info*/) override {}\n  void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}\n  void OnTestEnd(const TestInfo& /*test_info*/) override {}\n  void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& /*test_case*/) override {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& /*unit_test*/,\n                          int /*iteration*/) override {}\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n};\n\n// TestEventListeners lets users add listeners to track events in Google Test.\nclass GTEST_API_ TestEventListeners {\n public:\n  TestEventListeners();\n  ~TestEventListeners();\n\n  // Appends an event listener to the end of the list. Google Test assumes\n  // the ownership of the listener (i.e. it will delete the listener when\n  // the test program finishes).\n  void Append(TestEventListener* listener);\n\n  // Removes the given event listener from the list and returns it.  It then\n  // becomes the caller's responsibility to delete the listener. Returns\n  // NULL if the listener is not found in the list.\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Returns the standard listener responsible for the default console\n  // output.  Can be removed from the listeners list to shut down default\n  // console output.  Note that removing this object from the listener list\n  // with Release transfers its ownership to the caller and makes this\n  // function return NULL the next time.\n  TestEventListener* default_result_printer() const {\n    return default_result_printer_;\n  }\n\n  // Returns the standard listener responsible for the default XML output\n  // controlled by the --gtest_output=xml flag.  Can be removed from the\n  // listeners list by users who want to shut down the default XML output\n  // controlled by this flag and substitute it with custom one.  Note that\n  // removing this object from the listener list with Release transfers its\n  // ownership to the caller and makes this function return NULL the next\n  // time.\n  TestEventListener* default_xml_generator() const {\n    return default_xml_generator_;\n  }\n\n  // Controls whether events will be forwarded by the repeater to the\n  // listeners in the list.\n  void SuppressEventForwarding(bool);\n\n private:\n  friend class TestSuite;\n  friend class TestInfo;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::NoExecDeathTest;\n  friend class internal::TestEventListenersAccessor;\n  friend class internal::UnitTestImpl;\n\n  // Returns repeater that broadcasts the TestEventListener events to all\n  // subscribers.\n  TestEventListener* repeater();\n\n  // Sets the default_result_printer attribute to the provided listener.\n  // The listener is also added to the listener list and previous\n  // default_result_printer is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultResultPrinter(TestEventListener* listener);\n\n  // Sets the default_xml_generator attribute to the provided listener.  The\n  // listener is also added to the listener list and previous\n  // default_xml_generator is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultXmlGenerator(TestEventListener* listener);\n\n  // Controls whether events will be forwarded by the repeater to the\n  // listeners in the list.\n  bool EventForwardingEnabled() const;\n\n  // The actual list of listeners.\n  internal::TestEventRepeater* repeater_;\n  // Listener responsible for the standard result output.\n  TestEventListener* default_result_printer_;\n  // Listener responsible for the creation of the XML output file.\n  TestEventListener* default_xml_generator_;\n\n  // We disallow copying TestEventListeners.\n  TestEventListeners(const TestEventListeners&) = delete;\n  TestEventListeners& operator=(const TestEventListeners&) = delete;\n};\n\n// A UnitTest consists of a vector of TestSuites.\n//\n// This is a singleton class.  The only instance of UnitTest is\n// created when UnitTest::GetInstance() is first called.  This\n// instance is never deleted.\n//\n// UnitTest is not copyable.\n//\n// This class is thread-safe as long as the methods are called\n// according to their specification.\nclass GTEST_API_ UnitTest {\n public:\n  // Gets the singleton UnitTest object.  The first time this method\n  // is called, a UnitTest object is constructed and returned.\n  // Consecutive calls will return the same object.\n  static UnitTest* GetInstance();\n\n  // Runs all tests in this UnitTest object and prints the result.\n  // Returns 0 if successful, or 1 otherwise.\n  //\n  // This method can only be called from the main thread.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  int Run() GTEST_MUST_USE_RESULT_;\n\n  // Returns the working directory when the first TEST() or TEST_F()\n  // was executed.  The UnitTest object owns the string.\n  const char* original_working_dir() const;\n\n  // Returns the TestSuite object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n// Legacy API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_);\n#endif\n\n  // Returns the TestInfo object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Returns the random seed used at the start of the current test run.\n  int random_seed() const;\n\n  // Returns the ParameterizedTestSuiteRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry()\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Gets the number of successful test suites.\n  int successful_test_suite_count() const;\n\n  // Gets the number of failed test suites.\n  int failed_test_suite_count() const;\n\n  // Gets the number of all test suites.\n  int total_test_suite_count() const;\n\n  // Gets the number of all test suites that contain at least one test\n  // that should run.\n  int test_suite_to_run_count() const;\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  int successful_test_case_count() const;\n  int failed_test_case_count() const;\n  int total_test_case_count() const;\n  int test_case_to_run_count() const;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const;\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const;\n\n  // Returns true if and only if the unit test passed (i.e. all test suites\n  // passed).\n  bool Passed() const;\n\n  // Returns true if and only if the unit test failed (i.e. some test suite\n  // failed or something outside of all tests failed).\n  bool Failed() const;\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  const TestSuite* GetTestSuite(int i) const;\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* GetTestCase(int i) const;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns the TestResult containing information on test failures and\n  // properties logged outside of individual test suites.\n  const TestResult& ad_hoc_test_result() const;\n\n  // Returns the list of event listeners that can be used to track events\n  // inside Google Test.\n  TestEventListeners& listeners();\n\n private:\n  // Registers and returns a global test environment.  When a test\n  // program is run, all global test environments will be set-up in\n  // the order they were registered.  After all tests in the program\n  // have finished, all global test environments will be torn-down in\n  // the *reverse* order they were registered.\n  //\n  // The UnitTest object takes ownership of the given environment.\n  //\n  // This method can only be called from the main thread.\n  Environment* AddEnvironment(Environment* env);\n\n  // Adds a TestPartResult to the current TestResult object.  All\n  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)\n  // eventually call this to report their results.  The user code\n  // should use the assertion macros instead of calling this directly.\n  void AddTestPartResult(TestPartResult::Type result_type,\n                         const char* file_name, int line_number,\n                         const std::string& message,\n                         const std::string& os_stack_trace)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Adds a TestProperty to the current TestResult object when invoked from\n  // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked\n  // from SetUpTestSuite or TearDownTestSuite, or to the global property set\n  // when invoked elsewhere.  If the result already contains a property with\n  // the same key, the value will be updated.\n  void RecordProperty(const std::string& key, const std::string& value);\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  TestSuite* GetMutableTestSuite(int i);\n\n  // Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()\n  // should be called immediately before Google Test calls user code. It saves\n  // some information about the current stack that CurrentStackTrace() will use\n  // to find and hide Google Test stack frames.\n  void UponLeavingGTest();\n\n  // Sets the TestSuite object for the test that's currently running.\n  void set_current_test_suite(TestSuite* a_current_test_suite)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Sets the TestInfo object for the test that's currently running.\n  void set_current_test_info(TestInfo* a_current_test_info)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Accessors for the implementation object.\n  internal::UnitTestImpl* impl() { return impl_; }\n  const internal::UnitTestImpl* impl() const { return impl_; }\n\n  // These classes and functions are friends as they need to access private\n  // members of UnitTest.\n  friend class ScopedTrace;\n  friend class Test;\n  friend class TestInfo;\n  friend class TestSuite;\n  friend class internal::AssertHelper;\n  friend class internal::StreamingListenerTest;\n  friend class internal::UnitTestRecordPropertyTestHelper;\n  friend Environment* AddGlobalTestEnvironment(Environment* env);\n  friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites();\n  friend internal::UnitTestImpl* internal::GetUnitTestImpl();\n  friend void internal::ReportFailureInUnknownLocation(\n      TestPartResult::Type result_type, const std::string& message);\n\n  // Creates an empty UnitTest.\n  UnitTest();\n\n  // D'tor\n  virtual ~UnitTest();\n\n  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n  // Google Test trace stack.\n  void PushGTestTrace(const internal::TraceInfo& trace)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Pops a trace from the per-thread Google Test trace stack.\n  void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Protects mutable state in *impl_.  This is mutable as some const\n  // methods need to lock it too.\n  mutable internal::Mutex mutex_;\n\n  // Opaque implementation object.  This field is never changed once\n  // the object is constructed.  We don't mark it as const here, as\n  // doing so will cause a warning in the constructor of UnitTest.\n  // Mutable state in *impl_ is protected by mutex_.\n  internal::UnitTestImpl* impl_;\n\n  // We disallow copying UnitTest.\n  UnitTest(const UnitTest&) = delete;\n  UnitTest& operator=(const UnitTest&) = delete;\n};\n\n// A convenient wrapper for adding an environment for the test\n// program.\n//\n// You should call this before RUN_ALL_TESTS() is called, probably in\n// main().  If you use gtest_main, you need to call this before main()\n// starts for it to take effect.  For example, you can define a global\n// variable like this:\n//\n//   testing::Environment* const foo_env =\n//       testing::AddGlobalTestEnvironment(new FooEnvironment);\n//\n// However, we strongly recommend you to write your own main() and\n// call AddGlobalTestEnvironment() there, as relying on initialization\n// of global variables makes the code harder to read and may cause\n// problems when you register multiple environments from different\n// translation units and the environments have dependencies among them\n// (remember that the compiler doesn't guarantee the order in which\n// global variables from different translation units are initialized).\ninline Environment* AddGlobalTestEnvironment(Environment* env) {\n  return UnitTest::GetInstance()->AddEnvironment(env);\n}\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nGTEST_API_ void InitGoogleTest(int* argc, char** argv);\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleTest();\n\nnamespace internal {\n\n// Separate the error generating code from the code path to reduce the stack\n// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers\n// when calling EXPECT_* in a tight loop.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperEQFailure(const char* lhs_expression,\n                                   const char* rhs_expression, const T1& lhs,\n                                   const T2& rhs) {\n  return EqFailure(lhs_expression, rhs_expression,\n                   FormatForComparisonFailureMessage(lhs, rhs),\n                   FormatForComparisonFailureMessage(rhs, lhs), false);\n}\n\n// This block of code defines operator==/!=\n// to block lexical scope lookup.\n// It prevents using invalid operator==/!= defined at namespace scope.\nstruct faketype {};\ninline bool operator==(faketype, faketype) { return true; }\ninline bool operator!=(faketype, faketype) { return false; }\n\n// The helper function for {ASSERT|EXPECT}_EQ.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperEQ(const char* lhs_expression,\n                            const char* rhs_expression, const T1& lhs,\n                            const T2& rhs) {\n  if (lhs == rhs) {\n    return AssertionSuccess();\n  }\n\n  return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);\n}\n\nclass EqHelper {\n public:\n  // This templatized version is for the general case.\n  template <\n      typename T1, typename T2,\n      // Disable this overload for cases where one argument is a pointer\n      // and the other is the null pointer constant.\n      typename std::enable_if<!std::is_integral<T1>::value ||\n                              !std::is_pointer<T2>::value>::type* = nullptr>\n  static AssertionResult Compare(const char* lhs_expression,\n                                 const char* rhs_expression, const T1& lhs,\n                                 const T2& rhs) {\n    return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);\n  }\n\n  // With this overloaded version, we allow anonymous enums to be used\n  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous\n  // enums can be implicitly cast to BiggestInt.\n  //\n  // Even though its body looks the same as the above version, we\n  // cannot merge the two, as it will make anonymous enums unhappy.\n  static AssertionResult Compare(const char* lhs_expression,\n                                 const char* rhs_expression, BiggestInt lhs,\n                                 BiggestInt rhs) {\n    return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);\n  }\n\n  template <typename T>\n  static AssertionResult Compare(\n      const char* lhs_expression, const char* rhs_expression,\n      // Handle cases where '0' is used as a null pointer literal.\n      std::nullptr_t /* lhs */, T* rhs) {\n    // We already know that 'lhs' is a null pointer.\n    return CmpHelperEQ(lhs_expression, rhs_expression, static_cast<T*>(nullptr),\n                       rhs);\n  }\n};\n\n// Separate the error generating code from the code path to reduce the stack\n// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers\n// when calling EXPECT_OP in a tight loop.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,\n                                   const T1& val1, const T2& val2,\n                                   const char* op) {\n  return AssertionFailure()\n         << \"Expected: (\" << expr1 << \") \" << op << \" (\" << expr2\n         << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\n         << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\n}\n\n// A macro for implementing the helper functions needed to implement\n// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste\n// of similar code.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)                                \\\n  template <typename T1, typename T2>                                      \\\n  AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\n                                     const T1& val1, const T2& val2) {     \\\n    if (val1 op val2) {                                                    \\\n      return AssertionSuccess();                                           \\\n    } else {                                                               \\\n      return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);            \\\n    }                                                                      \\\n  }\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n// Implements the helper function for {ASSERT|EXPECT}_NE\nGTEST_IMPL_CMP_HELPER_(NE, !=)\n// Implements the helper function for {ASSERT|EXPECT}_LE\nGTEST_IMPL_CMP_HELPER_(LE, <=)\n// Implements the helper function for {ASSERT|EXPECT}_LT\nGTEST_IMPL_CMP_HELPER_(LT, <)\n// Implements the helper function for {ASSERT|EXPECT}_GE\nGTEST_IMPL_CMP_HELPER_(GE, >=)\n// Implements the helper function for {ASSERT|EXPECT}_GT\nGTEST_IMPL_CMP_HELPER_(GT, >)\n\n#undef GTEST_IMPL_CMP_HELPER_\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression,\n                                              const char* s2_expression,\n                                              const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                              const char* s2_expression,\n                                              const char* s1, const char* s2);\n\n// Helper function for *_STREQ on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const wchar_t* s1, const wchar_t* s2);\n\n// Helper function for *_STRNE on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const wchar_t* s1, const wchar_t* s2);\n\n}  // namespace internal\n\n// IsSubstring() and IsNotSubstring() are intended to be used as the\n// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by\n// themselves.  They check whether needle is a substring of haystack\n// (NULL is considered a substring of itself only), and return an\n// appropriate error message when they fail.\n//\n// The {needle,haystack}_expr arguments are the stringified\n// expressions that generated the two real arguments.\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const char* needle,\n                                       const char* haystack);\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const wchar_t* needle,\n                                       const wchar_t* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const char* needle,\n                                          const char* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const wchar_t* needle,\n                                          const wchar_t* haystack);\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const ::std::string& needle,\n                                       const ::std::string& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const ::std::string& needle,\n                                          const ::std::string& haystack);\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const ::std::wstring& needle,\n                                       const ::std::wstring& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const ::std::wstring& needle,\n                                          const ::std::wstring& haystack);\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n// Helper template function for comparing floating-points.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename RawType>\nAssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,\n                                         const char* rhs_expression,\n                                         RawType lhs_value, RawType rhs_value) {\n  const FloatingPoint<RawType> lhs(lhs_value), rhs(rhs_value);\n\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  ::std::stringstream lhs_ss;\n  lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);\n  lhs_ss << lhs_value;\n\n  ::std::stringstream rhs_ss;\n  rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);\n  rhs_ss << rhs_value;\n\n  return EqFailure(lhs_expression, rhs_expression,\n                   StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),\n                   false);\n}\n\n// Helper function for implementing ASSERT_NEAR.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,\n                                                const char* expr2,\n                                                const char* abs_error_expr,\n                                                double val1, double val2,\n                                                double abs_error);\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n// A class that enables one to stream messages to assertion macros\nclass GTEST_API_ AssertHelper {\n public:\n  // Constructor.\n  AssertHelper(TestPartResult::Type type, const char* file, int line,\n               const char* message);\n  ~AssertHelper();\n\n  // Message assignment is a semantic trick to enable assertion\n  // streaming; see the GTEST_MESSAGE_ macro below.\n  void operator=(const Message& message) const;\n\n private:\n  // We put our data in a struct so that the size of the AssertHelper class can\n  // be as small as possible.  This is important because gcc is incapable of\n  // re-using stack space even for temporary variables, so every EXPECT_EQ\n  // reserves stack space for another AssertHelper.\n  struct AssertHelperData {\n    AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,\n                     const char* msg)\n        : type(t), file(srcfile), line(line_num), message(msg) {}\n\n    TestPartResult::Type const type;\n    const char* const file;\n    int const line;\n    std::string const message;\n\n   private:\n    AssertHelperData(const AssertHelperData&) = delete;\n    AssertHelperData& operator=(const AssertHelperData&) = delete;\n  };\n\n  AssertHelperData* const data_;\n\n  AssertHelper(const AssertHelper&) = delete;\n  AssertHelper& operator=(const AssertHelper&) = delete;\n};\n\n}  // namespace internal\n\n// The pure interface class that all value-parameterized tests inherit from.\n// A value-parameterized class must inherit from both ::testing::Test and\n// ::testing::WithParamInterface. In most cases that just means inheriting\n// from ::testing::TestWithParam, but more complicated test hierarchies\n// may need to inherit from Test and WithParamInterface at different levels.\n//\n// This interface has support for accessing the test parameter value via\n// the GetParam() method.\n//\n// Use it with one of the parameter generator defining functions, like Range(),\n// Values(), ValuesIn(), Bool(), Combine(), and ConvertGenerator<T>().\n//\n// class FooTest : public ::testing::TestWithParam<int> {\n//  protected:\n//   FooTest() {\n//     // Can use GetParam() here.\n//   }\n//   ~FooTest() override {\n//     // Can use GetParam() here.\n//   }\n//   void SetUp() override {\n//     // Can use GetParam() here.\n//   }\n//   void TearDown override {\n//     // Can use GetParam() here.\n//   }\n// };\n// TEST_P(FooTest, DoesBar) {\n//   // Can use GetParam() method here.\n//   Foo foo;\n//   ASSERT_TRUE(foo.DoesBar(GetParam()));\n// }\n// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));\n\ntemplate <typename T>\nclass WithParamInterface {\n public:\n  typedef T ParamType;\n  virtual ~WithParamInterface() = default;\n\n  // The current parameter value. Is also available in the test fixture's\n  // constructor.\n  static const ParamType& GetParam() {\n    GTEST_CHECK_(parameter_ != nullptr)\n        << \"GetParam() can only be called inside a value-parameterized test \"\n        << \"-- did you intend to write TEST_P instead of TEST_F?\";\n    return *parameter_;\n  }\n\n private:\n  // Sets parameter value. The caller is responsible for making sure the value\n  // remains alive and unchanged throughout the current test.\n  static void SetParam(const ParamType* parameter) { parameter_ = parameter; }\n\n  // Static value used for accessing parameter during a test lifetime.\n  static const ParamType* parameter_;\n\n  // TestClass must be a subclass of WithParamInterface<T> and Test.\n  template <class TestClass>\n  friend class internal::ParameterizedTestFactory;\n};\n\ntemplate <typename T>\nconst T* WithParamInterface<T>::parameter_ = nullptr;\n\n// Most value-parameterized classes can ignore the existence of\n// WithParamInterface, and can just inherit from ::testing::TestWithParam.\n\ntemplate <typename T>\nclass TestWithParam : public Test, public WithParamInterface<T> {};\n\n// Macros for indicating success/failure in test code.\n\n// Skips test in runtime.\n// Skipping test aborts current function.\n// Skipped tests are neither successful nor failed.\n#define GTEST_SKIP() GTEST_SKIP_(\"\")\n\n// ADD_FAILURE unconditionally adds a failure to the current test.\n// SUCCEED generates a success - it doesn't automatically make the\n// current test successful, as a test is only successful when it has\n// no failure.\n//\n// EXPECT_* verifies that a certain condition is satisfied.  If not,\n// it behaves like ADD_FAILURE.  In particular:\n//\n//   EXPECT_TRUE  verifies that a Boolean condition is true.\n//   EXPECT_FALSE verifies that a Boolean condition is false.\n//\n// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except\n// that they will also abort the current function on failure.  People\n// usually want the fail-fast behavior of FAIL and ASSERT_*, but those\n// writing data-driven tests often find themselves using ADD_FAILURE\n// and EXPECT_* more.\n\n// Generates a nonfatal failure with a generic message.\n#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_(\"Failed\")\n\n// Generates a nonfatal failure at the given source file location with\n// a generic message.\n#define ADD_FAILURE_AT(file, line)        \\\n  GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\n                    ::testing::TestPartResult::kNonFatalFailure)\n\n// Generates a fatal failure with a generic message.\n#define GTEST_FAIL() GTEST_FATAL_FAILURE_(\"Failed\")\n\n// Like GTEST_FAIL(), but at the given source file location.\n#define GTEST_FAIL_AT(file, line)                \\\n  return GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\n                           ::testing::TestPartResult::kFatalFailure)\n\n// Define this macro to 1 to omit the definition of FAIL(), which is a\n// generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)\n#define FAIL() GTEST_FAIL()\n#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)\n#endif\n\n// Generates a success with a generic message.\n#define GTEST_SUCCEED() GTEST_SUCCESS_(\"Succeeded\")\n\n// Define this macro to 1 to omit the definition of SUCCEED(), which\n// is a generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_SUCCEED) && GTEST_DONT_DEFINE_SUCCEED)\n#define SUCCEED() GTEST_SUCCEED()\n#endif\n\n// Macros for testing exceptions.\n//\n//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):\n//         Tests that the statement throws the expected exception.\n//    * {ASSERT|EXPECT}_NO_THROW(statement):\n//         Tests that the statement doesn't throw any exception.\n//    * {ASSERT|EXPECT}_ANY_THROW(statement):\n//         Tests that the statement throws an exception.\n\n#define EXPECT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)\n#define ASSERT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)\n#define ASSERT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)\n\n// Boolean assertions. Condition can be either a Boolean expression or an\n// AssertionResult. For more information on how to use AssertionResult with\n// these macros see comments on that class.\n#define GTEST_EXPECT_TRUE(condition)                      \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define GTEST_EXPECT_FALSE(condition)                        \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define GTEST_ASSERT_TRUE(condition) \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)\n#define GTEST_ASSERT_FALSE(condition)                        \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_FATAL_FAILURE_)\n\n// Define these macros to 1 to omit the definition of the corresponding\n// EXPECT or ASSERT, which clashes with some users' own code.\n\n#if !(defined(GTEST_DONT_DEFINE_EXPECT_TRUE) && GTEST_DONT_DEFINE_EXPECT_TRUE)\n#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_EXPECT_FALSE) && GTEST_DONT_DEFINE_EXPECT_FALSE)\n#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_TRUE) && GTEST_DONT_DEFINE_ASSERT_TRUE)\n#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_FALSE) && GTEST_DONT_DEFINE_ASSERT_FALSE)\n#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition)\n#endif\n\n// Macros for testing equalities and inequalities.\n//\n//    * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2\n//    * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2\n//    * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2\n//    * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2\n//    * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2\n//    * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2\n//\n// When they are not, Google Test prints both the tested expressions and\n// their actual values.  The values must be compatible built-in types,\n// or you will get a compiler error.  By \"compatible\" we mean that the\n// values can be compared by the respective operator.\n//\n// Note:\n//\n//   1. It is possible to make a user-defined type work with\n//   {ASSERT|EXPECT}_??(), but that requires overloading the\n//   comparison operators and is thus discouraged by the Google C++\n//   Usage Guide.  Therefore, you are advised to use the\n//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are\n//   equal.\n//\n//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on\n//   pointers (in particular, C strings).  Therefore, if you use it\n//   with two C strings, you are testing how their locations in memory\n//   are related, not how their content is related.  To compare two C\n//   strings by content, use {ASSERT|EXPECT}_STR*().\n//\n//   3. {ASSERT|EXPECT}_EQ(v1, v2) is preferred to\n//   {ASSERT|EXPECT}_TRUE(v1 == v2), as the former tells you\n//   what the actual value is when it fails, and similarly for the\n//   other comparisons.\n//\n//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()\n//   evaluate their arguments, which is undefined.\n//\n//   5. These macros evaluate their arguments exactly once.\n//\n// Examples:\n//\n//   EXPECT_NE(Foo(), 5);\n//   EXPECT_EQ(a_pointer, NULL);\n//   ASSERT_LT(i, array_size);\n//   ASSERT_GT(records.size(), 0) << \"There is no record left.\";\n\n#define EXPECT_EQ(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)\n#define EXPECT_NE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\n#define EXPECT_LE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define EXPECT_LT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define EXPECT_GE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define EXPECT_GT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n#define GTEST_ASSERT_EQ(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)\n#define GTEST_ASSERT_NE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\n#define GTEST_ASSERT_LE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define GTEST_ASSERT_LT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define GTEST_ASSERT_GE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define GTEST_ASSERT_GT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of\n// ASSERT_XY(), which clashes with some users' own code.\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_EQ) && GTEST_DONT_DEFINE_ASSERT_EQ)\n#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_NE) && GTEST_DONT_DEFINE_ASSERT_NE)\n#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_LE) && GTEST_DONT_DEFINE_ASSERT_LE)\n#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_LT) && GTEST_DONT_DEFINE_ASSERT_LT)\n#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_GE) && GTEST_DONT_DEFINE_ASSERT_GE)\n#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_GT) && GTEST_DONT_DEFINE_ASSERT_GT)\n#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)\n#endif\n\n// C-string Comparisons.  All tests treat NULL and any non-NULL string\n// as different.  Two NULLs are equal.\n//\n//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2\n//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2\n//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case\n//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case\n//\n// For wide or narrow string objects, you can use the\n// {ASSERT|EXPECT}_??() macros.\n//\n// Don't depend on the order in which the arguments are evaluated,\n// which is undefined.\n//\n// These macros evaluate their arguments exactly once.\n\n#define EXPECT_STREQ(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)\n#define EXPECT_STRNE(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define EXPECT_STRCASEEQ(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)\n#define EXPECT_STRCASENE(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n#define ASSERT_STREQ(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)\n#define ASSERT_STRNE(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define ASSERT_STRCASEEQ(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)\n#define ASSERT_STRCASENE(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n// Macros for comparing floating-point numbers.\n//\n//    * {ASSERT|EXPECT}_FLOAT_EQ(val1, val2):\n//         Tests that two float values are almost equal.\n//    * {ASSERT|EXPECT}_DOUBLE_EQ(val1, val2):\n//         Tests that two double values are almost equal.\n//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):\n//         Tests that v1 and v2 are within the given distance to each other.\n//\n// Google Test uses ULP-based comparison to automatically pick a default\n// error bound that is appropriate for the operands.  See the\n// FloatingPoint template class in gtest-internal.h if you are\n// interested in the implementation details.\n\n#define EXPECT_FLOAT_EQ(val1, val2)                                         \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      val1, val2)\n\n#define EXPECT_DOUBLE_EQ(val1, val2)                                         \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      val1, val2)\n\n#define ASSERT_FLOAT_EQ(val1, val2)                                         \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      val1, val2)\n\n#define ASSERT_DOUBLE_EQ(val1, val2)                                         \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      val1, val2)\n\n#define EXPECT_NEAR(val1, val2, abs_error)                                   \\\n  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \\\n                      abs_error)\n\n#define ASSERT_NEAR(val1, val2, abs_error)                                   \\\n  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \\\n                      abs_error)\n\n// These predicate format functions work on floating-point values, and\n// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.\n//\n//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nGTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,\n                                   float val1, float val2);\nGTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,\n                                    double val1, double val2);\n\n#ifdef GTEST_OS_WINDOWS\n\n// Macros that test for HRESULT failure and success, these are only useful\n// on Windows, and rely on Windows SDK macros and APIs to compile.\n//\n//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)\n//\n// When expr unexpectedly fails or succeeds, Google Test prints the\n// expected result and the actual result with both a human-readable\n// string representation of the error, if available, as well as the\n// hex result code.\n#define EXPECT_HRESULT_SUCCEEDED(expr) \\\n  EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n#define ASSERT_HRESULT_SUCCEEDED(expr) \\\n  ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n#define EXPECT_HRESULT_FAILED(expr) \\\n  EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n#define ASSERT_HRESULT_FAILED(expr) \\\n  ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n#endif  // GTEST_OS_WINDOWS\n\n// Macros that execute statement and check that it doesn't generate new fatal\n// failures in the current thread.\n//\n//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);\n//\n// Examples:\n//\n//   EXPECT_NO_FATAL_FAILURE(Process());\n//   ASSERT_NO_FATAL_FAILURE(Process()) << \"Process() failed\";\n//\n#define ASSERT_NO_FATAL_FAILURE(statement) \\\n  GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)\n#define EXPECT_NO_FATAL_FAILURE(statement) \\\n  GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)\n\n// Causes a trace (including the given source file path and line number,\n// and the given message) to be included in every test failure message generated\n// by code in the scope of the lifetime of an instance of this class. The effect\n// is undone with the destruction of the instance.\n//\n// The message argument can be anything streamable to std::ostream.\n//\n// Example:\n//   testing::ScopedTrace trace(\"file.cc\", 123, \"message\");\n//\nclass GTEST_API_ ScopedTrace {\n public:\n  // The c'tor pushes the given source file location and message onto\n  // a trace stack maintained by Google Test.\n\n  // Template version. Uses Message() to convert the values into strings.\n  // Slow, but flexible.\n  template <typename T>\n  ScopedTrace(const char* file, int line, const T& message) {\n    PushTrace(file, line, (Message() << message).GetString());\n  }\n\n  // Optimize for some known types.\n  ScopedTrace(const char* file, int line, const char* message) {\n    PushTrace(file, line, message ? message : \"(null)\");\n  }\n\n  ScopedTrace(const char* file, int line, const std::string& message) {\n    PushTrace(file, line, message);\n  }\n\n  // The d'tor pops the info pushed by the c'tor.\n  //\n  // Note that the d'tor is not virtual in order to be efficient.\n  // Don't inherit from ScopedTrace!\n  ~ScopedTrace();\n\n private:\n  void PushTrace(const char* file, int line, std::string message);\n\n  ScopedTrace(const ScopedTrace&) = delete;\n  ScopedTrace& operator=(const ScopedTrace&) = delete;\n};\n\n// Causes a trace (including the source file path, the current line\n// number, and the given message) to be included in every test failure\n// message generated by code in the current scope.  The effect is\n// undone when the control leaves the current scope.\n//\n// The message argument can be anything streamable to std::ostream.\n//\n// In the implementation, we include the current line number as part\n// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s\n// to appear in the same block - as long as they are on different\n// lines.\n//\n// Assuming that each thread maintains its own stack of traces.\n// Therefore, a SCOPED_TRACE() would (correctly) only affect the\n// assertions in its own thread.\n#define SCOPED_TRACE(message)                                               \\\n  const ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \\\n      __FILE__, __LINE__, (message))\n\n// Compile-time assertion for type equality.\n// StaticAssertTypeEq<type1, type2>() compiles if and only if type1 and type2\n// are the same type.  The value it returns is not interesting.\n//\n// Instead of making StaticAssertTypeEq a class template, we make it a\n// function template that invokes a helper class template.  This\n// prevents a user from misusing StaticAssertTypeEq<T1, T2> by\n// defining objects of that type.\n//\n// CAVEAT:\n//\n// When used inside a method of a class template,\n// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is\n// instantiated.  For example, given:\n//\n//   template <typename T> class Foo {\n//    public:\n//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }\n//   };\n//\n// the code:\n//\n//   void Test1() { Foo<bool> foo; }\n//\n// will NOT generate a compiler error, as Foo<bool>::Bar() is never\n// actually instantiated.  Instead, you need:\n//\n//   void Test2() { Foo<bool> foo; foo.Bar(); }\n//\n// to cause a compiler error.\ntemplate <typename T1, typename T2>\nconstexpr bool StaticAssertTypeEq() noexcept {\n  static_assert(std::is_same<T1, T2>::value, \"T1 and T2 are not the same type\");\n  return true;\n}\n\n// Defines a test.\n//\n// The first parameter is the name of the test suite, and the second\n// parameter is the name of the test within the test suite.\n//\n// The convention is to end the test suite name with \"Test\".  For\n// example, a test suite for the Foo class can be named FooTest.\n//\n// Test code should appear between braces after an invocation of\n// this macro.  Example:\n//\n//   TEST(FooTest, InitializesCorrectly) {\n//     Foo foo;\n//     EXPECT_TRUE(foo.StatusIsOK());\n//   }\n\n// Note that we call GetTestTypeId() instead of GetTypeId<\n// ::testing::Test>() here to get the type ID of testing::Test.  This\n// is to work around a suspected linker bug when using Google Test as\n// a framework on Mac OS X.  The bug causes GetTypeId<\n// ::testing::Test>() to return different values depending on whether\n// the call is from the Google Test framework itself or from user test\n// code.  GetTestTypeId() is guaranteed to always return the same\n// value, as it always calls GetTypeId<>() from the Google Test\n// framework.\n#define GTEST_TEST(test_suite_name, test_name)             \\\n  GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \\\n              ::testing::internal::GetTestTypeId())\n\n// Define this macro to 1 to omit the definition of TEST(), which\n// is a generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_TEST) && GTEST_DONT_DEFINE_TEST)\n#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)\n#endif\n\n// Defines a test that uses a test fixture.\n//\n// The first parameter is the name of the test fixture class, which\n// also doubles as the test suite name.  The second parameter is the\n// name of the test within the test suite.\n//\n// A test fixture class must be declared earlier.  The user should put\n// the test code between braces after using this macro.  Example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     void SetUp() override { b_.AddElement(3); }\n//\n//     Foo a_;\n//     Foo b_;\n//   };\n//\n//   TEST_F(FooTest, InitializesCorrectly) {\n//     EXPECT_TRUE(a_.StatusIsOK());\n//   }\n//\n//   TEST_F(FooTest, ReturnsElementCountCorrectly) {\n//     EXPECT_EQ(a_.size(), 0);\n//     EXPECT_EQ(b_.size(), 1);\n//   }\n#define GTEST_TEST_F(test_fixture, test_name)        \\\n  GTEST_TEST_(test_fixture, test_name, test_fixture, \\\n              ::testing::internal::GetTypeId<test_fixture>())\n#if !(defined(GTEST_DONT_DEFINE_TEST_F) && GTEST_DONT_DEFINE_TEST_F)\n#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)\n#endif\n\n// Returns a path to a temporary directory, which should be writable. It is\n// implementation-dependent whether or not the path is terminated by the\n// directory-separator character.\nGTEST_API_ std::string TempDir();\n\n// Returns a path to a directory that contains ancillary data files that might\n// be used by tests. It is implementation dependent whether or not the path is\n// terminated by the directory-separator character. The directory and the files\n// in it should be considered read-only.\nGTEST_API_ std::string SrcDir();\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4805 4100\n\n// Dynamically registers a test with the framework.\n//\n// This is an advanced API only to be used when the `TEST` macros are\n// insufficient. The macros should be preferred when possible, as they avoid\n// most of the complexity of calling this function.\n//\n// The `factory` argument is a factory callable (move-constructible) object or\n// function pointer that creates a new instance of the Test object. It\n// handles ownership to the caller. The signature of the callable is\n// `Fixture*()`, where `Fixture` is the test fixture class for the test. All\n// tests registered with the same `test_suite_name` must return the same\n// fixture type. This is checked at runtime.\n//\n// The framework will infer the fixture class from the factory and will call\n// the `SetUpTestSuite` and `TearDownTestSuite` for it.\n//\n// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is\n// undefined.\n//\n// Use case example:\n//\n// class MyFixture : public ::testing::Test {\n//  public:\n//   // All of these optional, just like in regular macro usage.\n//   static void SetUpTestSuite() { ... }\n//   static void TearDownTestSuite() { ... }\n//   void SetUp() override { ... }\n//   void TearDown() override { ... }\n// };\n//\n// class MyTest : public MyFixture {\n//  public:\n//   explicit MyTest(int data) : data_(data) {}\n//   void TestBody() override { ... }\n//\n//  private:\n//   int data_;\n// };\n//\n// void RegisterMyTests(const std::vector<int>& values) {\n//   for (int v : values) {\n//     ::testing::RegisterTest(\n//         \"MyFixture\", (\"Test\" + std::to_string(v)).c_str(), nullptr,\n//         std::to_string(v).c_str(),\n//         __FILE__, __LINE__,\n//         // Important to use the fixture type as the return type here.\n//         [=]() -> MyFixture* { return new MyTest(v); });\n//   }\n// }\n// ...\n// int main(int argc, char** argv) {\n//   ::testing::InitGoogleTest(&argc, argv);\n//   std::vector<int> values_to_test = LoadValuesFromConfig();\n//   RegisterMyTests(values_to_test);\n//   ...\n//   return RUN_ALL_TESTS();\n// }\n//\ntemplate <int&... ExplicitParameterBarrier, typename Factory>\nTestInfo* RegisterTest(const char* test_suite_name, const char* test_name,\n                       const char* type_param, const char* value_param,\n                       const char* file, int line, Factory factory) {\n  using TestT = typename std::remove_pointer<decltype(factory())>::type;\n\n  class FactoryImpl : public internal::TestFactoryBase {\n   public:\n    explicit FactoryImpl(Factory f) : factory_(std::move(f)) {}\n    Test* CreateTest() override { return factory_(); }\n\n   private:\n    Factory factory_;\n  };\n\n  return internal::MakeAndRegisterTestInfo(\n      test_suite_name, test_name, type_param, value_param,\n      internal::CodeLocation(file, line), internal::GetTypeId<TestT>(),\n      internal::SuiteApiResolver<TestT>::GetSetUpCaseOrSuite(file, line),\n      internal::SuiteApiResolver<TestT>::GetTearDownCaseOrSuite(file, line),\n      new FactoryImpl{std::move(factory)});\n}\n\n}  // namespace testing\n\n// Use this function in main() to run all tests.  It returns 0 if all\n// tests are successful, or 1 otherwise.\n//\n// RUN_ALL_TESTS() should be invoked after the command line has been\n// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any\n// installed environments and should only be called once per binary.\n//\n// This function was formerly a macro; thus, it is in the global\n// namespace and has an all-caps name.\nint RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;\n\ninline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest_pred_impl.h",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Implements a family of generic predicate assertion macros.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n\n#include \"gtest/gtest-assertion-result.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// This header implements a family of generic predicate assertion\n// macros:\n//\n//   ASSERT_PRED_FORMAT1(pred_format, v1)\n//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)\n//   ...\n//\n// where pred_format is a function or functor that takes n (in the\n// case of ASSERT_PRED_FORMATn) values and their source expression\n// text, and returns a testing::AssertionResult.  See the definition\n// of ASSERT_EQ in gtest.h for an example.\n//\n// If you don't care about formatting, you can use the more\n// restrictive version:\n//\n//   ASSERT_PRED1(pred, v1)\n//   ASSERT_PRED2(pred, v1, v2)\n//   ...\n//\n// where pred is an n-ary function or functor that returns bool,\n// and the values v1, v2, ..., must support the << operator for\n// streaming to std::ostream.\n//\n// We also define the EXPECT_* variations.\n//\n// For now we only support predicates whose arity is at most 5.\n// Please email googletestframework@googlegroups.com if you need\n// support for higher arities.\n\n// GTEST_ASSERT_ is the basic statement to which all of the assertions\n// in this file reduce.  Don't use this in your code.\n\n#define GTEST_ASSERT_(expression, on_failure)                   \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                 \\\n  if (const ::testing::AssertionResult gtest_ar = (expression)) \\\n    ;                                                           \\\n  else                                                          \\\n    on_failure(gtest_ar.failure_message())\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1>\nAssertionResult AssertPred1Helper(const char* pred_text, const char* e1,\n                                  Pred pred, const T1& v1) {\n  if (pred(v1)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, v1), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\n#define GTEST_PRED1_(pred, v1, on_failure) \\\n  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)\n\n// Unary predicate assertion macros.\n#define EXPECT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2>\nAssertionResult AssertPred2Helper(const char* pred_text, const char* e1,\n                                  const char* e2, Pred pred, const T1& v1,\n                                  const T2& v2) {\n  if (pred(v1, v2)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\n#define GTEST_PRED2_(pred, v1, v2, on_failure)                               \\\n  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \\\n                on_failure)\n\n// Binary predicate assertion macros.\n#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3>\nAssertionResult AssertPred3Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3, Pred pred,\n                                  const T1& v1, const T2& v2, const T3& v3) {\n  if (pred(v1, v2, v3)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\n#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)                          \\\n  GTEST_ASSERT_(                                                            \\\n      ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \\\n      on_failure)\n\n// Ternary predicate assertion macros.\n#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3, typename T4>\nAssertionResult AssertPred4Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3,\n                                  const char* e4, Pred pred, const T1& v1,\n                                  const T2& v2, const T3& v3, const T4& v4) {\n  if (pred(v1, v2, v3, v4)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3 << \", \" << e4\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3) << \"\\n\"\n         << e4 << \" evaluates to \" << ::testing::PrintToString(v4);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\n#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)                        \\\n  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \\\n                                             v1, v2, v3, v4),                 \\\n                on_failure)\n\n// 4-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3, typename T4,\n          typename T5>\nAssertionResult AssertPred5Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3,\n                                  const char* e4, const char* e5, Pred pred,\n                                  const T1& v1, const T2& v2, const T3& v3,\n                                  const T4& v4, const T5& v5) {\n  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3 << \", \" << e4\n         << \", \" << e5 << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3) << \"\\n\"\n         << e4 << \" evaluates to \" << ::testing::PrintToString(v4) << \"\\n\"\n         << e5 << \" evaluates to \" << ::testing::PrintToString(v5);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)  \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\n#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)                   \\\n  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \\\n                                             pred, v1, v2, v3, v4, v5),      \\\n                on_failure)\n\n// 5-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/gtest_prod.h",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google C++ Testing and Mocking Framework definitions useful in production\n// code.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n\n// When you need to test the private or protected members of a class,\n// use the FRIEND_TEST macro to declare your tests as friends of the\n// class.  For example:\n//\n// class MyClass {\n//  private:\n//   void PrivateMethod();\n//   FRIEND_TEST(MyClassTest, PrivateMethodWorks);\n// };\n//\n// class MyClassTest : public testing::Test {\n//   // ...\n// };\n//\n// TEST_F(MyClassTest, PrivateMethodWorks) {\n//   // Can call MyClass::PrivateMethod() here.\n// }\n//\n// Note: The test class must be in the same namespace as the class being tested.\n// For example, putting MyClassTest in an anonymous namespace will not work.\n\n#define FRIEND_TEST(test_case_name, test_name) \\\n  friend class test_case_name##_##test_name##_Test\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/custom/README.md",
    "content": "# Customization Points\n\nThe custom directory is an injection point for custom user configurations.\n\n## Header `gtest.h`\n\n### The following macros can be defined:\n\n*   `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of\n    `OsStackTraceGetterInterface`.\n*   `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See\n    `testing::TempDir` for semantics and signature.\n\n## Header `gtest-port.h`\n\nThe following macros can be defined:\n\n### Logging:\n\n*   `GTEST_LOG_(severity)`\n*   `GTEST_CHECK_(condition)`\n*   Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.\n\n### Threading:\n\n*   `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.\n*   `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`\n    are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`\n    and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`\n*   `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`\n*   `GTEST_LOCK_EXCLUDED_(locks)`\n\n### Underlying library support features\n\n*   `GTEST_HAS_CXXABI_H_`\n\n### Exporting API symbols:\n\n*   `GTEST_API_` - Specifier for exported symbols.\n\n## Header `gtest-printers.h`\n\n*   See documentation at `gtest/gtest-printers.h` for details on how to define a\n    custom printer.\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/custom/gtest-port.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/custom/gtest-printers.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// This file provides an injection point for custom printers in a local\n// installation of gTest.\n// It will be included from gtest-printers.h and the overrides in this file\n// will be visible to everyone.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/custom/gtest.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines internal utilities needed for implementing\n// death tests.  They are subject to change without notice.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n\n#include <stdio.h>\n\n#include <memory>\n#include <string>\n\n#include \"gtest/gtest-matchers.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nGTEST_DECLARE_string_(internal_run_death_test);\n\nnamespace testing {\nnamespace internal {\n\n// Name of the flag (needed for parsing Google Test flag).\nconst char kInternalRunDeathTestFlag[] = \"internal_run_death_test\";\n\n// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads\n// and interpreted as a regex (rather than an Eq matcher) for legacy\n// compatibility.\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    ::testing::internal::RE regex) {\n  return ContainsRegex(regex.pattern());\n}\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {\n  return ContainsRegex(regex);\n}\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    const ::std::string& regex) {\n  return ContainsRegex(regex);\n}\n\n// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's\n// used directly.\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    Matcher<const ::std::string&> matcher) {\n  return matcher;\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// DeathTest is a class that hides much of the complexity of the\n// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method\n// returns a concrete class that depends on the prevailing death test\n// style, as defined by the --gtest_death_test_style and/or\n// --gtest_internal_run_death_test flags.\n\n// In describing the results of death tests, these terms are used with\n// the corresponding definitions:\n//\n// exit status:  The integer exit information in the format specified\n//               by wait(2)\n// exit code:    The integer code passed to exit(3), _Exit(2), or\n//               returned from main()\nclass GTEST_API_ DeathTest {\n public:\n  // Create returns false if there was an error determining the\n  // appropriate action to take for the current death test; for example,\n  // if the gtest_death_test_style flag is set to an invalid value.\n  // The LastMessage method will return a more detailed message in that\n  // case.  Otherwise, the DeathTest pointer pointed to by the \"test\"\n  // argument is set.  If the death test should be skipped, the pointer\n  // is set to NULL; otherwise, it is set to the address of a new concrete\n  // DeathTest object that controls the execution of the current test.\n  static bool Create(const char* statement, Matcher<const std::string&> matcher,\n                     const char* file, int line, DeathTest** test);\n  DeathTest();\n  virtual ~DeathTest() = default;\n\n  // A helper class that aborts a death test when it's deleted.\n  class ReturnSentinel {\n   public:\n    explicit ReturnSentinel(DeathTest* test) : test_(test) {}\n    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }\n\n   private:\n    DeathTest* const test_;\n    ReturnSentinel(const ReturnSentinel&) = delete;\n    ReturnSentinel& operator=(const ReturnSentinel&) = delete;\n  };\n\n  // An enumeration of possible roles that may be taken when a death\n  // test is encountered.  EXECUTE means that the death test logic should\n  // be executed immediately.  OVERSEE means that the program should prepare\n  // the appropriate environment for a child process to execute the death\n  // test, then wait for it to complete.\n  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };\n\n  // An enumeration of the three reasons that a test might be aborted.\n  enum AbortReason {\n    TEST_ENCOUNTERED_RETURN_STATEMENT,\n    TEST_THREW_EXCEPTION,\n    TEST_DID_NOT_DIE\n  };\n\n  // Assumes one of the above roles.\n  virtual TestRole AssumeRole() = 0;\n\n  // Waits for the death test to finish and returns its status.\n  virtual int Wait() = 0;\n\n  // Returns true if the death test passed; that is, the test process\n  // exited during the test, its exit status matches a user-supplied\n  // predicate, and its stderr output matches a user-supplied regular\n  // expression.\n  // The user-supplied predicate may be a macro expression rather\n  // than a function pointer or functor, or else Wait and Passed could\n  // be combined.\n  virtual bool Passed(bool exit_status_ok) = 0;\n\n  // Signals that the death test did not die as expected.\n  virtual void Abort(AbortReason reason) = 0;\n\n  // Returns a human-readable outcome message regarding the outcome of\n  // the last death test.\n  static const char* LastMessage();\n\n  static void set_last_death_test_message(const std::string& message);\n\n private:\n  // A string containing a description of the outcome of the last death test.\n  static std::string last_death_test_message_;\n\n  DeathTest(const DeathTest&) = delete;\n  DeathTest& operator=(const DeathTest&) = delete;\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Factory interface for death tests.  May be mocked out for testing.\nclass DeathTestFactory {\n public:\n  virtual ~DeathTestFactory() = default;\n  virtual bool Create(const char* statement,\n                      Matcher<const std::string&> matcher, const char* file,\n                      int line, DeathTest** test) = 0;\n};\n\n// A concrete DeathTestFactory implementation for normal use.\nclass DefaultDeathTestFactory : public DeathTestFactory {\n public:\n  bool Create(const char* statement, Matcher<const std::string&> matcher,\n              const char* file, int line, DeathTest** test) override;\n};\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nGTEST_API_ bool ExitedUnsuccessfully(int exit_status);\n\n// Traps C++ exceptions escaping statement and reports them as test\n// failures. Note that trapping SEH exceptions is not implemented here.\n#if GTEST_HAS_EXCEPTIONS\n#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test)           \\\n  try {                                                                      \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);               \\\n  } catch (const ::std::exception& gtest_exception) {                        \\\n    fprintf(                                                                 \\\n        stderr,                                                              \\\n        \"\\n%s: Caught std::exception-derived exception escaping the \"        \\\n        \"death test statement. Exception message: %s\\n\",                     \\\n        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \\\n        gtest_exception.what());                                             \\\n    fflush(stderr);                                                          \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  } catch (...) {                                                            \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  }\n\n#else\n#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\n  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n\n#endif\n\n// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,\n// ASSERT_EXIT*, and EXPECT_EXIT*.\n#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail)        \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                \\\n  if (::testing::internal::AlwaysTrue()) {                                     \\\n    ::testing::internal::DeathTest* gtest_dt;                                  \\\n    if (!::testing::internal::DeathTest::Create(                               \\\n            #statement,                                                        \\\n            ::testing::internal::MakeDeathTestMatcher(regex_or_matcher),       \\\n            __FILE__, __LINE__, &gtest_dt)) {                                  \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                        \\\n    }                                                                          \\\n    if (gtest_dt != nullptr) {                                                 \\\n      std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \\\n      switch (gtest_dt->AssumeRole()) {                                        \\\n        case ::testing::internal::DeathTest::OVERSEE_TEST:                     \\\n          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) {                \\\n            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                  \\\n          }                                                                    \\\n          break;                                                               \\\n        case ::testing::internal::DeathTest::EXECUTE_TEST: {                   \\\n          const ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \\\n              gtest_dt);                                                       \\\n          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt);            \\\n          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE);   \\\n          break;                                                               \\\n        }                                                                      \\\n      }                                                                        \\\n    }                                                                          \\\n  } else                                                                       \\\n    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__)                                \\\n        : fail(::testing::internal::DeathTest::LastMessage())\n// The symbol \"fail\" here expands to something into which a message\n// can be streamed.\n\n// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in\n// NDEBUG mode. In this case we need the statements to be executed and the macro\n// must accept a streamed message even though the message is never printed.\n// The regex object is not evaluated, but it is used to prevent \"unused\"\n// warnings and to avoid an expression that doesn't compile in debug mode.\n#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher)    \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                  \\\n  if (::testing::internal::AlwaysTrue()) {                       \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);   \\\n  } else if (!::testing::internal::AlwaysTrue()) {               \\\n    ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \\\n  } else                                                         \\\n    ::testing::Message()\n\n// A class representing the parsed contents of the\n// --gtest_internal_run_death_test flag, as it existed when\n// RUN_ALL_TESTS was called.\nclass InternalRunDeathTestFlag {\n public:\n  InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,\n                           int a_write_fd)\n      : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}\n\n  ~InternalRunDeathTestFlag() {\n    if (write_fd_ >= 0) posix::Close(write_fd_);\n  }\n\n  const std::string& file() const { return file_; }\n  int line() const { return line_; }\n  int index() const { return index_; }\n  int write_fd() const { return write_fd_; }\n\n private:\n  std::string file_;\n  int line_;\n  int index_;\n  int write_fd_;\n\n  InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;\n  InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;\n};\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-filepath.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test filepath utilities\n//\n// This header file declares classes and functions used internally by\n// Google Test.  They are subject to change without notice.\n//\n// This file is #included in gtest/internal/gtest-internal.h.\n// Do not include this header file separately!\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n\n#include <string>\n#include <utility>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n#if GTEST_HAS_FILE_SYSTEM\n\nnamespace testing {\nnamespace internal {\n\n// FilePath - a class for file and directory pathname manipulation which\n// handles platform-specific conventions (like the pathname separator).\n// Used for helper functions for naming files in a directory for xml output.\n// Except for Set methods, all methods are const or static, which provides an\n// \"immutable value object\" -- useful for peace of mind.\n// A FilePath with a value ending in a path separator (\"like/this/\") represents\n// a directory, otherwise it is assumed to represent a file. In either case,\n// it may or may not represent an actual file or directory in the file system.\n// Names are NOT checked for syntax correctness -- no checking for illegal\n// characters, malformed paths, etc.\n\nclass GTEST_API_ FilePath {\n public:\n  FilePath() : pathname_(\"\") {}\n  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}\n  FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}\n\n  explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {\n    Normalize();\n  }\n\n  FilePath& operator=(const FilePath& rhs) {\n    Set(rhs);\n    return *this;\n  }\n  FilePath& operator=(FilePath&& rhs) noexcept {\n    pathname_ = std::move(rhs.pathname_);\n    return *this;\n  }\n\n  void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }\n\n  const std::string& string() const { return pathname_; }\n  const char* c_str() const { return pathname_.c_str(); }\n\n  // Returns the current working directory, or \"\" if unsuccessful.\n  static FilePath GetCurrentDir();\n\n  // Given directory = \"dir\", base_name = \"test\", number = 0,\n  // extension = \"xml\", returns \"dir/test.xml\". If number is greater\n  // than zero (e.g., 12), returns \"dir/test_12.xml\".\n  // On Windows platform, uses \\ as the separator rather than /.\n  static FilePath MakeFileName(const FilePath& directory,\n                               const FilePath& base_name, int number,\n                               const char* extension);\n\n  // Given directory = \"dir\", relative_path = \"test.xml\",\n  // returns \"dir/test.xml\".\n  // On Windows, uses \\ as the separator rather than /.\n  static FilePath ConcatPaths(const FilePath& directory,\n                              const FilePath& relative_path);\n\n  // Returns a pathname for a file that does not currently exist. The pathname\n  // will be directory/base_name.extension or\n  // directory/base_name_<number>.extension if directory/base_name.extension\n  // already exists. The number will be incremented until a pathname is found\n  // that does not already exist.\n  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n  // There could be a race condition if two or more processes are calling this\n  // function at the same time -- they could both pick the same filename.\n  static FilePath GenerateUniqueFileName(const FilePath& directory,\n                                         const FilePath& base_name,\n                                         const char* extension);\n\n  // Returns true if and only if the path is \"\".\n  bool IsEmpty() const { return pathname_.empty(); }\n\n  // If input name has a trailing separator character, removes it and returns\n  // the name, otherwise return the name string unmodified.\n  // On Windows platform, uses \\ as the separator, other platforms use /.\n  FilePath RemoveTrailingPathSeparator() const;\n\n  // Returns a copy of the FilePath with the directory part removed.\n  // Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n  // FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n  // the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n  // returns an empty FilePath (\"\").\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveDirectoryName() const;\n\n  // RemoveFileName returns the directory path with the filename removed.\n  // Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n  // If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n  // FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n  // not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveFileName() const;\n\n  // Returns a copy of the FilePath with the case-insensitive extension removed.\n  // Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n  // FilePath(\"dir/file\"). If a case-insensitive extension is not\n  // found, returns a copy of the original FilePath.\n  FilePath RemoveExtension(const char* extension) const;\n\n  // Creates directories so that path exists. Returns true if successful or if\n  // the directories already exist; returns false if unable to create\n  // directories for any reason. Will also return false if the FilePath does\n  // not represent a directory (that is, it doesn't end with a path separator).\n  bool CreateDirectoriesRecursively() const;\n\n  // Create the directory so that path exists. Returns true if successful or\n  // if the directory already exists; returns false if unable to create the\n  // directory for any reason, including if the parent directory does not\n  // exist. Not named \"CreateDirectory\" because that's a macro on Windows.\n  bool CreateFolder() const;\n\n  // Returns true if FilePath describes something in the file-system,\n  // either a file, directory, or whatever, and that something exists.\n  bool FileOrDirectoryExists() const;\n\n  // Returns true if pathname describes a directory in the file-system\n  // that exists.\n  bool DirectoryExists() const;\n\n  // Returns true if FilePath ends with a path separator, which indicates that\n  // it is intended to represent a directory. Returns false otherwise.\n  // This does NOT check that a directory (or file) actually exists.\n  bool IsDirectory() const;\n\n  // Returns true if pathname describes a root directory. (Windows has one\n  // root directory per disk drive.)\n  bool IsRootDirectory() const;\n\n  // Returns true if pathname describes an absolute path.\n  bool IsAbsolutePath() const;\n\n private:\n  // Replaces multiple consecutive separators with a single separator.\n  // For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n  // redundancies that might be in a pathname involving \".\" or \"..\".\n  //\n  // A pathname with multiple consecutive separators may occur either through\n  // user error or as a result of some scripts or APIs that generate a pathname\n  // with a trailing separator. On other platforms the same API or script\n  // may NOT generate a pathname with a trailing \"/\". Then elsewhere that\n  // pathname may have another \"/\" and pathname components added to it,\n  // without checking for the separator already being there.\n  // The script language and operating system may allow paths like \"foo//bar\"\n  // but some of the functions in FilePath will not handle that correctly. In\n  // particular, RemoveTrailingPathSeparator() only removes one separator, and\n  // it is called in CreateDirectoriesRecursively() assuming that it will change\n  // a pathname from directory syntax (trailing separator) to filename syntax.\n  //\n  // On Windows this method also replaces the alternate path separator '/' with\n  // the primary path separator '\\\\', so that for example \"bar\\\\/\\\\foo\" becomes\n  // \"bar\\\\foo\".\n\n  void Normalize();\n\n  // Returns a pointer to the last occurrence of a valid path separator in\n  // the FilePath. On Windows, for example, both '/' and '\\' are valid path\n  // separators. Returns NULL if no path separator was found.\n  const char* FindLastPathSeparator() const;\n\n  // Returns the length of the path root, including the directory separator at\n  // the end of the prefix. Returns zero by definition if the path is relative.\n  // Examples:\n  // - [Windows] \"..\\Sibling\" => 0\n  // - [Windows] \"\\Windows\" => 1\n  // - [Windows] \"C:/Windows\\Notepad.exe\" => 3\n  // - [Windows] \"\\\\Host\\Share\\C$/Windows\" => 13\n  // - [UNIX] \"/bin\" => 1\n  size_t CalculateRootLength() const;\n\n  std::string pathname_;\n};  // class FilePath\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-internal.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file declares functions and macros used internally by\n// Google Test.  They are subject to change without notice.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_LINUX\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>\n#endif\n\n#include <ctype.h>\n#include <float.h>\n#include <string.h>\n\n#include <cstdint>\n#include <functional>\n#include <limits>\n#include <map>\n#include <set>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-filepath.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"gtest/internal/gtest-type-util.h\"\n\n// Due to C++ preprocessor weirdness, we need double indirection to\n// concatenate two tokens when one of them is __LINE__.  Writing\n//\n//   foo ## __LINE__\n//\n// will result in the token foo__LINE__, instead of foo followed by\n// the current line number.  For more details, see\n// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6\n#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)\n#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar\n\n// Stringifies its argument.\n// Work around a bug in visual studio which doesn't accept code like this:\n//\n//   #define GTEST_STRINGIFY_(name) #name\n//   #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...\n//   MACRO(, x, y)\n//\n// Complaining about the argument to GTEST_STRINGIFY_ being empty.\n// This is allowed by the spec.\n#define GTEST_STRINGIFY_HELPER_(name, ...) #name\n#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )\n\nnamespace proto2 {\nclass MessageLite;\n}\n\nnamespace testing {\n\n// Forward declarations.\n\nclass AssertionResult;  // Result of an assertion.\nclass Message;          // Represents a failure message.\nclass Test;             // Represents a test.\nclass TestInfo;         // Information about a test.\nclass TestPartResult;   // Result of a test part.\nclass UnitTest;         // A collection of test suites.\n\ntemplate <typename T>\n::std::string PrintToString(const T& value);\n\nnamespace internal {\n\nstruct TraceInfo;    // Information about a trace point.\nclass TestInfoImpl;  // Opaque implementation of TestInfo\nclass UnitTestImpl;  // Opaque implementation of UnitTest\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nGTEST_API_ extern const char kStackTraceMarker[];\n\n// An IgnoredValue object can be implicitly constructed from ANY value.\nclass IgnoredValue {\n  struct Sink {};\n\n public:\n  // This constructor template allows any value to be implicitly\n  // converted to IgnoredValue.  The object has no data member and\n  // doesn't try to remember anything about the argument.  We\n  // deliberately omit the 'explicit' keyword in order to allow the\n  // conversion to be implicit.\n  // Disable the conversion if T already has a magical conversion operator.\n  // Otherwise we get ambiguity.\n  template <typename T,\n            typename std::enable_if<!std::is_convertible<T, Sink>::value,\n                                    int>::type = 0>\n  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)\n};\n\n// Appends the user-supplied message to the Google-Test-generated message.\nGTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,\n                                         const Message& user_msg);\n\n#if GTEST_HAS_EXCEPTIONS\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4275 /* an exported class was derived from a class that was not exported */)\n\n// This exception is thrown by (and only by) a failed Google Test\n// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions\n// are enabled).  We derive it from std::runtime_error, which is for\n// errors presumably detectable only at run time.  Since\n// std::runtime_error inherits from std::exception, many testing\n// frameworks know how to extract and print the message inside it.\nclass GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {\n public:\n  explicit GoogleTestFailureException(const TestPartResult& failure);\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4275\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\nnamespace edit_distance {\n// Returns the optimal edits to go from 'left' to 'right'.\n// All edits cost the same, with replace having lower priority than\n// add/remove.\n// Simple implementation of the Wagner-Fischer algorithm.\n// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm\nenum EditType { kMatch, kAdd, kRemove, kReplace };\nGTEST_API_ std::vector<EditType> CalculateOptimalEdits(\n    const std::vector<size_t>& left, const std::vector<size_t>& right);\n\n// Same as above, but the input is represented as strings.\nGTEST_API_ std::vector<EditType> CalculateOptimalEdits(\n    const std::vector<std::string>& left,\n    const std::vector<std::string>& right);\n\n// Create a diff of the input strings in Unified diff format.\nGTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,\n                                         const std::vector<std::string>& right,\n                                         size_t context = 2);\n\n}  // namespace edit_distance\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   expected_expression: \"foo\"\n//   actual_expression:   \"bar\"\n//   expected_value:      \"5\"\n//   actual_value:        \"6\"\n//\n// The ignoring_case parameter is true if and only if the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\n// be inserted into the message.\nGTEST_API_ AssertionResult EqFailure(const char* expected_expression,\n                                     const char* actual_expression,\n                                     const std::string& expected_value,\n                                     const std::string& actual_value,\n                                     bool ignoring_case);\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nGTEST_API_ std::string GetBoolAssertionFailureMessage(\n    const AssertionResult& assertion_result, const char* expression_text,\n    const char* actual_predicate_value, const char* expected_predicate_value);\n\n// This template class represents an IEEE floating-point number\n// (either single-precision or double-precision, depending on the\n// template parameters).\n//\n// The purpose of this class is to do more sophisticated number\n// comparison.  (Due to round-off error, etc, it's very unlikely that\n// two floating-points will be equal exactly.  Hence a naive\n// comparison by the == operation often doesn't work.)\n//\n// Format of IEEE floating-point:\n//\n//   The most-significant bit being the leftmost, an IEEE\n//   floating-point looks like\n//\n//     sign_bit exponent_bits fraction_bits\n//\n//   Here, sign_bit is a single bit that designates the sign of the\n//   number.\n//\n//   For float, there are 8 exponent bits and 23 fraction bits.\n//\n//   For double, there are 11 exponent bits and 52 fraction bits.\n//\n//   More details can be found at\n//   https://en.wikipedia.org/wiki/IEEE_floating-point_standard.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\ntemplate <typename RawType>\nclass FloatingPoint {\n public:\n  // Defines the unsigned integer type that has the same size as the\n  // floating point number.\n  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;\n\n  // Constants.\n\n  // # of bits in a number.\n  static const size_t kBitCount = 8 * sizeof(RawType);\n\n  // # of fraction bits in a number.\n  static const size_t kFractionBitCount =\n      std::numeric_limits<RawType>::digits - 1;\n\n  // # of exponent bits in a number.\n  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;\n\n  // The mask for the sign bit.\n  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);\n\n  // The mask for the fraction bits.\n  static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>\n                                       (kExponentBitCount + 1);\n\n  // The mask for the exponent bits.\n  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);\n\n  // How many ULP's (Units in the Last Place) we want to tolerate when\n  // comparing two numbers.  The larger the value, the more error we\n  // allow.  A 0 value means that two numbers must be exactly the same\n  // to be considered equal.\n  //\n  // The maximum error of a single floating-point operation is 0.5\n  // units in the last place.  On Intel CPU's, all floating-point\n  // calculations are done with 80-bit precision, while double has 64\n  // bits.  Therefore, 4 should be enough for ordinary use.\n  //\n  // See the following article for more details on ULP:\n  // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/\n  static const uint32_t kMaxUlps = 4;\n\n  // Constructs a FloatingPoint from a raw floating-point number.\n  //\n  // On an Intel CPU, passing a non-normalized NAN (Not a Number)\n  // around may change its bits, although the new value is guaranteed\n  // to be also a NAN.  Therefore, don't expect this constructor to\n  // preserve the bits in x when x is a NAN.\n  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }\n\n  // Static methods\n\n  // Reinterprets a bit pattern as a floating-point number.\n  //\n  // This function is needed to test the AlmostEquals() method.\n  static RawType ReinterpretBits(const Bits bits) {\n    FloatingPoint fp(0);\n    fp.u_.bits_ = bits;\n    return fp.u_.value_;\n  }\n\n  // Returns the floating-point number that represent positive infinity.\n  static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }\n\n  // Non-static methods\n\n  // Returns the bits that represents this number.\n  const Bits& bits() const { return u_.bits_; }\n\n  // Returns the exponent bits of this number.\n  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }\n\n  // Returns the fraction bits of this number.\n  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }\n\n  // Returns the sign bit of this number.\n  Bits sign_bit() const { return kSignBitMask & u_.bits_; }\n\n  // Returns true if and only if this is NAN (not a number).\n  bool is_nan() const {\n    // It's a NAN if the exponent bits are all ones and the fraction\n    // bits are not entirely zeros.\n    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);\n  }\n\n  // Returns true if and only if this number is at most kMaxUlps ULP's away\n  // from rhs.  In particular, this function:\n  //\n  //   - returns false if either number is (or both are) NAN.\n  //   - treats really large numbers as almost equal to infinity.\n  //   - thinks +0.0 and -0.0 are 0 DLP's apart.\n  bool AlmostEquals(const FloatingPoint& rhs) const {\n    // The IEEE standard says that any comparison operation involving\n    // a NAN must return false.\n    if (is_nan() || rhs.is_nan()) return false;\n\n    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=\n           kMaxUlps;\n  }\n\n private:\n  // The data type used to store the actual floating-point number.\n  union FloatingPointUnion {\n    RawType value_;  // The raw floating-point number.\n    Bits bits_;      // The bits that represent the number.\n  };\n\n  // Converts an integer from the sign-and-magnitude representation to\n  // the biased representation.  More precisely, let N be 2 to the\n  // power of (kBitCount - 1), an integer x is represented by the\n  // unsigned number x + N.\n  //\n  // For instance,\n  //\n  //   -N + 1 (the most negative number representable using\n  //          sign-and-magnitude) is represented by 1;\n  //   0      is represented by N; and\n  //   N - 1  (the biggest number representable using\n  //          sign-and-magnitude) is represented by 2N - 1.\n  //\n  // Read https://en.wikipedia.org/wiki/Signed_number_representations\n  // for more details on signed number representations.\n  static Bits SignAndMagnitudeToBiased(const Bits& sam) {\n    if (kSignBitMask & sam) {\n      // sam represents a negative number.\n      return ~sam + 1;\n    } else {\n      // sam represents a positive number.\n      return kSignBitMask | sam;\n    }\n  }\n\n  // Given two numbers in the sign-and-magnitude representation,\n  // returns the distance between them as an unsigned number.\n  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,\n                                                     const Bits& sam2) {\n    const Bits biased1 = SignAndMagnitudeToBiased(sam1);\n    const Bits biased2 = SignAndMagnitudeToBiased(sam2);\n    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);\n  }\n\n  FloatingPointUnion u_;\n};\n\n// Typedefs the instances of the FloatingPoint template class that we\n// care to use.\ntypedef FloatingPoint<float> Float;\ntypedef FloatingPoint<double> Double;\n\n// In order to catch the mistake of putting tests that use different\n// test fixture classes in the same test suite, we need to assign\n// unique IDs to fixture classes and compare them.  The TypeId type is\n// used to hold such IDs.  The user should treat TypeId as an opaque\n// type: the only operation allowed on TypeId values is to compare\n// them for equality using the == operator.\ntypedef const void* TypeId;\n\ntemplate <typename T>\nclass TypeIdHelper {\n public:\n  // dummy_ must not have a const type.  Otherwise an overly eager\n  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge\n  // TypeIdHelper<T>::dummy_ for different Ts as an \"optimization\".\n  static bool dummy_;\n};\n\ntemplate <typename T>\nbool TypeIdHelper<T>::dummy_ = false;\n\n// GetTypeId<T>() returns the ID of type T.  Different values will be\n// returned for different types.  Calling the function twice with the\n// same type argument is guaranteed to return the same ID.\ntemplate <typename T>\nTypeId GetTypeId() {\n  // The compiler is required to allocate a different\n  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate\n  // the template.  Therefore, the address of dummy_ is guaranteed to\n  // be unique.\n  return &(TypeIdHelper<T>::dummy_);\n}\n\n// Returns the type ID of ::testing::Test.  Always call this instead\n// of GetTypeId< ::testing::Test>() to get the type ID of\n// ::testing::Test, as the latter may give the wrong result due to a\n// suspected linker bug when compiling Google Test as a Mac OS X\n// framework.\nGTEST_API_ TypeId GetTestTypeId();\n\n// Defines the abstract factory interface that creates instances\n// of a Test object.\nclass TestFactoryBase {\n public:\n  virtual ~TestFactoryBase() = default;\n\n  // Creates a test instance to run. The instance is both created and destroyed\n  // within TestInfoImpl::Run()\n  virtual Test* CreateTest() = 0;\n\n protected:\n  TestFactoryBase() {}\n\n private:\n  TestFactoryBase(const TestFactoryBase&) = delete;\n  TestFactoryBase& operator=(const TestFactoryBase&) = delete;\n};\n\n// This class provides implementation of TestFactoryBase interface.\n// It is used in TEST and TEST_F macros.\ntemplate <class TestClass>\nclass TestFactoryImpl : public TestFactoryBase {\n public:\n  Test* CreateTest() override { return new TestClass; }\n};\n\n#ifdef GTEST_OS_WINDOWS\n\n// Predicate-formatters for implementing the HRESULT checking macros\n// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}\n// We pass a long instead of HRESULT to avoid causing an\n// include dependency for the HRESULT type.\nGTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,\n                                            long hr);  // NOLINT\nGTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,\n                                            long hr);  // NOLINT\n\n#endif  // GTEST_OS_WINDOWS\n\n// Types of SetUpTestSuite() and TearDownTestSuite() functions.\nusing SetUpTestSuiteFunc = void (*)();\nusing TearDownTestSuiteFunc = void (*)();\n\nstruct CodeLocation {\n  CodeLocation(std::string a_file, int a_line)\n      : file(std::move(a_file)), line(a_line) {}\n\n  std::string file;\n  int line;\n};\n\n//  Helper to identify which setup function for TestCase / TestSuite to call.\n//  Only one function is allowed, either TestCase or TestSute but not both.\n\n// Utility functions to help SuiteApiResolver\nusing SetUpTearDownSuiteFuncType = void (*)();\n\ninline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(\n    SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {\n  return a == def ? nullptr : a;\n}\n\ntemplate <typename T>\n//  Note that SuiteApiResolver inherits from T because\n//  SetUpTestSuite()/TearDownTestSuite() could be protected. This way\n//  SuiteApiResolver can access them.\nstruct SuiteApiResolver : T {\n  // testing::Test is only forward declared at this point. So we make it a\n  // dependent class for the compiler to be OK with it.\n  using Test =\n      typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;\n\n  static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,\n                                                        int line_num) {\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n    SetUpTearDownSuiteFuncType test_case_fp =\n        GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);\n    SetUpTearDownSuiteFuncType test_suite_fp =\n        GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);\n\n    GTEST_CHECK_(!test_case_fp || !test_suite_fp)\n        << \"Test can not provide both SetUpTestSuite and SetUpTestCase, please \"\n           \"make sure there is only one present at \"\n        << filename << \":\" << line_num;\n\n    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;\n#else\n    (void)(filename);\n    (void)(line_num);\n    return &T::SetUpTestSuite;\n#endif\n  }\n\n  static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,\n                                                           int line_num) {\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n    SetUpTearDownSuiteFuncType test_case_fp =\n        GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);\n    SetUpTearDownSuiteFuncType test_suite_fp =\n        GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);\n\n    GTEST_CHECK_(!test_case_fp || !test_suite_fp)\n        << \"Test can not provide both TearDownTestSuite and TearDownTestCase,\"\n           \" please make sure there is only one present at\"\n        << filename << \":\" << line_num;\n\n    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;\n#else\n    (void)(filename);\n    (void)(line_num);\n    return &T::TearDownTestSuite;\n#endif\n  }\n};\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_suite_name:  name of the test suite\n//   name:             name of the test\n//   type_param:       the name of the test's type parameter, or NULL if\n//                     this is not a typed or a type-parameterized test.\n//   value_param:      text representation of the test's value parameter,\n//                     or NULL if this is not a value-parameterized test.\n//   code_location:    code location where the test is defined\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test suite\n//   tear_down_tc:     pointer to the function that tears down the test suite\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nGTEST_API_ TestInfo* MakeAndRegisterTestInfo(\n    std::string test_suite_name, const char* name, const char* type_param,\n    const char* value_param, CodeLocation code_location,\n    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,\n    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nGTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// State of the definition of a type-parameterized test suite.\nclass GTEST_API_ TypedTestSuitePState {\n public:\n  TypedTestSuitePState() : registered_(false) {}\n\n  // Adds the given test name to defined_test_names_ and return true\n  // if the test suite hasn't been registered; otherwise aborts the\n  // program.\n  bool AddTestName(const char* file, int line, const char* case_name,\n                   const char* test_name) {\n    if (registered_) {\n      fprintf(stderr,\n              \"%s Test %s must be defined before \"\n              \"REGISTER_TYPED_TEST_SUITE_P(%s, ...).\\n\",\n              FormatFileLocation(file, line).c_str(), test_name, case_name);\n      fflush(stderr);\n      posix::Abort();\n    }\n    registered_tests_.emplace(test_name, CodeLocation(file, line));\n    return true;\n  }\n\n  bool TestExists(const std::string& test_name) const {\n    return registered_tests_.count(test_name) > 0;\n  }\n\n  const CodeLocation& GetCodeLocation(const std::string& test_name) const {\n    RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);\n    GTEST_CHECK_(it != registered_tests_.end());\n    return it->second;\n  }\n\n  // Verifies that registered_tests match the test names in\n  // defined_test_names_; returns registered_tests if successful, or\n  // aborts the program otherwise.\n  const char* VerifyRegisteredTestNames(const char* test_suite_name,\n                                        const char* file, int line,\n                                        const char* registered_tests);\n\n private:\n  typedef ::std::map<std::string, CodeLocation, std::less<>> RegisteredTestsMap;\n\n  bool registered_;\n  RegisteredTestsMap registered_tests_;\n};\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nusing TypedTestCasePState = TypedTestSuitePState;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Skips to the first non-space char after the first comma in 'str';\n// returns NULL if no comma is found in 'str'.\ninline const char* SkipComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  if (comma == nullptr) {\n    return nullptr;\n  }\n  while (IsSpace(*(++comma))) {\n  }\n  return comma;\n}\n\n// Returns the prefix of 'str' before the first comma in it; returns\n// the entire string if it contains no comma.\ninline std::string GetPrefixUntilComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  return comma == nullptr ? str : std::string(str, comma);\n}\n\n// Splits a given string on a given delimiter, populating a given\n// vector with the fields.\nvoid SplitString(const ::std::string& str, char delimiter,\n                 ::std::vector<::std::string>* dest);\n\n// The default argument to the template below for the case when the user does\n// not provide a name generator.\nstruct DefaultNameGenerator {\n  template <typename T>\n  static std::string GetName(int i) {\n    return StreamableToString(i);\n  }\n};\n\ntemplate <typename Provided = DefaultNameGenerator>\nstruct NameGeneratorSelector {\n  typedef Provided type;\n};\n\ntemplate <typename NameGenerator>\nvoid GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}\n\ntemplate <typename NameGenerator, typename Types>\nvoid GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {\n  result->push_back(NameGenerator::template GetName<typename Types::Head>(i));\n  GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,\n                                          i + 1);\n}\n\ntemplate <typename NameGenerator, typename Types>\nstd::vector<std::string> GenerateNames() {\n  std::vector<std::string> result;\n  GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);\n  return result;\n}\n\n// TypeParameterizedTest<Fixture, TestSel, Types>::Register()\n// registers a list of type-parameterized tests with Google Test.  The\n// return value is insignificant - we just need to return something\n// such that we can call this function in a namespace scope.\n//\n// Implementation note: The GTEST_TEMPLATE_ macro declares a template\n// template parameter.  It's defined in gtest-type-util.h.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>\nclass TypeParameterizedTest {\n public:\n  // 'index' is the index of the test in the type list 'Types'\n  // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,\n  // Types).  Valid values for 'index' are [0, N - 1] where N is the\n  // length of Types.\n  static bool Register(const char* prefix, CodeLocation code_location,\n                       const char* case_name, const char* test_names, int index,\n                       const std::vector<std::string>& type_names =\n                           GenerateNames<DefaultNameGenerator, Types>()) {\n    typedef typename Types::Head Type;\n    typedef Fixture<Type> FixtureClass;\n    typedef typename GTEST_BIND_(TestSel, Type) TestClass;\n\n    // First, registers the first type-parameterized test in the type\n    // list.\n    MakeAndRegisterTestInfo(\n        (std::string(prefix) + (prefix[0] == '\\0' ? \"\" : \"/\") + case_name +\n         \"/\" + type_names[static_cast<size_t>(index)]),\n        StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),\n        GetTypeName<Type>().c_str(),\n        nullptr,  // No value parameter.\n        code_location, GetTypeId<FixtureClass>(),\n        SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(\n            code_location.file.c_str(), code_location.line),\n        SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(\n            code_location.file.c_str(), code_location.line),\n        new TestFactoryImpl<TestClass>);\n\n    // Next, recurses (at compile time) with the tail of the type list.\n    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::\n        Register(prefix, std::move(code_location), case_name, test_names,\n                 index + 1, type_names);\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel>\nclass TypeParameterizedTest<Fixture, TestSel, internal::None> {\n public:\n  static bool Register(const char* /*prefix*/, CodeLocation,\n                       const char* /*case_name*/, const char* /*test_names*/,\n                       int /*index*/,\n                       const std::vector<std::string>& =\n                           std::vector<std::string>() /*type_names*/) {\n    return true;\n  }\n};\n\nGTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,\n                                                   CodeLocation code_location);\nGTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(\n    const char* case_name);\n\n// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()\n// registers *all combinations* of 'Tests' and 'Types' with Google\n// Test.  The return value is insignificant - we just need to return\n// something such that we can call this function in a namespace scope.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>\nclass TypeParameterizedTestSuite {\n public:\n  static bool Register(const char* prefix, CodeLocation code_location,\n                       const TypedTestSuitePState* state, const char* case_name,\n                       const char* test_names,\n                       const std::vector<std::string>& type_names =\n                           GenerateNames<DefaultNameGenerator, Types>()) {\n    RegisterTypeParameterizedTestSuiteInstantiation(case_name);\n    std::string test_name =\n        StripTrailingSpaces(GetPrefixUntilComma(test_names));\n    if (!state->TestExists(test_name)) {\n      fprintf(stderr, \"Failed to get code location for test %s.%s at %s.\",\n              case_name, test_name.c_str(),\n              FormatFileLocation(code_location.file.c_str(), code_location.line)\n                  .c_str());\n      fflush(stderr);\n      posix::Abort();\n    }\n    const CodeLocation& test_location = state->GetCodeLocation(test_name);\n\n    typedef typename Tests::Head Head;\n\n    // First, register the first test in 'Test' for each type in 'Types'.\n    TypeParameterizedTest<Fixture, Head, Types>::Register(\n        prefix, test_location, case_name, test_names, 0, type_names);\n\n    // Next, recurses (at compile time) with the tail of the test list.\n    return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,\n                                      Types>::Register(prefix,\n                                                       std::move(code_location),\n                                                       state, case_name,\n                                                       SkipComma(test_names),\n                                                       type_names);\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Types>\nclass TypeParameterizedTestSuite<Fixture, internal::None, Types> {\n public:\n  static bool Register(const char* /*prefix*/, const CodeLocation&,\n                       const TypedTestSuitePState* /*state*/,\n                       const char* /*case_name*/, const char* /*test_names*/,\n                       const std::vector<std::string>& =\n                           std::vector<std::string>() /*type_names*/) {\n    return true;\n  }\n};\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nGTEST_API_ std::string GetCurrentOsStackTraceExceptTop(int skip_count);\n\n// Helpers for suppressing warnings on unreachable code or constant\n// condition.\n\n// Always returns true.\nGTEST_API_ bool AlwaysTrue();\n\n// Always returns false.\ninline bool AlwaysFalse() { return !AlwaysTrue(); }\n\n// Helper for suppressing false warning from Clang on a const char*\n// variable declared in a conditional expression always being NULL in\n// the else branch.\nstruct GTEST_API_ ConstCharPtr {\n  ConstCharPtr(const char* str) : value(str) {}\n  operator bool() const { return true; }\n  const char* value;\n};\n\n// Helper for declaring std::string within 'if' statement\n// in pre C++17 build environment.\nstruct TrueWithString {\n  TrueWithString() = default;\n  explicit TrueWithString(const char* str) : value(str) {}\n  explicit TrueWithString(const std::string& str) : value(str) {}\n  explicit operator bool() const { return true; }\n  std::string value;\n};\n\n// A simple Linear Congruential Generator for generating random\n// numbers with a uniform distribution.  Unlike rand() and srand(), it\n// doesn't use global state (and therefore can't interfere with user\n// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,\n// but it's good enough for our purposes.\nclass GTEST_API_ Random {\n public:\n  static const uint32_t kMaxRange = 1u << 31;\n\n  explicit Random(uint32_t seed) : state_(seed) {}\n\n  void Reseed(uint32_t seed) { state_ = seed; }\n\n  // Generates a random number from [0, range).  Crashes if 'range' is\n  // 0 or greater than kMaxRange.\n  uint32_t Generate(uint32_t range);\n\n private:\n  uint32_t state_;\n  Random(const Random&) = delete;\n  Random& operator=(const Random&) = delete;\n};\n\n// Turns const U&, U&, const U, and U all into U.\n#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \\\n  typename std::remove_const<typename std::remove_reference<T>::type>::type\n\n// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant\n// that's true if and only if T has methods DebugString() and ShortDebugString()\n// that return std::string.\ntemplate <typename T>\nclass HasDebugStringAndShortDebugString {\n private:\n  template <typename C>\n  static auto CheckDebugString(C*) -> typename std::is_same<\n      std::string, decltype(std::declval<const C>().DebugString())>::type;\n  template <typename>\n  static std::false_type CheckDebugString(...);\n\n  template <typename C>\n  static auto CheckShortDebugString(C*) -> typename std::is_same<\n      std::string, decltype(std::declval<const C>().ShortDebugString())>::type;\n  template <typename>\n  static std::false_type CheckShortDebugString(...);\n\n  using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));\n  using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));\n\n public:\n  static constexpr bool value =\n      HasDebugStringType::value && HasShortDebugStringType::value;\n};\n\n#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL\ntemplate <typename T>\nconstexpr bool HasDebugStringAndShortDebugString<T>::value;\n#endif\n\n// When the compiler sees expression IsContainerTest<C>(0), if C is an\n// STL-style container class, the first overload of IsContainerTest\n// will be viable (since both C::iterator* and C::const_iterator* are\n// valid types and NULL can be implicitly converted to them).  It will\n// be picked over the second overload as 'int' is a perfect match for\n// the type of argument 0.  If C::iterator or C::const_iterator is not\n// a valid type, the first overload is not viable, and the second\n// overload will be picked.  Therefore, we can determine whether C is\n// a container class by checking the type of IsContainerTest<C>(0).\n// The value of the expression is insignificant.\n//\n// In C++11 mode we check the existence of a const_iterator and that an\n// iterator is properly implemented for the container.\n//\n// For pre-C++11 that we look for both C::iterator and C::const_iterator.\n// The reason is that C++ injects the name of a class as a member of the\n// class itself (e.g. you can refer to class iterator as either\n// 'iterator' or 'iterator::iterator').  If we look for C::iterator\n// only, for example, we would mistakenly think that a class named\n// iterator is an STL container.\n//\n// Also note that the simpler approach of overloading\n// IsContainerTest(typename C::const_iterator*) and\n// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.\ntypedef int IsContainer;\ntemplate <class C,\n          class Iterator = decltype(::std::declval<const C&>().begin()),\n          class = decltype(::std::declval<const C&>().end()),\n          class = decltype(++::std::declval<Iterator&>()),\n          class = decltype(*::std::declval<Iterator>()),\n          class = typename C::const_iterator>\nIsContainer IsContainerTest(int /* dummy */) {\n  return 0;\n}\n\ntypedef char IsNotContainer;\ntemplate <class C>\nIsNotContainer IsContainerTest(long /* dummy */) {\n  return '\\0';\n}\n\n// Trait to detect whether a type T is a hash table.\n// The heuristic used is that the type contains an inner type `hasher` and does\n// not contain an inner type `reverse_iterator`.\n// If the container is iterable in reverse, then order might actually matter.\ntemplate <typename T>\nstruct IsHashTable {\n private:\n  template <typename U>\n  static char test(typename U::hasher*, typename U::reverse_iterator*);\n  template <typename U>\n  static int test(typename U::hasher*, ...);\n  template <typename U>\n  static char test(...);\n\n public:\n  static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);\n};\n\ntemplate <typename T>\nconst bool IsHashTable<T>::value;\n\ntemplate <typename C,\n          bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>\nstruct IsRecursiveContainerImpl;\n\ntemplate <typename C>\nstruct IsRecursiveContainerImpl<C, false> : public std::false_type {};\n\n// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to\n// obey the same inconsistencies as the IsContainerTest, namely check if\n// something is a container is relying on only const_iterator in C++11 and\n// is relying on both const_iterator and iterator otherwise\ntemplate <typename C>\nstruct IsRecursiveContainerImpl<C, true> {\n  using value_type = decltype(*std::declval<typename C::const_iterator>());\n  using type =\n      std::is_same<typename std::remove_const<\n                       typename std::remove_reference<value_type>::type>::type,\n                   C>;\n};\n\n// IsRecursiveContainer<Type> is a unary compile-time predicate that\n// evaluates whether C is a recursive container type. A recursive container\n// type is a container type whose value_type is equal to the container type\n// itself. An example for a recursive container type is\n// boost::filesystem::path, whose iterator has a value_type that is equal to\n// boost::filesystem::path.\ntemplate <typename C>\nstruct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};\n\n// Utilities for native arrays.\n\n// ArrayEq() compares two k-dimensional native arrays using the\n// elements' operator==, where k can be any integer >= 0.  When k is\n// 0, ArrayEq() degenerates into comparing a single pair of values.\n\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline bool ArrayEq(const T& lhs, const U& rhs) {\n  return lhs == rhs;\n}\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {\n  return internal::ArrayEq(lhs, N, rhs);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous ArrayEq() function, arrays with different sizes would\n// lead to different copies of the template code.\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs) {\n  for (size_t i = 0; i != size; i++) {\n    if (!internal::ArrayEq(lhs[i], rhs[i])) return false;\n  }\n  return true;\n}\n\n// Finds the first element in the iterator range [begin, end) that\n// equals elem.  Element may be a native array type itself.\ntemplate <typename Iter, typename Element>\nIter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {\n  for (Iter it = begin; it != end; ++it) {\n    if (internal::ArrayEq(*it, elem)) return it;\n  }\n  return end;\n}\n\n// CopyArray() copies a k-dimensional native array using the elements'\n// operator=, where k can be any integer >= 0.  When k is 0,\n// CopyArray() degenerates into copying a single value.\n\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline void CopyArray(const T& from, U* to) {\n  *to = from;\n}\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline void CopyArray(const T (&from)[N], U (*to)[N]) {\n  internal::CopyArray(from, N, *to);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous CopyArray() function, arrays with different sizes\n// would lead to different copies of the template code.\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to) {\n  for (size_t i = 0; i != size; i++) {\n    internal::CopyArray(from[i], to + i);\n  }\n}\n\n// The relation between an NativeArray object (see below) and the\n// native array it represents.\n// We use 2 different structs to allow non-copyable types to be used, as long\n// as RelationToSourceReference() is passed.\nstruct RelationToSourceReference {};\nstruct RelationToSourceCopy {};\n\n// Adapts a native array to a read-only STL-style container.  Instead\n// of the complete STL container concept, this adaptor only implements\n// members useful for Google Mock's container matchers.  New members\n// should be added as needed.  To simplify the implementation, we only\n// support Element being a raw type (i.e. having no top-level const or\n// reference modifier).  It's the client's responsibility to satisfy\n// this requirement.  Element can be an array type itself (hence\n// multi-dimensional arrays are supported).\ntemplate <typename Element>\nclass NativeArray {\n public:\n  // STL-style container typedefs.\n  typedef Element value_type;\n  typedef Element* iterator;\n  typedef const Element* const_iterator;\n\n  // Constructs from a native array. References the source.\n  NativeArray(const Element* array, size_t count, RelationToSourceReference) {\n    InitRef(array, count);\n  }\n\n  // Constructs from a native array. Copies the source.\n  NativeArray(const Element* array, size_t count, RelationToSourceCopy) {\n    InitCopy(array, count);\n  }\n\n  // Copy constructor.\n  NativeArray(const NativeArray& rhs) {\n    (this->*rhs.clone_)(rhs.array_, rhs.size_);\n  }\n\n  ~NativeArray() {\n    if (clone_ != &NativeArray::InitRef) delete[] array_;\n  }\n\n  // STL-style container methods.\n  size_t size() const { return size_; }\n  const_iterator begin() const { return array_; }\n  const_iterator end() const { return array_ + size_; }\n  bool operator==(const NativeArray& rhs) const {\n    return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());\n  }\n\n private:\n  static_assert(!std::is_const<Element>::value, \"Type must not be const\");\n  static_assert(!std::is_reference<Element>::value,\n                \"Type must not be a reference\");\n\n  // Initializes this object with a copy of the input.\n  void InitCopy(const Element* array, size_t a_size) {\n    Element* const copy = new Element[a_size];\n    CopyArray(array, a_size, copy);\n    array_ = copy;\n    size_ = a_size;\n    clone_ = &NativeArray::InitCopy;\n  }\n\n  // Initializes this object with a reference of the input.\n  void InitRef(const Element* array, size_t a_size) {\n    array_ = array;\n    size_ = a_size;\n    clone_ = &NativeArray::InitRef;\n  }\n\n  const Element* array_;\n  size_t size_;\n  void (NativeArray::*clone_)(const Element*, size_t);\n};\n\ntemplate <size_t>\nstruct Ignore {\n  Ignore(...);  // NOLINT\n};\n\ntemplate <typename>\nstruct ElemFromListImpl;\ntemplate <size_t... I>\nstruct ElemFromListImpl<std::index_sequence<I...>> {\n  // We make Ignore a template to solve a problem with MSVC.\n  // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but\n  // MSVC doesn't understand how to deal with that pack expansion.\n  // Use `0 * I` to have a single instantiation of Ignore.\n  template <typename R>\n  static R Apply(Ignore<0 * I>..., R (*)(), ...);\n};\n\ntemplate <size_t N, typename... T>\nstruct ElemFromList {\n  using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(\n      static_cast<T (*)()>(nullptr)...));\n};\n\nstruct FlatTupleConstructTag {};\n\ntemplate <typename... T>\nclass FlatTuple;\n\ntemplate <typename Derived, size_t I>\nstruct FlatTupleElemBase;\n\ntemplate <typename... T, size_t I>\nstruct FlatTupleElemBase<FlatTuple<T...>, I> {\n  using value_type = typename ElemFromList<I, T...>::type;\n  FlatTupleElemBase() = default;\n  template <typename Arg>\n  explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)\n      : value(std::forward<Arg>(t)) {}\n  value_type value;\n};\n\ntemplate <typename Derived, typename Idx>\nstruct FlatTupleBase;\n\ntemplate <size_t... Idx, typename... T>\nstruct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>\n    : FlatTupleElemBase<FlatTuple<T...>, Idx>... {\n  using Indices = std::index_sequence<Idx...>;\n  FlatTupleBase() = default;\n  template <typename... Args>\n  explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)\n      : FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},\n                                                std::forward<Args>(args))... {}\n\n  template <size_t I>\n  const typename ElemFromList<I, T...>::type& Get() const {\n    return FlatTupleElemBase<FlatTuple<T...>, I>::value;\n  }\n\n  template <size_t I>\n  typename ElemFromList<I, T...>::type& Get() {\n    return FlatTupleElemBase<FlatTuple<T...>, I>::value;\n  }\n\n  template <typename F>\n  auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {\n    return std::forward<F>(f)(Get<Idx>()...);\n  }\n\n  template <typename F>\n  auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {\n    return std::forward<F>(f)(Get<Idx>()...);\n  }\n};\n\n// Analog to std::tuple but with different tradeoffs.\n// This class minimizes the template instantiation depth, thus allowing more\n// elements than std::tuple would. std::tuple has been seen to require an\n// instantiation depth of more than 10x the number of elements in some\n// implementations.\n// FlatTuple and ElemFromList are not recursive and have a fixed depth\n// regardless of T...\n// std::make_index_sequence, on the other hand, it is recursive but with an\n// instantiation depth of O(ln(N)).\ntemplate <typename... T>\nclass FlatTuple\n    : private FlatTupleBase<FlatTuple<T...>,\n                            std::make_index_sequence<sizeof...(T)>> {\n  using Indices =\n      typename FlatTupleBase<FlatTuple<T...>,\n                             std::make_index_sequence<sizeof...(T)>>::Indices;\n\n public:\n  FlatTuple() = default;\n  template <typename... Args>\n  explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)\n      : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}\n\n  using FlatTuple::FlatTupleBase::Apply;\n  using FlatTuple::FlatTupleBase::Get;\n};\n\n// Utility functions to be called with static_assert to induce deprecation\n// warnings.\nGTEST_INTERNAL_DEPRECATED(\n    \"INSTANTIATE_TEST_CASE_P is deprecated, please use \"\n    \"INSTANTIATE_TEST_SUITE_P\")\nconstexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"TYPED_TEST_CASE_P is deprecated, please use \"\n    \"TYPED_TEST_SUITE_P\")\nconstexpr bool TypedTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"TYPED_TEST_CASE is deprecated, please use \"\n    \"TYPED_TEST_SUITE\")\nconstexpr bool TypedTestCaseIsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"REGISTER_TYPED_TEST_CASE_P is deprecated, please use \"\n    \"REGISTER_TYPED_TEST_SUITE_P\")\nconstexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use \"\n    \"INSTANTIATE_TYPED_TEST_SUITE_P\")\nconstexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }\n\n}  // namespace internal\n}  // namespace testing\n\nnamespace std {\n// Some standard library implementations use `struct tuple_size` and some use\n// `class tuple_size`. Clang warns about the mismatch.\n// https://reviews.llvm.org/D55466\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmismatched-tags\"\n#endif\ntemplate <typename... Ts>\nstruct tuple_size<testing::internal::FlatTuple<Ts...>>\n    : std::integral_constant<size_t, sizeof...(Ts)> {};\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n}  // namespace std\n\n#define GTEST_MESSAGE_AT_(file, line, message, result_type)             \\\n  ::testing::internal::AssertHelper(result_type, file, line, message) = \\\n      ::testing::Message()\n\n#define GTEST_MESSAGE_(message, result_type) \\\n  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)\n\n#define GTEST_FATAL_FAILURE_(message) \\\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)\n\n#define GTEST_NONFATAL_FAILURE_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)\n\n#define GTEST_SUCCESS_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)\n\n#define GTEST_SKIP_(message) \\\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)\n\n// Suppress MSVC warning 4072 (unreachable code) for the code following\n// statement if it returns or throws (or doesn't return or throw in some\n// situations).\n// NOTE: The \"else\" is important to keep this expansion to prevent a top-level\n// \"else\" from attaching to our \"if\".\n#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \\\n  if (::testing::internal::AlwaysTrue()) {                        \\\n    statement;                                                    \\\n  } else                     /* NOLINT */                         \\\n    static_assert(true, \"\")  // User must have a semicolon after expansion.\n\n#if GTEST_HAS_EXCEPTIONS\n\nnamespace testing {\nnamespace internal {\n\nclass NeverThrown {\n public:\n  const char* what() const noexcept {\n    return \"this exception should never be thrown\";\n  }\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#if GTEST_HAS_RTTI\n\n#define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))\n\n#else  // GTEST_HAS_RTTI\n\n#define GTEST_EXCEPTION_TYPE_(e) \\\n  std::string { \"an std::exception-derived error\" }\n\n#endif  // GTEST_HAS_RTTI\n\n#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)   \\\n  catch (typename std::conditional<                                            \\\n         std::is_same<typename std::remove_cv<typename std::remove_reference<  \\\n                          expected_exception>::type>::type,                    \\\n                      std::exception>::value,                                  \\\n         const ::testing::internal::NeverThrown&, const std::exception&>::type \\\n             e) {                                                              \\\n    gtest_msg.value = \"Expected: \" #statement                                  \\\n                      \" throws an exception of type \" #expected_exception      \\\n                      \".\\n  Actual: it throws \";                               \\\n    gtest_msg.value += GTEST_EXCEPTION_TYPE_(e);                               \\\n    gtest_msg.value += \" with description \\\"\";                                 \\\n    gtest_msg.value += e.what();                                               \\\n    gtest_msg.value += \"\\\".\";                                                  \\\n    goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);                \\\n  }\n\n#else  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_THROW_(statement, expected_exception, fail)              \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                             \\\n  if (::testing::internal::TrueWithString gtest_msg{}) {                    \\\n    bool gtest_caught_expected = false;                                     \\\n    try {                                                                   \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);            \\\n    } catch (expected_exception const&) {                                   \\\n      gtest_caught_expected = true;                                         \\\n    }                                                                       \\\n    GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)    \\\n    catch (...) {                                                           \\\n      gtest_msg.value = \"Expected: \" #statement                             \\\n                        \" throws an exception of type \" #expected_exception \\\n                        \".\\n  Actual: it throws a different type.\";         \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \\\n    }                                                                       \\\n    if (!gtest_caught_expected) {                                           \\\n      gtest_msg.value = \"Expected: \" #statement                             \\\n                        \" throws an exception of type \" #expected_exception \\\n                        \".\\n  Actual: it throws nothing.\";                  \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \\\n    }                                                                       \\\n  } else /*NOLINT*/                                                         \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__)                   \\\n        : fail(gtest_msg.value.c_str())\n\n#if GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()                \\\n  catch (std::exception const& e) {                               \\\n    gtest_msg.value = \"it throws \";                               \\\n    gtest_msg.value += GTEST_EXCEPTION_TYPE_(e);                  \\\n    gtest_msg.value += \" with description \\\"\";                    \\\n    gtest_msg.value += e.what();                                  \\\n    gtest_msg.value += \"\\\".\";                                     \\\n    goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \\\n  }\n\n#else  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_(statement, fail)                            \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                          \\\n  if (::testing::internal::TrueWithString gtest_msg{}) {                 \\\n    try {                                                                \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);         \\\n    }                                                                    \\\n    GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()                           \\\n    catch (...) {                                                        \\\n      gtest_msg.value = \"it throws.\";                                    \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__);      \\\n    }                                                                    \\\n  } else                                                                 \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__)              \\\n        : fail((\"Expected: \" #statement \" doesn't throw an exception.\\n\" \\\n                \"  Actual: \" +                                           \\\n                gtest_msg.value)                                         \\\n                   .c_str())\n\n#define GTEST_TEST_ANY_THROW_(statement, fail)                       \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                      \\\n  if (::testing::internal::AlwaysTrue()) {                           \\\n    bool gtest_caught_any = false;                                   \\\n    try {                                                            \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);     \\\n    } catch (...) {                                                  \\\n      gtest_caught_any = true;                                       \\\n    }                                                                \\\n    if (!gtest_caught_any) {                                         \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \\\n    }                                                                \\\n  } else                                                             \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__)         \\\n        : fail(\"Expected: \" #statement                               \\\n               \" throws an exception.\\n\"                             \\\n               \"  Actual: it doesn't.\")\n\n// Implements Boolean test assertions such as EXPECT_TRUE. expression can be\n// either a boolean expression or an AssertionResult. text is a textual\n// representation of expression as it was passed into the EXPECT_TRUE.\n#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                       \\\n  if (const ::testing::AssertionResult gtest_ar_ =                    \\\n          ::testing::AssertionResult(expression))                     \\\n    ;                                                                 \\\n  else                                                                \\\n    fail(::testing::internal::GetBoolAssertionFailureMessage(         \\\n             gtest_ar_, text, #actual, #expected)                     \\\n             .c_str())\n\n#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail)               \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                     \\\n  if (::testing::internal::AlwaysTrue()) {                          \\\n    const ::testing::internal::HasNewFatalFailureHelper             \\\n        gtest_fatal_failure_checker;                                \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);      \\\n    if (gtest_fatal_failure_checker.has_new_fatal_failure()) {      \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \\\n    }                                                               \\\n  } else /* NOLINT */                                               \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__)         \\\n        : fail(\"Expected: \" #statement                              \\\n               \" doesn't generate new fatal \"                       \\\n               \"failures in the current thread.\\n\"                  \\\n               \"  Actual: it does.\")\n\n// Expands to the name of the class that implements the given test.\n#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \\\n  test_suite_name##_##test_name##_Test\n\n// Helper macro for defining tests.\n#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id)       \\\n  static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1,                 \\\n                \"test_suite_name must not be empty\");                          \\\n  static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1,                       \\\n                \"test_name must not be empty\");                                \\\n  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \\\n      : public parent_class {                                                  \\\n   public:                                                                     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default;            \\\n    ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default;  \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                         \\\n    (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete;     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=(            \\\n        const GTEST_TEST_CLASS_NAME_(test_suite_name,                          \\\n                                     test_name) &) = delete; /* NOLINT */      \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                         \\\n    (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=(            \\\n        GTEST_TEST_CLASS_NAME_(test_suite_name,                                \\\n                               test_name) &&) noexcept = delete; /* NOLINT */  \\\n                                                                               \\\n   private:                                                                    \\\n    void TestBody() override;                                                  \\\n    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const    \\\n        test_info_;                                                            \\\n  };                                                                           \\\n                                                                               \\\n  ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,           \\\n                                                    test_name)::test_info_ =   \\\n      ::testing::internal::MakeAndRegisterTestInfo(                            \\\n          #test_suite_name, #test_name, nullptr, nullptr,                      \\\n          ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id),  \\\n          ::testing::internal::SuiteApiResolver<                               \\\n              parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__),          \\\n          ::testing::internal::SuiteApiResolver<                               \\\n              parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__),       \\\n          new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_(     \\\n              test_suite_name, test_name)>);                                   \\\n  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-param-util.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Type and function utilities for implementing parameterized tests.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n\n#include <ctype.h>\n\n#include <cassert>\n#include <iterator>\n#include <map>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-printers.h\"\n#include \"gtest/gtest-test-part.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n// Input to a parameterized test name generator, describing a test parameter.\n// Consists of the parameter value and the integer parameter index.\ntemplate <class ParamType>\nstruct TestParamInfo {\n  TestParamInfo(const ParamType& a_param, size_t an_index)\n      : param(a_param), index(an_index) {}\n  ParamType param;\n  size_t index;\n};\n\n// A builtin parameterized test name generator which returns the result of\n// testing::PrintToString.\nstruct PrintToStringParamName {\n  template <class ParamType>\n  std::string operator()(const TestParamInfo<ParamType>& info) const {\n    return PrintToString(info.param);\n  }\n};\n\nnamespace internal {\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n// Utility Functions\n\n// Outputs a message explaining invalid registration of different\n// fixture class for the same test suite. This may happen when\n// TEST_P macro is used to define two tests with the same name\n// but in different namespaces.\nGTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,\n                                           const CodeLocation& code_location);\n\ntemplate <typename>\nclass ParamGeneratorInterface;\ntemplate <typename>\nclass ParamGenerator;\n\n// Interface for iterating over elements provided by an implementation\n// of ParamGeneratorInterface<T>.\ntemplate <typename T>\nclass ParamIteratorInterface {\n public:\n  virtual ~ParamIteratorInterface() = default;\n  // A pointer to the base generator instance.\n  // Used only for the purposes of iterator comparison\n  // to make sure that two iterators belong to the same generator.\n  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;\n  // Advances iterator to point to the next element\n  // provided by the generator. The caller is responsible\n  // for not calling Advance() on an iterator equal to\n  // BaseGenerator()->End().\n  virtual void Advance() = 0;\n  // Clones the iterator object. Used for implementing copy semantics\n  // of ParamIterator<T>.\n  virtual ParamIteratorInterface* Clone() const = 0;\n  // Dereferences the current iterator and provides (read-only) access\n  // to the pointed value. It is the caller's responsibility not to call\n  // Current() on an iterator equal to BaseGenerator()->End().\n  // Used for implementing ParamGenerator<T>::operator*().\n  virtual const T* Current() const = 0;\n  // Determines whether the given iterator and other point to the same\n  // element in the sequence generated by the generator.\n  // Used for implementing ParamGenerator<T>::operator==().\n  virtual bool Equals(const ParamIteratorInterface& other) const = 0;\n};\n\n// Class iterating over elements provided by an implementation of\n// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>\n// and implements the const forward iterator concept.\ntemplate <typename T>\nclass ParamIterator {\n public:\n  typedef T value_type;\n  typedef const T& reference;\n  typedef ptrdiff_t difference_type;\n\n  // ParamIterator assumes ownership of the impl_ pointer.\n  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}\n  ParamIterator& operator=(const ParamIterator& other) {\n    if (this != &other) impl_.reset(other.impl_->Clone());\n    return *this;\n  }\n\n  const T& operator*() const { return *impl_->Current(); }\n  const T* operator->() const { return impl_->Current(); }\n  // Prefix version of operator++.\n  ParamIterator& operator++() {\n    impl_->Advance();\n    return *this;\n  }\n  // Postfix version of operator++.\n  ParamIterator operator++(int /*unused*/) {\n    ParamIteratorInterface<T>* clone = impl_->Clone();\n    impl_->Advance();\n    return ParamIterator(clone);\n  }\n  bool operator==(const ParamIterator& other) const {\n    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);\n  }\n  bool operator!=(const ParamIterator& other) const {\n    return !(*this == other);\n  }\n\n private:\n  friend class ParamGenerator<T>;\n  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}\n  std::unique_ptr<ParamIteratorInterface<T>> impl_;\n};\n\n// ParamGeneratorInterface<T> is the binary interface to access generators\n// defined in other translation units.\ntemplate <typename T>\nclass ParamGeneratorInterface {\n public:\n  typedef T ParamType;\n\n  virtual ~ParamGeneratorInterface() = default;\n\n  // Generator interface definition\n  virtual ParamIteratorInterface<T>* Begin() const = 0;\n  virtual ParamIteratorInterface<T>* End() const = 0;\n};\n\n// Wraps ParamGeneratorInterface<T> and provides general generator syntax\n// compatible with the STL Container concept.\n// This class implements copy initialization semantics and the contained\n// ParamGeneratorInterface<T> instance is shared among all copies\n// of the original object. This is possible because that instance is immutable.\ntemplate <typename T>\nclass ParamGenerator {\n public:\n  typedef ParamIterator<T> iterator;\n\n  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}\n  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}\n\n  ParamGenerator& operator=(const ParamGenerator& other) {\n    impl_ = other.impl_;\n    return *this;\n  }\n\n  iterator begin() const { return iterator(impl_->Begin()); }\n  iterator end() const { return iterator(impl_->End()); }\n\n private:\n  std::shared_ptr<const ParamGeneratorInterface<T>> impl_;\n};\n\n// Generates values from a range of two comparable values. Can be used to\n// generate sequences of user-defined types that implement operator+() and\n// operator<().\n// This class is used in the Range() function.\ntemplate <typename T, typename IncrementT>\nclass RangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  RangeGenerator(T begin, T end, IncrementT step)\n      : begin_(begin),\n        end_(end),\n        step_(step),\n        end_index_(CalculateEndIndex(begin, end, step)) {}\n  ~RangeGenerator() override = default;\n\n  ParamIteratorInterface<T>* Begin() const override {\n    return new Iterator(this, begin_, 0, step_);\n  }\n  ParamIteratorInterface<T>* End() const override {\n    return new Iterator(this, end_, end_index_, step_);\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,\n             IncrementT step)\n        : base_(base), value_(value), index_(index), step_(step) {}\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<T>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      value_ = static_cast<T>(value_ + step_);\n      index_++;\n    }\n    ParamIteratorInterface<T>* Clone() const override {\n      return new Iterator(*this);\n    }\n    const T* Current() const override { return &value_; }\n    bool Equals(const ParamIteratorInterface<T>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const int other_index =\n          CheckedDowncastToActualType<const Iterator>(&other)->index_;\n      return index_ == other_index;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : ParamIteratorInterface<T>(),\n          base_(other.base_),\n          value_(other.value_),\n          index_(other.index_),\n          step_(other.step_) {}\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<T>* const base_;\n    T value_;\n    int index_;\n    const IncrementT step_;\n  };  // class RangeGenerator::Iterator\n\n  static int CalculateEndIndex(const T& begin, const T& end,\n                               const IncrementT& step) {\n    int end_index = 0;\n    for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;\n    return end_index;\n  }\n\n  // No implementation - assignment is unsupported.\n  void operator=(const RangeGenerator& other);\n\n  const T begin_;\n  const T end_;\n  const IncrementT step_;\n  // The index for the end() iterator. All the elements in the generated\n  // sequence are indexed (0-based) to aid iterator comparison.\n  const int end_index_;\n};  // class RangeGenerator\n\n// Generates values from a pair of STL-style iterators. Used in the\n// ValuesIn() function. The elements are copied from the source range\n// since the source can be located on the stack, and the generator\n// is likely to persist beyond that stack frame.\ntemplate <typename T>\nclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  template <typename ForwardIterator>\n  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)\n      : container_(begin, end) {}\n  ~ValuesInIteratorRangeGenerator() override = default;\n\n  ParamIteratorInterface<T>* Begin() const override {\n    return new Iterator(this, container_.begin());\n  }\n  ParamIteratorInterface<T>* End() const override {\n    return new Iterator(this, container_.end());\n  }\n\n private:\n  typedef typename ::std::vector<T> ContainerType;\n\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base,\n             typename ContainerType::const_iterator iterator)\n        : base_(base), iterator_(iterator) {}\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<T>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      ++iterator_;\n      value_.reset();\n    }\n    ParamIteratorInterface<T>* Clone() const override {\n      return new Iterator(*this);\n    }\n    // We need to use cached value referenced by iterator_ because *iterator_\n    // can return a temporary object (and of type other then T), so just\n    // having \"return &*iterator_;\" doesn't work.\n    // value_ is updated here and not in Advance() because Advance()\n    // can advance iterator_ beyond the end of the range, and we cannot\n    // detect that fact. The client code, on the other hand, is\n    // responsible for not calling Current() on an out-of-range iterator.\n    const T* Current() const override {\n      if (value_.get() == nullptr) value_.reset(new T(*iterator_));\n      return value_.get();\n    }\n    bool Equals(const ParamIteratorInterface<T>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      return iterator_ ==\n             CheckedDowncastToActualType<const Iterator>(&other)->iterator_;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        // The explicit constructor call suppresses a false warning\n        // emitted by gcc when supplied with the -Wextra option.\n        : ParamIteratorInterface<T>(),\n          base_(other.base_),\n          iterator_(other.iterator_) {}\n\n    const ParamGeneratorInterface<T>* const base_;\n    typename ContainerType::const_iterator iterator_;\n    // A cached value of *iterator_. We keep it here to allow access by\n    // pointer in the wrapping iterator's operator->().\n    // value_ needs to be mutable to be accessed in Current().\n    // Use of std::unique_ptr helps manage cached value's lifetime,\n    // which is bound by the lifespan of the iterator itself.\n    mutable std::unique_ptr<const T> value_;\n  };  // class ValuesInIteratorRangeGenerator::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const ValuesInIteratorRangeGenerator& other);\n\n  const ContainerType container_;\n};  // class ValuesInIteratorRangeGenerator\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Default parameterized test name generator, returns a string containing the\n// integer test parameter index.\ntemplate <class ParamType>\nstd::string DefaultParamName(const TestParamInfo<ParamType>& info) {\n  return std::to_string(info.index);\n}\n\ntemplate <typename T = int>\nvoid TestNotEmpty() {\n  static_assert(sizeof(T) == 0, \"Empty arguments are not allowed.\");\n}\ntemplate <typename T = int>\nvoid TestNotEmpty(const T&) {}\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Stores a parameter value and later creates tests parameterized with that\n// value.\ntemplate <class TestClass>\nclass ParameterizedTestFactory : public TestFactoryBase {\n public:\n  typedef typename TestClass::ParamType ParamType;\n  explicit ParameterizedTestFactory(ParamType parameter)\n      : parameter_(parameter) {}\n  Test* CreateTest() override {\n    TestClass::SetParam(&parameter_);\n    return new TestClass();\n  }\n\n private:\n  const ParamType parameter_;\n\n  ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;\n  ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactoryBase is a base class for meta-factories that create\n// test factories for passing into MakeAndRegisterTestInfo function.\ntemplate <class ParamType>\nclass TestMetaFactoryBase {\n public:\n  virtual ~TestMetaFactoryBase() = default;\n\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactory creates test factories for passing into\n// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives\n// ownership of test factory pointer, same factory object cannot be passed\n// into that method twice. But ParameterizedTestSuiteInfo is going to call\n// it for each Test/Parameter value combination. Thus it needs meta factory\n// creator class.\ntemplate <class TestSuite>\nclass TestMetaFactory\n    : public TestMetaFactoryBase<typename TestSuite::ParamType> {\n public:\n  using ParamType = typename TestSuite::ParamType;\n\n  TestMetaFactory() = default;\n\n  TestFactoryBase* CreateTestFactory(ParamType parameter) override {\n    return new ParameterizedTestFactory<TestSuite>(parameter);\n  }\n\n private:\n  TestMetaFactory(const TestMetaFactory&) = delete;\n  TestMetaFactory& operator=(const TestMetaFactory&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteInfoBase is a generic interface\n// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase\n// accumulates test information provided by TEST_P macro invocations\n// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations\n// and uses that information to register all resulting test instances\n// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds\n// a collection of pointers to the ParameterizedTestSuiteInfo objects\n// and calls RegisterTests() on each of them when asked.\nclass ParameterizedTestSuiteInfoBase {\n public:\n  virtual ~ParameterizedTestSuiteInfoBase() = default;\n\n  // Base part of test suite name for display purposes.\n  virtual const std::string& GetTestSuiteName() const = 0;\n  // Test suite id to verify identity.\n  virtual TypeId GetTestSuiteTypeId() const = 0;\n  // UnitTest class invokes this method to register tests in this\n  // test suite right before running them in RUN_ALL_TESTS macro.\n  // This method should not be called more than once on any single\n  // instance of a ParameterizedTestSuiteInfoBase derived class.\n  virtual void RegisterTests() = 0;\n\n protected:\n  ParameterizedTestSuiteInfoBase() {}\n\n private:\n  ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =\n      delete;\n  ParameterizedTestSuiteInfoBase& operator=(\n      const ParameterizedTestSuiteInfoBase&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Report a the name of a test_suit as safe to ignore\n// as the side effect of construction of this type.\nstruct GTEST_API_ MarkAsIgnored {\n  explicit MarkAsIgnored(const char* test_suite);\n};\n\nGTEST_API_ void InsertSyntheticTestCase(const std::string& name,\n                                        CodeLocation location, bool has_test_p);\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P\n// macro invocations for a particular test suite and generators\n// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that\n// test suite. It registers tests with all values generated by all\n// generators when asked.\ntemplate <class TestSuite>\nclass ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {\n public:\n  // ParamType and GeneratorCreationFunc are private types but are required\n  // for declarations of public methods AddTestPattern() and\n  // AddTestSuiteInstantiation().\n  using ParamType = typename TestSuite::ParamType;\n  // A function that returns an instance of appropriate generator type.\n  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();\n  using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);\n\n  explicit ParameterizedTestSuiteInfo(std::string name,\n                                      CodeLocation code_location)\n      : test_suite_name_(std::move(name)),\n        code_location_(std::move(code_location)) {}\n\n  // Test suite base name for display purposes.\n  const std::string& GetTestSuiteName() const override {\n    return test_suite_name_;\n  }\n  // Test suite id to verify identity.\n  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }\n  // TEST_P macro uses AddTestPattern() to record information\n  // about a single test in a LocalTestInfo structure.\n  // test_suite_name is the base name of the test suite (without invocation\n  // prefix). test_base_name is the name of an individual test without\n  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is\n  // test suite base name and DoBar is test base name.\n  void AddTestPattern(const char*,\n                      const char* test_base_name,\n                      TestMetaFactoryBase<ParamType>* meta_factory,\n                      CodeLocation code_location) {\n    tests_.emplace_back(\n        new TestInfo(test_base_name, meta_factory, std::move(code_location)));\n  }\n  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information\n  // about a generator.\n  int AddTestSuiteInstantiation(std::string instantiation_name,\n                                GeneratorCreationFunc* func,\n                                ParamNameGeneratorFunc* name_func,\n                                const char* file, int line) {\n    instantiations_.emplace_back(std::move(instantiation_name), func, name_func,\n                                 file, line);\n    return 0;  // Return value used only to run this method in namespace scope.\n  }\n  // UnitTest class invokes this method to register tests in this test suite\n  // right before running tests in RUN_ALL_TESTS macro.\n  // This method should not be called more than once on any single\n  // instance of a ParameterizedTestSuiteInfoBase derived class.\n  // UnitTest has a guard to prevent from calling this method more than once.\n  void RegisterTests() override {\n    bool generated_instantiations = false;\n\n    std::string test_suite_name;\n    std::string test_name;\n    for (const std::shared_ptr<TestInfo>& test_info : tests_) {\n      for (const InstantiationInfo& instantiation : instantiations_) {\n        const std::string& instantiation_name = instantiation.name;\n        ParamGenerator<ParamType> generator((*instantiation.generator)());\n        ParamNameGeneratorFunc* name_func = instantiation.name_func;\n        const char* file = instantiation.file;\n        int line = instantiation.line;\n\n        if (!instantiation_name.empty())\n          test_suite_name = instantiation_name + \"/\";\n        else\n          test_suite_name.clear();\n        test_suite_name += test_suite_name_;\n\n        size_t i = 0;\n        std::set<std::string> test_param_names;\n        for (const auto& param : generator) {\n          generated_instantiations = true;\n\n          test_name.clear();\n\n          std::string param_name =\n              name_func(TestParamInfo<ParamType>(param, i));\n\n          GTEST_CHECK_(IsValidParamName(param_name))\n              << \"Parameterized test name '\" << param_name\n              << \"' is invalid (contains spaces, dashes, or any \"\n                 \"non-alphanumeric characters other than underscores), in \"\n              << file << \" line \" << line << \"\" << std::endl;\n\n          GTEST_CHECK_(test_param_names.count(param_name) == 0)\n              << \"Duplicate parameterized test name '\" << param_name << \"', in \"\n              << file << \" line \" << line << std::endl;\n\n          if (!test_info->test_base_name.empty()) {\n            test_name.append(test_info->test_base_name).append(\"/\");\n          }\n          test_name += param_name;\n\n          test_param_names.insert(std::move(param_name));\n\n          MakeAndRegisterTestInfo(\n              test_suite_name, test_name.c_str(),\n              nullptr,  // No type parameter.\n              PrintToString(param).c_str(), test_info->code_location,\n              GetTestSuiteTypeId(),\n              SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),\n              SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),\n              test_info->test_meta_factory->CreateTestFactory(param));\n          ++i;\n        }  // for param\n      }  // for instantiation\n    }  // for test_info\n\n    if (!generated_instantiations) {\n      // There are no generaotrs, or they all generate nothing ...\n      InsertSyntheticTestCase(GetTestSuiteName(), code_location_,\n                              !tests_.empty());\n    }\n  }  // RegisterTests\n\n private:\n  // LocalTestInfo structure keeps information about a single test registered\n  // with TEST_P macro.\n  struct TestInfo {\n    TestInfo(const char* a_test_base_name,\n             TestMetaFactoryBase<ParamType>* a_test_meta_factory,\n             CodeLocation a_code_location)\n        : test_base_name(a_test_base_name),\n          test_meta_factory(a_test_meta_factory),\n          code_location(std::move(a_code_location)) {}\n\n    const std::string test_base_name;\n    const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;\n    const CodeLocation code_location;\n  };\n  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;\n  // Records data received from INSTANTIATE_TEST_SUITE_P macros:\n  //  <Instantiation name, Sequence generator creation function,\n  //     Name generator function, Source file, Source line>\n  struct InstantiationInfo {\n    InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,\n                      ParamNameGeneratorFunc* name_func_in, const char* file_in,\n                      int line_in)\n        : name(std::move(name_in)),\n          generator(generator_in),\n          name_func(name_func_in),\n          file(file_in),\n          line(line_in) {}\n\n    std::string name;\n    GeneratorCreationFunc* generator;\n    ParamNameGeneratorFunc* name_func;\n    const char* file;\n    int line;\n  };\n  typedef ::std::vector<InstantiationInfo> InstantiationContainer;\n\n  static bool IsValidParamName(const std::string& name) {\n    // Check for empty string\n    if (name.empty()) return false;\n\n    // Check for invalid characters\n    for (std::string::size_type index = 0; index < name.size(); ++index) {\n      if (!IsAlNum(name[index]) && name[index] != '_') return false;\n    }\n\n    return true;\n  }\n\n  const std::string test_suite_name_;\n  CodeLocation code_location_;\n  TestInfoContainer tests_;\n  InstantiationContainer instantiations_;\n\n  ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;\n  ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =\n      delete;\n};  // class ParameterizedTestSuiteInfo\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\ntemplate <class TestCase>\nusing ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteRegistry contains a map of\n// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P\n// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding\n// ParameterizedTestSuiteInfo descriptors.\nclass ParameterizedTestSuiteRegistry {\n public:\n  ParameterizedTestSuiteRegistry() = default;\n  ~ParameterizedTestSuiteRegistry() {\n    for (auto& test_suite_info : test_suite_infos_) {\n      delete test_suite_info;\n    }\n  }\n\n  // Looks up or creates and returns a structure containing information about\n  // tests and instantiations of a particular test suite.\n  template <class TestSuite>\n  ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(\n      std::string test_suite_name, CodeLocation code_location) {\n    ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;\n\n    auto item_it = suite_name_to_info_index_.find(test_suite_name);\n    if (item_it != suite_name_to_info_index_.end()) {\n      auto* test_suite_info = test_suite_infos_[item_it->second];\n      if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {\n        // Complain about incorrect usage of Google Test facilities\n        // and terminate the program since we cannot guaranty correct\n        // test suite setup and tear-down in this case.\n        ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);\n        posix::Abort();\n      } else {\n        // At this point we are sure that the object we found is of the same\n        // type we are looking for, so we downcast it to that type\n        // without further checks.\n        typed_test_info =\n            CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(\n                test_suite_info);\n      }\n    }\n    if (typed_test_info == nullptr) {\n      typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(\n          test_suite_name, std::move(code_location));\n      suite_name_to_info_index_.emplace(std::move(test_suite_name),\n                                        test_suite_infos_.size());\n      test_suite_infos_.push_back(typed_test_info);\n    }\n    return typed_test_info;\n  }\n  void RegisterTests() {\n    for (auto& test_suite_info : test_suite_infos_) {\n      test_suite_info->RegisterTests();\n    }\n  }\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  template <class TestCase>\n  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(\n      std::string test_case_name, CodeLocation code_location) {\n    return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),\n                                               std::move(code_location));\n  }\n\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n private:\n  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;\n\n  TestSuiteInfoContainer test_suite_infos_;\n  ::std::unordered_map<std::string, size_t> suite_name_to_info_index_;\n\n  ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =\n      delete;\n  ParameterizedTestSuiteRegistry& operator=(\n      const ParameterizedTestSuiteRegistry&) = delete;\n};\n\n// Keep track of what type-parameterized test suite are defined and\n// where as well as which are intatiated. This allows susequently\n// identifying suits that are defined but never used.\nclass TypeParameterizedTestSuiteRegistry {\n public:\n  // Add a suite definition\n  void RegisterTestSuite(const char* test_suite_name,\n                         CodeLocation code_location);\n\n  // Add an instantiation of a suit.\n  void RegisterInstantiation(const char* test_suite_name);\n\n  // For each suit repored as defined but not reported as instantiation,\n  // emit a test that reports that fact (configurably, as an error).\n  void CheckForInstantiations();\n\n private:\n  struct TypeParameterizedTestSuiteInfo {\n    explicit TypeParameterizedTestSuiteInfo(CodeLocation c)\n        : code_location(std::move(c)), instantiated(false) {}\n\n    CodeLocation code_location;\n    bool instantiated;\n  };\n\n  std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;\n};\n\n}  // namespace internal\n\n// Forward declarations of ValuesIn(), which is implemented in\n// include/gtest/gtest-param-test.h.\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container);\n\nnamespace internal {\n// Used in the Values() function to provide polymorphic capabilities.\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\ntemplate <typename... Ts>\nclass ValueArray {\n public:\n  explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {  // NOLINT\n    return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));\n  }\n\n private:\n  template <typename T, size_t... I>\n  std::vector<T> MakeVector(std::index_sequence<I...>) const {\n    return std::vector<T>{static_cast<T>(v_.template Get<I>())...};\n  }\n\n  FlatTuple<Ts...> v_;\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\ntemplate <typename... T>\nclass CartesianProductGenerator\n    : public ParamGeneratorInterface<::std::tuple<T...>> {\n public:\n  typedef ::std::tuple<T...> ParamType;\n\n  CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)\n      : generators_(g) {}\n  ~CartesianProductGenerator() override = default;\n\n  ParamIteratorInterface<ParamType>* Begin() const override {\n    return new Iterator(this, generators_, false);\n  }\n  ParamIteratorInterface<ParamType>* End() const override {\n    return new Iterator(this, generators_, true);\n  }\n\n private:\n  template <class I>\n  class IteratorImpl;\n  template <size_t... I>\n  class IteratorImpl<std::index_sequence<I...>>\n      : public ParamIteratorInterface<ParamType> {\n   public:\n    IteratorImpl(const ParamGeneratorInterface<ParamType>* base,\n                 const std::tuple<ParamGenerator<T>...>& generators,\n                 bool is_end)\n        : base_(base),\n          begin_(std::get<I>(generators).begin()...),\n          end_(std::get<I>(generators).end()...),\n          current_(is_end ? end_ : begin_) {\n      ComputeCurrentValue();\n    }\n    ~IteratorImpl() override = default;\n\n    const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    void Advance() override {\n      assert(!AtEnd());\n      // Advance the last iterator.\n      ++std::get<sizeof...(T) - 1>(current_);\n      // if that reaches end, propagate that up.\n      AdvanceIfEnd<sizeof...(T) - 1>();\n      ComputeCurrentValue();\n    }\n    ParamIteratorInterface<ParamType>* Clone() const override {\n      return new IteratorImpl(*this);\n    }\n\n    const ParamType* Current() const override { return current_value_.get(); }\n\n    bool Equals(const ParamIteratorInterface<ParamType>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const IteratorImpl* typed_other =\n          CheckedDowncastToActualType<const IteratorImpl>(&other);\n\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      if (AtEnd() && typed_other->AtEnd()) return true;\n\n      bool same = true;\n      bool dummy[] = {\n          (same = same && std::get<I>(current_) ==\n                              std::get<I>(typed_other->current_))...};\n      (void)dummy;\n      return same;\n    }\n\n   private:\n    template <size_t ThisI>\n    void AdvanceIfEnd() {\n      if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;\n\n      bool last = ThisI == 0;\n      if (last) {\n        // We are done. Nothing else to propagate.\n        return;\n      }\n\n      constexpr size_t NextI = ThisI - (ThisI != 0);\n      std::get<ThisI>(current_) = std::get<ThisI>(begin_);\n      ++std::get<NextI>(current_);\n      AdvanceIfEnd<NextI>();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);\n    }\n    bool AtEnd() const {\n      bool at_end = false;\n      bool dummy[] = {\n          (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};\n      (void)dummy;\n      return at_end;\n    }\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    std::tuple<typename ParamGenerator<T>::iterator...> begin_;\n    std::tuple<typename ParamGenerator<T>::iterator...> end_;\n    std::tuple<typename ParamGenerator<T>::iterator...> current_;\n    std::shared_ptr<ParamType> current_value_;\n  };\n\n  using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;\n\n  std::tuple<ParamGenerator<T>...> generators_;\n};\n\ntemplate <class... Gen>\nclass CartesianProductHolder {\n public:\n  CartesianProductHolder(const Gen&... g) : generators_(g...) {}\n  template <typename... T>\n  operator ParamGenerator<::std::tuple<T...>>() const {\n    return ParamGenerator<::std::tuple<T...>>(\n        new CartesianProductGenerator<T...>(generators_));\n  }\n\n private:\n  std::tuple<Gen...> generators_;\n};\n\ntemplate <typename From, typename To>\nclass ParamGeneratorConverter : public ParamGeneratorInterface<To> {\n public:\n  ParamGeneratorConverter(ParamGenerator<From> gen)  // NOLINT\n      : generator_(std::move(gen)) {}\n\n  ParamIteratorInterface<To>* Begin() const override {\n    return new Iterator(this, generator_.begin(), generator_.end());\n  }\n  ParamIteratorInterface<To>* End() const override {\n    return new Iterator(this, generator_.end(), generator_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<To> {\n   public:\n    Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,\n             ParamIterator<From> end)\n        : base_(base), it_(it), end_(end) {\n      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));\n    }\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<To>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      ++it_;\n      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));\n    }\n    ParamIteratorInterface<To>* Clone() const override {\n      return new Iterator(*this);\n    }\n    const To* Current() const override { return value_.get(); }\n    bool Equals(const ParamIteratorInterface<To>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const ParamIterator<From> other_it =\n          CheckedDowncastToActualType<const Iterator>(&other)->it_;\n      return it_ == other_it;\n    }\n\n   private:\n    Iterator(const Iterator& other) = default;\n\n    const ParamGeneratorInterface<To>* const base_;\n    ParamIterator<From> it_;\n    ParamIterator<From> end_;\n    std::shared_ptr<To> value_;\n  };  // class ParamGeneratorConverter::Iterator\n\n  ParamGenerator<From> generator_;\n};  // class ParamGeneratorConverter\n\ntemplate <class Gen>\nclass ParamConverterGenerator {\n public:\n  ParamConverterGenerator(ParamGenerator<Gen> g)  // NOLINT\n      : generator_(std::move(g)) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {  // NOLINT\n    return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));\n  }\n\n private:\n  ParamGenerator<Gen> generator_;\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-port-arch.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the GTEST_OS_* macro.\n// It is separate from gtest-port.h so that custom/gtest-port.h can include it.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n\n// Determines the platform on which Google Test is compiled.\n#ifdef __CYGWIN__\n#define GTEST_OS_CYGWIN 1\n#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)\n#define GTEST_OS_WINDOWS_MINGW 1\n#define GTEST_OS_WINDOWS 1\n#elif defined _WIN32\n#define GTEST_OS_WINDOWS 1\n#ifdef _WIN32_WCE\n#define GTEST_OS_WINDOWS_MOBILE 1\n#elif defined(WINAPI_FAMILY)\n#include <winapifamily.h>\n#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)\n#define GTEST_OS_WINDOWS_PHONE 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)\n#define GTEST_OS_WINDOWS_RT 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)\n#define GTEST_OS_WINDOWS_PHONE 1\n#define GTEST_OS_WINDOWS_TV_TITLE 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)\n#define GTEST_OS_WINDOWS_GAMES 1\n#else\n// WINAPI_FAMILY defined but no known partition matched.\n// Default to desktop.\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#endif\n#else\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#endif  // _WIN32_WCE\n#elif defined __OS2__\n#define GTEST_OS_OS2 1\n#elif defined __APPLE__\n#define GTEST_OS_MAC 1\n#include <TargetConditionals.h>\n#if TARGET_OS_IPHONE\n#define GTEST_OS_IOS 1\n#endif\n#elif defined __DragonFly__\n#define GTEST_OS_DRAGONFLY 1\n#elif defined __FreeBSD__\n#define GTEST_OS_FREEBSD 1\n#elif defined __Fuchsia__\n#define GTEST_OS_FUCHSIA 1\n#elif defined(__GNU__)\n#define GTEST_OS_GNU_HURD 1\n#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)\n#define GTEST_OS_GNU_KFREEBSD 1\n#elif defined __linux__\n#define GTEST_OS_LINUX 1\n#if defined __ANDROID__\n#define GTEST_OS_LINUX_ANDROID 1\n#endif\n#elif defined __MVS__\n#define GTEST_OS_ZOS 1\n#elif defined(__sun) && defined(__SVR4)\n#define GTEST_OS_SOLARIS 1\n#elif defined(_AIX)\n#define GTEST_OS_AIX 1\n#elif defined(__hpux)\n#define GTEST_OS_HPUX 1\n#elif defined __native_client__\n#define GTEST_OS_NACL 1\n#elif defined __NetBSD__\n#define GTEST_OS_NETBSD 1\n#elif defined __OpenBSD__\n#define GTEST_OS_OPENBSD 1\n#elif defined __QNX__\n#define GTEST_OS_QNX 1\n#elif defined(__HAIKU__)\n#define GTEST_OS_HAIKU 1\n#elif defined ESP8266\n#define GTEST_OS_ESP8266 1\n#elif defined ESP32\n#define GTEST_OS_ESP32 1\n#elif defined(__XTENSA__)\n#define GTEST_OS_XTENSA 1\n#elif defined(__hexagon__)\n#define GTEST_OS_QURT 1\n#elif defined(CPU_QN9090) || defined(CPU_QN9090HN)\n#define GTEST_OS_NXP_QN9090 1\n#elif defined(NRF52)\n#define GTEST_OS_NRF52 1\n#endif  // __CYGWIN__\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-port.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Low-level types and utilities for porting Google Test to various\n// platforms.  All macros ending with _ and symbols defined in an\n// internal namespace are subject to change without notice.  Code\n// outside Google Test MUST NOT USE THEM DIRECTLY.  Macros that don't\n// end with _ are part of Google Test's public API and can be used by\n// code outside Google Test.\n//\n// This file is fundamental to Google Test.  All other Google Test source\n// files are expected to #include this.  Therefore, it cannot #include\n// any other Google Test header.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n\n// Environment-describing macros\n// -----------------------------\n//\n// Google Test can be used in many different environments.  Macros in\n// this section tell Google Test what kind of environment it is being\n// used in, such that Google Test can provide environment-specific\n// features and implementations.\n//\n// Google Test tries to automatically detect the properties of its\n// environment, so users usually don't need to worry about these\n// macros.  However, the automatic detection is not perfect.\n// Sometimes it's necessary for a user to define some of the following\n// macros in the build script to override Google Test's decisions.\n//\n// If the user doesn't define a macro in the list, Google Test will\n// provide a default definition.  After this header is #included, all\n// macros in this list will be defined to either 1 or 0.\n//\n// Notes to maintainers:\n//   - Each macro here is a user-tweakable knob; do not grow the list\n//     lightly.\n//   - Use #if to key off these macros.  Don't use #ifdef or \"#if\n//     defined(...)\", which will not work as these macros are ALWAYS\n//     defined.\n//\n//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)\n//                              is/isn't available.\n//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions\n//                              are enabled.\n//   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular\n//                              expressions are/aren't available.\n//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>\n//                              is/isn't available.\n//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't\n//                              enabled.\n//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that\n//                              std::wstring does/doesn't work (Google Test can\n//                              be used where std::wstring is unavailable).\n//   GTEST_HAS_FILE_SYSTEM    - Define it to 1/0 to indicate whether or not a\n//                              file system is/isn't available.\n//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the\n//                              compiler supports Microsoft's \"Structured\n//                              Exception Handling\".\n//   GTEST_HAS_STREAM_REDIRECTION\n//                            - Define it to 1/0 to indicate whether the\n//                              platform supports I/O stream redirection using\n//                              dup() and dup2().\n//   GTEST_LINKED_AS_SHARED_LIBRARY\n//                            - Define to 1 when compiling tests that use\n//                              Google Test as a shared library (known as\n//                              DLL on Windows).\n//   GTEST_CREATE_SHARED_LIBRARY\n//                            - Define to 1 when compiling Google Test itself\n//                              as a shared library.\n//   GTEST_DEFAULT_DEATH_TEST_STYLE\n//                            - The default value of --gtest_death_test_style.\n//                              The legacy default has been \"fast\" in the open\n//                              source version since 2008. The recommended value\n//                              is \"threadsafe\", and can be set in\n//                              custom/gtest-port.h.\n\n// Platform-indicating macros\n// --------------------------\n//\n// Macros indicating the platform on which Google Test is being used\n// (a macro is defined to 1 if compiled on the given platform;\n// otherwise UNDEFINED -- it's never defined to 0.).  Google Test\n// defines these macros automatically.  Code outside Google Test MUST\n// NOT define them.\n//\n//   GTEST_OS_AIX      - IBM AIX\n//   GTEST_OS_CYGWIN   - Cygwin\n//   GTEST_OS_DRAGONFLY - DragonFlyBSD\n//   GTEST_OS_FREEBSD  - FreeBSD\n//   GTEST_OS_FUCHSIA  - Fuchsia\n//   GTEST_OS_GNU_HURD - GNU/Hurd\n//   GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD\n//   GTEST_OS_HAIKU    - Haiku\n//   GTEST_OS_HPUX     - HP-UX\n//   GTEST_OS_LINUX    - Linux\n//     GTEST_OS_LINUX_ANDROID - Google Android\n//   GTEST_OS_MAC      - Mac OS X\n//     GTEST_OS_IOS    - iOS\n//   GTEST_OS_NACL     - Google Native Client (NaCl)\n//   GTEST_OS_NETBSD   - NetBSD\n//   GTEST_OS_OPENBSD  - OpenBSD\n//   GTEST_OS_OS2      - OS/2\n//   GTEST_OS_QNX      - QNX\n//   GTEST_OS_SOLARIS  - Sun Solaris\n//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)\n//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop\n//     GTEST_OS_WINDOWS_MINGW    - MinGW\n//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile\n//     GTEST_OS_WINDOWS_PHONE    - Windows Phone\n//     GTEST_OS_WINDOWS_RT       - Windows Store App/WinRT\n//   GTEST_OS_ZOS      - z/OS\n//\n// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the\n// most stable support.  Since core members of the Google Test project\n// don't have access to other platforms, support for them may be less\n// stable.  If you notice any problems on your platform, please notify\n// googletestframework@googlegroups.com (patches for fixing them are\n// even more welcome!).\n//\n// It is possible that none of the GTEST_OS_* macros are defined.\n\n// Feature-indicating macros\n// -------------------------\n//\n// Macros indicating which Google Test features are available (a macro\n// is defined to 1 if the corresponding feature is supported;\n// otherwise UNDEFINED -- it's never defined to 0.).  Google Test\n// defines these macros automatically.  Code outside Google Test MUST\n// NOT define them.\n//\n// These macros are public so that portable tests can be written.\n// Such tests typically surround code using a feature with an #ifdef\n// which controls that code.  For example:\n//\n// #ifdef GTEST_HAS_DEATH_TEST\n//   EXPECT_DEATH(DoSomethingDeadly());\n// #endif\n//\n//   GTEST_HAS_DEATH_TEST   - death tests\n//   GTEST_HAS_TYPED_TEST   - typed tests\n//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests\n//   GTEST_IS_THREADSAFE    - Google Test is thread-safe.\n//   GTEST_USES_RE2         - the RE2 regular expression library is used\n//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with\n//                            GTEST_HAS_POSIX_RE (see above) which users can\n//                            define themselves.\n//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;\n//                            the above RE\\b(s) are mutually exclusive.\n//   GTEST_HAS_ABSL         - Google Test is compiled with Abseil.\n\n// Misc public macros\n// ------------------\n//\n//   GTEST_FLAG(flag_name)  - references the variable corresponding to\n//                            the given Google Test flag.\n\n// Internal utilities\n// ------------------\n//\n// The following macros and utilities are for Google Test's INTERNAL\n// use only.  Code outside Google Test MUST NOT USE THEM DIRECTLY.\n//\n// Macros for basic C++ coding:\n//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.\n//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.\n//   GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is\n//                                        suppressed (constant conditional).\n//   GTEST_INTENTIONAL_CONST_COND_POP_  - finish code section where MSVC C4127\n//                                        is suppressed.\n//   GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or\n//                            UniversalPrinter<absl::any> specializations.\n//                            Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>\n//   or\n//                                 UniversalPrinter<absl::optional>\n//                                 specializations. Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>\n//                                 specializations. Always defined to 0 or 1\n//   GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or\n//                                    Matcher<absl::string_view>\n//                                    specializations. Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or\n//                                UniversalPrinter<absl::variant>\n//                                specializations. Always defined to 0 or 1.\n//   GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.\n//   GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.\n//   GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.\n//   GTEST_HAS_ALT_PATH_SEP_ - Always defined to 0 or 1.\n//   GTEST_WIDE_STRING_USES_UTF16_ - Always defined to 0 or 1.\n//   GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Always defined to 0 or 1.\n//   GTEST_HAS_NOTIFICATION_- Always defined to 0 or 1.\n//\n// Synchronization:\n//   Mutex, MutexLock, ThreadLocal, GetThreadCount()\n//                            - synchronization primitives.\n//\n// Regular expressions:\n//   RE             - a simple regular expression class using\n//                     1) the RE2 syntax on all platforms when built with RE2\n//                        and Abseil as dependencies\n//                     2) the POSIX Extended Regular Expression syntax on\n//                        UNIX-like platforms,\n//                     3) A reduced regular exception syntax on other platforms,\n//                        including Windows.\n// Logging:\n//   GTEST_LOG_()   - logs messages at the specified severity level.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n//\n// Stdout and stderr capturing:\n//   CaptureStdout()     - starts capturing stdout.\n//   GetCapturedStdout() - stops capturing stdout and returns the captured\n//                         string.\n//   CaptureStderr()     - starts capturing stderr.\n//   GetCapturedStderr() - stops capturing stderr and returns the captured\n//                         string.\n//\n// Integer types:\n//   TypeWithSize   - maps an integer to a int type.\n//   TimeInMillis   - integers of known sizes.\n//   BiggestInt     - the biggest signed integer type.\n//\n// Command-line utilities:\n//   GetInjectableArgvs() - returns the command line as a vector of strings.\n//\n// Environment variable utilities:\n//   GetEnv()             - gets the value of an environment variable.\n//   BoolFromGTestEnv()   - parses a bool environment variable.\n//   Int32FromGTestEnv()  - parses an int32_t environment variable.\n//   StringFromGTestEnv() - parses a string environment variable.\n//\n// Deprecation warnings:\n//   GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as\n//                                        deprecated; calling a marked function\n//                                        should generate a compiler warning\n\n// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can\n// potentially be used as an #include guard.\n#if defined(_MSVC_LANG)\n#define GTEST_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG\n#elif defined(__cplusplus)\n#define GTEST_INTERNAL_CPLUSPLUS_LANG __cplusplus\n#endif\n\n#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \\\n    GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L\n#error C++ versions less than C++14 are not supported.\n#endif\n\n// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.\n#ifdef __has_include\n#define GTEST_INTERNAL_HAS_INCLUDE __has_include\n#else\n#define GTEST_INTERNAL_HAS_INCLUDE(...) 0\n#endif\n\n// Detect C++ feature test macros as gracefully as possible.\n// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.\n#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \\\n    (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))\n#include <version>  // C++20 and later\n#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))\n#include <ciso646>  // Pre-C++20\n#endif\n\n#include <ctype.h>   // for isspace, etc\n#include <stddef.h>  // for ptrdiff_t\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cerrno>\n// #include <condition_variable>  // Guarded by GTEST_IS_THREADSAFE below\n#include <cstdint>\n#include <iostream>\n#include <limits>\n#include <locale>\n#include <memory>\n#include <ostream>\n#include <string>\n// #include <mutex>  // Guarded by GTEST_IS_THREADSAFE below\n#include <tuple>\n#include <type_traits>\n#include <vector>\n\n#ifndef _WIN32_WCE\n#include <sys/stat.h>\n#include <sys/types.h>\n#endif  // !_WIN32_WCE\n\n#if defined __APPLE__\n#include <AvailabilityMacros.h>\n#include <TargetConditionals.h>\n#endif\n\n#include \"gtest/internal/custom/gtest-port.h\"\n#include \"gtest/internal/gtest-port-arch.h\"\n\n#ifndef GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n#define GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ 0\n#endif\n\n#ifndef GTEST_HAS_NOTIFICATION_\n#define GTEST_HAS_NOTIFICATION_ 0\n#endif\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#define GTEST_INTERNAL_HAS_ABSL_FLAGS  // Used only in this file.\n#include \"absl/flags/declare.h\"\n#include \"absl/flags/flag.h\"\n#include \"absl/flags/reflection.h\"\n#endif\n\n#if !defined(GTEST_DEV_EMAIL_)\n#define GTEST_DEV_EMAIL_ \"googletestframework@@googlegroups.com\"\n#define GTEST_FLAG_PREFIX_ \"gtest_\"\n#define GTEST_FLAG_PREFIX_DASH_ \"gtest-\"\n#define GTEST_FLAG_PREFIX_UPPER_ \"GTEST_\"\n#define GTEST_NAME_ \"Google Test\"\n#define GTEST_PROJECT_URL_ \"https://github.com/google/googletest/\"\n#endif  // !defined(GTEST_DEV_EMAIL_)\n\n#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_)\n#define GTEST_INIT_GOOGLE_TEST_NAME_ \"testing::InitGoogleTest\"\n#endif  // !defined(GTEST_INIT_GOOGLE_TEST_NAME_)\n\n// Determines the version of gcc that is used to compile this.\n#ifdef __GNUC__\n// 40302 means version 4.3.2.\n#define GTEST_GCC_VER_ \\\n  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)\n#endif  // __GNUC__\n\n// Macros for disabling Microsoft Visual C++ warnings.\n//\n//   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)\n//   /* code that triggers warnings C4800 and C4385 */\n//   GTEST_DISABLE_MSC_WARNINGS_POP_()\n#if defined(_MSC_VER)\n#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \\\n  __pragma(warning(push)) __pragma(warning(disable : warnings))\n#define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop))\n#else\n// Not all compilers are MSVC\n#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)\n#define GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n// Clang on Windows does not understand MSVC's pragma warning.\n// We need clang-specific way to disable function deprecation warning.\n#ifdef __clang__\n#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_()                            \\\n  _Pragma(\"clang diagnostic push\")                                      \\\n      _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-declarations\\\"\") \\\n          _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-implementations\\\"\")\n#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma(\"clang diagnostic pop\")\n#else\n#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \\\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)\n#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n// Brings in definitions for functions used in the testing::internal::posix\n// namespace (read, write, close, chdir, isatty, stat). We do not currently\n// use them on Windows Mobile.\n#ifdef GTEST_OS_WINDOWS\n#ifndef GTEST_OS_WINDOWS_MOBILE\n#include <direct.h>\n#include <io.h>\n#endif\n// In order to avoid having to include <windows.h>, use forward declaration\n#if defined(GTEST_OS_WINDOWS_MINGW) && !defined(__MINGW64_VERSION_MAJOR)\n// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two\n// separate (equivalent) structs, instead of using typedef\ntypedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;\n#else\n// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.\n// This assumption is verified by\n// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.\ntypedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;\n#endif\n#elif defined(GTEST_OS_XTENSA)\n#include <unistd.h>\n// Xtensa toolchains define strcasecmp in the string.h header instead of\n// strings.h. string.h is already included.\n#else\n// This assumes that non-Windows OSes provide unistd.h. For OSes where this\n// is not the case, we need to include headers that provide the functions\n// mentioned above.\n#include <strings.h>\n#include <unistd.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_LINUX_ANDROID\n// Used to define __ANDROID_API__ matching the target NDK API level.\n#include <android/api-level.h>  // NOLINT\n#endif\n\n// Defines this to true if and only if Google Test can use POSIX regular\n// expressions.\n#ifndef GTEST_HAS_POSIX_RE\n#ifdef GTEST_OS_LINUX_ANDROID\n// On Android, <regex.h> is only available starting with Gingerbread.\n#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)\n#else\n#if !(defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_XTENSA) || \\\n      defined(GTEST_OS_QURT))\n#define GTEST_HAS_POSIX_RE 1\n#else\n#define GTEST_HAS_POSIX_RE 0\n#endif\n#endif  // GTEST_OS_LINUX_ANDROID\n#endif\n\n// Select the regular expression implementation.\n#ifdef GTEST_HAS_ABSL\n// When using Abseil, RE2 is required.\n#include \"absl/strings/string_view.h\"\n#include \"re2/re2.h\"\n#define GTEST_USES_RE2 1\n#elif GTEST_HAS_POSIX_RE\n#include <regex.h>  // NOLINT\n#define GTEST_USES_POSIX_RE 1\n#else\n// Use our own simple regex implementation.\n#define GTEST_USES_SIMPLE_RE 1\n#endif\n\n#ifndef GTEST_HAS_EXCEPTIONS\n// The user didn't tell us whether exceptions are enabled, so we need\n// to figure it out.\n#if defined(_MSC_VER) && defined(_CPPUNWIND)\n// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__BORLANDC__)\n// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS\n// macro to enable exceptions, so we'll do the same.\n// Assumes that exceptions are enabled by default.\n#ifndef _HAS_EXCEPTIONS\n#define _HAS_EXCEPTIONS 1\n#endif  // _HAS_EXCEPTIONS\n#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS\n#elif defined(__clang__)\n// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang\n// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files,\n// there can be cleanups for ObjC exceptions which also need cleanups, even if\n// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which\n// checks for C++ exceptions starting at clang r206352, but which checked for\n// cleanups prior to that. To reliably check for C++ exception availability with\n// clang, check for\n// __EXCEPTIONS && __has_feature(cxx_exceptions).\n#if defined(__EXCEPTIONS) && __EXCEPTIONS && __has_feature(cxx_exceptions)\n#define GTEST_HAS_EXCEPTIONS 1\n#else\n#define GTEST_HAS_EXCEPTIONS 0\n#endif\n#elif defined(__GNUC__) && defined(__EXCEPTIONS) && __EXCEPTIONS\n// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__SUNPRO_CC)\n// Sun Pro CC supports exceptions.  However, there is no compile-time way of\n// detecting whether they are enabled or not.  Therefore, we assume that\n// they are enabled unless the user tells us otherwise.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__IBMCPP__) && defined(__EXCEPTIONS) && __EXCEPTIONS\n// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__HP_aCC)\n// Exception handling is in effect by default in HP aCC compiler. It has to\n// be turned of by +noeh compiler option if desired.\n#define GTEST_HAS_EXCEPTIONS 1\n#else\n// For other compilers, we assume exceptions are disabled to be\n// conservative.\n#define GTEST_HAS_EXCEPTIONS 0\n#endif  // defined(_MSC_VER) || defined(__BORLANDC__)\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#ifndef GTEST_HAS_STD_WSTRING\n// The user didn't tell us whether ::std::wstring is available, so we need\n// to figure it out.\n// Cygwin 1.7 and below doesn't support ::std::wstring.\n// Solaris' libc++ doesn't support it either.  Android has\n// no support for it at least as recent as Froyo (2.2).\n#if (!(defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_CYGWIN) || \\\n       defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) ||        \\\n       defined(GTEST_OS_ESP32) || defined(GTEST_OS_ESP8266) ||        \\\n       defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) ||          \\\n       defined(GTEST_OS_NXP_QN9090) || defined(GTEST_OS_NRF52)))\n#define GTEST_HAS_STD_WSTRING 1\n#else\n#define GTEST_HAS_STD_WSTRING 0\n#endif\n#endif  // GTEST_HAS_STD_WSTRING\n\n#ifndef GTEST_HAS_FILE_SYSTEM\n// Most platforms support a file system.\n#define GTEST_HAS_FILE_SYSTEM 1\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Determines whether RTTI is available.\n#ifndef GTEST_HAS_RTTI\n// The user didn't tell us whether RTTI is enabled, so we need to\n// figure it out.\n\n#ifdef _MSC_VER\n\n#ifdef _CPPRTTI  // MSVC defines this macro if and only if RTTI is enabled.\n#define GTEST_HAS_RTTI 1\n#else\n#define GTEST_HAS_RTTI 0\n#endif\n\n// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is\n// enabled.\n#elif defined(__GNUC__)\n\n#ifdef __GXX_RTTI\n// When building against STLport with the Android NDK and with\n// -frtti -fno-exceptions, the build fails at link time with undefined\n// references to __cxa_bad_typeid. Note sure if STL or toolchain bug,\n// so disable RTTI when detected.\n#if defined(GTEST_OS_LINUX_ANDROID) && defined(_STLPORT_MAJOR) && \\\n    !defined(__EXCEPTIONS)\n#define GTEST_HAS_RTTI 0\n#else\n#define GTEST_HAS_RTTI 1\n#endif  // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS\n#else\n#define GTEST_HAS_RTTI 0\n#endif  // __GXX_RTTI\n\n// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends\n// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the\n// first version with C++ support.\n#elif defined(__clang__)\n\n#define GTEST_HAS_RTTI __has_feature(cxx_rtti)\n\n// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if\n// both the typeid and dynamic_cast features are present.\n#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)\n\n#ifdef __RTTI_ALL__\n#define GTEST_HAS_RTTI 1\n#else\n#define GTEST_HAS_RTTI 0\n#endif\n\n#else\n\n// For all other compilers, we assume RTTI is enabled.\n#define GTEST_HAS_RTTI 1\n\n#endif  // _MSC_VER\n\n#endif  // GTEST_HAS_RTTI\n\n// It's this header's responsibility to #include <typeinfo> when RTTI\n// is enabled.\n#if GTEST_HAS_RTTI\n#include <typeinfo>\n#endif\n\n// Determines whether Google Test can use the pthreads library.\n#ifndef GTEST_HAS_PTHREAD\n// The user didn't tell us explicitly, so we make reasonable assumptions about\n// which platforms have pthreads support.\n//\n// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0\n// to your compiler flags.\n#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) ||              \\\n     defined(GTEST_OS_HPUX) || defined(GTEST_OS_QNX) ||               \\\n     defined(GTEST_OS_FREEBSD) || defined(GTEST_OS_NACL) ||           \\\n     defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) ||         \\\n     defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n     defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) ||          \\\n     defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) ||       \\\n     defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))\n#define GTEST_HAS_PTHREAD 1\n#else\n#define GTEST_HAS_PTHREAD 0\n#endif\n#endif  // GTEST_HAS_PTHREAD\n\n#if GTEST_HAS_PTHREAD\n// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is\n// true.\n#include <pthread.h>  // NOLINT\n\n// For timespec and nanosleep, used below.\n#include <time.h>  // NOLINT\n#endif\n\n// Determines whether clone(2) is supported.\n// Usually it will only be available on Linux, excluding\n// Linux on the Itanium architecture.\n// Also see https://linux.die.net/man/2/clone.\n#ifndef GTEST_HAS_CLONE\n// The user didn't tell us, so we need to figure it out.\n\n#if defined(GTEST_OS_LINUX) && !defined(__ia64__)\n#if defined(GTEST_OS_LINUX_ANDROID)\n// On Android, clone() became available at different API levels for each 32-bit\n// architecture.\n#if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \\\n    (defined(__mips__) && __ANDROID_API__ >= 12) ||                    \\\n    (defined(__i386__) && __ANDROID_API__ >= 17)\n#define GTEST_HAS_CLONE 1\n#else\n#define GTEST_HAS_CLONE 0\n#endif\n#else\n#define GTEST_HAS_CLONE 1\n#endif\n#else\n#define GTEST_HAS_CLONE 0\n#endif  // GTEST_OS_LINUX && !defined(__ia64__)\n\n#endif  // GTEST_HAS_CLONE\n\n// Determines whether to support stream redirection. This is used to test\n// output correctness and to implement death tests.\n#ifndef GTEST_HAS_STREAM_REDIRECTION\n// By default, we assume that stream redirection is supported on all\n// platforms except known mobile / embedded ones. Also, if the port doesn't have\n// a file system, stream redirection is not supported.\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) ||     \\\n    defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) ||               \\\n    defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM\n#define GTEST_HAS_STREAM_REDIRECTION 0\n#else\n#define GTEST_HAS_STREAM_REDIRECTION 1\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\n// Determines whether to support death tests.\n// pops up a dialog window that cannot be suppressed programmatically.\n#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) ||           \\\n     defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) ||            \\\n     (defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) ||             \\\n     (defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) ||               \\\n     defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) ||      \\\n     defined(GTEST_OS_HPUX) || defined(GTEST_OS_OPENBSD) ||           \\\n     defined(GTEST_OS_QNX) || defined(GTEST_OS_FREEBSD) ||            \\\n     defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) ||         \\\n     defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n     defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))\n// Death tests require a file system to work properly.\n#if GTEST_HAS_FILE_SYSTEM\n#define GTEST_HAS_DEATH_TEST 1\n#endif  // GTEST_HAS_FILE_SYSTEM\n#endif\n\n// Determines whether to support type-driven tests.\n\n// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,\n// Sun Pro CC, IBM Visual Age, and HP aCC support.\n#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \\\n    defined(__IBMCPP__) || defined(__HP_aCC)\n#define GTEST_HAS_TYPED_TEST 1\n#define GTEST_HAS_TYPED_TEST_P 1\n#endif\n\n// Determines whether the system compiler uses UTF-16 for encoding wide strings.\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \\\n    defined(GTEST_OS_AIX) || defined(GTEST_OS_OS2)\n#define GTEST_WIDE_STRING_USES_UTF16_ 1\n#else\n#define GTEST_WIDE_STRING_USES_UTF16_ 0\n#endif\n\n// Determines whether test results can be streamed to a socket.\n#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n    defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) ||  \\\n    defined(GTEST_OS_NETBSD) || defined(GTEST_OS_OPENBSD) ||     \\\n    defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_MAC)\n#define GTEST_CAN_STREAM_RESULTS_ 1\n#else\n#define GTEST_CAN_STREAM_RESULTS_ 0\n#endif\n\n// Defines some utility macros.\n\n// The GNU compiler emits a warning if nested \"if\" statements are followed by\n// an \"else\" statement and braces are not used to explicitly disambiguate the\n// \"else\" binding.  This leads to problems with code like:\n//\n//   if (gate)\n//     ASSERT_*(condition) << \"Some message\";\n//\n// The \"switch (0) case 0:\" idiom is used to suppress this.\n#ifdef __INTEL_COMPILER\n#define GTEST_AMBIGUOUS_ELSE_BLOCKER_\n#else\n#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  switch (0)                          \\\n  case 0:                             \\\n  default:  // NOLINT\n#endif\n\n// GTEST_HAVE_ATTRIBUTE_\n//\n// A function-like feature checking macro that is a wrapper around\n// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a\n// nonzero constant integer if the attribute is supported or 0 if not.\n//\n// It evaluates to zero if `__has_attribute` is not defined by the compiler.\n//\n// GCC: https://gcc.gnu.org/gcc-5/changes.html\n// Clang: https://clang.llvm.org/docs/LanguageExtensions.html\n#ifdef __has_attribute\n#define GTEST_HAVE_ATTRIBUTE_(x) __has_attribute(x)\n#else\n#define GTEST_HAVE_ATTRIBUTE_(x) 0\n#endif\n\n// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE\n//\n// A function-like feature checking macro that accepts C++11 style attributes.\n// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6\n// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't\n// find `__has_cpp_attribute`, will evaluate to 0.\n#if defined(__has_cpp_attribute)\n// NOTE: requiring __cplusplus above should not be necessary, but\n// works around https://bugs.llvm.org/show_bug.cgi?id=23435.\n#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)\n#else\n#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0\n#endif\n\n// GTEST_HAVE_FEATURE_\n//\n// A function-like feature checking macro that is a wrapper around\n// `__has_feature`.\n#ifdef __has_feature\n#define GTEST_HAVE_FEATURE_(x) __has_feature(x)\n#else\n#define GTEST_HAVE_FEATURE_(x) 0\n#endif\n\n// Use this annotation after a variable or parameter declaration to tell the\n// compiler the variable/parameter may be used.\n// Example:\n//\n//   GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar();\n//\n// This can be removed once we only support only C++17 or newer and\n// [[maybe_unused]] is available on all supported platforms.\n#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused)\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]\n#elif GTEST_HAVE_ATTRIBUTE_(unused)\n// This is inferior to [[maybe_unused]] as it can produce a\n// -Wused-but-marked-unused warning on optionally used symbols, but it is all we\n// have.\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__))\n#else\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED\n#endif\n\n// Use this annotation before a function that takes a printf format string.\n#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)\n// MinGW has two different printf implementations. Ensure the format macro\n// matches the selected implementation. See\n// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \\\n  __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))\n#elif GTEST_HAVE_ATTRIBUTE_(format)\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \\\n  __attribute__((format(printf, string_index, first_to_check)))\n#else\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)\n#endif\n\n// Tell the compiler to warn about unused return values for functions declared\n// with this macro.  The macro should be used on function declarations\n// following the argument list:\n//\n//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;\n#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)\n#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))\n#else\n#define GTEST_MUST_USE_RESULT_\n#endif\n\n// MS C++ compiler emits warning when a conditional expression is compile time\n// constant. In some contexts this warning is false positive and needs to be\n// suppressed. Use the following two macros in such cases:\n//\n// GTEST_INTENTIONAL_CONST_COND_PUSH_()\n// while (true) {\n// GTEST_INTENTIONAL_CONST_COND_POP_()\n// }\n#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \\\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127)\n#define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()\n\n// Determine whether the compiler supports Microsoft's Structured Exception\n// Handling.  This is supported by several Windows compilers but generally\n// does not exist on any other system.\n#ifndef GTEST_HAS_SEH\n// The user didn't tell us, so we need to figure it out.\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\n// These two compilers are known to support SEH.\n#define GTEST_HAS_SEH 1\n#else\n// Assume no SEH.\n#define GTEST_HAS_SEH 0\n#endif\n\n#endif  // GTEST_HAS_SEH\n\n#ifndef GTEST_IS_THREADSAFE\n\n#if (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ ||                              \\\n     (defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n      !defined(GTEST_OS_WINDOWS_RT)) ||                                \\\n     GTEST_HAS_PTHREAD)\n#define GTEST_IS_THREADSAFE 1\n#endif\n\n#endif  // GTEST_IS_THREADSAFE\n\n#ifdef GTEST_IS_THREADSAFE\n// Some platforms don't support including these threading related headers.\n#include <condition_variable>  // NOLINT\n#include <mutex>               // NOLINT\n#endif                         // GTEST_IS_THREADSAFE\n\n// GTEST_API_ qualifies all symbols that must be exported. The definitions below\n// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in\n// gtest/internal/custom/gtest-port.h\n#ifndef GTEST_API_\n\n#ifdef _MSC_VER\n#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY\n#define GTEST_API_ __declspec(dllimport)\n#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY\n#define GTEST_API_ __declspec(dllexport)\n#endif\n#elif GTEST_HAVE_ATTRIBUTE_(visibility)\n#define GTEST_API_ __attribute__((visibility(\"default\")))\n#endif  // _MSC_VER\n\n#endif  // GTEST_API_\n\n#ifndef GTEST_API_\n#define GTEST_API_\n#endif  // GTEST_API_\n\n#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE\n#define GTEST_DEFAULT_DEATH_TEST_STYLE \"fast\"\n#endif  // GTEST_DEFAULT_DEATH_TEST_STYLE\n\n#if GTEST_HAVE_ATTRIBUTE_(noinline)\n// Ask the compiler to never inline a given function.\n#define GTEST_NO_INLINE_ __attribute__((noinline))\n#else\n#define GTEST_NO_INLINE_\n#endif\n\n#if GTEST_HAVE_ATTRIBUTE_(disable_tail_calls)\n// Ask the compiler not to perform tail call optimization inside\n// the marked function.\n#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))\n#elif defined(__GNUC__) && !defined(__NVCOMPILER)\n#define GTEST_NO_TAIL_CALL_ \\\n  __attribute__((optimize(\"no-optimize-sibling-calls\")))\n#else\n#define GTEST_NO_TAIL_CALL_\n#endif\n\n// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.\n#if !defined(GTEST_HAS_CXXABI_H_)\n#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))\n#define GTEST_HAS_CXXABI_H_ 1\n#else\n#define GTEST_HAS_CXXABI_H_ 0\n#endif\n#endif\n\n// A function level attribute to disable checking for use of uninitialized\n// memory when built with MemorySanitizer.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_memory)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_\n#endif\n\n// A function level attribute to disable AddressSanitizer instrumentation.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_address)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \\\n  __attribute__((no_sanitize_address))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n#endif\n\n// A function level attribute to disable HWAddressSanitizer instrumentation.\n#if GTEST_HAVE_FEATURE_(hwaddress_sanitizer) && \\\n    GTEST_HAVE_ATTRIBUTE_(no_sanitize)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \\\n  __attribute__((no_sanitize(\"hwaddress\")))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n#endif\n\n// A function level attribute to disable ThreadSanitizer instrumentation.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_thread)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute((no_sanitize_thread))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_\n#endif\n\nnamespace testing {\n\nclass Message;\n\n// Legacy imports for backwards compatibility.\n// New code should use std:: names directly.\nusing std::get;\nusing std::make_tuple;\nusing std::tuple;\nusing std::tuple_element;\nusing std::tuple_size;\n\nnamespace internal {\n\n// A secret type that Google Test users don't know about.  It has no\n// accessible constructors on purpose.  Therefore it's impossible to create a\n// Secret object, which is what we want.\nclass Secret {\n  Secret(const Secret&) = delete;\n};\n\n// A helper for suppressing warnings on constant condition.  It just\n// returns 'condition'.\nGTEST_API_ bool IsTrue(bool condition);\n\n// Defines RE.\n\n#ifdef GTEST_USES_RE2\n\n// This is almost `using RE = ::RE2`, except it is copy-constructible, and it\n// needs to disambiguate the `std::string`, `absl::string_view`, and `const\n// char*` constructors.\nclass GTEST_API_ RE {\n public:\n  RE(absl::string_view regex) : regex_(regex) {}                  // NOLINT\n  RE(const char* regex) : RE(absl::string_view(regex)) {}         // NOLINT\n  RE(const std::string& regex) : RE(absl::string_view(regex)) {}  // NOLINT\n  RE(const RE& other) : RE(other.pattern()) {}\n\n  const std::string& pattern() const { return regex_.pattern(); }\n\n  static bool FullMatch(absl::string_view str, const RE& re) {\n    return RE2::FullMatch(str, re.regex_);\n  }\n  static bool PartialMatch(absl::string_view str, const RE& re) {\n    return RE2::PartialMatch(str, re.regex_);\n  }\n\n private:\n  RE2 regex_;\n};\n\n#elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_SIMPLE_RE)\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended\n// Regular Expression syntax.\nclass GTEST_API_ RE {\n public:\n  // A copy constructor is required by the Standard to initialize object\n  // references from r-values.\n  RE(const RE& other) { Init(other.pattern()); }\n\n  // Constructs an RE from a string.\n  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT\n\n  RE(const char* regex) { Init(regex); }  // NOLINT\n  ~RE();\n\n  // Returns the string representation of the regex.\n  const char* pattern() const { return pattern_.c_str(); }\n\n  // FullMatch(str, re) returns true if and only if regular expression re\n  // matches the entire str.\n  // PartialMatch(str, re) returns true if and only if regular expression re\n  // matches a substring of str (including str itself).\n  static bool FullMatch(const ::std::string& str, const RE& re) {\n    return FullMatch(str.c_str(), re);\n  }\n  static bool PartialMatch(const ::std::string& str, const RE& re) {\n    return PartialMatch(str.c_str(), re);\n  }\n\n  static bool FullMatch(const char* str, const RE& re);\n  static bool PartialMatch(const char* str, const RE& re);\n\n private:\n  void Init(const char* regex);\n  std::string pattern_;\n  bool is_valid_;\n\n#ifdef GTEST_USES_POSIX_RE\n\n  regex_t full_regex_;     // For FullMatch().\n  regex_t partial_regex_;  // For PartialMatch().\n\n#else  // GTEST_USES_SIMPLE_RE\n\n  std::string full_pattern_;  // For FullMatch();\n\n#endif\n};\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n#endif  // ::testing::internal::RE implementation\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line);\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\n                                                               int line);\n\n// Defines logging utilities:\n//   GTEST_LOG_(severity) - logs messages at the specified severity level. The\n//                          message itself is streamed into the macro.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n\nenum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };\n\n// Formats log entry severity, provides a stream object for streaming the\n// log message, and terminates the message with a newline when going out of\n// scope.\nclass GTEST_API_ GTestLog {\n public:\n  GTestLog(GTestLogSeverity severity, const char* file, int line);\n\n  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\n  ~GTestLog();\n\n  ::std::ostream& GetStream() { return ::std::cerr; }\n\n private:\n  const GTestLogSeverity severity_;\n\n  GTestLog(const GTestLog&) = delete;\n  GTestLog& operator=(const GTestLog&) = delete;\n};\n\n#if !defined(GTEST_LOG_)\n\n#define GTEST_LOG_(severity)                                           \\\n  ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \\\n                                __FILE__, __LINE__)                    \\\n      .GetStream()\n\ninline void LogToStderr() {}\ninline void FlushInfoLog() { fflush(nullptr); }\n\n#endif  // !defined(GTEST_LOG_)\n\n#if !defined(GTEST_CHECK_)\n// INTERNAL IMPLEMENTATION - DO NOT USE.\n//\n// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition\n// is not satisfied.\n//  Synopsis:\n//    GTEST_CHECK_(boolean_condition);\n//     or\n//    GTEST_CHECK_(boolean_condition) << \"Additional message\";\n//\n//    This checks the condition and if the condition is not satisfied\n//    it prints message about the condition violation, including the\n//    condition itself, plus additional message streamed into it, if any,\n//    and then it aborts the program. It aborts the program irrespective of\n//    whether it is built in the debug mode or not.\n#define GTEST_CHECK_(condition)               \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_               \\\n  if (::testing::internal::IsTrue(condition)) \\\n    ;                                         \\\n  else                                        \\\n    GTEST_LOG_(FATAL) << \"Condition \" #condition \" failed. \"\n#endif  // !defined(GTEST_CHECK_)\n\n// An all-mode assert to verify that the given POSIX-style function\n// call returns 0 (indicating success).  Known limitation: this\n// doesn't expand to a balanced 'if' statement, so enclose the macro\n// in {} if you need to use it as the only statement in an 'if'\n// branch.\n#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \\\n  if (const int gtest_error = (posix_call))    \\\n  GTEST_LOG_(FATAL) << #posix_call << \"failed with error \" << gtest_error\n\n// Transforms \"T\" into \"const T&\" according to standard reference collapsing\n// rules (this is only needed as a backport for C++98 compilers that do not\n// support reference collapsing). Specifically, it transforms:\n//\n//   char         ==> const char&\n//   const char   ==> const char&\n//   char&        ==> char&\n//   const char&  ==> const char&\n//\n// Note that the non-const reference will not have \"const\" added. This is\n// standard, and necessary so that \"T\" can always bind to \"const T&\".\ntemplate <typename T>\nstruct ConstRef {\n  typedef const T& type;\n};\ntemplate <typename T>\nstruct ConstRef<T&> {\n  typedef T& type;\n};\n\n// The argument T must depend on some template parameters.\n#define GTEST_REFERENCE_TO_CONST_(T) \\\n  typename ::testing::internal::ConstRef<T>::type\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Use ImplicitCast_ as a safe version of static_cast for upcasting in\n// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a\n// const Foo*).  When you use ImplicitCast_, the compiler checks that\n// the cast is safe.  Such explicit ImplicitCast_s are necessary in\n// surprisingly many situations where C++ demands an exact type match\n// instead of an argument type convertible to a target type.\n//\n// The syntax for using ImplicitCast_ is the same as for static_cast:\n//\n//   ImplicitCast_<ToType>(expr)\n//\n// ImplicitCast_ would have been part of the C++ standard library,\n// but the proposal was submitted too late.  It will probably make\n// its way into the language in the future.\n//\n// This relatively ugly name is intentional. It prevents clashes with\n// similar functions users may have (e.g., implicit_cast). The internal\n// namespace alone is not enough because the function can be found by ADL.\ntemplate <typename To>\ninline To ImplicitCast_(To x) {\n  return x;\n}\n\n// Downcasts the pointer of type Base to Derived.\n// Derived must be a subclass of Base. The parameter MUST\n// point to a class of type Derived, not any subclass of it.\n// When RTTI is available, the function performs a runtime\n// check to enforce this.\ntemplate <class Derived, class Base>\nDerived* CheckedDowncastToActualType(Base* base) {\n  static_assert(std::is_base_of<Base, Derived>::value,\n                \"target type not derived from source type\");\n#if GTEST_HAS_RTTI\n  GTEST_CHECK_(base == nullptr || dynamic_cast<Derived*>(base) != nullptr);\n#endif\n  return static_cast<Derived*>(base);\n}\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Defines the stderr capturer:\n//   CaptureStdout     - starts capturing stdout.\n//   GetCapturedStdout - stops capturing stdout and returns the captured string.\n//   CaptureStderr     - starts capturing stderr.\n//   GetCapturedStderr - stops capturing stderr and returns the captured string.\n//\nGTEST_API_ void CaptureStdout();\nGTEST_API_ std::string GetCapturedStdout();\nGTEST_API_ void CaptureStderr();\nGTEST_API_ std::string GetCapturedStderr();\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n// Returns the size (in bytes) of a file.\nGTEST_API_ size_t GetFileSize(FILE* file);\n\n// Reads the entire content of a file as a string.\nGTEST_API_ std::string ReadEntireFile(FILE* file);\n\n// All command line arguments.\nGTEST_API_ std::vector<std::string> GetArgvs();\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nstd::vector<std::string> GetInjectableArgvs();\n// Deprecated: pass the args vector by value instead.\nvoid SetInjectableArgvs(const std::vector<std::string>* new_argvs);\nvoid SetInjectableArgvs(const std::vector<std::string>& new_argvs);\nvoid ClearInjectableArgvs();\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Defines synchronization primitives.\n#ifdef GTEST_IS_THREADSAFE\n\n#ifdef GTEST_OS_WINDOWS\n// Provides leak-safe Windows kernel handle ownership.\n// Used in death tests and in threading support.\nclass GTEST_API_ AutoHandle {\n public:\n  // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to\n  // avoid including <windows.h> in this header file. Including <windows.h> is\n  // undesirable because it defines a lot of symbols and macros that tend to\n  // conflict with client code. This assumption is verified by\n  // WindowsTypesTest.HANDLEIsVoidStar.\n  typedef void* Handle;\n  AutoHandle();\n  explicit AutoHandle(Handle handle);\n\n  ~AutoHandle();\n\n  Handle Get() const;\n  void Reset();\n  void Reset(Handle handle);\n\n private:\n  // Returns true if and only if the handle is a valid handle object that can be\n  // closed.\n  bool IsCloseable() const;\n\n  Handle handle_;\n\n  AutoHandle(const AutoHandle&) = delete;\n  AutoHandle& operator=(const AutoHandle&) = delete;\n};\n#endif\n\n#if GTEST_HAS_NOTIFICATION_\n// Notification has already been imported into the namespace.\n// Nothing to do here.\n\n#else\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Allows a controller thread to pause execution of newly created\n// threads until notified.  Instances of this class must be created\n// and destroyed in the controller thread.\n//\n// This class is only for testing Google Test's own constructs. Do not\n// use it in user tests, either directly or indirectly.\n// TODO(b/203539622): Replace unconditionally with absl::Notification.\nclass GTEST_API_ Notification {\n public:\n  Notification() : notified_(false) {}\n  Notification(const Notification&) = delete;\n  Notification& operator=(const Notification&) = delete;\n\n  // Notifies all threads created with this notification to start. Must\n  // be called from the controller thread.\n  void Notify() {\n    std::lock_guard<std::mutex> lock(mu_);\n    notified_ = true;\n    cv_.notify_all();\n  }\n\n  // Blocks until the controller thread notifies. Must be called from a test\n  // thread.\n  void WaitForNotification() {\n    std::unique_lock<std::mutex> lock(mu_);\n    cv_.wait(lock, [this]() { return notified_; });\n  }\n\n private:\n  std::mutex mu_;\n  std::condition_variable cv_;\n  bool notified_;\n};\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n#endif  // GTEST_HAS_NOTIFICATION_\n\n// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD\n// defined, but we don't want to use MinGW's pthreads implementation, which\n// has conformance problems with some versions of the POSIX standard.\n#if GTEST_HAS_PTHREAD && !defined(GTEST_OS_WINDOWS_MINGW)\n\n// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.\n// Consequently, it cannot select a correct instantiation of ThreadWithParam\n// in order to call its Run(). Introducing ThreadWithParamBase as a\n// non-templated base class for ThreadWithParam allows us to bypass this\n// problem.\nclass ThreadWithParamBase {\n public:\n  virtual ~ThreadWithParamBase() = default;\n  virtual void Run() = 0;\n};\n\n// pthread_create() accepts a pointer to a function type with the C linkage.\n// According to the Standard (7.5/1), function types with different linkages\n// are different even if they are otherwise identical.  Some compilers (for\n// example, SunStudio) treat them as different types.  Since class methods\n// cannot be defined with C-linkage we need to define a free C-function to\n// pass into pthread_create().\nextern \"C\" inline void* ThreadFuncWithCLinkage(void* thread) {\n  static_cast<ThreadWithParamBase*>(thread)->Run();\n  return nullptr;\n}\n\n// Helper class for testing Google Test's multi-threading constructs.\n// To use it, write:\n//\n//   void ThreadFunc(int param) { /* Do things with param */ }\n//   Notification thread_can_start;\n//   ...\n//   // The thread_can_start parameter is optional; you can supply NULL.\n//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);\n//   thread_can_start.Notify();\n//\n// These classes are only for testing Google Test's own constructs. Do\n// not use them in user tests, either directly or indirectly.\ntemplate <typename T>\nclass ThreadWithParam : public ThreadWithParamBase {\n public:\n  typedef void UserThreadFunc(T);\n\n  ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)\n      : func_(func),\n        param_(param),\n        thread_can_start_(thread_can_start),\n        finished_(false) {\n    ThreadWithParamBase* const base = this;\n    // The thread can be created only after all fields except thread_\n    // have been initialized.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base));\n  }\n  ~ThreadWithParam() override { Join(); }\n\n  void Join() {\n    if (!finished_) {\n      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr));\n      finished_ = true;\n    }\n  }\n\n  void Run() override {\n    if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification();\n    func_(param_);\n  }\n\n private:\n  UserThreadFunc* const func_;  // User-supplied thread function.\n  const T param_;  // User-supplied parameter to the thread function.\n  // When non-NULL, used to block execution until the controller thread\n  // notifies.\n  Notification* const thread_can_start_;\n  bool finished_;  // true if and only if we know that the thread function has\n                   // finished.\n  pthread_t thread_;  // The native thread object.\n\n  ThreadWithParam(const ThreadWithParam&) = delete;\n  ThreadWithParam& operator=(const ThreadWithParam&) = delete;\n};\n#endif  // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD ||\n        // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n\n#if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n// Mutex and ThreadLocal have already been imported into the namespace.\n// Nothing to do here.\n\n#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT)\n\n// Mutex implements mutex on Windows platforms.  It is used in conjunction\n// with class MutexLock:\n//\n//   Mutex mutex;\n//   ...\n//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the\n//                            // end of the current scope.\n//\n// A static Mutex *must* be defined or declared using one of the following\n// macros:\n//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);\n//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);\n//\n// (A non-static Mutex is defined/declared in the usual way).\nclass GTEST_API_ Mutex {\n public:\n  enum MutexType { kStatic = 0, kDynamic = 1 };\n  // We rely on kStaticMutex being 0 as it is to what the linker initializes\n  // type_ in static mutexes.  critical_section_ will be initialized lazily\n  // in ThreadSafeLazyInit().\n  enum StaticConstructorSelector { kStaticMutex = 0 };\n\n  // This constructor intentionally does nothing.  It relies on type_ being\n  // statically initialized to 0 (effectively setting it to kStatic) and on\n  // ThreadSafeLazyInit() to lazily initialize the rest of the members.\n  explicit Mutex(StaticConstructorSelector /*dummy*/) {}\n\n  Mutex();\n  ~Mutex();\n\n  void Lock();\n\n  void Unlock();\n\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\n  // with high probability.\n  void AssertHeld();\n\n private:\n  // Initializes owner_thread_id_ and critical_section_ in static mutexes.\n  void ThreadSafeLazyInit();\n\n  // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503,\n  // we assume that 0 is an invalid value for thread IDs.\n  unsigned int owner_thread_id_;\n\n  // For static mutexes, we rely on these members being initialized to zeros\n  // by the linker.\n  MutexType type_;\n  long critical_section_init_phase_;  // NOLINT\n  GTEST_CRITICAL_SECTION* critical_section_;\n\n  Mutex(const Mutex&) = delete;\n  Mutex& operator=(const Mutex&) = delete;\n};\n\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::Mutex mutex\n\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\n  ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex)\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }\n\n  ~GTestMutexLock() { mutex_->Unlock(); }\n\n private:\n  Mutex* const mutex_;\n\n  GTestMutexLock(const GTestMutexLock&) = delete;\n  GTestMutexLock& operator=(const GTestMutexLock&) = delete;\n};\n\ntypedef GTestMutexLock MutexLock;\n\n// Base class for ValueHolder<T>.  Allows a caller to hold and delete a value\n// without knowing its type.\nclass ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() {}\n};\n\n// Provides a way for a thread to send notifications to a ThreadLocal\n// regardless of its parameter type.\nclass ThreadLocalBase {\n public:\n  // Creates a new ValueHolder<T> object holding a default value passed to\n  // this ThreadLocal<T>'s constructor and returns it.  It is the caller's\n  // responsibility not to call this when the ThreadLocal<T> instance already\n  // has a value on the current thread.\n  virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;\n\n protected:\n  ThreadLocalBase() {}\n  virtual ~ThreadLocalBase() {}\n\n private:\n  ThreadLocalBase(const ThreadLocalBase&) = delete;\n  ThreadLocalBase& operator=(const ThreadLocalBase&) = delete;\n};\n\n// Maps a thread to a set of ThreadLocals that have values instantiated on that\n// thread and notifies them when the thread exits.  A ThreadLocal instance is\n// expected to persist until all threads it has values on have terminated.\nclass GTEST_API_ ThreadLocalRegistry {\n public:\n  // Registers thread_local_instance as having value on the current thread.\n  // Returns a value that can be used to identify the thread from other threads.\n  static ThreadLocalValueHolderBase* GetValueOnCurrentThread(\n      const ThreadLocalBase* thread_local_instance);\n\n  // Invoked when a ThreadLocal instance is destroyed.\n  static void OnThreadLocalDestroyed(\n      const ThreadLocalBase* thread_local_instance);\n};\n\nclass GTEST_API_ ThreadWithParamBase {\n public:\n  void Join();\n\n protected:\n  class Runnable {\n   public:\n    virtual ~Runnable() {}\n    virtual void Run() = 0;\n  };\n\n  ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start);\n  virtual ~ThreadWithParamBase();\n\n private:\n  AutoHandle thread_;\n};\n\n// Helper class for testing Google Test's multi-threading constructs.\ntemplate <typename T>\nclass ThreadWithParam : public ThreadWithParamBase {\n public:\n  typedef void UserThreadFunc(T);\n\n  ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)\n      : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}\n  virtual ~ThreadWithParam() {}\n\n private:\n  class RunnableImpl : public Runnable {\n   public:\n    RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}\n    virtual ~RunnableImpl() {}\n    virtual void Run() { func_(param_); }\n\n   private:\n    UserThreadFunc* const func_;\n    const T param_;\n\n    RunnableImpl(const RunnableImpl&) = delete;\n    RunnableImpl& operator=(const RunnableImpl&) = delete;\n  };\n\n  ThreadWithParam(const ThreadWithParam&) = delete;\n  ThreadWithParam& operator=(const ThreadWithParam&) = delete;\n};\n\n// Implements thread-local storage on Windows systems.\n//\n//   // Thread 1\n//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.\n//\n//   // Thread 2\n//   tl.set(150);  // Changes the value for thread 2 only.\n//   EXPECT_EQ(150, tl.get());\n//\n//   // Thread 1\n//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.\n//   tl.set(200);\n//   EXPECT_EQ(200, tl.get());\n//\n// The template type argument T must have a public copy constructor.\n// In addition, the default ThreadLocal constructor requires T to have\n// a public default constructor.\n//\n// The users of a TheadLocal instance have to make sure that all but one\n// threads (including the main one) using that instance have exited before\n// destroying it. Otherwise, the per-thread objects managed for them by the\n// ThreadLocal instance are not guaranteed to be destroyed on all platforms.\n//\n// Google Test only uses global ThreadLocal objects.  That means they\n// will die after main() has returned.  Therefore, no per-thread\n// object managed by Google Test will be leaked as long as all threads\n// using Google Test have exited when main() returns.\ntemplate <typename T>\nclass ThreadLocal : public ThreadLocalBase {\n public:\n  ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}\n  explicit ThreadLocal(const T& value)\n      : default_factory_(new InstanceValueHolderFactory(value)) {}\n\n  ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of T.  Can be deleted via its base class without the caller\n  // knowing the type of T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    ValueHolder() : value_() {}\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    ValueHolder(const ValueHolder&) = delete;\n    ValueHolder& operator=(const ValueHolder&) = delete;\n  };\n\n  T* GetOrCreateValue() const {\n    return static_cast<ValueHolder*>(\n               ThreadLocalRegistry::GetValueOnCurrentThread(this))\n        ->pointer();\n  }\n\n  ThreadLocalValueHolderBase* NewValueForCurrentThread() const override {\n    return default_factory_->MakeNewHolder();\n  }\n\n  class ValueHolderFactory {\n   public:\n    ValueHolderFactory() {}\n    virtual ~ValueHolderFactory() {}\n    virtual ValueHolder* MakeNewHolder() const = 0;\n\n   private:\n    ValueHolderFactory(const ValueHolderFactory&) = delete;\n    ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;\n  };\n\n  class DefaultValueHolderFactory : public ValueHolderFactory {\n   public:\n    DefaultValueHolderFactory() {}\n    ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }\n\n   private:\n    DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;\n    DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =\n        delete;\n  };\n\n  class InstanceValueHolderFactory : public ValueHolderFactory {\n   public:\n    explicit InstanceValueHolderFactory(const T& value) : value_(value) {}\n    ValueHolder* MakeNewHolder() const override {\n      return new ValueHolder(value_);\n    }\n\n   private:\n    const T value_;  // The value for each thread.\n\n    InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;\n    InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =\n        delete;\n  };\n\n  std::unique_ptr<ValueHolderFactory> default_factory_;\n\n  ThreadLocal(const ThreadLocal&) = delete;\n  ThreadLocal& operator=(const ThreadLocal&) = delete;\n};\n\n#elif GTEST_HAS_PTHREAD\n\n// MutexBase and Mutex implement mutex on pthreads-based platforms.\nclass MutexBase {\n public:\n  // Acquires this mutex.\n  void Lock() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));\n    owner_ = pthread_self();\n    has_owner_ = true;\n  }\n\n  // Releases this mutex.\n  void Unlock() {\n    // Since the lock is being released the owner_ field should no longer be\n    // considered valid. We don't protect writing to has_owner_ here, as it's\n    // the caller's responsibility to ensure that the current thread holds the\n    // mutex when this is called.\n    has_owner_ = false;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));\n  }\n\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\n  // with high probability.\n  void AssertHeld() const {\n    GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))\n        << \"The current thread is not holding the mutex @\" << this;\n  }\n\n  // A static mutex may be used before main() is entered.  It may even\n  // be used before the dynamic initialization stage.  Therefore we\n  // must be able to initialize a static mutex object at link time.\n  // This means MutexBase has to be a POD and its member variables\n  // have to be public.\n public:\n  pthread_mutex_t mutex_;  // The underlying pthread mutex.\n  // has_owner_ indicates whether the owner_ field below contains a valid thread\n  // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All\n  // accesses to the owner_ field should be protected by a check of this field.\n  // An alternative might be to memset() owner_ to all zeros, but there's no\n  // guarantee that a zero'd pthread_t is necessarily invalid or even different\n  // from pthread_self().\n  bool has_owner_;\n  pthread_t owner_;  // The thread holding the mutex.\n};\n\n// Forward-declares a static mutex.\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::MutexBase mutex\n\n// Defines and statically (i.e. at link time) initializes a static mutex.\n// The initialization list here does not explicitly initialize each field,\n// instead relying on default initialization for the unspecified fields. In\n// particular, the owner_ field (a pthread_t) is not explicitly initialized.\n// This allows initialization to work whether pthread_t is a scalar or struct.\n// The flag -Wmissing-field-initializers must not be specified for this to work.\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\n  ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}\n\n// The Mutex class can only be used for mutexes created at runtime. It\n// shares its API with MutexBase otherwise.\nclass Mutex : public MutexBase {\n public:\n  Mutex() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));\n    has_owner_ = false;\n  }\n  ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }\n\n private:\n  Mutex(const Mutex&) = delete;\n  Mutex& operator=(const Mutex&) = delete;\n};\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }\n\n  ~GTestMutexLock() { mutex_->Unlock(); }\n\n private:\n  MutexBase* const mutex_;\n\n  GTestMutexLock(const GTestMutexLock&) = delete;\n  GTestMutexLock& operator=(const GTestMutexLock&) = delete;\n};\n\ntypedef GTestMutexLock MutexLock;\n\n// Helpers for ThreadLocal.\n\n// pthread_key_create() requires DeleteThreadLocalValue() to have\n// C-linkage.  Therefore it cannot be templatized to access\n// ThreadLocal<T>.  Hence the need for class\n// ThreadLocalValueHolderBase.\nclass GTEST_API_ ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() = default;\n};\n\n// Called by pthread to delete thread-local data stored by\n// pthread_setspecific().\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\n}\n\n// Implements thread-local storage on pthreads-based systems.\ntemplate <typename T>\nclass GTEST_API_ ThreadLocal {\n public:\n  ThreadLocal()\n      : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}\n  explicit ThreadLocal(const T& value)\n      : key_(CreateKey()),\n        default_factory_(new InstanceValueHolderFactory(value)) {}\n\n  ~ThreadLocal() {\n    // Destroys the managed object for the current thread, if any.\n    DeleteThreadLocalValue(pthread_getspecific(key_));\n\n    // Releases resources associated with the key.  This will *not*\n    // delete managed objects for other threads.\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));\n  }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of type T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    ValueHolder() : value_() {}\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    ValueHolder(const ValueHolder&) = delete;\n    ValueHolder& operator=(const ValueHolder&) = delete;\n  };\n\n  static pthread_key_t CreateKey() {\n    pthread_key_t key;\n    // When a thread exits, DeleteThreadLocalValue() will be called on\n    // the object managed for that thread.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_key_create(&key, &DeleteThreadLocalValue));\n    return key;\n  }\n\n  T* GetOrCreateValue() const {\n    ThreadLocalValueHolderBase* const holder =\n        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));\n    if (holder != nullptr) {\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\n    }\n\n    ValueHolder* const new_holder = default_factory_->MakeNewHolder();\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));\n    return new_holder->pointer();\n  }\n\n  class ValueHolderFactory {\n   public:\n    ValueHolderFactory() = default;\n    virtual ~ValueHolderFactory() = default;\n    virtual ValueHolder* MakeNewHolder() const = 0;\n\n   private:\n    ValueHolderFactory(const ValueHolderFactory&) = delete;\n    ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;\n  };\n\n  class DefaultValueHolderFactory : public ValueHolderFactory {\n   public:\n    DefaultValueHolderFactory() = default;\n    ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }\n\n   private:\n    DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;\n    DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =\n        delete;\n  };\n\n  class InstanceValueHolderFactory : public ValueHolderFactory {\n   public:\n    explicit InstanceValueHolderFactory(const T& value) : value_(value) {}\n    ValueHolder* MakeNewHolder() const override {\n      return new ValueHolder(value_);\n    }\n\n   private:\n    const T value_;  // The value for each thread.\n\n    InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;\n    InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =\n        delete;\n  };\n\n  // A key pthreads uses for looking up per-thread values.\n  const pthread_key_t key_;\n  std::unique_ptr<ValueHolderFactory> default_factory_;\n\n  ThreadLocal(const ThreadLocal&) = delete;\n  ThreadLocal& operator=(const ThreadLocal&) = delete;\n};\n\n#endif  // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n\n#else  // GTEST_IS_THREADSAFE\n\n// A dummy implementation of synchronization primitives (mutex, lock,\n// and thread-local variable).  Necessary for compiling Google Test where\n// mutex is not supported - using Google Test in multiple threads is not\n// supported on such platforms.\n\nclass Mutex {\n public:\n  Mutex() {}\n  void Lock() {}\n  void Unlock() {}\n  void AssertHeld() const {}\n};\n\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::Mutex mutex\n\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(Mutex*) {}  // NOLINT\n};\n\ntypedef GTestMutexLock MutexLock;\n\ntemplate <typename T>\nclass GTEST_API_ ThreadLocal {\n public:\n  ThreadLocal() : value_() {}\n  explicit ThreadLocal(const T& value) : value_(value) {}\n  T* pointer() { return &value_; }\n  const T* pointer() const { return &value_; }\n  const T& get() const { return value_; }\n  void set(const T& value) { value_ = value; }\n\n private:\n  T value_;\n};\n\n#endif  // GTEST_IS_THREADSAFE\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nGTEST_API_ size_t GetThreadCount();\n\n#ifdef GTEST_OS_WINDOWS\n#define GTEST_PATH_SEP_ \"\\\\\"\n#define GTEST_HAS_ALT_PATH_SEP_ 1\n#else\n#define GTEST_PATH_SEP_ \"/\"\n#define GTEST_HAS_ALT_PATH_SEP_ 0\n#endif  // GTEST_OS_WINDOWS\n\n// Utilities for char.\n\n// isspace(int ch) and friends accept an unsigned char or EOF.  char\n// may be signed, depending on the compiler (or compiler flags).\n// Therefore we need to cast a char to unsigned char before calling\n// isspace(), etc.\n\ninline bool IsAlpha(char ch) {\n  return isalpha(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsAlNum(char ch) {\n  return isalnum(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsDigit(char ch) {\n  return isdigit(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsLower(char ch) {\n  return islower(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsSpace(char ch) {\n  return isspace(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsUpper(char ch) {\n  return isupper(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsXDigit(char ch) {\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\n}\n#ifdef __cpp_lib_char8_t\ninline bool IsXDigit(char8_t ch) {\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\n}\n#endif\ninline bool IsXDigit(char16_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\ninline bool IsXDigit(char32_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\ninline bool IsXDigit(wchar_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\n\ninline char ToLower(char ch) {\n  return static_cast<char>(tolower(static_cast<unsigned char>(ch)));\n}\ninline char ToUpper(char ch) {\n  return static_cast<char>(toupper(static_cast<unsigned char>(ch)));\n}\n\ninline std::string StripTrailingSpaces(std::string str) {\n  std::string::iterator it = str.end();\n  while (it != str.begin() && IsSpace(*--it)) it = str.erase(it);\n  return str;\n}\n\n// The testing::internal::posix namespace holds wrappers for common\n// POSIX functions.  These wrappers hide the differences between\n// Windows/MSVC and POSIX systems.  Since some compilers define these\n// standard functions as macros, the wrapper cannot have the same name\n// as the wrapped function.\n\nnamespace posix {\n\n// File system porting.\n// Note: Not every I/O-related function is related to file systems, so don't\n// just disable all of them here. For example, fileno() and isatty(), etc. must\n// always be available in order to detect if a pipe points to a terminal.\n#ifdef GTEST_OS_WINDOWS\n\ntypedef struct _stat StatStruct;\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\ninline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }\n// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this\n// time and thus not defined there.\n#else\ninline int FileNo(FILE* file) { return _fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }\ninline int RmDir(const char* dir) { return _rmdir(dir); }\ninline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }\n#endif\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n#elif defined(GTEST_OS_ESP8266)\ntypedef struct stat StatStruct;\n\ninline int FileNo(FILE* file) { return fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) {\n  // stat function not implemented on ESP8266\n  return 0;\n}\ninline int RmDir(const char* dir) { return rmdir(dir); }\ninline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }\n#endif\n\n#else\n\ntypedef struct stat StatStruct;\n\ninline int FileNo(FILE* file) { return fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }\n#ifdef GTEST_OS_QURT\n// QuRT doesn't support any directory functions, including rmdir\ninline int RmDir(const char*) { return 0; }\n#else\ninline int RmDir(const char* dir) { return rmdir(dir); }\n#endif\ninline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }\n#endif\n\n#endif  // GTEST_OS_WINDOWS\n\n// Other functions with a different name on Windows.\n\n#ifdef GTEST_OS_WINDOWS\n\n#ifdef __BORLANDC__\ninline int DoIsATTY(int fd) { return isatty(fd); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return stricmp(s1, s2);\n}\n#else  // !__BORLANDC__\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_ZOS) || \\\n    defined(GTEST_OS_IOS) || defined(GTEST_OS_WINDOWS_PHONE) ||  \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(ESP_PLATFORM)\ninline int DoIsATTY(int /* fd */) { return 0; }\n#else\ninline int DoIsATTY(int fd) { return _isatty(fd); }\n#endif  // GTEST_OS_WINDOWS_MOBILE\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return _stricmp(s1, s2);\n}\n#endif  // __BORLANDC__\n\n#else\n\ninline int DoIsATTY(int fd) { return isatty(fd); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return strcasecmp(s1, s2);\n}\n\n#endif  // GTEST_OS_WINDOWS\n\ninline int IsATTY(int fd) {\n  // DoIsATTY might change errno (for example ENOTTY in case you redirect stdout\n  // to a file on Linux), which is unexpected, so save the previous value, and\n  // restore it after the call.\n  int savedErrno = errno;\n  int isAttyValue = DoIsATTY(fd);\n  errno = savedErrno;\n\n  return isAttyValue;\n}\n\n// Functions deprecated by MSVC 8.0.\n\nGTEST_DISABLE_MSC_DEPRECATED_PUSH_()\n\n// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and\n// StrError() aren't needed on Windows CE at this time and thus not\n// defined there.\n#if GTEST_HAS_FILE_SYSTEM\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) &&     \\\n    !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) &&               \\\n    !defined(GTEST_OS_QURT)\ninline int ChDir(const char* dir) { return chdir(dir); }\n#endif\ninline FILE* FOpen(const char* path, const char* mode) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW)\n  struct wchar_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t> {};\n  std::wstring_convert<wchar_codecvt> converter;\n  std::wstring wide_path = converter.from_bytes(path);\n  std::wstring wide_mode = converter.from_bytes(mode);\n  return _wfopen(wide_path.c_str(), wide_mode.c_str());\n#else   // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW\n  return fopen(path, mode);\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW\n}\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline FILE* FReopen(const char* path, const char* mode, FILE* stream) {\n  return freopen(path, mode, stream);\n}\ninline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\ninline int FClose(FILE* fp) { return fclose(fp); }\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline int Read(int fd, void* buf, unsigned int count) {\n  return static_cast<int>(read(fd, buf, count));\n}\ninline int Write(int fd, const void* buf, unsigned int count) {\n  return static_cast<int>(write(fd, buf, count));\n}\ninline int Close(int fd) { return close(fd); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline const char* StrError(int errnum) { return strerror(errnum); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\n\ninline const char* GetEnv(const char* name) {\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) ||               \\\n    defined(GTEST_OS_QURT)\n  // We are on an embedded platform, which has no environment variables.\n  static_cast<void>(name);  // To prevent 'unused argument' warning.\n  return nullptr;\n#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)\n  // Environment variables which we programmatically clear will be set to the\n  // empty string rather than unset (NULL).  Handle that case.\n  const char* const env = getenv(name);\n  return (env != nullptr && env[0] != '\\0') ? env : nullptr;\n#else\n  return getenv(name);\n#endif\n}\n\nGTEST_DISABLE_MSC_DEPRECATED_POP_()\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Windows CE has no C library. The abort() function is used in\n// several places in Google Test. This implementation provides a reasonable\n// imitation of standard behaviour.\n[[noreturn]] void Abort();\n#else\n[[noreturn]] inline void Abort() { abort(); }\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n}  // namespace posix\n\n// MSVC \"deprecates\" snprintf and issues warnings wherever it is used.  In\n// order to avoid these warnings, we need to use _snprintf or _snprintf_s on\n// MSVC-based platforms.  We map the GTEST_SNPRINTF_ macro to the appropriate\n// function in order to achieve that.  We use macro definition here because\n// snprintf is a variadic function.\n#if defined(_MSC_VER) && !defined(GTEST_OS_WINDOWS_MOBILE)\n// MSVC 2005 and above support variadic macros.\n#define GTEST_SNPRINTF_(buffer, size, format, ...) \\\n  _snprintf_s(buffer, size, size, format, __VA_ARGS__)\n#elif defined(_MSC_VER)\n// Windows CE does not define _snprintf_s\n#define GTEST_SNPRINTF_ _snprintf\n#else\n#define GTEST_SNPRINTF_ snprintf\n#endif\n\n// The biggest signed integer type the compiler supports.\n//\n// long long is guaranteed to be at least 64-bits in C++11.\nusing BiggestInt = long long;  // NOLINT\n\n// The maximum number a BiggestInt can represent.\nconstexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();\n\n// This template class serves as a compile-time function from size to\n// type.  It maps a size in bytes to a primitive type with that\n// size. e.g.\n//\n//   TypeWithSize<4>::UInt\n//\n// is typedef-ed to be unsigned int (unsigned integer made up of 4\n// bytes).\n//\n// Such functionality should belong to STL, but I cannot find it\n// there.\n//\n// Google Test uses this class in the implementation of floating-point\n// comparison.\n//\n// For now it only handles UInt (unsigned int) as that's all Google Test\n// needs.  Other types can be easily added in the future if need\n// arises.\ntemplate <size_t size>\nclass TypeWithSize {\n public:\n  // This prevents the user from using TypeWithSize<N> with incorrect\n  // values of N.\n  using UInt = void;\n};\n\n// The specialization for size 4.\ntemplate <>\nclass TypeWithSize<4> {\n public:\n  using Int = std::int32_t;\n  using UInt = std::uint32_t;\n};\n\n// The specialization for size 8.\ntemplate <>\nclass TypeWithSize<8> {\n public:\n  using Int = std::int64_t;\n  using UInt = std::uint64_t;\n};\n\n// Integer types of known sizes.\nusing TimeInMillis = int64_t;  // Represents time in milliseconds.\n\n// Utilities for command line flags and environment variables.\n\n// Macro for referencing flags.\n#if !defined(GTEST_FLAG)\n#define GTEST_FLAG_NAME_(name) gtest_##name\n#define GTEST_FLAG(name) FLAGS_gtest_##name\n#endif  // !defined(GTEST_FLAG)\n\n// Pick a command line flags implementation.\n#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Macros for defining flags.\n#define GTEST_DEFINE_bool_(name, default_val, doc) \\\n  ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc)\n#define GTEST_DEFINE_int32_(name, default_val, doc) \\\n  ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc)\n#define GTEST_DEFINE_string_(name, default_val, doc) \\\n  ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc)\n\n// Macros for declaring flags.\n#define GTEST_DECLARE_bool_(name) \\\n  ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))\n#define GTEST_DECLARE_int32_(name) \\\n  ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))\n#define GTEST_DECLARE_string_(name) \\\n  ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))\n\n#define GTEST_FLAG_SAVER_ ::absl::FlagSaver\n\n#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name))\n#define GTEST_FLAG_SET(name, value) \\\n  (void)(::absl::SetFlag(&GTEST_FLAG(name), value))\n#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0\n\n#undef GTEST_INTERNAL_HAS_ABSL_FLAGS\n#else  // ndef GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Macros for defining flags.\n#define GTEST_DEFINE_bool_(name, default_val, doc)  \\\n  namespace testing {                               \\\n  GTEST_API_ bool GTEST_FLAG(name) = (default_val); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DEFINE_int32_(name, default_val, doc)         \\\n  namespace testing {                                       \\\n  GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \\\n  }                                                         \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DEFINE_string_(name, default_val, doc)         \\\n  namespace testing {                                        \\\n  GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \\\n  }                                                          \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n// Macros for declaring flags.\n#define GTEST_DECLARE_bool_(name)          \\\n  namespace testing {                      \\\n  GTEST_API_ extern bool GTEST_FLAG(name); \\\n  }                                        \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DECLARE_int32_(name)                 \\\n  namespace testing {                              \\\n  GTEST_API_ extern std::int32_t GTEST_FLAG(name); \\\n  }                                                \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DECLARE_string_(name)                 \\\n  namespace testing {                               \\\n  GTEST_API_ extern ::std::string GTEST_FLAG(name); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver\n\n#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)\n#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)\n#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1\n\n#endif  // GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Thread annotations\n#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)\n#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)\n#define GTEST_LOCK_EXCLUDED_(locks)\n#endif  // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes the result\n// to *value and returns true; otherwise leaves *value unchanged and returns\n// false.\nGTEST_API_ bool ParseInt32(const Message& src_text, const char* str,\n                           int32_t* value);\n\n// Parses a bool/int32_t/string from the environment variable\n// corresponding to the given Google Test flag.\nbool BoolFromGTestEnv(const char* flag, bool default_val);\nGTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val);\nstd::string OutputFlagAlsoCheckEnvVar();\nconst char* StringFromGTestEnv(const char* flag, const char* default_val);\n\n}  // namespace internal\n}  // namespace testing\n\n#if !defined(GTEST_INTERNAL_DEPRECATED)\n\n// Internal Macro to mark an API deprecated, for googletest usage only\n// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or\n// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of\n// a deprecated entity will trigger a warning when compiled with\n// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).\n// For msvc /W3 option will need to be used\n// Note that for 'other' compilers this macro evaluates to nothing to prevent\n// compilations errors.\n#if defined(_MSC_VER)\n#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))\n#elif defined(__GNUC__)\n#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))\n#else\n#define GTEST_INTERNAL_DEPRECATED(message)\n#endif\n\n#endif  // !defined(GTEST_INTERNAL_DEPRECATED)\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::any for UniversalPrinter<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_ANY 1\n#include \"absl/types/any.h\"\nnamespace testing {\nnamespace internal {\nusing Any = ::absl::any;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) &&        \\\n                               GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \\\n                               (!defined(_MSC_VER) || GTEST_HAS_RTTI))\n// Otherwise for C++17 and higher use std::any for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_ANY 1\n#include <any>\nnamespace testing {\nnamespace internal {\nusing Any = ::std::any;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::any is not\n// supported.\n#endif  // __cpp_lib_any\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_ANY\n#define GTEST_INTERNAL_HAS_ANY 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::optional for UniversalPrinter<> specializations if\n// googletest is built with absl support.\n#define GTEST_INTERNAL_HAS_OPTIONAL 1\n#include \"absl/types/optional.h\"\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing Optional = ::absl::optional<T>;\ninline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \\\n                                    GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_OPTIONAL 1\n#include <optional>\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing Optional = ::std::optional<T>;\ninline ::std::nullopt_t Nullopt() { return ::std::nullopt; }\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::optional is not\n// supported.\n#endif  // __cpp_lib_optional\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_OPTIONAL\n#define GTEST_INTERNAL_HAS_OPTIONAL 0\n#endif\n\n#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \\\n                                GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)\n#define GTEST_INTERNAL_HAS_STD_SPAN 1\n#endif  // __cpp_lib_span\n\n#ifndef GTEST_INTERNAL_HAS_STD_SPAN\n#define GTEST_INTERNAL_HAS_STD_SPAN 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::string_view for Matcher<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_STRING_VIEW 1\n#include \"absl/strings/string_view.h\"\nnamespace testing {\nnamespace internal {\nusing StringView = ::absl::string_view;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_string_view) ||             \\\n    (GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \\\n     GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::string_view for Matcher<>\n// specializations.\n#define GTEST_INTERNAL_HAS_STRING_VIEW 1\n#include <string_view>\nnamespace testing {\nnamespace internal {\nusing StringView = ::std::string_view;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::string_view is not\n// supported.\n#endif  // __cpp_lib_string_view\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_STRING_VIEW\n#define GTEST_INTERNAL_HAS_STRING_VIEW 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::variant for UniversalPrinter<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_VARIANT 1\n#include \"absl/types/variant.h\"\nnamespace testing {\nnamespace internal {\ntemplate <typename... T>\nusing Variant = ::absl::variant<T...>;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \\\n                                   GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_VARIANT 1\n#include <variant>\nnamespace testing {\nnamespace internal {\ntemplate <typename... T>\nusing Variant = ::std::variant<T...>;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::variant is not supported.\n#endif  // __cpp_lib_variant\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_VARIANT\n#define GTEST_INTERNAL_HAS_VARIANT 0\n#endif\n\n#if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \\\n    (defined(GTEST_INTERNAL_CPLUSPLUS_LANG) &&                        \\\n     GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L)\n#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1\n#endif\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-string.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file declares the String class and functions used internally by\n// Google Test.  They are subject to change without notice. They should not used\n// by code external to Google Test.\n//\n// This header file is #included by gtest-internal.h.\n// It should not be #included by other files.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n\n#ifdef __BORLANDC__\n// string.h is not guaranteed to provide strcpy on C++ Builder.\n#include <mem.h>\n#endif\n\n#include <string.h>\n\n#include <cstdint>\n#include <sstream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\nnamespace internal {\n\n// String - an abstract class holding static string utilities.\nclass GTEST_API_ String {\n public:\n  // Static utility methods\n\n  // Clones a 0-terminated C string, allocating memory using new.  The\n  // caller is responsible for deleting the return value using\n  // delete[].  Returns the cloned string, or NULL if the input is\n  // NULL.\n  //\n  // This is different from strdup() in string.h, which allocates\n  // memory using malloc().\n  static const char* CloneCString(const char* c_str);\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be\n  // able to pass strings to Win32 APIs on CE we need to convert them\n  // to 'Unicode', UTF-16.\n\n  // Creates a UTF-16 wide string from the given ANSI string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the wide string, or NULL if the\n  // input is NULL.\n  //\n  // The wide string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static LPCWSTR AnsiToUtf16(const char* c_str);\n\n  // Creates an ANSI string from the given wide string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the ANSI string, or NULL if the\n  // input is NULL.\n  //\n  // The returned string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static const char* Utf16ToAnsi(LPCWSTR utf16_str);\n#endif\n\n  // Compares two C strings.  Returns true if and only if they have the same\n  // content.\n  //\n  // Unlike strcmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CStringEquals(const char* lhs, const char* rhs);\n\n  // Converts a wide C string to a String using the UTF-8 encoding.\n  // NULL will be converted to \"(null)\".  If an error occurred during\n  // the conversion, \"(failed to convert from wide string)\" is\n  // returned.\n  static std::string ShowWideCString(const wchar_t* wide_c_str);\n\n  // Compares two wide C strings.  Returns true if and only if they have the\n  // same content.\n  //\n  // Unlike wcscmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);\n\n  // Compares two C strings, ignoring case.  Returns true if and only if\n  // they have the same content.\n  //\n  // Unlike strcasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);\n\n  // Compares two wide C strings, ignoring case.  Returns true if and only if\n  // they have the same content.\n  //\n  // Unlike wcscasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL wide C string,\n  // including the empty string.\n  // NB: The implementations on different platforms slightly differ.\n  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n  // environment variable. On GNU platform this method uses wcscasecmp\n  // which compares according to LC_CTYPE category of the current locale.\n  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n  // current locale.\n  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                               const wchar_t* rhs);\n\n  // Returns true if and only if the given string ends with the given suffix,\n  // ignoring case. Any string is considered to end with an empty suffix.\n  static bool EndsWithCaseInsensitive(const std::string& str,\n                                      const std::string& suffix);\n\n  // Formats an int value as \"%02d\".\n  static std::string FormatIntWidth2(int value);  // \"%02d\" for width == 2\n\n  // Formats an int value to given width with leading zeros.\n  static std::string FormatIntWidthN(int value, int width);\n\n  // Formats an int value as \"%X\".\n  static std::string FormatHexInt(int value);\n\n  // Formats an int value as \"%X\".\n  static std::string FormatHexUInt32(uint32_t value);\n\n  // Formats a byte as \"%02X\".\n  static std::string FormatByte(unsigned char value);\n\n private:\n  String();  // Not meant to be instantiated.\n};           // class String\n\n// Gets the content of the stringstream's buffer as an std::string.  Each '\\0'\n// character in the buffer is replaced with \"\\\\0\".\nGTEST_API_ std::string StringStreamToString(::std::stringstream* stream);\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/include/gtest/internal/gtest-type-util.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Type utilities needed for implementing typed and type-parameterized\n// tests.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n\n#include <string>\n#include <type_traits>\n#include <typeinfo>\n\n#include \"gtest/internal/gtest-port.h\"\n\n// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using\n// libstdc++ (which is where cxxabi.h comes from).\n#if GTEST_HAS_CXXABI_H_\n#include <cxxabi.h>\n#elif defined(__HP_aCC)\n#include <acxx_demangle.h>\n#endif  // GTEST_HASH_CXXABI_H_\n\nnamespace testing {\nnamespace internal {\n\n// Canonicalizes a given name with respect to the Standard C++ Library.\n// This handles removing the inline namespace within `std` that is\n// used by various standard libraries (e.g., `std::__1`).  Names outside\n// of namespace std are returned unmodified.\ninline std::string CanonicalizeForStdLibVersioning(std::string s) {\n  static const char prefix[] = \"std::__\";\n  if (s.compare(0, strlen(prefix), prefix) == 0) {\n    std::string::size_type end = s.find(\"::\", strlen(prefix));\n    if (end != s.npos) {\n      // Erase everything between the initial `std` and the second `::`.\n      s.erase(strlen(\"std\"), end - strlen(\"std\"));\n    }\n  }\n\n  // Strip redundant spaces in typename to match MSVC\n  // For example, std::pair<int, bool> -> std::pair<int,bool>\n  static const char to_search[] = \", \";\n  static const char replace_str[] = \",\";\n  size_t pos = 0;\n  while (true) {\n    // Get the next occurrence from the current position\n    pos = s.find(to_search, pos);\n    if (pos == std::string::npos) {\n      break;\n    }\n    // Replace this occurrence of substring\n    s.replace(pos, strlen(to_search), replace_str);\n    pos += strlen(replace_str);\n  }\n  return s;\n}\n\n#if GTEST_HAS_RTTI\n// GetTypeName(const std::type_info&) returns a human-readable name of type T.\ninline std::string GetTypeName(const std::type_info& type) {\n  const char* const name = type.name();\n#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)\n  int status = 0;\n  // gcc's implementation of typeid(T).name() mangles the type name,\n  // so we have to demangle it.\n#if GTEST_HAS_CXXABI_H_\n  using abi::__cxa_demangle;\n#endif  // GTEST_HAS_CXXABI_H_\n  char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);\n  const std::string name_str(status == 0 ? readable_name : name);\n  free(readable_name);\n  return CanonicalizeForStdLibVersioning(name_str);\n#elif defined(_MSC_VER)\n  // Strip struct and class due to differences between\n  // MSVC and other compilers. std::pair<int,bool> is printed as\n  // \"struct std::pair<int,bool>\" when using MSVC vs \"std::pair<int, bool>\" with\n  // other compilers.\n  std::string s = name;\n  // Only strip the leading \"struct \" and \"class \", so uses rfind == 0 to\n  // ensure that\n  if (s.rfind(\"struct \", 0) == 0) {\n    s = s.substr(strlen(\"struct \"));\n  } else if (s.rfind(\"class \", 0) == 0) {\n    s = s.substr(strlen(\"class \"));\n  }\n  return s;\n#else\n  return name;\n#endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC\n}\n#endif  // GTEST_HAS_RTTI\n\n// GetTypeName<T>() returns a human-readable name of type T if and only if\n// RTTI is enabled, otherwise it returns a dummy type name.\n// NB: This function is also used in Google Mock, so don't move it inside of\n// the typed-test-only section below.\ntemplate <typename T>\nstd::string GetTypeName() {\n#if GTEST_HAS_RTTI\n  return GetTypeName(typeid(T));\n#else\n  return \"<type>\";\n#endif  // GTEST_HAS_RTTI\n}\n\n// A unique type indicating an empty node\nstruct None {};\n\n#define GTEST_TEMPLATE_ \\\n  template <typename T> \\\n  class\n\n// The template \"selector\" struct TemplateSel<Tmpl> is used to\n// represent Tmpl, which must be a class template with one type\n// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined\n// as the type Tmpl<T>.  This allows us to actually instantiate the\n// template \"selected\" by TemplateSel<Tmpl>.\n//\n// This trick is necessary for simulating typedef for class templates,\n// which C++ doesn't support directly.\ntemplate <GTEST_TEMPLATE_ Tmpl>\nstruct TemplateSel {\n  template <typename T>\n  struct Bind {\n    typedef Tmpl<T> type;\n  };\n};\n\n#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type\n\ntemplate <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>\nstruct Templates {\n  using Head = TemplateSel<Head_>;\n  using Tail = Templates<Tail_...>;\n};\n\ntemplate <GTEST_TEMPLATE_ Head_>\nstruct Templates<Head_> {\n  using Head = TemplateSel<Head_>;\n  using Tail = None;\n};\n\n// Tuple-like type lists\ntemplate <typename Head_, typename... Tail_>\nstruct Types {\n  using Head = Head_;\n  using Tail = Types<Tail_...>;\n};\n\ntemplate <typename Head_>\nstruct Types<Head_> {\n  using Head = Head_;\n  using Tail = None;\n};\n\n// Helper metafunctions to tell apart a single type from types\n// generated by ::testing::Types\ntemplate <typename... Ts>\nstruct ProxyTypeList {\n  using type = Types<Ts...>;\n};\n\ntemplate <typename>\nstruct is_proxy_type_list : std::false_type {};\n\ntemplate <typename... Ts>\nstruct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};\n\n// Generator which conditionally creates type lists.\n// It recognizes if a requested type list should be created\n// and prevents creating a new type list nested within another one.\ntemplate <typename T>\nstruct GenerateTypeList {\n private:\n  using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,\n                                          ProxyTypeList<T>>::type;\n\n public:\n  using type = typename proxy::type;\n};\n\n}  // namespace internal\n\ntemplate <typename... Ts>\nusing Types = internal::ProxyTypeList<Ts...>;\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-all.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// Google C++ Testing and Mocking Framework (Google Test)\n//\n// Sometimes it's desirable to build Google Test by compiling a single file.\n// This file serves this purpose.\n\n// This line ensures that gtest.h can be compiled on its own, even\n// when it's fused.\n#include \"gtest/gtest.h\"\n\n// The following lines pull in the real gtest *.cc files.\n#include \"src/gtest-assertion-result.cc\"\n#include \"src/gtest-death-test.cc\"\n#include \"src/gtest-filepath.cc\"\n#include \"src/gtest-matchers.cc\"\n#include \"src/gtest-port.cc\"\n#include \"src/gtest-printers.cc\"\n#include \"src/gtest-test-part.cc\"\n#include \"src/gtest-typed-test.cc\"\n#include \"src/gtest.cc\"\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-assertion-result.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file defines the AssertionResult type.\n\n#include \"gtest/gtest-assertion-result.h\"\n\n#include <string>\n#include <utility>\n\n#include \"gtest/gtest-message.h\"\n\nnamespace testing {\n\n// AssertionResult constructors.\n// Used in EXPECT_TRUE/FALSE(assertion_result).\nAssertionResult::AssertionResult(const AssertionResult& other)\n    : success_(other.success_),\n      message_(other.message_ != nullptr\n                   ? new ::std::string(*other.message_)\n                   : static_cast< ::std::string*>(nullptr)) {}\n\n// Swaps two AssertionResults.\nvoid AssertionResult::swap(AssertionResult& other) {\n  using std::swap;\n  swap(success_, other.success_);\n  swap(message_, other.message_);\n}\n\n// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\nAssertionResult AssertionResult::operator!() const {\n  AssertionResult negation(!success_);\n  if (message_ != nullptr) negation << *message_;\n  return negation;\n}\n\n// Makes a successful assertion result.\nAssertionResult AssertionSuccess() { return AssertionResult(true); }\n\n// Makes a failed assertion result.\nAssertionResult AssertionFailure() { return AssertionResult(false); }\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << message.\nAssertionResult AssertionFailure(const Message& message) {\n  return AssertionFailure() << message;\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-death-test.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// This file implements death tests.\n\n#include \"gtest/gtest-death-test.h\"\n\n#include <stdlib.h>\n\n#include <functional>\n#include <memory>\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"gtest/internal/custom/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_HAS_DEATH_TEST\n\n#ifdef GTEST_OS_MAC\n#include <crt_externs.h>\n#endif  // GTEST_OS_MAC\n\n#include <errno.h>\n#include <fcntl.h>\n#include <limits.h>\n\n#ifdef GTEST_OS_LINUX\n#include <signal.h>\n#endif  // GTEST_OS_LINUX\n\n#include <stdarg.h>\n\n#ifdef GTEST_OS_WINDOWS\n#include <windows.h>\n#else\n#include <sys/mman.h>\n#include <sys/wait.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_QNX\n#include <spawn.h>\n#endif  // GTEST_OS_QNX\n\n#ifdef GTEST_OS_FUCHSIA\n#include <lib/fdio/fd.h>\n#include <lib/fdio/io.h>\n#include <lib/fdio/spawn.h>\n#include <lib/zx/channel.h>\n#include <lib/zx/port.h>\n#include <lib/zx/process.h>\n#include <lib/zx/socket.h>\n#include <zircon/processargs.h>\n#include <zircon/syscalls.h>\n#include <zircon/syscalls/policy.h>\n#include <zircon/syscalls/port.h>\n#endif  // GTEST_OS_FUCHSIA\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\n// Constants.\n\n// The default death test style.\n//\n// This is defined in internal/gtest-port.h as \"fast\", but can be overridden by\n// a definition in internal/custom/gtest-port.h. The recommended value, which is\n// used internally at Google, is \"threadsafe\".\nstatic const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;\n\n}  // namespace testing\n\nGTEST_DEFINE_string_(\n    death_test_style,\n    testing::internal::StringFromGTestEnv(\"death_test_style\",\n                                          testing::kDefaultDeathTestStyle),\n    \"Indicates how to run a death test in a forked child process: \"\n    \"\\\"threadsafe\\\" (child process re-executes the test binary \"\n    \"from the beginning, running only the specific death test) or \"\n    \"\\\"fast\\\" (child process runs the death test immediately \"\n    \"after forking).\");\n\nGTEST_DEFINE_bool_(\n    death_test_use_fork,\n    testing::internal::BoolFromGTestEnv(\"death_test_use_fork\", false),\n    \"Instructs to use fork()/_Exit() instead of clone() in death tests. \"\n    \"Ignored and always uses fork() on POSIX systems where clone() is not \"\n    \"implemented. Useful when running under valgrind or similar tools if \"\n    \"those do not support clone(). Valgrind 3.3.1 will just fail if \"\n    \"it sees an unsupported combination of clone() flags. \"\n    \"It is not recommended to use this flag w/o valgrind though it will \"\n    \"work in 99% of the cases. Once valgrind is fixed, this flag will \"\n    \"most likely be removed.\");\n\nGTEST_DEFINE_string_(\n    internal_run_death_test, \"\",\n    \"Indicates the file, line number, temporal index of \"\n    \"the single death test to run, and a file descriptor to \"\n    \"which a success code may be sent, all separated by \"\n    \"the '|' characters.  This flag is specified if and only if the \"\n    \"current process is a sub-process launched for running a thread-safe \"\n    \"death test.  FOR INTERNAL USE ONLY.\");\n\nnamespace testing {\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nnamespace internal {\n\n// Valid only for fast death tests. Indicates the code is running in the\n// child process of a fast style death test.\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\nstatic bool g_in_fast_death_test_child = false;\n#endif\n\n// Returns a Boolean value indicating whether the caller is currently\n// executing in the context of the death test child process.  Tools such as\n// Valgrind heap checkers may need this to modify their behavior in death\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\n// implementation of death tests.  User code MUST NOT use it.\nbool InDeathTestChild() {\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  // On Windows and Fuchsia, death tests are thread-safe regardless of the value\n  // of the death_test_style flag.\n  return !GTEST_FLAG_GET(internal_run_death_test).empty();\n\n#else\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\")\n    return !GTEST_FLAG_GET(internal_run_death_test).empty();\n  else\n    return g_in_fast_death_test_child;\n#endif\n}\n\n}  // namespace internal\n\n// ExitedWithCode constructor.\nExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {}\n\n// ExitedWithCode function-call operator.\nbool ExitedWithCode::operator()(int exit_status) const {\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  return exit_status == exit_code_;\n\n#else\n\n  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;\n\n#endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA\n}\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// KilledBySignal constructor.\nKilledBySignal::KilledBySignal(int signum) : signum_(signum) {}\n\n// KilledBySignal function-call operator.\nbool KilledBySignal::operator()(int exit_status) const {\n#if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)\n  {\n    bool result;\n    if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) {\n      return result;\n    }\n  }\n#endif  // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)\n  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;\n}\n#endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA\n\nnamespace internal {\n\n// Utilities needed for death tests.\n\n// Generates a textual description of a given exit code, in the format\n// specified by wait(2).\nstatic std::string ExitSummary(int exit_code) {\n  Message m;\n\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  m << \"Exited with exit status \" << exit_code;\n\n#else\n\n  if (WIFEXITED(exit_code)) {\n    m << \"Exited with exit status \" << WEXITSTATUS(exit_code);\n  } else if (WIFSIGNALED(exit_code)) {\n    m << \"Terminated by signal \" << WTERMSIG(exit_code);\n  }\n#ifdef WCOREDUMP\n  if (WCOREDUMP(exit_code)) {\n    m << \" (core dumped)\";\n  }\n#endif\n#endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA\n\n  return m.GetString();\n}\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nbool ExitedUnsuccessfully(int exit_status) {\n  return !ExitedWithCode(0)(exit_status);\n}\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// Generates a textual failure message when a death test finds more than\n// one thread running, or cannot determine the number of threads, prior\n// to executing the given statement.  It is the responsibility of the\n// caller not to pass a thread_count of 1.\nstatic std::string DeathTestThreadWarning(size_t thread_count) {\n  Message msg;\n  msg << \"Death tests use fork(), which is unsafe particularly\"\n      << \" in a threaded context. For this test, \" << GTEST_NAME_ << \" \";\n  if (thread_count == 0) {\n    msg << \"couldn't detect the number of threads.\";\n  } else {\n    msg << \"detected \" << thread_count << \" threads.\";\n  }\n  msg << \" See \"\n         \"https://github.com/google/googletest/blob/main/docs/\"\n         \"advanced.md#death-tests-and-threads\"\n      << \" for more explanation and suggested solutions, especially if\"\n      << \" this is the last message you see before your test times out.\";\n  return msg.GetString();\n}\n#endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA\n\n// Flag characters for reporting a death test that did not die.\nstatic const char kDeathTestLived = 'L';\nstatic const char kDeathTestReturned = 'R';\nstatic const char kDeathTestThrew = 'T';\nstatic const char kDeathTestInternalError = 'I';\n\n#ifdef GTEST_OS_FUCHSIA\n\n// File descriptor used for the pipe in the child process.\nstatic const int kFuchsiaReadPipeFd = 3;\n\n#endif\n\n// An enumeration describing all of the possible ways that a death test can\n// conclude.  DIED means that the process died while executing the test\n// code; LIVED means that process lived beyond the end of the test code;\n// RETURNED means that the test statement attempted to execute a return\n// statement, which is not allowed; THREW means that the test statement\n// returned control by throwing an exception.  IN_PROGRESS means the test\n// has not yet concluded.\nenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };\n\n// Routine for aborting the program which is safe to call from an\n// exec-style death test child process, in which case the error\n// message is propagated back to the parent process.  Otherwise, the\n// message is simply printed to stderr.  In either case, the program\n// then exits with status 1.\n[[noreturn]] static void DeathTestAbort(const std::string& message) {\n  // On a POSIX system, this function may be called from a threadsafe-style\n  // death test child process, which operates on a very small stack.  Use\n  // the heap for any additional non-minuscule memory requirements.\n  const InternalRunDeathTestFlag* const flag =\n      GetUnitTestImpl()->internal_run_death_test_flag();\n  if (flag != nullptr) {\n    FILE* parent = posix::FDOpen(flag->write_fd(), \"w\");\n    fputc(kDeathTestInternalError, parent);\n    fprintf(parent, \"%s\", message.c_str());\n    fflush(parent);\n    _Exit(1);\n  } else {\n    fprintf(stderr, \"%s\", message.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n\n// A replacement for CHECK that calls DeathTestAbort if the assertion\n// fails.\n#define GTEST_DEATH_TEST_CHECK_(expression)                              \\\n  do {                                                                   \\\n    if (!::testing::internal::IsTrue(expression)) {                      \\\n      DeathTestAbort(::std::string(\"CHECK failed: File \") + __FILE__ +   \\\n                     \", line \" +                                         \\\n                     ::testing::internal::StreamableToString(__LINE__) + \\\n                     \": \" + #expression);                                \\\n    }                                                                    \\\n  } while (::testing::internal::AlwaysFalse())\n\n// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for\n// evaluating any system call that fulfills two conditions: it must return\n// -1 on failure, and set errno to EINTR when it is interrupted and\n// should be tried again.  The macro expands to a loop that repeatedly\n// evaluates the expression as long as it evaluates to -1 and sets\n// errno to EINTR.  If the expression evaluates to -1 but errno is\n// something other than EINTR, DeathTestAbort is called.\n#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression)                      \\\n  do {                                                                   \\\n    int gtest_retval;                                                    \\\n    do {                                                                 \\\n      gtest_retval = (expression);                                       \\\n    } while (gtest_retval == -1 && errno == EINTR);                      \\\n    if (gtest_retval == -1) {                                            \\\n      DeathTestAbort(::std::string(\"CHECK failed: File \") + __FILE__ +   \\\n                     \", line \" +                                         \\\n                     ::testing::internal::StreamableToString(__LINE__) + \\\n                     \": \" + #expression + \" != -1\");                     \\\n    }                                                                    \\\n  } while (::testing::internal::AlwaysFalse())\n\n// Returns the message describing the last system error in errno.\nstd::string GetLastErrnoDescription() {\n  return errno == 0 ? \"\" : posix::StrError(errno);\n}\n\n// This is called from a death test parent process to read a failure\n// message from the death test child process and log it with the FATAL\n// severity. On Windows, the message is read from a pipe handle. On other\n// platforms, it is read from a file descriptor.\nstatic void FailFromInternalError(int fd) {\n  Message error;\n  char buffer[256];\n  int num_read;\n\n  do {\n    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {\n      buffer[num_read] = '\\0';\n      error << buffer;\n    }\n  } while (num_read == -1 && errno == EINTR);\n\n  if (num_read == 0) {\n    GTEST_LOG_(FATAL) << error.GetString();\n  } else {\n    const int last_error = errno;\n    GTEST_LOG_(FATAL) << \"Error while reading death test internal: \"\n                      << GetLastErrnoDescription() << \" [\" << last_error << \"]\";\n  }\n}\n\n// Death test constructor.  Increments the running death test count\n// for the current test.\nDeathTest::DeathTest() {\n  TestInfo* const info = GetUnitTestImpl()->current_test_info();\n  if (info == nullptr) {\n    DeathTestAbort(\n        \"Cannot run a death test outside of a TEST or \"\n        \"TEST_F construct\");\n  }\n}\n\n// Creates and returns a death test by dispatching to the current\n// death test factory.\nbool DeathTest::Create(const char* statement,\n                       Matcher<const std::string&> matcher, const char* file,\n                       int line, DeathTest** test) {\n  return GetUnitTestImpl()->death_test_factory()->Create(\n      statement, std::move(matcher), file, line, test);\n}\n\nconst char* DeathTest::LastMessage() {\n  return last_death_test_message_.c_str();\n}\n\nvoid DeathTest::set_last_death_test_message(const std::string& message) {\n  last_death_test_message_ = message;\n}\n\nstd::string DeathTest::last_death_test_message_;\n\n// Provides cross platform implementation for some death functionality.\nclass DeathTestImpl : public DeathTest {\n protected:\n  DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)\n      : statement_(a_statement),\n        matcher_(std::move(matcher)),\n        spawned_(false),\n        status_(-1),\n        outcome_(IN_PROGRESS),\n        read_fd_(-1),\n        write_fd_(-1) {}\n\n  // read_fd_ is expected to be closed and cleared by a derived class.\n  ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }\n\n  void Abort(AbortReason reason) override;\n  bool Passed(bool status_ok) override;\n\n  const char* statement() const { return statement_; }\n  bool spawned() const { return spawned_; }\n  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }\n  int status() const { return status_; }\n  void set_status(int a_status) { status_ = a_status; }\n  DeathTestOutcome outcome() const { return outcome_; }\n  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }\n  int read_fd() const { return read_fd_; }\n  void set_read_fd(int fd) { read_fd_ = fd; }\n  int write_fd() const { return write_fd_; }\n  void set_write_fd(int fd) { write_fd_ = fd; }\n\n  // Called in the parent process only. Reads the result code of the death\n  // test child process via a pipe, interprets it to set the outcome_\n  // member, and closes read_fd_.  Outputs diagnostics and terminates in\n  // case of unexpected codes.\n  void ReadAndInterpretStatusByte();\n\n  // Returns stderr output from the child process.\n  virtual std::string GetErrorLogs();\n\n private:\n  // The textual content of the code this object is testing.  This class\n  // doesn't own this string and should not attempt to delete it.\n  const char* const statement_;\n  // A matcher that's expected to match the stderr output by the child process.\n  Matcher<const std::string&> matcher_;\n  // True if the death test child process has been successfully spawned.\n  bool spawned_;\n  // The exit status of the child process.\n  int status_;\n  // How the death test concluded.\n  DeathTestOutcome outcome_;\n  // Descriptor to the read end of the pipe to the child process.  It is\n  // always -1 in the child process.  The child keeps its write end of the\n  // pipe in write_fd_.\n  int read_fd_;\n  // Descriptor to the child's write end of the pipe to the parent process.\n  // It is always -1 in the parent process.  The parent keeps its end of the\n  // pipe in read_fd_.\n  int write_fd_;\n};\n\n// Called in the parent process only. Reads the result code of the death\n// test child process via a pipe, interprets it to set the outcome_\n// member, and closes read_fd_.  Outputs diagnostics and terminates in\n// case of unexpected codes.\nvoid DeathTestImpl::ReadAndInterpretStatusByte() {\n  char flag;\n  int bytes_read;\n\n  // The read() here blocks until data is available (signifying the\n  // failure of the death test) or until the pipe is closed (signifying\n  // its success), so it's okay to call this in the parent before\n  // the child process has exited.\n  do {\n    bytes_read = posix::Read(read_fd(), &flag, 1);\n  } while (bytes_read == -1 && errno == EINTR);\n\n  if (bytes_read == 0) {\n    set_outcome(DIED);\n  } else if (bytes_read == 1) {\n    switch (flag) {\n      case kDeathTestReturned:\n        set_outcome(RETURNED);\n        break;\n      case kDeathTestThrew:\n        set_outcome(THREW);\n        break;\n      case kDeathTestLived:\n        set_outcome(LIVED);\n        break;\n      case kDeathTestInternalError:\n        FailFromInternalError(read_fd());  // Does not return.\n        break;\n      default:\n        GTEST_LOG_(FATAL) << \"Death test child process reported \"\n                          << \"unexpected status byte (\"\n                          << static_cast<unsigned int>(flag) << \")\";\n    }\n  } else {\n    GTEST_LOG_(FATAL) << \"Read from death test child process failed: \"\n                      << GetLastErrnoDescription();\n  }\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));\n  set_read_fd(-1);\n}\n\nstd::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }\n\n// Signals that the death test code which should have exited, didn't.\n// Should be called only in a death test child process.\n// Writes a status byte to the child's status file descriptor, then\n// calls _Exit(1).\nvoid DeathTestImpl::Abort(AbortReason reason) {\n  // The parent process considers the death test to be a failure if\n  // it finds any data in our pipe.  So, here we write a single flag byte\n  // to the pipe, then exit.\n  const char status_ch = reason == TEST_DID_NOT_DIE       ? kDeathTestLived\n                         : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew\n                                                          : kDeathTestReturned;\n\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));\n  // We are leaking the descriptor here because on some platforms (i.e.,\n  // when built as Windows DLL), destructors of global objects will still\n  // run after calling _Exit(). On such systems, write_fd_ will be\n  // indirectly closed from the destructor of UnitTestImpl, causing double\n  // close if it is also closed here. On debug configurations, double close\n  // may assert. As there are no in-process buffers to flush here, we are\n  // relying on the OS to close the descriptor after the process terminates\n  // when the destructors are not run.\n  _Exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)\n}\n\n// Returns an indented copy of stderr output for a death test.\n// This makes distinguishing death test output lines from regular log lines\n// much easier.\nstatic ::std::string FormatDeathTestOutput(const ::std::string& output) {\n  ::std::string ret;\n  for (size_t at = 0;;) {\n    const size_t line_end = output.find('\\n', at);\n    ret += \"[  DEATH   ] \";\n    if (line_end == ::std::string::npos) {\n      ret += output.substr(at);\n      break;\n    }\n    ret += output.substr(at, line_end + 1 - at);\n    at = line_end + 1;\n  }\n  return ret;\n}\n\n// Assesses the success or failure of a death test, using both private\n// members which have previously been set, and one argument:\n//\n// Private data members:\n//   outcome:  An enumeration describing how the death test\n//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test\n//             fails in the latter three cases.\n//   status:   The exit status of the child process. On *nix, it is in the\n//             in the format specified by wait(2). On Windows, this is the\n//             value supplied to the ExitProcess() API or a numeric code\n//             of the exception that terminated the program.\n//   matcher_: A matcher that's expected to match the stderr output by the child\n//             process.\n//\n// Argument:\n//   status_ok: true if exit_status is acceptable in the context of\n//              this particular death test, which fails if it is false\n//\n// Returns true if and only if all of the above conditions are met.  Otherwise,\n// the first failing condition, in the order given above, is the one that is\n// reported. Also sets the last death test message string.\nbool DeathTestImpl::Passed(bool status_ok) {\n  if (!spawned()) return false;\n\n  const std::string error_message = GetErrorLogs();\n\n  bool success = false;\n  Message buffer;\n\n  buffer << \"Death test: \" << statement() << \"\\n\";\n  switch (outcome()) {\n    case LIVED:\n      buffer << \"    Result: failed to die.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case THREW:\n      buffer << \"    Result: threw an exception.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case RETURNED:\n      buffer << \"    Result: illegal return in test statement.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case DIED:\n      if (status_ok) {\n        if (matcher_.Matches(error_message)) {\n          success = true;\n        } else {\n          std::ostringstream stream;\n          matcher_.DescribeTo(&stream);\n          buffer << \"    Result: died but not with expected error.\\n\"\n                 << \"  Expected: \" << stream.str() << \"\\n\"\n                 << \"Actual msg:\\n\"\n                 << FormatDeathTestOutput(error_message);\n        }\n      } else {\n        buffer << \"    Result: died but not with expected exit code:\\n\"\n               << \"            \" << ExitSummary(status()) << \"\\n\"\n               << \"Actual msg:\\n\"\n               << FormatDeathTestOutput(error_message);\n      }\n      break;\n    case IN_PROGRESS:\n    default:\n      GTEST_LOG_(FATAL)\n          << \"DeathTest::Passed somehow called before conclusion of test\";\n  }\n\n  DeathTest::set_last_death_test_message(buffer.GetString());\n  return success;\n}\n\n#ifndef GTEST_OS_WINDOWS\n// Note: The return value points into args, so the return value's lifetime is\n// bound to that of args.\nstatic std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {\n  std::vector<char*> result;\n  result.reserve(args.size() + 1);\n  for (auto& arg : args) {\n    result.push_back(&arg[0]);\n  }\n  result.push_back(nullptr);  // Extra null terminator.\n  return result;\n}\n#endif\n\n#ifdef GTEST_OS_WINDOWS\n// WindowsDeathTest implements death tests on Windows. Due to the\n// specifics of starting new processes on Windows, death tests there are\n// always threadsafe, and Google Test considers the\n// --gtest_death_test_style=fast setting to be equivalent to\n// --gtest_death_test_style=threadsafe there.\n//\n// A few implementation notes:  Like the Linux version, the Windows\n// implementation uses pipes for child-to-parent communication. But due to\n// the specifics of pipes on Windows, some extra steps are required:\n//\n// 1. The parent creates a communication pipe and stores handles to both\n//    ends of it.\n// 2. The parent starts the child and provides it with the information\n//    necessary to acquire the handle to the write end of the pipe.\n// 3. The child acquires the write end of the pipe and signals the parent\n//    using a Windows event.\n// 4. Now the parent can release the write end of the pipe on its side. If\n//    this is done before step 3, the object's reference count goes down to\n//    0 and it is destroyed, preventing the child from acquiring it. The\n//    parent now has to release it, or read operations on the read end of\n//    the pipe will not return when the child terminates.\n// 5. The parent reads child's output through the pipe (outcome code and\n//    any possible error messages) from the pipe, and its stderr and then\n//    determines whether to fail the test.\n//\n// Note: to distinguish Win32 API calls from the local method and function\n// calls, the former are explicitly resolved in the global namespace.\n//\nclass WindowsDeathTest : public DeathTestImpl {\n public:\n  WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                   const char* file, int line)\n      : DeathTestImpl(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n\n  // All of these virtual functions are inherited from DeathTest.\n  virtual int Wait();\n  virtual TestRole AssumeRole();\n\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n  // Handle to the write end of the pipe to the child process.\n  AutoHandle write_handle_;\n  // Child process handle.\n  AutoHandle child_handle_;\n  // Event the child process uses to signal the parent that it has\n  // acquired the handle to the write end of the pipe. After seeing this\n  // event the parent can release its own handles to make sure its\n  // ReadFile() calls return when the child terminates.\n  AutoHandle event_handle_;\n};\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint WindowsDeathTest::Wait() {\n  if (!spawned()) return 0;\n\n  // Wait until the child either signals that it has acquired the write end\n  // of the pipe or it dies.\n  const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()};\n  switch (::WaitForMultipleObjects(2, wait_handles,\n                                   FALSE,  // Waits for any of the handles.\n                                   INFINITE)) {\n    case WAIT_OBJECT_0:\n    case WAIT_OBJECT_0 + 1:\n      break;\n    default:\n      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.\n  }\n\n  // The child has acquired the write end of the pipe or exited.\n  // We release the handle on our side and continue.\n  write_handle_.Reset();\n  event_handle_.Reset();\n\n  ReadAndInterpretStatusByte();\n\n  // Waits for the child process to exit if it haven't already. This\n  // returns immediately if the child has already exited, regardless of\n  // whether previous calls to WaitForMultipleObjects synchronized on this\n  // handle or not.\n  GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 ==\n                          ::WaitForSingleObject(child_handle_.Get(), INFINITE));\n  DWORD status_code;\n  GTEST_DEATH_TEST_CHECK_(\n      ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);\n  child_handle_.Reset();\n  set_status(static_cast<int>(status_code));\n  return status();\n}\n\n// The AssumeRole process for a Windows death test.  It creates a child\n// process with the same executable as the current process to run the\n// death test.  The child process is given the --gtest_filter and\n// --gtest_internal_run_death_test flags such that it knows to run the\n// current death test only.\nDeathTest::TestRole WindowsDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\n    // processing.\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  // WindowsDeathTest uses an anonymous pipe to communicate results of\n  // a death test.\n  SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),\n                                                 nullptr, TRUE};\n  HANDLE read_handle, write_handle;\n  GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,\n                                       &handles_are_inheritable,\n                                       0)  // Default buffer size.\n                          != FALSE);\n  set_read_fd(\n      ::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), O_RDONLY));\n  write_handle_.Reset(write_handle);\n  event_handle_.Reset(::CreateEvent(\n      &handles_are_inheritable,\n      TRUE,       // The event will automatically reset to non-signaled state.\n      FALSE,      // The initial state is non-signalled.\n      nullptr));  // The even is unnamed.\n  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag =\n      std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n      \"internal_run_death_test=\" + file_ + \"|\" + StreamableToString(line_) +\n      \"|\" + StreamableToString(death_test_index) + \"|\" +\n      StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +\n      // size_t has the same width as pointers on both 32-bit and 64-bit\n      // Windows platforms.\n      // See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.\n      \"|\" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + \"|\" +\n      StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));\n\n  char executable_path[_MAX_PATH + 1];  // NOLINT\n  GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,\n                                                                executable_path,\n                                                                _MAX_PATH));\n\n  std::string command_line = std::string(::GetCommandLineA()) + \" \" +\n                             filter_flag + \" \\\"\" + internal_flag + \"\\\"\";\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // Flush the log buffers since the log streams are shared with the child.\n  FlushInfoLog();\n\n  // The child process will share the standard handles with the parent.\n  STARTUPINFOA startup_info;\n  memset(&startup_info, 0, sizeof(STARTUPINFO));\n  startup_info.dwFlags = STARTF_USESTDHANDLES;\n  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);\n  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);\n  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);\n\n  PROCESS_INFORMATION process_info;\n  GTEST_DEATH_TEST_CHECK_(\n      ::CreateProcessA(\n          executable_path, const_cast<char*>(command_line.c_str()),\n          nullptr,  // Returned process handle is not inheritable.\n          nullptr,  // Returned thread handle is not inheritable.\n          TRUE,  // Child inherits all inheritable handles (for write_handle_).\n          0x0,   // Default creation flags.\n          nullptr,  // Inherit the parent's environment.\n          UnitTest::GetInstance()->original_working_dir(), &startup_info,\n          &process_info) != FALSE);\n  child_handle_.Reset(process_info.hProcess);\n  ::CloseHandle(process_info.hThread);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\n#elif defined(GTEST_OS_FUCHSIA)\n\nclass FuchsiaDeathTest : public DeathTestImpl {\n public:\n  FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                   const char* file, int line)\n      : DeathTestImpl(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n\n  // All of these virtual functions are inherited from DeathTest.\n  int Wait() override;\n  TestRole AssumeRole() override;\n  std::string GetErrorLogs() override;\n\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n  // The stderr data captured by the child process.\n  std::string captured_stderr_;\n\n  zx::process child_process_;\n  zx::channel exception_channel_;\n  zx::socket stderr_socket_;\n};\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint FuchsiaDeathTest::Wait() {\n  const int kProcessKey = 0;\n  const int kSocketKey = 1;\n  const int kExceptionKey = 2;\n\n  if (!spawned()) return 0;\n\n  // Create a port to wait for socket/task/exception events.\n  zx_status_t status_zx;\n  zx::port port;\n  status_zx = zx::port::create(0, &port);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for the child process to terminate.\n  status_zx =\n      child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for the socket to be readable or closed.\n  status_zx = stderr_socket_.wait_async(\n      port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for an exception.\n  status_zx = exception_channel_.wait_async(port, kExceptionKey,\n                                            ZX_CHANNEL_READABLE, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  bool process_terminated = false;\n  bool socket_closed = false;\n  do {\n    zx_port_packet_t packet = {};\n    status_zx = port.wait(zx::time::infinite(), &packet);\n    GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n    if (packet.key == kExceptionKey) {\n      // Process encountered an exception. Kill it directly rather than\n      // letting other handlers process the event. We will get a kProcessKey\n      // event when the process actually terminates.\n      status_zx = child_process_.kill();\n      GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n    } else if (packet.key == kProcessKey) {\n      // Process terminated.\n      GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));\n      GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);\n      process_terminated = true;\n    } else if (packet.key == kSocketKey) {\n      GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));\n      if (packet.signal.observed & ZX_SOCKET_READABLE) {\n        // Read data from the socket.\n        constexpr size_t kBufferSize = 1024;\n        do {\n          size_t old_length = captured_stderr_.length();\n          size_t bytes_read = 0;\n          captured_stderr_.resize(old_length + kBufferSize);\n          status_zx =\n              stderr_socket_.read(0, &captured_stderr_.front() + old_length,\n                                  kBufferSize, &bytes_read);\n          captured_stderr_.resize(old_length + bytes_read);\n        } while (status_zx == ZX_OK);\n        if (status_zx == ZX_ERR_PEER_CLOSED) {\n          socket_closed = true;\n        } else {\n          GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);\n          status_zx = stderr_socket_.wait_async(\n              port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);\n          GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n        }\n      } else {\n        GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);\n        socket_closed = true;\n      }\n    }\n  } while (!process_terminated && !socket_closed);\n\n  ReadAndInterpretStatusByte();\n\n  zx_info_process_t buffer;\n  status_zx = child_process_.get_info(ZX_INFO_PROCESS, &buffer, sizeof(buffer),\n                                      nullptr, nullptr);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED);\n  set_status(static_cast<int>(buffer.return_code));\n  return status();\n}\n\n// The AssumeRole process for a Fuchsia death test.  It creates a child\n// process with the same executable as the current process to run the\n// death test.  The child process is given the --gtest_filter and\n// --gtest_internal_run_death_test flags such that it knows to run the\n// current death test only.\nDeathTest::TestRole FuchsiaDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\n    // processing.\n    set_write_fd(kFuchsiaReadPipeFd);\n    return EXECUTE_TEST;\n  }\n\n  // Flush the log buffers since the log streams are shared with the child.\n  FlushInfoLog();\n\n  // Build the child process command line.\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                    kInternalRunDeathTestFlag + \"=\" + file_ +\n                                    \"|\" + StreamableToString(line_) + \"|\" +\n                                    StreamableToString(death_test_index);\n\n  std::vector<std::string> args = GetInjectableArgvs();\n  args.push_back(filter_flag);\n  args.push_back(internal_flag);\n\n  // Build the pipe for communication with the child.\n  zx_status_t status;\n  zx_handle_t child_pipe_handle;\n  int child_pipe_fd;\n  status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n  set_read_fd(child_pipe_fd);\n\n  // Set the pipe handle for the child.\n  fdio_spawn_action_t spawn_actions[2] = {};\n  fdio_spawn_action_t* add_handle_action = &spawn_actions[0];\n  add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;\n  add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd);\n  add_handle_action->h.handle = child_pipe_handle;\n\n  // Create a socket pair will be used to receive the child process' stderr.\n  zx::socket stderr_producer_socket;\n  status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);\n  GTEST_DEATH_TEST_CHECK_(status >= 0);\n  int stderr_producer_fd = -1;\n  status =\n      fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);\n  GTEST_DEATH_TEST_CHECK_(status >= 0);\n\n  // Make the stderr socket nonblocking.\n  GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);\n\n  fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];\n  add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;\n  add_stderr_action->fd.local_fd = stderr_producer_fd;\n  add_stderr_action->fd.target_fd = STDERR_FILENO;\n\n  // Create a child job.\n  zx_handle_t child_job = ZX_HANDLE_INVALID;\n  status = zx_job_create(zx_job_default(), 0, &child_job);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n  zx_policy_basic_t policy;\n  policy.condition = ZX_POL_NEW_ANY;\n  policy.policy = ZX_POL_ACTION_ALLOW;\n  status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC,\n                             &policy, 1);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  // Create an exception channel attached to the |child_job|, to allow\n  // us to suppress the system default exception handler from firing.\n  status = zx_task_create_exception_channel(\n      child_job, 0, exception_channel_.reset_and_get_address());\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  // Spawn the child process.\n  // Note: The test component must have `fuchsia.process.Launcher` declared\n  // in its manifest. (Fuchsia integration tests require creating a\n  // \"Fuchsia Test Component\" which contains a \"Fuchsia Component Manifest\")\n  // Launching processes is a privileged operation in Fuchsia, and the\n  // declaration indicates that the ability is required for the component.\n  std::vector<char*> argv = CreateArgvFromArgs(args);\n  status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),\n                          nullptr, 2, spawn_actions,\n                          child_process_.reset_and_get_address(), nullptr);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\nstd::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; }\n\n#else  // We are neither on Windows, nor on Fuchsia.\n\n// ForkingDeathTest provides implementations for most of the abstract\n// methods of the DeathTest interface.  Only the AssumeRole method is\n// left undefined.\nclass ForkingDeathTest : public DeathTestImpl {\n public:\n  ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);\n\n  // All of these virtual functions are inherited from DeathTest.\n  int Wait() override;\n\n protected:\n  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }\n\n private:\n  // PID of child process during death test; 0 in the child process itself.\n  pid_t child_pid_;\n};\n\n// Constructs a ForkingDeathTest.\nForkingDeathTest::ForkingDeathTest(const char* a_statement,\n                                   Matcher<const std::string&> matcher)\n    : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint ForkingDeathTest::Wait() {\n  if (!spawned()) return 0;\n\n  ReadAndInterpretStatusByte();\n\n  int status_value;\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));\n  set_status(status_value);\n  return status_value;\n}\n\n// A concrete death test class that forks, then immediately runs the test\n// in the child process.\nclass NoExecDeathTest : public ForkingDeathTest {\n public:\n  NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)\n      : ForkingDeathTest(a_statement, std::move(matcher)) {}\n  TestRole AssumeRole() override;\n};\n\n// The AssumeRole process for a fork-and-run death test.  It implements a\n// straightforward fork, with a simple pipe to transmit the status byte.\nDeathTest::TestRole NoExecDeathTest::AssumeRole() {\n  const size_t thread_count = GetThreadCount();\n  if (thread_count != 1) {\n    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n\n  DeathTest::set_last_death_test_message(\"\");\n  CaptureStderr();\n  // When we fork the process below, the log file buffers are copied, but the\n  // file descriptors are shared.  We flush all log files here so that closing\n  // the file descriptors in the child process doesn't throw off the\n  // synchronization between descriptors and buffers in the parent process.\n  // This is as close to the fork as possible to avoid a race condition in case\n  // there are multiple threads running before the death test, and another\n  // thread writes to the log file.\n  FlushInfoLog();\n\n  const pid_t child_pid = fork();\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  set_child_pid(child_pid);\n  if (child_pid == 0) {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));\n    set_write_fd(pipe_fd[1]);\n    // Redirects all logging to stderr in the child process to prevent\n    // concurrent writes to the log files.  We capture stderr in the parent\n    // process and append the child process' output to a log.\n    LogToStderr();\n    // Event forwarding to the listeners of event listener API mush be shut\n    // down in death test subprocesses.\n    GetUnitTestImpl()->listeners()->SuppressEventForwarding(true);\n    g_in_fast_death_test_child = true;\n    return EXECUTE_TEST;\n  } else {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n    set_read_fd(pipe_fd[0]);\n    set_spawned(true);\n    return OVERSEE_TEST;\n  }\n}\n\n// A concrete death test class that forks and re-executes the main\n// program from the beginning, with command-line flags set that cause\n// only this specific death test to be run.\nclass ExecDeathTest : public ForkingDeathTest {\n public:\n  ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                const char* file, int line)\n      : ForkingDeathTest(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n  TestRole AssumeRole() override;\n\n private:\n  static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {\n    ::std::vector<std::string> args = GetInjectableArgvs();\n#if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)\n    ::std::vector<std::string> extra_args =\n        GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();\n    args.insert(args.end(), extra_args.begin(), extra_args.end());\n#endif  // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)\n    return args;\n  }\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n};\n\n// A struct that encompasses the arguments to the child process of a\n// threadsafe-style death test process.\nstruct ExecDeathTestArgs {\n  char* const* argv;  // Command-line arguments for the child's call to exec\n  int close_fd;       // File descriptor to close; the read end of a pipe\n};\n\n#ifdef GTEST_OS_QNX\nextern \"C\" char** environ;\n#else   // GTEST_OS_QNX\n// The main function for a threadsafe-style death test child process.\n// This function is called in a clone()-ed process and thus must avoid\n// any potentially unsafe operations like malloc or libc functions.\nstatic int ExecDeathTestChildMain(void* child_arg) {\n  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));\n\n  // We need to execute the test program in the same environment where\n  // it was originally invoked.  Therefore we change to the original\n  // working directory first.\n  const char* const original_dir =\n      UnitTest::GetInstance()->original_working_dir();\n  // We can safely call chdir() as it's a direct system call.\n  if (chdir(original_dir) != 0) {\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir +\n                   \"\\\") failed: \" + GetLastErrnoDescription());\n    return EXIT_FAILURE;\n  }\n\n  // We can safely call execv() as it's almost a direct system call. We\n  // cannot use execvp() as it's a libc function and thus potentially\n  // unsafe.  Since execv() doesn't search the PATH, the user must\n  // invoke the test program via a valid path that contains at least\n  // one path separator.\n  execv(args->argv[0], args->argv);\n  DeathTestAbort(std::string(\"execv(\") + args->argv[0] + \", ...) in \" +\n                 original_dir + \" failed: \" + GetLastErrnoDescription());\n  return EXIT_FAILURE;\n}\n#endif  // GTEST_OS_QNX\n\n#if GTEST_HAS_CLONE\n// Two utility routines that together determine the direction the stack\n// grows.\n// This could be accomplished more elegantly by a single recursive\n// function, but we want to guard against the unlikely possibility of\n// a smart compiler optimizing the recursion away.\n//\n// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining\n// StackLowerThanAddress into StackGrowsDown, which then doesn't give\n// correct answer.\nstatic void StackLowerThanAddress(const void* ptr,\n                                  bool* result) GTEST_NO_INLINE_;\n// Make sure sanitizers do not tamper with the stack here.\n// Ideally, we want to use `__builtin_frame_address` instead of a local variable\n// address with sanitizer disabled, but it does not work when the\n// compiler optimizes the stack frame out, which happens on PowerPC targets.\n// HWAddressSanitizer add a random tag to the MSB of the local variable address,\n// making comparison result unpredictable.\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nstatic void StackLowerThanAddress(const void* ptr, bool* result) {\n  int dummy = 0;\n  *result = std::less<const void*>()(&dummy, ptr);\n}\n\n// Make sure AddressSanitizer does not tamper with the stack here.\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nstatic bool StackGrowsDown() {\n  int dummy = 0;\n  bool result;\n  StackLowerThanAddress(&dummy, &result);\n  return result;\n}\n#endif  // GTEST_HAS_CLONE\n\n// Spawns a child process with the same executable as the current process in\n// a thread-safe manner and instructs it to run the death test.  The\n// implementation uses fork(2) + exec.  On systems where clone(2) is\n// available, it is used instead, being slightly more thread-safe.  On QNX,\n// fork supports only single-threaded environments, so this function uses\n// spawn(2) there instead.  The function dies with an error message if\n// anything goes wrong.\nstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {\n  ExecDeathTestArgs args = {argv, close_fd};\n  pid_t child_pid = -1;\n\n#ifdef GTEST_OS_QNX\n  // Obtains the current directory and sets it to be closed in the child\n  // process.\n  const int cwd_fd = open(\".\", O_RDONLY);\n  GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));\n  // We need to execute the test program in the same environment where\n  // it was originally invoked.  Therefore we change to the original\n  // working directory first.\n  const char* const original_dir =\n      UnitTest::GetInstance()->original_working_dir();\n  // We can safely call chdir() as it's a direct system call.\n  if (chdir(original_dir) != 0) {\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir +\n                   \"\\\") failed: \" + GetLastErrnoDescription());\n    return EXIT_FAILURE;\n  }\n\n  int fd_flags;\n  // Set close_fd to be closed after spawn.\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC));\n  struct inheritance inherit = {0};\n  // spawn is a system call.\n  child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ);\n  // Restores the current working directory.\n  GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));\n\n#else  // GTEST_OS_QNX\n#ifdef GTEST_OS_LINUX\n  // When a SIGPROF signal is received while fork() or clone() are executing,\n  // the process may hang. To avoid this, we ignore SIGPROF here and re-enable\n  // it after the call to fork()/clone() is complete.\n  struct sigaction saved_sigprof_action;\n  struct sigaction ignore_sigprof_action;\n  memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));\n  sigemptyset(&ignore_sigprof_action.sa_mask);\n  ignore_sigprof_action.sa_handler = SIG_IGN;\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_CLONE\n  const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);\n\n  if (!use_fork) {\n    static const bool stack_grows_down = StackGrowsDown();\n    const auto stack_size = static_cast<size_t>(getpagesize() * 2);\n    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.\n    void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,\n                             MAP_ANON | MAP_PRIVATE, -1, 0);\n    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);\n\n    // Maximum stack alignment in bytes:  For a downward-growing stack, this\n    // amount is subtracted from size of the stack space to get an address\n    // that is within the stack space and is aligned on all systems we care\n    // about.  As far as I know there is no ABI with stack alignment greater\n    // than 64.  We assume stack and stack_size already have alignment of\n    // kMaxStackAlignment.\n    const size_t kMaxStackAlignment = 64;\n    void* const stack_top =\n        static_cast<char*>(stack) +\n        (stack_grows_down ? stack_size - kMaxStackAlignment : 0);\n    GTEST_DEATH_TEST_CHECK_(\n        static_cast<size_t>(stack_size) > kMaxStackAlignment &&\n        reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0);\n\n    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);\n\n    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);\n  }\n#else\n  const bool use_fork = true;\n#endif  // GTEST_HAS_CLONE\n\n  if (use_fork && (child_pid = fork()) == 0) {\n    _Exit(ExecDeathTestChildMain(&args));\n  }\n#endif  // GTEST_OS_QNX\n#ifdef GTEST_OS_LINUX\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      sigaction(SIGPROF, &saved_sigprof_action, nullptr));\n#endif  // GTEST_OS_LINUX\n\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  return child_pid;\n}\n\n// The AssumeRole process for a fork-and-exec death test.  It re-executes the\n// main program from the beginning, setting the --gtest_filter\n// and --gtest_internal_run_death_test flags to cause only the current\n// death test to be re-run.\nDeathTest::TestRole ExecDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n  // Clear the close-on-exec flag on the write end of the pipe, lest\n  // it be closed when the child process does an exec:\n  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);\n\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                    \"internal_run_death_test=\" + file_ + \"|\" +\n                                    StreamableToString(line_) + \"|\" +\n                                    StreamableToString(death_test_index) + \"|\" +\n                                    StreamableToString(pipe_fd[1]);\n  std::vector<std::string> args = GetArgvsForDeathTestChildProcess();\n  args.push_back(filter_flag);\n  args.push_back(internal_flag);\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // See the comment in NoExecDeathTest::AssumeRole for why the next line\n  // is necessary.\n  FlushInfoLog();\n\n  std::vector<char*> argv = CreateArgvFromArgs(args);\n  const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n  set_child_pid(child_pid);\n  set_read_fd(pipe_fd[0]);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\n#endif  // !GTEST_OS_WINDOWS\n\n// Creates a concrete DeathTest-derived class that depends on the\n// --gtest_death_test_style flag, and sets the pointer pointed to\n// by the \"test\" argument to its address.  If the test should be\n// skipped, sets that pointer to NULL.  Returns true, unless the\n// flag is set to an invalid value.\nbool DefaultDeathTestFactory::Create(const char* statement,\n                                     Matcher<const std::string&> matcher,\n                                     const char* file, int line,\n                                     DeathTest** test) {\n  UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const int death_test_index =\n      impl->current_test_info()->increment_death_test_count();\n\n  if (flag != nullptr) {\n    if (death_test_index > flag->index()) {\n      DeathTest::set_last_death_test_message(\n          \"Death test count (\" + StreamableToString(death_test_index) +\n          \") somehow exceeded expected maximum (\" +\n          StreamableToString(flag->index()) + \")\");\n      return false;\n    }\n\n    if (!(flag->file() == file && flag->line() == line &&\n          flag->index() == death_test_index)) {\n      *test = nullptr;\n      return true;\n    }\n  }\n\n#ifdef GTEST_OS_WINDOWS\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\" ||\n      GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new WindowsDeathTest(statement, std::move(matcher), file, line);\n  }\n\n#elif defined(GTEST_OS_FUCHSIA)\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\" ||\n      GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);\n  }\n\n#else\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\") {\n    *test = new ExecDeathTest(statement, std::move(matcher), file, line);\n  } else if (GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new NoExecDeathTest(statement, std::move(matcher));\n  }\n\n#endif  // GTEST_OS_WINDOWS\n\n  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.\n    DeathTest::set_last_death_test_message(\"Unknown death test style \\\"\" +\n                                           GTEST_FLAG_GET(death_test_style) +\n                                           \"\\\" encountered\");\n    return false;\n  }\n\n  return true;\n}\n\n#ifdef GTEST_OS_WINDOWS\n// Recreates the pipe and event handles from the provided parameters,\n// signals the event, and returns a file descriptor wrapped around the pipe\n// handle. This function is called in the child process only.\nstatic int GetStatusFileDescriptor(unsigned int parent_process_id,\n                                   size_t write_handle_as_size_t,\n                                   size_t event_handle_as_size_t) {\n  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,\n                                                 FALSE,  // Non-inheritable.\n                                                 parent_process_id));\n  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {\n    DeathTestAbort(\"Unable to open parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));\n\n  const HANDLE write_handle = reinterpret_cast<HANDLE>(write_handle_as_size_t);\n  HANDLE dup_write_handle;\n\n  // The newly initialized handle is accessible only in the parent\n  // process. To obtain one accessible within the child, we need to use\n  // DuplicateHandle.\n  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,\n                         ::GetCurrentProcess(), &dup_write_handle,\n                         0x0,    // Requested privileges ignored since\n                                 // DUPLICATE_SAME_ACCESS is used.\n                         FALSE,  // Request non-inheritable handler.\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(\"Unable to duplicate the pipe handle \" +\n                   StreamableToString(write_handle_as_size_t) +\n                   \" from the parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);\n  HANDLE dup_event_handle;\n\n  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,\n                         ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE,\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(\"Unable to duplicate the event handle \" +\n                   StreamableToString(event_handle_as_size_t) +\n                   \" from the parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  const int write_fd =\n      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);\n  if (write_fd == -1) {\n    DeathTestAbort(\"Unable to convert pipe handle \" +\n                   StreamableToString(write_handle_as_size_t) +\n                   \" to a file descriptor\");\n  }\n\n  // Signals the parent that the write end of the pipe has been acquired\n  // so the parent can release its own write end.\n  ::SetEvent(dup_event_handle);\n\n  return write_fd;\n}\n#endif  // GTEST_OS_WINDOWS\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {\n  if (GTEST_FLAG_GET(internal_run_death_test).empty()) return nullptr;\n\n  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we\n  // can use it here.\n  int line = -1;\n  int index = -1;\n  ::std::vector< ::std::string> fields;\n  SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);\n  int write_fd = -1;\n\n#ifdef GTEST_OS_WINDOWS\n\n  unsigned int parent_process_id = 0;\n  size_t write_handle_as_size_t = 0;\n  size_t event_handle_as_size_t = 0;\n\n  if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index) ||\n      !ParseNaturalNumber(fields[3], &parent_process_id) ||\n      !ParseNaturalNumber(fields[4], &write_handle_as_size_t) ||\n      !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n  write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t,\n                                     event_handle_as_size_t);\n\n#elif defined(GTEST_OS_FUCHSIA)\n\n  if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n\n#else\n\n  if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index) ||\n      !ParseNaturalNumber(fields[3], &write_fd)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n\n#endif  // GTEST_OS_WINDOWS\n\n  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);\n}\n\n}  // namespace internal\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-filepath.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/internal/gtest-filepath.h\"\n\n#include <stdlib.h>\n\n#include <iterator>\n#include <string>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n#include <windows.h>\n#elif defined(GTEST_OS_WINDOWS)\n#include <direct.h>\n#include <io.h>\n#else\n#include <limits.h>\n\n#include <climits>  // Some Linux distributions define PATH_MAX here.\n#endif              // GTEST_OS_WINDOWS_MOBILE\n\n#include \"gtest/internal/gtest-string.h\"\n\n#ifdef GTEST_OS_WINDOWS\n#define GTEST_PATH_MAX_ _MAX_PATH\n#elif defined(PATH_MAX)\n#define GTEST_PATH_MAX_ PATH_MAX\n#elif defined(_XOPEN_PATH_MAX)\n#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX\n#else\n#define GTEST_PATH_MAX_ _POSIX_PATH_MAX\n#endif  // GTEST_OS_WINDOWS\n\n#if GTEST_HAS_FILE_SYSTEM\n\nnamespace testing {\nnamespace internal {\n\n#ifdef GTEST_OS_WINDOWS\n// On Windows, '\\\\' is the standard path separator, but many tools and the\n// Windows API also accept '/' as an alternate path separator. Unless otherwise\n// noted, a file path can contain either kind of path separators, or a mixture\n// of them.\nconst char kPathSeparator = '\\\\';\nconst char kAlternatePathSeparator = '/';\nconst char kAlternatePathSeparatorString[] = \"/\";\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Windows CE doesn't have a current directory. You should not use\n// the current directory in tests on Windows CE, but this at least\n// provides a reasonable fallback.\nconst char kCurrentDirectoryString[] = \"\\\\\";\n// Windows CE doesn't define INVALID_FILE_ATTRIBUTES\nconst DWORD kInvalidFileAttributes = 0xffffffff;\n#else\nconst char kCurrentDirectoryString[] = \".\\\\\";\n#endif  // GTEST_OS_WINDOWS_MOBILE\n#else\nconst char kPathSeparator = '/';\nconst char kCurrentDirectoryString[] = \"./\";\n#endif  // GTEST_OS_WINDOWS\n\n// Returns whether the given character is a valid path separator.\nstatic bool IsPathSeparator(char c) {\n#if GTEST_HAS_ALT_PATH_SEP_\n  return (c == kPathSeparator) || (c == kAlternatePathSeparator);\n#else\n  return c == kPathSeparator;\n#endif\n}\n\n// Returns the current working directory, or \"\" if unsuccessful.\nFilePath FilePath::GetCurrentDir() {\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) ||           \\\n    defined(GTEST_OS_ESP32) || defined(GTEST_OS_XTENSA) ||                 \\\n    defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) ||              \\\n    defined(GTEST_OS_NRF52)\n  // These platforms do not have a current directory, so we just return\n  // something reasonable.\n  return FilePath(kCurrentDirectoryString);\n#elif defined(GTEST_OS_WINDOWS)\n  char cwd[GTEST_PATH_MAX_ + 1] = {'\\0'};\n  return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? \"\" : cwd);\n#else\n  char cwd[GTEST_PATH_MAX_ + 1] = {'\\0'};\n  char* result = getcwd(cwd, sizeof(cwd));\n#ifdef GTEST_OS_NACL\n  // getcwd will likely fail in NaCl due to the sandbox, so return something\n  // reasonable. The user may have provided a shim implementation for getcwd,\n  // however, so fallback only when failure is detected.\n  return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);\n#endif  // GTEST_OS_NACL\n  return FilePath(result == nullptr ? \"\" : cwd);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns a copy of the FilePath with the case-insensitive extension removed.\n// Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n// FilePath(\"dir/file\"). If a case-insensitive extension is not\n// found, returns a copy of the original FilePath.\nFilePath FilePath::RemoveExtension(const char* extension) const {\n  const std::string dot_extension = std::string(\".\") + extension;\n  if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {\n    return FilePath(\n        pathname_.substr(0, pathname_.length() - dot_extension.length()));\n  }\n  return *this;\n}\n\n// Returns a pointer to the last occurrence of a valid path separator in\n// the FilePath. On Windows, for example, both '/' and '\\' are valid path\n// separators. Returns NULL if no path separator was found.\nconst char* FilePath::FindLastPathSeparator() const {\n  const char* const last_sep = strrchr(c_str(), kPathSeparator);\n#if GTEST_HAS_ALT_PATH_SEP_\n  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);\n  // Comparing two pointers of which only one is NULL is undefined.\n  if (last_alt_sep != nullptr &&\n      (last_sep == nullptr || last_alt_sep > last_sep)) {\n    return last_alt_sep;\n  }\n#endif\n  return last_sep;\n}\n\nsize_t FilePath::CalculateRootLength() const {\n  const auto& path = pathname_;\n  auto s = path.begin();\n  auto end = path.end();\n#ifdef GTEST_OS_WINDOWS\n  if (end - s >= 2 && s[1] == ':' && (end - s == 2 || IsPathSeparator(s[2])) &&\n      (('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) {\n    // A typical absolute path like \"C:\\Windows\" or \"D:\"\n    s += 2;\n    if (s != end) {\n      ++s;\n    }\n  } else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1)) &&\n             !IsPathSeparator(*(s + 2))) {\n    // Move past the \"\\\\\" prefix in a UNC path like \"\\\\Server\\Share\\Folder\"\n    s += 2;\n    // Skip 2 components and their following separators (\"Server\\\" and \"Share\\\")\n    for (int i = 0; i < 2; ++i) {\n      while (s != end) {\n        bool stop = IsPathSeparator(*s);\n        ++s;\n        if (stop) {\n          break;\n        }\n      }\n    }\n  } else if (s != end && IsPathSeparator(*s)) {\n    // A drive-rooted path like \"\\Windows\"\n    ++s;\n  }\n#else\n  if (s != end && IsPathSeparator(*s)) {\n    ++s;\n  }\n#endif\n  return static_cast<size_t>(s - path.begin());\n}\n\n// Returns a copy of the FilePath with the directory part removed.\n// Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n// FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n// the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n// returns an empty FilePath (\"\").\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveDirectoryName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  return last_sep ? FilePath(last_sep + 1) : *this;\n}\n\n// RemoveFileName returns the directory path with the filename removed.\n// Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n// If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n// FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n// not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveFileName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  std::string dir;\n  if (last_sep) {\n    dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));\n  } else {\n    dir = kCurrentDirectoryString;\n  }\n  return FilePath(dir);\n}\n\n// Helper functions for naming files in a directory for xml output.\n\n// Given directory = \"dir\", base_name = \"test\", number = 0,\n// extension = \"xml\", returns \"dir/test.xml\". If number is greater\n// than zero (e.g., 12), returns \"dir/test_12.xml\".\n// On Windows platform, uses \\ as the separator rather than /.\nFilePath FilePath::MakeFileName(const FilePath& directory,\n                                const FilePath& base_name, int number,\n                                const char* extension) {\n  std::string file;\n  if (number == 0) {\n    file = base_name.string() + \".\" + extension;\n  } else {\n    file =\n        base_name.string() + \"_\" + StreamableToString(number) + \".\" + extension;\n  }\n  return ConcatPaths(directory, FilePath(file));\n}\n\n// Given directory = \"dir\", relative_path = \"test.xml\", returns \"dir/test.xml\".\n// On Windows, uses \\ as the separator rather than /.\nFilePath FilePath::ConcatPaths(const FilePath& directory,\n                               const FilePath& relative_path) {\n  if (directory.IsEmpty()) return relative_path;\n  const FilePath dir(directory.RemoveTrailingPathSeparator());\n  return FilePath(dir.string() + kPathSeparator + relative_path.string());\n}\n\n// Returns true if pathname describes something findable in the file-system,\n// either a file, directory, or whatever.\nbool FilePath::FileOrDirectoryExists() const {\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete[] unicode;\n  return attributes != kInvalidFileAttributes;\n#else\n  posix::StatStruct file_stat{};\n  return posix::Stat(pathname_.c_str(), &file_stat) == 0;\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns true if pathname describes a directory in the file-system\n// that exists.\nbool FilePath::DirectoryExists() const {\n  bool result = false;\n#ifdef GTEST_OS_WINDOWS\n  // Don't strip off trailing separator if path is a root directory on\n  // Windows (like \"C:\\\\\").\n  const FilePath& path(IsRootDirectory() ? *this\n                                         : RemoveTrailingPathSeparator());\n#else\n  const FilePath& path(*this);\n#endif\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete[] unicode;\n  if ((attributes != kInvalidFileAttributes) &&\n      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {\n    result = true;\n  }\n#else\n  posix::StatStruct file_stat{};\n  result =\n      posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  return result;\n}\n\n// Returns true if pathname describes a root directory. (Windows has one\n// root directory per disk drive. UNC share roots are also included.)\nbool FilePath::IsRootDirectory() const {\n  size_t root_length = CalculateRootLength();\n  return root_length > 0 && root_length == pathname_.size() &&\n         IsPathSeparator(pathname_[root_length - 1]);\n}\n\n// Returns true if pathname describes an absolute path.\nbool FilePath::IsAbsolutePath() const { return CalculateRootLength() > 0; }\n\n// Returns a pathname for a file that does not currently exist. The pathname\n// will be directory/base_name.extension or\n// directory/base_name_<number>.extension if directory/base_name.extension\n// already exists. The number will be incremented until a pathname is found\n// that does not already exist.\n// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n// There could be a race condition if two or more processes are calling this\n// function at the same time -- they could both pick the same filename.\nFilePath FilePath::GenerateUniqueFileName(const FilePath& directory,\n                                          const FilePath& base_name,\n                                          const char* extension) {\n  FilePath full_pathname;\n  int number = 0;\n  do {\n    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));\n  } while (full_pathname.FileOrDirectoryExists());\n  return full_pathname;\n}\n\n// Returns true if FilePath ends with a path separator, which indicates that\n// it is intended to represent a directory. Returns false otherwise.\n// This does NOT check that a directory (or file) actually exists.\nbool FilePath::IsDirectory() const {\n  return !pathname_.empty() &&\n         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);\n}\n\n// Create directories so that path exists. Returns true if successful or if\n// the directories already exist; returns false if unable to create directories\n// for any reason.\nbool FilePath::CreateDirectoriesRecursively() const {\n  if (!this->IsDirectory()) {\n    return false;\n  }\n\n  if (pathname_.empty() || this->DirectoryExists()) {\n    return true;\n  }\n\n  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());\n  return parent.CreateDirectoriesRecursively() && this->CreateFolder();\n}\n\n// Create the directory so that path exists. Returns true if successful or\n// if the directory already exists; returns false if unable to create the\n// directory for any reason, including if the parent directory does not\n// exist. Not named \"CreateDirectory\" because that's a macro on Windows.\nbool FilePath::CreateFolder() const {\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  FilePath removed_sep(this->RemoveTrailingPathSeparator());\n  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());\n  int result = CreateDirectory(unicode, nullptr) ? 0 : -1;\n  delete[] unicode;\n#elif defined(GTEST_OS_WINDOWS)\n  int result = _mkdir(pathname_.c_str());\n#elif defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \\\n    defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) ||  \\\n    defined(GTEST_OS_NRF52)\n  // do nothing\n  int result = 0;\n#else\n  int result = mkdir(pathname_.c_str(), 0777);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  if (result == -1) {\n    return this->DirectoryExists();  // An error is OK if the directory exists.\n  }\n  return true;  // No error.\n}\n\n// If input name has a trailing separator character, remove it and return the\n// name, otherwise return the name string unmodified.\n// On Windows platform, uses \\ as the separator, other platforms use /.\nFilePath FilePath::RemoveTrailingPathSeparator() const {\n  return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))\n                       : *this;\n}\n\n// Removes any redundant separators that might be in the pathname.\n// For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n// redundancies that might be in a pathname involving \".\" or \"..\".\n// Note that \"\\\\Host\\Share\" does not contain a redundancy on Windows!\nvoid FilePath::Normalize() {\n  auto out = pathname_.begin();\n\n  auto i = pathname_.cbegin();\n#ifdef GTEST_OS_WINDOWS\n  // UNC paths are treated specially\n  if (pathname_.end() - i >= 3 && IsPathSeparator(*i) &&\n      IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) {\n    *(out++) = kPathSeparator;\n    *(out++) = kPathSeparator;\n  }\n#endif\n  while (i != pathname_.end()) {\n    const char character = *i;\n    if (!IsPathSeparator(character)) {\n      *(out++) = character;\n    } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {\n      *(out++) = kPathSeparator;\n    }\n    ++i;\n  }\n\n  pathname_.erase(out, pathname_.end());\n}\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_HAS_FILE_SYSTEM\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-internal-inl.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Utility functions and classes used by the Google C++ testing framework.//\n// This file contains purely Google Test's internal implementation.  Please\n// DO NOT #INCLUDE IT IN A USER PROGRAM.\n\n#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n\n#ifndef _WIN32_WCE\n#include <errno.h>\n#endif  // !_WIN32_WCE\n#include <stddef.h>\n#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.\n#include <string.h>  // For memmove.\n\n#include <algorithm>\n#include <cstdint>\n#include <memory>\n#include <set>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\n#include \"gtest/internal/gtest-port.h\"\n\n#if GTEST_CAN_STREAM_RESULTS_\n#include <arpa/inet.h>  // NOLINT\n#include <netdb.h>      // NOLINT\n#endif\n\n#ifdef GTEST_OS_WINDOWS\n#include <windows.h>  // NOLINT\n#endif                // GTEST_OS_WINDOWS\n\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Declares the flags.\n//\n// We don't want the users to modify this flag in the code, but want\n// Google Test's own unit tests to be able to access it. Therefore we\n// declare it here as opposed to in gtest.h.\nGTEST_DECLARE_bool_(death_test_use_fork);\n\nnamespace testing {\nnamespace internal {\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nGTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;\n\n// A valid random seed must be in [1, kMaxRandomSeed].\nconst int kMaxRandomSeed = 99999;\n\n// g_help_flag is true if and only if the --help flag or an equivalent form\n// is specified on the command line.\nGTEST_API_ extern bool g_help_flag;\n\n// Returns the current time in milliseconds.\nGTEST_API_ TimeInMillis GetTimeInMillis();\n\n// Returns true if and only if Google Test should use colors in the output.\nGTEST_API_ bool ShouldUseColor(bool stdout_is_tty);\n\n// Formats the given time in milliseconds as seconds. If the input is an exact N\n// seconds, the output has a trailing decimal point (e.g., \"N.\" instead of \"N\").\nGTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);\n\n// Converts the given time in milliseconds to a date string in the ISO 8601\n// format, without the timezone information.  N.B.: due to the use the\n// non-reentrant localtime() function, this function is not thread safe.  Do\n// not use it in any code that can be called from multiple threads.\nGTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);\n\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nGTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);\n\n// Returns a random seed in range [1, kMaxRandomSeed] based on the\n// given --gtest_random_seed flag value.\ninline int GetRandomSeedFromFlag(int32_t random_seed_flag) {\n  const unsigned int raw_seed =\n      (random_seed_flag == 0) ? static_cast<unsigned int>(GetTimeInMillis())\n                              : static_cast<unsigned int>(random_seed_flag);\n\n  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that\n  // it's easy to type.\n  const int normalized_seed =\n      static_cast<int>((raw_seed - 1U) %\n                       static_cast<unsigned int>(kMaxRandomSeed)) +\n      1;\n  return normalized_seed;\n}\n\n// Returns the first valid random seed after 'seed'.  The behavior is\n// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is\n// considered to be 1.\ninline int GetNextRandomSeed(int seed) {\n  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)\n      << \"Invalid random seed \" << seed << \" - must be in [1, \"\n      << kMaxRandomSeed << \"].\";\n  const int next_seed = seed + 1;\n  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;\n}\n\n// This class saves the values of all Google Test flags in its c'tor, and\n// restores them in its d'tor.\nclass GTestFlagSaver {\n public:\n  // The c'tor.\n  GTestFlagSaver() {\n    also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);\n    break_on_failure_ = GTEST_FLAG_GET(break_on_failure);\n    catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);\n    color_ = GTEST_FLAG_GET(color);\n    death_test_style_ = GTEST_FLAG_GET(death_test_style);\n    death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);\n    fail_fast_ = GTEST_FLAG_GET(fail_fast);\n    filter_ = GTEST_FLAG_GET(filter);\n    internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);\n    list_tests_ = GTEST_FLAG_GET(list_tests);\n    output_ = GTEST_FLAG_GET(output);\n    brief_ = GTEST_FLAG_GET(brief);\n    print_time_ = GTEST_FLAG_GET(print_time);\n    print_utf8_ = GTEST_FLAG_GET(print_utf8);\n    random_seed_ = GTEST_FLAG_GET(random_seed);\n    repeat_ = GTEST_FLAG_GET(repeat);\n    recreate_environments_when_repeating_ =\n        GTEST_FLAG_GET(recreate_environments_when_repeating);\n    shuffle_ = GTEST_FLAG_GET(shuffle);\n    stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth);\n    stream_result_to_ = GTEST_FLAG_GET(stream_result_to);\n    throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure);\n  }\n\n  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.\n  ~GTestFlagSaver() {\n    GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);\n    GTEST_FLAG_SET(break_on_failure, break_on_failure_);\n    GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);\n    GTEST_FLAG_SET(color, color_);\n    GTEST_FLAG_SET(death_test_style, death_test_style_);\n    GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);\n    GTEST_FLAG_SET(filter, filter_);\n    GTEST_FLAG_SET(fail_fast, fail_fast_);\n    GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);\n    GTEST_FLAG_SET(list_tests, list_tests_);\n    GTEST_FLAG_SET(output, output_);\n    GTEST_FLAG_SET(brief, brief_);\n    GTEST_FLAG_SET(print_time, print_time_);\n    GTEST_FLAG_SET(print_utf8, print_utf8_);\n    GTEST_FLAG_SET(random_seed, random_seed_);\n    GTEST_FLAG_SET(repeat, repeat_);\n    GTEST_FLAG_SET(recreate_environments_when_repeating,\n                   recreate_environments_when_repeating_);\n    GTEST_FLAG_SET(shuffle, shuffle_);\n    GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_);\n    GTEST_FLAG_SET(stream_result_to, stream_result_to_);\n    GTEST_FLAG_SET(throw_on_failure, throw_on_failure_);\n  }\n\n private:\n  // Fields for saving the original values of flags.\n  bool also_run_disabled_tests_;\n  bool break_on_failure_;\n  bool catch_exceptions_;\n  std::string color_;\n  std::string death_test_style_;\n  bool death_test_use_fork_;\n  bool fail_fast_;\n  std::string filter_;\n  std::string internal_run_death_test_;\n  bool list_tests_;\n  std::string output_;\n  bool brief_;\n  bool print_time_;\n  bool print_utf8_;\n  int32_t random_seed_;\n  int32_t repeat_;\n  bool recreate_environments_when_repeating_;\n  bool shuffle_;\n  int32_t stack_trace_depth_;\n  std::string stream_result_to_;\n  bool throw_on_failure_;\n};\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type UInt32 because wchar_t may not be\n// wide enough to contain a code point.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\nGTEST_API_ std::string CodePointToUtf8(uint32_t code_point);\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nGTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);\n\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded();\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (e.g., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nGTEST_API_ bool ShouldShard(const char* total_shards_str,\n                            const char* shard_index_str,\n                            bool in_subprocess_for_death_test);\n\n// Parses the environment variable var as a 32-bit integer. If it is unset,\n// returns default_val. If it is not a 32-bit integer, prints an error and\n// and aborts.\nGTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val);\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true if and only if the test should be run on this shard. The test id\n// is some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nGTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index,\n                                     int test_id);\n\n// STL container utilities.\n\n// Returns the number of elements in the given container that satisfy\n// the given predicate.\ntemplate <class Container, typename Predicate>\ninline int CountIf(const Container& c, Predicate predicate) {\n  // Implemented as an explicit loop since std::count_if() in libCstd on\n  // Solaris has a non-standard signature.\n  int count = 0;\n  for (auto it = c.begin(); it != c.end(); ++it) {\n    if (predicate(*it)) ++count;\n  }\n  return count;\n}\n\n// Applies a function/functor to each element in the container.\ntemplate <class Container, typename Functor>\nvoid ForEach(const Container& c, Functor functor) {\n  std::for_each(c.begin(), c.end(), functor);\n}\n\n// Returns the i-th element of the vector, or default_value if i is not\n// in range [0, v.size()).\ntemplate <typename E>\ninline E GetElementOr(const std::vector<E>& v, int i, E default_value) {\n  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value\n                                                    : v[static_cast<size_t>(i)];\n}\n\n// Performs an in-place shuffle of a range of the vector's elements.\n// 'begin' and 'end' are element indices as an STL-style range;\n// i.e. [begin, end) are shuffled, where 'end' == size() means to\n// shuffle to the end of the vector.\ntemplate <typename E>\nvoid ShuffleRange(internal::Random* random, int begin, int end,\n                  std::vector<E>* v) {\n  const int size = static_cast<int>(v->size());\n  GTEST_CHECK_(0 <= begin && begin <= size)\n      << \"Invalid shuffle range start \" << begin << \": must be in range [0, \"\n      << size << \"].\";\n  GTEST_CHECK_(begin <= end && end <= size)\n      << \"Invalid shuffle range finish \" << end << \": must be in range [\"\n      << begin << \", \" << size << \"].\";\n\n  // Fisher-Yates shuffle, from\n  // https://en.wikipedia.org/wiki/Fisher-Yates_shuffle\n  for (int range_width = end - begin; range_width >= 2; range_width--) {\n    const int last_in_range = begin + range_width - 1;\n    const int selected =\n        begin +\n        static_cast<int>(random->Generate(static_cast<uint32_t>(range_width)));\n    std::swap((*v)[static_cast<size_t>(selected)],\n              (*v)[static_cast<size_t>(last_in_range)]);\n  }\n}\n\n// Performs an in-place shuffle of the vector's elements.\ntemplate <typename E>\ninline void Shuffle(internal::Random* random, std::vector<E>* v) {\n  ShuffleRange(random, 0, static_cast<int>(v->size()), v);\n}\n\n// A function for deleting an object.  Handy for being used as a\n// functor.\ntemplate <typename T>\nstatic void Delete(T* x) {\n  delete x;\n}\n\n// A predicate that checks the key of a TestProperty against a known key.\n//\n// TestPropertyKeyIs is copyable.\nclass TestPropertyKeyIs {\n public:\n  // Constructor.\n  //\n  // TestPropertyKeyIs has NO default constructor.\n  explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}\n\n  // Returns true if and only if the test name of test property matches on key_.\n  bool operator()(const TestProperty& test_property) const {\n    return test_property.key() == key_;\n  }\n\n private:\n  std::string key_;\n};\n\n// Class UnitTestOptions.\n//\n// This class contains functions for processing options the user\n// specifies when running the tests.  It has only static members.\n//\n// In most cases, the user can specify an option using either an\n// environment variable or a command line flag.  E.g. you can set the\n// test filter using either GTEST_FILTER or --gtest_filter.  If both\n// the variable and the flag are present, the latter overrides the\n// former.\nclass GTEST_API_ UnitTestOptions {\n public:\n  // Functions for processing the gtest_output flag.\n\n  // Returns the output format, or \"\" for normal printed output.\n  static std::string GetOutputFormat();\n\n  // Returns the absolute path of the requested output file, or the\n  // default (test_detail.xml in the original working directory) if\n  // none was explicitly specified.\n  static std::string GetAbsolutePathToOutputFile();\n\n  // Functions for processing the gtest_filter flag.\n\n  // Returns true if and only if the user-specified filter matches the test\n  // suite name and the test name.\n  static bool FilterMatchesTest(const std::string& test_suite_name,\n                                const std::string& test_name);\n\n#ifdef GTEST_OS_WINDOWS\n  // Function for supporting the gtest_catch_exception flag.\n\n  // Returns EXCEPTION_EXECUTE_HANDLER if given SEH exception was handled, or\n  // EXCEPTION_CONTINUE_SEARCH otherwise.\n  // This function is useful as an __except condition.\n  static int GTestProcessSEH(DWORD seh_code, const char* location);\n#endif  // GTEST_OS_WINDOWS\n\n  // Returns true if \"name\" matches the ':' separated list of glob-style\n  // filters in \"filter\".\n  static bool MatchesFilter(const std::string& name, const char* filter);\n};\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the current application's name, removing directory path if that\n// is present.  Used by UnitTestOptions::GetOutputFile.\nGTEST_API_ FilePath GetCurrentExecutableName();\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// The role interface for getting the OS stack trace as a string.\nclass OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetterInterface() = default;\n  virtual ~OsStackTraceGetterInterface() = default;\n\n  // Returns the current OS stack trace as an std::string.  Parameters:\n  //\n  //   max_depth  - the maximum number of stack frames to be included\n  //                in the trace.\n  //   skip_count - the number of top frames to be skipped; doesn't count\n  //                against max_depth.\n  virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;\n\n  // UponLeavingGTest() should be called immediately before Google Test calls\n  // user code. It saves some information about the current stack that\n  // CurrentStackTrace() will use to find and hide Google Test stack frames.\n  virtual void UponLeavingGTest() = 0;\n\n  // This string is inserted in place of stack frames that are part of\n  // Google Test's implementation.\n  static const char* const kElidedFramesMarker;\n\n private:\n  OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete;\n  OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) =\n      delete;\n};\n\n// A working implementation of the OsStackTraceGetterInterface interface.\nclass OsStackTraceGetter : public OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetter() = default;\n\n  std::string CurrentStackTrace(int max_depth, int skip_count) override;\n  void UponLeavingGTest() override;\n\n private:\n#ifdef GTEST_HAS_ABSL\n  Mutex mutex_;  // Protects all internal state.\n\n  // We save the stack frame below the frame that calls user code.\n  // We do this because the address of the frame immediately below\n  // the user code changes between the call to UponLeavingGTest()\n  // and any calls to the stack trace code from within the user code.\n  void* caller_frame_ = nullptr;\n#endif  // GTEST_HAS_ABSL\n\n  OsStackTraceGetter(const OsStackTraceGetter&) = delete;\n  OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete;\n};\n\n// Information about a Google Test trace point.\nstruct TraceInfo {\n  const char* file;\n  int line;\n  std::string message;\n};\n\n// This is the default global test part result reporter used in UnitTestImpl.\n// This class should only be used by UnitTestImpl.\nclass DefaultGlobalTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. Reports the test part\n  // result in the current test.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  DefaultGlobalTestPartResultReporter(\n      const DefaultGlobalTestPartResultReporter&) = delete;\n  DefaultGlobalTestPartResultReporter& operator=(\n      const DefaultGlobalTestPartResultReporter&) = delete;\n};\n\n// This is the default per thread test part result reporter used in\n// UnitTestImpl. This class should only be used by UnitTestImpl.\nclass DefaultPerThreadTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. The implementation just\n  // delegates to the current global test part result reporter of *unit_test_.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  DefaultPerThreadTestPartResultReporter(\n      const DefaultPerThreadTestPartResultReporter&) = delete;\n  DefaultPerThreadTestPartResultReporter& operator=(\n      const DefaultPerThreadTestPartResultReporter&) = delete;\n};\n\n// The private implementation of the UnitTest class.  We don't protect\n// the methods under a mutex, as this class is not accessible by a\n// user and the UnitTest class that delegates work to this class does\n// proper locking.\nclass GTEST_API_ UnitTestImpl {\n public:\n  explicit UnitTestImpl(UnitTest* parent);\n  virtual ~UnitTestImpl();\n\n  // There are two different ways to register your own TestPartResultReporter.\n  // You can register your own reporter to listen either only for test results\n  // from the current thread or for results from all threads.\n  // By default, each per-thread test result reporter just passes a new\n  // TestPartResult to the global test result reporter, which registers the\n  // test part result for the currently running test.\n\n  // Returns the global test part result reporter.\n  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();\n\n  // Sets the global test part result reporter.\n  void SetGlobalTestPartResultReporter(\n      TestPartResultReporterInterface* reporter);\n\n  // Returns the test part result reporter for the current thread.\n  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();\n\n  // Sets the test part result reporter for the current thread.\n  void SetTestPartResultReporterForCurrentThread(\n      TestPartResultReporterInterface* reporter);\n\n  // Gets the number of successful test suites.\n  int successful_test_suite_count() const;\n\n  // Gets the number of failed test suites.\n  int failed_test_suite_count() const;\n\n  // Gets the number of all test suites.\n  int total_test_suite_count() const;\n\n  // Gets the number of all test suites that contain at least one test\n  // that should run.\n  int test_suite_to_run_count() const;\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Returns true if and only if the unit test passed (i.e. all test suites\n  // passed).\n  bool Passed() const { return !Failed(); }\n\n  // Returns true if and only if the unit test failed (i.e. some test suite\n  // failed or something outside of all tests failed).\n  bool Failed() const {\n    return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();\n  }\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  const TestSuite* GetTestSuite(int i) const {\n    const int index = GetElementOr(test_suite_indices_, i, -1);\n    return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];\n  }\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  TestSuite* GetMutableSuiteCase(int i) {\n    const int index = GetElementOr(test_suite_indices_, i, -1);\n    return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];\n  }\n\n  // Provides access to the event listener list.\n  TestEventListeners* listeners() { return &listeners_; }\n\n  // Returns the TestResult for the test that's currently running, or\n  // the TestResult for the ad hoc test if no test is running.\n  TestResult* current_test_result();\n\n  // Returns the TestResult for the ad hoc test.\n  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }\n\n  // Sets the OS stack trace getter.\n  //\n  // Does nothing if the input and the current OS stack trace getter\n  // are the same; otherwise, deletes the old getter and makes the\n  // input the current getter.\n  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);\n\n  // Returns the current OS stack trace getter if it is not NULL;\n  // otherwise, creates an OsStackTraceGetter, makes it the current\n  // getter, and returns it.\n  OsStackTraceGetterInterface* os_stack_trace_getter();\n\n  // Returns the current OS stack trace as an std::string.\n  //\n  // The maximum number of stack frames to be included is specified by\n  // the gtest_stack_trace_depth flag.  The skip_count parameter\n  // specifies the number of top frames to be skipped, which doesn't\n  // count against the number of frames to be included.\n  //\n  // For example, if Foo() calls Bar(), which in turn calls\n  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.\n  std::string CurrentOsStackTraceExceptTop(int skip_count)\n      GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_;\n\n  // Finds and returns a TestSuite with the given name.  If one doesn't\n  // exist, creates one and returns it.\n  //\n  // Arguments:\n  //\n  //   test_suite_name: name of the test suite\n  //   type_param:      the name of the test's type parameter, or NULL if\n  //                    this is not a typed or a type-parameterized test.\n  //   set_up_tc:       pointer to the function that sets up the test suite\n  //   tear_down_tc:    pointer to the function that tears down the test suite\n  TestSuite* GetTestSuite(const std::string& test_suite_name,\n                          const char* type_param,\n                          internal::SetUpTestSuiteFunc set_up_tc,\n                          internal::TearDownTestSuiteFunc tear_down_tc);\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  TestCase* GetTestCase(const std::string& test_case_name,\n                        const char* type_param,\n                        internal::SetUpTestSuiteFunc set_up_tc,\n                        internal::TearDownTestSuiteFunc tear_down_tc) {\n    return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);\n  }\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Adds a TestInfo to the unit test.\n  //\n  // Arguments:\n  //\n  //   set_up_tc:    pointer to the function that sets up the test suite\n  //   tear_down_tc: pointer to the function that tears down the test suite\n  //   test_info:    the TestInfo object\n  void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,\n                   internal::TearDownTestSuiteFunc tear_down_tc,\n                   TestInfo* test_info) {\n#if GTEST_HAS_FILE_SYSTEM\n    // In order to support thread-safe death tests, we need to\n    // remember the original working directory when the test program\n    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as\n    // the user may have changed the current directory before calling\n    // RUN_ALL_TESTS().  Therefore we capture the current directory in\n    // AddTestInfo(), which is called to register a TEST or TEST_F\n    // before main() is reached.\n    if (original_working_dir_.IsEmpty()) {\n      original_working_dir_ = FilePath::GetCurrentDir();\n      GTEST_CHECK_(!original_working_dir_.IsEmpty())\n          << \"Failed to get the current working directory.\";\n    }\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n    GetTestSuite(test_info->test_suite_name_, test_info->type_param(),\n                 set_up_tc, tear_down_tc)\n        ->AddTestInfo(test_info);\n  }\n\n  // Returns ParameterizedTestSuiteRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {\n    return parameterized_test_registry_;\n  }\n\n  std::set<std::string>* ignored_parameterized_test_suites() {\n    return &ignored_parameterized_test_suites_;\n  }\n\n  // Returns TypeParameterizedTestSuiteRegistry object used to keep track of\n  // type-parameterized tests and instantiations of them.\n  internal::TypeParameterizedTestSuiteRegistry&\n  type_parameterized_test_registry() {\n    return type_parameterized_test_registry_;\n  }\n\n  // Registers all parameterized tests defined using TEST_P and\n  // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter\n  // combination. This method can be called more then once; it has guards\n  // protecting from registering the tests more then once.  If\n  // value-parameterized tests are disabled, RegisterParameterizedTests is\n  // present but does nothing.\n  void RegisterParameterizedTests();\n\n  // Runs all tests in this UnitTest object, prints the result, and\n  // returns true if all tests are successful.  If any exception is\n  // thrown during a test, this test is considered to be failed, but\n  // the rest of the tests will still be run.\n  bool RunAllTests();\n\n  // Clears the results of all tests, except the ad hoc tests.\n  void ClearNonAdHocTestResult() {\n    ForEach(test_suites_, TestSuite::ClearTestSuiteResult);\n  }\n\n  // Clears the results of ad-hoc test assertions.\n  void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); }\n\n  // Adds a TestProperty to the current TestResult object when invoked in a\n  // context of a test or a test suite, or to the global property set. If the\n  // result already contains a property with the same key, the value will be\n  // updated.\n  void RecordProperty(const TestProperty& test_property);\n\n  enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL };\n\n  // Matches the full name of each test against the user-specified\n  // filter to decide whether the test should run, then records the\n  // result in each TestSuite and TestInfo object.\n  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests\n  // based on sharding variables in the environment.\n  // Returns the number of tests that should run.\n  int FilterTests(ReactionToSharding shard_tests);\n\n  // Prints the names of the tests matching the user-specified filter flag.\n  void ListTestsMatchingFilter();\n\n  const TestSuite* current_test_suite() const { return current_test_suite_; }\n  TestInfo* current_test_info() { return current_test_info_; }\n  const TestInfo* current_test_info() const { return current_test_info_; }\n\n  // Returns the vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*>& environments() { return environments_; }\n\n  // Getters for the per-thread Google Test trace stack.\n  std::vector<TraceInfo>& gtest_trace_stack() {\n    return *(gtest_trace_stack_.pointer());\n  }\n  const std::vector<TraceInfo>& gtest_trace_stack() const {\n    return gtest_trace_stack_.get();\n  }\n\n#ifdef GTEST_HAS_DEATH_TEST\n  void InitDeathTestSubprocessControlInfo() {\n    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());\n  }\n  // Returns a pointer to the parsed --gtest_internal_run_death_test\n  // flag, or NULL if that flag was not specified.\n  // This information is useful only in a death test child process.\n  // Must not be called before a call to InitGoogleTest.\n  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {\n    return internal_run_death_test_flag_.get();\n  }\n\n  // Returns a pointer to the current death test factory.\n  internal::DeathTestFactory* death_test_factory() {\n    return death_test_factory_.get();\n  }\n\n  void SuppressTestEventsIfInSubprocess();\n\n  friend class ReplaceDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // Initializes the event listener performing XML output as specified by\n  // UnitTestOptions. Must not be called before InitGoogleTest.\n  void ConfigureXmlOutput();\n\n#if GTEST_CAN_STREAM_RESULTS_\n  // Initializes the event listener for streaming test results to a socket.\n  // Must not be called before InitGoogleTest.\n  void ConfigureStreamingOutput();\n#endif\n\n  // Performs initialization dependent upon flag values obtained in\n  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n  // this function is also called from RunAllTests.  Since this function can be\n  // called more than once, it has to be idempotent.\n  void PostFlagParsingInit();\n\n  // Gets the random seed used at the start of the current test iteration.\n  int random_seed() const { return random_seed_; }\n\n  // Gets the random number generator.\n  internal::Random* random() { return &random_; }\n\n  // Shuffles all test suites, and the tests within each test suite,\n  // making sure that death tests are still run first.\n  void ShuffleTests();\n\n  // Restores the test suites and tests to their order before the first shuffle.\n  void UnshuffleTests();\n\n  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment\n  // UnitTest::Run() starts.\n  bool catch_exceptions() const { return catch_exceptions_; }\n\n private:\n  struct CompareTestSuitesByPointer {\n    bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {\n      return lhs->name_ < rhs->name_;\n    }\n  };\n\n  friend class ::testing::UnitTest;\n\n  // Used by UnitTest::Run() to capture the state of\n  // GTEST_FLAG(catch_exceptions) at the moment it starts.\n  void set_catch_exceptions(bool value) { catch_exceptions_ = value; }\n\n  // Sets the TestSuite object for the test that's currently running.\n  void set_current_test_suite(TestSuite* a_current_test_suite) {\n    current_test_suite_ = a_current_test_suite;\n  }\n\n  // Sets the TestInfo object for the test that's currently running.  If\n  // current_test_info is NULL, the assertion results will be stored in\n  // ad_hoc_test_result_.\n  void set_current_test_info(TestInfo* a_current_test_info) {\n    current_test_info_ = a_current_test_info;\n  }\n\n  // The UnitTest object that owns this implementation object.\n  UnitTest* const parent_;\n\n#if GTEST_HAS_FILE_SYSTEM\n  // The working directory when the first TEST() or TEST_F() was\n  // executed.\n  internal::FilePath original_working_dir_;\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n  // The default test part result reporters.\n  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;\n  DefaultPerThreadTestPartResultReporter\n      default_per_thread_test_part_result_reporter_;\n\n  // Points to (but doesn't own) the global test part result reporter.\n  TestPartResultReporterInterface* global_test_part_result_reporter_;\n\n  // Protects read and write access to global_test_part_result_reporter_.\n  internal::Mutex global_test_part_result_reporter_mutex_;\n\n  // Points to (but doesn't own) the per-thread test part result reporter.\n  internal::ThreadLocal<TestPartResultReporterInterface*>\n      per_thread_test_part_result_reporter_;\n\n  // The vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*> environments_;\n\n  // The vector of TestSuites in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestSuite*> test_suites_;\n\n  // The set of TestSuites by name.\n  std::unordered_map<std::string, TestSuite*> test_suites_by_name_;\n\n  // Provides a level of indirection for the test suite list to allow\n  // easy shuffling and restoring the test suite order.  The i-th\n  // element of this vector is the index of the i-th test suite in the\n  // shuffled order.\n  std::vector<int> test_suite_indices_;\n\n  // ParameterizedTestRegistry object used to register value-parameterized\n  // tests.\n  internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;\n  internal::TypeParameterizedTestSuiteRegistry\n      type_parameterized_test_registry_;\n\n  // The set holding the name of parameterized\n  // test suites that may go uninstantiated.\n  std::set<std::string> ignored_parameterized_test_suites_;\n\n  // Indicates whether RegisterParameterizedTests() has been called already.\n  bool parameterized_tests_registered_;\n\n  // Index of the last death test suite registered.  Initially -1.\n  int last_death_test_suite_;\n\n  // This points to the TestSuite for the currently running test.  It\n  // changes as Google Test goes through one test suite after another.\n  // When no test is running, this is set to NULL and Google Test\n  // stores assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestSuite* current_test_suite_;\n\n  // This points to the TestInfo for the currently running test.  It\n  // changes as Google Test goes through one test after another.  When\n  // no test is running, this is set to NULL and Google Test stores\n  // assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestInfo* current_test_info_;\n\n  // Normally, a user only writes assertions inside a TEST or TEST_F,\n  // or inside a function called by a TEST or TEST_F.  Since Google\n  // Test keeps track of which test is current running, it can\n  // associate such an assertion with the test it belongs to.\n  //\n  // If an assertion is encountered when no TEST or TEST_F is running,\n  // Google Test attributes the assertion result to an imaginary \"ad hoc\"\n  // test, and records the result in ad_hoc_test_result_.\n  TestResult ad_hoc_test_result_;\n\n  // The list of event listeners that can be used to track events inside\n  // Google Test.\n  TestEventListeners listeners_;\n\n  // The OS stack trace getter.  Will be deleted when the UnitTest\n  // object is destructed.  By default, an OsStackTraceGetter is used,\n  // but the user can set this field to use a custom getter if that is\n  // desired.\n  OsStackTraceGetterInterface* os_stack_trace_getter_;\n\n  // True if and only if PostFlagParsingInit() has been called.\n  bool post_flag_parse_init_performed_;\n\n  // The random number seed used at the beginning of the test run.\n  int random_seed_;\n\n  // Our random number generator.\n  internal::Random random_;\n\n  // The time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp_;\n\n  // How long the test took to run, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n#ifdef GTEST_HAS_DEATH_TEST\n  // The decomposed components of the gtest_internal_run_death_test flag,\n  // parsed when RUN_ALL_TESTS is called.\n  std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;\n  std::unique_ptr<internal::DeathTestFactory> death_test_factory_;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // A per-thread stack of traces created by the SCOPED_TRACE() macro.\n  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;\n\n  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()\n  // starts.\n  bool catch_exceptions_;\n\n  UnitTestImpl(const UnitTestImpl&) = delete;\n  UnitTestImpl& operator=(const UnitTestImpl&) = delete;\n};  // class UnitTestImpl\n\n// Convenience function for accessing the global UnitTest\n// implementation object.\ninline UnitTestImpl* GetUnitTestImpl() {\n  return UnitTest::GetInstance()->impl();\n}\n\n#ifdef GTEST_USES_SIMPLE_RE\n\n// Internal helper functions for implementing the simple regular\n// expression matcher.\nGTEST_API_ bool IsInSet(char ch, const char* str);\nGTEST_API_ bool IsAsciiDigit(char ch);\nGTEST_API_ bool IsAsciiPunct(char ch);\nGTEST_API_ bool IsRepeat(char ch);\nGTEST_API_ bool IsAsciiWhiteSpace(char ch);\nGTEST_API_ bool IsAsciiWordChar(char ch);\nGTEST_API_ bool IsValidEscape(char ch);\nGTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);\nGTEST_API_ bool ValidateRegex(const char* regex);\nGTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);\nGTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,\n                                              char repeat, const char* regex,\n                                              const char* str);\nGTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);\n\n#endif  // GTEST_USES_SIMPLE_RE\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);\n\n#ifdef GTEST_HAS_DEATH_TEST\n\n// Returns the message describing the last system error, regardless of the\n// platform.\nGTEST_API_ std::string GetLastErrnoDescription();\n\n// Attempts to parse a string into a positive integer pointed to by the\n// number parameter.  Returns true if that is possible.\n// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use\n// it here.\ntemplate <typename Integer>\nbool ParseNaturalNumber(const ::std::string& str, Integer* number) {\n  // Fail fast if the given string does not begin with a digit;\n  // this bypasses strtoXXX's \"optional leading whitespace and plus\n  // or minus sign\" semantics, which are undesirable here.\n  if (str.empty() || !IsDigit(str[0])) {\n    return false;\n  }\n  errno = 0;\n\n  char* end;\n  // BiggestConvertible is the largest integer type that system-provided\n  // string-to-number conversion routines can return.\n  using BiggestConvertible = unsigned long long;  // NOLINT\n\n  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);  // NOLINT\n  const bool parse_success = *end == '\\0' && errno == 0;\n\n  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));\n\n  const Integer result = static_cast<Integer>(parsed);\n  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {\n    *number = result;\n    return true;\n  }\n  return false;\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// TestResult contains some private methods that should be hidden from\n// Google Test user but are required for testing. This class allow our tests\n// to access them.\n//\n// This class is supplied only for the purpose of testing Google Test's own\n// constructs. Do not use it in user tests, either directly or indirectly.\nclass TestResultAccessor {\n public:\n  static void RecordProperty(TestResult* test_result,\n                             const std::string& xml_element,\n                             const TestProperty& property) {\n    test_result->RecordProperty(xml_element, property);\n  }\n\n  static void ClearTestPartResults(TestResult* test_result) {\n    test_result->ClearTestPartResults();\n  }\n\n  static const std::vector<testing::TestPartResult>& test_part_results(\n      const TestResult& test_result) {\n    return test_result.test_part_results();\n  }\n};\n\n#if GTEST_CAN_STREAM_RESULTS_\n\n// Streams test results to the given port on the given host machine.\nclass StreamingListener : public EmptyTestEventListener {\n public:\n  // Abstract base class for writing strings to a socket.\n  class AbstractSocketWriter {\n   public:\n    virtual ~AbstractSocketWriter() = default;\n\n    // Sends a string to the socket.\n    virtual void Send(const std::string& message) = 0;\n\n    // Closes the socket.\n    virtual void CloseConnection() {}\n\n    // Sends a string and a newline to the socket.\n    void SendLn(const std::string& message) { Send(message + \"\\n\"); }\n  };\n\n  // Concrete class for actually writing strings to a socket.\n  class SocketWriter : public AbstractSocketWriter {\n   public:\n    SocketWriter(const std::string& host, const std::string& port)\n        : sockfd_(-1), host_name_(host), port_num_(port) {\n      MakeConnection();\n    }\n\n    ~SocketWriter() override {\n      if (sockfd_ != -1) CloseConnection();\n    }\n\n    // Sends a string to the socket.\n    void Send(const std::string& message) override {\n      GTEST_CHECK_(sockfd_ != -1)\n          << \"Send() can be called only when there is a connection.\";\n\n      const auto len = static_cast<size_t>(message.length());\n      if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {\n        GTEST_LOG_(WARNING) << \"stream_result_to: failed to stream to \"\n                            << host_name_ << \":\" << port_num_;\n      }\n    }\n\n   private:\n    // Creates a client socket and connects to the server.\n    void MakeConnection();\n\n    // Closes the socket.\n    void CloseConnection() override {\n      GTEST_CHECK_(sockfd_ != -1)\n          << \"CloseConnection() can be called only when there is a connection.\";\n\n      close(sockfd_);\n      sockfd_ = -1;\n    }\n\n    int sockfd_;  // socket file descriptor\n    const std::string host_name_;\n    const std::string port_num_;\n\n    SocketWriter(const SocketWriter&) = delete;\n    SocketWriter& operator=(const SocketWriter&) = delete;\n  };  // class SocketWriter\n\n  // Escapes '=', '&', '%', and '\\n' characters in str as \"%xx\".\n  static std::string UrlEncode(const char* str);\n\n  StreamingListener(const std::string& host, const std::string& port)\n      : socket_writer_(new SocketWriter(host, port)) {\n    Start();\n  }\n\n  explicit StreamingListener(AbstractSocketWriter* socket_writer)\n      : socket_writer_(socket_writer) {\n    Start();\n  }\n\n  void OnTestProgramStart(const UnitTest& /* unit_test */) override {\n    SendLn(\"event=TestProgramStart\");\n  }\n\n  void OnTestProgramEnd(const UnitTest& unit_test) override {\n    // Note that Google Test current only report elapsed time for each\n    // test iteration, not for the entire test program.\n    SendLn(\"event=TestProgramEnd&passed=\" + FormatBool(unit_test.Passed()));\n\n    // Notify the streaming server to stop.\n    socket_writer_->CloseConnection();\n  }\n\n  void OnTestIterationStart(const UnitTest& /* unit_test */,\n                            int iteration) override {\n    SendLn(\"event=TestIterationStart&iteration=\" +\n           StreamableToString(iteration));\n  }\n\n  void OnTestIterationEnd(const UnitTest& unit_test,\n                          int /* iteration */) override {\n    SendLn(\"event=TestIterationEnd&passed=\" + FormatBool(unit_test.Passed()) +\n           \"&elapsed_time=\" + StreamableToString(unit_test.elapsed_time()) +\n           \"ms\");\n  }\n\n  // Note that \"event=TestCaseStart\" is a wire format and has to remain\n  // \"case\" for compatibility\n  void OnTestSuiteStart(const TestSuite& test_suite) override {\n    SendLn(std::string(\"event=TestCaseStart&name=\") + test_suite.name());\n  }\n\n  // Note that \"event=TestCaseEnd\" is a wire format and has to remain\n  // \"case\" for compatibility\n  void OnTestSuiteEnd(const TestSuite& test_suite) override {\n    SendLn(\"event=TestCaseEnd&passed=\" + FormatBool(test_suite.Passed()) +\n           \"&elapsed_time=\" + StreamableToString(test_suite.elapsed_time()) +\n           \"ms\");\n  }\n\n  void OnTestStart(const TestInfo& test_info) override {\n    SendLn(std::string(\"event=TestStart&name=\") + test_info.name());\n  }\n\n  void OnTestEnd(const TestInfo& test_info) override {\n    SendLn(\"event=TestEnd&passed=\" +\n           FormatBool((test_info.result())->Passed()) + \"&elapsed_time=\" +\n           StreamableToString((test_info.result())->elapsed_time()) + \"ms\");\n  }\n\n  void OnTestPartResult(const TestPartResult& test_part_result) override {\n    const char* file_name = test_part_result.file_name();\n    if (file_name == nullptr) file_name = \"\";\n    SendLn(\"event=TestPartResult&file=\" + UrlEncode(file_name) +\n           \"&line=\" + StreamableToString(test_part_result.line_number()) +\n           \"&message=\" + UrlEncode(test_part_result.message()));\n  }\n\n private:\n  // Sends the given message and a newline to the socket.\n  void SendLn(const std::string& message) { socket_writer_->SendLn(message); }\n\n  // Called at the start of streaming to notify the receiver what\n  // protocol we are using.\n  void Start() { SendLn(\"gtest_streaming_protocol_version=1.0\"); }\n\n  std::string FormatBool(bool value) { return value ? \"1\" : \"0\"; }\n\n  const std::unique_ptr<AbstractSocketWriter> socket_writer_;\n\n  StreamingListener(const StreamingListener&) = delete;\n  StreamingListener& operator=(const StreamingListener&) = delete;\n};  // class StreamingListener\n\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-matchers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements just enough of the matcher interface to allow\n// EXPECT_DEATH and friends to accept a matcher argument.\n\n#include \"gtest/gtest-matchers.h\"\n\n#include <string>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// Constructs a matcher that matches a const std::string& whose value is\n// equal to s.\nMatcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a const std::string& whose value is\n// equal to s.\nMatcher<const std::string&>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a std::string whose value is equal to\n// s.\nMatcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a std::string whose value is equal to\n// s.\nMatcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(const std::string& s) {\n  *this = Eq(s);\n}\n\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(internal::StringView s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(internal::StringView s) {\n  *this = Eq(std::string(s));\n}\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-port.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/internal/gtest-port.h\"\n\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cstdint>\n#include <fstream>\n#include <memory>\n#include <ostream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifdef GTEST_OS_WINDOWS\n#include <io.h>\n#include <sys/stat.h>\n#include <windows.h>\n\n#include <map>  // Used in ThreadLocal.\n#ifdef _MSC_VER\n#include <crtdbg.h>\n#endif  // _MSC_VER\n#else\n#include <unistd.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_MAC\n#include <mach/mach_init.h>\n#include <mach/task.h>\n#include <mach/vm_map.h>\n#endif  // GTEST_OS_MAC\n\n#if defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) ||   \\\n    defined(GTEST_OS_GNU_KFREEBSD) || defined(GTEST_OS_NETBSD) || \\\n    defined(GTEST_OS_OPENBSD)\n#include <sys/sysctl.h>\n#if defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) || \\\n    defined(GTEST_OS_GNU_KFREEBSD)\n#include <sys/user.h>\n#endif\n#endif\n\n#ifdef GTEST_OS_QNX\n#include <devctl.h>\n#include <fcntl.h>\n#include <sys/procfs.h>\n#endif  // GTEST_OS_QNX\n\n#ifdef GTEST_OS_AIX\n#include <procinfo.h>\n#include <sys/types.h>\n#endif  // GTEST_OS_AIX\n\n#ifdef GTEST_OS_FUCHSIA\n#include <zircon/process.h>\n#include <zircon/syscalls.h>\n#endif  // GTEST_OS_FUCHSIA\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\nnamespace internal {\n\n#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_GNU_HURD)\n\nnamespace {\ntemplate <typename T>\nT ReadProcFileField(const std::string& filename, int field) {\n  std::string dummy;\n  std::ifstream file(filename.c_str());\n  while (field-- > 0) {\n    file >> dummy;\n  }\n  T output = 0;\n  file >> output;\n  return output;\n}\n}  // namespace\n\n// Returns the number of active threads, or 0 when there is an error.\nsize_t GetThreadCount() {\n  const std::string filename =\n      (Message() << \"/proc/\" << getpid() << \"/stat\").GetString();\n  return ReadProcFileField<size_t>(filename, 19);\n}\n\n#elif defined(GTEST_OS_MAC)\n\nsize_t GetThreadCount() {\n  const task_t task = mach_task_self();\n  mach_msg_type_number_t thread_count;\n  thread_act_array_t thread_list;\n  const kern_return_t status = task_threads(task, &thread_list, &thread_count);\n  if (status == KERN_SUCCESS) {\n    // task_threads allocates resources in thread_list and we need to free them\n    // to avoid leaks.\n    vm_deallocate(task, reinterpret_cast<vm_address_t>(thread_list),\n                  sizeof(thread_t) * thread_count);\n    return static_cast<size_t>(thread_count);\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) || \\\n    defined(GTEST_OS_GNU_KFREEBSD) || defined(GTEST_OS_NETBSD)\n\n#ifdef GTEST_OS_NETBSD\n#undef KERN_PROC\n#define KERN_PROC KERN_PROC2\n#define kinfo_proc kinfo_proc2\n#endif\n\n#ifdef GTEST_OS_DRAGONFLY\n#define KP_NLWP(kp) (kp.kp_nthreads)\n#elif defined(GTEST_OS_FREEBSD) || defined(GTEST_OS_GNU_KFREEBSD)\n#define KP_NLWP(kp) (kp.ki_numthreads)\n#elif defined(GTEST_OS_NETBSD)\n#define KP_NLWP(kp) (kp.p_nlwps)\n#endif\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  int mib[] = {\n      CTL_KERN,\n      KERN_PROC,\n      KERN_PROC_PID,\n      getpid(),\n#ifdef GTEST_OS_NETBSD\n      sizeof(struct kinfo_proc),\n      1,\n#endif\n  };\n  u_int miblen = sizeof(mib) / sizeof(mib[0]);\n  struct kinfo_proc info;\n  size_t size = sizeof(info);\n  if (sysctl(mib, miblen, &info, &size, NULL, 0)) {\n    return 0;\n  }\n  return static_cast<size_t>(KP_NLWP(info));\n}\n#elif defined(GTEST_OS_OPENBSD)\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  int mib[] = {\n      CTL_KERN,\n      KERN_PROC,\n      KERN_PROC_PID | KERN_PROC_SHOW_THREADS,\n      getpid(),\n      sizeof(struct kinfo_proc),\n      0,\n  };\n  u_int miblen = sizeof(mib) / sizeof(mib[0]);\n\n  // get number of structs\n  size_t size;\n  if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {\n    return 0;\n  }\n\n  mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));\n\n  // populate array of structs\n  std::vector<struct kinfo_proc> info(mib[5]);\n  if (sysctl(mib, miblen, info.data(), &size, NULL, 0)) {\n    return 0;\n  }\n\n  // exclude empty members\n  size_t nthreads = 0;\n  for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {\n    if (info[i].p_tid != -1) nthreads++;\n  }\n  return nthreads;\n}\n\n#elif defined(GTEST_OS_QNX)\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  const int fd = open(\"/proc/self/as\", O_RDONLY);\n  if (fd < 0) {\n    return 0;\n  }\n  procfs_info process_info;\n  const int status =\n      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);\n  close(fd);\n  if (status == EOK) {\n    return static_cast<size_t>(process_info.num_threads);\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_AIX)\n\nsize_t GetThreadCount() {\n  struct procentry64 entry;\n  pid_t pid = getpid();\n  int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);\n  if (status == 1) {\n    return entry.pi_thcount;\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_FUCHSIA)\n\nsize_t GetThreadCount() {\n  int dummy_buffer;\n  size_t avail;\n  zx_status_t status =\n      zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS,\n                         &dummy_buffer, 0, nullptr, &avail);\n  if (status == ZX_OK) {\n    return avail;\n  } else {\n    return 0;\n  }\n}\n\n#else\n\nsize_t GetThreadCount() {\n  // There's no portable way to detect the number of threads, so we just\n  // return 0 to indicate that we cannot detect it.\n  return 0;\n}\n\n#endif  // GTEST_OS_LINUX\n\n#if defined(GTEST_IS_THREADSAFE) && defined(GTEST_OS_WINDOWS)\n\nAutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}\n\nAutoHandle::AutoHandle(Handle handle) : handle_(handle) {}\n\nAutoHandle::~AutoHandle() { Reset(); }\n\nAutoHandle::Handle AutoHandle::Get() const { return handle_; }\n\nvoid AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); }\n\nvoid AutoHandle::Reset(HANDLE handle) {\n  // Resetting with the same handle we already own is invalid.\n  if (handle_ != handle) {\n    if (IsCloseable()) {\n      ::CloseHandle(handle_);\n    }\n    handle_ = handle;\n  } else {\n    GTEST_CHECK_(!IsCloseable())\n        << \"Resetting a valid handle to itself is likely a programmer error \"\n           \"and thus not allowed.\";\n  }\n}\n\nbool AutoHandle::IsCloseable() const {\n  // Different Windows APIs may use either of these values to represent an\n  // invalid handle.\n  return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;\n}\n\nMutex::Mutex()\n    : owner_thread_id_(0),\n      type_(kDynamic),\n      critical_section_init_phase_(0),\n      critical_section_(new CRITICAL_SECTION) {\n  ::InitializeCriticalSection(critical_section_);\n}\n\nMutex::~Mutex() {\n  // Static mutexes are leaked intentionally. It is not thread-safe to try\n  // to clean them up.\n  if (type_ == kDynamic) {\n    ::DeleteCriticalSection(critical_section_);\n    delete critical_section_;\n    critical_section_ = nullptr;\n  }\n}\n\nvoid Mutex::Lock() {\n  ThreadSafeLazyInit();\n  ::EnterCriticalSection(critical_section_);\n  owner_thread_id_ = ::GetCurrentThreadId();\n}\n\nvoid Mutex::Unlock() {\n  ThreadSafeLazyInit();\n  // We don't protect writing to owner_thread_id_ here, as it's the\n  // caller's responsibility to ensure that the current thread holds the\n  // mutex when this is called.\n  owner_thread_id_ = 0;\n  ::LeaveCriticalSection(critical_section_);\n}\n\n// Does nothing if the current thread holds the mutex. Otherwise, crashes\n// with high probability.\nvoid Mutex::AssertHeld() {\n  ThreadSafeLazyInit();\n  GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())\n      << \"The current thread is not holding the mutex @\" << this;\n}\n\nnamespace {\n\n#ifdef _MSC_VER\n// Use the RAII idiom to flag mem allocs that are intentionally never\n// deallocated. The motivation is to silence the false positive mem leaks\n// that are reported by the debug version of MS's CRT which can only detect\n// if an alloc is missing a matching deallocation.\n// Example:\n//    MemoryIsNotDeallocated memory_is_not_deallocated;\n//    critical_section_ = new CRITICAL_SECTION;\n//\nclass MemoryIsNotDeallocated {\n public:\n  MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {\n    old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);\n    // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT\n    // doesn't report mem leak if there's no matching deallocation.\n    (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);\n  }\n\n  ~MemoryIsNotDeallocated() {\n    // Restore the original _CRTDBG_ALLOC_MEM_DF flag\n    (void)_CrtSetDbgFlag(old_crtdbg_flag_);\n  }\n\n private:\n  int old_crtdbg_flag_;\n\n  MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete;\n  MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete;\n};\n#endif  // _MSC_VER\n\n}  // namespace\n\n// Initializes owner_thread_id_ and critical_section_ in static mutexes.\nvoid Mutex::ThreadSafeLazyInit() {\n  // Dynamic mutexes are initialized in the constructor.\n  if (type_ == kStatic) {\n    switch (\n        ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {\n      case 0:\n        // If critical_section_init_phase_ was 0 before the exchange, we\n        // are the first to test it and need to perform the initialization.\n        owner_thread_id_ = 0;\n        {\n          // Use RAII to flag that following mem alloc is never deallocated.\n#ifdef _MSC_VER\n          MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n          critical_section_ = new CRITICAL_SECTION;\n        }\n        ::InitializeCriticalSection(critical_section_);\n        // Updates the critical_section_init_phase_ to 2 to signal\n        // initialization complete.\n        GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_,\n                                                  2L, 1L) == 1L);\n        break;\n      case 1:\n        // Somebody else is already initializing the mutex; spin until they\n        // are done.\n        while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L,\n                                            2L) != 2L) {\n          // Possibly yields the rest of the thread's time slice to other\n          // threads.\n          ::Sleep(0);\n        }\n        break;\n\n      case 2:\n        break;  // The mutex is already initialized and ready for use.\n\n      default:\n        GTEST_CHECK_(false)\n            << \"Unexpected value of critical_section_init_phase_ \"\n            << \"while initializing a static mutex.\";\n    }\n  }\n}\n\nnamespace {\n\nclass ThreadWithParamSupport : public ThreadWithParamBase {\n public:\n  static HANDLE CreateThread(Runnable* runnable,\n                             Notification* thread_can_start) {\n    ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);\n    DWORD thread_id;\n    HANDLE thread_handle = ::CreateThread(\n        nullptr,  // Default security.\n        0,        // Default stack size.\n        &ThreadWithParamSupport::ThreadMain,\n        param,        // Parameter to ThreadMainStatic\n        0x0,          // Default creation flags.\n        &thread_id);  // Need a valid pointer for the call to work under Win98.\n    GTEST_CHECK_(thread_handle != nullptr)\n        << \"CreateThread failed with error \" << ::GetLastError() << \".\";\n    if (thread_handle == nullptr) {\n      delete param;\n    }\n    return thread_handle;\n  }\n\n private:\n  struct ThreadMainParam {\n    ThreadMainParam(Runnable* runnable, Notification* thread_can_start)\n        : runnable_(runnable), thread_can_start_(thread_can_start) {}\n    std::unique_ptr<Runnable> runnable_;\n    // Does not own.\n    Notification* thread_can_start_;\n  };\n\n  static DWORD WINAPI ThreadMain(void* ptr) {\n    // Transfers ownership.\n    std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));\n    if (param->thread_can_start_ != nullptr)\n      param->thread_can_start_->WaitForNotification();\n    param->runnable_->Run();\n    return 0;\n  }\n\n  // Prohibit instantiation.\n  ThreadWithParamSupport();\n\n  ThreadWithParamSupport(const ThreadWithParamSupport&) = delete;\n  ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete;\n};\n\n}  // namespace\n\nThreadWithParamBase::ThreadWithParamBase(Runnable* runnable,\n                                         Notification* thread_can_start)\n    : thread_(\n          ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {}\n\nThreadWithParamBase::~ThreadWithParamBase() { Join(); }\n\nvoid ThreadWithParamBase::Join() {\n  GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)\n      << \"Failed to join the thread with error \" << ::GetLastError() << \".\";\n}\n\n// Maps a thread to a set of ThreadIdToThreadLocals that have values\n// instantiated on that thread and notifies them when the thread exits.  A\n// ThreadLocal instance is expected to persist until all threads it has\n// values on have terminated.\nclass ThreadLocalRegistryImpl {\n public:\n  // Registers thread_local_instance as having value on the current thread.\n  // Returns a value that can be used to identify the thread from other threads.\n  static ThreadLocalValueHolderBase* GetValueOnCurrentThread(\n      const ThreadLocalBase* thread_local_instance) {\n#ifdef _MSC_VER\n    MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n    DWORD current_thread = ::GetCurrentThreadId();\n    MutexLock lock(&mutex_);\n    ThreadIdToThreadLocals* const thread_to_thread_locals =\n        GetThreadLocalsMapLocked();\n    ThreadIdToThreadLocals::iterator thread_local_pos =\n        thread_to_thread_locals->find(current_thread);\n    if (thread_local_pos == thread_to_thread_locals->end()) {\n      thread_local_pos =\n          thread_to_thread_locals\n              ->insert(std::make_pair(current_thread, ThreadLocalValues()))\n              .first;\n      StartWatcherThreadFor(current_thread);\n    }\n    ThreadLocalValues& thread_local_values = thread_local_pos->second;\n    ThreadLocalValues::iterator value_pos =\n        thread_local_values.find(thread_local_instance);\n    if (value_pos == thread_local_values.end()) {\n      value_pos =\n          thread_local_values\n              .insert(std::make_pair(\n                  thread_local_instance,\n                  std::shared_ptr<ThreadLocalValueHolderBase>(\n                      thread_local_instance->NewValueForCurrentThread())))\n              .first;\n    }\n    return value_pos->second.get();\n  }\n\n  static void OnThreadLocalDestroyed(\n      const ThreadLocalBase* thread_local_instance) {\n    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;\n    // Clean up the ThreadLocalValues data structure while holding the lock, but\n    // defer the destruction of the ThreadLocalValueHolderBases.\n    {\n      MutexLock lock(&mutex_);\n      ThreadIdToThreadLocals* const thread_to_thread_locals =\n          GetThreadLocalsMapLocked();\n      for (ThreadIdToThreadLocals::iterator it =\n               thread_to_thread_locals->begin();\n           it != thread_to_thread_locals->end(); ++it) {\n        ThreadLocalValues& thread_local_values = it->second;\n        ThreadLocalValues::iterator value_pos =\n            thread_local_values.find(thread_local_instance);\n        if (value_pos != thread_local_values.end()) {\n          value_holders.push_back(value_pos->second);\n          thread_local_values.erase(value_pos);\n          // This 'if' can only be successful at most once, so theoretically we\n          // could break out of the loop here, but we don't bother doing so.\n        }\n      }\n    }\n    // Outside the lock, let the destructor for 'value_holders' deallocate the\n    // ThreadLocalValueHolderBases.\n  }\n\n  static void OnThreadExit(DWORD thread_id) {\n    GTEST_CHECK_(thread_id != 0) << ::GetLastError();\n    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;\n    // Clean up the ThreadIdToThreadLocals data structure while holding the\n    // lock, but defer the destruction of the ThreadLocalValueHolderBases.\n    {\n      MutexLock lock(&mutex_);\n      ThreadIdToThreadLocals* const thread_to_thread_locals =\n          GetThreadLocalsMapLocked();\n      ThreadIdToThreadLocals::iterator thread_local_pos =\n          thread_to_thread_locals->find(thread_id);\n      if (thread_local_pos != thread_to_thread_locals->end()) {\n        ThreadLocalValues& thread_local_values = thread_local_pos->second;\n        for (ThreadLocalValues::iterator value_pos =\n                 thread_local_values.begin();\n             value_pos != thread_local_values.end(); ++value_pos) {\n          value_holders.push_back(value_pos->second);\n        }\n        thread_to_thread_locals->erase(thread_local_pos);\n      }\n    }\n    // Outside the lock, let the destructor for 'value_holders' deallocate the\n    // ThreadLocalValueHolderBases.\n  }\n\n private:\n  // In a particular thread, maps a ThreadLocal object to its value.\n  typedef std::map<const ThreadLocalBase*,\n                   std::shared_ptr<ThreadLocalValueHolderBase> >\n      ThreadLocalValues;\n  // Stores all ThreadIdToThreadLocals having values in a thread, indexed by\n  // thread's ID.\n  typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;\n\n  struct WatcherThreadParams {\n    DWORD thread_id;\n    HANDLE handle;\n    Notification has_initialized;\n  };\n\n  static void StartWatcherThreadFor(DWORD thread_id) {\n    // The returned handle will be kept in thread_map and closed by\n    // watcher_thread in WatcherThreadFunc.\n    HANDLE thread =\n        ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);\n    GTEST_CHECK_(thread != nullptr);\n\n    WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;\n    watcher_thread_params->thread_id = thread_id;\n    watcher_thread_params->handle = thread;\n\n    // We need to pass a valid thread ID pointer into CreateThread for it\n    // to work correctly under Win98.\n    DWORD watcher_thread_id;\n    HANDLE watcher_thread =\n        ::CreateThread(nullptr,  // Default security.\n                       0,        // Default stack size\n                       &ThreadLocalRegistryImpl::WatcherThreadFunc,\n                       reinterpret_cast<LPVOID>(watcher_thread_params),\n                       CREATE_SUSPENDED, &watcher_thread_id);\n    GTEST_CHECK_(watcher_thread != nullptr)\n        << \"CreateThread failed with error \" << ::GetLastError() << \".\";\n    // Give the watcher thread the same priority as ours to avoid being\n    // blocked by it.\n    ::SetThreadPriority(watcher_thread,\n                        ::GetThreadPriority(::GetCurrentThread()));\n    ::ResumeThread(watcher_thread);\n    ::CloseHandle(watcher_thread);\n\n    // Wait for the watcher thread to start to avoid race conditions.\n    // One specific race condition that can happen is that we have returned\n    // from main and have started to tear down, the newly spawned watcher\n    // thread may access already-freed variables, like global shared_ptrs.\n    watcher_thread_params->has_initialized.WaitForNotification();\n  }\n\n  // Monitors exit from a given thread and notifies those\n  // ThreadIdToThreadLocals about thread termination.\n  static DWORD WINAPI WatcherThreadFunc(LPVOID param) {\n    WatcherThreadParams* watcher_thread_params =\n        reinterpret_cast<WatcherThreadParams*>(param);\n    watcher_thread_params->has_initialized.Notify();\n    GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,\n                                       INFINITE) == WAIT_OBJECT_0);\n    OnThreadExit(watcher_thread_params->thread_id);\n    ::CloseHandle(watcher_thread_params->handle);\n    delete watcher_thread_params;\n    return 0;\n  }\n\n  // Returns map of thread local instances.\n  static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {\n    mutex_.AssertHeld();\n#ifdef _MSC_VER\n    MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n    static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();\n    return map;\n  }\n\n  // Protects access to GetThreadLocalsMapLocked() and its return value.\n  static Mutex mutex_;\n  // Protects access to GetThreadMapLocked() and its return value.\n  static Mutex thread_map_mutex_;\n};\n\nMutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);  // NOLINT\nMutex ThreadLocalRegistryImpl::thread_map_mutex_(\n    Mutex::kStaticMutex);  // NOLINT\n\nThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(\n    const ThreadLocalBase* thread_local_instance) {\n  return ThreadLocalRegistryImpl::GetValueOnCurrentThread(\n      thread_local_instance);\n}\n\nvoid ThreadLocalRegistry::OnThreadLocalDestroyed(\n    const ThreadLocalBase* thread_local_instance) {\n  ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);\n}\n\n#endif  // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS\n\n#ifdef GTEST_USES_POSIX_RE\n\n// Implements RE.  Currently only needed for death tests.\n\nRE::~RE() {\n  if (is_valid_) {\n    // regfree'ing an invalid regex might crash because the content\n    // of the regex is undefined. Since the regex's are essentially\n    // the same, one cannot be valid (or invalid) without the other\n    // being so too.\n    regfree(&partial_regex_);\n    regfree(&full_regex_);\n  }\n}\n\n// Returns true if and only if regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;\n}\n\n// Returns true if and only if regular expression re matches a substring of\n// str (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  pattern_ = regex;\n\n  // NetBSD (and Android, which takes its regex implemntation from NetBSD) does\n  // not include the GNU regex extensions (such as Perl style character classes\n  // like \\w) in REG_EXTENDED. REG_EXTENDED is only specified to include the\n  // [[:alpha:]] style character classes. Enable REG_GNU wherever it is defined\n  // so users can use those extensions.\n#if defined(REG_GNU)\n  constexpr int reg_flags = REG_EXTENDED | REG_GNU;\n#else\n  constexpr int reg_flags = REG_EXTENDED;\n#endif\n\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match.\n  const size_t full_regex_len = strlen(regex) + 10;\n  char* const full_pattern = new char[full_regex_len];\n\n  snprintf(full_pattern, full_regex_len, \"^(%s)$\", regex);\n  is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0;\n  // We want to call regcomp(&partial_regex_, ...) even if the\n  // previous expression returns false.  Otherwise partial_regex_ may\n  // not be properly initialized can may cause trouble when it's\n  // freed.\n  //\n  // Some implementation of POSIX regex (e.g. on at least some\n  // versions of Cygwin) doesn't accept the empty string as a valid\n  // regex.  We change it to an equivalent form \"()\" to be safe.\n  if (is_valid_) {\n    const char* const partial_regex = (*regex == '\\0') ? \"()\" : regex;\n    is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0;\n  }\n  EXPECT_TRUE(is_valid_)\n      << \"Regular expression \\\"\" << regex\n      << \"\\\" is not a valid POSIX Extended regular expression.\";\n\n  delete[] full_pattern;\n}\n\n#elif defined(GTEST_USES_SIMPLE_RE)\n\n// Returns true if and only if ch appears anywhere in str (excluding the\n// terminating '\\0' character).\nbool IsInSet(char ch, const char* str) {\n  return ch != '\\0' && strchr(str, ch) != nullptr;\n}\n\n// Returns true if and only if ch belongs to the given classification.\n// Unlike similar functions in <ctype.h>, these aren't affected by the\n// current locale.\nbool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }\nbool IsAsciiPunct(char ch) {\n  return IsInSet(ch, \"^-!\\\"#$%&'()*+,./:;<=>?@[\\\\]_`{|}~\");\n}\nbool IsRepeat(char ch) { return IsInSet(ch, \"?*+\"); }\nbool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, \" \\f\\n\\r\\t\\v\"); }\nbool IsAsciiWordChar(char ch) {\n  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||\n         ('0' <= ch && ch <= '9') || ch == '_';\n}\n\n// Returns true if and only if \"\\\\c\" is a supported escape sequence.\nbool IsValidEscape(char c) {\n  return (IsAsciiPunct(c) || IsInSet(c, \"dDfnrsStvwW\"));\n}\n\n// Returns true if and only if the given atom (specified by escaped and\n// pattern) matches ch.  The result is undefined if the atom is invalid.\nbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {\n  if (escaped) {  // \"\\\\p\" where p is pattern_char.\n    switch (pattern_char) {\n      case 'd':\n        return IsAsciiDigit(ch);\n      case 'D':\n        return !IsAsciiDigit(ch);\n      case 'f':\n        return ch == '\\f';\n      case 'n':\n        return ch == '\\n';\n      case 'r':\n        return ch == '\\r';\n      case 's':\n        return IsAsciiWhiteSpace(ch);\n      case 'S':\n        return !IsAsciiWhiteSpace(ch);\n      case 't':\n        return ch == '\\t';\n      case 'v':\n        return ch == '\\v';\n      case 'w':\n        return IsAsciiWordChar(ch);\n      case 'W':\n        return !IsAsciiWordChar(ch);\n    }\n    return IsAsciiPunct(pattern_char) && pattern_char == ch;\n  }\n\n  return (pattern_char == '.' && ch != '\\n') || pattern_char == ch;\n}\n\n// Helper function used by ValidateRegex() to format error messages.\nstatic std::string FormatRegexSyntaxError(const char* regex, int index) {\n  return (Message() << \"Syntax error at index \" << index\n                    << \" in simple regular expression \\\"\" << regex << \"\\\": \")\n      .GetString();\n}\n\n// Generates non-fatal failures and returns false if regex is invalid;\n// otherwise returns true.\nbool ValidateRegex(const char* regex) {\n  if (regex == nullptr) {\n    ADD_FAILURE() << \"NULL is not a valid simple regular expression.\";\n    return false;\n  }\n\n  bool is_valid = true;\n\n  // True if and only if ?, *, or + can follow the previous atom.\n  bool prev_repeatable = false;\n  for (int i = 0; regex[i]; i++) {\n    if (regex[i] == '\\\\') {  // An escape sequence\n      i++;\n      if (regex[i] == '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"'\\\\' cannot appear at the end.\";\n        return false;\n      }\n\n      if (!IsValidEscape(regex[i])) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"invalid escape sequence \\\"\\\\\" << regex[i] << \"\\\".\";\n        is_valid = false;\n      }\n      prev_repeatable = true;\n    } else {  // Not an escape sequence.\n      const char ch = regex[i];\n\n      if (ch == '^' && i > 0) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'^' can only appear at the beginning.\";\n        is_valid = false;\n      } else if (ch == '$' && regex[i + 1] != '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'$' can only appear at the end.\";\n        is_valid = false;\n      } else if (IsInSet(ch, \"()[]{}|\")) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << \"'\" << ch\n                      << \"' is unsupported.\";\n        is_valid = false;\n      } else if (IsRepeat(ch) && !prev_repeatable) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << \"'\" << ch\n                      << \"' can only follow a repeatable token.\";\n        is_valid = false;\n      }\n\n      prev_repeatable = !IsInSet(ch, \"^$?*+\");\n    }\n  }\n\n  return is_valid;\n}\n\n// Matches a repeated regex atom followed by a valid simple regular\n// expression.  The regex atom is defined as c if escaped is false,\n// or \\c otherwise.  repeat is the repetition meta character (?, *,\n// or +).  The behavior is undefined if str contains too many\n// characters to be indexable by size_t, in which case the test will\n// probably time out anyway.  We are fine with this limitation as\n// std::string has it too.\nbool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,\n                                   const char* regex, const char* str) {\n  const size_t min_count = (repeat == '+') ? 1 : 0;\n  const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;\n  // We cannot call numeric_limits::max() as it conflicts with the\n  // max() macro on Windows.\n\n  for (size_t i = 0; i <= max_count; ++i) {\n    // We know that the atom matches each of the first i characters in str.\n    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {\n      // We have enough matches at the head, and the tail matches too.\n      // Since we only care about *whether* the pattern matches str\n      // (as opposed to *how* it matches), there is no need to find a\n      // greedy match.\n      return true;\n    }\n    if (str[i] == '\\0' || !AtomMatchesChar(escaped, c, str[i])) return false;\n  }\n  return false;\n}\n\n// Returns true if and only if regex matches a prefix of str. regex must\n// be a valid simple regular expression and not start with \"^\", or the\n// result is undefined.\nbool MatchRegexAtHead(const char* regex, const char* str) {\n  if (*regex == '\\0')  // An empty regex matches a prefix of anything.\n    return true;\n\n  // \"$\" only matches the end of a string.  Note that regex being\n  // valid guarantees that there's nothing after \"$\" in it.\n  if (*regex == '$') return *str == '\\0';\n\n  // Is the first thing in regex an escape sequence?\n  const bool escaped = *regex == '\\\\';\n  if (escaped) ++regex;\n  if (IsRepeat(regex[1])) {\n    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so\n    // here's an indirect recursion.  It terminates as the regex gets\n    // shorter in each recursion.\n    return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,\n                                         str);\n  } else {\n    // regex isn't empty, isn't \"$\", and doesn't start with a\n    // repetition.  We match the first atom of regex with the first\n    // character of str and recurse.\n    return (*str != '\\0') && AtomMatchesChar(escaped, *regex, *str) &&\n           MatchRegexAtHead(regex + 1, str + 1);\n  }\n}\n\n// Returns true if and only if regex matches any substring of str.  regex must\n// be a valid simple regular expression, or the result is undefined.\n//\n// The algorithm is recursive, but the recursion depth doesn't exceed\n// the regex length, so we won't need to worry about running out of\n// stack space normally.  In rare cases the time complexity can be\n// exponential with respect to the regex length + the string length,\n// but usually it's must faster (often close to linear).\nbool MatchRegexAnywhere(const char* regex, const char* str) {\n  if (regex == nullptr || str == nullptr) return false;\n\n  if (*regex == '^') return MatchRegexAtHead(regex + 1, str);\n\n  // A successful match can be anywhere in str.\n  do {\n    if (MatchRegexAtHead(regex, str)) return true;\n  } while (*str++ != '\\0');\n  return false;\n}\n\n// Implements the RE class.\n\nRE::~RE() = default;\n\n// Returns true if and only if regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str);\n}\n\n// Returns true if and only if regular expression re matches a substring of\n// str (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str);\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  full_pattern_.clear();\n  pattern_.clear();\n\n  if (regex != nullptr) {\n    pattern_ = regex;\n  }\n\n  is_valid_ = ValidateRegex(regex);\n  if (!is_valid_) {\n    // No need to calculate the full pattern when the regex is invalid.\n    return;\n  }\n\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match: we need space to prepend a '^' and append a '$'.\n  full_pattern_.reserve(pattern_.size() + 2);\n\n  if (pattern_.empty() || pattern_.front() != '^') {\n    full_pattern_.push_back('^');  // Makes sure full_pattern_ starts with '^'.\n  }\n\n  full_pattern_.append(pattern_);\n\n  if (pattern_.empty() || pattern_.back() != '$') {\n    full_pattern_.push_back('$');  // Makes sure full_pattern_ ends with '$'.\n  }\n}\n\n#endif  // GTEST_USES_POSIX_RE\n\nconst char kUnknownFile[] = \"unknown file\";\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {\n  const std::string file_name(file == nullptr ? kUnknownFile : file);\n\n  if (line < 0) {\n    return file_name + \":\";\n  }\n#ifdef _MSC_VER\n  return file_name + \"(\" + StreamableToString(line) + \"):\";\n#else\n  return file_name + \":\" + StreamableToString(line) + \":\";\n#endif  // _MSC_VER\n}\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\n// Note that FormatCompilerIndependentFileLocation() does NOT append colon\n// to the file location it produces, unlike FormatFileLocation().\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\n                                                               int line) {\n  const std::string file_name(file == nullptr ? kUnknownFile : file);\n\n  if (line < 0)\n    return file_name;\n  else\n    return file_name + \":\" + StreamableToString(line);\n}\n\nGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)\n    : severity_(severity) {\n  const char* const marker = severity == GTEST_INFO      ? \"[  INFO ]\"\n                             : severity == GTEST_WARNING ? \"[WARNING]\"\n                             : severity == GTEST_ERROR   ? \"[ ERROR ]\"\n                                                         : \"[ FATAL ]\";\n  GetStream() << ::std::endl\n              << marker << \" \" << FormatFileLocation(file, line).c_str()\n              << \": \";\n}\n\n// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\nGTestLog::~GTestLog() {\n  GetStream() << ::std::endl;\n  if (severity_ == GTEST_FATAL) {\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Disable Microsoft deprecation warnings for POSIX functions called from\n// this class (creat, dup, dup2, and close)\nGTEST_DISABLE_MSC_DEPRECATED_PUSH_()\n\nnamespace {\n\n#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)\nbool EndsWithPathSeparator(const std::string& path) {\n  return !path.empty() && path.back() == GTEST_PATH_SEP_[0];\n}\n#endif\n\n}  // namespace\n\n// Object that captures an output stream (stdout/stderr).\nclass CapturedStream {\n public:\n  // The ctor redirects the stream to a temporary file.\n  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {\n#ifdef GTEST_OS_WINDOWS\n    char temp_dir_path[MAX_PATH + 1] = {'\\0'};   // NOLINT\n    char temp_file_path[MAX_PATH + 1] = {'\\0'};  // NOLINT\n\n    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);\n    const UINT success = ::GetTempFileNameA(temp_dir_path, \"gtest_redir\",\n                                            0,  // Generate unique file name.\n                                            temp_file_path);\n    GTEST_CHECK_(success != 0)\n        << \"Unable to create a temporary file in \" << temp_dir_path;\n    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);\n    GTEST_CHECK_(captured_fd != -1)\n        << \"Unable to open temporary file \" << temp_file_path;\n    filename_ = temp_file_path;\n#else\n    // There's no guarantee that a test has write access to the current\n    // directory, so we create the temporary file in a temporary directory.\n    std::string name_template;\n\n#ifdef GTEST_OS_LINUX_ANDROID\n    // Note: Android applications are expected to call the framework's\n    // Context.getExternalStorageDirectory() method through JNI to get\n    // the location of the world-writable SD Card directory. However,\n    // this requires a Context handle, which cannot be retrieved\n    // globally from native code. Doing so also precludes running the\n    // code as part of a regular standalone executable, which doesn't\n    // run in a Dalvik process (e.g. when running it through 'adb shell').\n    //\n    // The location /data/local/tmp is directly accessible from native code.\n    // '/sdcard' and other variants cannot be relied on, as they are not\n    // guaranteed to be mounted, or may have a delay in mounting.\n    //\n    // However, prefer using the TMPDIR environment variable if set, as newer\n    // devices may have /data/local/tmp read-only.\n    name_template = TempDir();\n    if (!EndsWithPathSeparator(name_template))\n      name_template.push_back(GTEST_PATH_SEP_[0]);\n\n#elif defined(GTEST_OS_IOS)\n    char user_temp_dir[PATH_MAX + 1];\n\n    // Documented alternative to NSTemporaryDirectory() (for obtaining creating\n    // a temporary directory) at\n    // https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10\n    //\n    // _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not\n    // documented in the confstr() man page at\n    // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr\n    // but are still available, according to the WebKit patches at\n    // https://trac.webkit.org/changeset/262004/webkit\n    // https://trac.webkit.org/changeset/263705/webkit\n    //\n    // The confstr() implementation falls back to getenv(\"TMPDIR\"). See\n    // https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html\n    ::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));\n\n    name_template = user_temp_dir;\n    if (!EndsWithPathSeparator(name_template))\n      name_template.push_back(GTEST_PATH_SEP_[0]);\n#else\n    name_template = \"/tmp/\";\n#endif\n    name_template.append(\"gtest_captured_stream.XXXXXX\");\n\n    // mkstemp() modifies the string bytes in place, and does not go beyond the\n    // string's length. This results in well-defined behavior in C++17.\n    //\n    // The const_cast is needed below C++17. The constraints on std::string\n    // implementations in C++11 and above make assumption behind the const_cast\n    // fairly safe.\n    const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));\n    if (captured_fd == -1) {\n      GTEST_LOG_(WARNING)\n          << \"Failed to create tmp file \" << name_template\n          << \" for test; does the test have access to the /tmp directory?\";\n    }\n    filename_ = std::move(name_template);\n#endif  // GTEST_OS_WINDOWS\n    fflush(nullptr);\n    dup2(captured_fd, fd_);\n    close(captured_fd);\n  }\n\n  ~CapturedStream() { remove(filename_.c_str()); }\n\n  std::string GetCapturedString() {\n    if (uncaptured_fd_ != -1) {\n      // Restores the original stream.\n      fflush(nullptr);\n      dup2(uncaptured_fd_, fd_);\n      close(uncaptured_fd_);\n      uncaptured_fd_ = -1;\n    }\n\n    FILE* const file = posix::FOpen(filename_.c_str(), \"r\");\n    if (file == nullptr) {\n      GTEST_LOG_(FATAL) << \"Failed to open tmp file \" << filename_\n                        << \" for capturing stream.\";\n    }\n    const std::string content = ReadEntireFile(file);\n    posix::FClose(file);\n    return content;\n  }\n\n private:\n  const int fd_;  // A stream to capture.\n  int uncaptured_fd_;\n  // Name of the temporary file holding the stderr output.\n  ::std::string filename_;\n\n  CapturedStream(const CapturedStream&) = delete;\n  CapturedStream& operator=(const CapturedStream&) = delete;\n};\n\nGTEST_DISABLE_MSC_DEPRECATED_POP_()\n\nstatic CapturedStream* g_captured_stderr = nullptr;\nstatic CapturedStream* g_captured_stdout = nullptr;\n\n// Starts capturing an output stream (stdout/stderr).\nstatic void CaptureStream(int fd, const char* stream_name,\n                          CapturedStream** stream) {\n  if (*stream != nullptr) {\n    GTEST_LOG_(FATAL) << \"Only one \" << stream_name\n                      << \" capturer can exist at a time.\";\n  }\n  *stream = new CapturedStream(fd);\n}\n\n// Stops capturing the output stream and returns the captured string.\nstatic std::string GetCapturedStream(CapturedStream** captured_stream) {\n  const std::string content = (*captured_stream)->GetCapturedString();\n\n  delete *captured_stream;\n  *captured_stream = nullptr;\n\n  return content;\n}\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\n// MSVC and C++Builder do not provide a definition of STDERR_FILENO.\nconst int kStdOutFileno = 1;\nconst int kStdErrFileno = 2;\n#else\nconst int kStdOutFileno = STDOUT_FILENO;\nconst int kStdErrFileno = STDERR_FILENO;\n#endif  // defined(_MSC_VER) || defined(__BORLANDC__)\n\n// Starts capturing stdout.\nvoid CaptureStdout() {\n  CaptureStream(kStdOutFileno, \"stdout\", &g_captured_stdout);\n}\n\n// Starts capturing stderr.\nvoid CaptureStderr() {\n  CaptureStream(kStdErrFileno, \"stderr\", &g_captured_stderr);\n}\n\n// Stops capturing stdout and returns the captured string.\nstd::string GetCapturedStdout() {\n  return GetCapturedStream(&g_captured_stdout);\n}\n\n// Stops capturing stderr and returns the captured string.\nstd::string GetCapturedStderr() {\n  return GetCapturedStream(&g_captured_stderr);\n}\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\nsize_t GetFileSize(FILE* file) {\n  fseek(file, 0, SEEK_END);\n  return static_cast<size_t>(ftell(file));\n}\n\nstd::string ReadEntireFile(FILE* file) {\n  const size_t file_size = GetFileSize(file);\n  char* const buffer = new char[file_size];\n\n  size_t bytes_last_read = 0;  // # of bytes read in the last fread()\n  size_t bytes_read = 0;       // # of bytes read so far\n\n  fseek(file, 0, SEEK_SET);\n\n  // Keeps reading the file until we cannot read further or the\n  // pre-determined file size is reached.\n  do {\n    bytes_last_read =\n        fread(buffer + bytes_read, 1, file_size - bytes_read, file);\n    bytes_read += bytes_last_read;\n  } while (bytes_last_read > 0 && bytes_read < file_size);\n\n  const std::string content(buffer, bytes_read);\n  delete[] buffer;\n\n  return content;\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\nstatic const std::vector<std::string>* g_injected_test_argvs =\n    nullptr;  // Owned.\n\nstd::vector<std::string> GetInjectableArgvs() {\n  if (g_injected_test_argvs != nullptr) {\n    return *g_injected_test_argvs;\n  }\n  return GetArgvs();\n}\n\nvoid SetInjectableArgvs(const std::vector<std::string>* new_argvs) {\n  if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;\n  g_injected_test_argvs = new_argvs;\n}\n\nvoid SetInjectableArgvs(const std::vector<std::string>& new_argvs) {\n  SetInjectableArgvs(\n      new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));\n}\n\nvoid ClearInjectableArgvs() {\n  delete g_injected_test_argvs;\n  g_injected_test_argvs = nullptr;\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\nnamespace posix {\nvoid Abort() {\n  DebugBreak();\n  TerminateProcess(GetCurrentProcess(), 1);\n}\n}  // namespace posix\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Returns the name of the environment variable corresponding to the\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\n// \"GTEST_FOO\" in the open-source version.\nstatic std::string FlagToEnvVar(const char* flag) {\n  const std::string full_flag =\n      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();\n\n  Message env_var;\n  for (size_t i = 0; i != full_flag.length(); i++) {\n    env_var << ToUpper(full_flag.c_str()[i]);\n  }\n\n  return env_var.GetString();\n}\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\n// the result to *value and returns true; otherwise leaves *value\n// unchanged and returns false.\nbool ParseInt32(const Message& src_text, const char* str, int32_t* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const long long_value = strtol(str, &end, 10);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\"\n        << \" has value \\\"\" << str << \"\\\".\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  // Is the parsed value in the range of an int32_t?\n  const auto result = static_cast<int32_t>(long_value);\n  if (long_value == LONG_MAX || long_value == LONG_MIN ||\n      // The parsed value overflows as a long.  (strtol() returns\n      // LONG_MAX or LONG_MIN when the input overflows.)\n      result != long_value\n      // The parsed value overflows as an int32_t.\n  ) {\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\" << \" has value \"\n        << str << \", which overflows.\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  *value = result;\n  return true;\n}\n\n// Reads and returns the Boolean environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\n//\n// The value is considered true if and only if it's not \"0\".\nbool BoolFromGTestEnv(const char* flag, bool default_value) {\n#if defined(GTEST_GET_BOOL_FROM_ENV_)\n  return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  return string_value == nullptr ? default_value\n                                 : strcmp(string_value, \"0\") != 0;\n#endif  // defined(GTEST_GET_BOOL_FROM_ENV_)\n}\n\n// Reads and returns a 32-bit integer stored in the environment\n// variable corresponding to the given flag; if it isn't set or\n// doesn't represent a valid 32-bit integer, returns default_value.\nint32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {\n#if defined(GTEST_GET_INT32_FROM_ENV_)\n  return GTEST_GET_INT32_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  if (string_value == nullptr) {\n    // The environment variable is not set.\n    return default_value;\n  }\n\n  int32_t result = default_value;\n  if (!ParseInt32(Message() << \"Environment variable \" << env_var, string_value,\n                  &result)) {\n    printf(\"The default value %s is used.\\n\",\n           (Message() << default_value).GetString().c_str());\n    fflush(stdout);\n    return default_value;\n  }\n\n  return result;\n#endif  // defined(GTEST_GET_INT32_FROM_ENV_)\n}\n\n// As a special case for the 'output' flag, if GTEST_OUTPUT is not\n// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build\n// system.  The value of XML_OUTPUT_FILE is a filename without the\n// \"xml:\" prefix of GTEST_OUTPUT.\n// Note that this is meant to be called at the call site so it does\n// not check that the flag is 'output'\n// In essence this checks an env variable called XML_OUTPUT_FILE\n// and if it is set we prepend \"xml:\" to its value, if it not set we return \"\"\nstd::string OutputFlagAlsoCheckEnvVar() {\n  std::string default_value_for_output_flag = \"\";\n  const char* xml_output_file_env = posix::GetEnv(\"XML_OUTPUT_FILE\");\n  if (nullptr != xml_output_file_env) {\n    default_value_for_output_flag = std::string(\"xml:\") + xml_output_file_env;\n  }\n  return default_value_for_output_flag;\n}\n\n// Reads and returns the string environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\nconst char* StringFromGTestEnv(const char* flag, const char* default_value) {\n#if defined(GTEST_GET_STRING_FROM_ENV_)\n  return GTEST_GET_STRING_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value = posix::GetEnv(env_var.c_str());\n  return value == nullptr ? default_value : value;\n#endif  // defined(GTEST_GET_STRING_FROM_ENV_)\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-printers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test - The Google C++ Testing and Mocking Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// It uses the << operator when possible, and prints the bytes in the\n// object otherwise.  A user can override its behavior for a class\n// type Foo by defining either operator<<(::std::ostream&, const Foo&)\n// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that\n// defines Foo.\n\n#include \"gtest/gtest-printers.h\"\n\n#include <stdio.h>\n\n#include <cctype>\n#include <cstdint>\n#include <cwchar>\n#include <iomanip>\n#include <ios>\n#include <ostream>  // NOLINT\n#include <string>\n#include <type_traits>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\nnamespace {\n\nusing ::std::ostream;\n\n// Prints a segment of bytes in the given object.\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_THREAD_\nvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,\n                                size_t count, ostream* os) {\n  char text[5] = \"\";\n  for (size_t i = 0; i != count; i++) {\n    const size_t j = start + i;\n    if (i != 0) {\n      // Organizes the bytes into groups of 2 for easy parsing by\n      // human.\n      if ((j % 2) == 0)\n        *os << ' ';\n      else\n        *os << '-';\n    }\n    GTEST_SNPRINTF_(text, sizeof(text), \"%02X\", obj_bytes[j]);\n    *os << text;\n  }\n}\n\n// Prints the bytes in the given value to the given ostream.\nvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,\n                              ostream* os) {\n  // Tells the user how big the object is.\n  *os << count << \"-byte object <\";\n\n  const size_t kThreshold = 132;\n  const size_t kChunkSize = 64;\n  // If the object size is bigger than kThreshold, we'll have to omit\n  // some details by printing only the first and the last kChunkSize\n  // bytes.\n  if (count < kThreshold) {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);\n  } else {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);\n    *os << \" ... \";\n    // Rounds up to 2-byte boundary.\n    const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;\n    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);\n  }\n  *os << \">\";\n}\n\n// Helpers for widening a character to char32_t. Since the standard does not\n// specify if char / wchar_t is signed or unsigned, it is important to first\n// convert it to the unsigned type of the same width before widening it to\n// char32_t.\ntemplate <typename CharType>\nchar32_t ToChar32(CharType in) {\n  return static_cast<char32_t>(\n      static_cast<typename std::make_unsigned<CharType>::type>(in));\n}\n\n}  // namespace\n\nnamespace internal {\n\n// Delegates to PrintBytesInObjectToImpl() to print the bytes in the\n// given object.  The delegation simplifies the implementation, which\n// uses the << operator and thus is easier done outside of the\n// ::testing::internal namespace, which contains a << operator that\n// sometimes conflicts with the one in STL.\nvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,\n                          ostream* os) {\n  PrintBytesInObjectToImpl(obj_bytes, count, os);\n}\n\n// Depending on the value of a char (or wchar_t), we print it in one\n// of three formats:\n//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),\n//   - as a hexadecimal escape sequence (e.g. '\\x7F'), or\n//   - as a special escape sequence (e.g. '\\r', '\\n').\nenum CharFormat { kAsIs, kHexEscape, kSpecialEscape };\n\n// Returns true if c is a printable ASCII character.  We test the\n// value of c directly instead of calling isprint(), which is buggy on\n// Windows Mobile.\ninline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; }\n\n// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a\n// character literal without the quotes, escaping it when necessary; returns how\n// c was formatted.\ntemplate <typename Char>\nstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {\n  const char32_t u_c = ToChar32(c);\n  switch (u_c) {\n    case L'\\0':\n      *os << \"\\\\0\";\n      break;\n    case L'\\'':\n      *os << \"\\\\'\";\n      break;\n    case L'\\\\':\n      *os << \"\\\\\\\\\";\n      break;\n    case L'\\a':\n      *os << \"\\\\a\";\n      break;\n    case L'\\b':\n      *os << \"\\\\b\";\n      break;\n    case L'\\f':\n      *os << \"\\\\f\";\n      break;\n    case L'\\n':\n      *os << \"\\\\n\";\n      break;\n    case L'\\r':\n      *os << \"\\\\r\";\n      break;\n    case L'\\t':\n      *os << \"\\\\t\";\n      break;\n    case L'\\v':\n      *os << \"\\\\v\";\n      break;\n    default:\n      if (IsPrintableAscii(u_c)) {\n        *os << static_cast<char>(c);\n        return kAsIs;\n      } else {\n        ostream::fmtflags flags = os->flags();\n        *os << \"\\\\x\" << std::hex << std::uppercase << static_cast<int>(u_c);\n        os->flags(flags);\n        return kHexEscape;\n      }\n  }\n  return kSpecialEscape;\n}\n\n// Prints a char32_t c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {\n  switch (c) {\n    case L'\\'':\n      *os << \"'\";\n      return kAsIs;\n    case L'\"':\n      *os << \"\\\\\\\"\";\n      return kSpecialEscape;\n    default:\n      return PrintAsCharLiteralTo(c, os);\n  }\n}\n\nstatic const char* GetCharWidthPrefix(char) { return \"\"; }\n\nstatic const char* GetCharWidthPrefix(signed char) { return \"\"; }\n\nstatic const char* GetCharWidthPrefix(unsigned char) { return \"\"; }\n\n#ifdef __cpp_lib_char8_t\nstatic const char* GetCharWidthPrefix(char8_t) { return \"u8\"; }\n#endif\n\nstatic const char* GetCharWidthPrefix(char16_t) { return \"u\"; }\n\nstatic const char* GetCharWidthPrefix(char32_t) { return \"U\"; }\n\nstatic const char* GetCharWidthPrefix(wchar_t) { return \"L\"; }\n\n// Prints a char c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsStringLiteralTo(char c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\n#ifdef __cpp_lib_char8_t\nstatic CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n#endif\n\nstatic CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\nstatic CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\n// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t)\n// and its code. '\\0' is printed as \"'\\\\0'\", other unprintable characters are\n// also properly escaped using the standard C++ escape sequence.\ntemplate <typename Char>\nvoid PrintCharAndCodeTo(Char c, ostream* os) {\n  // First, print c as a literal in the most readable form we can find.\n  *os << GetCharWidthPrefix(c) << \"'\";\n  const CharFormat format = PrintAsCharLiteralTo(c, os);\n  *os << \"'\";\n\n  // To aid user debugging, we also print c's code in decimal, unless\n  // it's 0 (in which case c was printed as '\\\\0', making the code\n  // obvious).\n  if (c == 0) return;\n  *os << \" (\" << static_cast<int>(c);\n\n  // For more convenience, we print c's code again in hexadecimal,\n  // unless c was already printed in the form '\\x##' or the code is in\n  // [1, 9].\n  if (format == kHexEscape || (1 <= c && c <= 9)) {\n    // Do nothing.\n  } else {\n    *os << \", 0x\" << String::FormatHexInt(static_cast<int>(c));\n  }\n  *os << \")\";\n}\n\nvoid PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }\nvoid PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }\n\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its code.  L'\\0' is printed as \"L'\\\\0'\".\nvoid PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); }\n\n// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well.\nvoid PrintTo(char32_t c, ::std::ostream* os) {\n  *os << std::hex << \"U+\" << std::uppercase << std::setfill('0') << std::setw(4)\n      << static_cast<uint32_t>(c);\n}\n\n// gcc/clang __{u,}int128_t\n#if defined(__SIZEOF_INT128__)\nvoid PrintTo(__uint128_t v, ::std::ostream* os) {\n  if (v == 0) {\n    *os << \"0\";\n    return;\n  }\n\n  // Buffer large enough for ceil(log10(2^128))==39 and the null terminator\n  char buf[40];\n  char* p = buf + sizeof(buf);\n\n  // Some configurations have a __uint128_t, but no support for built in\n  // division. Do manual long division instead.\n\n  uint64_t high = static_cast<uint64_t>(v >> 64);\n  uint64_t low = static_cast<uint64_t>(v);\n\n  *--p = 0;\n  while (high != 0 || low != 0) {\n    uint64_t high_mod = high % 10;\n    high = high / 10;\n    // This is the long division algorithm specialized for a divisor of 10 and\n    // only two elements.\n    // Notable values:\n    //   2^64 / 10 == 1844674407370955161\n    //   2^64 % 10 == 6\n    const uint64_t carry = 6 * high_mod + low % 10;\n    low = low / 10 + high_mod * 1844674407370955161 + carry / 10;\n\n    char digit = static_cast<char>(carry % 10);\n    *--p = static_cast<char>('0' + digit);\n  }\n  *os << p;\n}\nvoid PrintTo(__int128_t v, ::std::ostream* os) {\n  __uint128_t uv = static_cast<__uint128_t>(v);\n  if (v < 0) {\n    *os << \"-\";\n    uv = -uv;\n  }\n  PrintTo(uv, os);\n}\n#endif  // __SIZEOF_INT128__\n\n// Prints the given array of characters to the ostream.  CharType must be either\n// char, char8_t, char16_t, char32_t, or wchar_t.\n// The array starts at begin, the length is len, it may include '\\0' characters\n// and may not be NUL-terminated.\ntemplate <typename CharType>\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n    GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n        GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat\n        PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {\n  const char* const quote_prefix = GetCharWidthPrefix(*begin);\n  *os << quote_prefix << \"\\\"\";\n  bool is_previous_hex = false;\n  CharFormat print_format = kAsIs;\n  for (size_t index = 0; index < len; ++index) {\n    const CharType cur = begin[index];\n    if (is_previous_hex && IsXDigit(cur)) {\n      // Previous character is of '\\x..' form and this character can be\n      // interpreted as another hexadecimal digit in its number. Break string to\n      // disambiguate.\n      *os << \"\\\" \" << quote_prefix << \"\\\"\";\n    }\n    is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;\n    // Remember if any characters required hex escaping.\n    if (is_previous_hex) {\n      print_format = kHexEscape;\n    }\n  }\n  *os << \"\\\"\";\n  return print_format;\n}\n\n// Prints a (const) char/wchar_t array of 'len' elements, starting at address\n// 'begin'.  CharType must be either char or wchar_t.\ntemplate <typename CharType>\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n    GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n        GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void\n        UniversalPrintCharArray(const CharType* begin, size_t len,\n                                ostream* os) {\n  // The code\n  //   const char kFoo[] = \"foo\";\n  // generates an array of 4, not 3, elements, with the last one being '\\0'.\n  //\n  // Therefore when printing a char array, we don't print the last element if\n  // it's '\\0', such that the output matches the string literal as it's\n  // written in the source code.\n  if (len > 0 && begin[len - 1] == '\\0') {\n    PrintCharsAsStringTo(begin, len - 1, os);\n    return;\n  }\n\n  // If, however, the last element in the array is not '\\0', e.g.\n  //    const char kFoo[] = { 'f', 'o', 'o' };\n  // we must print the entire array.  We also print a message to indicate\n  // that the array is not NUL-terminated.\n  PrintCharsAsStringTo(begin, len, os);\n  *os << \" (no terminating NUL)\";\n}\n\n// Prints a (const) char array of 'len' elements, starting at address 'begin'.\nvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n#ifdef __cpp_lib_char8_t\n// Prints a (const) char8_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n#endif\n\n// Prints a (const) char16_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n// Prints a (const) char32_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n// Prints a (const) wchar_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\nnamespace {\n\n// Prints a null-terminated C-style string to the ostream.\ntemplate <typename Char>\nvoid PrintCStringTo(const Char* s, ostream* os) {\n  if (s == nullptr) {\n    *os << \"NULL\";\n  } else {\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\n    PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os);\n  }\n}\n\n}  // anonymous namespace\n\nvoid PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); }\n\n#ifdef __cpp_lib_char8_t\nvoid PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); }\n#endif\n\nvoid PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }\n\nvoid PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); }\n\n// MSVC compiler can be configured to define whar_t as a typedef\n// of unsigned short. Defining an overload for const wchar_t* in that case\n// would cause pointers to unsigned shorts be printed as wide strings,\n// possibly accessing more memory than intended and causing invalid\n// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when\n// wchar_t is implemented as a native type.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Prints the given wide C string to the ostream.\nvoid PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }\n#endif  // wchar_t is native\n\nnamespace {\n\nbool ContainsUnprintableControlCodes(const char* str, size_t length) {\n  const unsigned char* s = reinterpret_cast<const unsigned char*>(str);\n\n  for (size_t i = 0; i < length; i++) {\n    unsigned char ch = *s++;\n    if (std::iscntrl(ch)) {\n      switch (ch) {\n        case '\\t':\n        case '\\n':\n        case '\\r':\n          break;\n        default:\n          return true;\n      }\n    }\n  }\n  return false;\n}\n\nbool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; }\n\nbool IsValidUTF8(const char* str, size_t length) {\n  const unsigned char* s = reinterpret_cast<const unsigned char*>(str);\n\n  for (size_t i = 0; i < length;) {\n    unsigned char lead = s[i++];\n\n    if (lead <= 0x7f) {\n      continue;  // single-byte character (ASCII) 0..7F\n    }\n    if (lead < 0xc2) {\n      return false;  // trail byte or non-shortest form\n    } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {\n      ++i;  // 2-byte character\n    } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&\n               IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&\n               // check for non-shortest form and surrogate\n               (lead != 0xe0 || s[i] >= 0xa0) &&\n               (lead != 0xed || s[i] < 0xa0)) {\n      i += 2;  // 3-byte character\n    } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&\n               IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&\n               IsUTF8TrailByte(s[i + 2]) &&\n               // check for non-shortest form\n               (lead != 0xf0 || s[i] >= 0x90) &&\n               (lead != 0xf4 || s[i] < 0x90)) {\n      i += 3;  // 4-byte character\n    } else {\n      return false;\n    }\n  }\n  return true;\n}\n\nvoid ConditionalPrintAsText(const char* str, size_t length, ostream* os) {\n  if (!ContainsUnprintableControlCodes(str, length) &&\n      IsValidUTF8(str, length)) {\n    *os << \"\\n    As Text: \\\"\" << str << \"\\\"\";\n  }\n}\n\n}  // anonymous namespace\n\nvoid PrintStringTo(const ::std::string& s, ostream* os) {\n  if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {\n    if (GTEST_FLAG_GET(print_utf8)) {\n      ConditionalPrintAsText(s.data(), s.size(), os);\n    }\n  }\n}\n\n#ifdef __cpp_lib_char8_t\nvoid PrintU8StringTo(const ::std::u8string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif\n\nvoid PrintU16StringTo(const ::std::u16string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n\nvoid PrintU32StringTo(const ::std::u32string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n\n#if GTEST_HAS_STD_WSTRING\nvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n}  // namespace internal\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-test-part.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// The Google C++ Testing and Mocking Framework (Google Test)\n\n#include \"gtest/gtest-test-part.h\"\n\n#include <ostream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\n// Gets the summary of the failure message by omitting the stack trace\n// in it.\nstd::string TestPartResult::ExtractSummary(const char* message) {\n  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);\n  return stack_trace == nullptr ? message : std::string(message, stack_trace);\n}\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result) {\n  return os << internal::FormatFileLocation(result.file_name(),\n                                            result.line_number())\n            << \" \"\n            << (result.type() == TestPartResult::kSuccess ? \"Success\"\n                : result.type() == TestPartResult::kSkip  ? \"Skipped\"\n                : result.type() == TestPartResult::kFatalFailure\n                    ? \"Fatal failure\"\n                    : \"Non-fatal failure\")\n            << \":\\n\"\n            << result.message() << std::endl;\n}\n\n// Appends a TestPartResult to the array.\nvoid TestPartResultArray::Append(const TestPartResult& result) {\n  array_.push_back(result);\n}\n\n// Returns the TestPartResult at the given index (0-based).\nconst TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {\n  if (index < 0 || index >= size()) {\n    printf(\"\\nInvalid index (%d) into TestPartResultArray.\\n\", index);\n    internal::posix::Abort();\n  }\n\n  return array_[static_cast<size_t>(index)];\n}\n\n// Returns the number of TestPartResult objects in the array.\nint TestPartResultArray::size() const {\n  return static_cast<int>(array_.size());\n}\n\nnamespace internal {\n\nHasNewFatalFailureHelper::HasNewFatalFailureHelper()\n    : has_new_fatal_failure_(false),\n      original_reporter_(\n          GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);\n}\n\nHasNewFatalFailureHelper::~HasNewFatalFailureHelper() {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(\n      original_reporter_);\n}\n\nvoid HasNewFatalFailureHelper::ReportTestPartResult(\n    const TestPartResult& result) {\n  if (result.fatally_failed()) has_new_fatal_failure_ = true;\n  original_reporter_->ReportTestPartResult(result);\n}\n\n}  // namespace internal\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest-typed-test.cc",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/gtest-typed-test.h\"\n\n#include <set>\n#include <string>\n#include <vector>\n\n#include \"gtest/gtest.h\"\n\nnamespace testing {\nnamespace internal {\n\n// Skips to the first non-space char in str. Returns an empty string if str\n// contains only whitespace characters.\nstatic const char* SkipSpaces(const char* str) {\n  while (IsSpace(*str)) str++;\n  return str;\n}\n\nstatic std::vector<std::string> SplitIntoTestNames(const char* src) {\n  std::vector<std::string> name_vec;\n  src = SkipSpaces(src);\n  for (; src != nullptr; src = SkipComma(src)) {\n    name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));\n  }\n  return name_vec;\n}\n\n// Verifies that registered_tests match the test names in\n// registered_tests_; returns registered_tests if successful, or\n// aborts the program otherwise.\nconst char* TypedTestSuitePState::VerifyRegisteredTestNames(\n    const char* test_suite_name, const char* file, int line,\n    const char* registered_tests) {\n  RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));\n\n  typedef RegisteredTestsMap::const_iterator RegisteredTestIter;\n  registered_ = true;\n\n  std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);\n\n  Message errors;\n\n  std::set<std::string> tests;\n  for (std::vector<std::string>::const_iterator name_it = name_vec.begin();\n       name_it != name_vec.end(); ++name_it) {\n    const std::string& name = *name_it;\n    if (tests.count(name) != 0) {\n      errors << \"Test \" << name << \" is listed more than once.\\n\";\n      continue;\n    }\n\n    if (registered_tests_.count(name) != 0) {\n      tests.insert(name);\n    } else {\n      errors << \"No test named \" << name\n             << \" can be found in this test suite.\\n\";\n    }\n  }\n\n  for (RegisteredTestIter it = registered_tests_.begin();\n       it != registered_tests_.end(); ++it) {\n    if (tests.count(it->first) == 0) {\n      errors << \"You forgot to list test \" << it->first << \".\\n\";\n    }\n  }\n\n  const std::string& errors_str = errors.GetString();\n  if (!errors_str.empty()) {\n    fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\n            errors_str.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n\n  return registered_tests;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// The Google C++ Testing and Mocking Framework (Google Test)\n\n#include \"gtest/gtest.h\"\n\n#include <ctype.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include <wchar.h>\n#include <wctype.h>\n\n#include <algorithm>\n#include <chrono>  // NOLINT\n#include <cmath>\n#include <csignal>  // NOLINT: raise(3) is used on some platforms\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <initializer_list>\n#include <iomanip>\n#include <ios>\n#include <iostream>\n#include <iterator>\n#include <limits>\n#include <list>\n#include <map>\n#include <ostream>  // NOLINT\n#include <set>\n#include <sstream>\n#include <unordered_set>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-assertion-result.h\"\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/internal/custom/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_LINUX\n\n#include <fcntl.h>   // NOLINT\n#include <limits.h>  // NOLINT\n#include <sched.h>   // NOLINT\n// Declares vsnprintf().  This header is not available on Windows.\n#include <strings.h>   // NOLINT\n#include <sys/mman.h>  // NOLINT\n#include <sys/time.h>  // NOLINT\n#include <unistd.h>    // NOLINT\n\n#include <string>\n\n#elif defined(GTEST_OS_ZOS)\n#include <sys/time.h>  // NOLINT\n\n// On z/OS we additionally need strings.h for strcasecmp.\n#include <strings.h>   // NOLINT\n\n#elif defined(GTEST_OS_WINDOWS_MOBILE)  // We are on Windows CE.\n\n#include <windows.h>  // NOLINT\n#undef min\n\n#elif defined(GTEST_OS_WINDOWS)  // We are on Windows proper.\n\n#include <windows.h>  // NOLINT\n#undef min\n\n#ifdef _MSC_VER\n#include <crtdbg.h>  // NOLINT\n#endif\n\n#include <io.h>         // NOLINT\n#include <sys/stat.h>   // NOLINT\n#include <sys/timeb.h>  // NOLINT\n#include <sys/types.h>  // NOLINT\n\n#ifdef GTEST_OS_WINDOWS_MINGW\n#include <sys/time.h>  // NOLINT\n#endif                 // GTEST_OS_WINDOWS_MINGW\n\n#else\n\n// cpplint thinks that the header is already included, so we want to\n// silence it.\n#include <sys/time.h>  // NOLINT\n#include <unistd.h>    // NOLINT\n\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>\n#endif\n\n#if GTEST_CAN_STREAM_RESULTS_\n#include <arpa/inet.h>   // NOLINT\n#include <netdb.h>       // NOLINT\n#include <sys/socket.h>  // NOLINT\n#include <sys/types.h>   // NOLINT\n#endif\n\n#include \"src/gtest-internal-inl.h\"\n\n#ifdef GTEST_OS_WINDOWS\n#define vsnprintf _vsnprintf\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_MAC\n#ifndef GTEST_OS_IOS\n#include <crt_externs.h>\n#endif\n#endif\n\n#ifdef GTEST_HAS_ABSL\n#include \"absl/container/flat_hash_set.h\"\n#include \"absl/debugging/failure_signal_handler.h\"\n#include \"absl/debugging/stacktrace.h\"\n#include \"absl/debugging/symbolize.h\"\n#include \"absl/flags/parse.h\"\n#include \"absl/flags/usage.h\"\n#include \"absl/strings/str_cat.h\"\n#include \"absl/strings/str_replace.h\"\n#include \"absl/strings/string_view.h\"\n#include \"absl/strings/strip.h\"\n#endif  // GTEST_HAS_ABSL\n\n// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs\n// at the callsite.\n#if defined(__has_builtin)\n#define GTEST_HAS_BUILTIN(x) __has_builtin(x)\n#else\n#define GTEST_HAS_BUILTIN(x) 0\n#endif  // defined(__has_builtin)\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#define GTEST_HAS_ABSL_FLAGS\n#endif\n\nnamespace testing {\n\nusing internal::CountIf;\nusing internal::ForEach;\nusing internal::GetElementOr;\nusing internal::Shuffle;\n\n// Constants.\n\n// A test whose test suite name or test name matches this filter is\n// disabled and not run.\nstatic const char kDisableTestFilter[] = \"DISABLED_*:*/DISABLED_*\";\n\n// A test suite whose name matches this filter is considered a death\n// test suite and will be run before test suites whose name doesn't\n// match this filter.\nstatic const char kDeathTestSuiteFilter[] = \"*DeathTest:*DeathTest/*\";\n\n// A test filter that matches everything.\nstatic const char kUniversalFilter[] = \"*\";\n\n// The default output format.\nstatic const char kDefaultOutputFormat[] = \"xml\";\n// The default output file.\nstatic const char kDefaultOutputFile[] = \"test_detail\";\n\n// The environment variable name for the test shard index.\nstatic const char kTestShardIndex[] = \"GTEST_SHARD_INDEX\";\n// The environment variable name for the total number of test shards.\nstatic const char kTestTotalShards[] = \"GTEST_TOTAL_SHARDS\";\n// The environment variable name for the test shard status file.\nstatic const char kTestShardStatusFile[] = \"GTEST_SHARD_STATUS_FILE\";\n\nnamespace internal {\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nconst char kStackTraceMarker[] = \"\\nStack trace:\\n\";\n\n// g_help_flag is true if and only if the --help flag or an equivalent form\n// is specified on the command line.\nbool g_help_flag = false;\n\n#if GTEST_HAS_FILE_SYSTEM\n// Utility function to Open File for Writing\nstatic FILE* OpenFileForWriting(const std::string& output_file) {\n  FILE* fileout = nullptr;\n  FilePath output_file_path(output_file);\n  FilePath output_dir(output_file_path.RemoveFileName());\n\n  if (output_dir.CreateDirectoriesRecursively()) {\n    fileout = posix::FOpen(output_file.c_str(), \"w\");\n  }\n  if (fileout == nullptr) {\n    GTEST_LOG_(FATAL) << \"Unable to open file \\\"\" << output_file << \"\\\"\";\n  }\n  return fileout;\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n}  // namespace internal\n\n// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY\n// environment variable.\nstatic const char* GetDefaultFilter() {\n  const char* const testbridge_test_only =\n      internal::posix::GetEnv(\"TESTBRIDGE_TEST_ONLY\");\n  if (testbridge_test_only != nullptr) {\n    return testbridge_test_only;\n  }\n  return kUniversalFilter;\n}\n\n// Bazel passes in the argument to '--test_runner_fail_fast' via the\n// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable.\nstatic bool GetDefaultFailFast() {\n  const char* const testbridge_test_runner_fail_fast =\n      internal::posix::GetEnv(\"TESTBRIDGE_TEST_RUNNER_FAIL_FAST\");\n  if (testbridge_test_runner_fail_fast != nullptr) {\n    return strcmp(testbridge_test_runner_fail_fast, \"1\") == 0;\n  }\n  return false;\n}\n\n}  // namespace testing\n\nGTEST_DEFINE_bool_(\n    fail_fast,\n    testing::internal::BoolFromGTestEnv(\"fail_fast\",\n                                        testing::GetDefaultFailFast()),\n    \"True if and only if a test failure should stop further test execution.\");\n\nGTEST_DEFINE_bool_(\n    also_run_disabled_tests,\n    testing::internal::BoolFromGTestEnv(\"also_run_disabled_tests\", false),\n    \"Run disabled tests too, in addition to the tests normally being run.\");\n\nGTEST_DEFINE_bool_(\n    break_on_failure,\n    testing::internal::BoolFromGTestEnv(\"break_on_failure\", false),\n    \"True if and only if a failed assertion should be a debugger \"\n    \"break-point.\");\n\nGTEST_DEFINE_bool_(catch_exceptions,\n                   testing::internal::BoolFromGTestEnv(\"catch_exceptions\",\n                                                       true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should catch exceptions and treat them as test failures.\");\n\nGTEST_DEFINE_string_(\n    color, testing::internal::StringFromGTestEnv(\"color\", \"auto\"),\n    \"Whether to use colors in the output.  Valid values: yes, no, \"\n    \"and auto.  'auto' means to use colors if the output is \"\n    \"being sent to a terminal and the TERM environment variable \"\n    \"is set to a terminal type that supports colors.\");\n\nGTEST_DEFINE_string_(\n    filter,\n    testing::internal::StringFromGTestEnv(\"filter\",\n                                          testing::GetDefaultFilter()),\n    \"A colon-separated list of glob (not regex) patterns \"\n    \"for filtering the tests to run, optionally followed by a \"\n    \"'-' and a : separated list of negative patterns (tests to \"\n    \"exclude).  A test is run if it matches one of the positive \"\n    \"patterns and does not match any of the negative patterns.\");\n\nGTEST_DEFINE_bool_(\n    install_failure_signal_handler,\n    testing::internal::BoolFromGTestEnv(\"install_failure_signal_handler\",\n                                        false),\n    \"If true and supported on the current platform, \" GTEST_NAME_\n    \" should \"\n    \"install a signal handler that dumps debugging information when fatal \"\n    \"signals are raised.\");\n\nGTEST_DEFINE_bool_(list_tests, false, \"List all tests without running them.\");\n\n// The net priority order after flag processing is thus:\n//   --gtest_output command line flag\n//   GTEST_OUTPUT environment variable\n//   XML_OUTPUT_FILE environment variable\n//   ''\nGTEST_DEFINE_string_(\n    output,\n    testing::internal::StringFromGTestEnv(\n        \"output\", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()),\n    \"A format (defaults to \\\"xml\\\" but can be specified to be \\\"json\\\"), \"\n    \"optionally followed by a colon and an output file name or directory. \"\n    \"A directory is indicated by a trailing pathname separator. \"\n    \"Examples: \\\"xml:filename.xml\\\", \\\"xml::directoryname/\\\". \"\n    \"If a directory is specified, output files will be created \"\n    \"within that directory, with file-names based on the test \"\n    \"executable's name and, if necessary, made unique by adding \"\n    \"digits.\");\n\nGTEST_DEFINE_bool_(\n    brief, testing::internal::BoolFromGTestEnv(\"brief\", false),\n    \"True if only test failures should be displayed in text output.\");\n\nGTEST_DEFINE_bool_(print_time,\n                   testing::internal::BoolFromGTestEnv(\"print_time\", true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should display elapsed time in text output.\");\n\nGTEST_DEFINE_bool_(print_utf8,\n                   testing::internal::BoolFromGTestEnv(\"print_utf8\", true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" prints UTF8 characters as text.\");\n\nGTEST_DEFINE_int32_(\n    random_seed, testing::internal::Int32FromGTestEnv(\"random_seed\", 0),\n    \"Random number seed to use when shuffling test orders.  Must be in range \"\n    \"[1, 99999], or 0 to use a seed based on the current time.\");\n\nGTEST_DEFINE_int32_(\n    repeat, testing::internal::Int32FromGTestEnv(\"repeat\", 1),\n    \"How many times to repeat each test.  Specify a negative number \"\n    \"for repeating forever.  Useful for shaking out flaky tests.\");\n\nGTEST_DEFINE_bool_(\n    recreate_environments_when_repeating,\n    testing::internal::BoolFromGTestEnv(\"recreate_environments_when_repeating\",\n                                        false),\n    \"Controls whether global test environments are recreated for each repeat \"\n    \"of the tests. If set to false the global test environments are only set \"\n    \"up once, for the first iteration, and only torn down once, for the last. \"\n    \"Useful for shaking out flaky tests with stable, expensive test \"\n    \"environments. If --gtest_repeat is set to a negative number, meaning \"\n    \"there is no last run, the environments will always be recreated to avoid \"\n    \"leaks.\");\n\nGTEST_DEFINE_bool_(show_internal_stack_frames, false,\n                   \"True if and only if \" GTEST_NAME_\n                   \" should include internal stack frames when \"\n                   \"printing test failure stack traces.\");\n\nGTEST_DEFINE_bool_(shuffle,\n                   testing::internal::BoolFromGTestEnv(\"shuffle\", false),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should randomize tests' order on every run.\");\n\nGTEST_DEFINE_int32_(\n    stack_trace_depth,\n    testing::internal::Int32FromGTestEnv(\"stack_trace_depth\",\n                                         testing::kMaxStackTraceDepth),\n    \"The maximum number of stack frames to print when an \"\n    \"assertion fails.  The valid range is 0 through 100, inclusive.\");\n\nGTEST_DEFINE_string_(\n    stream_result_to,\n    testing::internal::StringFromGTestEnv(\"stream_result_to\", \"\"),\n    \"This flag specifies the host name and the port number on which to stream \"\n    \"test results. Example: \\\"localhost:555\\\". The flag is effective only on \"\n    \"Linux and macOS.\");\n\nGTEST_DEFINE_bool_(\n    throw_on_failure,\n    testing::internal::BoolFromGTestEnv(\"throw_on_failure\", false),\n    \"When this flag is specified, a failed assertion will throw an exception \"\n    \"if exceptions are enabled or exit the program with a non-zero code \"\n    \"otherwise. For use with an external test framework.\");\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_\nGTEST_DEFINE_string_(\n    flagfile, testing::internal::StringFromGTestEnv(\"flagfile\", \"\"),\n    \"This flag specifies the flagfile to read command-line flags from.\");\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_\n\nnamespace testing {\nnamespace internal {\n\nconst uint32_t Random::kMaxRange;\n\n// Generates a random number from [0, range), using a Linear\n// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater\n// than kMaxRange.\nuint32_t Random::Generate(uint32_t range) {\n  // These constants are the same as are used in glibc's rand(3).\n  // Use wider types than necessary to prevent unsigned overflow diagnostics.\n  state_ = static_cast<uint32_t>(1103515245ULL * state_ + 12345U) % kMaxRange;\n\n  GTEST_CHECK_(range > 0) << \"Cannot generate a number in the range [0, 0).\";\n  GTEST_CHECK_(range <= kMaxRange)\n      << \"Generation of a number in [0, \" << range << \") was requested, \"\n      << \"but this can only generate numbers in [0, \" << kMaxRange << \").\";\n\n  // Converting via modulus introduces a bit of downward bias, but\n  // it's simple, and a linear congruential generator isn't too good\n  // to begin with.\n  return state_ % range;\n}\n\n// GTestIsInitialized() returns true if and only if the user has initialized\n// Google Test.  Useful for catching the user mistake of not initializing\n// Google Test before calling RUN_ALL_TESTS().\nstatic bool GTestIsInitialized() { return !GetArgvs().empty(); }\n\n// Iterates over a vector of TestSuites, keeping a running sum of the\n// results of calling a given int-returning method on each.\n// Returns the sum.\nstatic int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list,\n                                int (TestSuite::*method)() const) {\n  int sum = 0;\n  for (size_t i = 0; i < case_list.size(); i++) {\n    sum += (case_list[i]->*method)();\n  }\n  return sum;\n}\n\n// Returns true if and only if the test suite passed.\nstatic bool TestSuitePassed(const TestSuite* test_suite) {\n  return test_suite->should_run() && test_suite->Passed();\n}\n\n// Returns true if and only if the test suite failed.\nstatic bool TestSuiteFailed(const TestSuite* test_suite) {\n  return test_suite->should_run() && test_suite->Failed();\n}\n\n// Returns true if and only if test_suite contains at least one test that\n// should run.\nstatic bool ShouldRunTestSuite(const TestSuite* test_suite) {\n  return test_suite->should_run();\n}\n\nnamespace {\n\n// Returns true if test part results of type `type` should include a stack\n// trace.\nbool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {\n  // Suppress emission of the stack trace for SUCCEED() since it likely never\n  // requires investigation, and GTEST_SKIP() since skipping is an intentional\n  // act by the developer rather than a failure requiring investigation.\n  return type != TestPartResult::kSuccess && type != TestPartResult::kSkip;\n}\n\n}  // namespace\n\n// AssertHelper constructor.\nAssertHelper::AssertHelper(TestPartResult::Type type, const char* file,\n                           int line, const char* message)\n    : data_(new AssertHelperData(type, file, line, message)) {}\n\nAssertHelper::~AssertHelper() { delete data_; }\n\n// Message assignment, for assertion streaming support.\nvoid AssertHelper::operator=(const Message& message) const {\n  UnitTest::GetInstance()->AddTestPartResult(\n      data_->type, data_->file, data_->line,\n      AppendUserMessage(data_->message, message),\n      ShouldEmitStackTraceForResultType(data_->type)\n          ? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)\n          : \"\"\n      // Skips the stack frame for this function itself.\n  );  // NOLINT\n}\n\nnamespace {\n\n// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P\n// to creates test cases for it, a synthetic test case is\n// inserted to report ether an error or a log message.\n//\n// This configuration bit will likely be removed at some point.\nconstexpr bool kErrorOnUninstantiatedParameterizedTest = true;\nconstexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true;\n\n// A test that fails at a given file/line location with a given message.\nclass FailureTest : public Test {\n public:\n  explicit FailureTest(const CodeLocation& loc, std::string error_message,\n                       bool as_error)\n      : loc_(loc),\n        error_message_(std::move(error_message)),\n        as_error_(as_error) {}\n\n  void TestBody() override {\n    if (as_error_) {\n      AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(),\n                   loc_.line, \"\") = Message() << error_message_;\n    } else {\n      std::cout << error_message_ << std::endl;\n    }\n  }\n\n private:\n  const CodeLocation loc_;\n  const std::string error_message_;\n  const bool as_error_;\n};\n\n}  // namespace\n\nstd::set<std::string>* GetIgnoredParameterizedTestSuites() {\n  return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites();\n}\n\n// Add a given test_suit to the list of them allow to go un-instantiated.\nMarkAsIgnored::MarkAsIgnored(const char* test_suite) {\n  GetIgnoredParameterizedTestSuites()->insert(test_suite);\n}\n\n// If this parameterized test suite has no instantiations (and that\n// has not been marked as okay), emit a test case reporting that.\nvoid InsertSyntheticTestCase(const std::string& name, CodeLocation location,\n                             bool has_test_p) {\n  const auto& ignored = *GetIgnoredParameterizedTestSuites();\n  if (ignored.find(name) != ignored.end()) return;\n\n  const char kMissingInstantiation[] =  //\n      \" is defined via TEST_P, but never instantiated. None of the test \"\n      \"cases \"\n      \"will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only \"\n      \"ones provided expand to nothing.\"\n      \"\\n\\n\"\n      \"Ideally, TEST_P definitions should only ever be included as part of \"\n      \"binaries that intend to use them. (As opposed to, for example, being \"\n      \"placed in a library that may be linked in to get other utilities.)\";\n\n  const char kMissingTestCase[] =  //\n      \" is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are \"\n      \"defined via TEST_P . No test cases will run.\"\n      \"\\n\\n\"\n      \"Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from \"\n      \"code that always depend on code that provides TEST_P. Failing to do \"\n      \"so is often an indication of dead code, e.g. the last TEST_P was \"\n      \"removed but the rest got left behind.\";\n\n  std::string message =\n      \"Parameterized test suite \" + name +\n      (has_test_p ? kMissingInstantiation : kMissingTestCase) +\n      \"\\n\\n\"\n      \"To suppress this error for this test suite, insert the following line \"\n      \"(in a non-header) in the namespace it is defined in:\"\n      \"\\n\\n\"\n      \"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(\" +\n      name + \");\";\n\n  std::string full_name = \"UninstantiatedParameterizedTestSuite<\" + name + \">\";\n  RegisterTest(  //\n      \"GoogleTestVerification\", full_name.c_str(),\n      nullptr,  // No type parameter.\n      nullptr,  // No value parameter.\n      location.file.c_str(), location.line, [message, location] {\n        return new FailureTest(location, message,\n                               kErrorOnUninstantiatedParameterizedTest);\n      });\n}\n\nvoid RegisterTypeParameterizedTestSuite(const char* test_suite_name,\n                                        CodeLocation code_location) {\n  GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(\n      test_suite_name, std::move(code_location));\n}\n\nvoid RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {\n  GetUnitTestImpl()->type_parameterized_test_registry().RegisterInstantiation(\n      case_name);\n}\n\nvoid TypeParameterizedTestSuiteRegistry::RegisterTestSuite(\n    const char* test_suite_name, CodeLocation code_location) {\n  suites_.emplace(std::string(test_suite_name),\n                  TypeParameterizedTestSuiteInfo(std::move(code_location)));\n}\n\nvoid TypeParameterizedTestSuiteRegistry::RegisterInstantiation(\n    const char* test_suite_name) {\n  auto it = suites_.find(std::string(test_suite_name));\n  if (it != suites_.end()) {\n    it->second.instantiated = true;\n  } else {\n    GTEST_LOG_(ERROR) << \"Unknown type parameterized test suit '\"\n                      << test_suite_name << \"'\";\n  }\n}\n\nvoid TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {\n  const auto& ignored = *GetIgnoredParameterizedTestSuites();\n  for (const auto& testcase : suites_) {\n    if (testcase.second.instantiated) continue;\n    if (ignored.find(testcase.first) != ignored.end()) continue;\n\n    std::string message =\n        \"Type parameterized test suite \" + testcase.first +\n        \" is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated \"\n        \"via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run.\"\n        \"\\n\\n\"\n        \"Ideally, TYPED_TEST_P definitions should only ever be included as \"\n        \"part of binaries that intend to use them. (As opposed to, for \"\n        \"example, being placed in a library that may be linked in to get \"\n        \"other \"\n        \"utilities.)\"\n        \"\\n\\n\"\n        \"To suppress this error for this test suite, insert the following \"\n        \"line \"\n        \"(in a non-header) in the namespace it is defined in:\"\n        \"\\n\\n\"\n        \"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(\" +\n        testcase.first + \");\";\n\n    std::string full_name =\n        \"UninstantiatedTypeParameterizedTestSuite<\" + testcase.first + \">\";\n    RegisterTest(  //\n        \"GoogleTestVerification\", full_name.c_str(),\n        nullptr,  // No type parameter.\n        nullptr,  // No value parameter.\n        testcase.second.code_location.file.c_str(),\n        testcase.second.code_location.line, [message, testcase] {\n          return new FailureTest(testcase.second.code_location, message,\n                                 kErrorOnUninstantiatedTypeParameterizedTest);\n        });\n  }\n}\n\n// A copy of all command line arguments.  Set by InitGoogleTest().\nstatic ::std::vector<std::string> g_argvs;\n\n::std::vector<std::string> GetArgvs() {\n#if defined(GTEST_CUSTOM_GET_ARGVS_)\n  // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or\n  // ::string. This code converts it to the appropriate type.\n  const auto& custom = GTEST_CUSTOM_GET_ARGVS_();\n  return ::std::vector<std::string>(custom.begin(), custom.end());\n#else   // defined(GTEST_CUSTOM_GET_ARGVS_)\n  return g_argvs;\n#endif  // defined(GTEST_CUSTOM_GET_ARGVS_)\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the current application's name, removing directory path if that\n// is present.\nFilePath GetCurrentExecutableName() {\n  FilePath result;\n\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_OS2)\n  result.Set(FilePath(GetArgvs()[0]).RemoveExtension(\"exe\"));\n#else\n  result.Set(FilePath(GetArgvs()[0]));\n#endif  // GTEST_OS_WINDOWS\n\n  return result.RemoveDirectoryName();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Functions for processing the gtest_output flag.\n\n// Returns the output format, or \"\" for normal printed output.\nstd::string UnitTestOptions::GetOutputFormat() {\n  std::string s = GTEST_FLAG_GET(output);\n  const char* const gtest_output_flag = s.c_str();\n  const char* const colon = strchr(gtest_output_flag, ':');\n  return (colon == nullptr)\n             ? std::string(gtest_output_flag)\n             : std::string(gtest_output_flag,\n                           static_cast<size_t>(colon - gtest_output_flag));\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the name of the requested output file, or the default if none\n// was explicitly specified.\nstd::string UnitTestOptions::GetAbsolutePathToOutputFile() {\n  std::string s = GTEST_FLAG_GET(output);\n  const char* const gtest_output_flag = s.c_str();\n\n  std::string format = GetOutputFormat();\n  if (format.empty()) format = std::string(kDefaultOutputFormat);\n\n  const char* const colon = strchr(gtest_output_flag, ':');\n  if (colon == nullptr)\n    return internal::FilePath::MakeFileName(\n               internal::FilePath(\n                   UnitTest::GetInstance()->original_working_dir()),\n               internal::FilePath(kDefaultOutputFile), 0, format.c_str())\n        .string();\n\n  internal::FilePath output_name(colon + 1);\n  if (!output_name.IsAbsolutePath())\n    output_name = internal::FilePath::ConcatPaths(\n        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),\n        internal::FilePath(colon + 1));\n\n  if (!output_name.IsDirectory()) return output_name.string();\n\n  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(\n      output_name, internal::GetCurrentExecutableName(),\n      GetOutputFormat().c_str()));\n  return result.string();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Returns true if and only if the wildcard pattern matches the string. Each\n// pattern consists of regular characters, single-character wildcards (?), and\n// multi-character wildcards (*).\n//\n// This function implements a linear-time string globbing algorithm based on\n// https://research.swtch.com/glob.\nstatic bool PatternMatchesString(const std::string& name_str,\n                                 const char* pattern, const char* pattern_end) {\n  const char* name = name_str.c_str();\n  const char* const name_begin = name;\n  const char* const name_end = name + name_str.size();\n\n  const char* pattern_next = pattern;\n  const char* name_next = name;\n\n  while (pattern < pattern_end || name < name_end) {\n    if (pattern < pattern_end) {\n      switch (*pattern) {\n        default:  // Match an ordinary character.\n          if (name < name_end && *name == *pattern) {\n            ++pattern;\n            ++name;\n            continue;\n          }\n          break;\n        case '?':  // Match any single character.\n          if (name < name_end) {\n            ++pattern;\n            ++name;\n            continue;\n          }\n          break;\n        case '*':\n          // Match zero or more characters. Start by skipping over the wildcard\n          // and matching zero characters from name. If that fails, restart and\n          // match one more character than the last attempt.\n          pattern_next = pattern;\n          name_next = name + 1;\n          ++pattern;\n          continue;\n      }\n    }\n    // Failed to match a character. Restart if possible.\n    if (name_begin < name_next && name_next <= name_end) {\n      pattern = pattern_next;\n      name = name_next;\n      continue;\n    }\n    return false;\n  }\n  return true;\n}\n\nnamespace {\n\nbool IsGlobPattern(const std::string& pattern) {\n  return std::any_of(pattern.begin(), pattern.end(),\n                     [](const char c) { return c == '?' || c == '*'; });\n}\n\nclass UnitTestFilter {\n public:\n  UnitTestFilter() = default;\n\n  // Constructs a filter from a string of patterns separated by `:`.\n  explicit UnitTestFilter(const std::string& filter) {\n    // By design \"\" filter matches \"\" string.\n    std::vector<std::string> all_patterns;\n    SplitString(filter, ':', &all_patterns);\n    const auto exact_match_patterns_begin = std::partition(\n        all_patterns.begin(), all_patterns.end(), &IsGlobPattern);\n\n    glob_patterns_.reserve(static_cast<size_t>(\n        std::distance(all_patterns.begin(), exact_match_patterns_begin)));\n    std::move(all_patterns.begin(), exact_match_patterns_begin,\n              std::inserter(glob_patterns_, glob_patterns_.begin()));\n    std::move(\n        exact_match_patterns_begin, all_patterns.end(),\n        std::inserter(exact_match_patterns_, exact_match_patterns_.begin()));\n  }\n\n  // Returns true if and only if name matches at least one of the patterns in\n  // the filter.\n  bool MatchesName(const std::string& name) const {\n    return exact_match_patterns_.find(name) != exact_match_patterns_.end() ||\n           std::any_of(glob_patterns_.begin(), glob_patterns_.end(),\n                       [&name](const std::string& pattern) {\n                         return PatternMatchesString(\n                             name, pattern.c_str(),\n                             pattern.c_str() + pattern.size());\n                       });\n  }\n\n private:\n  std::vector<std::string> glob_patterns_;\n  std::unordered_set<std::string> exact_match_patterns_;\n};\n\nclass PositiveAndNegativeUnitTestFilter {\n public:\n  // Constructs a positive and a negative filter from a string. The string\n  // contains a positive filter optionally followed by a '-' character and a\n  // negative filter. In case only a negative filter is provided the positive\n  // filter will be assumed \"*\".\n  // A filter is a list of patterns separated by ':'.\n  explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) {\n    std::vector<std::string> positive_and_negative_filters;\n\n    // NOTE: `SplitString` always returns a non-empty container.\n    SplitString(filter, '-', &positive_and_negative_filters);\n    const auto& positive_filter = positive_and_negative_filters.front();\n\n    if (positive_and_negative_filters.size() > 1) {\n      positive_filter_ = UnitTestFilter(\n          positive_filter.empty() ? kUniversalFilter : positive_filter);\n\n      // TODO(b/214626361): Fail on multiple '-' characters\n      // For the moment to preserve old behavior we concatenate the rest of the\n      // string parts with `-` as separator to generate the negative filter.\n      auto negative_filter_string = positive_and_negative_filters[1];\n      for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++)\n        negative_filter_string =\n            negative_filter_string + '-' + positive_and_negative_filters[i];\n      negative_filter_ = UnitTestFilter(negative_filter_string);\n    } else {\n      // In case we don't have a negative filter and positive filter is \"\"\n      // we do not use kUniversalFilter by design as opposed to when we have a\n      // negative filter.\n      positive_filter_ = UnitTestFilter(positive_filter);\n    }\n  }\n\n  // Returns true if and only if test name (this is generated by appending test\n  // suit name and test name via a '.' character) matches the positive filter\n  // and does not match the negative filter.\n  bool MatchesTest(const std::string& test_suite_name,\n                   const std::string& test_name) const {\n    return MatchesName(test_suite_name + \".\" + test_name);\n  }\n\n  // Returns true if and only if name matches the positive filter and does not\n  // match the negative filter.\n  bool MatchesName(const std::string& name) const {\n    return positive_filter_.MatchesName(name) &&\n           !negative_filter_.MatchesName(name);\n  }\n\n private:\n  UnitTestFilter positive_filter_;\n  UnitTestFilter negative_filter_;\n};\n}  // namespace\n\nbool UnitTestOptions::MatchesFilter(const std::string& name_str,\n                                    const char* filter) {\n  return UnitTestFilter(filter).MatchesName(name_str);\n}\n\n// Returns true if and only if the user-specified filter matches the test\n// suite name and the test name.\nbool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,\n                                        const std::string& test_name) {\n  // Split --gtest_filter at '-', if there is one, to separate into\n  // positive filter and negative filter portions\n  return PositiveAndNegativeUnitTestFilter(GTEST_FLAG_GET(filter))\n      .MatchesTest(test_suite_name, test_name);\n}\n\n#if GTEST_HAS_SEH\nstatic std::string FormatSehExceptionMessage(DWORD exception_code,\n                                             const char* location) {\n  Message message;\n  message << \"SEH exception with code 0x\" << std::setbase(16) << exception_code\n          << std::setbase(10) << \" thrown in \" << location << \".\";\n  return message.GetString();\n}\n\nint UnitTestOptions::GTestProcessSEH(DWORD seh_code, const char* location) {\n  // Google Test should handle a SEH exception if:\n  //   1. the user wants it to, AND\n  //   2. this is not a breakpoint exception or stack overflow, AND\n  //   3. this is not a C++ exception (VC++ implements them via SEH,\n  //      apparently).\n  //\n  // SEH exception code for C++ exceptions.\n  // (see https://support.microsoft.com/kb/185294 for more information).\n  const DWORD kCxxExceptionCode = 0xe06d7363;\n\n  if (!GTEST_FLAG_GET(catch_exceptions) || seh_code == kCxxExceptionCode ||\n      seh_code == EXCEPTION_BREAKPOINT ||\n      seh_code == EXCEPTION_STACK_OVERFLOW) {\n    return EXCEPTION_CONTINUE_SEARCH;  // Don't handle these exceptions\n  }\n\n  internal::ReportFailureInUnknownLocation(\n      TestPartResult::kFatalFailure,\n      FormatSehExceptionMessage(seh_code, location) +\n          \"\\n\"\n          \"Stack trace:\\n\" +\n          ::testing::internal::GetCurrentOsStackTraceExceptTop(1));\n\n  return EXCEPTION_EXECUTE_HANDLER;\n}\n#endif  // GTEST_HAS_SEH\n\n}  // namespace internal\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results. Intercepts only failures from the current thread.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    TestPartResultArray* result)\n    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) {\n  Init();\n}\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    InterceptMode intercept_mode, TestPartResultArray* result)\n    : intercept_mode_(intercept_mode), result_(result) {\n  Init();\n}\n\nvoid ScopedFakeTestPartResultReporter::Init() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    old_reporter_ = impl->GetGlobalTestPartResultReporter();\n    impl->SetGlobalTestPartResultReporter(this);\n  } else {\n    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();\n    impl->SetTestPartResultReporterForCurrentThread(this);\n  }\n}\n\n// The d'tor restores the test part result reporter used by Google Test\n// before.\nScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    impl->SetGlobalTestPartResultReporter(old_reporter_);\n  } else {\n    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);\n  }\n}\n\n// Increments the test part result count and remembers the result.\n// This method is from the TestPartResultReporterInterface interface.\nvoid ScopedFakeTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  result_->Append(result);\n}\n\nnamespace internal {\n\n// Returns the type ID of ::testing::Test.  We should always call this\n// instead of GetTypeId< ::testing::Test>() to get the type ID of\n// testing::Test.  This is to work around a suspected linker bug when\n// using Google Test as a framework on Mac OS X.  The bug causes\n// GetTypeId< ::testing::Test>() to return different values depending\n// on whether the call is from the Google Test framework itself or\n// from user test code.  GetTestTypeId() is guaranteed to always\n// return the same value, as it always calls GetTypeId<>() from the\n// gtest.cc, which is within the Google Test framework.\nTypeId GetTestTypeId() { return GetTypeId<Test>(); }\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nextern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();\n\n// This predicate-formatter checks that 'results' contains a test part\n// failure of the given type and that the failure message contains the\n// given substring.\nstatic AssertionResult HasOneFailure(const char* /* results_expr */,\n                                     const char* /* type_expr */,\n                                     const char* /* substr_expr */,\n                                     const TestPartResultArray& results,\n                                     TestPartResult::Type type,\n                                     const std::string& substr) {\n  const std::string expected(type == TestPartResult::kFatalFailure\n                                 ? \"1 fatal failure\"\n                                 : \"1 non-fatal failure\");\n  Message msg;\n  if (results.size() != 1) {\n    msg << \"Expected: \" << expected << \"\\n\"\n        << \"  Actual: \" << results.size() << \" failures\";\n    for (int i = 0; i < results.size(); i++) {\n      msg << \"\\n\" << results.GetTestPartResult(i);\n    }\n    return AssertionFailure() << msg;\n  }\n\n  const TestPartResult& r = results.GetTestPartResult(0);\n  if (r.type() != type) {\n    return AssertionFailure() << \"Expected: \" << expected << \"\\n\"\n                              << \"  Actual:\\n\"\n                              << r;\n  }\n\n  if (strstr(r.message(), substr.c_str()) == nullptr) {\n    return AssertionFailure()\n           << \"Expected: \" << expected << \" containing \\\"\" << substr << \"\\\"\\n\"\n           << \"  Actual:\\n\"\n           << r;\n  }\n\n  return AssertionSuccess();\n}\n\n// The constructor of SingleFailureChecker remembers where to look up\n// test part results, what type of failure we expect, and what\n// substring the failure message should contain.\nSingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results,\n                                           TestPartResult::Type type,\n                                           const std::string& substr)\n    : results_(results), type_(type), substr_(substr) {}\n\n// The destructor of SingleFailureChecker verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nSingleFailureChecker::~SingleFailureChecker() {\n  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);\n}\n\nDefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(\n    UnitTestImpl* unit_test)\n    : unit_test_(unit_test) {}\n\nvoid DefaultGlobalTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->current_test_result()->AddTestPartResult(result);\n  unit_test_->listeners()->repeater()->OnTestPartResult(result);\n}\n\nDefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(\n    UnitTestImpl* unit_test)\n    : unit_test_(unit_test) {}\n\nvoid DefaultPerThreadTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);\n}\n\n// Returns the global test part result reporter.\nTestPartResultReporterInterface*\nUnitTestImpl::GetGlobalTestPartResultReporter() {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  return global_test_part_result_reporter_;\n}\n\n// Sets the global test part result reporter.\nvoid UnitTestImpl::SetGlobalTestPartResultReporter(\n    TestPartResultReporterInterface* reporter) {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  global_test_part_result_reporter_ = reporter;\n}\n\n// Returns the test part result reporter for the current thread.\nTestPartResultReporterInterface*\nUnitTestImpl::GetTestPartResultReporterForCurrentThread() {\n  return per_thread_test_part_result_reporter_.get();\n}\n\n// Sets the test part result reporter for the current thread.\nvoid UnitTestImpl::SetTestPartResultReporterForCurrentThread(\n    TestPartResultReporterInterface* reporter) {\n  per_thread_test_part_result_reporter_.set(reporter);\n}\n\n// Gets the number of successful test suites.\nint UnitTestImpl::successful_test_suite_count() const {\n  return CountIf(test_suites_, TestSuitePassed);\n}\n\n// Gets the number of failed test suites.\nint UnitTestImpl::failed_test_suite_count() const {\n  return CountIf(test_suites_, TestSuiteFailed);\n}\n\n// Gets the number of all test suites.\nint UnitTestImpl::total_test_suite_count() const {\n  return static_cast<int>(test_suites_.size());\n}\n\n// Gets the number of all test suites that contain at least one test\n// that should run.\nint UnitTestImpl::test_suite_to_run_count() const {\n  return CountIf(test_suites_, ShouldRunTestSuite);\n}\n\n// Gets the number of successful tests.\nint UnitTestImpl::successful_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count);\n}\n\n// Gets the number of skipped tests.\nint UnitTestImpl::skipped_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count);\n}\n\n// Gets the number of failed tests.\nint UnitTestImpl::failed_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count);\n}\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint UnitTestImpl::reportable_disabled_test_count() const {\n  return SumOverTestSuiteList(test_suites_,\n                              &TestSuite::reportable_disabled_test_count);\n}\n\n// Gets the number of disabled tests.\nint UnitTestImpl::disabled_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count);\n}\n\n// Gets the number of tests to be printed in the XML report.\nint UnitTestImpl::reportable_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count);\n}\n\n// Gets the number of all tests.\nint UnitTestImpl::total_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count);\n}\n\n// Gets the number of tests that should run.\nint UnitTestImpl::test_to_run_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count);\n}\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n// trace but Bar() and CurrentOsStackTraceExceptTop() won't.\nstd::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {\n  return os_stack_trace_getter()->CurrentStackTrace(\n      static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1\n      // Skips the user-specified number of frames plus this function\n      // itself.\n  );  // NOLINT\n}\n\n// A helper class for measuring elapsed times.\nclass Timer {\n public:\n  Timer() : start_(clock::now()) {}\n\n  // Return time elapsed in milliseconds since the timer was created.\n  TimeInMillis Elapsed() {\n    return std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() -\n                                                                 start_)\n        .count();\n  }\n\n private:\n  // Fall back to the system_clock when building with newlib on a system\n  // without a monotonic clock.\n#if defined(_NEWLIB_VERSION) && !defined(CLOCK_MONOTONIC)\n  using clock = std::chrono::system_clock;\n#else\n  using clock = std::chrono::steady_clock;\n#endif\n  clock::time_point start_;\n};\n\n// Returns a timestamp as milliseconds since the epoch. Note this time may jump\n// around subject to adjustments by the system, to measure elapsed time use\n// Timer instead.\nTimeInMillis GetTimeInMillis() {\n  return std::chrono::duration_cast<std::chrono::milliseconds>(\n             std::chrono::system_clock::now() -\n             std::chrono::system_clock::from_time_t(0))\n      .count();\n}\n\n// Utilities\n\n// class String.\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Creates a UTF-16 wide string from the given ANSI string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the wide string, or NULL if the\n// input is NULL.\nLPCWSTR String::AnsiToUtf16(const char* ansi) {\n  if (!ansi) return nullptr;\n  const int length = strlen(ansi);\n  const int unicode_length =\n      MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0);\n  WCHAR* unicode = new WCHAR[unicode_length + 1];\n  MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length);\n  unicode[unicode_length] = 0;\n  return unicode;\n}\n\n// Creates an ANSI string from the given wide string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the ANSI string, or NULL if the\n// input is NULL.\nconst char* String::Utf16ToAnsi(LPCWSTR utf16_str) {\n  if (!utf16_str) return nullptr;\n  const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr,\n                                              0, nullptr, nullptr);\n  char* ansi = new char[ansi_length + 1];\n  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr,\n                      nullptr);\n  ansi[ansi_length] = 0;\n  return ansi;\n}\n\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Compares two C strings.  Returns true if and only if they have the same\n// content.\n//\n// Unlike strcmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CStringEquals(const char* lhs, const char* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n  return strcmp(lhs, rhs) == 0;\n}\n\n#if GTEST_HAS_STD_WSTRING\n\n// Converts an array of wide chars to a narrow string using the UTF-8\n// encoding, and streams the result to the given Message object.\nstatic void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,\n                                     Message* msg) {\n  for (size_t i = 0; i != length;) {  // NOLINT\n    if (wstr[i] != L'\\0') {\n      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));\n      while (i != length && wstr[i] != L'\\0') i++;\n    } else {\n      *msg << '\\0';\n      i++;\n    }\n  }\n}\n\n#endif  // GTEST_HAS_STD_WSTRING\n\nvoid SplitString(const ::std::string& str, char delimiter,\n                 ::std::vector< ::std::string>* dest) {\n  ::std::vector< ::std::string> parsed;\n  ::std::string::size_type pos = 0;\n  while (::testing::internal::AlwaysTrue()) {\n    const ::std::string::size_type colon = str.find(delimiter, pos);\n    if (colon == ::std::string::npos) {\n      parsed.push_back(str.substr(pos));\n      break;\n    } else {\n      parsed.push_back(str.substr(pos, colon - pos));\n      pos = colon + 1;\n    }\n  }\n  dest->swap(parsed);\n}\n\n}  // namespace internal\n\n// Constructs an empty Message.\n// We allocate the stringstream separately because otherwise each use of\n// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's\n// stack frame leading to huge stack frames in some cases; gcc does not reuse\n// the stack space.\nMessage::Message() : ss_(new ::std::stringstream) {\n  // By default, we want there to be enough precision when printing\n  // a double to a Message.\n  *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);\n}\n\n// These two overloads allow streaming a wide C string to a Message\n// using the UTF-8 encoding.\nMessage& Message::operator<<(const wchar_t* wide_c_str) {\n  return *this << internal::String::ShowWideCString(wide_c_str);\n}\nMessage& Message::operator<<(wchar_t* wide_c_str) {\n  return *this << internal::String::ShowWideCString(wide_c_str);\n}\n\n#if GTEST_HAS_STD_WSTRING\n// Converts the given wide string to a narrow string using the UTF-8\n// encoding, and streams the result to this Message object.\nMessage& Message::operator<<(const ::std::wstring& wstr) {\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\n  return *this;\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n// Gets the text streamed to this object so far as an std::string.\n// Each '\\0' character in the buffer is replaced with \"\\\\0\".\nstd::string Message::GetString() const {\n  return internal::StringStreamToString(ss_.get());\n}\n\nnamespace internal {\n\nnamespace edit_distance {\nstd::vector<EditType> CalculateOptimalEdits(const std::vector<size_t>& left,\n                                            const std::vector<size_t>& right) {\n  std::vector<std::vector<double> > costs(\n      left.size() + 1, std::vector<double>(right.size() + 1));\n  std::vector<std::vector<EditType> > best_move(\n      left.size() + 1, std::vector<EditType>(right.size() + 1));\n\n  // Populate for empty right.\n  for (size_t l_i = 0; l_i < costs.size(); ++l_i) {\n    costs[l_i][0] = static_cast<double>(l_i);\n    best_move[l_i][0] = kRemove;\n  }\n  // Populate for empty left.\n  for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) {\n    costs[0][r_i] = static_cast<double>(r_i);\n    best_move[0][r_i] = kAdd;\n  }\n\n  for (size_t l_i = 0; l_i < left.size(); ++l_i) {\n    for (size_t r_i = 0; r_i < right.size(); ++r_i) {\n      if (left[l_i] == right[r_i]) {\n        // Found a match. Consume it.\n        costs[l_i + 1][r_i + 1] = costs[l_i][r_i];\n        best_move[l_i + 1][r_i + 1] = kMatch;\n        continue;\n      }\n\n      const double add = costs[l_i + 1][r_i];\n      const double remove = costs[l_i][r_i + 1];\n      const double replace = costs[l_i][r_i];\n      if (add < remove && add < replace) {\n        costs[l_i + 1][r_i + 1] = add + 1;\n        best_move[l_i + 1][r_i + 1] = kAdd;\n      } else if (remove < add && remove < replace) {\n        costs[l_i + 1][r_i + 1] = remove + 1;\n        best_move[l_i + 1][r_i + 1] = kRemove;\n      } else {\n        // We make replace a little more expensive than add/remove to lower\n        // their priority.\n        costs[l_i + 1][r_i + 1] = replace + 1.00001;\n        best_move[l_i + 1][r_i + 1] = kReplace;\n      }\n    }\n  }\n\n  // Reconstruct the best path. We do it in reverse order.\n  std::vector<EditType> best_path;\n  for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) {\n    EditType move = best_move[l_i][r_i];\n    best_path.push_back(move);\n    l_i -= move != kAdd;\n    r_i -= move != kRemove;\n  }\n  std::reverse(best_path.begin(), best_path.end());\n  return best_path;\n}\n\nnamespace {\n\n// Helper class to convert string into ids with deduplication.\nclass InternalStrings {\n public:\n  size_t GetId(const std::string& str) {\n    IdMap::iterator it = ids_.find(str);\n    if (it != ids_.end()) return it->second;\n    size_t id = ids_.size();\n    return ids_[str] = id;\n  }\n\n private:\n  typedef std::map<std::string, size_t> IdMap;\n  IdMap ids_;\n};\n\n}  // namespace\n\nstd::vector<EditType> CalculateOptimalEdits(\n    const std::vector<std::string>& left,\n    const std::vector<std::string>& right) {\n  std::vector<size_t> left_ids, right_ids;\n  {\n    InternalStrings intern_table;\n    for (size_t i = 0; i < left.size(); ++i) {\n      left_ids.push_back(intern_table.GetId(left[i]));\n    }\n    for (size_t i = 0; i < right.size(); ++i) {\n      right_ids.push_back(intern_table.GetId(right[i]));\n    }\n  }\n  return CalculateOptimalEdits(left_ids, right_ids);\n}\n\nnamespace {\n\n// Helper class that holds the state for one hunk and prints it out to the\n// stream.\n// It reorders adds/removes when possible to group all removes before all\n// adds. It also adds the hunk header before printint into the stream.\nclass Hunk {\n public:\n  Hunk(size_t left_start, size_t right_start)\n      : left_start_(left_start),\n        right_start_(right_start),\n        adds_(),\n        removes_(),\n        common_() {}\n\n  void PushLine(char edit, const char* line) {\n    switch (edit) {\n      case ' ':\n        ++common_;\n        FlushEdits();\n        hunk_.push_back(std::make_pair(' ', line));\n        break;\n      case '-':\n        ++removes_;\n        hunk_removes_.push_back(std::make_pair('-', line));\n        break;\n      case '+':\n        ++adds_;\n        hunk_adds_.push_back(std::make_pair('+', line));\n        break;\n    }\n  }\n\n  void PrintTo(std::ostream* os) {\n    PrintHeader(os);\n    FlushEdits();\n    for (std::list<std::pair<char, const char*> >::const_iterator it =\n             hunk_.begin();\n         it != hunk_.end(); ++it) {\n      *os << it->first << it->second << \"\\n\";\n    }\n  }\n\n  bool has_edits() const { return adds_ || removes_; }\n\n private:\n  void FlushEdits() {\n    hunk_.splice(hunk_.end(), hunk_removes_);\n    hunk_.splice(hunk_.end(), hunk_adds_);\n  }\n\n  // Print a unified diff header for one hunk.\n  // The format is\n  //   \"@@ -<left_start>,<left_length> +<right_start>,<right_length> @@\"\n  // where the left/right parts are omitted if unnecessary.\n  void PrintHeader(std::ostream* ss) const {\n    *ss << \"@@ \";\n    if (removes_) {\n      *ss << \"-\" << left_start_ << \",\" << (removes_ + common_);\n    }\n    if (removes_ && adds_) {\n      *ss << \" \";\n    }\n    if (adds_) {\n      *ss << \"+\" << right_start_ << \",\" << (adds_ + common_);\n    }\n    *ss << \" @@\\n\";\n  }\n\n  size_t left_start_, right_start_;\n  size_t adds_, removes_, common_;\n  std::list<std::pair<char, const char*> > hunk_, hunk_adds_, hunk_removes_;\n};\n\n}  // namespace\n\n// Create a list of diff hunks in Unified diff format.\n// Each hunk has a header generated by PrintHeader above plus a body with\n// lines prefixed with ' ' for no change, '-' for deletion and '+' for\n// addition.\n// 'context' represents the desired unchanged prefix/suffix around the diff.\n// If two hunks are close enough that their contexts overlap, then they are\n// joined into one hunk.\nstd::string CreateUnifiedDiff(const std::vector<std::string>& left,\n                              const std::vector<std::string>& right,\n                              size_t context) {\n  const std::vector<EditType> edits = CalculateOptimalEdits(left, right);\n\n  size_t l_i = 0, r_i = 0, edit_i = 0;\n  std::stringstream ss;\n  while (edit_i < edits.size()) {\n    // Find first edit.\n    while (edit_i < edits.size() && edits[edit_i] == kMatch) {\n      ++l_i;\n      ++r_i;\n      ++edit_i;\n    }\n\n    // Find the first line to include in the hunk.\n    const size_t prefix_context = std::min(l_i, context);\n    Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1);\n    for (size_t i = prefix_context; i > 0; --i) {\n      hunk.PushLine(' ', left[l_i - i].c_str());\n    }\n\n    // Iterate the edits until we found enough suffix for the hunk or the input\n    // is over.\n    size_t n_suffix = 0;\n    for (; edit_i < edits.size(); ++edit_i) {\n      if (n_suffix >= context) {\n        // Continue only if the next hunk is very close.\n        auto it = edits.begin() + static_cast<int>(edit_i);\n        while (it != edits.end() && *it == kMatch) ++it;\n        if (it == edits.end() ||\n            static_cast<size_t>(it - edits.begin()) - edit_i >= context) {\n          // There is no next edit or it is too far away.\n          break;\n        }\n      }\n\n      EditType edit = edits[edit_i];\n      // Reset count when a non match is found.\n      n_suffix = edit == kMatch ? n_suffix + 1 : 0;\n\n      if (edit == kMatch || edit == kRemove || edit == kReplace) {\n        hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str());\n      }\n      if (edit == kAdd || edit == kReplace) {\n        hunk.PushLine('+', right[r_i].c_str());\n      }\n\n      // Advance indices, depending on edit type.\n      l_i += edit != kAdd;\n      r_i += edit != kRemove;\n    }\n\n    if (!hunk.has_edits()) {\n      // We are done. We don't want this hunk.\n      break;\n    }\n\n    hunk.PrintTo(&ss);\n  }\n  return ss.str();\n}\n\n}  // namespace edit_distance\n\nnamespace {\n\n// The string representation of the values received in EqFailure() are already\n// escaped. Split them on escaped '\\n' boundaries. Leave all other escaped\n// characters the same.\nstd::vector<std::string> SplitEscapedString(const std::string& str) {\n  std::vector<std::string> lines;\n  size_t start = 0, end = str.size();\n  if (end > 2 && str[0] == '\"' && str[end - 1] == '\"') {\n    ++start;\n    --end;\n  }\n  bool escaped = false;\n  for (size_t i = start; i + 1 < end; ++i) {\n    if (escaped) {\n      escaped = false;\n      if (str[i] == 'n') {\n        lines.push_back(str.substr(start, i - start - 1));\n        start = i + 1;\n      }\n    } else {\n      escaped = str[i] == '\\\\';\n    }\n  }\n  lines.push_back(str.substr(start, end - start));\n  return lines;\n}\n\n}  // namespace\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   lhs_expression: \"foo\"\n//   rhs_expression: \"bar\"\n//   lhs_value:      \"5\"\n//   rhs_value:      \"6\"\n//\n// The ignoring_case parameter is true if and only if the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \"Ignoring case\" will\n// be inserted into the message.\nAssertionResult EqFailure(const char* lhs_expression,\n                          const char* rhs_expression,\n                          const std::string& lhs_value,\n                          const std::string& rhs_value, bool ignoring_case) {\n  Message msg;\n  msg << \"Expected equality of these values:\";\n  msg << \"\\n  \" << lhs_expression;\n  if (lhs_value != lhs_expression) {\n    msg << \"\\n    Which is: \" << lhs_value;\n  }\n  msg << \"\\n  \" << rhs_expression;\n  if (rhs_value != rhs_expression) {\n    msg << \"\\n    Which is: \" << rhs_value;\n  }\n\n  if (ignoring_case) {\n    msg << \"\\nIgnoring case\";\n  }\n\n  if (!lhs_value.empty() && !rhs_value.empty()) {\n    const std::vector<std::string> lhs_lines = SplitEscapedString(lhs_value);\n    const std::vector<std::string> rhs_lines = SplitEscapedString(rhs_value);\n    if (lhs_lines.size() > 1 || rhs_lines.size() > 1) {\n      msg << \"\\nWith diff:\\n\"\n          << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines);\n    }\n  }\n\n  return AssertionFailure() << msg;\n}\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nstd::string GetBoolAssertionFailureMessage(\n    const AssertionResult& assertion_result, const char* expression_text,\n    const char* actual_predicate_value, const char* expected_predicate_value) {\n  const char* actual_message = assertion_result.message();\n  Message msg;\n  msg << \"Value of: \" << expression_text\n      << \"\\n  Actual: \" << actual_predicate_value;\n  if (actual_message[0] != '\\0') msg << \" (\" << actual_message << \")\";\n  msg << \"\\nExpected: \" << expected_predicate_value;\n  return msg.GetString();\n}\n\n// Helper function for implementing ASSERT_NEAR.\nAssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2,\n                                     const char* abs_error_expr, double val1,\n                                     double val2, double abs_error) {\n  const double diff = fabs(val1 - val2);\n  if (diff <= abs_error) return AssertionSuccess();\n\n  // Find the value which is closest to zero.\n  const double min_abs = std::min(fabs(val1), fabs(val2));\n  // Find the distance to the next double from that value.\n  const double epsilon =\n      nextafter(min_abs, std::numeric_limits<double>::infinity()) - min_abs;\n  // Detect the case where abs_error is so small that EXPECT_NEAR is\n  // effectively the same as EXPECT_EQUAL, and give an informative error\n  // message so that the situation can be more easily understood without\n  // requiring exotic floating-point knowledge.\n  // Don't do an epsilon check if abs_error is zero because that implies\n  // that an equality check was actually intended.\n  if (!(std::isnan)(val1) && !(std::isnan)(val2) && abs_error > 0 &&\n      abs_error < epsilon) {\n    return AssertionFailure()\n           << \"The difference between \" << expr1 << \" and \" << expr2 << \" is \"\n           << diff << \", where\\n\"\n           << expr1 << \" evaluates to \" << val1 << \",\\n\"\n           << expr2 << \" evaluates to \" << val2 << \".\\nThe abs_error parameter \"\n           << abs_error_expr << \" evaluates to \" << abs_error\n           << \" which is smaller than the minimum distance between doubles for \"\n              \"numbers of this magnitude which is \"\n           << epsilon\n           << \", thus making this EXPECT_NEAR check equivalent to \"\n              \"EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead.\";\n  }\n  return AssertionFailure()\n         << \"The difference between \" << expr1 << \" and \" << expr2 << \" is \"\n         << diff << \", which exceeds \" << abs_error_expr << \", where\\n\"\n         << expr1 << \" evaluates to \" << val1 << \",\\n\"\n         << expr2 << \" evaluates to \" << val2 << \", and\\n\"\n         << abs_error_expr << \" evaluates to \" << abs_error << \".\";\n}\n\n// Helper template for implementing FloatLE() and DoubleLE().\ntemplate <typename RawType>\nAssertionResult FloatingPointLE(const char* expr1, const char* expr2,\n                                RawType val1, RawType val2) {\n  // Returns success if val1 is less than val2,\n  if (val1 < val2) {\n    return AssertionSuccess();\n  }\n\n  // or if val1 is almost equal to val2.\n  const FloatingPoint<RawType> lhs(val1), rhs(val2);\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  // Note that the above two checks will both fail if either val1 or\n  // val2 is NaN, as the IEEE floating-point standard requires that\n  // any predicate involving a NaN must return false.\n\n  ::std::stringstream val1_ss;\n  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val1;\n\n  ::std::stringstream val2_ss;\n  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val2;\n\n  return AssertionFailure()\n         << \"Expected: (\" << expr1 << \") <= (\" << expr2 << \")\\n\"\n         << \"  Actual: \" << StringStreamToString(&val1_ss) << \" vs \"\n         << StringStreamToString(&val2_ss);\n}\n\n}  // namespace internal\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult FloatLE(const char* expr1, const char* expr2, float val1,\n                        float val2) {\n  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);\n}\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult DoubleLE(const char* expr1, const char* expr2, double val1,\n                         double val2) {\n  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);\n}\n\nnamespace internal {\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\nAssertionResult CmpHelperSTREQ(const char* lhs_expression,\n                               const char* rhs_expression, const char* lhs,\n                               const char* rhs) {\n  if (String::CStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), false);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\nAssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,\n                                   const char* rhs_expression, const char* lhs,\n                                   const char* rhs) {\n  if (String::CaseInsensitiveCStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), true);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression, const char* s1,\n                               const char* s2) {\n  if (!String::CStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure()\n           << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n           << \"), actual: \\\"\" << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\nAssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                   const char* s2_expression, const char* s1,\n                                   const char* s2) {\n  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure()\n           << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n           << \") (ignoring case), actual: \\\"\" << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n}  // namespace internal\n\nnamespace {\n\n// Helper functions for implementing IsSubString() and IsNotSubstring().\n\n// This group of overloaded functions return true if and only if needle\n// is a substring of haystack.  NULL is considered a substring of\n// itself only.\n\nbool IsSubstringPred(const char* needle, const char* haystack) {\n  if (needle == nullptr || haystack == nullptr) return needle == haystack;\n\n  return strstr(haystack, needle) != nullptr;\n}\n\nbool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {\n  if (needle == nullptr || haystack == nullptr) return needle == haystack;\n\n  return wcsstr(haystack, needle) != nullptr;\n}\n\n// StringType here can be either ::std::string or ::std::wstring.\ntemplate <typename StringType>\nbool IsSubstringPred(const StringType& needle, const StringType& haystack) {\n  return haystack.find(needle) != StringType::npos;\n}\n\n// This function implements either IsSubstring() or IsNotSubstring(),\n// depending on the value of the expected_to_be_substring parameter.\n// StringType here can be const char*, const wchar_t*, ::std::string,\n// or ::std::wstring.\ntemplate <typename StringType>\nAssertionResult IsSubstringImpl(bool expected_to_be_substring,\n                                const char* needle_expr,\n                                const char* haystack_expr,\n                                const StringType& needle,\n                                const StringType& haystack) {\n  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)\n    return AssertionSuccess();\n\n  const bool is_wide_string = sizeof(needle[0]) > 1;\n  const char* const begin_string_quote = is_wide_string ? \"L\\\"\" : \"\\\"\";\n  return AssertionFailure()\n         << \"Value of: \" << needle_expr << \"\\n\"\n         << \"  Actual: \" << begin_string_quote << needle << \"\\\"\\n\"\n         << \"Expected: \" << (expected_to_be_substring ? \"\" : \"not \")\n         << \"a substring of \" << haystack_expr << \"\\n\"\n         << \"Which is: \" << begin_string_quote << haystack << \"\\\"\";\n}\n\n}  // namespace\n\n// IsSubstring() and IsNotSubstring() check whether needle is a\n// substring of haystack (NULL is considered a substring of itself\n// only), and return an appropriate error message when they fail.\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const char* needle, const char* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const wchar_t* needle, const wchar_t* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr, const char* needle,\n                               const char* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr, const wchar_t* needle,\n                               const wchar_t* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const ::std::string& needle,\n                            const ::std::string& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr,\n                               const ::std::string& needle,\n                               const ::std::string& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\n#if GTEST_HAS_STD_WSTRING\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const ::std::wstring& needle,\n                            const ::std::wstring& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr,\n                               const ::std::wstring& needle,\n                               const ::std::wstring& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n#ifdef GTEST_OS_WINDOWS\n\nnamespace {\n\n// Helper function for IsHRESULT{SuccessFailure} predicates\nAssertionResult HRESULTFailureHelper(const char* expr, const char* expected,\n                                     long hr) {  // NOLINT\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_TV_TITLE)\n\n  // Windows CE doesn't support FormatMessage.\n  const char error_text[] = \"\";\n\n#else\n\n  // Looks up the human-readable system message for the HRESULT code\n  // and since we're not passing any params to FormatMessage, we don't\n  // want inserts expanded.\n  const DWORD kFlags =\n      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;\n  const DWORD kBufSize = 4096;\n  // Gets the system's human readable message string for this HRESULT.\n  char error_text[kBufSize] = {'\\0'};\n  DWORD message_length = ::FormatMessageA(kFlags,\n                                          0,  // no source, we're asking system\n                                          static_cast<DWORD>(hr),  // the error\n                                          0,  // no line width restrictions\n                                          error_text,  // output buffer\n                                          kBufSize,    // buf size\n                                          nullptr);  // no arguments for inserts\n  // Trims tailing white space (FormatMessage leaves a trailing CR-LF)\n  for (; message_length && IsSpace(error_text[message_length - 1]);\n       --message_length) {\n    error_text[message_length - 1] = '\\0';\n  }\n\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  const std::string error_hex(\"0x\" + String::FormatHexInt(hr));\n  return ::testing::AssertionFailure()\n         << \"Expected: \" << expr << \" \" << expected << \".\\n\"\n         << \"  Actual: \" << error_hex << \" \" << error_text << \"\\n\";\n}\n\n}  // namespace\n\nAssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT\n  if (SUCCEEDED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"succeeds\", hr);\n}\n\nAssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT\n  if (FAILED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"fails\", hr);\n}\n\n#endif  // GTEST_OS_WINDOWS\n\n// Utility functions for encoding Unicode text (wide strings) in\n// UTF-8.\n\n// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8\n// like this:\n//\n// Code-point length   Encoding\n//   0 -  7 bits       0xxxxxxx\n//   8 - 11 bits       110xxxxx 10xxxxxx\n//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx\n//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n\n// The maximum code-point a one-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1;\n\n// The maximum code-point a two-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1;\n\n// The maximum code-point a three-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint3 =\n    (static_cast<uint32_t>(1) << (4 + 2 * 6)) - 1;\n\n// The maximum code-point a four-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint4 =\n    (static_cast<uint32_t>(1) << (3 + 3 * 6)) - 1;\n\n// Chops off the n lowest bits from a bit pattern.  Returns the n\n// lowest bits.  As a side effect, the original bit pattern will be\n// shifted to the right by n bits.\ninline uint32_t ChopLowBits(uint32_t* bits, int n) {\n  const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1);\n  *bits >>= n;\n  return low_bits;\n}\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type uint32_t because wchar_t may not be\n// wide enough to contain a code point.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\nstd::string CodePointToUtf8(uint32_t code_point) {\n  if (code_point > kMaxCodePoint4) {\n    return \"(Invalid Unicode 0x\" + String::FormatHexUInt32(code_point) + \")\";\n  }\n\n  char str[5];  // Big enough for the largest valid code point.\n  if (code_point <= kMaxCodePoint1) {\n    str[1] = '\\0';\n    str[0] = static_cast<char>(code_point);  // 0xxxxxxx\n  } else if (code_point <= kMaxCodePoint2) {\n    str[2] = '\\0';\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx\n  } else if (code_point <= kMaxCodePoint3) {\n    str[3] = '\\0';\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx\n  } else {  // code_point <= kMaxCodePoint4\n    str[4] = '\\0';\n    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx\n  }\n  return str;\n}\n\n// The following two functions only make sense if the system\n// uses UTF-16 for wide string encoding. All supported systems\n// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16.\n\n// Determines if the arguments constitute UTF-16 surrogate pair\n// and thus should be combined into a single Unicode code point\n// using CreateCodePointFromUtf16SurrogatePair.\ninline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {\n  return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 &&\n         (second & 0xFC00) == 0xDC00;\n}\n\n// Creates a Unicode code point from UTF16 surrogate pair.\ninline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,\n                                                      wchar_t second) {\n  const auto first_u = static_cast<uint32_t>(first);\n  const auto second_u = static_cast<uint32_t>(second);\n  const uint32_t mask = (1 << 10) - 1;\n  return (sizeof(wchar_t) == 2)\n             ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000\n             :\n             // This function should not be called when the condition is\n             // false, but we provide a sensible default in case it is.\n             first_u;\n}\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nstd::string WideStringToUtf8(const wchar_t* str, int num_chars) {\n  if (num_chars == -1) num_chars = static_cast<int>(wcslen(str));\n\n  ::std::stringstream stream;\n  for (int i = 0; i < num_chars; ++i) {\n    uint32_t unicode_code_point;\n\n    if (str[i] == L'\\0') {\n      break;\n    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {\n      unicode_code_point =\n          CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]);\n      i++;\n    } else {\n      unicode_code_point = static_cast<uint32_t>(str[i]);\n    }\n\n    stream << CodePointToUtf8(unicode_code_point);\n  }\n  return StringStreamToString(&stream);\n}\n\n// Converts a wide C string to an std::string using the UTF-8 encoding.\n// NULL will be converted to \"(null)\".\nstd::string String::ShowWideCString(const wchar_t* wide_c_str) {\n  if (wide_c_str == nullptr) return \"(null)\";\n\n  return internal::WideStringToUtf8(wide_c_str, -1);\n}\n\n// Compares two wide C strings.  Returns true if and only if they have the\n// same content.\n//\n// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n  return wcscmp(lhs, rhs) == 0;\n}\n\n// Helper function for *_STREQ on wide strings.\nAssertionResult CmpHelperSTREQ(const char* lhs_expression,\n                               const char* rhs_expression, const wchar_t* lhs,\n                               const wchar_t* rhs) {\n  if (String::WideCStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), false);\n}\n\n// Helper function for *_STRNE on wide strings.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression, const wchar_t* s1,\n                               const wchar_t* s2) {\n  if (!String::WideCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  }\n\n  return AssertionFailure()\n         << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n         << \"), actual: \" << PrintToString(s1) << \" vs \" << PrintToString(s2);\n}\n\n// Compares two C strings, ignoring case.  Returns true if and only if they have\n// the same content.\n//\n// Unlike strcasecmp(), this function can handle NULL argument(s).  A\n// NULL C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n  if (rhs == nullptr) return false;\n  return posix::StrCaseCmp(lhs, rhs) == 0;\n}\n\n// Compares two wide C strings, ignoring case.  Returns true if and only if they\n// have the same content.\n//\n// Unlike wcscasecmp(), this function can handle NULL argument(s).\n// A NULL C string is considered different to any non-NULL wide C string,\n// including the empty string.\n// NB: The implementations on different platforms slightly differ.\n// On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n// environment variable. On GNU platform this method uses wcscasecmp\n// which compares according to LC_CTYPE category of the current locale.\n// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n// current locale.\nbool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                              const wchar_t* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n#ifdef GTEST_OS_WINDOWS\n  return _wcsicmp(lhs, rhs) == 0;\n#elif defined(GTEST_OS_LINUX) && !defined(GTEST_OS_LINUX_ANDROID)\n  return wcscasecmp(lhs, rhs) == 0;\n#else\n  // Android, Mac OS X and Cygwin don't define wcscasecmp.\n  // Other unknown OSes may not define it either.\n  wint_t left, right;\n  do {\n    left = towlower(static_cast<wint_t>(*lhs++));\n    right = towlower(static_cast<wint_t>(*rhs++));\n  } while (left && left == right);\n  return left == right;\n#endif  // OS selector\n}\n\n// Returns true if and only if str ends with the given suffix, ignoring case.\n// Any string is considered to end with an empty suffix.\nbool String::EndsWithCaseInsensitive(const std::string& str,\n                                     const std::string& suffix) {\n  const size_t str_len = str.length();\n  const size_t suffix_len = suffix.length();\n  return (str_len >= suffix_len) &&\n         CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len,\n                                      suffix.c_str());\n}\n\n// Formats an int value as \"%02d\".\nstd::string String::FormatIntWidth2(int value) {\n  return FormatIntWidthN(value, 2);\n}\n\n// Formats an int value to given width with leading zeros.\nstd::string String::FormatIntWidthN(int value, int width) {\n  std::stringstream ss;\n  ss << std::setfill('0') << std::setw(width) << value;\n  return ss.str();\n}\n\n// Formats an int value as \"%X\".\nstd::string String::FormatHexUInt32(uint32_t value) {\n  std::stringstream ss;\n  ss << std::hex << std::uppercase << value;\n  return ss.str();\n}\n\n// Formats an int value as \"%X\".\nstd::string String::FormatHexInt(int value) {\n  return FormatHexUInt32(static_cast<uint32_t>(value));\n}\n\n// Formats a byte as \"%02X\".\nstd::string String::FormatByte(unsigned char value) {\n  std::stringstream ss;\n  ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase\n     << static_cast<unsigned int>(value);\n  return ss.str();\n}\n\n// Converts the buffer in a stringstream to an std::string, converting NUL\n// bytes to \"\\\\0\" along the way.\nstd::string StringStreamToString(::std::stringstream* ss) {\n  const ::std::string& str = ss->str();\n  const char* const start = str.c_str();\n  const char* const end = start + str.length();\n\n  std::string result;\n  result.reserve(static_cast<size_t>(2 * (end - start)));\n  for (const char* ch = start; ch != end; ++ch) {\n    if (*ch == '\\0') {\n      result += \"\\\\0\";  // Replaces NUL with \"\\\\0\";\n    } else {\n      result += *ch;\n    }\n  }\n\n  return result;\n}\n\n// Appends the user-supplied message to the Google-Test-generated message.\nstd::string AppendUserMessage(const std::string& gtest_msg,\n                              const Message& user_msg) {\n  // Appends the user message if it's non-empty.\n  const std::string user_msg_string = user_msg.GetString();\n  if (user_msg_string.empty()) {\n    return gtest_msg;\n  }\n  if (gtest_msg.empty()) {\n    return user_msg_string;\n  }\n  return gtest_msg + \"\\n\" + user_msg_string;\n}\n\n}  // namespace internal\n\n// class TestResult\n\n// Creates an empty TestResult.\nTestResult::TestResult()\n    : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}\n\n// D'tor.\nTestResult::~TestResult() = default;\n\n// Returns the i-th test part result among all the results. i can\n// range from 0 to total_part_count() - 1. If i is not in that range,\n// aborts the program.\nconst TestPartResult& TestResult::GetTestPartResult(int i) const {\n  if (i < 0 || i >= total_part_count()) internal::posix::Abort();\n  return test_part_results_.at(static_cast<size_t>(i));\n}\n\n// Returns the i-th test property. i can range from 0 to\n// test_property_count() - 1. If i is not in that range, aborts the\n// program.\nconst TestProperty& TestResult::GetTestProperty(int i) const {\n  if (i < 0 || i >= test_property_count()) internal::posix::Abort();\n  return test_properties_.at(static_cast<size_t>(i));\n}\n\n// Clears the test part results.\nvoid TestResult::ClearTestPartResults() { test_part_results_.clear(); }\n\n// Adds a test part result to the list.\nvoid TestResult::AddTestPartResult(const TestPartResult& test_part_result) {\n  test_part_results_.push_back(test_part_result);\n}\n\n// Adds a test property to the list. If a property with the same key as the\n// supplied property is already represented, the value of this test_property\n// replaces the old value for that key.\nvoid TestResult::RecordProperty(const std::string& xml_element,\n                                const TestProperty& test_property) {\n  if (!ValidateTestProperty(xml_element, test_property)) {\n    return;\n  }\n  internal::MutexLock lock(&test_properties_mutex_);\n  const std::vector<TestProperty>::iterator property_with_matching_key =\n      std::find_if(test_properties_.begin(), test_properties_.end(),\n                   internal::TestPropertyKeyIs(test_property.key()));\n  if (property_with_matching_key == test_properties_.end()) {\n    test_properties_.push_back(test_property);\n    return;\n  }\n  property_with_matching_key->SetValue(test_property.value());\n}\n\n// The list of reserved attributes used in the <testsuites> element of XML\n// output.\nstatic const char* const kReservedTestSuitesAttributes[] = {\n    \"disabled\",    \"errors\", \"failures\", \"name\",\n    \"random_seed\", \"tests\",  \"time\",     \"timestamp\"};\n\n// The list of reserved attributes used in the <testsuite> element of XML\n// output.\nstatic const char* const kReservedTestSuiteAttributes[] = {\n    \"disabled\", \"errors\", \"failures\",  \"name\",\n    \"tests\",    \"time\",   \"timestamp\", \"skipped\"};\n\n// The list of reserved attributes used in the <testcase> element of XML output.\nstatic const char* const kReservedTestCaseAttributes[] = {\n    \"classname\",  \"name\",        \"status\", \"time\",\n    \"type_param\", \"value_param\", \"file\",   \"line\"};\n\n// Use a slightly different set for allowed output to ensure existing tests can\n// still RecordProperty(\"result\") or RecordProperty(\"timestamp\")\nstatic const char* const kReservedOutputTestCaseAttributes[] = {\n    \"classname\",   \"name\", \"status\", \"time\",   \"type_param\",\n    \"value_param\", \"file\", \"line\",   \"result\", \"timestamp\"};\n\ntemplate <size_t kSize>\nstd::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {\n  return std::vector<std::string>(array, array + kSize);\n}\n\nstatic std::vector<std::string> GetReservedAttributesForElement(\n    const std::string& xml_element) {\n  if (xml_element == \"testsuites\") {\n    return ArrayAsVector(kReservedTestSuitesAttributes);\n  } else if (xml_element == \"testsuite\") {\n    return ArrayAsVector(kReservedTestSuiteAttributes);\n  } else if (xml_element == \"testcase\") {\n    return ArrayAsVector(kReservedTestCaseAttributes);\n  } else {\n    GTEST_CHECK_(false) << \"Unrecognized xml_element provided: \" << xml_element;\n  }\n  // This code is unreachable but some compilers may not realizes that.\n  return std::vector<std::string>();\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// TODO(jdesprez): Merge the two getReserved attributes once skip is improved\n// This function is only used when file systems are enabled.\nstatic std::vector<std::string> GetReservedOutputAttributesForElement(\n    const std::string& xml_element) {\n  if (xml_element == \"testsuites\") {\n    return ArrayAsVector(kReservedTestSuitesAttributes);\n  } else if (xml_element == \"testsuite\") {\n    return ArrayAsVector(kReservedTestSuiteAttributes);\n  } else if (xml_element == \"testcase\") {\n    return ArrayAsVector(kReservedOutputTestCaseAttributes);\n  } else {\n    GTEST_CHECK_(false) << \"Unrecognized xml_element provided: \" << xml_element;\n  }\n  // This code is unreachable but some compilers may not realizes that.\n  return std::vector<std::string>();\n}\n#endif\n\nstatic std::string FormatWordList(const std::vector<std::string>& words) {\n  Message word_list;\n  for (size_t i = 0; i < words.size(); ++i) {\n    if (i > 0 && words.size() > 2) {\n      word_list << \", \";\n    }\n    if (i == words.size() - 1) {\n      word_list << \"and \";\n    }\n    word_list << \"'\" << words[i] << \"'\";\n  }\n  return word_list.GetString();\n}\n\nstatic bool ValidateTestPropertyName(\n    const std::string& property_name,\n    const std::vector<std::string>& reserved_names) {\n  if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=\n      reserved_names.end()) {\n    ADD_FAILURE() << \"Reserved key used in RecordProperty(): \" << property_name\n                  << \" (\" << FormatWordList(reserved_names)\n                  << \" are reserved by \" << GTEST_NAME_ << \")\";\n    return false;\n  }\n  return true;\n}\n\n// Adds a failure if the key is a reserved attribute of the element named\n// xml_element.  Returns true if the property is valid.\nbool TestResult::ValidateTestProperty(const std::string& xml_element,\n                                      const TestProperty& test_property) {\n  return ValidateTestPropertyName(test_property.key(),\n                                  GetReservedAttributesForElement(xml_element));\n}\n\n// Clears the object.\nvoid TestResult::Clear() {\n  test_part_results_.clear();\n  test_properties_.clear();\n  death_test_count_ = 0;\n  elapsed_time_ = 0;\n}\n\n// Returns true off the test part was skipped.\nstatic bool TestPartSkipped(const TestPartResult& result) {\n  return result.skipped();\n}\n\n// Returns true if and only if the test was skipped.\nbool TestResult::Skipped() const {\n  return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0;\n}\n\n// Returns true if and only if the test failed.\nbool TestResult::Failed() const {\n  for (int i = 0; i < total_part_count(); ++i) {\n    if (GetTestPartResult(i).failed()) return true;\n  }\n  return false;\n}\n\n// Returns true if and only if the test part fatally failed.\nstatic bool TestPartFatallyFailed(const TestPartResult& result) {\n  return result.fatally_failed();\n}\n\n// Returns true if and only if the test fatally failed.\nbool TestResult::HasFatalFailure() const {\n  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;\n}\n\n// Returns true if and only if the test part non-fatally failed.\nstatic bool TestPartNonfatallyFailed(const TestPartResult& result) {\n  return result.nonfatally_failed();\n}\n\n// Returns true if and only if the test has a non-fatal failure.\nbool TestResult::HasNonfatalFailure() const {\n  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;\n}\n\n// Gets the number of all test parts.  This is the sum of the number\n// of successful test parts and the number of failed test parts.\nint TestResult::total_part_count() const {\n  return static_cast<int>(test_part_results_.size());\n}\n\n// Returns the number of the test properties.\nint TestResult::test_property_count() const {\n  return static_cast<int>(test_properties_.size());\n}\n\n// class Test\n\n// Creates a Test object.\n\n// The c'tor saves the states of all flags.\nTest::Test() : gtest_flag_saver_(new GTEST_FLAG_SAVER_) {}\n\n// The d'tor restores the states of all flags.  The actual work is\n// done by the d'tor of the gtest_flag_saver_ field, and thus not\n// visible here.\nTest::~Test() = default;\n\n// Sets up the test fixture.\n//\n// A sub-class may override this.\nvoid Test::SetUp() {}\n\n// Tears down the test fixture.\n//\n// A sub-class may override this.\nvoid Test::TearDown() {}\n\n// Allows user supplied key value pairs to be recorded for later output.\nvoid Test::RecordProperty(const std::string& key, const std::string& value) {\n  UnitTest::GetInstance()->RecordProperty(key, value);\n}\n\nnamespace internal {\n\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const std::string& message) {\n  // This function is a friend of UnitTest and as such has access to\n  // AddTestPartResult.\n  UnitTest::GetInstance()->AddTestPartResult(\n      result_type,\n      nullptr,  // No info about the source file where the exception occurred.\n      -1,       // We have no info on which line caused the exception.\n      message,\n      \"\");  // No stack trace, either.\n}\n\n}  // namespace internal\n\n// Google Test requires all tests in the same test suite to use the same test\n// fixture class.  This function checks if the current test has the\n// same fixture class as the first test in the current test suite.  If\n// yes, it returns true; otherwise it generates a Google Test failure and\n// returns false.\nbool Test::HasSameFixtureClass() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  const TestSuite* const test_suite = impl->current_test_suite();\n\n  // Info about the first test in the current test suite.\n  const TestInfo* const first_test_info = test_suite->test_info_list()[0];\n  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;\n  const char* const first_test_name = first_test_info->name();\n\n  // Info about the current test.\n  const TestInfo* const this_test_info = impl->current_test_info();\n  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;\n  const char* const this_test_name = this_test_info->name();\n\n  if (this_fixture_id != first_fixture_id) {\n    // Is the first test defined using TEST?\n    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();\n    // Is this test defined using TEST?\n    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();\n\n    if (first_is_TEST || this_is_TEST) {\n      // Both TEST and TEST_F appear in same test suite, which is incorrect.\n      // Tell the user how to fix this.\n\n      // Gets the name of the TEST and the name of the TEST_F.  Note\n      // that first_is_TEST and this_is_TEST cannot both be true, as\n      // the fixture IDs are different for the two tests.\n      const char* const TEST_name =\n          first_is_TEST ? first_test_name : this_test_name;\n      const char* const TEST_F_name =\n          first_is_TEST ? this_test_name : first_test_name;\n\n      ADD_FAILURE()\n          << \"All tests in the same test suite must use the same test fixture\\n\"\n          << \"class, so mixing TEST_F and TEST in the same test suite is\\n\"\n          << \"illegal.  In test suite \" << this_test_info->test_suite_name()\n          << \",\\n\"\n          << \"test \" << TEST_F_name << \" is defined using TEST_F but\\n\"\n          << \"test \" << TEST_name << \" is defined using TEST.  You probably\\n\"\n          << \"want to change the TEST to TEST_F or move it to another test\\n\"\n          << \"case.\";\n    } else {\n      // Two fixture classes with the same name appear in two different\n      // namespaces, which is not allowed. Tell the user how to fix this.\n      ADD_FAILURE()\n          << \"All tests in the same test suite must use the same test fixture\\n\"\n          << \"class.  However, in test suite \"\n          << this_test_info->test_suite_name() << \",\\n\"\n          << \"you defined test \" << first_test_name << \" and test \"\n          << this_test_name << \"\\n\"\n          << \"using two different test fixture classes.  This can happen if\\n\"\n          << \"the two classes are from different namespaces or translation\\n\"\n          << \"units and have the same name.  You should probably rename one\\n\"\n          << \"of the classes to put the tests into different test suites.\";\n    }\n    return false;\n  }\n\n  return true;\n}\n\nnamespace internal {\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Adds an \"exception thrown\" fatal failure to the current test.\nstatic std::string FormatCxxExceptionMessage(const char* description,\n                                             const char* location) {\n  Message message;\n  if (description != nullptr) {\n    message << \"C++ exception with description \\\"\" << description << \"\\\"\";\n  } else {\n    message << \"Unknown C++ exception\";\n  }\n  message << \" thrown in \" << location << \".\";\n\n  return message.GetString();\n}\n\nstatic std::string PrintTestPartResultToString(\n    const TestPartResult& test_part_result);\n\nGoogleTestFailureException::GoogleTestFailureException(\n    const TestPartResult& failure)\n    : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// We put these helper functions in the internal namespace as IBM's xlC\n// compiler rejects the code if they were declared static.\n\n// Runs the given method and handles SEH exceptions it throws, when\n// SEH is supported; returns the 0-value for type Result in case of an\n// SEH exception.  (Microsoft compilers cannot handle SEH and C++\n// exceptions in the same function.  Therefore, we provide a separate\n// wrapper function for handling SEH exceptions.)\ntemplate <class T, typename Result>\nResult HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(),\n                                              const char* location) {\n#if GTEST_HAS_SEH\n  __try {\n    return (object->*method)();\n  } __except (internal::UnitTestOptions::GTestProcessSEH(  // NOLINT\n      GetExceptionCode(), location)) {\n    return static_cast<Result>(0);\n  }\n#else\n  (void)location;\n  return (object->*method)();\n#endif  // GTEST_HAS_SEH\n}\n\n// Runs the given method and catches and reports C++ and/or SEH-style\n// exceptions, if they are supported; returns the 0-value for type\n// Result in case of an SEH exception.\ntemplate <class T, typename Result>\nResult HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),\n                                           const char* location) {\n  // NOTE: The user code can affect the way in which Google Test handles\n  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before\n  // RUN_ALL_TESTS() starts. It is technically possible to check the flag\n  // after the exception is caught and either report or re-throw the\n  // exception based on the flag's value:\n  //\n  // try {\n  //   // Perform the test method.\n  // } catch (...) {\n  //   if (GTEST_FLAG_GET(catch_exceptions))\n  //     // Report the exception as failure.\n  //   else\n  //     throw;  // Re-throws the original exception.\n  // }\n  //\n  // However, the purpose of this flag is to allow the program to drop into\n  // the debugger when the exception is thrown. On most platforms, once the\n  // control enters the catch block, the exception origin information is\n  // lost and the debugger will stop the program at the point of the\n  // re-throw in this function -- instead of at the point of the original\n  // throw statement in the code under test.  For this reason, we perform\n  // the check early, sacrificing the ability to affect Google Test's\n  // exception handling in the method where the exception is thrown.\n  if (internal::GetUnitTestImpl()->catch_exceptions()) {\n#if GTEST_HAS_EXCEPTIONS\n    try {\n      return HandleSehExceptionsInMethodIfSupported(object, method, location);\n    } catch (const AssertionException&) {  // NOLINT\n      // This failure was reported already.\n    } catch (const internal::GoogleTestFailureException&) {  // NOLINT\n      // This exception type can only be thrown by a failed Google\n      // Test assertion with the intention of letting another testing\n      // framework catch it.  Therefore we just re-throw it.\n      throw;\n    } catch (const std::exception& e) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(e.what(), location));\n    } catch (...) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(nullptr, location));\n    }\n    return static_cast<Result>(0);\n#else\n    return HandleSehExceptionsInMethodIfSupported(object, method, location);\n#endif  // GTEST_HAS_EXCEPTIONS\n  } else {\n    return (object->*method)();\n  }\n}\n\n}  // namespace internal\n\n// Runs the test and updates the test result.\nvoid Test::Run() {\n  if (!HasSameFixtureClass()) return;\n\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, \"SetUp()\");\n  // We will run the test only if SetUp() was successful and didn't call\n  // GTEST_SKIP().\n  if (!HasFatalFailure() && !IsSkipped()) {\n    impl->os_stack_trace_getter()->UponLeavingGTest();\n    internal::HandleExceptionsInMethodIfSupported(this, &Test::TestBody,\n                                                  \"the test body\");\n  }\n\n  // However, we want to clean up as much as possible.  Hence we will\n  // always call TearDown(), even if SetUp() or the test body has\n  // failed.\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::TearDown,\n                                                \"TearDown()\");\n}\n\n// Returns true if and only if the current test has a fatal failure.\nbool Test::HasFatalFailure() {\n  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();\n}\n\n// Returns true if and only if the current test has a non-fatal failure.\nbool Test::HasNonfatalFailure() {\n  return internal::GetUnitTestImpl()\n      ->current_test_result()\n      ->HasNonfatalFailure();\n}\n\n// Returns true if and only if the current test was skipped.\nbool Test::IsSkipped() {\n  return internal::GetUnitTestImpl()->current_test_result()->Skipped();\n}\n\n// class TestInfo\n\n// Constructs a TestInfo object. It assumes ownership of the test factory\n// object.\nTestInfo::TestInfo(std::string a_test_suite_name, std::string a_name,\n                   const char* a_type_param, const char* a_value_param,\n                   internal::CodeLocation a_code_location,\n                   internal::TypeId fixture_class_id,\n                   internal::TestFactoryBase* factory)\n    : test_suite_name_(std::move(a_test_suite_name)),\n      name_(std::move(a_name)),\n      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),\n      value_param_(a_value_param ? new std::string(a_value_param) : nullptr),\n      location_(std::move(a_code_location)),\n      fixture_class_id_(fixture_class_id),\n      should_run_(false),\n      is_disabled_(false),\n      matches_filter_(false),\n      is_in_another_shard_(false),\n      factory_(factory),\n      result_() {}\n\n// Destructs a TestInfo object.\nTestInfo::~TestInfo() { delete factory_; }\n\nnamespace internal {\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_suite_name:  name of the test suite\n//   name:             name of the test\n//   type_param:       the name of the test's type parameter, or NULL if\n//                     this is not a typed or a type-parameterized test.\n//   value_param:      text representation of the test's value parameter,\n//                     or NULL if this is not a value-parameterized test.\n//   code_location:    code location where the test is defined\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test suite\n//   tear_down_tc:     pointer to the function that tears down the test suite\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nTestInfo* MakeAndRegisterTestInfo(\n    std::string test_suite_name, const char* name, const char* type_param,\n    const char* value_param, CodeLocation code_location,\n    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,\n    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {\n  TestInfo* const test_info =\n      new TestInfo(std::move(test_suite_name), name, type_param, value_param,\n                   std::move(code_location), fixture_class_id, factory);\n  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);\n  return test_info;\n}\n\nvoid ReportInvalidTestSuiteType(const char* test_suite_name,\n                                const CodeLocation& code_location) {\n  Message errors;\n  errors\n      << \"Attempted redefinition of test suite \" << test_suite_name << \".\\n\"\n      << \"All tests in the same test suite must use the same test fixture\\n\"\n      << \"class.  However, in test suite \" << test_suite_name << \", you tried\\n\"\n      << \"to define a test using a fixture class different from the one\\n\"\n      << \"used earlier. This can happen if the two fixture classes are\\n\"\n      << \"from different namespaces and have the same name. You should\\n\"\n      << \"probably rename one of the classes to put the tests into different\\n\"\n      << \"test suites.\";\n\n  GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),\n                                          code_location.line)\n                    << \" \" << errors.GetString();\n}\n\n// This method expands all parameterized tests registered with macros TEST_P\n// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.\n// This will be done just once during the program runtime.\nvoid UnitTestImpl::RegisterParameterizedTests() {\n  if (!parameterized_tests_registered_) {\n    parameterized_test_registry_.RegisterTests();\n    type_parameterized_test_registry_.CheckForInstantiations();\n    parameterized_tests_registered_ = true;\n  }\n}\n\n}  // namespace internal\n\n// Creates the test object, runs it, records its result, and then\n// deletes it.\nvoid TestInfo::Run() {\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n  if (!should_run_) {\n    if (is_disabled_ && matches_filter_) repeater->OnTestDisabled(*this);\n    return;\n  }\n\n  // Tells UnitTest where to store test result.\n  UnitTest::GetInstance()->set_current_test_info(this);\n\n  // Notifies the unit test event listeners that a test is about to start.\n  repeater->OnTestStart(*this);\n  result_.set_start_timestamp(internal::GetTimeInMillis());\n  internal::Timer timer;\n  UnitTest::GetInstance()->UponLeavingGTest();\n\n  // Creates the test object.\n  Test* const test = internal::HandleExceptionsInMethodIfSupported(\n      factory_, &internal::TestFactoryBase::CreateTest,\n      \"the test fixture's constructor\");\n\n  // Runs the test if the constructor didn't generate a fatal failure or invoke\n  // GTEST_SKIP().\n  // Note that the object will not be null\n  if (!Test::HasFatalFailure() && !Test::IsSkipped()) {\n    // This doesn't throw as all user code that can throw are wrapped into\n    // exception handling code.\n    test->Run();\n  }\n\n  if (test != nullptr) {\n    // Deletes the test object.\n    UnitTest::GetInstance()->UponLeavingGTest();\n    internal::HandleExceptionsInMethodIfSupported(\n        test, &Test::DeleteSelf_, \"the test fixture's destructor\");\n  }\n\n  result_.set_elapsed_time(timer.Elapsed());\n\n  // Notifies the unit test event listener that a test has just finished.\n  repeater->OnTestEnd(*this);\n\n  // Tells UnitTest to stop associating assertion results to this\n  // test.\n  UnitTest::GetInstance()->set_current_test_info(nullptr);\n}\n\n// Skip and records a skipped test result for this object.\nvoid TestInfo::Skip() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_info(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Notifies the unit test event listeners that a test is about to start.\n  repeater->OnTestStart(*this);\n\n  const TestPartResult test_part_result =\n      TestPartResult(TestPartResult::kSkip, this->file(), this->line(), \"\");\n  internal::GetUnitTestImpl()\n      ->GetTestPartResultReporterForCurrentThread()\n      ->ReportTestPartResult(test_part_result);\n\n  // Notifies the unit test event listener that a test has just finished.\n  repeater->OnTestEnd(*this);\n  UnitTest::GetInstance()->set_current_test_info(nullptr);\n}\n\n// class TestSuite\n\n// Gets the number of successful tests in this test suite.\nint TestSuite::successful_test_count() const {\n  return CountIf(test_info_list_, TestPassed);\n}\n\n// Gets the number of successful tests in this test suite.\nint TestSuite::skipped_test_count() const {\n  return CountIf(test_info_list_, TestSkipped);\n}\n\n// Gets the number of failed tests in this test suite.\nint TestSuite::failed_test_count() const {\n  return CountIf(test_info_list_, TestFailed);\n}\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint TestSuite::reportable_disabled_test_count() const {\n  return CountIf(test_info_list_, TestReportableDisabled);\n}\n\n// Gets the number of disabled tests in this test suite.\nint TestSuite::disabled_test_count() const {\n  return CountIf(test_info_list_, TestDisabled);\n}\n\n// Gets the number of tests to be printed in the XML report.\nint TestSuite::reportable_test_count() const {\n  return CountIf(test_info_list_, TestReportable);\n}\n\n// Get the number of tests in this test suite that should run.\nint TestSuite::test_to_run_count() const {\n  return CountIf(test_info_list_, ShouldRunTest);\n}\n\n// Gets the number of all tests.\nint TestSuite::total_test_count() const {\n  return static_cast<int>(test_info_list_.size());\n}\n\n// Creates a TestSuite with the given name.\n//\n// Arguments:\n//\n//   a_name:       name of the test suite\n//   a_type_param: the name of the test suite's type parameter, or NULL if\n//                 this is not a typed or a type-parameterized test suite.\n//   set_up_tc:    pointer to the function that sets up the test suite\n//   tear_down_tc: pointer to the function that tears down the test suite\nTestSuite::TestSuite(const std::string& a_name, const char* a_type_param,\n                     internal::SetUpTestSuiteFunc set_up_tc,\n                     internal::TearDownTestSuiteFunc tear_down_tc)\n    : name_(a_name),\n      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),\n      set_up_tc_(set_up_tc),\n      tear_down_tc_(tear_down_tc),\n      should_run_(false),\n      start_timestamp_(0),\n      elapsed_time_(0) {}\n\n// Destructor of TestSuite.\nTestSuite::~TestSuite() {\n  // Deletes every Test in the collection.\n  ForEach(test_info_list_, internal::Delete<TestInfo>);\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nconst TestInfo* TestSuite::GetTestInfo(int i) const {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nTestInfo* TestSuite::GetMutableTestInfo(int i) {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];\n}\n\n// Adds a test to this test suite.  Will delete the test upon\n// destruction of the TestSuite object.\nvoid TestSuite::AddTestInfo(TestInfo* test_info) {\n  test_info_list_.push_back(test_info);\n  test_indices_.push_back(static_cast<int>(test_indices_.size()));\n}\n\n// Runs every test in this TestSuite.\nvoid TestSuite::Run() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_suite(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Ensure our tests are in a deterministic order.\n  //\n  // We do this by sorting lexicographically on (file, line number), providing\n  // an order matching what the user can see in the source code.\n  //\n  // In the common case the line number comparison shouldn't be necessary,\n  // because the registrations made by the TEST macro are executed in order\n  // within a translation unit. But this is not true of the manual registration\n  // API, and in more exotic scenarios a single file may be part of multiple\n  // translation units.\n  std::stable_sort(test_info_list_.begin(), test_info_list_.end(),\n                   [](const TestInfo* const a, const TestInfo* const b) {\n                     if (const int result = std::strcmp(a->file(), b->file())) {\n                       return result < 0;\n                     }\n\n                     return a->line() < b->line();\n                   });\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteStart(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseStart(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestSuite::RunSetUpTestSuite, \"SetUpTestSuite()\");\n\n  const bool skip_all =\n      ad_hoc_test_result().Failed() || ad_hoc_test_result().Skipped();\n\n  start_timestamp_ = internal::GetTimeInMillis();\n  internal::Timer timer;\n  for (int i = 0; i < total_test_count(); i++) {\n    if (skip_all) {\n      GetMutableTestInfo(i)->Skip();\n    } else {\n      GetMutableTestInfo(i)->Run();\n    }\n    if (GTEST_FLAG_GET(fail_fast) &&\n        GetMutableTestInfo(i)->result()->Failed()) {\n      for (int j = i + 1; j < total_test_count(); j++) {\n        GetMutableTestInfo(j)->Skip();\n      }\n      break;\n    }\n  }\n  elapsed_time_ = timer.Elapsed();\n\n  UnitTest::GetInstance()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestSuite::RunTearDownTestSuite, \"TearDownTestSuite()\");\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteEnd(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseEnd(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->set_current_test_suite(nullptr);\n}\n\n// Skips all tests under this TestSuite.\nvoid TestSuite::Skip() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_suite(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteStart(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseStart(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  for (int i = 0; i < total_test_count(); i++) {\n    GetMutableTestInfo(i)->Skip();\n  }\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteEnd(*this);\n  // Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseEnd(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->set_current_test_suite(nullptr);\n}\n\n// Clears the results of all tests in this test suite.\nvoid TestSuite::ClearResult() {\n  ad_hoc_test_result_.Clear();\n  ForEach(test_info_list_, TestInfo::ClearTestResult);\n}\n\n// Shuffles the tests in this test suite.\nvoid TestSuite::ShuffleTests(internal::Random* random) {\n  Shuffle(random, &test_indices_);\n}\n\n// Restores the test order to before the first shuffle.\nvoid TestSuite::UnshuffleTests() {\n  for (size_t i = 0; i < test_indices_.size(); i++) {\n    test_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Formats a countable noun.  Depending on its quantity, either the\n// singular form or the plural form is used. e.g.\n//\n// FormatCountableNoun(1, \"formula\", \"formuli\") returns \"1 formula\".\n// FormatCountableNoun(5, \"book\", \"books\") returns \"5 books\".\nstatic std::string FormatCountableNoun(int count, const char* singular_form,\n                                       const char* plural_form) {\n  return internal::StreamableToString(count) + \" \" +\n         (count == 1 ? singular_form : plural_form);\n}\n\n// Formats the count of tests.\nstatic std::string FormatTestCount(int test_count) {\n  return FormatCountableNoun(test_count, \"test\", \"tests\");\n}\n\n// Formats the count of test suites.\nstatic std::string FormatTestSuiteCount(int test_suite_count) {\n  return FormatCountableNoun(test_suite_count, \"test suite\", \"test suites\");\n}\n\n// Converts a TestPartResult::Type enum to human-friendly string\n// representation.  Both kNonFatalFailure and kFatalFailure are translated\n// to \"Failure\", as the user usually doesn't care about the difference\n// between the two when viewing the test result.\nstatic const char* TestPartResultTypeToString(TestPartResult::Type type) {\n  switch (type) {\n    case TestPartResult::kSkip:\n      return \"Skipped\\n\";\n    case TestPartResult::kSuccess:\n      return \"Success\";\n\n    case TestPartResult::kNonFatalFailure:\n    case TestPartResult::kFatalFailure:\n#ifdef _MSC_VER\n      return \"error: \";\n#else\n      return \"Failure\\n\";\n#endif\n    default:\n      return \"Unknown result type\";\n  }\n}\n\nnamespace internal {\nnamespace {\nenum class GTestColor { kDefault, kRed, kGreen, kYellow };\n}  // namespace\n\n// Prints a TestPartResult to an std::string.\nstatic std::string PrintTestPartResultToString(\n    const TestPartResult& test_part_result) {\n  return (Message() << internal::FormatFileLocation(\n                           test_part_result.file_name(),\n                           test_part_result.line_number())\n                    << \" \"\n                    << TestPartResultTypeToString(test_part_result.type())\n                    << test_part_result.message())\n      .GetString();\n}\n\n// Prints a TestPartResult.\nstatic void PrintTestPartResult(const TestPartResult& test_part_result) {\n  const std::string& result = PrintTestPartResultToString(test_part_result);\n  printf(\"%s\\n\", result.c_str());\n  fflush(stdout);\n  // If the test program runs in Visual Studio or a debugger, the\n  // following statements add the test part result message to the Output\n  // window such that the user can double-click on it to jump to the\n  // corresponding source code location; otherwise they do nothing.\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE)\n  // We don't call OutputDebugString*() on Windows Mobile, as printing\n  // to stdout is done by OutputDebugString() there already - we don't\n  // want the same message printed twice.\n  ::OutputDebugStringA(result.c_str());\n  ::OutputDebugStringA(\"\\n\");\n#endif\n}\n\n// class PrettyUnitTestResultPrinter\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) &&       \\\n    !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)\n\n// Returns the character attribute for the given color.\nstatic WORD GetColorAttribute(GTestColor color) {\n  switch (color) {\n    case GTestColor::kRed:\n      return FOREGROUND_RED;\n    case GTestColor::kGreen:\n      return FOREGROUND_GREEN;\n    case GTestColor::kYellow:\n      return FOREGROUND_RED | FOREGROUND_GREEN;\n    default:\n      return 0;\n  }\n}\n\nstatic int GetBitOffset(WORD color_mask) {\n  if (color_mask == 0) return 0;\n\n  int bitOffset = 0;\n  while ((color_mask & 1) == 0) {\n    color_mask >>= 1;\n    ++bitOffset;\n  }\n  return bitOffset;\n}\n\nstatic WORD GetNewColor(GTestColor color, WORD old_color_attrs) {\n  // Let's reuse the BG\n  static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |\n                                      BACKGROUND_RED | BACKGROUND_INTENSITY;\n  static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |\n                                      FOREGROUND_RED | FOREGROUND_INTENSITY;\n  const WORD existing_bg = old_color_attrs & background_mask;\n\n  WORD new_color =\n      GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;\n  static const int bg_bitOffset = GetBitOffset(background_mask);\n  static const int fg_bitOffset = GetBitOffset(foreground_mask);\n\n  if (((new_color & background_mask) >> bg_bitOffset) ==\n      ((new_color & foreground_mask) >> fg_bitOffset)) {\n    new_color ^= FOREGROUND_INTENSITY;  // invert intensity\n  }\n  return new_color;\n}\n\n#else\n\n// Returns the ANSI color code for the given color. GTestColor::kDefault is\n// an invalid input.\nstatic const char* GetAnsiColorCode(GTestColor color) {\n  switch (color) {\n    case GTestColor::kRed:\n      return \"1\";\n    case GTestColor::kGreen:\n      return \"2\";\n    case GTestColor::kYellow:\n      return \"3\";\n    default:\n      assert(false);\n      return \"9\";\n  }\n}\n\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n\n// Returns true if and only if Google Test should use colors in the output.\nbool ShouldUseColor(bool stdout_is_tty) {\n  std::string c = GTEST_FLAG_GET(color);\n  const char* const gtest_color = c.c_str();\n\n  if (String::CaseInsensitiveCStringEquals(gtest_color, \"auto\")) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW)\n    // On Windows the TERM variable is usually not set, but the\n    // console there does support colors.\n    return stdout_is_tty;\n#else\n    // On non-Windows platforms, we rely on the TERM variable.\n    const char* const term = posix::GetEnv(\"TERM\");\n    const bool term_supports_color =\n        term != nullptr && (String::CStringEquals(term, \"xterm\") ||\n                            String::CStringEquals(term, \"xterm-color\") ||\n                            String::CStringEquals(term, \"xterm-kitty\") ||\n                            String::CStringEquals(term, \"alacritty\") ||\n                            String::CStringEquals(term, \"screen\") ||\n                            String::CStringEquals(term, \"tmux\") ||\n                            String::CStringEquals(term, \"rxvt-unicode\") ||\n                            String::CStringEquals(term, \"linux\") ||\n                            String::CStringEquals(term, \"cygwin\") ||\n                            String::EndsWithCaseInsensitive(term, \"-256color\"));\n    return stdout_is_tty && term_supports_color;\n#endif  // GTEST_OS_WINDOWS\n  }\n\n  return String::CaseInsensitiveCStringEquals(gtest_color, \"yes\") ||\n         String::CaseInsensitiveCStringEquals(gtest_color, \"true\") ||\n         String::CaseInsensitiveCStringEquals(gtest_color, \"t\") ||\n         String::CStringEquals(gtest_color, \"1\");\n  // We take \"yes\", \"true\", \"t\", and \"1\" as meaning \"yes\".  If the\n  // value is neither one of these nor \"auto\", we treat it as \"no\" to\n  // be conservative.\n}\n\n// Helpers for printing colored strings to stdout. Note that on Windows, we\n// cannot simply emit special characters and have the terminal change colors.\n// This routine must actually emit the characters rather than return a string\n// that would be colored when printed, as can be done on Linux.\n\nGTEST_ATTRIBUTE_PRINTF_(2, 3)\nstatic void ColoredPrintf(GTestColor color, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n\n  static const bool in_color_mode =\n      // We don't condition this on GTEST_HAS_FILE_SYSTEM because we still need\n      // to be able to detect terminal I/O regardless.\n      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);\n\n  const bool use_color = in_color_mode && (color != GTestColor::kDefault);\n\n  if (!use_color) {\n    vprintf(fmt, args);\n    va_end(args);\n    return;\n  }\n\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) &&       \\\n    !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\n\n  // Gets the current text color.\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\n  const WORD old_color_attrs = buffer_info.wAttributes;\n  const WORD new_color = GetNewColor(color, old_color_attrs);\n\n  // We need to flush the stream buffers into the console before each\n  // SetConsoleTextAttribute call lest it affect the text that is already\n  // printed but has not yet reached the console.\n  fflush(stdout);\n  SetConsoleTextAttribute(stdout_handle, new_color);\n\n  vprintf(fmt, args);\n\n  fflush(stdout);\n  // Restores the text color.\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\n#else\n  printf(\"\\033[0;3%sm\", GetAnsiColorCode(color));\n  vprintf(fmt, args);\n  printf(\"\\033[m\");  // Resets the terminal to default.\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n  va_end(args);\n}\n\n// Text printed in Google Test's text output and --gtest_list_tests\n// output to label the type parameter and value parameter for a test.\nstatic const char kTypeParamLabel[] = \"TypeParam\";\nstatic const char kValueParamLabel[] = \"GetParam()\";\n\nstatic void PrintFullTestCommentIfPresent(const TestInfo& test_info) {\n  const char* const type_param = test_info.type_param();\n  const char* const value_param = test_info.value_param();\n\n  if (type_param != nullptr || value_param != nullptr) {\n    printf(\", where \");\n    if (type_param != nullptr) {\n      printf(\"%s = %s\", kTypeParamLabel, type_param);\n      if (value_param != nullptr) printf(\" and \");\n    }\n    if (value_param != nullptr) {\n      printf(\"%s = %s\", kValueParamLabel, value_param);\n    }\n  }\n}\n\n// This class implements the TestEventListener interface.\n//\n// Class PrettyUnitTestResultPrinter is copyable.\nclass PrettyUnitTestResultPrinter : public TestEventListener {\n public:\n  PrettyUnitTestResultPrinter() = default;\n  static void PrintTestName(const char* test_suite, const char* test) {\n    printf(\"%s.%s\", test_suite, test);\n  }\n\n  // The following methods override what's in the TestEventListener class.\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;\n  void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& test_case) override;\n#else\n  void OnTestSuiteStart(const TestSuite& test_suite) override;\n#endif  // OnTestCaseStart\n\n  void OnTestStart(const TestInfo& test_info) override;\n  void OnTestDisabled(const TestInfo& test_info) override;\n\n  void OnTestPartResult(const TestPartResult& result) override;\n  void OnTestEnd(const TestInfo& test_info) override;\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& test_case) override;\n#else\n  void OnTestSuiteEnd(const TestSuite& test_suite) override;\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n\n private:\n  static void PrintFailedTests(const UnitTest& unit_test);\n  static void PrintFailedTestSuites(const UnitTest& unit_test);\n  static void PrintSkippedTests(const UnitTest& unit_test);\n};\n\n// Fired before each iteration of tests starts.\nvoid PrettyUnitTestResultPrinter::OnTestIterationStart(\n    const UnitTest& unit_test, int iteration) {\n  if (GTEST_FLAG_GET(repeat) != 1)\n    printf(\"\\nRepeating all tests (iteration %d) . . .\\n\\n\", iteration + 1);\n\n  std::string f = GTEST_FLAG_GET(filter);\n  const char* const filter = f.c_str();\n\n  // Prints the filter if it's not *.  This reminds the user that some\n  // tests may be skipped.\n  if (!String::CStringEquals(filter, kUniversalFilter)) {\n    ColoredPrintf(GTestColor::kYellow, \"Note: %s filter = %s\\n\", GTEST_NAME_,\n                  filter);\n  }\n\n  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {\n    const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);\n    ColoredPrintf(GTestColor::kYellow, \"Note: This is test shard %d of %s.\\n\",\n                  static_cast<int>(shard_index) + 1,\n                  internal::posix::GetEnv(kTestTotalShards));\n  }\n\n  if (GTEST_FLAG_GET(shuffle)) {\n    ColoredPrintf(GTestColor::kYellow,\n                  \"Note: Randomizing tests' orders with a seed of %d .\\n\",\n                  unit_test.random_seed());\n  }\n\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"Running %s from %s.\\n\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"Global test environment set-up.\\n\");\n  fflush(stdout);\n}\n\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nvoid PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {\n  const std::string counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s\", counts.c_str(), test_case.name());\n  if (test_case.type_param() == nullptr) {\n    printf(\"\\n\");\n  } else {\n    printf(\", where %s = %s\\n\", kTypeParamLabel, test_case.type_param());\n  }\n  fflush(stdout);\n}\n#else\nvoid PrettyUnitTestResultPrinter::OnTestSuiteStart(\n    const TestSuite& test_suite) {\n  const std::string counts =\n      FormatCountableNoun(test_suite.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s\", counts.c_str(), test_suite.name());\n  if (test_suite.type_param() == nullptr) {\n    printf(\"\\n\");\n  } else {\n    printf(\", where %s = %s\\n\", kTypeParamLabel, test_suite.type_param());\n  }\n  fflush(stdout);\n}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nvoid PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {\n  ColoredPrintf(GTestColor::kGreen, \"[ RUN      ] \");\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  printf(\"\\n\");\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) {\n  ColoredPrintf(GTestColor::kYellow, \"[ DISABLED ] \");\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  printf(\"\\n\");\n  fflush(stdout);\n}\n\n// Called after an assertion failure.\nvoid PrettyUnitTestResultPrinter::OnTestPartResult(\n    const TestPartResult& result) {\n  switch (result.type()) {\n    // If the test part succeeded, we don't need to do anything.\n    case TestPartResult::kSuccess:\n      return;\n    default:\n      // Print failure message from the assertion\n      // (e.g. expected this and got that).\n      PrintTestPartResult(result);\n      fflush(stdout);\n  }\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\n  if (test_info.result()->Passed()) {\n    ColoredPrintf(GTestColor::kGreen, \"[       OK ] \");\n  } else if (test_info.result()->Skipped()) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n  } else {\n    ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n  }\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info);\n\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms)\\n\",\n           internal::StreamableToString(test_info.result()->elapsed_time())\n               .c_str());\n  } else {\n    printf(\"\\n\");\n  }\n  fflush(stdout);\n}\n\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nvoid PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {\n  if (!GTEST_FLAG_GET(print_time)) return;\n\n  const std::string counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s (%s ms total)\\n\\n\", counts.c_str(), test_case.name(),\n         internal::StreamableToString(test_case.elapsed_time()).c_str());\n  fflush(stdout);\n}\n#else\nvoid PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {\n  if (!GTEST_FLAG_GET(print_time)) return;\n\n  const std::string counts =\n      FormatCountableNoun(test_suite.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s (%s ms total)\\n\\n\", counts.c_str(), test_suite.name(),\n         internal::StreamableToString(test_suite.elapsed_time()).c_str());\n  fflush(stdout);\n}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"Global test environment tear-down\\n\");\n  fflush(stdout);\n}\n\n// Internal helper for printing the list of failed tests.\nvoid PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {\n  const int failed_test_count = unit_test.failed_test_count();\n  ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n  printf(\"%s, listed below:\\n\", FormatTestCount(failed_test_count).c_str());\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) {\n      continue;\n    }\n    for (int j = 0; j < test_suite.total_test_count(); ++j) {\n      const TestInfo& test_info = *test_suite.GetTestInfo(j);\n      if (!test_info.should_run() || !test_info.result()->Failed()) {\n        continue;\n      }\n      ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n      printf(\"%s.%s\", test_suite.name(), test_info.name());\n      PrintFullTestCommentIfPresent(test_info);\n      printf(\"\\n\");\n    }\n  }\n  printf(\"\\n%2d FAILED %s\\n\", failed_test_count,\n         failed_test_count == 1 ? \"TEST\" : \"TESTS\");\n}\n\n// Internal helper for printing the list of test suite failures not covered by\n// PrintFailedTests.\nvoid PrettyUnitTestResultPrinter::PrintFailedTestSuites(\n    const UnitTest& unit_test) {\n  int suite_failure_count = 0;\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run()) {\n      continue;\n    }\n    if (test_suite.ad_hoc_test_result().Failed()) {\n      ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n      printf(\"%s: SetUpTestSuite or TearDownTestSuite\\n\", test_suite.name());\n      ++suite_failure_count;\n    }\n  }\n  if (suite_failure_count > 0) {\n    printf(\"\\n%2d FAILED TEST %s\\n\", suite_failure_count,\n           suite_failure_count == 1 ? \"SUITE\" : \"SUITES\");\n  }\n}\n\n// Internal helper for printing the list of skipped tests.\nvoid PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count == 0) {\n    return;\n  }\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) {\n      continue;\n    }\n    for (int j = 0; j < test_suite.total_test_count(); ++j) {\n      const TestInfo& test_info = *test_suite.GetTestInfo(j);\n      if (!test_info.should_run() || !test_info.result()->Skipped()) {\n        continue;\n      }\n      ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n      printf(\"%s.%s\", test_suite.name(), test_info.name());\n      printf(\"\\n\");\n    }\n  }\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                     int /*iteration*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"%s from %s ran.\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms total)\",\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\n  }\n  printf(\"\\n\");\n  ColoredPrintf(GTestColor::kGreen, \"[  PASSED  ] \");\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\n\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count > 0) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n    printf(\"%s, listed below:\\n\", FormatTestCount(skipped_test_count).c_str());\n    PrintSkippedTests(unit_test);\n  }\n\n  if (!unit_test.Passed()) {\n    PrintFailedTests(unit_test);\n    PrintFailedTestSuites(unit_test);\n  }\n\n  int num_disabled = unit_test.reportable_disabled_test_count();\n  if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {\n    if (unit_test.Passed()) {\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\n    }\n    ColoredPrintf(GTestColor::kYellow, \"  YOU HAVE %d DISABLED %s\\n\\n\",\n                  num_disabled, num_disabled == 1 ? \"TEST\" : \"TESTS\");\n  }\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\n  fflush(stdout);\n}\n\n// End PrettyUnitTestResultPrinter\n\n// This class implements the TestEventListener interface.\n//\n// Class BriefUnitTestResultPrinter is copyable.\nclass BriefUnitTestResultPrinter : public TestEventListener {\n public:\n  BriefUnitTestResultPrinter() = default;\n  static void PrintTestName(const char* test_suite, const char* test) {\n    printf(\"%s.%s\", test_suite, test);\n  }\n\n  // The following methods override what's in the TestEventListener class.\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& /*unit_test*/,\n                            int /*iteration*/) override {}\n  void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& /*test_case*/) override {}\n#else\n  void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}\n#endif  // OnTestCaseStart\n\n  void OnTestStart(const TestInfo& /*test_info*/) override {}\n  void OnTestDisabled(const TestInfo& /*test_info*/) override {}\n\n  void OnTestPartResult(const TestPartResult& result) override;\n  void OnTestEnd(const TestInfo& test_info) override;\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& /*test_case*/) override {}\n#else\n  void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n};\n\n// Called after an assertion failure.\nvoid BriefUnitTestResultPrinter::OnTestPartResult(\n    const TestPartResult& result) {\n  switch (result.type()) {\n    // If the test part succeeded, we don't need to do anything.\n    case TestPartResult::kSuccess:\n      return;\n    default:\n      // Print failure message from the assertion\n      // (e.g. expected this and got that).\n      PrintTestPartResult(result);\n      fflush(stdout);\n  }\n}\n\nvoid BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\n  if (test_info.result()->Failed()) {\n    ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n    PrintTestName(test_info.test_suite_name(), test_info.name());\n    PrintFullTestCommentIfPresent(test_info);\n\n    if (GTEST_FLAG_GET(print_time)) {\n      printf(\" (%s ms)\\n\",\n             internal::StreamableToString(test_info.result()->elapsed_time())\n                 .c_str());\n    } else {\n      printf(\"\\n\");\n    }\n    fflush(stdout);\n  }\n}\n\nvoid BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                    int /*iteration*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"%s from %s ran.\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms total)\",\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\n  }\n  printf(\"\\n\");\n  ColoredPrintf(GTestColor::kGreen, \"[  PASSED  ] \");\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\n\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count > 0) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n    printf(\"%s.\\n\", FormatTestCount(skipped_test_count).c_str());\n  }\n\n  int num_disabled = unit_test.reportable_disabled_test_count();\n  if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {\n    if (unit_test.Passed()) {\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\n    }\n    ColoredPrintf(GTestColor::kYellow, \"  YOU HAVE %d DISABLED %s\\n\\n\",\n                  num_disabled, num_disabled == 1 ? \"TEST\" : \"TESTS\");\n  }\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\n  fflush(stdout);\n}\n\n// End BriefUnitTestResultPrinter\n\n// class TestEventRepeater\n//\n// This class forwards events to other event listeners.\nclass TestEventRepeater : public TestEventListener {\n public:\n  TestEventRepeater() : forwarding_enabled_(true) {}\n  ~TestEventRepeater() override;\n  void Append(TestEventListener* listener);\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled() const { return forwarding_enabled_; }\n  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }\n\n  void OnTestProgramStart(const UnitTest& parameter) override;\n  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;\n  void OnEnvironmentsSetUpStart(const UnitTest& parameter) override;\n  void OnEnvironmentsSetUpEnd(const UnitTest& parameter) override;\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestSuite& parameter) override;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestSuiteStart(const TestSuite& parameter) override;\n  void OnTestStart(const TestInfo& parameter) override;\n  void OnTestDisabled(const TestInfo& parameter) override;\n  void OnTestPartResult(const TestPartResult& parameter) override;\n  void OnTestEnd(const TestInfo& parameter) override;\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& parameter) override;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestSuiteEnd(const TestSuite& parameter) override;\n  void OnEnvironmentsTearDownStart(const UnitTest& parameter) override;\n  void OnEnvironmentsTearDownEnd(const UnitTest& parameter) override;\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& parameter) override;\n\n private:\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled_;\n  // The list of listeners that receive events.\n  std::vector<TestEventListener*> listeners_;\n\n  TestEventRepeater(const TestEventRepeater&) = delete;\n  TestEventRepeater& operator=(const TestEventRepeater&) = delete;\n};\n\nTestEventRepeater::~TestEventRepeater() {\n  ForEach(listeners_, Delete<TestEventListener>);\n}\n\nvoid TestEventRepeater::Append(TestEventListener* listener) {\n  listeners_.push_back(listener);\n}\n\nTestEventListener* TestEventRepeater::Release(TestEventListener* listener) {\n  for (size_t i = 0; i < listeners_.size(); ++i) {\n    if (listeners_[i] == listener) {\n      listeners_.erase(listeners_.begin() + static_cast<int>(i));\n      return listener;\n    }\n  }\n\n  return nullptr;\n}\n\n// Since most methods are very similar, use macros to reduce boilerplate.\n// This defines a member that forwards the call to all listeners.\n#define GTEST_REPEATER_METHOD_(Name, Type)              \\\n  void TestEventRepeater::Name(const Type& parameter) { \\\n    if (forwarding_enabled_) {                          \\\n      for (size_t i = 0; i < listeners_.size(); i++) {  \\\n        listeners_[i]->Name(parameter);                 \\\n      }                                                 \\\n    }                                                   \\\n  }\n// This defines a member that forwards the call to all listeners in reverse\n// order.\n#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type)      \\\n  void TestEventRepeater::Name(const Type& parameter) { \\\n    if (forwarding_enabled_) {                          \\\n      for (size_t i = listeners_.size(); i != 0; i--) { \\\n        listeners_[i - 1]->Name(parameter);             \\\n      }                                                 \\\n    }                                                   \\\n  }\n\nGTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)\nGTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)\nGTEST_REPEATER_METHOD_(OnTestStart, TestInfo)\nGTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo)\nGTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)\nGTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite)\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)\n\n#undef GTEST_REPEATER_METHOD_\n#undef GTEST_REVERSE_REPEATER_METHOD_\n\nvoid TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,\n                                             int iteration) {\n  if (forwarding_enabled_) {\n    for (size_t i = 0; i < listeners_.size(); i++) {\n      listeners_[i]->OnTestIterationStart(unit_test, iteration);\n    }\n  }\n}\n\nvoid TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,\n                                           int iteration) {\n  if (forwarding_enabled_) {\n    for (size_t i = listeners_.size(); i > 0; i--) {\n      listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration);\n    }\n  }\n}\n\n// End TestEventRepeater\n\n#if GTEST_HAS_FILE_SYSTEM\n// This class generates an XML output file.\nclass XmlUnitTestResultPrinter : public EmptyTestEventListener {\n public:\n  explicit XmlUnitTestResultPrinter(const char* output_file);\n\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites);\n\n  // Prints an XML summary of all unit tests.\n  static void PrintXmlTestsList(std::ostream* stream,\n                                const std::vector<TestSuite*>& test_suites);\n\n private:\n  // Is c a whitespace character that is normalized to a space character\n  // when it appears in an XML attribute value?\n  static bool IsNormalizableWhitespace(unsigned char c) {\n    return c == '\\t' || c == '\\n' || c == '\\r';\n  }\n\n  // May c appear in a well-formed XML document?\n  // https://www.w3.org/TR/REC-xml/#charsets\n  static bool IsValidXmlCharacter(unsigned char c) {\n    return IsNormalizableWhitespace(c) || c >= 0x20;\n  }\n\n  // Returns an XML-escaped copy of the input string str.  If\n  // is_attribute is true, the text is meant to appear as an attribute\n  // value, and normalizable whitespace is preserved by replacing it\n  // with character references.\n  static std::string EscapeXml(const std::string& str, bool is_attribute);\n\n  // Returns the given string with all characters invalid in XML removed.\n  static std::string RemoveInvalidXmlCharacters(const std::string& str);\n\n  // Convenience wrapper around EscapeXml when str is an attribute value.\n  static std::string EscapeXmlAttribute(const std::string& str) {\n    return EscapeXml(str, true);\n  }\n\n  // Convenience wrapper around EscapeXml when str is not an attribute value.\n  static std::string EscapeXmlText(const char* str) {\n    return EscapeXml(str, false);\n  }\n\n  // Verifies that the given attribute belongs to the given element and\n  // streams the attribute as XML.\n  static void OutputXmlAttribute(std::ostream* stream,\n                                 const std::string& element_name,\n                                 const std::string& name,\n                                 const std::string& value);\n\n  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\n  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);\n\n  // Streams a test suite XML stanza containing the given test result.\n  //\n  // Requires: result.Failed()\n  static void OutputXmlTestSuiteForTestResult(::std::ostream* stream,\n                                              const TestResult& result);\n\n  // Streams an XML representation of a TestResult object.\n  static void OutputXmlTestResult(::std::ostream* stream,\n                                  const TestResult& result);\n\n  // Streams an XML representation of a TestInfo object.\n  static void OutputXmlTestInfo(::std::ostream* stream,\n                                const char* test_suite_name,\n                                const TestInfo& test_info);\n\n  // Prints an XML representation of a TestSuite object\n  static void PrintXmlTestSuite(::std::ostream* stream,\n                                const TestSuite& test_suite);\n\n  // Prints an XML summary of unit_test to output stream out.\n  static void PrintXmlUnitTest(::std::ostream* stream,\n                               const UnitTest& unit_test);\n\n  // Produces a string representing the test properties in a result as space\n  // delimited XML attributes based on the property key=\"value\" pairs.\n  // When the std::string is not empty, it includes a space at the beginning,\n  // to delimit this attribute from prior attributes.\n  static std::string TestPropertiesAsXmlAttributes(const TestResult& result);\n\n  // Streams an XML representation of the test properties of a TestResult\n  // object.\n  static void OutputXmlTestProperties(std::ostream* stream,\n                                      const TestResult& result);\n\n  // The output file.\n  const std::string output_file_;\n\n  XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;\n  XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter&) = delete;\n};\n\n// Creates a new XmlUnitTestResultPrinter.\nXmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)\n    : output_file_(output_file) {\n  if (output_file_.empty()) {\n    GTEST_LOG_(FATAL) << \"XML output file may not be null\";\n  }\n}\n\n// Called after the unit test ends.\nvoid XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                  int /*iteration*/) {\n  FILE* xmlout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintXmlUnitTest(&stream, unit_test);\n  fprintf(xmlout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(xmlout);\n}\n\nvoid XmlUnitTestResultPrinter::ListTestsMatchingFilter(\n    const std::vector<TestSuite*>& test_suites) {\n  FILE* xmlout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintXmlTestsList(&stream, test_suites);\n  fprintf(xmlout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(xmlout);\n}\n\n// Returns an XML-escaped copy of the input string str.  If is_attribute\n// is true, the text is meant to appear as an attribute value, and\n// normalizable whitespace is preserved by replacing it with character\n// references.\n//\n// Invalid XML characters in str, if any, are stripped from the output.\n// It is expected that most, if not all, of the text processed by this\n// module will consist of ordinary English text.\n// If this module is ever modified to produce version 1.1 XML output,\n// most invalid characters can be retained using character references.\nstd::string XmlUnitTestResultPrinter::EscapeXml(const std::string& str,\n                                                bool is_attribute) {\n  Message m;\n\n  for (size_t i = 0; i < str.size(); ++i) {\n    const char ch = str[i];\n    switch (ch) {\n      case '<':\n        m << \"&lt;\";\n        break;\n      case '>':\n        m << \"&gt;\";\n        break;\n      case '&':\n        m << \"&amp;\";\n        break;\n      case '\\'':\n        if (is_attribute)\n          m << \"&apos;\";\n        else\n          m << '\\'';\n        break;\n      case '\"':\n        if (is_attribute)\n          m << \"&quot;\";\n        else\n          m << '\"';\n        break;\n      default:\n        if (IsValidXmlCharacter(static_cast<unsigned char>(ch))) {\n          if (is_attribute &&\n              IsNormalizableWhitespace(static_cast<unsigned char>(ch)))\n            m << \"&#x\" << String::FormatByte(static_cast<unsigned char>(ch))\n              << \";\";\n          else\n            m << ch;\n        }\n        break;\n    }\n  }\n\n  return m.GetString();\n}\n\n// Returns the given string with all characters invalid in XML removed.\n// Currently invalid characters are dropped from the string. An\n// alternative is to replace them with certain characters such as . or ?.\nstd::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(\n    const std::string& str) {\n  std::string output;\n  output.reserve(str.size());\n  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)\n    if (IsValidXmlCharacter(static_cast<unsigned char>(*it)))\n      output.push_back(*it);\n\n  return output;\n}\n\n// The following routines generate an XML representation of a UnitTest\n// object.\n//\n// This is how Google Test concepts map to the DTD:\n//\n// <testsuites name=\"AllTests\">        <-- corresponds to a UnitTest object\n//   <testsuite name=\"testcase-name\">  <-- corresponds to a TestSuite object\n//     <testcase name=\"test-name\">     <-- corresponds to a TestInfo object\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//                                     <-- individual assertion failures\n//     </testcase>\n//   </testsuite>\n// </testsuites>\n\n// Formats the given time in milliseconds as seconds.\nstd::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {\n  ::std::stringstream ss;\n  // For the exact N seconds, makes sure output has a trailing decimal point.\n  // Sets precision so that we won't have many trailing zeros (e.g., 300 ms\n  // will be just 0.3, 410 ms 0.41, and so on)\n  ss << std::fixed\n     << std::setprecision(\n            ms % 1000 == 0 ? 0 : (ms % 100 == 0 ? 1 : (ms % 10 == 0 ? 2 : 3)))\n     << std::showpoint;\n  ss << (static_cast<double>(ms) * 1e-3);\n  return ss.str();\n}\n\nstatic bool PortableLocaltime(time_t seconds, struct tm* out) {\n#if defined(_MSC_VER)\n  return localtime_s(out, &seconds) == 0;\n#elif defined(__MINGW32__) || defined(__MINGW64__)\n  // MINGW <time.h> provides neither localtime_r nor localtime_s, but uses\n  // Windows' localtime(), which has a thread-local tm buffer.\n  struct tm* tm_ptr = localtime(&seconds);  // NOLINT\n  if (tm_ptr == nullptr) return false;\n  *out = *tm_ptr;\n  return true;\n#elif defined(__STDC_LIB_EXT1__)\n  // Uses localtime_s when available as localtime_r is only available from\n  // C23 standard.\n  return localtime_s(&seconds, out) != nullptr;\n#else\n  return localtime_r(&seconds, out) != nullptr;\n#endif\n}\n\n// Converts the given epoch time in milliseconds to a date string in the ISO\n// 8601 format, without the timezone information.\nstd::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {\n  struct tm time_struct;\n  if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))\n    return \"\";\n  // YYYY-MM-DDThh:mm:ss.sss\n  return StreamableToString(time_struct.tm_year + 1900) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mon + 1) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mday) + \"T\" +\n         String::FormatIntWidth2(time_struct.tm_hour) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_min) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_sec) + \".\" +\n         String::FormatIntWidthN(static_cast<int>(ms % 1000), 3);\n}\n\n// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\nvoid XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,\n                                                     const char* data) {\n  const char* segment = data;\n  *stream << \"<![CDATA[\";\n  for (;;) {\n    const char* const next_segment = strstr(segment, \"]]>\");\n    if (next_segment != nullptr) {\n      stream->write(segment,\n                    static_cast<std::streamsize>(next_segment - segment));\n      *stream << \"]]>]]&gt;<![CDATA[\";\n      segment = next_segment + strlen(\"]]>\");\n    } else {\n      *stream << segment;\n      break;\n    }\n  }\n  *stream << \"]]>\";\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlAttribute(\n    std::ostream* stream, const std::string& element_name,\n    const std::string& name, const std::string& value) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Attribute \" << name << \" is not allowed for element <\" << element_name\n      << \">.\";\n\n  *stream << \" \" << name << \"=\\\"\" << EscapeXmlAttribute(value) << \"\\\"\";\n}\n\n// Streams a test suite XML stanza containing the given test result.\nvoid XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(\n    ::std::ostream* stream, const TestResult& result) {\n  // Output the boilerplate for a minimal test suite with one test.\n  *stream << \"  <testsuite\";\n  OutputXmlAttribute(stream, \"testsuite\", \"name\", \"NonTestSuiteFailure\");\n  OutputXmlAttribute(stream, \"testsuite\", \"tests\", \"1\");\n  OutputXmlAttribute(stream, \"testsuite\", \"failures\", \"1\");\n  OutputXmlAttribute(stream, \"testsuite\", \"disabled\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"skipped\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"errors\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, \"testsuite\", \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n  *stream << \">\";\n\n  // Output the boilerplate for a minimal test case with a single test.\n  *stream << \"    <testcase\";\n  OutputXmlAttribute(stream, \"testcase\", \"name\", \"\");\n  OutputXmlAttribute(stream, \"testcase\", \"status\", \"run\");\n  OutputXmlAttribute(stream, \"testcase\", \"result\", \"completed\");\n  OutputXmlAttribute(stream, \"testcase\", \"classname\", \"\");\n  OutputXmlAttribute(stream, \"testcase\", \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, \"testcase\", \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n\n  // Output the actual test result.\n  OutputXmlTestResult(stream, result);\n\n  // Complete the test suite.\n  *stream << \"  </testsuite>\\n\";\n}\n\n// Prints an XML representation of a TestInfo object.\nvoid XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,\n                                                 const char* test_suite_name,\n                                                 const TestInfo& test_info) {\n  const TestResult& result = *test_info.result();\n  const std::string kTestsuite = \"testcase\";\n\n  if (test_info.is_in_another_shard()) {\n    return;\n  }\n\n  *stream << \"    <testcase\";\n  OutputXmlAttribute(stream, kTestsuite, \"name\", test_info.name());\n\n  if (test_info.value_param() != nullptr) {\n    OutputXmlAttribute(stream, kTestsuite, \"value_param\",\n                       test_info.value_param());\n  }\n  if (test_info.type_param() != nullptr) {\n    OutputXmlAttribute(stream, kTestsuite, \"type_param\",\n                       test_info.type_param());\n  }\n\n  OutputXmlAttribute(stream, kTestsuite, \"file\", test_info.file());\n  OutputXmlAttribute(stream, kTestsuite, \"line\",\n                     StreamableToString(test_info.line()));\n  if (GTEST_FLAG_GET(list_tests)) {\n    *stream << \" />\\n\";\n    return;\n  }\n\n  OutputXmlAttribute(stream, kTestsuite, \"status\",\n                     test_info.should_run() ? \"run\" : \"notrun\");\n  OutputXmlAttribute(stream, kTestsuite, \"result\",\n                     test_info.should_run()\n                         ? (result.Skipped() ? \"skipped\" : \"completed\")\n                         : \"suppressed\");\n  OutputXmlAttribute(stream, kTestsuite, \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, kTestsuite, \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n  OutputXmlAttribute(stream, kTestsuite, \"classname\", test_suite_name);\n\n  OutputXmlTestResult(stream, result);\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,\n                                                   const TestResult& result) {\n  int failures = 0;\n  int skips = 0;\n  for (int i = 0; i < result.total_part_count(); ++i) {\n    const TestPartResult& part = result.GetTestPartResult(i);\n    if (part.failed()) {\n      if (++failures == 1 && skips == 0) {\n        *stream << \">\\n\";\n      }\n      const std::string location =\n          internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                          part.line_number());\n      const std::string summary = location + \"\\n\" + part.summary();\n      *stream << \"      <failure message=\\\"\" << EscapeXmlAttribute(summary)\n              << \"\\\" type=\\\"\\\">\";\n      const std::string detail = location + \"\\n\" + part.message();\n      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());\n      *stream << \"</failure>\\n\";\n    } else if (part.skipped()) {\n      if (++skips == 1 && failures == 0) {\n        *stream << \">\\n\";\n      }\n      const std::string location =\n          internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                          part.line_number());\n      const std::string summary = location + \"\\n\" + part.summary();\n      *stream << \"      <skipped message=\\\"\"\n              << EscapeXmlAttribute(summary.c_str()) << \"\\\">\";\n      const std::string detail = location + \"\\n\" + part.message();\n      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());\n      *stream << \"</skipped>\\n\";\n    }\n  }\n\n  if (failures == 0 && skips == 0 && result.test_property_count() == 0) {\n    *stream << \" />\\n\";\n  } else {\n    if (failures == 0 && skips == 0) {\n      *stream << \">\\n\";\n    }\n    OutputXmlTestProperties(stream, result);\n    *stream << \"    </testcase>\\n\";\n  }\n}\n\n// Prints an XML representation of a TestSuite object\nvoid XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,\n                                                 const TestSuite& test_suite) {\n  const std::string kTestsuite = \"testsuite\";\n  *stream << \"  <\" << kTestsuite;\n  OutputXmlAttribute(stream, kTestsuite, \"name\", test_suite.name());\n  OutputXmlAttribute(stream, kTestsuite, \"tests\",\n                     StreamableToString(test_suite.reportable_test_count()));\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputXmlAttribute(stream, kTestsuite, \"failures\",\n                       StreamableToString(test_suite.failed_test_count()));\n    OutputXmlAttribute(\n        stream, kTestsuite, \"disabled\",\n        StreamableToString(test_suite.reportable_disabled_test_count()));\n    OutputXmlAttribute(stream, kTestsuite, \"skipped\",\n                       StreamableToString(test_suite.skipped_test_count()));\n\n    OutputXmlAttribute(stream, kTestsuite, \"errors\", \"0\");\n\n    OutputXmlAttribute(stream, kTestsuite, \"time\",\n                       FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));\n    OutputXmlAttribute(\n        stream, kTestsuite, \"timestamp\",\n        FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));\n    *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());\n  }\n  *stream << \">\\n\";\n  for (int i = 0; i < test_suite.total_test_count(); ++i) {\n    if (test_suite.GetTestInfo(i)->is_reportable())\n      OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));\n  }\n  *stream << \"  </\" << kTestsuite << \">\\n\";\n}\n\n// Prints an XML summary of unit_test to output stream out.\nvoid XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,\n                                                const UnitTest& unit_test) {\n  const std::string kTestsuites = \"testsuites\";\n\n  *stream << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n  *stream << \"<\" << kTestsuites;\n\n  OutputXmlAttribute(stream, kTestsuites, \"tests\",\n                     StreamableToString(unit_test.reportable_test_count()));\n  OutputXmlAttribute(stream, kTestsuites, \"failures\",\n                     StreamableToString(unit_test.failed_test_count()));\n  OutputXmlAttribute(\n      stream, kTestsuites, \"disabled\",\n      StreamableToString(unit_test.reportable_disabled_test_count()));\n  OutputXmlAttribute(stream, kTestsuites, \"errors\", \"0\");\n  OutputXmlAttribute(stream, kTestsuites, \"time\",\n                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));\n  OutputXmlAttribute(\n      stream, kTestsuites, \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));\n\n  if (GTEST_FLAG_GET(shuffle)) {\n    OutputXmlAttribute(stream, kTestsuites, \"random_seed\",\n                       StreamableToString(unit_test.random_seed()));\n  }\n  *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());\n\n  OutputXmlAttribute(stream, kTestsuites, \"name\", \"AllTests\");\n  *stream << \">\\n\";\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)\n      PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));\n  }\n\n  // If there was a test failure outside of one of the test suites (like in a\n  // test environment) include that in the output.\n  if (unit_test.ad_hoc_test_result().Failed()) {\n    OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());\n  }\n\n  *stream << \"</\" << kTestsuites << \">\\n\";\n}\n\nvoid XmlUnitTestResultPrinter::PrintXmlTestsList(\n    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {\n  const std::string kTestsuites = \"testsuites\";\n\n  *stream << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n  *stream << \"<\" << kTestsuites;\n\n  int total_tests = 0;\n  for (auto test_suite : test_suites) {\n    total_tests += test_suite->total_test_count();\n  }\n  OutputXmlAttribute(stream, kTestsuites, \"tests\",\n                     StreamableToString(total_tests));\n  OutputXmlAttribute(stream, kTestsuites, \"name\", \"AllTests\");\n  *stream << \">\\n\";\n\n  for (auto test_suite : test_suites) {\n    PrintXmlTestSuite(stream, *test_suite);\n  }\n  *stream << \"</\" << kTestsuites << \">\\n\";\n}\n\n// Produces a string representing the test properties in a result as space\n// delimited XML attributes based on the property key=\"value\" pairs.\nstd::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(\n    const TestResult& result) {\n  Message attributes;\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    attributes << \" \" << property.key() << \"=\" << \"\\\"\"\n               << EscapeXmlAttribute(property.value()) << \"\\\"\";\n  }\n  return attributes.GetString();\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlTestProperties(\n    std::ostream* stream, const TestResult& result) {\n  const std::string kProperties = \"properties\";\n  const std::string kProperty = \"property\";\n\n  if (result.test_property_count() <= 0) {\n    return;\n  }\n\n  *stream << \"      <\" << kProperties << \">\\n\";\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    *stream << \"        <\" << kProperty;\n    *stream << \" name=\\\"\" << EscapeXmlAttribute(property.key()) << \"\\\"\";\n    *stream << \" value=\\\"\" << EscapeXmlAttribute(property.value()) << \"\\\"\";\n    *stream << \"/>\\n\";\n  }\n  *stream << \"      </\" << kProperties << \">\\n\";\n}\n\n// End XmlUnitTestResultPrinter\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if GTEST_HAS_FILE_SYSTEM\n// This class generates an JSON output file.\nclass JsonUnitTestResultPrinter : public EmptyTestEventListener {\n public:\n  explicit JsonUnitTestResultPrinter(const char* output_file);\n\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n\n  // Prints an JSON summary of all unit tests.\n  static void PrintJsonTestList(::std::ostream* stream,\n                                const std::vector<TestSuite*>& test_suites);\n\n private:\n  // Returns an JSON-escaped copy of the input string str.\n  static std::string EscapeJson(const std::string& str);\n\n  //// Verifies that the given attribute belongs to the given element and\n  //// streams the attribute as JSON.\n  static void OutputJsonKey(std::ostream* stream,\n                            const std::string& element_name,\n                            const std::string& name, const std::string& value,\n                            const std::string& indent, bool comma = true);\n  static void OutputJsonKey(std::ostream* stream,\n                            const std::string& element_name,\n                            const std::string& name, int value,\n                            const std::string& indent, bool comma = true);\n\n  // Streams a test suite JSON stanza containing the given test result.\n  //\n  // Requires: result.Failed()\n  static void OutputJsonTestSuiteForTestResult(::std::ostream* stream,\n                                               const TestResult& result);\n\n  // Streams a JSON representation of a TestResult object.\n  static void OutputJsonTestResult(::std::ostream* stream,\n                                   const TestResult& result);\n\n  // Streams a JSON representation of a TestInfo object.\n  static void OutputJsonTestInfo(::std::ostream* stream,\n                                 const char* test_suite_name,\n                                 const TestInfo& test_info);\n\n  // Prints a JSON representation of a TestSuite object\n  static void PrintJsonTestSuite(::std::ostream* stream,\n                                 const TestSuite& test_suite);\n\n  // Prints a JSON summary of unit_test to output stream out.\n  static void PrintJsonUnitTest(::std::ostream* stream,\n                                const UnitTest& unit_test);\n\n  // Produces a string representing the test properties in a result as\n  // a JSON dictionary.\n  static std::string TestPropertiesAsJson(const TestResult& result,\n                                          const std::string& indent);\n\n  // The output file.\n  const std::string output_file_;\n\n  JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;\n  JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrinter&) =\n      delete;\n};\n\n// Creates a new JsonUnitTestResultPrinter.\nJsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)\n    : output_file_(output_file) {\n  if (output_file_.empty()) {\n    GTEST_LOG_(FATAL) << \"JSON output file may not be null\";\n  }\n}\n\nvoid JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                   int /*iteration*/) {\n  FILE* jsonout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintJsonUnitTest(&stream, unit_test);\n  fprintf(jsonout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(jsonout);\n}\n\n// Returns an JSON-escaped copy of the input string str.\nstd::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {\n  Message m;\n\n  for (size_t i = 0; i < str.size(); ++i) {\n    const char ch = str[i];\n    switch (ch) {\n      case '\\\\':\n      case '\"':\n      case '/':\n        m << '\\\\' << ch;\n        break;\n      case '\\b':\n        m << \"\\\\b\";\n        break;\n      case '\\t':\n        m << \"\\\\t\";\n        break;\n      case '\\n':\n        m << \"\\\\n\";\n        break;\n      case '\\f':\n        m << \"\\\\f\";\n        break;\n      case '\\r':\n        m << \"\\\\r\";\n        break;\n      default:\n        if (ch < ' ') {\n          m << \"\\\\u00\" << String::FormatByte(static_cast<unsigned char>(ch));\n        } else {\n          m << ch;\n        }\n        break;\n    }\n  }\n\n  return m.GetString();\n}\n\n// The following routines generate an JSON representation of a UnitTest\n// object.\n\n// Formats the given time in milliseconds as seconds.\nstatic std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {\n  ::std::stringstream ss;\n  ss << (static_cast<double>(ms) * 1e-3) << \"s\";\n  return ss.str();\n}\n\n// Converts the given epoch time in milliseconds to a date string in the\n// RFC3339 format, without the timezone information.\nstatic std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {\n  struct tm time_struct;\n  if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))\n    return \"\";\n  // YYYY-MM-DDThh:mm:ss\n  return StreamableToString(time_struct.tm_year + 1900) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mon + 1) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mday) + \"T\" +\n         String::FormatIntWidth2(time_struct.tm_hour) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_min) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_sec) + \"Z\";\n}\n\nstatic inline std::string Indent(size_t width) {\n  return std::string(width, ' ');\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonKey(std::ostream* stream,\n                                              const std::string& element_name,\n                                              const std::string& name,\n                                              const std::string& value,\n                                              const std::string& indent,\n                                              bool comma) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Key \\\"\" << name << \"\\\" is not allowed for value \\\"\" << element_name\n      << \"\\\".\";\n\n  *stream << indent << \"\\\"\" << name << \"\\\": \\\"\" << EscapeJson(value) << \"\\\"\";\n  if (comma) *stream << \",\\n\";\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonKey(\n    std::ostream* stream, const std::string& element_name,\n    const std::string& name, int value, const std::string& indent, bool comma) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Key \\\"\" << name << \"\\\" is not allowed for value \\\"\" << element_name\n      << \"\\\".\";\n\n  *stream << indent << \"\\\"\" << name << \"\\\": \" << StreamableToString(value);\n  if (comma) *stream << \",\\n\";\n}\n\n// Streams a test suite JSON stanza containing the given test result.\nvoid JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(\n    ::std::ostream* stream, const TestResult& result) {\n  // Output the boilerplate for a new test suite.\n  *stream << Indent(4) << \"{\\n\";\n  OutputJsonKey(stream, \"testsuite\", \"name\", \"NonTestSuiteFailure\", Indent(6));\n  OutputJsonKey(stream, \"testsuite\", \"tests\", 1, Indent(6));\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputJsonKey(stream, \"testsuite\", \"failures\", 1, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"disabled\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"skipped\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"errors\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"time\",\n                  FormatTimeInMillisAsDuration(result.elapsed_time()),\n                  Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"timestamp\",\n                  FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                  Indent(6));\n  }\n  *stream << Indent(6) << \"\\\"testsuite\\\": [\\n\";\n\n  // Output the boilerplate for a new test case.\n  *stream << Indent(8) << \"{\\n\";\n  OutputJsonKey(stream, \"testcase\", \"name\", \"\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"status\", \"RUN\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"result\", \"COMPLETED\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"time\",\n                FormatTimeInMillisAsDuration(result.elapsed_time()),\n                Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"classname\", \"\", Indent(10), false);\n  *stream << TestPropertiesAsJson(result, Indent(10));\n\n  // Output the actual test result.\n  OutputJsonTestResult(stream, result);\n\n  // Finish the test suite.\n  *stream << \"\\n\" << Indent(6) << \"]\\n\" << Indent(4) << \"}\";\n}\n\n// Prints a JSON representation of a TestInfo object.\nvoid JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,\n                                                   const char* test_suite_name,\n                                                   const TestInfo& test_info) {\n  const TestResult& result = *test_info.result();\n  const std::string kTestsuite = \"testcase\";\n  const std::string kIndent = Indent(10);\n\n  *stream << Indent(8) << \"{\\n\";\n  OutputJsonKey(stream, kTestsuite, \"name\", test_info.name(), kIndent);\n\n  if (test_info.value_param() != nullptr) {\n    OutputJsonKey(stream, kTestsuite, \"value_param\", test_info.value_param(),\n                  kIndent);\n  }\n  if (test_info.type_param() != nullptr) {\n    OutputJsonKey(stream, kTestsuite, \"type_param\", test_info.type_param(),\n                  kIndent);\n  }\n\n  OutputJsonKey(stream, kTestsuite, \"file\", test_info.file(), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"line\", test_info.line(), kIndent, false);\n  if (GTEST_FLAG_GET(list_tests)) {\n    *stream << \"\\n\" << Indent(8) << \"}\";\n    return;\n  } else {\n    *stream << \",\\n\";\n  }\n\n  OutputJsonKey(stream, kTestsuite, \"status\",\n                test_info.should_run() ? \"RUN\" : \"NOTRUN\", kIndent);\n  OutputJsonKey(stream, kTestsuite, \"result\",\n                test_info.should_run()\n                    ? (result.Skipped() ? \"SKIPPED\" : \"COMPLETED\")\n                    : \"SUPPRESSED\",\n                kIndent);\n  OutputJsonKey(stream, kTestsuite, \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                kIndent);\n  OutputJsonKey(stream, kTestsuite, \"time\",\n                FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"classname\", test_suite_name, kIndent,\n                false);\n  *stream << TestPropertiesAsJson(result, kIndent);\n\n  OutputJsonTestResult(stream, result);\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream,\n                                                     const TestResult& result) {\n  const std::string kIndent = Indent(10);\n\n  {\n    int failures = 0;\n    for (int i = 0; i < result.total_part_count(); ++i) {\n      const TestPartResult& part = result.GetTestPartResult(i);\n      if (part.failed()) {\n        *stream << \",\\n\";\n        if (++failures == 1) {\n          *stream << kIndent << \"\\\"\" << \"failures\" << \"\\\": [\\n\";\n        }\n        const std::string location =\n            internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                            part.line_number());\n        const std::string message =\n            EscapeJson(location + \"\\n\" + part.message());\n        *stream << kIndent << \"  {\\n\"\n                << kIndent << \"    \\\"failure\\\": \\\"\" << message << \"\\\",\\n\"\n                << kIndent << \"    \\\"type\\\": \\\"\\\"\\n\"\n                << kIndent << \"  }\";\n      }\n    }\n\n    if (failures > 0) *stream << \"\\n\" << kIndent << \"]\";\n  }\n\n  {\n    int skipped = 0;\n    for (int i = 0; i < result.total_part_count(); ++i) {\n      const TestPartResult& part = result.GetTestPartResult(i);\n      if (part.skipped()) {\n        *stream << \",\\n\";\n        if (++skipped == 1) {\n          *stream << kIndent << \"\\\"\" << \"skipped\" << \"\\\": [\\n\";\n        }\n        const std::string location =\n            internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                            part.line_number());\n        const std::string message =\n            EscapeJson(location + \"\\n\" + part.message());\n        *stream << kIndent << \"  {\\n\"\n                << kIndent << \"    \\\"message\\\": \\\"\" << message << \"\\\"\\n\"\n                << kIndent << \"  }\";\n      }\n    }\n\n    if (skipped > 0) *stream << \"\\n\" << kIndent << \"]\";\n  }\n\n  *stream << \"\\n\" << Indent(8) << \"}\";\n}\n\n// Prints an JSON representation of a TestSuite object\nvoid JsonUnitTestResultPrinter::PrintJsonTestSuite(\n    std::ostream* stream, const TestSuite& test_suite) {\n  const std::string kTestsuite = \"testsuite\";\n  const std::string kIndent = Indent(6);\n\n  *stream << Indent(4) << \"{\\n\";\n  OutputJsonKey(stream, kTestsuite, \"name\", test_suite.name(), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"tests\", test_suite.reportable_test_count(),\n                kIndent);\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputJsonKey(stream, kTestsuite, \"failures\",\n                  test_suite.failed_test_count(), kIndent);\n    OutputJsonKey(stream, kTestsuite, \"disabled\",\n                  test_suite.reportable_disabled_test_count(), kIndent);\n    OutputJsonKey(stream, kTestsuite, \"errors\", 0, kIndent);\n    OutputJsonKey(\n        stream, kTestsuite, \"timestamp\",\n        FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),\n        kIndent);\n    OutputJsonKey(stream, kTestsuite, \"time\",\n                  FormatTimeInMillisAsDuration(test_suite.elapsed_time()),\n                  kIndent, false);\n    *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent)\n            << \",\\n\";\n  }\n\n  *stream << kIndent << \"\\\"\" << kTestsuite << \"\\\": [\\n\";\n\n  bool comma = false;\n  for (int i = 0; i < test_suite.total_test_count(); ++i) {\n    if (test_suite.GetTestInfo(i)->is_reportable()) {\n      if (comma) {\n        *stream << \",\\n\";\n      } else {\n        comma = true;\n      }\n      OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));\n    }\n  }\n  *stream << \"\\n\" << kIndent << \"]\\n\" << Indent(4) << \"}\";\n}\n\n// Prints a JSON summary of unit_test to output stream out.\nvoid JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,\n                                                  const UnitTest& unit_test) {\n  const std::string kTestsuites = \"testsuites\";\n  const std::string kIndent = Indent(2);\n  *stream << \"{\\n\";\n\n  OutputJsonKey(stream, kTestsuites, \"tests\", unit_test.reportable_test_count(),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"failures\", unit_test.failed_test_count(),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"disabled\",\n                unit_test.reportable_disabled_test_count(), kIndent);\n  OutputJsonKey(stream, kTestsuites, \"errors\", 0, kIndent);\n  if (GTEST_FLAG_GET(shuffle)) {\n    OutputJsonKey(stream, kTestsuites, \"random_seed\", unit_test.random_seed(),\n                  kIndent);\n  }\n  OutputJsonKey(stream, kTestsuites, \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"time\",\n                FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,\n                false);\n\n  *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)\n          << \",\\n\";\n\n  OutputJsonKey(stream, kTestsuites, \"name\", \"AllTests\", kIndent);\n  *stream << kIndent << \"\\\"\" << kTestsuites << \"\\\": [\\n\";\n\n  bool comma = false;\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) {\n      if (comma) {\n        *stream << \",\\n\";\n      } else {\n        comma = true;\n      }\n      PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i));\n    }\n  }\n\n  // If there was a test failure outside of one of the test suites (like in a\n  // test environment) include that in the output.\n  if (unit_test.ad_hoc_test_result().Failed()) {\n    if (comma) {\n      *stream << \",\\n\";\n    }\n    OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());\n  }\n\n  *stream << \"\\n\"\n          << kIndent << \"]\\n\"\n          << \"}\\n\";\n}\n\nvoid JsonUnitTestResultPrinter::PrintJsonTestList(\n    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {\n  const std::string kTestsuites = \"testsuites\";\n  const std::string kIndent = Indent(2);\n  *stream << \"{\\n\";\n  int total_tests = 0;\n  for (auto test_suite : test_suites) {\n    total_tests += test_suite->total_test_count();\n  }\n  OutputJsonKey(stream, kTestsuites, \"tests\", total_tests, kIndent);\n\n  OutputJsonKey(stream, kTestsuites, \"name\", \"AllTests\", kIndent);\n  *stream << kIndent << \"\\\"\" << kTestsuites << \"\\\": [\\n\";\n\n  for (size_t i = 0; i < test_suites.size(); ++i) {\n    if (i != 0) {\n      *stream << \",\\n\";\n    }\n    PrintJsonTestSuite(stream, *test_suites[i]);\n  }\n\n  *stream << \"\\n\"\n          << kIndent << \"]\\n\"\n          << \"}\\n\";\n}\n// Produces a string representing the test properties in a result as\n// a JSON dictionary.\nstd::string JsonUnitTestResultPrinter::TestPropertiesAsJson(\n    const TestResult& result, const std::string& indent) {\n  Message attributes;\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    attributes << \",\\n\"\n               << indent << \"\\\"\" << property.key() << \"\\\": \" << \"\\\"\"\n               << EscapeJson(property.value()) << \"\\\"\";\n  }\n  return attributes.GetString();\n}\n\n// End JsonUnitTestResultPrinter\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if GTEST_CAN_STREAM_RESULTS_\n\n// Checks if str contains '=', '&', '%' or '\\n' characters. If yes,\n// replaces them by \"%xx\" where xx is their hexadecimal value. For\n// example, replaces \"=\" with \"%3D\".  This algorithm is O(strlen(str))\n// in both time and space -- important as the input str may contain an\n// arbitrarily long test failure message and stack trace.\nstd::string StreamingListener::UrlEncode(const char* str) {\n  std::string result;\n  result.reserve(strlen(str) + 1);\n  for (char ch = *str; ch != '\\0'; ch = *++str) {\n    switch (ch) {\n      case '%':\n      case '=':\n      case '&':\n      case '\\n':\n        result.push_back('%');\n        result.append(String::FormatByte(static_cast<unsigned char>(ch)));\n        break;\n      default:\n        result.push_back(ch);\n        break;\n    }\n  }\n  return result;\n}\n\nvoid StreamingListener::SocketWriter::MakeConnection() {\n  GTEST_CHECK_(sockfd_ == -1)\n      << \"MakeConnection() can't be called when there is already a connection.\";\n\n  addrinfo hints;\n  memset(&hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;  // To allow both IPv4 and IPv6 addresses.\n  hints.ai_socktype = SOCK_STREAM;\n  addrinfo* servinfo = nullptr;\n\n  // Use the getaddrinfo() to get a linked list of IP addresses for\n  // the given host name.\n  const int error_num =\n      getaddrinfo(host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);\n  if (error_num != 0) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: getaddrinfo() failed: \"\n                        << gai_strerror(error_num);\n  }\n\n  // Loop through all the results and connect to the first we can.\n  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr;\n       cur_addr = cur_addr->ai_next) {\n    sockfd_ = socket(cur_addr->ai_family, cur_addr->ai_socktype,\n                     cur_addr->ai_protocol);\n    if (sockfd_ != -1) {\n      // Connect the client socket to the server socket.\n      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {\n        close(sockfd_);\n        sockfd_ = -1;\n      }\n    }\n  }\n\n  freeaddrinfo(servinfo);  // all done with this structure\n\n  if (sockfd_ == -1) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: failed to connect to \"\n                        << host_name_ << \":\" << port_num_;\n  }\n}\n\n// End of class Streaming Listener\n#endif  // GTEST_CAN_STREAM_RESULTS__\n\n// class OsStackTraceGetter\n\nconst char* const OsStackTraceGetterInterface::kElidedFramesMarker =\n    \"... \" GTEST_NAME_ \" internal frames ...\";\n\nstd::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n#ifdef GTEST_HAS_ABSL\n  std::string result;\n\n  if (max_depth <= 0) {\n    return result;\n  }\n\n  max_depth = std::min(max_depth, kMaxStackTraceDepth);\n\n  std::vector<void*> raw_stack(max_depth);\n  // Skips the frames requested by the caller, plus this function.\n  const int raw_stack_size =\n      absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1);\n\n  void* caller_frame = nullptr;\n  {\n    MutexLock lock(&mutex_);\n    caller_frame = caller_frame_;\n  }\n\n  for (int i = 0; i < raw_stack_size; ++i) {\n    if (raw_stack[i] == caller_frame &&\n        !GTEST_FLAG_GET(show_internal_stack_frames)) {\n      // Add a marker to the trace and stop adding frames.\n      absl::StrAppend(&result, kElidedFramesMarker, \"\\n\");\n      break;\n    }\n\n    char tmp[1024];\n    const char* symbol = \"(unknown)\";\n    if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) {\n      symbol = tmp;\n    }\n\n    char line[1024];\n    snprintf(line, sizeof(line), \"  %p: %s\\n\", raw_stack[i], symbol);\n    result += line;\n  }\n\n  return result;\n\n#else   // !GTEST_HAS_ABSL\n  static_cast<void>(max_depth);\n  static_cast<void>(skip_count);\n  return \"\";\n#endif  // GTEST_HAS_ABSL\n}\n\nvoid OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {\n#ifdef GTEST_HAS_ABSL\n  void* caller_frame = nullptr;\n  if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) {\n    caller_frame = nullptr;\n  }\n\n  MutexLock lock(&mutex_);\n  caller_frame_ = caller_frame;\n#endif  // GTEST_HAS_ABSL\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n// A helper class that creates the premature-exit file in its\n// constructor and deletes the file in its destructor.\nclass ScopedPrematureExitFile {\n public:\n  explicit ScopedPrematureExitFile(const char* premature_exit_filepath)\n      : premature_exit_filepath_(\n            premature_exit_filepath ? premature_exit_filepath : \"\") {\n    // If a path to the premature-exit file is specified...\n    if (!premature_exit_filepath_.empty()) {\n      // create the file with a single \"0\" character in it.  I/O\n      // errors are ignored as there's nothing better we can do and we\n      // don't want to fail the test because of this.\n      FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), \"w\");\n      fwrite(\"0\", 1, 1, pfile);\n      fclose(pfile);\n    }\n  }\n\n  ~ScopedPrematureExitFile() {\n#ifndef GTEST_OS_ESP8266\n    if (!premature_exit_filepath_.empty()) {\n      int retval = remove(premature_exit_filepath_.c_str());\n      if (retval) {\n        GTEST_LOG_(ERROR) << \"Failed to remove premature exit filepath \\\"\"\n                          << premature_exit_filepath_ << \"\\\" with error \"\n                          << retval;\n      }\n    }\n#endif\n  }\n\n private:\n  const std::string premature_exit_filepath_;\n\n  ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;\n  ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;\n};\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace internal\n\n// class TestEventListeners\n\nTestEventListeners::TestEventListeners()\n    : repeater_(new internal::TestEventRepeater()),\n      default_result_printer_(nullptr),\n      default_xml_generator_(nullptr) {}\n\nTestEventListeners::~TestEventListeners() { delete repeater_; }\n\n// Returns the standard listener responsible for the default console\n// output.  Can be removed from the listeners list to shut down default\n// console output.  Note that removing this object from the listener list\n// with Release transfers its ownership to the user.\nvoid TestEventListeners::Append(TestEventListener* listener) {\n  repeater_->Append(listener);\n}\n\n// Removes the given event listener from the list and returns it.  It then\n// becomes the caller's responsibility to delete the listener. Returns\n// NULL if the listener is not found in the list.\nTestEventListener* TestEventListeners::Release(TestEventListener* listener) {\n  if (listener == default_result_printer_)\n    default_result_printer_ = nullptr;\n  else if (listener == default_xml_generator_)\n    default_xml_generator_ = nullptr;\n  return repeater_->Release(listener);\n}\n\n// Returns repeater that broadcasts the TestEventListener events to all\n// subscribers.\nTestEventListener* TestEventListeners::repeater() { return repeater_; }\n\n// Sets the default_result_printer attribute to the provided listener.\n// The listener is also added to the listener list and previous\n// default_result_printer is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {\n  if (default_result_printer_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_result_printer_);\n    default_result_printer_ = listener;\n    if (listener != nullptr) Append(listener);\n  }\n}\n\n// Sets the default_xml_generator attribute to the provided listener.  The\n// listener is also added to the listener list and previous\n// default_xml_generator is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {\n  if (default_xml_generator_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_xml_generator_);\n    default_xml_generator_ = listener;\n    if (listener != nullptr) Append(listener);\n  }\n}\n\n// Controls whether events will be forwarded by the repeater to the\n// listeners in the list.\nbool TestEventListeners::EventForwardingEnabled() const {\n  return repeater_->forwarding_enabled();\n}\n\nvoid TestEventListeners::SuppressEventForwarding(bool suppress) {\n  repeater_->set_forwarding_enabled(!suppress);\n}\n\n// class UnitTest\n\n// Gets the singleton UnitTest object.  The first time this method is\n// called, a UnitTest object is constructed and returned.  Consecutive\n// calls will return the same object.\n//\n// We don't protect this under mutex_ as a user is not supposed to\n// call this before main() starts, from which point on the return\n// value will never change.\nUnitTest* UnitTest::GetInstance() {\n  // CodeGear C++Builder insists on a public destructor for the\n  // default implementation.  Use this implementation to keep good OO\n  // design with private destructor.\n\n#if defined(__BORLANDC__)\n  static UnitTest* const instance = new UnitTest;\n  return instance;\n#else\n  static UnitTest instance;\n  return &instance;\n#endif  // defined(__BORLANDC__)\n}\n\n// Gets the number of successful test suites.\nint UnitTest::successful_test_suite_count() const {\n  return impl()->successful_test_suite_count();\n}\n\n// Gets the number of failed test suites.\nint UnitTest::failed_test_suite_count() const {\n  return impl()->failed_test_suite_count();\n}\n\n// Gets the number of all test suites.\nint UnitTest::total_test_suite_count() const {\n  return impl()->total_test_suite_count();\n}\n\n// Gets the number of all test suites that contain at least one test\n// that should run.\nint UnitTest::test_suite_to_run_count() const {\n  return impl()->test_suite_to_run_count();\n}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nint UnitTest::successful_test_case_count() const {\n  return impl()->successful_test_suite_count();\n}\nint UnitTest::failed_test_case_count() const {\n  return impl()->failed_test_suite_count();\n}\nint UnitTest::total_test_case_count() const {\n  return impl()->total_test_suite_count();\n}\nint UnitTest::test_case_to_run_count() const {\n  return impl()->test_suite_to_run_count();\n}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Gets the number of successful tests.\nint UnitTest::successful_test_count() const {\n  return impl()->successful_test_count();\n}\n\n// Gets the number of skipped tests.\nint UnitTest::skipped_test_count() const {\n  return impl()->skipped_test_count();\n}\n\n// Gets the number of failed tests.\nint UnitTest::failed_test_count() const { return impl()->failed_test_count(); }\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint UnitTest::reportable_disabled_test_count() const {\n  return impl()->reportable_disabled_test_count();\n}\n\n// Gets the number of disabled tests.\nint UnitTest::disabled_test_count() const {\n  return impl()->disabled_test_count();\n}\n\n// Gets the number of tests to be printed in the XML report.\nint UnitTest::reportable_test_count() const {\n  return impl()->reportable_test_count();\n}\n\n// Gets the number of all tests.\nint UnitTest::total_test_count() const { return impl()->total_test_count(); }\n\n// Gets the number of tests that should run.\nint UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }\n\n// Gets the time of the test program start, in ms from the start of the\n// UNIX epoch.\ninternal::TimeInMillis UnitTest::start_timestamp() const {\n  return impl()->start_timestamp();\n}\n\n// Gets the elapsed time, in milliseconds.\ninternal::TimeInMillis UnitTest::elapsed_time() const {\n  return impl()->elapsed_time();\n}\n\n// Returns true if and only if the unit test passed (i.e. all test suites\n// passed).\nbool UnitTest::Passed() const { return impl()->Passed(); }\n\n// Returns true if and only if the unit test failed (i.e. some test suite\n// failed or something outside of all tests failed).\nbool UnitTest::Failed() const { return impl()->Failed(); }\n\n// Gets the i-th test suite among all the test suites. i can range from 0 to\n// total_test_suite_count() - 1. If i is not in that range, returns NULL.\nconst TestSuite* UnitTest::GetTestSuite(int i) const {\n  return impl()->GetTestSuite(i);\n}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nconst TestCase* UnitTest::GetTestCase(int i) const {\n  return impl()->GetTestCase(i);\n}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Returns the TestResult containing information on test failures and\n// properties logged outside of individual test suites.\nconst TestResult& UnitTest::ad_hoc_test_result() const {\n  return *impl()->ad_hoc_test_result();\n}\n\n// Gets the i-th test suite among all the test suites. i can range from 0 to\n// total_test_suite_count() - 1. If i is not in that range, returns NULL.\nTestSuite* UnitTest::GetMutableTestSuite(int i) {\n  return impl()->GetMutableSuiteCase(i);\n}\n\nvoid UnitTest::UponLeavingGTest() {\n  impl()->os_stack_trace_getter()->UponLeavingGTest();\n}\n\n// Sets the TestSuite object for the test that's currently running.\nvoid UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {\n  internal::MutexLock lock(&mutex_);\n  impl_->set_current_test_suite(a_current_test_suite);\n}\n\n// Sets the TestInfo object for the test that's currently running.\nvoid UnitTest::set_current_test_info(TestInfo* a_current_test_info) {\n  internal::MutexLock lock(&mutex_);\n  impl_->set_current_test_info(a_current_test_info);\n}\n\n// Returns the list of event listeners that can be used to track events\n// inside Google Test.\nTestEventListeners& UnitTest::listeners() { return *impl()->listeners(); }\n\n// Registers and returns a global test environment.  When a test\n// program is run, all global test environments will be set-up in the\n// order they were registered.  After all tests in the program have\n// finished, all global test environments will be torn-down in the\n// *reverse* order they were registered.\n//\n// The UnitTest object takes ownership of the given environment.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nEnvironment* UnitTest::AddEnvironment(Environment* env) {\n  if (env == nullptr) {\n    return nullptr;\n  }\n\n  impl_->environments().push_back(env);\n  return env;\n}\n\n// Adds a TestPartResult to the current TestResult object.  All Google Test\n// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call\n// this to report their results.  The user code should use the\n// assertion macros instead of calling this directly.\nvoid UnitTest::AddTestPartResult(TestPartResult::Type result_type,\n                                 const char* file_name, int line_number,\n                                 const std::string& message,\n                                 const std::string& os_stack_trace)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  Message msg;\n  msg << message;\n\n  internal::MutexLock lock(&mutex_);\n  if (!impl_->gtest_trace_stack().empty()) {\n    msg << \"\\n\" << GTEST_NAME_ << \" trace:\";\n\n    for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) {\n      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];\n      msg << \"\\n\"\n          << internal::FormatFileLocation(trace.file, trace.line) << \" \"\n          << trace.message;\n    }\n  }\n\n  if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) {\n    msg << internal::kStackTraceMarker << os_stack_trace;\n  } else {\n    msg << \"\\n\";\n  }\n\n  const TestPartResult result = TestPartResult(\n      result_type, file_name, line_number, msg.GetString().c_str());\n  impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(\n      result);\n\n  if (result_type != TestPartResult::kSuccess &&\n      result_type != TestPartResult::kSkip) {\n    // gtest_break_on_failure takes precedence over\n    // gtest_throw_on_failure.  This allows a user to set the latter\n    // in the code (perhaps in order to use Google Test assertions\n    // with another testing framework) and specify the former on the\n    // command line for debugging.\n    if (GTEST_FLAG_GET(break_on_failure)) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT)\n      // Using DebugBreak on Windows allows gtest to still break into a debugger\n      // when a failure happens and both the --gtest_break_on_failure and\n      // the --gtest_catch_exceptions flags are specified.\n      DebugBreak();\n#elif (!defined(__native_client__)) &&            \\\n    ((defined(__clang__) || defined(__GNUC__)) && \\\n     (defined(__x86_64__) || defined(__i386__)))\n      // with clang/gcc we can achieve the same effect on x86 by invoking int3\n      asm(\"int3\");\n#elif GTEST_HAS_BUILTIN(__builtin_trap)\n      __builtin_trap();\n#elif defined(SIGTRAP)\n      raise(SIGTRAP);\n#else\n      // Dereference nullptr through a volatile pointer to prevent the compiler\n      // from removing. We use this rather than abort() or __builtin_trap() for\n      // portability: some debuggers don't correctly trap abort().\n      *static_cast<volatile int*>(nullptr) = 1;\n#endif  // GTEST_OS_WINDOWS\n    } else if (GTEST_FLAG_GET(throw_on_failure)) {\n#if GTEST_HAS_EXCEPTIONS\n      throw internal::GoogleTestFailureException(result);\n#else\n      // We cannot call abort() as it generates a pop-up in debug mode\n      // that cannot be suppressed in VC 7.1 or below.\n      exit(1);\n#endif\n    }\n  }\n}\n\n// Adds a TestProperty to the current TestResult object when invoked from\n// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked\n// from SetUpTestSuite or TearDownTestSuite, or to the global property set\n// when invoked elsewhere.  If the result already contains a property with\n// the same key, the value will be updated.\nvoid UnitTest::RecordProperty(const std::string& key,\n                              const std::string& value) {\n  impl_->RecordProperty(TestProperty(key, value));\n}\n\n// Runs all tests in this UnitTest object and prints the result.\n// Returns 0 if successful, or 1 otherwise.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nint UnitTest::Run() {\n#ifdef GTEST_HAS_DEATH_TEST\n  const bool in_death_test_child_process =\n      !GTEST_FLAG_GET(internal_run_death_test).empty();\n\n  // Google Test implements this protocol for catching that a test\n  // program exits before returning control to Google Test:\n  //\n  //   1. Upon start, Google Test creates a file whose absolute path\n  //      is specified by the environment variable\n  //      TEST_PREMATURE_EXIT_FILE.\n  //   2. When Google Test has finished its work, it deletes the file.\n  //\n  // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before\n  // running a Google-Test-based test program and check the existence\n  // of the file at the end of the test execution to see if it has\n  // exited prematurely.\n\n  // If we are in the child process of a death test, don't\n  // create/delete the premature exit file, as doing so is unnecessary\n  // and will confuse the parent process.  Otherwise, create/delete\n  // the file upon entering/leaving this function.  If the program\n  // somehow exits before this function has a chance to return, the\n  // premature-exit file will be left undeleted, causing a test runner\n  // that understands the premature-exit-file protocol to report the\n  // test as having failed.\n  const internal::ScopedPrematureExitFile premature_exit_file(\n      in_death_test_child_process\n          ? nullptr\n          : internal::posix::GetEnv(\"TEST_PREMATURE_EXIT_FILE\"));\n#else\n  const bool in_death_test_child_process = false;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be\n  // used for the duration of the program.\n  impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions));\n\n#ifdef GTEST_OS_WINDOWS\n  // Either the user wants Google Test to catch exceptions thrown by the\n  // tests or this is executing in the context of death test child\n  // process. In either case the user does not want to see pop-up dialogs\n  // about crashes - they are expected.\n  if (impl()->catch_exceptions() || in_death_test_child_process) {\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES)\n    // SetErrorMode doesn't exist on CE.\n    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |\n                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n#if (defined(_MSC_VER) || defined(GTEST_OS_WINDOWS_MINGW)) && \\\n    !defined(GTEST_OS_WINDOWS_MOBILE)\n    // Death test children can be terminated with _abort().  On Windows,\n    // _abort() can show a dialog with a warning message.  This forces the\n    // abort message to go to stderr instead.\n    _set_error_mode(_OUT_TO_STDERR);\n#endif\n\n#if defined(_MSC_VER) && !defined(GTEST_OS_WINDOWS_MOBILE)\n    // In the debug version, Visual Studio pops up a separate dialog\n    // offering a choice to debug the aborted program. We need to suppress\n    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement\n    // executed. Google Test will notify the user of any unexpected\n    // failure via stderr.\n    if (!GTEST_FLAG_GET(break_on_failure))\n      _set_abort_behavior(\n          0x0,                                    // Clear the following flags:\n          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.\n\n    // In debug mode, the Windows CRT can crash with an assertion over invalid\n    // input (e.g. passing an invalid file descriptor).  The default handling\n    // for these assertions is to pop up a dialog and wait for user input.\n    // Instead ask the CRT to dump such assertions to stderr non-interactively.\n    if (!IsDebuggerPresent()) {\n      (void)_CrtSetReportMode(_CRT_ASSERT,\n                              _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n      (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);\n    }\n#endif\n  }\n#else\n  (void)in_death_test_child_process;  // Needed inside the #if block above\n#endif  // GTEST_OS_WINDOWS\n\n  return internal::HandleExceptionsInMethodIfSupported(\n             impl(), &internal::UnitTestImpl::RunAllTests,\n             \"auxiliary test code (environments or event listeners)\")\n             ? 0\n             : 1;\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the working directory when the first TEST() or TEST_F() was\n// executed.\nconst char* UnitTest::original_working_dir() const {\n  return impl_->original_working_dir_.c_str();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Returns the TestSuite object for the test that's currently running,\n// or NULL if no test is running.\nconst TestSuite* UnitTest::current_test_suite() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_suite();\n}\n\n// Legacy API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nconst TestCase* UnitTest::current_test_case() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_suite();\n}\n#endif\n\n// Returns the TestInfo object for the test that's currently running,\n// or NULL if no test is running.\nconst TestInfo* UnitTest::current_test_info() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_info();\n}\n\n// Returns the random seed used at the start of the current test run.\nint UnitTest::random_seed() const { return impl_->random_seed(); }\n\n// Returns ParameterizedTestSuiteRegistry object used to keep track of\n// value-parameterized tests and instantiate and register them.\ninternal::ParameterizedTestSuiteRegistry&\nUnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) {\n  return impl_->parameterized_test_registry();\n}\n\n// Creates an empty UnitTest.\nUnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); }\n\n// Destructor of UnitTest.\nUnitTest::~UnitTest() { delete impl_; }\n\n// Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n// Google Test trace stack.\nvoid UnitTest::PushGTestTrace(const internal::TraceInfo& trace)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().push_back(trace);\n}\n\n// Pops a trace from the per-thread Google Test trace stack.\nvoid UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().pop_back();\n}\n\nnamespace internal {\n\nUnitTestImpl::UnitTestImpl(UnitTest* parent)\n    : parent_(parent),\n      GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)\n          default_global_test_part_result_reporter_(this),\n      default_per_thread_test_part_result_reporter_(this),\n      GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_reporter_(\n          &default_global_test_part_result_reporter_),\n      per_thread_test_part_result_reporter_(\n          &default_per_thread_test_part_result_reporter_),\n      parameterized_test_registry_(),\n      parameterized_tests_registered_(false),\n      last_death_test_suite_(-1),\n      current_test_suite_(nullptr),\n      current_test_info_(nullptr),\n      ad_hoc_test_result_(),\n      os_stack_trace_getter_(nullptr),\n      post_flag_parse_init_performed_(false),\n      random_seed_(0),  // Will be overridden by the flag before first use.\n      random_(0),       // Will be reseeded before first use.\n      start_timestamp_(0),\n      elapsed_time_(0),\n#ifdef GTEST_HAS_DEATH_TEST\n      death_test_factory_(new DefaultDeathTestFactory),\n#endif\n      // Will be overridden by the flag before first use.\n      catch_exceptions_(false) {\n  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);\n}\n\nUnitTestImpl::~UnitTestImpl() {\n  // Deletes every TestSuite.\n  ForEach(test_suites_, internal::Delete<TestSuite>);\n\n  // Deletes every Environment.\n  ForEach(environments_, internal::Delete<Environment>);\n\n  delete os_stack_trace_getter_;\n}\n\n// Adds a TestProperty to the current TestResult object when invoked in a\n// context of a test, to current test suite's ad_hoc_test_result when invoke\n// from SetUpTestSuite/TearDownTestSuite, or to the global property set\n// otherwise.  If the result already contains a property with the same key,\n// the value will be updated.\nvoid UnitTestImpl::RecordProperty(const TestProperty& test_property) {\n  std::string xml_element;\n  TestResult* test_result;  // TestResult appropriate for property recording.\n\n  if (current_test_info_ != nullptr) {\n    xml_element = \"testcase\";\n    test_result = &(current_test_info_->result_);\n  } else if (current_test_suite_ != nullptr) {\n    xml_element = \"testsuite\";\n    test_result = &(current_test_suite_->ad_hoc_test_result_);\n  } else {\n    xml_element = \"testsuites\";\n    test_result = &ad_hoc_test_result_;\n  }\n  test_result->RecordProperty(xml_element, test_property);\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n// Disables event forwarding if the control is currently in a death test\n// subprocess. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::SuppressTestEventsIfInSubprocess() {\n  if (internal_run_death_test_flag_ != nullptr)\n    listeners()->SuppressEventForwarding(true);\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Initializes event listeners performing XML output as specified by\n// UnitTestOptions. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureXmlOutput() {\n  const std::string& output_format = UnitTestOptions::GetOutputFormat();\n#if GTEST_HAS_FILE_SYSTEM\n  if (output_format == \"xml\") {\n    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(\n        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\n  } else if (output_format == \"json\") {\n    listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(\n        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\n  } else if (!output_format.empty()) {\n    GTEST_LOG_(WARNING) << \"WARNING: unrecognized output format \\\"\"\n                        << output_format << \"\\\" ignored.\";\n  }\n#else\n  if (!output_format.empty()) {\n    GTEST_LOG_(ERROR) << \"ERROR: alternative output formats require \"\n                      << \"GTEST_HAS_FILE_SYSTEM to be enabled\";\n  }\n#endif  // GTEST_HAS_FILE_SYSTEM\n}\n\n#if GTEST_CAN_STREAM_RESULTS_\n// Initializes event listeners for streaming test results in string form.\n// Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureStreamingOutput() {\n  const std::string& target = GTEST_FLAG_GET(stream_result_to);\n  if (!target.empty()) {\n    const size_t pos = target.find(':');\n    if (pos != std::string::npos) {\n      listeners()->Append(\n          new StreamingListener(target.substr(0, pos), target.substr(pos + 1)));\n    } else {\n      GTEST_LOG_(WARNING) << \"unrecognized streaming target \\\"\" << target\n                          << \"\\\" ignored.\";\n    }\n  }\n}\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n// Performs initialization dependent upon flag values obtained in\n// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n// this function is also called from RunAllTests.  Since this function can be\n// called more than once, it has to be idempotent.\nvoid UnitTestImpl::PostFlagParsingInit() {\n  // Ensures that this function does not execute more than once.\n  if (!post_flag_parse_init_performed_) {\n    post_flag_parse_init_performed_ = true;\n\n#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)\n    // Register to send notifications about key process state changes.\n    listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());\n#endif  // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)\n\n#ifdef GTEST_HAS_DEATH_TEST\n    InitDeathTestSubprocessControlInfo();\n    SuppressTestEventsIfInSubprocess();\n#endif  // GTEST_HAS_DEATH_TEST\n\n    // Registers parameterized tests. This makes parameterized tests\n    // available to the UnitTest reflection API without running\n    // RUN_ALL_TESTS.\n    RegisterParameterizedTests();\n\n    // Configures listeners for XML output. This makes it possible for users\n    // to shut down the default XML output before invoking RUN_ALL_TESTS.\n    ConfigureXmlOutput();\n\n    if (GTEST_FLAG_GET(brief)) {\n      listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);\n    }\n\n#if GTEST_CAN_STREAM_RESULTS_\n    // Configures listeners for streaming test results to the specified server.\n    ConfigureStreamingOutput();\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n#ifdef GTEST_HAS_ABSL\n    if (GTEST_FLAG_GET(install_failure_signal_handler)) {\n      absl::FailureSignalHandlerOptions options;\n      absl::InstallFailureSignalHandler(options);\n    }\n#endif  // GTEST_HAS_ABSL\n  }\n}\n\n// Finds and returns a TestSuite with the given name.  If one doesn't\n// exist, creates one and returns it.  It's the CALLER'S\n// RESPONSIBILITY to ensure that this function is only called WHEN THE\n// TESTS ARE NOT SHUFFLED.\n//\n// Arguments:\n//\n//   test_suite_name: name of the test suite\n//   type_param:      the name of the test suite's type parameter, or NULL if\n//                    this is not a typed or a type-parameterized test suite.\n//   set_up_tc:       pointer to the function that sets up the test suite\n//   tear_down_tc:    pointer to the function that tears down the test suite\nTestSuite* UnitTestImpl::GetTestSuite(\n    const std::string& test_suite_name, const char* type_param,\n    internal::SetUpTestSuiteFunc set_up_tc,\n    internal::TearDownTestSuiteFunc tear_down_tc) {\n  // During initialization, all TestInfos for a given suite are added in\n  // sequence. To optimize this case, see if the most recently added suite is\n  // the one being requested now.\n  if (!test_suites_.empty() &&\n      (*test_suites_.rbegin())->name_ == test_suite_name) {\n    return *test_suites_.rbegin();\n  }\n\n  // Fall back to searching the collection.\n  auto item_it = test_suites_by_name_.find(test_suite_name);\n  if (item_it != test_suites_by_name_.end()) {\n    return item_it->second;\n  }\n\n  // Not found. Create a new instance.\n  auto* const new_test_suite =\n      new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);\n  test_suites_by_name_.emplace(test_suite_name, new_test_suite);\n\n  const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);\n  // Is this a death test suite?\n  if (death_test_suite_filter.MatchesName(test_suite_name)) {\n    // Yes.  Inserts the test suite after the last death test suite\n    // defined so far.  This only works when the test suites haven't\n    // been shuffled.  Otherwise we may end up running a death test\n    // after a non-death test.\n    ++last_death_test_suite_;\n    test_suites_.insert(test_suites_.begin() + last_death_test_suite_,\n                        new_test_suite);\n  } else {\n    // No.  Appends to the end of the list.\n    test_suites_.push_back(new_test_suite);\n  }\n\n  test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size()));\n  return new_test_suite;\n}\n\n// Helpers for setting up / tearing down the given environment.  They\n// are for use in the ForEach() function.\nstatic void SetUpEnvironment(Environment* env) { env->SetUp(); }\nstatic void TearDownEnvironment(Environment* env) { env->TearDown(); }\n\n// Runs all tests in this UnitTest object, prints the result, and\n// returns true if all tests are successful.  If any exception is\n// thrown during a test, the test is considered to be failed, but the\n// rest of the tests will still be run.\n//\n// When parameterized tests are enabled, it expands and registers\n// parameterized tests first in RegisterParameterizedTests().\n// All other functions called from RunAllTests() may safely assume that\n// parameterized tests are ready to be counted and run.\nbool UnitTestImpl::RunAllTests() {\n  // True if and only if Google Test is initialized before RUN_ALL_TESTS() is\n  // called.\n  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();\n\n  // Do not run any test if the --help flag was specified.\n  if (g_help_flag) return true;\n\n  // Repeats the call to the post-flag parsing initialization in case the\n  // user didn't call InitGoogleTest.\n  PostFlagParsingInit();\n\n#if GTEST_HAS_FILE_SYSTEM\n  // Even if sharding is not on, test runners may want to use the\n  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding\n  // protocol.\n  internal::WriteToShardStatusFileIfNeeded();\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n  // True if and only if we are in a subprocess for running a thread-safe-style\n  // death test.\n  bool in_subprocess_for_death_test = false;\n\n#ifdef GTEST_HAS_DEATH_TEST\n  in_subprocess_for_death_test = (internal_run_death_test_flag_ != nullptr);\n#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)\n  if (in_subprocess_for_death_test) {\n    GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();\n  }\n#endif  // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)\n#endif  // GTEST_HAS_DEATH_TEST\n\n  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,\n                                        in_subprocess_for_death_test);\n\n  // Compares the full test names with the filter to decide which\n  // tests to run.\n  const bool has_tests_to_run =\n      FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL\n                               : IGNORE_SHARDING_PROTOCOL) > 0;\n\n  // Lists the tests and exits if the --gtest_list_tests flag was specified.\n  if (GTEST_FLAG_GET(list_tests)) {\n    // This must be called *after* FilterTests() has been called.\n    ListTestsMatchingFilter();\n    return true;\n  }\n\n  random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed));\n\n  // True if and only if at least one test has failed.\n  bool failed = false;\n\n  TestEventListener* repeater = listeners()->repeater();\n\n  start_timestamp_ = GetTimeInMillis();\n  repeater->OnTestProgramStart(*parent_);\n\n  // How many times to repeat the tests?  We don't want to repeat them\n  // when we are inside the subprocess of a death test.\n  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);\n\n  // Repeats forever if the repeat count is negative.\n  const bool gtest_repeat_forever = repeat < 0;\n\n  // Should test environments be set up and torn down for each repeat, or only\n  // set up on the first and torn down on the last iteration? If there is no\n  // \"last\" iteration because the tests will repeat forever, always recreate the\n  // environments to avoid leaks in case one of the environments is using\n  // resources that are external to this process. Without this check there would\n  // be no way to clean up those external resources automatically.\n  const bool recreate_environments_when_repeating =\n      GTEST_FLAG_GET(recreate_environments_when_repeating) ||\n      gtest_repeat_forever;\n\n  for (int i = 0; gtest_repeat_forever || i != repeat; i++) {\n    // We want to preserve failures generated by ad-hoc test\n    // assertions executed before RUN_ALL_TESTS().\n    ClearNonAdHocTestResult();\n\n    Timer timer;\n\n    // Shuffles test suites and tests if requested.\n    if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {\n      random()->Reseed(static_cast<uint32_t>(random_seed_));\n      // This should be done before calling OnTestIterationStart(),\n      // such that a test event listener can see the actual test order\n      // in the event.\n      ShuffleTests();\n    }\n\n    // Tells the unit test event listeners that the tests are about to start.\n    repeater->OnTestIterationStart(*parent_, i);\n\n    // Runs each test suite if there is at least one test to run.\n    if (has_tests_to_run) {\n      // Sets up all environments beforehand. If test environments aren't\n      // recreated for each iteration, only do so on the first iteration.\n      if (i == 0 || recreate_environments_when_repeating) {\n        repeater->OnEnvironmentsSetUpStart(*parent_);\n        ForEach(environments_, SetUpEnvironment);\n        repeater->OnEnvironmentsSetUpEnd(*parent_);\n      }\n\n      // Runs the tests only if there was no fatal failure or skip triggered\n      // during global set-up.\n      if (Test::IsSkipped()) {\n        // Emit diagnostics when global set-up calls skip, as it will not be\n        // emitted by default.\n        TestResult& test_result =\n            *internal::GetUnitTestImpl()->current_test_result();\n        for (int j = 0; j < test_result.total_part_count(); ++j) {\n          const TestPartResult& test_part_result =\n              test_result.GetTestPartResult(j);\n          if (test_part_result.type() == TestPartResult::kSkip) {\n            const std::string& result = test_part_result.message();\n            printf(\"%s\\n\", result.c_str());\n          }\n        }\n        fflush(stdout);\n      } else if (!Test::HasFatalFailure()) {\n        for (int test_index = 0; test_index < total_test_suite_count();\n             test_index++) {\n          GetMutableSuiteCase(test_index)->Run();\n          if (GTEST_FLAG_GET(fail_fast) &&\n              GetMutableSuiteCase(test_index)->Failed()) {\n            for (int j = test_index + 1; j < total_test_suite_count(); j++) {\n              GetMutableSuiteCase(j)->Skip();\n            }\n            break;\n          }\n        }\n      } else if (Test::HasFatalFailure()) {\n        // If there was a fatal failure during the global setup then we know we\n        // aren't going to run any tests. Explicitly mark all of the tests as\n        // skipped to make this obvious in the output.\n        for (int test_index = 0; test_index < total_test_suite_count();\n             test_index++) {\n          GetMutableSuiteCase(test_index)->Skip();\n        }\n      }\n\n      // Tears down all environments in reverse order afterwards. If test\n      // environments aren't recreated for each iteration, only do so on the\n      // last iteration.\n      if (i == repeat - 1 || recreate_environments_when_repeating) {\n        repeater->OnEnvironmentsTearDownStart(*parent_);\n        std::for_each(environments_.rbegin(), environments_.rend(),\n                      TearDownEnvironment);\n        repeater->OnEnvironmentsTearDownEnd(*parent_);\n      }\n    }\n\n    elapsed_time_ = timer.Elapsed();\n\n    // Tells the unit test event listener that the tests have just finished.\n    repeater->OnTestIterationEnd(*parent_, i);\n\n    // Gets the result and clears it.\n    if (!Passed()) {\n      failed = true;\n    }\n\n    // Restores the original test order after the iteration.  This\n    // allows the user to quickly repro a failure that happens in the\n    // N-th iteration without repeating the first (N - 1) iterations.\n    // This is not enclosed in \"if (GTEST_FLAG(shuffle)) { ... }\", in\n    // case the user somehow changes the value of the flag somewhere\n    // (it's always safe to unshuffle the tests).\n    UnshuffleTests();\n\n    if (GTEST_FLAG_GET(shuffle)) {\n      // Picks a new random seed for each iteration.\n      random_seed_ = GetNextRandomSeed(random_seed_);\n    }\n  }\n\n  repeater->OnTestProgramEnd(*parent_);\n  // Destroy environments in normal code, not in static teardown.\n  bool delete_environment_on_teardown = true;\n  if (delete_environment_on_teardown) {\n    ForEach(environments_, internal::Delete<Environment>);\n    environments_.clear();\n  }\n\n  if (!gtest_is_initialized_before_run_all_tests) {\n    ColoredPrintf(\n        GTestColor::kRed,\n        \"\\nIMPORTANT NOTICE - DO NOT IGNORE:\\n\"\n        \"This test program did NOT call \" GTEST_INIT_GOOGLE_TEST_NAME_\n        \"() before calling RUN_ALL_TESTS(). This is INVALID. Soon \" GTEST_NAME_\n        \" will start to enforce the valid usage. \"\n        \"Please fix it ASAP, or IT WILL START TO FAIL.\\n\");  // NOLINT\n  }\n\n  return !failed;\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded() {\n  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);\n  if (test_shard_file != nullptr) {\n    FILE* const file = posix::FOpen(test_shard_file, \"w\");\n    if (file == nullptr) {\n      ColoredPrintf(GTestColor::kRed,\n                    \"Could not write to the test shard status file \\\"%s\\\" \"\n                    \"specified by the %s environment variable.\\n\",\n                    test_shard_file, kTestShardStatusFile);\n      fflush(stdout);\n      exit(EXIT_FAILURE);\n    }\n    fclose(file);\n  }\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (i.e., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nbool ShouldShard(const char* total_shards_env, const char* shard_index_env,\n                 bool in_subprocess_for_death_test) {\n  if (in_subprocess_for_death_test) {\n    return false;\n  }\n\n  const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1);\n  const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1);\n\n  if (total_shards == -1 && shard_index == -1) {\n    return false;\n  } else if (total_shards == -1 && shard_index != -1) {\n    const Message msg = Message() << \"Invalid environment variables: you have \"\n                                  << kTestShardIndex << \" = \" << shard_index\n                                  << \", but have left \" << kTestTotalShards\n                                  << \" unset.\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (total_shards != -1 && shard_index == -1) {\n    const Message msg = Message()\n                        << \"Invalid environment variables: you have \"\n                        << kTestTotalShards << \" = \" << total_shards\n                        << \", but have left \" << kTestShardIndex << \" unset.\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (shard_index < 0 || shard_index >= total_shards) {\n    const Message msg =\n        Message() << \"Invalid environment variables: we require 0 <= \"\n                  << kTestShardIndex << \" < \" << kTestTotalShards\n                  << \", but you have \" << kTestShardIndex << \"=\" << shard_index\n                  << \", \" << kTestTotalShards << \"=\" << total_shards << \".\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  }\n\n  return total_shards > 1;\n}\n\n// Parses the environment variable var as an Int32. If it is unset,\n// returns default_val. If it is not an Int32, prints an error\n// and aborts.\nint32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {\n  const char* str_val = posix::GetEnv(var);\n  if (str_val == nullptr) {\n    return default_val;\n  }\n\n  int32_t result;\n  if (!ParseInt32(Message() << \"The value of environment variable \" << var,\n                  str_val, &result)) {\n    exit(EXIT_FAILURE);\n  }\n  return result;\n}\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true if and only if the test should be run on this shard. The test id\n// is some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nbool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {\n  return (test_id % total_shards) == shard_index;\n}\n\n// Compares the name of each test with the user-specified filter to\n// decide whether the test should be run, then records the result in\n// each TestSuite and TestInfo object.\n// If shard_tests == true, further filters tests based on sharding\n// variables in the environment - see\n// https://github.com/google/googletest/blob/main/docs/advanced.md\n// . Returns the number of tests that should run.\nint UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {\n  const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL\n                                   ? Int32FromEnvOrDie(kTestTotalShards, -1)\n                                   : -1;\n  const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL\n                                  ? Int32FromEnvOrDie(kTestShardIndex, -1)\n                                  : -1;\n\n  const PositiveAndNegativeUnitTestFilter gtest_flag_filter(\n      GTEST_FLAG_GET(filter));\n  const UnitTestFilter disable_test_filter(kDisableTestFilter);\n  // num_runnable_tests are the number of tests that will\n  // run across all shards (i.e., match filter and are not disabled).\n  // num_selected_tests are the number of tests to be run on\n  // this shard.\n  int num_runnable_tests = 0;\n  int num_selected_tests = 0;\n  for (auto* test_suite : test_suites_) {\n    const std::string& test_suite_name = test_suite->name_;\n    test_suite->set_should_run(false);\n\n    for (TestInfo* test_info : test_suite->test_info_list()) {\n      const std::string& test_name = test_info->name_;\n      // A test is disabled if test suite name or test name matches\n      // kDisableTestFilter.\n      const bool is_disabled =\n          disable_test_filter.MatchesName(test_suite_name) ||\n          disable_test_filter.MatchesName(test_name);\n      test_info->is_disabled_ = is_disabled;\n\n      const bool matches_filter =\n          gtest_flag_filter.MatchesTest(test_suite_name, test_name);\n      test_info->matches_filter_ = matches_filter;\n\n      const bool is_runnable =\n          (GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) &&\n          matches_filter;\n\n      const bool is_in_another_shard =\n          shard_tests != IGNORE_SHARDING_PROTOCOL &&\n          !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);\n      test_info->is_in_another_shard_ = is_in_another_shard;\n      const bool is_selected = is_runnable && !is_in_another_shard;\n\n      num_runnable_tests += is_runnable;\n      num_selected_tests += is_selected;\n\n      test_info->should_run_ = is_selected;\n      test_suite->set_should_run(test_suite->should_run() || is_selected);\n    }\n  }\n  return num_selected_tests;\n}\n\n// Prints the given C-string on a single line by replacing all '\\n'\n// characters with string \"\\\\n\".  If the output takes more than\n// max_length characters, only prints the first max_length characters\n// and \"...\".\nstatic void PrintOnOneLine(const char* str, int max_length) {\n  if (str != nullptr) {\n    for (int i = 0; *str != '\\0'; ++str) {\n      if (i >= max_length) {\n        printf(\"...\");\n        break;\n      }\n      if (*str == '\\n') {\n        printf(\"\\\\n\");\n        i += 2;\n      } else {\n        printf(\"%c\", *str);\n        ++i;\n      }\n    }\n  }\n}\n\n// Prints the names of the tests matching the user-specified filter flag.\nvoid UnitTestImpl::ListTestsMatchingFilter() {\n  // Print at most this many characters for each type/value parameter.\n  const int kMaxParamLength = 250;\n\n  for (auto* test_suite : test_suites_) {\n    bool printed_test_suite_name = false;\n\n    for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {\n      const TestInfo* const test_info = test_suite->test_info_list()[j];\n      if (test_info->matches_filter_) {\n        if (!printed_test_suite_name) {\n          printed_test_suite_name = true;\n          printf(\"%s.\", test_suite->name());\n          if (test_suite->type_param() != nullptr) {\n            printf(\"  # %s = \", kTypeParamLabel);\n            // We print the type parameter on a single line to make\n            // the output easy to parse by a program.\n            PrintOnOneLine(test_suite->type_param(), kMaxParamLength);\n          }\n          printf(\"\\n\");\n        }\n        printf(\"  %s\", test_info->name());\n        if (test_info->value_param() != nullptr) {\n          printf(\"  # %s = \", kValueParamLabel);\n          // We print the value parameter on a single line to make the\n          // output easy to parse by a program.\n          PrintOnOneLine(test_info->value_param(), kMaxParamLength);\n        }\n        printf(\"\\n\");\n      }\n    }\n  }\n  fflush(stdout);\n#if GTEST_HAS_FILE_SYSTEM\n  const std::string& output_format = UnitTestOptions::GetOutputFormat();\n  if (output_format == \"xml\" || output_format == \"json\") {\n    FILE* fileout =\n        OpenFileForWriting(UnitTestOptions::GetAbsolutePathToOutputFile());\n    std::stringstream stream;\n    if (output_format == \"xml\") {\n      XmlUnitTestResultPrinter(\n          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())\n          .PrintXmlTestsList(&stream, test_suites_);\n    } else if (output_format == \"json\") {\n      JsonUnitTestResultPrinter(\n          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())\n          .PrintJsonTestList(&stream, test_suites_);\n    }\n    fprintf(fileout, \"%s\", StringStreamToString(&stream).c_str());\n    fclose(fileout);\n  }\n#endif  // GTEST_HAS_FILE_SYSTEM\n}\n\n// Sets the OS stack trace getter.\n//\n// Does nothing if the input and the current OS stack trace getter are\n// the same; otherwise, deletes the old getter and makes the input the\n// current getter.\nvoid UnitTestImpl::set_os_stack_trace_getter(\n    OsStackTraceGetterInterface* getter) {\n  if (os_stack_trace_getter_ != getter) {\n    delete os_stack_trace_getter_;\n    os_stack_trace_getter_ = getter;\n  }\n}\n\n// Returns the current OS stack trace getter if it is not NULL;\n// otherwise, creates an OsStackTraceGetter, makes it the current\n// getter, and returns it.\nOsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {\n  if (os_stack_trace_getter_ == nullptr) {\n#ifdef GTEST_OS_STACK_TRACE_GETTER_\n    os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;\n#else\n    os_stack_trace_getter_ = new OsStackTraceGetter;\n#endif  // GTEST_OS_STACK_TRACE_GETTER_\n  }\n\n  return os_stack_trace_getter_;\n}\n\n// Returns the most specific TestResult currently running.\nTestResult* UnitTestImpl::current_test_result() {\n  if (current_test_info_ != nullptr) {\n    return &current_test_info_->result_;\n  }\n  if (current_test_suite_ != nullptr) {\n    return &current_test_suite_->ad_hoc_test_result_;\n  }\n  return &ad_hoc_test_result_;\n}\n\n// Shuffles all test suites, and the tests within each test suite,\n// making sure that death tests are still run first.\nvoid UnitTestImpl::ShuffleTests() {\n  // Shuffles the death test suites.\n  ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_);\n\n  // Shuffles the non-death test suites.\n  ShuffleRange(random(), last_death_test_suite_ + 1,\n               static_cast<int>(test_suites_.size()), &test_suite_indices_);\n\n  // Shuffles the tests inside each test suite.\n  for (auto& test_suite : test_suites_) {\n    test_suite->ShuffleTests(random());\n  }\n}\n\n// Restores the test suites and tests to their order before the first shuffle.\nvoid UnitTestImpl::UnshuffleTests() {\n  for (size_t i = 0; i < test_suites_.size(); i++) {\n    // Unshuffles the tests in each test suite.\n    test_suites_[i]->UnshuffleTests();\n    // Resets the index of each test suite.\n    test_suite_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nGTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string\nGetCurrentOsStackTraceExceptTop(int skip_count) {\n  // We pass skip_count + 1 to skip this wrapper function in addition\n  // to what the user really wants to skip.\n  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);\n}\n\n// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to\n// suppress unreachable code warnings.\nnamespace {\nclass ClassUniqueToAlwaysTrue {};\n}  // namespace\n\nbool IsTrue(bool condition) { return condition; }\n\nbool AlwaysTrue() {\n#if GTEST_HAS_EXCEPTIONS\n  // This condition is always false so AlwaysTrue() never actually throws,\n  // but it makes the compiler think that it may throw.\n  if (IsTrue(false)) throw ClassUniqueToAlwaysTrue();\n#endif  // GTEST_HAS_EXCEPTIONS\n  return true;\n}\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nbool SkipPrefix(const char* prefix, const char** pstr) {\n  const size_t prefix_len = strlen(prefix);\n  if (strncmp(*pstr, prefix, prefix_len) == 0) {\n    *pstr += prefix_len;\n    return true;\n  }\n  return false;\n}\n\n// Parses a string as a command line flag.  The string should have\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\n// part can be omitted.\n//\n// Returns the value of the flag, or NULL if the parsing failed.\nstatic const char* ParseFlagValue(const char* str, const char* flag_name,\n                                  bool def_optional) {\n  // str and flag must not be NULL.\n  if (str == nullptr || flag_name == nullptr) return nullptr;\n\n  // The flag must start with \"--\" followed by GTEST_FLAG_PREFIX_.\n  const std::string flag_str =\n      std::string(\"--\") + GTEST_FLAG_PREFIX_ + flag_name;\n  const size_t flag_len = flag_str.length();\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) {\n    return flag_end;\n  }\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\n// Parses a string for a bool flag, in the form of either\n// \"--flag=value\" or \"--flag\".\n//\n// In the former case, the value is taken as true as long as it does\n// not start with '0', 'f', or 'F'.\n//\n// In the latter case, the value is taken as true.\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nstatic bool ParseFlag(const char* str, const char* flag_name, bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\n  return true;\n}\n\n// Parses a string for an int32_t flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nbool ParseFlag(const char* str, const char* flag_name, int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(Message() << \"The value of flag --\" << flag_name, value_str,\n                    value);\n}\n\n// Parses a string for a string flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\ntemplate <typename String>\nstatic bool ParseFlag(const char* str, const char* flag_name, String* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  *value = value_str;\n  return true;\n}\n\n// Determines whether a string has a prefix that Google Test uses for its\n// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.\n// If Google Test detects that a command line flag has its prefix but is not\n// recognized, it will print its help message. Flags starting with\n// GTEST_INTERNAL_PREFIX_ followed by \"internal_\" are considered Google Test\n// internal flags and do not trigger the help message.\nstatic bool HasGoogleTestFlagPrefix(const char* str) {\n  return (SkipPrefix(\"--\", &str) || SkipPrefix(\"-\", &str) ||\n          SkipPrefix(\"/\", &str)) &&\n         !SkipPrefix(GTEST_FLAG_PREFIX_ \"internal_\", &str) &&\n         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||\n          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));\n}\n\n// Prints a string containing code-encoded text.  The following escape\n// sequences can be used in the string to control the text color:\n//\n//   @@    prints a single '@' character.\n//   @R    changes the color to red.\n//   @G    changes the color to green.\n//   @Y    changes the color to yellow.\n//   @D    changes to the default terminal text color.\n//\nstatic void PrintColorEncoded(const char* str) {\n  GTestColor color = GTestColor::kDefault;  // The current color.\n\n  // Conceptually, we split the string into segments divided by escape\n  // sequences.  Then we print one segment at a time.  At the end of\n  // each iteration, the str pointer advances to the beginning of the\n  // next segment.\n  for (;;) {\n    const char* p = strchr(str, '@');\n    if (p == nullptr) {\n      ColoredPrintf(color, \"%s\", str);\n      return;\n    }\n\n    ColoredPrintf(color, \"%s\", std::string(str, p).c_str());\n\n    const char ch = p[1];\n    str = p + 2;\n    if (ch == '@') {\n      ColoredPrintf(color, \"@\");\n    } else if (ch == 'D') {\n      color = GTestColor::kDefault;\n    } else if (ch == 'R') {\n      color = GTestColor::kRed;\n    } else if (ch == 'G') {\n      color = GTestColor::kGreen;\n    } else if (ch == 'Y') {\n      color = GTestColor::kYellow;\n    } else {\n      --str;\n    }\n  }\n}\n\nstatic const char kColorEncodedHelpMessage[] =\n    \"This program contains tests written using \" GTEST_NAME_\n    \". You can use the\\n\"\n    \"following command line flags to control its behavior:\\n\"\n    \"\\n\"\n    \"Test Selection:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"list_tests@D\\n\"\n    \"      List the names of all tests instead of running them. The name of\\n\"\n    \"      TEST(Foo, Bar) is \\\"Foo.Bar\\\".\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"filter=@YPOSITIVE_PATTERNS\"\n    \"[@G-@YNEGATIVE_PATTERNS]@D\\n\"\n    \"      Run only the tests whose name matches one of the positive patterns \"\n    \"but\\n\"\n    \"      none of the negative patterns. '?' matches any single character; \"\n    \"'*'\\n\"\n    \"      matches any substring; ':' separates two patterns.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"also_run_disabled_tests@D\\n\"\n    \"      Run all disabled tests too.\\n\"\n    \"\\n\"\n    \"Test Execution:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"repeat=@Y[COUNT]@D\\n\"\n    \"      Run the tests repeatedly; use a negative count to repeat forever.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"shuffle@D\\n\"\n    \"      Randomize tests' orders on every iteration.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"random_seed=@Y[NUMBER]@D\\n\"\n    \"      Random number seed to use for shuffling test orders (between 1 and\\n\"\n    \"      99999, or 0 to use a seed based on the current time).\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"recreate_environments_when_repeating@D\\n\"\n    \"      Sets up and tears down the global test environment on each repeat\\n\"\n    \"      of the test.\\n\"\n    \"\\n\"\n    \"Test Output:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\\n\"\n    \"      Enable/disable colored output. The default is @Gauto@D.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"brief=1@D\\n\"\n    \"      Only print test failures.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"print_time=0@D\\n\"\n    \"      Don't print the elapsed time of each test.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G\" GTEST_PATH_SEP_\n    \"@Y|@G:@YFILE_PATH]@D\\n\"\n    \"      Generate a JSON or XML report in the given directory or with the \"\n    \"given\\n\"\n    \"      file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\\n\"\n#if GTEST_CAN_STREAM_RESULTS_\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"stream_result_to=@YHOST@G:@YPORT@D\\n\"\n    \"      Stream test results to the given server.\\n\"\n#endif  // GTEST_CAN_STREAM_RESULTS_\n    \"\\n\"\n    \"Assertion Behavior:\\n\"\n#if defined(GTEST_HAS_DEATH_TEST) && !defined(GTEST_OS_WINDOWS)\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\\n\"\n    \"      Set the default death test style.\\n\"\n#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"break_on_failure@D\\n\"\n    \"      Turn assertion failures into debugger break-points.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"throw_on_failure@D\\n\"\n    \"      Turn assertion failures into C++ exceptions for use by an external\\n\"\n    \"      test framework.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"catch_exceptions=0@D\\n\"\n    \"      Do not report exceptions as test failures. Instead, allow them\\n\"\n    \"      to crash the program or throw a pop-up (on Windows).\\n\"\n    \"\\n\"\n    \"Except for @G--\" GTEST_FLAG_PREFIX_\n    \"list_tests@D, you can alternatively set \"\n    \"the corresponding\\n\"\n    \"environment variable of a flag (all letters in upper-case). For example, \"\n    \"to\\n\"\n    \"disable colored text output, you can either specify \"\n    \"@G--\" GTEST_FLAG_PREFIX_\n    \"color=no@D or set\\n\"\n    \"the @G\" GTEST_FLAG_PREFIX_UPPER_\n    \"COLOR@D environment variable to @Gno@D.\\n\"\n    \"\\n\"\n    \"For more information, please read the \" GTEST_NAME_\n    \" documentation at\\n\"\n    \"@G\" GTEST_PROJECT_URL_ \"@D. If you find a bug in \" GTEST_NAME_\n    \"\\n\"\n    \"(not one in your own code or tests), please report it to\\n\"\n    \"@G<\" GTEST_DEV_EMAIL_ \">@D.\\n\";\n\nstatic bool ParseGoogleTestFlag(const char* const arg) {\n#define GTEST_INTERNAL_PARSE_FLAG(flag_name)  \\\n  do {                                        \\\n    auto value = GTEST_FLAG_GET(flag_name);   \\\n    if (ParseFlag(arg, #flag_name, &value)) { \\\n      GTEST_FLAG_SET(flag_name, value);       \\\n      return true;                            \\\n    }                                         \\\n  } while (false)\n\n  GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests);\n  GTEST_INTERNAL_PARSE_FLAG(break_on_failure);\n  GTEST_INTERNAL_PARSE_FLAG(catch_exceptions);\n  GTEST_INTERNAL_PARSE_FLAG(color);\n  GTEST_INTERNAL_PARSE_FLAG(death_test_style);\n  GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);\n  GTEST_INTERNAL_PARSE_FLAG(fail_fast);\n  GTEST_INTERNAL_PARSE_FLAG(filter);\n  GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);\n  GTEST_INTERNAL_PARSE_FLAG(list_tests);\n  GTEST_INTERNAL_PARSE_FLAG(output);\n  GTEST_INTERNAL_PARSE_FLAG(brief);\n  GTEST_INTERNAL_PARSE_FLAG(print_time);\n  GTEST_INTERNAL_PARSE_FLAG(print_utf8);\n  GTEST_INTERNAL_PARSE_FLAG(random_seed);\n  GTEST_INTERNAL_PARSE_FLAG(repeat);\n  GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);\n  GTEST_INTERNAL_PARSE_FLAG(shuffle);\n  GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);\n  GTEST_INTERNAL_PARSE_FLAG(stream_result_to);\n  GTEST_INTERNAL_PARSE_FLAG(throw_on_failure);\n  return false;\n}\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\nstatic void LoadFlagsFromFile(const std::string& path) {\n  FILE* flagfile = posix::FOpen(path.c_str(), \"r\");\n  if (!flagfile) {\n    GTEST_LOG_(FATAL) << \"Unable to open file \\\"\" << GTEST_FLAG_GET(flagfile)\n                      << \"\\\"\";\n  }\n  std::string contents(ReadEntireFile(flagfile));\n  posix::FClose(flagfile);\n  std::vector<std::string> lines;\n  SplitString(contents, '\\n', &lines);\n  for (size_t i = 0; i < lines.size(); ++i) {\n    if (lines[i].empty()) continue;\n    if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;\n  }\n}\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.  The type parameter CharType can be\n// instantiated to either char or wchar_t.\ntemplate <typename CharType>\nvoid ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {\n  std::string flagfile_value;\n  for (int i = 1; i < *argc; i++) {\n    const std::string arg_string = StreamableToString(argv[i]);\n    const char* const arg = arg_string.c_str();\n\n    using internal::ParseFlag;\n\n    bool remove_flag = false;\n    if (ParseGoogleTestFlag(arg)) {\n      remove_flag = true;\n#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n    } else if (ParseFlag(arg, \"flagfile\", &flagfile_value)) {\n      GTEST_FLAG_SET(flagfile, flagfile_value);\n      LoadFlagsFromFile(flagfile_value);\n      remove_flag = true;\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n    } else if (arg_string == \"--help\" || HasGoogleTestFlagPrefix(arg)) {\n      // Both help flag and unrecognized Google Test flags (excluding\n      // internal ones) trigger help display.\n      g_help_flag = true;\n    }\n\n    if (remove_flag) {\n      // Shift the remainder of the argv list left by one.\n      for (int j = i + 1; j < *argc; ++j) {\n        argv[j - 1] = argv[j];\n      }\n\n      // Decrements the argument count.\n      (*argc)--;\n\n      // Terminate the array with nullptr.\n      argv[*argc] = nullptr;\n\n      // We also need to decrement the iterator as we just removed\n      // an element.\n      i--;\n    }\n  }\n\n  if (g_help_flag) {\n    // We print the help here instead of in RUN_ALL_TESTS(), as the\n    // latter may not be called at all if the user is using Google\n    // Test with another testing framework.\n    PrintColorEncoded(kColorEncodedHelpMessage);\n  }\n}\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test. This function updates argc and argv by removing\n// flags that are known to GoogleTest (including other user flags defined using\n// ABSL_FLAG if GoogleTest is built with GTEST_USE_ABSL). Other arguments\n// remain in place. Unrecognized flags are not reported and do not cause the\n// program to exit.\nvoid ParseGoogleTestFlagsOnly(int* argc, char** argv) {\n#ifdef GTEST_HAS_ABSL_FLAGS\n  if (*argc <= 0) return;\n\n  std::vector<char*> positional_args;\n  std::vector<absl::UnrecognizedFlag> unrecognized_flags;\n  absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags);\n  absl::flat_hash_set<absl::string_view> unrecognized;\n  for (const auto& flag : unrecognized_flags) {\n    unrecognized.insert(flag.flag_name);\n  }\n  absl::flat_hash_set<char*> positional;\n  for (const auto& arg : positional_args) {\n    positional.insert(arg);\n  }\n\n  int out_pos = 1;\n  int in_pos = 1;\n  for (; in_pos < *argc; ++in_pos) {\n    char* arg = argv[in_pos];\n    absl::string_view arg_str(arg);\n    if (absl::ConsumePrefix(&arg_str, \"--\")) {\n      // Flag-like argument. If the flag was unrecognized, keep it.\n      // If it was a GoogleTest flag, remove it.\n      if (unrecognized.contains(arg_str)) {\n        argv[out_pos++] = argv[in_pos];\n        continue;\n      }\n    }\n\n    if (arg_str.empty()) {\n      ++in_pos;\n      break;  // '--' indicates that the rest of the arguments are positional\n    }\n\n    // Probably a positional argument. If it is in fact positional, keep it.\n    // If it was a value for the flag argument, remove it.\n    if (positional.contains(arg)) {\n      argv[out_pos++] = arg;\n    }\n  }\n\n  // The rest are positional args for sure.\n  while (in_pos < *argc) {\n    argv[out_pos++] = argv[in_pos++];\n  }\n\n  *argc = out_pos;\n  argv[out_pos] = nullptr;\n#else\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n#endif\n\n  // Fix the value of *_NSGetArgc() on macOS, but if and only if\n  // *_NSGetArgv() == argv\n  // Only applicable to char** version of argv\n#ifdef GTEST_OS_MAC\n#ifndef GTEST_OS_IOS\n  if (*_NSGetArgv() == argv) {\n    *_NSGetArgc() = *argc;\n  }\n#endif\n#endif\n}\nvoid ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n}\n\n// The internal implementation of InitGoogleTest().\n//\n// The type parameter CharType can be instantiated to either char or\n// wchar_t.\ntemplate <typename CharType>\nvoid InitGoogleTestImpl(int* argc, CharType** argv) {\n  // We don't want to run the initialization code twice.\n  if (GTestIsInitialized()) return;\n\n  if (*argc <= 0) return;\n\n  g_argvs.clear();\n  for (int i = 0; i != *argc; i++) {\n    g_argvs.push_back(StreamableToString(argv[i]));\n  }\n\n#ifdef GTEST_HAS_ABSL\n  absl::InitializeSymbolizer(g_argvs[0].c_str());\n\n#ifdef GTEST_HAS_ABSL_FLAGS\n  // When using the Abseil Flags library, set the program usage message to the\n  // help message, but remove the color-encoding from the message first.\n  absl::SetProgramUsageMessage(absl::StrReplaceAll(\n      kColorEncodedHelpMessage,\n      {{\"@D\", \"\"}, {\"@R\", \"\"}, {\"@G\", \"\"}, {\"@Y\", \"\"}, {\"@@\", \"@\"}}));\n#endif  // GTEST_HAS_ABSL_FLAGS\n#endif  // GTEST_HAS_ABSL\n\n  ParseGoogleTestFlagsOnly(argc, argv);\n  GetUnitTestImpl()->PostFlagParsingInit();\n}\n\n}  // namespace internal\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nvoid InitGoogleTest(int* argc, char** argv) {\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nvoid InitGoogleTest(int* argc, wchar_t** argv) {\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nvoid InitGoogleTest() {\n  // Since Arduino doesn't have a command line, fake out the argc/argv arguments\n  int argc = 1;\n  const auto arg0 = \"dummy\";\n  char* argv0 = const_cast<char*>(arg0);\n  char** argv = &argv0;\n\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(&argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) || \\\n    !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n// Returns the value of the first environment variable that is set and contains\n// a non-empty string. If there are none, returns the \"fallback\" string. Adds\n// the director-separator character as a suffix if not provided in the\n// environment variable value.\nstatic std::string GetDirFromEnv(\n    std::initializer_list<const char*> environment_variables,\n    const char* fallback, char separator) {\n  for (const char* variable_name : environment_variables) {\n    const char* value = internal::posix::GetEnv(variable_name);\n    if (value != nullptr && value[0] != '\\0') {\n      if (value[strlen(value) - 1] != separator) {\n        return std::string(value).append(1, separator);\n      }\n      return value;\n    }\n  }\n  return fallback;\n}\n#endif\n\nstd::string TempDir() {\n#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)\n  return GTEST_CUSTOM_TEMPDIR_FUNCTION_();\n#elif defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_WINDOWS_MOBILE)\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TEMP\"}, \"\\\\temp\\\\\", '\\\\');\n#elif defined(GTEST_OS_LINUX_ANDROID)\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TMPDIR\"}, \"/data/local/tmp/\", '/');\n#else\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TMPDIR\"}, \"/tmp/\", '/');\n#endif\n}\n\n#if GTEST_HAS_FILE_SYSTEM && !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n// Returns the directory path (including terminating separator) of the current\n// executable as derived from argv[0].\nstatic std::string GetCurrentExecutableDirectory() {\n  internal::FilePath argv_0(internal::GetArgvs()[0]);\n  return argv_0.RemoveFileName().string();\n}\n#endif\n\n#if GTEST_HAS_FILE_SYSTEM\nstd::string SrcDir() {\n#if defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n  return GTEST_CUSTOM_SRCDIR_FUNCTION_();\n#elif defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_WINDOWS_MOBILE)\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '\\\\');\n#elif defined(GTEST_OS_LINUX_ANDROID)\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '/');\n#else\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '/');\n#endif\n}\n#endif\n\n// Class ScopedTrace\n\n// Pushes the given source file location and message onto a per-thread\n// trace stack maintained by Google Test.\nvoid ScopedTrace::PushTrace(const char* file, int line, std::string message) {\n  internal::TraceInfo trace;\n  trace.file = file;\n  trace.line = line;\n  trace.message.swap(message);\n\n  UnitTest::GetInstance()->PushGTestTrace(trace);\n}\n\n// Pops the info pushed by the c'tor.\nScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {\n  UnitTest::GetInstance()->PopGTestTrace();\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/core/vendor/googletest/googletest/src/gtest_main.cc",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include <cstdio>\n\n#include \"gtest/gtest.h\"\n\n#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \\\n    (defined(GTEST_OS_NRF52) && defined(ARDUINO))\n// Arduino-like platforms: program entry points are setup/loop instead of main.\n\n#ifdef GTEST_OS_ESP8266\nextern \"C\" {\n#endif\n\nvoid setup() { testing::InitGoogleTest(); }\n\nvoid loop() { RUN_ALL_TESTS(); }\n\n#ifdef GTEST_OS_ESP8266\n}\n#endif\n\n#elif defined(GTEST_OS_QURT)\n// QuRT: program entry point is main, but argc/argv are unusable.\n\nGTEST_API_ int main() {\n  printf(\"Running main() from %s\\n\", __FILE__);\n  testing::InitGoogleTest();\n  return RUN_ALL_TESTS();\n}\n#else\n// Normal platforms: program entry point is main, argc/argv are initialized.\n\nGTEST_API_ int main(int argc, char **argv) {\n  printf(\"Running main() from %s\\n\", __FILE__);\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n#endif\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/hyper-schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/core\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/applicator\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/validation\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/meta-data\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/format\": false,\n        \"https://json-schema.org/draft/2019-09/vocab/content\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/hyper-schema\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"JSON Hyper-Schema\",\n    \"allOf\": [\n        {\"$ref\": \"https://json-schema.org/draft/2019-09/schema\"},\n        {\"$ref\": \"https://json-schema.org/draft/2019-09/meta/hyper-schema\"}\n    ],\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/links.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/links\",\n    \"title\": \"Link Description Object\",\n    \"allOf\": [\n        { \"required\": [ \"rel\", \"href\" ] },\n        { \"$ref\": \"#/$defs/noRequiredFields\" }\n    ],\n    \"$defs\": {\n        \"noRequiredFields\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"anchor\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                },\n                \"anchorPointer\": {\n                    \"type\": \"string\",\n                    \"anyOf\": [\n                        { \"format\": \"json-pointer\" },\n                        { \"format\": \"relative-json-pointer\" }\n                    ]\n                },\n                \"rel\": {\n                    \"anyOf\": [\n                        { \"type\": \"string\" },\n                        {\n                            \"type\": \"array\",\n                            \"items\": { \"type\": \"string\" },\n                            \"minItems\": 1\n                        }\n                    ]\n                },\n                \"href\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                },\n                \"hrefSchema\": {\n                    \"$ref\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n                    \"default\": false\n                },\n                \"templatePointers\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\",\n                        \"anyOf\": [\n                            { \"format\": \"json-pointer\" },\n                            { \"format\": \"relative-json-pointer\" }\n                        ]\n                    }\n                },\n                \"templateRequired\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    },\n                    \"uniqueItems\": true\n                },\n                \"title\": {\n                    \"type\": \"string\"\n                },\n                \"description\": {\n                    \"type\": \"string\"\n                },\n                \"targetSchema\": {\n                    \"$ref\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n                    \"default\": true\n                },\n                \"targetMediaType\": {\n                    \"type\": \"string\"\n                },\n                \"targetHints\": { },\n                \"headerSchema\": {\n                    \"$ref\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n                    \"default\": true\n                },\n                \"submissionMediaType\": {\n                    \"type\": \"string\",\n                    \"default\": \"application/json\"\n                },\n                \"submissionSchema\": {\n                    \"$ref\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n                    \"default\": true\n                },\n                \"$comment\": {\n                    \"type\": \"string\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/applicator.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/applicator\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/applicator\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Applicator vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"additionalItems\": { \"$recursiveRef\": \"#\" },\n        \"unevaluatedItems\": { \"$recursiveRef\": \"#\" },\n        \"items\": {\n            \"anyOf\": [\n                { \"$recursiveRef\": \"#\" },\n                { \"$ref\": \"#/$defs/schemaArray\" }\n            ]\n        },\n        \"contains\": { \"$recursiveRef\": \"#\" },\n        \"additionalProperties\": { \"$recursiveRef\": \"#\" },\n        \"unevaluatedProperties\": { \"$recursiveRef\": \"#\" },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$recursiveRef\": \"#\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$recursiveRef\": \"#\" },\n            \"propertyNames\": { \"format\": \"regex\" },\n            \"default\": {}\n        },\n        \"dependentSchemas\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"$recursiveRef\": \"#\"\n            }\n        },\n        \"propertyNames\": { \"$recursiveRef\": \"#\" },\n        \"if\": { \"$recursiveRef\": \"#\" },\n        \"then\": { \"$recursiveRef\": \"#\" },\n        \"else\": { \"$recursiveRef\": \"#\" },\n        \"allOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"not\": { \"$recursiveRef\": \"#\" }\n    },\n    \"$defs\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$recursiveRef\": \"#\" }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/content.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/content\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/content\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Content vocabulary meta-schema\",\n\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"contentMediaType\": { \"type\": \"string\" },\n        \"contentEncoding\": { \"type\": \"string\" },\n        \"contentSchema\": { \"$recursiveRef\": \"#\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/core.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/core\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/core\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Core vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"$id\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\",\n            \"$comment\": \"Non-empty fragments not allowed.\",\n            \"pattern\": \"^[^#]*#?$\"\n        },\n        \"$schema\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"$anchor\": {\n            \"type\": \"string\",\n            \"pattern\": \"^[A-Za-z][-A-Za-z0-9.:_]*$\"\n        },\n        \"$ref\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"$recursiveRef\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"$recursiveAnchor\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"$vocabulary\": {\n            \"type\": \"object\",\n            \"propertyNames\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n            },\n            \"additionalProperties\": {\n                \"type\": \"boolean\"\n            }\n        },\n        \"$comment\": {\n            \"type\": \"string\"\n        },\n        \"$defs\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$recursiveRef\": \"#\" },\n            \"default\": {}\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/format.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/format\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/format\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Format vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"format\": { \"type\": \"string\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/hyper-schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/hyper-schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/hyper-schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/hyper-schema\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"JSON Hyper-Schema Vocabulary Schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"base\": {\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"links\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"$ref\": \"https://json-schema.org/draft/2019-09/links\"\n            }\n        }\n    },\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/meta-data.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/meta-data\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/meta-data\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Meta-data vocabulary meta-schema\",\n\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": true,\n        \"deprecated\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"readOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"writeOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"examples\": {\n            \"type\": \"array\",\n            \"items\": true\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/meta/validation.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/meta/validation\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/validation\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Validation vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"exclusiveMinimum\": 0\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"number\"\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"number\"\n        },\n        \"maxLength\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minLength\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"maxItems\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minItems\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxContains\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minContains\": {\n            \"$ref\": \"#/$defs/nonNegativeInteger\",\n            \"default\": 1\n        },\n        \"maxProperties\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minProperties\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/$defs/stringArray\" },\n        \"dependentRequired\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"$ref\": \"#/$defs/stringArray\"\n            }\n        },\n        \"const\": true,\n        \"enum\": {\n            \"type\": \"array\",\n            \"items\": true\n        },\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/$defs/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/$defs/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        }\n    },\n    \"$defs\": {\n        \"nonNegativeInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"nonNegativeIntegerDefault0\": {\n            \"$ref\": \"#/$defs/nonNegativeInteger\",\n            \"default\": 0\n        },\n        \"simpleTypes\": {\n            \"enum\": [\n                \"array\",\n                \"boolean\",\n                \"integer\",\n                \"null\",\n                \"number\",\n                \"object\",\n                \"string\"\n            ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"uniqueItems\": true,\n            \"default\": []\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/output/hyper-schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/output/hyper-schema\",\n    \"title\": \"JSON Hyper-Schema Output\",\n    \"type\": \"array\",\n    \"items\": {\n        \"allOf\": [\n            {\"$ref\": \"https://json-schema.org/draft/2019-09/links#/$defs/noRequiredFields\" }\n        ],\n        \"type\": \"object\",\n        \"required\": [\n            \"contextUri\",\n            \"contextPointer\",\n            \"rel\",\n            \"attachmentPointer\"\n        ],\n        \"if\": { \"required\": [ \"hrefSchema\" ] },\n        \"then\": { \"required\": [ \"hrefInputTemplates\", \"hrefPrepopulatedInput\" ] },\n        \"else\": { \"required\": [ \"targetUri\" ] },\n        \"properties\": {\n            \"contextUri\": {\n                \"$comment\": \"The fully resolved URI of the link context, including a fragment if it is possible to construct one for the given media type and instance\",\n                \"type\": \"string\",\n                \"format\": \"uri\"\n            },\n            \"contextPointer\": {\n                \"$comment\": \"The absolute JSON Pointer to the location in the instance that is the context of the link.  If the context resource supports JSON Pointer fragments, this will the string form of the identical JSON Pointer\",\n                \"type\": \"string\",\n                \"format\": \"json-pointer\"\n            },\n            \"rel\": {\n                \"type\": \"string\"\n            },\n            \"targetUri\": {\n                \"$comment\": \"The fully resolved target URI\",\n                \"type\": \"string\",\n                \"format\": \"uri\"\n            },\n            \"hrefInputTemplates\": {\n                \"$comment\": \"The list of partially resolved URI Templates, starting with \\\"href\\\", followed by applicable \\\"base\\\" values from nearest to furthest.\",\n                \"type\": \"array\",\n                \"items\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                }\n            },\n            \"hrefPrepopulatedInput\": {\n                \"$comment\": \"The initial data set to be presented with the input form when URI Template input is accepted.\",\n                \"type\": \"object\",\n                \"propertyNames\": {\n                    \"$comment\": \"These are all URI Template variable names, specifically the 'varname' production from RFC 6570, Section 2.3\",\n                    \"pattern\": \"^(?:\\\\w|(?:%[a-f\\\\d]{2}))+(?:\\\\.(?:\\\\w|(?:%[a-f\\\\d]{2})))*$\"\n                }\n            },\n            \"attachmentPointer\": {\n                \"$comment\": \"The absolute JSON Pointer, in string form, of the position to which this resolved link applies\",\n                \"type\": \"string\",\n                \"format\": \"json-pointer\"\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/output/schema.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/output/schema\",\n  \"description\": \"A schema that validates the minimum requirements for validation output\",\n\n  \"oneOf\": [\n    { \"$ref\": \"#/$defs/flag\" },\n    { \"$ref\": \"#/$defs/basic\" },\n    { \"$ref\": \"#/$defs/detailed\" },\n    { \"$ref\": \"#/$defs/verbose\" }\n  ],\n  \"$defs\": {\n    \"outputUnit\":{\n      \"properties\": {\n        \"valid\": { \"type\": \"boolean\" },\n        \"keywordLocation\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"absoluteKeywordLocation\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"instanceLocation\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"errors\": {\n          \"$ref\": \"#/$defs/outputUnitArray\"\n        },\n        \"annotations\": {\n          \"$ref\": \"#/$defs/outputUnitArray\"\n        }\n      },\n      \"required\": [ \"valid\", \"keywordLocation\", \"instanceLocation\" ],\n      \"allOf\": [\n        {\n          \"if\": {\n            \"properties\": {\n              \"valid\": { \"const\": false }\n            }\n          },\n          \"then\": {\n            \"required\": [ \"errors\" ]\n          }\n        },\n        {\n          \"if\": {\n            \"anyOf\": [\n              {\n                \"properties\": {\n                  \"keywordLocation\": {\n                    \"pattern\": \"/\\\\$ref/\"\n                  }\n                }\n              },\n              {\n                \"properties\": {\n                  \"keywordLocation\": {\n                    \"pattern\": \"/\\\\$recursiveRef/\"\n                  }\n                }\n              }\n            ]\n          },\n          \"then\": {\n            \"required\": [ \"absoluteKeywordLocation\" ]\n          }\n        }\n      ]\n    },\n    \"outputUnitArray\": {\n      \"type\": \"array\",\n      \"items\": { \"$ref\": \"#/$defs/outputUnit\" }\n    },\n    \"flag\": {\n      \"properties\": {\n        \"valid\": { \"type\": \"boolean\" }\n      },\n      \"required\": [ \"valid\" ]\n    },\n    \"basic\": { \"$ref\": \"#/$defs/outputUnit\" },\n    \"detailed\": { \"$ref\": \"#/$defs/outputUnit\" },\n    \"verbose\": { \"$ref\": \"#/$defs/outputUnit\" }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2019-09/schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$id\": \"https://json-schema.org/draft/2019-09/schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/core\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/applicator\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/validation\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/meta-data\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/format\": false,\n        \"https://json-schema.org/draft/2019-09/vocab/content\": true\n    },\n    \"$recursiveAnchor\": true,\n\n    \"title\": \"Core and Validation specifications meta-schema\",\n    \"allOf\": [\n        {\"$ref\": \"meta/core\"},\n        {\"$ref\": \"meta/applicator\"},\n        {\"$ref\": \"meta/validation\"},\n        {\"$ref\": \"meta/meta-data\"},\n        {\"$ref\": \"meta/format\"},\n        {\"$ref\": \"meta/content\"}\n    ],\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"definitions\": {\n            \"$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.\",\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$recursiveRef\": \"#\" },\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"$comment\": \"\\\"dependencies\\\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \\\"dependentSchemas\\\" and \\\"dependentRequired\\\"\",\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$recursiveRef\": \"#\" },\n                    { \"$ref\": \"meta/validation#/$defs/stringArray\" }\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/hyper-schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/hyper-schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/hyper-schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/content\": true,\n        \"https://json-schema.org/draft/2019-09/vocab/hyper-schema\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"JSON Hyper-Schema\",\n    \"allOf\": [\n        { \"$ref\": \"https://json-schema.org/draft/2020-12/schema\" },\n        { \"$ref\": \"https://json-schema.org/draft/2020-12/meta/hyper-schema\" }\n    ],\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/links.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/links\",\n    \"title\": \"Link Description Object\",\n\n    \"type\": \"object\",\n    \"properties\": {\n        \"anchor\": {\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"anchorPointer\": {\n            \"type\": \"string\",\n            \"anyOf\": [\n                { \"format\": \"json-pointer\" },\n                { \"format\": \"relative-json-pointer\" }\n            ]\n        },\n        \"rel\": {\n            \"anyOf\": [\n                { \"type\": \"string\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"type\": \"string\" },\n                    \"minItems\": 1\n                }\n            ]\n        },\n        \"href\": {\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"hrefSchema\": {\n            \"$dynamicRef\": \"https://json-schema.org/draft/2020-12/hyper-schema#meta\",\n            \"default\": false\n        },\n        \"templatePointers\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"type\": \"string\",\n                \"anyOf\": [\n                    { \"format\": \"json-pointer\" },\n                    { \"format\": \"relative-json-pointer\" }\n                ]\n            }\n        },\n        \"templateRequired\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"string\"\n            },\n            \"uniqueItems\": true\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"targetSchema\": {\n            \"$dynamicRef\": \"https://json-schema.org/draft/2020-12/hyper-schema#meta\",\n            \"default\": true\n        },\n        \"targetMediaType\": {\n            \"type\": \"string\"\n        },\n        \"targetHints\": {},\n        \"headerSchema\": {\n            \"$dynamicRef\": \"https://json-schema.org/draft/2020-12/hyper-schema#meta\",\n            \"default\": true\n        },\n        \"submissionMediaType\": {\n            \"type\": \"string\",\n            \"default\": \"application/json\"\n        },\n        \"submissionSchema\": {\n            \"$dynamicRef\": \"https://json-schema.org/draft/2020-12/hyper-schema#meta\",\n            \"default\": true\n        },\n        \"$comment\": {\n            \"type\": \"string\"\n        }\n    },\n    \"required\": [ \"rel\", \"href\" ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/applicator.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/applicator\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/applicator\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Applicator vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"prefixItems\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"items\": { \"$dynamicRef\": \"#meta\" },\n        \"contains\": { \"$dynamicRef\": \"#meta\" },\n        \"additionalProperties\": { \"$dynamicRef\": \"#meta\" },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$dynamicRef\": \"#meta\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$dynamicRef\": \"#meta\" },\n            \"propertyNames\": { \"format\": \"regex\" },\n            \"default\": {}\n        },\n        \"dependentSchemas\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$dynamicRef\": \"#meta\" },\n            \"default\": {}\n        },\n        \"propertyNames\": { \"$dynamicRef\": \"#meta\" },\n        \"if\": { \"$dynamicRef\": \"#meta\" },\n        \"then\": { \"$dynamicRef\": \"#meta\" },\n        \"else\": { \"$dynamicRef\": \"#meta\" },\n        \"allOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/$defs/schemaArray\" },\n        \"not\": { \"$dynamicRef\": \"#meta\" }\n    },\n    \"$defs\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$dynamicRef\": \"#meta\" }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/content.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/content\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/content\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Content vocabulary meta-schema\",\n\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"contentEncoding\": { \"type\": \"string\" },\n        \"contentMediaType\": { \"type\": \"string\" },\n        \"contentSchema\": { \"$dynamicRef\": \"#meta\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/core.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/core\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/core\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Core vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"$id\": {\n            \"$ref\": \"#/$defs/uriReferenceString\",\n            \"$comment\": \"Non-empty fragments not allowed.\",\n            \"pattern\": \"^[^#]*#?$\"\n        },\n        \"$schema\": { \"$ref\": \"#/$defs/uriString\" },\n        \"$ref\": { \"$ref\": \"#/$defs/uriReferenceString\" },\n        \"$anchor\": { \"$ref\": \"#/$defs/anchorString\" },\n        \"$dynamicRef\": { \"$ref\": \"#/$defs/uriReferenceString\" },\n        \"$dynamicAnchor\": { \"$ref\": \"#/$defs/anchorString\" },\n        \"$vocabulary\": {\n            \"type\": \"object\",\n            \"propertyNames\": { \"$ref\": \"#/$defs/uriString\" },\n            \"additionalProperties\": {\n                \"type\": \"boolean\"\n            }\n        },\n        \"$comment\": {\n            \"type\": \"string\"\n        },\n        \"$defs\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$dynamicRef\": \"#meta\" }\n        }\n    },\n    \"$defs\": {\n        \"anchorString\": {\n            \"type\": \"string\",\n            \"pattern\": \"^[A-Za-z_][-A-Za-z0-9._]*$\"\n        },\n        \"uriString\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"uriReferenceString\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/format-annotation.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/format-annotation\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Format vocabulary meta-schema for annotation results\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"format\": { \"type\": \"string\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/format-assertion.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/format-assertion\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/format-assertion\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Format vocabulary meta-schema for assertion results\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"format\": { \"type\": \"string\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/hyper-schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/hyper-schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/hyper-schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2019-09/vocab/hyper-schema\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"JSON Hyper-Schema Vocabulary Schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"base\": {\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"links\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"$ref\": \"https://json-schema.org/draft/2020-12/links\"\n            }\n        }\n    },\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/meta-data.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/meta-data\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Meta-data vocabulary meta-schema\",\n\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": true,\n        \"deprecated\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"readOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"writeOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"examples\": {\n            \"type\": \"array\",\n            \"items\": true\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/unevaluated.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/unevaluated\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Unevaluated applicator vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"unevaluatedItems\": { \"$dynamicRef\": \"#meta\" },\n        \"unevaluatedProperties\": { \"$dynamicRef\": \"#meta\" }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/meta/validation.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/meta/validation\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/validation\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Validation vocabulary meta-schema\",\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/$defs/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/$defs/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        },\n        \"const\": true,\n        \"enum\": {\n            \"type\": \"array\",\n            \"items\": true\n        },\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"exclusiveMinimum\": 0\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"number\"\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"number\"\n        },\n        \"maxLength\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minLength\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"maxItems\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minItems\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxContains\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minContains\": {\n            \"$ref\": \"#/$defs/nonNegativeInteger\",\n            \"default\": 1\n        },\n        \"maxProperties\": { \"$ref\": \"#/$defs/nonNegativeInteger\" },\n        \"minProperties\": { \"$ref\": \"#/$defs/nonNegativeIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/$defs/stringArray\" },\n        \"dependentRequired\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"$ref\": \"#/$defs/stringArray\"\n            }\n        }\n    },\n    \"$defs\": {\n        \"nonNegativeInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"nonNegativeIntegerDefault0\": {\n            \"$ref\": \"#/$defs/nonNegativeInteger\",\n            \"default\": 0\n        },\n        \"simpleTypes\": {\n            \"enum\": [\n                \"array\",\n                \"boolean\",\n                \"integer\",\n                \"null\",\n                \"number\",\n                \"object\",\n                \"string\"\n            ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"uniqueItems\": true,\n            \"default\": []\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/output/schema.json",
    "content": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/output/schema\",\n  \"description\": \"A schema that validates the minimum requirements for validation output\",\n\n  \"anyOf\": [\n    { \"$ref\": \"#/$defs/flag\" },\n    { \"$ref\": \"#/$defs/basic\" },\n    { \"$ref\": \"#/$defs/detailed\" },\n    { \"$ref\": \"#/$defs/verbose\" }\n  ],\n  \"$defs\": {\n    \"outputUnit\":{\n      \"properties\": {\n        \"valid\": { \"type\": \"boolean\" },\n        \"keywordLocation\": {\n          \"type\": \"string\",\n          \"format\": \"json-pointer\"\n        },\n        \"absoluteKeywordLocation\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"instanceLocation\": {\n          \"type\": \"string\",\n          \"format\": \"json-pointer\"\n        },\n        \"error\": {\n          \"type\": \"string\"\n        },\n        \"errors\": {\n          \"$ref\": \"#/$defs/outputUnitArray\"\n        },\n        \"annotations\": {\n          \"$ref\": \"#/$defs/outputUnitArray\"\n        }\n      },\n      \"required\": [ \"valid\", \"keywordLocation\", \"instanceLocation\" ],\n      \"allOf\": [\n        {\n          \"if\": {\n            \"properties\": {\n              \"valid\": { \"const\": false }\n            }\n          },\n          \"then\": {\n            \"anyOf\": [\n              {\n                \"required\": [ \"error\" ]\n              },\n              {\n                \"required\": [ \"errors\" ]\n              }\n            ]\n          }\n        },\n        {\n          \"if\": {\n            \"anyOf\": [\n              {\n                \"properties\": {\n                  \"keywordLocation\": {\n                    \"pattern\": \"/\\\\$ref/\"\n                  }\n                }\n              },\n              {\n                \"properties\": {\n                  \"keywordLocation\": {\n                    \"pattern\": \"/\\\\$dynamicRef/\"\n                  }\n                }\n              }\n            ]\n          },\n          \"then\": {\n            \"required\": [ \"absoluteKeywordLocation\" ]\n          }\n        }\n      ]\n    },\n    \"outputUnitArray\": {\n      \"type\": \"array\",\n      \"items\": { \"$ref\": \"#/$defs/outputUnit\" }\n    },\n    \"flag\": {\n      \"properties\": {\n        \"valid\": { \"type\": \"boolean\" }\n      },\n      \"required\": [ \"valid\" ]\n    },\n    \"basic\": { \"$ref\": \"#/$defs/outputUnit\" },\n    \"detailed\": { \"$ref\": \"#/$defs/outputUnit\" },\n    \"verbose\": { \"$ref\": \"#/$defs/outputUnit\" }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-2020-12/schema.json",
    "content": "{\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$id\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/content\": true\n    },\n    \"$dynamicAnchor\": \"meta\",\n\n    \"title\": \"Core and Validation specifications meta-schema\",\n    \"allOf\": [\n        {\"$ref\": \"meta/core\"},\n        {\"$ref\": \"meta/applicator\"},\n        {\"$ref\": \"meta/unevaluated\"},\n        {\"$ref\": \"meta/validation\"},\n        {\"$ref\": \"meta/meta-data\"},\n        {\"$ref\": \"meta/format-annotation\"},\n        {\"$ref\": \"meta/content\"}\n    ],\n    \"type\": [\"object\", \"boolean\"],\n    \"$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.\",\n    \"properties\": {\n        \"definitions\": {\n            \"$comment\": \"\\\"definitions\\\" has been replaced by \\\"$defs\\\".\",\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$dynamicRef\": \"#meta\" },\n            \"deprecated\": true,\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"$comment\": \"\\\"dependencies\\\" has been split and replaced by \\\"dependentSchemas\\\" and \\\"dependentRequired\\\" in order to serve their differing semantics.\",\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$dynamicRef\": \"#meta\" },\n                    { \"$ref\": \"meta/validation#/$defs/stringArray\" }\n                ]\n            },\n            \"deprecated\": true,\n            \"default\": {}\n        },\n        \"$recursiveAnchor\": {\n            \"$comment\": \"\\\"$recursiveAnchor\\\" has been replaced by \\\"$dynamicAnchor\\\".\",\n            \"$ref\": \"meta/core#/$defs/anchorString\",\n            \"deprecated\": true\n        },\n        \"$recursiveRef\": {\n            \"$comment\": \"\\\"$recursiveRef\\\" has been replaced by \\\"$dynamicRef\\\".\",\n            \"$ref\": \"meta/core#/$defs/uriReferenceString\",\n            \"deprecated\": true\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft0/hyper-schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-00/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-00/hyper-schema#\",\n\n\t\"properties\" : {\n\t\t\"links\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"http://json-schema.org/draft-00/links#\"},\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"fragmentResolution\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : \"dot-delimited\"\n\t\t},\n\t\t\n\t\t\"root\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"readonly\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"pathStart\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"mediaType\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"media-type\"\n\t\t},\n\t\t\n\t\t\"alternate\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\",\n\t\"extends\" : {\"$ref\" : \"http://json-schema.org/draft-00/schema#\"}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft0/json-ref.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-00/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-00/json-ref#\",\n\t\n\t\"items\" : {\"$ref\" : \"#\"},\n\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\"\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft0/links.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-00/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-00/links#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"href\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"rel\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"method\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"GET\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enctype\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"requires\" : \"method\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"http://json-schema.org/draft-00/hyper-schema#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft0/schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-00/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-00/schema#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"type\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\n\t\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}]\n\t\t\t},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : \"any\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"items\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"optional\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"additionalProperties\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"boolean\"],\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"requires\" : {\n\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}],\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"maximum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"minimum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"maximumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"maximum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"minItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"pattern\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"regex\"\n\t\t},\n\t\t\n\t\t\"minLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enum\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minItems\" : 1\n\t\t},\n\t\t\n\t\t\"title\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"description\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"format\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"contentEncoding\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"default\" : {\n\t\t\t\"type\" : \"any\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"maxDecimal\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"disallow\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\"type\" : \"string\"},\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"extends\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t}\n\t},\n\t\n\t\"optional\" : true,\n\t\"default\" : {}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft1/hyper-schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-01/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-01/hyper-schema#\",\n\n\t\"properties\" : {\n\t\t\"links\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"http://json-schema.org/draft-01/links#\"},\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"fragmentResolution\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : \"dot-delimited\"\n\t\t},\n\t\t\n\t\t\"root\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"readonly\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"pathStart\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"mediaType\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"media-type\"\n\t\t},\n\t\t\n\t\t\"alternate\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\",\n\t\"extends\" : {\"$ref\" : \"http://json-schema.org/draft-01/schema#\"}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft1/json-ref.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-01/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-01/json-ref#\",\n\t\n\t\"items\" : {\"$ref\" : \"#\"},\n\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\"\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft1/links.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-01/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-01/links#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"href\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"rel\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"method\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"GET\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enctype\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"requires\" : \"method\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"http://json-schema.org/draft-01/hyper-schema#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft1/schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-01/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-01/schema#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"type\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\n\t\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}]\n\t\t\t},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : \"any\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"items\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"optional\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"additionalProperties\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"boolean\"],\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"requires\" : {\n\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}],\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"maximum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"minimum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"maximumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"maximum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"minItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"pattern\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"regex\"\n\t\t},\n\t\t\n\t\t\"minLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enum\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minItems\" : 1\n\t\t},\n\t\t\n\t\t\"title\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"description\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"format\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"contentEncoding\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"default\" : {\n\t\t\t\"type\" : \"any\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"maxDecimal\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"disallow\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\"type\" : \"string\"},\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"extends\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t}\n\t},\n\t\n\t\"optional\" : true,\n\t\"default\" : {}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft2/hyper-schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-02/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-02/hyper-schema#\",\n\n\t\"properties\" : {\n\t\t\"links\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"http://json-schema.org/draft-02/links#\"},\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"fragmentResolution\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : \"slash-delimited\"\n\t\t},\n\t\t\n\t\t\"root\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"readonly\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"pathStart\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"mediaType\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"media-type\"\n\t\t},\n\t\t\n\t\t\"alternate\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"slash-delimited\",\n\t\"extends\" : {\"$ref\" : \"http://json-schema.org/draft-02/schema#\"}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft2/json-ref.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-02/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-02/json-ref#\",\n\t\n\t\"items\" : {\"$ref\" : \"#\"},\n\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\"\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft2/links.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-02/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-02/links#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"href\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"rel\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"targetSchema\" : {\"$ref\" : \"http://json-schema.org/draft-02/hyper-schema#\"},\n\t\t\n\t\t\"method\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"GET\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enctype\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"requires\" : \"method\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"http://json-schema.org/draft-02/hyper-schema#\"},\n\t\t\t\"optional\" : true\n\t\t}\n\t}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft2/schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-02/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-02/schema#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"type\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\n\t\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}]\n\t\t\t},\n\t\t\t\"optional\" : true,\n\t\t\t\"uniqueItems\" : true,\n\t\t\t\"default\" : \"any\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"items\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"optional\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"additionalProperties\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"boolean\"],\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"requires\" : {\n\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}],\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"maximum\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"minimumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"minimum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"maximumCanEqual\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"requires\" : \"maximum\",\n\t\t\t\"default\" : true\n\t\t},\n\t\t\n\t\t\"minItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"uniqueItems\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"pattern\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true,\n\t\t\t\"format\" : \"regex\"\n\t\t},\n\t\t\n\t\t\"minLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"enum\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"optional\" : true,\n\t\t\t\"minItems\" : 1,\n\t\t\t\"uniqueItems\" : true\n\t\t},\n\t\t\n\t\t\"title\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"description\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"format\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"contentEncoding\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"default\" : {\n\t\t\t\"type\" : \"any\",\n\t\t\t\"optional\" : true\n\t\t},\n\t\t\n\t\t\"divisibleBy\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"minimum\" : 0,\n\t\t\t\"minimumCanEqual\" : false,\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : 1\n\t\t},\n\t\t\n\t\t\"disallow\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\"type\" : \"string\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"uniqueItems\" : true\n\t\t},\n\t\t\n\t\t\"extends\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"optional\" : true,\n\t\t\t\"default\" : {}\n\t\t}\n\t},\n\t\n\t\"optional\" : true,\n\t\"default\" : {}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft3/hyper-schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-03/hyper-schema#\",\n\t\"extends\" : {\"$ref\" : \"http://json-schema.org/draft-03/schema#\"},\n\t\"id\" : \"http://json-schema.org/draft-03/hyper-schema#\",\n\n\t\"properties\" : {\n\t\t\"links\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"items\" : {\"$ref\" : \"http://json-schema.org/draft-03/links#\"}\n\t\t},\n\t\t\n\t\t\"fragmentResolution\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"slash-delimited\"\n\t\t},\n\t\t\n\t\t\"root\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"readonly\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"contentEncoding\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"pathStart\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"mediaType\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"media-type\"\n\t\t}\n\t},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"slash-delimited\"\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft3/json-ref.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-03/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-03/json-ref#\",\n\t\n\t\"additionalItems\" : {\"$ref\" : \"#\"},\n\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\n\t\"links\" : [\n\t\t{\n\t\t\t\"href\" : \"{id}\",\n\t\t\t\"rel\" : \"self\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$ref}\",\n\t\t\t\"rel\" : \"full\"\n\t\t},\n\t\t\n\t\t{\n\t\t\t\"href\" : \"{$schema}\",\n\t\t\t\"rel\" : \"describedby\"\n\t\t}\n\t],\n\t\n\t\"fragmentResolution\" : \"dot-delimited\"\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft3/links.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-03/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-03/links#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"href\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"required\" : true,\n\t\t\t\"format\" : \"link-description-object-template\"\n\t\t},\n\t\t\n\t\t\"rel\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"required\" : true\n\t\t},\n\t\t\n\t\t\"targetSchema\" : {\"$ref\" : \"http://json-schema.org/draft-03/hyper-schema#\"},\n\t\t\n\t\t\"method\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"GET\"\n\t\t},\n\t\t\n\t\t\"enctype\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"requires\" : \"method\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"http://json-schema.org/draft-03/hyper-schema#\"}\n\t\t}\n\t}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft3/schema.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-03/schema#\",\n\t\"id\" : \"http://json-schema.org/draft-03/schema#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"type\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\n\t\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}]\n\t\t\t},\n\t\t\t\"uniqueItems\" : true,\n\t\t\t\"default\" : \"any\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"patternProperties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"#\"},\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"additionalProperties\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"boolean\"],\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"items\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"additionalItems\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"boolean\"],\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"required\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"dependencies\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\n\t\t\t\t\"type\" : [\"string\", \"array\", {\"$ref\" : \"#\"}],\n\t\t\t\t\"items\" : {\n\t\t\t\t\t\"type\" : \"string\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"minimum\" : {\n\t\t\t\"type\" : \"number\"\n\t\t},\n\t\t\n\t\t\"maximum\" : {\n\t\t\t\"type\" : \"number\"\n\t\t},\n\t\t\n\t\t\"exclusiveMinimum\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"exclusiveMaximum\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"minItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxItems\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"minimum\" : 0\n\t\t},\n\t\t\n\t\t\"uniqueItems\" : {\n\t\t\t\"type\" : \"boolean\",\n\t\t\t\"default\" : false\n\t\t},\n\t\t\n\t\t\"pattern\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"regex\"\n\t\t},\n\t\t\n\t\t\"minLength\" : {\n\t\t\t\"type\" : \"integer\",\n\t\t\t\"minimum\" : 0,\n\t\t\t\"default\" : 0\n\t\t},\n\t\t\n\t\t\"maxLength\" : {\n\t\t\t\"type\" : \"integer\"\n\t\t},\n\t\t\n\t\t\"enum\" : {\n\t\t\t\"type\" : \"array\",\n\t\t\t\"minItems\" : 1,\n\t\t\t\"uniqueItems\" : true\n\t\t},\n\t\t\n\t\t\"default\" : {\n\t\t\t\"type\" : \"any\"\n\t\t},\n\t\t\n\t\t\"title\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"description\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"format\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"divisibleBy\" : {\n\t\t\t\"type\" : \"number\",\n\t\t\t\"minimum\" : 0,\n\t\t\t\"exclusiveMinimum\" : true,\n\t\t\t\"default\" : 1\n\t\t},\n\t\t\n\t\t\"disallow\" : {\n\t\t\t\"type\" : [\"string\", \"array\"],\n\t\t\t\"items\" : {\n\t\t\t\t\"type\" : [\"string\", {\"$ref\" : \"#\"}]\n\t\t\t},\n\t\t\t\"uniqueItems\" : true\n\t\t},\n\t\t\n\t\t\"extends\" : {\n\t\t\t\"type\" : [{\"$ref\" : \"#\"}, \"array\"],\n\t\t\t\"items\" : {\"$ref\" : \"#\"},\n\t\t\t\"default\" : {}\n\t\t},\n\t\t\n\t\t\"id\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"$ref\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"uri\"\n\t\t},\n\t\t\n\t\t\"$schema\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"format\" : \"uri\"\n\t\t}\n\t},\n\t\n\t\"dependencies\" : {\n\t\t\"exclusiveMinimum\" : \"minimum\",\n\t\t\"exclusiveMaximum\" : \"maximum\"\n\t},\n\t\n\t\"default\" : {}\n}"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft4/hyper-schema.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-04/hyper-schema#\",\n    \"id\": \"http://json-schema.org/draft-04/hyper-schema#\",\n    \"title\": \"JSON Hyper-Schema\",\n    \"allOf\": [\n        {\"$ref\": \"http://json-schema.org/draft-04/schema#\"}\n    ],\n    \"properties\": {\n        \"additionalItems\": {\n            \"anyOf\": [\n                {\"type\": \"boolean\"},\n                {\"$ref\": \"#\"}\n            ]\n        },\n        \"additionalProperties\": {\n            \"anyOf\": [\n                {\"type\": \"boolean\"},\n                {\"$ref\": \"#\"}\n            ]\n        },\n        \"dependencies\": {\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    {\"$ref\": \"#\"},\n                    {\"type\": \"array\"}\n                ]\n            }\n        },\n        \"items\": {\n            \"anyOf\": [\n                {\"$ref\": \"#\"},\n                {\"$ref\": \"#/definitions/schemaArray\"}\n            ]\n        },\n        \"definitions\": {\n            \"additionalProperties\": {\"$ref\": \"#\"}\n        },\n        \"patternProperties\": {\n            \"additionalProperties\": {\"$ref\": \"#\"}\n        },\n        \"properties\": {\n            \"additionalProperties\": {\"$ref\": \"#\"}\n        },\n        \"allOf\": {\"$ref\": \"#/definitions/schemaArray\"},\n        \"anyOf\": {\"$ref\": \"#/definitions/schemaArray\"},\n        \"oneOf\": {\"$ref\": \"#/definitions/schemaArray\"},\n        \"not\": { \"$ref\": \"#\" },\n\n        \"links\": {\n            \"type\": \"array\",\n            \"items\": {\"$ref\": \"#/definitions/linkDescription\"}\n        },\n        \"fragmentResolution\": {\n            \"type\": \"string\"\n        },\n        \"media\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"type\": {\n                    \"description\": \"A media type, as described in RFC 2046\",\n                    \"type\": \"string\"\n                },\n                \"binaryEncoding\": {\n                    \"description\": \"A content encoding scheme, as described in RFC 2045\",\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"pathStart\": {\n            \"description\": \"Instances' URIs must start with this value for this schema to apply to them\",\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        }\n    },\n    \"definitions\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"items\": {\"$ref\": \"#\"}\n        },\n        \"linkDescription\": {\n            \"title\": \"Link Description Object\",\n            \"type\": \"object\",\n            \"required\": [\"href\", \"rel\"],\n            \"properties\": {\n                \"href\": {\n                    \"description\": \"a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing\",\n                    \"type\": \"string\"\n                },\n                \"rel\": {\n                    \"description\": \"relation to the target resource of the link\",\n                    \"type\": \"string\"\n                },\n                \"title\": {\n                    \"description\": \"a title for the link\",\n                    \"type\": \"string\"\n                },\n                \"targetSchema\": {\n                    \"description\": \"JSON Schema describing the link target\",\n                    \"$ref\": \"#\"\n                },\n                \"mediaType\": {\n                    \"description\": \"media type (as defined by RFC 2046) describing the link target\",\n                    \"type\": \"string\"\n                },\n                \"method\": {\n                    \"description\": \"method for requesting the target of the link (e.g. for HTTP this might be \\\"GET\\\" or \\\"DELETE\\\")\",\n                    \"type\": \"string\"\n                },\n                \"encType\": {\n                    \"description\": \"The media type in which to submit data along with the request\",\n                    \"type\": \"string\",\n                    \"default\": \"application/json\"\n                },\n                \"schema\": {\n                    \"description\": \"Schema describing the data to submit along with the request\",\n                    \"$ref\": \"#\"\n                }\n            }\n        },\n        \"readOnly\": {\n            \"description\": \"If true, indicates that the value of this property is controlled by the server.\",\n            \"type\": \"boolean\",\n            \"default\": false\n        }\n    },\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+id}\"\n        },\n        {\n            \"rel\": \"full\",\n            \"href\": \"{+($ref)}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft4/links.json",
    "content": "{\n\t\"$schema\" : \"http://json-schema.org/draft-04/hyper-schema#\",\n\t\"id\" : \"http://json-schema.org/draft-04/links#\",\n\t\"type\" : \"object\",\n\t\n\t\"properties\" : {\n\t\t\"rel\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\n\t\t\"href\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\n\t\t\"template\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"targetSchema\" : {\"$ref\" : \"http://json-schema.org/draft-04/hyper-schema#\"},\n\t\t\n\t\t\"method\" : {\n\t\t\t\"type\" : \"string\",\n\t\t\t\"default\" : \"GET\"\n\t\t},\n\t\t\n\t\t\"enctype\" : {\n\t\t\t\"type\" : \"string\"\n\t\t},\n\t\t\n\t\t\"properties\" : {\n\t\t\t\"type\" : \"object\",\n\t\t\t\"additionalProperties\" : {\"$ref\" : \"http://json-schema.org/draft-04/hyper-schema#\"}\n\t\t}\n\t},\n\t\n\t\"required\" : [\"rel\", \"href\"],\n\t\n\t\"dependencies\" : {\n\t\t\"enctype\" : [\"method\"]\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft4/schema.json",
    "content": "{\n    \"id\": \"http://json-schema.org/draft-04/schema#\",\n    \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n    \"description\": \"Core schema meta-schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$ref\": \"#\" }\n        },\n        \"positiveInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"positiveIntegerDefault0\": {\n            \"allOf\": [ { \"$ref\": \"#/definitions/positiveInteger\" }, { \"default\": 0 } ]\n        },\n        \"simpleTypes\": {\n            \"enum\": [ \"array\", \"boolean\", \"integer\", \"null\", \"number\", \"object\", \"string\" ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        }\n    },\n    \"type\": \"object\",\n    \"properties\": {\n        \"id\": {\n            \"type\": \"string\"\n        },\n        \"$schema\": {\n            \"type\": \"string\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": {},\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"minimum\": 0,\n            \"exclusiveMinimum\": true\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxLength\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minLength\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"additionalItems\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ],\n            \"default\": {}\n        },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ],\n            \"default\": {}\n        },\n        \"maxItems\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minItems\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxProperties\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minProperties\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/definitions/stringArray\" },\n        \"additionalProperties\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ],\n            \"default\": {}\n        },\n        \"definitions\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"$ref\": \"#/definitions/stringArray\" }\n                ]\n            }\n        },\n        \"enum\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        },\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/definitions/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/definitions/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        },\n        \"format\": { \"type\": \"string\" },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" }\n    },\n    \"dependencies\": {\n        \"exclusiveMaximum\": [ \"maximum\" ],\n        \"exclusiveMinimum\": [ \"minimum\" ]\n    },\n    \"default\": {}\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft6/hyper-schema.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-06/hyper-schema#\",\n    \"$id\": \"http://json-schema.org/draft-06/hyper-schema#\",\n    \"title\": \"JSON Hyper-Schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"allOf\": [\n                { \"$ref\": \"http://json-schema.org/draft-06/schema#/definitions/schemaArray\" },\n                {\n                    \"items\": { \"$ref\": \"#\" }\n                }\n            ]\n        },\n        \"linkDescription\": {\n            \"title\": \"Link Description Object\",\n            \"type\": \"object\",\n            \"required\": [ \"href\" ],\n            \"properties\": {\n                \"href\": {\n                    \"description\": \"a URI template, as defined by RFC 6570\",\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                },\n                \"hrefSchema\": {\n                    \"description\": \"a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \\\"href\\\"\",\n                    \"allOf\": [ {\"$ref\": \"#\"} ]\n                },\n                \"rel\": {\n                    \"description\": \"relation to the target resource of the link\",\n                    \"type\": \"string\"\n                },\n                \"title\": {\n                    \"description\": \"a title for the link\",\n                    \"type\": \"string\"\n                },\n                \"targetSchema\": {\n                    \"description\": \"JSON Schema describing the link target\",\n                    \"allOf\": [ { \"$ref\": \"#\" } ]\n                },\n                \"mediaType\": {\n                    \"description\": \"media type (as defined by RFC 2046) describing the link target\",\n                    \"type\": \"string\"\n                },\n                \"submissionEncType\": {\n                    \"description\": \"The media type in which to submit data along with the request\",\n                    \"type\": \"string\",\n                    \"default\": \"application/json\"\n                },\n                \"submissionSchema\": {\n                    \"description\": \"Schema describing the data to submit along with the request\",\n                    \"allOf\": [ { \"$ref\": \"#\" } ]\n                }\n            }\n        }\n    },\n    \"allOf\": [ { \"$ref\": \"http://json-schema.org/draft-06/schema#\" } ],\n    \"properties\": {\n        \"additionalItems\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ]\n        },\n        \"additionalProperties\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ]\n        },\n        \"dependencies\": {\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"type\": \"array\" }\n                ]\n            }\n        },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ]\n        },\n        \"definitions\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"patternProperties\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"properties\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" },\n\n        \"contains\": { \"$ref\": \"#\" },\n        \"propertyNames\": { \"$ref\": \"#\" },\n        \"base\": {\n            \"description\": \"URI Template resolved as for the 'href' keyword in the Link Description Object.  The resulting URI Reference is resolved against the current URI base and sets the new URI base for URI references within the instance.\",\n            \"type\": \"string\"\n        },\n        \"links\": {\n            \"type\": \"array\",\n            \"items\": { \"$ref\": \"#/definitions/linkDescription\" }\n        },\n        \"media\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"type\": {\n                    \"description\": \"A media type, as described in RFC 2046\",\n                    \"type\": \"string\"\n                },\n                \"binaryEncoding\": {\n                    \"description\": \"A content encoding scheme, as described in RFC 2045\",\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"readOnly\": {\n            \"description\": \"If true, indicates that the value of this property is controlled by the server.\",\n            \"type\": \"boolean\",\n            \"default\": false\n        }\n    },\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft6/links.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-06/hyper-schema#\",\n    \"$id\": \"http://json-schema.org/draft-06/links#\",\n    \"title\": \"Link Description Object\",\n    \"type\": \"object\",\n    \"required\": [ \"href\" ],\n    \"properties\": {\n        \"href\": {\n            \"description\": \"a URI template, as defined by RFC 6570\",\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"hrefSchema\": {\n            \"description\": \"a schema for validating user input to the URI template, where the input is in the form of a JSON object with property names matching variable names in \\\"href\\\"\",\n            \"allOf\": [ {\"$ref\": \"#\"} ]\n        },\n        \"rel\": {\n            \"description\": \"relation to the target resource of the link\",\n            \"type\": \"string\"\n        },\n        \"title\": {\n            \"description\": \"a title for the link\",\n            \"type\": \"string\"\n        },\n        \"targetSchema\": {\n            \"description\": \"JSON Schema describing the link target\",\n            \"allOf\": [ { \"$ref\": \"hyper-schema#\" } ]\n        },\n        \"mediaType\": {\n            \"description\": \"media type (as defined by RFC 2046) describing the link target\",\n            \"type\": \"string\"\n        },\n        \"submissionEncType\": {\n            \"description\": \"The media type in which to submit data along with the request\",\n            \"type\": \"string\",\n            \"default\": \"application/json\"\n        },\n        \"submissionSchema\": {\n            \"description\": \"Schema describing the data to submit along with the request\",\n            \"allOf\": [ { \"$ref\": \"hyper-schema#\" } ]\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft6/schema.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-06/schema#\",\n    \"$id\": \"http://json-schema.org/draft-06/schema#\",\n    \"title\": \"Core schema meta-schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$ref\": \"#\" }\n        },\n        \"nonNegativeInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"nonNegativeIntegerDefault0\": {\n            \"allOf\": [\n                { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n                { \"default\": 0 }\n            ]\n        },\n        \"simpleTypes\": {\n            \"enum\": [\n                \"array\",\n                \"boolean\",\n                \"integer\",\n                \"null\",\n                \"number\",\n                \"object\",\n                \"string\"\n            ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"uniqueItems\": true,\n            \"default\": []\n        }\n    },\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"$id\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"$schema\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"$ref\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": {},\n        \"examples\": {\n            \"type\": \"array\",\n            \"items\": {}\n        },\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"exclusiveMinimum\": 0\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"number\"\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"number\"\n        },\n        \"maxLength\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minLength\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"additionalItems\": { \"$ref\": \"#\" },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ],\n            \"default\": {}\n        },\n        \"maxItems\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minItems\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"contains\": { \"$ref\": \"#\" },\n        \"maxProperties\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minProperties\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/definitions/stringArray\" },\n        \"additionalProperties\": { \"$ref\": \"#\" },\n        \"definitions\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"propertyNames\": { \"format\": \"regex\" },\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"$ref\": \"#/definitions/stringArray\" }\n                ]\n            }\n        },\n        \"propertyNames\": { \"$ref\": \"#\" },\n        \"const\": {},\n        \"enum\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        },\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/definitions/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/definitions/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        },\n        \"format\": { \"type\": \"string\" },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" }\n    },\n    \"default\": {}\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft7/hyper-schema-output.json",
    "content": "{\n    \"$id\": \"http://json-schema.org/draft-07/hyper-schema-output\",\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"type\": \"array\",\n    \"items\": {\n        \"allOf\": [\n            {\"$ref\": \"http://json-schema.org/draft-07/links#/definitions/noRequiredFields\" }\n        ],\n        \"type\": \"object\",\n        \"required\": [\n            \"contextUri\",\n            \"contextPointer\",\n            \"rel\",\n            \"attachmentPointer\"\n        ],\n        \"if\": { \"required\": [ \"hrefSchema\" ] },\n        \"then\": { \"required\": [ \"hrefInputTemplates\", \"hrefPrepopulatedInput\" ] },\n        \"else\": { \"required\": [ \"targetUri\" ] },\n        \"properties\": {\n            \"contextUri\": {\n                \"$comment\": \"The fully resolved URI of the link context, including a fragment if it is possible to construct one for the given media type and instance\",\n                \"type\": \"string\",\n                \"format\": \"uri\"\n            },\n            \"contextPointer\": {\n                \"$comment\": \"The absolute JSON Pointer to the location in the instance that is the context of the link.  If the context resource supports JSON Pointer fragments, this will the string form of the identical JSON Pointer\",\n                \"type\": \"string\",\n                \"format\": \"json-pointer\"\n            },\n            \"rel\": {\n                \"type\": \"string\"\n            },\n            \"targetUri\": {\n                \"$comment\": \"The fully resolved target URI\",\n                \"type\": \"string\",\n                \"format\": \"uri\"\n            },\n            \"hrefInputTemplates\": {\n                \"$comment\": \"The list of partially resolved URI Templates, starting with \\\"href\\\", followed by applicable \\\"base\\\" values from nearest to furthest.\",\n                \"type\": \"array\",\n                \"items\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                }\n            },\n            \"hrefPrepopulatedInput\": {\n                \"$comment\": \"The initial data set to be presented with the input form when URI Tempalte input is accepted.\",\n                \"type\": \"object\",\n                \"propertyNames\": {\n                    \"$comment\": \"These are all URI Template variable names, specifically the 'varname' production from RFC 6570, Section 2.3\",\n                    \"pattern\": \"^(?:\\\\w|(?:%[a-f\\\\d]{2}))+(?:\\\\.(?:\\\\w|(?:%[a-f\\\\d]{2})))*$\"\n                }\n            },\n            \"attachmentPointer\": {\n                \"$comment\": \"The absolute JSON Pointer, in string form, of the position to which this resolved link applies\",\n                \"type\": \"string\",\n                \"format\": \"json-pointer\"\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft7/hyper-schema.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/hyper-schema#\",\n    \"$id\": \"http://json-schema.org/draft-07/hyper-schema#\",\n    \"title\": \"JSON Hyper-Schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"allOf\": [\n                { \"$ref\": \"http://json-schema.org/draft-07/schema#/definitions/schemaArray\" },\n                {\n                    \"items\": { \"$ref\": \"#\" }\n                }\n            ]\n        }\n    },\n    \"allOf\": [ { \"$ref\": \"http://json-schema.org/draft-07/schema#\" } ],\n    \"properties\": {\n        \"additionalItems\": { \"$ref\": \"#\" },\n        \"additionalProperties\": { \"$ref\": \"#\"},\n        \"dependencies\": {\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"type\": \"array\" }\n                ]\n            }\n        },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ]\n        },\n        \"definitions\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"patternProperties\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"properties\": {\n            \"additionalProperties\": { \"$ref\": \"#\" }\n        },\n        \"if\": { \"$ref\": \"#\" },\n        \"then\": { \"$ref\": \"#\" },\n        \"else\": { \"$ref\": \"#\" },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" },\n        \"contains\": { \"$ref\": \"#\" },\n        \"propertyNames\": { \"$ref\": \"#\" },\n        \"base\": {\n            \"type\": \"string\",\n            \"format\": \"uri-template\"\n        },\n        \"links\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"$ref\": \"http://json-schema.org/draft-07/links#\"\n            }\n        }\n    },\n    \"links\": [\n        {\n            \"rel\": \"self\",\n            \"href\": \"{+%24id}\"\n        }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft7/links.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/hyper-schema#\",\n    \"$id\": \"http://json-schema.org/draft-07/links#\",\n    \"title\": \"Link Description Object\",\n    \"allOf\": [\n        { \"required\": [ \"rel\", \"href\" ] },\n        { \"$ref\": \"#/definitions/noRequiredFields\" }\n    ],\n    \"definitions\": {\n        \"noRequiredFields\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"anchor\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                },\n                \"anchorPointer\": {\n                    \"type\": \"string\",\n                    \"anyOf\": [\n                        { \"format\": \"json-pointer\" },\n                        { \"format\": \"relative-json-pointer\" }\n                    ]\n                },\n                \"rel\": {\n                    \"type\": \"string\"\n                },\n                \"href\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-template\"\n                },\n                \"hrefSchema\": {\n                    \"$ref\": \"http://json-schema.org/draft-07/hyper-schema#\"\n                },\n                \"templatePointers\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\",\n                        \"anyOf\": [\n                            { \"format\": \"json-pointer\" },\n                            { \"format\": \"relative-json-pointer\" }\n                        ]\n                    }\n                },\n                \"templateRequired\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    },\n                    \"uniqueItems\": true\n                },\n                \"title\": {\n                    \"type\": \"string\"\n                },\n                \"description\": {\n                    \"type\": \"string\"\n                },\n                \"targetSchema\": {\n                    \"$ref\": \"http://json-schema.org/draft-07/hyper-schema#\"\n                },\n                \"targetMediaType\": {\n                    \"type\": \"string\"\n                },\n                \"targetHints\": { },\n                \"headerSchema\": {\n                    \"$ref\": \"http://json-schema.org/draft-07/hyper-schema#\"\n                },\n                \"submissionMediaType\": {\n                    \"type\": \"string\",\n                    \"default\": \"application/json\"\n                },\n                \"submissionSchema\": {\n                    \"$ref\": \"http://json-schema.org/draft-07/hyper-schema#\"\n                },\n                \"$comment\": {\n                    \"type\": \"string\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/jsonschema-draft7/schema.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"http://json-schema.org/draft-07/schema#\",\n    \"title\": \"Core schema meta-schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$ref\": \"#\" }\n        },\n        \"nonNegativeInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"nonNegativeIntegerDefault0\": {\n            \"allOf\": [\n                { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n                { \"default\": 0 }\n            ]\n        },\n        \"simpleTypes\": {\n            \"enum\": [\n                \"array\",\n                \"boolean\",\n                \"integer\",\n                \"null\",\n                \"number\",\n                \"object\",\n                \"string\"\n            ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"uniqueItems\": true,\n            \"default\": []\n        }\n    },\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"$id\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"$schema\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"$ref\": {\n            \"type\": \"string\",\n            \"format\": \"uri-reference\"\n        },\n        \"$comment\": {\n            \"type\": \"string\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": true,\n        \"readOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"writeOnly\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"examples\": {\n            \"type\": \"array\",\n            \"items\": true\n        },\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"exclusiveMinimum\": 0\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"number\"\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"number\"\n        },\n        \"maxLength\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minLength\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"additionalItems\": { \"$ref\": \"#\" },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ],\n            \"default\": true\n        },\n        \"maxItems\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minItems\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"contains\": { \"$ref\": \"#\" },\n        \"maxProperties\": { \"$ref\": \"#/definitions/nonNegativeInteger\" },\n        \"minProperties\": { \"$ref\": \"#/definitions/nonNegativeIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/definitions/stringArray\" },\n        \"additionalProperties\": { \"$ref\": \"#\" },\n        \"definitions\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"propertyNames\": { \"format\": \"regex\" },\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"$ref\": \"#/definitions/stringArray\" }\n                ]\n            }\n        },\n        \"propertyNames\": { \"$ref\": \"#\" },\n        \"const\": true,\n        \"enum\": {\n            \"type\": \"array\",\n            \"items\": true,\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        },\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/definitions/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/definitions/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        },\n        \"format\": { \"type\": \"string\" },\n        \"contentMediaType\": { \"type\": \"string\" },\n        \"contentEncoding\": { \"type\": \"string\" },\n        \"if\": { \"$ref\": \"#\" },\n        \"then\": { \"$ref\": \"#\" },\n        \"else\": { \"$ref\": \"#\" },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" }\n    },\n    \"default\": true\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/COPYING",
    "content": "Copyright 2016 Eric Biggers\nCopyright 2024 Google LLC\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation files\n(the \"Software\"), to deal in the Software without restriction,\nincluding without limitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of the Software,\nand to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\nBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/common_defs.h",
    "content": "/*\n * common_defs.h\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef COMMON_DEFS_H\n#define COMMON_DEFS_H\n\n#include \"libdeflate.h\"\n\n#include <stdbool.h>\n#include <stddef.h>\t/* for size_t */\n#include <stdint.h>\n#ifdef _MSC_VER\n#  include <intrin.h>\t/* for _BitScan*() and other intrinsics */\n#  include <stdlib.h>\t/* for _byteswap_*() */\n   /* Disable MSVC warnings that are expected. */\n   /* /W2 */\n#  pragma warning(disable : 4146) /* unary minus on unsigned type */\n   /* /W3 */\n#  pragma warning(disable : 4018) /* signed/unsigned mismatch */\n#  pragma warning(disable : 4244) /* possible loss of data */\n#  pragma warning(disable : 4267) /* possible loss of precision */\n#  pragma warning(disable : 4310) /* cast truncates constant value */\n   /* /W4 */\n#  pragma warning(disable : 4100) /* unreferenced formal parameter */\n#  pragma warning(disable : 4127) /* conditional expression is constant */\n#  pragma warning(disable : 4189) /* local variable initialized but not referenced */\n#  pragma warning(disable : 4232) /* nonstandard extension used */\n#  pragma warning(disable : 4245) /* conversion from 'int' to 'unsigned int' */\n#  pragma warning(disable : 4295) /* array too small to include terminating null */\n#endif\n#ifndef FREESTANDING\n#  include <string.h>\t/* for memcpy() */\n#endif\n\n/* ========================================================================== */\n/*                             Target architecture                            */\n/* ========================================================================== */\n\n/* If possible, define a compiler-independent ARCH_* macro. */\n#undef ARCH_X86_64\n#undef ARCH_X86_32\n#undef ARCH_ARM64\n#undef ARCH_ARM32\n#undef ARCH_RISCV\n#ifdef _MSC_VER\n   /* Way too many things are broken in ARM64EC to pretend that it is x86_64. */\n#  if defined(_M_X64) && !defined(_M_ARM64EC)\n#    define ARCH_X86_64\n#  elif defined(_M_IX86)\n#    define ARCH_X86_32\n#  elif defined(_M_ARM64)\n#    define ARCH_ARM64\n#  elif defined(_M_ARM)\n#    define ARCH_ARM32\n#  endif\n#else\n#  if defined(__x86_64__)\n#    define ARCH_X86_64\n#  elif defined(__i386__)\n#    define ARCH_X86_32\n#  elif defined(__aarch64__)\n#    define ARCH_ARM64\n#  elif defined(__arm__)\n#    define ARCH_ARM32\n#  elif defined(__riscv)\n#    define ARCH_RISCV\n#  endif\n#endif\n\n/* ========================================================================== */\n/*                              Type definitions                              */\n/* ========================================================================== */\n\n/* Fixed-width integer types */\ntypedef uint8_t u8;\ntypedef uint16_t u16;\ntypedef uint32_t u32;\ntypedef uint64_t u64;\ntypedef int8_t s8;\ntypedef int16_t s16;\ntypedef int32_t s32;\ntypedef int64_t s64;\n\n/* ssize_t, if not available in <sys/types.h> */\n#ifdef _MSC_VER\n#  ifdef _WIN64\n     typedef long long ssize_t;\n#  else\n     typedef long ssize_t;\n#  endif\n#endif\n\n/*\n * Word type of the target architecture.  Use 'size_t' instead of\n * 'unsigned long' to account for platforms such as Windows that use 32-bit\n * 'unsigned long' on 64-bit architectures.\n */\ntypedef size_t machine_word_t;\n\n/* Number of bytes in a word */\n#define WORDBYTES\t((int)sizeof(machine_word_t))\n\n/* Number of bits in a word */\n#define WORDBITS\t(8 * WORDBYTES)\n\n/* ========================================================================== */\n/*                         Optional compiler features                         */\n/* ========================================================================== */\n\n/* Compiler version checks.  Only use when absolutely necessary. */\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#  define GCC_PREREQ(major, minor)\t\t\\\n\t(__GNUC__ > (major) ||\t\t\t\\\n\t (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))\n#  if !GCC_PREREQ(4, 9)\n#    error \"gcc versions older than 4.9 are no longer supported\"\n#  endif\n#else\n#  define GCC_PREREQ(major, minor)\t0\n#endif\n#ifdef __clang__\n#  ifdef __apple_build_version__\n#    define CLANG_PREREQ(major, minor, apple_version)\t\\\n\t(__apple_build_version__ >= (apple_version))\n#  else\n#    define CLANG_PREREQ(major, minor, apple_version)\t\\\n\t(__clang_major__ > (major) ||\t\t\t\\\n\t (__clang_major__ == (major) && __clang_minor__ >= (minor)))\n#  endif\n#  if !CLANG_PREREQ(3, 9, 8000000)\n#    error \"clang versions older than 3.9 are no longer supported\"\n#  endif\n#else\n#  define CLANG_PREREQ(major, minor, apple_version)\t0\n#endif\n#ifdef _MSC_VER\n#  define MSVC_PREREQ(version)\t(_MSC_VER >= (version))\n#  if !MSVC_PREREQ(1900)\n#    error \"MSVC versions older than Visual Studio 2015 are no longer supported\"\n#  endif\n#else\n#  define MSVC_PREREQ(version)\t0\n#endif\n\n/*\n * __has_attribute(attribute) - check whether the compiler supports the given\n * attribute (and also supports doing the check in the first place).  Mostly\n * useful just for clang, since gcc didn't add this macro until gcc 5.\n */\n#ifndef __has_attribute\n#  define __has_attribute(attribute)\t0\n#endif\n\n/*\n * __has_builtin(builtin) - check whether the compiler supports the given\n * builtin (and also supports doing the check in the first place).  Mostly\n * useful just for clang, since gcc didn't add this macro until gcc 10.\n */\n#ifndef __has_builtin\n#  define __has_builtin(builtin)\t0\n#endif\n\n/* inline - suggest that a function be inlined */\n#ifdef _MSC_VER\n#  define inline\t\t__inline\n#endif /* else assume 'inline' is usable as-is */\n\n/* forceinline - force a function to be inlined, if possible */\n#if defined(__GNUC__) || __has_attribute(always_inline)\n#  define forceinline\t\tinline __attribute__((always_inline))\n#elif defined(_MSC_VER)\n#  define forceinline\t\t__forceinline\n#else\n#  define forceinline\t\tinline\n#endif\n\n/* MAYBE_UNUSED - mark a function or variable as maybe unused */\n#if defined(__GNUC__) || __has_attribute(unused)\n#  define MAYBE_UNUSED\t\t__attribute__((unused))\n#else\n#  define MAYBE_UNUSED\n#endif\n\n/* NORETURN - mark a function as never returning, e.g. due to calling abort() */\n#if defined(__GNUC__) || __has_attribute(noreturn)\n#  define NORETURN\t\t__attribute__((noreturn))\n#else\n#  define NORETURN\n#endif\n\n/*\n * restrict - hint that writes only occur through the given pointer.\n *\n * Don't use MSVC's __restrict, since it has nonstandard behavior.\n * Standard restrict is okay, if it is supported.\n */\n#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)\n#  if defined(__GNUC__) || defined(__clang__)\n#    define restrict\t\t__restrict__\n#  else\n#    define restrict\n#  endif\n#endif /* else assume 'restrict' is usable as-is */\n\n/* likely(expr) - hint that an expression is usually true */\n#if defined(__GNUC__) || __has_builtin(__builtin_expect)\n#  define likely(expr)\t\t__builtin_expect(!!(expr), 1)\n#else\n#  define likely(expr)\t\t(expr)\n#endif\n\n/* unlikely(expr) - hint that an expression is usually false */\n#if defined(__GNUC__) || __has_builtin(__builtin_expect)\n#  define unlikely(expr)\t__builtin_expect(!!(expr), 0)\n#else\n#  define unlikely(expr)\t(expr)\n#endif\n\n/* prefetchr(addr) - prefetch into L1 cache for read */\n#undef prefetchr\n#if defined(__GNUC__) || __has_builtin(__builtin_prefetch)\n#  define prefetchr(addr)\t__builtin_prefetch((addr), 0)\n#elif defined(_MSC_VER)\n#  if defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#    define prefetchr(addr)\t_mm_prefetch((addr), _MM_HINT_T0)\n#  elif defined(ARCH_ARM64)\n#    define prefetchr(addr)\t__prefetch2((addr), 0x00 /* prfop=PLDL1KEEP */)\n#  elif defined(ARCH_ARM32)\n#    define prefetchr(addr)\t__prefetch(addr)\n#  endif\n#endif\n#ifndef prefetchr\n#  define prefetchr(addr)\n#endif\n\n/* prefetchw(addr) - prefetch into L1 cache for write */\n#undef prefetchw\n#if defined(__GNUC__) || __has_builtin(__builtin_prefetch)\n#  define prefetchw(addr)\t__builtin_prefetch((addr), 1)\n#elif defined(_MSC_VER)\n#  if defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#    define prefetchw(addr)\t_m_prefetchw(addr)\n#  elif defined(ARCH_ARM64)\n#    define prefetchw(addr)\t__prefetch2((addr), 0x10 /* prfop=PSTL1KEEP */)\n#  elif defined(ARCH_ARM32)\n#    define prefetchw(addr)\t__prefetchw(addr)\n#  endif\n#endif\n#ifndef prefetchw\n#  define prefetchw(addr)\n#endif\n\n/*\n * _aligned_attribute(n) - declare that the annotated variable, or variables of\n * the annotated type, must be aligned on n-byte boundaries.\n */\n#undef _aligned_attribute\n#if defined(__GNUC__) || __has_attribute(aligned)\n#  define _aligned_attribute(n)\t__attribute__((aligned(n)))\n#elif defined(_MSC_VER)\n#  define _aligned_attribute(n)\t__declspec(align(n))\n#endif\n\n/*\n * _target_attribute(attrs) - override the compilation target for a function.\n *\n * This accepts one or more comma-separated suffixes to the -m prefix jointly\n * forming the name of a machine-dependent option.  On gcc-like compilers, this\n * enables codegen for the given targets, including arbitrary compiler-generated\n * code as well as the corresponding intrinsics.  On other compilers this macro\n * expands to nothing, though MSVC allows intrinsics to be used anywhere anyway.\n */\n#if defined(__GNUC__) || __has_attribute(target)\n#  define _target_attribute(attrs)\t__attribute__((target(attrs)))\n#else\n#  define _target_attribute(attrs)\n#endif\n\n/* ========================================================================== */\n/*                          Miscellaneous macros                              */\n/* ========================================================================== */\n\n#define ARRAY_LEN(A)\t\t(sizeof(A) / sizeof((A)[0]))\n#define MIN(a, b)\t\t((a) <= (b) ? (a) : (b))\n#define MAX(a, b)\t\t((a) >= (b) ? (a) : (b))\n#define DIV_ROUND_UP(n, d)\t(((n) + (d) - 1) / (d))\n#define STATIC_ASSERT(expr)\t((void)sizeof(char[1 - 2 * !(expr)]))\n#define ALIGN(n, a)\t\t(((n) + (a) - 1) & ~((a) - 1))\n#define ROUND_UP(n, d)\t\t((d) * DIV_ROUND_UP((n), (d)))\n\n/* ========================================================================== */\n/*                           Endianness handling                              */\n/* ========================================================================== */\n\n/*\n * CPU_IS_LITTLE_ENDIAN() - 1 if the CPU is little endian, or 0 if it is big\n * endian.  When possible this is a compile-time macro that can be used in\n * preprocessor conditionals.  As a fallback, a generic method is used that\n * can't be used in preprocessor conditionals but should still be optimized out.\n */\n#if defined(__BYTE_ORDER__) /* gcc v4.6+ and clang */\n#  define CPU_IS_LITTLE_ENDIAN()  (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#elif defined(_MSC_VER)\n#  define CPU_IS_LITTLE_ENDIAN()  true\n#else\nstatic forceinline bool CPU_IS_LITTLE_ENDIAN(void)\n{\n\tunion {\n\t\tu32 w;\n\t\tu8 b;\n\t} u;\n\n\tu.w = 1;\n\treturn u.b;\n}\n#endif\n\n/* bswap16(v) - swap the bytes of a 16-bit integer */\nstatic forceinline u16 bswap16(u16 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_bswap16)\n\treturn __builtin_bswap16(v);\n#elif defined(_MSC_VER)\n\treturn _byteswap_ushort(v);\n#else\n\treturn (v << 8) | (v >> 8);\n#endif\n}\n\n/* bswap32(v) - swap the bytes of a 32-bit integer */\nstatic forceinline u32 bswap32(u32 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_bswap32)\n\treturn __builtin_bswap32(v);\n#elif defined(_MSC_VER)\n\treturn _byteswap_ulong(v);\n#else\n\treturn ((v & 0x000000FF) << 24) |\n\t       ((v & 0x0000FF00) << 8) |\n\t       ((v & 0x00FF0000) >> 8) |\n\t       ((v & 0xFF000000) >> 24);\n#endif\n}\n\n/* bswap64(v) - swap the bytes of a 64-bit integer */\nstatic forceinline u64 bswap64(u64 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_bswap64)\n\treturn __builtin_bswap64(v);\n#elif defined(_MSC_VER)\n\treturn _byteswap_uint64(v);\n#else\n\treturn ((v & 0x00000000000000FF) << 56) |\n\t       ((v & 0x000000000000FF00) << 40) |\n\t       ((v & 0x0000000000FF0000) << 24) |\n\t       ((v & 0x00000000FF000000) << 8) |\n\t       ((v & 0x000000FF00000000) >> 8) |\n\t       ((v & 0x0000FF0000000000) >> 24) |\n\t       ((v & 0x00FF000000000000) >> 40) |\n\t       ((v & 0xFF00000000000000) >> 56);\n#endif\n}\n\n#define le16_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap16(v))\n#define le32_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap32(v))\n#define le64_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? (v) : bswap64(v))\n#define be16_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap16(v) : (v))\n#define be32_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap32(v) : (v))\n#define be64_bswap(v) (CPU_IS_LITTLE_ENDIAN() ? bswap64(v) : (v))\n\n/* ========================================================================== */\n/*                          Unaligned memory accesses                         */\n/* ========================================================================== */\n\n/*\n * UNALIGNED_ACCESS_IS_FAST() - 1 if unaligned memory accesses can be performed\n * efficiently on the target platform, otherwise 0.\n */\n#if (defined(__GNUC__) || defined(__clang__)) && \\\n\t(defined(ARCH_X86_64) || defined(ARCH_X86_32) || \\\n\t defined(__ARM_FEATURE_UNALIGNED) || defined(__powerpc64__) || \\\n\t defined(__riscv_misaligned_fast) || \\\n\t /*\n\t  * For all compilation purposes, WebAssembly behaves like any other CPU\n\t  * instruction set. Even though WebAssembly engine might be running on\n\t  * top of different actual CPU architectures, the WebAssembly spec\n\t  * itself permits unaligned access and it will be fast on most of those\n\t  * platforms, and simulated at the engine level on others, so it's\n\t  * worth treating it as a CPU architecture with fast unaligned access.\n\t  */ defined(__wasm__))\n#  define UNALIGNED_ACCESS_IS_FAST\t1\n#elif defined(_MSC_VER)\n#  define UNALIGNED_ACCESS_IS_FAST\t1\n#else\n#  define UNALIGNED_ACCESS_IS_FAST\t0\n#endif\n\n/*\n * Implementing unaligned memory accesses using memcpy() is portable, and it\n * usually gets optimized appropriately by modern compilers.  I.e., each\n * memcpy() of 1, 2, 4, or WORDBYTES bytes gets compiled to a load or store\n * instruction, not to an actual function call.\n *\n * We no longer use the \"packed struct\" approach to unaligned accesses, as that\n * is nonstandard, has unclear semantics, and doesn't receive enough testing\n * (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94994).\n *\n * arm32 with __ARM_FEATURE_UNALIGNED in gcc 5 and earlier is a known exception\n * where memcpy() generates inefficient code\n * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67366).  However, we no longer\n * consider that one case important enough to maintain different code for.\n * If you run into it, please just use a newer version of gcc (or use clang).\n */\n\n#ifdef FREESTANDING\n#  define MEMCOPY\t__builtin_memcpy\n#else\n#  define MEMCOPY\tmemcpy\n#endif\n\n/* Unaligned loads and stores without endianness conversion */\n\n#define DEFINE_UNALIGNED_TYPE(type)\t\t\t\t\\\nstatic forceinline type\t\t\t\t\t\t\\\nload_##type##_unaligned(const void *p)\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\ttype v;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tMEMCOPY(&v, p, sizeof(v));\t\t\t\t\\\n\treturn v;\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\nstatic forceinline void\t\t\t\t\t\t\\\nstore_##type##_unaligned(type v, void *p)\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\tMEMCOPY(p, &v, sizeof(v));\t\t\t\t\\\n}\n\nDEFINE_UNALIGNED_TYPE(u16)\nDEFINE_UNALIGNED_TYPE(u32)\nDEFINE_UNALIGNED_TYPE(u64)\nDEFINE_UNALIGNED_TYPE(machine_word_t)\n\n#undef MEMCOPY\n\n#define load_word_unaligned\tload_machine_word_t_unaligned\n#define store_word_unaligned\tstore_machine_word_t_unaligned\n\n/* Unaligned loads with endianness conversion */\n\nstatic forceinline u16\nget_unaligned_le16(const u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST)\n\t\treturn le16_bswap(load_u16_unaligned(p));\n\telse\n\t\treturn ((u16)p[1] << 8) | p[0];\n}\n\nstatic forceinline u16\nget_unaligned_be16(const u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST)\n\t\treturn be16_bswap(load_u16_unaligned(p));\n\telse\n\t\treturn ((u16)p[0] << 8) | p[1];\n}\n\nstatic forceinline u32\nget_unaligned_le32(const u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST)\n\t\treturn le32_bswap(load_u32_unaligned(p));\n\telse\n\t\treturn ((u32)p[3] << 24) | ((u32)p[2] << 16) |\n\t\t\t((u32)p[1] << 8) | p[0];\n}\n\nstatic forceinline u32\nget_unaligned_be32(const u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST)\n\t\treturn be32_bswap(load_u32_unaligned(p));\n\telse\n\t\treturn ((u32)p[0] << 24) | ((u32)p[1] << 16) |\n\t\t\t((u32)p[2] << 8) | p[3];\n}\n\nstatic forceinline u64\nget_unaligned_le64(const u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST)\n\t\treturn le64_bswap(load_u64_unaligned(p));\n\telse\n\t\treturn ((u64)p[7] << 56) | ((u64)p[6] << 48) |\n\t\t\t((u64)p[5] << 40) | ((u64)p[4] << 32) |\n\t\t\t((u64)p[3] << 24) | ((u64)p[2] << 16) |\n\t\t\t((u64)p[1] << 8) | p[0];\n}\n\nstatic forceinline machine_word_t\nget_unaligned_leword(const u8 *p)\n{\n\tSTATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64);\n\tif (WORDBITS == 32)\n\t\treturn get_unaligned_le32(p);\n\telse\n\t\treturn get_unaligned_le64(p);\n}\n\n/* Unaligned stores with endianness conversion */\n\nstatic forceinline void\nput_unaligned_le16(u16 v, u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\t\tstore_u16_unaligned(le16_bswap(v), p);\n\t} else {\n\t\tp[0] = (u8)(v >> 0);\n\t\tp[1] = (u8)(v >> 8);\n\t}\n}\n\nstatic forceinline void\nput_unaligned_be16(u16 v, u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\t\tstore_u16_unaligned(be16_bswap(v), p);\n\t} else {\n\t\tp[0] = (u8)(v >> 8);\n\t\tp[1] = (u8)(v >> 0);\n\t}\n}\n\nstatic forceinline void\nput_unaligned_le32(u32 v, u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\t\tstore_u32_unaligned(le32_bswap(v), p);\n\t} else {\n\t\tp[0] = (u8)(v >> 0);\n\t\tp[1] = (u8)(v >> 8);\n\t\tp[2] = (u8)(v >> 16);\n\t\tp[3] = (u8)(v >> 24);\n\t}\n}\n\nstatic forceinline void\nput_unaligned_be32(u32 v, u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\t\tstore_u32_unaligned(be32_bswap(v), p);\n\t} else {\n\t\tp[0] = (u8)(v >> 24);\n\t\tp[1] = (u8)(v >> 16);\n\t\tp[2] = (u8)(v >> 8);\n\t\tp[3] = (u8)(v >> 0);\n\t}\n}\n\nstatic forceinline void\nput_unaligned_le64(u64 v, u8 *p)\n{\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\t\tstore_u64_unaligned(le64_bswap(v), p);\n\t} else {\n\t\tp[0] = (u8)(v >> 0);\n\t\tp[1] = (u8)(v >> 8);\n\t\tp[2] = (u8)(v >> 16);\n\t\tp[3] = (u8)(v >> 24);\n\t\tp[4] = (u8)(v >> 32);\n\t\tp[5] = (u8)(v >> 40);\n\t\tp[6] = (u8)(v >> 48);\n\t\tp[7] = (u8)(v >> 56);\n\t}\n}\n\nstatic forceinline void\nput_unaligned_leword(machine_word_t v, u8 *p)\n{\n\tSTATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64);\n\tif (WORDBITS == 32)\n\t\tput_unaligned_le32(v, p);\n\telse\n\t\tput_unaligned_le64(v, p);\n}\n\n/* ========================================================================== */\n/*                         Bit manipulation functions                         */\n/* ========================================================================== */\n\n/*\n * Bit Scan Reverse (BSR) - find the 0-based index (relative to the least\n * significant end) of the *most* significant 1 bit in the input value.  The\n * input value must be nonzero!\n */\n\nstatic forceinline unsigned\nbsr32(u32 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_clz)\n\treturn 31 - __builtin_clz(v);\n#elif defined(_MSC_VER)\n\tunsigned long i;\n\n\t_BitScanReverse(&i, v);\n\treturn i;\n#else\n\tunsigned i = 0;\n\n\twhile ((v >>= 1) != 0)\n\t\ti++;\n\treturn i;\n#endif\n}\n\nstatic forceinline unsigned\nbsr64(u64 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_clzll)\n\treturn 63 - __builtin_clzll(v);\n#elif defined(_MSC_VER) && defined(_WIN64)\n\tunsigned long i;\n\n\t_BitScanReverse64(&i, v);\n\treturn i;\n#else\n\tunsigned i = 0;\n\n\twhile ((v >>= 1) != 0)\n\t\ti++;\n\treturn i;\n#endif\n}\n\nstatic forceinline unsigned\nbsrw(machine_word_t v)\n{\n\tSTATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64);\n\tif (WORDBITS == 32)\n\t\treturn bsr32(v);\n\telse\n\t\treturn bsr64(v);\n}\n\n/*\n * Bit Scan Forward (BSF) - find the 0-based index (relative to the least\n * significant end) of the *least* significant 1 bit in the input value.  The\n * input value must be nonzero!\n */\n\nstatic forceinline unsigned\nbsf32(u32 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_ctz)\n\treturn __builtin_ctz(v);\n#elif defined(_MSC_VER)\n\tunsigned long i;\n\n\t_BitScanForward(&i, v);\n\treturn i;\n#else\n\tunsigned i = 0;\n\n\tfor (; (v & 1) == 0; v >>= 1)\n\t\ti++;\n\treturn i;\n#endif\n}\n\nstatic forceinline unsigned\nbsf64(u64 v)\n{\n#if defined(__GNUC__) || __has_builtin(__builtin_ctzll)\n\treturn __builtin_ctzll(v);\n#elif defined(_MSC_VER) && defined(_WIN64)\n\tunsigned long i;\n\n\t_BitScanForward64(&i, v);\n\treturn i;\n#else\n\tunsigned i = 0;\n\n\tfor (; (v & 1) == 0; v >>= 1)\n\t\ti++;\n\treturn i;\n#endif\n}\n\nstatic forceinline unsigned\nbsfw(machine_word_t v)\n{\n\tSTATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64);\n\tif (WORDBITS == 32)\n\t\treturn bsf32(v);\n\telse\n\t\treturn bsf64(v);\n}\n\n/*\n * rbit32(v): reverse the bits in a 32-bit integer.  This doesn't have a\n * fallback implementation; use '#ifdef rbit32' to check if this is available.\n */\n#undef rbit32\n#if (defined(__GNUC__) || defined(__clang__)) && defined(ARCH_ARM32) && \\\n\t(__ARM_ARCH >= 7 || (__ARM_ARCH == 6 && defined(__ARM_ARCH_6T2__)))\nstatic forceinline u32\nrbit32(u32 v)\n{\n\t__asm__(\"rbit %0, %1\" : \"=r\" (v) : \"r\" (v));\n\treturn v;\n}\n#define rbit32 rbit32\n#elif (defined(__GNUC__) || defined(__clang__)) && defined(ARCH_ARM64)\nstatic forceinline u32\nrbit32(u32 v)\n{\n\t__asm__(\"rbit %w0, %w1\" : \"=r\" (v) : \"r\" (v));\n\treturn v;\n}\n#define rbit32 rbit32\n#endif\n\n#endif /* COMMON_DEFS_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/adler32.c",
    "content": "/*\n * adler32.c - Adler-32 checksum algorithm\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"lib_common.h\"\n\n/* The Adler-32 divisor, or \"base\", value */\n#define DIVISOR 65521\n\n/*\n * MAX_CHUNK_LEN is the most bytes that can be processed without the possibility\n * of s2 overflowing when it is represented as an unsigned 32-bit integer.  This\n * value was computed using the following Python script:\n *\n *\tdivisor = 65521\n *\tcount = 0\n *\ts1 = divisor - 1\n *\ts2 = divisor - 1\n *\twhile True:\n *\t\ts1 += 0xFF\n *\t\ts2 += s1\n *\t\tif s2 > 0xFFFFFFFF:\n *\t\t\tbreak\n *\t\tcount += 1\n *\tprint(count)\n *\n * Note that to get the correct worst-case value, we must assume that every byte\n * has value 0xFF and that s1 and s2 started with the highest possible values\n * modulo the divisor.\n */\n#define MAX_CHUNK_LEN\t5552\n\n/*\n * Update the Adler-32 values s1 and s2 using n bytes from p, update p to p + n,\n * update n to 0, and reduce s1 and s2 mod DIVISOR.  It is assumed that neither\n * s1 nor s2 can overflow before the reduction at the end, i.e. n plus any bytes\n * already processed after the last reduction must not exceed MAX_CHUNK_LEN.\n *\n * This uses only portable C code.  This is used as a fallback when a vectorized\n * implementation of Adler-32 (e.g. AVX2) is unavailable on the platform.\n *\n * Some of the vectorized implementations also use this to handle the end of the\n * data when the data isn't evenly divisible by the length the vectorized code\n * works on.  To avoid compiler errors about target-specific option mismatches\n * when this is used in that way, this is a macro rather than a function.\n *\n * Although this is unvectorized, this does include an optimization where the\n * main loop processes four bytes at a time using a strategy similar to that\n * used by vectorized implementations.  This provides increased instruction-\n * level parallelism compared to the traditional 's1 += *p++; s2 += s1;'.\n */\n#define ADLER32_CHUNK(s1, s2, p, n)\t\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tif (n >= 4) {\t\t\t\t\t\t\t\\\n\t\tu32 s1_sum = 0;\t\t\t\t\t\t\\\n\t\tu32 byte_0_sum = 0;\t\t\t\t\t\\\n\t\tu32 byte_1_sum = 0;\t\t\t\t\t\\\n\t\tu32 byte_2_sum = 0;\t\t\t\t\t\\\n\t\tu32 byte_3_sum = 0;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tdo {\t\t\t\t\t\t\t\\\n\t\t\ts1_sum += s1;\t\t\t\t\t\\\n\t\t\ts1 += p[0] + p[1] + p[2] + p[3];\t\t\\\n\t\t\tbyte_0_sum += p[0];\t\t\t\t\\\n\t\t\tbyte_1_sum += p[1];\t\t\t\t\\\n\t\t\tbyte_2_sum += p[2];\t\t\t\t\\\n\t\t\tbyte_3_sum += p[3];\t\t\t\t\\\n\t\t\tp += 4;\t\t\t\t\t\t\\\n\t\t\tn -= 4;\t\t\t\t\t\t\\\n\t\t} while (n >= 4);\t\t\t\t\t\\\n\t\ts2 += (4 * (s1_sum + byte_0_sum)) + (3 * byte_1_sum) +\t\\\n\t\t      (2 * byte_2_sum) + byte_3_sum;\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tfor (; n; n--, p++) {\t\t\t\t\t\t\\\n\t\ts1 += *p;\t\t\t\t\t\t\\\n\t\ts2 += s1;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\ts1 %= DIVISOR;\t\t\t\t\t\t\t\\\n\ts2 %= DIVISOR;\t\t\t\t\t\t\t\\\n} while (0)\n\nstatic u32 MAYBE_UNUSED\nadler32_generic(u32 adler, const u8 *p, size_t len)\n{\n\tu32 s1 = adler & 0xFFFF;\n\tu32 s2 = adler >> 16;\n\n\twhile (len) {\n\t\tsize_t n = MIN(len, MAX_CHUNK_LEN & ~3);\n\n\t\tlen -= n;\n\t\tADLER32_CHUNK(s1, s2, p, n);\n\t}\n\n\treturn (s2 << 16) | s1;\n}\n\n/* Include architecture-specific implementation(s) if available. */\n#undef DEFAULT_IMPL\n#undef arch_select_adler32_func\ntypedef u32 (*adler32_func_t)(u32 adler, const u8 *p, size_t len);\n#if defined(ARCH_ARM32) || defined(ARCH_ARM64)\n#  include \"arm/adler32_impl.h\"\n#elif defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#  include \"x86/adler32_impl.h\"\n#endif\n\n#ifndef DEFAULT_IMPL\n#  define DEFAULT_IMPL adler32_generic\n#endif\n\n#ifdef arch_select_adler32_func\nstatic u32 dispatch_adler32(u32 adler, const u8 *p, size_t len);\n\nstatic volatile adler32_func_t adler32_impl = dispatch_adler32;\n\n/* Choose the best implementation at runtime. */\nstatic u32 dispatch_adler32(u32 adler, const u8 *p, size_t len)\n{\n\tadler32_func_t f = arch_select_adler32_func();\n\n\tif (f == NULL)\n\t\tf = DEFAULT_IMPL;\n\n\tadler32_impl = f;\n\treturn f(adler, p, len);\n}\n#else\n/* The best implementation is statically known, so call it directly. */\n#define adler32_impl DEFAULT_IMPL\n#endif\n\nLIBDEFLATEAPI u32\nlibdeflate_adler32(u32 adler, const void *buffer, size_t len)\n{\n\tif (buffer == NULL) /* Return initial value. */\n\t\treturn 1;\n\treturn adler32_impl(adler, buffer, len);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/adler32_impl.h",
    "content": "/*\n * arm/adler32_impl.h - ARM implementations of Adler-32 checksum algorithm\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_ARM_ADLER32_IMPL_H\n#define LIB_ARM_ADLER32_IMPL_H\n\n#include \"cpu_features.h\"\n\n/* Regular NEON implementation */\n#if HAVE_NEON_INTRIN && CPU_IS_LITTLE_ENDIAN()\n#  define adler32_arm_neon\tadler32_arm_neon\n#  if HAVE_NEON_NATIVE\n     /*\n      * Use no attributes if none are needed, to support old versions of clang\n      * that don't accept the simd target attribute.\n      */\n#    define ATTRIBUTES\n#  elif defined(ARCH_ARM32)\n#    define ATTRIBUTES\t_target_attribute(\"fpu=neon\")\n#  elif defined(__clang__)\n#    define ATTRIBUTES\t_target_attribute(\"simd\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"+simd\")\n#  endif\nstatic ATTRIBUTES MAYBE_UNUSED u32\nadler32_arm_neon(u32 adler, const u8 *p, size_t len)\n{\n\tstatic const u16 _aligned_attribute(16) mults[64] = {\n\t\t64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,\n\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,\n\t\t32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n\t\t16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n\t};\n\tconst uint16x8_t mults_a = vld1q_u16(&mults[0]);\n\tconst uint16x8_t mults_b = vld1q_u16(&mults[8]);\n\tconst uint16x8_t mults_c = vld1q_u16(&mults[16]);\n\tconst uint16x8_t mults_d = vld1q_u16(&mults[24]);\n\tconst uint16x8_t mults_e = vld1q_u16(&mults[32]);\n\tconst uint16x8_t mults_f = vld1q_u16(&mults[40]);\n\tconst uint16x8_t mults_g = vld1q_u16(&mults[48]);\n\tconst uint16x8_t mults_h = vld1q_u16(&mults[56]);\n\tu32 s1 = adler & 0xFFFF;\n\tu32 s2 = adler >> 16;\n\n\t/*\n\t * If the length is large and the pointer is misaligned, align it.\n\t * For smaller lengths, just take the misaligned load penalty.\n\t */\n\tif (unlikely(len > 32768 && ((uintptr_t)p & 15))) {\n\t\tdo {\n\t\t\ts1 += *p++;\n\t\t\ts2 += s1;\n\t\t\tlen--;\n\t\t} while ((uintptr_t)p & 15);\n\t\ts1 %= DIVISOR;\n\t\ts2 %= DIVISOR;\n\t}\n\n\twhile (len) {\n\t\t/*\n\t\t * Calculate the length of the next data chunk such that s1 and\n\t\t * s2 are guaranteed to not exceed UINT32_MAX.\n\t\t */\n\t\tsize_t n = MIN(len, MAX_CHUNK_LEN & ~63);\n\n\t\tlen -= n;\n\n\t\tif (n >= 64) {\n\t\t\tuint32x4_t v_s1 = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s2 = vdupq_n_u32(0);\n\t\t\t/*\n\t\t\t * v_byte_sums_* contain the sum of the bytes at index i\n\t\t\t * across all 64-byte segments, for each index 0..63.\n\t\t\t */\n\t\t\tuint16x8_t v_byte_sums_a = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_b = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_c = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_d = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_e = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_f = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_g = vdupq_n_u16(0);\n\t\t\tuint16x8_t v_byte_sums_h = vdupq_n_u16(0);\n\n\t\t\ts2 += s1 * (n & ~63);\n\n\t\t\tdo {\n\t\t\t\t/* Load the next 64 data bytes. */\n\t\t\t\tconst uint8x16_t data_a = vld1q_u8(p + 0);\n\t\t\t\tconst uint8x16_t data_b = vld1q_u8(p + 16);\n\t\t\t\tconst uint8x16_t data_c = vld1q_u8(p + 32);\n\t\t\t\tconst uint8x16_t data_d = vld1q_u8(p + 48);\n\t\t\t\tuint16x8_t tmp;\n\n\t\t\t\t/*\n\t\t\t\t * Accumulate the previous s1 counters into the\n\t\t\t\t * s2 counters.  The needed multiplication by 64\n\t\t\t\t * is delayed to later.\n\t\t\t\t */\n\t\t\t\tv_s2 = vaddq_u32(v_s2, v_s1);\n\n\t\t\t\t/*\n\t\t\t\t * Add the 64 data bytes to their v_byte_sums\n\t\t\t\t * counters, while also accumulating the sums of\n\t\t\t\t * each adjacent set of 4 bytes into v_s1.\n\t\t\t\t */\n\t\t\t\ttmp = vpaddlq_u8(data_a);\n\t\t\t\tv_byte_sums_a = vaddw_u8(v_byte_sums_a,\n\t\t\t\t\t\t\t vget_low_u8(data_a));\n\t\t\t\tv_byte_sums_b = vaddw_u8(v_byte_sums_b,\n\t\t\t\t\t\t\t vget_high_u8(data_a));\n\t\t\t\ttmp = vpadalq_u8(tmp, data_b);\n\t\t\t\tv_byte_sums_c = vaddw_u8(v_byte_sums_c,\n\t\t\t\t\t\t\t vget_low_u8(data_b));\n\t\t\t\tv_byte_sums_d = vaddw_u8(v_byte_sums_d,\n\t\t\t\t\t\t\t vget_high_u8(data_b));\n\t\t\t\ttmp = vpadalq_u8(tmp, data_c);\n\t\t\t\tv_byte_sums_e = vaddw_u8(v_byte_sums_e,\n\t\t\t\t\t\t\t vget_low_u8(data_c));\n\t\t\t\tv_byte_sums_f = vaddw_u8(v_byte_sums_f,\n\t\t\t\t\t\t\t vget_high_u8(data_c));\n\t\t\t\ttmp = vpadalq_u8(tmp, data_d);\n\t\t\t\tv_byte_sums_g = vaddw_u8(v_byte_sums_g,\n\t\t\t\t\t\t\t vget_low_u8(data_d));\n\t\t\t\tv_byte_sums_h = vaddw_u8(v_byte_sums_h,\n\t\t\t\t\t\t\t vget_high_u8(data_d));\n\t\t\t\tv_s1 = vpadalq_u16(v_s1, tmp);\n\n\t\t\t\tp += 64;\n\t\t\t\tn -= 64;\n\t\t\t} while (n >= 64);\n\n\t\t\t/* s2 = 64*s2 + (64*bytesum0 + 63*bytesum1 + ... + 1*bytesum63) */\n\t\t#ifdef ARCH_ARM32\n\t\t#  define umlal2(a, b, c)  vmlal_u16((a), vget_high_u16(b), vget_high_u16(c))\n\t\t#else\n\t\t#  define umlal2\t   vmlal_high_u16\n\t\t#endif\n\t\t\tv_s2 = vqshlq_n_u32(v_s2, 6);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_a),\n\t\t\t\t\t vget_low_u16(mults_a));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_a, mults_a);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_b),\n\t\t\t\t\t vget_low_u16(mults_b));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_b, mults_b);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_c),\n\t\t\t\t\t vget_low_u16(mults_c));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_c, mults_c);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_d),\n\t\t\t\t\t vget_low_u16(mults_d));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_d, mults_d);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_e),\n\t\t\t\t\t vget_low_u16(mults_e));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_e, mults_e);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_f),\n\t\t\t\t\t vget_low_u16(mults_f));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_f, mults_f);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_g),\n\t\t\t\t\t vget_low_u16(mults_g));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_g, mults_g);\n\t\t\tv_s2 = vmlal_u16(v_s2, vget_low_u16(v_byte_sums_h),\n\t\t\t\t\t vget_low_u16(mults_h));\n\t\t\tv_s2 = umlal2(v_s2, v_byte_sums_h, mults_h);\n\t\t#undef umlal2\n\n\t\t\t/* Horizontal sum to finish up */\n\t\t#ifdef ARCH_ARM32\n\t\t\ts1 += vgetq_lane_u32(v_s1, 0) + vgetq_lane_u32(v_s1, 1) +\n\t\t\t      vgetq_lane_u32(v_s1, 2) + vgetq_lane_u32(v_s1, 3);\n\t\t\ts2 += vgetq_lane_u32(v_s2, 0) + vgetq_lane_u32(v_s2, 1) +\n\t\t\t      vgetq_lane_u32(v_s2, 2) + vgetq_lane_u32(v_s2, 3);\n\t\t#else\n\t\t\ts1 += vaddvq_u32(v_s1);\n\t\t\ts2 += vaddvq_u32(v_s2);\n\t\t#endif\n\t\t}\n\t\t/*\n\t\t * Process the last 0 <= n < 64 bytes of the chunk using\n\t\t * scalar instructions and reduce s1 and s2 mod DIVISOR.\n\t\t */\n\t\tADLER32_CHUNK(s1, s2, p, n);\n\t}\n\treturn (s2 << 16) | s1;\n}\n#undef ATTRIBUTES\n#endif /* Regular NEON implementation */\n\n/* NEON+dotprod implementation */\n#if HAVE_DOTPROD_INTRIN && CPU_IS_LITTLE_ENDIAN() && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_DOTPROD)\n#  define adler32_arm_neon_dotprod\tadler32_arm_neon_dotprod\n#  ifdef __clang__\n#    define ATTRIBUTES\t_target_attribute(\"dotprod\")\n   /*\n    * Both gcc and binutils originally considered dotprod to depend on\n    * arch=armv8.2-a or later.  This was fixed in gcc 13.2 by commit\n    * 9aac37ab8a7b (\"aarch64: Remove architecture dependencies from intrinsics\")\n    * and in binutils 2.41 by commit 205e4380c800 (\"aarch64: Remove version\n    * dependencies from features\").  Unfortunately, always using arch=armv8.2-a\n    * causes build errors with some compiler options because it may reduce the\n    * arch rather than increase it.  Therefore we try to omit the arch whenever\n    * possible.  If gcc is 14 or later, then both gcc and binutils are probably\n    * fixed, so we omit the arch.  We also omit the arch if a feature that\n    * depends on armv8.2-a or later (in gcc 13.1 and earlier) is present.\n    */\n#  elif GCC_PREREQ(14, 0) || defined(__ARM_FEATURE_JCVT) \\\n\t\t\t  || defined(__ARM_FEATURE_DOTPROD)\n#    define ATTRIBUTES\t_target_attribute(\"+dotprod\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"arch=armv8.2-a+dotprod\")\n#  endif\nstatic ATTRIBUTES u32\nadler32_arm_neon_dotprod(u32 adler, const u8 *p, size_t len)\n{\n\tstatic const u8 _aligned_attribute(16) mults[64] = {\n\t\t64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,\n\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,\n\t\t32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n\t\t16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n\t};\n\tconst uint8x16_t mults_a = vld1q_u8(&mults[0]);\n\tconst uint8x16_t mults_b = vld1q_u8(&mults[16]);\n\tconst uint8x16_t mults_c = vld1q_u8(&mults[32]);\n\tconst uint8x16_t mults_d = vld1q_u8(&mults[48]);\n\tconst uint8x16_t ones = vdupq_n_u8(1);\n\tu32 s1 = adler & 0xFFFF;\n\tu32 s2 = adler >> 16;\n\n\t/*\n\t * If the length is large and the pointer is misaligned, align it.\n\t * For smaller lengths, just take the misaligned load penalty.\n\t */\n\tif (unlikely(len > 32768 && ((uintptr_t)p & 15))) {\n\t\tdo {\n\t\t\ts1 += *p++;\n\t\t\ts2 += s1;\n\t\t\tlen--;\n\t\t} while ((uintptr_t)p & 15);\n\t\ts1 %= DIVISOR;\n\t\ts2 %= DIVISOR;\n\t}\n\n\twhile (len) {\n\t\t/*\n\t\t * Calculate the length of the next data chunk such that s1 and\n\t\t * s2 are guaranteed to not exceed UINT32_MAX.\n\t\t */\n\t\tsize_t n = MIN(len, MAX_CHUNK_LEN & ~63);\n\n\t\tlen -= n;\n\n\t\tif (n >= 64) {\n\t\t\tuint32x4_t v_s1_a = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_b = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_c = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_d = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s2_a = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s2_b = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s2_c = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s2_d = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_sums_a = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_sums_b = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_sums_c = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1_sums_d = vdupq_n_u32(0);\n\t\t\tuint32x4_t v_s1;\n\t\t\tuint32x4_t v_s2;\n\t\t\tuint32x4_t v_s1_sums;\n\n\t\t\ts2 += s1 * (n & ~63);\n\n\t\t\tdo {\n\t\t\t\tuint8x16_t data_a = vld1q_u8(p + 0);\n\t\t\t\tuint8x16_t data_b = vld1q_u8(p + 16);\n\t\t\t\tuint8x16_t data_c = vld1q_u8(p + 32);\n\t\t\t\tuint8x16_t data_d = vld1q_u8(p + 48);\n\n\t\t\t\tv_s1_sums_a = vaddq_u32(v_s1_sums_a, v_s1_a);\n\t\t\t\tv_s1_a = vdotq_u32(v_s1_a, data_a, ones);\n\t\t\t\tv_s2_a = vdotq_u32(v_s2_a, data_a, mults_a);\n\n\t\t\t\tv_s1_sums_b = vaddq_u32(v_s1_sums_b, v_s1_b);\n\t\t\t\tv_s1_b = vdotq_u32(v_s1_b, data_b, ones);\n\t\t\t\tv_s2_b = vdotq_u32(v_s2_b, data_b, mults_b);\n\n\t\t\t\tv_s1_sums_c = vaddq_u32(v_s1_sums_c, v_s1_c);\n\t\t\t\tv_s1_c = vdotq_u32(v_s1_c, data_c, ones);\n\t\t\t\tv_s2_c = vdotq_u32(v_s2_c, data_c, mults_c);\n\n\t\t\t\tv_s1_sums_d = vaddq_u32(v_s1_sums_d, v_s1_d);\n\t\t\t\tv_s1_d = vdotq_u32(v_s1_d, data_d, ones);\n\t\t\t\tv_s2_d = vdotq_u32(v_s2_d, data_d, mults_d);\n\n\t\t\t\tp += 64;\n\t\t\t\tn -= 64;\n\t\t\t} while (n >= 64);\n\n\t\t\tv_s1 = vaddq_u32(vaddq_u32(v_s1_a, v_s1_b),\n\t\t\t\t\t vaddq_u32(v_s1_c, v_s1_d));\n\t\t\tv_s2 = vaddq_u32(vaddq_u32(v_s2_a, v_s2_b),\n\t\t\t\t\t vaddq_u32(v_s2_c, v_s2_d));\n\t\t\tv_s1_sums = vaddq_u32(vaddq_u32(v_s1_sums_a,\n\t\t\t\t\t\t\tv_s1_sums_b),\n\t\t\t\t\t      vaddq_u32(v_s1_sums_c,\n\t\t\t\t\t\t\tv_s1_sums_d));\n\t\t\tv_s2 = vaddq_u32(v_s2, vqshlq_n_u32(v_s1_sums, 6));\n\n\t\t\ts1 += vaddvq_u32(v_s1);\n\t\t\ts2 += vaddvq_u32(v_s2);\n\t\t}\n\t\t/*\n\t\t * Process the last 0 <= n < 64 bytes of the chunk using\n\t\t * scalar instructions and reduce s1 and s2 mod DIVISOR.\n\t\t */\n\t\tADLER32_CHUNK(s1, s2, p, n);\n\t}\n\treturn (s2 << 16) | s1;\n}\n#undef ATTRIBUTES\n#endif /* NEON+dotprod implementation */\n\n#if defined(adler32_arm_neon_dotprod) && defined(__ARM_FEATURE_DOTPROD)\n#define DEFAULT_IMPL\tadler32_arm_neon_dotprod\n#else\nstatic inline adler32_func_t\narch_select_adler32_func(void)\n{\n\tconst u32 features MAYBE_UNUSED = get_arm_cpu_features();\n\n#ifdef adler32_arm_neon_dotprod\n\tif (HAVE_NEON(features) && HAVE_DOTPROD(features))\n\t\treturn adler32_arm_neon_dotprod;\n#endif\n#ifdef adler32_arm_neon\n\tif (HAVE_NEON(features))\n\t\treturn adler32_arm_neon;\n#endif\n\treturn NULL;\n}\n#define arch_select_adler32_func\tarch_select_adler32_func\n#endif\n\n#endif /* LIB_ARM_ADLER32_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/cpu_features.c",
    "content": "/*\n * arm/cpu_features.c - feature detection for ARM CPUs\n *\n * Copyright 2018 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * ARM CPUs don't have a standard way for unprivileged programs to detect CPU\n * features.  But an OS-specific way can be used when available.\n */\n\n#ifdef __APPLE__\n#  undef _ANSI_SOURCE\n#  undef _DARWIN_C_SOURCE\n#  define _DARWIN_C_SOURCE /* for sysctlbyname() */\n#endif\n\n#include \"../cpu_features_common.h\" /* must be included first */\n#include \"cpu_features.h\"\n\n#ifdef ARM_CPU_FEATURES_KNOWN\n/* Runtime ARM CPU feature detection is supported. */\n\n#ifdef __linux__\n/*\n * On Linux, arm32 and arm64 CPU features can be detected by reading the\n * AT_HWCAP and AT_HWCAP2 values from /proc/self/auxv.\n *\n * Ideally we'd use the C library function getauxval(), but it's not guaranteed\n * to be available: it was only added to glibc in 2.16, and in Android it was\n * added to API level 18 for arm32 and level 21 for arm64.\n */\n\n#include <errno.h>\n#include <fcntl.h>\n#include <string.h>\n#include <unistd.h>\n\n#define AT_HWCAP\t16\n#define AT_HWCAP2\t26\n\nstatic void scan_auxv(unsigned long *hwcap, unsigned long *hwcap2)\n{\n\tint fd;\n\tunsigned long auxbuf[32];\n\tint filled = 0;\n\tint i;\n\n\tfd = open(\"/proc/self/auxv\", O_RDONLY);\n\tif (fd < 0)\n\t\treturn;\n\n\tfor (;;) {\n\t\tdo {\n\t\t\tint ret = read(fd, &((char *)auxbuf)[filled],\n\t\t\t\t       sizeof(auxbuf) - filled);\n\t\t\tif (ret <= 0) {\n\t\t\t\tif (ret < 0 && errno == EINTR)\n\t\t\t\t\tcontinue;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tfilled += ret;\n\t\t} while (filled < 2 * sizeof(long));\n\n\t\ti = 0;\n\t\tdo {\n\t\t\tunsigned long type = auxbuf[i];\n\t\t\tunsigned long value = auxbuf[i + 1];\n\n\t\t\tif (type == AT_HWCAP)\n\t\t\t\t*hwcap = value;\n\t\t\telse if (type == AT_HWCAP2)\n\t\t\t\t*hwcap2 = value;\n\t\t\ti += 2;\n\t\t\tfilled -= 2 * sizeof(long);\n\t\t} while (filled >= 2 * sizeof(long));\n\n\t\tmemmove(auxbuf, &auxbuf[i], filled);\n\t}\nout:\n\tclose(fd);\n}\n\nstatic u32 query_arm_cpu_features(void)\n{\n\tu32 features = 0;\n\tunsigned long hwcap = 0;\n\tunsigned long hwcap2 = 0;\n\n\tscan_auxv(&hwcap, &hwcap2);\n\n#ifdef ARCH_ARM32\n\tSTATIC_ASSERT(sizeof(long) == 4);\n\tif (hwcap & (1 << 12))\t/* HWCAP_NEON */\n\t\tfeatures |= ARM_CPU_FEATURE_NEON;\n#else\n\tSTATIC_ASSERT(sizeof(long) == 8);\n\tif (hwcap & (1 << 1))\t/* HWCAP_ASIMD */\n\t\tfeatures |= ARM_CPU_FEATURE_NEON;\n\tif (hwcap & (1 << 4))\t/* HWCAP_PMULL */\n\t\tfeatures |= ARM_CPU_FEATURE_PMULL;\n\tif (hwcap & (1 << 7))\t/* HWCAP_CRC32 */\n\t\tfeatures |= ARM_CPU_FEATURE_CRC32;\n\tif (hwcap & (1 << 17))\t/* HWCAP_SHA3 */\n\t\tfeatures |= ARM_CPU_FEATURE_SHA3;\n\tif (hwcap & (1 << 20))\t/* HWCAP_ASIMDDP */\n\t\tfeatures |= ARM_CPU_FEATURE_DOTPROD;\n#endif\n\treturn features;\n}\n\n#elif defined(__APPLE__)\n/* On Apple platforms, arm64 CPU features can be detected via sysctlbyname(). */\n\n#include <sys/types.h>\n#include <sys/sysctl.h>\n#include <TargetConditionals.h>\n\nstatic const struct {\n\tconst char *name;\n\tu32 feature;\n} feature_sysctls[] = {\n\t{ \"hw.optional.neon\",\t\t  ARM_CPU_FEATURE_NEON },\n\t{ \"hw.optional.AdvSIMD\",\t  ARM_CPU_FEATURE_NEON },\n\t{ \"hw.optional.arm.FEAT_PMULL\",\t  ARM_CPU_FEATURE_PMULL },\n\t{ \"hw.optional.armv8_crc32\",\t  ARM_CPU_FEATURE_CRC32 },\n\t{ \"hw.optional.armv8_2_sha3\",\t  ARM_CPU_FEATURE_SHA3 },\n\t{ \"hw.optional.arm.FEAT_SHA3\",\t  ARM_CPU_FEATURE_SHA3 },\n\t{ \"hw.optional.arm.FEAT_DotProd\", ARM_CPU_FEATURE_DOTPROD },\n};\n\nstatic u32 query_arm_cpu_features(void)\n{\n\tu32 features = 0;\n\tsize_t i;\n\n\tfor (i = 0; i < ARRAY_LEN(feature_sysctls); i++) {\n\t\tconst char *name = feature_sysctls[i].name;\n\t\tu32 val = 0;\n\t\tsize_t valsize = sizeof(val);\n\n\t\tif (sysctlbyname(name, &val, &valsize, NULL, 0) == 0 &&\n\t\t    valsize == sizeof(val) && val == 1)\n\t\t\tfeatures |= feature_sysctls[i].feature;\n\t}\n\treturn features;\n}\n#elif defined(_WIN32)\n\n#include <windows.h>\n\n#ifndef PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE /* added in Windows SDK 20348 */\n#  define PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE 43\n#endif\n\nstatic u32 query_arm_cpu_features(void)\n{\n\tu32 features = ARM_CPU_FEATURE_NEON;\n\n\tif (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))\n\t\tfeatures |= ARM_CPU_FEATURE_PMULL;\n\tif (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))\n\t\tfeatures |= ARM_CPU_FEATURE_CRC32;\n\tif (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE))\n\t\tfeatures |= ARM_CPU_FEATURE_DOTPROD;\n\n\t/* FIXME: detect SHA3 support too. */\n\n\treturn features;\n}\n#else\n#error \"unhandled case\"\n#endif\n\nstatic const struct cpu_feature arm_cpu_feature_table[] = {\n\t{ARM_CPU_FEATURE_NEON,\t\t\"neon\"},\n\t{ARM_CPU_FEATURE_PMULL,\t\t\"pmull\"},\n\t{ARM_CPU_FEATURE_PREFER_PMULL,  \"prefer_pmull\"},\n\t{ARM_CPU_FEATURE_CRC32,\t\t\"crc32\"},\n\t{ARM_CPU_FEATURE_SHA3,\t\t\"sha3\"},\n\t{ARM_CPU_FEATURE_DOTPROD,\t\"dotprod\"},\n};\n\nvolatile u32 libdeflate_arm_cpu_features = 0;\n\nvoid libdeflate_init_arm_cpu_features(void)\n{\n\tu32 features = query_arm_cpu_features();\n\n\t/*\n\t * On the Apple M1 processor, crc32 instructions max out at about 25.5\n\t * GB/s in the best case of using a 3-way or greater interleaved chunked\n\t * implementation, whereas a pmull-based implementation achieves 68 GB/s\n\t * provided that the stride length is large enough (about 10+ vectors\n\t * with eor3, or 12+ without).\n\t *\n\t * Assume that crc32 instructions are preferable in other cases.\n\t */\n#if (defined(__APPLE__) && TARGET_OS_OSX) || defined(TEST_SUPPORT__DO_NOT_USE)\n\tfeatures |= ARM_CPU_FEATURE_PREFER_PMULL;\n#endif\n\n\tdisable_cpu_features_for_testing(&features, arm_cpu_feature_table,\n\t\t\t\t\t ARRAY_LEN(arm_cpu_feature_table));\n\n\tlibdeflate_arm_cpu_features = features | ARM_CPU_FEATURES_KNOWN;\n}\n\n#endif /* ARM_CPU_FEATURES_KNOWN */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/cpu_features.h",
    "content": "/*\n * arm/cpu_features.h - feature detection for ARM CPUs\n *\n * Copyright 2018 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_ARM_CPU_FEATURES_H\n#define LIB_ARM_CPU_FEATURES_H\n\n#include \"../lib_common.h\"\n\n#if defined(ARCH_ARM32) || defined(ARCH_ARM64)\n\n#define ARM_CPU_FEATURE_NEON\t\t(1 << 0)\n#define ARM_CPU_FEATURE_PMULL\t\t(1 << 1)\n/*\n * PREFER_PMULL indicates that the CPU has very high pmull throughput, and so\n * the 12x wide pmull-based CRC-32 implementation is likely to be faster than an\n * implementation based on the crc32 instructions.\n */\n#define ARM_CPU_FEATURE_PREFER_PMULL\t(1 << 2)\n#define ARM_CPU_FEATURE_CRC32\t\t(1 << 3)\n#define ARM_CPU_FEATURE_SHA3\t\t(1 << 4)\n#define ARM_CPU_FEATURE_DOTPROD\t\t(1 << 5)\n\n#if !defined(FREESTANDING) && \\\n    (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) && \\\n    (defined(__linux__) || \\\n     (defined(__APPLE__) && defined(ARCH_ARM64)) || \\\n     (defined(_WIN32) && defined(ARCH_ARM64)))\n/* Runtime ARM CPU feature detection is supported. */\n#  define ARM_CPU_FEATURES_KNOWN\t(1U << 31)\nextern volatile u32 libdeflate_arm_cpu_features;\n\nvoid libdeflate_init_arm_cpu_features(void);\n\nstatic inline u32 get_arm_cpu_features(void)\n{\n\tif (libdeflate_arm_cpu_features == 0)\n\t\tlibdeflate_init_arm_cpu_features();\n\treturn libdeflate_arm_cpu_features;\n}\n#else\nstatic inline u32 get_arm_cpu_features(void) { return 0; }\n#endif\n\n/* NEON */\n#if defined(__ARM_NEON) || (defined(_MSC_VER) && defined(ARCH_ARM64))\n#  define HAVE_NEON(features)\t1\n#  define HAVE_NEON_NATIVE\t1\n#else\n#  define HAVE_NEON(features)\t((features) & ARM_CPU_FEATURE_NEON)\n#  define HAVE_NEON_NATIVE\t0\n#endif\n/*\n * With both gcc and clang, NEON intrinsics require that the main target has\n * NEON enabled already.  Exception: with gcc 6.1 and later (r230411 for arm32,\n * r226563 for arm64), hardware floating point support is sufficient.\n */\n#if (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) && \\\n\t(HAVE_NEON_NATIVE || (GCC_PREREQ(6, 1) && defined(__ARM_FP)))\n#  define HAVE_NEON_INTRIN\t1\n#  include <arm_neon.h>\n#else\n#  define HAVE_NEON_INTRIN\t0\n#endif\n\n/* PMULL */\n#ifdef __ARM_FEATURE_CRYPTO\n#  define HAVE_PMULL(features)\t1\n#else\n#  define HAVE_PMULL(features)\t((features) & ARM_CPU_FEATURE_PMULL)\n#endif\n#if defined(ARCH_ARM64) && HAVE_NEON_INTRIN && \\\n\t(GCC_PREREQ(7, 1) || defined(__clang__) || defined(_MSC_VER)) && \\\n\tCPU_IS_LITTLE_ENDIAN() /* untested on big endian */\n#  define HAVE_PMULL_INTRIN\t1\n   /* Work around MSVC's vmull_p64() taking poly64x1_t instead of poly64_t */\n#  ifdef _MSC_VER\n#    define compat_vmull_p64(a, b)  vmull_p64(vcreate_p64(a), vcreate_p64(b))\n#  else\n#    define compat_vmull_p64(a, b)  vmull_p64((a), (b))\n#  endif\n#else\n#  define HAVE_PMULL_INTRIN\t0\n#endif\n\n/* CRC32 */\n#ifdef __ARM_FEATURE_CRC32\n#  define HAVE_CRC32(features)\t1\n#else\n#  define HAVE_CRC32(features)\t((features) & ARM_CPU_FEATURE_CRC32)\n#endif\n#if defined(ARCH_ARM64) && \\\n\t(defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER))\n#  define HAVE_CRC32_INTRIN\t1\n#  if defined(__GNUC__) || defined(__clang__)\n#    include <arm_acle.h>\n#  endif\n   /*\n    * Use an inline assembly fallback for clang 15 and earlier, which only\n    * defined the crc32 intrinsics when crc32 is enabled in the main target.\n    */\n#  if defined(__clang__) && !CLANG_PREREQ(16, 0, 16000000) && \\\n\t!defined(__ARM_FEATURE_CRC32)\n#    undef __crc32b\n#    define __crc32b(a, b)\t\t\t\t\t\\\n\t({ uint32_t res;\t\t\t\t\t\\\n\t   __asm__(\"crc32b %w0, %w1, %w2\"\t\t\t\\\n\t\t   : \"=r\" (res) : \"r\" (a), \"r\" (b));\t\t\\\n\t   res; })\n#    undef __crc32h\n#    define __crc32h(a, b)\t\t\t\t\t\\\n\t({ uint32_t res;\t\t\t\t\t\\\n\t   __asm__(\"crc32h %w0, %w1, %w2\"\t\t\t\\\n\t\t   : \"=r\" (res) : \"r\" (a), \"r\" (b));\t\t\\\n\t   res; })\n#    undef __crc32w\n#    define __crc32w(a, b)\t\t\t\t\t\\\n\t({ uint32_t res;\t\t\t\t\t\\\n\t   __asm__(\"crc32w %w0, %w1, %w2\"\t\t\t\\\n\t\t   : \"=r\" (res) : \"r\" (a), \"r\" (b));\t\t\\\n\t   res; })\n#    undef __crc32d\n#    define __crc32d(a, b)\t\t\t\t\t\\\n\t({ uint32_t res;\t\t\t\t\t\\\n\t   __asm__(\"crc32x %w0, %w1, %2\"\t\t\t\\\n\t\t   : \"=r\" (res) : \"r\" (a), \"r\" (b));\t\t\\\n\t   res; })\n#    pragma clang diagnostic ignored \"-Wgnu-statement-expression\"\n#  endif\n#else\n#  define HAVE_CRC32_INTRIN\t0\n#endif\n\n/* SHA3 (needed for the eor3 instruction) */\n#ifdef __ARM_FEATURE_SHA3\n#  define HAVE_SHA3(features)\t1\n#else\n#  define HAVE_SHA3(features)\t((features) & ARM_CPU_FEATURE_SHA3)\n#endif\n#if defined(ARCH_ARM64) && HAVE_NEON_INTRIN && \\\n\t(GCC_PREREQ(9, 1) /* r268049 */ || \\\n\t CLANG_PREREQ(7, 0, 10010463) /* r338010 */)\n#  define HAVE_SHA3_INTRIN\t1\n   /*\n    * Use an inline assembly fallback for clang 15 and earlier, which only\n    * defined the sha3 intrinsics when sha3 is enabled in the main target.\n    */\n#  if defined(__clang__) && !CLANG_PREREQ(16, 0, 16000000) && \\\n\t!defined(__ARM_FEATURE_SHA3)\n#    undef veor3q_u8\n#    define veor3q_u8(a, b, c)\t\t\t\t\t\\\n\t({ uint8x16_t res;\t\t\t\t\t\\\n\t   __asm__(\"eor3 %0.16b, %1.16b, %2.16b, %3.16b\"\t\\\n\t\t   : \"=w\" (res) : \"w\" (a), \"w\" (b), \"w\" (c));\t\\\n\t   res; })\n#    pragma clang diagnostic ignored \"-Wgnu-statement-expression\"\n#  endif\n#else\n#  define HAVE_SHA3_INTRIN\t0\n#endif\n\n/* dotprod */\n#ifdef __ARM_FEATURE_DOTPROD\n#  define HAVE_DOTPROD(features)\t1\n#else\n#  define HAVE_DOTPROD(features)\t((features) & ARM_CPU_FEATURE_DOTPROD)\n#endif\n#if defined(ARCH_ARM64) && HAVE_NEON_INTRIN && \\\n\t(GCC_PREREQ(8, 1) || CLANG_PREREQ(7, 0, 10010000) || defined(_MSC_VER))\n#  define HAVE_DOTPROD_INTRIN\t1\n   /*\n    * Use an inline assembly fallback for clang 15 and earlier, which only\n    * defined the dotprod intrinsics when dotprod is enabled in the main target.\n    */\n#  if defined(__clang__) && !CLANG_PREREQ(16, 0, 16000000) && \\\n\t!defined(__ARM_FEATURE_DOTPROD)\n#    undef vdotq_u32\n#    define vdotq_u32(a, b, c)\t\t\t\t\t\\\n\t({ uint32x4_t res = (a);\t\t\t\t\\\n\t   __asm__(\"udot %0.4s, %1.16b, %2.16b\"\t\t\t\\\n\t\t   : \"+w\" (res) : \"w\" (b), \"w\" (c));\t\t\\\n\t   res; })\n#    pragma clang diagnostic ignored \"-Wgnu-statement-expression\"\n#  endif\n#else\n#  define HAVE_DOTPROD_INTRIN\t0\n#endif\n\n#endif /* ARCH_ARM32 || ARCH_ARM64 */\n\n#endif /* LIB_ARM_CPU_FEATURES_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/crc32_impl.h",
    "content": "/*\n * arm/crc32_impl.h - ARM implementations of the gzip CRC-32 algorithm\n *\n * Copyright 2022 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_ARM_CRC32_IMPL_H\n#define LIB_ARM_CRC32_IMPL_H\n\n#include \"cpu_features.h\"\n\n/*\n * crc32_arm_crc() - implementation using crc32 instructions (only)\n *\n * In general this implementation is straightforward.  However, naive use of the\n * crc32 instructions is serial: one of the two inputs to each crc32 instruction\n * is the output of the previous one.  To take advantage of CPUs that can\n * execute multiple crc32 instructions in parallel, when possible we interleave\n * the checksumming of several adjacent chunks, then combine their CRCs.\n *\n * However, without pmull, combining CRCs is fairly slow.  So in this pmull-less\n * version, we only use a large chunk length, and thus we only do chunked\n * processing if there is a lot of data to checksum.  This also means that a\n * variable chunk length wouldn't help much, so we just support a fixed length.\n */\n#if HAVE_CRC32_INTRIN\n#  ifdef __clang__\n#    define ATTRIBUTES\t_target_attribute(\"crc\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"+crc\")\n#  endif\n\n/*\n * Combine the CRCs for 4 adjacent chunks of length L = CRC32_FIXED_CHUNK_LEN\n * bytes each by computing:\n *\n *\t[ crc0*x^(3*8*L) + crc1*x^(2*8*L) + crc2*x^(1*8*L) + crc3 ] mod G(x)\n *\n * This has been optimized in several ways:\n *\n *    - The needed multipliers (x to some power, reduced mod G(x)) were\n *\tprecomputed.\n *\n *    - The 3 multiplications are interleaved.\n *\n *    - The reduction mod G(x) is delayed to the end and done using __crc32d.\n *\tNote that the use of __crc32d introduces an extra factor of x^32.  To\n *\tcancel that out along with the extra factor of x^1 that gets introduced\n *\tbecause of how the 63-bit products are aligned in their 64-bit integers,\n *\tthe multipliers are actually x^(j*8*L - 33) instead of x^(j*8*L).\n */\nstatic forceinline ATTRIBUTES u32\ncombine_crcs_slow(u32 crc0, u32 crc1, u32 crc2, u32 crc3)\n{\n\tu64 res0 = 0, res1 = 0, res2 = 0;\n\tint i;\n\n\t/* Multiply crc{0,1,2} by CRC32_FIXED_CHUNK_MULT_{3,2,1}. */\n\tfor (i = 0; i < 32; i++) {\n\t\tif (CRC32_FIXED_CHUNK_MULT_3 & (1U << i))\n\t\t\tres0 ^= (u64)crc0 << i;\n\t\tif (CRC32_FIXED_CHUNK_MULT_2 & (1U << i))\n\t\t\tres1 ^= (u64)crc1 << i;\n\t\tif (CRC32_FIXED_CHUNK_MULT_1 & (1U << i))\n\t\t\tres2 ^= (u64)crc2 << i;\n\t}\n\t/* Add the different parts and reduce mod G(x). */\n\treturn __crc32d(0, res0 ^ res1 ^ res2) ^ crc3;\n}\n\n#define crc32_arm_crc\tcrc32_arm_crc\nstatic ATTRIBUTES u32\ncrc32_arm_crc(u32 crc, const u8 *p, size_t len)\n{\n\tif (len >= 64) {\n\t\tconst size_t align = -(uintptr_t)p & 7;\n\n\t\t/* Align p to the next 8-byte boundary. */\n\t\tif (align) {\n\t\t\tif (align & 1)\n\t\t\t\tcrc = __crc32b(crc, *p++);\n\t\t\tif (align & 2) {\n\t\t\t\tcrc = __crc32h(crc, le16_bswap(*(u16 *)p));\n\t\t\t\tp += 2;\n\t\t\t}\n\t\t\tif (align & 4) {\n\t\t\t\tcrc = __crc32w(crc, le32_bswap(*(u32 *)p));\n\t\t\t\tp += 4;\n\t\t\t}\n\t\t\tlen -= align;\n\t\t}\n\t\t/*\n\t\t * Interleave the processing of multiple adjacent data chunks to\n\t\t * take advantage of instruction-level parallelism.\n\t\t *\n\t\t * Some CPUs don't prefetch the data if it's being fetched in\n\t\t * multiple interleaved streams, so do explicit prefetching.\n\t\t */\n\t\twhile (len >= CRC32_NUM_CHUNKS * CRC32_FIXED_CHUNK_LEN) {\n\t\t\tconst u64 *wp0 = (const u64 *)p;\n\t\t\tconst u64 * const wp0_end =\n\t\t\t\t(const u64 *)(p + CRC32_FIXED_CHUNK_LEN);\n\t\t\tu32 crc1 = 0, crc2 = 0, crc3 = 0;\n\n\t\t\tSTATIC_ASSERT(CRC32_NUM_CHUNKS == 4);\n\t\t\tSTATIC_ASSERT(CRC32_FIXED_CHUNK_LEN % (4 * 8) == 0);\n\t\t\tdo {\n\t\t\t\tprefetchr(&wp0[64 + 0*CRC32_FIXED_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 1*CRC32_FIXED_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 2*CRC32_FIXED_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 3*CRC32_FIXED_CHUNK_LEN/8]);\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_FIXED_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t} while (wp0 != wp0_end);\n\t\t\tcrc = combine_crcs_slow(crc, crc1, crc2, crc3);\n\t\t\tp += CRC32_NUM_CHUNKS * CRC32_FIXED_CHUNK_LEN;\n\t\t\tlen -= CRC32_NUM_CHUNKS * CRC32_FIXED_CHUNK_LEN;\n\t\t}\n\t\t/*\n\t\t * Due to the large fixed chunk length used above, there might\n\t\t * still be a lot of data left.  So use a 64-byte loop here,\n\t\t * instead of a loop that is less unrolled.\n\t\t */\n\t\twhile (len >= 64) {\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 0)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 8)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 16)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 24)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 32)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 40)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 48)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 56)));\n\t\t\tp += 64;\n\t\t\tlen -= 64;\n\t\t}\n\t}\n\tif (len & 32) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 16));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 24));\n\t\tp += 32;\n\t}\n\tif (len & 16) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\tp += 16;\n\t}\n\tif (len & 8) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p));\n\t\tp += 8;\n\t}\n\tif (len & 4) {\n\t\tcrc = __crc32w(crc, get_unaligned_le32(p));\n\t\tp += 4;\n\t}\n\tif (len & 2) {\n\t\tcrc = __crc32h(crc, get_unaligned_le16(p));\n\t\tp += 2;\n\t}\n\tif (len & 1)\n\t\tcrc = __crc32b(crc, *p);\n\treturn crc;\n}\n#undef ATTRIBUTES\n#endif /* crc32_arm_crc() */\n\n/*\n * crc32_arm_crc_pmullcombine() - implementation using crc32 instructions, plus\n *\tpmull instructions for CRC combining\n *\n * This is similar to crc32_arm_crc(), but it enables the use of pmull\n * (carryless multiplication) instructions for the steps where the CRCs of\n * adjacent data chunks are combined.  As this greatly speeds up CRC\n * combination, this implementation also differs from crc32_arm_crc() in that it\n * uses a variable chunk length which can get fairly small.  The precomputed\n * multipliers needed for the selected chunk length are loaded from a table.\n *\n * Note that pmull is used here only for combining the CRCs of separately\n * checksummed chunks, not for folding the data itself.  See crc32_arm_pmull*()\n * for implementations that use pmull for folding the data itself.\n */\n#if HAVE_CRC32_INTRIN && HAVE_PMULL_INTRIN\n#  ifdef __clang__\n#    define ATTRIBUTES\t_target_attribute(\"crc,aes\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"+crc,+crypto\")\n#  endif\n\n/* Do carryless multiplication of two 32-bit values. */\nstatic forceinline ATTRIBUTES u64\nclmul_u32(u32 a, u32 b)\n{\n\tuint64x2_t res = vreinterpretq_u64_p128(\n\t\t\t\tcompat_vmull_p64((poly64_t)a, (poly64_t)b));\n\n\treturn vgetq_lane_u64(res, 0);\n}\n\n/*\n * Like combine_crcs_slow(), but uses vmull_p64 to do the multiplications more\n * quickly, and supports a variable chunk length.  The chunk length is\n * 'i * CRC32_MIN_VARIABLE_CHUNK_LEN'\n * where 1 <= i < ARRAY_LEN(crc32_mults_for_chunklen).\n */\nstatic forceinline ATTRIBUTES u32\ncombine_crcs_fast(u32 crc0, u32 crc1, u32 crc2, u32 crc3, size_t i)\n{\n\tu64 res0 = clmul_u32(crc0, crc32_mults_for_chunklen[i][0]);\n\tu64 res1 = clmul_u32(crc1, crc32_mults_for_chunklen[i][1]);\n\tu64 res2 = clmul_u32(crc2, crc32_mults_for_chunklen[i][2]);\n\n\treturn __crc32d(0, res0 ^ res1 ^ res2) ^ crc3;\n}\n\n#define crc32_arm_crc_pmullcombine\tcrc32_arm_crc_pmullcombine\nstatic ATTRIBUTES u32\ncrc32_arm_crc_pmullcombine(u32 crc, const u8 *p, size_t len)\n{\n\tconst size_t align = -(uintptr_t)p & 7;\n\n\tif (len >= align + CRC32_NUM_CHUNKS * CRC32_MIN_VARIABLE_CHUNK_LEN) {\n\t\t/* Align p to the next 8-byte boundary. */\n\t\tif (align) {\n\t\t\tif (align & 1)\n\t\t\t\tcrc = __crc32b(crc, *p++);\n\t\t\tif (align & 2) {\n\t\t\t\tcrc = __crc32h(crc, le16_bswap(*(u16 *)p));\n\t\t\t\tp += 2;\n\t\t\t}\n\t\t\tif (align & 4) {\n\t\t\t\tcrc = __crc32w(crc, le32_bswap(*(u32 *)p));\n\t\t\t\tp += 4;\n\t\t\t}\n\t\t\tlen -= align;\n\t\t}\n\t\t/*\n\t\t * Handle CRC32_MAX_VARIABLE_CHUNK_LEN specially, so that better\n\t\t * code is generated for it.\n\t\t */\n\t\twhile (len >= CRC32_NUM_CHUNKS * CRC32_MAX_VARIABLE_CHUNK_LEN) {\n\t\t\tconst u64 *wp0 = (const u64 *)p;\n\t\t\tconst u64 * const wp0_end =\n\t\t\t\t(const u64 *)(p + CRC32_MAX_VARIABLE_CHUNK_LEN);\n\t\t\tu32 crc1 = 0, crc2 = 0, crc3 = 0;\n\n\t\t\tSTATIC_ASSERT(CRC32_NUM_CHUNKS == 4);\n\t\t\tSTATIC_ASSERT(CRC32_MAX_VARIABLE_CHUNK_LEN % (4 * 8) == 0);\n\t\t\tdo {\n\t\t\t\tprefetchr(&wp0[64 + 0*CRC32_MAX_VARIABLE_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 1*CRC32_MAX_VARIABLE_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 2*CRC32_MAX_VARIABLE_CHUNK_LEN/8]);\n\t\t\t\tprefetchr(&wp0[64 + 3*CRC32_MAX_VARIABLE_CHUNK_LEN/8]);\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(wp0[0*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(wp0[1*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(wp0[2*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(wp0[3*CRC32_MAX_VARIABLE_CHUNK_LEN/8]));\n\t\t\t\twp0++;\n\t\t\t} while (wp0 != wp0_end);\n\t\t\tcrc = combine_crcs_fast(crc, crc1, crc2, crc3,\n\t\t\t\t\t\tARRAY_LEN(crc32_mults_for_chunklen) - 1);\n\t\t\tp += CRC32_NUM_CHUNKS * CRC32_MAX_VARIABLE_CHUNK_LEN;\n\t\t\tlen -= CRC32_NUM_CHUNKS * CRC32_MAX_VARIABLE_CHUNK_LEN;\n\t\t}\n\t\t/* Handle up to one variable-length chunk. */\n\t\tif (len >= CRC32_NUM_CHUNKS * CRC32_MIN_VARIABLE_CHUNK_LEN) {\n\t\t\tconst size_t i = len / (CRC32_NUM_CHUNKS *\n\t\t\t\t\t\tCRC32_MIN_VARIABLE_CHUNK_LEN);\n\t\t\tconst size_t chunk_len =\n\t\t\t\ti * CRC32_MIN_VARIABLE_CHUNK_LEN;\n\t\t\tconst u64 *wp0 = (const u64 *)(p + 0*chunk_len);\n\t\t\tconst u64 *wp1 = (const u64 *)(p + 1*chunk_len);\n\t\t\tconst u64 *wp2 = (const u64 *)(p + 2*chunk_len);\n\t\t\tconst u64 *wp3 = (const u64 *)(p + 3*chunk_len);\n\t\t\tconst u64 * const wp0_end = wp1;\n\t\t\tu32 crc1 = 0, crc2 = 0, crc3 = 0;\n\n\t\t\tSTATIC_ASSERT(CRC32_NUM_CHUNKS == 4);\n\t\t\tSTATIC_ASSERT(CRC32_MIN_VARIABLE_CHUNK_LEN % (4 * 8) == 0);\n\t\t\tdo {\n\t\t\t\tprefetchr(wp0 + 64);\n\t\t\t\tprefetchr(wp1 + 64);\n\t\t\t\tprefetchr(wp2 + 64);\n\t\t\t\tprefetchr(wp3 + 64);\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(*wp0++));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(*wp1++));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(*wp2++));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(*wp3++));\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(*wp0++));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(*wp1++));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(*wp2++));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(*wp3++));\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(*wp0++));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(*wp1++));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(*wp2++));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(*wp3++));\n\t\t\t\tcrc  = __crc32d(crc,  le64_bswap(*wp0++));\n\t\t\t\tcrc1 = __crc32d(crc1, le64_bswap(*wp1++));\n\t\t\t\tcrc2 = __crc32d(crc2, le64_bswap(*wp2++));\n\t\t\t\tcrc3 = __crc32d(crc3, le64_bswap(*wp3++));\n\t\t\t} while (wp0 != wp0_end);\n\t\t\tcrc = combine_crcs_fast(crc, crc1, crc2, crc3, i);\n\t\t\tp += CRC32_NUM_CHUNKS * chunk_len;\n\t\t\tlen -= CRC32_NUM_CHUNKS * chunk_len;\n\t\t}\n\n\t\twhile (len >= 32) {\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 0)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 8)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 16)));\n\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)(p + 24)));\n\t\t\tp += 32;\n\t\t\tlen -= 32;\n\t\t}\n\t} else {\n\t\twhile (len >= 32) {\n\t\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 16));\n\t\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 24));\n\t\t\tp += 32;\n\t\t\tlen -= 32;\n\t\t}\n\t}\n\tif (len & 16) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\tp += 16;\n\t}\n\tif (len & 8) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p));\n\t\tp += 8;\n\t}\n\tif (len & 4) {\n\t\tcrc = __crc32w(crc, get_unaligned_le32(p));\n\t\tp += 4;\n\t}\n\tif (len & 2) {\n\t\tcrc = __crc32h(crc, get_unaligned_le16(p));\n\t\tp += 2;\n\t}\n\tif (len & 1)\n\t\tcrc = __crc32b(crc, *p);\n\treturn crc;\n}\n#undef ATTRIBUTES\n#endif /* crc32_arm_crc_pmullcombine() */\n\n/*\n * crc32_arm_pmullx4() - implementation using \"folding\" with pmull instructions\n *\n * This implementation is intended for CPUs that support pmull instructions but\n * not crc32 instructions.\n */\n#if HAVE_PMULL_INTRIN\n#  define crc32_arm_pmullx4\tcrc32_arm_pmullx4\n#  define SUFFIX\t\t\t _pmullx4\n#  ifdef __clang__\n     /*\n      * This used to use \"crypto\", but that stopped working with clang 16.\n      * Now only \"aes\" works.  \"aes\" works with older versions too, so use\n      * that.  No \"+\" prefix; clang 15 and earlier doesn't accept that.\n      */\n#    define ATTRIBUTES\t_target_attribute(\"aes\")\n#  else\n     /*\n      * With gcc, only \"+crypto\" works.  Both the \"+\" prefix and the\n      * \"crypto\" (not \"aes\") are essential...\n      */\n#    define ATTRIBUTES\t_target_attribute(\"+crypto\")\n#  endif\n#  define ENABLE_EOR3\t\t0\n#  include \"crc32_pmull_helpers.h\"\n\nstatic ATTRIBUTES u32\ncrc32_arm_pmullx4(u32 crc, const u8 *p, size_t len)\n{\n\tstatic const u64 _aligned_attribute(16) mults[3][2] = {\n\t\t{ CRC32_X159_MODG, CRC32_X95_MODG },  /* 1 vecs */\n\t\t{ CRC32_X543_MODG, CRC32_X479_MODG }, /* 4 vecs */\n\t\t{ CRC32_X287_MODG, CRC32_X223_MODG }, /* 2 vecs */\n\t};\n\tstatic const u64 _aligned_attribute(16) barrett_consts[3][2] = {\n\t\t{ CRC32_X95_MODG, },\n\t\t{ CRC32_BARRETT_CONSTANT_1, },\n\t\t{ CRC32_BARRETT_CONSTANT_2, },\n\t};\n\tconst poly64x2_t multipliers_1 = load_multipliers(mults[0]);\n\tuint8x16_t v0, v1, v2, v3;\n\n\tif (len < 64 + 15) {\n\t\tif (len < 16)\n\t\t\treturn crc32_slice1(crc, p, len);\n\t\tv0 = veorq_u8(vld1q_u8(p), u32_to_bytevec(crc));\n\t\tp += 16;\n\t\tlen -= 16;\n\t\twhile (len >= 16) {\n\t\t\tv0 = fold_vec(v0, vld1q_u8(p), multipliers_1);\n\t\t\tp += 16;\n\t\t\tlen -= 16;\n\t\t}\n\t} else {\n\t\tconst poly64x2_t multipliers_4 = load_multipliers(mults[1]);\n\t\tconst poly64x2_t multipliers_2 = load_multipliers(mults[2]);\n\t\tconst size_t align = -(uintptr_t)p & 15;\n\t\tconst uint8x16_t *vp;\n\n\t\tv0 = veorq_u8(vld1q_u8(p), u32_to_bytevec(crc));\n\t\tp += 16;\n\t\t/* Align p to the next 16-byte boundary. */\n\t\tif (align) {\n\t\t\tv0 = fold_partial_vec(v0, p, align, multipliers_1);\n\t\t\tp += align;\n\t\t\tlen -= align;\n\t\t}\n\t\tvp = (const uint8x16_t *)p;\n\t\tv1 = *vp++;\n\t\tv2 = *vp++;\n\t\tv3 = *vp++;\n\t\twhile (len >= 64 + 64) {\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_4);\n\t\t\tv1 = fold_vec(v1, *vp++, multipliers_4);\n\t\t\tv2 = fold_vec(v2, *vp++, multipliers_4);\n\t\t\tv3 = fold_vec(v3, *vp++, multipliers_4);\n\t\t\tlen -= 64;\n\t\t}\n\t\tv0 = fold_vec(v0, v2, multipliers_2);\n\t\tv1 = fold_vec(v1, v3, multipliers_2);\n\t\tif (len & 32) {\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_2);\n\t\t\tv1 = fold_vec(v1, *vp++, multipliers_2);\n\t\t}\n\t\tv0 = fold_vec(v0, v1, multipliers_1);\n\t\tif (len & 16)\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_1);\n\t\tp = (const u8 *)vp;\n\t\tlen &= 15;\n\t}\n\n\t/* Handle any remaining partial block now before reducing to 32 bits. */\n\tif (len)\n\t\tv0 = fold_partial_vec(v0, p, len, multipliers_1);\n\n\t/* Reduce to 32 bits, following lib/x86/crc32_pclmul_template.h */\n\tv0 = veorq_u8(clmul_low(v0, load_multipliers(barrett_consts[0])),\n\t\t      vextq_u8(v0, vdupq_n_u8(0), 8));\n\tv1 = clmul_low(v0, load_multipliers(barrett_consts[1]));\n\tv1 = clmul_low(v1, load_multipliers(barrett_consts[2]));\n\tv0 = veorq_u8(v0, v1);\n\treturn vgetq_lane_u32(vreinterpretq_u32_u8(v0), 2);\n}\n#undef SUFFIX\n#undef ATTRIBUTES\n#undef ENABLE_EOR3\n#endif /* crc32_arm_pmullx4() */\n\n/*\n * crc32_arm_pmullx12_crc() - large-stride implementation using \"folding\" with\n *\tpmull instructions, where crc32 instructions are also available\n *\n * See crc32_pmull_wide.h for explanation.\n */\n#if HAVE_PMULL_INTRIN && HAVE_CRC32_INTRIN\n#  define crc32_arm_pmullx12_crc\tcrc32_arm_pmullx12_crc\n#  define SUFFIX\t\t\t\t _pmullx12_crc\n#  ifdef __clang__\n#    define ATTRIBUTES\t_target_attribute(\"aes,crc\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"+crypto,+crc\")\n#  endif\n#  define ENABLE_EOR3\t0\n#  include \"crc32_pmull_wide.h\"\n#endif\n\n/*\n * crc32_arm_pmullx12_crc_eor3()\n *\n * This like crc32_arm_pmullx12_crc(), but it adds the eor3 instruction (from\n * the sha3 extension) for even better performance.\n */\n#if HAVE_PMULL_INTRIN && HAVE_CRC32_INTRIN && HAVE_SHA3_INTRIN && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_SHA3)\n#  define crc32_arm_pmullx12_crc_eor3\tcrc32_arm_pmullx12_crc_eor3\n#  define SUFFIX\t\t\t\t _pmullx12_crc_eor3\n#  ifdef __clang__\n#    define ATTRIBUTES\t_target_attribute(\"aes,crc,sha3\")\n   /*\n    * Both gcc and binutils originally considered sha3 to depend on\n    * arch=armv8.2-a or later.  This was fixed in gcc 13.2 by commit\n    * 9aac37ab8a7b (\"aarch64: Remove architecture dependencies from intrinsics\")\n    * and in binutils 2.41 by commit 205e4380c800 (\"aarch64: Remove version\n    * dependencies from features\").  Unfortunately, always using arch=armv8.2-a\n    * causes build errors with some compiler options because it may reduce the\n    * arch rather than increase it.  Therefore we try to omit the arch whenever\n    * possible.  If gcc is 14 or later, then both gcc and binutils are probably\n    * fixed, so we omit the arch.  We also omit the arch if a feature that\n    * depends on armv8.2-a or later (in gcc 13.1 and earlier) is present.\n    */\n#  elif GCC_PREREQ(14, 0) || defined(__ARM_FEATURE_JCVT) \\\n\t\t\t  || defined(__ARM_FEATURE_DOTPROD)\n#    define ATTRIBUTES\t_target_attribute(\"+crypto,+crc,+sha3\")\n#  else\n#    define ATTRIBUTES\t_target_attribute(\"arch=armv8.2-a+crypto+crc+sha3\")\n#  endif\n#  define ENABLE_EOR3\t1\n#  include \"crc32_pmull_wide.h\"\n#endif\n\nstatic inline crc32_func_t\narch_select_crc32_func(void)\n{\n\tconst u32 features MAYBE_UNUSED = get_arm_cpu_features();\n\n#ifdef crc32_arm_pmullx12_crc_eor3\n\tif ((features & ARM_CPU_FEATURE_PREFER_PMULL) &&\n\t    HAVE_PMULL(features) && HAVE_CRC32(features) && HAVE_SHA3(features))\n\t\treturn crc32_arm_pmullx12_crc_eor3;\n#endif\n#ifdef crc32_arm_pmullx12_crc\n\tif ((features & ARM_CPU_FEATURE_PREFER_PMULL) &&\n\t    HAVE_PMULL(features) && HAVE_CRC32(features))\n\t\treturn crc32_arm_pmullx12_crc;\n#endif\n#ifdef crc32_arm_crc_pmullcombine\n\tif (HAVE_CRC32(features) && HAVE_PMULL(features))\n\t\treturn crc32_arm_crc_pmullcombine;\n#endif\n#ifdef crc32_arm_crc\n\tif (HAVE_CRC32(features))\n\t\treturn crc32_arm_crc;\n#endif\n#ifdef crc32_arm_pmullx4\n\tif (HAVE_PMULL(features))\n\t\treturn crc32_arm_pmullx4;\n#endif\n\treturn NULL;\n}\n#define arch_select_crc32_func\tarch_select_crc32_func\n\n#endif /* LIB_ARM_CRC32_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/crc32_pmull_helpers.h",
    "content": "/*\n * arm/crc32_pmull_helpers.h - helper functions for CRC-32 folding with PMULL\n *\n * Copyright 2022 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * This file is a \"template\" for instantiating helper functions for CRC folding\n * with pmull instructions.  It accepts the following parameters:\n *\n * SUFFIX:\n *\tName suffix to append to all instantiated functions.\n * ATTRIBUTES:\n *\tTarget function attributes to use.\n * ENABLE_EOR3:\n *\tUse the eor3 instruction (from the sha3 extension).\n */\n\n/* Create a vector with 'a' in the first 4 bytes, and the rest zeroed out. */\n#undef u32_to_bytevec\nstatic forceinline ATTRIBUTES uint8x16_t\nADD_SUFFIX(u32_to_bytevec)(u32 a)\n{\n\treturn vreinterpretq_u8_u32(vsetq_lane_u32(a, vdupq_n_u32(0), 0));\n}\n#define u32_to_bytevec\tADD_SUFFIX(u32_to_bytevec)\n\n/* Load two 64-bit values into a vector. */\n#undef load_multipliers\nstatic forceinline ATTRIBUTES poly64x2_t\nADD_SUFFIX(load_multipliers)(const u64 p[2])\n{\n\treturn vreinterpretq_p64_u64(vld1q_u64(p));\n}\n#define load_multipliers\tADD_SUFFIX(load_multipliers)\n\n/* Do carryless multiplication of the low halves of two vectors. */\n#undef clmul_low\nstatic forceinline ATTRIBUTES uint8x16_t\nADD_SUFFIX(clmul_low)(uint8x16_t a, poly64x2_t b)\n{\n\treturn vreinterpretq_u8_p128(\n\t\t     compat_vmull_p64(vgetq_lane_p64(vreinterpretq_p64_u8(a), 0),\n\t\t\t\t      vgetq_lane_p64(b, 0)));\n}\n#define clmul_low\tADD_SUFFIX(clmul_low)\n\n/* Do carryless multiplication of the high halves of two vectors. */\n#undef clmul_high\nstatic forceinline ATTRIBUTES uint8x16_t\nADD_SUFFIX(clmul_high)(uint8x16_t a, poly64x2_t b)\n{\n#ifdef __clang__\n\t/*\n\t * Use inline asm to ensure that pmull2 is really used.  This works\n\t * around clang bug https://github.com/llvm/llvm-project/issues/52868.\n\t */\n\tuint8x16_t res;\n\n\t__asm__(\"pmull2 %0.1q, %1.2d, %2.2d\" : \"=w\" (res) : \"w\" (a), \"w\" (b));\n\treturn res;\n#else\n\treturn vreinterpretq_u8_p128(vmull_high_p64(vreinterpretq_p64_u8(a), b));\n#endif\n}\n#define clmul_high\tADD_SUFFIX(clmul_high)\n\n#undef eor3\nstatic forceinline ATTRIBUTES uint8x16_t\nADD_SUFFIX(eor3)(uint8x16_t a, uint8x16_t b, uint8x16_t c)\n{\n#if ENABLE_EOR3\n\treturn veor3q_u8(a, b, c);\n#else\n\treturn veorq_u8(veorq_u8(a, b), c);\n#endif\n}\n#define eor3\tADD_SUFFIX(eor3)\n\n#undef fold_vec\nstatic forceinline ATTRIBUTES uint8x16_t\nADD_SUFFIX(fold_vec)(uint8x16_t src, uint8x16_t dst, poly64x2_t multipliers)\n{\n\tuint8x16_t a = clmul_low(src, multipliers);\n\tuint8x16_t b = clmul_high(src, multipliers);\n\n\treturn eor3(a, b, dst);\n}\n#define fold_vec\tADD_SUFFIX(fold_vec)\n\n/*\n * Given v containing a 16-byte polynomial, and a pointer 'p' that points to the\n * next '1 <= len <= 15' data bytes, rearrange the concatenation of v and the\n * data into vectors x0 and x1 that contain 'len' bytes and 16 bytes,\n * respectively.  Then fold x0 into x1 and return the result.  Assumes that\n * 'p + len - 16' is in-bounds.\n */\n#undef fold_partial_vec\nstatic forceinline ATTRIBUTES MAYBE_UNUSED uint8x16_t\nADD_SUFFIX(fold_partial_vec)(uint8x16_t v, const u8 *p, size_t len,\n\t\t\t     poly64x2_t multipliers_1)\n{\n\t/*\n\t * vqtbl1q_u8(v, shift_tab[len..len+15]) left shifts v by 16-len bytes.\n\t * vqtbl1q_u8(v, shift_tab[len+16..len+31]) right shifts v by len bytes.\n\t */\n\tstatic const u8 shift_tab[48] = {\n\t\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n\t\t0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\n\t\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t};\n\tconst uint8x16_t lshift = vld1q_u8(&shift_tab[len]);\n\tconst uint8x16_t rshift = vld1q_u8(&shift_tab[len + 16]);\n\tuint8x16_t x0, x1, bsl_mask;\n\n\t/* x0 = v left-shifted by '16 - len' bytes */\n\tx0 = vqtbl1q_u8(v, lshift);\n\n\t/* Create a vector of '16 - len' 0x00 bytes, then 'len' 0xff bytes. */\n\tbsl_mask = vreinterpretq_u8_s8(\n\t\t\tvshrq_n_s8(vreinterpretq_s8_u8(rshift), 7));\n\n\t/*\n\t * x1 = the last '16 - len' bytes from v (i.e. v right-shifted by 'len'\n\t * bytes) followed by the remaining data.\n\t */\n\tx1 = vbslq_u8(bsl_mask /* 0 bits select from arg3, 1 bits from arg2 */,\n\t\t      vld1q_u8(p + len - 16), vqtbl1q_u8(v, rshift));\n\n\treturn fold_vec(x0, x1, multipliers_1);\n}\n#define fold_partial_vec\tADD_SUFFIX(fold_partial_vec)\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/crc32_pmull_wide.h",
    "content": "/*\n * arm/crc32_pmull_wide.h - gzip CRC-32 with PMULL (extra-wide version)\n *\n * Copyright 2022 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * This file is a \"template\" for instantiating PMULL-based crc32_arm functions.\n * The \"parameters\" are:\n *\n * SUFFIX:\n *\tName suffix to append to all instantiated functions.\n * ATTRIBUTES:\n *\tTarget function attributes to use.\n * ENABLE_EOR3:\n *\tUse the eor3 instruction (from the sha3 extension).\n *\n * This is the extra-wide version; it uses an unusually large stride length of\n * 12, and it assumes that crc32 instructions are available too.  It's intended\n * for powerful CPUs that support both pmull and crc32 instructions, but where\n * throughput of pmull and xor (given enough instructions issued in parallel) is\n * significantly higher than that of crc32, thus making the crc32 instructions\n * (counterintuitively) not actually the fastest way to compute the CRC-32.  The\n * Apple M1 processor is an example of such a CPU.\n */\n\n#include \"crc32_pmull_helpers.h\"\n\nstatic ATTRIBUTES u32\nADD_SUFFIX(crc32_arm)(u32 crc, const u8 *p, size_t len)\n{\n\tuint8x16_t v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11;\n\n\tif (len < 3 * 192) {\n\t\tstatic const u64 _aligned_attribute(16) mults[3][2] = {\n\t\t\t{ CRC32_X543_MODG, CRC32_X479_MODG }, /* 4 vecs */\n\t\t\t{ CRC32_X287_MODG, CRC32_X223_MODG }, /* 2 vecs */\n\t\t\t{ CRC32_X159_MODG, CRC32_X95_MODG },  /* 1 vecs */\n\t\t};\n\t\tpoly64x2_t multipliers_4, multipliers_2, multipliers_1;\n\n\t\tif (len < 64)\n\t\t\tgoto tail;\n\t\tmultipliers_4 = load_multipliers(mults[0]);\n\t\tmultipliers_2 = load_multipliers(mults[1]);\n\t\tmultipliers_1 = load_multipliers(mults[2]);\n\t\t/*\n\t\t * Short length; don't bother aligning the pointer, and fold\n\t\t * 64 bytes (4 vectors) at a time, at most.\n\t\t */\n\t\tv0 = veorq_u8(vld1q_u8(p + 0), u32_to_bytevec(crc));\n\t\tv1 = vld1q_u8(p + 16);\n\t\tv2 = vld1q_u8(p + 32);\n\t\tv3 = vld1q_u8(p + 48);\n\t\tp += 64;\n\t\tlen -= 64;\n\t\twhile (len >= 64) {\n\t\t\tv0 = fold_vec(v0, vld1q_u8(p + 0), multipliers_4);\n\t\t\tv1 = fold_vec(v1, vld1q_u8(p + 16), multipliers_4);\n\t\t\tv2 = fold_vec(v2, vld1q_u8(p + 32), multipliers_4);\n\t\t\tv3 = fold_vec(v3, vld1q_u8(p + 48), multipliers_4);\n\t\t\tp += 64;\n\t\t\tlen -= 64;\n\t\t}\n\t\tv0 = fold_vec(v0, v2, multipliers_2);\n\t\tv1 = fold_vec(v1, v3, multipliers_2);\n\t\tif (len >= 32) {\n\t\t\tv0 = fold_vec(v0, vld1q_u8(p + 0), multipliers_2);\n\t\t\tv1 = fold_vec(v1, vld1q_u8(p + 16), multipliers_2);\n\t\t\tp += 32;\n\t\t\tlen -= 32;\n\t\t}\n\t\tv0 = fold_vec(v0, v1, multipliers_1);\n\t} else {\n\t\tstatic const u64 _aligned_attribute(16) mults[4][2] = {\n\t\t\t{ CRC32_X1567_MODG, CRC32_X1503_MODG }, /* 12 vecs */\n\t\t\t{ CRC32_X799_MODG, CRC32_X735_MODG },   /* 6 vecs */\n\t\t\t{ CRC32_X415_MODG, CRC32_X351_MODG },   /* 3 vecs */\n\t\t\t{ CRC32_X159_MODG, CRC32_X95_MODG },    /* 1 vecs */\n\t\t};\n\t\tconst poly64x2_t multipliers_12 = load_multipliers(mults[0]);\n\t\tconst poly64x2_t multipliers_6 = load_multipliers(mults[1]);\n\t\tconst poly64x2_t multipliers_3 = load_multipliers(mults[2]);\n\t\tconst poly64x2_t multipliers_1 = load_multipliers(mults[3]);\n\t\tconst size_t align = -(uintptr_t)p & 15;\n\t\tconst uint8x16_t *vp;\n\n\t\t/* Align p to the next 16-byte boundary. */\n\t\tif (align) {\n\t\t\tif (align & 1)\n\t\t\t\tcrc = __crc32b(crc, *p++);\n\t\t\tif (align & 2) {\n\t\t\t\tcrc = __crc32h(crc, le16_bswap(*(u16 *)p));\n\t\t\t\tp += 2;\n\t\t\t}\n\t\t\tif (align & 4) {\n\t\t\t\tcrc = __crc32w(crc, le32_bswap(*(u32 *)p));\n\t\t\t\tp += 4;\n\t\t\t}\n\t\t\tif (align & 8) {\n\t\t\t\tcrc = __crc32d(crc, le64_bswap(*(u64 *)p));\n\t\t\t\tp += 8;\n\t\t\t}\n\t\t\tlen -= align;\n\t\t}\n\t\tvp = (const uint8x16_t *)p;\n\t\tv0 = veorq_u8(*vp++, u32_to_bytevec(crc));\n\t\tv1 = *vp++;\n\t\tv2 = *vp++;\n\t\tv3 = *vp++;\n\t\tv4 = *vp++;\n\t\tv5 = *vp++;\n\t\tv6 = *vp++;\n\t\tv7 = *vp++;\n\t\tv8 = *vp++;\n\t\tv9 = *vp++;\n\t\tv10 = *vp++;\n\t\tv11 = *vp++;\n\t\tlen -= 192;\n\t\t/* Fold 192 bytes (12 vectors) at a time. */\n\t\tdo {\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_12);\n\t\t\tv1 = fold_vec(v1, *vp++, multipliers_12);\n\t\t\tv2 = fold_vec(v2, *vp++, multipliers_12);\n\t\t\tv3 = fold_vec(v3, *vp++, multipliers_12);\n\t\t\tv4 = fold_vec(v4, *vp++, multipliers_12);\n\t\t\tv5 = fold_vec(v5, *vp++, multipliers_12);\n\t\t\tv6 = fold_vec(v6, *vp++, multipliers_12);\n\t\t\tv7 = fold_vec(v7, *vp++, multipliers_12);\n\t\t\tv8 = fold_vec(v8, *vp++, multipliers_12);\n\t\t\tv9 = fold_vec(v9, *vp++, multipliers_12);\n\t\t\tv10 = fold_vec(v10, *vp++, multipliers_12);\n\t\t\tv11 = fold_vec(v11, *vp++, multipliers_12);\n\t\t\tlen -= 192;\n\t\t} while (len >= 192);\n\n\t\t/*\n\t\t * Fewer than 192 bytes left.  Fold v0-v11 down to just v0,\n\t\t * while processing up to 144 more bytes.\n\t\t */\n\t\tv0 = fold_vec(v0, v6, multipliers_6);\n\t\tv1 = fold_vec(v1, v7, multipliers_6);\n\t\tv2 = fold_vec(v2, v8, multipliers_6);\n\t\tv3 = fold_vec(v3, v9, multipliers_6);\n\t\tv4 = fold_vec(v4, v10, multipliers_6);\n\t\tv5 = fold_vec(v5, v11, multipliers_6);\n\t\tif (len >= 96) {\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_6);\n\t\t\tv1 = fold_vec(v1, *vp++, multipliers_6);\n\t\t\tv2 = fold_vec(v2, *vp++, multipliers_6);\n\t\t\tv3 = fold_vec(v3, *vp++, multipliers_6);\n\t\t\tv4 = fold_vec(v4, *vp++, multipliers_6);\n\t\t\tv5 = fold_vec(v5, *vp++, multipliers_6);\n\t\t\tlen -= 96;\n\t\t}\n\t\tv0 = fold_vec(v0, v3, multipliers_3);\n\t\tv1 = fold_vec(v1, v4, multipliers_3);\n\t\tv2 = fold_vec(v2, v5, multipliers_3);\n\t\tif (len >= 48) {\n\t\t\tv0 = fold_vec(v0, *vp++, multipliers_3);\n\t\t\tv1 = fold_vec(v1, *vp++, multipliers_3);\n\t\t\tv2 = fold_vec(v2, *vp++, multipliers_3);\n\t\t\tlen -= 48;\n\t\t}\n\t\tv0 = fold_vec(v0, v1, multipliers_1);\n\t\tv0 = fold_vec(v0, v2, multipliers_1);\n\t\tp = (const u8 *)vp;\n\t}\n\t/* Reduce 128 to 32 bits using crc32 instructions. */\n\tcrc = __crc32d(0, vgetq_lane_u64(vreinterpretq_u64_u8(v0), 0));\n\tcrc = __crc32d(crc, vgetq_lane_u64(vreinterpretq_u64_u8(v0), 1));\ntail:\n\t/* Finish up the remainder using crc32 instructions. */\n\tif (len & 32) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 16));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 24));\n\t\tp += 32;\n\t}\n\tif (len & 16) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 0));\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p + 8));\n\t\tp += 16;\n\t}\n\tif (len & 8) {\n\t\tcrc = __crc32d(crc, get_unaligned_le64(p));\n\t\tp += 8;\n\t}\n\tif (len & 4) {\n\t\tcrc = __crc32w(crc, get_unaligned_le32(p));\n\t\tp += 4;\n\t}\n\tif (len & 2) {\n\t\tcrc = __crc32h(crc, get_unaligned_le16(p));\n\t\tp += 2;\n\t}\n\tif (len & 1)\n\t\tcrc = __crc32b(crc, *p);\n\treturn crc;\n}\n\n#undef SUFFIX\n#undef ATTRIBUTES\n#undef ENABLE_EOR3\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/arm/matchfinder_impl.h",
    "content": "/*\n * arm/matchfinder_impl.h - ARM implementations of matchfinder functions\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_ARM_MATCHFINDER_IMPL_H\n#define LIB_ARM_MATCHFINDER_IMPL_H\n\n#include \"cpu_features.h\"\n\n#if HAVE_NEON_NATIVE\nstatic forceinline void\nmatchfinder_init_neon(mf_pos_t *data, size_t size)\n{\n\tint16x8_t *p = (int16x8_t *)data;\n\tint16x8_t v = vdupq_n_s16(MATCHFINDER_INITVAL);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\tp[0] = v;\n\t\tp[1] = v;\n\t\tp[2] = v;\n\t\tp[3] = v;\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_init matchfinder_init_neon\n\nstatic forceinline void\nmatchfinder_rebase_neon(mf_pos_t *data, size_t size)\n{\n\tint16x8_t *p = (int16x8_t *)data;\n\tint16x8_t v = vdupq_n_s16((u16)-MATCHFINDER_WINDOW_SIZE);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\tp[0] = vqaddq_s16(p[0], v);\n\t\tp[1] = vqaddq_s16(p[1], v);\n\t\tp[2] = vqaddq_s16(p[2], v);\n\t\tp[3] = vqaddq_s16(p[3], v);\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_rebase matchfinder_rebase_neon\n\n#endif /* HAVE_NEON_NATIVE */\n\n#endif /* LIB_ARM_MATCHFINDER_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/bt_matchfinder.h",
    "content": "/*\n * bt_matchfinder.h - Lempel-Ziv matchfinding with a hash table of binary trees\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * ----------------------------------------------------------------------------\n *\n * This is a Binary Trees (bt) based matchfinder.\n *\n * The main data structure is a hash table where each hash bucket contains a\n * binary tree of sequences whose first 4 bytes share the same hash code.  Each\n * sequence is identified by its starting position in the input buffer.  Each\n * binary tree is always sorted such that each left child represents a sequence\n * lexicographically lesser than its parent and each right child represents a\n * sequence lexicographically greater than its parent.\n *\n * The algorithm processes the input buffer sequentially.  At each byte\n * position, the hash code of the first 4 bytes of the sequence beginning at\n * that position (the sequence being matched against) is computed.  This\n * identifies the hash bucket to use for that position.  Then, a new binary tree\n * node is created to represent the current sequence.  Then, in a single tree\n * traversal, the hash bucket's binary tree is searched for matches and is\n * re-rooted at the new node.\n *\n * Compared to the simpler algorithm that uses linked lists instead of binary\n * trees (see hc_matchfinder.h), the binary tree version gains more information\n * at each node visitation.  Ideally, the binary tree version will examine only\n * 'log(n)' nodes to find the same matches that the linked list version will\n * find by examining 'n' nodes.  In addition, the binary tree version can\n * examine fewer bytes at each node by taking advantage of the common prefixes\n * that result from the sort order, whereas the linked list version may have to\n * examine up to the full length of the match at each node.\n *\n * However, it is not always best to use the binary tree version.  It requires\n * nearly twice as much memory as the linked list version, and it takes time to\n * keep the binary trees sorted, even at positions where the compressor does not\n * need matches.  Generally, when doing fast compression on small buffers,\n * binary trees are the wrong approach.  They are best suited for thorough\n * compression and/or large buffers.\n *\n * ----------------------------------------------------------------------------\n */\n\n#ifndef LIB_BT_MATCHFINDER_H\n#define LIB_BT_MATCHFINDER_H\n\n#include \"matchfinder_common.h\"\n\n#define BT_MATCHFINDER_HASH3_ORDER 16\n#define BT_MATCHFINDER_HASH3_WAYS  2\n#define BT_MATCHFINDER_HASH4_ORDER 16\n\n#define BT_MATCHFINDER_TOTAL_HASH_SIZE\t\t\\\n\t(((1UL << BT_MATCHFINDER_HASH3_ORDER) * BT_MATCHFINDER_HASH3_WAYS + \\\n\t  (1UL << BT_MATCHFINDER_HASH4_ORDER)) * sizeof(mf_pos_t))\n\n/* Representation of a match found by the bt_matchfinder  */\nstruct lz_match {\n\n\t/* The number of bytes matched.  */\n\tu16 length;\n\n\t/* The offset back from the current position that was matched.  */\n\tu16 offset;\n};\n\nstruct MATCHFINDER_ALIGNED bt_matchfinder {\n\n\t/* The hash table for finding length 3 matches  */\n\tmf_pos_t hash3_tab[1UL << BT_MATCHFINDER_HASH3_ORDER][BT_MATCHFINDER_HASH3_WAYS];\n\n\t/* The hash table which contains the roots of the binary trees for\n\t * finding length 4+ matches  */\n\tmf_pos_t hash4_tab[1UL << BT_MATCHFINDER_HASH4_ORDER];\n\n\t/* The child node references for the binary trees.  The left and right\n\t * children of the node for the sequence with position 'pos' are\n\t * 'child_tab[pos * 2]' and 'child_tab[pos * 2 + 1]', respectively.  */\n\tmf_pos_t child_tab[2UL * MATCHFINDER_WINDOW_SIZE];\n};\n\n/* Prepare the matchfinder for a new input buffer.  */\nstatic forceinline void\nbt_matchfinder_init(struct bt_matchfinder *mf)\n{\n\tSTATIC_ASSERT(BT_MATCHFINDER_TOTAL_HASH_SIZE %\n\t\t      MATCHFINDER_SIZE_ALIGNMENT == 0);\n\n\tmatchfinder_init((mf_pos_t *)mf, BT_MATCHFINDER_TOTAL_HASH_SIZE);\n}\n\nstatic forceinline void\nbt_matchfinder_slide_window(struct bt_matchfinder *mf)\n{\n\tSTATIC_ASSERT(sizeof(*mf) % MATCHFINDER_SIZE_ALIGNMENT == 0);\n\n\tmatchfinder_rebase((mf_pos_t *)mf, sizeof(*mf));\n}\n\nstatic forceinline mf_pos_t *\nbt_left_child(struct bt_matchfinder *mf, s32 node)\n{\n\treturn &mf->child_tab[2 * (node & (MATCHFINDER_WINDOW_SIZE - 1)) + 0];\n}\n\nstatic forceinline mf_pos_t *\nbt_right_child(struct bt_matchfinder *mf, s32 node)\n{\n\treturn &mf->child_tab[2 * (node & (MATCHFINDER_WINDOW_SIZE - 1)) + 1];\n}\n\n/* The minimum permissible value of 'max_len' for bt_matchfinder_get_matches()\n * and bt_matchfinder_skip_byte().  There must be sufficiently many bytes\n * remaining to load a 32-bit integer from the *next* position.  */\n#define BT_MATCHFINDER_REQUIRED_NBYTES\t5\n\n/* Advance the binary tree matchfinder by one byte, optionally recording\n * matches.  @record_matches should be a compile-time constant.  */\nstatic forceinline struct lz_match *\nbt_matchfinder_advance_one_byte(struct bt_matchfinder * const mf,\n\t\t\t\tconst u8 * const in_base,\n\t\t\t\tconst ptrdiff_t cur_pos,\n\t\t\t\tconst u32 max_len,\n\t\t\t\tconst u32 nice_len,\n\t\t\t\tconst u32 max_search_depth,\n\t\t\t\tu32 * const next_hashes,\n\t\t\t\tstruct lz_match *lz_matchptr,\n\t\t\t\tconst bool record_matches)\n{\n\tconst u8 *in_next = in_base + cur_pos;\n\tu32 depth_remaining = max_search_depth;\n\tconst s32 cutoff = cur_pos - MATCHFINDER_WINDOW_SIZE;\n\tu32 next_hashseq;\n\tu32 hash3;\n\tu32 hash4;\n\ts32 cur_node;\n#if BT_MATCHFINDER_HASH3_WAYS >= 2\n\ts32 cur_node_2;\n#endif\n\tconst u8 *matchptr;\n\tmf_pos_t *pending_lt_ptr, *pending_gt_ptr;\n\tu32 best_lt_len, best_gt_len;\n\tu32 len;\n\tu32 best_len = 3;\n\n\tSTATIC_ASSERT(BT_MATCHFINDER_HASH3_WAYS >= 1 &&\n\t\t      BT_MATCHFINDER_HASH3_WAYS <= 2);\n\n\tnext_hashseq = get_unaligned_le32(in_next + 1);\n\n\thash3 = next_hashes[0];\n\thash4 = next_hashes[1];\n\n\tnext_hashes[0] = lz_hash(next_hashseq & 0xFFFFFF, BT_MATCHFINDER_HASH3_ORDER);\n\tnext_hashes[1] = lz_hash(next_hashseq, BT_MATCHFINDER_HASH4_ORDER);\n\tprefetchw(&mf->hash3_tab[next_hashes[0]]);\n\tprefetchw(&mf->hash4_tab[next_hashes[1]]);\n\n\tcur_node = mf->hash3_tab[hash3][0];\n\tmf->hash3_tab[hash3][0] = cur_pos;\n#if BT_MATCHFINDER_HASH3_WAYS >= 2\n\tcur_node_2 = mf->hash3_tab[hash3][1];\n\tmf->hash3_tab[hash3][1] = cur_node;\n#endif\n\tif (record_matches && cur_node > cutoff) {\n\t\tu32 seq3 = load_u24_unaligned(in_next);\n\t\tif (seq3 == load_u24_unaligned(&in_base[cur_node])) {\n\t\t\tlz_matchptr->length = 3;\n\t\t\tlz_matchptr->offset = in_next - &in_base[cur_node];\n\t\t\tlz_matchptr++;\n\t\t}\n\t#if BT_MATCHFINDER_HASH3_WAYS >= 2\n\t\telse if (cur_node_2 > cutoff &&\n\t\t\tseq3 == load_u24_unaligned(&in_base[cur_node_2]))\n\t\t{\n\t\t\tlz_matchptr->length = 3;\n\t\t\tlz_matchptr->offset = in_next - &in_base[cur_node_2];\n\t\t\tlz_matchptr++;\n\t\t}\n\t#endif\n\t}\n\n\tcur_node = mf->hash4_tab[hash4];\n\tmf->hash4_tab[hash4] = cur_pos;\n\n\tpending_lt_ptr = bt_left_child(mf, cur_pos);\n\tpending_gt_ptr = bt_right_child(mf, cur_pos);\n\n\tif (cur_node <= cutoff) {\n\t\t*pending_lt_ptr = MATCHFINDER_INITVAL;\n\t\t*pending_gt_ptr = MATCHFINDER_INITVAL;\n\t\treturn lz_matchptr;\n\t}\n\n\tbest_lt_len = 0;\n\tbest_gt_len = 0;\n\tlen = 0;\n\n\tfor (;;) {\n\t\tmatchptr = &in_base[cur_node];\n\n\t\tif (matchptr[len] == in_next[len]) {\n\t\t\tlen = lz_extend(in_next, matchptr, len + 1, max_len);\n\t\t\tif (!record_matches || len > best_len) {\n\t\t\t\tif (record_matches) {\n\t\t\t\t\tbest_len = len;\n\t\t\t\t\tlz_matchptr->length = len;\n\t\t\t\t\tlz_matchptr->offset = in_next - matchptr;\n\t\t\t\t\tlz_matchptr++;\n\t\t\t\t}\n\t\t\t\tif (len >= nice_len) {\n\t\t\t\t\t*pending_lt_ptr = *bt_left_child(mf, cur_node);\n\t\t\t\t\t*pending_gt_ptr = *bt_right_child(mf, cur_node);\n\t\t\t\t\treturn lz_matchptr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (matchptr[len] < in_next[len]) {\n\t\t\t*pending_lt_ptr = cur_node;\n\t\t\tpending_lt_ptr = bt_right_child(mf, cur_node);\n\t\t\tcur_node = *pending_lt_ptr;\n\t\t\tbest_lt_len = len;\n\t\t\tif (best_gt_len < len)\n\t\t\t\tlen = best_gt_len;\n\t\t} else {\n\t\t\t*pending_gt_ptr = cur_node;\n\t\t\tpending_gt_ptr = bt_left_child(mf, cur_node);\n\t\t\tcur_node = *pending_gt_ptr;\n\t\t\tbest_gt_len = len;\n\t\t\tif (best_lt_len < len)\n\t\t\t\tlen = best_lt_len;\n\t\t}\n\n\t\tif (cur_node <= cutoff || !--depth_remaining) {\n\t\t\t*pending_lt_ptr = MATCHFINDER_INITVAL;\n\t\t\t*pending_gt_ptr = MATCHFINDER_INITVAL;\n\t\t\treturn lz_matchptr;\n\t\t}\n\t}\n}\n\n/*\n * Retrieve a list of matches with the current position.\n *\n * @mf\n *\tThe matchfinder structure.\n * @in_base\n *\tPointer to the next byte in the input buffer to process _at the last\n *\ttime bt_matchfinder_init() or bt_matchfinder_slide_window() was called_.\n * @cur_pos\n *\tThe current position in the input buffer relative to @in_base (the\n *\tposition of the sequence being matched against).\n * @max_len\n *\tThe maximum permissible match length at this position.  Must be >=\n *\tBT_MATCHFINDER_REQUIRED_NBYTES.\n * @nice_len\n *\tStop searching if a match of at least this length is found.\n *\tMust be <= @max_len.\n * @max_search_depth\n *\tLimit on the number of potential matches to consider.  Must be >= 1.\n * @next_hashes\n *\tThe precomputed hash codes for the sequence beginning at @in_next.\n *\tThese will be used and then updated with the precomputed hashcodes for\n *\tthe sequence beginning at @in_next + 1.\n * @lz_matchptr\n *\tAn array in which this function will record the matches.  The recorded\n *\tmatches will be sorted by strictly increasing length and (non-strictly)\n *\tincreasing offset.  The maximum number of matches that may be found is\n *\t'nice_len - 2'.\n *\n * The return value is a pointer to the next available slot in the @lz_matchptr\n * array.  (If no matches were found, this will be the same as @lz_matchptr.)\n */\nstatic forceinline struct lz_match *\nbt_matchfinder_get_matches(struct bt_matchfinder *mf,\n\t\t\t   const u8 *in_base,\n\t\t\t   ptrdiff_t cur_pos,\n\t\t\t   u32 max_len,\n\t\t\t   u32 nice_len,\n\t\t\t   u32 max_search_depth,\n\t\t\t   u32 next_hashes[2],\n\t\t\t   struct lz_match *lz_matchptr)\n{\n\treturn bt_matchfinder_advance_one_byte(mf,\n\t\t\t\t\t       in_base,\n\t\t\t\t\t       cur_pos,\n\t\t\t\t\t       max_len,\n\t\t\t\t\t       nice_len,\n\t\t\t\t\t       max_search_depth,\n\t\t\t\t\t       next_hashes,\n\t\t\t\t\t       lz_matchptr,\n\t\t\t\t\t       true);\n}\n\n/*\n * Advance the matchfinder, but don't record any matches.\n *\n * This is very similar to bt_matchfinder_get_matches() because both functions\n * must do hashing and tree re-rooting.\n */\nstatic forceinline void\nbt_matchfinder_skip_byte(struct bt_matchfinder *mf,\n\t\t\t const u8 *in_base,\n\t\t\t ptrdiff_t cur_pos,\n\t\t\t u32 nice_len,\n\t\t\t u32 max_search_depth,\n\t\t\t u32 next_hashes[2])\n{\n\tbt_matchfinder_advance_one_byte(mf,\n\t\t\t\t\tin_base,\n\t\t\t\t\tcur_pos,\n\t\t\t\t\tnice_len,\n\t\t\t\t\tnice_len,\n\t\t\t\t\tmax_search_depth,\n\t\t\t\t\tnext_hashes,\n\t\t\t\t\tNULL,\n\t\t\t\t\tfalse);\n}\n\n#endif /* LIB_BT_MATCHFINDER_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/cpu_features_common.h",
    "content": "/*\n * cpu_features_common.h - code shared by all lib/$arch/cpu_features.c\n *\n * Copyright 2020 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_CPU_FEATURES_COMMON_H\n#define LIB_CPU_FEATURES_COMMON_H\n\n#if defined(TEST_SUPPORT__DO_NOT_USE) && !defined(FREESTANDING)\n   /* for strdup() and strtok_r() */\n#  undef _ANSI_SOURCE\n#  ifndef __APPLE__\n#    undef _GNU_SOURCE\n#    define _GNU_SOURCE\n#  endif\n#  include <stdio.h>\n#  include <stdlib.h>\n#  include <string.h>\n#endif\n\n#include \"lib_common.h\"\n\nstruct cpu_feature {\n\tu32 bit;\n\tconst char *name;\n};\n\n#if defined(TEST_SUPPORT__DO_NOT_USE) && !defined(FREESTANDING)\n/* Disable any features that are listed in $LIBDEFLATE_DISABLE_CPU_FEATURES. */\nstatic inline void\ndisable_cpu_features_for_testing(u32 *features,\n\t\t\t\t const struct cpu_feature *feature_table,\n\t\t\t\t size_t feature_table_length)\n{\n\tchar *env_value, *strbuf, *p, *saveptr = NULL;\n\tsize_t i;\n\n\tenv_value = getenv(\"LIBDEFLATE_DISABLE_CPU_FEATURES\");\n\tif (!env_value)\n\t\treturn;\n\tstrbuf = strdup(env_value);\n\tif (!strbuf)\n\t\tabort();\n\tp = strtok_r(strbuf, \",\", &saveptr);\n\twhile (p) {\n\t\tfor (i = 0; i < feature_table_length; i++) {\n\t\t\tif (strcmp(p, feature_table[i].name) == 0) {\n\t\t\t\t*features &= ~feature_table[i].bit;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (i == feature_table_length) {\n\t\t\tfprintf(stderr,\n\t\t\t\t\"unrecognized feature in LIBDEFLATE_DISABLE_CPU_FEATURES: \\\"%s\\\"\\n\",\n\t\t\t\tp);\n\t\t\tabort();\n\t\t}\n\t\tp = strtok_r(NULL, \",\", &saveptr);\n\t}\n\tfree(strbuf);\n}\n#else /* TEST_SUPPORT__DO_NOT_USE */\nstatic inline void\ndisable_cpu_features_for_testing(u32 *features,\n\t\t\t\t const struct cpu_feature *feature_table,\n\t\t\t\t size_t feature_table_length)\n{\n}\n#endif /* !TEST_SUPPORT__DO_NOT_USE */\n\n#endif /* LIB_CPU_FEATURES_COMMON_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/crc32.c",
    "content": "/*\n * crc32.c - CRC-32 checksum algorithm for the gzip format\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * High-level description of CRC\n * =============================\n *\n * Consider a bit sequence 'bits[1...len]'.  Interpret 'bits' as the \"message\"\n * polynomial M(x) with coefficients in GF(2) (the field of integers modulo 2),\n * where the coefficient of 'x^i' is 'bits[len - i]'.  Then, compute:\n *\n *\t\t\tR(x) = M(x)*x^n mod G(x)\n *\n * where G(x) is a selected \"generator\" polynomial of degree 'n'.  The remainder\n * R(x) is a polynomial of max degree 'n - 1'.  The CRC of 'bits' is R(x)\n * interpreted as a bitstring of length 'n'.\n *\n * CRC used in gzip\n * ================\n *\n * In the gzip format (RFC 1952):\n *\n *\t- The bitstring to checksum is formed from the bytes of the uncompressed\n *\t  data by concatenating the bits from the bytes in order, proceeding\n *\t  from the low-order bit to the high-order bit within each byte.\n *\n *\t- The generator polynomial G(x) is: x^32 + x^26 + x^23 + x^22 + x^16 +\n *\t  x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1.\n *\t  Consequently, the CRC length is 32 bits (\"CRC-32\").\n *\n *\t- The highest order 32 coefficients of M(x)*x^n are inverted.\n *\n *\t- All 32 coefficients of R(x) are inverted.\n *\n * The two inversions cause added leading and trailing zero bits to affect the\n * resulting CRC, whereas with a regular CRC such bits would have no effect on\n * the CRC.\n *\n * Computation and optimizations\n * =============================\n *\n * We can compute R(x) through \"long division\", maintaining only 32 bits of\n * state at any given time.  Multiplication by 'x' can be implemented as\n * right-shifting by 1 (assuming the polynomial<=>bitstring mapping where the\n * highest order bit represents the coefficient of x^0), and both addition and\n * subtraction can be implemented as bitwise exclusive OR (since we are working\n * in GF(2)).  Here is an unoptimized implementation:\n *\n *\tstatic u32 crc32_gzip(const u8 *p, size_t len)\n *\t{\n *\t\tu32 crc = 0;\n *\t\tconst u32 divisor = 0xEDB88320;\n *\n *\t\tfor (size_t i = 0; i < len * 8 + 32; i++) {\n *\t\t\tint bit;\n *\t\t\tu32 multiple;\n *\n *\t\t\tif (i < len * 8)\n *\t\t\t\tbit = (p[i / 8] >> (i % 8)) & 1;\n *\t\t\telse\n *\t\t\t\tbit = 0; // one of the 32 appended 0 bits\n *\n *\t\t\tif (i < 32) // the first 32 bits are inverted\n *\t\t\t\tbit ^= 1;\n *\n *\t\t\tif (crc & 1)\n *\t\t\t\tmultiple = divisor;\n *\t\t\telse\n *\t\t\t\tmultiple = 0;\n *\n *\t\t\tcrc >>= 1;\n *\t\t\tcrc |= (u32)bit << 31;\n *\t\t\tcrc ^= multiple;\n *\t\t}\n *\n *\t\treturn ~crc;\n *\t}\n *\n * In this implementation, the 32-bit integer 'crc' maintains the remainder of\n * the currently processed portion of the message (with 32 zero bits appended)\n * when divided by the generator polynomial.  'crc' is the representation of\n * R(x), and 'divisor' is the representation of G(x) excluding the x^32\n * coefficient.  For each bit to process, we multiply R(x) by 'x^1', then add\n * 'x^0' if the new bit is a 1.  If this causes R(x) to gain a nonzero x^32\n * term, then we subtract G(x) from R(x).\n *\n * We can speed this up by taking advantage of the fact that XOR is commutative\n * and associative, so the order in which we combine the inputs into 'crc' is\n * unimportant.  And since each message bit we add doesn't affect the choice of\n * 'multiple' until 32 bits later, we need not actually add each message bit\n * until that point:\n *\n *\tstatic u32 crc32_gzip(const u8 *p, size_t len)\n *\t{\n *\t\tu32 crc = ~0;\n *\t\tconst u32 divisor = 0xEDB88320;\n *\n *\t\tfor (size_t i = 0; i < len * 8; i++) {\n *\t\t\tint bit;\n *\t\t\tu32 multiple;\n *\n *\t\t\tbit = (p[i / 8] >> (i % 8)) & 1;\n *\t\t\tcrc ^= bit;\n *\t\t\tif (crc & 1)\n *\t\t\t\tmultiple = divisor;\n *\t\t\telse\n *\t\t\t\tmultiple = 0;\n *\t\t\tcrc >>= 1;\n *\t\t\tcrc ^= multiple;\n *\t\t}\n *\n *\t\treturn ~crc;\n *\t}\n *\n * With the above implementation we get the effect of 32 appended 0 bits for\n * free; they never affect the choice of a divisor, nor would they change the\n * value of 'crc' if they were to be actually XOR'ed in.  And by starting with a\n * remainder of all 1 bits, we get the effect of complementing the first 32\n * message bits.\n *\n * The next optimization is to process the input in multi-bit units.  Suppose\n * that we insert the next 'n' message bits into the remainder.  Then we get an\n * intermediate remainder of length '32 + n' bits, and the CRC of the extra 'n'\n * bits is the amount by which the low 32 bits of the remainder will change as a\n * result of cancelling out those 'n' bits.  Taking n=8 (one byte) and\n * precomputing a table containing the CRC of each possible byte, we get\n * crc32_slice1() defined below.\n *\n * As a further optimization, we could increase the multi-bit unit size to 16.\n * However, that is inefficient because the table size explodes from 256 entries\n * (1024 bytes) to 65536 entries (262144 bytes), which wastes memory and won't\n * fit in L1 cache on typical processors.\n *\n * However, we can actually process 4 bytes at a time using 4 different tables\n * with 256 entries each.  Logically, we form a 64-bit intermediate remainder\n * and cancel out the high 32 bits in 8-bit chunks.  Bits 32-39 are cancelled\n * out by the CRC of those bits, whereas bits 40-47 are be cancelled out by the\n * CRC of those bits with 8 zero bits appended, and so on.\n *\n * In crc32_slice8(), this method is extended to 8 bytes at a time.  The\n * intermediate remainder (which we never actually store explicitly) is 96 bits.\n *\n * On CPUs that support fast carryless multiplication, CRCs can be computed even\n * more quickly via \"folding\".  See e.g. the x86 PCLMUL implementations.\n */\n\n#include \"lib_common.h\"\n#include \"crc32_multipliers.h\"\n#include \"crc32_tables.h\"\n\n/* This is the default implementation.  It uses the slice-by-8 method. */\nstatic u32 MAYBE_UNUSED\ncrc32_slice8(u32 crc, const u8 *p, size_t len)\n{\n\tconst u8 * const end = p + len;\n\tconst u8 *end64;\n\n\tfor (; ((uintptr_t)p & 7) && p != end; p++)\n\t\tcrc = (crc >> 8) ^ crc32_slice8_table[(u8)crc ^ *p];\n\n\tend64 = p + ((end - p) & ~7);\n\tfor (; p != end64; p += 8) {\n\t\tu32 v1 = le32_bswap(*(const u32 *)(p + 0));\n\t\tu32 v2 = le32_bswap(*(const u32 *)(p + 4));\n\n\t\tcrc = crc32_slice8_table[0x700 + (u8)((crc ^ v1) >> 0)] ^\n\t\t      crc32_slice8_table[0x600 + (u8)((crc ^ v1) >> 8)] ^\n\t\t      crc32_slice8_table[0x500 + (u8)((crc ^ v1) >> 16)] ^\n\t\t      crc32_slice8_table[0x400 + (u8)((crc ^ v1) >> 24)] ^\n\t\t      crc32_slice8_table[0x300 + (u8)(v2 >> 0)] ^\n\t\t      crc32_slice8_table[0x200 + (u8)(v2 >> 8)] ^\n\t\t      crc32_slice8_table[0x100 + (u8)(v2 >> 16)] ^\n\t\t      crc32_slice8_table[0x000 + (u8)(v2 >> 24)];\n\t}\n\n\tfor (; p != end; p++)\n\t\tcrc = (crc >> 8) ^ crc32_slice8_table[(u8)crc ^ *p];\n\n\treturn crc;\n}\n\n/*\n * This is a more lightweight generic implementation, which can be used as a\n * subroutine by architecture-specific implementations to process small amounts\n * of unaligned data at the beginning and/or end of the buffer.\n */\nstatic forceinline u32 MAYBE_UNUSED\ncrc32_slice1(u32 crc, const u8 *p, size_t len)\n{\n\tsize_t i;\n\n\tfor (i = 0; i < len; i++)\n\t\tcrc = (crc >> 8) ^ crc32_slice1_table[(u8)crc ^ p[i]];\n\treturn crc;\n}\n\n/* Include architecture-specific implementation(s) if available. */\n#undef DEFAULT_IMPL\n#undef arch_select_crc32_func\ntypedef u32 (*crc32_func_t)(u32 crc, const u8 *p, size_t len);\n#if defined(ARCH_ARM32) || defined(ARCH_ARM64)\n#  include \"arm/crc32_impl.h\"\n#elif defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#  include \"x86/crc32_impl.h\"\n#endif\n\n#ifndef DEFAULT_IMPL\n#  define DEFAULT_IMPL crc32_slice8\n#endif\n\n#ifdef arch_select_crc32_func\nstatic u32 dispatch_crc32(u32 crc, const u8 *p, size_t len);\n\nstatic volatile crc32_func_t crc32_impl = dispatch_crc32;\n\n/* Choose the best implementation at runtime. */\nstatic u32 dispatch_crc32(u32 crc, const u8 *p, size_t len)\n{\n\tcrc32_func_t f = arch_select_crc32_func();\n\n\tif (f == NULL)\n\t\tf = DEFAULT_IMPL;\n\n\tcrc32_impl = f;\n\treturn f(crc, p, len);\n}\n#else\n/* The best implementation is statically known, so call it directly. */\n#define crc32_impl DEFAULT_IMPL\n#endif\n\nLIBDEFLATEAPI u32\nlibdeflate_crc32(u32 crc, const void *p, size_t len)\n{\n\tif (p == NULL) /* Return initial value. */\n\t\treturn 0;\n\treturn ~crc32_impl(~crc, p, len);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/crc32_multipliers.h",
    "content": "/*\n * crc32_multipliers.h - constants for CRC-32 folding\n *\n * THIS FILE WAS GENERATED BY gen-crc32-consts.py.  DO NOT EDIT.\n */\n\n#define CRC32_X159_MODG 0xae689191 /* x^159 mod G(x) */\n#define CRC32_X95_MODG 0xccaa009e /* x^95 mod G(x) */\n\n#define CRC32_X287_MODG 0xf1da05aa /* x^287 mod G(x) */\n#define CRC32_X223_MODG 0x81256527 /* x^223 mod G(x) */\n\n#define CRC32_X415_MODG 0x3db1ecdc /* x^415 mod G(x) */\n#define CRC32_X351_MODG 0xaf449247 /* x^351 mod G(x) */\n\n#define CRC32_X543_MODG 0x8f352d95 /* x^543 mod G(x) */\n#define CRC32_X479_MODG 0x1d9513d7 /* x^479 mod G(x) */\n\n#define CRC32_X671_MODG 0x1c279815 /* x^671 mod G(x) */\n#define CRC32_X607_MODG 0xae0b5394 /* x^607 mod G(x) */\n\n#define CRC32_X799_MODG 0xdf068dc2 /* x^799 mod G(x) */\n#define CRC32_X735_MODG 0x57c54819 /* x^735 mod G(x) */\n\n#define CRC32_X927_MODG 0x31f8303f /* x^927 mod G(x) */\n#define CRC32_X863_MODG 0x0cbec0ed /* x^863 mod G(x) */\n\n#define CRC32_X1055_MODG 0x33fff533 /* x^1055 mod G(x) */\n#define CRC32_X991_MODG 0x910eeec1 /* x^991 mod G(x) */\n\n#define CRC32_X1183_MODG 0x26b70c3d /* x^1183 mod G(x) */\n#define CRC32_X1119_MODG 0x3f41287a /* x^1119 mod G(x) */\n\n#define CRC32_X1311_MODG 0xe3543be0 /* x^1311 mod G(x) */\n#define CRC32_X1247_MODG 0x9026d5b1 /* x^1247 mod G(x) */\n\n#define CRC32_X1439_MODG 0x5a1bb05d /* x^1439 mod G(x) */\n#define CRC32_X1375_MODG 0xd1df2327 /* x^1375 mod G(x) */\n\n#define CRC32_X1567_MODG 0x596c8d81 /* x^1567 mod G(x) */\n#define CRC32_X1503_MODG 0xf5e48c85 /* x^1503 mod G(x) */\n\n#define CRC32_X1695_MODG 0x682bdd4f /* x^1695 mod G(x) */\n#define CRC32_X1631_MODG 0x3c656ced /* x^1631 mod G(x) */\n\n#define CRC32_X1823_MODG 0x4a28bd43 /* x^1823 mod G(x) */\n#define CRC32_X1759_MODG 0xfe807bbd /* x^1759 mod G(x) */\n\n#define CRC32_X1951_MODG 0x0077f00d /* x^1951 mod G(x) */\n#define CRC32_X1887_MODG 0x1f0c2cdd /* x^1887 mod G(x) */\n\n#define CRC32_X2079_MODG 0xce3371cb /* x^2079 mod G(x) */\n#define CRC32_X2015_MODG 0xe95c1271 /* x^2015 mod G(x) */\n\n#define CRC32_X2207_MODG 0xa749e894 /* x^2207 mod G(x) */\n#define CRC32_X2143_MODG 0xb918a347 /* x^2143 mod G(x) */\n\n#define CRC32_X2335_MODG 0x2c538639 /* x^2335 mod G(x) */\n#define CRC32_X2271_MODG 0x71d54a59 /* x^2271 mod G(x) */\n\n#define CRC32_X2463_MODG 0x32b0733c /* x^2463 mod G(x) */\n#define CRC32_X2399_MODG 0xff6f2fc2 /* x^2399 mod G(x) */\n\n#define CRC32_X2591_MODG 0x0e9bd5cc /* x^2591 mod G(x) */\n#define CRC32_X2527_MODG 0xcec97417 /* x^2527 mod G(x) */\n\n#define CRC32_X2719_MODG 0x76278617 /* x^2719 mod G(x) */\n#define CRC32_X2655_MODG 0x1c63267b /* x^2655 mod G(x) */\n\n#define CRC32_X2847_MODG 0xc51b93e3 /* x^2847 mod G(x) */\n#define CRC32_X2783_MODG 0xf183c71b /* x^2783 mod G(x) */\n\n#define CRC32_X2975_MODG 0x7eaed122 /* x^2975 mod G(x) */\n#define CRC32_X2911_MODG 0x9b9bdbd0 /* x^2911 mod G(x) */\n\n#define CRC32_X3103_MODG 0x2ce423f1 /* x^3103 mod G(x) */\n#define CRC32_X3039_MODG 0xd31343ea /* x^3039 mod G(x) */\n\n#define CRC32_X3231_MODG 0x8b8d8645 /* x^3231 mod G(x) */\n#define CRC32_X3167_MODG 0x4470ac44 /* x^3167 mod G(x) */\n\n#define CRC32_X3359_MODG 0x4b700aa8 /* x^3359 mod G(x) */\n#define CRC32_X3295_MODG 0xeea395c4 /* x^3295 mod G(x) */\n\n#define CRC32_X3487_MODG 0xeff5e99d /* x^3487 mod G(x) */\n#define CRC32_X3423_MODG 0xf9d9c7ee /* x^3423 mod G(x) */\n\n#define CRC32_X3615_MODG 0xad0d2bb2 /* x^3615 mod G(x) */\n#define CRC32_X3551_MODG 0xcd669a40 /* x^3551 mod G(x) */\n\n#define CRC32_X3743_MODG 0x9fb66bd3 /* x^3743 mod G(x) */\n#define CRC32_X3679_MODG 0x6d40f445 /* x^3679 mod G(x) */\n\n#define CRC32_X3871_MODG 0xc2dcc467 /* x^3871 mod G(x) */\n#define CRC32_X3807_MODG 0x9ee62949 /* x^3807 mod G(x) */\n\n#define CRC32_X3999_MODG 0x398e2ff2 /* x^3999 mod G(x) */\n#define CRC32_X3935_MODG 0x145575d5 /* x^3935 mod G(x) */\n\n#define CRC32_X4127_MODG 0x1072db28 /* x^4127 mod G(x) */\n#define CRC32_X4063_MODG 0x0c30f51d /* x^4063 mod G(x) */\n\n#define CRC32_BARRETT_CONSTANT_1 0xb4e5b025f7011641ULL /* floor(x^95 / G(x)) */\n#define CRC32_BARRETT_CONSTANT_2 0x00000001db710641ULL /* G(x) */\n\n#define CRC32_NUM_CHUNKS 4\n#define CRC32_MIN_VARIABLE_CHUNK_LEN 128UL\n#define CRC32_MAX_VARIABLE_CHUNK_LEN 16384UL\n\n/* Multipliers for implementations that use a variable chunk length */\nstatic const u32 crc32_mults_for_chunklen[][CRC32_NUM_CHUNKS - 1] MAYBE_UNUSED = {\n\t{ 0 /* unused row */ },\n\t/* chunk_len=128 */\n\t{ 0xd31343ea /* x^3039 mod G(x) */, 0xe95c1271 /* x^2015 mod G(x) */, 0x910eeec1 /* x^991 mod G(x) */, },\n\t/* chunk_len=256 */\n\t{ 0x1d6708a0 /* x^6111 mod G(x) */, 0x0c30f51d /* x^4063 mod G(x) */, 0xe95c1271 /* x^2015 mod G(x) */, },\n\t/* chunk_len=384 */\n\t{ 0xdb3839f3 /* x^9183 mod G(x) */, 0x1d6708a0 /* x^6111 mod G(x) */, 0xd31343ea /* x^3039 mod G(x) */, },\n\t/* chunk_len=512 */\n\t{ 0x1753ab84 /* x^12255 mod G(x) */, 0xbbf2f6d6 /* x^8159 mod G(x) */, 0x0c30f51d /* x^4063 mod G(x) */, },\n\t/* chunk_len=640 */\n\t{ 0x3796455c /* x^15327 mod G(x) */, 0xb8e0e4a8 /* x^10207 mod G(x) */, 0xc352f6de /* x^5087 mod G(x) */, },\n\t/* chunk_len=768 */\n\t{ 0x3954de39 /* x^18399 mod G(x) */, 0x1753ab84 /* x^12255 mod G(x) */, 0x1d6708a0 /* x^6111 mod G(x) */, },\n\t/* chunk_len=896 */\n\t{ 0x632d78c5 /* x^21471 mod G(x) */, 0x3fc33de4 /* x^14303 mod G(x) */, 0x9a1b53c8 /* x^7135 mod G(x) */, },\n\t/* chunk_len=1024 */\n\t{ 0xa0decef3 /* x^24543 mod G(x) */, 0x7b4aa8b7 /* x^16351 mod G(x) */, 0xbbf2f6d6 /* x^8159 mod G(x) */, },\n\t/* chunk_len=1152 */\n\t{ 0xe9c09bb0 /* x^27615 mod G(x) */, 0x3954de39 /* x^18399 mod G(x) */, 0xdb3839f3 /* x^9183 mod G(x) */, },\n\t/* chunk_len=1280 */\n\t{ 0xd51917a4 /* x^30687 mod G(x) */, 0xcae68461 /* x^20447 mod G(x) */, 0xb8e0e4a8 /* x^10207 mod G(x) */, },\n\t/* chunk_len=1408 */\n\t{ 0x154a8a62 /* x^33759 mod G(x) */, 0x41e7589c /* x^22495 mod G(x) */, 0x3e9a43cd /* x^11231 mod G(x) */, },\n\t/* chunk_len=1536 */\n\t{ 0xf196555d /* x^36831 mod G(x) */, 0xa0decef3 /* x^24543 mod G(x) */, 0x1753ab84 /* x^12255 mod G(x) */, },\n\t/* chunk_len=1664 */\n\t{ 0x8eec2999 /* x^39903 mod G(x) */, 0xefb0a128 /* x^26591 mod G(x) */, 0x6044fbb0 /* x^13279 mod G(x) */, },\n\t/* chunk_len=1792 */\n\t{ 0x27892abf /* x^42975 mod G(x) */, 0x48d72bb1 /* x^28639 mod G(x) */, 0x3fc33de4 /* x^14303 mod G(x) */, },\n\t/* chunk_len=1920 */\n\t{ 0x77bc2419 /* x^46047 mod G(x) */, 0xd51917a4 /* x^30687 mod G(x) */, 0x3796455c /* x^15327 mod G(x) */, },\n\t/* chunk_len=2048 */\n\t{ 0xcea114a5 /* x^49119 mod G(x) */, 0x68c0a2c5 /* x^32735 mod G(x) */, 0x7b4aa8b7 /* x^16351 mod G(x) */, },\n\t/* chunk_len=2176 */\n\t{ 0xa1077e85 /* x^52191 mod G(x) */, 0x188cc628 /* x^34783 mod G(x) */, 0x0c21f835 /* x^17375 mod G(x) */, },\n\t/* chunk_len=2304 */\n\t{ 0xc5ed75e1 /* x^55263 mod G(x) */, 0xf196555d /* x^36831 mod G(x) */, 0x3954de39 /* x^18399 mod G(x) */, },\n\t/* chunk_len=2432 */\n\t{ 0xca4fba3f /* x^58335 mod G(x) */, 0x0acfa26f /* x^38879 mod G(x) */, 0x6cb21510 /* x^19423 mod G(x) */, },\n\t/* chunk_len=2560 */\n\t{ 0xcf5bcdc4 /* x^61407 mod G(x) */, 0x4fae7fc0 /* x^40927 mod G(x) */, 0xcae68461 /* x^20447 mod G(x) */, },\n\t/* chunk_len=2688 */\n\t{ 0xf36b9d16 /* x^64479 mod G(x) */, 0x27892abf /* x^42975 mod G(x) */, 0x632d78c5 /* x^21471 mod G(x) */, },\n\t/* chunk_len=2816 */\n\t{ 0xf76fd988 /* x^67551 mod G(x) */, 0xed5c39b1 /* x^45023 mod G(x) */, 0x41e7589c /* x^22495 mod G(x) */, },\n\t/* chunk_len=2944 */\n\t{ 0x6c45d92e /* x^70623 mod G(x) */, 0xff809fcd /* x^47071 mod G(x) */, 0x0c46baec /* x^23519 mod G(x) */, },\n\t/* chunk_len=3072 */\n\t{ 0x6116b82b /* x^73695 mod G(x) */, 0xcea114a5 /* x^49119 mod G(x) */, 0xa0decef3 /* x^24543 mod G(x) */, },\n\t/* chunk_len=3200 */\n\t{ 0x4d9899bb /* x^76767 mod G(x) */, 0x9f9d8d9c /* x^51167 mod G(x) */, 0x53deb236 /* x^25567 mod G(x) */, },\n\t/* chunk_len=3328 */\n\t{ 0x3e7c93b9 /* x^79839 mod G(x) */, 0x6666b805 /* x^53215 mod G(x) */, 0xefb0a128 /* x^26591 mod G(x) */, },\n\t/* chunk_len=3456 */\n\t{ 0x388b20ac /* x^82911 mod G(x) */, 0xc5ed75e1 /* x^55263 mod G(x) */, 0xe9c09bb0 /* x^27615 mod G(x) */, },\n\t/* chunk_len=3584 */\n\t{ 0x0956d953 /* x^85983 mod G(x) */, 0x97fbdb14 /* x^57311 mod G(x) */, 0x48d72bb1 /* x^28639 mod G(x) */, },\n\t/* chunk_len=3712 */\n\t{ 0x55cb4dfe /* x^89055 mod G(x) */, 0x1b37c832 /* x^59359 mod G(x) */, 0xc07331b3 /* x^29663 mod G(x) */, },\n\t/* chunk_len=3840 */\n\t{ 0x52222fea /* x^92127 mod G(x) */, 0xcf5bcdc4 /* x^61407 mod G(x) */, 0xd51917a4 /* x^30687 mod G(x) */, },\n\t/* chunk_len=3968 */\n\t{ 0x0603989b /* x^95199 mod G(x) */, 0xb03c8112 /* x^63455 mod G(x) */, 0x5e04b9a5 /* x^31711 mod G(x) */, },\n\t/* chunk_len=4096 */\n\t{ 0x4470c029 /* x^98271 mod G(x) */, 0x2339d155 /* x^65503 mod G(x) */, 0x68c0a2c5 /* x^32735 mod G(x) */, },\n\t/* chunk_len=4224 */\n\t{ 0xb6f35093 /* x^101343 mod G(x) */, 0xf76fd988 /* x^67551 mod G(x) */, 0x154a8a62 /* x^33759 mod G(x) */, },\n\t/* chunk_len=4352 */\n\t{ 0xc46805ba /* x^104415 mod G(x) */, 0x416f9449 /* x^69599 mod G(x) */, 0x188cc628 /* x^34783 mod G(x) */, },\n\t/* chunk_len=4480 */\n\t{ 0xc3876592 /* x^107487 mod G(x) */, 0x4b809189 /* x^71647 mod G(x) */, 0xc35cf6e7 /* x^35807 mod G(x) */, },\n\t/* chunk_len=4608 */\n\t{ 0x5b0c98b9 /* x^110559 mod G(x) */, 0x6116b82b /* x^73695 mod G(x) */, 0xf196555d /* x^36831 mod G(x) */, },\n\t/* chunk_len=4736 */\n\t{ 0x30d13e5f /* x^113631 mod G(x) */, 0x4c5a315a /* x^75743 mod G(x) */, 0x8c224466 /* x^37855 mod G(x) */, },\n\t/* chunk_len=4864 */\n\t{ 0x54afca53 /* x^116703 mod G(x) */, 0xbccfa2c1 /* x^77791 mod G(x) */, 0x0acfa26f /* x^38879 mod G(x) */, },\n\t/* chunk_len=4992 */\n\t{ 0x93102436 /* x^119775 mod G(x) */, 0x3e7c93b9 /* x^79839 mod G(x) */, 0x8eec2999 /* x^39903 mod G(x) */, },\n\t/* chunk_len=5120 */\n\t{ 0xbd2655a8 /* x^122847 mod G(x) */, 0x3e116c9d /* x^81887 mod G(x) */, 0x4fae7fc0 /* x^40927 mod G(x) */, },\n\t/* chunk_len=5248 */\n\t{ 0x70cd7f26 /* x^125919 mod G(x) */, 0x408e57f2 /* x^83935 mod G(x) */, 0x1691be45 /* x^41951 mod G(x) */, },\n\t/* chunk_len=5376 */\n\t{ 0x2d546c53 /* x^128991 mod G(x) */, 0x0956d953 /* x^85983 mod G(x) */, 0x27892abf /* x^42975 mod G(x) */, },\n\t/* chunk_len=5504 */\n\t{ 0xb53410a8 /* x^132063 mod G(x) */, 0x42ebf0ad /* x^88031 mod G(x) */, 0x161f3c12 /* x^43999 mod G(x) */, },\n\t/* chunk_len=5632 */\n\t{ 0x67a93f75 /* x^135135 mod G(x) */, 0xcf3233e4 /* x^90079 mod G(x) */, 0xed5c39b1 /* x^45023 mod G(x) */, },\n\t/* chunk_len=5760 */\n\t{ 0x9830ac33 /* x^138207 mod G(x) */, 0x52222fea /* x^92127 mod G(x) */, 0x77bc2419 /* x^46047 mod G(x) */, },\n\t/* chunk_len=5888 */\n\t{ 0xb0b6fc3e /* x^141279 mod G(x) */, 0x2fde73f8 /* x^94175 mod G(x) */, 0xff809fcd /* x^47071 mod G(x) */, },\n\t/* chunk_len=6016 */\n\t{ 0x84170f16 /* x^144351 mod G(x) */, 0xced90d99 /* x^96223 mod G(x) */, 0x30de0f98 /* x^48095 mod G(x) */, },\n\t/* chunk_len=6144 */\n\t{ 0xd7017a0c /* x^147423 mod G(x) */, 0x4470c029 /* x^98271 mod G(x) */, 0xcea114a5 /* x^49119 mod G(x) */, },\n\t/* chunk_len=6272 */\n\t{ 0xadb25de6 /* x^150495 mod G(x) */, 0x84f40beb /* x^100319 mod G(x) */, 0x2b7e0e1b /* x^50143 mod G(x) */, },\n\t/* chunk_len=6400 */\n\t{ 0x8282fddc /* x^153567 mod G(x) */, 0xec855937 /* x^102367 mod G(x) */, 0x9f9d8d9c /* x^51167 mod G(x) */, },\n\t/* chunk_len=6528 */\n\t{ 0x46362bee /* x^156639 mod G(x) */, 0xc46805ba /* x^104415 mod G(x) */, 0xa1077e85 /* x^52191 mod G(x) */, },\n\t/* chunk_len=6656 */\n\t{ 0xb9077a01 /* x^159711 mod G(x) */, 0xdf7a24ac /* x^106463 mod G(x) */, 0x6666b805 /* x^53215 mod G(x) */, },\n\t/* chunk_len=6784 */\n\t{ 0xf51d9bc6 /* x^162783 mod G(x) */, 0x2b52dc39 /* x^108511 mod G(x) */, 0x7e774cf6 /* x^54239 mod G(x) */, },\n\t/* chunk_len=6912 */\n\t{ 0x4ca19a29 /* x^165855 mod G(x) */, 0x5b0c98b9 /* x^110559 mod G(x) */, 0xc5ed75e1 /* x^55263 mod G(x) */, },\n\t/* chunk_len=7040 */\n\t{ 0xdc0fc3fc /* x^168927 mod G(x) */, 0xb939fcdf /* x^112607 mod G(x) */, 0x3678fed2 /* x^56287 mod G(x) */, },\n\t/* chunk_len=7168 */\n\t{ 0x63c3d167 /* x^171999 mod G(x) */, 0x70f9947d /* x^114655 mod G(x) */, 0x97fbdb14 /* x^57311 mod G(x) */, },\n\t/* chunk_len=7296 */\n\t{ 0x5851d254 /* x^175071 mod G(x) */, 0x54afca53 /* x^116703 mod G(x) */, 0xca4fba3f /* x^58335 mod G(x) */, },\n\t/* chunk_len=7424 */\n\t{ 0xfeacf2a1 /* x^178143 mod G(x) */, 0x7a3c0a6a /* x^118751 mod G(x) */, 0x1b37c832 /* x^59359 mod G(x) */, },\n\t/* chunk_len=7552 */\n\t{ 0x93b7edc8 /* x^181215 mod G(x) */, 0x1fea4d2a /* x^120799 mod G(x) */, 0x58fa96ee /* x^60383 mod G(x) */, },\n\t/* chunk_len=7680 */\n\t{ 0x5539e44a /* x^184287 mod G(x) */, 0xbd2655a8 /* x^122847 mod G(x) */, 0xcf5bcdc4 /* x^61407 mod G(x) */, },\n\t/* chunk_len=7808 */\n\t{ 0xde32a3d2 /* x^187359 mod G(x) */, 0x4ff61aa1 /* x^124895 mod G(x) */, 0x6a6a3694 /* x^62431 mod G(x) */, },\n\t/* chunk_len=7936 */\n\t{ 0xf0baeeb6 /* x^190431 mod G(x) */, 0x7ae2f6f4 /* x^126943 mod G(x) */, 0xb03c8112 /* x^63455 mod G(x) */, },\n\t/* chunk_len=8064 */\n\t{ 0xbe15887f /* x^193503 mod G(x) */, 0x2d546c53 /* x^128991 mod G(x) */, 0xf36b9d16 /* x^64479 mod G(x) */, },\n\t/* chunk_len=8192 */\n\t{ 0x64f34a05 /* x^196575 mod G(x) */, 0xe0ee5efe /* x^131039 mod G(x) */, 0x2339d155 /* x^65503 mod G(x) */, },\n\t/* chunk_len=8320 */\n\t{ 0x1b6d1aea /* x^199647 mod G(x) */, 0xfeafb67c /* x^133087 mod G(x) */, 0x4fb001a8 /* x^66527 mod G(x) */, },\n\t/* chunk_len=8448 */\n\t{ 0x82adb0b8 /* x^202719 mod G(x) */, 0x67a93f75 /* x^135135 mod G(x) */, 0xf76fd988 /* x^67551 mod G(x) */, },\n\t/* chunk_len=8576 */\n\t{ 0x694587c7 /* x^205791 mod G(x) */, 0x3b34408b /* x^137183 mod G(x) */, 0xeccb2978 /* x^68575 mod G(x) */, },\n\t/* chunk_len=8704 */\n\t{ 0xd2fc57c3 /* x^208863 mod G(x) */, 0x07fcf8c6 /* x^139231 mod G(x) */, 0x416f9449 /* x^69599 mod G(x) */, },\n\t/* chunk_len=8832 */\n\t{ 0x9dd6837c /* x^211935 mod G(x) */, 0xb0b6fc3e /* x^141279 mod G(x) */, 0x6c45d92e /* x^70623 mod G(x) */, },\n\t/* chunk_len=8960 */\n\t{ 0x3a9d1f97 /* x^215007 mod G(x) */, 0xefd033b2 /* x^143327 mod G(x) */, 0x4b809189 /* x^71647 mod G(x) */, },\n\t/* chunk_len=9088 */\n\t{ 0x1eee1d2a /* x^218079 mod G(x) */, 0xf2a6e46e /* x^145375 mod G(x) */, 0x55b4c814 /* x^72671 mod G(x) */, },\n\t/* chunk_len=9216 */\n\t{ 0xb57c7728 /* x^221151 mod G(x) */, 0xd7017a0c /* x^147423 mod G(x) */, 0x6116b82b /* x^73695 mod G(x) */, },\n\t/* chunk_len=9344 */\n\t{ 0xf2fc5d61 /* x^224223 mod G(x) */, 0x242aac86 /* x^149471 mod G(x) */, 0x05245cf0 /* x^74719 mod G(x) */, },\n\t/* chunk_len=9472 */\n\t{ 0x26387824 /* x^227295 mod G(x) */, 0xc15c4ca5 /* x^151519 mod G(x) */, 0x4c5a315a /* x^75743 mod G(x) */, },\n\t/* chunk_len=9600 */\n\t{ 0x8c151e77 /* x^230367 mod G(x) */, 0x8282fddc /* x^153567 mod G(x) */, 0x4d9899bb /* x^76767 mod G(x) */, },\n\t/* chunk_len=9728 */\n\t{ 0x8ea1f680 /* x^233439 mod G(x) */, 0xf5ff6cdd /* x^155615 mod G(x) */, 0xbccfa2c1 /* x^77791 mod G(x) */, },\n\t/* chunk_len=9856 */\n\t{ 0xe8cf3d2a /* x^236511 mod G(x) */, 0x338b1fb1 /* x^157663 mod G(x) */, 0xeda61f70 /* x^78815 mod G(x) */, },\n\t/* chunk_len=9984 */\n\t{ 0x21f15b59 /* x^239583 mod G(x) */, 0xb9077a01 /* x^159711 mod G(x) */, 0x3e7c93b9 /* x^79839 mod G(x) */, },\n\t/* chunk_len=10112 */\n\t{ 0x6f68d64a /* x^242655 mod G(x) */, 0x901b0161 /* x^161759 mod G(x) */, 0xb9fd3537 /* x^80863 mod G(x) */, },\n\t/* chunk_len=10240 */\n\t{ 0x71b74d95 /* x^245727 mod G(x) */, 0xf5ddd5ad /* x^163807 mod G(x) */, 0x3e116c9d /* x^81887 mod G(x) */, },\n\t/* chunk_len=10368 */\n\t{ 0x4c2e7261 /* x^248799 mod G(x) */, 0x4ca19a29 /* x^165855 mod G(x) */, 0x388b20ac /* x^82911 mod G(x) */, },\n\t/* chunk_len=10496 */\n\t{ 0x8a2d38e8 /* x^251871 mod G(x) */, 0xd27ee0a1 /* x^167903 mod G(x) */, 0x408e57f2 /* x^83935 mod G(x) */, },\n\t/* chunk_len=10624 */\n\t{ 0x7e58ca17 /* x^254943 mod G(x) */, 0x69dfedd2 /* x^169951 mod G(x) */, 0x3a76805e /* x^84959 mod G(x) */, },\n\t/* chunk_len=10752 */\n\t{ 0xf997967f /* x^258015 mod G(x) */, 0x63c3d167 /* x^171999 mod G(x) */, 0x0956d953 /* x^85983 mod G(x) */, },\n\t/* chunk_len=10880 */\n\t{ 0x48215963 /* x^261087 mod G(x) */, 0x71e1dfe0 /* x^174047 mod G(x) */, 0x42a6d410 /* x^87007 mod G(x) */, },\n\t/* chunk_len=11008 */\n\t{ 0xa704b94c /* x^264159 mod G(x) */, 0x679f198a /* x^176095 mod G(x) */, 0x42ebf0ad /* x^88031 mod G(x) */, },\n\t/* chunk_len=11136 */\n\t{ 0x1d699056 /* x^267231 mod G(x) */, 0xfeacf2a1 /* x^178143 mod G(x) */, 0x55cb4dfe /* x^89055 mod G(x) */, },\n\t/* chunk_len=11264 */\n\t{ 0x6800bcc5 /* x^270303 mod G(x) */, 0x16024f15 /* x^180191 mod G(x) */, 0xcf3233e4 /* x^90079 mod G(x) */, },\n\t/* chunk_len=11392 */\n\t{ 0x2d48e4ca /* x^273375 mod G(x) */, 0xbe61582f /* x^182239 mod G(x) */, 0x46026283 /* x^91103 mod G(x) */, },\n\t/* chunk_len=11520 */\n\t{ 0x4c4c2b55 /* x^276447 mod G(x) */, 0x5539e44a /* x^184287 mod G(x) */, 0x52222fea /* x^92127 mod G(x) */, },\n\t/* chunk_len=11648 */\n\t{ 0xd8ce94cb /* x^279519 mod G(x) */, 0xbc613c26 /* x^186335 mod G(x) */, 0x33776b4b /* x^93151 mod G(x) */, },\n\t/* chunk_len=11776 */\n\t{ 0xd0b5a02b /* x^282591 mod G(x) */, 0x490d3cc6 /* x^188383 mod G(x) */, 0x2fde73f8 /* x^94175 mod G(x) */, },\n\t/* chunk_len=11904 */\n\t{ 0xa223f7ec /* x^285663 mod G(x) */, 0xf0baeeb6 /* x^190431 mod G(x) */, 0x0603989b /* x^95199 mod G(x) */, },\n\t/* chunk_len=12032 */\n\t{ 0x58de337a /* x^288735 mod G(x) */, 0x3bf3d597 /* x^192479 mod G(x) */, 0xced90d99 /* x^96223 mod G(x) */, },\n\t/* chunk_len=12160 */\n\t{ 0x37f5d8f4 /* x^291807 mod G(x) */, 0x4d5b699b /* x^194527 mod G(x) */, 0xd7262e5f /* x^97247 mod G(x) */, },\n\t/* chunk_len=12288 */\n\t{ 0xfa8a435d /* x^294879 mod G(x) */, 0x64f34a05 /* x^196575 mod G(x) */, 0x4470c029 /* x^98271 mod G(x) */, },\n\t/* chunk_len=12416 */\n\t{ 0x238709fe /* x^297951 mod G(x) */, 0x52e7458f /* x^198623 mod G(x) */, 0x9a174cd3 /* x^99295 mod G(x) */, },\n\t/* chunk_len=12544 */\n\t{ 0x9e1ba6f5 /* x^301023 mod G(x) */, 0xef0272f7 /* x^200671 mod G(x) */, 0x84f40beb /* x^100319 mod G(x) */, },\n\t/* chunk_len=12672 */\n\t{ 0xcd8b57fa /* x^304095 mod G(x) */, 0x82adb0b8 /* x^202719 mod G(x) */, 0xb6f35093 /* x^101343 mod G(x) */, },\n\t/* chunk_len=12800 */\n\t{ 0x0aed142f /* x^307167 mod G(x) */, 0xb1650290 /* x^204767 mod G(x) */, 0xec855937 /* x^102367 mod G(x) */, },\n\t/* chunk_len=12928 */\n\t{ 0xd1f064db /* x^310239 mod G(x) */, 0x6e7340d3 /* x^206815 mod G(x) */, 0x5c28cb52 /* x^103391 mod G(x) */, },\n\t/* chunk_len=13056 */\n\t{ 0x464ac895 /* x^313311 mod G(x) */, 0xd2fc57c3 /* x^208863 mod G(x) */, 0xc46805ba /* x^104415 mod G(x) */, },\n\t/* chunk_len=13184 */\n\t{ 0xa0e6beea /* x^316383 mod G(x) */, 0xcfeec3d0 /* x^210911 mod G(x) */, 0x0225d214 /* x^105439 mod G(x) */, },\n\t/* chunk_len=13312 */\n\t{ 0x78703ce0 /* x^319455 mod G(x) */, 0xc60f6075 /* x^212959 mod G(x) */, 0xdf7a24ac /* x^106463 mod G(x) */, },\n\t/* chunk_len=13440 */\n\t{ 0xfea48165 /* x^322527 mod G(x) */, 0x3a9d1f97 /* x^215007 mod G(x) */, 0xc3876592 /* x^107487 mod G(x) */, },\n\t/* chunk_len=13568 */\n\t{ 0xdb89b8db /* x^325599 mod G(x) */, 0xa6172211 /* x^217055 mod G(x) */, 0x2b52dc39 /* x^108511 mod G(x) */, },\n\t/* chunk_len=13696 */\n\t{ 0x7ca03731 /* x^328671 mod G(x) */, 0x1db42849 /* x^219103 mod G(x) */, 0xc5df246e /* x^109535 mod G(x) */, },\n\t/* chunk_len=13824 */\n\t{ 0x8801d0aa /* x^331743 mod G(x) */, 0xb57c7728 /* x^221151 mod G(x) */, 0x5b0c98b9 /* x^110559 mod G(x) */, },\n\t/* chunk_len=13952 */\n\t{ 0xf89cd7f0 /* x^334815 mod G(x) */, 0xcc396a0b /* x^223199 mod G(x) */, 0xdb799c51 /* x^111583 mod G(x) */, },\n\t/* chunk_len=14080 */\n\t{ 0x1611a808 /* x^337887 mod G(x) */, 0xaeae6105 /* x^225247 mod G(x) */, 0xb939fcdf /* x^112607 mod G(x) */, },\n\t/* chunk_len=14208 */\n\t{ 0xe3cdb888 /* x^340959 mod G(x) */, 0x26387824 /* x^227295 mod G(x) */, 0x30d13e5f /* x^113631 mod G(x) */, },\n\t/* chunk_len=14336 */\n\t{ 0x552a4cf6 /* x^344031 mod G(x) */, 0xee2d04bb /* x^229343 mod G(x) */, 0x70f9947d /* x^114655 mod G(x) */, },\n\t/* chunk_len=14464 */\n\t{ 0x85e248e9 /* x^347103 mod G(x) */, 0x0a79663f /* x^231391 mod G(x) */, 0x53339cf7 /* x^115679 mod G(x) */, },\n\t/* chunk_len=14592 */\n\t{ 0x1c61c3e9 /* x^350175 mod G(x) */, 0x8ea1f680 /* x^233439 mod G(x) */, 0x54afca53 /* x^116703 mod G(x) */, },\n\t/* chunk_len=14720 */\n\t{ 0xb14cfc2b /* x^353247 mod G(x) */, 0x2e073302 /* x^235487 mod G(x) */, 0x10897992 /* x^117727 mod G(x) */, },\n\t/* chunk_len=14848 */\n\t{ 0x6ec444cc /* x^356319 mod G(x) */, 0x9e819f13 /* x^237535 mod G(x) */, 0x7a3c0a6a /* x^118751 mod G(x) */, },\n\t/* chunk_len=14976 */\n\t{ 0xe2fa5f80 /* x^359391 mod G(x) */, 0x21f15b59 /* x^239583 mod G(x) */, 0x93102436 /* x^119775 mod G(x) */, },\n\t/* chunk_len=15104 */\n\t{ 0x6d33f4c6 /* x^362463 mod G(x) */, 0x31a27455 /* x^241631 mod G(x) */, 0x1fea4d2a /* x^120799 mod G(x) */, },\n\t/* chunk_len=15232 */\n\t{ 0xb6dec609 /* x^365535 mod G(x) */, 0x4d437056 /* x^243679 mod G(x) */, 0x42eb1e2a /* x^121823 mod G(x) */, },\n\t/* chunk_len=15360 */\n\t{ 0x1846c518 /* x^368607 mod G(x) */, 0x71b74d95 /* x^245727 mod G(x) */, 0xbd2655a8 /* x^122847 mod G(x) */, },\n\t/* chunk_len=15488 */\n\t{ 0x9f947f8a /* x^371679 mod G(x) */, 0x2b501619 /* x^247775 mod G(x) */, 0xa4924b0e /* x^123871 mod G(x) */, },\n\t/* chunk_len=15616 */\n\t{ 0xb7442f4d /* x^374751 mod G(x) */, 0xba30a5d8 /* x^249823 mod G(x) */, 0x4ff61aa1 /* x^124895 mod G(x) */, },\n\t/* chunk_len=15744 */\n\t{ 0xe2c93242 /* x^377823 mod G(x) */, 0x8a2d38e8 /* x^251871 mod G(x) */, 0x70cd7f26 /* x^125919 mod G(x) */, },\n\t/* chunk_len=15872 */\n\t{ 0xcd6863df /* x^380895 mod G(x) */, 0x78fd88dc /* x^253919 mod G(x) */, 0x7ae2f6f4 /* x^126943 mod G(x) */, },\n\t/* chunk_len=16000 */\n\t{ 0xd512001d /* x^383967 mod G(x) */, 0xe6612dff /* x^255967 mod G(x) */, 0x5c4d0ca9 /* x^127967 mod G(x) */, },\n\t/* chunk_len=16128 */\n\t{ 0x4e8d6b6c /* x^387039 mod G(x) */, 0xf997967f /* x^258015 mod G(x) */, 0x2d546c53 /* x^128991 mod G(x) */, },\n\t/* chunk_len=16256 */\n\t{ 0xfa653ba1 /* x^390111 mod G(x) */, 0xc99014d4 /* x^260063 mod G(x) */, 0xa0c9fd27 /* x^130015 mod G(x) */, },\n\t/* chunk_len=16384 */\n\t{ 0x49893408 /* x^393183 mod G(x) */, 0x29c2448b /* x^262111 mod G(x) */, 0xe0ee5efe /* x^131039 mod G(x) */, },\n};\n\n/* Multipliers for implementations that use a large fixed chunk length */\n#define CRC32_FIXED_CHUNK_LEN 32768UL\n#define CRC32_FIXED_CHUNK_MULT_1 0x29c2448b /* x^262111 mod G(x) */\n#define CRC32_FIXED_CHUNK_MULT_2 0x4b912f53 /* x^524255 mod G(x) */\n#define CRC32_FIXED_CHUNK_MULT_3 0x454c93be /* x^786399 mod G(x) */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/crc32_tables.h",
    "content": "/*\n * crc32_tables.h - data tables for CRC-32 computation\n *\n * THIS FILE WAS GENERATED BY gen-crc32-consts.py.  DO NOT EDIT.\n */\n\nstatic const u32 crc32_slice1_table[] MAYBE_UNUSED = {\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,\n\t0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n\t0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n\t0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,\n\t0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n\t0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,\n\t0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,\n\t0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n\t0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,\n\t0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,\n\t0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n\t0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,\n\t0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n\t0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n\t0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,\n\t0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,\n\t0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n\t0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n\t0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,\n\t0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n\t0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,\n\t0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,\n\t0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n\t0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,\n\t0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,\n\t0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n\t0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,\n\t0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n\t0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n\t0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,\n\t0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,\n\t0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n\t0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n};\n\nstatic const u32 crc32_slice8_table[] MAYBE_UNUSED = {\n\t0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,\n\t0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,\n\t0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n\t0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,\n\t0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n\t0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n\t0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,\n\t0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,\n\t0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n\t0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n\t0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,\n\t0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n\t0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,\n\t0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,\n\t0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n\t0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,\n\t0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,\n\t0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n\t0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,\n\t0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n\t0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n\t0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,\n\t0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,\n\t0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n\t0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n\t0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,\n\t0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n\t0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,\n\t0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,\n\t0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n\t0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,\n\t0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,\n\t0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n\t0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,\n\t0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n\t0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n\t0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,\n\t0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,\n\t0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n\t0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n\t0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,\n\t0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n\t0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,\n\t0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,\n\t0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n\t0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,\n\t0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,\n\t0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n\t0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,\n\t0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n\t0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n\t0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,\n\t0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,\n\t0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n\t0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n\t0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,\n\t0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n\t0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,\n\t0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,\n\t0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n\t0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,\n\t0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,\n\t0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n\t0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n\t0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,\n\t0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,\n\t0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,\n\t0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,\n\t0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,\n\t0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,\n\t0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,\n\t0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,\n\t0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,\n\t0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,\n\t0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,\n\t0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,\n\t0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,\n\t0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,\n\t0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,\n\t0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,\n\t0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,\n\t0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,\n\t0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,\n\t0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,\n\t0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,\n\t0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,\n\t0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,\n\t0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,\n\t0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,\n\t0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,\n\t0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,\n\t0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,\n\t0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,\n\t0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,\n\t0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,\n\t0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,\n\t0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,\n\t0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,\n\t0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,\n\t0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,\n\t0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,\n\t0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,\n\t0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,\n\t0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,\n\t0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,\n\t0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,\n\t0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,\n\t0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,\n\t0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,\n\t0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,\n\t0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,\n\t0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,\n\t0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,\n\t0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,\n\t0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,\n\t0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,\n\t0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,\n\t0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,\n\t0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,\n\t0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,\n\t0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,\n\t0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,\n\t0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,\n\t0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,\n\t0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,\n\t0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,\n\t0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,\n\t0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,\n\t0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,\n\t0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,\n\t0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,\n\t0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,\n\t0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,\n\t0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,\n\t0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,\n\t0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,\n\t0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,\n\t0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,\n\t0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,\n\t0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,\n\t0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,\n\t0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,\n\t0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,\n\t0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,\n\t0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,\n\t0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,\n\t0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,\n\t0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,\n\t0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,\n\t0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,\n\t0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,\n\t0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,\n\t0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,\n\t0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,\n\t0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,\n\t0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,\n\t0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,\n\t0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,\n\t0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,\n\t0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,\n\t0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,\n\t0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,\n\t0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,\n\t0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,\n\t0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,\n\t0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,\n\t0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,\n\t0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,\n\t0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,\n\t0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,\n\t0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,\n\t0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,\n\t0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,\n\t0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,\n\t0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,\n\t0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,\n\t0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,\n\t0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,\n\t0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,\n\t0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,\n\t0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,\n\t0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,\n\t0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,\n\t0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,\n\t0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,\n\t0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,\n\t0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,\n\t0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,\n\t0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,\n\t0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,\n\t0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,\n\t0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,\n\t0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,\n\t0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,\n\t0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,\n\t0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,\n\t0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,\n\t0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,\n\t0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,\n\t0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,\n\t0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,\n\t0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,\n\t0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,\n\t0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,\n\t0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,\n\t0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,\n\t0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,\n\t0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,\n\t0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,\n\t0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,\n\t0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,\n\t0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,\n\t0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,\n\t0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,\n\t0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,\n\t0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,\n\t0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,\n\t0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,\n\t0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,\n\t0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,\n\t0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,\n\t0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,\n\t0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,\n\t0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,\n\t0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,\n\t0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,\n\t0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,\n\t0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,\n\t0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,\n\t0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,\n\t0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,\n\t0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,\n\t0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,\n\t0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,\n\t0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,\n\t0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,\n\t0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,\n\t0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,\n\t0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,\n\t0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,\n\t0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,\n\t0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,\n\t0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,\n\t0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,\n\t0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,\n\t0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,\n\t0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,\n\t0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,\n\t0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,\n\t0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,\n\t0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,\n\t0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,\n\t0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,\n\t0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,\n\t0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,\n\t0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1,\n\t0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0,\n\t0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10,\n\t0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111,\n\t0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1,\n\t0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,\n\t0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92,\n\t0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693,\n\t0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053,\n\t0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4,\n\t0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,\n\t0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15,\n\t0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5,\n\t0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256,\n\t0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496,\n\t0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,\n\t0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57,\n\t0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299,\n\t0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459,\n\t0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958,\n\t0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,\n\t0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b,\n\t0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db,\n\t0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda,\n\t0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a,\n\t0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,\n\t0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d,\n\t0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c,\n\t0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c,\n\t0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f,\n\t0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,\n\t0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de,\n\t0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e,\n\t0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42,\n\t0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82,\n\t0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,\n\t0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743,\n\t0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0,\n\t0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00,\n\t0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601,\n\t0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,\n\t0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546,\n\t0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386,\n\t0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87,\n\t0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847,\n\t0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,\n\t0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404,\n\t0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905,\n\t0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5,\n\t0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b,\n\t0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,\n\t0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca,\n\t0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a,\n\t0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589,\n\t0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349,\n\t0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,\n\t0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888,\n\t0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f,\n\t0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf,\n\t0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce,\n\t0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,\n\t0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d,\n\t0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d,\n\t0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c,\n\t0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c,\n\t0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae,\n\t0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8,\n\t0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3,\n\t0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5,\n\t0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,\n\t0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223,\n\t0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258,\n\t0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e,\n\t0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798,\n\t0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,\n\t0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5,\n\t0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3,\n\t0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503,\n\t0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715,\n\t0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,\n\t0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578,\n\t0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2,\n\t0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4,\n\t0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf,\n\t0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,\n\t0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59,\n\t0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f,\n\t0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834,\n\t0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22,\n\t0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,\n\t0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2,\n\t0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99,\n\t0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f,\n\t0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f,\n\t0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,\n\t0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02,\n\t0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14,\n\t0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676,\n\t0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460,\n\t0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,\n\t0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d,\n\t0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed,\n\t0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb,\n\t0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680,\n\t0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,\n\t0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340,\n\t0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156,\n\t0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d,\n\t0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b,\n\t0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,\n\t0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd,\n\t0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6,\n\t0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0,\n\t0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a,\n\t0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,\n\t0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77,\n\t0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61,\n\t0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81,\n\t0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97,\n\t0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,\n\t0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa,\n\t0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c,\n\t0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a,\n\t0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41,\n\t0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,\n\t0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7,\n\t0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1,\n\t0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da,\n\t0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc,\n\t0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d,\n\t0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e,\n\t0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa,\n\t0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9,\n\t0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,\n\t0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240,\n\t0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834,\n\t0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27,\n\t0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301,\n\t0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,\n\t0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66,\n\t0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975,\n\t0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf,\n\t0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc,\n\t0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,\n\t0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb,\n\t0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4,\n\t0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7,\n\t0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183,\n\t0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,\n\t0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a,\n\t0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739,\n\t0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d,\n\t0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e,\n\t0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,\n\t0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b,\n\t0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f,\n\t0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c,\n\t0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6,\n\t0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,\n\t0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1,\n\t0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2,\n\t0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f,\n\t0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c,\n\t0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,\n\t0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b,\n\t0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1,\n\t0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2,\n\t0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6,\n\t0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,\n\t0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3,\n\t0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0,\n\t0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794,\n\t0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387,\n\t0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,\n\t0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e,\n\t0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a,\n\t0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49,\n\t0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516,\n\t0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,\n\t0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71,\n\t0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62,\n\t0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8,\n\t0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb,\n\t0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,\n\t0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac,\n\t0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a,\n\t0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899,\n\t0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed,\n\t0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,\n\t0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044,\n\t0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457,\n\t0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23,\n\t0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30,\n\t0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3,\n\t0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919,\n\t0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56,\n\t0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac,\n\t0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,\n\t0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832,\n\t0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d,\n\t0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387,\n\t0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5,\n\t0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,\n\t0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00,\n\t0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa,\n\t0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e,\n\t0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64,\n\t0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,\n\t0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1,\n\t0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e,\n\t0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4,\n\t0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb,\n\t0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,\n\t0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425,\n\t0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf,\n\t0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90,\n\t0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a,\n\t0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,\n\t0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2,\n\t0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced,\n\t0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217,\n\t0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673,\n\t0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,\n\t0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6,\n\t0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c,\n\t0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239,\n\t0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3,\n\t0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,\n\t0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776,\n\t0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312,\n\t0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8,\n\t0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7,\n\t0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,\n\t0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f,\n\t0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95,\n\t0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda,\n\t0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520,\n\t0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,\n\t0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe,\n\t0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1,\n\t0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b,\n\t0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4,\n\t0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,\n\t0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61,\n\t0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b,\n\t0x061d761c, 0xcab77682, 0x44387161, 0x889271ff,\n\t0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05,\n\t0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,\n\t0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0,\n\t0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282,\n\t0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78,\n\t0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937,\n\t0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,\n\t0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9,\n\t0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53,\n\t0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c,\n\t0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6,\n};\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/decompress_template.h",
    "content": "/*\n * decompress_template.h\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * This is the actual DEFLATE decompression routine, lifted out of\n * deflate_decompress.c so that it can be compiled multiple times with different\n * target instruction sets.\n */\n\n#ifndef ATTRIBUTES\n#  define ATTRIBUTES\n#endif\n#ifndef EXTRACT_VARBITS\n#  define EXTRACT_VARBITS(word, count)\t((word) & BITMASK(count))\n#endif\n#ifndef EXTRACT_VARBITS8\n#  define EXTRACT_VARBITS8(word, count)\t((word) & BITMASK((u8)(count)))\n#endif\n\nstatic ATTRIBUTES MAYBE_UNUSED enum libdeflate_result\nFUNCNAME(struct libdeflate_decompressor * restrict d,\n\t const void * restrict in, size_t in_nbytes,\n\t void * restrict out, size_t out_nbytes_avail,\n\t size_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret)\n{\n\tu8 *out_next = out;\n\tu8 * const out_end = out_next + out_nbytes_avail;\n\tu8 * const out_fastloop_end =\n\t\tout_end - MIN(out_nbytes_avail, FASTLOOP_MAX_BYTES_WRITTEN);\n\n\t/* Input bitstream state; see deflate_decompress.c for documentation */\n\tconst u8 *in_next = in;\n\tconst u8 * const in_end = in_next + in_nbytes;\n\tconst u8 * const in_fastloop_end =\n\t\tin_end - MIN(in_nbytes, FASTLOOP_MAX_BYTES_READ);\n\tbitbuf_t bitbuf = 0;\n\tbitbuf_t saved_bitbuf;\n\tu32 bitsleft = 0;\n\tsize_t overread_count = 0;\n\n\tbool is_final_block;\n\tunsigned block_type;\n\tunsigned num_litlen_syms;\n\tunsigned num_offset_syms;\n\tbitbuf_t litlen_tablemask;\n\tu32 entry;\n\nnext_block:\n\t/* Starting to read the next block */\n\t;\n\n\tSTATIC_ASSERT(CAN_CONSUME(1 + 2 + 5 + 5 + 4 + 3));\n\tREFILL_BITS();\n\n\t/* BFINAL: 1 bit */\n\tis_final_block = bitbuf & BITMASK(1);\n\n\t/* BTYPE: 2 bits */\n\tblock_type = (bitbuf >> 1) & BITMASK(2);\n\n\tif (block_type == DEFLATE_BLOCKTYPE_DYNAMIC_HUFFMAN) {\n\n\t\t/* Dynamic Huffman block */\n\n\t\t/* The order in which precode lengths are stored */\n\t\tstatic const u8 deflate_precode_lens_permutation[DEFLATE_NUM_PRECODE_SYMS] = {\n\t\t\t16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15\n\t\t};\n\n\t\tunsigned num_explicit_precode_lens;\n\t\tunsigned i;\n\n\t\t/* Read the codeword length counts. */\n\n\t\tSTATIC_ASSERT(DEFLATE_NUM_LITLEN_SYMS == 257 + BITMASK(5));\n\t\tnum_litlen_syms = 257 + ((bitbuf >> 3) & BITMASK(5));\n\n\t\tSTATIC_ASSERT(DEFLATE_NUM_OFFSET_SYMS == 1 + BITMASK(5));\n\t\tnum_offset_syms = 1 + ((bitbuf >> 8) & BITMASK(5));\n\n\t\tSTATIC_ASSERT(DEFLATE_NUM_PRECODE_SYMS == 4 + BITMASK(4));\n\t\tnum_explicit_precode_lens = 4 + ((bitbuf >> 13) & BITMASK(4));\n\n\t\td->static_codes_loaded = false;\n\n\t\t/*\n\t\t * Read the precode codeword lengths.\n\t\t *\n\t\t * A 64-bit bitbuffer is just one bit too small to hold the\n\t\t * maximum number of precode lens, so to minimize branches we\n\t\t * merge one len with the previous fields.\n\t\t */\n\t\tSTATIC_ASSERT(DEFLATE_MAX_PRE_CODEWORD_LEN == (1 << 3) - 1);\n\t\tif (CAN_CONSUME(3 * (DEFLATE_NUM_PRECODE_SYMS - 1))) {\n\t\t\td->u.precode_lens[deflate_precode_lens_permutation[0]] =\n\t\t\t\t(bitbuf >> 17) & BITMASK(3);\n\t\t\tbitbuf >>= 20;\n\t\t\tbitsleft -= 20;\n\t\t\tREFILL_BITS();\n\t\t\ti = 1;\n\t\t\tdo {\n\t\t\t\td->u.precode_lens[deflate_precode_lens_permutation[i]] =\n\t\t\t\t\tbitbuf & BITMASK(3);\n\t\t\t\tbitbuf >>= 3;\n\t\t\t\tbitsleft -= 3;\n\t\t\t} while (++i < num_explicit_precode_lens);\n\t\t} else {\n\t\t\tbitbuf >>= 17;\n\t\t\tbitsleft -= 17;\n\t\t\ti = 0;\n\t\t\tdo {\n\t\t\t\tif ((u8)bitsleft < 3)\n\t\t\t\t\tREFILL_BITS();\n\t\t\t\td->u.precode_lens[deflate_precode_lens_permutation[i]] =\n\t\t\t\t\tbitbuf & BITMASK(3);\n\t\t\t\tbitbuf >>= 3;\n\t\t\t\tbitsleft -= 3;\n\t\t\t} while (++i < num_explicit_precode_lens);\n\t\t}\n\t\tfor (; i < DEFLATE_NUM_PRECODE_SYMS; i++)\n\t\t\td->u.precode_lens[deflate_precode_lens_permutation[i]] = 0;\n\n\t\t/* Build the decode table for the precode. */\n\t\tSAFETY_CHECK(build_precode_decode_table(d));\n\n\t\t/* Decode the litlen and offset codeword lengths. */\n\t\ti = 0;\n\t\tdo {\n\t\t\tunsigned presym;\n\t\t\tu8 rep_val;\n\t\t\tunsigned rep_count;\n\n\t\t\tif ((u8)bitsleft < DEFLATE_MAX_PRE_CODEWORD_LEN + 7)\n\t\t\t\tREFILL_BITS();\n\n\t\t\t/*\n\t\t\t * The code below assumes that the precode decode table\n\t\t\t * doesn't have any subtables.\n\t\t\t */\n\t\t\tSTATIC_ASSERT(PRECODE_TABLEBITS == DEFLATE_MAX_PRE_CODEWORD_LEN);\n\n\t\t\t/* Decode the next precode symbol. */\n\t\t\tentry = d->u.l.precode_decode_table[\n\t\t\t\tbitbuf & BITMASK(DEFLATE_MAX_PRE_CODEWORD_LEN)];\n\t\t\tbitbuf >>= (u8)entry;\n\t\t\tbitsleft -= entry; /* optimization: subtract full entry */\n\t\t\tpresym = entry >> 16;\n\n\t\t\tif (presym < 16) {\n\t\t\t\t/* Explicit codeword length */\n\t\t\t\td->u.l.lens[i++] = presym;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Run-length encoded codeword lengths */\n\n\t\t\t/*\n\t\t\t * Note: we don't need to immediately verify that the\n\t\t\t * repeat count doesn't overflow the number of elements,\n\t\t\t * since we've sized the lens array to have enough extra\n\t\t\t * space to allow for the worst-case overrun (138 zeroes\n\t\t\t * when only 1 length was remaining).\n\t\t\t *\n\t\t\t * In the case of the small repeat counts (presyms 16\n\t\t\t * and 17), it is fastest to always write the maximum\n\t\t\t * number of entries.  That gets rid of branches that\n\t\t\t * would otherwise be required.\n\t\t\t *\n\t\t\t * It is not just because of the numerical order that\n\t\t\t * our checks go in the order 'presym < 16', 'presym ==\n\t\t\t * 16', and 'presym == 17'.  For typical data this is\n\t\t\t * ordered from most frequent to least frequent case.\n\t\t\t */\n\t\t\tSTATIC_ASSERT(DEFLATE_MAX_LENS_OVERRUN == 138 - 1);\n\n\t\t\tif (presym == 16) {\n\t\t\t\t/* Repeat the previous length 3 - 6 times. */\n\t\t\t\tSAFETY_CHECK(i != 0);\n\t\t\t\trep_val = d->u.l.lens[i - 1];\n\t\t\t\tSTATIC_ASSERT(3 + BITMASK(2) == 6);\n\t\t\t\trep_count = 3 + (bitbuf & BITMASK(2));\n\t\t\t\tbitbuf >>= 2;\n\t\t\t\tbitsleft -= 2;\n\t\t\t\td->u.l.lens[i + 0] = rep_val;\n\t\t\t\td->u.l.lens[i + 1] = rep_val;\n\t\t\t\td->u.l.lens[i + 2] = rep_val;\n\t\t\t\td->u.l.lens[i + 3] = rep_val;\n\t\t\t\td->u.l.lens[i + 4] = rep_val;\n\t\t\t\td->u.l.lens[i + 5] = rep_val;\n\t\t\t\ti += rep_count;\n\t\t\t} else if (presym == 17) {\n\t\t\t\t/* Repeat zero 3 - 10 times. */\n\t\t\t\tSTATIC_ASSERT(3 + BITMASK(3) == 10);\n\t\t\t\trep_count = 3 + (bitbuf & BITMASK(3));\n\t\t\t\tbitbuf >>= 3;\n\t\t\t\tbitsleft -= 3;\n\t\t\t\td->u.l.lens[i + 0] = 0;\n\t\t\t\td->u.l.lens[i + 1] = 0;\n\t\t\t\td->u.l.lens[i + 2] = 0;\n\t\t\t\td->u.l.lens[i + 3] = 0;\n\t\t\t\td->u.l.lens[i + 4] = 0;\n\t\t\t\td->u.l.lens[i + 5] = 0;\n\t\t\t\td->u.l.lens[i + 6] = 0;\n\t\t\t\td->u.l.lens[i + 7] = 0;\n\t\t\t\td->u.l.lens[i + 8] = 0;\n\t\t\t\td->u.l.lens[i + 9] = 0;\n\t\t\t\ti += rep_count;\n\t\t\t} else {\n\t\t\t\t/* Repeat zero 11 - 138 times. */\n\t\t\t\tSTATIC_ASSERT(11 + BITMASK(7) == 138);\n\t\t\t\trep_count = 11 + (bitbuf & BITMASK(7));\n\t\t\t\tbitbuf >>= 7;\n\t\t\t\tbitsleft -= 7;\n\t\t\t\tmemset(&d->u.l.lens[i], 0,\n\t\t\t\t       rep_count * sizeof(d->u.l.lens[i]));\n\t\t\t\ti += rep_count;\n\t\t\t}\n\t\t} while (i < num_litlen_syms + num_offset_syms);\n\n\t\t/* Unnecessary, but check this for consistency with zlib. */\n\t\tSAFETY_CHECK(i == num_litlen_syms + num_offset_syms);\n\n\t} else if (block_type == DEFLATE_BLOCKTYPE_UNCOMPRESSED) {\n\t\tu16 len, nlen;\n\n\t\t/*\n\t\t * Uncompressed block: copy 'len' bytes literally from the input\n\t\t * buffer to the output buffer.\n\t\t */\n\n\t\tbitsleft -= 3; /* for BTYPE and BFINAL */\n\n\t\t/*\n\t\t * Align the bitstream to the next byte boundary.  This means\n\t\t * the next byte boundary as if we were reading a byte at a\n\t\t * time.  Therefore, we have to rewind 'in_next' by any bytes\n\t\t * that have been refilled but not actually consumed yet (not\n\t\t * counting overread bytes, which don't increment 'in_next').\n\t\t */\n\t\tbitsleft = (u8)bitsleft;\n\t\tSAFETY_CHECK(overread_count <= (bitsleft >> 3));\n\t\tin_next -= (bitsleft >> 3) - overread_count;\n\t\toverread_count = 0;\n\t\tbitbuf = 0;\n\t\tbitsleft = 0;\n\n\t\tSAFETY_CHECK(in_end - in_next >= 4);\n\t\tlen = get_unaligned_le16(in_next);\n\t\tnlen = get_unaligned_le16(in_next + 2);\n\t\tin_next += 4;\n\n\t\tSAFETY_CHECK(len == (u16)~nlen);\n\t\tif (unlikely(len > out_end - out_next))\n\t\t\treturn LIBDEFLATE_INSUFFICIENT_SPACE;\n\t\tSAFETY_CHECK(len <= in_end - in_next);\n\n\t\tmemcpy(out_next, in_next, len);\n\t\tin_next += len;\n\t\tout_next += len;\n\n\t\tgoto block_done;\n\n\t} else {\n\t\tunsigned i;\n\n\t\tSAFETY_CHECK(block_type == DEFLATE_BLOCKTYPE_STATIC_HUFFMAN);\n\n\t\t/*\n\t\t * Static Huffman block: build the decode tables for the static\n\t\t * codes.  Skip doing so if the tables are already set up from\n\t\t * an earlier static block; this speeds up decompression of\n\t\t * degenerate input of many empty or very short static blocks.\n\t\t *\n\t\t * Afterwards, the remainder is the same as decompressing a\n\t\t * dynamic Huffman block.\n\t\t */\n\n\t\tbitbuf >>= 3; /* for BTYPE and BFINAL */\n\t\tbitsleft -= 3;\n\n\t\tif (d->static_codes_loaded)\n\t\t\tgoto have_decode_tables;\n\n\t\td->static_codes_loaded = true;\n\n\t\tSTATIC_ASSERT(DEFLATE_NUM_LITLEN_SYMS == 288);\n\t\tSTATIC_ASSERT(DEFLATE_NUM_OFFSET_SYMS == 32);\n\n\t\tfor (i = 0; i < 144; i++)\n\t\t\td->u.l.lens[i] = 8;\n\t\tfor (; i < 256; i++)\n\t\t\td->u.l.lens[i] = 9;\n\t\tfor (; i < 280; i++)\n\t\t\td->u.l.lens[i] = 7;\n\t\tfor (; i < 288; i++)\n\t\t\td->u.l.lens[i] = 8;\n\n\t\tfor (; i < 288 + 32; i++)\n\t\t\td->u.l.lens[i] = 5;\n\n\t\tnum_litlen_syms = 288;\n\t\tnum_offset_syms = 32;\n\t}\n\n\t/* Decompressing a Huffman block (either dynamic or static) */\n\n\tSAFETY_CHECK(build_offset_decode_table(d, num_litlen_syms, num_offset_syms));\n\tSAFETY_CHECK(build_litlen_decode_table(d, num_litlen_syms, num_offset_syms));\nhave_decode_tables:\n\tlitlen_tablemask = BITMASK(d->litlen_tablebits);\n\n\t/*\n\t * This is the \"fastloop\" for decoding literals and matches.  It does\n\t * bounds checks on in_next and out_next in the loop conditions so that\n\t * additional bounds checks aren't needed inside the loop body.\n\t *\n\t * To reduce latency, the bitbuffer is refilled and the next litlen\n\t * decode table entry is preloaded before each loop iteration.\n\t */\n\tif (in_next >= in_fastloop_end || out_next >= out_fastloop_end)\n\t\tgoto generic_loop;\n\tREFILL_BITS_IN_FASTLOOP();\n\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\tdo {\n\t\tu32 length, offset, lit;\n\t\tconst u8 *src;\n\t\tu8 *dst;\n\n\t\t/*\n\t\t * Consume the bits for the litlen decode table entry.  Save the\n\t\t * original bitbuf for later, in case the extra match length\n\t\t * bits need to be extracted from it.\n\t\t */\n\t\tsaved_bitbuf = bitbuf;\n\t\tbitbuf >>= (u8)entry;\n\t\tbitsleft -= entry; /* optimization: subtract full entry */\n\n\t\t/*\n\t\t * Begin by checking for a \"fast\" literal, i.e. a literal that\n\t\t * doesn't need a subtable.\n\t\t */\n\t\tif (entry & HUFFDEC_LITERAL) {\n\t\t\t/*\n\t\t\t * On 64-bit platforms, we decode up to 2 extra fast\n\t\t\t * literals in addition to the primary item, as this\n\t\t\t * increases performance and still leaves enough bits\n\t\t\t * remaining for what follows.  We could actually do 3,\n\t\t\t * assuming LITLEN_TABLEBITS=11, but that actually\n\t\t\t * decreases performance slightly (perhaps by messing\n\t\t\t * with the branch prediction of the conditional refill\n\t\t\t * that happens later while decoding the match offset).\n\t\t\t *\n\t\t\t * Note: the definitions of FASTLOOP_MAX_BYTES_WRITTEN\n\t\t\t * and FASTLOOP_MAX_BYTES_READ need to be updated if the\n\t\t\t * number of extra literals decoded here is changed.\n\t\t\t */\n\t\t\tif (/* enough bits for 2 fast literals + length + offset preload? */\n\t\t\t    CAN_CONSUME_AND_THEN_PRELOAD(2 * LITLEN_TABLEBITS +\n\t\t\t\t\t\t\t LENGTH_MAXBITS,\n\t\t\t\t\t\t\t OFFSET_TABLEBITS) &&\n\t\t\t    /* enough bits for 2 fast literals + slow literal + litlen preload? */\n\t\t\t    CAN_CONSUME_AND_THEN_PRELOAD(2 * LITLEN_TABLEBITS +\n\t\t\t\t\t\t\t DEFLATE_MAX_LITLEN_CODEWORD_LEN,\n\t\t\t\t\t\t\t LITLEN_TABLEBITS)) {\n\t\t\t\t/* 1st extra fast literal */\n\t\t\t\tlit = entry >> 16;\n\t\t\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\t\t\tsaved_bitbuf = bitbuf;\n\t\t\t\tbitbuf >>= (u8)entry;\n\t\t\t\tbitsleft -= entry;\n\t\t\t\t*out_next++ = lit;\n\t\t\t\tif (entry & HUFFDEC_LITERAL) {\n\t\t\t\t\t/* 2nd extra fast literal */\n\t\t\t\t\tlit = entry >> 16;\n\t\t\t\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\t\t\t\tsaved_bitbuf = bitbuf;\n\t\t\t\t\tbitbuf >>= (u8)entry;\n\t\t\t\t\tbitsleft -= entry;\n\t\t\t\t\t*out_next++ = lit;\n\t\t\t\t\tif (entry & HUFFDEC_LITERAL) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Another fast literal, but\n\t\t\t\t\t\t * this one is in lieu of the\n\t\t\t\t\t\t * primary item, so it doesn't\n\t\t\t\t\t\t * count as one of the extras.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tlit = entry >> 16;\n\t\t\t\t\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\t\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\t\t\t\t*out_next++ = lit;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * Decode a literal.  While doing so, preload\n\t\t\t\t * the next litlen decode table entry and refill\n\t\t\t\t * the bitbuffer.  To reduce latency, we've\n\t\t\t\t * arranged for there to be enough \"preloadable\"\n\t\t\t\t * bits remaining to do the table preload\n\t\t\t\t * independently of the refill.\n\t\t\t\t */\n\t\t\t\tSTATIC_ASSERT(CAN_CONSUME_AND_THEN_PRELOAD(\n\t\t\t\t\t\tLITLEN_TABLEBITS, LITLEN_TABLEBITS));\n\t\t\t\tlit = entry >> 16;\n\t\t\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\t\t*out_next++ = lit;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * It's not a literal entry, so it can be a length entry, a\n\t\t * subtable pointer entry, or an end-of-block entry.  Detect the\n\t\t * two unlikely cases by testing the HUFFDEC_EXCEPTIONAL flag.\n\t\t */\n\t\tif (unlikely(entry & HUFFDEC_EXCEPTIONAL)) {\n\t\t\t/* Subtable pointer or end-of-block entry */\n\n\t\t\tif (unlikely(entry & HUFFDEC_END_OF_BLOCK))\n\t\t\t\tgoto block_done;\n\n\t\t\t/*\n\t\t\t * A subtable is required.  Load and consume the\n\t\t\t * subtable entry.  The subtable entry can be of any\n\t\t\t * type: literal, length, or end-of-block.\n\t\t\t */\n\t\t\tentry = d->u.litlen_decode_table[(entry >> 16) +\n\t\t\t\tEXTRACT_VARBITS(bitbuf, (entry >> 8) & 0x3F)];\n\t\t\tsaved_bitbuf = bitbuf;\n\t\t\tbitbuf >>= (u8)entry;\n\t\t\tbitsleft -= entry;\n\n\t\t\t/*\n\t\t\t * 32-bit platforms that use the byte-at-a-time refill\n\t\t\t * method have to do a refill here for there to always\n\t\t\t * be enough bits to decode a literal that requires a\n\t\t\t * subtable, then preload the next litlen decode table\n\t\t\t * entry; or to decode a match length that requires a\n\t\t\t * subtable, then preload the offset decode table entry.\n\t\t\t */\n\t\t\tif (!CAN_CONSUME_AND_THEN_PRELOAD(DEFLATE_MAX_LITLEN_CODEWORD_LEN,\n\t\t\t\t\t\t\t  LITLEN_TABLEBITS) ||\n\t\t\t    !CAN_CONSUME_AND_THEN_PRELOAD(LENGTH_MAXBITS,\n\t\t\t\t\t\t\t  OFFSET_TABLEBITS))\n\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\tif (entry & HUFFDEC_LITERAL) {\n\t\t\t\t/* Decode a literal that required a subtable. */\n\t\t\t\tlit = entry >> 16;\n\t\t\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\t\t*out_next++ = lit;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (unlikely(entry & HUFFDEC_END_OF_BLOCK))\n\t\t\t\tgoto block_done;\n\t\t\t/* Else, it's a length that required a subtable. */\n\t\t}\n\n\t\t/*\n\t\t * Decode the match length: the length base value associated\n\t\t * with the litlen symbol (which we extract from the decode\n\t\t * table entry), plus the extra length bits.  We don't need to\n\t\t * consume the extra length bits here, as they were included in\n\t\t * the bits consumed by the entry earlier.  We also don't need\n\t\t * to check for too-long matches here, as this is inside the\n\t\t * fastloop where it's already been verified that the output\n\t\t * buffer has enough space remaining to copy a max-length match.\n\t\t */\n\t\tlength = entry >> 16;\n\t\tlength += EXTRACT_VARBITS8(saved_bitbuf, entry) >> (u8)(entry >> 8);\n\n\t\t/*\n\t\t * Decode the match offset.  There are enough \"preloadable\" bits\n\t\t * remaining to preload the offset decode table entry, but a\n\t\t * refill might be needed before consuming it.\n\t\t */\n\t\tSTATIC_ASSERT(CAN_CONSUME_AND_THEN_PRELOAD(LENGTH_MAXFASTBITS,\n\t\t\t\t\t\t\t   OFFSET_TABLEBITS));\n\t\tentry = d->offset_decode_table[bitbuf & BITMASK(OFFSET_TABLEBITS)];\n\t\tif (CAN_CONSUME_AND_THEN_PRELOAD(OFFSET_MAXBITS,\n\t\t\t\t\t\t LITLEN_TABLEBITS)) {\n\t\t\t/*\n\t\t\t * Decoding a match offset on a 64-bit platform.  We may\n\t\t\t * need to refill once, but then we can decode the whole\n\t\t\t * offset and preload the next litlen table entry.\n\t\t\t */\n\t\t\tif (unlikely(entry & HUFFDEC_EXCEPTIONAL)) {\n\t\t\t\t/* Offset codeword requires a subtable */\n\t\t\t\tif (unlikely((u8)bitsleft < OFFSET_MAXBITS +\n\t\t\t\t\t     LITLEN_TABLEBITS - PRELOAD_SLACK))\n\t\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\t\tbitbuf >>= OFFSET_TABLEBITS;\n\t\t\t\tbitsleft -= OFFSET_TABLEBITS;\n\t\t\t\tentry = d->offset_decode_table[(entry >> 16) +\n\t\t\t\t\tEXTRACT_VARBITS(bitbuf, (entry >> 8) & 0x3F)];\n\t\t\t} else if (unlikely((u8)bitsleft < OFFSET_MAXFASTBITS +\n\t\t\t\t\t    LITLEN_TABLEBITS - PRELOAD_SLACK))\n\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t} else {\n\t\t\t/* Decoding a match offset on a 32-bit platform */\n\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\tif (unlikely(entry & HUFFDEC_EXCEPTIONAL)) {\n\t\t\t\t/* Offset codeword requires a subtable */\n\t\t\t\tbitbuf >>= OFFSET_TABLEBITS;\n\t\t\t\tbitsleft -= OFFSET_TABLEBITS;\n\t\t\t\tentry = d->offset_decode_table[(entry >> 16) +\n\t\t\t\t\tEXTRACT_VARBITS(bitbuf, (entry >> 8) & 0x3F)];\n\t\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\t\t\t/* No further refill needed before extra bits */\n\t\t\t\tSTATIC_ASSERT(CAN_CONSUME(\n\t\t\t\t\tOFFSET_MAXBITS - OFFSET_TABLEBITS));\n\t\t\t} else {\n\t\t\t\t/* No refill needed before extra bits */\n\t\t\t\tSTATIC_ASSERT(CAN_CONSUME(OFFSET_MAXFASTBITS));\n\t\t\t}\n\t\t}\n\t\tsaved_bitbuf = bitbuf;\n\t\tbitbuf >>= (u8)entry;\n\t\tbitsleft -= entry; /* optimization: subtract full entry */\n\t\toffset = entry >> 16;\n\t\toffset += EXTRACT_VARBITS8(saved_bitbuf, entry) >> (u8)(entry >> 8);\n\n\t\t/* Validate the match offset; needed even in the fastloop. */\n\t\tSAFETY_CHECK(offset <= out_next - (const u8 *)out);\n\t\tsrc = out_next - offset;\n\t\tdst = out_next;\n\t\tout_next += length;\n\n\t\t/*\n\t\t * Before starting to issue the instructions to copy the match,\n\t\t * refill the bitbuffer and preload the litlen decode table\n\t\t * entry for the next loop iteration.  This can increase\n\t\t * performance by allowing the latency of the match copy to\n\t\t * overlap with these other operations.  To further reduce\n\t\t * latency, we've arranged for there to be enough bits remaining\n\t\t * to do the table preload independently of the refill, except\n\t\t * on 32-bit platforms using the byte-at-a-time refill method.\n\t\t */\n\t\tif (!CAN_CONSUME_AND_THEN_PRELOAD(\n\t\t\tMAX(OFFSET_MAXBITS - OFFSET_TABLEBITS,\n\t\t\t    OFFSET_MAXFASTBITS),\n\t\t\tLITLEN_TABLEBITS) &&\n\t\t    unlikely((u8)bitsleft < LITLEN_TABLEBITS - PRELOAD_SLACK))\n\t\t\tREFILL_BITS_IN_FASTLOOP();\n\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\tREFILL_BITS_IN_FASTLOOP();\n\n\t\t/*\n\t\t * Copy the match.  On most CPUs the fastest method is a\n\t\t * word-at-a-time copy, unconditionally copying about 5 words\n\t\t * since this is enough for most matches without being too much.\n\t\t *\n\t\t * The normal word-at-a-time copy works for offset >= WORDBYTES,\n\t\t * which is most cases.  The case of offset == 1 is also common\n\t\t * and is worth optimizing for, since it is just RLE encoding of\n\t\t * the previous byte, which is the result of compressing long\n\t\t * runs of the same byte.\n\t\t *\n\t\t * Writing past the match 'length' is allowed here, since it's\n\t\t * been ensured there is enough output space left for a slight\n\t\t * overrun.  FASTLOOP_MAX_BYTES_WRITTEN needs to be updated if\n\t\t * the maximum possible overrun here is changed.\n\t\t */\n\t\tif (UNALIGNED_ACCESS_IS_FAST && offset >= WORDBYTES) {\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += WORDBYTES;\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += WORDBYTES;\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += WORDBYTES;\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += WORDBYTES;\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += WORDBYTES;\n\t\t\tdst += WORDBYTES;\n\t\t\twhile (dst < out_next) {\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += WORDBYTES;\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += WORDBYTES;\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += WORDBYTES;\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += WORDBYTES;\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += WORDBYTES;\n\t\t\t\tdst += WORDBYTES;\n\t\t\t}\n\t\t} else if (UNALIGNED_ACCESS_IS_FAST && offset == 1) {\n\t\t\tmachine_word_t v;\n\n\t\t\t/*\n\t\t\t * This part tends to get auto-vectorized, so keep it\n\t\t\t * copying a multiple of 16 bytes at a time.\n\t\t\t */\n\t\t\tv = (machine_word_t)0x0101010101010101 * src[0];\n\t\t\tstore_word_unaligned(v, dst);\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(v, dst);\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(v, dst);\n\t\t\tdst += WORDBYTES;\n\t\t\tstore_word_unaligned(v, dst);\n\t\t\tdst += WORDBYTES;\n\t\t\twhile (dst < out_next) {\n\t\t\t\tstore_word_unaligned(v, dst);\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(v, dst);\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(v, dst);\n\t\t\t\tdst += WORDBYTES;\n\t\t\t\tstore_word_unaligned(v, dst);\n\t\t\t\tdst += WORDBYTES;\n\t\t\t}\n\t\t} else if (UNALIGNED_ACCESS_IS_FAST) {\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += offset;\n\t\t\tdst += offset;\n\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\tsrc += offset;\n\t\t\tdst += offset;\n\t\t\tdo {\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += offset;\n\t\t\t\tdst += offset;\n\t\t\t\tstore_word_unaligned(load_word_unaligned(src), dst);\n\t\t\t\tsrc += offset;\n\t\t\t\tdst += offset;\n\t\t\t} while (dst < out_next);\n\t\t} else {\n\t\t\t*dst++ = *src++;\n\t\t\t*dst++ = *src++;\n\t\t\tdo {\n\t\t\t\t*dst++ = *src++;\n\t\t\t} while (dst < out_next);\n\t\t}\n\t} while (in_next < in_fastloop_end && out_next < out_fastloop_end);\n\n\t/*\n\t * This is the generic loop for decoding literals and matches.  This\n\t * handles cases where in_next and out_next are close to the end of\n\t * their respective buffers.  Usually this loop isn't performance-\n\t * critical, as most time is spent in the fastloop above instead.  We\n\t * therefore omit some optimizations here in favor of smaller code.\n\t */\ngeneric_loop:\n\tfor (;;) {\n\t\tu32 length, offset;\n\t\tconst u8 *src;\n\t\tu8 *dst;\n\n\t\tREFILL_BITS();\n\t\tentry = d->u.litlen_decode_table[bitbuf & litlen_tablemask];\n\t\tsaved_bitbuf = bitbuf;\n\t\tbitbuf >>= (u8)entry;\n\t\tbitsleft -= entry;\n\t\tif (unlikely(entry & HUFFDEC_SUBTABLE_POINTER)) {\n\t\t\tentry = d->u.litlen_decode_table[(entry >> 16) +\n\t\t\t\t\tEXTRACT_VARBITS(bitbuf, (entry >> 8) & 0x3F)];\n\t\t\tsaved_bitbuf = bitbuf;\n\t\t\tbitbuf >>= (u8)entry;\n\t\t\tbitsleft -= entry;\n\t\t}\n\t\tlength = entry >> 16;\n\t\tif (entry & HUFFDEC_LITERAL) {\n\t\t\tif (unlikely(out_next == out_end))\n\t\t\t\treturn LIBDEFLATE_INSUFFICIENT_SPACE;\n\t\t\t*out_next++ = length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (unlikely(entry & HUFFDEC_END_OF_BLOCK))\n\t\t\tgoto block_done;\n\t\tlength += EXTRACT_VARBITS8(saved_bitbuf, entry) >> (u8)(entry >> 8);\n\t\tif (unlikely(length > out_end - out_next))\n\t\t\treturn LIBDEFLATE_INSUFFICIENT_SPACE;\n\n\t\tif (!CAN_CONSUME(LENGTH_MAXBITS + OFFSET_MAXBITS))\n\t\t\tREFILL_BITS();\n\t\tentry = d->offset_decode_table[bitbuf & BITMASK(OFFSET_TABLEBITS)];\n\t\tif (unlikely(entry & HUFFDEC_EXCEPTIONAL)) {\n\t\t\tbitbuf >>= OFFSET_TABLEBITS;\n\t\t\tbitsleft -= OFFSET_TABLEBITS;\n\t\t\tentry = d->offset_decode_table[(entry >> 16) +\n\t\t\t\t\tEXTRACT_VARBITS(bitbuf, (entry >> 8) & 0x3F)];\n\t\t\tif (!CAN_CONSUME(OFFSET_MAXBITS))\n\t\t\t\tREFILL_BITS();\n\t\t}\n\t\toffset = entry >> 16;\n\t\toffset += EXTRACT_VARBITS8(bitbuf, entry) >> (u8)(entry >> 8);\n\t\tbitbuf >>= (u8)entry;\n\t\tbitsleft -= entry;\n\n\t\tSAFETY_CHECK(offset <= out_next - (const u8 *)out);\n\t\tsrc = out_next - offset;\n\t\tdst = out_next;\n\t\tout_next += length;\n\n\t\tSTATIC_ASSERT(DEFLATE_MIN_MATCH_LEN == 3);\n\t\t*dst++ = *src++;\n\t\t*dst++ = *src++;\n\t\tdo {\n\t\t\t*dst++ = *src++;\n\t\t} while (dst < out_next);\n\t}\n\nblock_done:\n\t/* Finished decoding a block */\n\n\tif (!is_final_block)\n\t\tgoto next_block;\n\n\t/* That was the last block. */\n\n\tbitsleft = (u8)bitsleft;\n\n\t/*\n\t * If any of the implicit appended zero bytes were consumed (not just\n\t * refilled) before hitting end of stream, then the data is bad.\n\t */\n\tSAFETY_CHECK(overread_count <= (bitsleft >> 3));\n\n\t/* Optionally return the actual number of bytes consumed. */\n\tif (actual_in_nbytes_ret) {\n\t\t/* Don't count bytes that were refilled but not consumed. */\n\t\tin_next -= (bitsleft >> 3) - overread_count;\n\n\t\t*actual_in_nbytes_ret = in_next - (u8 *)in;\n\t}\n\n\t/* Optionally return the actual number of bytes written. */\n\tif (actual_out_nbytes_ret) {\n\t\t*actual_out_nbytes_ret = out_next - (u8 *)out;\n\t} else {\n\t\tif (out_next != out_end)\n\t\t\treturn LIBDEFLATE_SHORT_OUTPUT;\n\t}\n\treturn LIBDEFLATE_SUCCESS;\n}\n\n#undef FUNCNAME\n#undef ATTRIBUTES\n#undef EXTRACT_VARBITS\n#undef EXTRACT_VARBITS8\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/deflate_compress.c",
    "content": "/*\n * deflate_compress.c - a compressor for DEFLATE\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"deflate_compress.h\"\n#include \"deflate_constants.h\"\n\n/******************************************************************************/\n\n/*\n * The following parameters can be changed at build time to customize the\n * compression algorithms slightly:\n *\n * (Note, not all customizable parameters are here.  Some others can be found in\n * libdeflate_alloc_compressor() and in *_matchfinder.h.)\n */\n\n/*\n * If this parameter is defined to 1, then the near-optimal parsing algorithm\n * will be included, and compression levels 10-12 will use it.  This algorithm\n * usually produces a compression ratio significantly better than the other\n * algorithms.  However, it is slow.  If this parameter is defined to 0, then\n * levels 10-12 will be the same as level 9 and will use the lazy2 algorithm.\n */\n#define SUPPORT_NEAR_OPTIMAL_PARSING\t1\n\n/*\n * This is the minimum block length that the compressor will use, in\n * uncompressed bytes.  This should be a value below which using shorter blocks\n * is unlikely to be worthwhile, due to the per-block overhead.  This value does\n * not apply to the final block, which may be shorter than this (if the input is\n * shorter, it will have to be), or to the final uncompressed block in a series\n * of uncompressed blocks that cover more than UINT16_MAX bytes.\n *\n * This value is also approximately the amount by which what would otherwise be\n * the second-to-last block is allowed to grow past the soft maximum length in\n * order to avoid having to use a very short final block.\n *\n * Defining a fixed minimum block length is needed in order to guarantee a\n * reasonable upper bound on the compressed size.  It's also needed because our\n * block splitting algorithm doesn't work well on very short blocks.\n */\n#define MIN_BLOCK_LENGTH\t5000\n\n/*\n * For the greedy, lazy, lazy2, and near-optimal compressors: This is the soft\n * maximum block length, in uncompressed bytes.  The compressor will try to end\n * blocks at this length, but it may go slightly past it if there is a match\n * that straddles this limit or if the input data ends soon after this limit.\n * This parameter doesn't apply to uncompressed blocks, which the DEFLATE format\n * limits to 65535 bytes.\n *\n * This should be a value above which it is very likely that splitting the block\n * would produce a better compression ratio.  For the near-optimal compressor,\n * increasing/decreasing this parameter will increase/decrease per-compressor\n * memory usage linearly.\n */\n#define SOFT_MAX_BLOCK_LENGTH\t300000\n\n/*\n * For the greedy, lazy, and lazy2 compressors: this is the length of the\n * sequence store, which is an array where the compressor temporarily stores\n * matches that it's going to use in the current block.  This value is the\n * maximum number of matches that can be used in a block.  If the sequence store\n * fills up, then the compressor will be forced to end the block early.  This\n * value should be large enough so that this rarely happens, due to the block\n * being ended normally before then.  Increasing/decreasing this value will\n * increase/decrease per-compressor memory usage linearly.\n */\n#define SEQ_STORE_LENGTH\t50000\n\n/*\n * For deflate_compress_fastest(): This is the soft maximum block length.\n * deflate_compress_fastest() doesn't use the regular block splitting algorithm;\n * it only ends blocks when they reach FAST_SOFT_MAX_BLOCK_LENGTH bytes or\n * FAST_SEQ_STORE_LENGTH matches.  Therefore, this value should be lower than\n * the regular SOFT_MAX_BLOCK_LENGTH.\n */\n#define FAST_SOFT_MAX_BLOCK_LENGTH\t65535\n\n/*\n * For deflate_compress_fastest(): this is the length of the sequence store.\n * This is like SEQ_STORE_LENGTH, but this should be a lower value.\n */\n#define FAST_SEQ_STORE_LENGTH\t8192\n\n/*\n * These are the maximum codeword lengths, in bits, the compressor will use for\n * each Huffman code.  The DEFLATE format defines limits for these.  However,\n * further limiting litlen codewords to 14 bits is beneficial, since it has\n * negligible effect on compression ratio but allows some optimizations when\n * outputting bits.  (It allows 4 literals to be written at once rather than 3.)\n */\n#define MAX_LITLEN_CODEWORD_LEN\t\t14\n#define MAX_OFFSET_CODEWORD_LEN\t\tDEFLATE_MAX_OFFSET_CODEWORD_LEN\n#define MAX_PRE_CODEWORD_LEN\t\tDEFLATE_MAX_PRE_CODEWORD_LEN\n\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\n/* Parameters specific to the near-optimal parsing algorithm */\n\n/*\n * BIT_COST is a scaling factor that allows the near-optimal compressor to\n * consider fractional bit costs when deciding which literal/match sequence to\n * use.  This is useful when the true symbol costs are unknown.  For example, if\n * the compressor thinks that a symbol has 6.5 bits of entropy, it can set its\n * cost to 6.5 bits rather than have to use 6 or 7 bits.  Although in the end\n * each symbol will use a whole number of bits due to the Huffman coding,\n * considering fractional bits can be helpful due to the limited information.\n *\n * BIT_COST should be a power of 2.  A value of 8 or 16 works well.  A higher\n * value isn't very useful since the calculations are approximate anyway.\n *\n * BIT_COST doesn't apply to deflate_flush_block() and\n * deflate_compute_true_cost(), which consider whole bits.\n */\n#define BIT_COST\t16\n\n/*\n * The NOSTAT_BITS value for a given alphabet is the number of bits assumed to\n * be needed to output a symbol that was unused in the previous optimization\n * pass.  Assigning a default cost allows the symbol to be used in the next\n * optimization pass.  However, the cost should be relatively high because the\n * symbol probably won't be used very many times (if at all).\n */\n#define LITERAL_NOSTAT_BITS\t13\n#define LENGTH_NOSTAT_BITS\t13\n#define OFFSET_NOSTAT_BITS\t10\n\n/*\n * This is (slightly less than) the maximum number of matches that the\n * near-optimal compressor will cache per block.  This behaves similarly to\n * SEQ_STORE_LENGTH for the other compressors.\n */\n#define MATCH_CACHE_LENGTH\t(SOFT_MAX_BLOCK_LENGTH * 5)\n\n#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\n/******************************************************************************/\n\n/* Include the needed matchfinders. */\n#define MATCHFINDER_WINDOW_ORDER\tDEFLATE_WINDOW_ORDER\n#include \"hc_matchfinder.h\"\n#include \"ht_matchfinder.h\"\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n#  include \"bt_matchfinder.h\"\n/*\n * This is the maximum number of matches the binary trees matchfinder can find\n * at a single position.  Since the matchfinder never finds more than one match\n * for the same length, presuming one of each possible length is sufficient for\n * an upper bound.  (This says nothing about whether it is worthwhile to\n * consider so many matches; this is just defining the worst case.)\n */\n#define MAX_MATCHES_PER_POS\t\\\n\t(DEFLATE_MAX_MATCH_LEN - DEFLATE_MIN_MATCH_LEN + 1)\n#endif\n\n/*\n * The largest block length we will ever use is when the final block is of\n * length SOFT_MAX_BLOCK_LENGTH + MIN_BLOCK_LENGTH - 1, or when any block is of\n * length SOFT_MAX_BLOCK_LENGTH + 1 + DEFLATE_MAX_MATCH_LEN.  The latter case\n * occurs when the lazy2 compressor chooses two literals and a maximum-length\n * match, starting at SOFT_MAX_BLOCK_LENGTH - 1.\n */\n#define MAX_BLOCK_LENGTH\t\\\n\tMAX(SOFT_MAX_BLOCK_LENGTH + MIN_BLOCK_LENGTH - 1,\t\\\n\t    SOFT_MAX_BLOCK_LENGTH + 1 + DEFLATE_MAX_MATCH_LEN)\n\nstatic forceinline void\ncheck_buildtime_parameters(void)\n{\n\t/*\n\t * Verify that MIN_BLOCK_LENGTH is being honored, as\n\t * libdeflate_deflate_compress_bound() depends on it.\n\t */\n\tSTATIC_ASSERT(SOFT_MAX_BLOCK_LENGTH >= MIN_BLOCK_LENGTH);\n\tSTATIC_ASSERT(FAST_SOFT_MAX_BLOCK_LENGTH >= MIN_BLOCK_LENGTH);\n\tSTATIC_ASSERT(SEQ_STORE_LENGTH * DEFLATE_MIN_MATCH_LEN >=\n\t\t      MIN_BLOCK_LENGTH);\n\tSTATIC_ASSERT(FAST_SEQ_STORE_LENGTH * HT_MATCHFINDER_MIN_MATCH_LEN >=\n\t\t      MIN_BLOCK_LENGTH);\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\tSTATIC_ASSERT(MIN_BLOCK_LENGTH * MAX_MATCHES_PER_POS <=\n\t\t      MATCH_CACHE_LENGTH);\n#endif\n\n\t/* The definition of MAX_BLOCK_LENGTH assumes this. */\n\tSTATIC_ASSERT(FAST_SOFT_MAX_BLOCK_LENGTH <= SOFT_MAX_BLOCK_LENGTH);\n\n\t/* Verify that the sequence stores aren't uselessly large. */\n\tSTATIC_ASSERT(SEQ_STORE_LENGTH * DEFLATE_MIN_MATCH_LEN <=\n\t\t      SOFT_MAX_BLOCK_LENGTH + MIN_BLOCK_LENGTH);\n\tSTATIC_ASSERT(FAST_SEQ_STORE_LENGTH * HT_MATCHFINDER_MIN_MATCH_LEN <=\n\t\t      FAST_SOFT_MAX_BLOCK_LENGTH + MIN_BLOCK_LENGTH);\n\n\t/* Verify that the maximum codeword lengths are valid. */\n\tSTATIC_ASSERT(\n\t\tMAX_LITLEN_CODEWORD_LEN <= DEFLATE_MAX_LITLEN_CODEWORD_LEN);\n\tSTATIC_ASSERT(\n\t\tMAX_OFFSET_CODEWORD_LEN <= DEFLATE_MAX_OFFSET_CODEWORD_LEN);\n\tSTATIC_ASSERT(\n\t\tMAX_PRE_CODEWORD_LEN <= DEFLATE_MAX_PRE_CODEWORD_LEN);\n\tSTATIC_ASSERT(\n\t\t(1U << MAX_LITLEN_CODEWORD_LEN) >= DEFLATE_NUM_LITLEN_SYMS);\n\tSTATIC_ASSERT(\n\t\t(1U << MAX_OFFSET_CODEWORD_LEN) >= DEFLATE_NUM_OFFSET_SYMS);\n\tSTATIC_ASSERT(\n\t\t(1U << MAX_PRE_CODEWORD_LEN) >= DEFLATE_NUM_PRECODE_SYMS);\n}\n\n/******************************************************************************/\n\n/* Table: length slot => length slot base value */\nstatic const u32 deflate_length_slot_base[] = {\n\t3,    4,    5,    6,    7,    8,    9,    10,\n\t11,   13,   15,   17,   19,   23,   27,   31,\n\t35,   43,   51,   59,   67,   83,   99,   115,\n\t131,  163,  195,  227,  258,\n};\n\n/* Table: length slot => number of extra length bits */\nstatic const u8 deflate_extra_length_bits[] = {\n\t0,    0,    0,    0,    0,    0,    0,    0,\n\t1,    1,    1,    1,    2,    2,    2,    2,\n\t3,    3,    3,    3,    4,    4,    4,    4,\n\t5,    5,    5,    5,    0,\n};\n\n/* Table: offset slot => offset slot base value */\nstatic const u32 deflate_offset_slot_base[] = {\n\t1,     2,     3,     4,     5,     7,     9,     13,\n\t17,    25,    33,    49,    65,    97,    129,   193,\n\t257,   385,   513,   769,   1025,  1537,  2049,  3073,\n\t4097,  6145,  8193,  12289, 16385, 24577,\n};\n\n/* Table: offset slot => number of extra offset bits */\nstatic const u8 deflate_extra_offset_bits[] = {\n\t0,     0,     0,     0,     1,     1,     2,     2,\n\t3,     3,     4,     4,     5,     5,     6,     6,\n\t7,     7,     8,     8,     9,     9,     10,    10,\n\t11,    11,    12,    12,    13,    13,\n};\n\n/* Table: length => length slot */\nstatic const u8 deflate_length_slot[DEFLATE_MAX_MATCH_LEN + 1] = {\n\t0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,\n\t12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,\n\t16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,\n\t18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 28,\n};\n\n/*\n * Table: 'offset - 1 => offset_slot' for offset <= 256.\n * This was generated by scripts/gen_offset_slot_map.py.\n */\nstatic const u8 deflate_offset_slot[256] = {\n\t0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,\n\t8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n};\n\n/* The order in which precode codeword lengths are stored */\nstatic const u8 deflate_precode_lens_permutation[DEFLATE_NUM_PRECODE_SYMS] = {\n\t16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15\n};\n\n/* Table: precode symbol => number of extra bits */\nstatic const u8 deflate_extra_precode_bits[DEFLATE_NUM_PRECODE_SYMS] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7\n};\n\n/* Codewords for the DEFLATE Huffman codes */\nstruct deflate_codewords {\n\tu32 litlen[DEFLATE_NUM_LITLEN_SYMS];\n\tu32 offset[DEFLATE_NUM_OFFSET_SYMS];\n};\n\n/*\n * Codeword lengths (in bits) for the DEFLATE Huffman codes.\n * A zero length means the corresponding symbol had zero frequency.\n */\nstruct deflate_lens {\n\tu8 litlen[DEFLATE_NUM_LITLEN_SYMS];\n\tu8 offset[DEFLATE_NUM_OFFSET_SYMS];\n};\n\n/* Codewords and lengths for the DEFLATE Huffman codes */\nstruct deflate_codes {\n\tstruct deflate_codewords codewords;\n\tstruct deflate_lens lens;\n};\n\n/* Symbol frequency counters for the DEFLATE Huffman codes */\nstruct deflate_freqs {\n\tu32 litlen[DEFLATE_NUM_LITLEN_SYMS];\n\tu32 offset[DEFLATE_NUM_OFFSET_SYMS];\n};\n\n/*\n * Represents a run of literals followed by a match or end-of-block.  This\n * struct is needed to temporarily store items chosen by the parser, since items\n * cannot be written until all items for the block have been chosen and the\n * block's Huffman codes have been computed.\n */\nstruct deflate_sequence {\n\n\t/*\n\t * Bits 0..22: the number of literals in this run.  This may be 0 and\n\t * can be at most MAX_BLOCK_LENGTH.  The literals are not stored\n\t * explicitly in this structure; instead, they are read directly from\n\t * the uncompressed data.\n\t *\n\t * Bits 23..31: the length of the match which follows the literals, or 0\n\t * if this literal run was the last in the block, so there is no match\n\t * which follows it.\n\t */\n#define SEQ_LENGTH_SHIFT 23\n#define SEQ_LITRUNLEN_MASK (((u32)1 << SEQ_LENGTH_SHIFT) - 1)\n\tu32 litrunlen_and_length;\n\n\t/*\n\t * If 'length' doesn't indicate end-of-block, then this is the offset of\n\t * the match which follows the literals.\n\t */\n\tu16 offset;\n\n\t/*\n\t * If 'length' doesn't indicate end-of-block, then this is the offset\n\t * slot of the match which follows the literals.\n\t */\n\tu16 offset_slot;\n};\n\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\n/* Costs for the near-optimal parsing algorithm */\nstruct deflate_costs {\n\n\t/* The cost to output each possible literal */\n\tu32 literal[DEFLATE_NUM_LITERALS];\n\n\t/* The cost to output each possible match length */\n\tu32 length[DEFLATE_MAX_MATCH_LEN + 1];\n\n\t/* The cost to output a match offset of each possible offset slot */\n\tu32 offset_slot[DEFLATE_NUM_OFFSET_SYMS];\n};\n\n/*\n * This structure represents a byte position in the input data and a node in the\n * graph of possible match/literal choices for the current block.\n *\n * Logically, each incoming edge to this node is labeled with a literal or a\n * match that can be taken to reach this position from an earlier position; and\n * each outgoing edge from this node is labeled with a literal or a match that\n * can be taken to advance from this position to a later position.\n *\n * But these \"edges\" are actually stored elsewhere (in 'match_cache').  Here we\n * associate with each node just two pieces of information:\n *\n *\t'cost_to_end' is the minimum cost to reach the end of the block from\n *\tthis position.\n *\n *\t'item' represents the literal or match that must be chosen from here to\n *\treach the end of the block with the minimum cost.  Equivalently, this\n *\tcan be interpreted as the label of the outgoing edge on the minimum-cost\n *\tpath to the \"end of block\" node from this node.\n */\nstruct deflate_optimum_node {\n\n\tu32 cost_to_end;\n\n\t/*\n\t * Notes on the match/literal representation used here:\n\t *\n\t *\tThe low bits of 'item' are the length: 1 if this is a literal,\n\t *\tor the match length if this is a match.\n\t *\n\t *\tThe high bits of 'item' are the actual literal byte if this is a\n\t *\tliteral, or the match offset if this is a match.\n\t */\n#define OPTIMUM_OFFSET_SHIFT 9\n#define OPTIMUM_LEN_MASK (((u32)1 << OPTIMUM_OFFSET_SHIFT) - 1)\n\tu32 item;\n\n};\n\n#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\n/* Block split statistics.  See \"Block splitting algorithm\" below. */\n#define NUM_LITERAL_OBSERVATION_TYPES 8\n#define NUM_MATCH_OBSERVATION_TYPES 2\n#define NUM_OBSERVATION_TYPES (NUM_LITERAL_OBSERVATION_TYPES + \\\n\t\t\t       NUM_MATCH_OBSERVATION_TYPES)\n#define NUM_OBSERVATIONS_PER_BLOCK_CHECK 512\nstruct block_split_stats {\n\tu32 new_observations[NUM_OBSERVATION_TYPES];\n\tu32 observations[NUM_OBSERVATION_TYPES];\n\tu32 num_new_observations;\n\tu32 num_observations;\n};\n\nstruct deflate_output_bitstream;\n\n/* The main DEFLATE compressor structure */\nstruct libdeflate_compressor {\n\n\t/* Pointer to the compress() implementation chosen at allocation time */\n\tvoid (*impl)(struct libdeflate_compressor *restrict c, const u8 *in,\n\t\t     size_t in_nbytes, struct deflate_output_bitstream *os);\n\n\t/* The free() function for this struct, chosen at allocation time */\n\tfree_func_t free_func;\n\n\t/* The compression level with which this compressor was created */\n\tunsigned compression_level;\n\n\t/* Anything of this size or less we won't bother trying to compress. */\n\tsize_t max_passthrough_size;\n\n\t/*\n\t * The maximum search depth: consider at most this many potential\n\t * matches at each position\n\t */\n\tu32 max_search_depth;\n\n\t/*\n\t * The \"nice\" match length: if a match of this length is found, choose\n\t * it immediately without further consideration\n\t */\n\tu32 nice_match_length;\n\n\t/* Frequency counters for the current block */\n\tstruct deflate_freqs freqs;\n\n\t/* Block split statistics for the current block */\n\tstruct block_split_stats split_stats;\n\n\t/* Dynamic Huffman codes for the current block */\n\tstruct deflate_codes codes;\n\n\t/* The static Huffman codes defined by the DEFLATE format */\n\tstruct deflate_codes static_codes;\n\n\t/* Temporary space for block flushing */\n\tunion {\n\t\t/* Information about the precode */\n\t\tstruct {\n\t\t\tu32 freqs[DEFLATE_NUM_PRECODE_SYMS];\n\t\t\tu32 codewords[DEFLATE_NUM_PRECODE_SYMS];\n\t\t\tu8 lens[DEFLATE_NUM_PRECODE_SYMS];\n\t\t\tunsigned items[DEFLATE_NUM_LITLEN_SYMS +\n\t\t\t\t       DEFLATE_NUM_OFFSET_SYMS];\n\t\t\tunsigned num_litlen_syms;\n\t\t\tunsigned num_offset_syms;\n\t\t\tunsigned num_explicit_lens;\n\t\t\tunsigned num_items;\n\t\t} precode;\n\t\t/*\n\t\t * The \"full\" length codewords.  Used only after the information\n\t\t * in 'precode' is no longer needed.\n\t\t */\n\t\tstruct {\n\t\t\tu32 codewords[DEFLATE_MAX_MATCH_LEN + 1];\n\t\t\tu8 lens[DEFLATE_MAX_MATCH_LEN + 1];\n\t\t} length;\n\t} o;\n\n\tunion {\n\t\t/* Data for greedy or lazy parsing */\n\t\tstruct {\n\t\t\t/* Hash chains matchfinder */\n\t\t\tstruct hc_matchfinder hc_mf;\n\n\t\t\t/* Matches and literals chosen for the current block */\n\t\t\tstruct deflate_sequence sequences[SEQ_STORE_LENGTH + 1];\n\n\t\t} g; /* (g)reedy */\n\n\t\t/* Data for fastest parsing */\n\t\tstruct {\n\t\t\t/* Hash table matchfinder */\n\t\t\tstruct ht_matchfinder ht_mf;\n\n\t\t\t/* Matches and literals chosen for the current block */\n\t\t\tstruct deflate_sequence sequences[\n\t\t\t\t\t\tFAST_SEQ_STORE_LENGTH + 1];\n\n\t\t} f; /* (f)astest */\n\n\t#if SUPPORT_NEAR_OPTIMAL_PARSING\n\t\t/* Data for near-optimal parsing */\n\t\tstruct {\n\n\t\t\t/* Binary tree matchfinder */\n\t\t\tstruct bt_matchfinder bt_mf;\n\n\t\t\t/*\n\t\t\t * Cached matches for the current block.  This array\n\t\t\t * contains the matches that were found at each position\n\t\t\t * in the block.  Specifically, for each position, there\n\t\t\t * is a list of matches found at that position, if any,\n\t\t\t * sorted by strictly increasing length.  In addition,\n\t\t\t * following the matches for each position, there is a\n\t\t\t * special 'struct lz_match' whose 'length' member\n\t\t\t * contains the number of matches found at that\n\t\t\t * position, and whose 'offset' member contains the\n\t\t\t * literal at that position.\n\t\t\t *\n\t\t\t * Note: in rare cases, there will be a very high number\n\t\t\t * of matches in the block and this array will overflow.\n\t\t\t * If this happens, we force the end of the current\n\t\t\t * block.  MATCH_CACHE_LENGTH is the length at which we\n\t\t\t * actually check for overflow.  The extra slots beyond\n\t\t\t * this are enough to absorb the worst case overflow,\n\t\t\t * which occurs if starting at\n\t\t\t * &match_cache[MATCH_CACHE_LENGTH - 1], we write\n\t\t\t * MAX_MATCHES_PER_POS matches and a match count header,\n\t\t\t * then skip searching for matches at\n\t\t\t * 'DEFLATE_MAX_MATCH_LEN - 1' positions and write the\n\t\t\t * match count header for each.\n\t\t\t */\n\t\t\tstruct lz_match match_cache[MATCH_CACHE_LENGTH +\n\t\t\t\t\t\t    MAX_MATCHES_PER_POS +\n\t\t\t\t\t\t    DEFLATE_MAX_MATCH_LEN - 1];\n\n\t\t\t/*\n\t\t\t * Array of nodes, one per position, for running the\n\t\t\t * minimum-cost path algorithm.\n\t\t\t *\n\t\t\t * This array must be large enough to accommodate the\n\t\t\t * worst-case number of nodes, which is MAX_BLOCK_LENGTH\n\t\t\t * plus 1 for the end-of-block node.\n\t\t\t */\n\t\t\tstruct deflate_optimum_node optimum_nodes[\n\t\t\t\tMAX_BLOCK_LENGTH + 1];\n\n\t\t\t/* The current cost model being used */\n\t\t\tstruct deflate_costs costs;\n\n\t\t\t/* Saved cost model */\n\t\t\tstruct deflate_costs costs_saved;\n\n\t\t\t/*\n\t\t\t * A table that maps match offset to offset slot.  This\n\t\t\t * differs from deflate_offset_slot[] in that this is a\n\t\t\t * full map, not a condensed one.  The full map is more\n\t\t\t * appropriate for the near-optimal parser, since the\n\t\t\t * near-optimal parser does more offset => offset_slot\n\t\t\t * translations, it doesn't intersperse them with\n\t\t\t * matchfinding (so cache evictions are less of a\n\t\t\t * concern), and it uses more memory anyway.\n\t\t\t */\n\t\t\tu8 offset_slot_full[DEFLATE_MAX_MATCH_OFFSET + 1];\n\n\t\t\t/* Literal/match statistics saved from previous block */\n\t\t\tu32 prev_observations[NUM_OBSERVATION_TYPES];\n\t\t\tu32 prev_num_observations;\n\n\t\t\t/*\n\t\t\t * Approximate match length frequencies based on a\n\t\t\t * greedy parse, gathered during matchfinding.  This is\n\t\t\t * used for setting the initial symbol costs.\n\t\t\t */\n\t\t\tu32 new_match_len_freqs[DEFLATE_MAX_MATCH_LEN + 1];\n\t\t\tu32 match_len_freqs[DEFLATE_MAX_MATCH_LEN + 1];\n\n\t\t\t/*\n\t\t\t * The maximum number of optimization passes\n\t\t\t * (min-cost path searches) per block.\n\t\t\t * Larger values = more compression.\n\t\t\t */\n\t\t\tunsigned max_optim_passes;\n\n\t\t\t/*\n\t\t\t * If an optimization pass improves the cost by fewer\n\t\t\t * than this number of bits, then optimization will stop\n\t\t\t * early, before max_optim_passes has been reached.\n\t\t\t * Smaller values = more compression.\n\t\t\t */\n\t\t\tu32 min_improvement_to_continue;\n\n\t\t\t/*\n\t\t\t * The minimum number of bits that would need to be\n\t\t\t * saved for it to be considered worth the time to\n\t\t\t * regenerate and use the min-cost path from a previous\n\t\t\t * optimization pass, in the case where the final\n\t\t\t * optimization pass actually increased the cost.\n\t\t\t * Smaller values = more compression.\n\t\t\t */\n\t\t\tu32 min_bits_to_use_nonfinal_path;\n\n\t\t\t/*\n\t\t\t * The maximum block length, in uncompressed bytes, at\n\t\t\t * which to find and consider the optimal match/literal\n\t\t\t * list for the static Huffman codes.  This strategy\n\t\t\t * improves the compression ratio produced by static\n\t\t\t * Huffman blocks and can discover more cases in which\n\t\t\t * static blocks are worthwhile.  This helps mostly with\n\t\t\t * small blocks, hence why this parameter is a max_len.\n\t\t\t *\n\t\t\t * Above this block length, static Huffman blocks are\n\t\t\t * only used opportunistically.  I.e. a static Huffman\n\t\t\t * block is only used if a static block using the same\n\t\t\t * match/literal list as the optimized dynamic block\n\t\t\t * happens to be cheaper than the dynamic block itself.\n\t\t\t */\n\t\t\tu32 max_len_to_optimize_static_block;\n\n\t\t} n; /* (n)ear-optimal */\n\t#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\n\t} p; /* (p)arser */\n};\n\n/*\n * The type for the bitbuffer variable, which temporarily holds bits that are\n * being packed into bytes and written to the output buffer.  For best\n * performance, this should have size equal to a machine word.\n */\ntypedef machine_word_t bitbuf_t;\n\n/*\n * The capacity of the bitbuffer, in bits.  This is 1 less than the real size,\n * in order to avoid undefined behavior when doing bitbuf >>= bitcount & ~7.\n */\n#define BITBUF_NBITS\t(8 * sizeof(bitbuf_t) - 1)\n\n/*\n * Can the specified number of bits always be added to 'bitbuf' after any\n * pending bytes have been flushed?  There can be up to 7 bits remaining after a\n * flush, so the count must not exceed BITBUF_NBITS after adding 'n' more bits.\n */\n#define CAN_BUFFER(n)\t(7 + (n) <= BITBUF_NBITS)\n\n/*\n * Structure to keep track of the current state of sending bits to the\n * compressed output buffer\n */\nstruct deflate_output_bitstream {\n\n\t/* Bits that haven't yet been written to the output buffer */\n\tbitbuf_t bitbuf;\n\n\t/*\n\t * Number of bits currently held in @bitbuf.  This can be between 0 and\n\t * BITBUF_NBITS in general, or between 0 and 7 after a flush.\n\t */\n\tunsigned bitcount;\n\n\t/*\n\t * Pointer to the position in the output buffer at which the next byte\n\t * should be written\n\t */\n\tu8 *next;\n\n\t/* Pointer to the end of the output buffer */\n\tu8 *end;\n\n\t/* true if the output buffer ran out of space */\n\tbool overflow;\n};\n\n/*\n * Add some bits to the bitbuffer variable of the output bitstream.  The caller\n * must ensure that 'bitcount + n <= BITBUF_NBITS', by calling FLUSH_BITS()\n * frequently enough.\n */\n#define ADD_BITS(bits, n)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n\tbitbuf |= (bitbuf_t)(bits) << bitcount;\t\\\n\tbitcount += (n);\t\t\t\\\n\tASSERT(bitcount <= BITBUF_NBITS);\t\\\n} while (0)\n\n/*\n * Flush bits from the bitbuffer variable to the output buffer.  After this, the\n * bitbuffer will contain at most 7 bits (a partial byte).\n *\n * Since deflate_flush_block() verified ahead of time that there is enough space\n * remaining before actually writing the block, it's guaranteed that out_next\n * won't exceed os->end.  However, there might not be enough space remaining to\n * flush a whole word, even though that's fastest.  Therefore, flush a whole\n * word if there is space for it, otherwise flush a byte at a time.\n */\n#define FLUSH_BITS()\t\t\t\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tif (UNALIGNED_ACCESS_IS_FAST && likely(out_next < out_fast_end)) { \\\n\t\t/* Flush a whole word (branchlessly). */\t\t\\\n\t\tput_unaligned_leword(bitbuf, out_next);\t\t\t\\\n\t\tbitbuf >>= bitcount & ~7;\t\t\t\t\\\n\t\tout_next += bitcount >> 3;\t\t\t\t\\\n\t\tbitcount &= 7;\t\t\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\t/* Flush a byte at a time. */\t\t\t\t\\\n\t\twhile (bitcount >= 8) {\t\t\t\t\t\\\n\t\t\tASSERT(out_next < os->end);\t\t\t\\\n\t\t\t*out_next++ = bitbuf;\t\t\t\t\\\n\t\t\tbitcount -= 8;\t\t\t\t\t\\\n\t\t\tbitbuf >>= 8;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * Given the binary tree node A[subtree_idx] whose children already satisfy the\n * maxheap property, swap the node with its greater child until it is greater\n * than or equal to both of its children, so that the maxheap property is\n * satisfied in the subtree rooted at A[subtree_idx].  'A' uses 1-based indices.\n */\nstatic void\nheapify_subtree(u32 A[], unsigned length, unsigned subtree_idx)\n{\n\tunsigned parent_idx;\n\tunsigned child_idx;\n\tu32 v;\n\n\tv = A[subtree_idx];\n\tparent_idx = subtree_idx;\n\twhile ((child_idx = parent_idx * 2) <= length) {\n\t\tif (child_idx < length && A[child_idx + 1] > A[child_idx])\n\t\t\tchild_idx++;\n\t\tif (v >= A[child_idx])\n\t\t\tbreak;\n\t\tA[parent_idx] = A[child_idx];\n\t\tparent_idx = child_idx;\n\t}\n\tA[parent_idx] = v;\n}\n\n/*\n * Rearrange the array 'A' so that it satisfies the maxheap property.\n * 'A' uses 1-based indices, so the children of A[i] are A[i*2] and A[i*2 + 1].\n */\nstatic void\nheapify_array(u32 A[], unsigned length)\n{\n\tunsigned subtree_idx;\n\n\tfor (subtree_idx = length / 2; subtree_idx >= 1; subtree_idx--)\n\t\theapify_subtree(A, length, subtree_idx);\n}\n\n/*\n * Sort the array 'A', which contains 'length' unsigned 32-bit integers.\n *\n * Note: name this function heap_sort() instead of heapsort() to avoid colliding\n * with heapsort() from stdlib.h on BSD-derived systems.\n */\nstatic void\nheap_sort(u32 A[], unsigned length)\n{\n\tA--; /* Use 1-based indices  */\n\n\theapify_array(A, length);\n\n\twhile (length >= 2) {\n\t\tu32 tmp = A[length];\n\n\t\tA[length] = A[1];\n\t\tA[1] = tmp;\n\t\tlength--;\n\t\theapify_subtree(A, length, 1);\n\t}\n}\n\n#define NUM_SYMBOL_BITS 10\n#define NUM_FREQ_BITS\t(32 - NUM_SYMBOL_BITS)\n#define SYMBOL_MASK\t((1 << NUM_SYMBOL_BITS) - 1)\n#define FREQ_MASK\t(~SYMBOL_MASK)\n\n#define GET_NUM_COUNTERS(num_syms)\t(num_syms)\n\n/*\n * Sort the symbols primarily by frequency and secondarily by symbol value.\n * Discard symbols with zero frequency and fill in an array with the remaining\n * symbols, along with their frequencies.  The low NUM_SYMBOL_BITS bits of each\n * array entry will contain the symbol value, and the remaining bits will\n * contain the frequency.\n *\n * @num_syms\n *\tNumber of symbols in the alphabet, at most 1 << NUM_SYMBOL_BITS.\n *\n * @freqs[num_syms]\n *\tFrequency of each symbol, summing to at most (1 << NUM_FREQ_BITS) - 1.\n *\n * @lens[num_syms]\n *\tAn array that eventually will hold the length of each codeword.  This\n *\tfunction only fills in the codeword lengths for symbols that have zero\n *\tfrequency, which are not well defined per se but will be set to 0.\n *\n * @symout[num_syms]\n *\tThe output array, described above.\n *\n * Returns the number of entries in 'symout' that were filled.  This is the\n * number of symbols that have nonzero frequency.\n */\nstatic unsigned\nsort_symbols(unsigned num_syms, const u32 freqs[], u8 lens[], u32 symout[])\n{\n\tunsigned sym;\n\tunsigned i;\n\tunsigned num_used_syms;\n\tunsigned num_counters;\n\tunsigned counters[GET_NUM_COUNTERS(DEFLATE_MAX_NUM_SYMS)];\n\n\t/*\n\t * We use heapsort, but with an added optimization.  Since often most\n\t * symbol frequencies are low, we first do a count sort using a limited\n\t * number of counters.  High frequencies are counted in the last\n\t * counter, and only they will be sorted with heapsort.\n\t *\n\t * Note: with more symbols, it is generally beneficial to have more\n\t * counters.  About 1 counter per symbol seems fastest.\n\t */\n\n\tnum_counters = GET_NUM_COUNTERS(num_syms);\n\n\tmemset(counters, 0, num_counters * sizeof(counters[0]));\n\n\t/* Count the frequencies. */\n\tfor (sym = 0; sym < num_syms; sym++)\n\t\tcounters[MIN(freqs[sym], num_counters - 1)]++;\n\n\t/*\n\t * Make the counters cumulative, ignoring the zero-th, which counted\n\t * symbols with zero frequency.  As a side effect, this calculates the\n\t * number of symbols with nonzero frequency.\n\t */\n\tnum_used_syms = 0;\n\tfor (i = 1; i < num_counters; i++) {\n\t\tunsigned count = counters[i];\n\n\t\tcounters[i] = num_used_syms;\n\t\tnum_used_syms += count;\n\t}\n\n\t/*\n\t * Sort nonzero-frequency symbols using the counters.  At the same time,\n\t * set the codeword lengths of zero-frequency symbols to 0.\n\t */\n\tfor (sym = 0; sym < num_syms; sym++) {\n\t\tu32 freq = freqs[sym];\n\n\t\tif (freq != 0) {\n\t\t\tsymout[counters[MIN(freq, num_counters - 1)]++] =\n\t\t\t\tsym | (freq << NUM_SYMBOL_BITS);\n\t\t} else {\n\t\t\tlens[sym] = 0;\n\t\t}\n\t}\n\n\t/* Sort the symbols counted in the last counter. */\n\theap_sort(symout + counters[num_counters - 2],\n\t\t  counters[num_counters - 1] - counters[num_counters - 2]);\n\n\treturn num_used_syms;\n}\n\n/*\n * Build a Huffman tree.\n *\n * This is an optimized implementation that\n *\t(a) takes advantage of the frequencies being already sorted;\n *\t(b) only generates non-leaf nodes, since the non-leaf nodes of a Huffman\n *\t    tree are sufficient to generate a canonical code;\n *\t(c) Only stores parent pointers, not child pointers;\n *\t(d) Produces the nodes in the same memory used for input frequency\n *\t    information.\n *\n * Array 'A', which contains 'sym_count' entries, is used for both input and\n * output.  For this function, 'sym_count' must be at least 2.\n *\n * For input, the array must contain the frequencies of the symbols, sorted in\n * increasing order.  Specifically, each entry must contain a frequency left\n * shifted by NUM_SYMBOL_BITS bits.  Any data in the low NUM_SYMBOL_BITS bits of\n * the entries will be ignored by this function.  Although these bits will, in\n * fact, contain the symbols that correspond to the frequencies, this function\n * is concerned with frequencies only and keeps the symbols as-is.\n *\n * For output, this function will produce the non-leaf nodes of the Huffman\n * tree.  These nodes will be stored in the first (sym_count - 1) entries of the\n * array.  Entry A[sym_count - 2] will represent the root node.  Each other node\n * will contain the zero-based index of its parent node in 'A', left shifted by\n * NUM_SYMBOL_BITS bits.  The low NUM_SYMBOL_BITS bits of each entry in A will\n * be kept as-is.  Again, note that although these low bits will, in fact,\n * contain a symbol value, this symbol will have *no relationship* with the\n * Huffman tree node that happens to occupy the same slot.  This is because this\n * implementation only generates the non-leaf nodes of the tree.\n */\nstatic void\nbuild_tree(u32 A[], unsigned sym_count)\n{\n\tconst unsigned last_idx = sym_count - 1;\n\n\t/* Index of the next lowest frequency leaf that still needs a parent */\n\tunsigned i = 0;\n\n\t/*\n\t * Index of the next lowest frequency non-leaf that still needs a\n\t * parent, or 'e' if there is currently no such node\n\t */\n\tunsigned b = 0;\n\n\t/* Index of the next spot for a non-leaf (will overwrite a leaf) */\n\tunsigned e = 0;\n\n\tdo {\n\t\tu32 new_freq;\n\n\t\t/*\n\t\t * Select the next two lowest frequency nodes among the leaves\n\t\t * A[i] and non-leaves A[b], and create a new node A[e] to be\n\t\t * their parent.  Set the new node's frequency to the sum of the\n\t\t * frequencies of its two children.\n\t\t *\n\t\t * Usually the next two lowest frequency nodes are of the same\n\t\t * type (leaf or non-leaf), so check those cases first.\n\t\t */\n\t\tif (i + 1 <= last_idx &&\n\t\t    (b == e || (A[i + 1] & FREQ_MASK) <= (A[b] & FREQ_MASK))) {\n\t\t\t/* Two leaves */\n\t\t\tnew_freq = (A[i] & FREQ_MASK) + (A[i + 1] & FREQ_MASK);\n\t\t\ti += 2;\n\t\t} else if (b + 2 <= e &&\n\t\t\t   (i > last_idx ||\n\t\t\t    (A[b + 1] & FREQ_MASK) < (A[i] & FREQ_MASK))) {\n\t\t\t/* Two non-leaves */\n\t\t\tnew_freq = (A[b] & FREQ_MASK) + (A[b + 1] & FREQ_MASK);\n\t\t\tA[b] = (e << NUM_SYMBOL_BITS) | (A[b] & SYMBOL_MASK);\n\t\t\tA[b + 1] = (e << NUM_SYMBOL_BITS) |\n\t\t\t\t   (A[b + 1] & SYMBOL_MASK);\n\t\t\tb += 2;\n\t\t} else {\n\t\t\t/* One leaf and one non-leaf */\n\t\t\tnew_freq = (A[i] & FREQ_MASK) + (A[b] & FREQ_MASK);\n\t\t\tA[b] = (e << NUM_SYMBOL_BITS) | (A[b] & SYMBOL_MASK);\n\t\t\ti++;\n\t\t\tb++;\n\t\t}\n\t\tA[e] = new_freq | (A[e] & SYMBOL_MASK);\n\t\t/*\n\t\t * A binary tree with 'n' leaves has 'n - 1' non-leaves, so the\n\t\t * tree is complete once we've created 'n - 1' non-leaves.\n\t\t */\n\t} while (++e < last_idx);\n}\n\n/*\n * Given the stripped-down Huffman tree constructed by build_tree(), determine\n * the number of codewords that should be assigned each possible length, taking\n * into account the length-limited constraint.\n *\n * @A\n *\tThe array produced by build_tree(), containing parent index information\n *\tfor the non-leaf nodes of the Huffman tree.  Each entry in this array is\n *\ta node; a node's parent always has a greater index than that node\n *\titself.  This function will overwrite the parent index information in\n *\tthis array, so essentially it will destroy the tree.  However, the data\n *\tin the low NUM_SYMBOL_BITS of each entry will be preserved.\n *\n * @root_idx\n *\tThe 0-based index of the root node in 'A', and consequently one less\n *\tthan the number of tree node entries in 'A'.  (Or, really 2 less than\n *\tthe actual length of 'A'.)\n *\n * @len_counts\n *\tAn array of length ('max_codeword_len' + 1) in which the number of\n *\tcodewords having each length <= max_codeword_len will be returned.\n *\n * @max_codeword_len\n *\tThe maximum permissible codeword length.\n */\nstatic void\ncompute_length_counts(u32 A[], unsigned root_idx, unsigned len_counts[],\n\t\t      unsigned max_codeword_len)\n{\n\tunsigned len;\n\tint node;\n\n\t/*\n\t * The key observations are:\n\t *\n\t * (1) We can traverse the non-leaf nodes of the tree, always visiting a\n\t *     parent before its children, by simply iterating through the array\n\t *     in reverse order.  Consequently, we can compute the depth of each\n\t *     node in one pass, overwriting the parent indices with depths.\n\t *\n\t * (2) We can initially assume that in the real Huffman tree, both\n\t *     children of the root are leaves.  This corresponds to two\n\t *     codewords of length 1.  Then, whenever we visit a (non-leaf) node\n\t *     during the traversal, we modify this assumption to account for\n\t *     the current node *not* being a leaf, but rather its two children\n\t *     being leaves.  This causes the loss of one codeword for the\n\t *     current depth and the addition of two codewords for the current\n\t *     depth plus one.\n\t *\n\t * (3) We can handle the length-limited constraint fairly easily by\n\t *     simply using the largest length available when a depth exceeds\n\t *     max_codeword_len.\n\t */\n\n\tfor (len = 0; len <= max_codeword_len; len++)\n\t\tlen_counts[len] = 0;\n\tlen_counts[1] = 2;\n\n\t/* Set the root node's depth to 0. */\n\tA[root_idx] &= SYMBOL_MASK;\n\n\tfor (node = root_idx - 1; node >= 0; node--) {\n\n\t\t/* Calculate the depth of this node. */\n\n\t\tunsigned parent = A[node] >> NUM_SYMBOL_BITS;\n\t\tunsigned parent_depth = A[parent] >> NUM_SYMBOL_BITS;\n\t\tunsigned depth = parent_depth + 1;\n\n\t\t/*\n\t\t * Set the depth of this node so that it is available when its\n\t\t * children (if any) are processed.\n\t\t */\n\t\tA[node] = (A[node] & SYMBOL_MASK) | (depth << NUM_SYMBOL_BITS);\n\n\t\t/*\n\t\t * If needed, decrease the length to meet the length-limited\n\t\t * constraint.  This is not the optimal method for generating\n\t\t * length-limited Huffman codes!  But it should be good enough.\n\t\t */\n\t\tif (depth >= max_codeword_len) {\n\t\t\tdepth = max_codeword_len;\n\t\t\tdo {\n\t\t\t\tdepth--;\n\t\t\t} while (len_counts[depth] == 0);\n\t\t}\n\n\t\t/*\n\t\t * Account for the fact that we have a non-leaf node at the\n\t\t * current depth.\n\t\t */\n\t\tlen_counts[depth]--;\n\t\tlen_counts[depth + 1] += 2;\n\t}\n}\n\n/*\n * DEFLATE uses bit-reversed codewords, so we must bit-reverse the codewords\n * after generating them.  All codewords have length <= 16 bits.  If the CPU has\n * a bit-reversal instruction, then that is the fastest method.  Otherwise the\n * fastest method is to reverse the bits in each of the two bytes using a table.\n * The table method is slightly faster than using bitwise operations to flip\n * adjacent 1, 2, 4, and then 8-bit fields, even if 2 to 4 codewords are packed\n * into a machine word and processed together using that method.\n */\n\n#ifdef rbit32\nstatic forceinline u32 reverse_codeword(u32 codeword, u8 len)\n{\n\treturn rbit32(codeword) >> ((32 - len) & 31);\n}\n#else\n/* Generated by scripts/gen_bitreverse_tab.py */\nstatic const u8 bitreverse_tab[256] = {\n\t0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,\n\t0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,\n\t0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,\n\t0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,\n\t0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,\n\t0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,\n\t0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,\n\t0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,\n\t0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,\n\t0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,\n\t0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,\n\t0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,\n\t0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,\n\t0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,\n\t0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,\n\t0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,\n\t0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,\n\t0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,\n\t0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,\n\t0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,\n\t0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,\n\t0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,\n\t0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,\n\t0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,\n\t0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,\n\t0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,\n\t0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,\n\t0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,\n\t0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,\n\t0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,\n\t0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,\n\t0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,\n};\n\nstatic forceinline u32 reverse_codeword(u32 codeword, u8 len)\n{\n\tSTATIC_ASSERT(DEFLATE_MAX_CODEWORD_LEN <= 16);\n\tcodeword = ((u32)bitreverse_tab[codeword & 0xff] << 8) |\n\t\t   bitreverse_tab[codeword >> 8];\n\treturn codeword >> (16 - len);\n}\n#endif /* !rbit32 */\n\n/*\n * Generate the codewords for a canonical Huffman code.\n *\n * @A\n *\tThe output array for codewords.  In addition, initially this\n *\tarray must contain the symbols, sorted primarily by frequency and\n *\tsecondarily by symbol value, in the low NUM_SYMBOL_BITS bits of\n *\teach entry.\n *\n * @len\n *\tOutput array for codeword lengths.\n *\n * @len_counts\n *\tAn array that provides the number of codewords that will have\n *\teach possible length <= max_codeword_len.\n *\n * @max_codeword_len\n *\tMaximum length, in bits, of each codeword.\n *\n * @num_syms\n *\tNumber of symbols in the alphabet, including symbols with zero\n *\tfrequency.  This is the length of the 'A' and 'len' arrays.\n */\nstatic void\ngen_codewords(u32 A[], u8 lens[], const unsigned len_counts[],\n\t      unsigned max_codeword_len, unsigned num_syms)\n{\n\tu32 next_codewords[DEFLATE_MAX_CODEWORD_LEN + 1];\n\tunsigned i;\n\tunsigned len;\n\tunsigned sym;\n\n\t/*\n\t * Given the number of codewords that will have each length, assign\n\t * codeword lengths to symbols.  We do this by assigning the lengths in\n\t * decreasing order to the symbols sorted primarily by increasing\n\t * frequency and secondarily by increasing symbol value.\n\t */\n\tfor (i = 0, len = max_codeword_len; len >= 1; len--) {\n\t\tunsigned count = len_counts[len];\n\n\t\twhile (count--)\n\t\t\tlens[A[i++] & SYMBOL_MASK] = len;\n\t}\n\n\t/*\n\t * Generate the codewords themselves.  We initialize the\n\t * 'next_codewords' array to provide the lexicographically first\n\t * codeword of each length, then assign codewords in symbol order.  This\n\t * produces a canonical code.\n\t */\n\tnext_codewords[0] = 0;\n\tnext_codewords[1] = 0;\n\tfor (len = 2; len <= max_codeword_len; len++)\n\t\tnext_codewords[len] =\n\t\t\t(next_codewords[len - 1] + len_counts[len - 1]) << 1;\n\n\tfor (sym = 0; sym < num_syms; sym++) {\n\t\t/* DEFLATE requires bit-reversed codewords. */\n\t\tA[sym] = reverse_codeword(next_codewords[lens[sym]]++,\n\t\t\t\t\t  lens[sym]);\n\t}\n}\n\n/*\n * ---------------------------------------------------------------------\n *\t\t\tdeflate_make_huffman_code()\n * ---------------------------------------------------------------------\n *\n * Given an alphabet and the frequency of each symbol in it, construct a\n * length-limited canonical Huffman code.\n *\n * @num_syms\n *\tThe number of symbols in the alphabet.  The symbols are the integers in\n *\tthe range [0, num_syms - 1].  This parameter must be at least 2 and\n *\tmust not exceed (1 << NUM_SYMBOL_BITS).\n *\n * @max_codeword_len\n *\tThe maximum permissible codeword length.\n *\n * @freqs\n *\tAn array of length @num_syms that gives the frequency of each symbol.\n *\tIt is valid for some, none, or all of the frequencies to be 0.  The sum\n *\tof frequencies must not exceed (1 << NUM_FREQ_BITS) - 1.\n *\n * @lens\n *\tAn array of @num_syms entries in which this function will return the\n *\tlength, in bits, of the codeword assigned to each symbol.  Symbols with\n *\t0 frequency will not have codewords per se, but their entries in this\n *\tarray will be set to 0.  No lengths greater than @max_codeword_len will\n *\tbe assigned.\n *\n * @codewords\n *\tAn array of @num_syms entries in which this function will return the\n *\tcodeword for each symbol, right-justified and padded on the left with\n *\tzeroes.  Codewords for symbols with 0 frequency will be undefined.\n *\n * ---------------------------------------------------------------------\n *\n * This function builds a length-limited canonical Huffman code.\n *\n * A length-limited Huffman code contains no codewords longer than some\n * specified length, and has exactly (with some algorithms) or approximately\n * (with the algorithm used here) the minimum weighted path length from the\n * root, given this constraint.\n *\n * A canonical Huffman code satisfies the properties that a longer codeword\n * never lexicographically precedes a shorter codeword, and the lexicographic\n * ordering of codewords of the same length is the same as the lexicographic\n * ordering of the corresponding symbols.  A canonical Huffman code, or more\n * generally a canonical prefix code, can be reconstructed from only a list\n * containing the codeword length of each symbol.\n *\n * The classic algorithm to generate a Huffman code creates a node for each\n * symbol, then inserts these nodes into a min-heap keyed by symbol frequency.\n * Then, repeatedly, the two lowest-frequency nodes are removed from the\n * min-heap and added as the children of a new node having frequency equal to\n * the sum of its two children, which is then inserted into the min-heap.  When\n * only a single node remains in the min-heap, it is the root of the Huffman\n * tree.  The codeword for each symbol is determined by the path needed to reach\n * the corresponding node from the root.  Descending to the left child appends a\n * 0 bit, whereas descending to the right child appends a 1 bit.\n *\n * The classic algorithm is relatively easy to understand, but it is subject to\n * a number of inefficiencies.  In practice, it is fastest to first sort the\n * symbols by frequency.  (This itself can be subject to an optimization based\n * on the fact that most frequencies tend to be low.)  At the same time, we sort\n * secondarily by symbol value, which aids the process of generating a canonical\n * code.  Then, during tree construction, no heap is necessary because both the\n * leaf nodes and the unparented non-leaf nodes can be easily maintained in\n * sorted order.  Consequently, there can never be more than two possibilities\n * for the next-lowest-frequency node.\n *\n * In addition, because we're generating a canonical code, we actually don't\n * need the leaf nodes of the tree at all, only the non-leaf nodes.  This is\n * because for canonical code generation we don't need to know where the symbols\n * are in the tree.  Rather, we only need to know how many leaf nodes have each\n * depth (codeword length).  And this information can, in fact, be quickly\n * generated from the tree of non-leaves only.\n *\n * Furthermore, we can build this stripped-down Huffman tree directly in the\n * array in which the codewords are to be generated, provided that these array\n * slots are large enough to hold a symbol and frequency value.\n *\n * Still furthermore, we don't even need to maintain explicit child pointers.\n * We only need the parent pointers, and even those can be overwritten in-place\n * with depth information as part of the process of extracting codeword lengths\n * from the tree.  So in summary, we do NOT need a big structure like:\n *\n *\tstruct huffman_tree_node {\n *\t\tunsigned int symbol;\n *\t\tunsigned int frequency;\n *\t\tunsigned int depth;\n *\t\tstruct huffman_tree_node *left_child;\n *\t\tstruct huffman_tree_node *right_child;\n *\t};\n *\n *\n * ... which often gets used in \"naive\" implementations of Huffman code\n * generation.\n *\n * Many of these optimizations are based on the implementation in 7-Zip (source\n * file: C/HuffEnc.c), which was placed in the public domain by Igor Pavlov.\n */\nstatic void\ndeflate_make_huffman_code(unsigned num_syms, unsigned max_codeword_len,\n\t\t\t  const u32 freqs[], u8 lens[], u32 codewords[])\n{\n\tu32 *A = codewords;\n\tunsigned num_used_syms;\n\n\tSTATIC_ASSERT(DEFLATE_MAX_NUM_SYMS <= 1 << NUM_SYMBOL_BITS);\n\tSTATIC_ASSERT(MAX_BLOCK_LENGTH <= ((u32)1 << NUM_FREQ_BITS) - 1);\n\n\t/*\n\t * We begin by sorting the symbols primarily by frequency and\n\t * secondarily by symbol value.  As an optimization, the array used for\n\t * this purpose ('A') shares storage with the space in which we will\n\t * eventually return the codewords.\n\t */\n\tnum_used_syms = sort_symbols(num_syms, freqs, lens, A);\n\t/*\n\t * 'num_used_syms' is the number of symbols with nonzero frequency.\n\t * This may be less than @num_syms.  'num_used_syms' is also the number\n\t * of entries in 'A' that are valid.  Each entry consists of a distinct\n\t * symbol and a nonzero frequency packed into a 32-bit integer.\n\t */\n\n\t/*\n\t * A complete Huffman code must contain at least 2 codewords.  Yet, it's\n\t * possible that fewer than 2 symbols were used.  When this happens,\n\t * it's usually for the offset code (0-1 symbols used).  But it's also\n\t * theoretically possible for the litlen and pre codes (1 symbol used).\n\t *\n\t * The DEFLATE RFC explicitly allows the offset code to contain just 1\n\t * codeword, or even be completely empty.  But it's silent about the\n\t * other codes.  It also doesn't say whether, in the 1-codeword case,\n\t * the codeword (which it says must be 1 bit) is '0' or '1'.\n\t *\n\t * In any case, some DEFLATE decompressors reject these cases.  zlib\n\t * generally allows them, but it does reject precodes that have just 1\n\t * codeword.  More problematically, zlib v1.2.1 and earlier rejected\n\t * empty offset codes, and this behavior can also be seen in Windows\n\t * Explorer's ZIP unpacker (supposedly even still in Windows 11).\n\t *\n\t * Other DEFLATE compressors, including zlib, always send at least 2\n\t * codewords in order to make a complete Huffman code.  Therefore, this\n\t * is a case where practice does not entirely match the specification.\n\t * We follow practice by generating 2 codewords of length 1: codeword\n\t * '0' for symbol 0, and codeword '1' for another symbol -- the used\n\t * symbol if it exists and is not symbol 0, otherwise symbol 1.  This\n\t * does worsen the compression ratio by having to send an unnecessary\n\t * offset codeword length.  But this only affects rare cases such as\n\t * blocks containing all literals, and it only makes a tiny difference.\n\t */\n\tif (unlikely(num_used_syms < 2)) {\n\t\tunsigned sym = num_used_syms ? (A[0] & SYMBOL_MASK) : 0;\n\t\tunsigned nonzero_idx = sym ? sym : 1;\n\n\t\tcodewords[0] = 0;\n\t\tlens[0] = 1;\n\t\tcodewords[nonzero_idx] = 1;\n\t\tlens[nonzero_idx] = 1;\n\t\treturn;\n\t}\n\n\t/*\n\t * Build a stripped-down version of the Huffman tree, sharing the array\n\t * 'A' with the symbol values.  Then extract length counts from the tree\n\t * and use them to generate the final codewords.\n\t */\n\n\tbuild_tree(A, num_used_syms);\n\n\t{\n\t\tunsigned len_counts[DEFLATE_MAX_CODEWORD_LEN + 1];\n\n\t\tcompute_length_counts(A, num_used_syms - 2,\n\t\t\t\t      len_counts, max_codeword_len);\n\n\t\tgen_codewords(A, lens, len_counts, max_codeword_len, num_syms);\n\t}\n}\n\n/*\n * Clear the Huffman symbol frequency counters.  This must be called when\n * starting a new DEFLATE block.\n */\nstatic void\ndeflate_reset_symbol_frequencies(struct libdeflate_compressor *c)\n{\n\tmemset(&c->freqs, 0, sizeof(c->freqs));\n}\n\n/*\n * Build the literal/length and offset Huffman codes for a DEFLATE block.\n *\n * This takes as input the frequency tables for each alphabet and produces as\n * output a set of tables that map symbols to codewords and codeword lengths.\n */\nstatic void\ndeflate_make_huffman_codes(const struct deflate_freqs *freqs,\n\t\t\t   struct deflate_codes *codes)\n{\n\tdeflate_make_huffman_code(DEFLATE_NUM_LITLEN_SYMS,\n\t\t\t\t  MAX_LITLEN_CODEWORD_LEN,\n\t\t\t\t  freqs->litlen,\n\t\t\t\t  codes->lens.litlen,\n\t\t\t\t  codes->codewords.litlen);\n\n\tdeflate_make_huffman_code(DEFLATE_NUM_OFFSET_SYMS,\n\t\t\t\t  MAX_OFFSET_CODEWORD_LEN,\n\t\t\t\t  freqs->offset,\n\t\t\t\t  codes->lens.offset,\n\t\t\t\t  codes->codewords.offset);\n}\n\n/* Initialize c->static_codes. */\nstatic void\ndeflate_init_static_codes(struct libdeflate_compressor *c)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < 144; i++)\n\t\tc->freqs.litlen[i] = 1 << (9 - 8);\n\tfor (; i < 256; i++)\n\t\tc->freqs.litlen[i] = 1 << (9 - 9);\n\tfor (; i < 280; i++)\n\t\tc->freqs.litlen[i] = 1 << (9 - 7);\n\tfor (; i < 288; i++)\n\t\tc->freqs.litlen[i] = 1 << (9 - 8);\n\n\tfor (i = 0; i < 32; i++)\n\t\tc->freqs.offset[i] = 1 << (5 - 5);\n\n\tdeflate_make_huffman_codes(&c->freqs, &c->static_codes);\n}\n\n/* Return the offset slot for the given match offset, using the small map. */\nstatic forceinline unsigned\ndeflate_get_offset_slot(u32 offset)\n{\n\t/*\n\t * 1 <= offset <= 32768 here.  For 1 <= offset <= 256,\n\t * deflate_offset_slot[offset - 1] gives the slot.\n\t *\n\t * For 257 <= offset <= 32768, we take advantage of the fact that 257 is\n\t * the beginning of slot 16, and each slot [16..30) is exactly 1 << 7 ==\n\t * 128 times larger than each slot [2..16) (since the number of extra\n\t * bits increases by 1 every 2 slots).  Thus, the slot is:\n\t *\n\t *\tdeflate_offset_slot[2 + ((offset - 257) >> 7)] + (16 - 2)\n\t *   == deflate_offset_slot[((offset - 1) >> 7)] + 14\n\t *\n\t * Define 'n = (offset <= 256) ? 0 : 7'.  Then any offset is handled by:\n\t *\n\t *      deflate_offset_slot[(offset - 1) >> n] + (n << 1)\n\t *\n\t * For better performance, replace 'n = (offset <= 256) ? 0 : 7' with\n\t * the equivalent (for offset <= 536871168) 'n = (256 - offset) >> 29'.\n\t */\n\tunsigned n = (256 - offset) >> 29;\n\n\tASSERT(offset >= 1 && offset <= 32768);\n\n\treturn deflate_offset_slot[(offset - 1) >> n] + (n << 1);\n}\n\nstatic unsigned\ndeflate_compute_precode_items(const u8 lens[], const unsigned num_lens,\n\t\t\t      u32 precode_freqs[], unsigned precode_items[])\n{\n\tunsigned *itemptr;\n\tunsigned run_start;\n\tunsigned run_end;\n\tunsigned extra_bits;\n\tu8 len;\n\n\tmemset(precode_freqs, 0,\n\t       DEFLATE_NUM_PRECODE_SYMS * sizeof(precode_freqs[0]));\n\n\titemptr = precode_items;\n\trun_start = 0;\n\tdo {\n\t\t/* Find the next run of codeword lengths. */\n\n\t\t/* len = the length being repeated */\n\t\tlen = lens[run_start];\n\n\t\t/* Extend the run. */\n\t\trun_end = run_start;\n\t\tdo {\n\t\t\trun_end++;\n\t\t} while (run_end != num_lens && len == lens[run_end]);\n\n\t\tif (len == 0) {\n\t\t\t/* Run of zeroes. */\n\n\t\t\t/* Symbol 18: RLE 11 to 138 zeroes at a time. */\n\t\t\twhile ((run_end - run_start) >= 11) {\n\t\t\t\textra_bits = MIN((run_end - run_start) - 11,\n\t\t\t\t\t\t 0x7F);\n\t\t\t\tprecode_freqs[18]++;\n\t\t\t\t*itemptr++ = 18 | (extra_bits << 5);\n\t\t\t\trun_start += 11 + extra_bits;\n\t\t\t}\n\n\t\t\t/* Symbol 17: RLE 3 to 10 zeroes at a time. */\n\t\t\tif ((run_end - run_start) >= 3) {\n\t\t\t\textra_bits = MIN((run_end - run_start) - 3,\n\t\t\t\t\t\t 0x7);\n\t\t\t\tprecode_freqs[17]++;\n\t\t\t\t*itemptr++ = 17 | (extra_bits << 5);\n\t\t\t\trun_start += 3 + extra_bits;\n\t\t\t}\n\t\t} else {\n\n\t\t\t/* A run of nonzero lengths. */\n\n\t\t\t/* Symbol 16: RLE 3 to 6 of the previous length. */\n\t\t\tif ((run_end - run_start) >= 4) {\n\t\t\t\tprecode_freqs[len]++;\n\t\t\t\t*itemptr++ = len;\n\t\t\t\trun_start++;\n\t\t\t\tdo {\n\t\t\t\t\textra_bits = MIN((run_end - run_start) -\n\t\t\t\t\t\t\t 3, 0x3);\n\t\t\t\t\tprecode_freqs[16]++;\n\t\t\t\t\t*itemptr++ = 16 | (extra_bits << 5);\n\t\t\t\t\trun_start += 3 + extra_bits;\n\t\t\t\t} while ((run_end - run_start) >= 3);\n\t\t\t}\n\t\t}\n\n\t\t/* Output any remaining lengths without RLE. */\n\t\twhile (run_start != run_end) {\n\t\t\tprecode_freqs[len]++;\n\t\t\t*itemptr++ = len;\n\t\t\trun_start++;\n\t\t}\n\t} while (run_start != num_lens);\n\n\treturn itemptr - precode_items;\n}\n\n/*\n * Huffman codeword lengths for dynamic Huffman blocks are compressed using a\n * separate Huffman code, the \"precode\", which contains a symbol for each\n * possible codeword length in the larger code as well as several special\n * symbols to represent repeated codeword lengths (a form of run-length\n * encoding).  The precode is itself constructed in canonical form, and its\n * codeword lengths are represented literally in 19 3-bit fields that\n * immediately precede the compressed codeword lengths of the larger code.\n */\n\n/* Precompute the information needed to output dynamic Huffman codes. */\nstatic void\ndeflate_precompute_huffman_header(struct libdeflate_compressor *c)\n{\n\t/* Compute how many litlen and offset symbols are needed. */\n\n\tfor (c->o.precode.num_litlen_syms = DEFLATE_NUM_LITLEN_SYMS;\n\t     c->o.precode.num_litlen_syms > 257;\n\t     c->o.precode.num_litlen_syms--)\n\t\tif (c->codes.lens.litlen[c->o.precode.num_litlen_syms - 1] != 0)\n\t\t\tbreak;\n\n\tfor (c->o.precode.num_offset_syms = DEFLATE_NUM_OFFSET_SYMS;\n\t     c->o.precode.num_offset_syms > 1;\n\t     c->o.precode.num_offset_syms--)\n\t\tif (c->codes.lens.offset[c->o.precode.num_offset_syms - 1] != 0)\n\t\t\tbreak;\n\n\t/*\n\t * If we're not using the full set of literal/length codeword lengths,\n\t * then temporarily move the offset codeword lengths over so that the\n\t * literal/length and offset codeword lengths are contiguous.\n\t */\n\tSTATIC_ASSERT(offsetof(struct deflate_lens, offset) ==\n\t\t      DEFLATE_NUM_LITLEN_SYMS);\n\tif (c->o.precode.num_litlen_syms != DEFLATE_NUM_LITLEN_SYMS) {\n\t\tmemmove((u8 *)&c->codes.lens + c->o.precode.num_litlen_syms,\n\t\t\t(u8 *)&c->codes.lens + DEFLATE_NUM_LITLEN_SYMS,\n\t\t\tc->o.precode.num_offset_syms);\n\t}\n\n\t/*\n\t * Compute the \"items\" (RLE / literal tokens and extra bits) with which\n\t * the codeword lengths in the larger code will be output.\n\t */\n\tc->o.precode.num_items =\n\t\tdeflate_compute_precode_items((u8 *)&c->codes.lens,\n\t\t\t\t\t      c->o.precode.num_litlen_syms +\n\t\t\t\t\t      c->o.precode.num_offset_syms,\n\t\t\t\t\t      c->o.precode.freqs,\n\t\t\t\t\t      c->o.precode.items);\n\n\t/* Build the precode. */\n\tdeflate_make_huffman_code(DEFLATE_NUM_PRECODE_SYMS,\n\t\t\t\t  MAX_PRE_CODEWORD_LEN,\n\t\t\t\t  c->o.precode.freqs, c->o.precode.lens,\n\t\t\t\t  c->o.precode.codewords);\n\n\t/* Count how many precode lengths we actually need to output. */\n\tfor (c->o.precode.num_explicit_lens = DEFLATE_NUM_PRECODE_SYMS;\n\t     c->o.precode.num_explicit_lens > 4;\n\t     c->o.precode.num_explicit_lens--)\n\t\tif (c->o.precode.lens[deflate_precode_lens_permutation[\n\t\t\t\tc->o.precode.num_explicit_lens - 1]] != 0)\n\t\t\tbreak;\n\n\t/* Restore the offset codeword lengths if needed. */\n\tif (c->o.precode.num_litlen_syms != DEFLATE_NUM_LITLEN_SYMS) {\n\t\tmemmove((u8 *)&c->codes.lens + DEFLATE_NUM_LITLEN_SYMS,\n\t\t\t(u8 *)&c->codes.lens + c->o.precode.num_litlen_syms,\n\t\t\tc->o.precode.num_offset_syms);\n\t}\n}\n\n/*\n * To make it faster to output matches, compute the \"full\" match length\n * codewords, i.e. the concatenation of the litlen codeword and the extra bits\n * for each possible match length.\n */\nstatic void\ndeflate_compute_full_len_codewords(struct libdeflate_compressor *c,\n\t\t\t\t   const struct deflate_codes *codes)\n{\n\tu32 len;\n\n\tSTATIC_ASSERT(MAX_LITLEN_CODEWORD_LEN +\n\t\t      DEFLATE_MAX_EXTRA_LENGTH_BITS <= 32);\n\n\tfor (len = DEFLATE_MIN_MATCH_LEN; len <= DEFLATE_MAX_MATCH_LEN; len++) {\n\t\tunsigned slot = deflate_length_slot[len];\n\t\tunsigned litlen_sym = DEFLATE_FIRST_LEN_SYM + slot;\n\t\tu32 extra_bits = len - deflate_length_slot_base[slot];\n\n\t\tc->o.length.codewords[len] =\n\t\t\tcodes->codewords.litlen[litlen_sym] |\n\t\t\t(extra_bits << codes->lens.litlen[litlen_sym]);\n\t\tc->o.length.lens[len] = codes->lens.litlen[litlen_sym] +\n\t\t\t\t\tdeflate_extra_length_bits[slot];\n\t}\n}\n\n/* Write a match to the output buffer. */\n#define WRITE_MATCH(c_, codes_, length_, offset_, offset_slot_)\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tconst struct libdeflate_compressor *c__ = (c_);\t\t\t\\\n\tconst struct deflate_codes *codes__ = (codes_);\t\t\t\\\n\tu32 length__ = (length_);\t\t\t\t\t\\\n\tu32 offset__ = (offset_);\t\t\t\t\t\\\n\tunsigned offset_slot__ = (offset_slot_);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t/* Litlen symbol and extra length bits */\t\t\t\\\n\tSTATIC_ASSERT(CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +\t\t\\\n\t\t\t\t DEFLATE_MAX_EXTRA_LENGTH_BITS));\t\\\n\tADD_BITS(c__->o.length.codewords[length__],\t\t\t\\\n\t\t c__->o.length.lens[length__]);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +\t\t\t\\\n\t\t\tDEFLATE_MAX_EXTRA_LENGTH_BITS +\t\t\t\\\n\t\t\tMAX_OFFSET_CODEWORD_LEN +\t\t\t\\\n\t\t\tDEFLATE_MAX_EXTRA_OFFSET_BITS))\t\t\t\\\n\t\tFLUSH_BITS();\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t/* Offset symbol */\t\t\t\t\t\t\\\n\tADD_BITS(codes__->codewords.offset[offset_slot__],\t\t\\\n\t\t codes__->lens.offset[offset_slot__]);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tif (!CAN_BUFFER(MAX_OFFSET_CODEWORD_LEN +\t\t\t\\\n\t\t\tDEFLATE_MAX_EXTRA_OFFSET_BITS))\t\t\t\\\n\t\tFLUSH_BITS();\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t/* Extra offset bits */\t\t\t\t\t\t\\\n\tADD_BITS(offset__ - deflate_offset_slot_base[offset_slot__],\t\\\n\t\t deflate_extra_offset_bits[offset_slot__]);\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tFLUSH_BITS();\t\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * Choose the best type of block to use (dynamic Huffman, static Huffman, or\n * uncompressed), then output it.\n *\n * The uncompressed data of the block is @block_begin[0..@block_length-1].  The\n * sequence of literals and matches that will be used to compress the block (if\n * a compressed block is chosen) is given by @sequences if it's non-NULL, or\n * else @c->p.n.optimum_nodes.  @c->freqs and @c->codes must be already set\n * according to the literals, matches, and end-of-block symbol.\n */\nstatic void\ndeflate_flush_block(struct libdeflate_compressor *c,\n\t\t    struct deflate_output_bitstream *os,\n\t\t    const u8 *block_begin, u32 block_length,\n\t\t    const struct deflate_sequence *sequences,\n\t\t    bool is_final_block)\n{\n\t/*\n\t * It is hard to get compilers to understand that writes to 'os->next'\n\t * don't alias 'os'.  That hurts performance significantly, as\n\t * everything in 'os' would keep getting re-loaded.  ('restrict'\n\t * *should* do the trick, but it's unreliable.)  Therefore, we keep all\n\t * the output bitstream state in local variables, and output bits using\n\t * macros.  This is similar to what the decompressor does.\n\t */\n\tconst u8 *in_next = block_begin;\n\tconst u8 * const in_end = block_begin + block_length;\n\tbitbuf_t bitbuf = os->bitbuf;\n\tunsigned bitcount = os->bitcount;\n\tu8 *out_next = os->next;\n\tu8 * const out_fast_end =\n\t\tos->end - MIN(WORDBYTES - 1, os->end - out_next);\n\t/*\n\t * The cost for each block type, in bits.  Start with the cost of the\n\t * block header which is 3 bits.\n\t */\n\tu32 dynamic_cost = 3;\n\tu32 static_cost = 3;\n\tu32 uncompressed_cost = 3;\n\tu32 best_cost;\n\tstruct deflate_codes *codes;\n\tunsigned sym;\n\n\tASSERT(block_length >= MIN_BLOCK_LENGTH ||\n\t       (is_final_block && block_length > 0));\n\tASSERT(block_length <= MAX_BLOCK_LENGTH);\n\tASSERT(bitcount <= 7);\n\tASSERT((bitbuf & ~(((bitbuf_t)1 << bitcount) - 1)) == 0);\n\tASSERT(out_next <= os->end);\n\tASSERT(!os->overflow);\n\n\t/* Precompute the precode items and build the precode. */\n\tdeflate_precompute_huffman_header(c);\n\n\t/* Account for the cost of encoding dynamic Huffman codes. */\n\tdynamic_cost += 5 + 5 + 4 + (3 * c->o.precode.num_explicit_lens);\n\tfor (sym = 0; sym < DEFLATE_NUM_PRECODE_SYMS; sym++) {\n\t\tu32 extra = deflate_extra_precode_bits[sym];\n\n\t\tdynamic_cost += c->o.precode.freqs[sym] *\n\t\t\t\t(extra + c->o.precode.lens[sym]);\n\t}\n\n\t/* Account for the cost of encoding literals. */\n\tfor (sym = 0; sym < 144; sym++) {\n\t\tdynamic_cost += c->freqs.litlen[sym] *\n\t\t\t\tc->codes.lens.litlen[sym];\n\t\tstatic_cost += c->freqs.litlen[sym] * 8;\n\t}\n\tfor (; sym < 256; sym++) {\n\t\tdynamic_cost += c->freqs.litlen[sym] *\n\t\t\t\tc->codes.lens.litlen[sym];\n\t\tstatic_cost += c->freqs.litlen[sym] * 9;\n\t}\n\n\t/* Account for the cost of encoding the end-of-block symbol. */\n\tdynamic_cost += c->codes.lens.litlen[DEFLATE_END_OF_BLOCK];\n\tstatic_cost += 7;\n\n\t/* Account for the cost of encoding lengths. */\n\tfor (sym = DEFLATE_FIRST_LEN_SYM;\n\t     sym < DEFLATE_FIRST_LEN_SYM + ARRAY_LEN(deflate_extra_length_bits);\n\t     sym++) {\n\t\tu32 extra = deflate_extra_length_bits[\n\t\t\t\t\tsym - DEFLATE_FIRST_LEN_SYM];\n\n\t\tdynamic_cost += c->freqs.litlen[sym] *\n\t\t\t\t(extra + c->codes.lens.litlen[sym]);\n\t\tstatic_cost += c->freqs.litlen[sym] *\n\t\t\t\t(extra + c->static_codes.lens.litlen[sym]);\n\t}\n\n\t/* Account for the cost of encoding offsets. */\n\tfor (sym = 0; sym < ARRAY_LEN(deflate_extra_offset_bits); sym++) {\n\t\tu32 extra = deflate_extra_offset_bits[sym];\n\n\t\tdynamic_cost += c->freqs.offset[sym] *\n\t\t\t\t(extra + c->codes.lens.offset[sym]);\n\t\tstatic_cost += c->freqs.offset[sym] * (extra + 5);\n\t}\n\n\t/* Compute the cost of using uncompressed blocks. */\n\tuncompressed_cost += (-(bitcount + 3) & 7) + 32 +\n\t\t\t     (40 * (DIV_ROUND_UP(block_length,\n\t\t\t\t\t\t UINT16_MAX) - 1)) +\n\t\t\t     (8 * block_length);\n\n\t/*\n\t * Choose and output the cheapest type of block.  If there is a tie,\n\t * prefer uncompressed, then static, then dynamic.\n\t */\n\n\tbest_cost = MIN(dynamic_cost, MIN(static_cost, uncompressed_cost));\n\n\t/* If the block isn't going to fit, then stop early. */\n\tif (DIV_ROUND_UP(bitcount + best_cost, 8) > os->end - out_next) {\n\t\tos->overflow = true;\n\t\treturn;\n\t}\n\t/*\n\t * Else, now we know that the block fits, so no further bounds checks on\n\t * the output buffer are required until the next block.\n\t */\n\n\tif (best_cost == uncompressed_cost) {\n\t\t/*\n\t\t * Uncompressed block(s).  DEFLATE limits the length of\n\t\t * uncompressed blocks to UINT16_MAX bytes, so if the length of\n\t\t * the \"block\" we're flushing is over UINT16_MAX, we actually\n\t\t * output multiple blocks.\n\t\t */\n\t\tdo {\n\t\t\tu8 bfinal = 0;\n\t\t\tsize_t len = UINT16_MAX;\n\n\t\t\tif (in_end - in_next <= UINT16_MAX) {\n\t\t\t\tbfinal = is_final_block;\n\t\t\t\tlen = in_end - in_next;\n\t\t\t}\n\t\t\t/* It was already checked that there is enough space. */\n\t\t\tASSERT(os->end - out_next >=\n\t\t\t       DIV_ROUND_UP(bitcount + 3, 8) + 4 + len);\n\t\t\t/*\n\t\t\t * Output BFINAL (1 bit) and BTYPE (2 bits), then align\n\t\t\t * to a byte boundary.\n\t\t\t */\n\t\t\tSTATIC_ASSERT(DEFLATE_BLOCKTYPE_UNCOMPRESSED == 0);\n\t\t\t*out_next++ = (bfinal << bitcount) | bitbuf;\n\t\t\tif (bitcount > 5)\n\t\t\t\t*out_next++ = 0;\n\t\t\tbitbuf = 0;\n\t\t\tbitcount = 0;\n\t\t\t/* Output LEN and NLEN, then the data itself. */\n\t\t\tput_unaligned_le16(len, out_next);\n\t\t\tout_next += 2;\n\t\t\tput_unaligned_le16(~len, out_next);\n\t\t\tout_next += 2;\n\t\t\tmemcpy(out_next, in_next, len);\n\t\t\tout_next += len;\n\t\t\tin_next += len;\n\t\t} while (in_next != in_end);\n\t\t/* Done outputting uncompressed block(s) */\n\t\tgoto out;\n\t}\n\n\tif (best_cost == static_cost) {\n\t\t/* Static Huffman block */\n\t\tcodes = &c->static_codes;\n\t\tADD_BITS(is_final_block, 1);\n\t\tADD_BITS(DEFLATE_BLOCKTYPE_STATIC_HUFFMAN, 2);\n\t\tFLUSH_BITS();\n\t} else {\n\t\tconst unsigned num_explicit_lens = c->o.precode.num_explicit_lens;\n\t\tconst unsigned num_precode_items = c->o.precode.num_items;\n\t\tunsigned precode_sym, precode_item;\n\t\tunsigned i;\n\n\t\t/* Dynamic Huffman block */\n\n\t\tcodes = &c->codes;\n\t\tSTATIC_ASSERT(CAN_BUFFER(1 + 2 + 5 + 5 + 4 + 3));\n\t\tADD_BITS(is_final_block, 1);\n\t\tADD_BITS(DEFLATE_BLOCKTYPE_DYNAMIC_HUFFMAN, 2);\n\t\tADD_BITS(c->o.precode.num_litlen_syms - 257, 5);\n\t\tADD_BITS(c->o.precode.num_offset_syms - 1, 5);\n\t\tADD_BITS(num_explicit_lens - 4, 4);\n\n\t\t/* Output the lengths of the codewords in the precode. */\n\t\tif (CAN_BUFFER(3 * (DEFLATE_NUM_PRECODE_SYMS - 1))) {\n\t\t\t/*\n\t\t\t * A 64-bit bitbuffer is just one bit too small to hold\n\t\t\t * the maximum number of precode lens, so to minimize\n\t\t\t * flushes we merge one len with the previous fields.\n\t\t\t */\n\t\t\tprecode_sym = deflate_precode_lens_permutation[0];\n\t\t\tADD_BITS(c->o.precode.lens[precode_sym], 3);\n\t\t\tFLUSH_BITS();\n\t\t\ti = 1; /* num_explicit_lens >= 4 */\n\t\t\tdo {\n\t\t\t\tprecode_sym =\n\t\t\t\t\tdeflate_precode_lens_permutation[i];\n\t\t\t\tADD_BITS(c->o.precode.lens[precode_sym], 3);\n\t\t\t} while (++i < num_explicit_lens);\n\t\t\tFLUSH_BITS();\n\t\t} else {\n\t\t\tFLUSH_BITS();\n\t\t\ti = 0;\n\t\t\tdo {\n\t\t\t\tprecode_sym =\n\t\t\t\t\tdeflate_precode_lens_permutation[i];\n\t\t\t\tADD_BITS(c->o.precode.lens[precode_sym], 3);\n\t\t\t\tFLUSH_BITS();\n\t\t\t} while (++i < num_explicit_lens);\n\t\t}\n\n\t\t/*\n\t\t * Output the lengths of the codewords in the litlen and offset\n\t\t * codes, encoded by the precode.\n\t\t */\n\t\ti = 0;\n\t\tdo {\n\t\t\tprecode_item = c->o.precode.items[i];\n\t\t\tprecode_sym = precode_item & 0x1F;\n\t\t\tSTATIC_ASSERT(CAN_BUFFER(MAX_PRE_CODEWORD_LEN + 7));\n\t\t\tADD_BITS(c->o.precode.codewords[precode_sym],\n\t\t\t\t c->o.precode.lens[precode_sym]);\n\t\t\tADD_BITS(precode_item >> 5,\n\t\t\t\t deflate_extra_precode_bits[precode_sym]);\n\t\t\tFLUSH_BITS();\n\t\t} while (++i < num_precode_items);\n\t}\n\n\t/* Output the literals and matches for a dynamic or static block. */\n\tASSERT(bitcount <= 7);\n\tdeflate_compute_full_len_codewords(c, codes);\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\tif (sequences == NULL) {\n\t\t/* Output the literals and matches from the minimum-cost path */\n\t\tstruct deflate_optimum_node *cur_node =\n\t\t\t&c->p.n.optimum_nodes[0];\n\t\tstruct deflate_optimum_node * const end_node =\n\t\t\t&c->p.n.optimum_nodes[block_length];\n\t\tdo {\n\t\t\tu32 length = cur_node->item & OPTIMUM_LEN_MASK;\n\t\t\tu32 offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;\n\n\t\t\tif (length == 1) {\n\t\t\t\t/* Literal */\n\t\t\t\tADD_BITS(codes->codewords.litlen[offset],\n\t\t\t\t\t codes->lens.litlen[offset]);\n\t\t\t\tFLUSH_BITS();\n\t\t\t} else {\n\t\t\t\t/* Match */\n\t\t\t\tWRITE_MATCH(c, codes, length, offset,\n\t\t\t\t\t    c->p.n.offset_slot_full[offset]);\n\t\t\t}\n\t\t\tcur_node += length;\n\t\t} while (cur_node != end_node);\n\t} else\n#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\t{\n\t\t/* Output the literals and matches from the sequences list. */\n\t\tconst struct deflate_sequence *seq;\n\n\t\tfor (seq = sequences; ; seq++) {\n\t\t\tu32 litrunlen = seq->litrunlen_and_length &\n\t\t\t\t\tSEQ_LITRUNLEN_MASK;\n\t\t\tu32 length = seq->litrunlen_and_length >>\n\t\t\t\t     SEQ_LENGTH_SHIFT;\n\t\t\tunsigned lit;\n\n\t\t\t/* Output a run of literals. */\n\t\t\tif (CAN_BUFFER(4 * MAX_LITLEN_CODEWORD_LEN)) {\n\t\t\t\tfor (; litrunlen >= 4; litrunlen -= 4) {\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tFLUSH_BITS();\n\t\t\t\t}\n\t\t\t\tif (litrunlen-- != 0) {\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tif (litrunlen-- != 0) {\n\t\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\t\tif (litrunlen-- != 0) {\n\t\t\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tFLUSH_BITS();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile (litrunlen--) {\n\t\t\t\t\tlit = *in_next++;\n\t\t\t\t\tADD_BITS(codes->codewords.litlen[lit],\n\t\t\t\t\t\t codes->lens.litlen[lit]);\n\t\t\t\t\tFLUSH_BITS();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (length == 0) { /* Last sequence? */\n\t\t\t\tASSERT(in_next == in_end);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* Output a match. */\n\t\t\tWRITE_MATCH(c, codes, length, seq->offset,\n\t\t\t\t    seq->offset_slot);\n\t\t\tin_next += length;\n\t\t}\n\t}\n\n\t/* Output the end-of-block symbol. */\n\tASSERT(bitcount <= 7);\n\tADD_BITS(codes->codewords.litlen[DEFLATE_END_OF_BLOCK],\n\t\t codes->lens.litlen[DEFLATE_END_OF_BLOCK]);\n\tFLUSH_BITS();\nout:\n\tASSERT(bitcount <= 7);\n\t/*\n\t * Assert that the block cost was computed correctly.  This is relied on\n\t * above for the bounds check on the output buffer.  Also,\n\t * libdeflate_deflate_compress_bound() relies on this via the assumption\n\t * that uncompressed blocks will always be used when cheapest.\n\t */\n\tASSERT(8 * (out_next - os->next) + bitcount - os->bitcount == best_cost);\n\tos->bitbuf = bitbuf;\n\tos->bitcount = bitcount;\n\tos->next = out_next;\n}\n\nstatic void\ndeflate_finish_block(struct libdeflate_compressor *c,\n\t\t     struct deflate_output_bitstream *os,\n\t\t     const u8 *block_begin, u32 block_length,\n\t\t     const struct deflate_sequence *sequences,\n\t\t     bool is_final_block)\n{\n\tc->freqs.litlen[DEFLATE_END_OF_BLOCK]++;\n\tdeflate_make_huffman_codes(&c->freqs, &c->codes);\n\tdeflate_flush_block(c, os, block_begin, block_length, sequences,\n\t\t\t    is_final_block);\n}\n\n/******************************************************************************/\n\n/*\n * Block splitting algorithm.  The problem is to decide when it is worthwhile to\n * start a new block with new Huffman codes.  There is a theoretically optimal\n * solution: recursively consider every possible block split, considering the\n * exact cost of each block, and choose the minimum cost approach.  But this is\n * far too slow.  Instead, as an approximation, we can count symbols and after\n * every N symbols, compare the expected distribution of symbols based on the\n * previous data with the actual distribution.  If they differ \"by enough\", then\n * start a new block.\n *\n * As an optimization and heuristic, we don't distinguish between every symbol\n * but rather we combine many symbols into a single \"observation type\".  For\n * literals we only look at the high bits and low bits, and for matches we only\n * look at whether the match is long or not.  The assumption is that for typical\n * \"real\" data, places that are good block boundaries will tend to be noticeable\n * based only on changes in these aggregate probabilities, without looking for\n * subtle differences in individual symbols.  For example, a change from ASCII\n * bytes to non-ASCII bytes, or from few matches (generally less compressible)\n * to many matches (generally more compressible), would be easily noticed based\n * on the aggregates.\n *\n * For determining whether the probability distributions are \"different enough\"\n * to start a new block, the simple heuristic of splitting when the sum of\n * absolute differences exceeds a constant seems to be good enough.  We also add\n * a number proportional to the block length so that the algorithm is more\n * likely to end long blocks than short blocks.  This reflects the general\n * expectation that it will become increasingly beneficial to start a new block\n * as the current block grows longer.\n *\n * Finally, for an approximation, it is not strictly necessary that the exact\n * symbols being used are considered.  With \"near-optimal parsing\", for example,\n * the actual symbols that will be used are unknown until after the block\n * boundary is chosen and the block has been optimized.  Since the final choices\n * cannot be used, we can use preliminary \"greedy\" choices instead.\n */\n\n/* Initialize the block split statistics when starting a new block. */\nstatic void\ninit_block_split_stats(struct block_split_stats *stats)\n{\n\tint i;\n\n\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++) {\n\t\tstats->new_observations[i] = 0;\n\t\tstats->observations[i] = 0;\n\t}\n\tstats->num_new_observations = 0;\n\tstats->num_observations = 0;\n}\n\n/*\n * Literal observation.  Heuristic: use the top 2 bits and low 1 bits of the\n * literal, for 8 possible literal observation types.\n */\nstatic forceinline void\nobserve_literal(struct block_split_stats *stats, u8 lit)\n{\n\tstats->new_observations[((lit >> 5) & 0x6) | (lit & 1)]++;\n\tstats->num_new_observations++;\n}\n\n/*\n * Match observation.  Heuristic: use one observation type for \"short match\" and\n * one observation type for \"long match\".\n */\nstatic forceinline void\nobserve_match(struct block_split_stats *stats, u32 length)\n{\n\tstats->new_observations[NUM_LITERAL_OBSERVATION_TYPES +\n\t\t\t\t(length >= 9)]++;\n\tstats->num_new_observations++;\n}\n\nstatic void\nmerge_new_observations(struct block_split_stats *stats)\n{\n\tint i;\n\n\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++) {\n\t\tstats->observations[i] += stats->new_observations[i];\n\t\tstats->new_observations[i] = 0;\n\t}\n\tstats->num_observations += stats->num_new_observations;\n\tstats->num_new_observations = 0;\n}\n\nstatic bool\ndo_end_block_check(struct block_split_stats *stats, u32 block_length)\n{\n\tif (stats->num_observations > 0) {\n\t\t/*\n\t\t * Compute the sum of absolute differences of probabilities.  To\n\t\t * avoid needing to use floating point arithmetic or do slow\n\t\t * divisions, we do all arithmetic with the probabilities\n\t\t * multiplied by num_observations * num_new_observations.  E.g.,\n\t\t * for the \"old\" observations the probabilities would be\n\t\t * (double)observations[i] / num_observations, but since we\n\t\t * multiply by both num_observations and num_new_observations we\n\t\t * really do observations[i] * num_new_observations.\n\t\t */\n\t\tu32 total_delta = 0;\n\t\tu32 num_items;\n\t\tu32 cutoff;\n\t\tint i;\n\n\t\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++) {\n\t\t\tu32 expected = stats->observations[i] *\n\t\t\t\t       stats->num_new_observations;\n\t\t\tu32 actual = stats->new_observations[i] *\n\t\t\t\t     stats->num_observations;\n\t\t\tu32 delta = (actual > expected) ? actual - expected :\n\t\t\t\t\t\t\t  expected - actual;\n\n\t\t\ttotal_delta += delta;\n\t\t}\n\n\t\tnum_items = stats->num_observations +\n\t\t\t    stats->num_new_observations;\n\t\t/*\n\t\t * Heuristic: the cutoff is when the sum of absolute differences\n\t\t * of probabilities becomes at least 200/512.  As above, the\n\t\t * probability is multiplied by both num_new_observations and\n\t\t * num_observations.  Be careful to avoid integer overflow.\n\t\t */\n\t\tcutoff = stats->num_new_observations * 200 / 512 *\n\t\t\t stats->num_observations;\n\t\t/*\n\t\t * Very short blocks have a lot of overhead for the Huffman\n\t\t * codes, so only use them if it clearly seems worthwhile.\n\t\t * (This is an additional penalty, which adds to the smaller\n\t\t * penalty below which scales more slowly.)\n\t\t */\n\t\tif (block_length < 10000 && num_items < 8192)\n\t\t\tcutoff += (u64)cutoff * (8192 - num_items) / 8192;\n\n\t\t/* Ready to end the block? */\n\t\tif (total_delta +\n\t\t    (block_length / 4096) * stats->num_observations >= cutoff)\n\t\t\treturn true;\n\t}\n\tmerge_new_observations(stats);\n\treturn false;\n}\n\nstatic forceinline bool\nready_to_check_block(const struct block_split_stats *stats,\n\t\t     const u8 *in_block_begin, const u8 *in_next,\n\t\t     const u8 *in_end)\n{\n\treturn stats->num_new_observations >= NUM_OBSERVATIONS_PER_BLOCK_CHECK\n\t\t&& in_next - in_block_begin >= MIN_BLOCK_LENGTH\n\t\t&& in_end - in_next >= MIN_BLOCK_LENGTH;\n}\n\nstatic forceinline bool\nshould_end_block(struct block_split_stats *stats,\n\t\t const u8 *in_block_begin, const u8 *in_next, const u8 *in_end)\n{\n\t/* Ready to try to end the block (again)? */\n\tif (!ready_to_check_block(stats, in_block_begin, in_next, in_end))\n\t\treturn false;\n\n\treturn do_end_block_check(stats, in_next - in_block_begin);\n}\n\n/******************************************************************************/\n\nstatic void\ndeflate_begin_sequences(struct libdeflate_compressor *c,\n\t\t\tstruct deflate_sequence *first_seq)\n{\n\tdeflate_reset_symbol_frequencies(c);\n\tfirst_seq->litrunlen_and_length = 0;\n}\n\nstatic forceinline void\ndeflate_choose_literal(struct libdeflate_compressor *c, unsigned literal,\n\t\t       bool gather_split_stats, struct deflate_sequence *seq)\n{\n\tc->freqs.litlen[literal]++;\n\n\tif (gather_split_stats)\n\t\tobserve_literal(&c->split_stats, literal);\n\n\tSTATIC_ASSERT(MAX_BLOCK_LENGTH <= SEQ_LITRUNLEN_MASK);\n\tseq->litrunlen_and_length++;\n}\n\nstatic forceinline void\ndeflate_choose_match(struct libdeflate_compressor *c,\n\t\t     u32 length, u32 offset, bool gather_split_stats,\n\t\t     struct deflate_sequence **seq_p)\n{\n\tstruct deflate_sequence *seq = *seq_p;\n\tunsigned length_slot = deflate_length_slot[length];\n\tunsigned offset_slot = deflate_get_offset_slot(offset);\n\n\tc->freqs.litlen[DEFLATE_FIRST_LEN_SYM + length_slot]++;\n\tc->freqs.offset[offset_slot]++;\n\tif (gather_split_stats)\n\t\tobserve_match(&c->split_stats, length);\n\n\tseq->litrunlen_and_length |= length << SEQ_LENGTH_SHIFT;\n\tseq->offset = offset;\n\tseq->offset_slot = offset_slot;\n\n\tseq++;\n\tseq->litrunlen_and_length = 0;\n\t*seq_p = seq;\n}\n\n/*\n * Decrease the maximum and nice match lengths if we're approaching the end of\n * the input buffer.\n */\nstatic forceinline void\nadjust_max_and_nice_len(u32 *max_len, u32 *nice_len, size_t remaining)\n{\n\tif (unlikely(remaining < DEFLATE_MAX_MATCH_LEN)) {\n\t\t*max_len = remaining;\n\t\t*nice_len = MIN(*nice_len, *max_len);\n\t}\n}\n\n/*\n * Choose the minimum match length for the greedy and lazy parsers.\n *\n * By default the minimum match length is 3, which is the smallest length the\n * DEFLATE format allows.  However, with greedy and lazy parsing, some data\n * (e.g. DNA sequencing data) benefits greatly from a longer minimum length.\n * Typically, this is because literals are very cheap.  In general, the\n * near-optimal parser handles this case naturally, but the greedy and lazy\n * parsers need a heuristic to decide when to use short matches.\n *\n * The heuristic we use is to make the minimum match length depend on the number\n * of different literals that exist in the data.  If there are many different\n * literals, then literals will probably be expensive, so short matches will\n * probably be worthwhile.  Conversely, if not many literals are used, then\n * probably literals will be cheap and short matches won't be worthwhile.\n */\nstatic u32\nchoose_min_match_len(u32 num_used_literals, u32 max_search_depth)\n{\n\t/* map from num_used_literals to min_len */\n\tstatic const u8 min_lens[] = {\n\t\t9, 9, 9, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6, 6, 6, 6,\n\t\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n\t\t5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4,\n\t\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n\t\t/* The rest is implicitly 3. */\n\t};\n\tu32 min_len;\n\n\tSTATIC_ASSERT(DEFLATE_MIN_MATCH_LEN <= 3);\n\tSTATIC_ASSERT(ARRAY_LEN(min_lens) <= DEFLATE_NUM_LITERALS + 1);\n\n\tif (num_used_literals >= ARRAY_LEN(min_lens))\n\t\treturn 3;\n\tmin_len = min_lens[num_used_literals];\n\t/*\n\t * With a low max_search_depth, it may be too hard to find long matches.\n\t */\n\tif (max_search_depth < 16) {\n\t\tif (max_search_depth < 5)\n\t\t\tmin_len = MIN(min_len, 4);\n\t\telse if (max_search_depth < 10)\n\t\t\tmin_len = MIN(min_len, 5);\n\t\telse\n\t\t\tmin_len = MIN(min_len, 7);\n\t}\n\treturn min_len;\n}\n\nstatic u32\ncalculate_min_match_len(const u8 *data, size_t data_len, u32 max_search_depth)\n{\n\tu8 used[256] = { 0 };\n\tu32 num_used_literals = 0;\n\tsize_t i;\n\n\t/*\n\t * For very short inputs, the static Huffman code has a good chance of\n\t * being best, in which case there is no reason to avoid short matches.\n\t */\n\tif (data_len < 512)\n\t\treturn DEFLATE_MIN_MATCH_LEN;\n\n\t/*\n\t * For an initial approximation, scan the first 4 KiB of data.  The\n\t * caller may use recalculate_min_match_len() to update min_len later.\n\t */\n\tdata_len = MIN(data_len, 4096);\n\tfor (i = 0; i < data_len; i++)\n\t\tused[data[i]] = 1;\n\tfor (i = 0; i < 256; i++)\n\t\tnum_used_literals += used[i];\n\treturn choose_min_match_len(num_used_literals, max_search_depth);\n}\n\n/*\n * Recalculate the minimum match length for a block, now that we know the\n * distribution of literals that are actually being used (freqs->litlen).\n */\nstatic u32\nrecalculate_min_match_len(const struct deflate_freqs *freqs,\n\t\t\t  u32 max_search_depth)\n{\n\tu32 literal_freq = 0;\n\tu32 cutoff;\n\tu32 num_used_literals = 0;\n\tint i;\n\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++)\n\t\tliteral_freq += freqs->litlen[i];\n\n\tcutoff = literal_freq >> 10; /* Ignore literals used very rarely. */\n\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++) {\n\t\tif (freqs->litlen[i] > cutoff)\n\t\t\tnum_used_literals++;\n\t}\n\treturn choose_min_match_len(num_used_literals, max_search_depth);\n}\n\nstatic forceinline const u8 *\nchoose_max_block_end(const u8 *in_block_begin, const u8 *in_end,\n\t\t     size_t soft_max_len)\n{\n\tif (in_end - in_block_begin < soft_max_len + MIN_BLOCK_LENGTH)\n\t\treturn in_end;\n\treturn in_block_begin + soft_max_len;\n}\n\n/*\n * This is the level 0 \"compressor\".  It always outputs uncompressed blocks.\n */\nstatic size_t\ndeflate_compress_none(const u8 *in, size_t in_nbytes,\n\t\t      u8 *out, size_t out_nbytes_avail)\n{\n\tconst u8 *in_next = in;\n\tconst u8 * const in_end = in + in_nbytes;\n\tu8 *out_next = out;\n\tu8 * const out_end = out + out_nbytes_avail;\n\n\t/*\n\t * If the input is zero-length, we still must output a block in order\n\t * for the output to be a valid DEFLATE stream.  Handle this case\n\t * specially to avoid potentially passing NULL to memcpy() below.\n\t */\n\tif (unlikely(in_nbytes == 0)) {\n\t\tif (out_nbytes_avail < 5)\n\t\t\treturn 0;\n\t\t/* BFINAL and BTYPE */\n\t\t*out_next++ = 1 | (DEFLATE_BLOCKTYPE_UNCOMPRESSED << 1);\n\t\t/* LEN and NLEN */\n\t\tput_unaligned_le32(0xFFFF0000, out_next);\n\t\treturn 5;\n\t}\n\n\tdo {\n\t\tu8 bfinal = 0;\n\t\tsize_t len = UINT16_MAX;\n\n\t\tif (in_end - in_next <= UINT16_MAX) {\n\t\t\tbfinal = 1;\n\t\t\tlen = in_end - in_next;\n\t\t}\n\t\tif (out_end - out_next < 5 + len)\n\t\t\treturn 0;\n\t\t/*\n\t\t * Output BFINAL and BTYPE.  The stream is already byte-aligned\n\t\t * here, so this step always requires outputting exactly 1 byte.\n\t\t */\n\t\t*out_next++ = bfinal | (DEFLATE_BLOCKTYPE_UNCOMPRESSED << 1);\n\n\t\t/* Output LEN and NLEN, then the data itself. */\n\t\tput_unaligned_le16(len, out_next);\n\t\tout_next += 2;\n\t\tput_unaligned_le16(~len, out_next);\n\t\tout_next += 2;\n\t\tmemcpy(out_next, in_next, len);\n\t\tout_next += len;\n\t\tin_next += len;\n\t} while (in_next != in_end);\n\n\treturn out_next - out;\n}\n\n/*\n * This is a faster variant of deflate_compress_greedy().  It uses the\n * ht_matchfinder rather than the hc_matchfinder.  It also skips the block\n * splitting algorithm and just uses fixed length blocks.  c->max_search_depth\n * has no effect with this algorithm, as it is hardcoded in ht_matchfinder.h.\n */\nstatic void\ndeflate_compress_fastest(struct libdeflate_compressor * restrict c,\n\t\t\t const u8 *in, size_t in_nbytes,\n\t\t\t struct deflate_output_bitstream *os)\n{\n\tconst u8 *in_next = in;\n\tconst u8 *in_end = in_next + in_nbytes;\n\tconst u8 *in_cur_base = in_next;\n\tu32 max_len = DEFLATE_MAX_MATCH_LEN;\n\tu32 nice_len = MIN(c->nice_match_length, max_len);\n\tu32 next_hash = 0;\n\n\tht_matchfinder_init(&c->p.f.ht_mf);\n\n\tdo {\n\t\t/* Starting a new DEFLATE block */\n\n\t\tconst u8 * const in_block_begin = in_next;\n\t\tconst u8 * const in_max_block_end = choose_max_block_end(\n\t\t\t\tin_next, in_end, FAST_SOFT_MAX_BLOCK_LENGTH);\n\t\tstruct deflate_sequence *seq = c->p.f.sequences;\n\n\t\tdeflate_begin_sequences(c, seq);\n\n\t\tdo {\n\t\t\tu32 length;\n\t\t\tu32 offset;\n\t\t\tsize_t remaining = in_end - in_next;\n\n\t\t\tif (unlikely(remaining < DEFLATE_MAX_MATCH_LEN)) {\n\t\t\t\tmax_len = remaining;\n\t\t\t\tif (max_len < HT_MATCHFINDER_REQUIRED_NBYTES) {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tdeflate_choose_literal(c,\n\t\t\t\t\t\t\t*in_next++, false, seq);\n\t\t\t\t\t} while (--max_len);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tnice_len = MIN(nice_len, max_len);\n\t\t\t}\n\t\t\tlength = ht_matchfinder_longest_match(&c->p.f.ht_mf,\n\t\t\t\t\t\t\t      &in_cur_base,\n\t\t\t\t\t\t\t      in_next,\n\t\t\t\t\t\t\t      max_len,\n\t\t\t\t\t\t\t      nice_len,\n\t\t\t\t\t\t\t      &next_hash,\n\t\t\t\t\t\t\t      &offset);\n\t\t\tif (length) {\n\t\t\t\t/* Match found */\n\t\t\t\tdeflate_choose_match(c, length, offset, false,\n\t\t\t\t\t\t     &seq);\n\t\t\t\tht_matchfinder_skip_bytes(&c->p.f.ht_mf,\n\t\t\t\t\t\t\t  &in_cur_base,\n\t\t\t\t\t\t\t  in_next + 1,\n\t\t\t\t\t\t\t  in_end,\n\t\t\t\t\t\t\t  length - 1,\n\t\t\t\t\t\t\t  &next_hash);\n\t\t\t\tin_next += length;\n\t\t\t} else {\n\t\t\t\t/* No match found */\n\t\t\t\tdeflate_choose_literal(c, *in_next++, false,\n\t\t\t\t\t\t       seq);\n\t\t\t}\n\n\t\t\t/* Check if it's time to output another block. */\n\t\t} while (in_next < in_max_block_end &&\n\t\t\t seq < &c->p.f.sequences[FAST_SEQ_STORE_LENGTH]);\n\n\t\tdeflate_finish_block(c, os, in_block_begin,\n\t\t\t\t     in_next - in_block_begin,\n\t\t\t\t     c->p.f.sequences, in_next == in_end);\n\t} while (in_next != in_end && !os->overflow);\n}\n\n/*\n * This is the \"greedy\" DEFLATE compressor. It always chooses the longest match.\n */\nstatic void\ndeflate_compress_greedy(struct libdeflate_compressor * restrict c,\n\t\t\tconst u8 *in, size_t in_nbytes,\n\t\t\tstruct deflate_output_bitstream *os)\n{\n\tconst u8 *in_next = in;\n\tconst u8 *in_end = in_next + in_nbytes;\n\tconst u8 *in_cur_base = in_next;\n\tu32 max_len = DEFLATE_MAX_MATCH_LEN;\n\tu32 nice_len = MIN(c->nice_match_length, max_len);\n\tu32 next_hashes[2] = {0, 0};\n\n\thc_matchfinder_init(&c->p.g.hc_mf);\n\n\tdo {\n\t\t/* Starting a new DEFLATE block */\n\n\t\tconst u8 * const in_block_begin = in_next;\n\t\tconst u8 * const in_max_block_end = choose_max_block_end(\n\t\t\t\tin_next, in_end, SOFT_MAX_BLOCK_LENGTH);\n\t\tstruct deflate_sequence *seq = c->p.g.sequences;\n\t\tu32 min_len;\n\n\t\tinit_block_split_stats(&c->split_stats);\n\t\tdeflate_begin_sequences(c, seq);\n\t\tmin_len = calculate_min_match_len(in_next,\n\t\t\t\t\t\t  in_max_block_end - in_next,\n\t\t\t\t\t\t  c->max_search_depth);\n\t\tdo {\n\t\t\tu32 length;\n\t\t\tu32 offset;\n\n\t\t\tadjust_max_and_nice_len(&max_len, &nice_len,\n\t\t\t\t\t\tin_end - in_next);\n\t\t\tlength = hc_matchfinder_longest_match(\n\t\t\t\t\t\t&c->p.g.hc_mf,\n\t\t\t\t\t\t&in_cur_base,\n\t\t\t\t\t\tin_next,\n\t\t\t\t\t\tmin_len - 1,\n\t\t\t\t\t\tmax_len,\n\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\tc->max_search_depth,\n\t\t\t\t\t\tnext_hashes,\n\t\t\t\t\t\t&offset);\n\n\t\t\tif (length >= min_len &&\n\t\t\t    (length > DEFLATE_MIN_MATCH_LEN ||\n\t\t\t     offset <= 4096)) {\n\t\t\t\t/* Match found */\n\t\t\t\tdeflate_choose_match(c, length, offset, true,\n\t\t\t\t\t\t     &seq);\n\t\t\t\thc_matchfinder_skip_bytes(&c->p.g.hc_mf,\n\t\t\t\t\t\t\t  &in_cur_base,\n\t\t\t\t\t\t\t  in_next + 1,\n\t\t\t\t\t\t\t  in_end,\n\t\t\t\t\t\t\t  length - 1,\n\t\t\t\t\t\t\t  next_hashes);\n\t\t\t\tin_next += length;\n\t\t\t} else {\n\t\t\t\t/* No match found */\n\t\t\t\tdeflate_choose_literal(c, *in_next++, true,\n\t\t\t\t\t\t       seq);\n\t\t\t}\n\n\t\t\t/* Check if it's time to output another block. */\n\t\t} while (in_next < in_max_block_end &&\n\t\t\t seq < &c->p.g.sequences[SEQ_STORE_LENGTH] &&\n\t\t\t !should_end_block(&c->split_stats,\n\t\t\t\t\t   in_block_begin, in_next, in_end));\n\n\t\tdeflate_finish_block(c, os, in_block_begin,\n\t\t\t\t     in_next - in_block_begin,\n\t\t\t\t     c->p.g.sequences, in_next == in_end);\n\t} while (in_next != in_end && !os->overflow);\n}\n\nstatic forceinline void\ndeflate_compress_lazy_generic(struct libdeflate_compressor * restrict c,\n\t\t\t      const u8 *in, size_t in_nbytes,\n\t\t\t      struct deflate_output_bitstream *os, bool lazy2)\n{\n\tconst u8 *in_next = in;\n\tconst u8 *in_end = in_next + in_nbytes;\n\tconst u8 *in_cur_base = in_next;\n\tu32 max_len = DEFLATE_MAX_MATCH_LEN;\n\tu32 nice_len = MIN(c->nice_match_length, max_len);\n\tu32 next_hashes[2] = {0, 0};\n\n\thc_matchfinder_init(&c->p.g.hc_mf);\n\n\tdo {\n\t\t/* Starting a new DEFLATE block */\n\n\t\tconst u8 * const in_block_begin = in_next;\n\t\tconst u8 * const in_max_block_end = choose_max_block_end(\n\t\t\t\tin_next, in_end, SOFT_MAX_BLOCK_LENGTH);\n\t\tconst u8 *next_recalc_min_len =\n\t\t\tin_next + MIN(in_end - in_next, 10000);\n\t\tstruct deflate_sequence *seq = c->p.g.sequences;\n\t\tu32 min_len;\n\n\t\tinit_block_split_stats(&c->split_stats);\n\t\tdeflate_begin_sequences(c, seq);\n\t\tmin_len = calculate_min_match_len(in_next,\n\t\t\t\t\t\t  in_max_block_end - in_next,\n\t\t\t\t\t\t  c->max_search_depth);\n\t\tdo {\n\t\t\tu32 cur_len;\n\t\t\tu32 cur_offset;\n\t\t\tu32 next_len;\n\t\t\tu32 next_offset;\n\n\t\t\t/*\n\t\t\t * Recalculate the minimum match length if it hasn't\n\t\t\t * been done recently.\n\t\t\t */\n\t\t\tif (in_next >= next_recalc_min_len) {\n\t\t\t\tmin_len = recalculate_min_match_len(\n\t\t\t\t\t\t&c->freqs,\n\t\t\t\t\t\tc->max_search_depth);\n\t\t\t\tnext_recalc_min_len +=\n\t\t\t\t\tMIN(in_end - next_recalc_min_len,\n\t\t\t\t\t    in_next - in_block_begin);\n\t\t\t}\n\n\t\t\t/* Find the longest match at the current position. */\n\t\t\tadjust_max_and_nice_len(&max_len, &nice_len,\n\t\t\t\t\t\tin_end - in_next);\n\t\t\tcur_len = hc_matchfinder_longest_match(\n\t\t\t\t\t\t&c->p.g.hc_mf,\n\t\t\t\t\t\t&in_cur_base,\n\t\t\t\t\t\tin_next,\n\t\t\t\t\t\tmin_len - 1,\n\t\t\t\t\t\tmax_len,\n\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\tc->max_search_depth,\n\t\t\t\t\t\tnext_hashes,\n\t\t\t\t\t\t&cur_offset);\n\t\t\tif (cur_len < min_len ||\n\t\t\t    (cur_len == DEFLATE_MIN_MATCH_LEN &&\n\t\t\t     cur_offset > 8192)) {\n\t\t\t\t/* No match found.  Choose a literal. */\n\t\t\t\tdeflate_choose_literal(c, *in_next++, true,\n\t\t\t\t\t\t       seq);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tin_next++;\n\nhave_cur_match:\n\t\t\t/*\n\t\t\t * We have a match at the current position.\n\t\t\t * If it's very long, choose it immediately.\n\t\t\t */\n\t\t\tif (cur_len >= nice_len) {\n\t\t\t\tdeflate_choose_match(c, cur_len, cur_offset,\n\t\t\t\t\t\t     true, &seq);\n\t\t\t\thc_matchfinder_skip_bytes(&c->p.g.hc_mf,\n\t\t\t\t\t\t\t  &in_cur_base,\n\t\t\t\t\t\t\t  in_next,\n\t\t\t\t\t\t\t  in_end,\n\t\t\t\t\t\t\t  cur_len - 1,\n\t\t\t\t\t\t\t  next_hashes);\n\t\t\t\tin_next += cur_len - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Try to find a better match at the next position.\n\t\t\t *\n\t\t\t * Note: since we already have a match at the *current*\n\t\t\t * position, we use only half the 'max_search_depth'\n\t\t\t * when checking the *next* position.  This is a useful\n\t\t\t * trade-off because it's more worthwhile to use a\n\t\t\t * greater search depth on the initial match.\n\t\t\t *\n\t\t\t * Note: it's possible to structure the code such that\n\t\t\t * there's only one call to longest_match(), which\n\t\t\t * handles both the \"find the initial match\" and \"try to\n\t\t\t * find a better match\" cases.  However, it is faster to\n\t\t\t * have two call sites, with longest_match() inlined at\n\t\t\t * each.\n\t\t\t */\n\t\t\tadjust_max_and_nice_len(&max_len, &nice_len,\n\t\t\t\t\t\tin_end - in_next);\n\t\t\tnext_len = hc_matchfinder_longest_match(\n\t\t\t\t\t\t&c->p.g.hc_mf,\n\t\t\t\t\t\t&in_cur_base,\n\t\t\t\t\t\tin_next++,\n\t\t\t\t\t\tcur_len - 1,\n\t\t\t\t\t\tmax_len,\n\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\tc->max_search_depth >> 1,\n\t\t\t\t\t\tnext_hashes,\n\t\t\t\t\t\t&next_offset);\n\t\t\tif (next_len >= cur_len &&\n\t\t\t    4 * (int)(next_len - cur_len) +\n\t\t\t    ((int)bsr32(cur_offset) -\n\t\t\t     (int)bsr32(next_offset)) > 2) {\n\t\t\t\t/*\n\t\t\t\t * Found a better match at the next position.\n\t\t\t\t * Output a literal.  Then the next match\n\t\t\t\t * becomes the current match.\n\t\t\t\t */\n\t\t\t\tdeflate_choose_literal(c, *(in_next - 2), true,\n\t\t\t\t\t\t       seq);\n\t\t\t\tcur_len = next_len;\n\t\t\t\tcur_offset = next_offset;\n\t\t\t\tgoto have_cur_match;\n\t\t\t}\n\n\t\t\tif (lazy2) {\n\t\t\t\t/* In lazy2 mode, look ahead another position */\n\t\t\t\tadjust_max_and_nice_len(&max_len, &nice_len,\n\t\t\t\t\t\t\tin_end - in_next);\n\t\t\t\tnext_len = hc_matchfinder_longest_match(\n\t\t\t\t\t\t&c->p.g.hc_mf,\n\t\t\t\t\t\t&in_cur_base,\n\t\t\t\t\t\tin_next++,\n\t\t\t\t\t\tcur_len - 1,\n\t\t\t\t\t\tmax_len,\n\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\tc->max_search_depth >> 2,\n\t\t\t\t\t\tnext_hashes,\n\t\t\t\t\t\t&next_offset);\n\t\t\t\tif (next_len >= cur_len &&\n\t\t\t\t    4 * (int)(next_len - cur_len) +\n\t\t\t\t    ((int)bsr32(cur_offset) -\n\t\t\t\t     (int)bsr32(next_offset)) > 6) {\n\t\t\t\t\t/*\n\t\t\t\t\t * There's a much better match two\n\t\t\t\t\t * positions ahead, so use two literals.\n\t\t\t\t\t */\n\t\t\t\t\tdeflate_choose_literal(\n\t\t\t\t\t\tc, *(in_next - 3), true, seq);\n\t\t\t\t\tdeflate_choose_literal(\n\t\t\t\t\t\tc, *(in_next - 2), true, seq);\n\t\t\t\t\tcur_len = next_len;\n\t\t\t\t\tcur_offset = next_offset;\n\t\t\t\t\tgoto have_cur_match;\n\t\t\t\t}\n\t\t\t\t/*\n\t\t\t\t * No better match at either of the next 2\n\t\t\t\t * positions.  Output the current match.\n\t\t\t\t */\n\t\t\t\tdeflate_choose_match(c, cur_len, cur_offset,\n\t\t\t\t\t\t     true, &seq);\n\t\t\t\tif (cur_len > 3) {\n\t\t\t\t\thc_matchfinder_skip_bytes(&c->p.g.hc_mf,\n\t\t\t\t\t\t\t\t  &in_cur_base,\n\t\t\t\t\t\t\t\t  in_next,\n\t\t\t\t\t\t\t\t  in_end,\n\t\t\t\t\t\t\t\t  cur_len - 3,\n\t\t\t\t\t\t\t\t  next_hashes);\n\t\t\t\t\tin_next += cur_len - 3;\n\t\t\t\t}\n\t\t\t} else { /* !lazy2 */\n\t\t\t\t/*\n\t\t\t\t * No better match at the next position.  Output\n\t\t\t\t * the current match.\n\t\t\t\t */\n\t\t\t\tdeflate_choose_match(c, cur_len, cur_offset,\n\t\t\t\t\t\t     true, &seq);\n\t\t\t\thc_matchfinder_skip_bytes(&c->p.g.hc_mf,\n\t\t\t\t\t\t\t  &in_cur_base,\n\t\t\t\t\t\t\t  in_next,\n\t\t\t\t\t\t\t  in_end,\n\t\t\t\t\t\t\t  cur_len - 2,\n\t\t\t\t\t\t\t  next_hashes);\n\t\t\t\tin_next += cur_len - 2;\n\t\t\t}\n\t\t\t/* Check if it's time to output another block. */\n\t\t} while (in_next < in_max_block_end &&\n\t\t\t seq < &c->p.g.sequences[SEQ_STORE_LENGTH] &&\n\t\t\t !should_end_block(&c->split_stats,\n\t\t\t\t\t   in_block_begin, in_next, in_end));\n\n\t\tdeflate_finish_block(c, os, in_block_begin,\n\t\t\t\t     in_next - in_block_begin,\n\t\t\t\t     c->p.g.sequences, in_next == in_end);\n\t} while (in_next != in_end && !os->overflow);\n}\n\n/*\n * This is the \"lazy\" DEFLATE compressor.  Before choosing a match, it checks to\n * see if there's a better match at the next position.  If yes, it outputs a\n * literal and continues to the next position.  If no, it outputs the match.\n */\nstatic void\ndeflate_compress_lazy(struct libdeflate_compressor * restrict c,\n\t\t      const u8 *in, size_t in_nbytes,\n\t\t      struct deflate_output_bitstream *os)\n{\n\tdeflate_compress_lazy_generic(c, in, in_nbytes, os, false);\n}\n\n/*\n * The lazy2 compressor.  This is similar to the regular lazy one, but it looks\n * for a better match at the next 2 positions rather than the next 1.  This\n * makes it take slightly more time, but compress some inputs slightly more.\n */\nstatic void\ndeflate_compress_lazy2(struct libdeflate_compressor * restrict c,\n\t\t       const u8 *in, size_t in_nbytes,\n\t\t       struct deflate_output_bitstream *os)\n{\n\tdeflate_compress_lazy_generic(c, in, in_nbytes, os, true);\n}\n\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\n/*\n * Follow the minimum-cost path in the graph of possible match/literal choices\n * for the current block and compute the frequencies of the Huffman symbols that\n * would be needed to output those matches and literals.\n */\nstatic void\ndeflate_tally_item_list(struct libdeflate_compressor *c, u32 block_length)\n{\n\tstruct deflate_optimum_node *cur_node = &c->p.n.optimum_nodes[0];\n\tstruct deflate_optimum_node *end_node =\n\t\t&c->p.n.optimum_nodes[block_length];\n\n\tdo {\n\t\tu32 length = cur_node->item & OPTIMUM_LEN_MASK;\n\t\tu32 offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;\n\n\t\tif (length == 1) {\n\t\t\t/* Literal */\n\t\t\tc->freqs.litlen[offset]++;\n\t\t} else {\n\t\t\t/* Match */\n\t\t\tc->freqs.litlen[DEFLATE_FIRST_LEN_SYM +\n\t\t\t\t\tdeflate_length_slot[length]]++;\n\t\t\tc->freqs.offset[c->p.n.offset_slot_full[offset]]++;\n\t\t}\n\t\tcur_node += length;\n\t} while (cur_node != end_node);\n\n\t/* Tally the end-of-block symbol. */\n\tc->freqs.litlen[DEFLATE_END_OF_BLOCK]++;\n}\n\nstatic void\ndeflate_choose_all_literals(struct libdeflate_compressor *c,\n\t\t\t    const u8 *block, u32 block_length)\n{\n\tu32 i;\n\n\tdeflate_reset_symbol_frequencies(c);\n\tfor (i = 0; i < block_length; i++)\n\t\tc->freqs.litlen[block[i]]++;\n\tc->freqs.litlen[DEFLATE_END_OF_BLOCK]++;\n\n\tdeflate_make_huffman_codes(&c->freqs, &c->codes);\n}\n\n/*\n * Compute the exact cost, in bits, that would be required to output the matches\n * and literals described by @c->freqs as a dynamic Huffman block.  The litlen\n * and offset codes are assumed to have already been built in @c->codes.\n */\nstatic u32\ndeflate_compute_true_cost(struct libdeflate_compressor *c)\n{\n\tu32 cost = 0;\n\tunsigned sym;\n\n\tdeflate_precompute_huffman_header(c);\n\n\tmemset(&c->codes.lens.litlen[c->o.precode.num_litlen_syms], 0,\n\t       DEFLATE_NUM_LITLEN_SYMS - c->o.precode.num_litlen_syms);\n\n\tcost += 5 + 5 + 4 + (3 * c->o.precode.num_explicit_lens);\n\tfor (sym = 0; sym < DEFLATE_NUM_PRECODE_SYMS; sym++) {\n\t\tcost += c->o.precode.freqs[sym] *\n\t\t\t(c->o.precode.lens[sym] +\n\t\t\t deflate_extra_precode_bits[sym]);\n\t}\n\n\tfor (sym = 0; sym < DEFLATE_FIRST_LEN_SYM; sym++)\n\t\tcost += c->freqs.litlen[sym] * c->codes.lens.litlen[sym];\n\n\tfor (; sym < DEFLATE_FIRST_LEN_SYM +\n\t       ARRAY_LEN(deflate_extra_length_bits); sym++)\n\t\tcost += c->freqs.litlen[sym] *\n\t\t\t(c->codes.lens.litlen[sym] +\n\t\t\t deflate_extra_length_bits[sym - DEFLATE_FIRST_LEN_SYM]);\n\n\tfor (sym = 0; sym < ARRAY_LEN(deflate_extra_offset_bits); sym++)\n\t\tcost += c->freqs.offset[sym] *\n\t\t\t(c->codes.lens.offset[sym] +\n\t\t\t deflate_extra_offset_bits[sym]);\n\treturn cost;\n}\n\n/* Set the current cost model from the codeword lengths specified in @lens. */\nstatic void\ndeflate_set_costs_from_codes(struct libdeflate_compressor *c,\n\t\t\t     const struct deflate_lens *lens)\n{\n\tunsigned i;\n\n\t/* Literals */\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++) {\n\t\tu32 bits = (lens->litlen[i] ?\n\t\t\t    lens->litlen[i] : LITERAL_NOSTAT_BITS);\n\n\t\tc->p.n.costs.literal[i] = bits * BIT_COST;\n\t}\n\n\t/* Lengths */\n\tfor (i = DEFLATE_MIN_MATCH_LEN; i <= DEFLATE_MAX_MATCH_LEN; i++) {\n\t\tunsigned length_slot = deflate_length_slot[i];\n\t\tunsigned litlen_sym = DEFLATE_FIRST_LEN_SYM + length_slot;\n\t\tu32 bits = (lens->litlen[litlen_sym] ?\n\t\t\t    lens->litlen[litlen_sym] : LENGTH_NOSTAT_BITS);\n\n\t\tbits += deflate_extra_length_bits[length_slot];\n\t\tc->p.n.costs.length[i] = bits * BIT_COST;\n\t}\n\n\t/* Offset slots */\n\tfor (i = 0; i < ARRAY_LEN(deflate_offset_slot_base); i++) {\n\t\tu32 bits = (lens->offset[i] ?\n\t\t\t    lens->offset[i] : OFFSET_NOSTAT_BITS);\n\n\t\tbits += deflate_extra_offset_bits[i];\n\t\tc->p.n.costs.offset_slot[i] = bits * BIT_COST;\n\t}\n}\n\n/*\n * This lookup table gives the default cost of a literal symbol and of a length\n * symbol, depending on the characteristics of the input data.  It was generated\n * by scripts/gen_default_litlen_costs.py.\n *\n * This table is indexed first by the estimated match probability:\n *\n *\ti=0: data doesn't contain many matches\t[match_prob=0.25]\n *\ti=1: neutral\t\t\t\t[match_prob=0.50]\n *\ti=2: data contains lots of matches\t[match_prob=0.75]\n *\n * This lookup produces a subtable which maps the number of distinct used\n * literals to the default cost of a literal symbol, i.e.:\n *\n *\tint(-log2((1 - match_prob) / num_used_literals) * BIT_COST)\n *\n * ... for num_used_literals in [1, 256] (and 0, which is copied from 1).  This\n * accounts for literals usually getting cheaper as the number of distinct\n * literals decreases, and as the proportion of literals to matches increases.\n *\n * The lookup also produces the cost of a length symbol, which is:\n *\n *\tint(-log2(match_prob/NUM_LEN_SLOTS) * BIT_COST)\n *\n * Note: we don't currently assign different costs to different literal symbols,\n * or to different length symbols, as this is hard to do in a useful way.\n */\nstatic const struct {\n\tu8 used_lits_to_lit_cost[257];\n\tu8 len_sym_cost;\n} default_litlen_costs[] = {\n\t{ /* match_prob = 0.25 */\n\t\t.used_lits_to_lit_cost = {\n\t\t\t6, 6, 22, 32, 38, 43, 48, 51,\n\t\t\t54, 57, 59, 61, 64, 65, 67, 69,\n\t\t\t70, 72, 73, 74, 75, 76, 77, 79,\n\t\t\t80, 80, 81, 82, 83, 84, 85, 85,\n\t\t\t86, 87, 88, 88, 89, 89, 90, 91,\n\t\t\t91, 92, 92, 93, 93, 94, 95, 95,\n\t\t\t96, 96, 96, 97, 97, 98, 98, 99,\n\t\t\t99, 99, 100, 100, 101, 101, 101, 102,\n\t\t\t102, 102, 103, 103, 104, 104, 104, 105,\n\t\t\t105, 105, 105, 106, 106, 106, 107, 107,\n\t\t\t107, 108, 108, 108, 108, 109, 109, 109,\n\t\t\t109, 110, 110, 110, 111, 111, 111, 111,\n\t\t\t112, 112, 112, 112, 112, 113, 113, 113,\n\t\t\t113, 114, 114, 114, 114, 114, 115, 115,\n\t\t\t115, 115, 115, 116, 116, 116, 116, 116,\n\t\t\t117, 117, 117, 117, 117, 118, 118, 118,\n\t\t\t118, 118, 118, 119, 119, 119, 119, 119,\n\t\t\t120, 120, 120, 120, 120, 120, 121, 121,\n\t\t\t121, 121, 121, 121, 121, 122, 122, 122,\n\t\t\t122, 122, 122, 123, 123, 123, 123, 123,\n\t\t\t123, 123, 124, 124, 124, 124, 124, 124,\n\t\t\t124, 125, 125, 125, 125, 125, 125, 125,\n\t\t\t125, 126, 126, 126, 126, 126, 126, 126,\n\t\t\t127, 127, 127, 127, 127, 127, 127, 127,\n\t\t\t128, 128, 128, 128, 128, 128, 128, 128,\n\t\t\t128, 129, 129, 129, 129, 129, 129, 129,\n\t\t\t129, 129, 130, 130, 130, 130, 130, 130,\n\t\t\t130, 130, 130, 131, 131, 131, 131, 131,\n\t\t\t131, 131, 131, 131, 131, 132, 132, 132,\n\t\t\t132, 132, 132, 132, 132, 132, 132, 133,\n\t\t\t133, 133, 133, 133, 133, 133, 133, 133,\n\t\t\t133, 134, 134, 134, 134, 134, 134, 134,\n\t\t\t134,\n\t\t},\n\t\t.len_sym_cost = 109,\n\t}, { /* match_prob = 0.5 */\n\t\t.used_lits_to_lit_cost = {\n\t\t\t16, 16, 32, 41, 48, 53, 57, 60,\n\t\t\t64, 66, 69, 71, 73, 75, 76, 78,\n\t\t\t80, 81, 82, 83, 85, 86, 87, 88,\n\t\t\t89, 90, 91, 92, 92, 93, 94, 95,\n\t\t\t96, 96, 97, 98, 98, 99, 99, 100,\n\t\t\t101, 101, 102, 102, 103, 103, 104, 104,\n\t\t\t105, 105, 106, 106, 107, 107, 108, 108,\n\t\t\t108, 109, 109, 110, 110, 110, 111, 111,\n\t\t\t112, 112, 112, 113, 113, 113, 114, 114,\n\t\t\t114, 115, 115, 115, 115, 116, 116, 116,\n\t\t\t117, 117, 117, 118, 118, 118, 118, 119,\n\t\t\t119, 119, 119, 120, 120, 120, 120, 121,\n\t\t\t121, 121, 121, 122, 122, 122, 122, 122,\n\t\t\t123, 123, 123, 123, 124, 124, 124, 124,\n\t\t\t124, 125, 125, 125, 125, 125, 126, 126,\n\t\t\t126, 126, 126, 127, 127, 127, 127, 127,\n\t\t\t128, 128, 128, 128, 128, 128, 129, 129,\n\t\t\t129, 129, 129, 129, 130, 130, 130, 130,\n\t\t\t130, 130, 131, 131, 131, 131, 131, 131,\n\t\t\t131, 132, 132, 132, 132, 132, 132, 133,\n\t\t\t133, 133, 133, 133, 133, 133, 134, 134,\n\t\t\t134, 134, 134, 134, 134, 134, 135, 135,\n\t\t\t135, 135, 135, 135, 135, 135, 136, 136,\n\t\t\t136, 136, 136, 136, 136, 136, 137, 137,\n\t\t\t137, 137, 137, 137, 137, 137, 138, 138,\n\t\t\t138, 138, 138, 138, 138, 138, 138, 139,\n\t\t\t139, 139, 139, 139, 139, 139, 139, 139,\n\t\t\t140, 140, 140, 140, 140, 140, 140, 140,\n\t\t\t140, 141, 141, 141, 141, 141, 141, 141,\n\t\t\t141, 141, 141, 142, 142, 142, 142, 142,\n\t\t\t142, 142, 142, 142, 142, 142, 143, 143,\n\t\t\t143, 143, 143, 143, 143, 143, 143, 143,\n\t\t\t144,\n\t\t},\n\t\t.len_sym_cost = 93,\n\t}, { /* match_prob = 0.75 */\n\t\t.used_lits_to_lit_cost = {\n\t\t\t32, 32, 48, 57, 64, 69, 73, 76,\n\t\t\t80, 82, 85, 87, 89, 91, 92, 94,\n\t\t\t96, 97, 98, 99, 101, 102, 103, 104,\n\t\t\t105, 106, 107, 108, 108, 109, 110, 111,\n\t\t\t112, 112, 113, 114, 114, 115, 115, 116,\n\t\t\t117, 117, 118, 118, 119, 119, 120, 120,\n\t\t\t121, 121, 122, 122, 123, 123, 124, 124,\n\t\t\t124, 125, 125, 126, 126, 126, 127, 127,\n\t\t\t128, 128, 128, 129, 129, 129, 130, 130,\n\t\t\t130, 131, 131, 131, 131, 132, 132, 132,\n\t\t\t133, 133, 133, 134, 134, 134, 134, 135,\n\t\t\t135, 135, 135, 136, 136, 136, 136, 137,\n\t\t\t137, 137, 137, 138, 138, 138, 138, 138,\n\t\t\t139, 139, 139, 139, 140, 140, 140, 140,\n\t\t\t140, 141, 141, 141, 141, 141, 142, 142,\n\t\t\t142, 142, 142, 143, 143, 143, 143, 143,\n\t\t\t144, 144, 144, 144, 144, 144, 145, 145,\n\t\t\t145, 145, 145, 145, 146, 146, 146, 146,\n\t\t\t146, 146, 147, 147, 147, 147, 147, 147,\n\t\t\t147, 148, 148, 148, 148, 148, 148, 149,\n\t\t\t149, 149, 149, 149, 149, 149, 150, 150,\n\t\t\t150, 150, 150, 150, 150, 150, 151, 151,\n\t\t\t151, 151, 151, 151, 151, 151, 152, 152,\n\t\t\t152, 152, 152, 152, 152, 152, 153, 153,\n\t\t\t153, 153, 153, 153, 153, 153, 154, 154,\n\t\t\t154, 154, 154, 154, 154, 154, 154, 155,\n\t\t\t155, 155, 155, 155, 155, 155, 155, 155,\n\t\t\t156, 156, 156, 156, 156, 156, 156, 156,\n\t\t\t156, 157, 157, 157, 157, 157, 157, 157,\n\t\t\t157, 157, 157, 158, 158, 158, 158, 158,\n\t\t\t158, 158, 158, 158, 158, 158, 159, 159,\n\t\t\t159, 159, 159, 159, 159, 159, 159, 159,\n\t\t\t160,\n\t\t},\n\t\t.len_sym_cost = 84,\n\t},\n};\n\n/*\n * Choose the default costs for literal and length symbols.  These symbols are\n * both part of the litlen alphabet.\n */\nstatic void\ndeflate_choose_default_litlen_costs(struct libdeflate_compressor *c,\n\t\t\t\t    const u8 *block_begin, u32 block_length,\n\t\t\t\t    u32 *lit_cost, u32 *len_sym_cost)\n{\n\tu32 num_used_literals = 0;\n\tu32 literal_freq = block_length;\n\tu32 match_freq = 0;\n\tu32 cutoff;\n\tu32 i;\n\n\t/* Calculate the number of distinct literals that exist in the data. */\n\tmemset(c->freqs.litlen, 0,\n\t       DEFLATE_NUM_LITERALS * sizeof(c->freqs.litlen[0]));\n\tcutoff = literal_freq >> 11; /* Ignore literals used very rarely. */\n\tfor (i = 0; i < block_length; i++)\n\t\tc->freqs.litlen[block_begin[i]]++;\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++) {\n\t\tif (c->freqs.litlen[i] > cutoff)\n\t\t\tnum_used_literals++;\n\t}\n\tif (num_used_literals == 0)\n\t\tnum_used_literals = 1;\n\n\t/*\n\t * Estimate the relative frequency of literals and matches in the\n\t * optimal parsing solution.  We don't know the optimal solution, so\n\t * this can only be a very rough estimate.  Therefore, we basically use\n\t * the match frequency from a greedy parse.  We also apply the min_len\n\t * heuristic used by the greedy and lazy parsers, to avoid counting too\n\t * many matches when literals are cheaper than short matches.\n\t */\n\tmatch_freq = 0;\n\ti = choose_min_match_len(num_used_literals, c->max_search_depth);\n\tfor (; i < ARRAY_LEN(c->p.n.match_len_freqs); i++) {\n\t\tmatch_freq += c->p.n.match_len_freqs[i];\n\t\tliteral_freq -= i * c->p.n.match_len_freqs[i];\n\t}\n\tif ((s32)literal_freq < 0) /* shouldn't happen */\n\t\tliteral_freq = 0;\n\n\tif (match_freq > literal_freq)\n\t\ti = 2; /* many matches */\n\telse if (match_freq * 4 > literal_freq)\n\t\ti = 1; /* neutral */\n\telse\n\t\ti = 0; /* few matches */\n\n\tSTATIC_ASSERT(BIT_COST == 16);\n\t*lit_cost = default_litlen_costs[i].used_lits_to_lit_cost[\n\t\t\t\t\t\t\tnum_used_literals];\n\t*len_sym_cost = default_litlen_costs[i].len_sym_cost;\n}\n\nstatic forceinline u32\ndeflate_default_length_cost(u32 len, u32 len_sym_cost)\n{\n\tunsigned slot = deflate_length_slot[len];\n\tu32 num_extra_bits = deflate_extra_length_bits[slot];\n\n\treturn len_sym_cost + (num_extra_bits * BIT_COST);\n}\n\nstatic forceinline u32\ndeflate_default_offset_slot_cost(unsigned slot)\n{\n\tu32 num_extra_bits = deflate_extra_offset_bits[slot];\n\t/*\n\t * Assume that all offset symbols are equally probable.\n\t * The resulting cost is 'int(-log2(1/30) * BIT_COST)',\n\t * where 30 is the number of potentially-used offset symbols.\n\t */\n\tu32 offset_sym_cost = 4*BIT_COST + (907*BIT_COST)/1000;\n\n\treturn offset_sym_cost + (num_extra_bits * BIT_COST);\n}\n\n/* Set default symbol costs for the first block's first optimization pass. */\nstatic void\ndeflate_set_default_costs(struct libdeflate_compressor *c,\n\t\t\t  u32 lit_cost, u32 len_sym_cost)\n{\n\tu32 i;\n\n\t/* Literals */\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++)\n\t\tc->p.n.costs.literal[i] = lit_cost;\n\n\t/* Lengths */\n\tfor (i = DEFLATE_MIN_MATCH_LEN; i <= DEFLATE_MAX_MATCH_LEN; i++)\n\t\tc->p.n.costs.length[i] =\n\t\t\tdeflate_default_length_cost(i, len_sym_cost);\n\n\t/* Offset slots */\n\tfor (i = 0; i < ARRAY_LEN(deflate_offset_slot_base); i++)\n\t\tc->p.n.costs.offset_slot[i] =\n\t\t\tdeflate_default_offset_slot_cost(i);\n}\n\nstatic forceinline void\ndeflate_adjust_cost(u32 *cost_p, u32 default_cost, int change_amount)\n{\n\tif (change_amount == 0)\n\t\t/* Block is very similar to previous; prefer previous costs. */\n\t\t*cost_p = (default_cost + 3 * *cost_p) / 4;\n\telse if (change_amount == 1)\n\t\t*cost_p = (default_cost + *cost_p) / 2;\n\telse if (change_amount == 2)\n\t\t*cost_p = (5 * default_cost + 3 * *cost_p) / 8;\n\telse\n\t\t/* Block differs greatly from previous; prefer default costs. */\n\t\t*cost_p = (3 * default_cost + *cost_p) / 4;\n}\n\nstatic forceinline void\ndeflate_adjust_costs_impl(struct libdeflate_compressor *c,\n\t\t\t  u32 lit_cost, u32 len_sym_cost, int change_amount)\n{\n\tu32 i;\n\n\t/* Literals */\n\tfor (i = 0; i < DEFLATE_NUM_LITERALS; i++)\n\t\tdeflate_adjust_cost(&c->p.n.costs.literal[i], lit_cost,\n\t\t\t\t    change_amount);\n\n\t/* Lengths */\n\tfor (i = DEFLATE_MIN_MATCH_LEN; i <= DEFLATE_MAX_MATCH_LEN; i++)\n\t\tdeflate_adjust_cost(&c->p.n.costs.length[i],\n\t\t\t\t    deflate_default_length_cost(i,\n\t\t\t\t\t\t\t\tlen_sym_cost),\n\t\t\t\t    change_amount);\n\n\t/* Offset slots */\n\tfor (i = 0; i < ARRAY_LEN(deflate_offset_slot_base); i++)\n\t\tdeflate_adjust_cost(&c->p.n.costs.offset_slot[i],\n\t\t\t\t    deflate_default_offset_slot_cost(i),\n\t\t\t\t    change_amount);\n}\n\n/*\n * Adjust the costs when beginning a new block.\n *\n * Since the current costs are optimized for the data already, it can be helpful\n * to reuse them instead of starting over with the default costs.  However, this\n * depends on how similar the new block is to the previous block.  Therefore,\n * use a heuristic to decide how similar the blocks are, and mix together the\n * current costs and the default costs accordingly.\n */\nstatic void\ndeflate_adjust_costs(struct libdeflate_compressor *c,\n\t\t     u32 lit_cost, u32 len_sym_cost)\n{\n\tu64 total_delta = 0;\n\tu64 cutoff;\n\tint i;\n\n\t/*\n\t * Decide how different the current block is from the previous block,\n\t * using the block splitting statistics from the current and previous\n\t * blocks.  The more different the current block is, the more we prefer\n\t * the default costs rather than the previous block's costs.\n\t *\n\t * The algorithm here is similar to the end-of-block check one, but here\n\t * we compare two entire blocks rather than a partial block with a small\n\t * extra part, and therefore we need 64-bit numbers in some places.\n\t */\n\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++) {\n\t\tu64 prev = (u64)c->p.n.prev_observations[i] *\n\t\t\t    c->split_stats.num_observations;\n\t\tu64 cur = (u64)c->split_stats.observations[i] *\n\t\t\t  c->p.n.prev_num_observations;\n\n\t\ttotal_delta += prev > cur ? prev - cur : cur - prev;\n\t}\n\tcutoff = ((u64)c->p.n.prev_num_observations *\n\t\t  c->split_stats.num_observations * 200) / 512;\n\n\tif (total_delta > 3 * cutoff)\n\t\t/* Big change in the data; just use the default costs. */\n\t\tdeflate_set_default_costs(c, lit_cost, len_sym_cost);\n\telse if (4 * total_delta > 9 * cutoff)\n\t\tdeflate_adjust_costs_impl(c, lit_cost, len_sym_cost, 3);\n\telse if (2 * total_delta > 3 * cutoff)\n\t\tdeflate_adjust_costs_impl(c, lit_cost, len_sym_cost, 2);\n\telse if (2 * total_delta > cutoff)\n\t\tdeflate_adjust_costs_impl(c, lit_cost, len_sym_cost, 1);\n\telse\n\t\tdeflate_adjust_costs_impl(c, lit_cost, len_sym_cost, 0);\n}\n\nstatic void\ndeflate_set_initial_costs(struct libdeflate_compressor *c,\n\t\t\t  const u8 *block_begin, u32 block_length,\n\t\t\t  bool is_first_block)\n{\n\tu32 lit_cost, len_sym_cost;\n\n\tdeflate_choose_default_litlen_costs(c, block_begin, block_length,\n\t\t\t\t\t    &lit_cost, &len_sym_cost);\n\tif (is_first_block)\n\t\tdeflate_set_default_costs(c, lit_cost, len_sym_cost);\n\telse\n\t\tdeflate_adjust_costs(c, lit_cost, len_sym_cost);\n}\n\n/*\n * Find the minimum-cost path through the graph of possible match/literal\n * choices for this block.\n *\n * We find the minimum cost path from 'c->p.n.optimum_nodes[0]', which\n * represents the node at the beginning of the block, to\n * 'c->p.n.optimum_nodes[block_length]', which represents the node at the end of\n * the block.  Edge costs are evaluated using the cost model 'c->p.n.costs'.\n *\n * The algorithm works backwards, starting at the end node and proceeding\n * backwards one node at a time.  At each node, the minimum cost to reach the\n * end node is computed and the match/literal choice that begins that path is\n * saved.\n */\nstatic void\ndeflate_find_min_cost_path(struct libdeflate_compressor *c,\n\t\t\t   const u32 block_length,\n\t\t\t   const struct lz_match *cache_ptr)\n{\n\tstruct deflate_optimum_node *end_node =\n\t\t&c->p.n.optimum_nodes[block_length];\n\tstruct deflate_optimum_node *cur_node = end_node;\n\n\tcur_node->cost_to_end = 0;\n\tdo {\n\t\tunsigned num_matches;\n\t\tu32 literal;\n\t\tu32 best_cost_to_end;\n\n\t\tcur_node--;\n\t\tcache_ptr--;\n\n\t\tnum_matches = cache_ptr->length;\n\t\tliteral = cache_ptr->offset;\n\n\t\t/* It's always possible to choose a literal. */\n\t\tbest_cost_to_end = c->p.n.costs.literal[literal] +\n\t\t\t\t   (cur_node + 1)->cost_to_end;\n\t\tcur_node->item = (literal << OPTIMUM_OFFSET_SHIFT) | 1;\n\n\t\t/* Also consider matches if there are any. */\n\t\tif (num_matches) {\n\t\t\tconst struct lz_match *match;\n\t\t\tu32 len;\n\t\t\tu32 offset;\n\t\t\tu32 offset_slot;\n\t\t\tu32 offset_cost;\n\t\t\tu32 cost_to_end;\n\n\t\t\t/*\n\t\t\t * Consider each length from the minimum\n\t\t\t * (DEFLATE_MIN_MATCH_LEN) to the length of the longest\n\t\t\t * match found at this position.  For each length, we\n\t\t\t * consider only the smallest offset for which that\n\t\t\t * length is available.  Although this is not guaranteed\n\t\t\t * to be optimal due to the possibility of a larger\n\t\t\t * offset costing less than a smaller offset to code,\n\t\t\t * this is a very useful heuristic.\n\t\t\t */\n\t\t\tmatch = cache_ptr - num_matches;\n\t\t\tlen = DEFLATE_MIN_MATCH_LEN;\n\t\t\tdo {\n\t\t\t\toffset = match->offset;\n\t\t\t\toffset_slot = c->p.n.offset_slot_full[offset];\n\t\t\t\toffset_cost =\n\t\t\t\t\tc->p.n.costs.offset_slot[offset_slot];\n\t\t\t\tdo {\n\t\t\t\t\tcost_to_end = offset_cost +\n\t\t\t\t\t\tc->p.n.costs.length[len] +\n\t\t\t\t\t\t(cur_node + len)->cost_to_end;\n\t\t\t\t\tif (cost_to_end < best_cost_to_end) {\n\t\t\t\t\t\tbest_cost_to_end = cost_to_end;\n\t\t\t\t\t\tcur_node->item = len |\n\t\t\t\t\t\t\t(offset <<\n\t\t\t\t\t\t\t OPTIMUM_OFFSET_SHIFT);\n\t\t\t\t\t}\n\t\t\t\t} while (++len <= match->length);\n\t\t\t} while (++match != cache_ptr);\n\t\t\tcache_ptr -= num_matches;\n\t\t}\n\t\tcur_node->cost_to_end = best_cost_to_end;\n\t} while (cur_node != &c->p.n.optimum_nodes[0]);\n\n\tdeflate_reset_symbol_frequencies(c);\n\tdeflate_tally_item_list(c, block_length);\n\tdeflate_make_huffman_codes(&c->freqs, &c->codes);\n}\n\n/*\n * Choose the literals and matches for the current block, then output the block.\n *\n * To choose the literal/match sequence, we find the minimum-cost path through\n * the block's graph of literal/match choices, given a cost model.  However, the\n * true cost of each symbol is unknown until the Huffman codes have been built,\n * but at the same time the Huffman codes depend on the frequencies of chosen\n * symbols.  Consequently, multiple passes must be used to try to approximate an\n * optimal solution.  The first pass uses default costs, mixed with the costs\n * from the previous block when it seems appropriate.  Later passes use the\n * Huffman codeword lengths from the previous pass as the costs.\n *\n * As an alternate strategy, also consider using only literals.  The boolean\n * returned in *used_only_literals indicates whether that strategy was best.\n */\nstatic void\ndeflate_optimize_and_flush_block(struct libdeflate_compressor *c,\n\t\t\t\t struct deflate_output_bitstream *os,\n\t\t\t\t const u8 *block_begin, u32 block_length,\n\t\t\t\t const struct lz_match *cache_ptr,\n\t\t\t\t bool is_first_block, bool is_final_block,\n\t\t\t\t bool *used_only_literals)\n{\n\tunsigned num_passes_remaining = c->p.n.max_optim_passes;\n\tu32 best_true_cost = UINT32_MAX;\n\tu32 true_cost;\n\tu32 only_lits_cost;\n\tu32 static_cost = UINT32_MAX;\n\tstruct deflate_sequence seq_;\n\tstruct deflate_sequence *seq = NULL;\n\tu32 i;\n\n\t/*\n\t * On some data, using only literals (no matches) ends up being better\n\t * than what the iterative optimization algorithm produces.  Therefore,\n\t * consider using only literals.\n\t */\n\tdeflate_choose_all_literals(c, block_begin, block_length);\n\tonly_lits_cost = deflate_compute_true_cost(c);\n\n\t/*\n\t * Force the block to really end at the desired length, even if some\n\t * matches extend beyond it.\n\t */\n\tfor (i = block_length;\n\t     i <= MIN(block_length - 1 + DEFLATE_MAX_MATCH_LEN,\n\t\t      ARRAY_LEN(c->p.n.optimum_nodes) - 1); i++)\n\t\tc->p.n.optimum_nodes[i].cost_to_end = 0x80000000;\n\n\t/*\n\t * Sometimes a static Huffman block ends up being cheapest, particularly\n\t * if the block is small.  So, if the block is sufficiently small, find\n\t * the optimal static block solution and remember its cost.\n\t */\n\tif (block_length <= c->p.n.max_len_to_optimize_static_block) {\n\t\t/* Save c->p.n.costs temporarily. */\n\t\tc->p.n.costs_saved = c->p.n.costs;\n\n\t\tdeflate_set_costs_from_codes(c, &c->static_codes.lens);\n\t\tdeflate_find_min_cost_path(c, block_length, cache_ptr);\n\t\tstatic_cost = c->p.n.optimum_nodes[0].cost_to_end / BIT_COST;\n\t\tstatic_cost += 7; /* for the end-of-block symbol */\n\n\t\t/* Restore c->p.n.costs. */\n\t\tc->p.n.costs = c->p.n.costs_saved;\n\t}\n\n\t/* Initialize c->p.n.costs with default costs. */\n\tdeflate_set_initial_costs(c, block_begin, block_length, is_first_block);\n\n\tdo {\n\t\t/*\n\t\t * Find the minimum-cost path for this pass.\n\t\t * Also set c->freqs and c->codes to match the path.\n\t\t */\n\t\tdeflate_find_min_cost_path(c, block_length, cache_ptr);\n\n\t\t/*\n\t\t * Compute the exact cost of the block if the path were to be\n\t\t * used.  Note that this differs from\n\t\t * c->p.n.optimum_nodes[0].cost_to_end in that true_cost uses\n\t\t * the actual Huffman codes instead of c->p.n.costs.\n\t\t */\n\t\ttrue_cost = deflate_compute_true_cost(c);\n\n\t\t/*\n\t\t * If the cost didn't improve much from the previous pass, then\n\t\t * doing more passes probably won't be helpful, so stop early.\n\t\t */\n\t\tif (true_cost + c->p.n.min_improvement_to_continue >\n\t\t    best_true_cost)\n\t\t\tbreak;\n\n\t\tbest_true_cost = true_cost;\n\n\t\t/* Save the cost model that gave 'best_true_cost'. */\n\t\tc->p.n.costs_saved = c->p.n.costs;\n\n\t\t/* Update the cost model from the Huffman codes. */\n\t\tdeflate_set_costs_from_codes(c, &c->codes.lens);\n\n\t} while (--num_passes_remaining);\n\n\t*used_only_literals = false;\n\tif (MIN(only_lits_cost, static_cost) < best_true_cost) {\n\t\tif (only_lits_cost < static_cost) {\n\t\t\t/* Using only literals ended up being best! */\n\t\t\tdeflate_choose_all_literals(c, block_begin, block_length);\n\t\t\tdeflate_set_costs_from_codes(c, &c->codes.lens);\n\t\t\tseq_.litrunlen_and_length = block_length;\n\t\t\tseq = &seq_;\n\t\t\t*used_only_literals = true;\n\t\t} else {\n\t\t\t/* Static block ended up being best! */\n\t\t\tdeflate_set_costs_from_codes(c, &c->static_codes.lens);\n\t\t\tdeflate_find_min_cost_path(c, block_length, cache_ptr);\n\t\t}\n\t} else if (true_cost >=\n\t\t   best_true_cost + c->p.n.min_bits_to_use_nonfinal_path) {\n\t\t/*\n\t\t * The best solution was actually from a non-final optimization\n\t\t * pass, so recover and use the min-cost path from that pass.\n\t\t */\n\t\tc->p.n.costs = c->p.n.costs_saved;\n\t\tdeflate_find_min_cost_path(c, block_length, cache_ptr);\n\t\tdeflate_set_costs_from_codes(c, &c->codes.lens);\n\t}\n\tdeflate_flush_block(c, os, block_begin, block_length, seq,\n\t\t\t    is_final_block);\n}\n\nstatic void\ndeflate_near_optimal_init_stats(struct libdeflate_compressor *c)\n{\n\tinit_block_split_stats(&c->split_stats);\n\tmemset(c->p.n.new_match_len_freqs, 0,\n\t       sizeof(c->p.n.new_match_len_freqs));\n\tmemset(c->p.n.match_len_freqs, 0, sizeof(c->p.n.match_len_freqs));\n}\n\nstatic void\ndeflate_near_optimal_merge_stats(struct libdeflate_compressor *c)\n{\n\tunsigned i;\n\n\tmerge_new_observations(&c->split_stats);\n\tfor (i = 0; i < ARRAY_LEN(c->p.n.match_len_freqs); i++) {\n\t\tc->p.n.match_len_freqs[i] += c->p.n.new_match_len_freqs[i];\n\t\tc->p.n.new_match_len_freqs[i] = 0;\n\t}\n}\n\n/*\n * Save some literal/match statistics from the previous block so that\n * deflate_adjust_costs() will be able to decide how much the current block\n * differs from the previous one.\n */\nstatic void\ndeflate_near_optimal_save_stats(struct libdeflate_compressor *c)\n{\n\tint i;\n\n\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++)\n\t\tc->p.n.prev_observations[i] = c->split_stats.observations[i];\n\tc->p.n.prev_num_observations = c->split_stats.num_observations;\n}\n\nstatic void\ndeflate_near_optimal_clear_old_stats(struct libdeflate_compressor *c)\n{\n\tint i;\n\n\tfor (i = 0; i < NUM_OBSERVATION_TYPES; i++)\n\t\tc->split_stats.observations[i] = 0;\n\tc->split_stats.num_observations = 0;\n\tmemset(c->p.n.match_len_freqs, 0, sizeof(c->p.n.match_len_freqs));\n}\n\n/*\n * This is the \"near-optimal\" DEFLATE compressor.  It computes the optimal\n * representation of each DEFLATE block using a minimum-cost path search over\n * the graph of possible match/literal choices for that block, assuming a\n * certain cost for each Huffman symbol.\n *\n * For several reasons, the end result is not guaranteed to be optimal:\n *\n * - Nonoptimal choice of blocks\n * - Heuristic limitations on which matches are actually considered\n * - Symbol costs are unknown until the symbols have already been chosen\n *   (so iterative optimization must be used)\n */\nstatic void\ndeflate_compress_near_optimal(struct libdeflate_compressor * restrict c,\n\t\t\t      const u8 *in, size_t in_nbytes,\n\t\t\t      struct deflate_output_bitstream *os)\n{\n\tconst u8 *in_next = in;\n\tconst u8 *in_block_begin = in_next;\n\tconst u8 *in_end = in_next + in_nbytes;\n\tconst u8 *in_cur_base = in_next;\n\tconst u8 *in_next_slide =\n\t\tin_next + MIN(in_end - in_next, MATCHFINDER_WINDOW_SIZE);\n\tu32 max_len = DEFLATE_MAX_MATCH_LEN;\n\tu32 nice_len = MIN(c->nice_match_length, max_len);\n\tstruct lz_match *cache_ptr = c->p.n.match_cache;\n\tu32 next_hashes[2] = {0, 0};\n\tbool prev_block_used_only_literals = false;\n\n\tbt_matchfinder_init(&c->p.n.bt_mf);\n\tdeflate_near_optimal_init_stats(c);\n\n\tdo {\n\t\t/* Starting a new DEFLATE block */\n\t\tconst u8 * const in_max_block_end = choose_max_block_end(\n\t\t\t\tin_block_begin, in_end, SOFT_MAX_BLOCK_LENGTH);\n\t\tconst u8 *prev_end_block_check = NULL;\n\t\tbool change_detected = false;\n\t\tconst u8 *next_observation = in_next;\n\t\tu32 min_len;\n\n\t\t/*\n\t\t * Use the minimum match length heuristic to improve the\n\t\t * literal/match statistics gathered during matchfinding.\n\t\t * However, the actual near-optimal parse won't respect min_len,\n\t\t * as it can accurately assess the costs of different matches.\n\t\t *\n\t\t * If the \"use only literals\" strategy happened to be the best\n\t\t * strategy on the previous block, then probably the\n\t\t * min_match_len heuristic is still not aggressive enough for\n\t\t * the data, so force gathering literal stats only.\n\t\t */\n\t\tif (prev_block_used_only_literals)\n\t\t\tmin_len = DEFLATE_MAX_MATCH_LEN + 1;\n\t\telse\n\t\t\tmin_len = calculate_min_match_len(\n\t\t\t\t\tin_block_begin,\n\t\t\t\t\tin_max_block_end - in_block_begin,\n\t\t\t\t\tc->max_search_depth);\n\n\t\t/*\n\t\t * Find matches until we decide to end the block.  We end the\n\t\t * block if any of the following is true:\n\t\t *\n\t\t * (1) Maximum block length has been reached\n\t\t * (2) Match catch may overflow.\n\t\t * (3) Block split heuristic says to split now.\n\t\t */\n\t\tfor (;;) {\n\t\t\tstruct lz_match *matches;\n\t\t\tu32 best_len;\n\t\t\tsize_t remaining = in_end - in_next;\n\n\t\t\t/* Slide the window forward if needed. */\n\t\t\tif (in_next == in_next_slide) {\n\t\t\t\tbt_matchfinder_slide_window(&c->p.n.bt_mf);\n\t\t\t\tin_cur_base = in_next;\n\t\t\t\tin_next_slide = in_next +\n\t\t\t\t\tMIN(remaining, MATCHFINDER_WINDOW_SIZE);\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Find matches with the current position using the\n\t\t\t * binary tree matchfinder and save them in match_cache.\n\t\t\t *\n\t\t\t * Note: the binary tree matchfinder is more suited for\n\t\t\t * optimal parsing than the hash chain matchfinder.  The\n\t\t\t * reasons for this include:\n\t\t\t *\n\t\t\t * - The binary tree matchfinder can find more matches\n\t\t\t *   in the same number of steps.\n\t\t\t * - One of the major advantages of hash chains is that\n\t\t\t *   skipping positions (not searching for matches at\n\t\t\t *   them) is faster; however, with optimal parsing we\n\t\t\t *   search for matches at almost all positions, so this\n\t\t\t *   advantage of hash chains is negated.\n\t\t\t */\n\t\t\tmatches = cache_ptr;\n\t\t\tbest_len = 0;\n\t\t\tadjust_max_and_nice_len(&max_len, &nice_len, remaining);\n\t\t\tif (likely(max_len >= BT_MATCHFINDER_REQUIRED_NBYTES)) {\n\t\t\t\tcache_ptr = bt_matchfinder_get_matches(\n\t\t\t\t\t\t&c->p.n.bt_mf,\n\t\t\t\t\t\tin_cur_base,\n\t\t\t\t\t\tin_next - in_cur_base,\n\t\t\t\t\t\tmax_len,\n\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\tc->max_search_depth,\n\t\t\t\t\t\tnext_hashes,\n\t\t\t\t\t\tmatches);\n\t\t\t\tif (cache_ptr > matches)\n\t\t\t\t\tbest_len = cache_ptr[-1].length;\n\t\t\t}\n\t\t\tif (in_next >= next_observation) {\n\t\t\t\tif (best_len >= min_len) {\n\t\t\t\t\tobserve_match(&c->split_stats,\n\t\t\t\t\t\t      best_len);\n\t\t\t\t\tnext_observation = in_next + best_len;\n\t\t\t\t\tc->p.n.new_match_len_freqs[best_len]++;\n\t\t\t\t} else {\n\t\t\t\t\tobserve_literal(&c->split_stats,\n\t\t\t\t\t\t\t*in_next);\n\t\t\t\t\tnext_observation = in_next + 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcache_ptr->length = cache_ptr - matches;\n\t\t\tcache_ptr->offset = *in_next;\n\t\t\tin_next++;\n\t\t\tcache_ptr++;\n\n\t\t\t/*\n\t\t\t * If there was a very long match found, don't cache any\n\t\t\t * matches for the bytes covered by that match.  This\n\t\t\t * avoids degenerate behavior when compressing highly\n\t\t\t * redundant data, where the number of matches can be\n\t\t\t * very large.\n\t\t\t *\n\t\t\t * This heuristic doesn't actually hurt the compression\n\t\t\t * ratio very much.  If there's a long match, then the\n\t\t\t * data must be highly compressible, so it doesn't\n\t\t\t * matter much what we do.\n\t\t\t */\n\t\t\tif (best_len >= DEFLATE_MIN_MATCH_LEN &&\n\t\t\t    best_len >= nice_len) {\n\t\t\t\t--best_len;\n\t\t\t\tdo {\n\t\t\t\t\tremaining = in_end - in_next;\n\t\t\t\t\tif (in_next == in_next_slide) {\n\t\t\t\t\t\tbt_matchfinder_slide_window(\n\t\t\t\t\t\t\t&c->p.n.bt_mf);\n\t\t\t\t\t\tin_cur_base = in_next;\n\t\t\t\t\t\tin_next_slide = in_next +\n\t\t\t\t\t\t\tMIN(remaining,\n\t\t\t\t\t\t\t    MATCHFINDER_WINDOW_SIZE);\n\t\t\t\t\t}\n\t\t\t\t\tadjust_max_and_nice_len(&max_len,\n\t\t\t\t\t\t\t\t&nice_len,\n\t\t\t\t\t\t\t\tremaining);\n\t\t\t\t\tif (max_len >=\n\t\t\t\t\t    BT_MATCHFINDER_REQUIRED_NBYTES) {\n\t\t\t\t\t\tbt_matchfinder_skip_byte(\n\t\t\t\t\t\t\t&c->p.n.bt_mf,\n\t\t\t\t\t\t\tin_cur_base,\n\t\t\t\t\t\t\tin_next - in_cur_base,\n\t\t\t\t\t\t\tnice_len,\n\t\t\t\t\t\t\tc->max_search_depth,\n\t\t\t\t\t\t\tnext_hashes);\n\t\t\t\t\t}\n\t\t\t\t\tcache_ptr->length = 0;\n\t\t\t\t\tcache_ptr->offset = *in_next;\n\t\t\t\t\tin_next++;\n\t\t\t\t\tcache_ptr++;\n\t\t\t\t} while (--best_len);\n\t\t\t}\n\t\t\t/* Maximum block length or end of input reached? */\n\t\t\tif (in_next >= in_max_block_end)\n\t\t\t\tbreak;\n\t\t\t/* Match cache overflowed? */\n\t\t\tif (cache_ptr >=\n\t\t\t    &c->p.n.match_cache[MATCH_CACHE_LENGTH])\n\t\t\t\tbreak;\n\t\t\t/* Not ready to try to end the block (again)? */\n\t\t\tif (!ready_to_check_block(&c->split_stats,\n\t\t\t\t\t\t  in_block_begin, in_next,\n\t\t\t\t\t\t  in_end))\n\t\t\t\tcontinue;\n\t\t\t/* Check if it would be worthwhile to end the block. */\n\t\t\tif (do_end_block_check(&c->split_stats,\n\t\t\t\t\t       in_next - in_block_begin)) {\n\t\t\t\tchange_detected = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* Ending the block doesn't seem worthwhile here. */\n\t\t\tdeflate_near_optimal_merge_stats(c);\n\t\t\tprev_end_block_check = in_next;\n\t\t}\n\t\t/*\n\t\t * All the matches for this block have been cached.  Now choose\n\t\t * the precise end of the block and the sequence of items to\n\t\t * output to represent it, then flush the block.\n\t\t */\n\t\tif (change_detected && prev_end_block_check != NULL) {\n\t\t\t/*\n\t\t\t * The block is being ended because a recent chunk of\n\t\t\t * data differs from the rest of the block.  We could\n\t\t\t * end the block at 'in_next' like the greedy and lazy\n\t\t\t * compressors do, but that's not ideal since it would\n\t\t\t * include the differing chunk in the block.  The\n\t\t\t * near-optimal compressor has time to do a better job.\n\t\t\t * Therefore, we rewind to just before the chunk, and\n\t\t\t * output a block that only goes up to there.\n\t\t\t *\n\t\t\t * We then set things up to correctly start the next\n\t\t\t * block, considering that some work has already been\n\t\t\t * done on it (some matches found and stats gathered).\n\t\t\t */\n\t\t\tstruct lz_match *orig_cache_ptr = cache_ptr;\n\t\t\tconst u8 *in_block_end = prev_end_block_check;\n\t\t\tu32 block_length = in_block_end - in_block_begin;\n\t\t\tbool is_first = (in_block_begin == in);\n\t\t\tbool is_final = false;\n\t\t\tu32 num_bytes_to_rewind = in_next - in_block_end;\n\t\t\tsize_t cache_len_rewound;\n\n\t\t\t/* Rewind the match cache. */\n\t\t\tdo {\n\t\t\t\tcache_ptr--;\n\t\t\t\tcache_ptr -= cache_ptr->length;\n\t\t\t} while (--num_bytes_to_rewind);\n\t\t\tcache_len_rewound = orig_cache_ptr - cache_ptr;\n\n\t\t\tdeflate_optimize_and_flush_block(\n\t\t\t\t\t\tc, os, in_block_begin,\n\t\t\t\t\t\tblock_length, cache_ptr,\n\t\t\t\t\t\tis_first, is_final,\n\t\t\t\t\t\t&prev_block_used_only_literals);\n\t\t\tmemmove(c->p.n.match_cache, cache_ptr,\n\t\t\t\tcache_len_rewound * sizeof(*cache_ptr));\n\t\t\tcache_ptr = &c->p.n.match_cache[cache_len_rewound];\n\t\t\tdeflate_near_optimal_save_stats(c);\n\t\t\t/*\n\t\t\t * Clear the stats for the just-flushed block, leaving\n\t\t\t * just the stats for the beginning of the next block.\n\t\t\t */\n\t\t\tdeflate_near_optimal_clear_old_stats(c);\n\t\t\tin_block_begin = in_block_end;\n\t\t} else {\n\t\t\t/*\n\t\t\t * The block is being ended for a reason other than a\n\t\t\t * differing data chunk being detected.  Don't rewind at\n\t\t\t * all; just end the block at the current position.\n\t\t\t */\n\t\t\tu32 block_length = in_next - in_block_begin;\n\t\t\tbool is_first = (in_block_begin == in);\n\t\t\tbool is_final = (in_next == in_end);\n\n\t\t\tdeflate_near_optimal_merge_stats(c);\n\t\t\tdeflate_optimize_and_flush_block(\n\t\t\t\t\t\tc, os, in_block_begin,\n\t\t\t\t\t\tblock_length, cache_ptr,\n\t\t\t\t\t\tis_first, is_final,\n\t\t\t\t\t\t&prev_block_used_only_literals);\n\t\t\tcache_ptr = &c->p.n.match_cache[0];\n\t\t\tdeflate_near_optimal_save_stats(c);\n\t\t\tdeflate_near_optimal_init_stats(c);\n\t\t\tin_block_begin = in_next;\n\t\t}\n\t} while (in_next != in_end && !os->overflow);\n}\n\n/* Initialize c->p.n.offset_slot_full. */\nstatic void\ndeflate_init_offset_slot_full(struct libdeflate_compressor *c)\n{\n\tu32 offset_slot;\n\tu32 offset;\n\tu32 offset_end;\n\n\tfor (offset_slot = 0; offset_slot < ARRAY_LEN(deflate_offset_slot_base);\n\t     offset_slot++) {\n\t\toffset = deflate_offset_slot_base[offset_slot];\n\t\toffset_end = offset +\n\t\t\t     (1 << deflate_extra_offset_bits[offset_slot]);\n\t\tdo {\n\t\t\tc->p.n.offset_slot_full[offset] = offset_slot;\n\t\t} while (++offset != offset_end);\n\t}\n}\n\n#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\nLIBDEFLATEAPI struct libdeflate_compressor *\nlibdeflate_alloc_compressor_ex(int compression_level,\n\t\t\t       const struct libdeflate_options *options)\n{\n\tstruct libdeflate_compressor *c;\n\tsize_t size = offsetof(struct libdeflate_compressor, p);\n\n\tcheck_buildtime_parameters();\n\n\t/*\n\t * Note: if more fields are added to libdeflate_options, this code will\n\t * need to be updated to support both the old and new structs.\n\t */\n\tif (options->sizeof_options != sizeof(*options))\n\t\treturn NULL;\n\n\tif (compression_level < 0 || compression_level > 12)\n\t\treturn NULL;\n\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\tif (compression_level >= 10)\n\t\tsize += sizeof(c->p.n);\n\telse\n#endif\n\t{\n\t\tif (compression_level >= 2)\n\t\t\tsize += sizeof(c->p.g);\n\t\telse if (compression_level == 1)\n\t\t\tsize += sizeof(c->p.f);\n\t}\n\n\tc = libdeflate_aligned_malloc(options->malloc_func ?\n\t\t\t\t      options->malloc_func :\n\t\t\t\t      libdeflate_default_malloc_func,\n\t\t\t\t      MATCHFINDER_MEM_ALIGNMENT, size);\n\tif (!c)\n\t\treturn NULL;\n\tc->free_func = options->free_func ?\n\t\t       options->free_func : libdeflate_default_free_func;\n\n\tc->compression_level = compression_level;\n\n\t/*\n\t * The higher the compression level, the more we should bother trying to\n\t * compress very small inputs.\n\t */\n\tc->max_passthrough_size = 55 - (compression_level * 4);\n\n\tswitch (compression_level) {\n\tcase 0:\n\t\tc->max_passthrough_size = SIZE_MAX;\n\t\tc->impl = NULL; /* not used */\n\t\tbreak;\n\tcase 1:\n\t\tc->impl = deflate_compress_fastest;\n\t\t/* max_search_depth is unused. */\n\t\tc->nice_match_length = 32;\n\t\tbreak;\n\tcase 2:\n\t\tc->impl = deflate_compress_greedy;\n\t\tc->max_search_depth = 6;\n\t\tc->nice_match_length = 10;\n\t\tbreak;\n\tcase 3:\n\t\tc->impl = deflate_compress_greedy;\n\t\tc->max_search_depth = 12;\n\t\tc->nice_match_length = 14;\n\t\tbreak;\n\tcase 4:\n\t\tc->impl = deflate_compress_greedy;\n\t\tc->max_search_depth = 16;\n\t\tc->nice_match_length = 30;\n\t\tbreak;\n\tcase 5:\n\t\tc->impl = deflate_compress_lazy;\n\t\tc->max_search_depth = 16;\n\t\tc->nice_match_length = 30;\n\t\tbreak;\n\tcase 6:\n\t\tc->impl = deflate_compress_lazy;\n\t\tc->max_search_depth = 35;\n\t\tc->nice_match_length = 65;\n\t\tbreak;\n\tcase 7:\n\t\tc->impl = deflate_compress_lazy;\n\t\tc->max_search_depth = 100;\n\t\tc->nice_match_length = 130;\n\t\tbreak;\n\tcase 8:\n\t\tc->impl = deflate_compress_lazy2;\n\t\tc->max_search_depth = 300;\n\t\tc->nice_match_length = DEFLATE_MAX_MATCH_LEN;\n\t\tbreak;\n\tcase 9:\n#if !SUPPORT_NEAR_OPTIMAL_PARSING\n\tdefault:\n#endif\n\t\tc->impl = deflate_compress_lazy2;\n\t\tc->max_search_depth = 600;\n\t\tc->nice_match_length = DEFLATE_MAX_MATCH_LEN;\n\t\tbreak;\n#if SUPPORT_NEAR_OPTIMAL_PARSING\n\tcase 10:\n\t\tc->impl = deflate_compress_near_optimal;\n\t\tc->max_search_depth = 35;\n\t\tc->nice_match_length = 75;\n\t\tc->p.n.max_optim_passes = 2;\n\t\tc->p.n.min_improvement_to_continue = 32;\n\t\tc->p.n.min_bits_to_use_nonfinal_path = 32;\n\t\tc->p.n.max_len_to_optimize_static_block = 0;\n\t\tdeflate_init_offset_slot_full(c);\n\t\tbreak;\n\tcase 11:\n\t\tc->impl = deflate_compress_near_optimal;\n\t\tc->max_search_depth = 100;\n\t\tc->nice_match_length = 150;\n\t\tc->p.n.max_optim_passes = 4;\n\t\tc->p.n.min_improvement_to_continue = 16;\n\t\tc->p.n.min_bits_to_use_nonfinal_path = 16;\n\t\tc->p.n.max_len_to_optimize_static_block = 1000;\n\t\tdeflate_init_offset_slot_full(c);\n\t\tbreak;\n\tcase 12:\n\tdefault:\n\t\tc->impl = deflate_compress_near_optimal;\n\t\tc->max_search_depth = 300;\n\t\tc->nice_match_length = DEFLATE_MAX_MATCH_LEN;\n\t\tc->p.n.max_optim_passes = 10;\n\t\tc->p.n.min_improvement_to_continue = 1;\n\t\tc->p.n.min_bits_to_use_nonfinal_path = 1;\n\t\tc->p.n.max_len_to_optimize_static_block = 10000;\n\t\tdeflate_init_offset_slot_full(c);\n\t\tbreak;\n#endif /* SUPPORT_NEAR_OPTIMAL_PARSING */\n\t}\n\n\tdeflate_init_static_codes(c);\n\n\treturn c;\n}\n\n\nLIBDEFLATEAPI struct libdeflate_compressor *\nlibdeflate_alloc_compressor(int compression_level)\n{\n\tstatic const struct libdeflate_options defaults = {\n\t\t.sizeof_options = sizeof(defaults),\n\t};\n\treturn libdeflate_alloc_compressor_ex(compression_level, &defaults);\n}\n\nLIBDEFLATEAPI size_t\nlibdeflate_deflate_compress(struct libdeflate_compressor *c,\n\t\t\t    const void *in, size_t in_nbytes,\n\t\t\t    void *out, size_t out_nbytes_avail)\n{\n\tstruct deflate_output_bitstream os;\n\n\t/*\n\t * For extremely short inputs, or for compression level 0, just output\n\t * uncompressed blocks.\n\t */\n\tif (unlikely(in_nbytes <= c->max_passthrough_size))\n\t\treturn deflate_compress_none(in, in_nbytes,\n\t\t\t\t\t     out, out_nbytes_avail);\n\n\t/* Initialize the output bitstream structure. */\n\tos.bitbuf = 0;\n\tos.bitcount = 0;\n\tos.next = out;\n\tos.end = os.next + out_nbytes_avail;\n\tos.overflow = false;\n\n\t/* Call the actual compression function. */\n\t(*c->impl)(c, in, in_nbytes, &os);\n\n\t/* Return 0 if the output buffer is too small. */\n\tif (os.overflow)\n\t\treturn 0;\n\n\t/*\n\t * Write the final byte if needed.  This can't overflow the output\n\t * buffer because deflate_flush_block() would have set the overflow flag\n\t * if there wasn't enough space remaining for the full final block.\n\t */\n\tASSERT(os.bitcount <= 7);\n\tif (os.bitcount) {\n\t\tASSERT(os.next < os.end);\n\t\t*os.next++ = os.bitbuf;\n\t}\n\n\t/* Return the compressed size in bytes. */\n\treturn os.next - (u8 *)out;\n}\n\nLIBDEFLATEAPI void\nlibdeflate_free_compressor(struct libdeflate_compressor *c)\n{\n\tif (c)\n\t\tlibdeflate_aligned_free(c->free_func, c);\n}\n\nunsigned int\nlibdeflate_get_compression_level(struct libdeflate_compressor *c)\n{\n\treturn c->compression_level;\n}\n\nLIBDEFLATEAPI size_t\nlibdeflate_deflate_compress_bound(struct libdeflate_compressor *c,\n\t\t\t\t  size_t in_nbytes)\n{\n\tsize_t max_blocks;\n\n\t/*\n\t * Since the compressor never uses a compressed block when an\n\t * uncompressed block is cheaper, the worst case can be no worse than\n\t * the case where only uncompressed blocks are used.\n\t *\n\t * This is true even though up to 7 bits are \"wasted\" to byte-align the\n\t * bitstream when a compressed block is followed by an uncompressed\n\t * block.  This is because a compressed block wouldn't have been used if\n\t * it wasn't cheaper than an uncompressed block, and uncompressed blocks\n\t * always end on a byte boundary.  So the alignment bits will, at worst,\n\t * go up to the place where the uncompressed block would have ended.\n\t */\n\n\t/*\n\t * Calculate the maximum number of uncompressed blocks that the\n\t * compressor can use for 'in_nbytes' of data.\n\t *\n\t * The minimum length that is passed to deflate_flush_block() is\n\t * MIN_BLOCK_LENGTH bytes, except for the final block if needed.  If\n\t * deflate_flush_block() decides to use an uncompressed block, it\n\t * actually will (in general) output a series of uncompressed blocks in\n\t * order to stay within the UINT16_MAX limit of DEFLATE.  But this can\n\t * be disregarded here as long as '2 * MIN_BLOCK_LENGTH <= UINT16_MAX',\n\t * as in that case this behavior can't result in more blocks than the\n\t * case where deflate_flush_block() is called with min-length inputs.\n\t *\n\t * So the number of uncompressed blocks needed would be bounded by\n\t * DIV_ROUND_UP(in_nbytes, MIN_BLOCK_LENGTH).  However, empty inputs\n\t * need 1 (empty) block, which gives the final expression below.\n\t */\n\tSTATIC_ASSERT(2 * MIN_BLOCK_LENGTH <= UINT16_MAX);\n\tmax_blocks = MAX(DIV_ROUND_UP(in_nbytes, MIN_BLOCK_LENGTH), 1);\n\n\t/*\n\t * Each uncompressed block has 5 bytes of overhead, for the BFINAL,\n\t * BTYPE, LEN, and NLEN fields.  (For the reason explained earlier, the\n\t * alignment bits at the very start of the block can be disregarded;\n\t * they would otherwise increase the overhead to 6 bytes per block.)\n\t * Therefore, the maximum number of overhead bytes is '5 * max_blocks'.\n\t * To get the final bound, add the number of uncompressed bytes.\n\t */\n\treturn (5 * max_blocks) + in_nbytes;\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/deflate_compress.h",
    "content": "#ifndef LIB_DEFLATE_COMPRESS_H\n#define LIB_DEFLATE_COMPRESS_H\n\n#include \"lib_common.h\"\n\n/*\n * DEFLATE compression is private to deflate_compress.c, but we do need to be\n * able to query the compression level for zlib and gzip header generation.\n */\n\nstruct libdeflate_compressor;\n\nunsigned int libdeflate_get_compression_level(struct libdeflate_compressor *c);\n\n#endif /* LIB_DEFLATE_COMPRESS_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/deflate_constants.h",
    "content": "/*\n * deflate_constants.h - constants for the DEFLATE compression format\n */\n\n#ifndef LIB_DEFLATE_CONSTANTS_H\n#define LIB_DEFLATE_CONSTANTS_H\n\n/* Valid block types  */\n#define DEFLATE_BLOCKTYPE_UNCOMPRESSED\t\t0\n#define DEFLATE_BLOCKTYPE_STATIC_HUFFMAN\t1\n#define DEFLATE_BLOCKTYPE_DYNAMIC_HUFFMAN\t2\n\n/* Minimum and maximum supported match lengths (in bytes)  */\n#define DEFLATE_MIN_MATCH_LEN\t\t\t3\n#define DEFLATE_MAX_MATCH_LEN\t\t\t258\n\n/* Maximum supported match offset (in bytes) */\n#define DEFLATE_MAX_MATCH_OFFSET\t\t32768\n\n/* log2 of DEFLATE_MAX_MATCH_OFFSET */\n#define DEFLATE_WINDOW_ORDER\t\t\t15\n\n/* Number of symbols in each Huffman code.  Note: for the literal/length\n * and offset codes, these are actually the maximum values; a given block\n * might use fewer symbols.  */\n#define DEFLATE_NUM_PRECODE_SYMS\t\t19\n#define DEFLATE_NUM_LITLEN_SYMS\t\t\t288\n#define DEFLATE_NUM_OFFSET_SYMS\t\t\t32\n\n/* The maximum number of symbols across all codes  */\n#define DEFLATE_MAX_NUM_SYMS\t\t\t288\n\n/* Division of symbols in the literal/length code  */\n#define DEFLATE_NUM_LITERALS\t\t\t256\n#define DEFLATE_END_OF_BLOCK\t\t\t256\n#define DEFLATE_FIRST_LEN_SYM\t\t\t257\n\n/* Maximum codeword length, in bits, within each Huffman code  */\n#define DEFLATE_MAX_PRE_CODEWORD_LEN\t\t7\n#define DEFLATE_MAX_LITLEN_CODEWORD_LEN\t\t15\n#define DEFLATE_MAX_OFFSET_CODEWORD_LEN\t\t15\n\n/* The maximum codeword length across all codes  */\n#define DEFLATE_MAX_CODEWORD_LEN\t\t15\n\n/* Maximum possible overrun when decoding codeword lengths  */\n#define DEFLATE_MAX_LENS_OVERRUN\t\t137\n\n/*\n * Maximum number of extra bits that may be required to represent a match\n * length or offset.\n */\n#define DEFLATE_MAX_EXTRA_LENGTH_BITS\t\t5\n#define DEFLATE_MAX_EXTRA_OFFSET_BITS\t\t13\n\n#endif /* LIB_DEFLATE_CONSTANTS_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/deflate_decompress.c",
    "content": "/*\n * deflate_decompress.c - a decompressor for DEFLATE\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * ---------------------------------------------------------------------------\n *\n * This is a highly optimized DEFLATE decompressor.  It is much faster than\n * vanilla zlib, typically well over twice as fast, though results vary by CPU.\n *\n * Why this is faster than vanilla zlib:\n *\n * - Word accesses rather than byte accesses when reading input\n * - Word accesses rather than byte accesses when copying matches\n * - Faster Huffman decoding combined with various DEFLATE-specific tricks\n * - Larger bitbuffer variable that doesn't need to be refilled as often\n * - Other optimizations to remove unnecessary branches\n * - Only full-buffer decompression is supported, so the code doesn't need to\n *   support stopping and resuming decompression.\n * - On x86_64, a version of the decompression routine is compiled with BMI2\n *   instructions enabled and is used automatically at runtime when supported.\n */\n\n#include \"lib_common.h\"\n#include \"deflate_constants.h\"\n\n/*\n * If the expression passed to SAFETY_CHECK() evaluates to false, then the\n * decompression routine immediately returns LIBDEFLATE_BAD_DATA, indicating the\n * compressed data is invalid.\n *\n * Theoretically, these checks could be disabled for specialized applications\n * where all input to the decompressor will be trusted.\n */\n#if 0\n#  pragma message(\"UNSAFE DECOMPRESSION IS ENABLED. THIS MUST ONLY BE USED IF THE DECOMPRESSOR INPUT WILL ALWAYS BE TRUSTED!\")\n#  define SAFETY_CHECK(expr)\t(void)(expr)\n#else\n#  define SAFETY_CHECK(expr)\tif (unlikely(!(expr))) return LIBDEFLATE_BAD_DATA\n#endif\n\n/*****************************************************************************\n *\t\t\t\tInput bitstream                              *\n *****************************************************************************/\n\n/*\n * The state of the \"input bitstream\" consists of the following variables:\n *\n *\t- in_next: a pointer to the next unread byte in the input buffer\n *\n *\t- in_end: a pointer to just past the end of the input buffer\n *\n *\t- bitbuf: a word-sized variable containing bits that have been read from\n *\t\t  the input buffer or from the implicit appended zero bytes\n *\n *\t- bitsleft: the number of bits in 'bitbuf' available to be consumed.\n *\t\t    After REFILL_BITS_BRANCHLESS(), 'bitbuf' can actually\n *\t\t    contain more bits than this.  However, only the bits counted\n *\t\t    by 'bitsleft' can actually be consumed; the rest can only be\n *\t\t    used for preloading.\n *\n *\t\t    As a micro-optimization, we allow bits 8 and higher of\n *\t\t    'bitsleft' to contain garbage.  When consuming the bits\n *\t\t    associated with a decode table entry, this allows us to do\n *\t\t    'bitsleft -= entry' instead of 'bitsleft -= (u8)entry'.\n *\t\t    On some CPUs, this helps reduce instruction dependencies.\n *\t\t    This does have the disadvantage that 'bitsleft' sometimes\n *\t\t    needs to be cast to 'u8', such as when it's used as a shift\n *\t\t    amount in REFILL_BITS_BRANCHLESS().  But that one happens\n *\t\t    for free since most CPUs ignore high bits in shift amounts.\n *\n *\t- overread_count: the total number of implicit appended zero bytes that\n *\t\t\t  have been loaded into the bitbuffer, including any\n *\t\t\t  counted by 'bitsleft' and any already consumed\n */\n\n/*\n * The type for the bitbuffer variable ('bitbuf' described above).  For best\n * performance, this should have size equal to a machine word.\n *\n * 64-bit platforms have a significant advantage: they get a bigger bitbuffer\n * which they don't have to refill as often.\n */\ntypedef machine_word_t bitbuf_t;\n#define BITBUF_NBITS\t(8 * (int)sizeof(bitbuf_t))\n\n/* BITMASK(n) returns a bitmask of length 'n'. */\n#define BITMASK(n)\t(((bitbuf_t)1 << (n)) - 1)\n\n/*\n * MAX_BITSLEFT is the maximum number of consumable bits, i.e. the maximum value\n * of '(u8)bitsleft'.  This is the size of the bitbuffer variable, minus 1 if\n * the branchless refill method is being used (see REFILL_BITS_BRANCHLESS()).\n */\n#define MAX_BITSLEFT\t\\\n\t(UNALIGNED_ACCESS_IS_FAST ? BITBUF_NBITS - 1 : BITBUF_NBITS)\n\n/*\n * CONSUMABLE_NBITS is the minimum number of bits that are guaranteed to be\n * consumable (counted in 'bitsleft') immediately after refilling the bitbuffer.\n * Since only whole bytes can be added to 'bitsleft', the worst case is\n * 'MAX_BITSLEFT - 7': the smallest amount where another byte doesn't fit.\n */\n#define CONSUMABLE_NBITS\t(MAX_BITSLEFT - 7)\n\n/*\n * FASTLOOP_PRELOADABLE_NBITS is the minimum number of bits that are guaranteed\n * to be preloadable immediately after REFILL_BITS_IN_FASTLOOP().  (It is *not*\n * guaranteed after REFILL_BITS(), since REFILL_BITS() falls back to a\n * byte-at-a-time refill method near the end of input.)  This may exceed the\n * number of consumable bits (counted by 'bitsleft').  Any bits not counted in\n * 'bitsleft' can only be used for precomputation and cannot be consumed.\n */\n#define FASTLOOP_PRELOADABLE_NBITS\t\\\n\t(UNALIGNED_ACCESS_IS_FAST ? BITBUF_NBITS : CONSUMABLE_NBITS)\n\n/*\n * PRELOAD_SLACK is the minimum number of bits that are guaranteed to be\n * preloadable but not consumable, following REFILL_BITS_IN_FASTLOOP() and any\n * subsequent consumptions.  This is 1 bit if the branchless refill method is\n * being used, and 0 bits otherwise.\n */\n#define PRELOAD_SLACK\tMAX(0, FASTLOOP_PRELOADABLE_NBITS - MAX_BITSLEFT)\n\n/*\n * CAN_CONSUME(n) is true if it's guaranteed that if the bitbuffer has just been\n * refilled, then it's always possible to consume 'n' bits from it.  'n' should\n * be a compile-time constant, to enable compile-time evaluation.\n */\n#define CAN_CONSUME(n)\t(CONSUMABLE_NBITS >= (n))\n\n/*\n * CAN_CONSUME_AND_THEN_PRELOAD(consume_nbits, preload_nbits) is true if it's\n * guaranteed that after REFILL_BITS_IN_FASTLOOP(), it's always possible to\n * consume 'consume_nbits' bits, then preload 'preload_nbits' bits.  The\n * arguments should be compile-time constants to enable compile-time evaluation.\n */\n#define CAN_CONSUME_AND_THEN_PRELOAD(consume_nbits, preload_nbits)\t\\\n\t(CONSUMABLE_NBITS >= (consume_nbits) &&\t\t\t\t\\\n\t FASTLOOP_PRELOADABLE_NBITS >= (consume_nbits) + (preload_nbits))\n\n/*\n * REFILL_BITS_BRANCHLESS() branchlessly refills the bitbuffer variable by\n * reading the next word from the input buffer and updating 'in_next' and\n * 'bitsleft' based on how many bits were refilled -- counting whole bytes only.\n * This is much faster than reading a byte at a time, at least if the CPU is\n * little endian and supports fast unaligned memory accesses.\n *\n * The simplest way of branchlessly updating 'bitsleft' would be:\n *\n *\tbitsleft += (MAX_BITSLEFT - bitsleft) & ~7;\n *\n * To make it faster, we define MAX_BITSLEFT to be 'WORDBITS - 1' rather than\n * WORDBITS, so that in binary it looks like 111111 or 11111.  Then, we update\n * 'bitsleft' by just setting the bits above the low 3 bits:\n *\n *\tbitsleft |= MAX_BITSLEFT & ~7;\n *\n * That compiles down to a single instruction like 'or $0x38, %rbp'.  Using\n * 'MAX_BITSLEFT == WORDBITS - 1' also has the advantage that refills can be\n * done when 'bitsleft == MAX_BITSLEFT' without invoking undefined behavior.\n *\n * The simplest way of branchlessly updating 'in_next' would be:\n *\n *\tin_next += (MAX_BITSLEFT - bitsleft) >> 3;\n *\n * With 'MAX_BITSLEFT == WORDBITS - 1' we could use an XOR instead, though this\n * isn't really better:\n *\n *\tin_next += (MAX_BITSLEFT ^ bitsleft) >> 3;\n *\n * An alternative which can be marginally better is the following:\n *\n *\tin_next += sizeof(bitbuf_t) - 1;\n *\tin_next -= (bitsleft >> 3) & 0x7;\n *\n * It seems this would increase the number of CPU instructions from 3 (sub, shr,\n * add) to 4 (add, shr, and, sub).  However, if the CPU has a bitfield\n * extraction instruction (e.g. arm's ubfx), it stays at 3, and is potentially\n * more efficient because the length of the longest dependency chain decreases\n * from 3 to 2.  This alternative also has the advantage that it ignores the\n * high bits in 'bitsleft', so it is compatible with the micro-optimization we\n * use where we let the high bits of 'bitsleft' contain garbage.\n */\n#define REFILL_BITS_BRANCHLESS()\t\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tbitbuf |= get_unaligned_leword(in_next) << (u8)bitsleft;\t\\\n\tin_next += sizeof(bitbuf_t) - 1;\t\t\t\t\\\n\tin_next -= (bitsleft >> 3) & 0x7;\t\t\t\t\\\n\tbitsleft |= MAX_BITSLEFT & ~7;\t\t\t\t\t\\\n} while (0)\n\n/*\n * REFILL_BITS() loads bits from the input buffer until the bitbuffer variable\n * contains at least CONSUMABLE_NBITS consumable bits.\n *\n * This checks for the end of input, and it doesn't guarantee\n * FASTLOOP_PRELOADABLE_NBITS, so it can't be used in the fastloop.\n *\n * If we would overread the input buffer, we just don't read anything, leaving\n * the bits zeroed but marking them filled.  This simplifies the decompressor\n * because it removes the need to always be able to distinguish between real\n * overreads and overreads caused only by the decompressor's own lookahead.\n *\n * We do still keep track of the number of bytes that have been overread, for\n * two reasons.  First, it allows us to determine the exact number of bytes that\n * were consumed once the stream ends or an uncompressed block is reached.\n * Second, it allows us to stop early if the overread amount gets so large (more\n * than sizeof bitbuf) that it can only be caused by a real overread.  (The\n * second part is arguably unneeded, since libdeflate is buffer-based; given\n * infinite zeroes, it will eventually either completely fill the output buffer\n * or return an error.  However, we do it to be slightly more friendly to the\n * not-recommended use case of decompressing with an unknown output size.)\n */\n#define REFILL_BITS()\t\t\t\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tif (UNALIGNED_ACCESS_IS_FAST &&\t\t\t\t\t\\\n\t    likely(in_end - in_next >= sizeof(bitbuf_t))) {\t\t\\\n\t\tREFILL_BITS_BRANCHLESS();\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\twhile ((u8)bitsleft < CONSUMABLE_NBITS) {\t\t\\\n\t\t\tif (likely(in_next != in_end)) {\t\t\\\n\t\t\t\tbitbuf |= (bitbuf_t)*in_next++ <<\t\\\n\t\t\t\t\t  (u8)bitsleft;\t\t\t\\\n\t\t\t} else {\t\t\t\t\t\\\n\t\t\t\toverread_count++;\t\t\t\\\n\t\t\t\tSAFETY_CHECK(overread_count <=\t\t\\\n\t\t\t\t\t     sizeof(bitbuf_t));\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t\tbitsleft += 8;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * REFILL_BITS_IN_FASTLOOP() is like REFILL_BITS(), but it doesn't check for the\n * end of the input.  It can only be used in the fastloop.\n */\n#define REFILL_BITS_IN_FASTLOOP()\t\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\tSTATIC_ASSERT(UNALIGNED_ACCESS_IS_FAST ||\t\t\t\\\n\t\t      FASTLOOP_PRELOADABLE_NBITS == CONSUMABLE_NBITS);\t\\\n\tif (UNALIGNED_ACCESS_IS_FAST) {\t\t\t\t\t\\\n\t\tREFILL_BITS_BRANCHLESS();\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\\\n\t\twhile ((u8)bitsleft < CONSUMABLE_NBITS) {\t\t\\\n\t\t\tbitbuf |= (bitbuf_t)*in_next++ << (u8)bitsleft;\t\\\n\t\t\tbitsleft += 8;\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * This is the worst-case maximum number of output bytes that are written to\n * during each iteration of the fastloop.  The worst case is 2 literals, then a\n * match of length DEFLATE_MAX_MATCH_LEN.  Additionally, some slack space must\n * be included for the intentional overrun in the match copy implementation.\n */\n#define FASTLOOP_MAX_BYTES_WRITTEN\t\\\n\t(2 + DEFLATE_MAX_MATCH_LEN + (5 * WORDBYTES) - 1)\n\n/*\n * This is the worst-case maximum number of input bytes that are read during\n * each iteration of the fastloop.  To get this value, we first compute the\n * greatest number of bits that can be refilled during a loop iteration.  The\n * refill at the beginning can add at most MAX_BITSLEFT, and the amount that can\n * be refilled later is no more than the maximum amount that can be consumed by\n * 2 literals that don't need a subtable, then a match.  We convert this value\n * to bytes, rounding up; this gives the maximum number of bytes that 'in_next'\n * can be advanced.  Finally, we add sizeof(bitbuf_t) to account for\n * REFILL_BITS_BRANCHLESS() reading a word past 'in_next'.\n */\n#define FASTLOOP_MAX_BYTES_READ\t\t\t\t\t\\\n\t(DIV_ROUND_UP(MAX_BITSLEFT + (2 * LITLEN_TABLEBITS) +\t\\\n\t\t      LENGTH_MAXBITS + OFFSET_MAXBITS, 8) +\t\\\n\t sizeof(bitbuf_t))\n\n/*****************************************************************************\n *                              Huffman decoding                             *\n *****************************************************************************/\n\n/*\n * The fastest way to decode Huffman-encoded data is basically to use a decode\n * table that maps the next TABLEBITS bits of data to their symbol.  Each entry\n * decode_table[i] maps to the symbol whose codeword is a prefix of 'i'.  A\n * symbol with codeword length 'n' has '2**(TABLEBITS-n)' entries in the table.\n *\n * Ideally, TABLEBITS and the maximum codeword length would be the same; some\n * compression formats are designed with this goal in mind.  Unfortunately, in\n * DEFLATE, the maximum litlen and offset codeword lengths are 15 bits, which is\n * too large for a practical TABLEBITS.  It's not *that* much larger, though, so\n * the workaround is to use a single level of subtables.  In the main table,\n * entries for prefixes of codewords longer than TABLEBITS contain a \"pointer\"\n * to the appropriate subtable along with the number of bits it is indexed with.\n *\n * The most efficient way to allocate subtables is to allocate them dynamically\n * after the main table.  The worst-case number of table entries needed,\n * including subtables, is precomputable; see the ENOUGH constants below.\n *\n * A useful optimization is to store the codeword lengths in the decode table so\n * that they don't have to be looked up by indexing a separate table that maps\n * symbols to their codeword lengths.  We basically do this; however, for the\n * litlen and offset codes we also implement some DEFLATE-specific optimizations\n * that build in the consideration of the \"extra bits\" and the\n * literal/length/end-of-block division.  For the exact decode table entry\n * format we use, see the definitions of the *_decode_results[] arrays below.\n */\n\n\n/*\n * These are the TABLEBITS values we use for each of the DEFLATE Huffman codes,\n * along with their corresponding ENOUGH values.\n *\n * For the precode, we use PRECODE_TABLEBITS == 7 since this is the maximum\n * precode codeword length.  This avoids ever needing subtables.\n *\n * For the litlen and offset codes, we cannot realistically avoid ever needing\n * subtables, since litlen and offset codewords can be up to 15 bits.  A higher\n * TABLEBITS reduces the number of lookups that need a subtable, which increases\n * performance; however, it increases memory usage and makes building the table\n * take longer, which decreases performance.  We choose values that work well in\n * practice, making subtables rarely needed without making the tables too large.\n *\n * Our choice of OFFSET_TABLEBITS == 8 is a bit low; without any special\n * considerations, 9 would fit the trade-off curve better.  However, there is a\n * performance benefit to using exactly 8 bits when it is a compile-time\n * constant, as many CPUs can take the low byte more easily than the low 9 bits.\n *\n * zlib treats its equivalents of TABLEBITS as maximum values; whenever it\n * builds a table, it caps the actual table_bits to the longest codeword.  This\n * makes sense in theory, as there's no need for the table to be any larger than\n * needed to support the longest codeword.  However, having the table bits be a\n * compile-time constant is beneficial to the performance of the decode loop, so\n * there is a trade-off.  libdeflate currently uses the dynamic table_bits\n * strategy for the litlen table only, due to its larger maximum size.\n * PRECODE_TABLEBITS and OFFSET_TABLEBITS are smaller, so going dynamic there\n * isn't as useful, and OFFSET_TABLEBITS=8 is useful as mentioned above.\n *\n * Each TABLEBITS value has a corresponding ENOUGH value that gives the\n * worst-case maximum number of decode table entries, including the main table\n * and all subtables.  The ENOUGH value depends on three parameters:\n *\n *\t(1) the maximum number of symbols in the code (DEFLATE_NUM_*_SYMS)\n *\t(2) the maximum number of main table bits (*_TABLEBITS)\n *\t(3) the maximum allowed codeword length (DEFLATE_MAX_*_CODEWORD_LEN)\n *\n * The ENOUGH values were computed using the utility program 'enough' from zlib.\n */\n#define PRECODE_TABLEBITS\t7\n#define PRECODE_ENOUGH\t\t128\t/* enough 19 7 7\t*/\n#define LITLEN_TABLEBITS\t11\n#define LITLEN_ENOUGH\t\t2342\t/* enough 288 11 15\t*/\n#define OFFSET_TABLEBITS\t8\n#define OFFSET_ENOUGH\t\t402\t/* enough 32 8 15\t*/\n\n/*\n * make_decode_table_entry() creates a decode table entry for the given symbol\n * by combining the static part 'decode_results[sym]' with the dynamic part\n * 'len', which is the remaining codeword length (the codeword length for main\n * table entries, or the codeword length minus TABLEBITS for subtable entries).\n *\n * In all cases, we add 'len' to each of the two low-order bytes to create the\n * appropriately-formatted decode table entry.  See the definitions of the\n * *_decode_results[] arrays below, where the entry format is described.\n */\nstatic forceinline u32\nmake_decode_table_entry(const u32 decode_results[], u32 sym, u32 len)\n{\n\treturn decode_results[sym] + (len << 8) + len;\n}\n\n/*\n * Here is the format of our precode decode table entries.  Bits not explicitly\n * described contain zeroes:\n *\n *\tBit 20-16:  presym\n *\tBit 10-8:   codeword length [not used]\n *\tBit 2-0:    codeword length\n *\n * The precode decode table never has subtables, since we use\n * PRECODE_TABLEBITS == DEFLATE_MAX_PRE_CODEWORD_LEN.\n *\n * precode_decode_results[] contains the static part of the entry for each\n * symbol.  make_decode_table_entry() produces the final entries.\n */\nstatic const u32 precode_decode_results[] = {\n#define ENTRY(presym)\t((u32)presym << 16)\n\tENTRY(0)   , ENTRY(1)   , ENTRY(2)   , ENTRY(3)   ,\n\tENTRY(4)   , ENTRY(5)   , ENTRY(6)   , ENTRY(7)   ,\n\tENTRY(8)   , ENTRY(9)   , ENTRY(10)  , ENTRY(11)  ,\n\tENTRY(12)  , ENTRY(13)  , ENTRY(14)  , ENTRY(15)  ,\n\tENTRY(16)  , ENTRY(17)  , ENTRY(18)  ,\n#undef ENTRY\n};\n\n/* Litlen and offset decode table entry flags */\n\n/* Indicates a literal entry in the litlen decode table */\n#define HUFFDEC_LITERAL\t\t\t0x80000000\n\n/* Indicates that HUFFDEC_SUBTABLE_POINTER or HUFFDEC_END_OF_BLOCK is set */\n#define HUFFDEC_EXCEPTIONAL\t\t0x00008000\n\n/* Indicates a subtable pointer entry in the litlen or offset decode table */\n#define HUFFDEC_SUBTABLE_POINTER\t0x00004000\n\n/* Indicates an end-of-block entry in the litlen decode table */\n#define HUFFDEC_END_OF_BLOCK\t\t0x00002000\n\n/* Maximum number of bits that can be consumed by decoding a match length */\n#define LENGTH_MAXBITS\t\t(DEFLATE_MAX_LITLEN_CODEWORD_LEN + \\\n\t\t\t\t DEFLATE_MAX_EXTRA_LENGTH_BITS)\n#define LENGTH_MAXFASTBITS\t(LITLEN_TABLEBITS /* no subtable needed */ + \\\n\t\t\t\t DEFLATE_MAX_EXTRA_LENGTH_BITS)\n\n/*\n * Here is the format of our litlen decode table entries.  Bits not explicitly\n * described contain zeroes:\n *\n *\tLiterals:\n *\t\tBit 31:     1 (HUFFDEC_LITERAL)\n *\t\tBit 23-16:  literal value\n *\t\tBit 15:     0 (!HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     0 (!HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 13:     0 (!HUFFDEC_END_OF_BLOCK)\n *\t\tBit 11-8:   remaining codeword length [not used]\n *\t\tBit 3-0:    remaining codeword length\n *\tLengths:\n *\t\tBit 31:     0 (!HUFFDEC_LITERAL)\n *\t\tBit 24-16:  length base value\n *\t\tBit 15:     0 (!HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     0 (!HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 13:     0 (!HUFFDEC_END_OF_BLOCK)\n *\t\tBit 11-8:   remaining codeword length\n *\t\tBit 4-0:    remaining codeword length + number of extra bits\n *\tEnd of block:\n *\t\tBit 31:     0 (!HUFFDEC_LITERAL)\n *\t\tBit 15:     1 (HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     0 (!HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 13:     1 (HUFFDEC_END_OF_BLOCK)\n *\t\tBit 11-8:   remaining codeword length [not used]\n *\t\tBit 3-0:    remaining codeword length\n *\tSubtable pointer:\n *\t\tBit 31:     0 (!HUFFDEC_LITERAL)\n *\t\tBit 30-16:  index of start of subtable\n *\t\tBit 15:     1 (HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     1 (HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 13:     0 (!HUFFDEC_END_OF_BLOCK)\n *\t\tBit 11-8:   number of subtable bits\n *\t\tBit 3-0:    number of main table bits\n *\n * This format has several desirable properties:\n *\n *\t- The codeword length, length slot base, and number of extra length bits\n *\t  are all built in.  This eliminates the need to separately look up this\n *\t  information by indexing separate arrays by symbol or length slot.\n *\n *\t- The HUFFDEC_* flags enable easily distinguishing between the different\n *\t  types of entries.  The HUFFDEC_LITERAL flag enables a fast path for\n *\t  literals; the high bit is used for this, as some CPUs can test the\n *\t  high bit more easily than other bits.  The HUFFDEC_EXCEPTIONAL flag\n *\t  makes it possible to detect the two unlikely cases (subtable pointer\n *\t  and end of block) in a single bit flag test.\n *\n *\t- The low byte is the number of bits that need to be removed from the\n *\t  bitstream; this makes this value easily accessible, and it enables the\n *\t  micro-optimization of doing 'bitsleft -= entry' instead of\n *\t  'bitsleft -= (u8)entry'.  It also includes the number of extra bits,\n *\t  so they don't need to be removed separately.\n *\n *\t- The flags in bits 15-13 are arranged to be 0 when the\n *\t  \"remaining codeword length\" in bits 11-8 is needed, making this value\n *\t  fairly easily accessible as well via a shift and downcast.\n *\n *\t- Similarly, bits 13-12 are 0 when the \"subtable bits\" in bits 11-8 are\n *\t  needed, making it possible to extract this value with '& 0x3F' rather\n *\t  than '& 0xF'.  This value is only used as a shift amount, so this can\n *\t  save an 'and' instruction as the masking by 0x3F happens implicitly.\n *\n * litlen_decode_results[] contains the static part of the entry for each\n * symbol.  make_decode_table_entry() produces the final entries.\n */\nstatic const u32 litlen_decode_results[] = {\n\n\t/* Literals */\n#define ENTRY(literal)\t(HUFFDEC_LITERAL | ((u32)literal << 16))\n\tENTRY(0)   , ENTRY(1)   , ENTRY(2)   , ENTRY(3)   ,\n\tENTRY(4)   , ENTRY(5)   , ENTRY(6)   , ENTRY(7)   ,\n\tENTRY(8)   , ENTRY(9)   , ENTRY(10)  , ENTRY(11)  ,\n\tENTRY(12)  , ENTRY(13)  , ENTRY(14)  , ENTRY(15)  ,\n\tENTRY(16)  , ENTRY(17)  , ENTRY(18)  , ENTRY(19)  ,\n\tENTRY(20)  , ENTRY(21)  , ENTRY(22)  , ENTRY(23)  ,\n\tENTRY(24)  , ENTRY(25)  , ENTRY(26)  , ENTRY(27)  ,\n\tENTRY(28)  , ENTRY(29)  , ENTRY(30)  , ENTRY(31)  ,\n\tENTRY(32)  , ENTRY(33)  , ENTRY(34)  , ENTRY(35)  ,\n\tENTRY(36)  , ENTRY(37)  , ENTRY(38)  , ENTRY(39)  ,\n\tENTRY(40)  , ENTRY(41)  , ENTRY(42)  , ENTRY(43)  ,\n\tENTRY(44)  , ENTRY(45)  , ENTRY(46)  , ENTRY(47)  ,\n\tENTRY(48)  , ENTRY(49)  , ENTRY(50)  , ENTRY(51)  ,\n\tENTRY(52)  , ENTRY(53)  , ENTRY(54)  , ENTRY(55)  ,\n\tENTRY(56)  , ENTRY(57)  , ENTRY(58)  , ENTRY(59)  ,\n\tENTRY(60)  , ENTRY(61)  , ENTRY(62)  , ENTRY(63)  ,\n\tENTRY(64)  , ENTRY(65)  , ENTRY(66)  , ENTRY(67)  ,\n\tENTRY(68)  , ENTRY(69)  , ENTRY(70)  , ENTRY(71)  ,\n\tENTRY(72)  , ENTRY(73)  , ENTRY(74)  , ENTRY(75)  ,\n\tENTRY(76)  , ENTRY(77)  , ENTRY(78)  , ENTRY(79)  ,\n\tENTRY(80)  , ENTRY(81)  , ENTRY(82)  , ENTRY(83)  ,\n\tENTRY(84)  , ENTRY(85)  , ENTRY(86)  , ENTRY(87)  ,\n\tENTRY(88)  , ENTRY(89)  , ENTRY(90)  , ENTRY(91)  ,\n\tENTRY(92)  , ENTRY(93)  , ENTRY(94)  , ENTRY(95)  ,\n\tENTRY(96)  , ENTRY(97)  , ENTRY(98)  , ENTRY(99)  ,\n\tENTRY(100) , ENTRY(101) , ENTRY(102) , ENTRY(103) ,\n\tENTRY(104) , ENTRY(105) , ENTRY(106) , ENTRY(107) ,\n\tENTRY(108) , ENTRY(109) , ENTRY(110) , ENTRY(111) ,\n\tENTRY(112) , ENTRY(113) , ENTRY(114) , ENTRY(115) ,\n\tENTRY(116) , ENTRY(117) , ENTRY(118) , ENTRY(119) ,\n\tENTRY(120) , ENTRY(121) , ENTRY(122) , ENTRY(123) ,\n\tENTRY(124) , ENTRY(125) , ENTRY(126) , ENTRY(127) ,\n\tENTRY(128) , ENTRY(129) , ENTRY(130) , ENTRY(131) ,\n\tENTRY(132) , ENTRY(133) , ENTRY(134) , ENTRY(135) ,\n\tENTRY(136) , ENTRY(137) , ENTRY(138) , ENTRY(139) ,\n\tENTRY(140) , ENTRY(141) , ENTRY(142) , ENTRY(143) ,\n\tENTRY(144) , ENTRY(145) , ENTRY(146) , ENTRY(147) ,\n\tENTRY(148) , ENTRY(149) , ENTRY(150) , ENTRY(151) ,\n\tENTRY(152) , ENTRY(153) , ENTRY(154) , ENTRY(155) ,\n\tENTRY(156) , ENTRY(157) , ENTRY(158) , ENTRY(159) ,\n\tENTRY(160) , ENTRY(161) , ENTRY(162) , ENTRY(163) ,\n\tENTRY(164) , ENTRY(165) , ENTRY(166) , ENTRY(167) ,\n\tENTRY(168) , ENTRY(169) , ENTRY(170) , ENTRY(171) ,\n\tENTRY(172) , ENTRY(173) , ENTRY(174) , ENTRY(175) ,\n\tENTRY(176) , ENTRY(177) , ENTRY(178) , ENTRY(179) ,\n\tENTRY(180) , ENTRY(181) , ENTRY(182) , ENTRY(183) ,\n\tENTRY(184) , ENTRY(185) , ENTRY(186) , ENTRY(187) ,\n\tENTRY(188) , ENTRY(189) , ENTRY(190) , ENTRY(191) ,\n\tENTRY(192) , ENTRY(193) , ENTRY(194) , ENTRY(195) ,\n\tENTRY(196) , ENTRY(197) , ENTRY(198) , ENTRY(199) ,\n\tENTRY(200) , ENTRY(201) , ENTRY(202) , ENTRY(203) ,\n\tENTRY(204) , ENTRY(205) , ENTRY(206) , ENTRY(207) ,\n\tENTRY(208) , ENTRY(209) , ENTRY(210) , ENTRY(211) ,\n\tENTRY(212) , ENTRY(213) , ENTRY(214) , ENTRY(215) ,\n\tENTRY(216) , ENTRY(217) , ENTRY(218) , ENTRY(219) ,\n\tENTRY(220) , ENTRY(221) , ENTRY(222) , ENTRY(223) ,\n\tENTRY(224) , ENTRY(225) , ENTRY(226) , ENTRY(227) ,\n\tENTRY(228) , ENTRY(229) , ENTRY(230) , ENTRY(231) ,\n\tENTRY(232) , ENTRY(233) , ENTRY(234) , ENTRY(235) ,\n\tENTRY(236) , ENTRY(237) , ENTRY(238) , ENTRY(239) ,\n\tENTRY(240) , ENTRY(241) , ENTRY(242) , ENTRY(243) ,\n\tENTRY(244) , ENTRY(245) , ENTRY(246) , ENTRY(247) ,\n\tENTRY(248) , ENTRY(249) , ENTRY(250) , ENTRY(251) ,\n\tENTRY(252) , ENTRY(253) , ENTRY(254) , ENTRY(255) ,\n#undef ENTRY\n\n\t/* End of block */\n\tHUFFDEC_EXCEPTIONAL | HUFFDEC_END_OF_BLOCK,\n\n\t/* Lengths */\n#define ENTRY(length_base, num_extra_bits)\t\\\n\t(((u32)(length_base) << 16) | (num_extra_bits))\n\tENTRY(3  , 0) , ENTRY(4  , 0) , ENTRY(5  , 0) , ENTRY(6  , 0),\n\tENTRY(7  , 0) , ENTRY(8  , 0) , ENTRY(9  , 0) , ENTRY(10 , 0),\n\tENTRY(11 , 1) , ENTRY(13 , 1) , ENTRY(15 , 1) , ENTRY(17 , 1),\n\tENTRY(19 , 2) , ENTRY(23 , 2) , ENTRY(27 , 2) , ENTRY(31 , 2),\n\tENTRY(35 , 3) , ENTRY(43 , 3) , ENTRY(51 , 3) , ENTRY(59 , 3),\n\tENTRY(67 , 4) , ENTRY(83 , 4) , ENTRY(99 , 4) , ENTRY(115, 4),\n\tENTRY(131, 5) , ENTRY(163, 5) , ENTRY(195, 5) , ENTRY(227, 5),\n\tENTRY(258, 0) , ENTRY(258, 0) , ENTRY(258, 0) ,\n#undef ENTRY\n};\n\n/* Maximum number of bits that can be consumed by decoding a match offset */\n#define OFFSET_MAXBITS\t\t(DEFLATE_MAX_OFFSET_CODEWORD_LEN + \\\n\t\t\t\t DEFLATE_MAX_EXTRA_OFFSET_BITS)\n#define OFFSET_MAXFASTBITS\t(OFFSET_TABLEBITS /* no subtable needed */ + \\\n\t\t\t\t DEFLATE_MAX_EXTRA_OFFSET_BITS)\n\n/*\n * Here is the format of our offset decode table entries.  Bits not explicitly\n * described contain zeroes:\n *\n *\tOffsets:\n *\t\tBit 31-16:  offset base value\n *\t\tBit 15:     0 (!HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     0 (!HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 11-8:   remaining codeword length\n *\t\tBit 4-0:    remaining codeword length + number of extra bits\n *\tSubtable pointer:\n *\t\tBit 31-16:  index of start of subtable\n *\t\tBit 15:     1 (HUFFDEC_EXCEPTIONAL)\n *\t\tBit 14:     1 (HUFFDEC_SUBTABLE_POINTER)\n *\t\tBit 11-8:   number of subtable bits\n *\t\tBit 3-0:    number of main table bits\n *\n * These work the same way as the length entries and subtable pointer entries in\n * the litlen decode table; see litlen_decode_results[] above.\n */\nstatic const u32 offset_decode_results[] = {\n#define ENTRY(offset_base, num_extra_bits)\t\\\n\t(((u32)(offset_base) << 16) | (num_extra_bits))\n\tENTRY(1     , 0)  , ENTRY(2     , 0)  , ENTRY(3     , 0)  , ENTRY(4     , 0)  ,\n\tENTRY(5     , 1)  , ENTRY(7     , 1)  , ENTRY(9     , 2)  , ENTRY(13    , 2) ,\n\tENTRY(17    , 3)  , ENTRY(25    , 3)  , ENTRY(33    , 4)  , ENTRY(49    , 4)  ,\n\tENTRY(65    , 5)  , ENTRY(97    , 5)  , ENTRY(129   , 6)  , ENTRY(193   , 6)  ,\n\tENTRY(257   , 7)  , ENTRY(385   , 7)  , ENTRY(513   , 8)  , ENTRY(769   , 8)  ,\n\tENTRY(1025  , 9)  , ENTRY(1537  , 9)  , ENTRY(2049  , 10) , ENTRY(3073  , 10) ,\n\tENTRY(4097  , 11) , ENTRY(6145  , 11) , ENTRY(8193  , 12) , ENTRY(12289 , 12) ,\n\tENTRY(16385 , 13) , ENTRY(24577 , 13) , ENTRY(24577 , 13) , ENTRY(24577 , 13) ,\n#undef ENTRY\n};\n\n/*\n * The main DEFLATE decompressor structure.  Since libdeflate only supports\n * full-buffer decompression, this structure doesn't store the entire\n * decompression state, most of which is in stack variables.  Instead, this\n * struct just contains the decode tables and some temporary arrays used for\n * building them, as these are too large to comfortably allocate on the stack.\n *\n * Storing the decode tables in the decompressor struct also allows the decode\n * tables for the static codes to be reused whenever two static Huffman blocks\n * are decoded without an intervening dynamic block, even across streams.\n */\nstruct libdeflate_decompressor {\n\n\t/*\n\t * The arrays aren't all needed at the same time.  'precode_lens' and\n\t * 'precode_decode_table' are unneeded after 'lens' has been filled.\n\t * Furthermore, 'lens' need not be retained after building the litlen\n\t * and offset decode tables.  In fact, 'lens' can be in union with\n\t * 'litlen_decode_table' provided that 'offset_decode_table' is separate\n\t * and is built first.\n\t */\n\n\tunion {\n\t\tu8 precode_lens[DEFLATE_NUM_PRECODE_SYMS];\n\n\t\tstruct {\n\t\t\tu8 lens[DEFLATE_NUM_LITLEN_SYMS +\n\t\t\t\tDEFLATE_NUM_OFFSET_SYMS +\n\t\t\t\tDEFLATE_MAX_LENS_OVERRUN];\n\n\t\t\tu32 precode_decode_table[PRECODE_ENOUGH];\n\t\t} l;\n\n\t\tu32 litlen_decode_table[LITLEN_ENOUGH];\n\t} u;\n\n\tu32 offset_decode_table[OFFSET_ENOUGH];\n\n\t/* used only during build_decode_table() */\n\tu16 sorted_syms[DEFLATE_MAX_NUM_SYMS];\n\n\tbool static_codes_loaded;\n\tunsigned litlen_tablebits;\n\n\t/* The free() function for this struct, chosen at allocation time */\n\tfree_func_t free_func;\n};\n\n/*\n * Build a table for fast decoding of symbols from a Huffman code.  As input,\n * this function takes the codeword length of each symbol which may be used in\n * the code.  As output, it produces a decode table for the canonical Huffman\n * code described by the codeword lengths.  The decode table is built with the\n * assumption that it will be indexed with \"bit-reversed\" codewords, where the\n * low-order bit is the first bit of the codeword.  This format is used for all\n * Huffman codes in DEFLATE.\n *\n * @decode_table\n *\tThe array in which the decode table will be generated.  This array must\n *\thave sufficient length; see the definition of the ENOUGH numbers.\n * @lens\n *\tAn array which provides, for each symbol, the length of the\n *\tcorresponding codeword in bits, or 0 if the symbol is unused.  This may\n *\talias @decode_table, since nothing is written to @decode_table until all\n *\t@lens have been consumed.  All codeword lengths are assumed to be <=\n *\t@max_codeword_len but are otherwise considered untrusted.  If they do\n *\tnot form a valid Huffman code, then the decode table is not built and\n *\t%false is returned.\n * @num_syms\n *\tThe number of symbols in the code, including all unused symbols.\n * @decode_results\n *\tAn array which gives the incomplete decode result for each symbol.  The\n *\tneeded values in this array will be combined with codeword lengths to\n *\tmake the final decode table entries using make_decode_table_entry().\n * @table_bits\n *\tThe log base-2 of the number of main table entries to use.\n *\tIf @table_bits_ret != NULL, then @table_bits is treated as a maximum\n *\tvalue and it will be decreased if a smaller table would be sufficient.\n * @max_codeword_len\n *\tThe maximum allowed codeword length for this Huffman code.\n *\tMust be <= DEFLATE_MAX_CODEWORD_LEN.\n * @sorted_syms\n *\tA temporary array of length @num_syms.\n * @table_bits_ret\n *\tIf non-NULL, then the dynamic table_bits is enabled, and the actual\n *\ttable_bits value will be returned here.\n *\n * Returns %true if successful; %false if the codeword lengths do not form a\n * valid Huffman code.\n */\nstatic bool\nbuild_decode_table(u32 decode_table[],\n\t\t   const u8 lens[],\n\t\t   const unsigned num_syms,\n\t\t   const u32 decode_results[],\n\t\t   unsigned table_bits,\n\t\t   unsigned max_codeword_len,\n\t\t   u16 *sorted_syms,\n\t\t   unsigned *table_bits_ret)\n{\n\tunsigned len_counts[DEFLATE_MAX_CODEWORD_LEN + 1];\n\tunsigned offsets[DEFLATE_MAX_CODEWORD_LEN + 1];\n\tunsigned sym;\t\t/* current symbol */\n\tunsigned codeword;\t/* current codeword, bit-reversed */\n\tunsigned len;\t\t/* current codeword length in bits */\n\tunsigned count;\t\t/* num codewords remaining with this length */\n\tu32 codespace_used;\t/* codespace used out of '2^max_codeword_len' */\n\tunsigned cur_table_end; /* end index of current table */\n\tunsigned subtable_prefix; /* codeword prefix of current subtable */\n\tunsigned subtable_start;  /* start index of current subtable */\n\tunsigned subtable_bits;   /* log2 of current subtable length */\n\n\t/* Count how many codewords have each length, including 0. */\n\tfor (len = 0; len <= max_codeword_len; len++)\n\t\tlen_counts[len] = 0;\n\tfor (sym = 0; sym < num_syms; sym++)\n\t\tlen_counts[lens[sym]]++;\n\n\t/*\n\t * Determine the actual maximum codeword length that was used, and\n\t * decrease table_bits to it if allowed.\n\t */\n\twhile (max_codeword_len > 1 && len_counts[max_codeword_len] == 0)\n\t\tmax_codeword_len--;\n\tif (table_bits_ret != NULL) {\n\t\ttable_bits = MIN(table_bits, max_codeword_len);\n\t\t*table_bits_ret = table_bits;\n\t}\n\n\t/*\n\t * Sort the symbols primarily by increasing codeword length and\n\t * secondarily by increasing symbol value; or equivalently by their\n\t * codewords in lexicographic order, since a canonical code is assumed.\n\t *\n\t * For efficiency, also compute 'codespace_used' in the same pass over\n\t * 'len_counts[]' used to build 'offsets[]' for sorting.\n\t */\n\n\t/* Ensure that 'codespace_used' cannot overflow. */\n\tSTATIC_ASSERT(sizeof(codespace_used) == 4);\n\tSTATIC_ASSERT(UINT32_MAX / (1U << (DEFLATE_MAX_CODEWORD_LEN - 1)) >=\n\t\t      DEFLATE_MAX_NUM_SYMS);\n\n\toffsets[0] = 0;\n\toffsets[1] = len_counts[0];\n\tcodespace_used = 0;\n\tfor (len = 1; len < max_codeword_len; len++) {\n\t\toffsets[len + 1] = offsets[len] + len_counts[len];\n\t\tcodespace_used = (codespace_used << 1) + len_counts[len];\n\t}\n\tcodespace_used = (codespace_used << 1) + len_counts[len];\n\n\tfor (sym = 0; sym < num_syms; sym++)\n\t\tsorted_syms[offsets[lens[sym]]++] = sym;\n\n\tsorted_syms += offsets[0]; /* Skip unused symbols */\n\n\t/* lens[] is done being used, so we can write to decode_table[] now. */\n\n\t/*\n\t * Check whether the lengths form a complete code (exactly fills the\n\t * codespace), an incomplete code (doesn't fill the codespace), or an\n\t * overfull code (overflows the codespace).  A codeword of length 'n'\n\t * uses proportion '1/(2^n)' of the codespace.  An overfull code is\n\t * nonsensical, so is considered invalid.  An incomplete code is\n\t * considered valid only in two specific cases; see below.\n\t */\n\n\t/* overfull code? */\n\tif (unlikely(codespace_used > (1U << max_codeword_len)))\n\t\treturn false;\n\n\t/* incomplete code? */\n\tif (unlikely(codespace_used < (1U << max_codeword_len))) {\n\t\tu32 entry;\n\t\tunsigned i;\n\n\t\t/*\n\t\t * The DEFLATE RFC explicitly allows the offset code to be\n\t\t * incomplete in two cases: a code containing just 1 codeword,\n\t\t * if that codeword has length 1; and a code containing no\n\t\t * codewords.  Note: the list of offset codeword lengths is\n\t\t * always nonempty, but lengths of 0 don't count as codewords.\n\t\t *\n\t\t * The RFC doesn't say whether the same cases are allowed for\n\t\t * the litlen and pre codes.  It's actually impossible for no\n\t\t * symbols to be used from these codes; however, it's\n\t\t * technically possible for only one symbol to be used.  zlib\n\t\t * allows 1 codeword for the litlen code, but not the precode.\n\t\t * The RFC also doesn't say whether, when there is 1 codeword,\n\t\t * that codeword is '0' or '1'.  zlib uses '0'.\n\t\t *\n\t\t * We accept what zlib accepts, plus a bit more.  First, we\n\t\t * don't treat the precode more strictly than the litlen and\n\t\t * offset codes.  There's no convincing reason to add a special\n\t\t * case for the precode here.\n\t\t *\n\t\t * Second, we just map each allowed incompete code to a complete\n\t\t * code with only real symbols.  To do this, we choose a symbol,\n\t\t * either the used symbol (for codes with 1 codeword) or an\n\t\t * arbitrary symbol (for empty codes), and give it both\n\t\t * codewords '0' and '1'.  zlib instead uses a special ERROR\n\t\t * symbol in the part of the codespace the code doesn't use.\n\t\t * However, having an ERROR symbol reduces the performance of\n\t\t * the Huffman decoder, for no real benefit.  Our approach also\n\t\t * avoids having to decide whether '0' or '1' is correct.\n\t\t *\n\t\t * Like zlib, we still reject all incomplete codes that contain\n\t\t * more than 1 codeword or a codeword length greater than 1.\n\t\t */\n\t\tif (codespace_used == 0) {\n\t\t\tsym = 0; /* arbitrary */\n\t\t} else {\n\t\t\tif (codespace_used != (1U << (max_codeword_len - 1)) ||\n\t\t\t    len_counts[1] != 1)\n\t\t\t\treturn false;\n\t\t\tsym = sorted_syms[0];\n\t\t}\n\t\tentry = make_decode_table_entry(decode_results, sym, 1);\n\t\tfor (i = 0; i < (1U << table_bits); i++)\n\t\t\tdecode_table[i] = entry;\n\t\treturn true;\n\t}\n\n\t/*\n\t * The lengths form a complete code.  Now, enumerate the codewords in\n\t * lexicographic order and fill the decode table entries for each one.\n\t *\n\t * First, process all codewords with len <= table_bits.  Each one gets\n\t * '2^(table_bits-len)' direct entries in the table.\n\t *\n\t * Since DEFLATE uses bit-reversed codewords, these entries aren't\n\t * consecutive but rather are spaced '2^len' entries apart.  This makes\n\t * filling them naively somewhat awkward and inefficient, since strided\n\t * stores are less cache-friendly and preclude the use of word or\n\t * vector-at-a-time stores to fill multiple entries per instruction.\n\t *\n\t * To optimize this, we incrementally double the table size.  When\n\t * processing codewords with length 'len', the table is treated as\n\t * having only '2^len' entries, so each codeword uses just one entry.\n\t * Then, each time 'len' is incremented, the table size is doubled and\n\t * the first half is copied to the second half.  This significantly\n\t * improves performance over naively doing strided stores.\n\t *\n\t * Note that some entries copied for each table doubling may not have\n\t * been initialized yet, but it doesn't matter since they're guaranteed\n\t * to be initialized later (because the Huffman code is complete).\n\t */\n\tcodeword = 0;\n\tlen = 1;\n\twhile ((count = len_counts[len]) == 0)\n\t\tlen++;\n\tcur_table_end = 1U << len;\n\twhile (len <= table_bits) {\n\t\t/* Process all 'count' codewords with length 'len' bits. */\n\t\tdo {\n\t\t\tunsigned bit;\n\n\t\t\t/* Fill the first entry for the current codeword. */\n\t\t\tdecode_table[codeword] =\n\t\t\t\tmake_decode_table_entry(decode_results,\n\t\t\t\t\t\t\t*sorted_syms++, len);\n\n\t\t\tif (codeword == cur_table_end - 1) {\n\t\t\t\t/* Last codeword (all 1's) */\n\t\t\t\tfor (; len < table_bits; len++) {\n\t\t\t\t\tmemcpy(&decode_table[cur_table_end],\n\t\t\t\t\t       decode_table,\n\t\t\t\t\t       cur_table_end *\n\t\t\t\t\t\tsizeof(decode_table[0]));\n\t\t\t\t\tcur_table_end <<= 1;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t/*\n\t\t\t * To advance to the lexicographically next codeword in\n\t\t\t * the canonical code, the codeword must be incremented,\n\t\t\t * then 0's must be appended to the codeword as needed\n\t\t\t * to match the next codeword's length.\n\t\t\t *\n\t\t\t * Since the codeword is bit-reversed, appending 0's is\n\t\t\t * a no-op.  However, incrementing it is nontrivial.  To\n\t\t\t * do so efficiently, use the 'bsr' instruction to find\n\t\t\t * the last (highest order) 0 bit in the codeword, set\n\t\t\t * it, and clear any later (higher order) 1 bits.  But\n\t\t\t * 'bsr' actually finds the highest order 1 bit, so to\n\t\t\t * use it first flip all bits in the codeword by XOR'ing\n\t\t\t * it with (1U << len) - 1 == cur_table_end - 1.\n\t\t\t */\n\t\t\tbit = 1U << bsr32(codeword ^ (cur_table_end - 1));\n\t\t\tcodeword &= bit - 1;\n\t\t\tcodeword |= bit;\n\t\t} while (--count);\n\n\t\t/* Advance to the next codeword length. */\n\t\tdo {\n\t\t\tif (++len <= table_bits) {\n\t\t\t\tmemcpy(&decode_table[cur_table_end],\n\t\t\t\t       decode_table,\n\t\t\t\t       cur_table_end * sizeof(decode_table[0]));\n\t\t\t\tcur_table_end <<= 1;\n\t\t\t}\n\t\t} while ((count = len_counts[len]) == 0);\n\t}\n\n\t/* Process codewords with len > table_bits.  These require subtables. */\n\tcur_table_end = 1U << table_bits;\n\tsubtable_prefix = -1;\n\tsubtable_start = 0;\n\tfor (;;) {\n\t\tu32 entry;\n\t\tunsigned i;\n\t\tunsigned stride;\n\t\tunsigned bit;\n\n\t\t/*\n\t\t * Start a new subtable if the first 'table_bits' bits of the\n\t\t * codeword don't match the prefix of the current subtable.\n\t\t */\n\t\tif ((codeword & ((1U << table_bits) - 1)) != subtable_prefix) {\n\t\t\tsubtable_prefix = (codeword & ((1U << table_bits) - 1));\n\t\t\tsubtable_start = cur_table_end;\n\t\t\t/*\n\t\t\t * Calculate the subtable length.  If the codeword has\n\t\t\t * length 'table_bits + n', then the subtable needs\n\t\t\t * '2^n' entries.  But it may need more; if fewer than\n\t\t\t * '2^n' codewords of length 'table_bits + n' remain,\n\t\t\t * then the length will need to be incremented to bring\n\t\t\t * in longer codewords until the subtable can be\n\t\t\t * completely filled.  Note that because the Huffman\n\t\t\t * code is complete, it will always be possible to fill\n\t\t\t * the subtable eventually.\n\t\t\t */\n\t\t\tsubtable_bits = len - table_bits;\n\t\t\tcodespace_used = count;\n\t\t\twhile (codespace_used < (1U << subtable_bits)) {\n\t\t\t\tsubtable_bits++;\n\t\t\t\tcodespace_used = (codespace_used << 1) +\n\t\t\t\t\tlen_counts[table_bits + subtable_bits];\n\t\t\t}\n\t\t\tcur_table_end = subtable_start + (1U << subtable_bits);\n\n\t\t\t/*\n\t\t\t * Create the entry that points from the main table to\n\t\t\t * the subtable.\n\t\t\t */\n\t\t\tdecode_table[subtable_prefix] =\n\t\t\t\t((u32)subtable_start << 16) |\n\t\t\t\tHUFFDEC_EXCEPTIONAL |\n\t\t\t\tHUFFDEC_SUBTABLE_POINTER |\n\t\t\t\t(subtable_bits << 8) | table_bits;\n\t\t}\n\n\t\t/* Fill the subtable entries for the current codeword. */\n\t\tentry = make_decode_table_entry(decode_results, *sorted_syms++,\n\t\t\t\t\t\tlen - table_bits);\n\t\ti = subtable_start + (codeword >> table_bits);\n\t\tstride = 1U << (len - table_bits);\n\t\tdo {\n\t\t\tdecode_table[i] = entry;\n\t\t\ti += stride;\n\t\t} while (i < cur_table_end);\n\n\t\t/* Advance to the next codeword. */\n\t\tif (codeword == (1U << len) - 1) /* last codeword (all 1's)? */\n\t\t\treturn true;\n\t\tbit = 1U << bsr32(codeword ^ ((1U << len) - 1));\n\t\tcodeword &= bit - 1;\n\t\tcodeword |= bit;\n\t\tcount--;\n\t\twhile (count == 0)\n\t\t\tcount = len_counts[++len];\n\t}\n}\n\n/* Build the decode table for the precode.  */\nstatic bool\nbuild_precode_decode_table(struct libdeflate_decompressor *d)\n{\n\t/* When you change TABLEBITS, you must change ENOUGH, and vice versa! */\n\tSTATIC_ASSERT(PRECODE_TABLEBITS == 7 && PRECODE_ENOUGH == 128);\n\n\tSTATIC_ASSERT(ARRAY_LEN(precode_decode_results) ==\n\t\t      DEFLATE_NUM_PRECODE_SYMS);\n\n\treturn build_decode_table(d->u.l.precode_decode_table,\n\t\t\t\t  d->u.precode_lens,\n\t\t\t\t  DEFLATE_NUM_PRECODE_SYMS,\n\t\t\t\t  precode_decode_results,\n\t\t\t\t  PRECODE_TABLEBITS,\n\t\t\t\t  DEFLATE_MAX_PRE_CODEWORD_LEN,\n\t\t\t\t  d->sorted_syms,\n\t\t\t\t  NULL);\n}\n\n/* Build the decode table for the literal/length code.  */\nstatic bool\nbuild_litlen_decode_table(struct libdeflate_decompressor *d,\n\t\t\t  unsigned num_litlen_syms, unsigned num_offset_syms)\n{\n\t/* When you change TABLEBITS, you must change ENOUGH, and vice versa! */\n\tSTATIC_ASSERT(LITLEN_TABLEBITS == 11 && LITLEN_ENOUGH == 2342);\n\n\tSTATIC_ASSERT(ARRAY_LEN(litlen_decode_results) ==\n\t\t      DEFLATE_NUM_LITLEN_SYMS);\n\n\treturn build_decode_table(d->u.litlen_decode_table,\n\t\t\t\t  d->u.l.lens,\n\t\t\t\t  num_litlen_syms,\n\t\t\t\t  litlen_decode_results,\n\t\t\t\t  LITLEN_TABLEBITS,\n\t\t\t\t  DEFLATE_MAX_LITLEN_CODEWORD_LEN,\n\t\t\t\t  d->sorted_syms,\n\t\t\t\t  &d->litlen_tablebits);\n}\n\n/* Build the decode table for the offset code.  */\nstatic bool\nbuild_offset_decode_table(struct libdeflate_decompressor *d,\n\t\t\t  unsigned num_litlen_syms, unsigned num_offset_syms)\n{\n\t/* When you change TABLEBITS, you must change ENOUGH, and vice versa! */\n\tSTATIC_ASSERT(OFFSET_TABLEBITS == 8 && OFFSET_ENOUGH == 402);\n\n\tSTATIC_ASSERT(ARRAY_LEN(offset_decode_results) ==\n\t\t      DEFLATE_NUM_OFFSET_SYMS);\n\n\treturn build_decode_table(d->offset_decode_table,\n\t\t\t\t  d->u.l.lens + num_litlen_syms,\n\t\t\t\t  num_offset_syms,\n\t\t\t\t  offset_decode_results,\n\t\t\t\t  OFFSET_TABLEBITS,\n\t\t\t\t  DEFLATE_MAX_OFFSET_CODEWORD_LEN,\n\t\t\t\t  d->sorted_syms,\n\t\t\t\t  NULL);\n}\n\n/*****************************************************************************\n *                         Main decompression routine\n *****************************************************************************/\n\ntypedef enum libdeflate_result (*decompress_func_t)\n\t(struct libdeflate_decompressor * restrict d,\n\t const void * restrict in, size_t in_nbytes,\n\t void * restrict out, size_t out_nbytes_avail,\n\t size_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret);\n\n#define FUNCNAME deflate_decompress_default\n#undef ATTRIBUTES\n#undef EXTRACT_VARBITS\n#undef EXTRACT_VARBITS8\n#include \"decompress_template.h\"\n\n/* Include architecture-specific implementation(s) if available. */\n#undef DEFAULT_IMPL\n#undef arch_select_decompress_func\n#if defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#  include \"x86/decompress_impl.h\"\n#endif\n\n#ifndef DEFAULT_IMPL\n#  define DEFAULT_IMPL deflate_decompress_default\n#endif\n\n#ifdef arch_select_decompress_func\nstatic enum libdeflate_result\ndispatch_decomp(struct libdeflate_decompressor *d,\n\t\tconst void *in, size_t in_nbytes,\n\t\tvoid *out, size_t out_nbytes_avail,\n\t\tsize_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret);\n\nstatic volatile decompress_func_t decompress_impl = dispatch_decomp;\n\n/* Choose the best implementation at runtime. */\nstatic enum libdeflate_result\ndispatch_decomp(struct libdeflate_decompressor *d,\n\t\tconst void *in, size_t in_nbytes,\n\t\tvoid *out, size_t out_nbytes_avail,\n\t\tsize_t *actual_in_nbytes_ret, size_t *actual_out_nbytes_ret)\n{\n\tdecompress_func_t f = arch_select_decompress_func();\n\n\tif (f == NULL)\n\t\tf = DEFAULT_IMPL;\n\n\tdecompress_impl = f;\n\treturn f(d, in, in_nbytes, out, out_nbytes_avail,\n\t\t actual_in_nbytes_ret, actual_out_nbytes_ret);\n}\n#else\n/* The best implementation is statically known, so call it directly. */\n#  define decompress_impl DEFAULT_IMPL\n#endif\n\n/*\n * This is the main DEFLATE decompression routine.  See libdeflate.h for the\n * documentation.\n *\n * Note that the real code is in decompress_template.h.  The part here just\n * handles calling the appropriate implementation depending on the CPU features\n * at runtime.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_deflate_decompress_ex(struct libdeflate_decompressor *d,\n\t\t\t\t const void *in, size_t in_nbytes,\n\t\t\t\t void *out, size_t out_nbytes_avail,\n\t\t\t\t size_t *actual_in_nbytes_ret,\n\t\t\t\t size_t *actual_out_nbytes_ret)\n{\n\treturn decompress_impl(d, in, in_nbytes, out, out_nbytes_avail,\n\t\t\t       actual_in_nbytes_ret, actual_out_nbytes_ret);\n}\n\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_deflate_decompress(struct libdeflate_decompressor *d,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_out_nbytes_ret)\n{\n\treturn libdeflate_deflate_decompress_ex(d, in, in_nbytes,\n\t\t\t\t\t\tout, out_nbytes_avail,\n\t\t\t\t\t\tNULL, actual_out_nbytes_ret);\n}\n\nLIBDEFLATEAPI struct libdeflate_decompressor *\nlibdeflate_alloc_decompressor_ex(const struct libdeflate_options *options)\n{\n\tstruct libdeflate_decompressor *d;\n\n\t/*\n\t * Note: if more fields are added to libdeflate_options, this code will\n\t * need to be updated to support both the old and new structs.\n\t */\n\tif (options->sizeof_options != sizeof(*options))\n\t\treturn NULL;\n\n\td = (options->malloc_func ? options->malloc_func :\n\t     libdeflate_default_malloc_func)(sizeof(*d));\n\tif (d == NULL)\n\t\treturn NULL;\n\t/*\n\t * Note that only certain parts of the decompressor actually must be\n\t * initialized here:\n\t *\n\t * - 'static_codes_loaded' must be initialized to false.\n\t *\n\t * - The first half of the main portion of each decode table must be\n\t *   initialized to any value, to avoid reading from uninitialized\n\t *   memory during table expansion in build_decode_table().  (Although,\n\t *   this is really just to avoid warnings with dynamic tools like\n\t *   valgrind, since build_decode_table() is guaranteed to initialize\n\t *   all entries eventually anyway.)\n\t *\n\t * - 'free_func' must be set.\n\t *\n\t * But for simplicity, we currently just zero the whole decompressor.\n\t */\n\tmemset(d, 0, sizeof(*d));\n\td->free_func = options->free_func ?\n\t\t       options->free_func : libdeflate_default_free_func;\n\treturn d;\n}\n\nLIBDEFLATEAPI struct libdeflate_decompressor *\nlibdeflate_alloc_decompressor(void)\n{\n\tstatic const struct libdeflate_options defaults = {\n\t\t.sizeof_options = sizeof(defaults),\n\t};\n\treturn libdeflate_alloc_decompressor_ex(&defaults);\n}\n\nLIBDEFLATEAPI void\nlibdeflate_free_decompressor(struct libdeflate_decompressor *d)\n{\n\tif (d)\n\t\td->free_func(d);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/gzip_compress.c",
    "content": "/*\n * gzip_compress.c - compress with a gzip wrapper\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"deflate_compress.h\"\n#include \"gzip_constants.h\"\n\nLIBDEFLATEAPI size_t\nlibdeflate_gzip_compress(struct libdeflate_compressor *c,\n\t\t\t const void *in, size_t in_nbytes,\n\t\t\t void *out, size_t out_nbytes_avail)\n{\n\tu8 *out_next = out;\n\tunsigned compression_level;\n\tu8 xfl;\n\tsize_t deflate_size;\n\n\tif (out_nbytes_avail <= GZIP_MIN_OVERHEAD)\n\t\treturn 0;\n\n\t/* ID1 */\n\t*out_next++ = GZIP_ID1;\n\t/* ID2 */\n\t*out_next++ = GZIP_ID2;\n\t/* CM */\n\t*out_next++ = GZIP_CM_DEFLATE;\n\t/* FLG */\n\t*out_next++ = 0;\n\t/* MTIME */\n\tput_unaligned_le32(GZIP_MTIME_UNAVAILABLE, out_next);\n\tout_next += 4;\n\t/* XFL */\n\txfl = 0;\n\tcompression_level = libdeflate_get_compression_level(c);\n\tif (compression_level < 2)\n\t\txfl |= GZIP_XFL_FASTEST_COMPRESSION;\n\telse if (compression_level >= 8)\n\t\txfl |= GZIP_XFL_SLOWEST_COMPRESSION;\n\t*out_next++ = xfl;\n\t/* OS */\n\t*out_next++ = GZIP_OS_UNKNOWN;\t/* OS  */\n\n\t/* Compressed data  */\n\tdeflate_size = libdeflate_deflate_compress(c, in, in_nbytes, out_next,\n\t\t\t\t\tout_nbytes_avail - GZIP_MIN_OVERHEAD);\n\tif (deflate_size == 0)\n\t\treturn 0;\n\tout_next += deflate_size;\n\n\t/* CRC32 */\n\tput_unaligned_le32(libdeflate_crc32(0, in, in_nbytes), out_next);\n\tout_next += 4;\n\n\t/* ISIZE */\n\tput_unaligned_le32((u32)in_nbytes, out_next);\n\tout_next += 4;\n\n\treturn out_next - (u8 *)out;\n}\n\nLIBDEFLATEAPI size_t\nlibdeflate_gzip_compress_bound(struct libdeflate_compressor *c,\n\t\t\t       size_t in_nbytes)\n{\n\treturn GZIP_MIN_OVERHEAD +\n\t       libdeflate_deflate_compress_bound(c, in_nbytes);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/gzip_constants.h",
    "content": "/*\n * gzip_constants.h - constants for the gzip wrapper format\n */\n\n#ifndef LIB_GZIP_CONSTANTS_H\n#define LIB_GZIP_CONSTANTS_H\n\n#define GZIP_MIN_HEADER_SIZE\t10\n#define GZIP_FOOTER_SIZE\t8\n#define GZIP_MIN_OVERHEAD\t(GZIP_MIN_HEADER_SIZE + GZIP_FOOTER_SIZE)\n\n#define GZIP_ID1\t\t0x1F\n#define GZIP_ID2\t\t0x8B\n\n#define GZIP_CM_DEFLATE\t\t8\n\n#define GZIP_FTEXT\t\t0x01\n#define GZIP_FHCRC\t\t0x02\n#define GZIP_FEXTRA\t\t0x04\n#define GZIP_FNAME\t\t0x08\n#define GZIP_FCOMMENT\t\t0x10\n#define GZIP_FRESERVED\t\t0xE0\n\n#define GZIP_MTIME_UNAVAILABLE\t0\n\n#define GZIP_XFL_SLOWEST_COMPRESSION\t0x02\n#define GZIP_XFL_FASTEST_COMPRESSION\t0x04\n\n#define GZIP_OS_FAT\t\t0\n#define GZIP_OS_AMIGA\t\t1\n#define GZIP_OS_VMS\t\t2\n#define GZIP_OS_UNIX\t\t3\n#define GZIP_OS_VM_CMS\t\t4\n#define GZIP_OS_ATARI_TOS\t5\n#define GZIP_OS_HPFS\t\t6\n#define GZIP_OS_MACINTOSH\t7\n#define GZIP_OS_Z_SYSTEM\t8\n#define GZIP_OS_CP_M\t\t9\n#define GZIP_OS_TOPS_20\t\t10\n#define GZIP_OS_NTFS\t\t11\n#define GZIP_OS_QDOS\t\t12\n#define GZIP_OS_RISCOS\t\t13\n#define GZIP_OS_UNKNOWN\t\t255\n\n#endif /* LIB_GZIP_CONSTANTS_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/gzip_decompress.c",
    "content": "/*\n * gzip_decompress.c - decompress with a gzip wrapper\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"lib_common.h\"\n#include \"gzip_constants.h\"\n\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_gzip_decompress_ex(struct libdeflate_decompressor *d,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_in_nbytes_ret,\n\t\t\t      size_t *actual_out_nbytes_ret)\n{\n\tconst u8 *in_next = in;\n\tconst u8 * const in_end = in_next + in_nbytes;\n\tu8 flg;\n\tsize_t actual_in_nbytes;\n\tsize_t actual_out_nbytes;\n\tenum libdeflate_result result;\n\n\tif (in_nbytes < GZIP_MIN_OVERHEAD)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* ID1 */\n\tif (*in_next++ != GZIP_ID1)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\t/* ID2 */\n\tif (*in_next++ != GZIP_ID2)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\t/* CM */\n\tif (*in_next++ != GZIP_CM_DEFLATE)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\tflg = *in_next++;\n\t/* MTIME */\n\tin_next += 4;\n\t/* XFL */\n\tin_next += 1;\n\t/* OS */\n\tin_next += 1;\n\n\tif (flg & GZIP_FRESERVED)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* Extra field */\n\tif (flg & GZIP_FEXTRA) {\n\t\tu16 xlen = get_unaligned_le16(in_next);\n\t\tin_next += 2;\n\n\t\tif (in_end - in_next < (u32)xlen + GZIP_FOOTER_SIZE)\n\t\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t\tin_next += xlen;\n\t}\n\n\t/* Original file name (zero terminated) */\n\tif (flg & GZIP_FNAME) {\n\t\twhile (*in_next++ != 0 && in_next != in_end)\n\t\t\t;\n\t\tif (in_end - in_next < GZIP_FOOTER_SIZE)\n\t\t\treturn LIBDEFLATE_BAD_DATA;\n\t}\n\n\t/* File comment (zero terminated) */\n\tif (flg & GZIP_FCOMMENT) {\n\t\twhile (*in_next++ != 0 && in_next != in_end)\n\t\t\t;\n\t\tif (in_end - in_next < GZIP_FOOTER_SIZE)\n\t\t\treturn LIBDEFLATE_BAD_DATA;\n\t}\n\n\t/* CRC16 for gzip header */\n\tif (flg & GZIP_FHCRC) {\n\t\tin_next += 2;\n\t\tif (in_end - in_next < GZIP_FOOTER_SIZE)\n\t\t\treturn LIBDEFLATE_BAD_DATA;\n\t}\n\n\t/* Compressed data  */\n\tresult = libdeflate_deflate_decompress_ex(d, in_next,\n\t\t\t\t\tin_end - GZIP_FOOTER_SIZE - in_next,\n\t\t\t\t\tout, out_nbytes_avail,\n\t\t\t\t\t&actual_in_nbytes,\n\t\t\t\t\tactual_out_nbytes_ret);\n\tif (result != LIBDEFLATE_SUCCESS)\n\t\treturn result;\n\n\tif (actual_out_nbytes_ret)\n\t\tactual_out_nbytes = *actual_out_nbytes_ret;\n\telse\n\t\tactual_out_nbytes = out_nbytes_avail;\n\n\tin_next += actual_in_nbytes;\n\n\t/* CRC32 */\n\tif (libdeflate_crc32(0, out, actual_out_nbytes) !=\n\t    get_unaligned_le32(in_next))\n\t\treturn LIBDEFLATE_BAD_DATA;\n\tin_next += 4;\n\n\t/* ISIZE */\n\tif ((u32)actual_out_nbytes != get_unaligned_le32(in_next))\n\t\treturn LIBDEFLATE_BAD_DATA;\n\tin_next += 4;\n\n\tif (actual_in_nbytes_ret)\n\t\t*actual_in_nbytes_ret = in_next - (u8 *)in;\n\n\treturn LIBDEFLATE_SUCCESS;\n}\n\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_gzip_decompress(struct libdeflate_decompressor *d,\n\t\t\t   const void *in, size_t in_nbytes,\n\t\t\t   void *out, size_t out_nbytes_avail,\n\t\t\t   size_t *actual_out_nbytes_ret)\n{\n\treturn libdeflate_gzip_decompress_ex(d, in, in_nbytes,\n\t\t\t\t\t     out, out_nbytes_avail,\n\t\t\t\t\t     NULL, actual_out_nbytes_ret);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/hc_matchfinder.h",
    "content": "/*\n * hc_matchfinder.h - Lempel-Ziv matchfinding with a hash table of linked lists\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * ---------------------------------------------------------------------------\n *\n *\t\t\t\t   Algorithm\n *\n * This is a Hash Chains (hc) based matchfinder.\n *\n * The main data structure is a hash table where each hash bucket contains a\n * linked list (or \"chain\") of sequences whose first 4 bytes share the same hash\n * code.  Each sequence is identified by its starting position in the input\n * buffer.\n *\n * The algorithm processes the input buffer sequentially.  At each byte\n * position, the hash code of the first 4 bytes of the sequence beginning at\n * that position (the sequence being matched against) is computed.  This\n * identifies the hash bucket to use for that position.  Then, this hash\n * bucket's linked list is searched for matches.  Then, a new linked list node\n * is created to represent the current sequence and is prepended to the list.\n *\n * This algorithm has several useful properties:\n *\n * - It only finds true Lempel-Ziv matches; i.e., those where the matching\n *   sequence occurs prior to the sequence being matched against.\n *\n * - The sequences in each linked list are always sorted by decreasing starting\n *   position.  Therefore, the closest (smallest offset) matches are found\n *   first, which in many compression formats tend to be the cheapest to encode.\n *\n * - Although fast running time is not guaranteed due to the possibility of the\n *   lists getting very long, the worst degenerate behavior can be easily\n *   prevented by capping the number of nodes searched at each position.\n *\n * - If the compressor decides not to search for matches at a certain position,\n *   then that position can be quickly inserted without searching the list.\n *\n * - The algorithm is adaptable to sliding windows: just store the positions\n *   relative to a \"base\" value that is updated from time to time, and stop\n *   searching each list when the sequences get too far away.\n *\n * ----------------------------------------------------------------------------\n *\n *\t\t\t\t Optimizations\n *\n * The main hash table and chains handle length 4+ matches.  Length 3 matches\n * are handled by a separate hash table with no chains.  This works well for\n * typical \"greedy\" or \"lazy\"-style compressors, where length 3 matches are\n * often only helpful if they have small offsets.  Instead of searching a full\n * chain for length 3+ matches, the algorithm just checks for one close length 3\n * match, then focuses on finding length 4+ matches.\n *\n * The longest_match() and skip_bytes() functions are inlined into the\n * compressors that use them.  This isn't just about saving the overhead of a\n * function call.  These functions are intended to be called from the inner\n * loops of compressors, where giving the compiler more control over register\n * allocation is very helpful.  There is also significant benefit to be gained\n * from allowing the CPU to predict branches independently at each call site.\n * For example, \"lazy\"-style compressors can be written with two calls to\n * longest_match(), each of which starts with a different 'best_len' and\n * therefore has significantly different performance characteristics.\n *\n * Although any hash function can be used, a multiplicative hash is fast and\n * works well.\n *\n * On some processors, it is significantly faster to extend matches by whole\n * words (32 or 64 bits) instead of by individual bytes.  For this to be the\n * case, the processor must implement unaligned memory accesses efficiently and\n * must have either a fast \"find first set bit\" instruction or a fast \"find last\n * set bit\" instruction, depending on the processor's endianness.\n *\n * The code uses one loop for finding the first match and one loop for finding a\n * longer match.  Each of these loops is tuned for its respective task and in\n * combination are faster than a single generalized loop that handles both\n * tasks.\n *\n * The code also uses a tight inner loop that only compares the last and first\n * bytes of a potential match.  It is only when these bytes match that a full\n * match extension is attempted.\n *\n * ----------------------------------------------------------------------------\n */\n\n#ifndef LIB_HC_MATCHFINDER_H\n#define LIB_HC_MATCHFINDER_H\n\n#include \"matchfinder_common.h\"\n\n#define HC_MATCHFINDER_HASH3_ORDER\t15\n#define HC_MATCHFINDER_HASH4_ORDER\t16\n\n#define HC_MATCHFINDER_TOTAL_HASH_SIZE\t\t\t\\\n\t(((1UL << HC_MATCHFINDER_HASH3_ORDER) +\t\t\\\n\t  (1UL << HC_MATCHFINDER_HASH4_ORDER)) * sizeof(mf_pos_t))\n\nstruct MATCHFINDER_ALIGNED hc_matchfinder  {\n\n\t/* The hash table for finding length 3 matches  */\n\tmf_pos_t hash3_tab[1UL << HC_MATCHFINDER_HASH3_ORDER];\n\n\t/* The hash table which contains the first nodes of the linked lists for\n\t * finding length 4+ matches  */\n\tmf_pos_t hash4_tab[1UL << HC_MATCHFINDER_HASH4_ORDER];\n\n\t/* The \"next node\" references for the linked lists.  The \"next node\" of\n\t * the node for the sequence with position 'pos' is 'next_tab[pos]'.  */\n\tmf_pos_t next_tab[MATCHFINDER_WINDOW_SIZE];\n};\n\n/* Prepare the matchfinder for a new input buffer.  */\nstatic forceinline void\nhc_matchfinder_init(struct hc_matchfinder *mf)\n{\n\tSTATIC_ASSERT(HC_MATCHFINDER_TOTAL_HASH_SIZE %\n\t\t      MATCHFINDER_SIZE_ALIGNMENT == 0);\n\n\tmatchfinder_init((mf_pos_t *)mf, HC_MATCHFINDER_TOTAL_HASH_SIZE);\n}\n\nstatic forceinline void\nhc_matchfinder_slide_window(struct hc_matchfinder *mf)\n{\n\tSTATIC_ASSERT(sizeof(*mf) % MATCHFINDER_SIZE_ALIGNMENT == 0);\n\n\tmatchfinder_rebase((mf_pos_t *)mf, sizeof(*mf));\n}\n\n/*\n * Find the longest match longer than 'best_len' bytes.\n *\n * @mf\n *\tThe matchfinder structure.\n * @in_base_p\n *\tLocation of a pointer which points to the place in the input data the\n *\tmatchfinder currently stores positions relative to.  This may be updated\n *\tby this function.\n * @in_next\n *\tPointer to the next position in the input buffer, i.e. the sequence\n *\tbeing matched against.\n * @best_len\n *\tRequire a match longer than this length.\n * @max_len\n *\tThe maximum permissible match length at this position.\n * @nice_len\n *\tStop searching if a match of at least this length is found.\n *\tMust be <= @max_len.\n * @max_search_depth\n *\tLimit on the number of potential matches to consider.  Must be >= 1.\n * @next_hashes\n *\tThe precomputed hash codes for the sequence beginning at @in_next.\n *\tThese will be used and then updated with the precomputed hashcodes for\n *\tthe sequence beginning at @in_next + 1.\n * @offset_ret\n *\tIf a match is found, its offset is returned in this location.\n *\n * Return the length of the match found, or 'best_len' if no match longer than\n * 'best_len' was found.\n */\nstatic forceinline u32\nhc_matchfinder_longest_match(struct hc_matchfinder * const mf,\n\t\t\t     const u8 ** const in_base_p,\n\t\t\t     const u8 * const in_next,\n\t\t\t     u32 best_len,\n\t\t\t     const u32 max_len,\n\t\t\t     const u32 nice_len,\n\t\t\t     const u32 max_search_depth,\n\t\t\t     u32 * const next_hashes,\n\t\t\t     u32 * const offset_ret)\n{\n\tu32 depth_remaining = max_search_depth;\n\tconst u8 *best_matchptr = in_next;\n\tmf_pos_t cur_node3, cur_node4;\n\tu32 hash3, hash4;\n\tu32 next_hashseq;\n\tu32 seq4;\n\tconst u8 *matchptr;\n\tu32 len;\n\tu32 cur_pos = in_next - *in_base_p;\n\tconst u8 *in_base;\n\tmf_pos_t cutoff;\n\n\tif (cur_pos == MATCHFINDER_WINDOW_SIZE) {\n\t\thc_matchfinder_slide_window(mf);\n\t\t*in_base_p += MATCHFINDER_WINDOW_SIZE;\n\t\tcur_pos = 0;\n\t}\n\n\tin_base = *in_base_p;\n\tcutoff = cur_pos - MATCHFINDER_WINDOW_SIZE;\n\n\tif (unlikely(max_len < 5)) /* can we read 4 bytes from 'in_next + 1'? */\n\t\tgoto out;\n\n\t/* Get the precomputed hash codes.  */\n\thash3 = next_hashes[0];\n\thash4 = next_hashes[1];\n\n\t/* From the hash buckets, get the first node of each linked list.  */\n\tcur_node3 = mf->hash3_tab[hash3];\n\tcur_node4 = mf->hash4_tab[hash4];\n\n\t/* Update for length 3 matches.  This replaces the singleton node in the\n\t * 'hash3' bucket with the node for the current sequence.  */\n\tmf->hash3_tab[hash3] = cur_pos;\n\n\t/* Update for length 4 matches.  This prepends the node for the current\n\t * sequence to the linked list in the 'hash4' bucket.  */\n\tmf->hash4_tab[hash4] = cur_pos;\n\tmf->next_tab[cur_pos] = cur_node4;\n\n\t/* Compute the next hash codes.  */\n\tnext_hashseq = get_unaligned_le32(in_next + 1);\n\tnext_hashes[0] = lz_hash(next_hashseq & 0xFFFFFF, HC_MATCHFINDER_HASH3_ORDER);\n\tnext_hashes[1] = lz_hash(next_hashseq, HC_MATCHFINDER_HASH4_ORDER);\n\tprefetchw(&mf->hash3_tab[next_hashes[0]]);\n\tprefetchw(&mf->hash4_tab[next_hashes[1]]);\n\n\tif (best_len < 4) {  /* No match of length >= 4 found yet?  */\n\n\t\t/* Check for a length 3 match if needed.  */\n\n\t\tif (cur_node3 <= cutoff)\n\t\t\tgoto out;\n\n\t\tseq4 = load_u32_unaligned(in_next);\n\n\t\tif (best_len < 3) {\n\t\t\tmatchptr = &in_base[cur_node3];\n\t\t\tif (load_u24_unaligned(matchptr) == loaded_u32_to_u24(seq4)) {\n\t\t\t\tbest_len = 3;\n\t\t\t\tbest_matchptr = matchptr;\n\t\t\t}\n\t\t}\n\n\t\t/* Check for a length 4 match.  */\n\n\t\tif (cur_node4 <= cutoff)\n\t\t\tgoto out;\n\n\t\tfor (;;) {\n\t\t\t/* No length 4 match found yet.  Check the first 4 bytes.  */\n\t\t\tmatchptr = &in_base[cur_node4];\n\n\t\t\tif (load_u32_unaligned(matchptr) == seq4)\n\t\t\t\tbreak;\n\n\t\t\t/* The first 4 bytes did not match.  Keep trying.  */\n\t\t\tcur_node4 = mf->next_tab[cur_node4 & (MATCHFINDER_WINDOW_SIZE - 1)];\n\t\t\tif (cur_node4 <= cutoff || !--depth_remaining)\n\t\t\t\tgoto out;\n\t\t}\n\n\t\t/* Found a match of length >= 4.  Extend it to its full length.  */\n\t\tbest_matchptr = matchptr;\n\t\tbest_len = lz_extend(in_next, best_matchptr, 4, max_len);\n\t\tif (best_len >= nice_len)\n\t\t\tgoto out;\n\t\tcur_node4 = mf->next_tab[cur_node4 & (MATCHFINDER_WINDOW_SIZE - 1)];\n\t\tif (cur_node4 <= cutoff || !--depth_remaining)\n\t\t\tgoto out;\n\t} else {\n\t\tif (cur_node4 <= cutoff || best_len >= nice_len)\n\t\t\tgoto out;\n\t}\n\n\t/* Check for matches of length >= 5.  */\n\n\tfor (;;) {\n\t\tfor (;;) {\n\t\t\tmatchptr = &in_base[cur_node4];\n\n\t\t\t/* Already found a length 4 match.  Try for a longer\n\t\t\t * match; start by checking either the last 4 bytes and\n\t\t\t * the first 4 bytes, or the last byte.  (The last byte,\n\t\t\t * the one which would extend the match length by 1, is\n\t\t\t * the most important.)  */\n\t\t#if UNALIGNED_ACCESS_IS_FAST\n\t\t\tif ((load_u32_unaligned(matchptr + best_len - 3) ==\n\t\t\t     load_u32_unaligned(in_next + best_len - 3)) &&\n\t\t\t    (load_u32_unaligned(matchptr) ==\n\t\t\t     load_u32_unaligned(in_next)))\n\t\t#else\n\t\t\tif (matchptr[best_len] == in_next[best_len])\n\t\t#endif\n\t\t\t\tbreak;\n\n\t\t\t/* Continue to the next node in the list.  */\n\t\t\tcur_node4 = mf->next_tab[cur_node4 & (MATCHFINDER_WINDOW_SIZE - 1)];\n\t\t\tif (cur_node4 <= cutoff || !--depth_remaining)\n\t\t\t\tgoto out;\n\t\t}\n\n\t#if UNALIGNED_ACCESS_IS_FAST\n\t\tlen = 4;\n\t#else\n\t\tlen = 0;\n\t#endif\n\t\tlen = lz_extend(in_next, matchptr, len, max_len);\n\t\tif (len > best_len) {\n\t\t\t/* This is the new longest match.  */\n\t\t\tbest_len = len;\n\t\t\tbest_matchptr = matchptr;\n\t\t\tif (best_len >= nice_len)\n\t\t\t\tgoto out;\n\t\t}\n\n\t\t/* Continue to the next node in the list.  */\n\t\tcur_node4 = mf->next_tab[cur_node4 & (MATCHFINDER_WINDOW_SIZE - 1)];\n\t\tif (cur_node4 <= cutoff || !--depth_remaining)\n\t\t\tgoto out;\n\t}\nout:\n\t*offset_ret = in_next - best_matchptr;\n\treturn best_len;\n}\n\n/*\n * Advance the matchfinder, but don't search for matches.\n *\n * @mf\n *\tThe matchfinder structure.\n * @in_base_p\n *\tLocation of a pointer which points to the place in the input data the\n *\tmatchfinder currently stores positions relative to.  This may be updated\n *\tby this function.\n * @in_next\n *\tPointer to the next position in the input buffer.\n * @in_end\n *\tPointer to the end of the input buffer.\n * @count\n *\tThe number of bytes to advance.  Must be > 0.\n * @next_hashes\n *\tThe precomputed hash codes for the sequence beginning at @in_next.\n *\tThese will be used and then updated with the precomputed hashcodes for\n *\tthe sequence beginning at @in_next + @count.\n */\nstatic forceinline void\nhc_matchfinder_skip_bytes(struct hc_matchfinder * const mf,\n\t\t\t  const u8 ** const in_base_p,\n\t\t\t  const u8 *in_next,\n\t\t\t  const u8 * const in_end,\n\t\t\t  const u32 count,\n\t\t\t  u32 * const next_hashes)\n{\n\tu32 cur_pos;\n\tu32 hash3, hash4;\n\tu32 next_hashseq;\n\tu32 remaining = count;\n\n\tif (unlikely(count + 5 > in_end - in_next))\n\t\treturn;\n\n\tcur_pos = in_next - *in_base_p;\n\thash3 = next_hashes[0];\n\thash4 = next_hashes[1];\n\tdo {\n\t\tif (cur_pos == MATCHFINDER_WINDOW_SIZE) {\n\t\t\thc_matchfinder_slide_window(mf);\n\t\t\t*in_base_p += MATCHFINDER_WINDOW_SIZE;\n\t\t\tcur_pos = 0;\n\t\t}\n\t\tmf->hash3_tab[hash3] = cur_pos;\n\t\tmf->next_tab[cur_pos] = mf->hash4_tab[hash4];\n\t\tmf->hash4_tab[hash4] = cur_pos;\n\n\t\tnext_hashseq = get_unaligned_le32(++in_next);\n\t\thash3 = lz_hash(next_hashseq & 0xFFFFFF, HC_MATCHFINDER_HASH3_ORDER);\n\t\thash4 = lz_hash(next_hashseq, HC_MATCHFINDER_HASH4_ORDER);\n\t\tcur_pos++;\n\t} while (--remaining);\n\n\tprefetchw(&mf->hash3_tab[hash3]);\n\tprefetchw(&mf->hash4_tab[hash4]);\n\tnext_hashes[0] = hash3;\n\tnext_hashes[1] = hash4;\n}\n\n#endif /* LIB_HC_MATCHFINDER_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/ht_matchfinder.h",
    "content": "/*\n * ht_matchfinder.h - Lempel-Ziv matchfinding with a hash table\n *\n * Copyright 2022 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * ---------------------------------------------------------------------------\n *\n * This is a Hash Table (ht) matchfinder.\n *\n * This is a variant of the Hash Chains (hc) matchfinder that is optimized for\n * very fast compression.  The ht_matchfinder stores the hash chains inline in\n * the hash table, whereas the hc_matchfinder stores them in a separate array.\n * Storing the hash chains inline is the faster method when max_search_depth\n * (the maximum chain length) is very small.  It is not appropriate when\n * max_search_depth is larger, as then it uses too much memory.\n *\n * Due to its focus on speed, the ht_matchfinder doesn't support length 3\n * matches.  It also doesn't allow max_search_depth to vary at runtime; it is\n * fixed at build time as HT_MATCHFINDER_BUCKET_SIZE.\n *\n * See hc_matchfinder.h for more information.\n */\n\n#ifndef LIB_HT_MATCHFINDER_H\n#define LIB_HT_MATCHFINDER_H\n\n#include \"matchfinder_common.h\"\n\n#define HT_MATCHFINDER_HASH_ORDER\t15\n#define HT_MATCHFINDER_BUCKET_SIZE\t2\n\n#define HT_MATCHFINDER_MIN_MATCH_LEN\t4\n/* Minimum value of max_len for ht_matchfinder_longest_match() */\n#define HT_MATCHFINDER_REQUIRED_NBYTES\t5\n\nstruct MATCHFINDER_ALIGNED ht_matchfinder {\n\tmf_pos_t hash_tab[1UL << HT_MATCHFINDER_HASH_ORDER]\n\t\t\t [HT_MATCHFINDER_BUCKET_SIZE];\n};\n\nstatic forceinline void\nht_matchfinder_init(struct ht_matchfinder *mf)\n{\n\tSTATIC_ASSERT(sizeof(*mf) % MATCHFINDER_SIZE_ALIGNMENT == 0);\n\n\tmatchfinder_init((mf_pos_t *)mf, sizeof(*mf));\n}\n\nstatic forceinline void\nht_matchfinder_slide_window(struct ht_matchfinder *mf)\n{\n\tmatchfinder_rebase((mf_pos_t *)mf, sizeof(*mf));\n}\n\n/* Note: max_len must be >= HT_MATCHFINDER_REQUIRED_NBYTES */\nstatic forceinline u32\nht_matchfinder_longest_match(struct ht_matchfinder * const mf,\n\t\t\t     const u8 ** const in_base_p,\n\t\t\t     const u8 * const in_next,\n\t\t\t     const u32 max_len,\n\t\t\t     const u32 nice_len,\n\t\t\t     u32 * const next_hash,\n\t\t\t     u32 * const offset_ret)\n{\n\tu32 best_len = 0;\n\tconst u8 *best_matchptr = in_next;\n\tu32 cur_pos = in_next - *in_base_p;\n\tconst u8 *in_base;\n\tmf_pos_t cutoff;\n\tu32 hash;\n\tu32 seq;\n\tmf_pos_t cur_node;\n\tconst u8 *matchptr;\n#if HT_MATCHFINDER_BUCKET_SIZE > 1\n\tmf_pos_t to_insert;\n\tu32 len;\n#endif\n#if HT_MATCHFINDER_BUCKET_SIZE > 2\n\tint i;\n#endif\n\n\t/* This is assumed throughout this function. */\n\tSTATIC_ASSERT(HT_MATCHFINDER_MIN_MATCH_LEN == 4);\n\n\tif (cur_pos == MATCHFINDER_WINDOW_SIZE) {\n\t\tht_matchfinder_slide_window(mf);\n\t\t*in_base_p += MATCHFINDER_WINDOW_SIZE;\n\t\tcur_pos = 0;\n\t}\n\tin_base = *in_base_p;\n\tcutoff = cur_pos - MATCHFINDER_WINDOW_SIZE;\n\n\thash = *next_hash;\n\tSTATIC_ASSERT(HT_MATCHFINDER_REQUIRED_NBYTES == 5);\n\t*next_hash = lz_hash(get_unaligned_le32(in_next + 1),\n\t\t\t     HT_MATCHFINDER_HASH_ORDER);\n\tseq = load_u32_unaligned(in_next);\n\tprefetchw(&mf->hash_tab[*next_hash]);\n#if HT_MATCHFINDER_BUCKET_SIZE == 1\n\t/* Hand-unrolled version for BUCKET_SIZE == 1 */\n\tcur_node = mf->hash_tab[hash][0];\n\tmf->hash_tab[hash][0] = cur_pos;\n\tif (cur_node <= cutoff)\n\t\tgoto out;\n\tmatchptr = &in_base[cur_node];\n\tif (load_u32_unaligned(matchptr) == seq) {\n\t\tbest_len = lz_extend(in_next, matchptr, 4, max_len);\n\t\tbest_matchptr = matchptr;\n\t}\n#elif HT_MATCHFINDER_BUCKET_SIZE == 2\n\t/*\n\t * Hand-unrolled version for BUCKET_SIZE == 2.  The logic here also\n\t * differs slightly in that it copies the first entry to the second even\n\t * if nice_len is reached on the first, as this can be slightly faster.\n\t */\n\tcur_node = mf->hash_tab[hash][0];\n\tmf->hash_tab[hash][0] = cur_pos;\n\tif (cur_node <= cutoff)\n\t\tgoto out;\n\tmatchptr = &in_base[cur_node];\n\n\tto_insert = cur_node;\n\tcur_node = mf->hash_tab[hash][1];\n\tmf->hash_tab[hash][1] = to_insert;\n\n\tif (load_u32_unaligned(matchptr) == seq) {\n\t\tbest_len = lz_extend(in_next, matchptr, 4, max_len);\n\t\tbest_matchptr = matchptr;\n\t\tif (cur_node <= cutoff || best_len >= nice_len)\n\t\t\tgoto out;\n\t\tmatchptr = &in_base[cur_node];\n\t\tif (load_u32_unaligned(matchptr) == seq &&\n\t\t    load_u32_unaligned(matchptr + best_len - 3) ==\n\t\t    load_u32_unaligned(in_next + best_len - 3)) {\n\t\t\tlen = lz_extend(in_next, matchptr, 4, max_len);\n\t\t\tif (len > best_len) {\n\t\t\t\tbest_len = len;\n\t\t\t\tbest_matchptr = matchptr;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (cur_node <= cutoff)\n\t\t\tgoto out;\n\t\tmatchptr = &in_base[cur_node];\n\t\tif (load_u32_unaligned(matchptr) == seq) {\n\t\t\tbest_len = lz_extend(in_next, matchptr, 4, max_len);\n\t\t\tbest_matchptr = matchptr;\n\t\t}\n\t}\n#else\n\t/* Generic version for HT_MATCHFINDER_BUCKET_SIZE > 2 */\n\tto_insert = cur_pos;\n\tfor (i = 0; i < HT_MATCHFINDER_BUCKET_SIZE; i++) {\n\t\tcur_node = mf->hash_tab[hash][i];\n\t\tmf->hash_tab[hash][i] = to_insert;\n\t\tif (cur_node <= cutoff)\n\t\t\tgoto out;\n\t\tmatchptr = &in_base[cur_node];\n\t\tif (load_u32_unaligned(matchptr) == seq) {\n\t\t\tlen = lz_extend(in_next, matchptr, 4, max_len);\n\t\t\tif (len > best_len) {\n\t\t\t\tbest_len = len;\n\t\t\t\tbest_matchptr = matchptr;\n\t\t\t\tif (best_len >= nice_len)\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\tto_insert = cur_node;\n\t}\n#endif\nout:\n\t*offset_ret = in_next - best_matchptr;\n\treturn best_len;\n}\n\nstatic forceinline void\nht_matchfinder_skip_bytes(struct ht_matchfinder * const mf,\n\t\t\t  const u8 ** const in_base_p,\n\t\t\t  const u8 *in_next,\n\t\t\t  const u8 * const in_end,\n\t\t\t  const u32 count,\n\t\t\t  u32 * const next_hash)\n{\n\ts32 cur_pos = in_next - *in_base_p;\n\tu32 hash;\n\tu32 remaining = count;\n\tint i;\n\n\tif (unlikely(count + HT_MATCHFINDER_REQUIRED_NBYTES > in_end - in_next))\n\t\treturn;\n\n\tif (cur_pos + count - 1 >= MATCHFINDER_WINDOW_SIZE) {\n\t\tht_matchfinder_slide_window(mf);\n\t\t*in_base_p += MATCHFINDER_WINDOW_SIZE;\n\t\tcur_pos -= MATCHFINDER_WINDOW_SIZE;\n\t}\n\n\thash = *next_hash;\n\tdo {\n\t\tfor (i = HT_MATCHFINDER_BUCKET_SIZE - 1; i > 0; i--)\n\t\t\tmf->hash_tab[hash][i] = mf->hash_tab[hash][i - 1];\n\t\tmf->hash_tab[hash][0] = cur_pos;\n\n\t\thash = lz_hash(get_unaligned_le32(++in_next),\n\t\t\t       HT_MATCHFINDER_HASH_ORDER);\n\t\tcur_pos++;\n\t} while (--remaining);\n\n\tprefetchw(&mf->hash_tab[hash]);\n\t*next_hash = hash;\n}\n\n#endif /* LIB_HT_MATCHFINDER_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/lib_common.h",
    "content": "/*\n * lib_common.h - internal header included by all library code\n */\n\n#ifndef LIB_LIB_COMMON_H\n#define LIB_LIB_COMMON_H\n\n#ifdef LIBDEFLATE_H\n /*\n  * When building the library, LIBDEFLATEAPI needs to be defined properly before\n  * including libdeflate.h.\n  */\n#  error \"lib_common.h must always be included before libdeflate.h\"\n#endif\n\n#if defined(LIBDEFLATE_DLL) && (defined(_WIN32) || defined(__CYGWIN__))\n#  define LIBDEFLATE_EXPORT_SYM  __declspec(dllexport)\n#elif defined(__GNUC__)\n#  define LIBDEFLATE_EXPORT_SYM  __attribute__((visibility(\"default\")))\n#else\n#  define LIBDEFLATE_EXPORT_SYM\n#endif\n\n/*\n * On i386, gcc assumes that the stack is 16-byte aligned at function entry.\n * However, some compilers (e.g. MSVC) and programming languages (e.g. Delphi)\n * only guarantee 4-byte alignment when calling functions.  This is mainly an\n * issue on Windows, but it has been seen on Linux too.  Work around this ABI\n * incompatibility by realigning the stack pointer when entering libdeflate.\n * This prevents crashes in SSE/AVX code.\n */\n#if defined(__GNUC__) && defined(__i386__)\n#  define LIBDEFLATE_ALIGN_STACK  __attribute__((force_align_arg_pointer))\n#else\n#  define LIBDEFLATE_ALIGN_STACK\n#endif\n\n#define LIBDEFLATEAPI\tLIBDEFLATE_EXPORT_SYM LIBDEFLATE_ALIGN_STACK\n\n#include \"../common_defs.h\"\n\ntypedef void *(*malloc_func_t)(size_t);\ntypedef void (*free_func_t)(void *);\n\nextern malloc_func_t libdeflate_default_malloc_func;\nextern free_func_t libdeflate_default_free_func;\n\nvoid *libdeflate_aligned_malloc(malloc_func_t malloc_func,\n\t\t\t\tsize_t alignment, size_t size);\nvoid libdeflate_aligned_free(free_func_t free_func, void *ptr);\n\n#ifdef FREESTANDING\n/*\n * With -ffreestanding, <string.h> may be missing, and we must provide\n * implementations of memset(), memcpy(), memmove(), and memcmp().\n * See https://gcc.gnu.org/onlinedocs/gcc/Standards.html\n *\n * Also, -ffreestanding disables interpreting calls to these functions as\n * built-ins.  E.g., calling memcpy(&v, p, WORDBYTES) will make a function call,\n * not be optimized to a single load instruction.  For performance reasons we\n * don't want that.  So, declare these functions as macros that expand to the\n * corresponding built-ins.  This approach is recommended in the gcc man page.\n * We still need the actual function definitions in case gcc calls them.\n */\nvoid *memset(void *s, int c, size_t n);\n#define memset(s, c, n)\t\t__builtin_memset((s), (c), (n))\n\nvoid *memcpy(void *dest, const void *src, size_t n);\n#define memcpy(dest, src, n)\t__builtin_memcpy((dest), (src), (n))\n\nvoid *memmove(void *dest, const void *src, size_t n);\n#define memmove(dest, src, n)\t__builtin_memmove((dest), (src), (n))\n\nint memcmp(const void *s1, const void *s2, size_t n);\n#define memcmp(s1, s2, n)\t__builtin_memcmp((s1), (s2), (n))\n\n#undef LIBDEFLATE_ENABLE_ASSERTIONS\n#else\n#  include <string.h>\n   /*\n    * To prevent false positive static analyzer warnings, ensure that assertions\n    * are visible to the static analyzer.\n    */\n#  ifdef __clang_analyzer__\n#    define LIBDEFLATE_ENABLE_ASSERTIONS\n#  endif\n#endif\n\n/*\n * Runtime assertion support.  Don't enable this in production builds; it may\n * hurt performance significantly.\n */\n#ifdef LIBDEFLATE_ENABLE_ASSERTIONS\nNORETURN void\nlibdeflate_assertion_failed(const char *expr, const char *file, int line);\n#define ASSERT(expr) { if (unlikely(!(expr))) \\\n\tlibdeflate_assertion_failed(#expr, __FILE__, __LINE__); }\n#else\n#define ASSERT(expr) (void)(expr)\n#endif\n\n#define CONCAT_IMPL(a, b)\ta##b\n#define CONCAT(a, b)\t\tCONCAT_IMPL(a, b)\n#define ADD_SUFFIX(name)\tCONCAT(name, SUFFIX)\n\n#endif /* LIB_LIB_COMMON_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/matchfinder_common.h",
    "content": "/*\n * matchfinder_common.h - common code for Lempel-Ziv matchfinding\n */\n\n#ifndef LIB_MATCHFINDER_COMMON_H\n#define LIB_MATCHFINDER_COMMON_H\n\n#include \"lib_common.h\"\n\n#ifndef MATCHFINDER_WINDOW_ORDER\n#  error \"MATCHFINDER_WINDOW_ORDER must be defined!\"\n#endif\n\n/*\n * Given a 32-bit value that was loaded with the platform's native endianness,\n * return a 32-bit value whose high-order 8 bits are 0 and whose low-order 24\n * bits contain the first 3 bytes, arranged in octets in a platform-dependent\n * order, at the memory location from which the input 32-bit value was loaded.\n */\nstatic forceinline u32\nloaded_u32_to_u24(u32 v)\n{\n\tif (CPU_IS_LITTLE_ENDIAN())\n\t\treturn v & 0xFFFFFF;\n\telse\n\t\treturn v >> 8;\n}\n\n/*\n * Load the next 3 bytes from @p into the 24 low-order bits of a 32-bit value.\n * The order in which the 3 bytes will be arranged as octets in the 24 bits is\n * platform-dependent.  At least 4 bytes (not 3) must be available at @p.\n */\nstatic forceinline u32\nload_u24_unaligned(const u8 *p)\n{\n#if UNALIGNED_ACCESS_IS_FAST\n\treturn loaded_u32_to_u24(load_u32_unaligned(p));\n#else\n\tif (CPU_IS_LITTLE_ENDIAN())\n\t\treturn ((u32)p[0] << 0) | ((u32)p[1] << 8) | ((u32)p[2] << 16);\n\telse\n\t\treturn ((u32)p[2] << 0) | ((u32)p[1] << 8) | ((u32)p[0] << 16);\n#endif\n}\n\n#define MATCHFINDER_WINDOW_SIZE (1UL << MATCHFINDER_WINDOW_ORDER)\n\ntypedef s16 mf_pos_t;\n\n#define MATCHFINDER_INITVAL ((mf_pos_t)-MATCHFINDER_WINDOW_SIZE)\n\n/*\n * This is the memory address alignment, in bytes, required for the matchfinder\n * buffers by the architecture-specific implementations of matchfinder_init()\n * and matchfinder_rebase().  \"Matchfinder buffer\" means an entire struct\n * hc_matchfinder, bt_matchfinder, or ht_matchfinder; the next_tab field of\n * struct hc_matchfinder; or the child_tab field of struct bt_matchfinder.\n *\n * This affects how the entire 'struct deflate_compressor' is allocated, since\n * the matchfinder structures are embedded inside it.\n *\n * Currently the maximum memory address alignment required is 32 bytes, needed\n * by the AVX-2 matchfinder functions.\n */\n#define MATCHFINDER_MEM_ALIGNMENT\t32\n\n/*\n * This declares a size, in bytes, that is guaranteed to divide the sizes of the\n * matchfinder buffers (where \"matchfinder buffers\" is as defined for\n * MATCHFINDER_MEM_ALIGNMENT).  The architecture-specific implementations of\n * matchfinder_init() and matchfinder_rebase() take advantage of this value.\n *\n * Currently the maximum size alignment required is 128 bytes, needed by\n * the AVX-2 matchfinder functions.  However, the RISC-V Vector Extension\n * matchfinder functions can, in principle, take advantage of a larger size\n * alignment.  Therefore, we set this to 1024, which still easily divides the\n * actual sizes that result from the current matchfinder struct definitions.\n * This value can safely be changed to any power of two that is >= 128.\n */\n#define MATCHFINDER_SIZE_ALIGNMENT\t1024\n\n#undef matchfinder_init\n#undef matchfinder_rebase\n#ifdef _aligned_attribute\n#  define MATCHFINDER_ALIGNED _aligned_attribute(MATCHFINDER_MEM_ALIGNMENT)\n#  if defined(ARCH_ARM32) || defined(ARCH_ARM64)\n#    include \"arm/matchfinder_impl.h\"\n#  elif defined(ARCH_RISCV)\n#    include \"riscv/matchfinder_impl.h\"\n#  elif defined(ARCH_X86_32) || defined(ARCH_X86_64)\n#    include \"x86/matchfinder_impl.h\"\n#  endif\n#else\n#  define MATCHFINDER_ALIGNED\n#endif\n\n/*\n * Initialize the hash table portion of the matchfinder.\n *\n * Essentially, this is an optimized memset().\n *\n * 'data' must be aligned to a MATCHFINDER_MEM_ALIGNMENT boundary, and\n * 'size' must be a multiple of MATCHFINDER_SIZE_ALIGNMENT.\n */\n#ifndef matchfinder_init\nstatic forceinline void\nmatchfinder_init(mf_pos_t *data, size_t size)\n{\n\tsize_t num_entries = size / sizeof(*data);\n\tsize_t i;\n\n\tfor (i = 0; i < num_entries; i++)\n\t\tdata[i] = MATCHFINDER_INITVAL;\n}\n#endif\n\n/*\n * Slide the matchfinder by MATCHFINDER_WINDOW_SIZE bytes.\n *\n * This must be called just after each MATCHFINDER_WINDOW_SIZE bytes have been\n * run through the matchfinder.\n *\n * This subtracts MATCHFINDER_WINDOW_SIZE bytes from each entry in the given\n * array, making the entries be relative to the current position rather than the\n * position MATCHFINDER_WINDOW_SIZE bytes prior.  To avoid integer underflows,\n * entries that would become less than -MATCHFINDER_WINDOW_SIZE stay at\n * -MATCHFINDER_WINDOW_SIZE, keeping them permanently out of bounds.\n *\n * The given array must contain all matchfinder data that is position-relative:\n * the hash table(s) as well as any hash chain or binary tree links.  Its\n * address must be aligned to a MATCHFINDER_MEM_ALIGNMENT boundary, and its size\n * must be a multiple of MATCHFINDER_SIZE_ALIGNMENT.\n */\n#ifndef matchfinder_rebase\nstatic forceinline void\nmatchfinder_rebase(mf_pos_t *data, size_t size)\n{\n\tsize_t num_entries = size / sizeof(*data);\n\tsize_t i;\n\n\tif (MATCHFINDER_WINDOW_SIZE == 32768) {\n\t\t/*\n\t\t * Branchless version for 32768-byte windows.  Clear all bits if\n\t\t * the value was already negative, then set the sign bit.  This\n\t\t * is equivalent to subtracting 32768 with signed saturation.\n\t\t */\n\t\tfor (i = 0; i < num_entries; i++)\n\t\t\tdata[i] = 0x8000 | (data[i] & ~(data[i] >> 15));\n\t} else {\n\t\tfor (i = 0; i < num_entries; i++) {\n\t\t\tif (data[i] >= 0)\n\t\t\t\tdata[i] -= (mf_pos_t)-MATCHFINDER_WINDOW_SIZE;\n\t\t\telse\n\t\t\t\tdata[i] = (mf_pos_t)-MATCHFINDER_WINDOW_SIZE;\n\t\t}\n\t}\n}\n#endif\n\n/*\n * The hash function: given a sequence prefix held in the low-order bits of a\n * 32-bit value, multiply by a carefully-chosen large constant.  Discard any\n * bits of the product that don't fit in a 32-bit value, but take the\n * next-highest @num_bits bits of the product as the hash value, as those have\n * the most randomness.\n */\nstatic forceinline u32\nlz_hash(u32 seq, unsigned num_bits)\n{\n\treturn (u32)(seq * 0x1E35A7BD) >> (32 - num_bits);\n}\n\n/*\n * Return the number of bytes at @matchptr that match the bytes at @strptr, up\n * to a maximum of @max_len.  Initially, @start_len bytes are matched.\n */\nstatic forceinline u32\nlz_extend(const u8 * const strptr, const u8 * const matchptr,\n\t  const u32 start_len, const u32 max_len)\n{\n\tu32 len = start_len;\n\tmachine_word_t v_word;\n\n\tif (UNALIGNED_ACCESS_IS_FAST) {\n\n\t\tif (likely(max_len - len >= 4 * WORDBYTES)) {\n\n\t\t#define COMPARE_WORD_STEP\t\t\t\t\\\n\t\t\tv_word = load_word_unaligned(&matchptr[len]) ^\t\\\n\t\t\t\t load_word_unaligned(&strptr[len]);\t\\\n\t\t\tif (v_word != 0)\t\t\t\t\\\n\t\t\t\tgoto word_differs;\t\t\t\\\n\t\t\tlen += WORDBYTES;\t\t\t\t\\\n\n\t\t\tCOMPARE_WORD_STEP\n\t\t\tCOMPARE_WORD_STEP\n\t\t\tCOMPARE_WORD_STEP\n\t\t\tCOMPARE_WORD_STEP\n\t\t#undef COMPARE_WORD_STEP\n\t\t}\n\n\t\twhile (len + WORDBYTES <= max_len) {\n\t\t\tv_word = load_word_unaligned(&matchptr[len]) ^\n\t\t\t\t load_word_unaligned(&strptr[len]);\n\t\t\tif (v_word != 0)\n\t\t\t\tgoto word_differs;\n\t\t\tlen += WORDBYTES;\n\t\t}\n\t}\n\n\twhile (len < max_len && matchptr[len] == strptr[len])\n\t\tlen++;\n\treturn len;\n\nword_differs:\n\tif (CPU_IS_LITTLE_ENDIAN())\n\t\tlen += (bsfw(v_word) >> 3);\n\telse\n\t\tlen += (WORDBITS - 1 - bsrw(v_word)) >> 3;\n\treturn len;\n}\n\n#endif /* LIB_MATCHFINDER_COMMON_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/riscv/matchfinder_impl.h",
    "content": "/*\n * riscv/matchfinder_impl.h - RISC-V implementations of matchfinder functions\n *\n * Copyright 2024 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_RISCV_MATCHFINDER_IMPL_H\n#define LIB_RISCV_MATCHFINDER_IMPL_H\n\n#if defined(ARCH_RISCV) && defined(__riscv_vector)\n#include <riscv_vector.h>\n\n/*\n * Return the maximum number of 16-bit (mf_pos_t) elements that fit in 8 RISC-V\n * vector registers and also evenly divide the sizes of the matchfinder buffers.\n */\nstatic forceinline size_t\nriscv_matchfinder_vl(void)\n{\n\tconst size_t vl = __riscv_vsetvlmax_e16m8();\n\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == sizeof(s16));\n\t/*\n\t * MATCHFINDER_SIZE_ALIGNMENT is a power of 2, as is 'vl' because the\n\t * RISC-V Vector Extension requires that the vector register length\n\t * (VLEN) be a power of 2.  Thus, a simple MIN() gives the correct\n\t * answer here; rounding to a power of 2 is not required.\n\t */\n\tSTATIC_ASSERT((MATCHFINDER_SIZE_ALIGNMENT &\n\t\t       (MATCHFINDER_SIZE_ALIGNMENT - 1)) == 0);\n\tASSERT((vl & (vl - 1)) == 0);\n\treturn MIN(vl, MATCHFINDER_SIZE_ALIGNMENT / sizeof(mf_pos_t));\n}\n\n/* matchfinder_init() optimized using the RISC-V Vector Extension */\nstatic forceinline void\nmatchfinder_init_rvv(mf_pos_t *p, size_t size)\n{\n\tconst size_t vl = riscv_matchfinder_vl();\n\tconst vint16m8_t v = __riscv_vmv_v_x_i16m8(MATCHFINDER_INITVAL, vl);\n\n\tASSERT(size > 0 && size % (vl * sizeof(p[0])) == 0);\n\tdo {\n\t\t__riscv_vse16_v_i16m8(p, v, vl);\n\t\tp += vl;\n\t\tsize -= vl * sizeof(p[0]);\n\t} while (size != 0);\n}\n#define matchfinder_init matchfinder_init_rvv\n\n/* matchfinder_rebase() optimized using the RISC-V Vector Extension */\nstatic forceinline void\nmatchfinder_rebase_rvv(mf_pos_t *p, size_t size)\n{\n\tconst size_t vl = riscv_matchfinder_vl();\n\n\tASSERT(size > 0 && size % (vl * sizeof(p[0])) == 0);\n\tdo {\n\t\tvint16m8_t v = __riscv_vle16_v_i16m8(p, vl);\n\n\t\t/*\n\t\t * This should generate the vsadd.vx instruction\n\t\t * (Vector Saturating Add, integer vector-scalar)\n\t\t */\n\t\tv = __riscv_vsadd_vx_i16m8(v, (s16)-MATCHFINDER_WINDOW_SIZE,\n\t\t\t\t\t   vl);\n\t\t__riscv_vse16_v_i16m8(p, v, vl);\n\t\tp += vl;\n\t\tsize -= vl * sizeof(p[0]);\n\t} while (size != 0);\n}\n#define matchfinder_rebase matchfinder_rebase_rvv\n\n#endif /* ARCH_RISCV && __riscv_vector */\n\n#endif /* LIB_RISCV_MATCHFINDER_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/utils.c",
    "content": "/*\n * utils.c - utility functions for libdeflate\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"lib_common.h\"\n\n#ifdef FREESTANDING\n#  define malloc NULL\n#  define free NULL\n#else\n#  include <stdlib.h>\n#endif\n\nmalloc_func_t libdeflate_default_malloc_func = malloc;\nfree_func_t libdeflate_default_free_func = free;\n\nvoid *\nlibdeflate_aligned_malloc(malloc_func_t malloc_func,\n\t\t\t  size_t alignment, size_t size)\n{\n\tvoid *ptr = (*malloc_func)(sizeof(void *) + alignment - 1 + size);\n\n\tif (ptr) {\n\t\tvoid *orig_ptr = ptr;\n\n\t\tptr = (void *)ALIGN((uintptr_t)ptr + sizeof(void *), alignment);\n\t\t((void **)ptr)[-1] = orig_ptr;\n\t}\n\treturn ptr;\n}\n\nvoid\nlibdeflate_aligned_free(free_func_t free_func, void *ptr)\n{\n\t(*free_func)(((void **)ptr)[-1]);\n}\n\nLIBDEFLATEAPI void\nlibdeflate_set_memory_allocator(malloc_func_t malloc_func,\n\t\t\t\tfree_func_t free_func)\n{\n\tlibdeflate_default_malloc_func = malloc_func;\n\tlibdeflate_default_free_func = free_func;\n}\n\n/*\n * Implementations of libc functions for freestanding library builds.\n * Normal library builds don't use these.  Not optimized yet; usually the\n * compiler expands these functions and doesn't actually call them anyway.\n */\n#ifdef FREESTANDING\n#undef memset\nvoid * __attribute__((weak))\nmemset(void *s, int c, size_t n)\n{\n\tu8 *p = s;\n\tsize_t i;\n\n\tfor (i = 0; i < n; i++)\n\t\tp[i] = c;\n\treturn s;\n}\n\n#undef memcpy\nvoid * __attribute__((weak))\nmemcpy(void *dest, const void *src, size_t n)\n{\n\tu8 *d = dest;\n\tconst u8 *s = src;\n\tsize_t i;\n\n\tfor (i = 0; i < n; i++)\n\t\td[i] = s[i];\n\treturn dest;\n}\n\n#undef memmove\nvoid * __attribute__((weak))\nmemmove(void *dest, const void *src, size_t n)\n{\n\tu8 *d = dest;\n\tconst u8 *s = src;\n\tsize_t i;\n\n\tif (d <= s)\n\t\treturn memcpy(d, s, n);\n\n\tfor (i = n; i > 0; i--)\n\t\td[i - 1] = s[i - 1];\n\treturn dest;\n}\n\n#undef memcmp\nint __attribute__((weak))\nmemcmp(const void *s1, const void *s2, size_t n)\n{\n\tconst u8 *p1 = s1;\n\tconst u8 *p2 = s2;\n\tsize_t i;\n\n\tfor (i = 0; i < n; i++) {\n\t\tif (p1[i] != p2[i])\n\t\t\treturn (int)p1[i] - (int)p2[i];\n\t}\n\treturn 0;\n}\n#endif /* FREESTANDING */\n\n#ifdef LIBDEFLATE_ENABLE_ASSERTIONS\n#include <stdio.h>\n#include <stdlib.h>\nNORETURN void\nlibdeflate_assertion_failed(const char *expr, const char *file, int line)\n{\n\tfprintf(stderr, \"Assertion failed: %s at %s:%d\\n\", expr, file, line);\n\tabort();\n}\n#endif /* LIBDEFLATE_ENABLE_ASSERTIONS */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/adler32_impl.h",
    "content": "/*\n * x86/adler32_impl.h - x86 implementations of Adler-32 checksum algorithm\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_X86_ADLER32_IMPL_H\n#define LIB_X86_ADLER32_IMPL_H\n\n#include \"cpu_features.h\"\n\n/* SSE2 and AVX2 implementations.  Used on older CPUs. */\n#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)\n#  define adler32_x86_sse2\tadler32_x86_sse2\n#  define SUFFIX\t\t\t   _sse2\n#  define ATTRIBUTES\t\t_target_attribute(\"sse2\")\n#  define VL\t\t\t16\n#  define USE_VNNI\t\t0\n#  define USE_AVX512\t\t0\n#  include \"adler32_template.h\"\n\n#  define adler32_x86_avx2\tadler32_x86_avx2\n#  define SUFFIX\t\t\t   _avx2\n#  define ATTRIBUTES\t\t_target_attribute(\"avx2\")\n#  define VL\t\t\t32\n#  define USE_VNNI\t\t0\n#  define USE_AVX512\t\t0\n#  include \"adler32_template.h\"\n#endif\n\n/*\n * AVX-VNNI implementation.  This is used on CPUs that have AVX2 and AVX-VNNI\n * but don't have AVX-512, for example Intel Alder Lake.\n *\n * Unusually for a new CPU feature, gcc added support for the AVX-VNNI\n * intrinsics (in gcc 11.1) slightly before binutils added support for\n * assembling AVX-VNNI instructions (in binutils 2.36).  Distros can reasonably\n * have gcc 11 with binutils 2.35.  Because of this issue, we check for gcc 12\n * instead of gcc 11.  (libdeflate supports direct compilation without a\n * configure step, so checking the binutils version is not always an option.)\n */\n#if (GCC_PREREQ(12, 1) || CLANG_PREREQ(12, 0, 13000000) || MSVC_PREREQ(1930)) && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_AVX_VNNI)\n#  define adler32_x86_avx2_vnni\tadler32_x86_avx2_vnni\n#  define SUFFIX\t\t\t   _avx2_vnni\n#  define ATTRIBUTES\t\t_target_attribute(\"avx2,avxvnni\")\n#  define VL\t\t\t32\n#  define USE_VNNI\t\t1\n#  define USE_AVX512\t\t0\n#  include \"adler32_template.h\"\n#endif\n\n#if (GCC_PREREQ(8, 1) || CLANG_PREREQ(6, 0, 10000000) || MSVC_PREREQ(1920)) && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_AVX512VNNI)\n/*\n * AVX512VNNI implementation using 256-bit vectors.  This is very similar to the\n * AVX-VNNI implementation but takes advantage of masking and more registers.\n * This is used on certain older Intel CPUs, specifically Ice Lake and Tiger\n * Lake, which support AVX512VNNI but downclock a bit too eagerly when ZMM\n * registers are used.\n */\n#  define adler32_x86_avx512_vl256_vnni\tadler32_x86_avx512_vl256_vnni\n#  define SUFFIX\t\t\t\t   _avx512_vl256_vnni\n#  define ATTRIBUTES\t\t_target_attribute(\"avx512bw,avx512vl,avx512vnni\")\n#  define VL\t\t\t32\n#  define USE_VNNI\t\t1\n#  define USE_AVX512\t\t1\n#  include \"adler32_template.h\"\n\n/*\n * AVX512VNNI implementation using 512-bit vectors.  This is used on CPUs that\n * have a good AVX-512 implementation including AVX512VNNI.\n */\n#  define adler32_x86_avx512_vl512_vnni\tadler32_x86_avx512_vl512_vnni\n#  define SUFFIX\t\t\t\t   _avx512_vl512_vnni\n#  define ATTRIBUTES\t\t_target_attribute(\"avx512bw,avx512vnni\")\n#  define VL\t\t\t64\n#  define USE_VNNI\t\t1\n#  define USE_AVX512\t\t1\n#  include \"adler32_template.h\"\n#endif\n\nstatic inline adler32_func_t\narch_select_adler32_func(void)\n{\n\tconst u32 features MAYBE_UNUSED = get_x86_cpu_features();\n\n#ifdef adler32_x86_avx512_vl512_vnni\n\tif ((features & X86_CPU_FEATURE_ZMM) &&\n\t    HAVE_AVX512BW(features) && HAVE_AVX512VNNI(features))\n\t\treturn adler32_x86_avx512_vl512_vnni;\n#endif\n#ifdef adler32_x86_avx512_vl256_vnni\n\tif (HAVE_AVX512BW(features) && HAVE_AVX512VL(features) &&\n\t    HAVE_AVX512VNNI(features))\n\t\treturn adler32_x86_avx512_vl256_vnni;\n#endif\n#ifdef adler32_x86_avx2_vnni\n\tif (HAVE_AVX2(features) && HAVE_AVXVNNI(features))\n\t\treturn adler32_x86_avx2_vnni;\n#endif\n#ifdef adler32_x86_avx2\n\tif (HAVE_AVX2(features))\n\t\treturn adler32_x86_avx2;\n#endif\n#ifdef adler32_x86_sse2\n\tif (HAVE_SSE2(features))\n\t\treturn adler32_x86_sse2;\n#endif\n\treturn NULL;\n}\n#define arch_select_adler32_func\tarch_select_adler32_func\n\n#endif /* LIB_X86_ADLER32_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/adler32_template.h",
    "content": "/*\n * x86/adler32_template.h - template for vectorized Adler-32 implementations\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * This file is a \"template\" for instantiating Adler-32 functions for x86.\n * The \"parameters\" are:\n *\n * SUFFIX:\n *\tName suffix to append to all instantiated functions.\n * ATTRIBUTES:\n *\tTarget function attributes to use.  Must satisfy the dependencies of the\n *\tother parameters as follows:\n *\t   VL=16 && USE_VNNI=0 && USE_AVX512=0: at least sse2\n *\t   VL=32 && USE_VNNI=0 && USE_AVX512=0: at least avx2\n *\t   VL=32 && USE_VNNI=1 && USE_AVX512=0: at least avx2,avxvnni\n *\t   VL=32 && USE_VNNI=1 && USE_AVX512=1: at least avx512bw,avx512vl,avx512vnni\n *\t   VL=64 && USE_VNNI=1 && USE_AVX512=1: at least avx512bw,avx512vnni\n *\t   (Other combinations are not useful and have not been tested.)\n * VL:\n *\tVector length in bytes.  Must be 16, 32, or 64.\n * USE_VNNI:\n *\tIf 1, use the VNNI dot product based algorithm.\n *\tIf 0, use the legacy SSE2 and AVX2 compatible algorithm.\n * USE_AVX512:\n *\tIf 1, take advantage of AVX-512 features such as masking.  This doesn't\n *\tenable the use of 512-bit vectors; the vector length is controlled by\n *\tVL.  If 0, assume that the CPU might not support AVX-512.\n */\n\n#if VL == 16\n#  define vec_t\t\t\t__m128i\n#  define mask_t\t\tu16\n#  define LOG2_VL\t\t4\n#  define VADD8(a, b)\t\t_mm_add_epi8((a), (b))\n#  define VADD16(a, b)\t\t_mm_add_epi16((a), (b))\n#  define VADD32(a, b)\t\t_mm_add_epi32((a), (b))\n#  if USE_AVX512\n#    define VDPBUSD(a, b, c)\t_mm_dpbusd_epi32((a), (b), (c))\n#  else\n#    define VDPBUSD(a, b, c)\t_mm_dpbusd_avx_epi32((a), (b), (c))\n#  endif\n#  define VLOAD(p)\t\t_mm_load_si128((const void *)(p))\n#  define VLOADU(p)\t\t_mm_loadu_si128((const void *)(p))\n#  define VMADD16(a, b)\t\t_mm_madd_epi16((a), (b))\n#  define VMASKZ_LOADU(mask, p) _mm_maskz_loadu_epi8((mask), (p))\n#  define VMULLO32(a, b)\t_mm_mullo_epi32((a), (b))\n#  define VSAD8(a, b)\t\t_mm_sad_epu8((a), (b))\n#  define VSET1_8(a)\t\t_mm_set1_epi8(a)\n#  define VSET1_32(a)\t\t_mm_set1_epi32(a)\n#  define VSETZERO()\t\t_mm_setzero_si128()\n#  define VSLL32(a, b)\t\t_mm_slli_epi32((a), (b))\n#  define VUNPACKLO8(a, b)\t_mm_unpacklo_epi8((a), (b))\n#  define VUNPACKHI8(a, b)\t_mm_unpackhi_epi8((a), (b))\n#elif VL == 32\n#  define vec_t\t\t\t__m256i\n#  define mask_t\t\tu32\n#  define LOG2_VL\t\t5\n#  define VADD8(a, b)\t\t_mm256_add_epi8((a), (b))\n#  define VADD16(a, b)\t\t_mm256_add_epi16((a), (b))\n#  define VADD32(a, b)\t\t_mm256_add_epi32((a), (b))\n#  if USE_AVX512\n#    define VDPBUSD(a, b, c)\t_mm256_dpbusd_epi32((a), (b), (c))\n#  else\n#    define VDPBUSD(a, b, c)\t_mm256_dpbusd_avx_epi32((a), (b), (c))\n#  endif\n#  define VLOAD(p)\t\t_mm256_load_si256((const void *)(p))\n#  define VLOADU(p)\t\t_mm256_loadu_si256((const void *)(p))\n#  define VMADD16(a, b)\t\t_mm256_madd_epi16((a), (b))\n#  define VMASKZ_LOADU(mask, p) _mm256_maskz_loadu_epi8((mask), (p))\n#  define VMULLO32(a, b)\t_mm256_mullo_epi32((a), (b))\n#  define VSAD8(a, b)\t\t_mm256_sad_epu8((a), (b))\n#  define VSET1_8(a)\t\t_mm256_set1_epi8(a)\n#  define VSET1_32(a)\t\t_mm256_set1_epi32(a)\n#  define VSETZERO()\t\t_mm256_setzero_si256()\n#  define VSLL32(a, b)\t\t_mm256_slli_epi32((a), (b))\n#  define VUNPACKLO8(a, b)\t_mm256_unpacklo_epi8((a), (b))\n#  define VUNPACKHI8(a, b)\t_mm256_unpackhi_epi8((a), (b))\n#elif VL == 64\n#  define vec_t\t\t\t__m512i\n#  define mask_t\t\tu64\n#  define LOG2_VL\t\t6\n#  define VADD8(a, b)\t\t_mm512_add_epi8((a), (b))\n#  define VADD16(a, b)\t\t_mm512_add_epi16((a), (b))\n#  define VADD32(a, b)\t\t_mm512_add_epi32((a), (b))\n#  define VDPBUSD(a, b, c)\t_mm512_dpbusd_epi32((a), (b), (c))\n#  define VLOAD(p)\t\t_mm512_load_si512((const void *)(p))\n#  define VLOADU(p)\t\t_mm512_loadu_si512((const void *)(p))\n#  define VMADD16(a, b)\t\t_mm512_madd_epi16((a), (b))\n#  define VMASKZ_LOADU(mask, p) _mm512_maskz_loadu_epi8((mask), (p))\n#  define VMULLO32(a, b)\t_mm512_mullo_epi32((a), (b))\n#  define VSAD8(a, b)\t\t_mm512_sad_epu8((a), (b))\n#  define VSET1_8(a)\t\t_mm512_set1_epi8(a)\n#  define VSET1_32(a)\t\t_mm512_set1_epi32(a)\n#  define VSETZERO()\t\t_mm512_setzero_si512()\n#  define VSLL32(a, b)\t\t_mm512_slli_epi32((a), (b))\n#  define VUNPACKLO8(a, b)\t_mm512_unpacklo_epi8((a), (b))\n#  define VUNPACKHI8(a, b)\t_mm512_unpackhi_epi8((a), (b))\n#else\n#  error \"unsupported vector length\"\n#endif\n\n#define VADD32_3X(a, b, c)\tVADD32(VADD32((a), (b)), (c))\n#define VADD32_4X(a, b, c, d)\tVADD32(VADD32((a), (b)), VADD32((c), (d)))\n#define VADD32_5X(a, b, c, d, e) VADD32((a), VADD32_4X((b), (c), (d), (e)))\n#define VADD32_7X(a, b, c, d, e, f, g)\t\\\n\tVADD32(VADD32_3X((a), (b), (c)), VADD32_4X((d), (e), (f), (g)))\n\n/* Sum the 32-bit elements of v_s1 and add them to s1, and likewise for s2. */\n#undef reduce_to_32bits\nstatic forceinline ATTRIBUTES void\nADD_SUFFIX(reduce_to_32bits)(vec_t v_s1, vec_t v_s2, u32 *s1_p, u32 *s2_p)\n{\n\t__m128i v_s1_128, v_s2_128;\n#if VL == 16\n\t{\n\t\tv_s1_128 = v_s1;\n\t\tv_s2_128 = v_s2;\n\t}\n#else\n\t{\n\t\t__m256i v_s1_256, v_s2_256;\n\t#if VL == 32\n\t\tv_s1_256 = v_s1;\n\t\tv_s2_256 = v_s2;\n\t#else\n\t\t/* Reduce 512 bits to 256 bits. */\n\t\tv_s1_256 = _mm256_add_epi32(_mm512_extracti64x4_epi64(v_s1, 0),\n\t\t\t\t\t    _mm512_extracti64x4_epi64(v_s1, 1));\n\t\tv_s2_256 = _mm256_add_epi32(_mm512_extracti64x4_epi64(v_s2, 0),\n\t\t\t\t\t    _mm512_extracti64x4_epi64(v_s2, 1));\n\t#endif\n\t\t/* Reduce 256 bits to 128 bits. */\n\t\tv_s1_128 = _mm_add_epi32(_mm256_extracti128_si256(v_s1_256, 0),\n\t\t\t\t\t _mm256_extracti128_si256(v_s1_256, 1));\n\t\tv_s2_128 = _mm_add_epi32(_mm256_extracti128_si256(v_s2_256, 0),\n\t\t\t\t\t _mm256_extracti128_si256(v_s2_256, 1));\n\t}\n#endif\n\n\t/*\n\t * Reduce 128 bits to 32 bits.\n\t *\n\t * If the bytes were summed into v_s1 using psadbw + paddd, then ignore\n\t * the odd-indexed elements of v_s1_128 since they are zero.\n\t */\n#if USE_VNNI\n\tv_s1_128 = _mm_add_epi32(v_s1_128, _mm_shuffle_epi32(v_s1_128, 0x31));\n#endif\n\tv_s2_128 = _mm_add_epi32(v_s2_128, _mm_shuffle_epi32(v_s2_128, 0x31));\n\tv_s1_128 = _mm_add_epi32(v_s1_128, _mm_shuffle_epi32(v_s1_128, 0x02));\n\tv_s2_128 = _mm_add_epi32(v_s2_128, _mm_shuffle_epi32(v_s2_128, 0x02));\n\n\t*s1_p += (u32)_mm_cvtsi128_si32(v_s1_128);\n\t*s2_p += (u32)_mm_cvtsi128_si32(v_s2_128);\n}\n#define reduce_to_32bits\tADD_SUFFIX(reduce_to_32bits)\n\nstatic ATTRIBUTES u32\nADD_SUFFIX(adler32_x86)(u32 adler, const u8 *p, size_t len)\n{\n#if USE_VNNI\n\t/* This contains the bytes [VL, VL-1, VL-2, ..., 1]. */\n\tstatic const u8 _aligned_attribute(VL) raw_mults[VL] = {\n\t#if VL == 64\n\t\t64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,\n\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,\n\t#endif\n\t#if VL >= 32\n\t\t32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n\t#endif\n\t\t16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n\t};\n\tconst vec_t ones = VSET1_8(1);\n#else\n\t/*\n\t * This contains the 16-bit values [2*VL, 2*VL - 1, 2*VL - 2, ..., 1].\n\t * For VL==32 the ordering is weird because it has to match the way that\n\t * vpunpcklbw and vpunpckhbw work on 128-bit lanes separately.\n\t */\n\tstatic const u16 _aligned_attribute(VL) raw_mults[4][VL / 2] = {\n\t#if VL == 16\n\t\t{ 32, 31, 30, 29, 28, 27, 26, 25 },\n\t\t{ 24, 23, 22, 21, 20, 19, 18, 17 },\n\t\t{ 16, 15, 14, 13, 12, 11, 10, 9  },\n\t\t{ 8,  7,  6,  5,  4,  3,  2,  1  },\n\t#elif VL == 32\n\t\t{ 64, 63, 62, 61, 60, 59, 58, 57, 48, 47, 46, 45, 44, 43, 42, 41 },\n\t\t{ 56, 55, 54, 53, 52, 51, 50, 49, 40, 39, 38, 37, 36, 35, 34, 33 },\n\t\t{ 32, 31, 30, 29, 28, 27, 26, 25, 16, 15, 14, 13, 12, 11, 10,  9 },\n\t\t{ 24, 23, 22, 21, 20, 19, 18, 17,  8,  7,  6,  5,  4,  3,  2,  1 },\n\t#else\n\t#  error \"unsupported parameters\"\n\t#endif\n\t};\n\tconst vec_t mults_a = VLOAD(raw_mults[0]);\n\tconst vec_t mults_b = VLOAD(raw_mults[1]);\n\tconst vec_t mults_c = VLOAD(raw_mults[2]);\n\tconst vec_t mults_d = VLOAD(raw_mults[3]);\n#endif\n\tconst vec_t zeroes = VSETZERO();\n\tu32 s1 = adler & 0xFFFF;\n\tu32 s2 = adler >> 16;\n\n\t/*\n\t * If the length is large and the pointer is misaligned, align it.\n\t * For smaller lengths, just take the misaligned load penalty.\n\t */\n\tif (unlikely(len > 65536 && ((uintptr_t)p & (VL-1)))) {\n\t\tdo {\n\t\t\ts1 += *p++;\n\t\t\ts2 += s1;\n\t\t\tlen--;\n\t\t} while ((uintptr_t)p & (VL-1));\n\t\ts1 %= DIVISOR;\n\t\ts2 %= DIVISOR;\n\t}\n\n#if USE_VNNI\n\t/*\n\t * This is Adler-32 using the vpdpbusd instruction from AVX512VNNI or\n\t * AVX-VNNI.  vpdpbusd multiplies the unsigned bytes of one vector by\n\t * the signed bytes of another vector and adds the sums in groups of 4\n\t * to the 32-bit elements of a third vector.  We use it in two ways:\n\t * multiplying the data bytes by a sequence like 64,63,62,...,1 for\n\t * calculating part of s2, and multiplying the data bytes by an all-ones\n\t * sequence 1,1,1,...,1 for calculating s1 and part of s2.  The all-ones\n\t * trick seems to be faster than the alternative of vpsadbw + vpaddd.\n\t */\n\twhile (len) {\n\t\t/*\n\t\t * Calculate the length of the next data chunk such that s1 and\n\t\t * s2 are guaranteed to not exceed UINT32_MAX.\n\t\t */\n\t\tsize_t n = MIN(len, MAX_CHUNK_LEN & ~(4*VL - 1));\n\t\tvec_t mults = VLOAD(raw_mults);\n\t\tvec_t v_s1 = zeroes;\n\t\tvec_t v_s2 = zeroes;\n\n\t\ts2 += s1 * n;\n\t\tlen -= n;\n\n\t\tif (n >= 4*VL) {\n\t\t\tvec_t v_s1_b = zeroes;\n\t\t\tvec_t v_s1_c = zeroes;\n\t\t\tvec_t v_s1_d = zeroes;\n\t\t\tvec_t v_s2_b = zeroes;\n\t\t\tvec_t v_s2_c = zeroes;\n\t\t\tvec_t v_s2_d = zeroes;\n\t\t\tvec_t v_s1_sums   = zeroes;\n\t\t\tvec_t v_s1_sums_b = zeroes;\n\t\t\tvec_t v_s1_sums_c = zeroes;\n\t\t\tvec_t v_s1_sums_d = zeroes;\n\t\t\tvec_t tmp0, tmp1;\n\n\t\t\tdo {\n\t\t\t\tvec_t data_a = VLOADU(p + 0*VL);\n\t\t\t\tvec_t data_b = VLOADU(p + 1*VL);\n\t\t\t\tvec_t data_c = VLOADU(p + 2*VL);\n\t\t\t\tvec_t data_d = VLOADU(p + 3*VL);\n\n\t\t\t\t/*\n\t\t\t\t * Workaround for gcc bug where it generates\n\t\t\t\t * unnecessary move instructions\n\t\t\t\t * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107892)\n\t\t\t\t */\n\t\t\t#if GCC_PREREQ(1, 0)\n\t\t\t\t__asm__(\"\" : \"+v\" (data_a), \"+v\" (data_b),\n\t\t\t\t\t     \"+v\" (data_c), \"+v\" (data_d));\n\t\t\t#endif\n\n\t\t\t\tv_s2   = VDPBUSD(v_s2,   data_a, mults);\n\t\t\t\tv_s2_b = VDPBUSD(v_s2_b, data_b, mults);\n\t\t\t\tv_s2_c = VDPBUSD(v_s2_c, data_c, mults);\n\t\t\t\tv_s2_d = VDPBUSD(v_s2_d, data_d, mults);\n\n\t\t\t\tv_s1_sums   = VADD32(v_s1_sums,   v_s1);\n\t\t\t\tv_s1_sums_b = VADD32(v_s1_sums_b, v_s1_b);\n\t\t\t\tv_s1_sums_c = VADD32(v_s1_sums_c, v_s1_c);\n\t\t\t\tv_s1_sums_d = VADD32(v_s1_sums_d, v_s1_d);\n\n\t\t\t\tv_s1   = VDPBUSD(v_s1,   data_a, ones);\n\t\t\t\tv_s1_b = VDPBUSD(v_s1_b, data_b, ones);\n\t\t\t\tv_s1_c = VDPBUSD(v_s1_c, data_c, ones);\n\t\t\t\tv_s1_d = VDPBUSD(v_s1_d, data_d, ones);\n\n\t\t\t\t/* Same gcc bug workaround.  See above */\n\t\t\t#if GCC_PREREQ(1, 0) && !defined(ARCH_X86_32)\n\t\t\t\t__asm__(\"\" : \"+v\" (v_s2), \"+v\" (v_s2_b),\n\t\t\t\t\t     \"+v\" (v_s2_c), \"+v\" (v_s2_d),\n\t\t\t\t\t     \"+v\" (v_s1_sums),\n\t\t\t\t\t     \"+v\" (v_s1_sums_b),\n\t\t\t\t\t     \"+v\" (v_s1_sums_c),\n\t\t\t\t\t     \"+v\" (v_s1_sums_d),\n\t\t\t\t\t     \"+v\" (v_s1), \"+v\" (v_s1_b),\n\t\t\t\t\t     \"+v\" (v_s1_c), \"+v\" (v_s1_d));\n\t\t\t#endif\n\t\t\t\tp += 4*VL;\n\t\t\t\tn -= 4*VL;\n\t\t\t} while (n >= 4*VL);\n\n\t\t\t/*\n\t\t\t * Reduce into v_s1 and v_s2 as follows:\n\t\t\t *\n\t\t\t * v_s2 = v_s2 + v_s2_b + v_s2_c + v_s2_d +\n\t\t\t *\t  (4*VL)*(v_s1_sums   + v_s1_sums_b +\n\t\t\t *\t\t  v_s1_sums_c + v_s1_sums_d) +\n\t\t\t *\t  (3*VL)*v_s1 + (2*VL)*v_s1_b + VL*v_s1_c\n\t\t\t * v_s1 = v_s1 + v_s1_b + v_s1_c + v_s1_d\n\t\t\t */\n\t\t\ttmp0 = VADD32(v_s1, v_s1_b);\n\t\t\ttmp1 = VADD32(v_s1, v_s1_c);\n\t\t\tv_s1_sums = VADD32_4X(v_s1_sums, v_s1_sums_b,\n\t\t\t\t\t      v_s1_sums_c, v_s1_sums_d);\n\t\t\tv_s1 = VADD32_3X(tmp0, v_s1_c, v_s1_d);\n\t\t\tv_s2 = VADD32_7X(VSLL32(v_s1_sums, LOG2_VL + 2),\n\t\t\t\t\t VSLL32(tmp0, LOG2_VL + 1),\n\t\t\t\t\t VSLL32(tmp1, LOG2_VL),\n\t\t\t\t\t v_s2, v_s2_b, v_s2_c, v_s2_d);\n\t\t}\n\n\t\t/* Process the last 0 <= n < 4*VL bytes of the chunk. */\n\t\tif (n >= 2*VL) {\n\t\t\tconst vec_t data_a = VLOADU(p + 0*VL);\n\t\t\tconst vec_t data_b = VLOADU(p + 1*VL);\n\n\t\t\tv_s2 = VADD32(v_s2, VSLL32(v_s1, LOG2_VL + 1));\n\t\t\tv_s1 = VDPBUSD(v_s1, data_a, ones);\n\t\t\tv_s1 = VDPBUSD(v_s1, data_b, ones);\n\t\t\tv_s2 = VDPBUSD(v_s2, data_a, VSET1_8(VL));\n\t\t\tv_s2 = VDPBUSD(v_s2, data_a, mults);\n\t\t\tv_s2 = VDPBUSD(v_s2, data_b, mults);\n\t\t\tp += 2*VL;\n\t\t\tn -= 2*VL;\n\t\t}\n\t\tif (n) {\n\t\t\t/* Process the last 0 < n < 2*VL bytes of the chunk. */\n\t\t\tvec_t data;\n\n\t\t\tv_s2 = VADD32(v_s2, VMULLO32(v_s1, VSET1_32(n)));\n\n\t\t\tmults = VADD8(mults, VSET1_8((int)n - VL));\n\t\t\tif (n > VL) {\n\t\t\t\tdata = VLOADU(p);\n\t\t\t\tv_s1 = VDPBUSD(v_s1, data, ones);\n\t\t\t\tv_s2 = VDPBUSD(v_s2, data, mults);\n\t\t\t\tp += VL;\n\t\t\t\tn -= VL;\n\t\t\t\tmults = VADD8(mults, VSET1_8(-VL));\n\t\t\t}\n\t\t\t/*\n\t\t\t * Process the last 0 < n <= VL bytes of the chunk.\n\t\t\t * Utilize a masked load if it's available.\n\t\t\t */\n\t\t#if USE_AVX512\n\t\t\tdata = VMASKZ_LOADU((mask_t)-1 >> (VL - n), p);\n\t\t#else\n\t\t\tdata = zeroes;\n\t\t\tmemcpy(&data, p, n);\n\t\t#endif\n\t\t\tv_s1 = VDPBUSD(v_s1, data, ones);\n\t\t\tv_s2 = VDPBUSD(v_s2, data, mults);\n\t\t\tp += n;\n\t\t}\n\n\t\treduce_to_32bits(v_s1, v_s2, &s1, &s2);\n\t\ts1 %= DIVISOR;\n\t\ts2 %= DIVISOR;\n\t}\n#else /* USE_VNNI */\n\t/*\n\t * This is Adler-32 for SSE2 and AVX2.\n\t *\n\t * To horizontally sum bytes, use psadbw + paddd, where one of the\n\t * arguments to psadbw is all-zeroes.\n\t *\n\t * For the s2 contribution from (2*VL - i)*data[i] for each of the 2*VL\n\t * bytes of each iteration of the inner loop, use punpck{l,h}bw + paddw\n\t * to sum, for each i across iterations, byte i into a corresponding\n\t * 16-bit counter in v_byte_sums_*.  After the inner loop, use pmaddwd\n\t * to multiply each counter by (2*VL - i), then add the products to s2.\n\t *\n\t * An alternative implementation would use pmaddubsw and pmaddwd in the\n\t * inner loop to do (2*VL - i)*data[i] directly and add the products in\n\t * groups of 4 to 32-bit counters.  However, on average that approach\n\t * seems to be slower than the current approach which delays the\n\t * multiplications.  Also, pmaddubsw requires SSSE3; the current\n\t * approach keeps the implementation aligned between SSE2 and AVX2.\n\t *\n\t * The inner loop processes 2*VL bytes per iteration.  Increasing this\n\t * to 4*VL doesn't seem to be helpful here.\n\t */\n\twhile (len) {\n\t\t/*\n\t\t * Calculate the length of the next data chunk such that s1 and\n\t\t * s2 are guaranteed to not exceed UINT32_MAX, and every\n\t\t * v_byte_sums_* counter is guaranteed to not exceed INT16_MAX.\n\t\t * It's INT16_MAX, not UINT16_MAX, because v_byte_sums_* are\n\t\t * used with pmaddwd which does signed multiplication.  In the\n\t\t * SSE2 case this limits chunks to 4096 bytes instead of 5536.\n\t\t */\n\t\tsize_t n = MIN(len, MIN(2 * VL * (INT16_MAX / UINT8_MAX),\n\t\t\t\t\tMAX_CHUNK_LEN) & ~(2*VL - 1));\n\t\tlen -= n;\n\n\t\tif (n >= 2*VL) {\n\t\t\tvec_t v_s1 = zeroes;\n\t\t\tvec_t v_s1_sums = zeroes;\n\t\t\tvec_t v_byte_sums_a = zeroes;\n\t\t\tvec_t v_byte_sums_b = zeroes;\n\t\t\tvec_t v_byte_sums_c = zeroes;\n\t\t\tvec_t v_byte_sums_d = zeroes;\n\t\t\tvec_t v_s2;\n\n\t\t\ts2 += s1 * (n & ~(2*VL - 1));\n\n\t\t\tdo {\n\t\t\t\tvec_t data_a = VLOADU(p + 0*VL);\n\t\t\t\tvec_t data_b = VLOADU(p + 1*VL);\n\n\t\t\t\tv_s1_sums = VADD32(v_s1_sums, v_s1);\n\t\t\t\tv_byte_sums_a = VADD16(v_byte_sums_a,\n\t\t\t\t\t\t       VUNPACKLO8(data_a, zeroes));\n\t\t\t\tv_byte_sums_b = VADD16(v_byte_sums_b,\n\t\t\t\t\t\t       VUNPACKHI8(data_a, zeroes));\n\t\t\t\tv_byte_sums_c = VADD16(v_byte_sums_c,\n\t\t\t\t\t\t       VUNPACKLO8(data_b, zeroes));\n\t\t\t\tv_byte_sums_d = VADD16(v_byte_sums_d,\n\t\t\t\t\t\t       VUNPACKHI8(data_b, zeroes));\n\t\t\t\tv_s1 = VADD32(v_s1,\n\t\t\t\t\t      VADD32(VSAD8(data_a, zeroes),\n\t\t\t\t\t\t     VSAD8(data_b, zeroes)));\n\t\t\t\t/*\n\t\t\t\t * Workaround for gcc bug where it generates\n\t\t\t\t * unnecessary move instructions\n\t\t\t\t * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107892)\n\t\t\t\t */\n\t\t\t#if GCC_PREREQ(1, 0)\n\t\t\t\t__asm__(\"\" : \"+x\" (v_s1), \"+x\" (v_s1_sums),\n\t\t\t\t\t     \"+x\" (v_byte_sums_a),\n\t\t\t\t\t     \"+x\" (v_byte_sums_b),\n\t\t\t\t\t     \"+x\" (v_byte_sums_c),\n\t\t\t\t\t     \"+x\" (v_byte_sums_d));\n\t\t\t#endif\n\t\t\t\tp += 2*VL;\n\t\t\t\tn -= 2*VL;\n\t\t\t} while (n >= 2*VL);\n\n\t\t\t/*\n\t\t\t * Calculate v_s2 as (2*VL)*v_s1_sums +\n\t\t\t * [2*VL, 2*VL - 1, 2*VL - 2, ..., 1] * v_byte_sums.\n\t\t\t * Then update s1 and s2 from v_s1 and v_s2.\n\t\t\t */\n\t\t\tv_s2 = VADD32_5X(VSLL32(v_s1_sums, LOG2_VL + 1),\n\t\t\t\t\t VMADD16(v_byte_sums_a, mults_a),\n\t\t\t\t\t VMADD16(v_byte_sums_b, mults_b),\n\t\t\t\t\t VMADD16(v_byte_sums_c, mults_c),\n\t\t\t\t\t VMADD16(v_byte_sums_d, mults_d));\n\t\t\treduce_to_32bits(v_s1, v_s2, &s1, &s2);\n\t\t}\n\t\t/*\n\t\t * Process the last 0 <= n < 2*VL bytes of the chunk using\n\t\t * scalar instructions and reduce s1 and s2 mod DIVISOR.\n\t\t */\n\t\tADLER32_CHUNK(s1, s2, p, n);\n\t}\n#endif /* !USE_VNNI */\n\treturn (s2 << 16) | s1;\n}\n\n#undef vec_t\n#undef mask_t\n#undef LOG2_VL\n#undef VADD8\n#undef VADD16\n#undef VADD32\n#undef VDPBUSD\n#undef VLOAD\n#undef VLOADU\n#undef VMADD16\n#undef VMASKZ_LOADU\n#undef VMULLO32\n#undef VSAD8\n#undef VSET1_8\n#undef VSET1_32\n#undef VSETZERO\n#undef VSLL32\n#undef VUNPACKLO8\n#undef VUNPACKHI8\n\n#undef SUFFIX\n#undef ATTRIBUTES\n#undef VL\n#undef USE_VNNI\n#undef USE_AVX512\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/cpu_features.c",
    "content": "/*\n * x86/cpu_features.c - feature detection for x86 CPUs\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"../cpu_features_common.h\" /* must be included first */\n#include \"cpu_features.h\"\n\n#ifdef X86_CPU_FEATURES_KNOWN\n/* Runtime x86 CPU feature detection is supported. */\n\n/* Execute the CPUID instruction. */\nstatic inline void\ncpuid(u32 leaf, u32 subleaf, u32 *a, u32 *b, u32 *c, u32 *d)\n{\n#ifdef _MSC_VER\n\tint result[4];\n\n\t__cpuidex(result, leaf, subleaf);\n\t*a = result[0];\n\t*b = result[1];\n\t*c = result[2];\n\t*d = result[3];\n#else\n\t__asm__ volatile(\"cpuid\" : \"=a\" (*a), \"=b\" (*b), \"=c\" (*c), \"=d\" (*d)\n\t\t\t : \"a\" (leaf), \"c\" (subleaf));\n#endif\n}\n\n/* Read an extended control register. */\nstatic inline u64\nread_xcr(u32 index)\n{\n#ifdef _MSC_VER\n\treturn _xgetbv(index);\n#else\n\tu32 d, a;\n\n\t/*\n\t * Execute the \"xgetbv\" instruction.  Old versions of binutils do not\n\t * recognize this instruction, so list the raw bytes instead.\n\t *\n\t * This must be 'volatile' to prevent this code from being moved out\n\t * from under the check for OSXSAVE.\n\t */\n\t__asm__ volatile(\".byte 0x0f, 0x01, 0xd0\" :\n\t\t\t \"=d\" (d), \"=a\" (a) : \"c\" (index));\n\n\treturn ((u64)d << 32) | a;\n#endif\n}\n\nstatic const struct cpu_feature x86_cpu_feature_table[] = {\n\t{X86_CPU_FEATURE_SSE2,\t\t\"sse2\"},\n\t{X86_CPU_FEATURE_PCLMULQDQ,\t\"pclmulqdq\"},\n\t{X86_CPU_FEATURE_AVX,\t\t\"avx\"},\n\t{X86_CPU_FEATURE_AVX2,\t\t\"avx2\"},\n\t{X86_CPU_FEATURE_BMI2,\t\t\"bmi2\"},\n\t{X86_CPU_FEATURE_ZMM,\t\t\"zmm\"},\n\t{X86_CPU_FEATURE_AVX512BW,\t\"avx512bw\"},\n\t{X86_CPU_FEATURE_AVX512VL,\t\"avx512vl\"},\n\t{X86_CPU_FEATURE_VPCLMULQDQ,\t\"vpclmulqdq\"},\n\t{X86_CPU_FEATURE_AVX512VNNI,\t\"avx512_vnni\"},\n\t{X86_CPU_FEATURE_AVXVNNI,\t\"avx_vnni\"},\n};\n\nvolatile u32 libdeflate_x86_cpu_features = 0;\n\nstatic inline bool\nos_supports_avx512(u64 xcr0)\n{\n#ifdef __APPLE__\n\t/*\n\t * The Darwin kernel had a bug where it could corrupt the opmask\n\t * registers.  See\n\t * https://community.intel.com/t5/Software-Tuning-Performance/MacOS-Darwin-kernel-bug-clobbers-AVX-512-opmask-register-state/m-p/1327259\n\t * Darwin also does not initially set the XCR0 bits for AVX512, but they\n\t * are set if the thread tries to use AVX512 anyway.  Thus, to safely\n\t * and consistently use AVX512 on macOS we'd need to check the kernel\n\t * version as well as detect AVX512 support using a macOS-specific\n\t * method.  We don't bother with this, especially given Apple's\n\t * transition to arm64.\n\t */\n\treturn false;\n#else\n\treturn (xcr0 & 0xe6) == 0xe6;\n#endif\n}\n\n/*\n * Don't use 512-bit vectors (ZMM registers) on Intel CPUs before Rocket Lake\n * and Sapphire Rapids, due to the overly-eager downclocking which can reduce\n * the performance of workloads that use ZMM registers only occasionally.\n */\nstatic inline bool\nallow_512bit_vectors(const u32 manufacturer[3], u32 family, u32 model)\n{\n#ifdef TEST_SUPPORT__DO_NOT_USE\n\treturn true;\n#endif\n\tif (memcmp(manufacturer, \"GenuineIntel\", 12) != 0)\n\t\treturn true;\n\tif (family != 6)\n\t\treturn true;\n\tswitch (model) {\n\tcase 85: /* Skylake (Server), Cascade Lake, Cooper Lake */\n\tcase 106: /* Ice Lake (Server) */\n\tcase 108: /* Ice Lake (Server) */\n\tcase 126: /* Ice Lake (Client) */\n\tcase 140: /* Tiger Lake */\n\tcase 141: /* Tiger Lake */\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/* Initialize libdeflate_x86_cpu_features. */\nvoid libdeflate_init_x86_cpu_features(void)\n{\n\tu32 max_leaf;\n\tu32 manufacturer[3];\n\tu32 family, model;\n\tu32 a, b, c, d;\n\tu64 xcr0 = 0;\n\tu32 features = 0;\n\n\t/* EAX=0: Highest Function Parameter and Manufacturer ID */\n\tcpuid(0, 0, &max_leaf, &manufacturer[0], &manufacturer[2],\n\t      &manufacturer[1]);\n\tif (max_leaf < 1)\n\t\tgoto out;\n\n\t/* EAX=1: Processor Info and Feature Bits */\n\tcpuid(1, 0, &a, &b, &c, &d);\n\tfamily = (a >> 8) & 0xf;\n\tmodel = (a >> 4) & 0xf;\n\tif (family == 6 || family == 0xf)\n\t\tmodel += (a >> 12) & 0xf0;\n\tif (family == 0xf)\n\t\tfamily += (a >> 20) & 0xff;\n\tif (d & (1 << 26))\n\t\tfeatures |= X86_CPU_FEATURE_SSE2;\n\t/*\n\t * No known CPUs have pclmulqdq without sse4.1, so in practice code\n\t * targeting pclmulqdq can use sse4.1 instructions.  But to be safe,\n\t * explicitly check for both the pclmulqdq and sse4.1 bits.\n\t */\n\tif ((c & (1 << 1)) && (c & (1 << 19)))\n\t\tfeatures |= X86_CPU_FEATURE_PCLMULQDQ;\n\tif (c & (1 << 27))\n\t\txcr0 = read_xcr(0);\n\tif ((c & (1 << 28)) && ((xcr0 & 0x6) == 0x6))\n\t\tfeatures |= X86_CPU_FEATURE_AVX;\n\n\tif (max_leaf < 7)\n\t\tgoto out;\n\n\t/* EAX=7, ECX=0: Extended Features */\n\tcpuid(7, 0, &a, &b, &c, &d);\n\tif (b & (1 << 8))\n\t\tfeatures |= X86_CPU_FEATURE_BMI2;\n\tif ((xcr0 & 0x6) == 0x6) {\n\t\tif (b & (1 << 5))\n\t\t\tfeatures |= X86_CPU_FEATURE_AVX2;\n\t\tif (c & (1 << 10))\n\t\t\tfeatures |= X86_CPU_FEATURE_VPCLMULQDQ;\n\t}\n\tif (os_supports_avx512(xcr0)) {\n\t\tif (allow_512bit_vectors(manufacturer, family, model))\n\t\t\tfeatures |= X86_CPU_FEATURE_ZMM;\n\t\tif (b & (1 << 30))\n\t\t\tfeatures |= X86_CPU_FEATURE_AVX512BW;\n\t\tif (b & (1U << 31))\n\t\t\tfeatures |= X86_CPU_FEATURE_AVX512VL;\n\t\tif (c & (1 << 11))\n\t\t\tfeatures |= X86_CPU_FEATURE_AVX512VNNI;\n\t}\n\n\t/* EAX=7, ECX=1: Extended Features */\n\tcpuid(7, 1, &a, &b, &c, &d);\n\tif ((a & (1 << 4)) && ((xcr0 & 0x6) == 0x6))\n\t\tfeatures |= X86_CPU_FEATURE_AVXVNNI;\n\nout:\n\tdisable_cpu_features_for_testing(&features, x86_cpu_feature_table,\n\t\t\t\t\t ARRAY_LEN(x86_cpu_feature_table));\n\n\tlibdeflate_x86_cpu_features = features | X86_CPU_FEATURES_KNOWN;\n}\n\n#endif /* X86_CPU_FEATURES_KNOWN */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/cpu_features.h",
    "content": "/*\n * x86/cpu_features.h - feature detection for x86 CPUs\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_X86_CPU_FEATURES_H\n#define LIB_X86_CPU_FEATURES_H\n\n#include \"../lib_common.h\"\n\n#if defined(ARCH_X86_32) || defined(ARCH_X86_64)\n\n#define X86_CPU_FEATURE_SSE2\t\t(1 << 0)\n#define X86_CPU_FEATURE_PCLMULQDQ\t(1 << 1)\n#define X86_CPU_FEATURE_AVX\t\t(1 << 2)\n#define X86_CPU_FEATURE_AVX2\t\t(1 << 3)\n#define X86_CPU_FEATURE_BMI2\t\t(1 << 4)\n/*\n * ZMM indicates whether 512-bit vectors (zmm registers) should be used.  On\n * some CPUs, to avoid downclocking issues we don't set ZMM even if the CPU and\n * operating system support AVX-512.  On these CPUs, we may still use AVX-512\n * instructions, but only with xmm and ymm registers.\n */\n#define X86_CPU_FEATURE_ZMM\t\t(1 << 5)\n#define X86_CPU_FEATURE_AVX512BW\t(1 << 6)\n#define X86_CPU_FEATURE_AVX512VL\t(1 << 7)\n#define X86_CPU_FEATURE_VPCLMULQDQ\t(1 << 8)\n#define X86_CPU_FEATURE_AVX512VNNI\t(1 << 9)\n#define X86_CPU_FEATURE_AVXVNNI\t\t(1 << 10)\n\n#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)\n/* Runtime x86 CPU feature detection is supported. */\n#  define X86_CPU_FEATURES_KNOWN\t(1U << 31)\nextern volatile u32 libdeflate_x86_cpu_features;\n\nvoid libdeflate_init_x86_cpu_features(void);\n\nstatic inline u32 get_x86_cpu_features(void)\n{\n\tif (libdeflate_x86_cpu_features == 0)\n\t\tlibdeflate_init_x86_cpu_features();\n\treturn libdeflate_x86_cpu_features;\n}\n/*\n * x86 intrinsics are also supported.  Include the headers needed to use them.\n * Normally just immintrin.h suffices.  With clang in MSVC compatibility mode,\n * immintrin.h incorrectly skips including sub-headers, so include those too.\n */\n#  include <immintrin.h>\n#  if defined(_MSC_VER) && defined(__clang__)\n#    include <tmmintrin.h>\n#    include <smmintrin.h>\n#    include <wmmintrin.h>\n#    include <avxintrin.h>\n#    include <avx2intrin.h>\n#    include <avx512fintrin.h>\n#    include <avx512bwintrin.h>\n#    include <avx512vlintrin.h>\n#    if __has_include(<avx512vlbwintrin.h>)\n#      include <avx512vlbwintrin.h>\n#    endif\n#    if __has_include(<vpclmulqdqintrin.h>)\n#      include <vpclmulqdqintrin.h>\n#    endif\n#    if __has_include(<avx512vnniintrin.h>)\n#      include <avx512vnniintrin.h>\n#    endif\n#    if __has_include(<avx512vlvnniintrin.h>)\n#      include <avx512vlvnniintrin.h>\n#    endif\n#    if __has_include(<avxvnniintrin.h>)\n#      include <avxvnniintrin.h>\n#    endif\n#  endif\n#else\nstatic inline u32 get_x86_cpu_features(void) { return 0; }\n#endif\n\n#if defined(__SSE2__) || \\\n\t(defined(_MSC_VER) && \\\n\t (defined(ARCH_X86_64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)))\n#  define HAVE_SSE2(features)\t\t1\n#  define HAVE_SSE2_NATIVE\t\t1\n#else\n#  define HAVE_SSE2(features)\t\t((features) & X86_CPU_FEATURE_SSE2)\n#  define HAVE_SSE2_NATIVE\t\t0\n#endif\n\n#if (defined(__PCLMUL__) && defined(__SSE4_1__)) || \\\n\t(defined(_MSC_VER) && defined(__AVX2__))\n#  define HAVE_PCLMULQDQ(features)\t1\n#else\n#  define HAVE_PCLMULQDQ(features)\t((features) & X86_CPU_FEATURE_PCLMULQDQ)\n#endif\n\n#ifdef __AVX__\n#  define HAVE_AVX(features)\t\t1\n#else\n#  define HAVE_AVX(features)\t\t((features) & X86_CPU_FEATURE_AVX)\n#endif\n\n#ifdef __AVX2__\n#  define HAVE_AVX2(features)\t\t1\n#else\n#  define HAVE_AVX2(features)\t\t((features) & X86_CPU_FEATURE_AVX2)\n#endif\n\n#if defined(__BMI2__) || (defined(_MSC_VER) && defined(__AVX2__))\n#  define HAVE_BMI2(features)\t\t1\n#  define HAVE_BMI2_NATIVE\t\t1\n#else\n#  define HAVE_BMI2(features)\t\t((features) & X86_CPU_FEATURE_BMI2)\n#  define HAVE_BMI2_NATIVE\t\t0\n#endif\n\n#ifdef __AVX512BW__\n#  define HAVE_AVX512BW(features)\t1\n#else\n#  define HAVE_AVX512BW(features)\t((features) & X86_CPU_FEATURE_AVX512BW)\n#endif\n\n#ifdef __AVX512VL__\n#  define HAVE_AVX512VL(features)\t1\n#else\n#  define HAVE_AVX512VL(features)\t((features) & X86_CPU_FEATURE_AVX512VL)\n#endif\n\n#ifdef __VPCLMULQDQ__\n#  define HAVE_VPCLMULQDQ(features)\t1\n#else\n#  define HAVE_VPCLMULQDQ(features)\t((features) & X86_CPU_FEATURE_VPCLMULQDQ)\n#endif\n\n#ifdef __AVX512VNNI__\n#  define HAVE_AVX512VNNI(features)\t1\n#else\n#  define HAVE_AVX512VNNI(features)\t((features) & X86_CPU_FEATURE_AVX512VNNI)\n#endif\n\n#ifdef __AVXVNNI__\n#  define HAVE_AVXVNNI(features)\t1\n#else\n#  define HAVE_AVXVNNI(features)\t((features) & X86_CPU_FEATURE_AVXVNNI)\n#endif\n\n#endif /* ARCH_X86_32 || ARCH_X86_64 */\n\n#endif /* LIB_X86_CPU_FEATURES_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/crc32_impl.h",
    "content": "/*\n * x86/crc32_impl.h - x86 implementations of the gzip CRC-32 algorithm\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_X86_CRC32_IMPL_H\n#define LIB_X86_CRC32_IMPL_H\n\n#include \"cpu_features.h\"\n\n/*\n * pshufb(x, shift_tab[len..len+15]) left shifts x by 16-len bytes.\n * pshufb(x, shift_tab[len+16..len+31]) right shifts x by len bytes.\n */\nstatic const u8 MAYBE_UNUSED shift_tab[48] = {\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n\t0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n};\n\n#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)\n/*\n * PCLMULQDQ implementation.  This targets PCLMULQDQ+SSE4.1, since in practice\n * all CPUs that support PCLMULQDQ also support SSE4.1.\n */\n#  define crc32_x86_pclmulqdq\tcrc32_x86_pclmulqdq\n#  define SUFFIX\t\t\t _pclmulqdq\n#  define ATTRIBUTES\t\t_target_attribute(\"pclmul,sse4.1\")\n#  define VL\t\t\t16\n#  define USE_AVX512\t\t0\n#  include \"crc32_pclmul_template.h\"\n\n/*\n * PCLMULQDQ/AVX implementation.  Same as above, but this is compiled with AVX\n * enabled so that the compiler can generate VEX-coded instructions which can be\n * slightly more efficient.  It still uses 128-bit vectors.\n */\n#  define crc32_x86_pclmulqdq_avx\tcrc32_x86_pclmulqdq_avx\n#  define SUFFIX\t\t\t\t _pclmulqdq_avx\n#  define ATTRIBUTES\t\t_target_attribute(\"pclmul,avx\")\n#  define VL\t\t\t16\n#  define USE_AVX512\t\t0\n#  include \"crc32_pclmul_template.h\"\n#endif\n\n/*\n * VPCLMULQDQ/AVX2 implementation.  This is used on CPUs that have AVX2 and\n * VPCLMULQDQ but don't have AVX-512, for example Intel Alder Lake.\n *\n * Currently this can't be enabled with MSVC because MSVC has a bug where it\n * incorrectly assumes that VPCLMULQDQ implies AVX-512:\n * https://developercommunity.visualstudio.com/t/Compiler-incorrectly-assumes-VAES-and-VP/10578785\n *\n * gcc 8.1 and 8.2 had a similar bug where they assumed that\n * _mm256_clmulepi64_epi128() always needed AVX512.  It's fixed in gcc 8.3.\n *\n * _mm256_zextsi128_si256() requires gcc 10.\n */\n#if (GCC_PREREQ(10, 1) || CLANG_PREREQ(6, 0, 10000000)) && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_VPCLMULQDQ)\n#  define crc32_x86_vpclmulqdq_avx2\tcrc32_x86_vpclmulqdq_avx2\n#  define SUFFIX\t\t\t\t _vpclmulqdq_avx2\n#  define ATTRIBUTES\t\t_target_attribute(\"vpclmulqdq,pclmul,avx2\")\n#  define VL\t\t\t32\n#  define USE_AVX512\t\t0\n#  include \"crc32_pclmul_template.h\"\n#endif\n\n#if (GCC_PREREQ(10, 1) || CLANG_PREREQ(6, 0, 10000000) || MSVC_PREREQ(1920)) && \\\n\t!defined(LIBDEFLATE_ASSEMBLER_DOES_NOT_SUPPORT_VPCLMULQDQ)\n/*\n * VPCLMULQDQ/AVX512 implementation using 256-bit vectors.  This is very similar\n * to the VPCLMULQDQ/AVX2 implementation but takes advantage of the vpternlog\n * instruction and more registers.  This is used on certain older Intel CPUs,\n * specifically Ice Lake and Tiger Lake, which support VPCLMULQDQ and AVX512 but\n * downclock a bit too eagerly when ZMM registers are used.\n *\n * _mm256_zextsi128_si256() requires gcc 10.\n */\n#  define crc32_x86_vpclmulqdq_avx512_vl256  crc32_x86_vpclmulqdq_avx512_vl256\n#  define SUFFIX\t\t\t\t      _vpclmulqdq_avx512_vl256\n#  define ATTRIBUTES\t\t_target_attribute(\"vpclmulqdq,pclmul,avx512bw,avx512vl\")\n#  define VL\t\t\t32\n#  define USE_AVX512\t\t1\n#  include \"crc32_pclmul_template.h\"\n\n/*\n * VPCLMULQDQ/AVX512 implementation using 512-bit vectors.  This is used on CPUs\n * that have a good AVX-512 implementation including VPCLMULQDQ.\n *\n * _mm512_zextsi128_si512() requires gcc 10.\n */\n#  define crc32_x86_vpclmulqdq_avx512_vl512  crc32_x86_vpclmulqdq_avx512_vl512\n#  define SUFFIX\t\t\t\t      _vpclmulqdq_avx512_vl512\n#  define ATTRIBUTES\t\t_target_attribute(\"vpclmulqdq,pclmul,avx512bw,avx512vl\")\n#  define VL\t\t\t64\n#  define USE_AVX512\t\t1\n#  include \"crc32_pclmul_template.h\"\n#endif\n\nstatic inline crc32_func_t\narch_select_crc32_func(void)\n{\n\tconst u32 features MAYBE_UNUSED = get_x86_cpu_features();\n\n#ifdef crc32_x86_vpclmulqdq_avx512_vl512\n\tif ((features & X86_CPU_FEATURE_ZMM) &&\n\t    HAVE_VPCLMULQDQ(features) && HAVE_PCLMULQDQ(features) &&\n\t    HAVE_AVX512BW(features) && HAVE_AVX512VL(features))\n\t\treturn crc32_x86_vpclmulqdq_avx512_vl512;\n#endif\n#ifdef crc32_x86_vpclmulqdq_avx512_vl256\n\tif (HAVE_VPCLMULQDQ(features) && HAVE_PCLMULQDQ(features) &&\n\t    HAVE_AVX512BW(features) && HAVE_AVX512VL(features))\n\t\treturn crc32_x86_vpclmulqdq_avx512_vl256;\n#endif\n#ifdef crc32_x86_vpclmulqdq_avx2\n\tif (HAVE_VPCLMULQDQ(features) && HAVE_PCLMULQDQ(features) &&\n\t    HAVE_AVX2(features))\n\t\treturn crc32_x86_vpclmulqdq_avx2;\n#endif\n#ifdef crc32_x86_pclmulqdq_avx\n\tif (HAVE_PCLMULQDQ(features) && HAVE_AVX(features))\n\t\treturn crc32_x86_pclmulqdq_avx;\n#endif\n#ifdef crc32_x86_pclmulqdq\n\tif (HAVE_PCLMULQDQ(features))\n\t\treturn crc32_x86_pclmulqdq;\n#endif\n\treturn NULL;\n}\n#define arch_select_crc32_func\tarch_select_crc32_func\n\n#endif /* LIB_X86_CRC32_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/crc32_pclmul_template.h",
    "content": "/*\n * x86/crc32_pclmul_template.h - gzip CRC-32 with PCLMULQDQ instructions\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/*\n * This file is a \"template\" for instantiating PCLMULQDQ-based crc32_x86\n * functions.  The \"parameters\" are:\n *\n * SUFFIX:\n *\tName suffix to append to all instantiated functions.\n * ATTRIBUTES:\n *\tTarget function attributes to use.  Must satisfy the dependencies of the\n *\tother parameters as follows:\n *\t   VL=16 && USE_AVX512=0: at least pclmul,sse4.1\n *\t   VL=32 && USE_AVX512=0: at least vpclmulqdq,pclmul,avx2\n *\t   VL=32 && USE_AVX512=1: at least vpclmulqdq,pclmul,avx512bw,avx512vl\n *\t   VL=64 && USE_AVX512=1: at least vpclmulqdq,pclmul,avx512bw,avx512vl\n *\t   (Other combinations are not useful and have not been tested.)\n * VL:\n *\tVector length in bytes.  Must be 16, 32, or 64.\n * USE_AVX512:\n *\tIf 1, take advantage of AVX-512 features such as masking and the\n *\tvpternlog instruction.  This doesn't enable the use of 512-bit vectors;\n *\tthe vector length is controlled by VL.  If 0, assume that the CPU might\n *\tnot support AVX-512.\n *\n * The overall algorithm used is CRC folding with carryless multiplication\n * instructions.  Note that the x86 crc32 instruction cannot be used, as it is\n * for a different polynomial, not the gzip one.  For an explanation of CRC\n * folding with carryless multiplication instructions, see\n * scripts/gen-crc32-consts.py and the following blog posts and papers:\n *\n *\t\"An alternative exposition of crc32_4k_pclmulqdq\"\n *\thttps://www.corsix.org/content/alternative-exposition-crc32_4k_pclmulqdq\n *\n *\t\"Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction\"\n *\thttps://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf\n *\n * The original pclmulqdq instruction does one 64x64 to 128-bit carryless\n * multiplication.  The VPCLMULQDQ feature added instructions that do two\n * parallel 64x64 to 128-bit carryless multiplications in combination with AVX\n * or AVX512VL, or four in combination with AVX512F.\n */\n\n#if VL == 16\n#  define vec_t\t\t\t__m128i\n#  define fold_vec\t\tfold_vec128\n#  define VLOADU(p)\t\t_mm_loadu_si128((const void *)(p))\n#  define VXOR(a, b)\t\t_mm_xor_si128((a), (b))\n#  define M128I_TO_VEC(a)\ta\n#  define MULTS_8V\t\t_mm_set_epi64x(CRC32_X991_MODG, CRC32_X1055_MODG)\n#  define MULTS_4V\t\t_mm_set_epi64x(CRC32_X479_MODG, CRC32_X543_MODG)\n#  define MULTS_2V\t\t_mm_set_epi64x(CRC32_X223_MODG, CRC32_X287_MODG)\n#  define MULTS_1V\t\t_mm_set_epi64x(CRC32_X95_MODG, CRC32_X159_MODG)\n#elif VL == 32\n#  define vec_t\t\t\t__m256i\n#  define fold_vec\t\tfold_vec256\n#  define VLOADU(p)\t\t_mm256_loadu_si256((const void *)(p))\n#  define VXOR(a, b)\t\t_mm256_xor_si256((a), (b))\n#  define M128I_TO_VEC(a)\t_mm256_zextsi128_si256(a)\n#  define MULTS(a, b)\t\t_mm256_set_epi64x(a, b, a, b)\n#  define MULTS_8V\t\tMULTS(CRC32_X2015_MODG, CRC32_X2079_MODG)\n#  define MULTS_4V\t\tMULTS(CRC32_X991_MODG, CRC32_X1055_MODG)\n#  define MULTS_2V\t\tMULTS(CRC32_X479_MODG, CRC32_X543_MODG)\n#  define MULTS_1V\t\tMULTS(CRC32_X223_MODG, CRC32_X287_MODG)\n#elif VL == 64\n#  define vec_t\t\t\t__m512i\n#  define fold_vec\t\tfold_vec512\n#  define VLOADU(p)\t\t_mm512_loadu_si512((const void *)(p))\n#  define VXOR(a, b)\t\t_mm512_xor_si512((a), (b))\n#  define M128I_TO_VEC(a)\t_mm512_zextsi128_si512(a)\n#  define MULTS(a, b)\t\t_mm512_set_epi64(a, b, a, b, a, b, a, b)\n#  define MULTS_8V\t\tMULTS(CRC32_X4063_MODG, CRC32_X4127_MODG)\n#  define MULTS_4V\t\tMULTS(CRC32_X2015_MODG, CRC32_X2079_MODG)\n#  define MULTS_2V\t\tMULTS(CRC32_X991_MODG, CRC32_X1055_MODG)\n#  define MULTS_1V\t\tMULTS(CRC32_X479_MODG, CRC32_X543_MODG)\n#else\n#  error \"unsupported vector length\"\n#endif\n\n#undef fold_vec128\nstatic forceinline ATTRIBUTES __m128i\nADD_SUFFIX(fold_vec128)(__m128i src, __m128i dst, __m128i /* __v2du */ mults)\n{\n\tdst = _mm_xor_si128(dst, _mm_clmulepi64_si128(src, mults, 0x00));\n\tdst = _mm_xor_si128(dst, _mm_clmulepi64_si128(src, mults, 0x11));\n\treturn dst;\n}\n#define fold_vec128\tADD_SUFFIX(fold_vec128)\n\n#if VL >= 32\n#undef fold_vec256\nstatic forceinline ATTRIBUTES __m256i\nADD_SUFFIX(fold_vec256)(__m256i src, __m256i dst, __m256i /* __v4du */ mults)\n{\n#if USE_AVX512\n\t/* vpternlog with immediate 0x96 is a three-argument XOR. */\n\treturn _mm256_ternarylogic_epi32(\n\t\t\t_mm256_clmulepi64_epi128(src, mults, 0x00),\n\t\t\t_mm256_clmulepi64_epi128(src, mults, 0x11),\n\t\t\tdst,\n\t\t\t0x96);\n#else\n\treturn _mm256_xor_si256(\n\t\t\t_mm256_xor_si256(dst,\n\t\t\t\t\t _mm256_clmulepi64_epi128(src, mults, 0x00)),\n\t\t\t_mm256_clmulepi64_epi128(src, mults, 0x11));\n#endif\n}\n#define fold_vec256\tADD_SUFFIX(fold_vec256)\n#endif /* VL >= 32 */\n\n#if VL >= 64\n#undef fold_vec512\nstatic forceinline ATTRIBUTES __m512i\nADD_SUFFIX(fold_vec512)(__m512i src, __m512i dst, __m512i /* __v8du */ mults)\n{\n\t/* vpternlog with immediate 0x96 is a three-argument XOR. */\n\treturn _mm512_ternarylogic_epi32(\n\t\t\t_mm512_clmulepi64_epi128(src, mults, 0x00),\n\t\t\t_mm512_clmulepi64_epi128(src, mults, 0x11),\n\t\t\tdst,\n\t\t\t0x96);\n}\n#define fold_vec512\tADD_SUFFIX(fold_vec512)\n#endif /* VL >= 64 */\n\n/*\n * Given 'x' containing a 16-byte polynomial, and a pointer 'p' that points to\n * the next '1 <= len <= 15' data bytes, rearrange the concatenation of 'x' and\n * the data into vectors x0 and x1 that contain 'len' bytes and 16 bytes,\n * respectively.  Then fold x0 into x1 and return the result.\n * Assumes that 'p + len - 16' is in-bounds.\n */\n#undef fold_lessthan16bytes\nstatic forceinline ATTRIBUTES __m128i\nADD_SUFFIX(fold_lessthan16bytes)(__m128i x, const u8 *p, size_t len,\n\t\t\t\t __m128i /* __v2du */ mults_128b)\n{\n\t__m128i lshift = _mm_loadu_si128((const void *)&shift_tab[len]);\n\t__m128i rshift = _mm_loadu_si128((const void *)&shift_tab[len + 16]);\n\t__m128i x0, x1;\n\n\t/* x0 = x left-shifted by '16 - len' bytes */\n\tx0 = _mm_shuffle_epi8(x, lshift);\n\n\t/*\n\t * x1 = the last '16 - len' bytes from x (i.e. x right-shifted by 'len'\n\t * bytes) followed by the remaining data.\n\t */\n\tx1 = _mm_blendv_epi8(_mm_shuffle_epi8(x, rshift),\n\t\t\t     _mm_loadu_si128((const void *)(p + len - 16)),\n\t\t\t     /* msb 0/1 of each byte selects byte from arg1/2 */\n\t\t\t     rshift);\n\n\treturn fold_vec128(x0, x1, mults_128b);\n}\n#define fold_lessthan16bytes\tADD_SUFFIX(fold_lessthan16bytes)\n\nstatic ATTRIBUTES u32\nADD_SUFFIX(crc32_x86)(u32 crc, const u8 *p, size_t len)\n{\n\t/*\n\t * mults_{N}v are the vectors of multipliers for folding across N vec_t\n\t * vectors, i.e. N*VL*8 bits.  mults_128b are the two multipliers for\n\t * folding across 128 bits.  mults_128b differs from mults_1v when\n\t * VL != 16.  All multipliers are 64-bit, to match what pclmulqdq needs,\n\t * but since this is for CRC-32 only their low 32 bits are nonzero.\n\t * For more details, see scripts/gen-crc32-consts.py.\n\t */\n\tconst vec_t mults_8v = MULTS_8V;\n\tconst vec_t mults_4v = MULTS_4V;\n\tconst vec_t mults_2v = MULTS_2V;\n\tconst vec_t mults_1v = MULTS_1V;\n\tconst __m128i mults_128b = _mm_set_epi64x(CRC32_X95_MODG, CRC32_X159_MODG);\n\tconst __m128i barrett_reduction_constants =\n\t\t_mm_set_epi64x(CRC32_BARRETT_CONSTANT_2, CRC32_BARRETT_CONSTANT_1);\n\tvec_t v0, v1, v2, v3, v4, v5, v6, v7;\n\t__m128i x0 = _mm_cvtsi32_si128(crc);\n\t__m128i x1;\n\n\tif (len < 8*VL) {\n\t\tif (len < VL) {\n\t\t\tSTATIC_ASSERT(VL == 16 || VL == 32 || VL == 64);\n\t\t\tif (len < 16) {\n\t\t\t#if USE_AVX512\n\t\t\t\tif (len < 4)\n\t\t\t\t\treturn crc32_slice1(crc, p, len);\n\t\t\t\t/*\n\t\t\t\t * Handle 4 <= len <= 15 bytes by doing a masked\n\t\t\t\t * load, XOR'ing the current CRC with the first\n\t\t\t\t * 4 bytes, left-shifting by '16 - len' bytes to\n\t\t\t\t * align the result to the end of x0 (so that it\n\t\t\t\t * becomes the low-order coefficients of a\n\t\t\t\t * 128-bit polynomial), and then doing the usual\n\t\t\t\t * reduction from 128 bits to 32 bits.\n\t\t\t\t */\n\t\t\t\tx0 = _mm_xor_si128(\n\t\t\t\t\tx0, _mm_maskz_loadu_epi8((1 << len) - 1, p));\n\t\t\t\tx0 = _mm_shuffle_epi8(\n\t\t\t\t\tx0, _mm_loadu_si128((const void *)&shift_tab[len]));\n\t\t\t\tgoto reduce_x0;\n\t\t\t#else\n\t\t\t\treturn crc32_slice1(crc, p, len);\n\t\t\t#endif\n\t\t\t}\n\t\t\t/*\n\t\t\t * Handle 16 <= len < VL bytes where VL is 32 or 64.\n\t\t\t * Use 128-bit instructions so that these lengths aren't\n\t\t\t * slower with VL > 16 than with VL=16.\n\t\t\t */\n\t\t\tx0 = _mm_xor_si128(_mm_loadu_si128((const void *)p), x0);\n\t\t\tif (len >= 32) {\n\t\t\t\tx0 = fold_vec128(x0, _mm_loadu_si128((const void *)(p + 16)),\n\t\t\t\t\t\t mults_128b);\n\t\t\t\tif (len >= 48)\n\t\t\t\t\tx0 = fold_vec128(x0, _mm_loadu_si128((const void *)(p + 32)),\n\t\t\t\t\t\t\t mults_128b);\n\t\t\t}\n\t\t\tp += len & ~15;\n\t\t\tgoto less_than_16_remaining;\n\t\t}\n\t\tv0 = VXOR(VLOADU(p), M128I_TO_VEC(x0));\n\t\tif (len < 2*VL) {\n\t\t\tp += VL;\n\t\t\tgoto less_than_vl_remaining;\n\t\t}\n\t\tv1 = VLOADU(p + 1*VL);\n\t\tif (len < 4*VL) {\n\t\t\tp += 2*VL;\n\t\t\tgoto less_than_2vl_remaining;\n\t\t}\n\t\tv2 = VLOADU(p + 2*VL);\n\t\tv3 = VLOADU(p + 3*VL);\n\t\tp += 4*VL;\n\t} else {\n\t\t/*\n\t\t * If the length is large and the pointer is misaligned, align\n\t\t * it.  For smaller lengths, just take the misaligned load\n\t\t * penalty.  Note that on recent x86 CPUs, vmovdqu with an\n\t\t * aligned address is just as fast as vmovdqa, so there's no\n\t\t * need to use vmovdqa in the main loop.\n\t\t */\n\t\tif (len > 65536 && ((uintptr_t)p & (VL-1))) {\n\t\t\tsize_t align = -(uintptr_t)p & (VL-1);\n\n\t\t\tlen -= align;\n\t\t\tx0 = _mm_xor_si128(_mm_loadu_si128((const void *)p), x0);\n\t\t\tp += 16;\n\t\t\tif (align & 15) {\n\t\t\t\tx0 = fold_lessthan16bytes(x0, p, align & 15,\n\t\t\t\t\t\t\t  mults_128b);\n\t\t\t\tp += align & 15;\n\t\t\t\talign &= ~15;\n\t\t\t}\n\t\t\twhile (align) {\n\t\t\t\tx0 = fold_vec128(x0, *(const __m128i *)p,\n\t\t\t\t\t\t mults_128b);\n\t\t\t\tp += 16;\n\t\t\t\talign -= 16;\n\t\t\t}\n\t\t\tv0 = M128I_TO_VEC(x0);\n\t\t#  if VL == 32\n\t\t\tv0 = _mm256_inserti128_si256(v0, *(const __m128i *)p, 1);\n\t\t#  elif VL == 64\n\t\t\tv0 = _mm512_inserti32x4(v0, *(const __m128i *)p, 1);\n\t\t\tv0 = _mm512_inserti64x4(v0, *(const __m256i *)(p + 16), 1);\n\t\t#  endif\n\t\t\tp -= 16;\n\t\t} else {\n\t\t\tv0 = VXOR(VLOADU(p), M128I_TO_VEC(x0));\n\t\t}\n\t\tv1 = VLOADU(p + 1*VL);\n\t\tv2 = VLOADU(p + 2*VL);\n\t\tv3 = VLOADU(p + 3*VL);\n\t\tv4 = VLOADU(p + 4*VL);\n\t\tv5 = VLOADU(p + 5*VL);\n\t\tv6 = VLOADU(p + 6*VL);\n\t\tv7 = VLOADU(p + 7*VL);\n\t\tp += 8*VL;\n\n\t\t/*\n\t\t * This is the main loop, processing 8*VL bytes per iteration.\n\t\t * 4*VL is usually enough and would result in smaller code, but\n\t\t * Skylake and Cascade Lake need 8*VL to get full performance.\n\t\t */\n\t\twhile (len >= 16*VL) {\n\t\t\tv0 = fold_vec(v0, VLOADU(p + 0*VL), mults_8v);\n\t\t\tv1 = fold_vec(v1, VLOADU(p + 1*VL), mults_8v);\n\t\t\tv2 = fold_vec(v2, VLOADU(p + 2*VL), mults_8v);\n\t\t\tv3 = fold_vec(v3, VLOADU(p + 3*VL), mults_8v);\n\t\t\tv4 = fold_vec(v4, VLOADU(p + 4*VL), mults_8v);\n\t\t\tv5 = fold_vec(v5, VLOADU(p + 5*VL), mults_8v);\n\t\t\tv6 = fold_vec(v6, VLOADU(p + 6*VL), mults_8v);\n\t\t\tv7 = fold_vec(v7, VLOADU(p + 7*VL), mults_8v);\n\t\t\tp += 8*VL;\n\t\t\tlen -= 8*VL;\n\t\t}\n\n\t\t/* Fewer than 8*VL bytes remain. */\n\t\tv0 = fold_vec(v0, v4, mults_4v);\n\t\tv1 = fold_vec(v1, v5, mults_4v);\n\t\tv2 = fold_vec(v2, v6, mults_4v);\n\t\tv3 = fold_vec(v3, v7, mults_4v);\n\t\tif (len & (4*VL)) {\n\t\t\tv0 = fold_vec(v0, VLOADU(p + 0*VL), mults_4v);\n\t\t\tv1 = fold_vec(v1, VLOADU(p + 1*VL), mults_4v);\n\t\t\tv2 = fold_vec(v2, VLOADU(p + 2*VL), mults_4v);\n\t\t\tv3 = fold_vec(v3, VLOADU(p + 3*VL), mults_4v);\n\t\t\tp += 4*VL;\n\t\t}\n\t}\n\t/* Fewer than 4*VL bytes remain. */\n\tv0 = fold_vec(v0, v2, mults_2v);\n\tv1 = fold_vec(v1, v3, mults_2v);\n\tif (len & (2*VL)) {\n\t\tv0 = fold_vec(v0, VLOADU(p + 0*VL), mults_2v);\n\t\tv1 = fold_vec(v1, VLOADU(p + 1*VL), mults_2v);\n\t\tp += 2*VL;\n\t}\nless_than_2vl_remaining:\n\t/* Fewer than 2*VL bytes remain. */\n\tv0 = fold_vec(v0, v1, mults_1v);\n\tif (len & VL) {\n\t\tv0 = fold_vec(v0, VLOADU(p), mults_1v);\n\t\tp += VL;\n\t}\nless_than_vl_remaining:\n\t/*\n\t * Fewer than VL bytes remain.  Reduce v0 (length VL bytes) to x0\n\t * (length 16 bytes) and fold in any 16-byte data segments that remain.\n\t */\n#if VL == 16\n\tx0 = v0;\n#else\n\t{\n\t#if VL == 32\n\t\t__m256i y0 = v0;\n\t#else\n\t\tconst __m256i mults_256b =\n\t\t\t_mm256_set_epi64x(CRC32_X223_MODG, CRC32_X287_MODG,\n\t\t\t\t\t  CRC32_X223_MODG, CRC32_X287_MODG);\n\t\t__m256i y0 = fold_vec256(_mm512_extracti64x4_epi64(v0, 0),\n\t\t\t\t\t _mm512_extracti64x4_epi64(v0, 1),\n\t\t\t\t\t mults_256b);\n\t\tif (len & 32) {\n\t\t\ty0 = fold_vec256(y0, _mm256_loadu_si256((const void *)p),\n\t\t\t\t\t mults_256b);\n\t\t\tp += 32;\n\t\t}\n\t#endif\n\t\tx0 = fold_vec128(_mm256_extracti128_si256(y0, 0),\n\t\t\t\t _mm256_extracti128_si256(y0, 1), mults_128b);\n\t}\n\tif (len & 16) {\n\t\tx0 = fold_vec128(x0, _mm_loadu_si128((const void *)p),\n\t\t\t\t mults_128b);\n\t\tp += 16;\n\t}\n#endif\nless_than_16_remaining:\n\tlen &= 15;\n\n\t/* Handle any remainder of 1 to 15 bytes. */\n\tif (len)\n\t\tx0 = fold_lessthan16bytes(x0, p, len, mults_128b);\n#if USE_AVX512\nreduce_x0:\n#endif\n\t/*\n\t * Multiply the remaining 128-bit message polynomial 'x0' by x^32, then\n\t * reduce it modulo the generator polynomial G.  This gives the CRC.\n\t *\n\t * This implementation matches that used in crc-pclmul-template.S from\n\t * https://lore.kernel.org/r/20250210174540.161705-4-ebiggers@kernel.org/\n\t * with the parameters n=32 and LSB_CRC=1 (what the gzip CRC uses).  See\n\t * there for a detailed explanation of the math used here.\n\t */\n\tx0 = _mm_xor_si128(_mm_clmulepi64_si128(x0, mults_128b, 0x10),\n\t\t\t   _mm_bsrli_si128(x0, 8));\n\tx1 = _mm_clmulepi64_si128(x0, barrett_reduction_constants, 0x00);\n\tx1 = _mm_clmulepi64_si128(x1, barrett_reduction_constants, 0x10);\n\tx0 = _mm_xor_si128(x0, x1);\n\treturn _mm_extract_epi32(x0, 2);\n}\n\n#undef vec_t\n#undef fold_vec\n#undef VLOADU\n#undef VXOR\n#undef M128I_TO_VEC\n#undef MULTS\n#undef MULTS_8V\n#undef MULTS_4V\n#undef MULTS_2V\n#undef MULTS_1V\n\n#undef SUFFIX\n#undef ATTRIBUTES\n#undef VL\n#undef USE_AVX512\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/decompress_impl.h",
    "content": "#ifndef LIB_X86_DECOMPRESS_IMPL_H\n#define LIB_X86_DECOMPRESS_IMPL_H\n\n#include \"cpu_features.h\"\n\n/*\n * BMI2 optimized decompression function.\n *\n * With gcc and clang we just compile the whole function with\n * __attribute__((target(\"bmi2\"))), and the compiler uses bmi2 automatically.\n *\n * With MSVC, there is no target function attribute, but it's still possible to\n * use bmi2 intrinsics explicitly.  Currently we mostly don't, but there's a\n * case in which we do (see below), so we at least take advantage of that.\n * However, MSVC from VS2017 (toolset v141) apparently miscompiles the _bzhi_*()\n * intrinsics.  It seems to be fixed in VS2022.  Hence, use MSVC_PREREQ(1930).\n */\n#if defined(__GNUC__) || defined(__clang__) || MSVC_PREREQ(1930)\n#  define deflate_decompress_bmi2\tdeflate_decompress_bmi2\n#  define FUNCNAME\t\t\tdeflate_decompress_bmi2\n#  define ATTRIBUTES\t\t\t_target_attribute(\"bmi2\")\n   /*\n    * Even with __attribute__((target(\"bmi2\"))), gcc doesn't reliably use the\n    * bzhi instruction for 'word & BITMASK(count)'.  So use the bzhi intrinsic\n    * explicitly.  EXTRACT_VARBITS() is equivalent to 'word & BITMASK(count)';\n    * EXTRACT_VARBITS8() is equivalent to 'word & BITMASK((u8)count)'.\n    * Nevertheless, their implementation using the bzhi intrinsic is identical,\n    * as the bzhi instruction truncates the count to 8 bits implicitly.\n    */\n#  ifndef __clang__\n#    ifdef ARCH_X86_64\n#      define EXTRACT_VARBITS(word, count)  _bzhi_u64((word), (count))\n#      define EXTRACT_VARBITS8(word, count) _bzhi_u64((word), (count))\n#    else\n#      define EXTRACT_VARBITS(word, count)  _bzhi_u32((word), (count))\n#      define EXTRACT_VARBITS8(word, count) _bzhi_u32((word), (count))\n#    endif\n#  endif\n#  include \"../decompress_template.h\"\n#endif\n\n#if defined(deflate_decompress_bmi2) && HAVE_BMI2_NATIVE\n#define DEFAULT_IMPL\tdeflate_decompress_bmi2\n#else\nstatic inline decompress_func_t\narch_select_decompress_func(void)\n{\n#ifdef deflate_decompress_bmi2\n\tif (HAVE_BMI2(get_x86_cpu_features()))\n\t\treturn deflate_decompress_bmi2;\n#endif\n\treturn NULL;\n}\n#define arch_select_decompress_func\tarch_select_decompress_func\n#endif\n\n#endif /* LIB_X86_DECOMPRESS_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/x86/matchfinder_impl.h",
    "content": "/*\n * x86/matchfinder_impl.h - x86 implementations of matchfinder functions\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIB_X86_MATCHFINDER_IMPL_H\n#define LIB_X86_MATCHFINDER_IMPL_H\n\n#include \"cpu_features.h\"\n\n#ifdef __AVX2__\nstatic forceinline void\nmatchfinder_init_avx2(mf_pos_t *data, size_t size)\n{\n\t__m256i *p = (__m256i *)data;\n\t__m256i v = _mm256_set1_epi16(MATCHFINDER_INITVAL);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\tp[0] = v;\n\t\tp[1] = v;\n\t\tp[2] = v;\n\t\tp[3] = v;\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_init matchfinder_init_avx2\n\nstatic forceinline void\nmatchfinder_rebase_avx2(mf_pos_t *data, size_t size)\n{\n\t__m256i *p = (__m256i *)data;\n\t__m256i v = _mm256_set1_epi16((u16)-MATCHFINDER_WINDOW_SIZE);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\t/* PADDSW: Add Packed Signed Integers With Signed Saturation  */\n\t\tp[0] = _mm256_adds_epi16(p[0], v);\n\t\tp[1] = _mm256_adds_epi16(p[1], v);\n\t\tp[2] = _mm256_adds_epi16(p[2], v);\n\t\tp[3] = _mm256_adds_epi16(p[3], v);\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_rebase matchfinder_rebase_avx2\n\n#elif HAVE_SSE2_NATIVE\nstatic forceinline void\nmatchfinder_init_sse2(mf_pos_t *data, size_t size)\n{\n\t__m128i *p = (__m128i *)data;\n\t__m128i v = _mm_set1_epi16(MATCHFINDER_INITVAL);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\tp[0] = v;\n\t\tp[1] = v;\n\t\tp[2] = v;\n\t\tp[3] = v;\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_init matchfinder_init_sse2\n\nstatic forceinline void\nmatchfinder_rebase_sse2(mf_pos_t *data, size_t size)\n{\n\t__m128i *p = (__m128i *)data;\n\t__m128i v = _mm_set1_epi16((u16)-MATCHFINDER_WINDOW_SIZE);\n\n\tSTATIC_ASSERT(MATCHFINDER_MEM_ALIGNMENT % sizeof(*p) == 0);\n\tSTATIC_ASSERT(MATCHFINDER_SIZE_ALIGNMENT % (4 * sizeof(*p)) == 0);\n\tSTATIC_ASSERT(sizeof(mf_pos_t) == 2);\n\n\tdo {\n\t\t/* PADDSW: Add Packed Signed Integers With Signed Saturation  */\n\t\tp[0] = _mm_adds_epi16(p[0], v);\n\t\tp[1] = _mm_adds_epi16(p[1], v);\n\t\tp[2] = _mm_adds_epi16(p[2], v);\n\t\tp[3] = _mm_adds_epi16(p[3], v);\n\t\tp += 4;\n\t\tsize -= 4 * sizeof(*p);\n\t} while (size != 0);\n}\n#define matchfinder_rebase matchfinder_rebase_sse2\n#endif /* HAVE_SSE2_NATIVE */\n\n#endif /* LIB_X86_MATCHFINDER_IMPL_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/zlib_compress.c",
    "content": "/*\n * zlib_compress.c - compress with a zlib wrapper\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"deflate_compress.h\"\n#include \"zlib_constants.h\"\n\nLIBDEFLATEAPI size_t\nlibdeflate_zlib_compress(struct libdeflate_compressor *c,\n\t\t\t const void *in, size_t in_nbytes,\n\t\t\t void *out, size_t out_nbytes_avail)\n{\n\tu8 *out_next = out;\n\tu16 hdr;\n\tunsigned compression_level;\n\tunsigned level_hint;\n\tsize_t deflate_size;\n\n\tif (out_nbytes_avail <= ZLIB_MIN_OVERHEAD)\n\t\treturn 0;\n\n\t/* 2 byte header: CMF and FLG  */\n\thdr = (ZLIB_CM_DEFLATE << 8) | (ZLIB_CINFO_32K_WINDOW << 12);\n\tcompression_level = libdeflate_get_compression_level(c);\n\tif (compression_level < 2)\n\t\tlevel_hint = ZLIB_FASTEST_COMPRESSION;\n\telse if (compression_level < 6)\n\t\tlevel_hint = ZLIB_FAST_COMPRESSION;\n\telse if (compression_level < 8)\n\t\tlevel_hint = ZLIB_DEFAULT_COMPRESSION;\n\telse\n\t\tlevel_hint = ZLIB_SLOWEST_COMPRESSION;\n\thdr |= level_hint << 6;\n\thdr |= 31 - (hdr % 31);\n\n\tput_unaligned_be16(hdr, out_next);\n\tout_next += 2;\n\n\t/* Compressed data  */\n\tdeflate_size = libdeflate_deflate_compress(c, in, in_nbytes, out_next,\n\t\t\t\t\tout_nbytes_avail - ZLIB_MIN_OVERHEAD);\n\tif (deflate_size == 0)\n\t\treturn 0;\n\tout_next += deflate_size;\n\n\t/* ADLER32  */\n\tput_unaligned_be32(libdeflate_adler32(1, in, in_nbytes), out_next);\n\tout_next += 4;\n\n\treturn out_next - (u8 *)out;\n}\n\nLIBDEFLATEAPI size_t\nlibdeflate_zlib_compress_bound(struct libdeflate_compressor *c,\n\t\t\t       size_t in_nbytes)\n{\n\treturn ZLIB_MIN_OVERHEAD +\n\t       libdeflate_deflate_compress_bound(c, in_nbytes);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/zlib_constants.h",
    "content": "/*\n * zlib_constants.h - constants for the zlib wrapper format\n */\n\n#ifndef LIB_ZLIB_CONSTANTS_H\n#define LIB_ZLIB_CONSTANTS_H\n\n#define ZLIB_MIN_HEADER_SIZE\t2\n#define ZLIB_FOOTER_SIZE\t4\n#define ZLIB_MIN_OVERHEAD\t(ZLIB_MIN_HEADER_SIZE + ZLIB_FOOTER_SIZE)\n\n#define ZLIB_CM_DEFLATE\t\t8\n\n#define ZLIB_CINFO_32K_WINDOW\t7\n\n#define ZLIB_FASTEST_COMPRESSION\t0\n#define ZLIB_FAST_COMPRESSION\t\t1\n#define ZLIB_DEFAULT_COMPRESSION\t2\n#define ZLIB_SLOWEST_COMPRESSION\t3\n\n#endif /* LIB_ZLIB_CONSTANTS_H */\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/lib/zlib_decompress.c",
    "content": "/*\n * zlib_decompress.c - decompress with a zlib wrapper\n *\n * Copyright 2016 Eric Biggers\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"lib_common.h\"\n#include \"zlib_constants.h\"\n\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_zlib_decompress_ex(struct libdeflate_decompressor *d,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_in_nbytes_ret,\n\t\t\t      size_t *actual_out_nbytes_ret)\n{\n\tconst u8 *in_next = in;\n\tconst u8 * const in_end = in_next + in_nbytes;\n\tu16 hdr;\n\tsize_t actual_in_nbytes;\n\tsize_t actual_out_nbytes;\n\tenum libdeflate_result result;\n\n\tif (in_nbytes < ZLIB_MIN_OVERHEAD)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* 2 byte header: CMF and FLG  */\n\thdr = get_unaligned_be16(in_next);\n\tin_next += 2;\n\n\t/* FCHECK */\n\tif ((hdr % 31) != 0)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* CM */\n\tif (((hdr >> 8) & 0xF) != ZLIB_CM_DEFLATE)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* CINFO */\n\tif ((hdr >> 12) > ZLIB_CINFO_32K_WINDOW)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* FDICT */\n\tif ((hdr >> 5) & 1)\n\t\treturn LIBDEFLATE_BAD_DATA;\n\n\t/* Compressed data  */\n\tresult = libdeflate_deflate_decompress_ex(d, in_next,\n\t\t\t\t\tin_end - ZLIB_FOOTER_SIZE - in_next,\n\t\t\t\t\tout, out_nbytes_avail,\n\t\t\t\t\t&actual_in_nbytes, actual_out_nbytes_ret);\n\tif (result != LIBDEFLATE_SUCCESS)\n\t\treturn result;\n\n\tif (actual_out_nbytes_ret)\n\t\tactual_out_nbytes = *actual_out_nbytes_ret;\n\telse\n\t\tactual_out_nbytes = out_nbytes_avail;\n\n\tin_next += actual_in_nbytes;\n\n\t/* ADLER32  */\n\tif (libdeflate_adler32(1, out, actual_out_nbytes) !=\n\t    get_unaligned_be32(in_next))\n\t\treturn LIBDEFLATE_BAD_DATA;\n\tin_next += 4;\n\n\tif (actual_in_nbytes_ret)\n\t\t*actual_in_nbytes_ret = in_next - (u8 *)in;\n\n\treturn LIBDEFLATE_SUCCESS;\n}\n\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_zlib_decompress(struct libdeflate_decompressor *d,\n\t\t\t   const void *in, size_t in_nbytes,\n\t\t\t   void *out, size_t out_nbytes_avail,\n\t\t\t   size_t *actual_out_nbytes_ret)\n{\n\treturn libdeflate_zlib_decompress_ex(d, in, in_nbytes,\n\t\t\t\t\t     out, out_nbytes_avail,\n\t\t\t\t\t     NULL, actual_out_nbytes_ret);\n}\n"
  },
  {
    "path": "vendor/core/vendor/libdeflate/libdeflate.h",
    "content": "/*\n * libdeflate.h - public header for libdeflate\n */\n\n#ifndef LIBDEFLATE_H\n#define LIBDEFLATE_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define LIBDEFLATE_VERSION_MAJOR\t1\n#define LIBDEFLATE_VERSION_MINOR\t25\n#define LIBDEFLATE_VERSION_STRING\t\"1.25\"\n\n/*\n * Users of libdeflate.dll on Windows can define LIBDEFLATE_DLL to cause\n * __declspec(dllimport) to be used.  This should be done when it's easy to do.\n * Otherwise it's fine to skip it, since it is a very minor performance\n * optimization that is irrelevant for most use cases of libdeflate.\n */\n#ifndef LIBDEFLATEAPI\n#  if defined(LIBDEFLATE_DLL) && (defined(_WIN32) || defined(__CYGWIN__))\n#    define LIBDEFLATEAPI\t__declspec(dllimport)\n#  else\n#    define LIBDEFLATEAPI\n#  endif\n#endif\n\n/* ========================================================================== */\n/*                             Compression                                    */\n/* ========================================================================== */\n\nstruct libdeflate_compressor;\nstruct libdeflate_options;\n\n/*\n * libdeflate_alloc_compressor() allocates a new compressor that supports\n * DEFLATE, zlib, and gzip compression.  'compression_level' is the compression\n * level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 =\n * medium/default, 9 = slow, 12 = slowest).  Level 0 is also supported and means\n * \"no compression\", specifically \"create a valid stream, but only emit\n * uncompressed blocks\" (this will expand the data slightly).\n *\n * The return value is a pointer to the new compressor, or NULL if out of memory\n * or if the compression level is invalid (i.e. outside the range [0, 12]).\n *\n * Note: for compression, the sliding window size is defined at compilation time\n * to 32768, the largest size permissible in the DEFLATE format.  It cannot be\n * changed at runtime.\n *\n * A single compressor is not safe to use by multiple threads concurrently.\n * However, different threads may use different compressors concurrently.\n */\nLIBDEFLATEAPI struct libdeflate_compressor *\nlibdeflate_alloc_compressor(int compression_level);\n\n/*\n * Like libdeflate_alloc_compressor(), but adds the 'options' argument.\n */\nLIBDEFLATEAPI struct libdeflate_compressor *\nlibdeflate_alloc_compressor_ex(int compression_level,\n\t\t\t       const struct libdeflate_options *options);\n\n/*\n * libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of\n * data.  It attempts to compress 'in_nbytes' bytes of data located at 'in' and\n * write the result to 'out', which has space for 'out_nbytes_avail' bytes.  The\n * return value is the compressed size in bytes, or 0 if the data could not be\n * compressed to 'out_nbytes_avail' bytes or fewer.\n *\n * If compression is successful, then the output data is guaranteed to be a\n * valid DEFLATE stream that decompresses to the input data.  No other\n * guarantees are made about the output data.  Notably, different versions of\n * libdeflate can produce different compressed data for the same uncompressed\n * data, even at the same compression level.  Do ***NOT*** do things like\n * writing tests that compare compressed data to a golden output, as this can\n * break when libdeflate is updated.  (This property isn't specific to\n * libdeflate; the same is true for zlib and other compression libraries too.)\n */\nLIBDEFLATEAPI size_t\nlibdeflate_deflate_compress(struct libdeflate_compressor *compressor,\n\t\t\t    const void *in, size_t in_nbytes,\n\t\t\t    void *out, size_t out_nbytes_avail);\n\n/*\n * libdeflate_deflate_compress_bound() returns a worst-case upper bound on the\n * number of bytes of compressed data that may be produced by compressing any\n * buffer of length less than or equal to 'in_nbytes' using\n * libdeflate_deflate_compress() with the specified compressor.  This bound will\n * necessarily be a number greater than or equal to 'in_nbytes'.  It may be an\n * overestimate of the true upper bound.  The return value is guaranteed to be\n * the same for all invocations with the same compressor and same 'in_nbytes'.\n *\n * As a special case, 'compressor' may be NULL.  This causes the bound to be\n * taken across *any* libdeflate_compressor that could ever be allocated with\n * this build of the library, with any options.\n *\n * Note that this function is not necessary in many applications.  With\n * block-based compression, it is usually preferable to separately store the\n * uncompressed size of each block and to store any blocks that did not compress\n * to less than their original size uncompressed.  In that scenario, there is no\n * need to know the worst-case compressed size, since the maximum number of\n * bytes of compressed data that may be used would always be one less than the\n * input length.  You can just pass a buffer of that size to\n * libdeflate_deflate_compress() and store the data uncompressed if\n * libdeflate_deflate_compress() returns 0, indicating that the compressed data\n * did not fit into the provided output buffer.\n */\nLIBDEFLATEAPI size_t\nlibdeflate_deflate_compress_bound(struct libdeflate_compressor *compressor,\n\t\t\t\t  size_t in_nbytes);\n\n/*\n * Like libdeflate_deflate_compress(), but uses the zlib wrapper format instead\n * of raw DEFLATE.\n */\nLIBDEFLATEAPI size_t\nlibdeflate_zlib_compress(struct libdeflate_compressor *compressor,\n\t\t\t const void *in, size_t in_nbytes,\n\t\t\t void *out, size_t out_nbytes_avail);\n\n/*\n * Like libdeflate_deflate_compress_bound(), but assumes the data will be\n * compressed with libdeflate_zlib_compress() rather than with\n * libdeflate_deflate_compress().\n */\nLIBDEFLATEAPI size_t\nlibdeflate_zlib_compress_bound(struct libdeflate_compressor *compressor,\n\t\t\t       size_t in_nbytes);\n\n/*\n * Like libdeflate_deflate_compress(), but uses the gzip wrapper format instead\n * of raw DEFLATE.\n */\nLIBDEFLATEAPI size_t\nlibdeflate_gzip_compress(struct libdeflate_compressor *compressor,\n\t\t\t const void *in, size_t in_nbytes,\n\t\t\t void *out, size_t out_nbytes_avail);\n\n/*\n * Like libdeflate_deflate_compress_bound(), but assumes the data will be\n * compressed with libdeflate_gzip_compress() rather than with\n * libdeflate_deflate_compress().\n */\nLIBDEFLATEAPI size_t\nlibdeflate_gzip_compress_bound(struct libdeflate_compressor *compressor,\n\t\t\t       size_t in_nbytes);\n\n/*\n * libdeflate_free_compressor() frees a compressor that was allocated with\n * libdeflate_alloc_compressor().  If a NULL pointer is passed in, no action is\n * taken.\n */\nLIBDEFLATEAPI void\nlibdeflate_free_compressor(struct libdeflate_compressor *compressor);\n\n/* ========================================================================== */\n/*                             Decompression                                  */\n/* ========================================================================== */\n\nstruct libdeflate_decompressor;\nstruct libdeflate_options;\n\n/*\n * libdeflate_alloc_decompressor() allocates a new decompressor that can be used\n * for DEFLATE, zlib, and gzip decompression.  The return value is a pointer to\n * the new decompressor, or NULL if out of memory.\n *\n * This function takes no parameters, and the returned decompressor is valid for\n * decompressing data that was compressed at any compression level and with any\n * sliding window size.\n *\n * A single decompressor is not safe to use by multiple threads concurrently.\n * However, different threads may use different decompressors concurrently.\n */\nLIBDEFLATEAPI struct libdeflate_decompressor *\nlibdeflate_alloc_decompressor(void);\n\n/*\n * Like libdeflate_alloc_decompressor(), but adds the 'options' argument.\n */\nLIBDEFLATEAPI struct libdeflate_decompressor *\nlibdeflate_alloc_decompressor_ex(const struct libdeflate_options *options);\n\n/*\n * Result of a call to libdeflate_deflate_decompress(),\n * libdeflate_zlib_decompress(), or libdeflate_gzip_decompress().\n */\nenum libdeflate_result {\n\t/* Decompression was successful.  */\n\tLIBDEFLATE_SUCCESS = 0,\n\n\t/* Decompression failed because the compressed data was invalid,\n\t * corrupt, or otherwise unsupported.  */\n\tLIBDEFLATE_BAD_DATA = 1,\n\n\t/* A NULL 'actual_out_nbytes_ret' was provided, but the data would have\n\t * decompressed to fewer than 'out_nbytes_avail' bytes.  */\n\tLIBDEFLATE_SHORT_OUTPUT = 2,\n\n\t/* The data would have decompressed to more than 'out_nbytes_avail'\n\t * bytes.  */\n\tLIBDEFLATE_INSUFFICIENT_SPACE = 3,\n};\n\n/*\n * libdeflate_deflate_decompress() decompresses a DEFLATE stream from the buffer\n * 'in' with compressed size up to 'in_nbytes' bytes.  The uncompressed data is\n * written to 'out', a buffer with size 'out_nbytes_avail' bytes.  If\n * decompression succeeds, then 0 (LIBDEFLATE_SUCCESS) is returned.  Otherwise,\n * a nonzero result code such as LIBDEFLATE_BAD_DATA is returned, and the\n * contents of the output buffer are undefined.\n *\n * Decompression stops at the end of the DEFLATE stream (as indicated by the\n * BFINAL flag), even if it is actually shorter than 'in_nbytes' bytes.\n *\n * libdeflate_deflate_decompress() can be used in cases where the actual\n * uncompressed size is known (recommended) or unknown (not recommended):\n *\n *   - If the actual uncompressed size is known, then pass the actual\n *     uncompressed size as 'out_nbytes_avail' and pass NULL for\n *     'actual_out_nbytes_ret'.  This makes libdeflate_deflate_decompress() fail\n *     with LIBDEFLATE_SHORT_OUTPUT if the data decompressed to fewer than the\n *     specified number of bytes.\n *\n *   - If the actual uncompressed size is unknown, then provide a non-NULL\n *     'actual_out_nbytes_ret' and provide a buffer with some size\n *     'out_nbytes_avail' that you think is large enough to hold all the\n *     uncompressed data.  In this case, if the data decompresses to less than\n *     or equal to 'out_nbytes_avail' bytes, then\n *     libdeflate_deflate_decompress() will write the actual uncompressed size\n *     to *actual_out_nbytes_ret and return 0 (LIBDEFLATE_SUCCESS).  Otherwise,\n *     it will return LIBDEFLATE_INSUFFICIENT_SPACE if the provided buffer was\n *     not large enough but no other problems were encountered, or another\n *     nonzero result code if decompression failed for another reason.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_deflate_decompress(struct libdeflate_decompressor *decompressor,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_out_nbytes_ret);\n\n/*\n * Like libdeflate_deflate_decompress(), but adds the 'actual_in_nbytes_ret'\n * argument.  If decompression succeeds and 'actual_in_nbytes_ret' is not NULL,\n * then the actual compressed size of the DEFLATE stream (aligned to the next\n * byte boundary) is written to *actual_in_nbytes_ret.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_deflate_decompress_ex(struct libdeflate_decompressor *decompressor,\n\t\t\t\t const void *in, size_t in_nbytes,\n\t\t\t\t void *out, size_t out_nbytes_avail,\n\t\t\t\t size_t *actual_in_nbytes_ret,\n\t\t\t\t size_t *actual_out_nbytes_ret);\n\n/*\n * Like libdeflate_deflate_decompress(), but assumes the zlib wrapper format\n * instead of raw DEFLATE.\n *\n * Decompression will stop at the end of the zlib stream, even if it is shorter\n * than 'in_nbytes'.  If you need to know exactly where the zlib stream ended,\n * use libdeflate_zlib_decompress_ex().\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor,\n\t\t\t   const void *in, size_t in_nbytes,\n\t\t\t   void *out, size_t out_nbytes_avail,\n\t\t\t   size_t *actual_out_nbytes_ret);\n\n/*\n * Like libdeflate_zlib_decompress(), but adds the 'actual_in_nbytes_ret'\n * argument.  If 'actual_in_nbytes_ret' is not NULL and the decompression\n * succeeds (indicating that the first zlib-compressed stream in the input\n * buffer was decompressed), then the actual number of input bytes consumed is\n * written to *actual_in_nbytes_ret.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_zlib_decompress_ex(struct libdeflate_decompressor *decompressor,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_in_nbytes_ret,\n\t\t\t      size_t *actual_out_nbytes_ret);\n\n/*\n * Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format\n * instead of raw DEFLATE.\n *\n * If multiple gzip-compressed members are concatenated, then only the first\n * will be decompressed.  Use libdeflate_gzip_decompress_ex() if you need\n * multi-member support.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_gzip_decompress(struct libdeflate_decompressor *decompressor,\n\t\t\t   const void *in, size_t in_nbytes,\n\t\t\t   void *out, size_t out_nbytes_avail,\n\t\t\t   size_t *actual_out_nbytes_ret);\n\n/*\n * Like libdeflate_gzip_decompress(), but adds the 'actual_in_nbytes_ret'\n * argument.  If 'actual_in_nbytes_ret' is not NULL and the decompression\n * succeeds (indicating that the first gzip-compressed member in the input\n * buffer was decompressed), then the actual number of input bytes consumed is\n * written to *actual_in_nbytes_ret.\n */\nLIBDEFLATEAPI enum libdeflate_result\nlibdeflate_gzip_decompress_ex(struct libdeflate_decompressor *decompressor,\n\t\t\t      const void *in, size_t in_nbytes,\n\t\t\t      void *out, size_t out_nbytes_avail,\n\t\t\t      size_t *actual_in_nbytes_ret,\n\t\t\t      size_t *actual_out_nbytes_ret);\n\n/*\n * libdeflate_free_decompressor() frees a decompressor that was allocated with\n * libdeflate_alloc_decompressor().  If a NULL pointer is passed in, no action\n * is taken.\n */\nLIBDEFLATEAPI void\nlibdeflate_free_decompressor(struct libdeflate_decompressor *decompressor);\n\n/* ========================================================================== */\n/*                                Checksums                                   */\n/* ========================================================================== */\n\n/*\n * libdeflate_adler32() updates a running Adler-32 checksum with 'len' bytes of\n * data and returns the updated checksum.  When starting a new checksum, the\n * required initial value for 'adler' is 1.  This value is also returned when\n * 'buffer' is specified as NULL.\n */\nLIBDEFLATEAPI uint32_t\nlibdeflate_adler32(uint32_t adler, const void *buffer, size_t len);\n\n\n/*\n * libdeflate_crc32() updates a running CRC-32 checksum with 'len' bytes of data\n * and returns the updated checksum.  When starting a new checksum, the required\n * initial value for 'crc' is 0.  This value is also returned when 'buffer' is\n * specified as NULL.\n */\nLIBDEFLATEAPI uint32_t\nlibdeflate_crc32(uint32_t crc, const void *buffer, size_t len);\n\n/* ========================================================================== */\n/*                           Custom memory allocator                          */\n/* ========================================================================== */\n\n/*\n * Install a custom memory allocator which libdeflate will use for all memory\n * allocations by default.  'malloc_func' is a function that must behave like\n * malloc(), and 'free_func' is a function that must behave like free().\n *\n * The per-(de)compressor custom memory allocator that can be specified in\n * 'struct libdeflate_options' takes priority over this.\n *\n * This doesn't affect the free() function that will be used to free\n * (de)compressors that were already in existence when this is called.\n */\nLIBDEFLATEAPI void\nlibdeflate_set_memory_allocator(void *(*malloc_func)(size_t),\n\t\t\t\tvoid (*free_func)(void *));\n\n/*\n * Advanced options.  This is the options structure that\n * libdeflate_alloc_compressor_ex() and libdeflate_alloc_decompressor_ex()\n * require.  Most users won't need this and should just use the non-\"_ex\"\n * functions instead.  If you do need this, it should be initialized like this:\n *\n *\tstruct libdeflate_options options;\n *\n *\tmemset(&options, 0, sizeof(options));\n *\toptions.sizeof_options = sizeof(options);\n *\t// Then set the fields that you need to override the defaults for.\n */\nstruct libdeflate_options {\n\n\t/*\n\t * This field must be set to the struct size.  This field exists for\n\t * extensibility, so that fields can be appended to this struct in\n\t * future versions of libdeflate while still supporting old binaries.\n\t */\n\tsize_t sizeof_options;\n\n\t/*\n\t * An optional custom memory allocator to use for this (de)compressor.\n\t * 'malloc_func' must be a function that behaves like malloc(), and\n\t * 'free_func' must be a function that behaves like free().\n\t *\n\t * This is useful in cases where a process might have multiple users of\n\t * libdeflate who want to use different memory allocators.  For example,\n\t * a library might want to use libdeflate with a custom memory allocator\n\t * without interfering with user code that might use libdeflate too.\n\t *\n\t * This takes priority over the \"global\" memory allocator (which by\n\t * default is malloc() and free(), but can be changed by\n\t * libdeflate_set_memory_allocator()).  Moreover, libdeflate will never\n\t * call the \"global\" memory allocator if a per-(de)compressor custom\n\t * allocator is always given.\n\t */\n\tvoid *(*malloc_func)(size_t);\n\tvoid (*free_func)(void *);\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* LIBDEFLATE_H */\n"
  },
  {
    "path": "vendor/core/vendor/openapi/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/2.0/schema/2017-08-27",
    "content": "{\n  \"title\": \"A JSON Schema for Swagger 2.0 API.\",\n  \"id\": \"http://swagger.io/v2/schema.json#\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"required\": [\n    \"swagger\",\n    \"info\",\n    \"paths\"\n  ],\n  \"additionalProperties\": false,\n  \"patternProperties\": {\n    \"^x-\": {\n      \"$ref\": \"#/definitions/vendorExtension\"\n    }\n  },\n  \"properties\": {\n    \"swagger\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"2.0\"\n      ],\n      \"description\": \"The Swagger version of this document.\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/info\"\n    },\n    \"host\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^{}/ :\\\\\\\\]+(?::\\\\d+)?$\",\n      \"description\": \"The host (name or ip) of the API. Example: 'swagger.io'\"\n    },\n    \"basePath\": {\n      \"type\": \"string\",\n      \"pattern\": \"^/\",\n      \"description\": \"The base path to the API. Example: '/api'.\"\n    },\n    \"schemes\": {\n      \"$ref\": \"#/definitions/schemesList\"\n    },\n    \"consumes\": {\n      \"description\": \"A list of MIME types accepted by the API.\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/mediaTypeList\"\n        }\n      ]\n    },\n    \"produces\": {\n      \"description\": \"A list of MIME types the API can produce.\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/mediaTypeList\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/paths\"\n    },\n    \"definitions\": {\n      \"$ref\": \"#/definitions/definitions\"\n    },\n    \"parameters\": {\n      \"$ref\": \"#/definitions/parameterDefinitions\"\n    },\n    \"responses\": {\n      \"$ref\": \"#/definitions/responseDefinitions\"\n    },\n    \"security\": {\n      \"$ref\": \"#/definitions/security\"\n    },\n    \"securityDefinitions\": {\n      \"$ref\": \"#/definitions/securityDefinitions\"\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/externalDocs\"\n    }\n  },\n  \"definitions\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"description\": \"General information about the API.\",\n      \"required\": [\n        \"version\",\n        \"title\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\",\n          \"description\": \"A unique and precise title of the API.\"\n        },\n        \"version\": {\n          \"type\": \"string\",\n          \"description\": \"A semantic version number of the API.\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A longer description of the API. Should be different from the title.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"description\": \"The terms of service for the API.\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/license\"\n        }\n      }\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"description\": \"Contact information for the owners of the API.\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The identifying name of the contact person/organization.\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"description\": \"The URL pointing to the contact information.\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"description\": \"The email address of the contact person/organization.\",\n          \"format\": \"email\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the license type. It's encouraged to use an OSI compatible license.\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"description\": \"The URL pointing to the license.\",\n          \"format\": \"uri\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"description\": \"Relative paths to the individual endpoints. They must be relative to the 'basePath'.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        },\n        \"^/\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"definitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/schema\"\n      },\n      \"description\": \"One or more JSON objects describing the schemas being consumed and produced by the API.\"\n    },\n    \"parameterDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/parameter\"\n      },\n      \"description\": \"One or more JSON representations for parameters\"\n    },\n    \"responseDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/response\"\n      },\n      \"description\": \"One or more JSON representations for responses\"\n    },\n    \"externalDocs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"description\": \"information about external documentation\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"examples\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"mimeType\": {\n      \"type\": \"string\",\n      \"description\": \"The MIME type of the HTTP message.\"\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"summary\": {\n          \"type\": \"string\",\n          \"description\": \"A brief summary of the operation.\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A longer description of the operation, GitHub Flavored Markdown is allowed.\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"operationId\": {\n          \"type\": \"string\",\n          \"description\": \"A unique identifier of the operation.\"\n        },\n        \"produces\": {\n          \"description\": \"A list of MIME types the API can produce.\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/mediaTypeList\"\n            }\n          ]\n        },\n        \"consumes\": {\n          \"description\": \"A list of MIME types the API can consume.\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/mediaTypeList\"\n            }\n          ]\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersList\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responses\"\n        },\n        \"schemes\": {\n          \"$ref\": \"#/definitions/schemesList\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"security\": {\n          \"$ref\": \"#/definitions/security\"\n        }\n      }\n    },\n    \"pathItem\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"get\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersList\"\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"description\": \"Response objects names can either be any valid HTTP status code or 'default'.\",\n      \"minProperties\": 1,\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^([0-9]{3})$|^(default)$\": {\n          \"$ref\": \"#/definitions/responseValue\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"not\": {\n        \"type\": \"object\",\n        \"additionalProperties\": false,\n        \"patternProperties\": {\n          \"^x-\": {\n            \"$ref\": \"#/definitions/vendorExtension\"\n          }\n        }\n      }\n    },\n    \"responseValue\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/response\"\n        },\n        {\n          \"$ref\": \"#/definitions/jsonReference\"\n        }\n      ]\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"description\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/fileSchema\"\n            }\n          ]\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headers\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examples\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"headers\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/header\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"integer\",\n            \"boolean\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"vendorExtension\": {\n      \"description\": \"Any property starting with x- is valid.\",\n      \"additionalProperties\": true,\n      \"additionalItems\": true\n    },\n    \"bodyParameter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"in\",\n        \"schema\"\n      ],\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"body\"\n          ]\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schema\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"headerParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"header\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"queryParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"query\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"allows sending a parameter by name only or with an empty value.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormatWithMulti\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"formDataParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"formData\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"allows sending a parameter by name only or with an empty value.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\",\n            \"file\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormatWithMulti\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"pathParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"required\": [\n        \"required\"\n      ],\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"enum\": [\n            true\n          ],\n          \"description\": \"Determines whether or not this parameter is required or optional.\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"path\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"nonBodyParameter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"in\",\n        \"type\"\n      ],\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/headerParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/formDataParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/queryParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/pathParameterSubSchema\"\n        }\n      ]\n    },\n    \"parameter\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/bodyParameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/nonBodyParameter\"\n        }\n      ]\n    },\n    \"schema\": {\n      \"type\": \"object\",\n      \"description\": \"A deterministic version of a JSON Schema object.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"description\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n        },\n        \"default\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n        },\n        \"maximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"pattern\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n        },\n        \"maxProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/stringArray\"\n        },\n        \"enum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n        },\n        \"additionalProperties\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ],\n          \"default\": {}\n        },\n        \"type\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/type\"\n        },\n        \"items\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/definitions/schema\"\n              }\n            }\n          ],\n          \"default\": {}\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"items\": {\n            \"$ref\": \"#/definitions/schema\"\n          }\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/schema\"\n          },\n          \"default\": {}\n        },\n        \"discriminator\": {\n          \"type\": \"string\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/xml\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"fileSchema\": {\n      \"type\": \"object\",\n      \"description\": \"A deterministic version of a JSON Schema object.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"description\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n        },\n        \"default\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/stringArray\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"file\"\n          ]\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"primitivesItems\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"integer\",\n            \"boolean\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/securityRequirement\"\n      },\n      \"uniqueItems\": true\n    },\n    \"securityRequirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        },\n        \"uniqueItems\": true\n      }\n    },\n    \"xml\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"securityDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/basicAuthenticationSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/apiKeySecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2ImplicitSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2PasswordSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2ApplicationSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2AccessCodeSecurity\"\n          }\n        ]\n      }\n    },\n    \"basicAuthenticationSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"basic\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"apiKeySecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"name\",\n        \"in\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apiKey\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"header\",\n            \"query\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2ImplicitSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"authorizationUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"implicit\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2PasswordSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"password\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2ApplicationSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"application\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2AccessCodeSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"authorizationUrl\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"accessCode\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2Scopes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"mediaTypeList\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/mimeType\"\n      },\n      \"uniqueItems\": true\n    },\n    \"parametersList\": {\n      \"type\": \"array\",\n      \"description\": \"The parameters needed to send a valid API call.\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/parameter\"\n          },\n          {\n            \"$ref\": \"#/definitions/jsonReference\"\n          }\n        ]\n      },\n      \"uniqueItems\": true\n    },\n    \"schemesList\": {\n      \"type\": \"array\",\n      \"description\": \"The transfer protocol of the API.\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enum\": [\n          \"http\",\n          \"https\",\n          \"ws\",\n          \"wss\"\n        ]\n      },\n      \"uniqueItems\": true\n    },\n    \"collectionFormat\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"csv\",\n        \"ssv\",\n        \"tsv\",\n        \"pipes\"\n      ],\n      \"default\": \"csv\"\n    },\n    \"collectionFormatWithMulti\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"csv\",\n        \"ssv\",\n        \"tsv\",\n        \"pipes\",\n        \"multi\"\n      ],\n      \"default\": \"csv\"\n    },\n    \"title\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n    },\n    \"description\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n    },\n    \"default\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n    },\n    \"multipleOf\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n    },\n    \"maximum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n    },\n    \"exclusiveMaximum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n    },\n    \"minimum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n    },\n    \"exclusiveMinimum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n    },\n    \"maxLength\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n    },\n    \"minLength\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n    },\n    \"pattern\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n    },\n    \"maxItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n    },\n    \"minItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n    },\n    \"uniqueItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n    },\n    \"enum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n    },\n    \"jsonReference\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.0/schema/2021-09-28",
    "content": "{\n  \"id\": \"https://spec.openapis.org/oas/3.0/schema/2021-09-28\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"description\": \"The description of OpenAPI v3.0.x documents, as defined by https://spec.openapis.org/oas/v3.0.3\",\n  \"type\": \"object\",\n  \"required\": [\n    \"openapi\",\n    \"info\",\n    \"paths\"\n  ],\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.0\\\\.\\\\d(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/Info\"\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/ExternalDocumentation\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Server\"\n      }\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/SecurityRequirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/Paths\"\n    },\n    \"components\": {\n      \"$ref\": \"#/definitions/Components\"\n    }\n  },\n  \"patternProperties\": {\n    \"^x-\": {\n    }\n  },\n  \"additionalProperties\": false,\n  \"definitions\": {\n    \"Reference\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"patternProperties\": {\n        \"^\\\\$ref$\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      }\n    },\n    \"Info\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/Contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/License\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"License\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Server\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ServerVariable\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ServerVariable\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"default\"\n      ],\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Schema\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                }\n              ]\n            }\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Response\"\n                }\n              ]\n            }\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Parameter\"\n                }\n              ]\n            }\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Example\"\n                }\n              ]\n            }\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/RequestBody\"\n                }\n              ]\n            }\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Header\"\n                }\n              ]\n            }\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SecurityScheme\"\n                }\n              ]\n            }\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Link\"\n                }\n              ]\n            }\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Callback\"\n                }\n              ]\n            }\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"multipleOf\": {\n          \"type\": \"number\",\n          \"minimum\": 0,\n          \"exclusiveMinimum\": true\n        },\n        \"maximum\": {\n          \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"minimum\": {\n          \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"maxLength\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minLength\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"pattern\": {\n          \"type\": \"string\",\n          \"format\": \"regex\"\n        },\n        \"maxItems\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minItems\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"uniqueItems\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"maxProperties\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minProperties\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"required\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        },\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n          },\n          \"minItems\": 1,\n          \"uniqueItems\": false\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"array\",\n            \"boolean\",\n            \"integer\",\n            \"number\",\n            \"object\",\n            \"string\"\n          ]\n        },\n        \"not\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"oneOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"anyOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"items\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"additionalProperties\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ],\n          \"default\": true\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"default\": {\n        },\n        \"nullable\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"discriminator\": {\n          \"$ref\": \"#/definitions/Discriminator\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"example\": {\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/XML\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Discriminator\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"properties\": {\n        \"propertyName\": {\n          \"type\": \"string\"\n        },\n        \"mapping\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"XML\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Response\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"description\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Header\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Link\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"MediaType\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"example\": {\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/Encoding\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false,\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        }\n      ]\n    },\n    \"Example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n        },\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"style\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"simple\"\n          ],\n          \"default\": \"simple\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          },\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        },\n        \"example\": {\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false,\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        },\n        {\n          \"$ref\": \"#/definitions/SchemaXORContent\"\n        }\n      ]\n    },\n    \"Paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^\\\\/\": {\n          \"$ref\": \"#/definitions/PathItem\"\n        },\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PathItem\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Parameter\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|put|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Operation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Parameter\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        },\n        \"requestBody\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/RequestBody\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/Responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Callback\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/SecurityRequirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Server\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Response\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:\\\\d{2}|XX)$\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Response\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"^x-\": {\n        }\n      },\n      \"minProperties\": 1,\n      \"additionalProperties\": false\n    },\n    \"SecurityRequirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Tag\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExternalDocumentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ExampleXORExamples\": {\n      \"description\": \"Example and examples are mutually exclusive\",\n      \"not\": {\n        \"required\": [\n          \"example\",\n          \"examples\"\n        ]\n      }\n    },\n    \"SchemaXORContent\": {\n      \"description\": \"Schema and content are mutually exclusive, at least one is required\",\n      \"not\": {\n        \"required\": [\n          \"schema\",\n          \"content\"\n        ]\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ],\n          \"description\": \"Some properties are not allowed if content is present\",\n          \"allOf\": [\n            {\n              \"not\": {\n                \"required\": [\n                  \"style\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"explode\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"allowReserved\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"example\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"examples\"\n                ]\n              }\n            }\n          ]\n        }\n      ]\n    },\n    \"Parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          },\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        },\n        \"example\": {\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        },\n        {\n          \"$ref\": \"#/definitions/SchemaXORContent\"\n        },\n        {\n          \"$ref\": \"#/definitions/ParameterLocation\"\n        }\n      ]\n    },\n    \"ParameterLocation\": {\n      \"description\": \"Parameter location\",\n      \"oneOf\": [\n        {\n          \"description\": \"Parameter in path\",\n          \"required\": [\n            \"required\"\n          ],\n          \"properties\": {\n            \"in\": {\n              \"enum\": [\n                \"path\"\n              ]\n            },\n            \"style\": {\n              \"enum\": [\n                \"matrix\",\n                \"label\",\n                \"simple\"\n              ],\n              \"default\": \"simple\"\n            },\n            \"required\": {\n              \"enum\": [\n                true\n              ]\n            }\n          }\n        },\n        {\n          \"description\": \"Parameter in query\",\n          \"properties\": {\n            \"in\": {\n              \"enum\": [\n                \"query\"\n              ]\n            },\n            \"style\": {\n              \"enum\": [\n                \"form\",\n                \"spaceDelimited\",\n                \"pipeDelimited\",\n                \"deepObject\"\n              ],\n              \"default\": \"form\"\n            }\n          }\n        },\n        {\n          \"description\": \"Parameter in header\",\n          \"properties\": {\n            \"in\": {\n              \"enum\": [\n                \"header\"\n              ]\n            },\n            \"style\": {\n              \"enum\": [\n                \"simple\"\n              ],\n              \"default\": \"simple\"\n            }\n          }\n        },\n        {\n          \"description\": \"Parameter in cookie\",\n          \"properties\": {\n            \"in\": {\n              \"enum\": [\n                \"cookie\"\n              ]\n            },\n            \"style\": {\n              \"enum\": [\n                \"form\"\n              ],\n              \"default\": \"form\"\n            }\n          }\n        }\n      ]\n    },\n    \"RequestBody\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"content\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          }\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"SecurityScheme\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/APIKeySecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/HTTPSecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/OAuth2SecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/OpenIdConnectSecurityScheme\"\n        }\n      ]\n    },\n    \"APIKeySecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"name\",\n        \"in\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apiKey\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"header\",\n            \"query\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"HTTPSecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"scheme\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"scheme\": {\n          \"type\": \"string\"\n        },\n        \"bearerFormat\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"http\"\n          ]\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false,\n      \"oneOf\": [\n        {\n          \"description\": \"Bearer\",\n          \"properties\": {\n            \"scheme\": {\n              \"type\": \"string\",\n              \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n            }\n          }\n        },\n        {\n          \"description\": \"Non Bearer\",\n          \"not\": {\n            \"required\": [\n              \"bearerFormat\"\n            ]\n          },\n          \"properties\": {\n            \"scheme\": {\n              \"not\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            }\n          }\n        }\n      ]\n    },\n    \"OAuth2SecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"flows\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flows\": {\n          \"$ref\": \"#/definitions/OAuthFlows\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"OpenIdConnectSecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"openIdConnectUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"openIdConnect\"\n          ]\n        },\n        \"openIdConnectUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"OAuthFlows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/definitions/ImplicitOAuthFlow\"\n        },\n        \"password\": {\n          \"$ref\": \"#/definitions/PasswordOAuthFlow\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/definitions/ClientCredentialsFlow\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/definitions/AuthorizationCodeOAuthFlow\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ImplicitOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"authorizationUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"PasswordOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"ClientCredentialsFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"AuthorizationCodeOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"authorizationUrl\",\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"Link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n          }\n        },\n        \"requestBody\": {\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/definitions/Server\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      },\n      \"additionalProperties\": false,\n      \"not\": {\n        \"description\": \"Operation Id and Operation Ref are mutually exclusive\",\n        \"required\": [\n          \"operationId\",\n          \"operationRef\"\n        ]\n      }\n    },\n    \"Callback\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/PathItem\"\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n        }\n      }\n    },\n    \"Encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Header\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"style\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"additionalProperties\": false\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.0/schema/2024-10-18",
    "content": "{\n  \"id\": \"https://spec.openapis.org/oas/3.0/schema/2024-10-18\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"description\": \"The description of OpenAPI v3.0.x Documents\",\n  \"type\": \"object\",\n  \"required\": [\n    \"openapi\",\n    \"info\",\n    \"paths\"\n  ],\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.0\\\\.\\\\d(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/Info\"\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/ExternalDocumentation\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Server\"\n      }\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/SecurityRequirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/Paths\"\n    },\n    \"components\": {\n      \"$ref\": \"#/definitions/Components\"\n    }\n  },\n  \"patternProperties\": {\n    \"^x-\": {}\n  },\n  \"additionalProperties\": false,\n  \"definitions\": {\n    \"Reference\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"patternProperties\": {\n        \"^\\\\$ref$\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      }\n    },\n    \"Info\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/Contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/License\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"License\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Server\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ServerVariable\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"ServerVariable\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"default\"\n      ],\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Schema\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                }\n              ]\n            }\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Response\"\n                }\n              ]\n            }\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Parameter\"\n                }\n              ]\n            }\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Example\"\n                }\n              ]\n            }\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/RequestBody\"\n                }\n              ]\n            }\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Header\"\n                }\n              ]\n            }\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/SecurityScheme\"\n                }\n              ]\n            }\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Link\"\n                }\n              ]\n            }\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n              \"oneOf\": [\n                {\n                  \"$ref\": \"#/definitions/Reference\"\n                },\n                {\n                  \"$ref\": \"#/definitions/Callback\"\n                }\n              ]\n            }\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"multipleOf\": {\n          \"type\": \"number\",\n          \"minimum\": 0,\n          \"exclusiveMinimum\": true\n        },\n        \"maximum\": {\n          \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"minimum\": {\n          \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"maxLength\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minLength\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"pattern\": {\n          \"type\": \"string\",\n          \"format\": \"regex\"\n        },\n        \"maxItems\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minItems\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"uniqueItems\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"maxProperties\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"minProperties\": {\n          \"type\": \"integer\",\n          \"minimum\": 0,\n          \"default\": 0\n        },\n        \"required\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1,\n          \"uniqueItems\": true\n        },\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {},\n          \"minItems\": 1,\n          \"uniqueItems\": false\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"array\",\n            \"boolean\",\n            \"integer\",\n            \"number\",\n            \"object\",\n            \"string\"\n          ]\n        },\n        \"not\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"oneOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"anyOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"items\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Schema\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"additionalProperties\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ],\n          \"default\": true\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"default\": {},\n        \"nullable\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"discriminator\": {\n          \"$ref\": \"#/definitions/Discriminator\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"example\": {},\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/XML\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Discriminator\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"properties\": {\n        \"propertyName\": {\n          \"type\": \"string\"\n        },\n        \"mapping\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"XML\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Response\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"description\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Header\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Link\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"MediaType\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"example\": {},\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/Encoding\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false,\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        }\n      ]\n    },\n    \"Example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": {},\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"style\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"simple\"\n          ],\n          \"default\": \"simple\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          },\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        },\n        \"example\": {},\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false,\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        },\n        {\n          \"$ref\": \"#/definitions/SchemaXORContent\"\n        }\n      ]\n    },\n    \"Paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^\\\\/\": {\n          \"$ref\": \"#/definitions/PathItem\"\n        },\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"PathItem\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"get\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/definitions/Operation\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Parameter\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Operation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Parameter\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        },\n        \"requestBody\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/RequestBody\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/Responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Callback\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/SecurityRequirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Server\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Response\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:\\\\d{2}|XX)$\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Response\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"^x-\": {}\n      },\n      \"minProperties\": 1,\n      \"additionalProperties\": false\n    },\n    \"SecurityRequirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Tag\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/ExternalDocumentation\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"ExternalDocumentation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"ExampleXORExamples\": {\n      \"description\": \"Example and examples are mutually exclusive\",\n      \"not\": {\n        \"required\": [\n          \"example\",\n          \"examples\"\n        ]\n      }\n    },\n    \"SchemaXORContent\": {\n      \"description\": \"Schema and content are mutually exclusive, at least one is required\",\n      \"not\": {\n        \"required\": [\n          \"schema\",\n          \"content\"\n        ]\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ],\n          \"description\": \"Some properties are not allowed if content is present\",\n          \"allOf\": [\n            {\n              \"not\": {\n                \"required\": [\n                  \"style\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"explode\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"allowReserved\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"example\"\n                ]\n              }\n            },\n            {\n              \"not\": {\n                \"required\": [\n                  \"examples\"\n                ]\n              }\n            }\n          ]\n        }\n      ]\n    },\n    \"Parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/Schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/Reference\"\n            }\n          ]\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          },\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        },\n        \"example\": {},\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Example\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/ExampleXORExamples\"\n        },\n        {\n          \"$ref\": \"#/definitions/SchemaXORContent\"\n        }\n      ],\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/PathParameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/QueryParameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/HeaderParameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/CookieParameter\"\n        }\n      ]\n    },\n    \"PathParameter\": {\n      \"description\": \"Parameter in path\",\n      \"required\": [\n        \"required\"\n      ],\n      \"properties\": {\n        \"in\": {\n          \"enum\": [\n            \"path\"\n          ]\n        },\n        \"style\": {\n          \"enum\": [\n            \"matrix\",\n            \"label\",\n            \"simple\"\n          ],\n          \"default\": \"simple\"\n        },\n        \"required\": {\n          \"enum\": [\n            true\n          ]\n        }\n      }\n    },\n    \"QueryParameter\": {\n      \"description\": \"Parameter in query\",\n      \"properties\": {\n        \"in\": {\n          \"enum\": [\n            \"query\"\n          ]\n        },\n        \"style\": {\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ],\n          \"default\": \"form\"\n        }\n      }\n    },\n    \"HeaderParameter\": {\n      \"description\": \"Parameter in header\",\n      \"properties\": {\n        \"in\": {\n          \"enum\": [\n            \"header\"\n          ]\n        },\n        \"style\": {\n          \"enum\": [\n            \"simple\"\n          ],\n          \"default\": \"simple\"\n        }\n      }\n    },\n    \"CookieParameter\": {\n      \"description\": \"Parameter in cookie\",\n      \"properties\": {\n        \"in\": {\n          \"enum\": [\n            \"cookie\"\n          ]\n        },\n        \"style\": {\n          \"enum\": [\n            \"form\"\n          ],\n          \"default\": \"form\"\n        }\n      }\n    },\n    \"RequestBody\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"content\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/MediaType\"\n          }\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"SecurityScheme\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/APIKeySecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/HTTPSecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/OAuth2SecurityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/OpenIdConnectSecurityScheme\"\n        }\n      ]\n    },\n    \"APIKeySecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"name\",\n        \"in\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apiKey\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"header\",\n            \"query\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"HTTPSecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"scheme\",\n        \"type\"\n      ],\n      \"properties\": {\n        \"scheme\": {\n          \"type\": \"string\"\n        },\n        \"bearerFormat\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"http\"\n          ]\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false,\n      \"oneOf\": [\n        {\n          \"description\": \"Bearer\",\n          \"properties\": {\n            \"scheme\": {\n              \"type\": \"string\",\n              \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n            }\n          }\n        },\n        {\n          \"description\": \"Non Bearer\",\n          \"not\": {\n            \"required\": [\n              \"bearerFormat\"\n            ]\n          },\n          \"properties\": {\n            \"scheme\": {\n              \"not\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            }\n          }\n        }\n      ]\n    },\n    \"OAuth2SecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"flows\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flows\": {\n          \"$ref\": \"#/definitions/OAuthFlows\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"OpenIdConnectSecurityScheme\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"type\",\n        \"openIdConnectUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"openIdConnect\"\n          ]\n        },\n        \"openIdConnectUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"OAuthFlows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/definitions/ImplicitOAuthFlow\"\n        },\n        \"password\": {\n          \"$ref\": \"#/definitions/PasswordOAuthFlow\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/definitions/ClientCredentialsFlow\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/definitions/AuthorizationCodeOAuthFlow\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"ImplicitOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"authorizationUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"PasswordOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"ClientCredentialsFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"AuthorizationCodeOAuthFlow\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"authorizationUrl\",\n        \"tokenUrl\",\n        \"scopes\"\n      ],\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"scopes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"Link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {}\n        },\n        \"requestBody\": {},\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/definitions/Server\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false,\n      \"not\": {\n        \"description\": \"Operation Id and Operation Ref are mutually exclusive\",\n        \"required\": [\n          \"operationId\",\n          \"operationRef\"\n        ]\n      }\n    },\n    \"Callback\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/PathItem\"\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      }\n    },\n    \"Encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"oneOf\": [\n              {\n                \"$ref\": \"#/definitions/Header\"\n              },\n              {\n                \"$ref\": \"#/definitions/Reference\"\n              }\n            ]\n          }\n        },\n        \"style\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {}\n      },\n      \"additionalProperties\": false\n    }\n  }\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/dialect/2024-10-25",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/dialect/2024-10-25\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OpenAPI 3.1 Schema Object Dialect\",\n  \"description\": \"A JSON Schema dialect describing schemas found in OpenAPI v3.1 Descriptions\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/content\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n    \"https://spec.openapis.org/oas/3.1/vocab/base\": false\n  },\n  \"allOf\": [\n    {\n      \"$ref\": \"https://json-schema.org/draft/2020-12/schema\"\n    },\n    {\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/meta/2024-10-25\"\n    }\n  ]\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/dialect/2024-11-10",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OpenAPI 3.1 Schema Object Dialect\",\n  \"description\": \"A JSON Schema dialect describing schemas found in OpenAPI v3.1 Descriptions\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/content\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n    \"https://spec.openapis.org/oas/3.1/vocab/base\": false\n  },\n  \"allOf\": [\n    {\n      \"$ref\": \"https://json-schema.org/draft/2020-12/schema\"\n    },\n    {\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/meta/2024-11-10\"\n    }\n  ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/dialect/base",
    "content": "{\n    \"$id\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n    \"title\": \"OpenAPI 3.1 Schema Object Dialect\",\n    \"description\": \"A JSON Schema dialect describing schemas found in OpenAPI documents\",\n\n    \"$vocabulary\": {\n        \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n        \"https://json-schema.org/draft/2020-12/vocab/content\": true,\n        \"https://spec.openapis.org/oas/3.1/vocab/base\": false\n    },\n\n    \"$dynamicAnchor\": \"meta\",\n\n    \"allOf\": [\n        { \"$ref\": \"https://json-schema.org/draft/2020-12/schema\" },\n        { \"$ref\": \"https://spec.openapis.org/oas/3.1/meta/base\" }\n    ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/meta/2024-10-25",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/meta/2024-10-25\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OAS Base Vocabulary\",\n  \"description\": \"A JSON Schema Vocabulary used in the OpenAPI Schema Dialect\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://spec.openapis.org/oas/3.1/vocab/base\": true\n  },\n  \"type\": [\n    \"object\",\n    \"boolean\"\n  ],\n  \"properties\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/discriminator\"\n    },\n    \"example\": true,\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-docs\"\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/xml\"\n    }\n  },\n  \"$defs\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"mapping\": {\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"type\": \"object\"\n        },\n        \"propertyName\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"extensible\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"external-docs\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"format\": \"uri-reference\",\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"attribute\": {\n          \"type\": \"boolean\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"format\": \"uri\",\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\"\n        }\n      },\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    }\n  }\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/meta/2024-11-10",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/meta/2024-11-10\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OAS Base Vocabulary\",\n  \"description\": \"A JSON Schema Vocabulary used in the OpenAPI Schema Dialect\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://spec.openapis.org/oas/3.1/vocab/base\": true\n  },\n  \"type\": [\n    \"object\",\n    \"boolean\"\n  ],\n  \"properties\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/discriminator\"\n    },\n    \"example\": true,\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-docs\"\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/xml\"\n    }\n  },\n  \"$defs\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"mapping\": {\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"type\": \"object\"\n        },\n        \"propertyName\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"extensible\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"external-docs\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"format\": \"uri-reference\",\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"attribute\": {\n          \"type\": \"boolean\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"format\": \"uri\",\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\"\n        }\n      },\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/meta/base",
    "content": "{\n    \"$id\": \"https://spec.openapis.org/oas/3.1/meta/base\",\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n    \"title\": \"OAS Base vocabulary\",\n    \"description\": \"A JSON Schema Vocabulary used in the OpenAPI Schema Dialect\",\n\n    \"$vocabulary\": {\n        \"https://spec.openapis.org/oas/3.1/vocab/base\": true\n    },\n\n    \"$dynamicAnchor\": \"meta\",\n\n    \"type\": [\"object\", \"boolean\"],\n    \"properties\": {\n        \"example\": true,\n        \"discriminator\": { \"$ref\": \"#/$defs/discriminator\" },\n        \"externalDocs\": { \"$ref\": \"#/$defs/external-docs\" },\n        \"xml\": { \"$ref\": \"#/$defs/xml\" }\n    },\n\n    \"$defs\": {\n        \"extensible\": {\n            \"patternProperties\": {\n                \"^x-\": true\n            }\n        },\n\n        \"discriminator\": {\n            \"$ref\": \"#/$defs/extensible\",\n            \"type\": \"object\",\n            \"properties\": {\n                \"propertyName\": {\n                    \"type\": \"string\"\n                },\n                \"mapping\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                }\n            },\n            \"required\": [\"propertyName\"],\n            \"unevaluatedProperties\": false\n        },\n\n        \"external-docs\": {\n            \"$ref\": \"#/$defs/extensible\",\n            \"type\": \"object\",\n            \"properties\": {\n                \"url\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri-reference\"\n                },\n                \"description\": {\n                    \"type\": \"string\"\n                }\n            },\n            \"required\": [\"url\"],\n            \"unevaluatedProperties\": false\n        },\n\n        \"xml\": {\n            \"$ref\": \"#/$defs/extensible\",\n            \"type\": \"object\",\n            \"properties\": {\n                \"name\": {\n                    \"type\": \"string\"\n                },\n                \"namespace\": {\n                    \"type\": \"string\",\n                    \"format\": \"uri\"\n                },\n                \"prefix\": {\n                    \"type\": \"string\"\n                },\n                \"attribute\": {\n                    \"type\": \"boolean\"\n                },\n                \"wrapped\": {\n                    \"type\": \"boolean\"\n                }\n            },\n            \"unevaluatedProperties\": false\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2021-03-02",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2021-03-02\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"$ref\": \"#/$defs/server\"\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"identifier\"\n          ]\n        },\n        {\n          \"required\": [\n            \"url\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"descriptions\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        }\n      },\n      \"required\": [\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"simple\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5][0-9X]{2}$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"operationId\": true,\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"enum\": [\n                \"simple\"\n              ]\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"schema\": {\n              \"$dynamicRef\": \"#meta\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        },\n        \"content\": {\n          \"properties\": {\n            \"content\": {\n              \"$ref\": \"#/$defs/content\"\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"const\": \"bearer\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"$ref\": \"#/$defs/uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"uri\": {\n      \"type\": \"string\",\n      \"format\": \"uri\"\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2021-04-15",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2021-04-15\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      }\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"identifier\"\n          ]\n        },\n        {\n          \"required\": [\n            \"url\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"descriptions\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|put|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        }\n      },\n      \"required\": [\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"simple\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5][0-9X]{2}$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"$ref\": \"#/$defs/uri\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"operationId\": true,\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"enum\": [\n                \"simple\"\n              ]\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"schema\": {\n              \"$dynamicRef\": \"#meta\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        },\n        \"content\": {\n          \"properties\": {\n            \"content\": {\n              \"$ref\": \"#/$defs/content\"\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"$ref\": \"#/$defs/uri\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"const\": \"bearer\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"$ref\": \"#/$defs/uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"uri\": {\n      \"type\": \"string\",\n      \"format\": \"uri\"\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2021-05-20",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2021-05-20\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      }\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"identifier\"\n          ]\n        },\n        {\n          \"required\": [\n            \"url\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"descriptions\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|put|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        }\n      },\n      \"required\": [\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"simple\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5][0-9X]{2}$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": true,\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"enum\": [\n                \"simple\"\n              ]\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"schema\": {\n              \"$dynamicRef\": \"#meta\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        },\n        \"content\": {\n          \"properties\": {\n            \"content\": {\n              \"$ref\": \"#/$defs/content\"\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"const\": \"bearer\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2021-09-28",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2021-09-28\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      }\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"identifier\"\n          ]\n        },\n        {\n          \"required\": [\n            \"url\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"descriptions\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|put|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        }\n      },\n      \"required\": [\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"name\": {\n                    \"pattern\": \"[^/#?]+$\"\n                  },\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": true,\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2022-02-27",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2022-02-27\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x documents without schema validation, as defined by https://spec.openapis.org/oas/v3.1.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        { \"url\": \"/\" }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"identifier\"\n          ]\n        },\n        {\n          \"required\": [\n            \"url\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(get|put|post|delete|options|head|patch|trace)$\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"name\": {\n                    \"pattern\": \"[^/#?]+$\"\n                  },\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": true,\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2022-10-07",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2022-10-07\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x documents without schema validation, as defined by https://spec.openapis.org/oas/v3.1.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"name\": {\n                    \"pattern\": \"[^/#?]+$\"\n                  },\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            },\n            \"styles-for-form\": {\n              \"if\": {\n                \"properties\": {\n                  \"style\": {\n                    \"const\": \"form\"\n                  }\n                },\n                \"required\": [\n                  \"style\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": true\n                  }\n                }\n              },\n              \"else\": {\n                \"properties\": {\n                  \"explode\": {\n                    \"default\": false\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/encoding/$defs/explode-default\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"explode-default\": {\n          \"if\": {\n            \"properties\": {\n              \"style\": {\n                \"const\": \"form\"\n              }\n            },\n            \"required\": [\n              \"style\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": true\n              }\n            }\n          },\n          \"else\": {\n            \"properties\": {\n              \"explode\": {\n                \"default\": false\n              }\n            }\n          }\n        }\n      }\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item-or-reference\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1.0#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2024-11-14",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2024-11-14\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents without Schema Object validation\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/2024-10-25\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/styles-for-form\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"if\": {\n        \"$comment\": \"either default, or at least one response code property must exist\",\n        \"patternProperties\": {\n          \"^[1-5](?:[0-9]{2}|XX)$\": false\n        }\n      },\n      \"then\": {\n        \"required\": [\n          \"default\"\n        ]\n      }\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"styles-for-form\": {\n      \"if\": {\n        \"properties\": {\n          \"style\": {\n            \"const\": \"form\"\n          }\n        },\n        \"required\": [\n          \"style\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": true\n          }\n        }\n      },\n      \"else\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": false\n          }\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2025-02-13",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2025-02-13\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents without Schema Object validation\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri-reference\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/styles-for-form\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"if\": {\n        \"$comment\": \"either default, or at least one response code property must exist\",\n        \"patternProperties\": {\n          \"^[1-5](?:[0-9]{2}|XX)$\": false\n        }\n      },\n      \"then\": {\n        \"required\": [\n          \"default\"\n        ]\n      }\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"body\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri-reference\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"styles-for-form\": {\n      \"if\": {\n        \"properties\": {\n          \"style\": {\n            \"const\": \"form\"\n          }\n        },\n        \"required\": [\n          \"style\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": true\n          }\n        }\n      },\n      \"else\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": false\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2025-08-31",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2025-08-31\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents without Schema Object validation\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri-reference\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                },\n                \"required\": [\n                  \"in\"\n                ]\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"default\": \"form\",\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/styles-for-form\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"if\": {\n        \"$comment\": \"either default, or at least one response code property must exist\",\n        \"patternProperties\": {\n          \"^[1-5](?:[0-9]{2}|XX)$\": false\n        }\n      },\n      \"then\": {\n        \"required\": [\n          \"default\"\n        ]\n      }\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            },\n            \"required\": [\n              \"type\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri-reference\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"example\",\n          \"examples\"\n        ]\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"styles-for-form\": {\n      \"if\": {\n        \"properties\": {\n          \"style\": {\n            \"const\": \"form\"\n          }\n        },\n        \"required\": [\n          \"style\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": true\n          }\n        }\n      },\n      \"else\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": false\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema/2025-09-15",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema/2025-09-15\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents without Schema Object validation\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.1\\\\.\\\\d+(-.+)?$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri-reference\",\n      \"default\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(?:schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"if\": {\n        \"properties\": {\n          \"in\": {\n            \"const\": \"query\"\n          }\n        }\n      },\n      \"then\": {\n        \"properties\": {\n          \"allowEmptyValue\": {\n            \"default\": false,\n            \"type\": \"boolean\"\n          }\n        }\n      },\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/examples\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  },\n                  \"allowReserved\": {\n                    \"default\": false,\n                    \"type\": \"boolean\"\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"const\": \"form\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/examples\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"style\": {\n          \"properties\": {\n            \"allowReserved\": {\n              \"default\": false\n            }\n          }\n        },\n        \"explode\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"form\"\n            },\n            \"allowReserved\": {\n              \"default\": false\n            }\n          }\n        },\n        \"allowReserved\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"form\"\n            }\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/styles-for-form\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"if\": {\n        \"$comment\": \"either default, or at least one response code property must exist\",\n        \"patternProperties\": {\n          \"^[1-5](?:[0-9]{2}|XX)$\": false\n        }\n      },\n      \"then\": {\n        \"required\": [\n          \"default\"\n        ]\n      }\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"required\": [\n        \"description\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"value\",\n          \"externalValue\"\n        ]\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"$ref\": \"#/$defs/examples\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri-reference\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.1#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"example\",\n          \"examples\"\n        ]\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"styles-for-form\": {\n      \"if\": {\n        \"properties\": {\n          \"style\": {\n            \"const\": \"form\"\n          }\n        },\n        \"required\": [\n          \"style\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": true\n          }\n        }\n      },\n      \"else\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": false\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2021-03-02",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2021-03-02\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2021-03-02\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2021-04-15",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2021-04-15\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2021-04-15\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2021-05-20",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2021-05-20\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2021-05-20\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2021-09-28",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2021-09-28\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2021-09-28\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2022-02-27",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2022-02-27\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"description\": \"The description of OpenAPI v3.1.x documents using the OpenAPI JSON Schema dialect, as defined by https://spec.openapis.org/oas/v3.1.0\",\n\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2022-02-27\",\n  \"properties\": {\n    \"jsonSchemaDialect\": { \"$ref\": \"#/$defs/dialect\" }\n  },\n\n  \"$defs\": {\n    \"dialect\": { \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\" },\n\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": { \"$ref\": \"#/$defs/dialect\" }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2022-10-07",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2022-10-07\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n\n  \"description\": \"The description of OpenAPI v3.1.x documents using the OpenAPI JSON Schema dialect, as defined by https://spec.openapis.org/oas/v3.1.0\",\n\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2022-10-07\",\n  \"properties\": {\n    \"jsonSchemaDialect\": { \"$ref\": \"#/$defs/dialect\" }\n  },\n\n  \"$defs\": {\n    \"dialect\": { \"const\": \"https://spec.openapis.org/oas/3.1/dialect/base\" },\n\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/base\",\n      \"properties\": {\n        \"$schema\": { \"$ref\": \"#/$defs/dialect\" }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2024-11-14",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2024-11-14\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents using the OpenAPI JSON Schema dialect\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2024-11-14\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/2024-10-25\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/2024-10-25\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2025-02-13",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2025-02-13\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents using the OpenAPI JSON Schema dialect\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2025-02-13\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2025-08-31",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2025-08-31\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents using the OpenAPI JSON Schema dialect\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2025-08-31\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.1/schema-base/2025-09-15",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.1/schema-base/2025-09-15\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.1.x Documents using the OpenAPI JSON Schema dialect\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.1/schema/2025-09-15\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.1/dialect/2024-11-10\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.2/dialect/2025-09-17",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.2/dialect/2025-09-17\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OpenAPI 3.2 Schema Object Dialect\",\n  \"description\": \"A JSON Schema dialect describing schemas found in OpenAPI v3.2.x Descriptions\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://json-schema.org/draft/2020-12/vocab/applicator\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/content\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/core\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/format-annotation\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/meta-data\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/unevaluated\": true,\n    \"https://json-schema.org/draft/2020-12/vocab/validation\": true,\n    \"https://spec.openapis.org/oas/3.2/vocab/base\": false\n  },\n  \"allOf\": [\n    {\n      \"$ref\": \"https://json-schema.org/draft/2020-12/schema\"\n    },\n    {\n      \"$ref\": \"https://spec.openapis.org/oas/3.2/meta/2025-09-17\"\n    }\n  ]\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.2/meta/2025-09-17",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.2/meta/2025-09-17\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"OAS Base Vocabulary\",\n  \"description\": \"A JSON Schema Vocabulary used in the OpenAPI JSON Schema Dialect\",\n  \"$dynamicAnchor\": \"meta\",\n  \"$vocabulary\": {\n    \"https://spec.openapis.org/oas/3.2/vocab/base\": true\n  },\n  \"type\": [\n    \"object\",\n    \"boolean\"\n  ],\n  \"properties\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/discriminator\"\n    },\n    \"example\": {\n      \"deprecated\": true\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-docs\"\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/xml\"\n    }\n  },\n  \"$defs\": {\n    \"discriminator\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"mapping\": {\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          },\n          \"type\": \"object\"\n        },\n        \"defaultMapping\": {\n          \"type\": \"string\"\n        },\n        \"propertyName\": {\n          \"type\": \"string\"\n        }\n      },\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"extensible\": {\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"external-docs\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"format\": \"uri-reference\",\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"type\": \"object\",\n      \"unevaluatedProperties\": false\n    },\n    \"xml\": {\n      \"$ref\": \"#/$defs/extensible\",\n      \"properties\": {\n        \"nodeType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"element\",\n            \"attribute\",\n            \"text\",\n            \"cdata\",\n            \"none\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"format\": \"iri\",\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\",\n          \"deprecated\": true\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\",\n          \"deprecated\": true\n        }\n      },\n      \"type\": \"object\",\n      \"dependentSchemas\": {\n        \"nodeType\": {\n          \"properties\": {\n            \"attribute\": false,\n            \"wrapped\": false\n          }\n        }\n      },\n      \"unevaluatedProperties\": false\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.2/schema/2025-09-17",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.2/schema/2025-09-17\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.2.x Documents without Schema Object validation\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\",\n      \"pattern\": \"^3\\\\.2\\\\.\\\\d+(-.+)?$\"\n    },\n    \"$self\": {\n      \"type\": \"string\",\n      \"format\": \"uri-reference\",\n      \"$comment\": \"MUST NOT contain a fragment\",\n      \"pattern\": \"^[^#]*$\"\n    },\n    \"info\": {\n      \"$ref\": \"#/$defs/info\"\n    },\n    \"jsonSchemaDialect\": {\n      \"type\": \"string\",\n      \"format\": \"uri-reference\",\n      \"default\": \"https://spec.openapis.org/oas/3.2/dialect/2025-09-17\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/server\"\n      },\n      \"default\": [\n        {\n          \"url\": \"/\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/$defs/paths\"\n    },\n    \"webhooks\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"components\": {\n      \"$ref\": \"#/$defs/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/security-requirement\"\n      }\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/tag\"\n      }\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/$defs/external-documentation\"\n    }\n  },\n  \"required\": [\n    \"openapi\",\n    \"info\"\n  ],\n  \"anyOf\": [\n    {\n      \"required\": [\n        \"paths\"\n      ]\n    },\n    {\n      \"required\": [\n        \"components\"\n      ]\n    },\n    {\n      \"required\": [\n        \"webhooks\"\n      ]\n    }\n  ],\n  \"$ref\": \"#/$defs/specification-extensions\",\n  \"unevaluatedProperties\": false,\n  \"$defs\": {\n    \"info\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#info-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/$defs/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/$defs/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"contact\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#contact-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"license\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#license-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"identifier\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"dependentSchemas\": {\n        \"identifier\": {\n          \"not\": {\n            \"required\": [\n              \"url\"\n            ]\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#server-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/server-variable\"\n          }\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"server-variable\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#server-variable-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"minItems\": 1\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"default\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"components\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#components-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"schemas\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$dynamicRef\": \"#meta\"\n          }\n        },\n        \"responses\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/response-or-reference\"\n          }\n        },\n        \"parameters\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/parameter-or-reference\"\n          }\n        },\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        },\n        \"requestBodies\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/request-body-or-reference\"\n          }\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"securitySchemes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/security-scheme-or-reference\"\n          }\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"pathItems\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/path-item\"\n          }\n        },\n        \"mediaTypes\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/media-type-or-reference\"\n          }\n        }\n      },\n      \"patternProperties\": {\n        \"^(?:schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems|mediaTypes)$\": {\n          \"$comment\": \"Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected\",\n          \"propertyNames\": {\n            \"pattern\": \"^[a-zA-Z0-9._-]+$\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"paths\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#paths-object\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/$defs/path-item\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"path-item\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#path-item-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/parameters\"\n        },\n        \"additionalOperations\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/operation\"\n          },\n          \"propertyNames\": {\n            \"$comment\": \"RFC9110 restricts methods to \\\"1*tchar\\\" in ABNF\",\n            \"pattern\": \"^[a-zA-Z0-9!#$%&'*+.^_`|~-]+$\",\n            \"not\": {\n              \"enum\": [\n                \"GET\",\n                \"PUT\",\n                \"POST\",\n                \"DELETE\",\n                \"OPTIONS\",\n                \"HEAD\",\n                \"PATCH\",\n                \"TRACE\",\n                \"QUERY\"\n              ]\n            }\n          }\n        },\n        \"get\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/$defs/operation\"\n        },\n        \"query\": {\n          \"$ref\": \"#/$defs/operation\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"operation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#operation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/parameters\"\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/$defs/request-body-or-reference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/$defs/responses\"\n        },\n        \"callbacks\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/callbacks-or-reference\"\n          }\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/security-requirement\"\n          }\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/server\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"external-documentation\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#external-documentation-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"required\": [\n        \"url\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"parameters\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/$defs/parameter-or-reference\"\n      },\n      \"not\": {\n        \"allOf\": [\n          {\n            \"contains\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"in\": {\n                  \"const\": \"query\"\n                }\n              },\n              \"required\": [\n                \"in\"\n              ]\n            }\n          },\n          {\n            \"contains\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"in\": {\n                  \"const\": \"querystring\"\n                }\n              },\n              \"required\": [\n                \"in\"\n              ]\n            }\n          }\n        ]\n      },\n      \"contains\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"in\": {\n            \"const\": \"querystring\"\n          }\n        },\n        \"required\": [\n          \"in\"\n        ]\n      },\n      \"minContains\": 0,\n      \"maxContains\": 1\n    },\n    \"parameter\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#parameter-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"enum\": [\n            \"query\",\n            \"querystring\",\n            \"header\",\n            \"path\",\n            \"cookie\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/examples\"\n        },\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"if\": {\n            \"properties\": {\n              \"in\": {\n                \"const\": \"query\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"allowEmptyValue\": {\n                \"default\": false,\n                \"type\": \"boolean\"\n              }\n            }\n          }\n        },\n        {\n          \"if\": {\n            \"properties\": {\n              \"in\": {\n                \"const\": \"querystring\"\n              }\n            }\n          },\n          \"then\": {\n            \"required\": [\n              \"content\"\n            ]\n          }\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"type\": \"string\"\n            },\n            \"explode\": {\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          },\n          \"allOf\": [\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query\"\n            },\n            {\n              \"$ref\": \"#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie\"\n            },\n            {\n              \"$ref\": \"#/$defs/styles-for-form\"\n            }\n          ],\n          \"$defs\": {\n            \"styles-for-path\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"path\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"enum\": [\n                      \"matrix\",\n                      \"label\",\n                      \"simple\"\n                    ]\n                  },\n                  \"required\": {\n                    \"const\": true\n                  }\n                },\n                \"required\": [\n                  \"required\"\n                ]\n              }\n            },\n            \"styles-for-header\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"header\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"simple\",\n                    \"const\": \"simple\"\n                  }\n                }\n              }\n            },\n            \"styles-for-query\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"query\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"spaceDelimited\",\n                      \"pipeDelimited\",\n                      \"deepObject\"\n                    ]\n                  }\n                }\n              }\n            },\n            \"styles-for-cookie\": {\n              \"if\": {\n                \"properties\": {\n                  \"in\": {\n                    \"const\": \"cookie\"\n                  }\n                }\n              },\n              \"then\": {\n                \"properties\": {\n                  \"style\": {\n                    \"default\": \"form\",\n                    \"enum\": [\n                      \"form\",\n                      \"cookie\"\n                    ]\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"unevaluatedProperties\": false\n    },\n    \"parameter-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/parameter\"\n      }\n    },\n    \"request-body\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#request-body-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"content\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"request-body-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/request-body\"\n      }\n    },\n    \"content\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#fixed-fields-10\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/media-type-or-reference\"\n      },\n      \"propertyNames\": {\n        \"format\": \"media-range\"\n      }\n    },\n    \"media-type\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#media-type-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"itemSchema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        },\n        \"prefixEncoding\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        },\n        \"itemEncoding\": {\n          \"$ref\": \"#/$defs/encoding\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"encoding\": {\n          \"properties\": {\n            \"prefixEncoding\": false,\n            \"itemEncoding\": false\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/examples\"\n        },\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"media-type-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/media-type\"\n      }\n    },\n    \"encoding\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#encoding-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\",\n          \"format\": \"media-range\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"style\": {\n          \"enum\": [\n            \"form\",\n            \"spaceDelimited\",\n            \"pipeDelimited\",\n            \"deepObject\"\n          ]\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        },\n        \"encoding\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        },\n        \"prefixEncoding\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/$defs/encoding\"\n          }\n        },\n        \"itemEncoding\": {\n          \"$ref\": \"#/$defs/encoding\"\n        }\n      },\n      \"dependentSchemas\": {\n        \"encoding\": {\n          \"properties\": {\n            \"prefixEncoding\": false,\n            \"itemEncoding\": false\n          }\n        },\n        \"style\": {\n          \"properties\": {\n            \"allowReserved\": {\n              \"default\": false\n            }\n          }\n        },\n        \"explode\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"form\"\n            },\n            \"allowReserved\": {\n              \"default\": false\n            }\n          }\n        },\n        \"allowReserved\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"form\"\n            }\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/styles-for-form\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"responses\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#responses-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"patternProperties\": {\n        \"^[1-5](?:[0-9]{2}|XX)$\": {\n          \"$ref\": \"#/$defs/response-or-reference\"\n        }\n      },\n      \"minProperties\": 1,\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"if\": {\n        \"$comment\": \"either default, or at least one response code property must exist\",\n        \"patternProperties\": {\n          \"^[1-5](?:[0-9]{2}|XX)$\": false\n        }\n      },\n      \"then\": {\n        \"required\": [\n          \"default\"\n        ]\n      }\n    },\n    \"response\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#response-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/header-or-reference\"\n          }\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\"\n        },\n        \"links\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/link-or-reference\"\n          }\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"response-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/response\"\n      }\n    },\n    \"callbacks\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#callback-object\",\n      \"type\": \"object\",\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/$defs/path-item\"\n      }\n    },\n    \"callbacks-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/callbacks\"\n      }\n    },\n    \"example\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#example-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"dataValue\": true,\n        \"serializedValue\": {\n          \"type\": \"string\"\n        },\n        \"value\": true,\n        \"externalValue\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        }\n      },\n      \"allOf\": [\n        {\n          \"not\": {\n            \"required\": [\n              \"value\",\n              \"externalValue\"\n            ]\n          }\n        },\n        {\n          \"not\": {\n            \"required\": [\n              \"value\",\n              \"dataValue\"\n            ]\n          }\n        },\n        {\n          \"not\": {\n            \"required\": [\n              \"value\",\n              \"serializedValue\"\n            ]\n          }\n        },\n        {\n          \"not\": {\n            \"required\": [\n              \"serializedValue\",\n              \"externalValue\"\n            ]\n          }\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"example-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/example\"\n      }\n    },\n    \"link\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#link-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/$defs/map-of-strings\"\n        },\n        \"requestBody\": true,\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/$defs/server\"\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"operationRef\"\n          ]\n        },\n        {\n          \"required\": [\n            \"operationId\"\n          ]\n        }\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"link-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/link\"\n      }\n    },\n    \"header\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#header-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$dynamicRef\": \"#meta\"\n        },\n        \"content\": {\n          \"$ref\": \"#/$defs/content\",\n          \"minProperties\": 1,\n          \"maxProperties\": 1\n        }\n      },\n      \"oneOf\": [\n        {\n          \"required\": [\n            \"schema\"\n          ]\n        },\n        {\n          \"required\": [\n            \"content\"\n          ]\n        }\n      ],\n      \"dependentSchemas\": {\n        \"schema\": {\n          \"properties\": {\n            \"style\": {\n              \"default\": \"simple\",\n              \"const\": \"simple\"\n            },\n            \"explode\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            },\n            \"allowReserved\": {\n              \"default\": false,\n              \"type\": \"boolean\"\n            }\n          }\n        }\n      },\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/examples\"\n        },\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        }\n      ],\n      \"unevaluatedProperties\": false\n    },\n    \"header-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/header\"\n      }\n    },\n    \"tag\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#tag-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/$defs/external-documentation\"\n        },\n        \"parent\": {\n          \"type\": \"string\"\n        },\n        \"kind\": {\n          \"type\": \"string\"\n        }\n      },\n      \"required\": [\n        \"name\"\n      ],\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false\n    },\n    \"reference\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#reference-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\",\n          \"format\": \"uri-reference\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#schema-object\",\n      \"$dynamicAnchor\": \"meta\",\n      \"type\": [\n        \"object\",\n        \"boolean\"\n      ]\n    },\n    \"security-scheme\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#security-scheme-object\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"type\": {\n          \"enum\": [\n            \"apiKey\",\n            \"http\",\n            \"mutualTLS\",\n            \"oauth2\",\n            \"openIdConnect\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"deprecated\": {\n          \"default\": false,\n          \"type\": \"boolean\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"allOf\": [\n        {\n          \"$ref\": \"#/$defs/specification-extensions\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-apikey\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-http-bearer\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oauth2\"\n        },\n        {\n          \"$ref\": \"#/$defs/security-scheme/$defs/type-oidc\"\n        }\n      ],\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"type-apikey\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"apiKey\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"in\": {\n                \"enum\": [\n                  \"query\",\n                  \"header\",\n                  \"cookie\"\n                ]\n              }\n            },\n            \"required\": [\n              \"name\",\n              \"in\"\n            ]\n          }\n        },\n        \"type-http\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"scheme\": {\n                \"type\": \"string\"\n              }\n            },\n            \"required\": [\n              \"scheme\"\n            ]\n          }\n        },\n        \"type-http-bearer\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"http\"\n              },\n              \"scheme\": {\n                \"type\": \"string\",\n                \"pattern\": \"^[Bb][Ee][Aa][Rr][Ee][Rr]$\"\n              }\n            },\n            \"required\": [\n              \"type\",\n              \"scheme\"\n            ]\n          },\n          \"then\": {\n            \"properties\": {\n              \"bearerFormat\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        },\n        \"type-oauth2\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"oauth2\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"flows\": {\n                \"$ref\": \"#/$defs/oauth-flows\"\n              },\n              \"oauth2MetadataUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri-reference\"\n              }\n            },\n            \"required\": [\n              \"flows\"\n            ]\n          }\n        },\n        \"type-oidc\": {\n          \"if\": {\n            \"properties\": {\n              \"type\": {\n                \"const\": \"openIdConnect\"\n              }\n            }\n          },\n          \"then\": {\n            \"properties\": {\n              \"openIdConnectUrl\": {\n                \"type\": \"string\",\n                \"format\": \"uri-reference\"\n              }\n            },\n            \"required\": [\n              \"openIdConnectUrl\"\n            ]\n          }\n        }\n      }\n    },\n    \"security-scheme-or-reference\": {\n      \"if\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"$ref\"\n        ]\n      },\n      \"then\": {\n        \"$ref\": \"#/$defs/reference\"\n      },\n      \"else\": {\n        \"$ref\": \"#/$defs/security-scheme\"\n      }\n    },\n    \"oauth-flows\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/implicit\"\n        },\n        \"password\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/password\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/client-credentials\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/authorization-code\"\n        },\n        \"deviceAuthorization\": {\n          \"$ref\": \"#/$defs/oauth-flows/$defs/device-authorization\"\n        }\n      },\n      \"$ref\": \"#/$defs/specification-extensions\",\n      \"unevaluatedProperties\": false,\n      \"$defs\": {\n        \"implicit\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"password\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"client-credentials\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"authorization-code\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"authorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"authorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        },\n        \"device-authorization\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"deviceAuthorizationUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"tokenUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"refreshUrl\": {\n              \"type\": \"string\",\n              \"format\": \"uri-reference\"\n            },\n            \"scopes\": {\n              \"$ref\": \"#/$defs/map-of-strings\"\n            }\n          },\n          \"required\": [\n            \"deviceAuthorizationUrl\",\n            \"tokenUrl\",\n            \"scopes\"\n          ],\n          \"$ref\": \"#/$defs/specification-extensions\",\n          \"unevaluatedProperties\": false\n        }\n      }\n    },\n    \"security-requirement\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#security-requirement-object\",\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"specification-extensions\": {\n      \"$comment\": \"https://spec.openapis.org/oas/v3.2#specification-extensions\",\n      \"patternProperties\": {\n        \"^x-\": true\n      }\n    },\n    \"examples\": {\n      \"properties\": {\n        \"example\": true,\n        \"examples\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/$defs/example-or-reference\"\n          }\n        }\n      },\n      \"not\": {\n        \"required\": [\n          \"example\",\n          \"examples\"\n        ]\n      }\n    },\n    \"map-of-strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"styles-for-form\": {\n      \"if\": {\n        \"properties\": {\n          \"style\": {\n            \"const\": \"form\"\n          }\n        },\n        \"required\": [\n          \"style\"\n        ]\n      },\n      \"then\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": true\n          }\n        }\n      },\n      \"else\": {\n        \"properties\": {\n          \"explode\": {\n            \"default\": false\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/openapi/oas/3.2/schema-base/2025-09-17",
    "content": "{\n  \"$id\": \"https://spec.openapis.org/oas/3.2/schema-base/2025-09-17\",\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"description\": \"The description of OpenAPI v3.2.x Documents using the OpenAPI JSON Schema dialect\",\n  \"$ref\": \"https://spec.openapis.org/oas/3.2/schema/2025-09-17\",\n  \"properties\": {\n    \"jsonSchemaDialect\": {\n      \"$ref\": \"#/$defs/dialect\"\n    }\n  },\n  \"$defs\": {\n    \"dialect\": {\n      \"const\": \"https://spec.openapis.org/oas/3.2/dialect/2025-09-17\"\n    },\n    \"schema\": {\n      \"$dynamicAnchor\": \"meta\",\n      \"$ref\": \"https://spec.openapis.org/oas/3.2/dialect/2025-09-17\",\n      \"properties\": {\n        \"$schema\": {\n          \"$ref\": \"#/$defs/dialect\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/LICENCE.md",
    "content": "PCRE2 Licence\n=============\n\n| SPDX-License-Identifier: | BSD-3-Clause WITH PCRE2-exception |\n|---------|-------|\n\nPCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\nReleases 10.00 and above of PCRE2 are distributed under the terms of the \"BSD\"\nlicence, as specified below, with one exemption for certain binary\nredistributions. The documentation for PCRE2, supplied in the \"doc\" directory,\nis distributed under the same terms as the software itself. The data in the\ntestdata directory is not copyrighted and is in the public domain.\n\nThe basic library functions are written in C and are freestanding. Also\nincluded in the distribution is a just-in-time compiler that can be used to\noptimize pattern matching. This is an optional feature that can be omitted when\nthe library is built. The just-in-time compiler is separately licensed under the\n\"2-clause BSD\" licence.\n\n\nCOPYRIGHT\n---------\n\n### The basic library functions\n\n    Written by:       Philip Hazel\n    Email local part: Philip.Hazel\n    Email domain:     gmail.com\n\n    Retired from University of Cambridge Computing Service,\n    Cambridge, England.\n\n    Copyright (c) 1997-2007 University of Cambridge\n    Copyright (c) 2007-2024 Philip Hazel\n    All rights reserved.\n\n### PCRE2 Just-In-Time compilation support\n\n    Written by:       Zoltan Herczeg\n    Email local part: hzmester\n    Email domain:     freemail.hu\n\n    Copyright (c) 2010-2024 Zoltan Herczeg\n    All rights reserved.\n\n### Stack-less Just-In-Time compiler\n\n    Written by:       Zoltan Herczeg\n    Email local part: hzmester\n    Email domain:     freemail.hu\n\n    Copyright (c) 2009-2024 Zoltan Herczeg\n    All rights reserved.\n\nThe code in the `deps/sljit` directory has its own LICENSE file.\n\n### All other contributions\n\nMany other contributors have participated in the authorship of PCRE2. As PCRE2\nhas never required a Contributor Licensing Agreement, or other copyright\nassignment agreement, all contributions have copyright retained by each\noriginal contributor or their employer.\n\n\nTHE \"BSD\" LICENCE\n-----------------\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notices,\n  this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright\n  notices, this list of conditions and the following disclaimer in the\n  documentation and/or other materials provided with the distribution.\n\n* Neither the name of the University of Cambridge nor the names of any\n  contributors may be used to endorse or promote products derived from this\n  software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\n\nEXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES\n------------------------------------------\n\nThe second condition in the BSD licence (covering binary redistributions) does\nnot apply all the way down a chain of software. If binary package A includes\nPCRE2, it must respect the condition, but if package B is software that\nincludes package A, the condition is not imposed on package B unless it uses\nPCRE2 independently.\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/LICENSE",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorApple.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <sys/types.h>\n#include <sys/mman.h>\n/*\n   On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a\n   version where it's OK to have more than one JIT block or where MAP_JIT is\n   required.\n   On non-macOS systems, returns MAP_JIT if it is defined.\n*/\n#include <TargetConditionals.h>\n\n#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (TARGET_OS_MAC && !TARGET_OS_IPHONE)\n\n#if defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86\n\n#include <sys/utsname.h>\n#include <stdlib.h>\n\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)\n\n#ifdef MAP_JIT\n#define SLJIT_MAP_JIT\t(get_map_jit_flag())\nstatic SLJIT_INLINE int get_map_jit_flag(void)\n{\n\tsize_t page_size;\n\tvoid *ptr;\n\tstruct utsname name;\n\tstatic int map_jit_flag = -1;\n\n\tif (map_jit_flag < 0) {\n\t\tmap_jit_flag = 0;\n\t\tuname(&name);\n\n\t\t/* Kernel version for 10.14.0 (Mojave) or later */\n\t\tif (atoi(name.release) >= 18) {\n\t\t\tpage_size = get_page_alignment() + 1;\n\t\t\t/* Only use MAP_JIT if a hardened runtime is used */\n\t\t\tptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,\n\t\t\t\t\tMAP_PRIVATE | MAP_ANON, -1, 0);\n\n\t\t\tif (ptr != MAP_FAILED)\n\t\t\t\tmunmap(ptr, page_size);\n\t\t\telse\n\t\t\t\tmap_jit_flag = MAP_JIT;\n\t\t}\n\t}\n\treturn map_jit_flag;\n}\n#else /* !defined(MAP_JIT) */\n#define SLJIT_MAP_JIT\t(0)\n#endif\n\n#elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM\n\n#include <AvailabilityMacros.h>\n#include <pthread.h>\n\n#define SLJIT_MAP_JIT\t(MAP_JIT)\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \\\n\t\tapple_update_wx_flags(enable_exec)\n\nstatic SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)\n{\n#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000\n\tif (__builtin_available(macos 11, *))\n#endif /* BigSur */\n\tpthread_jit_write_protect_np(enable_exec);\n}\n\n#elif defined(SLJIT_CONFIG_PPC) && SLJIT_CONFIG_PPC\n\n#define SLJIT_MAP_JIT\t(0)\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)\n\n#else\n#error \"Unsupported architecture\"\n#endif /* SLJIT_CONFIG */\n\n#else /* !TARGET_OS_OSX */\n\n#ifdef MAP_JIT\n#define SLJIT_MAP_JIT\t(MAP_JIT)\n#else\n#define SLJIT_MAP_JIT\t(0)\n#endif\n\n#endif /* TARGET_OS_OSX */\n\nstatic SLJIT_INLINE void* alloc_chunk(sljit_uw size)\n{\n\tvoid *retval;\n\tint prot = PROT_READ | PROT_WRITE | PROT_EXEC;\n\tint flags = MAP_PRIVATE;\n\tint fd = -1;\n\n\tflags |= MAP_ANON | SLJIT_MAP_JIT;\n\n\tretval = mmap(NULL, size, prot, flags, fd, 0);\n\tif (retval == MAP_FAILED)\n\t\treturn NULL;\n\n\tSLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);\n\n\treturn retval;\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tmunmap(chunk, size);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/*\n   This file contains a simple executable memory allocator\n\n   It is assumed, that executable code blocks are usually medium (or sometimes\n   large) memory blocks, and the allocator is not too frequently called (less\n   optimized than other allocators). Thus, using it as a generic allocator is\n   not suggested.\n\n   How does it work:\n     Memory is allocated in continuous memory areas called chunks by alloc_chunk()\n     Chunk format:\n     [ block ][ block ] ... [ block ][ block terminator ]\n\n   All blocks and the block terminator is started with block_header. The block\n   header contains the size of the previous and the next block. These sizes\n   can also contain special values.\n     Block size:\n       0 - The block is a free_block, with a different size member.\n       1 - The block is a block terminator.\n       n - The block is used at the moment, and the value contains its size.\n     Previous block size:\n       0 - This is the first block of the memory chunk.\n       n - The size of the previous block.\n\n   Using these size values we can go forward or backward on the block chain.\n   The unused blocks are stored in a chain list pointed by sljit_free_blocks.\n   This list is useful if we need to find a suitable memory area when the\n   allocator is called.\n\n   When a block is freed, the new free block is connected to its adjacent free\n   blocks if possible.\n\n     [ free block ][ used block ][ free block ]\n   and \"used block\" is freed, the three blocks are connected together:\n     [           one big free block           ]\n*/\n\n/* Expected functions:\n     alloc_chunk / free_chunk :\n       * allocate executable system memory chunks\n       * the size is always divisible by CHUNK_SIZE\n     SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :\n       * provided as part of sljitUtils\n       * only the allocator requires this lock, sljit is fully thread safe\n         as it only uses local variables\n\n   Supported defines:\n     SLJIT_HAS_CHUNK_HEADER - (optional) sljit_chunk_header is defined\n     SLJIT_HAS_EXECUTABLE_OFFSET - (optional) has executable offset data\n     SLJIT_UPDATE_WX_FLAGS - (optional) update WX flags\n*/\n\n#ifdef SLJIT_HAS_CHUNK_HEADER\n#define CHUNK_HEADER_SIZE (sizeof(struct sljit_chunk_header))\n#else /* !SLJIT_HAS_CHUNK_HEADER */\n#define CHUNK_HEADER_SIZE 0\n#endif /* SLJIT_HAS_CHUNK_HEADER */\n\n#ifndef SLJIT_UPDATE_WX_FLAGS\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)\n#endif /* SLJIT_UPDATE_WX_FLAGS */\n\n#ifndef CHUNK_SIZE\n/* 64 KByte if not specified. */\n#define CHUNK_SIZE\t(sljit_uw)0x10000\n#endif /* CHUNK_SIZE */\n\nstruct block_header {\n\tsljit_uw size;\n\tsljit_uw prev_size;\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\tsljit_sw executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n};\n\nstruct free_block {\n\tstruct block_header header;\n\tstruct free_block *next;\n\tstruct free_block *prev;\n\tsljit_uw size;\n};\n\n#define AS_BLOCK_HEADER(base, offset) \\\n\t((struct block_header*)(((sljit_u8*)base) + offset))\n#define AS_FREE_BLOCK(base, offset) \\\n\t((struct free_block*)(((sljit_u8*)base) + offset))\n#define MEM_START(base)\t\t((void*)((base) + 1))\n#define CHUNK_MASK\t\t(~(CHUNK_SIZE - 1))\n#define ALIGN_SIZE(size)\t(((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)\n#define CHUNK_EXTRA_SIZE\t(sizeof(struct block_header) + CHUNK_HEADER_SIZE)\n\nstatic struct free_block* sljit_free_blocks;\nstatic sljit_uw sljit_allocated_size;\nstatic sljit_uw sljit_total_size;\n\nstatic SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)\n{\n\tfree_block->header.size = 0;\n\tfree_block->size = size;\n\n\tfree_block->next = sljit_free_blocks;\n\tfree_block->prev = NULL;\n\tif (sljit_free_blocks)\n\t\tsljit_free_blocks->prev = free_block;\n\tsljit_free_blocks = free_block;\n}\n\nstatic SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)\n{\n\tif (free_block->next)\n\t\tfree_block->next->prev = free_block->prev;\n\n\tif (free_block->prev)\n\t\tfree_block->prev->next = free_block->next;\n\telse {\n\t\tSLJIT_ASSERT(sljit_free_blocks == free_block);\n\t\tsljit_free_blocks = free_block->next;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)\n{\n\tstruct block_header *header;\n\tstruct block_header *next_header;\n\tstruct free_block *free_block;\n\tsljit_uw chunk_size;\n\n#ifdef SLJIT_HAS_CHUNK_HEADER\n\tstruct sljit_chunk_header *chunk_header;\n#else /* !SLJIT_HAS_CHUNK_HEADER */\n\tvoid *chunk_header;\n#endif /* SLJIT_HAS_CHUNK_HEADER */\n\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\tsljit_sw executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\n\tif (size < (64 - sizeof(struct block_header)))\n\t\tsize = (64 - sizeof(struct block_header));\n\tsize = ALIGN_SIZE(size);\n\n\tSLJIT_ALLOCATOR_LOCK();\n\tfree_block = sljit_free_blocks;\n\twhile (free_block) {\n\t\tif (free_block->size >= size) {\n\t\t\tchunk_size = free_block->size;\n\t\t\tSLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);\n\t\t\tif (chunk_size > size + 64) {\n\t\t\t\t/* We just cut a block from the end of the free block. */\n\t\t\t\tchunk_size -= size;\n\t\t\t\tfree_block->size = chunk_size;\n\t\t\t\theader = AS_BLOCK_HEADER(free_block, chunk_size);\n\t\t\t\theader->prev_size = chunk_size;\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\t\t\t\theader->executable_offset = free_block->header.executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\t\t\t\tAS_BLOCK_HEADER(header, size)->prev_size = size;\n\t\t\t} else {\n\t\t\t\tsljit_remove_free_block(free_block);\n\t\t\t\theader = (struct block_header*)free_block;\n\t\t\t\tsize = chunk_size;\n\t\t\t}\n\t\t\tsljit_allocated_size += size;\n\t\t\theader->size = size;\n\t\t\tSLJIT_ALLOCATOR_UNLOCK();\n\t\t\treturn MEM_START(header);\n\t\t}\n\t\tfree_block = free_block->next;\n\t}\n\n\tchunk_size = (size + CHUNK_EXTRA_SIZE + CHUNK_SIZE - 1) & CHUNK_MASK;\n\n\tchunk_header = alloc_chunk(chunk_size);\n\tif (!chunk_header) {\n\t\tSLJIT_ALLOCATOR_UNLOCK();\n\t\treturn NULL;\n\t}\n\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\texecutable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header);\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\n\tchunk_size -= CHUNK_EXTRA_SIZE;\n\tsljit_total_size += chunk_size;\n\n\theader = (struct block_header*)(((sljit_u8*)chunk_header) + CHUNK_HEADER_SIZE);\n\n\theader->prev_size = 0;\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\theader->executable_offset = executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\n\tif (chunk_size > size + 64) {\n\t\t/* Cut the allocated space into a free and a used block. */\n\t\tsljit_allocated_size += size;\n\t\theader->size = size;\n\t\tchunk_size -= size;\n\n\t\tfree_block = AS_FREE_BLOCK(header, size);\n\t\tfree_block->header.prev_size = size;\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\t\tfree_block->header.executable_offset = executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\t\tsljit_insert_free_block(free_block, chunk_size);\n\t\tnext_header = AS_BLOCK_HEADER(free_block, chunk_size);\n\t} else {\n\t\t/* All space belongs to this allocation. */\n\t\tsljit_allocated_size += chunk_size;\n\t\theader->size = chunk_size;\n\t\tnext_header = AS_BLOCK_HEADER(header, chunk_size);\n\t}\n\tnext_header->size = 1;\n\tnext_header->prev_size = chunk_size;\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\tnext_header->executable_offset = executable_offset;\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\tSLJIT_ALLOCATOR_UNLOCK();\n\treturn MEM_START(header);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void *ptr)\n{\n\tstruct block_header *header;\n\tstruct free_block *free_block;\n\n\tSLJIT_ALLOCATOR_LOCK();\n\theader = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\n\theader = AS_BLOCK_HEADER(header, -header->executable_offset);\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n\tsljit_allocated_size -= header->size;\n\n\tSLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);\n\n\t/* Connecting free blocks together if possible. */\n\n\t/* If header->prev_size == 0, free_block will equal to header.\n\t   In this case, free_block->header.size will be > 0. */\n\tfree_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);\n\tif (SLJIT_UNLIKELY(!free_block->header.size)) {\n\t\tfree_block->size += header->size;\n\t\theader = AS_BLOCK_HEADER(free_block, free_block->size);\n\t\theader->prev_size = free_block->size;\n\t} else {\n\t\tfree_block = (struct free_block*)header;\n\t\tsljit_insert_free_block(free_block, header->size);\n\t}\n\n\theader = AS_BLOCK_HEADER(free_block, free_block->size);\n\tif (SLJIT_UNLIKELY(!header->size)) {\n\t\tfree_block->size += ((struct free_block*)header)->size;\n\t\tsljit_remove_free_block((struct free_block*)header);\n\t\theader = AS_BLOCK_HEADER(free_block, free_block->size);\n\t\theader->prev_size = free_block->size;\n\t}\n\n\t/* The whole chunk is free. */\n\tif (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {\n\t\t/* If this block is freed, we still have (sljit_allocated_size / 2) free space. */\n\t\tif (sljit_total_size - free_block->size > (sljit_allocated_size * 3 / 2)) {\n\t\t\tsljit_total_size -= free_block->size;\n\t\t\tsljit_remove_free_block(free_block);\n\t\t\tfree_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);\n\t\t}\n\t}\n\n\tSLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);\n\tSLJIT_ALLOCATOR_UNLOCK();\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)\n{\n\tstruct free_block* free_block;\n\tstruct free_block* next_free_block;\n\n\tSLJIT_ALLOCATOR_LOCK();\n\tSLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);\n\n\tfree_block = sljit_free_blocks;\n\twhile (free_block) {\n\t\tnext_free_block = free_block->next;\n\t\tif (!free_block->header.prev_size &&\n\t\t\t\tAS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {\n\t\t\tsljit_total_size -= free_block->size;\n\t\t\tsljit_remove_free_block(free_block);\n\t\t\tfree_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);\n\t\t}\n\t\tfree_block = next_free_block;\n\t}\n\n\tSLJIT_ASSERT(sljit_total_size || (!sljit_total_size && !sljit_free_blocks));\n\tSLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);\n\tSLJIT_ALLOCATOR_UNLOCK();\n}\n\n#ifdef SLJIT_HAS_EXECUTABLE_OFFSET\nSLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code)\n{\n\treturn ((struct block_header*)SLJIT_CODE_TO_PTR(code))[-1].executable_offset;\n}\n#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorFreeBSD.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <sys/mman.h>\n#include <sys/procctl.h>\n\n#ifdef PROC_WXMAP_CTL\nstatic SLJIT_INLINE int sljit_is_wx_block(void)\n{\n\tstatic int wx_block = -1;\n\tif (wx_block < 0) {\n\t\tint sljit_wx_enable = PROC_WX_MAPPINGS_PERMIT;\n\t\twx_block = !!procctl(P_PID, 0, PROC_WXMAP_CTL, &sljit_wx_enable);\n\t}\n\treturn wx_block;\n}\n\n#define SLJIT_IS_WX_BLOCK sljit_is_wx_block()\n#else /* !PROC_WXMAP_CTL */\n#define SLJIT_IS_WX_BLOCK (1)\n#endif /* PROC_WXMAP_CTL */\n\nstatic SLJIT_INLINE void* alloc_chunk(sljit_uw size)\n{\n\tvoid *retval;\n\tint prot = PROT_READ | PROT_WRITE | PROT_EXEC;\n\tint flags = MAP_PRIVATE;\n\tint fd = -1;\n\n#ifdef PROT_MAX\n\tprot |= PROT_MAX(prot);\n#endif\n\n#ifdef MAP_ANON\n\tflags |= MAP_ANON;\n#else /* !MAP_ANON */\n\tif (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))\n\t\treturn NULL;\n\n\tfd = dev_zero;\n#endif /* MAP_ANON */\n\nretry:\n\tretval = mmap(NULL, size, prot, flags, fd, 0);\n\tif (retval == MAP_FAILED) {\n\t\tif (!SLJIT_IS_WX_BLOCK)\n\t\t\tgoto retry;\n\n\t\treturn NULL;\n\t}\n\n\t/* HardenedBSD's mmap lies, so check permissions again. */\n\tif (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {\n\t\tmunmap(retval, size);\n\t\treturn NULL;\n\t}\n\n\treturn retval;\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tmunmap(chunk, size);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorPosix.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <sys/types.h>\n#include <sys/mman.h>\n\nstatic SLJIT_INLINE void* alloc_chunk(sljit_uw size)\n{\n\tvoid *retval;\n\tint prot = PROT_READ | PROT_WRITE | PROT_EXEC;\n\tint flags = MAP_PRIVATE;\n\tint fd = -1;\n\n#ifdef PROT_MAX\n\tprot |= PROT_MAX(prot);\n#endif\n\n#ifdef MAP_ANON\n\tflags |= MAP_ANON;\n#else /* !MAP_ANON */\n\tif (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))\n\t\treturn NULL;\n\n\tfd = dev_zero;\n#endif /* MAP_ANON */\n\n\tretval = mmap(NULL, size, prot, flags, fd, 0);\n\tif (retval == MAP_FAILED)\n\t\treturn NULL;\n\n\treturn retval;\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tmunmap(chunk, size);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorWindows.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)\n\nstatic SLJIT_INLINE void* alloc_chunk(sljit_uw size)\n{\n\treturn VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\tVirtualFree(chunk, 0, MEM_RELEASE);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitProtExecAllocatorNetBSD.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#define SLJIT_HAS_CHUNK_HEADER\n#define SLJIT_HAS_EXECUTABLE_OFFSET\n\nstruct sljit_chunk_header {\n\tvoid *executable;\n};\n\n/*\n * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to\n * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed\n */\nstatic SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size)\n{\n\tstruct sljit_chunk_header *retval;\n\n\tretval = (struct sljit_chunk_header *)mmap(NULL, size,\n\t\t\tPROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),\n\t\t\tMAP_ANON | MAP_SHARED, -1, 0);\n\n\tif (retval == MAP_FAILED)\n\t\treturn NULL;\n\n\tretval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);\n\tif (retval->executable == MAP_FAILED) {\n\t\tmunmap((void *)retval, size);\n\t\treturn NULL;\n\t}\n\n\tif (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {\n\t\tmunmap(retval->executable, size);\n\t\tmunmap((void *)retval, size);\n\t\treturn NULL;\n\t}\n\n\treturn retval;\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tstruct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1;\n\n\tmunmap(header->executable, size);\n\tmunmap((void *)header, size);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitProtExecAllocatorPosix.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#define SLJIT_HAS_CHUNK_HEADER\n#define SLJIT_HAS_EXECUTABLE_OFFSET\n\nstruct sljit_chunk_header {\n\tvoid *executable;\n};\n\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <string.h>\n\n#ifndef O_NOATIME\n#define O_NOATIME 0\n#endif\n\n/* this is a linux extension available since kernel 3.11 */\n#ifndef O_TMPFILE\n#define O_TMPFILE 0x404000\n#endif\n\n#ifndef _GNU_SOURCE\nchar *secure_getenv(const char *name);\nint mkostemp(char *template, int flags);\n#endif\n\nstatic SLJIT_INLINE int create_tempfile(void)\n{\n\tint fd;\n\tchar tmp_name[256];\n\tsize_t tmp_name_len = 0;\n\tchar *dir;\n\tstruct stat st;\n#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED\n\tmode_t mode;\n#endif\n\n#ifdef HAVE_MEMFD_CREATE\n\t/* this is a GNU extension, make sure to use -D_GNU_SOURCE */\n\tfd = memfd_create(\"sljit\", MFD_CLOEXEC);\n\tif (fd != -1) {\n\t\tfchmod(fd, 0);\n\t\treturn fd;\n\t}\n#endif\n\n\tdir = secure_getenv(\"TMPDIR\");\n\n\tif (dir) {\n\t\tsize_t len = strlen(dir);\n\t\tif (len > 0 && len < sizeof(tmp_name)) {\n\t\t\tif ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) {\n\t\t\t\tmemcpy(tmp_name, dir, len + 1);\n\t\t\t\ttmp_name_len = len;\n\t\t\t}\n\t\t}\n\t}\n\n#ifdef P_tmpdir\n\tif (!tmp_name_len) {\n\t\ttmp_name_len = strlen(P_tmpdir);\n\t\tif (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))\n\t\t\tstrcpy(tmp_name, P_tmpdir);\n\t}\n#endif\n\tif (!tmp_name_len) {\n\t\tstrcpy(tmp_name, \"/tmp\");\n\t\ttmp_name_len = 4;\n\t}\n\n\tSLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));\n\n\tif (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/')\n\t\ttmp_name[--tmp_name_len] = '\\0';\n\n\tfd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);\n\tif (fd != -1)\n\t\treturn fd;\n\n\tif (tmp_name_len >= sizeof(tmp_name) - 7)\n\t\treturn -1;\n\n\tstrcpy(tmp_name + tmp_name_len, \"/XXXXXX\");\n#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED\n\tmode = umask(0777);\n#endif\n\tfd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);\n#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED\n\tumask(mode);\n#else\n\tfchmod(fd, 0);\n#endif\n\n\tif (fd == -1)\n\t\treturn -1;\n\n\tif (unlink(tmp_name)) {\n\t\tclose(fd);\n\t\treturn -1;\n\t}\n\n\treturn fd;\n}\n\nstatic SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size)\n{\n\tstruct sljit_chunk_header *retval;\n\tint fd;\n\n\tfd = create_tempfile();\n\tif (fd == -1)\n\t\treturn NULL;\n\n\tif (ftruncate(fd, (off_t)size)) {\n\t\tclose(fd);\n\t\treturn NULL;\n\t}\n\n\tretval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);\n\n\tif (retval == MAP_FAILED) {\n\t\tclose(fd);\n\t\treturn NULL;\n\t}\n\n\tretval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);\n\n\tif (retval->executable == MAP_FAILED) {\n\t\tmunmap((void *)retval, size);\n\t\tclose(fd);\n\t\treturn NULL;\n\t}\n\n\tclose(fd);\n\treturn retval;\n}\n\nstatic SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)\n{\n\tstruct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1;\n\n\tmunmap(header->executable, size);\n\tmunmap((void *)header, size);\n}\n\n#include \"sljitExecAllocatorCore.c\"\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitWXExecAllocatorPosix.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/*\n   This file contains a simple W^X executable memory allocator\n\n   In *NIX, MAP_ANON is required (that is considered a feature) so make\n   sure to set the right availability macros for your system or the code\n   will fail to build.\n\n   If your system doesn't support mapping of anonymous pages (ex: IRIX) it\n   is also likely that it doesn't need this allocator and should be using\n   the standard one instead.\n\n   It allocates a separate map for each code block and may waste a lot of\n   memory, because whatever was requested, will be rounded up to the page\n   size (minimum 4KB, but could be even bigger).\n\n   It changes the page permissions (RW <-> RX) as needed and therefore, if you\n   will be updating the code after it has been generated, need to make sure to\n   block any concurrent execution, or could result in a SIGBUS, that could\n   even manifest itself at a different address than the one that was being\n   modified.\n\n   Only use if you are unable to use the regular allocator because of security\n   restrictions and adding exceptions to your application or the system are\n   not possible.\n*/\n\n#include <sys/types.h>\n#include <sys/mman.h>\n\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \\\n\tsljit_update_wx_flags((from), (to), (enable_exec))\n\n#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)\n#include <pthread.h>\n#define SLJIT_SE_LOCK()\t\tpthread_mutex_lock(&se_lock)\n#define SLJIT_SE_UNLOCK()\tpthread_mutex_unlock(&se_lock)\n#else\n#define SLJIT_SE_LOCK()\n#define SLJIT_SE_UNLOCK()\n#endif /* !SLJIT_SINGLE_THREADED */\n\n#define SLJIT_WX_IS_BLOCK(ptr, size) generic_check_is_wx_block(ptr, size)\n\nstatic SLJIT_INLINE int generic_check_is_wx_block(void *ptr, sljit_uw size)\n{\n\tif (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))\n\t\treturn !!mprotect(ptr, size, PROT_READ | PROT_WRITE);\n\n\treturn 1;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)\n{\n#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)\n\tstatic pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;\n#endif\n\tstatic int wx_block = -1;\n\tint prot = PROT_READ | PROT_WRITE;\n\tsljit_uw* ptr;\n\n\tif (SLJIT_UNLIKELY(wx_block > 0))\n\t\treturn NULL;\n\n#ifdef PROT_MAX\n\tprot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC);\n#endif\n\n\tsize += sizeof(sljit_uw);\n\tptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);\n\n\tif (ptr == MAP_FAILED)\n\t\treturn NULL;\n\n\tif (SLJIT_UNLIKELY(wx_block < 0)) {\n\t\tSLJIT_SE_LOCK();\n\t\twx_block = SLJIT_WX_IS_BLOCK(ptr, size);\n\t\tSLJIT_SE_UNLOCK();\n\t\tif (SLJIT_UNLIKELY(wx_block)) {\n\t\t\tmunmap((void *)ptr, size);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\t*ptr++ = size;\n\treturn ptr;\n}\n\n#undef SLJIT_SE_UNLOCK\n#undef SLJIT_SE_LOCK\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)\n{\n\tsljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;\n\tmunmap((void*)start_ptr, *start_ptr);\n}\n\nstatic void sljit_update_wx_flags(void *from, void *to, int enable_exec)\n{\n\tsljit_uw page_mask = (sljit_uw)get_page_alignment();\n\tsljit_uw start = (sljit_uw)from;\n\tsljit_uw end = (sljit_uw)to;\n\tint prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);\n\n\tSLJIT_ASSERT(start < end);\n\n\tstart &= ~page_mask;\n\tend = (end + page_mask) & ~page_mask;\n\n\tmprotect((void*)start, end - start, prot);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)\n{\n\t/* This allocator does not keep unused memory for future allocations. */\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/allocator_src/sljitWXExecAllocatorWindows.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/*\n   This file contains a simple W^X executable memory allocator\n\n   In *NIX, MAP_ANON is required (that is considered a feature) so make\n   sure to set the right availability macros for your system or the code\n   will fail to build.\n\n   If your system doesn't support mapping of anonymous pages (ex: IRIX) it\n   is also likely that it doesn't need this allocator and should be using\n   the standard one instead.\n\n   It allocates a separate map for each code block and may waste a lot of\n   memory, because whatever was requested, will be rounded up to the page\n   size (minimum 4KB, but could be even bigger).\n\n   It changes the page permissions (RW <-> RX) as needed and therefore, if you\n   will be updating the code after it has been generated, need to make sure to\n   block any concurrent execution, or could result in a SIGBUS, that could\n   even manifest itself at a different address than the one that was being\n   modified.\n\n   Only use if you are unable to use the regular allocator because of security\n   restrictions and adding exceptions to your application or the system are\n   not possible.\n*/\n\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \\\n\tsljit_update_wx_flags((from), (to), (enable_exec))\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)\n{\n\tsljit_uw *ptr;\n\n\tsize += sizeof(sljit_uw);\n\tptr = (sljit_uw*)VirtualAlloc(NULL, size,\n\t\t\t\tMEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\n\tif (!ptr)\n\t\treturn NULL;\n\n\t*ptr++ = size;\n\n\treturn ptr;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)\n{\n\tsljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);\n#if defined(SLJIT_DEBUG) && SLJIT_DEBUG\n\tsljit_uw page_mask = (sljit_uw)get_page_alignment();\n\n\tSLJIT_ASSERT(!(start & page_mask));\n#endif\n\tVirtualFree((void*)start, 0, MEM_RELEASE);\n}\n\nstatic void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)\n{\n\tDWORD oldprot;\n\tsljit_uw page_mask = (sljit_uw)get_page_alignment();\n\tsljit_uw start = (sljit_uw)from;\n\tsljit_uw end = (sljit_uw)to;\n\tDWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;\n\n\tSLJIT_ASSERT(start < end);\n\n\tstart &= ~page_mask;\n\tend = (end + page_mask) & ~page_mask;\n\n\tVirtualProtect((void*)start, end - start, prot, &oldprot);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)\n{\n\t/* This allocator does not keep unused memory for future allocations. */\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitConfig.h",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SLJIT_CONFIG_H_\n#define SLJIT_CONFIG_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*\n  This file contains the basic configuration options for the SLJIT compiler\n  and their default values. These options can be overridden in the\n  sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a\n  non-zero value.\n*/\n\n/* --------------------------------------------------------------------- */\n/*  Utilities                                                            */\n/* --------------------------------------------------------------------- */\n\n/* Implements a stack like data structure (by using mmap / VirtualAlloc  */\n/* or a custom allocator). */\n#ifndef SLJIT_UTIL_STACK\n/* Enabled by default */\n#define SLJIT_UTIL_STACK 1\n#endif /* SLJIT_UTIL_STACK */\n\n/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */\n#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION\n/* Disabled by default */\n#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0\n#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */\n\n/* Single threaded application. Does not require any locks. */\n#ifndef SLJIT_SINGLE_THREADED\n/* Disabled by default. */\n#define SLJIT_SINGLE_THREADED 0\n#endif /* SLJIT_SINGLE_THREADED */\n\n/* --------------------------------------------------------------------- */\n/*  Configuration                                                        */\n/* --------------------------------------------------------------------- */\n\n/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should\n   define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */\n#ifndef SLJIT_STD_MACROS_DEFINED\n/* Disabled by default. */\n#define SLJIT_STD_MACROS_DEFINED 0\n#endif /* SLJIT_STD_MACROS_DEFINED */\n\n/* Executable code allocation:\n   If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should\n   define SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC.\n   Optionally, depending on the implementation used for the allocator,\n   SLJIT_EXEC_OFFSET and SLJIT_UPDATE_WX_FLAGS might also be needed. */\n#ifndef SLJIT_EXECUTABLE_ALLOCATOR\n/* Enabled by default. */\n#define SLJIT_EXECUTABLE_ALLOCATOR 1\n\n/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses\n   an allocator which does not set writable and executable\n   permission flags at the same time.\n   Instead, it creates a shared memory segment (usually backed by a file)\n   and maps it twice, with different permissions, depending on the use\n   case.\n   The trade-off is increased use of virtual memory, incompatibility with\n   fork(), and some possible additional security risks by the use of\n   publicly accessible files for the generated code. */\n#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR\n/* Disabled by default. */\n#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0\n#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n\n/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an\n   allocator which does not set writable and executable permission\n   flags at the same time.\n   Instead, it creates a new independent map on each invocation and\n   switches permissions at the underlying pages as needed.\n   The trade-off is increased memory use and degraded performance. */\n#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR\n/* Disabled by default. */\n#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0\n#endif /* SLJIT_WX_EXECUTABLE_ALLOCATOR */\n\n#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */\n\n/* Return with error when an invalid argument is passed. */\n#ifndef SLJIT_ARGUMENT_CHECKS\n/* Disabled by default */\n#define SLJIT_ARGUMENT_CHECKS 0\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n/* Debug checks (assertions, etc.). */\n#ifndef SLJIT_DEBUG\n/* Enabled by default */\n#define SLJIT_DEBUG 1\n#endif /* SLJIT_DEBUG */\n\n/* Verbose operations. */\n#ifndef SLJIT_VERBOSE\n/* Enabled by default */\n#define SLJIT_VERBOSE 1\n#endif /* SLJIT_VERBOSE */\n\n/*\n  SLJIT_IS_FPU_AVAILABLE\n    The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE.\n      zero value - FPU is NOT present.\n      nonzero value - FPU is present.\n*/\n\n/* For further configurations, see the beginning of sljitConfigInternal.h */\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif /* __cplusplus */\n\n#endif /* SLJIT_CONFIG_H_ */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitConfigCPU.h",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SLJIT_CONFIG_CPU_H_\n#define SLJIT_CONFIG_CPU_H_\n\n/* --------------------------------------------------------------------- */\n/*  Architecture                                                         */\n/* --------------------------------------------------------------------- */\n\n/* Architecture selection. */\n/* #define SLJIT_CONFIG_X86_32 1 */\n/* #define SLJIT_CONFIG_X86_64 1 */\n/* #define SLJIT_CONFIG_ARM_V6 1 */\n/* #define SLJIT_CONFIG_ARM_V7 1 */\n/* #define SLJIT_CONFIG_ARM_THUMB2 1 */\n/* #define SLJIT_CONFIG_ARM_64 1 */\n/* #define SLJIT_CONFIG_PPC_32 1 */\n/* #define SLJIT_CONFIG_PPC_64 1 */\n/* #define SLJIT_CONFIG_MIPS_32 1 */\n/* #define SLJIT_CONFIG_MIPS_64 1 */\n/* #define SLJIT_CONFIG_RISCV_32 1 */\n/* #define SLJIT_CONFIG_RISCV_64 1 */\n/* #define SLJIT_CONFIG_S390X 1 */\n/* #define SLJIT_CONFIG_LOONGARCH_64 */\n\n/* #define SLJIT_CONFIG_AUTO 1 */\n/* #define SLJIT_CONFIG_UNSUPPORTED 1 */\n\n/*****************/\n/* Sanity check. */\n/*****************/\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \\\n\t+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \\\n\t+ (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \\\n\t+ (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \\\n\t+ (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \\\n\t+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \\\n\t+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \\\n\t+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \\\n\t+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \\\n\t+ (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \\\n\t+ (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \\\n\t+ (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t+ (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \\\n\t+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \\\n\t+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2\n#error \"Multiple architectures are selected\"\n#endif\n\n#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \\\n\t&& !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \\\n\t&& !(defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \\\n\t&& !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \\\n\t&& !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \\\n\t&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t&& !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \\\n\t&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \\\n\t&& !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \\\n\t&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \\\n\t&& !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \\\n\t&& !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \\\n\t&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t&& !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \\\n\t&& !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \\\n\t&& !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)\n#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO\n#error \"An architecture must be selected\"\n#else /* SLJIT_CONFIG_AUTO */\n#define SLJIT_CONFIG_AUTO 1\n#endif /* !SLJIT_CONFIG_AUTO */\n#endif /* !SLJIT_CONFIG */\n\n/********************************************************/\n/* Automatic CPU detection (requires compiler support). */\n/********************************************************/\n\n#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)\n#ifndef _WIN32\n\n#if defined(__i386__) || defined(__i386)\n#define SLJIT_CONFIG_X86_32 1\n#elif defined(__x86_64__)\n#define SLJIT_CONFIG_X86_64 1\n#elif defined(__aarch64__)\n#define SLJIT_CONFIG_ARM_64 1\n#elif defined(__thumb2__)\n#define SLJIT_CONFIG_ARM_THUMB2 1\n#elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \\\n\t((defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__)) \\\n\t || (defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8R__)) \\\n\t || (defined(__ARM_ARCH_9A__)))\n#define SLJIT_CONFIG_ARM_V7 1\n#elif defined(__arm__) || defined (__ARM__)\n#define SLJIT_CONFIG_ARM_V6 1\n#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))\n#define SLJIT_CONFIG_PPC_64 1\n#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)\n#define SLJIT_CONFIG_PPC_32 1\n#elif defined(__mips__) && !defined(_LP64)\n#define SLJIT_CONFIG_MIPS_32 1\n#elif defined(__mips64)\n#define SLJIT_CONFIG_MIPS_64 1\n#elif defined (__riscv_xlen) && (__riscv_xlen == 32)\n#define SLJIT_CONFIG_RISCV_32 1\n#elif defined (__riscv_xlen) && (__riscv_xlen == 64)\n#define SLJIT_CONFIG_RISCV_64 1\n#elif defined (__loongarch_lp64)\n#define SLJIT_CONFIG_LOONGARCH_64 1\n#elif defined(__s390x__)\n#define SLJIT_CONFIG_S390X 1\n#else\n/* Unsupported architecture */\n#define SLJIT_CONFIG_UNSUPPORTED 1\n#endif\n\n#else /* _WIN32 */\n\n#if defined(_M_X64) || defined(__x86_64__)\n#define SLJIT_CONFIG_X86_64 1\n#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)\n#define SLJIT_CONFIG_ARM_THUMB2 1\n#elif (defined(_M_ARM) && _M_ARM >= 7)\n#define SLJIT_CONFIG_ARM_V7 1\n#elif defined(_ARM_)\n#define SLJIT_CONFIG_ARM_V6 1\n#elif defined(_M_ARM64) || defined(__aarch64__)\n#define SLJIT_CONFIG_ARM_64 1\n#else\n#define SLJIT_CONFIG_X86_32 1\n#endif\n\n#endif /* !_WIN32 */\n#endif /* SLJIT_CONFIG_AUTO */\n\n#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)\n#undef SLJIT_EXECUTABLE_ALLOCATOR\n#endif /* SLJIT_CONFIG_UNSUPPORTED */\n\n/******************************/\n/* CPU family type detection. */\n/******************************/\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \\\n\t|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)\n#define SLJIT_CONFIG_ARM_32 1\n#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 || SLJIT_CONFIG_ARM_THUMB2 */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n#define SLJIT_CONFIG_X86 1\n#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n#define SLJIT_CONFIG_ARM 1\n#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#define SLJIT_CONFIG_PPC 1\n#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n#define SLJIT_CONFIG_MIPS 1\n#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n#define SLJIT_CONFIG_RISCV 1\n#elif (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)\n#define SLJIT_CONFIG_LOONGARCH 1\n#endif\n\n#endif /* SLJIT_CONFIG_CPU_H_ */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SLJIT_CONFIG_INTERNAL_H_\n#define SLJIT_CONFIG_INTERNAL_H_\n\n/*\n   SLJIT defines the following architecture dependent types and macros:\n\n   Types:\n     sljit_s8, sljit_u8   : signed and unsigned 8 bit integer type\n     sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type\n     sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type\n     sljit_sw, sljit_uw   : signed and unsigned machine word, enough to store a pointer\n     sljit_sp, sljit_up   : signed and unsigned pointer value (usually the same as\n                            sljit_uw, but some 64 bit ABIs may use 32 bit pointers)\n     sljit_f32            : 32 bit single precision floating point value\n     sljit_f64            : 64 bit double precision floating point value\n\n   Macros for feature detection (boolean):\n     SLJIT_32BIT_ARCHITECTURE : 32 bit architecture\n     SLJIT_64BIT_ARCHITECTURE : 64 bit architecture\n     SLJIT_LITTLE_ENDIAN : little endian architecture\n     SLJIT_BIG_ENDIAN : big endian architecture\n     SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported\n     SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported\n     SLJIT_MASKED_SHIFT : all word shifts are always masked\n     SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked\n     SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information\n     SLJIT_UPPER_BITS_IGNORED : 32 bit operations ignores the upper bits of source registers\n     SLJIT_UPPER_BITS_ZERO_EXTENDED : 32 bit operations clears the upper bits of destination registers\n     SLJIT_UPPER_BITS_SIGN_EXTENDED : 32 bit operations replicates the sign bit in the upper bits of destination registers\n     SLJIT_UPPER_BITS_PRESERVED : 32 bit operations preserves the upper bits of destination registers\n\n   Constants:\n     SLJIT_NUMBER_OF_REGISTERS : number of available registers\n     SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers\n     SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers\n     SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers\n     SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available scratch floating point registers\n     SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available saved floating point registers\n     SLJIT_NUMBER_OF_VECTOR_REGISTERS : number of available vector registers\n     SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS : number of available scratch vector registers\n     SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS : number of available saved vector registers\n     SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers\n     SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers\n     SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS : number of available temporary vector registers\n     SLJIT_SEPARATE_VECTOR_REGISTERS : if this macro is defined, the vector registers do not\n                                       overlap with floating point registers\n     SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index\n     SLJIT_POINTER_SHIFT : the shift required to apply when accessing a sljit_sp/sljit_up array by index\n     SLJIT_F32_SHIFT : the shift required to apply when accessing\n                       a single precision floating point array by index\n     SLJIT_F64_SHIFT : the shift required to apply when accessing\n                       a double precision floating point array by index\n     SLJIT_PREF_SHIFT_REG : x86 systems prefers ecx for shifting by register\n                            the scratch register index of ecx is stored in this variable\n     SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)\n     SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address\n     SLJIT_CONV_MAX_FLOAT : result when a floating point value is converted to integer\n                            and the floating point value is higher than the maximum integer value\n                            (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT)\n     SLJIT_CONV_MIN_FLOAT : result when a floating point value is converted to integer\n                            and the floating point value is lower than the minimum integer value\n                            (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT)\n     SLJIT_CONV_NAN_FLOAT : result when a NaN floating point value is converted to integer\n                            (possible values: SLJIT_CONV_RESULT_MAX_INT, SLJIT_CONV_RESULT_MIN_INT,\n                            or SLJIT_CONV_RESULT_ZERO)\n\n   Other macros:\n     SLJIT_TMP_R0 .. R9 : accessing temporary registers\n     SLJIT_TMP_R(i) : accessing temporary registers\n     SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers\n     SLJIT_TMP_FR(i) : accessing temporary floating point registers\n     SLJIT_TMP_VR0 .. VR9 : accessing temporary vector registers\n     SLJIT_TMP_VR(i) : accessing temporary vector registers\n     SLJIT_TMP_DEST_REG : a temporary register for results, see the rules below\n     SLJIT_TMP_DEST_FREG : a temporary register for float results, see the rules below\n     SLJIT_TMP_DEST_VREG : a temporary register for vector results, see the rules below\n     SLJIT_TMP_OPT_REG : a temporary register which might not be defined, see the rules below\n     SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT\n     SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)\n     SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit\n                             floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero\n\n   Temporary register rules (e.g. SLJIT_TMP_DEST_REG / SLJIT_TMP_OPT_REG):\n     Sljit tries to emit instructions without using any temporary registers whenever it is possible.\n     When a single temporary register is needed, it is always the \"OPT\" register. When two temporary\n     registers are needed, both the \"DEST\" and \"OPT\" are used. The x86-32 does not define an \"OPT\"\n     register, and handles all cases without an \"OPT\" register which requires an \"OPT\" register\n     on other architectures.\n*/\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \\\n\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))\n#include <stdio.h>\n#endif\n\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG \\\n\t&& (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))\n#include <stdlib.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/***********************************************************/\n/* Intel Control-flow Enforcement Technology (CET) spport. */\n/***********************************************************/\n\n#ifdef SLJIT_CONFIG_X86\n\n#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)\n#define SLJIT_CONFIG_X86_CET 1\n#endif\n\n#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)\n#include <x86intrin.h>\n#endif\n\n#endif /* SLJIT_CONFIG_X86 */\n\n/**********************************/\n/* External function definitions. */\n/**********************************/\n\n/* General macros:\n   Note: SLJIT is designed to be independent from them as possible.\n\n   In release mode (SLJIT_DEBUG is not defined) only the following\n   external functions are needed:\n*/\n\n#ifndef SLJIT_MALLOC\n#define SLJIT_MALLOC(size, allocator_data) (malloc(size))\n#endif\n\n#ifndef SLJIT_FREE\n#define SLJIT_FREE(ptr, allocator_data) (free(ptr))\n#endif\n\n#ifndef SLJIT_MEMCPY\n#define SLJIT_MEMCPY(dest, src, len) (memcpy(dest, src, len))\n#endif\n\n#ifndef SLJIT_MEMMOVE\n#define SLJIT_MEMMOVE(dest, src, len) (memmove(dest, src, len))\n#endif\n\n#ifndef SLJIT_ZEROMEM\n#define SLJIT_ZEROMEM(dest, len) (memset(dest, 0, len))\n#endif\n\n/***************************/\n/* Compiler helper macros. */\n/***************************/\n\n#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)\n\n#if defined(__GNUC__) && (__GNUC__ >= 3)\n#define SLJIT_LIKELY(x)\t\t__builtin_expect((x), 1)\n#define SLJIT_UNLIKELY(x)\t__builtin_expect((x), 0)\n#else\n#define SLJIT_LIKELY(x)\t\t(x)\n#define SLJIT_UNLIKELY(x)\t(x)\n#endif\n\n#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */\n\n#ifndef SLJIT_INLINE\n/* Inline functions. Some old compilers do not support them. */\n#ifdef __SUNPRO_C\n#if __SUNPRO_C < 0x560\n#define SLJIT_INLINE\n#else\n#define SLJIT_INLINE inline\n#endif /* __SUNPRO_C */\n#else\n#define SLJIT_INLINE __inline\n#endif\n#endif /* !SLJIT_INLINE */\n\n#ifndef SLJIT_NOINLINE\n/* Not inline functions. */\n#if defined(__GNUC__)\n#define SLJIT_NOINLINE __attribute__ ((noinline))\n#else\n#define SLJIT_NOINLINE\n#endif\n#endif /* !SLJIT_INLINE */\n\n#ifndef SLJIT_UNUSED_ARG\n/* Unused arguments. */\n#define SLJIT_UNUSED_ARG(arg) (void)arg\n#endif\n\n/*********************************/\n/* Type of public API functions. */\n/*********************************/\n\n#ifndef SLJIT_API_FUNC_ATTRIBUTE\n#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)\n/* Static ABI functions. For all-in-one programs. */\n\n#if defined(__GNUC__)\n/* Disable unused warnings in gcc. */\n#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))\n#else\n#define SLJIT_API_FUNC_ATTRIBUTE static\n#endif\n\n#else\n#define SLJIT_API_FUNC_ATTRIBUTE\n#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */\n#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */\n\n/****************************/\n/* Instruction cache flush. */\n/****************************/\n\n#ifdef __APPLE__\n#include <AvailabilityMacros.h>\n#endif\n\n/*\n * TODO:\n *\n * clang >= 15 could be safe to enable below\n * older versions are known to abort in some targets\n * https://github.com/PhilipHazel/pcre2/issues/92\n *\n * beware some vendors (ex: Microsoft, Apple) are known to have\n * removed the code to support this builtin even if the call for\n * __has_builtin reports it is available.\n *\n * make sure linking doesn't fail because __clear_cache() is\n * missing before changing it or add an exception so that the\n * system provided method that should be defined below is used\n * instead.\n */\n#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)\n#if __has_builtin(__builtin___clear_cache) && !defined(__clang__)\n\n/*\n * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=91248\n * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=93811\n * gcc's clear_cache builtin for power is broken\n */\n#if !defined(SLJIT_CONFIG_PPC)\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\t__builtin___clear_cache((char*)(from), (char*)(to))\n#endif\n\n#endif /* gcc >= 10 */\n#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */\n\n#ifndef SLJIT_CACHE_FLUSH\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\n/* Not required to implement on archs with unified caches. */\n#define SLJIT_CACHE_FLUSH(from, to)\n\n#elif defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050\n\n/* Supported by all macs since Mac OS 10.5.\n   However, it does not work on non-jailbroken iOS devices,\n   although the compilation is successful. */\n#include <libkern/OSCacheControl.h>\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\tsys_icache_invalidate((void*)(from), (size_t)((char*)(to) - (char*)(from)))\n\n#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\n/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\tppc_cache_flush((from), (to))\n#define SLJIT_CACHE_FLUSH_OWN_IMPL 1\n\n#elif defined(_WIN32)\n\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\tFlushInstructionCache(GetCurrentProcess(), (void*)(from), (size_t)((char*)(to) - (char*)(from)))\n\n#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || defined(__clang__)\n\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\t__builtin___clear_cache((char*)(from), (char*)(to))\n\n#elif defined __ANDROID__\n\n/* Android ARMv7 with gcc lacks __clear_cache; use cacheflush instead. */\n#include <sys/cachectl.h>\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\tcacheflush((long)(from), (long)(to), 0)\n\n#else\n\n/* Call __ARM_NR_cacheflush on ARM-Linux or the corresponding MIPS syscall. */\n#define SLJIT_CACHE_FLUSH(from, to) \\\n\t__clear_cache((char*)(from), (char*)(to))\n\n#endif\n\n#endif /* !SLJIT_CACHE_FLUSH */\n\n/******************************************************/\n/*    Integer and floating point type definitions.    */\n/******************************************************/\n\n/* 8 bit byte type. */\ntypedef unsigned char sljit_u8;\ntypedef signed char sljit_s8;\n\n/* 16 bit half-word type. */\ntypedef unsigned short int sljit_u16;\ntypedef signed short int sljit_s16;\n\n/* 32 bit integer type. */\ntypedef unsigned int sljit_u32;\ntypedef signed int sljit_s32;\n\n/* Machine word type. Enough for storing a pointer.\n     32 bit for 32 bit machines.\n     64 bit for 64 bit machines. */\n#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)\n/* Just to have something. */\n#define SLJIT_WORD_SHIFT 0\ntypedef unsigned int sljit_uw;\ntypedef int sljit_sw;\n#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \\\n\t&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \\\n\t&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \\\n\t&& !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \\\n\t&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t&& !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)\n#define SLJIT_32BIT_ARCHITECTURE 1\n#define SLJIT_WORD_SHIFT 2\ntypedef unsigned int sljit_uw;\ntypedef int sljit_sw;\n#else\n#define SLJIT_64BIT_ARCHITECTURE 1\n#define SLJIT_WORD_SHIFT 3\n#ifdef _WIN32\n#ifdef __GNUC__\n/* These types do not require windows.h */\ntypedef unsigned long long sljit_uw;\ntypedef long long sljit_sw;\n#else\ntypedef unsigned __int64 sljit_uw;\ntypedef __int64 sljit_sw;\n#endif\n#else /* !_WIN32 */\ntypedef unsigned long int sljit_uw;\ntypedef long int sljit_sw;\n#endif /* _WIN32 */\n#endif\n\ntypedef sljit_sw sljit_sp;\ntypedef sljit_uw sljit_up;\n\n/* Floating point types. */\ntypedef float sljit_f32;\ntypedef double sljit_f64;\n\n/* Shift for pointer sized data. */\n#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT\n\n/* Shift for double precision sized data. */\n#define SLJIT_F32_SHIFT 2\n#define SLJIT_F64_SHIFT 3\n\n#define SLJIT_CONV_RESULT_MAX_INT 0\n#define SLJIT_CONV_RESULT_MIN_INT 1\n#define SLJIT_CONV_RESULT_ZERO 2\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#elif (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_ZERO\n#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT\n#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT\n#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_ZERO\n#else\n#error \"Result for float to integer conversion is not defined\"\n#endif\n\n#ifndef SLJIT_W\n\n/* Defining long constants. */\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n#ifdef _WIN64\n#define SLJIT_W(w)\t(w##ll)\n#else /* !windows */\n#define SLJIT_W(w)\t(w##l)\n#endif /* windows */\n#else /* 32 bit */\n#define SLJIT_W(w)\t(w)\n#endif /* unknown */\n\n#endif /* !SLJIT_W */\n\n/*************************/\n/* Endianness detection. */\n/*************************/\n\n#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)\n\n/* These macros are mostly useful for the applications. */\n#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\n#ifdef __LITTLE_ENDIAN__\n#define SLJIT_LITTLE_ENDIAN 1\n#else\n#define SLJIT_BIG_ENDIAN 1\n#endif\n\n#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\n#ifdef __MIPSEL__\n#define SLJIT_LITTLE_ENDIAN 1\n#else\n#define SLJIT_BIG_ENDIAN 1\n#endif\n\n#ifndef SLJIT_MIPS_REV\n\n/* Auto detecting mips revision. */\n#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)\n#define SLJIT_MIPS_REV 6\n#elif defined(__mips_isa_rev) && __mips_isa_rev >= 1\n#define SLJIT_MIPS_REV __mips_isa_rev\n#elif defined(__clang__) \\\n\t&& (defined(_MIPS_ARCH_OCTEON) || defined(_MIPS_ARCH_P5600))\n/* clang either forgets to define (clang-7) __mips_isa_rev at all\n * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)\n * and -march=p5600 (MIPS32 R5).\n * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5\n * (should be set to N exactly) so we cannot rely on this too.\n */\n#define SLJIT_MIPS_REV 1\n#endif\n\n#endif /* !SLJIT_MIPS_REV */\n\n#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\n#define SLJIT_BIG_ENDIAN 1\n\n#else\n#define SLJIT_LITTLE_ENDIAN 1\n#endif\n\n#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */\n\n/* Sanity check. */\n#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#error \"Exactly one endianness must be selected\"\n#endif\n\n#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#error \"Exactly one endianness must be selected\"\n#endif\n\n#ifndef SLJIT_UNALIGNED\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t|| (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \\\n\t|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \\\n\t|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \\\n\t|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n#define SLJIT_UNALIGNED 1\n#endif\n\n#endif /* !SLJIT_UNALIGNED */\n\n#ifndef SLJIT_FPU_UNALIGNED\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \\\n\t|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n#define SLJIT_FPU_UNALIGNED 1\n#endif\n\n#endif /* !SLJIT_FPU_UNALIGNED */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n/* Auto detect SSE2 support using CPUID.\n   On 64 bit x86 cpus, sse2 must be present. */\n#define SLJIT_DETECT_SSE2 1\n#endif\n\n/*****************************************************************************************/\n/* Calling convention of functions generated by SLJIT or called from the generated code. */\n/*****************************************************************************************/\n\n#ifndef SLJIT_FUNC\n#define SLJIT_FUNC\n#endif /* !SLJIT_FUNC */\n\n#ifndef SLJIT_INDIRECT_CALL\n#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \\\n\t|| ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)\n/* It seems certain ppc compilers use an indirect addressing for functions\n   which makes things complicated. */\n#define SLJIT_INDIRECT_CALL 1\n#endif\n#endif /* SLJIT_INDIRECT_CALL */\n\n/* The offset which needs to be subtracted from the return address to\ndetermine the next executed instruction after return. */\n#ifndef SLJIT_RETURN_ADDRESS_OFFSET\n#define SLJIT_RETURN_ADDRESS_OFFSET 0\n#endif /* SLJIT_RETURN_ADDRESS_OFFSET */\n\n/***************************************************/\n/* Functions of the built-in executable allocator. */\n/***************************************************/\n\n#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);\n/* Note: sljitLir.h also defines sljit_free_unused_memory_exec() function. */\n#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)\n#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)\n\n#ifndef SLJIT_MALLOC_EXEC\n#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))\n#endif /* SLJIT_MALLOC_EXEC */\n\n#ifndef SLJIT_FREE_EXEC\n#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))\n#endif /* SLJIT_FREE_EXEC */\n\n#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)\nSLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);\n#define SLJIT_EXEC_OFFSET(code) sljit_exec_offset(code)\n#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n\n#endif /* SLJIT_EXECUTABLE_ALLOCATOR */\n\n#ifndef SLJIT_EXEC_OFFSET\n#define SLJIT_EXEC_OFFSET(ptr) 0\n#endif\n\n/**********************************************/\n/* Registers and locals offset determination. */\n/**********************************************/\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\n#define SLJIT_NUMBER_OF_REGISTERS 12\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 1\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_LOCALS_OFFSET_BASE (8 * (sljit_s32)sizeof(sljit_sw))\n#define SLJIT_PREF_SHIFT_REG SLJIT_R2\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_IGNORED 1\n#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\n#define SLJIT_NUMBER_OF_REGISTERS 13\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1\n#ifndef _WIN64\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0\n#define SLJIT_LOCALS_OFFSET_BASE 0\n#else /* _WIN64 */\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10\n#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))\n#endif /* !_WIN64 */\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_PREF_SHIFT_REG SLJIT_R3\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_IGNORED 1\n#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)\n\n#define SLJIT_NUMBER_OF_REGISTERS 12\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_LOCALS_OFFSET_BASE 0\n\n#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n\n#define SLJIT_NUMBER_OF_REGISTERS 26\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_IGNORED 1\n#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\n#define SLJIT_NUMBER_OF_REGISTERS 23\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)\n#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))\n#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n/* Add +1 for double alignment. */\n#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * (sljit_s32)sizeof(sljit_sw))\n#else\n#define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw))\n#endif /* SLJIT_CONFIG_PPC_64 || _AIX */\n#define SLJIT_UPPER_BITS_IGNORED 1\n\n#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\n#define SLJIT_NUMBER_OF_REGISTERS 21\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 13\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 6\n#else\n#define SLJIT_LOCALS_OFFSET_BASE 0\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8\n#endif\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n\n#define SLJIT_NUMBER_OF_REGISTERS 23\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 12\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2\n#define SLJIT_SEPARATE_VECTOR_REGISTERS 1\n#define SLJIT_NUMBER_OF_VECTOR_REGISTERS 30\n#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS 0\n#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS 2\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_TMP_DEST_VREG SLJIT_TMP_VR0\n#define SLJIT_LOCALS_OFFSET_BASE 0\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_IGNORED 1\n#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\n/*\n * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME\n *\n * 160\n *  .. FR6\n *  .. FR4\n *  .. FR2\n * 128 FR0\n * 120 R15 (used for SP)\n * 112 R14\n * 104 R13\n *  96 R12\n *  ..\n *  48 R6\n *  ..\n *  16 R2\n *   8 RESERVED\n *   0 SP\n */\n#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160\n\n#define SLJIT_NUMBER_OF_REGISTERS 12\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R2\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_UPPER_BITS_IGNORED 1\n#define SLJIT_UPPER_BITS_PRESERVED 1\n\n#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n\n#define SLJIT_NUMBER_OF_REGISTERS 23\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2\n#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1\n#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0\n#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0\n#define SLJIT_LOCALS_OFFSET_BASE 0\n#define SLJIT_MASKED_SHIFT 1\n#define SLJIT_MASKED_SHIFT32 1\n#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1\n\n#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)\n\n/* Just to have something. */\n#define SLJIT_NUMBER_OF_REGISTERS 0\n#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0\n#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 0\n#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0\n#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0\n#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0\n#define SLJIT_TMP_DEST_REG 0\n#define SLJIT_TMP_DEST_FREG 0\n#define SLJIT_LOCALS_OFFSET_BASE 0\n\n#endif\n\n#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n#define SLJIT_NUMBER_OF_VECTOR_REGISTERS (SLJIT_NUMBER_OF_FLOAT_REGISTERS)\n#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS (SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)\n#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS (SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)\n#define SLJIT_TMP_DEST_VREG (SLJIT_TMP_DEST_FREG)\n#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n\n#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)\n\n#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \\\n\t(SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)\n\n#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \\\n\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)\n\n#define SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS \\\n\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS)\n\n#if (defined SLJIT_UPPER_BITS_ZERO_EXTENDED && SLJIT_UPPER_BITS_ZERO_EXTENDED) \\\n\t+ (defined SLJIT_UPPER_BITS_SIGN_EXTENDED && SLJIT_UPPER_BITS_SIGN_EXTENDED) \\\n\t+ (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) > 1\n#error \"Invalid upper bits defintion\"\n#endif\n\n#if (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) \\\n\t&& !(defined SLJIT_UPPER_BITS_IGNORED && SLJIT_UPPER_BITS_IGNORED)\n#error \"Upper bits preserved requires bits ignored\"\n#endif\n\n/**********************************/\n/* Temporary register management. */\n/**********************************/\n\n#define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2)\n#define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define SLJIT_TMP_VREGISTER_BASE (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1)\n\n/* WARNING: Accessing temporary registers is not recommended, because they\n   are also used by the JIT compiler for various computations. Using them\n   might have any side effects including incorrect operations and crashes,\n   so use them at your own risk. The machine registers themselves might have\n   limitations, e.g. the r0 register on s390x / ppc cannot be used as\n   base address for memory operations. */\n\n/* Temporary registers */\n#define SLJIT_TMP_R0\t\t(SLJIT_TMP_REGISTER_BASE + 0)\n#define SLJIT_TMP_R1\t\t(SLJIT_TMP_REGISTER_BASE + 1)\n#define SLJIT_TMP_R2\t\t(SLJIT_TMP_REGISTER_BASE + 2)\n#define SLJIT_TMP_R3\t\t(SLJIT_TMP_REGISTER_BASE + 3)\n#define SLJIT_TMP_R4\t\t(SLJIT_TMP_REGISTER_BASE + 4)\n#define SLJIT_TMP_R5\t\t(SLJIT_TMP_REGISTER_BASE + 5)\n#define SLJIT_TMP_R6\t\t(SLJIT_TMP_REGISTER_BASE + 6)\n#define SLJIT_TMP_R7\t\t(SLJIT_TMP_REGISTER_BASE + 7)\n#define SLJIT_TMP_R8\t\t(SLJIT_TMP_REGISTER_BASE + 8)\n#define SLJIT_TMP_R9\t\t(SLJIT_TMP_REGISTER_BASE + 9)\n#define SLJIT_TMP_R(i)\t\t(SLJIT_TMP_REGISTER_BASE + (i))\n\n#define SLJIT_TMP_FR0\t\t(SLJIT_TMP_FREGISTER_BASE + 0)\n#define SLJIT_TMP_FR1\t\t(SLJIT_TMP_FREGISTER_BASE + 1)\n#define SLJIT_TMP_FR2\t\t(SLJIT_TMP_FREGISTER_BASE + 2)\n#define SLJIT_TMP_FR3\t\t(SLJIT_TMP_FREGISTER_BASE + 3)\n#define SLJIT_TMP_FR4\t\t(SLJIT_TMP_FREGISTER_BASE + 4)\n#define SLJIT_TMP_FR5\t\t(SLJIT_TMP_FREGISTER_BASE + 5)\n#define SLJIT_TMP_FR6\t\t(SLJIT_TMP_FREGISTER_BASE + 6)\n#define SLJIT_TMP_FR7\t\t(SLJIT_TMP_FREGISTER_BASE + 7)\n#define SLJIT_TMP_FR8\t\t(SLJIT_TMP_FREGISTER_BASE + 8)\n#define SLJIT_TMP_FR9\t\t(SLJIT_TMP_FREGISTER_BASE + 9)\n#define SLJIT_TMP_FR(i)\t\t(SLJIT_TMP_FREGISTER_BASE + (i))\n\n#define SLJIT_TMP_VR0\t\t(SLJIT_TMP_VREGISTER_BASE + 0)\n#define SLJIT_TMP_VR1\t\t(SLJIT_TMP_VREGISTER_BASE + 1)\n#define SLJIT_TMP_VR2\t\t(SLJIT_TMP_VREGISTER_BASE + 2)\n#define SLJIT_TMP_VR3\t\t(SLJIT_TMP_VREGISTER_BASE + 3)\n#define SLJIT_TMP_VR4\t\t(SLJIT_TMP_VREGISTER_BASE + 4)\n#define SLJIT_TMP_VR5\t\t(SLJIT_TMP_VREGISTER_BASE + 5)\n#define SLJIT_TMP_VR6\t\t(SLJIT_TMP_VREGISTER_BASE + 6)\n#define SLJIT_TMP_VR7\t\t(SLJIT_TMP_VREGISTER_BASE + 7)\n#define SLJIT_TMP_VR8\t\t(SLJIT_TMP_VREGISTER_BASE + 8)\n#define SLJIT_TMP_VR9\t\t(SLJIT_TMP_VREGISTER_BASE + 9)\n#define SLJIT_TMP_VR(i)\t\t(SLJIT_TMP_VREGISTER_BASE + (i))\n\n/********************************/\n/* CPU status flags management. */\n/********************************/\n\n#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \\\n\t|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \\\n\t|| (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \\\n\t|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n#define SLJIT_HAS_STATUS_FLAGS_STATE 1\n#endif\n\n/***************************************/\n/* Floating point register management. */\n/***************************************/\n\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \\\n\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define SLJIT_F64_SECOND(reg) \\\n\t((reg) + SLJIT_FS0 + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)\n#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */\n#define SLJIT_F64_SECOND(reg) \\\n\t(reg)\n#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */\n\n/*************************************/\n/* Debug and verbose related macros. */\n/*************************************/\n\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\n#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)\n\n/* SLJIT_HALT_PROCESS must halt the process. */\n#ifndef SLJIT_HALT_PROCESS\n#define SLJIT_HALT_PROCESS() \\\n\tabort();\n#endif /* !SLJIT_HALT_PROCESS */\n\n#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */\n\n/* Feel free to redefine these two macros. */\n#ifndef SLJIT_ASSERT\n\n#define SLJIT_ASSERT(x) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(!(x))) { \\\n\t\t\tprintf(\"Assertion failed at \" __FILE__ \":%d\\n\", __LINE__); \\\n\t\t\tSLJIT_HALT_PROCESS(); \\\n\t\t} \\\n\t} while (0)\n\n#endif /* !SLJIT_ASSERT */\n\n#ifndef SLJIT_UNREACHABLE\n\n#define SLJIT_UNREACHABLE() \\\n\tdo { \\\n\t\tprintf(\"Should never been reached \" __FILE__ \":%d\\n\", __LINE__); \\\n\t\tSLJIT_HALT_PROCESS(); \\\n\t} while (0)\n\n#endif /* !SLJIT_UNREACHABLE */\n\n#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */\n\n/* Forcing empty, but valid statements. */\n#undef SLJIT_ASSERT\n#undef SLJIT_UNREACHABLE\n\n#define SLJIT_ASSERT(x) \\\n\tdo { } while (0)\n#define SLJIT_UNREACHABLE() \\\n\tdo { } while (0)\n\n#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */\n\n#ifndef SLJIT_COMPILE_ASSERT\n\n#define SLJIT_COMPILE_ASSERT(x, description) \\\n\tswitch(0) { case 0: case ((x) ? 1 : 0): break; }\n\n#endif /* !SLJIT_COMPILE_ASSERT */\n\n#ifndef SLJIT_FALLTHROUGH\n\n#if defined(__cplusplus) && __cplusplus >= 202002L && \\\n\tdefined(__has_cpp_attribute)\n/* Standards-compatible C++ variant. */\n#if __has_cpp_attribute(fallthrough)\n#define SLJIT_FALLTHROUGH [[fallthrough]];\n#endif\n#elif !defined(__cplusplus) && \\\n\t  defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \\\n\t  defined(__has_c_attribute)\n/* Standards-compatible C variant. */\n#if __has_c_attribute(fallthrough)\n#define SLJIT_FALLTHROUGH [[fallthrough]];\n#endif\n#elif ((defined(__clang__) && __clang_major__ >= 10) || \\\n\t   (defined(__GNUC__) && __GNUC__ >= 7)) && \\\n\t  defined(__has_attribute)\n/* Clang and GCC syntax. Rule out old versions because apparently Clang at\n   least has a broken implementation of __has_attribute. */\n#if __has_attribute(fallthrough)\n#define SLJIT_FALLTHROUGH __attribute__((fallthrough));\n#endif\n#endif\n\n#ifndef SLJIT_FALLTHROUGH\n#define SLJIT_FALLTHROUGH\n#endif\n\n#endif /* !SLJIT_FALLTHROUGH */\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /* SLJIT_CONFIG_INTERNAL_H_ */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitLir.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"sljitLir.h\"\n\n#ifdef _WIN32\n\n#include <windows.h>\n\n#endif /* _WIN32 */\n\n#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)\n\n/* These libraries are needed for the macros below. */\n#include <stdlib.h>\n#include <string.h>\n\n#endif /* SLJIT_STD_MACROS_DEFINED */\n\n#define CHECK_ERROR() \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(compiler->error)) \\\n\t\t\treturn compiler->error; \\\n\t} while (0)\n\n#define CHECK_ERROR_PTR() \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(compiler->error)) \\\n\t\t\treturn NULL; \\\n\t} while (0)\n\n#define FAIL_IF(expr) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(expr)) \\\n\t\t\treturn compiler->error; \\\n\t} while (0)\n\n#define PTR_FAIL_IF(expr) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(expr)) \\\n\t\t\treturn NULL; \\\n\t} while (0)\n\n#define FAIL_IF_NULL(ptr) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(!(ptr))) { \\\n\t\t\tcompiler->error = SLJIT_ERR_ALLOC_FAILED; \\\n\t\t\treturn SLJIT_ERR_ALLOC_FAILED; \\\n\t\t} \\\n\t} while (0)\n\n#define PTR_FAIL_IF_NULL(ptr) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(!(ptr))) { \\\n\t\t\tcompiler->error = SLJIT_ERR_ALLOC_FAILED; \\\n\t\t\treturn NULL; \\\n\t\t} \\\n\t} while (0)\n\n#define PTR_FAIL_WITH_EXEC_IF(ptr) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(!(ptr))) { \\\n\t\t\tcompiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \\\n\t\t\treturn NULL; \\\n\t\t} \\\n\t} while (0)\n\n#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)\n\n#define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type))\n\n#define VARIABLE_FLAG_SHIFT (10)\n/* All variable flags are even. */\n#define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT)\n#define ALL_STATUS_FLAGS_MASK (VARIABLE_FLAG_MASK | SLJIT_SET_Z)\n#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)\n#define GET_FLAG_TYPE_MASK(op) (((op) >> VARIABLE_FLAG_SHIFT) & 0x3e)\n#define GET_OPCODE(op) ((op) & 0xff)\n#define HAS_FLAGS(op) ((op) & ALL_STATUS_FLAGS_MASK)\n#define GET_ALL_FLAGS(op) ((op) & (SLJIT_32 | ALL_STATUS_FLAGS_MASK))\n\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n#define TYPE_CAST_NEEDED(op) \\\n\t((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)\n#else /* !SLJIT_64BIT_ARCHITECTURE */\n#define TYPE_CAST_NEEDED(op) \\\n\t((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)\n#endif /* SLJIT_64BIT_ARCHITECTURE */\n\n#define BUF_SIZE\t4096\n\n#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)\n#define ABUF_SIZE\t2048\n#else /* !SLJIT_32BIT_ARCHITECTURE */\n#define ABUF_SIZE\t4096\n#endif /* SLJIT_32BIT_ARCHITECTURE */\n\n/* Parameter parsing. */\n#define REG_MASK\t\t0x7f\n#define OFFS_REG(reg)\t\t(((reg) >> 8) & REG_MASK)\n#define OFFS_REG_MASK\t\t(REG_MASK << 8)\n#define TO_OFFS_REG(reg)\t((reg) << 8)\n#define FAST_IS_REG(reg)\t((reg) < REG_MASK)\n\n/* Mask for argument types. */\n#define SLJIT_ARG_MASK\t\t0x7\n#define SLJIT_ARG_FULL_MASK\t(SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG)\n\n/* Mask for register pairs. */\n#define REG_PAIR_MASK\t\t0x7f00\n#define REG_PAIR_FIRST(reg)\t((reg) & 0x7f)\n#define REG_PAIR_SECOND(reg)\t((reg) >> 8)\n\n/* Mask for sljit_emit_enter. */\n#define ENTER_GET_REGS(regs)\t\t\t((regs) & 0xff)\n#define ENTER_GET_FLOAT_REGS(regs)\t\t(((regs) >> 8) & 0xff)\n#define ENTER_GET_VECTOR_REGS(regs)\t\t(((regs) >> 16) & 0xff)\n#define SLJIT_KEPT_SAVEDS_COUNT(options)\t((options) & 0x3)\n\n/* Getters for simd operations, which returns with log2(size). */\n#define SLJIT_SIMD_GET_OPCODE(type)\t\t((type) & 0xff)\n#define SLJIT_SIMD_GET_REG_SIZE(type)\t\t(((type) >> 12) & 0x3f)\n#define SLJIT_SIMD_GET_ELEM_SIZE(type)\t\t(((type) >> 18) & 0x3f)\n#define SLJIT_SIMD_GET_ELEM2_SIZE(type)\t\t(((type) >> 24) & 0x3f)\n\n#define SLJIT_SIMD_CHECK_REG(type) (((type) & 0x3f000) >= SLJIT_SIMD_REG_64 && ((type) & 0x3f000) <= SLJIT_SIMD_REG_512)\n#define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))\n#define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))\n\n/* Label definitions. */\n\n#define SLJIT_LABEL_ALIGNED ((~(sljit_uw)0) - 1)\n\nstruct sljit_extended_label {\n\tstruct sljit_label label;\n\tsljit_uw index;\n\tsljit_uw data;\n};\n\n/* Jump definitions. */\n\n/* Jump flag bits. */\n#define JUMP_ADDR\t0x1\n#define JUMP_MOV_ADDR\t0x2\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n#\tdefine PATCH_MB\t\t0x04\n#\tdefine PATCH_MW\t\t0x08\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n#\tdefine PATCH_MD\t\t0x10\n#\tdefine MOV_ADDR_HI\t0x20\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)(10 + 3))\n#\tdefine CJUMP_MAX_SIZE\t((sljit_uw)(2 + 10 + 3))\n#else /* !SLJIT_CONFIG_X86_64 */\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)5)\n#\tdefine CJUMP_MAX_SIZE\t((sljit_uw)6)\n#endif /* SLJIT_CONFIG_X86_64 */\n#\tdefine TYPE_SHIFT\t17\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n/* Bits 7..15 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x10000 */\n#\tdefine JUMP_SIZE_SHIFT\t8\n#endif /* SLJIT_DEBUG */\n#endif /* SLJIT_CONFIG_X86 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_BL\t\t0x04\n#\tdefine PATCH_B\t\t0x08\n#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n#\tdefine CPOOL_SIZE\t512\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n#\tdefine JUMP_SIZE_SHIFT\t26\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)3)\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\n#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_COND\t\t0x04\n#\tdefine IS_BL\t\t0x08\n\t/* mov_addr does not use IS_BL */\n#\tdefine IS_ABS\t\tIS_BL\n\t/* conditional + imm8 */\n#\tdefine PATCH_TYPE1\t0x10\n\t/* conditional + imm20 */\n#\tdefine PATCH_TYPE2\t0x20\n\t/* imm11 */\n#\tdefine PATCH_TYPE3\t0x30\n\t/* imm24 */\n#\tdefine PATCH_TYPE4\t0x40\n\t/* BL + imm24 */\n#\tdefine PATCH_TYPE5\t0x50\n\t/* addwi/subwi */\n#\tdefine PATCH_TYPE6\t0x60\n\t/* 0xf00 cc code for branches */\n#\tdefine JUMP_SIZE_SHIFT\t26\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)5)\n#endif /* SLJIT_CONFIG_ARM_THUMB2 */\n\n#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_COND\t\t0x004\n#\tdefine IS_CBZ\t\t0x008\n#\tdefine IS_BL\t\t0x010\n#\tdefine PATCH_COND\t0x020\n#\tdefine PATCH_B\t\t0x040\n#\tdefine PATCH_B32\t0x080\n#\tdefine PATCH_ABS48\t0x100\n#\tdefine PATCH_ABS64\t0x200\n#\tdefine JUMP_SIZE_SHIFT\t58\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)5)\n#endif /* SLJIT_CONFIG_ARM_64 */\n\n#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_COND\t\t0x004\n#\tdefine IS_CALL\t\t0x008\n#\tdefine PATCH_B\t\t0x010\n#\tdefine PATCH_ABS_B\t0x020\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#\tdefine PATCH_ABS32\t0x040\n#\tdefine PATCH_ABS48\t0x080\n#\tdefine JUMP_SIZE_SHIFT\t58\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)7)\n#else /* !SLJIT_CONFIG_PPC_64 */\n#\tdefine JUMP_SIZE_SHIFT\t26\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)4)\n#endif /* SLJIT_CONFIG_PPC_64 */\n#endif /* SLJIT_CONFIG_PPC */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_MOVABLE\t0x004\n#\tdefine IS_JAL\t\t0x008\n#\tdefine IS_CALL\t\t0x010\n#\tdefine IS_BIT26_COND\t0x020\n#\tdefine IS_BIT16_COND\t0x040\n#\tdefine IS_BIT23_COND\t0x080\n\n#\tdefine IS_COND\t\t(IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)\n\n#\tdefine PATCH_B\t\t0x100\n#\tdefine PATCH_J\t\t0x200\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n#\tdefine PATCH_ABS32\t0x400\n#\tdefine PATCH_ABS48\t0x800\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\t/* instruction types */\n#\tdefine MOVABLE_INS\t0\n\t/* 1 - 31 last destination register */\n\t/* no destination (i.e: store) */\n#\tdefine UNMOVABLE_INS\t32\n\t/* FPU status register */\n#\tdefine FCSR_FCC\t\t33\n#endif /* SLJIT_CONFIG_MIPS */\n\n#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_COND\t\t0x0004\n#\tdefine IS_CALL\t\t0x0008\n\n#\tdefine IS_COND16\t0x0010\n#\tdefine PATCH_B\t\t0x0020\n#\tdefine PATCH_J\t\t0x0040\n#\tdefine PATCH_16\t\t0x0080\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n#\tdefine PATCH_REL32\t0x0100\n#\tdefine PATCH_ABS32\t0x0200\n#\tdefine PATCH_ABS44\t0x0400\n#\tdefine PATCH_ABS52\t0x0800\n#\tdefine JUMP_SIZE_SHIFT\t58\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)12)\n#else /* !SLJIT_CONFIG_RISCV_64 */\n#\tdefine JUMP_SIZE_SHIFT\t26\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)4)\n#endif /* SLJIT_CONFIG_RISCV_64 */\n#endif /* SLJIT_CONFIG_RISCV */\n\n#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine PATCH_POOL\t\t0x004\n#\tdefine PATCH_IMM32\t\t0x008\n#endif /* SLJIT_CONFIG_S390X */\n\n#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n/* SLJIT_REWRITABLE_JUMP is 0x10000. */\n#\tdefine IS_COND\t\t0x004\n#\tdefine IS_CALL\t\t0x008\n\n#\tdefine PATCH_B\t\t0x010\n#\tdefine PATCH_J\t\t0x020\n\n#\tdefine PATCH_REL32\t0x040\n#\tdefine PATCH_ABS32\t0x080\n#\tdefine PATCH_ABS52\t0x100\n#\tdefine JUMP_SIZE_SHIFT\t58\n#\tdefine JUMP_MAX_SIZE\t((sljit_uw)4)\n\n#endif /* SLJIT_CONFIG_LOONGARCH */\n\n/* Stack management. */\n\n#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \\\n\t(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \\\n\t\t(saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))\n\n#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, type) \\\n\t(((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \\\n\t\t(fsaveds)) * SSIZE_OF(type))\n\n#define ADJUST_LOCAL_OFFSET(p, i) \\\n\tif ((p) == (SLJIT_MEM1(SLJIT_SP))) \\\n\t\t(i) += SLJIT_LOCALS_OFFSET;\n\n#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */\n\n/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */\n#include \"sljitUtils.c\"\n\n#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)\n#define SLJIT_CODE_TO_PTR(code) ((void*)((sljit_up)(code) & ~(sljit_up)0x1))\n#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n#define SLJIT_CODE_TO_PTR(code) ((void*)(*(sljit_up*)code))\n#else /* !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_INDIRECT_CALL */\n#define SLJIT_CODE_TO_PTR(code) ((void*)(code))\n#endif /* SLJIT_CONFIG_ARM_THUMB2 || SLJIT_INDIRECT_CALL */\n\n#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)\n\n#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)\n\n#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)\n\n#if defined(__NetBSD__)\n#include \"allocator_src/sljitProtExecAllocatorNetBSD.c\"\n#else /* !__NetBSD__ */\n#include \"allocator_src/sljitProtExecAllocatorPosix.c\"\n#endif /* __NetBSD__ */\n\n#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)\n\n#if defined(_WIN32)\n#include \"allocator_src/sljitWXExecAllocatorWindows.c\"\n#else /* !_WIN32 */\n#include \"allocator_src/sljitWXExecAllocatorPosix.c\"\n#endif /* _WIN32 */\n\n#else /* !SLJIT_PROT_EXECUTABLAE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */\n\n#if defined(_WIN32)\n#include \"allocator_src/sljitExecAllocatorWindows.c\"\n#elif defined(__APPLE__)\n#include \"allocator_src/sljitExecAllocatorApple.c\"\n#elif defined(__FreeBSD__)\n#include \"allocator_src/sljitExecAllocatorFreeBSD.c\"\n#else /* !_WIN32 && !__APPLE__ && !__FreeBSD__ */\n#include \"allocator_src/sljitExecAllocatorPosix.c\"\n#endif /* _WIN32 */\n\n#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n\n#else /* !SLJIT_EXECUTABLE_ALLOCATOR */\n\n#ifndef SLJIT_UPDATE_WX_FLAGS\n#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)\n#endif /* SLJIT_UPDATE_WX_FLAGS */\n\n#endif /* SLJIT_EXECUTABLE_ALLOCATOR */\n\n#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)\n#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))\n#else /* !SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))\n#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n\n/* Argument checking features. */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\n/* Returns with error when an invalid argument is passed. */\n\n#define CHECK_ARGUMENT(x) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(!(x))) \\\n\t\t\treturn 1; \\\n\t} while (0)\n\n#define CHECK_RETURN_TYPE sljit_s32\n#define CHECK_RETURN_OK return 0\n\n#define CHECK(x) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(x)) { \\\n\t\t\tcompiler->error = SLJIT_ERR_BAD_ARGUMENT; \\\n\t\t\treturn SLJIT_ERR_BAD_ARGUMENT; \\\n\t\t} \\\n\t} while (0)\n\n#define CHECK_PTR(x) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(x)) { \\\n\t\t\tcompiler->error = SLJIT_ERR_BAD_ARGUMENT; \\\n\t\t\treturn NULL; \\\n\t\t} \\\n\t} while (0)\n\n#define CHECK_REG_INDEX(x) \\\n\tdo { \\\n\t\tif (SLJIT_UNLIKELY(x)) { \\\n\t\t\treturn -2; \\\n\t\t} \\\n\t} while (0)\n\n#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\n/* Assertion failure occures if an invalid argument is passed. */\n#undef SLJIT_ARGUMENT_CHECKS\n#define SLJIT_ARGUMENT_CHECKS 1\n\n#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)\n#define CHECK_RETURN_TYPE void\n#define CHECK_RETURN_OK return\n#define CHECK(x) x\n#define CHECK_PTR(x) x\n#define CHECK_REG_INDEX(x) x\n\n#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\n/* Arguments are not checked. */\n#define CHECK_RETURN_TYPE void\n#define CHECK_RETURN_OK return\n#define CHECK(x) x\n#define CHECK_PTR(x) x\n#define CHECK_REG_INDEX(x) x\n\n#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_DEBUG && !SLJIT_VERBOSE */\n\n/* Arguments are not checked. */\n#define CHECK(x)\n#define CHECK_PTR(x)\n#define CHECK_REG_INDEX(x)\n\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n/* --------------------------------------------------------------------- */\n/*  Public functions                                                     */\n/* --------------------------------------------------------------------- */\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n#define SLJIT_NEEDS_COMPILER_INIT 1\nstatic sljit_s32 compiler_initialized = 0;\n/* A thread safe initialization. */\nstatic void init_compiler(void);\n#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_RISCV */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)\n{\n\tstruct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);\n\tif (!compiler)\n\t\treturn NULL;\n\tSLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));\n\n\tSLJIT_COMPILE_ASSERT(\n\t\tsizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1\n\t\t&& sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2\n\t\t&& sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4\n\t\t&& (sizeof(sljit_up) == 4 || sizeof(sljit_up) == 8)\n\t\t&& sizeof(sljit_up) <= sizeof(sljit_sw)\n\t\t&& sizeof(sljit_up) == sizeof(sljit_sp)\n\t\t&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)\n\t\t&& (sizeof(sljit_uw) == sizeof(sljit_sw)),\n\t\tinvalid_integer_types);\n\tSLJIT_COMPILE_ASSERT((SLJIT_REWRITABLE_JUMP & SLJIT_32) == 0\n\t\t\t&& (ALL_STATUS_FLAGS_MASK & SLJIT_32) == 0\n\t\t\t&& (SLJIT_REWRITABLE_JUMP & ALL_STATUS_FLAGS_MASK) == 0,\n\t\trewritable_jump_and_status_flag_bits_and_sljit_32_must_not_have_common_bits);\n\tSLJIT_COMPILE_ASSERT((VARIABLE_FLAG_MASK & SLJIT_SET_Z) == 0,\n\t\trewritable_jump_and_status_flag_bits_must_not_have_common_bits);\n\tSLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),\n\t\tconditional_flags_must_be_even_numbers);\n\n\t/* Only the non-zero members must be set. */\n\tcompiler->error = SLJIT_SUCCESS;\n\n\tcompiler->allocator_data = allocator_data;\n\tcompiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);\n\tcompiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);\n\n\tif (!compiler->buf || !compiler->abuf) {\n\t\tif (compiler->buf)\n\t\t\tSLJIT_FREE(compiler->buf, allocator_data);\n\t\tif (compiler->abuf)\n\t\t\tSLJIT_FREE(compiler->abuf, allocator_data);\n\t\tSLJIT_FREE(compiler, allocator_data);\n\t\treturn NULL;\n\t}\n\n\tcompiler->buf->next = NULL;\n\tcompiler->buf->used_size = 0;\n\tcompiler->abuf->next = NULL;\n\tcompiler->abuf->used_size = 0;\n\n\tcompiler->scratches = -1;\n\tcompiler->saveds = -1;\n\tcompiler->fscratches = -1;\n\tcompiler->fsaveds = -1;\n#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \\\n\t\t|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tcompiler->vscratches = -1;\n\tcompiler->vsaveds = -1;\n#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */\n\tcompiler->local_size = -1;\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tcompiler->args_size = -1;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tcompiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)\n\t\t+ CPOOL_SIZE * sizeof(sljit_u8), allocator_data);\n\tif (!compiler->cpool) {\n\t\tSLJIT_FREE(compiler->buf, allocator_data);\n\t\tSLJIT_FREE(compiler->abuf, allocator_data);\n\t\tSLJIT_FREE(compiler, allocator_data);\n\t\treturn NULL;\n\t}\n\tcompiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);\n\tcompiler->cpool_diff = 0xffffffff;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\tcompiler->delay_slot = UNMOVABLE_INS;\n#endif /* SLJIT_CONFIG_MIPS */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tSLJIT_ASSERT(compiler->last_flags == 0 && compiler->logical_local_size == 0);\n\tcompiler->last_return = -1;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\tcompiler->real_fscratches = -1;\n\tcompiler->real_fsaveds = -1;\n#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n\tSLJIT_ASSERT(compiler->skip_checks == 0);\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */\n\n#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)\n\tif (!compiler_initialized) {\n\t\tinit_compiler();\n\t\tcompiler_initialized = 1;\n\t}\n#endif /* SLJIT_NEEDS_COMPILER_INIT */\n\n\treturn compiler;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)\n{\n\tstruct sljit_memory_fragment *buf;\n\tstruct sljit_memory_fragment *curr;\n\tvoid *allocator_data = compiler->allocator_data;\n\tSLJIT_UNUSED_ARG(allocator_data);\n\n\tbuf = compiler->buf;\n\twhile (buf) {\n\t\tcurr = buf;\n\t\tbuf = buf->next;\n\t\tSLJIT_FREE(curr, allocator_data);\n\t}\n\n\tbuf = compiler->abuf;\n\twhile (buf) {\n\t\tcurr = buf;\n\t\tbuf = buf->next;\n\t\tSLJIT_FREE(curr, allocator_data);\n\t}\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tSLJIT_FREE(compiler->cpool, allocator_data);\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\tSLJIT_FREE(compiler, allocator_data);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)\n{\n\tif (compiler->error == SLJIT_SUCCESS)\n\t\tcompiler->error = SLJIT_ERR_ALLOC_FAILED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)\n{\n\tSLJIT_UNUSED_ARG(exec_allocator_data);\n\n\tSLJIT_FREE_EXEC(SLJIT_CODE_TO_PTR(code), exec_allocator_data);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)\n{\n\tif (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {\n\t\tjump->flags &= (sljit_uw)~JUMP_ADDR;\n\t\tjump->u.label = label;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)\n{\n\tif (SLJIT_LIKELY(!!jump)) {\n\t\tjump->flags |= JUMP_ADDR;\n\t\tjump->u.target = target;\n\t}\n}\n\n#define SLJIT_CURRENT_FLAGS_ALL (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD \\\n\t| SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE | SLJIT_CURRENT_FLAGS_OP2CMPZ)\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)\n{\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(current_flags);\n\n#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)\n#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\tif (current_flags & SLJIT_CURRENT_FLAGS_OP2CMPZ) {\n\t\tcurrent_flags |= SLJIT_SET_Z;\n\t}\n#endif /* SLJIT_CONFIG_S390X */\n\n\tcompiler->status_flags_state = current_flags;\n#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tcompiler->last_flags = 0;\n\tif ((current_flags & ~(ALL_STATUS_FLAGS_MASK | SLJIT_CURRENT_FLAGS_ALL)) == 0) {\n\t\tcompiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n}\n\n/* --------------------------------------------------------------------- */\n/*  Private functions                                                    */\n/* --------------------------------------------------------------------- */\n\nstatic void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)\n{\n\tsljit_u8 *ret;\n\tstruct sljit_memory_fragment *new_frag;\n\n\tSLJIT_ASSERT(size <= 256);\n\tif (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {\n\t\tret = compiler->buf->memory + compiler->buf->used_size;\n\t\tcompiler->buf->used_size += size;\n\t\treturn ret;\n\t}\n\tnew_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);\n\tPTR_FAIL_IF_NULL(new_frag);\n\tnew_frag->next = compiler->buf;\n\tcompiler->buf = new_frag;\n\tnew_frag->used_size = size;\n\treturn new_frag->memory;\n}\n\nstatic void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)\n{\n\tsljit_u8 *ret;\n\tstruct sljit_memory_fragment *new_frag;\n\n\tSLJIT_ASSERT(size <= 256);\n\tif (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {\n\t\tret = compiler->abuf->memory + compiler->abuf->used_size;\n\t\tcompiler->abuf->used_size += size;\n\t\treturn ret;\n\t}\n\tnew_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);\n\tPTR_FAIL_IF_NULL(new_frag);\n\tnew_frag->next = compiler->abuf;\n\tcompiler->abuf = new_frag;\n\tnew_frag->used_size = size;\n\treturn new_frag->memory;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)\n{\n\tCHECK_ERROR_PTR();\n\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n\tif (size <= 0 || size > 128)\n\t\treturn NULL;\n\tsize = (size + 7) & ~7;\n#else /* !SLJIT_64BIT_ARCHITECTURE */\n\tif (size <= 0 || size > 64)\n\t\treturn NULL;\n\tsize = (size + 3) & ~3;\n#endif /* SLJIT_64BIT_ARCHITECTURE */\n\treturn ensure_abuf(compiler, (sljit_uw)size);\n}\n\nstatic SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)\n{\n\tstruct sljit_memory_fragment *buf = compiler->buf;\n\tstruct sljit_memory_fragment *prev = NULL;\n\tstruct sljit_memory_fragment *tmp;\n\n\tdo {\n\t\ttmp = buf->next;\n\t\tbuf->next = prev;\n\t\tprev = buf;\n\t\tbuf = tmp;\n\t} while (buf != NULL);\n\n\tcompiler->buf = prev;\n}\n\nstatic SLJIT_INLINE void* allocate_executable_memory(sljit_uw size, sljit_s32 options,\n\tvoid *exec_allocator_data, sljit_sw *executable_offset)\n{\n\tvoid *code;\n\tstruct sljit_generate_code_buffer *buffer;\n\n\tif (SLJIT_LIKELY(!(options & SLJIT_GENERATE_CODE_BUFFER))) {\n\t\tcode = SLJIT_MALLOC_EXEC(size, exec_allocator_data);\n\t\t*executable_offset = SLJIT_EXEC_OFFSET(code);\n\t\treturn code;\n\t}\n\n\tbuffer = (struct sljit_generate_code_buffer*)exec_allocator_data;\n\n\tif (size <= buffer->size) {\n\t\t*executable_offset = buffer->executable_offset;\n\t\treturn buffer->buffer;\n\t}\n\n\treturn NULL;\n}\n\n#define SLJIT_MAX_ADDRESS ~(sljit_uw)0\n\n#define SLJIT_GET_NEXT_SIZE(ptr) (ptr != NULL) ? ((ptr)->size) : SLJIT_MAX_ADDRESS\n#define SLJIT_GET_NEXT_ADDRESS(ptr) (ptr != NULL) ? ((ptr)->addr) : SLJIT_MAX_ADDRESS\n\n#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n\n#define SLJIT_NEXT_DEFINE_TYPES \\\n\tsljit_uw next_label_size; \\\n\tsljit_uw next_jump_addr; \\\n\tsljit_uw next_const_addr; \\\n\tsljit_uw next_min_addr\n\n#define SLJIT_NEXT_INIT_TYPES() \\\n\tnext_label_size = SLJIT_GET_NEXT_SIZE(label); \\\n\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); \\\n\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\n#define SLJIT_GET_NEXT_MIN() \\\n\tnext_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_const_addr);\n\nstatic SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size,\n\tsljit_uw next_jump_addr, sljit_uw next_const_addr)\n{\n\tsljit_uw result = next_jump_addr;\n\n\tSLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_const_addr);\n\n\tif (next_const_addr < result)\n\t\tresult = next_const_addr;\n\n\tif (next_label_size < result)\n\t\tresult = next_label_size;\n\n\treturn result;\n}\n\n#endif /* !SLJIT_CONFIG_X86 */\n\n#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\nstatic void update_float_register_count(struct sljit_compiler *compiler, sljit_s32 scratches, sljit_s32 saveds)\n{\n\tsljit_s32 vscratches = ENTER_GET_VECTOR_REGS(scratches);\n\tsljit_s32 vsaveds = ENTER_GET_VECTOR_REGS(saveds);\n\n\tif (compiler->fscratches < vscratches)\n\t\tcompiler->fscratches = vscratches;\n\n\tif (compiler->fsaveds < vsaveds)\n\t\tcompiler->fsaveds = vsaveds;\n\n\tif (compiler->fsaveds + compiler->fscratches > SLJIT_NUMBER_OF_FLOAT_REGISTERS)\n\t\tcompiler->fscratches = SLJIT_NUMBER_OF_FLOAT_REGISTERS - compiler->fsaveds;\n}\n\n#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n\nstatic SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 args,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tSLJIT_UNUSED_ARG(args);\n\tSLJIT_UNUSED_ARG(local_size);\n\n\tcompiler->options = options;\n\tcompiler->scratches = ENTER_GET_REGS(scratches);\n\tcompiler->saveds = ENTER_GET_REGS(saveds);\n\t/* These members may be copied to real_* members below. */\n\tcompiler->fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tcompiler->fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\tcompiler->vscratches = ENTER_GET_VECTOR_REGS(scratches);\n\tcompiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds);\n#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tcompiler->real_fscratches = compiler->fscratches;\n\tcompiler->real_fsaveds = compiler->fsaveds;\n\tcompiler->vscratches = ENTER_GET_VECTOR_REGS(scratches);\n\tcompiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds);\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */\n\tupdate_float_register_count(compiler, scratches, saveds);\n#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tcompiler->last_return = args & SLJIT_ARG_MASK;\n\tcompiler->logical_local_size = local_size;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n}\n\nstatic SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)\n{\n\tlabel->next = NULL;\n\tlabel->u.index = compiler->label_count++;\n\tlabel->size = compiler->size;\n\n\tif (compiler->last_label != NULL)\n\t\tcompiler->last_label->next = label;\n\telse\n\t\tcompiler->labels = label;\n\n\tcompiler->last_label = label;\n}\n\nstatic SLJIT_INLINE void set_extended_label(struct sljit_extended_label *ext_label, struct sljit_compiler *compiler, sljit_uw type, sljit_uw data)\n{\n\tset_label(&ext_label->label, compiler);\n\text_label->index = ext_label->label.u.index;\n\text_label->label.u.index = type;\n\text_label->data = data;\n}\n\nstatic SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)\n{\n\tjump->next = NULL;\n\tjump->flags = flags;\n\tjump->u.label = NULL;\n\n\tif (compiler->last_jump != NULL)\n\t\tcompiler->last_jump->next = jump;\n\telse\n\t\tcompiler->jumps = jump;\n\n\tcompiler->last_jump = jump;\n}\n\nstatic SLJIT_INLINE void set_mov_addr(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_uw offset)\n{\n\tjump->next = NULL;\n\tjump->addr = compiler->size - offset;\n\tjump->flags = JUMP_MOV_ADDR;\n\tjump->u.label = NULL;\n\tif (compiler->last_jump != NULL)\n\t\tcompiler->last_jump->next = jump;\n\telse\n\t\tcompiler->jumps = jump;\n\tcompiler->last_jump = jump;\n}\n\nstatic SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)\n{\n\tconst_->next = NULL;\n\tconst_->addr = compiler->size;\n\tif (compiler->last_const != NULL)\n\t\tcompiler->last_const->next = const_;\n\telse\n\t\tcompiler->consts = const_;\n\tcompiler->last_const = const_;\n}\n\n#define ADDRESSING_DEPENDS_ON(exp, reg) \\\n\t(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\nstatic sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)\n{\n\tsljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;\n\n\tcurr_type = (arg_types & SLJIT_ARG_FULL_MASK);\n\n\tif (curr_type >= SLJIT_ARG_TYPE_F64) {\n\t\tif (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)\n\t\t\treturn 0;\n\t} else if (curr_type >= SLJIT_ARG_TYPE_W) {\n\t\tif (scratches == 0)\n\t\t\treturn 0;\n\t}\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\tword_arg_count = 0;\n\tscratch_arg_end = 0;\n\tsaved_arg_count = 0;\n\tfloat_arg_count = 0;\n\twhile (arg_types != 0) {\n\t\tif (word_arg_count + float_arg_count >= 4)\n\t\t\treturn 0;\n\n\t\tcurr_type = (arg_types & SLJIT_ARG_MASK);\n\n\t\tif (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {\n\t\t\tif (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)\n\t\t\t\treturn 0;\n\n\t\t\tword_arg_count++;\n\t\t\tscratch_arg_end = word_arg_count;\n\t\t} else {\n\t\t\tif (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)\n\t\t\t\treturn 0;\n\n\t\t\tif (curr_type < SLJIT_ARG_TYPE_F64) {\n\t\t\t\tword_arg_count++;\n\t\t\t\tsaved_arg_count++;\n\t\t\t} else\n\t\t\t\tfloat_arg_count++;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (saveds == -1)\n\t\treturn (word_arg_count <= scratches && float_arg_count <= fscratches);\n\n\treturn (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);\n}\n\n#define FUNCTION_CHECK_IS_REG(r) \\\n\t(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \\\n\t|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0) \\\n\t|| ((r) >= SLJIT_TMP_REGISTER_BASE && (r) < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)))\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n#define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)\n#else /* !SLJIT_CONFIG_X86_32 */\n#define CHECK_IF_VIRTUAL_REGISTER(p) 0\n#endif /* SLJIT_CONFIG_X86_32 */\n\nstatic sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (!(p & SLJIT_MEM))\n\t\treturn 0;\n\n\tif (p == SLJIT_MEM1(SLJIT_SP))\n\t\treturn (i >= 0 && i < compiler->logical_local_size);\n\n\tif (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))\n\t\treturn 0;\n\n\tif (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))\n\t\treturn 0;\n\n\tif (p & OFFS_REG_MASK) {\n\t\tif (!(p & REG_MASK))\n\t\t\treturn 0;\n\n\t\tif (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))\n\t\t\treturn 0;\n\n\t\tif (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))\n\t\t\treturn 0;\n\n\t\tif ((i & ~0x3) != 0)\n\t\t\treturn 0;\n\t}\n\n\treturn (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;\n}\n\n#define FUNCTION_CHECK_SRC_MEM(p, i) \\\n\tCHECK_ARGUMENT(function_check_src_mem(compiler, p, i));\n\nstatic sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (FUNCTION_CHECK_IS_REG(p))\n\t\treturn (i == 0);\n\n\tif (p == SLJIT_IMM)\n\t\treturn 1;\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\n#define FUNCTION_CHECK_SRC(p, i) \\\n\tCHECK_ARGUMENT(function_check_src(compiler, p, i));\n\nstatic sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (FUNCTION_CHECK_IS_REG(p))\n\t\treturn (i == 0);\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\n#define FUNCTION_CHECK_DST(p, i) \\\n\tCHECK_ARGUMENT(function_check_dst(compiler, p, i));\n\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \\\n\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\n#define FUNCTION_CHECK_IS_FREG(fr, is_32) \\\n\tfunction_check_is_freg(compiler, (fr), (is_32))\n\nstatic sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32);\n\n#define FUNCTION_FCHECK(p, i, is_32) \\\n\tCHECK_ARGUMENT(function_fcheck(compiler, (p), (i), (is_32)));\n\nstatic sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 is_32)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (FUNCTION_CHECK_IS_FREG(p, is_32))\n\t\treturn (i == 0);\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\nstatic sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type);\n\n#define FUNCTION_CHECK_IS_VREG(vr, type) \\\n\tfunction_check_is_vreg(compiler, (vr), (type))\n\n#define FUNCTION_VCHECK(p, i, type) \\\n\tCHECK_ARGUMENT(function_vcheck(compiler, (p), (i), (type)))\n\nstatic sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 type)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (FUNCTION_CHECK_IS_VREG(p, type))\n\t\treturn (i == 0);\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\n#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */\n\n#define FUNCTION_CHECK_IS_FREG(fr, is_32) \\\n\tfunction_check_is_freg(compiler, (fr))\n\nstatic sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr)\n{\n\tsljit_s32 fscratches, fsaveds;\n\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n#else /* SLJIT_SEPARATE_VECTOR_REGISTERS */\n\tfscratches = compiler->real_fscratches;\n\tfsaveds = compiler->real_fsaveds;\n#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n\n\treturn (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + fscratches))\n\t\t|| (fr > (SLJIT_FS0 - fsaveds) && fr <= SLJIT_FS0)\n\t\t|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));\n}\n\n#define FUNCTION_FCHECK(p, i, is_32) \\\n\tCHECK_ARGUMENT(function_fcheck(compiler, (p), (i)));\n\nstatic sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (function_check_is_freg(compiler, p))\n\t\treturn (i == 0);\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\n#define FUNCTION_CHECK_IS_VREG(vr, type) \\\n\tfunction_check_is_vreg(compiler, (vr))\n\nstatic sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\treturn (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches))\n\t\t|| (vr > (SLJIT_VS0 - compiler->vsaveds) && vr <= SLJIT_VS0)\n\t\t|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));\n}\n\n#define FUNCTION_VCHECK(p, i, type) \\\n\tCHECK_ARGUMENT(function_vcheck(compiler, (p), (i)))\n\nstatic sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (function_check_is_vreg(compiler, p))\n\t\treturn (i == 0);\n\n\treturn function_check_src_mem(compiler, p, i);\n}\n\n#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */\n\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)\n{\n\tcompiler->verbose = verbose;\n}\n\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n#ifdef _WIN64\n#ifdef __GNUC__\n#\tdefine SLJIT_PRINT_D\t\"ll\"\n#else /* !__GNUC__ */\n#\tdefine SLJIT_PRINT_D\t\"I64\"\n#endif  /* __GNUC__ */\n#else /* !_WIN64 */\n#\tdefine SLJIT_PRINT_D\t\"l\"\n#endif /* _WIN64 */\n#else /* !SLJIT_64BIT_ARCHITECTURE */\n#\tdefine SLJIT_PRINT_D\t\"\"\n#endif /* SLJIT_64BIT_ARCHITECTURE */\n\nstatic void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)\n{\n\tif (r < (SLJIT_R0 + compiler->scratches))\n\t\tfprintf(compiler->verbose, \"r%d\", r - SLJIT_R0);\n\telse if (r < SLJIT_SP)\n\t\tfprintf(compiler->verbose, \"s%d\", SLJIT_NUMBER_OF_REGISTERS - r);\n\telse if (r == SLJIT_SP)\n\t\tfprintf(compiler->verbose, \"sp\");\n\telse\n\t\tfprintf(compiler->verbose, \"t%d\", r - SLJIT_TMP_REGISTER_BASE);\n}\n\nstatic void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)\n{\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \\\n\t\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (r >= SLJIT_F64_SECOND(SLJIT_FR0)) {\n\t\tfprintf(compiler->verbose, \"^\");\n\t\tr -= SLJIT_F64_SECOND(0);\n\t}\n#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */\n\n\tif (r < (SLJIT_FR0 + compiler->fscratches))\n\t\tfprintf(compiler->verbose, \"fr%d\", r - SLJIT_FR0);\n\telse if (r < SLJIT_TMP_FREGISTER_BASE)\n\t\tfprintf(compiler->verbose, \"fs%d\", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);\n\telse\n\t\tfprintf(compiler->verbose, \"ft%d\", r - SLJIT_TMP_FREGISTER_BASE);\n}\n\nstatic void sljit_verbose_vreg(struct sljit_compiler *compiler, sljit_s32 r)\n{\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \\\n\t\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (r >= SLJIT_F64_SECOND(SLJIT_VR0)) {\n\t\tfprintf(compiler->verbose, \"^\");\n\t\tr -= SLJIT_F64_SECOND(0);\n\t}\n#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */\n\n\tif (r < (SLJIT_VR0 + compiler->vscratches))\n\t\tfprintf(compiler->verbose, \"vr%d\", r - SLJIT_VR0);\n\telse if (r < SLJIT_TMP_VREGISTER_BASE)\n\t\tfprintf(compiler->verbose, \"vs%d\", SLJIT_NUMBER_OF_VECTOR_REGISTERS - r);\n\telse\n\t\tfprintf(compiler->verbose, \"vt%d\", r - SLJIT_TMP_VREGISTER_BASE);\n}\n\nstatic void sljit_verbose_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (!(p & REG_MASK)) {\n\t\tfprintf(compiler->verbose, \"[%\" SLJIT_PRINT_D \"d]\", i);\n\t\treturn;\n\t}\n\n\tfputc('[', compiler->verbose);\n\tsljit_verbose_reg(compiler, (p) & REG_MASK);\n\tif (p & OFFS_REG_MASK) {\n\t\tfprintf(compiler->verbose, \" + \");\n\t\tsljit_verbose_reg(compiler, OFFS_REG(p));\n\t\tif (i)\n\t\t\tfprintf(compiler->verbose, \" * %d\", 1 << (i));\n\t} else if (i)\n\t\tfprintf(compiler->verbose, \" + %\" SLJIT_PRINT_D \"d\", (i));\n\tfputc(']', compiler->verbose);\n}\n\nstatic void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (p == SLJIT_IMM)\n\t\tfprintf(compiler->verbose, \"#%\" SLJIT_PRINT_D \"d\", i);\n\telse if (p & SLJIT_MEM)\n\t\tsljit_verbose_mem(compiler, p, i);\n\telse\n\t\tsljit_verbose_reg(compiler, p);\n}\n\nstatic void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (p & SLJIT_MEM)\n\t\tsljit_verbose_mem(compiler, p, i);\n\telse\n\t\tsljit_verbose_freg(compiler, p);\n}\n\nstatic void sljit_verbose_vparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)\n{\n\tif (p & SLJIT_MEM)\n\t\tsljit_verbose_mem(compiler, p, i);\n\telse\n\t\tsljit_verbose_vreg(compiler, p);\n}\n\nstatic const char* op0_names[] = {\n\t\"breakpoint\", \"nop\", \"lmul.uw\", \"lmul.sw\",\n\t\"divmod.u\", \"divmod.s\", \"div.u\", \"div.s\",\n\t\"memory_barrier\", \"endbr\", \"skip_frames_before_return\"\n};\n\nstatic const char* op1_names[] = {\n\t\"mov\", \"mov\", \"mov\", \"mov\",\n\t\"mov\", \"mov\", \"mov\", \"mov\",\n\t\"mov\", \"clz\", \"ctz\", \"rev\",\n\t\"rev\", \"rev\", \"rev\", \"rev\"\n};\n\nstatic const char* op1_types[] = {\n\t\"\", \".u8\", \".s8\", \".u16\",\n\t\".s16\", \".u32\", \".s32\", \"32\",\n\t\".p\", \"\", \"\", \"\",\n\t\".u16\", \".s16\", \".u32\", \".s32\"\n};\n\nstatic const char* op2_names[] = {\n\t\"add\", \"addc\", \"sub\", \"subc\",\n\t\"mul\", \"and\", \"or\", \"xor\",\n\t\"shl\", \"mshl\", \"lshr\", \"mlshr\",\n\t\"ashr\", \"mashr\", \"rotl\", \"rotr\"\n};\n\nstatic const char* op2r_names[] = {\n\t\"muladd\"\n};\n\nstatic const char* op_src_dst_names[] = {\n\t\"fast_return\", \"skip_frames_before_fast_return\",\n\t\"prefetch_l1\", \"prefetch_l2\",\n\t\"prefetch_l3\", \"prefetch_once\",\n\t\"fast_enter\", \"get_return_address\"\n};\n\nstatic const char* fop1_names[] = {\n\t\"mov\", \"conv\", \"conv\", \"conv\",\n\t\"conv\", \"conv\", \"conv\", \"conv\",\n\t\"cmp\", \"neg\", \"abs\",\n};\n\nstatic const char* fop1_conv_types[] = {\n\t\"sw\", \"s32\", \"sw\", \"s32\",\n\t\"uw\", \"u32\"\n};\n\nstatic const char* fop2_names[] = {\n\t\"add\", \"sub\", \"mul\", \"div\"\n};\n\nstatic const char* fop2r_names[] = {\n\t\"copysign\"\n};\n\nstatic const char* simd_op2_names[] = {\n\t\"and\", \"or\", \"xor\", \"shuffle\"\n};\n\nstatic const char* jump_names[] = {\n\t\"equal\", \"not_equal\",\n\t\"less\", \"greater_equal\",\n\t\"greater\", \"less_equal\",\n\t\"sig_less\", \"sig_greater_equal\",\n\t\"sig_greater\", \"sig_less_equal\",\n\t\"overflow\", \"not_overflow\",\n\t\"carry\", \"not_carry\",\n\t\"atomic_stored\", \"atomic_not_stored\",\n\t\"f_equal\", \"f_not_equal\",\n\t\"f_less\", \"f_greater_equal\",\n\t\"f_greater\", \"f_less_equal\",\n\t\"unordered\", \"ordered\",\n\t\"ordered_equal\", \"unordered_or_not_equal\",\n\t\"ordered_less\", \"unordered_or_greater_equal\",\n\t\"ordered_greater\", \"unordered_or_less_equal\",\n\t\"unordered_or_equal\", \"ordered_not_equal\",\n\t\"unordered_or_less\", \"ordered_greater_equal\",\n\t\"unordered_or_greater\", \"ordered_less_equal\",\n\t\"jump\", \"fast_call\",\n\t\"call\", \"call_reg_arg\"\n};\n\nstatic const char* call_arg_names[] = {\n\t\"void\", \"w\", \"32\", \"p\", \"f64\", \"f32\"\n};\n\nstatic const char* op_addr_types[] = {\n\t\"mov_addr\", \"mov_abs_addr\", \"add_abs_addr\"\n};\n\n#endif /* SLJIT_VERBOSE */\n\n/* --------------------------------------------------------------------- */\n/*  Arch dependent                                                       */\n/* --------------------------------------------------------------------- */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\n#define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1\n#define SLJIT_CHECK_OPCODE(op, flags) ((op) & ~(SLJIT_32 | ALL_STATUS_FLAGS_MASK | (flags)))\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tstruct sljit_jump *jump;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(options);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(compiler->size > 0);\n\tCHECK_ARGUMENT((options & ~(SLJIT_GENERATE_CODE_BUFFER | SLJIT_GENERATE_CODE_NO_CONTEXT)) == 0);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\t/* All jumps have target. */\n\t\tCHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL);\n\t\tjump = jump->next;\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\tCHECK_RETURN_OK;\n}\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (SLJIT_ENTER_USE_VEX)\n#else /* !SLJIT_CONFIG_X86 */\n#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (0)\n#endif /* !SLJIT_CONFIG_X86 */\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tsljit_s32 real_scratches = ENTER_GET_REGS(scratches);\n\tsljit_s32 real_saveds = ENTER_GET_REGS(saveds);\n\tsljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\tsljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches);\n\tsljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\tSLJIT_UNUSED_ARG(compiler);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\tCHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));\n\t} else {\n\t\tCHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);\n\t}\n\tCHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);\n\tCHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0);\n\tCHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS);\n\tCHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);\n\tCHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS);\n\tCHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);\n\tCHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32);\n\tCHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches,\n\t\t(options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches));\n\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  enter ret[%s\", call_arg_names[arg_types & SLJIT_ARG_MASK]);\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\tif (arg_types) {\n\t\t\tfprintf(compiler->verbose, \"], args[\");\n\t\t\tdo {\n\t\t\t\tfprintf(compiler->verbose, \"%s%s\", call_arg_names[arg_types & SLJIT_ARG_MASK],\n\t\t\t\t\t(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? \"_r\" : \"\");\n\t\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t\t\tif (arg_types)\n\t\t\t\t\tfprintf(compiler->verbose, \",\");\n\t\t\t} while (arg_types);\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"],\");\n\n\t\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\t\tif (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)\n\t\t\t\tfprintf(compiler->verbose, \" opt:reg_arg(%d),\", SLJIT_KEPT_SAVEDS_COUNT(options));\n\t\t\telse\n\t\t\t\tfprintf(compiler->verbose, \" opt:reg_arg,\");\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n\t\tif (options & SLJIT_ENTER_USE_VEX) {\n\t\t\t\tfprintf(compiler->verbose, \" opt:use_vex,\");\n\t\t}\n#endif /* !SLJIT_CONFIG_X86 */\n\n\t\tfprintf(compiler->verbose, \" scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\\n\",\n\t\t\tENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds),\n\t\t\tENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tsljit_s32 real_scratches = ENTER_GET_REGS(scratches);\n\tsljit_s32 real_saveds = ENTER_GET_REGS(saveds);\n\tsljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\tsljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches);\n\tsljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\tSLJIT_UNUSED_ARG(compiler);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\tCHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));\n\t} else {\n\t\tCHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);\n\t}\n\tCHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);\n\tCHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0);\n\tCHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS);\n\tCHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);\n\tCHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS);\n\tCHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);\n\tCHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS);\n\tCHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);\n\tCHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);\n\tCHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches,\n\t\t(options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches));\n\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  set_context ret[%s\", call_arg_names[arg_types & SLJIT_ARG_MASK]);\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\tif (arg_types) {\n\t\t\tfprintf(compiler->verbose, \"], args[\");\n\t\t\tdo {\n\t\t\t\tfprintf(compiler->verbose, \"%s%s\", call_arg_names[arg_types & SLJIT_ARG_MASK],\n\t\t\t\t\t(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? \"_r\" : \"\");\n\t\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t\t\tif (arg_types)\n\t\t\t\t\tfprintf(compiler->verbose, \",\");\n\t\t\t} while (arg_types);\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"],\");\n\n\t\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\t\tif (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)\n\t\t\t\tfprintf(compiler->verbose, \" opt:reg_arg(%d),\", SLJIT_KEPT_SAVEDS_COUNT(options));\n\t\t\telse\n\t\t\t\tfprintf(compiler->verbose, \" opt:reg_arg,\");\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n\t\tif (options & SLJIT_ENTER_USE_VEX) {\n\t\t\t\tfprintf(compiler->verbose, \" opt:use_vex,\");\n\t\t}\n#endif /* !SLJIT_CONFIG_X86 */\n\n\t\tfprintf(compiler->verbose, \" scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\\n\",\n\t\t\tENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds),\n\t\t\tENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\n#undef SLJIT_ENTER_CPU_SPECIFIC_OPTIONS\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  return_void\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(compiler->scratches >= 0);\n\n\tswitch (compiler->last_return) {\n\tcase SLJIT_ARG_TYPE_W:\n\t\tCHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);\n\t\tbreak;\n\tcase SLJIT_ARG_TYPE_32:\n\t\tCHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));\n\t\tbreak;\n\tcase SLJIT_ARG_TYPE_P:\n\t\tCHECK_ARGUMENT(op == SLJIT_MOV_P);\n\t\tbreak;\n\tcase SLJIT_ARG_TYPE_F64:\n\t\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\t\tCHECK_ARGUMENT(op == SLJIT_MOV_F64);\n\t\tbreak;\n\tcase SLJIT_ARG_TYPE_F32:\n\t\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\t\tCHECK_ARGUMENT(op == SLJIT_MOV_F32);\n\t\tbreak;\n\tdefault:\n\t\t/* Context not initialized, void, etc. */\n\t\tCHECK_ARGUMENT(0);\n\t\tbreak;\n\t}\n\n\tif (SLJIT_CHECK_OPCODE(op, 0) < SLJIT_MOV_F64) {\n\t\tFUNCTION_CHECK_SRC(src, srcw);\n\t} else {\n\t\tFUNCTION_FCHECK(src, srcw, op & SLJIT_32);\n\t}\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (GET_OPCODE(op) < SLJIT_MOV_F64) {\n\t\t\tfprintf(compiler->verbose, \"  return%s%s \", !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t\top1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);\n\t\t\tsljit_verbose_param(compiler, src, srcw);\n\t\t} else {\n\t\t\tfprintf(compiler->verbose, \"  return%s \", !(op & SLJIT_32) ? \".f64\" : \".f32\");\n\t\t\tsljit_verbose_fparam(compiler, src, srcw);\n\t\t}\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tFUNCTION_CHECK_SRC(src, srcw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  return_to \");\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)\n\t\t|| ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)\n\t\t|| (op >= SLJIT_MEMORY_BARRIER && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) < SLJIT_LMUL_UW || SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MEMORY_BARRIER || compiler->scratches >= 2);\n\tif ((SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_LMUL_UW && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)\n\t\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose))\n\t{\n\t\tfprintf(compiler->verbose, \"  %s\", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);\n\t\tif (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {\n\t\t\tfprintf(compiler->verbose, (op & SLJIT_32) ? \"32\" : \"w\");\n\t\t}\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_REV_S32);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_P:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\t/* Nothing allowed */\n\t\tCHECK_ARGUMENT(!(op & (SLJIT_32 | ALL_STATUS_FLAGS_MASK)));\n\t\tbreak;\n\tdefault:\n\t\t/* Only SLJIT_32 is allowed. */\n\t\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\t\tbreak;\n\t}\n\n\tFUNCTION_CHECK_DST(dst, dstw);\n\tFUNCTION_CHECK_SRC(src, srcw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s%s \", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE],\n\t\t\t!(op & SLJIT_32) ? \"\" : \"32\", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);\n\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | ALL_STATUS_FLAGS_MASK) >= SLJIT_MOV\n\t\t&& SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | ALL_STATUS_FLAGS_MASK) <= SLJIT_MOV_P);\n\tCHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS));\n\n\t/* All arguments must be valid registers. */\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));\n\n\tif (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) {\n\t\t/* Nothing allowed. */\n\t\tCHECK_ARGUMENT(!(op & SLJIT_32));\n\t}\n\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_atomic_load(compiler, op | SLJIT_ATOMIC_TEST, dst_reg, mem_reg)) {\n\t\t\tfprintf(compiler->verbose, \"    # atomic_load: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  atomic_load\");\n\t\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\t\tfprintf(compiler->verbose, \"_cas\");\n\t\tif (op & SLJIT_ATOMIC_USE_LS)\n\t\t\tfprintf(compiler->verbose, \"_ls\");\n\n\t\tfprintf(compiler->verbose, \"%s%s \", !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t\top1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);\n\t\tsljit_verbose_reg(compiler, dst_reg);\n\t\tfprintf(compiler->verbose, \", [\");\n\t\tsljit_verbose_reg(compiler, mem_reg);\n\t\tfprintf(compiler->verbose, \"]\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) >= SLJIT_MOV\n\t\t&& SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) <= SLJIT_MOV_P);\n\tCHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS));\n\n\t/* All arguments must be valid registers. */\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && (src_reg != temp_reg || (op & SLJIT_ATOMIC_USE_LS)));\n\n\tCHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE_MASK(op) == SLJIT_ATOMIC_STORED);\n\n\tif (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) {\n\t\t/* Nothing allowed. */\n\t\tCHECK_ARGUMENT(!(op & SLJIT_32));\n\t}\n\n\tcompiler->last_flags = GET_FLAG_TYPE_MASK(op) | (op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_atomic_store(compiler, op | SLJIT_ATOMIC_TEST, src_reg, mem_reg, temp_reg)) {\n\t\t\tfprintf(compiler->verbose, \"    # atomic_store: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  atomic_store\");\n\t\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\t\tfprintf(compiler->verbose, \"_cas\");\n\t\tif (op & SLJIT_ATOMIC_USE_LS)\n\t\t\tfprintf(compiler->verbose, \"_ls\");\n\n\t\tfprintf(compiler->verbose, \"%s%s%s \", !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t\top1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? \"\" : \".stored\");\n\t\tsljit_verbose_reg(compiler, src_reg);\n\t\tfprintf(compiler->verbose, \", [\");\n\t\tsljit_verbose_reg(compiler, mem_reg);\n\t\tfprintf(compiler->verbose, \"], \");\n\t\tsljit_verbose_reg(compiler, temp_reg);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\nstatic sljit_s32 check_sljit_emit_op2_operation(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\treturn !(op & VARIABLE_FLAG_MASK);\n\tcase SLJIT_MUL:\n\t\treturn !(op & SLJIT_SET_Z) && (!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);\n\tcase SLJIT_ADD:\n\t\treturn !(op & VARIABLE_FLAG_MASK)\n\t\t\t|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)\n\t\t\t|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\tcase SLJIT_SUB:\n\t\treturn !(op & VARIABLE_FLAG_MASK)\n\t\t\t|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)\n\t\t\t|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);\n\tcase SLJIT_ADDC:\n\tcase SLJIT_SUBC:\n\t\treturn (!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY))\n\t\t\t&& (compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY)\n\t\t\t&& (op & SLJIT_32) == (compiler->last_flags & SLJIT_32);\n\t\tbreak;\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\treturn !(op & ALL_STATUS_FLAGS_MASK);\n\t}\n\n\t/* Operation type should be checked earlier. */\n\tSLJIT_UNREACHABLE();\n\treturn 1;\n}\n\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ROTR);\n\tCHECK_ARGUMENT(check_sljit_emit_op2_operation(compiler, op));\n\n\tif (unset) {\n\t\tCHECK_ARGUMENT(HAS_FLAGS(op));\n\t} else {\n\t\tFUNCTION_CHECK_DST(dst, dstw);\n\t}\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tFUNCTION_CHECK_SRC(src2, src2w);\n\tcompiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s%s%s%s \", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t!(op & SLJIT_SET_Z) ? \"\" : \".z\", !(op & VARIABLE_FLAG_MASK) ? \"\" : \".\",\n\t\t\t!(op & VARIABLE_FLAG_MASK) ? \"\" : jump_names[GET_FLAG_TYPE(op)]);\n\t\tif (unset)\n\t\t\tfprintf(compiler->verbose, \"unset\");\n\t\telse\n\t\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT((op | SLJIT_32) == SLJIT_MULADD32);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tFUNCTION_CHECK_SRC(src2, src2w);\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s \", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? \"\" : \"32\");\n\n\t\tsljit_verbose_reg(compiler, dst_reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_SHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_LSHR\n\t\t|| SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MSHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MLSHR);\n\tCHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));\n\tFUNCTION_CHECK_SRC(src3, src3w);\n\tCHECK_ARGUMENT(dst_reg != src2_reg);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s.into%s \", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t(op & SLJIT_SHIFT_INTO_NON_ZERO) ? \".nz\" : \"\");\n\n\t\tsljit_verbose_reg(compiler, dst_reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_reg(compiler, src1_reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_reg(compiler, src2_reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src3, src3w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tSLJIT_UNUSED_ARG(shift_arg);\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT((op & ~SLJIT_SRC2_UNDEFINED) == (SLJIT_ADD | SLJIT_SHL_IMM));\n\tFUNCTION_CHECK_DST(dst, dstw);\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tFUNCTION_CHECK_SRC(src2, src2w);\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s.shl_imm%s \", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],\n\t\t\t(op & SLJIT_SRC2_UNDEFINED) ? \".src2und\" : \"\");\n\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \", #%\" SLJIT_PRINT_D \"d\\n\", shift_arg);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);\n\tFUNCTION_CHECK_SRC(src, srcw);\n\n\tif (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) {\n\t\tCHECK_ARGUMENT(src != SLJIT_IMM);\n\t\tcompiler->last_flags = 0;\n\t} else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) {\n\t\tCHECK_ARGUMENT(src & SLJIT_MEM);\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s \", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(op >= SLJIT_FAST_ENTER && op <= SLJIT_GET_RETURN_ADDRESS);\n\tFUNCTION_CHECK_DST(dst, dstw);\n\n\tif (op == SLJIT_FAST_ENTER)\n\t\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s \", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(reg);\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tif (type == SLJIT_GP_REGISTER) {\n\t\tCHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS)\n\t\t\t|| (reg >= SLJIT_TMP_REGISTER_BASE && reg < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)));\n\t}\n#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\telse if (((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))) {\n\t\tCHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_VECTOR_REGISTERS)\n\t\t\t|| (reg >= SLJIT_TMP_VREGISTER_BASE && reg < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)));\n\t}\n#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */\n\telse {\n\t\tCHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6) || (type & (3 << 12)) || (type & (4 << 12)) || (type & (5 << 12)) || (type & (6 << 12))));\n\t\tCHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS)\n\t\t\t|| (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)));\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tsljit_u32 i;\n#endif /* SLJIT_VERBOSE */\n\n\tSLJIT_UNUSED_ARG(compiler);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(instruction);\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n\tCHECK_ARGUMENT(size > 0 && size < 16);\n#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n\tCHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)\n\t\t|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));\n#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\tCHECK_ARGUMENT(size == 2 || size == 4 || size == 6);\n#else /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_CONFIG_RISCV && !SLJIT_CONFIG_S390X */\n\tCHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);\n#endif /* SLJIT_CONFIG_X86 */\n\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  op_custom\");\n\t\tfor (i = 0; i < size; i++)\n\t\t\tfprintf(compiler->verbose, \" 0x%x\", ((sljit_u8*)instruction)[i]);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ABS_F64);\n\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\tFUNCTION_FCHECK(src, srcw, op & SLJIT_32);\n\tFUNCTION_FCHECK(dst, dstw, op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)\n\t\t\tfprintf(compiler->verbose, \"  %s%s \", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],\n\t\t\t\t(op & SLJIT_32) ? \".f32.from.f64\" : \".f64.from.f32\");\n\t\telse\n\t\t\tfprintf(compiler->verbose, \"  %s%s \", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],\n\t\t\t\t(op & SLJIT_32) ? \".f32\" : \".f64\");\n\n\t\tsljit_verbose_fparam(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tcompiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_CMP_F64);\n\tCHECK_ARGUMENT(!(op & SLJIT_SET_Z));\n\tCHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)\n\t\t|| (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL));\n\tFUNCTION_FCHECK(src1, src1w, op & SLJIT_32);\n\tFUNCTION_FCHECK(src2, src2w, op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s\", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? \".f32\" : \".f64\");\n\t\tif (op & VARIABLE_FLAG_MASK) {\n\t\t\tfprintf(compiler->verbose, \".%s\", jump_names[GET_FLAG_TYPE(op)]);\n\t\t}\n\t\tfprintf(compiler->verbose, \" \");\n\t\tsljit_verbose_fparam(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\tFUNCTION_FCHECK(src, srcw, op & SLJIT_32);\n\tFUNCTION_CHECK_DST(dst, dstw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s.from%s \", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],\n\t\t\tfop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64],\n\t\t\t(op & SLJIT_32) ? \".f32\" : \".f64\");\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\tFUNCTION_CHECK_SRC(src, srcw);\n\tFUNCTION_FCHECK(dst, dstw, op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s.from.%s \", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],\n\t\t\t(op & SLJIT_32) ? \".f32\" : \".f64\",\n\t\t\tfop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64]);\n\t\tsljit_verbose_fparam(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_F64);\n\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\tFUNCTION_FCHECK(src1, src1w, op & SLJIT_32);\n\tFUNCTION_FCHECK(src2, src2w, op & SLJIT_32);\n\tFUNCTION_FCHECK(dst, dstw, op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s \", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? \".f32\" : \".f64\");\n\t\tsljit_verbose_fparam(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_COPYSIGN_F64);\n\tFUNCTION_FCHECK(src1, src1w, op & SLJIT_32);\n\tFUNCTION_FCHECK(src2, src2w, op & SLJIT_32);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s \", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? \".f32\" : \".f64\");\n\t\tsljit_verbose_freg(compiler, dst_freg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tSLJIT_UNUSED_ARG(value);\n\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  fset32 \");\n\t\tsljit_verbose_freg(compiler, freg);\n\t\tfprintf(compiler->verbose, \", %f\\n\", value);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tSLJIT_UNUSED_ARG(value);\n\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  fset64 \");\n\t\tsljit_verbose_freg(compiler, freg);\n\t\tfprintf(compiler->verbose, \", %f\\n\", value);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_COPY_TO_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_COPY_FROM_F64);\n\tCHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32));\n\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));\n#else /* !SLJIT_64BIT_ARCHITECTURE */\n\tswitch (op) {\n\tcase SLJIT_COPY32_TO_F32:\n\tcase SLJIT_COPY32_FROM_F32:\n\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));\n\t\tbreak;\n\tcase SLJIT_COPY_TO_F64:\n\tcase SLJIT_COPY_FROM_F64:\n\t\tif (reg & REG_PAIR_MASK) {\n\t\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));\n\t\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));\n\n\t\t\tif (op == SLJIT_COPY_TO_F64)\n\t\t\t\tbreak;\n\n\t\t\tCHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));\n\t\t\tbreak;\n\t\t}\n\n\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));\n\t\tbreak;\n\t}\n#endif /* SLJIT_64BIT_ARCHITECTURE */\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  copy%s_%s_f%s \", (op & SLJIT_32) ? \"32\" : \"\",\n\t\t\tGET_OPCODE(op) == SLJIT_COPY_TO_F64 ? \"to\" : \"from\", (op & SLJIT_32) ? \"32\" : \"64\");\n\n\t\tsljit_verbose_freg(compiler, freg);\n\n\t\tif (reg & REG_PAIR_MASK) {\n\t\t\tfprintf(compiler->verbose, \", {\");\n\t\t\tsljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));\n\t\t\tfprintf(compiler->verbose, \", \");\n\t\t\tsljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));\n\t\t\tfprintf(compiler->verbose, \"}\\n\");\n\t\t} else {\n\t\t\tfprintf(compiler->verbose, \", \");\n\t\t\tsljit_verbose_reg(compiler, reg);\n\t\t\tfprintf(compiler->verbose, \"\\n\");\n\t\t}\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tSLJIT_UNUSED_ARG(compiler);\n\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose))\n\t\tfprintf(compiler->verbose, \"label:\\n\");\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(buffers);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(alignment >= SLJIT_LABEL_ALIGN_1 && alignment <= SLJIT_LABEL_ALIGN_16);\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"label.al%d:%s\", 1 << alignment, buffers == NULL ? \"\\n\" : \" [\");\n\n\t\tif (buffers != NULL) {\n\t\t\tfprintf(compiler->verbose, \"%ld\", (long int)buffers->size);\n\t\t\tbuffers = buffers->next;\n\n\t\t\twhile (buffers != NULL) {\n\t\t\t\tfprintf(compiler->verbose, \", %ld\", (long int)buffers->size);\n\t\t\t\tbuffers = buffers->next;\n\t\t\t}\n\n\t\t\tfprintf(compiler->verbose, \"]\\n\");\n\t\t}\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t|| (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)\n#define CHECK_UNORDERED(type, last_flags) \\\n\t((((type) & 0xfe) == SLJIT_ORDERED) && \\\n\t\t((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL)\n#else /* !SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */\n#define CHECK_UNORDERED(type, last_flags) 0\n#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);\n\n\tif ((type & 0xff) < SLJIT_JUMP) {\n\t\tif ((type & 0xff) <= SLJIT_NOT_ZERO)\n\t\t\tCHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);\n\t\telse if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {\n\t\t\tCHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);\n\t\t\tcompiler->last_flags = 0;\n\t\t} else\n\t\t\tCHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)\n\t\t\t\t|| CHECK_UNORDERED(type, compiler->last_flags));\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose))\n\t\tfprintf(compiler->verbose, \"  jump%s %s\\n\", !(type & SLJIT_REWRITABLE_JUMP) ? \"\" : \".r\",\n\t\t\tjump_names[type & 0xff]);\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);\n\tCHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tCHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);\n\n\t\tif (compiler->options & SLJIT_ENTER_REG_ARG) {\n\t\t\tCHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);\n\t\t} else {\n\t\t\tCHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);\n\t\t}\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s%s%s ret[%s\", jump_names[type & 0xff],\n\t\t\t!(type & SLJIT_REWRITABLE_JUMP) ? \"\" : \".r\",\n\t\t\t!(type & SLJIT_CALL_RETURN) ? \"\" : \".ret\",\n\t\t\tcall_arg_names[arg_types & SLJIT_ARG_MASK]);\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\tif (arg_types) {\n\t\t\tfprintf(compiler->verbose, \"], args[\");\n\t\t\tdo {\n\t\t\t\tfprintf(compiler->verbose, \"%s\", call_arg_names[arg_types & SLJIT_ARG_MASK]);\n\t\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t\t\tif (arg_types)\n\t\t\t\t\tfprintf(compiler->verbose, \",\");\n\t\t\t} while (arg_types);\n\t\t}\n\t\tfprintf(compiler->verbose, \"]\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tFUNCTION_CHECK_SRC(src2, src2w);\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  cmp%s%s %s, \", (type & SLJIT_32) ? \"32\" : \"\",\n\t\t\t!(type & SLJIT_REWRITABLE_JUMP) ? \"\" : \".r\", jump_names[type & 0xff]);\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL);\n\tFUNCTION_FCHECK(src1, src1w, type & SLJIT_32);\n\tFUNCTION_FCHECK(src2, src2w, type & SLJIT_32);\n\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  fcmp%s%s %s, \", (type & SLJIT_32) ? \".f32\" : \".f64\",\n\t\t\t!(type & SLJIT_REWRITABLE_JUMP) ? \"\" : \".r\", jump_names[type & 0xff]);\n\t\tsljit_verbose_fparam(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tSLJIT_COMPILE_ASSERT((SLJIT_JUMP_IF_ZERO == SLJIT_SET_Z) && (SLJIT_JUMP_IF_NON_ZERO == 0),\n\t\tincorrect_values_for_sljit_jump_zero_or_non_zero);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_REWRITABLE_JUMP) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, SLJIT_REWRITABLE_JUMP) <= SLJIT_ROTR);\n\t/* Not all opcodes allow setting zero flags. */\n\tCHECK_ARGUMENT(check_sljit_emit_op2_operation(compiler, ((op | SLJIT_SET_Z) & ~SLJIT_REWRITABLE_JUMP)));\n\tFUNCTION_CHECK_DST(dst, dstw);\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tFUNCTION_CHECK_SRC(src2, src2w);\n\tcompiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  cmp%sz.%s%s%s%s%s \", (op & SLJIT_JUMP_IF_ZERO) ? \"\" : \"n\",\n\t\t\top2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? \"\" : \"32\",\n\t\t\t!(op & VARIABLE_FLAG_MASK) ? \"\" : \".\", !(op & VARIABLE_FLAG_MASK) ? \"\" : jump_names[GET_FLAG_TYPE(op & ~SLJIT_REWRITABLE_JUMP)],\n\t\t\t!(op & SLJIT_REWRITABLE_JUMP) ? \"\" : \".r\");\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);\n\tFUNCTION_CHECK_SRC(src, srcw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  ijump.%s \", jump_names[type]);\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);\n\tCHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));\n\tFUNCTION_CHECK_SRC(src, srcw);\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tCHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);\n\n\t\tif (compiler->options & SLJIT_ENTER_REG_ARG) {\n\t\t\tCHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);\n\t\t} else {\n\t\t\tCHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);\n\t\t}\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  i%s%s ret[%s\", jump_names[type & 0xff],\n\t\t\t!(type & SLJIT_CALL_RETURN) ? \"\" : \".ret\",\n\t\t\tcall_arg_names[arg_types & SLJIT_ARG_MASK]);\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\tif (arg_types) {\n\t\t\tfprintf(compiler->verbose, \"], args[\");\n\t\t\tdo {\n\t\t\t\tfprintf(compiler->verbose, \"%s\", call_arg_names[arg_types & SLJIT_ARG_MASK]);\n\t\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t\t\tif (arg_types)\n\t\t\t\t\tfprintf(compiler->verbose, \",\");\n\t\t\t} while (arg_types);\n\t\t}\n\t\tfprintf(compiler->verbose, \"], \");\n\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);\n\tCHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32\n\t\t|| (SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_AND && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_XOR));\n\tCHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));\n\n\tif (type <= SLJIT_NOT_ZERO)\n\t\tCHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);\n\telse\n\t\tCHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)\n\t\t\t|| CHECK_UNORDERED(type, compiler->last_flags));\n\n\tFUNCTION_CHECK_DST(dst, dstw);\n\n\tif (GET_OPCODE(op) >= SLJIT_ADD)\n\t\tcompiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  flags.%s%s%s \",\n\t\t\tGET_OPCODE(op) < SLJIT_OP2_BASE ? \"mov\" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],\n\t\t\tGET_OPCODE(op) < SLJIT_OP2_BASE ? op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? \"32\" : \"\"),\n\t\t\t!(op & SLJIT_SET_Z) ? \"\" : \".z\");\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", %s\\n\", jump_names[type]);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tsljit_s32 cond = type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\tCHECK_ARGUMENT((type & SLJIT_COMPARE_SELECT) ? (cond >= SLJIT_LESS && cond <= SLJIT_SET_SIG_LESS_EQUAL)\n\t\t\t\t: (cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL));\n\tCHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));\n\tFUNCTION_CHECK_SRC(src1, src1w);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));\n\n\tif (!(type & SLJIT_COMPARE_SELECT)) {\n\t\tif (cond <= SLJIT_NOT_ZERO)\n\t\t\tCHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);\n\t\telse if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {\n\t\t\tCHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);\n\t\t\tcompiler->last_flags = 0;\n\t\t} else\n\t\t\tCHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)\n\t\t\t\t|| CHECK_UNORDERED(cond, compiler->last_flags));\n\t} else\n\t\tcompiler->last_flags = 0;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %sselect%s %s, \",\n\t\t\t!(type & SLJIT_COMPARE_SELECT) ? \"\" : \"cmp_\",\n\t\t\t!(type & SLJIT_32) ? \"\" : \"32\",\n\t\t\tjump_names[type & ~SLJIT_32]);\n\t\tsljit_verbose_reg(compiler, dst_reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_reg(compiler, src2_reg);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tsljit_s32 cond = type & ~SLJIT_32;\n\n\tCHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);\n\n\tCHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, type & SLJIT_32));\n\tFUNCTION_FCHECK(src1, src1w, type & SLJIT_32);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, type & SLJIT_32));\n\n\tif (cond <= SLJIT_NOT_ZERO)\n\t\tCHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);\n\telse if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {\n\t\tCHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);\n\t\tcompiler->last_flags = 0;\n\t} else\n\t\tCHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)\n\t\t\t|| CHECK_UNORDERED(cond, compiler->last_flags));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  fselect%s %s, \",\n\t\t\t!(type & SLJIT_32) ? \"\" : \"32\",\n\t\t\tjump_names[type & ~SLJIT_32]);\n\t\tsljit_verbose_freg(compiler, dst_freg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_fparam(compiler, src1, src1w);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_freg(compiler, src2_freg);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tsljit_s32 allowed_flags;\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tif (type & SLJIT_MEM_UNALIGNED) {\n\t\tCHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));\n\t} else if (type & SLJIT_MEM_ALIGNED_16) {\n\t\tCHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));\n\t} else {\n\t\tCHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_ALIGNED_32));\n\t}\n\n\tallowed_flags = SLJIT_MEM_UNALIGNED;\n\n\tswitch (type & 0xff) {\n\tcase SLJIT_MOV_P:\n\tcase SLJIT_MOV:\n\t\tallowed_flags |= SLJIT_MEM_ALIGNED_32;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\tallowed_flags |= SLJIT_MEM_ALIGNED_16;\n\t\tbreak;\n\t}\n\n\tCHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | allowed_flags)) == 0);\n\n\tif (reg & REG_PAIR_MASK) {\n\t\tCHECK_ARGUMENT((type & 0xff) == SLJIT_MOV);\n\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));\n\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));\n\t\tCHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));\n\t} else {\n\t\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);\n\t\tCHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) >= SLJIT_MOV_U8 && (type & 0xff) <= SLJIT_MOV_S16));\n\t\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));\n\t}\n\n\tFUNCTION_CHECK_SRC_MEM(mem, memw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif ((type & 0xff) == SLJIT_MOV32)\n\t\t\tfprintf(compiler->verbose, \"  %s32\",\n\t\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\");\n\t\telse\n\t\t\tfprintf(compiler->verbose, \"  %s%s%s\",\n\t\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\",\n\t\t\t\t!(type & SLJIT_32) ? \"\" : \"32\", op1_types[(type & 0xff) - SLJIT_OP1_BASE]);\n\n\t\tif (type & SLJIT_MEM_UNALIGNED)\n\t\t\tfprintf(compiler->verbose, \".unal\");\n\t\telse if (type & SLJIT_MEM_ALIGNED_16)\n\t\t\tfprintf(compiler->verbose, \".al16\");\n\t\telse if (type & SLJIT_MEM_ALIGNED_32)\n\t\t\tfprintf(compiler->verbose, \".al32\");\n\n\t\tif (reg & REG_PAIR_MASK) {\n\t\t\tfprintf(compiler->verbose, \" {\");\n\t\t\tsljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));\n\t\t\tfprintf(compiler->verbose, \", \");\n\t\t\tsljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));\n\t\t\tfprintf(compiler->verbose, \"}, \");\n\t\t} else {\n\t\t\tfprintf(compiler->verbose, \" \");\n\t\t\tsljit_verbose_reg(compiler, reg);\n\t\t\tfprintf(compiler->verbose, \", \");\n\t\t}\n\t\tsljit_verbose_param(compiler, mem, memw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tif (SLJIT_UNLIKELY(compiler->skip_checks)) {\n\t\tcompiler->skip_checks = 0;\n\t\tCHECK_RETURN_OK;\n\t}\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);\n\tCHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);\n\tCHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);\n\n\tFUNCTION_CHECK_SRC_MEM(mem, memw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_MEM_SUPP)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_mem_update(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # mem: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tif ((type & 0xff) == SLJIT_MOV32)\n\t\t\tfprintf(compiler->verbose, \"  %s32.%s \",\n\t\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\",\n\t\t\t\t(type & SLJIT_MEM_POST) ? \"post\" : \"pre\");\n\t\telse\n\t\t\tfprintf(compiler->verbose, \"  %s%s%s.%s \",\n\t\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\",\n\t\t\t\t!(type & SLJIT_32) ? \"\" : \"32\",\n\t\t\t\top1_types[(type & 0xff) - SLJIT_OP1_BASE],\n\t\t\t\t(type & SLJIT_MEM_POST) ? \"post\" : \"pre\");\n\n\t\tsljit_verbose_reg(compiler, reg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, mem, memw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);\n\n\tif (type & SLJIT_MEM_UNALIGNED) {\n\t\tCHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));\n\t} else if (type & SLJIT_MEM_ALIGNED_16) {\n\t\tCHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));\n\t} else {\n\t\tCHECK_ARGUMENT(type & SLJIT_MEM_ALIGNED_32);\n\t\tCHECK_ARGUMENT(!(type & SLJIT_32));\n\t}\n\n\tCHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));\n\tFUNCTION_CHECK_SRC_MEM(mem, memw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s.%s\",\n\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\",\n\t\t\t!(type & SLJIT_32) ? \"f64\" : \"f32\");\n\n\t\tif (type & SLJIT_MEM_UNALIGNED)\n\t\t\tprintf(\".unal\");\n\t\telse if (type & SLJIT_MEM_ALIGNED_16)\n\t\t\tprintf(\".al16\");\n\t\telse if (type & SLJIT_MEM_ALIGNED_32)\n\t\t\tprintf(\".al32\");\n\n\t\tfprintf(compiler->verbose, \" \");\n\t\tsljit_verbose_freg(compiler, freg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, mem, memw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));\n\tCHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);\n\tCHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);\n\tFUNCTION_CHECK_SRC_MEM(mem, memw);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_MEM_SUPP)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_fmem_update(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # fmem: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  %s.%s.%s \",\n\t\t\t(type & SLJIT_MEM_STORE) ? \"store\" : \"load\",\n\t\t\t!(type & SLJIT_32) ? \"f64\" : \"f32\",\n\t\t\t(type & SLJIT_MEM_POST) ? \"post\" : \"pre\");\n\n\t\tsljit_verbose_freg(compiler, freg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, mem, memw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_STORE)) == 0);\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\tFUNCTION_VCHECK(srcdst, srcdstw, type);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, vreg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_mem: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_%s.%d.%s%d\",\n\t\t\t(type & SLJIT_SIMD_STORE) ? \"store\" : \"load\",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tif ((type & 0x3f000000) == SLJIT_SIMD_MEM_UNALIGNED)\n\t\t\tfprintf(compiler->verbose, \".unal \");\n\t\telse\n\t\t\tfprintf(compiler->verbose, \".al%d \", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_vparam(compiler, srcdst, srcdstw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM) {\n\t\t\tCHECK_ARGUMENT(srcw == 0);\n\t\t} else {\n\t\t\tFUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);\n\t\t}\n\t} else if (src != SLJIT_IMM) {\n\t\tFUNCTION_CHECK_DST(src, srcw);\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_dup: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_replicate.%d.%s%d \",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tif (type & SLJIT_SIMD_FLOAT)\n\t\t\tsljit_verbose_fparam(compiler, src, srcw);\n\t\telse\n\t\t\tsljit_verbose_param(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO | SLJIT_SIMD_LANE_SIGNED | SLJIT_32)) == 0);\n\tCHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)) != (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO));\n\tCHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_SIGNED)) != SLJIT_SIMD_LANE_SIGNED);\n\tCHECK_ARGUMENT(!(type & SLJIT_SIMD_FLOAT) || !(type & (SLJIT_SIMD_LANE_SIGNED | SLJIT_32)));\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\tCHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tFUNCTION_FCHECK(srcdst, srcdstw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);\n\t} else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) {\n\t\tFUNCTION_CHECK_DST(srcdst, srcdstw);\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, vreg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_move_lane: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_%s_lane%s%s%s.%d.%s%d \",\n\t\t\t(type & SLJIT_SIMD_STORE) ? \"store\" : \"load\",\n\t\t\t(type & SLJIT_32) ? \"32\" : \"\",\n\t\t\t(type & SLJIT_SIMD_LANE_ZERO) ? \"_z\" : \"\",\n\t\t\t(type & SLJIT_SIMD_LANE_SIGNED) ? \"_s\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \"[%d], \", lane_index);\n\t\tif (type & SLJIT_SIMD_FLOAT)\n\t\t\tsljit_verbose_fparam(compiler, srcdst, srcdstw);\n\t\telse\n\t\t\tsljit_verbose_param(compiler, srcdst, srcdstw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src, type));\n\tCHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_lane_replicate: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_lane_replicate.%d.%s%d \",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_vreg(compiler, src);\n\t\tfprintf(compiler->verbose, \"[%d]\\n\", src_lane_index);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_EXTEND_SIGNED)) == 0);\n\tCHECK_ARGUMENT((type & (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)) != (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT));\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\tFUNCTION_VCHECK(src, srcw, type);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_extend: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_load_extend%s.%d.%s%d.%s%d \",\n\t\t\t(type & SLJIT_SIMD_EXTEND_SIGNED) ? \"_s\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_vparam(compiler, src, srcw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE);\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));\n\tFUNCTION_CHECK_DST(dst, dstw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, vreg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_sign: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_store_sign%s.%d.%s%d \",\n\t\t\t(type & SLJIT_32) ? \"32\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tsljit_verbose_vreg(compiler, vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));\n\tCHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK2(0)) <= SLJIT_SIMD_OP2_SHUFFLE);\n\tCHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE || (SLJIT_SIMD_GET_ELEM_SIZE(type) == 0 && !(type & SLJIT_SIMD_FLOAT)));\n\tCHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (src2 & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(dst_vreg, type));\n\tCHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src1_vreg, type));\n\tFUNCTION_VCHECK(src2, src2w, type);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\tCHECK_RETURN_OK;\n\t\tif (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_vreg, src1_vreg, src2, src2w) == SLJIT_ERR_UNSUPPORTED) {\n\t\t\tfprintf(compiler->verbose, \"    # simd_op2: unsupported form, no instructions are emitted\\n\");\n\t\t\tCHECK_RETURN_OK;\n\t\t}\n\n\t\tfprintf(compiler->verbose, \"  simd_%s.%d.%s%d\",\n\t\t\tsimd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1],\n\t\t\t(8 << SLJIT_SIMD_GET_REG_SIZE(type)),\n\t\t\t(type & SLJIT_SIMD_FLOAT) ? \"f\" : \"\",\n\t\t\t(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));\n\n\t\tif ((type & 0x3f000000) != SLJIT_SIMD_MEM_UNALIGNED)\n\t\t\tfprintf(compiler->verbose, \".al%d\", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)));\n\n\t\tfprintf(compiler->verbose, \" \");\n\t\tsljit_verbose_vreg(compiler, dst_vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_vreg(compiler, src1_vreg);\n\t\tfprintf(compiler->verbose, \", \");\n\t\tsljit_verbose_vparam(compiler, src2, src2w);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)\n{\n\t/* Any offset is allowed. */\n\tSLJIT_UNUSED_ARG(offset);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tFUNCTION_CHECK_DST(dst, dstw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  local_base \");\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", #%\" SLJIT_PRINT_D \"d\\n\", offset);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tSLJIT_UNUSED_ARG(init_value);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV_S32\n\t\t|| op == SLJIT_MOV32 || (op | SLJIT_32) == SLJIT_MOV32_U8);\n\tFUNCTION_CHECK_DST(dst, dstw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  const%s%s \",\n\t\t\t!(op & SLJIT_32) ? \"\" : \"32\", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \", #%\" SLJIT_PRINT_D \"d\\n\", init_value);\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\nstatic SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\tCHECK_ARGUMENT(op == SLJIT_MOV_ADDR || op == SLJIT_MOV_ABS_ADDR || op == SLJIT_ADD_ABS_ADDR);\n\tFUNCTION_CHECK_DST(dst, dstw);\n#endif /* SLJIT_ARGUMENT_CHECKS */\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tif (SLJIT_UNLIKELY(!!compiler->verbose)) {\n\t\tfprintf(compiler->verbose, \"  %s \", op_addr_types[op]);\n\t\tsljit_verbose_param(compiler, dst, dstw);\n\t\tfprintf(compiler->verbose, \"\\n\");\n\t}\n#endif /* SLJIT_VERBOSE */\n\tCHECK_RETURN_OK;\n}\n\n#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_VERBOSE */\n\n#define SLJIT_SKIP_CHECKS(compiler)\n\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */\n\n#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \\\n\tSLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1) && !(SLJIT_CONV_F64_FROM_UW & 0x1), \\\n\t\tinvalid_float_opcodes); \\\n\tif (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \\\n\t\tif (GET_OPCODE(op) == SLJIT_CMP_F64) { \\\n\t\t\tCHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \\\n\t\t\tADJUST_LOCAL_OFFSET(dst, dstw); \\\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw); \\\n\t\t\treturn sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \\\n\t\t} \\\n\t\tif ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \\\n\t\t\tCHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \\\n\t\t\tADJUST_LOCAL_OFFSET(dst, dstw); \\\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw); \\\n\t\t\treturn sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \\\n\t\t} \\\n\t\tif ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_F64_FROM_S32) { \\\n\t\t\tCHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \\\n\t\t\tADJUST_LOCAL_OFFSET(dst, dstw); \\\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw); \\\n\t\t\treturn sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \\\n\t\t} \\\n\t\tCHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \\\n\t\tADJUST_LOCAL_OFFSET(dst, dstw); \\\n\t\tADJUST_LOCAL_OFFSET(src, srcw); \\\n\t\treturn sljit_emit_fop1_conv_f64_from_uw(compiler, op, dst, dstw, src, srcw); \\\n\t} \\\n\tCHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \\\n\tADJUST_LOCAL_OFFSET(dst, dstw); \\\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6))\n\nstatic sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (type & SLJIT_MEM_STORE)\n\t\treturn sljit_emit_op1(compiler, type & (0xff | SLJIT_32), mem, memw, reg, 0);\n\treturn sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw);\n}\n\n#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) */\n\n#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \\\n\t&& !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)\n\nstatic sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (type & SLJIT_MEM_STORE)\n\t\treturn sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), mem, memw, freg, 0);\n\treturn sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), freg, 0, mem, memw);\n}\n\n#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */\n\nstatic void sljit_reset_read_only_buffers(struct sljit_read_only_buffer *buffers)\n{\n\twhile (buffers != NULL) {\n\t\tbuffers->u.label = NULL;\n\t\tbuffers = buffers->next;\n\t}\n}\n\n/* CPU description section */\n\n#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)\n#define SLJIT_CPUINFO_PART1 \" 32bit (\"\n#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n#define SLJIT_CPUINFO_PART1 \" 64bit (\"\n#else /* !SLJIT_32BIT_ARCHITECTURE && !SLJIT_64BIT_ARCHITECTURE */\n#error \"Internal error: CPU type info missing\"\n#endif /* SLJIT_32BIT_ARCHITECTURE */\n\n#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#define SLJIT_CPUINFO_PART2 \"little endian + \"\n#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)\n#define SLJIT_CPUINFO_PART2 \"big endian + \"\n#else /* !SLJIT_LITTLE_ENDIAN && !SLJIT_BIG_ENDIAN */\n#error \"Internal error: CPU type info missing\"\n#endif /* SLJIT_LITTLE_ENDIAN */\n\n#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)\n#define SLJIT_CPUINFO_PART3 \"unaligned)\"\n#else /* !SLJIT_UNALIGNED */\n#define SLJIT_CPUINFO_PART3 \"aligned)\"\n#endif /* SLJIT_UNALIGNED */\n\n#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n#\tinclude \"sljitNativeX86_common.c\"\n#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n#\tinclude \"sljitNativeARM_32.c\"\n#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n#\tinclude \"sljitNativeARM_32.c\"\n#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)\n#\tinclude \"sljitNativeARM_T2_32.c\"\n#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n#\tinclude \"sljitNativeARM_64.c\"\n#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n#\tinclude \"sljitNativePPC_common.c\"\n#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n#\tinclude \"sljitNativeMIPS_common.c\"\n#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n#\tinclude \"sljitNativeRISCV_common.c\"\n#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n#\tinclude \"sljitNativeS390X.c\"\n#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n#\tinclude \"sljitNativeLOONGARCH_64.c\"\n#endif /* SLJIT_CONFIG_X86 */\n\n#include \"sljitSerialize.c\"\n\nstatic SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)\n\t/* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */\n\tif (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))\n\t\treturn SLJIT_SUCCESS;\n#else /* !SLJIT_64BIT_ARCHITECTURE */\n\tif (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))\n\t\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_64BIT_ARCHITECTURE */\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);\n}\n\n#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \\\n\t&& !((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && defined __SOFTFP__)\n\nstatic SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n\tif (src == SLJIT_FR0)\n\t\treturn SLJIT_SUCCESS;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);\n}\n\n#endif /* !SLJIT_CONFIG_X86_32 && !(SLJIT_CONFIG_ARM_32 && __SOFTFP__) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return(compiler, op, src, srcw));\n\n\tif (GET_OPCODE(op) < SLJIT_MOV_F64) {\n\t\tFAIL_IF(emit_mov_before_return(compiler, op, src, srcw));\n\t} else {\n\t\tFAIL_IF(emit_fmov_before_return(compiler, op, src, srcw));\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_return_void(compiler);\n}\n\n#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t&& !(defined(SLJIT_CONFIG_LOONGARCH_64) && SLJIT_CONFIG_LOONGARCH_64)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_fop2(compiler, op, dst_freg, 0, src1, src1w, src2, src2w);\n}\n\n#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH_64 */\n\n#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \\\n\t&& !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t&& !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* Default compare for most architectures. */\n\tsljit_s32 flags, tmp_src, condition;\n\tsljit_sw tmp_srcw;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));\n\n\tcondition = type & 0xff;\n#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n\tif ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {\n\t\tif (src1 == SLJIT_IMM && !src1w) {\n\t\t\tsrc1 = src2;\n\t\t\tsrc1w = src2w;\n\t\t\tsrc2 = SLJIT_IMM;\n\t\t\tsrc2w = 0;\n\t\t}\n\t\tif (src2 == SLJIT_IMM && !src2w)\n\t\t\treturn emit_cmp_to0(compiler, type, src1, src1w);\n\t}\n#endif /* SLJIT_CONFIG_ARM_64 */\n\n\tif (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) {\n\t\t/* Immediate is preferred as second argument by most architectures. */\n\t\tswitch (condition) {\n\t\tcase SLJIT_LESS:\n\t\t\tcondition = SLJIT_GREATER;\n\t\t\tbreak;\n\t\tcase SLJIT_GREATER_EQUAL:\n\t\t\tcondition = SLJIT_LESS_EQUAL;\n\t\t\tbreak;\n\t\tcase SLJIT_GREATER:\n\t\t\tcondition = SLJIT_LESS;\n\t\t\tbreak;\n\t\tcase SLJIT_LESS_EQUAL:\n\t\t\tcondition = SLJIT_GREATER_EQUAL;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_LESS:\n\t\t\tcondition = SLJIT_SIG_GREATER;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\t\tcondition = SLJIT_SIG_LESS_EQUAL;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_GREATER:\n\t\t\tcondition = SLJIT_SIG_LESS;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\tcondition = SLJIT_SIG_GREATER_EQUAL;\n\t\t\tbreak;\n\t\t}\n\n\t\ttype = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));\n\t\ttmp_src = src1;\n\t\tsrc1 = src2;\n\t\tsrc2 = tmp_src;\n\t\ttmp_srcw = src1w;\n\t\tsrc1w = src2w;\n\t\tsrc2w = tmp_srcw;\n\t}\n\n\tif (condition <= SLJIT_NOT_ZERO)\n\t\tflags = SLJIT_SET_Z;\n\telse\n\t\tflags = (condition & 0xfe) << VARIABLE_FLAG_SHIFT;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tPTR_FAIL_IF(sljit_emit_op2u(compiler,\n\t\tSLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));\n}\n\n#endif /* !SLJIT_CONFIG_MIPS */\n\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n#endif /* SLJIT_CONFIG_ARM */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tsljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xfe) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\n#if !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t&& !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \\\n\t&& !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op2cmpz(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tPTR_FAIL_IF(sljit_emit_op2(compiler, ((op | SLJIT_SET_Z) & ~SLJIT_REWRITABLE_JUMP), dst, dstw, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, ((op & SLJIT_JUMP_IF_ZERO) ? SLJIT_ZERO : SLJIT_NOT_ZERO) | (op & SLJIT_REWRITABLE_JUMP));\n}\n\n#else /* SLJIT_CONFIG_RISCV || SLJIT_CONFIG_MIPS || SLJIT_CONFIG_LOONGARCH */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op2cmpz(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tPTR_FAIL_IF(sljit_emit_op2(compiler, (op & ~(SLJIT_SET_Z | SLJIT_REWRITABLE_JUMP)), dst, dstw, src1, src1w, src2, src2w));\n\n\t/* When dst is a memory operand, its value is stored in SLJIT_TMP_DEST_FREG. */\n\treg = FAST_IS_REG(dst) ? dst : SLJIT_TMP_DEST_REG;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_cmp(compiler, ((op & SLJIT_JUMP_IF_ZERO) ? SLJIT_ZERO : SLJIT_NOT_ZERO) | (op & (SLJIT_32 | SLJIT_REWRITABLE_JUMP)), reg, 0, SLJIT_IMM, 0);\n}\n\n#endif /* !SLJIT_CONFIG_RISCV && !SLJIT_CONFIG_MIPS && !SLJIT_CONFIG_LOONGARCH */\n\n#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \\\n\t&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(reg);\n\tSLJIT_UNUSED_ARG(mem);\n\tSLJIT_UNUSED_ARG(memw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\n#endif /* !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_PPC */\n\n#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \\\n\t&& !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));\n\n\treturn sljit_emit_fmem_unaligned(compiler, type, freg, mem, memw);\n}\n\n#endif /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS */\n\n#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n\t&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(freg);\n\tSLJIT_UNUSED_ARG(mem);\n\tSLJIT_UNUSED_ARG(memw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\n#endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */\n\n#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t&& !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \\\n\t&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n\t&& !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \\\n\t&& !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(srcdst);\n\tSLJIT_UNUSED_ARG(srcdstw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(src);\n\tSLJIT_UNUSED_ARG(srcw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(lane_index);\n\tSLJIT_UNUSED_ARG(srcdst);\n\tSLJIT_UNUSED_ARG(srcdstw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(src);\n\tSLJIT_UNUSED_ARG(src_lane_index);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(src);\n\tSLJIT_UNUSED_ARG(srcw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(vreg);\n\tSLJIT_UNUSED_ARG(dst);\n\tSLJIT_UNUSED_ARG(dstw);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(type);\n\tSLJIT_UNUSED_ARG(dst_vreg);\n\tSLJIT_UNUSED_ARG(src1_vreg);\n\tSLJIT_UNUSED_ARG(src2);\n\tSLJIT_UNUSED_ARG(src2w);\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\n#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH */\n\n#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n\t&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));\n\n\tADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (offset != 0)\n\t\treturn sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);\n\treturn sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);\n}\n\n#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_read_only_buffer_start_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset)\n{\n\tSLJIT_UNUSED_ARG(size);\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + size), 0);\n\treturn SLJIT_ADD_EXEC_OFFSET(addr, -executable_offset);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_read_only_buffer_end_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset)\n{\n\tSLJIT_UNUSED_ARG(addr);\n\tSLJIT_UNUSED_ARG(size);\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + size), 1);\n\tSLJIT_CACHE_FLUSH((void*)addr, (void*)(addr + size));\n}\n\n#endif /* !SLJIT_CONFIG_UNSUPPORTED */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitLir.h",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef SLJIT_LIR_H_\n#define SLJIT_LIR_H_\n\n/*\n   ------------------------------------------------------------------------\n    Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)\n   ------------------------------------------------------------------------\n\n   Short description\n    Advantages:\n      - The execution can be continued from any LIR instruction. In other\n        words, it is possible to jump to any label from anywhere, even from\n        a code fragment, which is compiled later, as long as the compiling\n        context is the same. See sljit_emit_enter for more details.\n      - Supports self modifying code: target of any jump and call\n        instructions and some constant values can be dynamically modified\n        during runtime. See SLJIT_REWRITABLE_JUMP.\n        - although it is not suggested to do it frequently\n        - can be used for inline caching: save an important value once\n          in the instruction stream\n      - A fixed stack space can be allocated for local variables\n      - The compiler is thread-safe\n      - The compiler is highly configurable through preprocessor macros.\n        You can disable unneeded features (multithreading in single\n        threaded applications), and you can use your own system functions\n        (including memory allocators). See sljitConfig.h.\n    Disadvantages:\n      - The compiler is more like a platform independent assembler, so\n        there is no built-in variable management. Registers and stack must\n        be managed manually (the name of the compiler refers to this).\n    In practice:\n      - This approach is very effective for interpreters\n        - One of the saved registers typically points to a stack interface\n        - It can jump to any exception handler anytime (even if it belongs\n          to another function)\n        - Hot paths can be modified during runtime reflecting the changes\n          of the fastest execution path of the dynamic language\n        - SLJIT supports complex memory addressing modes\n        - mainly position and context independent code (except some cases)\n\n    For valgrind users:\n      - pass --smc-check=all argument to valgrind, since JIT is a \"self-modifying code\"\n*/\n\n#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)\n#include \"sljitConfigPre.h\"\n#endif /* SLJIT_HAVE_CONFIG_PRE */\n\n#include \"sljitConfigCPU.h\"\n#include \"sljitConfig.h\"\n\n/* The following header file defines useful macros for fine tuning\nSLJIT based code generators. They are listed in the beginning\nof sljitConfigInternal.h */\n\n#include \"sljitConfigInternal.h\"\n\n#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)\n#include \"sljitConfigPost.h\"\n#endif /* SLJIT_HAVE_CONFIG_POST */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Version numbers. */\n#define SLJIT_MAJOR_VERSION\t0\n#define SLJIT_MINOR_VERSION\t95\n\n/* --------------------------------------------------------------------- */\n/*  Error codes                                                          */\n/* --------------------------------------------------------------------- */\n\n/* Indicates no error. */\n#define SLJIT_SUCCESS\t\t\t0\n/* After the call of sljit_generate_code(), the error code of the compiler\n   is set to this value to avoid further code generation.\n   The complier should be freed after sljit_generate_code(). */\n#define SLJIT_ERR_COMPILED\t\t1\n/* Cannot allocate non-executable memory. */\n#define SLJIT_ERR_ALLOC_FAILED\t\t2\n/* Cannot allocate executable memory.\n   Only sljit_generate_code() returns with this error code. */\n#define SLJIT_ERR_EX_ALLOC_FAILED\t3\n/* Unsupported instruction form. */\n#define SLJIT_ERR_UNSUPPORTED\t\t4\n/* An invalid argument is passed to any SLJIT function. */\n#define SLJIT_ERR_BAD_ARGUMENT\t\t5\n\n/* --------------------------------------------------------------------- */\n/*  Registers                                                            */\n/* --------------------------------------------------------------------- */\n\n/*\n  Scratch (R) registers: registers which may not preserve their values\n  across function calls.\n\n  Saved (S) registers: registers which preserve their values across\n  function calls.\n\n  The scratch and saved register sets overlap. The last scratch register\n  is the first saved register, the one before the last is the second saved\n  register, and so on.\n\n  For example, in an architecture with only five registers (A-E), if two\n  are scratch and three saved registers, they will be defined as follows:\n\n    A |   R0   |      |  R0 always represent scratch register A\n    B |   R1   |      |  R1 always represent scratch register B\n    C |  [R2]  |  S2  |  R2 and S2 represent the same physical register C\n    D |  [R3]  |  S1  |  R3 and S1 represent the same physical register D\n    E |  [R4]  |  S0  |  R4 and S0 represent the same physical register E\n\n  Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS will be 2 and\n        SLJIT_NUMBER_OF_SAVED_REGISTERS will be 3.\n\n  Note: For all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12\n        and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers\n        are virtual on x86-32. See below.\n\n  The purpose of this definition is convenience: saved registers can\n  be used as extra scratch registers. For example, building in the\n  previous example, four registers can be specified as scratch registers\n  and the fifth one as saved register, allowing any user code which requires\n  four scratch registers to run unmodified. The SLJIT compiler automatically\n  saves the content of the two extra scratch register on the stack. Scratch\n  registers can also be preserved by saving their value on the stack but\n  that needs to be done manually.\n\n  Note: To emphasize that registers assigned to R2-R4 are saved\n        registers, they are enclosed by square brackets.\n\n  Note: sljit_emit_enter and sljit_set_context define whether a register\n        is S or R register. E.g: if in the previous example 3 scratches and\n        1 saved are mapped by sljit_emit_enter, the allowed register set\n        will be: R0-R2 and S0. Although S2 is mapped to the same register\n        than R2, it is not available in that configuration. Furthermore\n        the S1 register cannot be used at all.\n*/\n\n/* Scratch registers. */\n#define SLJIT_R0\t1\n#define SLJIT_R1\t2\n#define SLJIT_R2\t3\n/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they\n   are allocated on the stack). These registers are called virtual\n   and cannot be used for memory addressing (cannot be part of\n   any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such\n   limitation on other CPUs. See sljit_get_register_index(). */\n#define SLJIT_R3\t4\n#define SLJIT_R4\t5\n#define SLJIT_R5\t6\n#define SLJIT_R6\t7\n#define SLJIT_R7\t8\n#define SLJIT_R8\t9\n#define SLJIT_R9\t10\n/* All R registers provided by the architecture can be accessed by SLJIT_R(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */\n#define SLJIT_R(i)\t(1 + (i))\n\n/* Saved registers. */\n#define SLJIT_S0\t(SLJIT_NUMBER_OF_REGISTERS)\n#define SLJIT_S1\t(SLJIT_NUMBER_OF_REGISTERS - 1)\n#define SLJIT_S2\t(SLJIT_NUMBER_OF_REGISTERS - 2)\n/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they\n   are allocated on the stack). These registers are called virtual\n   and cannot be used for memory addressing (cannot be part of\n   any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such\n   limitation on other CPUs. See sljit_get_register_index(). */\n#define SLJIT_S3\t(SLJIT_NUMBER_OF_REGISTERS - 3)\n#define SLJIT_S4\t(SLJIT_NUMBER_OF_REGISTERS - 4)\n#define SLJIT_S5\t(SLJIT_NUMBER_OF_REGISTERS - 5)\n#define SLJIT_S6\t(SLJIT_NUMBER_OF_REGISTERS - 6)\n#define SLJIT_S7\t(SLJIT_NUMBER_OF_REGISTERS - 7)\n#define SLJIT_S8\t(SLJIT_NUMBER_OF_REGISTERS - 8)\n#define SLJIT_S9\t(SLJIT_NUMBER_OF_REGISTERS - 9)\n/* All S registers provided by the architecture can be accessed by SLJIT_S(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */\n#define SLJIT_S(i)\t(SLJIT_NUMBER_OF_REGISTERS - (i))\n\n/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */\n#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)\n\n/* The SLJIT_SP provides direct access to the linear stack space allocated by\n   sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).\n   The immediate offset is extended by the relative stack offset automatically.\n   sljit_get_local_base can be used to obtain the real address of a value. */\n#define SLJIT_SP\t(SLJIT_NUMBER_OF_REGISTERS + 1)\n\n/* Return with machine word. */\n\n#define SLJIT_RETURN_REG\tSLJIT_R0\n\n/* --------------------------------------------------------------------- */\n/*  Floating point registers                                             */\n/* --------------------------------------------------------------------- */\n\n/* Each floating point register can store a 32 or a 64 bit precision\n   value. The FR and FS register sets overlap in the same way as R\n   and S register sets. See above. */\n\n/* Floating point scratch registers. */\n#define SLJIT_FR0\t1\n#define SLJIT_FR1\t2\n#define SLJIT_FR2\t3\n#define SLJIT_FR3\t4\n#define SLJIT_FR4\t5\n#define SLJIT_FR5\t6\n#define SLJIT_FR6\t7\n#define SLJIT_FR7\t8\n#define SLJIT_FR8\t9\n#define SLJIT_FR9\t10\n/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */\n#define SLJIT_FR(i)\t(1 + (i))\n\n/* Floating point saved registers. */\n#define SLJIT_FS0\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS)\n#define SLJIT_FS1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)\n#define SLJIT_FS2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)\n#define SLJIT_FS3\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)\n#define SLJIT_FS4\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)\n#define SLJIT_FS5\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)\n#define SLJIT_FS6\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 6)\n#define SLJIT_FS7\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7)\n#define SLJIT_FS8\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8)\n#define SLJIT_FS9\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9)\n/* All FS registers provided by the architecture can be accessed by SLJIT_FS(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */\n#define SLJIT_FS(i)\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))\n\n/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */\n#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)\n\n/* Return with floating point arg. */\n\n#define SLJIT_RETURN_FREG\tSLJIT_FR0\n\n/* --------------------------------------------------------------------- */\n/*  Vector registers                                                     */\n/* --------------------------------------------------------------------- */\n\n/* Vector registers are storage areas, which are used for Single Instruction\n   Multiple Data (SIMD) computations. The VR and VS register sets overlap\n   in the same way as R and S register sets. See above.\n\n   The storage space of vector registers often overlap with floating point\n   registers. In this case setting the value of SLJIT_VR(i) destroys the\n   value of SLJIT_FR(i) and vice versa. See SLJIT_SEPARATE_VECTOR_REGISTERS\n   macro. */\n\n/* Vector scratch registers. */\n#define SLJIT_VR0\t1\n#define SLJIT_VR1\t2\n#define SLJIT_VR2\t3\n#define SLJIT_VR3\t4\n#define SLJIT_VR4\t5\n#define SLJIT_VR5\t6\n#define SLJIT_VR6\t7\n#define SLJIT_VR7\t8\n#define SLJIT_VR8\t9\n#define SLJIT_VR9\t10\n/* All VR registers provided by the architecture can be accessed by SLJIT_VR(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_VECTOR_REGISTERS. */\n#define SLJIT_VR(i)\t(1 + (i))\n\n/* Vector saved registers. */\n#define SLJIT_VS0\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS)\n#define SLJIT_VS1\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 1)\n#define SLJIT_VS2\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 2)\n#define SLJIT_VS3\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 3)\n#define SLJIT_VS4\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 4)\n#define SLJIT_VS5\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 5)\n#define SLJIT_VS6\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 6)\n#define SLJIT_VS7\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 7)\n#define SLJIT_VS8\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 8)\n#define SLJIT_VS9\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - 9)\n/* All VS registers provided by the architecture can be accessed by SLJIT_VS(i)\n   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS. */\n#define SLJIT_VS(i)\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS - (i))\n\n/* Vector registers >= SLJIT_FIRST_SAVED_VECTOR_REG are saved registers. */\n#define SLJIT_FIRST_SAVED_VECTOR_REG (SLJIT_VS0 - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS + 1)\n\n/* --------------------------------------------------------------------- */\n/*  Argument type definitions                                            */\n/* --------------------------------------------------------------------- */\n\n/* The following argument type definitions are used by sljit_emit_enter,\n   sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.\n\n   For sljit_emit_call and sljit_emit_icall, the first integer argument\n   must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on.\n   Similarly the first floating point argument must be placed into SLJIT_FR0,\n   the second one into SLJIT_FR1, and so on.\n\n   For sljit_emit_enter, the integer arguments can be stored in scratch\n   or saved registers. Scratch registers are identified by a _R suffix.\n\n   If only saved registers are used, then the allocation mirrors what is\n   done for the \"call\" functions but using saved registers, meaning that\n   the first integer argument goes to SLJIT_S0, the second one goes into\n   SLJIT_S1, and so on.\n\n   If scratch registers are used, then the way the integer registers are\n   allocated changes so that SLJIT_S0, SLJIT_S1, etc; will be assigned\n   only for the arguments not using scratch registers, while SLJIT_R<n>\n   will be used for the ones using scratch registers.\n\n   Furthermore, the index (shown as \"n\" above) that will be used for the\n   scratch register depends on how many previous integer registers\n   (scratch or saved) were used already, starting with SLJIT_R0.\n   Eventhough some indexes will be likely skipped, they still need to be\n   accounted for in the scratches parameter of sljit_emit_enter. See below\n   for some examples.\n\n   The floating point arguments always use scratch registers (but not the\n   _R suffix like the integer arguments) and must use SLJIT_FR0, SLJIT_FR1,\n   just like in the \"call\" functions.\n\n   Note: the mapping for scratch registers is part of the compiler context\n         and therefore a new context after sljit_emit_call/sljit_emit_icall\n         could remove access to some scratch registers that were used as\n         arguments.\n\n   Example function definition:\n     sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a,\n         sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);\n\n   Argument type definition:\n     SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_F32)\n        | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_P, 1) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F64, 2)\n        | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4)\n\n   Short form of argument type definition:\n     SLJIT_ARGS4(F32, P, F64, 32, F32)\n\n   Argument passing:\n     arg_a must be placed in SLJIT_R0\n     arg_b must be placed in SLJIT_FR0\n     arg_c must be placed in SLJIT_R1\n     arg_d must be placed in SLJIT_FR1\n\n   Examples for argument processing by sljit_emit_enter:\n     SLJIT_ARGS4V(P, 32_R, F32, W)\n     Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_FR0, SLJIT_S1\n     The type of the result is void.\n\n     SLJIT_ARGS4(F32, W, W_R, W, W_R)\n     Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_S1, SLJIT_R3\n     The type of the result is sljit_f32.\n\n     SLJIT_ARGS4(P, W, F32, P_R)\n     Arguments are placed into: SLJIT_FR0, SLJIT_S0, SLJIT_FR1, SLJIT_R1\n     The type of the result is pointer.\n\n     Note: it is recommended to pass the scratch arguments first\n     followed by the saved arguments:\n\n       SLJIT_ARGS4(W, W_R, W_R, W, W)\n       Arguments are placed into: SLJIT_R0, SLJIT_R1, SLJIT_S0, SLJIT_S1\n       The type of the result is sljit_sw / sljit_uw.\n*/\n\n/* The following flag is only allowed for the integer arguments of\n   sljit_emit_enter. When the flag is set, the integer argument is\n   stored in a scratch register instead of a saved register. */\n#define SLJIT_ARG_TYPE_SCRATCH_REG 0x8\n\n/* No return value, only supported by SLJIT_ARG_RETURN. */\n#define SLJIT_ARG_TYPE_RET_VOID\t\t0\n/* Machine word sized integer argument or result. */\n#define SLJIT_ARG_TYPE_W\t\t1\n#define SLJIT_ARG_TYPE_W_R\t(SLJIT_ARG_TYPE_W | SLJIT_ARG_TYPE_SCRATCH_REG)\n/* 32 bit integer argument or result. */\n#define SLJIT_ARG_TYPE_32\t\t2\n#define SLJIT_ARG_TYPE_32_R\t(SLJIT_ARG_TYPE_32 | SLJIT_ARG_TYPE_SCRATCH_REG)\n/* Pointer sized integer argument or result. */\n#define SLJIT_ARG_TYPE_P\t\t3\n#define SLJIT_ARG_TYPE_P_R\t(SLJIT_ARG_TYPE_P | SLJIT_ARG_TYPE_SCRATCH_REG)\n/* 64 bit floating point argument or result. */\n#define SLJIT_ARG_TYPE_F64\t\t4\n/* 32 bit floating point argument or result. */\n#define SLJIT_ARG_TYPE_F32\t\t5\n\n#define SLJIT_ARG_SHIFT 4\n#define SLJIT_ARG_RETURN(type) (type)\n#define SLJIT_ARG_VALUE(type, idx) ((type) << ((idx) * SLJIT_ARG_SHIFT))\n\n/* Simplified argument list definitions.\n\n   The following definition:\n       SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_W) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 1)\n\n   can be shortened to:\n       SLJIT_ARGS1(W, F32)\n\n   Another example where no value is returned:\n       SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W_R, 1)\n\n   can be shortened to:\n       SLJIT_ARGS1V(W_R)\n*/\n\n#define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type\n\n#define SLJIT_ARGS0(ret) \\\n\tSLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret))\n#define SLJIT_ARGS0V() \\\n\tSLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID)\n\n#define SLJIT_ARGS1(ret, arg1) \\\n\t(SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))\n#define SLJIT_ARGS1V(arg1) \\\n\t(SLJIT_ARGS0V() | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))\n\n#define SLJIT_ARGS2(ret, arg1, arg2) \\\n\t(SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))\n#define SLJIT_ARGS2V(arg1, arg2) \\\n\t(SLJIT_ARGS1V(arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))\n\n#define SLJIT_ARGS3(ret, arg1, arg2, arg3) \\\n\t(SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))\n#define SLJIT_ARGS3V(arg1, arg2, arg3) \\\n\t(SLJIT_ARGS2V(arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))\n\n#define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \\\n\t(SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))\n#define SLJIT_ARGS4V(arg1, arg2, arg3, arg4) \\\n\t(SLJIT_ARGS3V(arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))\n\n/* --------------------------------------------------------------------- */\n/*  Main structures and functions                                        */\n/* --------------------------------------------------------------------- */\n\n/*\n\tThe following structures are private, and can be changed in the\n\tfuture. Keeping them here allows code inlining.\n*/\n\nstruct sljit_memory_fragment {\n\tstruct sljit_memory_fragment *next;\n\tsljit_uw used_size;\n\t/* Must be aligned to sljit_sw. */\n\tsljit_u8 memory[1];\n};\n\nstruct sljit_label {\n\tstruct sljit_label *next;\n\tunion {\n\t\tsljit_uw index;\n\t\tsljit_uw addr;\n\t} u;\n\t/* The maximum size difference. */\n\tsljit_uw size;\n};\n\nstruct sljit_jump {\n\tstruct sljit_jump *next;\n\tsljit_uw addr;\n\t/* Architecture dependent flags. */\n\tsljit_uw flags;\n\tunion {\n\t\tsljit_uw target;\n\t\tstruct sljit_label *label;\n\t} u;\n};\n\nstruct sljit_const {\n\tstruct sljit_const *next;\n\tsljit_uw addr;\n};\n\nstruct sljit_generate_code_buffer {\n\tvoid *buffer;\n\tsljit_uw size;\n\tsljit_sw executable_offset;\n};\n\nstruct sljit_read_only_buffer {\n\tstruct sljit_read_only_buffer *next;\n\tsljit_uw size;\n\t/* Label can be replaced by address after sljit_generate_code. */\n\tunion {\n\t\tstruct sljit_label *label;\n\t\tsljit_uw addr;\n\t} u;\n};\n\nstruct sljit_compiler {\n\tsljit_s32 error;\n\tsljit_s32 options;\n\n\tstruct sljit_label *labels;\n\tstruct sljit_jump *jumps;\n\tstruct sljit_const *consts;\n\tstruct sljit_label *last_label;\n\tstruct sljit_jump *last_jump;\n\tstruct sljit_const *last_const;\n\n\tvoid *allocator_data;\n\tvoid *user_data;\n\tstruct sljit_memory_fragment *buf;\n\tstruct sljit_memory_fragment *abuf;\n\n\t/* Number of labels created by the compiler. */\n\tsljit_uw label_count;\n\t/* Available scratch registers. */\n\tsljit_s32 scratches;\n\t/* Available saved registers. */\n\tsljit_s32 saveds;\n\t/* Available float scratch registers. */\n\tsljit_s32 fscratches;\n\t/* Available float saved registers. */\n\tsljit_s32 fsaveds;\n#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \\\n\t\t|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \\\n\t\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\t/* Available vector scratch registers. */\n\tsljit_s32 vscratches;\n\t/* Available vector saved registers. */\n\tsljit_s32 vsaveds;\n#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */\n\t/* Local stack size. */\n\tsljit_s32 local_size;\n\t/* Maximum code size. */\n\tsljit_uw size;\n\t/* Relative offset of the executable mapping from the writable mapping. */\n\tsljit_sw executable_offset;\n\t/* Executable size for statistical purposes. */\n\tsljit_uw executable_size;\n\n#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)\n\tsljit_s32 status_flags_state;\n#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 args_size;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t/* Temporary fields. */\n\tsljit_s32 mode32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t/* Constant pool handling. */\n\tsljit_uw *cpool;\n\tsljit_u8 *cpool_unique;\n\tsljit_uw cpool_diff;\n\tsljit_uw cpool_fill;\n\t/* Other members. */\n\t/* Contains pointer, \"ldr pc, [...]\" pairs. */\n\tsljit_uw patches;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\t/* Temporary fields. */\n\tsljit_uw shift_imm;\n#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)\n\tsljit_uw args_size;\n#endif /* SLJIT_CONFIG_ARM_32 && __SOFTFP__ */\n\n#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)\n\t/* Temporary fields. */\n\tsljit_u32 imm;\n#endif /* SLJIT_CONFIG_PPC */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\tsljit_s32 delay_slot;\n\t/* Temporary fields. */\n\tsljit_s32 cache_arg;\n\tsljit_sw cache_argw;\n#endif /* SLJIT_CONFIG_MIPS */\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_uw args_size;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)\n\t/* Temporary fields. */\n\tsljit_s32 cache_arg;\n\tsljit_sw cache_argw;\n#endif /* SLJIT_CONFIG_RISCV */\n\n#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\t/* Need to allocate register save area to make calls. */\n\t/* Temporary fields. */\n\tsljit_s32 mode;\n#endif /* SLJIT_CONFIG_S390X */\n\n#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)\n\t/* Temporary fields. */\n\tsljit_s32 cache_arg;\n\tsljit_sw cache_argw;\n#endif /* SLJIT_CONFIG_LOONGARCH */\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n\tFILE* verbose;\n#endif /* SLJIT_VERBOSE */\n\n\t/* Note: SLJIT_DEBUG enables SLJIT_ARGUMENT_CHECKS. */\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t/* Flags specified by the last arithmetic instruction.\n\t   It contains the type of the variable flag. */\n\tsljit_s32 last_flags;\n\t/* Return value type set by entry functions. */\n\tsljit_s32 last_return;\n\t/* Local size passed to entry functions. */\n\tsljit_s32 logical_local_size;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \\\n\t\t|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)\n\t/* Available float scratch registers. */\n\tsljit_s32 real_fscratches;\n\t/* Available float saved registers. */\n\tsljit_s32 real_fsaveds;\n#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */\n\n\t/* Trust arguments when an API function is called.\n\t   Used internally for calling API functions. */\n\tsljit_s32 skip_checks;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */\n};\n\n/* --------------------------------------------------------------------- */\n/*  Main functions                                                       */\n/* --------------------------------------------------------------------- */\n\n/* Creates an SLJIT compiler. The allocator_data is required by some\n   custom memory managers. This pointer is passed to SLJIT_MALLOC\n   and SLJIT_FREE macros. Most allocators (including the default\n   one) ignores this value, and it is recommended to pass NULL\n   as a dummy value for allocator_data.\n\n   Returns NULL if failed. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);\n\n/* Frees everything except the compiled machine code. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);\n\n/* Returns the current error code. If an error occurres, future calls\n   which uses the same compiler argument returns early with the same\n   error code. Thus there is no need for checking the error after every\n   call, it is enough to do it after the code is compiled. Removing\n   these checks increases the performance of the compiling process. */\nstatic SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }\n\n/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except\n   if an error was detected before. After the error code is set\n   the compiler behaves as if the allocation failure happened\n   during an SLJIT function call. This can greatly simplify error\n   checking, since it is enough to check the compiler status\n   after the code is compiled. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);\n\n/* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,\n   and <= 128 bytes on 64 bit architectures. The memory area is owned by the\n   compiler, and freed by sljit_free_compiler. The returned pointer is\n   sizeof(sljit_sw) aligned. Excellent for allocating small blocks during\n   compiling, and no need to worry about freeing them. The size is enough\n   to contain at most 16 pointers. If the size is outside of the range,\n   the function will return with NULL. However, this return value does not\n   indicate that there is no more memory (does not set the current error code\n   of the compiler to out-of-memory status). */\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);\n\n/* Returns the allocator data passed to sljit_create_compiler. */\nstatic SLJIT_INLINE void* sljit_compiler_get_allocator_data(struct sljit_compiler *compiler) { return compiler->allocator_data; }\n/* Sets/get the user data for a compiler. */\nstatic SLJIT_INLINE void sljit_compiler_set_user_data(struct sljit_compiler *compiler, void *user_data) { compiler->user_data = user_data; }\nstatic SLJIT_INLINE void* sljit_compiler_get_user_data(struct sljit_compiler *compiler) { return compiler->user_data; }\n\n#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)\n/* Passing NULL disables verbose. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);\n#endif /* SLJIT_VERBOSE */\n\n/* Option bits for sljit_generate_code. */\n\n/* The exec_allocator_data points to a pre-allocated\n   buffer which type is sljit_generate_code_buffer. */\n#define SLJIT_GENERATE_CODE_BUFFER\t\t0x1\n\n/* When SLJIT_INDIRECT_CALL is defined, no function context is\ncreated for the generated code (see sljit_set_function_context),\nso the returned pointer cannot be directly called from C code.\nThe flag is ignored when SLJIT_INDIRECT_CALL is not defined. */\n#define SLJIT_GENERATE_CODE_NO_CONTEXT\t\t0x2\n\n/* Create executable code from the instruction stream. This is the final step\n   of the code generation, and no more instructions can be emitted after this call.\n\n   options is the combination of SLJIT_GENERATE_CODE_* bits\n   exec_allocator_data is passed to SLJIT_MALLOC_EXEC and\n                       SLJIT_MALLOC_FREE functions */\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data);\n\n/* Free executable code. */\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);\n\n/* When the protected executable allocator is used the JIT code is mapped\n   twice. The first mapping has read/write and the second mapping has read/exec\n   permissions. This function returns with the relative offset of the executable\n   mapping using the writable mapping as the base after the machine code is\n   successfully generated. The returned value is always 0 for the normal executable\n   allocator, since it uses only one mapping with read/write/exec permissions.\n   Dynamic code modifications requires this value.\n\n   Before a successful code generation, this function returns with 0. */\nstatic SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }\n\n/* The executable memory consumption of the generated code can be retrieved by\n   this function. The returned value can be used for statistical purposes.\n\n   Before a successful code generation, this function returns with 0. */\nstatic SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }\n\n/* Returns with non-zero if the feature or limitation type passed as its\n   argument is present on the current CPU. The return value is one, if a\n   feature is fully supported, and it is two, if partially supported.\n\n   Some features (e.g. floating point operations) require hardware (CPU)\n   support while others (e.g. move with update) are emulated if not available.\n   However, even when a feature is emulated, specialized code paths may be\n   faster than the emulation. Some limitations are emulated as well so their\n   general case is supported but it has extra performance costs.\n\n   Note: sljitConfigInternal.h also provides several feature detection macros. */\n\n/* [Not emulated] Floating-point support is available. */\n#define SLJIT_HAS_FPU\t\t\t0\n/* [Limitation] Some registers are virtual registers. */\n#define SLJIT_HAS_VIRTUAL_REGISTERS\t1\n/* [Emulated] Has zero register (setting a memory location to zero is efficient). */\n#define SLJIT_HAS_ZERO_REGISTER\t\t2\n/* [Emulated] Count leading zero is supported. */\n#define SLJIT_HAS_CLZ\t\t\t3\n/* [Emulated] Count trailing zero is supported. */\n#define SLJIT_HAS_CTZ\t\t\t4\n/* [Emulated] Reverse the order of bytes is supported. */\n#define SLJIT_HAS_REV\t\t\t5\n/* [Emulated] Rotate left/right is supported. */\n#define SLJIT_HAS_ROT\t\t\t6\n/* [Emulated] Conditional move is supported. */\n#define SLJIT_HAS_CMOV\t\t\t7\n/* [Emulated] Prefetch instruction is available (emulated as a nop). */\n#define SLJIT_HAS_PREFETCH\t\t8\n/* [Emulated] Copy from/to f32 operation is available (see sljit_emit_fcopy). */\n#define SLJIT_HAS_COPY_F32\t\t9\n/* [Emulated] Copy from/to f64 operation is available (see sljit_emit_fcopy). */\n#define SLJIT_HAS_COPY_F64\t\t10\n/* [Not emulated] The 64 bit floating point registers can be used as\n   two separate 32 bit floating point registers (e.g. ARM32). The\n   second 32 bit part can be accessed by SLJIT_F64_SECOND. */\n#define SLJIT_HAS_F64_AS_F32_PAIR\t11\n/* [Not emulated] Some SIMD operations are supported by the compiler. */\n#define SLJIT_HAS_SIMD\t\t\t12\n/* [Not emulated] SIMD registers are mapped to a pair of double precision\n   floating point registers. E.g. passing either SLJIT_FR0 or SLJIT_FR1 to\n   a simd operation represents the same 128 bit register, and both SLJIT_FR0\n   and SLJIT_FR1 are overwritten. */\n#define SLJIT_SIMD_REGS_ARE_PAIRS\t13\n/* [Not emulated] Atomic support is available. */\n#define SLJIT_HAS_ATOMIC\t\t14\n/* [Not emulated] Memory barrier support is available. */\n#define SLJIT_HAS_MEMORY_BARRIER\t\t15\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n/* [Not emulated] AVX support is available on x86. */\n#define SLJIT_HAS_AVX\t\t\t100\n/* [Not emulated] AVX2 support is available on x86. */\n#define SLJIT_HAS_AVX2\t\t\t101\n#endif /* SLJIT_CONFIG_X86 */\n\n#if (defined SLJIT_CONFIG_LOONGARCH)\n/* [Not emulated] LASX support is available on LoongArch */\n#define SLJIT_HAS_LASX        201\n#endif /* SLJIT_CONFIG_LOONGARCH */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type);\n\n/* If type is between SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL,\n   sljit_cmp_info returns with:\n     zero - if the cpu supports the floating point comparison type\n     one - if the comparison requires two machine instructions\n     two - if the comparison requires more than two machine instructions\n\n   When the result is non-zero, it is recommended to avoid\n   using the specified comparison type if it is easy to do so.\n\n   Otherwise it returns zero. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type);\n\n/* The following functions generate machine code. If there is no\n   error, they return with SLJIT_SUCCESS, otherwise they return\n   with an error code. */\n\n/*\n   The executable code is a callable function from the viewpoint\n   of the C language. Function calls must conform with the ABI\n   (Application Binary Interface) of the target platform, which\n   specify the purpose of machine registers and stack handling\n   among other things. The sljit_emit_enter function emits the\n   necessary instructions for setting up an entry point for the\n   executable code. This is often called as function prologue.\n\n   The \"options\" argument can be used to pass configuration options\n   to the sljit compiler which affects the generated code, until\n   another sljit_emit_enter or sljit_set_context is called. The\n   available options are listed before sljit_emit_enter.\n\n   The function argument list is specified by the SLJIT_ARGSx\n   (SLJIT_ARGS0 .. SLJIT_ARGS4) macros. Currently maximum four\n   arguments are supported. See the description of SLJIT_ARGSx\n   macros about argument passing.\n\n   The register set used by the function must be declared as well.\n   The number of scratch and saved registers available to the\n   function must be passed to sljit_emit_enter. Only R registers\n   between R0 and \"scratches\" argument can be used later. E.g.\n   if \"scratches\" is set to two, the scratch register set will\n   be limited to SLJIT_R0 and SLJIT_R1. The S registers are\n   declared in a similar manner, but their count is specified\n   by \"saveds\" argument. The floating point scratch and saved\n   registers can be set by using \"scratches\" and \"saveds\" argument\n   as well, but their value must be passed to the SLJIT_ENTER_FLOAT\n   macro, see below.\n\n   The sljit_emit_enter is also capable of allocating a stack\n   space for local data. The \"local_size\" argument contains the\n   size in bytes of this local area, and it can be accessed using\n   SLJIT_MEM1(SLJIT_SP). The memory area between SLJIT_SP (inclusive)\n   and SLJIT_SP + local_size (exclusive) can be modified freely\n   until the function returns. The alocated stack space is an\n   uninitialized memory area.\n\n   Floating point scratch and saved registers must be specified\n   by the SLJIT_ENTER_FLOAT macro, which result value should be\n   combined with scratches / saveds argument.\n\n   Examples:\n       To use three scratch and four floating point scratch\n       registers, the \"scratches\" argument must be set to:\n            3 | SLJIT_ENTER_FLOAT(4)\n\n       To use six saved and five floating point saved\n       registers, the \"saveds\" argument must be set to:\n            6 | SLJIT_ENTER_FLOAT(5)\n\n   Note: the following conditions must met:\n         0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS\n         0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS\n         scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS\n\n         0 <= float scratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS\n         0 <= float saveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS\n         float scratches + float saveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS\n\n   Note: the compiler can use saved registers as scratch registers,\n         but the opposite is not supported\n\n   Note: every call of sljit_emit_enter and sljit_set_context\n         overwrites the previous context.\n*/\n\n/* The following options are available for sljit_emit_enter. */\n\n/* Saved registers between SLJIT_S0 and SLJIT_S(n - 1) (inclusive)\n   are not saved / restored on function enter / return. Instead,\n   these registers can be used to pass / return data (such as\n   global / local context pointers) across function calls. The\n   value of n must be between 1 and 3. This option is only\n   supported by SLJIT_ENTER_REG_ARG calling convention. */\n#define SLJIT_ENTER_KEEP(n)\t\t(n)\n\n/* The compiled function uses an SLJIT specific register argument\n   calling convention. This is a lightweight function call type where\n   both the caller and the called functions must be compiled by\n   SLJIT. The type argument of the call must be SLJIT_CALL_REG_ARG\n   and all arguments must be stored in scratch registers. */\n#define SLJIT_ENTER_REG_ARG\t\t0x00000004\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n/* Use VEX prefix for all SIMD operations on x86. */\n#define SLJIT_ENTER_USE_VEX\t\t0x00010000\n#endif /* !SLJIT_CONFIG_X86 */\n\n/* Macros for other sljit_emit_enter arguments. */\n\n/* Floating point scratch and saved registers can be\n   specified by SLJIT_ENTER_FLOAT. */\n#define SLJIT_ENTER_FLOAT(regs)\t\t((regs) << 8)\n\n/* Vector scratch and saved registers can be specified\n   by SLJIT_ENTER_VECTOR. */\n#define SLJIT_ENTER_VECTOR(regs)\t((regs) << 16)\n\n/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */\n#define SLJIT_MAX_LOCAL_SIZE\t\t1048576\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size);\n\n/* The SLJIT compiler has a current context (which contains the local\n   stack space size, number of used registers, etc.) which is initialized\n   by sljit_emit_enter. Several functions (such as sljit_emit_return)\n   requires this context to be able to generate the appropriate code.\n   However, some code fragments (compiled separately) may have no\n   normal entry point so their context is unknown to the compiler.\n\n   sljit_set_context and sljit_emit_enter have the same arguments,\n   but sljit_set_context does not generate any machine code.\n\n   Note: every call of sljit_emit_enter and sljit_set_context overwrites\n         the previous context. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size);\n\n/* Return to the caller function. The sljit_emit_return_void function\n   does not return with any value. The sljit_emit_return function returns\n   with a single value loaded from its source operand. The load operation\n   can be between SLJIT_MOV and SLJIT_MOV_P (see sljit_emit_op1) and\n   SLJIT_MOV_F32/SLJIT_MOV_F64 (see sljit_emit_fop1) depending on the\n   return value specified by sljit_emit_enter/sljit_set_context. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler);\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* Restores the saved registers and free the stack area, then the execution\n   continues from the address specified by the source operand. This\n   operation is similar to sljit_emit_return, but it ignores the return\n   address. The code where the exection continues should use the same context\n   as the caller function (see sljit_set_context). A word (pointer) value\n   can be passed in the SLJIT_RETURN_REG register. This function can be used\n   to jump to exception handlers. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw);\n\n/*\n   Source and destination operands for arithmetical instructions\n    imm              - a simple immediate value (cannot be used as a destination)\n    reg              - any of the available registers (immediate argument must be 0)\n    [imm]            - absolute memory address\n    [reg+imm]        - indirect memory address\n    [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)\n                       useful for accessing arrays (fully supported by both x86 and\n                       ARM architectures, and cheap operation on others)\n*/\n\n/*\n   IMPORTANT NOTE: memory accesses MUST be naturally aligned unless\n                   SLJIT_UNALIGNED macro is defined and its value is 1.\n\n     length | alignment\n   ---------+-----------\n     byte   | 1 byte (any physical_address is accepted)\n     half   | 2 byte (physical_address & 0x1 == 0)\n     int    | 4 byte (physical_address & 0x3 == 0)\n     word   | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1\n            | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1\n    pointer | size of sljit_up type (4 byte on 32 bit machines, 4 or 8 byte\n            | on 64 bit machines)\n\n   Note:   Different architectures have different addressing limitations.\n           A single instruction is enough for the following addressing\n           modes. Other addressing modes are emulated by instruction\n           sequences. This information could help to improve those code\n           generators which focuses only a few architectures.\n\n   x86:    [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)\n           [reg+(reg<<imm)] is supported\n           [imm], -2^32+1 <= imm <= 2^32-1 is supported\n           Write-back is not supported\n   arm:    [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed\n                bytes, any halfs or floating point values)\n           [reg+(reg<<imm)] is supported\n           Write-back is supported\n   arm-t2: [reg+imm], -255 <= imm <= 4095\n           [reg+(reg<<imm)] is supported\n           Write back is supported only for [reg+imm], where -255 <= imm <= 255\n   arm64:  [reg+imm], -256 <= imm <= 255, 0 <= aligned imm <= 4095 * alignment\n           [reg+(reg<<imm)] is supported\n           Write back is supported only for [reg+imm], where -256 <= imm <= 255\n   ppc:    [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit\n                signed load on 64 bit requires immediates divisible by 4.\n                [reg+imm] is not supported for signed 8 bit values.\n           [reg+reg] is supported\n           Write-back is supported except for one instruction: 32 bit signed\n                load with [reg+imm] addressing mode on 64 bit.\n   mips:   [reg+imm], -65536 <= imm <= 65535\n           Write-back is not supported\n   riscv:  [reg+imm], -2048 <= imm <= 2047\n           Write-back is not supported\n   s390x:  [reg+imm], -2^19 <= imm < 2^19\n           [reg+reg] is supported\n           Write-back is not supported\n   loongarch:  [reg+imm], -2048 <= imm <= 2047\n           [reg+reg] is supported\n           Write-back is not supported\n*/\n\n/* Macros for specifying operand types. */\n#define SLJIT_MEM\t\t0x80\n#define SLJIT_MEM0()\t\t(SLJIT_MEM)\n#define SLJIT_MEM1(r1)\t\t(SLJIT_MEM | (r1))\n#define SLJIT_MEM2(r1, r2)\t(SLJIT_MEM | (r1) | ((r2) << 8))\n#define SLJIT_IMM\t\t0x7f\n#define SLJIT_REG_PAIR(r1, r2)\t((r1) | ((r2) << 8))\n\n/* Macros for checking operand types (only for valid arguments). */\n#define SLJIT_IS_REG(arg)\t((arg) > 0 && (arg) < SLJIT_IMM)\n#define SLJIT_IS_MEM(arg)\t((arg) & SLJIT_MEM)\n#define SLJIT_IS_MEM0(arg)\t((arg) == SLJIT_MEM)\n#define SLJIT_IS_MEM1(arg)\t((arg) > SLJIT_MEM && (arg) < (SLJIT_MEM << 1))\n#define SLJIT_IS_MEM2(arg)\t(((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1))\n#define SLJIT_IS_IMM(arg)\t((arg) == SLJIT_IMM)\n#define SLJIT_IS_REG_PAIR(arg)\t(!((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1))\n\n/* Macros for extracting registers from operands. */\n/* Support operands which contains a single register or\n   constructed using SLJIT_MEM1, SLJIT_MEM2, or SLJIT_REG_PAIR. */\n#define SLJIT_EXTRACT_REG(arg)\t\t((arg) & 0x7f)\n/* Support operands which constructed using SLJIT_MEM2, or SLJIT_REG_PAIR. */\n#define SLJIT_EXTRACT_SECOND_REG(arg)\t((arg) >> 8)\n\n/* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on\n   32 bit CPUs. When this option is set for an arithmetic operation, only\n   the lower 32 bits of the input registers are used, and the CPU status\n   flags are set according to the 32 bit result. Although the higher 32 bit\n   of the input and the result registers are not defined by SLJIT, it might\n   be defined by the CPU architecture (e.g. MIPS). To satisfy these CPU\n   requirements all source registers must be the result of those operations\n   where this option was also set. Memory loads read 32 bit values rather\n   than 64 bit ones. In other words 32 bit and 64 bit operations cannot be\n   mixed. The only exception is SLJIT_MOV32 which source register can hold\n   any 32 or 64 bit value, and it is converted to a 32 bit compatible format\n   first. When the source and destination registers are the same, this\n   conversion is free (no instructions are emitted) on most CPUs. A 32 bit\n   value can also be converted to a 64 bit value by SLJIT_MOV_S32\n   (sign extension) or SLJIT_MOV_U32 (zero extension).\n\n   As for floating-point operations, this option sets 32 bit single\n   precision mode. Similar to the integer operations, all register arguments\n   must be the result of those operations where this option was also set.\n\n   Note: memory addressing always uses 64 bit values on 64 bit systems so\n         the result of a 32 bit operation must not be used with SLJIT_MEMx\n         macros.\n\n   This option is part of the instruction name, so there is no need to\n   manually set it. E.g:\n\n     SLJIT_ADD32 == (SLJIT_ADD | SLJIT_32) */\n#define SLJIT_32\t\t0x100\n\n/* Many CPUs (x86, ARM, PPC) have status flag bits which can be set according\n   to the result of an operation. Other CPUs (MIPS) do not have status\n   flag bits, and results must be stored in registers. To cover both\n   architecture types efficiently only two flags are defined by SLJIT:\n\n    * Zero (equal) flag: it is set if the result is zero\n    * Variable flag: its value is defined by the arithmetic operation\n\n   SLJIT instructions can set any or both of these flags. The value of\n   these flags is undefined if the instruction does not specify their\n   value. The description of each instruction contains the list of\n   allowed flag types.\n\n   Note: the logical or operation can be used to set flags.\n\n   Example: SLJIT_ADD can set the Z, OVERFLOW, CARRY flags hence\n\n     sljit_op2(..., SLJIT_ADD, ...)\n       Both the zero and variable flags are undefined so they can\n       have any value after the operation is completed.\n\n     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)\n       Sets the zero flag if the result is zero, clears it otherwise.\n       The variable flag is undefined.\n\n     sljit_op2(..., SLJIT_ADD | SLJIT_SET_OVERFLOW, ...)\n       Sets the variable flag if an integer overflow occurs, clears\n       it otherwise. The zero flag is undefined.\n\n     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z | SLJIT_SET_CARRY, ...)\n       Sets the zero flag if the result is zero, clears it otherwise.\n       Sets the variable flag if unsigned overflow (carry) occurs,\n       clears it otherwise.\n\n   Certain instructions (e.g. SLJIT_MOV) does not modify flags, so\n   status flags are unchanged.\n\n   Example:\n\n     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)\n     sljit_op1(..., SLJIT_MOV, ...)\n       Zero flag is set according to the result of SLJIT_ADD.\n\n     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)\n     sljit_op2(..., SLJIT_ADD, ...)\n       Zero flag has unknown value.\n\n   These flags can be used for code optimization. E.g. a fast loop can be\n   implemented by decreasing a counter register and set the zero flag\n   using a single instruction. The zero register can be used by a\n   conditional jump to restart the loop. A single comparison can set a\n   zero and less flags to check if a value is less, equal, or greater\n   than another value.\n\n   Motivation: although some CPUs can set a large number of flag bits,\n   usually their values are ignored or only a few of them are used. Emulating\n   a large number of flags on systems without a flag register is complicated\n   so SLJIT instructions must specify the flag they want to use and only\n   that flag is computed. The last arithmetic instruction can be repeated if\n   multiple flags need to be checked.\n*/\n\n/* Set Zero status flag. */\n#define SLJIT_SET_Z\t\t\t0x0200\n/* Set the variable status flag if condition is true.\n   See comparison types (e.g. SLJIT_SET_LESS, SLJIT_SET_F_EQUAL). */\n#define SLJIT_SET(condition)\t\t\t((condition) << 10)\n\n/* Starting index of opcodes for sljit_emit_op0. */\n#define SLJIT_OP0_BASE\t\t\t0\n\n/* Flags: - (does not modify flags)\n   Note: breakpoint instruction is not supported by all architectures (e.g. ppc)\n         It falls back to SLJIT_NOP in those cases. */\n#define SLJIT_BREAKPOINT\t\t(SLJIT_OP0_BASE + 0)\n/* Flags: - (does not modify flags)\n   Note: may or may not cause an extra cycle wait\n         it can even decrease the runtime in a few cases. */\n#define SLJIT_NOP\t\t\t(SLJIT_OP0_BASE + 1)\n/* Flags: - (may destroy flags)\n   Unsigned multiplication of SLJIT_R0 and SLJIT_R1.\n   Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */\n#define SLJIT_LMUL_UW\t\t\t(SLJIT_OP0_BASE + 2)\n/* Flags: - (may destroy flags)\n   Signed multiplication of SLJIT_R0 and SLJIT_R1.\n   Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */\n#define SLJIT_LMUL_SW\t\t\t(SLJIT_OP0_BASE + 3)\n/* Flags: - (may destroy flags)\n   Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.\n   The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.\n   Note: if SLJIT_R1 is 0, the behaviour is undefined. */\n#define SLJIT_DIVMOD_UW\t\t\t(SLJIT_OP0_BASE + 4)\n#define SLJIT_DIVMOD_U32\t\t(SLJIT_DIVMOD_UW | SLJIT_32)\n/* Flags: - (may destroy flags)\n   Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.\n   The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.\n   Note: if SLJIT_R1 is 0, the behaviour is undefined.\n   Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),\n         the behaviour is undefined. */\n#define SLJIT_DIVMOD_SW\t\t\t(SLJIT_OP0_BASE + 5)\n#define SLJIT_DIVMOD_S32\t\t(SLJIT_DIVMOD_SW | SLJIT_32)\n/* Flags: - (may destroy flags)\n   Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.\n   The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.\n   Note: if SLJIT_R1 is 0, the behaviour is undefined. */\n#define SLJIT_DIV_UW\t\t\t(SLJIT_OP0_BASE + 6)\n#define SLJIT_DIV_U32\t\t\t(SLJIT_DIV_UW | SLJIT_32)\n/* Flags: - (may destroy flags)\n   Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.\n   The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.\n   Note: if SLJIT_R1 is 0, the behaviour is undefined.\n   Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),\n         the behaviour is undefined. */\n#define SLJIT_DIV_SW\t\t\t(SLJIT_OP0_BASE + 7)\n#define SLJIT_DIV_S32\t\t\t(SLJIT_DIV_SW | SLJIT_32)\n/* Flags: - (does not modify flags)\n   May return with SLJIT_ERR_UNSUPPORTED if SLJIT_HAS_MEMORY_BARRIER\n   feature is not supported (calling sljit_has_cpu_feature() with\n   this feature option returns with 0). */\n#define SLJIT_MEMORY_BARRIER\t\t(SLJIT_OP0_BASE + 8)\n/* Flags: - (does not modify flags)\n   ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64\n   when Intel Control-flow Enforcement Technology (CET) is enabled.\n   No instructions are emitted for other architectures. */\n#define SLJIT_ENDBR\t\t\t(SLJIT_OP0_BASE + 9)\n/* Flags: - (may destroy flags)\n   Skip stack frames before return when Intel Control-flow\n   Enforcement Technology (CET) is enabled. No instructions\n   are emitted for other architectures. */\n#define SLJIT_SKIP_FRAMES_BEFORE_RETURN\t(SLJIT_OP0_BASE + 10)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);\n\n/* Starting index of opcodes for sljit_emit_op1. */\n#define SLJIT_OP1_BASE\t\t\t32\n\n/* The MOV instruction transfers data from source to destination.\n\n   MOV instruction suffixes:\n\n   U8  - unsigned 8 bit data transfer\n   S8  - signed 8 bit data transfer\n   U16 - unsigned 16 bit data transfer\n   S16 - signed 16 bit data transfer\n   U32 - unsigned int (32 bit) data transfer\n   S32 - signed int (32 bit) data transfer\n   P   - pointer (sljit_up) data transfer\n*/\n\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV\t\t\t(SLJIT_OP1_BASE + 0)\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV_U8\t\t\t(SLJIT_OP1_BASE + 1)\n#define SLJIT_MOV32_U8\t\t\t(SLJIT_MOV_U8 | SLJIT_32)\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV_S8\t\t\t(SLJIT_OP1_BASE + 2)\n#define SLJIT_MOV32_S8\t\t\t(SLJIT_MOV_S8 | SLJIT_32)\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV_U16\t\t\t(SLJIT_OP1_BASE + 3)\n#define SLJIT_MOV32_U16\t\t\t(SLJIT_MOV_U16 | SLJIT_32)\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV_S16\t\t\t(SLJIT_OP1_BASE + 4)\n#define SLJIT_MOV32_S16\t\t\t(SLJIT_MOV_S16 | SLJIT_32)\n/* Flags: - (does not modify flags)\n   Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */\n#define SLJIT_MOV_U32\t\t\t(SLJIT_OP1_BASE + 5)\n/* Flags: - (does not modify flags)\n   Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */\n#define SLJIT_MOV_S32\t\t\t(SLJIT_OP1_BASE + 6)\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV32\t\t\t(SLJIT_OP1_BASE + 7)\n/* Flags: - (does not modify flags)\n   Note: loads a pointer sized data, useful on x32 mode (a 64 bit mode\n         on x86-64 which uses 32 bit pointers) or similar compiling modes */\n#define SLJIT_MOV_P\t\t\t(SLJIT_OP1_BASE + 8)\n/* Count leading zeroes\n   Flags: - (may destroy flags)\n   Note: immediate source argument is not supported */\n#define SLJIT_CLZ\t\t\t(SLJIT_OP1_BASE + 9)\n#define SLJIT_CLZ32\t\t\t(SLJIT_CLZ | SLJIT_32)\n/* Count trailing zeroes\n   Flags: - (may destroy flags)\n   Note: immediate source argument is not supported */\n#define SLJIT_CTZ\t\t\t(SLJIT_OP1_BASE + 10)\n#define SLJIT_CTZ32\t\t\t(SLJIT_CTZ | SLJIT_32)\n/* Reverse the order of bytes\n   Flags: - (may destroy flags)\n   Note: converts between little and big endian formats\n   Note: immediate source argument is not supported */\n#define SLJIT_REV\t\t\t(SLJIT_OP1_BASE + 11)\n#define SLJIT_REV32\t\t\t(SLJIT_REV | SLJIT_32)\n/* Reverse the order of bytes in the lower 16 bit and extend as unsigned\n   Flags: - (may destroy flags)\n   Note: converts between little and big endian formats\n   Note: immediate source argument is not supported */\n#define SLJIT_REV_U16\t\t\t(SLJIT_OP1_BASE + 12)\n#define SLJIT_REV32_U16\t\t\t(SLJIT_REV_U16 | SLJIT_32)\n/* Reverse the order of bytes in the lower 16 bit and extend as signed\n   Flags: - (may destroy flags)\n   Note: converts between little and big endian formats\n   Note: immediate source argument is not supported */\n#define SLJIT_REV_S16\t\t\t(SLJIT_OP1_BASE + 13)\n#define SLJIT_REV32_S16\t\t\t(SLJIT_REV_S16 | SLJIT_32)\n/* Reverse the order of bytes in the lower 32 bit and extend as unsigned\n   Flags: - (may destroy flags)\n   Note: converts between little and big endian formats\n   Note: immediate source argument is not supported */\n#define SLJIT_REV_U32\t\t\t(SLJIT_OP1_BASE + 14)\n/* Reverse the order of bytes in the lower 32 bit and extend as signed\n   Flags: - (may destroy flags)\n   Note: converts between little and big endian formats\n   Note: immediate source argument is not supported */\n#define SLJIT_REV_S32\t\t\t(SLJIT_OP1_BASE + 15)\n\n/* The following unary operations are supported by using sljit_emit_op2:\n     - binary not: SLJIT_XOR with immedate -1 as src1 or src2\n     - negate: SLJIT_SUB with immedate 0 as src1\n   Note: these operations are optimized by the compiler if the\n     target CPU has specialized instruction forms for them. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* Starting index of opcodes for sljit_emit_op2. */\n#define SLJIT_OP2_BASE\t\t\t64\n\n/* Flags: Z | OVERFLOW | CARRY */\n#define SLJIT_ADD\t\t\t(SLJIT_OP2_BASE + 0)\n#define SLJIT_ADD32\t\t\t(SLJIT_ADD | SLJIT_32)\n/* Flags: CARRY */\n#define SLJIT_ADDC\t\t\t(SLJIT_OP2_BASE + 1)\n#define SLJIT_ADDC32\t\t\t(SLJIT_ADDC | SLJIT_32)\n/* Flags: Z | LESS | GREATER_EQUAL | GREATER | LESS_EQUAL\n          SIG_LESS | SIG_GREATER_EQUAL | SIG_GREATER\n          SIG_LESS_EQUAL | OVERFLOW | CARRY */\n#define SLJIT_SUB\t\t\t(SLJIT_OP2_BASE + 2)\n#define SLJIT_SUB32\t\t\t(SLJIT_SUB | SLJIT_32)\n/* Flags: CARRY */\n#define SLJIT_SUBC\t\t\t(SLJIT_OP2_BASE + 3)\n#define SLJIT_SUBC32\t\t\t(SLJIT_SUBC | SLJIT_32)\n/* Note: integer mul\n   Flags: OVERFLOW */\n#define SLJIT_MUL\t\t\t(SLJIT_OP2_BASE + 4)\n#define SLJIT_MUL32\t\t\t(SLJIT_MUL | SLJIT_32)\n/* Flags: Z */\n#define SLJIT_AND\t\t\t(SLJIT_OP2_BASE + 5)\n#define SLJIT_AND32\t\t\t(SLJIT_AND | SLJIT_32)\n/* Flags: Z */\n#define SLJIT_OR\t\t\t(SLJIT_OP2_BASE + 6)\n#define SLJIT_OR32\t\t\t(SLJIT_OR | SLJIT_32)\n/* Flags: Z */\n#define SLJIT_XOR\t\t\t(SLJIT_OP2_BASE + 7)\n#define SLJIT_XOR32\t\t\t(SLJIT_XOR | SLJIT_32)\n/* Flags: Z\n   Let bit_length be the length of the shift operation: 32 or 64.\n   If src2 is immediate, src2w is masked by (bit_length - 1).\n   Otherwise, if the content of src2 is outside the range from 0\n   to bit_length - 1, the result is undefined. */\n#define SLJIT_SHL\t\t\t(SLJIT_OP2_BASE + 8)\n#define SLJIT_SHL32\t\t\t(SLJIT_SHL | SLJIT_32)\n/* Flags: Z\n   Same as SLJIT_SHL, except the the second operand is\n   always masked by the length of the shift operation. */\n#define SLJIT_MSHL\t\t\t(SLJIT_OP2_BASE + 9)\n#define SLJIT_MSHL32\t\t\t(SLJIT_MSHL | SLJIT_32)\n/* Flags: Z\n   Let bit_length be the length of the shift operation: 32 or 64.\n   If src2 is immediate, src2w is masked by (bit_length - 1).\n   Otherwise, if the content of src2 is outside the range from 0\n   to bit_length - 1, the result is undefined. */\n#define SLJIT_LSHR\t\t\t(SLJIT_OP2_BASE + 10)\n#define SLJIT_LSHR32\t\t\t(SLJIT_LSHR | SLJIT_32)\n/* Flags: Z\n   Same as SLJIT_LSHR, except the the second operand is\n   always masked by the length of the shift operation. */\n#define SLJIT_MLSHR\t\t\t(SLJIT_OP2_BASE + 11)\n#define SLJIT_MLSHR32\t\t\t(SLJIT_MLSHR | SLJIT_32)\n/* Flags: Z\n   Let bit_length be the length of the shift operation: 32 or 64.\n   If src2 is immediate, src2w is masked by (bit_length - 1).\n   Otherwise, if the content of src2 is outside the range from 0\n   to bit_length - 1, the result is undefined. */\n#define SLJIT_ASHR\t\t\t(SLJIT_OP2_BASE + 12)\n#define SLJIT_ASHR32\t\t\t(SLJIT_ASHR | SLJIT_32)\n/* Flags: Z\n   Same as SLJIT_ASHR, except the the second operand is\n   always masked by the length of the shift operation. */\n#define SLJIT_MASHR\t\t\t(SLJIT_OP2_BASE + 13)\n#define SLJIT_MASHR32\t\t\t(SLJIT_MASHR | SLJIT_32)\n/* Flags: - (may destroy flags)\n   Let bit_length be the length of the rotate operation: 32 or 64.\n   The second operand is always masked by (bit_length - 1). */\n#define SLJIT_ROTL\t\t\t(SLJIT_OP2_BASE + 14)\n#define SLJIT_ROTL32\t\t\t(SLJIT_ROTL | SLJIT_32)\n/* Flags: - (may destroy flags)\n   Let bit_length be the length of the rotate operation: 32 or 64.\n   The second operand is always masked by (bit_length - 1). */\n#define SLJIT_ROTR\t\t\t(SLJIT_OP2_BASE + 15)\n#define SLJIT_ROTR32\t\t\t(SLJIT_ROTR | SLJIT_32)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* The sljit_emit_op2u function is the same as sljit_emit_op2\n   except the result is discarded. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Starting index of opcodes for sljit_emit_op2r. */\n#define SLJIT_OP2R_BASE\t\t\t96\n\n/* Flags: - (may destroy flags) */\n#define SLJIT_MULADD\t\t\t(SLJIT_OP2R_BASE + 0)\n#define SLJIT_MULADD32\t\t\t(SLJIT_MULADD | SLJIT_32)\n\n/* Similar to sljit_emit_fop2, except the destination is always a register. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Emit a left or right shift operation, where the bits shifted\n   in comes from a separate source operand. All operands are\n   interpreted as unsigned integers.\n\n   In the followings the value_mask variable is 31 for 32 bit\n     operations and word_size - 1 otherwise.\n\n   op must be one of the following operations:\n     SLJIT_SHL or SLJIT_SHL32:\n       dst_reg = src1_reg << src3_reg\n       dst_reg |= ((src2_reg >> 1) >> (src3 ^ value_mask))\n     SLJIT_MSHL or SLJIT_MSHL32:\n       src3 &= value_mask\n       perform the SLJIT_SHL or SLJIT_SHL32 operation\n     SLJIT_LSHR or SLJIT_LSHR32:\n       dst_reg = src1_reg >> src3_reg\n       dst_reg |= ((src2_reg << 1) << (src3 ^ value_mask))\n     SLJIT_MLSHR or SLJIT_MLSHR32:\n       src3 &= value_mask\n       perform the SLJIT_LSHR or SLJIT_LSHR32 operation\n\n   op can be combined (or'ed) with SLJIT_SHIFT_INTO_NON_ZERO\n\n   dst_reg specifies the destination register, where dst_reg\n     and src2_reg cannot be the same registers\n   src1_reg specifies the source register\n   src2_reg specifies the register which is shifted into src1_reg\n   src3 / src3w contains the shift amount\n\n   Note: a rotate operation is performed if src1_reg and\n         src2_reg are the same registers\n\n   Flags: - (may destroy flags) */\n\n/* The src3 operand contains a non-zero value. Improves\n   the generated code on certain architectures, which\n   provides a small performance improvement. */\n#define SLJIT_SHIFT_INTO_NON_ZERO\t0x200\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w);\n\n/* The following options are used by sljit_emit_op2_shift. */\n\n/* The src2 argument is shifted left by an immedate value. */\n#define SLJIT_SHL_IMM\t\t\t(1 << 9)\n/* When src2 argument is a register, its value is undefined after the operation. */\n#define SLJIT_SRC2_UNDEFINED\t\t(1 << 10)\n\n/* Emits an addition operation, where the second argument is shifted by a value.\n\n   op must be SLJIT_ADD | SLJIT_SHL_IMM, where the immedate value is stored in shift_arg\n\n   Flags: - (may destroy flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg);\n\n/* Starting index of opcodes for sljit_emit_op_src\n   and sljit_emit_op_dst. */\n#define SLJIT_OP_SRC_DST_BASE\t\t112\n\n/* Fast return, see SLJIT_FAST_CALL for more details.\n   Note: src cannot be an immedate value\n   Flags: - (does not modify flags) */\n#define SLJIT_FAST_RETURN\t\t(SLJIT_OP_SRC_DST_BASE + 0)\n/* Skip stack frames before fast return.\n   Note: src cannot be an immedate value\n   Flags: may destroy flags. */\n#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN\t(SLJIT_OP_SRC_DST_BASE + 1)\n/* Prefetch value into the level 1 data cache\n   Note: if the target CPU does not support data prefetch,\n         no instructions are emitted.\n   Note: this instruction never fails, even if the memory address is invalid.\n   Flags: - (does not modify flags) */\n#define SLJIT_PREFETCH_L1\t\t(SLJIT_OP_SRC_DST_BASE + 2)\n/* Prefetch value into the level 2 data cache\n   Note: same as SLJIT_PREFETCH_L1 if the target CPU\n         does not support this instruction form.\n   Note: this instruction never fails, even if the memory address is invalid.\n   Flags: - (does not modify flags) */\n#define SLJIT_PREFETCH_L2\t\t(SLJIT_OP_SRC_DST_BASE + 3)\n/* Prefetch value into the level 3 data cache\n   Note: same as SLJIT_PREFETCH_L2 if the target CPU\n         does not support this instruction form.\n   Note: this instruction never fails, even if the memory address is invalid.\n   Flags: - (does not modify flags) */\n#define SLJIT_PREFETCH_L3\t\t(SLJIT_OP_SRC_DST_BASE + 4)\n/* Prefetch a value which is only used once (and can be discarded afterwards)\n   Note: same as SLJIT_PREFETCH_L1 if the target CPU\n         does not support this instruction form.\n   Note: this instruction never fails, even if the memory address is invalid.\n   Flags: - (does not modify flags) */\n#define SLJIT_PREFETCH_ONCE\t\t(SLJIT_OP_SRC_DST_BASE + 5)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* Fast enter, see SLJIT_FAST_CALL for more details.\n   Flags: - (does not modify flags) */\n#define SLJIT_FAST_ENTER\t\t(SLJIT_OP_SRC_DST_BASE + 6)\n\n/* Copies the return address into dst. The return address is the\n   address where the execution continues after the called function\n   returns (see: sljit_emit_return / sljit_emit_return_void).\n   Flags: - (does not modify flags) */\n#define SLJIT_GET_RETURN_ADDRESS\t(SLJIT_OP_SRC_DST_BASE + 7)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw);\n\n/* Starting index of opcodes for sljit_emit_fop1. */\n#define SLJIT_FOP1_BASE\t\t\t144\n\n/* Flags: - (does not modify flags) */\n#define SLJIT_MOV_F64\t\t\t(SLJIT_FOP1_BASE + 0)\n#define SLJIT_MOV_F32\t\t\t(SLJIT_MOV_F64 | SLJIT_32)\n/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]\n   SRC/DST TYPE can be: F64, F32, S32, SW\n   Rounding mode when the destination is SW or S32: round towards zero. */\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_F64_FROM_F32\t\t(SLJIT_FOP1_BASE + 1)\n#define SLJIT_CONV_F32_FROM_F64\t\t(SLJIT_CONV_F64_FROM_F32 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_SW_FROM_F64\t\t(SLJIT_FOP1_BASE + 2)\n#define SLJIT_CONV_SW_FROM_F32\t\t(SLJIT_CONV_SW_FROM_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_S32_FROM_F64\t\t(SLJIT_FOP1_BASE + 3)\n#define SLJIT_CONV_S32_FROM_F32\t\t(SLJIT_CONV_S32_FROM_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_F64_FROM_SW\t\t(SLJIT_FOP1_BASE + 4)\n#define SLJIT_CONV_F32_FROM_SW\t\t(SLJIT_CONV_F64_FROM_SW | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_F64_FROM_S32\t\t(SLJIT_FOP1_BASE + 5)\n#define SLJIT_CONV_F32_FROM_S32\t\t(SLJIT_CONV_F64_FROM_S32 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_F64_FROM_UW\t\t(SLJIT_FOP1_BASE + 6)\n#define SLJIT_CONV_F32_FROM_UW\t\t(SLJIT_CONV_F64_FROM_UW | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_CONV_F64_FROM_U32\t\t(SLJIT_FOP1_BASE + 7)\n#define SLJIT_CONV_F32_FROM_U32\t\t(SLJIT_CONV_F64_FROM_U32 | SLJIT_32)\n/* Note: dst is the left and src is the right operand for SLJIT_CMP_F32/64.\n   Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */\n#define SLJIT_CMP_F64\t\t\t(SLJIT_FOP1_BASE + 8)\n#define SLJIT_CMP_F32\t\t\t(SLJIT_CMP_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_NEG_F64\t\t\t(SLJIT_FOP1_BASE + 9)\n#define SLJIT_NEG_F32\t\t\t(SLJIT_NEG_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_ABS_F64\t\t\t(SLJIT_FOP1_BASE + 10)\n#define SLJIT_ABS_F32\t\t\t(SLJIT_ABS_F64 | SLJIT_32)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* Starting index of opcodes for sljit_emit_fop2. */\n#define SLJIT_FOP2_BASE\t\t\t176\n\n/* Flags: - (may destroy flags) */\n#define SLJIT_ADD_F64\t\t\t(SLJIT_FOP2_BASE + 0)\n#define SLJIT_ADD_F32\t\t\t(SLJIT_ADD_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_SUB_F64\t\t\t(SLJIT_FOP2_BASE + 1)\n#define SLJIT_SUB_F32\t\t\t(SLJIT_SUB_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_MUL_F64\t\t\t(SLJIT_FOP2_BASE + 2)\n#define SLJIT_MUL_F32\t\t\t(SLJIT_MUL_F64 | SLJIT_32)\n/* Flags: - (may destroy flags) */\n#define SLJIT_DIV_F64\t\t\t(SLJIT_FOP2_BASE + 3)\n#define SLJIT_DIV_F32\t\t\t(SLJIT_DIV_F64 | SLJIT_32)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Starting index of opcodes for sljit_emit_fop2r. */\n#define SLJIT_FOP2R_BASE\t\t192\n\n/* Flags: - (may destroy flags) */\n#define SLJIT_COPYSIGN_F64\t\t(SLJIT_FOP2R_BASE + 0)\n#define SLJIT_COPYSIGN_F32\t\t(SLJIT_COPYSIGN_F64 | SLJIT_32)\n\n/* Similar to sljit_emit_fop2, except the destination is always a register. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Sets a floating point register to an immediate value. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value);\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value);\n\n/* The following opcodes are used by sljit_emit_fcopy(). */\n\n/* 64 bit: copy a 64 bit value from an integer register into a\n           64 bit floating point register without any modifications.\n   32 bit: copy a 32 bit register or register pair into a 64 bit\n           floating point register without any modifications. The\n           register, or the first register of the register pair\n           replaces the high order 32 bit of the floating point\n           register. If a register pair is passed, the low\n           order 32 bit is replaced by the second register.\n           Otherwise, the low order 32 bit is unchanged. */\n#define SLJIT_COPY_TO_F64\t\t1\n/* Copy a 32 bit value from an integer register into a 32 bit\n   floating point register without any modifications. */\n#define SLJIT_COPY32_TO_F32\t\t(SLJIT_COPY_TO_F64 | SLJIT_32)\n/* 64 bit: copy the value of a 64 bit floating point register into\n           an integer register without any modifications.\n   32 bit: copy a 64 bit floating point register into a 32 bit register\n           or a 32 bit register pair without any modifications. The\n           high order 32 bit of the floating point register is copied\n           into the register, or the first register of the register\n           pair. If a register pair is passed, the low order 32 bit\n           is copied into the second register. */\n#define SLJIT_COPY_FROM_F64\t\t2\n/* Copy the value of a 32 bit floating point register into an integer\n   register without any modifications. The register should be processed\n   with 32 bit operations later. */\n#define SLJIT_COPY32_FROM_F32\t\t(SLJIT_COPY_FROM_F64 | SLJIT_32)\n\n/* Special data copy which involves floating point registers.\n\n  op must be between SLJIT_COPY_TO_F64 and SLJIT_COPY32_FROM_F32\n  freg must be a floating point register\n  reg must be a register or register pair */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg);\n\n/* Label and jump instructions. */\n\n/* Emits a label which can be the target of jump / mov_addr instructions. */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);\n\n/* Alignment values for sljit_emit_aligned_label. */\n\n#define SLJIT_LABEL_ALIGN_1\t0\n#define SLJIT_LABEL_ALIGN_2\t1\n#define SLJIT_LABEL_ALIGN_4\t2\n#define SLJIT_LABEL_ALIGN_8\t3\n#define SLJIT_LABEL_ALIGN_16\t4\n#define SLJIT_LABEL_ALIGN_W\tSLJIT_WORD_SHIFT\n#define SLJIT_LABEL_ALIGN_P\tSLJIT_POINTER_SHIFT\n\n/* Emits a label which address is aligned to a power of 2 value. When some\n   extra space needs to be added to align the label, that space is filled\n   with SLJIT_NOP instructions. These labels usually represent the end of a\n   compilation block, and a new function or some read-only data (e.g. a\n   jump table) follows it. In these typical cases the SLJIT_NOPs are never\n   executed.\n\n   Optionally, buffers for storing read-only data or code can be allocated\n   by this operation. The buffers are passed as a chain list, and a separate\n   memory area is allocated for each item in the list. All buffers are aligned\n   to SLJIT_NOP instruction size, and their starting address is returned as\n   as a label. The sljit_get_label_abs_addr function or the SLJIT_MOV_ABS_ADDR\n   operation can be used to get the real address. The label of the first buffer\n   is always the same as the returned label. The buffers are initially\n   initialized with SLJIT_NOP instructions. The alignment of the buffers can\n   be controlled by their starting address and sizes. If the starting address\n   is aligned to N, and size is also divisible by N, the next buffer is aligned\n   to N. I.e. if a buffer is 16 byte aligned, and its size is divisible by 4,\n   the next buffer is 4 byte aligned. Note: if a buffer is N (>=2) byte aligned,\n   it is also N/2 byte aligned.\n\n   align represents the alignment, and its value can\n         be specified by SLJIT_LABEL_* constants\n\n   buffers is a list of read-only buffers stored in a chain list.\n           After calling sljit_generate_code, these buffers can be\n           modified by sljit_read_only_buffer_start_writing() /\n           sljit_read_only_buffer_end_writing() functions\n\n   Note: the constant pool (if present) may be stored before the label. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers);\n\n/* The SLJIT_FAST_CALL is a calling method for creating lightweight function\n   calls. This type of calls preserve the values of all registers and stack\n   frame. Unlike normal function calls, the enter and return operations must\n   be performed by the SLJIT_FAST_ENTER and SLJIT_FAST_RETURN operations\n   respectively. The return address is stored in the dst argument of the\n   SLJIT_FAST_ENTER operation, and this return address should be passed as\n   the src argument for the SLJIT_FAST_RETURN operation to return from the\n   called function.\n\n   Fast calls are cheap operations (usually only a single call instruction is\n   emitted) but they do not preserve any registers. However the callee function\n   can freely use / update any registers and the locals area which can be\n   efficiently exploited by various optimizations. Registers can be saved\n   and restored manually if needed.\n\n   Although returning to different address by SLJIT_FAST_RETURN is possible,\n   this address usually cannot be predicted by the return address predictor of\n   modern CPUs which may reduce performance. Furthermore certain security\n   enhancement technologies such as Intel Control-flow Enforcement Technology\n   (CET) may disallow returning to a different address (indirect jumps\n   can be used instead, see SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN). */\n\n/* Invert (negate) conditional type: xor (^) with 0x1 */\n\n/* Integer comparison types. */\n#define SLJIT_EQUAL\t\t\t0\n#define SLJIT_ZERO\t\t\tSLJIT_EQUAL\n#define SLJIT_NOT_EQUAL\t\t\t1\n#define SLJIT_NOT_ZERO\t\t\tSLJIT_NOT_EQUAL\n\n#define SLJIT_LESS\t\t\t2\n#define SLJIT_SET_LESS\t\t\tSLJIT_SET(SLJIT_LESS)\n#define SLJIT_GREATER_EQUAL\t\t3\n#define SLJIT_SET_GREATER_EQUAL\t\tSLJIT_SET(SLJIT_LESS)\n#define SLJIT_GREATER\t\t\t4\n#define SLJIT_SET_GREATER\t\tSLJIT_SET(SLJIT_GREATER)\n#define SLJIT_LESS_EQUAL\t\t5\n#define SLJIT_SET_LESS_EQUAL\t\tSLJIT_SET(SLJIT_GREATER)\n#define SLJIT_SIG_LESS\t\t\t6\n#define SLJIT_SET_SIG_LESS\t\tSLJIT_SET(SLJIT_SIG_LESS)\n#define SLJIT_SIG_GREATER_EQUAL\t\t7\n#define SLJIT_SET_SIG_GREATER_EQUAL\tSLJIT_SET(SLJIT_SIG_LESS)\n#define SLJIT_SIG_GREATER\t\t8\n#define SLJIT_SET_SIG_GREATER\t\tSLJIT_SET(SLJIT_SIG_GREATER)\n#define SLJIT_SIG_LESS_EQUAL\t\t9\n#define SLJIT_SET_SIG_LESS_EQUAL\tSLJIT_SET(SLJIT_SIG_GREATER)\n\n#define SLJIT_OVERFLOW\t\t\t10\n#define SLJIT_SET_OVERFLOW\t\tSLJIT_SET(SLJIT_OVERFLOW)\n#define SLJIT_NOT_OVERFLOW\t\t11\n\n/* Unlike other flags, sljit_emit_jump may destroy the carry flag. */\n#define SLJIT_CARRY\t\t\t12\n#define SLJIT_SET_CARRY\t\t\tSLJIT_SET(SLJIT_CARRY)\n#define SLJIT_NOT_CARRY\t\t\t13\n\n#define SLJIT_ATOMIC_STORED\t\t14\n#define SLJIT_SET_ATOMIC_STORED\t\tSLJIT_SET(SLJIT_ATOMIC_STORED)\n#define SLJIT_ATOMIC_NOT_STORED\t\t15\n\n/* Basic floating point comparison types.\n\n   Note: when the comparison result is unordered, their behaviour is unspecified. */\n\n#define SLJIT_F_EQUAL\t\t\t\t16\n#define SLJIT_SET_F_EQUAL\t\t\tSLJIT_SET(SLJIT_F_EQUAL)\n#define SLJIT_F_NOT_EQUAL\t\t\t17\n#define SLJIT_SET_F_NOT_EQUAL\t\t\tSLJIT_SET(SLJIT_F_EQUAL)\n#define SLJIT_F_LESS\t\t\t\t18\n#define SLJIT_SET_F_LESS\t\t\tSLJIT_SET(SLJIT_F_LESS)\n#define SLJIT_F_GREATER_EQUAL\t\t\t19\n#define SLJIT_SET_F_GREATER_EQUAL\t\tSLJIT_SET(SLJIT_F_LESS)\n#define SLJIT_F_GREATER\t\t\t\t20\n#define SLJIT_SET_F_GREATER\t\t\tSLJIT_SET(SLJIT_F_GREATER)\n#define SLJIT_F_LESS_EQUAL\t\t\t21\n#define SLJIT_SET_F_LESS_EQUAL\t\t\tSLJIT_SET(SLJIT_F_GREATER)\n\n/* Jumps when either argument contains a NaN value. */\n#define SLJIT_UNORDERED\t\t\t\t22\n#define SLJIT_SET_UNORDERED\t\t\tSLJIT_SET(SLJIT_UNORDERED)\n/* Jumps when neither argument contains a NaN value. */\n#define SLJIT_ORDERED\t\t\t\t23\n#define SLJIT_SET_ORDERED\t\t\tSLJIT_SET(SLJIT_UNORDERED)\n\n/* Ordered / unordered floating point comparison types.\n\n   Note: each comparison type has an ordered and unordered form. Some\n         architectures supports only either of them (see: sljit_cmp_info). */\n\n#define SLJIT_ORDERED_EQUAL\t\t\t24\n#define SLJIT_SET_ORDERED_EQUAL\t\t\tSLJIT_SET(SLJIT_ORDERED_EQUAL)\n#define SLJIT_UNORDERED_OR_NOT_EQUAL\t\t25\n#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL\tSLJIT_SET(SLJIT_ORDERED_EQUAL)\n#define SLJIT_ORDERED_LESS\t\t\t26\n#define SLJIT_SET_ORDERED_LESS\t\t\tSLJIT_SET(SLJIT_ORDERED_LESS)\n#define SLJIT_UNORDERED_OR_GREATER_EQUAL\t27\n#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL\tSLJIT_SET(SLJIT_ORDERED_LESS)\n#define SLJIT_ORDERED_GREATER\t\t\t28\n#define SLJIT_SET_ORDERED_GREATER\t\tSLJIT_SET(SLJIT_ORDERED_GREATER)\n#define SLJIT_UNORDERED_OR_LESS_EQUAL\t\t29\n#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL\tSLJIT_SET(SLJIT_ORDERED_GREATER)\n\n#define SLJIT_UNORDERED_OR_EQUAL\t\t30\n#define SLJIT_SET_UNORDERED_OR_EQUAL\t\tSLJIT_SET(SLJIT_UNORDERED_OR_EQUAL)\n#define SLJIT_ORDERED_NOT_EQUAL\t\t\t31\n#define SLJIT_SET_ORDERED_NOT_EQUAL\t\tSLJIT_SET(SLJIT_UNORDERED_OR_EQUAL)\n#define SLJIT_UNORDERED_OR_LESS\t\t\t32\n#define SLJIT_SET_UNORDERED_OR_LESS\t\tSLJIT_SET(SLJIT_UNORDERED_OR_LESS)\n#define SLJIT_ORDERED_GREATER_EQUAL\t\t33\n#define SLJIT_SET_ORDERED_GREATER_EQUAL\t\tSLJIT_SET(SLJIT_UNORDERED_OR_LESS)\n#define SLJIT_UNORDERED_OR_GREATER\t\t34\n#define SLJIT_SET_UNORDERED_OR_GREATER\t\tSLJIT_SET(SLJIT_UNORDERED_OR_GREATER)\n#define SLJIT_ORDERED_LESS_EQUAL\t\t35\n#define SLJIT_SET_ORDERED_LESS_EQUAL\t\tSLJIT_SET(SLJIT_UNORDERED_OR_GREATER)\n\n/* Unconditional jump types. */\n#define SLJIT_JUMP\t\t\t36\n/* Fast calling method. See the description above. */\n#define SLJIT_FAST_CALL\t\t\t37\n/* Default C calling convention. */\n#define SLJIT_CALL\t\t\t38\n/* Called function must be compiled by SLJIT.\n   See SLJIT_ENTER_REG_ARG option. */\n#define SLJIT_CALL_REG_ARG\t\t39\n\n/* The target can be changed during runtime (see: sljit_set_jump_addr). */\n#define SLJIT_REWRITABLE_JUMP\t\t0x10000\n/* When this flag is passed, the execution of the current function ends and\n   the called function returns to the caller of the current function. The\n   stack usage is reduced before the call, but it is not necessarily reduced\n   to zero. In the latter case the compiler needs to allocate space for some\n   arguments and the return address must be stored on the stack as well. */\n#define SLJIT_CALL_RETURN\t\t0x20000\n\n/* Emit a jump instruction. The destination is not set, only the type of the jump.\n    type must be between SLJIT_JUMP and SLJIT_FAST_CALL\n    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP\n\n   Flags: does not modify flags. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);\n\n/* Emit a C compiler (ABI) compatible function call.\n    type must be SLJIT_CALL or SLJIT_CALL_REG_ARG\n    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and/or SLJIT_CALL_RETURN\n    arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros\n\n   Flags: destroy all flags. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);\n\n/* Integer comparison operation. In most architectures it is implemented\n   as a compare (sljit_emit_op2u with SLJIT_SUB) operation followed by\n   an sljit_emit_jump. However, some architectures (e.g: ARM64 or RISCV)\n   may optimize the generated code further. It is suggested to use this\n   comparison form when appropriate.\n    type must be between SLJIT_EQUAL and SLJIT_SIG_LESS_EQUAL\n    type can be combined (or'ed) with SLJIT_32 or SLJIT_REWRITABLE_JUMP\n\n   Flags: may destroy flags. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Floating point comparison operation. In most architectures it is\n   implemented as a SLJIT_CMP_F32/64 operation (setting appropriate\n   flags) followed by a sljit_emit_jump. However, some architectures\n   (e.g: MIPS) may optimize the generated code further. It is suggested\n   to use this comparison form when appropriate.\n    type must be between SLJIT_F_EQUAL and SLJIT_ORDERED_LESS_EQUAL\n    type can be combined (or'ed) with SLJIT_32 or SLJIT_REWRITABLE_JUMP\n\n   Flags: destroy flags.\n   Note: when any operand is NaN the behaviour depends on the comparison type. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* The following flags are used by sljit_emit_op2cmpz(). */\n#define SLJIT_JUMP_IF_NON_ZERO\t\t0\n#define SLJIT_JUMP_IF_ZERO\t\tSLJIT_SET_Z\n\n/* Perform an integer arithmetic operation, then its result is compared to\n   zero. In most architectures it is implemented as an sljit_emit_op2\n   followed by an sljit_emit_jump. However, some architectures (e.g: RISCV)\n   may optimize the generated code further. It is suggested to use this\n   operation form when appropriate (e.g. for loops with counters).\n\n   op must be an sljit_emit_op2 operation where zero flag can be set,\n   op can be combined with SLJIT_SET_* status flag setters except\n     SLJIT_SET_Z, SLJIT_REWRITABLE_JUMP or SLJIT_JUMP_IF_* option bits.\n\n   Note: SLJIT_JUMP_IF_NON_ZERO is the default operation if neither\n      SLJIT_JUMP_IF_ZERO or SLJIT_JUMP_IF_NON_ZERO is specified.\n   Flags: sets the variable flag depending on op argument, the\n      zero flag is undefined. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\n/* Set the destination of the jump to this label. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);\n/* Set the destination address of the jump to this label. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);\n\n/* Emit an indirect jump or fast call.\n   Direct form: set src to SLJIT_IMM() and srcw to the address\n   Indirect form: any other valid addressing mode\n    type must be between SLJIT_JUMP and SLJIT_FAST_CALL\n\n   Flags: does not modify flags. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);\n\n/* Emit a C compiler (ABI) compatible function call.\n   Direct form: set src to SLJIT_IMM() and srcw to the address\n   Indirect form: any other valid addressing mode\n    type must be SLJIT_CALL or SLJIT_CALL_REG_ARG\n    type can be combined (or'ed) with SLJIT_CALL_RETURN\n    arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros\n\n   Flags: destroy all flags. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw);\n\n/* Perform an operation using the conditional flags as the second argument.\n   Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL.\n   The value represented by the type is 1, if the condition represented\n   by type is fulfilled, and 0 otherwise.\n\n   When op is SLJIT_MOV or SLJIT_MOV32:\n     Set dst to the value represented by the type (0 or 1).\n     Flags: - (does not modify flags)\n   When op is SLJIT_AND, SLJIT_AND32, SLJIT_OR, SLJIT_OR32, SLJIT_XOR, or SLJIT_XOR32\n     Performs the binary operation using dst as the first, and the value\n     represented by type as the second argument. Result is written into dst.\n     Flags: Z (may destroy flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type);\n\n/* The following flags are used by sljit_emit_select(). */\n\n/* Compare src1 and src2_reg operands before executing select\n   (i.e. converts the select operation to a min/max operation). */\n#define SLJIT_COMPARE_SELECT\tSLJIT_SET_Z\n\n/* Emit a conditional select instruction which moves src1 to dst_reg,\n   if the conditional flag is set, or src2_reg to dst_reg otherwise.\n   The conditional flag should be set before executing the select\n   instruction unless SLJIT_COMPARE_SELECT is specified.\n\n   type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL\n       when SLJIT_COMPARE_SELECT option is NOT specified\n   type must be between SLJIT_LESS and SLJIT_SET_SIG_LESS_EQUAL\n       when SLJIT_COMPARE_SELECT option is specified\n   type can be combined (or'ed) with SLJIT_32 to move 32 bit\n       register values instead of word sized ones\n   type can be combined (or'ed) with SLJIT_COMPARE_SELECT\n       which compares src1 and src2_reg before executing the select\n   dst_reg and src2_reg must be valid registers\n   src1 must be valid operand\n\n   Note: if src1 is a memory operand, its value\n         might be loaded even if the condition is false\n\n   Note: when SLJIT_COMPARE_SELECT is specified, the status flag\n         bits might not represent the result of a normal compare\n         operation, hence flags are not specified after the operation\n\n   Note: if sljit_has_cpu_feature(SLJIT_HAS_CMOV) returns with a non-zero value:\n         (a) conditional register move (dst_reg==src2_reg, src1 is register)\n             can be performed using a single instruction, except on RISCV,\n             where three instructions are needed\n         (b) conditional clearing (dst_reg==src2_reg, src1==SLJIT_IMM,\n             src1w==0) can be performed using a single instruction,\n             except on x86, where two instructions are needed\n\n   Flags:\n     When SLJIT_COMPARE_SELECT is NOT specified: - (does not modify flags)\n     When SLJIT_COMPARE_SELECT is specified: - (may destroy flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg);\n\n/* Emit a conditional floating point select instruction which moves\n   src1 to dst_reg, if the conditional flag is set, or src2_reg to\n   dst_reg otherwise. The conditional flag should be set before\n   executing the select instruction.\n\n   type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL\n   type can be combined (or'ed) with SLJIT_32 to move 32 bit\n       floating point values instead of 64 bit ones\n   dst_freg and src2_freg must be valid floating point registers\n   src1 must be valid operand\n\n   Note: if src1 is a memory operand, its value\n         might be loaded even if the condition is false.\n\n   Flags: - (does not modify flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg);\n\n/* The following flags are used by sljit_emit_mem(), sljit_emit_mem_update(),\n   sljit_emit_fmem(), and sljit_emit_fmem_update(). */\n\n/* Memory load operation. This is the default. */\n#define SLJIT_MEM_LOAD\t\t0x000000\n/* Memory store operation. */\n#define SLJIT_MEM_STORE\t\t0x000200\n\n/* The following flags are used by sljit_emit_mem() and sljit_emit_fmem(). */\n\n/* Load or stora data from an unaligned (byte aligned) address. */\n#define SLJIT_MEM_UNALIGNED\t0x000400\n/* Load or stora data from a 16 bit aligned address. */\n#define SLJIT_MEM_ALIGNED_16\t0x000800\n/* Load or stora data from a 32 bit aligned address. */\n#define SLJIT_MEM_ALIGNED_32\t0x001000\n\n/* The following flags are used by sljit_emit_mem_update(),\n   and sljit_emit_fmem_update(). */\n\n/* Base register is updated before the memory access (default). */\n#define SLJIT_MEM_PRE\t\t0x000000\n/* Base register is updated after the memory access. */\n#define SLJIT_MEM_POST\t\t0x000400\n\n/* When SLJIT_MEM_SUPP is passed, no instructions are emitted.\n   Instead the function returns with SLJIT_SUCCESS if the instruction\n   form is supported and SLJIT_ERR_UNSUPPORTED otherwise. This flag\n   allows runtime checking of available instruction forms. */\n#define SLJIT_MEM_SUPP\t\t0x000800\n\n/* The sljit_emit_mem emits instructions for various memory operations:\n\n   When SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_16 /\n        SLJIT_MEM_ALIGNED_32 is set in type argument:\n     Emit instructions for unaligned memory loads or stores. When\n     SLJIT_UNALIGNED is not defined, the only way to access unaligned\n     memory data is using sljit_emit_mem. Otherwise all operations (e.g.\n     sljit_emit_op1/2, or sljit_emit_fop1/2) supports unaligned access.\n     In general, the performance of unaligned memory accesses are often\n     lower than aligned and should be avoided.\n\n   When a pair of registers is passed in reg argument:\n     Emit instructions for moving data between a register pair and\n     memory. The register pair can be specified by the SLJIT_REG_PAIR\n     macro. The first register is loaded from or stored into the\n     location specified by the mem/memw arguments, and the end address\n     of this operation is the starting address of the data transfer\n     between the second register and memory. The type argument must\n     be SLJIT_MOV. The SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_*\n     options are allowed for this operation.\n\n   type must be between SLJIT_MOV and SLJIT_MOV_P and can be\n     combined (or'ed) with SLJIT_MEM_* flags\n   reg is a register or register pair, which is the source or\n     destination of the operation\n   mem must be a memory operand\n\n   Flags: - (does not modify flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw);\n\n/* Emit a single memory load or store with update instruction.\n   When the requested instruction form is not supported by the CPU,\n   it returns with SLJIT_ERR_UNSUPPORTED instead of emulating the\n   instruction. This allows specializing tight loops based on\n   the supported instruction forms (see SLJIT_MEM_SUPP flag).\n   Absolute address (SLJIT_MEM0) forms are never supported\n   and the base (first) register specified by the mem argument\n   must not be SLJIT_SP and must also be different from the\n   register specified by the reg argument.\n\n   type must be between SLJIT_MOV and SLJIT_MOV_P and can be\n     combined (or'ed) with SLJIT_MEM_* flags\n   reg is the source or destination register of the operation\n   mem must be a memory operand\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw);\n\n/* Same as sljit_emit_mem except the followings:\n\n   Loading or storing a pair of registers is not supported.\n\n   type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be\n     combined (or'ed) with SLJIT_MEM_* flags.\n   freg is the source or destination floating point register\n     of the operation\n   mem must be a memory operand\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw);\n\n/* Same as sljit_emit_mem_update except the followings:\n\n   type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be\n     combined (or'ed) with SLJIT_MEM_* flags\n   freg is the source or destination floating point register\n     of the operation\n   mem must be a memory operand\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw);\n\n/* The following options are used by several simd operations. */\n\n/* Load data into a vector register, this is the default */\n#define SLJIT_SIMD_LOAD\t\t\t0x000000\n/* Store data from a vector register */\n#define SLJIT_SIMD_STORE\t\t0x000001\n/* The vector register contains floating point values */\n#define SLJIT_SIMD_FLOAT\t\t0x000400\n/* Tests whether the operation is available */\n#define SLJIT_SIMD_TEST\t\t\t0x000800\n/* Move data to/from a 64 bit (8 byte) long vector register */\n#define SLJIT_SIMD_REG_64\t\t(3 << 12)\n/* Move data to/from a 128 bit (16 byte) long vector register */\n#define SLJIT_SIMD_REG_128\t\t(4 << 12)\n/* Move data to/from a 256 bit (32 byte) long vector register */\n#define SLJIT_SIMD_REG_256\t\t(5 << 12)\n/* Move data to/from a 512 bit (64 byte) long vector register */\n#define SLJIT_SIMD_REG_512\t\t(6 << 12)\n/* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */\n#define SLJIT_SIMD_ELEM_8\t\t(0 << 18)\n/* Element size is 16 bit long, usually cannot be combined with SLJIT_SIMD_FLOAT */\n#define SLJIT_SIMD_ELEM_16\t\t(1 << 18)\n/* Element size is 32 bit long */\n#define SLJIT_SIMD_ELEM_32\t\t(2 << 18)\n/* Element size is 64 bit long */\n#define SLJIT_SIMD_ELEM_64\t\t(3 << 18)\n/* Element size is 128 bit long */\n#define SLJIT_SIMD_ELEM_128\t\t(4 << 18)\n/* Element size is 256 bit long */\n#define SLJIT_SIMD_ELEM_256\t\t(5 << 18)\n\n/* The following options are used by sljit_emit_simd_mov()\n   and sljit_emit_simd_op2(). */\n\n/* Memory address is unaligned (this is the default) */\n#define SLJIT_SIMD_MEM_UNALIGNED\t(0 << 24)\n/* Memory address is 16 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_16\t(1 << 24)\n/* Memory address is 32 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_32\t(2 << 24)\n/* Memory address is 64 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_64\t(3 << 24)\n/* Memory address is 128 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_128\t(4 << 24)\n/* Memory address is 256 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_256\t(5 << 24)\n/* Memory address is 512 bit aligned */\n#define SLJIT_SIMD_MEM_ALIGNED_512\t(6 << 24)\n\n/* Moves data between a vector register and memory.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_* and\n     SLJIT_SIMD_MEM_* options\n   vreg is the source or destination vector register\n     of the operation\n   srcdst must be a memory operand or a vector register\n\n   Note:\n       The alignment and element size must be\n       less or equal than vector register size.\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw);\n\n/* Replicates a scalar value to all lanes of a vector\n   register.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_* options\n     except SLJIT_SIMD_STORE.\n   vreg is the destination vector register of the operation\n   src is the value which is replicated\n\n   Note:\n       The src == SLJIT_IMM and srcw == 0 can be used to\n       clear a register even when SLJIT_SIMD_FLOAT is set.\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* The following options are used by sljit_emit_simd_lane_mov(). */\n\n/* Clear all bits of the simd register before loading the lane. */\n#define SLJIT_SIMD_LANE_ZERO\t\t0x000002\n/* Sign extend the integer value stored from the lane. */\n#define SLJIT_SIMD_LANE_SIGNED\t\t0x000004\n\n/* Moves data between a vector register lane and a register or\n   memory. If the srcdst argument is a register, it must be\n   a floating point register when SLJIT_SIMD_FLOAT is specified,\n   or a general purpose register otherwise.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_* options\n     Further options:\n       SLJIT_32 - when SLJIT_SIMD_FLOAT is not set\n       SLJIT_SIMD_LANE_SIGNED - when SLJIT_SIMD_STORE\n           is set and SLJIT_SIMD_FLOAT is not set\n       SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD\n           is specified\n   vreg is the source or destination vector register\n     of the operation\n   lane_index is the index of the lane\n   srcdst is the destination operand for loads, and\n     source operand for stores\n\n   Note:\n       The elem size must be lower than register size.\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw);\n\n/* Replicates a scalar value from a lane to all lanes\n   of a vector register.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_* options\n     except SLJIT_SIMD_STORE.\n   vreg is the destination vector register of the operation\n   src is the vector register which lane is replicated\n   src_lane_index is the lane index of the src register\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index);\n\n/* The following options are used by sljit_emit_simd_load_extend(). */\n\n/* Sign extend the integer elements */\n#define SLJIT_SIMD_EXTEND_SIGNED\t0x000002\n/* Extend data to 16 bit */\n#define SLJIT_SIMD_EXTEND_16\t\t(1 << 24)\n/* Extend data to 32 bit */\n#define SLJIT_SIMD_EXTEND_32\t\t(2 << 24)\n/* Extend data to 64 bit */\n#define SLJIT_SIMD_EXTEND_64\t\t(3 << 24)\n\n/* Extend elements and stores them in a vector register.\n   The extension operation increases the size of the\n   elements (e.g. from 16 bit to 64 bit). For integer\n   values, the extension can be signed or unsigned.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_*, and\n     SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE\n   vreg is the destination vector register of the operation\n   src must be a memory operand or a vector register.\n     In the latter case, the source elements are stored\n     in the lower half of the register.\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw);\n\n/* Extract the highest bit (usually the sign bit) from\n   each elements of a vector.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_* and SLJIT_32\n     options except SLJIT_SIMD_LOAD\n   vreg is the source vector register of the operation\n   dst is the destination operand\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw);\n\n/* The following operations are used by sljit_emit_simd_op2(). */\n\n/* Binary 'and' operation */\n#define SLJIT_SIMD_OP2_AND\t\t0x000001\n/* Binary 'or' operation */\n#define SLJIT_SIMD_OP2_OR\t\t0x000002\n/* Binary 'xor' operation */\n#define SLJIT_SIMD_OP2_XOR\t\t0x000003\n/* Shuffle bytes of src1 using the indicies in src2 */\n#define SLJIT_SIMD_OP2_SHUFFLE\t\t0x000004\n\n/* Perform simd operations using vector registers.\n\n   If the operation is not supported, it returns with\n   SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,\n   it does not emit any instructions.\n\n   type must be a combination of SLJIT_SIMD_*, SLJIT_SIMD_MEM_*\n     and SLJIT_SIMD_OP2_* options except SLJIT_SIMD_LOAD\n     and SLJIT_SIMD_STORE\n   dst_vreg is the destination register of the operation\n   src1_vreg is the first source register of the operation\n   src2 is the second source operand of the operation\n\n   Flags: - (does not modify flags) */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w);\n\n/* The following operations are used by sljit_emit_atomic_load() and\n   sljit_emit_atomic_store() operations. */\n\n/* Tests whether the atomic operation is available (does not generate\n   any instructions). When a load from is allowed, its corresponding\n   store form is allowed and vice versa. */\n#define SLJIT_ATOMIC_TEST 0x10000\n/* The compiler must generate compare and swap instruction.\n   When this bit is set, calling sljit_emit_atomic_load() is optional. */\n#define SLJIT_ATOMIC_USE_CAS 0x20000\n/* The compiler must generate load-acquire and store-release instructions.\n   When this bit is set, the temp_reg for sljit_emit_atomic_store is not used. */\n#define SLJIT_ATOMIC_USE_LS 0x40000\n\n/* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair\n   can perform an atomic read-modify-write operation. First, an unsigned\n   value must be loaded from memory using sljit_emit_atomic_load. Then,\n   the updated value must be written back to the same memory location by\n   sljit_emit_atomic_store. A thread can only perform a single atomic\n   operation at a time.\n\n   The following conditions must be satisfied, or the operation\n   is undefined:\n     - the address provided in mem_reg must be divisible by the size of\n       the value (only naturally aligned updates are supported)\n     - no memory operations are allowed between the load and store operations\n     - the memory operation (op) and the base address (stored in mem_reg)\n       passed to the load/store operations must be the same (the mem_reg\n       can be a different register, only its value must be the same)\n     - a store must always follow a load for the same transaction.\n\n   op must be between SLJIT_MOV and SLJIT_MOV_P\n   dst_reg is the register where the data will be loaded into\n   mem_reg is the base address of the memory load (it cannot be\n     SLJIT_SP or a virtual register on x86-32)\n\n   Flags: - (does not modify flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg);\n\n/* The sljit_emit_atomic_load and sljit_emit_atomic_store operations\n   allows performing an atomic read-modify-write operation. See the\n   description of sljit_emit_atomic_load.\n\n   op must be between SLJIT_MOV and SLJIT_MOV_P\n   src_reg is the register which value is stored into the memory\n   mem_reg is the base address of the memory store (it cannot be\n     SLJIT_SP or a virtual register on x86-32)\n   temp_reg is a scratch register, which must be initialized with\n     the value loaded into the dst_reg during the corresponding\n     sljit_emit_atomic_load operation, or the operation is undefined.\n     The temp_reg register preserves its value, if the memory store\n     is successful. Otherwise, its value is undefined.\n\n   Flags: ATOMIC_STORED\n     if ATOMIC_STORED flag is set, it represents that the memory\n     is updated with a new value. Otherwise the memory is unchanged. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg);\n\n/* Copies the base address of SLJIT_SP + offset to dst. The offset can\n   represent the starting address of a value in the local data (stack).\n   The offset is not limited by the local data limits, it can be any value.\n   For example if an array of bytes are stored on the stack from\n   offset 0x40, and R0 contains the offset of an array item plus 0x120,\n   this item can be changed by two SLJIT instructions:\n\n   sljit_get_local_base(compiler, SLJIT_R1, 0, 0x40 - 0x120);\n   sljit_emit_op1(compiler, SLJIT_MOV_U8, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_IMM, 0x5);\n\n   Flags: - (may destroy flags) */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);\n\n/* Store a value that can be changed at runtime. The constant\n   can be managed by sljit_get_const_addr and sljit_set_const.\n\n   op must be SLJIT_MOV, SLJIT_MOV32, SLJIT_MOV_S32,\n     SLJIT_MOV_U8, SLJIT_MOV32_U8\n\n   Note: when SLJIT_MOV_U8 is used, and dst is a register,\n         init_value supports a 9 bit signed value between [-256..255]\n\n   Flags: - (does not modify flags) */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value);\n\n/* Opcodes for sljit_emit_mov_addr. */\n\n/* The address is suitable for jump/call target. */\n#define SLJIT_MOV_ADDR 0\n/* The address is suitable for reading memory. */\n#define SLJIT_MOV_ABS_ADDR 1\n/* Add absolute address. */\n#define SLJIT_ADD_ABS_ADDR 2\n\n/* Store the value of a label (see: sljit_set_label / sljit_set_target)\n   Flags: - (does not modify flags) */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw);\n\n/* Returns the address of a label after sljit_generate_code is called, and\n   before the compiler is freed by sljit_free_compiler. It is recommended\n   to save these addresses elsewhere before sljit_free_compiler is called.\n\n   The address returned by sljit_get_label_addr is suitable for a jump/call\n   target, and the address returned by sljit_get_label_abs_addr is suitable\n   for reading memory. */\n\nstatic SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->u.addr; }\n#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)\nstatic SLJIT_INLINE sljit_uw sljit_get_label_abs_addr(struct sljit_label *label) { return label->u.addr & ~(sljit_uw)1; }\n#else /* !SLJIT_CONFIG_ARM_THUMB2 */\nstatic SLJIT_INLINE sljit_uw sljit_get_label_abs_addr(struct sljit_label *label) { return label->u.addr; }\n#endif /* SLJIT_CONFIG_ARM_THUMB2 */\n\n/* Returns the address of jump and const instructions after sljit_generate_code\n   is called, and before the compiler is freed by sljit_free_compiler. It is\n   recommended to save these addresses elsewhere before sljit_free_compiler is called. */\n\nstatic SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }\nstatic SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }\n\n/* Only the address and executable offset are required to perform dynamic\n   code modifications. See sljit_get_executable_offset function. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);\n/* The op opcode must be set to the same value that was passed to sljit_emit_const. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset);\n\n/* Only a single buffer is writable at a time, so sljit_read_only_buffer_end_writing()\n   must be called before sljit_read_only_buffer_start_writing() is called again. */\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_read_only_buffer_start_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset);\nSLJIT_API_FUNC_ATTRIBUTE void sljit_read_only_buffer_end_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset);\n\n/* --------------------------------------------------------------------- */\n/*  CPU specific functions                                               */\n/* --------------------------------------------------------------------- */\n\n/* Types for sljit_get_register_index */\n\n/* General purpose (integer) registers. */\n#define SLJIT_GP_REGISTER 0\n/* Floating point registers. */\n#define SLJIT_FLOAT_REGISTER 1\n\n/* The following function is a helper function for sljit_emit_op_custom.\n   It returns with the real machine register index ( >=0 ) of any registers.\n\n   When type is SLJIT_GP_REGISTER:\n      reg must be an SLJIT_R(i), SLJIT_S(i), or SLJIT_SP register\n\n   When type is SLJIT_FLOAT_REGISTER:\n      reg must be an SLJIT_FR(i) or SLJIT_FS(i) register\n\n   When type is SLJIT_SIMD_REG_64 / 128 / 256 / 512 :\n      reg must be an SLJIT_FR(i) or SLJIT_FS(i) register\n\n   Note: it returns with -1 for unknown registers, such as virtual\n         registers on x86-32 or unsupported simd registers. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg);\n\n/* Any instruction can be inserted into the instruction stream by\n   sljit_emit_op_custom. It has a similar purpose as inline assembly.\n   The size parameter must match to the instruction size of the target\n   architecture:\n\n         x86: 0 < size <= 15, the instruction argument can be byte aligned.\n      Thumb2: if size == 2, the instruction argument must be 2 byte aligned.\n              if size == 4, the instruction argument must be 4 byte aligned.\n       s390x: size can be 2, 4, or 6, the instruction argument can be byte aligned.\n   Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size);\n\n/* Flags were set by a 32 bit operation. */\n#define SLJIT_CURRENT_FLAGS_32\t\t\tSLJIT_32\n\n/* Flags were set by an ADD or ADDC operations. */\n#define SLJIT_CURRENT_FLAGS_ADD\t\t\t0x01\n/* Flags were set by a SUB or SUBC operation. */\n#define SLJIT_CURRENT_FLAGS_SUB\t\t\t0x02\n\n/* Flags were set by sljit_emit_op2u with SLJIT_SUB opcode.\n   Must be combined with SLJIT_CURRENT_FLAGS_SUB. */\n#define SLJIT_CURRENT_FLAGS_COMPARE\t\t0x04\n\n/* Flags were set by sljit_emit_op2cmpz operation. */\n#define SLJIT_CURRENT_FLAGS_OP2CMPZ\t\t0x08\n\n/* Define the currently available CPU status flags. It is usually used after\n   an sljit_emit_label or sljit_emit_op_custom operations to define which CPU\n   status flags are available.\n\n   The current_flags must be a valid combination of SLJIT_SET_* and\n   SLJIT_CURRENT_FLAGS_* constants. */\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,\n\tsljit_s32 current_flags);\n\n/* --------------------------------------------------------------------- */\n/*  Serialization functions                                              */\n/* --------------------------------------------------------------------- */\n\n/* Label/jump/const enumeration functions. The items in each group\n   are enumerated in creation order. Serialization / deserialization\n   preserves this order for each group. For example the fifth label\n   after deserialization refers to the same machine code location as\n   the fifth label before the serialization. */\nstatic SLJIT_INLINE struct sljit_label *sljit_get_first_label(struct sljit_compiler *compiler) { return compiler->labels; }\nstatic SLJIT_INLINE struct sljit_jump *sljit_get_first_jump(struct sljit_compiler *compiler) { return compiler->jumps; }\nstatic SLJIT_INLINE struct sljit_const *sljit_get_first_const(struct sljit_compiler *compiler) { return compiler->consts; }\n\nstatic SLJIT_INLINE struct sljit_label *sljit_get_next_label(struct sljit_label *label) { return label->next; }\nstatic SLJIT_INLINE struct sljit_jump *sljit_get_next_jump(struct sljit_jump *jump) { return jump->next; }\nstatic SLJIT_INLINE struct sljit_const *sljit_get_next_const(struct sljit_const *const_) { return const_->next; }\n\n/* A number starting from 0 is assigned to each label, which\nrepresents its creation index. The first label created by the\ncompiler has index 0, the second one has index 1, the third one\nhas index 2, and so on. The returned value is unspecified after\nsljit_generate_code() is called.\n\nIt is recommended to use this function to get the creation index\nof a label, since sljit_emit_label() may return with the last label,\nif no code is generated since the last sljit_emit_label() call. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_uw sljit_get_label_index(struct sljit_label *label);\n\n/* The sljit_jump_has_label() and sljit_jump_has_target() functions\nreturns non-zero value if a label or target is set for the jump\nrespectively. Both may return with a zero value. The other two\nfunctions return the value assigned to the jump. */\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump);\nstatic SLJIT_INLINE struct sljit_label *sljit_jump_get_label(struct sljit_jump *jump) { return jump->u.label; }\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump);\nstatic SLJIT_INLINE sljit_uw sljit_jump_get_target(struct sljit_jump *jump) { return jump->u.target; }\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump);\n\n/* Option bits for sljit_serialize_compiler. */\n\n/* When debugging is enabled, the serialized buffer contains\ndebugging information unless this option is specified. */\n#define SLJIT_SERIALIZE_IGNORE_DEBUG\t\t0x1\n\n/* Serialize the internal structure of the compiler into a buffer.\nIf the serialization is successful, the returned value is a newly\nallocated buffer which is allocated by the memory allocator assigned\nto the compiler. Otherwise the returned value is NULL. Unlike\nsljit_generate_code(), serialization does not modify the internal\nstate of the compiler, so the code generation can be continued.\n\n  options must be the combination of SLJIT_SERIALIZE_* option bits\n  size is an output argument, which is set to the byte size of\n    the result buffer if the operation is successful\n\nNotes:\n  - This function is useful for ahead-of-time compilation (AOT).\n  - The returned buffer must be freed later by the caller.\n    The SLJIT_FREE() macro is suitable for this purpose:\n    SLJIT_FREE(returned_buffer, sljit_get_allocator_data(compiler))\n  - Memory allocated by sljit_alloc_memory() is not serialized.\n  - The type of the returned buffer is sljit_uw* to emphasize that\n    the buffer is word aligned. However, the 'size' output argument\n    contains the byte size, so this value is always divisible by\n    sizeof(sljit_uw).\n*/\nSLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_uw *size);\n\n/* Construct a new compiler instance from a buffer produced by\nsljit_serialize_compiler(). If the operation is successful, the new\ncompiler instance is returned. Otherwise the returned value is NULL.\n\n  buffer points to a word aligned memory data which was\n    created by sljit_serialize_compiler()\n  size is the byte size of the buffer\n  options must be 0\n  allocator_data specify an allocator specific data, see\n                 sljit_create_compiler() for further details\n\nNotes:\n  - Labels assigned to jumps are restored with their\n    corresponding label in the label set created by\n    the deserializer. Target addresses assigned to\n    jumps are also restored. Uninitialized jumps\n    remain uninitialized.\n  - After the deserialization, sljit_generate_code() does\n    not need to be the next operation on the returned\n    compiler, the code generation can be continued.\n    Even sljit_serialize_compiler() can be called again.\n  - When debugging is enabled, a buffers without debug\n    information cannot be deserialized.\n*/\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,\n\tsljit_s32 options, void *allocator_data);\n\n/* --------------------------------------------------------------------- */\n/*  Miscellaneous utility functions                                      */\n/* --------------------------------------------------------------------- */\n\n/* Get the human readable name of the platform. Can be useful on platforms\n   like ARM, where ARM and Thumb2 functions can be mixed, and it is useful\n   to know the type of the code generator. */\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);\n\n/* Portable helper function to get an offset of a member.\n   Same as offsetof() macro defined in stddef.h */\n#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)\n\n#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)\n\n/* The sljit_stack structure and its manipulation functions provides\n   an implementation for a top-down stack. The stack top is stored\n   in the end field of the sljit_stack structure and the stack goes\n   down to the min_start field, so the memory region reserved for\n   this stack is between min_start (inclusive) and end (exclusive)\n   fields. However the application can only use the region between\n   start (inclusive) and end (exclusive) fields. The sljit_stack_resize\n   function can be used to extend this region up to min_start.\n\n   This feature uses the \"address space reserve\" feature of modern\n   operating systems. Instead of allocating a large memory block\n   applications can allocate a small memory region and extend it\n   later without moving the content of the memory area. Therefore\n   after a successful resize by sljit_stack_resize all pointers into\n   this region are still valid.\n\n   Note:\n     this structure may not be supported by all operating systems.\n     end and max_limit fields are aligned to PAGE_SIZE bytes (usually\n         4 Kbyte or more).\n     stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */\n\nstruct sljit_stack {\n\t/* User data, anything can be stored here.\n\t   Initialized to the same value as the end field. */\n\tsljit_u8 *top;\n/* These members are read only. */\n\t/* End address of the stack */\n\tsljit_u8 *end;\n\t/* Current start address of the stack. */\n\tsljit_u8 *start;\n\t/* Lowest start address of the stack. */\n\tsljit_u8 *min_start;\n};\n\n/* Allocates a new stack. Returns NULL if unsuccessful.\n   Note: see sljit_create_compiler for the explanation of allocator_data. */\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);\nSLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);\n\n/* Can be used to increase (extend) or decrease (shrink) the stack\n   memory area. Returns with new_start if successful and NULL otherwise.\n   It always fails if new_start is less than min_start or greater or equal\n   than end fields. The fields of the stack are not changed if the returned\n   value is NULL (the current memory content is never lost). */\nSLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);\n\n#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */\n\n#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n\n/* Get the entry address of a given function (signed, unsigned result). */\n#define SLJIT_FUNC_ADDR(func_name)\t((sljit_sw)func_name)\n#define SLJIT_FUNC_UADDR(func_name)\t((sljit_uw)func_name)\n\n#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */\n\n/* All JIT related code should be placed in the same context (library, binary, etc.). */\n\n/* Get the entry address of a given function (signed, unsigned result). */\n#define SLJIT_FUNC_ADDR(func_name)\t(*(sljit_sw*)(void*)func_name)\n#define SLJIT_FUNC_UADDR(func_name)\t(*(sljit_uw*)(void*)func_name)\n\n/* For powerpc64, the function pointers point to a context descriptor. */\nstruct sljit_function_context {\n\tsljit_uw addr;\n\tsljit_uw r2;\n\tsljit_uw r11;\n};\n\n/* Fill the context arguments using the addr and the function.\n   If func_ptr is NULL, it will not be set to the address of context\n   If addr is NULL, the function address also comes from the func pointer. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func);\n\n#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */\n\n#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)\n/* Free unused executable memory. The allocator keeps some free memory\n   around to reduce the number of OS executable memory allocations.\n   This improves performance since these calls are costly. However\n   it is sometimes desired to free all unused memory regions, e.g.\n   before the application terminates. */\nSLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);\n#endif /* SLJIT_EXECUTABLE_ALLOCATOR */\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif /* __cplusplus */\n\n#endif /* SLJIT_LIR_H_ */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifdef __SOFTFP__\n#define ARM_ABI_INFO \" ABI:softfp\"\n#else\n#define ARM_ABI_INFO \" ABI:hardfp\"\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\treturn \"ARMv7\" SLJIT_CPUINFO ARM_ABI_INFO;\n#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\treturn \"ARMv6\" SLJIT_CPUINFO ARM_ABI_INFO;\n#else\n#error \"Internal error: Unknown ARM architecture\"\n#endif\n}\n\n/* Length of an instruction word. */\ntypedef sljit_u32 sljit_ins;\n\n/* Last register + 1. */\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_PC\t\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\n/* In ARM instruction words.\n   Cache lines are usually 32 byte aligned. */\n#define CONST_POOL_ALIGNMENT\t8\n#define CONST_POOL_EMPTY\t0xffffffff\n\n#define ALIGN_INSTRUCTION(ptr) \\\n\t(sljit_ins*)(((sljit_ins)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1))\n#define MAX_DIFFERENCE(max_diff) \\\n\t(((max_diff) / (sljit_s32)sizeof(sljit_ins)) - (CONST_POOL_ALIGNMENT - 1))\n\n/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {\n\t0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15\n};\n\nstatic const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {\n\t0,\n\t0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,\n\t7, 6,\n\t0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,\n\t7, 6\n};\n\nstatic const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {\n\t0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1\n};\n\n#define RM(rm) ((sljit_ins)reg_map[rm])\n#define RM8(rm) ((sljit_ins)reg_map[rm] << 8)\n#define RD(rd) ((sljit_ins)reg_map[rd] << 12)\n#define RN(rn) ((sljit_ins)reg_map[rn] << 16)\n\n#define VM(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5))\n#define VD(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22))\n#define VN(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7))\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n/* The instruction includes the AL condition.\n   INST_NAME - CONDITIONAL remove this flag. */\n#define COND_MASK\t0xf0000000\n#define CONDITIONAL\t0xe0000000\n#define PUSH_POOL\t0xff000000\n\n#define ADC\t\t0xe0a00000\n#define ADD\t\t0xe0800000\n#define AND\t\t0xe0000000\n#define B\t\t0xea000000\n#define BIC\t\t0xe1c00000\n#define BKPT\t\t0xe1200070\n#define BL\t\t0xeb000000\n#define BLX\t\t0xe12fff30\n#define BX\t\t0xe12fff10\n#define CLZ\t\t0xe16f0f10\n#define CMN\t\t0xe1600000\n#define CMP\t\t0xe1400000\n#define DMB_SY\t\t0xf57ff05f\n#define EOR\t\t0xe0200000\n#define LDR\t\t0xe5100000\n#define LDR_POST\t0xe4100000\n#define LDREX\t\t0xe1900f9f\n#define LDREXB\t\t0xe1d00f9f\n#define LDREXH\t\t0xe1f00f9f\n#define MLA\t\t0xe0200090\n#define MOV\t\t0xe1a00000\n#define MUL\t\t0xe0000090\n#define MVN\t\t0xe1e00000\n#define NOP\t\t0xe1a00000\n#define ORR\t\t0xe1800000\n#define PUSH\t\t0xe92d0000\n#define POP\t\t0xe8bd0000\n#define REV\t\t0xe6bf0f30\n#define REV16\t\t0xe6bf0fb0\n#define RSB\t\t0xe0600000\n#define RSC\t\t0xe0e00000\n#define SBC\t\t0xe0c00000\n#define SMULL\t\t0xe0c00090\n#define STR\t\t0xe5000000\n#define STREX\t\t0xe1800f90\n#define STREXB\t\t0xe1c00f90\n#define STREXH\t\t0xe1e00f90\n#define SUB\t\t0xe0400000\n#define SXTB\t\t0xe6af0070\n#define SXTH\t\t0xe6bf0070\n#define TST\t\t0xe1000000\n#define UMULL\t\t0xe0800090\n#define UXTB\t\t0xe6ef0070\n#define UXTH\t\t0xe6ff0070\n#define VABS_F32\t0xeeb00ac0\n#define VADD_F32\t0xee300a00\n#define VAND\t\t0xf2000110\n#define VCMP_F32\t0xeeb40a40\n#define VCVT_F32_S32\t0xeeb80ac0\n#define VCVT_F32_U32\t0xeeb80a40\n#define VCVT_F64_F32\t0xeeb70ac0\n#define VCVT_S32_F32\t0xeebd0ac0\n#define VDIV_F32\t0xee800a00\n#define VDUP\t\t0xee800b10\n#define VDUP_s\t\t0xf3b00c00\n#define VEOR\t\t0xf3000110\n#define VLD1\t\t0xf4200000\n#define VLD1_r\t\t0xf4a00c00\n#define VLD1_s\t\t0xf4a00000\n#define VLDR_F32\t0xed100a00\n#define VMOV_F32\t0xeeb00a40\n#define VMOV\t\t0xee000a10\n#define VMOV2\t\t0xec400a10\n#define VMOV_i\t\t0xf2800010\n#define VMOV_s\t\t0xee000b10\n#define VMOVN\t\t0xf3b20200\n#define VMRS\t\t0xeef1fa10\n#define VMUL_F32\t0xee200a00\n#define VNEG_F32\t0xeeb10a40\n#define VORR\t\t0xf2200110\n#define VPOP\t\t0xecbd0b00\n#define VPUSH\t\t0xed2d0b00\n#define VSHLL\t\t0xf2800a10\n#define VSHR\t\t0xf2800010\n#define VSRA\t\t0xf2800110\n#define VST1\t\t0xf4000000\n#define VST1_s\t\t0xf4800000\n#define VSTR_F32\t0xed000a00\n#define VSUB_F32\t0xee300a40\n#define VTBL\t\t0xf3b00800\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n/* Arm v7 specific instructions. */\n#define MOVT\t\t0xe3400000\n#define MOVW\t\t0xe3000000\n#define RBIT\t\t0xe6ff0f30\n#endif\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\nstatic sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))\n\t\tfr -= SLJIT_F64_SECOND(0);\n\n\treturn (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))\n\t\t|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)\n\t\t|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));\n}\n\nstatic sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)\n{\n\tsljit_s32 vr_low = vr;\n\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (SLJIT_SIMD_GET_REG_SIZE(type) == 4) {\n\t\tvr += (vr & 0x1);\n\t\tvr_low = vr - 1;\n\t}\n\n\treturn (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches))\n\t\t|| (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0)\n\t\t|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));\n}\n\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\nstatic sljit_s32 push_cpool(struct sljit_compiler *compiler)\n{\n\t/* Pushing the constant pool into the instruction stream. */\n\tsljit_ins* inst;\n\tsljit_uw* cpool_ptr;\n\tsljit_uw* cpool_end;\n\tsljit_s32 i;\n\n\t/* The label could point the address after the constant pool. */\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\tcompiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;\n\n\tSLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);\n\tinst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!inst);\n\tcompiler->size++;\n\t*inst = 0xff000000 | compiler->cpool_fill;\n\n\tfor (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {\n\t\tinst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\t\tFAIL_IF(!inst);\n\t\tcompiler->size++;\n\t\t*inst = 0;\n\t}\n\n\tcpool_ptr = compiler->cpool;\n\tcpool_end = cpool_ptr + compiler->cpool_fill;\n\twhile (cpool_ptr < cpool_end) {\n\t\tinst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\t\tFAIL_IF(!inst);\n\t\tcompiler->size++;\n\t\t*inst = *cpool_ptr++;\n\t}\n\tcompiler->cpool_diff = CONST_POOL_EMPTY;\n\tcompiler->cpool_fill = 0;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst)\n{\n\tsljit_ins* ptr;\n\n\tif (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))\n\t\tFAIL_IF(push_cpool(compiler));\n\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\t*ptr = inst;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal)\n{\n\tsljit_ins* ptr;\n\tsljit_uw cpool_index = CPOOL_SIZE;\n\tsljit_uw* cpool_ptr;\n\tsljit_uw* cpool_end;\n\tsljit_u8* cpool_unique_ptr;\n\n\tif (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))\n\t\tFAIL_IF(push_cpool(compiler));\n\telse if (compiler->cpool_fill > 0) {\n\t\tcpool_ptr = compiler->cpool;\n\t\tcpool_end = cpool_ptr + compiler->cpool_fill;\n\t\tcpool_unique_ptr = compiler->cpool_unique;\n\t\tdo {\n\t\t\tif ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {\n\t\t\t\tcpool_index = (sljit_uw)(cpool_ptr - compiler->cpool);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcpool_ptr++;\n\t\t\tcpool_unique_ptr++;\n\t\t} while (cpool_ptr < cpool_end);\n\t}\n\n\tif (cpool_index == CPOOL_SIZE) {\n\t\t/* Must allocate a new entry in the literal pool. */\n\t\tif (compiler->cpool_fill < CPOOL_SIZE) {\n\t\t\tcpool_index = compiler->cpool_fill;\n\t\t\tcompiler->cpool_fill++;\n\t\t}\n\t\telse {\n\t\t\tFAIL_IF(push_cpool(compiler));\n\t\t\tcpool_index = 0;\n\t\t\tcompiler->cpool_fill = 1;\n\t\t}\n\t}\n\n\tSLJIT_ASSERT((inst & 0xfff) == 0);\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\t*ptr = inst | cpool_index;\n\n\tcompiler->cpool[cpool_index] = literal;\n\tcompiler->cpool_unique[cpool_index] = 0;\n\tif (compiler->cpool_diff == CONST_POOL_EMPTY)\n\t\tcompiler->cpool_diff = compiler->size;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal)\n{\n\tsljit_ins* ptr;\n\n\tif (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))\n\t\tFAIL_IF(push_cpool(compiler));\n\n\tSLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\t*ptr = inst | compiler->cpool_fill;\n\n\tcompiler->cpool[compiler->cpool_fill] = literal;\n\tcompiler->cpool_unique[compiler->cpool_fill] = 1;\n\tcompiler->cpool_fill++;\n\tif (compiler->cpool_diff == CONST_POOL_EMPTY)\n\t\tcompiler->cpool_diff = compiler->size;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler)\n{\n\t/* Place for at least two instruction (doesn't matter whether the first has a literal). */\n\tif (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))\n\t\treturn push_cpool(compiler);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler)\n{\n\t/* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */\n\tSLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));\n\tSLJIT_ASSERT(reg_map[TMP_REG1] != 14);\n\n\treturn push_inst(compiler, BLX | RM(TMP_REG1));\n}\n\nstatic sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)\n{\n\tsljit_uw diff;\n\tsljit_uw ind;\n\tsljit_uw counter = 0;\n\tsljit_uw* clear_const_pool = const_pool;\n\tsljit_uw* clear_const_pool_end = const_pool + cpool_size;\n\n\tSLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);\n\t/* Set unused flag for all literals in the constant pool.\n\t   I.e.: unused literals can belong to branches, which can be encoded as B or BL.\n\t   We can \"compress\" the constant pool by discarding these literals. */\n\twhile (clear_const_pool < clear_const_pool_end)\n\t\t*clear_const_pool++ = (sljit_uw)(-1);\n\n\twhile (last_pc_patch < code_ptr) {\n\t\t/* Data transfer instruction with Rn == r15. */\n\t\tif ((*last_pc_patch & 0x0e4f0000) == 0x040f0000) {\n\t\t\tdiff = (sljit_uw)(const_pool - last_pc_patch);\n\t\t\tind = (*last_pc_patch) & 0xfff;\n\n\t\t\t/* Must be a load instruction with immediate offset. */\n\t\t\tSLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));\n\t\t\tif ((sljit_s32)const_pool[ind] < 0) {\n\t\t\t\tconst_pool[ind] = counter;\n\t\t\t\tind = counter;\n\t\t\t\tcounter++;\n\t\t\t}\n\t\t\telse\n\t\t\t\tind = const_pool[ind];\n\n\t\t\tSLJIT_ASSERT(diff >= 1);\n\t\t\tif (diff >= 2 || ind > 0) {\n\t\t\t\tdiff = (diff + (sljit_uw)ind - 2) << 2;\n\t\t\t\tSLJIT_ASSERT(diff <= 0xfff);\n\t\t\t\t*last_pc_patch = (*last_pc_patch & ~(sljit_uw)0xfff) | diff;\n\t\t\t}\n\t\t\telse\n\t\t\t\t*last_pc_patch = (*last_pc_patch & ~(sljit_uw)(0xfff | (1 << 23))) | 0x004;\n\t\t}\n\t\tlast_pc_patch++;\n\t}\n\treturn counter;\n}\n\n/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */\nstruct future_patch {\n\tstruct future_patch* next;\n\tsljit_s32 index;\n\tsljit_s32 value;\n};\n\nstatic sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)\n{\n\tsljit_u32 value;\n\tstruct future_patch *curr_patch, *prev_patch;\n\n\tSLJIT_UNUSED_ARG(compiler);\n\n\t/* Using the values generated by patch_pc_relative_loads. */\n\tif (!*first_patch)\n\t\tvalue = cpool_start_address[cpool_current_index];\n\telse {\n\t\tcurr_patch = *first_patch;\n\t\tprev_patch = NULL;\n\t\twhile (1) {\n\t\t\tif (!curr_patch) {\n\t\t\t\tvalue = cpool_start_address[cpool_current_index];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ((sljit_uw)curr_patch->index == cpool_current_index) {\n\t\t\t\tvalue = (sljit_uw)curr_patch->value;\n\t\t\t\tif (prev_patch)\n\t\t\t\t\tprev_patch->next = curr_patch->next;\n\t\t\t\telse\n\t\t\t\t\t*first_patch = curr_patch->next;\n\t\t\t\tSLJIT_FREE(curr_patch, compiler->allocator_data);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tprev_patch = curr_patch;\n\t\t\tcurr_patch = curr_patch->next;\n\t\t}\n\t}\n\n\tif ((sljit_sw)value >= 0) {\n\t\tif (value > cpool_current_index) {\n\t\t\tcurr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data);\n\t\t\tif (!curr_patch) {\n\t\t\t\twhile (*first_patch) {\n\t\t\t\t\tcurr_patch = *first_patch;\n\t\t\t\t\t*first_patch = (*first_patch)->next;\n\t\t\t\t\tSLJIT_FREE(curr_patch, compiler->allocator_data);\n\t\t\t\t}\n\t\t\t\treturn SLJIT_ERR_ALLOC_FAILED;\n\t\t\t}\n\t\t\tcurr_patch->next = *first_patch;\n\t\t\tcurr_patch->index = (sljit_sw)value;\n\t\t\tcurr_patch->value = (sljit_sw)cpool_start_address[value];\n\t\t\t*first_patch = curr_patch;\n\t\t}\n\t\tcpool_start_address[value] = *buf_ptr;\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\n#else\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst)\n{\n\tsljit_ins* ptr;\n\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\t*ptr = inst;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)\n{\n\tFAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | ((sljit_u32)imm & 0xfff)));\n\treturn push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | (((sljit_u32)imm >> 16) & 0xfff));\n}\n\n#endif\n\nstatic SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\tjump->addr = jump_addr;\n#endif\n\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\treturn 0;\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tif (jump->flags & IS_BL)\n\t\tcode_ptr--;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 8, executable_offset);\n\n\t/* Branch to Thumb code has not been optimized yet. */\n\tif (diff & 0x3)\n\t\treturn 0;\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tif (jump->flags & IS_BL) {\n\t\tif (diff <= 0x01ffffff && diff >= -0x02000000) {\n\t\t\t*code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);\n\t\t\tjump->flags |= PATCH_B;\n\t\t\treturn 1;\n\t\t}\n\t} else if (diff <= 0x01ffffff && diff >= -0x02000000) {\n\t\t*code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);\n\t\tjump->flags |= PATCH_B;\n\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tif (diff <= 0x01ffffff && diff >= -0x02000000) {\n\t\t*code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (*code_ptr & COND_MASK);\n\t\tjump->flags |= PATCH_B;\n\t\treturn 1;\n\t}\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\treturn 0;\n}\n\nstatic void set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)\n{\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tsljit_ins *ptr = (sljit_ins*)jump_ptr;\n\tsljit_ins *inst = (sljit_ins*)ptr[0];\n\tsljit_ins mov_pc = ptr[1];\n\tsljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);\n\tsljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);\n\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (diff <= 0x7fffff && diff >= -0x800000) {\n\t\t/* Turn to branch. */\n\t\tif (!bl) {\n\t\t\tif (flush_cache) {\n\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\t\t}\n\t\t\tinst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);\n\t\t\tif (flush_cache) {\n\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (flush_cache) {\n\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\t\t}\n\t\t\tinst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);\n\t\t\tinst[1] = NOP;\n\t\t\tif (flush_cache) {\n\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* Get the position of the constant. */\n\t\tif (mov_pc & (1 << 23))\n\t\t\tptr = inst + ((mov_pc & 0xfff) >> 2) + 2;\n\t\telse\n\t\t\tptr = inst + 1;\n\n\t\tif (*inst != mov_pc) {\n\t\t\tif (flush_cache) {\n\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);\n\t\t\t}\n\t\t\tinst[0] = mov_pc;\n\t\t\tif (!bl) {\n\t\t\t\tif (flush_cache) {\n\t\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\t\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tinst[1] = BLX | RM(TMP_REG1);\n\t\t\t\tif (flush_cache) {\n\t\t\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\t\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);\n\t\t}\n\n\t\t*ptr = new_addr;\n\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);\n\t\t}\n\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tsljit_ins *inst = (sljit_ins*)jump_ptr;\n\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t}\n\n\tinst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);\n\tinst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t}\n#endif /* SLJIT_CONFIG_ARM_V6 */\n}\n\nstatic sljit_uw get_imm(sljit_uw imm);\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm);\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);\n\nstatic void set_const_value(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache)\n{\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tsljit_ins *ptr = (sljit_ins*)addr;\n\tsljit_ins *inst = (sljit_ins*)ptr[0];\n\tsljit_uw ldr_literal = ptr[1];\n\tsljit_uw src2;\n\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tsrc2 = get_imm(new_constant);\n\tif (src2) {\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\t}\n\n\t\t*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;\n\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\t}\n\t\treturn;\n\t}\n\n\tsrc2 = get_imm(~new_constant);\n\tif (src2) {\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\t}\n\n\t\t*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;\n\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (ldr_literal & (1 << 23))\n\t\tptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;\n\telse\n\t\tptr = inst + 1;\n\n\tif (*inst != ldr_literal) {\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\t}\n\n\t\t*inst = ldr_literal;\n\n\t\tif (flush_cache) {\n\t\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\t}\n\t}\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);\n\t}\n\n\t*ptr = new_constant;\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);\n\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tsljit_ins *inst = (sljit_ins*)addr;\n\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t}\n\n\tinst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);\n\tinst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);\n\n\tif (flush_cache) {\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t}\n#endif /* SLJIT_CONFIG_ARM_V6 */\n}\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse {\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t}\n\n\t/* The pc+8 offset is represented by the 2 * SSIZE_OF(ins) below. */\n\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif ((diff & 0x3) == 0 && diff <= (0x3fc + 2 * SSIZE_OF(ins)) && diff >= (-0x3fc + 2 * SSIZE_OF(ins))) {\n\t\tjump->flags |= PATCH_B;\n\t\treturn 0;\n\t}\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\treturn 0;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\treturn 1;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n}\n\nstatic SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE - 1;\n\n\t\t\tif (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) {\n\t\t\t\t/* Unit size: instruction. */\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins)))\n\t\t\t\t\ttotal_size = 1 - 1;\n\t\t\t}\n\n\t\t\tsize_reduce += JUMP_MAX_SIZE - 1 - total_size;\n\t\t} else {\n\t\t\t/* Real size minus 1. Unit size: instruction. */\n\t\t\ttotal_size = 1;\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff <= 0xff + 2 && diff >= -0xff + 2)\n\t\t\t\t\ttotal_size = 0;\n\t\t\t}\n\n\t\t\tsize_reduce += 1 - total_size;\n\t\t}\n\n\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *code;\n\tsljit_ins *code_ptr;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_uw word_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\tsljit_uw addr;\n\tsljit_sw diff;\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tsljit_uw cpool_size;\n\tsljit_uw cpool_skip_alignment;\n\tsljit_uw cpool_current_index;\n\tsljit_ins *cpool_start_address;\n\tsljit_ins *last_pc_patch;\n\tstruct future_patch *first_patch;\n#endif\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\t/* Second code generation pass. */\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tcompiler->size += (compiler->patches << 1);\n\tif (compiler->cpool_fill > 0)\n\t\tcompiler->size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\treduce_code_size(compiler);\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\tcode = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tcpool_size = 0;\n\tcpool_skip_alignment = 0;\n\tcpool_current_index = 0;\n\tcpool_start_address = NULL;\n\tfirst_patch = NULL;\n\tlast_pc_patch = code;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tcode_ptr = code;\n\tword_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 2);\n\t\tdo {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\tif (cpool_size > 0) {\n\t\t\t\tif (cpool_skip_alignment > 0) {\n\t\t\t\t\tbuf_ptr++;\n\t\t\t\t\tcpool_skip_alignment--;\n\t\t\t\t} else {\n\t\t\t\t\tif (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {\n\t\t\t\t\t\tSLJIT_FREE_EXEC(code, exec_allocator_data);\n\t\t\t\t\t\tcompiler->error = SLJIT_ERR_ALLOC_FAILED;\n\t\t\t\t\t\treturn NULL;\n\t\t\t\t\t}\n\t\t\t\t\tbuf_ptr++;\n\t\t\t\t\tif (++cpool_current_index >= cpool_size) {\n\t\t\t\t\t\tSLJIT_ASSERT(!first_patch);\n\t\t\t\t\t\tcpool_size = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t\t\t\t*code_ptr = *buf_ptr++;\n\t\t\t\tif (next_min_addr == word_count) {\n\t\t\t\t\tSLJIT_ASSERT(!label || label->size >= word_count);\n\t\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= word_count);\n\t\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= word_count);\n\n\t\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\t\tlabel = label->next;\n\t\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\t\t\t\t\tif (detect_jump_type(jump, code_ptr, code, executable_offset))\n\t\t\t\t\t\t\t\tcode_ptr--;\n\t\t\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\t\tif (!detect_jump_type(jump, code_ptr, code, executable_offset)) {\n\t\t\t\t\t\t\t\tcode_ptr[2] = code_ptr[0];\n\t\t\t\t\t\t\t\taddr = ((code_ptr[0] & 0xf) << 12);\n\t\t\t\t\t\t\t\tcode_ptr[0] = MOVW | addr;\n\t\t\t\t\t\t\t\tcode_ptr[1] = MOVT | addr;\n\t\t\t\t\t\t\t\tcode_ptr += 2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tSLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t\t\t\t\t\t} else {\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\t\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\t\t\t\t\t\t\taddr = (sljit_uw)code_ptr;\n\t\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\t\tjump->addr = addr;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tjump = jump->next;\n\t\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t\t}\n\n\t\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t\t}\n\t\t\t\tcode_ptr++;\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\t} else {\n\t\t\t\t/* Fortunately, no need to shift. */\n\t\t\t\tcpool_size = *buf_ptr++ & ~PUSH_POOL;\n\t\t\t\tSLJIT_ASSERT(cpool_size > 0);\n\t\t\t\tcpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);\n\t\t\t\tcpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);\n\t\t\t\tif (cpool_current_index > 0) {\n\t\t\t\t\t/* Unconditional branch. */\n\t\t\t\t\t*code_ptr = B | (((sljit_ins)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);\n\t\t\t\t\tcode_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index);\n\t\t\t\t}\n\t\t\t\tcpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;\n\t\t\t\tcpool_current_index = 0;\n\t\t\t\tlast_pc_patch = code_ptr;\n\t\t\t}\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t\t\tword_count++;\n\t\t} while (buf_ptr < buf_end);\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == word_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tSLJIT_ASSERT(cpool_size == 0);\n\tif (compiler->cpool_fill > 0) {\n\t\tcpool_start_address = ALIGN_INSTRUCTION(code_ptr);\n\t\tcpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);\n\t\tif (cpool_current_index > 0)\n\t\t\tcode_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index);\n\n\t\tbuf_ptr = compiler->cpool;\n\t\tbuf_end = buf_ptr + compiler->cpool_fill;\n\t\tcpool_current_index = 0;\n\t\twhile (buf_ptr < buf_end) {\n\t\t\tif (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {\n\t\t\t\tSLJIT_FREE_EXEC(code, exec_allocator_data);\n\t\t\t\tcompiler->error = SLJIT_ERR_ALLOC_FAILED;\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tbuf_ptr++;\n\t\t\tcpool_current_index++;\n\t\t}\n\t\tSLJIT_ASSERT(!first_patch);\n\t}\n#endif\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\taddr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\t\tbuf_ptr = (sljit_ins*)jump->addr;\n\n\t\tif (jump->flags & JUMP_MOV_ADDR) {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\tSLJIT_ASSERT((buf_ptr[0] & (sljit_ins)0xffff0000) == 0xe59f0000);\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\t\tSLJIT_ASSERT((buf_ptr[0] & ~(sljit_ins)0xf000) == 0);\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\t\t\tif (jump->flags & PATCH_B) {\n\t\t\t\tSLJIT_ASSERT((((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) & 0x3) == 0);\n\t\t\t\tdiff = ((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) >> 2;\n\n\t\t\t\tSLJIT_ASSERT(diff <= 0xff && diff >= -0xff);\n\n\t\t\t\taddr = ADD;\n\t\t\t\tif (diff < 0) {\n\t\t\t\t\tdiff = -diff;\n\t\t\t\t\taddr = SUB;\n\t\t\t\t}\n\n\t\t\t\tbuf_ptr[0] = addr | (buf_ptr[0] & 0xf000) | RN(TMP_PC) | (1 << 25) | (0xf << 8) | (sljit_ins)(diff & 0xff);\n\t\t\t} else {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\t\tbuf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\t\t\tbuf_ptr[1] = MOVT | buf_ptr[0] | ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);\n\t\t\t\tbuf_ptr[0] = MOVW | buf_ptr[0] | ((addr << 4) & 0xf0000) | (addr & 0xfff);\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t\t\t}\n\t\t} else if (jump->flags & PATCH_B) {\n\t\t\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);\n\t\t\tSLJIT_ASSERT(diff <= 0x01ffffff && diff >= -0x02000000);\n\t\t\t*buf_ptr |= (diff >> 2) & 0x00ffffff;\n\t\t} else {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\t\tif (jump->flags & IS_BL)\n\t\t\t\tbuf_ptr--;\n\n\t\t\tif (jump->flags & SLJIT_REWRITABLE_JUMP) {\n\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\t\tcode_ptr[0] = (sljit_ins)buf_ptr;\n\t\t\t\tcode_ptr[1] = *buf_ptr;\n\t\t\t\tset_jump_addr((sljit_uw)code_ptr, executable_offset, addr, 0);\n\t\t\t\tcode_ptr += 2;\n\t\t\t} else {\n\t\t\t\tif (*buf_ptr & (1 << 23))\n\t\t\t\t\tbuf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;\n\t\t\t\telse\n\t\t\t\t\tbuf_ptr += 1;\n\t\t\t\t*buf_ptr = addr;\n\t\t\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\t\tset_jump_addr((sljit_uw)buf_ptr, executable_offset, addr, 0);\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t\t}\n\n\t\tjump = jump->next;\n\t}\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tconst_ = compiler->consts;\n\twhile (const_) {\n\t\tbuf_ptr = (sljit_ins*)const_->addr;\n\n\t\t/* Note: MVN = (MOV ^ 0x400000) */\n\t\tSLJIT_ASSERT((*buf_ptr & 0xfdb00000) == MOV || (*buf_ptr & 0xfd100000) == LDR);\n\n\t\tif ((*buf_ptr & 0x4000000) != 0) {\n\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\n\t\t\tcode_ptr[0] = (sljit_ins)buf_ptr;\n\t\t\tcode_ptr[1] = *buf_ptr;\n\t\t\tif (*buf_ptr & (1 << 23))\n\t\t\t\tbuf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;\n\t\t\telse\n\t\t\t\tbuf_ptr += 1;\n\t\t\t/* Set the value again (can be a simple constant). */\n\t\t\tset_const_value((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);\n\t\t\tcode_ptr += 2;\n\t\t}\n\n\t\tconst_ = const_->next;\n\t}\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_uw);\n\n\tcode = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n\tcase SLJIT_HAS_F64_AS_F32_PAIR:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n\tcase SLJIT_HAS_SIMD:\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\treturn 0;\n#else\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tcase SLJIT_SIMD_REGS_ARE_PAIRS:\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_CMOV:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_ATOMIC:\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\t\treturn 1;\n\n\tcase SLJIT_HAS_CTZ:\n#if defined(SLJIT_CONFIG_ARM_V6) && SLJIT_CONFIG_ARM_V6\n\t\treturn 2;\n#else\n\t\treturn 1;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\n/* Creates an index in data_transfer_insts array. */\n#define WORD_SIZE\t0x00\n#define BYTE_SIZE\t0x01\n#define HALF_SIZE\t0x02\n#define PRELOAD\t\t0x03\n#define SIGNED\t\t0x04\n#define LOAD_DATA\t0x08\n\n/* Flag bits for emit_op. */\n#define ALLOW_IMM\t\t0x10\n#define ALLOW_INV_IMM\t\t0x20\n#define ALLOW_ANY_IMM\t\t(ALLOW_IMM | ALLOW_INV_IMM)\n#define ALLOW_NEG_IMM\t\t0x40\n#define ALLOW_DOUBLE_IMM\t0x80\n\n/* s/l - store/load (1 bit)\n   u/s - signed/unsigned (1 bit)\n   w/b/h/N - word/byte/half/NOT allowed (2 bit)\n   Storing signed and unsigned values are the same operations. */\n\nstatic const sljit_ins data_transfer_insts[16] = {\n/* s u w */ 0xe5000000 /* str */,\n/* s u b */ 0xe5400000 /* strb */,\n/* s u h */ 0xe10000b0 /* strh */,\n/* s u N */ 0x00000000 /* not allowed */,\n/* s s w */ 0xe5000000 /* str */,\n/* s s b */ 0xe5400000 /* strb */,\n/* s s h */ 0xe10000b0 /* strh */,\n/* s s N */ 0x00000000 /* not allowed */,\n\n/* l u w */ 0xe5100000 /* ldr */,\n/* l u b */ 0xe5500000 /* ldrb */,\n/* l u h */ 0xe11000b0 /* ldrh */,\n/* l u p */ 0xf5500000 /* preload */,\n/* l s w */ 0xe5100000 /* ldr */,\n/* l s b */ 0xe11000d0 /* ldrsb */,\n/* l s h */ 0xe11000f0 /* ldrsh */,\n/* l s N */ 0x00000000 /* not allowed */,\n};\n\n#define EMIT_DATA_TRANSFER(type, add, target_reg, base_reg, arg) \\\n\t(data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_ins)(arg))\n\n/* Normal ldr/str instruction.\n   Type2: ldrsb, ldrh, ldrsh */\n#define IS_TYPE1_TRANSFER(type) \\\n\t(data_transfer_insts[(type) & 0xf] & 0x04000000)\n#define TYPE2_TRANSFER_IMM(imm) \\\n\t(((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))\n\n#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \\\n\t((sljit_ins)(opcode) | (sljit_ins)(mode) | VD(dst) | VM(src1) | VN(src2))\n\n/* Flags for emit_op: */\n  /* Arguments are swapped. */\n#define ARGS_SWAPPED\t0x01\n  /* Inverted immediate. */\n#define INV_IMM\t\t0x02\n  /* Source and destination is register. */\n#define REGISTER_OP\t0x04\n  /* Unused return value. */\n#define UNUSED_RETURN\t0x08\n/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */\n#define SET_FLAGS\t(1 << 20)\n/* dst: reg\n   src1: reg\n   src2: reg or imm (if allowed)\n   SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */\n#define SRC2_IMM\t(1 << 25)\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_uw imm, offset;\n\tsljit_s32 i, tmp, size, word_arg_count;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n#ifdef __SOFTFP__\n\tsljit_u32 float_arg_count;\n#else\n\tsljit_u32 old_offset, f32_offset;\n\tsljit_u32 remap[3];\n\tsljit_u32 *remap_ptr = remap;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\timm = 0;\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--)\n\t\timm |= (sljit_uw)1 << reg_map[i];\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)\n\t\timm |= (sljit_uw)1 << reg_map[i];\n\n\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14);\n\n\t/* Push saved and temporary registers\n\t   multiple registers: stmdb sp!, {..., lr}\n\t   single register: str reg, [sp, #-4]! */\n\tif (imm != 0)\n\t\tFAIL_IF(push_inst(compiler, PUSH | (1 << 14) | imm));\n\telse\n\t\tFAIL_IF(push_inst(compiler, 0xe52d0004 | RD(TMP_REG2)));\n\n\t/* Stack must be aligned to 8 bytes: */\n\tsize = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((size & SSIZE_OF(sw)) != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | sizeof(sljit_sw)));\n\t\t\tsize += SSIZE_OF(sw);\n\t\t}\n\n\t\tif (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {\n\t\t\tFAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));\n\t\t} else {\n\t\t\tif (fsaveds > 0)\n\t\t\t\tFAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1)));\n\t\t\tif (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)\n\t\t\t\tFAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));\n\t\t}\n\t}\n\n\tlocal_size = ((size + local_size + 0x7) & ~0x7) - size;\n\tcompiler->local_size = local_size;\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\targ_types = 0;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tword_arg_count = 0;\n\tsaved_arg_count = 0;\n#ifdef __SOFTFP__\n\tSLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);\n\n\toffset = 0;\n\tfloat_arg_count = 0;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset & 0x7)\n\t\t\t\toffset += sizeof(sljit_sw);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, VLDR_F32 | 0x800100 | RN(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tfloat_arg_count++;\n\t\t\toffset += sizeof(sljit_f64) - sizeof(sljit_sw);\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst(compiler, VMOV | (float_arg_count << 16) | (offset << 10)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, VLDR_F32 | 0x800000 | RN(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\ttmp = SLJIT_S0 - saved_arg_count;\n\t\t\t\tsaved_arg_count++;\n\t\t\t} else if (word_arg_count - 1 != (sljit_s32)(offset >> 2))\n\t\t\t\ttmp = word_arg_count;\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(tmp) | (offset >> 2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_ins)size - 4 * sizeof(sljit_sw))));\n\t\t\tbreak;\n\t\t}\n\n\t\toffset += sizeof(sljit_sw);\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tcompiler->args_size = offset;\n#else\n\toffset = SLJIT_FR0;\n\told_offset = SLJIT_FR0;\n\tf32_offset = 0;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset != old_offset)\n\t\t\t\t*remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, SLJIT_32, offset, old_offset, 0);\n\t\t\told_offset++;\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (f32_offset != 0) {\n\t\t\t\t*remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, 0x20, offset, f32_offset, 0);\n\t\t\t\tf32_offset = 0;\n\t\t\t} else {\n\t\t\t\tif (offset != old_offset)\n\t\t\t\t\t*remap_ptr++ = EMIT_FPU_OPERATION(VMOV_F32, 0, offset, old_offset, 0);\n\t\t\t\tf32_offset = old_offset;\n\t\t\t\told_offset++;\n\t\t\t}\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0 - saved_arg_count) | RM(SLJIT_R0 + word_arg_count)));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\n\t\t\tword_arg_count++;\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tSLJIT_ASSERT((sljit_uw)(remap_ptr - remap) <= sizeof(remap));\n\n\twhile (remap_ptr > remap)\n\t\tFAIL_IF(push_inst(compiler, *(--remap_ptr)));\n#endif\n\n\tif (local_size > 0)\n\t\tFAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\tsize = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n\n\t/* Doubles are saved, so alignment is unaffected. */\n\tif ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG))\n\t\tsize += SSIZE_OF(sw);\n\n\tcompiler->local_size = ((size + local_size + 0x7) & ~0x7) - size;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm)\n{\n\tsljit_uw imm2 = get_imm(imm);\n\n\tif (imm2 == 0)\n\t\treturn emit_op(compiler, SLJIT_ADD, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, (sljit_sw)imm);\n\n\treturn push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | imm2);\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size)\n{\n\tsljit_s32 local_size, fscratches, fsaveds, i, tmp;\n\tsljit_s32 restored_reg = 0;\n\tsljit_s32 lr_dst = TMP_PC;\n\tsljit_uw reg_list = 0;\n\n\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14 && frame_size <= 128);\n\n\tlocal_size = compiler->local_size;\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif (local_size > 0)\n\t\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));\n\n\t\tif (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {\n\t\t\tFAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));\n\t\t} else {\n\t\t\tif (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)\n\t\t\t\tFAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));\n\t\t\tif (fsaveds > 0)\n\t\t\t\tFAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1)));\n\t\t}\n\n\t\tlocal_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7;\n\t}\n\n\tif (frame_size < 0) {\n\t\tlr_dst = TMP_REG2;\n\t\tframe_size = 0;\n\t} else if (frame_size > 0) {\n\t\tSLJIT_ASSERT(frame_size == 1 || (frame_size & 0x7) == 0);\n\t\tlr_dst = 0;\n\t\tframe_size &= ~0x7;\n\t}\n\n\tif (lr_dst != 0)\n\t\treg_list |= (sljit_uw)1 << reg_map[lr_dst];\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\ti = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\tif (tmp < i) {\n\t\trestored_reg = i;\n\t\tdo {\n\t\t\treg_list |= (sljit_uw)1 << reg_map[i];\n\t\t} while (--i > tmp);\n\t}\n\n\ti = compiler->scratches;\n\tif (i >= SLJIT_FIRST_SAVED_REG) {\n\t\trestored_reg = i;\n\t\tdo {\n\t\t\treg_list |= (sljit_uw)1 << reg_map[i];\n\t\t} while (--i >= SLJIT_FIRST_SAVED_REG);\n\t}\n\n\tif (lr_dst == TMP_REG2 && reg_list == 0) {\n\t\trestored_reg = TMP_REG2;\n\t\tlr_dst = 0;\n\t}\n\n\tif (lr_dst == 0 && (reg_list & (reg_list - 1)) == 0) {\n\t\t/* The local_size does not include the saved registers. */\n\t\ttmp = 0;\n\t\tif (reg_list != 0) {\n\t\t\ttmp = 2;\n\t\t\tif (local_size <= 0xfff) {\n\t\t\t\tif (local_size == 0) {\n\t\t\t\t\tSLJIT_ASSERT(restored_reg != TMP_REG2);\n\t\t\t\t\tif (frame_size == 0)\n\t\t\t\t\t\treturn push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | 0x800008);\n\t\t\t\t\tif (frame_size > 2 * SSIZE_OF(sw))\n\t\t\t\t\t\treturn push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)(frame_size - (2 * SSIZE_OF(sw))));\n\t\t\t\t}\n\n\t\t\t\tFAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)local_size));\n\t\t\t\ttmp = 1;\n\t\t\t} else if (frame_size == 0) {\n\t\t\t\tframe_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw);\n\t\t\t\ttmp = 3;\n\t\t\t}\n\n\t\t\t/* Place for the saved register. */\n\t\t\tif (restored_reg != TMP_REG2)\n\t\t\t\tlocal_size += SSIZE_OF(sw);\n\t\t}\n\n\t\t/* Place for the lr register. */\n\t\tlocal_size += SSIZE_OF(sw);\n\n\t\tif (frame_size > local_size)\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_ins)(frame_size - local_size)));\n\t\telse if (frame_size < local_size)\n\t\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size)));\n\n\t\tif (tmp <= 1)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (tmp == 2) {\n\t\t\tframe_size -= SSIZE_OF(sw);\n\t\t\tif (restored_reg != TMP_REG2)\n\t\t\t\tframe_size -= SSIZE_OF(sw);\n\n\t\t\treturn push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)frame_size);\n\t\t}\n\n\t\ttmp = (restored_reg == TMP_REG2) ? 0x800004 : 0x800008;\n\t\treturn push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)tmp);\n\t}\n\n\tif (local_size > 0)\n\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));\n\n\t/* Pop saved and temporary registers\n\t   multiple registers: ldmia sp!, {...}\n\t   single register: ldr reg, [sp], #4 */\n\tif ((reg_list & (reg_list - 1)) == 0) {\n\t\tSLJIT_ASSERT(lr_dst != 0);\n\t\tSLJIT_ASSERT(reg_list == (sljit_uw)1 << reg_map[lr_dst]);\n\n\t\treturn push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(lr_dst) | 0x800004);\n\t}\n\n\tFAIL_IF(push_inst(compiler, POP | reg_list));\n\n\tif (frame_size > 0)\n\t\treturn push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_ins)frame_size - sizeof(sljit_sw)));\n\n\tif (lr_dst != 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | sizeof(sljit_sw));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\treturn emit_stack_frame_release(compiler, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_uw dst, sljit_uw src1, sljit_uw src2)\n{\n\tsljit_s32 reg, is_masked;\n\tsljit_uw shift_type;\n\n\tswitch (op) {\n\tcase SLJIT_MOV:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));\n\t\tif (dst != src2) {\n\t\t\tif (src2 & SRC2_IMM) {\n\t\t\t\treturn push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);\n\t\t\t}\n\t\t\treturn push_inst(compiler, MOV | RD(dst) | RM(src2));\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U8:\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));\n\t\tif (flags & REGISTER_OP)\n\t\t\treturn push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2));\n\n\t\tif (dst != src2) {\n\t\t\tSLJIT_ASSERT(src2 & SRC2_IMM);\n\t\t\treturn push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));\n\t\tif (flags & REGISTER_OP)\n\t\t\treturn push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2));\n\n\t\tif (dst != src2) {\n\t\t\tSLJIT_ASSERT(src2 & SRC2_IMM);\n\t\t\treturn push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM));\n\t\tFAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM));\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && src2 != TMP_REG2 && !(flags & ARGS_SWAPPED));\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\tFAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0));\n\t\tFAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RN(src2) | RM(TMP_REG2)));\n\t\tFAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(dst) | 32));\n\t\treturn push_inst(compiler, (EOR ^ 0xf0000000) | SRC2_IMM | RD(dst) | RN(dst) | 0x1f);\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\tFAIL_IF(push_inst(compiler, RBIT | RD(dst) | RM(src2)));\n\t\treturn push_inst(compiler, CLZ | RD(dst) | RM(dst));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));\n\t\treturn push_inst(compiler, REV | RD(dst) | RM(src2));\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));\n\t\tFAIL_IF(push_inst(compiler, REV16 | RD(dst) | RM(src2)));\n\t\tif (!(flags & REGISTER_OP))\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, (op == SLJIT_REV_U16 ? UXTH : SXTH) | RD(dst) | RM(dst));\n\tcase SLJIT_ADD:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\n\t\tif ((flags & (UNUSED_RETURN | ARGS_SWAPPED)) == UNUSED_RETURN)\n\t\t\treturn push_inst(compiler, CMN | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\t\treturn push_inst(compiler, ADD | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_ADDC:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\t\treturn push_inst(compiler, ADC | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_SUB:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\n\t\tif ((flags & (UNUSED_RETURN | ARGS_SWAPPED)) == UNUSED_RETURN)\n\t\t\treturn push_inst(compiler, CMP | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\t\treturn push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SUB : RSB) | (flags & SET_FLAGS)\n\t\t\t| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_SUBC:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\t\treturn push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SBC : RSC) | (flags & SET_FLAGS)\n\t\t\t| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_MUL:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\t\tSLJIT_ASSERT(!(src2 & SRC2_IMM));\n\t\tcompiler->status_flags_state = 0;\n\n\t\tif (!(flags & SET_FLAGS))\n\t\t\treturn push_inst(compiler, MUL | RN(dst) | RM8(src2) | RM(src1));\n\n\t\treg = dst == TMP_REG1 ? TMP_REG2 : TMP_REG1;\n\t\tFAIL_IF(push_inst(compiler, SMULL | RN(reg) | RD(dst) | RM8(src2) | RM(src1)));\n\n\t\t/* cmp TMP_REG1, dst asr #31. */\n\t\treturn push_inst(compiler, CMP | SET_FLAGS | RN(reg) | RM(dst) | 0xfc0);\n\n\tcase SLJIT_AND:\n\t\tif ((flags & (UNUSED_RETURN | INV_IMM)) == UNUSED_RETURN)\n\t\t\treturn push_inst(compiler, TST | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\t\treturn push_inst(compiler, (!(flags & INV_IMM) ? AND : BIC) | (flags & SET_FLAGS)\n\t\t\t| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_OR:\n\t\tSLJIT_ASSERT(!(flags & INV_IMM));\n\t\treturn push_inst(compiler, ORR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_XOR:\n\t\tif (flags & INV_IMM) {\n\t\t\tSLJIT_ASSERT(src2 == SRC2_IMM);\n\t\t\treturn push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src1));\n\t\t}\n\t\treturn push_inst(compiler, EOR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tshift_type = 0;\n\t\tis_masked = op == SLJIT_MSHL;\n\t\tbreak;\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tshift_type = 1;\n\t\tis_masked = op == SLJIT_MLSHR;\n\t\tbreak;\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tshift_type = 2;\n\t\tis_masked = op == SLJIT_MASHR;\n\t\tbreak;\n\n\tcase SLJIT_ROTL:\n\t\tif (compiler->shift_imm == 0x20) {\n\t\t\tFAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0));\n\t\t\tsrc2 = TMP_REG2;\n\t\t} else\n\t\t\tcompiler->shift_imm = (sljit_uw)(-(sljit_sw)compiler->shift_imm) & 0x1f;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ROTR:\n\t\tshift_type = 3;\n\t\tis_masked = 0;\n\t\tbreak;\n\n\tcase SLJIT_MULADD:\n\t\treturn push_inst(compiler, MLA | RN(dst) | RD(dst) | RM8(src2) | RM(src1));\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tSLJIT_ASSERT(!(flags & ARGS_SWAPPED) && !(flags & INV_IMM) && !(src2 & SRC2_IMM));\n\n\tif (compiler->shift_imm != 0x20) {\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\n\t\tif (compiler->shift_imm != 0)\n\t\t\treturn push_inst(compiler, MOV | (flags & SET_FLAGS) |\n\t\t\t\tRD(dst) | (compiler->shift_imm << 7) | (shift_type << 5) | RM(src2));\n\t\treturn push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) | RM(src2));\n\t}\n\n\tSLJIT_ASSERT(src1 != TMP_REG2);\n\n\tif (is_masked) {\n\t\tFAIL_IF(push_inst(compiler, AND | RD(TMP_REG2) | RN(src2) | SRC2_IMM | 0x1f));\n\t\tsrc2 = TMP_REG2;\n\t}\n\n\treturn push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst)\n\t\t| RM8(src2) | (sljit_ins)(shift_type << 5) | 0x10 | RM(src1));\n}\n\n#undef EMIT_SHIFT_INS_AND_RETURN\n\n/* Tests whether the immediate can be stored in the 12 bit imm field.\n   Returns with 0 if not possible. */\nstatic sljit_uw get_imm(sljit_uw imm)\n{\n\tsljit_u32 rol;\n\n\tif (imm <= 0xff)\n\t\treturn SRC2_IMM | imm;\n\n\tif (!(imm & 0xff000000)) {\n\t\timm <<= 8;\n\t\trol = 8;\n\t} else {\n\t\timm = (imm << 24) | (imm >> 8);\n\t\trol = 0;\n\t}\n\n\tif (!(imm & 0xff000000)) {\n\t\timm <<= 8;\n\t\trol += 4;\n\t}\n\n\tif (!(imm & 0xf0000000)) {\n\t\timm <<= 4;\n\t\trol += 2;\n\t}\n\n\tif (!(imm & 0xc0000000)) {\n\t\timm <<= 2;\n\t\trol += 1;\n\t}\n\n\tif (!(imm & 0x00ffffff))\n\t\treturn SRC2_IMM | (imm >> 24) | (rol << 8);\n\treturn 0;\n}\n\nstatic sljit_uw compute_imm(sljit_uw imm, sljit_uw* imm2)\n{\n\tsljit_uw mask;\n\tsljit_uw imm1;\n\tsljit_uw rol;\n\n\t/* Step1: Search a zero byte (8 continous zero bit). */\n\tmask = 0xff000000;\n\trol = 8;\n\twhile (1) {\n\t\tif (!(imm & mask)) {\n\t\t\t/* Rol imm by rol. */\n\t\t\timm = (imm << rol) | (imm >> (32 - rol));\n\t\t\t/* Calculate arm rol. */\n\t\t\trol = 4 + (rol >> 1);\n\t\t\tbreak;\n\t\t}\n\n\t\trol += 2;\n\t\tmask >>= 2;\n\t\tif (mask & 0x3) {\n\t\t\t/* rol by 8. */\n\t\t\timm = (imm << 8) | (imm >> 24);\n\t\t\tmask = 0xff00;\n\t\t\trol = 24;\n\t\t\twhile (1) {\n\t\t\t\tif (!(imm & mask)) {\n\t\t\t\t\t/* Rol imm by rol. */\n\t\t\t\t\timm = (imm << rol) | (imm >> (32 - rol));\n\t\t\t\t\t/* Calculate arm rol. */\n\t\t\t\t\trol = (rol >> 1) - 8;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\trol += 2;\n\t\t\t\tmask >>= 2;\n\t\t\t\tif (mask & 0x3)\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* The low 8 bit must be zero. */\n\tSLJIT_ASSERT(!(imm & 0xff));\n\n\tif (!(imm & 0xff000000)) {\n\t\timm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);\n\t\t*imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);\n\t} else if (imm & 0xc0000000) {\n\t\timm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);\n\t\timm <<= 8;\n\t\trol += 4;\n\n\t\tif (!(imm & 0xff000000)) {\n\t\t\timm <<= 8;\n\t\t\trol += 4;\n\t\t}\n\n\t\tif (!(imm & 0xf0000000)) {\n\t\t\timm <<= 4;\n\t\t\trol += 2;\n\t\t}\n\n\t\tif (!(imm & 0xc0000000)) {\n\t\t\timm <<= 2;\n\t\t\trol += 1;\n\t\t}\n\n\t\tif (!(imm & 0x00ffffff))\n\t\t\t*imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);\n\t\telse\n\t\t\treturn 0;\n\t} else {\n\t\tif (!(imm & 0xf0000000)) {\n\t\t\timm <<= 4;\n\t\t\trol += 2;\n\t\t}\n\n\t\tif (!(imm & 0xc0000000)) {\n\t\t\timm <<= 2;\n\t\t\trol += 1;\n\t\t}\n\n\t\timm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);\n\t\timm <<= 8;\n\t\trol += 4;\n\n\t\tif (!(imm & 0xf0000000)) {\n\t\t\timm <<= 4;\n\t\t\trol += 2;\n\t\t}\n\n\t\tif (!(imm & 0xc0000000)) {\n\t\t\timm <<= 2;\n\t\t\trol += 1;\n\t\t}\n\n\t\tif (!(imm & 0x00ffffff))\n\t\t\t*imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);\n\t\telse\n\t\t\treturn 0;\n\t}\n\n\treturn imm1;\n}\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm)\n{\n\tsljit_uw tmp;\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tsljit_uw imm1, imm2;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tif (!(imm & ~(sljit_uw)0xffff))\n\t\treturn push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\t/* Create imm by 1 inst. */\n\ttmp = get_imm(imm);\n\tif (tmp)\n\t\treturn push_inst(compiler, MOV | RD(reg) | tmp);\n\n\ttmp = get_imm(~imm);\n\tif (tmp)\n\t\treturn push_inst(compiler, MVN | RD(reg) | tmp);\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t/* Create imm by 2 inst. */\n\timm1 = compute_imm(imm, &imm2);\n\tif (imm1 != 0) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(reg) | imm1));\n\t\treturn push_inst(compiler, ORR | RD(reg) | RN(reg) | imm2);\n\t}\n\n\timm1 = compute_imm(~imm, &imm2);\n\tif (imm1 != 0) {\n\t\tFAIL_IF(push_inst(compiler, MVN | RD(reg) | imm1));\n\t\treturn push_inst(compiler, BIC | RD(reg) | RN(reg) | imm2);\n\t}\n\n\t/* Load integer. */\n\treturn push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm);\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tFAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));\n\tif (imm <= 0xffff)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n}\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,\n\tsljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)\n{\n\tsljit_uw imm, offset_reg, tmp;\n\tsljit_sw mask = IS_TYPE1_TRANSFER(flags) ? 0xfff : 0xff;\n\tsljit_sw sign = IS_TYPE1_TRANSFER(flags) ? 0x1000 : 0x100;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\tSLJIT_ASSERT((arg & REG_MASK) != tmp_reg || (arg == SLJIT_MEM1(tmp_reg) && argw >= -mask && argw <= mask));\n\n\tif (SLJIT_UNLIKELY(!(arg & REG_MASK))) {\n\t\ttmp = (sljit_uw)(argw & (sign | mask));\n\t\ttmp = (sljit_uw)((argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);\n\n\t\tFAIL_IF(load_immediate(compiler, tmp_reg, tmp));\n\n\t\targw -= (sljit_sw)tmp;\n\t\ttmp = 1;\n\n\t\tif (argw < 0) {\n\t\t\targw = -argw;\n\t\t\ttmp = 0;\n\t\t}\n\n\t\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, tmp, reg, tmp_reg,\n\t\t\t(mask == 0xff) ? TYPE2_TRANSFER_IMM(argw) : argw));\n\t}\n\n\tif (arg & OFFS_REG_MASK) {\n\t\toffset_reg = OFFS_REG(arg);\n\t\targ &= REG_MASK;\n\t\targw &= 0x3;\n\n\t\tif (argw != 0 && (mask == 0xff)) {\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_ins)argw << 7)));\n\t\t\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg, TYPE2_TRANSFER_IMM(0)));\n\t\t}\n\n\t\t/* Bit 25: RM is offset. */\n\t\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,\n\t\t\tRM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_ins)argw << 7)));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (argw > mask) {\n\t\ttmp = (sljit_uw)(argw & (sign | mask));\n\t\ttmp = (sljit_uw)((argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);\n\t\timm = get_imm(tmp);\n\n\t\tif (imm) {\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | imm));\n\t\t\targw -= (sljit_sw)tmp;\n\t\t\targ = tmp_reg;\n\n\t\t\tSLJIT_ASSERT(argw >= -mask && argw <= mask);\n\t\t}\n\t} else if (argw < -mask) {\n\t\ttmp = (sljit_uw)(-argw & (sign | mask));\n\t\ttmp = (sljit_uw)((-argw + (tmp <= (sljit_uw)sign ? 0 : sign)) & ~mask);\n\t\timm = get_imm(tmp);\n\n\t\tif (imm) {\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(tmp_reg) | RN(arg) | imm));\n\t\t\targw += (sljit_sw)tmp;\n\t\t\targ = tmp_reg;\n\n\t\t\tSLJIT_ASSERT(argw >= -mask && argw <= mask);\n\t\t}\n\t}\n\n\tif (argw <= mask && argw >= -mask) {\n\t\tif (argw >= 0) {\n\t\t\tif (mask == 0xff)\n\t\t\t\targw = TYPE2_TRANSFER_IMM(argw);\n\t\t\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, argw));\n\t\t}\n\n\t\targw = -argw;\n\n\t\tif (mask == 0xff)\n\t\t\targw = TYPE2_TRANSFER_IMM(argw);\n\n\t\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, 0, reg, arg, argw));\n\t}\n\n\tFAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));\n\treturn push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,\n\t\tRM(tmp_reg) | (mask == 0xff ? 0 : (1 << 25))));\n}\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* src1 is reg or TMP_REG1\n\t   src2 is reg, TMP_REG2, or imm\n\t   result goes to TMP_REG2, so put result can use TMP_REG1. */\n\n\t/* We prefers register and simple consts. */\n\tsljit_s32 dst_reg;\n\tsljit_s32 src1_reg = 0;\n\tsljit_s32 src2_reg = 0;\n\tsljit_s32 src2_tmp_reg = 0;\n\tsljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;\n\tsljit_s32 neg_op = 0;\n\tsljit_u32 imm2;\n\n\top = GET_OPCODE(op);\n\n\tif (flags & SET_FLAGS)\n\t\tinp_flags &= ~ALLOW_DOUBLE_IMM;\n\n\tif (dst == TMP_REG1)\n\t\tflags |= UNUSED_RETURN;\n\n\tSLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM));\n\n\tif (inp_flags & ALLOW_NEG_IMM) {\n\t\tswitch (op) {\n\t\tcase SLJIT_ADD:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\t\tneg_op = SLJIT_SUB;\n\t\t\tbreak;\n\t\tcase SLJIT_ADDC:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\t\tneg_op = SLJIT_SUBC;\n\t\t\tbreak;\n\t\tcase SLJIT_SUB:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\t\tneg_op = SLJIT_ADD;\n\t\t\tbreak;\n\t\tcase SLJIT_SUBC:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\t\tneg_op = SLJIT_ADDC;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tdo {\n\t\tif (!(inp_flags & ALLOW_IMM))\n\t\t\tbreak;\n\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tsrc2_reg = (sljit_s32)get_imm((sljit_uw)src2w);\n\t\t\tif (src2_reg)\n\t\t\t\tbreak;\n\n\t\t\tif (inp_flags & ALLOW_INV_IMM) {\n\t\t\t\tsrc2_reg = (sljit_s32)get_imm(~(sljit_uw)src2w);\n\t\t\t\tif (src2_reg) {\n\t\t\t\t\tflags |= INV_IMM;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (neg_op != 0) {\n\t\t\t\tsrc2_reg = (sljit_s32)get_imm((neg_op == SLJIT_ADD || neg_op == SLJIT_SUB) ? (sljit_uw)-src2w : ~(sljit_uw)src2w);\n\t\t\t\tif (src2_reg) {\n\t\t\t\t\top = neg_op | GET_ALL_FLAGS(op);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (src1 == SLJIT_IMM) {\n\t\t\tsrc2_reg = (sljit_s32)get_imm((sljit_uw)src1w);\n\t\t\tif (src2_reg) {\n\t\t\t\tflags |= ARGS_SWAPPED;\n\t\t\t\tsrc1 = src2;\n\t\t\t\tsrc1w = src2w;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (inp_flags & ALLOW_INV_IMM) {\n\t\t\t\tsrc2_reg = (sljit_s32)get_imm(~(sljit_uw)src1w);\n\t\t\t\tif (src2_reg) {\n\t\t\t\t\tflags |= ARGS_SWAPPED | INV_IMM;\n\t\t\t\t\tsrc1 = src2;\n\t\t\t\t\tsrc1w = src2w;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (neg_op >= SLJIT_SUB) {\n\t\t\t\t/* Note: additive operation (commutative). */\n\t\t\t\tSLJIT_ASSERT(op == SLJIT_ADD || op == SLJIT_ADDC);\n\n\t\t\t\tsrc2_reg = (sljit_s32)get_imm((sljit_uw)-src1w);\n\t\t\t\tif (src2_reg) {\n\t\t\t\t\tsrc1 = src2;\n\t\t\t\t\tsrc1w = src2w;\n\t\t\t\t\top = neg_op | GET_ALL_FLAGS(op);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while(0);\n\n\t/* Destination. */\n\tdst_reg = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op <= SLJIT_MOV_P) {\n\t\tif (dst & SLJIT_MEM) {\n\t\t\tif (inp_flags & BYTE_SIZE)\n\t\t\t\tinp_flags &= ~SIGNED;\n\n\t\t\tif (FAST_IS_REG(src2))\n\t\t\t\treturn emit_op_mem(compiler, inp_flags, src2, dst, dstw, TMP_REG1);\n\t\t}\n\n\t\tif (FAST_IS_REG(src2) && dst_reg != TMP_REG2)\n\t\t\tflags |= REGISTER_OP;\n\n\t\tsrc2_tmp_reg = dst_reg;\n\t} else {\n\t\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {\n\t\t\tif (!(dst & SLJIT_MEM) && (!(src2 & SLJIT_MEM) || op == SLJIT_REV_S16))\n\t\t\t\tflags |= REGISTER_OP;\n\t\t}\n\n\t\tsrc2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;\n\t}\n\n\tif (src2_reg == 0 && (src2 & SLJIT_MEM)) {\n\t\tsrc2_reg = src2_tmp_reg;\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG1));\n\t}\n\n\t/* Source 1. */\n\tif (FAST_IS_REG(src1))\n\t\tsrc1_reg = src1;\n\telse if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1_reg = TMP_REG1;\n\t} else if (!(inp_flags & ALLOW_DOUBLE_IMM) || src2_reg != 0 || op == SLJIT_SUB || op == SLJIT_SUBC) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\tsrc1_reg = TMP_REG1;\n\t}\n\n\t/* Source 2. */\n\tif (src2_reg == 0) {\n\t\tsrc2_reg = src2_tmp_reg;\n\n\t\tif (FAST_IS_REG(src2))\n\t\t\tsrc2_reg = src2;\n\t\telse if (!(inp_flags & ALLOW_DOUBLE_IMM))\n\t\t\tFAIL_IF(load_immediate(compiler, src2_reg, (sljit_uw)src2w));\n\t\telse {\n\t\t\tSLJIT_ASSERT(!(flags & SET_FLAGS));\n\n\t\t\tif (src1_reg == 0) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\t\t\tsrc1_reg = TMP_REG1;\n\t\t\t}\n\n\t\t\tsrc2_reg = (sljit_s32)compute_imm((sljit_uw)src2w, &imm2);\n\n\t\t\tif (src2_reg == 0 && neg_op != 0) {\n\t\t\t\tsrc2_reg = (sljit_s32)compute_imm((sljit_uw)-src2w, &imm2);\n\t\t\t\tif (src2_reg != 0)\n\t\t\t\t\top = neg_op;\n\t\t\t}\n\n\t\t\tif (src2_reg == 0) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, src2_tmp_reg, (sljit_uw)src2w));\n\t\t\t\tsrc2_reg = src2_tmp_reg;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg));\n\t\t\t\tsrc1_reg = dst_reg;\n\t\t\t\tsrc2_reg = (sljit_s32)imm2;\n\n\t\t\t\tif (op == SLJIT_ADDC)\n\t\t\t\t\top = SLJIT_ADD;\n\t\t\t\telse if (op == SLJIT_SUBC)\n\t\t\t\t\top = SLJIT_SUB;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (src1_reg == 0) {\n\t\tSLJIT_ASSERT((inp_flags & ALLOW_DOUBLE_IMM) && !(flags & SET_FLAGS));\n\n\t\tsrc1_reg = (sljit_s32)compute_imm((sljit_uw)src1w, &imm2);\n\n\t\tif (src1_reg == 0 && neg_op != 0) {\n\t\t\tsrc1_reg = (sljit_s32)compute_imm((sljit_uw)-src1w, &imm2);\n\t\t\tif (src1_reg != 0)\n\t\t\t\top = neg_op;\n\t\t}\n\n\t\tif (src1_reg == 0) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\t\tsrc1_reg = TMP_REG1;\n\t\t} else {\n\t\t\tFAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src2_reg, (sljit_uw)src1_reg));\n\t\t\tsrc1_reg = dst_reg;\n\t\t\tsrc2_reg = (sljit_s32)imm2;\n\n\t\t\tif (op == SLJIT_ADDC)\n\t\t\t\top = SLJIT_ADD;\n\t\t}\n\t}\n\n\tFAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg));\n\n\tif (!(dst & SLJIT_MEM))\n\t\treturn SLJIT_SUCCESS;\n\n\treturn emit_op_mem(compiler, inp_flags, dst_reg, dst, dstw, TMP_REG1);\n}\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(__GNUC__)\nextern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);\nextern int __aeabi_idivmod(int numerator, int denominator);\n#else\n#error \"Software divmod functions are needed\"\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tsljit_uw saved_reg_list[3];\n\tsljit_sw saved_reg_count;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\t\tFAIL_IF(push_inst(compiler, BKPT));\n\t\tbreak;\n\tcase SLJIT_NOP:\n\t\tFAIL_IF(push_inst(compiler, NOP));\n\t\tbreak;\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n\t\treturn push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)\n\t\t\t| RN(SLJIT_R1) | RD(SLJIT_R0) | RM8(SLJIT_R0) | RM(SLJIT_R1));\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n\t\tSLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);\n\t\tSLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);\n\n\t\tsaved_reg_count = 0;\n\t\tif (compiler->scratches >= 4)\n\t\t\tsaved_reg_list[saved_reg_count++] = 3;\n\t\tif (compiler->scratches >= 3)\n\t\t\tsaved_reg_list[saved_reg_count++] = 2;\n\t\tif (op >= SLJIT_DIV_UW)\n\t\t\tsaved_reg_list[saved_reg_count++] = 1;\n\n\t\tif (saved_reg_count > 0) {\n\t\t\tFAIL_IF(push_inst(compiler, STR | 0x2d0000 | (saved_reg_count >= 3 ? 16 : 8)\n\t\t\t\t\t\t| (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));\n\t\t\tif (saved_reg_count >= 2) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[1] < 8);\n\t\t\t\tFAIL_IF(push_inst(compiler, STR | 0x8d0004 | (saved_reg_list[1] << 12) /* str rX, [sp, #4] */));\n\t\t\t}\n\t\t\tif (saved_reg_count >= 3) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[2] < 8);\n\t\t\t\tFAIL_IF(push_inst(compiler, STR | 0x8d0008 | (saved_reg_list[2] << 12) /* str rX, [sp, #8] */));\n\t\t\t}\n\t\t}\n\n#if defined(__GNUC__)\n\t\tFAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,\n\t\t\t((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__aeabi_uidivmod) : SLJIT_FUNC_ADDR(__aeabi_idivmod))));\n#else\n#error \"Software divmod functions are needed\"\n#endif\n\n\t\tif (saved_reg_count > 0) {\n\t\t\tif (saved_reg_count >= 3) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[2] < 8);\n\t\t\t\tFAIL_IF(push_inst(compiler, LDR | 0x8d0008 | (saved_reg_list[2] << 12) /* ldr rX, [sp, #8] */));\n\t\t\t}\n\t\t\tif (saved_reg_count >= 2) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[1] < 8);\n\t\t\t\tFAIL_IF(push_inst(compiler, LDR | 0x8d0004 | (saved_reg_list[1] << 12) /* ldr rX, [sp, #4] */));\n\t\t\t}\n\t\t\treturn push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_ins)(saved_reg_count >= 3 ? 16 : 8)\n\t\t\t\t\t\t| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_MEMORY_BARRIER:\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\t\treturn push_inst(compiler, DMB_SY);\n#else /* !SLJIT_CONFIG_ARM_V7 */\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_P:\n\t\treturn emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);\n\n\tcase SLJIT_MOV_U8:\n\t\treturn emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);\n\n\tcase SLJIT_MOV_S8:\n\t\treturn emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);\n\n\tcase SLJIT_MOV_U16:\n\t\treturn emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);\n\n\tcase SLJIT_MOV_S16:\n\t\treturn emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\treturn emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\treturn emit_op(compiler, op, HALF_SIZE, dst, dstw, TMP_REG1, 0, src, srcw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 inp_flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\tcase SLJIT_ADDC:\n\tcase SLJIT_SUB:\n\tcase SLJIT_SUBC:\n\t\treturn emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_OR:\n\t\treturn emit_op(compiler, op, ALLOW_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_XOR:\n\t\tinp_flags = ALLOW_IMM | ALLOW_DOUBLE_IMM;\n\t\tif ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {\n\t\t\tinp_flags |= ALLOW_INV_IMM;\n\t\t}\n\t\treturn emit_op(compiler, op, inp_flags, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_MUL:\n\t\treturn emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_AND:\n\t\treturn emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tcompiler->shift_imm = src2w & 0x1f;\n\t\t\treturn emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);\n\t\t} else {\n\t\t\tcompiler->shift_imm = 0x20;\n\t\t\treturn emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\treturn emit_op(compiler, op, 0, dst_reg, 0, src1, src1w, src2, src2w);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_left;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\top = GET_OPCODE(op);\n\tis_left = (op == SLJIT_SHL || op == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\t/* Shift type of ROR is 3. */\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= 0x1f;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src1_reg) | ((sljit_ins)(is_left ? 0 : 1) << 5) | ((sljit_ins)src3w << 7)));\n\t\tsrc3w = (src3w ^ 0x1f) + 1;\n\t\treturn push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | ((sljit_ins)src3w << 7));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src3, src3w, TMP_REG2));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) {\n\t\tFAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM8(src3) | ((sljit_ins)(is_left ? 0 : 1) << 5) | 0x10 | RM(src1_reg)));\n\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | (1 << 7)));\n\tFAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f));\n\treturn push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM8(TMP_REG2) | ((sljit_ins)(is_left ? 1 : 0) << 5) | 0x10 | RM(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= 0x1f;\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, tmp_r, src2, src2w, tmp_r));\n\t\tsrc2 = tmp_r;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tFAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(src1) | RM(src2) | ((sljit_ins)shift_arg << 7)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE, dst_r, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14);\n\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (src != TMP_REG2)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));\n\n\t\treturn push_inst(compiler, BX | RM(TMP_REG2));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\tSLJIT_ASSERT(src & SLJIT_MEM);\n\t\treturn emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 size, dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14);\n\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (dst == TMP_REG2)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2));\n\t\t}\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tsize = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0);\n\n\t\tif (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\t\t/* The size of pc is not added above. */\n\t\t\tif ((size & SSIZE_OF(sw)) == 0)\n\t\t\t\tsize += SSIZE_OF(sw);\n\n\t\t\tsize += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64);\n\t\t}\n\n\t\tSLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0);\n\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64)\n\t\treturn freg_map[reg];\n\n\tif (type == SLJIT_SIMD_REG_128)\n\t\treturn freg_map[reg] & ~0x1;\n\n\treturn -1;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define FPU_LOAD (1 << 20)\n#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \\\n\t((inst) | (sljit_ins)((add) << 23) | RN(base) | VD(freg) | (sljit_ins)(offs))\n\nstatic sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_uw imm;\n\tsljit_ins inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD));\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\targ &= ~SLJIT_MEM;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_ins)argw & 0x3) << 7)));\n\t\targ = TMP_REG1;\n\t\targw = 0;\n\t}\n\n\t/* Fast loads and stores. */\n\tif (arg) {\n\t\tif (!(argw & ~0x3fc))\n\t\t\treturn push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2));\n\t\tif (!(-argw & ~0x3fc))\n\t\t\treturn push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2));\n\n\t\timm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc);\n\t\tif (imm) {\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | imm));\n\t\t\treturn push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));\n\t\t}\n\t\timm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc);\n\t\tif (imm) {\n\t\t\targw = -argw;\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RN(arg & REG_MASK) | imm));\n\t\t\treturn push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));\n\t\t}\n\t}\n\n\tif (arg) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(TMP_REG1)));\n\t}\n\telse\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));\n\n\treturn push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\top ^= SLJIT_32;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src, srcw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_32, TMP_FREG1, src, 0)));\n\n\tif (FAST_IS_REG(dst))\n\t\treturn push_inst(compiler, VMOV | (1 << 20) | RD(dst) | VN(TMP_FREG1));\n\n\t/* Store the integer value from a VFP register. */\n\treturn emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);\n}\n\nstatic sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (FAST_IS_REG(src))\n\t\tFAIL_IF(push_inst(compiler, VMOV | RD(src) | VN(TMP_FREG1)));\n\telse if (src & SLJIT_MEM) {\n\t\t/* Load the integer value into a VFP register. */\n\t\tFAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));\n\t}\n\telse {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));\n\t\tFAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | VN(TMP_FREG1)));\n\t}\n\n\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(ins, ins & SLJIT_32, dst_r, TMP_FREG1, 0)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\top ^= SLJIT_32;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_32, src1, src2, 0)));\n\tFAIL_IF(push_inst(compiler, VMRS));\n\n\tif (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, (CMP - CONDITIONAL) | (0x60000000 /* VS */) | SET_FLAGS | RN(TMP_REG1) | RM(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_32, dst_r, src, 0)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_32, dst_r, src, 0)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_32, dst_r, src, 0)));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_32, dst_r, src, 0)));\n\t\top ^= SLJIT_32;\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, (op & SLJIT_32), dst_r, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_32, dst_r, src2, src1)));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_32, dst_r, src2, src1)));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_32, dst_r, src2, src1)));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_32, dst_r, src2, src1)));\n\t\tbreak;\n\tcase SLJIT_COPYSIGN_F64:\n\t\tFAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(src2) | RD(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0)));\n\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_32, dst_r, src1, 0)));\n\t\tFAIL_IF(push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | SRC2_IMM | 0));\n\t\treturn push_inst(compiler, EMIT_FPU_OPERATION((VNEG_F32 & ~COND_MASK) | 0xb0000000, op & SLJIT_32, dst_r, dst_r, 0));\n\t}\n\n\tif (dst_r != dst)\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw));\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef EMIT_FPU_DATA_TRANSFER\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n#if defined(__ARM_NEON) && __ARM_NEON\n\tsljit_u32 exp;\n\tsljit_ins ins;\n#endif /* NEON */\n\tunion {\n\t\tsljit_u32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n#if defined(__ARM_NEON) && __ARM_NEON\n\tif ((u.imm << (32 - 19)) == 0) {\n\t\texp = (u.imm >> (23 + 2)) & 0x3f;\n\n\t\tif (exp == 0x20 || exp == 0x1f) {\n\t\t\tins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f);\n\t\t\treturn push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf));\n\t\t}\n\t}\n#endif /* NEON */\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\treturn push_inst(compiler, VMOV | VN(freg) | RD(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n#if defined(__ARM_NEON) && __ARM_NEON\n\tsljit_u32 exp;\n\tsljit_ins ins;\n#endif /* NEON */\n\tunion {\n\t\tsljit_u32 imm[2];\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n#if defined(__ARM_NEON) && __ARM_NEON\n\tif (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) {\n\t\texp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff;\n\n\t\tif (exp == 0x100 || exp == 0xff) {\n\t\t\tins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f);\n\t\t\treturn push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf));\n\t\t}\n\t}\n#endif /* NEON */\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0]));\n\tif (u.imm[0] == u.imm[1])\n\t\treturn push_inst(compiler, VMOV2 | RN(TMP_REG1) | RD(TMP_REG1) | VM(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1]));\n\treturn push_inst(compiler, VMOV2 | RN(TMP_REG2) | RD(TMP_REG1) | VM(freg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_s32 reg2;\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\n\t\tinst = VMOV2 | RN(reg) | RD(reg2) | VM(freg);\n\t} else {\n\t\tinst = VMOV | VN(freg) | RD(reg);\n\n\t\tif (!(op & SLJIT_32))\n\t\t\tinst |= 1 << 7;\n\t}\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_FROM_F64)\n\t\tinst |= 1 << 20;\n\n\treturn push_inst(compiler, inst);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn 0x00000000;\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 0x10000000;\n\n\tcase SLJIT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x20000000;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_LESS:\n\t\treturn 0x30000000;\n\n\tcase SLJIT_NOT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x30000000;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_GREATER_EQUAL:\n\t\treturn 0x20000000;\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn 0x80000000;\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn 0x90000000;\n\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn 0xb0000000;\n\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\treturn 0xa0000000;\n\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\treturn 0xc0000000;\n\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn 0xd0000000;\n\n\tcase SLJIT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x10000000;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_UNORDERED:\n\t\treturn 0x60000000;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x00000000;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ORDERED:\n\t\treturn 0x70000000;\n\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\treturn 0x40000000;\n\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\treturn 0x50000000;\n\n\tdefault:\n\t\tSLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_REG_ARG);\n\t\treturn 0xe0000000;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tif (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY))\n\t\tPTR_FAIL_IF(push_cpool(compiler));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tSLJIT_ASSERT(reg_map[TMP_REG1] != 14);\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tif (type >= SLJIT_FAST_CALL)\n\t\tPTR_FAIL_IF(prepare_blx(compiler));\n\n\tPTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,\n\t\ttype <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(compiler, type), 0));\n\tjump->addr = compiler->size - 1;\n\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tcompiler->patches++;\n\n\tif (type >= SLJIT_FAST_CALL) {\n\t\tjump->flags |= IS_BL;\n\t\tjump->addr = compiler->size;\n\t\tPTR_FAIL_IF(emit_blx(compiler));\n\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tjump->addr = compiler->size;\n\tif (type >= SLJIT_FAST_CALL)\n\t\tjump->flags |= IS_BL;\n\tPTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(compiler, type)));\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\treturn jump;\n}\n\n#ifdef __SOFTFP__\n\nstatic sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src, sljit_u32 *extra_space)\n{\n\tsljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;\n\tsljit_u32 offset = 0;\n\tsljit_u32 word_arg_offset = 0;\n\tsljit_u32 src_offset = 4 * sizeof(sljit_sw);\n\tsljit_u32 float_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_u8 offsets[4];\n\tsljit_u8 *offset_ptr = offsets;\n\n\tif (src && FAST_IS_REG(*src))\n\t\tsrc_offset = (sljit_u32)reg_map[*src] * sizeof(sljit_sw);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset & 0x7)\n\t\t\t\toffset += sizeof(sljit_sw);\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_f64);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_f32);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_sw);\n\t\t\tword_arg_offset += sizeof(sljit_sw);\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {\n\t\t/* Keep lr register on the stack. */\n\t\tif (is_tail_call)\n\t\t\toffset += sizeof(sljit_sw);\n\n\t\toffset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_u32)0x7;\n\n\t\t*extra_space = offset;\n\n\t\tif (is_tail_call)\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | offset));\n\t} else {\n\t\tif (is_tail_call)\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\t*extra_space = 0;\n\t}\n\n\t/* Process arguments in reversed direction. */\n\twhile (types) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tfloat_arg_count--;\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tSLJIT_ASSERT((offset & 0x7) == 0);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\tif (src_offset == offset || src_offset == offset + sizeof(sljit_sw)) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));\n\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst(compiler, VMOV2 | 0x100000 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, VSTR_F32 | 0x800100 | RN(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tfloat_arg_count--;\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\tif (src_offset == offset) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));\n\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (offset << 10)));\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, VSTR_F32 | 0x800000 | RN(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_offset -= sizeof(sljit_sw);\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tSLJIT_ASSERT(offset >= word_arg_offset);\n\n\t\t\tif (offset != word_arg_offset) {\n\t\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\t\tif (src_offset == offset) {\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));\n\t\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t\t}\n\t\t\t\t\telse if (src_offset == word_arg_offset) {\n\t\t\t\t\t\t*src = (sljit_s32)(SLJIT_R0 + (offset >> 2));\n\t\t\t\t\t\tsrc_offset = offset;\n\t\t\t\t\t}\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV | (offset << 10) | (word_arg_offset >> 2)));\n\t\t\t\t} else\n\t\t\t\t\tFAIL_IF(push_inst(compiler, STR | 0x800000 | RN(SLJIT_SP) | (word_arg_offset << 10) | (offset - 4 * sizeof(sljit_sw))));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)\n{\n\tif ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64)\n\t\tFAIL_IF(push_inst(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));\n\tif ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32)\n\t\tFAIL_IF(push_inst(compiler, VMOV | (0 << 16) | (0 << 12)));\n\n\treturn SLJIT_SUCCESS;\n}\n\n#else /* !__SOFTFP__ */\n\nstatic sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)\n{\n\tsljit_u32 offset = SLJIT_FR0;\n\tsljit_u32 new_offset = SLJIT_FR0;\n\tsljit_u32 f32_offset = 0;\n\n\t/* Remove return value. */\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset != new_offset)\n\t\t\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,\n\t\t\t\t\tSLJIT_32, new_offset, offset, 0)));\n\n\t\t\tnew_offset++;\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (f32_offset != 0) {\n\t\t\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,\n\t\t\t\t\t0x400000, f32_offset, offset, 0)));\n\t\t\t\tf32_offset = 0;\n\t\t\t} else {\n\t\t\t\tif (offset != new_offset)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,\n\t\t\t\t\t\t0, new_offset, offset, 0)));\n\t\t\t\tf32_offset = new_offset;\n\t\t\t\tnew_offset++;\n\t\t\t}\n\t\t\toffset++;\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#endif /* __SOFTFP__ */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n#ifdef __SOFTFP__\n\tstruct sljit_jump *jump;\n\tsljit_u32 extra_space = (sljit_u32)type;\n#endif\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n#ifdef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG) {\n\t\tPTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL, &extra_space));\n\t\tSLJIT_ASSERT((extra_space & 0x7) == 0);\n\n\t\tif ((type & SLJIT_CALL_RETURN) && extra_space == 0)\n\t\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tjump = sljit_emit_jump(compiler, type);\n\t\tPTR_FAIL_IF(jump == NULL);\n\n\t\tif (extra_space > 0) {\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,\n\t\t\t\t\tTMP_REG2, SLJIT_SP, extra_space - sizeof(sljit_sw))));\n\n\t\t\tPTR_FAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | extra_space));\n\n\t\t\tif (type & SLJIT_CALL_RETURN) {\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, BX | RM(TMP_REG2)));\n\t\t\t\treturn jump;\n\t\t\t}\n\t\t}\n\n\t\tSLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));\n\t\tPTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));\n\t\treturn jump;\n\t}\n#endif /* __SOFTFP__ */\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n#ifndef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tPTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));\n#endif /* !__SOFTFP__ */\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tSLJIT_ASSERT(reg_map[TMP_REG1] != 14);\n\n\tif (src != SLJIT_IMM) {\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tSLJIT_ASSERT(reg_map[src] != 14);\n\t\t\treturn push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));\n\t\t}\n\n\t\tSLJIT_ASSERT(src & SLJIT_MEM);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\treturn push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1));\n\t}\n\n\t/* These jumps are converted to jump/call instructions when possible. */\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));\n\tjump->u.target = (sljit_uw)srcw;\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tif (type >= SLJIT_FAST_CALL)\n\t\tFAIL_IF(prepare_blx(compiler));\n\tjump->addr = compiler->size;\n\tFAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));\n\tif (type >= SLJIT_FAST_CALL) {\n\t\tjump->addr = compiler->size;\n\t\tFAIL_IF(emit_blx(compiler));\n\t}\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tjump->addr = compiler->size;\n\tFAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#ifdef __SOFTFP__\n\tsljit_u32 extra_space = (sljit_u32)type;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));\n\t\tsrc = TMP_REG1;\n\t}\n\n#ifdef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG) {\n\t\tFAIL_IF(softfloat_call_with_args(compiler, arg_types, &src, &extra_space));\n\t\tSLJIT_ASSERT((extra_space & 0x7) == 0);\n\n\t\tif ((type & SLJIT_CALL_RETURN) && extra_space == 0)\n\t\t\ttype = SLJIT_JUMP;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));\n\n\t\tif (extra_space > 0) {\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\tFAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1,\n\t\t\t\t\tTMP_REG2, SLJIT_SP, extra_space - sizeof(sljit_sw))));\n\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | extra_space));\n\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\treturn push_inst(compiler, BX | RM(TMP_REG2));\n\t\t}\n\n\t\tSLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));\n\t\treturn softfloat_post_call_with_args(compiler, arg_types);\n\t}\n#endif /* __SOFTFP__ */\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tFAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n#ifndef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tFAIL_IF(hardfloat_call_with_args(compiler, arg_types));\n#endif /* !__SOFTFP__ */\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\n#ifdef __SOFTFP__\n\nstatic SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n\tif (compiler->options & SLJIT_ENTER_REG_ARG) {\n\t\tif (src == SLJIT_FR0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);\n\t}\n\n\tif (FAST_IS_REG(src)) {\n\t\tif (op & SLJIT_32)\n\t\t\treturn push_inst(compiler, VMOV | (1 << 20) | RD(SLJIT_R0) | VN(src));\n\t\treturn push_inst(compiler, VMOV2 | (1 << 20) | RD(SLJIT_R0) | RN(SLJIT_R1) | VM(src));\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (op & SLJIT_32)\n\t\treturn sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, src, srcw);\n\treturn sljit_emit_mem(compiler, SLJIT_MOV, SLJIT_REG_PAIR(SLJIT_R0, SLJIT_R1), src, srcw);\n}\n\n#endif /* __SOFTFP__ */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 dst_reg, flags = GET_ALL_FLAGS(op);\n\tsljit_ins cc, ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\tcc = get_cc(compiler, type);\n\tdst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (op < SLJIT_ADD) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | SRC2_IMM | 0));\n\t\tFAIL_IF(push_inst(compiler, ((MOV | RD(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tins = (op == SLJIT_AND ? AND : (op == SLJIT_OR ? ORR : EOR));\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG2));\n\n\tFAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));\n\n\tif (op == SLJIT_AND)\n\t\tFAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));\n\n\tif (flags & SLJIT_SET_Z)\n\t\treturn push_inst(compiler, MOV | SET_FLAGS | RD(TMP_REG2) | RM(dst_reg));\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_ins cc, tmp, tmp2;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (src2_reg != dst_reg && src1 == dst_reg) {\n\t\tsrc1 = src2_reg;\n\t\tsrc1w = 0;\n\t\tsrc2_reg = dst_reg;\n\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\ttype ^= 0x1;\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG1));\n\n\t\tif (src2_reg != dst_reg) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t}\n\t} else if (dst_reg != src2_reg)\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src2_reg)));\n\n\tif (type & SLJIT_COMPARE_SELECT)\n\t\ttype ^= 0x1;\n\n\tcc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));\n\n\tif (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {\n\t\ttmp = get_imm((sljit_uw)src1w);\n\t\tif (tmp) {\n\t\t\tif (type & SLJIT_COMPARE_SELECT)\n\t\t\t\tFAIL_IF(push_inst(compiler, (CMP | SET_FLAGS | RN(dst_reg) | tmp)));\n\t\t\treturn push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc);\n\t\t}\n\n\t\ttmp = get_imm(~(sljit_uw)src1w);\n\t\tif (tmp && (type & SLJIT_COMPARE_SELECT)) {\n\t\t\ttmp2 = get_imm((sljit_uw)-src1w);\n\t\t\tif (tmp2)\n\t\t\t\tFAIL_IF(push_inst(compiler, (CMN | SET_FLAGS | RN(dst_reg) | tmp2)));\n\t\t\telse\n\t\t\t\ttmp = 0;\n\t\t}\n\n\t\tif (tmp)\n\t\t\treturn push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc);\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\t\tif (!(type & SLJIT_COMPARE_SELECT)) {\n\t\t\ttmp = (sljit_ins)src1w;\n\t\t\tFAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff)));\n\t\t\tif (tmp <= 0xffff)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff));\n\t\t}\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (type & SLJIT_COMPARE_SELECT)\n\t\tFAIL_IF(push_inst(compiler, (CMP | SET_FLAGS | RN(dst_reg) | RM(src1))));\n\n\treturn push_inst(compiler, ((MOV | RD(dst_reg) | RM(src1)) & ~COND_MASK) | cc);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_ins cc;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\ttype ^= SLJIT_32;\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, (type & SLJIT_32), dst_freg, src2_freg, 0)));\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG2, src1, src1w));\n\t\tsrc1 = TMP_FREG2;\n\t}\n\n\tcc = get_cc(compiler, type & ~SLJIT_32);\n\treturn push_inst(compiler, EMIT_FPU_OPERATION((VMOV_F32 & ~COND_MASK) | cc, (type & SLJIT_32), dst_freg, src1, 0));\n}\n\n#undef EMIT_FPU_OPERATION\n\nstatic sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset)\n{\n\tsljit_s32 arg = *mem;\n\tsljit_sw argw = *memw;\n\tsljit_uw imm, tmp;\n\tsljit_sw mask = 0xfff;\n\tsljit_sw sign = 0x1000;\n\n\tSLJIT_ASSERT(max_offset >= 0xf00);\n\n\t*mem = TMP_REG1;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\t*memw = 0;\n\t\treturn push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)(argw & 0x3) << 7));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (arg) {\n\t\tif (argw <= max_offset && argw >= -mask) {\n\t\t\t*mem = arg;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tif (argw >= 0) {\n\t\t\ttmp = (sljit_uw)(argw & (sign | mask));\n\t\t\ttmp = (sljit_uw)((argw + ((tmp <= (sljit_uw)max_offset || tmp == (sljit_uw)sign) ? 0 : sign)) & ~mask);\n\t\t\timm = get_imm(tmp);\n\n\t\t\tif (imm) {\n\t\t\t\t*memw = argw - (sljit_sw)tmp;\n\t\t\t\tSLJIT_ASSERT(*memw >= -mask && *memw <= max_offset);\n\n\t\t\t\treturn push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | imm);\n\t\t\t}\n\t\t} else {\n\t\t\ttmp = (sljit_uw)(-argw & (sign | mask));\n\t\t\ttmp = (sljit_uw)((-argw + ((tmp <= (sljit_uw)((sign << 1) - max_offset - 1)) ? 0 : sign)) & ~mask);\n\t\t\timm = get_imm(tmp);\n\n\t\t\tif (imm) {\n\t\t\t\t*memw = argw + (sljit_sw)tmp;\n\t\t\t\tSLJIT_ASSERT(*memw >= -mask && *memw <= max_offset);\n\n\t\t\t\treturn push_inst(compiler, SUB | RD(TMP_REG1) | RN(arg) | imm);\n\t\t\t}\n\t\t}\n\t}\n\n\ttmp = (sljit_uw)(argw & (sign | mask));\n\ttmp = (sljit_uw)((argw + ((tmp <= (sljit_uw)max_offset || tmp == (sljit_uw)sign) ? 0 : sign)) & ~mask);\n\t*memw = argw - (sljit_sw)tmp;\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, tmp));\n\n\tif (arg == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(arg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));\n\n\tflags = WORD_SIZE;\n\n\tif (!(type & SLJIT_MEM_STORE)) {\n\t\tif (REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw), TMP_REG1));\n\t\t\treturn emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw, TMP_REG1);\n\t\t}\n\n\t\tflags = WORD_SIZE | LOAD_DATA;\n\t}\n\n\tFAIL_IF(emit_op_mem(compiler, flags, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw, TMP_REG1));\n\treturn emit_op_mem(compiler, flags, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw), TMP_REG1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\tsljit_ins is_type1_transfer, inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));\n\n\tis_type1_transfer = 1;\n\n\tswitch (type & 0xff) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_P:\n\t\tflags = WORD_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n\t\tflags = BYTE_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_S8:\n\t\tif (!(type & SLJIT_MEM_STORE))\n\t\t\tis_type1_transfer = 0;\n\t\tflags = BYTE_SIZE | SIGNED;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tis_type1_transfer = 0;\n\t\tflags = HALF_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_S16:\n\t\tis_type1_transfer = 0;\n\t\tflags = HALF_SIZE | SIGNED;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\tflags = WORD_SIZE;\n\t\tbreak;\n\t}\n\n\tif (!(type & SLJIT_MEM_STORE))\n\t\tflags |= LOAD_DATA;\n\n\tSLJIT_ASSERT(is_type1_transfer == !!IS_TYPE1_TRANSFER(flags));\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tif (!is_type1_transfer && memw != 0)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t} else {\n\t\tif (is_type1_transfer) {\n\t\t\tif (memw > 4095 || memw < -4095)\n\t\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\t} else if (memw > 255 || memw < -255)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (type & SLJIT_MEM_SUPP)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tmemw &= 0x3;\n\n\t\tinst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_ins)memw << 7));\n\n\t\tif (is_type1_transfer)\n\t\t\tinst |= (1 << 25);\n\n\t\tif (type & SLJIT_MEM_POST)\n\t\t\tinst ^= (1 << 24);\n\t\telse\n\t\t\tinst |= (1 << 21);\n\n\t\treturn push_inst(compiler, inst);\n\t}\n\n\tinst = EMIT_DATA_TRANSFER(flags, 0, reg, mem & REG_MASK, 0);\n\n\tif (type & SLJIT_MEM_POST)\n\t\tinst ^= (1 << 24);\n\telse\n\t\tinst |= (1 << 21);\n\n\tif (is_type1_transfer) {\n\t\tif (memw >= 0)\n\t\t\tinst |= (1 << 23);\n\t\telse\n\t\t\tmemw = -memw;\n\n\t\treturn push_inst(compiler, inst | (sljit_ins)memw);\n\t}\n\n\tif (memw >= 0)\n\t\tinst |= (1 << 23);\n\telse\n\t\tmemw = -memw;\n\n\treturn push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_ins)memw));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));\n\n\tif (type & SLJIT_MEM_ALIGNED_32)\n\t\treturn emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw);\n\n\tif (type & SLJIT_MEM_STORE) {\n\t\tFAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2)));\n\n\t\tif (type & SLJIT_32)\n\t\t\treturn emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1);\n\n\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));\n\t\tmem |= SLJIT_MEM;\n\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));\n\t\tFAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | 0x80 | RD(TMP_REG2)));\n\t\treturn emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw + 4, TMP_REG1);\n\t}\n\n\tif (type & SLJIT_32) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1));\n\t\treturn push_inst(compiler, VMOV | VN(freg) | RD(TMP_REG2));\n\t}\n\n\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));\n\tmem |= SLJIT_MEM;\n\n\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1));\n\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, mem, memw + 4, TMP_REG1));\n\treturn push_inst(compiler, VMOV2 | VM(freg) | RD(TMP_REG2) | RN(TMP_REG1));\n}\n\nstatic sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw)\n{\n\tsljit_s32 mem = *mem_ptr;\n\tsljit_uw imm;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\t*mem_ptr = TMP_REG1;\n\t\treturn push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 7));\n\t}\n\n\tif (SLJIT_UNLIKELY(!(mem & REG_MASK))) {\n\t\t*mem_ptr = TMP_REG1;\n\t\treturn load_immediate(compiler, TMP_REG1, (sljit_uw)memw);\n\t}\n\n\tmem &= REG_MASK;\n\n\tif (memw == 0) {\n\t\t*mem_ptr = mem;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t*mem_ptr = TMP_REG1;\n\timm = get_imm((sljit_uw)(memw < 0 ? -memw : memw));\n\n\tif (imm != 0)\n\t\treturn push_inst(compiler, ((memw < 0) ? SUB : ADD) | RD(TMP_REG1) | RN(mem) | imm);\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\treturn push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(mem));\n}\n\nstatic SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg)\n{\n\tfreg += freg & 0x1;\n\n\tSLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS));\n\n\tif (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)\n\t\tfreg--;\n\n\treturn freg;\n}\n\n#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (!(srcdst & SLJIT_MEM)) {\n\t\tif (reg_size == 4)\n\t\t\tsrcdst = simd_get_quad_reg_index(srcdst);\n\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = VD(srcdst) | VN(vreg) | VM(vreg);\n\t\telse\n\t\t\tins = VD(vreg) | VN(srcdst) | VM(srcdst);\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 6;\n\n\t\treturn push_inst(compiler, VORR | ins);\n\t}\n\n\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\tif (elem_size > 3)\n\t\telem_size = 3;\n\n\tins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(vreg)\n\t\t| (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8));\n\n\tSLJIT_ASSERT(reg_size >= alignment);\n\n\tif (alignment == 3)\n\t\tins |= 0x10;\n\telse if (alignment >= 3)\n\t\tins |= 0x20;\n\n\treturn push_inst(compiler, ins | RN(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf);\n}\n\nstatic sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value)\n{\n\tsljit_ins result;\n\n\tif (elem_size > 1 && (sljit_u16)value == (value >> 16)) {\n\t\telem_size = 1;\n\t\tvalue = (sljit_u16)value;\n\t}\n\n\tif (elem_size == 1 && (sljit_u8)value == (value >> 8)) {\n\t\telem_size = 0;\n\t\tvalue = (sljit_u8)value;\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tSLJIT_ASSERT(value <= 0xff);\n\t\tresult = 0xe00;\n\t\tbreak;\n\tcase 1:\n\t\tSLJIT_ASSERT(value <= 0xffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x800;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & 0xff) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xa00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue ^= (sljit_uw)0xffff;\n\t\t\tresult = (1 << 5);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_ASSERT(value <= 0xffffffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff00) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0x200;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff0000) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0x400;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff000000) == 0) {\n\t\t\t\tvalue >>= 24;\n\t\t\t\tresult |= 0x600;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xc00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0xd00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue = ~value;\n\t\t\tresult = (1 << 5);\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 17) | result;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imm;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (src == SLJIT_IMM && srcw == 0)\n\t\treturn push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(vreg));\n\n\tif (SLJIT_UNLIKELY(elem_size == 3)) {\n\t\tSLJIT_ASSERT(type & SLJIT_SIMD_FLOAT);\n\n\t\tif (src & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw));\n\t\t\tsrc = vreg;\n\t\t} else if (vreg != src)\n\t\t\tFAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)));\n\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\tif (vreg != src)\n\t\t\treturn push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\n\t\tins = (sljit_ins)(elem_size << 6);\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 5;\n\n\t\treturn push_inst(compiler, VLD1_r | ins | VD(vreg) | RN(src) | 0xf);\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tSLJIT_ASSERT(elem_size == 2);\n\t\tins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2));\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 6;\n\n\t\treturn push_inst(compiler, VDUP_s | ins | VD(vreg) | (sljit_ins)freg_map[src]);\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tif (elem_size < 2)\n\t\t\tsrcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\timm = simd_get_imm(elem_size, (sljit_uw)srcw);\n\n\t\tif (imm != ~(sljit_ins)0) {\n\t\t\tif (reg_size == 4)\n\t\t\t\timm |= (sljit_ins)1 << 6;\n\n\t\t\treturn push_inst(compiler, VMOV_i | imm | VD(vreg));\n\t\t}\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tins = 1 << 22;\n\t\tbreak;\n\tcase 1:\n\t\tins = 1 << 5;\n\t\tbreak;\n\tdefault:\n\t\tins = 0;\n\t\tbreak;\n\t}\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 21;\n\n\treturn push_inst(compiler, VDUP | ins | VN(vreg) | RD(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6);\n\n\t\tif (type & SLJIT_SIMD_FLOAT) {\n\t\t\tif (elem_size == 3 && !(srcdst & SLJIT_MEM)) {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\t\t\tif (srcdst != vreg)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(srcdst) | VM(srcdst)));\n\n\t\t\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\t\t\treturn push_inst(compiler, VMOV_i | VD(vreg));\n\t\t\t}\n\n\t\t\tif (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) {\n\t\t\t\tFAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(vreg) | VM(vreg)));\n\t\t\t\tsrcdst = TMP_FREG2;\n\t\t\t\tsrcdstw = 0;\n\t\t\t}\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, VMOV_i | ins | VD(vreg)));\n\t}\n\n\tif (reg_size == 4 && lane_index >= (0x8 >> elem_size)) {\n\t\tlane_index -= (0x8 >> elem_size);\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tif (elem_size == 3)\n\t\t\treturn emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw);\n\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\t\tlane_index = lane_index << elem_size;\n\t\tins = (sljit_ins)((elem_size << 10) | (lane_index << 5));\n\t\treturn push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(vreg) | RN(srcdst) | 0xf);\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size == 3) {\n\t\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\t\treturn push_inst(compiler, VORR | VD(srcdst) | VN(vreg) | VM(vreg));\n\t\t\treturn push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(vreg) | VM(srcdst));\n\t\t}\n\n\t\tif (type & SLJIT_SIMD_STORE) {\n\t\t\tif (freg_ebit_map[vreg] == 0) {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tvreg = SLJIT_F64_SECOND(vreg);\n\n\t\t\t\treturn push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(vreg));\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1)));\n\t\t\treturn push_inst(compiler, VMOV | VN(srcdst) | RD(TMP_REG1));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(srcdst) | RD(TMP_REG1)));\n\t\treturn push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1));\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tif (elem_size < 2)\n\t\t\tsrcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw));\n\t\tsrcdst = TMP_REG1;\n\t}\n\n\tif (elem_size == 0)\n\t\tins = 0x400000;\n\telse if (elem_size == 1)\n\t\tins = 0x20;\n\telse\n\t\tins = 0;\n\n\tlane_index = lane_index << elem_size;\n\tins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5));\n\n\tif (type & SLJIT_SIMD_STORE) {\n\t\tins |= (1 << 20);\n\n\t\tif (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED))\n\t\t\tins |= (1 << 23);\n\t}\n\n\treturn push_inst(compiler, VMOV_s | ins | VN(vreg) | RD(srcdst));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4) {\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\t\tsrc = simd_get_quad_reg_index(src);\n\n\t\tif (src_lane_index >= (0x8 >> elem_size)) {\n\t\t\tsrc_lane_index -= (0x8 >> elem_size);\n\t\t\tsrc += SLJIT_QUAD_OTHER_HALF(src);\n\t\t}\n\t}\n\n\tif (elem_size == 3) {\n\t\tif (vreg != src)\n\t\t\tFAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)));\n\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\tif (vreg != src)\n\t\t\treturn push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size));\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 6;\n\n\treturn push_inst(compiler, VDUP_s | ins | VD(vreg) | VM(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_s32 dst_reg;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\t\tif (reg_size == 4 && elem2_size - elem_size == 1)\n\t\t\tFAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(vreg) | RN(src) | 0xf));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(vreg) | RN(src) | 0xf));\n\t\tsrc = vreg;\n\t} else if (reg_size == 4)\n\t\tsrc = simd_get_quad_reg_index(src);\n\n\tif (!(type & SLJIT_SIMD_FLOAT)) {\n\t\tdst_reg = (reg_size == 4) ? vreg : TMP_FREG2;\n\n\t\tdo {\n\t\t\tFAIL_IF(push_inst(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 24))\n\t\t\t\t| ((sljit_ins)1 << (19 + elem_size)) | VD(dst_reg) | VM(src)));\n\t\t\tsrc = dst_reg;\n\t\t} while (++elem_size < elem2_size);\n\n\t\tif (dst_reg == TMP_FREG2)\n\t\t\treturn push_inst(compiler, VORR | VD(vreg) | VN(TMP_FREG2) | VM(TMP_FREG2));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* No SIMD variant, must use VFP instead. */\n\tSLJIT_ASSERT(reg_size == 4);\n\n\tif (vreg == src) {\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\tFAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20));\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\treturn push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src));\n\t}\n\n\tFAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src)));\n\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\treturn push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imms;\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\timms = 0x243219;\n\t\tins = VSHR | (1 << 24) | (0x9 << 16);\n\t\tbreak;\n\tcase 1:\n\t\timms = (reg_size == 4) ? 0x243219 : 0x2231;\n\t\tins = VSHR | (1 << 24) | (0x11 << 16);\n\t\tbreak;\n\tcase 2:\n\t\timms = (reg_size == 4) ? 0x2231 : 0x21;\n\t\tins = VSHR | (1 << 24) | (0x21 << 16);\n\t\tbreak;\n\tdefault:\n\t\timms = 0x21;\n\t\tins = VSHR | (1 << 24) | (0x1 << 16) | (1 << 7);\n\t\tbreak;\n\t}\n\n\tif (reg_size == 4) {\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\t\tins |= (sljit_ins)1 << 6;\n\t}\n\n\tSLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0);\n\tFAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(vreg)));\n\n\tif (reg_size == 4 && elem_size > 0)\n\t\tFAIL_IF(push_inst(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD(TMP_FREG2) | VM(TMP_FREG2)));\n\n\tins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0;\n\n\twhile (imms >= 0x100) {\n\t\tFAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | ((imms & 0xff) << 16) | VD(TMP_FREG2) | VM(TMP_FREG2)));\n\t\timms >>= 8;\n\t}\n\n\tFAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | (1 << 7) | (imms << 16) | VD(TMP_FREG2) | VM(TMP_FREG2)));\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tFAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(dst_r) | VN(TMP_FREG2)));\n\n\tif (reg_size == 4 && elem_size == 0) {\n\t\tSLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]);\n\t\tFAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(TMP_REG2) | VN(TMP_FREG1)));\n\t\tFAIL_IF(push_inst(compiler, ORR | RD(dst_r) | RN(dst_r) | RM(TMP_REG2) | (0x8 << 7)));\n\t}\n\n\tif (dst_r == TMP_REG1)\n\t\treturn emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment;\n\tsljit_ins ins = 0, load_ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = VAND;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = VORR;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = VEOR;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tins = VTBL;\n\t\tbreak;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (elem_size > 3)\n\t\t\telem_size = 3;\n\n\t\tload_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8));\n\t\talignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\n\t\tSLJIT_ASSERT(reg_size >= alignment);\n\n\t\tif (alignment == 3)\n\t\t\tload_ins |= 0x10;\n\t\telse if (alignment >= 4)\n\t\t\tload_ins |= 0x20;\n\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w));\n\t\tFAIL_IF(push_inst(compiler, load_ins | VD(TMP_FREG2) | RN(src2) | ((sljit_ins)elem_size) << 6 | 0xf));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tif (reg_size == 4) {\n\t\tdst_vreg = simd_get_quad_reg_index(dst_vreg);\n\t\tsrc1_vreg = simd_get_quad_reg_index(src1_vreg);\n\t\tsrc2 = simd_get_quad_reg_index(src2);\n\n\t\tif (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) {\n\t\t\tins |= (sljit_ins)1 << 8;\n\n\t\t\tFAIL_IF(push_inst(compiler, ins | VD(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN(src1_vreg) | VM(src2)));\n\t\t\tsrc2 += SLJIT_QUAD_OTHER_HALF(src2);\n\t\t\tFAIL_IF(push_inst(compiler, ins | VD(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN(src1_vreg) | VM(src2)));\n\n\t\t\tif (dst_vreg == src1_vreg)\n\t\t\t\treturn push_inst(compiler, VORR | VD(dst_vreg) | VN(TMP_FREG2) | VM(TMP_FREG2));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tins |= (sljit_ins)1 << 6;\n\t}\n\n\treturn push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2));\n}\n\n#undef FPU_LOAD\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_u32 ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV_U8:\n\t\tins = LDREXB;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = LDREXH;\n\t\tbreak;\n\tdefault:\n\t\tins = LDREX;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | RN(mem_reg) | RD(dst_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_u32 ins;\n\n\t/* temp_reg == mem_reg is undefined so use another temp register */\n\tSLJIT_UNUSED_ARG(temp_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV_U8:\n\t\tins = STREXB;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = STREXH;\n\t\tbreak;\n\tdefault:\n\t\tins = STREX;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst(compiler, ins | RN(mem_reg) | RD(TMP_REG1) | RM(src_reg)));\n\tif (op & SLJIT_SET_ATOMIC_STORED)\n\t\treturn push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(TMP_REG1));\n\n\treturn SLJIT_SUCCESS;\n}\n\n#define SLJIT_EMIT_CONST_U8(c) \\\n\t(((c) & 0x100) != 0 ? (MVN | SRC2_IMM | (~(c) & 0xff)) : (MOV | SRC2_IMM | ((c) & 0xff)))\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_SIZE;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (GET_OPCODE(op) == SLJIT_MOV_U8) {\n\t\tPTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_U8(init_value) | RD(dst_r)));\n\t\tmem_flags = BYTE_SIZE;\n\t} else {\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\t\tPTR_FAIL_IF(push_inst_with_unique_literal(compiler,\n\t\t\tEMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_ins)init_value));\n\t\tcompiler->patches++;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\t\tPTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw, TMP_REG1));\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, dst, dstw, TMP_REG1));\n\t}\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tPTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, target_r, TMP_PC, 0), 0));\n\tcompiler->patches++;\n#else /* !SLJIT_CONFIG_ARM_V6 */\n\tPTR_FAIL_IF(push_inst(compiler, RD(target_r)));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 1);\n\n#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)\n\tcompiler->size += 1;\n#endif /* SLJIT_CONFIG_ARM_V7 */\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(dst_r) | RM(TMP_REG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tset_jump_addr(addr, executable_offset, new_target, 1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_ins *inst;\n\n\tif (GET_OPCODE(op) != SLJIT_MOV_U8) {\n\t\tset_const_value(addr, executable_offset, (sljit_uw)new_constant, 1);\n\t\treturn;\n\t}\n\n\tinst = (sljit_ins*)addr;\n\tSLJIT_ASSERT((inst[0] & 0xfff00000) == (MOV | SRC2_IMM) || (inst[0] & 0xfff00000) == (MVN | SRC2_IMM));\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t*inst = SLJIT_EMIT_CONST_U8(new_constant) | (*inst & 0xf000);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\tinst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifdef __ARM_FEATURE_ATOMICS\n#define ARM_ATOMIC_INFO \" (LSE)\"\n#else\n#define ARM_ATOMIC_INFO \"\"\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\treturn \"ARM-64\" ARM_ATOMIC_INFO SLJIT_CPUINFO;\n}\n\n/* Length of an instruction word */\ntypedef sljit_u32 sljit_ins;\n\n#define TMP_ZERO\t(0)\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_LR\t\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n#define TMP_FP\t\t(SLJIT_NUMBER_OF_REGISTERS + 5)\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\n/* r18 - platform register, currently not used */\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {\n\t31, 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 31, 9, 10, 30, 29\n};\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {\n\t0, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 14, 13, 12, 11, 10, 9, 8, 30, 31\n};\n\n#define W_OP ((sljit_ins)1 << 31)\n#define RD(rd) ((sljit_ins)reg_map[rd])\n#define RT(rt) ((sljit_ins)reg_map[rt])\n#define RN(rn) ((sljit_ins)reg_map[rn] << 5)\n#define RT2(rt2) ((sljit_ins)reg_map[rt2] << 10)\n#define RM(rm) ((sljit_ins)reg_map[rm] << 16)\n#define VD(vd) ((sljit_ins)freg_map[vd])\n#define VT(vt) ((sljit_ins)freg_map[vt])\n#define VT2(vt) ((sljit_ins)freg_map[vt] << 10)\n#define VN(vn) ((sljit_ins)freg_map[vn] << 5)\n#define VM(vm) ((sljit_ins)freg_map[vm] << 16)\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n#define ADC\t\t0x9a000000\n#define ADD\t\t0x8b000000\n#define ADDE\t\t0x8b200000\n#define ADDI\t\t0x91000000\n#define ADR\t\t0x10000000\n#define ADRP\t\t0x90000000\n#define AND\t\t0x8a000000\n#define ANDI\t\t0x92000000\n#define AND_v\t\t0x0e201c00\n#define ASRV\t\t0x9ac02800\n#define B\t\t0x14000000\n#define B_CC\t\t0x54000000\n#define BL\t\t0x94000000\n#define BLR\t\t0xd63f0000\n#define BR\t\t0xd61f0000\n#define BRK\t\t0xd4200000\n#define CAS\t\t0xc8a07c00\n#define CASB\t\t0x08a07c00\n#define CASH\t\t0x48a07c00\n#define CBZ\t\t0xb4000000\n#define CCMPI\t\t0xfa400800\n#define CLZ\t\t0xdac01000\n#define CSEL\t\t0x9a800000\n#define CSINC\t\t0x9a800400\n#define CSINV\t\t0xda800000\n#define DMB_SY\t\t0xd5033fbf\n#define DUP_e\t\t0x0e000400\n#define DUP_g\t\t0x0e000c00\n#define EOR\t\t0xca000000\n#define EOR_v\t\t0x2e201c00\n#define EORI\t\t0xd2000000\n#define EXTR\t\t0x93c00000\n#define FABS\t\t0x1e60c000\n#define FADD\t\t0x1e602800\n#define FCMP\t\t0x1e602000\n#define FCSEL\t\t0x1e600c00\n#define FCVT\t\t0x1e224000\n#define FCVTL\t\t0x0e217800\n#define FCVTZS\t\t0x9e780000\n#define FDIV\t\t0x1e601800\n#define FMOV\t\t0x1e604000\n#define FMOV_R\t\t0x9e660000\n#define FMOV_I\t\t0x1e601000\n#define FMUL\t\t0x1e600800\n#define FNEG\t\t0x1e614000\n#define FSUB\t\t0x1e603800\n#define INS\t\t0x4e001c00\n#define INS_e\t\t0x6e000400\n#define LD1\t\t0x0c407000\n#define LD1_s\t\t0x0d400000\n#define LD1R\t\t0x0d40c000\n#define LDRI\t\t0xf9400000\n#define LDRI_F64\t0xfd400000\n#define LDRI_POST\t0xf8400400\n#define LDP\t\t0xa9400000\n#define LDP_F64\t\t0x6d400000\n#define LDP_POST\t0xa8c00000\n#define LDR_PRE\t\t0xf8400c00\n#define LDXR\t\t0xc85f7c00\n#define LDXRB\t\t0x085f7c00\n#define LDXRH\t\t0x485f7c00\n#define LSLV\t\t0x9ac02000\n#define LSRV\t\t0x9ac02400\n#define MADD\t\t0x9b000000\n#define MOVI\t\t0x0f000400\n#define MOVK\t\t0xf2800000\n#define MOVN\t\t0x92800000\n#define MOVZ\t\t0xd2800000\n#define NOP\t\t0xd503201f\n#define ORN\t\t0xaa200000\n#define ORR\t\t0xaa000000\n#define ORR_v\t\t0x0ea01c00\n#define ORRI\t\t0xb2000000\n#define RBIT\t\t0xdac00000\n#define RET\t\t0xd65f0000\n#define REV\t\t0xdac00c00\n#define REV16\t\t0xdac00400\n#define RORV\t\t0x9ac02c00\n#define SBC\t\t0xda000000\n#define SBFM\t\t0x93400000\n#define SCVTF\t\t0x9e620000\n#define SDIV\t\t0x9ac00c00\n#define SMADDL\t\t0x9b200000\n#define SMOV\t\t0x0e002c00\n#define SMULH\t\t0x9b403c00\n#define SSHLL\t\t0x0f00a400\n#define ST1\t\t0x0c007000\n#define ST1_s\t\t0x0d000000\n#define STP\t\t0xa9000000\n#define STP_F64\t\t0x6d000000\n#define STP_PRE\t\t0xa9800000\n#define STRB\t\t0x38206800\n#define STRBI\t\t0x39000000\n#define STRI\t\t0xf9000000\n#define STRI_F64\t0xfd000000\n#define STR_FI\t\t0x3d000000\n#define STR_FR\t\t0x3c206800\n#define STUR_FI\t\t0x3c000000\n#define STURBI\t\t0x38000000\n#define STXR\t\t0xc8007c00\n#define STXRB\t\t0x8007c00\n#define STXRH\t\t0x48007c00\n#define SUB\t\t0xcb000000\n#define SUBI\t\t0xd1000000\n#define SUBS\t\t0xeb000000\n#define TBZ\t\t0x36000000\n#define TBL_v\t\t0x0e000000\n#define UBFM\t\t0xd3400000\n#define UCVTF\t\t0x9e630000\n#define UDIV\t\t0x9ac00800\n#define UMOV\t\t0x0e003c00\n#define UMULH\t\t0x9bc03c00\n#define USHLL\t\t0x2f00a400\n#define USHR\t\t0x2f000400\n#define USRA\t\t0x2f001400\n#define XTN\t\t0x0e212800\n\n#define CSET\t\t(CSINC | RM(TMP_ZERO) | RN(TMP_ZERO))\n#define LDR\t\t(STRI | (1 << 22))\n#define LDRB\t\t(STRBI | (1 << 22))\n#define LDRH\t\t(LDRB | (1 << 30))\n#define MOV\t\t(ORR | RN(TMP_ZERO))\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)\n{\n\tsljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\t*ptr = ins;\n\tcompiler->size++;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)\n{\n\tFAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)(imm & 0xffff) << 5)));\n\tFAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)(imm >> 16) & 0xffff) << 5) | (1 << 21)));\n\tFAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)(imm >> 32) & 0xffff) << 5) | (2 << 21)));\n\treturn push_inst(compiler, MOVK | RD(dst) | ((sljit_ins)(imm >> 48) << 5) | (3 << 21));\n}\n\nstatic SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tjump->addr = jump_addr;\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (jump->flags & IS_COND) {\n\t\tdiff += SSIZE_OF(ins);\n\t\tif (diff <= 0xfffff && diff >= -0x100000) {\n\t\t\t*(--code_ptr) ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;\n\t\t\tjump->flags |= PATCH_COND;\n\t\t\tjump->addr -= sizeof(sljit_ins);\n\t\t\treturn code_ptr;\n\t\t}\n\t\tdiff -= SSIZE_OF(ins);\n\t}\n\n\tif (diff <= 0x7ffffff && diff >= -0x8000000) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] -= (4 << 5);\n\t\tjump->flags |= PATCH_B;\n\t\treturn code_ptr;\n\t}\n\n\tif (target_addr < 0x100000000l) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] -= (2 << 5);\n\t\tcode_ptr[2] = code_ptr[0];\n\t\treturn code_ptr + 2;\n\t}\n\n\tif (diff <= 0xfffff000l && diff >= -0x100000000l) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] -= (2 << 5);\n\t\tjump->flags |= PATCH_B32;\n\t\tcode_ptr[2] = code_ptr[0];\n\t\treturn code_ptr + 2;\n\t}\n\n\tif (target_addr < 0x1000000000000l) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] -= (1 << 5);\n\t\tjump->flags |= PATCH_ABS48;\n\t\tcode_ptr[3] = code_ptr[0];\n\t\treturn code_ptr + 3;\n\t}\n\nexit:\n\tjump->flags |= PATCH_ABS64;\n\tcode_ptr[4] = code_ptr[0];\n\treturn code_ptr + 4;\n}\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT(jump->flags < ((sljit_uw)4 << JUMP_SIZE_SHIFT));\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse {\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t}\n\n\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (diff <= 0xfffff && diff >= -0x100000) {\n\t\tjump->flags |= PATCH_B;\n\t\treturn 0;\n\t}\n\n\tif (diff <= 0xfffff000l && diff >= -0x100000000l) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_B32;\n\t\treturn 1;\n\t}\n\n\tif (addr < 0x100000000l) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));\n\t\treturn 1;\n\t}\n\n\tif (addr < 0x1000000000000l) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)2 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS48;\n\t\treturn 2;\n\t}\n\n\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));\n\tjump->flags |= PATCH_ABS64;\n\treturn 3;\n}\n\nstatic SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_sw addr = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);\n\tsljit_ins* buf_ptr = (sljit_ins*)jump->addr;\n\tsljit_u32 dst;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\tif (jump->flags & PATCH_COND) {\n\t\t\taddr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;\n\t\t\tSLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000);\n\t\t\tbuf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5);\n\t\t\treturn;\n\t\t}\n\n\t\tif (jump->flags & PATCH_B) {\n\t\t\taddr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;\n\t\t\tSLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000);\n\t\t\tbuf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff);\n\t\t\treturn;\n\t\t}\n\n\t\tdst = (buf_ptr[0] >> 5) & 0x1f;\n\n\t\tif (jump->flags & PATCH_B32) {\n\t\t\taddr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) & ~(sljit_sw)0xfff;\n\t\t\tSLJIT_ASSERT(addr <= 0xfffff000l && addr >= -0x100000000l);\n\t\t\tbuf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst;\n\t\t\tbuf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10);\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tdst = *buf_ptr;\n\n\t\tif (jump->flags & PATCH_B) {\n\t\t\taddr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);\n\t\t\tSLJIT_ASSERT(addr <= 0xfffff && addr >= -0x100000);\n\t\t\tbuf_ptr[0] = ADR | (((sljit_ins)addr & 0x3) << 29) | (((sljit_ins)(addr >> 2) & 0x7ffff) << 5) | dst;\n\t\t\treturn;\n\t\t}\n\n\t\tif (jump->flags & PATCH_B32) {\n\t\t\taddr -= ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) & ~(sljit_sw)0xfff;\n\t\t\tSLJIT_ASSERT(addr <= 0xffffffffl && addr >= -0x100000000l);\n\t\t\tbuf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst;\n\t\t\tbuf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tSLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff);\n\tSLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff);\n\n\tbuf_ptr[0] = MOVZ | (((sljit_ins)addr & 0xffff) << 5) | dst;\n\tbuf_ptr[1] = MOVK | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21) | dst;\n\tif (jump->flags & (PATCH_ABS48 | PATCH_ABS64))\n\t\tbuf_ptr[2] = MOVK | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21) | dst;\n\n\tif (jump->flags & PATCH_ABS64)\n\t\tbuf_ptr[3] = MOVK | ((sljit_ins)((sljit_uw)addr >> 48) << 5) | (3 << 21) | dst;\n}\n\nstatic SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE;\n\n\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\tif (jump->flags & JUMP_ADDR) {\n\t\t\t\t\tif (jump->u.target < 0x100000000l)\n\t\t\t\t\t\ttotal_size = 3;\n\t\t\t\t\telse if (jump->u.target < 0x1000000000000l)\n\t\t\t\t\t\ttotal_size = 4;\n\t\t\t\t} else {\n\t\t\t\t\t/* Unit size: instruction. */\n\t\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((jump->flags & IS_COND) && (diff + 1) <= (0xfffff / SSIZE_OF(ins)) && (diff + 1) >= (-0x100000 / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 0;\n\t\t\t\t\telse if (diff <= (0x7ffffff / SSIZE_OF(ins)) && diff >= (-0x8000000 / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 1;\n\t\t\t\t\telse if (diff <= (0xfffff000l / SSIZE_OF(ins)) && diff >= (-0x100000000l / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 3;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsize_reduce += JUMP_MAX_SIZE - total_size;\n\t\t} else {\n\t\t\t/* Real size minus 1. Unit size: instruction. */\n\t\t\ttotal_size = 3;\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins)))\n\t\t\t\t\ttotal_size = 0;\n\t\t\t\telse if (diff <= (0xfffff000l / SSIZE_OF(ins)) && diff >= (-0x100000000l / SSIZE_OF(ins)))\n\t\t\t\t\ttotal_size = 1;\n\t\t\t} else if (jump->u.target < 0x100000000l)\n\t\t\t\ttotal_size = 1;\n\t\t\telse if (jump->u.target < 0x1000000000000l)\n\t\t\t\ttotal_size = 2;\n\n\t\t\tsize_reduce += 3 - total_size;\n\t\t}\n\n\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *code;\n\tsljit_ins *code_ptr;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_uw word_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\tsljit_sw addr;\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n\tcode = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\tword_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 2);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == word_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= word_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= word_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= word_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\tword_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tSLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\taddr = (sljit_sw)code_ptr;\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tjump->addr = (sljit_uw)addr;\n\t\t\t\t\t}\n\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\tword_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == word_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tgenerate_jump_or_mov_addr(jump, executable_offset);\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);\n\n\tcode = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n\tcase SLJIT_HAS_SIMD:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif\n\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_CTZ:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_CMOV:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 2;\n\t}\n\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Core code generator functions.                                       */\n/* --------------------------------------------------------------------- */\n\n#define COUNT_TRAILING_ZERO(value, result) \\\n\tresult = 0; \\\n\tif (!(value & 0xffffffff)) { \\\n\t\tresult += 32; \\\n\t\tvalue >>= 32; \\\n\t} \\\n\tif (!(value & 0xffff)) { \\\n\t\tresult += 16; \\\n\t\tvalue >>= 16; \\\n\t} \\\n\tif (!(value & 0xff)) { \\\n\t\tresult += 8; \\\n\t\tvalue >>= 8; \\\n\t} \\\n\tif (!(value & 0xf)) { \\\n\t\tresult += 4; \\\n\t\tvalue >>= 4; \\\n\t} \\\n\tif (!(value & 0x3)) { \\\n\t\tresult += 2; \\\n\t\tvalue >>= 2; \\\n\t} \\\n\tif (!(value & 0x1)) { \\\n\t\tresult += 1; \\\n\t\tvalue >>= 1; \\\n\t}\n\n#define LOGICAL_IMM_CHECK (sljit_ins)0x100\n\nstatic sljit_ins logical_imm(sljit_sw imm, sljit_u32 len)\n{\n\tsljit_s32 negated;\n\tsljit_u32 ones, right;\n\tsljit_uw mask, uimm;\n\tsljit_ins ins;\n\n\tif (len & LOGICAL_IMM_CHECK) {\n\t\tlen &= ~LOGICAL_IMM_CHECK;\n\t\tif (len == 32 && (imm == 0 || imm == -1))\n\t\t\treturn 0;\n\t\tif (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1))\n\t\t\treturn 0;\n\t}\n\n\tSLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)\n\t\t|| (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1));\n\n\tuimm = (sljit_uw)imm;\n\twhile (1) {\n\t\tif (len <= 0) {\n\t\t\tSLJIT_UNREACHABLE();\n\t\t\treturn 0;\n\t\t}\n\n\t\tmask = ((sljit_uw)1 << len) - 1;\n\t\tif ((uimm & mask) != ((uimm >> len) & mask))\n\t\t\tbreak;\n\t\tlen >>= 1;\n\t}\n\n\tlen <<= 1;\n\n\tnegated = 0;\n\tif (uimm & 0x1) {\n\t\tnegated = 1;\n\t\tuimm = ~uimm;\n\t}\n\n\tif (len < 64)\n\t\tuimm &= ((sljit_uw)1 << len) - 1;\n\n\t/* Unsigned right shift. */\n\tCOUNT_TRAILING_ZERO(uimm, right);\n\n\t/* Signed shift. We also know that the highest bit is set. */\n\timm = (sljit_sw)~uimm;\n\tSLJIT_ASSERT(imm < 0);\n\n\tCOUNT_TRAILING_ZERO(imm, ones);\n\n\tif (~imm)\n\t\treturn 0;\n\n\tif (len == 64)\n\t\tins = 1 << 22;\n\telse\n\t\tins = (0x3f - ((len << 1) - 1)) << 10;\n\n\tif (negated)\n\t\treturn ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);\n\n\treturn ins | ((ones - 1) << 10) | ((len - right) << 16);\n}\n\n#undef COUNT_TRAILING_ZERO\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm)\n{\n\tsljit_uw imm = (sljit_uw)simm;\n\tsljit_u32 i, zeros, ones, first;\n\tsljit_ins bitmask;\n\n\t/* Handling simple immediates first. */\n\tif (imm <= 0xffff)\n\t\treturn push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)imm << 5));\n\n\tif (simm < 0 && simm >= -0x10000)\n\t\treturn push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5));\n\n\tif (imm <= 0xffffffffl) {\n\t\tif ((imm & 0xffff) == 0)\n\t\t\treturn push_inst(compiler, MOVZ | RD(dst) | ((sljit_ins)(imm >> 16) << 5) | (1 << 21));\n\t\tif ((imm & 0xffff0000l) == 0xffff0000)\n\t\t\treturn push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5));\n\t\tif ((imm & 0xffff) == 0xffff)\n\t\t\treturn push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | (((sljit_ins)~imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));\n\n\t\tbitmask = logical_imm(simm, 16);\n\t\tif (bitmask != 0)\n\t\t\treturn push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);\n\n\t\tFAIL_IF(push_inst(compiler, MOVZ | RD(dst) | (((sljit_ins)imm & 0xffff) << 5)));\n\t\treturn push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));\n\t}\n\n\tbitmask = logical_imm(simm, 32);\n\tif (bitmask != 0)\n\t\treturn push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);\n\n\tif (simm < 0 && simm >= -0x100000000l) {\n\t\tif ((imm & 0xffff) == 0xffff)\n\t\t\treturn push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));\n\n\t\tFAIL_IF(push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)~imm & 0xffff) << 5)));\n\t\treturn push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)imm & 0xffff0000u) >> (16 - 5)) | (1 << 21));\n\t}\n\n\t/* A large amount of number can be constructed from ORR and MOVx, but computing them is costly. */\n\n\tzeros = 0;\n\tones = 0;\n\tfor (i = 4; i > 0; i--) {\n\t\tif ((simm & 0xffff) == 0)\n\t\t\tzeros++;\n\t\tif ((simm & 0xffff) == 0xffff)\n\t\t\tones++;\n\t\tsimm >>= 16;\n\t}\n\n\tsimm = (sljit_sw)imm;\n\tfirst = 1;\n\tif (ones > zeros) {\n\t\tsimm = ~simm;\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tif (!(simm & 0xffff)) {\n\t\t\t\tsimm >>= 16;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (first) {\n\t\t\t\tfirst = 0;\n\t\t\t\tFAIL_IF(push_inst(compiler, MOVN | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));\n\t\t\t}\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)~simm & 0xffff) << 5) | (i << 21)));\n\t\t\tsimm >>= 16;\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tfor (i = 0; i < 4; i++) {\n\t\tif (!(simm & 0xffff)) {\n\t\t\tsimm >>= 16;\n\t\t\tcontinue;\n\t\t}\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t\tFAIL_IF(push_inst(compiler, MOVZ | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((sljit_ins)simm & 0xffff) << 5) | (i << 21)));\n\t\tsimm >>= 16;\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\n#define ARG1_IMM\t0x0010000\n#define ARG2_IMM\t0x0020000\n#define INT_OP\t\t0x0040000\n#define SET_FLAGS\t0x0080000\n#define UNUSED_RETURN\t0x0100000\n\n#define CHECK_FLAGS(flag_bits) \\\n\tif (flags & SET_FLAGS) { \\\n\t\tinv_bits |= flag_bits; \\\n\t\tif (flags & UNUSED_RETURN) \\\n\t\t\tdst = TMP_ZERO; \\\n\t}\n\nstatic sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2)\n{\n\t/* dst must be register, TMP_REG1\n\t   arg1 must be register, TMP_REG1, imm\n\t   arg2 must be register, TMP_REG2, imm */\n\tsljit_ins inv_bits = (flags & INT_OP) ? W_OP : 0;\n\tsljit_ins inst_bits;\n\tsljit_s32 op = (flags & 0xffff);\n\tsljit_s32 reg;\n\tsljit_sw imm, nimm;\n\n\tif (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {\n\t\t/* Both are immediates. */\n\t\tflags &= ~ARG1_IMM;\n\t\tif (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)\n\t\t\targ1 = TMP_ZERO;\n\t\telse {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, arg1));\n\t\t\targ1 = TMP_REG1;\n\t\t}\n\t}\n\n\tif (flags & (ARG1_IMM | ARG2_IMM)) {\n\t\treg = (sljit_s32)((flags & ARG2_IMM) ? arg1 : arg2);\n\t\timm = (flags & ARG2_IMM) ? arg2 : arg1;\n\n\t\tswitch (op) {\n\t\tcase SLJIT_CLZ:\n\t\tcase SLJIT_CTZ:\n\t\tcase SLJIT_REV:\n\t\tcase SLJIT_REV_U16:\n\t\tcase SLJIT_REV_S16:\n\t\tcase SLJIT_REV_U32:\n\t\tcase SLJIT_REV_S32:\n\t\tcase SLJIT_ADDC:\n\t\tcase SLJIT_SUBC:\n\t\tcase SLJIT_MUL:\n\t\tcase SLJIT_MULADD:\n\t\t\t/* No form with immediate operand (except imm 0, which\n\t\t\tis represented by a ZERO register). */\n\t\t\tbreak;\n\t\tcase SLJIT_MOV:\n\t\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);\n\t\t\treturn load_immediate(compiler, dst, imm);\n\t\tcase SLJIT_SUB:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\t\t\timm = -imm;\n\t\t\tSLJIT_FALLTHROUGH\n\t\tcase SLJIT_ADD:\n\t\t\tif (op != SLJIT_SUB)\n\t\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\n\t\t\tif (imm == 0) {\n\t\t\t\tCHECK_FLAGS(1 << 29);\n\t\t\t\treturn push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));\n\t\t\t}\n\t\t\tif (imm > 0 && imm <= 0xfff) {\n\t\t\t\tCHECK_FLAGS(1 << 29);\n\t\t\t\treturn push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((sljit_ins)imm << 10));\n\t\t\t}\n\t\t\tnimm = -imm;\n\t\t\tif (nimm > 0 && nimm <= 0xfff) {\n\t\t\t\tCHECK_FLAGS(1 << 29);\n\t\t\t\treturn push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((sljit_ins)nimm << 10));\n\t\t\t}\n\t\t\tif (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {\n\t\t\t\tCHECK_FLAGS(1 << 29);\n\t\t\t\treturn push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)imm >> 12) << 10) | (1 << 22));\n\t\t\t}\n\t\t\tif (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {\n\t\t\t\tCHECK_FLAGS(1 << 29);\n\t\t\t\treturn push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)nimm >> 12) << 10) | (1 << 22));\n\t\t\t}\n\t\t\tif (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)imm >> 12) << 10) | (1 << 22)));\n\t\t\t\treturn push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | (((sljit_ins)imm & 0xfff) << 10));\n\t\t\t}\n\t\t\tif (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (((sljit_ins)nimm >> 12) << 10) | (1 << 22)));\n\t\t\t\treturn push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | (((sljit_ins)nimm & 0xfff) << 10));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SLJIT_AND:\n\t\t\tinst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));\n\t\t\tif (!inst_bits)\n\t\t\t\tbreak;\n\t\t\tCHECK_FLAGS(3 << 29);\n\t\t\treturn push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);\n\t\tcase SLJIT_XOR:\n\t\t\tif (imm == -1) {\n\t\t\t\tFAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(reg)));\n\t\t\t\tgoto set_flags;\n\t\t\t}\n\t\t\tSLJIT_FALLTHROUGH\n\t\tcase SLJIT_OR:\n\t\t\tinst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));\n\t\t\tif (!inst_bits)\n\t\t\t\tbreak;\n\t\t\tif (op == SLJIT_OR)\n\t\t\t\tinst_bits |= ORRI;\n\t\t\telse\n\t\t\t\tinst_bits |= EORI;\n\t\t\tFAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));\n\t\t\tgoto set_flags;\n\t\tcase SLJIT_SHL:\n\t\tcase SLJIT_MSHL:\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\n\t\t\tif (flags & INT_OP) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\tinst_bits = (((sljit_ins)-imm & 0x1f) << 16) | ((31 - (sljit_ins)imm) << 10);\n\t\t\t} else {\n\t\t\t\timm &= 0x3f;\n\t\t\t\tinst_bits = ((sljit_ins)1 << 22) | (((sljit_ins)-imm & 0x3f) << 16) | ((63 - (sljit_ins)imm) << 10);\n\t\t\t}\n\n\t\t\tinv_bits |= inv_bits >> 9;\n\t\t\tFAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits));\n\t\t\tgoto set_flags;\n\t\tcase SLJIT_LSHR:\n\t\tcase SLJIT_MLSHR:\n\t\tcase SLJIT_ASHR:\n\t\tcase SLJIT_MASHR:\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\n\t\t\tinv_bits |= inv_bits >> 9;\n\t\t\tif (op >= SLJIT_ASHR)\n\t\t\t\tinv_bits |= 1 << 30;\n\n\t\t\tif (flags & INT_OP) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\tinst_bits = ((sljit_ins)imm << 16) | (31 << 10);\n\t\t\t} else {\n\t\t\t\timm &= 0x3f;\n\t\t\t\tinst_bits = ((sljit_ins)1 << 22) | ((sljit_ins)imm << 16) | (63 << 10);\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits));\n\t\t\tgoto set_flags;\n\t\tcase SLJIT_ROTL:\n\t\tcase SLJIT_ROTR:\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\n\t\t\tif (op == SLJIT_ROTL)\n\t\t\t\timm = -imm;\n\n\t\t\timm &= (flags & INT_OP) ? 0x1f : 0x3f;\n\t\t\treturn push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(dst) | RN(arg1) | RM(arg1) | ((sljit_ins)imm << 10));\n\t\tdefault:\n\t\t\tSLJIT_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tif (flags & ARG2_IMM) {\n\t\t\tif (arg2 == 0)\n\t\t\t\targ2 = TMP_ZERO;\n\t\t\telse {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, arg2));\n\t\t\t\targ2 = TMP_REG2;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (arg1 == 0)\n\t\t\t\targ1 = TMP_ZERO;\n\t\t\telse {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, arg1));\n\t\t\t\targ1 = TMP_REG1;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Both arguments are registers. */\n\tswitch (op) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tif (dst == arg2)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, MOV | RD(dst) | RM(arg2));\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tinv_bits |= inv_bits >> 9;\n\t\treturn push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tinv_bits |= inv_bits >> 9;\n\t\treturn push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));\n\tcase SLJIT_MOV_U16:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tinv_bits |= inv_bits >> 9;\n\t\treturn push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tinv_bits |= inv_bits >> 9;\n\t\treturn push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));\n\tcase SLJIT_MOV32:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\tif (dst == arg2)\n\t\t\treturn SLJIT_SUCCESS;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_U32:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\treturn push_inst(compiler, (MOV ^ W_OP) | RD(dst) | RM(arg2));\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);\n\t\treturn push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG1);\n\t\treturn push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2));\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG1);\n\t\tFAIL_IF(push_inst(compiler, (RBIT ^ inv_bits) | RD(dst) | RN(arg2)));\n\t\treturn push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(dst));\n\tcase SLJIT_REV:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG1);\n\t\tinv_bits |= inv_bits >> 21;\n\t\treturn push_inst(compiler, (REV ^ inv_bits) | RD(dst) | RN(arg2));\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2);\n\t\tFAIL_IF(push_inst(compiler, (REV16 ^ (sljit_ins)0x80000000) | RD(dst) | RN(arg2)));\n\t\tif (dst == TMP_REG1 || (arg2 == TMP_REG2 && op == SLJIT_REV_U16))\n\t\t\treturn SLJIT_SUCCESS;\n\t\tinv_bits |= inv_bits >> 9;\n\t\treturn push_inst(compiler, ((op == SLJIT_REV_U16 ? UBFM : SBFM) ^ inv_bits) | RD(dst) | RN(dst) | (15 << 10));\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2);\n\t\tFAIL_IF(push_inst(compiler, (REV ^ (sljit_ins)0x80000400) | RD(dst) | RN(arg2)));\n\t\tif (op == SLJIT_REV_U32 || dst == TMP_REG1)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(dst) | (31 << 10));\n\tcase SLJIT_ADD:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\tCHECK_FLAGS(1 << 29);\n\t\treturn push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\tCHECK_FLAGS(1 << 29);\n\t\treturn push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_SUB:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\tCHECK_FLAGS(1 << 29);\n\t\treturn push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\tCHECK_FLAGS(1 << 29);\n\t\treturn push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_MUL:\n\t\tcompiler->status_flags_state = 0;\n\t\tif (!(flags & SET_FLAGS))\n\t\t\treturn push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));\n\t\tif (flags & INT_OP) {\n\t\t\tFAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));\n\t\t\treturn push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));\n\t\tFAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));\n\t\treturn push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));\n\tcase SLJIT_AND:\n\t\tCHECK_FLAGS(3 << 29);\n\t\treturn push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_OR:\n\t\tFAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));\n\t\tbreak; /* Set flags. */\n\tcase SLJIT_XOR:\n\t\tFAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));\n\t\tbreak; /* Set flags. */\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tFAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));\n\t\tbreak; /* Set flags. */\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tFAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));\n\t\tbreak; /* Set flags. */\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tFAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));\n\t\tbreak; /* Set flags. */\n\tcase SLJIT_ROTL:\n\t\tFAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(arg2)));\n\t\targ2 = TMP_REG2;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_ROTR:\n\t\treturn push_inst(compiler, (RORV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));\n\tcase SLJIT_MULADD:\n\t\tcompiler->status_flags_state = 0;\n\t\treturn push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(dst));\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn SLJIT_SUCCESS;\n\t}\n\nset_flags:\n\tif (flags & SET_FLAGS)\n\t\treturn push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));\n\treturn SLJIT_SUCCESS;\n}\n\n#define STORE\t\t0x10\n#define SIGNED\t\t0x20\n\n#define BYTE_SIZE\t0x0\n#define HALF_SIZE\t0x1\n#define INT_SIZE\t0x2\n#define WORD_SIZE\t0x3\n\n#define MEM_SIZE_SHIFT(flags) ((sljit_ins)(flags) & 0x3)\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,\n\tsljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)\n{\n\tsljit_u32 shift = MEM_SIZE_SHIFT(flags);\n\tsljit_u32 type = (shift << 30);\n\n\tif (!(flags & STORE))\n\t\ttype |= (flags & SIGNED) ? 0x00800000 : 0x00400000;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (argw == 0 || argw == shift)\n\t\t\treturn push_inst(compiler, STRB | type | RT(reg)\n\t\t\t\t| RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));\n\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));\n\t\treturn push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (!arg) {\n\t\tFAIL_IF(load_immediate(compiler, tmp_reg, argw & ~(0xfff << shift)));\n\n\t\targw = (argw >> shift) & 0xfff;\n\n\t\treturn push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));\n\t}\n\n\tif ((argw & ((1 << shift) - 1)) == 0) {\n\t\tif (argw >= 0) {\n\t\t\tif ((argw >> shift) <= 0xfff)\n\t\t\t\treturn push_inst(compiler, STRBI | type | RT(reg) | RN(arg) | ((sljit_ins)argw << (10 - shift)));\n\n\t\t\tif (argw <= 0xffffff) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));\n\n\t\t\t\targw = ((argw & 0xfff) >> shift);\n\t\t\t\treturn push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));\n\t\t\t}\n\t\t} else if (argw < -256 && argw >= -0xfff000) {\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)(-argw + 0xfff) >> 12) << 10)));\n\t\t\targw = ((0x1000 + argw) & 0xfff) >> shift;\n\t\t\treturn push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | ((sljit_ins)argw << 10));\n\t\t}\n\t}\n\n\tif (argw <= 0xff && argw >= -0x100)\n\t\treturn push_inst(compiler, STURBI | type | RT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));\n\n\tif (((argw + 0x100) & 0xfff) <= 0x1ff && argw <= 0xfff0ff && argw >= -0xfff100) {\n\t\tif (argw >= 0) {\n\t\t\tif (argw & 0x100)\n\t\t\t\targw += 0x1000;\n\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));\n\t\t\treturn push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));\n\t\t} else {\n\t\t\tif (!(argw & 0x100))\n\t\t\t\targw -= 0x1000;\n\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)-argw >> 12) << 10)));\n\t\t\treturn push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));\n\t\t}\n\t}\n\n\tFAIL_IF(load_immediate(compiler, tmp_reg, argw));\n\n\treturn push_inst(compiler, STRB | type | RT(reg) | RN(arg) | RM(tmp_reg));\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 prev, fprev, saved_regs_size, i, tmp;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\tsljit_ins offs;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\tsaved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2);\n\tsaved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tlocal_size = (local_size + saved_regs_size + 0xf) & ~0xf;\n\tcompiler->local_size = local_size;\n\n\tif (local_size <= 512) {\n\t\tFAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)\n\t\t\t| RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));\n\t\toffs = (sljit_ins)(local_size - 2 * SSIZE_OF(sw)) << (15 - 3);\n\t\tlocal_size = 0;\n\t} else {\n\t\tsaved_regs_size = ((saved_regs_size - 2 * SSIZE_OF(sw)) + 0xf) & ~0xf;\n\n\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)saved_regs_size << 10)));\n\t\toffs = (sljit_ins)(saved_regs_size - 2 * SSIZE_OF(sw)) << (15 - 3);\n\t\tlocal_size -= saved_regs_size;\n\t\tSLJIT_ASSERT(local_size > 0);\n\t}\n\n\tprev = -1;\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\tif (prev == -1) {\n\t\t\tprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tprev = -1;\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\tif (prev == -1) {\n\t\t\tprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tprev = -1;\n\t}\n\n\tfprev = -1;\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\tif (fprev == -1) {\n\t\t\tfprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, STP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tfprev = -1;\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\tif (fprev == -1) {\n\t\t\tfprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, STP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tfprev = -1;\n\t}\n\n\tif (fprev != -1)\n\t\tFAIL_IF(push_inst(compiler, STRI_F64 | VT(fprev) | RN(SLJIT_SP) | (offs >> 5) | (1 << 10)));\n\n\tif (prev != -1)\n\t\tFAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5) | ((fprev == -1) ? (1 << 10) : 0)));\n\n\n#ifdef _WIN32\n\tif (local_size > 4096)\n\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));\n#endif /* _WIN32 */\n\n\tif (!(options & SLJIT_ENTER_REG_ARG)) {\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\tsaved_arg_count = 0;\n\t\ttmp = SLJIT_R0;\n\n\t\twhile (arg_types) {\n\t\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0 - saved_arg_count) | RM(tmp)));\n\t\t\t\t\tsaved_arg_count++;\n\t\t\t\t}\n\t\t\t\ttmp++;\n\t\t\t}\n\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t}\n\t}\n\n#ifdef _WIN32\n\tif (local_size > 4096) {\n\t\tif (local_size < 4 * 4096) {\n\t\t\t/* No need for a loop. */\n\n\t\t\tif (local_size >= 2 * 4096) {\n\t\t\t\tif (local_size >= 3 * 4096) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));\n\t\t\t\t}\n\n\t\t\t\tFAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));\n\t\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tFAIL_IF(push_inst(compiler, MOVZ | RD(TMP_REG1) | ((((sljit_ins)local_size >> 12) - 1) << 5)));\n\t\t\tFAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | (1 << 29) | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10)));\n\t\t\tFAIL_IF(push_inst(compiler, B_CC | ((((sljit_ins) -3) & 0x7ffff) << 5) | 0x1 /* not-equal */));\n\t\t}\n\n\t\tlocal_size &= 0xfff;\n\n\t\tif (local_size > 0)\n\t\t\tFAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(SLJIT_SP)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));\n\t}\n\n\tif (local_size > 0) {\n\t\tif (local_size <= 512)\n\t\t\tFAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)\n\t\t\t\t| RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));\n\t\telse {\n\t\t\tif (local_size >= 4096)\n\t\t\t\tlocal_size = (1 << (22 - 10));\n\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));\n\t\t\tFAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));\n\t\t}\n\t}\n\n#else /* !_WIN32 */\n\n\t/* The local_size does not include saved registers size. */\n\tif (local_size != 0) {\n\t\tif (local_size > 0xfff) {\n\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (((sljit_ins)local_size >> 12) << 10) | (1 << 22)));\n\t\t\tlocal_size &= 0xfff;\n\t\t}\n\n\t\tif (local_size > 512 || local_size == 0) {\n\t\t\tif (local_size != 0)\n\t\t\t\tFAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));\n\n\t\t\tFAIL_IF(push_inst(compiler, STP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)\n\t\t\t\t| RN(SLJIT_SP) | (sljit_ins)((-(local_size >> 3) & 0x7f) << 15)));\n\t}\n\n#endif /* _WIN32 */\n\n\treturn push_inst(compiler, ADDI | RD(TMP_FP) | RN(SLJIT_SP) | (0 << 10));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 saved_regs_size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\tsaved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2);\n\tsaved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tcompiler->local_size = (local_size + saved_regs_size + 0xf) & ~0xf;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_s32 local_size, prev, fprev, i, tmp;\n\tsljit_ins offs;\n\n\tlocal_size = compiler->local_size;\n\n\tif (!is_return_to) {\n\t\tif (local_size > 512 && local_size <= 512 + 496) {\n\t\t\tFAIL_IF(push_inst(compiler, LDP_POST | RT(TMP_FP) | RT2(TMP_LR)\n\t\t\t\t| RN(SLJIT_SP) | ((sljit_ins)(local_size - 512) << (15 - 3))));\n\t\t\tlocal_size = 512;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));\n\t} else {\n\t\tif (local_size > 512 && local_size <= 512 + 248) {\n\t\t\tFAIL_IF(push_inst(compiler, LDRI_POST | RT(TMP_FP) | RN(SLJIT_SP) | ((sljit_ins)(local_size - 512) << 12)));\n\t\t\tlocal_size = 512;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, LDRI | RT(TMP_FP) | RN(SLJIT_SP) | 0));\n\t}\n\n\tif (local_size > 512) {\n\t\tlocal_size -= 512;\n\t\tif (local_size > 0xfff) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP)\n\t\t\t\t| (((sljit_ins)local_size >> 12) << 10) | (1 << 22)));\n\t\t\tlocal_size &= 0xfff;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((sljit_ins)local_size << 10)));\n\t\tlocal_size = 512;\n\t}\n\n\toffs = (sljit_ins)(local_size - 2 * SSIZE_OF(sw)) << (15 - 3);\n\tprev = -1;\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\tfor (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {\n\t\tif (prev == -1) {\n\t\t\tprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tprev = -1;\n\t}\n\n\tfor (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\tif (prev == -1) {\n\t\t\tprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tprev = -1;\n\t}\n\n\tfprev = -1;\n\n\ttmp = SLJIT_FS0 - compiler->fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\tif (fprev == -1) {\n\t\t\tfprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, LDP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tfprev = -1;\n\t}\n\n\tfor (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\tif (fprev == -1) {\n\t\t\tfprev = i;\n\t\t\tcontinue;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, LDP_F64 | VT(fprev) | VT2(i) | RN(SLJIT_SP) | offs));\n\t\toffs -= (sljit_ins)2 << 15;\n\t\tfprev = -1;\n\t}\n\n\tif (fprev != -1)\n\t\tFAIL_IF(push_inst(compiler, LDRI_F64 | VT(fprev) | RN(SLJIT_SP) | (offs >> 5) | (1 << 10)));\n\n\tif (prev != -1)\n\t\tFAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5) | ((fprev == -1) ? (1 << 10) : 0)));\n\n\t/* This and the next call/jump instruction can be executed parallelly. */\n\treturn push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (sljit_ins)(local_size << 10));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\n\treturn push_inst(compiler, RET | RN(TMP_LR));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tsljit_ins inv_bits = (op & SLJIT_32) ? W_OP : 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\t\treturn push_inst(compiler, BRK | (0xf000 << 5));\n\tcase SLJIT_NOP:\n\t\treturn push_inst(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(SLJIT_R0)));\n\t\tFAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));\n\t\treturn push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RD(TMP_REG1) | RM(SLJIT_R0)));\n\t\tFAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));\n\t\tFAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));\n\t\treturn push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n\t\treturn push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst(compiler, DMB_SY);\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r, flags, mem_flags;\n\tsljit_s32 op_flags = GET_ALL_FLAGS(op);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\top = GET_OPCODE(op);\n\tif (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {\n\t\t/* Both operands are registers. */\n\t\tif (FAST_IS_REG(dst) && FAST_IS_REG(src))\n\t\t\treturn emit_op_imm(compiler, op | ((op_flags & SLJIT_32) ? INT_OP : 0), dst_r, TMP_REG1, src);\n\n\t\tswitch (op) {\n\t\tcase SLJIT_MOV:\n\t\tcase SLJIT_MOV_P:\n\t\t\tmem_flags = WORD_SIZE;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U8:\n\t\t\tmem_flags = BYTE_SIZE;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_u8)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S8:\n\t\t\tmem_flags = BYTE_SIZE | SIGNED;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_s8)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U16:\n\t\t\tmem_flags = HALF_SIZE;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_u16)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S16:\n\t\t\tmem_flags = HALF_SIZE | SIGNED;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_s16)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U32:\n\t\t\tmem_flags = INT_SIZE;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_u32)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S32:\n\t\tcase SLJIT_MOV32:\n\t\t\tmem_flags = INT_SIZE | SIGNED;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_s32)srcw;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSLJIT_UNREACHABLE();\n\t\t\tmem_flags = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (src == SLJIT_IMM)\n\t\t\tFAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));\n\t\telse if (!(src & SLJIT_MEM))\n\t\t\tdst_r = src;\n\t\telse\n\t\t\tFAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG2));\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tflags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;\n\n\tswitch (op) {\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tmem_flags = HALF_SIZE;\n\t\tbreak;\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\tmem_flags = INT_SIZE;\n\t\tbreak;\n\tdefault:\n\t\tmem_flags = WORD_SIZE;\n\n\t\tif (op_flags & SLJIT_32) {\n\t\t\tflags |= INT_OP;\n\t\t\tmem_flags = INT_SIZE;\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src, srcw, TMP_REG2));\n\t\tsrc = TMP_REG2;\n\t}\n\n\temit_op_imm(compiler, flags | op, dst_r, TMP_REG1, src);\n\n\tif (SLJIT_UNLIKELY(dst & SLJIT_MEM))\n\t\treturn emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r, flags, mem_flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tflags = HAS_FLAGS(op) ? SET_FLAGS : 0;\n\tmem_flags = WORD_SIZE;\n\n\tif (op & SLJIT_32) {\n\t\tflags |= INT_OP;\n\t\tmem_flags = INT_SIZE;\n\t}\n\n\tif (dst == TMP_REG2)\n\t\tflags |= UNUSED_RETURN;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src2, src2w, TMP_REG2));\n\t\tsrc2 = TMP_REG2;\n\t}\n\n\tif (src1 == SLJIT_IMM)\n\t\tflags |= ARG1_IMM;\n\telse\n\t\tsrc1w = src1;\n\n\tif (src2 == SLJIT_IMM)\n\t\tflags |= ARG2_IMM;\n\telse\n\t\tsrc2w = src2;\n\n\temit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_ins inv_bits, imm;\n\tsljit_s32 is_left;\n\tsljit_sw mask;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tinv_bits = (op & SLJIT_32) ? W_OP : 0;\n\n\tif (src3 == SLJIT_IMM) {\n\t\tmask = inv_bits ? 0x1f : 0x3f;\n\t\tsrc3w &= mask;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (is_left)\n\t\t\tsrc3w = (src3w ^ mask) + 1;\n\n\t\treturn push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(dst_reg)\n\t\t\t| RN(is_left ? src1_reg : src2_reg) | RM(is_left ? src2_reg : src1_reg) | ((sljit_ins)src3w << 10));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2));\n\t\tsrc3 = TMP_REG2;\n\t} else if (dst_reg == src3) {\n\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src3)));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(dst_reg) | RN(src1_reg) | RM(src3)));\n\n\tif (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {\n\t\t/* Shift left/right by 1. */\n\t\tif (is_left)\n\t\t\timm = (sljit_ins)(inv_bits ? ((1 << 16) | (31 << 10)) : ((1 << 16) | (63 << 10) | (1 << 22)));\n\t\telse\n\t\t\timm = (sljit_ins)(inv_bits ? ((31 << 16) | (30 << 10)) : ((63 << 16) | (62 << 10) | (1 << 22)));\n\n\t\tFAIL_IF(push_inst(compiler, (UBFM ^ (inv_bits | (inv_bits >> 9))) | RD(TMP_REG1) | RN(src2_reg) | imm));\n\n\t\t/* Set imm to mask. */\n\t\timm = (sljit_ins)(inv_bits ? (4 << 10) : ((5 << 10) | (1 << 22)));\n\t\tFAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src3) | imm));\n\n\t\tsrc2_reg = TMP_REG1;\n\t} else\n\t\tFAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src3)));\n\n\tFAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src2_reg) | RM(TMP_REG2)));\n\treturn push_inst(compiler, (ORR ^ inv_bits) | RD(dst_reg) | RN(dst_reg) | RM(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= 0x3f;\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, src1w));\n\t\tsrc1 = TMP_REG2;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src1, src1w, TMP_REG2));\n\t\tsrc1 = TMP_REG2;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\ttmp_r = (src1 == TMP_REG2) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, tmp_r, src2, src2w, tmp_r));\n\t\tsrc2 = tmp_r;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tFAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(src1) | RM(src2) | ((sljit_ins)shift_arg << 10)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (src != TMP_LR)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_LR) | RM(src)));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));\n\n\t\treturn push_inst(compiler, RET | RN(TMP_LR));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\tSLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);\n\n\t\t/* The reg_map[op] should provide the appropriate constant. */\n\t\tif (op == SLJIT_PREFETCH_L1)\n\t\t\top = 1;\n\t\telse if (op == SLJIT_PREFETCH_L2)\n\t\t\top = 3;\n\t\telse if (op == SLJIT_PREFETCH_L3)\n\t\t\top = 5;\n\t\telse\n\t\t\top = 2;\n\n\t\t/* Signed word sized load is the prefetch instruction. */\n\t\treturn emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 dst_r = TMP_LR;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (dst == TMP_LR)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, MOV | RD(dst) | RM(TMP_LR));\n\t\t}\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), 0x8, TMP_REG2));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_64 && type != SLJIT_SIMD_REG_128)\n\t\treturn -1;\n\n\treturn freg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_u32 shift = MEM_SIZE_SHIFT(flags);\n\tsljit_ins type = (shift << 30);\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (!(flags & STORE))\n\t\ttype |= 0x00400000;\n\n\tif (arg & OFFS_REG_MASK) {\n\t\targw &= 3;\n\t\tif (argw == 0 || argw == shift)\n\t\t\treturn push_inst(compiler, STR_FR | type | VT(reg)\n\t\t\t\t| RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));\n\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));\n\t\treturn push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (!arg) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, argw & ~(0xfff << shift)));\n\n\t\targw = (argw >> shift) & 0xfff;\n\n\t\treturn push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2) | ((sljit_ins)argw << 10));\n\t}\n\n\tif (argw >= 0 && (argw & ((1 << shift) - 1)) == 0) {\n\t\tif ((argw >> shift) <= 0xfff)\n\t\t\treturn push_inst(compiler, STR_FI | type | VT(reg) | RN(arg) | ((sljit_ins)argw << (10 - shift)));\n\n\t\tif (argw <= 0xffffff) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(TMP_REG2) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));\n\n\t\t\targw = ((argw & 0xfff) >> shift);\n\t\t\treturn push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2) | ((sljit_ins)argw << 10));\n\t\t}\n\t}\n\n\tif (argw <= 255 && argw >= -256)\n\t\treturn push_inst(compiler, STUR_FI | type | VT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG2, argw));\n\treturn push_inst(compiler, STR_FR | type | VT(reg) | RN(arg) | RM(TMP_REG2));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tsljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64)\n\t\tinv_bits |= W_OP;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw, TMP_REG2);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\temit_op_mem(compiler, (ins & W_OP) ? WORD_SIZE : INT_SIZE, TMP_REG1, src, srcw, TMP_REG1);\n\t\tsrc = TMP_REG1;\n\t} else if (src == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins | VD(dst_r) | RN(src)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, ((ins & (1 << 22)) ? WORD_SIZE : INT_SIZE) | STORE, TMP_FREG1, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {\n\t\tinv_bits |= W_OP;\n\n\t\tif (src == SLJIT_IMM)\n\t\t\tsrcw = (sljit_s32)srcw;\n\t}\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, SCVTF ^ inv_bits, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {\n\t\tinv_bits |= W_OP;\n\n\t\tif (src == SLJIT_IMM)\n\t\t\tsrcw = (sljit_u32)srcw;\n\t}\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, UCVTF ^ inv_bits, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;\n\tsljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)));\n\n\tif (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst(compiler, CSINC | (0x0 << 12) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(TMP_ZERO)));\n\treturn push_inst(compiler, CCMPI | (0x0 << 16) | (0x7 << 12) | RN(TMP_REG1) | 0x4);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r, mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;\n\tsljit_ins inv_bits;\n\n\tCHECK_ERROR();\n\n\tSLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x1) == WORD_SIZE, must_be_one_bit_difference);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tinv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\tFAIL_IF(push_inst(compiler, FCVT | (sljit_ins)((op & SLJIT_32) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r, mem_flags = (op & SLJIT_32) ? INT_SIZE : WORD_SIZE;\n\tsljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));\n\t\tbreak;\n\tcase SLJIT_COPYSIGN_F64:\n\t\tFAIL_IF(push_inst(compiler, (FMOV_R ^ ((op & SLJIT_32) ? (W_OP | (1 << 22)) : 0)) | VN(src2) | RD(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src1)));\n\t\tFAIL_IF(push_inst(compiler, TBZ | ((op & SLJIT_32) ? 0 : ((sljit_ins)1 << 31)) | (0x1f << 19) | (2 << 5) | RT(TMP_REG1)));\n\t\treturn push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(dst_r));\n\t}\n\n\tif (!(dst & SLJIT_MEM))\n\t\treturn SLJIT_SUCCESS;\n\treturn emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tsljit_u32 exp;\n\tunion {\n\t\tsljit_u32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_ZERO) | VD(freg) | (1 << 16));\n\n\tif ((u.imm << (32 - 19)) == 0) {\n\t\texp = (u.imm >> (23 + 2)) & 0x3f;\n\n\t\tif (exp == 0x20 || exp == 0x1f)\n\t\t\treturn push_inst(compiler, (FMOV_I ^ (1 << 22)) | (sljit_ins)((((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f)) << 13) | VD(freg));\n\t}\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_s32)u.imm));\n\treturn push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_REG1) | VD(freg) | (1 << 16));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tsljit_uw exp;\n\tunion {\n\t\tsljit_uw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, FMOV_R | RN(TMP_ZERO) | VD(freg) | (sljit_ins)1 << 16);\n\n\tif ((u.imm << (64 - 48)) == 0) {\n\t\texp = (u.imm >> (52 + 2)) & 0x1ff;\n\n\t\tif (exp == 0x100 || exp == 0xff)\n\t\t\treturn push_inst(compiler, FMOV_I | (sljit_ins)((((u.imm >> 56) & 0x80) | ((u.imm >> 48) & 0x7f)) << 13) | VD(freg));\n\t}\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_sw)u.imm));\n\treturn push_inst(compiler, FMOV_R | RN(TMP_REG1) | VD(freg) | (1 << 16));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64)\n\t\tinst = FMOV_R | RN(reg) | VD(freg) | (1 << 16);\n\telse\n\t\tinst = FMOV_R | VN(freg) | RD(reg);\n\n\tif (op & SLJIT_32)\n\t\tinst ^= W_OP | (1 << 22);\n\n\treturn push_inst(compiler, inst);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn 0x1;\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 0x0;\n\n\tcase SLJIT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x3;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_LESS:\n\t\treturn 0x2;\n\n\tcase SLJIT_NOT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x2;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_GREATER_EQUAL:\n\t\treturn 0x3;\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn 0x9;\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn 0x8;\n\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn 0xa;\n\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\treturn 0xb;\n\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\treturn 0xd;\n\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn 0xc;\n\n\tcase SLJIT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x0;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_UNORDERED:\n\t\treturn 0x7;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x1;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ORDERED:\n\t\treturn 0x6;\n\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\treturn 0x5;\n\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\treturn 0x4;\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn 0xe;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tif (type < SLJIT_JUMP) {\n\t\tjump->flags |= IS_COND;\n\t\tPTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(compiler, type)));\n\t} else if (type >= SLJIT_FAST_CALL)\n\t\tjump->flags |= IS_BL;\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG2)));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nstatic SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0;\n\n\tSLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\tjump->flags |= IS_CBZ | IS_COND;\n\n\tif (src & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\telse if (src == SLJIT_IMM) {\n\t\tPTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tSLJIT_ASSERT(FAST_IS_REG(src));\n\n\tif ((type & 0xff) == SLJIT_EQUAL)\n\t\tinv_bits |= 1 << 24;\n\n\tPTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG2)));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src != SLJIT_IMM) {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));\n\t\t\tsrc = TMP_REG2;\n\t\t}\n\t\treturn push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));\n\t}\n\n\t/* These jumps are converted to jump/call instructions when possible. */\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));\n\tjump->u.target = (sljit_uw)srcw;\n\n\tjump->addr = compiler->size;\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tFAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 dst_r, src_r, flags, mem_flags;\n\tsljit_ins cc;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tcc = get_cc(compiler, type);\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (GET_OPCODE(op) < SLJIT_ADD) {\n\t\tFAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));\n\n\t\tif (dst & SLJIT_MEM) {\n\t\t\tmem_flags = (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE;\n\t\t\treturn emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG2);\n\t\t}\n\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tflags = HAS_FLAGS(op) ? SET_FLAGS : 0;\n\tmem_flags = WORD_SIZE;\n\n\tif (op & SLJIT_32) {\n\t\tflags |= INT_OP;\n\t\tmem_flags = INT_SIZE;\n\t}\n\n\tsrc_r = dst;\n\n\tif (dst & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG1));\n\t\tsrc_r = TMP_REG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));\n\temit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src_r, TMP_REG2);\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, TMP_REG2);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0;\n\tsljit_ins op = CSEL;\n\tsljit_ins cmp = 0;\n\tsljit_ins cc;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (src1 == SLJIT_IMM) {\n\t\tif (type & SLJIT_32)\n\t\t\tsrc1w = (sljit_s32)src1w;\n\n\t\tif (src1w <= 1 && src1w >= -1) {\n\t\t\tsrc1 = TMP_ZERO;\n\t\t\tcmp = (SUBI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO);\n\n\t\t\tif (src1w == 1) {\n\t\t\t\top = CSINC;\n\t\t\t\tcmp = (SUBI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | (1 << 10);\n\t\t\t} else if (src1w == -1) {\n\t\t\t\top = CSINV;\n\t\t\t\tcmp = (ADDI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | (1 << 10);\n\t\t\t}\n\n\t\t\tsrc1w = 0;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, src1w));\n\t\t\tsrc1 = TMP_REG2;\n\t\t}\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src1, src1w, TMP_REG2));\n\t\tsrc1 = TMP_REG2;\n\t}\n\n\tif (type & SLJIT_COMPARE_SELECT) {\n\t\ttype ^= 0x1;\n\t\tif (cmp == 0)\n\t\t\tcmp = (SUB ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | RM(src1);\n\t\tFAIL_IF(push_inst(compiler, cmp | RN(src2_reg)));\n\t}\n\n\tcc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));\n\treturn push_inst(compiler, (op ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(src2_reg) | RM(src1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_ins inv_bits = (type & SLJIT_32) ? (1 << 22) : 0;\n\tsljit_ins cc;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG2, src1, src1w));\n\t\tsrc1 = TMP_FREG2;\n\t}\n\n\tcc = get_cc(compiler, type & ~SLJIT_32);\n\treturn push_inst(compiler, (FCSEL ^ inv_bits) | (cc << 12) | VD(dst_freg) | VN(src2_freg) | VM(src1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_u32 inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tif (!(mem & REG_MASK)) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw & ~0x1f8));\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\tmemw &= 0x1f8;\n\t} else if (mem & OFFS_REG_MASK) {\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 10)));\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\tmemw = 0;\n\t} else if ((memw & 0x7) != 0 || memw > 0x1f8 || memw < -0x200) {\n\t\tinst = ADDI;\n\n\t\tif (memw < 0) {\n\t\t\t/* Remains negative for integer min. */\n\t\t\tmemw = -memw;\n\t\t\tinst = SUBI;\n\t\t} else if ((memw & 0x7) == 0 && memw <= 0x7ff0) {\n\t\t\tif (!(type & SLJIT_MEM_STORE) && (mem & REG_MASK) == REG_PAIR_FIRST(reg)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, LDRI | RD(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | ((sljit_ins)memw << 7)));\n\t\t\t\treturn push_inst(compiler, LDRI | RD(REG_PAIR_FIRST(reg)) | RN(mem & REG_MASK) | ((sljit_ins)(memw + 0x8) << 7));\n\t\t\t}\n\n\t\t\tinst = (type & SLJIT_MEM_STORE) ? STRI : LDRI;\n\n\t\t\tFAIL_IF(push_inst(compiler, inst | RD(REG_PAIR_FIRST(reg)) | RN(mem & REG_MASK) | ((sljit_ins)memw << 7)));\n\t\t\treturn push_inst(compiler, inst | RD(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | ((sljit_ins)(memw + 0x8) << 7));\n\t\t}\n\n\t\tif ((sljit_uw)memw <= 0xfff) {\n\t\t\tFAIL_IF(push_inst(compiler, inst | RD(TMP_REG1) | RN(mem & REG_MASK) | ((sljit_ins)memw << 10)));\n\t\t\tmemw = 0;\n\t\t} else if ((sljit_uw)memw <= 0xffffff) {\n\t\t\tFAIL_IF(push_inst(compiler, inst | (1 << 22) | RD(TMP_REG1) | RN(mem & REG_MASK) | (((sljit_ins)memw >> 12) << 10)));\n\n\t\t\tif ((memw & 0xe07) != 0) {\n\t\t\t\tFAIL_IF(push_inst(compiler, inst | RD(TMP_REG1) | RN(TMP_REG1) | (((sljit_ins)memw & 0xfff) << 10)));\n\t\t\t\tmemw = 0;\n\t\t\t} else {\n\t\t\t\tmemw &= 0xfff;\n\t\t\t}\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw));\n\t\t\tFAIL_IF(push_inst(compiler, (inst == ADDI ? ADD : SUB) | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(TMP_REG1)));\n\t\t\tmemw = 0;\n\t\t}\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\n\t\tif (inst == SUBI)\n\t\t\tmemw = -memw;\n\t}\n\n\tSLJIT_ASSERT((memw & 0x7) == 0 && memw <= 0x1f8 && memw >= -0x200);\n\treturn push_inst(compiler, ((type & SLJIT_MEM_STORE) ? STP : LDP) | RT(REG_PAIR_FIRST(reg)) | RT2(REG_PAIR_SECOND(reg)) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x3f8) << 12));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_u32 sign = 0, inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));\n\n\tif ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_MEM_SUPP)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (type & 0xff) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\tinst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;\n\t\tbreak;\n\tcase SLJIT_MOV_S8:\n\t\tsign = 1;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_U8:\n\t\tinst = STURBI | (MEM_SIZE_SHIFT(BYTE_SIZE) << 30) | 0x400;\n\t\tbreak;\n\tcase SLJIT_MOV_S16:\n\t\tsign = 1;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_U16:\n\t\tinst = STURBI | (MEM_SIZE_SHIFT(HALF_SIZE) << 30) | 0x400;\n\t\tbreak;\n\tcase SLJIT_MOV_S32:\n\t\tsign = 1;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV32:\n\t\tinst = STURBI | (MEM_SIZE_SHIFT(INT_SIZE) << 30) | 0x400;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\tinst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;\n\t\tbreak;\n\t}\n\n\tif (!(type & SLJIT_MEM_STORE))\n\t\tinst |= sign ? 0x00800000 : 0x00400000;\n\n\tif (!(type & SLJIT_MEM_POST))\n\t\tinst |= 0x800;\n\n\treturn push_inst(compiler, inst | RT(reg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_u32 inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));\n\n\tif ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_MEM_SUPP)\n\t\treturn SLJIT_SUCCESS;\n\n\tinst = STUR_FI | 0x80000400;\n\n\tif (!(type & SLJIT_32))\n\t\tinst |= 0x40000000;\n\n\tif (!(type & SLJIT_MEM_STORE))\n\t\tinst |= 0x00400000;\n\n\tif (!(type & SLJIT_MEM_POST))\n\t\tinst |= 0x800;\n\n\treturn push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12));\n}\n\nstatic sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw)\n{\n\tsljit_ins ins;\n\tsljit_s32 mem = *mem_ptr;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\t*mem_ptr = TMP_REG2;\n\t\treturn push_inst(compiler, ADD | RD(TMP_REG2) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 10));\n\t}\n\n\tif (!(mem & REG_MASK)) {\n\t\t*mem_ptr = TMP_REG2;\n\t\treturn load_immediate(compiler, TMP_REG2, memw);\n\t}\n\n\tmem &= REG_MASK;\n\n\tif (memw == 0) {\n\t\t*mem_ptr = mem;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t*mem_ptr = TMP_REG2;\n\n\tif (memw < -0xffffff || memw > 0xffffff) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, memw));\n\t\treturn push_inst(compiler, ADD | RD(TMP_REG2) | RN(TMP_REG2) | RM(mem));\n\t}\n\n\tins = ADDI;\n\n\tif (memw < 0) {\n\t\tmemw = -memw;\n\t\tins = SUBI;\n\t}\n\n\tif (memw > 0xfff) {\n\t\tFAIL_IF(push_inst(compiler, ins | (1 << 22) | RD(TMP_REG2) | RN(mem) | ((sljit_ins)(memw >> 12) << 10)));\n\n\t\tmemw &= 0xfff;\n\t\tif (memw == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tmem = TMP_REG2;\n\t}\n\n\treturn push_inst(compiler, ins | RD(TMP_REG2) | RN(mem) | ((sljit_ins)memw << 10));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (!(srcdst & SLJIT_MEM)) {\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = VD(srcdst) | VN(vreg) | VM(vreg);\n\t\telse\n\t\t\tins = VD(vreg) | VN(srcdst) | VM(srcdst);\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (1 << 30);\n\n\t\treturn push_inst(compiler, ORR_v | ins);\n\t}\n\n\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\tif (elem_size > 3)\n\t\telem_size = 3;\n\n\tins = (type & SLJIT_SIMD_STORE) ? ST1 : LD1;\n\n\tif (reg_size == 4)\n\t\tins |= (1 << 30);\n\n\treturn push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(vreg));\n}\n\nstatic sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value)\n{\n\tsljit_ins result;\n\n\tif (elem_size > 2 && (sljit_u32)value == (value >> 32)) {\n\t\telem_size = 2;\n\t\tvalue = (sljit_u32)value;\n\t}\n\n\tif (elem_size == 2 && (sljit_u16)value == (value >> 16)) {\n\t\telem_size = 1;\n\t\tvalue = (sljit_u16)value;\n\t}\n\n\tif (elem_size == 1 && (sljit_u8)value == (value >> 8)) {\n\t\telem_size = 0;\n\t\tvalue = (sljit_u8)value;\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tSLJIT_ASSERT(value <= 0xff);\n\t\tresult = 0xe000;\n\t\tbreak;\n\tcase 1:\n\t\tSLJIT_ASSERT(value <= 0xffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x8000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & 0xff) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xa000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue ^= (sljit_uw)0xffff;\n\t\t\tresult = (1 << 29);\n\t\t}\n\t\tbreak;\n\tcase 2:\n\t\tSLJIT_ASSERT(value <= 0xffffffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x0000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff00) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0x2000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff0000) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0x4000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff000000) == 0) {\n\t\t\t\tvalue >>= 24;\n\t\t\t\tresult |= 0x6000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xc000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0xd000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue ^= (sljit_uw)0xffffffff;\n\t\t\tresult = (1 << 29);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn ~(sljit_ins)0;\n\t}\n\n\treturn (((sljit_ins)value & 0x1f) << 5) | (((sljit_ins)value & 0xe0) << 11) | result;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imm;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\n\t\tins = (sljit_ins)elem_size << 10;\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 30;\n\n\t\treturn push_inst(compiler, LD1R | ins | RN(src) | VT(vreg));\n\t}\n\n\tins = (sljit_ins)1 << (16 + elem_size);\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 30;\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM)\n\t\t\treturn push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(vreg));\n\n\t\treturn push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src));\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tif (elem_size < 3)\n\t\t\tsrcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\timm = simd_get_imm(elem_size, (sljit_uw)srcw);\n\n\t\tif (imm != ~(sljit_ins)0) {\n\t\t\timm |= ins & ((sljit_ins)1 << 30);\n\n\t\t\treturn push_inst(compiler, MOVI | imm | VD(vreg));\n\t\t}\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, srcw));\n\t\tsrc = TMP_REG2;\n\t}\n\n\treturn push_inst(compiler, DUP_g | ins | VD(vreg) | RN(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 30);\n\n\t\tif ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) {\n\t\t\tFAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(vreg) | VM(vreg)));\n\t\t\tsrcdst = TMP_FREG1;\n\t\t\tsrcdstw = 0;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, MOVI | ins | VD(vreg)));\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\t\tif (elem_size == 3)\n\t\t\tins = 0x8400;\n\t\telse if (elem_size == 0)\n\t\t\tins = 0;\n\t\telse\n\t\t\tins = (sljit_ins)0x2000 << elem_size;\n\n\t\tlane_index = lane_index << elem_size;\n\t\tins |= (sljit_ins)(((lane_index & 0x8) << 27) | ((lane_index & 0x7) << 10));\n\n\t\treturn push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(vreg));\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(vreg);\n\t\telse\n\t\t\tins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(vreg) | VN(srcdst);\n\n\t\treturn push_inst(compiler, ins);\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tif (elem_size < 3)\n\t\t\tsrcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, srcdstw));\n\t\tsrcdst = TMP_REG2;\n\t}\n\n\tif (type & SLJIT_SIMD_STORE) {\n\t\tins = RD(srcdst) | VN(vreg);\n\n\t\tif ((type & SLJIT_SIMD_LANE_SIGNED) && (elem_size < 2 || (elem_size == 2 && !(type & SLJIT_32)))) {\n\t\t\tins |= SMOV;\n\n\t\t\tif (!(type & SLJIT_32))\n\t\t\t\tins |= (sljit_ins)1 << 30;\n\t\t} else\n\t\t\tins |= UMOV;\n\t} else\n\t\tins = INS | VD(vreg) | RN(srcdst);\n\n\tif (elem_size == 3)\n\t\tins |= (sljit_ins)1 << 30;\n\n\treturn push_inst(compiler, ins | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tins = (((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size);\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 30;\n\n\treturn push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\n\t\tif (reg_size == 4 && elem2_size - elem_size == 1)\n\t\t\tFAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(vreg)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(vreg)));\n\t\tsrc = vreg;\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tSLJIT_ASSERT(reg_size == 4);\n\t\treturn push_inst(compiler, FCVTL | (1 << 22) | VD(vreg) | VN(src));\n\t}\n\n\tdo {\n\t\tFAIL_IF(push_inst(compiler, ((type & SLJIT_SIMD_EXTEND_SIGNED) ? SSHLL : USHLL)\n\t\t\t| ((sljit_ins)1 << (19 + elem_size)) | VD(vreg) | VN(src)));\n\t\tsrc = vreg;\n\t} while (++elem_size < elem2_size);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imms;\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\timms = 0x643219;\n\t\tins = USHR | (0x9 << 16);\n\t\tbreak;\n\tcase 1:\n\t\timms = (reg_size == 4) ? 0x643219 : 0x6231;\n\t\tins = USHR | (0x11 << 16);\n\t\tbreak;\n\tcase 2:\n\t\timms = (reg_size == 4) ? 0x6231 : 0x61;\n\t\tins = USHR | (0x21 << 16);\n\t\tbreak;\n\tdefault:\n\t\timms = 0x61;\n\t\tins = USHR | (0x41 << 16);\n\t\tbreak;\n\t}\n\n\tif (reg_size == 4)\n\t\tins |= (1 << 30);\n\n\tFAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(vreg)));\n\n\tif (reg_size == 4 && elem_size > 0)\n\t\tFAIL_IF(push_inst(compiler, XTN | ((sljit_ins)(elem_size - 1) << 22) | VD(TMP_FREG1) | VN(TMP_FREG1)));\n\n\tif (imms >= 0x100) {\n\t\tins = (reg_size == 4 && elem_size == 0) ? (1 << 30) : 0;\n\n\t\tdo {\n\t\t\tFAIL_IF(push_inst(compiler, USRA | ins | ((imms & 0xff) << 16) | VD(TMP_FREG1) | VN(TMP_FREG1)));\n\t\t\timms >>= 8;\n\t\t} while (imms >= 0x100);\n\t}\n\n\tFAIL_IF(push_inst(compiler, USRA | (1 << 30) | (imms << 16) | VD(TMP_FREG1) | VN(TMP_FREG1)));\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tins = (0x1 << 16);\n\n\tif (reg_size == 4 && elem_size == 0) {\n\t\tFAIL_IF(push_inst(compiler, INS_e | (0x3 << 16) | (0x8 << 11) | VD(TMP_FREG1) | VN(TMP_FREG1)));\n\t\tins = (0x2 << 16);\n\t}\n\n\tFAIL_IF(push_inst(compiler, UMOV | ins | RD(dst_r) | VN(TMP_FREG1)));\n\n\tif (dst_r == TMP_REG2)\n\t\treturn emit_op_mem(compiler, STORE | ((type & SLJIT_32) ? INT_SIZE : WORD_SIZE), TMP_REG2, dst, dstw, TMP_REG1);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = AND_v;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = ORR_v;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = EOR_v;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tins = TBL_v;\n\t\tbreak;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (elem_size > 3)\n\t\t\telem_size = 3;\n\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w));\n\t\tpush_inst(compiler,  LD1 | (reg_size == 4 ? (1 << 30) : 0) | ((sljit_ins)elem_size << 10) | RN(src2) | VT(TMP_FREG1));\n\t\tsrc2 = TMP_FREG1;\n\t}\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 30;\n\n\treturn push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n#ifndef __ARM_FEATURE_ATOMICS\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* ARM_FEATURE_ATOMICS */\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_U32:\n#ifdef __ARM_FEATURE_ATOMICS\n\t\tif (!(op & SLJIT_ATOMIC_USE_LS))\n\t\t\tins = LDR ^ (1 << 30);\n\t\telse\n#endif /* ARM_FEATURE_ATOMICS */\n\t\t\tins = LDXR ^ (1 << 30);\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n#ifdef __ARM_FEATURE_ATOMICS\n\t\tif (!(op & SLJIT_ATOMIC_USE_LS))\n\t\t\tins = LDRB;\n\t\telse\n#endif /* ARM_FEATURE_ATOMICS */\n\t\t\tins = LDXRB;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n#ifdef __ARM_FEATURE_ATOMICS\n\t\tif (!(op & SLJIT_ATOMIC_USE_LS))\n\t\t\tins = LDRH;\n\t\telse\n#endif /* ARM_FEATURE_ATOMICS */\n\t\t\tins = LDXRH;\n\t\tbreak;\n\tdefault:\n#ifdef __ARM_FEATURE_ATOMICS\n\t\tif (!(op & SLJIT_ATOMIC_USE_LS))\n\t\t\tins = LDR;\n\t\telse\n#endif /* ARM_FEATURE_ATOMICS */\n\t\t\tins = LDXR;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | RN(mem_reg) | RT(dst_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\tsljit_ins cmp = 0;\n\tSLJIT_UNUSED_ARG(temp_reg); /* !__ARM_FEATURE_ATOMICS */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n#ifdef __ARM_FEATURE_ATOMICS\n\tif (!(op & SLJIT_ATOMIC_USE_LS)) {\n\t\tif (op & SLJIT_SET_ATOMIC_STORED)\n\t\t\tcmp = (SUBS ^ W_OP) | RD(TMP_ZERO);\n\n\t\tswitch (GET_OPCODE(op)) {\n\t\tcase SLJIT_MOV_S8:\n\t\tcase SLJIT_MOV_S16:\n\t\tcase SLJIT_MOV_S32:\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tcase SLJIT_MOV32:\n\t\tcase SLJIT_MOV_U32:\n\t\t\tins = CAS ^ (1 << 30);\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U16:\n\t\t\tins = CASH;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U8:\n\t\t\tins = CASB;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tins = CAS;\n\t\t\tif (cmp)\n\t\t\t\tcmp ^= W_OP;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (cmp)\n\t\t\tFAIL_IF(push_inst(compiler, ((MOV ^ W_OP) ^ (cmp & W_OP)) | RM(temp_reg) | RD(TMP_REG2)));\n\n\t\tFAIL_IF(push_inst(compiler, ins | RM(temp_reg) | RN(mem_reg) | RD(src_reg)));\n\t\tif (!cmp)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, cmp | RM(TMP_REG2) | RN(temp_reg));\n\t}\n#else /* !__ARM_FEATURE_ATOMICS */\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* __ARM_FEATURE_ATOMICS */\n\n\tif (op & SLJIT_SET_ATOMIC_STORED)\n\t\tcmp = (SUBI ^ W_OP) | (1 << 29);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_U32:\n\t\tins = STXR ^ (1 << 30);\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n\t\tins = STXRB;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = STXRH;\n\t\tbreak;\n\tdefault:\n\t\tins = STXR;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst(compiler, ins | RM(TMP_REG2) | RN(mem_reg) | RT(src_reg)));\n\tif (!cmp)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)\n{\n\tsljit_s32 dst_reg;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);\n\n\tdst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\t/* Not all instruction forms support accessing SP register. */\n\tif (offset <= 0xffffff && offset >= -0xffffff) {\n\t\tins = ADDI;\n\t\tif (offset < 0) {\n\t\t\toffset = -offset;\n\t\t\tins = SUBI;\n\t\t}\n\n\t\tif (offset <= 0xfff)\n\t\t\tFAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (sljit_ins)(offset << 10)));\n\t\telse {\n\t\t\tFAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (sljit_ins)((offset & 0xfff000) >> (12 - 10)) | (1 << 22)));\n\n\t\t\toffset &= 0xfff;\n\t\t\tif (offset != 0)\n\t\t\t\tFAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(dst_reg) | (sljit_ins)(offset << 10)));\n\t\t}\n\t}\n\telse {\n\t\tFAIL_IF(load_immediate (compiler, dst_reg, offset));\n\t\t/* Add extended register form. */\n\t\tFAIL_IF(push_inst(compiler, ADDE | (0x3 << 13) | RD(dst_reg) | RN(SLJIT_SP) | RM(dst_reg)));\n\t}\n\n\tif (SLJIT_UNLIKELY(dst & SLJIT_MEM))\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\n#define SLJIT_EMIT_CONST_U8(c) \\\n\t(((c) & 0x100) != 0 ? (MOVN | (sljit_ins)((~(c) & 0xff) << 5)) : (MOVZ | (sljit_ins)(((c) & 0xff) << 5)))\n#define SLJIT_EMIT_CONST_S32(c) \\\n\t(((c) < 0) ? (MOVN | (sljit_ins)((~(c) & 0xffff) << 5)) : (MOVZ | (sljit_ins)(((c) & 0xffff) << 5)))\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_SIZE | STORE;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tPTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_U8(init_value) | RD(dst_r)));\n\t\tmem_flags = BYTE_SIZE | STORE;\n\t\tbreak;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tif (GET_OPCODE(op) == SLJIT_MOV32) {\n\t\t\tinit_value = (sljit_u32)init_value;\n\t\t\tmem_flags = INT_SIZE | STORE;\n\t\t} else\n\t\t\tinit_value = (sljit_s32)init_value;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_S32(init_value) | RD(dst_r)));\n\t\tPTR_FAIL_IF(push_inst(compiler, MOVK | (1 << 21) | (sljit_ins)((init_value >> 11) & 0x1fffe0) | RD(dst_r)));\n\t\tbreak;\n\n\tdefault:\n\t\tPTR_FAIL_IF(emit_imm64_const(compiler, dst_r, (sljit_uw)init_value));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG2));\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG2;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));\n\t}\n\n\tPTR_FAIL_IF(push_inst(compiler, RD(target_r)));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 1);\n\n\tcompiler->size += 3;\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(dst_r) | RM(TMP_REG2)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins* inst = (sljit_ins*)addr;\n\tsljit_u32 dst;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);\n\n\tdst = inst[0] & 0x1f;\n\tSLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));\n\tinst[0] = MOVZ | dst | (((sljit_u32)new_target & 0xffff) << 5);\n\tinst[1] = MOVK | dst | (((sljit_u32)(new_target >> 16) & 0xffff) << 5) | (1 << 21);\n\tinst[2] = MOVK | dst | (((sljit_u32)(new_target >> 32) & 0xffff) << 5) | (2 << 21);\n\tinst[3] = MOVK | dst | ((sljit_u32)(new_target >> 48) << 5) | (3 << 21);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 4);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_ins* inst;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tinst = (sljit_ins*)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ || (inst[0] & 0xffe00000) == MOVN);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\tinst[0] = SLJIT_EMIT_CONST_U8(new_constant) | (inst[0] & 0x1f);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\treturn;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tif (GET_OPCODE(op) == SLJIT_MOV32)\n\t\t\tnew_constant = (sljit_u32)new_constant;\n\t\telse\n\t\t\tnew_constant = (sljit_s32)new_constant;\n\n\t\tinst = (sljit_ins*)addr;\n\t\tSLJIT_ASSERT(((inst[0] & 0xffe00000) == MOVZ || (inst[0] & 0xffe00000) == MOVN) && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[0] = SLJIT_EMIT_CONST_S32(new_constant) | (inst[0] & 0x1f);\n\t\tinst[1] = MOVK | (1 << 21) | (sljit_ins)((new_constant >> 11) & 0x1fffe0) | (inst[1] & 0x1f);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n\n\tdefault:\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n#ifdef __SOFTFP__\n\treturn \"ARM-Thumb2\" SLJIT_CPUINFO \" ABI:softfp\";\n#else\n\treturn \"ARM-Thumb2\" SLJIT_CPUINFO \" ABI:hardfp\";\n#endif\n}\n\n/* Length of an instruction word. */\ntypedef sljit_u32 sljit_ins;\n\n/* Last register + 1. */\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_PC\t\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\n/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {\n\t0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15\n};\n\nstatic const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {\n\t0,\n\t0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,\n\t7, 6,\n\t0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,\n\t7, 6\n};\n\nstatic const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {\n\t0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1\n};\n\n#define COPY_BITS(src, from, to, bits) \\\n\t((from >= to ? ((sljit_ins)(src) >> (from - to)) : ((sljit_ins)(src) << (to - from))) & (((1 << bits) - 1) << to))\n\n#define NEGATE(uimm) ((sljit_uw)-(sljit_sw)(uimm))\n\n/* Thumb16 encodings. */\n#define RD3(rd) ((sljit_ins)reg_map[rd])\n#define RN3(rn) ((sljit_ins)reg_map[rn] << 3)\n#define RM3(rm) ((sljit_ins)reg_map[rm] << 6)\n#define RDN3(rdn) ((sljit_ins)reg_map[rdn] << 8)\n#define IMM3(imm) ((sljit_ins)imm << 6)\n#define IMM8(imm) ((sljit_ins)imm)\n\n/* Thumb16 helpers. */\n#define SET_REGS44(rd, rn) \\\n\t(((sljit_ins)reg_map[rn] << 3) | ((sljit_ins)reg_map[rd] & 0x7) | (((sljit_ins)reg_map[rd] & 0x8) << 4))\n#define IS_2_LO_REGS(reg1, reg2) \\\n\t(reg_map[reg1] <= 7 && reg_map[reg2] <= 7)\n#define IS_3_LO_REGS(reg1, reg2, reg3) \\\n\t(reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)\n\n/* Thumb32 encodings. */\n#define RM4(rm) ((sljit_ins)reg_map[rm])\n#define RD4(rd) ((sljit_ins)reg_map[rd] << 8)\n#define RT4(rt) ((sljit_ins)reg_map[rt] << 12)\n#define RN4(rn) ((sljit_ins)reg_map[rn] << 16)\n\n#define VM4(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5))\n#define VD4(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22))\n#define VN4(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7))\n\n#define IMM5(imm) \\\n\t(COPY_BITS(imm, 2, 12, 3) | (((sljit_ins)imm & 0x3) << 6))\n#define IMM12(imm) \\\n\t(COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | ((sljit_ins)imm & 0xff))\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n/* dot '.' changed to _\n   I immediate form (possibly followed by number of immediate bits). */\n#define ADCI\t\t0xf1400000\n#define ADCS\t\t0x4140\n#define ADC_W\t\t0xeb400000\n#define ADD\t\t0x4400\n#define ADDS\t\t0x1800\n#define ADDSI3\t\t0x1c00\n#define ADDSI8\t\t0x3000\n#define ADDWI\t\t0xf2000000\n#define ADD_SP\t\t0x4485\n#define ADD_SP_I\t0xb000\n#define ADD_W\t\t0xeb000000\n#define ADD_WI\t\t0xf1000000\n#define ANDI\t\t0xf0000000\n#define ANDS\t\t0x4000\n#define AND_W\t\t0xea000000\n#define ASRS\t\t0x4100\n#define ASRSI\t\t0x1000\n#define ASR_W\t\t0xfa40f000\n#define ASR_WI\t\t0xea4f0020\n#define BCC\t\t0xd000\n#define BICI\t\t0xf0200000\n#define BKPT\t\t0xbe00\n#define BLX\t\t0x4780\n#define BX\t\t0x4700\n#define CLZ\t\t0xfab0f080\n#define CMNI_W\t\t0xf1100f00\n#define CMP\t\t0x4280\n#define CMPI\t\t0x2800\n#define CMPI_W\t\t0xf1b00f00\n#define CMP_X\t\t0x4500\n#define CMP_W\t\t0xebb00f00\n#define DMB_SY\t\t0xf3bf8f5f\n#define EORI\t\t0xf0800000\n#define EORS\t\t0x4040\n#define EOR_W\t\t0xea800000\n#define IT\t\t0xbf00\n#define LDR\t\t0xf8d00000\n#define LDR_SP\t\t0x9800\n#define LDRD\t\t0xe9500000\n#define LDREX\t\t0xe8500f00\n#define LDREXB\t\t0xe8d00f4f\n#define LDREXH\t\t0xe8d00f5f\n#define LDRI\t\t0xf8500800\n#define LSLS\t\t0x4080\n#define LSLSI\t\t0x0000\n#define LSL_W\t\t0xfa00f000\n#define LSL_WI\t\t0xea4f0000\n#define LSRS\t\t0x40c0\n#define LSRSI\t\t0x0800\n#define LSR_W\t\t0xfa20f000\n#define LSR_WI\t\t0xea4f0010\n#define MLA\t\t0xfb000000\n#define MOV\t\t0x4600\n#define MOVI\t\t0x2000\n#define MOVS\t\t0x0000\n#define MOVSI\t\t0x2000\n#define MOVT\t\t0xf2c00000\n#define MOVW\t\t0xf2400000\n#define MOV_W\t\t0xea4f0000\n#define MOV_WI\t\t0xf04f0000\n#define MUL\t\t0xfb00f000\n#define MVNS\t\t0x43c0\n#define MVN_W\t\t0xea6f0000\n#define MVN_WI\t\t0xf06f0000\n#define NOP\t\t0xbf00\n#define ORNI\t\t0xf0600000\n#define ORRI\t\t0xf0400000\n#define ORRS\t\t0x4300\n#define ORR_W\t\t0xea400000\n#define POP\t\t0xbc00\n#define POP_W\t\t0xe8bd0000\n#define PUSH\t\t0xb400\n#define PUSH_W\t\t0xe92d0000\n#define REV\t\t0xba00\n#define REV_W\t\t0xfa90f080\n#define REV16\t\t0xba40\n#define REV16_W\t\t0xfa90f090\n#define RBIT\t\t0xfa90f0a0\n#define RORS\t\t0x41c0\n#define ROR_W\t\t0xfa60f000\n#define ROR_WI\t\t0xea4f0030\n#define RSB_WI\t\t0xf1c00000\n#define RSBSI\t\t0x4240\n#define SBCI\t\t0xf1600000\n#define SBCS\t\t0x4180\n#define SBC_W\t\t0xeb600000\n#define SDIV\t\t0xfb90f0f0\n#define SMULL\t\t0xfb800000\n#define STR_SP\t\t0x9000\n#define STRD\t\t0xe9400000\n#define STREX\t\t0xe8400000\n#define STREXB\t\t0xe8c00f40\n#define STREXH\t\t0xe8c00f50\n#define SUBS\t\t0x1a00\n#define SUBSI3\t\t0x1e00\n#define SUBSI8\t\t0x3800\n#define SUB_W\t\t0xeba00000\n#define SUBWI\t\t0xf2a00000\n#define SUB_SP_I\t0xb080\n#define SUB_WI\t\t0xf1a00000\n#define SXTB\t\t0xb240\n#define SXTB_W\t\t0xfa4ff080\n#define SXTH\t\t0xb200\n#define SXTH_W\t\t0xfa0ff080\n#define TST\t\t0x4200\n#define TSTI\t\t0xf0000f00\n#define TST_W\t\t0xea000f00\n#define UDIV\t\t0xfbb0f0f0\n#define UMULL\t\t0xfba00000\n#define UXTB\t\t0xb2c0\n#define UXTB_W\t\t0xfa5ff080\n#define UXTH\t\t0xb280\n#define UXTH_W\t\t0xfa1ff080\n#define VABS_F32\t0xeeb00ac0\n#define VADD_F32\t0xee300a00\n#define VAND\t\t0xef000110\n#define VCMP_F32\t0xeeb40a40\n#define VCVT_F32_S32\t0xeeb80ac0\n#define VCVT_F32_U32\t0xeeb80a40\n#define VCVT_F64_F32\t0xeeb70ac0\n#define VCVT_S32_F32\t0xeebd0ac0\n#define VDIV_F32\t0xee800a00\n#define VDUP\t\t0xee800b10\n#define VDUP_s\t\t0xffb00c00\n#define VEOR\t\t0xff000110\n#define VLD1\t\t0xf9200000\n#define VLD1_r\t\t0xf9a00c00\n#define VLD1_s\t\t0xf9a00000\n#define VLDR_F32\t0xed100a00\n#define VMOV_F32\t0xeeb00a40\n#define VMOV\t\t0xee000a10\n#define VMOV2\t\t0xec400a10\n#define VMOV_i\t\t0xef800010\n#define VMOV_s\t\t0xee000b10\n#define VMOVN\t\t0xffb20200\n#define VMRS\t\t0xeef1fa10\n#define VMUL_F32\t0xee200a00\n#define VNEG_F32\t0xeeb10a40\n#define VORR\t\t0xef200110\n#define VPOP\t\t0xecbd0b00\n#define VPUSH\t\t0xed2d0b00\n#define VSHLL\t\t0xef800a10\n#define VSHR\t\t0xef800010\n#define VSRA\t\t0xef800110\n#define VST1\t\t0xf9000000\n#define VST1_s\t\t0xf9800000\n#define VSTR_F32\t0xed000a00\n#define VSUB_F32\t0xee300a40\n#define VTBL\t\t0xffb00800\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\nstatic sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))\n\t\tfr -= SLJIT_F64_SECOND(0);\n\n\treturn (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))\n\t\t|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)\n\t\t|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));\n}\n\nstatic sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)\n{\n\tsljit_s32 vr_low = vr;\n\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (SLJIT_SIMD_GET_REG_SIZE(type) == 4) {\n\t\tvr += (vr & 0x1);\n\t\tvr_low = vr - 1;\n\t}\n\n\treturn (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches))\n\t\t|| (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0)\n\t\t|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));\n}\n\n#endif /* SLJIT_ARGUMENT_CHECKS */\n\nstatic sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)\n{\n\tsljit_u16 *ptr;\n\tSLJIT_ASSERT(!(inst & 0xffff0000));\n\n\tptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));\n\tFAIL_IF(!ptr);\n\t*ptr = (sljit_u16)(inst);\n\tcompiler->size++;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)\n{\n\tsljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\t*ptr++ = (sljit_u16)(inst >> 16);\n\t*ptr = (sljit_u16)(inst);\n\tcompiler->size += 2;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)\n{\n\tFAIL_IF(push_inst32(compiler, MOVW | RD4(dst)\n\t\t| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));\n\treturn push_inst32(compiler, MOVT | RD4(dst)\n\t\t| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));\n}\n\n/* Dst must be in bits[11-8] */\nstatic void set_imm32_const(sljit_u16 *inst, sljit_ins dst, sljit_uw new_imm)\n{\n\tinst[0] = (sljit_u16)((MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1));\n\tinst[1] = (sljit_u16)(dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff));\n\tinst[2] = (sljit_u16)((MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1));\n\tinst[3] = (sljit_u16)(dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16));\n}\n\nstatic SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)\n{\n\tsljit_ins dst = inst[1] & 0x0f00;\n\tSLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));\n\tset_imm32_const(inst, dst, new_imm);\n}\n\nstatic SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tjump->addr = jump_addr;\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n\n\tif (jump->flags & JUMP_ADDR) {\n\t\t/* Branch to ARM code is not optimized yet. */\n\t\tif (!(jump->u.target & 0x1))\n\t\t\tgoto exit;\n\t\ttarget_addr = jump->u.target;\n\t} else {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 4, executable_offset);\n\n\tif (jump->flags & IS_COND) {\n\t\tSLJIT_ASSERT(!(jump->flags & IS_BL));\n\t\t/* Size of the prefix IT instruction. */\n\t\tdiff += SSIZE_OF(u16);\n\t\tif (diff <= 0xff && diff >= -0x100) {\n\t\t\tjump->flags |= PATCH_TYPE1;\n\t\t\tjump->addr = (sljit_uw)(code_ptr - 1);\n\t\t\treturn code_ptr - 1;\n\t\t}\n\t\tif (diff <= 0xfffff && diff >= -0x100000) {\n\t\t\tjump->flags |= PATCH_TYPE2;\n\t\t\tjump->addr = (sljit_uw)(code_ptr - 1);\n\t\t\treturn code_ptr;\n\t\t}\n\t\tdiff -= SSIZE_OF(u16);\n\t} else if (jump->flags & IS_BL) {\n\t\t/* Branch and link. */\n\t\tif (diff <= 0xffffff && diff >= -0x1000000) {\n\t\t\tjump->flags |= PATCH_TYPE5;\n\t\t\treturn code_ptr + 1;\n\t\t}\n\t\tgoto exit;\n\t} else if (diff <= 0x7ff && diff >= -0x800) {\n\t\tjump->flags |= PATCH_TYPE3;\n\t\treturn code_ptr;\n\t}\n\n\tif (diff <= 0xffffff && diff >= -0x1000000) {\n\t\tjump->flags |= PATCH_TYPE4;\n\t\treturn code_ptr + 1;\n\t}\n\nexit:\n\tcode_ptr[4] = code_ptr[0];\n\n\tif (jump->flags & IS_COND) {\n\t\tcode_ptr[3] = code_ptr[-1];\n\t\tjump->addr = (sljit_uw)(code_ptr - 1);\n\t}\n\n\treturn code_ptr + 4;\n}\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse {\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t}\n\n\t/* The pc+4 offset is represented by the 2 * SSIZE_OF(sljit_u16) below. */\n\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\t/* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */\n\n\tif (diff <= 0xffd + 2 * SSIZE_OF(u16) && diff >= -0xfff + 2 * SSIZE_OF(u16)) {\n\t\tjump->flags |= PATCH_TYPE6;\n\t\treturn 1;\n\t}\n\n\treturn 3;\n}\n\nstatic SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_s32 type = (jump->flags >> 4) & 0xf;\n\tsljit_u16 *jump_inst = (sljit_u16*)jump->addr;\n\tsljit_sw diff;\n\tsljit_ins ins;\n\n\tdiff = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);\n\n\tif ((jump->flags & (JUMP_MOV_ADDR | IS_ABS)) == (JUMP_MOV_ADDR | IS_ABS))\n\t\tdiff &= ~(sljit_sw)1;\n\n\tif (SLJIT_UNLIKELY(type == 0)) {\n\t\tins = (jump->flags & JUMP_MOV_ADDR) ? *jump_inst : RDN3(TMP_REG1);\n\t\tset_imm32_const((sljit_u16*)jump->addr, ins, (sljit_uw)diff);\n\t\treturn;\n\t}\n\n\tif (SLJIT_UNLIKELY(type == 6)) {\n\t\tSLJIT_ASSERT(jump->flags & JUMP_MOV_ADDR);\n\t\tdiff -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_inst + 2, executable_offset) & ~(sljit_sw)0x3;\n\n\t\tSLJIT_ASSERT(diff <= 0xfff && diff >= -0xfff);\n\n\t\tins = ADDWI >> 16;\n\t\tif (diff <= 0) {\n\t\t\tdiff = -diff;\n\t\t\tins = SUBWI >> 16;\n\t\t}\n\n\t\tjump_inst[1] = (sljit_u16)(jump_inst[0] | COPY_BITS(diff, 8, 12, 3) | (diff & 0xff));\n\t\tjump_inst[0] = (sljit_u16)(ins | 0xf | COPY_BITS(diff, 11, 10, 1));\n\t\treturn;\n\t}\n\n\tSLJIT_ASSERT((diff & 0x1) != 0 && !(jump->flags & JUMP_MOV_ADDR));\n\tdiff = (diff - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;\n\n\tswitch (type) {\n\tcase 1:\n\t\t/* Encoding T1 of 'B' instruction */\n\t\tSLJIT_ASSERT(diff <= 0x7f && diff >= -0x80 && (jump->flags & IS_COND));\n\t\tjump_inst[0] = (sljit_u16)(0xd000 | (jump->flags & 0xf00) | ((sljit_ins)diff & 0xff));\n\t\treturn;\n\tcase 2:\n\t\t/* Encoding T3 of 'B' instruction */\n\t\tSLJIT_ASSERT(diff <= 0x7ffff && diff >= -0x80000 && (jump->flags & IS_COND));\n\t\tjump_inst[0] = (sljit_u16)(0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1));\n\t\tjump_inst[1] = (sljit_u16)(0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | ((sljit_ins)diff & 0x7ff));\n\t\treturn;\n\tcase 3:\n\t\t/* Encoding T2 of 'B' instruction */\n\t\tSLJIT_ASSERT(diff <= 0x3ff && diff >= -0x400 && !(jump->flags & IS_COND));\n\t\tjump_inst[0] = (sljit_u16)(0xe000 | (diff & 0x7ff));\n\t\treturn;\n\t}\n\n\tSLJIT_ASSERT(diff <= 0x7fffff && diff >= -0x800000);\n\n\t/* Really complex instruction form for branches. Negate with sign bit. */\n\tdiff ^= ((diff >> 2) & 0x600000) ^ 0x600000;\n\n\tjump_inst[0] = (sljit_u16)(0xf000 | COPY_BITS(diff, 11, 0, 10) | COPY_BITS(diff, 23, 10, 1));\n\tjump_inst[1] = (sljit_u16)((diff & 0x7ff) | COPY_BITS(diff, 22, 13, 1) | COPY_BITS(diff, 21, 11, 1));\n\n\tSLJIT_ASSERT(type == 4 || type == 5);\n\n\t/* The others have a common form. */\n\tif (type == 4) /* Encoding T4 of 'B' instruction */\n\t\tjump_inst[1] |= 0x9000;\n\telse /* Encoding T1 of 'BL' instruction */\n\t\tjump_inst[1] |= 0xd000;\n}\n\nstatic SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE;\n\n\t\t\tif (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) {\n\t\t\t\t/* Unit size: instruction. */\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (jump->flags & IS_COND) {\n\t\t\t\t\tdiff++;\n\n\t\t\t\t\tif (diff <= (0xff / SSIZE_OF(u16)) && diff >= (-0x100 / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = 0;\n\t\t\t\t\telse if (diff <= (0xfffff / SSIZE_OF(u16)) && diff >= (-0x100000 / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = 1;\n\t\t\t\t\tdiff--;\n\t\t\t\t} else if (!(jump->flags & IS_BL) && diff <= (0x7ff / SSIZE_OF(u16)) && diff >= (-0x800 / SSIZE_OF(u16)))\n\t\t\t\t\ttotal_size = 1;\n\n\t\t\t\tif (total_size == JUMP_MAX_SIZE && diff <= (0xffffff / SSIZE_OF(u16)) && diff >= (-0x1000000 / SSIZE_OF(u16)))\n\t\t\t\t\ttotal_size = 2;\n\t\t\t}\n\n\t\t\tsize_reduce += JUMP_MAX_SIZE - total_size;\n\t\t} else {\n\t\t\t/* Real size minus 1. Unit size: instruction. */\n\t\t\ttotal_size = 3;\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16)))\n\t\t\t\t\ttotal_size = 1;\n\t\t\t}\n\n\t\t\tsize_reduce += 3 - total_size;\n\t\t}\n\n\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_u16 *code;\n\tsljit_u16 *code_ptr;\n\tsljit_u16 *buf_ptr;\n\tsljit_u16 *buf_end;\n\tsljit_uw half_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw addr;\n\tsljit_sw executable_offset;\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n\tcode = (sljit_u16*)allocate_executable_memory(compiler->size * sizeof(sljit_u16), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\thalf_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_u16*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 1);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == half_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= half_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= half_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= half_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\tlabel->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\thalf_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tSLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <\n\t\t\t\t\t\t\t((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) * sizeof(sljit_u16));\n\t\t\t\t\t} else {\n\t\t\t\t\t\thalf_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\taddr = (sljit_sw)code_ptr;\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tjump->addr = (sljit_uw)addr;\n\t\t\t\t\t}\n\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\thalf_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == half_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tgenerate_jump_or_mov_addr(jump, executable_offset);\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_u16);\n\n\tcode = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\n\t/* Set thumb mode flag. */\n\treturn (void*)((sljit_uw)code | 0x1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n\tcase SLJIT_HAS_F64_AS_F32_PAIR:\n\tcase SLJIT_HAS_SIMD:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif\n\n\tcase SLJIT_SIMD_REGS_ARE_PAIRS:\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_CTZ:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_CMOV:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\n/* --------------------------------------------------------------------- */\n/*  Core code generator functions.                                       */\n/* --------------------------------------------------------------------- */\n\n#define INVALID_IMM\t0x80000000\nstatic sljit_uw get_imm(sljit_uw imm)\n{\n\t/* Thumb immediate form. */\n\tsljit_s32 counter;\n\n\tif (imm <= 0xff)\n\t\treturn imm;\n\n\tif ((imm & 0xffff) == (imm >> 16)) {\n\t\t/* Some special cases. */\n\t\tif (!(imm & 0xff00))\n\t\t\treturn (1 << 12) | (imm & 0xff);\n\t\tif (!(imm & 0xff))\n\t\t\treturn (2 << 12) | ((imm >> 8) & 0xff);\n\t\tif ((imm & 0xff00) == ((imm & 0xff) << 8))\n\t\t\treturn (3 << 12) | (imm & 0xff);\n\t}\n\n\t/* Assembly optimization: count leading zeroes? */\n\tcounter = 8;\n\tif (!(imm & 0xffff0000)) {\n\t\tcounter += 16;\n\t\timm <<= 16;\n\t}\n\tif (!(imm & 0xff000000)) {\n\t\tcounter += 8;\n\t\timm <<= 8;\n\t}\n\tif (!(imm & 0xf0000000)) {\n\t\tcounter += 4;\n\t\timm <<= 4;\n\t}\n\tif (!(imm & 0xc0000000)) {\n\t\tcounter += 2;\n\t\timm <<= 2;\n\t}\n\tif (!(imm & 0x80000000)) {\n\t\tcounter += 1;\n\t\timm <<= 1;\n\t}\n\t/* Since imm >= 128, this must be true. */\n\tSLJIT_ASSERT(counter <= 31);\n\n\tif (imm & 0x00ffffff)\n\t\treturn INVALID_IMM; /* Cannot be encoded. */\n\n\treturn ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);\n}\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)\n{\n\tsljit_uw tmp;\n\n\t/* MOVS cannot be used since it destroy flags. */\n\n\tif (imm >= 0x10000) {\n\t\ttmp = get_imm(imm);\n\t\tif (tmp != INVALID_IMM)\n\t\t\treturn push_inst32(compiler, MOV_WI | RD4(dst) | tmp);\n\t\ttmp = get_imm(~imm);\n\t\tif (tmp != INVALID_IMM)\n\t\t\treturn push_inst32(compiler, MVN_WI | RD4(dst) | tmp);\n\t}\n\n\t/* set low 16 bits, set hi 16 bits to 0. */\n\tFAIL_IF(push_inst32(compiler, MOVW | RD4(dst)\n\t\t| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));\n\n\t/* set hi 16 bit if needed. */\n\tif (imm >= 0x10000)\n\t\treturn push_inst32(compiler, MOVT | RD4(dst)\n\t\t\t| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));\n\treturn SLJIT_SUCCESS;\n}\n\n#define ARG1_IMM\t0x0010000\n#define ARG2_IMM\t0x0020000\n/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */\n#define SET_FLAGS\t0x0100000\n#define UNUSED_RETURN\t0x0200000\n#define REGISTER_OP\t0x0400000\n\nstatic sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)\n{\n\t/* dst must be register\n\t   arg1 must be register, imm\n\t   arg2 must be register, imm */\n\tsljit_s32 reg;\n\tsljit_uw imm, imm2;\n\n\tif (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {\n\t\t/* Both are immediates, no temporaries are used. */\n\t\tflags &= ~ARG1_IMM;\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, arg1));\n\t\targ1 = TMP_REG1;\n\t}\n\n\tif (flags & (ARG1_IMM | ARG2_IMM)) {\n\t\treg = (sljit_s32)((flags & ARG2_IMM) ? arg1 : arg2);\n\t\timm = (flags & ARG2_IMM) ? arg2 : arg1;\n\n\t\tswitch (flags & 0xffff) {\n\t\tcase SLJIT_CLZ:\n\t\tcase SLJIT_CTZ:\n\t\tcase SLJIT_REV:\n\t\tcase SLJIT_REV_U16:\n\t\tcase SLJIT_REV_S16:\n\t\tcase SLJIT_REV_U32:\n\t\tcase SLJIT_REV_S32:\n\t\tcase SLJIT_MUL:\n\t\tcase SLJIT_MULADD:\n\t\t\t/* No form with immediate operand. */\n\t\t\tbreak;\n\t\tcase SLJIT_MOV:\n\t\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2);\n\t\t\treturn load_immediate(compiler, dst, imm);\n\t\tcase SLJIT_ADD:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\t\timm2 = NEGATE(imm);\n\t\t\tif (IS_2_LO_REGS(reg, dst)) {\n\t\t\t\tif (imm <= 0x7)\n\t\t\t\t\treturn push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));\n\t\t\t\tif (imm2 <= 0x7)\n\t\t\t\t\treturn push_inst16(compiler, SUBSI3 | IMM3(imm2) | RD3(dst) | RN3(reg));\n\t\t\t\tif (reg == dst) {\n\t\t\t\t\tif (imm <= 0xff)\n\t\t\t\t\t\treturn push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));\n\t\t\t\t\tif (imm2 <= 0xff)\n\t\t\t\t\t\treturn push_inst16(compiler, SUBSI8 | IMM8(imm2) | RDN3(dst));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(flags & SET_FLAGS)) {\n\t\t\t\tif (imm <= 0xfff)\n\t\t\t\t\treturn push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));\n\t\t\t\tif (imm2 <= 0xfff)\n\t\t\t\t\treturn push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm2));\n\t\t\t}\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\timm = get_imm(NEGATE(imm));\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_ADDC:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\tif (flags & ARG2_IMM) {\n\t\t\t\timm = get_imm(~imm);\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\treturn push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SLJIT_SUB:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\t\tif (flags & ARG1_IMM) {\n\t\t\t\tif (imm == 0 && IS_2_LO_REGS(reg, dst))\n\t\t\t\t\treturn push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));\n\t\t\t\timm = get_imm(imm);\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\treturn push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (flags & UNUSED_RETURN) {\n\t\t\t\tif (imm <= 0xff && reg_map[reg] <= 7)\n\t\t\t\t\treturn push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));\n\t\t\t\timm2 = get_imm(imm);\n\t\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\t\treturn push_inst32(compiler, CMPI_W | RN4(reg) | imm2);\n\t\t\t\timm = get_imm(NEGATE(imm));\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\treturn push_inst32(compiler, CMNI_W | RN4(reg) | imm);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\timm2 = NEGATE(imm);\n\t\t\tif (IS_2_LO_REGS(reg, dst)) {\n\t\t\t\tif (imm <= 0x7)\n\t\t\t\t\treturn push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));\n\t\t\t\tif (imm2 <= 0x7)\n\t\t\t\t\treturn push_inst16(compiler, ADDSI3 | IMM3(imm2) | RD3(dst) | RN3(reg));\n\t\t\t\tif (reg == dst) {\n\t\t\t\t\tif (imm <= 0xff)\n\t\t\t\t\t\treturn push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));\n\t\t\t\t\tif (imm2 <= 0xff)\n\t\t\t\t\t\treturn push_inst16(compiler, ADDSI8 | IMM8(imm2) | RDN3(dst));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(flags & SET_FLAGS)) {\n\t\t\t\tif (imm <= 0xfff)\n\t\t\t\t\treturn push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));\n\t\t\t\tif (imm2 <= 0xfff)\n\t\t\t\t\treturn push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm2));\n\t\t\t}\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\timm = get_imm(NEGATE(imm));\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_SUBC:\n\t\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\timm = get_imm(~imm);\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_AND:\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ((flags & UNUSED_RETURN) ? TSTI : ANDI) | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\timm = get_imm(~imm);\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_OR:\n\t\t\timm2 = get_imm(imm);\n\t\t\tif (imm2 != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2);\n\t\t\timm = get_imm(~imm);\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_XOR:\n\t\t\tif (imm == (sljit_uw)-1) {\n\t\t\t\tif (IS_2_LO_REGS(dst, reg))\n\t\t\t\t\treturn push_inst16(compiler, MVNS | RD3(dst) | RN3(reg));\n\t\t\t\treturn push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(reg));\n\t\t\t}\n\t\t\timm = get_imm(imm);\n\t\t\tif (imm != INVALID_IMM)\n\t\t\t\treturn push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);\n\t\t\tbreak;\n\t\tcase SLJIT_SHL:\n\t\tcase SLJIT_MSHL:\n\t\tcase SLJIT_LSHR:\n\t\tcase SLJIT_MLSHR:\n\t\tcase SLJIT_ASHR:\n\t\tcase SLJIT_MASHR:\n\t\tcase SLJIT_ROTL:\n\t\tcase SLJIT_ROTR:\n\t\t\tif (flags & ARG1_IMM)\n\t\t\t\tbreak;\n\t\t\timm &= 0x1f;\n\n\t\t\tif (imm == 0) {\n\t\t\t\tif (!(flags & SET_FLAGS))\n\t\t\t\t\treturn push_inst16(compiler, MOV | SET_REGS44(dst, reg));\n\t\t\t\tif (IS_2_LO_REGS(dst, reg))\n\t\t\t\t\treturn push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));\n\t\t\t\treturn push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));\n\t\t\t}\n\n\t\t\tswitch (flags & 0xffff) {\n\t\t\tcase SLJIT_SHL:\n\t\t\tcase SLJIT_MSHL:\n\t\t\t\tif (IS_2_LO_REGS(dst, reg))\n\t\t\t\t\treturn push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));\n\t\t\t\treturn push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));\n\t\t\tcase SLJIT_LSHR:\n\t\t\tcase SLJIT_MLSHR:\n\t\t\t\tif (IS_2_LO_REGS(dst, reg))\n\t\t\t\t\treturn push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));\n\t\t\t\treturn push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));\n\t\t\tcase SLJIT_ASHR:\n\t\t\tcase SLJIT_MASHR:\n\t\t\t\tif (IS_2_LO_REGS(dst, reg))\n\t\t\t\t\treturn push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));\n\t\t\t\treturn push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));\n\t\t\tcase SLJIT_ROTL:\n\t\t\t\timm = (imm ^ 0x1f) + 1;\n\t\t\t\tSLJIT_FALLTHROUGH\n\t\t\tdefault: /* SLJIT_ROTR */\n\t\t\t\treturn push_inst32(compiler, ROR_WI | RD4(dst) | RM4(reg) | IMM5(imm));\n\t\t\t}\n\t\tdefault:\n\t\t\tSLJIT_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tif (flags & ARG2_IMM) {\n\t\t\timm = arg2;\n\t\t\targ2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\t\tFAIL_IF(load_immediate(compiler, (sljit_s32)arg2, imm));\n\t\t} else {\n\t\t\timm = arg1;\n\t\t\targ1 = (arg2 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\t\tFAIL_IF(load_immediate(compiler, (sljit_s32)arg1, imm));\n\t\t}\n\n\t\tSLJIT_ASSERT(arg1 != arg2);\n\t}\n\n\t/* Both arguments are registers. */\n\tswitch (flags & 0xffff) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_P:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);\n\t\tif (dst == (sljit_s32)arg2)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst16(compiler, MOV | SET_REGS44(dst, arg2));\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));\n\tcase SLJIT_MOV_U16:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG2);\n\t\treturn push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2));\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG2);\n\t\tFAIL_IF(push_inst32(compiler, RBIT | RN4(arg2) | RD4(dst) | RM4(arg2)));\n\t\treturn push_inst32(compiler, CLZ | RN4(dst) | RD4(dst) | RM4(dst));\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG2);\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, REV | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, REV_W | RN4(arg2) | RD4(dst) | RM4(arg2));\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(arg1 == TMP_REG2);\n\n\t\tif (IS_2_LO_REGS(dst, arg2))\n\t\t\tFAIL_IF(push_inst16(compiler, REV16 | RD3(dst) | RN3(arg2)));\n\t\telse\n\t\t\tFAIL_IF(push_inst32(compiler, REV16_W | RN4(arg2) | RD4(dst) | RM4(arg2)));\n\n\t\tif (!(flags & REGISTER_OP))\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tflags &= 0xffff;\n\t\tif (reg_map[dst] <= 7)\n\t\t\treturn push_inst16(compiler, (flags == SLJIT_REV_U16 ? UXTH : SXTH) | RD3(dst) | RN3(dst));\n\t\treturn push_inst32(compiler, (flags == SLJIT_REV_U16 ? UXTH_W : SXTH_W) | RD4(dst) | RM4(dst));\n\tcase SLJIT_ADD:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\tif (IS_3_LO_REGS(dst, arg1, arg2))\n\t\t\treturn push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));\n\t\tif (dst == (sljit_s32)arg1 && !(flags & SET_FLAGS))\n\t\t\treturn push_inst16(compiler, ADD | SET_REGS44(dst, arg2));\n\t\treturn push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_SUB:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\tif (flags & UNUSED_RETURN) {\n\t\t\tif (IS_2_LO_REGS(arg1, arg2))\n\t\t\t\treturn push_inst16(compiler, CMP | RD3(arg1) | RN3(arg2));\n\t\t\treturn push_inst16(compiler, CMP_X | SET_REGS44(arg1, arg2));\n\t\t}\n\t\tif (IS_3_LO_REGS(dst, arg1, arg2))\n\t\t\treturn push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));\n\t\treturn push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_MUL:\n\t\tcompiler->status_flags_state = 0;\n\t\tif (!(flags & SET_FLAGS))\n\t\t\treturn push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));\n\t\treg = (dst == TMP_REG2) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(reg) | RN4(arg1) | RM4(arg2)));\n\t\t/* cmp TMP_REG2, dst asr #31. */\n\t\treturn push_inst32(compiler, CMP_W | RN4(reg) | 0x70e0 | RM4(dst));\n\tcase SLJIT_AND:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));\n\t\tif ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))\n\t\t\treturn push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));\n\t\treturn push_inst32(compiler, ((flags & UNUSED_RETURN) ? TST_W : AND_W) | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_OR:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_XOR:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_MSHL:\n\t\treg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));\n\t\targ2 = (sljit_uw)reg;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_SHL:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_MLSHR:\n\t\treg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));\n\t\targ2 = (sljit_uw)reg;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_LSHR:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_MASHR:\n\t\treg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));\n\t\targ2 = (sljit_uw)reg;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_ASHR:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_ROTL:\n\t\treg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;\n\t\tFAIL_IF(push_inst32(compiler, RSB_WI | RD4(reg) | RN4(arg2) | 0));\n\t\targ2 = (sljit_uw)reg;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_ROTR:\n\t\tif (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))\n\t\t\treturn push_inst16(compiler, RORS | RD3(dst) | RN3(arg2));\n\t\treturn push_inst32(compiler, ROR_W | RD4(dst) | RN4(arg1) | RM4(arg2));\n\tcase SLJIT_MULADD:\n\t\tcompiler->status_flags_state = 0;\n\t\treturn push_inst32(compiler, MLA | RD4(dst) | RN4(arg1) | RM4(arg2) | RT4(dst));\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\n#define STORE\t\t0x01\n#define SIGNED\t\t0x02\n\n#define WORD_SIZE\t0x00\n#define BYTE_SIZE\t0x04\n#define HALF_SIZE\t0x08\n#define PRELOAD\t\t0x0c\n\n#define IS_WORD_SIZE(flags)\t\t(!((flags) & (BYTE_SIZE | HALF_SIZE)))\n#define ALIGN_CHECK(argw, imm, shift)\t(!((argw) & ~((imm) << (shift))))\n\n/*\n  1st letter:\n  w = word\n  b = byte\n  h = half\n\n  2nd letter:\n  s = signed\n  u = unsigned\n\n  3rd letter:\n  l = load\n  s = store\n*/\n\nstatic const sljit_ins sljit_mem16[12] = {\n/* w u l */ 0x5800 /* ldr */,\n/* w u s */ 0x5000 /* str */,\n/* w s l */ 0x5800 /* ldr */,\n/* w s s */ 0x5000 /* str */,\n\n/* b u l */ 0x5c00 /* ldrb */,\n/* b u s */ 0x5400 /* strb */,\n/* b s l */ 0x5600 /* ldrsb */,\n/* b s s */ 0x5400 /* strb */,\n\n/* h u l */ 0x5a00 /* ldrh */,\n/* h u s */ 0x5200 /* strh */,\n/* h s l */ 0x5e00 /* ldrsh */,\n/* h s s */ 0x5200 /* strh */,\n};\n\nstatic const sljit_ins sljit_mem16_imm5[12] = {\n/* w u l */ 0x6800 /* ldr imm5 */,\n/* w u s */ 0x6000 /* str imm5 */,\n/* w s l */ 0x6800 /* ldr imm5 */,\n/* w s s */ 0x6000 /* str imm5 */,\n\n/* b u l */ 0x7800 /* ldrb imm5 */,\n/* b u s */ 0x7000 /* strb imm5 */,\n/* b s l */ 0x0000 /* not allowed */,\n/* b s s */ 0x7000 /* strb imm5 */,\n\n/* h u l */ 0x8800 /* ldrh imm5 */,\n/* h u s */ 0x8000 /* strh imm5 */,\n/* h s l */ 0x0000 /* not allowed */,\n/* h s s */ 0x8000 /* strh imm5 */,\n};\n\n#define MEM_IMM8\t0xc00\n#define MEM_IMM12\t0x800000\nstatic const sljit_ins sljit_mem32[13] = {\n/* w u l */ 0xf8500000 /* ldr.w */,\n/* w u s */ 0xf8400000 /* str.w */,\n/* w s l */ 0xf8500000 /* ldr.w */,\n/* w s s */ 0xf8400000 /* str.w */,\n\n/* b u l */ 0xf8100000 /* ldrb.w */,\n/* b u s */ 0xf8000000 /* strb.w */,\n/* b s l */ 0xf9100000 /* ldrsb.w */,\n/* b s s */ 0xf8000000 /* strb.w */,\n\n/* h u l */ 0xf8300000 /* ldrh.w */,\n/* h u s */ 0xf8200000 /* strsh.w */,\n/* h s l */ 0xf9300000 /* ldrsh.w */,\n/* h s s */ 0xf8200000 /* strsh.w */,\n\n/* p u l */ 0xf8100000 /* pld */,\n};\n\n/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */\nstatic sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)\n{\n\tsljit_uw imm;\n\n\tif (value >= 0) {\n\t\tif (value <= 0xfff)\n\t\t\treturn push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));\n\t\timm = get_imm((sljit_uw)value);\n\t\tif (imm != INVALID_IMM)\n\t\t\treturn push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | imm);\n\t}\n\telse {\n\t\tvalue = -value;\n\t\tif (value <= 0xfff)\n\t\t\treturn push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));\n\t\timm = get_imm((sljit_uw)value);\n\t\tif (imm != INVALID_IMM)\n\t\t\treturn push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | imm);\n\t}\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,\n\tsljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)\n{\n\tsljit_s32 other_r;\n\tsljit_uw imm, tmp;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\tSLJIT_ASSERT((arg & REG_MASK) != tmp_reg || (arg == SLJIT_MEM1(tmp_reg) && argw >= -0xff && argw <= 0xfff));\n\n\tif (SLJIT_UNLIKELY(!(arg & REG_MASK))) {\n\t\timm = get_imm((sljit_uw)argw & ~(sljit_uw)0xfff);\n\t\tif (imm != INVALID_IMM) {\n\t\t\tFAIL_IF(push_inst32(compiler, MOV_WI | RD4(tmp_reg) | imm));\n\t\t\treturn push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg) | (argw & 0xfff));\n\t\t}\n\n\t\tFAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));\n\t\tif (IS_2_LO_REGS(reg, tmp_reg) && sljit_mem16_imm5[flags])\n\t\t\treturn push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(tmp_reg));\n\t\treturn push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg));\n\t}\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\t\tother_r = OFFS_REG(arg);\n\t\targ &= REG_MASK;\n\n\t\tif (!argw && IS_3_LO_REGS(reg, arg, other_r))\n\t\t\treturn push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r));\n\t\treturn push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | ((sljit_ins)argw << 4));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (argw > 0xfff) {\n\t\timm = get_imm((sljit_uw)(argw & ~0xfff));\n\t\tif (imm != INVALID_IMM) {\n\t\t\tpush_inst32(compiler, ADD_WI | RD4(tmp_reg) | RN4(arg) | imm);\n\t\t\targ = tmp_reg;\n\t\t\targw = argw & 0xfff;\n\t\t}\n\t}\n\telse if (argw < -0xff) {\n\t\ttmp = (sljit_uw)((-argw + 0xfff) & ~0xfff);\n\t\tSLJIT_ASSERT(tmp >= (sljit_uw)-argw);\n\t\timm = get_imm(tmp);\n\n\t\tif (imm != INVALID_IMM) {\n\t\t\tpush_inst32(compiler, SUB_WI | RD4(tmp_reg) | RN4(arg) | imm);\n\t\t\targ = tmp_reg;\n\t\t\targw += (sljit_sw)tmp;\n\n\t\t\tSLJIT_ASSERT(argw >= 0 && argw <= 0xfff);\n\t\t}\n\t}\n\n\t/* 16 bit instruction forms. */\n\tif (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {\n\t\ttmp = 3;\n\t\tif (IS_WORD_SIZE(flags)) {\n\t\t\tif (ALIGN_CHECK(argw, 0x1f, 2))\n\t\t\t\ttmp = 2;\n\t\t}\n\t\telse if (flags & BYTE_SIZE)\n\t\t{\n\t\t\tif (ALIGN_CHECK(argw, 0x1f, 0))\n\t\t\t\ttmp = 0;\n\t\t}\n\t\telse {\n\t\t\tSLJIT_ASSERT(flags & HALF_SIZE);\n\t\t\tif (ALIGN_CHECK(argw, 0x1f, 1))\n\t\t\t\ttmp = 1;\n\t\t}\n\n\t\tif (tmp < 3)\n\t\t\treturn push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | ((sljit_ins)argw << (6 - tmp)));\n\t}\n\telse if (SLJIT_UNLIKELY(arg == SLJIT_SP) && IS_WORD_SIZE(flags) && ALIGN_CHECK(argw, 0xff, 2) && reg_map[reg] <= 7) {\n\t\t/* SP based immediate. */\n\t\treturn push_inst16(compiler, STR_SP | (sljit_ins)((flags & STORE) ? 0 : 0x800) | RDN3(reg) | ((sljit_ins)argw >> 2));\n\t}\n\n\tif (argw >= 0 && argw <= 0xfff)\n\t\treturn push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | (sljit_ins)argw);\n\telse if (argw < 0 && argw >= -0xff)\n\t\treturn push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | (sljit_ins)-argw);\n\n\tSLJIT_ASSERT(arg != tmp_reg);\n\n\tFAIL_IF(load_immediate(compiler, tmp_reg, (sljit_uw)argw));\n\tif (IS_3_LO_REGS(reg, arg, tmp_reg))\n\t\treturn push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp_reg));\n\treturn push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp_reg));\n}\n\n#undef ALIGN_CHECK\n#undef IS_WORD_SIZE\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 size, i, tmp, word_arg_count;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\tsljit_uw offset;\n\tsljit_uw imm = 0;\n#ifdef __SOFTFP__\n\tsljit_u32 float_arg_count;\n#else\n\tsljit_u32 old_offset, f32_offset;\n\tsljit_u32 remap[3];\n\tsljit_u32 *remap_ptr = remap;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--)\n\t\timm |= (sljit_uw)1 << reg_map[i];\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)\n\t\timm |= (sljit_uw)1 << reg_map[i];\n\n\t/* At least two registers must be set for PUSH_W and one for PUSH instruction. */\n\tFAIL_IF((imm & 0xff00)\n\t\t? push_inst32(compiler, PUSH_W | (1 << 14) | imm)\n\t\t: push_inst16(compiler, PUSH | (1 << 8) | imm));\n\n\t/* Stack must be aligned to 8 bytes: (LR, R4) */\n\tsize = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((size & SSIZE_OF(sw)) != 0) {\n\t\t\tFAIL_IF(push_inst16(compiler, SUB_SP_I | (sizeof(sljit_sw) >> 2)));\n\t\t\tsize += SSIZE_OF(sw);\n\t\t}\n\n\t\tif (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {\n\t\t\tFAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));\n\t\t} else {\n\t\t\tif (fsaveds > 0)\n\t\t\t\tFAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));\n\t\t\tif (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)\n\t\t\t\tFAIL_IF(push_inst32(compiler, VPUSH | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));\n\t\t}\n\t}\n\n\tlocal_size = ((size + local_size + 0x7) & ~0x7) - size;\n\tcompiler->local_size = local_size;\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\targ_types = 0;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tword_arg_count = 0;\n\tsaved_arg_count = 0;\n#ifdef __SOFTFP__\n\tSLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);\n\n\toffset = 0;\n\tfloat_arg_count = 0;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset & 0x7)\n\t\t\t\toffset += sizeof(sljit_sw);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst32(compiler, VLDR_F32 | 0x800100 | RN4(SLJIT_SP)\n\t\t\t\t\t| (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tfloat_arg_count++;\n\t\t\toffset += sizeof(sljit_f64) - sizeof(sljit_sw);\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV | (float_arg_count << 16) | (offset << 10)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst32(compiler, VLDR_F32 | 0x800000 | RN4(SLJIT_SP)\n\t\t\t\t\t| (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\ttmp = SLJIT_S0 - saved_arg_count;\n\t\t\t\tsaved_arg_count++;\n\t\t\t} else if (word_arg_count - 1 != (sljit_s32)(offset >> 2))\n\t\t\t\ttmp = word_arg_count;\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw))\n\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | ((sljit_ins)reg_map[tmp] & 0x7) | (((sljit_ins)reg_map[tmp] & 0x8) << 4) | (offset << 1)));\n\t\t\telse if (reg_map[tmp] <= 7)\n\t\t\t\tFAIL_IF(push_inst16(compiler, LDR_SP | RDN3(tmp)\n\t\t\t\t\t| ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst32(compiler, LDR | RT4(tmp) | RN4(SLJIT_SP)\n\t\t\t\t\t| ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)))));\n\t\t\tbreak;\n\t\t}\n\n\t\toffset += sizeof(sljit_sw);\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tcompiler->args_size = offset;\n#else\n\toffset = SLJIT_FR0;\n\told_offset = SLJIT_FR0;\n\tf32_offset = 0;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset != old_offset)\n\t\t\t\t*remap_ptr++ = VMOV_F32 | SLJIT_32 | VD4(offset) | VM4(old_offset);\n\t\t\told_offset++;\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (f32_offset != 0) {\n\t\t\t\t*remap_ptr++ = VMOV_F32 | 0x20 | VD4(offset) | VM4(f32_offset);\n\t\t\t\tf32_offset = 0;\n\t\t\t} else {\n\t\t\t\tif (offset != old_offset)\n\t\t\t\t\t*remap_ptr++ = VMOV_F32 | VD4(offset) | VM4(old_offset);\n\t\t\t\tf32_offset = old_offset;\n\t\t\t\told_offset++;\n\t\t\t}\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0 - saved_arg_count, SLJIT_R0 + word_arg_count)));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\n\t\t\tword_arg_count++;\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tSLJIT_ASSERT((sljit_uw)(remap_ptr - remap) <= sizeof(remap));\n\n\twhile (remap_ptr > remap)\n\t\tFAIL_IF(push_inst32(compiler, *(--remap_ptr)));\n#endif\n\n#ifdef _WIN32\n\tif (local_size >= 4096) {\n\t\timm = get_imm(4096);\n\t\tSLJIT_ASSERT(imm != INVALID_IMM);\n\n\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));\n\n\t\tif (local_size < 4 * 4096) {\n\t\t\tif (local_size > 2 * 4096) {\n\t\t\t\tif (local_size > 3 * 4096) {\n\t\t\t\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));\n\t\t\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));\n\t\t\t\t}\n\n\t\t\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));\n\t\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));\n\t\t\t}\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, ((sljit_uw)local_size >> 12) - 1));\n\t\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));\n\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm));\n\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | SET_FLAGS | RD4(TMP_REG2) | RN4(TMP_REG2) | 1));\n\t\t\tFAIL_IF(push_inst16(compiler, BCC | (0x1 << 8) /* not-equal */ | (-8 & 0xff)));\n\t\t}\n\n\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));\n\t\tlocal_size &= 0xfff;\n\t}\n\n\tif (local_size >= 256) {\n\t\tSLJIT_ASSERT(local_size < 4096);\n\n\t\tif (local_size <= (127 << 2))\n\t\t\tFAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_uw)local_size >> 2)));\n\t\telse\n\t\t\tFAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, (sljit_uw)local_size));\n\n\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG1) | RN4(SLJIT_SP)));\n\t} else if (local_size > 0)\n\t\tFAIL_IF(push_inst32(compiler, LDRI | 0x500 | RT4(TMP_REG1) | RN4(SLJIT_SP) | (sljit_uw)local_size));\n#else /* !_WIN32 */\n\tif (local_size > 0) {\n\t\tif (local_size <= (127 << 2))\n\t\t\tFAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_uw)local_size >> 2)));\n\t\telse\n\t\t\tFAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, (sljit_uw)local_size));\n\t}\n#endif /* _WIN32 */\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\tsize = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n\n\t/* Doubles are saved, so alignment is unaffected. */\n\tif ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG))\n\t\tsize += SSIZE_OF(sw);\n\n\tcompiler->local_size = ((size + local_size + 0x7) & ~0x7) - size;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm)\n{\n\tsljit_uw imm2;\n\n\t/* The TMP_REG1 register must keep its value. */\n\tif (imm <= (127u << 2))\n\t\treturn push_inst16(compiler, ADD_SP_I | (imm >> 2));\n\n\tif (imm <= 0xfff)\n\t\treturn push_inst32(compiler, ADDWI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | IMM12(imm));\n\n\timm2 = get_imm(imm);\n\n\tif (imm2 != INVALID_IMM)\n\t\treturn push_inst32(compiler, ADD_WI | RD4(SLJIT_SP) | RN4(SLJIT_SP) | imm2);\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG2, imm));\n\treturn push_inst16(compiler, ADD_SP | RN3(TMP_REG2));\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size)\n{\n\tsljit_s32 local_size, fscratches, fsaveds, i, tmp;\n\tsljit_s32 restored_reg = 0;\n\tsljit_s32 lr_dst = TMP_PC;\n\tsljit_uw reg_list = 0;\n\n\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14 && frame_size <= 128);\n\n\tlocal_size = compiler->local_size;\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif (local_size > 0)\n\t\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));\n\n\t\tif (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {\n\t\t\tFAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1)));\n\t\t} else {\n\t\t\tif (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)\n\t\t\t\tFAIL_IF(push_inst32(compiler, VPOP | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1)));\n\t\t\tif (fsaveds > 0)\n\t\t\t\tFAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1)));\n\t\t}\n\n\t\tlocal_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7;\n\t}\n\n\tif (frame_size < 0) {\n\t\tlr_dst = TMP_REG2;\n\t\tframe_size = 0;\n\t} else if (frame_size > 0) {\n\t\tSLJIT_ASSERT(frame_size == 1 || (frame_size & 0x7) == 0);\n\t\tlr_dst = 0;\n\t\tframe_size &= ~0x7;\n\t}\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\ti = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\tif (tmp < i) {\n\t\trestored_reg = i;\n\t\tdo {\n\t\t\treg_list |= (sljit_uw)1 << reg_map[i];\n\t\t} while (--i > tmp);\n\t}\n\n\ti = compiler->scratches;\n\tif (i >= SLJIT_FIRST_SAVED_REG) {\n\t\trestored_reg = i;\n\t\tdo {\n\t\t\treg_list |= (sljit_uw)1 << reg_map[i];\n\t\t} while (--i >= SLJIT_FIRST_SAVED_REG);\n\t}\n\n\tif (lr_dst == TMP_REG2 && reg_list == 0) {\n\t\treg_list |= (sljit_uw)1 << reg_map[TMP_REG2];\n\t\trestored_reg = TMP_REG2;\n\t\tlr_dst = 0;\n\t}\n\n\tif (lr_dst == 0 && (reg_list & (reg_list - 1)) == 0) {\n\t\t/* The local_size does not include the saved registers. */\n\t\ttmp = 0;\n\t\tif (reg_list != 0) {\n\t\t\ttmp = 2;\n\t\t\tif (local_size <= 0xfff) {\n\t\t\t\tif (local_size == 0) {\n\t\t\t\t\tSLJIT_ASSERT(restored_reg != TMP_REG2);\n\t\t\t\t\tif (frame_size == 0)\n\t\t\t\t\t\treturn push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | 0x308);\n\t\t\t\t\tif (frame_size > 2 * SSIZE_OF(sw))\n\t\t\t\t\t\treturn push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | 0x100 | (sljit_ins)(frame_size - (2 * SSIZE_OF(sw))));\n\t\t\t\t}\n\n\t\t\t\tif (reg_map[restored_reg] <= 7 && local_size <= 0x3fc)\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, STR_SP | 0x800 | RDN3(restored_reg) | (sljit_ins)(local_size >> 2)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst32(compiler, LDR | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)local_size));\n\t\t\t\ttmp = 1;\n\t\t\t} else if (frame_size == 0) {\n\t\t\t\tframe_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw);\n\t\t\t\ttmp = 3;\n\t\t\t}\n\n\t\t\t/* Place for the saved register. */\n\t\t\tif (restored_reg != TMP_REG2)\n\t\t\t\tlocal_size += SSIZE_OF(sw);\n\t\t}\n\n\t\t/* Place for the lr register. */\n\t\tlocal_size += SSIZE_OF(sw);\n\n\t\tif (frame_size > local_size)\n\t\t\tFAIL_IF(push_inst16(compiler, SUB_SP_I | ((sljit_ins)(frame_size - local_size) >> 2)));\n\t\telse if (frame_size < local_size)\n\t\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size)));\n\n\t\tif (tmp <= 1)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (tmp == 2) {\n\t\t\tframe_size -= SSIZE_OF(sw);\n\t\t\tif (restored_reg != TMP_REG2)\n\t\t\t\tframe_size -= SSIZE_OF(sw);\n\n\t\t\tif (reg_map[restored_reg] <= 7)\n\t\t\t\treturn push_inst16(compiler, STR_SP | 0x800 | RDN3(restored_reg) | (sljit_ins)(frame_size >> 2));\n\n\t\t\treturn push_inst32(compiler, LDR | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)frame_size);\n\t\t}\n\n\t\ttmp = (restored_reg == TMP_REG2) ? 0x304 : 0x308;\n\t\treturn push_inst32(compiler, LDRI | RT4(restored_reg) | RN4(SLJIT_SP) | (sljit_ins)tmp);\n\t}\n\n\tif (local_size > 0)\n\t\tFAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size));\n\n\tif (!(reg_list & 0xff00) && lr_dst != TMP_REG2) {\n\t\tif (lr_dst == TMP_PC)\n\t\t\treg_list |= 1u << 8;\n\n\t\t/* At least one register must be set for POP instruction. */\n\t\tSLJIT_ASSERT(reg_list != 0);\n\n\t\tFAIL_IF(push_inst16(compiler, POP | reg_list));\n\t} else {\n\t\tif (lr_dst != 0)\n\t\t\treg_list |= (sljit_uw)1 << reg_map[lr_dst];\n\n\t\t/* At least two registers must be set for POP_W instruction. */\n\t\tSLJIT_ASSERT((reg_list & (reg_list - 1)) != 0);\n\n\t\tFAIL_IF(push_inst32(compiler, POP_W | reg_list));\n\t}\n\n\tif (frame_size > 0)\n\t\treturn push_inst16(compiler, SUB_SP_I | (((sljit_ins)frame_size - sizeof(sljit_sw)) >> 2));\n\n\tif (lr_dst != 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst16(compiler, ADD_SP_I | 1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\treturn emit_stack_frame_release(compiler, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\n#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef _WIN32\nextern unsigned long long __rt_udiv(unsigned int denominator, unsigned int numerator);\nextern long long __rt_sdiv(int denominator, int numerator);\n#elif defined(__GNUC__)\nextern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator);\nextern int __aeabi_idivmod(int numerator, int denominator);\n#else\n#error \"Software divmod functions are needed\"\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)\n\tsljit_uw saved_reg_list[3];\n\tsljit_uw saved_reg_count;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\t\treturn push_inst16(compiler, BKPT);\n\tcase SLJIT_NOP:\n\t\treturn push_inst16(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n\t\treturn push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)\n\t\t\t| RD4(SLJIT_R1) | RT4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));\n#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__)\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));\n\t\tFAIL_IF(push_inst32(compiler, (op == SLJIT_DIVMOD_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));\n\t\tFAIL_IF(push_inst32(compiler, MUL | RD4(SLJIT_R1) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));\n\t\treturn push_inst32(compiler, SUB_W | RD4(SLJIT_R1) | RN4(TMP_REG1) | RM4(SLJIT_R1));\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n\t\treturn push_inst32(compiler, (op == SLJIT_DIV_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));\n#else /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n\t\tSLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);\n\t\tSLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);\n\n\t\tsaved_reg_count = 0;\n\t\tif (compiler->scratches >= 4)\n\t\t\tsaved_reg_list[saved_reg_count++] = 3;\n\t\tif (compiler->scratches >= 3)\n\t\t\tsaved_reg_list[saved_reg_count++] = 2;\n\t\tif (op >= SLJIT_DIV_UW)\n\t\t\tsaved_reg_list[saved_reg_count++] = 1;\n\n\t\tif (saved_reg_count > 0) {\n\t\t\tFAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)\n\t\t\t\t\t\t| (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));\n\t\t\tif (saved_reg_count >= 2) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[1] < 8);\n\t\t\t\tFAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));\n\t\t\t}\n\t\t\tif (saved_reg_count >= 3) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[2] < 8);\n\t\t\t\tFAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));\n\t\t\t}\n\t\t}\n\n#ifdef _WIN32\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R0, SLJIT_R1)));\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R1, TMP_REG1)));\n\t\tFAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,\n\t\t\t((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__rt_udiv) : SLJIT_FUNC_ADDR(__rt_sdiv))));\n#elif defined(__GNUC__)\n\t\tFAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,\n\t\t\t((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_ADDR(__aeabi_uidivmod) : SLJIT_FUNC_ADDR(__aeabi_idivmod))));\n#else\n#error \"Software divmod functions are needed\"\n#endif\n\n\t\tif (saved_reg_count > 0) {\n\t\t\tif (saved_reg_count >= 3) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[2] < 8);\n\t\t\t\tFAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));\n\t\t\t}\n\t\t\tif (saved_reg_count >= 2) {\n\t\t\t\tSLJIT_ASSERT(saved_reg_list[1] < 8);\n\t\t\t\tFAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));\n\t\t\t}\n\t\t\treturn push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)\n\t\t\t\t\t\t| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst32(compiler, DMB_SY);\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r, flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\top = GET_OPCODE(op);\n\tif (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {\n\t\tswitch (op) {\n\t\tcase SLJIT_MOV:\n\t\tcase SLJIT_MOV_U32:\n\t\tcase SLJIT_MOV_S32:\n\t\tcase SLJIT_MOV32:\n\t\tcase SLJIT_MOV_P:\n\t\t\tflags = WORD_SIZE;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U8:\n\t\t\tflags = BYTE_SIZE;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_u8)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S8:\n\t\t\tflags = BYTE_SIZE | SIGNED;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_s8)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U16:\n\t\t\tflags = HALF_SIZE;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_u16)srcw;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S16:\n\t\t\tflags = HALF_SIZE | SIGNED;\n\t\t\tif (src == SLJIT_IMM)\n\t\t\t\tsrcw = (sljit_s16)srcw;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSLJIT_UNREACHABLE();\n\t\t\tflags = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (src == SLJIT_IMM)\n\t\t\tFAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, (sljit_uw)srcw));\n\t\telse if (src & SLJIT_MEM)\n\t\t\tFAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1));\n\t\telse if (FAST_IS_REG(dst))\n\t\t\treturn emit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);\n\t\telse\n\t\t\tdst_r = src;\n\n\t\tif (!(dst & SLJIT_MEM))\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG1);\n\t}\n\n\tSLJIT_COMPILE_ASSERT(WORD_SIZE == 0, word_size_must_be_0);\n\tflags = WORD_SIZE;\n\n\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {\n\t\tif (!(dst & SLJIT_MEM) && (!(src & SLJIT_MEM) || op == SLJIT_REV_S16))\n\t\t\top |= REGISTER_OP;\n\t\tflags |= HALF_SIZE;\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, flags, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\temit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);\n\n\tif (SLJIT_UNLIKELY(dst & SLJIT_MEM))\n\t\treturn emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_reg, src2_tmp_reg, flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tdst_reg = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tflags = HAS_FLAGS(op) ? SET_FLAGS : 0;\n\n\tif (dst == TMP_REG1)\n\t\tflags |= UNUSED_RETURN;\n\n\tif (src2 == SLJIT_IMM)\n\t\tflags |= ARG2_IMM;\n\telse if (src2 & SLJIT_MEM) {\n\t\tsrc2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;\n\t\temit_op_mem(compiler, WORD_SIZE, src2_tmp_reg, src2, src2w, TMP_REG1);\n\t\tsrc2w = src2_tmp_reg;\n\t} else\n\t\tsrc2w = src2;\n\n\tif (src1 == SLJIT_IMM)\n\t\tflags |= ARG1_IMM;\n\telse if (src1 & SLJIT_MEM) {\n\t\temit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1);\n\t\tsrc1w = TMP_REG1;\n\t} else\n\t\tsrc1w = src1;\n\n\temit_op_imm(compiler, flags | GET_OPCODE(op), dst_reg, (sljit_uw)src1w, (sljit_uw)src2w);\n\n\tif (!(dst & SLJIT_MEM))\n\t\treturn SLJIT_SUCCESS;\n\treturn emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_left;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\top = GET_OPCODE(op);\n\tis_left = (op == SLJIT_SHL || op == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= 0x1f;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (IS_2_LO_REGS(dst_reg, src1_reg))\n\t\t\tFAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(dst_reg) | RN3(src1_reg) | ((sljit_ins)src3w << 6)));\n\t\telse\n\t\t\tFAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(dst_reg) | RM4(src1_reg) | IMM5(src3w)));\n\n\t\tsrc3w = (src3w ^ 0x1f) + 1;\n\t\treturn push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(src2_reg) | (is_left ? 0x10 : 0x0) | IMM5(src3w));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) {\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src3) | 0x1f));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (dst_reg == src1_reg && IS_2_LO_REGS(dst_reg, src3))\n\t\tFAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(dst_reg) | RN3(src3)));\n\telse\n\t\tFAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(dst_reg) | RN4(src1_reg) | RM4(src3)));\n\n\tFAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src2_reg) | (1 << 6)));\n\tFAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src3) | 0x1f));\n\tFAIL_IF(push_inst32(compiler, (is_left ? LSR_W : LSL_W) | RD4(TMP_REG1) | RN4(TMP_REG1) | RM4(TMP_REG2)));\n\treturn push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= 0x1f;\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, tmp_r, src2, src2w, tmp_r));\n\t\tsrc2 = tmp_r;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tFAIL_IF(push_inst32(compiler, ADD_W | RD4(dst_r) | RN4(src1) | RM4(src2) | ((sljit_ins)(shift_arg & 0x3) << 6) | ((sljit_ins)(shift_arg & 0x1c) << 10)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14);\n\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (src != TMP_REG2)\n\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));\n\n\t\treturn push_inst16(compiler, BX | RN3(TMP_REG2));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\treturn emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 size, dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tSLJIT_ASSERT(reg_map[TMP_REG2] == 14);\n\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (dst == TMP_REG2)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));\n\t\t}\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tsize = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0);\n\n\t\tif (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\t\t/* The size of pc is not added above. */\n\t\t\tif ((size & SSIZE_OF(sw)) == 0)\n\t\t\t\tsize += SSIZE_OF(sw);\n\n\t\t\tsize += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64);\n\t\t}\n\n\t\tSLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0);\n\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64)\n\t\treturn freg_map[reg];\n\n\tif (type == SLJIT_SIMD_REG_128)\n\t\treturn freg_map[reg] & ~0x1;\n\n\treturn -1;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\tif (size == 2)\n\t\treturn push_inst16(compiler, *(sljit_u16*)instruction);\n\treturn push_inst32(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define FPU_LOAD (1 << 20)\n\nstatic sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_uw imm;\n\tsljit_ins inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD));\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\t/* Fast loads and stores. */\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\tFAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | (((sljit_uw)argw & 0x3) << 6)));\n\t\targ = SLJIT_MEM | TMP_REG1;\n\t\targw = 0;\n\t}\n\n\tif ((arg & REG_MASK) && (argw & 0x3) == 0) {\n\t\tif (!(argw & ~0x3fc))\n\t\t\treturn push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)argw >> 2));\n\t\tif (!(-argw & ~0x3fc))\n\t\t\treturn push_inst32(compiler, inst | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)-argw >> 2));\n\t}\n\n\tif (arg & REG_MASK) {\n\t\tif (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\treturn push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg));\n\t\t}\n\n\t\timm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc);\n\t\tif (imm != INVALID_IMM) {\n\t\t\tFAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));\n\t\t\treturn push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2));\n\t\t}\n\n\t\timm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc);\n\t\tif (imm != INVALID_IMM) {\n\t\t\targw = -argw;\n\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));\n\t\t\treturn push_inst32(compiler, inst | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2));\n\t\t}\n\t}\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));\n\tif (arg & REG_MASK)\n\t\tFAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, (arg & REG_MASK))));\n\treturn push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\top ^= SLJIT_32;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src, srcw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | VD4(TMP_FREG1) | VM4(src)));\n\n\tif (FAST_IS_REG(dst))\n\t\treturn push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | VN4(TMP_FREG1));\n\n\t/* Store the integer value from a VFP register. */\n\treturn emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);\n}\n\nstatic sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (FAST_IS_REG(src))\n\t\tFAIL_IF(push_inst32(compiler, VMOV | RT4(src) | VN4(TMP_FREG1)));\n\telse if (src & SLJIT_MEM) {\n\t\t/* Load the integer value into a VFP register. */\n\t\tFAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));\n\t}\n\telse {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));\n\t\tFAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | VN4(TMP_FREG1)));\n\t}\n\n\tFAIL_IF(push_inst32(compiler, ins | VD4(dst_r) | VM4(TMP_FREG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\top ^= SLJIT_32;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | VD4(src1) | VM4(src2)));\n\tFAIL_IF(push_inst32(compiler, VMRS));\n\n\tif (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst16(compiler, IT | (0x6 << 4) | 0x8));\n\treturn push_inst16(compiler, CMP /* Rm, Rn = r0 */);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src)));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\tFAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src)));\n\t\top ^= SLJIT_32;\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_fop_mem(compiler, (op & SLJIT_32), dst_r, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2)));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2)));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2)));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2)));\n\t\tbreak;\n\tcase SLJIT_COPYSIGN_F64:\n\t\tFAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(src2) | RT4(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0)));\n\t\tFAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src1)));\n\t\tFAIL_IF(push_inst32(compiler, CMPI_W | RN4(TMP_REG1) | 0));\n\t\tFAIL_IF(push_inst16(compiler, IT | (0xb << 4) | 0x8));\n\t\treturn push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(dst_r));\n\t}\n\n\tif (!(dst & SLJIT_MEM))\n\t\treturn SLJIT_SUCCESS;\n\treturn emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n#if defined(__ARM_NEON) && __ARM_NEON\n\tsljit_u32 exp;\n\tsljit_ins ins;\n#endif /* NEON */\n\tunion {\n\t\tsljit_u32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n#if defined(__ARM_NEON) && __ARM_NEON\n\tif ((u.imm << (32 - 19)) == 0) {\n\t\texp = (u.imm >> (23 + 2)) & 0x3f;\n\n\t\tif (exp == 0x20 || exp == 0x1f) {\n\t\t\tins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f);\n\t\t\treturn push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf));\n\t\t}\n\t}\n#endif /* NEON */\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\treturn push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n#if defined(__ARM_NEON) && __ARM_NEON\n\tsljit_u32 exp;\n\tsljit_ins ins;\n#endif /* NEON */\n\tunion {\n\t\tsljit_u32 imm[2];\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n#if defined(__ARM_NEON) && __ARM_NEON\n\tif (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) {\n\t\texp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff;\n\n\t\tif (exp == 0x100 || exp == 0xff) {\n\t\t\tins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f);\n\t\t\treturn push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf));\n\t\t}\n\t}\n#endif /* NEON */\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0]));\n\tif (u.imm[0] == u.imm[1])\n\t\treturn push_inst32(compiler, VMOV2 | RN4(TMP_REG1) | RT4(TMP_REG1) | VM4(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1]));\n\treturn push_inst32(compiler, VMOV2 | RN4(TMP_REG2) | RT4(TMP_REG1) | VM4(freg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_s32 reg2;\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\n\t\tinst = VMOV2 | RN4(reg) | RT4(reg2) | VM4(freg);\n\t} else {\n\t\tinst = VMOV | VN4(freg) | RT4(reg);\n\n\t\tif (!(op & SLJIT_32))\n\t\t\tinst |= 1 << 7;\n\t}\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_FROM_F64)\n\t\tinst |= 1 << 20;\n\n\treturn push_inst32(compiler, inst);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn 0x0;\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 0x1;\n\n\tcase SLJIT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x2;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_LESS:\n\t\treturn 0x3;\n\n\tcase SLJIT_NOT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)\n\t\t\treturn 0x3;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_GREATER_EQUAL:\n\t\treturn 0x2;\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn 0x8;\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn 0x9;\n\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn 0xb;\n\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\treturn 0xa;\n\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\treturn 0xc;\n\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn 0xd;\n\n\tcase SLJIT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x1;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_UNORDERED:\n\t\treturn 0x6;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\tif (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))\n\t\t\treturn 0x0;\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ORDERED:\n\t\treturn 0x7;\n\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\treturn 0x4;\n\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\treturn 0x5;\n\n\tdefault: /* SLJIT_JUMP */\n\t\tSLJIT_UNREACHABLE();\n\t\treturn 0xe;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_2) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);\n\n\t\tfor (i = (mask >> 1); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst16(compiler, NOP));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 1) >> 1; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst16(compiler, NOP));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins cc;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tif (type < SLJIT_JUMP) {\n\t\tjump->flags |= IS_COND;\n\t\tcc = get_cc(compiler, type);\n\t\tjump->flags |= cc << 8;\n\t\tPTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t}\n\n\tjump->addr = compiler->size;\n\tif (type <= SLJIT_JUMP)\n\t\tPTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));\n\telse {\n\t\tjump->flags |= IS_BL;\n\t\tPTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));\n\t}\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\n#ifdef __SOFTFP__\n\nstatic sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src, sljit_u32 *extra_space)\n{\n\tsljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;\n\tsljit_u32 offset = 0;\n\tsljit_u32 word_arg_offset = 0;\n\tsljit_u32 float_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_u32 src_offset = 4 * sizeof(sljit_sw);\n\tsljit_u8 offsets[4];\n\tsljit_u8 *offset_ptr = offsets;\n\n\tif (src && FAST_IS_REG(*src))\n\t\tsrc_offset = (sljit_u32)reg_map[*src] * sizeof(sljit_sw);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset & 0x7)\n\t\t\t\toffset += sizeof(sljit_sw);\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_f64);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_f32);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*offset_ptr++ = (sljit_u8)offset;\n\t\t\toffset += sizeof(sljit_sw);\n\t\t\tword_arg_offset += sizeof(sljit_sw);\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {\n\t\t/* Keep lr register on the stack. */\n\t\tif (is_tail_call)\n\t\t\toffset += sizeof(sljit_sw);\n\n\t\toffset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_uw)0x7;\n\n\t\t*extra_space = offset;\n\n\t\tif (is_tail_call)\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset));\n\t\telse\n\t\t\tFAIL_IF(push_inst16(compiler, SUB_SP_I | (offset >> 2)));\n\t} else {\n\t\tif (is_tail_call)\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\t*extra_space = 0;\n\t}\n\n\tSLJIT_ASSERT(reg_map[TMP_REG1] == 12);\n\n\t/* Process arguments in reversed direction. */\n\twhile (types) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tfloat_arg_count--;\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tSLJIT_ASSERT((offset & 0x7) == 0);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\tif (src_offset == offset || src_offset == offset + sizeof(sljit_sw)) {\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));\n\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV2 | 0x100000 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count));\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800100 | RN4(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tfloat_arg_count--;\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\tif (src_offset == offset) {\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));\n\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (offset << 10)));\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800000 | RN4(SLJIT_SP)\n\t\t\t\t\t\t| (float_arg_count << 12) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_offset -= sizeof(sljit_sw);\n\t\t\toffset = *(--offset_ptr);\n\n\t\t\tSLJIT_ASSERT(offset >= word_arg_offset);\n\n\t\t\tif (offset != word_arg_offset) {\n\t\t\t\tif (offset < 4 * sizeof(sljit_sw)) {\n\t\t\t\t\tif (src_offset == offset) {\n\t\t\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));\n\t\t\t\t\t\t*src = TMP_REG1;\n\t\t\t\t\t}\n\t\t\t\t\telse if (src_offset == word_arg_offset) {\n\t\t\t\t\t\t*src = (sljit_s32)(1 + (offset >> 2));\n\t\t\t\t\t\tsrc_offset = offset;\n\t\t\t\t\t}\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, MOV | (offset >> 2) | (word_arg_offset << 1)));\n\t\t\t\t} else\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, STR_SP | (word_arg_offset << 6) | ((offset - 4 * sizeof(sljit_sw)) >> 2)));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)\n{\n\tif ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64)\n\t\tFAIL_IF(push_inst32(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));\n\tif ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32)\n\t\tFAIL_IF(push_inst32(compiler, VMOV | (0 << 16) | (0 << 12)));\n\n\treturn SLJIT_SUCCESS;\n}\n\n#else\n\nstatic sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)\n{\n\tsljit_u32 offset = SLJIT_FR0;\n\tsljit_u32 new_offset = SLJIT_FR0;\n\tsljit_u32 f32_offset = 0;\n\n\t/* Remove return value. */\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset != new_offset)\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(new_offset) | VM4(offset)));\n\n\t\t\tnew_offset++;\n\t\t\toffset++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (f32_offset != 0) {\n\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(f32_offset) | VM4(offset)));\n\t\t\t\tf32_offset = 0;\n\t\t\t} else {\n\t\t\t\tif (offset != new_offset)\n\t\t\t\t\tFAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(new_offset) | VM4(offset)));\n\t\t\t\tf32_offset = new_offset;\n\t\t\t\tnew_offset++;\n\t\t\t}\n\t\t\toffset++;\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n#ifdef __SOFTFP__\n\tstruct sljit_jump *jump;\n\tsljit_u32 extra_space = (sljit_u32)type;\n#endif\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n#ifdef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG) {\n\t\tPTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL, &extra_space));\n\t\tSLJIT_ASSERT((extra_space & 0x7) == 0);\n\n\t\tif ((type & SLJIT_CALL_RETURN) && extra_space == 0)\n\t\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tjump = sljit_emit_jump(compiler, type);\n\t\tPTR_FAIL_IF(jump == NULL);\n\n\t\tif (extra_space > 0) {\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\tPTR_FAIL_IF(push_inst32(compiler, LDR | RT4(TMP_REG2)\n\t\t\t\t\t| RN4(SLJIT_SP) | (extra_space - sizeof(sljit_sw))));\n\n\t\t\tPTR_FAIL_IF(push_inst16(compiler, ADD_SP_I | (extra_space >> 2)));\n\n\t\t\tif (type & SLJIT_CALL_RETURN) {\n\t\t\t\tPTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG2)));\n\t\t\t\treturn jump;\n\t\t\t}\n\t\t}\n\n\t\tSLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));\n\t\tPTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));\n\t\treturn jump;\n\t}\n#endif /* __SOFTFP__ */\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\t/* ldmia sp!, {..., lr} */\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n#ifndef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tPTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));\n#endif /* !__SOFTFP__ */\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tSLJIT_ASSERT(reg_map[TMP_REG1] != 14);\n\n\tif (src != SLJIT_IMM) {\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tSLJIT_ASSERT(reg_map[src] != 14);\n\t\t\treturn push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));\n\t\t}\n\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw, TMP_REG1));\n\t\tif (type >= SLJIT_FAST_CALL)\n\t\t\treturn push_inst16(compiler, BLX | RN3(TMP_REG1));\n\t}\n\n\t/* These jumps are converted to jump/call instructions when possible. */\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));\n\tjump->u.target = (sljit_uw)srcw;\n\n\tjump->addr = compiler->size;\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#ifdef __SOFTFP__\n\tsljit_u32 extra_space = (sljit_u32)type;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));\n\t\tsrc = TMP_REG1;\n\t}\n\n#ifdef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG) {\n\t\tFAIL_IF(softfloat_call_with_args(compiler, arg_types, &src, &extra_space));\n\t\tSLJIT_ASSERT((extra_space & 0x7) == 0);\n\n\t\tif ((type & SLJIT_CALL_RETURN) && extra_space == 0)\n\t\t\ttype = SLJIT_JUMP;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));\n\n\t\tif (extra_space > 0) {\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\tFAIL_IF(push_inst32(compiler, LDR | RT4(TMP_REG2)\n\t\t\t\t\t| RN4(SLJIT_SP) | (extra_space - sizeof(sljit_sw))));\n\n\t\t\tFAIL_IF(push_inst16(compiler, ADD_SP_I | (extra_space >> 2)));\n\n\t\t\tif (type & SLJIT_CALL_RETURN)\n\t\t\t\treturn push_inst16(compiler, BX | RN3(TMP_REG2));\n\t\t}\n\n\t\tSLJIT_ASSERT(!(type & SLJIT_CALL_RETURN));\n\t\treturn softfloat_post_call_with_args(compiler, arg_types);\n\t}\n#endif /* __SOFTFP__ */\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\t/* ldmia sp!, {..., lr} */\n\t\tFAIL_IF(emit_stack_frame_release(compiler, -1));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n#ifndef __SOFTFP__\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tFAIL_IF(hardfloat_call_with_args(compiler, arg_types));\n#endif /* !__SOFTFP__ */\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\n#ifdef __SOFTFP__\n\nstatic SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n\tif (compiler->options & SLJIT_ENTER_REG_ARG) {\n\t\tif (src == SLJIT_FR0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);\n\t}\n\n\tif (FAST_IS_REG(src)) {\n\t\tif (op & SLJIT_32)\n\t\t\treturn push_inst32(compiler, VMOV | (1 << 20) | VN4(src) | RT4(SLJIT_R0));\n\t\treturn push_inst32(compiler, VMOV2 | (1 << 20) | VM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1));\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (op & SLJIT_32)\n\t\treturn sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, src, srcw);\n\treturn sljit_emit_mem(compiler, SLJIT_MOV, SLJIT_REG_PAIR(SLJIT_R0, SLJIT_R1), src, srcw);\n}\n\n#endif /* __SOFTFP__ */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 dst_r, flags = GET_ALL_FLAGS(op);\n\tsljit_ins cc;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\tcc = get_cc(compiler, type);\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (op < SLJIT_ADD) {\n\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));\n\t\tif (reg_map[dst_r] > 7) {\n\t\t\tFAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1));\n\t\t\tFAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0));\n\t\t} else {\n\t\t\t/* The movsi (immediate) instruction does not set flags in IT block. */\n\t\t\tFAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1));\n\t\t\tFAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0));\n\t\t}\n\t\tif (!(dst & SLJIT_MEM))\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2);\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));\n\n\tif (op == SLJIT_AND) {\n\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 1));\n\t\tFAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 0));\n\t}\n\telse {\n\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\tFAIL_IF(push_inst32(compiler, ((op == SLJIT_OR) ? ORRI : EORI) | RN4(dst_r) | RD4(dst_r) | 1));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2));\n\n\tif (!(flags & SLJIT_SET_Z))\n\t\treturn SLJIT_SUCCESS;\n\n\t/* The condition must always be set, even if the ORR/EORI is not executed above. */\n\treturn push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_uw cc, tmp, tmp2;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (src2_reg != dst_reg && src1 == dst_reg) {\n\t\tsrc1 = src2_reg;\n\t\tsrc1w = 0;\n\t\tsrc2_reg = dst_reg;\n\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\ttype ^= 0x1;\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG1));\n\n\t\tif (src2_reg != dst_reg) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t}\n\t} else if (dst_reg != src2_reg)\n\t\tFAIL_IF(push_inst16(compiler, MOV | SET_REGS44(dst_reg, src2_reg)));\n\n\tif ((type & SLJIT_COMPARE_SELECT))\n\t\ttype ^= 0x1;\n\tcc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));\n\n\tif (src1 == SLJIT_IMM && (type & SLJIT_COMPARE_SELECT)) {\n\t\ttmp = (sljit_uw)src1w;\n\t\tif (tmp <= 0xff && reg_map[dst_reg] <= 7) {\n\t\t\tif (type & SLJIT_COMPARE_SELECT)\n\t\t\t\tFAIL_IF(push_inst16(compiler, CMPI | IMM8(tmp) | RDN3(dst_reg)));\n\t\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\t\treturn push_inst16(compiler, MOVI | IMM8(tmp) | RDN3(dst_reg));\n\t\t}\n\n\t\ttmp = get_imm((sljit_uw)src1w);\n\t\tif (tmp != INVALID_IMM) {\n\t\t\tif (type & SLJIT_COMPARE_SELECT)\n\t\t\t\tFAIL_IF(push_inst32(compiler, CMPI_W | RN4(dst_reg) | tmp));\n\t\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\t\treturn push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp);\n\t\t}\n\n\t\ttmp = get_imm(~(sljit_uw)src1w);\n\t\tif (tmp != INVALID_IMM && (type & SLJIT_COMPARE_SELECT)) {\n\t\t\ttmp2 = get_imm(NEGATE(src1w));\n\t\t\tif (tmp2 != INVALID_IMM)\n\t\t\t\tFAIL_IF(push_inst32(compiler, CMNI_W | RN4(dst_reg) | tmp2));\n\t\t\telse\n\t\t\t\ttmp = INVALID_IMM;\n\t\t}\n\n\t\tif (tmp != INVALID_IMM) {\n\t\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\t\treturn push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp);\n\t\t}\n\n\t\tif (type & SLJIT_COMPARE_SELECT) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));\n\t\t\tsrc1 = TMP_REG1;\n\t\t}\n\t}\n\n\tif (src1 != SLJIT_IMM) {\n\t\tif (type & SLJIT_COMPARE_SELECT) {\n\t\t\tif (IS_2_LO_REGS(dst_reg, src1))\n\t\t\t\tFAIL_IF(push_inst16(compiler, CMP | RD3(dst_reg) | RN3(src1)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst16(compiler, CMP_X | SET_REGS44(dst_reg, src1)));\n\t\t}\n\n\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\treturn push_inst16(compiler, MOV | SET_REGS44(dst_reg, src1));\n\t}\n\n\ttmp = (sljit_uw)src1w;\n\n\tif (tmp < 0x10000) {\n\t\t/* set low 16 bits, set hi 16 bits to 0. */\n\t\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));\n\t\treturn push_inst32(compiler, MOVW | RD4(dst_reg)\n\t\t\t| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));\n\t}\n\n\tFAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));\n\n\ttmp = (sljit_uw)src1w;\n\tFAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg)\n\t\t| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)));\n\treturn push_inst32(compiler, MOVT | RD4(dst_reg)\n\t\t| COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\ttype ^= SLJIT_32;\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src2_freg)));\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG2, src1, src1w));\n\t\tsrc1 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst16(compiler, IT | (get_cc(compiler, type & ~SLJIT_32) << 4) | 0x8));\n\treturn push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\tsljit_uw imm, tmp;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tif (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)) {\n\t\tif ((mem & REG_MASK) == 0) {\n\t\t\tif ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {\n\t\t\t\timm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff));\n\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\tmemw = (memw & 0xfff) - 0x1000;\n\t\t\t} else {\n\t\t\t\timm = get_imm((sljit_uw)(memw & ~0xfff));\n\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\tmemw &= 0xfff;\n\t\t\t}\n\n\t\t\tif (imm == INVALID_IMM) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\t\tmemw = 0;\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst32(compiler, MOV_WI | RD4(TMP_REG1) | imm));\n\n\t\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\t} else if (mem & OFFS_REG_MASK) {\n\t\t\tFAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)));\n\t\t\tmemw = 0;\n\t\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\t} else if (memw < -0xff) {\n\t\t\t/* Zero value can be included in the first case. */\n\t\t\tif ((-memw & 0xfff) <= SSIZE_OF(sw))\n\t\t\t\ttmp = (sljit_uw)((-memw + 0x7ff) & ~0x7ff);\n\t\t\telse\n\t\t\t\ttmp = (sljit_uw)((-memw + 0xfff) & ~0xfff);\n\n\t\t\tSLJIT_ASSERT(tmp >= (sljit_uw)-memw);\n\t\t\timm = get_imm(tmp);\n\n\t\t\tif (imm != INVALID_IMM) {\n\t\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));\n\t\t\t\tmemw += (sljit_sw)tmp;\n\t\t\t\tSLJIT_ASSERT(memw >= 0 && memw <= 0xfff - SSIZE_OF(sw));\n\t\t\t} else {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\t\tFAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));\n\t\t\t\tmemw = 0;\n\t\t\t}\n\n\t\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\t} else if (memw >= (0x1000 - SSIZE_OF(sw))) {\n\t\t\tif ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {\n\t\t\t\timm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff));\n\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\tmemw = (memw & 0xfff) - 0x1000;\n\t\t\t} else {\n\t\t\t\timm = get_imm((sljit_uw)(memw & ~0xfff));\n\n\t\t\t\tif (imm != INVALID_IMM)\n\t\t\t\t\tmemw &= 0xfff;\n\t\t\t}\n\n\t\t\tif (imm != INVALID_IMM) {\n\t\t\t\tSLJIT_ASSERT(memw >= -0xff && memw <= 0xfff);\n\t\t\t\tFAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));\n\t\t\t} else {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\t\tFAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));\n\t\t\t\tmemw = 0;\n\t\t\t}\n\n\t\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\t}\n\n\t\tflags = WORD_SIZE;\n\n\t\tSLJIT_ASSERT(memw <= 0xfff - SSIZE_OF(sw) && memw >= -0xff);\n\n\t\tif (type & SLJIT_MEM_STORE) {\n\t\t\tflags |= STORE;\n\t\t} else if (REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, REG_PAIR_SECOND(reg), mem, memw + SSIZE_OF(sw), TMP_REG2));\n\t\t\treturn emit_op_mem(compiler, WORD_SIZE, REG_PAIR_FIRST(reg), mem, memw, TMP_REG2);\n\t\t}\n\n\t\tFAIL_IF(emit_op_mem(compiler, flags, REG_PAIR_FIRST(reg), mem, memw, TMP_REG2));\n\t\treturn emit_op_mem(compiler, flags, REG_PAIR_SECOND(reg), mem, memw + SSIZE_OF(sw), TMP_REG2);\n\t}\n\n\tflags = 1 << 23;\n\n\tif ((mem & REG_MASK) == 0) {\n\t\ttmp = (sljit_uw)(memw & 0x7fc);\n\t\timm = get_imm((sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));\n\n\t\tif (imm == INVALID_IMM) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\tmemw = 0;\n\t\t} else {\n\t\t\tFAIL_IF(push_inst32(compiler, MOV_WI | RD4(TMP_REG1) | imm));\n\t\t\tmemw = (memw & 0x3fc) >> 2;\n\n\t\t\tif (tmp > 0x400) {\n\t\t\t\tmemw = 0x100 - memw;\n\t\t\t\tflags = 0;\n\t\t\t}\n\n\t\t\tSLJIT_ASSERT(memw >= 0 && memw <= 0xff);\n\t\t}\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t} else if (mem & OFFS_REG_MASK) {\n\t\tFAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)));\n\t\tmemw = 0;\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t} else if (memw < 0) {\n\t\tif ((-memw & ~0x3fc) == 0) {\n\t\t\tflags = 0;\n\t\t\tmemw = -memw >> 2;\n\t\t} else {\n\t\t\ttmp = (sljit_uw)(-memw & 0x7fc);\n\t\t\timm = get_imm((sljit_uw)((-memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));\n\n\t\t\tif (imm != INVALID_IMM) {\n\t\t\t\tFAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));\n\t\t\t\tmemw = (-memw & 0x3fc) >> 2;\n\n\t\t\t\tif (tmp <= 0x400)\n\t\t\t\t\tflags = 0;\n\t\t\t\telse\n\t\t\t\t\tmemw = 0x100 - memw;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\t\tFAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));\n\t\t\t\tmemw = 0;\n\t\t\t}\n\n\t\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\t}\n\t} else if ((memw & ~0x3fc) != 0) {\n\t\ttmp = (sljit_uw)(memw & 0x7fc);\n\t\timm = get_imm((sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));\n\n\t\tif (imm != INVALID_IMM) {\n\t\t\tFAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(mem & REG_MASK) | imm));\n\t\t\tmemw = (memw & 0x3fc) >> 2;\n\n\t\t\tif (tmp > 0x400) {\n\t\t\t\tmemw = 0x100 - memw;\n\t\t\t\tflags = 0;\n\t\t\t}\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\t\t\tFAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem & REG_MASK)));\n\t\t\tmemw = 0;\n\t\t}\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t} else\n\t\tmemw >>= 2;\n\n\tSLJIT_ASSERT(memw >= 0 && memw <= 0xff);\n\treturn push_inst32(compiler, ((type & SLJIT_MEM_STORE) ? STRD : LDRD) | (sljit_ins)flags | RN4(mem & REG_MASK) | RT4(REG_PAIR_FIRST(reg)) | RD4(REG_PAIR_SECOND(reg)) | (sljit_ins)memw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));\n\n\tif ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_MEM_SUPP)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (type & 0xff) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_P:\n\t\tflags = WORD_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n\t\tflags = BYTE_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_S8:\n\t\tflags = BYTE_SIZE | SIGNED;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tflags = HALF_SIZE;\n\t\tbreak;\n\tcase SLJIT_MOV_S16:\n\t\tflags = HALF_SIZE | SIGNED;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\tflags = WORD_SIZE;\n\t\tbreak;\n\t}\n\n\tif (type & SLJIT_MEM_STORE)\n\t\tflags |= STORE;\n\n\tinst = sljit_mem32[flags] | 0x900;\n\n\tif (!(type & SLJIT_MEM_POST))\n\t\tinst |= 0x400;\n\n\tif (memw >= 0)\n\t\tinst |= 0x200;\n\telse\n\t\tmemw = -memw;\n\n\treturn push_inst32(compiler, inst | RT4(reg) | RN4(mem & REG_MASK) | (sljit_ins)memw);\n}\n\nstatic sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset)\n{\n\tsljit_s32 arg = *mem;\n\tsljit_sw argw = *memw;\n\tsljit_uw imm;\n\n\t*mem = TMP_REG1;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\t*memw = 0;\n\t\treturn push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((sljit_uw)(argw & 0x3) << 6));\n\t}\n\n\targ &= REG_MASK;\n\n\tif (arg) {\n\t\tif (argw <= max_offset && argw >= -0xff) {\n\t\t\t*mem = arg;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tif (argw < 0) {\n\t\t\timm = get_imm((sljit_uw)(-argw & ~0xff));\n\n\t\t\tif (imm) {\n\t\t\t\t*memw = -(-argw & 0xff);\n\t\t\t\treturn push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg) | imm);\n\t\t\t}\n\t\t} else if ((argw & 0xfff) <= max_offset) {\n\t\t\timm = get_imm((sljit_uw)(argw & ~0xfff));\n\n\t\t\tif (imm) {\n\t\t\t\t*memw = argw & 0xfff;\n\t\t\t\treturn push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg) | imm);\n\t\t\t}\n\t\t} else {\n\t\t\timm = get_imm((sljit_uw)((argw | 0xfff) + 1));\n\n\t\t\tif (imm) {\n\t\t\t\t*memw = (argw & 0xfff) - 0x1000;\n\t\t\t\treturn push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg) | imm);\n\t\t\t}\n\t\t}\n\t}\n\n\timm = (sljit_uw)(argw & ~0xfff);\n\n\tif ((argw & 0xfff) > max_offset) {\n\t\timm += 0x1000;\n\t\t*memw = (argw & 0xfff) - 0x1000;\n\t} else\n\t\t*memw = argw & 0xfff;\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, imm));\n\n\tif (arg == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, arg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));\n\n\tif (type & SLJIT_MEM_ALIGNED_32)\n\t\treturn emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw);\n\n\tif (type & SLJIT_MEM_STORE) {\n\t\tFAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | RT4(TMP_REG2)));\n\n\t\tif (type & SLJIT_32)\n\t\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1);\n\n\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));\n\t\tmem |= SLJIT_MEM;\n\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1));\n\t\tFAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | 0x80 | RT4(TMP_REG2)));\n\t\treturn emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw + 4, TMP_REG1);\n\t}\n\n\tif (type & SLJIT_32) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));\n\t\treturn push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG2));\n\t}\n\n\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));\n\tmem |= SLJIT_MEM;\n\n\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1));\n\tFAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, mem, memw + 4, TMP_REG1));\n\treturn push_inst32(compiler, VMOV2 | VM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1));\n}\n\nstatic sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw)\n{\n\tsljit_uw imm;\n\tsljit_s32 mem = *mem_ptr;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\t*mem_ptr = TMP_REG1;\n\t\treturn push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6));\n\t}\n\n\tif (SLJIT_UNLIKELY(!(mem & REG_MASK))) {\n\t\t*mem_ptr = TMP_REG1;\n\t\treturn load_immediate(compiler, TMP_REG1, (sljit_uw)memw);\n\t}\n\n\tmem &= REG_MASK;\n\n\tif (memw == 0) {\n\t\t*mem_ptr = mem;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t*mem_ptr = TMP_REG1;\n\timm = get_imm((sljit_uw)(memw < 0 ? -memw : memw));\n\n\tif (imm != INVALID_IMM)\n\t\treturn push_inst32(compiler, ((memw < 0) ? SUB_WI : ADD_WI) | RD4(TMP_REG1) | RN4(mem) | imm);\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw));\n\treturn push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem));\n}\n\nstatic SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg)\n{\n\tfreg += freg & 0x1;\n\n\tSLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS));\n\n\tif (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)\n\t\tfreg--;\n\n\treturn freg;\n}\n\n#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (!(srcdst & SLJIT_MEM)) {\n\t\tif (reg_size == 4)\n\t\t\tsrcdst = simd_get_quad_reg_index(srcdst);\n\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = VD4(srcdst) | VN4(vreg) | VM4(vreg);\n\t\telse\n\t\t\tins = VD4(vreg) | VN4(srcdst) | VM4(srcdst);\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 6;\n\n\t\treturn push_inst32(compiler, VORR | ins);\n\t}\n\n\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\tif (elem_size > 3)\n\t\telem_size = 3;\n\n\tins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(vreg)\n\t\t| (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8));\n\n\tSLJIT_ASSERT(reg_size >= alignment);\n\n\tif (alignment == 3)\n\t\tins |= 0x10;\n\telse if (alignment >= 4)\n\t\tins |= 0x20;\n\n\treturn push_inst32(compiler, ins | RN4(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf);\n}\n\nstatic sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value)\n{\n\tsljit_ins result;\n\n\tif (elem_size > 1 && (sljit_u16)value == (value >> 16)) {\n\t\telem_size = 1;\n\t\tvalue = (sljit_u16)value;\n\t}\n\n\tif (elem_size == 1 && (sljit_u8)value == (value >> 8)) {\n\t\telem_size = 0;\n\t\tvalue = (sljit_u8)value;\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tSLJIT_ASSERT(value <= 0xff);\n\t\tresult = 0xe00;\n\t\tbreak;\n\tcase 1:\n\t\tSLJIT_ASSERT(value <= 0xffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x800;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & 0xff) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xa00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue ^= (sljit_uw)0xffff;\n\t\t\tresult = (1 << 5);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_ASSERT(value <= 0xffffffff);\n\t\tresult = 0;\n\n\t\twhile (1) {\n\t\t\tif (value <= 0xff) {\n\t\t\t\tresult |= 0x000;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff00) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0x200;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff0000) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0x400;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & ~(sljit_uw)0xff000000) == 0) {\n\t\t\t\tvalue >>= 24;\n\t\t\t\tresult |= 0x600;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) {\n\t\t\t\tvalue >>= 8;\n\t\t\t\tresult |= 0xc00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) {\n\t\t\t\tvalue >>= 16;\n\t\t\t\tresult |= 0xd00;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (result != 0)\n\t\t\t\treturn ~(sljit_ins)0;\n\n\t\t\tvalue = ~value;\n\t\t\tresult = (1 << 5);\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 21) | result;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imm;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (src == SLJIT_IMM && srcw == 0)\n\t\treturn push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(vreg));\n\n\tif (SLJIT_UNLIKELY(elem_size == 3)) {\n\t\tSLJIT_ASSERT(type & SLJIT_SIMD_FLOAT);\n\n\t\tif (src & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw));\n\t\t\tsrc = vreg;\n\t\t} else if (vreg != src)\n\t\t\tFAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)));\n\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\tif (vreg != src)\n\t\t\treturn push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\n\t\tins = (sljit_ins)(elem_size << 6);\n\n\t\tif (reg_size == 4)\n\t\t\tins |= 1 << 5;\n\n\t\treturn push_inst32(compiler, VLD1_r | ins | VD4(vreg) | RN4(src) | 0xf);\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tSLJIT_ASSERT(elem_size == 2);\n\t\tins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2));\n\n\t\tif (reg_size == 4)\n\t\t\tins |= (sljit_ins)1 << 6;\n\n\t\treturn push_inst32(compiler, VDUP_s | ins | VD4(vreg) | (sljit_ins)freg_map[src]);\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tif (elem_size < 2)\n\t\t\tsrcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\timm = simd_get_imm(elem_size, (sljit_uw)srcw);\n\n\t\tif (imm != ~(sljit_ins)0) {\n\t\t\tif (reg_size == 4)\n\t\t\t\timm |= (sljit_ins)1 << 6;\n\n\t\t\treturn push_inst32(compiler, VMOV_i | imm | VD4(vreg));\n\t\t}\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tins = 1 << 22;\n\t\tbreak;\n\tcase 1:\n\t\tins = 1 << 5;\n\t\tbreak;\n\tdefault:\n\t\tins = 0;\n\t\tbreak;\n\t}\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 21;\n\n\treturn push_inst32(compiler, VDUP | ins | VN4(vreg) | RT4(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6);\n\n\t\tif (type & SLJIT_SIMD_FLOAT) {\n\t\t\tif (elem_size == 3 && !(srcdst & SLJIT_MEM)) {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\t\t\tif (srcdst != vreg)\n\t\t\t\t\tFAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(srcdst) | VM4(srcdst)));\n\n\t\t\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\t\t\treturn push_inst32(compiler, VMOV_i | VD4(vreg));\n\t\t\t}\n\n\t\t\tif (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) {\n\t\t\t\tFAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(vreg) | VM4(vreg)));\n\t\t\t\tsrcdst = TMP_FREG2;\n\t\t\t\tsrcdstw = 0;\n\t\t\t}\n\t\t}\n\n\t\tFAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(vreg)));\n\t}\n\n\tif (reg_size == 4 && lane_index >= (0x8 >> elem_size)) {\n\t\tlane_index -= (0x8 >> elem_size);\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tif (elem_size == 3)\n\t\t\treturn emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw);\n\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\t\tlane_index = lane_index << elem_size;\n\t\tins = (sljit_ins)((elem_size << 10) | (lane_index << 5));\n\t\treturn push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(vreg) | RN4(srcdst) | 0xf);\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size == 3) {\n\t\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\t\treturn push_inst32(compiler, VORR | VD4(srcdst) | VN4(vreg) | VM4(vreg));\n\t\t\treturn push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(vreg) | VM4(srcdst));\n\t\t}\n\n\t\tif (type & SLJIT_SIMD_STORE) {\n\t\t\tif (freg_ebit_map[vreg] == 0) {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tvreg = SLJIT_F64_SECOND(vreg);\n\n\t\t\t\treturn push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(vreg));\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1)));\n\t\t\treturn push_inst32(compiler, VMOV | VN4(srcdst) | RT4(TMP_REG1));\n\t\t}\n\n\t\tFAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(srcdst) | RT4(TMP_REG1)));\n\t\treturn push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1));\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tif (elem_size < 2)\n\t\t\tsrcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw));\n\t\tsrcdst = TMP_REG1;\n\t}\n\n\tif (elem_size == 0)\n\t\tins = 0x400000;\n\telse if (elem_size == 1)\n\t\tins = 0x20;\n\telse\n\t\tins = 0;\n\n\tlane_index = lane_index << elem_size;\n\tins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5));\n\n\tif (type & SLJIT_SIMD_STORE) {\n\t\tins |= (1 << 20);\n\n\t\tif (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED))\n\t\t\tins |= (1 << 23);\n\t}\n\n\treturn push_inst32(compiler, VMOV_s | ins | VN4(vreg) | RT4(srcdst));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4) {\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\t\tsrc = simd_get_quad_reg_index(src);\n\n\t\tif (src_lane_index >= (0x8 >> elem_size)) {\n\t\t\tsrc_lane_index -= (0x8 >> elem_size);\n\t\t\tsrc += SLJIT_QUAD_OTHER_HALF(src);\n\t\t}\n\t}\n\n\tif (elem_size == 3) {\n\t\tif (vreg != src)\n\t\t\tFAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)));\n\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\n\t\tif (vreg != src)\n\t\t\treturn push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size));\n\n\tif (reg_size == 4)\n\t\tins |= (sljit_ins)1 << 6;\n\n\treturn push_inst32(compiler, VDUP_s | ins | VD4(vreg) | VM4(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_s32 dst_reg;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 4)\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\t\tif (reg_size == 4 && elem2_size - elem_size == 1)\n\t\t\tFAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(vreg) | RN4(src) | 0xf));\n\t\telse\n\t\t\tFAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(vreg) | RN4(src) | 0xf));\n\t\tsrc = vreg;\n\t} else if (reg_size == 4)\n\t\tsrc = simd_get_quad_reg_index(src);\n\n\tif (!(type & SLJIT_SIMD_FLOAT)) {\n\t\tdst_reg = (reg_size == 4) ? vreg : TMP_FREG2;\n\n\t\tdo {\n\t\t\tFAIL_IF(push_inst32(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 28))\n\t\t\t\t| ((sljit_ins)1 << (19 + elem_size)) | VD4(dst_reg) | VM4(src)));\n\t\t\tsrc = dst_reg;\n\t\t} while (++elem_size < elem2_size);\n\n\t\tif (dst_reg == TMP_FREG2)\n\t\t\treturn push_inst32(compiler, VORR | VD4(vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* No SIMD variant, must use VFP instead. */\n\tSLJIT_ASSERT(reg_size == 4);\n\n\tif (vreg == src) {\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\tFAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20));\n\t\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\t\treturn push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src));\n\t}\n\n\tFAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src)));\n\tvreg += SLJIT_QUAD_OTHER_HALF(vreg);\n\treturn push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins, imms;\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\timms = 0x243219;\n\t\tins = VSHR | (1 << 28) | (0x9 << 16);\n\t\tbreak;\n\tcase 1:\n\t\timms = (reg_size == 4) ? 0x243219 : 0x2231;\n\t\tins = VSHR | (1 << 28) | (0x11 << 16);\n\t\tbreak;\n\tcase 2:\n\t\timms = (reg_size == 4) ? 0x2231 : 0x21;\n\t\tins = VSHR | (1 << 28) | (0x21 << 16);\n\t\tbreak;\n\tdefault:\n\t\timms = 0x21;\n\t\tins = VSHR | (1 << 28) | (0x1 << 16) | (1 << 7);\n\t\tbreak;\n\t}\n\n\tif (reg_size == 4) {\n\t\tvreg = simd_get_quad_reg_index(vreg);\n\t\tins |= (sljit_ins)1 << 6;\n\t}\n\n\tSLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0);\n\tFAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(vreg)));\n\n\tif (reg_size == 4 && elem_size > 0)\n\t\tFAIL_IF(push_inst32(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD4(TMP_FREG2) | VM4(TMP_FREG2)));\n\n\tins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0;\n\n\twhile (imms >= 0x100) {\n\t\tFAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | ((imms & 0xff) << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2)));\n\t\timms >>= 8;\n\t}\n\n\tFAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | (1 << 7) | (imms << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2)));\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tFAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(dst_r) | VN4(TMP_FREG2)));\n\n\tif (reg_size == 4 && elem_size == 0) {\n\t\tSLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]);\n\t\tFAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(TMP_REG2)| VN4(TMP_FREG1)));\n\t\tFAIL_IF(push_inst32(compiler, ORR_W | RD4(dst_r) | RN4(dst_r) | RM4(TMP_REG2) | (0x2 << 12)));\n\t}\n\n\tif (dst_r == TMP_REG1)\n\t\treturn emit_op_mem(compiler, STORE | WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment;\n\tsljit_ins ins = 0, load_ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size != 3 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = VAND;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = VORR;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = VEOR;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tins = VTBL;\n\t\tbreak;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (elem_size > 3)\n\t\t\telem_size = 3;\n\n\t\tload_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8));\n\t\talignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\n\t\tSLJIT_ASSERT(reg_size >= alignment);\n\n\t\tif (alignment == 3)\n\t\t\tload_ins |= 0x10;\n\t\telse if (alignment >= 4)\n\t\t\tload_ins |= 0x20;\n\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w));\n\t\tFAIL_IF(push_inst32(compiler, load_ins | VD4(TMP_FREG2) | RN4(src2) | ((sljit_ins)elem_size) << 6 | 0xf));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tif (reg_size == 4) {\n\t\tdst_vreg = simd_get_quad_reg_index(dst_vreg);\n\t\tsrc1_vreg = simd_get_quad_reg_index(src1_vreg);\n\t\tsrc2 = simd_get_quad_reg_index(src2);\n\n\t\tif (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) {\n\t\t\tins |= (sljit_ins)1 << 8;\n\n\t\t\tFAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN4(src1_vreg) | VM4(src2)));\n\t\t\tsrc2 += SLJIT_QUAD_OTHER_HALF(src2);\n\t\t\tFAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN4(src1_vreg) | VM4(src2)));\n\n\t\t\tif (dst_vreg == src1_vreg)\n\t\t\t\treturn push_inst32(compiler, VORR | VD4(dst_vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tins |= (sljit_ins)1 << 6;\n\t}\n\n\treturn push_inst32(compiler, ins | VD4(dst_vreg) | VN4(src1_vreg) | VM4(src2));\n}\n\n#undef FPU_LOAD\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV_U8:\n\t\tins = LDREXB;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = LDREXH;\n\t\tbreak;\n\tdefault:\n\t\tins = LDREX;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst32(compiler, ins | RN4(mem_reg) | RT4(dst_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\n\t/* temp_reg == mem_reg is undefined so use another temp register */\n\tSLJIT_UNUSED_ARG(temp_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\tcase SLJIT_MOV_S16:\n\tcase SLJIT_MOV_S32:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tcase SLJIT_MOV_U8:\n\t\tins = STREXB | RM4(TMP_REG1);\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = STREXH | RM4(TMP_REG1);\n\t\tbreak;\n\tdefault:\n\t\tins = STREX | RD4(TMP_REG1);\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst32(compiler, ins | RN4(mem_reg) | RT4(src_reg)));\n\tif (op & SLJIT_SET_ATOMIC_STORED)\n\t\treturn push_inst32(compiler, CMPI_W | RN4(TMP_REG1));\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_SIZE | STORE;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (GET_OPCODE(op) == SLJIT_MOV_U8) {\n\t\tPTR_FAIL_IF(push_inst32(compiler,\n\t\t\t((init_value & 0x100) != 0 ? (MVN_WI | (~init_value & 0xff)) : (MOV_WI | (init_value & 0xff))) | RD4(dst_r)));\n\t\tmem_flags = BYTE_SIZE | STORE;\n\t} else\n\t\tPTR_FAIL_IF(emit_imm32_const(compiler, dst_r, (sljit_uw)init_value));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG2));\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, dst, dstw, TMP_REG1));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\tif (op != SLJIT_MOV_ADDR)\n\t\tjump->flags |= IS_ABS;\n\n\tPTR_FAIL_IF(push_inst16(compiler, RDN3(target_r)));\n\tcompiler->size += 3;\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(dst_r, TMP_REG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG1));\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst = (sljit_u16*)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);\n\tmodify_imm32_const(inst, new_target);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);\n\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 4);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst;\n\n\tif (GET_OPCODE(op) != SLJIT_MOV_U8) {\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n\n\tinst = (sljit_u16*)addr;\n\tSLJIT_ASSERT(inst[0] == (MOV_WI >> 16) || inst[0] == (MVN_WI >> 16));\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\n\tif ((new_constant & 0x100) != 0) {\n\t\tinst[0] = (sljit_u16)(MVN_WI >> 16);\n\t\tnew_constant = ~new_constant;\n\t} else\n\t\tinst[0] = (sljit_u16)(MOV_WI >> 16);\n\n\tinst[1] = (sljit_u16)((new_constant & 0xff) | (inst[1] & 0xf00));\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst + 1, inst + 2);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\treturn \"LOONGARCH\" SLJIT_CPUINFO;\n}\n\ntypedef sljit_u32 sljit_ins;\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_REG3\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n#define TMP_ZERO\t0\n\n/* Flags are kept in volatile registers. */\n#define EQUAL_FLAG\t(SLJIT_NUMBER_OF_REGISTERS + 5)\n#define RETURN_ADDR_REG\tTMP_REG2\n#define OTHER_FLAG\t(SLJIT_NUMBER_OF_REGISTERS + 6)\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {\n\t0, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 22, 31, 30, 29, 28, 27, 26, 25, 24, 23, 3, 13, 1, 14, 12, 15\n};\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {\n\t0, 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 31, 30, 29, 28, 27, 26, 25, 24, 8, 9\n};\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n/*\nLoongArch instructions are 32 bits wide, belonging to 9 basic instruction formats (and variants of them):\n\n| Format name  | Composition                 |\n| 2R           | Opcode + Rj + Rd            |\n| 3R           | Opcode + Rk + Rj + Rd       |\n| 4R           | Opcode + Ra + Rk + Rj + Rd  |\n| 2RI8         | Opcode + I8 + Rj + Rd       |\n| 2RI12        | Opcode + I12 + Rj + Rd      |\n| 2RI14        | Opcode + I14 + Rj + Rd      |\n| 2RI16        | Opcode + I16 + Rj + Rd      |\n| 1RI21        | Opcode + I21L + Rj + I21H   |\n| I26          | Opcode + I26L + I26H        |\n\nRd is the destination register operand, while Rj, Rk and Ra (“a” stands for “additional”) are the source register operands.\nI8/I12/I14/I16/I21/I26 are immediate operands of respective width. The longer I21 and I26 are stored in separate higher and\nlower parts in the instruction word, denoted by the “L” and “H” suffixes. */\n\n#define RD(rd) ((sljit_ins)reg_map[rd])\n#define RJ(rj) ((sljit_ins)reg_map[rj] << 5)\n#define RK(rk) ((sljit_ins)reg_map[rk] << 10)\n#define RA(ra) ((sljit_ins)reg_map[ra] << 15)\n\n#define FD(fd) ((sljit_ins)reg_map[fd])\n#define FRD(fd) ((sljit_ins)freg_map[fd])\n#define FRJ(fj) ((sljit_ins)freg_map[fj] << 5)\n#define FRK(fk) ((sljit_ins)freg_map[fk] << 10)\n#define FRA(fa) ((sljit_ins)freg_map[fa] << 15)\n\n#define IMM_V(imm) ((sljit_ins)(imm) << 10)\n#define IMM_I8(imm) (((sljit_ins)(imm)&0xff) << 10)\n#define IMM_I12(imm) (((sljit_ins)(imm)&0xfff) << 10)\n#define IMM_I14(imm) (((sljit_ins)(imm)&0xfff3) << 10)\n#define IMM_I16(imm) (((sljit_ins)(imm)&0xffff) << 10)\n#define IMM_I20(imm) (((sljit_ins)(imm)&0xffffffff) >> 12 << 5)\n#define IMM_I21(imm) ((((sljit_ins)(imm)&0xffff) << 10) | (((sljit_ins)(imm) >> 16) & 0x1f))\n#define IMM_I26(imm) ((((sljit_ins)(imm)&0xffff) << 10) | (((sljit_ins)(imm) >> 16) & 0x3ff))\n\n#define OPC_I26(opc) ((sljit_ins)(opc) << 26)\n#define OPC_1RI21(opc) ((sljit_ins)(opc) << 26)\n#define OPC_2RI16(opc) ((sljit_ins)(opc) << 26)\n#define OPC_2RI14(opc) ((sljit_ins)(opc) << 24)\n#define OPC_2RI12(opc) ((sljit_ins)(opc) << 22)\n#define OPC_2RI8(opc) ((sljit_ins)(opc) << 18)\n#define OPC_4R(opc) ((sljit_ins)(opc) << 20)\n#define OPC_3R(opc) ((sljit_ins)(opc) << 15)\n#define OPC_2R(opc) ((sljit_ins)(opc) << 10)\n#define OPC_1RI20(opc) ((sljit_ins)(opc) << 25)\n\n/* Arithmetic operation instructions */\n#define ADD_W OPC_3R(0x20)\n#define ADD_D OPC_3R(0x21)\n#define SUB_W OPC_3R(0x22)\n#define SUB_D OPC_3R(0x23)\n#define ADDI_W OPC_2RI12(0xa)\n#define ADDI_D OPC_2RI12(0xb)\n#define ANDI OPC_2RI12(0xd)\n#define ORI OPC_2RI12(0xe)\n#define XORI OPC_2RI12(0xf)\n#define ADDU16I_D OPC_2RI16(0x4)\n#define LU12I_W OPC_1RI20(0xa)\n#define LU32I_D OPC_1RI20(0xb)\n#define LU52I_D OPC_2RI12(0xc)\n#define SLT OPC_3R(0x24)\n#define SLTU OPC_3R(0x25)\n#define SLTI OPC_2RI12(0x8)\n#define SLTUI OPC_2RI12(0x9)\n#define PCADDI OPC_1RI20(0xc)\n#define PCALAU12I OPC_1RI20(0xd)\n#define PCADDU12I OPC_1RI20(0xe)\n#define PCADDU18I OPC_1RI20(0xf)\n#define NOR OPC_3R(0x28)\n#define AND OPC_3R(0x29)\n#define OR OPC_3R(0x2a)\n#define XOR OPC_3R(0x2b)\n#define ORN OPC_3R(0x2c)\n#define ANDN OPC_3R(0x2d)\n#define MUL_W OPC_3R(0x38)\n#define MULH_W OPC_3R(0x39)\n#define MULH_WU OPC_3R(0x3a)\n#define MUL_D OPC_3R(0x3b)\n#define MULH_D OPC_3R(0x3c)\n#define MULH_DU OPC_3R(0x3d)\n#define MULW_D_W OPC_3R(0x3e)\n#define MULW_D_WU OPC_3R(0x3f)\n#define DIV_W OPC_3R(0x40)\n#define MOD_W OPC_3R(0x41)\n#define DIV_WU OPC_3R(0x42)\n#define MOD_WU OPC_3R(0x43)\n#define DIV_D OPC_3R(0x44)\n#define MOD_D OPC_3R(0x45)\n#define DIV_DU OPC_3R(0x46)\n#define MOD_DU OPC_3R(0x47)\n\n/* Bit-shift instructions */\n#define SLL_W OPC_3R(0x2e)\n#define SRL_W OPC_3R(0x2f)\n#define SRA_W OPC_3R(0x30)\n#define SLL_D OPC_3R(0x31)\n#define SRL_D OPC_3R(0x32)\n#define SRA_D OPC_3R(0x33)\n#define ROTR_W OPC_3R(0x36)\n#define ROTR_D OPC_3R(0x37)\n#define SLLI_W OPC_3R(0x81)\n#define SLLI_D ((sljit_ins)(0x41) << 16)\n#define SRLI_W OPC_3R(0x89)\n#define SRLI_D ((sljit_ins)(0x45) << 16)\n#define SRAI_W OPC_3R(0x91)\n#define SRAI_D ((sljit_ins)(0x49) << 16)\n#define ROTRI_W OPC_3R(0x99)\n#define ROTRI_D ((sljit_ins)(0x4d) << 16)\n\n/* Bit-manipulation instructions */\n#define CLO_W OPC_2R(0x4)\n#define CLZ_W OPC_2R(0x5)\n#define CTO_W OPC_2R(0x6)\n#define CTZ_W OPC_2R(0x7)\n#define CLO_D OPC_2R(0x8)\n#define CLZ_D OPC_2R(0x9)\n#define CTO_D OPC_2R(0xa)\n#define CTZ_D OPC_2R(0xb)\n#define REVB_2H OPC_2R(0xc)\n#define REVB_4H OPC_2R(0xd)\n#define REVB_2W OPC_2R(0xe)\n#define REVB_D OPC_2R(0xf)\n#define REVH_2W OPC_2R(0x10)\n#define REVH_D OPC_2R(0x11)\n#define BITREV_4B OPC_2R(0x12)\n#define BITREV_8B OPC_2R(0x13)\n#define BITREV_W OPC_2R(0x14)\n#define BITREV_D OPC_2R(0x15)\n#define EXT_W_H OPC_2R(0x16)\n#define EXT_W_B OPC_2R(0x17)\n#define BSTRINS_W (0x1 << 22 | 1 << 21)\n#define BSTRPICK_W (0x1 << 22 | 1 << 21 | 1 << 15)\n#define BSTRINS_D (0x2 << 22)\n#define BSTRPICK_D (0x3 << 22)\n\n/* Branch instructions */\n#define BEQZ  OPC_1RI21(0x10)\n#define BNEZ  OPC_1RI21(0x11)\n#define JIRL  OPC_2RI16(0x13)\n#define B     OPC_I26(0x14)\n#define BL    OPC_I26(0x15)\n#define BEQ   OPC_2RI16(0x16)\n#define BNE   OPC_2RI16(0x17)\n#define BLT   OPC_2RI16(0x18)\n#define BGE   OPC_2RI16(0x19)\n#define BLTU  OPC_2RI16(0x1a)\n#define BGEU  OPC_2RI16(0x1b)\n\n/* Memory access instructions */\n#define LD_B OPC_2RI12(0xa0)\n#define LD_H OPC_2RI12(0xa1)\n#define LD_W OPC_2RI12(0xa2)\n#define LD_D OPC_2RI12(0xa3)\n\n#define ST_B OPC_2RI12(0xa4)\n#define ST_H OPC_2RI12(0xa5)\n#define ST_W OPC_2RI12(0xa6)\n#define ST_D OPC_2RI12(0xa7)\n\n#define LD_BU OPC_2RI12(0xa8)\n#define LD_HU OPC_2RI12(0xa9)\n#define LD_WU OPC_2RI12(0xaa)\n\n#define LDX_B OPC_3R(0x7000)\n#define LDX_H OPC_3R(0x7008)\n#define LDX_W OPC_3R(0x7010)\n#define LDX_D OPC_3R(0x7018)\n\n#define STX_B OPC_3R(0x7020)\n#define STX_H OPC_3R(0x7028)\n#define STX_W OPC_3R(0x7030)\n#define STX_D OPC_3R(0x7038)\n\n#define LDX_BU OPC_3R(0x7040)\n#define LDX_HU OPC_3R(0x7048)\n#define LDX_WU OPC_3R(0x7050)\n\n#define PRELD OPC_2RI12(0xab)\n\n/* Atomic memory access instructions */\n#define LL_W OPC_2RI14(0x20)\n#define SC_W OPC_2RI14(0x21)\n#define LL_D OPC_2RI14(0x22)\n#define SC_D OPC_2RI14(0x23)\n\n/* LoongArch V1.10 Instructions */\n#define AMCAS_B OPC_3R(0x70B0)\n#define AMCAS_H OPC_3R(0x70B1)\n#define AMCAS_W OPC_3R(0x70B2)\n#define AMCAS_D OPC_3R(0x70B3)\n\n/* Memory barrier instructions */\n#define DBAR OPC_3R(0x70e4)\n\n/* Other instructions */\n#define BREAK OPC_3R(0x54)\n#define DBGCALL OPC_3R(0x55)\n#define NOP ANDI\n#define SYSCALL OPC_3R(0x56)\n\n/* Basic Floating-Point Instructions */\n/* Floating-Point Arithmetic Operation Instructions */\n#define FADD_S  OPC_3R(0x201)\n#define FADD_D  OPC_3R(0x202)\n#define FSUB_S  OPC_3R(0x205)\n#define FSUB_D  OPC_3R(0x206)\n#define FMUL_S  OPC_3R(0x209)\n#define FMUL_D  OPC_3R(0x20a)\n#define FDIV_S  OPC_3R(0x20d)\n#define FDIV_D  OPC_3R(0x20e)\n#define FCMP_COND_S  OPC_4R(0xc1)\n#define FCMP_COND_D  OPC_4R(0xc2)\n#define FCOPYSIGN_S  OPC_3R(0x225)\n#define FCOPYSIGN_D  OPC_3R(0x226)\n#define FSEL  OPC_4R(0xd0)\n#define FABS_S  OPC_2R(0x4501)\n#define FABS_D  OPC_2R(0x4502)\n#define FNEG_S  OPC_2R(0x4505)\n#define FNEG_D  OPC_2R(0x4506)\n#define FMOV_S  OPC_2R(0x4525)\n#define FMOV_D  OPC_2R(0x4526)\n\n/* Floating-Point Conversion Instructions */\n#define FCVT_S_D  OPC_2R(0x4646)\n#define FCVT_D_S  OPC_2R(0x4649)\n#define FTINTRZ_W_S  OPC_2R(0x46a1)\n#define FTINTRZ_W_D  OPC_2R(0x46a2)\n#define FTINTRZ_L_S  OPC_2R(0x46a9)\n#define FTINTRZ_L_D  OPC_2R(0x46aa)\n#define FFINT_S_W  OPC_2R(0x4744)\n#define FFINT_S_L  OPC_2R(0x4746)\n#define FFINT_D_W  OPC_2R(0x4748)\n#define FFINT_D_L  OPC_2R(0x474a)\n\n/* Floating-Point Move Instructions */\n#define FMOV_S  OPC_2R(0x4525)\n#define FMOV_D  OPC_2R(0x4526)\n#define MOVGR2FR_W  OPC_2R(0x4529)\n#define MOVGR2FR_D  OPC_2R(0x452a)\n#define MOVGR2FRH_W  OPC_2R(0x452b)\n#define MOVFR2GR_S  OPC_2R(0x452d)\n#define MOVFR2GR_D  OPC_2R(0x452e)\n#define MOVFRH2GR_S  OPC_2R(0x452f)\n#define MOVGR2FCSR  OPC_2R(0x4530)\n#define MOVFCSR2GR  OPC_2R(0x4532)\n#define MOVFR2CF  OPC_2R(0x4534)\n#define MOVCF2FR  OPC_2R(0x4535)\n#define MOVGR2CF  OPC_2R(0x4536)\n#define MOVCF2GR  OPC_2R(0x4537)\n\n/* Floating-Point Branch Instructions */\n#define BCEQZ OPC_I26(0x12)\n#define BCNEZ OPC_I26(0x12)\n\n/* Floating-Point Common Memory Access Instructions */\n#define FLD_S OPC_2RI12(0xac)\n#define FLD_D OPC_2RI12(0xae)\n#define FST_S OPC_2RI12(0xad)\n#define FST_D OPC_2RI12(0xaf)\n\n#define FLDX_S OPC_3R(0x7060)\n#define FLDX_D OPC_3R(0x7068)\n#define FSTX_S OPC_3R(0x7070)\n#define FSTX_D OPC_3R(0x7078)\n\n/* Vector Instructions */\n\n/* Vector Arithmetic Instructions */\n#define VOR_V OPC_3R(0xe24d)\n#define VXOR_V OPC_3R(0xe24e)\n#define VAND_V OPC_3R(0xe24c)\n#define VMSKLTZ OPC_2R(0x1ca710)\n\n/* Vector Memory Access Instructions */\n#define VLD OPC_2RI12(0xb0)\n#define VST OPC_2RI12(0xb1)\n#define XVLD OPC_2RI12(0xb2)\n#define XVST OPC_2RI12(0xb3)\n#define VSTELM OPC_2RI8(0xc40)\n\n/* Vector Float Conversion Instructions */\n#define VFCVTL_D_S OPC_2R(0x1ca77c)\n\n/* Vector Bit Manipulate Instructions */\n#define VSLLWIL OPC_2R(0x1cc200)\n\n/* Vector Move And Shuffle Instructions */\n#define VLDREPL OPC_2R(0xc0000)\n#define VINSGR2VR OPC_2R(0x1cbac0)\n#define VPICKVE2GR_U OPC_2R(0x1cbce0)\n#define VREPLGR2VR OPC_2R(0x1ca7c0)\n#define VREPLVE OPC_3R(0xe244)\n#define VREPLVEI OPC_2R(0x1cbde0)\n#define VSHUF_B OPC_4R(0xd5)\n#define XVPERMI OPC_2RI8(0x1dfa)\n\n#define I12_MAX (0x7ff)\n#define I12_MIN (-0x800)\n#define BRANCH16_MAX (0x7fff << 2)\n#define BRANCH16_MIN (-(0x8000 << 2))\n#define BRANCH21_MAX (0xfffff << 2)\n#define BRANCH21_MIN (-(0x100000 << 2))\n#define JUMP_MAX (0x1ffffff << 2)\n#define JUMP_MIN (-(0x2000000 << 2))\n#define JIRL_MAX (0x7fff << 2)\n#define JIRL_MIN (-(0x8000 << 2))\n\n#define S32_MAX\t\t(0x7fffffffl)\n#define S32_MIN\t\t(-0x80000000l)\n#define S52_MAX\t\t(0x7ffffffffffffl)\n\n#define INST(inst, type) ((sljit_ins)((type & SLJIT_32) ? inst##_W : inst##_D))\n\n/* LoongArch CPUCFG register for feature detection */\n#define LOONGARCH_CFG2\t\t\t0x02\n#define LOONGARCH_CFG2_LAMCAS\t(1 << 28)\n\nstatic sljit_u32 cfg2_feature_list = 0;\n\n/* According to Software Development and Build Convention for LoongArch Architectures,\n+   the status of LSX and LASX extension must be checked through HWCAP */\n#include <sys/auxv.h>\n\n#define LOONGARCH_HWCAP_LSX\t\t(1 << 4)\n#define LOONGARCH_HWCAP_LASX\t(1 << 5)\n\nstatic sljit_u32 hwcap_feature_list = 0;\n\n/* Feature type */\n#define GET_CFG2 \t0\n#define GET_HWCAP\t1\n\n#define LOONGARCH_SUPPORT_AMCAS (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2))\n\nstatic SLJIT_INLINE sljit_u32 get_cpu_features(sljit_u32 feature_type)\n {\n \tif (cfg2_feature_list == 0)\n \t\t__asm__ (\"cpucfg %0, %1\" : \"+&r\"(cfg2_feature_list) : \"r\"(LOONGARCH_CFG2));\n\tif (hwcap_feature_list == 0)\n\t\thwcap_feature_list = (sljit_u32)getauxval(AT_HWCAP);\n\n\treturn feature_type ? hwcap_feature_list : cfg2_feature_list;\n }\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)\n{\n\tsljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\t*ptr = ins;\n\tcompiler->size++;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tjump->addr = jump_addr;\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (jump->flags & IS_COND) {\n\t\tdiff += SSIZE_OF(ins);\n\n\t\tif (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) {\n\t\t\tcode_ptr--;\n\t\t\tcode_ptr[0] = (code_ptr[0] & 0xfc0003ff) ^ 0x4000000;\n\t\t\tjump->flags |= PATCH_B;\n\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\treturn code_ptr;\n\t\t}\n\n\t\tdiff -= SSIZE_OF(ins);\n\t}\n\n\tif (diff >= JUMP_MIN && diff <= JUMP_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tcode_ptr[-1] |= (sljit_ins)IMM_I16(2);\n\t\t}\n\n\t\tjump->flags |= PATCH_J;\n\t\treturn code_ptr;\n\t}\n\n\tif (diff >= S32_MIN && diff <= S32_MAX) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] |= (sljit_ins)IMM_I16(3);\n\n\t\tjump->flags |= PATCH_REL32;\n\t\tcode_ptr[1] = code_ptr[0];\n\t\treturn code_ptr + 1;\n\t}\n\n\tif (target_addr <= (sljit_uw)S32_MAX) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] |= (sljit_ins)IMM_I16(3);\n\n\t\tjump->flags |= PATCH_ABS32;\n\t\tcode_ptr[1] = code_ptr[0];\n\t\treturn code_ptr + 1;\n\t}\n\n\tif (target_addr <= S52_MAX) {\n\t\tif (jump->flags & IS_COND)\n\t\t\tcode_ptr[-1] |= (sljit_ins)IMM_I16(4);\n\n\t\tjump->flags |= PATCH_ABS52;\n\t\tcode_ptr[2] = code_ptr[0];\n\t\treturn code_ptr + 2;\n\t}\n\nexit:\n\tif (jump->flags & IS_COND)\n\t\tcode_ptr[-1] |= (sljit_ins)IMM_I16(5);\n\tcode_ptr[3] = code_ptr[0];\n\treturn code_ptr + 3;\n}\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT));\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse {\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t}\n\n\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (diff >= S32_MIN && diff <= S32_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_REL32;\n\t\treturn 1;\n\t}\n\n\tif (addr <= S32_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS32;\n\t\treturn 1;\n\t}\n\n\tif (addr <= S52_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)2 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS52;\n\t\treturn 2;\n\t}\n\n\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));\n\treturn 3;\n}\n\nstatic SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_uw flags = jump->flags;\n\tsljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\tsljit_ins *ins = (sljit_ins*)jump->addr;\n\tsljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (flags & PATCH_REL32) {\n\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);\n\n\t\tSLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);\n\n\t\tif ((addr & 0x800) != 0)\n\t\t\taddr += 0x1000;\n\n\t\tins[0] = PCADDU12I | RD(reg) | IMM_I20(addr);\n\n\t\tif (!(flags & JUMP_MOV_ADDR)) {\n\t\t\tSLJIT_ASSERT((ins[1] & OPC_2RI16(0x3f)) == JIRL);\n\t\t\tins[1] = (ins[1] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I16((addr & 0xfff) >> 2);\n\t\t} else\n\t\t\tins[1] = ADDI_D | RD(reg) | RJ(reg) | IMM_I12(addr);\n\t\treturn;\n\t}\n\n\tif (flags & PATCH_ABS32) {\n\t\tSLJIT_ASSERT(addr <= S32_MAX);\n\t\tins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);\n\t} else if (flags & PATCH_ABS52) {\n\t\tins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);\n\t\tins[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);\n\t\tins += 1;\n\t} else {\n\t\tins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);\n\t\tins[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);\n\t\tins[2] = LU52I_D | RD(reg) | RJ(reg) | IMM_I12(addr >> 52);\n\t\tins += 2;\n\t}\n\n\tif (!(flags & JUMP_MOV_ADDR)) {\n\t\tSLJIT_ASSERT((ins[1] & OPC_2RI16(0x3f)) == JIRL);\n\t\tins[1] = (ins[1] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I16((addr & 0xfff) >> 2);\n\t} else\n\t\tins[1] = ORI | RD(reg) | RJ(reg) | IMM_I12(addr);\n}\n\nstatic SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE;\n\n\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\tif (jump->flags & JUMP_ADDR) {\n\t\t\t\t\tif (jump->u.target <= S32_MAX)\n\t\t\t\t\t\t\ttotal_size = 2;\n\t\t\t\t\telse if (jump->u.target <= S52_MAX)\n\t\t\t\t\t\t\ttotal_size = 3;\n\t\t\t\t} else {\n\t\t\t\t\t/* Unit size: instruction. */\n\t\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH16_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH16_MIN / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 0;\n\t\t\t\t\telse if (diff >= (JUMP_MIN / SSIZE_OF(ins)) && diff <= (JUMP_MAX / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 1;\n\t\t\t\t\telse if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsize_reduce += JUMP_MAX_SIZE - total_size;\n\t\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n\t\t} else {\n\t\t\ttotal_size = 3;\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\t/* Real size minus 1. Unit size: instruction. */\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))\n\t\t\t\t\ttotal_size = 1;\n\t\t\t} else if (jump->u.target < S32_MAX)\n\t\t\t\ttotal_size = 1;\n\t\t\telse if (jump->u.target <= S52_MAX)\n\t\t\t\ttotal_size = 2;\n\n\t\t\tsize_reduce += 3 - total_size;\n\t\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n\t\t}\n\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *code;\n\tsljit_ins *code_ptr;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_uw word_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\tsljit_uw addr;\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n\tcode = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\tword_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 2);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == word_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= word_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= word_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= word_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\tword_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tSLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\taddr = (sljit_uw)code_ptr;\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tjump->addr = addr;\n\t\t\t\t\t}\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\tword_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == word_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)code_ptr;\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tdo {\n\t\t\tif (!(jump->flags & (PATCH_B | PATCH_J)) || (jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\tload_addr_to_reg(jump, executable_offset);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\taddr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\t\t\tbuf_ptr = (sljit_ins *)jump->addr;\n\t\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);\n\n\t\t\tif (jump->flags & PATCH_B) {\n\t\t\t\tSLJIT_ASSERT((sljit_sw)addr >= BRANCH16_MIN && (sljit_sw)addr <= BRANCH16_MAX);\n\t\t\t\tbuf_ptr[0] |= (sljit_ins)IMM_I16(addr >> 2);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tSLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);\n\t\t\tif (jump->flags & IS_CALL)\n\t\t\t\tbuf_ptr[0] = BL | (sljit_ins)IMM_I26(addr >> 2);\n\t\t\telse\n\t\t\t\tbuf_ptr[0] = B | (sljit_ins)IMM_I26(addr >> 2);\n\t\t} while (0);\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);\n\n\tcode = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type)\n\t{\n\tcase SLJIT_HAS_FPU:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif\n\n\tcase SLJIT_HAS_LASX:\n\t\treturn (LOONGARCH_HWCAP_LASX & get_cpu_features(GET_HWCAP));\n\n\tcase SLJIT_HAS_SIMD:\n\t\treturn (LOONGARCH_HWCAP_LSX & get_cpu_features(GET_HWCAP));\n\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_CTZ:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tSLJIT_UNUSED_ARG(type);\n\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\n/* Creates an index in data_transfer_insts array. */\n#define LOAD_DATA\t0x01\n#define WORD_DATA\t0x00\n#define BYTE_DATA\t0x02\n#define HALF_DATA\t0x04\n#define INT_DATA\t0x06\n#define SIGNED_DATA\t0x08\n/* Separates integer and floating point registers */\n#define GPR_REG\t\t0x0f\n#define DOUBLE_DATA\t0x10\n#define SINGLE_DATA\t0x12\n\n#define MEM_MASK\t0x1f\n\n#define ARG_TEST\t0x00020\n#define ALT_KEEP_CACHE\t0x00040\n#define CUMULATIVE_OP\t0x00080\n#define IMM_OP\t\t0x00100\n#define MOVE_OP\t\t0x00200\n#define SRC2_IMM\t0x00400\n\n#define UNUSED_DEST\t0x00800\n#define REG_DEST\t0x01000\n#define REG1_SOURCE\t0x02000\n#define REG2_SOURCE\t0x04000\n#define SLOW_SRC1\t0x08000\n#define SLOW_SRC2\t0x10000\n#define SLOW_DEST\t0x20000\n#define MEM_USE_TMP2\t0x40000\n\n#define STACK_STORE\tST_D\n#define STACK_LOAD\tLD_D\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm)\n{\n\tif (imm <= I12_MAX && imm >= I12_MIN)\n\t\treturn push_inst(compiler, ADDI_D | RD(dst_r) | RJ(TMP_ZERO) | IMM_I12(imm));\n\n\tif (imm <= 0x7fffffffl && imm >= -0x80000000l) {\n\t\tFAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));\n\t\tif (IMM_I12(imm) != 0)\n\t\t\treturn push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm));\n\t\treturn SLJIT_SUCCESS;\n\t} else if (imm <= 0x7ffffffffffffl && imm >= -0x8000000000000l) {\n\t\tFAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));\n\t\tif (IMM_I12(imm) != 0)\n\t\t\tFAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));\n\t\treturn push_inst(compiler, LU32I_D | RD(dst_r) | (sljit_ins)(((imm >> 32) & 0xfffff) << 5));\n\t}\n\tFAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));\n\tif (IMM_I12(imm) != 0)\n\t\tFAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));\n\tFAIL_IF(push_inst(compiler, LU32I_D | RD(dst_r) | (sljit_ins)(((imm >> 32) & 0xfffff) << 5)));\n\treturn push_inst(compiler, LU52I_D | RD(dst_r) | RJ(dst_r) | IMM_I12(imm >> 52));\n}\n\n#define STACK_MAX_DISTANCE (-I12_MIN)\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw);\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 i, tmp, offset;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tlocal_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\tcompiler->local_size = local_size;\n\n\tif (local_size <= STACK_MAX_DISTANCE) {\n\t\t/* Frequent case. */\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | IMM_I12(-local_size)));\n\t\toffset = local_size - SSIZE_OF(sw);\n\t\tlocal_size = 0;\n\t} else {\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | IMM_I12(STACK_MAX_DISTANCE)));\n\t\tlocal_size -= STACK_MAX_DISTANCE;\n\n\t\tif (local_size > STACK_MAX_DISTANCE)\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, local_size));\n\t\toffset = STACK_MAX_DISTANCE - SSIZE_OF(sw);\n\t}\n\n\tFAIL_IF(push_inst(compiler, STACK_STORE | RD(RETURN_ADDR_REG) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_STORE | RD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_STORE | RD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, FST_D | FRD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, FST_D | FRD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\tif (local_size > STACK_MAX_DISTANCE)\n\t\tFAIL_IF(push_inst(compiler, SUB_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | RK(TMP_REG1)));\n\telse if (local_size > 0)\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | IMM_I12(-local_size)));\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\treturn SLJIT_SUCCESS;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tsaved_arg_count = 0;\n\ttmp = SLJIT_R0;\n\n\twhile (arg_types > 0) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(SLJIT_S0 - saved_arg_count) | RJ(tmp) | IMM_I12(0)));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\t\t\ttmp++;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef STACK_MAX_DISTANCE\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tcompiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\n\treturn SLJIT_SUCCESS;\n}\n\n#define STACK_MAX_DISTANCE (-I12_MIN - 16)\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_s32 i, tmp, offset;\n\tsljit_s32 local_size = compiler->local_size;\n\n\tif (local_size > STACK_MAX_DISTANCE) {\n\t\tlocal_size -= STACK_MAX_DISTANCE;\n\n\t\tif (local_size > STACK_MAX_DISTANCE) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, local_size));\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | RK(TMP_REG2)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | IMM_I12(local_size)));\n\n\t\tlocal_size = STACK_MAX_DISTANCE;\n\t}\n\n\tSLJIT_ASSERT(local_size > 0);\n\n\toffset = local_size - SSIZE_OF(sw);\n\tif (!is_return_to)\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(RETURN_ADDR_REG) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\tfor (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\tfor (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\ttmp = SLJIT_FS0 - compiler->fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, FLD_D | FRD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\tfor (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, FLD_D | FRD(i) | RJ(SLJIT_SP) | IMM_I12(offset)));\n\t}\n\n\treturn push_inst(compiler, ADDI_D | RD(SLJIT_SP) | RJ(SLJIT_SP) | IMM_I12(local_size));\n}\n\n#undef STACK_MAX_DISTANCE\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\treturn push_inst(compiler, JIRL | RD(TMP_ZERO) | RJ(RETURN_ADDR_REG) | IMM_I12(0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(src) | IMM_I12(0)));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nstatic const sljit_ins data_transfer_insts[16 + 4] = {\n/* u w s */ ST_D /* st.d */,\n/* u w l */ LD_D /* ld.d */,\n/* u b s */ ST_B /* st.b */,\n/* u b l */ LD_BU /* ld.bu */,\n/* u h s */ ST_H /* st.h */,\n/* u h l */ LD_HU /* ld.hu */,\n/* u i s */ ST_W /* st.w */,\n/* u i l */ LD_WU /* ld.wu */,\n\n/* s w s */ ST_D /* st.d */,\n/* s w l */ LD_D /* ld.d */,\n/* s b s */ ST_B /* st.b */,\n/* s b l */ LD_B /* ld.b */,\n/* s h s */ ST_H /* st.h */,\n/* s h l */ LD_H /* ld.h */,\n/* s i s */ ST_W /* st.w */,\n/* s i l */ LD_W /* ld.w */,\n\n/* d   s */ FST_D /* fst.d */,\n/* d   l */ FLD_D /* fld.d */,\n/* s   s */ FST_S /* fst.s */,\n/* s   l */ FLD_S /* fld.s */,\n};\n\nstatic const sljit_ins data_transfer_insts_x[16 + 4] = {\n/* u w s */ STX_D /* stx.d */,\n/* u w l */ LDX_D /* ldx.d */,\n/* u b s */ STX_B /* stx.b */,\n/* u b l */ LDX_BU /* ldx.bu */,\n/* u h s */ STX_H /* stx.h */,\n/* u h l */ LDX_HU /* ldx.hu */,\n/* u i s */ STX_W /* stx.w */,\n/* u i l */ LDX_WU /* ldx.wu */,\n\n/* s w s */ STX_D /* stx.d */,\n/* s w l */ LDX_D /* ldx.d */,\n/* s b s */ STX_B /* stx.b */,\n/* s b l */ LDX_B /* ldx.b */,\n/* s h s */ STX_H /* stx.h */,\n/* s h l */ LDX_H /* ldx.h */,\n/* s i s */ STX_W /* stx.w */,\n/* s i l */ LDX_W /* ldx.w */,\n\n/* d   s */ FSTX_D /* fstx.d */,\n/* d   l */ FLDX_D /* fldx.d */,\n/* s   s */ FSTX_S /* fstx.s */,\n/* s   l */ FLDX_S /* fldx.s */,\n};\n\nstatic sljit_s32 push_mem_inst(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_ins ins;\n\tsljit_s32 base = arg & REG_MASK;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (arg & OFFS_REG_MASK) {\n\t\tsljit_s32 offs = OFFS_REG(arg);\n\n\t\tSLJIT_ASSERT(!argw);\n\t\tins = data_transfer_insts_x[flags & MEM_MASK] |\n\t\t\t  ((flags & MEM_MASK) <= GPR_REG ? RD(reg) : FRD(reg)) |\n\t\t\t  RJ(base) | RK(offs);\n\t} else {\n\t\tSLJIT_ASSERT(argw <= 0xfff && argw >= I12_MIN);\n\n\t\tins = data_transfer_insts[flags & MEM_MASK] |\n\t\t\t  ((flags & MEM_MASK) <= GPR_REG ? RD(reg) : FRD(reg)) |\n\t\t\t  RJ(base) | IMM_I12(argw);\n\t}\n\treturn push_inst(compiler, ins);\n}\n\n/* Can perform an operation using at most 1 instruction. */\nstatic sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\t/* argw == 0 (ldx/stx rd, rj, rk) can be used.\n\t * argw in [-2048, 2047] (ld/st rd, rj, imm) can be used. */\n\tif (!argw || (!(arg & OFFS_REG_MASK) && (argw <= I12_MAX && argw >= I12_MIN))) {\n\t\t/* Works for both absolute and relative addresses. */\n\t\tif (SLJIT_UNLIKELY(flags & ARG_TEST))\n\t\t\treturn 1;\n\n\t\tFAIL_IF(push_mem_inst(compiler, flags, reg, arg, argw));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#define TO_ARGW_HI(argw) (((argw) & ~0xfff) + (((argw) & 0x800) ? 0x1000 : 0))\n\n/* See getput_arg below.\n   Note: can_cache is called only for binary operators. */\nstatic sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tSLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));\n\n\tif (arg & OFFS_REG_MASK)\n\t\treturn 0;\n\n\tif (arg == next_arg) {\n\t\tif (((next_argw - argw) <= I12_MAX && (next_argw - argw) >= I12_MIN)\n\t\t\t\t|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))\n\t\t\treturn 1;\n\t\treturn 0;\n\t}\n\n\treturn 0;\n}\n\n/* Emit the necessary instructions. See can_cache above. */\nstatic sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tsljit_s32 base = arg & REG_MASK;\n\tsljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1;\n\tsljit_sw offset;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\tif (!(next_arg & SLJIT_MEM)) {\n\t\tnext_arg = 0;\n\t\tnext_argw = 0;\n\t}\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(argw))\n\t\t\tFAIL_IF(push_inst(compiler, SLLI_D | RD(TMP_REG3) | RJ(OFFS_REG(arg)) | IMM_I12(argw)));\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM2(base, TMP_REG3), 0);\n\t}\n\n\tif (compiler->cache_arg == arg && argw - compiler->cache_argw <= I12_MAX && argw - compiler->cache_argw >= I12_MIN)\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM1(TMP_REG3), argw - compiler->cache_argw);\n\n\tif (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw <= I12_MAX) && (argw - compiler->cache_argw >= I12_MIN)) {\n\t\toffset = argw - compiler->cache_argw;\n\t} else {\n\t\tsljit_sw argw_hi=TO_ARGW_HI(argw);\n\t\tcompiler->cache_arg = SLJIT_MEM;\n\n\t\tif (next_arg && next_argw - argw <= I12_MAX && next_argw - argw >= I12_MIN && argw_hi != TO_ARGW_HI(next_argw)) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG3, argw));\n\t\t\tcompiler->cache_argw = argw;\n\t\t\toffset = 0;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG3, argw_hi));\n\t\t\tcompiler->cache_argw = argw_hi;\n\t\t\toffset = argw & 0xfff;\n\t\t\targw = argw_hi;\n\t\t}\n\t}\n\n\tif (!base)\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM1(TMP_REG3), offset);\n\n\tif (arg == next_arg && next_argw - argw <= I12_MAX && next_argw - argw >= I12_MIN) {\n\t\tcompiler->cache_arg = arg;\n\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(TMP_REG3) | RJ(TMP_REG3) | RK(base)));\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM1(TMP_REG3), offset);\n\t}\n\n\tif (!offset)\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM2(base, TMP_REG3), 0);\n\n\tFAIL_IF(push_inst(compiler, ADD_D | RD(tmp_r) | RJ(TMP_REG3) | RK(base)));\n\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM1(tmp_r), offset);\n}\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_s32 base = arg & REG_MASK;\n\tsljit_s32 tmp_r = TMP_REG1;\n\n\tif (getput_arg_fast(compiler, flags, reg, arg, argw))\n\t\treturn compiler->error;\n\n\tif ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))\n\t\ttmp_r = reg;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(argw))\n\t\t\tFAIL_IF(push_inst(compiler, SLLI_D | RD(tmp_r) | RJ(OFFS_REG(arg)) | IMM_I12(argw)));\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM2(base, tmp_r), 0);\n\t} else {\n\t\tFAIL_IF(load_immediate(compiler, tmp_r, argw));\n\n\t\tif (base != 0)\n\t\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM2(base, tmp_r), 0);\n\t\treturn push_mem_inst(compiler, flags, reg, SLJIT_MEM1(tmp_r), 0);\n\t}\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)\n{\n\tif (getput_arg_fast(compiler, flags, reg, arg1, arg1w))\n\t\treturn compiler->error;\n\treturn getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);\n}\n\n#define IMM_EXTEND(v) (IMM_I12((op & SLJIT_32) ? (v) : (32 + (v))))\n\n/* andi/ori/xori are zero-extended */\n#define EMIT_LOGICAL(op_imm, op_reg) \\\n\tif (flags & SRC2_IMM) { \\\n\t\tif (op & SLJIT_SET_Z) {\\\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(EQUAL_FLAG) | RJ(TMP_ZERO) | IMM_I12(src2))); \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG))); \\\n\t\t} \\\n\t\tif (!(flags & UNUSED_DEST)) { \\\n\t\t\tif (dst == src1) { \\\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(TMP_ZERO) | IMM_I12(src2))); \\\n\t\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(dst) | RJ(src1) | RK(TMP_REG1))); \\\n\t\t\t} else { \\\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(dst) | RJ(TMP_ZERO) | IMM_I12(src2))); \\\n\t\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(dst) | RJ(src1) | RK(dst))); \\\n\t\t\t} \\\n\t\t} \\\n\t} else { \\\n\t\tif (op & SLJIT_SET_Z) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RJ(src1) | RK(src2))); \\\n\t\tif (!(flags & UNUSED_DEST)) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(dst) | RJ(src1) | RK(src2))); \\\n\t} \\\n\twhile (0)\n\n#define EMIT_SHIFT(imm, reg) \\\n\top_imm = (imm); \\\n\top_reg = (reg)\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_s32 src1, sljit_sw src2)\n{\n\tsljit_s32 is_overflow, is_carry, carry_src_r, is_handled, reg;\n\tsljit_ins op_imm, op_reg;\n\tsljit_ins word_size = ((op & SLJIT_32) ? 32 : 64);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif (dst != src2)\n\t\t\treturn push_inst(compiler, INST(ADD, op) | RD(dst) | RJ(src2) | IMM_I12(0));\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, ANDI | RD(dst) | RJ(src2) | IMM_I12(0xff));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, EXT_W_B | RD(dst) | RJ(src2));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, INST(BSTRPICK, op) | RD(dst) | RJ(src2) | (15 << 16));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, EXT_W_H | RD(dst) | RJ(src2));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, BSTRPICK_D | RD(dst) | RJ(src2) | (31 << 16));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, SLLI_W | RD(dst) | RJ(src2) | IMM_I12(0));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\treturn push_inst(compiler, INST(CLZ, op) | RD(dst) | RJ(src2));\n\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\treturn push_inst(compiler, INST(CTZ, op) | RD(dst) | RJ(src2));\n\n\tcase SLJIT_REV:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\treturn push_inst(compiler, ((op & SLJIT_32) ? REVB_2W : REVB_D) | RD(dst) | RJ(src2));\n\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tFAIL_IF(push_inst(compiler, REVB_2H | RD(dst) | RJ(src2)));\n\t\treturn push_inst(compiler, EXT_W_H | RD(dst) | RJ(dst));\n\n\tcase SLJIT_REV_U16:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tFAIL_IF(push_inst(compiler, REVB_2H | RD(dst) | RJ(src2)));\n\t\treturn push_inst(compiler, INST(BSTRPICK, op) | RD(dst) | RJ(dst) | (15 << 16));\n\n\tcase SLJIT_REV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);\n\t\tFAIL_IF(push_inst(compiler, REVB_2W | RD(dst) | RJ(src2)));\n\t\treturn push_inst(compiler, SLLI_W | RD(dst) | RJ(dst) | IMM_I12(0));\n\n\tcase SLJIT_REV_U32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);\n\t\tFAIL_IF(push_inst(compiler, REVB_2W | RD(dst) | RJ(src2)));\n\t\treturn push_inst(compiler, BSTRPICK_D | RD(dst) | RJ(dst) | (31 << 16));\n\n\tcase SLJIT_ADD:\n\t\t/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tcarry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(0)));\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(TMP_ZERO) | IMM_I12(-1)));\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG)));\n\t\t\t\t}\n\t\t\t} else if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(src2)));\n\t\t} else {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADD, op) | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\n\t\t\tif (is_overflow || carry_src_r != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src1;\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src2;\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(0)));\n\t\t\t\t\tcarry_src_r = OTHER_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADD, op) | RD(dst) | RJ(src1) | RK(src2)));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (is_overflow || carry_src_r != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(dst) | IMM_I12(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RJ(dst) | RK(carry_src_r)));\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RJ(dst) | RK(EQUAL_FLAG)));\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, INST(ADD, op) | RD(EQUAL_FLAG) | RJ(dst) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, INST(SRLI, op) | RD(TMP_REG1) | RJ(TMP_REG1) | IMM_EXTEND(31)));\n\t\treturn push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(TMP_REG1) | RK(OTHER_FLAG));\n\n\tcase SLJIT_ADDC:\n\t\tcarry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(dst) | RJ(src1) | IMM_I12(src2)));\n\t\t} else {\n\t\t\tif (carry_src_r != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src1;\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src2;\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(0)));\n\t\t\t\t\tcarry_src_r = EQUAL_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(dst) | RJ(src1) | RK(src2)));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (carry_src_r != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RJ(dst) | IMM_I12(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RJ(dst) | RK(carry_src_r)));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(dst) | RJ(dst) | RK(OTHER_FLAG)));\n\n\t\tif (carry_src_r == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\t/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */\n\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RJ(dst) | RK(OTHER_FLAG)));\n\t\t/* Set carry flag. */\n\t\treturn push_inst(compiler, OR | RD(OTHER_FLAG) | RJ(OTHER_FLAG) | RK(EQUAL_FLAG));\n\n\tcase SLJIT_SUB:\n\t\tif ((flags & SRC2_IMM) && src2 == I12_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG2) | RJ(TMP_ZERO) | IMM_I12(src2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_handled = 0;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (GET_FLAG_TYPE(op) == SLJIT_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(src2)));\n\t\t\t\tis_handled = 1;\n\t\t\t} else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(src2)));\n\t\t\t\tis_handled = 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {\n\t\t\tis_handled = 1;\n\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\treg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(reg) | RJ(TMP_ZERO) | IMM_I12(src2)));\n\t\t\t\tsrc2 = reg;\n\t\t\t\tflags &= ~SRC2_IMM;\n\t\t\t}\n\n\t\t\tswitch (GET_FLAG_TYPE(op)) {\n\t\t\tcase SLJIT_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RJ(src1) | RK(src2)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RJ(src2) | RK(src1)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RJ(src1) | RK(src2)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RJ(src2) | RK(src1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (is_handled) {\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-src2)));\n\t\t\t\tif (!(flags & UNUSED_DEST))\n\t\t\t\t\treturn push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2));\n\t\t\t} else {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\t\t\t\tif (!(flags & UNUSED_DEST))\n\t\t\t\t\treturn push_inst(compiler, INST(SUB, op) | RD(dst) | RJ(src1) | RK(src2));\n\t\t\t}\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(0)));\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(TMP_ZERO) | IMM_I12(-1)));\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG)));\n\t\t\t\t}\n\t\t\t} else if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-src2)));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2)));\n\t\t} else {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RJ(src1) | RK(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(dst) | RJ(src1) | RK(src2)));\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RJ(dst) | RK(EQUAL_FLAG)));\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(dst) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, INST(SRLI, op) | RD(TMP_REG1) | RJ(TMP_REG1) | IMM_EXTEND(31)));\n\t\treturn push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(TMP_REG1) | RK(OTHER_FLAG));\n\n\tcase SLJIT_SUBC:\n\t\tif ((flags & SRC2_IMM) && src2 == I12_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(TMP_REG2) | RJ(TMP_ZERO) | IMM_I12(src2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(src2)));\n\n\t\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2)));\n\t\t} else {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\n\t\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(dst) | RJ(src1) | RK(src2)));\n\t\t}\n\n\t\tif (is_carry)\n\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(TMP_REG1) | RJ(dst) | RK(OTHER_FLAG)));\n\n\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(dst) | RJ(dst) | RK(OTHER_FLAG)));\n\n\t\tif (!is_carry)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, OR | RD(OTHER_FLAG) | RJ(EQUAL_FLAG) | RK(TMP_REG1));\n\n\tcase SLJIT_MUL:\n\t\tSLJIT_ASSERT(!(flags & SRC2_IMM));\n\n\t\tif (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW)\n\t\t\treturn push_inst(compiler, INST(MUL, op) | RD(dst) | RJ(src1) | RK(src2));\n\n\t\tif (op & SLJIT_32) {\n\t\t\tFAIL_IF(push_inst(compiler, MUL_D | RD(OTHER_FLAG) | RJ(src1) | RK(src2)));\n\t\t\tFAIL_IF(push_inst(compiler, MUL_W | RD(dst) | RJ(src1) | RK(src2)));\n\t\t\treturn push_inst(compiler, SUB_D | RD(OTHER_FLAG) | RJ(dst) | RK(OTHER_FLAG));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, MULH_D | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\t\tFAIL_IF(push_inst(compiler, MUL_D | RD(dst) | RJ(src1) | RK(src2)));\n\t\tFAIL_IF(push_inst(compiler, SRAI_D | RD(OTHER_FLAG) | RJ(dst) | IMM_I12((63))));\n\t\treturn push_inst(compiler, SUB_D | RD(OTHER_FLAG) | RJ(EQUAL_FLAG) | RK(OTHER_FLAG));\n\n\tcase SLJIT_AND:\n\t\tEMIT_LOGICAL(ANDI, AND);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_OR:\n\t\tEMIT_LOGICAL(ORI, OR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_XOR:\n\t\tEMIT_LOGICAL(XORI, XOR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tif (op & SLJIT_32) {\n\t\t\tEMIT_SHIFT(SLLI_W, SLL_W);\n\t\t} else {\n\t\t\tEMIT_SHIFT(SLLI_D, SLL_D);\n\t\t}\n\t\tbreak;\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tif (op & SLJIT_32) {\n\t\t\tEMIT_SHIFT(SRLI_W, SRL_W);\n\t\t} else {\n\t\t\tEMIT_SHIFT(SRLI_D, SRL_D);\n\t\t}\n\t\tbreak;\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tif (op & SLJIT_32) {\n\t\t\tEMIT_SHIFT(SRAI_W, SRA_W);\n\t\t} else {\n\t\t\tEMIT_SHIFT(SRAI_D, SRA_D);\n\t\t}\n\t\tbreak;\n\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (flags & SRC2_IMM) {\n\t\t\tSLJIT_ASSERT(src2 != 0);\n\n\t\t\tif (GET_OPCODE(op) == SLJIT_ROTL)\n\t\t\t\tsrc2 = word_size - src2;\n\t\t\treturn push_inst(compiler, INST(ROTRI, op) | RD(dst) | RJ(src1) | IMM_I12(src2));\n\t\t}\n\n\t\tif (src2 == TMP_ZERO) {\n\t\t\tif (dst != src1)\n\t\t\t\treturn push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(0));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tif (GET_OPCODE(op) == SLJIT_ROTL) {\n\t\t\tFAIL_IF(push_inst(compiler, INST(SUB, op)| RD(OTHER_FLAG) | RJ(TMP_ZERO) | RK(src2)));\n\t\t\tsrc2 = OTHER_FLAG;\n\t\t}\n\t\treturn push_inst(compiler, INST(ROTR, op) | RD(dst) | RJ(src1) | RK(src2));\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (flags & SRC2_IMM) {\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(src2)));\n\n\t\tif (flags & UNUSED_DEST)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, op_imm | RD(dst) | RJ(src1) | IMM_I12(src2));\n\t}\n\n\tif (op & SLJIT_SET_Z)\n\t\tFAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));\n\n\tif (flags & UNUSED_DEST)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, op_reg | RD(dst) | RJ(src1) | RK(src2));\n}\n\n#undef IMM_EXTEND\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* arg1 goes to TMP_REG1 or src reg\n\t   arg2 goes to TMP_REG2, imm or src reg\n\t   TMP_REG3 can be used for caching\n\t   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */\n\tsljit_s32 dst_r = TMP_REG2;\n\tsljit_s32 src1_r;\n\tsljit_sw src2_r = 0;\n\tsljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;\n\n\tif (!(flags & ALT_KEEP_CACHE)) {\n\t\tcompiler->cache_arg = 0;\n\t\tcompiler->cache_argw = 0;\n\t}\n\n\tif (dst == 0) {\n\t\tSLJIT_ASSERT(HAS_FLAGS(op));\n\t\tflags |= UNUSED_DEST;\n\t\tdst = TMP_REG2;\n\t} else if (FAST_IS_REG(dst)) {\n\t\tdst_r = dst;\n\t\tflags |= REG_DEST;\n\t\tif (flags & MOVE_OP)\n\t\t\tsrc2_tmp_reg = dst_r;\n\t} else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))\n\t\tflags |= SLOW_DEST;\n\n\tif (flags & IMM_OP) {\n\t\tif (src2 == SLJIT_IMM && src2w != 0 && src2w <= I12_MAX && src2w >= I12_MIN) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src2w;\n\t\t} else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= I12_MAX && src1w >= I12_MIN) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src1w;\n\n\t\t\t/* And swap arguments. */\n\t\t\tsrc1 = src2;\n\t\t\tsrc1w = src2w;\n\t\t\tsrc2 = SLJIT_IMM;\n\t\t\t/* src2w = src2_r unneeded. */\n\t\t}\n\t}\n\n\t/* Source 1. */\n\tif (FAST_IS_REG(src1)) {\n\t\tsrc1_r = src1;\n\t\tflags |= REG1_SOURCE;\n\t} else if (src1 == SLJIT_IMM) {\n\t\tif (src1w) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\t\tsrc1_r = TMP_REG1;\n\t\t}\n\t\telse\n\t\t\tsrc1_r = TMP_ZERO;\n\t} else {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC1;\n\t\tsrc1_r = TMP_REG1;\n\t}\n\n\t/* Source 2. */\n\tif (FAST_IS_REG(src2)) {\n\t\tsrc2_r = src2;\n\t\tflags |= REG2_SOURCE;\n\t\tif ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)\n\t\t\tdst_r = (sljit_s32)src2_r;\n\t} else if (src2 == SLJIT_IMM) {\n\t\tif (!(flags & SRC2_IMM)) {\n\t\t\tif (src2w) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));\n\t\t\t\tsrc2_r = src2_tmp_reg;\n\t\t\t} else {\n\t\t\t\tsrc2_r = TMP_ZERO;\n\t\t\t\tif (flags & MOVE_OP) {\n\t\t\t\t\tif (dst & SLJIT_MEM)\n\t\t\t\t\t\tdst_r = 0;\n\t\t\t\t\telse\n\t\t\t\t\t\top = SLJIT_MOV;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, src2_tmp_reg, src2, src2w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC2;\n\n\t\tsrc2_r = src2_tmp_reg;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tSLJIT_ASSERT(src2_r == TMP_REG2);\n\t\tif ((flags & SLOW_DEST) && !can_cache(src2, src2w, src1, src1w) && can_cache(src2, src2w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA | MEM_USE_TMP2, TMP_REG2, src2, src2w, dst, dstw));\n\t\t} else {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA | ((src1_r == TMP_REG1) ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, dst, dstw));\n\n\tFAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));\n\n\tif (dst & SLJIT_MEM) {\n\t\tif (!(flags & SLOW_DEST)) {\n\t\t\tgetput_arg_fast(compiler, flags, dst_r, dst, dstw);\n\t\t\treturn compiler->error;\n\t\t}\n\t\treturn getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_BREAKPOINT:\n\t\treturn push_inst(compiler, BREAK);\n\tcase SLJIT_NOP:\n\t\treturn push_inst(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(SLJIT_R1) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, MULH_DU | RD(SLJIT_R1) | RJ(SLJIT_R0) | RK(SLJIT_R1)));\n\t\treturn push_inst(compiler, MUL_D | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(TMP_REG1));\n\tcase SLJIT_LMUL_SW:\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(SLJIT_R1) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, MULH_D | RD(SLJIT_R1) | RJ(SLJIT_R0) | RK(SLJIT_R1)));\n\t\treturn push_inst(compiler, MUL_D | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(TMP_REG1));\n\tcase SLJIT_DIVMOD_UW:\n\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(TMP_REG1) | RJ(SLJIT_R0) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32)? DIV_WU: DIV_DU) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)));\n\t\treturn push_inst(compiler, ((op & SLJIT_32)? MOD_WU: MOD_DU) | RD(SLJIT_R1) | RJ(TMP_REG1) | RK(SLJIT_R1));\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(TMP_REG1) | RJ(SLJIT_R0) | IMM_I12(0)));\n\t\tFAIL_IF(push_inst(compiler, INST(DIV, op) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)));\n\t\treturn push_inst(compiler, INST(MOD, op) | RD(SLJIT_R1) | RJ(TMP_REG1) | RK(SLJIT_R1));\n\tcase SLJIT_DIV_UW:\n\t\treturn push_inst(compiler, ((op & SLJIT_32)? DIV_WU: DIV_DU) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1));\n\tcase SLJIT_DIV_SW:\n\t\treturn push_inst(compiler, INST(DIV, op) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1));\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst(compiler, DBAR);\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (op & SLJIT_32)\n\t\tflags = INT_DATA | SIGNED_DATA;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\treturn emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n\tcase SLJIT_MOV_U32:\n\t\treturn emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);\n\n\tcase SLJIT_MOV_S32:\n\t/* Logical operators have no W variant, so sign extended input is necessary for them. */\n\tcase SLJIT_MOV32:\n\t\treturn emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);\n\n\tcase SLJIT_MOV_U8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);\n\n\tcase SLJIT_MOV_S8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);\n\n\tcase SLJIT_MOV_U16:\n\t\treturn emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);\n\n\tcase SLJIT_MOV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\tcase SLJIT_REV:\n\t\treturn emit_op(compiler, op, flags, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\treturn emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (op & SLJIT_32) {\n\t\tflags |= INT_DATA | SIGNED_DATA;\n\t\tif (src1 == SLJIT_IMM)\n\t\t\tsrc1w = (sljit_s32)src1w;\n\t\tif (src2 == SLJIT_IMM)\n\t\t\tsrc2w = (sljit_s32)src2w;\n\t}\n\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SUB:\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_MUL:\n\t\tcompiler->status_flags_state = 0;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tif (op & SLJIT_32)\n\t\t\t\tsrc2w &= 0x1f;\n\t\t\telse\n\t\t\t\tsrc2w &= 0x3f;\n\t\t}\n\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));\n\t\treturn push_inst(compiler, ADD_D | RD(dst_reg) | RJ(dst_reg) | RK(TMP_REG2));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_left;\n\tsljit_ins ins1, ins2, ins3;\n\tsljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\tsljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;\n\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= bit_length - 1;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (is_left) {\n\t\t\tins1 = INST(SLLI, op) | IMM_I12(src3w);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = INST(SRLI, op) | IMM_I12(src3w);\n\t\t} else {\n\t\t\tins1 = INST(SRLI, op) | IMM_I12(src3w);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = INST(SLLI, op) | IMM_I12(src3w);\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins1 | RD(dst_reg) | RJ(src1_reg)));\n\t\tFAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RJ(src2_reg)));\n\t\treturn push_inst(compiler, OR | RD(dst_reg) | RJ(dst_reg) | RK(TMP_REG1));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w));\n\t\tsrc3 = TMP_REG2;\n\t} else if (dst_reg == src3) {\n\t\tpush_inst(compiler, INST(ADDI, op) | RD(TMP_REG2) | RJ(src3) | IMM_I12(0));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (is_left) {\n\t\tins1 = INST(SLL, op);\n\t\tins2 = INST(SRLI, op);\n\t\tins3 = INST(SRL, op);\n\t} else {\n\t\tins1 = INST(SRL, op);\n\t\tins2 = INST(SLLI, op);\n\t\tins3 = INST(SLL, op);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins1 | RD(dst_reg) | RJ(src1_reg) | RK(src3)));\n\n\tif (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {\n\t\tFAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RJ(src2_reg) | IMM_I12(1)));\n\t\tFAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RJ(src3) | IMM_I12((sljit_ins)bit_length - 1)));\n\t\tsrc2_reg = TMP_REG1;\n\t} else\n\t\tFAIL_IF(push_inst(compiler, INST(SUB, op) | RD(TMP_REG2) | RJ(TMP_ZERO) | RK(src3)));\n\n\tFAIL_IF(push_inst(compiler, ins3 | RD(TMP_REG1) | RJ(src2_reg) | RK(TMP_REG2)));\n\treturn push_inst(compiler, OR | RD(dst_reg) | RJ(dst_reg) | RK(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));\n\t\tsrc2 = TMP_REG2;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\tFAIL_IF(push_inst(compiler, SLLI_D | RD(tmp_r) | RJ(src2) | IMM_I12(shift_arg)));\n\tFAIL_IF(push_inst(compiler, ADD_D | RD(dst_r) | RJ(src1) | RK(tmp_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, WORD_DATA, dst_r, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 base = src & REG_MASK;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (src != RETURN_ADDR_REG)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(RETURN_ADDR_REG) | RJ(src) | IMM_I12(0)));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));\n\n\t\treturn push_inst(compiler, JIRL | RD(TMP_ZERO) | RJ(RETURN_ADDR_REG) | IMM_I12(0));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\tif (SLJIT_UNLIKELY(src & OFFS_REG_MASK)) {\n\t\t\tsrcw &= 0x3;\n\t\t\tif (SLJIT_UNLIKELY(srcw))\n\t\t\t\tFAIL_IF(push_inst(compiler, SLLI_D | RD(TMP_REG1) | RJ(OFFS_REG(src)) | IMM_I12(srcw)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(TMP_REG1) | RJ(base) | RK(TMP_REG1)));\n\t\t} else {\n\t\t\tif (base && srcw <= I12_MAX && srcw >= I12_MIN)\n\t\t\t\treturn push_inst(compiler,PRELD | RJ(base) | IMM_I12(srcw));\n\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\t\tif (base != 0)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(TMP_REG1) | RJ(base) | RK(TMP_REG1)));\n\t\t}\n\t\treturn push_inst(compiler, PRELD | RD(0) | RJ(TMP_REG1));\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (dst == RETURN_ADDR_REG)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, ADDI_D | RD(dst) | RJ(RETURN_ADDR_REG) | IMM_I12(0));\n\t\t}\n\n\t\tSLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2);\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128 && type != SLJIT_SIMD_REG_256)\n\t\treturn -1;\n\n\treturn freg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n#define SET_COND(cond) (sljit_ins)(cond << 15)\n\n#define COND_CUN SET_COND(0x8)\t /* UN */\n#define COND_CEQ SET_COND(0x4)\t /* EQ */\n#define COND_CUEQ SET_COND(0xc)\t /* UN EQ */\n#define COND_CLT SET_COND(0x2)\t /* LT */\n#define COND_CULT SET_COND(0xa)\t /* UN LT */\n#define COND_CLE SET_COND(0x6)\t /* LT EQ */\n#define COND_CULE SET_COND(0xe)\t /* UN LT EQ */\n#define COND_CNE SET_COND(0x10)\t /* GT LT */\n#define COND_CUNE SET_COND(0x18) /* UN GT LT */\n#define COND_COR SET_COND(0x14)\t /* GT LT EQ */\n\n#define FINST(inst, type) (sljit_ins)((type & SLJIT_32) ? inst##_S : inst##_D)\n#define FCD(cd) (sljit_ins)(cd & 0x7)\n#define FCJ(cj) (sljit_ins)((cj & 0x7) << 5)\n#define FCA(ca) (sljit_ins)((ca & 0x7) << 15)\n#define F_OTHER_FLAG 1\n\n#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))\n\n/* convert to inter exact toward zero */\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins inst;\n\tsljit_u32 word_data = 0;\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tswitch (GET_OPCODE(op))\n\t{\n\tcase SLJIT_CONV_SW_FROM_F64:\n\t\tword_data = 1;\n\t\tinst = FINST(FTINTRZ_L, op);\n\t\tbreak;\n\tcase SLJIT_CONV_S32_FROM_F64:\n\t\tinst = FINST(FTINTRZ_W, op);\n\t\tbreak;\n\tdefault:\n\t\tinst = BREAK;\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, inst | FRD(TMP_FREG1) | FRJ(src)));\n\tFAIL_IF(push_inst(compiler, FINST(MOVFR2GR, word_data) | RD(dst_r) | FRJ(TMP_FREG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, word_data ? WORD_DATA : INT_DATA, TMP_REG2, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins inst;\n\tsljit_u32 word_data = 0;\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tswitch (GET_OPCODE(op))\n\t{\n\tcase SLJIT_CONV_F64_FROM_SW:\n\t\tword_data = 1;\n\t\tinst = (sljit_ins)((op & SLJIT_32) ? FFINT_S_L : FFINT_D_L);\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_S32:\n\t\tinst = (sljit_ins)((op & SLJIT_32) ? FFINT_S_W : FFINT_D_W);\n\t\tbreak;\n\tdefault:\n\t\tinst = BREAK;\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, (word_data ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));\n\t\tsrc = TMP_REG1;\n\t} else if (src == SLJIT_IMM) {\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)\n\t\t\tsrcw = (sljit_s32)srcw;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\tFAIL_IF(push_inst(compiler, (word_data ? MOVGR2FR_D : MOVGR2FR_W) | FRD(dst_r) | RJ(src)));\n\tFAIL_IF(push_inst(compiler, inst | FRD(dst_r) | FRJ(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins inst;\n\tsljit_u32 word_data = 0;\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tswitch (GET_OPCODE(op))\n\t{\n\tcase SLJIT_CONV_F64_FROM_UW:\n\t\tword_data = 1;\n\t\tinst = (sljit_ins)((op & SLJIT_32) ? FFINT_S_L : FFINT_D_L);\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_U32:\n\t\tinst = (sljit_ins)((op & SLJIT_32) ? FFINT_S_W : FFINT_D_W);\n\t\tbreak;\n\tdefault:\n\t\tinst = BREAK;\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, (word_data ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));\n\t\tsrc = TMP_REG1;\n\t} else if (src == SLJIT_IMM) {\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32)\n\t\t\tsrcw = (sljit_u32)srcw;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif (!word_data)\n\t\tFAIL_IF(push_inst(compiler, SRLI_W | RD(src) | RJ(src) | IMM_I12(0)));\n\n\tFAIL_IF(push_inst(compiler, BLT | RJ(src) | RD(TMP_ZERO) | IMM_I16(4)));\n\n\tFAIL_IF(push_inst(compiler, (word_data ? MOVGR2FR_D : MOVGR2FR_W) | FRD(dst_r) | RJ(src)));\n\tFAIL_IF(push_inst(compiler, inst | FRD(dst_r) | FRJ(dst_r)));\n\tFAIL_IF(push_inst(compiler, B | IMM_I26(7)));\n\n\tFAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG2) | RJ(src) | IMM_I12(1)));\n\tFAIL_IF(push_inst(compiler, (word_data ? SRLI_D : SRLI_W) | RD(TMP_REG1) | RJ(src) | IMM_I12(1)));\n\tFAIL_IF(push_inst(compiler, OR | RD(TMP_REG1) | RJ(TMP_REG1) | RK(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, INST(MOVGR2FR, (!word_data)) | FRD(dst_r) | RJ(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, inst | FRD(dst_r) | FRJ(dst_r)));\n\tFAIL_IF(push_inst(compiler, FINST(FADD, op) | FRD(dst_r) | FRJ(dst_r) | FRK(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(OTHER_FLAG) | RK(OTHER_FLAG)));\n\n\tswitch (GET_FLAG_TYPE(op)) {\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CEQ | FCD(F_OTHER_FLAG) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CLT | FCD(F_OTHER_FLAG) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CLT | FCD(F_OTHER_FLAG) | FRJ(src2) | FRK(src1)));\n\t\tbreak;\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CULT | FCD(F_OTHER_FLAG) | FRJ(src2) | FRK(src1)));\n\t\tbreak;\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CULT | FCD(F_OTHER_FLAG) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CUEQ | FCD(F_OTHER_FLAG) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tdefault: /* SLJIT_UNORDERED */\n\t\tFAIL_IF(push_inst(compiler, FINST(FCMP_COND, op) | COND_CUN | FCD(F_OTHER_FLAG) | FRJ(src1) | FRK(src2)));\n\t}\n\treturn push_inst(compiler, MOVCF2GR | RD(OTHER_FLAG) | FCJ(F_OTHER_FLAG));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, FINST(FMOV, op) | FRD(dst_r) | FRJ(src)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FNEG, op) | FRD(dst_r) | FRJ(src)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FABS, op) | FRD(dst_r) | FRJ(src)));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\t/* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? FCVT_D_S : FCVT_S_D) | FRD(dst_r) | FRJ(src)));\n\t\top ^= SLJIT_32;\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r, flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc1 = TMP_FREG1;\n\t\t} else\n\t\t\tflags |= SLOW_SRC1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc2 = TMP_FREG2;\n\t\t} else\n\t\t\tflags |= SLOW_SRC2;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tif ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));\n\t\t} else {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));\n\n\tif (flags & SLOW_SRC1)\n\t\tsrc1 = TMP_FREG1;\n\tif (flags & SLOW_SRC2)\n\t\tsrc2 = TMP_FREG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FADD, op) | FRD(dst_r) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FSUB, op) | FRD(dst_r) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FMUL, op) | FRD(dst_r) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, FINST(FDIV, op) | FRD(dst_r) | FRJ(src1) | FRK(src2)));\n\t\tbreak;\n\t}\n\n\tif (dst_r != dst)\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src2, src2w, 0, 0));\n\t\tsrc2 = TMP_FREG1;\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\treg = (dst_freg == src2) ? TMP_FREG1 : dst_freg;\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, reg, src1, src1w, 0, 0));\n\t\tsrc1 = reg;\n\t}\n\n\treturn push_inst(compiler, FINST(FCOPYSIGN, op) | FRD(dst_freg) | FRJ(src1) | FRK(src2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, MOVGR2FR_W | RJ(TMP_ZERO) | FRD(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\treturn push_inst(compiler, MOVGR2FR_W | RJ(TMP_REG1) | FRD(freg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, MOVGR2FR_D | RJ(TMP_ZERO) | FRD(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\treturn push_inst(compiler, MOVGR2FR_D | RJ(TMP_REG1) | FRD(freg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64)\n\t\tinst = ((op & SLJIT_32) ? MOVGR2FR_W : MOVGR2FR_D) | FRD(freg) | RJ(reg);\n\telse\n\t\tinst = ((op & SLJIT_32) ? MOVFR2GR_S : MOVFR2GR_D) | RD(reg) | FRJ(freg);\n\treturn push_inst(compiler, inst);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nstatic sljit_ins get_jump_instruction(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\treturn BNE | RJ(EQUAL_FLAG) | RD(TMP_ZERO);\n\tcase SLJIT_NOT_EQUAL:\n\t\treturn BEQ | RJ(EQUAL_FLAG) | RD(TMP_ZERO);\n\tcase SLJIT_LESS:\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_OVERFLOW:\n\tcase SLJIT_CARRY:\n\tcase SLJIT_ATOMIC_STORED:\n\t\treturn BEQ | RJ(OTHER_FLAG) | RD(TMP_ZERO);\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_NOT_OVERFLOW:\n\tcase SLJIT_NOT_CARRY:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\treturn BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO);\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_UNORDERED:\n\t\treturn BEQ | RJ(OTHER_FLAG) | RD(TMP_ZERO);\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED:\n\t\treturn BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO);\n\tdefault:\n\t\t/* Not conditional branch. */\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins inst;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tinst = get_jump_instruction(type);\n\n\tif (inst != 0) {\n\t\tPTR_FAIL_IF(push_inst(compiler, inst));\n\t\tjump->flags |= IS_COND;\n\t}\n\n\tjump->addr = compiler->size;\n\tinst = JIRL | RJ(TMP_REG1) | IMM_I16(0);\n\n\tif (type >= SLJIT_FAST_CALL) {\n\t\tjump->flags |= IS_CALL;\n\t\tinst |= RD(RETURN_ADDR_REG);\n\t}\n\n\tPTR_FAIL_IF(push_inst(compiler, inst));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 flags;\n\tsljit_ins inst;\n\tsljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tflags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG1, src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags, src2_tmp_reg, src2, src2w, 0, 0));\n\t\tsrc2 = src2_tmp_reg;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tif (src1w != 0) {\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\t\tsrc1 = TMP_REG1;\n\t\t}\n\t\telse\n\t\t\tsrc1 = TMP_ZERO;\n\t}\n\n\tif (src2 == SLJIT_IMM) {\n\t\tif (src2w != 0) {\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));\n\t\t\tsrc2 = src2_tmp_reg;\n\t\t}\n\t\telse\n\t\t\tsrc2 = TMP_ZERO;\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | IS_COND));\n\ttype &= 0xff;\n\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\tinst = BNE | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_NOT_EQUAL:\n\t\tinst = BEQ | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_LESS:\n\t\tinst = BGEU | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_GREATER_EQUAL:\n\t\tinst = BLTU | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_GREATER:\n\t\tinst = BGEU | RJ(src2) | RD(src1);\n\t\tbreak;\n\tcase SLJIT_LESS_EQUAL:\n\t\tinst = BLTU | RJ(src2) | RD(src1);\n\t\tbreak;\n\tcase SLJIT_SIG_LESS:\n\t\tinst = BGE | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\tinst = BLT | RJ(src1) | RD(src2);\n\t\tbreak;\n\tcase SLJIT_SIG_GREATER:\n\t\tinst = BGE | RJ(src2) | RD(src1);\n\t\tbreak;\n\tcase SLJIT_SIG_LESS_EQUAL:\n\t\tinst = BLT | RJ(src2) | RD(src1);\n\t\tbreak;\n\tdefault:\n\t\tinst = BREAK;\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tPTR_FAIL_IF(push_inst(compiler, inst));\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, JIRL | RD(TMP_ZERO) | RJ(TMP_REG1) | IMM_I12(0)));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src != SLJIT_IMM) {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\t\treturn push_inst(compiler, JIRL | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RJ(src) | IMM_I12(0));\n\t}\n\n\t/* These jumps are converted to jump/call instructions when possible. */\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_CALL : 0));\n\tjump->u.target = (sljit_uw)srcw;\n\n\tjump->addr = compiler->size;\n\tFAIL_IF(push_inst(compiler, JIRL | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RJ(TMP_REG1) | IMM_I12(0)));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(src) | IMM_I12(0)));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 src_r, dst_r, invert;\n\tsljit_s32 saved_op = op;\n\tsljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\tdst_r = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tif (op >= SLJIT_ADD && (dst & SLJIT_MEM))\n\t\tFAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));\n\n\tif (type < SLJIT_F_EQUAL) {\n\t\tsrc_r = OTHER_FLAG;\n\t\tinvert = type & 0x1;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_EQUAL:\n\t\tcase SLJIT_NOT_EQUAL:\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(EQUAL_FLAG) | IMM_I12(1)));\n\t\t\tsrc_r = dst_r;\n\t\t\tbreak;\n\t\tcase SLJIT_ATOMIC_STORED:\n\t\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(OTHER_FLAG) | IMM_I12(1)));\n\t\t\tsrc_r = dst_r;\n\t\t\tinvert ^= 0x1;\n\t\t\tbreak;\n\t\tcase SLJIT_OVERFLOW:\n\t\tcase SLJIT_NOT_OVERFLOW:\n\t\t\tif (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {\n\t\t\t\tsrc_r = OTHER_FLAG;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(OTHER_FLAG) | IMM_I12(1)));\n\t\t\tsrc_r = dst_r;\n\t\t\tinvert ^= 0x1;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tinvert = 0;\n\t\tsrc_r = OTHER_FLAG;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\tcase SLJIT_F_NOT_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\tcase SLJIT_F_LESS_EQUAL:\n\t\tcase SLJIT_F_GREATER_EQUAL:\n\t\tcase SLJIT_ORDERED:\n\t\t\tinvert = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (invert) {\n\t\tFAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RJ(src_r) | IMM_I12(1)));\n\t\tsrc_r = dst_r;\n\t}\n\n\tif (op < SLJIT_ADD) {\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem(compiler, mem_type, src_r, dst, dstw);\n\n\t\tif (src_r != dst_r)\n\t\t\treturn push_inst(compiler, ADDI_D | RD(dst_r) | RJ(src_r) | IMM_I12(0));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tmem_type |= CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE;\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, src_r, 0);\n\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, src_r, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_ins *ptr;\n\tsljit_uw size;\n\tsljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);\n\tsljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (src1 == SLJIT_IMM && type & SLJIT_32)\n\t\tsrc1w = (sljit_s32)src1w;\n\n\ttype &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\tif (!is_compare)\n\t\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tif (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\t\tSLJIT_ASSERT(!(type & SLJIT_COMPARE_SELECT));\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(dst_reg) | IMM_I12(0)));\n\n\t\t\t\tif ((src1 & REG_MASK) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~REG_MASK) | TMP_REG1;\n\n\t\t\t\tif (OFFS_REG(src1) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(dst_reg) | RJ(src2_reg) | IMM_I12(0)));\n\t\t}\n\t}\n\n\tif (is_compare) {\n\t\tif (src1 & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG3, src1, src1w));\n\t\t} else if (src1 == SLJIT_IMM) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG3, src1w));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG3) | RJ(src1) | IMM_I12(0)));\n\t}\n\n\tsize = compiler->size;\n\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w));\n\t} else if (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, dst_reg, src1w));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, ADDI_D | RD(dst_reg) | RJ(src1) | IMM_I12(0)));\n\n\tif (is_compare) {\n\t\tswitch (type) {\n\t\tcase SLJIT_LESS:\n\t\tcase SLJIT_LESS_EQUAL:\n\t\t\t*ptr = BGEU;\n\t\t\tbreak;\n\t\tcase SLJIT_GREATER:\n\t\tcase SLJIT_GREATER_EQUAL:\n\t\t\t*ptr = BLTU;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_LESS:\n\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\t*ptr = BGE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*ptr = BLT;\n\t\t\tbreak;\n\t\t}\n\n\t\t*ptr |= RJ(TMP_REG3) | RD(dst_reg);\n\t} else {\n\t\t*ptr = get_jump_instruction(type);\n\t}\n\n\t*ptr |= IMM_I16(compiler->size - size);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_s32 invert = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif ((type & ~SLJIT_32) == SLJIT_EQUAL || (type & ~SLJIT_32) == SLJIT_NOT_EQUAL) {\n\t\tif ((type & ~SLJIT_32) == SLJIT_EQUAL)\n\t\t\tinvert = 1;\n\t\tFAIL_IF(push_inst(compiler, MOVGR2CF | FCD(F_OTHER_FLAG) | RJ(EQUAL_FLAG)));\n\t} else {\n\t\tif (get_jump_instruction(type & ~SLJIT_32) == (BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO)))\n\t\t\tinvert = 1;\n\t\tFAIL_IF(push_inst(compiler, MOVGR2CF | FCD(F_OTHER_FLAG) | RJ(OTHER_FLAG)));\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src1, src1w));\n\t\tif (invert)\n\t\t\treturn push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(TMP_FREG2) | FRK(src2_freg) | FCA(F_OTHER_FLAG));\n\t\treturn push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src2_freg) | FRK(TMP_FREG2) | FCA(F_OTHER_FLAG));\n\t} else {\n\t\tif (invert)\n\t\t\treturn push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src1) | FRK(src2_freg) | FCA(F_OTHER_FLAG));\n\t\treturn push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src2_freg) | FRK(src1) | FCA(F_OTHER_FLAG));\n\t}\n}\n\n#undef FLOAT_DATA\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tmemw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(memw != 0)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI_D | RD(TMP_REG1) | RJ(OFFS_REG(mem)) | IMM_I12(memw)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D| RD(TMP_REG1) | RJ(TMP_REG1) | RK(mem & REG_MASK)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D| RD(TMP_REG1) | RJ(mem & REG_MASK) | RK(OFFS_REG(mem))));\n\n\t\tmem = TMP_REG1;\n\t\tmemw = 0;\n\t} else if (memw > I12_MAX - SSIZE_OF(sw) || memw < I12_MIN) {\n\t\tif (((memw + 0x800) & 0xfff) <= 0xfff - SSIZE_OF(sw)) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, TO_ARGW_HI(memw)));\n\t\t\tmemw &= 0xfff;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw));\n\t\t\tmemw = 0;\n\t\t}\n\n\t\tif (mem & REG_MASK)\n\t\t\tFAIL_IF(push_inst(compiler, ADD_D| RD(TMP_REG1) | RJ(TMP_REG1) | RK(mem & REG_MASK)));\n\n\t\tmem = TMP_REG1;\n\t} else {\n\t\tmem &= REG_MASK;\n\t\tmemw &= 0xfff;\n\t}\n\n\tSLJIT_ASSERT((memw >= 0 && memw <= I12_MAX - SSIZE_OF(sw)) || (memw > I12_MAX && memw <= 0xfff));\n\n\tif (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {\n\t\tFAIL_IF(push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), (memw + SSIZE_OF(sw)) & 0xfff));\n\t\treturn push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw);\n\t}\n\n\tflags = WORD_DATA | (!(type & SLJIT_MEM_STORE) ? LOAD_DATA : 0);\n\n\tFAIL_IF(push_mem_inst(compiler, flags, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw));\n\treturn push_mem_inst(compiler, flags, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), (memw + SSIZE_OF(sw)) & 0xfff);\n}\n\n#undef TO_ARGW_HI\n\nstatic sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw)\n{\n\tsljit_s32 mem = *mem_ptr;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\t*mem_ptr = TMP_REG3;\n\t\tFAIL_IF(push_inst(compiler, SLLI_D | RD(TMP_REG3) | RJ(OFFS_REG(mem)) | IMM_I12(memw & 0x3)));\n\t\treturn push_inst(compiler, ADD_D | RD(TMP_REG3) | RJ(TMP_REG3) | RK(mem & REG_MASK));\n\t}\n\n\tif (!(mem & REG_MASK)) {\n\t\t*mem_ptr = TMP_REG3;\n\t\treturn load_immediate(compiler, TMP_REG3, memw);\n\t}\n\n\tmem &= REG_MASK;\n\n\tif (memw == 0) {\n\t\t*mem_ptr = mem;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t*mem_ptr = TMP_REG3;\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG3, memw));\n\treturn push_inst(compiler, ADD_D | RD(TMP_REG3) | RJ(TMP_REG3) | RK(mem));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (!(srcdst & SLJIT_MEM)) {\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = FRD(srcdst) | FRJ(vreg) | FRK(vreg);\n\t\telse\n\t\t\tins = FRD(vreg) | FRJ(srcdst) | FRK(srcdst);\n\n\t\tif (reg_size == 5)\n\t\t\tins |= VOR_V | (sljit_ins)1 << 26;\n\t\telse\n\t\t\tins |= VOR_V;\n\n\t\treturn push_inst(compiler, ins);\n\t}\n\n\tins = (type & SLJIT_SIMD_STORE) ? VST : VLD;\n\n\tif (reg_size == 5)\n\t\tins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD;\n\n\tif (FAST_IS_REG(srcdst) && srcdst >= 0 && (srcdstw >= I12_MIN && srcdstw <= I12_MAX))\n\t\treturn push_inst(compiler, ins | FRD(vreg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw));\n\telse {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\t\treturn push_inst(compiler, ins | FRD(vreg) | RJ(srcdst) | IMM_I12(0));\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\n\t\tif (reg_size == 5)\n\t\t\tins = (sljit_ins)1 << 25;\n\n\t\treturn push_inst(compiler, VLDREPL | ins | FRD(vreg) | RJ(src) | (sljit_ins)1 << (23 - elem_size));\n\t}\n\n\tif (reg_size == 5)\n\t\tins = (sljit_ins)1 << 26;\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM)\n\t\t\treturn push_inst(compiler, VREPLGR2VR | ins | FRD(vreg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10);\n\n\t\tFAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(vreg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15));\n\n\t\tif (reg_size == 5) {\n\t\t\tins = (sljit_ins)(0x44 << 10);\n\t\t\treturn push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg));\n\t\t}\n\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tins |= VREPLGR2VR | (sljit_ins)elem_size << 10;\n\n\tif (src == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, srcw));\n\t\tsrc = TMP_REG2;\n\t}\n\n\treturn push_inst(compiler, ins | FRD(vreg) | RJ(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tins = (reg_size == 5) ? ((sljit_ins)1 << 26) : 0;\n\n\t\tif ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) {\n\t\t\tFAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg)));\n\t\t\tsrcdst = TMP_FREG1;\n\t\t\tsrcdstw = 0;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(vreg) | FRJ(vreg) | FRK(vreg)));\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));\n\n\t\tif (reg_size == 5)\n\t\t\tins = (sljit_ins)1 << 25;\n\n\t\tif (type & SLJIT_SIMD_STORE) {\n\t\t\tins |= (sljit_ins)lane_index << 18 | (sljit_ins)(1 << (23 - elem_size));\n\t\t\treturn push_inst(compiler, VSTELM | ins | FRD(vreg) | RJ(srcdst));\n\t\t} else {\n\t\t\temit_op_mem(compiler, (elem_size == 3 ? WORD_DATA : (elem_size == 2 ? INT_DATA : (elem_size == 1 ? HALF_DATA : BYTE_DATA))) | LOAD_DATA, TMP_REG1, srcdst | SLJIT_MEM, 0);\n\t\t\tsrcdst = TMP_REG1;\n\t\t\tins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;\n\n\t\t\tif (reg_size == 5) {\n\t\t\t\tif (elem_size < 2) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg)));\n\t\t\t\t\tif (lane_index >= (2 << (3 - elem_size))) {\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1)));\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size)))));\n\t\t\t\t\t\treturn push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)));\n\t\t\t\t\t\treturn push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18));\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t\tins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26;\n\t\t\t}\n\n\t\t\treturn push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index));\n\t\t}\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tins = (reg_size == 5) ? (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26 : (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;\n\n\t\tif (type & SLJIT_SIMD_STORE) {\n\t\t\tFAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(vreg) | IMM_V(lane_index)));\n\t\t\treturn push_inst(compiler, VINSGR2VR | ins | FRD(srcdst) | RJ(TMP_REG1) | IMM_V(0));\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(srcdst) | IMM_V(0)));\n\t\t\treturn push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(TMP_REG1) | IMM_V(lane_index));\n\t\t}\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw));\n\t\tsrcdst = TMP_REG1;\n\t}\n\n\tif (type & SLJIT_SIMD_STORE) {\n\t\tins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;\n\n\t\tif (type & SLJIT_SIMD_LANE_SIGNED)\n\t\t\tins |= (sljit_ins)(VPICKVE2GR_U ^ (0x7 << 18));\n\t\telse\n\t\t\tins |= VPICKVE2GR_U;\n\n\t\tif (reg_size == 5) {\n\t\t\tif (elem_size < 2) {\n\t\t\t\tif (lane_index >= (2 << (3 - elem_size))) {\n\t\t\t\t\tif (type & SLJIT_SIMD_LANE_SIGNED)\n\t\t\t\t\t\tins |= (sljit_ins)(VPICKVE2GR_U ^ (0x7 << 18));\n\t\t\t\t\telse\n\t\t\t\t\t\tins |= VPICKVE2GR_U;\n\n\t\t\t\t\tFAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg)));\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1)));\n\t\t\t\t\treturn push_inst(compiler, ins | RD(srcdst) | FRJ(TMP_FREG1) | IMM_V(lane_index % (2 << (3 - elem_size))));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tins ^= (sljit_ins)1 << (15 - elem_size);\n\t\t\t\tins |= (sljit_ins)1 << 26;\n\t\t\t}\n\t\t}\n\n\t\treturn push_inst(compiler, ins | RD(srcdst) | FRJ(vreg) | IMM_V(lane_index));\n\t} else {\n\t\tins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;\n\n\t\tif (reg_size == 5) {\n\t\t\tif (elem_size < 2) {\n\t\t\t\tFAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg)));\n\t\t\t\tif (lane_index >= (2 << (3 - elem_size))) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1)));\n\t\t\t\t\tFAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size)))));\n\t\t\t\t\treturn push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2));\n\t\t\t\t} else {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)));\n\t\t\t\t\treturn push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18));\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26;\n\t\t}\n\n\t\treturn push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index));\n\t}\n\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;\n\n\tif (reg_size == 5) {\n\t\tFAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size)))));\n\n\t\tins = (src_lane_index < (2 << (3 - elem_size))) ? (sljit_ins)(0x44 << 10) : (sljit_ins)(0xee << 10);\n\n\t\treturn push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg));\n\t}\n\n\treturn push_inst(compiler, VREPLVEI | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tins = (type & SLJIT_SIMD_STORE) ? VST : VLD;\n\n\t\tif (reg_size == 5)\n\t\t\tins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD;\n\n\t\tif (FAST_IS_REG(src) && src >= 0 && (srcw >= I12_MIN && srcw <= I12_MAX))\n\t\t\tFAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(srcw)));\n\t\telse {\n\t\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));\n\t\t\tFAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(0)));\n\t\t}\n\t\tsrc = vreg;\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size != 2 || elem2_size != 3)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tins = 0;\n\t\tif (reg_size == 5) {\n\t\t\tins = (sljit_ins)1 << 26;\n\t\t\tFAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16)));\n\t\t}\n\n\t\treturn push_inst(compiler, VFCVTL_D_S | ins | FRD(vreg) | FRJ(src));\n\t}\n\n\tins = (type & SLJIT_SIMD_EXTEND_SIGNED) ? VSLLWIL : (VSLLWIL | (sljit_ins)1 << 18);\n\n\tif (reg_size == 5)\n\t\tins |= (sljit_ins)1 << 26;\n\n\tdo {\n\t\tif (reg_size == 5)\n\t\t\tFAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16)));\n\n\t\tFAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(vreg) | FRJ(src)));\n\t\tsrc = vreg;\n\t} while (++elem_size < elem2_size);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (reg_size == 5)\n\t\tins = (sljit_ins)1 << 26;\n\n\tFAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(vreg)));\n\n\tFAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x3c << 10) | RD(dst_r) | FRJ(TMP_FREG1)));\n\n\tif (reg_size == 5) {\n\t\tFAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x38 << 10) | ins | RD(TMP_REG3) | FRJ(TMP_FREG1) | IMM_V(2)));\n\t\tFAIL_IF(push_inst(compiler, SLLI_W | RD(TMP_REG3) | RJ(TMP_REG3) | IMM_I12(2 << (3 - elem_size))));\n\t\tFAIL_IF(push_inst(compiler, OR | RD(dst_r) | RJ(dst_r) | RK(TMP_REG3)));\n\t}\n\n\tif (dst_r == TMP_REG2)\n\t\treturn emit_op_mem(compiler, ((type & SLJIT_32) ? INT_DATA : WORD_DATA), TMP_REG2, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size != 5 && reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w));\n\t\tFAIL_IF(push_inst(compiler, (reg_size == 4 ? VLD : XVLD) | FRD(TMP_FREG1) | RJ(src2) | IMM_I12(0)));\n\t\tsrc2 = TMP_FREG1;\n\t}\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = VAND_V;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = VOR_V;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = VXOR_V;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tif (reg_size != 4)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\treturn push_inst(compiler, VSHUF_B | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src1_vreg) | FRA(src2));\n\t}\n\n\tif (reg_size == 5)\n\t\tins |= (sljit_ins)1 << 26;\n\n\treturn push_inst(compiler, ins | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler,\n\tsljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) {\n\t\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tswitch (GET_OPCODE(op)) {\n\t\tcase SLJIT_MOV:\n\t\tcase SLJIT_MOV_P:\n\t\t\tins = LL_D;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S32:\n\t\tcase SLJIT_MOV32:\n\t\t\tins = LL_W;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\t}\n\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg));\n\t}\n\n\tswitch(GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\t\tins = LD_B;\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n\t\tins = LD_BU;\n\t\tbreak;\n\tcase SLJIT_MOV_S16:\n\t\tins = LD_H;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = LD_HU;\n\t\tbreak;\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tins = LD_W;\n\t\tbreak;\n\tcase SLJIT_MOV_U32:\n\t\tins = LD_WU;\n\t\tbreak;\n\tdefault:\n\t\tins = LD_D;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg) | IMM_I12(0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler,\n\tsljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins = 0;\n\tsljit_ins unsign = 0;\n\tsljit_s32 tmp = temp_reg;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) {\n\t\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tswitch (GET_OPCODE(op)) {\n\t\tcase SLJIT_MOV:\n\t\tcase SLJIT_MOV_P:\n\t\t\tins = SC_D;\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S32:\n\t\tcase SLJIT_MOV32:\n\t\t\tins = SC_W;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\t}\n\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, ADD_D | RD(OTHER_FLAG) | RJ(src_reg) | RK(TMP_ZERO)));\n\t\treturn push_inst(compiler, ins | RD(OTHER_FLAG) | RJ(mem_reg));\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_S8:\n\t\tins = AMCAS_B;\n\t\tbreak;\n\tcase SLJIT_MOV_U8:\n\t\tins = AMCAS_B;\n\t\tunsign = BSTRPICK_D | (7 << 16);\n\t\tbreak;\n\tcase SLJIT_MOV_S16:\n\t\tins = AMCAS_H;\n\t\tbreak;\n\tcase SLJIT_MOV_U16:\n\t\tins = AMCAS_H;\n\t\tunsign = BSTRPICK_D | (15 << 16);\n\t\tbreak;\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tins = AMCAS_W;\n\t\tbreak;\n\tcase SLJIT_MOV_U32:\n\t\tins = AMCAS_W;\n\t\tunsign = BSTRPICK_D | (31 << 16);\n\t\tbreak;\n\tdefault:\n\t\tins = AMCAS_D;\n\t\tbreak;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (op & SLJIT_SET_ATOMIC_STORED) {\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(TMP_REG3) | RJ(temp_reg) | RK(TMP_ZERO)));\n\t\ttmp = TMP_REG3;\n\t}\n\tFAIL_IF(push_inst(compiler, ins | RD(tmp) | RJ(mem_reg) | RK(src_reg)));\n\tif (!(op & SLJIT_SET_ATOMIC_STORED))\n\t\treturn SLJIT_SUCCESS;\n\n\tif (unsign)\n\t\tFAIL_IF(push_inst(compiler, unsign | RD(tmp) | RJ(tmp)));\n\n\tFAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(tmp) | RK(temp_reg)));\n\treturn push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(OTHER_FLAG) | IMM_I12(1));\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins)\n{\n\tSLJIT_UNUSED_ARG(last_ins);\n\n\tFAIL_IF(push_inst(compiler, LU12I_W | RD(dst) | (sljit_ins)(((init_value & 0xffffffff) >> 12) << 5)));\n\tFAIL_IF(push_inst(compiler, LU32I_D | RD(dst) | (sljit_ins)(((init_value >> 32) & 0xfffff) << 5)));\n\tFAIL_IF(push_inst(compiler, LU52I_D | RD(dst) | RJ(dst) | (sljit_ins)(IMM_I12(init_value >> 52))));\n\treturn push_inst(compiler, ORI | RD(dst) | RJ(dst) | IMM_I12(init_value));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins *inst = (sljit_ins*)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);\n\n\tSLJIT_ASSERT((inst[0] & OPC_1RI20(0x7f)) == LU12I_W);\n\tinst[0] = (inst[0] & (OPC_1RI20(0x7f) | 0x1f)) | (sljit_ins)(((new_target & 0xffffffff) >> 12) << 5);\n\n\tSLJIT_ASSERT((inst[1] & OPC_1RI20(0x7f)) == LU32I_D);\n\tinst[1] = (inst[1] & (OPC_1RI20(0x7f) | 0x1f)) | (sljit_ins)(sljit_ins)(((new_target >> 32) & 0xfffff) << 5);\n\n\tSLJIT_ASSERT((inst[2] & OPC_2RI12(0x3ff)) == LU52I_D);\n\tinst[2] = (inst[2] & (OPC_2RI12(0x3ff) | 0x3ff)) | IMM_I12(new_target >> 52);\n\n\tSLJIT_ASSERT((inst[3] & OPC_2RI12(0x3ff)) == ORI || (inst[3] & OPC_2RI16(0x3f)) == JIRL);\n\tif ((inst[3] & OPC_2RI12(0x3ff)) == ORI)\n\t\tinst[3] = (inst[3] & (OPC_2RI12(0x3ff) | 0x3ff)) | IMM_I12(new_target);\n\telse\n\t\tinst[3] = (inst[3] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I12((new_target & 0xfff) >> 2);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);\n\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 4);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_DATA;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tif (init_value & 0x100)\n\t\t\tinit_value |= 0xf00;\n\t\telse\n\t\t\tinit_value &= 0xff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDI_D | RD(dst_r) | RJ(TMP_ZERO) | IMM_I12(init_value)));\n\t\tmem_flags = BYTE_DATA;\n\t\tbreak;\n\n\tcase SLJIT_MOV32:\n\t\tmem_flags = INT_DATA;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_S32:\n\t\tPTR_FAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)((init_value >> 7) & 0x1ffffe0)));\n\t\tPTR_FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(init_value)));\n\t\tbreak;\n\n\tdefault:\n\t\tPTR_FAIL_IF(emit_const(compiler, dst_r, init_value, 0));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw));\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, dst, dstw));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\tPTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r));\n\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADD_D | RD(dst_r) | RJ(dst_r) | RK(TMP_REG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_ins* inst;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tinst = (sljit_ins*)addr;\n\t\tSLJIT_ASSERT((inst[0] & OPC_2RI12(0xb)) == ADDI_D);\n\n\t\tif (new_constant & 0x100)\n\t\t\tnew_constant |= 0xf00;\n\t\telse\n\t\t\tnew_constant &= 0xff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\tinst[0] = (inst[0] & 0xffc003ff) | (sljit_ins)((new_constant & 0xfff) << 10);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\treturn;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tinst = (sljit_ins *)addr;\n\t\tSLJIT_ASSERT((inst[0] & OPC_1RI20(0xa)) == LU12I_W && (inst[1] & OPC_2RI12(0xe)) == ORI);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[0] = (inst[0] & (OPC_1RI20(0xa) | 0x1f)) | (sljit_ins)((new_constant >> 7) & 0x1ffffe0);\n\t\tinst[1] = (inst[1] & (OPC_2RI12(0xe) | 0x3ff)) | (sljit_ins)((new_constant & 0xfff) << 10);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n\n\tdefault:\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* mips 32-bit arch dependent functions. */\n\nstatic sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op,\n\t\tsljit_sw src1, sljit_sw src2, sljit_sw dst)\n{\n\tint is_32 = (op & SLJIT_32);\n\tsljit_ins mfhc = MFC1, mthc = MTC1;\n\tsljit_ins src1_r = FS(src1), src2_r = FS(src2), dst_r = FS(dst);\n\n\tif (!is_32) {\n\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\tcase CPU_FEATURE_FR:\n\t\t\tmfhc = MFHC1;\n\t\t\tmthc = MTHC1;\n\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\tdefault:\n\t\t\tsrc1_r |= (1 << 11);\n\t\t\tsrc2_r |= (1 << 11);\n\t\t\tdst_r |= (1 << 11);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tFAIL_IF(push_inst(compiler, mfhc | T(TMP_REG1) | src1_r, DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, mfhc | T(TMP_REG2) | src2_r, DR(TMP_REG2)));\n\tif (!is_32 && src1 != dst)\n\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(src1) | FD(dst), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\telse\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\tFAIL_IF(push_inst(compiler, XOR | T(TMP_REG1) | D(TMP_REG2) | S(TMP_REG2), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, SLL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, XOR | T(TMP_REG2) | D(TMP_REG1) | S(TMP_REG1), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, mthc | T(TMP_REG1) | dst_r, MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tif (mthc == MTC1)\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)\n{\n\tif (!(imm & ~0xffff))\n\t\treturn push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);\n\n\tif (imm < 0 && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);\n\n\tFAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));\n\treturn (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)\n{\n\tFAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));\n\treturn push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tstruct {\n#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN\n\t\t\tsljit_s32 lo;\n\t\t\tsljit_s32 hi;\n#else /* !SLJIT_LITTLE_ENDIAN */\n\t\t\tsljit_s32 hi;\n\t\t\tsljit_s32 lo;\n#endif /* SLJIT_LITTLE_ENDIAN */\n\t\t} bin;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.bin.lo != 0)\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.bin.lo));\n\tif (u.bin.hi != 0)\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG2), u.bin.hi));\n\n\tFAIL_IF(push_inst(compiler, MTC1 | (u.bin.lo != 0 ? T(TMP_REG1) : TA(0)) | FS(freg), MOVABLE_INS));\n\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\tcase CPU_FEATURE_FR:\n\t\treturn push_inst(compiler, MTHC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg), MOVABLE_INS);\n#endif /* SLJIT_MIPS_REV >= 2 */\n\tdefault:\n\t\tFAIL_IF(push_inst(compiler, MTC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg) | (1 << 11), MOVABLE_INS));\n\t\tbreak;\n\t}\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_s32 reg2 = 0;\n\tsljit_ins inst = FS(freg);\n\tsljit_ins mthc = MTC1, mfhc = MFC1;\n\tint is_32 = (op & SLJIT_32);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\top = GET_OPCODE(op);\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\n\t\tinst |= T(reg2);\n\n\t\tif (op == SLJIT_COPY_TO_F64)\n\t\t\tFAIL_IF(push_inst(compiler, MTC1 | inst, MOVABLE_INS));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, MFC1 | inst, DR(reg2)));\n\n\t\tinst = FS(freg) | (1 << 11);\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\tif (cpu_feature_list & CPU_FEATURE_FR) {\n\t\t\tmthc = MTHC1;\n\t\t\tmfhc = MFHC1;\n\t\t\tinst = FS(freg);\n\t\t}\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t}\n\n\tinst |= T(reg);\n\tif (!is_32 && !reg2) {\n\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\tcase CPU_FEATURE_FR:\n\t\t\tmthc = MTHC1;\n\t\t\tmfhc = MFHC1;\n\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\tdefault:\n\t\t\tinst |= (1 << 11);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (op == SLJIT_COPY_TO_F64)\n\t\tFAIL_IF(push_inst(compiler, mthc | inst, MOVABLE_INS));\n\telse\n\t\tFAIL_IF(push_inst(compiler, mfhc | inst, DR(reg)));\n\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tif (mthc == MTC1 || mfhc == MFC1)\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins *inst = (sljit_ins *)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\tSLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);\n\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 16);\n\tinst[1] = (inst[1] & 0xffff0000) | IMM(new_target);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n}\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr, sljit_u32 *extra_space)\n{\n\tsljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;\n\tsljit_u32 offset = 0;\n\tsljit_s32 float_arg_count = 0;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_ins prev_ins = NOP;\n\tsljit_ins ins = NOP;\n\tsljit_u8 offsets[4];\n\tsljit_u8 *offsets_ptr = offsets;\n#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN\n\tsljit_ins f64_hi = TA(7), f64_lo = TA(6);\n#else\n\tsljit_ins f64_hi = TA(6), f64_lo = TA(7);\n#endif /* SLJIT_LITTLE_ENDIAN */\n\n\tSLJIT_ASSERT(reg_map[TMP_REG2] == 4 && freg_map[TMP_FREG1] == 12);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\t/* See ABI description in sljit_emit_enter. */\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\t\t*offsets_ptr = (sljit_u8)offset;\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (offset & 0x7) {\n\t\t\t\toffset += sizeof(sljit_sw);\n\t\t\t\t*offsets_ptr = (sljit_u8)offset;\n\t\t\t}\n\n\t\t\tif (word_arg_count == 0 && float_arg_count <= 1)\n\t\t\t\t*offsets_ptr = (sljit_u8)(254 + float_arg_count);\n\n\t\t\toffset += sizeof(sljit_f64);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (word_arg_count == 0 && float_arg_count <= 1)\n\t\t\t\t*offsets_ptr = (sljit_u8)(254 + float_arg_count);\n\n\t\t\toffset += sizeof(sljit_f32);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\toffset += sizeof(sljit_sw);\n\t\t\tword_arg_count++;\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\toffsets_ptr++;\n\t}\n\n\t/* Stack is aligned to 16 bytes. */\n\tSLJIT_ASSERT(offset <= 8 * sizeof(sljit_sw));\n\n\tif (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {\n\t\tif (is_tail_call) {\n\t\t\toffset = (offset + sizeof(sljit_sw) + 15) & ~(sljit_uw)0xf;\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset, &prev_ins));\n\t\t\t*extra_space = offset;\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));\n\t\t\t*extra_space = 16;\n\t\t}\n\t} else {\n\t\tif (is_tail_call)\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, 0, &prev_ins));\n\t\t*extra_space = 0;\n\t}\n\n\twhile (types) {\n\t\t--offsets_ptr;\n\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (*offsets_ptr < 4 * sizeof(sljit_sw)) {\n\t\t\t\tif (prev_ins != NOP)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));\n\n\t\t\t\t/* Must be preceded by at least one other argument,\n\t\t\t\t * and its starting offset must be 8 because of alignment. */\n\t\t\t\tSLJIT_ASSERT((*offsets_ptr >> 2) == 2);\n\t\t\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\t\t\tcase CPU_FEATURE_FR:\n\t\t\t\t\tprev_ins = MFHC1 | f64_hi | FS(float_arg_count);\n\t\t\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\t\t\tdefault:\n\t\t\t\t\tprev_ins = MFC1 | f64_hi | FS(float_arg_count) | (1 << 11);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tins = MFC1 | f64_lo | FS(float_arg_count);\n\t\t\t} else if (*offsets_ptr < 254)\n\t\t\t\tins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);\n\t\t\telse if (*offsets_ptr == 254)\n\t\t\t\tins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1);\n\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (*offsets_ptr < 4 * sizeof (sljit_sw))\n\t\t\t\tins = MFC1 | TA(4 + (*offsets_ptr >> 2)) | FS(float_arg_count);\n\t\t\telse if (*offsets_ptr < 254)\n\t\t\t\tins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);\n\t\t\telse if (*offsets_ptr == 254)\n\t\t\t\tins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1);\n\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (*offsets_ptr >= 4 * sizeof (sljit_sw))\n\t\t\t\tins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(*offsets_ptr);\n\t\t\telse if ((*offsets_ptr >> 2) != word_arg_count - 1)\n\t\t\t\tins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (*offsets_ptr >> 2));\n\t\t\telse if (*offsets_ptr == 0)\n\t\t\t\tins = ADDU | S(SLJIT_R0) | TA(0) | DA(4);\n\n\t\t\tword_arg_count--;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ins != NOP) {\n\t\t\tif (prev_ins != NOP)\n\t\t\t\tFAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));\n\t\t\tprev_ins = ins;\n\t\t\tins = NOP;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\t*ins_ptr = prev_ins;\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tstruct sljit_jump *jump;\n\tsljit_u32 extra_space = 0;\n\tsljit_ins ins = NOP;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG) {\n\t\textra_space = (sljit_u32)type;\n\t\tPTR_FAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));\n\t} else if (type & SLJIT_CALL_RETURN)\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));\n\n\tSLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);\n\n\tif (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)\n\t\tjump->flags |= IS_MOVABLE;\n\n\tif (!(type & SLJIT_CALL_RETURN) || extra_space > 0) {\n\t\tjump->flags |= IS_JAL;\n\n\t\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\t\tjump->flags |= IS_CALL;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\t} else\n\t\tPTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += 2;\n\n\tif (extra_space == 0)\n\t\treturn jump;\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,\n\t\t\tSLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tPTR_FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\n\tPTR_FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),\n\t\t(type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP)));\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u32 extra_space = (sljit_u32)type;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));\n\t\tsrc = PIC_ADDR_REG;\n\t\tsrcw = 0;\n\t}\n\n\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\tif (type & SLJIT_CALL_RETURN) {\n\t\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));\n\t\t\t\tsrc = PIC_ADDR_REG;\n\t\t\t\tsrcw = 0;\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, 0, &ins));\n\n\t\t\tif (ins != NOP)\n\t\t\t\tFAIL_IF(push_inst(compiler, ins, MOVABLE_INS));\n\t\t}\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_ijump(compiler, type, src, srcw);\n\t}\n\n\tSLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);\n\n\tif (src == SLJIT_IMM)\n\t\tFAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));\n\telse if (src != PIC_ADDR_REG)\n\t\tFAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));\n\n\tFAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));\n\n\t/* Register input. */\n\tif (!(type & SLJIT_CALL_RETURN) || extra_space > 0)\n\t\tFAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\telse\n\t\tFAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\tFAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));\n\n\tif (extra_space == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,\n\t\t\tSLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tFAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\n\treturn push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),\n\t\t(type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP));\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* mips 64-bit arch dependent functions. */\n\nstatic sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op,\n\t\tsljit_s32 src1, sljit_s32 src2, sljit_s32 dst)\n{\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG1) | FS(src1), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG2) | FS(src2), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, XOR | S(TMP_REG2) | T(TMP_REG1) | D(TMP_REG2), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | T(TMP_REG1) | FS(dst), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tif (!(op & SLJIT_32))\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)\n{\n\tsljit_s32 shift = 32;\n\tsljit_s32 shift2;\n\tsljit_s32 inv = 0;\n\tsljit_ins ins;\n\tsljit_uw uimm;\n\n\tif (!(imm & ~0xffff))\n\t\treturn push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);\n\n\tif (imm < 0 && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);\n\n\tif (imm <= 0x7fffffffl && imm >= -0x80000000l) {\n\t\tFAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));\n\t\treturn (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;\n\t}\n\n\t/* Zero extended number. */\n\tuimm = (sljit_uw)imm;\n\tif (imm < 0) {\n\t\tuimm = ~(sljit_uw)imm;\n\t\tinv = 1;\n\t}\n\n\twhile (!(uimm & 0xff00000000000000l)) {\n\t\tshift -= 8;\n\t\tuimm <<= 8;\n\t}\n\n\tif (!(uimm & 0xf000000000000000l)) {\n\t\tshift -= 4;\n\t\tuimm <<= 4;\n\t}\n\n\tif (!(uimm & 0xc000000000000000l)) {\n\t\tshift -= 2;\n\t\tuimm <<= 2;\n\t}\n\n\tif ((sljit_sw)uimm < 0) {\n\t\tuimm >>= 1;\n\t\tshift += 1;\n\t}\n\tSLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32));\n\n\tif (inv)\n\t\tuimm = ~uimm;\n\n\tFAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar));\n\tif (uimm & 0x0000ffff00000000l)\n\t\tFAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar));\n\n\timm &= (1l << shift) - 1;\n\tif (!(imm & ~0xffff)) {\n\t\tins = (shift == 32) ? DSLL32 : DSLL;\n\t\tif (shift < 32)\n\t\t\tins |= SH_IMM(shift);\n\t\tFAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar));\n\t\treturn !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);\n\t}\n\n\t/* Double shifts needs to be performed. */\n\tuimm <<= 32;\n\tshift2 = shift - 16;\n\n\twhile (!(uimm & 0xf000000000000000l)) {\n\t\tshift2 -= 4;\n\t\tuimm <<= 4;\n\t}\n\n\tif (!(uimm & 0xc000000000000000l)) {\n\t\tshift2 -= 2;\n\t\tuimm <<= 2;\n\t}\n\n\tif (!(uimm & 0x8000000000000000l)) {\n\t\tshift2--;\n\t\tuimm <<= 1;\n\t}\n\n\tSLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16));\n\n\tFAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar));\n\tFAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar));\n\tFAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar));\n\n\timm &= (1l << shift2) - 1;\n\treturn !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)\n{\n\tFAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));\n\tFAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));\n\tFAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));\n\tFAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst)));\n\tFAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));\n\treturn push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0) {\n\t\tFAIL_IF(push_inst(compiler, DMTC1 | TA(0) | FS(freg), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));\n\tFAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tinst = T(reg) | FS(freg);\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64)\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | inst, MOVABLE_INS));\n\telse\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | inst, DR(reg)));\n\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tif (!(op & SLJIT_32))\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins *inst = (sljit_ins *)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);\n\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 48);\n\tinst[1] = (inst[1] & 0xffff0000) | IMM(new_target >> 32);\n\tinst[3] = (inst[3] & 0xffff0000) | IMM(new_target >> 16);\n\tinst[5] = (inst[5] & 0xffff0000) | IMM(new_target);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 6);\n}\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)\n{\n\tsljit_s32 arg_count = 0;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 float_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_ins prev_ins = *ins_ptr;\n\tsljit_ins ins = NOP;\n\n\tSLJIT_ASSERT(reg_map[TMP_REG2] == 4 && freg_map[TMP_FREG1] == 12);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targ_count++;\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\targ_count++;\n\t\t\tword_arg_count++;\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\twhile (types) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tins = MOV_fmt(FMT_D) | FS(float_arg_count) | FD(arg_count);\n\t\t\telse if (arg_count == 1)\n\t\t\t\tins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1);\n\t\t\targ_count--;\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tins = MOV_fmt(FMT_S) | FS(float_arg_count) | FD(arg_count);\n\t\t\telse if (arg_count == 1)\n\t\t\t\tins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1);\n\t\t\targ_count--;\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (arg_count != word_arg_count)\n\t\t\t\tins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);\n\t\t\telse if (arg_count == 1)\n\t\t\t\tins = DADDU | S(SLJIT_R0) | TA(0) | DA(4);\n\t\t\targ_count--;\n\t\t\tword_arg_count--;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ins != NOP) {\n\t\t\tif (prev_ins != NOP)\n\t\t\t\tFAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));\n\t\t\tprev_ins = ins;\n\t\t\tins = NOP;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\t*ins_ptr = prev_ins;\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins ins = NOP;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));\n\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tPTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));\n\n\tSLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);\n\n\tif (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)\n\t\tjump->flags |= IS_MOVABLE;\n\n\tif (!(type & SLJIT_CALL_RETURN)) {\n\t\tjump->flags |= IS_JAL;\n\n\t\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\t\tjump->flags |= IS_CALL;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\t} else\n\t\tPTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += 6;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins = NOP;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));\n\t\tsrc = PIC_ADDR_REG;\n\t\tsrcw = 0;\n\t}\n\n\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\tif (type & SLJIT_CALL_RETURN) {\n\t\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\t\tFAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));\n\t\t\t\tsrc = PIC_ADDR_REG;\n\t\t\t\tsrcw = 0;\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, 0, &ins));\n\n\t\t\tif (ins != NOP)\n\t\t\t\tFAIL_IF(push_inst(compiler, ins, MOVABLE_INS));\n\t\t}\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_ijump(compiler, type, src, srcw);\n\t}\n\n\tSLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG1);\n\n\tif (src == SLJIT_IMM)\n\t\tFAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));\n\telse if (src != PIC_ADDR_REG)\n\t\tFAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0, &ins));\n\n\tFAIL_IF(call_with_args(compiler, arg_types, &ins));\n\n\t/* Register input. */\n\tif (!(type & SLJIT_CALL_RETURN))\n\t\tFAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\telse\n\t\tFAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\treturn push_inst(compiler, ins, UNMOVABLE_INS);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* Latest MIPS architecture. */\n\n#ifdef HAVE_PRCTL\n#include <sys/prctl.h>\n#endif\n\n#if !defined(__mips_hard_float) || defined(__mips_single_float)\n/* Disable automatic detection, covers both -msoft-float and -mno-float */\n#define SLJIT_IS_FPU_AVAILABLE 0\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\treturn \"MIPS32-R6\" SLJIT_CPUINFO;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\treturn \"MIPS64-R6\" SLJIT_CPUINFO;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 5)\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\treturn \"MIPS32-R5\" SLJIT_CPUINFO;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\treturn \"MIPS64-R5\" SLJIT_CPUINFO;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\treturn \"MIPS32-R2\" SLJIT_CPUINFO;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\treturn \"MIPS64-R2\" SLJIT_CPUINFO;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\treturn \"MIPS32-R1\" SLJIT_CPUINFO;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\treturn \"MIPS64-R1\" SLJIT_CPUINFO;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#else /* SLJIT_MIPS_REV < 1 */\n\treturn \"MIPS III\" SLJIT_CPUINFO;\n#endif /* SLJIT_MIPS_REV >= 6 */\n}\n\n/* Length of an instruction word\n   Both for mips-32 and mips-64 */\ntypedef sljit_u32 sljit_ins;\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_REG3\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n\n/* For position independent code, t9 must contain the function address. */\n#define PIC_ADDR_REG\tTMP_REG1\n\n/* Floating point status register. */\n#define FCSR_REG\t31\n/* Return address register. */\n#define RETURN_ADDR_REG\t31\n\n/* Flags are kept in volatile registers. */\n#define EQUAL_FLAG\t3\n#define OTHER_FLAG\t1\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {\n\t0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 25, 4, 31, 3, 1\n};\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n#define TMP_FREG3\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\nstatic const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) << 1) + 1] = {\n\t0,\n\t0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20,\n\t12, 10, 16,\n\t1, 15, 3, 5, 7, 9, 19, 31, 29, 27, 25, 23, 21,\n\t13, 11, 17\n};\n\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {\n\t0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10\n};\n\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n#define S(s)\t\t((sljit_ins)reg_map[s] << 21)\n#define T(t)\t\t((sljit_ins)reg_map[t] << 16)\n#define D(d)\t\t((sljit_ins)reg_map[d] << 11)\n#define FT(t)\t\t((sljit_ins)freg_map[t] << 16)\n#define FS(s)\t\t((sljit_ins)freg_map[s] << 11)\n#define FD(d)\t\t((sljit_ins)freg_map[d] << 6)\n/* Absolute registers. */\n#define SA(s)\t\t((sljit_ins)(s) << 21)\n#define TA(t)\t\t((sljit_ins)(t) << 16)\n#define DA(d)\t\t((sljit_ins)(d) << 11)\n#define IMM(imm)\t((sljit_ins)(imm) & 0xffff)\n#define SH_IMM(imm)\t((sljit_ins)(imm) << 6)\n\n#define DR(dr)\t\t(reg_map[dr])\n#define FR(dr)\t\t(freg_map[dr])\n#define HI(opcode)\t((sljit_ins)(opcode) << 26)\n#define LO(opcode)\t((sljit_ins)(opcode))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n/* CMP.cond.fmt */\n/* S = (20 << 21) D = (21 << 21) */\n#define CMP_FMT_S\t(20 << 21)\n#endif /* SLJIT_MIPS_REV >= 6 */\n/* S = (16 << 21) D = (17 << 21) */\n#define FMT_S\t\t(16 << 21)\n#define FMT_D\t\t(17 << 21)\n\n#define ABS_S\t\t(HI(17) | FMT_S | LO(5))\n#define ADD_S\t\t(HI(17) | FMT_S | LO(0))\n#define ADDIU\t\t(HI(9))\n#define ADDU\t\t(HI(0) | LO(33))\n#define AND\t\t(HI(0) | LO(36))\n#define ANDI\t\t(HI(12))\n#define B\t\t(HI(4))\n#define BAL\t\t(HI(1) | (17 << 16))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define BC1EQZ\t\t(HI(17) | (9 << 21) | FT(TMP_FREG3))\n#define BC1NEZ\t\t(HI(17) | (13 << 21) | FT(TMP_FREG3))\n#else /* SLJIT_MIPS_REV < 6 */\n#define BC1F\t\t(HI(17) | (8 << 21))\n#define BC1T\t\t(HI(17) | (8 << 21) | (1 << 16))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define BEQ\t\t(HI(4))\n#define BGEZ\t\t(HI(1) | (1 << 16))\n#define BGTZ\t\t(HI(7))\n#define BLEZ\t\t(HI(6))\n#define BLTZ\t\t(HI(1) | (0 << 16))\n#define BNE\t\t(HI(5))\n#define BREAK\t\t(HI(0) | LO(13))\n#define CFC1\t\t(HI(17) | (2 << 21))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define C_EQ_S\t\t(HI(17) | CMP_FMT_S | LO(2))\n#define C_OLE_S\t\t(HI(17) | CMP_FMT_S | LO(6))\n#define C_OLT_S\t\t(HI(17) | CMP_FMT_S | LO(4))\n#define C_UEQ_S\t\t(HI(17) | CMP_FMT_S | LO(3))\n#define C_ULE_S\t\t(HI(17) | CMP_FMT_S | LO(7))\n#define C_ULT_S\t\t(HI(17) | CMP_FMT_S | LO(5))\n#define C_UN_S\t\t(HI(17) | CMP_FMT_S | LO(1))\n#define C_FD\t\t(FD(TMP_FREG3))\n#else /* SLJIT_MIPS_REV < 6 */\n#define C_EQ_S\t\t(HI(17) | FMT_S | LO(50))\n#define C_OLE_S\t\t(HI(17) | FMT_S | LO(54))\n#define C_OLT_S\t\t(HI(17) | FMT_S | LO(52))\n#define C_UEQ_S\t\t(HI(17) | FMT_S | LO(51))\n#define C_ULE_S\t\t(HI(17) | FMT_S | LO(55))\n#define C_ULT_S\t\t(HI(17) | FMT_S | LO(53))\n#define C_UN_S\t\t(HI(17) | FMT_S | LO(49))\n#define C_FD\t\t(0)\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define CVT_S_S\t\t(HI(17) | FMT_S | LO(32))\n#define DADDIU\t\t(HI(25))\n#define DADDU\t\t(HI(0) | LO(45))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define DDIV\t\t(HI(0) | (2 << 6) | LO(30))\n#define DDIVU\t\t(HI(0) | (2 << 6) | LO(31))\n#define DMOD\t\t(HI(0) | (3 << 6) | LO(30))\n#define DMODU\t\t(HI(0) | (3 << 6) | LO(31))\n#define DIV\t\t(HI(0) | (2 << 6) | LO(26))\n#define DIVU\t\t(HI(0) | (2 << 6) | LO(27))\n#define DMUH\t\t(HI(0) | (3 << 6) | LO(28))\n#define DMUHU\t\t(HI(0) | (3 << 6) | LO(29))\n#define DMUL\t\t(HI(0) | (2 << 6) | LO(28))\n#define DMULU\t\t(HI(0) | (2 << 6) | LO(29))\n#else /* SLJIT_MIPS_REV < 6 */\n#define DDIV\t\t(HI(0) | LO(30))\n#define DDIVU\t\t(HI(0) | LO(31))\n#define DIV\t\t(HI(0) | LO(26))\n#define DIVU\t\t(HI(0) | LO(27))\n#define DMULT\t\t(HI(0) | LO(28))\n#define DMULTU\t\t(HI(0) | LO(29))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define DIV_S\t\t(HI(17) | FMT_S | LO(3))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define DINSU\t\t(HI(31) | LO(6))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#define DMFC1\t\t(HI(17) | (1 << 21))\n#define DMTC1\t\t(HI(17) | (5 << 21))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define DROTR\t\t(HI(0) | (1 << 21) | LO(58))\n#define DROTR32\t\t(HI(0) | (1 << 21) | LO(62))\n#define DROTRV\t\t(HI(0) | (1 << 6) | LO(22))\n#define DSBH\t\t(HI(31) | (2 << 6) | LO(36))\n#define DSHD\t\t(HI(31) | (5 << 6) | LO(36))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#define DSLL\t\t(HI(0) | LO(56))\n#define DSLL32\t\t(HI(0) | LO(60))\n#define DSLLV\t\t(HI(0) | LO(20))\n#define DSRA\t\t(HI(0) | LO(59))\n#define DSRA32\t\t(HI(0) | LO(63))\n#define DSRAV\t\t(HI(0) | LO(23))\n#define DSRL\t\t(HI(0) | LO(58))\n#define DSRL32\t\t(HI(0) | LO(62))\n#define DSRLV\t\t(HI(0) | LO(22))\n#define DSUBU\t\t(HI(0) | LO(47))\n#define J\t\t(HI(2))\n#define JAL\t\t(HI(3))\n#define JALR\t\t(HI(0) | LO(9))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define JR\t\t(HI(0) | LO(9))\n#else /* SLJIT_MIPS_REV < 6 */\n#define JR\t\t(HI(0) | LO(8))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define LD\t\t(HI(55))\n#define LDL\t\t(HI(26))\n#define LDR\t\t(HI(27))\n#define LDC1\t\t(HI(53))\n#define LL\t\t(HI(48))\n#define LLD\t\t(HI(52))\n#define LUI\t\t(HI(15))\n#define LW\t\t(HI(35))\n#define LWL\t\t(HI(34))\n#define LWR\t\t(HI(38))\n#define LWC1\t\t(HI(49))\n#define MFC1\t\t(HI(17))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define MFHC1\t\t(HI(17) | (3 << 21))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define MOD\t\t(HI(0) | (3 << 6) | LO(26))\n#define MODU\t\t(HI(0) | (3 << 6) | LO(27))\n#else /* SLJIT_MIPS_REV < 6 */\n#define MFHI\t\t(HI(0) | LO(16))\n#define MFLO\t\t(HI(0) | LO(18))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define MTC1\t\t(HI(17) | (4 << 21))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define MTHC1\t\t(HI(17) | (7 << 21))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define MUH\t\t(HI(0) | (3 << 6) | LO(24))\n#define MUHU\t\t(HI(0) | (3 << 6) | LO(25))\n#define MUL\t\t(HI(0) | (2 << 6) | LO(24))\n#define MULU\t\t(HI(0) | (2 << 6) | LO(25))\n#else /* SLJIT_MIPS_REV < 6 */\n#define MULT\t\t(HI(0) | LO(24))\n#define MULTU\t\t(HI(0) | LO(25))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define MUL_S\t\t(HI(17) | FMT_S | LO(2))\n#define NEG_S\t\t(HI(17) | FMT_S | LO(7))\n#define NOP\t\t(HI(0) | LO(0))\n#define NOR\t\t(HI(0) | LO(39))\n#define OR\t\t(HI(0) | LO(37))\n#define ORI\t\t(HI(13))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define ROTR\t\t(HI(0) | (1 << 21) | LO(2))\n#define ROTRV\t\t(HI(0) | (1 << 6) | LO(6))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#define SC\t\t(HI(56))\n#define SCD\t\t(HI(60))\n#define SD\t\t(HI(63))\n#define SDL\t\t(HI(44))\n#define SDR\t\t(HI(45))\n#define SDC1\t\t(HI(61))\n#define SLT\t\t(HI(0) | LO(42))\n#define SLTI\t\t(HI(10))\n#define SLTIU\t\t(HI(11))\n#define SLTU\t\t(HI(0) | LO(43))\n#define SLL\t\t(HI(0) | LO(0))\n#define SLLV\t\t(HI(0) | LO(4))\n#define SRL\t\t(HI(0) | LO(2))\n#define SRLV\t\t(HI(0) | LO(6))\n#define SRA\t\t(HI(0) | LO(3))\n#define SRAV\t\t(HI(0) | LO(7))\n#define SUB_S\t\t(HI(17) | FMT_S | LO(1))\n#define SUBU\t\t(HI(0) | LO(35))\n#define SW\t\t(HI(43))\n#define SWL\t\t(HI(42))\n#define SWR\t\t(HI(46))\n#define SWC1\t\t(HI(57))\n#define SYNC\t\t(HI(0) | LO(15))\n#define TRUNC_W_S\t(HI(17) | FMT_S | LO(13))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define WSBH\t\t(HI(31) | (2 << 6) | LO(32))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#define XOR\t\t(HI(0) | LO(38))\n#define XORI\t\t(HI(14))\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n#define CLZ\t\t(HI(28) | LO(32))\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#define DCLZ\t\t(LO(18))\n#else /* SLJIT_MIPS_REV < 6 */\n#define DCLZ\t\t(HI(28) | LO(36))\n#define MOVF\t\t(HI(0) | (0 << 16) | LO(1))\n#define MOVF_S\t\t(HI(17) | FMT_S | (0 << 16) | LO(17))\n#define MOVN\t\t(HI(0) | LO(11))\n#define MOVN_S\t\t(HI(17) | FMT_S | LO(19))\n#define MOVT\t\t(HI(0) | (1 << 16) | LO(1))\n#define MOVT_S\t\t(HI(17) | FMT_S | (1 << 16) | LO(17))\n#define MOVZ\t\t(HI(0) | LO(10))\n#define MOVZ_S\t\t(HI(17) | FMT_S | LO(18))\n#define MUL\t\t(HI(28) | LO(2))\n#endif /* SLJIT_MIPS_REV >= 6 */\n#define PREF\t\t(HI(51))\n#define PREFX\t\t(HI(19) | LO(15))\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#define SEB\t\t(HI(31) | (16 << 6) | LO(32))\n#define SEH\t\t(HI(31) | (24 << 6) | LO(32))\n#endif /* SLJIT_MIPS_REV >= 2 */\n#endif /* SLJIT_MIPS_REV >= 1 */\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define ADDU_W\t\tADDU\n#define ADDIU_W\t\tADDIU\n#define SLL_W\t\tSLL\n#define SRA_W\t\tSRA\n#define SUBU_W\t\tSUBU\n#define STORE_W\t\tSW\n#define LOAD_W\t\tLW\n#else\n#define ADDU_W\t\tDADDU\n#define ADDIU_W\t\tDADDIU\n#define SLL_W\t\tDSLL\n#define SRA_W\t\tDSRA\n#define SUBU_W\t\tDSUBU\n#define STORE_W\t\tSD\n#define LOAD_W\t\tLD\n#endif\n\n#define MOV_fmt(f)\t(HI(17) | f | LO(6))\n\n#define SIMM_MAX\t(0x7fff)\n#define SIMM_MIN\t(-0x8000)\n#define UIMM_MAX\t(0xffff)\n\n#define CPU_FEATURE_DETECTED\t(1 << 0)\n#define CPU_FEATURE_FPU\t\t(1 << 1)\n#define CPU_FEATURE_FP64\t(1 << 2)\n#define CPU_FEATURE_FR\t\t(1 << 3)\n\nstatic sljit_u32 cpu_feature_list = 0;\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \\\n\t&& (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)\n\nstatic sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32)\n{\n\tif (compiler->scratches == -1)\n\t\treturn 0;\n\n\tif (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))\n\t\tfr -= SLJIT_F64_SECOND(0);\n\n\treturn (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))\n\t\t|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)\n\t\t|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));\n}\n\nstatic sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)\n{\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(vr);\n\tSLJIT_UNUSED_ARG(type);\n\n\t/* SIMD is not supported. */\n\treturn 0;\n}\n\n#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */\n\nstatic void get_cpu_features(void)\n{\n#if !defined(SLJIT_IS_FPU_AVAILABLE) && defined(__GNUC__)\n\tsljit_u32 fir = 0;\n#endif /* !SLJIT_IS_FPU_AVAILABLE && __GNUC__ */\n\tsljit_u32 feature_list = CPU_FEATURE_DETECTED;\n\n#if defined(SLJIT_IS_FPU_AVAILABLE)\n#if SLJIT_IS_FPU_AVAILABLE\n\tfeature_list |= CPU_FEATURE_FPU;\n#if SLJIT_IS_FPU_AVAILABLE == 64\n\tfeature_list |= CPU_FEATURE_FP64;\n#endif /* SLJIT_IS_FPU_AVAILABLE == 64 */\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n#elif defined(__GNUC__)\n\t__asm__ (\"cfc1 %0, $0\" : \"=r\"(fir));\n\tif ((fir & (0x3 << 16)) == (0x3 << 16))\n\t\tfeature_list |= CPU_FEATURE_FPU;\n\n#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64) \\\n\t&& (!defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV < 2)\n\tif ((feature_list & CPU_FEATURE_FPU))\n\t\tfeature_list |= CPU_FEATURE_FP64;\n#else /* SLJIT_CONFIG_MIPS32 || SLJIT_MIPS_REV >= 2 */\n\tif ((fir & (1 << 22)))\n\t\tfeature_list |= CPU_FEATURE_FP64;\n#endif /* SLJIT_CONFIG_MIPS_64 && SLJIT_MIPS_REV < 2 */\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n\n\tif ((feature_list & CPU_FEATURE_FPU) && (feature_list & CPU_FEATURE_FP64)) {\n#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 6\n\t\tfeature_list |= CPU_FEATURE_FR;\n#elif defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 0\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 5\n\t\tfeature_list |= CPU_FEATURE_FR;\n#endif /* SLJIT_MIPS_REV >= 5 */\n#else\n\t\tsljit_s32 flag = -1;\n#ifndef FR_GET_FP_MODE\n\t\tsljit_f64 zero = 0.0;\n#else /* PR_GET_FP_MODE */\n\t\tflag = prctl(PR_GET_FP_MODE);\n\n\t\tif (flag > 0)\n\t\t\tfeature_list |= CPU_FEATURE_FR;\n#endif /* FP_GET_PR_MODE */\n#if ((defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 2) \\\n\t|| (!defined(PR_GET_FP_MODE) && (!defined(SLJIT_DETECT_FR) || SLJIT_DETECT_FR >= 1))) \\\n\t&& (defined(__GNUC__) && (defined(__mips) && __mips >= 2))\n\t\tif (flag < 0) {\n\t\t\t__asm__ (\".set oddspreg\\n\"\n\t\t\t\t\"lwc1 $f17, %0\\n\"\n\t\t\t\t\"ldc1 $f16, %1\\n\"\n\t\t\t\t\"swc1 $f17, %0\\n\"\n\t\t\t: \"+m\" (flag) : \"m\" (zero) : \"$f16\", \"$f17\");\n\t\t\tif (flag)\n\t\t\t\tfeature_list |= CPU_FEATURE_FR;\n\t\t}\n#endif /* (!PR_GET_FP_MODE || (PR_GET_FP_MODE && SLJIT_DETECT_FR == 2)) && __GNUC__ */\n#endif /* SLJIT_MIPS_REV >= 6 */\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t/* StatusFR=1 is the only mode supported by the code in MIPS64 */\n\t\tfeature_list |= CPU_FEATURE_FR;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t}\n\n\tcpu_feature_list = feature_list;\n}\n\n/* dest_reg is the absolute name of the register\n   Useful for reordering instructions in the delay slot. */\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)\n{\n\tsljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tSLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS\n\t\t|| (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)\n\t\t|| (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));\n\tFAIL_IF(!ptr);\n\t*ptr = ins;\n\tcompiler->size++;\n\tcompiler->delay_slot = delay_slot;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)\n{\n\tif (flags & IS_BIT26_COND)\n\t\treturn (1 << 26);\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\tif (flags & IS_BIT23_COND)\n\t\treturn (1 << 23);\n#endif /* SLJIT_MIPS_REV >= 6 */\n\treturn (1 << 16);\n}\n\nstatic SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_ins *inst;\n\tsljit_ins saved_inst;\n\n\tinst = (sljit_ins *)jump->addr;\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))\n\t\tgoto exit;\n#else\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n#endif\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;\n\t}\n\n\tif (jump->flags & IS_COND)\n\t\tinst--;\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (jump->flags & IS_CALL)\n\t\tgoto preserve_addr;\n#endif\n\n\t/* B instructions. */\n\tif (jump->flags & IS_MOVABLE) {\n\t\tdiff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;\n\t\tif (diff <= SIMM_MAX && diff >= SIMM_MIN) {\n\t\t\tjump->flags |= PATCH_B;\n\n\t\t\tif (!(jump->flags & IS_COND)) {\n\t\t\t\tinst[0] = inst[-1];\n\t\t\t\tinst[-1] = (jump->flags & IS_JAL) ? BAL : B;\n\t\t\t\tjump->addr -= sizeof(sljit_ins);\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t\tsaved_inst = inst[0];\n\t\t\tinst[0] = inst[-1];\n\t\t\tinst[-1] = saved_inst ^ invert_branch(jump->flags);\n\t\t\tjump->addr -= 2 * sizeof(sljit_ins);\n\t\t\treturn inst;\n\t\t}\n\t} else {\n\t\tdiff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;\n\t\tif (diff <= SIMM_MAX && diff >= SIMM_MIN) {\n\t\t\tjump->flags |= PATCH_B;\n\n\t\t\tif (!(jump->flags & IS_COND)) {\n\t\t\t\tinst[0] = (jump->flags & IS_JAL) ? BAL : B;\n\t\t\t\t/* Keep inst[1] */\n\t\t\t\treturn inst + 1;\n\t\t\t}\n\t\t\tinst[0] ^= invert_branch(jump->flags);\n\t\t\tinst[1] = NOP;\n\t\t\tjump->addr -= sizeof(sljit_ins);\n\t\t\treturn inst + 1;\n\t\t}\n\t}\n\n\tif (jump->flags & IS_COND) {\n\t\tif ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {\n\t\t\tjump->flags |= PATCH_J;\n\t\t\tsaved_inst = inst[0];\n\t\t\tinst[0] = inst[-1];\n\t\t\tinst[-1] = (saved_inst & 0xffff0000) | 3;\n\t\t\tinst[1] = J;\n\t\t\tinst[2] = NOP;\n\t\t\treturn inst + 2;\n\t\t}\n\t\telse if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {\n\t\t\tjump->flags |= PATCH_J;\n\t\t\tinst[0] = (inst[0] & 0xffff0000) | 3;\n\t\t\tinst[1] = NOP;\n\t\t\tinst[2] = J;\n\t\t\tinst[3] = NOP;\n\t\t\tjump->addr += sizeof(sljit_ins);\n\t\t\treturn inst + 3;\n\t\t}\n\t}\n\telse {\n\t\t/* J instuctions. */\n\t\tif ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {\n\t\t\tjump->flags |= PATCH_J;\n\t\t\tinst[0] = inst[-1];\n\t\t\tinst[-1] = (jump->flags & IS_JAL) ? JAL : J;\n\t\t\tjump->addr -= sizeof(sljit_ins);\n\t\t\treturn inst;\n\t\t}\n\n\t\tif ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {\n\t\t\tjump->flags |= PATCH_J;\n\t\t\tinst[0] = (jump->flags & IS_JAL) ? JAL : J;\n\t\t\t/* Keep inst[1] */\n\t\t\treturn inst + 1;\n\t\t}\n\t}\n\n\tif (jump->flags & IS_COND)\n\t\tinst++;\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\npreserve_addr:\n\tif (target_addr <= 0x7fffffff) {\n\t\tjump->flags |= PATCH_ABS32;\n\t\tif (jump->flags & IS_COND)\n\t\t\tinst[-1] -= 4;\n\n\t\tinst[2] = inst[0];\n\t\tinst[3] = inst[1];\n\t\treturn inst + 3;\n\t}\n\tif (target_addr <= 0x7fffffffffffl) {\n\t\tjump->flags |= PATCH_ABS48;\n\t\tif (jump->flags & IS_COND)\n\t\t\tinst[-1] -= 2;\n\n\t\tinst[4] = inst[0];\n\t\tinst[5] = inst[1];\n\t\treturn inst + 5;\n\t}\n#endif\n\nexit:\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tinst[2] = inst[0];\n\tinst[3] = inst[1];\n\treturn inst + 3;\n#else\n\tinst[6] = inst[0];\n\tinst[7] = inst[1];\n\treturn inst + 7;\n#endif\n}\n\n#ifdef __GNUC__\nstatic __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)\n{\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n}\n#endif\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\tif (addr < 0x80000000l) {\n\t\tjump->flags |= PATCH_ABS32;\n\t\treturn 1;\n\t}\n\n\tif (addr < 0x800000000000l) {\n\t\tjump->flags |= PATCH_ABS48;\n\t\treturn 3;\n\t}\n\n\treturn 5;\n}\n\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\nstatic SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)\n{\n\tsljit_uw flags = jump->flags;\n\tsljit_ins *ins = (sljit_ins*)jump->addr;\n\tsljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\tsljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG;\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tins[0] = LUI | T(reg) | IMM(addr >> 16);\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tif (flags & PATCH_ABS32) {\n\t\tSLJIT_ASSERT(addr < 0x80000000l);\n\t\tins[0] = LUI | T(reg) | IMM(addr >> 16);\n\t}\n\telse if (flags & PATCH_ABS48) {\n\t\tSLJIT_ASSERT(addr < 0x800000000000l);\n\t\tins[0] = LUI | T(reg) | IMM(addr >> 32);\n\t\tins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);\n\t\tins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);\n\t\tins += 2;\n\t}\n\telse {\n\t\tins[0] = LUI | T(reg) | IMM(addr >> 48);\n\t\tins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);\n\t\tins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);\n\t\tins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);\n\t\tins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);\n\t\tins += 4;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n\tins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);\n}\n\nstatic SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *code;\n\tsljit_ins *code_ptr;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_uw word_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\tsljit_uw addr;\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\treverse_buf(compiler);\n\n\tcode = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\tword_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 2);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == word_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= word_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= word_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= word_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\t\t\t\t\tword_count += 2;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t\t\t\t\tword_count += 6;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t\t\t\t\t\tjump->addr = (sljit_uw)(code_ptr - 1);\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code, executable_offset);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\t\t\t\t\tcode_ptr += 1;\n\t\t\t\t\t\tword_count += 1;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code, executable_offset);\n\t\t\t\t\t\tword_count += 5;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t\t\t\t\t}\n\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\tword_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == word_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)code_ptr;\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tdo {\n\t\t\taddr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\t\t\tbuf_ptr = (sljit_ins *)jump->addr;\n\n\t\t\tif (jump->flags & PATCH_B) {\n\t\t\t\taddr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);\n\t\t\t\tSLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);\n\t\t\t\tbuf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (jump->flags & PATCH_J) {\n\t\t\t\tSLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)\n\t\t\t\t\t== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));\n\t\t\t\tbuf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tload_addr_to_reg(jump);\n\t\t} while (0);\n\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);\n\n\tcode = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n#ifndef __GNUC__\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n#else\n\t/* GCC workaround for invalid code generation with -O2. */\n\tsljit_cache_flush(code, code_ptr);\n#endif\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \\\n\t\t&& (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE)\n\tcase SLJIT_HAS_F64_AS_F32_PAIR:\n\t\tif (!cpu_feature_list)\n\t\t\tget_cpu_features();\n\n\t\treturn (cpu_feature_list & CPU_FEATURE_FR) != 0;\n#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */\n\tcase SLJIT_HAS_FPU:\n\t\tif (!cpu_feature_list)\n\t\t\tget_cpu_features();\n\n\t\treturn (cpu_feature_list & CPU_FEATURE_FPU) != 0;\n\tcase SLJIT_HAS_ZERO_REGISTER:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\t\treturn 1;\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_CMOV:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tcase SLJIT_HAS_CTZ:\n\t\treturn 2;\n#endif /* SLJIT_MIPS_REV >= 1 */\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\t\treturn 1;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tSLJIT_UNUSED_ARG(type);\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\n/* Creates an index in data_transfer_insts array. */\n#define LOAD_DATA\t0x01\n#define WORD_DATA\t0x00\n#define BYTE_DATA\t0x02\n#define HALF_DATA\t0x04\n#define INT_DATA\t0x06\n#define SIGNED_DATA\t0x08\n/* Separates integer and floating point registers */\n#define GPR_REG\t\t0x0f\n#define DOUBLE_DATA\t0x10\n#define SINGLE_DATA\t0x12\n\n#define MEM_MASK\t0x1f\n\n#define ARG_TEST\t0x00020\n#define ALT_KEEP_CACHE\t0x00040\n#define CUMULATIVE_OP\t0x00080\n#define LOGICAL_OP\t0x00100\n#define IMM_OP\t\t0x00200\n#define MOVE_OP\t\t0x00400\n#define SRC2_IMM\t0x00800\n\n#define UNUSED_DEST\t0x01000\n#define REG_DEST\t0x02000\n#define REG1_SOURCE\t0x04000\n#define REG2_SOURCE\t0x08000\n#define SLOW_SRC1\t0x10000\n#define SLOW_SRC2\t0x20000\n#define SLOW_DEST\t0x40000\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define SELECT_OP(d, w)\t(w)\n#else\n#define SELECT_OP(d, w)\t(!(op & SLJIT_32) ? (d) : (w))\n#endif\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#include \"sljitNativeMIPS_32.c\"\n#else\n#include \"sljitNativeMIPS_64.c\"\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\tsljit_ins base;\n\tsljit_s32 i, tmp, offset;\n\tsljit_s32 arg_count, word_arg_count, float_arg_count;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((local_size & SSIZE_OF(sw)) != 0)\n\t\t\tlocal_size += SSIZE_OF(sw);\n\t\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\t}\n\n\tlocal_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n#else\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\tlocal_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;\n#endif\n\tcompiler->local_size = local_size;\n\n\toffset = 0;\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (!(options & SLJIT_ENTER_REG_ARG)) {\n\t\ttmp = arg_types >> SLJIT_ARG_SHIFT;\n\t\targ_count = 0;\n\n\t\twhile (tmp) {\n\t\t\toffset = arg_count;\n\t\t\tif ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {\n\t\t\t\tif ((arg_count & 0x1) != 0)\n\t\t\t\t\targ_count++;\n\t\t\t\targ_count++;\n\t\t\t}\n\n\t\t\targ_count++;\n\t\t\ttmp >>= SLJIT_ARG_SHIFT;\n\t\t}\n\n\t\tcompiler->args_size = (sljit_uw)arg_count << 2;\n\t\toffset = (offset >= 4) ? (offset << 2) : 0;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n\tif (local_size + offset <= -SIMM_MIN) {\n\t\t/* Frequent case. */\n\t\tFAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));\n\t\tbase = S(SLJIT_SP);\n\t\toffset = local_size - SSIZE_OF(sw);\n\t} else {\n\t\tFAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));\n\t\tbase = S(TMP_REG1);\n\t\toffset = -SSIZE_OF(sw);\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\tlocal_size = 0;\n#endif\n\t}\n\n\tFAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t/* This alignment is valid because offset is not used after storing FPU regs. */\n\tif ((offset & SSIZE_OF(sw)) != 0)\n\t\toffset -= SSIZE_OF(sw);\n#endif\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\treturn SLJIT_SUCCESS;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\targ_count = 0;\n\tword_arg_count = 0;\n\tfloat_arg_count = 0;\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t/* The first maximum two floating point arguments are passed in floating point\n\t   registers if no integer argument precedes them. The first 16 byte data is\n\t   passed in four integer registers, the rest is placed onto the stack.\n\t   The floating point registers are also part of the first 16 byte data, so\n\t   their corresponding integer registers are not used when they are present. */\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tfloat_arg_count++;\n\t\t\tif ((arg_count & 0x1) != 0)\n\t\t\t\targ_count++;\n\n\t\t\tif (word_arg_count == 0 && float_arg_count <= 2) {\n\t\t\t\tif (float_arg_count == 1)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));\n\t\t\t} else if (arg_count < 4) {\n\t\t\t\tFAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));\n\t\t\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\t\t\tcase CPU_FEATURE_FR:\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS));\n\t\t\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\t\t\tdefault:\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));\n\t\t\targ_count++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tfloat_arg_count++;\n\n\t\t\tif (word_arg_count == 0 && float_arg_count <= 2) {\n\t\t\t\tif (float_arg_count == 1)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));\n\t\t\t} else if (arg_count < 4)\n\t\t\t\tFAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\ttmp = SLJIT_S0 - saved_arg_count;\n\t\t\t\tsaved_arg_count++;\n\t\t\t} else if (word_arg_count != arg_count + 1 || arg_count == 0)\n\t\t\t\ttmp = word_arg_count;\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tif (arg_count < 4)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));\n\t\t\tbreak;\n\t\t}\n\t\targ_count++;\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tSLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\twhile (arg_types) {\n\t\targ_count++;\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tfloat_arg_count++;\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));\n\t\t\telse if (arg_count == 1)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tfloat_arg_count++;\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));\n\t\t\telse if (arg_count == 1)\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\ttmp = SLJIT_S0 - saved_arg_count;\n\t\t\t\tsaved_arg_count++;\n\t\t\t} else if (word_arg_count != arg_count || word_arg_count <= 1)\n\t\t\t\ttmp = word_arg_count;\n\t\t\telse\n\t\t\t\tbreak;\n\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((local_size & SSIZE_OF(sw)) != 0)\n\t\t\tlocal_size += SSIZE_OF(sw);\n\t\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\t}\n\n\tcompiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n#else\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\tcompiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;\n#endif\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)\n{\n\tsljit_s32 local_size, i, tmp, offset;\n\tsljit_s32 load_return_addr = (frame_size == 0);\n\tsljit_s32 scratches = compiler->scratches;\n\tsljit_s32 saveds = compiler->saveds;\n\tsljit_s32 fsaveds = compiler->fsaveds;\n\tsljit_s32 fscratches = compiler->fscratches;\n\tsljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\n\tSLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);\n\tframe_size &= ~0xf;\n\n\tlocal_size = compiler->local_size;\n\n\ttmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((tmp & SSIZE_OF(sw)) != 0)\n\t\t\ttmp += SSIZE_OF(sw);\n\t\ttmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\t}\n#else\n\ttmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n#endif\n\n\tif (local_size <= SIMM_MAX) {\n\t\tif (local_size < frame_size) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));\n\t\t\tlocal_size = frame_size;\n\t\t}\n\t} else {\n\t\tif (tmp < frame_size)\n\t\t\ttmp = frame_size;\n\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG2), local_size - tmp));\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG2) | D(SLJIT_SP), DR(SLJIT_SP)));\n\t\tlocal_size = tmp;\n\t}\n\n\tSLJIT_ASSERT(local_size >= frame_size);\n\n\toffset = local_size - SSIZE_OF(sw);\n\tif (load_return_addr)\n\t\tFAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t/* This alignment is valid because offset is not used after storing FPU regs. */\n\tif ((offset & SSIZE_OF(sw)) != 0)\n\t\toffset -= SSIZE_OF(sw);\n#endif\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));\n\t}\n\n\tif (local_size > frame_size)\n\t\t*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);\n\telse\n\t\t*ins_ptr = NOP;\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\temit_stack_frame_release(compiler, 0, &ins);\n\n\tFAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\treturn push_inst(compiler, ins, UNMOVABLE_INS);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));\n\t\tsrc = PIC_ADDR_REG;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));\n\t\tsrc = PIC_ADDR_REG;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1, &ins));\n\n\tif (src != SLJIT_IMM) {\n\t\tFAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));\n\t\treturn push_inst(compiler, ins, UNMOVABLE_INS);\n\t}\n\n\tif (ins != NOP)\n\t\tFAIL_IF(push_inst(compiler, ins, MOVABLE_INS));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define ARCH_32_64(a, b)\ta\n#else\n#define ARCH_32_64(a, b)\tb\n#endif\n\nstatic const sljit_ins data_transfer_insts[16 + 4] = {\n/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),\n/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),\n/* u b s */ HI(40) /* sb */,\n/* u b l */ HI(36) /* lbu */,\n/* u h s */ HI(41) /* sh */,\n/* u h l */ HI(37) /* lhu */,\n/* u i s */ HI(43) /* sw */,\n/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),\n\n/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),\n/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),\n/* s b s */ HI(40) /* sb */,\n/* s b l */ HI(32) /* lb */,\n/* s h s */ HI(41) /* sh */,\n/* s h l */ HI(33) /* lh */,\n/* s i s */ HI(43) /* sw */,\n/* s i l */ HI(35) /* lw */,\n\n/* d   s */ HI(61) /* sdc1 */,\n/* d   l */ HI(53) /* ldc1 */,\n/* s   s */ HI(57) /* swc1 */,\n/* s   l */ HI(49) /* lwc1 */,\n};\n\n#undef ARCH_32_64\n\n/* reg_ar is an absoulute register! */\n\n/* Can perform an operation using at most 1 instruction. */\nstatic sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)\n{\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {\n\t\t/* Works for both absoulte and relative addresses. */\n\t\tif (SLJIT_UNLIKELY(flags & ARG_TEST))\n\t\t\treturn 1;\n\t\tFAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)\n\t\t\t| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))\n\n/* See getput_arg below.\n   Note: can_cache is called only for binary operators. */\nstatic sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tSLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));\n\n\t/* Simple operation except for updates. */\n\tif (arg & OFFS_REG_MASK) {\n\t\targw &= 0x3;\n\t\tnext_argw &= 0x3;\n\t\tif (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))\n\t\t\treturn 1;\n\t\treturn 0;\n\t}\n\n\tif (arg == next_arg) {\n\t\tif (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)\n\t\t\t\t|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))\n\t\t\treturn 1;\n\t\treturn 0;\n\t}\n\n\treturn 0;\n}\n\n/* Emit the necessary instructions. See can_cache above. */\nstatic sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tsljit_s32 tmp_ar, base, delay_slot;\n\tsljit_sw offset, argw_hi;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\tif (!(next_arg & SLJIT_MEM)) {\n\t\tnext_arg = 0;\n\t\tnext_argw = 0;\n\t}\n\n\t/* Since tmp can be the same as base or offset registers,\n\t * these might be unavailable after modifying tmp. */\n\tif ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {\n\t\ttmp_ar = reg_ar;\n\t\tdelay_slot = reg_ar;\n\t}\n\telse {\n\t\ttmp_ar = DR(TMP_REG1);\n\t\tdelay_slot = MOVABLE_INS;\n\t}\n\tbase = arg & REG_MASK;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\t/* Using the cache. */\n\t\tif (argw == compiler->cache_argw) {\n\t\t\tif (arg == compiler->cache_arg)\n\t\t\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);\n\n\t\t\tif ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {\n\t\t\t\tif (arg == next_arg && argw == (next_argw & 0x3)) {\n\t\t\t\t\tcompiler->cache_arg = arg;\n\t\t\t\t\tcompiler->cache_argw = argw;\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));\n\t\t\t\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));\n\t\t\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);\n\t\t\t}\n\t\t}\n\n\t\tif (SLJIT_UNLIKELY(argw)) {\n\t\t\tcompiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);\n\t\t\tcompiler->cache_argw = argw;\n\t\t\tFAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));\n\t\t}\n\n\t\tif (arg == next_arg && argw == (next_argw & 0x3)) {\n\t\t\tcompiler->cache_arg = arg;\n\t\t\tcompiler->cache_argw = argw;\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));\n\t\t\ttmp_ar = DR(TMP_REG3);\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));\n\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);\n\t}\n\n\tif (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)\n\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);\n\n\tif (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {\n\t\toffset = argw - compiler->cache_argw;\n\t} else {\n\t\tcompiler->cache_arg = SLJIT_MEM;\n\n\t\targw_hi = TO_ARGW_HI(argw);\n\n\t\tif (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {\n\t\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));\n\t\t\tcompiler->cache_argw = argw;\n\t\t\toffset = 0;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));\n\t\t\tcompiler->cache_argw = argw_hi;\n\t\t\toffset = argw & 0xffff;\n\t\t\targw = argw_hi;\n\t\t}\n\t}\n\n\tif (!base)\n\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);\n\n\tif (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {\n\t\tcompiler->cache_arg = arg;\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));\n\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));\n\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);\n}\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_s32 tmp_ar, base, delay_slot;\n\n\tif (getput_arg_fast(compiler, flags, reg_ar, arg, argw))\n\t\treturn compiler->error;\n\n\tif ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {\n\t\ttmp_ar = reg_ar;\n\t\tdelay_slot = reg_ar;\n\t}\n\telse {\n\t\ttmp_ar = DR(TMP_REG1);\n\t\tdelay_slot = MOVABLE_INS;\n\t}\n\tbase = arg & REG_MASK;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(argw)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));\n\t\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);\n\t}\n\n\tFAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));\n\n\tif (base != 0)\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));\n\n\treturn push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)\n{\n\tif (getput_arg_fast(compiler, flags, reg_ar, arg1, arg1w))\n\t\treturn compiler->error;\n\treturn getput_arg(compiler, flags, reg_ar, arg1, arg1w, arg2, arg2w);\n}\n\n#define EMIT_LOGICAL(op_imm, op_reg) \\\n\tif (flags & SRC2_IMM) { \\\n\t\tif (op & SLJIT_SET_Z) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \\\n\t\tif (!(flags & UNUSED_DEST)) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \\\n\t} \\\n\telse { \\\n\t\tif (op & SLJIT_SET_Z) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \\\n\t\tif (!(flags & UNUSED_DEST)) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \\\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\n#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \\\n\top_imm = (imm); \\\n\top_v = (v);\n\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\n\n#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \\\n\top_dimm = (dimm); \\\n\top_dimm32 = (dimm32); \\\n\top_imm = (imm); \\\n\top_dv = (dv); \\\n\top_v = (v);\n\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)\n\nstatic sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n\tsljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tsljit_ins word_size = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tsljit_ins word_size = 32;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\t/* The TMP_REG2 is the next value. */\n\tif (src != TMP_REG2)\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));\n\n\tFAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));\n\t/* The OTHER_FLAG is the counter. Delay slot. */\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG));\n\n\tif (!is_clz) {\n\t\tFAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));\n\n\t/* Delay slot. */\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));\n\n\t/* The TMP_REG1 is the next shift. */\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1)));\n\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));\n\n\tFAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG1) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));\n\t/* Delay slot. */\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG2) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));\n\n\tFAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));\n\t/* Delay slot. */\n\tFAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));\n\n\treturn push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));\n}\n\n#endif /* SLJIT_MIPS_REV < 1 */\n\nstatic sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64\n\tint is_32 = (op & SLJIT_32);\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\top = GET_OPCODE(op);\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64\n\tif (!is_32 && (op == SLJIT_REV)) {\n\t\tFAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));\n\t\treturn push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst));\n\t}\n\tif (op != SLJIT_REV && src != TMP_REG2) {\n\t\tFAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tsrc = TMP_REG1;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\tFAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));\n\tFAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst)));\n#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64\n\tif (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3)\n\t\tFAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst)));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n#else /* SLJIT_MIPS_REV < 2 */\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (!is_32) {\n\t\tFAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));\n\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG));\n\t\tFAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));\n\n\t\tFAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));\n\t\tFAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG));\n\t\tFAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\tFAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));\n\n\t\tFAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));\n\t\treturn push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));\n\t}\n\n\tif (op != SLJIT_REV && src != TMP_REG2) {\n\t\tFAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2)));\n\t\tsrc = TMP_REG2;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\tFAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));\n\tFAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst)));\n\tFAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));\n\tFAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));\n\n\tFAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));\n\tFAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));\n\tFAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) {\n\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));\n\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n#endif /* SLJIT_MIPR_REV >= 2 */\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32\n\tFAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tFAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\tif (GET_OPCODE(op) == SLJIT_REV_U16)\n\t\treturn push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst));\n\telse\n\t\treturn push_inst(compiler, SEH | T(dst) | D(dst), DR(dst));\n#else /* SLJIT_MIPS_REV < 2 */\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst)));\n\tFAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SELECT_OP(DSRL32, SRL) : SELECT_OP(DSRA32, SRA)) | T(dst) | D(dst) | SH_IMM(16), DR(dst)));\n\treturn push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_s32 src1, sljit_sw src2)\n{\n\tsljit_s32 is_overflow, is_carry, carry_src_ar, is_handled, reg;\n\tsljit_ins op_imm, op_v;\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tsljit_ins ins, op_dimm, op_dimm32, op_dv;\n#endif\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tif (dst != src2)\n\t\t\treturn push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\t\t\treturn push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));\n#else /* SLJIT_MIPS_REV < 2 */\n\t\t\tFAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));\n\t\t\treturn push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n#else /* !SLJIT_CONFIG_MIPS_32 */\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\t\t\tif (op & SLJIT_32)\n\t\t\t\treturn push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));\n\t\t\treturn push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\t\t\treturn push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));\n#else /* SLJIT_MIPS_REV < 2 */\n\t\t\tFAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));\n\t\t\treturn push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n#else /* !SLJIT_CONFIG_MIPS_32 */\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\t\t\tif (op & SLJIT_32)\n\t\t\t\treturn push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));\n\t\t\treturn push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tcase SLJIT_MOV_U32:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\t\t\tif (dst == src2)\n\t\t\t\treturn push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));\n\t\t\treturn push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\treturn push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\treturn push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));\n#else /* SLJIT_MIPS_REV < 6 */\n\t\treturn push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));\n#else /* SLJIT_MIPS_REV < 6 */\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));\n\t\treturn push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));\n#else /* SLJIT_MIPS_REV < 1 */\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\treturn emit_clz_ctz(compiler, op, dst, src2);\n#endif /* SLJIT_MIPS_REV >= 1 */\n\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1);\n\t\treturn emit_rev(compiler, op, dst, src2);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));\n\t\treturn emit_rev16(compiler, op, dst, src2);\n\n\tcase SLJIT_ADD:\n\t\t/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tcarry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t}\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));\n\t\t}\n\t\telse {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n\t\t\tif (is_overflow || carry_src_ar != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_ar = DR(src1);\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_ar = DR(src2);\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\t\t\tcarry_src_ar = OTHER_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (is_overflow || carry_src_ar != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));\n\t\treturn push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);\n\n\tcase SLJIT_ADDC:\n\t\tcarry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));\n\t\t} else {\n\t\t\tif (carry_src_ar != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_ar = DR(src1);\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_ar = DR(src2);\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t\t\tcarry_src_ar = EQUAL_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (carry_src_ar != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));\n\n\t\tif (carry_src_ar == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\t/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */\n\t\tFAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t/* Set carry flag. */\n\t\treturn push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);\n\n\tcase SLJIT_SUB:\n\t\tif ((flags & SRC2_IMM) && src2 == SIMM_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_handled = 0;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (GET_FLAG_TYPE(op) == SLJIT_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));\n\t\t\t\tis_handled = 1;\n\t\t\t}\n\t\t\telse if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));\n\t\t\t\tis_handled = 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {\n\t\t\tis_handled = 1;\n\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\treg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(reg) | IMM(src2), DR(reg)));\n\t\t\t\tsrc2 = reg;\n\t\t\t\tflags &= ~SRC2_IMM;\n\t\t\t}\n\n\t\t\tswitch (GET_FLAG_TYPE(op)) {\n\t\t\tcase SLJIT_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (is_handled) {\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));\n\t\t\t\tif (!(flags & UNUSED_DEST))\n\t\t\t\t\treturn push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t\tif (!(flags & UNUSED_DEST))\n\t\t\t\t\treturn push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));\n\t\t\t}\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\t}\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));\n\t\t}\n\t\telse {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));\n\t\treturn push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);\n\n\tcase SLJIT_SUBC:\n\t\tif ((flags & SRC2_IMM) && src2 == SIMM_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));\n\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));\n\t\t}\n\t\telse {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));\n\t\t}\n\n\t\tif (is_carry)\n\t\t\tFAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));\n\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));\n\n\t\tif (!is_carry)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);\n\n\tcase SLJIT_MUL:\n\t\tSLJIT_ASSERT(!(flags & SRC2_IMM));\n\n\t\tif (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\t\treturn push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));\n#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\t\treturn push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t\tif (op & SLJIT_32)\n\t\t\t\treturn push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));\n\t\t\tFAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));\n\t\t\treturn push_inst(compiler, MFLO | D(dst), DR(dst));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n#else /* SLJIT_MIPS_REV < 1 */\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));\n\t\t\treturn push_inst(compiler, MFLO | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\t\t}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n#else /* SLJIT_MIPS_REV < 6 */\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));\n\t\tFAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\tFAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));\n\t\treturn push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);\n\n\tcase SLJIT_AND:\n\t\tEMIT_LOGICAL(ANDI, AND);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_OR:\n\t\tEMIT_LOGICAL(ORI, OR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_XOR:\n\t\tif (!(flags & LOGICAL_OP)) {\n\t\t\tSLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1);\n\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\t\t\tif (!(flags & UNUSED_DEST))\n\t\t\t\tFAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst)));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\tEMIT_LOGICAL(XORI, XOR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tEMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);\n\t\tbreak;\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tEMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);\n\t\tbreak;\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tEMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);\n\t\tbreak;\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\tcase SLJIT_ROTL:\n\t\tif ((flags & SRC2_IMM) || src2 == 0) {\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\t\tsrc2 = -src2 & 0x1f;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t\tsrc2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ROTR:\n\t\tEMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);\n\t\tbreak;\n#else /* SLJIT_MIPS_REV < 1 */\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (flags & SRC2_IMM) {\n\t\t\tSLJIT_ASSERT(src2 != 0);\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\t\tif (!(op & SLJIT_32)) {\n\t\t\t\tif (GET_OPCODE(op) == SLJIT_ROTL)\n\t\t\t\t\top_imm = ((src2 < 32) ? DSLL : DSLL32);\n\t\t\t\telse\n\t\t\t\t\top_imm = ((src2 < 32) ? DSRL : DSRL32);\n\n\t\t\t\tFAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));\n\n\t\t\t\tsrc2 = 64 - src2;\n\t\t\t\tif (GET_OPCODE(op) == SLJIT_ROTL)\n\t\t\t\t\top_imm = ((src2 < 32) ? DSRL : DSRL32);\n\t\t\t\telse\n\t\t\t\t\top_imm = ((src2 < 32) ? DSLL : DSLL32);\n\n\t\t\t\tFAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));\n\t\t\t\treturn push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));\n\t\t\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\t\t\top_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));\n\n\t\t\tsrc2 = 32 - src2;\n\t\t\top_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));\n\t\t\treturn push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));\n\t\t}\n\n\t\tif (src2 == 0) {\n\t\t\tif (dst != src1)\n\t\t\t\treturn push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tif (!(op & SLJIT_32)) {\n\t\t\top_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;\n\t\t\tFAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\t\top_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;\n\t\t\tFAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));\n\t\t\treturn push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));\n\t\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\t\top_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;\n\t\tFAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));\n\t\top_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;\n\t\tFAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));\n\t\treturn push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));\n#endif /* SLJIT_MIPS_REV >= 2 */\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tif ((flags & SRC2_IMM) || src2 == 0) {\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));\n\n\t\tif (flags & UNUSED_DEST)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));\n\t}\n\n\tif (op & SLJIT_SET_Z)\n\t\tFAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n\tif (flags & UNUSED_DEST)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tif ((flags & SRC2_IMM) || src2 == 0) {\n\t\tif (src2 >= 32) {\n\t\t\tSLJIT_ASSERT(!(op & SLJIT_32));\n\t\t\tins = op_dimm32;\n\t\t\tsrc2 -= 32;\n\t\t}\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? op_imm : op_dimm;\n\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));\n\n\t\tif (flags & UNUSED_DEST)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));\n\t}\n\n\tins = (op & SLJIT_32) ? op_v : op_dv;\n\tif (op & SLJIT_SET_Z)\n\t\tFAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));\n\n\tif (flags & UNUSED_DEST)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n}\n\n#define CHECK_IMM(flags, srcw) \\\n\t((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \\\n\t\t|| (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* arg1 goes to TMP_REG1 or src reg\n\t   arg2 goes to TMP_REG2, imm or src reg\n\t   TMP_REG3 can be used for caching\n\t   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */\n\tsljit_s32 dst_r = TMP_REG2;\n\tsljit_s32 src1_r;\n\tsljit_sw src2_r = 0;\n\tsljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;\n\n\tif (!(flags & ALT_KEEP_CACHE)) {\n\t\tcompiler->cache_arg = 0;\n\t\tcompiler->cache_argw = 0;\n\t}\n\n\tif (dst == 0) {\n\t\tSLJIT_ASSERT(HAS_FLAGS(op));\n\t\tflags |= UNUSED_DEST;\n\t\tdst = TMP_REG2;\n\t}\n\telse if (FAST_IS_REG(dst)) {\n\t\tdst_r = dst;\n\t\tflags |= REG_DEST;\n\t\tif (flags & MOVE_OP)\n\t\t\tsrc2_tmp_reg = dst_r;\n\t}\n\telse if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))\n\t\tflags |= SLOW_DEST;\n\n\tif (flags & IMM_OP) {\n\t\tif (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src2w;\n\t\t} else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src1w;\n\n\t\t\t/* And swap arguments. */\n\t\t\tsrc1 = src2;\n\t\t\tsrc1w = src2w;\n\t\t\tsrc2 = SLJIT_IMM;\n\t\t\t/* src2w = src2_r unneeded. */\n\t\t}\n\t}\n\n\t/* Source 1. */\n\tif (FAST_IS_REG(src1)) {\n\t\tsrc1_r = src1;\n\t\tflags |= REG1_SOURCE;\n\t}\n\telse if (src1 == SLJIT_IMM) {\n\t\tif (src1w) {\n\t\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));\n\t\t\tsrc1_r = TMP_REG1;\n\t\t}\n\t\telse\n\t\t\tsrc1_r = 0;\n\t}\n\telse {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC1;\n\t\tsrc1_r = TMP_REG1;\n\t}\n\n\t/* Source 2. */\n\tif (FAST_IS_REG(src2)) {\n\t\tsrc2_r = src2;\n\t\tflags |= REG2_SOURCE;\n\t\tif ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)\n\t\t\tdst_r = (sljit_s32)src2_r;\n\t}\n\telse if (src2 == SLJIT_IMM) {\n\t\tif (!(flags & SRC2_IMM)) {\n\t\t\tif (src2w) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w));\n\t\t\t\tsrc2_r = src2_tmp_reg;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsrc2_r = 0;\n\t\t\t\tif (flags & MOVE_OP) {\n\t\t\t\t\tif (dst & SLJIT_MEM)\n\t\t\t\t\t\tdst_r = 0;\n\t\t\t\t\telse\n\t\t\t\t\t\top = SLJIT_MOV;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC2;\n\t\tsrc2_r = src2_tmp_reg;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tSLJIT_ASSERT(src2_r == TMP_REG2);\n\t\tif ((flags & SLOW_DEST) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));\n\t\t}\n\t\telse {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w, dst, dstw));\n\n\tFAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));\n\n\tif (dst & SLJIT_MEM) {\n\t\tif (!(flags & SLOW_DEST)) {\n\t\t\tgetput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);\n\t\t\treturn compiler->error;\n\t\t}\n\t\treturn getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef CHECK_IMM\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tsljit_s32 int_op = op & SLJIT_32;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\t\treturn push_inst(compiler, BREAK, UNMOVABLE_INS);\n\tcase SLJIT_NOP:\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));\n\t\treturn push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));\n#else /* SLJIT_MIPS_REV < 6 */\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));\n\t\treturn push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n\t\tSLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tif (int_op) {\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t}\n\t\telse {\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t}\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));\n\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));\n\t\treturn (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));\n#else /* SLJIT_MIPS_REV < 6 */\n#if !(defined SLJIT_MIPS_REV)\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* !SLJIT_MIPS_REV */\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tif (int_op)\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\t\tFAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));\n\t\treturn (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\tcase SLJIT_MEMORY_BARRIER:\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n\t\treturn push_inst(compiler, SYNC, UNMOVABLE_INS);\n#else /* SLJIT_MIPS_REV < 1 */\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_MIPS_REV >= 1 */\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\nstatic sljit_s32 emit_prefetch(struct sljit_compiler *compiler,\n        sljit_s32 src, sljit_sw srcw)\n{\n\tif (!(src & OFFS_REG_MASK)) {\n\t\tif (srcw <= SIMM_MAX && srcw >= SIMM_MIN)\n\t\t\treturn push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);\n\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));\n\t\treturn push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);\n\t}\n\n\tsrcw &= 0x3;\n\n\tif (SLJIT_UNLIKELY(srcw != 0)) {\n\t\tFAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));\n\t\treturn push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);\n\t}\n\n\treturn push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);\n}\n#endif /* SLJIT_MIPS_REV >= 1 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (op & SLJIT_32)\n\t\tflags = INT_DATA | SIGNED_DATA;\n#endif\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n#endif\n\tcase SLJIT_MOV_P:\n\t\treturn emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tcase SLJIT_MOV_U32:\n\t\treturn emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);\n\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\treturn emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);\n#endif\n\n\tcase SLJIT_MOV_U8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);\n\n\tcase SLJIT_MOV_S8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);\n\n\tcase SLJIT_MOV_U16:\n\t\treturn emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);\n\n\tcase SLJIT_MOV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\tcase SLJIT_REV:\n\t\treturn emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw);\n\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\treturn emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (op & SLJIT_32) {\n\t\tflags |= INT_DATA | SIGNED_DATA;\n\t\tif (src1 == SLJIT_IMM)\n\t\t\tsrc1w = (sljit_s32)src1w;\n\t\tif (src2 == SLJIT_IMM)\n\t\t\tsrc2w = (sljit_s32)src2w;\n\t}\n#endif\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SUB:\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_MUL:\n\t\tcompiler->status_flags_state = 0;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_XOR:\n\t\tif ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {\n\t\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\tif (src2 == SLJIT_IMM)\n\t\t\tsrc2w &= 0x1f;\n#else\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tif (op & SLJIT_32)\n\t\t\t\tsrc2w &= 0x1f;\n\t\t\telse\n\t\t\t\tsrc2w &= 0x3f;\n\t\t}\n#endif\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);\n}\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n#define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))\n#else /* !SLJIT_CONFIG_MIPS_64 */\n#define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));\n\t\treturn push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst_reg) | T(TMP_REG2) | D(dst_reg), DR(dst_reg));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_left;\n\tsljit_ins ins1, ins2, ins3;\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tsljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\tsljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tsljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n\tsljit_sw bit_length = 32;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= bit_length - 1;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (is_left) {\n\t\t\tins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);\n\t\t} else {\n\t\t\tins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg)));\n\t\tFAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));\n\t\treturn push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w));\n\t\tsrc3 = TMP_REG2;\n\t} else if (dst_reg == src3) {\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (is_left) {\n\t\tins1 = SELECT_OP(DSRL, SRL);\n\t\tins2 = SELECT_OP(DSLLV, SLLV);\n\t\tins3 = SELECT_OP(DSRLV, SRLV);\n\t} else {\n\t\tins1 = SELECT_OP(DSLL, SLL);\n\t\tins2 = SELECT_OP(DSRLV, SRLV);\n\t\tins3 = SELECT_OP(DSLLV, SLLV);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg)));\n\n\tif (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {\n\t\tFAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));\n\t\tsrc2_reg = TMP_REG1;\n\t} else\n\t\tFAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2)));\n\n\tFAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));\n\treturn push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));\n\t\tsrc2 = TMP_REG2;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tFAIL_IF(push_inst(compiler, (shift_arg >= 32 ? DSLL32 : DSLL) | T(src2) | D(tmp_r) | SH_IMM(shift_arg & 0x1f), DR(tmp_r)));\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tFAIL_IF(push_inst(compiler, SLL | T(src2) | D(tmp_r) | SH_IMM(shift_arg), DR(tmp_r)));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\tFAIL_IF(push_inst(compiler, ADDU_W | S(src1) | T(tmp_r) | D(dst_r), DR(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, WORD_DATA, DR(dst_r), dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\n#undef SELECT_OP3\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (DR(src) != RETURN_ADDR_REG)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));\n\n\t\tFAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\t\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)\n\t\treturn emit_prefetch(compiler, src, srcw);\n#else /* SLJIT_MIPS_REV < 1 */\n\t\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_MIPS_REV >= 1 */\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 dst_ar = RETURN_ADDR_REG;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (DR(dst) == RETURN_ADDR_REG)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);\n\t\t}\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_ar, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw));\n\n\t\tif (op == SLJIT_FAST_ENTER)\n\t\t\tcompiler->delay_slot = UNMOVABLE_INS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type != SLJIT_FLOAT_REGISTER)\n\t\treturn -1;\n\n\treturn FR(reg);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))\n#define FMT(op) (FMT_S | (~(sljit_ins)op & SLJIT_32) << (21 - (5 + 3)))\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_u32 flags = 0;\n#else\n\tsljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;\n#endif\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));\n\n\tif (FAST_IS_REG(dst)) {\n\t\tFAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_u32 flags = 0;\n#else\n\tsljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;\n#endif\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));\n\telse {\n\t\tif (src == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)\n\t\t\t\tsrcw = (sljit_s32)srcw;\n#endif\n\t\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t}\n\n\tFAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_u32 flags = 0;\n#else\n\tsljit_u32 flags = 1 << 21;\n#endif\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW ? WORD_DATA : INT_DATA) | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));\n\t\tsrc = TMP_REG1;\n\t} else if (src == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32)\n\t\t\tsrcw = (sljit_u32)srcw;\n#endif\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {\n\t\tif (src != TMP_REG1) {\n\t\t\tFAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));\n\t\t\tFAIL_IF(push_inst(compiler, DSRL32 | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV)\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\n\t\tFAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tif (!(op & SLJIT_32)) {\n\t\tFAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));\n\t\tFAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));\n\n\t\tFAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG2) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\n\t\tFAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | 1 | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));\n\n#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)\n\t\tFAIL_IF(push_inst(compiler, BGEZ | S(src) | 5, UNMOVABLE_INS));\n#else /* SLJIT_MIPS_REV >= 1 */\n\t\tFAIL_IF(push_inst(compiler, BGEZ | S(src) | 4, UNMOVABLE_INS));\n#endif  /* SLJIT_MIPS_REV < 1 */\n\n\t\tFAIL_IF(push_inst(compiler, LUI | T(TMP_REG2) | IMM(0x41e0), UNMOVABLE_INS));\n\t\tFAIL_IF(push_inst(compiler, MTC1 | TA(0) | FS(TMP_FREG2), UNMOVABLE_INS));\n\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\tcase CPU_FEATURE_FR:\n\t\t\tFAIL_IF(push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(TMP_FREG2), UNMOVABLE_INS));\n\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\tdefault:\n\t\t\tFAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(TMP_FREG2) | (1 << 11), UNMOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\t\tbreak;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(TMP_FREG2) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)\n\tFAIL_IF(push_inst(compiler, BLTZ | S(src) | 5, UNMOVABLE_INS));\n#else /* SLJIT_MIPS_REV >= 1 */\n\tFAIL_IF(push_inst(compiler, BLTZ | S(src) | 4, UNMOVABLE_INS));\n#endif  /* SLJIT_MIPS_REV < 1 */\n\tFAIL_IF(push_inst(compiler, ANDI | S(src) | T(TMP_REG2) | IMM(1), DR(TMP_REG2)));\n\n\tFAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV)\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* !SLJIT_MIPS_REV */\n\n\tFAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));\n\n#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)\n\tFAIL_IF(push_inst(compiler, BEQ | 6, UNMOVABLE_INS));\n#else /* SLJIT_MIPS_REV >= 1 */\n\tFAIL_IF(push_inst(compiler, BEQ | 5, UNMOVABLE_INS));\n#endif  /* SLJIT_MIPS_REV < 1 */\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tFAIL_IF(push_inst(compiler, DSRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tFAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\tFAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1)));\n\n\tFAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV)\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* !SLJIT_MIPS_REV */\n\n\tFAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));\n\tFAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(dst_r) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_ins inst;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tswitch (GET_FLAG_TYPE(op)) {\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\t\tinst = C_EQ_S;\n\t\tbreak;\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\tinst = C_UEQ_S;\n\t\tbreak;\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\tinst = C_OLT_S;\n\t\tbreak;\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\tinst = C_ULT_S;\n\t\tbreak;\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\tinst = C_ULE_S;\n\t\tbreak;\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tinst = C_OLE_S;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED);\n\t\tinst = C_UN_S;\n\t\tbreak;\n\t}\n\treturn push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\t/* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */\n\t\tFAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));\n\t\top ^= SLJIT_32;\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r, flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc1 = TMP_FREG1;\n\t\t} else\n\t\t\tflags |= SLOW_SRC1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc2 = TMP_FREG2;\n\t\t} else\n\t\t\tflags |= SLOW_SRC2;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tif ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));\n\t\t} else {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));\n\n\tif (flags & SLOW_SRC1)\n\t\tsrc1 = TMP_FREG1;\n\tif (flags & SLOW_SRC2)\n\t\tsrc2 = TMP_FREG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));\n\t\tbreak;\n\tcase SLJIT_COPYSIGN_F64:\n\t\treturn emit_copysign(compiler, op, src1, src2, dst_r);\n\t}\n\n\tif (dst_r == TMP_FREG2)\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS);\n\n\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));\n\treturn push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\tcompiler->delay_slot = UNMOVABLE_INS;\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define BRANCH_LENGTH\t4\n#else\n#define BRANCH_LENGTH\t8\n#endif\n\n#define BR_Z(src) \\\n\tinst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \\\n\tflags = IS_BIT26_COND; \\\n\tdelay_check = src;\n\n#define BR_NZ(src) \\\n\tinst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \\\n\tflags = IS_BIT26_COND; \\\n\tdelay_check = src;\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\n#define BR_T() \\\n\tinst = BC1NEZ; \\\n\tflags = IS_BIT23_COND; \\\n\tdelay_check = FCSR_FCC;\n#define BR_F() \\\n\tinst = BC1EQZ; \\\n\tflags = IS_BIT23_COND; \\\n\tdelay_check = FCSR_FCC;\n\n#else /* SLJIT_MIPS_REV < 6 */\n\n#define BR_T() \\\n\tinst = BC1T | BRANCH_LENGTH; \\\n\tflags = IS_BIT16_COND; \\\n\tdelay_check = FCSR_FCC;\n#define BR_F() \\\n\tinst = BC1F | BRANCH_LENGTH; \\\n\tflags = IS_BIT16_COND; \\\n\tdelay_check = FCSR_FCC;\n\n#endif /* SLJIT_MIPS_REV >= 6 */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins inst;\n\tsljit_u32 flags = 0;\n\tsljit_s32 delay_check = UNMOVABLE_INS;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\tBR_NZ(EQUAL_FLAG);\n\t\tbreak;\n\tcase SLJIT_NOT_EQUAL:\n\t\tBR_Z(EQUAL_FLAG);\n\t\tbreak;\n\tcase SLJIT_LESS:\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_OVERFLOW:\n\tcase SLJIT_CARRY:\n\tcase SLJIT_ATOMIC_STORED:\n\t\tBR_Z(OTHER_FLAG);\n\t\tbreak;\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_NOT_OVERFLOW:\n\tcase SLJIT_NOT_CARRY:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\tBR_NZ(OTHER_FLAG);\n\t\tbreak;\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\tcase SLJIT_ORDERED:\n\t\tBR_T();\n\t\tbreak;\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_UNORDERED:\n\t\tBR_F();\n\t\tbreak;\n\tdefault:\n\t\t/* Not conditional branch. */\n\t\tinst = 0;\n\t\tbreak;\n\t}\n\n\tjump->flags |= flags;\n\tif (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))\n\t\tjump->flags |= IS_MOVABLE;\n\n\tif (inst)\n\t\tPTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));\n\n\tif (type <= SLJIT_JUMP)\n\t\tPTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\telse {\n\t\tjump->flags |= IS_JAL;\n\t\tPTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\t}\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\n\t/* Maximum number of instructions required for generating a constant. */\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tcompiler->size += 2;\n#else\n\tcompiler->size += 6;\n#endif\n\treturn jump;\n}\n\n#define RESOLVE_IMM1() \\\n\tif (src1 == SLJIT_IMM) { \\\n\t\tif (src1w) { \\\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \\\n\t\t\tsrc1 = TMP_REG1; \\\n\t\t} \\\n\t\telse \\\n\t\t\tsrc1 = 0; \\\n\t}\n\n#define RESOLVE_IMM2() \\\n\tif (src2 == SLJIT_IMM) { \\\n\t\tif (src2w) { \\\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w)); \\\n\t\t\tsrc2 = src2_tmp_reg; \\\n\t\t} \\\n\t\telse \\\n\t\t\tsrc2 = 0; \\\n\t}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 flags;\n\tsljit_ins inst;\n\tsljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tflags = WORD_DATA | LOAD_DATA;\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tflags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n\tif (src1 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(src2_tmp_reg), src2, src2w, 0, 0));\n\t\tsrc2 = src2_tmp_reg;\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tif (type <= SLJIT_NOT_EQUAL) {\n\t\tRESOLVE_IMM1();\n\t\tRESOLVE_IMM2();\n\t\tjump->flags |= IS_BIT26_COND;\n\t\tif (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))\n\t\t\tjump->flags |= IS_MOVABLE;\n\t\tPTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS));\n\t} else if (type >= SLJIT_SIG_LESS && ((src1 == SLJIT_IMM && src1w == 0) || (src2 == SLJIT_IMM && src2w == 0))) {\n\t\tinst = NOP;\n\t\tif (src1 == SLJIT_IMM && src1w == 0) {\n\t\t\tRESOLVE_IMM2();\n\t\t\tswitch (type) {\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tinst = BLEZ;\n\t\t\t\tjump->flags |= IS_BIT26_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\t\t\tinst = BGTZ;\n\t\t\t\tjump->flags |= IS_BIT26_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER:\n\t\t\t\tinst = BGEZ;\n\t\t\t\tjump->flags |= IS_BIT16_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\t\tinst = BLTZ;\n\t\t\t\tjump->flags |= IS_BIT16_COND;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsrc1 = src2;\n\t\t}\n\t\telse {\n\t\t\tRESOLVE_IMM1();\n\t\t\tswitch (type) {\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tinst = BGEZ;\n\t\t\t\tjump->flags |= IS_BIT16_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\t\t\tinst = BLTZ;\n\t\t\t\tjump->flags |= IS_BIT16_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER:\n\t\t\t\tinst = BLEZ;\n\t\t\t\tjump->flags |= IS_BIT26_COND;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\t\tinst = BGTZ;\n\t\t\t\tjump->flags |= IS_BIT26_COND;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tPTR_FAIL_IF(push_inst(compiler, inst | S(src1) | BRANCH_LENGTH, UNMOVABLE_INS));\n\t}\n\telse {\n\t\tif (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {\n\t\t\tRESOLVE_IMM1();\n\t\t\tif (src2 == SLJIT_IMM && src2w <= SIMM_MAX && src2w >= SIMM_MIN)\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));\n\t\t\telse {\n\t\t\t\tRESOLVE_IMM2();\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t\t}\n\t\t\ttype = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;\n\t\t}\n\t\telse {\n\t\t\tRESOLVE_IMM2();\n\t\t\tif (src1 == SLJIT_IMM && src1w <= SIMM_MAX && src1w >= SIMM_MIN)\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));\n\t\t\telse {\n\t\t\t\tRESOLVE_IMM1();\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t\t}\n\t\t\ttype = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;\n\t\t}\n\n\t\tjump->flags |= IS_BIT26_COND;\n\t\tPTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));\n\t}\n\n\tPTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n\n\t/* Maximum number of instructions required for generating a constant. */\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tcompiler->size += 2;\n#else\n\tcompiler->size += 6;\n#endif\n\treturn jump;\n}\n\n#undef RESOLVE_IMM1\n#undef RESOLVE_IMM2\n\n#undef BRANCH_LENGTH\n#undef BR_Z\n#undef BR_NZ\n#undef BR_T\n#undef BR_F\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump = NULL;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src == SLJIT_IMM) {\n\t\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\t\tFAIL_IF(!jump);\n\t\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));\n\t\tjump->u.target = (sljit_uw)srcw;\n\n\t\tif (compiler->delay_slot != UNMOVABLE_INS)\n\t\t\tjump->flags |= IS_MOVABLE;\n\n\t\tsrc = PIC_ADDR_REG;\n\t} else if (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));\n\t\tsrc = PIC_ADDR_REG;\n\t}\n\n\tif (type <= SLJIT_JUMP)\n\t\tFAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));\n\telse\n\t\tFAIL_IF(push_inst(compiler, JALR | S(src) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));\n\n\tif (jump != NULL) {\n\t\tjump->addr = compiler->size;\n\n\t\t/* Maximum number of instructions required for generating a constant. */\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\tcompiler->size += 2;\n#else\n\t\tcompiler->size += 6;\n#endif\n\t}\n\n\treturn push_inst(compiler, NOP, UNMOVABLE_INS);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 src_ar, dst_ar, invert;\n\tsljit_s32 saved_op = op;\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_s32 mem_type = WORD_DATA;\n#else\n\tsljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\tdst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tif (op >= SLJIT_ADD && (dst & SLJIT_MEM))\n\t\tFAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));\n\n\tif (type < SLJIT_F_EQUAL) {\n\t\tsrc_ar = OTHER_FLAG;\n\t\tinvert = type & 0x1;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_EQUAL:\n\t\tcase SLJIT_NOT_EQUAL:\n\t\t\tFAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));\n\t\t\tsrc_ar = dst_ar;\n\t\t\tbreak;\n\t\tcase SLJIT_OVERFLOW:\n\t\tcase SLJIT_NOT_OVERFLOW:\n\t\t\tif (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {\n\t\t\t\tsrc_ar = OTHER_FLAG;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));\n\t\t\tsrc_ar = dst_ar;\n\t\t\tinvert ^= 0x1;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tinvert = 0;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_F_NOT_EQUAL:\n\t\tcase SLJIT_F_GREATER_EQUAL:\n\t\tcase SLJIT_F_GREATER:\n\t\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\tcase SLJIT_ORDERED_GREATER:\n\t\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tcase SLJIT_ORDERED:\n\t\t\tinvert = 1;\n\t\t\tbreak;\n\t\t}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\tFAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));\n#else /* SLJIT_MIPS_REV < 6 */\n\t\tFAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));\n#endif /* SLJIT_MIPS_REV >= 6 */\n\t\tFAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));\n\t\tFAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));\n\t\tsrc_ar = dst_ar;\n\t}\n\n\tif (invert) {\n\t\tFAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));\n\t\tsrc_ar = dst_ar;\n\t}\n\n\tif (op < SLJIT_ADD) {\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem(compiler, mem_type, src_ar, dst, dstw);\n\n\t\tif (src_ar != dst_ar)\n\t\t\treturn push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* OTHER_FLAG cannot be specified as src2 argument at the moment. */\n\tif (DR(TMP_REG2) != src_ar)\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));\n\n\tmem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);\n\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);\n}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)\n\nstatic sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\treturn (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG);\n\tcase SLJIT_NOT_EQUAL:\n\t\treturn (is_float ? MOVN_S : MOVN) | TA(EQUAL_FLAG);\n\tcase SLJIT_LESS:\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_OVERFLOW:\n\tcase SLJIT_CARRY:\n\t\treturn (is_float ? MOVN_S : MOVN) | TA(OTHER_FLAG);\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_NOT_OVERFLOW:\n\tcase SLJIT_NOT_CARRY:\n\t\treturn (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_UNORDERED:\n\t\treturn is_float ? MOVT_S : MOVT;\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\tcase SLJIT_ORDERED:\n\t\treturn is_float ? MOVF_S : MOVF;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);\n\t}\n}\n\n#endif /* SLJIT_MIPS_REV >= 1 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tsljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\tsljit_ins mov_ins = (type & SLJIT_32) ? ADDU : DADDU;\n#else /* !SLJIT_CONFIG_MIPS_64 */\n\tsljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n\tsljit_ins mov_ins = ADDU;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\tif (src1 == SLJIT_IMM && (type & SLJIT_32))\n\t\tsrc1w = (sljit_s32)src1w;\n#endif\n\n\ttype &= ~SLJIT_32;\n\n\tif (type & SLJIT_COMPARE_SELECT) {\n\t\ttype ^= SLJIT_COMPARE_SELECT;\n\n\t\tif (src1 & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));\n\t\t\tsrc1 = TMP_REG1;\n\t\t} else if (src1 == SLJIT_IMM) {\n\t\t\tif (src1w == 0) {\n\t\t\t\tsrc1 = 0;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t}\n\t\t}\n\n\t\tsrc1w = 0;\n\t\tFAIL_IF(emit_op(compiler, SLJIT_SUB | SLJIT_SET(type & ~0x1), IMM_OP, 0, 0, src1, 0, src2_reg, 0));\n\t}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));\n\t}\n\n\treturn push_inst(compiler, get_select_cc(type, 0) | S(src1) | D(dst_reg), DR(dst_reg));\n\n#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tif (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));\n\n\t\t\t\tif ((src1 & REG_MASK) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~REG_MASK) | TMP_REG1;\n\n\t\t\t\tif (OFFS_REG(src1) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));\n\t\t}\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tjump = sljit_emit_jump(compiler, type ^ 0x1);\n\tFAIL_IF(!jump);\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w));\n\t} else if (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, DR(dst_reg), src1w));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg)));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tlabel = sljit_emit_label(compiler);\n\tFAIL_IF(!label);\n\n\tsljit_set_label(jump, label);\n\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_MIPS_REV >= 1 */\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src2_freg) | FD(dst_freg), MOVABLE_INS));\n\t}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG2), src1, src1w));\n\t\tsrc1 = TMP_FREG2;\n\t}\n\n\treturn push_inst(compiler, get_select_cc(type & ~SLJIT_32, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);\n\n#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */\n\tSLJIT_SKIP_CHECKS(compiler);\n\tjump = sljit_emit_jump(compiler, type ^ 0x1);\n\tFAIL_IF(!jump);\n\n\tif (src1 & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(dst_freg), src1, src1w));\n\telse\n\t\tFAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src1) | FD(dst_freg), MOVABLE_INS));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tlabel = sljit_emit_label(compiler);\n\tFAIL_IF(!label);\n\n\tsljit_set_label(jump, label);\n\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_MIPS_REV >= 1 */\n}\n\n#undef FLOAT_DATA\n#undef FMT\n\nstatic sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset)\n{\n\tsljit_s32 arg = *mem;\n\tsljit_sw argw = *memw;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(argw)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(arg & REG_MASK) | T(OFFS_REG(arg)) | D(TMP_REG1), DR(TMP_REG1)));\n\n\t\t*mem = TMP_REG1;\n\t\t*memw = 0;\n\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (argw <= max_offset && argw >= SIMM_MIN) {\n\t\t*mem = arg & REG_MASK;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t*mem = TMP_REG1;\n\n\tif ((sljit_s16)argw > max_offset) {\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), argw));\n\t\t*memw = 0;\n\t} else {\n\t\tFAIL_IF(load_immediate(compiler, DR(TMP_REG1), TO_ARGW_HI(argw)));\n\t\t*memw = (sljit_s16)argw;\n\t}\n\n\tif ((arg & REG_MASK) == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1));\n}\n\n#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#define IMM_LEFT(memw)\t\t\tIMM((memw) + SSIZE_OF(sw) - 1)\n#define IMM_RIGHT(memw)\t\t\tIMM(memw)\n#define IMM_32_LEFT(memw)\t\tIMM((memw) + SSIZE_OF(s32) - 1)\n#define IMM_32_RIGHT(memw)\t\tIMM(memw)\n#define IMM_F64_FIRST_LEFT(memw)\tIMM((memw) + SSIZE_OF(s32) - 1)\n#define IMM_F64_FIRST_RIGHT(memw)\tIMM(memw)\n#define IMM_F64_SECOND_LEFT(memw)\tIMM((memw) + SSIZE_OF(f64) - 1)\n#define IMM_F64_SECOND_RIGHT(memw)\tIMM((memw) + SSIZE_OF(s32))\n#define IMM_16_FIRST(memw)\t\tIMM((memw) + 1)\n#define IMM_16_SECOND(memw)\t\tIMM(memw)\n#else /* !SLJIT_LITTLE_ENDIAN */\n#define IMM_LEFT(memw)\t\t\tIMM(memw)\n#define IMM_RIGHT(memw)\t\t\tIMM((memw) + SSIZE_OF(sw) - 1)\n#define IMM_32_LEFT(memw)\t\tIMM(memw)\n#define IMM_32_RIGHT(memw)\t\tIMM((memw) + SSIZE_OF(s32) - 1)\n#define IMM_F64_FIRST_LEFT(memw)\tIMM((memw) + SSIZE_OF(s32))\n#define IMM_F64_FIRST_RIGHT(memw)\tIMM((memw) + SSIZE_OF(f64) - 1)\n#define IMM_F64_SECOND_LEFT(memw)\tIMM(memw)\n#define IMM_F64_SECOND_RIGHT(memw)\tIMM((memw) + SSIZE_OF(s32) - 1)\n#define IMM_16_FIRST(memw)\t\tIMM(memw)\n#define IMM_16_SECOND(memw)\t\tIMM((memw) + 1)\n#endif /* SLJIT_LITTLE_ENDIAN */\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16))\n#else /* !SLJIT_CONFIG_MIPS_32 */\n#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 op = type & 0xff;\n\tsljit_s32 flags = 0;\n\tsljit_ins ins;\n#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\tsljit_ins ins_right;\n#endif /* !(SLJIT_MIPS_REV >= 6) */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (reg & REG_PAIR_MASK) {\n\t\tADJUST_LOCAL_OFFSET(mem, memw);\n\n#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\t\tif (MEM_CHECK_UNALIGNED(type)) {\n\t\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (2 * SSIZE_OF(sw) - 1)));\n\n\t\t\tif (!(type & SLJIT_MEM_STORE) && (mem == REG_PAIR_FIRST(reg) || mem == REG_PAIR_SECOND(reg))) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t\t\tmem = TMP_REG1;\n\t\t\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\t\tins = ((type & SLJIT_MEM_STORE) ? SWL : LWL) | S(mem);\n\t\t\tins_right = ((type & SLJIT_MEM_STORE) ? SWR : LWR) | S(mem);\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\t\tins = ((type & SLJIT_MEM_STORE) ? SDL : LDL) | S(mem);\n\t\t\tins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem);\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\n\t\t\tFAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM_LEFT(memw), DR(REG_PAIR_FIRST(reg))));\n\t\t\tFAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM_RIGHT(memw), DR(REG_PAIR_FIRST(reg))));\n\t\t\tFAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM_LEFT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));\n\t\t\treturn push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM_RIGHT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));\n\t\t}\n#endif /* !(SLJIT_MIPS_REV >= 6) */\n\n\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - SSIZE_OF(sw)));\n\n\t\tins = ((type & SLJIT_MEM_STORE) ? STORE_W : LOAD_W) | S(mem);\n\n\t\tif (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {\n\t\t\tFAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));\n\t\t\treturn push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));\n\t\treturn push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));\n\t}\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n#else /* !(SLJIT_MIPS_REV >= 6) */\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tswitch (op) {\n\tcase SLJIT_MOV_U8:\n\tcase SLJIT_MOV_S8:\n\t\tflags = BYTE_DATA;\n\t\tif (!(type & SLJIT_MEM_STORE))\n\t\t\tflags |= LOAD_DATA;\n\n\t\tif (op == SLJIT_MOV_S8)\n\t\t\tflags |= SIGNED_DATA;\n\n\t\treturn emit_op_mem(compiler, flags, DR(reg), mem, memw);\n\n\tcase SLJIT_MOV_U16:\n\tcase SLJIT_MOV_S16:\n\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 1));\n\t\tSLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);\n\n\t\tif (type & SLJIT_MEM_STORE) {\n\t\t\tFAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));\n\t\t\tFAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), MOVABLE_INS));\n\t\t\treturn push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), MOVABLE_INS);\n\t\t}\n\n\t\tflags = BYTE_DATA | LOAD_DATA;\n\n\t\tif (op == SLJIT_MOV_S16)\n\t\t\tflags |= SIGNED_DATA;\n\n\t\tFAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), DR(TMP_REG2)));\n\t\tFAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), DR(reg)));\n\t\tFAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));\n\t\treturn push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg));\n\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\tif (type & SLJIT_MEM_ALIGNED_32) {\n\t\t\tflags = WORD_DATA;\n\t\t\tif (!(type & SLJIT_MEM_STORE))\n\t\t\t\tflags |= LOAD_DATA;\n\n\t\t\treturn emit_op_mem(compiler, flags, DR(reg), mem, memw);\n\t\t}\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 7));\n\t\tSLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);\n\n\t\tif (type & SLJIT_MEM_STORE) {\n\t\t\tFAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM_LEFT(memw), MOVABLE_INS));\n\t\t\treturn push_inst(compiler, SDR | S(mem) | T(reg) | IMM_RIGHT(memw), MOVABLE_INS);\n\t\t}\n\n\t\tif (mem == reg) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));\n\t\t\tmem = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM_LEFT(memw), DR(reg)));\n\t\treturn push_inst(compiler, LDR | S(mem) | T(reg) | IMM_RIGHT(memw), DR(reg));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t}\n\n\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 3));\n\tSLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);\n\n\tif (type & SLJIT_MEM_STORE) {\n\t\tFAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM_32_LEFT(memw), MOVABLE_INS));\n\t\treturn push_inst(compiler, SWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), MOVABLE_INS);\n\t}\n\n\tif (mem == reg) {\n\t\tFAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));\n\t\tmem = TMP_REG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM_32_LEFT(memw), DR(reg)));\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\treturn push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg));\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tFAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg)));\n\n\tif (op != SLJIT_MOV_U32)\n\t\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)\n\treturn push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11), DR(reg));\n#else  /* SLJIT_MIPS_REV < 2 */\n\tFAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)));\n\treturn push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg));\n#endif /* SLJIT_MIPS_REV >= 2 */\n#endif /* SLJIT_CONFIG_MIPS_32 */\n#endif /* SLJIT_MIPS_REV >= 6 */\n}\n\n#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));\n\n\tFAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (type & SLJIT_32) ? 3 : 7));\n\tSLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);\n\n\tif (type & SLJIT_MEM_STORE) {\n\t\tif (type & SLJIT_32) {\n\t\t\tFAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));\n#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)\n\t\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\t\tFAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), MOVABLE_INS));\n\t\t\treturn push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), MOVABLE_INS);\n\t\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\t\tFAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\tFAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), MOVABLE_INS));\n\t\tFAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), MOVABLE_INS));\n\t\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\t\tcase CPU_FEATURE_FR:\n\t\t\tFAIL_IF(push_inst(compiler, MFHC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));\n\t\t\tbreak;\n#endif /* SLJIT_MIPS_REV >= 2 */\n\t\tdefault:\n\t\t\tFAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg) | (1 << 11), DR(TMP_REG2)));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), MOVABLE_INS));\n\t\treturn push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), MOVABLE_INS);\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\t\tFAIL_IF(push_inst(compiler, DMFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\tFAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), MOVABLE_INS));\n\t\treturn push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), MOVABLE_INS);\n#endif /* SLJIT_CONFIG_MIPS_32 */\n\t}\n\n\tif (type & SLJIT_32) {\n\t\tFAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), DR(TMP_REG2)));\n\t\tFAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), DR(TMP_REG2)));\n\n\t\tFAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));\n#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)\n\t\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tFAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));\n\n\tFAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), DR(TMP_REG2)));\n\tswitch (cpu_feature_list & CPU_FEATURE_FR) {\n#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2\n\tcase CPU_FEATURE_FR:\n\t\treturn push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS);\n#endif /* SLJIT_MIPS_REV >= 2 */\n\tdefault:\n\t\tFAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg) | (1 << 11), MOVABLE_INS));\n\t\tbreak;\n\t}\n#else /* !SLJIT_CONFIG_MIPS_32 */\n\tFAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), DR(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), DR(TMP_REG2)));\n\n\tFAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));\n#endif /* SLJIT_CONFIG_MIPS_32 */\n#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1\n\tFAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));\n#endif /* MIPS III */\n\treturn SLJIT_SUCCESS;\n}\n\n#endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */\n\n#undef IMM_16_SECOND\n#undef IMM_16_FIRST\n#undef IMM_F64_SECOND_RIGHT\n#undef IMM_F64_SECOND_LEFT\n#undef IMM_F64_FIRST_RIGHT\n#undef IMM_F64_FIRST_LEFT\n#undef IMM_32_RIGHT\n#undef IMM_32_LEFT\n#undef IMM_RIGHT\n#undef IMM_LEFT\n#undef MEM_CHECK_UNALIGNED\n\n#undef TO_ARGW_HI\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tins = LLD;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\tins = LL;\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | T(dst_reg) | S(mem_reg), DR(dst_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\n\t/* temp_reg == mem_reg is undefined so use another temp register */\n\tSLJIT_UNUSED_ARG(temp_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)\n\t\tins = SCD;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\top |= SLJIT_32;\n\t\tins = SC;\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src_reg) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));\n\treturn push_inst(compiler, ins | TA(OTHER_FLAG) | S(mem_reg), OTHER_FLAG);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_DATA;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tif (init_value & 0x100)\n\t\t\tinit_value |= 0xff00;\n\t\telse\n\t\t\tinit_value &= 0xff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst_r) | IMM(init_value), DR(dst_r)));\n\t\tmem_flags = BYTE_DATA;\n\t\tbreak;\n\n#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)\n\tcase SLJIT_MOV32:\n\t\tmem_flags = INT_DATA;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_S32:\n\t\tPTR_FAIL_IF(push_inst(compiler, LUI | T(dst_r) | IMM(init_value >> 16), DR(dst_r)));\n\t\tPTR_FAIL_IF(push_inst(compiler, ORI | S(dst_r) | T(dst_r) | IMM(init_value), DR(dst_r)));\n\t\tbreak;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\tdefault:\n\t\tPTR_FAIL_IF(emit_const(compiler, dst_r, init_value));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, DR(TMP_REG2), dst, dstw));\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), dst, dstw));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\tPTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r, UNMOVABLE_INS));\n#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tcompiler->size += 1;\n#else\n\tcompiler->size += 5;\n#endif\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDU_W | S(dst_r) | T(TMP_REG1) | D(dst_r), DR(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_ins *inst;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tinst = (sljit_ins *)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0xfc000000) == ADDIU);\n\n\t\tif (new_constant & 0x100)\n\t\t\tnew_constant |= 0xff00;\n\t\telse\n\t\t\tnew_constant &= 0xff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_constant);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\treturn;\n\n#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tinst = (sljit_ins *)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_constant >> 16);\n\t\tinst[1] = (inst[1] & 0xffff0000) | IMM(new_constant);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n#endif /* SLJIT_CONFIG_MIPS_64 */\n\n\tdefault:\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* ppc 32-bit arch dependent functions. */\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)\n{\n\tif (imm <= SIMM_MAX && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));\n\n\tif (!(imm & ~0xffff))\n\t\treturn push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));\n\n\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));\n\treturn (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;\n}\n\n/* Simplified mnemonics: clrlwi. */\n#define INS_CLEAR_LEFT(dst, src, from) \\\n\t(RLWINM | S(src) | A(dst) | RLWI_MBE(from, 31))\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_s32 src1, sljit_s32 src2)\n{\n\tsljit_u32 imm;\n\n\tswitch (op) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV_P:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif (dst != src2)\n\t\t\treturn push_inst(compiler, OR | S(src2) | A(dst) | B(src2));\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U8:\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (op == SLJIT_MOV_S8)\n\t\t\t\treturn push_inst(compiler, EXTSB | S(src2) | A(dst));\n\t\t\treturn push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));\n\t\t}\n\t\telse if ((flags & REG_DEST) && op == SLJIT_MOV_S8)\n\t\t\treturn push_inst(compiler, EXTSB | S(src2) | A(dst));\n\t\telse {\n\t\t\tSLJIT_ASSERT(dst == src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (op == SLJIT_MOV_S16)\n\t\t\t\treturn push_inst(compiler, EXTSH | S(src2) | A(dst));\n\t\t\treturn push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));\n\t\t}\n\t\telse {\n\t\t\tSLJIT_ASSERT(dst == src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\treturn push_inst(compiler, CNTLZW | S(src2) | A(dst));\n\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tFAIL_IF(push_inst(compiler, NEG | D(TMP_REG1) | A(src2)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(src2) | A(dst) | B(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, CNTLZW | S(dst) | A(dst)));\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(dst) | IMM(-32)));\n\t\t/* The highest bits are set, if dst < 32, zero otherwise. */\n\t\tFAIL_IF(push_inst(compiler, SRWI(27) | S(TMP_REG1) | A(TMP_REG1)));\n\t\treturn push_inst(compiler, XOR | S(dst) | A(dst) | B(TMP_REG1));\n\n\tcase SLJIT_ADD:\n\t\tif (flags & ALT_FORM1) {\n\t\t\t/* Setting XER SO is not enough, CR SO is also needed. */\n\t\t\treturn push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));\n\t\t}\n\n\t\tif (flags & ALT_FORM2) {\n\t\t\t/* Flags does not set: BIN_IMM_EXTS unnecessary. */\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\n\t\t\tif (flags & ALT_FORM3)\n\t\t\t\treturn push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);\n\n\t\t\timm = compiler->imm;\n\n\t\t\tif (flags & ALT_FORM4) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((imm >> 16) & 0xffff) + ((imm >> 15) & 0x1))));\n\t\t\t\tsrc1 = dst;\n\t\t\t}\n\n\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (imm & 0xffff));\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\t\tSLJIT_ASSERT(!(flags & ALT_FORM4));\n\t\tif (!(flags & ALT_SET_FLAGS))\n\t\t\treturn push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));\n\t\tif (flags & ALT_FORM5)\n\t\t\treturn push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));\n\t\treturn push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));\n\n\tcase SLJIT_ADDC:\n\t\treturn push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));\n\n\tcase SLJIT_SUB:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\tFAIL_IF(push_inst(compiler, CMPLI | CRD(0) | A(src1) | compiler->imm));\n\t\t\t\tif (!(flags & ALT_FORM3))\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, CMPL | CRD(0) | A(src1) | B(src2)));\n\t\t\tif (!(flags & ALT_FORM3))\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tif (flags & ALT_FORM2) {\n\t\t\tif (flags & ALT_FORM3) {\n\t\t\t\tFAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));\n\t\t\t\tif (!(flags & ALT_FORM4))\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));\n\t\t\tif (!(flags & ALT_FORM4))\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tif (flags & ALT_FORM3) {\n\t\t\t/* Setting XER SO is not enough, CR SO is also needed. */\n\t\t\tif (src1 != TMP_ZERO)\n\t\t\t\treturn push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));\n\t\t\treturn push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2));\n\t\t}\n\n\t\tif (flags & ALT_FORM4) {\n\t\t\t/* Flags does not set: BIN_IMM_EXTS unnecessary. */\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\n\t\tif (!(flags & ALT_SET_FLAGS)) {\n\t\t\tSLJIT_ASSERT(src1 != TMP_ZERO);\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tif (flags & ALT_FORM5)\n\t\t\treturn push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));\n\n\t\tif (src1 != TMP_ZERO)\n\t\t\treturn push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));\n\t\treturn push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));\n\n\tcase SLJIT_SUBC:\n\t\treturn push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));\n\n\tcase SLJIT_MUL:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\t\treturn push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));\n\n\tcase SLJIT_AND:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\treturn push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_OR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tFAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(imm)));\n\t\t\treturn push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(imm >> 16));\n\t\t}\n\t\treturn push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_XOR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tFAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));\n\t\t\treturn push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));\n\t\t}\n\t\tif (flags & ALT_FORM4) {\n\t\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\t\treturn push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));\n\t\t}\n\t\treturn push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm & 0x1f;\n\t\t\treturn push_inst(compiler, SLWI(imm) | RC(flags) | S(src1) | A(dst));\n\t\t}\n\n\t\tif (op == SLJIT_MSHL) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm & 0x1f;\n\t\t\t/* Since imm can be 0, SRWI() cannot be used. */\n\t\t\treturn push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | RLWI_SH((32 - imm) & 0x1f) | RLWI_MBE(imm, 31));\n\t\t}\n\n\t\tif (op == SLJIT_MLSHR) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm & 0x1f;\n\t\t\treturn push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (imm << 11));\n\t\t}\n\n\t\tif (op == SLJIT_MASHR) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tif (op == SLJIT_ROTR)\n\t\t\t\timm = (sljit_u32)(-(sljit_s32)imm);\n\n\t\t\timm &= 0x1f;\n\t\t\treturn push_inst(compiler, RLWINM | S(src1) | A(dst) | RLWI_SH(imm) | RLWI_MBE(0, 31));\n\t\t}\n\n\t\tif (op == SLJIT_ROTR) {\n\t\t\tFAIL_IF(push_inst(compiler, SUBFIC | D(TMP_REG2) | A(src2) | 0));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, RLWNM | S(src1) | A(dst) | B(src2) | RLWI_MBE(0, 31));\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)\n{\n\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));\n\treturn push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\tsljit_s32 invert_sign = 1;\n\n\tif (src == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000));\n\t\tsrc = TMP_REG1;\n\t\tinvert_sign = 0;\n\t} else if (!FAST_IS_REG(src)) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\t/* First, a special double precision floating point value is constructed:\n\t      (2^53 + (src xor (2^31)))\n\t   The upper 32 bits of this number is a constant, and the lower 32 bits\n\t   is simply the value of the source argument. The xor 2^31 operation adds\n\t   0x80000000 to the source argument, which moves it into the 0 - 0xffffffff\n\t   range. Finally we substract 2^53 + 2^31 to get the converted value. */\n\tFAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));\n\tif (invert_sign)\n\t\tFAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));\n\tFAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));\n\tFAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\tFAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));\n\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\tFAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\n\tFAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));\n\n\tif (op & SLJIT_32)\n\t\tFAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t} else if (!FAST_IS_REG(src)) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\t/* First, a special double precision floating point value is constructed:\n\t      (2^53 + src)\n\t   The upper 32 bits of this number is a constant, and the lower 32 bits\n\t   is simply the value of the source argument. Finally we substract 2^53\n\t   to get the converted value. */\n\tFAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));\n\tFAIL_IF(push_inst(compiler, STW | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\tFAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));\n\n\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\tFAIL_IF(push_inst(compiler, STW | S(TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\n\tFAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));\n\n\tif (op & SLJIT_32)\n\t\tFAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_s32 imm[2];\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm[0] != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0]));\n\tif (u.imm[1] != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1]));\n\n\t/* Saved in the same endianness. */\n\tFAIL_IF(push_inst(compiler, STW | S(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\tFAIL_IF(push_inst(compiler, STW | S(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | A(SLJIT_SP) | (TMP_MEM_OFFSET + sizeof(sljit_s32))));\n\treturn push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_s32 reg2 = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (op & SLJIT_32) {\n\t\tif (op == SLJIT_COPY32_TO_F32) {\n\t\t\tFAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\t\treturn push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, STFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\treturn push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t}\n\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\t}\n\n\tif (op == SLJIT_COPY_TO_F64) {\n\t\tFAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));\n\n\t\tif (reg2 != 0)\n\t\t\tFAIL_IF(push_inst(compiler, STW | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\n\t\treturn push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t}\n\n\tFAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\n\tif (reg2 != 0)\n\t\tFAIL_IF(push_inst(compiler, LWZ | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));\n\n\treturn push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins *inst = (sljit_ins *)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\tSLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);\n\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 16);\n\tinst[1] = (inst[1] & 0xffff0000) | IMM(new_target);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* ppc 64-bit arch dependent functions. */\n\n#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)\n#define ASM_SLJIT_CLZ(src, dst) \\\n\t__asm__ volatile ( \"cntlzd %0, %1\" : \"=r\"(dst) : \"r\"(src) )\n#elif defined(__xlc__)\n#error \"Please enable GCC syntax for inline assembly statements\"\n#else\n#error \"Must implement count leading zeroes\"\n#endif\n\n/* Computes SLDI(63 - shift). */\n#define PUSH_SLDI_NEG(reg, shift) \\\n\tpush_inst(compiler, RLDICR | S(reg) | A(reg) | RLDI_SH(63 - shift) | RLDI_ME(shift))\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)\n{\n\tsljit_uw tmp;\n\tsljit_uw shift;\n\tsljit_uw tmp2;\n\tsljit_uw shift2;\n\n\tif (imm <= SIMM_MAX && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));\n\n\tif (((sljit_uw)imm >> 16) == 0)\n\t\treturn push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));\n\n\tif (imm <= 0x7fffffffl && imm >= -0x80000000l) {\n\t\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));\n\t\treturn (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;\n\t}\n\n\tif (((sljit_uw)imm >> 32) == 0) {\n\t\tFAIL_IF(push_inst(compiler, ORIS | S(TMP_ZERO) | A(reg) | IMM(imm >> 16)));\n\t\treturn (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;\n\t}\n\n\t/* Count leading zeroes. */\n\ttmp = (sljit_uw)((imm >= 0) ? imm : ~imm);\n\tASM_SLJIT_CLZ(tmp, shift);\n\tSLJIT_ASSERT(shift > 0);\n\tshift--;\n\ttmp = ((sljit_uw)imm << shift);\n\n\tif ((tmp & ~0xffff000000000000ul) == 0) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));\n\t\tshift += 15;\n\t\treturn PUSH_SLDI_NEG(reg, shift);\n\t}\n\n\tif ((tmp & ~0xffffffff00000000ul) == 0) {\n\t\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));\n\t\tFAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));\n\t\tshift += 31;\n\t\treturn PUSH_SLDI_NEG(reg, shift);\n\t}\n\n\t/* Cut out the 16 bit from immediate. */\n\tshift += 15;\n\ttmp2 = (sljit_uw)imm & (((sljit_uw)1 << (63 - shift)) - 1);\n\n\tif (tmp2 <= 0xffff) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));\n\t\tFAIL_IF(PUSH_SLDI_NEG(reg, shift));\n\t\treturn push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)tmp2);\n\t}\n\n\tif (tmp2 <= 0xffffffff) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));\n\t\tFAIL_IF(PUSH_SLDI_NEG(reg, shift));\n\t\tFAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 16)));\n\t\treturn (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;\n\t}\n\n\tASM_SLJIT_CLZ(tmp2, shift2);\n\ttmp2 <<= shift2;\n\n\tif ((tmp2 & ~0xffff000000000000ul) == 0) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));\n\t\tshift2 += 15;\n\t\tshift += (63 - shift2);\n\t\tFAIL_IF(PUSH_SLDI_NEG(reg, shift));\n\t\tFAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 48)));\n\t\treturn PUSH_SLDI_NEG(reg, shift2);\n\t}\n\n\t/* The general version. */\n\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)((sljit_uw)imm >> 48)));\n\tFAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));\n\tFAIL_IF(PUSH_SLDI_NEG(reg, 31));\n\tFAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));\n\treturn push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));\n}\n\n#undef PUSH_SLDI_NEG\n\n#define CLRLDI(dst, src, n) \\\n\t(RLDICL | S(src) | A(dst) | RLDI_SH(0) | RLDI_MB(n))\n\n/* Sign extension for integer operations. */\n#define UN_EXTS() \\\n\tif ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \\\n\t\tFAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \\\n\t\tsrc2 = TMP_REG2; \\\n\t}\n\n#define BIN_EXTS() \\\n\tif (flags & ALT_SIGN_EXT) { \\\n\t\tif (flags & REG1_SOURCE) { \\\n\t\t\tFAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \\\n\t\t\tsrc1 = TMP_REG1; \\\n\t\t} \\\n\t\tif (flags & REG2_SOURCE) { \\\n\t\t\tFAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \\\n\t\t\tsrc2 = TMP_REG2; \\\n\t\t} \\\n\t}\n\n#define BIN_IMM_EXTS() \\\n\tif ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \\\n\t\tFAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \\\n\t\tsrc1 = TMP_REG1; \\\n\t}\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_s32 src1, sljit_s32 src2)\n{\n\tsljit_u32 imm;\n\n\tswitch (op) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif (dst != src2)\n\t\t\treturn push_inst(compiler, OR | S(src2) | A(dst) | B(src2));\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (op == SLJIT_MOV_S32)\n\t\t\t\treturn push_inst(compiler, EXTSW | S(src2) | A(dst));\n\t\t\treturn push_inst(compiler, CLRLDI(dst, src2, 32));\n\t\t}\n\t\telse {\n\t\t\tSLJIT_ASSERT(dst == src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U8:\n\tcase SLJIT_MOV_S8:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (op == SLJIT_MOV_S8)\n\t\t\t\treturn push_inst(compiler, EXTSB | S(src2) | A(dst));\n\t\t\treturn push_inst(compiler, CLRLDI(dst, src2, 56));\n\t\t}\n\t\telse if ((flags & REG_DEST) && op == SLJIT_MOV_S8)\n\t\t\treturn push_inst(compiler, EXTSB | S(src2) | A(dst));\n\t\telse {\n\t\t\tSLJIT_ASSERT(dst == src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\tcase SLJIT_MOV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (op == SLJIT_MOV_S16)\n\t\t\t\treturn push_inst(compiler, EXTSH | S(src2) | A(dst));\n\t\t\treturn push_inst(compiler, CLRLDI(dst, src2, 48));\n\t\t}\n\t\telse {\n\t\t\tSLJIT_ASSERT(dst == src2);\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_CLZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\treturn push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(src2) | A(dst));\n\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\tFAIL_IF(push_inst(compiler, NEG | D(TMP_REG1) | A(src2)));\n\t\tFAIL_IF(push_inst(compiler, AND | S(src2) | A(dst) | B(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(dst) | A(dst)));\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(dst) | IMM((flags & ALT_FORM1) ? -32 : -64)));\n\t\t/* The highest bits are set, if dst < bit width, zero otherwise. */\n\t\tFAIL_IF(push_inst(compiler, ((flags & ALT_FORM1) ? SRWI(27) : SRDI(58)) | S(TMP_REG1) | A(TMP_REG1)));\n\t\treturn push_inst(compiler, XOR | S(dst) | A(dst) | B(TMP_REG1));\n\n\tcase SLJIT_ADD:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tif (flags & ALT_SIGN_EXT) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLDI(32) | S(src1) | A(TMP_REG1)));\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\tFAIL_IF(push_inst(compiler, SLDI(32) | S(src2) | A(TMP_REG2)));\n\t\t\t\tsrc2 = TMP_REG2;\n\t\t\t}\n\t\t\t/* Setting XER SO is not enough, CR SO is also needed. */\n\t\t\tFAIL_IF(push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)));\n\t\t\tif (flags & ALT_SIGN_EXT)\n\t\t\t\treturn push_inst(compiler, SRDI(32) | S(dst) | A(dst));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tif (flags & ALT_FORM2) {\n\t\t\t/* Flags does not set: BIN_IMM_EXTS unnecessary. */\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\n\t\t\tif (flags & ALT_FORM3)\n\t\t\t\treturn push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);\n\n\t\t\timm = compiler->imm;\n\n\t\t\tif (flags & ALT_FORM4) {\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((imm >> 16) & 0xffff) + ((imm >> 15) & 0x1))));\n\t\t\t\tsrc1 = dst;\n\t\t\t}\n\n\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (imm & 0xffff));\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\tBIN_IMM_EXTS();\n\t\t\treturn push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM4) {\n\t\t\tif (flags & ALT_FORM5)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)));\n\t\t\treturn push_inst(compiler, CMPI | A(dst) | 0);\n\t\t}\n\t\tif (!(flags & ALT_SET_FLAGS))\n\t\t\treturn push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));\n\t\tBIN_EXTS();\n\t\tif (flags & ALT_FORM5)\n\t\t\treturn push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));\n\t\treturn push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));\n\n\tcase SLJIT_ADDC:\n\t\tBIN_EXTS();\n\t\treturn push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));\n\n\tcase SLJIT_SUB:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\tFAIL_IF(push_inst(compiler, CMPLI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));\n\t\t\t\tif (!(flags & ALT_FORM3))\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, CMPL | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));\n\t\t\tif (!(flags & ALT_FORM3))\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tif (flags & ALT_FORM2) {\n\t\t\tif (flags & ALT_FORM3) {\n\t\t\t\tFAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));\n\t\t\t\tif (!(flags & ALT_FORM4))\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\treturn push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));\n\t\t\tif (!(flags & ALT_FORM4))\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tif (flags & ALT_FORM3) {\n\t\t\tif (flags & ALT_SIGN_EXT) {\n\t\t\t\tif (src1 != TMP_ZERO) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SLDI(32) | S(src1) | A(TMP_REG1)));\n\t\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\t}\n\t\t\t\tif (src2 != TMP_ZERO) {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SLDI(32) | S(src2) | A(TMP_REG2)));\n\t\t\t\t\tsrc2 = TMP_REG2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Setting XER SO is not enough, CR SO is also needed. */\n\t\t\tif (src1 != TMP_ZERO)\n\t\t\t\tFAIL_IF(push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2)));\n\n\t\t\tif (flags & ALT_SIGN_EXT)\n\t\t\t\treturn push_inst(compiler, SRDI(32) | S(dst) | A(dst));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tif (flags & ALT_FORM4) {\n\t\t\t/* Flags does not set: BIN_IMM_EXTS unnecessary. */\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\n\t\tif (!(flags & ALT_SET_FLAGS)) {\n\t\t\tSLJIT_ASSERT(src1 != TMP_ZERO);\n\t\t\treturn push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));\n\t\t}\n\n\t\tBIN_EXTS();\n\t\tif (flags & ALT_FORM5)\n\t\t\treturn push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));\n\n\t\tif (src1 != TMP_ZERO)\n\t\t\treturn push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));\n\t\treturn push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));\n\n\tcase SLJIT_SUBC:\n\t\tBIN_EXTS();\n\t\treturn push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));\n\n\tcase SLJIT_MUL:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);\n\t\t}\n\t\tBIN_EXTS();\n\t\tif (flags & ALT_FORM2)\n\t\t\treturn push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));\n\t\treturn push_inst(compiler, MULLD | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));\n\n\tcase SLJIT_AND:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\treturn push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_OR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tFAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(imm)));\n\t\t\treturn push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(imm >> 16));\n\t\t}\n\t\treturn push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_XOR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM2) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\treturn push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);\n\t\t}\n\t\tif (flags & ALT_FORM3) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tFAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));\n\t\t\treturn push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));\n\t\t}\n\t\tif (flags & ALT_FORM4) {\n\t\t\tSLJIT_ASSERT(src1 == TMP_REG1);\n\t\t\tUN_EXTS();\n\t\t\treturn push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));\n\t\t}\n\t\treturn push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\treturn push_inst(compiler, SLWI(imm) | RC(flags) | S(src1) | A(dst));\n\t\t\t}\n\n\t\t\timm &= 0x3f;\n\t\t\treturn push_inst(compiler, SLDI(imm) | RC(flags) | S(src1) | A(dst));\n\t\t}\n\n\t\tif (op == SLJIT_MSHL) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\t/* Since imm can be 0, SRWI() cannot be used. */\n\t\t\t\treturn push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | RLWI_SH((32 - imm) & 0x1f) | RLWI_MBE(imm, 31));\n\t\t\t}\n\n\t\t\timm &= 0x3f;\n\t\t\t/* Since imm can be 0, SRDI() cannot be used. */\n\t\t\treturn push_inst(compiler, RLDICL | RC(flags) | S(src1) | A(dst) | RLDI_SH((64 - imm) & 0x3f) | RLDI_MB(imm));\n\t\t}\n\n\t\tif (op == SLJIT_MLSHR) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\treturn push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (imm << 11));\n\t\t\t}\n\n\t\t\timm &= 0x3f;\n\t\t\treturn push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | RLDI_SH(imm));\n\t\t}\n\n\t\tif (op == SLJIT_MASHR) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | ((flags & ALT_FORM2) ? 0x1f : 0x3f)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));\n\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (flags & ALT_FORM1) {\n\t\t\tSLJIT_ASSERT(src2 == TMP_REG2);\n\t\t\timm = compiler->imm;\n\n\t\t\tif (op == SLJIT_ROTR)\n\t\t\t\timm = (sljit_u32)(-(sljit_s32)imm);\n\n\t\t\tif (flags & ALT_FORM2) {\n\t\t\t\timm &= 0x1f;\n\t\t\t\treturn push_inst(compiler, RLWINM | S(src1) | A(dst) | RLWI_SH(imm) | RLWI_MBE(0, 31));\n\t\t\t}\n\n\t\t\timm &= 0x3f;\n\t\t\treturn push_inst(compiler, RLDICL | S(src1) | A(dst) | RLDI_SH(imm));\n\t\t}\n\n\t\tif (op == SLJIT_ROTR) {\n\t\t\tFAIL_IF(push_inst(compiler, SUBFIC | D(TMP_REG2) | A(src2) | 0));\n\t\t\tsrc2 = TMP_REG2;\n\t\t}\n\n\t\treturn push_inst(compiler, ((flags & ALT_FORM2) ? (RLWNM | RLWI_MBE(0, 31)) : (RLDCL | RLDI_MB(0))) | S(src1) | A(dst) | B(src2));\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)\n{\n\tsljit_s32 arg_count = 0;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_s32 reg = 0;\n\n\tif (src)\n\t\treg = *src & REG_MASK;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targ_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\targ_count++;\n\t\t\tword_arg_count++;\n\n\t\t\tif (arg_count != word_arg_count && arg_count == reg) {\n\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));\n\t\t\t\t*src = TMP_CALL_REG;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\twhile (types) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targ_count--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (arg_count != word_arg_count)\n\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));\n\n\t\t\targ_count--;\n\t\t\tword_arg_count--;\n\t\t\tbreak;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)\n{\n\tFAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));\n\tFAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));\n\tFAIL_IF(push_inst(compiler, SLDI(32) | S(reg) | A(reg)));\n\tFAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));\n\treturn push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src == SLJIT_IMM) {\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)\n\t\t\tsrcw = (sljit_s32)srcw;\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\tsrc = TMP_REG1;\n\t} else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {\n\t\tif (FAST_IS_REG(src))\n\t\t\tFAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));\n\t\telse\n\t\t\tFAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif (FAST_IS_REG(src)) {\n\t\tFAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t} else\n\t\tFAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));\n\n\tFAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));\n\n\tif (op & SLJIT_32)\n\t\tFAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {\n\t\tif (src == SLJIT_IMM) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_u32)srcw));\n\t\t\tsrc = TMP_REG1;\n\t\t} else {\n\t\t\tif (FAST_IS_REG(src))\n\t\t\t\tFAIL_IF(push_inst(compiler, CLRLDI(TMP_REG1, src, 32)));\n\t\t\telse\n\t\t\t\tFAIL_IF(emit_op_mem(compiler, INT_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));\n\t} else {\n\t\tif (src == SLJIT_IMM) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\t\tsrc = TMP_REG1;\n\t\t} else if (src & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, CMPI | CRD(0 | 1) | A(src) | 0));\n\t\tFAIL_IF(push_inst(compiler, BCx | (12 << 21) | (0 << 16) | 20));\n\t\tFAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));\n\t\tFAIL_IF(push_inst(compiler, Bx | ((op & SLJIT_32) ? 36 : 32)));\n\n\t\tif (op & SLJIT_32)\n\t\t\tFAIL_IF(push_inst(compiler, RLWINM | S(src) | A(TMP_REG2) | RLWI_SH(10) | RLWI_MBE(10, 21)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src) | A(TMP_REG2) | 0x1));\n\n\t\t/* Shift right. */\n\t\tFAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(63) | RLDI_MB(1)));\n\n\t\tif (op & SLJIT_32)\n\t\t\tFAIL_IF(push_inst(compiler, RLDICR | S(TMP_REG1) | A(TMP_REG1) | RLDI_SH(0) | RLDI_ME(53)));\n\n\t\tFAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));\n\n\t\tFAIL_IF(push_inst(compiler, STD | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));\n\t\tFAIL_IF(push_inst(compiler, FADD | FD(dst_r) | FA(dst_r) | FB(dst_r)));\n\t}\n\n\tif (op & SLJIT_32)\n\t\tFAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\n\tFAIL_IF(push_inst(compiler, STD | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\treturn push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64) {\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STW : STD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\treturn push_inst(compiler, ((op & SLJIT_32) ? LFS : LFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\treturn push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_ins *inst = (sljit_ins*)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);\n\tinst[0] = (inst[0] & 0xffff0000u) | IMM(new_target >> 48);\n\tinst[1] = (inst[1] & 0xffff0000u) | IMM(new_target >> 32);\n\tinst[3] = (inst[3] & 0xffff0000u) | IMM(new_target >> 16);\n\tinst[4] = (inst[4] & 0xffff0000u) | IMM(new_target);\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);\n\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 5);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\treturn \"PowerPC\" SLJIT_CPUINFO;\n}\n\n/* Length of an instruction word.\n   Both for ppc-32 and ppc-64. */\ntypedef sljit_u32 sljit_ins;\n\n#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \\\n\t|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#define SLJIT_PPC_STACK_FRAME_V2 1\n#endif\n\n#ifdef _AIX\n#include <sys/cache.h>\n#endif\n\n#if (defined _CALL_ELF && _CALL_ELF == 2)\n#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1\n#endif\n\n#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)\n\nstatic void ppc_cache_flush(sljit_ins *from, sljit_ins *to)\n{\n#ifdef _AIX\n\t_sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));\n#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)\n#\tif defined(_ARCH_PWR) || defined(_ARCH_PWR2)\n\t/* Cache flush for POWER architecture. */\n\twhile (from < to) {\n\t\t__asm__ volatile (\n\t\t\t\"clf 0, %0\\n\"\n\t\t\t\"dcs\\n\"\n\t\t\t: : \"r\"(from)\n\t\t);\n\t\tfrom++;\n\t}\n\t__asm__ volatile ( \"ics\" );\n#\telif defined(_ARCH_COM) && !defined(_ARCH_PPC)\n#\terror \"Cache flush is not implemented for PowerPC/POWER common mode.\"\n#\telse\n\t/* Cache flush for PowerPC architecture. */\n\twhile (from < to) {\n\t\t__asm__ volatile (\n\t\t\t\"dcbf 0, %0\\n\"\n\t\t\t\"sync\\n\"\n\t\t\t\"icbi 0, %0\\n\"\n\t\t\t: : \"r\"(from)\n\t\t);\n\t\tfrom++;\n\t}\n\t__asm__ volatile ( \"isync\" );\n#\tendif\n#\tifdef __xlc__\n#\twarning \"This file may fail to compile if -qfuncsect is used\"\n#\tendif\n#elif defined(__xlc__)\n#error \"Please enable GCC syntax for inline assembly statements with -qasm=gcc\"\n#else\n#error \"This platform requires a cache flush implementation.\"\n#endif /* _AIX */\n}\n\n#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_ZERO\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)\n#define TMP_CALL_REG\t(SLJIT_NUMBER_OF_REGISTERS + 5)\n#else\n#define TMP_CALL_REG\tTMP_REG1\n#endif\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {\n\t0, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 9, 10, 31, 12\n};\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 0, 13\n};\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n#define D(d)\t\t((sljit_ins)reg_map[d] << 21)\n#define S(s)\t\t((sljit_ins)reg_map[s] << 21)\n#define A(a)\t\t((sljit_ins)reg_map[a] << 16)\n#define B(b)\t\t((sljit_ins)reg_map[b] << 11)\n#define C(c)\t\t((sljit_ins)reg_map[c] << 6)\n#define FD(fd)\t\t((sljit_ins)freg_map[fd] << 21)\n#define FS(fs)\t\t((sljit_ins)freg_map[fs] << 21)\n#define FA(fa)\t\t((sljit_ins)freg_map[fa] << 16)\n#define FB(fb)\t\t((sljit_ins)freg_map[fb] << 11)\n#define FC(fc)\t\t((sljit_ins)freg_map[fc] << 6)\n#define IMM(imm)\t((sljit_ins)(imm) & 0xffff)\n#define CRD(d)\t\t((sljit_ins)(d) << 21)\n\n/* Instruction bit sections.\n   OE and Rc flag (see ALT_SET_FLAGS). */\n#define OE(flags)\t((flags) & ALT_SET_FLAGS)\n/* Rc flag (see ALT_SET_FLAGS). */\n#define RC(flags)\t((sljit_ins)((flags) & ALT_SET_FLAGS) >> 10)\n#define HI(opcode)\t((sljit_ins)(opcode) << 26)\n#define LO(opcode)\t((sljit_ins)(opcode) << 1)\n\n#define ADD\t\t(HI(31) | LO(266))\n#define ADDC\t\t(HI(31) | LO(10))\n#define ADDE\t\t(HI(31) | LO(138))\n#define ADDI\t\t(HI(14))\n#define ADDIC\t\t(HI(13))\n#define ADDIS\t\t(HI(15))\n#define ADDME\t\t(HI(31) | LO(234))\n#define AND\t\t(HI(31) | LO(28))\n#define ANDI\t\t(HI(28))\n#define ANDIS\t\t(HI(29))\n#define Bx\t\t(HI(18))\n#define BCx\t\t(HI(16))\n#define BCCTR\t\t(HI(19) | LO(528) | (3 << 11))\n#define BLR\t\t(HI(19) | LO(16) | (0x14 << 21))\n#if defined(_ARCH_PWR10) && _ARCH_PWR10\n#define BRD\t\t(HI(31) | LO(187))\n#endif /* POWER10 */\n#define CNTLZD\t\t(HI(31) | LO(58))\n#define CNTLZW\t\t(HI(31) | LO(26))\n#define CMP\t\t(HI(31) | LO(0))\n#define CMPI\t\t(HI(11))\n#define CMPL\t\t(HI(31) | LO(32))\n#define CMPLI\t\t(HI(10))\n#define CROR\t\t(HI(19) | LO(449))\n#define DCBT\t\t(HI(31) | LO(278))\n#define DIVD\t\t(HI(31) | LO(489))\n#define DIVDU\t\t(HI(31) | LO(457))\n#define DIVW\t\t(HI(31) | LO(491))\n#define DIVWU\t\t(HI(31) | LO(459))\n#define EXTSB\t\t(HI(31) | LO(954))\n#define EXTSH\t\t(HI(31) | LO(922))\n#define EXTSW\t\t(HI(31) | LO(986))\n#define FABS\t\t(HI(63) | LO(264))\n#define FADD\t\t(HI(63) | LO(21))\n#define FADDS\t\t(HI(59) | LO(21))\n#define FCFID\t\t(HI(63) | LO(846))\n#define FCMPU\t\t(HI(63) | LO(0))\n#define FCTIDZ\t\t(HI(63) | LO(815))\n#define FCTIWZ\t\t(HI(63) | LO(15))\n#define FDIV\t\t(HI(63) | LO(18))\n#define FDIVS\t\t(HI(59) | LO(18))\n#define FMR\t\t(HI(63) | LO(72))\n#define FMUL\t\t(HI(63) | LO(25))\n#define FMULS\t\t(HI(59) | LO(25))\n#define FNEG\t\t(HI(63) | LO(40))\n#define FRSP\t\t(HI(63) | LO(12))\n#define FSUB\t\t(HI(63) | LO(20))\n#define FSUBS\t\t(HI(59) | LO(20))\n#define LD\t\t(HI(58) | 0)\n#define LFD\t\t(HI(50))\n#define LFS\t\t(HI(48))\n#define LDARX\t\t(HI(31) | LO(84))\n#if defined(_ARCH_PWR7) && _ARCH_PWR7\n#define LDBRX\t\t(HI(31) | LO(532))\n#endif /* POWER7 */\n#define LHBRX\t\t(HI(31) | LO(790))\n#define LWARX\t\t(HI(31) | LO(20))\n#define LWBRX\t\t(HI(31) | LO(534))\n#define LWZ\t\t(HI(32))\n#define MFCR\t\t(HI(31) | LO(19))\n#define MFLR\t\t(HI(31) | LO(339) | 0x80000)\n#define MFXER\t\t(HI(31) | LO(339) | 0x10000)\n#define MTCTR\t\t(HI(31) | LO(467) | 0x90000)\n#define MTLR\t\t(HI(31) | LO(467) | 0x80000)\n#define MTXER\t\t(HI(31) | LO(467) | 0x10000)\n#define MULHD\t\t(HI(31) | LO(73))\n#define MULHDU\t\t(HI(31) | LO(9))\n#define MULHW\t\t(HI(31) | LO(75))\n#define MULHWU\t\t(HI(31) | LO(11))\n#define MULLD\t\t(HI(31) | LO(233))\n#define MULLI\t\t(HI(7))\n#define MULLW\t\t(HI(31) | LO(235))\n#define NEG\t\t(HI(31) | LO(104))\n#define NOP\t\t(HI(24))\n#define NOR\t\t(HI(31) | LO(124))\n#define OR\t\t(HI(31) | LO(444))\n#define ORI\t\t(HI(24))\n#define ORIS\t\t(HI(25))\n#define RLDCL\t\t(HI(30) | LO(8))\n#define RLDICL\t\t(HI(30) | LO(0 << 1))\n#define RLDICR\t\t(HI(30) | LO(1 << 1))\n#define RLDIMI\t\t(HI(30) | LO(3 << 1))\n#define RLWIMI\t\t(HI(20))\n#define RLWINM\t\t(HI(21))\n#define RLWNM\t\t(HI(23))\n#define SLD\t\t(HI(31) | LO(27))\n#define SLW\t\t(HI(31) | LO(24))\n#define SRAD\t\t(HI(31) | LO(794))\n#define SRADI\t\t(HI(31) | LO(413 << 1))\n#define SRAW\t\t(HI(31) | LO(792))\n#define SRAWI\t\t(HI(31) | LO(824))\n#define SRD\t\t(HI(31) | LO(539))\n#define SRW\t\t(HI(31) | LO(536))\n#define STD\t\t(HI(62) | 0)\n#if defined(_ARCH_PWR7) && _ARCH_PWR7\n#define STDBRX\t\t(HI(31) | LO(660))\n#endif /* POWER7 */\n#define STDCX\t\t(HI(31) | LO(214))\n#define STDU\t\t(HI(62) | 1)\n#define STDUX\t\t(HI(31) | LO(181))\n#define STFD\t\t(HI(54))\n#define STFIWX\t\t(HI(31) | LO(983))\n#define STFS\t\t(HI(52))\n#define STHBRX\t\t(HI(31) | LO(918))\n#define STW\t\t(HI(36))\n#define STWBRX\t\t(HI(31) | LO(662))\n#define STWCX\t\t(HI(31) | LO(150))\n#define STWU\t\t(HI(37))\n#define STWUX\t\t(HI(31) | LO(183))\n#define SUBF\t\t(HI(31) | LO(40))\n#define SUBFC\t\t(HI(31) | LO(8))\n#define SUBFE\t\t(HI(31) | LO(136))\n#define SUBFIC\t\t(HI(8))\n#define SYNC\t\t(HI(31) | LO(598))\n#define XOR\t\t(HI(31) | LO(316))\n#define XORI\t\t(HI(26))\n#define XORIS\t\t(HI(27))\n\n#define SIMM_MAX\t(0x7fff)\n#define SIMM_MIN\t(-0x8000)\n#define UIMM_MAX\t(0xffff)\n\n/* Shift helpers. */\n#define RLWI_SH(sh) ((sljit_ins)(sh) << 11)\n#define RLWI_MBE(mb, me) (((sljit_ins)(mb) << 6) | ((sljit_ins)(me) << 1))\n#define RLDI_SH(sh) ((((sljit_ins)(sh) & 0x1f) << 11) | (((sljit_ins)(sh) & 0x20) >> 4))\n#define RLDI_MB(mb) ((((sljit_ins)(mb) & 0x1f) << 6) | ((sljit_ins)(mb) & 0x20))\n#define RLDI_ME(me) RLDI_MB(me)\n\n#define SLWI(shift) (RLWINM | RLWI_SH(shift) | RLWI_MBE(0, 31 - (shift)))\n#define SLDI(shift) (RLDICR | RLDI_SH(shift) | RLDI_ME(63 - (shift)))\n/* shift > 0 */\n#define SRWI(shift) (RLWINM | RLWI_SH(32 - (shift)) | RLWI_MBE((shift), 31))\n#define SRDI(shift) (RLDICL | RLDI_SH(64 - (shift)) | RLDI_MB(shift))\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n#define SLWI_W(shift) SLWI(shift)\n#define TMP_MEM_OFFSET (2 * sizeof(sljit_sw))\n#else /* !SLJIT_CONFIG_PPC_32 */\n#define SLWI_W(shift) SLDI(shift)\n#define TMP_MEM_OFFSET (6 * sizeof(sljit_sw))\n#endif /* SLJIT_CONFIG_PPC_32 */\n\n#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#define TMP_MEM_OFFSET_LO\t(TMP_MEM_OFFSET)\n#define TMP_MEM_OFFSET_HI\t(TMP_MEM_OFFSET + sizeof(sljit_s32))\n#define LWBRX_FIRST_REG\t\tS(TMP_REG1)\n#define LWBRX_SECOND_REG\tS(dst)\n#else /* !SLJIT_LITTLE_ENDIAN */\n#define TMP_MEM_OFFSET_LO\t(TMP_MEM_OFFSET + sizeof(sljit_s32))\n#define TMP_MEM_OFFSET_HI\t(TMP_MEM_OFFSET)\n#define LWBRX_FIRST_REG\t\tS(dst)\n#define LWBRX_SECOND_REG\tS(TMP_REG1)\n#endif /* SLJIT_LITTLE_ENDIAN */\n\n#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func)\n{\n\tsljit_uw* ptrs;\n\n\tif (func_ptr)\n\t\t*func_ptr = (void*)context;\n\n\tptrs = (sljit_uw*)func;\n\tcontext->addr = addr ? addr : ptrs[0];\n\tcontext->r2 = ptrs[1];\n\tcontext->r11 = ptrs[2];\n}\n#endif\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)\n{\n\tsljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\t*ptr = ins;\n\tcompiler->size++;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tjump->addr = jump_addr;\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tif (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))\n\t\tgoto exit;\n#else\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n#endif\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (jump->flags & IS_CALL)\n\t\tgoto keep_address;\n#endif\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (jump->flags & IS_COND) {\n\t\tif (diff <= 0x7fff && diff >= -0x8000) {\n\t\t\tjump->flags |= PATCH_B;\n\t\t\treturn code_ptr;\n\t\t}\n\t\tif (target_addr <= 0xffff) {\n\t\t\tjump->flags |= PATCH_B | PATCH_ABS_B;\n\t\t\treturn code_ptr;\n\t\t}\n\n\t\tdiff -= SSIZE_OF(ins);\n\t}\n\n\tif (diff <= 0x01ffffff && diff >= -0x02000000) {\n\t\tjump->flags |= PATCH_B;\n\t} else if (target_addr <= 0x01ffffff) {\n\t\tjump->flags |= PATCH_B | PATCH_ABS_B;\n\t}\n\n\tif (jump->flags & PATCH_B) {\n\t\tif (!(jump->flags & IS_COND))\n\t\t\treturn code_ptr;\n\n\t\tcode_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);\n\t\tcode_ptr[1] = Bx;\n\t\tjump->addr += sizeof(sljit_ins);\n\t\tjump->flags -= IS_COND;\n\t\treturn code_ptr + 1;\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)\nkeep_address:\n#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */\n\tif (target_addr < 0x80000000l) {\n\t\tjump->flags |= PATCH_ABS32;\n\t\tcode_ptr[2] = MTCTR | S(TMP_CALL_REG);\n\t\tcode_ptr[3] = code_ptr[0];\n\t\treturn code_ptr + 3;\n\t}\n\n\tif (target_addr < 0x800000000000l) {\n\t\tjump->flags |= PATCH_ABS48;\n\t\tcode_ptr[4] = MTCTR | S(TMP_CALL_REG);\n\t\tcode_ptr[5] = code_ptr[0];\n\t\treturn code_ptr + 5;\n\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\nexit:\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tcode_ptr[2] = MTCTR | S(TMP_CALL_REG);\n\tcode_ptr[3] = code_ptr[0];\n#else /* !SLJIT_CONFIG_PPC_32 */\n\tcode_ptr[5] = MTCTR | S(TMP_CALL_REG);\n\tcode_ptr[6] = code_ptr[0];\n#endif /* SLJIT_CONFIG_PPC_32 */\n\treturn code_ptr + JUMP_MAX_SIZE - 1;\n}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT(jump->flags < ((sljit_uw)5 << JUMP_SIZE_SHIFT));\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\tif (addr < 0x80000000l) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS32;\n\t\treturn 1;\n\t}\n\n\tif (addr < 0x800000000000l) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS48;\n\t\treturn 3;\n\t}\n\n\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)4 << JUMP_SIZE_SHIFT));\n\treturn 4;\n}\n\n#endif /* SLJIT_CONFIG_PPC_64 */\n\nstatic void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_uw flags = jump->flags;\n\tsljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\tsljit_ins *ins = (sljit_ins*)jump->addr;\n\tsljit_s32 reg;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (flags & PATCH_B) {\n\t\tif (flags & IS_COND) {\n\t\t\tif (!(flags & PATCH_ABS_B)) {\n\t\t\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);\n\t\t\t\tSLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);\n\t\t\t\tins[0] = BCx | ((sljit_ins)addr & 0xfffc) | (ins[0] & 0x03ff0001);\n\t\t\t} else {\n\t\t\t\tSLJIT_ASSERT(addr <= 0xffff);\n\t\t\t\tins[0] = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*ins) & 0x03ff0001);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(flags & PATCH_ABS_B)) {\n\t\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);\n\t\t\tSLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);\n\t\t\tins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | (ins[0] & 0x1);\n\t\t} else {\n\t\t\tSLJIT_ASSERT(addr <= 0x03ffffff);\n\t\t\tins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | (ins[0] & 0x1);\n\t\t}\n\t\treturn;\n\t}\n\n\treg = (flags & JUMP_MOV_ADDR) ? (sljit_s32)ins[0] : TMP_CALL_REG;\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16);\n\tins[1] = ORI | S(reg) | A(reg) | IMM(addr);\n#else /* !SLJIT_CONFIG_PPC_32 */\n\n\t/* The TMP_ZERO cannot be used because it is restored for tail calls. */\n\tif (flags & PATCH_ABS32) {\n\t\tSLJIT_ASSERT(addr < 0x80000000l);\n\t\tins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16);\n\t\tins[1] = ORI | S(reg) | A(reg) | IMM(addr);\n\t\treturn;\n\t}\n\n\tif (flags & PATCH_ABS48) {\n\t\tSLJIT_ASSERT(addr < 0x800000000000l);\n\t\tins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 32);\n\t\tins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 16);\n\t\tins[2] = SLDI(16) | S(reg) | A(reg);\n\t\tins[3] = ORI | S(reg) | A(reg) | IMM(addr);\n\t\treturn;\n\t}\n\n\tins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 48);\n\tins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 32);\n\tins[2] = SLDI(32) | S(reg) | A(reg);\n\tins[3] = ORIS | S(reg) | A(reg) | IMM(addr >> 16);\n\tins[4] = ORI | S(reg) | A(reg) | IMM(addr);\n#endif /* SLJIT_CONFIG_PPC_32 */\n}\n\nstatic SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE - 1;\n\n\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\tif (jump->flags & JUMP_ADDR) {\n\t\t\t\t\tif (jump->u.target <= 0x01ffffff)\n\t\t\t\t\t\ttotal_size = 1 - 1;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\t\t\t\telse if (jump->u.target < 0x80000000l)\n\t\t\t\t\t\ttotal_size = 4 - 1;\n\t\t\t\t\telse if (jump->u.target < 0x800000000000l)\n\t\t\t\t\t\ttotal_size = 6 - 1;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\t\t\t} else {\n\t\t\t\t\t/* Unit size: instruction. */\n\t\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (jump->flags & IS_COND) {\n\t\t\t\t\t\tif (diff <= (0x7fff / SSIZE_OF(ins)) && diff >= (-0x8000 / SSIZE_OF(ins)))\n\t\t\t\t\t\t\ttotal_size = 1 - 1;\n\t\t\t\t\t\telse if ((diff - 1) <= (0x01ffffff / SSIZE_OF(ins)) && (diff - 1) >= (-0x02000000 / SSIZE_OF(ins)))\n\t\t\t\t\t\t\ttotal_size = 2 - 1;\n\t\t\t\t\t} else if (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins)))\n\t\t\t\t\t\ttotal_size = 1 - 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsize_reduce += (JUMP_MAX_SIZE - 1) - total_size;\n\t\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\t} else {\n\t\t\ttotal_size = (sljit_uw)4 << JUMP_SIZE_SHIFT;\n\n\t\t\tif (jump->flags & JUMP_ADDR) {\n\t\t\t\tif (jump->u.target < 0x80000000l) {\n\t\t\t\t\ttotal_size = (sljit_uw)1 << JUMP_SIZE_SHIFT;\n\t\t\t\t\tsize_reduce += 3;\n\t\t\t\t} else if (jump->u.target < 0x800000000000l) {\n\t\t\t\t\ttotal_size = (sljit_uw)3 << JUMP_SIZE_SHIFT;\n\t\t\t\t\tsize_reduce += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tjump->flags |= total_size;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\t}\n\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *code;\n\tsljit_ins *code_ptr;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_uw word_count;\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tsljit_uw jump_addr;\n#endif\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n\tif (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {\n\t/* add to compiler->size additional instruction space to hold the trampoline and padding */\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tcompiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));\n#else /* !SLJIT_CONFIG_PPC_64 */\n\t\tcompiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t}\n#endif /* SLJIT_INDIRECT_CALL */\n\tcode = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\tword_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 2);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == word_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= word_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= word_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= word_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Just recording the address. */\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\t\t\t\tjump_addr = (sljit_uw)code_ptr;\n#endif\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tSLJIT_ASSERT(((sljit_uw)code_ptr - jump_addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\t\t\t\t\tword_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code, executable_offset);\n#else /* !SLJIT_CONFIG_PPC_64 */\n\t\t\t\t\t\tword_count++;\n\t\t\t\t\t\tcode_ptr++;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\t\t\t\t}\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\tword_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == word_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\n#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size -\n\t\t((options & SLJIT_GENERATE_CODE_NO_CONTEXT) ? 0 : (sizeof(struct sljit_function_context) / sizeof(sljit_ins)))));\n#else\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n#endif\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tgenerate_jump_or_mov_addr(jump, executable_offset);\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\n\tcode = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\n#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n\tif (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (((sljit_sw)code_ptr) & 0x4)\n\t\t\tcode_ptr++;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\tsljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_uw)code, (void*)sljit_generate_code);\n\t}\n#endif /* SLJIT_INDIRECT_CALL */\n\n\tcode_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\n#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)\n\tif (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {\n\t\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins) + sizeof(struct sljit_function_context);\n\t\treturn code_ptr;\n\t}\n#endif /* SLJIT_INDIRECT_CALL */\n\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\t/* Available by default. */\n\t\treturn 1;\n#endif\n\tcase SLJIT_HAS_REV:\n#if defined(_ARCH_PWR10) && _ARCH_PWR10\n\t\treturn 1;\n#else /* !POWER10 */\n\t\treturn 2;\n#endif /* POWER10 */\n\t/* A saved register is set to a zero value. */\n\tcase SLJIT_HAS_ZERO_REGISTER:\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tcase SLJIT_HAS_CTZ:\n\t\treturn 2;\n\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\n/* inp_flags: */\n\n/* Creates an index in data_transfer_insts array. */\n#define LOAD_DATA\t0x01\n#define INDEXED\t\t0x02\n#define SIGNED_DATA\t0x04\n\n#define WORD_DATA\t0x00\n#define BYTE_DATA\t0x08\n#define HALF_DATA\t0x10\n#define INT_DATA\t0x18\n/* Separates integer and floating point registers */\n#define GPR_REG\t\t0x1f\n#define DOUBLE_DATA\t0x20\n\n#define MEM_MASK\t0x7f\n\n#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6))\n\n/* Other inp_flags. */\n\n/* Integer opertion and set flags -> requires exts on 64 bit systems. */\n#define ALT_SIGN_EXT\t0x000100\n/* This flag affects the RC() and OERC() macros. */\n#define ALT_SET_FLAGS\t0x000400\n#define ALT_FORM1\t0x001000\n#define ALT_FORM2\t0x002000\n#define ALT_FORM3\t0x004000\n#define ALT_FORM4\t0x008000\n#define ALT_FORM5\t0x010000\n\n/* Source and destination is register. */\n#define REG_DEST\t0x000001\n#define REG1_SOURCE\t0x000002\n#define REG2_SOURCE\t0x000004\n/*\nALT_SIGN_EXT\t\t0x000100\nALT_SET_FLAGS\t\t0x000200\nALT_FORM1\t\t0x001000\n...\nALT_FORM5\t\t0x010000 */\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,\n\tsljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n#include \"sljitNativePPC_32.c\"\n#else\n#include \"sljitNativePPC_64.c\"\n#endif\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n#define STACK_STORE\tSTW\n#define STACK_LOAD\tLWZ\n#else\n#define STACK_STORE\tSTD\n#define STACK_LOAD\tLD\n#endif\n\n#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)\n#define LR_SAVE_OFFSET\t\t(2 * SSIZE_OF(sw))\n#else\n#define LR_SAVE_OFFSET\t\tSSIZE_OF(sw)\n#endif\n\n#define STACK_MAX_DISTANCE\t(0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\tsljit_s32 i, tmp, base, offset;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 arg_count = 0;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0)\n\t\t+ GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\tlocal_size += SSIZE_OF(sw);\n\n\tlocal_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\tcompiler->local_size = local_size;\n\n\tFAIL_IF(push_inst(compiler, MFLR | D(0)));\n\n\tbase = SLJIT_SP;\n\toffset = local_size;\n\n\tif (local_size <= STACK_MAX_DISTANCE) {\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\t\tFAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));\n#else\n\t\tFAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));\n#endif\n\t} else {\n\t\tbase = TMP_REG1;\n\t\tFAIL_IF(push_inst(compiler, OR | S(SLJIT_SP) | A(TMP_REG1) | B(SLJIT_SP)));\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, -local_size));\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\t\tFAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(TMP_REG2)));\n#else\n\t\tFAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(TMP_REG2)));\n#endif\n\t\tlocal_size = 0;\n\t\toffset = 0;\n\t}\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, STFD | FS(i) | A(base) | IMM(offset)));\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, STFD | FS(i) | A(base) | IMM(offset)));\n\t}\n\n\tif (!(options & SLJIT_ENTER_REG_ARG)) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(base) | IMM(offset)));\n\t}\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(base) | IMM(offset)));\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(base) | IMM(offset)));\n\t}\n\n\tFAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(base) | IMM(local_size + LR_SAVE_OFFSET)));\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tsaved_arg_count = 0;\n\n\twhile (arg_types > 0) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\t\tdo {\n\t\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\t\ttmp = SLJIT_S0 - saved_arg_count;\n\t\t\t\t\tsaved_arg_count++;\n\t\t\t\t} else if (arg_count != word_arg_count)\n\t\t\t\t\ttmp = SLJIT_R0 + word_arg_count;\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\n\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(SLJIT_R0 + arg_count) | A(tmp) | B(SLJIT_R0 + arg_count)));\n\t\t\t} while (0);\n#else\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(SLJIT_R0 + word_arg_count) | A(SLJIT_S0 - saved_arg_count) | B(SLJIT_R0 + word_arg_count)));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n#endif\n\t\t\tword_arg_count++;\n\t\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\targ_count++;\n#endif\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0)\n\t\t+ GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\n\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\tlocal_size += SSIZE_OF(sw);\n\n\tcompiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_s32 i, tmp, base, offset;\n\tsljit_s32 local_size = compiler->local_size;\n\n\tSLJIT_ASSERT(TMP_CALL_REG != TMP_REG2);\n\n\tbase = SLJIT_SP;\n\tif (local_size > STACK_MAX_DISTANCE) {\n\t\tbase = TMP_REG2;\n\t\tif (local_size > 2 * STACK_MAX_DISTANCE + LR_SAVE_OFFSET) {\n\t\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | D(base) | A(SLJIT_SP) | IMM(0)));\n\t\t\tlocal_size = 0;\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(SLJIT_SP) | IMM(local_size - STACK_MAX_DISTANCE)));\n\t\t\tlocal_size = STACK_MAX_DISTANCE;\n\t\t}\n\t}\n\n\toffset = local_size;\n\tif (!is_return_to)\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | S(0) | A(base) | IMM(offset + LR_SAVE_OFFSET)));\n\n\ttmp = SLJIT_FS0 - compiler->fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(i) | A(base) | IMM(offset)));\n\t}\n\n\tfor (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tFAIL_IF(push_inst(compiler, LFD | FS(i) | A(base) | IMM(offset)));\n\t}\n\n\tif (!(compiler->options & SLJIT_ENTER_REG_ARG)) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | S(TMP_ZERO) | A(base) | IMM(offset)));\n\t}\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\tfor (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | S(i) | A(base) | IMM(offset)));\n\t}\n\n\tfor (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | S(i) | A(base) | IMM(offset)));\n\t}\n\n\tif (!is_return_to)\n\t\tpush_inst(compiler, MTLR | S(0));\n\n\tif (local_size > 0)\n\t\treturn push_inst(compiler, ADDI | D(SLJIT_SP) | A(base) | IMM(local_size));\n\n\tSLJIT_ASSERT(base == TMP_REG2);\n\treturn push_inst(compiler, OR | S(base) | A(SLJIT_SP) | B(base));\n}\n\n#undef STACK_STORE\n#undef STACK_LOAD\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\treturn push_inst(compiler, BLR);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));\n\t\tsrc = TMP_CALL_REG;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));\n\t\tsrc = TMP_CALL_REG;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\n/* s/l - store/load (1 bit)\n   i/x - immediate/indexed form\n   u/s - signed/unsigned (1 bit)\n   w/b/h/i - word/byte/half/int allowed (2 bit)\n\n   Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */\n\n/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#define INT_ALIGNED\t0x10000\n#endif\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n#define ARCH_32_64(a, b)\ta\n#define INST_CODE_AND_DST(inst, flags, reg) \\\n\t((sljit_ins)(inst) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))\n#else\n#define ARCH_32_64(a, b)\tb\n#define INST_CODE_AND_DST(inst, flags, reg) \\\n\t(((sljit_ins)(inst) & ~(sljit_ins)INT_ALIGNED) | (sljit_ins)(((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))\n#endif\n\nstatic const sljit_ins data_transfer_insts[64 + 16] = {\n\n/* -------- Integer -------- */\n\n/* Word. */\n\n/* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),\n/* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),\n/* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),\n/* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),\n\n/* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),\n/* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),\n/* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),\n/* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),\n\n/* Byte. */\n\n/* b u i s */ HI(38) /* stb */,\n/* b u i l */ HI(34) /* lbz */,\n/* b u x s */ HI(31) | LO(215) /* stbx */,\n/* b u x l */ HI(31) | LO(87) /* lbzx */,\n\n/* b s i s */ HI(38) /* stb */,\n/* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,\n/* b s x s */ HI(31) | LO(215) /* stbx */,\n/* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,\n\n/* Half. */\n\n/* h u i s */ HI(44) /* sth */,\n/* h u i l */ HI(40) /* lhz */,\n/* h u x s */ HI(31) | LO(407) /* sthx */,\n/* h u x l */ HI(31) | LO(279) /* lhzx */,\n\n/* h s i s */ HI(44) /* sth */,\n/* h s i l */ HI(42) /* lha */,\n/* h s x s */ HI(31) | LO(407) /* sthx */,\n/* h s x l */ HI(31) | LO(343) /* lhax */,\n\n/* Int. */\n\n/* i u i s */ HI(36) /* stw */,\n/* i u i l */ HI(32) /* lwz */,\n/* i u x s */ HI(31) | LO(151) /* stwx */,\n/* i u x l */ HI(31) | LO(23) /* lwzx */,\n\n/* i s i s */ HI(36) /* stw */,\n/* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),\n/* i s x s */ HI(31) | LO(151) /* stwx */,\n/* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),\n\n/* -------- Floating point -------- */\n\n/* d   i s */ HI(54) /* stfd */,\n/* d   i l */ HI(50) /* lfd */,\n/* d   x s */ HI(31) | LO(727) /* stfdx */,\n/* d   x l */ HI(31) | LO(599) /* lfdx */,\n\n/* s   i s */ HI(52) /* stfs */,\n/* s   i l */ HI(48) /* lfs */,\n/* s   x s */ HI(31) | LO(663) /* stfsx */,\n/* s   x l */ HI(31) | LO(535) /* lfsx */,\n};\n\nstatic const sljit_ins updated_data_transfer_insts[64] = {\n\n/* -------- Integer -------- */\n\n/* Word. */\n\n/* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),\n/* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),\n/* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),\n/* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),\n\n/* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),\n/* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),\n/* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),\n/* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),\n\n/* Byte. */\n\n/* b u i s */ HI(39) /* stbu */,\n/* b u i l */ HI(35) /* lbzu */,\n/* b u x s */ HI(31) | LO(247) /* stbux */,\n/* b u x l */ HI(31) | LO(119) /* lbzux */,\n\n/* b s i s */ HI(39) /* stbu */,\n/* b s i l */ 0 /* no such instruction */,\n/* b s x s */ HI(31) | LO(247) /* stbux */,\n/* b s x l */ 0 /* no such instruction */,\n\n/* Half. */\n\n/* h u i s */ HI(45) /* sthu */,\n/* h u i l */ HI(41) /* lhzu */,\n/* h u x s */ HI(31) | LO(439) /* sthux */,\n/* h u x l */ HI(31) | LO(311) /* lhzux */,\n\n/* h s i s */ HI(45) /* sthu */,\n/* h s i l */ HI(43) /* lhau */,\n/* h s x s */ HI(31) | LO(439) /* sthux */,\n/* h s x l */ HI(31) | LO(375) /* lhaux */,\n\n/* Int. */\n\n/* i u i s */ HI(37) /* stwu */,\n/* i u i l */ HI(33) /* lwzu */,\n/* i u x s */ HI(31) | LO(183) /* stwux */,\n/* i u x l */ HI(31) | LO(55) /* lwzux */,\n\n/* i s i s */ HI(37) /* stwu */,\n/* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),\n/* i s x s */ HI(31) | LO(183) /* stwux */,\n/* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),\n\n/* -------- Floating point -------- */\n\n/* d   i s */ HI(55) /* stfdu */,\n/* d   i l */ HI(51) /* lfdu */,\n/* d   x s */ HI(31) | LO(759) /* stfdux */,\n/* d   x l */ HI(31) | LO(631) /* lfdux */,\n\n/* s   i s */ HI(53) /* stfsu */,\n/* s   i l */ HI(49) /* lfsu */,\n/* s   x s */ HI(31) | LO(695) /* stfsux */,\n/* s   x l */ HI(31) | LO(567) /* lfsux */,\n};\n\n#undef ARCH_32_64\n\n/* Simple cases, (no caching is required). */\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,\n\tsljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)\n{\n\tsljit_ins inst;\n\tsljit_s32 offs_reg;\n\n\t/* Should work when (arg & REG_MASK) == 0. */\n\tSLJIT_ASSERT(A(0) == 0);\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\t\toffs_reg = OFFS_REG(arg);\n\n\t\tif (argw != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, SLWI_W(argw) | S(OFFS_REG(arg)) | A(tmp_reg)));\n\t\t\toffs_reg = tmp_reg;\n\t\t}\n\n\t\tinst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tSLJIT_ASSERT(!(inst & INT_ALIGNED));\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\t\treturn push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));\n\t}\n\n\tinst = data_transfer_insts[inp_flags & MEM_MASK];\n\targ &= REG_MASK;\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {\n\t\tFAIL_IF(load_immediate(compiler, tmp_reg, argw));\n\n\t\tinst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];\n\t\treturn push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));\n\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (argw <= SIMM_MAX && argw >= SIMM_MIN)\n\t\treturn push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (argw <= 0x7fff7fffl && argw >= -0x80000000l) {\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\tFAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM((argw + 0x8000) >> 16)));\n\t\treturn push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t}\n\n\tFAIL_IF(load_immediate(compiler, tmp_reg, argw));\n\n\tinst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];\n\treturn push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));\n#endif /* SLJIT_CONFIG_PPC_64 */\n}\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* arg1 goes to TMP_REG1 or src reg\n\t   arg2 goes to TMP_REG2, imm or src reg\n\t   result goes to TMP_REG2, so put result can use TMP_REG1. */\n\tsljit_s32 dst_r = TMP_REG2;\n\tsljit_s32 src1_r;\n\tsljit_s32 src2_r;\n\tsljit_s32 src2_tmp_reg = (!(input_flags & ALT_SIGN_EXT) && GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;\n\tsljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);\n\n\t/* Destination check. */\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = dst;\n\t\t/* The REG_DEST is only used by SLJIT_MOV operations, although\n\t\t * it is set for op2 operations with unset destination. */\n\t\tflags |= REG_DEST;\n\n\t\tif (op >= SLJIT_MOV && op <= SLJIT_MOV_P)\n\t\t\tsrc2_tmp_reg = dst_r;\n\t}\n\n\t/* Source 2. */\n\tif (FAST_IS_REG(src2)) {\n\t\tsrc2_r = src2;\n\t\tflags |= REG2_SOURCE;\n\n\t\tif (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)\n\t\t\tdst_r = src2_r;\n\t} else if (src2 == SLJIT_IMM) {\n\t\tsrc2_r = TMP_ZERO;\n\t\tif (src2w != 0) {\n\t\t\tFAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));\n\t\t\tsrc2_r = src2_tmp_reg;\n\t\t}\n\t} else {\n\t\tFAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, src2_tmp_reg, src2, src2w, TMP_REG1));\n\t\tsrc2_r = src2_tmp_reg;\n\t}\n\n\t/* Source 1. */\n\tif (FAST_IS_REG(src1)) {\n\t\tsrc1_r = src1;\n\t\tflags |= REG1_SOURCE;\n\t} else if (src1 == SLJIT_IMM) {\n\t\tsrc1_r = TMP_ZERO;\n\t\tif (src1w != 0) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\t\tsrc1_r = TMP_REG1;\n\t\t}\n\t} else {\n\t\tFAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1_r = TMP_REG1;\n\t}\n\n\tFAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));\n\n\tif (!(dst & SLJIT_MEM))\n\t\treturn SLJIT_SUCCESS;\n\n\treturn emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 int_op = op & SLJIT_32;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\tcase SLJIT_NOP:\n\t\treturn push_inst(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n\t\tFAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tFAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));\n\t\treturn push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));\n#else\n\t\tFAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));\n\t\treturn push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));\n#endif\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tFAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));\n\t\tFAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));\n#else\n\t\tFAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));\n\t\tFAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));\n#endif\n\t\treturn push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\treturn push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));\n#else\n\t\treturn push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));\n#endif\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst(compiler, SYNC);\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 mem, offs_reg, inp_flags;\n\tsljit_sw memw;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 is_32 = op & SLJIT_32;\n\n\top = GET_OPCODE(op);\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (!((dst | src) & SLJIT_MEM)) {\n\t\t/* Both are registers. */\n\t\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {\n\t\t\tif (src == dst) {\n\t\t\t\tFAIL_IF(push_inst(compiler, RLWIMI | S(dst) | A(dst) | RLWI_SH(16) | RLWI_MBE(8, 15)));\n\t\t\t\tFAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | RLWI_SH(24) | RLWI_MBE(16, 31)));\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_inst(compiler, RLWINM | S(src) | A(dst) | RLWI_SH(8) | RLWI_MBE(16, 23)));\n\t\t\t\tFAIL_IF(push_inst(compiler, RLWIMI | S(src) | A(dst) | RLWI_SH(24) | RLWI_MBE(24, 31)));\n\t\t\t}\n\n\t\t\tif (op == SLJIT_REV_U16)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, EXTSH | S(dst) | A(dst));\n\t\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (!is_32) {\n#if defined(_ARCH_PWR10) && _ARCH_PWR10\n\t\t\treturn push_inst(compiler, BRD | S(src) | A(dst));\n#else /* !POWER10 */\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_HI)));\n\t\t\tFAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32)));\n\t\t\tFAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2)));\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_LO)));\n\t\t\tFAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(SLJIT_SP) | B(TMP_REG2)));\n\t\t\treturn push_inst(compiler, LD | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n#endif /* POWER10 */\n\t\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET)));\n\t\tFAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2)));\n\t\tFAIL_IF(push_inst(compiler, LWZ | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (op == SLJIT_REV_S32)\n\t\t\treturn push_inst(compiler, EXTSW | S(dst) | A(dst));\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tmem = src;\n\tmemw = srcw;\n\n\tif (dst & SLJIT_MEM) {\n\t\tmem = dst;\n\t\tmemw = dstw;\n\n\t\tif (src & SLJIT_MEM) {\n\t\t\tinp_flags = HALF_DATA | LOAD_DATA;\n\n\t\t\tif (op != SLJIT_REV_U16 && op != SLJIT_REV_S16) {\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\t\t\tinp_flags = (is_32 ? INT_DATA : WORD_DATA) | LOAD_DATA;\n#else /* !SLJIT_CONFIG_PPC_64 */\n\t\t\t\tinp_flags = WORD_DATA | LOAD_DATA;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src, srcw, TMP_REG2));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\t}\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\toffs_reg = OFFS_REG(mem);\n\t\tmem &= REG_MASK;\n\t\tmemw &= 0x3;\n\n\t\tif (memw != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, SLWI_W(memw) | S(offs_reg) | A(TMP_REG2)));\n\t\t\toffs_reg = TMP_REG2;\n\t\t}\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t} else if (memw > 0x7fff7fffl || memw < -0x80000000l) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, memw));\n\t\toffs_reg = TMP_REG2;\n\t\tmem &= REG_MASK;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t} else {\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(mem & REG_MASK) | IMM(memw)));\n\t\tif (memw > SIMM_MAX || memw < SIMM_MIN)\n\t\t\tFAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(TMP_REG2) | IMM((memw + 0x8000) >> 16)));\n\n\t\tmem = 0;\n\t\toffs_reg = TMP_REG2;\n\t}\n\n\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn push_inst(compiler, STHBRX | S(src) | A(mem) | B(offs_reg));\n\n\t\tFAIL_IF(push_inst(compiler, LHBRX | S(dst) | A(mem) | B(offs_reg)));\n\n\t\tif (op == SLJIT_REV_U16)\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn push_inst(compiler, EXTSH | S(dst) | A(dst));\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (!is_32) {\n\t\tif (dst & SLJIT_MEM) {\n#if defined(_ARCH_PWR7) && _ARCH_PWR7\n\t\t\treturn push_inst(compiler, STDBRX | S(src) | A(mem) | B(offs_reg));\n#else /* !POWER7 */\n#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN\n\t\t\tFAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32)));\n\t\t\tFAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(offs_reg)));\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32))));\n\t\t\treturn push_inst(compiler, STWBRX | S(src) | A(mem) | B(TMP_REG2));\n#else /* !SLJIT_LITTLE_ENDIAN */\n\t\t\tFAIL_IF(push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg)));\n\t\t\tFAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32)));\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32))));\n\t\t\treturn push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(TMP_REG2));\n#endif /* SLJIT_LITTLE_ENDIAN */\n#endif /* POWER7 */\n\t\t}\n#if defined(_ARCH_PWR7) && _ARCH_PWR7\n\t\treturn push_inst(compiler, LDBRX | S(dst) | A(mem) | B(offs_reg));\n#else /* !POWER7 */\n\t\tFAIL_IF(push_inst(compiler, LWBRX | LWBRX_FIRST_REG | A(mem) | B(offs_reg)));\n\t\tFAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32))));\n\t\tFAIL_IF(push_inst(compiler, LWBRX | LWBRX_SECOND_REG | A(mem) | B(TMP_REG2)));\n\t\treturn push_inst(compiler, RLDIMI | S(TMP_REG1) | A(dst) | RLDI_SH(32) | RLDI_MB(0));\n#endif /* POWER7 */\n\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (dst & SLJIT_MEM)\n\t\treturn push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg));\n\n\tFAIL_IF(push_inst(compiler, LWBRX | S(dst) | A(mem) | B(offs_reg)));\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (op == SLJIT_REV_S32)\n\t\treturn push_inst(compiler, EXTSW | S(dst) | A(dst));\n#endif /* SLJIT_CONFIG_PPC_64 */\n\treturn SLJIT_SUCCESS;\n}\n\n#define EMIT_MOV(type, type_flags, type_cast) \\\n\temit_op(compiler, (src == SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? type_cast srcw : srcw)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;\n\tsljit_s32 op_flags = GET_ALL_FLAGS(op);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\top = GET_OPCODE(op);\n\n\tif (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)\n\t\tFAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));\n\n\tif (op <= SLJIT_MOV_P && FAST_IS_REG(src) && src == dst) {\n\t\tif (!TYPE_CAST_NEEDED(op))\n\t\t\treturn SLJIT_SUCCESS;\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (op_flags & SLJIT_32) {\n\t\tif (op <= SLJIT_MOV_P) {\n\t\t\tif (src & SLJIT_MEM) {\n\t\t\t\tif (op == SLJIT_MOV_S32)\n\t\t\t\t\top = SLJIT_MOV_U32;\n\t\t\t}\n\t\t\telse if (src == SLJIT_IMM) {\n\t\t\t\tif (op == SLJIT_MOV_U32)\n\t\t\t\t\top = SLJIT_MOV_S32;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t/* Most operations expect sign extended arguments. */\n\t\t\tflags |= INT_DATA | SIGNED_DATA;\n\t\t\tif (HAS_FLAGS(op_flags))\n\t\t\t\tflags |= ALT_SIGN_EXT;\n\t\t}\n\t}\n#endif\n\n\tswitch (op) {\n\tcase SLJIT_MOV:\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n#endif\n\tcase SLJIT_MOV_P:\n\t\treturn emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tcase SLJIT_MOV_U32:\n\t\treturn EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));\n\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\treturn EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));\n#endif\n\n\tcase SLJIT_MOV_U8:\n\t\treturn EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));\n\n\tcase SLJIT_MOV_S8:\n\t\treturn EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));\n\n\tcase SLJIT_MOV_U16:\n\t\treturn EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));\n\n\tcase SLJIT_MOV_S16:\n\t\treturn EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (op_flags & SLJIT_32)\n\t\t\tflags |= ALT_FORM1;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\treturn emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\top |= SLJIT_32;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\top |= (op_flags & SLJIT_32);\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\treturn emit_rev(compiler, op, dst, dstw, src, srcw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef EMIT_MOV\n\n/* Macros for checking different operand types / values. */\n#define TEST_SL_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)\n#define TEST_UL_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && !((srcw) & ~0xffff))\n#define TEST_UH_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && !((srcw) & ~(sljit_sw)0xffff0000))\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n#define TEST_SH_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)\n#define TEST_ADD_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)\n#define TEST_UI_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && !((srcw) & ~0xffffffff))\n\n#define TEST_ADD_FORM1(op) \\\n\t(GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \\\n\t\t|| (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY))\n#define TEST_SUB_FORM2(op) \\\n\t((GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) \\\n\t\t|| (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z))\n#define TEST_SUB_FORM3(op) \\\n\t(GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \\\n\t\t|| (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z))\n\n#else /* !SLJIT_CONFIG_PPC_64 */\n#define TEST_SH_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM && !((srcw) & 0xffff))\n#define TEST_ADD_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM)\n#define TEST_UI_IMM(src, srcw) \\\n\t((src) == SLJIT_IMM)\n\n#define TEST_ADD_FORM1(op) \\\n\t(GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)\n#define TEST_SUB_FORM2(op) \\\n\t(GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL)\n#define TEST_SUB_FORM3(op) \\\n\t(GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)\n#endif /* SLJIT_CONFIG_PPC_64 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (op & SLJIT_32) {\n\t\t/* Most operations expect sign extended arguments. */\n\t\tflags |= INT_DATA | SIGNED_DATA;\n\t\tif (src1 == SLJIT_IMM)\n\t\t\tsrc1w = (sljit_s32)(src1w);\n\t\tif (src2 == SLJIT_IMM)\n\t\t\tsrc2w = (sljit_s32)(src2w);\n\t\tif (HAS_FLAGS(op))\n\t\t\tflags |= ALT_SIGN_EXT;\n\t}\n#endif\n\tif (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)\n\t\tFAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\n\t\tif (TEST_ADD_FORM1(op))\n\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);\n\n\t\tif (!HAS_FLAGS(op) && (src1 == SLJIT_IMM || src2 == SLJIT_IMM)) {\n\t\t\tif (TEST_SL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SL_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SH_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)(src2w >> 16) & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SH_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)(src1w >> 16) & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t\t/* Range between -1 and -32768 is covered above. */\n\t\t\tif (TEST_ADD_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffffffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_ADD_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffffffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif ((op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z)) {\n\t\t\tif (TEST_SL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SL_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n#endif\n\t\tif (HAS_FLAGS(op)) {\n\t\t\tif (TEST_SL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SL_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\t\treturn emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\treturn emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SUB:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\n\t\tif (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {\n\t\t\tif (dst == TMP_REG1) {\n\t\t\t\tif (TEST_UL_IMM(src2, src2w)) {\n\t\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t\t}\n\t\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);\n\t\t\t}\n\n\t\t\tif (src2 == SLJIT_IMM && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w;\n\t\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n\n\t\tif (dst == TMP_REG1 && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {\n\t\t\tif (TEST_SL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n\n\t\tif (TEST_SUB_FORM2(op)) {\n\t\t\tif (src2 == SLJIT_IMM && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);\n\t\t}\n\n\t\tif (TEST_SUB_FORM3(op))\n\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);\n\n\t\tif (TEST_SL_IMM(src2, -src2w)) {\n\t\t\tcompiler->imm = (sljit_ins)(-src2w) & 0xffff;\n\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | (!HAS_FLAGS(op) ? ALT_FORM2 : ALT_FORM3), dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t}\n\n\t\tif (TEST_SL_IMM(src1, src1w) && !(op & SLJIT_SET_Z)) {\n\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffff;\n\t\t\treturn emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t}\n\n\t\tif (!HAS_FLAGS(op)) {\n\t\t\tif (TEST_SH_IMM(src2, -src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)((-src2w) >> 16) & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags |  ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\t/* Range between -1 and -32768 is covered above. */\n\t\t\tif (TEST_ADD_IMM(src2, -src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)-src2w;\n\t\t\t\treturn emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\n\t\t/* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */\n\t\treturn emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\treturn emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_MUL:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (op & SLJIT_32)\n\t\t\tflags |= ALT_FORM2;\n#endif\n\t\tif (!HAS_FLAGS(op)) {\n\t\t\tif (TEST_SL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_SL_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w & 0xffff;\n\t\t\t\treturn emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));\n\t\treturn emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_XOR:\n\t\tif (src2 == SLJIT_IMM && src2w == -1) {\n\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src1, src1w);\n\t\t}\n\t\tif (src1 == SLJIT_IMM && src1w == -1) {\n\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src2, src2w);\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\t\t/* Commutative unsigned operations. */\n\t\tif (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {\n\t\t\tif (TEST_UL_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_UL_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_UH_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)(src2w >> 16) & 0xffff;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_UH_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)(src1w >> 16) & 0xffff;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\t\tif (!HAS_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {\n\t\t\t/* Unlike or and xor, the and resets unwanted bits as well. */\n\t\t\tif (TEST_UI_IMM(src2, src2w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src2w;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t\t}\n\t\t\tif (TEST_UI_IMM(src1, src1w)) {\n\t\t\t\tcompiler->imm = (sljit_ins)src1w;\n\t\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);\n\t\t\t}\n\t\t}\n\t\treturn emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (op & SLJIT_32)\n\t\t\tflags |= ALT_FORM2;\n#endif\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tcompiler->imm = (sljit_ins)src2w;\n\t\t\treturn emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);\n\t\t}\n\t\treturn emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);\n}\n\n#undef TEST_ADD_FORM1\n#undef TEST_SUB_FORM2\n#undef TEST_SUB_FORM3\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));\n\t\treturn push_inst(compiler, ADD | D(dst_reg) | A(dst_reg) | B(TMP_REG2));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_right;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\tsljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_PPC_64 */\n\tsljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n\tsljit_sw bit_length = 32;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= bit_length - 1;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (!(op & SLJIT_32)) {\n\t\t\tif (is_right) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SRDI(src3w) | S(src1_reg) | A(dst_reg)));\n\t\t\t\treturn push_inst(compiler, RLDIMI | S(src2_reg) | A(dst_reg) | RLDI_SH(64 - src3w) | RLDI_MB(0));\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, SLDI(src3w) | S(src1_reg) | A(dst_reg)));\n\t\t\t/* Computes SRDI(64 - src2w). */\n\t\t\tFAIL_IF(push_inst(compiler, RLDICL | S(src2_reg) | A(TMP_REG1) | RLDI_SH(src3w) | RLDI_MB(64 - src3w)));\n\t\t\treturn push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1));\n\t\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\t\tif (is_right) {\n\t\t\tFAIL_IF(push_inst(compiler, SRWI(src3w) | S(src1_reg) | A(dst_reg)));\n\t\t\treturn push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(32 - src3w) | RLWI_MBE(0, src3w - 1));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, SLWI(src3w) | S(src1_reg) | A(dst_reg)));\n\t\treturn push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(src3w) | RLWI_MBE(32 - src3w, 31));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w, TMP_REG2));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (!(op & SLJIT_32)) {\n\t\tif (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) {\n\t\t\tFAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x3f));\n\t\t\tsrc3 = TMP_REG2;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src1_reg) | A(dst_reg) | B(src3)));\n\t\tFAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src2_reg) | A(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x3f));\n\t\tFAIL_IF(push_inst(compiler, (is_right ? SLD : SRD) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));\n\t\treturn push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1));\n\t}\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) {\n\t\tFAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x1f));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src1_reg) | A(dst_reg) | B(src3)));\n\tFAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src2_reg) | A(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x1f));\n\tFAIL_IF(push_inst(compiler, (is_right ? SLW : SRW) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));\n\treturn push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, tmp_r, src2, src2w, tmp_r));\n\t\tsrc2 = tmp_r;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tFAIL_IF(push_inst(compiler, SLWI_W(shift_arg) | S(src2) | A(tmp_r)));\n\tFAIL_IF(push_inst(compiler, ADD | D(dst_r) | A(src1) | B(tmp_r)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_prefetch(struct sljit_compiler *compiler,\n        sljit_s32 src, sljit_sw srcw)\n{\n\tif (!(src & OFFS_REG_MASK)) {\n\t\tif (srcw == 0 && (src & REG_MASK))\n\t\t\treturn push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw));\n\t\t/* Works with SLJIT_MEM0() case as well. */\n\t\treturn push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));\n\t}\n\n\tsrcw &= 0x3;\n\n\tif (srcw == 0)\n\t\treturn push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));\n\n\tFAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1)));\n\treturn push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src))\n\t\t\tFAIL_IF(push_inst(compiler, MTLR | S(src)));\n\t\telse {\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG2));\n\t\t\tFAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));\n\t\t}\n\n\t\treturn push_inst(compiler, BLR);\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\treturn emit_prefetch(compiler, src, srcw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst))\n\t\t\treturn push_inst(compiler, MFLR | D(dst));\n\n\t\tFAIL_IF(push_inst(compiler, MFLR | D(TMP_REG1)));\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + LR_SAVE_OFFSET, TMP_REG2));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_DATA, TMP_REG1, dst, dstw, TMP_REG2);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type != SLJIT_FLOAT_REGISTER)\n\t\treturn -1;\n\n\treturn freg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double))\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tif (src & SLJIT_MEM) {\n\t\t/* We can ignore the temporary data store on the stack from caching point of view. */\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));\n\t\tsrc = TMP_FREG1;\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\top = GET_OPCODE(op);\n\tFAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));\n\n\tif (op == SLJIT_CONV_SW_FROM_F64) {\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tFAIL_IF(push_inst(compiler, STFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\t\t\treturn push_inst(compiler, LD | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t\t}\n\t\treturn emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);\n\t}\n#else /* !SLJIT_CONFIG_PPC_64 */\n\tFAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (FAST_IS_REG(dst)) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, TMP_MEM_OFFSET));\n\t\tFAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));\n\t\treturn push_inst(compiler, LWZ | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n\t}\n\n\tSLJIT_ASSERT(dst & SLJIT_MEM);\n\n\tif (dst & OFFS_REG_MASK) {\n\t\tdstw &= 0x3;\n\t\tif (dstw) {\n\t\t\tFAIL_IF(push_inst(compiler, SLWI_W(dstw) | S(OFFS_REG(dst)) | A(TMP_REG1)));\n\t\t\tdstw = TMP_REG1;\n\t\t} else\n\t\t\tdstw = OFFS_REG(dst);\n\t}\n\telse {\n\t\tif ((dst & REG_MASK) && !dstw) {\n\t\t\tdstw = dst & REG_MASK;\n\t\t\tdst = 0;\n\t\t} else {\n\t\t\t/* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, dstw));\n\t\t\tdstw = TMP_REG1;\n\t\t}\n\t}\n\n\treturn push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tFAIL_IF(push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)));\n\n\tswitch (GET_FLAG_TYPE(op)) {\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn push_inst(compiler, CROR | ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11));\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn push_inst(compiler, CROR | ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11));\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn push_inst(compiler, CROR | ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\top ^= SLJIT_32;\n\t\tif (op & SLJIT_32) {\n\t\t\tFAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));\n\t\t\tbreak;\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG1));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));\n\t\tbreak;\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));\n\t\tbreak;\n\tcase SLJIT_COPYSIGN_F64:\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(src2) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\t\tFAIL_IF(push_inst(compiler, LWZ | S(TMP_REG1) | A(SLJIT_SP) | ((op & SLJIT_32) ? TMP_MEM_OFFSET : TMP_MEM_OFFSET_HI)));\n#else /* !SLJIT_CONFIG_PPC_32 */\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n#endif /* SLJIT_CONFIG_PPC_32 */\n\t\tFAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src1)));\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\t\tFAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(TMP_REG1) | 0));\n#else /* !SLJIT_CONFIG_PPC_32 */\n\t\tFAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((op & SLJIT_32) ? 0 : 1)) | A(TMP_REG1) | 0));\n#endif /* SLJIT_CONFIG_PPC_32 */\n\t\tFAIL_IF(push_inst(compiler, BCx | (4 << 21) | (0 << 16) | 8));\n\t\treturn push_inst(compiler, FNEG | FD(dst_r) | FB(dst_r));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef SELECT_FOP\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));\n\n\tFAIL_IF(push_inst(compiler, STW | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));\n\treturn push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nstatic sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_NOT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)\n\t\t\treturn (4 << 21) | (2 << 16);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\t\treturn (12 << 21) | (2 << 16);\n\n\tcase SLJIT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)\n\t\t\treturn (12 << 21) | (2 << 16);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\treturn (4 << 21) | (2 << 16);\n\n\tcase SLJIT_LESS:\n\tcase SLJIT_SIG_LESS:\n\t\treturn (12 << 21) | (0 << 16);\n\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\treturn (4 << 21) | (0 << 16);\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_GREATER:\n\t\treturn (12 << 21) | (1 << 16);\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\t\treturn (4 << 21) | (1 << 16);\n\n\tcase SLJIT_OVERFLOW:\n\t\treturn (12 << 21) | (3 << 16);\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\treturn (4 << 21) | (3 << 16);\n\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn (12 << 21) | ((4 + 0) << 16);\n\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\treturn (4 << 21) | ((4 + 0) << 16);\n\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn (12 << 21) | ((4 + 1) << 16);\n\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn (4 << 21) | ((4 + 1) << 16);\n\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn (12 << 21) | ((4 + 2) << 16);\n\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\treturn (4 << 21) | ((4 + 2) << 16);\n\n\tcase SLJIT_UNORDERED:\n\t\treturn (12 << 21) | ((4 + 3) << 16);\n\n\tcase SLJIT_ORDERED:\n\t\treturn (4 << 21) | ((4 + 3) << 16);\n\n\tdefault:\n\t\tSLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_REG_ARG);\n\t\treturn (20 << 21);\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins bo_bi_flags;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tbo_bi_flags = get_bo_bi_flags(compiler, type & 0xff);\n\tif (!bo_bi_flags)\n\t\treturn NULL;\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, (sljit_u32)type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tif ((type | 0x1) == SLJIT_NOT_CARRY)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG2) | A(TMP_ZERO) | B(TMP_ZERO)));\n\n\t/* In PPC, we don't need to touch the arguments. */\n\tif (type < SLJIT_JUMP)\n\t\tjump->flags |= IS_COND;\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)\n\tif (type >= SLJIT_CALL)\n\t\tjump->flags |= IS_CALL;\n#endif\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tPTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));\n#endif\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump = NULL;\n\tsljit_s32 src_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src == SLJIT_IMM) {\n\t\t/* These jumps are converted to jump/call instructions when possible. */\n\t\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\t\tFAIL_IF(!jump);\n\t\tset_jump(jump, compiler, JUMP_ADDR);\n\t\tjump->u.target = (sljit_uw)srcw;\n\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)\n\t\tif (type >= SLJIT_CALL)\n\t\t\tjump->flags |= IS_CALL;\n#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */\n\n\t\tjump->addr = compiler->size;\n\t\tFAIL_IF(push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)));\n\n\t\t/* Maximum number of instructions required for generating a constant. */\n\t\tcompiler->size += JUMP_MAX_SIZE - 1;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(src)) {\n#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)\n\t\tif (type >= SLJIT_CALL && src != TMP_CALL_REG) {\n\t\t\tFAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));\n\t\t\tsrc_r = TMP_CALL_REG;\n\t\t} else\n\t\t\tsrc_r = src;\n#else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */\n\t\tsrc_r = src;\n#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */\n\t} else {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));\n\t\tsrc_r = TMP_CALL_REG;\n\t}\n\n\tFAIL_IF(push_inst(compiler, MTCTR | S(src_r)));\n\treturn push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));\n\t\tsrc = TMP_CALL_REG;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tFAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));\n\t\t\tsrc = TMP_CALL_REG;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tFAIL_IF(call_with_args(compiler, arg_types, &src));\n#endif\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 reg, invert;\n\tsljit_u32 bit, from_xer;\n\tsljit_s32 saved_op = op;\n\tsljit_sw saved_dstw = dstw;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 input_flags = ((op & SLJIT_32) || op == SLJIT_MOV32) ? INT_DATA : WORD_DATA;\n#else\n\tsljit_s32 input_flags = WORD_DATA;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\treg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;\n\n\tif (op >= SLJIT_ADD && (dst & SLJIT_MEM))\n\t\tFAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));\n\n\tinvert = 0;\n\tbit = 0;\n\tfrom_xer = 0;\n\n\tswitch (type) {\n\tcase SLJIT_LESS:\n\tcase SLJIT_SIG_LESS:\n\t\tbreak;\n\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_GREATER:\n\t\tbit = 1;\n\t\tbreak;\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\t\tbit = 1;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\t\tbit = 2;\n\t\tbreak;\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\tbit = 2;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_OVERFLOW:\n\t\tfrom_xer = 1;\n\t\tbit = 1;\n\t\tbreak;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\tfrom_xer = 1;\n\t\tbit = 1;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_CARRY:\n\t\tfrom_xer = 1;\n\t\tbit = 2;\n\t\tinvert = (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB) != 0;\n\t\tbreak;\n\n\tcase SLJIT_NOT_CARRY:\n\t\tfrom_xer = 1;\n\t\tbit = 2;\n\t\tinvert = (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD) != 0;\n\t\tbreak;\n\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\tbit = 4 + 0;\n\t\tbreak;\n\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\tbit = 4 + 0;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tbit = 4 + 1;\n\t\tbreak;\n\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\tbit = 4 + 1;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\tbit = 4 + 2;\n\t\tbreak;\n\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\tbit = 4 + 2;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tcase SLJIT_UNORDERED:\n\t\tbit = 4 + 3;\n\t\tbreak;\n\n\tcase SLJIT_ORDERED:\n\t\tbit = 4 + 3;\n\t\tinvert = 1;\n\t\tbreak;\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\tbreak;\n\t}\n\n\tFAIL_IF(push_inst(compiler, (from_xer ? MFXER : MFCR) | D(reg)));\n\t/* Simplified mnemonics: extrwi. */\n\tFAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | RLWI_SH(1 + bit) | RLWI_MBE(31, 31)));\n\n\tif (invert)\n\t\tFAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));\n\n\tif (op < SLJIT_ADD) {\n\t\tif (!(dst & SLJIT_MEM))\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\n\tif (dst & SLJIT_MEM)\n\t\treturn sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);\n\treturn sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_ins *ptr;\n\tsljit_uw size;\n\tsljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);\n\tsljit_ins ins;\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tsljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n#else /* !SLJIT_CONFIG_PPC_64 */\n        sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tif (src1 == SLJIT_IMM && (type & SLJIT_32))\n\t\tsrc1w = (sljit_s32)src1w;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\ttype &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\n\tif (is_compare) {\n\t\tins = 0;\n\n\t\tif (src1 & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w, TMP_REG1));\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t}\n\n\t\tif (src1 == SLJIT_IMM) {\n\t\t\tif (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL && src1w >= 0 && src1w <= UIMM_MAX)\n\t\t\t\tins = CMPLI | CRD(0) | IMM(src1w);\n\t\t\telse if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL && src1w >= SIMM_MIN && src1w <= SIMM_MAX)\n\t\t\t\tins = CMPI | CRD(0) | IMM(src1w);\n\t\t\telse {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w));\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\tsrc1w = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (ins == 0)\n\t\t\tins = ((type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL) ? CMPL : CMP) | CRD(0) | B(src1);\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif (inp_flags == (WORD_DATA | LOAD_DATA))\n\t\t\tins |= CRD(1);\n#endif /* SLJIT_CONFIG_PPC_64 */\n\t\tFAIL_IF(push_inst(compiler, ins | A(src2_reg)));\n\t\ttype ^= 0x1;\n\t}\n\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\t\tsrc1 = src2_reg;\n\t\t\t\tsrc1w = 0;\n\t\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tif (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, OR | S(dst_reg) | A(TMP_REG1) | B(dst_reg)));\n\n\t\t\t\tif ((src1 & REG_MASK) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~REG_MASK) | TMP_REG1;\n\n\t\t\t\tif (OFFS_REG(src1) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, OR | S(src2_reg) | A(dst_reg) | B(src2_reg)));\n\t\t}\n\t}\n\n\tif ((type | 0x1) == SLJIT_NOT_CARRY)\n\t\tFAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO)));\n\n\tsize = compiler->size;\n\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w, TMP_REG1));\n\t} else if (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, dst_reg, src1w));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, OR | S(src1) | A(dst_reg) | B(src1)));\n\n\t*ptr = BCx | get_bo_bi_flags(compiler, type ^ 0x1) | (sljit_ins)((compiler->size - size) << 2);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_ins *ptr;\n\tsljit_uw size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src2_freg)));\n\t}\n\n\tif (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY)\n\t\tFAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO)));\n\n\tsize = compiler->size;\n\n\tptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size++;\n\n\tif (src1 & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w, TMP_REG1));\n\telse\n\t\tFAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src1)));\n\n\t*ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2);\n\treturn SLJIT_SUCCESS;\n}\n\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\n#define EMIT_MEM_LOAD_IMM(inst, mem, memw) \\\n\t((sljit_s16)(memw) > SIMM_MAX - SSIZE_OF(sw))\n\n#else /* !SLJIT_CONFIG_PPC_32 */\n\n#define EMIT_MEM_LOAD_IMM(inst, mem, memw) \\\n\t((((inst) & INT_ALIGNED) && ((memw) & 0x3) != 0) \\\n\t\t|| ((sljit_s16)(memw) > SIMM_MAX - SSIZE_OF(sw)) \\\n\t\t|| ((memw) > 0x7fff7fffl || (memw) < -0x80000000l)) \\\n\n#endif /* SLJIT_CONFIG_PPC_32 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tinst = data_transfer_insts[WORD_DATA | ((type & SLJIT_MEM_STORE) ? 0 : LOAD_DATA)];\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tmemw &= 0x3;\n\n\t\tif (memw != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, SLWI_W(memw) | S(OFFS_REG(mem)) | A(TMP_REG1)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD | D(TMP_REG1) | A(TMP_REG1) | B(mem & REG_MASK)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADD | D(TMP_REG1) | A(mem & REG_MASK) | B(OFFS_REG(mem))));\n\n\t\tmem = TMP_REG1;\n\t\tmemw = 0;\n\t} else {\n\t\tif (EMIT_MEM_LOAD_IMM(inst, mem, memw)) {\n\t\t\tif ((mem & REG_MASK) != 0) {\n\t\t\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\t\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_ADD, TMP_REG1, 0, mem & REG_MASK, 0, SLJIT_IMM, memw));\n\t\t\t} else\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw));\n\n\t\t\tmemw = 0;\n\t\t\tmem = TMP_REG1;\n\t\t} else if (memw > SIMM_MAX || memw < SIMM_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(mem & REG_MASK) | IMM((memw + 0x8000) >> 16)));\n\n\t\t\tmemw &= 0xffff;\n\t\t\tmem = TMP_REG1;\n\t\t} else {\n\t\t\tmemw &= 0xffff;\n\t\t\tmem &= REG_MASK;\n\t\t}\n\t}\n\n\tSLJIT_ASSERT((memw >= 0 && memw <= SIMM_MAX - SSIZE_OF(sw)) || (memw >= 0x8000 && memw <= 0xffff));\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tinst &= (sljit_ins)~INT_ALIGNED;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tif (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {\n\t\tFAIL_IF(push_inst(compiler, inst | D(REG_PAIR_SECOND(reg)) | A(mem) | IMM(memw + SSIZE_OF(sw))));\n\t\treturn push_inst(compiler, inst | D(REG_PAIR_FIRST(reg)) | A(mem) | IMM(memw));\n\t}\n\n\tFAIL_IF(push_inst(compiler, inst | D(REG_PAIR_FIRST(reg)) | A(mem) | IMM(memw)));\n\treturn push_inst(compiler, inst | D(REG_PAIR_SECOND(reg)) | A(mem) | IMM(memw + SSIZE_OF(sw)));\n}\n\n#undef EMIT_MEM_LOAD_IMM\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 mem_flags;\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));\n\n\tif (type & SLJIT_MEM_POST)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (type & 0xff) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n#endif\n\t\tmem_flags = WORD_DATA;\n\t\tbreak;\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV32:\n\t\tmem_flags = INT_DATA;\n\t\tbreak;\n\n\tcase SLJIT_MOV_S32:\n\t\tmem_flags = INT_DATA;\n\n\t\tif (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_32)) {\n\t\t\tif (mem & OFFS_REG_MASK)\n\t\t\t\tmem_flags |= SIGNED_DATA;\n\t\t\telse\n\t\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\t}\n\t\tbreak;\n#endif\n\n\tcase SLJIT_MOV_U8:\n\tcase SLJIT_MOV_S8:\n\t\tmem_flags = BYTE_DATA;\n\t\tbreak;\n\n\tcase SLJIT_MOV_U16:\n\t\tmem_flags = HALF_DATA;\n\t\tbreak;\n\n\tcase SLJIT_MOV_S16:\n\t\tmem_flags = HALF_DATA | SIGNED_DATA;\n\t\tbreak;\n\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\tmem_flags = WORD_DATA;\n\t\tbreak;\n\t}\n\n\tif (!(type & SLJIT_MEM_STORE))\n\t\tmem_flags |= LOAD_DATA;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tif (memw != 0)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tif (type & SLJIT_MEM_SUPP)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tinst = updated_data_transfer_insts[mem_flags | INDEXED];\n\t\tFAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));\n\t}\n\telse {\n\t\tif (memw > SIMM_MAX || memw < SIMM_MIN)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tinst = updated_data_transfer_insts[mem_flags];\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tif ((inst & INT_ALIGNED) && (memw & 0x3) != 0)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif\n\n\t\tif (type & SLJIT_MEM_SUPP)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));\n\t}\n\n\tif ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)\n\t\treturn push_inst(compiler, EXTSB | S(reg) | A(reg));\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 freg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 mem_flags;\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));\n\n\tif (type & SLJIT_MEM_POST)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tif (memw != 0)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\telse {\n\t\tif (memw > SIMM_MAX || memw < SIMM_MIN)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (type & SLJIT_MEM_SUPP)\n\t\treturn SLJIT_SUCCESS;\n\n\tmem_flags = FLOAT_DATA(type);\n\n\tif (!(type & SLJIT_MEM_STORE))\n\t\tmem_flags |= LOAD_DATA;\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tinst = updated_data_transfer_insts[mem_flags | INDEXED];\n\t\treturn push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));\n\t}\n\n\tinst = updated_data_transfer_insts[mem_flags];\n\treturn push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tins = LDARX;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV32:\n\t\tins = LWARX;\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | D(dst_reg) | B(mem_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\n\t/* temp_reg == mem_reg is undefined so use another temp register */\n\tSLJIT_UNUSED_ARG(temp_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_CAS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\t\tins = STDCX | 0x1;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV32:\n\t\tins = STWCX | 0x1;\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | D(src_reg) | B(mem_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_DATA;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tif (init_value & 0x100)\n\t\t\tinit_value |= 0xff00;\n\t\telse\n\t\t\tinit_value &= 0xff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDI | D(dst_r) | A(0) | IMM(init_value)));\n\t\tmem_flags = BYTE_DATA;\n\t\tbreak;\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tcase SLJIT_MOV32:\n\t\tmem_flags = INT_DATA;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_S32:\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDIS | D(dst_r) | A(0) | IMM(init_value >> 16)));\n\t\tPTR_FAIL_IF(push_inst(compiler, ORI | S(dst_r) | A(dst_r) | IMM(init_value)));\n\t\tbreak;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tdefault:\n\t\tPTR_FAIL_IF(emit_const(compiler, dst_r, init_value));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG1));\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, dst, dstw, TMP_REG1));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\tPTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r));\n#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)\n\tcompiler->size++;\n#else\n\tcompiler->size += 4;\n#endif\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, ADD | D(dst_r) | A(dst_r) | B(TMP_REG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_ins *inst;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tinst = (sljit_ins *)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDI);\n\n\t\tif (new_constant & 0x100)\n\t\t\tnew_constant |= 0xff00;\n\t\telse\n\t\t\tnew_constant &= 0xff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);\n\t\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_constant);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 1);\n\t\treturn;\n\n#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tinst = (sljit_ins *)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[0] = (inst[0] & 0xffff0000) | IMM(new_constant >> 16);\n\t\tinst[1] = (inst[1] & 0xffff0000) | IMM(new_constant);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n#endif /* SLJIT_CONFIG_PPC_64 */\n\n\tdefault:\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)\n{\n\tSLJIT_UNUSED_ARG(tmp_r);\n\n\tif (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)\n\t\treturn push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm));\n\n\tif (imm <= SIMM_MAX && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));\n\n\tif (imm & 0x800)\n\t\timm += 0x1000;\n\n\tif (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)\n\t\tFAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));\n\telse\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~(sljit_sw)0xfff)));\n\n\timm &= 0xfff;\n\n\tif (imm == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))\n\t\treturn push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm));\n\n\treturn push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_s32 imm[2];\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm[0] != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0], TMP_REG3));\n\tif (u.imm[1] != 0)\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1], TMP_REG3));\n\n\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16)));\n\tFAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | (8 << 7)));\n\tFAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | (12 << 7)));\n\tFAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8)));\n\treturn push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_ins inst;\n\tsljit_s32 reg2 = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (op & SLJIT_32) {\n\t\tif (op == SLJIT_COPY32_TO_F32)\n\t\t\tinst = FMV_W_X | RS1(reg) | FRD(freg);\n\t\telse\n\t\t\tinst = FMV_X_W | FRS1(freg) | RD(reg);\n\n\t\treturn push_inst(compiler, inst);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16)));\n\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\t}\n\n\tif (op == SLJIT_COPY_TO_F64) {\n\t\tif (reg2 != 0)\n\t\t\tFAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg2) | (8 << 7)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, FSW | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7)));\n\n\t\tFAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg) | (12 << 7)));\n\t\tFAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8)));\n\t} else {\n\t\tFAIL_IF(push_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7)));\n\n\t\tif (reg2 != 0)\n\t\t\tFAIL_IF(push_inst(compiler, FMV_X_W | FRS1(freg) | RD(reg2)));\n\n\t\tFAIL_IF(push_inst(compiler, LW | RD(reg) | RS1(SLJIT_SP) | IMM_I(12)));\n\t}\n\n\treturn push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16));\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins)\n{\n\tif ((init_value & 0x800) != 0)\n\t\tinit_value += 0x1000;\n\n\tFAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff)));\n\treturn push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst = (sljit_u16*)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif ((new_target & 0x800) != 0)\n\t\tnew_target += 0x1000;\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);\n\n\tSLJIT_ASSERT((inst[0] & 0x7f) == LUI);\n\tinst[0] = (sljit_u16)((inst[0] & 0xfff) | (new_target & 0xf000));\n\tinst[1] = (sljit_u16)(new_target >> 16);\n\tSLJIT_ASSERT((inst[2] & 0x707f) == ADDI || (inst[2] & 0x707f) == JALR);\n\tinst[3] = (sljit_u16)((inst[3] & 0xf) | (new_target << 4));\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);\n\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 4);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nstatic sljit_s32 load_immediate32(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm)\n{\n\tSLJIT_ASSERT((imm <= 0x7fffffffl && imm > SIMM_MAX) || (imm >= S32_MIN && imm < SIMM_MIN));\n\n\tif (imm > S32_MAX) {\n\t\tSLJIT_ASSERT((imm & 0x800) != 0);\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));\n\t\treturn push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000) {\n\t\tif (imm > 0x1f7ff) {\n\t\t\tSLJIT_ASSERT((imm & 0x800) != 0);\n\t\t\tFAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | (sljit_u16)0x1000));\n\t\t\treturn push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));\n\t\t}\n\n\t\tif ((imm & 0x800) != 0)\n\t\t\timm += 0x1000;\n\n\t\tFAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));\n\t} else {\n\t\tif ((imm & 0x800) != 0)\n\t\t\timm += 0x1000;\n\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~(sljit_sw)0xfff)));\n\t}\n\n\timm &= 0xfff;\n\n\tif (imm == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))\n\t\treturn push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm));\n\n\treturn push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));\n}\n\nstatic sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)\n{\n\tsljit_sw high, shift;\n\n\tif (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)\n\t\treturn push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm));\n\n\tif (imm <= SIMM_MAX && imm >= SIMM_MIN)\n\t\treturn push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));\n\n\tif (imm <= 0x7fffffffl && imm >= S32_MIN)\n\t\treturn load_immediate32(compiler, dst_r, imm);\n\n\t/* Shifted small immediates. */\n\n\thigh = imm;\n\tshift = 0;\n\twhile ((high & 0xff) == 0) {\n\t\thigh >>= 8;\n\t\tshift += 8;\n\t}\n\n\tif ((high & 0xf) == 0) {\n\t\thigh >>= 4;\n\t\tshift += 4;\n\t}\n\n\tif ((high & 0x3) == 0) {\n\t\thigh >>= 2;\n\t\tshift += 2;\n\t}\n\n\tif ((high & 0x1) == 0) {\n\t\thigh >>= 1;\n\t\tshift += 1;\n\t}\n\n\tif (high <= 0x7fffffffl && high >= S32_MIN) {\n\t\tload_immediate(compiler, dst_r, high, tmp_r);\n\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\treturn push_inst16(compiler, C_SLLI | C_RD(dst_r) | C_IMM_I(shift));\n\t\treturn push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(shift));\n\t}\n\n\t/* Trailing zeroes could be used to produce shifted immediates. */\n\n\tif (imm <= 0x7ffffffffffl && imm >= -0x80000000000l) {\n\t\thigh = imm >> 12;\n\n\t\tif (imm & 0x800)\n\t\t\thigh = ~high;\n\n\t\tFAIL_IF(load_immediate32(compiler, dst_r, high));\n\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\tFAIL_IF(push_inst16(compiler, C_SLLI | C_RD(dst_r) | (sljit_u16)(12 << 2)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));\n\n\t\tSLJIT_ASSERT((imm & 0xfff) != 0);\n\t\treturn push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));\n\t}\n\n\tSLJIT_ASSERT(dst_r != tmp_r);\n\n\thigh = imm >> 32;\n\timm = (sljit_s32)imm;\n\n\tif ((imm & 0x80000000l) != 0)\n\t\thigh = ~high;\n\n\tif (high <= 0x7ffff && high >= -0x80000) {\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high << 12)));\n\t\thigh = 0x1000;\n\t} else {\n\t\tif ((high & 0x800) != 0)\n\t\t\thigh += 0x1000;\n\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(tmp_r) | (sljit_ins)(high & ~0xfff)));\n\t\thigh &= 0xfff;\n\t}\n\n\tif (imm <= SIMM_MAX && imm >= SIMM_MIN) {\n\t\tif (RISCV_HAS_COMPRESSED(200) && imm <= 0x1f && imm >= -0x20)\n\t\t\tFAIL_IF(push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));\n\t\timm = 0;\n\t} else if (imm > S32_MAX) {\n\t\tSLJIT_ASSERT((imm & 0x800) != 0);\n\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));\n\t\timm = 0x1000 | (imm & 0xfff);\n\t} else {\n\t\tif ((imm & 0x800) != 0)\n\t\t\timm += 0x1000;\n\n\t\tif (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)\n\t\t\tFAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));\n\t\timm &= 0xfff;\n\t}\n\n\tif ((high & 0xfff) != 0) {\n\t\tSLJIT_ASSERT(high <= 0xfff);\n\t\tif (RISCV_HAS_COMPRESSED(200) && (high <= 0x1f || high >= 0xfe0))\n\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI | C_RD(tmp_r) | C_IMM_I(high)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));\n\t}\n\n\tif (imm & 0x1000)\n\t\tFAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));\n\telse if (imm != 0) {\n\t\tSLJIT_ASSERT(imm <= 0xfff);\n\t\tif (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))\n\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200))\n\t\tFAIL_IF(push_inst16(compiler, C_SLLI | C_RD(tmp_r) | (sljit_u16)((high & 0x1000) ? (20 << 2) : (1 << 12))));\n\telse\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));\n\treturn push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_ZERO) | FRD(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3));\n\treturn push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_REG1) | FRD(freg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_ins inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64)\n\t\tinst = FMV_W_X | RS1(reg) | FRD(freg);\n\telse\n\t\tinst = FMV_X_W | FRS1(freg) | RD(reg);\n\n\tif (!(op & SLJIT_32))\n\t\tinst |= (sljit_ins)1 << 25;\n\n\treturn push_inst(compiler, inst);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins)\n{\n\tsljit_sw high;\n\n\tif ((init_value & 0x800) != 0)\n\t\tinit_value += 0x1000;\n\n\thigh = init_value >> 32;\n\n\tif ((init_value & 0x80000000l) != 0)\n\t\thigh = ~high;\n\n\tif ((high & 0x800) != 0)\n\t\thigh += 0x1000;\n\n\tFAIL_IF(push_inst(compiler, LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff)));\n\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high)));\n\tFAIL_IF(push_inst(compiler, LUI | RD(dst) | (sljit_ins)(init_value & ~0xfff)));\n\tFAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(32)));\n\tFAIL_IF(push_inst(compiler, XOR | RD(dst) | RS1(dst) | RS2(TMP_REG3)));\n\treturn push_inst(compiler, last_ins | RS1(dst) | IMM_I(init_value));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst = (sljit_u16*)addr;\n\tsljit_sw high;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif ((new_target & 0x800) != 0)\n\t\tnew_target += 0x1000;\n\n\thigh = (sljit_sw)new_target >> 32;\n\n\tif ((new_target & 0x80000000l) != 0)\n\t\thigh = ~high;\n\n\tif ((high & 0x800) != 0)\n\t\thigh += 0x1000;\n\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 12, 0);\n\n\tSLJIT_ASSERT((inst[0] & 0x7f) == LUI);\n\tinst[0] = (sljit_u16)((inst[0] & 0xfff) | (high & 0xf000));\n\tinst[1] = (sljit_u16)(high >> 16);\n\tSLJIT_ASSERT((inst[2] & 0x707f) == ADDI);\n\tinst[3] = (sljit_u16)((inst[3] & 0xf) | (high << 4));\n\tSLJIT_ASSERT((inst[4] & 0x7f) == LUI);\n\tinst[4] = (sljit_u16)((inst[4] & 0xfff) | (new_target & 0xf000));\n\tinst[5] = (sljit_u16)(new_target >> 16);\n\tSLJIT_ASSERT((inst[10] & 0x707f) == ADDI || (inst[10] & 0x707f) == JALR);\n\tinst[11] = (sljit_u16)((inst[11] & 0xf) | (new_target << 4));\n\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 12, 1);\n\n\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\tSLJIT_CACHE_FLUSH(inst, inst + 12);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#if !(defined SLJIT_CONFIG_RISCV_ATOMIC) && defined(__riscv_atomic)\n/* Auto detect atomic instruction support. */\n#define SLJIT_CONFIG_RISCV_ATOMIC 200\n#endif /* !SLJIT_CONFIG_RISCV_ATOMIC && __riscv_atomic */\n\n/* SLJIT_CONFIG_RISCV_ATOMIC enables/disables atomic instruction\n   support. Non-zero values represents the highest version of the feature\n   that is supported by the CPU.\n   Allowed values: 0 - disabled, 200 - 2.00 */\n#if (defined SLJIT_CONFIG_RISCV_ATOMIC && SLJIT_CONFIG_RISCV_ATOMIC != 0)\n#if SLJIT_CONFIG_RISCV_ATOMIC != 200\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_ATOMIC\"\n#endif\n#define RISCV_HAS_ATOMIC(x) ((SLJIT_CONFIG_RISCV_ATOMIC) >= (x))\n#define RISCV_ATOMIC_INFO \"a\"\n#else /* !SLJIT_CONFIG_RISCV_ATOMIC || SLJIT_CONFIG_RISCV_ATOMIC == 0 */\n#define RISCV_HAS_ATOMIC(x) 0\n#define RISCV_ATOMIC_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_ATOMIC && SLJIT_CONFIG_RISCV_ATOMIC != 0 */\n\n#if !(defined SLJIT_CONFIG_RISCV_COMPRESSED) && defined(__riscv_compressed)\n/* Auto detect compressed instruction support. */\n#define SLJIT_CONFIG_RISCV_COMPRESSED 200\n#endif /* !SLJIT_CONFIG_RISCV_COMPRESSED && __riscv_compressed */\n\n/* SLJIT_CONFIG_RISCV_COMPRESSED enables/disables compressed instruction\n   support. Non-zero values represents the highest version of the feature\n   that is supported by the CPU.\n   Allowed values: 0 - disabled, 200 - 2.00 */\n#if (defined SLJIT_CONFIG_RISCV_COMPRESSED && SLJIT_CONFIG_RISCV_COMPRESSED != 0)\n#if SLJIT_CONFIG_RISCV_COMPRESSED != 200\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_COMPRESSED\"\n#endif\n#define RISCV_HAS_COMPRESSED(x) ((SLJIT_CONFIG_RISCV_COMPRESSED) >= (x))\n#define RISCV_COMPRESSED_CHECK(x) (x)\n#define RISCV_COMPRESSED_INFO \"c\"\n#else /* !SLJIT_CONFIG_RISCV_COMPRESSED || SLJIT_CONFIG_RISCV_COMPRESSED == 0 */\n#define RISCV_HAS_COMPRESSED(x) 0\n#define RISCV_COMPRESSED_CHECK(x) 0\n#define RISCV_COMPRESSED_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_COMPRESSED && SLJIT_CONFIG_RISCV_COMPRESSED != 0 */\n\n#if !(defined SLJIT_CONFIG_RISCV_VECTOR) && defined(__riscv_vector)\n/* Auto detect vector instruction support. */\n#define SLJIT_CONFIG_RISCV_VECTOR 100\n#endif /* !SLJIT_CONFIG_RISCV_VECTOR && __riscv_vector */\n\n/* SLJIT_CONFIG_RISCV_VECTOR enables/disables vector instruction\n   support. Non-zero values represents the highest version of the feature\n   that is supported by the CPU.\n   Allowed values: 0 - disabled, 100 - 1.00 */\n#if (defined SLJIT_CONFIG_RISCV_VECTOR && SLJIT_CONFIG_RISCV_VECTOR != 0)\n#if SLJIT_CONFIG_RISCV_VECTOR != 100\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_VECTOR\"\n#endif\n#define RISCV_HAS_VECTOR(x) ((SLJIT_CONFIG_RISCV_VECTOR) >= (x))\n#define RISCV_VECTOR_INFO \"v\"\n#else /* !SLJIT_CONFIG_RISCV_VECTOR || SLJIT_CONFIG_RISCV_VECTOR == 0 */\n#define RISCV_HAS_VECTOR(x) 0\n#define RISCV_VECTOR_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_VECTOR && SLJIT_CONFIG_RISCV_VECTOR != 0 */\n\n#if !(defined SLJIT_CONFIG_RISCV_BITMANIP_A) && defined(__riscv_zba)\n/* Auto detect bit manipulation extension A instruction support. */\n#define SLJIT_CONFIG_RISCV_BITMANIP_A 93\n#endif /* !SLJIT_CONFIG_RISCV_BITMANIP_A && __riscv_zba */\n\n/* SLJIT_CONFIG_RISCV_BITMANIP_A enables/disables bit manipulation extension A\n   instruction support. Non-zero values represents the highest version of the\n   feature that is supported by the CPU.\n   Allowed values: 0 - disabled, 93 - 0.93 */\n#if (defined SLJIT_CONFIG_RISCV_BITMANIP_A && SLJIT_CONFIG_RISCV_BITMANIP_A != 0)\n#if SLJIT_CONFIG_RISCV_BITMANIP_A != 93\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_BITMANIP_A\"\n#endif\n#define RISCV_HAS_BITMANIP_A(x) ((SLJIT_CONFIG_RISCV_BITMANIP_A) >= (x))\n#define RISCV_BITMANIP_A_INFO \"_zba\"\n#else /* !SLJIT_CONFIG_RISCV_BITMANIP_A || SLJIT_CONFIG_RISCV_BITMANIP_A == 0 */\n#define RISCV_HAS_BITMANIP_A(x) 0\n#define RISCV_BITMANIP_A_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_BITMANIP_A && SLJIT_CONFIG_RISCV_BITMANIP_A != 0 */\n\n#if !(defined SLJIT_CONFIG_RISCV_BITMANIP_B) && defined(__riscv_zbb)\n/* Auto detect bit manipulation extension B instruction support. */\n#define SLJIT_CONFIG_RISCV_BITMANIP_B 93\n#endif /* !SLJIT_CONFIG_RISCV_BITMANIP_B && __riscv_zbb */\n\n/* SLJIT_CONFIG_RISCV_BITMANIP_B enables/disables bit manipulation extension B\n   instruction support. Non-zero values represents the highest version of the\n   feature that is supported by the CPU.\n   Allowed values: 0 - disabled, 93 - 0.93 */\n#if (defined SLJIT_CONFIG_RISCV_BITMANIP_B && SLJIT_CONFIG_RISCV_BITMANIP_B != 0)\n#if SLJIT_CONFIG_RISCV_BITMANIP_B != 93\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_BITMANIP_B\"\n#endif\n#define RISCV_HAS_BITMANIP_B(x) ((SLJIT_CONFIG_RISCV_BITMANIP_B) >= (x))\n#define RISCV_BITMANIP_B_INFO \"_zbb\"\n#else /* !SLJIT_CONFIG_RISCV_BITMANIP_B || SLJIT_CONFIG_RISCV_BITMANIP_B == 0 */\n#define RISCV_HAS_BITMANIP_B(x) 0\n#define RISCV_BITMANIP_B_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_BITMANIP_B && SLJIT_CONFIG_RISCV_BITMANIP_B != 0 */\n\n#if !(defined SLJIT_CONFIG_RISCV_ICOND) && defined(__riscv_zicond)\n/* Auto detect integer conditional instruction support. */\n#define SLJIT_CONFIG_RISCV_ICOND 100\n#endif /* !SLJIT_CONFIG_RISCV_ICOND && __riscv_zicond */\n\n/* SLJIT_CONFIG_RISCV_ICOND enables/disables integer conditional\n   instruction support. Non-zero values represents the highest version of the\n   feature that is supported by the CPU.\n   Allowed values: 0 - disabled, 100 - 1.00 */\n#if (defined SLJIT_CONFIG_RISCV_ICOND && SLJIT_CONFIG_RISCV_ICOND != 0)\n#if SLJIT_CONFIG_RISCV_ICOND != 100\n#error \"Unsupported value for SLJIT_CONFIG_RISCV_ICOND\"\n#endif\n#define RISCV_HAS_ICOND(x) ((SLJIT_CONFIG_RISCV_ICOND) >= (x))\n#define RISCV_ICOND_INFO \"_zicond\"\n#else /* !SLJIT_CONFIG_RISCV_ICOND || SLJIT_CONFIG_RISCV_ICOND == 0 */\n#define RISCV_HAS_ICOND(x) 0\n#define RISCV_ICOND_INFO \"\"\n#endif /* SLJIT_CONFIG_RISCV_ICOND && SLJIT_CONFIG_RISCV_ICOND != 0 */\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n#define RISCV_CHECK_COMPRESSED_JUMP(jump, diff, unit) \\\n\t(!((jump)->flags & IS_CALL) && (diff) >= (JUMP16_MIN / SSIZE_OF(unit)) && (diff) <= (JUMP16_MAX / SSIZE_OF(unit)))\n#else /* !SLJIT_CONFIG_RISCV_64 */\n#define RISCV_CHECK_COMPRESSED_JUMP(jump, diff, unit) \\\n\t((diff) >= (JUMP16_MIN / SSIZE_OF(unit)) && (diff) <= (JUMP16_MAX / SSIZE_OF(unit)))\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\t/* The arch string is not entirely correct since 'g' contains 'a'. */\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\treturn \"RISC-V-32 (rv32g\" RISCV_ATOMIC_INFO RISCV_COMPRESSED_INFO RISCV_VECTOR_INFO RISCV_BITMANIP_A_INFO RISCV_BITMANIP_B_INFO RISCV_ICOND_INFO \")\" SLJIT_CPUINFO;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\treturn \"RISC-V-64 (rv64g\" RISCV_ATOMIC_INFO RISCV_COMPRESSED_INFO RISCV_VECTOR_INFO RISCV_BITMANIP_A_INFO RISCV_BITMANIP_B_INFO RISCV_ICOND_INFO \")\" SLJIT_CPUINFO;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n}\n\n/* Most instructions are 32 bit long on RISCV.\n   Code is processed as 16 bit units. */\ntypedef sljit_u32 sljit_ins;\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n#define TMP_REG3\t(SLJIT_NUMBER_OF_REGISTERS + 4)\n#define TMP_ZERO\t0\n\n/* Flags are kept in volatile registers. */\n#define EQUAL_FLAG\t(SLJIT_NUMBER_OF_REGISTERS + 5)\n#define RETURN_ADDR_REG\tTMP_REG2\n#define OTHER_FLAG\t(SLJIT_NUMBER_OF_REGISTERS + 6)\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n#define TMP_FREG2\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)\n\n#define TMP_VREG1\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1)\n#define TMP_VREG2\t(SLJIT_NUMBER_OF_VECTOR_REGISTERS + 2)\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {\n\t0, 10, 11, 12, 13, 14, 15, 16, 17, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 2, 6, 1, 7, 5, 28\n};\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {\n\t0, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 0, 1,\n};\n\nstatic const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {\n\t0, 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, 26, 27, 28, 29, 30, 31\n};\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                     */\n/* --------------------------------------------------------------------- */\n\n#define RD(rd)\t\t((sljit_ins)reg_map[rd] << 7)\n#define RS1(rs1)\t((sljit_ins)reg_map[rs1] << 15)\n#define RS2(rs2)\t((sljit_ins)reg_map[rs2] << 20)\n#define FRD(rd)\t\t((sljit_ins)freg_map[rd] << 7)\n#define FRS1(rs1)\t((sljit_ins)freg_map[rs1] << 15)\n#define FRS2(rs2)\t((sljit_ins)freg_map[rs2] << 20)\n#define VRD(rd)\t\t((sljit_ins)vreg_map[rd] << 7)\n#define VRS1(rs1)\t((sljit_ins)vreg_map[rs1] << 15)\n#define VRS2(rs2)\t((sljit_ins)vreg_map[rs2] << 20)\n#define IMM_I(imm)\t((sljit_ins)(imm) << 20)\n#define IMM_S(imm)\t((((sljit_ins)(imm) & 0xfe0) << 20) | (((sljit_ins)(imm) & 0x1f) << 7))\n#define C_RD(rd)\t((sljit_u16)((sljit_u16)reg_map[rd] << 7))\n#define C_RS2(rd)\t((sljit_u16)((sljit_u16)reg_map[rd] << 2))\n#define C_FRD(rd)\t((sljit_u16)((sljit_u16)freg_map[rd] << 7))\n#define C_FRS2(rd)\t((sljit_u16)((sljit_u16)freg_map[rd] << 2))\n#define C_RS1_R3(rs1)\t((sljit_u16)((sljit_u16)(reg_map[rs1] & 0x7) << 7))\n#define C_RS2_R3(rs2)\t((sljit_u16)((sljit_u16)(reg_map[rs2] & 0x7) << 2))\n#define C_FRS2_R3(rs2)\t((sljit_u16)((sljit_u16)(freg_map[rs2] & 0x7) << 2))\n#define C_IS_R3(r)\t((reg_map[r] & 0x18) == 0x08)\n#define C_IS_FR3(r)\t((freg_map[r] & 0x18) == 0x08)\n#define C_IMM_I(imm)\t((sljit_u16)((((imm) & 0x1f) << 2) | (((imm) & 0x20) << 7)))\n#define C_LD32_SP(imm)\t((sljit_u16)((((imm) & 0x1c) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0xc0) >> 4)))\n#define C_ST32_SP(imm)\t((sljit_u16)((((imm) & 0x3c) << 7) | (((imm) & 0xc0) << 1)))\n#define C_LD64_SP(imm)\t((sljit_u16)((((imm) & 0x18) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0x1c0) >> 4)))\n#define C_ST64_SP(imm)\t((sljit_u16)((((imm) & 0x38) << 7) | (((imm) & 0x1c0) << 1)))\n#define C_MEM32(imm)\t((sljit_u16)((((imm) & 0x4) << 4) | (((imm) & 0x38) << 7) | (((imm) & 0x40) >> 1)))\n#define C_MEM64(imm)\t((sljit_u16)((((imm) & 0x38) << 7) | (((imm) & 0xc0) >> 1)))\n#define C_BRN16(imm)\t((sljit_u16)((((imm) & 0x6) << 2) | (((imm) & 0x18) << 7) | (((imm) & 0x20) >> 3) | (((imm) & 0xc0) >> 1) | (((imm) & 0x100) << 4)))\n#define C_JMP16(imm)\t((sljit_u16)((((imm) & 0xb40) << 1) | (((imm) & 0xe) << 2) | (((imm) & 0x10) << 7) | (((imm) & 0x20) >> 3) | (((imm) & 0x80) >> 1) | (((imm) & 0x400) >> 2)))\n\n/* Represents funct(i) parts of the instructions. */\n#define OPC(o)\t\t((sljit_ins)(o))\n#define C_OPC(o1, o2)\t((sljit_u16)((o1) | ((o2) << 13)))\n#define F3(f)\t\t((sljit_ins)(f) << 12)\n#define F12(f)\t\t((sljit_ins)(f) << 20)\n#define F7(f)\t\t((sljit_ins)(f) << 25)\n\n/* Vector instruction types. */\n#define OPFVF\t\t(F3(0x5) | OPC(0x57))\n#define OPFVV\t\t(F3(0x1) | OPC(0x57))\n#define OPIVI\t\t(F3(0x3) | OPC(0x57))\n#define OPIVV\t\t(F3(0x0) | OPC(0x57))\n#define OPIVX\t\t(F3(0x4) | OPC(0x57))\n#define OPMVV\t\t(F3(0x2) | OPC(0x57))\n#define OPMVX\t\t(F3(0x6) | OPC(0x57))\n\n#define ADD\t\t(F7(0x0) | F3(0x0) | OPC(0x33))\n#define ADDI\t\t(F3(0x0) | OPC(0x13))\n#define AND\t\t(F7(0x0) | F3(0x7) | OPC(0x33))\n#define ANDI\t\t(F3(0x7) | OPC(0x13))\n#define AUIPC\t\t(OPC(0x17))\n#define BEQ\t\t(F3(0x0) | OPC(0x63))\n#define BNE\t\t(F3(0x1) | OPC(0x63))\n#define BLT\t\t(F3(0x4) | OPC(0x63))\n#define BGE\t\t(F3(0x5) | OPC(0x63))\n#define BLTU\t\t(F3(0x6) | OPC(0x63))\n#define BGEU\t\t(F3(0x7) | OPC(0x63))\n/* C_*: compressed */\n#define C_ADD\t\t(C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))\n#define C_ADDI\t\t(C_OPC(0x1, 0x0))\n#define C_ADDIW\t\t(C_OPC(0x1, 0x1))\n#define C_ADDW\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(7 << 10) | (sljit_u16)(1 << 5))\n#define C_ADDI16SP\t(C_OPC(0x1, 0x3) | (sljit_u16)(2 << 7))\n#define C_AND\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(3 << 5))\n#define C_ANDI\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(2 << 10))\n#define C_BEQZ\t\t(C_OPC(0x1, 0x6))\n#define C_BNEZ\t\t(C_OPC(0x1, 0x7))\n#define C_EBREAK\t(C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))\n#define C_FLDSP\t\t(C_OPC(0x2, 0x1))\n#define C_FLWSP\t\t(C_OPC(0x2, 0x3))\n#define C_FSD\t\t(C_OPC(0x0, 0x5))\n#define C_FSDSP\t\t(C_OPC(0x2, 0x5))\n#define C_FSW\t\t(C_OPC(0x0, 0x7))\n#define C_FSWSP\t\t(C_OPC(0x2, 0x7))\n#define C_J\t\t(C_OPC(0x1, 0x5))\n#define C_JR\t\t(C_OPC(0x2, 0x4))\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define C_JAL\t\t(C_OPC(0x1, 0x1))\n#endif\n#define C_JALR\t\t(C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))\n#define C_LI\t\t(C_OPC(0x1, 0x2))\n#define C_LUI\t\t(C_OPC(0x1, 0x3))\n#define C_LDSP\t\t(C_OPC(0x2, 0x3))\n#define C_LWSP\t\t(C_OPC(0x2, 0x2))\n#define C_MV\t\t(C_OPC(0x2, 0x4))\n#define C_NOP\t\t(C_OPC(0x1, 0x0))\n#define C_SD\t\t(C_OPC(0x0, 0x7))\n#define C_SDSP\t\t(C_OPC(0x2, 0x7))\n#define C_SLLI\t\t(C_OPC(0x2, 0x0))\n#define C_OR\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(2 << 5))\n#define C_SRAI\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(1 << 10))\n#define C_SRLI\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(0 << 10))\n#define C_SUB\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(0 << 5))\n#define C_SW\t\t(C_OPC(0x0, 0x6))\n#define C_SWSP\t\t(C_OPC(0x2, 0x6))\n#define C_XOR\t\t(C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(1 << 5))\n/* CLZ / CTZ: zbb */\n#define CLZ\t\t(F7(0x30) | F3(0x1) | OPC(0x13))\n#define CTZ\t\t(F7(0x30) | F12(0x1) | F3(0x1) | OPC(0x13))\n#define CZERO_EQZ\t(F7(0x7) | F3(0x5) | OPC(0x33))\n#define CZERO_NEZ\t(F7(0x7) | F3(0x7) | OPC(0x33))\n#define DIV\t\t(F7(0x1) | F3(0x4) | OPC(0x33))\n#define DIVU\t\t(F7(0x1) | F3(0x5) | OPC(0x33))\n#define EBREAK\t\t(F12(0x1) | F3(0x0) | OPC(0x73))\n#define FADD_S\t\t(F7(0x0) | F3(0x7) | OPC(0x53))\n#define FDIV_S\t\t(F7(0xc) | F3(0x7) | OPC(0x53))\n#define FENCE\t\t(F3(0x0) | OPC(0xf))\n#define FEQ_S\t\t(F7(0x50) | F3(0x2) | OPC(0x53))\n#define FLD\t\t(F3(0x3) | OPC(0x7))\n#define FLE_S\t\t(F7(0x50) | F3(0x0) | OPC(0x53))\n#define FLT_S\t\t(F7(0x50) | F3(0x1) | OPC(0x53))\n/* These conversion opcodes are partly defined. */\n#define FCVT_S_D\t(F7(0x20) | OPC(0x53))\n#define FCVT_S_W\t(F7(0x68) | OPC(0x53))\n#define FCVT_S_WU\t(F7(0x68) | F12(0x1) | OPC(0x53))\n#define FCVT_W_S\t(F7(0x60) | F3(0x1) | OPC(0x53))\n#define FMUL_S\t\t(F7(0x8) | F3(0x7) | OPC(0x53))\n#define FMV_X_W\t\t(F7(0x70) | F3(0x0) | OPC(0x53))\n#define FMV_W_X\t\t(F7(0x78) | F3(0x0) | OPC(0x53))\n#define FSD\t\t(F3(0x3) | OPC(0x27))\n#define FSGNJ_S\t\t(F7(0x10) | F3(0x0) | OPC(0x53))\n#define FSGNJN_S\t(F7(0x10) | F3(0x1) | OPC(0x53))\n#define FSGNJX_S\t(F7(0x10) | F3(0x2) | OPC(0x53))\n#define FSUB_S\t\t(F7(0x4) | F3(0x7) | OPC(0x53))\n#define FSW\t\t(F3(0x2) | OPC(0x27))\n#define JAL\t\t(OPC(0x6f))\n#define JALR\t\t(F3(0x0) | OPC(0x67))\n#define LD\t\t(F3(0x3) | OPC(0x3))\n#define LUI\t\t(OPC(0x37))\n#define LW\t\t(F3(0x2) | OPC(0x3))\n/* LR: atomic */\n#define LR\t\t(F7(0x8) | OPC(0x2f))\n#define MAX\t\t(F7(0x5) | F3(0x6) | OPC(0x33))\n#define MAXU\t\t(F7(0x5) | F3(0x7) | OPC(0x33))\n#define MIN\t\t(F7(0x5) | F3(0x4) | OPC(0x33))\n#define MINU\t\t(F7(0x5) | F3(0x5) | OPC(0x33))\n#define MUL\t\t(F7(0x1) | F3(0x0) | OPC(0x33))\n#define MULH\t\t(F7(0x1) | F3(0x1) | OPC(0x33))\n#define MULHU\t\t(F7(0x1) | F3(0x3) | OPC(0x33))\n#define NOP\t\tADDI\n#define OR\t\t(F7(0x0) | F3(0x6) | OPC(0x33))\n#define ORI\t\t(F3(0x6) | OPC(0x13))\n#define REM\t\t(F7(0x1) | F3(0x6) | OPC(0x33))\n#define REMU\t\t(F7(0x1) | F3(0x7) | OPC(0x33))\n/* REV8 / ROL / ROR / RORI: zbb */\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define REV8\t\t(F12(0x698) | F3(0x5) | OPC(0x13))\n#elif (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n#define REV8\t\t(F12(0x6b8) | F3(0x5) | OPC(0x13))\n#endif /* SLJIT_CONFIG_RISCV_32 */\n#define ROL\t\t(F7(0x30) | F3(0x1) | OPC(0x33))\n#define ROR\t\t(F7(0x30) | F3(0x5) | OPC(0x33))\n#define RORI\t\t(F7(0x30) | F3(0x5) | OPC(0x13))\n/* SC: atomic */\n#define SC\t\t(F7(0xc) | OPC(0x2f))\n#define SD\t\t(F3(0x3) | OPC(0x23))\n/* SEXTB / SEXTH: zbb */\n#define SEXTB\t\t(F7(0x30) | F12(0x4) | F3(0x1) | OPC(0x13))\n#define SEXTH\t\t(F7(0x30) | F12(0x5) | F3(0x1) | OPC(0x13))\n/* SH1ADD / SH2ADD / SH3ADD: zba */\n#define SH1ADD\t\t(F7(0x10) | F3(0x2) | OPC(0x33))\n#define SH2ADD\t\t(F7(0x10) | F3(0x4) | OPC(0x33))\n#define SH3ADD\t\t(F7(0x10) | F3(0x6) | OPC(0x33))\n#define SLL\t\t(F7(0x0) | F3(0x1) | OPC(0x33))\n#define SLLI\t\t(F3(0x1) | OPC(0x13))\n#define SLT\t\t(F7(0x0) | F3(0x2) | OPC(0x33))\n#define SLTI\t\t(F3(0x2) | OPC(0x13))\n#define SLTU\t\t(F7(0x0) | F3(0x3) | OPC(0x33))\n#define SLTUI\t\t(F3(0x3) | OPC(0x13))\n#define SRL\t\t(F7(0x0) | F3(0x5) | OPC(0x33))\n#define SRLI\t\t(F3(0x5) | OPC(0x13))\n#define SRA\t\t(F7(0x20) | F3(0x5) | OPC(0x33))\n#define SRAI\t\t(F7(0x20) | F3(0x5) | OPC(0x13))\n#define SUB\t\t(F7(0x20) | F3(0x0) | OPC(0x33))\n#define SW\t\t(F3(0x2) | OPC(0x23))\n/* V*: vector */\n#define VAND_VV\t\t(F7(0x13) | OPIVV)\n#define VFMV_FS\t\t(F7(0x21) | OPFVV)\n#define VFMV_SF\t\t(F7(0x21) | OPFVF)\n#define VFMV_VF\t\t(F7(0x2f) | OPFVF)\n#define VFWCVT_FFV\t(F7(0x25) | (0xc << 15) | OPFVV)\n#define VL\t\t(F7(0x1) | OPC(0x7))\n#define VMSLE_VI\t(F7(0x3b) | OPIVI)\n#define VMV_SX\t\t(F7(0x21) | OPMVX)\n#define VMV_VI\t\t(F7(0x2f) | OPIVI)\n#define VMV_VV\t\t(F7(0x2f) | OPIVV)\n#define VMV_VX\t\t(F7(0x2f) | OPIVX)\n#define VMV_XS\t\t(F7(0x21) | OPMVV)\n#define VOR_VV\t\t(F7(0x15) | OPIVV)\n#define VSETVLI\t\t(F7(0x0) | F3(0x7) | OPC(0x57))\n#define VSETIVLI\t(F7(0x60) | F3(0x7) | OPC(0x57))\n#define VS\t\t(F7(0x1) | OPC(0x27))\n#define VSLIDEDOWN_VX\t(F7(0x1f) | OPIVX)\n#define VSLIDEDOWN_VI\t(F7(0x1f) | OPIVI)\n#define VSLIDEUP_VX\t(F7(0x1d) | OPIVX)\n#define VSLIDEUP_VI\t(F7(0x1d) | OPIVI)\n#define VRGATHER_VI\t(F7(0x19) | OPIVI)\n#define VRGATHER_VV\t(F7(0x19) | OPIVV)\n#define VXOR_VV\t\t(F7(0x17) | OPIVV)\n#define VZEXT_VF2\t(F7(0x25) | (0x6 << 15) | OPMVV)\n#define VZEXT_VF4\t(F7(0x25) | (0x4 << 15) | OPMVV)\n#define VZEXT_VF8\t(F7(0x25) | (0x2 << 15) | OPMVV)\n#define XOR\t\t(F7(0x0) | F3(0x4) | OPC(0x33))\n#define XORI\t\t(F3(0x4) | OPC(0x13))\n/* ZEXTH: zbb */\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define ZEXTH\t\t(F7(0x4) | F3(0x4) | OPC(0x33))\n#else /* SLJIT_CONFIG_RISCV_64 */\n#define ZEXTH\t\t(F7(0x4) | F3(0x4) | OPC(0x3B))\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n#define SIMM_MAX\t(0x7ff)\n#define SIMM_MIN\t(-0x800)\n#define SIMM16_MAX\t(0x1f)\n#define SIMM16_MIN\t(-0x20)\n#define BRANCH_MAX\t(0xfff)\n#define BRANCH_MIN\t(-0x1000)\n#define BRANCH16_MAX\t(0xff)\n#define BRANCH16_MIN\t(-0x100)\n#define JUMP_MAX\t(0xfffff)\n#define JUMP_MIN\t(-0x100000)\n#define JUMP16_MAX\tSIMM_MAX\n#define JUMP16_MIN\tSIMM_MIN\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n#define S32_MAX\t\t(0x7ffff7ffl)\n#define S32_MIN\t\t(-0x80000000l)\n#define S44_MAX\t\t(0x7fffffff7ffl)\n#define S52_MAX\t\t(0x7ffffffffffffl)\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n#define C_ADDI_W(word)\t(C_ADDI | (sljit_u16)((word) << 10))\n#define C_SUB_W(word)\t(C_SUB | (sljit_u16)((word) << 9))\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define BRANCH_LENGTH\t\t((sljit_ins)(3 * sizeof(sljit_ins)) << 7)\n#define BRANCH16_LENGTH\t\tC_BRN16(5 * sizeof(sljit_u16))\n#else /* !SLJIT_CONFIG_RISCV_32 */\n#define BRANCH_LENGTH\t\t((sljit_ins)(7 * sizeof(sljit_ins)) << 7)\n#define BRANCH16_LENGTH\t\tC_BRN16(13 * sizeof(sljit_u16))\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)\n{\n\tsljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tptr[0] = (sljit_u16)ins;\n\tptr[1] = (sljit_u16)(ins >> 16);\n\tcompiler->size += 2;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_u16 ins)\n{\n\tsljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));\n\tFAIL_IF(!ptr);\n\t*ptr = ins;\n\tcompiler->size++;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 push_imm_s_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_sw imm)\n{\n\treturn push_inst(compiler, ins | IMM_S(imm));\n}\n\nstatic SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)\n{\n\tsljit_sw diff, cond_diff;\n\tsljit_uw target_addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_uw orig_addr = jump->addr;\n\tsljit_ins ins;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_s32 jalr_offset = JUMP_MAX_SIZE - 1;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tjump->addr = jump_addr;\n\tif (jump->flags & SLJIT_REWRITABLE_JUMP)\n\t\tgoto exit;\n\n\tif (jump->flags & JUMP_ADDR)\n\t\ttarget_addr = jump->u.target;\n\telse {\n\t\tSLJIT_ASSERT(jump->u.label != NULL);\n\t\ttarget_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > orig_addr)\n\t\t\tjump_addr = (sljit_uw)(code + orig_addr);\n\t}\n\n\tdiff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (jump->flags & IS_COND) {\n\t\tcond_diff = diff + SSIZE_OF(ins);\n\n\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16))) {\n\t\t\tSLJIT_ASSERT((code_ptr[-1] & 0xe003) == C_BEQZ || (code_ptr[-1] & 0xe003) == C_BNEZ);\n\n\t\t\tcond_diff = diff + SSIZE_OF(u16);\n\n\t\t\tif (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) {\n\t\t\t\tcode_ptr--;\n\t\t\t\tcode_ptr[0] = (sljit_u16)((code_ptr[0] & 0xe383) ^ 0x2000);\n\t\t\t\tjump->flags |= PATCH_B | PATCH_16;\n\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\t\treturn code_ptr;\n\t\t\t}\n\t\t}\n\n\t\tif (cond_diff >= BRANCH_MIN && cond_diff <= BRANCH_MAX) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16))) {\n\t\t\t\t/* Converting 16 bit branch to 32 bit branch. */\n\t\t\t\tcode_ptr--;\n\t\t\t\tcode_ptr[1] = (sljit_u16)(((code_ptr[0] & 0x300) >> 8) | 0x4);\n\t\t\t\tcode_ptr[0] = (sljit_u16)((BNE ^ ((code_ptr[0] & 0x2000) >> 1)) | ((code_ptr[0] & 0x80) << 8));\n\t\t\t} else {\n\t\t\t\tcode_ptr -= 2;\n\t\t\t\tcode_ptr[0] = (sljit_u16)((code_ptr[0] & 0xf07f) ^ 0x1000);\n\t\t\t\tcode_ptr[1] = (sljit_u16)(code_ptr[1] & 0x1ff);\n\t\t\t}\n\n\t\t\tjump->flags |= PATCH_B;\n\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\treturn code_ptr + 1;\n\t\t}\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200) && RISCV_CHECK_COMPRESSED_JUMP(jump, diff, u8)) {\n\t\t/* A conditional instruction has larger max offset\n\t\t   than a 16 bit jump instruction. */\n\t\tSLJIT_ASSERT(!(jump->flags & IS_COND));\n\t\tjump->flags |= PATCH_J | PATCH_16;\n\t\treturn code_ptr;\n\t}\n\n\tif (diff >= JUMP_MIN && diff <= JUMP_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))\n\t\t\t\tcode_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(3 * sizeof(sljit_u16)));\n\t\t\telse\n\t\t\t\tcode_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (2 * sizeof(sljit_ins) << 7));\n\t\t}\n\n\t\tjump->flags |= PATCH_J;\n\t\treturn code_ptr + 1;\n\t}\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (diff >= S32_MIN && diff <= S32_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))\n\t\t\t\tcode_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(5 * sizeof(sljit_u16)));\n\t\t\telse\n\t\t\t\tcode_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (3 * sizeof(sljit_ins) << 7));\n\t\t}\n\n\t\tjump->flags |= PATCH_REL32;\n\t\tjalr_offset = 3;\n\t} else if (target_addr <= (sljit_uw)S32_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))\n\t\t\t\tcode_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(5 * sizeof(sljit_u16)));\n\t\t\telse\n\t\t\t\tcode_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (3 * sizeof(sljit_ins) << 7));\n\t\t}\n\n\t\tjump->flags |= PATCH_ABS32;\n\t\tjalr_offset = 3;\n\t} else if (target_addr <= S44_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))\n\t\t\t\tcode_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(9 * sizeof(sljit_u16)));\n\t\t\telse\n\t\t\t\tcode_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (5 * sizeof(sljit_ins) << 7));\n\t\t}\n\n\t\tjump->flags |= PATCH_ABS44;\n\t\tjalr_offset = 7;\n\t} else if (target_addr <= S52_MAX) {\n\t\tif (jump->flags & IS_COND) {\n\t\t\tif (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))\n\t\t\t\tcode_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(11 * sizeof(sljit_u16)));\n\t\t\telse\n\t\t\t\tcode_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (6 * sizeof(sljit_ins) << 7));\n\t\t}\n\n\t\tjump->flags |= PATCH_ABS52;\n\t\tjalr_offset = 9;\n\t}\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\nexit:\n\tins = JALR | RS1(TMP_REG1) | IMM_I(0);\n\tif (jump->flags & IS_CALL)\n\t\tins |= RD(RETURN_ADDR_REG);\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tcode_ptr[2] = (sljit_u16)ins;\n\tcode_ptr[3] = (sljit_u16)(ins >> 16);\n\treturn code_ptr + 3;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tcode_ptr += jalr_offset;\n\tcode_ptr[-1] = (sljit_u16)ins;\n\tcode_ptr[0] = (sljit_u16)(ins >> 16);\n\treturn code_ptr;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n}\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\nstatic SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_uw jump_addr = (sljit_uw)code_ptr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT(jump->flags < (JUMP_MAX_SIZE << JUMP_SIZE_SHIFT));\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse {\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t}\n\n\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);\n\n\tif (diff >= S32_MIN && diff <= S32_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_REL32;\n\t\treturn 3;\n\t}\n\n\tif (addr <= S32_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS32;\n\t\treturn 3;\n\t}\n\n\tif (addr <= S44_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)7 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS44;\n\t\treturn 7;\n\t}\n\n\tif (addr <= S52_MAX) {\n\t\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)9 << JUMP_SIZE_SHIFT));\n\t\tjump->flags |= PATCH_ABS52;\n\t\treturn 9;\n\t}\n\n\tSLJIT_ASSERT(jump->flags >= ((sljit_uw)11 << JUMP_SIZE_SHIFT));\n\treturn 11;\n}\n\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\nstatic SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_uw flags = jump->flags;\n\tsljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\tsljit_ins ins;\n\tsljit_u16 *buf = (sljit_u16 *)jump->addr;\n\tsljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *buf : TMP_REG1;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_sw high;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (flags & PATCH_REL32) {\n\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf, executable_offset);\n\n\t\tSLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);\n\n\t\tif ((addr & 0x800) != 0)\n\t\t\taddr += 0x1000;\n\n\t\tins = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);\n\t\tbuf[0] = (sljit_u16)ins;\n\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\n\t\tif (!(flags & JUMP_MOV_ADDR)) {\n\t\t\tins = JALR | RS1(reg) | IMM_I(addr);\n\t\t\tif (jump->flags & IS_CALL)\n\t\t\t\tins |= RD(RETURN_ADDR_REG);\n\t\t} else\n\t\t\tins = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);\n\n\t\tbuf[2] = (sljit_u16)ins;\n\t\tbuf[3] = (sljit_u16)(ins >> 16);\n\t\treturn;\n\t}\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tif ((addr & 0x800) != 0)\n\t\taddr += 0x1000;\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);\n\tbuf[0] = (sljit_u16)ins;\n\tbuf[1] = (sljit_u16)(ins >> 16);\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\n\tif (flags & PATCH_ABS32) {\n\t\tSLJIT_ASSERT(addr <= S32_MAX);\n\t\tins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);\n\t\tbuf[0] = (sljit_u16)ins;\n\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\t} else if (flags & PATCH_ABS44) {\n\t\thigh = (sljit_sw)addr >> 12;\n\t\tSLJIT_ASSERT((sljit_uw)high <= 0x7fffffff);\n\n\t\tif (high > S32_MAX) {\n\t\t\tSLJIT_ASSERT((high & 0x800) != 0);\n\t\t\tins = LUI | RD(reg) | (sljit_ins)0x80000000u;\n\t\t\tbuf[0] = (sljit_u16)ins;\n\t\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\t\t\tins = XORI | RD(reg) | RS1(reg) | IMM_I(high);\n\t\t\tbuf[2] = (sljit_u16)ins;\n\t\t\tbuf[3] = (sljit_u16)(ins >> 16);\n\t\t} else {\n\t\t\tif ((high & 0x800) != 0)\n\t\t\t\thigh += 0x1000;\n\n\t\t\tins = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);\n\t\t\tbuf[0] = (sljit_u16)ins;\n\t\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\t\t\tins = ADDI | RD(reg) | RS1(reg) | IMM_I(high);\n\t\t\tbuf[2] = (sljit_u16)ins;\n\t\t\tbuf[3] = (sljit_u16)(ins >> 16);\n\t\t}\n\n\t\tins = SLLI | RD(reg) | RS1(reg) | IMM_I(12);\n\t\tbuf[4] = (sljit_u16)ins;\n\t\tbuf[5] = (sljit_u16)(ins >> 16);\n\t\tbuf += 4;\n\t} else {\n\t\thigh = (sljit_sw)addr >> 32;\n\n\t\tif ((addr & 0x80000000l) != 0)\n\t\t\thigh = ~high;\n\n\t\tif (flags & PATCH_ABS52) {\n\t\t\tSLJIT_ASSERT(addr <= S52_MAX);\n\t\t\tins = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12);\n\t\t\tbuf[0] = (sljit_u16)ins;\n\t\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\t\t} else {\n\t\t\tif ((high & 0x800) != 0)\n\t\t\t\thigh += 0x1000;\n\t\t\tins = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff);\n\t\t\tbuf[0] = (sljit_u16)ins;\n\t\t\tbuf[1] = (sljit_u16)(ins >> 16);\n\t\t\tins = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high);\n\t\t\tbuf[2] = (sljit_u16)ins;\n\t\t\tbuf[3] = (sljit_u16)(ins >> 16);\n\t\t\tbuf += 2;\n\t\t}\n\n\t\tins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);\n\t\tbuf[2] = (sljit_u16)ins;\n\t\tbuf[3] = (sljit_u16)(ins >> 16);\n\t\tins = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);\n\t\tbuf[4] = (sljit_u16)ins;\n\t\tbuf[5] = (sljit_u16)(ins >> 16);\n\t\tins = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);\n\t\tbuf[6] = (sljit_u16)ins;\n\t\tbuf[7] = (sljit_u16)(ins >> 16);\n\t\tbuf += 6;\n\t}\n#endif /* !SLJIT_CONFIG_RISCV_32 */\n\n\tif (!(flags & JUMP_MOV_ADDR)) {\n\t\tins = JALR | RS1(reg) | IMM_I(addr);\n\t\tif (jump->flags & IS_CALL)\n\t\t\tins |= RD(RETURN_ADDR_REG);\n\t} else\n\t\tins = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);\n\n\tbuf[2] = (sljit_u16)ins;\n\tbuf[3] = (sljit_u16)(ins >> 16);\n}\n\nstatic SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_uw total_size;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff, cond_size, cond_diff;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\n\twhile (1) {\n\t\tSLJIT_GET_NEXT_MIN();\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr == next_const_addr) {\n\t\t\tconst_->addr -= size_reduce;\n\t\t\tconst_ = const_->next;\n\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\ttotal_size = JUMP_MAX_SIZE;\n\n\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\tif (jump->flags & JUMP_ADDR) {\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\t\t\tif (jump->u.target <= S32_MAX)\n\t\t\t\t\t\ttotal_size = 4;\n\t\t\t\t\telse if (jump->u.target <= S44_MAX)\n\t\t\t\t\t\ttotal_size = 8;\n\t\t\t\t\telse if (jump->u.target <= S52_MAX)\n\t\t\t\t\t\ttotal_size = 10;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\t\t} else {\n\t\t\t\t\t/* Unit size: instruction. */\n\t\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t\t}\n\n\t\t\t\t\tcond_size = RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16) != 0);\n\t\t\t\t\tcond_diff = diff + 2 - cond_size;\n\n\t\t\t\t\tif (RISCV_COMPRESSED_CHECK(cond_size) && diff >= (BRANCH16_MIN / SSIZE_OF(u16)) && diff <= (BRANCH16_MAX / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = 0;\n\t\t\t\t\telse if ((jump->flags & IS_COND) && cond_diff <= (BRANCH_MAX / SSIZE_OF(u16)) && cond_diff >= (BRANCH_MIN / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = (sljit_uw)cond_size;\n\t\t\t\t\telse if (RISCV_HAS_COMPRESSED(200) && RISCV_CHECK_COMPRESSED_JUMP(jump, diff, u16))\n\t\t\t\t\t\ttotal_size = 1;\n\t\t\t\t\telse if (diff >= (JUMP_MIN / SSIZE_OF(u16)) && diff <= (JUMP_MAX / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = 2;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\t\t\telse if (diff >= (S32_MIN / SSIZE_OF(u16)) && diff <= (S32_MAX / SSIZE_OF(u16)))\n\t\t\t\t\t\ttotal_size = 4;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsize_reduce += JUMP_MAX_SIZE - total_size;\n\t\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t} else {\n\t\t\ttotal_size = 11;\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\t/* Real size minus 1. Unit size: 16 bit. */\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t}\n\n\t\t\t\tif (diff >= (S32_MIN / SSIZE_OF(u16)) && diff <= (S32_MAX / SSIZE_OF(u16)))\n\t\t\t\t\ttotal_size = 3;\n\t\t\t} else if (jump->u.target < S32_MAX)\n\t\t\t\ttotal_size = 3;\n\t\t\telse if (jump->u.target < S44_MAX)\n\t\t\t\ttotal_size = 7;\n\t\t\telse if (jump->u.target <= S52_MAX)\n\t\t\t\ttotal_size = 9;\n\n\t\t\tsize_reduce += 11 - total_size;\n\t\t\tjump->flags |= total_size << JUMP_SIZE_SHIFT;\n#endif /* !SLJIT_CONFIG_RISCV_64 */\n\t\t}\n\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_u16 *code;\n\tsljit_u16 *code_ptr;\n\tsljit_u16 *buf_ptr;\n\tsljit_u16 *buf_end;\n\tsljit_uw half_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tsljit_sw executable_offset;\n\tsljit_uw addr;\n\tsljit_ins ins;\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n\tcode = (sljit_u16 *)allocate_executable_memory(compiler->size * sizeof(sljit_u16), options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\thalf_count = 0;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_u16*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 1);\n\t\tdo {\n\t\t\t*code_ptr = *buf_ptr++;\n\t\t\tif (next_min_addr == half_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= half_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= half_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= half_count);\n\n\t\t\t\t/* These structures are ordered by their address. */\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\t\t\t\t\t\t*code_ptr = buf_ptr[-1];\n\t\t\t\t\t}\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\thalf_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);\n\t\t\t\t\t\tcode_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tSLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));\n\t\t\t\t\t} else {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\t\t\t\t\thalf_count += 3;\n\t\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\t\t\t\tcode_ptr += 3;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\t\t\t\t\thalf_count += jump->flags >> JUMP_SIZE_SHIFT;\n\t\t\t\t\t\taddr = (sljit_uw)code_ptr;\n\t\t\t\t\t\tcode_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);\n\t\t\t\t\t\tjump->addr = addr;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\t\t\t\t}\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\t\t\tcode_ptr++;\n\t\t\thalf_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (label && label->size == half_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)code_ptr;\n\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tdo {\n\t\t\tif (!(jump->flags & (PATCH_B | PATCH_J)) || (jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\tload_addr_to_reg(jump, executable_offset);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\taddr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\t\t\tbuf_ptr = (sljit_u16 *)jump->addr;\n\t\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);\n\n\t\t\tif (jump->flags & PATCH_B) {\n\t\t\t\tSLJIT_ASSERT(RISCV_HAS_COMPRESSED(200) || !(jump->flags & PATCH_16));\n\t\t\t\tSLJIT_ASSERT((sljit_sw)addr >= BRANCH_MIN && (sljit_sw)addr <= BRANCH_MAX);\n\n\t\t\t\tif (RISCV_COMPRESSED_CHECK(jump->flags & PATCH_16)) {\n\t\t\t\t\tbuf_ptr[0] |= C_BRN16(addr);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbuf_ptr[0] |= (sljit_u16)(((addr & 0x800) >> 4) | ((addr & 0x1e) << 7));\n\t\t\t\tbuf_ptr[1] |= (sljit_u16)(((addr & 0x7e0) << 4) | ((addr & 0x1000) << 3));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tSLJIT_ASSERT(RISCV_HAS_COMPRESSED(200) || !(jump->flags & PATCH_16));\n\t\t\tif (RISCV_COMPRESSED_CHECK(jump->flags & PATCH_16)) {\n\t\t\t\tSLJIT_ASSERT((sljit_sw)addr >= JUMP16_MIN && (sljit_sw)addr <= JUMP16_MAX);\n#if defined SLJIT_CONFIG_RISCV_32\n\t\t\t\tins = ((jump->flags & IS_CALL) ? C_JAL : C_J) | C_JMP16(addr);\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\t\t\tSLJIT_ASSERT(!(jump->flags & IS_CALL));\n\t\t\t\tins = C_J | C_JMP16(addr);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\t\t\tbuf_ptr[0] = (sljit_u16)ins;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tSLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);\n\t\t\taddr = (addr & 0xff000) | ((addr & 0x800) << 9) | ((addr & 0x7fe) << 20) | ((addr & 0x100000) << 11);\n\t\t\tins = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr;\n\t\t\tbuf_ptr[0] = (sljit_u16)ins;\n\t\t\tbuf_ptr[1] = (sljit_u16)(ins >> 16);\n\t\t} while (0);\n\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);\n\n\tcode = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#elif defined(__riscv_float_abi_soft)\n\t\treturn 0;\n#else /* !SLJIT_IS_FPU_AVAILABLE && !__riscv_float_abi_soft */\n\t\treturn 1;\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n\tcase SLJIT_HAS_ZERO_REGISTER:\n\tcase SLJIT_HAS_COPY_F32:\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase SLJIT_HAS_COPY_F64:\n#endif /* !SLJIT_CONFIG_RISCV_64 */\n\tcase SLJIT_HAS_ATOMIC:\n\t\treturn RISCV_HAS_ATOMIC(200) ? 1 : 0;\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_CTZ:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\t\treturn RISCV_HAS_BITMANIP_B(93) ? 1 : 0;\n\tcase SLJIT_HAS_CMOV:\n\t\treturn RISCV_HAS_ICOND(100) ? 2 : 0;\n\tcase SLJIT_HAS_SIMD:\n\t\treturn RISCV_HAS_VECTOR(100) ? 1 : 0;\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 2;\n\n\tcase SLJIT_UNORDERED:\n\tcase SLJIT_ORDERED:\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\n/* Creates an index in data_transfer_insts array. */\n#define LOAD_DATA\t0x01\n#define WORD_DATA\t0x00\n#define BYTE_DATA\t0x02\n#define HALF_DATA\t0x04\n#define INT_DATA\t0x06\n#define SIGNED_DATA\t0x08\n/* Separates integer and floating point registers */\n#define GPR_REG\t\t0x0f\n#define DOUBLE_DATA\t0x10\n#define SINGLE_DATA\t0x12\n\n#define MEM_MASK\t0x1f\n\n#define ARG_TEST\t0x00020\n#define ALT_KEEP_CACHE\t0x00040\n#define CUMULATIVE_OP\t0x00080\n#define IMM_OP\t\t0x00100\n#define MOVE_OP\t\t0x00200\n#define SRC2_IMM\t0x00400\n\n#define UNUSED_DEST\t0x00800\n#define REG_DEST\t0x01000\n#define REG1_SOURCE\t0x02000\n#define REG2_SOURCE\t0x04000\n#define SLOW_SRC1\t0x08000\n#define SLOW_SRC2\t0x10000\n#define SLOW_DEST\t0x20000\n#define MEM_USE_TMP2\t0x40000\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define STACK_STORE\tSW\n#define STACK_LOAD\tLW\n#define C_STACK_OFFSET_CHECK(offset) ((offset) <= 0xfc)\n#define C_STACK_LOAD(offset) (C_LWSP | C_LD32_SP(offset))\n#define C_STACK_STORE(offset) (C_SWSP | C_ST32_SP(offset))\n#else /* !SLJIT_CONFIG_RISCV_32 */\n#define STACK_STORE\tSD\n#define STACK_LOAD\tLD\n#define C_STACK_OFFSET_CHECK(offset) ((offset) <= 0x1f8)\n#define C_STACK_LOAD(offset) (C_LDSP | C_LD64_SP(offset))\n#define C_STACK_STORE(offset) (C_SDSP | C_ST64_SP(offset))\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#include \"sljitNativeRISCV_32.c\"\n#else /* !SLJIT_CONFIG_RISCV_32 */\n#include \"sljitNativeRISCV_64.c\"\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n#define STACK_MAX_DISTANCE (-SIMM_MIN)\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw);\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\tsljit_s32 i, tmp, offset;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((local_size & SSIZE_OF(sw)) != 0)\n\t\t\tlocal_size += SSIZE_OF(sw);\n\t\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\t}\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\tlocal_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\tcompiler->local_size = local_size;\n\n\tif (local_size <= STACK_MAX_DISTANCE) {\n\t\t/* Frequent case. */\n\t\toffset = local_size - SSIZE_OF(sw);\n\t\tlocal_size = -local_size;\n\t\tif (RISCV_HAS_COMPRESSED(200) && local_size >= -0x200) {\n\t\t\tSLJIT_ASSERT((local_size & 0x200) != 0 && (local_size & 0xf) == 0);\n\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI16SP | (sljit_u16)(((local_size & 0x10) << 2) | ((local_size & 0x20) >> 3) | ((local_size & 0x40) >> 1) | ((local_size & 0x180) >> 4) | (1 << 12))));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size)));\n\t\tlocal_size = 0;\n\t} else {\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(STACK_MAX_DISTANCE)));\n\t\tlocal_size -= STACK_MAX_DISTANCE;\n\n\t\tif (local_size > STACK_MAX_DISTANCE)\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, local_size, TMP_REG3));\n\t\toffset = STACK_MAX_DISTANCE - SSIZE_OF(sw);\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\tFAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(RETURN_ADDR_REG)));\n\telse\n\t\tFAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(RETURN_ADDR_REG), offset));\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\t\tFAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(i)));\n\t\telse\n\t\t\tFAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\t\tFAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(i)));\n\t\telse\n\t\t\tFAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));\n\t}\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t/* This alignment is valid because offset is not used after storing FPU regs. */\n\tif ((offset & SSIZE_OF(sw)) != 0)\n\t\toffset -= SSIZE_OF(sw);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tif (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)\n\t\t\tFAIL_IF(push_inst16(compiler, C_FSDSP | C_FRS2(i) | C_ST64_SP(offset)));\n\t\telse\n\t\t\tFAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tif (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)\n\t\t\tFAIL_IF(push_inst16(compiler, C_FSDSP | C_FRS2(i) | C_ST64_SP(offset)));\n\t\telse\n\t\t\tFAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));\n\t}\n\n\tif (local_size > STACK_MAX_DISTANCE)\n\t\tFAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RS1(SLJIT_SP) | RS2(TMP_REG1)));\n\telse if (local_size > 0)\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-local_size)));\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\treturn SLJIT_SUCCESS;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tsaved_arg_count = 0;\n\ttmp = SLJIT_R0;\n\n\twhile (arg_types > 0) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(SLJIT_S0 - saved_arg_count) | C_RS2(tmp)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_S0 - saved_arg_count) | RS1(tmp) | IMM_I(0)));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\t\t\ttmp++;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#undef STACK_MAX_DISTANCE\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);\n\tsljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tlocal_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {\n\t\tif ((local_size & SSIZE_OF(sw)) != 0)\n\t\t\tlocal_size += SSIZE_OF(sw);\n\t\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n\t}\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tlocal_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\tcompiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;\n\n\treturn SLJIT_SUCCESS;\n}\n\n#define STACK_MAX_DISTANCE (-SIMM_MIN - 16)\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_s32 i, tmp, offset;\n\tsljit_s32 local_size = compiler->local_size;\n\n\tif (local_size > STACK_MAX_DISTANCE) {\n\t\tlocal_size -= STACK_MAX_DISTANCE;\n\n\t\tif (local_size > STACK_MAX_DISTANCE) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG2, local_size, TMP_REG3));\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(SLJIT_SP) | RS1(SLJIT_SP) | RS2(TMP_REG2)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size)));\n\n\t\tlocal_size = STACK_MAX_DISTANCE;\n\t}\n\n\tSLJIT_ASSERT(local_size > 0);\n\n\toffset = local_size - SSIZE_OF(sw);\n\tif (!is_return_to) {\n\t\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\t\tFAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(RETURN_ADDR_REG)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(RETURN_ADDR_REG) | RS1(SLJIT_SP) | IMM_I(offset)));\n\t}\n\n\ttmp = SLJIT_S0 - compiler->saveds;\n\tfor (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\t\tFAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(i)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));\n\t}\n\n\tfor (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tif (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))\n\t\t\tFAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(i)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));\n\t}\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t/* This alignment is valid because offset is not used after storing FPU regs. */\n\tif ((offset & SSIZE_OF(sw)) != 0)\n\t\toffset -= SSIZE_OF(sw);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\ttmp = SLJIT_FS0 - compiler->fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tif (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)\n\t\t\tFAIL_IF(push_inst16(compiler, C_FLDSP | C_FRD(i) | C_LD64_SP(offset)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));\n\t}\n\n\tfor (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\toffset -= SSIZE_OF(f64);\n\t\tif (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)\n\t\t\tFAIL_IF(push_inst16(compiler, C_FLDSP | C_FRD(i) | C_LD64_SP(offset)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200) && local_size <= 0x1f0) {\n\t\tSLJIT_ASSERT((local_size & 0xf) == 0);\n\t\treturn push_inst16(compiler, C_ADDI16SP | (sljit_u16)(((local_size & 0x10) << 2) | ((local_size & 0x20) >> 3) | ((local_size & 0x40) >> 1) | ((local_size & 0x180) >> 4)));\n\t}\n\n\treturn push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size));\n}\n\n#undef STACK_MAX_DISTANCE\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\treturn push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(RETURN_ADDR_REG) | IMM_I(0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src) | IMM_I(0)));\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define ARCH_32_64(a, b)\ta\n#else /* !SLJIT_CONFIG_RISCV_32 */\n#define ARCH_32_64(a, b)\tb\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\nstatic const sljit_ins data_transfer_insts[16 + 4] = {\n/* u w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */),\n/* u w l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x3) | OPC(0x3) /* ld */),\n/* u b s */ F3(0x0) | OPC(0x23) /* sb */,\n/* u b l */ F3(0x4) | OPC(0x3) /* lbu */,\n/* u h s */ F3(0x1) | OPC(0x23) /* sh */,\n/* u h l */ F3(0x5) | OPC(0x3) /* lhu */,\n/* u i s */ F3(0x2) | OPC(0x23) /* sw */,\n/* u i l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x6) | OPC(0x3) /* lwu */),\n\n/* s w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */),\n/* s w l */ ARCH_32_64(F3(0x2) | OPC(0x3) /* lw */, F3(0x3) | OPC(0x3) /* ld */),\n/* s b s */ F3(0x0) | OPC(0x23) /* sb */,\n/* s b l */ F3(0x0) | OPC(0x3) /* lb */,\n/* s h s */ F3(0x1) | OPC(0x23) /* sh */,\n/* s h l */ F3(0x1) | OPC(0x3) /* lh */,\n/* s i s */ F3(0x2) | OPC(0x23) /* sw */,\n/* s i l */ F3(0x2) | OPC(0x3) /* lw */,\n\n/* d   s */ F3(0x3) | OPC(0x27) /* fsd */,\n/* d   l */ F3(0x3) | OPC(0x7) /* fld */,\n/* s   s */ F3(0x2) | OPC(0x27) /* fsw */,\n/* s   l */ F3(0x2) | OPC(0x7) /* flw */,\n};\n\n#undef ARCH_32_64\n\nstatic sljit_s32 push_mem_inst(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 base, sljit_sw offset)\n{\n\tsljit_ins ins;\n\tsljit_s32 signed_flags;\n\tsljit_s32 load_flags;\n\n\tSLJIT_ASSERT(FAST_IS_REG(base) && offset <= 0xfff && offset >= SIMM_MIN);\n\n\tflags &= MEM_MASK;\n\n\tif (RISCV_HAS_COMPRESSED(200) && offset >= 0) {\n\t\tif (base == SLJIT_SP) {\n\t\t\tsigned_flags = flags | SIGNED_DATA;\n\n\t\t\tif ((offset & 0x3) == 0 && offset <= 0xfc) {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\t\t\tif ((signed_flags == (SIGNED_DATA | LOAD_DATA) || signed_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA)))\n\t\t\t\t\treturn push_inst16(compiler, C_LWSP | C_RD(reg) | C_LD32_SP(offset));\n\t\t\t\tif ((signed_flags == SIGNED_DATA || signed_flags == (INT_DATA | SIGNED_DATA)))\n\t\t\t\t\treturn push_inst16(compiler, C_SWSP | C_RS2(reg) | C_ST32_SP(offset));\n\t\t\t\tif (flags == (SINGLE_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, C_FLWSP | C_FRD(reg) | C_LD32_SP(offset));\n\t\t\t\tif (flags == SINGLE_DATA)\n\t\t\t\t\treturn push_inst16(compiler, C_FSWSP | C_FRS2(reg) | C_ST32_SP(offset));\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\t\t\tif (flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, C_LWSP | C_RD(reg) | C_LD32_SP(offset));\n\t\t\t\tif (signed_flags == (INT_DATA | SIGNED_DATA))\n\t\t\t\t\treturn push_inst16(compiler, C_SWSP | C_RS2(reg) | C_ST32_SP(offset));\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\t\t}\n\n\t\t\tif ((offset & 0x7) == 0 && offset <= 0x1f8) {\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\t\tif (signed_flags == (SIGNED_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, C_LDSP | C_RD(reg) | C_LD64_SP(offset));\n\t\t\t\tif (signed_flags == SIGNED_DATA)\n\t\t\t\t\treturn push_inst16(compiler, C_SDSP | C_RS2(reg) | C_ST64_SP(offset));\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\t\tif (flags == (DOUBLE_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, C_FLDSP | C_FRD(reg) | C_LD64_SP(offset));\n\t\t\t\tif (flags == DOUBLE_DATA)\n\t\t\t\t\treturn push_inst16(compiler, C_FSDSP | C_FRS2(reg) | C_ST64_SP(offset));\n\t\t\t}\n\t\t} else if (C_IS_R3(base) && (flags <= GPR_REG ? C_IS_R3(reg) : C_IS_FR3(reg))) {\n\t\t\tSLJIT_COMPILE_ASSERT(LOAD_DATA == 1, load_data_bit_error);\n\t\t\tsigned_flags = flags | LOAD_DATA | SIGNED_DATA;\n\t\t\tload_flags = flags | LOAD_DATA;\n\n\t\t\tif ((offset & 0x3) == 0 && offset <= 0x7c) {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\t\t\tif (signed_flags == (SIGNED_DATA | LOAD_DATA) || signed_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, (C_SW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM32(offset));\n\t\t\t\tif (load_flags == (SINGLE_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, (C_FSW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_FRS2_R3(reg) | C_MEM32(offset));\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\t\t\tif (load_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, (C_SW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM32(offset));\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\t\t}\n\n\t\t\tif ((offset & 0x7) == 0 && offset <= 0xf8) {\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\t\tif (signed_flags == (SIGNED_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, (C_SD ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM64(offset));\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\t\tif (load_flags == (DOUBLE_DATA | LOAD_DATA))\n\t\t\t\t\treturn push_inst16(compiler, (C_FSD ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_FRS2_R3(reg) | C_MEM64(offset));\n\t\t\t}\n\t\t}\n\t}\n\n\tins = data_transfer_insts[flags] | RS1(base);\n\tif (flags & LOAD_DATA)\n\t\tins |= (flags <= GPR_REG ? RD(reg) : FRD(reg)) | IMM_I(offset);\n\telse\n\t\tins |= (flags <= GPR_REG ? RS2(reg) : FRS2(reg)) | IMM_S(offset);\n\n\treturn push_inst(compiler, ins);\n}\n\n/* Can perform an operation using at most 1 instruction. */\nstatic sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\n\tif (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {\n\t\t/* Works for both absoulte and relative addresses. */\n\t\tif (SLJIT_UNLIKELY(flags & ARG_TEST))\n\t\t\treturn 1;\n\n\t\tFAIL_IF(push_mem_inst(compiler, flags, reg, arg & REG_MASK, argw));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#define TO_ARGW_HI(argw) (((argw) & ~0xfff) + (((argw) & 0x800) ? 0x1000 : 0))\n\n/* See getput_arg below.\n   Note: can_cache is called only for binary operators. */\nstatic sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tSLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));\n\n\t/* Simple operation except for updates. */\n\tif (arg & OFFS_REG_MASK) {\n\t\targw &= 0x3;\n\t\tnext_argw &= 0x3;\n\t\tif (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))\n\t\t\treturn 1;\n\t\treturn 0;\n\t}\n\n\tif (arg == next_arg) {\n\t\tif (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)\n\t\t\t\t|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))\n\t\t\treturn 1;\n\t\treturn 0;\n\t}\n\n\treturn 0;\n}\n\n/* Emit the necessary instructions. See can_cache above. */\nstatic sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)\n{\n\tsljit_s32 base = arg & REG_MASK;\n\tsljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1;\n\tsljit_sw offset, argw_hi;\n\tsljit_ins ins = ADD;\n\n\tSLJIT_ASSERT(arg & SLJIT_MEM);\n\tif (!(next_arg & SLJIT_MEM)) {\n\t\tnext_arg = 0;\n\t\tnext_argw = 0;\n\t}\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (RISCV_HAS_BITMANIP_A(93)) {\n\t\t\tswitch (argw) {\n\t\t\t\tcase 1:\n\t\t\t\t\tins = SH1ADD;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tins = SH2ADD;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tins = SH3ADD;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, ins | RD(tmp_r) | RS1(OFFS_REG(arg)) | RS2(base)));\n\t\t\treturn push_mem_inst(compiler, flags, reg, tmp_r, 0);\n\t\t}\n\n\t\t/* Using the cache. */\n\t\tif (argw == compiler->cache_argw) {\n\t\t\tif (arg == compiler->cache_arg)\n\t\t\t\treturn push_mem_inst(compiler, flags, reg, TMP_REG3, 0);\n\n\t\t\tif ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {\n\t\t\t\tif (arg == next_arg && argw == (next_argw & 0x3)) {\n\t\t\t\t\tcompiler->cache_arg = arg;\n\t\t\t\t\tcompiler->cache_argw = argw;\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(TMP_REG3) | RS2(base)));\n\t\t\t\t\treturn push_mem_inst(compiler, flags, reg, TMP_REG3, 0);\n\t\t\t\t}\n\t\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(TMP_REG3)));\n\t\t\t\treturn push_mem_inst(compiler, flags, reg, tmp_r, 0);\n\t\t\t}\n\t\t}\n\n\t\tif (SLJIT_UNLIKELY(argw)) {\n\t\t\tcompiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);\n\t\t\tcompiler->cache_argw = argw;\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG3) | RS1(OFFS_REG(arg)) | IMM_I(argw)));\n\t\t}\n\n\t\tif (arg == next_arg && argw == (next_argw & 0x3)) {\n\t\t\tcompiler->cache_arg = arg;\n\t\t\tcompiler->cache_argw = argw;\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3)));\n\t\t\ttmp_r = TMP_REG3;\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3)));\n\n\t\treturn push_mem_inst(compiler, flags, reg, tmp_r, 0);\n\t}\n\n\tif (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)\n\t\treturn push_mem_inst(compiler, flags, reg, TMP_REG3, argw - compiler->cache_argw);\n\n\tif (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw <= SIMM_MAX) && (argw - compiler->cache_argw >= SIMM_MIN)) {\n\t\toffset = argw - compiler->cache_argw;\n\t} else {\n\t\tcompiler->cache_arg = SLJIT_MEM;\n\n\t\targw_hi = TO_ARGW_HI(argw);\n\n\t\tif (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG3, argw, tmp_r));\n\t\t\tcompiler->cache_argw = argw;\n\t\t\toffset = 0;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG3, argw_hi, tmp_r));\n\t\t\tcompiler->cache_argw = argw_hi;\n\t\t\toffset = argw & 0xfff;\n\t\t\targw = argw_hi;\n\t\t}\n\t}\n\n\tif (!base)\n\t\treturn push_mem_inst(compiler, flags, reg, TMP_REG3, offset);\n\n\tif (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {\n\t\tcompiler->cache_arg = arg;\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RS1(TMP_REG3) | RS2(base)));\n\t\treturn push_mem_inst(compiler, flags, reg, TMP_REG3, offset);\n\t}\n\n\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(TMP_REG3) | RS2(base)));\n\treturn push_mem_inst(compiler, flags, reg, tmp_r, offset);\n}\n\nstatic sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)\n{\n\tsljit_s32 base = arg & REG_MASK;\n\tsljit_s32 tmp_r = TMP_REG1;\n\n\tif (getput_arg_fast(compiler, flags, reg, arg, argw))\n\t\treturn compiler->error;\n\n\tif ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))\n\t\ttmp_r = reg;\n\n\tif (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {\n\t\targw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(argw)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(OFFS_REG(arg)) | IMM_I(argw)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(tmp_r) | RS2(base)));\n\t\t}\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(OFFS_REG(arg))));\n\n\t\targw = 0;\n\t} else {\n\t\tFAIL_IF(load_immediate(compiler, tmp_r, TO_ARGW_HI(argw), TMP_REG3));\n\n\t\tif (base != 0)\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(tmp_r) | RS2(base)));\n\t}\n\n\treturn push_mem_inst(compiler, flags, reg, tmp_r, argw & 0xfff);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)\n{\n\tif (getput_arg_fast(compiler, flags, reg, arg1, arg1w))\n\t\treturn compiler->error;\n\treturn getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);\n}\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#define WORD 0\n#define WORD_32 0\n#define IMM_EXTEND(v) (IMM_I(v))\n#else /* !SLJIT_CONFIG_RISCV_32 */\n#define WORD word\n#define WORD_32 0x08\n#define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v))))\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\nstatic sljit_s32 emit_add(struct sljit_compiler *compiler, sljit_ins word, sljit_s32 dst, sljit_s32 src1, sljit_sw src2)\n{\n\tSLJIT_UNUSED_ARG(word);\n\n\tif (dst == src2) {\n\t\tsrc2 = src1;\n\t\tsrc1 = dst;\n\t}\n\n\tif (RISCV_HAS_COMPRESSED(200) && dst == src1) {\n\t\tif (WORD == 0 && src2 != 0)\n\t\t\treturn push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(src2));\n\n\t\tif (WORD == 0x8 && C_IS_R3(dst) && C_IS_R3(src2))\n\t\t\treturn push_inst16(compiler, C_ADDW | C_RS1_R3(dst) | C_RS2_R3(src2));\n\t}\n\n\treturn push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2));\n}\n\nstatic sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n\tsljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n\tsljit_ins word_size = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\tsljit_ins word_size = 32;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tSLJIT_ASSERT(WORD == 0 || WORD == 0x8);\n\n\t/* The OTHER_FLAG is the counter. */\n\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(word_size)));\n\n\t/* The TMP_REG2 is the next value. */\n\tif (src != TMP_REG2)\n\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(src) | IMM_I(0)));\n\n\tFAIL_IF(push_inst(compiler, BEQ | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)((is_clz ? 4 : 5) * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));\n\n\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(0)));\n\tif (!is_clz) {\n\t\tFAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG1) | RS1(TMP_REG2) | IMM_I(1)));\n\t\tFAIL_IF(push_inst(compiler, BNE | RS1(TMP_REG1) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, BLT | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20)));\n\n\t/* The TMP_REG1 is the next shift. */\n\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(word_size)));\n\n\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(TMP_REG2) | IMM_I(0)));\n\tFAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(1)));\n\n\tFAIL_IF(push_inst(compiler, (is_clz ? SRL : SLL) | WORD | RD(TMP_REG2) | RS1(EQUAL_FLAG) | RS2(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, BNE | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)0xfe000e80 - ((2 * SSIZE_OF(ins)) << 7))));\n\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(TMP_REG1) | IMM_I(-1)));\n\tFAIL_IF(push_inst(compiler, (is_clz ? SRL : SLL) | WORD | RD(TMP_REG2) | RS1(EQUAL_FLAG) | RS2(TMP_REG2)));\n\tFAIL_IF(push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1)));\n\tFAIL_IF(push_inst(compiler, BEQ | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)0xfe000e80 - ((5 * SSIZE_OF(ins)) << 7))));\n\n\treturn push_inst(compiler, ADDI | WORD | RD(dst) | RS1(OTHER_FLAG) | IMM_I(0));\n}\n\nstatic sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n\tSLJIT_UNUSED_ARG(op);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (!(op & SLJIT_32)) {\n\t\tFAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0x10000));\n\t\tFAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(src) | IMM_I(32)));\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xfff)));\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src) | IMM_I(32)));\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(32)));\n\t\tFAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)));\n\t\tFAIL_IF(push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG)));\n\n\t\tFAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(16)));\n\t\tFAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));\n\t\tFAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG)));\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(8)));\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(16)));\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG)));\n\t\tFAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)));\n\n\t\tFAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(8)));\n\t\tFAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));\n\t\tFAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG)));\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(8)));\n\t\treturn push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1));\n\t}\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tFAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(src) | IMM_I(16)));\n\tFAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0xff0000));\n\tFAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(src) | IMM_I(16)));\n\tFAIL_IF(push_inst(compiler, ORI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xff)));\n\tFAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)));\n\n\tFAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(dst) | IMM_I(8)));\n\tFAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));\n\tFAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG)));\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tFAIL_IF(push_inst(compiler, SLLI | (GET_OPCODE(op) == SLJIT_REV_S32 ? WORD_32 : 0) | RD(dst) | RS1(dst) | IMM_I(8)));\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\tFAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(8)));\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\treturn push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1));\n}\n\nstatic sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)\n{\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n\tsljit_ins word_size = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\tsljit_ins word_size = 32;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tFAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(src) | IMM_I(8)));\n\tFAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src) | IMM_I(word_size - 8)));\n\tFAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(0xff)));\n\tFAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16)));\n\treturn push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1));\n}\n\n#define EMIT_LOGICAL(op_imm, op_c_imm, op_reg, op_c_reg) \\\n\tif (flags & SRC2_IMM) { \\\n\t\tif (op & SLJIT_SET_Z) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2))); \\\n\t\tif (!(flags & UNUSED_DEST)) { \\\n\t\t\tif (op_c_imm != 0 && RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN && C_IS_R3(dst)) \\\n\t\t\t\tFAIL_IF(push_inst16(compiler, op_c_imm | C_RS1_R3(dst) | C_IMM_I(src2))); \\\n\t\t\telse \\\n\t\t\t\tFAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \\\n\t\t} \\\n\t} else { \\\n\t\tif (dst == src2) { \\\n\t\t\tsrc2 = src1; \\\n\t\t\tsrc1 = dst; \\\n\t\t} \\\n\t\t\\\n\t\tif (op & SLJIT_SET_Z) \\\n\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); \\\n\t\tif (!(flags & UNUSED_DEST)) { \\\n\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) \\\n\t\t\t\tFAIL_IF(push_inst16(compiler, op_c_reg | C_RS1_R3(dst) | C_RS2_R3(src2))); \\\n\t\t\telse \\\n\t\t\t\tFAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \\\n\t\t} \\\n\t}\n\nstatic SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_s32 src1, sljit_sw src2)\n{\n\tsljit_s32 is_overflow, is_carry, carry_src_r, is_handled, reg;\n\tsljit_ins op_imm, op_reg;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tSLJIT_ASSERT(WORD == 0 || WORD == 0x8);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif (dst == src2)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (!RISCV_HAS_COMPRESSED(200))\n\t\t\treturn push_inst(compiler, ADDI | RD(dst) | RS1(src2) | IMM_I(0));\n\n\t\t/* Revert the x0 to immediate 0. */\n\t\tif (src2 == 0)\n\t\t\treturn push_inst16(compiler, C_LI | C_RD(dst));\n\t\treturn push_inst16(compiler, C_MV | C_RD(dst) | C_RS2(src2));\n\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))\n\t\t\treturn push_inst(compiler, ANDI | RD(dst) | RS1(src2) | IMM_I(0xff));\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S8:\n\t\tif (RISCV_HAS_BITMANIP_B(93))\n\t\t\treturn push_inst(compiler, SEXTB | RD(dst) | RS1(src2));\n\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24)));\n\t\t\treturn push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(24));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_U16:\n\t\tif (RISCV_HAS_BITMANIP_B(93))\n\t\t\treturn push_inst(compiler, ZEXTH | RD(dst) | RS1(src2));\n\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));\n\t\t\treturn push_inst(compiler, SRLI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S16:\n\t\tif (RISCV_HAS_BITMANIP_B(93))\n\t\t\treturn push_inst(compiler, SEXTH | RD(dst) | RS1(src2));\n\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));\n\t\t\treturn push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase SLJIT_MOV_U32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src2) | IMM_I(32)));\n\t\t\treturn push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {\n\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src2)\n\t\t\t\treturn push_inst16(compiler, C_ADDIW | C_RD(dst));\n\t\t\treturn push_inst(compiler, ADDI | 0x8 | RD(dst) | RS1(src2) | IMM_I(0));\n\t\t}\n\t\tSLJIT_ASSERT(dst == src2);\n\t\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif (RISCV_HAS_BITMANIP_B(93))\n\t\t\treturn push_inst(compiler, ((GET_OPCODE(op) == SLJIT_CLZ) ? CLZ : CTZ) | WORD | RD(dst) | RS1(src2));\n\n\t\treturn emit_clz_ctz(compiler, op, dst, src2);\n\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_S32:\n\tcase SLJIT_REV_U32:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif (RISCV_HAS_BITMANIP_B(93)) {\n#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64\n\t\t\tFAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));\n\t\t\tif ((op & SLJIT_32) || GET_OPCODE(op) != SLJIT_REV)\n\t\t\t\treturn push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U32 ? SRLI : SRAI)| RD(dst) | RS1(dst) | IMM_I(32));\n\t\t\treturn SLJIT_SUCCESS;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\t\t\treturn push_inst(compiler, REV8 | RD(dst) | RS1(src2));\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t}\n\n\t\treturn emit_rev(compiler, op, dst, src2);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\tSLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));\n\t\tif (RISCV_HAS_BITMANIP_B(93)) {\n\t\t\tFAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));\n#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64\n\t\t\treturn push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI)| RD(dst) | RS1(dst) | IMM_I(48));\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\t\t\treturn push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | RD(dst) | RS1(dst) | IMM_I(16));\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t}\n\n\t\treturn emit_rev16(compiler, op, dst, src2);\n\n\tcase SLJIT_ADD:\n\t\t/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tcarry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0) {\n\t\t\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));\n\t\t\t\t\telse\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));\n\t\t\t\t} else\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));\n\t\t\t}\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {\n\t\t\t\tSLJIT_ASSERT(src2 != 0);\n\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));\n\t\t\t}\n\t\t} else {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADD | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\n\t\t\tif (is_overflow || carry_src_r != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src1;\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src2;\n\t\t\t\telse {\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(0)));\n\t\t\t\t\tcarry_src_r = OTHER_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))\n\t\t\t\tFAIL_IF(emit_add(compiler, WORD, dst, src1, src2));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (is_overflow || carry_src_r != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(dst) | RS2(carry_src_r)));\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));\n\t\tif (op & SLJIT_SET_Z) {\n\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(dst)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));\n\t\treturn push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));\n\n\tcase SLJIT_ADDC:\n\t\tcarry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tSLJIT_ASSERT(src2 != 0);\n\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));\n\t\t} else {\n\t\t\tif (carry_src_r != 0) {\n\t\t\t\tif (src1 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src1;\n\t\t\t\telse if (src2 != dst)\n\t\t\t\t\tcarry_src_r = (sljit_s32)src2;\n\t\t\t\telse {\n\t\t\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));\n\t\t\t\t\telse\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));\n\t\t\t\t\tcarry_src_r = EQUAL_FLAG;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_add(compiler, WORD, dst, src1, src2));\n\t\t}\n\n\t\t/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */\n\t\tif (carry_src_r != 0) {\n\t\t\tif (flags & SRC2_IMM)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(dst) | RS2(carry_src_r)));\n\t\t}\n\n\t\tif (RISCV_HAS_COMPRESSED(200) && WORD == 0)\n\t\t\tFAIL_IF(push_inst16(compiler,  C_ADD | C_RD(dst) | C_RS2(OTHER_FLAG)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));\n\n\t\tif (carry_src_r == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\t/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */\n\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(dst) | RS2(OTHER_FLAG)));\n\t\t/* Set carry flag. */\n\t\treturn push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG));\n\n\tcase SLJIT_SUB:\n\t\tif ((flags & SRC2_IMM) && src2 == SIMM_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_handled = 0;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (GET_FLAG_TYPE(op) == SLJIT_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));\n\t\t\t\tis_handled = 1;\n\t\t\t} else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));\n\t\t\t\tis_handled = 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {\n\t\t\tis_handled = 1;\n\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\treg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_LI | C_RD(reg) | C_IMM_I(src2)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(reg) | RS1(TMP_ZERO) | IMM_I(src2)));\n\n\t\t\t\tsrc2 = reg;\n\t\t\t\tflags &= ~SRC2_IMM;\n\t\t\t}\n\n\t\t\tswitch (GET_FLAG_TYPE(op)) {\n\t\t\tcase SLJIT_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src2) | RS2(src1)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_SIG_GREATER:\n\t\t\t\tFAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src2) | RS2(src1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (is_handled) {\n\t\t\tif (flags & SRC2_IMM) {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));\n\t\t\t\tif (!(flags & UNUSED_DEST)) {\n\t\t\t\t\tsrc2 = -src2;\n\t\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\t\t\treturn push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2));\n\n\t\t\t\t\treturn push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (op & SLJIT_SET_Z)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\t\tif (!(flags & UNUSED_DEST)) {\n\t\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))\n\t\t\t\t\t\treturn push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2));\n\n\t\t\t\t\treturn push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tis_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_overflow) {\n\t\t\t\tif (src2 >= 0) {\n\t\t\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));\n\t\t\t\t\telse\n\t\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));\n\t\t\t\t} else\n\t\t\t\t\tFAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));\n\t\t\t} else if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {\n\t\t\t\tsrc2 = -src2;\n\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));\n\t\t\t}\n\t\t} else {\n\t\t\tif (is_overflow)\n\t\t\t\tFAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\telse if (op & SLJIT_SET_Z)\n\t\t\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\n\t\t\tif (is_overflow || is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));\n\n\t\t\t/* Only the zero flag is needed. */\n\t\t\tif (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {\n\t\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))\n\t\t\t\t\tFAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2)));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));\n\t\t\t}\n\t\t}\n\n\t\tif (!is_overflow)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));\n\t\tif (op & SLJIT_SET_Z) {\n\t\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\t\tFAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(dst)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));\n\t\treturn push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));\n\n\tcase SLJIT_SUBC:\n\t\tif ((flags & SRC2_IMM) && src2 == SIMM_MIN) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));\n\t\t\tsrc2 = TMP_REG2;\n\t\t\tflags &= ~SRC2_IMM;\n\t\t}\n\n\t\tis_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;\n\n\t\tif (flags & SRC2_IMM) {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));\n\n\t\t\tsrc2 = -src2;\n\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)\n\t\t\t\tFAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));\n\t\t} else {\n\t\t\tif (is_carry)\n\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\n\t\t\tif (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))\n\t\t\t\tFAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));\n\t\t}\n\n\t\tif (is_carry)\n\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(TMP_REG1) | RS1(dst) | RS2(OTHER_FLAG)));\n\n\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));\n\n\t\tif (!is_carry)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(TMP_REG1));\n\n\tcase SLJIT_MUL:\n\t\tSLJIT_ASSERT(!(flags & SRC2_IMM));\n\n\t\tif (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW)\n\t\t\treturn push_inst(compiler, MUL | WORD | RD(dst) | RS1(src1) | RS2(src2));\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\tif (word) {\n\t\t\tFAIL_IF(push_inst(compiler, MUL | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));\n\t\t\tFAIL_IF(push_inst(compiler, MUL | 0x8 | RD(dst) | RS1(src1) | RS2(src2)));\n\t\t\treturn push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(dst) | RS2(OTHER_FLAG));\n\t\t}\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\t\tFAIL_IF(push_inst(compiler, MULH | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\t\tFAIL_IF(push_inst(compiler, MUL | RD(dst) | RS1(src1) | RS2(src2)));\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\tFAIL_IF(push_inst(compiler, SRAI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(31)));\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\tFAIL_IF(push_inst(compiler, SRAI | RD(OTHER_FLAG) | RS1(dst) | IMM_I(63)));\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\treturn push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(OTHER_FLAG));\n\n\tcase SLJIT_AND:\n\t\tEMIT_LOGICAL(ANDI, C_ANDI, AND, C_AND);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_OR:\n\t\tEMIT_LOGICAL(ORI, 0, OR, C_OR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_XOR:\n\t\tEMIT_LOGICAL(XORI, 0, XOR, C_XOR);\n\t\treturn SLJIT_SUCCESS;\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\top_imm = SLLI;\n\t\top_reg = SLL;\n\t\tbreak;\n\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\top_imm = SRLI;\n\t\top_reg = SRL;\n\t\tbreak;\n\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\top_imm = SRAI;\n\t\top_reg = SRA;\n\t\tbreak;\n\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (flags & SRC2_IMM) {\n\t\t\tSLJIT_ASSERT(src2 != 0);\n\n\t\t\tif (RISCV_HAS_BITMANIP_B(93)) {\n\t\t\t\tif (GET_OPCODE(op) == SLJIT_ROTL) {\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\t\t\tsrc2 = ((op & SLJIT_32) ? 32 : 64) - src2;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\t\t\t\t\tsrc2 = 32 - src2;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\t\t}\n\t\t\t\treturn push_inst(compiler, RORI | WORD | RD(dst) | RS1(src1) | IMM_I(src2));\n\t\t\t}\n\n\t\t\top_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLI : SRLI;\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | WORD | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\t\tsrc2 = ((op & SLJIT_32) ? 32 : 64) - src2;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\t\t\tsrc2 = 32 - src2;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\t\t\top_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLI : SLLI;\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));\n\t\t\treturn push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));\n\t\t}\n\n\t\tif (RISCV_HAS_BITMANIP_B(93))\n\t\t\treturn push_inst(compiler, (GET_OPCODE(op) == SLJIT_ROTL ? ROL : ROR) | WORD | RD(dst) | RS1(src1) | RS2(src2));\n\n\t\tif (src2 == TMP_ZERO) {\n\t\t\tif (dst != src1)\n\t\t\t\treturn push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(0));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(TMP_ZERO) | RS2(src2)));\n\t\top_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;\n\t\tFAIL_IF(push_inst(compiler, op_reg | WORD | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));\n\t\top_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;\n\t\tFAIL_IF(push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(EQUAL_FLAG)));\n\t\treturn push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (flags & SRC2_IMM) {\n\t\tif (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(push_inst(compiler, op_imm | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));\n\n\t\tif (flags & UNUSED_DEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (RISCV_HAS_COMPRESSED(200) && WORD == 0 && dst == src1) {\n\t\t\tif (op_imm == SLLI)\n\t\t\t\treturn push_inst16(compiler, C_SLLI | C_RD(dst) | C_IMM_I(src2));\n\n\t\t\tif (C_IS_R3(dst))\n\t\t\t\treturn push_inst16(compiler, (op_imm == SRLI ? C_SRLI : C_SRAI) | C_RS1_R3(dst) | C_IMM_I(src2));\n\t\t}\n\n\t\treturn push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2));\n\t}\n\n\tif (op & SLJIT_SET_Z)\n\t\tFAIL_IF(push_inst(compiler, op_reg | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));\n\n\tif (flags & UNUSED_DEST)\n\t\treturn SLJIT_SUCCESS;\n\treturn push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(src2));\n}\n\n#undef IMM_EXTEND\n\nstatic sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* arg1 goes to TMP_REG1 or src reg\n\t   arg2 goes to TMP_REG2, imm or src reg\n\t   TMP_REG3 can be used for caching\n\t   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */\n\tsljit_s32 dst_r = TMP_REG2;\n\tsljit_s32 src1_r;\n\tsljit_sw src2_r = 0;\n\tsljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;\n\n\tif (!(flags & ALT_KEEP_CACHE)) {\n\t\tcompiler->cache_arg = 0;\n\t\tcompiler->cache_argw = 0;\n\t}\n\n\tif (dst == 0) {\n\t\tSLJIT_ASSERT(HAS_FLAGS(op));\n\t\tflags |= UNUSED_DEST;\n\t\tdst = TMP_REG2;\n\t}\n\telse if (FAST_IS_REG(dst)) {\n\t\tdst_r = dst;\n\t\tflags |= REG_DEST;\n\t\tif (flags & MOVE_OP)\n\t\t\tsrc2_tmp_reg = dst_r;\n\t}\n\telse if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))\n\t\tflags |= SLOW_DEST;\n\n\tif (flags & IMM_OP) {\n\t\tif (src2 == SLJIT_IMM && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src2w;\n\t\t}\n\t\telse if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) {\n\t\t\tflags |= SRC2_IMM;\n\t\t\tsrc2_r = src1w;\n\n\t\t\t/* And swap arguments. */\n\t\t\tsrc1 = src2;\n\t\t\tsrc1w = src2w;\n\t\t\tsrc2 = SLJIT_IMM;\n\t\t\t/* src2w = src2_r unneeded. */\n\t\t}\n\t}\n\n\t/* Source 1. */\n\tif (FAST_IS_REG(src1)) {\n\t\tsrc1_r = src1;\n\t\tflags |= REG1_SOURCE;\n\t} else if (src1 == SLJIT_IMM) {\n\t\tif (src1w) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));\n\t\t\tsrc1_r = TMP_REG1;\n\t\t}\n\t\telse\n\t\t\tsrc1_r = TMP_ZERO;\n\t} else {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC1;\n\t\tsrc1_r = TMP_REG1;\n\t}\n\n\t/* Source 2. */\n\tif (FAST_IS_REG(src2)) {\n\t\tsrc2_r = src2;\n\t\tflags |= REG2_SOURCE;\n\t\tif ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)\n\t\t\tdst_r = (sljit_s32)src2_r;\n\t} else if (src2 == SLJIT_IMM) {\n\t\tif (!(flags & SRC2_IMM)) {\n\t\t\tif (src2w) {\n\t\t\t\tFAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w, TMP_REG3));\n\t\t\t\tsrc2_r = src2_tmp_reg;\n\t\t\t} else {\n\t\t\t\tsrc2_r = TMP_ZERO;\n\t\t\t\tif (flags & MOVE_OP) {\n\t\t\t\t\tif (dst & SLJIT_MEM)\n\t\t\t\t\t\tdst_r = 0;\n\t\t\t\t\telse\n\t\t\t\t\t\top = SLJIT_MOV;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (getput_arg_fast(compiler, flags | LOAD_DATA, src2_tmp_reg, src2, src2w))\n\t\t\tFAIL_IF(compiler->error);\n\t\telse\n\t\t\tflags |= SLOW_SRC2;\n\t\tsrc2_r = src2_tmp_reg;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tSLJIT_ASSERT(src2_r == TMP_REG2);\n\t\tif ((flags & SLOW_DEST) && !can_cache(src2, src2w, src1, src1w) && can_cache(src2, src2w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA | MEM_USE_TMP2, TMP_REG2, src2, src2w, dst, dstw));\n\t\t} else {\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, flags | LOAD_DATA | ((src1_r == TMP_REG1) ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, dst, dstw));\n\n\tFAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));\n\n\tif (dst & SLJIT_MEM) {\n\t\tif (!(flags & SLOW_DEST)) {\n\t\t\tgetput_arg_fast(compiler, flags, dst_r, dst, dstw);\n\t\t\treturn compiler->error;\n\t\t}\n\t\treturn getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n\n\tSLJIT_ASSERT(word == 0 || word == 0x8);\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_BREAKPOINT:\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\treturn push_inst16(compiler, C_EBREAK);\n\t\treturn push_inst(compiler, EBREAK);\n\tcase SLJIT_NOP:\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\treturn push_inst16(compiler, C_NOP);\n\t\treturn push_inst(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R1) | IMM_I(0)));\n\t\tFAIL_IF(push_inst(compiler, MULHU | RD(SLJIT_R1) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));\n\t\treturn push_inst(compiler, MUL | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(TMP_REG1));\n\tcase SLJIT_LMUL_SW:\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R1) | IMM_I(0)));\n\t\tFAIL_IF(push_inst(compiler, MULH | RD(SLJIT_R1) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));\n\t\treturn push_inst(compiler, MUL | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(TMP_REG1));\n\tcase SLJIT_DIVMOD_UW:\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R0) | IMM_I(0)));\n\t\tFAIL_IF(push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));\n\t\treturn push_inst(compiler, REMU | WORD | RD(SLJIT_R1) | RS1(TMP_REG1) | RS2(SLJIT_R1));\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R0) | IMM_I(0)));\n\t\tFAIL_IF(push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));\n\t\treturn push_inst(compiler, REM | WORD | RD(SLJIT_R1) | RS1(TMP_REG1) | RS2(SLJIT_R1));\n\tcase SLJIT_DIV_UW:\n\t\treturn push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1));\n\tcase SLJIT_DIV_SW:\n\t\treturn push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1));\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst(compiler, FENCE | 0x0ff00000);\n\tcase SLJIT_ENDBR:\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (op & SLJIT_32)\n\t\tflags = INT_DATA | SIGNED_DATA;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\tcase SLJIT_MOV_P:\n\t\treturn emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase SLJIT_MOV_U32:\n\t\treturn emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);\n\n\tcase SLJIT_MOV_S32:\n\t/* Logical operators have no W variant, so sign extended input is necessary for them. */\n\tcase SLJIT_MOV32:\n\t\treturn emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tcase SLJIT_MOV_U8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);\n\n\tcase SLJIT_MOV_S8:\n\t\treturn emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);\n\n\tcase SLJIT_MOV_U16:\n\t\treturn emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);\n\n\tcase SLJIT_MOV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);\n\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\tcase SLJIT_REV:\n\t\treturn emit_op(compiler, op, flags, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\treturn emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);\n\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\treturn emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (op & SLJIT_32) {\n\t\tflags |= INT_DATA | SIGNED_DATA;\n\t\tif (src1 == SLJIT_IMM)\n\t\t\tsrc1w = (sljit_s32)src1w;\n\t\tif (src2 == SLJIT_IMM)\n\t\t\tsrc2w = (sljit_s32)src2w;\n\t}\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SUB:\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_MUL:\n\t\tcompiler->status_flags_state = 0;\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\t\treturn emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\t\tsrc2w &= 0x1f;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\t\tif (op & SLJIT_32)\n\t\t\t\tsrc2w &= 0x1f;\n\t\t\telse\n\t\t\t\tsrc2w &= 0x3f;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t\t}\n\n\t\treturn emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tSLJIT_ASSERT(WORD == 0 || WORD == 0x8);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));\n\t\treturn push_inst(compiler, ADD | WORD | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG2));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_left;\n\tsljit_ins ins1, ins2, ins3;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;\n\tsljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n\tsljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n\tsljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n\tsljit_sw bit_length = 32;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tSLJIT_ASSERT(WORD == 0 || WORD == 0x8);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= bit_length - 1;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (is_left) {\n\t\t\tins1 = SLLI | WORD | IMM_I(src3w);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = SRLI | WORD | IMM_I(src3w);\n\t\t} else {\n\t\t\tins1 = SRLI | WORD | IMM_I(src3w);\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins2 = SLLI | WORD | IMM_I(src3w);\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins1 | RD(dst_reg) | RS1(src1_reg)));\n\t\tFAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src2_reg)));\n\t\treturn push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));\n\t}\n\n\tif (src3 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w));\n\t\tsrc3 = TMP_REG2;\n\t} else if (dst_reg == src3) {\n\t\tpush_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(src3) | IMM_I(0));\n\t\tsrc3 = TMP_REG2;\n\t}\n\n\tif (is_left) {\n\t\tins1 = SLL;\n\t\tins2 = SRLI;\n\t\tins3 = SRL;\n\t} else {\n\t\tins1 = SRL;\n\t\tins2 = SLLI;\n\t\tins3 = SLL;\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins1 | WORD | RD(dst_reg) | RS1(src1_reg) | RS2(src3)));\n\n\tif (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {\n\t\tFAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src2_reg) | IMM_I(1)));\n\t\tFAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src3) | IMM_I((sljit_ins)bit_length - 1)));\n\t\tsrc2_reg = TMP_REG1;\n\t} else\n\t\tFAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src3)));\n\n\tFAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src2_reg) | RS2(TMP_REG2)));\n\treturn push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r, tmp_r;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));\n\t\tsrc2 = TMP_REG2;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));\n\t\tsrc1 = TMP_REG1;\n\t} else if (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\tins = 0;\n\n\tif (RISCV_HAS_BITMANIP_A(93)) {\n\t\tswitch (shift_arg) {\n\t\tcase 1:\n\t\t\tins = SH1ADD;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tins = SH2ADD;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tins = SH3ADD;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (ins == 0) {\n\t\ttmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(src2) | IMM_I(shift_arg)));\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RS1(src1) | RS2(tmp_r)));\n\t} else {\n\t\tFAIL_IF(push_inst(compiler, ins | RD(dst_r) | RS1(src2) | RS2(src1)));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, WORD_DATA, dst_r, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tif (src != RETURN_ADDR_REG)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(RETURN_ADDR_REG) | RS1(src) | IMM_I(0)));\n\t\t} else\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));\n\n\t\treturn push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(RETURN_ADDR_REG) | IMM_I(0));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (dst == RETURN_ADDR_REG)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0));\n\t\t}\n\n\t\tSLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2);\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn reg_map[reg];\n\n\tif (type == SLJIT_FLOAT_REGISTER)\n\t\treturn freg_map[reg];\n\n\treturn vreg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tSLJIT_UNUSED_ARG(size);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\tif (size == 2)\n\t\treturn push_inst16(compiler, *(sljit_u16*)instruction);\n\n\treturn push_inst(compiler, *(sljit_ins*)instruction);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))\n#define FMT(op) ((sljit_ins)((op & SLJIT_32) ^ SLJIT_32) << 17)\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#\tdefine flags (sljit_u32)0\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tsljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, FCVT_W_S | FMT(op) | flags | RD(dst_r) | FRS1(src)));\n\n\t/* Store the integer value from a VFP register. */\n\tif (dst & SLJIT_MEM) {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\treturn emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\treturn emit_op_mem2(compiler, flags ? WORD_DATA : INT_DATA, TMP_REG2, dst, dstw, 0, 0);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\t}\n\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n#\tundef flags\n#endif /* SLJIT_CONFIG_RISCV_32 */\n}\n\nstatic sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\tFAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));\n#else /* SLJIT_CONFIG_RISCV_32 */\n\t\tFAIL_IF(emit_op_mem2(compiler, ((ins & (1 << 21)) ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));\n#endif /* !SLJIT_CONFIG_RISCV_32 */\n\t\tsrc = TMP_REG1;\n\t} else if (src == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins | FRD(dst_r) | RS1(src)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, DOUBLE_DATA | ((sljit_s32)(~ins >> 24) & 0x2), TMP_FREG1, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins = FCVT_S_W | FMT(op);\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif (op & SLJIT_32)\n\t\tins |= F3(0x7);\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)\n\t\tins |= (1 << 21);\n\telse if (src == SLJIT_IMM)\n\t\tsrcw = (sljit_s32)srcw;\n\n\tif (op != SLJIT_CONV_F64_FROM_S32)\n\t\tins |= F3(0x7);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins = FCVT_S_WU | FMT(op);\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif (op & SLJIT_32)\n\t\tins |= F3(0x7);\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW)\n\t\tins |= (1 << 21);\n\telse if (src == SLJIT_IMM)\n\t\tsrcw = (sljit_u32)srcw;\n\n\tif (op != SLJIT_CONV_F64_FROM_S32)\n\t\tins |= F3(0x7);\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_ins inst;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));\n\t\tsrc2 = TMP_FREG2;\n\t}\n\n\tswitch (GET_FLAG_TYPE(op)) {\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\t\tinst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);\n\t\tbreak;\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\tinst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);\n\t\tbreak;\n\tcase SLJIT_ORDERED_GREATER:\n\t\tinst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1);\n\t\tbreak;\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tinst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2);\n\t\tbreak;\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\tinst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1);\n\t\tbreak;\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\tFAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2)));\n\t\tFAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src1)));\n\t\tinst = OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1);\n\t\tbreak;\n\tdefault: /* SLJIT_UNORDERED */\n\t\tif (src1 == src2) {\n\t\t\tinst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1);\n\t\t\tbreak;\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1)));\n\t\tFAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src2)));\n\t\tinst = AND | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1);\n\t\tbreak;\n\t}\n\n\treturn push_inst(compiler, inst);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tSLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)\n\t\top ^= SLJIT_32;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));\n\t\tsrc = dst_r;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_F64:\n\t\tif (src != dst_r) {\n\t\t\tif (!(dst & SLJIT_MEM))\n\t\t\t\tFAIL_IF(push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));\n\t\t\telse\n\t\t\t\tdst_r = src;\n\t\t}\n\t\tbreak;\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(push_inst(compiler, FSGNJN_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));\n\t\tbreak;\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(push_inst(compiler, FSGNJX_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));\n\t\tbreak;\n\tcase SLJIT_CONV_F64_FROM_F32:\n\t\t/* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */\n\t\tFAIL_IF(push_inst(compiler, FCVT_S_D | ((op & SLJIT_32) ? (1 << 25) : ((1 << 20) | F3(7))) | FRD(dst_r) | FRS1(src)));\n\t\top ^= SLJIT_32;\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r, flags = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc1 = TMP_FREG1;\n\t\t} else\n\t\t\tflags |= SLOW_SRC1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tif (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {\n\t\t\tFAIL_IF(compiler->error);\n\t\t\tsrc2 = TMP_FREG2;\n\t\t} else\n\t\t\tflags |= SLOW_SRC2;\n\t}\n\n\tif ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {\n\t\tif ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));\n\t\t} else {\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));\n\t\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));\n\t\t}\n\t}\n\telse if (flags & SLOW_SRC1)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));\n\telse if (flags & SLOW_SRC2)\n\t\tFAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));\n\n\tif (flags & SLOW_SRC1)\n\t\tsrc1 = TMP_FREG1;\n\tif (flags & SLOW_SRC2)\n\t\tsrc2 = TMP_FREG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(push_inst(compiler, FADD_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));\n\t\tbreak;\n\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(push_inst(compiler, FSUB_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));\n\t\tbreak;\n\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(push_inst(compiler, FMUL_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));\n\t\tbreak;\n\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(push_inst(compiler, FDIV_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)));\n\t\tbreak;\n\n\tcase SLJIT_COPYSIGN_F64:\n\t\treturn push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2));\n\t}\n\n\tif (dst_r != dst)\n\t\tFAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm == 0)\n\t\treturn push_inst(compiler, FMV_W_X | RS1(TMP_ZERO) | FRD(freg));\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3));\n\treturn push_inst(compiler, FMV_W_X | RS1(TMP_REG1) | FRD(freg));\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask = 0, i;\n\tstruct sljit_label *label = NULL;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (RISCV_HAS_COMPRESSED(200)) {\n\t\tif (alignment <= SLJIT_LABEL_ALIGN_2) {\n\t\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\t\tlabel = sljit_emit_label(compiler);\n\t\t\tPTR_FAIL_IF(!label);\n\t\t} else {\n\t\t\t/* The used space is filled with NOPs. */\n\t\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);\n\n\t\t\tfor (i = (mask >> 1); i != 0; i--)\n\t\t\t\tPTR_FAIL_IF(push_inst16(compiler, C_NOP));\n\t\t}\n\t} else {\n\t\tif (alignment <= SLJIT_LABEL_ALIGN_4) {\n\t\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\t\tlabel = sljit_emit_label(compiler);\n\t\t\tPTR_FAIL_IF(!label);\n\t\t} else {\n\t\t\t/* The used space is filled with NOPs. */\n\t\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);\n\n\t\t\tfor (i = (mask >> 2); i != 0; i--)\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\t\t}\n\t}\n\n\tif (label == NULL) {\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tif (RISCV_HAS_COMPRESSED(200)) {\n\t\t\tfor (i = (buffers->size + 1) >> 1; i > 0; i--)\n\t\t\t\tPTR_FAIL_IF(push_inst16(compiler, C_NOP));\n\t\t} else {\n\t\t\tfor (i = (buffers->size + 3) >> 2; i > 0; i--)\n\t\t\t\tPTR_FAIL_IF(push_inst(compiler, NOP));\n\t\t}\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nstatic sljit_ins get_jump_instruction(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\treturn BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO);\n\tcase SLJIT_NOT_EQUAL:\n\t\treturn BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO);\n\tcase SLJIT_LESS:\n\tcase SLJIT_GREATER:\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_OVERFLOW:\n\tcase SLJIT_CARRY:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_ORDERED_GREATER:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_ORDERED:\n\t\treturn BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO);\n\t\tbreak;\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_NOT_OVERFLOW:\n\tcase SLJIT_NOT_CARRY:\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_UNORDERED:\n\t\treturn BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO);\n\tdefault:\n\t\t/* Not conditional branch. */\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_ins inst;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\ttype &= 0xff;\n\n\tinst = get_jump_instruction(type);\n\n\tif (inst != 0) {\n\t\tPTR_FAIL_IF(push_inst(compiler, inst | BRANCH_LENGTH));\n\t\tjump->flags |= IS_COND;\n\t}\n\n\tjump->addr = compiler->size;\n\n\tif (type >= SLJIT_FAST_CALL)\n\t\tjump->flags |= IS_CALL;\n\n\tPTR_FAIL_IF(push_inst16(compiler, 0));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 flags;\n\tsljit_ins inst;\n\tsljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tflags = WORD_DATA | LOAD_DATA;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tflags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\tif (src1 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG1, src1, src1w, src2, src2w));\n\t\tsrc1 = TMP_REG1;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tPTR_FAIL_IF(emit_op_mem2(compiler, flags | (src1 == TMP_REG1 ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, 0, 0));\n\t\tsrc2 = src2_tmp_reg;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tif (src1w != 0) {\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));\n\t\t\tsrc1 = TMP_REG1;\n\t\t}\n\t\telse\n\t\t\tsrc1 = TMP_ZERO;\n\t}\n\n\tif (src2 == SLJIT_IMM) {\n\t\tif (src2w != 0) {\n\t\t\tPTR_FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w, TMP_REG3));\n\t\t\tsrc2 = src2_tmp_reg;\n\t\t}\n\t\telse\n\t\t\tsrc2 = TMP_ZERO;\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | IS_COND));\n\ttype &= 0xff;\n\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\tif (RISCV_HAS_COMPRESSED(200)) {\n\t\t\tif (src1 == TMP_ZERO && C_IS_R3(src2)) {\n\t\t\t\tinst = C_BNEZ | C_RS1_R3(src2) | BRANCH16_LENGTH;\n\t\t\t\tjump->flags |= IS_COND16;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (src2 == TMP_ZERO && C_IS_R3(src1)) {\n\t\t\t\tinst = C_BNEZ | C_RS1_R3(src1) | BRANCH16_LENGTH;\n\t\t\t\tjump->flags |= IS_COND16;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tinst = BNE | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_NOT_EQUAL:\n\t\tif (RISCV_HAS_COMPRESSED(200)) {\n\t\t\tif (src1 == TMP_ZERO && C_IS_R3(src2)) {\n\t\t\t\tinst = C_BEQZ | C_RS1_R3(src2) | BRANCH16_LENGTH;\n\t\t\t\tjump->flags |= IS_COND16;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (src2 == TMP_ZERO && C_IS_R3(src1)) {\n\t\t\t\tinst = C_BEQZ | C_RS1_R3(src1) | BRANCH16_LENGTH;\n\t\t\t\tjump->flags |= IS_COND16;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tinst = BEQ | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_LESS:\n\t\tinst = BGEU | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_GREATER_EQUAL:\n\t\tinst = BLTU | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_GREATER:\n\t\tinst = BGEU | RS1(src2) | RS2(src1) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_LESS_EQUAL:\n\t\tinst = BLTU | RS1(src2) | RS2(src1) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_SIG_LESS:\n\t\tinst = BGE | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\tinst = BLT | RS1(src1) | RS2(src2) | BRANCH_LENGTH;\n\t\tbreak;\n\tcase SLJIT_SIG_GREATER:\n\t\tinst = BGE | RS1(src2) | RS2(src1) | BRANCH_LENGTH;\n\t\tbreak;\n\tdefault: /* SLJIT_SIG_LESS_EQUAL */\n\t\tinst = BLT | RS1(src2) | RS2(src1) | BRANCH_LENGTH;\n\t\tbreak;\n\t}\n\n\tSLJIT_COMPILE_ASSERT((C_BEQZ & 0x2) == 0 && (C_BNEZ & 0x2) == 0, branch16_bit_error);\n\tif (RISCV_COMPRESSED_CHECK((inst & 0x2) == 0))\n\t\tPTR_FAIL_IF(push_inst16(compiler, (sljit_u16)inst));\n\telse\n\t\tPTR_FAIL_IF(push_inst(compiler, inst));\n\n\tjump->addr = compiler->size;\n\tPTR_FAIL_IF(push_inst16(compiler, 0));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src != SLJIT_IMM) {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\treturn push_inst16(compiler, ((type >= SLJIT_FAST_CALL) ? C_JALR : C_JR) | C_RD(src));\n\n\t\treturn push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(src) | IMM_I(0));\n\t}\n\n\t/* These jumps are converted to jump/call instructions when possible. */\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_CALL : 0));\n\tjump->u.target = (sljit_uw)srcw;\n\n\tjump->addr = compiler->size;\n\tFAIL_IF(push_inst16(compiler, 0));\n\n\t/* Maximum number of instructions required for generating a constant. */\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src) | IMM_I(0)));\n\t\t\tsrc = TMP_REG1;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_s32 src_r, dst_r, invert;\n\tsljit_s32 saved_op = op;\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tsljit_s32 mem_type = WORD_DATA;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tsljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\top = GET_OPCODE(op);\n\tdst_r = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;\n\n\tcompiler->cache_arg = 0;\n\tcompiler->cache_argw = 0;\n\n\tif (op >= SLJIT_ADD && (dst & SLJIT_MEM))\n\t\tFAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));\n\n\tif (type < SLJIT_F_EQUAL) {\n\t\tsrc_r = OTHER_FLAG;\n\t\tinvert = type & 0x1;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_EQUAL:\n\t\tcase SLJIT_NOT_EQUAL:\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RS1(EQUAL_FLAG) | IMM_I(1)));\n\t\t\tsrc_r = dst_r;\n\t\t\tbreak;\n\t\tcase SLJIT_OVERFLOW:\n\t\tcase SLJIT_NOT_OVERFLOW:\n\t\t\tif (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {\n\t\t\t\tsrc_r = OTHER_FLAG;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RS1(OTHER_FLAG) | IMM_I(1)));\n\t\t\tsrc_r = dst_r;\n\t\t\tinvert ^= 0x1;\n\t\t\tbreak;\n\t\tcase SLJIT_ATOMIC_STORED:\n\t\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\t\tinvert ^= 0x1;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tinvert = 0;\n\t\tsrc_r = OTHER_FLAG;\n\n\t\tswitch (type) {\n\t\tcase SLJIT_F_NOT_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */\n\t\tcase SLJIT_F_GREATER_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\tcase SLJIT_F_GREATER:\n\t\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\tcase SLJIT_UNORDERED_OR_LESS:\n\t\tcase SLJIT_UNORDERED:\n\t\t\tinvert = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (invert) {\n\t\tFAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(src_r) | IMM_I(1)));\n\t\tsrc_r = dst_r;\n\t}\n\n\tif (op < SLJIT_ADD) {\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn emit_op_mem(compiler, mem_type, src_r, dst, dstw);\n\n\t\tif (src_r != dst_r)\n\t\t\treturn push_inst(compiler, ADDI | RD(dst_r) | RS1(src_r) | IMM_I(0));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tmem_type |= CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE;\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, src_r, 0);\n\treturn emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, src_r, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_u16 *ptr;\n\tsljit_uw size;\n\tsljit_ins ins;\n\tsljit_s32 cond_is_1;\n\tsljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tsljit_ins word = (sljit_ins)(type & SLJIT_32) >> 5;\n\tsljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;\n#else /* !SLJIT_CONFIG_RISCV_64 */\n        sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tSLJIT_ASSERT(WORD == 0 || WORD == 0x8);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tif (src1 == SLJIT_IMM && word)\n\t\tsrc1w = (sljit_s32)src1w;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\ttype &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\n\tif (is_compare || RISCV_HAS_ICOND(100)) {\n\t\tif (src1 & SLJIT_MEM) {\n\t\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w));\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t} else if (src1 == SLJIT_IMM) {\n\t\t\tif (src1w == 0) {\n\t\t\t\tsrc1 = TMP_ZERO;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\tsrc1w = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (RISCV_HAS_BITMANIP_B(93) && is_compare) {\n\t\t\tswitch (type) {\n\t\t\tcase SLJIT_LESS:\n\t\t\tcase SLJIT_LESS_EQUAL:\n\t\t\t\treturn push_inst(compiler, MINU | RD(dst_reg) | RS1(src1) | RS2(src2_reg));\n\t\t\tcase SLJIT_GREATER:\n\t\t\tcase SLJIT_GREATER_EQUAL:\n\t\t\t\treturn push_inst(compiler, MAXU | RD(dst_reg) | RS1(src1) | RS2(src2_reg));\n\t\t\tcase SLJIT_SIG_LESS:\n\t\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\t\treturn push_inst(compiler, MIN | RD(dst_reg) | RS1(src1) | RS2(src2_reg));\n\t\t\tdefault:\n\t\t\t\treturn push_inst(compiler, MAX | RD(dst_reg) | RS1(src1) | RS2(src2_reg));\n\t\t\t}\n\t\t}\n\n\t\tif (RISCV_HAS_ICOND(100)) {\n\t\t\tif (is_compare) {\n\t\t\t\tcond_is_1 = 0;\n\n\t\t\t\tswitch (type) {\n\t\t\t\tcase SLJIT_LESS:\n\t\t\t\tcase SLJIT_LESS_EQUAL:\n\t\t\t\t\tcond_is_1 = 1;\n\t\t\t\t\tSLJIT_FALLTHROUGH\n\t\t\t\tcase SLJIT_GREATER:\n\t\t\t\tcase SLJIT_GREATER_EQUAL:\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2_reg)));\n\t\t\t\t\tbreak;\n\t\t\t\tcase SLJIT_SIG_LESS:\n\t\t\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\t\t\tcond_is_1 = 1;\n\t\t\t\t\tSLJIT_FALLTHROUGH\n\t\t\t\tdefault:\n\t\t\t\t\tFAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2_reg)));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\ttype = OTHER_FLAG;\n\t\t\t} else {\n\t\t\t\t/* BEQ instruction (type is inverted). */\n\t\t\t\tcond_is_1 = (get_jump_instruction(type) & F3(0x1)) == 0;\n\t\t\t\ttype = (type == SLJIT_EQUAL || type == SLJIT_NOT_EQUAL) ? EQUAL_FLAG : OTHER_FLAG;\n\t\t\t}\n\n\t\t\tif (src1 == TMP_ZERO)\n\t\t\t\treturn push_inst(compiler, (cond_is_1 ? CZERO_NEZ : CZERO_EQZ) | RD(dst_reg) | RS1(src2_reg) | RS2(type));\n\n\t\t\tFAIL_IF(push_inst(compiler, (cond_is_1 ? CZERO_EQZ : CZERO_NEZ) | RD(TMP_REG1) | RS1(src1) | RS2(type)));\n\t\t\tFAIL_IF(push_inst(compiler, (cond_is_1 ? CZERO_NEZ : CZERO_EQZ) | RD(dst_reg) | RS1(src2_reg) | RS2(type)));\n\t\t\treturn push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));\n\t\t}\n\t}\n\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\tsrc2_reg = dst_reg;\n\t\t\tif (!is_compare)\n\t\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tif (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\t\tSLJIT_ASSERT(!(type & SLJIT_COMPARE_SELECT));\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(dst_reg) | IMM_I(0)));\n\n\t\t\t\tif ((src1 & REG_MASK) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~REG_MASK) | TMP_REG1;\n\n\t\t\t\tif (OFFS_REG(src1) == dst_reg)\n\t\t\t\t\tsrc1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src2_reg) | IMM_I(0)));\n\t\t}\n\t}\n\n\tif (src1 == SLJIT_IMM && (src1w <= 0 && src1w >= -1)) {\n\t\tsrc1 = OTHER_FLAG;\n\n\t\tif (type == SLJIT_EQUAL || type == SLJIT_NOT_EQUAL) {\n\t\t\tFAIL_IF(push_inst(compiler, SLTUI | RD(TMP_REG1) | RS1(EQUAL_FLAG) | IMM_I(1)));\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tcond_is_1 = (type == SLJIT_EQUAL);\n\t\t} else {\n\t\t\t/* BEQ instruction (type is inverted). */\n\t\t\tcond_is_1 = (get_jump_instruction(type) & F3(0x1)) == 0;\n\t\t}\n\n\t\tif (src1w == 0) {\n\t\t\tif (cond_is_1)\n\t\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src1) | IMM_I(-1)));\n\t\t\telse\n\t\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RS1(TMP_ZERO) | RS2(src1)));\n\n\t\t\treturn push_inst(compiler, AND | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));\n\t\t}\n\n\t\tif (cond_is_1)\n\t\t\tFAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RS1(TMP_ZERO) | RS2(src1)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src1) | IMM_I(-1)));\n\n\t\treturn push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));\n\t}\n\n\tsize = compiler->size;\n\n\tptr = (sljit_u16 *)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size += 2;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w));\n\t} else if (src1 == SLJIT_IMM) {\n\t\tFAIL_IF(load_immediate(compiler, dst_reg, src1w, TMP_REG1));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src1) | IMM_I(0)));\n\n\tsize = compiler->size - size;\n\n\tif (is_compare) {\n\t\tswitch (type) {\n\t\tcase SLJIT_LESS:\n\t\tcase SLJIT_LESS_EQUAL:\n\t\t\tins = BGEU;\n\t\t\tbreak;\n\t\tcase SLJIT_GREATER:\n\t\tcase SLJIT_GREATER_EQUAL:\n\t\t\tins = BLTU;\n\t\t\tbreak;\n\t\tcase SLJIT_SIG_LESS:\n\t\tcase SLJIT_SIG_LESS_EQUAL:\n\t\t\tins = BGE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tins = BLT;\n\t\t\tbreak;\n\t\t}\n\n\t\tins |= RS1(src1) | RS2(src2_reg);\n\t} else {\n\t\tins = get_jump_instruction(type);\n\t}\n\n\tins |= (sljit_ins)((size & 0xf) << 8) | (sljit_ins)((size >> 4) << 25);\n\tptr[0] = (sljit_u16)ins;\n\tptr[1] = (sljit_u16)(ins >> 16);\n\treturn SLJIT_SUCCESS;\n}\n\n#undef WORD\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_u16 *ptr;\n\tsljit_ins ins;\n\tsljit_uw size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src2_freg) | FRS2(src2_freg)));\n\t}\n\n\tsize = compiler->size;\n\n\tptr = (sljit_u16 *)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ptr);\n\tcompiler->size += 2;\n\n\tif (src1 & SLJIT_MEM)\n\t\tFAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w));\n\telse\n\t\tFAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src1) | FRS2(src1)));\n\n\tsize = compiler->size - size;\n\tins = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0xf) << 8) | (sljit_ins)((size >> 4) << 25);\n\tptr[0] = (sljit_u16)ins;\n\tptr[1] = (sljit_u16)(ins >> 16);\n\treturn SLJIT_SUCCESS;\n}\n\n#undef FLOAT_DATA\n#undef FMT\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tmemw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(memw != 0)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG1) | RS1(OFFS_REG(mem)) | IMM_I(memw)));\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(mem & REG_MASK)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(mem & REG_MASK) | RS2(OFFS_REG(mem))));\n\n\t\tmem = TMP_REG1;\n\t\tmemw = 0;\n\t} else if (memw > SIMM_MAX - SSIZE_OF(sw) || memw < SIMM_MIN) {\n\t\tif (((memw + 0x800) & 0xfff) <= 0xfff - SSIZE_OF(sw)) {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, TO_ARGW_HI(memw), TMP_REG3));\n\t\t\tmemw &= 0xfff;\n\t\t} else {\n\t\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw, TMP_REG3));\n\t\t\tmemw = 0;\n\t\t}\n\n\t\tif (mem & REG_MASK)\n\t\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(mem & REG_MASK)));\n\n\t\tmem = TMP_REG1;\n\t} else {\n\t\tmem &= REG_MASK;\n\t\tmemw &= 0xfff;\n\t}\n\n\tSLJIT_ASSERT((memw >= 0 && memw <= SIMM_MAX - SSIZE_OF(sw)) || (memw > SIMM_MAX && memw <= 0xfff));\n\n\tif (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {\n\t\tFAIL_IF(push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_SECOND(reg), mem, (memw + SSIZE_OF(sw)) & 0xfff));\n\t\treturn push_mem_inst(compiler, WORD_DATA | LOAD_DATA, REG_PAIR_FIRST(reg), mem, memw);\n\t}\n\n\tflags = WORD_DATA | (!(type & SLJIT_MEM_STORE) ? LOAD_DATA : 0);\n\n\tFAIL_IF(push_mem_inst(compiler, flags, REG_PAIR_FIRST(reg), mem, memw));\n\treturn push_mem_inst(compiler, flags, REG_PAIR_SECOND(reg), mem, (memw + SSIZE_OF(sw)) & 0xfff);\n}\n\n#undef TO_ARGW_HI\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (!RISCV_HAS_ATOMIC(200) || (op & SLJIT_ATOMIC_USE_CAS))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\tins = LR | (3 << 12);\n\t\tbreak;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\tins = LR | (2 << 12);\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | RD(dst_reg) | RS1(mem_reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\n\t/* temp_reg == mem_reg is undefined so use another temp register */\n\tSLJIT_UNUSED_ARG(temp_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (!RISCV_HAS_ATOMIC(200) || (op & SLJIT_ATOMIC_USE_CAS))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\t\tins = SC | (3 << 12);\n\t\tbreak;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tcase SLJIT_MOV_S32:\n\tcase SLJIT_MOV32:\n\t\tins = SC | (2 << 12);\n\t\tbreak;\n\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins | RD(OTHER_FLAG) | RS1(mem_reg) | RS2(src_reg));\n}\n\nstatic sljit_s32 sljit_max_vector_length = 0;\n\nstatic void init_compiler(void)\n{\n\tsljit_sw vector_length;\n\tsljit_s32 vector_length_log2;\n\n\tif (!RISCV_HAS_VECTOR(100))\n\t\treturn;\n\n\t__asm__ __volatile__ (\"csrr %0, 0xc22\" : \"=r\" (vector_length));\n\n\t/* Probably something is wrong. */\n\tif (vector_length < (1 << 3))\n\t\treturn;\n\n\tvector_length_log2 = 3;\n\tif (vector_length_log2 < 6 && vector_length > (1 << vector_length_log2))\n\t\tvector_length_log2++;\n\tsljit_max_vector_length = vector_length_log2;\n}\n\n/*\n  SEW = Selected element width\n  LMUL = Vector register group multiplier\n\n  VLMUL values (in binary):\n    100 : reserved\n    101 : 1/8\n    110 : 1/4\n    111 : 1/2\n    000 : 1\n    001 : 2\n    010 : 4\n    011 : 8\n*/\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_vsetivli(struct sljit_compiler *compiler, sljit_s32 type, sljit_ins vlmul)\n{\n\tsljit_ins elem_size = (sljit_ins)SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins avl = (sljit_ins)1 << (SLJIT_SIMD_GET_REG_SIZE(type) - elem_size);\n\n\tif (avl < 31)\n\t\treturn push_inst(compiler, VSETIVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | (avl << 15));\n\n\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(avl)));\n\treturn push_inst(compiler, VSETVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | RS1(TMP_REG1));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_vsetivli_size(struct sljit_compiler *compiler, sljit_s32 reg_size, sljit_s32 elem_size)\n{\n\tsljit_ins avl = (sljit_ins)1 << (reg_size - elem_size);\n\n\tif (avl < 31)\n\t\treturn push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (avl << 15));\n\n\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(avl)));\n\treturn push_inst(compiler, VSETVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | RS1(TMP_REG1));\n}\n\nstatic sljit_s32 sljit_emit_vmem(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 elem_size, sljit_s32 mem, sljit_sw memw)\n{\n\tsljit_s32 base = mem & REG_MASK;\n\n\tif (elem_size > 0)\n\t\tins |= (1 << 14) | ((sljit_ins)elem_size << 12);\n\n\tif (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {\n\t\tmemw &= 0x3;\n\n\t\tif (SLJIT_UNLIKELY(memw)) {\n\t\t\tFAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG1) | RS1(OFFS_REG(mem)) | IMM_I(memw)));\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(base) | RS2(!memw ? OFFS_REG(mem) : TMP_REG1)));\n\t\treturn push_inst(compiler, ins | RS1(TMP_REG1));\n\t}\n\n\tif (memw == 0)\n\t\treturn push_inst(compiler, ins | RS1(base));\n\n\tif (memw <= SIMM_MAX && memw >= SIMM_MIN) {\n\t\tFAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(base) | IMM_I(memw)));\n\t\treturn push_inst(compiler, ins | RS1(TMP_REG1));\n\t}\n\n\tFAIL_IF(load_immediate(compiler, TMP_REG1, memw, TMP_REG3));\n\n\tif (base != 0)\n\t\tFAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(base)));\n\n\treturn push_inst(compiler, ins | RS1(TMP_REG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (elem_size > 3)\n\t\telem_size = 3;\n\n\tFAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size));\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tins = (type & SLJIT_SIMD_STORE) ? VS : VL;\n\t\treturn sljit_emit_vmem(compiler, ins | VRD(vreg), elem_size, srcdst, srcdstw);\n\t}\n\n\tif (type & SLJIT_SIMD_STORE)\n\t\tins = VRD(srcdst) | VRS1(vreg);\n\telse\n\t\tins = VRD(vreg) | VRS1(srcdst);\n\n\treturn push_inst(compiler, VMV_VV | ins);\n}\n\nstatic sljit_s32 sljit_simd_get_mem_flags(sljit_s32 elem_size)\n{\n\tswitch (elem_size) {\n\tcase 0:\n\t\treturn BYTE_DATA;\n\tcase 1:\n\t\treturn HALF_DATA;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase 2:\n\t\treturn INT_DATA;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tdefault:\n\t\treturn WORD_DATA;\n\t}\n}\n\nstatic sljit_sw sljit_simd_get_imm(sljit_s32 elem_size, sljit_sw imm)\n{\n\tswitch (elem_size) {\n\tcase 0:\n\t\treturn (sljit_s8)imm;\n\tcase 1:\n\t\treturn (sljit_s16)imm;\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase 2:\n\t\treturn (sljit_s32)imm;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\tdefault:\n\t\treturn imm;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tif (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(sljit_emit_vsetivli(compiler, type, 0));\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM)\n\t\t\treturn push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15));\n\n\t\tif (src & SLJIT_MEM) {\n\t\t\tflags = (elem_size == 2) ? SINGLE_DATA : DOUBLE_DATA;\n\t\t\tFAIL_IF(emit_op_mem(compiler, flags | LOAD_DATA, TMP_FREG1, src, srcw));\n\t\t\tsrc = TMP_FREG1;\n\t\t}\n\n\t\treturn push_inst(compiler, VFMV_VF | VRD(vreg) | FRS1(src));\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tsrcw = sljit_simd_get_imm(elem_size, srcw);\n\n\t\tif (srcw >= -0x10 && srcw <= 0xf)\n\t\t\treturn push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15));\n\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3));\n\t\tsrc = TMP_REG1;\n\t} else if (src & SLJIT_MEM) {\n\t\tFAIL_IF(emit_op_mem(compiler, sljit_simd_get_mem_flags(elem_size) | LOAD_DATA, TMP_REG1, src, srcw));\n\t\tsrc = TMP_REG1;\n\t}\n\n\treturn push_inst(compiler, VMV_VX | VRD(vreg) | RS1(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 flags;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tif (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (type & SLJIT_SIMD_STORE) {\n\t\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15)));\n\n\t\tif (lane_index > 0) {\n\t\t\tFAIL_IF(push_inst(compiler, VSLIDEDOWN_VI | VRD(TMP_VREG1) | ((sljit_ins)lane_index << 15) | VRS2(vreg)));\n\t\t\tvreg = TMP_VREG1;\n\t\t}\n\n\t\tif (srcdst & SLJIT_MEM)\n\t\t\treturn sljit_emit_vmem(compiler, VS | VRD(vreg), elem_size, srcdst, srcdstw);\n\n\t\tif (type & SLJIT_SIMD_FLOAT)\n\t\t\treturn push_inst(compiler, VFMV_FS | FRD(srcdst) | VRS2(vreg));\n\n\t\tFAIL_IF(push_inst(compiler, VMV_XS | RD(srcdst) | VRS2(vreg)));\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\tif ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 2)\n\t\t\treturn SLJIT_SUCCESS;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\tif ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3 || (elem_size == 2 && (type & SLJIT_32)))\n\t\t\treturn SLJIT_SUCCESS;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\t\tif (elem_size == 0)\n\t\t\treturn push_inst(compiler, ANDI | RD(srcdst) | RS1(srcdst) | IMM_I(0xff));\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\t\tflags = 16;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\t\tflags = (elem_size == 1) ? 48 : 32;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\t\tFAIL_IF(push_inst(compiler, SLLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags)));\n\t\treturn push_inst(compiler, SRLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags));\n\t}\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tFAIL_IF(sljit_emit_vsetivli(compiler, type, 0));\n\t\tFAIL_IF(push_inst(compiler, VMV_VI | VRD(vreg)));\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15)));\n\t\tFAIL_IF(sljit_emit_vmem(compiler, VL | VRD(lane_index > 0 ? TMP_VREG1 : vreg), elem_size, srcdst, srcdstw));\n\n\t\tif (lane_index == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15)));\n\t\treturn push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1));\n\t}\n\n\tif (!(type & SLJIT_SIMD_LANE_ZERO) || lane_index > 0)\n\t\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15)));\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tFAIL_IF(push_inst(compiler, VFMV_SF | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | FRS1(srcdst)));\n\n\t\tif (lane_index == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\treturn push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1));\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tsrcdstw = sljit_simd_get_imm(elem_size, srcdstw);\n\t\tFAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw, TMP_REG3));\n\t\tsrcdst = TMP_REG1;\n\t}\n\n\tFAIL_IF(push_inst(compiler, VMV_SX | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | RS1(srcdst)));\n\n\tif (lane_index == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(sljit_emit_vsetivli(compiler, type, 0));\n\n\tFAIL_IF(push_inst(compiler, VRGATHER_VI | VRD(vreg != src ? vreg : TMP_VREG1) | ((sljit_ins)src_lane_index << 15) | VRS2(src)));\n\tif (vreg == src)\n\t\treturn push_inst(compiler, VMV_VV | VRD(vreg) | VRS1(TMP_VREG1));\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#else /* !SLJIT_CONFIG_RISCV_32 */\n\tif (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_RISCV_32 */\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif ((src & SLJIT_MEM) || vreg == src) {\n\t\tins = (sljit_ins)1 << (reg_size - elem2_size);\n\t\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (ins << 15)));\n\n\t\tif (src & SLJIT_MEM)\n\t\t\tFAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src, srcw));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src)));\n\n\t\tsrc = TMP_VREG1;\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tFAIL_IF(sljit_emit_vsetivli(compiler, type, 0x7));\n\t\treturn push_inst(compiler, VFWCVT_FFV | VRD(vreg) | VRS2(src));\n\t}\n\n\tins = (sljit_ins)1 << (reg_size - elem2_size);\n\tFAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem2_size << 23) | (ins << 15)));\n\n\tswitch (elem2_size - elem_size) {\n\tcase 1:\n\t\tins = VZEXT_VF2;\n\t\tbreak;\n\tcase 2:\n\t\tins = VZEXT_VF4;\n\t\tbreak;\n\tdefault:\n\t\tins = VZEXT_VF8;\n\t\tbreak;\n\t}\n\n\tif (type & SLJIT_SIMD_EXTEND_SIGNED)\n\t\tins |= 1 << 15;\n\n\treturn push_inst(compiler, ins | VRD(vreg) | VRS2(src));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tFAIL_IF(sljit_emit_vsetivli(compiler, type, 0));\n\tFAIL_IF(push_inst(compiler, VMV_VI | VRD(TMP_VREG1) | (0x0 << 15)));\n\tFAIL_IF(push_inst(compiler, VMSLE_VI | VRD(TMP_VREG1) | (0x1f << 15) | VRS2(vreg)));\n\n\tFAIL_IF(sljit_emit_vsetivli_size(compiler, 2, 2));\n\tFAIL_IF(push_inst(compiler, VMV_XS | RD(dst_r) | VRS2(TMP_VREG1)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_op_mem(compiler, (type & SLJIT_32) ? INT_DATA : WORD_DATA, dst_r, dst, dstw);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size < 3 || reg_size > sljit_max_vector_length)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = VAND_VV;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = VOR_VV;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = VXOR_VV;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tins = VRGATHER_VV;\n\t\telem_size = 0;\n\t\tbreak;\n\t}\n\n\tif (elem_size > 3)\n\t\telem_size = 3;\n\n\tFAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size));\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src2, src2w));\n\t\tsrc2 = TMP_VREG1;\n\t}\n\n\tif (SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE)\n\t\treturn push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src1_vreg) | VRS2(src2));\n\n\tif (dst_vreg == src2) {\n\t\tFAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src2)));\n\t\tsrc2 = TMP_VREG1;\n\t}\n\n\tif (dst_vreg == src1_vreg) {\n\t\tFAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG2) | VRS1(src1_vreg)));\n\t\tsrc1_vreg = TMP_VREG2;\n\t}\n\n\treturn push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src2) | VRS2(src1_vreg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_s32 dst_r;\n\tsljit_s32 mem_flags = WORD_DATA;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tif (init_value & 0x100)\n\t\t\tinit_value |= 0xf00;\n\t\telse\n\t\t\tinit_value &= 0xff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | IMM_I(init_value)));\n\t\tmem_flags = BYTE_DATA;\n\t\tbreak;\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase SLJIT_MOV32:\n\t\tmem_flags = INT_DATA;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_S32:\n\t\tif ((init_value & 0x800) != 0)\n\t\t\tinit_value ^= ~(sljit_sw)0xfff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(init_value & ~(sljit_sw)0xfff)));\n\t\tPTR_FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(init_value)));\n\t\tbreak;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tdefault:\n\t\tPTR_FAIL_IF(emit_const(compiler, dst_r, init_value, ADDI | RD(dst_r)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw));\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_s32 dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = TMP_REG1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, dst, dstw));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\tPTR_FAIL_IF(push_inst16(compiler, (sljit_u16)target_r));\n\tcompiler->size += JUMP_MAX_SIZE - 1;\n\n\tif (op == SLJIT_ADD_ABS_ADDR) {\n\t\tif (RISCV_HAS_COMPRESSED(200))\n\t\t\tPTR_FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst_r) | C_RS2(TMP_REG1)));\n\t\telse\n\t\t\tPTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RS1(dst_r) | RS2(TMP_REG1)));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tinst = (sljit_u16*)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0x707f) == ADDI);\n\n\t\tif (new_constant & 0x100)\n\t\t\tnew_constant |= 0xf00;\n\t\telse\n\t\t\tnew_constant &= 0xff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[1] = (sljit_u16)(new_constant << 4) | (inst[1] & 0xf);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n\n#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tinst = (sljit_u16*)addr;\n\t\tSLJIT_ASSERT((inst[0] & 0x7f) == LUI && (inst[2] & 0x707f) == XORI);\n\n\t\tif ((new_constant & 0x800) != 0)\n\t\t\tnew_constant ^= ~(sljit_sw)0xfff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);\n\t\tinst[0] = (sljit_u16)((inst[0] & 0xfff) | (new_constant & 0xf000));\n\t\tinst[1] = (sljit_u16)(new_constant >> 16);\n\t\tinst[3] = (sljit_u16)(new_constant << 4) | (inst[3] & 0xf);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);\n\t\tinst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 4);\n\t\treturn;\n#endif /* SLJIT_CONFIG_RISCV_64 */\n\n\tdefault:\n\t\tsljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);\n\t\treturn;\n\t}\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <sys/auxv.h>\n\n#ifdef __ARCH__\n#define ENABLE_STATIC_FACILITY_DETECTION 1\n#else\n#define ENABLE_STATIC_FACILITY_DETECTION 0\n#endif\n#define ENABLE_DYNAMIC_FACILITY_DETECTION 1\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\treturn \"s390x\" SLJIT_CPUINFO;\n}\n\n/* Instructions are stored as 64 bit values regardless their size. */\ntypedef sljit_uw sljit_ins;\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {\n\t0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1, 14\n};\n\n/* there are also a[2-15] available, but they are slower to access and\n * their use is limited as mundaym explained:\n *   https://github.com/zherczeg/sljit/pull/91#discussion_r486895689\n */\n\n/* General Purpose Registers [0-15]. */\ntypedef sljit_uw sljit_gpr;\n\n/*\n * WARNING\n * the following code is non standard and should be improved for\n * consistency, but doesn't use SLJIT_NUMBER_OF_REGISTERS based\n * registers because r0 and r1 are the ABI recommended volatiles.\n * there is a gpr() function that maps sljit to physical register numbers\n * that should be used instead of the usual index into reg_map[] and\n * will be retired ASAP (TODO: carenas)\n */\n\nstatic const sljit_gpr r0 = 0;\t\t/* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */\nstatic const sljit_gpr r1 = 1;\t\t/* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */\nstatic const sljit_gpr r2 = 2;\t\t/* reg_map[1]: 1st argument */\nstatic const sljit_gpr r3 = 3;\t\t/* reg_map[2]: 2nd argument */\nstatic const sljit_gpr r4 = 4;\t\t/* reg_map[3]: 3rd argument */\nstatic const sljit_gpr r5 = 5;\t\t/* reg_map[4]: 4th argument */\nstatic const sljit_gpr r6 = 6;\t\t/* reg_map[5]: 5th argument; 1st saved register */\nstatic const sljit_gpr r7 = 7;\t\t/* reg_map[6] */\nstatic const sljit_gpr r8 = 8;\t\t/* reg_map[7] */\nstatic const sljit_gpr r9 = 9;\t\t/* reg_map[8] */\nstatic const sljit_gpr r10 = 10;\t/* reg_map[9] */\nstatic const sljit_gpr r11 = 11;\t/* reg_map[10] */\nstatic const sljit_gpr r12 = 12;\t/* reg_map[11]: GOT */\nstatic const sljit_gpr r13 = 13;\t/* reg_map[12]: Literal Pool pointer */\nstatic const sljit_gpr r14 = 14;\t/* reg_map[0]: return address */\nstatic const sljit_gpr r15 = 15;\t/* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */\n\n/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */\n/* TODO(carenas): r12 might conflict in PIC code, reserve? */\n/* TODO(carenas): r13 is usually pointed to \"pool\" per ABI, using a tmp\n *                like we do know might be faster though, reserve?\n */\n\n/* TODO(carenas): should be named TMP_REG[1-2] for consistency */\n#define tmp0\tr0\n#define tmp1\tr1\n\n/* Link register. */\nstatic const sljit_gpr link_r = 14;     /* r14 */\n\n#define TMP_FREG1\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {\n\t0, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8, 1\n};\n\n#define R0A(r) (r)\n#define R4A(r) ((r) << 4)\n#define R8A(r) ((r) << 8)\n#define R12A(r) ((r) << 12)\n#define R16A(r) ((r) << 16)\n#define R20A(r) ((r) << 20)\n#define R28A(r) ((r) << 28)\n#define R32A(r) ((r) << 32)\n#define R36A(r) ((r) << 36)\n\n#define R0(r) ((sljit_ins)reg_map[r])\n\n#define F0(r) ((sljit_ins)freg_map[r])\n#define F4(r) (R4A((sljit_ins)freg_map[r]))\n#define F12(r) (R12A((sljit_ins)freg_map[r]))\n#define F20(r) (R20A((sljit_ins)freg_map[r]))\n#define F28(r) (R28A((sljit_ins)freg_map[r]))\n#define F32(r) (R32A((sljit_ins)freg_map[r]))\n#define F36(r) (R36A((sljit_ins)freg_map[r]))\n\n/* Convert SLJIT register to hardware register. */\nstatic SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)\n{\n\tSLJIT_ASSERT(r >= 0 && r < (sljit_s32)(sizeof(reg_map) / sizeof(reg_map[0])));\n\treturn reg_map[r];\n}\n\nstatic sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)\n{\n\tsljit_ins *ibuf = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));\n\tFAIL_IF(!ibuf);\n\t*ibuf = ins;\n\n\tSLJIT_ASSERT(ins <= 0xffffffffffffL);\n\n\tcompiler->size++;\n\tif (ins & 0xffff00000000L)\n\t\tcompiler->size++;\n\n\tif (ins & 0xffffffff0000L)\n\t\tcompiler->size++;\n\n\treturn SLJIT_SUCCESS;\n}\n\n#define SLJIT_ADD_SUB_NO_COMPARE(status_flags_state) \\\n\t(((status_flags_state) & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) \\\n\t\t&& !((status_flags_state) & SLJIT_CURRENT_FLAGS_COMPARE))\n\n/* Map the given type to a 4-bit condition code mask. */\nstatic SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 type) {\n\tconst sljit_u8 cc0 = 1 << 3; /* equal {,to zero} */\n\tconst sljit_u8 cc1 = 1 << 2; /* less than {,zero} */\n\tconst sljit_u8 cc2 = 1 << 1; /* greater than {,zero} */\n\tconst sljit_u8 cc3 = 1 << 0; /* {overflow,NaN} */\n\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\t\tif (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {\n\t\t\tsljit_s32 flag_type = GET_FLAG_TYPE(compiler->status_flags_state);\n\t\t\tif (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_SIG_LESS_EQUAL)\n\t\t\t\treturn cc0;\n\t\t\tif (flag_type == SLJIT_OVERFLOW)\n\t\t\t\treturn (cc0 | cc3);\n\t\t\treturn (cc0 | cc2);\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_ORDERED_EQUAL:\n\t\treturn cc0;\n\n\tcase SLJIT_NOT_EQUAL:\n\t\tif (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {\n\t\t\tsljit_s32 flag_type = GET_FLAG_TYPE(compiler->status_flags_state);\n\t\t\tif (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_SIG_LESS_EQUAL)\n\t\t\t\treturn (cc1 | cc2 | cc3);\n\t\t\tif (flag_type == SLJIT_OVERFLOW)\n\t\t\t\treturn (cc1 | cc2);\n\t\t\treturn (cc1 | cc3);\n\t\t}\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\treturn (cc1 | cc2 | cc3);\n\n\tcase SLJIT_LESS:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\t\treturn cc1;\n\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\t\treturn (cc0 | cc2 | cc3);\n\n\tcase SLJIT_GREATER:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_COMPARE)\n\t\t\treturn cc2;\n\t\treturn cc3;\n\n\tcase SLJIT_LESS_EQUAL:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_COMPARE)\n\t\t\treturn (cc0 | cc1);\n\t\treturn (cc0 | cc1 | cc2);\n\n\tcase SLJIT_SIG_LESS:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_ORDERED_LESS:\n\t\treturn cc1;\n\n\tcase SLJIT_NOT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)\n\t\t\treturn (cc2 | cc3);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_SIG_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn (cc0 | cc1);\n\n\tcase SLJIT_CARRY:\n\t\tif (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)\n\t\t\treturn (cc0 | cc1);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_SIG_GREATER:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\t/* Overflow is considered greater, see SLJIT_SUB. */\n\t\treturn cc2 | cc3;\n\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\treturn (cc0 | cc2 | cc3);\n\n\tcase SLJIT_OVERFLOW:\n\t\tif (compiler->status_flags_state & SLJIT_SET_Z)\n\t\t\treturn (cc2 | cc3);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_UNORDERED:\n\t\treturn cc3;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\tif (compiler->status_flags_state & SLJIT_SET_Z)\n\t\t\treturn (cc0 | cc1);\n\t\tSLJIT_FALLTHROUGH\n\n\tcase SLJIT_ORDERED:\n\t\treturn (cc0 | cc1 | cc2);\n\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn (cc1 | cc2);\n\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_GREATER:\n\t\treturn cc2;\n\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\t\treturn (cc0 | cc2);\n\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn (cc0 | cc1 | cc3);\n\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn (cc0 | cc3);\n\n\tcase SLJIT_UNORDERED_OR_LESS:\n\t\treturn (cc1 | cc3);\n\t}\n\n\tSLJIT_UNREACHABLE();\n\treturn (sljit_u8)-1;\n}\n\n/* Facility to bit index mappings.\n   Note: some facilities share the same bit index. */\ntypedef sljit_uw facility_bit;\n#define STORE_FACILITY_LIST_EXTENDED_FACILITY 7\n#define FAST_LONG_DISPLACEMENT_FACILITY 19\n#define EXTENDED_IMMEDIATE_FACILITY 21\n#define GENERAL_INSTRUCTION_EXTENSION_FACILITY 34\n#define DISTINCT_OPERAND_FACILITY 45\n#define HIGH_WORD_FACILITY 45\n#define POPULATION_COUNT_FACILITY 45\n#define LOAD_STORE_ON_CONDITION_1_FACILITY 45\n#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY 49\n#define LOAD_STORE_ON_CONDITION_2_FACILITY 53\n#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY 58\n#define VECTOR_FACILITY 129\n#define VECTOR_ENHANCEMENTS_1_FACILITY 135\n\n/* Report whether a facility is known to be present due to the compiler\n   settings. This function should always be compiled to a constant\n   value given a constant argument. */\nstatic SLJIT_INLINE int have_facility_static(facility_bit x)\n{\n#if ENABLE_STATIC_FACILITY_DETECTION\n\tswitch (x) {\n\tcase FAST_LONG_DISPLACEMENT_FACILITY:\n\t\treturn (__ARCH__ >=  6 /* z990 */);\n\tcase EXTENDED_IMMEDIATE_FACILITY:\n\tcase STORE_FACILITY_LIST_EXTENDED_FACILITY:\n\t\treturn (__ARCH__ >=  7 /* z9-109 */);\n\tcase GENERAL_INSTRUCTION_EXTENSION_FACILITY:\n\t\treturn (__ARCH__ >=  8 /* z10 */);\n\tcase DISTINCT_OPERAND_FACILITY:\n\t\treturn (__ARCH__ >=  9 /* z196 */);\n\tcase MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY:\n\t\treturn (__ARCH__ >= 10 /* zEC12 */);\n\tcase LOAD_STORE_ON_CONDITION_2_FACILITY:\n\tcase VECTOR_FACILITY:\n\t\treturn (__ARCH__ >= 11 /* z13 */);\n\tcase MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY:\n\tcase VECTOR_ENHANCEMENTS_1_FACILITY:\n\t\treturn (__ARCH__ >= 12 /* z14 */);\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t}\n#endif\n\treturn 0;\n}\n\nstatic SLJIT_INLINE unsigned long get_hwcap(void)\n{\n\tstatic unsigned long hwcap = 0;\n\tif (SLJIT_UNLIKELY(!hwcap)) {\n\t\thwcap = getauxval(AT_HWCAP);\n\t\tSLJIT_ASSERT(hwcap != 0);\n\t}\n\treturn hwcap;\n}\n\nstatic SLJIT_INLINE int have_stfle(void)\n{\n\tif (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY))\n\t\treturn 1;\n\n\treturn (get_hwcap() & HWCAP_S390_STFLE);\n}\n\n/* Report whether the given facility is available. This function always\n   performs a runtime check. */\nstatic int have_facility_dynamic(facility_bit x)\n{\n#if ENABLE_DYNAMIC_FACILITY_DETECTION\n\tstatic struct {\n\t\tsljit_uw bits[4];\n\t} cpu_features;\n\tsize_t size = sizeof(cpu_features);\n\tconst sljit_uw word_index = x >> 6;\n\tconst sljit_uw bit_index = ((1UL << 63) >> (x & 63));\n\n\tSLJIT_ASSERT(x < size * 8);\n\tif (SLJIT_UNLIKELY(!have_stfle()))\n\t\treturn 0;\n\n\tif (SLJIT_UNLIKELY(cpu_features.bits[0] == 0)) {\n\t\t__asm__ __volatile__ (\n\t\t\t\"lgr   %%r0, %0;\"\n\t\t\t\"stfle 0(%1);\"\n\t\t\t/* outputs  */:\n\t\t\t/* inputs   */: \"d\" ((size / 8) - 1), \"a\" (&cpu_features)\n\t\t\t/* clobbers */: \"r0\", \"cc\", \"memory\"\n\t\t);\n\t\tSLJIT_ASSERT(cpu_features.bits[0] != 0);\n\t}\n\treturn (cpu_features.bits[word_index] & bit_index) != 0;\n#else\n\treturn 0;\n#endif\n}\n\n#define HAVE_FACILITY(name, bit) \\\nstatic SLJIT_INLINE int name() \\\n{ \\\n\tstatic int have = -1; \\\n\t/* Static check first. May allow the function to be optimized away. */ \\\n\tif (have_facility_static(bit)) \\\n\t\thave = 1; \\\n\telse if (SLJIT_UNLIKELY(have < 0)) \\\n\t\thave = have_facility_dynamic(bit) ? 1 : 0; \\\n\\\n\treturn have; \\\n}\n\nHAVE_FACILITY(have_eimm,    EXTENDED_IMMEDIATE_FACILITY)\nHAVE_FACILITY(have_ldisp,   FAST_LONG_DISPLACEMENT_FACILITY)\nHAVE_FACILITY(have_genext,  GENERAL_INSTRUCTION_EXTENSION_FACILITY)\nHAVE_FACILITY(have_lscond1, LOAD_STORE_ON_CONDITION_1_FACILITY)\nHAVE_FACILITY(have_lscond2, LOAD_STORE_ON_CONDITION_2_FACILITY)\nHAVE_FACILITY(have_misc2,   MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY)\n#undef HAVE_FACILITY\n\n#define is_u12(d)\t(0 <= (d) && (d) <= 0x00000fffL)\n#define is_u32(d)\t(0 <= (d) && (d) <= 0xffffffffL)\n\n#define CHECK_SIGNED(v, bitlen) \\\n\t((v) >= -(1 << ((bitlen) - 1)) && (v) < (1 << ((bitlen) - 1)))\n\n#define is_s8(d)\t((sljit_sw)(d) == (sljit_s8)(d))\n#define is_s16(d)\t((sljit_sw)(d) == (sljit_s16)(d))\n#define is_s20(d)\tCHECK_SIGNED((d), 20)\n#define is_s32(d)\t((sljit_sw)(d) == (sljit_s32)(d))\n\nstatic SLJIT_INLINE sljit_ins disp_s20(sljit_s32 d)\n{\n\tsljit_uw dh, dl;\n\n\tSLJIT_ASSERT(is_s20(d));\n\n\tdh = (d >> 12) & 0xff;\n\tdl = ((sljit_uw)d << 8) & 0xfff00;\n\treturn (dh | dl) << 8;\n}\n\n/* TODO(carenas): variadic macro is not strictly needed */\n#define SLJIT_S390X_INSTRUCTION(op, ...) \\\nstatic SLJIT_INLINE sljit_ins op(__VA_ARGS__)\n\n/* RR form instructions. */\n#define SLJIT_S390X_RR(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \\\n{ \\\n\treturn (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \\\n}\n\n/* AND */\nSLJIT_S390X_RR(nr,   0x1400)\n\n/* BRANCH AND SAVE */\nSLJIT_S390X_RR(basr, 0x0d00)\n\n/* BRANCH ON CONDITION */\nSLJIT_S390X_RR(bcr,  0x0700) /* TODO(mundaym): type for mask? */\n\n/* DIVIDE */\nSLJIT_S390X_RR(dr,   0x1d00)\n\n/* EXCLUSIVE OR */\nSLJIT_S390X_RR(xr,   0x1700)\n\n/* LOAD */\nSLJIT_S390X_RR(lr,   0x1800)\n\n/* LOAD COMPLEMENT */\nSLJIT_S390X_RR(lcr,  0x1300)\n\n/* OR */\nSLJIT_S390X_RR(or,   0x1600)\n\n#undef SLJIT_S390X_RR\n\n/* RRE form instructions */\n#define SLJIT_S390X_RRE(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \\\n{ \\\n\treturn (pattern) | R4A(dst) | R0A(src); \\\n}\n\n/* AND */\nSLJIT_S390X_RRE(ngr,   0xb9800000)\n\n/* DIVIDE LOGICAL */\nSLJIT_S390X_RRE(dlr,   0xb9970000)\nSLJIT_S390X_RRE(dlgr,  0xb9870000)\n\n/* DIVIDE SINGLE */\nSLJIT_S390X_RRE(dsgr,  0xb90d0000)\n\n/* EXCLUSIVE OR */\nSLJIT_S390X_RRE(xgr,   0xb9820000)\n\n/* LOAD */\nSLJIT_S390X_RRE(lgr,   0xb9040000)\nSLJIT_S390X_RRE(lgfr,  0xb9140000)\n\n/* LOAD BYTE */\nSLJIT_S390X_RRE(lbr,   0xb9260000)\nSLJIT_S390X_RRE(lgbr,  0xb9060000)\n\n/* LOAD COMPLEMENT */\nSLJIT_S390X_RRE(lcgr,  0xb9030000)\n\n/* LOAD HALFWORD */\nSLJIT_S390X_RRE(lhr,   0xb9270000)\nSLJIT_S390X_RRE(lghr,  0xb9070000)\n\n/* LOAD LOGICAL */\nSLJIT_S390X_RRE(llgfr, 0xb9160000)\n\n/* LOAD LOGICAL CHARACTER */\nSLJIT_S390X_RRE(llcr,  0xb9940000)\nSLJIT_S390X_RRE(llgcr, 0xb9840000)\n\n/* LOAD LOGICAL HALFWORD */\nSLJIT_S390X_RRE(llhr,  0xb9950000)\nSLJIT_S390X_RRE(llghr, 0xb9850000)\n\n/* MULTIPLY LOGICAL */\nSLJIT_S390X_RRE(mlgr,  0xb9860000)\n\n/* MULTIPLY SINGLE */\nSLJIT_S390X_RRE(msgfr, 0xb91c0000)\n\n/* OR */\nSLJIT_S390X_RRE(ogr,   0xb9810000)\n\n/* SUBTRACT */\nSLJIT_S390X_RRE(sgr,   0xb9090000)\n\n#undef SLJIT_S390X_RRE\n\n/* RI-a form instructions */\n#define SLJIT_S390X_RIA(name, pattern, imm_type) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \\\n{ \\\n\treturn (pattern) | R20A(reg) | (imm & 0xffff); \\\n}\n\n/* ADD HALFWORD IMMEDIATE */\nSLJIT_S390X_RIA(aghi,  0xa70b0000, sljit_s16)\n\n/* LOAD HALFWORD IMMEDIATE */\nSLJIT_S390X_RIA(lhi,   0xa7080000, sljit_s16)\nSLJIT_S390X_RIA(lghi,  0xa7090000, sljit_s16)\n\n/* LOAD LOGICAL IMMEDIATE */\nSLJIT_S390X_RIA(llihh, 0xa50c0000, sljit_u16)\nSLJIT_S390X_RIA(llihl, 0xa50d0000, sljit_u16)\nSLJIT_S390X_RIA(llilh, 0xa50e0000, sljit_u16)\nSLJIT_S390X_RIA(llill, 0xa50f0000, sljit_u16)\n\n/* MULTIPLY HALFWORD IMMEDIATE */\nSLJIT_S390X_RIA(mhi,   0xa70c0000, sljit_s16)\nSLJIT_S390X_RIA(mghi,  0xa70d0000, sljit_s16)\n\n/* OR IMMEDIATE */\nSLJIT_S390X_RIA(oilh,  0xa50a0000, sljit_u16)\n\n#undef SLJIT_S390X_RIA\n\n/* RIL-a form instructions (requires extended immediate facility) */\n#define SLJIT_S390X_RILA(name, pattern, imm_type) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \\\n{ \\\n\tSLJIT_ASSERT(have_eimm()); \\\n\treturn (pattern) | R36A(reg) | ((sljit_ins)imm & 0xffffffffu); \\\n}\n\n/* ADD IMMEDIATE */\nSLJIT_S390X_RILA(agfi,  0xc20800000000, sljit_s32)\n\n/* ADD IMMEDIATE HIGH */\nSLJIT_S390X_RILA(aih,   0xcc0800000000, sljit_s32) /* TODO(mundaym): high-word facility? */\n\n/* AND IMMEDIATE */\nSLJIT_S390X_RILA(nihf,  0xc00a00000000, sljit_u32)\n\n/* EXCLUSIVE OR IMMEDIATE */\nSLJIT_S390X_RILA(xilf,  0xc00700000000, sljit_u32)\n\n/* INSERT IMMEDIATE */\nSLJIT_S390X_RILA(iihf,  0xc00800000000, sljit_u32)\nSLJIT_S390X_RILA(iilf,  0xc00900000000, sljit_u32)\n\n/* LOAD IMMEDIATE */\nSLJIT_S390X_RILA(lgfi,  0xc00100000000, sljit_s32)\n\n/* LOAD LOGICAL IMMEDIATE */\nSLJIT_S390X_RILA(llihf, 0xc00e00000000, sljit_u32)\nSLJIT_S390X_RILA(llilf, 0xc00f00000000, sljit_u32)\n\n/* SUBTRACT LOGICAL IMMEDIATE */\nSLJIT_S390X_RILA(slfi,  0xc20500000000, sljit_u32)\n\n#undef SLJIT_S390X_RILA\n\n/* RX-a form instructions */\n#define SLJIT_S390X_RXA(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \\\n{ \\\n\tSLJIT_ASSERT((d & 0xfff) == d); \\\n\\\n\treturn (pattern) | R20A(r) | R16A(x) | R12A(b) | (sljit_ins)(d & 0xfff); \\\n}\n\n/* LOAD */\nSLJIT_S390X_RXA(l,   0x58000000)\n\n/* LOAD ADDRESS */\nSLJIT_S390X_RXA(la,  0x41000000)\n\n/* LOAD HALFWORD */\nSLJIT_S390X_RXA(lh,  0x48000000)\n\n/* MULTIPLY SINGLE */\nSLJIT_S390X_RXA(ms,  0x71000000)\n\n/* STORE */\nSLJIT_S390X_RXA(st,  0x50000000)\n\n/* STORE CHARACTER */\nSLJIT_S390X_RXA(stc, 0x42000000)\n\n/* STORE HALFWORD */\nSLJIT_S390X_RXA(sth, 0x40000000)\n\n#undef SLJIT_S390X_RXA\n\n/* RXY-a instructions */\n#define SLJIT_S390X_RXYA(name, pattern, cond) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \\\n{ \\\n\tSLJIT_ASSERT(cond); \\\n\\\n\treturn (pattern) | R36A(r) | R32A(x) | R28A(b) | disp_s20(d); \\\n}\n\n/* LOAD */\nSLJIT_S390X_RXYA(ly,    0xe30000000058, have_ldisp())\nSLJIT_S390X_RXYA(lg,    0xe30000000004, 1)\nSLJIT_S390X_RXYA(lgf,   0xe30000000014, 1)\n\n/* LOAD BYTE */\nSLJIT_S390X_RXYA(lb,    0xe30000000076, have_ldisp())\nSLJIT_S390X_RXYA(lgb,   0xe30000000077, have_ldisp())\n\n/* LOAD HALFWORD */\nSLJIT_S390X_RXYA(lhy,   0xe30000000078, have_ldisp())\nSLJIT_S390X_RXYA(lgh,   0xe30000000015, 1)\n\n/* LOAD LOGICAL */\nSLJIT_S390X_RXYA(llgf,  0xe30000000016, 1)\n\n/* LOAD LOGICAL CHARACTER */\nSLJIT_S390X_RXYA(llc,   0xe30000000094, have_eimm())\nSLJIT_S390X_RXYA(llgc,  0xe30000000090, 1)\n\n/* LOAD LOGICAL HALFWORD */\nSLJIT_S390X_RXYA(llh,   0xe30000000095, have_eimm())\nSLJIT_S390X_RXYA(llgh,  0xe30000000091, 1)\n\n/* MULTIPLY SINGLE */\nSLJIT_S390X_RXYA(msy,   0xe30000000051, have_ldisp())\nSLJIT_S390X_RXYA(msg,   0xe3000000000c, 1)\n\n/* STORE */\nSLJIT_S390X_RXYA(sty,   0xe30000000050, have_ldisp())\nSLJIT_S390X_RXYA(stg,   0xe30000000024, 1)\n\n/* STORE CHARACTER */\nSLJIT_S390X_RXYA(stcy,  0xe30000000072, have_ldisp())\n\n/* STORE HALFWORD */\nSLJIT_S390X_RXYA(sthy,  0xe30000000070, have_ldisp())\n\n#undef SLJIT_S390X_RXYA\n\n/* RSY-a instructions */\n#define SLJIT_S390X_RSYA(name, pattern, cond) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_s32 d, sljit_gpr b) \\\n{ \\\n\tSLJIT_ASSERT(cond); \\\n\\\n\treturn (pattern) | R36A(dst) | R32A(src) | R28A(b) | disp_s20(d); \\\n}\n\n/* LOAD MULTIPLE */\nSLJIT_S390X_RSYA(lmg,   0xeb0000000004, 1)\n\n/* SHIFT LEFT LOGICAL */\nSLJIT_S390X_RSYA(sllg,  0xeb000000000d, 1)\n\n/* SHIFT RIGHT SINGLE */\nSLJIT_S390X_RSYA(srag,  0xeb000000000a, 1)\n\n/* STORE MULTIPLE */\nSLJIT_S390X_RSYA(stmg,  0xeb0000000024, 1)\n\n#undef SLJIT_S390X_RSYA\n\n/* RIE-f instructions (require general-instructions-extension facility) */\n#define SLJIT_S390X_RIEF(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) \\\n{ \\\n\tsljit_ins i3, i4, i5; \\\n\\\n\tSLJIT_ASSERT(have_genext()); \\\n\ti3 = (sljit_ins)start << 24; \\\n\ti4 = (sljit_ins)end << 16; \\\n\ti5 = (sljit_ins)rot << 8; \\\n\\\n\treturn (pattern) | R36A(dst & 0xf) | R32A(src & 0xf) | i3 | i4 | i5; \\\n}\n\n/* ROTATE THEN AND SELECTED BITS */\n/* SLJIT_S390X_RIEF(rnsbg,  0xec0000000054) */\n\n/* ROTATE THEN EXCLUSIVE OR SELECTED BITS */\n/* SLJIT_S390X_RIEF(rxsbg,  0xec0000000057) */\n\n/* ROTATE THEN OR SELECTED BITS */\nSLJIT_S390X_RIEF(rosbg,  0xec0000000056)\n\n/* ROTATE THEN INSERT SELECTED BITS */\n/* SLJIT_S390X_RIEF(risbg,  0xec0000000055) */\n/* SLJIT_S390X_RIEF(risbgn, 0xec0000000059) */\n\n/* ROTATE THEN INSERT SELECTED BITS HIGH */\nSLJIT_S390X_RIEF(risbhg, 0xec000000005d)\n\n/* ROTATE THEN INSERT SELECTED BITS LOW */\n/* SLJIT_S390X_RIEF(risblg, 0xec0000000051) */\n\n#undef SLJIT_S390X_RIEF\n\n/* RRF-c instructions (require load/store-on-condition 1 facility) */\n#define SLJIT_S390X_RRFC(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_uw mask) \\\n{ \\\n\tsljit_ins m3; \\\n\\\n\tSLJIT_ASSERT(have_lscond1()); \\\n\tm3 = (sljit_ins)(mask & 0xf) << 12; \\\n\\\n\treturn (pattern) | m3 | R4A(dst) | R0A(src); \\\n}\n\n/* LOAD HALFWORD IMMEDIATE ON CONDITION */\nSLJIT_S390X_RRFC(locr,  0xb9f20000)\nSLJIT_S390X_RRFC(locgr, 0xb9e20000)\n\n#undef SLJIT_S390X_RRFC\n\n/* RIE-g instructions (require load/store-on-condition 2 facility) */\n#define SLJIT_S390X_RIEG(name, pattern) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw imm, sljit_uw mask) \\\n{ \\\n\tsljit_ins m3, i2; \\\n\\\n\tSLJIT_ASSERT(have_lscond2()); \\\n\tm3 = (sljit_ins)(mask & 0xf) << 32; \\\n\ti2 = (sljit_ins)(imm & 0xffffL) << 16; \\\n\\\n\treturn (pattern) | R36A(reg) | m3 | i2; \\\n}\n\n/* LOAD HALFWORD IMMEDIATE ON CONDITION */\nSLJIT_S390X_RIEG(lochi,  0xec0000000042)\nSLJIT_S390X_RIEG(locghi, 0xec0000000046)\n\n#undef SLJIT_S390X_RIEG\n\n#define SLJIT_S390X_RILB(name, pattern, cond) \\\nSLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw ri) \\\n{ \\\n\tSLJIT_ASSERT(cond); \\\n\\\n\treturn (pattern) | R36A(reg) | (sljit_ins)(ri & 0xffffffff); \\\n}\n\n/* BRANCH RELATIVE AND SAVE LONG */\nSLJIT_S390X_RILB(brasl, 0xc00500000000, 1)\n\n/* LOAD ADDRESS RELATIVE LONG */\nSLJIT_S390X_RILB(larl,  0xc00000000000, 1)\n\n/* LOAD RELATIVE LONG */\nSLJIT_S390X_RILB(lgrl,  0xc40800000000, have_genext())\n\n#undef SLJIT_S390X_RILB\n\nSLJIT_S390X_INSTRUCTION(br, sljit_gpr target)\n{\n\treturn 0x07f0 | target;\n}\n\nSLJIT_S390X_INSTRUCTION(brc, sljit_uw mask, sljit_sw target)\n{\n\tsljit_ins m1 = (sljit_ins)(mask & 0xf) << 20;\n\tsljit_ins ri2 = (sljit_ins)target & 0xffff;\n\treturn 0xa7040000L | m1 | ri2;\n}\n\nSLJIT_S390X_INSTRUCTION(brcl, sljit_uw mask, sljit_sw target)\n{\n\tsljit_ins m1 = (sljit_ins)(mask & 0xf) << 36;\n\tsljit_ins ri2 = (sljit_ins)target & 0xffffffff;\n\treturn 0xc00400000000L | m1 | ri2;\n}\n\nSLJIT_S390X_INSTRUCTION(flogr, sljit_gpr dst, sljit_gpr src)\n{\n\tSLJIT_ASSERT(have_eimm());\n\treturn 0xb9830000 | R8A(dst) | R0A(src);\n}\n\n/* INSERT PROGRAM MASK */\nSLJIT_S390X_INSTRUCTION(ipm, sljit_gpr dst)\n{\n\treturn 0xb2220000 | R4A(dst);\n}\n\n/* SET PROGRAM MASK */\nSLJIT_S390X_INSTRUCTION(spm, sljit_gpr dst)\n{\n\treturn 0x0400 | R4A(dst);\n}\n\n/* ROTATE THEN INSERT SELECTED BITS HIGH (ZERO) */\nSLJIT_S390X_INSTRUCTION(risbhgz, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot)\n{\n\treturn risbhg(dst, src, start, 0x8 | end, rot);\n}\n\n#undef SLJIT_S390X_INSTRUCTION\n\nstatic sljit_s32 update_zero_overflow(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr dst_r)\n{\n\t/* Condition codes: bits 18 and 19.\n\t   Transformation:\n\t     0 (zero and no overflow) : unchanged\n\t     1 (non-zero and no overflow) : unchanged\n\t     2 (zero and overflow) : decreased by 1\n\t     3 (non-zero and overflow) : decreased by 1 if non-zero */\n\tFAIL_IF(push_inst(compiler, brc(0xc, 2 + 2 + ((op & SLJIT_32) ? 1 : 2) + 2 + 3 + 1)));\n\tFAIL_IF(push_inst(compiler, ipm(tmp1)));\n\tFAIL_IF(push_inst(compiler, (op & SLJIT_32) ? or(dst_r, dst_r) : ogr(dst_r, dst_r)));\n\tFAIL_IF(push_inst(compiler, brc(0x8, 2 + 3)));\n\tFAIL_IF(push_inst(compiler, slfi(tmp1, 0x10000000)));\n\tFAIL_IF(push_inst(compiler, spm(tmp1)));\n\treturn SLJIT_SUCCESS;\n}\n\n/* load 64-bit immediate into register without clobbering flags */\nstatic sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr target, sljit_sw v)\n{\n\t/* 4 byte instructions */\n\tif (is_s16(v))\n\t\treturn push_inst(compiler, lghi(target, (sljit_s16)v));\n\n\tif (((sljit_uw)v & ~(sljit_uw)0x000000000000ffff) == 0)\n\t\treturn push_inst(compiler, llill(target, (sljit_u16)v));\n\n\tif (((sljit_uw)v & ~(sljit_uw)0x00000000ffff0000) == 0)\n\t\treturn push_inst(compiler, llilh(target, (sljit_u16)(v >> 16)));\n\n\tif (((sljit_uw)v & ~(sljit_uw)0x0000ffff00000000) == 0)\n\t\treturn push_inst(compiler, llihl(target, (sljit_u16)(v >> 32)));\n\n\tif (((sljit_uw)v & ~(sljit_uw)0xffff000000000000) == 0)\n\t\treturn push_inst(compiler, llihh(target, (sljit_u16)(v >> 48)));\n\n\tif (is_s32(v))\n\t\treturn push_inst(compiler, lgfi(target, (sljit_s32)v));\n\n\tif (((sljit_uw)v >> 32) == 0)\n\t\treturn push_inst(compiler, llilf(target, (sljit_u32)v));\n\n\tif (((sljit_uw)v << 32) == 0)\n\t\treturn push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32)));\n\n\tFAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v)));\n\treturn push_inst(compiler, iihf(target, (sljit_u32)(v >> 32)));\n}\n\nstruct addr {\n\tsljit_gpr base;\n\tsljit_gpr index;\n\tsljit_s32 offset;\n};\n\n/* transform memory operand into D(X,B) form with a signed 20-bit offset */\nstatic sljit_s32 make_addr_bxy(struct sljit_compiler *compiler,\n\tstruct addr *addr, sljit_s32 mem, sljit_sw off,\n\tsljit_gpr tmp /* clobbered, must not be r0 */)\n{\n\tsljit_gpr base = r0;\n\tsljit_gpr index = r0;\n\n\tSLJIT_ASSERT(tmp != r0);\n\tif (mem & REG_MASK)\n\t\tbase = gpr(mem & REG_MASK);\n\n\tif (mem & OFFS_REG_MASK) {\n\t\tindex = gpr(OFFS_REG(mem));\n\t\tif (off != 0) {\n\t\t\t/* shift and put the result into tmp */\n\t\t\tSLJIT_ASSERT(0 <= off && off < 64);\n\t\t\tFAIL_IF(push_inst(compiler, sllg(tmp, index, (sljit_s32)off, 0)));\n\t\t\tindex = tmp;\n\t\t\toff = 0; /* clear offset */\n\t\t}\n\t}\n\telse if (!is_s20(off)) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp, off));\n\t\tindex = tmp;\n\t\toff = 0; /* clear offset */\n\t}\n\taddr->base = base;\n\taddr->index = index;\n\taddr->offset = (sljit_s32)off;\n\treturn SLJIT_SUCCESS;\n}\n\n/* transform memory operand into D(X,B) form with an unsigned 12-bit offset */\nstatic sljit_s32 make_addr_bx(struct sljit_compiler *compiler,\n\tstruct addr *addr, sljit_s32 mem, sljit_sw off,\n\tsljit_gpr tmp /* clobbered, must not be r0 */)\n{\n\tsljit_gpr base = r0;\n\tsljit_gpr index = r0;\n\n\tSLJIT_ASSERT(tmp != r0);\n\tif (mem & REG_MASK)\n\t\tbase = gpr(mem & REG_MASK);\n\n\tif (mem & OFFS_REG_MASK) {\n\t\tindex = gpr(OFFS_REG(mem));\n\t\tif (off != 0) {\n\t\t\t/* shift and put the result into tmp */\n\t\t\tSLJIT_ASSERT(0 <= off && off < 64);\n\t\t\tFAIL_IF(push_inst(compiler, sllg(tmp, index, (sljit_s32)off, 0)));\n\t\t\tindex = tmp;\n\t\t\toff = 0; /* clear offset */\n\t\t}\n\t}\n\telse if (!is_u12(off)) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp, off));\n\t\tindex = tmp;\n\t\toff = 0; /* clear offset */\n\t}\n\taddr->base = base;\n\taddr->index = index;\n\taddr->offset = (sljit_s32)off;\n\treturn SLJIT_SUCCESS;\n}\n\n#define EVAL(op, r, addr) op(r, addr.offset, addr.index, addr.base)\n#define WHEN(cond, r, i1, i2, addr) \\\n\t(cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr)\n\n/* May clobber tmp1. */\nstatic sljit_s32 load_store_op(struct sljit_compiler *compiler, sljit_gpr reg,\n\t\tsljit_s32 mem, sljit_sw memw,\n\t\tsljit_s32 is_32bit, const sljit_ins* forms)\n{\n\tstruct addr addr;\n\n\tSLJIT_ASSERT(mem & SLJIT_MEM);\n\n\tif (is_32bit && ((mem & OFFS_REG_MASK) || is_u12(memw) || !is_s20(memw))) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, mem, memw, tmp1));\n\t\treturn push_inst(compiler, forms[0] | R20A(reg) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset);\n\t}\n\n\tFAIL_IF(make_addr_bxy(compiler, &addr, mem, memw, tmp1));\n\treturn push_inst(compiler, (is_32bit ? forms[1] : forms[2]) | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));\n}\n\nstatic const sljit_ins load_forms[3] = {\n\t0x58000000 /* l */,\n\t0xe30000000058 /* ly */,\n\t0xe30000000004 /* lg */\n};\n\nstatic const sljit_ins store_forms[3] = {\n\t0x50000000 /* st */,\n\t0xe30000000050 /* sty */,\n\t0xe30000000024 /* stg */\n};\n\nstatic const sljit_ins store_byte_forms[3] = {\n\t0x42000000 /* stc */,\n\t0xe30000000072 /* stcy */,\n\t0\n};\n\nstatic const sljit_ins load_halfword_forms[3] = {\n\t0x48000000 /* lh */,\n\t0xe30000000078 /* lhy */,\n\t0xe30000000015 /* lgh */\n};\n\n/* May clobber tmp1. */\nstatic SLJIT_INLINE sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r,\n\t\tsljit_s32 src, sljit_sw srcw,\n\t\tsljit_s32 is_32bit)\n{\n\treturn load_store_op(compiler, dst_r, src, srcw, is_32bit, load_forms);\n}\n\n/* May clobber tmp1. */\nstatic sljit_s32 load_unsigned_word(struct sljit_compiler *compiler, sljit_gpr dst_r,\n\t\tsljit_s32 src, sljit_sw srcw,\n\t\tsljit_s32 is_32bit)\n{\n\tstruct addr addr;\n\tsljit_ins ins;\n\n\tSLJIT_ASSERT(src & SLJIT_MEM);\n\n\tFAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));\n\n\tins = is_32bit ? 0xe30000000016 /* llgf */ : 0xe30000000004 /* lg */;\n\treturn push_inst(compiler, ins | R36A(dst_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));\n}\n\n/* May clobber tmp1. */\nstatic SLJIT_INLINE sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r,\n\t\tsljit_s32 dst, sljit_sw dstw,\n\t\tsljit_s32 is_32bit)\n{\n\treturn load_store_op(compiler, src_r, dst, dstw, is_32bit, store_forms);\n}\n\n/* May clobber tmp1. */\nstatic SLJIT_INLINE sljit_s32 store_byte(struct sljit_compiler *compiler, sljit_gpr src_r,\n\t\tsljit_s32 dst, sljit_sw dstw)\n{\n\treturn load_store_op(compiler, src_r, dst, dstw, 1, store_byte_forms);\n}\n\n#undef WHEN\n\nstatic sljit_s32 emit_move(struct sljit_compiler *compiler,\n\tsljit_gpr dst_r,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_gpr src_r;\n\n\tSLJIT_ASSERT(!FAST_IS_REG(src) || dst_r != gpr(src & REG_MASK));\n\n\tif (src == SLJIT_IMM)\n\t\treturn push_load_imm_inst(compiler, dst_r, srcw);\n\n\tif (src & SLJIT_MEM)\n\t\treturn load_word(compiler, dst_r, src, srcw, (compiler->mode & SLJIT_32) != 0);\n\n\tsrc_r = gpr(src & REG_MASK);\n\treturn push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, src_r) : lgr(dst_r, src_r));\n}\n\nstatic sljit_s32 emit_rr(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_gpr dst_r = tmp0;\n\tsljit_gpr src_r = tmp1;\n\tsljit_s32 needs_move = 1;\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = gpr(dst);\n\n\t\tif (dst == src1)\n\t\t\tneeds_move = 0;\n\t\telse if (dst == src2) {\n\t\t\tdst_r = tmp0;\n\t\t\tneeds_move = 2;\n\t\t}\n\t}\n\n\tif (needs_move)\n\t\tFAIL_IF(emit_move(compiler, dst_r, src1, src1w));\n\n\tif (FAST_IS_REG(src2))\n\t\tsrc_r = gpr(src2);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp1, src2, src2w));\n\n\tFAIL_IF(push_inst(compiler, ins | R4A(dst_r) | R0A(src_r)));\n\n\tif (needs_move != 2)\n\t\treturn SLJIT_SUCCESS;\n\n\tdst_r = gpr(dst & REG_MASK);\n\treturn push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, tmp0) : lgr(dst_r, tmp0));\n}\n\nstatic sljit_s32 emit_rr1(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w)\n{\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\tsljit_gpr src_r = tmp1;\n\n\tif (FAST_IS_REG(src1))\n\t\tsrc_r = gpr(src1);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp1, src1, src1w));\n\n\treturn push_inst(compiler, ins | R4A(dst_r) | R0A(src_r));\n}\n\nstatic sljit_s32 emit_rrf(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\tsljit_gpr src1_r = tmp0;\n\tsljit_gpr src2_r = tmp1;\n\n\tif (FAST_IS_REG(src1))\n\t\tsrc1_r = gpr(src1);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp0, src1, src1w));\n\n\tif (FAST_IS_REG(src2))\n\t\tsrc2_r = gpr(src2);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp1, src2, src2w));\n\n\treturn push_inst(compiler, ins | R4A(dst_r) | R0A(src1_r) | R12A(src2_r));\n}\n\ntypedef enum {\n\tRI_A,\n\tRIL_A,\n} emit_ril_type;\n\nstatic sljit_s32 emit_ri(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_sw src2w,\n\temit_ril_type type)\n{\n\tsljit_gpr dst_r = tmp0;\n\tsljit_s32 needs_move = 1;\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = gpr(dst);\n\n\t\tif (dst == src1)\n\t\t\tneeds_move = 0;\n\t}\n\n\tif (needs_move)\n\t\tFAIL_IF(emit_move(compiler, dst_r, src1, src1w));\n\n\tif (type == RIL_A)\n\t\treturn push_inst(compiler, ins | R36A(dst_r) | (src2w & 0xffffffff));\n\treturn push_inst(compiler, ins | R20A(dst_r) | (src2w & 0xffff));\n}\n\nstatic sljit_s32 emit_rie_d(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_sw src2w)\n{\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\tsljit_gpr src_r = tmp0;\n\n\tif (!FAST_IS_REG(src1))\n\t\tFAIL_IF(emit_move(compiler, tmp0, src1, src1w));\n\telse\n\t\tsrc_r = gpr(src1 & REG_MASK);\n\n\treturn push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | (sljit_ins)(src2w & 0xffff) << 16);\n}\n\ntypedef enum {\n\tRX_A,\n\tRXY_A,\n} emit_rx_type;\n\nstatic sljit_s32 emit_rx(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\temit_rx_type type)\n{\n\tsljit_gpr dst_r = tmp0;\n\tsljit_s32 needs_move = 1;\n\tsljit_gpr base, index;\n\n\tSLJIT_ASSERT(src2 & SLJIT_MEM);\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = gpr(dst);\n\n\t\tif (dst == src1)\n\t\t\tneeds_move = 0;\n\t\telse if (dst == (src2 & REG_MASK) || (dst == OFFS_REG(src2))) {\n\t\t\tdst_r = tmp0;\n\t\t\tneeds_move = 2;\n\t\t}\n\t}\n\n\tif (needs_move)\n\t\tFAIL_IF(emit_move(compiler, dst_r, src1, src1w));\n\n\tbase = gpr(src2 & REG_MASK);\n\tindex = tmp0;\n\n\tif (src2 & OFFS_REG_MASK) {\n\t\tindex = gpr(OFFS_REG(src2));\n\n\t\tif (src2w != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, sllg(tmp1, index, src2w & 0x3, 0)));\n\t\t\tsrc2w = 0;\n\t\t\tindex = tmp1;\n\t\t}\n\t} else if ((type == RX_A && !is_u12(src2w)) || (type == RXY_A && !is_s20(src2w))) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp1, src2w));\n\n\t\tif (src2 & REG_MASK)\n\t\t\tindex = tmp1;\n\t\telse\n\t\t\tbase = tmp1;\n\t\tsrc2w = 0;\n\t}\n\n\tif (type == RX_A)\n\t\tins |= R20A(dst_r) | R16A(index) | R12A(base) | (sljit_ins)src2w;\n\telse\n\t\tins |= R36A(dst_r) | R32A(index) | R28A(base) | disp_s20((sljit_s32)src2w);\n\n\tFAIL_IF(push_inst(compiler, ins));\n\n\tif (needs_move != 2)\n\t\treturn SLJIT_SUCCESS;\n\n\tdst_r = gpr(dst);\n\treturn push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, tmp0) : lgr(dst_r, tmp0));\n}\n\nstatic sljit_s32 emit_siy(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw srcw)\n{\n\tsljit_gpr dst_r = tmp1;\n\n\tSLJIT_ASSERT(dst & SLJIT_MEM);\n\n\tif (dst & OFFS_REG_MASK) {\n\t\tsljit_gpr index = tmp1;\n\n\t\tif ((dstw & 0x3) == 0)\n\t\t\tindex = gpr(OFFS_REG(dst));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, sllg(tmp1, index, dstw & 0x3, 0)));\n\n\t\tFAIL_IF(push_inst(compiler, la(tmp1, 0, dst_r, index)));\n\t\tdstw = 0;\n\t}\n\telse if (!is_s20(dstw)) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp1, dstw));\n\n\t\tif (dst & REG_MASK)\n\t\t\tFAIL_IF(push_inst(compiler, la(tmp1, 0, dst_r, tmp1)));\n\n\t\tdstw = 0;\n\t}\n\telse\n\t\tdst_r = gpr(dst & REG_MASK);\n\n\treturn push_inst(compiler, ins | ((sljit_ins)(srcw & 0xff) << 32) | R28A(dst_r) | disp_s20((sljit_s32)dstw));\n}\n\nstruct ins_forms {\n\tsljit_ins op_r;\n\tsljit_ins op_gr;\n\tsljit_ins op_rk;\n\tsljit_ins op_grk;\n\tsljit_ins op;\n\tsljit_ins op_y;\n\tsljit_ins op_g;\n};\n\nstatic sljit_s32 emit_commutative(struct sljit_compiler *compiler, const struct ins_forms *forms,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 mode = compiler->mode;\n\tsljit_ins ins, ins_k;\n\n\tif ((src1 | src2) & SLJIT_MEM) {\n\t\tsljit_ins ins12, ins20;\n\n\t\tif (mode & SLJIT_32) {\n\t\t\tins12 = forms->op;\n\t\t\tins20 = forms->op_y;\n\t\t}\n\t\telse {\n\t\t\tins12 = 0;\n\t\t\tins20 = forms->op_g;\n\t\t}\n\n\t\tif (ins12 && ins20) {\n\t\t\t/* Extra instructions needed for address computation can be executed independently. */\n\t\t\tif ((src2 & SLJIT_MEM) && (!(src1 & SLJIT_MEM)\n\t\t\t\t\t|| ((src1 & OFFS_REG_MASK) ? (src1w & 0x3) == 0 : is_s20(src1w)))) {\n\t\t\t\tif ((src2 & OFFS_REG_MASK) || is_u12(src2w) || !is_s20(src2w))\n\t\t\t\t\treturn emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);\n\n\t\t\t\treturn emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);\n\t\t\t}\n\n\t\t\tif (src1 & SLJIT_MEM) {\n\t\t\t\tif ((src1 & OFFS_REG_MASK) || is_u12(src1w) || !is_s20(src1w))\n\t\t\t\t\treturn emit_rx(compiler, ins12, dst, src2, src2w, src1, src1w, RX_A);\n\n\t\t\t\treturn emit_rx(compiler, ins20, dst, src2, src2w, src1, src1w, RXY_A);\n\t\t\t}\n\t\t}\n\t\telse if (ins12 || ins20) {\n\t\t\temit_rx_type rx_type;\n\n\t\t\tif (ins12) {\n\t\t\t\trx_type = RX_A;\n\t\t\t\tins = ins12;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trx_type = RXY_A;\n\t\t\t\tins = ins20;\n\t\t\t}\n\n\t\t\tif ((src2 & SLJIT_MEM) && (!(src1 & SLJIT_MEM)\n\t\t\t\t\t|| ((src1 & OFFS_REG_MASK) ? (src1w & 0x3) == 0 : (rx_type == RX_A ? is_u12(src1w) : is_s20(src1w)))))\n\t\t\t\treturn emit_rx(compiler, ins, dst, src1, src1w, src2, src2w, rx_type);\n\n\t\t\tif (src1 & SLJIT_MEM)\n\t\t\t\treturn emit_rx(compiler, ins, dst, src2, src2w, src1, src1w, rx_type);\n\t\t}\n\t}\n\n\tif (mode & SLJIT_32) {\n\t\tins = forms->op_r;\n\t\tins_k = forms->op_rk;\n\t}\n\telse {\n\t\tins = forms->op_gr;\n\t\tins_k = forms->op_grk;\n\t}\n\n\tSLJIT_ASSERT(ins != 0 || ins_k != 0);\n\n\tif (ins && FAST_IS_REG(dst)) {\n\t\tif (dst == src1)\n\t\t\treturn emit_rr(compiler, ins, dst, src1, src1w, src2, src2w);\n\n\t\tif (dst == src2)\n\t\t\treturn emit_rr(compiler, ins, dst, src2, src2w, src1, src1w);\n\t}\n\n\tif (ins_k == 0)\n\t\treturn emit_rr(compiler, ins, dst, src1, src1w, src2, src2w);\n\n\treturn emit_rrf(compiler, ins_k, dst, src1, src1w, src2, src2w);\n}\n\nstatic sljit_s32 emit_non_commutative(struct sljit_compiler *compiler, const struct ins_forms *forms,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 mode = compiler->mode;\n\tsljit_ins ins;\n\n\tif (src2 & SLJIT_MEM) {\n\t\tsljit_ins ins12, ins20;\n\n\t\tif (mode & SLJIT_32) {\n\t\t\tins12 = forms->op;\n\t\t\tins20 = forms->op_y;\n\t\t}\n\t\telse {\n\t\t\tins12 = 0;\n\t\t\tins20 = forms->op_g;\n\t\t}\n\n\t\tif (ins12 && ins20) {\n\t\t\tif ((src2 & OFFS_REG_MASK) || is_u12(src2w) || !is_s20(src2w))\n\t\t\t\treturn emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);\n\n\t\t\treturn emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);\n\t\t}\n\t\telse if (ins12)\n\t\t\treturn emit_rx(compiler, ins12, dst, src1, src1w, src2, src2w, RX_A);\n\t\telse if (ins20)\n\t\t\treturn emit_rx(compiler, ins20, dst, src1, src1w, src2, src2w, RXY_A);\n\t}\n\n\tins = (mode & SLJIT_32) ? forms->op_rk : forms->op_grk;\n\n\tif (ins == 0 || (FAST_IS_REG(dst) && dst == src1))\n\t\treturn emit_rr(compiler, (mode & SLJIT_32) ? forms->op_r : forms->op_gr, dst, src1, src1w, src2, src2w);\n\n\treturn emit_rrf(compiler, ins, dst, src1, src1w, src2, src2w);\n}\n\nstatic SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\treturn (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tsljit_sw executable_offset;\n\tsljit_uw ins_size = compiler->size << 1;\n\tsljit_uw pool_size = 0; /* literal pool */\n\tsljit_uw pad_size;\n\tsljit_uw half_count;\n\tSLJIT_NEXT_DEFINE_TYPES;\n\tstruct sljit_memory_fragment *buf;\n\tsljit_ins *buf_ptr;\n\tsljit_ins *buf_end;\n\tsljit_u16 *code;\n\tsljit_u16 *code_ptr;\n\tsljit_uw *pool, *pool_ptr;\n\tsljit_ins ins;\n\tsljit_sw source, offset;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\treverse_buf(compiler);\n\n\tjump = compiler->jumps;\n\twhile (jump != NULL) {\n\t\tif (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) {\n\t\t\t/* encoded: */\n\t\t\t/*   brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */\n\t\t\t/* replace with: */\n\t\t\t/*   lgrl %r1, <pool_addr> */\n\t\t\t/*   bras %r14, %r1 (or bcr <mask>, %r1) */\n\t\t\tif (((jump->flags & SLJIT_REWRITABLE_JUMP) || !is_s32(jump->u.target)))\n\t\t\t\tpool_size += sizeof(sljit_uw);\n\t\t\telse\n\t\t\t\tjump->flags |= PATCH_IMM32;\n\n\t\t\tif (!(jump->flags & JUMP_MOV_ADDR))\n\t\t\t\tins_size += 2;\n\t\t}\n\t\tjump = jump->next;\n\t}\n\n\t/* pad code size to 8 bytes so is accessible with half word offsets */\n\t/* the literal pool needs to be doubleword aligned */\n\tpad_size = ((ins_size + 7UL) & ~7UL) - ins_size;\n\tSLJIT_ASSERT(pad_size < 8UL);\n\n\t/* allocate target buffer */\n\tcode = (sljit_u16*)allocate_executable_memory(ins_size + pad_size + pool_size, options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\tcode_ptr = code;\n\n\t/* TODO(carenas): pool is optional, and the ABI recommends it to\n         *                be created before the function code, instead of\n         *                globally; if generated code is too big could\n         *                need offsets bigger than 32bit words and asser()\n         */\n\tpool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size);\n\tpool_ptr = pool;\n\tbuf = compiler->buf;\n\thalf_count = 0;\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\tSLJIT_NEXT_INIT_TYPES();\n\tSLJIT_GET_NEXT_MIN();\n\n\tdo {\n\t\tbuf_ptr = (sljit_ins*)buf->memory;\n\t\tbuf_end = buf_ptr + (buf->used_size >> 3);\n\t\tdo {\n\t\t\tins = *buf_ptr++;\n\n\t\t\tif (next_min_addr == half_count) {\n\t\t\t\tSLJIT_ASSERT(!label || label->size >= half_count);\n\t\t\t\tSLJIT_ASSERT(!jump || jump->addr >= half_count);\n\t\t\t\tSLJIT_ASSERT(!const_ || const_->addr >= half_count);\n\n\t\t\t\tif (next_min_addr == next_label_size) {\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t\t\t}\n\n\t\t\t\tif (next_min_addr == next_jump_addr) {\n\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n\n\t\t\t\t\tif (SLJIT_UNLIKELY(jump->flags & JUMP_MOV_ADDR)) {\n\t\t\t\t\t\tif (jump->flags & PATCH_IMM32) {\n\t\t\t\t\t\t\tSLJIT_ASSERT((jump->flags & JUMP_ADDR) && is_s32(jump->u.target));\n\t\t\t\t\t\t\tins = 0xc00100000000 /* lgfi */ | (ins & 0xf000000000);\n\t\t\t\t\t\t} else if (jump->flags & JUMP_ADDR) {\n\t\t\t\t\t\t\tsource = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\t\t\toffset = (sljit_sw)(jump->u.target - (sljit_uw)source);\n\n\t\t\t\t\t\t\tif ((offset & 0x1) != 0 || offset > 0xffffffffl || offset < -0x100000000l) {\n\t\t\t\t\t\t\t\tjump->addr = (sljit_uw)pool_ptr;\n\t\t\t\t\t\t\t\tjump->flags |= PATCH_POOL;\n\n\t\t\t\t\t\t\t\t/* store target into pool */\n\t\t\t\t\t\t\t\toffset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;\n\t\t\t\t\t\t\t\tpool_ptr++;\n\n\t\t\t\t\t\t\t\tSLJIT_ASSERT(!(offset & 1));\n\t\t\t\t\t\t\t\toffset >>= 1;\n\t\t\t\t\t\t\t\tSLJIT_ASSERT(is_s32(offset));\n\t\t\t\t\t\t\t\tins = 0xc40800000000 /* lgrl */ | (ins & 0xf000000000) | (sljit_ins)(offset & 0xffffffff);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) {\n\t\t\t\t\t\tsource = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\t\t\t\t\t\tif (jump->flags & PATCH_IMM32) {\n\t\t\t\t\t\t\tSLJIT_ASSERT((jump->flags & JUMP_ADDR) && is_s32(jump->u.target));\n\t\t\t\t\t\t\tcode_ptr[0] = (sljit_u16)(0xc001 /* lgfi */ | R4A(tmp1));\n\t\t\t\t\t\t\tcode_ptr += 3;\n\t\t\t\t\t\t} else if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\t\t\t\toffset = (sljit_sw)(jump->u.target - (sljit_uw)source);\n\n\t\t\t\t\t\t\tif ((offset & 0x1) != 0 || offset > 0xffffffffl || offset < -0x100000000l)\n\t\t\t\t\t\t\t\tjump->flags |= PATCH_POOL;\n\t\t\t\t\t\t} else\n\t\t\t\t\t\t\tjump->flags |= PATCH_POOL;\n\n\t\t\t\t\t\tif (jump->flags & PATCH_POOL) {\n\t\t\t\t\t\t\tjump->addr = (sljit_uw)pool_ptr;\n\n\t\t\t\t\t\t\t/* load address into tmp1 */\n\t\t\t\t\t\t\toffset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;\n\n\t\t\t\t\t\t\tSLJIT_ASSERT(!(offset & 1));\n\t\t\t\t\t\t\toffset >>= 1;\n\t\t\t\t\t\t\tSLJIT_ASSERT(is_s32(offset));\n\n\t\t\t\t\t\t\tcode_ptr[0] = (sljit_u16)(0xc408 /* lgrl */ | R4A(tmp1));\n\t\t\t\t\t\t\tcode_ptr[1] = (sljit_u16)(offset >> 16);\n\t\t\t\t\t\t\tcode_ptr[2] = (sljit_u16)offset;\n\t\t\t\t\t\t\tcode_ptr += 3;\n\t\t\t\t\t\t\tpool_ptr++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (jump->flags & (PATCH_POOL | PATCH_IMM32)) {\n\t\t\t\t\t\t\t/* branch to tmp1 */\n\t\t\t\t\t\t\tif (((ins >> 32) & 0xf) == 4) {\n\t\t\t\t\t\t\t\t/* brcl -> bcr */\n\t\t\t\t\t\t\t\tins = 0x0700 /* bcr */ | ((ins >> 32) & 0xf0) | R0A(tmp1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tSLJIT_ASSERT(((ins >> 32) & 0xf) == 5);\n\t\t\t\t\t\t\t\t/* brasl -> basr */\n\t\t\t\t\t\t\t\tins = 0x0d00 /* basr */ | ((ins >> 32) & 0xf0) | R0A(tmp1);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/* Adjust half_count. */\n\t\t\t\t\t\t\thalf_count += 2;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t\t\t\t} else if (next_min_addr == next_const_addr) {\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tnext_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);\n\t\t\t\t}\n\n\t\t\t\tSLJIT_GET_NEXT_MIN();\n\t\t\t}\n\n\t\t\tif (ins & 0xffff00000000L) {\n\t\t\t\t*code_ptr++ = (sljit_u16)(ins >> 32);\n\t\t\t\thalf_count++;\n\t\t\t}\n\n\t\t\tif (ins & 0xffffffff0000L) {\n\t\t\t\t*code_ptr++ = (sljit_u16)(ins >> 16);\n\t\t\t\thalf_count++;\n\t\t\t}\n\n\t\t\t*code_ptr++ = (sljit_u16)ins;\n\t\t\thalf_count++;\n\t\t} while (buf_ptr < buf_end);\n\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tif (next_label_size == half_count) {\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\tlabel = label->next;\n\t}\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr <= code + (ins_size >> 1));\n\tSLJIT_ASSERT((sljit_u8 *)pool_ptr <= (sljit_u8 *)pool + pool_size);\n\n\tjump = compiler->jumps;\n\twhile (jump != NULL) {\n\t\toffset = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);\n\n\t\tif (!(jump->flags & (PATCH_POOL | PATCH_IMM32))) {\n\t\t\tcode_ptr = (sljit_u16*)jump->addr;\n\t\t\toffset -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\t\t\t/* Offset must be halfword aligned. */\n\t\t\tSLJIT_ASSERT(!(offset & 1));\n\t\t\toffset >>= 1;\n\t\t\tSLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */\n\n\t\t\tcode_ptr[1] = (sljit_u16)(offset >> 16);\n\t\t\tcode_ptr[2] = (sljit_u16)offset;\n\t\t} else if (jump->flags & PATCH_POOL) {\n\t\t\t/* Store jump target into pool. */\n\t\t\t*(sljit_uw*)(jump->addr) = (sljit_uw)offset;\n\t\t} else {\n\t\t\tSLJIT_ASSERT(is_s32(offset));\n\t\t\tcode_ptr = (sljit_u16*)jump->addr;\n\t\t\tcode_ptr[1] = (sljit_u16)(offset >> 16);\n\t\t\tcode_ptr[2] = (sljit_u16)offset;\n\t\t}\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = ins_size;\n\tif (pool_size)\n\t\tcompiler->executable_size += (pad_size + pool_size);\n\n\tcode = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\tcode_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\tSLJIT_CACHE_FLUSH(code, code_ptr);\n\tSLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);\n\treturn code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\t/* TODO(mundaym): implement all */\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#else\n\t\treturn 1;\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n\n\tcase SLJIT_HAS_CLZ:\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_SIMD:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n\tcase SLJIT_HAS_CTZ:\n\t\treturn 2;\n\n\tcase SLJIT_HAS_CMOV:\n\t\treturn have_lscond1() ? 1 : 0;\n\t}\n\treturn 0;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tSLJIT_UNUSED_ARG(type);\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Entry, exit                                                          */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\tsljit_s32 offset, i, tmp;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\t/* Saved registers are stored in callee allocated save area. */\n\tSLJIT_ASSERT(gpr(SLJIT_FIRST_SAVED_REG) == r6 && gpr(SLJIT_S0) == r13);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\toffset = 2 * SSIZE_OF(sw);\n\tif (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) {\n\t\tif (saved_arg_count == 0) {\n\t\t\tFAIL_IF(push_inst(compiler, stmg(r6, r14, offset, r15)));\n\t\t\toffset += 9 * SSIZE_OF(sw);\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, stmg(r6, r13 - (sljit_gpr)saved_arg_count, offset, r15)));\n\t\t\toffset += (8 - saved_arg_count) * SSIZE_OF(sw);\n\t\t}\n\t} else {\n\t\tif (scratches == SLJIT_FIRST_SAVED_REG) {\n\t\t\tFAIL_IF(push_inst(compiler, stg(r6, offset, 0, r15)));\n\t\t\toffset += SSIZE_OF(sw);\n\t\t} else if (scratches > SLJIT_FIRST_SAVED_REG) {\n\t\t\tFAIL_IF(push_inst(compiler, stmg(r6, r6 + (sljit_gpr)(scratches - SLJIT_FIRST_SAVED_REG), offset, r15)));\n\t\t\toffset += (scratches - (SLJIT_FIRST_SAVED_REG - 1)) * SSIZE_OF(sw);\n\t\t}\n\n\t\tif (saved_arg_count == 0) {\n\t\t\tif (saveds == 0) {\n\t\t\t\tFAIL_IF(push_inst(compiler, stg(r14, offset, 0, r15)));\n\t\t\t\toffset += SSIZE_OF(sw);\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_inst(compiler, stmg(r14 - (sljit_gpr)saveds, r14, offset, r15)));\n\t\t\t\toffset += (saveds + 1) * SSIZE_OF(sw);\n\t\t\t}\n\t\t} else if (saveds > saved_arg_count) {\n\t\t\tif (saveds == saved_arg_count + 1) {\n\t\t\t\tFAIL_IF(push_inst(compiler, stg(r14 - (sljit_gpr)saveds, offset, 0, r15)));\n\t\t\t\toffset += SSIZE_OF(sw);\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_inst(compiler, stmg(r14 - (sljit_gpr)saveds, r13 - (sljit_gpr)saved_arg_count, offset, r15)));\n\t\t\t\toffset += (saveds - saved_arg_count) * SSIZE_OF(sw);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (saved_arg_count > 0) {\n\t\tFAIL_IF(push_inst(compiler, stg(r14, offset, 0, r15)));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\ttmp = SLJIT_FS0 - fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\tFAIL_IF(push_inst(compiler, 0x60000000 /* std */ | F20(i) | R12A(r15) | (sljit_ins)offset));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\tFAIL_IF(push_inst(compiler, 0x60000000 /* std */ | F20(i) | R12A(r15) | (sljit_ins)offset));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\tlocal_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf;\n\tcompiler->local_size = local_size;\n\n\tif (is_s20(-local_size))\n\t\tFAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size)));\n\telse\n\t\tFAIL_IF(push_inst(compiler, 0xc20400000000 /* slgfi */ | R36A(r15) | (sljit_ins)local_size));\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\treturn SLJIT_SUCCESS;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tsaved_arg_count = 0;\n\ttmp = 0;\n\twhile (arg_types > 0) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\tif (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {\n\t\t\t\tFAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S0 - saved_arg_count), gpr(SLJIT_R0 + tmp))));\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\t\t\ttmp++;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tcompiler->local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_gpr last_reg)\n{\n\tsljit_s32 offset, i, tmp;\n\tsljit_s32 local_size = compiler->local_size;\n\tsljit_s32 saveds = compiler->saveds;\n\tsljit_s32 scratches = compiler->scratches;\n\tsljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\n\tif (is_u12(local_size))\n\t\tFAIL_IF(push_inst(compiler, 0x41000000 /* ly */ | R20A(r15) | R12A(r15) | (sljit_ins)local_size));\n\telse if (is_s20(local_size))\n\t\tFAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(local_size)));\n\telse\n\t\tFAIL_IF(push_inst(compiler, 0xc20a00000000 /* algfi */ | R36A(r15) | (sljit_ins)local_size));\n\n\toffset = 2 * SSIZE_OF(sw);\n\tif (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) {\n\t\tif (kept_saveds_count == 0) {\n\t\t\tFAIL_IF(push_inst(compiler, lmg(r6, last_reg, offset, r15)));\n\t\t\toffset += 9 * SSIZE_OF(sw);\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, lmg(r6, r13 - (sljit_gpr)kept_saveds_count, offset, r15)));\n\t\t\toffset += (8 - kept_saveds_count) * SSIZE_OF(sw);\n\t\t}\n\t} else {\n\t\tif (scratches == SLJIT_FIRST_SAVED_REG) {\n\t\t\tFAIL_IF(push_inst(compiler, lg(r6, offset, 0, r15)));\n\t\t\toffset += SSIZE_OF(sw);\n\t\t} else if (scratches > SLJIT_FIRST_SAVED_REG) {\n\t\t\tFAIL_IF(push_inst(compiler, lmg(r6, r6 + (sljit_gpr)(scratches - SLJIT_FIRST_SAVED_REG), offset, r15)));\n\t\t\toffset += (scratches - (SLJIT_FIRST_SAVED_REG - 1)) * SSIZE_OF(sw);\n\t\t}\n\n\t\tif (kept_saveds_count == 0) {\n\t\t\tif (saveds == 0) {\n\t\t\t\tif (last_reg == r14)\n\t\t\t\t\tFAIL_IF(push_inst(compiler, lg(r14, offset, 0, r15)));\n\t\t\t\toffset += SSIZE_OF(sw);\n\t\t\t} else if (saveds == 1 && last_reg == r13) {\n\t\t\t\tFAIL_IF(push_inst(compiler, lg(r13, offset, 0, r15)));\n\t\t\t\toffset += 2 * SSIZE_OF(sw);\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_inst(compiler, lmg(r14 - (sljit_gpr)saveds, last_reg, offset, r15)));\n\t\t\t\toffset += (saveds + 1) * SSIZE_OF(sw);\n\t\t\t}\n\t\t} else if (saveds > kept_saveds_count) {\n\t\t\tif (saveds == kept_saveds_count + 1) {\n\t\t\t\tFAIL_IF(push_inst(compiler, lg(r14 - (sljit_gpr)saveds, offset, 0, r15)));\n\t\t\t\toffset += SSIZE_OF(sw);\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_inst(compiler, lmg(r14 - (sljit_gpr)saveds, r13 - (sljit_gpr)kept_saveds_count, offset, r15)));\n\t\t\t\toffset += (saveds - kept_saveds_count) * SSIZE_OF(sw);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (kept_saveds_count > 0) {\n\t\tif (last_reg == r14)\n\t\t\tFAIL_IF(push_inst(compiler, lg(r14, offset, 0, r15)));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\ttmp = SLJIT_FS0 - compiler->fsaveds;\n\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\tFAIL_IF(push_inst(compiler, 0x68000000 /* ld */ | F20(i) | R12A(r15) | (sljit_ins)offset));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\tfor (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\tFAIL_IF(push_inst(compiler, 0x68000000 /* ld */ | F20(i) | R12A(r15) | (sljit_ins)offset));\n\t\toffset += SSIZE_OF(sw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tFAIL_IF(emit_stack_frame_release(compiler, r14));\n\treturn push_inst(compiler, br(r14)); /* return */\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(load_word(compiler, tmp1, src, srcw, 0 /* 64-bit */));\n\t\tsrc = TMP_REG2;\n\t\tsrcw = 0;\n\t} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tFAIL_IF(push_inst(compiler, lgr(tmp1, gpr(src))));\n\t\tsrc = TMP_REG2;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, r13));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tsljit_gpr arg0 = gpr(SLJIT_R0);\n\tsljit_gpr arg1 = gpr(SLJIT_R1);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\top = GET_OPCODE(op) | (op & SLJIT_32);\n\tswitch (op) {\n\tcase SLJIT_BREAKPOINT:\n\t\t/* The following invalid instruction is emitted by gdb. */\n\t\treturn push_inst(compiler, 0x0001 /* 2-byte trap */);\n\tcase SLJIT_NOP:\n\t\treturn push_inst(compiler, 0x0700 /* 2-byte nop */);\n\tcase SLJIT_LMUL_UW:\n\t\tFAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));\n\t\tbreak;\n\tcase SLJIT_LMUL_SW:\n\t\t/* signed multiplication from: */\n\t\t/* Hacker's Delight, Second Edition: Chapter 8-3. */\n\t\tFAIL_IF(push_inst(compiler, srag(tmp0, arg0, 63, 0)));\n\t\tFAIL_IF(push_inst(compiler, srag(tmp1, arg1, 63, 0)));\n\t\tFAIL_IF(push_inst(compiler, ngr(tmp0, arg1)));\n\t\tFAIL_IF(push_inst(compiler, ngr(tmp1, arg0)));\n\n\t\t/* unsigned multiplication */\n\t\tFAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));\n\n\t\tFAIL_IF(push_inst(compiler, sgr(arg0, tmp0)));\n\t\tFAIL_IF(push_inst(compiler, sgr(arg0, tmp1)));\n\t\tbreak;\n\tcase SLJIT_DIV_U32:\n\tcase SLJIT_DIVMOD_U32:\n\t\tFAIL_IF(push_inst(compiler, lhi(tmp0, 0)));\n\t\tFAIL_IF(push_inst(compiler, lr(tmp1, arg0)));\n\t\tFAIL_IF(push_inst(compiler, dlr(tmp0, arg1)));\n\t\tFAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */\n\t\tif (op == SLJIT_DIVMOD_U32)\n\t\t\treturn push_inst(compiler, lr(arg1, tmp0)); /* remainder */\n\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_DIV_S32:\n\tcase SLJIT_DIVMOD_S32:\n\t\tFAIL_IF(push_inst(compiler, 0xeb00000000dc /* srak */ | R36A(tmp0) | R32A(arg0) | (31 << 16)));\n\t\tFAIL_IF(push_inst(compiler, lr(tmp1, arg0)));\n\t\tFAIL_IF(push_inst(compiler, dr(tmp0, arg1)));\n\t\tFAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */\n\t\tif (op == SLJIT_DIVMOD_S32)\n\t\t\treturn push_inst(compiler, lr(arg1, tmp0)); /* remainder */\n\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIVMOD_UW:\n\t\tFAIL_IF(push_inst(compiler, lghi(tmp0, 0)));\n\t\tFAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));\n\t\tFAIL_IF(push_inst(compiler, dlgr(tmp0, arg1)));\n\t\tFAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */\n\t\tif (op == SLJIT_DIVMOD_UW)\n\t\t\treturn push_inst(compiler, lgr(arg1, tmp0)); /* remainder */\n\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_DIV_SW:\n\tcase SLJIT_DIVMOD_SW:\n\t\tFAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));\n\t\tFAIL_IF(push_inst(compiler, dsgr(tmp0, arg1)));\n\t\tFAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */\n\t\tif (op == SLJIT_DIVMOD_SW)\n\t\t\treturn push_inst(compiler, lgr(arg1, tmp0)); /* remainder */\n\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_MEMORY_BARRIER:\n\t\treturn push_inst(compiler, 0x0700 /* bcr */ | (0xe << 4) | 0);\n\tcase SLJIT_ENDBR:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t}\n\t/* swap result registers */\n\tFAIL_IF(push_inst(compiler, lgr(tmp0, arg0)));\n\tFAIL_IF(push_inst(compiler, lgr(arg0, arg1)));\n\treturn push_inst(compiler, lgr(arg1, tmp0));\n}\n\nstatic sljit_s32 sljit_emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr dst_r, sljit_gpr src_r)\n{\n\tsljit_s32 is_ctz = (GET_OPCODE(op) == SLJIT_CTZ);\n\n\tif ((op & SLJIT_32) && src_r != tmp0) {\n\t\tFAIL_IF(push_inst(compiler, 0xb9160000 /* llgfr */ | R4A(tmp0) | R0A(src_r)));\n\t\tsrc_r = tmp0;\n\t}\n\n\tif (is_ctz) {\n\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */) | R4A(tmp1) | R0A(src_r)));\n\n\t\tif (src_r == tmp0)\n\t\t\tFAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? 0x1400 /* nr */ : 0xb9800000 /* ngr */) | R4A(tmp0) | R0A(tmp1)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9e40000 /* ngrk */ | R12A(tmp1) | R4A(tmp0) | R0A(src_r)));\n\n\t\tsrc_r = tmp0;\n\t}\n\n\tFAIL_IF(push_inst(compiler, 0xb9830000 /* flogr */ | R4A(tmp0) | R0A(src_r)));\n\n\tif (is_ctz)\n\t\tFAIL_IF(push_inst(compiler, 0xec00000000d9 /* aghik */ | R36A(tmp1) | R32A(tmp0) | ((sljit_ins)(-64 & 0xffff) << 16)));\n\n\tif (op & SLJIT_32) {\n\t\tif (!is_ctz && dst_r != tmp0)\n\t\t\treturn push_inst(compiler, 0xec00000000d9 /* aghik */ | R36A(dst_r) | R32A(tmp0) | ((sljit_ins)(-32 & 0xffff) << 16));\n\n\t\tFAIL_IF(push_inst(compiler, 0xc20800000000 /* agfi */ | R36A(tmp0) | (sljit_u32)-32));\n\t}\n\n\tif (is_ctz)\n\t\tFAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp0) | R32A(tmp1) | ((sljit_ins)((op & SLJIT_32) ? 59 : 58) << 24) | (63 << 16) | ((sljit_ins)((op & SLJIT_32) ? 5 : 6) << 8)));\n\n\tif (dst_r == tmp0)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ((op & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(tmp0));\n}\n\nstatic sljit_s32 sljit_emit_rev(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tstruct addr addr;\n\tsljit_gpr reg;\n\tsljit_ins ins;\n\tsljit_s32 opcode = GET_OPCODE(op);\n\tsljit_s32 is_16bit = (opcode == SLJIT_REV_U16 || opcode == SLJIT_REV_S16);\n\n\tif (dst & SLJIT_MEM) {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tFAIL_IF(load_store_op(compiler, tmp0, src, srcw, op & SLJIT_32, is_16bit ? load_halfword_forms : load_forms));\n\t\t\treg = tmp0;\n\t\t} else\n\t\t\treg = gpr(src);\n\n\t\tFAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1));\n\n\t\tif (is_16bit)\n\t\t\tins = 0xe3000000003f /* strvh */;\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? 0xe3000000003e /* strv */ : 0xe3000000002f /* strvg */;\n\n\t\treturn push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));\n\t}\n\n\treg = gpr(dst);\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));\n\n\t\tif (is_16bit)\n\t\t\tins = 0xe3000000001f /* lrvh */;\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? 0xe3000000001e /* lrv */ : 0xe3000000000f /* lrvg */;\n\n\t\tFAIL_IF(push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)));\n\n\t\tif (opcode == SLJIT_REV)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (is_16bit) {\n\t\t\tif (op & SLJIT_32)\n\t\t\t\tins = (opcode == SLJIT_REV_U16) ? 0xb9950000 /* llhr */ : 0xb9270000 /* lhr */;\n\t\t\telse\n\t\t\t\tins = (opcode == SLJIT_REV_U16) ? 0xb9850000 /* llghr */ : 0xb9070000 /* lghr */;\n\t\t} else\n\t\t\tins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */;\n\n\t\treturn push_inst(compiler, ins | R4A(reg) | R0A(reg));\n\t}\n\n\tins = (op & SLJIT_32) ? 0xb91f0000 /* lrvr */ : 0xb90f0000 /* lrvgr */;\n\tFAIL_IF(push_inst(compiler, ins | R4A(reg) | R0A(gpr(src))));\n\n\tif (opcode == SLJIT_REV)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (!is_16bit) {\n\t\tins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */;\n\t\treturn push_inst(compiler, ins | R4A(reg) | R0A(reg));\n\t}\n\n\tif (op & SLJIT_32) {\n\t\tins = (opcode == SLJIT_REV_U16) ? 0x88000000 /* srl */ : 0x8a000000 /* sra */;\n\t\treturn push_inst(compiler, ins | R20A(reg) | 16);\n\t}\n\n\tins = (opcode == SLJIT_REV_U16) ? 0xeb000000000c /* srlg */ : 0xeb000000000a /* srag */;\n\treturn push_inst(compiler, ins | R36A(reg) | R32A(reg) | (48 << 16));\n}\n\n/* LEVAL will be defined later with different parameters as needed */\n#define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins;\n\tstruct addr mem;\n\tsljit_gpr dst_r;\n\tsljit_gpr src_r;\n\tsljit_s32 opcode = GET_OPCODE(op);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (opcode >= SLJIT_MOV && opcode <= SLJIT_MOV_P) {\n\t\t/* LOAD REGISTER */\n\t\tif (FAST_IS_REG(dst) && FAST_IS_REG(src)) {\n\t\t\tdst_r = gpr(dst);\n\t\t\tsrc_r = gpr(src);\n\t\t\tswitch (opcode | (op & SLJIT_32)) {\n\t\t\t/* 32-bit */\n\t\t\tcase SLJIT_MOV32_U8:\n\t\t\t\tins = llcr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_S8:\n\t\t\t\tins = lbr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_U16:\n\t\t\t\tins = llhr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_S16:\n\t\t\t\tins = lhr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32:\n\t\t\t\tif (dst_r == src_r)\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\tins = lr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\t/* 64-bit */\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\t\tins = llgcr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\tins = lgbr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\t\tins = llghr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\tins = lghr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\t\tins = llgfr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\t\tins = lgfr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV:\n\t\t\tcase SLJIT_MOV_P:\n\t\t\t\tif (dst_r == src_r)\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t\tins = lgr(dst_r, src_r);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tins = 0;\n\t\t\t\tSLJIT_UNREACHABLE();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, ins));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\t/* LOAD IMMEDIATE */\n\t\tif (FAST_IS_REG(dst) && src == SLJIT_IMM) {\n\t\t\tswitch (opcode) {\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\t\tsrcw = (sljit_sw)((sljit_u8)(srcw));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\tsrcw = (sljit_sw)((sljit_s8)(srcw));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\t\tsrcw = (sljit_sw)((sljit_u16)(srcw));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\tsrcw = (sljit_sw)((sljit_s16)(srcw));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\t\tsrcw = (sljit_sw)((sljit_u32)(srcw));\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\tcase SLJIT_MOV32:\n\t\t\t\tsrcw = (sljit_sw)((sljit_s32)(srcw));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn push_load_imm_inst(compiler, gpr(dst), srcw);\n\t\t}\n\t\t/* LOAD */\n\t\t/* TODO(carenas): avoid reg being defined later */\n\t\t#define LEVAL(i) EVAL(i, reg, mem)\n\t\tif (FAST_IS_REG(dst) && (src & SLJIT_MEM)) {\n\t\t\tsljit_gpr reg = gpr(dst);\n\n\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));\n\t\t\t/* TODO(carenas): convert all calls below to LEVAL */\n\t\t\tswitch (opcode | (op & SLJIT_32)) {\n\t\t\tcase SLJIT_MOV32_U8:\n\t\t\t\tins = llc(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_S8:\n\t\t\t\tins = lb(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_U16:\n\t\t\t\tins = llh(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32_S16:\n\t\t\t\tins = WHEN2(is_u12(mem.offset), lh, lhy);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV32:\n\t\t\t\tins = WHEN2(is_u12(mem.offset), l, ly);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\t\tins = LEVAL(llgc);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\tins = lgb(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\t\tins = LEVAL(llgh);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\tins = lgh(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\t\tins = LEVAL(llgf);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\t\tins = lgf(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_P:\n\t\t\tcase SLJIT_MOV:\n\t\t\t\tins = lg(reg, mem.offset, mem.index, mem.base);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tins = 0;\n\t\t\t\tSLJIT_UNREACHABLE();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tFAIL_IF(push_inst(compiler, ins));\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\t/* STORE and STORE IMMEDIATE */\n\t\tif ((dst & SLJIT_MEM) && (FAST_IS_REG(src) || src == SLJIT_IMM)) {\n\t\t\tsljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0;\n\n\t\t\tif (src == SLJIT_IMM) {\n\t\t\t\t/* TODO(mundaym): MOVE IMMEDIATE? */\n\t\t\t\tFAIL_IF(push_load_imm_inst(compiler, reg, srcw));\n\t\t\t}\n\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));\n\t\t\tswitch (opcode) {\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tWHEN2(is_u12(mem.offset), stc, stcy));\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tWHEN2(is_u12(mem.offset), sth, sthy));\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\tcase SLJIT_MOV32:\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tWHEN2(is_u12(mem.offset), st, sty));\n\t\t\tcase SLJIT_MOV_P:\n\t\t\tcase SLJIT_MOV:\n\t\t\t\tFAIL_IF(push_inst(compiler, LEVAL(stg)));\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\tdefault:\n\t\t\t\tSLJIT_UNREACHABLE();\n\t\t\t}\n\t\t}\n\t\t#undef LEVAL\n\t\t/* MOVE CHARACTERS */\n\t\tif ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) {\n\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));\n\t\t\tswitch (opcode) {\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\tFAIL_IF(push_inst(compiler,\n\t\t\t\t\tEVAL(llgc, tmp0, mem)));\n\t\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tEVAL(stcy, tmp0, mem));\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\tFAIL_IF(push_inst(compiler,\n\t\t\t\t\tEVAL(llgh, tmp0, mem)));\n\t\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tEVAL(sthy, tmp0, mem));\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\tcase SLJIT_MOV32:\n\t\t\t\tFAIL_IF(push_inst(compiler,\n\t\t\t\t\tEVAL(ly, tmp0, mem)));\n\t\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));\n\t\t\t\treturn push_inst(compiler,\n\t\t\t\t\tEVAL(sty, tmp0, mem));\n\t\t\tcase SLJIT_MOV_P:\n\t\t\tcase SLJIT_MOV:\n\t\t\t\tFAIL_IF(push_inst(compiler,\n\t\t\t\t\tEVAL(lg, tmp0, mem)));\n\t\t\t\tFAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));\n\t\t\t\tFAIL_IF(push_inst(compiler,\n\t\t\t\t\tEVAL(stg, tmp0, mem)));\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\tdefault:\n\t\t\t\tSLJIT_UNREACHABLE();\n\t\t\t}\n\t\t}\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tSLJIT_ASSERT(src != SLJIT_IMM);\n\n\tdst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\tsrc_r = FAST_IS_REG(src) ? gpr(src) : tmp0;\n\n\tcompiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z);\n\n\t/* TODO(mundaym): optimize loads and stores */\n\tswitch (opcode) {\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\t\tif (src & SLJIT_MEM)\n\t\t\tFAIL_IF(load_unsigned_word(compiler, src_r, src, srcw, op & SLJIT_32));\n\n\t\tFAIL_IF(sljit_emit_clz_ctz(compiler, op, dst_r, src_r));\n\t\tbreak;\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n\t\top |= SLJIT_32;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\t\treturn sljit_emit_rev(compiler, op, dst, dstw, src, srcw);\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, dst_r, dst, dstw, op & SLJIT_32);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE int is_commutative(sljit_s32 op)\n{\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\tcase SLJIT_ADDC:\n\tcase SLJIT_MUL:\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic const struct ins_forms add_forms = {\n\t0x1a00, /* ar */\n\t0xb9080000, /* agr */\n\t0xb9f80000, /* ark */\n\t0xb9e80000, /* agrk */\n\t0x5a000000, /* a */\n\t0xe3000000005a, /* ay */\n\t0xe30000000008, /* ag */\n};\n\nstatic const struct ins_forms logical_add_forms = {\n\t0x1e00, /* alr */\n\t0xb90a0000, /* algr */\n\t0xb9fa0000, /* alrk */\n\t0xb9ea0000, /* algrk */\n\t0x5e000000, /* al */\n\t0xe3000000005e, /* aly */\n\t0xe3000000000a, /* alg */\n};\n\nstatic sljit_s32 sljit_emit_add(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tint sets_overflow = (op & VARIABLE_FLAG_MASK) == SLJIT_SET_OVERFLOW;\n\tint sets_zero_overflow = (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW);\n\tconst struct ins_forms *forms;\n\tsljit_ins ins;\n\n\tif (src2 == SLJIT_IMM) {\n\t\tif (!sets_zero_overflow && is_s8(src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) {\n\t\t\tif (sets_overflow)\n\t\t\t\tins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */;\n\t\t\telse\n\t\t\t\tins = (op & SLJIT_32) ? 0xeb000000006e /* alsi */ : 0xeb000000007e /* algsi */;\n\t\t\treturn emit_siy(compiler, ins, dst, dstw, src2w);\n\t\t}\n\n\t\tif (is_s16(src2w)) {\n\t\t\tif (sets_overflow)\n\t\t\t\tins = (op & SLJIT_32) ? 0xec00000000d8 /* ahik */ : 0xec00000000d9 /* aghik */;\n\t\t\telse\n\t\t\t\tins = (op & SLJIT_32) ? 0xec00000000da /* alhsik */ : 0xec00000000db /* alghsik */;\n\t\t\tFAIL_IF(emit_rie_d(compiler, ins, dst, src1, src1w, src2w));\n\t\t\tgoto done;\n\t\t}\n\n\t\tif (!sets_overflow) {\n\t\t\tif ((op & SLJIT_32) || is_u32(src2w)) {\n\t\t\t\tins = (op & SLJIT_32) ? 0xc20b00000000 /* alfi */ : 0xc20a00000000 /* algfi */;\n\t\t\t\tFAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tif (is_u32(-src2w)) {\n\t\t\t\tFAIL_IF(emit_ri(compiler, 0xc20400000000 /* slgfi */, dst, src1, src1w, -src2w, RIL_A));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t}\n\t\telse if ((op & SLJIT_32) || is_s32(src2w)) {\n\t\t\tins = (op & SLJIT_32) ? 0xc20900000000 /* afi */ : 0xc20800000000 /* agfi */;\n\t\t\tFAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\tforms = sets_overflow ? &add_forms : &logical_add_forms;\n\tFAIL_IF(emit_commutative(compiler, forms, dst, src1, src1w, src2, src2w));\n\ndone:\n\tif (sets_zero_overflow)\n\t\tFAIL_IF(update_zero_overflow(compiler, op, FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic const struct ins_forms sub_forms = {\n\t0x1b00, /* sr */\n\t0xb9090000, /* sgr */\n\t0xb9f90000, /* srk */\n\t0xb9e90000, /* sgrk */\n\t0x5b000000, /* s */\n\t0xe3000000005b, /* sy */\n\t0xe30000000009, /* sg */\n};\n\nstatic const struct ins_forms logical_sub_forms = {\n\t0x1f00, /* slr */\n\t0xb90b0000, /* slgr */\n\t0xb9fb0000, /* slrk */\n\t0xb9eb0000, /* slgrk */\n\t0x5f000000, /* sl */\n\t0xe3000000005f, /* sly */\n\t0xe3000000000b, /* slg */\n};\n\nstatic sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 flag_type = GET_FLAG_TYPE(op);\n\tint sets_signed = (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_NOT_OVERFLOW);\n\tint sets_zero_overflow = (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW);\n\tconst struct ins_forms *forms;\n\tsljit_ins ins;\n\n\tif (dst == TMP_REG2 && flag_type <= SLJIT_SIG_LESS_EQUAL) {\n\t\tint compare_signed = flag_type >= SLJIT_SIG_LESS;\n\n\t\tcompiler->status_flags_state |= SLJIT_CURRENT_FLAGS_COMPARE;\n\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tif (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w))) {\n\t\t\t\tif ((op & SLJIT_32) || is_s32(src2w)) {\n\t\t\t\t\tins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */;\n\t\t\t\t\treturn emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A);\n\t\t\t\t}\n\t\t\t} else if ((op & SLJIT_32) || is_u32(src2w)) {\n\t\t\t\tins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */;\n\t\t\t\treturn emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A);\n\t\t\t}\n\t\t}\n\t\telse if (src2 & SLJIT_MEM) {\n\t\t\tif ((op & SLJIT_32) && ((src2 & OFFS_REG_MASK) || is_u12(src2w))) {\n\t\t\t\tins = compare_signed ? 0x59000000 /* c */ : 0x55000000 /* cl */;\n\t\t\t\treturn emit_rx(compiler, ins, src1, src1, src1w, src2, src2w, RX_A);\n\t\t\t}\n\n\t\t\tif (compare_signed)\n\t\t\t\tins = (op & SLJIT_32) ? 0xe30000000059 /* cy */ : 0xe30000000020 /* cg */;\n\t\t\telse\n\t\t\t\tins = (op & SLJIT_32) ? 0xe30000000055 /* cly */ : 0xe30000000021 /* clg */;\n\t\t\treturn emit_rx(compiler, ins, src1, src1, src1w, src2, src2w, RXY_A);\n\t\t}\n\n\t\tif (compare_signed)\n\t\t\tins = (op & SLJIT_32) ? 0x1900 /* cr */ : 0xb9200000 /* cgr */;\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? 0x1500 /* clr */ : 0xb9210000 /* clgr */;\n\t\treturn emit_rr(compiler, ins, src1, src1, src1w, src2, src2w);\n\t}\n\n\tif (src1 == SLJIT_IMM && src1w == 0 && (flag_type == 0 || sets_signed)) {\n\t\tins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */;\n\t\tFAIL_IF(emit_rr1(compiler, ins, dst, src2, src2w));\n\t\tgoto done;\n\t}\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsljit_sw neg_src2w = -src2w;\n\n\t\tif (sets_signed || neg_src2w != 0 || (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == 0) {\n\t\t\tif (!sets_zero_overflow && is_s8(neg_src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) {\n\t\t\t\tif (sets_signed)\n\t\t\t\t\tins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */;\n\t\t\t\telse\n\t\t\t\t\tins = (op & SLJIT_32) ? 0xeb000000006e /* alsi */ : 0xeb000000007e /* algsi */;\n\t\t\t\treturn emit_siy(compiler, ins, dst, dstw, neg_src2w);\n\t\t\t}\n\n\t\t\tif (is_s16(neg_src2w)) {\n\t\t\t\tif (sets_signed)\n\t\t\t\t\tins = (op & SLJIT_32) ? 0xec00000000d8 /* ahik */ : 0xec00000000d9 /* aghik */;\n\t\t\t\telse\n\t\t\t\t\tins = (op & SLJIT_32) ? 0xec00000000da /* alhsik */ : 0xec00000000db /* alghsik */;\n\t\t\t\tFAIL_IF(emit_rie_d(compiler, ins, dst, src1, src1w, neg_src2w));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t}\n\n\t\tif (!sets_signed) {\n\t\t\tif ((op & SLJIT_32) || is_u32(src2w)) {\n\t\t\t\tins = (op & SLJIT_32) ? 0xc20500000000 /* slfi */ : 0xc20400000000 /* slgfi */;\n\t\t\t\tFAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tif (is_u32(neg_src2w)) {\n\t\t\t\tFAIL_IF(emit_ri(compiler, 0xc20a00000000 /* algfi */, dst, src1, src1w, neg_src2w, RIL_A));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t}\n\t\telse if ((op & SLJIT_32) || is_s32(neg_src2w)) {\n\t\t\tins = (op & SLJIT_32) ? 0xc20900000000 /* afi */ : 0xc20800000000 /* agfi */;\n\t\t\tFAIL_IF(emit_ri(compiler, ins, dst, src1, src1w, neg_src2w, RIL_A));\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\tforms = sets_signed ? &sub_forms : &logical_sub_forms;\n\tFAIL_IF(emit_non_commutative(compiler, forms, dst, src1, src1w, src2, src2w));\n\ndone:\n\tif (sets_signed) {\n\t\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\n\t\tif ((op & VARIABLE_FLAG_MASK) != SLJIT_SET_OVERFLOW) {\n\t\t\t/* In case of overflow, the sign bit of the two source operands must be different, and\n\t\t\t     - the first operand is greater if the sign bit of the result is set\n\t\t\t     - the first operand is less if the sign bit of the result is not set\n\t\t\t   The -result operation sets the corrent sign, because the result cannot be zero.\n\t\t\t   The overflow is considered greater, since the result must be equal to INT_MIN so its sign bit is set. */\n\t\t\tFAIL_IF(push_inst(compiler, brc(0xe, (op & SLJIT_32) ? (2 + 1) : (2 + 2))));\n\t\t\tFAIL_IF(push_inst(compiler, (op & SLJIT_32) ? lcr(tmp1, dst_r) : lcgr(tmp1, dst_r)));\n\t\t}\n\t\telse if (op & SLJIT_SET_Z)\n\t\t\tFAIL_IF(update_zero_overflow(compiler, op, dst_r));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic const struct ins_forms multiply_forms = {\n\t0xb2520000, /* msr */\n\t0xb90c0000, /* msgr */\n\t0xb9fd0000, /* msrkc */\n\t0xb9ed0000, /* msgrkc */\n\t0x71000000, /* ms */\n\t0xe30000000051, /* msy */\n\t0xe3000000000c, /* msg */\n};\n\nstatic const struct ins_forms multiply_overflow_forms = {\n\t0,\n\t0,\n\t0xb9fd0000, /* msrkc */\n\t0xb9ed0000, /* msgrkc */\n\t0,\n\t0xe30000000053, /* msc */\n\t0xe30000000083, /* msgc */\n};\n\nstatic sljit_s32 sljit_emit_multiply(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_ins ins;\n\n\tif (HAS_FLAGS(op)) {\n\t\t/* if have_misc2 fails, this operation should be emulated. 32 bit emulation:\n\t\tFAIL_IF(push_inst(compiler, lgfr(tmp0, src1_r)));\n\t\tFAIL_IF(push_inst(compiler, msgfr(tmp0, src2_r)));\n\t\tif (dst_r != tmp0) {\n\t\t\tFAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));\n\t\t}\n\t\tFAIL_IF(push_inst(compiler, aih(tmp0, 1)));\n\t\tFAIL_IF(push_inst(compiler, nihf(tmp0, ~1U)));\n\t\tFAIL_IF(push_inst(compiler, ipm(tmp1)));\n\t\tFAIL_IF(push_inst(compiler, oilh(tmp1, 0x2000))); */\n\n\t\treturn emit_commutative(compiler, &multiply_overflow_forms, dst, src1, src1w, src2, src2w);\n\t}\n\n\tif (src2 == SLJIT_IMM) {\n\t\tif (is_s16(src2w)) {\n\t\t\tins = (op & SLJIT_32) ? 0xa70c0000 /* mhi */ : 0xa70d0000 /* mghi */;\n\t\t\treturn emit_ri(compiler, ins, dst, src1, src1w, src2w, RI_A);\n\t\t}\n\n\t\tif (is_s32(src2w)) {\n\t\t\tins = (op & SLJIT_32) ? 0xc20100000000 /* msfi */ : 0xc20000000000 /* msgfi */;\n\t\t\treturn emit_ri(compiler, ins, dst, src1, src1w, src2w, RIL_A);\n\t\t}\n\t}\n\n\treturn emit_commutative(compiler, &multiply_forms, dst, src1, src1w, src2, src2w);\n}\n\nstatic sljit_s32 sljit_emit_bitwise_imm(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_uw imm, sljit_s32 count16)\n{\n\tsljit_s32 mode = compiler->mode;\n\tsljit_gpr dst_r = tmp0;\n\tsljit_s32 needs_move = 1;\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = gpr(dst & REG_MASK);\n\t\tif (dst == src1)\n\t\t\tneeds_move = 0;\n\t}\n\n\tif (needs_move)\n\t\tFAIL_IF(emit_move(compiler, dst_r, src1, src1w));\n\n\tif (type == SLJIT_AND) {\n\t\tif (!(mode & SLJIT_32))\n\t\t\tFAIL_IF(push_inst(compiler, 0xc00a00000000 /* nihf */ | R36A(dst_r) | (imm >> 32)));\n\t\treturn push_inst(compiler, 0xc00b00000000 /* nilf */ | R36A(dst_r) | (imm & 0xffffffff));\n\t}\n\telse if (type == SLJIT_OR) {\n\t\tif (count16 >= 3) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xc00c00000000 /* oihf */ | R36A(dst_r) | (imm >> 32)));\n\t\t\treturn push_inst(compiler, 0xc00d00000000 /* oilf */ | R36A(dst_r) | (imm & 0xffffffff));\n\t\t}\n\n\t\tif (count16 >= 2) {\n\t\t\tif ((imm & 0x00000000ffffffffull) == 0)\n\t\t\t\treturn push_inst(compiler, 0xc00c00000000 /* oihf */ | R36A(dst_r) | (imm >> 32));\n\t\t\tif ((imm & 0xffffffff00000000ull) == 0)\n\t\t\t\treturn push_inst(compiler, 0xc00d00000000 /* oilf */ | R36A(dst_r) | (imm & 0xffffffff));\n\t\t}\n\n\t\tif ((imm & 0xffff000000000000ull) != 0)\n\t\t\tFAIL_IF(push_inst(compiler, 0xa5080000 /* oihh */ | R20A(dst_r) | (imm >> 48)));\n\t\tif ((imm & 0x0000ffff00000000ull) != 0)\n\t\t\tFAIL_IF(push_inst(compiler, 0xa5090000 /* oihl */ | R20A(dst_r) | ((imm >> 32) & 0xffff)));\n\t\tif ((imm & 0x00000000ffff0000ull) != 0)\n\t\t\tFAIL_IF(push_inst(compiler, 0xa50a0000 /* oilh */ | R20A(dst_r) | ((imm >> 16) & 0xffff)));\n\t\tif ((imm & 0x000000000000ffffull) != 0 || imm == 0)\n\t\t\treturn push_inst(compiler, 0xa50b0000 /* oill */ | R20A(dst_r) | (imm & 0xffff));\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif ((imm & 0xffffffff00000000ull) != 0)\n\t\tFAIL_IF(push_inst(compiler, 0xc00600000000 /* xihf */ | R36A(dst_r) | (imm >> 32)));\n\tif ((imm & 0x00000000ffffffffull) != 0 || imm == 0)\n\t\treturn push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(dst_r) | (imm & 0xffffffff));\n\treturn SLJIT_SUCCESS;\n}\n\nstatic const struct ins_forms bitwise_and_forms = {\n\t0x1400, /* nr */\n\t0xb9800000, /* ngr */\n\t0xb9f40000, /* nrk */\n\t0xb9e40000, /* ngrk */\n\t0x54000000, /* n */\n\t0xe30000000054, /* ny */\n\t0xe30000000080, /* ng */\n};\n\nstatic const struct ins_forms bitwise_or_forms = {\n\t0x1600, /* or */\n\t0xb9810000, /* ogr */\n\t0xb9f60000, /* ork */\n\t0xb9e60000, /* ogrk */\n\t0x56000000, /* o */\n\t0xe30000000056, /* oy */\n\t0xe30000000081, /* og */\n};\n\nstatic const struct ins_forms bitwise_xor_forms = {\n\t0x1700, /* xr */\n\t0xb9820000, /* xgr */\n\t0xb9f70000, /* xrk */\n\t0xb9e70000, /* xgrk */\n\t0x57000000, /* x */\n\t0xe30000000057, /* xy */\n\t0xe30000000082, /* xg */\n};\n\nstatic sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 type = GET_OPCODE(op);\n\tconst struct ins_forms *forms;\n\n\tif (src2 == SLJIT_IMM && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == TMP_REG2))) {\n\t\tsljit_s32 count16 = 0;\n\t\tsljit_uw imm = (sljit_uw)src2w;\n\n\t\tif (op & SLJIT_32)\n\t\t\timm &= 0xffffffffull;\n\n\t\tif ((imm & 0x000000000000ffffull) != 0 || imm == 0)\n\t\t\tcount16++;\n\t\tif ((imm & 0x00000000ffff0000ull) != 0)\n\t\t\tcount16++;\n\t\tif ((imm & 0x0000ffff00000000ull) != 0)\n\t\t\tcount16++;\n\t\tif ((imm & 0xffff000000000000ull) != 0)\n\t\t\tcount16++;\n\n\t\tif (type == SLJIT_AND && dst == TMP_REG2 && count16 == 1) {\n\t\t\tsljit_gpr src_r = tmp1;\n\n\t\t\tif (FAST_IS_REG(src1))\n\t\t\t\tsrc_r = gpr(src1 & REG_MASK);\n\t\t\telse\n\t\t\t\tFAIL_IF(emit_move(compiler, tmp1, src1, src1w));\n\n\t\t\tif ((imm & 0x000000000000ffffull) != 0 || imm == 0)\n\t\t\t\treturn push_inst(compiler, 0xa7010000 /* tmll */ | R20A(src_r) | imm);\n\t\t\tif ((imm & 0x00000000ffff0000ull) != 0)\n\t\t\t\treturn push_inst(compiler, 0xa7000000 /* tmlh */ | R20A(src_r) | (imm >> 16));\n\t\t\tif ((imm & 0x0000ffff00000000ull) != 0)\n\t\t\t\treturn push_inst(compiler, 0xa7030000 /* tmhl */ | R20A(src_r) | (imm >> 32));\n\t\t\treturn push_inst(compiler, 0xa7020000 /* tmhh */ | R20A(src_r) | (imm >> 48));\n\t\t}\n\n\t\tif (!(op & SLJIT_SET_Z))\n\t\t\treturn sljit_emit_bitwise_imm(compiler, type, dst, src1, src1w, imm, count16);\n\t}\n\n\tif (type == SLJIT_AND)\n\t\tforms = &bitwise_and_forms;\n\telse if (type == SLJIT_OR)\n\t\tforms = &bitwise_or_forms;\n\telse\n\t\tforms = &bitwise_xor_forms;\n\n\treturn emit_commutative(compiler, forms, dst, src1, src1w, src2, src2w);\n}\n\nstatic sljit_s32 sljit_emit_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 type = GET_OPCODE(op);\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\tsljit_gpr src_r = tmp0;\n\tsljit_gpr base_r = tmp0;\n\tsljit_ins imm = 0;\n\tsljit_ins ins;\n\n\tif (FAST_IS_REG(src1))\n\t\tsrc_r = gpr(src1);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp0, src1, src1w));\n\n\tif (src2 != SLJIT_IMM) {\n\t\tif (FAST_IS_REG(src2))\n\t\t\tbase_r = gpr(src2);\n\t\telse {\n\t\t\tFAIL_IF(emit_move(compiler, tmp1, src2, src2w));\n\t\t\tbase_r = tmp1;\n\t\t}\n\n\t\tif ((op & SLJIT_32) && (type == SLJIT_MSHL || type == SLJIT_MLSHR || type == SLJIT_MASHR)) {\n\t\t\tif (base_r != tmp1) {\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(base_r) | (59 << 24) | (1 << 23) | (63 << 16)));\n\t\t\t\tbase_r = tmp1;\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f));\n\t\t}\n\t} else\n\t\timm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f));\n\n\tif ((op & SLJIT_32) && dst_r == src_r) {\n\t\tif (type == SLJIT_SHL || type == SLJIT_MSHL)\n\t\t\tins = 0x89000000 /* sll */;\n\t\telse if (type == SLJIT_LSHR || type == SLJIT_MLSHR)\n\t\t\tins = 0x88000000 /* srl */;\n\t\telse\n\t\t\tins = 0x8a000000 /* sra */;\n\n\t\tFAIL_IF(push_inst(compiler, ins | R20A(dst_r) | R12A(base_r) | imm));\n\t} else {\n\t\tif (type == SLJIT_SHL || type == SLJIT_MSHL)\n\t\t\tins = (op & SLJIT_32) ? 0xeb00000000df /* sllk */ : 0xeb000000000d /* sllg */;\n\t\telse if (type == SLJIT_LSHR || type == SLJIT_MLSHR)\n\t\t\tins = (op & SLJIT_32) ? 0xeb00000000de /* srlk */ : 0xeb000000000c /* srlg */;\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? 0xeb00000000dc /* srak */ : 0xeb000000000a /* srag */;\n\n\t\tFAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | R28A(base_r) | (imm << 16)));\n\t}\n\n\tif ((op & SLJIT_SET_Z) && type != SLJIT_ASHR)\n\t\treturn push_inst(compiler, (op & SLJIT_32) ? or(dst_r, dst_r) : ogr(dst_r, dst_r));\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\tsljit_gpr src_r = tmp0;\n\tsljit_gpr base_r = tmp0;\n\tsljit_ins imm = 0;\n\tsljit_ins ins;\n\n\tif (FAST_IS_REG(src1))\n\t\tsrc_r = gpr(src1);\n\telse\n\t\tFAIL_IF(emit_move(compiler, tmp0, src1, src1w));\n\n\tif (src2 != SLJIT_IMM) {\n\t\tif (FAST_IS_REG(src2))\n\t\t\tbase_r = gpr(src2);\n\t\telse {\n\t\t\tFAIL_IF(emit_move(compiler, tmp1, src2, src2w));\n\t\t\tbase_r = tmp1;\n\t\t}\n\t}\n\n\tif (GET_OPCODE(op) == SLJIT_ROTR) {\n\t\tif (src2 != SLJIT_IMM) {\n\t\t\tins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | R4A(tmp1) | R0A(base_r)));\n\t\t\tbase_r = tmp1;\n\t\t} else\n\t\t\tsrc2w = -src2w;\n\t}\n\n\tif (src2 == SLJIT_IMM)\n\t\timm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f));\n\n\tins = (op & SLJIT_32) ? 0xeb000000001d /* rll */ : 0xeb000000001c /* rllg */;\n\treturn push_inst(compiler, ins | R36A(dst_r) | R32A(src_r) | R28A(base_r) | (imm << 16));\n}\n\nstatic const struct ins_forms addc_forms = {\n\t0xb9980000, /* alcr */\n\t0xb9880000, /* alcgr */\n\t0,\n\t0,\n\t0,\n\t0xe30000000098, /* alc */\n\t0xe30000000088, /* alcg */\n};\n\nstatic const struct ins_forms subc_forms = {\n\t0xb9990000, /* slbr */\n\t0xb9890000, /* slbgr */\n\t0,\n\t0,\n\t0,\n\t0xe30000000099, /* slb */\n\t0xe30000000089, /* slbg */\n};\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tcompiler->mode = op & SLJIT_32;\n\tcompiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z);\n\n\tif (is_commutative(op) && src1 == SLJIT_IMM && src2 != SLJIT_IMM) {\n\t\tsrc1 ^= src2;\n\t\tsrc2 ^= src1;\n\t\tsrc1 ^= src2;\n\n\t\tsrc1w ^= src2w;\n\t\tsrc2w ^= src1w;\n\t\tsrc1w ^= src2w;\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\t\tcompiler->status_flags_state |= SLJIT_CURRENT_FLAGS_ADD;\n\t\treturn sljit_emit_add(compiler, op, dst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_ADDC:\n\t\tcompiler->status_flags_state |= SLJIT_CURRENT_FLAGS_ADD;\n\t\tFAIL_IF(emit_commutative(compiler, &addc_forms, dst, src1, src1w, src2, src2w));\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_SUB:\n\t\tcompiler->status_flags_state |= SLJIT_CURRENT_FLAGS_SUB;\n\t\treturn sljit_emit_sub(compiler, op, dst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_SUBC:\n\t\tcompiler->status_flags_state |= SLJIT_CURRENT_FLAGS_SUB;\n\t\tFAIL_IF(emit_non_commutative(compiler, &subc_forms, dst, src1, src1w, src2, src2w));\n\t\tif (dst & SLJIT_MEM)\n\t\t\treturn store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_MUL:\n\t\tFAIL_IF(sljit_emit_multiply(compiler, op, dst, src1, src1w, src2, src2w));\n\t\tbreak;\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\t\tFAIL_IF(sljit_emit_bitwise(compiler, op, dst, src1, src1w, src2, src2w));\n\t\tbreak;\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\tFAIL_IF(sljit_emit_shift(compiler, op, dst, src1, src1w, src2, src2w));\n\t\tbreak;\n\tcase SLJIT_ROTL:\n\tcase SLJIT_ROTR:\n\t\tFAIL_IF(sljit_emit_rotate(compiler, op, dst, src1, src1w, src2, src2w));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, tmp0, dst, dstw, op & SLJIT_32);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_reg = (GET_OPCODE(op) == SLJIT_SUB || GET_OPCODE(op) == SLJIT_AND) ? TMP_REG2 : TMP_REG1;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tFAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), 0 /* tmp0 */, 0, src1, src1w, src2, src2w));\n\t\treturn push_inst(compiler, ((op & SLJIT_32) ? 0x1a00 /* ar */ : 0xb9080000 /* agr */) | R4A(gpr(dst_reg)) | R0A(tmp0));\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_right;\n\tsljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;\n\tsljit_gpr dst_r = gpr(dst_reg);\n\tsljit_gpr src1_r = gpr(src1_reg);\n\tsljit_gpr src2_r = gpr(src2_reg);\n\tsljit_gpr src3_r = tmp1;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\n\tis_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR);\n\n\tif (src1_reg == src2_reg) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tif (src3 == SLJIT_IMM) {\n\t\tsrc3w &= bit_length - 1;\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (op & SLJIT_32) {\n\t\t\tif (dst_r == src1_r) {\n\t\t\t\tins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */;\n\t\t\t\tFAIL_IF(push_inst(compiler, ins | R20A(dst_r) | (sljit_ins)src3w));\n\t\t\t} else {\n\t\t\t\tins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */;\n\t\t\t\tFAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16)));\n\t\t\t}\n\t\t} else {\n\t\t\tins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16)));\n\t\t}\n\n\t\tins = 0xec0000000055 /* risbg */;\n\n\t\tif (is_right) {\n\t\t\tsrc3w = bit_length - src3w;\n\t\t\tins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src3w) << 16) | ((sljit_ins)src3w << 8);\n\t\t} else\n\t\t\tins |= ((sljit_ins)(64 - src3w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)(src3w + 64 - bit_length) << 8);\n\n\t\treturn push_inst(compiler, ins | R36A(dst_r) | R32A(src2_r));\n\t}\n\n\tif (!(src3 & SLJIT_MEM)) {\n\t\tsrc3_r = gpr(src3);\n\n\t\tif (dst_r == src3_r) {\n\t\t\tFAIL_IF(push_inst(compiler, 0x1800 /* lr */ | R4A(tmp1) | R0A(src3_r)));\n\t\t\tsrc3_r = tmp1;\n\t\t}\n\t} else\n\t\tFAIL_IF(load_word(compiler, tmp1, src3, src3w, op & SLJIT_32));\n\n\tif (op & SLJIT_32) {\n\t\tif (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) {\n\t\t\tif (src3_r != tmp1) {\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src3_r) | (59 << 24) | (1 << 23) | (63 << 16)));\n\t\t\t\tsrc3_r = tmp1;\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f));\n\t\t}\n\n\t\tif (dst_r == src1_r) {\n\t\t\tins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | R20A(dst_r) | R12A(src3_r)));\n\t\t} else {\n\t\t\tins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r)));\n\t\t}\n\n\t\tif (src3_r != tmp1) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x1f));\n\t\t\tFAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src3_r)));\n\t\t} else\n\t\t\tFAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x1f));\n\n\t\tins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */;\n\t\tFAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1) | (0x1 << 16)));\n\n\t\treturn push_inst(compiler, 0x1600 /* or */ | R4A(dst_r) | R0A(tmp0));\n\t}\n\n\tins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */;\n\tFAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r)));\n\n\tins = is_right ? 0xeb000000000d /* sllg */ : 0xeb000000000c /* srlg */;\n\n\tif (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {\n\t\tif (src3_r != tmp1)\n\t\t\tFAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x3f));\n\n\t\tFAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | (0x1 << 16)));\n\t\tsrc2_r = tmp0;\n\n\t\tif (src3_r != tmp1)\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src3_r)));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x3f));\n\t} else\n\t\tFAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src3_r)));\n\n\tFAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1)));\n\treturn push_inst(compiler, 0xb9810000 /* ogr */ | R4A(dst_r) | R0A(tmp0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_gpr dst_r, tmp_r, src_r;\n\tstruct addr addr;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= 0x3f;\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\ttmp_r = FAST_IS_REG(dst) && (dst != src1) ? gpr(dst) : tmp0;\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(load_word(compiler, tmp_r, src2, src2w, 0 /* 64-bit */));\n\t\tsrc_r = tmp_r;\n\t} else {\n\t\tsrc_r = gpr(src2);\n\t}\n\n\tFAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp_r) | R32A(src_r) | ((sljit_ins)shift_arg << 16)));\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bxy(compiler, &addr, src1, src1w, tmp1));\n\t\tFAIL_IF(push_inst(compiler, 0xe30000000008 /* ag */ | R36A(tmp_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)));\n\t\tsrc_r = tmp_r;\n\t} else if (src1 == SLJIT_IMM) {\n\t\tif (is_s32(src1w)) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xc20800000000 /* agfi */ | R36A(tmp_r) | (sljit_u32)src1w));\n\t\t\tsrc_r = tmp_r;\n\t\t} else {\n\t\t\tsrc_r = tmp_r != tmp0 ? tmp0 : tmp1;\n\t\t\tFAIL_IF(push_load_imm_inst(compiler, src_r, src1w));\n\t\t}\n\t} else {\n\t\tsrc_r = gpr(src1);\n\t}\n\n\tdst_r = (FAST_IS_REG(dst) ? gpr(dst) : tmp0);\n\n\tif (src_r != tmp_r) {\n\t\tif (src_r == dst_r) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9080000 /* agr */ | R4A(dst_r) | R0A(tmp_r)));\n\t\t} else {\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(tmp_r) | R4A(dst_r) | R0A(src_r)));\n\t\t}\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, dst_r, dst, dstw, 0 /* 64-bit */);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_gpr src_r;\n\tstruct addr addr;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\tif (FAST_IS_REG(src)) {\n\t\t\tsrc_r = gpr(src);\n\t\t\tif (src_r != link_r)\n\t\t\t\tFAIL_IF(push_inst(compiler, lgr(link_r, src_r)));\n\t\t} else\n\t\t\tFAIL_IF(load_word(compiler, link_r, src, srcw, 0));\n\n\t\treturn push_inst(compiler, br(link_r));\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\tFAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1));\n\t\treturn push_inst(compiler, 0xe31000000036 /* pfd */ | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));\n\tdefault:\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_gpr dst_r = link_r;\n\tsljit_s32 size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tdst_r = gpr(dst);\n\n\t\t\tif (dst_r == link_r)\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\treturn push_inst(compiler, lgr(dst_r, link_r));\n\t\t}\n\t\tbreak;\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\tdst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\n\t\tsize = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 2);\n\t\tFAIL_IF(load_word(compiler, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, 0));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, dst_r, dst, dstw, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER)\n\t\treturn (sljit_s32)gpr(reg);\n\n\tif (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128)\n\t\treturn -1;\n\n\treturn (sljit_s32)freg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\tmemcpy((sljit_u8 *)&ins + sizeof(ins) - size, instruction, size);\n\treturn push_inst(compiler, ins);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n#define FLOAT_LOAD 0\n#define FLOAT_STORE 1\n\nstatic sljit_s32 float_mem(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tstruct addr addr;\n\tsljit_ins ins;\n\n\tSLJIT_ASSERT(mem & SLJIT_MEM);\n\n\tif ((mem & OFFS_REG_MASK) || is_u12(memw) || !is_s20(memw)) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, mem, memw, tmp1));\n\n\t\tif (op & FLOAT_STORE)\n\t\t\tins = (op & SLJIT_32) ? 0x70000000 /* ste */ : 0x60000000 /* std */;\n\t\telse\n\t\t\tins = (op & SLJIT_32) ? 0x78000000 /* le */ : 0x68000000 /* ld */;\n\n\t\treturn push_inst(compiler, ins | F20(reg) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset);\n\t}\n\n\tFAIL_IF(make_addr_bxy(compiler, &addr, mem, memw, tmp1));\n\n\tif (op & FLOAT_STORE)\n\t\tins = (op & SLJIT_32) ? 0xed0000000066 /* stey */ : 0xed0000000067 /* stdy */;\n\telse\n\t\tins = (op & SLJIT_32) ? 0xed0000000064 /* ley */ : 0xed0000000065 /* ldy */;\n\n\treturn push_inst(compiler, ins | F36(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset));\n}\n\nstatic sljit_s32 emit_float(struct sljit_compiler *compiler, sljit_ins ins_r, sljit_ins ins,\n\tsljit_s32 reg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tstruct addr addr;\n\n\tif (!(src & SLJIT_MEM))\n\t\treturn push_inst(compiler, ins_r | F4(reg) | F0(src));\n\n\tFAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1));\n\treturn push_inst(compiler, ins | F36(reg) | R32A(addr.index) | R28A(addr.base) | ((sljit_ins)addr.offset << 16));\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\tsljit_ins ins;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src, srcw));\n\t\tsrc = TMP_FREG1;\n\t}\n\n\t/* M3 is set to 5 */\n\tif (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)\n\t\tins = (op & SLJIT_32) ? 0xb3a85000 /* cgebr */ : 0xb3a95000 /* cgdbr */;\n\telse\n\t\tins = (op & SLJIT_32) ? 0xb3985000 /* cfebr */ : 0xb3995000 /* cfdbr */;\n\n\tFAIL_IF(push_inst(compiler, ins | R4A(dst_r) | F0(src)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, dst_r, dst, dstw, GET_OPCODE(op) >= SLJIT_CONV_S32_FROM_F64);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (src == SLJIT_IMM) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp0, srcw));\n\t\tsrc = (sljit_s32)tmp0;\n\t}\n\telse if (src & SLJIT_MEM) {\n\t\tFAIL_IF(load_word(compiler, tmp0, src, srcw, ins & 0x100000));\n\t\tsrc = (sljit_s32)tmp0;\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src)));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn float_mem(compiler, FLOAT_STORE | ((ins & 0x10000) ? 0 : SLJIT_32), TMP_FREG1, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins;\n\n\tif (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)\n\t\tsrcw = (sljit_s32)srcw;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)\n\t\tins = (op & SLJIT_32) ? 0xb3a40000 /* cegbr */ : 0xb3a50000 /* cdgbr */;\n\telse\n\t\tins = (op & SLJIT_32) ? 0xb3940000 /* cefbr */ : 0xb3950000 /* cdfbr */;\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_ins ins;\n\n\tif (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32)\n\t\tsrcw = (sljit_u32)srcw;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW)\n\t\tins = (op & SLJIT_32) ? 0xb3a00000 /* celgbr */ : 0xb3a10000 /* cdlgbr */;\n\telse\n\t\tins = (op & SLJIT_32) ? 0xb3900000 /* celfbr */ : 0xb3910000 /* cdlfbr */;\n\n\treturn sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_ins ins_r, ins;\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src1, src1w));\n\t\tsrc1 = TMP_FREG1;\n\t}\n\n\tif (op & SLJIT_32) {\n\t\tins_r = 0xb3090000 /* cebr */;\n\t\tins = 0xed0000000009 /* ceb */;\n\t} else {\n\t\tins_r = 0xb3190000 /* cdbr */;\n\t\tins = 0xed0000000019 /* cdb */;\n\t}\n\n\treturn emit_float(compiler, ins_r, ins, src1, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;\n\n\tif (op == SLJIT_CONV_F64_FROM_F32)\n\t\tFAIL_IF(emit_float(compiler, 0xb3040000 /* ldebr */, 0xed0000000004 /* ldeb */, dst_r, src, srcw));\n\telse {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op == SLJIT_CONV_F32_FROM_F64 ? 0 : (op & SLJIT_32)), dst_r, src, srcw));\n\t\t\tsrc = dst_r;\n\t\t}\n\n\t\tswitch (GET_OPCODE(op)) {\n\t\tcase SLJIT_MOV_F64:\n\t\t\tif (FAST_IS_REG(dst)) {\n\t\t\t\tif (dst == src)\n\t\t\t\t\treturn SLJIT_SUCCESS;\n\n\t\t\t\tins = (op & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), src, dst, dstw);\n\t\tcase SLJIT_CONV_F64_FROM_F32:\n\t\t\t/* Only SLJIT_CONV_F32_FROM_F64. */\n\t\t\tins = 0xb3440000 /* ledbr */;\n\t\t\tbreak;\n\t\tcase SLJIT_NEG_F64:\n\t\t\tins = (op & SLJIT_32) ? 0xb3030000 /* lcebr */ : 0xb3130000 /* lcdbr */;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSLJIT_ASSERT(GET_OPCODE(op) == SLJIT_ABS_F64);\n\t\t\tins = (op & SLJIT_32) ? 0xb3000000 /* lpebr */ : 0xb3100000 /* lpdbr */;\n\t\t\tbreak;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins | F4(dst_r) | F0(src)));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\treturn float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\n#define FLOAT_MOV(op, dst_r, src_r) \\\n\t(((op & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */) | F4(dst_r) | F0(src_r))\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r = TMP_FREG1;\n\tsljit_ins ins_r, ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tdo {\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tdst_r = dst;\n\n\t\t\tif (dst == src1)\n\t\t\t\tbreak;\n\n\t\t\tif (dst == src2) {\n\t\t\t\tif (GET_OPCODE(op) == SLJIT_ADD_F64 || GET_OPCODE(op) == SLJIT_MUL_F64) {\n\t\t\t\t\tsrc2 = src1;\n\t\t\t\t\tsrc2w = src1w;\n\t\t\t\t\tsrc1 = dst;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tFAIL_IF(push_inst(compiler, FLOAT_MOV(op, TMP_FREG1, src2)));\n\t\t\t\tsrc2 = TMP_FREG1;\n\t\t\t}\n\t\t}\n\n\t\tif (src1 & SLJIT_MEM)\n\t\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), dst_r, src1, src1w));\n\t\telse\n\t\t\tFAIL_IF(push_inst(compiler, FLOAT_MOV(op, dst_r, src1)));\n\t} while (0);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tins_r = (op & SLJIT_32) ? 0xb30a0000 /* aebr */ : 0xb31a0000 /* adbr */;\n\t\tins = (op & SLJIT_32) ? 0xed000000000a /* aeb */ : 0xed000000001a /* adb */;\n\t\tbreak;\n\tcase SLJIT_SUB_F64:\n\t\tins_r = (op & SLJIT_32) ? 0xb30b0000 /* sebr */ : 0xb31b0000 /* sdbr */;\n\t\tins = (op & SLJIT_32) ? 0xed000000000b /* seb */ : 0xed000000001b /* sdb */;\n\t\tbreak;\n\tcase SLJIT_MUL_F64:\n\t\tins_r = (op & SLJIT_32) ? 0xb3170000 /* meebr */ : 0xb31c0000 /* mdbr */;\n\t\tins = (op & SLJIT_32) ? 0xed0000000017 /* meeb */ : 0xed000000001c /* mdb */;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_ASSERT(GET_OPCODE(op) == SLJIT_DIV_F64);\n\t\tins_r = (op & SLJIT_32) ? 0xb30d0000 /* debr */ : 0xb31d0000 /* ddbr */;\n\t\tins = (op & SLJIT_32) ? 0xed000000000d /* deb */ : 0xed000000001d /* ddb */;\n\t\tbreak;\n\t}\n\n\tFAIL_IF(emit_float(compiler, ins_r, ins, dst_r, src2, src2w));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src2, src2w));\n\t\tsrc2 = TMP_FREG1;\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\treg = (dst_freg == src2) ? TMP_FREG1 : dst_freg;\n\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), reg, src1, src1w));\n\t\tsrc1 = reg;\n\t}\n\n\treturn push_inst(compiler, 0xb3720000 /* cpsdr */ | F12(src2) | F4(dst_freg) | F0(src1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tFAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)(((sljit_uw)u.imm << 32))));\n\treturn push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tFAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)u.imm));\n\treturn push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_gpr gen_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tgen_r = gpr(reg);\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64) {\n\t\tif (op & SLJIT_32) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(gen_r) | (32 << 16)));\n\t\t\tgen_r = tmp0;\n\t\t}\n\n\t\treturn push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(gen_r));\n\t}\n\n\tFAIL_IF(push_inst(compiler, 0xb3cd0000 /* lgdr */ | R4A(gen_r) | F0(freg)));\n\n\tif (!(op & SLJIT_32))\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, 0xeb000000000c /* srlg */ | R36A(gen_r) | R32A(gen_r) | (32 << 16));\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, i;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_2) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);\n\n\t\tfor (i = (mask >> 1); i != 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, 0x0700 /* 2-byte nop */));\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\n\t\tfor (i = (buffers->size + 1) >> 1; i > 0; i--)\n\t\t\tPTR_FAIL_IF(push_inst(compiler, 0x0700 /* 2-byte nop */));\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tstruct sljit_jump *jump;\n\tsljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(compiler, type & 0xff) : 0xf;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\t/* record jump */\n\tjump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);\n\tjump->addr = compiler->size;\n\n\t/* emit jump instruction */\n\ttype &= 0xff;\n\tif (type >= SLJIT_FAST_CALL)\n\t\tPTR_FAIL_IF(push_inst(compiler, brasl(link_r, 0)));\n\telse\n\t\tPTR_FAIL_IF(push_inst(compiler, brcl(mask, 0)));\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, r14));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\n\tif (src != SLJIT_IMM) {\n\t\tif (src & SLJIT_MEM) {\n\t\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\t\tFAIL_IF(load_word(compiler, src_r, src, srcw, 0 /* 64-bit */));\n\t\t}\n\n\t\t/* emit jump instruction */\n\t\tif (type >= SLJIT_FAST_CALL)\n\t\t\treturn push_inst(compiler, basr(link_r, src_r));\n\n\t\treturn push_inst(compiler, br(src_r));\n\t}\n\n\tjump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tFAIL_IF(!jump);\n\tset_jump(jump, compiler, JUMP_ADDR);\n\tjump->addr = compiler->size;\n\tjump->u.target = (sljit_uw)srcw;\n\n\ttype &= 0xff;\n\tif (type >= SLJIT_FAST_CALL)\n\t\treturn push_inst(compiler, brasl(link_r, 0));\n\n\treturn push_inst(compiler, brcl(0xf, 0));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tSLJIT_UNUSED_ARG(arg_types);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tSLJIT_ASSERT(gpr(TMP_REG2) == tmp1);\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tFAIL_IF(load_word(compiler, tmp1, src, srcw, 0 /* 64-bit */));\n\t\tsrc = TMP_REG2;\n\t\tsrcw = 0;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tFAIL_IF(push_inst(compiler, lgr(tmp1, gpr(src))));\n\t\t\tsrc = TMP_REG2;\n\t\t\tsrcw = 0;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, r14));\n\t\ttype = SLJIT_JUMP;\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\tsljit_gpr loc_r = tmp1;\n\tsljit_u8 mask = get_cc(compiler, type);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_AND:\n\tcase SLJIT_OR:\n\tcase SLJIT_XOR:\n\t\tcompiler->status_flags_state = op & SLJIT_SET_Z;\n\n\t\t/* dst is also source operand */\n\t\tif (dst & SLJIT_MEM)\n\t\t\tFAIL_IF(load_word(compiler, dst_r, dst, dstw, op & SLJIT_32));\n\n\t\tbreak;\n\tcase SLJIT_MOV32:\n\t\top |= SLJIT_32;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV:\n\t\t/* can write straight into destination */\n\t\tloc_r = dst_r;\n\t\tbreak;\n\tdefault:\n\t\tSLJIT_UNREACHABLE();\n\t}\n\n\t/* TODO(mundaym): fold into cmov helper function? */\n\t#define LEVAL(i) i(loc_r, 1, mask)\n\tif (have_lscond2()) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, loc_r, 0));\n\t\tFAIL_IF(push_inst(compiler,\n\t\t\tWHEN2(op & SLJIT_32, lochi, locghi)));\n\t} else {\n\t\tFAIL_IF(push_load_imm_inst(compiler, loc_r, 1));\n\t\tFAIL_IF(push_inst(compiler, brc(mask, 2 + 2)));\n\t\tFAIL_IF(push_load_imm_inst(compiler, loc_r, 0));\n\t}\n\t#undef LEVAL\n\n\t/* apply bitwise op and set condition codes */\n\tswitch (GET_OPCODE(op)) {\n\t#define LEVAL(i) i(dst_r, loc_r)\n\tcase SLJIT_AND:\n\t\tFAIL_IF(push_inst(compiler,\n\t\t\tWHEN2(op & SLJIT_32, nr, ngr)));\n\t\tbreak;\n\tcase SLJIT_OR:\n\t\tFAIL_IF(push_inst(compiler,\n\t\t\tWHEN2(op & SLJIT_32, or, ogr)));\n\t\tbreak;\n\tcase SLJIT_XOR:\n\t\tFAIL_IF(push_inst(compiler,\n\t\t\tWHEN2(op & SLJIT_32, xr, xgr)));\n\t\tbreak;\n\t#undef LEVAL\n\t}\n\n\t/* store result to memory if required */\n\tif (dst & SLJIT_MEM)\n\t\treturn store_word(compiler, dst_r, dst, dstw, (op & SLJIT_32));\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_ins mask;\n\tsljit_gpr src_r;\n\tsljit_gpr dst_r = gpr(dst_reg);\n\tsljit_s32 is_32bit = (type & SLJIT_32) != 0;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\ttype &= ~SLJIT_32;\n\tif (src1 == SLJIT_IMM && is_32bit)\n\t\tsrc1w = (sljit_s32)src1w;\n\n\tif (type & SLJIT_COMPARE_SELECT) {\n\t\ttype ^= SLJIT_COMPARE_SELECT;\n\t\tcompiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE;\n\n\t\tif (src1 & SLJIT_MEM) {\n\t\t\tFAIL_IF(load_word(compiler, tmp0, src1, src1w, is_32bit));\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t} else if (src1 == SLJIT_IMM) {\n\t\t\tif (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL && src1w >= 0 && src1w <= 0x7fff) {\n\t\t\t\tins = is_32bit ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */;\n\t\t\t\tFAIL_IF(push_inst(compiler, ins | R36A(gpr(src2_reg)) | (sljit_ins)src1w));\n\t\t\t\ttype ^= 0x1;\n\t\t\t} else if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL && is_s20(src1w)) {\n\t\t\t\tins = is_32bit ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */;\n\t\t\t\tFAIL_IF(push_inst(compiler, ins | R36A(gpr(src2_reg)) | ((sljit_ins)src1w & 0xffffffff)));\n\t\t\t\ttype ^= 0x1;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(push_load_imm_inst(compiler, tmp0, src1w));\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\tsrc1w = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (FAST_IS_REG(src1)) {\n\t\t\tif (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL)\n\t\t\t\tins = is_32bit ? 0x1500 /* clr */ : 0xb9210000 /* clgr */;\n\t\t\telse\n\t\t\t\tins = is_32bit ? 0x1900 /* cr */ : 0xb9200000 /* cgr */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | R4A(gpr(src1)) | R0A(gpr(src2_reg))));\n\t\t}\n\t}\n\n\tif (dst_reg != src2_reg) {\n\t\tif (src1 == dst_reg) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tif (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\t\tFAIL_IF(load_word(compiler, dst_r, src1, src1w, is_32bit));\n\t\t\t\tsrc1 = src2_reg;\n\t\t\t\tsrc1w = 0;\n\t\t\t\ttype ^= 0x1;\n\t\t\t} else\n\t\t\t\tFAIL_IF(push_inst(compiler, (is_32bit ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(gpr(src2_reg))));\n\t\t}\n\t}\n\n\tmask = get_cc(compiler, type);\n\n\tif (src1 & SLJIT_MEM) {\n\t\tif (src1 & OFFS_REG_MASK) {\n\t\t\tsrc_r = gpr(OFFS_REG(src1));\n\n\t\t\tif (src1w != 0) {\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp1) | R32A(src_r) | ((sljit_ins)(src1w & 0x3) << 16)));\n\t\t\t\tsrc_r = tmp1;\n\t\t\t}\n\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(src_r) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK))));\n\t\t\tsrc_r = tmp1;\n\t\t\tsrc1w = 0;\n\t\t} else if (!is_s20(src1w)) {\n\t\t\tFAIL_IF(push_load_imm_inst(compiler, tmp1, src1w));\n\n\t\t\tif (src1 & REG_MASK)\n\t\t\t\tFAIL_IF(push_inst(compiler, 0xb9080000 /* agr */ | R4A(tmp1) | R0A(gpr(src1 & REG_MASK))));\n\n\t\t\tsrc_r = tmp1;\n\t\t\tsrc1w = 0;\n\t\t} else\n\t\t\tsrc_r = gpr(src1 & REG_MASK);\n\n\t\tins = is_32bit ? 0xeb00000000f2 /* loc */ : 0xeb00000000e2 /* locg */;\n\t\treturn push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | R28A(src_r) | disp_s20((sljit_s32)src1w));\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tif (have_lscond2() && is_s16(src1w)) {\n\t\t\tins = is_32bit ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */;\n\t\t\treturn push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | (sljit_ins)(src1w & 0xffff) << 16);\n\t\t}\n\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp1, src1w));\n\t\tsrc_r = tmp1;\n\t} else\n\t\tsrc_r = gpr(src1);\n\n\tins = is_32bit ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */;\n\treturn push_inst(compiler, ins | (mask << 12) | R4A(dst_r) | R0A(src_r));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_ins ins;\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else {\n\t\t\tins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */;\n\t\t\tFAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src2_freg)));\n\t\t}\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tjump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);\n\tFAIL_IF(!jump);\n\n\tif (!(src1 & SLJIT_MEM)) {\n\t\tins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */;\n\t\tFAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src1)));\n\t} else\n\t\tFAIL_IF(float_mem(compiler, FLOAT_LOAD | (type & SLJIT_32), dst_freg, src1, src1w));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tlabel = sljit_emit_label(compiler);\n\tFAIL_IF(!label);\n\n\tsljit_set_label(jump, label);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_ins ins, reg1, reg2, base, offs = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tbase = gpr(mem & REG_MASK);\n\treg1 = gpr(REG_PAIR_FIRST(reg));\n\treg2 = gpr(REG_PAIR_SECOND(reg));\n\n\tif (mem & OFFS_REG_MASK) {\n\t\tmemw &= 0x3;\n\t\toffs = gpr(OFFS_REG(mem));\n\n\t\tif (memw != 0) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp1) | R32A(offs) | ((sljit_ins)memw << 16)));\n\t\t\toffs = tmp1;\n\t\t} else if (!(type & SLJIT_MEM_STORE) && (base == reg1 || base == reg2) && (offs == reg1 || offs == reg2)) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xb9f80000 | R12A(tmp1) | R4A(base) | R0A(offs)));\n\t\t\tbase = tmp1;\n\t\t\toffs = 0;\n\t\t}\n\n\t\tmemw = 0;\n\t} else if (memw < -0x80000 || memw > 0x7ffff - ((reg2 == reg1 + 1) ? 0 : SSIZE_OF(sw))) {\n\t\tFAIL_IF(push_load_imm_inst(compiler, tmp1, memw));\n\n\t\tif (base == 0)\n\t\t\tbase = tmp1;\n\t\telse\n\t\t\toffs = tmp1;\n\n\t\tmemw = 0;\n\t}\n\n\tif (offs == 0 && reg2 == (reg1 + 1)) {\n\t\tins = (type & SLJIT_MEM_STORE) ? 0xeb0000000024 /* stmg */ : 0xeb0000000004 /* lmg */;\n\t\treturn push_inst(compiler, ins | R36A(reg1) | R32A(reg2) | R28A(base) | disp_s20((sljit_s32)memw));\n\t}\n\n\tins = ((type & SLJIT_MEM_STORE) ? 0xe30000000024 /* stg */ : 0xe30000000004 /* lg */) | R32A(offs) | R28A(base);\n\n\tif (!(type & SLJIT_MEM_STORE) && base == reg1) {\n\t\tFAIL_IF(push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw))));\n\t\treturn push_inst(compiler, ins | R36A(reg1) | disp_s20((sljit_s32)memw));\n\t}\n\n\tFAIL_IF(push_inst(compiler, ins | R36A(reg1) | disp_s20((sljit_s32)memw)));\n\treturn push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw)));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tstruct addr addr;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (!(srcdst & SLJIT_MEM)) {\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins = F36(srcdst) | F32(vreg);\n\t\telse\n\t\t\tins = F36(vreg) | F32(srcdst);\n\n\t\treturn push_inst(compiler, 0xe70000000056 /* vlr */ | ins);\n\t}\n\n\tFAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1));\n\tins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset);\n\n\tif (alignment >= 4)\n\t\tins |= 4 << 12;\n\telse if (alignment == 3)\n\t\tins |= 3 << 12;\n\n\treturn push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? 0xe7000000000e /* vst */ : 0xe70000000006 /* vl */) | ins);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tstruct addr addr;\n\tsljit_gpr reg;\n\tsljit_sw sign_ext;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1));\n\t\treturn push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(vreg)\n\t\t\t| R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset) | ((sljit_ins)elem_size << 12));\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM)\n\t\t\treturn push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg));\n\n\t\treturn push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src) | ((sljit_ins)elem_size << 12));\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tsign_ext = 0x10000;\n\n\t\tswitch (elem_size) {\n\t\tcase 0:\n\t\t\tsrcw &= 0xff;\n\t\t\tsign_ext = (sljit_s8)srcw;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsrcw &= 0xffff;\n\t\t\tsign_ext = (sljit_s16)srcw;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif ((sljit_s32)srcw == (sljit_s16)srcw) {\n\t\t\t\tsrcw &= 0xffff;\n\t\t\t\tsign_ext = (sljit_s16)srcw;\n\t\t\t} else\n\t\t\t\tsrcw &= 0xffffffff;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (srcw == (sljit_s16)srcw) {\n\t\t\t\tsrcw &= 0xffff;\n\t\t\t\tsign_ext = (sljit_s16)srcw;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (sign_ext != 0x10000) {\n\t\t\tif (sign_ext == 0 || sign_ext == -1)\n\t\t\t\treturn push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg)\n\t\t\t\t\t| (sign_ext == 0 ? 0 : ((sljit_ins)0xffff << 16)));\n\n\t\t\treturn push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(vreg)\n\t\t\t\t| ((sljit_ins)srcw << 16) | ((sljit_ins)elem_size << 12));\n\t\t}\n\n\t\tpush_load_imm_inst(compiler, tmp0, srcw);\n\t\treg = tmp0;\n\t} else\n\t\treg = gpr(src);\n\n\tFAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ((sljit_ins)elem_size << 12)));\n\treturn push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(vreg) | ((sljit_ins)elem_size << 12));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tstruct addr addr;\n\tsljit_gpr reg;\n\tsljit_ins ins = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1));\n\t\tins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset);\n\t}\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tif ((srcdst & SLJIT_MEM) && lane_index == ((1 << (3 - elem_size)) - 1))\n\t\t\treturn push_inst(compiler, 0xe70000000004 /* vllez */ | ins | ((sljit_ins)elem_size << 12));\n\n\t\tif ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) {\n\t\t\tFAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(vreg)));\n\t\t\tsrcdst = TMP_FREG1;\n\t\t\tsrcdstw = 0;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg)));\n\t}\n\n\tif (srcdst & SLJIT_MEM) {\n\t\tswitch (elem_size) {\n\t\tcase 0:\n\t\t\tins |= 0xe70000000000 /* vleb */;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tins |= 0xe70000000001 /* vleh */;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tins |= 0xe70000000003 /* vlef */;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tins |= 0xe70000000002 /* vleg */;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Convert to vsteb - vsteg  */\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\tins |= 0x8;\n\n\t\treturn push_inst(compiler, ins | ((sljit_ins)lane_index << 12));\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\treturn push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(vreg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12));\n\n\t\tif (elem_size == 3) {\n\t\t\tif (lane_index == 0)\n\t\t\t\tins = F32(srcdst) | F28(vreg) | (1 << 12);\n\t\t\telse\n\t\t\t\tins = F32(vreg) | F28(srcdst);\n\n\t\t\treturn push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(vreg) | ins);\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(tmp0) | F32(srcdst) | ((sljit_ins)2 << 12)));\n\t\treturn push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12));\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tswitch (elem_size) {\n\t\tcase 0:\n\t\t\tins = 0xe70000000040 /* vleib */;\n\t\t\tsrcdstw &= 0xff;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tins = 0xe70000000041 /* vleih */;\n\t\t\tsrcdstw &= 0xffff;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif ((sljit_s32)srcdstw == (sljit_s16)srcdstw) {\n\t\t\t\tsrcdstw &= 0xffff;\n\t\t\t\tins = 0xe70000000043 /* vleif */;\n\t\t\t} else\n\t\t\t\tsrcdstw &= 0xffffffff;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (srcdstw == (sljit_s16)srcdstw) {\n\t\t\t\tsrcdstw &= 0xffff;\n\t\t\t\tins = 0xe70000000042 /* vleig */;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ins != 0)\n\t\t\treturn push_inst(compiler, ins | F36(vreg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12));\n\n\t\tpush_load_imm_inst(compiler, tmp0, srcdstw);\n\t\treg = tmp0;\n\t} else\n\t\treg = gpr(srcdst);\n\n\tins = ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12);\n\n\tif (!(type & SLJIT_SIMD_STORE))\n\t\treturn push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ins);\n\n\tFAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(vreg) | ins));\n\n\tif (!(type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tins = 0xb9060000 /* lgbr */;\n\t\tbreak;\n\tcase 1:\n\t\tins = 0xb9070000 /* lghr */;\n\t\tbreak;\n\tdefault:\n\t\tins = 0xb9140000 /* lgfr */;\n\t\tbreak;\n\t}\n\n\treturn push_inst(compiler, ins | R4A(reg) | R0A(reg));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src)\n\t\t| ((sljit_ins)src_lane_index << 16) | ((sljit_ins)elem_size << 12));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tstruct addr addr;\n\tsljit_ins ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (src & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1));\n\t\tins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset);\n\n\t\tswitch (elem2_size - elem_size) {\n\t\tcase 1:\n\t\t\tins |= 0xe70000000002 /* vleg */;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tins |= 0xe70000000003 /* vlef */;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tins |= 0xe70000000001 /* vleh */;\n\t\t\tbreak;\n\t\t}\n\n\t\tFAIL_IF(push_inst(compiler, ins));\n\t\tsrc = vreg;\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tFAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(vreg) | F32(src) | (2 << 12)));\n\t\tFAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(vreg) | F32(vreg) | (32 << 16) | (3 << 12)));\n\t\treturn push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(vreg) | F32(vreg) | (2 << 12));\n\t}\n\n\tins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(vreg);\n\n\tdo {\n\t\tFAIL_IF(push_inst(compiler, ins | F32(src) | ((sljit_ins)elem_size << 12)));\n\t\tsrc = vreg;\n\t} while (++elem_size < elem2_size);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_gpr dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tpush_load_imm_inst(compiler, tmp0, (sljit_sw)0x4048505860687078);\n\t\tpush_load_imm_inst(compiler, tmp1, (sljit_sw)0x0008101820283038);\n\t\tFAIL_IF(push_inst(compiler, 0xe70000000062 /* vlvgp */ | F36(TMP_FREG1) | R32A(tmp1) | R28A(tmp0)));\n\t\tbreak;\n\tcase 1:\n\t\tpush_load_imm_inst(compiler, tmp0, (sljit_sw)0x0010203040506070);\n\t\tbreak;\n\tcase 2:\n\t\tpush_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808000204060);\n\t\tbreak;\n\tdefault:\n\t\tpush_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808080800040);\n\t\tbreak;\n\t}\n\n\tif (elem_size != 0)\n\t\tFAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(TMP_FREG1) | R32A(tmp0) | (1 << 16) | (3 << 12)));\n\n\tFAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(vreg) | F28(TMP_FREG1)));\n\n\tdst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;\n\tFAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(dst_r) | F32(TMP_FREG1)\n\t\t| (elem_size == 0 ? ((3 << 16) | (1 << 12)) : (7 << 16))));\n\n\tif (dst_r == tmp0)\n\t\treturn store_word(compiler, tmp0, dst, dstw, type & SLJIT_32);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment;\n\tstruct addr addr;\n\tsljit_ins ins = 0, load_ins;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tif (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\tins = 0xe70000000068 /* vn */;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\tins = 0xe7000000006a /* vo */;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\tins = 0xe7000000006d /* vx */;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tins = 0xe7000000008c /* vperm */;\n\t\tbreak;\n\t}\n\n\tif (src2 & SLJIT_MEM) {\n\t\tFAIL_IF(make_addr_bx(compiler, &addr, src2, src2w, tmp1));\n\t\tload_ins = 0xe70000000006 /* vl */ | F36(TMP_FREG1) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset);\n\t\talignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\n\t\tif (alignment >= 4)\n\t\t\tload_ins |= 4 << 12;\n\t\telse if (alignment == 3)\n\t\t\tload_ins |= 3 << 12;\n\n\t\tFAIL_IF(push_inst(compiler, load_ins));\n\t\tsrc2 = TMP_FREG1;\n\t}\n\n\tif (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE)\n\t\treturn push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src1_vreg) | F12(src2));\n\n\treturn push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src2));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_LS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_U32:\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\tif (op & SLJIT_ATOMIC_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0);\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_ins ins;\n\tsljit_gpr tmp_r = gpr(temp_reg);\n\tsljit_gpr mem_r = gpr(mem_reg);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\n\tif (op & SLJIT_ATOMIC_USE_LS)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_U32:\n\t\tins = 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r);\n\t\tbreak;\n\tcase SLJIT_MOV:\n\tcase SLJIT_MOV_P:\n\t\tins = 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r);\n\t\tbreak;\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\treturn push_inst(compiler, ins);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Other instructions                                                   */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tstruct sljit_const *const_;\n\tsljit_gpr dst_r;\n\tint is_32 = 0;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const((struct sljit_const*)const_, compiler);\n\n\tdst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tif (init_value & 0x100)\n\t\t\tinit_value |= 0xff00;\n\t\telse\n\t\t\tinit_value &= 0xff;\n\n\t\tPTR_FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(dst_r) | (sljit_ins)(init_value & 0xffff)));\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(store_byte(compiler, dst_r, dst, dstw));\n\t\treturn (struct sljit_const*)const_;\n\n\tcase SLJIT_MOV32:\n\t\tis_32 = 1;\n\t\tSLJIT_FALLTHROUGH\n\tcase SLJIT_MOV_S32:\n\t\tPTR_FAIL_IF(push_inst(compiler, 0xc00100000000 /* lgfi */ | R36A(dst_r) | (sljit_ins)(init_value & 0xffffffff)));\n\t\tbreak;\n\n\tdefault:\n\t\tPTR_FAIL_IF(push_inst(compiler, 0xc00f00000000 /* llilf */ | R36A(dst_r) | (sljit_ins)(init_value & 0xffffffff)));\n\t\tPTR_FAIL_IF(push_inst(compiler, 0xc00800000000 /* iihf */ | R36A(dst_r) | (sljit_ins)((init_value >> 32) & 0xffffffff)));\n\t\tbreak;\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, is_32));\n\n\treturn (struct sljit_const*)const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\t/* Update the constant pool. */\n\tsljit_uw *ptr = (sljit_uw *)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);\n\t*ptr = new_target;\n\tSLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);\n\tSLJIT_CACHE_FLUSH(ptr, ptr + 1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tsljit_u16 *inst = (sljit_u16*)addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n\t\tSLJIT_ASSERT((inst[0] & 0xff0f) == 0xa709 /* lghi */);\n\n\t\tif (new_constant & 0x100)\n\t\t\tnew_constant |= 0xff00;\n\t\telse\n\t\t\tnew_constant &= 0xff;\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);\n\t\tinst[1] = (sljit_u16)new_constant;\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);\n\t\tinst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 2);\n\t\treturn;\n\n\tcase SLJIT_MOV32:\n\tcase SLJIT_MOV_S32:\n\t\tSLJIT_ASSERT((inst[0] & 0xff0f) == 0xc001 /* lgfi */);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 3, 0);\n\t\tinst[1] = (sljit_u16)(new_constant >> 16);\n\t\tinst[2] = (sljit_u16)new_constant;\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 3, 1);\n\t\tinst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 3);\n\t\treturn;\n\n\tdefault:\n\t\tSLJIT_ASSERT((inst[0] & 0xff0f) == 0xc00f /* llilf */ && (inst[3] & 0xff0f) == 0xc008 /* iihf */);\n\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);\n\t\tinst[1] = (sljit_u16)(new_constant >> 16);\n\t\tinst[2] = (sljit_u16)new_constant;\n\t\tinst[4] = (sljit_u16)(new_constant >> 48);\n\t\tinst[5] = (sljit_u16)(new_constant >> 32);\n\t\tSLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);\n\t\tinst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);\n\t\tSLJIT_CACHE_FLUSH(inst, inst + 6);\n\t\treturn;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_gpr dst_r, target_r;\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tdst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;\n\n\tif (op != SLJIT_ADD_ABS_ADDR)\n\t\ttarget_r = dst_r;\n\telse {\n\t\ttarget_r = tmp1;\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tPTR_FAIL_IF(load_word(compiler, dst_r, dst, dstw, 0));\n\t}\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n\t/* Might be converted to lgrl. */\n\tPTR_FAIL_IF(push_inst(compiler, 0xc00000000000 /* larl */ | R36A(target_r)));\n\n\tif (op == SLJIT_ADD_ABS_ADDR)\n\t\tPTR_FAIL_IF(push_inst(compiler, 0xb90a0000 /* algr */ | R4A(dst_r) | R0A(tmp1)));\n\n\tif (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0));\n\n\treturn jump;\n}\n\n/* TODO(carenas): EVAL probably should move up or be refactored */\n#undef WHEN2\n#undef EVAL\n\n#undef tmp1\n#undef tmp0\n\n/* TODO(carenas): undef other macros that spill like is_u12? */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* x86 32-bit arch dependent functions. */\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)\n{\n\tsljit_u8 *inst;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));\n\tFAIL_IF(!inst);\n\tINC_SIZE(1 + sizeof(sljit_sw));\n\t*inst++ = opcode;\n\tsljit_unaligned_store_sw(inst, imm);\n\treturn SLJIT_SUCCESS;\n}\n\n/* Size contains the flags as well. */\nstatic sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw size,\n\t/* The register or immediate operand. */\n\tsljit_s32 a, sljit_sw imma,\n\t/* The general operand (not immediate). */\n\tsljit_s32 b, sljit_sw immb)\n{\n\tsljit_u8 *inst;\n\tsljit_u8 *buf_ptr;\n\tsljit_u8 reg_map_b;\n\tsljit_uw flags = size;\n\tsljit_uw inst_size;\n\n\t/* Both cannot be switched on. */\n\tSLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));\n\t/* Size flags not allowed for typed instructions. */\n\tSLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);\n\t/* Both size flags cannot be switched on. */\n\tSLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));\n\t/* SSE2 and immediate is not possible. */\n\tSLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2));\n\tSLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\t\t& ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0);\n\tSLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT);\n\n\tsize &= 0xf;\n\t/* The mod r/m byte is always present. */\n\tinst_size = size + 1;\n\n\tif (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\tinst_size++;\n\n\t/* Calculate size of b. */\n\tif (b & SLJIT_MEM) {\n\t\tif (!(b & REG_MASK))\n\t\t\tinst_size += sizeof(sljit_sw);\n\t\telse {\n\t\t\tif (immb != 0 && !(b & OFFS_REG_MASK)) {\n\t\t\t\t/* Immediate operand. */\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\telse\n\t\t\t\t\tinst_size += sizeof(sljit_sw);\n\t\t\t} else if (reg_map[b & REG_MASK] == 5) {\n\t\t\t\t/* Swap registers if possible. */\n\t\t\t\tif ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_map[OFFS_REG(b)] != 5)\n\t\t\t\t\tb = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);\n\t\t\t\telse\n\t\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t}\n\n\t\t\tif (reg_map[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))\n\t\t\t\tb |= TO_OFFS_REG(SLJIT_SP);\n\n\t\t\tif (b & OFFS_REG_MASK)\n\t\t\t\tinst_size += 1; /* SIB byte. */\n\t\t}\n\t}\n\n\t/* Calculate size of a. */\n\tif (a == SLJIT_IMM) {\n\t\tif (flags & EX86_BIN_INS) {\n\t\t\tif (imma <= 127 && imma >= -128) {\n\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\tflags |= EX86_BYTE_ARG;\n\t\t\t} else\n\t\t\t\tinst_size += sizeof(sljit_sw);\n\t\t} else if (flags & EX86_SHIFT_INS) {\n\t\t\tSLJIT_ASSERT(imma <= 0x1f);\n\t\t\tif (imma != 1) {\n\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\tflags |= EX86_BYTE_ARG;\n\t\t\t}\n\t\t} else if (flags & EX86_BYTE_ARG)\n\t\t\tinst_size += sizeof(sljit_s8);\n\t\telse if (flags & EX86_HALF_ARG)\n\t\t\tinst_size += sizeof(sljit_s16);\n\t\telse\n\t\t\tinst_size += sizeof(sljit_sw);\n\t} else\n\t\tSLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);\n\tPTR_FAIL_IF(!inst);\n\n\t/* Encoding the byte. */\n\tINC_SIZE(inst_size);\n\tif (flags & EX86_PREF_F2)\n\t\t*inst++ = 0xf2;\n\telse if (flags & EX86_PREF_F3)\n\t\t*inst++ = 0xf3;\n\telse if (flags & EX86_PREF_66)\n\t\t*inst++ = 0x66;\n\n\tbuf_ptr = inst + size;\n\n\t/* Encode mod/rm byte. */\n\tif (!(flags & EX86_SHIFT_INS)) {\n\t\tif ((flags & EX86_BIN_INS) && a == SLJIT_IMM)\n\t\t\t*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;\n\n\t\tif (a == SLJIT_IMM)\n\t\t\t*buf_ptr = 0;\n\t\telse if (!(flags & EX86_SSE2_OP1))\n\t\t\t*buf_ptr = U8(reg_map[a] << 3);\n\t\telse\n\t\t\t*buf_ptr = U8(freg_map[a] << 3);\n\t} else {\n\t\tif (a == SLJIT_IMM) {\n\t\t\tif (imma == 1)\n\t\t\t\t*inst = GROUP_SHIFT_1;\n\t\t\telse\n\t\t\t\t*inst = GROUP_SHIFT_N;\n\t\t} else\n\t\t\t*inst = GROUP_SHIFT_CL;\n\t\t*buf_ptr = 0;\n\t}\n\n\tif (!(b & SLJIT_MEM)) {\n\t\t*buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : freg_map[b]));\n\t\tbuf_ptr++;\n\t} else if (b & REG_MASK) {\n\t\treg_map_b = reg_map[b & REG_MASK];\n\n\t\tif (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {\n\t\t\tif (immb != 0 || reg_map_b == 5) {\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\t*buf_ptr |= 0x40;\n\t\t\t\telse\n\t\t\t\t\t*buf_ptr |= 0x80;\n\t\t\t}\n\n\t\t\tif (!(b & OFFS_REG_MASK))\n\t\t\t\t*buf_ptr++ |= reg_map_b;\n\t\t\telse {\n\t\t\t\tbuf_ptr[0] |= 0x04;\n\t\t\t\tbuf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3));\n\t\t\t\tbuf_ptr += 2;\n\t\t\t}\n\n\t\t\tif (immb != 0 || reg_map_b == 5) {\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\t*buf_ptr++ = U8(immb); /* 8 bit displacement. */\n\t\t\t\telse {\n\t\t\t\t\tsljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */\n\t\t\t\t\tbuf_ptr += sizeof(sljit_sw);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (reg_map_b == 5)\n\t\t\t\t*buf_ptr |= 0x40;\n\n\t\t\tbuf_ptr[0] |= 0x04;\n\t\t\tbuf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6));\n\t\t\tbuf_ptr += 2;\n\n\t\t\tif (reg_map_b == 5)\n\t\t\t\t*buf_ptr++ = 0;\n\t\t}\n\t} else {\n\t\t*buf_ptr++ |= 0x05;\n\t\tsljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */\n\t\tbuf_ptr += sizeof(sljit_sw);\n\t}\n\n\tif (a == SLJIT_IMM) {\n\t\tif (flags & EX86_BYTE_ARG)\n\t\t\t*buf_ptr = U8(imma);\n\t\telse if (flags & EX86_HALF_ARG)\n\t\t\tsljit_unaligned_store_s16(buf_ptr, (sljit_s16)imma);\n\t\telse if (!(flags & EX86_SHIFT_INS))\n\t\t\tsljit_unaligned_store_sw(buf_ptr, imma);\n\t}\n\n\treturn inst;\n}\n\nstatic sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op,\n\t/* The first and second register operand. */\n\tsljit_s32 a, sljit_s32 v,\n\t/* The general operand (not immediate). */\n\tsljit_s32 b, sljit_sw immb)\n{\n\tsljit_u8 *inst;\n\tsljit_u8 vex = 0;\n\tsljit_u8 vex_m = 0;\n\tsljit_uw size;\n\n\tSLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\t\t& ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0);\n\n\tif (op & VEX_OP_0F38)\n\t\tvex_m = 0x2;\n\telse if (op & VEX_OP_0F3A)\n\t\tvex_m = 0x3;\n\n\tif (op & VEX_W) {\n\t\tif (vex_m == 0)\n\t\t\tvex_m = 0x1;\n\n\t\tvex |= 0x80;\n\t}\n\n\tif (op & EX86_PREF_66)\n\t\tvex |= 0x1;\n\telse if (op & EX86_PREF_F2)\n\t\tvex |= 0x3;\n\telse if (op & EX86_PREF_F3)\n\t\tvex |= 0x2;\n\n\top &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3);\n\n\tif (op & VEX_256)\n\t\tvex |= 0x4;\n\n\tvex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3));\n\n\tsize = op & ~(sljit_uw)0xff;\n\tsize |= (vex_m == 0) ? 3 : 4;\n\n\tinst = emit_x86_instruction(compiler, size, a, 0, b, immb);\n\tFAIL_IF(!inst);\n\n\tif (vex_m == 0) {\n\t\tinst[0] = 0xc5;\n\t\tinst[1] = U8(vex | 0x80);\n\t\tinst[2] = U8(op);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tinst[0] = 0xc4;\n\tinst[1] = U8(vex_m | 0xe0);\n\tinst[2] = vex;\n\tinst[3] = U8(op);\n\treturn SLJIT_SUCCESS;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Enter / return                                                       */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)\n{\n\tsljit_uw type = jump->flags >> TYPE_SHIFT;\n\n\tif (type == SLJIT_JUMP) {\n\t\t*code_ptr++ = JMP_i32;\n\t} else if (type >= SLJIT_FAST_CALL) {\n\t\t*code_ptr++ = CALL_i32;\n\t} else {\n\t\t*code_ptr++ = GROUP_0F;\n\t\t*code_ptr++ = get_jump_code(type);\n\t}\n\n\tjump->addr = (sljit_uw)code_ptr;\n\n\tif (jump->flags & JUMP_ADDR)\n\t\tsljit_unaligned_store_sw(code_ptr, (sljit_sw)(jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset));\n\telse\n\t\tjump->flags |= PATCH_MW;\n\tcode_ptr += 4;\n\n\treturn code_ptr;\n}\n\n#define ENTER_TMP_TO_R4\t\t0x00001\n#define ENTER_TMP_TO_S\t\t0x00002\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 word_arg_count, saved_arg_count, float_arg_count;\n\tsljit_s32 size, args_size, types, status;\n\tsljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\tsljit_u8 *inst;\n#ifdef _WIN32\n\tsljit_s32 r2_offset = -1;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\n\t/* Emit ENDBR32 at function entry if needed.  */\n\tFAIL_IF(emit_endbranch(compiler));\n\n\tSLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\tword_arg_count = 0;\n\tstatus = 0;\n\n\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\targs_size = 3 * SSIZE_OF(sw);\n\n\t\twhile (arg_types) {\n\t\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\t\tword_arg_count++;\n\t\t\t\tif (word_arg_count >= 4)\n\t\t\t\t\tstatus |= ENTER_TMP_TO_R4;\n\t\t\t}\n\n\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t}\n\n\t\tcompiler->args_size = 0;\n\t} else {\n\t\ttypes = arg_types;\n\t\tsaved_arg_count = 0;\n\t\tfloat_arg_count = 0;\n\t\targs_size = SSIZE_OF(sw);\n\t\twhile (types) {\n\t\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\t\tfloat_arg_count++;\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, 0, float_arg_count, SLJIT_MEM1(SLJIT_SP), args_size));\n\t\t\t\targs_size += SSIZE_OF(f64);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\t\tfloat_arg_count++;\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, 1, float_arg_count, SLJIT_MEM1(SLJIT_SP), args_size));\n\t\t\t\targs_size += SSIZE_OF(f32);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tword_arg_count++;\n\n\t\t\t\tif (!(types & SLJIT_ARG_TYPE_SCRATCH_REG))\n\t\t\t\t\tsaved_arg_count++;\n\n\t\t\t\tif (word_arg_count == 4) {\n\t\t\t\t\tif (types & SLJIT_ARG_TYPE_SCRATCH_REG) {\n\t\t\t\t\t\tstatus |= ENTER_TMP_TO_R4;\n\t\t\t\t\t\targ_types &= ~(SLJIT_ARG_FULL_MASK << 3 * SLJIT_ARG_SHIFT);\n\t\t\t\t\t} else if (saved_arg_count == 4) {\n\t\t\t\t\t\tstatus |= ENTER_TMP_TO_S;\n\t\t\t\t\t\targ_types &= ~(SLJIT_ARG_FULL_MASK << 3 * SLJIT_ARG_SHIFT);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\targs_size += SSIZE_OF(sw);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t\t}\n\n\t\targs_size -= SSIZE_OF(sw);\n\t\tcompiler->args_size = args_size;\n\t}\n\n\tsize = (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - kept_saveds_count;\n\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\tsize++;\n\n\tif (size != 0) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(size + 1));\n\t\tFAIL_IF(!inst);\n\n\t\tINC_SIZE((sljit_uw)size);\n\n\t\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\t\tPUSH_REG(reg_map[TMP_REG1]);\n\n\t\tif ((saveds > 2 && kept_saveds_count <= 2) || scratches > 9)\n\t\t\tPUSH_REG(reg_map[SLJIT_S2]);\n\t\tif ((saveds > 1 && kept_saveds_count <= 1) || scratches > 10)\n\t\t\tPUSH_REG(reg_map[SLJIT_S1]);\n\t\tif ((saveds > 0 && kept_saveds_count == 0) || scratches > 11)\n\t\t\tPUSH_REG(reg_map[SLJIT_S0]);\n\n\t\tsize *= SSIZE_OF(sw);\n\t}\n\n\tif (status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S))\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), args_size + size);\n\n\tsize += SSIZE_OF(sw);\n\n\tlocal_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size + size + 0xf) & ~0xf) - size;\n\tcompiler->local_size = local_size;\n\n\tword_arg_count = 0;\n\tsaved_arg_count = 0;\n\targs_size = size;\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\targs_size += SSIZE_OF(f64);\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targs_size += SSIZE_OF(f32);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\t\t\tSLJIT_ASSERT(word_arg_count <= 3 || (word_arg_count == 4 && !(status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S))));\n\n\t\t\tif (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {\n#ifdef _WIN32\n\t\t\t\tif (word_arg_count == 3 && local_size > 4 * 4096)\n\t\t\t\t\tr2_offset = local_size + args_size;\n\t\t\t\telse\n#endif\n\t\t\t\t\tEMIT_MOV(compiler, word_arg_count, 0, SLJIT_MEM1(SLJIT_SP), args_size);\n\n\t\t\t} else {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_S0 - saved_arg_count, 0, SLJIT_MEM1(SLJIT_SP), args_size);\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\n\t\t\targs_size += SSIZE_OF(sw);\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tSLJIT_ASSERT(SLJIT_LOCALS_OFFSET > 0);\n\n#ifdef _WIN32\n\tSLJIT_ASSERT(r2_offset == -1 || local_size > 4 * 4096);\n\n\tif (local_size > 4096) {\n\t\tif (local_size <= 4 * 4096) {\n\t\t\tBINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096);\n\n\t\t\tif (local_size > 2 * 4096)\n\t\t\t\tBINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);\n\t\t\tif (local_size > 3 * 4096)\n\t\t\t\tBINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);\n\t\t}\n\t\telse {\n\t\t\tif (options & SLJIT_ENTER_REG_ARG) {\n\t\t\t\tSLJIT_ASSERT(r2_offset == -1);\n\n\t\t\t\tinst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 1));\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\tINC_SIZE(1);\n\t\t\t\tPUSH_REG(reg_map[SLJIT_R2]);\n\n\t\t\t\tlocal_size -= SSIZE_OF(sw);\n\t\t\t\tr2_offset = local_size;\n\t\t\t}\n\n\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_IMM, local_size >> 12);\n\n\t\t\tBINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -4096);\n\t\t\tBINARY_IMM32(SUB, 4096, SLJIT_SP, 0);\n\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(2);\n\t\t\tinst[0] = LOOP_i8;\n\t\t\tinst[1] = (sljit_u8)-16;\n\t\t\tlocal_size &= 0xfff;\n\t\t}\n\t}\n\n\tif (local_size > 0) {\n\t\tBINARY_IMM32(OR, 0, SLJIT_MEM1(SLJIT_SP), -local_size);\n\t\tBINARY_IMM32(SUB, local_size, SLJIT_SP, 0);\n\t}\n\n\tif (r2_offset != -1)\n\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), r2_offset);\n\n#else /* !_WIN32 */\n\n\tSLJIT_ASSERT(local_size > 0);\n\n\tBINARY_IMM32(SUB, local_size, SLJIT_SP, 0);\n\n#endif /* _WIN32 */\n\n\tsize = SLJIT_LOCALS_OFFSET_BASE - SSIZE_OF(sw);\n\tkept_saveds_count = SLJIT_R3 - kept_saveds_count;\n\n\twhile (saved_arg_count > 3) {\n\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), size, kept_saveds_count, 0);\n\t\tkept_saveds_count++;\n\t\tsize -= SSIZE_OF(sw);\n\t\tsaved_arg_count--;\n\t}\n\n\tif (status & (ENTER_TMP_TO_R4 | ENTER_TMP_TO_S)) {\n\t\tif (status & ENTER_TMP_TO_R4)\n\t\t\tsize = 2 * SSIZE_OF(sw);\n\n\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), size, TMP_REG1, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 args_size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\targs_size = 0;\n\n\tif (!(options & SLJIT_ENTER_REG_ARG)) {\n\t\twhile (arg_types) {\n\t\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\t\targs_size += SSIZE_OF(f64);\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\t\targs_size += SSIZE_OF(f32);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\targs_size += SSIZE_OF(sw);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t\t}\n\t}\n\n\tcompiler->args_size = args_size;\n\n\t/* [esp+0] for saving temporaries and for function calls. */\n\n\tsaveds = (1 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(options)) * SSIZE_OF(sw);\n\n\t/* Saving ebp. */\n\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\tsaveds += SSIZE_OF(sw);\n\n\tcompiler->local_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size + saveds + 0xf) & ~0xf) - saveds;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\tsljit_s32 local_size, saveds;\n\tsljit_uw size;\n\tsljit_u8 *inst;\n\n\tsize = (sljit_uw)((compiler->scratches > 9 ? (compiler->scratches - 9) : 0) +\n\t\t(compiler->saveds <= 3 ? compiler->saveds : 3) - kept_saveds_count);\n\n\tlocal_size = compiler->local_size;\n\n\tif (!(compiler->options & SLJIT_ENTER_REG_ARG))\n\t\tsize++;\n\telse if (is_return_to && size == 0) {\n\t\tlocal_size += SSIZE_OF(sw);\n\t\tis_return_to = 0;\n\t}\n\n\tif (local_size > 0)\n\t\tBINARY_IMM32(ADD, local_size, SLJIT_SP, 0);\n\n\tif (size == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\n\tINC_SIZE(size);\n\n\tsaveds = compiler->saveds;\n\n\tif ((saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11)\n\t\tPOP_REG(reg_map[SLJIT_S0]);\n\tif ((saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10)\n\t\tPOP_REG(reg_map[SLJIT_S1]);\n\tif ((saveds > 2 && kept_saveds_count <= 2) || compiler->scratches > 9)\n\t\tPOP_REG(reg_map[SLJIT_S2]);\n\n\tif (!(compiler->options & SLJIT_ENTER_REG_ARG))\n\t\tPOP_REG(reg_map[TMP_REG1]);\n\n\tif (is_return_to)\n\t\tBINARY_IMM32(ADD, sizeof(sljit_sw), SLJIT_SP, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tSLJIT_ASSERT(compiler->args_size >= 0);\n\tSLJIT_ASSERT(compiler->local_size > 0);\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\n\treturn emit_byte(compiler, RET_near);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 src_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tif ((src & SLJIT_MEM) || (src > SLJIT_R2 && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\t\tsrc_r = (compiler->options & SLJIT_ENTER_REG_ARG) ? TMP_REG1 : SLJIT_R1;\n\n\t\tEMIT_MOV(compiler, src_r, 0, src, srcw);\n\t\tsrc = src_r;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Call / return instructions                                           */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_s32 call_get_stack_size(sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)\n{\n\tsljit_sw stack_size = 0;\n\tsljit_s32 word_arg_count = 0;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tstack_size += SSIZE_OF(f64);\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tstack_size += SSIZE_OF(f32);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\t\t\tstack_size += SSIZE_OF(sw);\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (word_arg_count_ptr)\n\t\t*word_arg_count_ptr = word_arg_count;\n\n\tif (stack_size <= 4 * SSIZE_OF(sw))\n\t\treturn 0;\n\n\treturn ((stack_size - (4 * SSIZE_OF(sw)) + 0xf) & ~0xf);\n}\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler,\n\tsljit_s32 arg_types, sljit_sw stack_size, sljit_s32 word_arg_count, sljit_s32 keep_tmp1)\n{\n\tsljit_s32 float_arg_count = 0, arg4_reg = 0, arg_offset;\n\tsljit_u8 *inst;\n\n\tif (word_arg_count >= 4) {\n\t\targ4_reg = SLJIT_R0;\n\n\t\tif (!keep_tmp1) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));\n\t\t\targ4_reg = TMP_REG1;\n\t\t}\n\t}\n\n\tif (stack_size > 0)\n\t\tBINARY_IMM32(SUB, stack_size, SLJIT_SP, 0);\n\n\targ_offset = 0;\n\tword_arg_count = 0;\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tfloat_arg_count++;\n\t\t\tFAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), arg_offset, float_arg_count));\n\t\t\targ_offset += SSIZE_OF(f64);\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tfloat_arg_count++;\n\t\t\tFAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), arg_offset, float_arg_count));\n\t\t\targ_offset += SSIZE_OF(f32);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), arg_offset, (word_arg_count >= 4) ? arg4_reg : word_arg_count, 0);\n\n\t\t\tif (word_arg_count == 1 && arg4_reg == SLJIT_R0)\n\t\t\t\tEMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw) + stack_size);\n\n\t\t\targ_offset += SSIZE_OF(sw);\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 post_call_with_args(struct sljit_compiler *compiler,\n\tsljit_s32 arg_types, sljit_s32 stack_size)\n{\n\tsljit_u8 *inst;\n\tsljit_s32 single;\n\n\tif (stack_size > 0)\n\t\tBINARY_IMM32(ADD, stack_size, SLJIT_SP, 0);\n\n\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)\n\t\treturn SLJIT_SUCCESS;\n\n\tsingle = ((arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3);\n\tFAIL_IF(!inst);\n\tINC_SIZE(3);\n\tinst[0] = single ? FSTPS : FSTPD;\n\tinst[1] = (0x03 << 3) | 0x04;\n\tinst[2] = (0x04 << 3) | reg_map[SLJIT_SP];\n\n\treturn emit_sse2_load(compiler, single, SLJIT_FR0, SLJIT_MEM1(SLJIT_SP), 0);\n}\n\nstatic sljit_s32 tail_call_with_args(struct sljit_compiler *compiler,\n\tsljit_s32 *extra_space, sljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_sw args_size, saved_regs_size;\n\tsljit_sw types, word_arg_count, float_arg_count;\n\tsljit_sw stack_size, prev_stack_size, min_size, offset;\n\tsljit_sw word_arg4_offset;\n\tsljit_u8 r2_offset = 0;\n\tsljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\tsljit_u8* inst;\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tsaved_regs_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0)\n\t\t+ (compiler->saveds <= 3 ? compiler->saveds : 3) - kept_saveds_count) * SSIZE_OF(sw);\n\n\tword_arg_count = 0;\n\tfloat_arg_count = 0;\n\targ_types >>= SLJIT_ARG_SHIFT;\n\ttypes = 0;\n\targs_size = 0;\n\n\twhile (arg_types != 0) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\targs_size += SSIZE_OF(f64);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targs_size += SSIZE_OF(f32);\n\t\t\tfloat_arg_count++;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tword_arg_count++;\n\t\t\targs_size += SSIZE_OF(sw);\n\t\t\tbreak;\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (args_size <= compiler->args_size) {\n\t\t*extra_space = 0;\n\t\tstack_size = args_size + SSIZE_OF(sw) + saved_regs_size;\n\n\t\toffset = stack_size + compiler->local_size;\n\n\t\tif (src != SLJIT_IMM && src != SLJIT_R0) {\n\t\t\tif (word_arg_count >= 1) {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0);\n\t\t\t\tr2_offset = sizeof(sljit_sw);\n\t\t\t}\n\t\t\tEMIT_MOV(compiler, SLJIT_R0, 0, src, srcw);\n\t\t}\n\n\t\twhile (types != 0) {\n\t\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\t\toffset -= SSIZE_OF(f64);\n\t\t\t\tFAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));\n\t\t\t\tfloat_arg_count--;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\t\toffset -= SSIZE_OF(f32);\n\t\t\t\tFAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));\n\t\t\t\tfloat_arg_count--;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tswitch (word_arg_count) {\n\t\t\t\tcase 1:\n\t\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\t\tif (r2_offset != 0) {\n\t\t\t\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 0);\n\t\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);\n\t\t\t\t\t} else\n\t\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R0, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R1, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tword_arg_count--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t\t}\n\n\t\treturn emit_stack_frame_release(compiler, 0);\n\t}\n\n\tstack_size = args_size + SSIZE_OF(sw);\n\n\tif (word_arg_count >= 1 && src != SLJIT_IMM && src != SLJIT_R0) {\n\t\tr2_offset = SSIZE_OF(sw);\n\t\tstack_size += SSIZE_OF(sw);\n\t}\n\n\tif (word_arg_count >= 3)\n\t\tstack_size += SSIZE_OF(sw);\n\n\tprev_stack_size = SSIZE_OF(sw) + saved_regs_size;\n\tmin_size = prev_stack_size + compiler->local_size;\n\n\tword_arg4_offset = 2 * SSIZE_OF(sw);\n\n\tif (stack_size > min_size) {\n\t\tBINARY_IMM32(SUB, stack_size - min_size, SLJIT_SP, 0);\n\t\tif (src == SLJIT_MEM1(SLJIT_SP))\n\t\t\tsrcw += stack_size - min_size;\n\t\tword_arg4_offset += stack_size - min_size;\n\t}\n\telse\n\t\tstack_size = min_size;\n\n\tif (word_arg_count >= 3) {\n\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), r2_offset, SLJIT_R2, 0);\n\n\t\tif (word_arg_count >= 4)\n\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), word_arg4_offset);\n\t}\n\n\tif (src != SLJIT_IMM && src != SLJIT_R0) {\n\t\tif (word_arg_count >= 1) {\n\t\t\tSLJIT_ASSERT(r2_offset == sizeof(sljit_sw));\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0);\n\t\t}\n\t\tEMIT_MOV(compiler, SLJIT_R0, 0, src, srcw);\n\t}\n\n\t/* Restore saved registers. */\n\toffset = stack_size - 2 * SSIZE_OF(sw);\n\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), offset);\n\n\tif (compiler->saveds > 2 || compiler->scratches > 9) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tEMIT_MOV(compiler, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), offset);\n\t}\n\tif ((compiler->saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tEMIT_MOV(compiler, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_SP), offset);\n\t}\n\tif ((compiler->saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tEMIT_MOV(compiler, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), offset);\n\t}\n\n\t/* Copy fourth argument and return address. */\n\toffset = stack_size - SSIZE_OF(sw);\n\t*extra_space = args_size;\n\n\tif (word_arg_count >= 4) {\n\t\toffset -= SSIZE_OF(sw);\n\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);\n\t}\n\n\twhile (types != 0) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\toffset -= SSIZE_OF(f64);\n\t\t\tFAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\toffset -= SSIZE_OF(f32);\n\t\t\tFAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), offset, float_arg_count));\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tswitch (word_arg_count) {\n\t\t\tcase 1:\n\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\tif (r2_offset != 0) {\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), 0);\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);\n\t\t\t\t} else\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R0, 0);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R1, 0);\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\toffset -= SSIZE_OF(sw);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), r2_offset);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, SLJIT_R2, 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tword_arg_count--;\n\t\t\tbreak;\n\t\t}\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tSLJIT_ASSERT(offset >= 0);\n\n\tif (offset == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tBINARY_IMM32(ADD, offset, SLJIT_SP, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_tail_call_end(struct sljit_compiler *compiler, sljit_s32 extra_space)\n{\n\t/* Called when stack consumption cannot be reduced to 0. */\n\tsljit_u8 *inst;\n\n\tBINARY_IMM32(ADD, extra_space, SLJIT_SP, 0);\n\treturn emit_byte(compiler, RET_near);\n}\n\nstatic sljit_s32 tail_call_reg_arg_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)\n{\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 kept_saveds_count, offset;\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)\n\t\t\tword_arg_count++;\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (word_arg_count < 4)\n\t\treturn SLJIT_SUCCESS;\n\n\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), 2 * SSIZE_OF(sw));\n\n\tkept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\toffset = compiler->local_size + 3 * SSIZE_OF(sw);\n\n\tif ((compiler->saveds > 0 && kept_saveds_count == 0) || compiler->scratches > 11)\n\t\toffset += SSIZE_OF(sw);\n\tif ((compiler->saveds > 1 && kept_saveds_count <= 1) || compiler->scratches > 10)\n\t\toffset += SSIZE_OF(sw);\n\tif ((compiler->saveds > 2 && kept_saveds_count <= 2) || compiler->scratches > 9)\n\t\toffset += SSIZE_OF(sw);\n\n\treturn emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), offset, TMP_REG1, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tstruct sljit_jump *jump;\n\tsljit_sw stack_size = 0;\n\tsljit_s32 word_arg_count;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\t\tPTR_FAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));\n\t\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\n\t\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\t\treturn sljit_emit_jump(compiler, SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP));\n\t\t}\n\n\t\tstack_size = type;\n\t\tPTR_FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, SLJIT_IMM, 0));\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\n\t\tif (stack_size == 0)\n\t\t\treturn sljit_emit_jump(compiler, SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP));\n\n\t\tjump = sljit_emit_jump(compiler, type);\n\t\tPTR_FAIL_IF(jump == NULL);\n\n\t\tPTR_FAIL_IF(emit_tail_call_end(compiler, stack_size));\n\t\treturn jump;\n\t}\n\n\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_jump(compiler, type);\n\t}\n\n\tstack_size = call_get_stack_size(arg_types, &word_arg_count);\n\tPTR_FAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, 0));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tjump = sljit_emit_jump(compiler, type);\n\tPTR_FAIL_IF(jump == NULL);\n\n\tPTR_FAIL_IF(post_call_with_args(compiler, arg_types, stack_size));\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_sw stack_size = 0;\n\tsljit_s32 word_arg_count;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\t\tFAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));\n\n\t\t\tif ((src & SLJIT_MEM) || (src > SLJIT_R2 && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {\n\t\t\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\t\t\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\t\t\tsrc = TMP_REG1;\n\t\t\t\tsrcw = 0;\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\n\t\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\t\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n\t\t}\n\n\t\tstack_size = type;\n\t\tFAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, src, srcw));\n\n\t\tif (src != SLJIT_IMM) {\n\t\t\tsrc = SLJIT_R0;\n\t\t\tsrcw = 0;\n\t\t}\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\n\t\tif (stack_size == 0)\n\t\t\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n\n\t\tFAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));\n\t\treturn emit_tail_call_end(compiler, stack_size);\n\t}\n\n\tif ((type & 0xff) == SLJIT_CALL_REG_ARG) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_ijump(compiler, type, src, srcw);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tif (src & SLJIT_MEM) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tstack_size = call_get_stack_size(arg_types, &word_arg_count);\n\tFAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, src == TMP_REG1));\n\n\tif (stack_size > 0 && src == SLJIT_MEM1(SLJIT_SP))\n\t\tsrcw += stack_size;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\tFAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));\n\n\treturn post_call_with_args(compiler, arg_types, stack_size);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\n\tif (compiler->options & SLJIT_ENTER_REG_ARG) {\n\t\tif (src == SLJIT_FR0)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);\n\t}\n\n\tif (FAST_IS_REG(src)) {\n\t\tFAIL_IF(emit_sse2_store(compiler, op & SLJIT_32, SLJIT_MEM1(SLJIT_SP), 0, src));\n\n\t\tsrc = SLJIT_MEM1(SLJIT_SP);\n\t\tsrcw = 0;\n\t} else {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t}\n\n\tinst = emit_x86_instruction(compiler, 1 | EX86_SSE2_OP1, 0, 0, src, srcw);\n\t*inst = (op & SLJIT_32) ? FLDS : FLDL;\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_u8 *inst;\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\n\t/* Unused dest is possible here. */\n\tif (FAST_IS_REG(dst))\n\t\treturn emit_byte(compiler, U8(POP_r + reg_map[dst]));\n\n\t/* Memory. */\n\tinst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);\n\tFAIL_IF(!inst);\n\t*inst = POP_rm;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst;\n\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tif (FAST_IS_REG(src)) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);\n\t\tFAIL_IF(!inst);\n\n\t\tINC_SIZE(1 + 1);\n\t\tPUSH_REG(reg_map[src]);\n\t}\n\telse {\n\t\tinst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_FF;\n\t\tinst[1] |= PUSH_rm;\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 1);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(1);\n\t}\n\n\tRET();\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 options = compiler->options;\n\tsljit_s32 saveds = compiler->saveds;\n\tsljit_s32 scratches = compiler->scratches;\n\n\tsaveds = ((scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(options)) * SSIZE_OF(sw);\n\n\t/* Saving ebp. */\n\tif (!(options & SLJIT_ENTER_REG_ARG))\n\t\tsaveds += SSIZE_OF(sw);\n\n\treturn emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saveds);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Other operations                                                     */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_s32 dst = dst_reg;\n\tsljit_sw dstw = 0;\n\tsljit_sw src2w = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\tCHECK_EXTRA_REGS(src1, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2_reg, src2w, (void)0);\n\n\tif (dst & SLJIT_MEM) {\n\t\tif (src1 == SLJIT_IMM || (!(src1 & SLJIT_MEM) && (src2_reg & SLJIT_MEM))) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = src2w;\n\t\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w);\n\n\t\tdst_reg = TMP_REG1;\n\t} else if (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = src2w;\n\t\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\t\ttype ^= 0x1;\n\t\t} else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\tEMIT_MOV(compiler, dst_reg, 0, src1, src1w);\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = src2w;\n\t\t\tif (!(type & SLJIT_COMPARE_SELECT))\n\t\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tEMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w);\n\t}\n\n\tif (type & SLJIT_COMPARE_SELECT) {\n\t\tif (dst_reg != TMP_REG1 && !FAST_IS_REG(src1)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t}\n\n\t\ttype ^= 0x1;\n\t\tFAIL_IF(emit_cmp_binary(compiler, dst_reg, 0, src1, src1w));\n\t}\n\n\ttype &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\n\tif (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) {\n\t\tif (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {\n\t\t\tif (dst_reg != TMP_REG1) {\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, src1w);\n\t\t\t\tsrc1 = TMP_REG1;\n\t\t\t\tsrc1w = 0;\n\t\t\t} else {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_IMM, src1w);\n\t\t\t\tsrc1 = SLJIT_MEM1(SLJIT_SP);\n\t\t\t\tsrc1w = 0;\n\t\t\t}\n\t\t}\n\n\t\tFAIL_IF(emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w));\n\t} else\n\t\tFAIL_IF(emit_cmov_generic(compiler, type, dst_reg, src1, src1w));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 i, next, reg_idx, offset;\n\tsljit_u8 regs[2];\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tregs[0] = U8(REG_PAIR_FIRST(reg));\n\tregs[1] = U8(REG_PAIR_SECOND(reg));\n\n\tnext = SSIZE_OF(sw);\n\n\tif (!(type & SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {\n\t\tif (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {\n\t\t\t/* None of them are virtual register so TMP_REG1 will not be used. */\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, OFFS_REG(mem), 0);\n\n\t\t\tif (regs[1] == OFFS_REG(mem))\n\t\t\t\tnext = -SSIZE_OF(sw);\n\n\t\t\tmem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t} else {\n\t\t\tnext = -SSIZE_OF(sw);\n\n\t\t\tif (!(mem & OFFS_REG_MASK))\n\t\t\t\tmemw += SSIZE_OF(sw);\n\t\t}\n\t}\n\n\tfor (i = 0; i < 2; i++) {\n\t\treg_idx = next > 0 ? i : (i ^ 0x1);\n\t\treg = regs[reg_idx];\n\n\t\toffset = -1;\n\n\t\tif (reg >= SLJIT_R3 && reg <= SLJIT_S3) {\n\t\t\toffset = (2 * SSIZE_OF(sw)) + ((reg) - SLJIT_R3) * SSIZE_OF(sw);\n\t\t\treg = TMP_REG1;\n\n\t\t\tif (type & SLJIT_MEM_STORE)\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), offset);\n\t\t}\n\n\t\tif ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 4));\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(4);\n\n\t\t\tinst[0] = (type & SLJIT_MEM_STORE) ? MOV_rm_r : MOV_r_rm;\n\t\t\tinst[1] = 0x44 | U8(reg_map[reg] << 3);\n\t\t\tinst[2] = U8(memw << 6) | U8(reg_map[OFFS_REG(mem)] << 3) | reg_map[mem & REG_MASK];\n\t\t\tinst[3] = sizeof(sljit_sw);\n\t\t} else if (type & SLJIT_MEM_STORE) {\n\t\t\tEMIT_MOV(compiler, mem, memw, reg, 0);\n\t\t} else {\n\t\t\tEMIT_MOV(compiler, reg, 0, mem, memw);\n\t\t}\n\n\t\tif (!(mem & OFFS_REG_MASK))\n\t\t\tmemw += next;\n\n\t\tif (!(type & SLJIT_MEM_STORE) && offset != -1)\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), offset, TMP_REG1, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;\n\tsljit_u8 *inst, *jump_inst1, *jump_inst2;\n\tsljit_uw size1, size2;\n\n\t/* Binary representation of 0x80000000. */\n\tstatic const sljit_f64 f64_high_bit = (sljit_f64)0x80000000ul;\n\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tif (!(op & SLJIT_32)) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[1] |= ROL;\n\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[1] |= SHR;\n\n\t\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_PREF_F2 | EX86_SSE2_OP1, dst_r, TMP_REG1, 0));\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(2);\n\t\tinst[0] = U8(get_jump_code(SLJIT_NOT_CARRY) - 0x10);\n\n\t\tsize1 = compiler->size;\n\t\tFAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_PREF_F2 | EX86_SSE2, dst_r, SLJIT_MEM0(), (sljit_sw)&f64_high_bit));\n\n\t\tinst[1] = U8(compiler->size - size1);\n\n\t\tif (dst_r == TMP_FREG)\n\t\t\treturn emit_sse2_store(compiler, 0, dst, dstw, TMP_FREG);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (!FAST_IS_REG(src)) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\tsrc = TMP_REG1;\n\t}\n\n\tBINARY_IMM32(CMP, 0, src, 0);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JL_i8;\n\tjump_inst1 = inst;\n\n\tsize1 = compiler->size;\n\n\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0));\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JMP_i8;\n\tjump_inst2 = inst;\n\n\tsize2 = compiler->size;\n\n\tjump_inst1[1] = U8(size2 - size1);\n\n\tif (src != TMP_REG1)\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, 0);\n\n\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0);\n\tFAIL_IF(!inst);\n\tinst[1] |= SHR;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JNC_i8;\n\tjump_inst1 = inst;\n\n\tsize1 = compiler->size;\n\n\tBINARY_IMM32(OR, 1, TMP_REG1, 0);\n\tjump_inst1[1] = U8(compiler->size - size1);\n\n\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0));\n\tFAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0));\n\n\tjump_inst2[1] = U8(compiler->size - size2);\n\n\tif (dst_r == TMP_FREG)\n\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tsljit_u8 *inst;\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm != 0)\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\tFAIL_IF(!inst);\n\tINC_SIZE(4);\n\n\tinst[0] = GROUP_66;\n\tinst[1] = GROUP_0F;\n\n\tif (u.imm == 0) {\n\t\tinst[2] = PXOR_x_xm;\n\t\tinst[3] = U8(freg_map[freg] | (freg_map[freg] << 3) | MOD_REG);\n\t} else {\n\t\tinst[2] = MOVD_x_rm;\n\t\tinst[3] = U8(reg_map[TMP_REG1] | (freg_map[freg] << 3) | MOD_REG);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tsljit_u8 *inst;\n\tunion {\n\t\tsljit_s32 imm[2];\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm[0] == 0) {\n\t\tif (u.imm[1] == 0)\n\t\t\treturn emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0);\n\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]);\n\t} else {\n\t\tSLJIT_ASSERT(cpu_feature_list != 0);\n\n\t\tif (!(cpu_feature_list & CPU_FEATURE_SSE41) && u.imm[1] != 0 && u.imm[0] != u.imm[1]) {\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_IMM, u.imm[0]);\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_IMM, u.imm[1]);\n\n\t\t\treturn emit_groupf(compiler, MOVLPD_x_m | EX86_SSE2, freg, SLJIT_MEM1(SLJIT_SP), 0);\n\t\t}\n\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[0]);\n\t}\n\n\tFAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, TMP_REG1, 0));\n\n\tif (u.imm[1] == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (u.imm[0] == 0) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(4);\n\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = SHUFPS_x_xm;\n\t\tinst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);\n\t\tinst[3] = 0x51;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (u.imm[0] != u.imm[1]) {\n\t\tSLJIT_ASSERT(cpu_feature_list & CPU_FEATURE_SSE41);\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]);\n\n\t\tFAIL_IF(emit_groupf_ext(compiler, PINSRD_x_rm_i8 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, TMP_REG1, 0));\n\t\treturn emit_byte(compiler, 1);\n\t}\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3);\n\tFAIL_IF(!inst);\n\tINC_SIZE(3);\n\n\tinst[0] = GROUP_0F;\n\tinst[1] = UNPCKLPS_x_xm;\n\tinst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_u8 *inst;\n\tsljit_s32 reg2;\n\tsljit_sw regw, reg2w;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tregw = 0;\n\treg2 = 0;\n\treg2w = 0;\n\n\tSLJIT_ASSERT(cpu_feature_list != 0);\n\n\tif (!(op & SLJIT_32) && (cpu_feature_list & CPU_FEATURE_SSE41)) {\n\t\tif (reg & REG_PAIR_MASK) {\n\t\t\treg2 = REG_PAIR_FIRST(reg);\n\t\t\treg = REG_PAIR_SECOND(reg);\n\n\t\t\tCHECK_EXTRA_REGS(reg, regw, (void)0);\n\n\t\t\tFAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x)\n\t\t\t\t| EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw));\n\t\t} else\n\t\t\treg2 = reg;\n\n\t\tCHECK_EXTRA_REGS(reg2, reg2w, (void)0);\n\n\t\tFAIL_IF(emit_groupf_ext(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? PINSRD_x_rm_i8 : PEXTRD_rm_x_i8)\n\t\t\t| EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, reg2, reg2w));\n\t\treturn emit_byte(compiler, 1);\n\t}\n\n\tif (reg & REG_PAIR_MASK) {\n\t\treg2 = REG_PAIR_SECOND(reg);\n\t\treg = REG_PAIR_FIRST(reg);\n\n\t\tif (reg == reg2)\n\t\t\treg = 0;\n\n\t\tCHECK_EXTRA_REGS(reg2, reg2w, (void)0);\n\t}\n\n\tCHECK_EXTRA_REGS(reg, regw, (void)0);\n\n\tif (op & SLJIT_32)\n\t\treturn emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x)\n\t\t\t| EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw);\n\n\tif (op == SLJIT_COPY_FROM_F64) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 5);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(5);\n\n\t\tinst[0] = GROUP_66;\n\t\tinst[1] = GROUP_0F;\n\t\tinst[2] = PSHUFD_x_xm;\n\t\tinst[3] = U8(MOD_REG | (TMP_FREG << 3) | freg_map[freg]);\n\t\tinst[4] = 1;\n\t} else if (reg != 0)\n\t\tFAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw));\n\n\tif (reg2 != 0)\n\t\tFAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x)\n\t\t\t| EX86_PREF_66 | EX86_SSE2_OP1, freg, reg2, reg2w));\n\n\tif (GET_OPCODE(op) == SLJIT_COPY_TO_F64) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(3);\n\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = UNPCKLPS_x_xm;\n\t\tinst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[reg == 0 ? freg : TMP_FREG]);\n\t} else\n\t\tFAIL_IF(emit_groupf(compiler, MOVD_rm_x | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw));\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)\n{\n\tsljit_sw size;\n\n\t/* Don't adjust shadow stack if it isn't enabled.  */\n\tif (!cpu_has_shadow_stack())\n\t\treturn SLJIT_SUCCESS;\n\n\tSLJIT_ASSERT(compiler->args_size >= 0);\n\tSLJIT_ASSERT(compiler->local_size > 0);\n\n\tsize = compiler->local_size;\n\tsize += (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0)\n\t\t+ (compiler->saveds <= 3 ? compiler->saveds : 3)) * SSIZE_OF(sw);\n\n\treturn adjust_shadow_stack(compiler, SLJIT_MEM1(SLJIT_SP), size);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* x86 64-bit arch dependent functions. */\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)\n{\n\tsljit_u8 *inst;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));\n\tFAIL_IF(!inst);\n\tINC_SIZE(2 + sizeof(sljit_sw));\n\tinst[0] = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);\n\tinst[1] = U8(MOV_r_i32 | reg_lmap[reg]);\n\tsljit_unaligned_store_sw(inst + 2, imm);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm)\n{\n\tsljit_u8 *inst;\n\tsljit_uw length = (rex ? 2 : 1) + sizeof(sljit_s32);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + length);\n\tFAIL_IF(!inst);\n\tINC_SIZE(length);\n\tif (rex)\n\t\t*inst++ = rex;\n\t*inst++ = opcode;\n\tsljit_unaligned_store_s32(inst, (sljit_s32)imm);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw size,\n\t/* The register or immediate operand. */\n\tsljit_s32 a, sljit_sw imma,\n\t/* The general operand (not immediate). */\n\tsljit_s32 b, sljit_sw immb)\n{\n\tsljit_u8 *inst;\n\tsljit_u8 *buf_ptr;\n\tsljit_u8 rex = 0;\n\tsljit_u8 reg_lmap_b;\n\tsljit_uw flags = size;\n\tsljit_uw inst_size;\n\n\t/* The immediate operand must be 32 bit. */\n\tSLJIT_ASSERT(a != SLJIT_IMM || compiler->mode32 || IS_HALFWORD(imma));\n\t/* Both cannot be switched on. */\n\tSLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));\n\t/* Size flags not allowed for typed instructions. */\n\tSLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);\n\t/* Both size flags cannot be switched on. */\n\tSLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));\n\t/* SSE2 and immediate is not possible. */\n\tSLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2));\n\tSLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\t\t& ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0);\n\tSLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT);\n\n\tsize &= 0xf;\n\t/* The mod r/m byte is always present. */\n\tinst_size = size + 1;\n\n\tif (!compiler->mode32 && !(flags & EX86_NO_REXW))\n\t\trex |= REX_W;\n\telse if (flags & EX86_REX)\n\t\trex |= REX;\n\n\tif (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\tinst_size++;\n\n\t/* Calculate size of b. */\n\tif (b & SLJIT_MEM) {\n\t\tif (!(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) {\n\t\t\tPTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb));\n\t\t\timmb = 0;\n\t\t\tif (b & REG_MASK)\n\t\t\t\tb |= TO_OFFS_REG(TMP_REG2);\n\t\t\telse\n\t\t\t\tb |= TMP_REG2;\n\t\t}\n\n\t\tif (!(b & REG_MASK))\n\t\t\tinst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */\n\t\telse {\n\t\t\tif (immb != 0 && !(b & OFFS_REG_MASK)) {\n\t\t\t\t/* Immediate operand. */\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\telse\n\t\t\t\t\tinst_size += sizeof(sljit_s32);\n\t\t\t} else if (reg_lmap[b & REG_MASK] == 5) {\n\t\t\t\t/* Swap registers if possible. */\n\t\t\t\tif ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_lmap[OFFS_REG(b)] != 5)\n\t\t\t\t\tb = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);\n\t\t\t\telse\n\t\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t}\n\n\t\t\tif (reg_map[b & REG_MASK] >= 8)\n\t\t\t\trex |= REX_B;\n\n\t\t\tif (reg_lmap[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))\n\t\t\t\tb |= TO_OFFS_REG(SLJIT_SP);\n\n\t\t\tif (b & OFFS_REG_MASK) {\n\t\t\t\tinst_size += 1; /* SIB byte. */\n\t\t\t\tif (reg_map[OFFS_REG(b)] >= 8)\n\t\t\t\t\trex |= REX_X;\n\t\t\t}\n\t\t}\n\t} else if (!(flags & EX86_SSE2_OP2)) {\n\t\tif (reg_map[b] >= 8)\n\t\t\trex |= REX_B;\n\t} else if (freg_map[b] >= 8)\n\t\trex |= REX_B;\n\n\tif ((flags & EX86_VEX_EXT) && (rex & 0x3)) {\n\t\tSLJIT_ASSERT(size == 2);\n\t\tsize++;\n\t\tinst_size++;\n\t}\n\n\tif (a == SLJIT_IMM) {\n\t\tif (flags & EX86_BIN_INS) {\n\t\t\tif (imma <= 127 && imma >= -128) {\n\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\tflags |= EX86_BYTE_ARG;\n\t\t\t} else\n\t\t\t\tinst_size += sizeof(sljit_s32);\n\t\t} else if (flags & EX86_SHIFT_INS) {\n\t\t\tSLJIT_ASSERT(imma <= (compiler->mode32 ? 0x1f : 0x3f));\n\t\t\tif (imma != 1) {\n\t\t\t\tinst_size += sizeof(sljit_s8);\n\t\t\t\tflags |= EX86_BYTE_ARG;\n\t\t\t}\n\t\t} else if (flags & EX86_BYTE_ARG)\n\t\t\tinst_size += sizeof(sljit_s8);\n\t\telse if (flags & EX86_HALF_ARG)\n\t\t\tinst_size += sizeof(sljit_s16);\n\t\telse\n\t\t\tinst_size += sizeof(sljit_s32);\n\t} else {\n\t\tSLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);\n\t\t/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */\n\t\tif (!(flags & EX86_SSE2_OP1)) {\n\t\t\tif (reg_map[a] >= 8)\n\t\t\t\trex |= REX_R;\n\t\t}\n\t\telse if (freg_map[a] >= 8)\n\t\t\trex |= REX_R;\n\t}\n\n\tif (rex)\n\t\tinst_size++;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);\n\tPTR_FAIL_IF(!inst);\n\n\t/* Encoding prefixes. */\n\tINC_SIZE(inst_size);\n\tif (flags & EX86_PREF_F2)\n\t\t*inst++ = 0xf2;\n\telse if (flags & EX86_PREF_F3)\n\t\t*inst++ = 0xf3;\n\telse if (flags & EX86_PREF_66)\n\t\t*inst++ = 0x66;\n\n\t/* Rex is always the last prefix. */\n\tif (rex)\n\t\t*inst++ = rex;\n\n\tbuf_ptr = inst + size;\n\n\t/* Encode mod/rm byte. */\n\tif (!(flags & EX86_SHIFT_INS)) {\n\t\tif ((flags & EX86_BIN_INS) && a == SLJIT_IMM)\n\t\t\t*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;\n\n\t\tif (a == SLJIT_IMM)\n\t\t\t*buf_ptr = 0;\n\t\telse if (!(flags & EX86_SSE2_OP1))\n\t\t\t*buf_ptr = U8(reg_lmap[a] << 3);\n\t\telse\n\t\t\t*buf_ptr = U8(freg_lmap[a] << 3);\n\t} else {\n\t\tif (a == SLJIT_IMM) {\n\t\t\tif (imma == 1)\n\t\t\t\t*inst = GROUP_SHIFT_1;\n\t\t\telse\n\t\t\t\t*inst = GROUP_SHIFT_N;\n\t\t} else\n\t\t\t*inst = GROUP_SHIFT_CL;\n\t\t*buf_ptr = 0;\n\t}\n\n\tif (!(b & SLJIT_MEM)) {\n\t\t*buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_lmap[b] : freg_lmap[b]));\n\t\tbuf_ptr++;\n\t} else if (b & REG_MASK) {\n\t\treg_lmap_b = reg_lmap[b & REG_MASK];\n\n\t\tif (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {\n\t\t\tif (immb != 0 || reg_lmap_b == 5) {\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\t*buf_ptr |= 0x40;\n\t\t\t\telse\n\t\t\t\t\t*buf_ptr |= 0x80;\n\t\t\t}\n\n\t\t\tif (!(b & OFFS_REG_MASK))\n\t\t\t\t*buf_ptr++ |= reg_lmap_b;\n\t\t\telse {\n\t\t\t\tbuf_ptr[0] |= 0x04;\n\t\t\t\tbuf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3));\n\t\t\t\tbuf_ptr += 2;\n\t\t\t}\n\n\t\t\tif (immb != 0 || reg_lmap_b == 5) {\n\t\t\t\tif (immb <= 127 && immb >= -128)\n\t\t\t\t\t*buf_ptr++ = U8(immb); /* 8 bit displacement. */\n\t\t\t\telse {\n\t\t\t\t\tsljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */\n\t\t\t\t\tbuf_ptr += sizeof(sljit_s32);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (reg_lmap_b == 5)\n\t\t\t\t*buf_ptr |= 0x40;\n\n\t\t\tbuf_ptr[0] |= 0x04;\n\t\t\tbuf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6));\n\t\t\tbuf_ptr += 2;\n\n\t\t\tif (reg_lmap_b == 5)\n\t\t\t\t*buf_ptr++ = 0;\n\t\t}\n\t} else {\n\t\tbuf_ptr[0] |= 0x04;\n\t\tbuf_ptr[1] = 0x25;\n\t\tbuf_ptr += 2;\n\t\tsljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */\n\t\tbuf_ptr += sizeof(sljit_s32);\n\t}\n\n\tif (a == SLJIT_IMM) {\n\t\tif (flags & EX86_BYTE_ARG)\n\t\t\t*buf_ptr = U8(imma);\n\t\telse if (flags & EX86_HALF_ARG)\n\t\t\tsljit_unaligned_store_s16(buf_ptr, (sljit_s16)imma);\n\t\telse if (!(flags & EX86_SHIFT_INS))\n\t\t\tsljit_unaligned_store_s32(buf_ptr, (sljit_s32)imma);\n\t}\n\n\treturn inst;\n}\n\nstatic sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op,\n\t/* The first and second register operand. */\n\tsljit_s32 a, sljit_s32 v,\n\t/* The general operand (not immediate). */\n\tsljit_s32 b, sljit_sw immb)\n{\n\tsljit_u8 *inst;\n\tsljit_u8 vex = 0;\n\tsljit_u8 vex_m = 0;\n\tsljit_uw size;\n\n\tSLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66))\n\t\t\t& ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0);\n\n\top |= EX86_REX;\n\n\tif (op & VEX_OP_0F38)\n\t\tvex_m = 0x2;\n\telse if (op & VEX_OP_0F3A)\n\t\tvex_m = 0x3;\n\n\tif ((op & VEX_W) || ((op & VEX_AUTO_W) && !compiler->mode32)) {\n\t\tif (vex_m == 0)\n\t\t\tvex_m = 0x1;\n\n\t\tvex |= 0x80;\n\t}\n\n\tif (op & EX86_PREF_66)\n\t\tvex |= 0x1;\n\telse if (op & EX86_PREF_F2)\n\t\tvex |= 0x3;\n\telse if (op & EX86_PREF_F3)\n\t\tvex |= 0x2;\n\n\top &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3);\n\n\tif (op & VEX_256)\n\t\tvex |= 0x4;\n\n\tvex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3));\n\n\tsize = op & ~(sljit_uw)0xff;\n\tsize |= (vex_m == 0) ? (EX86_VEX_EXT | 2) : 3;\n\n\tinst = emit_x86_instruction(compiler, size, a, 0, b, immb);\n\tFAIL_IF(!inst);\n\n\tSLJIT_ASSERT((inst[-1] & 0xf0) == REX);\n\n\t/* If X or B is present in REX prefix. */\n\tif (vex_m == 0 && inst[-1] & 0x3)\n\t\tvex_m = 0x1;\n\n\tif (vex_m == 0) {\n\t\tvex |= U8(((inst[-1] >> 2) ^ 0x1) << 7);\n\n\t\tinst[-1] = 0xc5;\n\t\tinst[0] = vex;\n\t\tinst[1] = U8(op);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tvex_m |= U8((inst[-1] ^ 0x7) << 5);\n\tinst[-1] = 0xc4;\n\tinst[0] = vex_m;\n\tinst[1] = vex;\n\tinst[2] = U8(op);\n\treturn SLJIT_SUCCESS;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Enter / return                                                       */\n/* --------------------------------------------------------------------- */\n\nstatic sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr)\n{\n\tsljit_uw type = jump->flags >> TYPE_SHIFT;\n\n\tint short_addr = ((jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) == JUMP_ADDR) && (jump->u.target <= 0xffffffff);\n\n\t/* The relative jump below specialized for this case. */\n\tSLJIT_ASSERT(reg_map[TMP_REG2] >= 8 && TMP_REG2 != SLJIT_TMP_DEST_REG);\n\n\tif (type < SLJIT_JUMP) {\n\t\t/* Invert type. */\n\t\tcode_ptr[0] = U8(get_jump_code(type ^ 0x1) - 0x10);\n\t\tcode_ptr[1] = short_addr ? (6 + 3) : (10 + 3);\n\t\tcode_ptr += 2;\n\t}\n\n\tcode_ptr[0] = short_addr ? REX_B : (REX_W | REX_B);\n\tcode_ptr[1] = MOV_r_i32 | reg_lmap[TMP_REG2];\n\tcode_ptr += 2;\n\tjump->addr = (sljit_uw)code_ptr;\n\n\tif (!(jump->flags & JUMP_ADDR))\n\t\tjump->flags |= PATCH_MD;\n\telse if (short_addr)\n\t\tsljit_unaligned_store_s32(code_ptr, (sljit_s32)jump->u.target);\n\telse\n\t\tsljit_unaligned_store_sw(code_ptr, (sljit_sw)jump->u.target);\n\n\tcode_ptr += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);\n\n\tcode_ptr[0] = REX_B;\n\tcode_ptr[1] = GROUP_FF;\n\tcode_ptr[2] = U8(MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2]);\n\n\treturn code_ptr + 3;\n}\n\nstatic sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)\n{\n\tsljit_uw addr;\n\tsljit_sw diff;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) <= 10);\n\tif (jump->flags & JUMP_ADDR)\n\t\taddr = jump->u.target;\n\telse\n\t\taddr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + jump->u.label->size;\n\n\tif (addr > 0xffffffffl) {\n\t\tdiff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\n\t\tif (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) {\n\t\t\tSLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 7);\n\t\t\tcode_ptr -= SSIZE_OF(s32) - 1;\n\n\t\t\tSLJIT_ASSERT((code_ptr[-3 - SSIZE_OF(s32)] & 0xf8) == REX_W);\n\t\t\tSLJIT_ASSERT((code_ptr[-2 - SSIZE_OF(s32)] & 0xf8) == MOV_r_i32);\n\n\t\t\tcode_ptr[-3 - SSIZE_OF(s32)] = U8(REX_W | ((code_ptr[-3 - SSIZE_OF(s32)] & 0x1) << 2));\n\t\t\tcode_ptr[-1 - SSIZE_OF(s32)] = U8(((code_ptr[-2 - SSIZE_OF(s32)] & 0x7) << 3) | 0x5);\n\t\t\tcode_ptr[-2 - SSIZE_OF(s32)] = LEA_r_m;\n\n\t\t\tjump->flags |= PATCH_MW;\n\t\t\treturn code_ptr;\n\t\t}\n\n\t\tjump->flags |= PATCH_MD;\n\t\treturn code_ptr;\n\t}\n\n\tcode_ptr -= 2 + sizeof(sljit_uw);\n\n\tSLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);\n\tSLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);\n\n\tif ((code_ptr[0] & 0x07) != 0) {\n\t\tSLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 6);\n\t\tcode_ptr[0] = U8(code_ptr[0] & ~0x08);\n\t\tcode_ptr += 2 + sizeof(sljit_s32);\n\t} else {\n\t\tSLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 5);\n\t\tcode_ptr[0] = code_ptr[1];\n\t\tcode_ptr += 1 + sizeof(sljit_s32);\n\t}\n\n\treturn code_ptr;\n}\n\n#ifdef _WIN64\ntypedef struct {\n\tsljit_sw regs[2];\n} sljit_sse2_reg;\n#endif /* _WIN64 */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_uw size;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);\n\tsljit_s32 saved_regs_size, tmp, i;\n#ifdef _WIN64\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 saved_float_regs_size;\n\tsljit_s32 saved_float_regs_offset = 0;\n\tsljit_s32 float_arg_count = 0;\n#endif /* _WIN64 */\n\tsljit_u8 *inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n#ifdef _WIN64\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n#endif /* _WIN64 */\n\n\tif (options & SLJIT_ENTER_REG_ARG)\n\t\targ_types = 0;\n\n\t/* Emit ENDBR64 at function entry if needed.  */\n\tFAIL_IF(emit_endbranch(compiler));\n\n\tcompiler->mode32 = 0;\n\n\t/* Including the return address saved by the call instruction. */\n\tsaved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);\n\n\ttmp = SLJIT_S0 - saveds;\n\tfor (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {\n\t\tsize = reg_map[i] >= 8 ? 2 : 1;\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n\t\tif (reg_map[i] >= 8)\n\t\t\t*inst++ = REX_B;\n\t\tPUSH_REG(reg_lmap[i]);\n\t}\n\n\tfor (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {\n\t\tsize = reg_map[i] >= 8 ? 2 : 1;\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n\t\tif (reg_map[i] >= 8)\n\t\t\t*inst++ = REX_B;\n\t\tPUSH_REG(reg_lmap[i]);\n\t}\n\n#ifdef _WIN64\n\tlocal_size += SLJIT_LOCALS_OFFSET;\n\tsaved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);\n\n\tif (saved_float_regs_size > 0) {\n\t\tsaved_float_regs_offset = ((local_size + 0xf) & ~0xf);\n\t\tlocal_size = saved_float_regs_offset + saved_float_regs_size;\n\t}\n#else /* !_WIN64 */\n\tSLJIT_ASSERT(SLJIT_LOCALS_OFFSET == 0);\n#endif /* _WIN64 */\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types > 0) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {\n\t\t\ttmp = 0;\n#ifndef _WIN64\n\t\t\tswitch (word_arg_count) {\n\t\t\tcase 0:\n\t\t\t\ttmp = SLJIT_R2;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\ttmp = SLJIT_R1;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttmp = TMP_REG1;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttmp = SLJIT_R3;\n\t\t\t\tbreak;\n\t\t\t}\n#else /* !_WIN64 */\n\t\t\tswitch (word_arg_count + float_arg_count) {\n\t\t\tcase 0:\n\t\t\t\ttmp = SLJIT_R3;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\ttmp = SLJIT_R1;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttmp = SLJIT_R2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttmp = TMP_REG1;\n\t\t\t\tbreak;\n\t\t\t}\n#endif /* _WIN64 */\n\t\t\tif (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {\n\t\t\t\tif (tmp != SLJIT_R0 + word_arg_count)\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_R0 + word_arg_count, 0, tmp, 0);\n\t\t\t} else {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_S0 - saved_arg_count, 0, tmp, 0);\n\t\t\t\tsaved_arg_count++;\n\t\t\t}\n\t\t\tword_arg_count++;\n\t\t} else {\n#ifdef _WIN64\n\t\t\tSLJIT_COMPILE_ASSERT(SLJIT_FR0 == 1, float_register_index_start);\n\t\t\tfloat_arg_count++;\n\t\t\tif (float_arg_count != float_arg_count + word_arg_count)\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, (arg_types & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F32,\n\t\t\t\t\tfloat_arg_count, float_arg_count + word_arg_count, 0));\n#endif /* _WIN64 */\n\t\t}\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tlocal_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;\n\tcompiler->local_size = local_size;\n\n#ifdef _WIN64\n\tif (local_size > 0) {\n\t\tif (local_size <= 4 * 4096) {\n\t\t\tif (local_size > 4096)\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);\n\t\t\tif (local_size > 2 * 4096)\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);\n\t\t\tif (local_size > 3 * 4096)\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);\n\t\t}\n\t\telse {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, local_size >> 12);\n\n\t\t\tEMIT_MOV(compiler, TMP_REG2, 0, SLJIT_MEM1(SLJIT_SP), -4096);\n\t\t\tBINARY_IMM32(SUB, 4096, SLJIT_SP, 0);\n\t\t\tBINARY_IMM32(SUB, 1, TMP_REG1, 0);\n\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(2);\n\t\t\tinst[0] = JNE_i8;\n\t\t\tinst[1] = (sljit_u8)-21;\n\t\t\tlocal_size &= 0xfff;\n\t\t}\n\n\t\tif (local_size > 0)\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);\n\t}\n#endif /* _WIN64 */\n\n\tif (local_size > 0)\n\t\tBINARY_IMM32(SUB, local_size, SLJIT_SP, 0);\n\n#ifdef _WIN64\n\tif (saved_float_regs_size > 0) {\n\t\tcompiler->mode32 = 1;\n\n\t\ttmp = SLJIT_FS0 - fsaveds;\n\t\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\t\tFAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset));\n\t\t\tsaved_float_regs_offset += 16;\n\t\t}\n\n\t\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\t\tFAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset));\n\t\t\tsaved_float_regs_offset += 16;\n\t\t}\n\t}\n#endif /* _WIN64 */\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_s32 arg_types,\n\tsljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)\n{\n\tsljit_s32 saved_regs_size;\n#ifdef _WIN64\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 saved_float_regs_size;\n#endif /* _WIN64 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));\n\tset_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);\n\n\tscratches = ENTER_GET_REGS(scratches);\n\n#ifdef _WIN64\n\tsaveds = ENTER_GET_REGS(saveds);\n\tfscratches = compiler->fscratches;\n\tfsaveds = compiler->fsaveds;\n\n\tlocal_size += SLJIT_LOCALS_OFFSET;\n\tsaved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);\n\n\tif (saved_float_regs_size > 0)\n\t\tlocal_size = ((local_size + 0xf) & ~0xf) + saved_float_regs_size;\n#else /* !_WIN64 */\n\tSLJIT_ASSERT(SLJIT_LOCALS_OFFSET == 0);\n#endif /* _WIN64 */\n\n\t/* Including the return address saved by the call instruction. */\n\tsaved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);\n\tcompiler->local_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)\n{\n\tsljit_uw size;\n\tsljit_s32 local_size, i, tmp;\n\tsljit_u8 *inst;\n#ifdef _WIN64\n\tsljit_s32 saved_float_regs_offset;\n\tsljit_s32 fscratches = compiler->fscratches;\n\tsljit_s32 fsaveds = compiler->fsaveds;\n#endif /* _WIN64 */\n\n#ifdef _WIN64\n\tsaved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);\n\n\tif (saved_float_regs_offset > 0) {\n\t\tcompiler->mode32 = 1;\n\t\tsaved_float_regs_offset = (compiler->local_size - saved_float_regs_offset) & ~0xf;\n\n\t\ttmp = SLJIT_FS0 - fsaveds;\n\t\tfor (i = SLJIT_FS0; i > tmp; i--) {\n\t\t\tFAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset));\n\t\t\tsaved_float_regs_offset += 16;\n\t\t}\n\n\t\tfor (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {\n\t\t\tFAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset));\n\t\t\tsaved_float_regs_offset += 16;\n\t\t}\n\n\t\tcompiler->mode32 = 0;\n\t}\n#endif /* _WIN64 */\n\n\tlocal_size = compiler->local_size;\n\n\tif (is_return_to && compiler->scratches < SLJIT_FIRST_SAVED_REG && (compiler->saveds == SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\tlocal_size += SSIZE_OF(sw);\n\t\tis_return_to = 0;\n\t}\n\n\tif (local_size > 0)\n\t\tBINARY_IMM32(ADD, local_size, SLJIT_SP, 0);\n\n\ttmp = compiler->scratches;\n\tfor (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {\n\t\tsize = reg_map[i] >= 8 ? 2 : 1;\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n\t\tif (reg_map[i] >= 8)\n\t\t\t*inst++ = REX_B;\n\t\tPOP_REG(reg_lmap[i]);\n\t}\n\n\ttmp = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options);\n\tfor (i = SLJIT_S0 + 1 - compiler->saveds; i <= tmp; i++) {\n\t\tsize = reg_map[i] >= 8 ? 2 : 1;\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n\t\tif (reg_map[i] >= 8)\n\t\t\t*inst++ = REX_B;\n\t\tPOP_REG(reg_lmap[i]);\n\t}\n\n\tif (is_return_to)\n\t\tBINARY_IMM32(ADD, sizeof(sljit_sw), SLJIT_SP, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_void(compiler));\n\n\tcompiler->mode32 = 0;\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\treturn emit_byte(compiler, RET_near);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_return_to(compiler, src, srcw));\n\n\tcompiler->mode32 = 0;\n\n\tif ((src & SLJIT_MEM) || (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\t\tEMIT_MOV(compiler, TMP_REG2, 0, src, srcw);\n\t\tsrc = TMP_REG2;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_stack_frame_release(compiler, 1));\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Call / return instructions                                           */\n/* --------------------------------------------------------------------- */\n\n#ifndef _WIN64\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr)\n{\n\tsljit_s32 src = src_ptr ? (*src_ptr) : 0;\n\tsljit_s32 word_arg_count = 0;\n\n\tSLJIT_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R3] == 1 && reg_map[TMP_REG1] == 2);\n\tSLJIT_ASSERT(!(src & SLJIT_MEM));\n\n\t/* Remove return value. */\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\tif ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64)\n\t\t\tword_arg_count++;\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (word_arg_count == 0)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (word_arg_count >= 3 || src == SLJIT_R2) {\n\t\tif (src == SLJIT_R2)\n\t\t\t*src_ptr = TMP_REG1;\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R2, 0);\n\t}\n\n\treturn emit_mov(compiler, SLJIT_R2, 0, SLJIT_R0, 0);\n}\n\n#else\n\nstatic sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr)\n{\n\tsljit_s32 src = src_ptr ? (*src_ptr) : 0;\n\tsljit_s32 arg_count = 0;\n\tsljit_s32 word_arg_count = 0;\n\tsljit_s32 float_arg_count = 0;\n\tsljit_s32 types = 0;\n\tsljit_s32 data_trandfer = 0;\n\tstatic sljit_u8 word_arg_regs[5] = { 0, SLJIT_R3, SLJIT_R1, SLJIT_R2, TMP_REG1 };\n\n\tSLJIT_ASSERT(reg_map[SLJIT_R3] == 1 && reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R2] == 8 && reg_map[TMP_REG1] == 9);\n\tSLJIT_ASSERT(!(src & SLJIT_MEM));\n\n\targ_types >>= SLJIT_ARG_SHIFT;\n\n\twhile (arg_types) {\n\t\ttypes = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);\n\n\t\tswitch (arg_types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\targ_count++;\n\t\t\tfloat_arg_count++;\n\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tdata_trandfer = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\targ_count++;\n\t\t\tword_arg_count++;\n\n\t\t\tif (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count]) {\n\t\t\t\tdata_trandfer = 1;\n\n\t\t\t\tif (src == word_arg_regs[arg_count]) {\n\t\t\t\t\tEMIT_MOV(compiler, TMP_REG2, 0, src, 0);\n\t\t\t\t\t*src_ptr = TMP_REG2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\targ_types >>= SLJIT_ARG_SHIFT;\n\t}\n\n\tif (!data_trandfer)\n\t\treturn SLJIT_SUCCESS;\n\n\twhile (types) {\n\t\tswitch (types & SLJIT_ARG_MASK) {\n\t\tcase SLJIT_ARG_TYPE_F64:\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, 0, arg_count, float_arg_count, 0));\n\t\t\targ_count--;\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tcase SLJIT_ARG_TYPE_F32:\n\t\t\tif (arg_count != float_arg_count)\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, 1, arg_count, float_arg_count, 0));\n\t\t\targ_count--;\n\t\t\tfloat_arg_count--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count])\n\t\t\t\tEMIT_MOV(compiler, word_arg_regs[arg_count], 0, word_arg_count, 0);\n\t\t\targ_count--;\n\t\t\tword_arg_count--;\n\t\t\tbreak;\n\t\t}\n\n\t\ttypes >>= SLJIT_ARG_SHIFT;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\n#endif\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types)\n{\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));\n\n\tcompiler->mode32 = 0;\n\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tPTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tPTR_FAIL_IF(emit_stack_frame_release(compiler, 0));\n\t\ttype = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_jump(compiler, type);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 arg_types,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));\n\n\tcompiler->mode32 = 0;\n\n\tif (src & SLJIT_MEM) {\n\t\tADJUST_LOCAL_OFFSET(src, srcw);\n\t\tEMIT_MOV(compiler, TMP_REG2, 0, src, srcw);\n\t\tsrc = TMP_REG2;\n\t}\n\n\tif (type & SLJIT_CALL_RETURN) {\n\t\tif (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {\n\t\t\tEMIT_MOV(compiler, TMP_REG2, 0, src, srcw);\n\t\t\tsrc = TMP_REG2;\n\t\t}\n\n\t\tFAIL_IF(emit_stack_frame_release(compiler, 0));\n\t}\n\n\tif ((type & 0xff) != SLJIT_CALL_REG_ARG)\n\t\tFAIL_IF(call_with_args(compiler, arg_types, &src));\n\n\tif (type & SLJIT_CALL_RETURN)\n\t\ttype = SLJIT_JUMP;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_ijump(compiler, type, src, srcw);\n}\n\nstatic sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_u8 *inst;\n\n\tif (FAST_IS_REG(dst)) {\n\t\tif (reg_map[dst] < 8)\n\t\t\treturn emit_byte(compiler, U8(POP_r + reg_lmap[dst]));\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(2);\n\t\t*inst++ = REX_B;\n\t\tPOP_REG(reg_lmap[dst]);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* REX_W is not necessary (src is not immediate). */\n\tcompiler->mode32 = 1;\n\tinst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);\n\tFAIL_IF(!inst);\n\t*inst = POP_rm;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst;\n\n\tif (FAST_IS_REG(src)) {\n\t\tif (reg_map[src] < 8) {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(1 + 1);\n\t\t\tPUSH_REG(reg_lmap[src]);\n\t\t}\n\t\telse {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(2 + 1);\n\t\t\t*inst++ = REX_B;\n\t\t\tPUSH_REG(reg_lmap[src]);\n\t\t}\n\t}\n\telse {\n\t\t/* REX_W is not necessary (src is not immediate). */\n\t\tcompiler->mode32 = 1;\n\t\tinst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_FF;\n\t\tinst[1] |= PUSH_rm;\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 1);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(1);\n\t}\n\n\tRET();\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 saved_regs_size;\n\n\tcompiler->mode32 = 0;\n\tsaved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0);\n\treturn emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saved_regs_size);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Other operations                                                     */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_reg)\n{\n\tsljit_u8* inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n\tcompiler->mode32 = type & SLJIT_32;\n\n\tif (type & SLJIT_COMPARE_SELECT) {\n\t\tif (!FAST_IS_REG(src1)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG2, 0, src1, src1w);\n\t\t\tsrc1 = TMP_REG2;\n\t\t\tsrc1w = 0;\n\t\t}\n\n\t\tinst = emit_x86_instruction(compiler, 1, src1, 0, src2_reg, 0);\n\t\tFAIL_IF(!inst);\n\t\t*inst = CMP_r_rm;\n\t}\n\n\ttype &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);\n\n\tif (dst_reg != src2_reg) {\n\t\tif (dst_reg == src1) {\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {\n\t\t\tEMIT_MOV(compiler, dst_reg, 0, src1, src1w);\n\t\t\tsrc1 = src2_reg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tEMIT_MOV(compiler, dst_reg, 0, src2_reg, 0);\n\t}\n\n\tif (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) {\n\t\tif (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG2, 0, src1, src1w);\n\t\t\tsrc1 = TMP_REG2;\n\t\t\tsrc1w = 0;\n\t\t}\n\n\t\treturn emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w);\n\t}\n\n\treturn emit_cmov_generic(compiler, type, dst_reg, src1, src1w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 reg,\n\tsljit_s32 mem, sljit_sw memw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 i, next, reg_idx;\n\tsljit_u8 regs[2];\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));\n\n\tif (!(reg & REG_PAIR_MASK))\n\t\treturn sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);\n\n\tADJUST_LOCAL_OFFSET(mem, memw);\n\n\tcompiler->mode32 = 0;\n\n\tif ((mem & REG_MASK) == 0) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, memw);\n\n\t\tmem = SLJIT_MEM1(TMP_REG1);\n\t\tmemw = 0;\n\t} else if (!(mem & OFFS_REG_MASK) && ((memw < HALFWORD_MIN) || (memw > HALFWORD_MAX - SSIZE_OF(sw)))) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, memw);\n\n\t\tmem = SLJIT_MEM2(mem & REG_MASK, TMP_REG1);\n\t\tmemw = 0;\n\t}\n\n\tregs[0] = U8(REG_PAIR_FIRST(reg));\n\tregs[1] = U8(REG_PAIR_SECOND(reg));\n\n\tnext = SSIZE_OF(sw);\n\n\tif (!(type & SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {\n\t\tif (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {\n\t\t\t/* Base and offset cannot be TMP_REG1. */\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, OFFS_REG(mem), 0);\n\n\t\t\tif (regs[1] == OFFS_REG(mem))\n\t\t\t\tnext = -SSIZE_OF(sw);\n\n\t\t\tmem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);\n\t\t} else {\n\t\t\tnext = -SSIZE_OF(sw);\n\n\t\t\tif (!(mem & OFFS_REG_MASK))\n\t\t\t\tmemw += SSIZE_OF(sw);\n\t\t}\n\t}\n\n\tfor (i = 0; i < 2; i++) {\n\t\treg_idx = next > 0 ? i : (i ^ 0x1);\n\t\treg = regs[reg_idx];\n\n\t\tif ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, (sljit_uw)(1 + 5));\n\t\t\tFAIL_IF(!inst);\n\n\t\t\tINC_SIZE(5);\n\n\t\t\tinst[0] = U8(REX_W | ((reg_map[reg] >= 8) ? REX_R : 0) | ((reg_map[mem & REG_MASK] >= 8) ? REX_B : 0) | ((reg_map[OFFS_REG(mem)] >= 8) ? REX_X : 0));\n\t\t\tinst[1] = (type & SLJIT_MEM_STORE) ? MOV_rm_r : MOV_r_rm;\n\t\t\tinst[2] = 0x44 | U8(reg_lmap[reg] << 3);\n\t\t\tinst[3] = U8(memw << 6) | U8(reg_lmap[OFFS_REG(mem)] << 3) | reg_lmap[mem & REG_MASK];\n\t\t\tinst[4] = sizeof(sljit_sw);\n\t\t} else if (type & SLJIT_MEM_STORE) {\n\t\t\tEMIT_MOV(compiler, mem, memw, reg, 0);\n\t\t} else {\n\t\t\tEMIT_MOV(compiler, reg, 0, mem, memw);\n\t\t}\n\n\t\tif (!(mem & OFFS_REG_MASK))\n\t\t\tmemw += next;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r;\n\n\tcompiler->mode32 = 0;\n\n\tif (src == SLJIT_IMM) {\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tif (!sign || ((sljit_u32)srcw <= 0x7fffffff))\n\t\t\t\treturn emit_do_imm32(compiler, reg_map[dst] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[dst]), srcw);\n\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = MOV_rm_i32;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\tcompiler->mode32 = 1;\n\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_i32;\n\t\tcompiler->mode32 = 0;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif ((dst & SLJIT_MEM) && FAST_IS_REG(src))\n\t\tdst_r = src;\n\telse {\n\t\tif (sign) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = MOVSXD_r_rm;\n\t\t} else {\n\t\t\tcompiler->mode32 = 1;\n\t\t\tEMIT_MOV(compiler, dst_r, 0, src, srcw);\n\t\t\tcompiler->mode32 = 0;\n\t\t}\n\t}\n\n\tif (dst & SLJIT_MEM) {\n\t\tcompiler->mode32 = 1;\n\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_r;\n\t\tcompiler->mode32 = 0;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;\n\tsljit_u8 *inst, *jump_inst1, *jump_inst2;\n\tsljit_uw size1, size2;\n\n\tcompiler->mode32 = 0;\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {\n\t\tif (src != SLJIT_IMM) {\n\t\t\tcompiler->mode32 = 1;\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\t\tcompiler->mode32 = 0;\n\t\t} else\n\t\t\tFAIL_IF(emit_do_imm32(compiler, reg_map[TMP_REG1] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[TMP_REG1]), srcw));\n\n\t\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0));\n\n\t\tcompiler->mode32 = 1;\n\n\t\tif (dst_r == TMP_FREG)\n\t\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (!FAST_IS_REG(src)) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\tsrc = TMP_REG1;\n\t}\n\n\tBINARY_IMM32(CMP, 0, src, 0);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JL_i8;\n\tjump_inst1 = inst;\n\n\tsize1 = compiler->size;\n\n\tcompiler->mode32 = 0;\n\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0));\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JMP_i8;\n\tjump_inst2 = inst;\n\n\tsize2 = compiler->size;\n\n\tjump_inst1[1] = U8(size2 - size1);\n\n\tif (src != TMP_REG1)\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, 0);\n\n\tEMIT_MOV(compiler, TMP_REG2, 0, src, 0);\n\n\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0);\n\tFAIL_IF(!inst);\n\tinst[1] |= SHR;\n\n\tcompiler->mode32 = 1;\n\tBINARY_IMM32(AND, 1, TMP_REG2, 0);\n\n\tcompiler->mode32 = 0;\n\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG2, 0);\n\tFAIL_IF(!inst);\n\tinst[0] = OR_r_rm;\n\n\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0));\n\tcompiler->mode32 = 1;\n\tFAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0));\n\n\tjump_inst2[1] = U8(compiler->size - size2);\n\n\tif (dst_r == TMP_FREG)\n\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 sljit_emit_fset(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_u8 rex, sljit_s32 is_zero)\n{\n\tsljit_u8 *inst;\n\tsljit_u32 size;\n\n\tif (is_zero) {\n\t\trex = freg_map[freg] >= 8 ? (REX_R | REX_B) : 0;\n\t} else {\n\t\tif (freg_map[freg] >= 8)\n\t\t\trex |= REX_R;\n\t\tif (reg_map[TMP_REG1] >= 8)\n\t\t\trex |= REX_B;\n\t}\n\n\tsize = (rex != 0) ? 5 : 4;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\n\t*inst++ = GROUP_66;\n\tif (rex != 0)\n\t\t*inst++ = rex;\n\tinst[0] = GROUP_0F;\n\n\tif (is_zero) {\n\t\tinst[1] = PXOR_x_xm;\n\t\tinst[2] = U8(freg_lmap[freg] | (freg_lmap[freg] << 3) | MOD_REG);\n\t} else {\n\t\tinst[1] = MOVD_x_rm;\n\t\tinst[2] = U8(reg_lmap[TMP_REG1] | (freg_lmap[freg] << 3) | MOD_REG);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f32 value)\n{\n\tunion {\n\t\tsljit_s32 imm;\n\t\tsljit_f32 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset32(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm != 0) {\n\t\tcompiler->mode32 = 1;\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm);\n\t}\n\n\treturn sljit_emit_fset(compiler, freg, 0, u.imm == 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,\n\tsljit_s32 freg, sljit_f64 value)\n{\n\tunion {\n\t\tsljit_sw imm;\n\t\tsljit_f64 value;\n\t} u;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fset64(compiler, freg, value));\n\n\tu.value = value;\n\n\tif (u.imm != 0) {\n\t\tcompiler->mode32 = 0;\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm);\n\t}\n\n\treturn sljit_emit_fset(compiler, freg, REX_W, u.imm == 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 freg, sljit_s32 reg)\n{\n\tsljit_u8 *inst;\n\tsljit_u32 size;\n\tsljit_u8 rex = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));\n\n\tif (!(op & SLJIT_32))\n\t\trex = REX_W;\n\n\tif (freg_map[freg] >= 8)\n\t\trex |= REX_R;\n\n\tif (reg_map[reg] >= 8)\n\t\trex |= REX_B;\n\n\tsize = (rex != 0) ? 5 : 4;\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\n\t*inst++ = GROUP_66;\n\tif (rex != 0)\n\t\t*inst++ = rex;\n\tinst[0] = GROUP_0F;\n\tinst[1] = GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x;\n\tinst[2] = U8(reg_lmap[reg] | (freg_lmap[freg] << 3) | MOD_REG);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)\n{\n\tsljit_s32 tmp, size;\n\n\t/* Don't adjust shadow stack if it isn't enabled.  */\n\tif (!cpu_has_shadow_stack())\n\t\treturn SLJIT_SUCCESS;\n\n\tsize = compiler->local_size;\n\ttmp = compiler->scratches;\n\tif (tmp >= SLJIT_FIRST_SAVED_REG)\n\t\tsize += (tmp - SLJIT_FIRST_SAVED_REG + 1) * SSIZE_OF(sw);\n\ttmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;\n\tif (SLJIT_S0 >= tmp)\n\t\tsize += (SLJIT_S0 - tmp + 1) * SSIZE_OF(sw);\n\n\treturn adjust_shadow_stack(compiler, SLJIT_MEM1(SLJIT_SP), size);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nSLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)\n{\n\treturn \"x86\" SLJIT_CPUINFO;\n}\n\n/*\n   32b register indexes:\n     0 - EAX\n     1 - ECX\n     2 - EDX\n     3 - EBX\n     4 - ESP\n     5 - EBP\n     6 - ESI\n     7 - EDI\n*/\n\n/*\n   64b register indexes:\n     0 - RAX\n     1 - RCX\n     2 - RDX\n     3 - RBX\n     4 - RSP\n     5 - RBP\n     6 - RSI\n     7 - RDI\n     8 - R8   - From now on REX prefix is required\n     9 - R9\n    10 - R10\n    11 - R11\n    12 - R12\n    13 - R13\n    14 - R14\n    15 - R15\n*/\n\n#define TMP_REG1\t(SLJIT_NUMBER_OF_REGISTERS + 2)\n#define TMP_FREG\t(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {\n\t0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 5, 7, 6, 4, 3\n};\n\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {\n\t0, 1, 2, 3, 4, 5, 6, 7, 0\n};\n\n#define CHECK_EXTRA_REGS(p, w, do) \\\n\tif (p >= SLJIT_R3 && p <= SLJIT_S3) { \\\n\t\tw = (2 * SSIZE_OF(sw)) + ((p) - SLJIT_R3) * SSIZE_OF(sw); \\\n\t\tp = SLJIT_MEM1(SLJIT_SP); \\\n\t\tdo; \\\n\t}\n\n#else /* SLJIT_CONFIG_X86_32 */\n\n#define TMP_REG2\t(SLJIT_NUMBER_OF_REGISTERS + 3)\n\n/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present\n   Note: avoid to use r12 and r13 for memory addressing\n   therefore r12 is better to be a higher saved register. */\n#ifndef _WIN64\n/* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {\n\t0, 0, 6, 7, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 9\n};\n/* low-map. reg_map & 0x7. */\nstatic const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {\n\t0, 0, 6, 7, 1, 0,  3,  2,  4, 5,  5,  6,  7, 3, 4, 2, 1\n};\n#else\n/* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */\nstatic const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {\n\t0, 0, 2, 8, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 9, 10\n};\n/* low-map. reg_map & 0x7. */\nstatic const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {\n\t0, 0, 2, 0, 1,  3,  4, 5,  5,  6,  7, 7, 6, 3, 4, 1,  2\n};\n#endif\n\n/* Args: xmm0-xmm3 */\nstatic const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {\n\t0, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4\n};\n/* low-map. freg_map & 0x7. */\nstatic const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {\n\t0, 0, 1, 2, 3, 5, 6, 7, 0, 1,  2,  3,  4,  5,  6,  7, 4\n};\n\n#define REX_W\t\t0x48\n#define REX_R\t\t0x44\n#define REX_X\t\t0x42\n#define REX_B\t\t0x41\n#define REX\t\t0x40\n\n#ifndef _WIN64\n#define HALFWORD_MAX 0x7fffffffl\n#define HALFWORD_MIN -0x80000000l\n#else\n#define HALFWORD_MAX 0x7fffffffll\n#define HALFWORD_MIN -0x80000000ll\n#endif\n\n#define IS_HALFWORD(x)\t\t((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN)\n#define NOT_HALFWORD(x)\t\t((x) > HALFWORD_MAX || (x) < HALFWORD_MIN)\n\n#define CHECK_EXTRA_REGS(p, w, do)\n\n#endif /* SLJIT_CONFIG_X86_32 */\n\n#define U8(v)\t\t\t((sljit_u8)(v))\n\n/* Size flags for emit_x86_instruction: */\n#define EX86_BIN_INS\t\t((sljit_uw)0x000010)\n#define EX86_SHIFT_INS\t\t((sljit_uw)0x000020)\n#define EX86_BYTE_ARG\t\t((sljit_uw)0x000040)\n#define EX86_HALF_ARG\t\t((sljit_uw)0x000080)\n/* Size flags for both emit_x86_instruction and emit_vex_instruction: */\n#define EX86_REX\t\t((sljit_uw)0x000100)\n#define EX86_NO_REXW\t\t((sljit_uw)0x000200)\n#define EX86_PREF_66\t\t((sljit_uw)0x000400)\n#define EX86_PREF_F2\t\t((sljit_uw)0x000800)\n#define EX86_PREF_F3\t\t((sljit_uw)0x001000)\n#define EX86_SSE2_OP1\t\t((sljit_uw)0x002000)\n#define EX86_SSE2_OP2\t\t((sljit_uw)0x004000)\n#define EX86_SSE2\t\t(EX86_SSE2_OP1 | EX86_SSE2_OP2)\n#define EX86_VEX_EXT\t\t((sljit_uw)0x008000)\n/* Op flags for emit_vex_instruction: */\n#define VEX_OP_0F38\t\t((sljit_uw)0x010000)\n#define VEX_OP_0F3A\t\t((sljit_uw)0x020000)\n#define VEX_SSE2_OPV\t\t((sljit_uw)0x040000)\n#define VEX_AUTO_W\t\t((sljit_uw)0x080000)\n#define VEX_W\t\t\t((sljit_uw)0x100000)\n#define VEX_256\t\t\t((sljit_uw)0x200000)\n\n#define EX86_SELECT_66(op)\t(((op) & SLJIT_32) ? 0 : EX86_PREF_66)\n#define EX86_SELECT_F2_F3(op)\t(((op) & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2)\n\n/* --------------------------------------------------------------------- */\n/*  Instruction forms                                                    */\n/* --------------------------------------------------------------------- */\n\n#define ADD\t\t\t(/* BINARY */ 0 << 3)\n#define ADD_EAX_i32\t\t0x05\n#define ADD_r_rm\t\t0x03\n#define ADD_rm_r\t\t0x01\n#define ADDSD_x_xm\t\t0x58\n#define ADC\t\t\t(/* BINARY */ 2 << 3)\n#define ADC_EAX_i32\t\t0x15\n#define ADC_r_rm\t\t0x13\n#define ADC_rm_r\t\t0x11\n#define AND\t\t\t(/* BINARY */ 4 << 3)\n#define AND_EAX_i32\t\t0x25\n#define AND_r_rm\t\t0x23\n#define AND_rm_r\t\t0x21\n#define ANDPD_x_xm\t\t0x54\n#define BSR_r_rm\t\t(/* GROUP_0F */ 0xbd)\n#define BSF_r_rm\t\t(/* GROUP_0F */ 0xbc)\n#define BSWAP_r\t\t\t(/* GROUP_0F */ 0xc8)\n#define CALL_i32\t\t0xe8\n#define CALL_rm\t\t\t(/* GROUP_FF */ 2 << 3)\n#define CDQ\t\t\t0x99\n#define CMOVE_r_rm\t\t(/* GROUP_0F */ 0x44)\n#define CMP\t\t\t(/* BINARY */ 7 << 3)\n#define CMP_EAX_i32\t\t0x3d\n#define CMP_r_rm\t\t0x3b\n#define CMP_rm_r\t\t0x39\n#define CMPS_x_xm\t\t0xc2\n#define CMPXCHG_rm_r\t\t0xb1\n#define CMPXCHG_rm8_r\t\t0xb0\n#define CVTPD2PS_x_xm\t\t0x5a\n#define CVTPS2PD_x_xm\t\t0x5a\n#define CVTSI2SD_x_rm\t\t0x2a\n#define CVTTSD2SI_r_xm\t\t0x2c\n#define DIV\t\t\t(/* GROUP_F7 */ 6 << 3)\n#define DIVSD_x_xm\t\t0x5e\n#define EXTRACTPS_x_xm\t\t0x17\n#define FLDS\t\t\t0xd9\n#define FLDL\t\t\t0xdd\n#define FSTPS\t\t\t0xd9\n#define FSTPD\t\t\t0xdd\n#define INSERTPS_x_xm\t\t0x21\n#define INT3\t\t\t0xcc\n#define IDIV\t\t\t(/* GROUP_F7 */ 7 << 3)\n#define IMUL\t\t\t(/* GROUP_F7 */ 5 << 3)\n#define IMUL_r_rm\t\t(/* GROUP_0F */ 0xaf)\n#define IMUL_r_rm_i8\t\t0x6b\n#define IMUL_r_rm_i32\t\t0x69\n#define JL_i8\t\t\t0x7c\n#define JE_i8\t\t\t0x74\n#define JNC_i8\t\t\t0x73\n#define JNE_i8\t\t\t0x75\n#define JMP_i8\t\t\t0xeb\n#define JMP_i32\t\t\t0xe9\n#define JMP_rm\t\t\t(/* GROUP_FF */ 4 << 3)\n#define LEA_r_m\t\t\t0x8d\n#define LOOP_i8\t\t\t0xe2\n#define LZCNT_r_rm\t\t(/* GROUP_F3 */ /* GROUP_0F */ 0xbd)\n#define MOV_r_rm\t\t0x8b\n#define MOV_r_i32\t\t0xb8\n#define MOV_rm_r\t\t0x89\n#define MOV_rm_i32\t\t0xc7\n#define MOV_rm8_i8\t\t0xc6\n#define MOV_rm8_r8\t\t0x88\n#define MOVAPS_x_xm\t\t0x28\n#define MOVAPS_xm_x\t\t0x29\n#define MOVD_x_rm\t\t0x6e\n#define MOVD_rm_x\t\t0x7e\n#define MOVDDUP_x_xm\t\t0x12\n#define MOVDQA_x_xm\t\t0x6f\n#define MOVDQA_xm_x\t\t0x7f\n#define MOVDQU_x_xm\t\t0x6f\n#define MOVHLPS_x_x\t\t0x12\n#define MOVHPD_m_x\t\t0x17\n#define MOVHPD_x_m\t\t0x16\n#define MOVLHPS_x_x\t\t0x16\n#define MOVLPD_m_x\t\t0x13\n#define MOVLPD_x_m\t\t0x12\n#define MOVMSKPS_r_x\t\t(/* GROUP_0F */ 0x50)\n#define MOVQ_x_xm\t\t(/* GROUP_0F */ 0x7e)\n#define MOVSD_x_xm\t\t0x10\n#define MOVSD_xm_x\t\t0x11\n#define MOVSHDUP_x_xm\t\t0x16\n#define MOVSXD_r_rm\t\t0x63\n#define MOVSX_r_rm8\t\t(/* GROUP_0F */ 0xbe)\n#define MOVSX_r_rm16\t\t(/* GROUP_0F */ 0xbf)\n#define MOVUPS_x_xm\t\t0x10\n#define MOVZX_r_rm8\t\t(/* GROUP_0F */ 0xb6)\n#define MOVZX_r_rm16\t\t(/* GROUP_0F */ 0xb7)\n#define MUL\t\t\t(/* GROUP_F7 */ 4 << 3)\n#define MULSD_x_xm\t\t0x59\n#define NEG_rm\t\t\t(/* GROUP_F7 */ 3 << 3)\n#define NOP\t\t\t0x90\n#define NOT_rm\t\t\t(/* GROUP_F7 */ 2 << 3)\n#define OR\t\t\t(/* BINARY */ 1 << 3)\n#define OR_r_rm\t\t\t0x0b\n#define OR_EAX_i32\t\t0x0d\n#define OR_rm_r\t\t\t0x09\n#define OR_rm8_r8\t\t0x08\n#define ORPD_x_xm\t\t0x56\n#define PACKSSWB_x_xm\t\t(/* GROUP_0F */ 0x63)\n#define PAND_x_xm\t\t0xdb\n#define PCMPEQD_x_xm\t\t0x76\n#define PINSRB_x_rm_i8\t\t0x20\n#define PINSRW_x_rm_i8\t\t0xc4\n#define PINSRD_x_rm_i8\t\t0x22\n#define PEXTRB_rm_x_i8\t\t0x14\n#define PEXTRW_rm_x_i8\t\t0x15\n#define PEXTRD_rm_x_i8\t\t0x16\n#define PMOVMSKB_r_x\t\t(/* GROUP_0F */ 0xd7)\n#define PMOVSXBD_x_xm\t\t0x21\n#define PMOVSXBQ_x_xm\t\t0x22\n#define PMOVSXBW_x_xm\t\t0x20\n#define PMOVSXDQ_x_xm\t\t0x25\n#define PMOVSXWD_x_xm\t\t0x23\n#define PMOVSXWQ_x_xm\t\t0x24\n#define PMOVZXBD_x_xm\t\t0x31\n#define PMOVZXBQ_x_xm\t\t0x32\n#define PMOVZXBW_x_xm\t\t0x30\n#define PMOVZXDQ_x_xm\t\t0x35\n#define PMOVZXWD_x_xm\t\t0x33\n#define PMOVZXWQ_x_xm\t\t0x34\n#define POP_r\t\t\t0x58\n#define POP_rm\t\t\t0x8f\n#define POPF\t\t\t0x9d\n#define POR_x_xm\t\t0xeb\n#define PREFETCH\t\t0x18\n#define PSHUFB_x_xm\t\t0x00\n#define PSHUFD_x_xm\t\t0x70\n#define PSHUFLW_x_xm\t\t0x70\n#define PSRLDQ_x\t\t0x73\n#define PSLLD_x_i8\t\t0x72\n#define PSLLQ_x_i8\t\t0x73\n#define PUSH_i32\t\t0x68\n#define PUSH_r\t\t\t0x50\n#define PUSH_rm\t\t\t(/* GROUP_FF */ 6 << 3)\n#define PUSHF\t\t\t0x9c\n#define PXOR_x_xm\t\t0xef\n#define ROL\t\t\t(/* SHIFT */ 0 << 3)\n#define ROR\t\t\t(/* SHIFT */ 1 << 3)\n#define RET_near\t\t0xc3\n#define RET_i16\t\t\t0xc2\n#define SBB\t\t\t(/* BINARY */ 3 << 3)\n#define SBB_EAX_i32\t\t0x1d\n#define SBB_r_rm\t\t0x1b\n#define SBB_rm_r\t\t0x19\n#define SAR\t\t\t(/* SHIFT */ 7 << 3)\n#define SHL\t\t\t(/* SHIFT */ 4 << 3)\n#define SHLD\t\t\t(/* GROUP_0F */ 0xa5)\n#define SHRD\t\t\t(/* GROUP_0F */ 0xad)\n#define SHR\t\t\t(/* SHIFT */ 5 << 3)\n#define SHUFPS_x_xm\t\t0xc6\n#define SUB\t\t\t(/* BINARY */ 5 << 3)\n#define SUB_EAX_i32\t\t0x2d\n#define SUB_r_rm\t\t0x2b\n#define SUB_rm_r\t\t0x29\n#define SUBSD_x_xm\t\t0x5c\n#define TEST_EAX_i32\t\t0xa9\n#define TEST_rm_r\t\t0x85\n#define TZCNT_r_rm\t\t(/* GROUP_F3 */ /* GROUP_0F */ 0xbc)\n#define UCOMISD_x_xm\t\t0x2e\n#define UNPCKLPD_x_xm\t\t0x14\n#define UNPCKLPS_x_xm\t\t0x14\n#define VBROADCASTSD_x_xm\t0x19\n#define VBROADCASTSS_x_xm\t0x18\n#define VEXTRACTF128_x_ym\t0x19\n#define VEXTRACTI128_x_ym\t0x39\n#define VINSERTF128_y_y_xm\t0x18\n#define VINSERTI128_y_y_xm\t0x38\n#define VPBROADCASTB_x_xm\t0x78\n#define VPBROADCASTD_x_xm\t0x58\n#define VPBROADCASTQ_x_xm\t0x59\n#define VPBROADCASTW_x_xm\t0x79\n#define VPERMPD_y_ym\t\t0x01\n#define VPERMQ_y_ym\t\t0x00\n#define XCHG_EAX_r\t\t0x90\n#define XCHG_r_rm\t\t0x87\n#define XOR\t\t\t(/* BINARY */ 6 << 3)\n#define XOR_EAX_i32\t\t0x35\n#define XOR_r_rm\t\t0x33\n#define XOR_rm_r\t\t0x31\n#define XORPD_x_xm\t\t0x57\n\n#define GROUP_0F\t\t0x0f\n#define GROUP_66\t\t0x66\n#define GROUP_F3\t\t0xf3\n#define GROUP_F7\t\t0xf7\n#define GROUP_FF\t\t0xff\n#define GROUP_BINARY_81\t\t0x81\n#define GROUP_BINARY_83\t\t0x83\n#define GROUP_SHIFT_1\t\t0xd1\n#define GROUP_SHIFT_N\t\t0xc1\n#define GROUP_SHIFT_CL\t\t0xd3\n#define GROUP_LOCK\t\t0xf0\n\n#define MOD_REG\t\t\t0xc0\n#define MOD_DISP8\t\t0x40\n\n#define INC_SIZE(s)\t\t(*inst++ = U8(s), compiler->size += (s))\n\n#define PUSH_REG(r)\t\t(*inst++ = U8(PUSH_r + (r)))\n#define POP_REG(r)\t\t(*inst++ = U8(POP_r + (r)))\n#define RET()\t\t\t(*inst++ = RET_near)\n#define RET_I16(n)\t\t(*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0)\n\n#define SLJIT_INST_LABEL\t255\n#define SLJIT_INST_JUMP\t\t254\n#define SLJIT_INST_MOV_ADDR\t253\n#define SLJIT_INST_CONST\t252\n\n/* Multithreading does not affect these static variables, since they store\n   built-in CPU features. Therefore they can be overwritten by different threads\n   if they detect the CPU features in the same time. */\n#define CPU_FEATURE_DETECTED\t\t0x001\n#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)\n#define CPU_FEATURE_SSE2\t\t0x002\n#endif\n#define CPU_FEATURE_SSE41\t\t0x004\n#define CPU_FEATURE_LZCNT\t\t0x008\n#define CPU_FEATURE_TZCNT\t\t0x010\n#define CPU_FEATURE_CMOV\t\t0x020\n#define CPU_FEATURE_AVX\t\t\t0x040\n#define CPU_FEATURE_AVX2\t\t0x080\n#define CPU_FEATURE_OSXSAVE\t\t0x100\n\nstatic sljit_u32 cpu_feature_list = 0;\n\n#ifdef _WIN32_WCE\n#include <cmnintrin.h>\n#elif defined(_MSC_VER) && _MSC_VER >= 1400\n#include <intrin.h>\n#elif defined(__INTEL_COMPILER)\n#include <cpuid.h>\n#endif\n\n#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \\\n\t|| (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__))\n#include <immintrin.h>\n#endif\n\n/******************************************************/\n/*    Unaligned-store functions                       */\n/******************************************************/\n\nstatic SLJIT_INLINE void sljit_unaligned_store_s16(void *addr, sljit_s16 value)\n{\n\tSLJIT_MEMCPY(addr, &value, sizeof(value));\n}\n\nstatic SLJIT_INLINE void sljit_unaligned_store_s32(void *addr, sljit_s32 value)\n{\n\tSLJIT_MEMCPY(addr, &value, sizeof(value));\n}\n\nstatic SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value)\n{\n\tSLJIT_MEMCPY(addr, &value, sizeof(value));\n}\n\n/******************************************************/\n/*    Utility functions                               */\n/******************************************************/\n\nstatic void execute_cpu_id(sljit_u32 info[4])\n{\n#if (defined(_MSC_VER) && _MSC_VER >= 1400) \\\n\t|| (defined(__INTEL_COMPILER) && __INTEL_COMPILER == 2021 && __INTEL_COMPILER_UPDATE >= 7)\n\n\t__cpuidex((int*)info, (int)info[0], (int)info[2]);\n\n#elif (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900)\n\n\t__get_cpuid_count(info[0], info[2], info, info + 1, info + 2, info + 3);\n\n#elif (defined(_MSC_VER) || defined(__INTEL_COMPILER)) \\\n\t&& (defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32)\n\n\t/* Intel syntax. */\n\t__asm {\n\t\tmov esi, info\n\t\tmov eax, [esi]\n\t\tmov ecx, [esi + 8]\n\t\tcpuid\n\t\tmov [esi], eax\n\t\tmov [esi + 4], ebx\n\t\tmov [esi + 8], ecx\n\t\tmov [esi + 12], edx\n\t}\n\n#else\n\n\t__asm__ __volatile__ (\n\t\t\"cpuid\\n\"\n\t\t: \"=a\" (info[0]), \"=b\" (info[1]), \"=c\" (info[2]), \"=d\" (info[3])\n\t\t: \"0\" (info[0]), \"2\" (info[2])\n\t);\n\n#endif\n}\n\nstatic sljit_u32 execute_get_xcr0_low(void)\n{\n\tsljit_u32 xcr0;\n\n#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \\\n\t|| (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__))\n\n\txcr0 = (sljit_u32)_xgetbv(0);\n\n#elif defined(__TINYC__)\n\n\t__asm__ (\n\t\t\"xorl %%ecx, %%ecx\\n\"\n\t\t\".byte 0x0f\\n\"\n\t\t\".byte 0x01\\n\"\n\t\t\".byte 0xd0\\n\"\n\t\t: \"=a\" (xcr0)\n\t\t:\n#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32\n\t\t: \"ecx\", \"edx\"\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\t: \"rcx\", \"rdx\"\n#endif /* SLJIT_CONFIG_X86_32 */\n\t);\n\n#elif (defined(__INTEL_LLVM_COMPILER) && __INTEL_LLVM_COMPILER < 20220100) \\\n\t|| (defined(__clang__) && __clang_major__ < 14) \\\n\t|| (defined(__GNUC__) && __GNUC__ < 3) \\\n\t|| defined(__SUNPRO_C) || defined(__SUNPRO_CC)\n\n\t/* AT&T syntax. */\n\t__asm__ (\n\t\t\"xorl %%ecx, %%ecx\\n\"\n\t\t\"xgetbv\\n\"\n\t\t: \"=a\" (xcr0)\n\t\t:\n#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32\n\t\t: \"ecx\", \"edx\"\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\t: \"rcx\", \"rdx\"\n#endif /* SLJIT_CONFIG_X86_32 */\n\t);\n\n#elif defined(_MSC_VER)\n\n\t/* Intel syntax. */\n\t__asm {\n\t\txor ecx, ecx\n\t\txgetbv\n\t\tmov xcr0, eax\n\t}\n\n#else\n\n\t__asm__ (\n\t\t\"xor{l %%ecx, %%ecx | ecx, ecx}\\n\"\n\t\t\"xgetbv\\n\"\n\t\t: \"=a\" (xcr0)\n\t\t:\n#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32\n\t\t: \"ecx\", \"edx\"\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\t: \"rcx\", \"rdx\"\n#endif /* SLJIT_CONFIG_X86_32 */\n\t);\n\n#endif\n\treturn xcr0;\n}\n\nstatic void get_cpu_features(void)\n{\n\tsljit_u32 feature_list = CPU_FEATURE_DETECTED;\n\tsljit_u32 info[4] = {0};\n\tsljit_u32 max_id;\n\n\texecute_cpu_id(info);\n\tmax_id = info[0];\n\n\tif (max_id >= 7) {\n\t\tinfo[0] = 7;\n\t\tinfo[2] = 0;\n\t\texecute_cpu_id(info);\n\n\t\tif (info[1] & 0x8)\n\t\t\tfeature_list |= CPU_FEATURE_TZCNT;\n\t\tif (info[1] & 0x20)\n\t\t\tfeature_list |= CPU_FEATURE_AVX2;\n\t}\n\n\tif (max_id >= 1) {\n\t\tinfo[0] = 1;\n#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32\n\t\t/* Winchip 2 and Cyrix MII bugs */\n\t\tinfo[1] = info[2] = 0;\n#endif\n\t\texecute_cpu_id(info);\n\n\t\tif (info[2] & 0x80000)\n\t\t\tfeature_list |= CPU_FEATURE_SSE41;\n\t\tif (info[2] & 0x8000000)\n\t\t\tfeature_list |= CPU_FEATURE_OSXSAVE;\n\t\tif (info[2] & 0x10000000)\n\t\t\tfeature_list |= CPU_FEATURE_AVX;\n#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)\n\t\tif (info[3] & 0x4000000)\n\t\t\tfeature_list |= CPU_FEATURE_SSE2;\n#endif\n\t\tif (info[3] & 0x8000)\n\t\t\tfeature_list |= CPU_FEATURE_CMOV;\n\t}\n\n\tinfo[0] = 0x80000000;\n\texecute_cpu_id(info);\n\tmax_id = info[0];\n\n\tif (max_id >= 0x80000001) {\n\t\tinfo[0] = 0x80000001;\n\t\texecute_cpu_id(info);\n\n\t\tif (info[2] & 0x20)\n\t\t\tfeature_list |= CPU_FEATURE_LZCNT;\n\t}\n\n\tif ((feature_list & CPU_FEATURE_OSXSAVE) && (execute_get_xcr0_low() & 0x4) == 0)\n\t\tfeature_list &= ~(sljit_u32)(CPU_FEATURE_AVX | CPU_FEATURE_AVX2);\n\n\tcpu_feature_list = feature_list;\n}\n\nstatic sljit_u8 get_jump_code(sljit_uw type)\n{\n\tswitch (type) {\n\tcase SLJIT_EQUAL:\n\tcase SLJIT_ATOMIC_STORED:\n\tcase SLJIT_F_EQUAL:\n\tcase SLJIT_UNORDERED_OR_EQUAL:\n\t\treturn 0x84 /* je */;\n\n\tcase SLJIT_NOT_EQUAL:\n\tcase SLJIT_ATOMIC_NOT_STORED:\n\tcase SLJIT_F_NOT_EQUAL:\n\tcase SLJIT_ORDERED_NOT_EQUAL:\n\t\treturn 0x85 /* jne */;\n\n\tcase SLJIT_LESS:\n\tcase SLJIT_CARRY:\n\tcase SLJIT_F_LESS:\n\tcase SLJIT_UNORDERED_OR_LESS:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\treturn 0x82 /* jc */;\n\n\tcase SLJIT_GREATER_EQUAL:\n\tcase SLJIT_NOT_CARRY:\n\tcase SLJIT_F_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_GREATER_EQUAL:\n\tcase SLJIT_ORDERED_LESS_EQUAL:\n\t\treturn 0x83 /* jae */;\n\n\tcase SLJIT_GREATER:\n\tcase SLJIT_F_GREATER:\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_ORDERED_GREATER:\n\t\treturn 0x87 /* jnbe */;\n\n\tcase SLJIT_LESS_EQUAL:\n\tcase SLJIT_F_LESS_EQUAL:\n\tcase SLJIT_UNORDERED_OR_GREATER_EQUAL:\n\tcase SLJIT_UNORDERED_OR_LESS_EQUAL:\n\t\treturn 0x86 /* jbe */;\n\n\tcase SLJIT_SIG_LESS:\n\t\treturn 0x8c /* jl */;\n\n\tcase SLJIT_SIG_GREATER_EQUAL:\n\t\treturn 0x8d /* jnl */;\n\n\tcase SLJIT_SIG_GREATER:\n\t\treturn 0x8f /* jnle */;\n\n\tcase SLJIT_SIG_LESS_EQUAL:\n\t\treturn 0x8e /* jle */;\n\n\tcase SLJIT_OVERFLOW:\n\t\treturn 0x80 /* jo */;\n\n\tcase SLJIT_NOT_OVERFLOW:\n\t\treturn 0x81 /* jno */;\n\n\tcase SLJIT_UNORDERED:\n\tcase SLJIT_ORDERED_EQUAL: /* NaN. */\n\t\treturn 0x8a /* jp */;\n\n\tcase SLJIT_ORDERED:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not NaN. */\n\t\treturn 0x8b /* jpo */;\n\t}\n\treturn 0;\n}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\nstatic sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);\n#else /* !SLJIT_CONFIG_X86_32 */\nstatic sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr);\nstatic sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset);\n#endif /* SLJIT_CONFIG_X86_32 */\n\nstatic sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)\n{\n\tsljit_uw type = jump->flags >> TYPE_SHIFT;\n\tsljit_s32 short_jump;\n\tsljit_uw label_addr;\n\tsljit_uw jump_addr;\n\n\tjump_addr = (sljit_uw)code_ptr;\n\tif (!(jump->flags & JUMP_ADDR)) {\n\t\tlabel_addr = (sljit_uw)(code + jump->u.label->size);\n\n\t\tif (jump->u.label->size > jump->addr)\n\t\t\tjump_addr = (sljit_uw)(code + jump->addr);\n\t} else\n\t\tlabel_addr = jump->u.target - (sljit_uw)executable_offset;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif ((sljit_sw)(label_addr - (jump_addr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump_addr + 5)) < HALFWORD_MIN)\n\t\treturn detect_far_jump_type(jump, code_ptr);\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tshort_jump = (sljit_sw)(label_addr - (jump_addr + 2)) >= -0x80 && (sljit_sw)(label_addr - (jump_addr + 2)) <= 0x7f;\n\n\tif (type == SLJIT_JUMP) {\n\t\tif (short_jump)\n\t\t\t*code_ptr++ = JMP_i8;\n\t\telse\n\t\t\t*code_ptr++ = JMP_i32;\n\t} else if (type > SLJIT_JUMP) {\n\t\tshort_jump = 0;\n\t\t*code_ptr++ = CALL_i32;\n\t} else if (short_jump) {\n\t\t*code_ptr++ = U8(get_jump_code(type) - 0x10);\n\t} else {\n\t\t*code_ptr++ = GROUP_0F;\n\t\t*code_ptr++ = get_jump_code(type);\n\t}\n\n\tjump->addr = (sljit_uw)code_ptr;\n\n\tif (short_jump) {\n\t\tjump->flags |= PATCH_MB;\n\t\tcode_ptr += sizeof(sljit_s8);\n\t} else {\n\t\tjump->flags |= PATCH_MW;\n\t\tcode_ptr += sizeof(sljit_s32);\n\t}\n\n\treturn code_ptr;\n}\n\nstatic void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)\n{\n\tsljit_uw flags = jump->flags;\n\tsljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;\n\tsljit_uw jump_addr = jump->addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tif (SLJIT_UNLIKELY(flags & JUMP_MOV_ADDR)) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tsljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr);\n#else /* SLJIT_CONFIG_X86_32 */\n\t\tif (flags & PATCH_MD) {\n\t\t\tSLJIT_ASSERT(addr > HALFWORD_MAX);\n\t\t\tsljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr);\n\t\t\treturn;\n\t\t}\n\n\t\tif (flags & PATCH_MW) {\n\t\t\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset);\n\t\t\tSLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN);\n\t\t} else {\n\t\t\tSLJIT_ASSERT(addr <= HALFWORD_MAX);\n\t\t}\n\t\tsljit_unaligned_store_s32((void*)(jump_addr - sizeof(sljit_s32)), (sljit_s32)addr);\n#endif /* !SLJIT_CONFIG_X86_32 */\n\t\treturn;\n\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (SLJIT_UNLIKELY(flags & PATCH_MD)) {\n\t\tSLJIT_ASSERT(!(flags & JUMP_ADDR));\n\t\tsljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr);\n\t\treturn;\n\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\taddr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset);\n\n\tif (flags & PATCH_MB) {\n\t\taddr -= sizeof(sljit_s8);\n\t\tSLJIT_ASSERT((sljit_sw)addr <= 0x7f && (sljit_sw)addr >= -0x80);\n\t\t*(sljit_u8*)jump_addr = U8(addr);\n\t\treturn;\n\t} else if (flags & PATCH_MW) {\n\t\taddr -= sizeof(sljit_s32);\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tsljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr);\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\tSLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN);\n\t\tsljit_unaligned_store_s32((void*)jump_addr, (sljit_s32)addr);\n#endif /* SLJIT_CONFIG_X86_32 */\n\t}\n}\n\nstatic sljit_u8 *process_extended_label(sljit_u8 *code_ptr, struct sljit_extended_label *ext_label)\n{\n\tsljit_uw mask;\n\tsljit_u8 *ptr = code_ptr;\n\n\tSLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);\n\tmask = ext_label->data;\n\n\tcode_ptr = (sljit_u8*)(((sljit_uw)code_ptr + mask) & ~mask);\n\n\twhile (ptr < code_ptr)\n\t\t*ptr++ = NOP;\n\n\treturn code_ptr;\n}\n\nstatic void reduce_code_size(struct sljit_compiler *compiler)\n{\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tsljit_uw next_label_size;\n\tsljit_uw next_jump_addr;\n\tsljit_uw next_min_addr;\n\tsljit_uw size_reduce = 0;\n\tsljit_sw diff;\n\tsljit_uw type;\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tsljit_uw size_reduce_max;\n#endif /* SLJIT_DEBUG */\n\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\n\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\n\twhile (1) {\n\t\tnext_min_addr = next_label_size;\n\t\tif (next_jump_addr < next_min_addr)\n\t\t\tnext_min_addr = next_jump_addr;\n\n\t\tif (next_min_addr == SLJIT_MAX_ADDRESS)\n\t\t\tbreak;\n\n\t\tif (next_min_addr == next_label_size) {\n\t\t\tlabel->size -= size_reduce;\n\n\t\t\tlabel = label->next;\n\t\t\tnext_label_size = SLJIT_GET_NEXT_SIZE(label);\n\t\t}\n\n\t\tif (next_min_addr != next_jump_addr)\n\t\t\tcontinue;\n\n\t\tjump->addr -= size_reduce;\n\t\tif (!(jump->flags & JUMP_MOV_ADDR)) {\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\tsize_reduce_max = size_reduce + (((jump->flags >> TYPE_SHIFT) < SLJIT_JUMP) ? CJUMP_MAX_SIZE : JUMP_MAX_SIZE);\n#endif /* SLJIT_DEBUG */\n\n\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {\n\t\t\t\tif (jump->flags & JUMP_ADDR) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\t\tif (jump->u.target <= 0xffffffffl)\n\t\t\t\t\t\tsize_reduce += sizeof(sljit_s32);\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\t} else {\n\t\t\t\t\t/* Unit size: instruction. */\n\t\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;\n\t\t\t\t\tif (jump->u.label->size > jump->addr) {\n\t\t\t\t\t\tSLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);\n\t\t\t\t\t\tdiff -= (sljit_sw)size_reduce;\n\t\t\t\t\t}\n\t\t\t\t\ttype = jump->flags >> TYPE_SHIFT;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\t\tif (type == SLJIT_JUMP) {\n\t\t\t\t\t\tif (diff <= 0x7f + 2 && diff >= -0x80 + 2)\n\t\t\t\t\t\t\tsize_reduce += JUMP_MAX_SIZE - 2;\n\t\t\t\t\t\telse if (diff <= HALFWORD_MAX + 5 && diff >= HALFWORD_MIN + 5)\n\t\t\t\t\t\t\tsize_reduce += JUMP_MAX_SIZE - 5;\n\t\t\t\t\t} else if (type < SLJIT_JUMP) {\n\t\t\t\t\t\tif (diff <= 0x7f + 2 && diff >= -0x80 + 2)\n\t\t\t\t\t\t\tsize_reduce += CJUMP_MAX_SIZE - 2;\n\t\t\t\t\t\telse if (diff <= HALFWORD_MAX + 6 && diff >= HALFWORD_MIN + 6)\n\t\t\t\t\t\t\tsize_reduce += CJUMP_MAX_SIZE - 6;\n\t\t\t\t\t} else  {\n\t\t\t\t\t\tif (diff <= HALFWORD_MAX + 5 && diff >= HALFWORD_MIN + 5)\n\t\t\t\t\t\t\tsize_reduce += JUMP_MAX_SIZE - 5;\n\t\t\t\t\t}\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\t\t\t\tif (type == SLJIT_JUMP) {\n\t\t\t\t\t\tif (diff <= 0x7f + 2 && diff >= -0x80 + 2)\n\t\t\t\t\t\t\tsize_reduce += JUMP_MAX_SIZE - 2;\n\t\t\t\t\t} else if (type < SLJIT_JUMP) {\n\t\t\t\t\t\tif (diff <= 0x7f + 2 && diff >= -0x80 + 2)\n\t\t\t\t\t\t\tsize_reduce += CJUMP_MAX_SIZE - 2;\n\t\t\t\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\t}\n\t\t\t}\n\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\tjump->flags |= (size_reduce_max - size_reduce) << JUMP_SIZE_SHIFT;\n#endif /* SLJIT_DEBUG */\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t} else {\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\tsize_reduce_max = size_reduce + 10;\n#endif /* SLJIT_DEBUG */\n\n\t\t\tif (!(jump->flags & JUMP_ADDR)) {\n\t\t\t\tdiff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - 3);\n\n\t\t\t\tif (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN)\n\t\t\t\t\tsize_reduce += 3;\n\t\t\t} else if (jump->u.target <= 0xffffffffl)\n\t\t\t\tsize_reduce += (jump->flags & MOV_ADDR_HI) ? 4 : 5;\n\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\tjump->flags |= (size_reduce_max - size_reduce) << JUMP_SIZE_SHIFT;\n#endif /* SLJIT_DEBUG */\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t}\n\n\t\tjump = jump->next;\n\t\tnext_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);\n\t}\n\n\tcompiler->size -= size_reduce;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)\n{\n\tstruct sljit_memory_fragment *buf;\n\tsljit_u8 *code;\n\tsljit_u8 *code_ptr;\n\tsljit_u8 *buf_ptr;\n\tsljit_u8 *buf_end;\n\tsljit_u8 len;\n\tsljit_sw executable_offset;\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tsljit_uw addr;\n#endif /* SLJIT_DEBUG */\n\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_generate_code(compiler, options));\n\n\treduce_code_size(compiler);\n\n\t/* Second code generation pass. */\n\tcode = (sljit_u8*)allocate_executable_memory(compiler->size, options, exec_allocator_data, &executable_offset);\n\tPTR_FAIL_WITH_EXEC_IF(code);\n\n\treverse_buf(compiler);\n\tbuf = compiler->buf;\n\n\tcode_ptr = code;\n\tlabel = compiler->labels;\n\tjump = compiler->jumps;\n\tconst_ = compiler->consts;\n\n\tdo {\n\t\tbuf_ptr = buf->memory;\n\t\tbuf_end = buf_ptr + buf->used_size;\n\t\tdo {\n\t\t\tlen = *buf_ptr++;\n\t\t\tSLJIT_ASSERT(len > 0);\n\t\t\tif (len < SLJIT_INST_CONST) {\n\t\t\t\t/* The code is already generated. */\n\t\t\t\tSLJIT_MEMCPY(code_ptr, buf_ptr, len);\n\t\t\t\tcode_ptr += len;\n\t\t\t\tbuf_ptr += len;\n\t\t\t} else {\n\t\t\t\tswitch (len) {\n\t\t\t\tcase SLJIT_INST_LABEL:\n\t\t\t\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\t\t\t\tcode_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);\n\n\t\t\t\t\tlabel->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);\n\t\t\t\t\tlabel->size = (sljit_uw)(code_ptr - code);\n\t\t\t\t\tlabel = label->next;\n\t\t\t\t\tbreak;\n\t\t\t\tcase SLJIT_INST_JUMP:\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\t\t\t\taddr = (sljit_uw)code_ptr;\n#endif /* SLJIT_DEBUG */\n\t\t\t\t\tif (!(jump->flags & SLJIT_REWRITABLE_JUMP))\n\t\t\t\t\t\tcode_ptr = detect_near_jump_type(jump, code_ptr, code, executable_offset);\n\t\t\t\t\telse {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\t\t\t\tcode_ptr = detect_far_jump_type(jump, code_ptr, executable_offset);\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\t\t\t\t\tcode_ptr = detect_far_jump_type(jump, code_ptr);\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\t\t\t\t}\n\n\t\t\t\t\tSLJIT_ASSERT((sljit_uw)code_ptr - addr <= ((jump->flags >> JUMP_SIZE_SHIFT) & 0xff));\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tbreak;\n\t\t\t\tcase SLJIT_INST_MOV_ADDR:\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\t\tcode_ptr = generate_mov_addr_code(jump, code_ptr, code, executable_offset);\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\t\tjump->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tjump = jump->next;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tSLJIT_ASSERT(len == SLJIT_INST_CONST);\n\t\t\t\t\tconst_->addr = (sljit_uw)code_ptr;\n\t\t\t\t\tconst_ = const_->next;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while (buf_ptr < buf_end);\n\n\t\tSLJIT_ASSERT(buf_ptr == buf_end);\n\t\tbuf = buf->next;\n\t} while (buf);\n\n\tSLJIT_ASSERT(!label);\n\tSLJIT_ASSERT(!jump);\n\tSLJIT_ASSERT(!const_);\n\tSLJIT_ASSERT(code_ptr <= code + compiler->size);\n\n\tjump = compiler->jumps;\n\twhile (jump) {\n\t\tgenerate_jump_or_mov_addr(jump, executable_offset);\n\t\tjump = jump->next;\n\t}\n\n\tcompiler->error = SLJIT_ERR_COMPILED;\n\tcompiler->executable_offset = executable_offset;\n\tcompiler->executable_size = (sljit_uw)(code_ptr - code);\n\n\tcode = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);\n\treturn (void*)code;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)\n{\n\tswitch (feature_type) {\n\tcase SLJIT_HAS_FPU:\n#ifdef SLJIT_IS_FPU_AVAILABLE\n\t\treturn (SLJIT_IS_FPU_AVAILABLE) != 0;\n#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\t\treturn (cpu_feature_list & CPU_FEATURE_SSE2) != 0;\n#else /* SLJIT_DETECT_SSE2 */\n\t\treturn 1;\n#endif /* SLJIT_DETECT_SSE2 */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tcase SLJIT_HAS_VIRTUAL_REGISTERS:\n\t\treturn 1;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tcase SLJIT_HAS_CLZ:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\n\t\treturn (cpu_feature_list & CPU_FEATURE_LZCNT) ? 1 : 2;\n\n\tcase SLJIT_HAS_CTZ:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\n\t\treturn (cpu_feature_list & CPU_FEATURE_TZCNT) ? 1 : 2;\n\n\tcase SLJIT_HAS_CMOV:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\t\treturn (cpu_feature_list & CPU_FEATURE_CMOV) != 0;\n\n\tcase SLJIT_HAS_REV:\n\tcase SLJIT_HAS_ROT:\n\tcase SLJIT_HAS_PREFETCH:\n\tcase SLJIT_HAS_COPY_F32:\n\tcase SLJIT_HAS_COPY_F64:\n\tcase SLJIT_HAS_ATOMIC:\n\tcase SLJIT_HAS_MEMORY_BARRIER:\n\t\treturn 1;\n\n#if !(defined SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE\n\tcase SLJIT_HAS_AVX:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\t\treturn (cpu_feature_list & CPU_FEATURE_AVX) != 0;\n\tcase SLJIT_HAS_AVX2:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\t\treturn (cpu_feature_list & CPU_FEATURE_AVX2) != 0;\n\tcase SLJIT_HAS_SIMD:\n\t\tif (cpu_feature_list == 0)\n\t\t\tget_cpu_features();\n\t\treturn (cpu_feature_list & CPU_FEATURE_SSE41) != 0;\n#endif /* SLJIT_IS_FPU_AVAILABLE */\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)\n{\n\tswitch (type) {\n\tcase SLJIT_ORDERED_EQUAL:\n\tcase SLJIT_UNORDERED_OR_NOT_EQUAL:\n\t\treturn 2;\n\t}\n\n\treturn 0;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Operators                                                            */\n/* --------------------------------------------------------------------- */\n\n#define BINARY_OPCODE(opcode) (((opcode ## _EAX_i32) << 24) | ((opcode ## _r_rm) << 16) | ((opcode ## _rm_r) << 8) | (opcode))\n\n#define BINARY_IMM32(op_imm, immw, arg, argw) \\\n\tdo { \\\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \\\n\t\tFAIL_IF(!inst); \\\n\t\t*(inst + 1) |= (op_imm); \\\n\t} while (0)\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\n#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \\\n\tdo { \\\n\t\tif (IS_HALFWORD(immw) || compiler->mode32) { \\\n\t\t\tBINARY_IMM32(op_imm, immw, arg, argw); \\\n\t\t} \\\n\t\telse { \\\n\t\t\tFAIL_IF(emit_load_imm64(compiler, FAST_IS_REG(arg) ? TMP_REG2 : TMP_REG1, immw)); \\\n\t\t\tinst = emit_x86_instruction(compiler, 1, FAST_IS_REG(arg) ? TMP_REG2 : TMP_REG1, 0, arg, argw); \\\n\t\t\tFAIL_IF(!inst); \\\n\t\t\t*inst = (op_mr); \\\n\t\t} \\\n\t} while (0)\n\n#define BINARY_EAX_IMM(op_eax_imm, immw) \\\n\tFAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw))\n\n#else /* !SLJIT_CONFIG_X86_64 */\n\n#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \\\n\tBINARY_IMM32(op_imm, immw, arg, argw)\n\n#define BINARY_EAX_IMM(op_eax_imm, immw) \\\n\tFAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw))\n\n#endif /* SLJIT_CONFIG_X86_64 */\n\nstatic sljit_s32 emit_byte(struct sljit_compiler *compiler, sljit_u8 byte)\n{\n\tsljit_u8 *inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);\n\tFAIL_IF(!inst);\n\tINC_SIZE(1);\n\t*inst = byte;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_mov(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw);\n\n#define EMIT_MOV(compiler, dst, dstw, src, srcw) \\\n\tFAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));\n\nstatic sljit_s32 emit_groupf(struct sljit_compiler *compiler,\n\tsljit_uw op,\n\tsljit_s32 dst, sljit_s32 src, sljit_sw srcw);\n\nstatic sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler,\n\tsljit_uw op,\n\tsljit_s32 dst, sljit_s32 src, sljit_sw srcw);\n\nstatic SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,\n\tsljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src);\n\nstatic SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,\n\tsljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);\n\nstatic sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w);\n\nstatic sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src, sljit_sw srcw);\n\nstatic SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)\n{\n#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)\n\t/* Emit endbr32/endbr64 when CET is enabled.  */\n\tsljit_u8 *inst;\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\tFAIL_IF(!inst);\n\tINC_SIZE(4);\n\tinst[0] = GROUP_F3;\n\tinst[1] = GROUP_0F;\n\tinst[2] = 0x1e;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tinst[3] = 0xfb;\n#else /* !SLJIT_CONFIG_X86_32 */\n\tinst[3] = 0xfa;\n#endif /* SLJIT_CONFIG_X86_32 */\n#else /* !SLJIT_CONFIG_X86_CET */\n\tSLJIT_UNUSED_ARG(compiler);\n#endif /* SLJIT_CONFIG_X86_CET */\n\treturn SLJIT_SUCCESS;\n}\n\n#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)\n\nstatic SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)\n{\n\tsljit_u8 *inst;\n\tsljit_s32 size;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsize = 5;\n#else\n\tsize = 4;\n#endif\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\t*inst++ = GROUP_F3;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);\n#endif\n\tinst[0] = GROUP_0F;\n\tinst[1] = 0x1e;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tinst[2] = U8(MOD_REG | (0x1 << 3) | reg_lmap[reg]);\n#else\n\tinst[2] = U8(MOD_REG | (0x1 << 3) | reg_map[reg]);\n#endif\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)\n{\n\tsljit_u8 *inst;\n\tsljit_s32 size;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsize = 5;\n#else\n\tsize = 4;\n#endif\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\t*inst++ = GROUP_F3;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);\n#endif\n\tinst[0] = GROUP_0F;\n\tinst[1] = 0xae;\n\tinst[2] = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);\n\treturn SLJIT_SUCCESS;\n}\n\n#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */\n\nstatic SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)\n{\n#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)\n\treturn _get_ssp() != 0;\n#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */\n\treturn 0;\n#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */\n}\n\nstatic SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)\n\tsljit_u8 *inst, *jz_after_cmp_inst;\n\tsljit_uw size_jz_after_cmp_inst;\n\n\tsljit_uw size_before_rdssp_inst = compiler->size;\n\n\t/* Generate \"RDSSP TMP_REG1\". */\n\tFAIL_IF(emit_rdssp(compiler, TMP_REG1));\n\n\t/* Load return address on shadow stack into TMP_REG1. */\n\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);\n\n\t/* Compare return address against TMP_REG1. */\n\tFAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));\n\n\t/* Generate JZ to skip shadow stack ajdustment when shadow\n\t   stack matches normal stack. */\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\t*inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;\n\tsize_jz_after_cmp_inst = compiler->size;\n\tjz_after_cmp_inst = inst;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t/* REX_W is not necessary. */\n\tcompiler->mode32 = 1;\n#endif\n\t/* Load 1 into TMP_REG1. */\n\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);\n\n\t/* Generate \"INCSSP TMP_REG1\". */\n\tFAIL_IF(emit_incssp(compiler, TMP_REG1));\n\n\t/* Jump back to \"RDSSP TMP_REG1\" to check shadow stack again. */\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = JMP_i8;\n\tinst[1] = size_before_rdssp_inst - compiler->size;\n\n\t*jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;\n#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */\n\tSLJIT_UNUSED_ARG(compiler);\n\tSLJIT_UNUSED_ARG(src);\n\tSLJIT_UNUSED_ARG(srcw);\n#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */\n\treturn SLJIT_SUCCESS;\n}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n#include \"sljitNativeX86_32.c\"\n#else\n#include \"sljitNativeX86_64.c\"\n#endif\n\nstatic sljit_s32 emit_mov(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\n\tif (FAST_IS_REG(src)) {\n\t\tinst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_r;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tif (FAST_IS_REG(dst)) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\treturn emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);\n#else\n\t\t\tif (!compiler->mode32) {\n\t\t\t\tif (NOT_HALFWORD(srcw))\n\t\t\t\t\treturn emit_load_imm64(compiler, dst, srcw);\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, U8(MOV_r_i32 | reg_lmap[dst]), srcw);\n#endif\n\t\t}\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (!compiler->mode32 && NOT_HALFWORD(srcw)) {\n\t\t\t/* Immediate to memory move. Only SLJIT_MOV operation copies\n\t\t\t   an immediate directly into memory so TMP_REG1 can be used. */\n\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = MOV_rm_r;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n#endif\n\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_i32;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\tif (FAST_IS_REG(dst)) {\n\t\tinst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_r_rm;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* Memory to memory move. Only SLJIT_MOV operation copies\n\t   data from memory to memory so TMP_REG1 can be used. */\n\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);\n\tFAIL_IF(!inst);\n\t*inst = MOV_r_rm;\n\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);\n\tFAIL_IF(!inst);\n\t*inst = MOV_rm_r;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\tsljit_uw size;\n\n\tSLJIT_ASSERT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = U8(get_jump_code((sljit_uw)type ^ 0x1) - 0x10);\n\n\tsize = compiler->size;\n\tEMIT_MOV(compiler, dst_reg, 0, src, srcw);\n\n\tinst[1] = U8(compiler->size - size);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)\n{\n\tsljit_u8 *inst;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsljit_uw size;\n#endif\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op0(compiler, op));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_BREAKPOINT:\n\t\treturn emit_byte(compiler, INT3);\n\tcase SLJIT_NOP:\n\t\treturn emit_byte(compiler, NOP);\n\tcase SLJIT_LMUL_UW:\n\tcase SLJIT_LMUL_SW:\n\tcase SLJIT_DIVMOD_UW:\n\tcase SLJIT_DIVMOD_SW:\n\tcase SLJIT_DIV_UW:\n\tcase SLJIT_DIV_SW:\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n#ifdef _WIN64\n\t\tSLJIT_ASSERT(\n\t\t\treg_map[SLJIT_R0] == 0\n\t\t\t&& reg_map[SLJIT_R1] == 2\n\t\t\t&& reg_map[TMP_REG1] > 7);\n#else\n\t\tSLJIT_ASSERT(\n\t\t\treg_map[SLJIT_R0] == 0\n\t\t\t&& reg_map[SLJIT_R1] < 7\n\t\t\t&& reg_map[TMP_REG1] == 2);\n#endif\n\t\tcompiler->mode32 = op & SLJIT_32;\n#endif\n\t\tSLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);\n\n\t\top = GET_OPCODE(op);\n\t\tif ((op | 0x2) == SLJIT_DIV_UW) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);\n#else\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);\n#endif\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = XOR_r_rm;\n\t\t}\n\n\t\tif ((op | 0x2) == SLJIT_DIV_SW) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);\n#endif\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\tFAIL_IF(emit_byte(compiler, CDQ));\n#else\n\t\t\tif (!compiler->mode32) {\n\t\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\tINC_SIZE(2);\n\t\t\t\tinst[0] = REX_W;\n\t\t\t\tinst[1] = CDQ;\n\t\t\t} else\n\t\t\t\tFAIL_IF(emit_byte(compiler, CDQ));\n#endif\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(2);\n\t\tinst[0] = GROUP_F7;\n\t\tinst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);\n#else /* !SLJIT_CONFIG_X86_32 */\n#ifdef _WIN64\n\t\tsize = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2;\n#else /* !_WIN64 */\n\t\tsize = (!compiler->mode32) ? 3 : 2;\n#endif /* _WIN64 */\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n#ifdef _WIN64\n\t\tif (!compiler->mode32)\n\t\t\t*inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0);\n\t\telse if (op >= SLJIT_DIVMOD_UW)\n\t\t\t*inst++ = REX_B;\n\t\tinst[0] = GROUP_F7;\n\t\tinst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);\n#else /* !_WIN64 */\n\t\tif (!compiler->mode32)\n\t\t\t*inst++ = REX_W;\n\t\tinst[0] = GROUP_F7;\n\t\tinst[1] = MOD_REG | reg_map[SLJIT_R1];\n#endif /* _WIN64 */\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\tswitch (op) {\n\t\tcase SLJIT_LMUL_UW:\n\t\t\tinst[1] |= MUL;\n\t\t\tbreak;\n\t\tcase SLJIT_LMUL_SW:\n\t\t\tinst[1] |= IMUL;\n\t\t\tbreak;\n\t\tcase SLJIT_DIVMOD_UW:\n\t\tcase SLJIT_DIV_UW:\n\t\t\tinst[1] |= DIV;\n\t\t\tbreak;\n\t\tcase SLJIT_DIVMOD_SW:\n\t\tcase SLJIT_DIV_SW:\n\t\t\tinst[1] |= IDIV;\n\t\t\tbreak;\n\t\t}\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)\n\t\tif (op <= SLJIT_DIVMOD_SW)\n\t\t\tEMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);\n#else\n\t\tif (op >= SLJIT_DIV_UW)\n\t\t\tEMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);\n#endif\n\t\tbreak;\n\tcase SLJIT_MEMORY_BARRIER:\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(3);\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = 0xae;\n\t\tinst[2] = 0xf0;\n\t\treturn SLJIT_SUCCESS;\n\tcase SLJIT_ENDBR:\n\t\treturn emit_endbranch(compiler);\n\tcase SLJIT_SKIP_FRAMES_BEFORE_RETURN:\n\t\treturn skip_frames_before_return(compiler);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 0;\n#endif\n\n\tif (src == SLJIT_IMM) {\n\t\tif (FAST_IS_REG(dst)) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\treturn emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);\n#else\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = MOV_rm_i32;\n\t\t\treturn SLJIT_SUCCESS;\n#endif\n\t\t}\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm8_i8;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif ((dst & SLJIT_MEM) && FAST_IS_REG(src)) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (reg_map[src] >= 4) {\n\t\t\tSLJIT_ASSERT(dst_r == TMP_REG1);\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, 0);\n\t\t} else\n\t\t\tdst_r = src;\n#else\n\t\tdst_r = src;\n#endif\n\t} else {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (FAST_IS_REG(src) && reg_map[src] >= 4) {\n\t\t\t/* Both src and dst are registers. */\n\t\t\tSLJIT_ASSERT(FAST_IS_REG(dst));\n\n\t\t\tif (src == dst && !sign) {\n\t\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\t*(inst + 1) |= AND;\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t\t}\n\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, 0);\n\t\t\tsrc = TMP_REG1;\n\t\t\tsrcw = 0;\n\t\t}\n#endif /* !SLJIT_CONFIG_X86_32 */\n\n\t\t/* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */\n\t\tFAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm8 : MOVZX_r_rm8, dst_r, src, srcw));\n\t}\n\n\tif (dst & SLJIT_MEM) {\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm8_r8;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif\n\n\tinst = emit_x86_instruction(compiler, 2, 0, 0, src, srcw);\n\tFAIL_IF(!inst);\n\tinst[0] = GROUP_0F;\n\tinst[1] = PREFETCH;\n\n\tif (op == SLJIT_PREFETCH_L1)\n\t\tinst[2] |= (1 << 3);\n\telse if (op == SLJIT_PREFETCH_L2)\n\t\tinst[2] |= (2 << 3);\n\telse if (op == SLJIT_PREFETCH_L3)\n\t\tinst[2] |= (3 << 3);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 0;\n#endif\n\n\tif (src == SLJIT_IMM) {\n\t\tif (FAST_IS_REG(dst)) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\treturn emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);\n#else\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = MOV_rm_i32;\n\t\t\treturn SLJIT_SUCCESS;\n#endif\n\t\t}\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_i32;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif ((dst & SLJIT_MEM) && FAST_IS_REG(src))\n\t\tdst_r = src;\n\telse\n\t\tFAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm16 : MOVZX_r_rm16, dst_r, src, srcw));\n\n\tif (dst & SLJIT_MEM) {\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOV_rm_r;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\n\tif (dst == src && dstw == srcw) {\n\t\t/* Same input and output */\n\t\tinst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_F7;\n\t\tinst[1] |= opcode;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(dst)) {\n\t\tEMIT_MOV(compiler, dst, 0, src, srcw);\n\t\tinst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_F7;\n\t\tinst[1] |= opcode;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\tinst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);\n\tFAIL_IF(!inst);\n\tinst[0] = GROUP_F7;\n\tinst[1] |= opcode;\n\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\treturn SLJIT_SUCCESS;\n}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\nstatic const sljit_sw emit_clz_arg = 32 + 31;\nstatic const sljit_sw emit_ctz_arg = 32;\n#endif\n\nstatic sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r;\n\tsljit_sw max;\n\n\tSLJIT_ASSERT(cpu_feature_list != 0);\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (is_clz ? (cpu_feature_list & CPU_FEATURE_LZCNT) : (cpu_feature_list & CPU_FEATURE_TZCNT)) {\n\t\tFAIL_IF(emit_groupf(compiler, (is_clz ? LZCNT_r_rm : TZCNT_r_rm) | EX86_PREF_F3, dst_r, src, srcw));\n\n\t\tif (dst & SLJIT_MEM)\n\t\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tFAIL_IF(emit_groupf(compiler, is_clz ? BSR_r_rm : BSF_r_rm, dst_r, src, srcw));\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tmax = is_clz ? (32 + 31) : 32;\n\n\tif (cpu_feature_list & CPU_FEATURE_CMOV) {\n\t\tif (dst_r != TMP_REG1) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, max);\n\t\t\tinst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0);\n\t\t}\n\t\telse\n\t\t\tinst = emit_x86_instruction(compiler, 2, dst_r, 0, SLJIT_MEM0(), is_clz ? (sljit_sw)&emit_clz_arg : (sljit_sw)&emit_ctz_arg);\n\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = CMOVE_r_rm;\n\t}\n\telse\n\t\tFAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max));\n\n\tif (is_clz) {\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);\n\t\tFAIL_IF(!inst);\n\t\t*(inst + 1) |= XOR;\n\t}\n#else\n\tif (is_clz)\n\t\tmax = compiler->mode32 ? (32 + 31) : (64 + 63);\n\telse\n\t\tmax = compiler->mode32 ? 32 : 64;\n\n\tif (cpu_feature_list & CPU_FEATURE_CMOV) {\n\t\tEMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, max);\n\t\tFAIL_IF(emit_groupf(compiler, CMOVE_r_rm, dst_r, TMP_REG2, 0));\n\t} else\n\t\tFAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max));\n\n\tif (is_clz) {\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, max >> 1, dst_r, 0);\n\t\tFAIL_IF(!inst);\n\t\t*(inst + 1) |= XOR;\n\t}\n#endif\n\n\tif (dst & SLJIT_MEM)\n\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_bswap(struct sljit_compiler *compiler,\n\tsljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst;\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\tsljit_uw size;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsljit_u8 rex = 0;\n#else /* !SLJIT_CONFIG_X86_64 */\n\tsljit_s32 dst_is_ereg = op & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (op == SLJIT_REV_U32 || op == SLJIT_REV_S32)\n\t\tcompiler->mode32 = 1;\n#else /* !SLJIT_CONFIG_X86_64 */\n\top &= ~SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (src != dst_r) {\n\t\t/* Only the lower 16 bit is read for eregs. */\n\t\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16)\n\t\t\tFAIL_IF(emit_mov_half(compiler, 0, dst_r, 0, src, srcw));\n\t\telse\n\t\t\tEMIT_MOV(compiler, dst_r, 0, src, srcw);\n\t}\n\n\tsize = 2;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (!compiler->mode32)\n\t\trex = REX_W;\n\n\tif (reg_map[dst_r] >= 8)\n\t\trex |= REX_B;\n\n\tif (rex != 0)\n\t\tsize++;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (rex != 0)\n\t\t*inst++ = rex;\n\n\tinst[0] = GROUP_0F;\n\tinst[1] = BSWAP_r | reg_lmap[dst_r];\n#else /* !SLJIT_CONFIG_X86_64 */\n\tinst[0] = GROUP_0F;\n\tinst[1] = BSWAP_r | reg_map[dst_r];\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tsize = compiler->mode32 ? 16 : 48;\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tsize = 16;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, (sljit_sw)size, dst_r, 0);\n\t\tFAIL_IF(!inst);\n\t\tif (op == SLJIT_REV_U16)\n\t\t\tinst[1] |= SHR;\n\t\telse\n\t\t\tinst[1] |= SAR;\n\t}\n\n\tif (dst & SLJIT_MEM) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (dst_is_ereg)\n\t\t\top = SLJIT_REV;\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\tif (op == SLJIT_REV_U16 || op == SLJIT_REV_S16)\n\t\t\treturn emit_mov_half(compiler, 0, dst, dstw, TMP_REG1, 0);\n\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (op == SLJIT_REV_S32) {\n\t\tcompiler->mode32 = 0;\n\t\tinst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);\n\t\tFAIL_IF(!inst);\n\t\t*inst = MOVSXD_r_rm;\n\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 dst_is_ereg = 0;\n#else /* !SLJIT_CONFIG_X86_32 */\n\tsljit_s32 op_flags = GET_ALL_FLAGS(op);\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tCHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op_flags & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\top = GET_OPCODE(op);\n\n\tif (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = 0;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (FAST_IS_REG(src) && src == dst) {\n\t\t\tif (!TYPE_CAST_NEEDED(op))\n\t\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (op_flags & SLJIT_32) {\n\t\t\tif (src & SLJIT_MEM) {\n\t\t\t\tif (op == SLJIT_MOV_S32)\n\t\t\t\t\top = SLJIT_MOV_U32;\n\t\t\t}\n\t\t\telse if (src == SLJIT_IMM) {\n\t\t\t\tif (op == SLJIT_MOV_U32)\n\t\t\t\t\top = SLJIT_MOV_S32;\n\t\t\t}\n\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (src == SLJIT_IMM) {\n\t\t\tswitch (op) {\n\t\t\tcase SLJIT_MOV_U8:\n\t\t\t\tsrcw = (sljit_u8)srcw;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S8:\n\t\t\t\tsrcw = (sljit_s8)srcw;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_U16:\n\t\t\t\tsrcw = (sljit_u16)srcw;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S16:\n\t\t\t\tsrcw = (sljit_s16)srcw;\n\t\t\t\tbreak;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tcase SLJIT_MOV_U32:\n\t\t\t\tsrcw = (sljit_u32)srcw;\n\t\t\t\tbreak;\n\t\t\tcase SLJIT_MOV_S32:\n\t\t\t\tsrcw = (sljit_s32)srcw;\n\t\t\t\tbreak;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t}\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\t\tif (SLJIT_UNLIKELY(dst_is_ereg))\n\t\t\t\treturn emit_mov(compiler, dst, dstw, src, srcw);\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) {\n\t\t\tSLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP));\n\t\t\tdst = TMP_REG1;\n\t\t}\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\t\tswitch (op) {\n\t\tcase SLJIT_MOV:\n\t\tcase SLJIT_MOV_P:\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tcase SLJIT_MOV_U32:\n\t\tcase SLJIT_MOV_S32:\n\t\tcase SLJIT_MOV32:\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\t\tEMIT_MOV(compiler, dst, dstw, src, srcw);\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U8:\n\t\t\tFAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw));\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S8:\n\t\t\tFAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw));\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_U16:\n\t\t\tFAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw));\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S16:\n\t\t\tFAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw));\n\t\t\tbreak;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcase SLJIT_MOV_U32:\n\t\t\tFAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw));\n\t\t\tbreak;\n\t\tcase SLJIT_MOV_S32:\n\t\t\tFAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw));\n\t\t\tbreak;\n\t\tcase SLJIT_MOV32:\n\t\t\tcompiler->mode32 = 1;\n\t\t\tEMIT_MOV(compiler, dst, dstw, src, srcw);\n\t\t\tcompiler->mode32 = 0;\n\t\t\tbreak;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)\n\t\t\treturn emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tswitch (op) {\n\tcase SLJIT_CLZ:\n\tcase SLJIT_CTZ:\n\t\treturn emit_clz_ctz(compiler, (op == SLJIT_CLZ), dst, dstw, src, srcw);\n\tcase SLJIT_REV:\n\tcase SLJIT_REV_U16:\n\tcase SLJIT_REV_S16:\n\tcase SLJIT_REV_U32:\n\tcase SLJIT_REV_S32:\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (dst_is_ereg)\n\t\t\top |= SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\treturn emit_bswap(compiler, op, dst, dstw, src, srcw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,\n\tsljit_u32 op_types,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\tsljit_u8 op_eax_imm = U8(op_types >> 24);\n\tsljit_u8 op_rm = U8((op_types >> 16) & 0xff);\n\tsljit_u8 op_mr = U8((op_types >> 8) & 0xff);\n\tsljit_u8 op_imm = U8(op_types & 0xff);\n\n\tif (dst == src1 && dstw == src1w) {\n\t\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {\n#else\n\t\t\tif ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {\n#endif\n\t\t\t\tBINARY_EAX_IMM(op_eax_imm, src2w);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tBINARY_IMM(op_imm, op_mr, src2w, dst, dstw);\n\t\t\t}\n\t\t}\n\t\telse if (FAST_IS_REG(dst)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t\telse if (FAST_IS_REG(src2)) {\n\t\t\t/* Special exception for sljit_emit_op_flags. */\n\t\t\tinst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\telse {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* Only for cumulative operations. */\n\tif (dst == src2 && dstw == src2w) {\n\t\tif (src1 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {\n#else\n\t\t\tif ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) {\n#endif\n\t\t\t\tBINARY_EAX_IMM(op_eax_imm, src1w);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tBINARY_IMM(op_imm, op_mr, src1w, dst, dstw);\n\t\t\t}\n\t\t}\n\t\telse if (FAST_IS_REG(dst)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t\telse if (FAST_IS_REG(src1)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\telse {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* General version. */\n\tif (FAST_IS_REG(dst)) {\n\t\tEMIT_MOV(compiler, dst, 0, src1, src1w);\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tBINARY_IMM(op_imm, op_mr, src2w, dst, 0);\n\t\t}\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t}\n\telse {\n\t\t/* This version requires less memory writing. */\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tBINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);\n\t\t}\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,\n\tsljit_u32 op_types,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\tsljit_u8 op_eax_imm = U8(op_types >> 24);\n\tsljit_u8 op_rm = U8((op_types >> 16) & 0xff);\n\tsljit_u8 op_mr = U8((op_types >> 8) & 0xff);\n\tsljit_u8 op_imm = U8(op_types & 0xff);\n\n\tif (dst == src1 && dstw == src1w) {\n\t\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {\n#else\n\t\t\tif ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {\n#endif\n\t\t\t\tBINARY_EAX_IMM(op_eax_imm, src2w);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tBINARY_IMM(op_imm, op_mr, src2w, dst, dstw);\n\t\t\t}\n\t\t}\n\t\telse if (FAST_IS_REG(dst)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t\telse if (FAST_IS_REG(src2)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\telse {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_mr;\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* General version. */\n\tif (FAST_IS_REG(dst) && dst != src2) {\n\t\tEMIT_MOV(compiler, dst, 0, src1, src1w);\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tBINARY_IMM(op_imm, op_mr, src2w, dst, 0);\n\t\t}\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t}\n\telse {\n\t\t/* This version requires less memory writing. */\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tBINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);\n\t\t}\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = op_rm;\n\t\t}\n\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_mul(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\t/* Register destination. */\n\tif (dst_r == src1 && src2 != SLJIT_IMM) {\n\t\tFAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w));\n\t} else if (dst_r == src2 && src1 != SLJIT_IMM) {\n\t\tFAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src1, src1w));\n\t} else if (src1 == SLJIT_IMM) {\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tEMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);\n\t\t\tsrc2 = dst_r;\n\t\t\tsrc2w = 0;\n\t\t}\n\n\t\tif (src1w <= 127 && src1w >= -128) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i8;\n\n\t\t\tFAIL_IF(emit_byte(compiler, U8(src1w)));\n\t\t}\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i32;\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\t\tFAIL_IF(!inst);\n\t\t\tINC_SIZE(4);\n\t\t\tsljit_unaligned_store_sw(inst, src1w);\n\t\t}\n#else\n\t\telse if (IS_HALFWORD(src1w)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i32;\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\t\tFAIL_IF(!inst);\n\t\t\tINC_SIZE(4);\n\t\t\tsljit_unaligned_store_s32(inst, (sljit_s32)src1w);\n\t\t}\n\t\telse {\n\t\t\tif (dst_r != src2)\n\t\t\t\tEMIT_MOV(compiler, dst_r, 0, src2, src2w);\n\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));\n\t\t\tFAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0));\n\t\t}\n#endif\n\t}\n\telse if (src2 == SLJIT_IMM) {\n\t\t/* Note: src1 is NOT immediate. */\n\n\t\tif (src2w <= 127 && src2w >= -128) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i8;\n\n\t\t\tFAIL_IF(emit_byte(compiler, U8(src2w)));\n\t\t}\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i32;\n\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\t\tFAIL_IF(!inst);\n\t\t\tINC_SIZE(4);\n\t\t\tsljit_unaligned_store_sw(inst, src2w);\n\t\t}\n#else\n\t\telse if (IS_HALFWORD(src2w)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = IMUL_r_rm_i32;\n\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\t\tFAIL_IF(!inst);\n\t\t\tINC_SIZE(4);\n\t\t\tsljit_unaligned_store_s32(inst, (sljit_s32)src2w);\n\t\t} else {\n\t\t\tif (dst_r != src1)\n\t\t\t\tEMIT_MOV(compiler, dst_r, 0, src1, src1w);\n\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));\n\t\t\tFAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0));\n\t\t}\n#endif\n\t} else {\n\t\t/* Neither argument is immediate. */\n\t\tif (ADDRESSING_DEPENDS_ON(src2, dst_r))\n\t\t\tdst_r = TMP_REG1;\n\t\tEMIT_MOV(compiler, dst_r, 0, src1, src1w);\n\t\tFAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w));\n\t}\n\n\tif (dst & SLJIT_MEM)\n\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_lea_binary(struct sljit_compiler *compiler,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\tsljit_s32 dst_r, done = 0;\n\n\t/* These cases better be left to handled by normal way. */\n\tif (dst == src1 && dstw == src1w)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\tif (dst == src2 && dstw == src2w)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (FAST_IS_REG(src1)) {\n\t\tif (FAST_IS_REG(src2)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = LEA_r_m;\n\t\t\tdone = 1;\n\t\t}\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (src2 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src2w))) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w);\n#else\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);\n#endif\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = LEA_r_m;\n\t\t\tdone = 1;\n\t\t}\n\t}\n\telse if (FAST_IS_REG(src2)) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (src1 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src1w))) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w);\n#else\n\t\tif (src1 == SLJIT_IMM) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);\n#endif\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = LEA_r_m;\n\t\t\tdone = 1;\n\t\t}\n\t}\n\n\tif (done) {\n\t\tif (dst_r == TMP_REG1)\n\t\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\treturn SLJIT_ERR_UNSUPPORTED;\n}\n\nstatic sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {\n#else\n\tif (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) {\n#endif\n\t\tBINARY_EAX_IMM(CMP_EAX_i32, src2w);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(src1)) {\n\t\tif (src2 == SLJIT_IMM) {\n\t\t\tBINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0);\n\t\t}\n\t\telse {\n\t\t\tinst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = CMP_r_rm;\n\t\t}\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(src2) && src1 != SLJIT_IMM) {\n\t\tinst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);\n\t\tFAIL_IF(!inst);\n\t\t*inst = CMP_rm_r;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src2 == SLJIT_IMM) {\n\t\tif (src1 == SLJIT_IMM) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tsrc1 = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t}\n\t\tBINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w);\n\t}\n\telse {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);\n\t\tFAIL_IF(!inst);\n\t\t*inst = CMP_r_rm;\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_test_binary(struct sljit_compiler *compiler,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {\n#else\n\tif (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) {\n#endif\n\t\tBINARY_EAX_IMM(TEST_EAX_i32, src2w);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {\n#else\n\tif (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128)) {\n#endif\n\t\tBINARY_EAX_IMM(TEST_EAX_i32, src1w);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src1 != SLJIT_IMM) {\n\t\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif (IS_HALFWORD(src2w) || compiler->mode32) {\n\t\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\t*inst = GROUP_F7;\n\t\t\t} else {\n\t\t\t\tFAIL_IF(emit_load_imm64(compiler, FAST_IS_REG(src1) ? TMP_REG2 : TMP_REG1, src2w));\n\t\t\t\tinst = emit_x86_instruction(compiler, 1, FAST_IS_REG(src1) ? TMP_REG2 : TMP_REG1, 0, src1, src1w);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\t*inst = TEST_rm_r;\n\t\t\t}\n#else\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = GROUP_F7;\n#endif\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\telse if (FAST_IS_REG(src1)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = TEST_rm_r;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t}\n\n\tif (src2 != SLJIT_IMM) {\n\t\tif (src1 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif (IS_HALFWORD(src1w) || compiler->mode32) {\n\t\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\t*inst = GROUP_F7;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG1, src1w));\n\t\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);\n\t\t\t\tFAIL_IF(!inst);\n\t\t\t\t*inst = TEST_rm_r;\n\t\t\t}\n#else\n\t\t\tinst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = GROUP_F7;\n#endif\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\telse if (FAST_IS_REG(src2)) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = TEST_rm_r;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t}\n\n\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (IS_HALFWORD(src2w) || compiler->mode32) {\n\t\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = GROUP_F7;\n\t\t}\n\t\telse {\n\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));\n\t\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\t*inst = TEST_rm_r;\n\t\t}\n#else\n\t\tinst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);\n\t\tFAIL_IF(!inst);\n\t\t*inst = GROUP_F7;\n#endif\n\t}\n\telse {\n\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);\n\t\tFAIL_IF(!inst);\n\t\t*inst = TEST_rm_r;\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_shift(struct sljit_compiler *compiler,\n\tsljit_u8 mode,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsljit_s32 mode32;\n#endif\n\tsljit_u8* inst;\n\n\tif (src2 == SLJIT_IMM || src2 == SLJIT_PREF_SHIFT_REG) {\n\t\tif (dst == src1 && dstw == src1w) {\n\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);\n\t\t\tFAIL_IF(!inst);\n\t\t\tinst[1] |= mode;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\tif (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\tinst[1] |= mode;\n\t\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\t\tif (FAST_IS_REG(dst)) {\n\t\t\tEMIT_MOV(compiler, dst, 0, src1, src1w);\n\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\tinst[1] |= mode;\n\t\t\treturn SLJIT_SUCCESS;\n\t\t}\n\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[1] |= mode;\n\t\tEMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (dst == SLJIT_PREF_SHIFT_REG) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[1] |= mode;\n\t\treturn emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\t}\n\n\tif (FAST_IS_REG(dst) && dst != src2 && dst != TMP_REG1 && !ADDRESSING_DEPENDS_ON(src2, dst)) {\n\t\tif (src1 != dst)\n\t\t\tEMIT_MOV(compiler, dst, 0, src1, src1w);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tmode32 = compiler->mode32;\n\t\tcompiler->mode32 = 0;\n#endif\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = mode32;\n#endif\n\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);\n\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);\n\t\tFAIL_IF(!inst);\n\t\tinst[1] |= mode;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = 0;\n#endif\n\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = mode32;\n#endif\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\t/* This case is complex since ecx itself may be used for\n\t   addressing, and this case must be supported as well. */\n\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0);\n#else /* !SLJIT_CONFIG_X86_32 */\n\tmode32 = compiler->mode32;\n\tcompiler->mode32 = 0;\n\tEMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);\n\tcompiler->mode32 = mode32;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);\n\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\tFAIL_IF(!inst);\n\tinst[1] |= mode;\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0);\n#else\n\tcompiler->mode32 = 0;\n\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);\n\tcompiler->mode32 = mode32;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (dst != TMP_REG1)\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,\n\tsljit_u8 mode, sljit_s32 set_flags,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\t/* The CPU does not set flags if the shift count is 0. */\n\tif (src2 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tsrc2w &= compiler->mode32 ? 0x1f : 0x3f;\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tsrc2w &= 0x1f;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\tif (src2w != 0)\n\t\t\treturn emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);\n\n\t\tif (!set_flags)\n\t\t\treturn emit_mov(compiler, dst, dstw, src1, src1w);\n\t\t/* OR dst, src, 0 */\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(OR),\n\t\t\tdst, dstw, src1, src1w, SLJIT_IMM, 0);\n\t}\n\n\tif (!set_flags)\n\t\treturn emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);\n\n\tif (!FAST_IS_REG(dst))\n\t\tFAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));\n\n\tFAIL_IF(emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w));\n\n\tif (FAST_IS_REG(dst))\n\t\treturn emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\tCHECK_EXTRA_REGS(src1, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2, src2w, (void)0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op & SLJIT_32;\n#endif\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD:\n\t\tif (!HAS_FLAGS(op)) {\n\t\t\tif (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)\n\t\t\t\treturn compiler->error;\n\t\t}\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(ADD),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_ADDC:\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(ADC),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_SUB:\n\t\tif (src1 == SLJIT_IMM && src1w == 0)\n\t\t\treturn emit_unary(compiler, NEG_rm, dst, dstw, src2, src2w);\n\n\t\tif (!HAS_FLAGS(op)) {\n\t\t\tif (src2 == SLJIT_IMM && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)\n\t\t\t\treturn compiler->error;\n\t\t\tif (FAST_IS_REG(dst) && src2 == dst) {\n\t\t\t\tFAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));\n\t\t\t\treturn emit_unary(compiler, NEG_rm, dst, 0, dst, 0);\n\t\t\t}\n\t\t}\n\n\t\treturn emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_SUBC:\n\t\treturn emit_non_cum_binary(compiler, BINARY_OPCODE(SBB),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_MUL:\n\t\treturn emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_AND:\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(AND),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_OR:\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(OR),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_XOR:\n\t\tif (!HAS_FLAGS(op)) {\n\t\t\tif (src2 == SLJIT_IMM && src2w == -1)\n\t\t\t\treturn emit_unary(compiler, NOT_rm, dst, dstw, src1, src1w);\n\t\t\tif (src1 == SLJIT_IMM && src1w == -1)\n\t\t\t\treturn emit_unary(compiler, NOT_rm, dst, dstw, src2, src2w);\n\t\t}\n\n\t\treturn emit_cum_binary(compiler, BINARY_OPCODE(XOR),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_SHL:\n\tcase SLJIT_MSHL:\n\t\treturn emit_shift_with_flags(compiler, SHL, HAS_FLAGS(op),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_LSHR:\n\tcase SLJIT_MLSHR:\n\t\treturn emit_shift_with_flags(compiler, SHR, HAS_FLAGS(op),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_ASHR:\n\tcase SLJIT_MASHR:\n\t\treturn emit_shift_with_flags(compiler, SAR, HAS_FLAGS(op),\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_ROTL:\n\t\treturn emit_shift_with_flags(compiler, ROL, 0,\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\tcase SLJIT_ROTR:\n\t\treturn emit_shift_with_flags(compiler, ROR, 0,\n\t\t\tdst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 opcode = GET_OPCODE(op);\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));\n\n\tif (opcode != SLJIT_SUB && opcode != SLJIT_AND) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);\n\t}\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tCHECK_EXTRA_REGS(src1, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2, src2w, (void)0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op & SLJIT_32;\n#endif\n\n\tif (opcode == SLJIT_SUB)\n\t\treturn emit_cmp_binary(compiler, src1, src1w, src2, src2w);\n\n\treturn emit_test_binary(compiler, src1, src1w, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_u8* inst;\n\tsljit_sw dstw = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tCHECK_EXTRA_REGS(dst_reg, dstw, (void)0);\n\tCHECK_EXTRA_REGS(src1, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2, src2w, (void)0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op & SLJIT_32;\n#endif\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MULADD:\n\t\tFAIL_IF(emit_mul(compiler, TMP_REG1, 0, src1, src1w, src2, src2w));\n\t\tinst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst_reg, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = ADD_rm_r;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 src1_reg,\n\tsljit_s32 src2_reg,\n\tsljit_s32 src3, sljit_sw src3w)\n{\n\tsljit_s32 is_rotate, is_left, move_src1;\n\tsljit_u8* inst;\n\tsljit_sw src1w = 0;\n\tsljit_sw dstw = 0;\n\t/* The whole register must be saved even for 32 bit operations. */\n\tsljit_u8 restore_ecx = 0;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_sw src2w = 0;\n\tsljit_s32 restore_sp4 = 0;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));\n\tADJUST_LOCAL_OFFSET(src3, src3w);\n\n\tCHECK_EXTRA_REGS(dst_reg, dstw, (void)0);\n\tCHECK_EXTRA_REGS(src3, src3w, (void)0);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (src3 == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tsrc3w &= 0x1f;\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\tsrc3w &= (op & SLJIT_32) ? 0x1f : 0x3f;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\t\tif (src3w == 0)\n\t\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tis_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);\n\n\tis_rotate = (src1_reg == src2_reg);\n\tCHECK_EXTRA_REGS(src1_reg, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2_reg, src2w, (void)0);\n\n\tif (is_rotate)\n\t\treturn emit_shift(compiler, is_left ? ROL : ROR, dst_reg, dstw, src1_reg, src1w, src3, src3w);\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tif (src2_reg & SLJIT_MEM) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w);\n\t\tsrc2_reg = TMP_REG1;\n\t}\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (dst_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && (src3 != SLJIT_PREF_SHIFT_REG || src1_reg != SLJIT_PREF_SHIFT_REG)) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w);\n\t\tsrc1_reg = TMP_REG1;\n\t\tsrc1w = 0;\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tif (src2_reg != TMP_REG1) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w);\n\t\t\tsrc1_reg = TMP_REG1;\n\t\t\tsrc1w = 0;\n\t\t} else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) {\n\t\t\trestore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0;\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0);\n\t\t\tEMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w);\n\t\t\tsrc1_reg = restore_sp4;\n\t\t\tsrc1w = 0;\n\t\t} else {\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0);\n\t\t\trestore_sp4 = src1_reg;\n\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (src3 != SLJIT_PREF_SHIFT_REG)\n\t\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w);\n\t} else {\n\t\tif (src2_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tcompiler->mode32 = 0;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tcompiler->mode32 = op & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\tsrc2_reg = TMP_REG1;\n\t\t\trestore_ecx = 1;\n\t\t}\n\n\t\tmove_src1 = 0;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (dst_reg != src1_reg) {\n\t\t\tif (dst_reg != src3) {\n\t\t\t\tEMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w);\n\t\t\t\tsrc1_reg = dst_reg;\n\t\t\t\tsrc1w = 0;\n\t\t\t} else\n\t\t\t\tmove_src1 = 1;\n\t\t}\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tif (dst_reg & SLJIT_MEM) {\n\t\t\tif (src2_reg != TMP_REG1) {\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w);\n\t\t\t\tsrc1_reg = TMP_REG1;\n\t\t\t\tsrc1w = 0;\n\t\t\t} else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) {\n\t\t\t\trestore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0;\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0);\n\t\t\t\tEMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w);\n\t\t\t\tsrc1_reg = restore_sp4;\n\t\t\t\tsrc1w = 0;\n\t\t\t} else {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0);\n\t\t\t\trestore_sp4 = src1_reg;\n\t\t\t}\n\t\t} else if (dst_reg != src1_reg) {\n\t\t\tif (dst_reg != src3) {\n\t\t\t\tEMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w);\n\t\t\t\tsrc1_reg = dst_reg;\n\t\t\t\tsrc1w = 0;\n\t\t\t} else\n\t\t\t\tmove_src1 = 1;\n\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) {\n\t\t\tif (!restore_ecx) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\tcompiler->mode32 = 0;\n\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);\n\t\t\t\tcompiler->mode32 = op & SLJIT_32;\n\t\t\t\trestore_ecx = 1;\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\t\t\tif (src1_reg != TMP_REG1 && src2_reg != TMP_REG1) {\n\t\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);\n\t\t\t\t\trestore_ecx = 1;\n\t\t\t\t} else {\n\t\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0);\n\t\t\t\t\trestore_ecx = 2;\n\t\t\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t}\n\t\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w);\n\t\t}\n\n\t\tif (move_src1) {\n\t\t\tEMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w);\n\t\t\tsrc1_reg = dst_reg;\n\t\t\tsrc1w = 0;\n\t\t}\n\t}\n\n\tinst = emit_x86_instruction(compiler, 2, src2_reg, 0, src1_reg, src1w);\n\tFAIL_IF(!inst);\n\tinst[0] = GROUP_0F;\n\n\tif (src3 == SLJIT_IMM) {\n\t\tinst[1] = U8((is_left ? SHLD : SHRD) - 1);\n\n\t\t/* Immediate argument is added separately. */\n\t\tFAIL_IF(emit_byte(compiler, U8(src3w)));\n\t} else\n\t\tinst[1] = U8(is_left ? SHLD : SHRD);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (restore_ecx) {\n\t\tcompiler->mode32 = 0;\n\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);\n\t}\n\n\tif (src1_reg != dst_reg) {\n\t\tcompiler->mode32 = op & SLJIT_32;\n\t\treturn emit_mov(compiler, dst_reg, dstw, src1_reg, 0);\n\t}\n#else /* !SLJIT_CONFIG_X86_64 */\n\tif (restore_ecx)\n\t\tEMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, restore_ecx == 1 ? TMP_REG1 : SLJIT_MEM1(SLJIT_SP), 0);\n\n\tif (src1_reg != dst_reg)\n\t\tEMIT_MOV(compiler, dst_reg, dstw, src1_reg, 0);\n\n\tif (restore_sp4)\n\t\treturn emit_mov(compiler, restore_sp4, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32));\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w,\n\tsljit_sw shift_arg)\n{\n\tsljit_s32 dst_r;\n\tint use_lea = 0;\n\tsljit_u8* inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n\tshift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);\n\n\tif (src2 == SLJIT_IMM) {\n\t\tsrc2w = src2w << shift_arg;\n\t\tshift_arg = 0;\n\t}\n\n\tif (shift_arg == 0) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\treturn sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);\n\t}\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\tCHECK_EXTRA_REGS(src1, src1w, (void)0);\n\tCHECK_EXTRA_REGS(src2, src2w, (void)0);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 0;\n#endif\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (shift_arg <= 3) {\n\t\tuse_lea = 1;\n\t\tif (!FAST_IS_REG(src2)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);\n\t\t\tsrc2 = TMP_REG1;\n\t\t}\n\n\t\tif (!FAST_IS_REG(src1)) {\n\t\t\tEMIT_MOV(compiler, src2 == TMP_REG1 ? TMP_REG2 : TMP_REG1, 0, src1, src1w);\n\t\t\tsrc1 = src2 == TMP_REG1 ? TMP_REG2 : TMP_REG1;\n\t\t}\n\t}\n#else /* !SLJIT_CONFIG_X86_64 */\n\tif (shift_arg <= 3 && (FAST_IS_REG(src1) || (FAST_IS_REG(src2) && src2 != TMP_REG1))) {\n\t\tuse_lea = 1;\n\t\tif (!FAST_IS_REG(src2)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);\n\t\t\tsrc2 = TMP_REG1;\n\t\t}\n\n\t\tif (!FAST_IS_REG(src1)) {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);\n\t\t\tsrc1 = TMP_REG1;\n\t\t}\n\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (use_lea) {\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), shift_arg);\n\t\tFAIL_IF(!inst);\n\t\t*inst = LEA_r_m;\n\n\t\tif (!FAST_IS_REG(dst))\n\t\t\treturn emit_mov(compiler, dst, dstw, dst_r, 0);\n\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif ((op & SLJIT_SRC2_UNDEFINED) != 0 && FAST_IS_REG(src2) && src1 != src2)\n\t\tdst_r = src2;\n\telse {\n\t\tdst_r = FAST_IS_REG(dst) && (dst != src1) ? dst : TMP_REG1;\n\n\t\tif (src2 != dst_r) {\n\t\t\tEMIT_MOV(compiler, dst_r, 0, src2, src2w);\n\t\t}\n\t}\n\n\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, shift_arg, dst_r, 0);\n\tFAIL_IF(!inst);\n\tinst[1] |= SHL;\n\n\tif (dst == src1 && dstw == src1w) {\n\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);\n\t\tFAIL_IF(!inst);\n\t\t*inst = ADD_rm_r;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(dst) && FAST_IS_REG(src1)) {\n\t\tinst = emit_x86_instruction(compiler, 1, dst, 0, SLJIT_MEM2(src1, dst_r), 0);\n\t\tFAIL_IF(!inst);\n\t\t*inst = LEA_r_m;\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src1 == SLJIT_IMM) {\n\t\tBINARY_IMM(ADD, ADD_rm_r, src1w, dst_r, 0);\n\t} else {\n\t\tinst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);\n\t\tFAIL_IF(!inst);\n\t\t*inst = ADD_r_rm;\n\t}\n\n\tif (dst != dst_r)\n\t\treturn emit_mov(compiler, dst, dstw, dst_r, 0);\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_src(compiler, op, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_RETURN:\n\t\treturn emit_fast_return(compiler, src, srcw);\n\tcase SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:\n\t\t/* Don't adjust shadow stack if it isn't enabled.  */\n\t\tif (!cpu_has_shadow_stack ())\n\t\t\treturn SLJIT_SUCCESS;\n\t\treturn adjust_shadow_stack(compiler, src, srcw);\n\tcase SLJIT_PREFETCH_L1:\n\tcase SLJIT_PREFETCH_L2:\n\tcase SLJIT_PREFETCH_L3:\n\tcase SLJIT_PREFETCH_ONCE:\n\t\treturn emit_prefetch(compiler, op, src, srcw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\n\tswitch (op) {\n\tcase SLJIT_FAST_ENTER:\n\t\treturn emit_fast_enter(compiler, dst, dstw);\n\tcase SLJIT_GET_RETURN_ADDRESS:\n\t\treturn sljit_emit_get_return_address(compiler, dst, dstw);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)\n{\n\tCHECK_REG_INDEX(check_sljit_get_register_index(type, reg));\n\n\tif (type == SLJIT_GP_REGISTER) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (reg >= SLJIT_R3 && reg <= SLJIT_R8)\n\t\t\treturn -1;\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\treturn reg_map[reg];\n\t}\n\n\tif (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128 && type != SLJIT_SIMD_REG_256 && type != SLJIT_SIMD_REG_512)\n\t\treturn -1;\n\n\treturn freg_map[reg];\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,\n\tvoid *instruction, sljit_u32 size)\n{\n\tsljit_u8 *inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_custom(compiler, instruction, size));\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\tSLJIT_MEMCPY(inst, instruction, size);\n\treturn SLJIT_SUCCESS;\n}\n\n/* --------------------------------------------------------------------- */\n/*  Floating point operators                                             */\n/* --------------------------------------------------------------------- */\n\n/* Alignment(3) + 4 * 16 bytes. */\nstatic sljit_u32 sse2_data[3 + (4 * 4)];\nstatic sljit_u32 *sse2_buffer;\n\nstatic void init_compiler(void)\n{\n\tget_cpu_features();\n\n\t/* Align to 16 bytes. */\n\tsse2_buffer = (sljit_u32*)(((sljit_uw)sse2_data + 15) & ~(sljit_uw)0xf);\n\n\t/* Single precision constants (each constant is 16 byte long). */\n\tsse2_buffer[0] = 0x80000000;\n\tsse2_buffer[4] = 0x7fffffff;\n\t/* Double precision constants (each constant is 16 byte long). */\n\tsse2_buffer[8] = 0;\n\tsse2_buffer[9] = 0x80000000;\n\tsse2_buffer[12] = 0xffffffff;\n\tsse2_buffer[13] = 0x7fffffff;\n}\n\nstatic sljit_s32 emit_groupf(struct sljit_compiler *compiler,\n\tsljit_uw op,\n\tsljit_s32 dst, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst = emit_x86_instruction(compiler, 2 | (op & ~(sljit_uw)0xff), dst, 0, src, srcw);\n\tFAIL_IF(!inst);\n\tinst[0] = GROUP_0F;\n\tinst[1] = op & 0xff;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler,\n\tsljit_uw op,\n\tsljit_s32 dst, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst;\n\n\tSLJIT_ASSERT((op & EX86_SSE2) && ((op & VEX_OP_0F38) || (op & VEX_OP_0F3A)));\n\n\tinst = emit_x86_instruction(compiler, 3 | (op & ~((sljit_uw)0xff | VEX_OP_0F38 | VEX_OP_0F3A)), dst, 0, src, srcw);\n\tFAIL_IF(!inst);\n\tinst[0] = GROUP_0F;\n\tinst[1] = U8((op & VEX_OP_0F38) ? 0x38 : 0x3A);\n\tinst[2] = op & 0xff;\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,\n\tsljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw)\n{\n\treturn emit_groupf(compiler, MOVSD_x_xm | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, dst, src, srcw);\n}\n\nstatic SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,\n\tsljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src)\n{\n\treturn emit_groupf(compiler, MOVSD_xm_x | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, src, dst, dstw);\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)\n\t\tcompiler->mode32 = 0;\n#endif\n\n\tFAIL_IF(emit_groupf(compiler, CVTTSD2SI_r_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP2, dst_r, src, srcw));\n\n\tif (dst & SLJIT_MEM)\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;\n\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)\n\t\tcompiler->mode32 = 0;\n#endif\n\n\tif (src == SLJIT_IMM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)\n\t\t\tsrcw = (sljit_s32)srcw;\n#endif\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, src, srcw);\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\t}\n\n\tFAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, srcw));\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif\n\tif (dst_r == TMP_FREG)\n\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\treturn SLJIT_SUCCESS;\n}\n\nstatic SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tswitch (GET_FLAG_TYPE(op)) {\n\tcase SLJIT_ORDERED_EQUAL:\n\t\t/* Also: SLJIT_UNORDERED_OR_NOT_EQUAL */\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));\n\t\tFAIL_IF(emit_groupf(compiler, CMPS_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, TMP_FREG, src2, src2w));\n\n\t\t/* EQ */\n\t\tFAIL_IF(emit_byte(compiler, 0));\n\n\t\tsrc1 = TMP_FREG;\n\t\tsrc2 = TMP_FREG;\n\t\tsrc2w = 0;\n\t\tbreak;\n\n\tcase SLJIT_ORDERED_LESS:\n\tcase SLJIT_UNORDERED_OR_GREATER:\n\t\t/* Also: SLJIT_UNORDERED_OR_GREATER_EQUAL, SLJIT_ORDERED_LESS_EQUAL  */\n\t\tif (!FAST_IS_REG(src2)) {\n\t\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w));\n\t\t\tsrc2 = TMP_FREG;\n\t\t}\n\n\t\treturn emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src2, src1, src1w);\n\t}\n\n\tif (!FAST_IS_REG(src1)) {\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));\n\t\tsrc1 = TMP_FREG;\n\t}\n\n\treturn emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src1, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 dst_r;\n\tsljit_u8 *inst;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif\n\n\tCHECK_ERROR();\n\tSELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);\n\n\tif (GET_OPCODE(op) == SLJIT_MOV_F64) {\n\t\tif (FAST_IS_REG(dst))\n\t\t\treturn emit_sse2_load(compiler, op & SLJIT_32, dst, src, srcw);\n\t\tif (FAST_IS_REG(src))\n\t\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, src);\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw));\n\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\t}\n\n\tif (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) {\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;\n\t\tif (FAST_IS_REG(src)) {\n\t\t\t/* We overwrite the high bits of source. From SLJIT point of view,\n\t\t\t   this is not an issue.\n\t\t\t   Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */\n\t\t\tFAIL_IF(emit_groupf(compiler, UNPCKLPD_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, src, src, 0));\n\t\t} else {\n\t\t\tFAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_32), TMP_FREG, src, srcw));\n\t\t\tsrc = TMP_FREG;\n\t\t}\n\n\t\tFAIL_IF(emit_groupf(compiler, CVTPD2PS_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, dst_r, src, 0));\n\t\tif (dst_r == TMP_FREG)\n\t\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = (dst == src) ? TMP_FREG : dst;\n\n\t\tif (src & SLJIT_MEM)\n\t\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw));\n\n\t\tFAIL_IF(emit_groupf(compiler, PCMPEQD_x_xm | EX86_PREF_66 | EX86_SSE2, dst_r, dst_r, 0));\n\n\t\tinst = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2_OP2, 0, 0, dst_r, 0);\n\t\tinst[0] = GROUP_0F;\n\t\t/* Same as PSRLD_x / PSRLQ_x */\n\t\tinst[1] = (op & SLJIT_32) ? PSLLD_x_i8 : PSLLQ_x_i8;\n\n\t\tif (GET_OPCODE(op) == SLJIT_ABS_F64) {\n\t\t\tinst[2] |= 2 << 3;\n\t\t\tFAIL_IF(emit_byte(compiler, 1));\n\t\t} else {\n\t\t\tinst[2] |= 6 << 3;\n\t\t\tFAIL_IF(emit_byte(compiler, ((op & SLJIT_32) ? 31 : 63)));\n\t\t}\n\n\t\tif (dst_r != TMP_FREG)\n\t\t\tdst_r = (src & SLJIT_MEM) ? TMP_FREG : src;\n\t\treturn emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_NEG_F64 ? XORPD_x_xm : ANDPD_x_xm) | EX86_SSE2, dst, dst_r, 0);\n\t}\n\n\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw));\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_NEG_F64:\n\t\tFAIL_IF(emit_groupf(compiler, XORPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8)));\n\t\tbreak;\n\n\tcase SLJIT_ABS_F64:\n\t\tFAIL_IF(emit_groupf(compiler, ANDPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer + 4 : sse2_buffer + 12)));\n\t\tbreak;\n\t}\n\n\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 dst_r;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif\n\n\tif (FAST_IS_REG(dst)) {\n\t\tdst_r = dst;\n\t\tif (dst == src1)\n\t\t\t; /* Do nothing here. */\n\t\telse if (dst == src2 && (GET_OPCODE(op) == SLJIT_ADD_F64 || GET_OPCODE(op) == SLJIT_MUL_F64)) {\n\t\t\t/* Swap arguments. */\n\t\t\tsrc2 = src1;\n\t\t\tsrc2w = src1w;\n\t\t} else if (dst != src2)\n\t\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src1, src1w));\n\t\telse {\n\t\t\tdst_r = TMP_FREG;\n\t\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));\n\t\t}\n\t} else {\n\t\tdst_r = TMP_FREG;\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));\n\t}\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_ADD_F64:\n\t\tFAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w));\n\t\tbreak;\n\n\tcase SLJIT_SUB_F64:\n\t\tFAIL_IF(emit_groupf(compiler, SUBSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w));\n\t\tbreak;\n\n\tcase SLJIT_MUL_F64:\n\t\tFAIL_IF(emit_groupf(compiler, MULSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w));\n\t\tbreak;\n\n\tcase SLJIT_DIV_F64:\n\t\tFAIL_IF(emit_groupf(compiler, DIVSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w));\n\t\tbreak;\n\t}\n\n\tif (dst_r != dst)\n\t\treturn emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_uw pref;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif\n\n\tif (dst_freg == src1) {\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w));\n\t\tpref = EX86_SELECT_66(op) | EX86_SSE2;\n\t\tFAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, TMP_FREG, src1, src1w));\n\t\tFAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8)));\n\t\treturn emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, TMP_FREG, 0);\n\t}\n\n\tif (src1 & SLJIT_MEM) {\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));\n\t\tsrc1 = TMP_FREG;\n\t\tsrc1w = 0;\n\t}\n\n\tif (dst_freg != src2)\n\t\tFAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_freg, src2, src2w));\n\n\tpref = EX86_SELECT_66(op) | EX86_SSE2;\n\tFAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w));\n\tFAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, dst_freg, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8)));\n\treturn emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w);\n}\n\n/* --------------------------------------------------------------------- */\n/*  Conditional instructions                                             */\n/* --------------------------------------------------------------------- */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)\n{\n\tsljit_u8 *inst;\n\tstruct sljit_label *label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_label(compiler));\n\n\tif (compiler->last_label && compiler->last_label->size == compiler->size)\n\t\treturn compiler->last_label;\n\n\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\tPTR_FAIL_IF(!label);\n\tset_label(label, compiler);\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\tPTR_FAIL_IF(!inst);\n\tinst[0] = SLJIT_INST_LABEL;\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,\n\tsljit_s32 alignment, struct sljit_read_only_buffer *buffers)\n{\n\tsljit_uw mask, size;\n\tsljit_u8 *inst;\n\tstruct sljit_label *label;\n\tstruct sljit_label *next_label;\n\tstruct sljit_extended_label *ext_label;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));\n\n\tsljit_reset_read_only_buffers(buffers);\n\n\tif (alignment <= SLJIT_LABEL_ALIGN_1) {\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tlabel = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!label);\n\t} else {\n\t\t/* The used space is filled with NOPs. */\n\t\tmask = ((sljit_uw)1 << alignment) - 1;\n\t\tcompiler->size += mask;\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\t\tPTR_FAIL_IF(!inst);\n\t\tinst[0] = SLJIT_INST_LABEL;\n\n\t\text_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\tPTR_FAIL_IF(!ext_label);\n\t\tset_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);\n\t\tlabel = &ext_label->label;\n\t}\n\n\tif (buffers == NULL)\n\t\treturn label;\n\n\tnext_label = label;\n\n\twhile (1) {\n\t\tbuffers->u.label = next_label;\n\t\tsize = buffers->size;\n\n\t\twhile (size >= 4) {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 4);\n\t\t\tPTR_FAIL_IF(!inst);\n\t\t\tINC_SIZE(4);\n\t\t\tinst[0] = NOP;\n\t\t\tinst[1] = NOP;\n\t\t\tinst[2] = NOP;\n\t\t\tinst[3] = NOP;\n\t\t\tsize -= 4;\n\t\t}\n\n\t\tif (size > 0) {\n\t\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\t\tPTR_FAIL_IF(!inst);\n\t\t\tINC_SIZE(size);\n\n\t\t\tdo {\n\t\t\t\t*inst++ = NOP;\n\t\t\t} while (--size != 0);\n\t\t}\n\n\t\tbuffers = buffers->next;\n\n\t\tif (buffers == NULL)\n\t\t\tbreak;\n\n\t\tSLJIT_SKIP_CHECKS(compiler);\n\t\tnext_label = sljit_emit_label(compiler);\n\t\tPTR_FAIL_IF(!next_label);\n\t}\n\n\treturn label;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)\n{\n\tsljit_u8 *inst;\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_jump(compiler, type));\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF_NULL(jump);\n\tset_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT)));\n\ttype &= 0xff;\n\n\tjump->addr = compiler->size;\n\t/* Worst case size. */\n\tcompiler->size += (type >= SLJIT_JUMP) ? JUMP_MAX_SIZE : CJUMP_MAX_SIZE;\n\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\tPTR_FAIL_IF_NULL(inst);\n\n\tinst[0] = SLJIT_INST_JUMP;\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)\n{\n\tsljit_u8 *inst;\n\tstruct sljit_jump *jump;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_ijump(compiler, type, src, srcw));\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\n\tif (src == SLJIT_IMM) {\n\t\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\t\tFAIL_IF_NULL(jump);\n\t\tset_jump(jump, compiler, (sljit_u32)(JUMP_ADDR | (type << TYPE_SHIFT)));\n\t\tjump->u.target = (sljit_uw)srcw;\n\n\t\tjump->addr = compiler->size;\n\t\t/* Worst case size. */\n\t\tcompiler->size += JUMP_MAX_SIZE;\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\t\tFAIL_IF_NULL(inst);\n\n\t\tinst[0] = SLJIT_INST_JUMP;\n\t} else {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t/* REX_W is not necessary (src is not immediate). */\n\t\tcompiler->mode32 = 1;\n#endif\n\t\tinst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_FF;\n\t\tinst[1] = U8(inst[1] | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm));\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_s32 type)\n{\n\tsljit_u8 *inst;\n\tsljit_u8 cond_set;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsljit_s32 reg;\n\tsljit_uw size;\n#endif /* !SLJIT_CONFIG_X86_64 */\n\t/* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */\n\tsljit_s32 dst_save = dst;\n\tsljit_sw dstw_save = dstw;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\n\t/* setcc = jcc + 0x10. */\n\tcond_set = U8(get_jump_code((sljit_uw)type) + 0x10);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) {\n\t\tsize = 3 + 2;\n\t\tif (reg_map[TMP_REG1] >= 4)\n\t\t\tsize += 1 + 1;\n\t\telse if (reg_map[dst] >= 4)\n\t\t\tsize++;\n\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(size);\n\t\t/* Set low register to conditional flag. */\n\t\tif (reg_map[TMP_REG1] >= 4)\n\t\t\t*inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B;\n\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = cond_set;\n\t\tinst[2] = MOD_REG | reg_lmap[TMP_REG1];\n\t\tinst += 3;\n\n\t\tif (reg_map[TMP_REG1] >= 4 || reg_map[dst] >= 4)\n\t\t\t*inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B));\n\n\t\tinst[0] = OR_rm8_r8;\n\t\tinst[1] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\treg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1;\n\n\tsize = 3 + (reg_map[reg] >= 4) + 4;\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + size);\n\tFAIL_IF(!inst);\n\tINC_SIZE(size);\n\t/* Set low register to conditional flag. */\n\n\tif (reg_map[reg] >= 4)\n\t\t*inst++ = (reg_map[reg] <= 7) ? REX : REX_B;\n\n\tinst[0] = GROUP_0F;\n\tinst[1] = cond_set;\n\tinst[2] = MOD_REG | reg_lmap[reg];\n\n\tinst[3] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));\n\t/* The movzx instruction does not affect flags. */\n\tinst[4] = GROUP_0F;\n\tinst[5] = MOVZX_r_rm8;\n\tinst[6] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]);\n\n\tif (reg != TMP_REG1)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (GET_OPCODE(op) < SLJIT_ADD) {\n\t\tcompiler->mode32 = GET_OPCODE(op) != SLJIT_MOV;\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\t}\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);\n\n#else /* !SLJIT_CONFIG_X86_64 */\n\tSLJIT_ASSERT(reg_map[TMP_REG1] < 4);\n\n\t/* The SLJIT_CONFIG_X86_32 code path starts here. */\n\tif (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst) && reg_map[dst] <= 4) {\n\t\t/* Low byte is accessible. */\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(3 + 3);\n\t\t/* Set low byte to conditional flag. */\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = cond_set;\n\t\tinst[2] = U8(MOD_REG | reg_map[dst]);\n\n\t\tinst[3] = GROUP_0F;\n\t\tinst[4] = MOVZX_r_rm8;\n\t\tinst[5] = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && reg_map[dst] <= 4) {\n\t\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 2);\n\t\tFAIL_IF(!inst);\n\t\tINC_SIZE(3 + 2);\n\n\t\t/* Set low byte to conditional flag. */\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = cond_set;\n\t\tinst[2] = U8(MOD_REG | reg_map[TMP_REG1]);\n\n\t\tinst[3] = OR_rm8_r8;\n\t\tinst[4] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[dst]);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3);\n\tFAIL_IF(!inst);\n\tINC_SIZE(3 + 3);\n\t/* Set low byte to conditional flag. */\n\tinst[0] = GROUP_0F;\n\tinst[1] = cond_set;\n\tinst[2] = U8(MOD_REG | reg_map[TMP_REG1]);\n\n\tinst[3] = GROUP_0F;\n\tinst[4] = MOVZX_r_rm8;\n\tinst[5] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[TMP_REG1]);\n\n\tif (GET_OPCODE(op) < SLJIT_ADD)\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);\n#endif /* SLJIT_CONFIG_X86_64 */\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_freg,\n\tsljit_s32 src1, sljit_sw src1w,\n\tsljit_s32 src2_freg)\n{\n\tsljit_u8* inst;\n\tsljit_uw size;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));\n\n\tADJUST_LOCAL_OFFSET(src1, src1w);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (dst_freg != src2_freg) {\n\t\tif (dst_freg == src1) {\n\t\t\tsrc1 = src2_freg;\n\t\t\tsrc1w = 0;\n\t\t\ttype ^= 0x1;\n\t\t} else\n\t\t\tFAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src2_freg, 0));\n\t}\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1 + 2);\n\tFAIL_IF(!inst);\n\tINC_SIZE(2);\n\tinst[0] = U8(get_jump_code((sljit_uw)(type & ~SLJIT_32) ^ 0x1) - 0x10);\n\n\tsize = compiler->size;\n\tFAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src1, src1w));\n\n\tinst[1] = U8(compiler->size - size);\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_uw op;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tswitch (reg_size) {\n\tcase 4:\n\t\top = EX86_SSE2;\n\t\tbreak;\n\tcase 5:\n\t\tif (!(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\top = EX86_SSE2 | VEX_256;\n\t\tbreak;\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (!(srcdst & SLJIT_MEM))\n\t\talignment = reg_size;\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size == 2 || elem_size == 3) {\n\t\t\top |= alignment >= reg_size ? MOVAPS_x_xm : MOVUPS_x_xm;\n\n\t\t\tif (elem_size == 3)\n\t\t\t\top |= EX86_PREF_66;\n\n\t\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\t\top += 1;\n\t\t} else\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t} else {\n\t\top |= ((type & SLJIT_SIMD_STORE) ? MOVDQA_xm_x : MOVDQA_x_xm)\n\t\t\t| (alignment >= reg_size ? EX86_PREF_66 : EX86_PREF_F3);\n\t}\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif ((op & VEX_256) || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX)))\n\t\treturn emit_vex_instruction(compiler, op, vreg, 0, srcdst, srcdstw);\n\n\treturn emit_groupf(compiler, op, vreg, srcdst, srcdstw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_u8 *inst;\n\tsljit_u8 opcode = 0;\n\tsljit_uw op;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n\tif (!(type & SLJIT_SIMD_FLOAT)) {\n\t\tCHECK_EXTRA_REGS(src, srcw, (void)0);\n\t}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#else /* !SLJIT_CONFIG_X86_32 */\n\tcompiler->mode32 = 1;\n\n\tif (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (reg_size != 4 && (reg_size != 5 || !(cpu_feature_list & CPU_FEATURE_AVX2)))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (reg_size == 5)\n\t\tuse_vex = 1;\n\n\tif (use_vex && src != SLJIT_IMM) {\n\t\top = 0;\n\n\t\tswitch (elem_size) {\n\t\tcase 0:\n\t\t\tif (cpu_feature_list & CPU_FEATURE_AVX2)\n\t\t\t\top = VPBROADCASTB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tif (cpu_feature_list & CPU_FEATURE_AVX2)\n\t\t\t\top = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif (type & SLJIT_SIMD_FLOAT) {\n\t\t\t\tif ((cpu_feature_list & CPU_FEATURE_AVX2) || ((cpu_feature_list & CPU_FEATURE_AVX) && (src & SLJIT_MEM)))\n\t\t\t\t\top = VBROADCASTSS_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\t} else if (cpu_feature_list & CPU_FEATURE_AVX2)\n\t\t\t\top = VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\tdefault:\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\tif (!(type & SLJIT_SIMD_FLOAT)) {\n\t\t\t\tif (cpu_feature_list & CPU_FEATURE_AVX2)\n\t\t\t\t\top = VPBROADCASTQ_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\t\tbreak;\n\t\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\t\tif (reg_size == 5)\n\t\t\t\top = VBROADCASTSD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (op != 0) {\n\t\t\tif (!(src & SLJIT_MEM) && !(type & SLJIT_SIMD_FLOAT)) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\tif (elem_size >= 3)\n\t\t\t\t\tcompiler->mode32 = 0;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw));\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\tsrc = vreg;\n\t\t\t\tsrcw = 0;\n\t\t\t}\n\n\t\t\tif (reg_size == 5)\n\t\t\t\top |= VEX_256;\n\n\t\t\treturn emit_vex_instruction(compiler, op, vreg, 0, src, srcw);\n\t\t}\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (src == SLJIT_IMM) {\n\t\t\tif (use_vex)\n\t\t\t\treturn emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0);\n\n\t\t\treturn emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, vreg, vreg, 0);\n\t\t}\n\n\t\tSLJIT_ASSERT(reg_size == 4);\n\n\t\tif (use_vex) {\n\t\t\tif (elem_size == 3)\n\t\t\t\treturn emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, srcw);\n\n\t\t\tSLJIT_ASSERT(!(src & SLJIT_MEM));\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0));\n\t\t\treturn emit_byte(compiler, 0);\n\t\t}\n\n\t\tif (elem_size == 2 && vreg != src) {\n\t\t\tFAIL_IF(emit_sse2_load(compiler, 1, vreg, src, srcw));\n\t\t\tsrc = vreg;\n\t\t\tsrcw = 0;\n\t\t}\n\n\t\top = (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2;\n\t\tFAIL_IF(emit_groupf(compiler, op, vreg, src, srcw));\n\n\t\tif (elem_size == 2)\n\t\t\treturn emit_byte(compiler, 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (src == SLJIT_IMM) {\n\t\tif (elem_size == 0) {\n\t\t\tsrcw = (sljit_u8)srcw;\n\t\t\tsrcw |= srcw << 8;\n\t\t\tsrcw |= srcw << 16;\n\t\t\telem_size = 2;\n\t\t} else if (elem_size == 1) {\n\t\t\tsrcw = (sljit_u16)srcw;\n\t\t\tsrcw |= srcw << 16;\n\t\t\telem_size = 2;\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (elem_size == 2 && (sljit_s32)srcw == -1)\n\t\t\tsrcw = -1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (srcw == 0 || srcw == -1) {\n\t\t\tif (use_vex)\n\t\t\t\treturn emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0);\n\n\t\t\treturn emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0);\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (elem_size == 3)\n\t\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));\n\t\telse\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);\n\n\t\tsrc = TMP_REG1;\n\t\tsrcw = 0;\n\n\t}\n\n\top = 2;\n\topcode = MOVD_x_rm;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tif (!FAST_IS_REG(src)) {\n\t\t\topcode = 0x3a /* Prefix of PINSRB_x_rm_i8. */;\n\t\t\top = 3;\n\t\t}\n\t\tbreak;\n\tcase 1:\n\t\tif (!FAST_IS_REG(src))\n\t\t\topcode = PINSRW_x_rm_i8;\n\t\tbreak;\n\tcase 2:\n\t\tbreak;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcase 3:\n\t\t/* MOVQ */\n\t\tcompiler->mode32 = 0;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t}\n\n\tif (use_vex) {\n\t\tif (opcode != MOVD_x_rm) {\n\t\t\top = (opcode == 0x3a) ? (PINSRB_x_rm_i8 | VEX_OP_0F3A) : opcode;\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, vreg, src, srcw));\n\t\t} else\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw));\n\t} else {\n\t\tinst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = opcode;\n\n\t\tif (op == 3) {\n\t\t\tSLJIT_ASSERT(opcode == 0x3a);\n\t\t\tinst[2] = PINSRB_x_rm_i8;\n\t\t}\n\t}\n\n\tif ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && elem_size >= 2) {\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\top = VPBROADCASTD_x_xm;\n#else /* !SLJIT_CONFIG_X86_32 */\n\t\top = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm;\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\treturn emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0);\n\t}\n\n\tSLJIT_ASSERT(reg_size == 4);\n\n\tif (opcode != MOVD_x_rm)\n\t\tFAIL_IF(emit_byte(compiler, 0));\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tif (use_vex) {\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0));\n\t\t\treturn emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, TMP_FREG, 0);\n\t\t}\n\t\tFAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0));\n\t\treturn emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0);\n\tcase 1:\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, vreg, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, vreg, 0));\n\t\tFAIL_IF(emit_byte(compiler, 0));\n\t\tSLJIT_FALLTHROUGH\n\tdefault:\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0));\n\t\treturn emit_byte(compiler, 0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcase 3:\n\t\tcompiler->mode32 = 1;\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0));\n\t\treturn emit_byte(compiler, 0x44);\n#endif /* SLJIT_CONFIG_X86_64 */\n\t}\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg, sljit_s32 lane_index,\n\tsljit_s32 srcdst, sljit_sw srcdstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_u8 *inst;\n\tsljit_u8 opcode = 0;\n\tsljit_uw op;\n\tsljit_s32 vreg_orig = vreg;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 srcdst_is_ereg = 0;\n\tsljit_s32 srcdst_orig = 0;\n\tsljit_sw srcdstw_orig = 0;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw));\n\n\tADJUST_LOCAL_OFFSET(srcdst, srcdstw);\n\n\tif (reg_size == 5) {\n\t\tif (!(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tuse_vex = 1;\n\t} else if (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tif ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#else /* SLJIT_CONFIG_X86_32 */\n\tif (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#else /* !SLJIT_CONFIG_X86_64 */\n\tif (!(type & SLJIT_SIMD_FLOAT)) {\n\t\tCHECK_EXTRA_REGS(srcdst, srcdstw, srcdst_is_ereg = 1);\n\n\t\tif ((type & SLJIT_SIMD_STORE) && ((srcdst_is_ereg && elem_size < 2) || (elem_size == 0 && (type & SLJIT_SIMD_LANE_SIGNED) && FAST_IS_REG(srcdst) && reg_map[srcdst] >= 4))) {\n\t\t\tsrcdst_orig = srcdst;\n\t\t\tsrcdstw_orig = srcdstw;\n\t\t\tsrcdst = TMP_REG1;\n\t\t\tsrcdstw = 0;\n\t\t}\n\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\tif (lane_index == 0) {\n\t\t\tif (!(type & SLJIT_SIMD_FLOAT)) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\t\t\tif (elem_size == 3) {\n\t\t\t\t\tcompiler->mode32 = 0;\n\t\t\t\t\telem_size = 2;\n\t\t\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\t\t\tif (srcdst == SLJIT_IMM) {\n\t\t\t\t\tif (elem_size == 0)\n\t\t\t\t\t\tsrcdstw = (sljit_u8)srcdstw;\n\t\t\t\t\telse if (elem_size == 1)\n\t\t\t\t\t\tsrcdstw = (sljit_u16)srcdstw;\n\n\t\t\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw);\n\t\t\t\t\tsrcdst = TMP_REG1;\n\t\t\t\t\tsrcdstw = 0;\n\t\t\t\t\telem_size = 2;\n\t\t\t\t}\n\n\t\t\t\tif (elem_size == 2) {\n\t\t\t\t\tif (use_vex)\n\t\t\t\t\t\treturn emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw);\n\t\t\t\t\treturn emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, vreg, srcdst, srcdstw);\n\t\t\t\t}\n\t\t\t} else if (srcdst & SLJIT_MEM) {\n\t\t\t\tSLJIT_ASSERT(elem_size == 2 || elem_size == 3);\n\n\t\t\t\tif (use_vex)\n\t\t\t\t\treturn emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, 0, srcdst, srcdstw);\n\t\t\t\treturn emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, srcdst, srcdstw);\n\t\t\t} else if (elem_size == 3) {\n\t\t\t\tif (use_vex)\n\t\t\t\t\treturn emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, 0, srcdst, 0);\n\t\t\t\treturn emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, srcdst, 0);\n\t\t\t} else if (use_vex) {\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, XORPD_x_xm | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0));\n\t\t\t\treturn emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, vreg, TMP_FREG, srcdst, 0);\n\t\t\t}\n\t\t}\n\n\t\tif (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) {\n\t\t\tvreg = TMP_FREG;\n\t\t\tlane_index -= (1 << (4 - elem_size));\n\t\t} else if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) {\n\t\t\tif (use_vex)\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, srcdst, srcdstw));\n\t\t\telse\n\t\t\t\tFAIL_IF(emit_sse2_load(compiler, elem_size == 2, TMP_FREG, srcdst, srcdstw));\n\t\t\tsrcdst = TMP_FREG;\n\t\t\tsrcdstw = 0;\n\t\t}\n\n\t\top = ((!(type & SLJIT_SIMD_FLOAT) || elem_size != 2) ? EX86_PREF_66 : 0)\n\t\t\t| ((type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm) | EX86_SSE2;\n\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, vreg, vreg, vreg, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, op, vreg, vreg, 0));\n\t} else if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) {\n\t\tFAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0));\n\t\tFAIL_IF(emit_byte(compiler, 1));\n\n\t\tvreg = TMP_FREG;\n\t\tlane_index -= (1 << (4 - elem_size));\n\t}\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size == 3) {\n\t\t\tif (srcdst & SLJIT_MEM) {\n\t\t\t\tif (type & SLJIT_SIMD_STORE)\n\t\t\t\t\top = lane_index == 0 ? MOVLPD_m_x : MOVHPD_m_x;\n\t\t\t\telse\n\t\t\t\t\top = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m;\n\n\t\t\t\t/* VEX prefix clears upper bits of the target register. */\n\t\t\t\tif (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || vreg == TMP_FREG))\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2\n\t\t\t\t\t\t| ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), vreg, (type & SLJIT_SIMD_STORE) ? 0 : vreg, srcdst, srcdstw));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(emit_groupf(compiler, op | EX86_PREF_66 | EX86_SSE2, vreg, srcdst, srcdstw));\n\n\t\t\t\t/* In case of store, vreg is not TMP_FREG. */\n\t\t\t} else if (type & SLJIT_SIMD_STORE) {\n\t\t\t\tif (lane_index == 1) {\n\t\t\t\t\tif (use_vex)\n\t\t\t\t\t\treturn emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0);\n\t\t\t\t\treturn emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, vreg, 0);\n\t\t\t\t}\n\t\t\t\tif (use_vex)\n\t\t\t\t\treturn emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0);\n\t\t\t\treturn emit_sse2_load(compiler, 0, srcdst, vreg, 0);\n\t\t\t} else if (use_vex && (reg_size == 4 || vreg == TMP_FREG)) {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0));\n\t\t\t} else {\n\t\t\t\tif (lane_index == 1)\n\t\t\t\t\tFAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, vreg, srcdst, 0));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(emit_sse2_load(compiler, 0, vreg, srcdst, 0));\n\t\t\t}\n\t\t} else if (type & SLJIT_SIMD_STORE) {\n\t\t\tif (lane_index == 0) {\n\t\t\t\tif (use_vex)\n\t\t\t\t\treturn emit_vex_instruction(compiler, MOVSD_xm_x | EX86_PREF_F3 | EX86_SSE2 | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV),\n\t\t\t\t\t\tvreg, ((srcdst & SLJIT_MEM) ? 0 : srcdst), srcdst, srcdstw);\n\t\t\t\treturn emit_sse2_store(compiler, 1, srcdst, srcdstw, vreg);\n\t\t\t}\n\n\t\t\tif (srcdst & SLJIT_MEM) {\n\t\t\t\tif (use_vex)\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, srcdst, srcdstw));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw));\n\t\t\t\treturn emit_byte(compiler, U8(lane_index));\n\t\t\t}\n\n\t\t\tif (use_vex) {\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, vreg, vreg, 0));\n\t\t\t\treturn emit_byte(compiler, U8(lane_index));\n\t\t\t}\n\n\t\t\tif (srcdst == vreg)\n\t\t\t\top = SHUFPS_x_xm | EX86_SSE2;\n\t\t\telse {\n\t\t\t\tswitch (lane_index) {\n\t\t\t\tcase 1:\n\t\t\t\t\top = MOVSHDUP_x_xm | EX86_PREF_F3 | EX86_SSE2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\top = MOVHLPS_x_x | EX86_SSE2;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tSLJIT_ASSERT(lane_index == 3);\n\t\t\t\t\top = PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_groupf(compiler, op, srcdst, vreg, 0));\n\n\t\t\top &= 0xff;\n\t\t\tif (op == SHUFPS_x_xm || op == PSHUFD_x_xm)\n\t\t\t\treturn emit_byte(compiler, U8(lane_index));\n\n\t\t\treturn SLJIT_SUCCESS;\n\t\t} else {\n\t\t\tif (lane_index != 0 || (srcdst & SLJIT_MEM)) {\n\t\t\t\tFAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw));\n\t\t\t\tFAIL_IF(emit_byte(compiler, U8(lane_index << 4)));\n\t\t\t} else\n\t\t\t\tFAIL_IF(emit_sse2_store(compiler, 1, vreg, 0, srcdst));\n\t\t}\n\n\t\tif (vreg != TMP_FREG || (type & SLJIT_SIMD_STORE))\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_ASSERT(reg_size == 5);\n\n\t\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0));\n\t\t\treturn emit_byte(compiler, 0x4e);\n\t\t}\n\n\t\tFAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0));\n\t\treturn emit_byte(compiler, 1);\n\t}\n\n\tif (srcdst == SLJIT_IMM) {\n\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw);\n\t\tsrcdst = TMP_REG1;\n\t\tsrcdstw = 0;\n\t}\n\n\top = 3;\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\topcode = (type & SLJIT_SIMD_STORE) ? PEXTRB_rm_x_i8 : PINSRB_x_rm_i8;\n\t\tbreak;\n\tcase 1:\n\t\tif (!(type & SLJIT_SIMD_STORE)) {\n\t\t\top = 2;\n\t\t\topcode = PINSRW_x_rm_i8;\n\t\t} else\n\t\t\topcode = PEXTRW_rm_x_i8;\n\t\tbreak;\n\tcase 2:\n\t\topcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8;\n\t\tbreak;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcase 3:\n\t\t/* PINSRQ / PEXTRQ */\n\t\topcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8;\n\t\tcompiler->mode32 = 0;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t}\n\n\tif (use_vex && (type & SLJIT_SIMD_STORE)) {\n\t\top = opcode | ((op == 3) ? VEX_OP_0F3A : 0);\n\t\tFAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, 0, srcdst, srcdstw));\n\t} else {\n\t\tinst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw);\n\t\tFAIL_IF(!inst);\n\t\tinst[0] = GROUP_0F;\n\n\t\tif (op == 3) {\n\t\t\tinst[1] = 0x3a;\n\t\t\tinst[2] = opcode;\n\t\t} else\n\t\t\tinst[1] = opcode;\n\t}\n\n\tFAIL_IF(emit_byte(compiler, U8(lane_index)));\n\n\tif (!(type & SLJIT_SIMD_LANE_SIGNED) || (srcdst & SLJIT_MEM)) {\n\t\tif (vreg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) {\n\t\t\tSLJIT_ASSERT(reg_size == 5);\n\n\t\t\tif (type & SLJIT_SIMD_LANE_ZERO) {\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0));\n\t\t\t\treturn emit_byte(compiler, 0x4e);\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0));\n\t\t\treturn emit_byte(compiler, 1);\n\t\t}\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (srcdst_orig & SLJIT_MEM)\n\t\t\treturn emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0);\n#endif /* SLJIT_CONFIG_X86_32 */\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (elem_size >= 3)\n\t\treturn SLJIT_SUCCESS;\n\n\tcompiler->mode32 = (type & SLJIT_32);\n\n\top = 2;\n\n\tif (elem_size == 0)\n\t\top |= EX86_REX;\n\n\tif (elem_size == 2) {\n\t\tif (type & SLJIT_32)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tSLJIT_ASSERT(!(compiler->mode32));\n\t\top = 1;\n\t}\n\n\tinst = emit_x86_instruction(compiler, op, srcdst, 0, srcdst, 0);\n\tFAIL_IF(!inst);\n\n\tif (op != 1) {\n\t\tinst[0] = GROUP_0F;\n\t\tinst[1] = U8((elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16);\n\t} else\n\t\tinst[0] = MOVSXD_r_rm;\n#else /* !SLJIT_CONFIG_X86_64 */\n\tif (elem_size >= 2)\n\t\treturn SLJIT_SUCCESS;\n\n\tFAIL_IF(emit_groupf(compiler, (elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16,\n\t\t(srcdst_orig != 0 && FAST_IS_REG(srcdst_orig)) ? srcdst_orig : srcdst, srcdst, 0));\n\n\tif (srcdst_orig & SLJIT_MEM)\n\t\treturn emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0);\n#endif /* SLJIT_CONFIG_X86_64 */\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_s32 src_lane_index)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_uw pref;\n\tsljit_u8 byte;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 opcode3 = TMP_REG1;\n#else /* !SLJIT_CONFIG_X86_32 */\n\tsljit_s32 opcode3 = SLJIT_S0;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\tSLJIT_ASSERT(reg_map[opcode3] == 3);\n\n\tif (reg_size == 5) {\n\t\tif (!(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tuse_vex = 1;\n\t} else if (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tpref = 0;\n\t\tbyte = U8(src_lane_index);\n\n\t\tif (elem_size == 3) {\n\t\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\t\treturn SLJIT_SUCCESS;\n\n\t\t\tif (reg_size == 5) {\n\t\t\t\tif (src_lane_index == 0)\n\t\t\t\t\treturn emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0);\n\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0));\n\n\t\t\t\tbyte = U8(byte | (byte << 2));\n\t\t\t\treturn emit_byte(compiler, U8(byte | (byte << 4)));\n\t\t\t}\n\n\t\t\tif (src_lane_index == 0) {\n\t\t\t\tif (use_vex)\n\t\t\t\t\treturn emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, 0);\n\t\t\t\treturn emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, src, 0);\n\t\t\t}\n\n\t\t\t/* Changes it to SHUFPD_x_xm. */\n\t\t\tpref = EX86_PREF_66;\n\t\t} else if (elem_size != 2)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\telse if (type & SLJIT_SIMD_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (reg_size == 5) {\n\t\t\tSLJIT_ASSERT(elem_size == 2);\n\n\t\t\tif (src_lane_index == 0)\n\t\t\t\treturn emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0);\n\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0));\n\n\t\t\tbyte = 0x44;\n\t\t\tif (src_lane_index >= 4) {\n\t\t\t\tbyte = 0xee;\n\t\t\t\tsrc_lane_index -= 4;\n\t\t\t}\n\n\t\t\tFAIL_IF(emit_byte(compiler, byte));\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0));\n\t\t\tbyte = U8(src_lane_index);\n\t\t} else if (use_vex) {\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0));\n\t\t} else {\n\t\t\tif (vreg != src)\n\t\t\t\tFAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, vreg, src, 0));\n\n\t\t\tFAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, vreg, vreg, 0));\n\t\t}\n\n\t\tif (elem_size == 2) {\n\t\t\tbyte = U8(byte | (byte << 2));\n\t\t\tbyte = U8(byte | (byte << 4));\n\t\t} else\n\t\t\tbyte = U8(byte | (byte << 1));\n\n\t\treturn emit_byte(compiler, U8(byte));\n\t}\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (elem_size == 0) {\n\t\tif (reg_size == 5 && src_lane_index >= 16) {\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0));\n\t\t\tFAIL_IF(emit_byte(compiler, src_lane_index >= 24 ? 0xff : 0xaa));\n\t\t\tsrc_lane_index &= 0x7;\n\t\t\tsrc = vreg;\n\t\t}\n\n\t\tif (src_lane_index != 0 || (vreg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) {\n\t\t\tpref = 0;\n\n\t\t\tif ((src_lane_index & 0x3) == 0) {\n\t\t\t\tpref = EX86_PREF_66;\n\t\t\t\tbyte = U8(src_lane_index >> 2);\n\t\t\t} else if (src_lane_index < 8 && (src_lane_index & 0x1) == 0) {\n\t\t\t\tpref = EX86_PREF_F2;\n\t\t\t\tbyte = U8(src_lane_index >> 1);\n\t\t\t} else {\n\t\t\t\tif (!use_vex) {\n\t\t\t\t\tif (vreg != src)\n\t\t\t\t\t\tFAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0));\n\n\t\t\t\t\tFAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, vreg, 0));\n\t\t\t\t} else\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, vreg, src, 0));\n\n\t\t\t\tFAIL_IF(emit_byte(compiler, U8(src_lane_index)));\n\t\t\t}\n\n\t\t\tif (pref != 0) {\n\t\t\t\tif (use_vex)\n\t\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0));\n\t\t\t\telse\n\t\t\t\t\tFAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0));\n\t\t\t\tFAIL_IF(emit_byte(compiler, byte));\n\t\t\t}\n\n\t\t\tsrc = vreg;\n\t\t}\n\n\t\tif (use_vex && (cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0);\n\n\t\tSLJIT_ASSERT(reg_size == 4);\n\t\tFAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0));\n\t\treturn emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0);\n\t}\n\n\tif ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && src_lane_index == 0 && elem_size <= 3) {\n\t\tswitch (elem_size) {\n\t\tcase 1:\n\t\t\tpref = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tpref = VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpref = VPBROADCASTQ_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (reg_size == 5)\n\t\t\tpref |= VEX_256;\n\n\t\treturn emit_vex_instruction(compiler, pref, vreg, 0, src, 0);\n\t}\n\n\tif (reg_size == 5) {\n\t\tswitch (elem_size) {\n\t\tcase 1:\n\t\t\tbyte = U8(src_lane_index & 0x3);\n\t\t\tsrc_lane_index >>= 2;\n\t\t\tpref = PSHUFLW_x_xm | VEX_256 | ((src_lane_index & 1) == 0 ? EX86_PREF_F2 : EX86_PREF_F3) | EX86_SSE2;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbyte = U8(src_lane_index & 0x3);\n\t\t\tsrc_lane_index >>= 1;\n\t\t\tpref = PSHUFD_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tpref = 0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0));\n\t\t\treturn emit_byte(compiler, U8(src_lane_index == 0 ? 0x44 : 0xee));\n\t\t}\n\n\t\tif (pref != 0) {\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, pref, vreg, 0, src, 0));\n\t\t\tbyte = U8(byte | (byte << 2));\n\t\t\tFAIL_IF(emit_byte(compiler, U8(byte | (byte << 4))));\n\n\t\t\tif (src_lane_index == 0)\n\t\t\t\treturn emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0);\n\n\t\t\tsrc = vreg;\n\t\t}\n\n\t\tFAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0));\n\t\tbyte = U8(src_lane_index);\n\t\tbyte = U8(byte | (byte << 2));\n\t\treturn emit_byte(compiler, U8(byte | (byte << 4)));\n\t}\n\n\tswitch (elem_size) {\n\tcase 1:\n\t\tbyte = U8(src_lane_index & 0x3);\n\t\tsrc_lane_index >>= 1;\n\t\tpref = (src_lane_index & 2) == 0 ? EX86_PREF_F2 : EX86_PREF_F3;\n\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0));\n\t\tbyte = U8(byte | (byte << 2));\n\t\tFAIL_IF(emit_byte(compiler, U8(byte | (byte << 4))));\n\n\t\tif ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && pref == EX86_PREF_F2)\n\t\t\treturn emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0);\n\n\t\tsrc = vreg;\n\t\tSLJIT_FALLTHROUGH\n\tcase 2:\n\t\tbyte = U8(src_lane_index);\n\t\tbyte = U8(byte | (byte << 2));\n\t\tbreak;\n\tdefault:\n\t\tbyte = U8(src_lane_index << 1);\n\t\tbyte = U8(byte | (byte << 2) | 0x4);\n\t\tbreak;\n\t}\n\n\tif (use_vex)\n\t\tFAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, src, 0));\n\telse\n\t\tFAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0));\n\treturn emit_byte(compiler, U8(byte | (byte << 4)));\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 src, sljit_sw srcw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_u8 opcode;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw));\n\n\tADJUST_LOCAL_OFFSET(src, srcw);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (reg_size == 5) {\n\t\tif (!(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tuse_vex = 1;\n\t} else if (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_FLOAT) {\n\t\tif (elem_size != 2 || elem2_size != 3)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\tif (use_vex)\n\t\t\treturn emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, vreg, 0, src, srcw);\n\t\treturn emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, vreg, src, srcw);\n\t}\n\n\tswitch (elem_size) {\n\tcase 0:\n\t\tif (elem2_size == 1)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBW_x_xm : PMOVZXBW_x_xm;\n\t\telse if (elem2_size == 2)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBD_x_xm : PMOVZXBD_x_xm;\n\t\telse if (elem2_size == 3)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBQ_x_xm : PMOVZXBQ_x_xm;\n\t\telse\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tbreak;\n\tcase 1:\n\t\tif (elem2_size == 2)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWD_x_xm : PMOVZXWD_x_xm;\n\t\telse if (elem2_size == 3)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWQ_x_xm : PMOVZXWQ_x_xm;\n\t\telse\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tbreak;\n\tcase 2:\n\t\tif (elem2_size == 3)\n\t\t\topcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXDQ_x_xm : PMOVZXDQ_x_xm;\n\t\telse\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t\tbreak;\n\tdefault:\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t}\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif (use_vex)\n\t\treturn emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, srcw);\n\treturn emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, src, srcw);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 vreg,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_s32 dst_r;\n\tsljit_uw op;\n\tsljit_u8 *inst;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw));\n\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (reg_size == 4) {\n\t\tif (type & SLJIT_SIMD_TEST)\n\t\t\treturn SLJIT_SUCCESS;\n\n\t\top = EX86_PREF_66 | EX86_SSE2_OP2;\n\n\t\tswitch (elem_size) {\n\t\tcase 1:\n\t\t\tif (use_vex)\n\t\t\t\tFAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, vreg, 0));\n\t\t\telse\n\t\t\t\tFAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, vreg, 0));\n\t\t\tvreg = TMP_FREG;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\top = EX86_SSE2_OP2;\n\t\t\tbreak;\n\t\t}\n\n\t\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\t\top |= (elem_size < 2) ? PMOVMSKB_r_x : MOVMSKPS_r_x;\n\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, op, dst_r, vreg, 0));\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = type & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (elem_size == 1) {\n\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 8, dst_r, 0);\n\t\t\tFAIL_IF(!inst);\n\t\t\tinst[1] |= SHR;\n\t\t}\n\n\t\tif (dst_r == TMP_REG1)\n\t\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\n\t\treturn SLJIT_SUCCESS;\n\t}\n\n\tif (reg_size != 5 || !(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tdst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\tif (elem_size == 1) {\n\t\tFAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0));\n\t\tFAIL_IF(emit_byte(compiler, 1));\n\t\tFAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, TMP_FREG, 0));\n\t\tFAIL_IF(emit_groupf(compiler, PMOVMSKB_r_x | EX86_PREF_66 | EX86_SSE2_OP2, dst_r, TMP_FREG, 0));\n\t} else {\n\t\top = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2;\n\n\t\tif (elem_size == 0)\n\t\t\top = PMOVMSKB_r_x | VEX_256 | EX86_PREF_66 | EX86_SSE2_OP2;\n\t\telse if (elem_size == 3)\n\t\t\top |= EX86_PREF_66;\n\n\t\tFAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0));\n\t}\n\n\tif (dst_r == TMP_REG1) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = type & SLJIT_32;\n#endif /* SLJIT_CONFIG_X86_64 */\n\t\treturn emit_mov(compiler, dst, dstw, TMP_REG1, 0);\n\t}\n\n\treturn SLJIT_SUCCESS;\n}\n\nstatic sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src_vreg)\n{\n\tsljit_uw op = ((type & SLJIT_SIMD_FLOAT) ? MOVAPS_x_xm : MOVDQA_x_xm) | EX86_SSE2;\n\n\tSLJIT_ASSERT(SLJIT_SIMD_GET_REG_SIZE(type) == 4);\n\n\tif (!(type & SLJIT_SIMD_FLOAT) || SLJIT_SIMD_GET_ELEM_SIZE(type) == 3)\n\t\top |= EX86_PREF_66;\n\n\treturn emit_groupf(compiler, op, dst_vreg, src_vreg, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,\n\tsljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w)\n{\n\tsljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);\n\tsljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);\n\tsljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);\n\tsljit_uw op = 0;\n\tsljit_uw mov_op = 0;\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w));\n\tADJUST_LOCAL_OFFSET(src2, src2w);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 1;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tif (reg_size == 5) {\n\t\tif (!(cpu_feature_list & CPU_FEATURE_AVX2))\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\t} else if (reg_size != 4)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tswitch (SLJIT_SIMD_GET_OPCODE(type)) {\n\tcase SLJIT_SIMD_OP2_AND:\n\t\top = (type & SLJIT_SIMD_FLOAT) ? ANDPD_x_xm : PAND_x_xm;\n\n\t\tif (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3)\n\t\t\top |= EX86_PREF_66;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_OR:\n\t\top = (type & SLJIT_SIMD_FLOAT) ? ORPD_x_xm : POR_x_xm;\n\n\t\tif (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3)\n\t\t\top |= EX86_PREF_66;\n\t\tbreak;\n\tcase SLJIT_SIMD_OP2_XOR:\n\t\top = (type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm;\n\n\t\tif (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3)\n\t\t\top |= EX86_PREF_66;\n\t\tbreak;\n\n\tcase SLJIT_SIMD_OP2_SHUFFLE:\n\t\tif (reg_size != 4)\n\t\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\t\top = PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38;\n\t\tbreak;\n\t}\n\n\tif (type & SLJIT_SIMD_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tif ((src2 & SLJIT_MEM) && SLJIT_SIMD_GET_ELEM2_SIZE(type) < reg_size) {\n\t\tmov_op = ((type & SLJIT_SIMD_FLOAT) ? (MOVUPS_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0)) : (MOVDQU_x_xm | EX86_PREF_F3)) | EX86_SSE2;\n\t\tif (use_vex)\n\t\t\tFAIL_IF(emit_vex_instruction(compiler, mov_op, TMP_FREG, 0, src2, src2w));\n\t\telse\n\t\t\tFAIL_IF(emit_groupf(compiler, mov_op, TMP_FREG, src2, src2w));\n\n\t\tsrc2 = TMP_FREG;\n\t\tsrc2w = 0;\n\t}\n\n\tif (reg_size == 5 || use_vex) {\n\t\tif (reg_size == 5)\n\t\t\top |= VEX_256;\n\n\t\treturn emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_vreg, src1_vreg, src2, src2w);\n\t}\n\n\tif (dst_vreg != src1_vreg) {\n\t\tif (dst_vreg == src2) {\n\t\t\tif (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) {\n\t\t\t\tFAIL_IF(emit_simd_mov(compiler, type, TMP_FREG, src2));\n\t\t\t\tFAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg));\n\t\t\t\tsrc2 = TMP_FREG;\n\t\t\t\tsrc2w = 0;\n\t\t\t} else\n\t\t\t\tsrc2 = src1_vreg;\n\t\t} else\n\t\t\tFAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg));\n\t}\n\n\tif (op & (VEX_OP_0F38 | VEX_OP_0F3A))\n\t\treturn emit_groupf_ext(compiler, op | EX86_SSE2, dst_vreg, src2, src2w);\n\treturn emit_groupf(compiler, op | EX86_SSE2, dst_vreg, src2, src2w);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst_reg,\n\tsljit_s32 mem_reg)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));\n\n\tif ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\tSLJIT_SKIP_CHECKS(compiler);\n\treturn sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 src_reg,\n\tsljit_s32 mem_reg,\n\tsljit_s32 temp_reg)\n{\n\tsljit_uw pref;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 saved_reg = TMP_REG1;\n\tsljit_s32 swap_tmp = 0;\n\tsljit_sw srcw = 0;\n\tsljit_sw tempw = 0;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR();\n\tCHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));\n\tCHECK_EXTRA_REGS(src_reg, srcw, (void)0);\n\tCHECK_EXTRA_REGS(temp_reg, tempw, (void)0);\n\n\tSLJIT_ASSERT(FAST_IS_REG(src_reg) || src_reg == SLJIT_MEM1(SLJIT_SP));\n\tSLJIT_ASSERT(FAST_IS_REG(temp_reg) || temp_reg == SLJIT_MEM1(SLJIT_SP));\n\n\tif ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32)\n\t\treturn SLJIT_ERR_UNSUPPORTED;\n\n\tif (op & SLJIT_ATOMIC_TEST)\n\t\treturn SLJIT_SUCCESS;\n\n\top = GET_OPCODE(op);\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tif (temp_reg == SLJIT_TMP_DEST_REG) {\n\t\tFAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1]));\n\n\t\tif (src_reg == SLJIT_R0)\n\t\t\tsrc_reg = TMP_REG1;\n\t\tif (mem_reg == SLJIT_R0)\n\t\t\tmem_reg = TMP_REG1;\n\n\t\ttemp_reg = SLJIT_R0;\n\t\tswap_tmp = 1;\n\t}\n\n\t/* Src is virtual register or its low byte is not accessible. */\n\tif ((src_reg & SLJIT_MEM) || (op == SLJIT_MOV_U8 && reg_map[src_reg] >= 4)) {\n\t\tSLJIT_ASSERT(src_reg != SLJIT_R1 && temp_reg != SLJIT_TMP_DEST_REG);\n\n\t\tif (swap_tmp) {\n\t\t\tsaved_reg = (mem_reg != SLJIT_R1) ? SLJIT_R1 : SLJIT_R2;\n\n\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, saved_reg, 0);\n\t\t\tEMIT_MOV(compiler, saved_reg, 0, src_reg, srcw);\n\t\t} else\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw);\n\n\t\tsrc_reg = saved_reg;\n\n\t\tif (mem_reg == src_reg)\n\t\t\tmem_reg = saved_reg;\n\t}\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (temp_reg != SLJIT_R0) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = 0;\n\n\t\tEMIT_MOV(compiler, TMP_REG2, 0, SLJIT_R0, 0);\n\t\tEMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, 0);\n\n\t\tif (src_reg == SLJIT_R0)\n\t\t\tsrc_reg = TMP_REG2;\n\t\tif (mem_reg == SLJIT_R0)\n\t\t\tmem_reg = TMP_REG2;\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tSLJIT_ASSERT(!swap_tmp);\n\n\t\tif (src_reg == TMP_REG1) {\n\t\t\tif (mem_reg == SLJIT_R0) {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw);\n\n\t\t\t\tmem_reg = SLJIT_R1;\n\t\t\t\tsaved_reg = SLJIT_R1;\n\t\t\t} else {\n\t\t\t\tEMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0);\n\t\t\t\tEMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw);\n\t\t\t\tsaved_reg = SLJIT_R0;\n\t\t\t}\n\t\t} else {\n\t\t\tEMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R0, 0);\n\t\t\tEMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw);\n\n\t\t\tif (src_reg == SLJIT_R0)\n\t\t\t\tsrc_reg = TMP_REG1;\n\t\t\tif (mem_reg == SLJIT_R0)\n\t\t\t\tmem_reg = TMP_REG1;\n\t\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\t}\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = op != SLJIT_MOV && op != SLJIT_MOV_P;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t/* Lock prefix. */\n\tFAIL_IF(emit_byte(compiler, GROUP_LOCK));\n\n\tpref = 0;\n\tif (op == SLJIT_MOV_U16)\n\t\tpref = EX86_HALF_ARG | EX86_PREF_66;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (op == SLJIT_MOV_U8)\n\t\tpref = EX86_REX;\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tFAIL_IF(emit_groupf(compiler, (op == SLJIT_MOV_U8 ? CMPXCHG_rm8_r : CMPXCHG_rm_r) | pref, src_reg, SLJIT_MEM1(mem_reg), 0));\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tif (swap_tmp) {\n\t\tSLJIT_ASSERT(temp_reg == SLJIT_R0);\n\t\tFAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1]));\n\n\t\tif (saved_reg != TMP_REG1)\n\t\t\treturn emit_mov(compiler, saved_reg, 0, SLJIT_MEM1(SLJIT_SP), 0);\n\t\treturn SLJIT_SUCCESS;\n\t}\n#endif /* SLJIT_CONFIG_X86_32 */\n\n\tif (temp_reg != SLJIT_R0) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = 0;\n\t\treturn emit_mov(compiler, SLJIT_R0, 0, TMP_REG2, 0);\n#else /* !SLJIT_CONFIG_X86_64 */\n\t\tEMIT_MOV(compiler, SLJIT_R0, 0, (saved_reg == SLJIT_R0) ? SLJIT_MEM1(SLJIT_SP) : saved_reg, 0);\n\t\tif (saved_reg == SLJIT_R1)\n\t\t\treturn emit_mov(compiler, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_SP), 0);\n#endif /* SLJIT_CONFIG_X86_64 */\n\t}\n\treturn SLJIT_SUCCESS;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)\n{\n\tCHECK_ERROR();\n\tCHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\tADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 0;\n#endif\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (NOT_HALFWORD(offset)) {\n\t\tFAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\tSLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);\n\t\treturn compiler->error;\n#else\n\t\treturn emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);\n#endif\n\t}\n#endif\n\n\tif (offset != 0)\n\t\treturn emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);\n\treturn emit_mov(compiler, dst, dstw, SLJIT_SP, 0);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw,\n\tsljit_sw init_value)\n{\n\tsljit_u8 *inst;\n\tstruct sljit_const *const_;\n\tsljit_s32 reg;\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 dst_is_ereg = 0;\n#endif /* !SLJIT_CONFIG_X86_32 */\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tCHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);\n\n\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\tPTR_FAIL_IF(!const_);\n\tset_const(const_, compiler);\n\n\tswitch (GET_OPCODE(op)) {\n\tcase SLJIT_MOV_U8:\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = (op & SLJIT_32);\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif ((init_value & 0x100) != 0)\n\t\t\tinit_value = init_value | -(sljit_sw)0x100;\n\t\telse\n\t\t\tinit_value = (sljit_u8)init_value;\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\t\tif (dst_is_ereg) {\n\t\t\tif (emit_mov(compiler, dst, dstw, SLJIT_IMM, (sljit_s32)init_value))\n\t\t\t\treturn NULL;\n\t\t\tdst = 0;\n\t\t\tbreak;\n\t\t}\n#endif /* !SLJIT_CONFIG_X86_32 */\n\n\t\treg = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\t\tif (emit_mov(compiler, reg, 0, SLJIT_IMM, init_value))\n\t\t\treturn NULL;\n\t\tbreak;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcase SLJIT_MOV:\n\t\tcompiler->mode32 = 0;\n\t\treg = FAST_IS_REG(dst) ? dst : TMP_REG1;\n\n\t\tif (emit_load_imm64(compiler, reg, init_value))\n\t\t\treturn NULL;\n\t\tbreak;\n#endif /* SLJIT_CONFIG_X86_64 */\n\tdefault:\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tcompiler->mode32 = (op == SLJIT_MOV32);\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\t\tif (emit_mov(compiler, dst, dstw, SLJIT_IMM, (sljit_s32)init_value))\n\t\t\treturn NULL;\n\t\tdst = 0;\n\t\tbreak;\n\t}\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\tPTR_FAIL_IF(!inst);\n\n\tinst[0] = SLJIT_INST_CONST;\n\n\tif (dst & SLJIT_MEM) {\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\t\tif (op == SLJIT_MOV) {\n\t\t\tif (emit_mov(compiler, dst, dstw, TMP_REG1, 0))\n\t\t\t\treturn NULL;\n\t\t\treturn const_;\n\t\t}\n#endif\n\n\t\tif (emit_mov_byte(compiler, 0, dst, dstw, TMP_REG1, 0))\n\t\t\treturn NULL;\n\t}\n\n\treturn const_;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,\n\tsljit_s32 dst, sljit_sw dstw)\n{\n\tstruct sljit_jump *jump;\n\tsljit_u8 *inst;\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tsljit_s32 reg;\n#endif /* SLJIT_CONFIG_X86_64 */\n\tSLJIT_UNUSED_ARG(op);\n\n\tCHECK_ERROR_PTR();\n\tCHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));\n\tADJUST_LOCAL_OFFSET(dst, dstw);\n\n\tCHECK_EXTRA_REGS(dst, dstw, (void)0);\n\n\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\tPTR_FAIL_IF(!jump);\n\tset_mov_addr(jump, compiler, 0);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tcompiler->mode32 = 0;\n\tif (dst & SLJIT_MEM)\n\t\treg = TMP_REG1;\n\telse\n\t\treg = (op != SLJIT_ADD_ABS_ADDR) ? dst : TMP_REG2;\n\n\tPTR_FAIL_IF(emit_load_imm64(compiler, reg, 0));\n\tjump->addr = compiler->size;\n\n\tif (reg_map[reg] >= 8)\n\t\tjump->flags |= MOV_ADDR_HI;\n#else /* !SLJIT_CONFIG_X86_64 */\n\tif (op == SLJIT_ADD_ABS_ADDR) {\n\t\tif (dst != SLJIT_R0) {\n\t\t\t/* Must not be a signed byte argument. */\n\t\t\tinst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0x100, dst, dstw);\n\t\t\tPTR_FAIL_IF(!inst);\n\t\t\t*(inst + 1) |= ADD;\n\t\t} else\n\t\t\tPTR_FAIL_IF(emit_do_imm(compiler, ADD_EAX_i32, 0));\n\t} else {\n\t\tPTR_FAIL_IF(emit_mov(compiler, dst, dstw, SLJIT_IMM, 0));\n\t}\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\tinst = (sljit_u8*)ensure_buf(compiler, 1);\n\tPTR_FAIL_IF(!inst);\n\n\tinst[0] = SLJIT_INST_MOV_ADDR;\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (op == SLJIT_ADD_ABS_ADDR) {\n\t\tinst = emit_x86_instruction(compiler, 1, reg, 0, dst, dstw);\n\t\tPTR_FAIL_IF(!inst);\n\t\t*inst = ADD_rm_r;\n\t} else if (dst & SLJIT_MEM)\n\t\tPTR_FAIL_IF(emit_mov(compiler, dst, dstw, TMP_REG1, 0));\n#endif /* SLJIT_CONFIG_X86_64 */\n\n\treturn jump;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)\n{\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n\tSLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_unaligned_store_sw((void*)addr, (sljit_sw)(new_target - (addr + 4) - (sljit_uw)executable_offset));\n#else\n\tsljit_unaligned_store_sw((void*)addr, (sljit_sw)new_target);\n#endif\n\tSLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)\n{\n\tvoid *start_addr;\n\tSLJIT_UNUSED_ARG(executable_offset);\n\n#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)\n\tif (op == SLJIT_MOV) {\n\t\tstart_addr = (void*)(addr - sizeof(sljit_sw));\n\t\tSLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 0);\n\t\tsljit_unaligned_store_sw(start_addr, new_constant);\n\t\tSLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 1);\n\t\treturn;\n\t}\n#endif\n\n\tstart_addr = (void*)(addr - sizeof(sljit_s32));\n\n\tif ((op | SLJIT_32) == SLJIT_MOV32_U8) {\n\t\tif ((new_constant & 0x100) != 0)\n\t\t\tnew_constant = new_constant | -(sljit_sw)0x100;\n\t\telse\n\t\t\tnew_constant = (sljit_u8)new_constant;\n\t}\n\n\tSLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 0);\n\tsljit_unaligned_store_s32(start_addr, (sljit_s32)new_constant);\n\tSLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 1);\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitSerialize.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#define SLJIT_GET_LABEL_INDEX(label) \\\n\t((label)->u.index < SLJIT_LABEL_ALIGNED ? (label)->u.index : ((struct sljit_extended_label*)(label))->index)\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_uw sljit_get_label_index(struct sljit_label *label)\n{\n\treturn SLJIT_GET_LABEL_INDEX(label);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump)\n{\n\treturn !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump)\n{\n\treturn (jump->flags & JUMP_ADDR) != 0;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump)\n{\n\treturn (jump->flags & JUMP_MOV_ADDR) != 0;\n}\n\n#define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1)\n\nstruct sljit_serialized_compiler {\n\tsljit_u32 signature;\n\tsljit_u16 version;\n\tsljit_u16 cpu_type;\n\n\tsljit_uw buf_segment_count;\n\tsljit_uw label_count;\n\tsljit_uw aligned_label_count;\n\tsljit_uw jump_count;\n\tsljit_uw const_count;\n\n\tsljit_s32 options;\n\tsljit_s32 scratches;\n\tsljit_s32 saveds;\n\tsljit_s32 fscratches;\n\tsljit_s32 fsaveds;\n\tsljit_s32 local_size;\n\tsljit_uw size;\n\n#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)\n\tsljit_s32 status_flags_state;\n#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n\tsljit_s32 args_size;\n#endif /* SLJIT_CONFIG_X86_32 */\n\n#if ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \\\n\t\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tsljit_uw args_size;\n#endif /* (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tsljit_uw cpool_diff;\n\tsljit_uw cpool_fill;\n\tsljit_uw patches;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\tsljit_s32 delay_slot;\n#endif /* SLJIT_CONFIG_MIPS */\n\n};\n\nstruct sljit_serialized_debug_info {\n\tsljit_sw last_flags;\n\tsljit_s32 last_return;\n\tsljit_s32 logical_local_size;\n};\n\nstruct sljit_serialized_label {\n\tsljit_uw size;\n};\n\nstruct sljit_serialized_aligned_label {\n\tsljit_uw size;\n\tsljit_uw data;\n};\n\nstruct sljit_serialized_jump {\n\tsljit_uw addr;\n\tsljit_uw flags;\n\tsljit_uw value;\n};\n\nstruct sljit_serialized_const {\n\tsljit_uw addr;\n};\n\n#define SLJIT_SERIALIZE_ALIGN(v) (((v) + sizeof(sljit_uw) - 1) & ~(sljit_uw)(sizeof(sljit_uw) - 1))\n#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\n#define SLJIT_SERIALIZE_SIGNATURE 0x534c4a54\n#else /* !SLJIT_LITTLE_ENDIAN */\n#define SLJIT_SERIALIZE_SIGNATURE 0x544a4c53\n#endif /* SLJIT_LITTLE_ENDIAN */\n#define SLJIT_SERIALIZE_VERSION 1\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,\n\tsljit_s32 options, sljit_uw *size)\n{\n\tsljit_uw serialized_size = sizeof(struct sljit_serialized_compiler);\n\tstruct sljit_memory_fragment *buf;\n\tstruct sljit_label *label;\n\tstruct sljit_jump *jump;\n\tstruct sljit_const *const_;\n\tstruct sljit_serialized_compiler *serialized_compiler;\n\tstruct sljit_serialized_label *serialized_label;\n\tstruct sljit_serialized_aligned_label *serialized_aligned_label;\n\tstruct sljit_serialized_jump *serialized_jump;\n\tstruct sljit_serialized_const *serialized_const;\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tstruct sljit_serialized_debug_info *serialized_debug_info;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\tsljit_uw counter, used_size;\n\tsljit_u8 *result;\n\tsljit_u8 *ptr;\n\tSLJIT_UNUSED_ARG(options);\n\n\tif (size != NULL)\n\t\t*size = 0;\n\n\tPTR_FAIL_IF(compiler->error);\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tif (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG))\n\t\tserialized_size += sizeof(struct sljit_serialized_debug_info);\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tserialized_size += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n\t/* Compute the size of the data. */\n\tbuf = compiler->buf;\n\twhile (buf != NULL) {\n\t\tserialized_size += sizeof(sljit_uw) + SLJIT_SERIALIZE_ALIGN(buf->used_size);\n\t\tbuf = buf->next;\n\t}\n\n\tlabel = compiler->labels;\n\twhile (label != NULL) {\n\t\tused_size = sizeof(struct sljit_serialized_label);\n\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED)\n\t\t\tused_size += sizeof(struct sljit_serialized_aligned_label);\n\n\t\tserialized_size += used_size;\n\t\tlabel = label->next;\n\t}\n\n\tjump = compiler->jumps;\n\twhile (jump != NULL) {\n\t\tserialized_size += sizeof(struct sljit_serialized_jump);\n\t\tjump = jump->next;\n\t}\n\n\tconst_ = compiler->consts;\n\twhile (const_ != NULL) {\n\t\tserialized_size += sizeof(struct sljit_serialized_const);\n\t\tconst_ = const_->next;\n\t}\n\n\tresult = (sljit_u8*)SLJIT_MALLOC(serialized_size, compiler->allocator_data);\n\tPTR_FAIL_IF_NULL(result);\n\n\tif (size != NULL)\n\t\t*size = serialized_size;\n\n\tptr = result;\n\tserialized_compiler = (struct sljit_serialized_compiler*)ptr;\n\tptr += sizeof(struct sljit_serialized_compiler);\n\n\tserialized_compiler->signature = SLJIT_SERIALIZE_SIGNATURE;\n\tserialized_compiler->version = SLJIT_SERIALIZE_VERSION;\n\tserialized_compiler->cpu_type = 0;\n\tserialized_compiler->label_count = compiler->label_count;\n\tserialized_compiler->options = compiler->options;\n\tserialized_compiler->scratches = compiler->scratches;\n\tserialized_compiler->saveds = compiler->saveds;\n\tserialized_compiler->fscratches = compiler->fscratches;\n\tserialized_compiler->fsaveds = compiler->fsaveds;\n\tserialized_compiler->local_size = compiler->local_size;\n\tserialized_compiler->size = compiler->size;\n\n#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)\n\tserialized_compiler->status_flags_state = compiler->status_flags_state;\n#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \\\n\t\t|| ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \\\n\t\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tserialized_compiler->args_size = compiler->args_size;\n#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tserialized_compiler->cpool_diff = compiler->cpool_diff;\n\tserialized_compiler->cpool_fill = compiler->cpool_fill;\n\tserialized_compiler->patches = compiler->patches;\n\n\tSLJIT_MEMCPY(ptr, compiler->cpool, compiler->cpool_fill * sizeof(sljit_uw));\n\tSLJIT_MEMCPY(ptr + compiler->cpool_fill * sizeof(sljit_uw), compiler->cpool_unique, compiler->cpool_fill);\n\tptr += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\tserialized_compiler->delay_slot = compiler->delay_slot;\n#endif /* SLJIT_CONFIG_MIPS */\n\n\tbuf = compiler->buf;\n\tcounter = 0;\n\twhile (buf != NULL) {\n\t\tused_size = buf->used_size;\n\t\t*(sljit_uw*)ptr = used_size;\n\t\tptr += sizeof(sljit_uw);\n\t\tSLJIT_MEMCPY(ptr, buf->memory, used_size);\n\t\tptr += SLJIT_SERIALIZE_ALIGN(used_size);\n\t\tbuf = buf->next;\n\t\tcounter++;\n\t}\n\tserialized_compiler->buf_segment_count = counter;\n\n\tlabel = compiler->labels;\n\tcounter = 0;\n\twhile (label != NULL) {\n\t\tserialized_label = (struct sljit_serialized_label*)ptr;\n\t\tserialized_label->size = (label->u.index < SLJIT_LABEL_ALIGNED) ? label->size : label->u.index;\n\t\tptr += sizeof(struct sljit_serialized_label);\n\n\t\tif (label->u.index >= SLJIT_LABEL_ALIGNED) {\n\t\t\tserialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr;\n\t\t\tserialized_aligned_label->size = label->size;\n\t\t\tserialized_aligned_label->data = ((struct sljit_extended_label*)label)->data;\n\t\t\tptr += sizeof(struct sljit_serialized_aligned_label);\n\t\t\tcounter++;\n\t\t}\n\n\t\tlabel = label->next;\n\t}\n\tserialized_compiler->aligned_label_count = counter;\n\n\tjump = compiler->jumps;\n\tcounter = 0;\n\twhile (jump != NULL) {\n\t\tserialized_jump = (struct sljit_serialized_jump*)ptr;\n\t\tserialized_jump->addr = jump->addr;\n\t\tserialized_jump->flags = jump->flags;\n\n\t\tif (jump->flags & JUMP_ADDR)\n\t\t\tserialized_jump->value = jump->u.target;\n\t\telse if (jump->u.label != NULL)\n\t\t\tserialized_jump->value = SLJIT_GET_LABEL_INDEX(jump->u.label);\n\t\telse\n\t\t\tserialized_jump->value = SLJIT_MAX_ADDRESS;\n\n\t\tptr += sizeof(struct sljit_serialized_jump);\n\t\tjump = jump->next;\n\t\tcounter++;\n\t}\n\tserialized_compiler->jump_count = counter;\n\n\tconst_ = compiler->consts;\n\tcounter = 0;\n\twhile (const_ != NULL) {\n\t\tserialized_const = (struct sljit_serialized_const*)ptr;\n\t\tserialized_const->addr = const_->addr;\n\t\tptr += sizeof(struct sljit_serialized_const);\n\t\tconst_ = const_->next;\n\t\tcounter++;\n\t}\n\tserialized_compiler->const_count = counter;\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tif (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) {\n\t\tserialized_debug_info = (struct sljit_serialized_debug_info*)ptr;\n\t\tserialized_debug_info->last_flags = compiler->last_flags;\n\t\tserialized_debug_info->last_return = compiler->last_return;\n\t\tserialized_debug_info->logical_local_size = compiler->logical_local_size;\n\t\tserialized_compiler->cpu_type |= SLJIT_SERIALIZE_DEBUG;\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\t\tptr += sizeof(struct sljit_serialized_debug_info);\n#endif /* SLJIT_DEBUG */\n\t}\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n\tSLJIT_ASSERT((sljit_uw)(ptr - result) == serialized_size);\n\treturn (sljit_uw*)result;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,\n\tsljit_s32 options, void *allocator_data)\n{\n\tstruct sljit_compiler *compiler;\n\tstruct sljit_serialized_compiler *serialized_compiler;\n\tstruct sljit_serialized_label *serialized_label;\n\tstruct sljit_serialized_aligned_label *serialized_aligned_label;\n\tstruct sljit_serialized_jump *serialized_jump;\n\tstruct sljit_serialized_const *serialized_const;\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tstruct sljit_serialized_debug_info *serialized_debug_info;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\tstruct sljit_memory_fragment *buf;\n\tstruct sljit_memory_fragment *last_buf;\n\tstruct sljit_label *label;\n\tstruct sljit_label *last_label;\n\tstruct sljit_label **label_list = NULL;\n\tstruct sljit_label **label_list_ptr = NULL;\n\tstruct sljit_jump *jump;\n\tstruct sljit_jump *last_jump;\n\tstruct sljit_const *const_;\n\tstruct sljit_const *last_const;\n\tsljit_u8 *ptr = (sljit_u8*)buffer;\n\tsljit_u8 *end = ptr + size;\n\tsljit_uw i, type, used_size, aligned_size;\n\tsljit_uw label_count, aligned_label_count;\n\tSLJIT_UNUSED_ARG(options);\n\n\tif (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0)\n\t\treturn NULL;\n\n\tserialized_compiler = (struct sljit_serialized_compiler*)ptr;\n\n\tif (serialized_compiler->signature != SLJIT_SERIALIZE_SIGNATURE || serialized_compiler->version != SLJIT_SERIALIZE_VERSION)\n\t\treturn NULL;\n\n\tcompiler = sljit_create_compiler(allocator_data);\n\tPTR_FAIL_IF(compiler == NULL);\n\n\tcompiler->label_count = serialized_compiler->label_count;\n\tcompiler->options = serialized_compiler->options;\n\tcompiler->scratches = serialized_compiler->scratches;\n\tcompiler->saveds = serialized_compiler->saveds;\n\tcompiler->fscratches = serialized_compiler->fscratches;\n\tcompiler->fsaveds = serialized_compiler->fsaveds;\n\tcompiler->local_size = serialized_compiler->local_size;\n\tcompiler->size = serialized_compiler->size;\n\n#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)\n\tcompiler->status_flags_state = serialized_compiler->status_flags_state;\n#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \\\n\t\t|| ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \\\n\t\t|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)\n\tcompiler->args_size = serialized_compiler->args_size;\n#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */\n\n#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)\n\tused_size = serialized_compiler->cpool_fill;\n\taligned_size = SLJIT_SERIALIZE_ALIGN(used_size * (sizeof(sljit_uw) + 1));\n\tcompiler->cpool_diff = serialized_compiler->cpool_diff;\n\tcompiler->cpool_fill = used_size;\n\tcompiler->patches = serialized_compiler->patches;\n\n\tif ((sljit_uw)(end - ptr) < aligned_size)\n\t\tgoto error;\n\n\tSLJIT_MEMCPY(compiler->cpool, ptr, used_size * sizeof(sljit_uw));\n\tSLJIT_MEMCPY(compiler->cpool_unique, ptr + used_size * sizeof(sljit_uw), used_size);\n\tptr += aligned_size;\n#endif /* SLJIT_CONFIG_ARM_V6 */\n\n#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)\n\tcompiler->delay_slot = serialized_compiler->delay_slot;\n#endif /* SLJIT_CONFIG_MIPS */\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tif (!(serialized_compiler->cpu_type & SLJIT_SERIALIZE_DEBUG))\n\t\tgoto error;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n\tptr += sizeof(struct sljit_serialized_compiler);\n\ti = serialized_compiler->buf_segment_count;\n\tlast_buf = NULL;\n\twhile (i > 0) {\n\t\tif ((sljit_uw)(end - ptr) < sizeof(sljit_uw))\n\t\t\tgoto error;\n\n\t\tused_size = *(sljit_uw*)ptr;\n\t\taligned_size = SLJIT_SERIALIZE_ALIGN(used_size);\n\t\tptr += sizeof(sljit_uw);\n\n\t\tif ((sljit_uw)(end - ptr) < aligned_size)\n\t\t\tgoto error;\n\n\t\tif (last_buf == NULL) {\n\t\t\tSLJIT_ASSERT(compiler->buf != NULL && compiler->buf->next == NULL);\n\t\t\tbuf = compiler->buf;\n\t\t} else {\n\t\t\tbuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);\n\t\t\tif (!buf)\n\t\t\t\tgoto error;\n\t\t\tbuf->next = NULL;\n\t\t}\n\n\t\tbuf->used_size = used_size;\n\t\tSLJIT_MEMCPY(buf->memory, ptr, used_size);\n\n\t\tif (last_buf != NULL)\n\t\t\tlast_buf->next = buf;\n\t\tlast_buf = buf;\n\n\t\tptr += aligned_size;\n\t\ti--;\n\t}\n\n\tlast_label = NULL;\n\tlabel_count = serialized_compiler->label_count;\n\taligned_label_count = serialized_compiler->aligned_label_count;\n\ti = (label_count * sizeof(struct sljit_serialized_label)) + (aligned_label_count * sizeof(struct sljit_serialized_aligned_label));\n\n\tif ((sljit_uw)(end - ptr) < i)\n\t\tgoto error;\n\n\tlabel_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data);\n\tif (label_list == NULL)\n\t\tgoto error;\n\n\tlabel_list_ptr = label_list;\n\tfor (i = 0; i < label_count; i++) {\n\t\tserialized_label = (struct sljit_serialized_label*)ptr;\n\t\ttype = serialized_label->size;\n\n\t\tif (type < SLJIT_LABEL_ALIGNED) {\n\t\t\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));\n\t\t} else {\n\t\t\tlabel = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));\n\t\t}\n\n\t\tif (label == NULL)\n\t\t\tgoto error;\n\n\t\tlabel->next = NULL;\n\n\t\tif (last_label != NULL)\n\t\t\tlast_label->next = label;\n\t\telse\n\t\t\tcompiler->labels = label;\n\t\tlast_label = label;\n\n\t\t*label_list_ptr++ = label;\n\n\t\tptr += sizeof(struct sljit_serialized_label);\n\n\t\tif (type < SLJIT_LABEL_ALIGNED) {\n\t\t\tlabel->u.index = i;\n\t\t\tlabel->size = type;\n\t\t} else {\n\t\t\tif (aligned_label_count == 0)\n\t\t\t\tgoto error;\n\n\t\t\taligned_label_count--;\n\n\t\t\tserialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr;\n\t\t\tlabel->u.index = type;\n\t\t\tlabel->size = serialized_aligned_label->size;\n\n\t\t\t((struct sljit_extended_label*)label)->index = i;\n\t\t\t((struct sljit_extended_label*)label)->data = serialized_aligned_label->data;\n\t\t\tptr += sizeof(struct sljit_serialized_aligned_label);\n\t\t}\n\t}\n\tcompiler->last_label = last_label;\n\n\tif (aligned_label_count != 0)\n\t\tgoto error;\n\n\tlast_jump = NULL;\n\ti = serialized_compiler->jump_count;\n\tif ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump))\n\t\tgoto error;\n\n\twhile (i > 0) {\n\t\tjump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));\n\t\tif (jump == NULL)\n\t\t\tgoto error;\n\n\t\tserialized_jump = (struct sljit_serialized_jump*)ptr;\n\t\tjump->next = NULL;\n\t\tjump->addr = serialized_jump->addr;\n\t\tjump->flags = serialized_jump->flags;\n\n\t\tif (!(serialized_jump->flags & JUMP_ADDR)) {\n\t\t\tif (serialized_jump->value != SLJIT_MAX_ADDRESS) {\n\t\t\t\tif (serialized_jump->value >= label_count)\n\t\t\t\t\tgoto error;\n\t\t\t\tjump->u.label = label_list[serialized_jump->value];\n\t\t\t} else\n\t\t\t\tjump->u.label = NULL;\n\t\t} else\n\t\t\tjump->u.target = serialized_jump->value;\n\n\t\tif (last_jump != NULL)\n\t\t\tlast_jump->next = jump;\n\t\telse\n\t\t\tcompiler->jumps = jump;\n\t\tlast_jump = jump;\n\n\t\tptr += sizeof(struct sljit_serialized_jump);\n\t\ti--;\n\t}\n\tcompiler->last_jump = last_jump;\n\n\tSLJIT_FREE(label_list, allocator_data);\n\tlabel_list = NULL;\n\n\tlast_const = NULL;\n\ti = serialized_compiler->const_count;\n\tif ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_const))\n\t\tgoto error;\n\n\twhile (i > 0) {\n\t\tconst_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));\n\t\tif (const_ == NULL)\n\t\t\tgoto error;\n\n\t\tserialized_const = (struct sljit_serialized_const*)ptr;\n\t\tconst_->next = NULL;\n\t\tconst_->addr = serialized_const->addr;\n\n\t\tif (last_const != NULL)\n\t\t\tlast_const->next = const_;\n\t\telse\n\t\t\tcompiler->consts = const_;\n\t\tlast_const = const_;\n\n\t\tptr += sizeof(struct sljit_serialized_const);\n\t\ti--;\n\t}\n\tcompiler->last_const = last_const;\n\n#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \\\n\t\t|| (defined SLJIT_DEBUG && SLJIT_DEBUG)\n\tif ((sljit_uw)(end - ptr) < sizeof(struct sljit_serialized_debug_info))\n\t\tgoto error;\n\n\tserialized_debug_info = (struct sljit_serialized_debug_info*)ptr;\n\tcompiler->last_flags = (sljit_s32)serialized_debug_info->last_flags;\n\tcompiler->last_return = serialized_debug_info->last_return;\n\tcompiler->logical_local_size = serialized_debug_info->logical_local_size;\n#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */\n\n\treturn compiler;\n\nerror:\n\tsljit_free_compiler(compiler);\n\tif (label_list != NULL)\n\t\tSLJIT_FREE(label_list, allocator_data);\n\treturn NULL;\n}\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/deps/sljit/sljit_src/sljitUtils.c",
    "content": "/*\n *    Stack-less Just-In-Time compiler\n *\n *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *   1. Redistributions of source code must retain the above copyright notice, this list of\n *      conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright notice, this list\n *      of conditions and the following disclaimer in the documentation and/or other materials\n *      provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* ------------------------------------------------------------------------ */\n/*  Locks                                                                   */\n/* ------------------------------------------------------------------------ */\n\n/* Executable Allocator */\n\n#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \\\n\t&& !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)\n#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)\n#define SLJIT_ALLOCATOR_LOCK()\n#define SLJIT_ALLOCATOR_UNLOCK()\n#elif !(defined _WIN32)\n#include <pthread.h>\n\nstatic pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;\n\n#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)\n#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)\n#else /* windows */\nstatic HANDLE allocator_lock;\n\nstatic SLJIT_INLINE void allocator_grab_lock(void)\n{\n\tHANDLE lock;\n\tif (SLJIT_UNLIKELY(!InterlockedCompareExchangePointer(&allocator_lock, NULL, NULL))) {\n\t\tlock = CreateMutex(NULL, FALSE, NULL);\n\t\tif (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))\n\t\t\tCloseHandle(lock);\n\t}\n\tWaitForSingleObject(allocator_lock, INFINITE);\n}\n\n#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()\n#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)\n#endif /* thread implementation */\n#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */\n\n/* ------------------------------------------------------------------------ */\n/*  Stack                                                                   */\n/* ------------------------------------------------------------------------ */\n\n#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \\\n\t&& !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \\\n\t|| ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \\\n\t&& !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \\\n\t|| (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))\n\n#ifndef _WIN32\n/* Provides mmap function. */\n#include <sys/types.h>\n#include <sys/mman.h>\n\n#ifndef MAP_ANON\n#ifdef MAP_ANONYMOUS\n#define MAP_ANON MAP_ANONYMOUS\n#endif /* MAP_ANONYMOUS */\n#endif /* !MAP_ANON */\n\n#ifndef MAP_ANON\n\n#include <fcntl.h>\n\n#ifdef O_CLOEXEC\n#define SLJIT_CLOEXEC\tO_CLOEXEC\n#else /* !O_CLOEXEC */\n#define SLJIT_CLOEXEC\t0\n#endif /* O_CLOEXEC */\n\n/* Some old systems do not have MAP_ANON. */\nstatic int dev_zero = -1;\n\n#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)\n\nstatic SLJIT_INLINE int open_dev_zero(void)\n{\n\tdev_zero = open(\"/dev/zero\", O_RDWR | SLJIT_CLOEXEC);\n\n\treturn dev_zero < 0;\n}\n\n#else /* !SLJIT_SINGLE_THREADED */\n\n#include <pthread.h>\n\nstatic pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;\n\nstatic SLJIT_INLINE int open_dev_zero(void)\n{\n\tpthread_mutex_lock(&dev_zero_mutex);\n\tif (SLJIT_UNLIKELY(dev_zero < 0))\n\t\tdev_zero = open(\"/dev/zero\", O_RDWR | SLJIT_CLOEXEC);\n\n\tpthread_mutex_unlock(&dev_zero_mutex);\n\treturn dev_zero < 0;\n}\n\n#endif /* SLJIT_SINGLE_THREADED */\n#undef SLJIT_CLOEXEC\n#endif /* !MAP_ANON */\n#endif /* !_WIN32 */\n#endif /* open_dev_zero */\n\n#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \\\n\t|| (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)\n\n#ifdef _WIN32\n\nstatic SLJIT_INLINE sljit_uw get_page_alignment(void) {\n\tSYSTEM_INFO si;\n\tstatic sljit_uw sljit_page_align = 0;\n\tif (!sljit_page_align) {\n\t\tGetSystemInfo(&si);\n\t\tsljit_page_align = (sljit_uw)si.dwPageSize - 1;\n\t}\n\treturn sljit_page_align;\n}\n\n#else\n\n#include <unistd.h>\n\nstatic SLJIT_INLINE sljit_uw get_page_alignment(void) {\n\tstatic sljit_uw sljit_page_align = 0;\n\n\tsljit_sw align;\n\n\tif (!sljit_page_align) {\n#ifdef _SC_PAGESIZE\n\t\talign = sysconf(_SC_PAGESIZE);\n#else\n\t\talign = getpagesize();\n#endif\n\t\t/* Should never happen. */\n\t\tif (align < 0)\n\t\t\talign = 4096;\n\t\tsljit_page_align = (sljit_uw)align - 1;\n\t}\n\treturn sljit_page_align;\n}\n\n#endif /* _WIN32 */\n\n#endif /* get_page_alignment() */\n\n#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)\n\n#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)\n{\n\tstruct sljit_stack *stack;\n\tvoid *ptr;\n\n\tSLJIT_UNUSED_ARG(allocator_data);\n\n\tif (start_size > max_size || start_size < 1)\n\t\treturn NULL;\n\n\tstack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);\n\tif (stack == NULL)\n\t\treturn NULL;\n\n\tptr = SLJIT_MALLOC(max_size, allocator_data);\n\tif (ptr == NULL) {\n\t\tSLJIT_FREE(stack, allocator_data);\n\t\treturn NULL;\n\t}\n\n\tstack->min_start = (sljit_u8 *)ptr;\n \tstack->end = stack->min_start + max_size;\n \tstack->start = stack->end - start_size;\n\tstack->top = stack->end;\n\treturn stack;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)\n{\n\tSLJIT_UNUSED_ARG(allocator_data);\n\tSLJIT_FREE((void*)stack->min_start, allocator_data);\n\tSLJIT_FREE(stack, allocator_data);\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)\n{\n\tif ((new_start < stack->min_start) || (new_start >= stack->end))\n\t\treturn NULL;\n\tstack->start = new_start;\n\treturn new_start;\n}\n\n#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */\n\n#ifdef _WIN32\n\nSLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)\n{\n\tSLJIT_UNUSED_ARG(allocator_data);\n\tVirtualFree((void*)stack->min_start, 0, MEM_RELEASE);\n\tSLJIT_FREE(stack, allocator_data);\n}\n\n#else /* !_WIN32 */\n\nSLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)\n{\n\tSLJIT_UNUSED_ARG(allocator_data);\n\tmunmap((void*)stack->min_start, (size_t)(stack->end - stack->min_start));\n\tSLJIT_FREE(stack, allocator_data);\n}\n\n#endif /* _WIN32 */\n\nSLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)\n{\n\tstruct sljit_stack *stack;\n\tvoid *ptr;\n\tsljit_uw page_align;\n\n\tSLJIT_UNUSED_ARG(allocator_data);\n\n\tif (start_size > max_size || start_size < 1)\n\t\treturn NULL;\n\n\tstack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);\n\tif (stack == NULL)\n\t\treturn NULL;\n\n\t/* Align max_size. */\n\tpage_align = get_page_alignment();\n\tmax_size = (max_size + page_align) & ~page_align;\n\n#ifdef _WIN32\n\tptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);\n\tif (!ptr) {\n\t\tSLJIT_FREE(stack, allocator_data);\n\t\treturn NULL;\n\t}\n\n\tstack->min_start = (sljit_u8 *)ptr;\n\tstack->end = stack->min_start + max_size;\n\tstack->start = stack->end;\n\n\tif (sljit_stack_resize(stack, stack->end - start_size) == NULL) {\n\t\tsljit_free_stack(stack, allocator_data);\n\t\treturn NULL;\n\t}\n#else /* !_WIN32 */\n#ifdef MAP_ANON\n\tptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n#else /* !MAP_ANON */\n\tif (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {\n\t\tSLJIT_FREE(stack, allocator_data);\n\t\treturn NULL;\n\t}\n\tptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);\n#endif /* MAP_ANON */\n\tif (ptr == MAP_FAILED) {\n\t\tSLJIT_FREE(stack, allocator_data);\n\t\treturn NULL;\n\t}\n\tstack->min_start = (sljit_u8 *)ptr;\n\tstack->end = stack->min_start + max_size;\n\tstack->start = stack->end - start_size;\n#endif /* _WIN32 */\n\n\tstack->top = stack->end;\n\treturn stack;\n}\n\nSLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)\n{\n#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)\n\tsljit_uw aligned_old_start;\n\tsljit_uw aligned_new_start;\n\tsljit_uw page_align;\n#endif\n\n\tif ((new_start < stack->min_start) || (new_start >= stack->end))\n\t\treturn NULL;\n\n#ifdef _WIN32\n\tpage_align = get_page_alignment();\n\n\taligned_new_start = (sljit_uw)new_start & ~page_align;\n\taligned_old_start = ((sljit_uw)stack->start) & ~page_align;\n\tif (aligned_new_start != aligned_old_start) {\n\t\tif (aligned_new_start < aligned_old_start) {\n\t\t\tif (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))\n\t\t\t\treturn NULL;\n\t\t}\n\t\telse {\n\t\t\tif (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))\n\t\t\t\treturn NULL;\n\t\t}\n\t}\n#elif defined(POSIX_MADV_DONTNEED)\n\tif (stack->start < new_start) {\n\t\tpage_align = get_page_alignment();\n\n\t\taligned_new_start = (sljit_uw)new_start & ~page_align;\n\t\taligned_old_start = ((sljit_uw)stack->start) & ~page_align;\n\n\t\tif (aligned_new_start > aligned_old_start) {\n\t\t\tposix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);\n#ifdef MADV_FREE\n\t\t\tmadvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);\n#endif /* MADV_FREE */\n\t\t}\n\t}\n#endif /* _WIN32 */\n\n\tstack->start = new_start;\n\treturn new_start;\n}\n\n#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */\n\n#endif /* SLJIT_UTIL_STACK */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/config-cmake.h.in",
    "content": "/* config.h for CMake builds */\n\n#cmakedefine HAVE_ASSERT_H 1\n#cmakedefine HAVE_BUILTIN_ASSUME 1\n#cmakedefine HAVE_BUILTIN_MUL_OVERFLOW 1\n#cmakedefine HAVE_BUILTIN_UNREACHABLE 1\n#cmakedefine HAVE_ATTRIBUTE_UNINITIALIZED 1\n#cmakedefine HAVE_DIRENT_H 1\n#cmakedefine HAVE_SYS_STAT_H 1\n#cmakedefine HAVE_SYS_TYPES_H 1\n#cmakedefine HAVE_UNISTD_H 1\n#cmakedefine HAVE_WINDOWS_H 1\n\n#cmakedefine HAVE_MEMFD_CREATE 1\n#cmakedefine HAVE_SECURE_GETENV 1\n\n#cmakedefine SUPPORT_PCRE2_8 1\n#cmakedefine SUPPORT_PCRE2_16 1\n#cmakedefine SUPPORT_PCRE2_32 1\n#cmakedefine DISABLE_PERCENT_ZT 1\n\n#cmakedefine SUPPORT_LIBBZ2 1\n#cmakedefine SUPPORT_LIBEDIT 1\n#cmakedefine SUPPORT_LIBREADLINE 1\n#cmakedefine SUPPORT_LIBZ 1\n\n#cmakedefine SUPPORT_JIT 1\n#cmakedefine SLJIT_PROT_EXECUTABLE_ALLOCATOR 1\n#cmakedefine SUPPORT_PCRE2GREP_JIT 1\n#cmakedefine SUPPORT_PCRE2GREP_CALLOUT 1\n#cmakedefine SUPPORT_PCRE2GREP_CALLOUT_FORK 1\n#cmakedefine SUPPORT_UNICODE 1\n#cmakedefine SUPPORT_VALGRIND 1\n\n#cmakedefine BSR_ANYCRLF 1\n#cmakedefine EBCDIC 1\n#cmakedefine EBCDIC_NL25 1\n#cmakedefine EBCDIC_IGNORING_COMPILER 1\n#cmakedefine NEVER_BACKSLASH_C 1\n\n#define PCRE2_EXPORT            @PCRE2_EXPORT@\n#define LINK_SIZE               @PCRE2_LINK_SIZE@\n#define HEAP_LIMIT              @PCRE2_HEAP_LIMIT@\n#define MATCH_LIMIT             @PCRE2_MATCH_LIMIT@\n#define MATCH_LIMIT_DEPTH       @PCRE2_MATCH_LIMIT_DEPTH@\n#define MAX_VARLOOKBEHIND       @PCRE2_MAX_VARLOOKBEHIND@\n#define NEWLINE_DEFAULT         @NEWLINE_DEFAULT@\n#define PARENS_NEST_LIMIT       @PCRE2_PARENS_NEST_LIMIT@\n#define PCRE2GREP_BUFSIZE       @PCRE2GREP_BUFSIZE@\n#define PCRE2GREP_MAX_BUFSIZE   @PCRE2GREP_MAX_BUFSIZE@\n\n#define MAX_NAME_SIZE           128\n#define MAX_NAME_COUNT          10000\n\n/* end config.h for CMake builds */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/config.h.generic",
    "content": "/* src/config.h.  Generated from config.h.in by configure.  */\n/* src/config.h.in.  Generated from configure.ac by autoheader.  */\n\n/* PCRE2 is written in Standard C, but there are a few non-standard things it\ncan cope with, allowing it to run on SunOS4 and other \"close to standard\"\nsystems.\n\nIn environments that support the GNU autotools, config.h.in is converted into\nconfig.h by the \"configure\" script. In environments that use CMake,\nconfig-cmake.in is converted into config.h. If you are going to build PCRE2 \"by\nhand\" without using \"configure\" or CMake, you should copy the distributed\nconfig.h.generic to config.h, and edit the macro definitions to be the way you\nneed them. You must then add -DHAVE_CONFIG_H to all of your compile commands,\nso that config.h is included at the start of every source.\n\nAlternatively, you can avoid editing by using -D on the compiler command line\nto set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,\nbut if you do, default values will be taken from config.h for non-boolean\nmacros that are not defined on the command line.\n\nBoolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be\ndefined (conventionally to 1) for TRUE, and not defined at all for FALSE. All\nsuch macros are listed as a commented #undef in config.h.generic. Macros such\nas MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are\nsurrounded by #ifndef/#endif lines so that the value can be overridden by -D. */\n\n/* By default, the \\R escape sequence matches any Unicode line ending\n   character or sequence of characters. If BSR_ANYCRLF is defined (to any\n   value), this is changed so that backslash-R matches only CR, LF, or CRLF.\n   The build-time default can be overridden by the user of PCRE2 at runtime.\n   */\n/* #undef BSR_ANYCRLF */\n\n/* Define to any value to disable the use of the z and t modifiers in\n   formatting settings such as %zu or %td (this is rarely needed). */\n/* #undef DISABLE_PERCENT_ZT */\n\n/* If you are compiling for a system that uses EBCDIC instead of ASCII\n   character codes, define this macro to any value. When EBCDIC is set, PCRE2\n   assumes that all input strings are in EBCDIC. If you do not define this\n   macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It\n   is not possible to build a version of PCRE2 that supports both EBCDIC and\n   ASCII or UTF-8/16/32. */\n/* #undef EBCDIC */\n\n/* To force an EBCDIC environment, define this macro to make the core PCRE2\n   library functions use EBCDIC codepage 1047, regardless of whether the\n   compiler supports it using C character literals. */\n/* #undef EBCDIC_IGNORING_COMPILER */\n\n/* In an EBCDIC environment, define this macro to any value to arrange for the\n   NL character to be 0x25 instead of the default 0x15. NL plays the role that\n   LF does in an ASCII/Unicode environment. */\n/* #undef EBCDIC_NL25 */\n\n/* Define to 1 if you have the <assert.h> header file. */\n/* #undef HAVE_ASSERT_H */\n\n/* Define this if your compiler supports __attribute__((uninitialized)) */\n/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */\n\n/* Define this if your compiler provides __assume() */\n/* #undef HAVE_BUILTIN_ASSUME */\n\n/* Define this if your compiler provides __builtin_mul_overflow() */\n/* #undef HAVE_BUILTIN_MUL_OVERFLOW */\n\n/* Define this if your compiler provides __builtin_unreachable() */\n/* #undef HAVE_BUILTIN_UNREACHABLE */\n\n/* Define to 1 if you have the <bzlib.h> header file. */\n/* #undef HAVE_BZLIB_H */\n\n/* Define to 1 if you have the <dirent.h> header file. */\n/* #undef HAVE_DIRENT_H */\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n/* #undef HAVE_DLFCN_H */\n\n/* Define to 1 if you have the <editline/readline.h> header file. */\n/* #undef HAVE_EDITLINE_READLINE_H */\n\n/* Define to 1 if you have the <edit/readline/readline.h> header file. */\n/* #undef HAVE_EDIT_READLINE_READLINE_H */\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n/* #undef HAVE_INTTYPES_H */\n\n/* Define to 1 if you have the <limits.h> header file. */\n/* #undef HAVE_LIMITS_H */\n\n/* Define to 1 if you have the `memfd_create' function. */\n/* #undef HAVE_MEMFD_CREATE */\n\n/* Define to 1 if you have the <minix/config.h> header file. */\n/* #undef HAVE_MINIX_CONFIG_H */\n\n/* Define to 1 if you have the `mkostemp' function. */\n/* #undef HAVE_MKOSTEMP */\n\n/* Define if you have POSIX threads libraries and header files. */\n/* #undef HAVE_PTHREAD */\n\n/* Have PTHREAD_PRIO_INHERIT. */\n/* #undef HAVE_PTHREAD_PRIO_INHERIT */\n\n/* Define to 1 if you have the <readline.h> header file. */\n/* #undef HAVE_READLINE_H */\n\n/* Define to 1 if you have the <readline/history.h> header file. */\n/* #undef HAVE_READLINE_HISTORY_H */\n\n/* Define to 1 if you have the <readline/readline.h> header file. */\n/* #undef HAVE_READLINE_READLINE_H */\n\n/* Define to 1 if you have the `realpath' function. */\n/* #undef HAVE_REALPATH */\n\n/* Define to 1 if you have the `secure_getenv' function. */\n/* #undef HAVE_SECURE_GETENV */\n\n/* Define to 1 if you have the <stdint.h> header file. */\n/* #undef HAVE_STDINT_H */\n\n/* Define to 1 if you have the <stdio.h> header file. */\n/* #undef HAVE_STDIO_H */\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n/* #undef HAVE_STDLIB_H */\n\n/* Define to 1 if you have the <strings.h> header file. */\n/* #undef HAVE_STRINGS_H */\n\n/* Define to 1 if you have the <string.h> header file. */\n/* #undef HAVE_STRING_H */\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n/* #undef HAVE_SYS_STAT_H */\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n/* #undef HAVE_SYS_TYPES_H */\n\n/* Define to 1 if you have the <sys/wait.h> header file. */\n/* #undef HAVE_SYS_WAIT_H */\n\n/* Define to 1 if you have the <unistd.h> header file. */\n/* #undef HAVE_UNISTD_H */\n\n/* Define to 1 if the compiler supports GCC compatible visibility\n   declarations. */\n/* #undef HAVE_VISIBILITY */\n\n/* Define to 1 if you have the <wchar.h> header file. */\n/* #undef HAVE_WCHAR_H */\n\n/* Define to 1 if you have the <windows.h> header file. */\n/* #undef HAVE_WINDOWS_H */\n\n/* Define to 1 if you have the <zlib.h> header file. */\n/* #undef HAVE_ZLIB_H */\n\n/* This limits the amount of memory that may be used while matching a pattern.\n   It applies to both pcre2_match() and pcre2_dfa_match(). It does not apply\n   to JIT matching. The value is in kibibytes (units of 1024 bytes). */\n#ifndef HEAP_LIMIT\n#define HEAP_LIMIT 20000000\n#endif\n\n/* The value of LINK_SIZE determines the number of bytes used to store links\n   as offsets within the compiled regex. The default is 2, which allows for\n   compiled patterns up to 65535 code units long. This covers the vast\n   majority of cases. However, PCRE2 can also be compiled to use 3 or 4 bytes\n   instead. This allows for longer patterns in extreme cases. */\n#ifndef LINK_SIZE\n#define LINK_SIZE 2\n#endif\n\n/* Define to the sub-directory where libtool stores uninstalled libraries. */\n/* This is ignored unless you are using libtool. */\n#ifndef LT_OBJDIR\n#define LT_OBJDIR \".libs/\"\n#endif\n\n/* The value of MATCH_LIMIT determines the default number of times the\n   pcre2_match() function can record a backtrack position during a single\n   matching attempt. The value is also used to limit a loop counter in\n   pcre2_dfa_match(). There is a runtime interface for setting a different\n   limit. The limit exists in order to catch runaway regular expressions that\n   take forever to determine that they do not match. The default is set very\n   large so that it does not accidentally catch legitimate cases. */\n#ifndef MATCH_LIMIT\n#define MATCH_LIMIT 10000000\n#endif\n\n/* The above limit applies to all backtracks, whether or not they are nested.\n   In some environments it is desirable to limit the nesting of backtracking\n   (that is, the depth of tree that is searched) more strictly, in order to\n   restrict the maximum amount of heap memory that is used. The value of\n   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it\n   must be less than the value of MATCH_LIMIT. The default is to use the same\n   value as MATCH_LIMIT. There is a runtime method for setting a different\n   limit. In the case of pcre2_dfa_match(), this limit controls the depth of\n   the internal nested function calls that are used for pattern recursions,\n   lookarounds, and atomic groups. */\n#ifndef MATCH_LIMIT_DEPTH\n#define MATCH_LIMIT_DEPTH MATCH_LIMIT\n#endif\n\n/* This limit is parameterized just in case anybody ever wants to change it.\n   Care must be taken if it is increased, because it guards against integer\n   overflow caused by enormously large patterns. */\n#ifndef MAX_NAME_COUNT\n#define MAX_NAME_COUNT 10000\n#endif\n\n/* This limit is parameterized just in case anybody ever wants to change it.\n   Care must be taken if it is increased, because it guards against integer\n   overflow caused by enormously large patterns. */\n#ifndef MAX_NAME_SIZE\n#define MAX_NAME_SIZE 128\n#endif\n\n/* The value of MAX_VARLOOKBEHIND specifies the default maximum length, in\n   characters, for a variable-length lookbehind assertion. */\n#ifndef MAX_VARLOOKBEHIND\n#define MAX_VARLOOKBEHIND 255\n#endif\n\n/* Defining NEVER_BACKSLASH_C locks out the use of \\C in all patterns. */\n/* #undef NEVER_BACKSLASH_C */\n\n/* The value of NEWLINE_DEFAULT determines the default newline character\n   sequence. PCRE2 client programs can override this by selecting other values\n   at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5\n   (ANYCRLF), and 6 (NUL). */\n#ifndef NEWLINE_DEFAULT\n#define NEWLINE_DEFAULT 2\n#endif\n\n/* Name of package */\n#define PACKAGE \"pcre2\"\n\n/* Define to the address where bug reports for this package should be sent. */\n#define PACKAGE_BUGREPORT \"\"\n\n/* Define to the full name of this package. */\n#define PACKAGE_NAME \"PCRE2\"\n\n/* Define to the full name and version of this package. */\n#define PACKAGE_STRING \"PCRE2 10.47\"\n\n/* Define to the one symbol short name of this package. */\n#define PACKAGE_TARNAME \"pcre2\"\n\n/* Define to the home page for this package. */\n#define PACKAGE_URL \"\"\n\n/* Define to the version of this package. */\n#define PACKAGE_VERSION \"10.47\"\n\n/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested\n   parentheses (of any kind) in a pattern. This limits the amount of system\n   stack that is used while compiling a pattern. */\n#ifndef PARENS_NEST_LIMIT\n#define PARENS_NEST_LIMIT 250\n#endif\n\n/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by\n   pcre2grep to hold parts of the file it is searching. The buffer will be\n   expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing\n   very long lines. The actual amount of memory used by pcre2grep is three\n   times this number, because it allows for the buffering of \"before\" and\n   \"after\" lines. */\n#ifndef PCRE2GREP_BUFSIZE\n#define PCRE2GREP_BUFSIZE 20480\n#endif\n\n/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer\n   used by pcre2grep to hold parts of the file it is searching. The actual\n   amount of memory used by pcre2grep is three times this number, because it\n   allows for the buffering of \"before\" and \"after\" lines. */\n#ifndef PCRE2GREP_MAX_BUFSIZE\n#define PCRE2GREP_MAX_BUFSIZE 1048576\n#endif\n\n/* See PCRE2_EXP_DEFN; but this is applied to functions in the libpcre2-posix\n   library. */\n/* #undef PCRE2POSIX_EXP_DEFN */\n\n/* Define to any value if linking libpcre2-posix dynamically. Ideally, if both\n   static and shared libraries are being built, then PCRE2POSIX_SHARED would\n   be defined only for the shared build. Indeed, this is a requirement on\n   Windows. However, when building with Autoconf and libtool, we compile the\n   sources once only to create both the static and shared library, so in this\n   case, PCRE2POSIX_SHARED should only be defined if the shared library is\n   being built, regardless of whether or not the static library is also being\n   built. */\n/* #undef PCRE2POSIX_SHARED */\n\n/* Define to any value to include debugging code. */\n/* #undef PCRE2_DEBUG */\n\n/* Define to the annotation for making a symbol visible. */\n#define PCRE2_EXPORT\n\n/* If you are compiling for a system other than a Unix-like system or\n   Win32, and it needs some magic to be inserted before the definition\n   of a function that is exported by the library, define this macro to\n   contain the relevant magic. If you do not define this macro, a suitable\n   __declspec value is used for Windows systems; in other environments\n   a compiler relevant \"extern\" is used with any \"visibility\" related\n   attributes from PCRE2_EXPORT included.\n   This macro apears at the start of every exported function that is part\n   of the external API. It does not appear on functions that are \"external\"\n   in the C sense, but which are internal to the library. */\n/* #undef PCRE2_EXP_DEFN */\n\n/* Define to any value if linking statically. Ideally, if both static and\n   shared libraries are being built, then PCRE2_STATIC would be defined only\n   for the static build. Indeed, this is a requirement on Windows. With\n   Autoconf and libtool however, it is idiomatic to compile the sources once\n   to create both the static and shared library, so in this case, PCRE2_STATIC\n   should only be defined if no shared library is being built. */\n/* #undef PCRE2_STATIC */\n\n/* Define to necessary symbol if this constant uses a non-standard name on\n   your system. */\n/* #undef PTHREAD_CREATE_JOINABLE */\n\n/* Define to any non-zero number to enable support for SELinux compatible\n   executable memory allocator in JIT. Note that this will have no effect\n   unless SUPPORT_JIT is also defined. */\n/* #undef SLJIT_PROT_EXECUTABLE_ALLOCATOR */\n\n/* Define to 1 if all of the C90 standard headers exist (not just the ones\n   required in a freestanding environment). This macro is provided for\n   backward compatibility; new code need not use it. */\n/* #undef STDC_HEADERS */\n\n/* Define to any value to enable differential fuzzing support. */\n/* #undef SUPPORT_DIFF_FUZZ */\n\n/* Define to any value to enable support for Just-In-Time compiling. */\n/* #undef SUPPORT_JIT */\n\n/* Define to any value to allow pcre2grep to be linked with libbz2, so that it\n   is able to handle .bz2 files. */\n/* #undef SUPPORT_LIBBZ2 */\n\n/* Define to any value to allow pcre2test to be linked with libedit. */\n/* #undef SUPPORT_LIBEDIT */\n\n/* Define to any value to allow pcre2test to be linked with libreadline. */\n/* #undef SUPPORT_LIBREADLINE */\n\n/* Define to any value to allow pcre2grep to be linked with libz, so that it\n   is able to handle .gz files. */\n/* #undef SUPPORT_LIBZ */\n\n/* Define to any value to enable callout script support in pcre2grep. */\n/* #undef SUPPORT_PCRE2GREP_CALLOUT */\n\n/* Define to any value to enable fork support in pcre2grep callout scripts.\n   This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined.\n   */\n/* #undef SUPPORT_PCRE2GREP_CALLOUT_FORK */\n\n/* Define to any value to enable JIT support in pcre2grep. Note that this will\n   have no effect unless SUPPORT_JIT is also defined. */\n/* #undef SUPPORT_PCRE2GREP_JIT */\n\n/* Define to any value to enable the 16 bit PCRE2 library. */\n/* #undef SUPPORT_PCRE2_16 */\n\n/* Define to any value to enable the 32 bit PCRE2 library. */\n/* #undef SUPPORT_PCRE2_32 */\n\n/* Define to any value to enable the 8 bit PCRE2 library. */\n/* #undef SUPPORT_PCRE2_8 */\n\n/* Define to any value to enable support for Unicode and UTF encoding. This\n   will work even in an EBCDIC environment, but it is incompatible with the\n   EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*\n   ASCII/Unicode, but not both at once. */\n/* #undef SUPPORT_UNICODE */\n\n/* Define to any value for valgrind support to find invalid memory reads. */\n/* #undef SUPPORT_VALGRIND */\n\n/* Enable extensions on AIX 3, Interix.  */\n#ifndef _ALL_SOURCE\n# define _ALL_SOURCE 1\n#endif\n/* Enable general extensions on macOS.  */\n#ifndef _DARWIN_C_SOURCE\n# define _DARWIN_C_SOURCE 1\n#endif\n/* Enable general extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# define __EXTENSIONS__ 1\n#endif\n/* Enable GNU extensions on systems that have them.  */\n#ifndef _GNU_SOURCE\n# define _GNU_SOURCE 1\n#endif\n/* Enable X/Open compliant socket functions that do not require linking\n   with -lxnet on HP-UX 11.11.  */\n#ifndef _HPUX_ALT_XOPEN_SOCKET_API\n# define _HPUX_ALT_XOPEN_SOCKET_API 1\n#endif\n/* Identify the host operating system as Minix.\n   This macro does not affect the system headers' behavior.\n   A future release of Autoconf may stop defining this macro.  */\n#ifndef _MINIX\n/* # undef _MINIX */\n#endif\n/* Enable general extensions on NetBSD.\n   Enable NetBSD compatibility extensions on Minix.  */\n#ifndef _NETBSD_SOURCE\n# define _NETBSD_SOURCE 1\n#endif\n/* Enable OpenBSD compatibility extensions on NetBSD.\n   Oddly enough, this does nothing on OpenBSD.  */\n#ifndef _OPENBSD_SOURCE\n# define _OPENBSD_SOURCE 1\n#endif\n/* Define to 1 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_SOURCE\n/* # undef _POSIX_SOURCE */\n#endif\n/* Define to 2 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_1_SOURCE\n/* # undef _POSIX_1_SOURCE */\n#endif\n/* Enable POSIX-compatible threading on Solaris.  */\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# define _POSIX_PTHREAD_SEMANTICS 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */\n#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */\n#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n# define __STDC_WANT_IEC_60559_BFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */\n#ifndef __STDC_WANT_IEC_60559_DFP_EXT__\n# define __STDC_WANT_IEC_60559_DFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */\n#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__\n# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */\n#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__\n# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */\n#ifndef __STDC_WANT_LIB_EXT2__\n# define __STDC_WANT_LIB_EXT2__ 1\n#endif\n/* Enable extensions specified by ISO/IEC 24747:2009.  */\n#ifndef __STDC_WANT_MATH_SPEC_FUNCS__\n# define __STDC_WANT_MATH_SPEC_FUNCS__ 1\n#endif\n/* Enable extensions on HP NonStop.  */\n#ifndef _TANDEM_SOURCE\n# define _TANDEM_SOURCE 1\n#endif\n/* Enable X/Open extensions.  Define to 500 only if necessary\n   to make mbstate_t available.  */\n#ifndef _XOPEN_SOURCE\n/* # undef _XOPEN_SOURCE */\n#endif\n\n/* Version number of package */\n#define VERSION \"10.47\"\n\n/* Number of bits in a file offset, on hosts where this is settable. */\n/* #undef _FILE_OFFSET_BITS */\n\n/* Define for large files, on AIX-style hosts. */\n/* #undef _LARGE_FILES */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Define to the type of a signed integer type of width exactly 64 bits if\n   such a type exists and the standard includes do not define it. */\n/* #undef int64_t */\n\n/* Define to `unsigned int' if <sys/types.h> does not define. */\n/* #undef size_t */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/config.h.in",
    "content": "/* src/config.h.in.  Generated from configure.ac by autoheader.  */\n\n\n/* PCRE2 is written in Standard C, but there are a few non-standard things it\ncan cope with, allowing it to run on SunOS4 and other \"close to standard\"\nsystems.\n\nIn environments that support the GNU autotools, config.h.in is converted into\nconfig.h by the \"configure\" script. In environments that use CMake,\nconfig-cmake.in is converted into config.h. If you are going to build PCRE2 \"by\nhand\" without using \"configure\" or CMake, you should copy the distributed\nconfig.h.generic to config.h, and edit the macro definitions to be the way you\nneed them. You must then add -DHAVE_CONFIG_H to all of your compile commands,\nso that config.h is included at the start of every source.\n\nAlternatively, you can avoid editing by using -D on the compiler command line\nto set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,\nbut if you do, default values will be taken from config.h for non-boolean\nmacros that are not defined on the command line.\n\nBoolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be\ndefined (conventionally to 1) for TRUE, and not defined at all for FALSE. All\nsuch macros are listed as a commented #undef in config.h.generic. Macros such\nas MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are\nsurrounded by #ifndef/#endif lines so that the value can be overridden by -D. */\n\n/* By default, the \\R escape sequence matches any Unicode line ending\n   character or sequence of characters. If BSR_ANYCRLF is defined (to any\n   value), this is changed so that backslash-R matches only CR, LF, or CRLF.\n   The build-time default can be overridden by the user of PCRE2 at runtime.\n   */\n#undef BSR_ANYCRLF\n\n/* Define to any value to disable the use of the z and t modifiers in\n   formatting settings such as %zu or %td (this is rarely needed). */\n#undef DISABLE_PERCENT_ZT\n\n/* If you are compiling for a system that uses EBCDIC instead of ASCII\n   character codes, define this macro to any value. When EBCDIC is set, PCRE2\n   assumes that all input strings are in EBCDIC. If you do not define this\n   macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It\n   is not possible to build a version of PCRE2 that supports both EBCDIC and\n   ASCII or UTF-8/16/32. */\n#undef EBCDIC\n\n/* To force an EBCDIC environment, define this macro to make the core PCRE2\n   library functions use EBCDIC codepage 1047, regardless of whether the\n   compiler supports it using C character literals. */\n#undef EBCDIC_IGNORING_COMPILER\n\n/* In an EBCDIC environment, define this macro to any value to arrange for the\n   NL character to be 0x25 instead of the default 0x15. NL plays the role that\n   LF does in an ASCII/Unicode environment. */\n#undef EBCDIC_NL25\n\n/* Define to 1 if you have the <assert.h> header file. */\n#undef HAVE_ASSERT_H\n\n/* Define this if your compiler supports __attribute__((uninitialized)) */\n#undef HAVE_ATTRIBUTE_UNINITIALIZED\n\n/* Define this if your compiler provides __assume() */\n#undef HAVE_BUILTIN_ASSUME\n\n/* Define this if your compiler provides __builtin_mul_overflow() */\n#undef HAVE_BUILTIN_MUL_OVERFLOW\n\n/* Define this if your compiler provides __builtin_unreachable() */\n#undef HAVE_BUILTIN_UNREACHABLE\n\n/* Define to 1 if you have the <bzlib.h> header file. */\n#undef HAVE_BZLIB_H\n\n/* Define to 1 if you have the <dirent.h> header file. */\n#undef HAVE_DIRENT_H\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#undef HAVE_DLFCN_H\n\n/* Define to 1 if you have the <editline/readline.h> header file. */\n#undef HAVE_EDITLINE_READLINE_H\n\n/* Define to 1 if you have the <edit/readline/readline.h> header file. */\n#undef HAVE_EDIT_READLINE_READLINE_H\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#undef HAVE_INTTYPES_H\n\n/* Define to 1 if you have the <limits.h> header file. */\n#undef HAVE_LIMITS_H\n\n/* Define to 1 if you have the `memfd_create' function. */\n#undef HAVE_MEMFD_CREATE\n\n/* Define to 1 if you have the <minix/config.h> header file. */\n#undef HAVE_MINIX_CONFIG_H\n\n/* Define to 1 if you have the `mkostemp' function. */\n#undef HAVE_MKOSTEMP\n\n/* Define if you have POSIX threads libraries and header files. */\n#undef HAVE_PTHREAD\n\n/* Have PTHREAD_PRIO_INHERIT. */\n#undef HAVE_PTHREAD_PRIO_INHERIT\n\n/* Define to 1 if you have the <readline.h> header file. */\n#undef HAVE_READLINE_H\n\n/* Define to 1 if you have the <readline/history.h> header file. */\n#undef HAVE_READLINE_HISTORY_H\n\n/* Define to 1 if you have the <readline/readline.h> header file. */\n#undef HAVE_READLINE_READLINE_H\n\n/* Define to 1 if you have the `realpath' function. */\n#undef HAVE_REALPATH\n\n/* Define to 1 if you have the `secure_getenv' function. */\n#undef HAVE_SECURE_GETENV\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#undef HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdio.h> header file. */\n#undef HAVE_STDIO_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#undef HAVE_STDLIB_H\n\n/* Define to 1 if you have the <strings.h> header file. */\n#undef HAVE_STRINGS_H\n\n/* Define to 1 if you have the <string.h> header file. */\n#undef HAVE_STRING_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_H\n\n/* Define to 1 if you have the <sys/wait.h> header file. */\n#undef HAVE_SYS_WAIT_H\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#undef HAVE_UNISTD_H\n\n/* Define to 1 if the compiler supports GCC compatible visibility\n   declarations. */\n#undef HAVE_VISIBILITY\n\n/* Define to 1 if you have the <wchar.h> header file. */\n#undef HAVE_WCHAR_H\n\n/* Define to 1 if you have the <windows.h> header file. */\n#undef HAVE_WINDOWS_H\n\n/* Define to 1 if you have the <zlib.h> header file. */\n#undef HAVE_ZLIB_H\n\n/* This limits the amount of memory that may be used while matching a pattern.\n   It applies to both pcre2_match() and pcre2_dfa_match(). It does not apply\n   to JIT matching. The value is in kibibytes (units of 1024 bytes). */\n#undef HEAP_LIMIT\n\n/* The value of LINK_SIZE determines the number of bytes used to store links\n   as offsets within the compiled regex. The default is 2, which allows for\n   compiled patterns up to 65535 code units long. This covers the vast\n   majority of cases. However, PCRE2 can also be compiled to use 3 or 4 bytes\n   instead. This allows for longer patterns in extreme cases. */\n#undef LINK_SIZE\n\n/* Define to the sub-directory where libtool stores uninstalled libraries. */\n#undef LT_OBJDIR\n\n/* The value of MATCH_LIMIT determines the default number of times the\n   pcre2_match() function can record a backtrack position during a single\n   matching attempt. The value is also used to limit a loop counter in\n   pcre2_dfa_match(). There is a runtime interface for setting a different\n   limit. The limit exists in order to catch runaway regular expressions that\n   take forever to determine that they do not match. The default is set very\n   large so that it does not accidentally catch legitimate cases. */\n#undef MATCH_LIMIT\n\n/* The above limit applies to all backtracks, whether or not they are nested.\n   In some environments it is desirable to limit the nesting of backtracking\n   (that is, the depth of tree that is searched) more strictly, in order to\n   restrict the maximum amount of heap memory that is used. The value of\n   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it\n   must be less than the value of MATCH_LIMIT. The default is to use the same\n   value as MATCH_LIMIT. There is a runtime method for setting a different\n   limit. In the case of pcre2_dfa_match(), this limit controls the depth of\n   the internal nested function calls that are used for pattern recursions,\n   lookarounds, and atomic groups. */\n#undef MATCH_LIMIT_DEPTH\n\n/* This limit is parameterized just in case anybody ever wants to change it.\n   Care must be taken if it is increased, because it guards against integer\n   overflow caused by enormously large patterns. */\n#undef MAX_NAME_COUNT\n\n/* This limit is parameterized just in case anybody ever wants to change it.\n   Care must be taken if it is increased, because it guards against integer\n   overflow caused by enormously large patterns. */\n#undef MAX_NAME_SIZE\n\n/* The value of MAX_VARLOOKBEHIND specifies the default maximum length, in\n   characters, for a variable-length lookbehind assertion. */\n#undef MAX_VARLOOKBEHIND\n\n/* Defining NEVER_BACKSLASH_C locks out the use of \\C in all patterns. */\n#undef NEVER_BACKSLASH_C\n\n/* The value of NEWLINE_DEFAULT determines the default newline character\n   sequence. PCRE2 client programs can override this by selecting other values\n   at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5\n   (ANYCRLF), and 6 (NUL). */\n#undef NEWLINE_DEFAULT\n\n/* Name of package */\n#undef PACKAGE\n\n/* Define to the address where bug reports for this package should be sent. */\n#undef PACKAGE_BUGREPORT\n\n/* Define to the full name of this package. */\n#undef PACKAGE_NAME\n\n/* Define to the full name and version of this package. */\n#undef PACKAGE_STRING\n\n/* Define to the one symbol short name of this package. */\n#undef PACKAGE_TARNAME\n\n/* Define to the home page for this package. */\n#undef PACKAGE_URL\n\n/* Define to the version of this package. */\n#undef PACKAGE_VERSION\n\n/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested\n   parentheses (of any kind) in a pattern. This limits the amount of system\n   stack that is used while compiling a pattern. */\n#undef PARENS_NEST_LIMIT\n\n/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by\n   pcre2grep to hold parts of the file it is searching. The buffer will be\n   expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing\n   very long lines. The actual amount of memory used by pcre2grep is three\n   times this number, because it allows for the buffering of \"before\" and\n   \"after\" lines. */\n#undef PCRE2GREP_BUFSIZE\n\n/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer\n   used by pcre2grep to hold parts of the file it is searching. The actual\n   amount of memory used by pcre2grep is three times this number, because it\n   allows for the buffering of \"before\" and \"after\" lines. */\n#undef PCRE2GREP_MAX_BUFSIZE\n\n\n/* See PCRE2_EXP_DEFN; but this is applied to functions in the libpcre2-posix\n   library. */\n#undef PCRE2POSIX_EXP_DEFN\n\n/* Define to any value if linking libpcre2-posix dynamically. Ideally, if both\n   static and shared libraries are being built, then PCRE2POSIX_SHARED would\n   be defined only for the shared build. Indeed, this is a requirement on\n   Windows. However, when building with Autoconf and libtool, we compile the\n   sources once only to create both the static and shared library, so in this\n   case, PCRE2POSIX_SHARED should only be defined if the shared library is\n   being built, regardless of whether or not the static library is also being\n   built. */\n#undef PCRE2POSIX_SHARED\n\n/* Define to any value to include debugging code. */\n#undef PCRE2_DEBUG\n\n/* Define to the annotation for making a symbol visible. */\n#undef PCRE2_EXPORT\n\n\n/* If you are compiling for a system other than a Unix-like system or\n   Win32, and it needs some magic to be inserted before the definition\n   of a function that is exported by the library, define this macro to\n   contain the relevant magic. If you do not define this macro, a suitable\n   __declspec value is used for Windows systems; in other environments\n   a compiler relevant \"extern\" is used with any \"visibility\" related\n   attributes from PCRE2_EXPORT included.\n   This macro apears at the start of every exported function that is part\n   of the external API. It does not appear on functions that are \"external\"\n   in the C sense, but which are internal to the library. */\n#undef PCRE2_EXP_DEFN\n\n/* Define to any value if linking statically. Ideally, if both static and\n   shared libraries are being built, then PCRE2_STATIC would be defined only\n   for the static build. Indeed, this is a requirement on Windows. With\n   Autoconf and libtool however, it is idiomatic to compile the sources once\n   to create both the static and shared library, so in this case, PCRE2_STATIC\n   should only be defined if no shared library is being built. */\n#undef PCRE2_STATIC\n\n/* Define to necessary symbol if this constant uses a non-standard name on\n   your system. */\n#undef PTHREAD_CREATE_JOINABLE\n\n/* Define to any non-zero number to enable support for SELinux compatible\n   executable memory allocator in JIT. Note that this will have no effect\n   unless SUPPORT_JIT is also defined. */\n#undef SLJIT_PROT_EXECUTABLE_ALLOCATOR\n\n/* Define to 1 if all of the C90 standard headers exist (not just the ones\n   required in a freestanding environment). This macro is provided for\n   backward compatibility; new code need not use it. */\n#undef STDC_HEADERS\n\n/* Define to any value to enable differential fuzzing support. */\n#undef SUPPORT_DIFF_FUZZ\n\n/* Define to any value to enable support for Just-In-Time compiling. */\n#undef SUPPORT_JIT\n\n/* Define to any value to allow pcre2grep to be linked with libbz2, so that it\n   is able to handle .bz2 files. */\n#undef SUPPORT_LIBBZ2\n\n/* Define to any value to allow pcre2test to be linked with libedit. */\n#undef SUPPORT_LIBEDIT\n\n/* Define to any value to allow pcre2test to be linked with libreadline. */\n#undef SUPPORT_LIBREADLINE\n\n/* Define to any value to allow pcre2grep to be linked with libz, so that it\n   is able to handle .gz files. */\n#undef SUPPORT_LIBZ\n\n/* Define to any value to enable callout script support in pcre2grep. */\n#undef SUPPORT_PCRE2GREP_CALLOUT\n\n/* Define to any value to enable fork support in pcre2grep callout scripts.\n   This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined.\n   */\n#undef SUPPORT_PCRE2GREP_CALLOUT_FORK\n\n/* Define to any value to enable JIT support in pcre2grep. Note that this will\n   have no effect unless SUPPORT_JIT is also defined. */\n#undef SUPPORT_PCRE2GREP_JIT\n\n/* Define to any value to enable the 16 bit PCRE2 library. */\n#undef SUPPORT_PCRE2_16\n\n/* Define to any value to enable the 32 bit PCRE2 library. */\n#undef SUPPORT_PCRE2_32\n\n/* Define to any value to enable the 8 bit PCRE2 library. */\n#undef SUPPORT_PCRE2_8\n\n/* Define to any value to enable support for Unicode and UTF encoding. This\n   will work even in an EBCDIC environment, but it is incompatible with the\n   EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*\n   ASCII/Unicode, but not both at once. */\n#undef SUPPORT_UNICODE\n\n/* Define to any value for valgrind support to find invalid memory reads. */\n#undef SUPPORT_VALGRIND\n\n/* Enable extensions on AIX 3, Interix.  */\n#ifndef _ALL_SOURCE\n# undef _ALL_SOURCE\n#endif\n/* Enable general extensions on macOS.  */\n#ifndef _DARWIN_C_SOURCE\n# undef _DARWIN_C_SOURCE\n#endif\n/* Enable general extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# undef __EXTENSIONS__\n#endif\n/* Enable GNU extensions on systems that have them.  */\n#ifndef _GNU_SOURCE\n# undef _GNU_SOURCE\n#endif\n/* Enable X/Open compliant socket functions that do not require linking\n   with -lxnet on HP-UX 11.11.  */\n#ifndef _HPUX_ALT_XOPEN_SOCKET_API\n# undef _HPUX_ALT_XOPEN_SOCKET_API\n#endif\n/* Identify the host operating system as Minix.\n   This macro does not affect the system headers' behavior.\n   A future release of Autoconf may stop defining this macro.  */\n#ifndef _MINIX\n# undef _MINIX\n#endif\n/* Enable general extensions on NetBSD.\n   Enable NetBSD compatibility extensions on Minix.  */\n#ifndef _NETBSD_SOURCE\n# undef _NETBSD_SOURCE\n#endif\n/* Enable OpenBSD compatibility extensions on NetBSD.\n   Oddly enough, this does nothing on OpenBSD.  */\n#ifndef _OPENBSD_SOURCE\n# undef _OPENBSD_SOURCE\n#endif\n/* Define to 1 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_SOURCE\n# undef _POSIX_SOURCE\n#endif\n/* Define to 2 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_1_SOURCE\n# undef _POSIX_1_SOURCE\n#endif\n/* Enable POSIX-compatible threading on Solaris.  */\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# undef _POSIX_PTHREAD_SEMANTICS\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */\n#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */\n#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n# undef __STDC_WANT_IEC_60559_BFP_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */\n#ifndef __STDC_WANT_IEC_60559_DFP_EXT__\n# undef __STDC_WANT_IEC_60559_DFP_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */\n#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__\n# undef __STDC_WANT_IEC_60559_FUNCS_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */\n#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__\n# undef __STDC_WANT_IEC_60559_TYPES_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */\n#ifndef __STDC_WANT_LIB_EXT2__\n# undef __STDC_WANT_LIB_EXT2__\n#endif\n/* Enable extensions specified by ISO/IEC 24747:2009.  */\n#ifndef __STDC_WANT_MATH_SPEC_FUNCS__\n# undef __STDC_WANT_MATH_SPEC_FUNCS__\n#endif\n/* Enable extensions on HP NonStop.  */\n#ifndef _TANDEM_SOURCE\n# undef _TANDEM_SOURCE\n#endif\n/* Enable X/Open extensions.  Define to 500 only if necessary\n   to make mbstate_t available.  */\n#ifndef _XOPEN_SOURCE\n# undef _XOPEN_SOURCE\n#endif\n\n\n/* Version number of package */\n#undef VERSION\n\n/* Number of bits in a file offset, on hosts where this is settable. */\n#undef _FILE_OFFSET_BITS\n\n/* Define for large files, on AIX-style hosts. */\n#undef _LARGE_FILES\n\n/* Define to empty if `const' does not conform to ANSI C. */\n#undef const\n\n/* Define to the type of a signed integer type of width exactly 64 bits if\n   such a type exists and the standard includes do not define it. */\n#undef int64_t\n\n/* Define to `unsigned int' if <sys/types.h> does not define. */\n#undef size_t\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/libpcre2-16.sym",
    "content": "# First version of PCRE2 in which symbols were assigned versions.\nPCRE2_10.47 {\n  global:\n    pcre2_callout_enumerate_16;\n    pcre2_code_copy_16;\n    pcre2_code_copy_with_tables_16;\n    pcre2_code_free_16;\n    pcre2_compile_16;\n    pcre2_compile_context_copy_16;\n    pcre2_compile_context_create_16;\n    pcre2_compile_context_free_16;\n    pcre2_config_16;\n    pcre2_convert_context_copy_16;\n    pcre2_convert_context_create_16;\n    pcre2_convert_context_free_16;\n    pcre2_converted_pattern_free_16;\n    pcre2_dfa_match_16;\n    pcre2_general_context_copy_16;\n    pcre2_general_context_create_16;\n    pcre2_general_context_free_16;\n    pcre2_get_error_message_16;\n    pcre2_get_mark_16;\n    pcre2_get_match_data_heapframes_size_16;\n    pcre2_get_match_data_size_16;\n    pcre2_get_ovector_count_16;\n    pcre2_get_ovector_pointer_16;\n    pcre2_get_startchar_16;\n    pcre2_jit_compile_16;\n    pcre2_jit_free_unused_memory_16;\n    pcre2_jit_match_16;\n    pcre2_jit_stack_assign_16;\n    pcre2_jit_stack_create_16;\n    pcre2_jit_stack_free_16;\n    pcre2_maketables_16;\n    pcre2_maketables_free_16;\n    pcre2_match_16;\n    pcre2_match_context_copy_16;\n    pcre2_match_context_create_16;\n    pcre2_match_context_free_16;\n    pcre2_match_data_create_16;\n    pcre2_match_data_create_from_pattern_16;\n    pcre2_match_data_free_16;\n    pcre2_next_match_16;\n    pcre2_pattern_convert_16;\n    pcre2_pattern_info_16;\n    pcre2_serialize_decode_16;\n    pcre2_serialize_encode_16;\n    pcre2_serialize_free_16;\n    pcre2_serialize_get_number_of_codes_16;\n    pcre2_set_bsr_16;\n    pcre2_set_callout_16;\n    pcre2_set_character_tables_16;\n    pcre2_set_compile_extra_options_16;\n    pcre2_set_compile_recursion_guard_16;\n    pcre2_set_depth_limit_16;\n    pcre2_set_glob_escape_16;\n    pcre2_set_glob_separator_16;\n    pcre2_set_heap_limit_16;\n    pcre2_set_match_limit_16;\n    pcre2_set_max_pattern_compiled_length_16;\n    pcre2_set_max_pattern_length_16;\n    pcre2_set_max_varlookbehind_16;\n    pcre2_set_newline_16;\n    pcre2_set_offset_limit_16;\n    pcre2_set_optimize_16;\n    pcre2_set_parens_nest_limit_16;\n    pcre2_set_recursion_limit_16;\n    pcre2_set_recursion_memory_management_16;\n    pcre2_set_substitute_callout_16;\n    pcre2_set_substitute_case_callout_16;\n    pcre2_substitute_16;\n    pcre2_substring_copy_byname_16;\n    pcre2_substring_copy_bynumber_16;\n    pcre2_substring_free_16;\n    pcre2_substring_get_byname_16;\n    pcre2_substring_get_bynumber_16;\n    pcre2_substring_length_byname_16;\n    pcre2_substring_length_bynumber_16;\n    pcre2_substring_list_free_16;\n    pcre2_substring_list_get_16;\n    pcre2_substring_nametable_scan_16;\n    pcre2_substring_number_from_name_16;\n  local:\n    _fini;\n    _init;\n};\n\n# PCRE2_10.48 {} PCRE2_10.47;\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/libpcre2-32.sym",
    "content": "# First version of PCRE2 in which symbols were assigned versions.\nPCRE2_10.47 {\n  global:\n    pcre2_callout_enumerate_32;\n    pcre2_code_copy_32;\n    pcre2_code_copy_with_tables_32;\n    pcre2_code_free_32;\n    pcre2_compile_32;\n    pcre2_compile_context_copy_32;\n    pcre2_compile_context_create_32;\n    pcre2_compile_context_free_32;\n    pcre2_config_32;\n    pcre2_convert_context_copy_32;\n    pcre2_convert_context_create_32;\n    pcre2_convert_context_free_32;\n    pcre2_converted_pattern_free_32;\n    pcre2_dfa_match_32;\n    pcre2_general_context_copy_32;\n    pcre2_general_context_create_32;\n    pcre2_general_context_free_32;\n    pcre2_get_error_message_32;\n    pcre2_get_mark_32;\n    pcre2_get_match_data_heapframes_size_32;\n    pcre2_get_match_data_size_32;\n    pcre2_get_ovector_count_32;\n    pcre2_get_ovector_pointer_32;\n    pcre2_get_startchar_32;\n    pcre2_jit_compile_32;\n    pcre2_jit_free_unused_memory_32;\n    pcre2_jit_match_32;\n    pcre2_jit_stack_assign_32;\n    pcre2_jit_stack_create_32;\n    pcre2_jit_stack_free_32;\n    pcre2_maketables_32;\n    pcre2_maketables_free_32;\n    pcre2_match_32;\n    pcre2_match_context_copy_32;\n    pcre2_match_context_create_32;\n    pcre2_match_context_free_32;\n    pcre2_match_data_create_32;\n    pcre2_match_data_create_from_pattern_32;\n    pcre2_match_data_free_32;\n    pcre2_next_match_32;\n    pcre2_pattern_convert_32;\n    pcre2_pattern_info_32;\n    pcre2_serialize_decode_32;\n    pcre2_serialize_encode_32;\n    pcre2_serialize_free_32;\n    pcre2_serialize_get_number_of_codes_32;\n    pcre2_set_bsr_32;\n    pcre2_set_callout_32;\n    pcre2_set_character_tables_32;\n    pcre2_set_compile_extra_options_32;\n    pcre2_set_compile_recursion_guard_32;\n    pcre2_set_depth_limit_32;\n    pcre2_set_glob_escape_32;\n    pcre2_set_glob_separator_32;\n    pcre2_set_heap_limit_32;\n    pcre2_set_match_limit_32;\n    pcre2_set_max_pattern_compiled_length_32;\n    pcre2_set_max_pattern_length_32;\n    pcre2_set_max_varlookbehind_32;\n    pcre2_set_newline_32;\n    pcre2_set_offset_limit_32;\n    pcre2_set_optimize_32;\n    pcre2_set_parens_nest_limit_32;\n    pcre2_set_recursion_limit_32;\n    pcre2_set_recursion_memory_management_32;\n    pcre2_set_substitute_callout_32;\n    pcre2_set_substitute_case_callout_32;\n    pcre2_substitute_32;\n    pcre2_substring_copy_byname_32;\n    pcre2_substring_copy_bynumber_32;\n    pcre2_substring_free_32;\n    pcre2_substring_get_byname_32;\n    pcre2_substring_get_bynumber_32;\n    pcre2_substring_length_byname_32;\n    pcre2_substring_length_bynumber_32;\n    pcre2_substring_list_free_32;\n    pcre2_substring_list_get_32;\n    pcre2_substring_nametable_scan_32;\n    pcre2_substring_number_from_name_32;\n  local:\n    _fini;\n    _init;\n};\n\n# PCRE2_10.48 {} PCRE2_10.47;\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/libpcre2-8.sym",
    "content": "# First version of PCRE2 in which symbols were assigned versions.\nPCRE2_10.47 {\n  global:\n    pcre2_callout_enumerate_8;\n    pcre2_code_copy_8;\n    pcre2_code_copy_with_tables_8;\n    pcre2_code_free_8;\n    pcre2_compile_8;\n    pcre2_compile_context_copy_8;\n    pcre2_compile_context_create_8;\n    pcre2_compile_context_free_8;\n    pcre2_config_8;\n    pcre2_convert_context_copy_8;\n    pcre2_convert_context_create_8;\n    pcre2_convert_context_free_8;\n    pcre2_converted_pattern_free_8;\n    pcre2_dfa_match_8;\n    pcre2_general_context_copy_8;\n    pcre2_general_context_create_8;\n    pcre2_general_context_free_8;\n    pcre2_get_error_message_8;\n    pcre2_get_mark_8;\n    pcre2_get_match_data_heapframes_size_8;\n    pcre2_get_match_data_size_8;\n    pcre2_get_ovector_count_8;\n    pcre2_get_ovector_pointer_8;\n    pcre2_get_startchar_8;\n    pcre2_jit_compile_8;\n    pcre2_jit_free_unused_memory_8;\n    pcre2_jit_match_8;\n    pcre2_jit_stack_assign_8;\n    pcre2_jit_stack_create_8;\n    pcre2_jit_stack_free_8;\n    pcre2_maketables_8;\n    pcre2_maketables_free_8;\n    pcre2_match_8;\n    pcre2_match_context_copy_8;\n    pcre2_match_context_create_8;\n    pcre2_match_context_free_8;\n    pcre2_match_data_create_8;\n    pcre2_match_data_create_from_pattern_8;\n    pcre2_match_data_free_8;\n    pcre2_next_match_8;\n    pcre2_pattern_convert_8;\n    pcre2_pattern_info_8;\n    pcre2_serialize_decode_8;\n    pcre2_serialize_encode_8;\n    pcre2_serialize_free_8;\n    pcre2_serialize_get_number_of_codes_8;\n    pcre2_set_bsr_8;\n    pcre2_set_callout_8;\n    pcre2_set_character_tables_8;\n    pcre2_set_compile_extra_options_8;\n    pcre2_set_compile_recursion_guard_8;\n    pcre2_set_depth_limit_8;\n    pcre2_set_glob_escape_8;\n    pcre2_set_glob_separator_8;\n    pcre2_set_heap_limit_8;\n    pcre2_set_match_limit_8;\n    pcre2_set_max_pattern_compiled_length_8;\n    pcre2_set_max_pattern_length_8;\n    pcre2_set_max_varlookbehind_8;\n    pcre2_set_newline_8;\n    pcre2_set_offset_limit_8;\n    pcre2_set_optimize_8;\n    pcre2_set_parens_nest_limit_8;\n    pcre2_set_recursion_limit_8;\n    pcre2_set_recursion_memory_management_8;\n    pcre2_set_substitute_callout_8;\n    pcre2_set_substitute_case_callout_8;\n    pcre2_substitute_8;\n    pcre2_substring_copy_byname_8;\n    pcre2_substring_copy_bynumber_8;\n    pcre2_substring_free_8;\n    pcre2_substring_get_byname_8;\n    pcre2_substring_get_bynumber_8;\n    pcre2_substring_length_byname_8;\n    pcre2_substring_length_bynumber_8;\n    pcre2_substring_list_free_8;\n    pcre2_substring_list_get_8;\n    pcre2_substring_nametable_scan_8;\n    pcre2_substring_number_from_name_8;\n  local:\n    _fini;\n    _init;\n};\n\n# PCRE2_10.48 {} PCRE2_10.47;\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/libpcre2-posix.sym",
    "content": "# First version of PCRE2 in which symbols were assigned versions.\nPCRE2_10.47 {\n  global:\n    pcre2_regcomp;\n    pcre2_regerror;\n    pcre2_regexec;\n    pcre2_regfree;\n  local:\n    _fini;\n    _init;\n};\n\n# PCRE2_10.48 {} PCRE2_10.47;\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2.h.generic",
    "content": "/*************************************************\n*       Perl-Compatible Regular Expressions      *\n*************************************************/\n\n/* This is the public header file for the PCRE library, second API, to be\n#included by applications that call PCRE2 functions.\n\n           Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_H_IDEMPOTENT_GUARD\n#define PCRE2_H_IDEMPOTENT_GUARD\n\n/* The current PCRE version information. */\n\n#define PCRE2_MAJOR           10\n#define PCRE2_MINOR           47\n#define PCRE2_PRERELEASE      \n#define PCRE2_DATE            2025-10-21\n\n/* When an application links to a PCRE2 DLL in Windows, the symbols that are\nimported have to be identified as such. When building PCRE2, the appropriate\nexport setting is defined in pcre2_internal.h, which includes this file. So, we\ndon't change existing definitions of PCRE2_EXP_DECL.\n\nBy default, we use the standard \"extern\" declarations. */\n\n#ifndef PCRE2_EXP_DECL\n#  if defined(_WIN32) && !defined(PCRE2_STATIC)\n#    define PCRE2_EXP_DECL  extern __declspec(dllimport)\n#  elif defined __cplusplus\n#    define PCRE2_EXP_DECL  extern \"C\"\n#  else\n#    define PCRE2_EXP_DECL  extern\n#  endif\n#endif\n\n/* When compiling with the MSVC compiler, it is sometimes necessary to include\na \"calling convention\" before exported function names. For example:\n\n  void __cdecl function(....)\n\nmight be needed. In order to make this easy, all the exported functions have\nPCRE2_CALL_CONVENTION just before their names.\n\nPCRE2 normally uses the platform's standard calling convention, so this should\nnot be set unless you know you need it. */\n\n#ifndef PCRE2_CALL_CONVENTION\n#define PCRE2_CALL_CONVENTION\n#endif\n\n/* Have to include limits.h, stdlib.h, and inttypes.h to ensure that size_t and\nuint8_t, UCHAR_MAX, etc are defined. Some systems that do have inttypes.h do\nnot have stdint.h, which is why we use inttypes.h, which according to the C\nstandard is a superset of stdint.h. If inttypes.h is not available the build\nwill break and the relevant values must be provided by some other means. */\n\n#include <limits.h>\n#include <stdlib.h>\n#include <inttypes.h>\n\n/* Allow for C++ users compiling this directly. */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* The following option bits can be passed to pcre2_compile(), pcre2_match(),\nor pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it\nis passed. Put these bits at the most significant end of the options word so\nothers can be added next to them */\n\n#define PCRE2_ANCHORED            0x80000000u\n#define PCRE2_NO_UTF_CHECK        0x40000000u\n#define PCRE2_ENDANCHORED         0x20000000u\n\n/* The following option bits can be passed only to pcre2_compile(). However,\nthey may affect compilation, JIT compilation, and/or interpretive execution.\nThe following tags indicate which:\n\nC   alters what is compiled by pcre2_compile()\nJ   alters what is compiled by pcre2_jit_compile()\nM   is inspected during pcre2_match() execution\nD   is inspected during pcre2_dfa_match() execution\n*/\n\n#define PCRE2_ALLOW_EMPTY_CLASS   0x00000001u  /* C       */\n#define PCRE2_ALT_BSUX            0x00000002u  /* C       */\n#define PCRE2_AUTO_CALLOUT        0x00000004u  /* C       */\n#define PCRE2_CASELESS            0x00000008u  /* C       */\n#define PCRE2_DOLLAR_ENDONLY      0x00000010u  /*   J M D */\n#define PCRE2_DOTALL              0x00000020u  /* C       */\n#define PCRE2_DUPNAMES            0x00000040u  /* C       */\n#define PCRE2_EXTENDED            0x00000080u  /* C       */\n#define PCRE2_FIRSTLINE           0x00000100u  /*   J M D */\n#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u  /* C J M   */\n#define PCRE2_MULTILINE           0x00000400u  /* C       */\n#define PCRE2_NEVER_UCP           0x00000800u  /* C       */\n#define PCRE2_NEVER_UTF           0x00001000u  /* C       */\n#define PCRE2_NO_AUTO_CAPTURE     0x00002000u  /* C       */\n#define PCRE2_NO_AUTO_POSSESS     0x00004000u  /* C       */\n#define PCRE2_NO_DOTSTAR_ANCHOR   0x00008000u  /* C       */\n#define PCRE2_NO_START_OPTIMIZE   0x00010000u  /*   J M D */\n#define PCRE2_UCP                 0x00020000u  /* C J M D */\n#define PCRE2_UNGREEDY            0x00040000u  /* C       */\n#define PCRE2_UTF                 0x00080000u  /* C J M D */\n#define PCRE2_NEVER_BACKSLASH_C   0x00100000u  /* C       */\n#define PCRE2_ALT_CIRCUMFLEX      0x00200000u  /*   J M D */\n#define PCRE2_ALT_VERBNAMES       0x00400000u  /* C       */\n#define PCRE2_USE_OFFSET_LIMIT    0x00800000u  /*   J M D */\n#define PCRE2_EXTENDED_MORE       0x01000000u  /* C       */\n#define PCRE2_LITERAL             0x02000000u  /* C       */\n#define PCRE2_MATCH_INVALID_UTF   0x04000000u  /*   J M D */\n#define PCRE2_ALT_EXTENDED_CLASS  0x08000000u  /* C       */\n\n/* An additional compile options word is available in the compile context. */\n\n#define PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  0x00000001u  /* C */\n#define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    0x00000002u  /* C */\n#define PCRE2_EXTRA_MATCH_WORD               0x00000004u  /* C */\n#define PCRE2_EXTRA_MATCH_LINE               0x00000008u  /* C */\n#define PCRE2_EXTRA_ESCAPED_CR_IS_LF         0x00000010u  /* C */\n#define PCRE2_EXTRA_ALT_BSUX                 0x00000020u  /* C */\n#define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK     0x00000040u  /* C */\n#define PCRE2_EXTRA_CASELESS_RESTRICT        0x00000080u  /* C */\n#define PCRE2_EXTRA_ASCII_BSD                0x00000100u  /* C */\n#define PCRE2_EXTRA_ASCII_BSS                0x00000200u  /* C */\n#define PCRE2_EXTRA_ASCII_BSW                0x00000400u  /* C */\n#define PCRE2_EXTRA_ASCII_POSIX              0x00000800u  /* C */\n#define PCRE2_EXTRA_ASCII_DIGIT              0x00001000u  /* C */\n#define PCRE2_EXTRA_PYTHON_OCTAL             0x00002000u  /* C */\n#define PCRE2_EXTRA_NO_BS0                   0x00004000u  /* C */\n#define PCRE2_EXTRA_NEVER_CALLOUT            0x00008000u  /* C */\n#define PCRE2_EXTRA_TURKISH_CASING           0x00010000u  /* C */\n\n/* These are for pcre2_jit_compile(). */\n\n#define PCRE2_JIT_COMPLETE        0x00000001u  /* For full matching */\n#define PCRE2_JIT_PARTIAL_SOFT    0x00000002u\n#define PCRE2_JIT_PARTIAL_HARD    0x00000004u\n#define PCRE2_JIT_INVALID_UTF     0x00000100u\n#define PCRE2_JIT_TEST_ALLOC      0x00000200u\n\n/* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and\npcre2_substitute(). Some are allowed only for one of the functions, and in\nthese cases it is noted below. Note that PCRE2_ANCHORED, PCRE2_ENDANCHORED and\nPCRE2_NO_UTF_CHECK can also be passed to these functions (though\npcre2_jit_match() ignores the latter since it bypasses all sanity checks). */\n\n#define PCRE2_NOTBOL                      0x00000001u\n#define PCRE2_NOTEOL                      0x00000002u\n#define PCRE2_NOTEMPTY                    0x00000004u  /* ) These two must be kept */\n#define PCRE2_NOTEMPTY_ATSTART            0x00000008u  /* ) adjacent to each other. */\n#define PCRE2_PARTIAL_SOFT                0x00000010u\n#define PCRE2_PARTIAL_HARD                0x00000020u\n#define PCRE2_DFA_RESTART                 0x00000040u  /* pcre2_dfa_match() only */\n#define PCRE2_DFA_SHORTEST                0x00000080u  /* pcre2_dfa_match() only */\n#define PCRE2_SUBSTITUTE_GLOBAL           0x00000100u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_EXTENDED         0x00000200u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_UNSET_EMPTY      0x00000400u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET    0x00000800u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  0x00001000u  /* pcre2_substitute() only */\n#define PCRE2_NO_JIT                      0x00002000u  /* not for pcre2_dfa_match() */\n#define PCRE2_COPY_MATCHED_SUBJECT        0x00004000u\n#define PCRE2_SUBSTITUTE_LITERAL          0x00008000u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_MATCHED          0x00010000u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u  /* pcre2_substitute() only */\n#define PCRE2_DISABLE_RECURSELOOP_CHECK   0x00040000u  /* not for pcre2_dfa_match() or pcre2_jit_match() */\n\n/* Options for pcre2_pattern_convert(). */\n\n#define PCRE2_CONVERT_UTF                    0x00000001u\n#define PCRE2_CONVERT_NO_UTF_CHECK           0x00000002u\n#define PCRE2_CONVERT_POSIX_BASIC            0x00000004u\n#define PCRE2_CONVERT_POSIX_EXTENDED         0x00000008u\n#define PCRE2_CONVERT_GLOB                   0x00000010u\n#define PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR 0x00000030u\n#define PCRE2_CONVERT_GLOB_NO_STARSTAR       0x00000050u\n\n/* Newline and \\R settings, for use in compile contexts. The newline values\nmust be kept in step with values set in config.h and both sets must all be\ngreater than zero. */\n\n#define PCRE2_NEWLINE_CR          1\n#define PCRE2_NEWLINE_LF          2\n#define PCRE2_NEWLINE_CRLF        3\n#define PCRE2_NEWLINE_ANY         4\n#define PCRE2_NEWLINE_ANYCRLF     5\n#define PCRE2_NEWLINE_NUL         6\n\n#define PCRE2_BSR_UNICODE         1\n#define PCRE2_BSR_ANYCRLF         2\n\n/* Error codes for pcre2_compile(). Some of these are also used by\npcre2_pattern_convert(). */\n\n#define PCRE2_ERROR_END_BACKSLASH                  101\n#define PCRE2_ERROR_END_BACKSLASH_C                102\n#define PCRE2_ERROR_UNKNOWN_ESCAPE                 103\n#define PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER        104\n#define PCRE2_ERROR_QUANTIFIER_TOO_BIG             105\n#define PCRE2_ERROR_MISSING_SQUARE_BRACKET         106\n#define PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS        107\n#define PCRE2_ERROR_CLASS_RANGE_ORDER              108\n#define PCRE2_ERROR_QUANTIFIER_INVALID             109\n#define PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT     110\n#define PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY     111\n#define PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS       112\n#define PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING     113\n#define PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS    114\n#define PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE       115\n#define PCRE2_ERROR_NULL_PATTERN                   116\n#define PCRE2_ERROR_BAD_OPTIONS                    117\n#define PCRE2_ERROR_MISSING_COMMENT_CLOSING        118\n#define PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP      119\n#define PCRE2_ERROR_PATTERN_TOO_LARGE              120\n#define PCRE2_ERROR_HEAP_FAILED                    121\n#define PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS  122\n#define PCRE2_ERROR_INTERNAL_CODE_OVERFLOW         123\n#define PCRE2_ERROR_MISSING_CONDITION_CLOSING      124\n#define PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH    125\n#define PCRE2_ERROR_ZERO_RELATIVE_REFERENCE        126\n#define PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES    127\n#define PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED   128\n#define PCRE2_ERROR_BAD_RELATIVE_REFERENCE         129\n#define PCRE2_ERROR_UNKNOWN_POSIX_CLASS            130\n#define PCRE2_ERROR_INTERNAL_STUDY_ERROR           131\n#define PCRE2_ERROR_UNICODE_NOT_SUPPORTED          132\n#define PCRE2_ERROR_PARENTHESES_STACK_CHECK        133\n#define PCRE2_ERROR_CODE_POINT_TOO_BIG             134\n#define PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED     135\n#define PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C 136\n#define PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE    137\n#define PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG         138\n#define PCRE2_ERROR_MISSING_CALLOUT_CLOSING        139\n#define PCRE2_ERROR_ESCAPE_INVALID_IN_VERB         140\n#define PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P     141\n#define PCRE2_ERROR_MISSING_NAME_TERMINATOR        142\n#define PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME      143\n#define PCRE2_ERROR_INVALID_SUBPATTERN_NAME        144\n#define PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE 145\n#define PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY     146\n#define PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY       147\n#define PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG       148\n#define PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS     149\n#define PCRE2_ERROR_CLASS_INVALID_RANGE            150\n#define PCRE2_ERROR_OCTAL_BYTE_TOO_BIG             151\n#define PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE     152\n#define PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN    153\n#define PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES       154\n#define PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE      155\n#define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE       156\n#define PCRE2_ERROR_BACKSLASH_G_SYNTAX             157\n#define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158\n/* Error 159 is obsolete and should now never occur */\n#define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED      159\n#define PCRE2_ERROR_VERB_UNKNOWN                   160\n#define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG      161\n#define PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED       162\n#define PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW       163\n#define PCRE2_ERROR_INVALID_OCTAL                  164\n#define PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH      165\n#define PCRE2_ERROR_MARK_MISSING_ARGUMENT          166\n#define PCRE2_ERROR_INVALID_HEXADECIMAL            167\n#define PCRE2_ERROR_BACKSLASH_C_SYNTAX             168\n#define PCRE2_ERROR_BACKSLASH_K_SYNTAX             169\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS  170\n#define PCRE2_ERROR_BACKSLASH_N_IN_CLASS           171\n#define PCRE2_ERROR_CALLOUT_STRING_TOO_LONG        172\n#define PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT  173\n#define PCRE2_ERROR_UTF_IS_DISABLED                174\n#define PCRE2_ERROR_UCP_IS_DISABLED                175\n#define PCRE2_ERROR_VERB_NAME_TOO_LONG             176\n#define PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG 177\n#define PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS    178\n#define PCRE2_ERROR_VERSION_CONDITION_SYNTAX       179\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS 180\n#define PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER    181\n#define PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER   182\n#define PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED    183\n#define PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP      184\n#define PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED   185\n#define PCRE2_ERROR_PATTERN_TOO_COMPLICATED        186\n#define PCRE2_ERROR_LOOKBEHIND_TOO_LONG            187\n#define PCRE2_ERROR_PATTERN_STRING_TOO_LONG        188\n#define PCRE2_ERROR_INTERNAL_BAD_CODE              189\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP      190\n#define PCRE2_ERROR_NO_SURROGATES_IN_UTF16         191\n#define PCRE2_ERROR_BAD_LITERAL_OPTIONS            192\n#define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE      193\n#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS      194\n#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN        195\n#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE       196\n#define PCRE2_ERROR_TOO_MANY_CAPTURES              197\n#define PCRE2_ERROR_MISSING_OCTAL_DIGIT            198\n#define PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND      199\n#define PCRE2_ERROR_MAX_VAR_LOOKBEHIND_EXCEEDED    200\n#define PCRE2_ERROR_PATTERN_COMPILED_SIZE_TOO_BIG  201\n#define PCRE2_ERROR_OVERSIZE_PYTHON_OCTAL          202\n#define PCRE2_ERROR_CALLOUT_CALLER_DISABLED        203\n#define PCRE2_ERROR_EXTRA_CASING_REQUIRES_UNICODE  204\n#define PCRE2_ERROR_TURKISH_CASING_REQUIRES_UTF    205\n#define PCRE2_ERROR_EXTRA_CASING_INCOMPATIBLE      206\n#define PCRE2_ERROR_ECLASS_NEST_TOO_DEEP           207\n#define PCRE2_ERROR_ECLASS_INVALID_OPERATOR        208\n#define PCRE2_ERROR_ECLASS_UNEXPECTED_OPERATOR     209\n#define PCRE2_ERROR_ECLASS_EXPECTED_OPERAND        210\n#define PCRE2_ERROR_ECLASS_MIXED_OPERATORS         211\n#define PCRE2_ERROR_ECLASS_HINT_SQUARE_BRACKET     212\n#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_EXPR    213\n#define PCRE2_ERROR_PERL_ECLASS_EMPTY_EXPR         214\n#define PCRE2_ERROR_PERL_ECLASS_MISSING_CLOSE      215\n#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_CHAR    216\n#define PCRE2_ERROR_EXPECTED_CAPTURE_GROUP         217\n#define PCRE2_ERROR_MISSING_OPENING_PARENTHESIS    218\n#define PCRE2_ERROR_MISSING_NUMBER_TERMINATOR      219\n#define PCRE2_ERROR_NULL_ERROROFFSET               220\n\n/* \"Expected\" matching error codes: no match and partial match. */\n\n#define PCRE2_ERROR_NOMATCH          (-1)\n#define PCRE2_ERROR_PARTIAL          (-2)\n\n/* Error codes for UTF-8 validity checks */\n\n#define PCRE2_ERROR_UTF8_ERR1        (-3)\n#define PCRE2_ERROR_UTF8_ERR2        (-4)\n#define PCRE2_ERROR_UTF8_ERR3        (-5)\n#define PCRE2_ERROR_UTF8_ERR4        (-6)\n#define PCRE2_ERROR_UTF8_ERR5        (-7)\n#define PCRE2_ERROR_UTF8_ERR6        (-8)\n#define PCRE2_ERROR_UTF8_ERR7        (-9)\n#define PCRE2_ERROR_UTF8_ERR8       (-10)\n#define PCRE2_ERROR_UTF8_ERR9       (-11)\n#define PCRE2_ERROR_UTF8_ERR10      (-12)\n#define PCRE2_ERROR_UTF8_ERR11      (-13)\n#define PCRE2_ERROR_UTF8_ERR12      (-14)\n#define PCRE2_ERROR_UTF8_ERR13      (-15)\n#define PCRE2_ERROR_UTF8_ERR14      (-16)\n#define PCRE2_ERROR_UTF8_ERR15      (-17)\n#define PCRE2_ERROR_UTF8_ERR16      (-18)\n#define PCRE2_ERROR_UTF8_ERR17      (-19)\n#define PCRE2_ERROR_UTF8_ERR18      (-20)\n#define PCRE2_ERROR_UTF8_ERR19      (-21)\n#define PCRE2_ERROR_UTF8_ERR20      (-22)\n#define PCRE2_ERROR_UTF8_ERR21      (-23)\n\n/* Error codes for UTF-16 validity checks */\n\n#define PCRE2_ERROR_UTF16_ERR1      (-24)\n#define PCRE2_ERROR_UTF16_ERR2      (-25)\n#define PCRE2_ERROR_UTF16_ERR3      (-26)\n\n/* Error codes for UTF-32 validity checks */\n\n#define PCRE2_ERROR_UTF32_ERR1      (-27)\n#define PCRE2_ERROR_UTF32_ERR2      (-28)\n\n/* Miscellaneous error codes for pcre2[_dfa]_match(), substring extraction\nfunctions, context functions, and serializing functions. They are in numerical\norder. Originally they were in alphabetical order too, but now that PCRE2 is\nreleased, the numbers must not be changed. */\n\n#define PCRE2_ERROR_BADDATA           (-29)\n#define PCRE2_ERROR_MIXEDTABLES       (-30)  /* Name was changed */\n#define PCRE2_ERROR_BADMAGIC          (-31)\n#define PCRE2_ERROR_BADMODE           (-32)\n#define PCRE2_ERROR_BADOFFSET         (-33)\n#define PCRE2_ERROR_BADOPTION         (-34)\n#define PCRE2_ERROR_BADREPLACEMENT    (-35)\n#define PCRE2_ERROR_BADUTFOFFSET      (-36)\n#define PCRE2_ERROR_CALLOUT           (-37)  /* Never used by PCRE2 itself */\n#define PCRE2_ERROR_DFA_BADRESTART    (-38)\n#define PCRE2_ERROR_DFA_RECURSE       (-39)\n#define PCRE2_ERROR_DFA_UCOND         (-40)\n#define PCRE2_ERROR_DFA_UFUNC         (-41)\n#define PCRE2_ERROR_DFA_UITEM         (-42)\n#define PCRE2_ERROR_DFA_WSSIZE        (-43)\n#define PCRE2_ERROR_INTERNAL          (-44)\n#define PCRE2_ERROR_JIT_BADOPTION     (-45)\n#define PCRE2_ERROR_JIT_STACKLIMIT    (-46)\n#define PCRE2_ERROR_MATCHLIMIT        (-47)\n#define PCRE2_ERROR_NOMEMORY          (-48)\n#define PCRE2_ERROR_NOSUBSTRING       (-49)\n#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)\n#define PCRE2_ERROR_NULL              (-51)\n#define PCRE2_ERROR_RECURSELOOP       (-52)\n#define PCRE2_ERROR_DEPTHLIMIT        (-53)\n#define PCRE2_ERROR_RECURSIONLIMIT    (-53)  /* Obsolete synonym */\n#define PCRE2_ERROR_UNAVAILABLE       (-54)\n#define PCRE2_ERROR_UNSET             (-55)\n#define PCRE2_ERROR_BADOFFSETLIMIT    (-56)\n#define PCRE2_ERROR_BADREPESCAPE      (-57)\n#define PCRE2_ERROR_REPMISSINGBRACE   (-58)\n#define PCRE2_ERROR_BADSUBSTITUTION   (-59)\n#define PCRE2_ERROR_BADSUBSPATTERN    (-60)\n#define PCRE2_ERROR_TOOMANYREPLACE    (-61)\n#define PCRE2_ERROR_BADSERIALIZEDDATA (-62)\n#define PCRE2_ERROR_HEAPLIMIT         (-63)\n#define PCRE2_ERROR_CONVERT_SYNTAX    (-64)\n#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)\n#define PCRE2_ERROR_DFA_UINVALID_UTF  (-66)\n#define PCRE2_ERROR_INVALIDOFFSET     (-67)\n#define PCRE2_ERROR_JIT_UNSUPPORTED   (-68)\n#define PCRE2_ERROR_REPLACECASE       (-69)\n#define PCRE2_ERROR_TOOLARGEREPLACE   (-70)\n#define PCRE2_ERROR_DIFFSUBSPATTERN   (-71)\n#define PCRE2_ERROR_DIFFSUBSSUBJECT   (-72)\n#define PCRE2_ERROR_DIFFSUBSOFFSET    (-73)\n#define PCRE2_ERROR_DIFFSUBSOPTIONS   (-74)\n#define PCRE2_ERROR_BAD_BACKSLASH_K   (-75)\n\n\n/* Request types for pcre2_pattern_info() */\n\n#define PCRE2_INFO_ALLOPTIONS            0\n#define PCRE2_INFO_ARGOPTIONS            1\n#define PCRE2_INFO_BACKREFMAX            2\n#define PCRE2_INFO_BSR                   3\n#define PCRE2_INFO_CAPTURECOUNT          4\n#define PCRE2_INFO_FIRSTCODEUNIT         5\n#define PCRE2_INFO_FIRSTCODETYPE         6\n#define PCRE2_INFO_FIRSTBITMAP           7\n#define PCRE2_INFO_HASCRORLF             8\n#define PCRE2_INFO_JCHANGED              9\n#define PCRE2_INFO_JITSIZE              10\n#define PCRE2_INFO_LASTCODEUNIT         11\n#define PCRE2_INFO_LASTCODETYPE         12\n#define PCRE2_INFO_MATCHEMPTY           13\n#define PCRE2_INFO_MATCHLIMIT           14\n#define PCRE2_INFO_MAXLOOKBEHIND        15\n#define PCRE2_INFO_MINLENGTH            16\n#define PCRE2_INFO_NAMECOUNT            17\n#define PCRE2_INFO_NAMEENTRYSIZE        18\n#define PCRE2_INFO_NAMETABLE            19\n#define PCRE2_INFO_NEWLINE              20\n#define PCRE2_INFO_DEPTHLIMIT           21\n#define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */\n#define PCRE2_INFO_SIZE                 22\n#define PCRE2_INFO_HASBACKSLASHC        23\n#define PCRE2_INFO_FRAMESIZE            24\n#define PCRE2_INFO_HEAPLIMIT            25\n#define PCRE2_INFO_EXTRAOPTIONS         26\n\n/* Request types for pcre2_config(). */\n\n#define PCRE2_CONFIG_BSR                     0\n#define PCRE2_CONFIG_JIT                     1\n#define PCRE2_CONFIG_JITTARGET               2\n#define PCRE2_CONFIG_LINKSIZE                3\n#define PCRE2_CONFIG_MATCHLIMIT              4\n#define PCRE2_CONFIG_NEWLINE                 5\n#define PCRE2_CONFIG_PARENSLIMIT             6\n#define PCRE2_CONFIG_DEPTHLIMIT              7\n#define PCRE2_CONFIG_RECURSIONLIMIT          7  /* Obsolete synonym */\n#define PCRE2_CONFIG_STACKRECURSE            8  /* Obsolete */\n#define PCRE2_CONFIG_UNICODE                 9\n#define PCRE2_CONFIG_UNICODE_VERSION        10\n#define PCRE2_CONFIG_VERSION                11\n#define PCRE2_CONFIG_HEAPLIMIT              12\n#define PCRE2_CONFIG_NEVER_BACKSLASH_C      13\n#define PCRE2_CONFIG_COMPILED_WIDTHS        14\n#define PCRE2_CONFIG_TABLES_LENGTH          15\n#define PCRE2_CONFIG_EFFECTIVE_LINKSIZE     16\n\n/* Optimization directives for pcre2_set_optimize().\nFor binary compatibility, only add to this list; do not renumber. */\n\n#define PCRE2_OPTIMIZATION_NONE    0\n#define PCRE2_OPTIMIZATION_FULL    1\n\n#define PCRE2_AUTO_POSSESS         64\n#define PCRE2_AUTO_POSSESS_OFF     65\n#define PCRE2_DOTSTAR_ANCHOR       66\n#define PCRE2_DOTSTAR_ANCHOR_OFF   67\n#define PCRE2_START_OPTIMIZE       68\n#define PCRE2_START_OPTIMIZE_OFF   69\n\n/* Types used in pcre2_set_substitute_case_callout().\n\nPCRE2_SUBSTITUTE_CASE_LOWER and PCRE2_SUBSTITUTE_CASE_UPPER are passed to the\ncallout to indicate that the case of the entire callout input should be\ncase-transformed. PCRE2_SUBSTITUTE_CASE_TITLE_FIRST is passed to indicate that\nonly the first character or glyph should be transformed to Unicode titlecase,\nand the rest to lowercase. */\n\n#define PCRE2_SUBSTITUTE_CASE_LOWER        1\n#define PCRE2_SUBSTITUTE_CASE_UPPER        2\n#define PCRE2_SUBSTITUTE_CASE_TITLE_FIRST  3\n\n/* Types for code units in patterns and subject strings. */\n\ntypedef uint8_t  PCRE2_UCHAR8;\ntypedef uint16_t PCRE2_UCHAR16;\ntypedef uint32_t PCRE2_UCHAR32;\n\ntypedef const PCRE2_UCHAR8  *PCRE2_SPTR8;\ntypedef const PCRE2_UCHAR16 *PCRE2_SPTR16;\ntypedef const PCRE2_UCHAR32 *PCRE2_SPTR32;\n\n/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2,\nincluding pattern offsets for errors and subject offsets after a match. We\ndefine special values to indicate zero-terminated strings and unset offsets in\nthe offset vector (ovector). */\n\n#define PCRE2_SIZE            size_t\n#define PCRE2_SIZE_MAX        SIZE_MAX\n#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)\n#define PCRE2_UNSET           (~(PCRE2_SIZE)0)\n\n/* Generic types for opaque structures and JIT callback functions. These\ndeclarations are defined in a macro that is expanded for each width later. */\n\n#define PCRE2_TYPES_LIST \\\nstruct pcre2_real_general_context; \\\ntypedef struct pcre2_real_general_context pcre2_general_context; \\\n\\\nstruct pcre2_real_compile_context; \\\ntypedef struct pcre2_real_compile_context pcre2_compile_context; \\\n\\\nstruct pcre2_real_match_context; \\\ntypedef struct pcre2_real_match_context pcre2_match_context; \\\n\\\nstruct pcre2_real_convert_context; \\\ntypedef struct pcre2_real_convert_context pcre2_convert_context; \\\n\\\nstruct pcre2_real_code; \\\ntypedef struct pcre2_real_code pcre2_code; \\\n\\\nstruct pcre2_real_match_data; \\\ntypedef struct pcre2_real_match_data pcre2_match_data; \\\n\\\nstruct pcre2_real_jit_stack; \\\ntypedef struct pcre2_real_jit_stack pcre2_jit_stack; \\\n\\\ntypedef pcre2_jit_stack *(*pcre2_jit_callback)(void *);\n\n\n/* The structures for passing out data via callout functions. We use structures\nso that new fields can be added on the end in future versions, without changing\nthe API of the function, thereby allowing old clients to work without\nmodification. Define the generic versions in a macro; the width-specific\nversions are generated from this macro below. */\n\n/* Flags for the callout_flags field. These are cleared after a callout. */\n\n#define PCRE2_CALLOUT_STARTMATCH    0x00000001u  /* Set for each bumpalong */\n#define PCRE2_CALLOUT_BACKTRACK     0x00000002u  /* Set after a backtrack */\n\n#define PCRE2_STRUCTURE_LIST \\\ntypedef struct pcre2_callout_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  uint32_t      callout_number;    /* Number compiled into pattern */ \\\n  uint32_t      capture_top;       /* Max current capture */ \\\n  uint32_t      capture_last;      /* Most recently closed capture */ \\\n  PCRE2_SIZE   *offset_vector;     /* The offset vector */ \\\n  PCRE2_SPTR    mark;              /* Pointer to current mark or NULL */ \\\n  PCRE2_SPTR    subject;           /* The subject being matched */ \\\n  PCRE2_SIZE    subject_length;    /* The length of the subject */ \\\n  PCRE2_SIZE    start_match;       /* Offset to start of this match attempt */ \\\n  PCRE2_SIZE    current_position;  /* Where we currently are in the subject */ \\\n  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \\\n  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \\\n  /* ------------------- Added for Version 1 -------------------------- */ \\\n  PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \\\n  PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \\\n  PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \\\n  /* ------------------- Added for Version 2 -------------------------- */ \\\n  uint32_t      callout_flags;     /* See above for list */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_callout_block; \\\n\\\ntypedef struct pcre2_callout_enumerate_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \\\n  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \\\n  uint32_t      callout_number;    /* Number compiled into pattern */ \\\n  PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \\\n  PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \\\n  PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_callout_enumerate_block; \\\n\\\ntypedef struct pcre2_substitute_callout_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  PCRE2_SPTR    input;             /* Pointer to input subject string */ \\\n  PCRE2_SPTR    output;            /* Pointer to output buffer */ \\\n  PCRE2_SIZE    output_offsets[2]; /* Changed portion of the output */ \\\n  PCRE2_SIZE   *ovector;           /* Pointer to current ovector */ \\\n  uint32_t      oveccount;         /* Count of pairs set in ovector */ \\\n  uint32_t      subscount;         /* Substitution number */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_substitute_callout_block;\n\n\n/* List the generic forms of all other functions in macros, which will be\nexpanded for each width below. Start with functions that give general\ninformation. */\n\n#define PCRE2_GENERAL_INFO_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);\n\n\n/* Functions for manipulating contexts. */\n\n#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_copy(pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_create(void *(*)(size_t, void *), \\\n    void (*)(void *, void *), void *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_free(pcre2_general_context *);\n\n#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_copy(pcre2_compile_context *); \\\nPCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_create(pcre2_general_context *);\\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_free(pcre2_compile_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_bsr(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_character_tables(pcre2_compile_context *, const uint8_t *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_pattern_compiled_length(pcre2_compile_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_varlookbehind(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_newline(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_compile_recursion_guard(pcre2_compile_context *, \\\n    int (*)(uint32_t, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_optimize(pcre2_compile_context *, uint32_t);\n\n#define PCRE2_MATCH_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_copy(pcre2_match_context *); \\\nPCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_create(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_free(pcre2_match_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_callout(pcre2_match_context *, \\\n    int (*)(pcre2_callout_block *, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_substitute_callout(pcre2_match_context *, \\\n    int (*)(pcre2_substitute_callout_block *, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_substitute_case_callout(pcre2_match_context *, \\\n    PCRE2_SIZE (*)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE, int, \\\n                   void *), \\\n    void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_match_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_recursion_memory_management(pcre2_match_context *, \\\n    void *(*)(size_t, void *), void (*)(void *, void *), void *);\n\n#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_copy(pcre2_convert_context *); \\\nPCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_create(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_free(pcre2_convert_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_glob_escape(pcre2_convert_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_glob_separator(pcre2_convert_context *, uint32_t);\n\n\n/* Functions concerned with compiling a pattern to PCRE internal code. */\n\n#define PCRE2_COMPILE_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \\\n    pcre2_compile_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_code_free(pcre2_code *); \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_code_copy(const pcre2_code *); \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_code_copy_with_tables(const pcre2_code *);\n\n\n/* Functions that give information about a compiled pattern. */\n\n#define PCRE2_PATTERN_INFO_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_callout_enumerate(const pcre2_code *, \\\n    int (*)(pcre2_callout_enumerate_block *, void *), void *);\n\n\n/* Functions for running a match and inspecting the result. */\n\n#define PCRE2_MATCH_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_create(uint32_t, pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_create_from_pattern(const pcre2_code *, \\\n    pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_free(pcre2_match_data *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *); \\\nPCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \\\n  pcre2_get_mark(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_match_data_size(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_match_data_heapframes_size(pcre2_match_data *); \\\nPCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \\\n  pcre2_get_ovector_count(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \\\n  pcre2_get_ovector_pointer(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_startchar(pcre2_match_data *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_next_match(pcre2_match_data *, PCRE2_SIZE *, uint32_t *);\n\n\n/* Convenience functions for handling matched substrings. */\n\n#define PCRE2_SUBSTRING_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_substring_free(PCRE2_UCHAR *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \\\n    PCRE2_SPTR *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_substring_list_free(PCRE2_UCHAR **); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **);\n\n\n/* Functions for serializing / deserializing compiled patterns. */\n\n#define PCRE2_SERIALIZE_FUNCTIONS \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \\\n    PCRE2_SIZE *, pcre2_general_context *); \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \\\n    pcre2_general_context *); \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_get_number_of_codes(const uint8_t *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_free(uint8_t *);\n\n\n/* Convenience function for match + substitute. */\n\n#define PCRE2_SUBSTITUTE_FUNCTION \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \\\n    PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);\n\n\n/* Functions for converting pattern source strings. */\n\n#define PCRE2_CONVERT_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_pattern_convert(PCRE2_SPTR, PCRE2_SIZE, uint32_t, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *, pcre2_convert_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_converted_pattern_free(PCRE2_UCHAR *);\n\n\n/* Functions for JIT processing */\n\n#define PCRE2_JIT_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_jit_compile(pcre2_code *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_free_unused_memory(pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_create(size_t, size_t, pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_free(pcre2_jit_stack *);\n\n\n/* Other miscellaneous functions. */\n\n#define PCRE2_OTHER_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL const uint8_t *PCRE2_CALL_CONVENTION \\\n  pcre2_maketables(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_maketables_free(pcre2_general_context *, const uint8_t *);\n\n/* Define macros that generate width-specific names from generic versions. The\nthree-level macro scheme is necessary to get the macros expanded when we want\nthem to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for\ngenerating three versions of everything below. After that, PCRE2_SUFFIX will be\nre-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as\npcre2_compile are called by application code. */\n\n#define PCRE2_JOIN(a,b) a ## b\n#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b)\n#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH)\n\n\n/* Data types */\n\n#define PCRE2_UCHAR                 PCRE2_SUFFIX(PCRE2_UCHAR)\n#define PCRE2_SPTR                  PCRE2_SUFFIX(PCRE2_SPTR)\n\n#define pcre2_code                  PCRE2_SUFFIX(pcre2_code_)\n#define pcre2_jit_callback          PCRE2_SUFFIX(pcre2_jit_callback_)\n#define pcre2_jit_stack             PCRE2_SUFFIX(pcre2_jit_stack_)\n\n#define pcre2_real_code             PCRE2_SUFFIX(pcre2_real_code_)\n#define pcre2_real_general_context  PCRE2_SUFFIX(pcre2_real_general_context_)\n#define pcre2_real_compile_context  PCRE2_SUFFIX(pcre2_real_compile_context_)\n#define pcre2_real_convert_context  PCRE2_SUFFIX(pcre2_real_convert_context_)\n#define pcre2_real_match_context    PCRE2_SUFFIX(pcre2_real_match_context_)\n#define pcre2_real_jit_stack        PCRE2_SUFFIX(pcre2_real_jit_stack_)\n#define pcre2_real_match_data       PCRE2_SUFFIX(pcre2_real_match_data_)\n\n\n/* Data blocks */\n\n#define pcre2_callout_block            PCRE2_SUFFIX(pcre2_callout_block_)\n#define pcre2_callout_enumerate_block  PCRE2_SUFFIX(pcre2_callout_enumerate_block_)\n#define pcre2_substitute_callout_block PCRE2_SUFFIX(pcre2_substitute_callout_block_)\n#define pcre2_general_context          PCRE2_SUFFIX(pcre2_general_context_)\n#define pcre2_compile_context          PCRE2_SUFFIX(pcre2_compile_context_)\n#define pcre2_convert_context          PCRE2_SUFFIX(pcre2_convert_context_)\n#define pcre2_match_context            PCRE2_SUFFIX(pcre2_match_context_)\n#define pcre2_match_data               PCRE2_SUFFIX(pcre2_match_data_)\n\n\n/* Functions: the complete list in alphabetical order */\n\n#define pcre2_callout_enumerate               PCRE2_SUFFIX(pcre2_callout_enumerate_)\n#define pcre2_code_copy                       PCRE2_SUFFIX(pcre2_code_copy_)\n#define pcre2_code_copy_with_tables           PCRE2_SUFFIX(pcre2_code_copy_with_tables_)\n#define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)\n#define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)\n#define pcre2_compile_context_copy            PCRE2_SUFFIX(pcre2_compile_context_copy_)\n#define pcre2_compile_context_create          PCRE2_SUFFIX(pcre2_compile_context_create_)\n#define pcre2_compile_context_free            PCRE2_SUFFIX(pcre2_compile_context_free_)\n#define pcre2_config                          PCRE2_SUFFIX(pcre2_config_)\n#define pcre2_convert_context_copy            PCRE2_SUFFIX(pcre2_convert_context_copy_)\n#define pcre2_convert_context_create          PCRE2_SUFFIX(pcre2_convert_context_create_)\n#define pcre2_convert_context_free            PCRE2_SUFFIX(pcre2_convert_context_free_)\n#define pcre2_converted_pattern_free          PCRE2_SUFFIX(pcre2_converted_pattern_free_)\n#define pcre2_dfa_match                       PCRE2_SUFFIX(pcre2_dfa_match_)\n#define pcre2_general_context_copy            PCRE2_SUFFIX(pcre2_general_context_copy_)\n#define pcre2_general_context_create          PCRE2_SUFFIX(pcre2_general_context_create_)\n#define pcre2_general_context_free            PCRE2_SUFFIX(pcre2_general_context_free_)\n#define pcre2_get_error_message               PCRE2_SUFFIX(pcre2_get_error_message_)\n#define pcre2_get_mark                        PCRE2_SUFFIX(pcre2_get_mark_)\n#define pcre2_get_match_data_heapframes_size  PCRE2_SUFFIX(pcre2_get_match_data_heapframes_size_)\n#define pcre2_get_match_data_size             PCRE2_SUFFIX(pcre2_get_match_data_size_)\n#define pcre2_get_ovector_pointer             PCRE2_SUFFIX(pcre2_get_ovector_pointer_)\n#define pcre2_get_ovector_count               PCRE2_SUFFIX(pcre2_get_ovector_count_)\n#define pcre2_get_startchar                   PCRE2_SUFFIX(pcre2_get_startchar_)\n#define pcre2_jit_compile                     PCRE2_SUFFIX(pcre2_jit_compile_)\n#define pcre2_jit_match                       PCRE2_SUFFIX(pcre2_jit_match_)\n#define pcre2_jit_free_unused_memory          PCRE2_SUFFIX(pcre2_jit_free_unused_memory_)\n#define pcre2_jit_stack_assign                PCRE2_SUFFIX(pcre2_jit_stack_assign_)\n#define pcre2_jit_stack_create                PCRE2_SUFFIX(pcre2_jit_stack_create_)\n#define pcre2_jit_stack_free                  PCRE2_SUFFIX(pcre2_jit_stack_free_)\n#define pcre2_maketables                      PCRE2_SUFFIX(pcre2_maketables_)\n#define pcre2_maketables_free                 PCRE2_SUFFIX(pcre2_maketables_free_)\n#define pcre2_match                           PCRE2_SUFFIX(pcre2_match_)\n#define pcre2_match_context_copy              PCRE2_SUFFIX(pcre2_match_context_copy_)\n#define pcre2_match_context_create            PCRE2_SUFFIX(pcre2_match_context_create_)\n#define pcre2_match_context_free              PCRE2_SUFFIX(pcre2_match_context_free_)\n#define pcre2_match_data_create               PCRE2_SUFFIX(pcre2_match_data_create_)\n#define pcre2_match_data_create_from_pattern  PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)\n#define pcre2_match_data_free                 PCRE2_SUFFIX(pcre2_match_data_free_)\n#define pcre2_next_match                      PCRE2_SUFFIX(pcre2_next_match_)\n#define pcre2_pattern_convert                 PCRE2_SUFFIX(pcre2_pattern_convert_)\n#define pcre2_pattern_info                    PCRE2_SUFFIX(pcre2_pattern_info_)\n#define pcre2_serialize_decode                PCRE2_SUFFIX(pcre2_serialize_decode_)\n#define pcre2_serialize_encode                PCRE2_SUFFIX(pcre2_serialize_encode_)\n#define pcre2_serialize_free                  PCRE2_SUFFIX(pcre2_serialize_free_)\n#define pcre2_serialize_get_number_of_codes   PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_)\n#define pcre2_set_bsr                         PCRE2_SUFFIX(pcre2_set_bsr_)\n#define pcre2_set_callout                     PCRE2_SUFFIX(pcre2_set_callout_)\n#define pcre2_set_character_tables            PCRE2_SUFFIX(pcre2_set_character_tables_)\n#define pcre2_set_compile_extra_options       PCRE2_SUFFIX(pcre2_set_compile_extra_options_)\n#define pcre2_set_compile_recursion_guard     PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)\n#define pcre2_set_depth_limit                 PCRE2_SUFFIX(pcre2_set_depth_limit_)\n#define pcre2_set_glob_escape                 PCRE2_SUFFIX(pcre2_set_glob_escape_)\n#define pcre2_set_glob_separator              PCRE2_SUFFIX(pcre2_set_glob_separator_)\n#define pcre2_set_heap_limit                  PCRE2_SUFFIX(pcre2_set_heap_limit_)\n#define pcre2_set_match_limit                 PCRE2_SUFFIX(pcre2_set_match_limit_)\n#define pcre2_set_max_varlookbehind           PCRE2_SUFFIX(pcre2_set_max_varlookbehind_)\n#define pcre2_set_max_pattern_length          PCRE2_SUFFIX(pcre2_set_max_pattern_length_)\n#define pcre2_set_max_pattern_compiled_length PCRE2_SUFFIX(pcre2_set_max_pattern_compiled_length_)\n#define pcre2_set_newline                     PCRE2_SUFFIX(pcre2_set_newline_)\n#define pcre2_set_parens_nest_limit           PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)\n#define pcre2_set_offset_limit                PCRE2_SUFFIX(pcre2_set_offset_limit_)\n#define pcre2_set_optimize                    PCRE2_SUFFIX(pcre2_set_optimize_)\n#define pcre2_set_substitute_callout          PCRE2_SUFFIX(pcre2_set_substitute_callout_)\n#define pcre2_set_substitute_case_callout     PCRE2_SUFFIX(pcre2_set_substitute_case_callout_)\n#define pcre2_substitute                      PCRE2_SUFFIX(pcre2_substitute_)\n#define pcre2_substring_copy_byname           PCRE2_SUFFIX(pcre2_substring_copy_byname_)\n#define pcre2_substring_copy_bynumber         PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)\n#define pcre2_substring_free                  PCRE2_SUFFIX(pcre2_substring_free_)\n#define pcre2_substring_get_byname            PCRE2_SUFFIX(pcre2_substring_get_byname_)\n#define pcre2_substring_get_bynumber          PCRE2_SUFFIX(pcre2_substring_get_bynumber_)\n#define pcre2_substring_length_byname         PCRE2_SUFFIX(pcre2_substring_length_byname_)\n#define pcre2_substring_length_bynumber       PCRE2_SUFFIX(pcre2_substring_length_bynumber_)\n#define pcre2_substring_list_get              PCRE2_SUFFIX(pcre2_substring_list_get_)\n#define pcre2_substring_list_free             PCRE2_SUFFIX(pcre2_substring_list_free_)\n#define pcre2_substring_nametable_scan        PCRE2_SUFFIX(pcre2_substring_nametable_scan_)\n#define pcre2_substring_number_from_name      PCRE2_SUFFIX(pcre2_substring_number_from_name_)\n\n/* Keep this old function name for backwards compatibility */\n#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)\n\n/* Keep this obsolete function for backwards compatibility: it is now a noop. */\n#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)\n\n/* Now generate all three sets of width-specific structures and function\nprototypes. */\n\n#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \\\nPCRE2_TYPES_LIST \\\nPCRE2_STRUCTURE_LIST \\\nPCRE2_GENERAL_INFO_FUNCTIONS \\\nPCRE2_GENERAL_CONTEXT_FUNCTIONS \\\nPCRE2_COMPILE_CONTEXT_FUNCTIONS \\\nPCRE2_CONVERT_CONTEXT_FUNCTIONS \\\nPCRE2_CONVERT_FUNCTIONS \\\nPCRE2_MATCH_CONTEXT_FUNCTIONS \\\nPCRE2_COMPILE_FUNCTIONS \\\nPCRE2_PATTERN_INFO_FUNCTIONS \\\nPCRE2_MATCH_FUNCTIONS \\\nPCRE2_SUBSTRING_FUNCTIONS \\\nPCRE2_SERIALIZE_FUNCTIONS \\\nPCRE2_SUBSTITUTE_FUNCTION \\\nPCRE2_JIT_FUNCTIONS \\\nPCRE2_OTHER_FUNCTIONS\n\n#define PCRE2_LOCAL_WIDTH 8\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n#define PCRE2_LOCAL_WIDTH 16\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n#define PCRE2_LOCAL_WIDTH 32\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n/* Undefine the list macros; they are no longer needed. */\n\n#undef PCRE2_TYPES_LIST\n#undef PCRE2_STRUCTURE_LIST\n#undef PCRE2_GENERAL_INFO_FUNCTIONS\n#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS\n#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS\n#undef PCRE2_CONVERT_CONTEXT_FUNCTIONS\n#undef PCRE2_MATCH_CONTEXT_FUNCTIONS\n#undef PCRE2_COMPILE_FUNCTIONS\n#undef PCRE2_PATTERN_INFO_FUNCTIONS\n#undef PCRE2_MATCH_FUNCTIONS\n#undef PCRE2_SUBSTRING_FUNCTIONS\n#undef PCRE2_SERIALIZE_FUNCTIONS\n#undef PCRE2_SUBSTITUTE_FUNCTION\n#undef PCRE2_JIT_FUNCTIONS\n#undef PCRE2_OTHER_FUNCTIONS\n#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n\n/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine\nPCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make\nPCRE2_SUFFIX a no-op. Otherwise, generate an error. */\n\n#undef PCRE2_SUFFIX\n#ifndef PCRE2_CODE_UNIT_WIDTH\n#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h.\n#error Use 8, 16, or 32; or 0 for a multi-width application.\n#else  /* PCRE2_CODE_UNIT_WIDTH is defined */\n#if PCRE2_CODE_UNIT_WIDTH == 8 || \\\n    PCRE2_CODE_UNIT_WIDTH == 16 || \\\n    PCRE2_CODE_UNIT_WIDTH == 32\n#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH)\n#elif PCRE2_CODE_UNIT_WIDTH == 0\n#undef PCRE2_JOIN\n#undef PCRE2_GLUE\n#define PCRE2_SUFFIX(a) a\n#else\n#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32.\n#endif\n#endif  /* PCRE2_CODE_UNIT_WIDTH is defined */\n\n#ifdef __cplusplus\n}  /* extern \"C\" */\n#endif\n\n#endif  /* PCRE2_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2.h.in",
    "content": "/*************************************************\n*       Perl-Compatible Regular Expressions      *\n*************************************************/\n\n/* This is the public header file for the PCRE library, second API, to be\n#included by applications that call PCRE2 functions.\n\n           Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_H_IDEMPOTENT_GUARD\n#define PCRE2_H_IDEMPOTENT_GUARD\n\n/* The current PCRE version information. */\n\n#define PCRE2_MAJOR           @PCRE2_MAJOR@\n#define PCRE2_MINOR           @PCRE2_MINOR@\n#define PCRE2_PRERELEASE      @PCRE2_PRERELEASE@\n#define PCRE2_DATE            @PCRE2_DATE@\n\n/* When an application links to a PCRE2 DLL in Windows, the symbols that are\nimported have to be identified as such. When building PCRE2, the appropriate\nexport setting is defined in pcre2_internal.h, which includes this file. So, we\ndon't change existing definitions of PCRE2_EXP_DECL.\n\nBy default, we use the standard \"extern\" declarations. */\n\n#ifndef PCRE2_EXP_DECL\n#  if defined(_WIN32) && !defined(PCRE2_STATIC)\n#    define PCRE2_EXP_DECL  extern __declspec(dllimport)\n#  elif defined __cplusplus\n#    define PCRE2_EXP_DECL  extern \"C\"\n#  else\n#    define PCRE2_EXP_DECL  extern\n#  endif\n#endif\n\n/* When compiling with the MSVC compiler, it is sometimes necessary to include\na \"calling convention\" before exported function names. For example:\n\n  void __cdecl function(....)\n\nmight be needed. In order to make this easy, all the exported functions have\nPCRE2_CALL_CONVENTION just before their names.\n\nPCRE2 normally uses the platform's standard calling convention, so this should\nnot be set unless you know you need it. */\n\n#ifndef PCRE2_CALL_CONVENTION\n#define PCRE2_CALL_CONVENTION\n#endif\n\n/* Have to include limits.h, stdlib.h, and inttypes.h to ensure that size_t and\nuint8_t, UCHAR_MAX, etc are defined. Some systems that do have inttypes.h do\nnot have stdint.h, which is why we use inttypes.h, which according to the C\nstandard is a superset of stdint.h. If inttypes.h is not available the build\nwill break and the relevant values must be provided by some other means. */\n\n#include <limits.h>\n#include <stdlib.h>\n#include <inttypes.h>\n\n/* Allow for C++ users compiling this directly. */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* The following option bits can be passed to pcre2_compile(), pcre2_match(),\nor pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it\nis passed. Put these bits at the most significant end of the options word so\nothers can be added next to them */\n\n#define PCRE2_ANCHORED            0x80000000u\n#define PCRE2_NO_UTF_CHECK        0x40000000u\n#define PCRE2_ENDANCHORED         0x20000000u\n\n/* The following option bits can be passed only to pcre2_compile(). However,\nthey may affect compilation, JIT compilation, and/or interpretive execution.\nThe following tags indicate which:\n\nC   alters what is compiled by pcre2_compile()\nJ   alters what is compiled by pcre2_jit_compile()\nM   is inspected during pcre2_match() execution\nD   is inspected during pcre2_dfa_match() execution\n*/\n\n#define PCRE2_ALLOW_EMPTY_CLASS   0x00000001u  /* C       */\n#define PCRE2_ALT_BSUX            0x00000002u  /* C       */\n#define PCRE2_AUTO_CALLOUT        0x00000004u  /* C       */\n#define PCRE2_CASELESS            0x00000008u  /* C       */\n#define PCRE2_DOLLAR_ENDONLY      0x00000010u  /*   J M D */\n#define PCRE2_DOTALL              0x00000020u  /* C       */\n#define PCRE2_DUPNAMES            0x00000040u  /* C       */\n#define PCRE2_EXTENDED            0x00000080u  /* C       */\n#define PCRE2_FIRSTLINE           0x00000100u  /*   J M D */\n#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u  /* C J M   */\n#define PCRE2_MULTILINE           0x00000400u  /* C       */\n#define PCRE2_NEVER_UCP           0x00000800u  /* C       */\n#define PCRE2_NEVER_UTF           0x00001000u  /* C       */\n#define PCRE2_NO_AUTO_CAPTURE     0x00002000u  /* C       */\n#define PCRE2_NO_AUTO_POSSESS     0x00004000u  /* C       */\n#define PCRE2_NO_DOTSTAR_ANCHOR   0x00008000u  /* C       */\n#define PCRE2_NO_START_OPTIMIZE   0x00010000u  /*   J M D */\n#define PCRE2_UCP                 0x00020000u  /* C J M D */\n#define PCRE2_UNGREEDY            0x00040000u  /* C       */\n#define PCRE2_UTF                 0x00080000u  /* C J M D */\n#define PCRE2_NEVER_BACKSLASH_C   0x00100000u  /* C       */\n#define PCRE2_ALT_CIRCUMFLEX      0x00200000u  /*   J M D */\n#define PCRE2_ALT_VERBNAMES       0x00400000u  /* C       */\n#define PCRE2_USE_OFFSET_LIMIT    0x00800000u  /*   J M D */\n#define PCRE2_EXTENDED_MORE       0x01000000u  /* C       */\n#define PCRE2_LITERAL             0x02000000u  /* C       */\n#define PCRE2_MATCH_INVALID_UTF   0x04000000u  /*   J M D */\n#define PCRE2_ALT_EXTENDED_CLASS  0x08000000u  /* C       */\n\n/* An additional compile options word is available in the compile context. */\n\n#define PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  0x00000001u  /* C */\n#define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    0x00000002u  /* C */\n#define PCRE2_EXTRA_MATCH_WORD               0x00000004u  /* C */\n#define PCRE2_EXTRA_MATCH_LINE               0x00000008u  /* C */\n#define PCRE2_EXTRA_ESCAPED_CR_IS_LF         0x00000010u  /* C */\n#define PCRE2_EXTRA_ALT_BSUX                 0x00000020u  /* C */\n#define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK     0x00000040u  /* C */\n#define PCRE2_EXTRA_CASELESS_RESTRICT        0x00000080u  /* C */\n#define PCRE2_EXTRA_ASCII_BSD                0x00000100u  /* C */\n#define PCRE2_EXTRA_ASCII_BSS                0x00000200u  /* C */\n#define PCRE2_EXTRA_ASCII_BSW                0x00000400u  /* C */\n#define PCRE2_EXTRA_ASCII_POSIX              0x00000800u  /* C */\n#define PCRE2_EXTRA_ASCII_DIGIT              0x00001000u  /* C */\n#define PCRE2_EXTRA_PYTHON_OCTAL             0x00002000u  /* C */\n#define PCRE2_EXTRA_NO_BS0                   0x00004000u  /* C */\n#define PCRE2_EXTRA_NEVER_CALLOUT            0x00008000u  /* C */\n#define PCRE2_EXTRA_TURKISH_CASING           0x00010000u  /* C */\n\n/* These are for pcre2_jit_compile(). */\n\n#define PCRE2_JIT_COMPLETE        0x00000001u  /* For full matching */\n#define PCRE2_JIT_PARTIAL_SOFT    0x00000002u\n#define PCRE2_JIT_PARTIAL_HARD    0x00000004u\n#define PCRE2_JIT_INVALID_UTF     0x00000100u\n#define PCRE2_JIT_TEST_ALLOC      0x00000200u\n\n/* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and\npcre2_substitute(). Some are allowed only for one of the functions, and in\nthese cases it is noted below. Note that PCRE2_ANCHORED, PCRE2_ENDANCHORED and\nPCRE2_NO_UTF_CHECK can also be passed to these functions (though\npcre2_jit_match() ignores the latter since it bypasses all sanity checks). */\n\n#define PCRE2_NOTBOL                      0x00000001u\n#define PCRE2_NOTEOL                      0x00000002u\n#define PCRE2_NOTEMPTY                    0x00000004u  /* ) These two must be kept */\n#define PCRE2_NOTEMPTY_ATSTART            0x00000008u  /* ) adjacent to each other. */\n#define PCRE2_PARTIAL_SOFT                0x00000010u\n#define PCRE2_PARTIAL_HARD                0x00000020u\n#define PCRE2_DFA_RESTART                 0x00000040u  /* pcre2_dfa_match() only */\n#define PCRE2_DFA_SHORTEST                0x00000080u  /* pcre2_dfa_match() only */\n#define PCRE2_SUBSTITUTE_GLOBAL           0x00000100u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_EXTENDED         0x00000200u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_UNSET_EMPTY      0x00000400u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET    0x00000800u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  0x00001000u  /* pcre2_substitute() only */\n#define PCRE2_NO_JIT                      0x00002000u  /* not for pcre2_dfa_match() */\n#define PCRE2_COPY_MATCHED_SUBJECT        0x00004000u\n#define PCRE2_SUBSTITUTE_LITERAL          0x00008000u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_MATCHED          0x00010000u  /* pcre2_substitute() only */\n#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u  /* pcre2_substitute() only */\n#define PCRE2_DISABLE_RECURSELOOP_CHECK   0x00040000u  /* not for pcre2_dfa_match() or pcre2_jit_match() */\n\n/* Options for pcre2_pattern_convert(). */\n\n#define PCRE2_CONVERT_UTF                    0x00000001u\n#define PCRE2_CONVERT_NO_UTF_CHECK           0x00000002u\n#define PCRE2_CONVERT_POSIX_BASIC            0x00000004u\n#define PCRE2_CONVERT_POSIX_EXTENDED         0x00000008u\n#define PCRE2_CONVERT_GLOB                   0x00000010u\n#define PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR 0x00000030u\n#define PCRE2_CONVERT_GLOB_NO_STARSTAR       0x00000050u\n\n/* Newline and \\R settings, for use in compile contexts. The newline values\nmust be kept in step with values set in config.h and both sets must all be\ngreater than zero. */\n\n#define PCRE2_NEWLINE_CR          1\n#define PCRE2_NEWLINE_LF          2\n#define PCRE2_NEWLINE_CRLF        3\n#define PCRE2_NEWLINE_ANY         4\n#define PCRE2_NEWLINE_ANYCRLF     5\n#define PCRE2_NEWLINE_NUL         6\n\n#define PCRE2_BSR_UNICODE         1\n#define PCRE2_BSR_ANYCRLF         2\n\n/* Error codes for pcre2_compile(). Some of these are also used by\npcre2_pattern_convert(). */\n\n#define PCRE2_ERROR_END_BACKSLASH                  101\n#define PCRE2_ERROR_END_BACKSLASH_C                102\n#define PCRE2_ERROR_UNKNOWN_ESCAPE                 103\n#define PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER        104\n#define PCRE2_ERROR_QUANTIFIER_TOO_BIG             105\n#define PCRE2_ERROR_MISSING_SQUARE_BRACKET         106\n#define PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS        107\n#define PCRE2_ERROR_CLASS_RANGE_ORDER              108\n#define PCRE2_ERROR_QUANTIFIER_INVALID             109\n#define PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT     110\n#define PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY     111\n#define PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS       112\n#define PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING     113\n#define PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS    114\n#define PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE       115\n#define PCRE2_ERROR_NULL_PATTERN                   116\n#define PCRE2_ERROR_BAD_OPTIONS                    117\n#define PCRE2_ERROR_MISSING_COMMENT_CLOSING        118\n#define PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP      119\n#define PCRE2_ERROR_PATTERN_TOO_LARGE              120\n#define PCRE2_ERROR_HEAP_FAILED                    121\n#define PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS  122\n#define PCRE2_ERROR_INTERNAL_CODE_OVERFLOW         123\n#define PCRE2_ERROR_MISSING_CONDITION_CLOSING      124\n#define PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH    125\n#define PCRE2_ERROR_ZERO_RELATIVE_REFERENCE        126\n#define PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES    127\n#define PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED   128\n#define PCRE2_ERROR_BAD_RELATIVE_REFERENCE         129\n#define PCRE2_ERROR_UNKNOWN_POSIX_CLASS            130\n#define PCRE2_ERROR_INTERNAL_STUDY_ERROR           131\n#define PCRE2_ERROR_UNICODE_NOT_SUPPORTED          132\n#define PCRE2_ERROR_PARENTHESES_STACK_CHECK        133\n#define PCRE2_ERROR_CODE_POINT_TOO_BIG             134\n#define PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED     135\n#define PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C 136\n#define PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE    137\n#define PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG         138\n#define PCRE2_ERROR_MISSING_CALLOUT_CLOSING        139\n#define PCRE2_ERROR_ESCAPE_INVALID_IN_VERB         140\n#define PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P     141\n#define PCRE2_ERROR_MISSING_NAME_TERMINATOR        142\n#define PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME      143\n#define PCRE2_ERROR_INVALID_SUBPATTERN_NAME        144\n#define PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE 145\n#define PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY     146\n#define PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY       147\n#define PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG       148\n#define PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS     149\n#define PCRE2_ERROR_CLASS_INVALID_RANGE            150\n#define PCRE2_ERROR_OCTAL_BYTE_TOO_BIG             151\n#define PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE     152\n#define PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN    153\n#define PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES       154\n#define PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE      155\n#define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE       156\n#define PCRE2_ERROR_BACKSLASH_G_SYNTAX             157\n#define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158\n/* Error 159 is obsolete and should now never occur */\n#define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED      159\n#define PCRE2_ERROR_VERB_UNKNOWN                   160\n#define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG      161\n#define PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED       162\n#define PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW       163\n#define PCRE2_ERROR_INVALID_OCTAL                  164\n#define PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH      165\n#define PCRE2_ERROR_MARK_MISSING_ARGUMENT          166\n#define PCRE2_ERROR_INVALID_HEXADECIMAL            167\n#define PCRE2_ERROR_BACKSLASH_C_SYNTAX             168\n#define PCRE2_ERROR_BACKSLASH_K_SYNTAX             169\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS  170\n#define PCRE2_ERROR_BACKSLASH_N_IN_CLASS           171\n#define PCRE2_ERROR_CALLOUT_STRING_TOO_LONG        172\n#define PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT  173\n#define PCRE2_ERROR_UTF_IS_DISABLED                174\n#define PCRE2_ERROR_UCP_IS_DISABLED                175\n#define PCRE2_ERROR_VERB_NAME_TOO_LONG             176\n#define PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG 177\n#define PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS    178\n#define PCRE2_ERROR_VERSION_CONDITION_SYNTAX       179\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS 180\n#define PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER    181\n#define PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER   182\n#define PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED    183\n#define PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP      184\n#define PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED   185\n#define PCRE2_ERROR_PATTERN_TOO_COMPLICATED        186\n#define PCRE2_ERROR_LOOKBEHIND_TOO_LONG            187\n#define PCRE2_ERROR_PATTERN_STRING_TOO_LONG        188\n#define PCRE2_ERROR_INTERNAL_BAD_CODE              189\n#define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP      190\n#define PCRE2_ERROR_NO_SURROGATES_IN_UTF16         191\n#define PCRE2_ERROR_BAD_LITERAL_OPTIONS            192\n#define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE      193\n#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS      194\n#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN        195\n#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE       196\n#define PCRE2_ERROR_TOO_MANY_CAPTURES              197\n#define PCRE2_ERROR_MISSING_OCTAL_DIGIT            198\n#define PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND      199\n#define PCRE2_ERROR_MAX_VAR_LOOKBEHIND_EXCEEDED    200\n#define PCRE2_ERROR_PATTERN_COMPILED_SIZE_TOO_BIG  201\n#define PCRE2_ERROR_OVERSIZE_PYTHON_OCTAL          202\n#define PCRE2_ERROR_CALLOUT_CALLER_DISABLED        203\n#define PCRE2_ERROR_EXTRA_CASING_REQUIRES_UNICODE  204\n#define PCRE2_ERROR_TURKISH_CASING_REQUIRES_UTF    205\n#define PCRE2_ERROR_EXTRA_CASING_INCOMPATIBLE      206\n#define PCRE2_ERROR_ECLASS_NEST_TOO_DEEP           207\n#define PCRE2_ERROR_ECLASS_INVALID_OPERATOR        208\n#define PCRE2_ERROR_ECLASS_UNEXPECTED_OPERATOR     209\n#define PCRE2_ERROR_ECLASS_EXPECTED_OPERAND        210\n#define PCRE2_ERROR_ECLASS_MIXED_OPERATORS         211\n#define PCRE2_ERROR_ECLASS_HINT_SQUARE_BRACKET     212\n#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_EXPR    213\n#define PCRE2_ERROR_PERL_ECLASS_EMPTY_EXPR         214\n#define PCRE2_ERROR_PERL_ECLASS_MISSING_CLOSE      215\n#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_CHAR    216\n#define PCRE2_ERROR_EXPECTED_CAPTURE_GROUP         217\n#define PCRE2_ERROR_MISSING_OPENING_PARENTHESIS    218\n#define PCRE2_ERROR_MISSING_NUMBER_TERMINATOR      219\n#define PCRE2_ERROR_NULL_ERROROFFSET               220\n\n/* \"Expected\" matching error codes: no match and partial match. */\n\n#define PCRE2_ERROR_NOMATCH          (-1)\n#define PCRE2_ERROR_PARTIAL          (-2)\n\n/* Error codes for UTF-8 validity checks */\n\n#define PCRE2_ERROR_UTF8_ERR1        (-3)\n#define PCRE2_ERROR_UTF8_ERR2        (-4)\n#define PCRE2_ERROR_UTF8_ERR3        (-5)\n#define PCRE2_ERROR_UTF8_ERR4        (-6)\n#define PCRE2_ERROR_UTF8_ERR5        (-7)\n#define PCRE2_ERROR_UTF8_ERR6        (-8)\n#define PCRE2_ERROR_UTF8_ERR7        (-9)\n#define PCRE2_ERROR_UTF8_ERR8       (-10)\n#define PCRE2_ERROR_UTF8_ERR9       (-11)\n#define PCRE2_ERROR_UTF8_ERR10      (-12)\n#define PCRE2_ERROR_UTF8_ERR11      (-13)\n#define PCRE2_ERROR_UTF8_ERR12      (-14)\n#define PCRE2_ERROR_UTF8_ERR13      (-15)\n#define PCRE2_ERROR_UTF8_ERR14      (-16)\n#define PCRE2_ERROR_UTF8_ERR15      (-17)\n#define PCRE2_ERROR_UTF8_ERR16      (-18)\n#define PCRE2_ERROR_UTF8_ERR17      (-19)\n#define PCRE2_ERROR_UTF8_ERR18      (-20)\n#define PCRE2_ERROR_UTF8_ERR19      (-21)\n#define PCRE2_ERROR_UTF8_ERR20      (-22)\n#define PCRE2_ERROR_UTF8_ERR21      (-23)\n\n/* Error codes for UTF-16 validity checks */\n\n#define PCRE2_ERROR_UTF16_ERR1      (-24)\n#define PCRE2_ERROR_UTF16_ERR2      (-25)\n#define PCRE2_ERROR_UTF16_ERR3      (-26)\n\n/* Error codes for UTF-32 validity checks */\n\n#define PCRE2_ERROR_UTF32_ERR1      (-27)\n#define PCRE2_ERROR_UTF32_ERR2      (-28)\n\n/* Miscellaneous error codes for pcre2[_dfa]_match(), substring extraction\nfunctions, context functions, and serializing functions. They are in numerical\norder. Originally they were in alphabetical order too, but now that PCRE2 is\nreleased, the numbers must not be changed. */\n\n#define PCRE2_ERROR_BADDATA           (-29)\n#define PCRE2_ERROR_MIXEDTABLES       (-30)  /* Name was changed */\n#define PCRE2_ERROR_BADMAGIC          (-31)\n#define PCRE2_ERROR_BADMODE           (-32)\n#define PCRE2_ERROR_BADOFFSET         (-33)\n#define PCRE2_ERROR_BADOPTION         (-34)\n#define PCRE2_ERROR_BADREPLACEMENT    (-35)\n#define PCRE2_ERROR_BADUTFOFFSET      (-36)\n#define PCRE2_ERROR_CALLOUT           (-37)  /* Never used by PCRE2 itself */\n#define PCRE2_ERROR_DFA_BADRESTART    (-38)\n#define PCRE2_ERROR_DFA_RECURSE       (-39)\n#define PCRE2_ERROR_DFA_UCOND         (-40)\n#define PCRE2_ERROR_DFA_UFUNC         (-41)\n#define PCRE2_ERROR_DFA_UITEM         (-42)\n#define PCRE2_ERROR_DFA_WSSIZE        (-43)\n#define PCRE2_ERROR_INTERNAL          (-44)\n#define PCRE2_ERROR_JIT_BADOPTION     (-45)\n#define PCRE2_ERROR_JIT_STACKLIMIT    (-46)\n#define PCRE2_ERROR_MATCHLIMIT        (-47)\n#define PCRE2_ERROR_NOMEMORY          (-48)\n#define PCRE2_ERROR_NOSUBSTRING       (-49)\n#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)\n#define PCRE2_ERROR_NULL              (-51)\n#define PCRE2_ERROR_RECURSELOOP       (-52)\n#define PCRE2_ERROR_DEPTHLIMIT        (-53)\n#define PCRE2_ERROR_RECURSIONLIMIT    (-53)  /* Obsolete synonym */\n#define PCRE2_ERROR_UNAVAILABLE       (-54)\n#define PCRE2_ERROR_UNSET             (-55)\n#define PCRE2_ERROR_BADOFFSETLIMIT    (-56)\n#define PCRE2_ERROR_BADREPESCAPE      (-57)\n#define PCRE2_ERROR_REPMISSINGBRACE   (-58)\n#define PCRE2_ERROR_BADSUBSTITUTION   (-59)\n#define PCRE2_ERROR_BADSUBSPATTERN    (-60)\n#define PCRE2_ERROR_TOOMANYREPLACE    (-61)\n#define PCRE2_ERROR_BADSERIALIZEDDATA (-62)\n#define PCRE2_ERROR_HEAPLIMIT         (-63)\n#define PCRE2_ERROR_CONVERT_SYNTAX    (-64)\n#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)\n#define PCRE2_ERROR_DFA_UINVALID_UTF  (-66)\n#define PCRE2_ERROR_INVALIDOFFSET     (-67)\n#define PCRE2_ERROR_JIT_UNSUPPORTED   (-68)\n#define PCRE2_ERROR_REPLACECASE       (-69)\n#define PCRE2_ERROR_TOOLARGEREPLACE   (-70)\n#define PCRE2_ERROR_DIFFSUBSPATTERN   (-71)\n#define PCRE2_ERROR_DIFFSUBSSUBJECT   (-72)\n#define PCRE2_ERROR_DIFFSUBSOFFSET    (-73)\n#define PCRE2_ERROR_DIFFSUBSOPTIONS   (-74)\n#define PCRE2_ERROR_BAD_BACKSLASH_K   (-75)\n\n\n/* Request types for pcre2_pattern_info() */\n\n#define PCRE2_INFO_ALLOPTIONS            0\n#define PCRE2_INFO_ARGOPTIONS            1\n#define PCRE2_INFO_BACKREFMAX            2\n#define PCRE2_INFO_BSR                   3\n#define PCRE2_INFO_CAPTURECOUNT          4\n#define PCRE2_INFO_FIRSTCODEUNIT         5\n#define PCRE2_INFO_FIRSTCODETYPE         6\n#define PCRE2_INFO_FIRSTBITMAP           7\n#define PCRE2_INFO_HASCRORLF             8\n#define PCRE2_INFO_JCHANGED              9\n#define PCRE2_INFO_JITSIZE              10\n#define PCRE2_INFO_LASTCODEUNIT         11\n#define PCRE2_INFO_LASTCODETYPE         12\n#define PCRE2_INFO_MATCHEMPTY           13\n#define PCRE2_INFO_MATCHLIMIT           14\n#define PCRE2_INFO_MAXLOOKBEHIND        15\n#define PCRE2_INFO_MINLENGTH            16\n#define PCRE2_INFO_NAMECOUNT            17\n#define PCRE2_INFO_NAMEENTRYSIZE        18\n#define PCRE2_INFO_NAMETABLE            19\n#define PCRE2_INFO_NEWLINE              20\n#define PCRE2_INFO_DEPTHLIMIT           21\n#define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */\n#define PCRE2_INFO_SIZE                 22\n#define PCRE2_INFO_HASBACKSLASHC        23\n#define PCRE2_INFO_FRAMESIZE            24\n#define PCRE2_INFO_HEAPLIMIT            25\n#define PCRE2_INFO_EXTRAOPTIONS         26\n\n/* Request types for pcre2_config(). */\n\n#define PCRE2_CONFIG_BSR                     0\n#define PCRE2_CONFIG_JIT                     1\n#define PCRE2_CONFIG_JITTARGET               2\n#define PCRE2_CONFIG_LINKSIZE                3\n#define PCRE2_CONFIG_MATCHLIMIT              4\n#define PCRE2_CONFIG_NEWLINE                 5\n#define PCRE2_CONFIG_PARENSLIMIT             6\n#define PCRE2_CONFIG_DEPTHLIMIT              7\n#define PCRE2_CONFIG_RECURSIONLIMIT          7  /* Obsolete synonym */\n#define PCRE2_CONFIG_STACKRECURSE            8  /* Obsolete */\n#define PCRE2_CONFIG_UNICODE                 9\n#define PCRE2_CONFIG_UNICODE_VERSION        10\n#define PCRE2_CONFIG_VERSION                11\n#define PCRE2_CONFIG_HEAPLIMIT              12\n#define PCRE2_CONFIG_NEVER_BACKSLASH_C      13\n#define PCRE2_CONFIG_COMPILED_WIDTHS        14\n#define PCRE2_CONFIG_TABLES_LENGTH          15\n#define PCRE2_CONFIG_EFFECTIVE_LINKSIZE     16\n\n/* Optimization directives for pcre2_set_optimize().\nFor binary compatibility, only add to this list; do not renumber. */\n\n#define PCRE2_OPTIMIZATION_NONE    0\n#define PCRE2_OPTIMIZATION_FULL    1\n\n#define PCRE2_AUTO_POSSESS         64\n#define PCRE2_AUTO_POSSESS_OFF     65\n#define PCRE2_DOTSTAR_ANCHOR       66\n#define PCRE2_DOTSTAR_ANCHOR_OFF   67\n#define PCRE2_START_OPTIMIZE       68\n#define PCRE2_START_OPTIMIZE_OFF   69\n\n/* Types used in pcre2_set_substitute_case_callout().\n\nPCRE2_SUBSTITUTE_CASE_LOWER and PCRE2_SUBSTITUTE_CASE_UPPER are passed to the\ncallout to indicate that the case of the entire callout input should be\ncase-transformed. PCRE2_SUBSTITUTE_CASE_TITLE_FIRST is passed to indicate that\nonly the first character or glyph should be transformed to Unicode titlecase,\nand the rest to lowercase. */\n\n#define PCRE2_SUBSTITUTE_CASE_LOWER        1\n#define PCRE2_SUBSTITUTE_CASE_UPPER        2\n#define PCRE2_SUBSTITUTE_CASE_TITLE_FIRST  3\n\n/* Types for code units in patterns and subject strings. */\n\ntypedef uint8_t  PCRE2_UCHAR8;\ntypedef uint16_t PCRE2_UCHAR16;\ntypedef uint32_t PCRE2_UCHAR32;\n\ntypedef const PCRE2_UCHAR8  *PCRE2_SPTR8;\ntypedef const PCRE2_UCHAR16 *PCRE2_SPTR16;\ntypedef const PCRE2_UCHAR32 *PCRE2_SPTR32;\n\n/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2,\nincluding pattern offsets for errors and subject offsets after a match. We\ndefine special values to indicate zero-terminated strings and unset offsets in\nthe offset vector (ovector). */\n\n#define PCRE2_SIZE            size_t\n#define PCRE2_SIZE_MAX        SIZE_MAX\n#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)\n#define PCRE2_UNSET           (~(PCRE2_SIZE)0)\n\n/* Generic types for opaque structures and JIT callback functions. These\ndeclarations are defined in a macro that is expanded for each width later. */\n\n#define PCRE2_TYPES_LIST \\\nstruct pcre2_real_general_context; \\\ntypedef struct pcre2_real_general_context pcre2_general_context; \\\n\\\nstruct pcre2_real_compile_context; \\\ntypedef struct pcre2_real_compile_context pcre2_compile_context; \\\n\\\nstruct pcre2_real_match_context; \\\ntypedef struct pcre2_real_match_context pcre2_match_context; \\\n\\\nstruct pcre2_real_convert_context; \\\ntypedef struct pcre2_real_convert_context pcre2_convert_context; \\\n\\\nstruct pcre2_real_code; \\\ntypedef struct pcre2_real_code pcre2_code; \\\n\\\nstruct pcre2_real_match_data; \\\ntypedef struct pcre2_real_match_data pcre2_match_data; \\\n\\\nstruct pcre2_real_jit_stack; \\\ntypedef struct pcre2_real_jit_stack pcre2_jit_stack; \\\n\\\ntypedef pcre2_jit_stack *(*pcre2_jit_callback)(void *);\n\n\n/* The structures for passing out data via callout functions. We use structures\nso that new fields can be added on the end in future versions, without changing\nthe API of the function, thereby allowing old clients to work without\nmodification. Define the generic versions in a macro; the width-specific\nversions are generated from this macro below. */\n\n/* Flags for the callout_flags field. These are cleared after a callout. */\n\n#define PCRE2_CALLOUT_STARTMATCH    0x00000001u  /* Set for each bumpalong */\n#define PCRE2_CALLOUT_BACKTRACK     0x00000002u  /* Set after a backtrack */\n\n#define PCRE2_STRUCTURE_LIST \\\ntypedef struct pcre2_callout_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  uint32_t      callout_number;    /* Number compiled into pattern */ \\\n  uint32_t      capture_top;       /* Max current capture */ \\\n  uint32_t      capture_last;      /* Most recently closed capture */ \\\n  PCRE2_SIZE   *offset_vector;     /* The offset vector */ \\\n  PCRE2_SPTR    mark;              /* Pointer to current mark or NULL */ \\\n  PCRE2_SPTR    subject;           /* The subject being matched */ \\\n  PCRE2_SIZE    subject_length;    /* The length of the subject */ \\\n  PCRE2_SIZE    start_match;       /* Offset to start of this match attempt */ \\\n  PCRE2_SIZE    current_position;  /* Where we currently are in the subject */ \\\n  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \\\n  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \\\n  /* ------------------- Added for Version 1 -------------------------- */ \\\n  PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \\\n  PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \\\n  PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \\\n  /* ------------------- Added for Version 2 -------------------------- */ \\\n  uint32_t      callout_flags;     /* See above for list */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_callout_block; \\\n\\\ntypedef struct pcre2_callout_enumerate_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \\\n  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \\\n  uint32_t      callout_number;    /* Number compiled into pattern */ \\\n  PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \\\n  PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \\\n  PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_callout_enumerate_block; \\\n\\\ntypedef struct pcre2_substitute_callout_block { \\\n  uint32_t      version;           /* Identifies version of block */ \\\n  /* ------------------------ Version 0 ------------------------------- */ \\\n  PCRE2_SPTR    input;             /* Pointer to input subject string */ \\\n  PCRE2_SPTR    output;            /* Pointer to output buffer */ \\\n  PCRE2_SIZE    output_offsets[2]; /* Changed portion of the output */ \\\n  PCRE2_SIZE   *ovector;           /* Pointer to current ovector */ \\\n  uint32_t      oveccount;         /* Count of pairs set in ovector */ \\\n  uint32_t      subscount;         /* Substitution number */ \\\n  /* ------------------------------------------------------------------ */ \\\n} pcre2_substitute_callout_block;\n\n\n/* List the generic forms of all other functions in macros, which will be\nexpanded for each width below. Start with functions that give general\ninformation. */\n\n#define PCRE2_GENERAL_INFO_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);\n\n\n/* Functions for manipulating contexts. */\n\n#define PCRE2_GENERAL_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_copy(pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_create(void *(*)(size_t, void *), \\\n    void (*)(void *, void *), void *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_general_context_free(pcre2_general_context *);\n\n#define PCRE2_COMPILE_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_copy(pcre2_compile_context *); \\\nPCRE2_EXP_DECL pcre2_compile_context *PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_create(pcre2_general_context *);\\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_compile_context_free(pcre2_compile_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_bsr(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_character_tables(pcre2_compile_context *, const uint8_t *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_pattern_compiled_length(pcre2_compile_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_max_varlookbehind(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_newline(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_compile_recursion_guard(pcre2_compile_context *, \\\n    int (*)(uint32_t, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_optimize(pcre2_compile_context *, uint32_t);\n\n#define PCRE2_MATCH_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_copy(pcre2_match_context *); \\\nPCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_create(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_match_context_free(pcre2_match_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_callout(pcre2_match_context *, \\\n    int (*)(pcre2_callout_block *, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_substitute_callout(pcre2_match_context *, \\\n    int (*)(pcre2_substitute_callout_block *, void *), void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_substitute_case_callout(pcre2_match_context *, \\\n    PCRE2_SIZE (*)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE, int, \\\n                   void *), \\\n    void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_match_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_recursion_memory_management(pcre2_match_context *, \\\n    void *(*)(size_t, void *), void (*)(void *, void *), void *);\n\n#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_copy(pcre2_convert_context *); \\\nPCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_create(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_convert_context_free(pcre2_convert_context *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_glob_escape(pcre2_convert_context *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_set_glob_separator(pcre2_convert_context *, uint32_t);\n\n\n/* Functions concerned with compiling a pattern to PCRE internal code. */\n\n#define PCRE2_COMPILE_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \\\n    pcre2_compile_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_code_free(pcre2_code *); \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_code_copy(const pcre2_code *); \\\nPCRE2_EXP_DECL pcre2_code *PCRE2_CALL_CONVENTION \\\n  pcre2_code_copy_with_tables(const pcre2_code *);\n\n\n/* Functions that give information about a compiled pattern. */\n\n#define PCRE2_PATTERN_INFO_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_callout_enumerate(const pcre2_code *, \\\n    int (*)(pcre2_callout_enumerate_block *, void *), void *);\n\n\n/* Functions for running a match and inspecting the result. */\n\n#define PCRE2_MATCH_FUNCTIONS \\\nPCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_create(uint32_t, pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_create_from_pattern(const pcre2_code *, \\\n    pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_match_data_free(pcre2_match_data *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *); \\\nPCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \\\n  pcre2_get_mark(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_match_data_size(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_match_data_heapframes_size(pcre2_match_data *); \\\nPCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \\\n  pcre2_get_ovector_count(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \\\n  pcre2_get_ovector_pointer(pcre2_match_data *); \\\nPCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \\\n  pcre2_get_startchar(pcre2_match_data *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_next_match(pcre2_match_data *, PCRE2_SIZE *, uint32_t *);\n\n\n/* Convenience functions for handling matched substrings. */\n\n#define PCRE2_SUBSTRING_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_substring_free(PCRE2_UCHAR *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \\\n    PCRE2_SPTR *); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_substring_list_free(PCRE2_UCHAR **); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **);\n\n\n/* Functions for serializing / deserializing compiled patterns. */\n\n#define PCRE2_SERIALIZE_FUNCTIONS \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \\\n    PCRE2_SIZE *, pcre2_general_context *); \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \\\n    pcre2_general_context *); \\\nPCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_get_number_of_codes(const uint8_t *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_serialize_free(uint8_t *);\n\n\n/* Convenience function for match + substitute. */\n\n#define PCRE2_SUBSTITUTE_FUNCTION \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \\\n    PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);\n\n\n/* Functions for converting pattern source strings. */\n\n#define PCRE2_CONVERT_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_pattern_convert(PCRE2_SPTR, PCRE2_SIZE, uint32_t, PCRE2_UCHAR **, \\\n    PCRE2_SIZE *, pcre2_convert_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_converted_pattern_free(PCRE2_UCHAR *);\n\n\n/* Functions for JIT processing */\n\n#define PCRE2_JIT_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_jit_compile(pcre2_code *, uint32_t); \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \\\n    uint32_t, pcre2_match_data *, pcre2_match_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_free_unused_memory(pcre2_general_context *); \\\nPCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_create(size_t, size_t, pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_jit_stack_free(pcre2_jit_stack *);\n\n\n/* Other miscellaneous functions. */\n\n#define PCRE2_OTHER_FUNCTIONS \\\nPCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \\\n  pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \\\nPCRE2_EXP_DECL const uint8_t *PCRE2_CALL_CONVENTION \\\n  pcre2_maketables(pcre2_general_context *); \\\nPCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \\\n  pcre2_maketables_free(pcre2_general_context *, const uint8_t *);\n\n/* Define macros that generate width-specific names from generic versions. The\nthree-level macro scheme is necessary to get the macros expanded when we want\nthem to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for\ngenerating three versions of everything below. After that, PCRE2_SUFFIX will be\nre-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as\npcre2_compile are called by application code. */\n\n#define PCRE2_JOIN(a,b) a ## b\n#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b)\n#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH)\n\n\n/* Data types */\n\n#define PCRE2_UCHAR                 PCRE2_SUFFIX(PCRE2_UCHAR)\n#define PCRE2_SPTR                  PCRE2_SUFFIX(PCRE2_SPTR)\n\n#define pcre2_code                  PCRE2_SUFFIX(pcre2_code_)\n#define pcre2_jit_callback          PCRE2_SUFFIX(pcre2_jit_callback_)\n#define pcre2_jit_stack             PCRE2_SUFFIX(pcre2_jit_stack_)\n\n#define pcre2_real_code             PCRE2_SUFFIX(pcre2_real_code_)\n#define pcre2_real_general_context  PCRE2_SUFFIX(pcre2_real_general_context_)\n#define pcre2_real_compile_context  PCRE2_SUFFIX(pcre2_real_compile_context_)\n#define pcre2_real_convert_context  PCRE2_SUFFIX(pcre2_real_convert_context_)\n#define pcre2_real_match_context    PCRE2_SUFFIX(pcre2_real_match_context_)\n#define pcre2_real_jit_stack        PCRE2_SUFFIX(pcre2_real_jit_stack_)\n#define pcre2_real_match_data       PCRE2_SUFFIX(pcre2_real_match_data_)\n\n\n/* Data blocks */\n\n#define pcre2_callout_block            PCRE2_SUFFIX(pcre2_callout_block_)\n#define pcre2_callout_enumerate_block  PCRE2_SUFFIX(pcre2_callout_enumerate_block_)\n#define pcre2_substitute_callout_block PCRE2_SUFFIX(pcre2_substitute_callout_block_)\n#define pcre2_general_context          PCRE2_SUFFIX(pcre2_general_context_)\n#define pcre2_compile_context          PCRE2_SUFFIX(pcre2_compile_context_)\n#define pcre2_convert_context          PCRE2_SUFFIX(pcre2_convert_context_)\n#define pcre2_match_context            PCRE2_SUFFIX(pcre2_match_context_)\n#define pcre2_match_data               PCRE2_SUFFIX(pcre2_match_data_)\n\n\n/* Functions: the complete list in alphabetical order */\n\n#define pcre2_callout_enumerate               PCRE2_SUFFIX(pcre2_callout_enumerate_)\n#define pcre2_code_copy                       PCRE2_SUFFIX(pcre2_code_copy_)\n#define pcre2_code_copy_with_tables           PCRE2_SUFFIX(pcre2_code_copy_with_tables_)\n#define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)\n#define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)\n#define pcre2_compile_context_copy            PCRE2_SUFFIX(pcre2_compile_context_copy_)\n#define pcre2_compile_context_create          PCRE2_SUFFIX(pcre2_compile_context_create_)\n#define pcre2_compile_context_free            PCRE2_SUFFIX(pcre2_compile_context_free_)\n#define pcre2_config                          PCRE2_SUFFIX(pcre2_config_)\n#define pcre2_convert_context_copy            PCRE2_SUFFIX(pcre2_convert_context_copy_)\n#define pcre2_convert_context_create          PCRE2_SUFFIX(pcre2_convert_context_create_)\n#define pcre2_convert_context_free            PCRE2_SUFFIX(pcre2_convert_context_free_)\n#define pcre2_converted_pattern_free          PCRE2_SUFFIX(pcre2_converted_pattern_free_)\n#define pcre2_dfa_match                       PCRE2_SUFFIX(pcre2_dfa_match_)\n#define pcre2_general_context_copy            PCRE2_SUFFIX(pcre2_general_context_copy_)\n#define pcre2_general_context_create          PCRE2_SUFFIX(pcre2_general_context_create_)\n#define pcre2_general_context_free            PCRE2_SUFFIX(pcre2_general_context_free_)\n#define pcre2_get_error_message               PCRE2_SUFFIX(pcre2_get_error_message_)\n#define pcre2_get_mark                        PCRE2_SUFFIX(pcre2_get_mark_)\n#define pcre2_get_match_data_heapframes_size  PCRE2_SUFFIX(pcre2_get_match_data_heapframes_size_)\n#define pcre2_get_match_data_size             PCRE2_SUFFIX(pcre2_get_match_data_size_)\n#define pcre2_get_ovector_pointer             PCRE2_SUFFIX(pcre2_get_ovector_pointer_)\n#define pcre2_get_ovector_count               PCRE2_SUFFIX(pcre2_get_ovector_count_)\n#define pcre2_get_startchar                   PCRE2_SUFFIX(pcre2_get_startchar_)\n#define pcre2_jit_compile                     PCRE2_SUFFIX(pcre2_jit_compile_)\n#define pcre2_jit_match                       PCRE2_SUFFIX(pcre2_jit_match_)\n#define pcre2_jit_free_unused_memory          PCRE2_SUFFIX(pcre2_jit_free_unused_memory_)\n#define pcre2_jit_stack_assign                PCRE2_SUFFIX(pcre2_jit_stack_assign_)\n#define pcre2_jit_stack_create                PCRE2_SUFFIX(pcre2_jit_stack_create_)\n#define pcre2_jit_stack_free                  PCRE2_SUFFIX(pcre2_jit_stack_free_)\n#define pcre2_maketables                      PCRE2_SUFFIX(pcre2_maketables_)\n#define pcre2_maketables_free                 PCRE2_SUFFIX(pcre2_maketables_free_)\n#define pcre2_match                           PCRE2_SUFFIX(pcre2_match_)\n#define pcre2_match_context_copy              PCRE2_SUFFIX(pcre2_match_context_copy_)\n#define pcre2_match_context_create            PCRE2_SUFFIX(pcre2_match_context_create_)\n#define pcre2_match_context_free              PCRE2_SUFFIX(pcre2_match_context_free_)\n#define pcre2_match_data_create               PCRE2_SUFFIX(pcre2_match_data_create_)\n#define pcre2_match_data_create_from_pattern  PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)\n#define pcre2_match_data_free                 PCRE2_SUFFIX(pcre2_match_data_free_)\n#define pcre2_next_match                      PCRE2_SUFFIX(pcre2_next_match_)\n#define pcre2_pattern_convert                 PCRE2_SUFFIX(pcre2_pattern_convert_)\n#define pcre2_pattern_info                    PCRE2_SUFFIX(pcre2_pattern_info_)\n#define pcre2_serialize_decode                PCRE2_SUFFIX(pcre2_serialize_decode_)\n#define pcre2_serialize_encode                PCRE2_SUFFIX(pcre2_serialize_encode_)\n#define pcre2_serialize_free                  PCRE2_SUFFIX(pcre2_serialize_free_)\n#define pcre2_serialize_get_number_of_codes   PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_)\n#define pcre2_set_bsr                         PCRE2_SUFFIX(pcre2_set_bsr_)\n#define pcre2_set_callout                     PCRE2_SUFFIX(pcre2_set_callout_)\n#define pcre2_set_character_tables            PCRE2_SUFFIX(pcre2_set_character_tables_)\n#define pcre2_set_compile_extra_options       PCRE2_SUFFIX(pcre2_set_compile_extra_options_)\n#define pcre2_set_compile_recursion_guard     PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)\n#define pcre2_set_depth_limit                 PCRE2_SUFFIX(pcre2_set_depth_limit_)\n#define pcre2_set_glob_escape                 PCRE2_SUFFIX(pcre2_set_glob_escape_)\n#define pcre2_set_glob_separator              PCRE2_SUFFIX(pcre2_set_glob_separator_)\n#define pcre2_set_heap_limit                  PCRE2_SUFFIX(pcre2_set_heap_limit_)\n#define pcre2_set_match_limit                 PCRE2_SUFFIX(pcre2_set_match_limit_)\n#define pcre2_set_max_varlookbehind           PCRE2_SUFFIX(pcre2_set_max_varlookbehind_)\n#define pcre2_set_max_pattern_length          PCRE2_SUFFIX(pcre2_set_max_pattern_length_)\n#define pcre2_set_max_pattern_compiled_length PCRE2_SUFFIX(pcre2_set_max_pattern_compiled_length_)\n#define pcre2_set_newline                     PCRE2_SUFFIX(pcre2_set_newline_)\n#define pcre2_set_parens_nest_limit           PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)\n#define pcre2_set_offset_limit                PCRE2_SUFFIX(pcre2_set_offset_limit_)\n#define pcre2_set_optimize                    PCRE2_SUFFIX(pcre2_set_optimize_)\n#define pcre2_set_substitute_callout          PCRE2_SUFFIX(pcre2_set_substitute_callout_)\n#define pcre2_set_substitute_case_callout     PCRE2_SUFFIX(pcre2_set_substitute_case_callout_)\n#define pcre2_substitute                      PCRE2_SUFFIX(pcre2_substitute_)\n#define pcre2_substring_copy_byname           PCRE2_SUFFIX(pcre2_substring_copy_byname_)\n#define pcre2_substring_copy_bynumber         PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)\n#define pcre2_substring_free                  PCRE2_SUFFIX(pcre2_substring_free_)\n#define pcre2_substring_get_byname            PCRE2_SUFFIX(pcre2_substring_get_byname_)\n#define pcre2_substring_get_bynumber          PCRE2_SUFFIX(pcre2_substring_get_bynumber_)\n#define pcre2_substring_length_byname         PCRE2_SUFFIX(pcre2_substring_length_byname_)\n#define pcre2_substring_length_bynumber       PCRE2_SUFFIX(pcre2_substring_length_bynumber_)\n#define pcre2_substring_list_get              PCRE2_SUFFIX(pcre2_substring_list_get_)\n#define pcre2_substring_list_free             PCRE2_SUFFIX(pcre2_substring_list_free_)\n#define pcre2_substring_nametable_scan        PCRE2_SUFFIX(pcre2_substring_nametable_scan_)\n#define pcre2_substring_number_from_name      PCRE2_SUFFIX(pcre2_substring_number_from_name_)\n\n/* Keep this old function name for backwards compatibility */\n#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)\n\n/* Keep this obsolete function for backwards compatibility: it is now a noop. */\n#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)\n\n/* Now generate all three sets of width-specific structures and function\nprototypes. */\n\n#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \\\nPCRE2_TYPES_LIST \\\nPCRE2_STRUCTURE_LIST \\\nPCRE2_GENERAL_INFO_FUNCTIONS \\\nPCRE2_GENERAL_CONTEXT_FUNCTIONS \\\nPCRE2_COMPILE_CONTEXT_FUNCTIONS \\\nPCRE2_CONVERT_CONTEXT_FUNCTIONS \\\nPCRE2_CONVERT_FUNCTIONS \\\nPCRE2_MATCH_CONTEXT_FUNCTIONS \\\nPCRE2_COMPILE_FUNCTIONS \\\nPCRE2_PATTERN_INFO_FUNCTIONS \\\nPCRE2_MATCH_FUNCTIONS \\\nPCRE2_SUBSTRING_FUNCTIONS \\\nPCRE2_SERIALIZE_FUNCTIONS \\\nPCRE2_SUBSTITUTE_FUNCTION \\\nPCRE2_JIT_FUNCTIONS \\\nPCRE2_OTHER_FUNCTIONS\n\n#define PCRE2_LOCAL_WIDTH 8\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n#define PCRE2_LOCAL_WIDTH 16\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n#define PCRE2_LOCAL_WIDTH 32\nPCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n#undef PCRE2_LOCAL_WIDTH\n\n/* Undefine the list macros; they are no longer needed. */\n\n#undef PCRE2_TYPES_LIST\n#undef PCRE2_STRUCTURE_LIST\n#undef PCRE2_GENERAL_INFO_FUNCTIONS\n#undef PCRE2_GENERAL_CONTEXT_FUNCTIONS\n#undef PCRE2_COMPILE_CONTEXT_FUNCTIONS\n#undef PCRE2_CONVERT_CONTEXT_FUNCTIONS\n#undef PCRE2_MATCH_CONTEXT_FUNCTIONS\n#undef PCRE2_COMPILE_FUNCTIONS\n#undef PCRE2_PATTERN_INFO_FUNCTIONS\n#undef PCRE2_MATCH_FUNCTIONS\n#undef PCRE2_SUBSTRING_FUNCTIONS\n#undef PCRE2_SERIALIZE_FUNCTIONS\n#undef PCRE2_SUBSTITUTE_FUNCTION\n#undef PCRE2_JIT_FUNCTIONS\n#undef PCRE2_OTHER_FUNCTIONS\n#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS\n\n/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine\nPCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make\nPCRE2_SUFFIX a no-op. Otherwise, generate an error. */\n\n#undef PCRE2_SUFFIX\n#ifndef PCRE2_CODE_UNIT_WIDTH\n#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h.\n#error Use 8, 16, or 32; or 0 for a multi-width application.\n#else  /* PCRE2_CODE_UNIT_WIDTH is defined */\n#if PCRE2_CODE_UNIT_WIDTH == 8 || \\\n    PCRE2_CODE_UNIT_WIDTH == 16 || \\\n    PCRE2_CODE_UNIT_WIDTH == 32\n#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH)\n#elif PCRE2_CODE_UNIT_WIDTH == 0\n#undef PCRE2_JOIN\n#undef PCRE2_GLUE\n#define PCRE2_SUFFIX(a) a\n#else\n#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32.\n#endif\n#endif  /* PCRE2_CODE_UNIT_WIDTH is defined */\n\n#ifdef __cplusplus\n}  /* extern \"C\" */\n#endif\n\n#endif  /* PCRE2_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_auto_possess.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains functions that scan a compiled pattern and change\nrepeats into possessive repeats where possible. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* This macro represents the max size of list[] and that is used to keep\ntrack of UCD info in several places, it should be kept on sync with the\nvalue used by GenerateUcd.py */\n#define MAX_LIST 8\n\n/*************************************************\n*        Tables for auto-possessification        *\n*************************************************/\n\n/* This table is used to check whether auto-possessification is possible\nbetween adjacent character-type opcodes. The left-hand (repeated) opcode is\nused to select the row, and the right-hand opcode is use to select the column.\nA value of 1 means that auto-possessification is OK. For example, the second\nvalue in the first row means that \\D+\\d can be turned into \\D++\\d.\n\nThe Unicode property types (\\P and \\p) have to be present to fill out the table\nbecause of what their opcode values are, but the table values should always be\nzero because property types are handled separately in the code. The last four\ncolumns apply to items that cannot be repeated, so there is no need to have\nrows for them. Note that OP_DIGIT etc. are generated only when PCRE2_UCP is\n*not* set. When it is set, \\d etc. are converted into OP_(NOT_)PROP codes. */\n\n#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)\n#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)\n\nstatic const uint8_t autoposstab[APTROWS][APTCOLS] = {\n/* \\D \\d \\S \\s \\W \\w  . .+ \\C \\P \\p \\R \\H \\h \\V \\v \\X \\Z \\z  $ $M */\n  { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \\D */\n  { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \\d */\n  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \\S */\n  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \\s */\n  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \\W */\n  { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \\w */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* .  */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* .+ */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \\C */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* \\P */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* \\p */\n  { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },  /* \\R */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },  /* \\H */\n  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 },  /* \\h */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 },  /* \\V */\n  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 },  /* \\v */\n  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }   /* \\X */\n};\n\n#ifdef SUPPORT_UNICODE\n/* This table is used to check whether auto-possessification is possible\nbetween adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The\nleft-hand (repeated) opcode is used to select the row, and the right-hand\nopcode is used to select the column. The values are as follows:\n\n  0   Always return FALSE (never auto-possessify)\n  1   Character groups are distinct (possessify if both are OP_PROP)\n  2   Check character categories in the same group (general or particular)\n  3   TRUE if the two opcodes are not the same (PROP vs NOTPROP)\n\n  4   Check left general category vs right particular category\n  5   Check right general category vs left particular category\n\n  6   Left alphanum vs right general category\n  7   Left space vs right general category\n  8   Left word vs right general category\n\n  9   Right alphanum vs left general category\n 10   Right space vs left general category\n 11   Right word vs left general category\n\n 12   Left alphanum vs right particular category\n 13   Left space vs right particular category\n 14   Left word vs right particular category\n\n 15   Right alphanum vs left particular category\n 16   Right space vs left particular category\n 17   Right word vs left particular category\n*/\n\nstatic const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = {\n/* LAMP GC  PC  SC  SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */\n  { 3,  0,  0,  0,   0,    3,    1,      1,   0,    0,   0,    0,    0 },  /* PT_LAMP */\n  { 0,  2,  4,  0,   0,    9,   10,     10,  11,    0,   0,    0,    0 },  /* PT_GC */\n  { 0,  5,  2,  0,   0,   15,   16,     16,  17,    0,   0,    0,    0 },  /* PT_PC */\n  { 0,  0,  0,  2,   2,    0,    0,      0,   0,    0,   0,    0,    0 },  /* PT_SC */\n  { 0,  0,  0,  2,   2,    0,    0,      0,   0,    0,   0,    0,    0 },  /* PT_SCX */\n  { 3,  6, 12,  0,   0,    3,    1,      1,   0,    0,   0,    0,    0 },  /* PT_ALNUM */\n  { 1,  7, 13,  0,   0,    1,    3,      3,   1,    0,   0,    0,    0 },  /* PT_SPACE */\n  { 1,  7, 13,  0,   0,    1,    3,      3,   1,    0,   0,    0,    0 },  /* PT_PXSPACE */\n  { 0,  8, 14,  0,   0,    0,    1,      1,   3,    0,   0,    0,    0 },  /* PT_WORD */\n  { 0,  0,  0,  0,   0,    0,    0,      0,   0,    0,   0,    0,    0 },  /* PT_CLIST */\n  { 0,  0,  0,  0,   0,    0,    0,      0,   0,    0,   3,    0,    0 },  /* PT_UCNC */\n  { 0,  0,  0,  0,   0,    0,    0,      0,   0,    0,   0,    0,    0 },  /* PT_BIDICL */\n  { 0,  0,  0,  0,   0,    0,    0,      0,   0,    0,   0,    0,    0 }   /* PT_BOOL */\n  /* PT_ANY does not need a record. */\n};\n\n/* This table is used to check whether auto-possessification is possible\nbetween adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one\nspecifies a general category and the other specifies a particular category. The\nrow is selected by the general category and the column by the particular\ncategory. The value is 1 if the particular category is not part of the general\ncategory. */\n\nstatic const uint8_t catposstab[7][30] = {\n/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */\n  { 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 },  /* C */\n  { 1, 1, 1, 1, 1, 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 },  /* L */\n  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* M */\n  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* N */\n  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },  /* P */\n  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 },  /* S */\n  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }   /* Z */\n};\n\n/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against\na general or particular category. The properties in each row are those\nthat apply to the character set in question. Duplication means that a little\nunnecessary work is done when checking, but this keeps things much simpler\nbecause they can all use the same code. For more details see the comment where\nthis table is used.\n\nNote: SPACE and PXSPACE used to be different because Perl excluded VT from\n\"space\", but from Perl 5.18 it's included, so both categories are treated the\nsame here. */\n\nstatic const uint8_t posspropstab[3][4] = {\n  { ucp_L, ucp_N, ucp_N, ucp_Nl },  /* ALNUM, 3rd and 4th values redundant */\n  { ucp_Z, ucp_Z, ucp_C, ucp_Cc },  /* SPACE and PXSPACE, 2nd value redundant */\n  { ucp_L, ucp_N, ucp_P, ucp_Po }   /* WORD */\n};\n#endif  /* SUPPORT_UNICODE */\n\n\n\n#ifdef SUPPORT_UNICODE\n/*************************************************\n*        Check a character and a property        *\n*************************************************/\n\n/* This function is called by compare_opcodes() when a property item is\nadjacent to a fixed character.\n\nArguments:\n  c            the character\n  ptype        the property type\n  pdata        the data for the type\n  negated      TRUE if it's a negated property (\\P or \\p{^)\n\nReturns:       TRUE if auto-possessifying is OK\n*/\n\nstatic BOOL\ncheck_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata,\n  BOOL negated)\n{\nBOOL ok, rc;\nconst uint32_t *p;\nconst ucd_record *prop = GET_UCD(c);\n\nswitch(ptype)\n  {\n  case PT_LAMP:\n  return (prop->chartype == ucp_Lu ||\n          prop->chartype == ucp_Ll ||\n          prop->chartype == ucp_Lt) == negated;\n\n  case PT_GC:\n  return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;\n\n  case PT_PC:\n  return (pdata == prop->chartype) == negated;\n\n  case PT_SC:\n  return (pdata == prop->script) == negated;\n\n  case PT_SCX:\n  ok = (pdata == prop->script\n        || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), pdata) != 0);\n  return ok == negated;\n\n  /* These are specials */\n\n  case PT_ALNUM:\n  return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||\n          PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;\n\n  /* Perl space used to exclude VT, but from Perl 5.18 it is included, which\n  means that Perl space and POSIX space are now identical. PCRE was changed\n  at release 8.34. */\n\n  case PT_SPACE:    /* Perl space */\n  case PT_PXSPACE:  /* POSIX space */\n  switch(c)\n    {\n    HSPACE_CASES:\n    VSPACE_CASES:\n    rc = negated;\n    break;\n\n    default:\n    rc = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;\n    }\n  return rc;\n\n  case PT_WORD:\n  return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||\n          PRIV(ucp_gentype)[prop->chartype] == ucp_N ||\n          c == CHAR_UNDERSCORE) == negated;\n\n  case PT_CLIST:\n  p = PRIV(ucd_caseless_sets) + prop->caseset;\n  for (;;)\n    {\n    if (c < *p) return !negated;\n    if (c == *p++) return negated;\n    }\n  /* LCOV_EXCL_START */\n  PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\n  break;\n  /* LCOV_EXCL_STOP */\n\n  /* Haven't yet thought these through. */\n\n  case PT_BIDICL:\n  return FALSE;\n\n  case PT_BOOL:\n  return FALSE;\n  }\n\nreturn FALSE;\n}\n#endif  /* SUPPORT_UNICODE */\n\n\n\n/*************************************************\n*        Base opcode of repeated opcodes         *\n*************************************************/\n\n/* Returns the base opcode for repeated single character type opcodes. If the\nopcode is not a repeated character type, it returns with the original value.\n\nArguments:  c opcode\nReturns:    base opcode for the type\n*/\n\nstatic PCRE2_UCHAR\nget_repeat_base(PCRE2_UCHAR c)\n{\nreturn (c > OP_TYPEPOSUPTO)? c :\n       (c >= OP_TYPESTAR)?   OP_TYPESTAR :\n       (c >= OP_NOTSTARI)?   OP_NOTSTARI :\n       (c >= OP_NOTSTAR)?    OP_NOTSTAR :\n       (c >= OP_STARI)?      OP_STARI :\n                             OP_STAR;\n}\n\n\n/*************************************************\n*        Fill the character property list        *\n*************************************************/\n\n/* Checks whether the code points to an opcode that can take part in auto-\npossessification, and if so, fills a list with its properties.\n\nArguments:\n  code        points to start of expression\n  utf         TRUE if in UTF mode\n  ucp         TRUE if in UCP mode\n  fcc         points to the case-flipping table\n  list        points to output list\n              list[0] will be filled with the opcode\n              list[1] will be non-zero if this opcode\n                can match an empty character string\n              list[2..7] depends on the opcode\n\nReturns:      points to the start of the next opcode if *code is accepted\n              NULL if *code is not accepted\n*/\n\nstatic PCRE2_SPTR\nget_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc,\n  uint32_t *list)\n{\nPCRE2_UCHAR c = *code;\nPCRE2_UCHAR base;\nPCRE2_SPTR end;\nPCRE2_SPTR class_end;\nuint32_t chr;\n\n#ifdef SUPPORT_UNICODE\nuint32_t *clist_dest;\nconst uint32_t *clist_src;\n#else\n(void)utf;    /* Suppress \"unused parameter\" compiler warnings */\n(void)ucp;\n#endif\n\nlist[0] = c;\nlist[1] = FALSE;\ncode++;\n\nif (c >= OP_STAR && c <= OP_TYPEPOSUPTO)\n  {\n  base = get_repeat_base(c);\n  c -= (base - OP_STAR);\n\n  if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)\n    code += IMM2_SIZE;\n\n  list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT &&\n             c != OP_POSPLUS);\n\n  switch(base)\n    {\n    case OP_STAR:\n    list[0] = OP_CHAR;\n    break;\n\n    case OP_STARI:\n    list[0] = OP_CHARI;\n    break;\n\n    case OP_NOTSTAR:\n    list[0] = OP_NOT;\n    break;\n\n    case OP_NOTSTARI:\n    list[0] = OP_NOTI;\n    break;\n\n    case OP_TYPESTAR:\n    list[0] = *code;\n    code++;\n    break;\n    }\n  c = list[0];\n  }\n\nswitch(c)\n  {\n  case OP_NOT_DIGIT:\n  case OP_DIGIT:\n  case OP_NOT_WHITESPACE:\n  case OP_WHITESPACE:\n  case OP_NOT_WORDCHAR:\n  case OP_WORDCHAR:\n  case OP_ANY:\n  case OP_ALLANY:\n  case OP_ANYNL:\n  case OP_NOT_HSPACE:\n  case OP_HSPACE:\n  case OP_NOT_VSPACE:\n  case OP_VSPACE:\n  case OP_EXTUNI:\n  case OP_EODN:\n  case OP_EOD:\n  case OP_DOLL:\n  case OP_DOLLM:\n  return code;\n\n  case OP_CHAR:\n  case OP_NOT:\n  GETCHARINCTEST(chr, code);\n  list[2] = chr;\n  list[3] = NOTACHAR;\n  return code;\n\n  case OP_CHARI:\n  case OP_NOTI:\n  list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;\n  GETCHARINCTEST(chr, code);\n  list[2] = chr;\n\n#ifdef SUPPORT_UNICODE\n  if (chr < 128 || (chr < 256 && !utf && !ucp))\n    list[3] = fcc[chr];\n  else\n    list[3] = UCD_OTHERCASE(chr);\n#elif defined SUPPORT_WIDE_CHARS\n  list[3] = (chr < 256) ? fcc[chr] : chr;\n#else\n  list[3] = fcc[chr];\n#endif\n\n  /* The othercase might be the same value. */\n\n  if (chr == list[3])\n    list[3] = NOTACHAR;\n  else\n    list[4] = NOTACHAR;\n  return code;\n\n#ifdef SUPPORT_UNICODE\n  case OP_PROP:\n  case OP_NOTPROP:\n  if (code[0] != PT_CLIST)\n    {\n    list[2] = code[0];\n    list[3] = code[1];\n    return code + 2;\n    }\n\n  /* Convert only if we have enough space. */\n\n  clist_src = PRIV(ucd_caseless_sets) + code[1];\n  clist_dest = list + 2;\n  code += 2;\n\n  do {\n     if (clist_dest >= list + MAX_LIST)\n       {\n       /* Early return if there is not enough space. GenerateUcd.py\n       generated a list with more than 5 characters and something\n       must be done about that going forward. */\n       PCRE2_DEBUG_UNREACHABLE();   /* Remove if it ever triggers */\n       list[2] = code[0];\n       list[3] = code[1];\n       return code;\n       }\n     *clist_dest++ = *clist_src;\n     }\n  while(*clist_src++ != NOTACHAR);\n\n  /* All characters are stored. The terminating NOTACHAR is copied from the\n  clist itself. */\n\n  list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;\n  return code;\n#endif\n\n  case OP_NCLASS:\n  case OP_CLASS:\n#ifdef SUPPORT_WIDE_CHARS\n  case OP_XCLASS:\n  case OP_ECLASS:\n  if (c == OP_XCLASS || c == OP_ECLASS)\n    end = code + GET(code, 0) - 1;\n  else\n#endif\n    end = code + 32 / sizeof(PCRE2_UCHAR);\n  class_end = end;\n\n  switch(*end)\n    {\n    case OP_CRSTAR:\n    case OP_CRMINSTAR:\n    case OP_CRQUERY:\n    case OP_CRMINQUERY:\n    case OP_CRPOSSTAR:\n    case OP_CRPOSQUERY:\n    list[1] = TRUE;\n    end++;\n    break;\n\n    case OP_CRPLUS:\n    case OP_CRMINPLUS:\n    case OP_CRPOSPLUS:\n    end++;\n    break;\n\n    case OP_CRRANGE:\n    case OP_CRMINRANGE:\n    case OP_CRPOSRANGE:\n    list[1] = (GET2(end, 1) == 0);\n    end += 1 + 2 * IMM2_SIZE;\n    break;\n    }\n  list[2] = (uint32_t)(end - code);\n  list[3] = (uint32_t)(end - class_end);\n  return end;\n  }\n\nreturn NULL;    /* Opcode not accepted */\n}\n\n\n\n/*************************************************\n*    Scan further character sets for match       *\n*************************************************/\n\n/* Checks whether the base and the current opcode have a common character, in\nwhich case the base cannot be possessified.\n\nArguments:\n  code        points to the byte code\n  utf         TRUE in UTF mode\n  ucp         TRUE in UCP mode\n  cb          compile data block\n  base_list   the data list of the base opcode\n  base_end    the end of the base opcode\n  rec_limit   points to recursion depth counter\n\nReturns:      TRUE if the auto-possessification is possible\n*/\n\nstatic BOOL\ncompare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb,\n  const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)\n{\nPCRE2_UCHAR c;\nuint32_t list[MAX_LIST];\nconst uint32_t *chr_ptr;\nconst uint32_t *ochr_ptr;\nconst uint32_t *list_ptr;\nPCRE2_SPTR next_code;\n#ifdef SUPPORT_WIDE_CHARS\nPCRE2_SPTR xclass_flags;\n#endif\nconst uint8_t *class_bitset;\nconst uint8_t *set1, *set2, *set_end;\nuint32_t chr;\nBOOL accepted, invert_bits;\nBOOL entered_a_group = FALSE;\n\nif (--(*rec_limit) <= 0) return FALSE;  /* Recursion has gone too deep */\n\n/* Note: the base_list[1] contains whether the current opcode has a greedy\n(represented by a non-zero value) quantifier. This is a different from\nother character type lists, which store here that the character iterator\nmatches to an empty string (also represented by a non-zero value). */\n\nfor(;;)\n  {\n  PCRE2_SPTR bracode;\n\n  /* All operations move the code pointer forward.\n  Therefore infinite recursions are not possible. */\n\n  c = *code;\n\n  /* Skip over callouts */\n\n  if (c == OP_CALLOUT)\n    {\n    code += PRIV(OP_lengths)[c];\n    continue;\n    }\n\n  if (c == OP_CALLOUT_STR)\n    {\n    code += GET(code, 1 + 2*LINK_SIZE);\n    continue;\n    }\n\n  /* At the end of a branch, skip to the end of the group and process it. */\n\n  if (c == OP_ALT)\n    {\n    do code += GET(code, 1); while (*code == OP_ALT);\n    c = *code;\n    }\n\n  /* Inspect the next opcode. */\n\n  switch(c)\n    {\n    /* We can always possessify a greedy iterator at the end of the pattern,\n    which is reached after skipping over the final OP_KET. A non-greedy\n    iterator must never be possessified. */\n\n    case OP_END:\n    return base_list[1] != 0;\n\n    /* When an iterator is at the end of certain kinds of group we can inspect\n    what follows the group by skipping over the closing ket. Note that this\n    does not apply to OP_KETRMAX or OP_KETRMIN because what follows any given\n    iteration is variable (could be another iteration or could be the next\n    item). As these two opcodes are not listed in the next switch, they will\n    end up as the next code to inspect, and return FALSE by virtue of being\n    unsupported. */\n\n    case OP_KET:\n    case OP_KETRPOS:\n    /* The non-greedy case cannot be converted to a possessive form. */\n\n    if (base_list[1] == 0) return FALSE;\n\n    /* If the bracket is capturing it might be referenced by an OP_RECURSE\n    so its last iterator can never be possessified if the pattern contains\n    recursions. (This could be improved by keeping a list of group numbers that\n    are called by recursion.) */\n\n    bracode = code - GET(code, 1);\n    switch(*bracode)\n      {\n      case OP_CBRA:\n      case OP_SCBRA:\n      case OP_CBRAPOS:\n      case OP_SCBRAPOS:\n      if (cb->had_recurse) return FALSE;\n      break;\n\n      /* A script run might have to backtrack if the iterated item can match\n      characters from more than one script. So give up unless repeating an\n      explicit character. */\n\n      case OP_SCRIPT_RUN:\n      if (base_list[0] != OP_CHAR && base_list[0] != OP_CHARI)\n        return FALSE;\n      break;\n\n      /* Atomic sub-patterns and forward assertions can always auto-possessify\n      their last iterator. However, if the group was entered as a result of\n      checking a previous iterator, this is not possible. */\n\n      case OP_ASSERT:\n      case OP_ASSERT_NOT:\n      case OP_ONCE:\n      return !entered_a_group;\n\n      /* Fixed-length lookbehinds can be treated the same way, but variable\n      length lookbehinds must not auto-possessify their last iterator. Note\n      that in order to identify a variable length lookbehind we must check\n      through all branches, because some may be of fixed length. */\n\n      case OP_ASSERTBACK:\n      case OP_ASSERTBACK_NOT:\n      do\n        {\n        if (bracode[1+LINK_SIZE] == OP_VREVERSE) return FALSE;  /* Variable */\n        bracode += GET(bracode, 1);\n        }\n      while (*bracode == OP_ALT);\n      return !entered_a_group;  /* Not variable length */\n\n      /* Non-atomic assertions - don't possessify last iterator. This needs\n      more thought. */\n\n      case OP_ASSERT_NA:\n      case OP_ASSERTBACK_NA:\n      return FALSE;\n      }\n\n    /* Skip over the bracket and inspect what comes next. */\n\n    code += PRIV(OP_lengths)[c];\n    continue;\n\n    /* Handle cases where the next item is a group. */\n\n    case OP_ONCE:\n    case OP_BRA:\n    case OP_CBRA:\n    next_code = code + GET(code, 1);\n    code += PRIV(OP_lengths)[c];\n\n    /* Check each branch. We have to recurse a level for all but the last\n    branch. */\n\n    while (*next_code == OP_ALT)\n      {\n      if (!compare_opcodes(code, utf, ucp, cb, base_list, base_end, rec_limit))\n        return FALSE;\n      code = next_code + 1 + LINK_SIZE;\n      next_code += GET(next_code, 1);\n      }\n\n    entered_a_group = TRUE;\n    continue;\n\n    case OP_BRAZERO:\n    case OP_BRAMINZERO:\n\n    next_code = code + 1;\n    if (*next_code != OP_BRA && *next_code != OP_CBRA &&\n        *next_code != OP_ONCE) return FALSE;\n\n    do next_code += GET(next_code, 1); while (*next_code == OP_ALT);\n\n    /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */\n\n    next_code += 1 + LINK_SIZE;\n    if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end,\n         rec_limit))\n      return FALSE;\n\n    code += PRIV(OP_lengths)[c];\n    continue;\n\n    /* The next opcode does not need special handling; fall through and use it\n    to see if the base can be possessified. */\n\n    default:\n    break;\n    }\n\n  /* We now have the next appropriate opcode to compare with the base. Check\n  for a supported opcode, and load its properties. */\n\n  code = get_chr_property_list(code, utf, ucp, cb->fcc, list);\n  if (code == NULL) return FALSE;    /* Unsupported */\n\n  /* If either opcode is a small character list, set pointers for comparing\n  characters from that list with another list, or with a property. */\n\n  if (base_list[0] == OP_CHAR)\n    {\n    chr_ptr = base_list + 2;\n    list_ptr = list;\n    }\n  else if (list[0] == OP_CHAR)\n    {\n    chr_ptr = list + 2;\n    list_ptr = base_list;\n    }\n\n  /* Character bitsets can also be compared to certain opcodes. */\n\n  else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */\n      || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))\n#endif\n      )\n    {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))\n#else\n    if (base_list[0] == OP_CLASS)\n#endif\n      {\n      set1 = (const uint8_t *)(base_end - base_list[2]);\n      list_ptr = list;\n      }\n    else\n      {\n      set1 = (const uint8_t *)(code - list[2]);\n      list_ptr = base_list;\n      }\n\n    invert_bits = FALSE;\n    switch(list_ptr[0])\n      {\n      case OP_CLASS:\n      case OP_NCLASS:\n      set2 = (const uint8_t *)\n        ((list_ptr == list ? code : base_end) - list_ptr[2]);\n      break;\n\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_XCLASS:\n      xclass_flags = (list_ptr == list ? code : base_end) -\n        list_ptr[2] + LINK_SIZE;\n      if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE;\n      if ((*xclass_flags & XCL_MAP) == 0)\n        {\n        /* No bits are set for characters < 256. */\n        if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0;\n        /* Might be an empty repeat. */\n        continue;\n        }\n      set2 = (const uint8_t *)(xclass_flags + 1);\n      break;\n#endif\n\n      case OP_NOT_DIGIT:\n      invert_bits = TRUE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_DIGIT:\n      set2 = (const uint8_t *)(cb->cbits + cbit_digit);\n      break;\n\n      case OP_NOT_WHITESPACE:\n      invert_bits = TRUE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_WHITESPACE:\n      set2 = (const uint8_t *)(cb->cbits + cbit_space);\n      break;\n\n      case OP_NOT_WORDCHAR:\n      invert_bits = TRUE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_WORDCHAR:\n      set2 = (const uint8_t *)(cb->cbits + cbit_word);\n      break;\n\n      default:\n      return FALSE;\n      }\n\n    /* Because the bit sets are unaligned bytes, we need to perform byte\n    comparison here. */\n\n    set_end = set1 + 32;\n    if (invert_bits)\n      {\n      do\n        {\n        if ((*set1++ & ~(*set2++)) != 0) return FALSE;\n        }\n      while (set1 < set_end);\n      }\n    else\n      {\n      do\n        {\n        if ((*set1++ & *set2++) != 0) return FALSE;\n        }\n      while (set1 < set_end);\n      }\n\n    if (list[1] == 0) return TRUE;\n    /* Might be an empty repeat. */\n    continue;\n    }\n\n  /* Some property combinations also acceptable. Unicode property opcodes are\n  processed specially; the rest can be handled with a lookup table. */\n\n  else\n    {\n    uint32_t leftop, rightop;\n\n    leftop = base_list[0];\n    rightop = list[0];\n\n#ifdef SUPPORT_UNICODE\n    accepted = FALSE; /* Always set in non-unicode case. */\n    if (leftop == OP_PROP || leftop == OP_NOTPROP)\n      {\n      if (rightop == OP_EOD)\n        accepted = TRUE;\n      else if (rightop == OP_PROP || rightop == OP_NOTPROP)\n        {\n        int n;\n        const uint8_t *p;\n        BOOL same = leftop == rightop;\n        BOOL lisprop = leftop == OP_PROP;\n        BOOL risprop = rightop == OP_PROP;\n        BOOL bothprop = lisprop && risprop;\n\n        /* There's a table that specifies how each combination is to be\n        processed:\n          0   Always return FALSE (never auto-possessify)\n          1   Character groups are distinct (possessify if both are OP_PROP)\n          2   Check character categories in the same group (general or particular)\n          3   Return TRUE if the two opcodes are not the same\n          ... see comments below\n        */\n\n        n = propposstab[base_list[2]][list[2]];\n        switch(n)\n          {\n          case 0: break;\n          case 1: accepted = bothprop; break;\n          case 2: accepted = (base_list[3] == list[3]) != same; break;\n          case 3: accepted = !same; break;\n\n          case 4:  /* Left general category, right particular category */\n          accepted = risprop && catposstab[base_list[3]][list[3]] == same;\n          break;\n\n          case 5:  /* Right general category, left particular category */\n          accepted = lisprop && catposstab[list[3]][base_list[3]] == same;\n          break;\n\n          /* This code is logically tricky. Think hard before fiddling with it.\n          The posspropstab table has four entries per row. Each row relates to\n          one of PCRE's special properties such as ALNUM or SPACE or WORD.\n          Only WORD actually needs all four entries, but using repeats for the\n          others means they can all use the same code below.\n\n          The first two entries in each row are Unicode general categories, and\n          apply always, because all the characters they include are part of the\n          PCRE character set. The third and fourth entries are a general and a\n          particular category, respectively, that include one or more relevant\n          characters. One or the other is used, depending on whether the check\n          is for a general or a particular category. However, in both cases the\n          category contains more characters than the specials that are defined\n          for the property being tested against. Therefore, it cannot be used\n          in a NOTPROP case.\n\n          Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.\n          Underscore is covered by ucp_P or ucp_Po. */\n\n          case 6:  /* Left alphanum vs right general category */\n          case 7:  /* Left space vs right general category */\n          case 8:  /* Left word vs right general category */\n          p = posspropstab[n-6];\n          accepted = risprop && lisprop ==\n            (list[3] != p[0] &&\n             list[3] != p[1] &&\n            (list[3] != p[2] || !lisprop));\n          break;\n\n          case 9:   /* Right alphanum vs left general category */\n          case 10:  /* Right space vs left general category */\n          case 11:  /* Right word vs left general category */\n          p = posspropstab[n-9];\n          accepted = lisprop && risprop ==\n            (base_list[3] != p[0] &&\n             base_list[3] != p[1] &&\n            (base_list[3] != p[2] || !risprop));\n          break;\n\n          case 12:  /* Left alphanum vs right particular category */\n          case 13:  /* Left space vs right particular category */\n          case 14:  /* Left word vs right particular category */\n          p = posspropstab[n-12];\n          accepted = risprop && lisprop ==\n            (catposstab[p[0]][list[3]] &&\n             catposstab[p[1]][list[3]] &&\n            (list[3] != p[3] || !lisprop));\n          break;\n\n          case 15:  /* Right alphanum vs left particular category */\n          case 16:  /* Right space vs left particular category */\n          case 17:  /* Right word vs left particular category */\n          p = posspropstab[n-15];\n          accepted = lisprop && risprop ==\n            (catposstab[p[0]][base_list[3]] &&\n             catposstab[p[1]][base_list[3]] &&\n            (base_list[3] != p[3] || !risprop));\n          break;\n          }\n        }\n      }\n\n    else\n#endif  /* SUPPORT_UNICODE */\n\n    accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&\n           rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&\n           autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];\n\n    if (!accepted) return FALSE;\n\n    if (list[1] == 0) return TRUE;\n    /* Might be an empty repeat. */\n    continue;\n    }\n\n  /* Control reaches here only if one of the items is a small character list.\n  All characters are checked against the other side. */\n\n  do\n    {\n    chr = *chr_ptr;\n\n    switch(list_ptr[0])\n      {\n      case OP_CHAR:\n      ochr_ptr = list_ptr + 2;\n      do\n        {\n        if (chr == *ochr_ptr) return FALSE;\n        ochr_ptr++;\n        }\n      while(*ochr_ptr != NOTACHAR);\n      break;\n\n      case OP_NOT:\n      ochr_ptr = list_ptr + 2;\n      do\n        {\n        if (chr == *ochr_ptr)\n          break;\n        ochr_ptr++;\n        }\n      while(*ochr_ptr != NOTACHAR);\n      if (*ochr_ptr == NOTACHAR) return FALSE;   /* Not found */\n      break;\n\n      /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not*\n      set. When it is set, \\d etc. are converted into OP_(NOT_)PROP codes. */\n\n      case OP_DIGIT:\n      if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE;\n      break;\n\n      case OP_NOT_DIGIT:\n      if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE;\n      break;\n\n      case OP_WHITESPACE:\n      if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE;\n      break;\n\n      case OP_NOT_WHITESPACE:\n      if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE;\n      break;\n\n      case OP_WORDCHAR:\n      if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE;\n      break;\n\n      case OP_NOT_WORDCHAR:\n      if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE;\n      break;\n\n      case OP_HSPACE:\n      switch(chr)\n        {\n        HSPACE_CASES: return FALSE;\n        default: break;\n        }\n      break;\n\n      case OP_NOT_HSPACE:\n      switch(chr)\n        {\n        HSPACE_CASES: break;\n        default: return FALSE;\n        }\n      break;\n\n      case OP_ANYNL:\n      case OP_VSPACE:\n      switch(chr)\n        {\n        VSPACE_CASES: return FALSE;\n        default: break;\n        }\n      break;\n\n      case OP_NOT_VSPACE:\n      switch(chr)\n        {\n        VSPACE_CASES: break;\n        default: return FALSE;\n        }\n      break;\n\n      case OP_DOLL:\n      case OP_EODN:\n      switch (chr)\n        {\n        case CHAR_CR:\n        case CHAR_LF:\n        case CHAR_VT:\n        case CHAR_FF:\n        case CHAR_NEL:\n#ifndef EBCDIC\n        case 0x2028:\n        case 0x2029:\n#endif  /* Not EBCDIC */\n        return FALSE;\n        }\n      break;\n\n      case OP_EOD:    /* Can always possessify before \\z */\n      break;\n\n#ifdef SUPPORT_UNICODE\n      case OP_PROP:\n      case OP_NOTPROP:\n      if (!check_char_prop(chr, list_ptr[2], list_ptr[3],\n            list_ptr[0] == OP_NOTPROP))\n        return FALSE;\n      break;\n#endif\n\n      case OP_NCLASS:\n      if (chr > 255) return FALSE;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_CLASS:\n      if (chr > 255) break;\n      class_bitset = (const uint8_t *)\n        ((list_ptr == list ? code : base_end) - list_ptr[2]);\n      if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE;\n      break;\n\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_XCLASS:\n      if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -\n          list_ptr[2] + LINK_SIZE, (const uint8_t*)cb->start_code, utf))\n        return FALSE;\n      break;\n\n      case OP_ECLASS:\n      if (PRIV(eclass)(chr,\n          (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE,\n          (list_ptr == list ? code : base_end) - list_ptr[3],\n          (const uint8_t*)cb->start_code, utf))\n        return FALSE;\n      break;\n#endif /* SUPPORT_WIDE_CHARS */\n\n      default:\n      return FALSE;\n      }\n\n    chr_ptr++;\n    }\n  while(*chr_ptr != NOTACHAR);\n\n  /* At least one character must be matched from this opcode. */\n\n  if (list[1] == 0) return TRUE;\n  }\n\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\nreturn FALSE;              /* Avoid compiler warnings */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*    Scan compiled regex for auto-possession     *\n*************************************************/\n\n/* Replaces single character iterations with their possessive alternatives\nif appropriate. This function modifies the compiled opcode! Hitting a\nnon-existent opcode may indicate a bug in PCRE2, but it can also be caused if a\nbad UTF string was compiled with PCRE2_NO_UTF_CHECK. The rec_limit catches\noverly complicated or large patterns. In these cases, the check just stops,\nleaving the remainder of the pattern unpossessified.\n\nArguments:\n  code        points to start of the byte code\n  cb          compile data block\n\nReturns:      0 for success\n              -1 if a non-existant opcode is encountered\n*/\n\nint\nPRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb)\n{\nPCRE2_UCHAR c;\nPCRE2_SPTR end;\nPCRE2_UCHAR *repeat_opcode;\nuint32_t list[MAX_LIST];\nint rec_limit = 1000;  /* Was 10,000 but clang+ASAN uses a lot of stack. */\nBOOL utf = (cb->external_options & PCRE2_UTF) != 0;\nBOOL ucp = (cb->external_options & PCRE2_UCP) != 0;\n\nfor (;;)\n  {\n  c = *code;\n\n  /* LCOV_EXCL_START */\n  if (c >= OP_TABLE_LENGTH)\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    return -1;   /* Something gone wrong */\n    }\n  /* LCOV_EXCL_STOP */\n\n  if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)\n    {\n    c -= get_repeat_base(c) - OP_STAR;\n    end = (c <= OP_MINUPTO) ?\n      get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL;\n    list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;\n\n    if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end,\n        &rec_limit))\n      {\n      switch(c)\n        {\n        case OP_STAR:\n        *code += OP_POSSTAR - OP_STAR;\n        break;\n\n        case OP_MINSTAR:\n        *code += OP_POSSTAR - OP_MINSTAR;\n        break;\n\n        case OP_PLUS:\n        *code += OP_POSPLUS - OP_PLUS;\n        break;\n\n        case OP_MINPLUS:\n        *code += OP_POSPLUS - OP_MINPLUS;\n        break;\n\n        case OP_QUERY:\n        *code += OP_POSQUERY - OP_QUERY;\n        break;\n\n        case OP_MINQUERY:\n        *code += OP_POSQUERY - OP_MINQUERY;\n        break;\n\n        case OP_UPTO:\n        *code += OP_POSUPTO - OP_UPTO;\n        break;\n\n        case OP_MINUPTO:\n        *code += OP_POSUPTO - OP_MINUPTO;\n        break;\n        }\n      }\n    c = *code;\n    }\n  else if (c == OP_CLASS || c == OP_NCLASS\n#ifdef SUPPORT_WIDE_CHARS\n           || c == OP_XCLASS || c == OP_ECLASS\n#endif\n           )\n    {\n#ifdef SUPPORT_WIDE_CHARS\n    if (c == OP_XCLASS || c == OP_ECLASS)\n      repeat_opcode = code + GET(code, 1);\n    else\n#endif\n      repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR));\n\n    c = *repeat_opcode;\n    if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)\n      {\n      /* The return from get_chr_property_list() will never be NULL when\n      *code (aka c) is one of the four class opcodes. However, gcc with\n      -fanalyzer notes that a NULL return is possible, and grumbles. Hence we\n      put in a check. */\n\n      end = get_chr_property_list(code, utf, ucp, cb->fcc, list);\n      list[1] = (c & 1) == 0;\n\n      if (end != NULL &&\n          compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit))\n        {\n        switch (c)\n          {\n          case OP_CRSTAR:\n          case OP_CRMINSTAR:\n          *repeat_opcode = OP_CRPOSSTAR;\n          break;\n\n          case OP_CRPLUS:\n          case OP_CRMINPLUS:\n          *repeat_opcode = OP_CRPOSPLUS;\n          break;\n\n          case OP_CRQUERY:\n          case OP_CRMINQUERY:\n          *repeat_opcode = OP_CRPOSQUERY;\n          break;\n\n          case OP_CRRANGE:\n          case OP_CRMINRANGE:\n          *repeat_opcode = OP_CRPOSRANGE;\n          break;\n          }\n        }\n      }\n    c = *code;\n    }\n\n  switch(c)\n    {\n    case OP_END:\n    return 0;\n\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;\n    break;\n\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEEXACT:\n    case OP_TYPEPOSUPTO:\n    if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)\n      code += 2;\n    break;\n\n    case OP_CALLOUT_STR:\n    code += GET(code, 1 + 2*LINK_SIZE);\n    break;\n\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_XCLASS:\n    case OP_ECLASS:\n    code += GET(code, 1);\n    break;\n#endif\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_SKIP_ARG:\n    case OP_THEN_ARG:\n    code += code[1];\n    break;\n    }\n\n  /* Add in the fixed length from the table */\n\n  code += PRIV(OP_lengths)[c];\n\n  /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be\n  followed by a multi-byte character. The length in the table is a minimum, so\n  we have to arrange to skip the extra code units. */\n\n#ifdef MAYBE_UTF_MULTI\n  if (utf) switch(c)\n    {\n    case OP_CHAR:\n    case OP_CHARI:\n    case OP_NOT:\n    case OP_NOTI:\n    case OP_STAR:\n    case OP_MINSTAR:\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_UPTO:\n    case OP_MINUPTO:\n    case OP_EXACT:\n    case OP_POSSTAR:\n    case OP_POSPLUS:\n    case OP_POSQUERY:\n    case OP_POSUPTO:\n    case OP_STARI:\n    case OP_MINSTARI:\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_UPTOI:\n    case OP_MINUPTOI:\n    case OP_EXACTI:\n    case OP_POSSTARI:\n    case OP_POSPLUSI:\n    case OP_POSQUERYI:\n    case OP_POSUPTOI:\n    case OP_NOTSTAR:\n    case OP_NOTMINSTAR:\n    case OP_NOTPLUS:\n    case OP_NOTMINPLUS:\n    case OP_NOTQUERY:\n    case OP_NOTMINQUERY:\n    case OP_NOTUPTO:\n    case OP_NOTMINUPTO:\n    case OP_NOTEXACT:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSUPTO:\n    case OP_NOTSTARI:\n    case OP_NOTMINSTARI:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUSI:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERYI:\n    case OP_NOTUPTOI:\n    case OP_NOTMINUPTOI:\n    case OP_NOTEXACTI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTPOSQUERYI:\n    case OP_NOTPOSUPTOI:\n    if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);\n    break;\n    }\n#else\n  (void)(utf);  /* Keep compiler happy by referencing function argument */\n#endif  /* SUPPORT_WIDE_CHARS */\n  }\n}\n\n/* End of pcre2_auto_possess.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_chartables.c.dist",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* This file was automatically written by the pcre2_dftables auxiliary\nprogram. It contains character tables that are used when no external\ntables are passed to PCRE2 by the application that calls it. The tables\nare used only for characters whose code values are less than 256, and\nonly relevant if not in UCP mode. */\n\n/* This set of tables was written in the C locale. */\n\n/* The pcre2_ftables program (which is distributed with PCRE2) can be used\nto build alternative versions of this file. This is necessary if you are\nrunning in an EBCDIC environment, or if you want to default to a different\nencoding, for example ISO-8859-1. When pcre2_dftables is run, it creates\nthese tables in the \"C\" locale by default. This happens automatically if\nPCRE2 is configured with --enable-rebuild-chartables. However, you can run\npcre2_dftables manually with the -L option to build tables using the LC_ALL\nlocale. */\n\n#include \"pcre2_internal.h\"\n\nconst uint8_t PRIV(default_tables)[] = {\n\n/* This table is a lower casing table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122, 91, 92, 93, 94, 95,\n   96, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122,123,124,125,126,127,\n  128,129,130,131,132,133,134,135,\n  136,137,138,139,140,141,142,143,\n  144,145,146,147,148,149,150,151,\n  152,153,154,155,156,157,158,159,\n  160,161,162,163,164,165,166,167,\n  168,169,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,193,194,195,196,197,198,199,\n  200,201,202,203,204,205,206,207,\n  208,209,210,211,212,213,214,215,\n  216,217,218,219,220,221,222,223,\n  224,225,226,227,228,229,230,231,\n  232,233,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table is a case flipping table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122, 91, 92, 93, 94, 95,\n   96, 65, 66, 67, 68, 69, 70, 71,\n   72, 73, 74, 75, 76, 77, 78, 79,\n   80, 81, 82, 83, 84, 85, 86, 87,\n   88, 89, 90,123,124,125,126,127,\n  128,129,130,131,132,133,134,135,\n  136,137,138,139,140,141,142,143,\n  144,145,146,147,148,149,150,151,\n  152,153,154,155,156,157,158,159,\n  160,161,162,163,164,165,166,167,\n  168,169,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,193,194,195,196,197,198,199,\n  200,201,202,203,204,205,206,207,\n  208,209,210,211,212,213,214,215,\n  216,217,218,219,220,221,222,223,\n  224,225,226,227,228,229,230,231,\n  232,233,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table contains bit maps for various character classes. Each map is 32\nbytes long and the bits run from the least significant end of each byte. The\nclasses that have their own maps are: space, xdigit, digit, upper, lower, word,\ngraph, print, punct, and cntrl. Other classes are built from combinations. */\n\n  0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,  /* space */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* xdigit */\n  0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* digit */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* upper */\n  0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* lower */\n  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* word */\n  0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,  /* graph */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,  /* print */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,  /* punct */\n  0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,  /* cntrl */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n/* This table identifies various classes of character by individual bits:\n  0x01   white space character\n  0x02   letter\n  0x04   lower case letter\n  0x08   decimal digit\n  0x10   word (alphanumeric or '_')\n*/\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */\n  0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */\n  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*    - '  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ( - /  */\n  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /*  0 - 7  */\n  0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /*  8 - ?  */\n  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  @ - G  */\n  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */\n  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */\n  0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /*  X - _  */\n  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  ` - g  */\n  0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  h - o  */\n  0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  p - w  */\n  0x16,0x16,0x16,0x00,0x00,0x00,0x00,0x00, /*  x -127 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */\n\n/* End of pcre2_chartables.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_chartables.c.ebcdic-1047-nl15",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* This file was automatically written by the pcre2_dftables auxiliary\nprogram. It contains character tables that are used when no external\ntables are passed to PCRE2 by the application that calls it. The tables\nare used only for characters whose code values are less than 256, and\nonly relevant if not in UCP mode. */\n\n/* This set of tables was written in the EBCDIC 1047 (NL 0x15) locale. */\n\n/* The pcre2_ftables program (which is distributed with PCRE2) can be used\nto build alternative versions of this file. This is necessary if you are\nrunning in an EBCDIC environment, or if you want to default to a different\nencoding, for example ISO-8859-1. When pcre2_dftables is run, it creates\nthese tables in the \"C\" locale by default. This happens automatically if\nPCRE2 is configured with --enable-rebuild-chartables. However, you can run\npcre2_dftables manually with the -L option to build tables using the LC_ALL\nlocale. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"pcre2_internal.h\"\n\nconst uint8_t PRIV(default_tables)[] = {\n\n/* This table is a lower casing table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 65, 66, 67, 68, 69, 70, 71,\n   72, 73, 74, 75, 76, 77, 78, 79,\n   80, 81, 82, 83, 84, 85, 86, 87,\n   88, 89, 90, 91, 92, 93, 94, 95,\n   96, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122,123,124,125,126,127,\n  128,129,130,131,132,133,134,135,\n  136,137,138,139,140,141,142,143,\n  144,145,146,147,148,149,150,151,\n  152,153,154,155,156,157,158,159,\n  160,161,162,163,164,165,166,167,\n  168,169,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,129,130,131,132,133,134,135,\n  136,137,202,203,204,205,206,207,\n  208,145,146,147,148,149,150,151,\n  152,153,218,219,220,221,222,223,\n  224,225,162,163,164,165,166,167,\n  168,169,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table is a case flipping table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 65, 66, 67, 68, 69, 70, 71,\n   72, 73, 74, 75, 76, 77, 78, 79,\n   80, 81, 82, 83, 84, 85, 86, 87,\n   88, 89, 90, 91, 92, 93, 94, 95,\n   96, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122,123,124,125,126,127,\n  128,193,194,195,196,197,198,199,\n  200,201,138,139,140,141,142,143,\n  144,209,210,211,212,213,214,215,\n  216,217,154,155,156,157,158,159,\n  160,161,226,227,228,229,230,231,\n  232,233,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,129,130,131,132,133,134,135,\n  136,137,202,203,204,205,206,207,\n  208,145,146,147,148,149,150,151,\n  152,153,218,219,220,221,222,223,\n  224,225,162,163,164,165,166,167,\n  168,169,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table contains bit maps for various character classes. Each map is 32\nbytes long and the bits run from the least significant end of each byte. The\nclasses that have their own maps are: space, xdigit, digit, upper, lower, word,\ngraph, print, punct, and cntrl. Other classes are built from combinations. */\n\n  0x20,0x38,0x20,0x00,0x00,0x00,0x00,0x00,  /* space */\n  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* xdigit */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x7e,0x00,0x00,0x00,0x00,0x00,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* digit */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* upper */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* lower */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* word */\n  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* graph */\n  0x00,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0xfe,0x03,0xfe,0x03,0xfe,0x23,0x00,0x20,\n  0xff,0x03,0xff,0x03,0xfd,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* print */\n  0x01,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0xfe,0x03,0xfe,0x03,0xfe,0x23,0x00,0x20,\n  0xff,0x03,0xff,0x03,0xfd,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* punct */\n  0x00,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0x00,0x00,0x00,0x00,0x02,0x20,0x00,0x20,\n  0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,\n\n  0xaf,0xf8,0x6f,0xf3,0xc0,0xe0,0x84,0xb0,  /* cntrl */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n/* This table identifies various classes of character by individual bits:\n  0x01   white space character\n  0x02   letter\n  0x04   lower case letter\n  0x08   decimal digit\n  0x10   word (alphanumeric or '_')\n*/\n\n  0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /*   0-  7 */\n  0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */\n  0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /*  16- 23 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*    - '  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ( - /  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  0 - 7  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  8 - ?  */\n  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  @ - G  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  H - O  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  P - W  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  X - _  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ` - g  */\n  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, /*  h - o  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  p - w  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  x -127 */\n  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* 128-135 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */\n  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* 144-151 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */\n  0x00,0x00,0x16,0x16,0x16,0x16,0x16,0x16, /* 160-167 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */\n  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 192-199 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */\n  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 208-215 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */\n  0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 224-231 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */\n  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 240-247 */\n  0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */\n\n/* End of pcre2_chartables.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_chartables.c.ebcdic-1047-nl25",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* This file was automatically written by the pcre2_dftables auxiliary\nprogram. It contains character tables that are used when no external\ntables are passed to PCRE2 by the application that calls it. The tables\nare used only for characters whose code values are less than 256, and\nonly relevant if not in UCP mode. */\n\n/* This set of tables was written in the EBCDIC 1047 (NL 0x25) locale. */\n\n/* The pcre2_ftables program (which is distributed with PCRE2) can be used\nto build alternative versions of this file. This is necessary if you are\nrunning in an EBCDIC environment, or if you want to default to a different\nencoding, for example ISO-8859-1. When pcre2_dftables is run, it creates\nthese tables in the \"C\" locale by default. This happens automatically if\nPCRE2 is configured with --enable-rebuild-chartables. However, you can run\npcre2_dftables manually with the -L option to build tables using the LC_ALL\nlocale. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"pcre2_internal.h\"\n\nconst uint8_t PRIV(default_tables)[] = {\n\n/* This table is a lower casing table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 65, 66, 67, 68, 69, 70, 71,\n   72, 73, 74, 75, 76, 77, 78, 79,\n   80, 81, 82, 83, 84, 85, 86, 87,\n   88, 89, 90, 91, 92, 93, 94, 95,\n   96, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122,123,124,125,126,127,\n  128,129,130,131,132,133,134,135,\n  136,137,138,139,140,141,142,143,\n  144,145,146,147,148,149,150,151,\n  152,153,154,155,156,157,158,159,\n  160,161,162,163,164,165,166,167,\n  168,169,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,129,130,131,132,133,134,135,\n  136,137,202,203,204,205,206,207,\n  208,145,146,147,148,149,150,151,\n  152,153,218,219,220,221,222,223,\n  224,225,162,163,164,165,166,167,\n  168,169,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table is a case flipping table. */\n\n    0,  1,  2,  3,  4,  5,  6,  7,\n    8,  9, 10, 11, 12, 13, 14, 15,\n   16, 17, 18, 19, 20, 21, 22, 23,\n   24, 25, 26, 27, 28, 29, 30, 31,\n   32, 33, 34, 35, 36, 37, 38, 39,\n   40, 41, 42, 43, 44, 45, 46, 47,\n   48, 49, 50, 51, 52, 53, 54, 55,\n   56, 57, 58, 59, 60, 61, 62, 63,\n   64, 65, 66, 67, 68, 69, 70, 71,\n   72, 73, 74, 75, 76, 77, 78, 79,\n   80, 81, 82, 83, 84, 85, 86, 87,\n   88, 89, 90, 91, 92, 93, 94, 95,\n   96, 97, 98, 99,100,101,102,103,\n  104,105,106,107,108,109,110,111,\n  112,113,114,115,116,117,118,119,\n  120,121,122,123,124,125,126,127,\n  128,193,194,195,196,197,198,199,\n  200,201,138,139,140,141,142,143,\n  144,209,210,211,212,213,214,215,\n  216,217,154,155,156,157,158,159,\n  160,161,226,227,228,229,230,231,\n  232,233,170,171,172,173,174,175,\n  176,177,178,179,180,181,182,183,\n  184,185,186,187,188,189,190,191,\n  192,129,130,131,132,133,134,135,\n  136,137,202,203,204,205,206,207,\n  208,145,146,147,148,149,150,151,\n  152,153,218,219,220,221,222,223,\n  224,225,162,163,164,165,166,167,\n  168,169,234,235,236,237,238,239,\n  240,241,242,243,244,245,246,247,\n  248,249,250,251,252,253,254,255,\n\n/* This table contains bit maps for various character classes. Each map is 32\nbytes long and the bits run from the least significant end of each byte. The\nclasses that have their own maps are: space, xdigit, digit, upper, lower, word,\ngraph, print, punct, and cntrl. Other classes are built from combinations. */\n\n  0x20,0x38,0x00,0x00,0x20,0x00,0x00,0x00,  /* space */\n  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* xdigit */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x7e,0x00,0x00,0x00,0x00,0x00,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* digit */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* upper */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* lower */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* word */\n  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0x00,0x00,\n  0xfe,0x03,0xfe,0x03,0xfc,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* graph */\n  0x00,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0xfe,0x03,0xfe,0x03,0xfe,0x23,0x00,0x20,\n  0xff,0x03,0xff,0x03,0xfd,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* print */\n  0x01,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0xfe,0x03,0xfe,0x03,0xfe,0x23,0x00,0x20,\n  0xff,0x03,0xff,0x03,0xfd,0x03,0xff,0x03,\n\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* punct */\n  0x00,0xf8,0x01,0xfc,0x03,0xf8,0x00,0xfe,\n  0x00,0x00,0x00,0x00,0x02,0x20,0x00,0x20,\n  0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,\n\n  0xaf,0xf8,0x4f,0xf3,0xe0,0xe0,0x84,0xb0,  /* cntrl */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\n/* This table identifies various classes of character by individual bits:\n  0x01   white space character\n  0x02   letter\n  0x04   lower case letter\n  0x08   decimal digit\n  0x10   word (alphanumeric or '_')\n*/\n\n  0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /*   0-  7 */\n  0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */\n  0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /*    - '  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ( - /  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  0 - 7  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  8 - ?  */\n  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  @ - G  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  H - O  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  P - W  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  X - _  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ` - g  */\n  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, /*  h - o  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  p - w  */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  x -127 */\n  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* 128-135 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */\n  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* 144-151 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */\n  0x00,0x00,0x16,0x16,0x16,0x16,0x16,0x16, /* 160-167 */\n  0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */\n  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 192-199 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */\n  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 208-215 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */\n  0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 224-231 */\n  0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */\n  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 240-247 */\n  0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */\n\n/* End of pcre2_chartables.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_chkdint.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                     Written by Philip Hazel\n            Copyright (c) 2023 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This file contains functions to implement checked integer operation */\n\n\n#ifndef PCRE2_PCRE2TEST\n#include \"pcre2_internal.h\"\n#endif\n\n\n\n/*************************************************\n*        Checked Integer Multiplication          *\n*************************************************/\n\n/*\nArguments:\n  r         A pointer to PCRE2_SIZE to store the answer\n  a, b      Two integers\n\nReturns:    Bool indicating if the operation overflows\n\nIt is modeled after C23's <stdckdint.h> interface\nThe INT64_OR_DOUBLE type is a 64-bit integer type when available,\notherwise double. */\n\nBOOL\nPRIV(ckd_smul)(PCRE2_SIZE *r, int a, int b)\n{\n#ifdef HAVE_BUILTIN_MUL_OVERFLOW\nPCRE2_SIZE m;\n\nif (__builtin_mul_overflow(a, b, &m)) return TRUE;\n\n*r = m;\n#else\nINT64_OR_DOUBLE m;\n\nPCRE2_ASSERT(a >= 0 && b >= 0);\n\nm = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b;\n\n#if defined INT64_MAX || defined int64_t\nif (sizeof(m) > sizeof(*r) && m > (INT64_OR_DOUBLE)PCRE2_SIZE_MAX) return TRUE;\n*r = (PCRE2_SIZE)m;\n#else\nif (m > PCRE2_SIZE_MAX) return TRUE;\n*r = m;\n#endif\n\n#endif\n\nreturn FALSE;\n}\n\n/* End of pcre2_chkdint.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_compile.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_compile.h\"\n\n\n\n#define NLBLOCK cb             /* Block containing newline information */\n#define PSSTART start_pattern  /* Field containing processed string start */\n#define PSEND   end_pattern    /* Field containing processed string end */\n\n/* In rare error cases debugging might require calling pcre2_printint(). */\n\n#if 0\n#ifdef EBCDIC\n#define PRINTABLE(c) ((c) >= 64 && (c) < 255)\n#else\n#define PRINTABLE(c) ((c) >= 32 && (c) < 127)\n#endif\n#define CHAR_OUTPUT(c)      (c)\n#define CHAR_OUTPUT_HEX(c)  (c)\n#define CHAR_INPUT(c)       (c)\n#define CHAR_INPUT_HEX(c)   (c)\n#include \"pcre2_printint_inc.h\"\n#undef PRINTABLE\n#undef CHAR_OUTPUT\n#undef CHAR_OUTPUT_HEX\n#undef CHAR_INPUT\n#define DEBUG_CALL_PRINTINT\n#endif\n\n/* Other debugging code can be enabled by these defines. */\n\n/* #define DEBUG_SHOW_CAPTURES */\n/* #define DEBUG_SHOW_PARSED */\n\n/* There are a few things that vary with different code unit sizes. Handle them\nby defining macros in order to minimize #if usage. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define STRING_UTFn_RIGHTPAR     STRING_UTF8_RIGHTPAR, 5\n#define XDIGIT(c)                xdigitab[c]\n\n#else  /* Either 16-bit or 32-bit */\n#define XDIGIT(c)                (MAX_255(c)? xdigitab[c] : 0xff)\n\n#if PCRE2_CODE_UNIT_WIDTH == 16\n#define STRING_UTFn_RIGHTPAR     STRING_UTF16_RIGHTPAR, 6\n\n#else  /* 32-bit */\n#define STRING_UTFn_RIGHTPAR     STRING_UTF32_RIGHTPAR, 6\n#endif\n#endif\n\n/* Function definitions to allow mutual recursion */\n\nstatic int\n  compile_regex(uint32_t, uint32_t, PCRE2_UCHAR **, uint32_t **, int *,\n    uint32_t, uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *,\n    open_capitem *, compile_block *, PCRE2_SIZE *);\n\nstatic int\n  get_branchlength(uint32_t **, int *, int *, int *, parsed_recurse_check *,\n    compile_block *);\n\nstatic BOOL\n  set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,\n    compile_block *);\n\nstatic int\n  check_lookbehinds(uint32_t *, uint32_t **, parsed_recurse_check *,\n    compile_block *, int *);\n\n\n/*************************************************\n*      Code parameters and static tables         *\n*************************************************/\n\n#define MAX_GROUP_NUMBER   65535u\n#define MAX_REPEAT_COUNT   65535u\n#define REPEAT_UNLIMITED   (MAX_REPEAT_COUNT+1)\n\n/* COMPILE_WORK_SIZE specifies the size of stack workspace, which is used in\ndifferent ways in the different pattern scans. The parsing and group-\nidentifying pre-scan uses it to handle nesting, and needs it to be 16-bit\naligned for this. Having defined the size in code units, we set up\nC16_WORK_SIZE as the number of elements in the 16-bit vector.\n\nDuring the first compiling phase, when determining how much memory is required,\nthe regex is partly compiled into this space, but the compiled parts are\ndiscarded as soon as they can be, so that hopefully there will never be an\noverrun. The code does, however, check for an overrun, which can occur for\npathological patterns. The size of the workspace depends on LINK_SIZE because\nthe length of compiled items varies with this.\n\nIn the real compile phase, this workspace is not currently used. */\n\n#define COMPILE_WORK_SIZE (3000*LINK_SIZE)   /* Size in code units */\n\n#define C16_WORK_SIZE \\\n  ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint16_t))\n\n/* A uint32_t vector is used for caching information about the size of\ncapturing groups, to improve performance. A default is created on the stack of\nthis size. */\n\n#define GROUPINFO_DEFAULT_SIZE 256\n\n/* The overrun tests check for a slightly smaller size so that they detect the\noverrun before it actually does run off the end of the data block. */\n\n#define WORK_SIZE_SAFETY_MARGIN (100)\n\n/* This value determines the size of the initial vector that is used for\nremembering named groups during the pre-compile. It is allocated on the stack,\nbut if it is too small, it is expanded, in a similar way to the workspace. The\nvalue is the number of slots in the list. */\n\n#define NAMED_GROUP_LIST_SIZE  20\n\n/* The pre-compiling pass over the pattern creates a parsed pattern in a vector\nof uint32_t. For short patterns this lives on the stack, with this size. Heap\nmemory is used for longer patterns. */\n\n#define PARSED_PATTERN_DEFAULT_SIZE 1024\n\n/* Maximum length value to check against when making sure that the variable\nthat holds the compiled pattern length does not overflow. We make it a bit less\nthan INT_MAX to allow for adding in group terminating code units, so that we\ndon't have to check them every time. */\n\n#define OFLOW_MAX (INT_MAX - 20)\n\n/* Table of extra lengths for each of the meta codes. Must be kept in step with\nthe definitions above. For some items these values are a basic length to which\na variable amount has to be added. */\n\nstatic unsigned char meta_extra_lengths[] = {\n  0,             /* META_END */\n  0,             /* META_ALT */\n  0,             /* META_ATOMIC */\n  0,             /* META_BACKREF - more if group is >= 10 */\n  1+SIZEOFFSET,  /* META_BACKREF_BYNAME */\n  1,             /* META_BIGVALUE */\n  3,             /* META_CALLOUT_NUMBER */\n  3+SIZEOFFSET,  /* META_CALLOUT_STRING */\n  0,             /* META_CAPTURE */\n  0,             /* META_CIRCUMFLEX */\n  0,             /* META_CLASS */\n  0,             /* META_CLASS_EMPTY */\n  0,             /* META_CLASS_EMPTY_NOT */\n  0,             /* META_CLASS_END */\n  0,             /* META_CLASS_NOT */\n  0,             /* META_COND_ASSERT */\n  SIZEOFFSET,    /* META_COND_DEFINE */\n  1+SIZEOFFSET,  /* META_COND_NAME */\n  1+SIZEOFFSET,  /* META_COND_NUMBER */\n  1+SIZEOFFSET,  /* META_COND_RNAME */\n  1+SIZEOFFSET,  /* META_COND_RNUMBER */\n  3,             /* META_COND_VERSION */\n  SIZEOFFSET,    /* META_OFFSET */\n  0,             /* META_SCS */\n  1,             /* META_CAPTURE_NAME */\n  1,             /* META_CAPTURE_NUMBER */\n  0,             /* META_DOLLAR */\n  0,             /* META_DOT */\n  0,             /* META_ESCAPE - one more for ESC_P and ESC_p */\n  0,             /* META_KET */\n  0,             /* META_NOCAPTURE */\n  2,             /* META_OPTIONS */\n  1,             /* META_POSIX */\n  1,             /* META_POSIX_NEG */\n  0,             /* META_RANGE_ESCAPED */\n  0,             /* META_RANGE_LITERAL */\n  SIZEOFFSET,    /* META_RECURSE */\n  1+SIZEOFFSET,  /* META_RECURSE_BYNAME */\n  0,             /* META_SCRIPT_RUN */\n  0,             /* META_LOOKAHEAD */\n  0,             /* META_LOOKAHEADNOT */\n  SIZEOFFSET,    /* META_LOOKBEHIND */\n  SIZEOFFSET,    /* META_LOOKBEHINDNOT */\n  0,             /* META_LOOKAHEAD_NA */\n  SIZEOFFSET,    /* META_LOOKBEHIND_NA */\n  1,             /* META_MARK - plus the string length */\n  0,             /* META_ACCEPT */\n  0,             /* META_FAIL */\n  0,             /* META_COMMIT */\n  1,             /* META_COMMIT_ARG - plus the string length */\n  0,             /* META_PRUNE */\n  1,             /* META_PRUNE_ARG - plus the string length */\n  0,             /* META_SKIP */\n  1,             /* META_SKIP_ARG - plus the string length */\n  0,             /* META_THEN */\n  1,             /* META_THEN_ARG - plus the string length */\n  0,             /* META_ASTERISK */\n  0,             /* META_ASTERISK_PLUS */\n  0,             /* META_ASTERISK_QUERY */\n  0,             /* META_PLUS */\n  0,             /* META_PLUS_PLUS */\n  0,             /* META_PLUS_QUERY */\n  0,             /* META_QUERY */\n  0,             /* META_QUERY_PLUS */\n  0,             /* META_QUERY_QUERY */\n  2,             /* META_MINMAX */\n  2,             /* META_MINMAX_PLUS */\n  2,             /* META_MINMAX_QUERY */\n  0,             /* META_ECLASS_AND */\n  0,             /* META_ECLASS_OR */\n  0,             /* META_ECLASS_SUB */\n  0,             /* META_ECLASS_XOR */\n  0              /* META_ECLASS_NOT */\n};\n\n/* Types for skipping parts of a parsed pattern. */\n\nenum { PSKIP_ALT, PSKIP_CLASS, PSKIP_KET };\n\n/* Values and flags for the unsigned xxcuflags variables that accompany xxcu\nvariables, which are concerned with first and required code units. A value\ngreater than or equal to REQ_NONE means \"no code unit set\"; otherwise the\nmatching xxcu variable is set, and the low valued bits are relevant. */\n\n#define REQ_UNSET     0xffffffffu  /* Not yet found anything */\n#define REQ_NONE      0xfffffffeu  /* Found not fixed character */\n#define REQ_CASELESS  0x00000001u  /* Code unit in xxcu is caseless */\n#define REQ_VARY      0x00000002u  /* Code unit is followed by non-literal */\n\n/* These flags are used in the groupinfo vector. */\n\n#define GI_SET_FIXED_LENGTH    0x80000000u\n#define GI_NOT_FIXED_LENGTH    0x40000000u\n#define GI_FIXED_LENGTH_MASK   0x0000ffffu\n\n/* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC\nand is fast (a good compiler can turn it into a subtraction and unsigned\ncomparison). */\n\n#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)\n\n/* Table to identify hex digits. The tables in chartables are dependent on the\nlocale, and may mark arbitrary characters as digits. We want to recognize only\n0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It\ncosts 256 bytes, but it is a lot faster than doing character value tests (at\nleast in some simple cases I timed), and in some applications one wants PCRE2\nto compile efficiently as well as match efficiently. The value in the table is\nthe binary hex digit value, or 0xff for non-hex digits. */\n\n/* This is the \"normal\" case, for ASCII systems, and EBCDIC systems running in\nUTF-8 mode. */\n\n#ifndef EBCDIC\nstatic const uint8_t xdigitab[] =\n  {\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   0-  7 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   8- 15 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  16- 23 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  24- 31 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*    - '  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  ( - /  */\n  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /*  0 - 7  */\n  0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /*  8 - ?  */\n  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  @ - G  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  H - O  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  P - W  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  X - _  */\n  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  ` - g  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  h - o  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  p - w  */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  x -127 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */\n\n#else\n\n/* This is the \"abnormal\" case, for EBCDIC systems not running in UTF-8 mode. */\n\nstatic const uint8_t xdigitab[] =\n  {\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   0-  7  0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   8- 15    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  16- 23 10 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  24- 31    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  32- 39 20 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  40- 47    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  48- 55 30 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  56- 63    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*    - 71 40 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  72- |     */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  & - 87 50 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  88- 95    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  - -103 60 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ?     */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- \"     */\n  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g  80 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  h -143    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p  90 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  q -159    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x  A0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  y -175    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  ^ -183 B0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191    */\n  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  { - G  C0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  H -207    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  } - P  D0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  Q -223    */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  \\ - X  E0 */\n  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  Y -239    */\n  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /*  0 - 7  F0 */\n  0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/*  8 -255    */\n#endif  /* EBCDIC */\n\n\n/* Table for handling alphanumeric escaped characters. Positive returns are\nsimple data values; negative values are for special things like \\d and so on.\nZero means further processing is needed (for things like \\x), or the escape is\ninvalid. */\n\n/* This is the \"normal\" table for ASCII systems or for EBCDIC systems running\nin UTF-8 mode. It runs from '0' to 'z'. */\n\n#ifndef EBCDIC\n#define ESCAPES_FIRST       CHAR_0\n#define ESCAPES_LAST        CHAR_z\n#define UPPER_CASE(c)       (c-32)\n\nstatic const short int escapes[] = {\n    /* 0 */ 0,                       /* 1 */ 0,\n    /* 2 */ 0,                       /* 3 */ 0,\n    /* 4 */ 0,                       /* 5 */ 0,\n    /* 6 */ 0,                       /* 7 */ 0,\n    /* 8 */ 0,                       /* 9 */ 0,\n    /* : */ ESCAPES_FIRST+0x0a,      /* ; */ ESCAPES_FIRST+0x0b,\n    /* < */ ESCAPES_FIRST+0x0c,      /* = */ ESCAPES_FIRST+0x0d,\n    /* > */ ESCAPES_FIRST+0x0e,      /* ? */ ESCAPES_FIRST+0x0f,\n    /* @ */ ESCAPES_FIRST+0x10,      /* A */ -ESC_A,\n    /* B */ -ESC_B,                  /* C */ -ESC_C,\n    /* D */ -ESC_D,                  /* E */ -ESC_E,\n    /* F */ 0,                       /* G */ -ESC_G,\n    /* H */ -ESC_H,                  /* I */ 0,\n    /* J */ 0,                       /* K */ -ESC_K,\n    /* L */ 0,                       /* M */ 0,\n    /* N */ -ESC_N,                  /* O */ 0,\n    /* P */ -ESC_P,                  /* Q */ -ESC_Q,\n    /* R */ -ESC_R,                  /* S */ -ESC_S,\n    /* T */ 0,                       /* U */ 0,\n    /* V */ -ESC_V,                  /* W */ -ESC_W,\n    /* X */ -ESC_X,                  /* Y */ 0,\n    /* Z */ -ESC_Z,                  /* [ */ ESCAPES_FIRST+0x2b,\n    /* \\ */ ESCAPES_FIRST+0x2c,      /* ] */ ESCAPES_FIRST+0x2d,\n    /* ^ */ ESCAPES_FIRST+0x2e,      /* _ */ ESCAPES_FIRST+0x2f,\n    /* ` */ ESCAPES_FIRST+0x30,      /* a */ CHAR_BEL,\n    /* b */ -ESC_b,                  /* c */ 0,\n    /* d */ -ESC_d,                  /* e */ CHAR_ESC,\n    /* f */ CHAR_FF,                 /* g */ 0,\n    /* h */ -ESC_h,                  /* i */ 0,\n    /* j */ 0,                       /* k */ -ESC_k,\n    /* l */ 0,                       /* m */ 0,\n    /* n */ CHAR_LF,                 /* o */ 0,\n    /* p */ -ESC_p,                  /* q */ 0,\n    /* r */ CHAR_CR,                 /* s */ -ESC_s,\n    /* t */ CHAR_HT,                 /* u */ 0,\n    /* v */ -ESC_v,                  /* w */ -ESC_w,\n    /* x */ 0,                       /* y */ 0,\n    /* z */ -ESC_z\n};\n\n#else\n\n/* This is the \"abnormal\" table for EBCDIC systems without UTF-8 support.\nIt runs from 'a' to '9'. Our EBCDIC support can be provided via the compiler,\nwhich can interpret character literals like 'a' or '[' in an EBCDIC codepage;\nin this case, there is wide variance between codepages on the interpretation of\ncharacters between the letters ('[' and '{' and so on are placed in all sorts of\ndifferent positions in the table). Thankfully however, all EBCDIC codepages\nplace the letters and digits in the same location, so we hardcode that here.\nOur EBCDIC support can also be provided via numeric literals instead of\ncharacter literals, so either way, 'CHAR_a' will be 0x81 when PCRE2 is compiled\nin EBCDIC mode. */\n\n#define ESCAPES_FIRST       CHAR_a\n#define ESCAPES_LAST        CHAR_9\n#define UPPER_CASE(c)       (c+64)\n\nstatic const short int escapes[] = {\n    /* 0x81 a */ CHAR_BEL,             /* 0x82 b */ -ESC_b,\n    /* 0x83 c */ 0,                    /* 0x84 d */ -ESC_d,\n    /* 0x85 e */ CHAR_ESC,             /* 0x86 f */ CHAR_FF,\n    /* 0x87 g */ 0,                    /* 0x88 h */ -ESC_h,\n    /* 0x89 i */ 0,                    /* 0x8a   */ ESCAPES_FIRST+0x09,\n    /* 0x8b   */ ESCAPES_FIRST+0x0a,   /* 0x8c   */ ESCAPES_FIRST+0x0b,\n    /* 0x8d   */ ESCAPES_FIRST+0x0c,   /* 0x8e   */ ESCAPES_FIRST+0x0d,\n    /* 0x8f   */ ESCAPES_FIRST+0x0e,   /* 0x90   */ ESCAPES_FIRST+0x0f,\n    /* 0x91 j */ 0,                    /* 0x92 k */ -ESC_k,\n    /* 0x93 l */ 0,                    /* 0x94 m */ 0,\n    /* 0x95 n */ CHAR_LF,              /* 0x96 o */ 0,\n    /* 0x97 p */ -ESC_p,               /* 0x98 q */ 0,\n    /* 0x99 r */ CHAR_CR,              /* 0x9a   */ ESCAPES_FIRST+0x19,\n    /* 0x9b   */ ESCAPES_FIRST+0x1a,   /* 0x9c   */ ESCAPES_FIRST+0x1b,\n    /* 0x9d   */ ESCAPES_FIRST+0x1c,   /* 0x9e   */ ESCAPES_FIRST+0x1d,\n    /* 0x9f   */ ESCAPES_FIRST+0x1e,   /* 0xa0   */ ESCAPES_FIRST+0x1f,\n    /* 0xa1   */ ESCAPES_FIRST+0x20,   /* 0xa2 s */ -ESC_s,\n    /* 0xa3 t */ CHAR_HT,              /* 0xa4 u */ 0,\n    /* 0xa5 v */ -ESC_v,               /* 0xa6 w */ -ESC_w,\n    /* 0xa7 x */ 0,                    /* 0xa8 y */ 0,\n    /* 0xa9 z */ -ESC_z,               /* 0xaa   */ ESCAPES_FIRST+0x29,\n    /* 0xab   */ ESCAPES_FIRST+0x2a,   /* 0xac   */ ESCAPES_FIRST+0x2b,\n    /* 0xad   */ ESCAPES_FIRST+0x2c,   /* 0xae   */ ESCAPES_FIRST+0x2d,\n    /* 0xaf   */ ESCAPES_FIRST+0x2e,   /* 0xb0   */ ESCAPES_FIRST+0x2f,\n    /* 0xb1   */ ESCAPES_FIRST+0x30,   /* 0xb2   */ ESCAPES_FIRST+0x31,\n    /* 0xb3   */ ESCAPES_FIRST+0x32,   /* 0xb4   */ ESCAPES_FIRST+0x33,\n    /* 0xb5   */ ESCAPES_FIRST+0x34,   /* 0xb6   */ ESCAPES_FIRST+0x35,\n    /* 0xb7   */ ESCAPES_FIRST+0x36,   /* 0xb8   */ ESCAPES_FIRST+0x37,\n    /* 0xb9   */ ESCAPES_FIRST+0x38,   /* 0xba   */ ESCAPES_FIRST+0x39,\n    /* 0xbb   */ ESCAPES_FIRST+0x3a,   /* 0xbc   */ ESCAPES_FIRST+0x3b,\n    /* 0xbd   */ ESCAPES_FIRST+0x3c,   /* 0xbe   */ ESCAPES_FIRST+0x3d,\n    /* 0xbf   */ ESCAPES_FIRST+0x3e,   /* 0xc0   */ ESCAPES_FIRST+0x3f,\n    /* 0xc1 A */ -ESC_A,               /* 0xc2 B */ -ESC_B,\n    /* 0xc3 C */ -ESC_C,               /* 0xc4 D */ -ESC_D,\n    /* 0xc5 E */ -ESC_E,               /* 0xc6 F */ 0,\n    /* 0xc7 G */ -ESC_G,               /* 0xc8 H */ -ESC_H,\n    /* 0xc9 I */ 0,                    /* 0xca   */ ESCAPES_FIRST+0x49,\n    /* 0xcb   */ ESCAPES_FIRST+0x4a,   /* 0xcc   */ ESCAPES_FIRST+0x4b,\n    /* 0xcd   */ ESCAPES_FIRST+0x4c,   /* 0xce   */ ESCAPES_FIRST+0x4d,\n    /* 0xcf   */ ESCAPES_FIRST+0x4e,   /* 0xd0   */ ESCAPES_FIRST+0x4f,\n    /* 0xd1 J */ 0,                    /* 0xd2 K */ -ESC_K,\n    /* 0xd3 L */ 0,                    /* 0xd4 M */ 0,\n    /* 0xd5 N */ -ESC_N,               /* 0xd6 O */ 0,\n    /* 0xd7 P */ -ESC_P,               /* 0xd8 Q */ -ESC_Q,\n    /* 0xd9 R */ -ESC_R,               /* 0xda   */ ESCAPES_FIRST+0x59,\n    /* 0xdb   */ ESCAPES_FIRST+0x5a,   /* 0xdc   */ ESCAPES_FIRST+0x5b,\n    /* 0xdd   */ ESCAPES_FIRST+0x5c,   /* 0xde   */ ESCAPES_FIRST+0x5d,\n    /* 0xdf   */ ESCAPES_FIRST+0x5e,   /* 0xe0   */ ESCAPES_FIRST+0x5f,\n    /* 0xe1   */ ESCAPES_FIRST+0x60,   /* 0xe2 S */ -ESC_S,\n    /* 0xe3 T */ 0,                    /* 0xe4 U */ 0,\n    /* 0xe5 V */ -ESC_V,               /* 0xe6 W */ -ESC_W,\n    /* 0xe7 X */ -ESC_X,               /* 0xe8 Y */ 0,\n    /* 0xe9 Z */ -ESC_Z,               /* 0xea   */ ESCAPES_FIRST+0x69,\n    /* 0xeb   */ ESCAPES_FIRST+0x6a,   /* 0xec   */ ESCAPES_FIRST+0x6b,\n    /* 0xed   */ ESCAPES_FIRST+0x6c,   /* 0xee   */ ESCAPES_FIRST+0x6d,\n    /* 0xef   */ ESCAPES_FIRST+0x6e,   /* 0xf0 0 */ 0,\n    /* 0xf1 1 */ 0,                    /* 0xf2 2 */ 0,\n    /* 0xf3 3 */ 0,                    /* 0xf4 4 */ 0,\n    /* 0xf5 5 */ 0,                    /* 0xf6 6 */ 0,\n    /* 0xf7 7 */ 0,                    /* 0xf8 8 */ 0,\n    /* 0xf9 9 */ 0,\n};\n\n/* We also need a table of characters that may follow \\c in an EBCDIC\nenvironment for characters 0-31. */\n\nstatic unsigned char ebcdic_escape_c[] = {\n  CHAR_COMMERCIAL_AT, CHAR_A, CHAR_B, CHAR_C, CHAR_D, CHAR_E, CHAR_F, CHAR_G,\n  CHAR_H, CHAR_I, CHAR_J, CHAR_K, CHAR_L, CHAR_M, CHAR_N, CHAR_O, CHAR_P,\n  CHAR_Q, CHAR_R, CHAR_S, CHAR_T, CHAR_U, CHAR_V, CHAR_W, CHAR_X, CHAR_Y,\n  CHAR_Z, CHAR_LEFT_SQUARE_BRACKET, CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,\n  CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE\n};\n\n#endif   /* EBCDIC */\n\n\n/* Table of special \"verbs\" like (*PRUNE). This is a short table, so it is\nsearched linearly. Put all the names into a single string, in order to reduce\nthe number of relocations when a shared library is dynamically linked. The\nstring is built from string macros so that it works in UTF-8 mode on EBCDIC\nplatforms. */\n\ntypedef struct verbitem {\n  unsigned int len;          /* Length of verb name */\n  uint32_t meta;             /* Base META_ code */\n  int has_arg;               /* Argument requirement */\n} verbitem;\n\nstatic const char verbnames[] =\n  \"\\0\"                       /* Empty name is a shorthand for MARK */\n  STRING_MARK0\n  STRING_ACCEPT0\n  STRING_F0\n  STRING_FAIL0\n  STRING_COMMIT0\n  STRING_PRUNE0\n  STRING_SKIP0\n  STRING_THEN;\n\nstatic const verbitem verbs[] = {\n  { 0, META_MARK,   +1 },  /* > 0 => must have an argument */\n  { 4, META_MARK,   +1 },\n  { 6, META_ACCEPT, -1 },  /* < 0 => Optional argument, convert to pre-MARK */\n  { 1, META_FAIL,   -1 },\n  { 4, META_FAIL,   -1 },\n  { 6, META_COMMIT,  0 },\n  { 5, META_PRUNE,   0 },  /* Optional argument; bump META code if found */\n  { 4, META_SKIP,    0 },\n  { 4, META_THEN,    0 }\n};\n\nstatic const int verbcount = sizeof(verbs)/sizeof(verbitem);\n\n/* Verb opcodes, indexed by their META code offset from META_MARK. */\n\nstatic const uint32_t verbops[] = {\n  OP_MARK, OP_ACCEPT, OP_FAIL, OP_COMMIT, OP_COMMIT_ARG, OP_PRUNE,\n  OP_PRUNE_ARG, OP_SKIP, OP_SKIP_ARG, OP_THEN, OP_THEN_ARG };\n\n/* Table of \"alpha assertions\" like (*pla:...), similar to the (*VERB) table. */\n\ntypedef struct alasitem {\n  unsigned int len;          /* Length of name */\n  uint32_t meta;             /* Base META_ code */\n} alasitem;\n\nstatic const char alasnames[] =\n  STRING_pla0\n  STRING_plb0\n  STRING_napla0\n  STRING_naplb0\n  STRING_nla0\n  STRING_nlb0\n  STRING_positive_lookahead0\n  STRING_positive_lookbehind0\n  STRING_non_atomic_positive_lookahead0\n  STRING_non_atomic_positive_lookbehind0\n  STRING_negative_lookahead0\n  STRING_negative_lookbehind0\n  STRING_scs0\n  STRING_scan_substring0\n  STRING_atomic0\n  STRING_sr0\n  STRING_asr0\n  STRING_script_run0\n  STRING_atomic_script_run;\n\nstatic const alasitem alasmeta[] = {\n  {  3, META_LOOKAHEAD         },\n  {  3, META_LOOKBEHIND        },\n  {  5, META_LOOKAHEAD_NA      },\n  {  5, META_LOOKBEHIND_NA     },\n  {  3, META_LOOKAHEADNOT      },\n  {  3, META_LOOKBEHINDNOT     },\n  { 18, META_LOOKAHEAD         },\n  { 19, META_LOOKBEHIND        },\n  { 29, META_LOOKAHEAD_NA      },\n  { 30, META_LOOKBEHIND_NA     },\n  { 18, META_LOOKAHEADNOT      },\n  { 19, META_LOOKBEHINDNOT     },\n  {  3, META_SCS               },\n  { 14, META_SCS               },\n  {  6, META_ATOMIC            },\n  {  2, META_SCRIPT_RUN        }, /* sr = script run */\n  {  3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */\n  { 10, META_SCRIPT_RUN        }, /* script run */\n  { 17, META_ATOMIC_SCRIPT_RUN }  /* atomic script run */\n};\n\nstatic const int alascount = sizeof(alasmeta)/sizeof(alasitem);\n\n/* Offsets from OP_STAR for case-independent and negative repeat opcodes. */\n\nstatic uint32_t chartypeoffset[] = {\n  OP_STAR - OP_STAR,    OP_STARI - OP_STAR,\n  OP_NOTSTAR - OP_STAR, OP_NOTSTARI - OP_STAR };\n\n/* Tables of names of POSIX character classes and their lengths. The names are\nnow all in a single string, to reduce the number of relocations when a shared\nlibrary is dynamically loaded. The list of lengths is terminated by a zero\nlength entry. The first three must be alpha, lower, upper, as this is assumed\nfor handling case independence.\n\nThe indices for several classes are stored in pcre2_compile.h - these must\nbe kept in sync with posix_names, posix_name_lengths, posix_class_maps,\nand posix_substitutes. */\n\nstatic const char posix_names[] =\n  STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0\n  STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0\n  STRING_graph0 STRING_print0 STRING_punct0 STRING_space0\n  STRING_word0  STRING_xdigit;\n\nstatic const uint8_t posix_name_lengths[] = {\n  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };\n\n/* Table of class bit maps for each POSIX class. Each class is formed from a\nbase map, with an optional addition or removal of another map. Then, for some\nclasses, there is some additional tweaking: for [:blank:] the vertical space\ncharacters are removed, and for [:alpha:] and [:alnum:] the underscore\ncharacter is removed. The triples in the table consist of the base map offset,\nsecond map offset or -1 if no second map, and a non-negative value for map\naddition or a negative value for map subtraction (if there are two maps). The\nabsolute value of the third field has these meanings: 0 => no tweaking, 1 =>\nremove vertical space characters, 2 => remove underscore. */\n\nconst int PRIV(posix_class_maps)[] = {\n  cbit_word,   cbit_digit, -2,            /* alpha */\n  cbit_lower,  -1,          0,            /* lower */\n  cbit_upper,  -1,          0,            /* upper */\n  cbit_word,   -1,          2,            /* alnum - word without underscore */\n  cbit_print,  cbit_cntrl,  0,            /* ascii */\n  cbit_space,  -1,          1,            /* blank - a GNU extension */\n  cbit_cntrl,  -1,          0,            /* cntrl */\n  cbit_digit,  -1,          0,            /* digit */\n  cbit_graph,  -1,          0,            /* graph */\n  cbit_print,  -1,          0,            /* print */\n  cbit_punct,  -1,          0,            /* punct */\n  cbit_space,  -1,          0,            /* space */\n  cbit_word,   -1,          0,            /* word - a Perl extension */\n  cbit_xdigit, -1,          0             /* xdigit */\n};\n\n#ifdef SUPPORT_UNICODE\n\n/* The POSIX class Unicode property substitutes that are used in UCP mode must\nbe in the order of the POSIX class names, defined above. */\n\nstatic int posix_substitutes[] = {\n  PT_GC, ucp_L,     /* alpha */\n  PT_PC, ucp_Ll,    /* lower */\n  PT_PC, ucp_Lu,    /* upper */\n  PT_ALNUM, 0,      /* alnum */\n  -1, 0,            /* ascii, treat as non-UCP */\n  -1, 1,            /* blank, treat as \\h */\n  PT_PC, ucp_Cc,    /* cntrl */\n  PT_PC, ucp_Nd,    /* digit */\n  PT_PXGRAPH, 0,    /* graph */\n  PT_PXPRINT, 0,    /* print */\n  PT_PXPUNCT, 0,    /* punct */\n  PT_PXSPACE, 0,    /* space */   /* Xps is POSIX space, but from 8.34 */\n  PT_WORD, 0,       /* word  */   /* Perl and POSIX space are the same */\n  PT_PXXDIGIT, 0    /* xdigit */  /* Perl has additional hex digits */\n};\n#endif  /* SUPPORT_UNICODE */\n\n/* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset\nare allowed. */\n\n#define PUBLIC_LITERAL_COMPILE_OPTIONS \\\n  (PCRE2_ANCHORED|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_ENDANCHORED| \\\n   PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_MATCH_INVALID_UTF| \\\n   PCRE2_NO_START_OPTIMIZE|PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)\n\n#define PUBLIC_COMPILE_OPTIONS \\\n  (PUBLIC_LITERAL_COMPILE_OPTIONS| \\\n   PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \\\n   PCRE2_ALT_VERBNAMES|PCRE2_DOLLAR_ENDONLY|PCRE2_DOTALL|PCRE2_DUPNAMES| \\\n   PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MATCH_UNSET_BACKREF| \\\n   PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C|PCRE2_NEVER_UCP| \\\n   PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE|PCRE2_NO_AUTO_POSSESS| \\\n   PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_ALT_EXTENDED_CLASS)\n\n#define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \\\n   (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD| \\\n    PCRE2_EXTRA_CASELESS_RESTRICT|PCRE2_EXTRA_TURKISH_CASING)\n\n#define PUBLIC_COMPILE_EXTRA_OPTIONS \\\n   (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \\\n    PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL| \\\n    PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \\\n    PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK|PCRE2_EXTRA_ASCII_BSD| \\\n    PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX| \\\n    PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_PYTHON_OCTAL|PCRE2_EXTRA_NO_BS0| \\\n    PCRE2_EXTRA_NEVER_CALLOUT)\n\n/* This is a table of start-of-pattern options such as (*UTF) and settings such\nas (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward\ncompatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is\ngeneric and always supported. */\n\nenum { PSO_OPT,     /* Value is an option bit */\n       PSO_XOPT,    /* Value is an xoption bit */\n       PSO_FLG,     /* Value is a flag bit */\n       PSO_NL,      /* Value is a newline type */\n       PSO_BSR,     /* Value is a \\R type */\n       PSO_LIMH,    /* Read integer value for heap limit */\n       PSO_LIMM,    /* Read integer value for match limit */\n       PSO_LIMD,    /* Read integer value for depth limit */\n       PSO_OPTMZ    /* Value is an optimization bit */\n     };\n\ntypedef struct pso {\n  const char *name;\n  uint16_t length;\n  uint16_t type;\n  uint32_t value;\n} pso;\n\n/* NB: STRING_UTFn_RIGHTPAR contains the length as well */\n\nstatic const pso pso_list[] = {\n  { STRING_UTFn_RIGHTPAR,                  PSO_OPT, PCRE2_UTF },\n  { STRING_UTF_RIGHTPAR,                4, PSO_OPT, PCRE2_UTF },\n  { STRING_UCP_RIGHTPAR,                4, PSO_OPT, PCRE2_UCP },\n  { STRING_NOTEMPTY_RIGHTPAR,           9, PSO_FLG, PCRE2_NOTEMPTY_SET },\n  { STRING_NOTEMPTY_ATSTART_RIGHTPAR,  17, PSO_FLG, PCRE2_NE_ATST_SET },\n  { STRING_NO_AUTO_POSSESS_RIGHTPAR,   16, PSO_OPTMZ, PCRE2_OPTIM_AUTO_POSSESS },\n  { STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPTMZ, PCRE2_OPTIM_DOTSTAR_ANCHOR },\n  { STRING_NO_JIT_RIGHTPAR,             7, PSO_FLG, PCRE2_NOJIT },\n  { STRING_NO_START_OPT_RIGHTPAR,      13, PSO_OPTMZ, PCRE2_OPTIM_START_OPTIMIZE },\n  { STRING_CASELESS_RESTRICT_RIGHTPAR, 18, PSO_XOPT, PCRE2_EXTRA_CASELESS_RESTRICT },\n  { STRING_TURKISH_CASING_RIGHTPAR,    15, PSO_XOPT, PCRE2_EXTRA_TURKISH_CASING },\n  { STRING_LIMIT_HEAP_EQ,              11, PSO_LIMH, 0 },\n  { STRING_LIMIT_MATCH_EQ,             12, PSO_LIMM, 0 },\n  { STRING_LIMIT_DEPTH_EQ,             12, PSO_LIMD, 0 },\n  { STRING_LIMIT_RECURSION_EQ,         16, PSO_LIMD, 0 },\n  { STRING_CR_RIGHTPAR,                 3, PSO_NL,  PCRE2_NEWLINE_CR },\n  { STRING_LF_RIGHTPAR,                 3, PSO_NL,  PCRE2_NEWLINE_LF },\n  { STRING_CRLF_RIGHTPAR,               5, PSO_NL,  PCRE2_NEWLINE_CRLF },\n  { STRING_ANY_RIGHTPAR,                4, PSO_NL,  PCRE2_NEWLINE_ANY },\n  { STRING_NUL_RIGHTPAR,                4, PSO_NL,  PCRE2_NEWLINE_NUL },\n  { STRING_ANYCRLF_RIGHTPAR,            8, PSO_NL,  PCRE2_NEWLINE_ANYCRLF },\n  { STRING_BSR_ANYCRLF_RIGHTPAR,       12, PSO_BSR, PCRE2_BSR_ANYCRLF },\n  { STRING_BSR_UNICODE_RIGHTPAR,       12, PSO_BSR, PCRE2_BSR_UNICODE }\n};\n\n/* This table is used when converting repeating opcodes into possessified\nversions as a result of an explicit possessive quantifier such as ++. A zero\nvalue means there is no possessified version - in those cases the item in\nquestion must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT\nbecause all relevant opcodes are less than that. */\n\nstatic const uint8_t opcode_possessify[] = {\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0 - 15  */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 16 - 31 */\n\n  0,                       /* NOTI */\n  OP_POSSTAR, 0,           /* STAR, MINSTAR */\n  OP_POSPLUS, 0,           /* PLUS, MINPLUS */\n  OP_POSQUERY, 0,          /* QUERY, MINQUERY */\n  OP_POSUPTO, 0,           /* UPTO, MINUPTO */\n  0,                       /* EXACT */\n  0, 0, 0, 0,              /* POS{STAR,PLUS,QUERY,UPTO} */\n\n  OP_POSSTARI, 0,          /* STARI, MINSTARI */\n  OP_POSPLUSI, 0,          /* PLUSI, MINPLUSI */\n  OP_POSQUERYI, 0,         /* QUERYI, MINQUERYI */\n  OP_POSUPTOI, 0,          /* UPTOI, MINUPTOI */\n  0,                       /* EXACTI */\n  0, 0, 0, 0,              /* POS{STARI,PLUSI,QUERYI,UPTOI} */\n\n  OP_NOTPOSSTAR, 0,        /* NOTSTAR, NOTMINSTAR */\n  OP_NOTPOSPLUS, 0,        /* NOTPLUS, NOTMINPLUS */\n  OP_NOTPOSQUERY, 0,       /* NOTQUERY, NOTMINQUERY */\n  OP_NOTPOSUPTO, 0,        /* NOTUPTO, NOTMINUPTO */\n  0,                       /* NOTEXACT */\n  0, 0, 0, 0,              /* NOTPOS{STAR,PLUS,QUERY,UPTO} */\n\n  OP_NOTPOSSTARI, 0,       /* NOTSTARI, NOTMINSTARI */\n  OP_NOTPOSPLUSI, 0,       /* NOTPLUSI, NOTMINPLUSI */\n  OP_NOTPOSQUERYI, 0,      /* NOTQUERYI, NOTMINQUERYI */\n  OP_NOTPOSUPTOI, 0,       /* NOTUPTOI, NOTMINUPTOI */\n  0,                       /* NOTEXACTI */\n  0, 0, 0, 0,              /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */\n\n  OP_TYPEPOSSTAR, 0,       /* TYPESTAR, TYPEMINSTAR */\n  OP_TYPEPOSPLUS, 0,       /* TYPEPLUS, TYPEMINPLUS */\n  OP_TYPEPOSQUERY, 0,      /* TYPEQUERY, TYPEMINQUERY */\n  OP_TYPEPOSUPTO, 0,       /* TYPEUPTO, TYPEMINUPTO */\n  0,                       /* TYPEEXACT */\n  0, 0, 0, 0,              /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */\n\n  OP_CRPOSSTAR, 0,         /* CRSTAR, CRMINSTAR */\n  OP_CRPOSPLUS, 0,         /* CRPLUS, CRMINPLUS */\n  OP_CRPOSQUERY, 0,        /* CRQUERY, CRMINQUERY */\n  OP_CRPOSRANGE, 0,        /* CRRANGE, CRMINRANGE */\n  0, 0, 0, 0,              /* CRPOS{STAR,PLUS,QUERY,RANGE} */\n\n  0, 0, 0, 0,              /* CLASS, NCLASS, XCLASS, ECLASS */\n  0, 0,                    /* REF, REFI */\n  0, 0,                    /* DNREF, DNREFI */\n  0, 0,                    /* RECURSE, CALLOUT */\n};\n\n/* Compile-time check that the table has the correct size. */\nSTATIC_ASSERT(sizeof(opcode_possessify) == OP_CALLOUT+1, opcode_possessify);\n\n\n#ifdef DEBUG_SHOW_PARSED\n/*************************************************\n*     Show the parsed pattern for debugging      *\n*************************************************/\n\n/* For debugging the pre-scan, this code, which outputs the parsed data vector,\ncan be enabled. */\n\nstatic void show_parsed(compile_block *cb)\n{\nuint32_t *pptr = cb->parsed_pattern;\n\nfor (;;)\n  {\n  int max, min;\n  PCRE2_SIZE offset;\n  uint32_t i;\n  uint32_t length;\n  uint32_t meta_arg = META_DATA(*pptr);\n\n  fprintf(stderr, \"+++ %02d %.8x \", (int)(pptr - cb->parsed_pattern), *pptr);\n\n  if (*pptr < META_END)\n    {\n    if (*pptr > 32 && *pptr < 128) fprintf(stderr, \"%c\", *pptr);\n    pptr++;\n    }\n\n  else switch (META_CODE(*pptr++))\n    {\n    default:\n    fprintf(stderr, \"**** OOPS - unknown META value - giving up ****\\n\");\n    return;\n\n    case META_END:\n    fprintf(stderr, \"META_END\\n\");\n    return;\n\n    case META_CAPTURE:\n    fprintf(stderr, \"META_CAPTURE %d\", meta_arg);\n    break;\n\n    case META_RECURSE:\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"META_RECURSE %d %zd\", meta_arg, offset);\n    break;\n\n    case META_BACKREF:\n    if (meta_arg < 10)\n      offset = cb->small_ref_offset[meta_arg];\n    else\n      GETOFFSET(offset, pptr);\n    fprintf(stderr, \"META_BACKREF %d %zd\", meta_arg, offset);\n    break;\n\n    case META_ESCAPE:\n    if (meta_arg == ESC_P || meta_arg == ESC_p)\n      {\n      uint32_t ptype = *pptr >> 16;\n      uint32_t pvalue = *pptr++ & 0xffff;\n      fprintf(stderr, \"META \\\\%c %d %d\", (meta_arg == ESC_P)? CHAR_P:CHAR_p,\n        ptype, pvalue);\n      }\n    else\n      {\n      uint32_t cc;\n      /* There's just one escape we might have here that isn't negated in the\n      escapes table. */\n      if (meta_arg == ESC_g) cc = CHAR_g;\n      else for (cc = ESCAPES_FIRST; cc <= ESCAPES_LAST; cc++)\n        {\n        if (meta_arg == (uint32_t)(-escapes[cc - ESCAPES_FIRST])) break;\n        }\n      if (cc > ESCAPES_LAST) cc = CHAR_QUESTION_MARK;\n      fprintf(stderr, \"META \\\\%c\", cc);\n      }\n    break;\n\n    case META_MINMAX:\n    min = *pptr++;\n    max = *pptr++;\n    if (max != REPEAT_UNLIMITED)\n      fprintf(stderr, \"META {%d,%d}\", min, max);\n    else\n      fprintf(stderr, \"META {%d,}\", min);\n    break;\n\n    case META_MINMAX_QUERY:\n    min = *pptr++;\n    max = *pptr++;\n    if (max != REPEAT_UNLIMITED)\n      fprintf(stderr, \"META {%d,%d}?\", min, max);\n    else\n      fprintf(stderr, \"META {%d,}?\", min);\n    break;\n\n    case META_MINMAX_PLUS:\n    min = *pptr++;\n    max = *pptr++;\n    if (max != REPEAT_UNLIMITED)\n      fprintf(stderr, \"META {%d,%d}+\", min, max);\n    else\n      fprintf(stderr, \"META {%d,}+\", min);\n    break;\n\n    case META_BIGVALUE: fprintf(stderr, \"META_BIGVALUE %.8x\", *pptr++); break;\n    case META_CIRCUMFLEX: fprintf(stderr, \"META_CIRCUMFLEX\"); break;\n    case META_COND_ASSERT: fprintf(stderr, \"META_COND_ASSERT\"); break;\n    case META_DOLLAR: fprintf(stderr, \"META_DOLLAR\"); break;\n    case META_DOT: fprintf(stderr, \"META_DOT\"); break;\n    case META_ASTERISK: fprintf(stderr, \"META *\"); break;\n    case META_ASTERISK_QUERY: fprintf(stderr, \"META *?\"); break;\n    case META_ASTERISK_PLUS: fprintf(stderr, \"META *+\"); break;\n    case META_PLUS: fprintf(stderr, \"META +\"); break;\n    case META_PLUS_QUERY: fprintf(stderr, \"META +?\"); break;\n    case META_PLUS_PLUS: fprintf(stderr, \"META ++\"); break;\n    case META_QUERY: fprintf(stderr, \"META ?\"); break;\n    case META_QUERY_QUERY: fprintf(stderr, \"META ??\"); break;\n    case META_QUERY_PLUS: fprintf(stderr, \"META ?+\"); break;\n\n    case META_ATOMIC: fprintf(stderr, \"META (?>\"); break;\n    case META_NOCAPTURE: fprintf(stderr, \"META (?:\"); break;\n    case META_LOOKAHEAD: fprintf(stderr, \"META (?=\"); break;\n    case META_LOOKAHEADNOT: fprintf(stderr, \"META (?!\"); break;\n    case META_LOOKAHEAD_NA: fprintf(stderr, \"META (*napla:\"); break;\n    case META_SCRIPT_RUN: fprintf(stderr, \"META (*sr:\"); break;\n    case META_KET: fprintf(stderr, \"META )\"); break;\n    case META_ALT: fprintf(stderr, \"META | %d\", meta_arg); break;\n\n    case META_CLASS: fprintf(stderr, \"META [\"); break;\n    case META_CLASS_NOT: fprintf(stderr, \"META [^\"); break;\n    case META_CLASS_END: fprintf(stderr, \"META ]\"); break;\n    case META_CLASS_EMPTY: fprintf(stderr, \"META []\"); break;\n    case META_CLASS_EMPTY_NOT: fprintf(stderr, \"META [^]\"); break;\n\n    case META_RANGE_LITERAL: fprintf(stderr, \"META - (literal)\"); break;\n    case META_RANGE_ESCAPED: fprintf(stderr, \"META - (escaped)\"); break;\n\n    case META_POSIX: fprintf(stderr, \"META_POSIX %d\", *pptr++); break;\n    case META_POSIX_NEG: fprintf(stderr, \"META_POSIX_NEG %d\", *pptr++); break;\n\n    case META_ACCEPT: fprintf(stderr, \"META (*ACCEPT)\"); break;\n    case META_FAIL: fprintf(stderr, \"META (*FAIL)\"); break;\n    case META_COMMIT: fprintf(stderr, \"META (*COMMIT)\"); break;\n    case META_PRUNE: fprintf(stderr, \"META (*PRUNE)\"); break;\n    case META_SKIP: fprintf(stderr, \"META (*SKIP)\"); break;\n    case META_THEN: fprintf(stderr, \"META (*THEN)\"); break;\n\n    case META_OPTIONS:\n    fprintf(stderr, \"META_OPTIONS 0x%08x 0x%08x\", pptr[0], pptr[1]);\n    pptr += 2;\n    break;\n\n    case META_LOOKBEHIND:\n    fprintf(stderr, \"META (?<= %d %d\", meta_arg, *pptr);\n    pptr += 2;\n    break;\n\n    case META_LOOKBEHIND_NA:\n    fprintf(stderr, \"META (*naplb: %d %d\", meta_arg, *pptr);\n    pptr += 2;\n    break;\n\n    case META_LOOKBEHINDNOT:\n    fprintf(stderr, \"META (?<! %d %d\", meta_arg, *pptr);\n    pptr += 2;\n    break;\n\n    case META_CALLOUT_NUMBER:\n    fprintf(stderr, \"META (?C%d) next=%d/%d\", pptr[2], pptr[0],\n       pptr[1]);\n    pptr += 3;\n    break;\n\n    case META_CALLOUT_STRING:\n      {\n      uint32_t patoffset = *pptr++;    /* Offset of next pattern item */\n      uint32_t patlength = *pptr++;    /* Length of next pattern item */\n      fprintf(stderr, \"META (?Cstring) length=%d offset=\", *pptr++);\n      GETOFFSET(offset, pptr);\n      fprintf(stderr, \"%zd next=%d/%d\", offset, patoffset, patlength);\n      }\n    break;\n\n    case META_RECURSE_BYNAME:\n    fprintf(stderr, \"META (?(&name) length=%d offset=\", *pptr++);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_BACKREF_BYNAME:\n    fprintf(stderr, \"META_BACKREF_BYNAME length=%d offset=\", *pptr++);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_COND_NUMBER:\n    fprintf(stderr, \"META_COND_NUMBER %d offset=\", pptr[SIZEOFFSET]);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    pptr++;\n    break;\n\n    case META_COND_DEFINE:\n    fprintf(stderr, \"META (?(DEFINE) offset=\");\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_COND_VERSION:\n    fprintf(stderr, \"META (?(VERSION%s\", (*pptr++ == 0)? \"=\" : \">=\");\n    fprintf(stderr, \"%d.\", *pptr++);\n    fprintf(stderr, \"%d)\", *pptr++);\n    break;\n\n    case META_COND_NAME:\n    fprintf(stderr, \"META (?(<name>) length=%d offset=\", *pptr++);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_COND_RNAME:\n    fprintf(stderr, \"META (?(R&name) length=%d offset=\", *pptr++);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    /* This is kept as a name, because it might be. */\n\n    case META_COND_RNUMBER:\n    fprintf(stderr, \"META (?(Rnumber) length=%d offset=\", *pptr++);\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_OFFSET:\n    fprintf(stderr, \"META_OFFSET offset=\");\n    GETOFFSET(offset, pptr);\n    fprintf(stderr, \"%zd\", offset);\n    break;\n\n    case META_SCS:\n    fprintf(stderr, \"META (*scan_substring:\");\n    break;\n\n    case META_CAPTURE_NAME:\n    fprintf(stderr, \"META_CAPTURE_NAME length=%d relative_offset=%d\", *pptr++, (int)meta_arg);\n    break;\n\n    case META_CAPTURE_NUMBER:\n    fprintf(stderr, \"META_CAPTURE_NUMBER %d relative_offset=%d\", *pptr++, (int)meta_arg);\n    break;\n\n    case META_MARK:\n    fprintf(stderr, \"META (*MARK:\");\n    goto SHOWARG;\n\n    case META_COMMIT_ARG:\n    fprintf(stderr, \"META (*COMMIT:\");\n    goto SHOWARG;\n\n    case META_PRUNE_ARG:\n    fprintf(stderr, \"META (*PRUNE:\");\n    goto SHOWARG;\n\n    case META_SKIP_ARG:\n    fprintf(stderr, \"META (*SKIP:\");\n    goto SHOWARG;\n\n    case META_THEN_ARG:\n    fprintf(stderr, \"META (*THEN:\");\n    SHOWARG:\n    length = *pptr++;\n    for (i = 0; i < length; i++)\n      {\n      uint32_t cc = *pptr++;\n      if (cc > 32 && cc < 128) fprintf(stderr, \"%c\", cc);\n        else fprintf(stderr, \"\\\\x{%x}\", cc);\n      }\n    fprintf(stderr, \") length=%u\", length);\n    break;\n\n    case META_ECLASS_AND: fprintf(stderr, \"META_ECLASS_AND\"); break;\n    case META_ECLASS_OR: fprintf(stderr, \"META_ECLASS_OR\"); break;\n    case META_ECLASS_SUB: fprintf(stderr, \"META_ECLASS_SUB\"); break;\n    case META_ECLASS_XOR: fprintf(stderr, \"META_ECLASS_XOR\"); break;\n    case META_ECLASS_NOT: fprintf(stderr, \"META_ECLASS_NOT\"); break;\n    }\n  fprintf(stderr, \"\\n\");\n  }\nreturn;\n}\n#endif  /* DEBUG_SHOW_PARSED */\n\n\n\n/*************************************************\n*               Copy compiled code               *\n*************************************************/\n\n/* Compiled JIT code cannot be copied, so the new compiled block has no\nassociated JIT data. */\n\nPCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION\npcre2_code_copy(const pcre2_code *code)\n{\nPCRE2_SIZE *ref_count;\npcre2_code *newcode;\n\nif (code == NULL) return NULL;\nnewcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);\nif (newcode == NULL) return NULL;\nmemcpy(newcode, code, code->blocksize);\nnewcode->executable_jit = NULL;\n\n/* If the code is one that has been deserialized, increment the reference count\nin the decoded tables. */\n\nif ((code->flags & PCRE2_DEREF_TABLES) != 0)\n  {\n  ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);\n  (*ref_count)++;\n  }\n\nreturn newcode;\n}\n\n\n\n/*************************************************\n*     Copy compiled code and character tables    *\n*************************************************/\n\n/* Compiled JIT code cannot be copied, so the new compiled block has no\nassociated JIT data. This version of code_copy also makes a separate copy of\nthe character tables. */\n\nPCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION\npcre2_code_copy_with_tables(const pcre2_code *code)\n{\nPCRE2_SIZE* ref_count;\npcre2_code *newcode;\nuint8_t *newtables;\n\nif (code == NULL) return NULL;\nnewcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);\nif (newcode == NULL) return NULL;\nmemcpy(newcode, code, code->blocksize);\nnewcode->executable_jit = NULL;\n\nnewtables = code->memctl.malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE),\n  code->memctl.memory_data);\nif (newtables == NULL)\n  {\n  code->memctl.free((void *)newcode, code->memctl.memory_data);\n  return NULL;\n  }\nmemcpy(newtables, code->tables, TABLES_LENGTH);\nref_count = (PCRE2_SIZE *)(newtables + TABLES_LENGTH);\n*ref_count = 1;\n\nnewcode->tables = newtables;\nnewcode->flags |= PCRE2_DEREF_TABLES;\nreturn newcode;\n}\n\n\n\n/*************************************************\n*               Free compiled code               *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_code_free(pcre2_code *code)\n{\nPCRE2_SIZE* ref_count;\n\nif (code != NULL)\n  {\n#ifdef SUPPORT_JIT\n  if (code->executable_jit != NULL)\n    PRIV(jit_free)(code->executable_jit, &code->memctl);\n#endif\n\n  if ((code->flags & PCRE2_DEREF_TABLES) != 0)\n    {\n    /* Decoded tables belong to the codes after deserialization, and they must\n    be freed when there are no more references to them. The *ref_count should\n    always be > 0. */\n\n    ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);\n    if (*ref_count > 0)\n      {\n      (*ref_count)--;\n      if (*ref_count == 0)\n        code->memctl.free((void *)code->tables, code->memctl.memory_data);\n      }\n    }\n\n  code->memctl.free(code, code->memctl.memory_data);\n  }\n}\n\n\n\n/*************************************************\n*         Read a number, possibly signed         *\n*************************************************/\n\n/* This function is used to read numbers in the pattern. The initial pointer\nmust be at the sign or first digit of the number. When relative values\n(introduced by + or -) are allowed, they are relative group numbers, and the\nresult must be greater than zero.\n\nArguments:\n  ptrptr      points to the character pointer variable\n  ptrend      points to the end of the input string\n  allow_sign  if < 0, sign not allowed; if >= 0, sign is relative to this\n  max_value   the largest number allowed;\n              you must not pass a value for max_value larger than\n              INT_MAX/10 - 1 because this function relies on max_value to\n              avoid integer overflow\n  max_error   the error to give for an over-large number\n  intptr      where to put the result\n  errcodeptr  where to put an error code\n\nReturns:      TRUE  - a number was read\n              FALSE - errorcode == 0 => no number was found\n                      errorcode != 0 => an error occurred\n*/\n\nstatic BOOL\nread_number(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, int32_t allow_sign,\n  uint32_t max_value, uint32_t max_error, int *intptr, int *errorcodeptr)\n{\nint sign = 0;\nuint32_t n = 0;\nPCRE2_SPTR ptr = *ptrptr;\nBOOL yield = FALSE;\n\nPCRE2_ASSERT(max_value <= INT_MAX/10 - 1);\n\n*errorcodeptr = 0;\n\nif (allow_sign >= 0 && ptr < ptrend)\n  {\n  if (*ptr == CHAR_PLUS)\n    {\n    sign = +1;\n    max_value -= allow_sign;\n    ptr++;\n    }\n  else if (*ptr == CHAR_MINUS)\n    {\n    sign = -1;\n    ptr++;\n    }\n  }\n\nif (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE;\nwhile (ptr < ptrend && IS_DIGIT(*ptr))\n  {\n  n = n * 10 + (*ptr++ - CHAR_0);\n  if (n > max_value)\n    {\n    *errorcodeptr = max_error;\n    while (ptr < ptrend && IS_DIGIT(*ptr)) ptr++;\n    goto EXIT;\n    }\n  }\n\nif (allow_sign >= 0 && sign != 0)\n  {\n  if (n == 0)\n    {\n    *errorcodeptr = ERR26;  /* +0 and -0 are not allowed */\n    goto EXIT;\n    }\n\n  if (sign > 0) n += allow_sign;\n  else if (n > (uint32_t)allow_sign)\n    {\n    *errorcodeptr = ERR15;  /* Non-existent subpattern */\n    goto EXIT;\n    }\n  else n = allow_sign + 1 - n;\n  }\n\nyield = TRUE;\n\nEXIT:\n*intptr = n;\n*ptrptr = ptr;\nreturn yield;\n}\n\n\n\n/*************************************************\n*         Read repeat counts                     *\n*************************************************/\n\n/* Read an item of the form {n,m} and return the values when non-NULL pointers\nare supplied. Repeat counts must be less than 65536 (MAX_REPEAT_COUNT); a\nlarger value is used for \"unlimited\". We have to use signed arguments for\nread_number() because it is capable of returning a signed value. As of Perl\n5.34.0 either n or m may be absent, but not both. Perl also allows spaces and\ntabs after { and before } and between the numbers and the comma, so we do too.\n\nArguments:\n  ptrptr         points to pointer to character after '{'\n  ptrend         pointer to end of input\n  minp           if not NULL, pointer to int for min\n  maxp           if not NULL, pointer to int for max\n  errorcodeptr   points to error code variable\n\nReturns:         FALSE if not a repeat quantifier, errorcode set zero\n                 FALSE on error, with errorcode set non-zero\n                 TRUE on success, with pointer updated to point after '}'\n*/\n\nstatic BOOL\nread_repeat_counts(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *minp,\n  uint32_t *maxp, int *errorcodeptr)\n{\nPCRE2_SPTR p = *ptrptr;\nPCRE2_SPTR pp;\nBOOL yield = FALSE;\nBOOL had_minimum = FALSE;\nint32_t min = 0;\nint32_t max = REPEAT_UNLIMITED; /* This value is larger than MAX_REPEAT_COUNT */\n\n*errorcodeptr = 0;\nwhile (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n\n/* Check the syntax before interpreting. Otherwise, a non-quantifier sequence\nsuch as \"X{123456ABC\" would incorrectly give a \"number too big in quantifier\"\nerror. */\n\npp = p;\nif (pp < ptrend && IS_DIGIT(*pp))\n  {\n  had_minimum = TRUE;\n  while (++pp < ptrend && IS_DIGIT(*pp)) {}\n  }\n\nwhile (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++;\nif (pp >= ptrend) return FALSE;\n\nif (*pp == CHAR_RIGHT_CURLY_BRACKET)\n  {\n  if (!had_minimum) return FALSE;\n  }\nelse\n  {\n  if (*pp++ != CHAR_COMMA) return FALSE;\n  while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++;\n  if (pp >= ptrend) return FALSE;\n  if (IS_DIGIT(*pp))\n    {\n    while (++pp < ptrend && IS_DIGIT(*pp)) {}\n    }\n  else if (!had_minimum) return FALSE;\n  while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++;\n  if (pp >= ptrend || *pp != CHAR_RIGHT_CURLY_BRACKET) return FALSE;\n  }\n\n/* Now process the quantifier for real. We know it must be {n} or {n,} or {,m}\nor {n,m}. The only error that read_number() can return is for a number that is\ntoo big. If *errorcodeptr is returned as zero it means no number was found. */\n\n/* Deal with {,m} or n too big. If we successfully read m there is no need to\ncheck m >= n because n defaults to zero. */\n\nif (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr))\n  {\n  if (*errorcodeptr != 0) goto EXIT;    /* n too big */\n  p++;  /* Skip comma and subsequent spaces */\n  while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n  if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr))\n    {\n    if (*errorcodeptr != 0) goto EXIT;  /* m too big */\n    }\n  }\n\n/* Have read one number. Deal with {n} or {n,} or {n,m} */\n\nelse\n  {\n  while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n  if (*p == CHAR_RIGHT_CURLY_BRACKET)\n    {\n    max = min;\n    }\n  else   /* Handle {n,} or {n,m} */\n    {\n    p++;    /* Skip comma and subsequent spaces */\n    while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n    if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr))\n      {\n      if (*errorcodeptr != 0) goto EXIT;   /* m too big */\n      }\n\n    if (max < min)\n      {\n      *errorcodeptr = ERR4;\n      goto EXIT;\n      }\n    }\n  }\n\n/* Valid quantifier exists */\n\nwhile (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\np++;\nyield = TRUE;\nif (minp != NULL) *minp = (uint32_t)min;\nif (maxp != NULL) *maxp = (uint32_t)max;\n\n/* Update the pattern pointer */\n\nEXIT:\n*ptrptr = p;\nreturn yield;\n}\n\n\n\n/*************************************************\n*            Handle escapes                      *\n*************************************************/\n\n/* This function is called when a \\ has been encountered. It either returns a\npositive value for a simple escape such as \\d, or 0 for a data character, which\nis placed in chptr. A backreference to group n is returned as -(n+1). On\nentry, ptr is pointing at the character after \\. On exit, it points after the\nfinal code unit of the escape sequence.\n\nThis function is also called from pcre2_substitute() to handle escape sequences\nin replacement strings. In this case, the cb argument is NULL, and in the case\nof escapes that have further processing, only sequences that define a data\ncharacter are recognised. The options argument is the final value of the\ncompiled pattern's options.\n\nArguments:\n  ptrptr         points to the input position pointer\n  ptrend         points to the end of the input\n  chptr          points to a returned data character\n  errorcodeptr   points to the errorcode variable (containing zero)\n  options        the current options bits\n  xoptions       the current extra options bits\n  bracount       the number of capturing parentheses encountered so far\n  isclass        TRUE if in a character class\n  cb             compile data block or NULL when called from pcre2_substitute()\n\nReturns:         zero => a data character\n                 positive => a special escape sequence\n                 negative => a numerical back reference\n                 on error, errorcodeptr is set non-zero\n*/\n\nint\nPRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr,\n  int *errorcodeptr, uint32_t options, uint32_t xoptions, uint32_t bracount,\n  BOOL isclass, compile_block *cb)\n{\nBOOL utf = (options & PCRE2_UTF) != 0;\nBOOL alt_bsux =\n  ((options & PCRE2_ALT_BSUX) | (xoptions & PCRE2_EXTRA_ALT_BSUX)) != 0;\nPCRE2_SPTR ptr = *ptrptr;\nuint32_t c, cc;\nint escape = 0;\nint i;\n\n/* If backslash is at the end of the string, it's an error. */\n\nif (ptr >= ptrend)\n  {\n  *errorcodeptr = ERR1;\n  return 0;\n  }\n\nGETCHARINCTEST(c, ptr);         /* Get character value, increment pointer */\n*errorcodeptr = 0;              /* Be optimistic */\n\n/* Non-alphanumerics are literals, so we just leave the value in c. An initial\nvalue test saves a memory lookup for code points outside the alphanumeric\nrange. */\n\nif (c < ESCAPES_FIRST || c > ESCAPES_LAST) {}  /* Definitely literal */\n\n/* Otherwise, do a table lookup. Non-zero values need little processing here. A\npositive value is a literal value for something like \\n. A negative value is\nthe negation of one of the ESC_ macros that is passed back for handling by the\ncalling function. Some extra checking is needed for \\N because only \\N{U+dddd}\nis supported. If the value is zero, further processing is handled below. */\n\nelse if ((i = escapes[c - ESCAPES_FIRST]) != 0)\n  {\n  if (i > 0)\n    {\n    c = (uint32_t)i;\n    if (c == CHAR_CR && (xoptions & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0)\n      c = CHAR_LF;\n    }\n  else  /* Negative table entry */\n    {\n    escape = -i;                    /* Else return a special escape */\n    if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X))\n      cb->external_flags |= PCRE2_HASBKPORX;   /* Note \\P, \\p, or \\X */\n\n    /* Perl supports \\N{name} for character names and \\N{U+dddd} for numerical\n    Unicode code points, as well as plain \\N for \"not newline\". PCRE does not\n    support \\N{name}. However, it does support quantification such as \\N{2,3},\n    so if \\N{ is not followed by U+dddd we check for a quantifier. */\n\n    if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)\n      {\n      PCRE2_SPTR p = ptr + 1;\n\n      /* Perl ignores spaces and tabs after { */\n\n      while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n\n      /* \\N{U+ can be handled by the \\x{ code. However, this construction is\n      not valid in EBCDIC environments because it specifies a Unicode\n      character, not a codepoint in the local code. For example \\N{U+0041}\n      must be \"A\" in all environments. Also, in Perl, \\N{U+ forces Unicode\n      casing semantics for the entire pattern, so allow it only in UTF (i.e.\n      Unicode) mode. */\n\n      if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS)\n        {\n#ifndef EBCDIC\n        if (utf)\n          {\n          ptr = p + 2;\n          escape = 0;   /* Not a fancy escape after all */\n          goto COME_FROM_NU;\n          }\n#endif\n\n        /* Improve error offset. */\n        ptr = p + 2;\n        while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;\n        while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n        if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET) ptr++;\n\n        *errorcodeptr = ERR93;\n        }\n\n      /* Give an error in contexts where quantifiers are not allowed\n      (character classes; substitution strings). */\n\n      else if (isclass || cb == NULL)\n        {\n        ptr++; /* Skip over the opening brace */\n        *errorcodeptr = ERR37;\n        }\n\n      /* Give an error if what follows is not a quantifier, but don't override\n      an error set by the quantifier reader (e.g. number overflow). */\n\n      else\n        {\n        if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&\n             *errorcodeptr == 0)\n          {\n          ptr++; /* Skip over the opening brace */\n          *errorcodeptr = ERR37;\n          }\n        }\n      }\n    }\n  }\n\n/* Escapes that need further processing, including those that are unknown, have\na zero entry in the lookup table. When called from pcre2_substitute(), only \\c,\n\\o, and \\x are recognized (\\u and \\U can never appear as they are used for case\nforcing). */\n\nelse\n  {\n  int s;\n  PCRE2_SPTR oldptr;\n  BOOL overflow;\n\n  /* Filter calls from pcre2_substitute(). */\n\n  if (cb == NULL)\n    {\n    if (!(c >= CHAR_0 && c <= CHAR_9) && c != CHAR_c && c != CHAR_o &&\n        c != CHAR_x && c != CHAR_g)\n      {\n      *errorcodeptr = ERR3;\n      goto EXIT;\n      }\n    alt_bsux = FALSE;   /* Do not modify \\x handling */\n    }\n\n  switch (c)\n    {\n    /* A number of Perl escapes are not handled by PCRE. We give an explicit\n    error. */\n\n    case CHAR_F:\n    case CHAR_l:\n    case CHAR_L:\n    *errorcodeptr = ERR37;\n    break;\n\n    /* \\u is unrecognized when neither PCRE2_ALT_BSUX nor PCRE2_EXTRA_ALT_BSUX\n    is set. Otherwise, \\u must be followed by exactly four hex digits or, if\n    PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces.\n    Otherwise it is a lowercase u letter. This gives some compatibility with\n    ECMAScript (aka JavaScript). Unlike other braced items, white space is NOT\n    allowed. When \\u{ is not followed by hex digits, a special return is given\n    because otherwise \\u{ 12} (for example) would be treated as u{12}. */\n\n    case CHAR_u:\n    if (!alt_bsux)\n      *errorcodeptr = ERR37;\n    else\n      {\n      uint32_t xc;\n\n      if (ptr >= ptrend) break;\n      if (*ptr == CHAR_LEFT_CURLY_BRACKET &&\n          (xoptions & PCRE2_EXTRA_ALT_BSUX) != 0)\n        {\n        PCRE2_SPTR hptr = ptr + 1;\n\n        cc = 0;\n        while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff)\n          {\n          if ((cc & 0xf0000000) != 0)  /* Test for 32-bit overflow */\n            {\n            *errorcodeptr = ERR77;\n            ptr = hptr;   /* Show where */\n            break;        /* *hptr != } will cause another break below */\n            }\n          cc = (cc << 4) | xc;\n          hptr++;\n          }\n\n        if (hptr == ptr + 1 ||   /* No hex digits */\n            hptr >= ptrend ||    /* Hit end of input */\n            *hptr != CHAR_RIGHT_CURLY_BRACKET)  /* No } terminator */\n          {\n          if (isclass) break; /* In a class, just treat as '\\u' literal */\n          escape = ESC_ub;    /* Special return */\n          ptr++;              /* Skip { */\n          break;              /* Hex escape not recognized */\n          }\n\n        c = cc;          /* Accept the code point */\n        ptr = hptr + 1;\n        }\n\n      else  /* Must be exactly 4 hex digits */\n        {\n        if (ptrend - ptr < 4) break;               /* Less than 4 chars */\n        if ((cc = XDIGIT(ptr[0])) == 0xff) break;  /* Not a hex digit */\n        if ((xc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */\n        cc = (cc << 4) | xc;\n        if ((xc = XDIGIT(ptr[2])) == 0xff) break;  /* Not a hex digit */\n        cc = (cc << 4) | xc;\n        if ((xc = XDIGIT(ptr[3])) == 0xff) break;  /* Not a hex digit */\n        c = (cc << 4) | xc;\n        ptr += 4;\n        }\n\n      if (utf)\n        {\n        if (c > 0x10ffffU) *errorcodeptr = ERR77;\n        else\n          if (c >= 0xd800 && c <= 0xdfff &&\n              (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)\n                *errorcodeptr = ERR73;\n        }\n      else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;\n      }\n    break;\n\n    /* \\U is unrecognized unless PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set,\n    in which case it is an upper case letter. */\n\n    case CHAR_U:\n    if (!alt_bsux) *errorcodeptr = ERR37;\n    break;\n\n    /* In a character class, \\g is just a literal \"g\". Outside a character\n    class, \\g must be followed by one of a number of specific things:\n\n    (1) A number, either plain or braced. If positive, it is an absolute\n    backreference. If negative, it is a relative backreference. This is a Perl\n    5.10 feature.\n\n    (2) Perl 5.10 also supports \\g{name} as a reference to a named group. This\n    is part of Perl's movement towards a unified syntax for back references. As\n    this is synonymous with \\k{name}, we fudge it up by pretending it really\n    was \\k{name}.\n\n    (3) For Oniguruma compatibility we also support \\g followed by a name or a\n    number either in angle brackets or in single quotes. However, these are\n    (possibly recursive) subroutine calls, _not_ backreferences. We return\n    the ESC_g code.\n\n    Summary: Return a negative number for a numerical back reference (offset\n    by 1), ESC_k for a named back reference, and ESC_g for a named or\n    numbered subroutine call.\n\n    The above describes the \\g behaviour inside patterns. Inside replacement\n    strings (pcre2_substitute) we support only \\g<nameornum> for Python\n    compatibility. Return ESG_g for the named case, and -(num+1) for the\n    numbered case.\n    */\n\n    case CHAR_g:\n    if (isclass) break;\n\n    if (ptr >= ptrend)\n      {\n      *errorcodeptr = ERR57;\n      break;\n      }\n\n    if (cb == NULL)\n      {\n      PCRE2_SPTR p;\n      /* Substitution strings */\n      if (*ptr != CHAR_LESS_THAN_SIGN)\n        {\n        *errorcodeptr = ERR57;\n        break;\n        }\n\n      p = ptr + 1;\n\n      if (!read_number(&p, ptrend, -1, MAX_GROUP_NUMBER, ERR61, &s,\n          errorcodeptr))\n        {\n        if (*errorcodeptr == 0) escape = ESC_g;  /* No number found */\n        break;\n        }\n\n      if (p >= ptrend || *p != CHAR_GREATER_THAN_SIGN)\n        {\n        ptr = p;\n        *errorcodeptr = ERR119;  /* Missing terminator for number */\n        break;\n        }\n\n      /* This is the reason that back references are returned as -(s+1) rather\n      than just -s. In a pattern, \\0 is not a back reference, but \\g<0> is\n      valid in a substitution string, so this must be representable. */\n      ptr = p + 1;\n      escape = -(s+1);\n      break;\n      }\n\n    if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE)\n      {\n      escape = ESC_g;\n      break;\n      }\n\n    /* If there is a brace delimiter, try to read a numerical reference. If\n    there isn't one, assume we have a name and treat it as \\k. */\n\n    if (*ptr == CHAR_LEFT_CURLY_BRACKET)\n      {\n      PCRE2_SPTR p = ptr + 1;\n\n      while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n      if (!read_number(&p, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s,\n          errorcodeptr))\n        {\n        if (*errorcodeptr == 0) escape = ESC_k;  /* No number found */\n        break;\n        }\n      while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++;\n\n      if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)\n        {\n        ptr = p;\n        *errorcodeptr = ERR119;  /* Missing terminator for number */\n        break;\n        }\n      ptr = p + 1;\n      }\n\n    /* Read an undelimited number */\n\n    else\n      {\n      if (!read_number(&ptr, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s,\n          errorcodeptr))\n        {\n        if (*errorcodeptr == 0) *errorcodeptr = ERR57;  /* No number found */\n        break;\n        }\n      }\n\n    if (s <= 0)\n      {\n      *errorcodeptr = ERR15;\n      break;\n      }\n\n    escape = -(s+1);\n    break;\n\n    /* The handling of escape sequences consisting of a string of digits\n    starting with one that is not zero is not straightforward. Perl has changed\n    over the years. Nowadays \\g{} for backreferences and \\o{} for octal are\n    recommended to avoid the ambiguities in the old syntax.\n\n    Outside a character class, the digits are read as a decimal number. If the\n    number is less than 10, or if there are that many previous extracting left\n    brackets, it is a back reference. Otherwise, up to three octal digits are\n    read to form an escaped character code. Thus \\123 is likely to be octal 123\n    (cf \\0123, which is octal 012 followed by the literal 3). This is the \"Perl\n    style\" of handling ambiguous octal/backrefences such as \\12.\n\n    There is an alternative disambiguation strategy, selected by\n    PCRE2_EXTRA_PYTHON_OCTAL, which follows Python's behaviour. An octal must\n    have either a leading zero, or exactly three octal digits; otherwise it's\n    a backreference. The disambiguation is stable, and does not depend on how\n    many capture groups are defined (it's simply an invalid backreference if\n    there is no corresponding capture group). Additionally, octal values above\n    \\377 (\\xff) are rejected.\n\n    Inside a character class, \\ followed by a digit is always either a literal\n    8 or 9 or an octal number. */\n\n    case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:\n    case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:\n\n    if (isclass)\n      {\n      /* Fall through to octal handling; never a backreference inside a class. */\n      }\n    else if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0)\n      {\n      /* Python-style disambiguation. */\n      if (ptr[-1] <= CHAR_7 && ptr + 1 < ptrend && ptr[0] >= CHAR_0 &&\n          ptr[0] <= CHAR_7 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)\n        {\n        /* We peeked a three-digit octal, so fall through */\n        }\n      else\n        {\n        /* We are at a digit, so the only possible error from read_number() is\n        a number that is too large. */\n        ptr--;   /* Back to the digit */\n\n        if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr))\n          {\n          *errorcodeptr = ERR61;\n          break;\n          }\n\n        escape = -(s+1);\n        break;\n        }\n      }\n    else\n      {\n      /* Perl-style disambiguation. */\n      oldptr = ptr;\n      ptr--;   /* Back to the digit */\n\n      /* As we know we are at a digit, the only possible error from\n      read_number() is a number that is too large to be a group number. Because\n      that number might be still valid if read as an octal, errorcodeptr is not\n      set on failure and therefore a sentinel value of INT_MAX is used instead\n      of the original value, and will be used later to properly set the error,\n      if not falling through. */\n\n      if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr))\n        s = INT_MAX;\n\n      /* \\1 to \\9 are always back references. \\8x and \\9x are too; \\1x to \\7x\n      are octal escapes if there are not that many previous captures. */\n\n      if (s < 10 || c >= CHAR_8 || (unsigned)s <= bracount)\n        {\n        /* s > MAX_GROUP_NUMBER should not be possible because of read_number(),\n        but we keep it just to be safe and because it will also catch the\n        sentinel value that was set on failure by that function. */\n\n        if ((unsigned)s > MAX_GROUP_NUMBER)\n          {\n          PCRE2_ASSERT(s == INT_MAX);\n          *errorcodeptr = ERR61;\n          }\n        else escape = -(s+1);     /* Indicates a back reference */\n        break;\n        }\n\n      ptr = oldptr;      /* Put the pointer back and fall through */\n      }\n\n    /* Handle a digit following \\ when the number is not a back reference, or\n    we are within a character class. If the first digit is 8 or 9, Perl used to\n    generate a binary zero and then treat the digit as a following literal. At\n    least by Perl 5.18 this changed so as not to insert the binary zero. */\n\n    if (c >= CHAR_8) break;\n\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* \\0 always starts an octal number, but we may drop through to here with a\n    larger first octal digit. The original code used just to take the least\n    significant 8 bits of octal numbers (I think this is what early Perls used\n    to do). Nowadays we allow for larger numbers in UTF-8 mode and 16/32-bit mode,\n    but no more than 3 octal digits. */\n\n    case CHAR_0:\n    c -= CHAR_0;\n    while(i++ < 2 && ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)\n        c = c * 8 + *ptr++ - CHAR_0;\n    if (c > 0xff)\n      {\n      if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0) *errorcodeptr = ERR102;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      else if (!utf) *errorcodeptr = ERR51;\n#endif\n      }\n\n    /* PCRE2_EXTRA_NO_BS0 disables the NUL escape '\\0' but doesn't affect\n    two- or three-character octal escapes \\00 and \\000, nor \\x00. */\n\n    if ((xoptions & PCRE2_EXTRA_NO_BS0) != 0 && c == 0 && i == 1)\n        *errorcodeptr = ERR98;\n    break;\n\n    /* \\o is a relatively new Perl feature, supporting a more general way of\n    specifying character codes in octal. The only supported form is \\o{ddd},\n    with optional spaces or tabs after { and before }. */\n\n    case CHAR_o:\n    if (ptr >= ptrend || *ptr != CHAR_LEFT_CURLY_BRACKET)\n      {\n      *errorcodeptr = ERR55;\n      break;\n      }\n    ptr++;\n\n    while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n    if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)\n      {\n      *errorcodeptr = ERR78;\n      break;\n      }\n\n    c = 0;\n    overflow = FALSE;\n    while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)\n      {\n      cc = *ptr++;\n      if (c == 0 && cc == CHAR_0) continue;     /* Leading zeroes */\n#if PCRE2_CODE_UNIT_WIDTH == 32\n      if (c >= 0x20000000u) { overflow = TRUE; break; }\n#endif\n      c = (c << 3) + (cc - CHAR_0);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n      if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n      if (utf && c > 0x10ffffU) { overflow = TRUE; break; }\n#endif\n      }\n\n    while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n\n    if (overflow)\n      {\n      while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;\n      *errorcodeptr = ERR34;\n      }\n    else if (utf && c >= 0xd800 && c <= 0xdfff &&\n             (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)\n      {\n      *errorcodeptr = ERR73;\n      }\n    else if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET)\n      {\n      ptr++;\n      }\n    else\n      {\n      *errorcodeptr = ERR64;\n      goto ESCAPE_FAILED_FORWARD;\n      }\n    break;\n\n    /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \\x must be followed\n    by two hexadecimal digits. Otherwise it is a lowercase x letter. */\n\n    case CHAR_x:\n    if (alt_bsux)\n      {\n      uint32_t xc;\n      if (ptrend - ptr < 2) break;               /* Less than 2 characters */\n      if ((cc = XDIGIT(ptr[0])) == 0xff) break;  /* Not a hex digit */\n      if ((xc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */\n      c = (cc << 4) | xc;\n      ptr += 2;\n      }\n\n    /* Handle \\x in Perl's style. \\x{ddd} is a character code which can be\n    greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex\n    digits. If not, { used to be treated as a data character. However, Perl\n    seems to read hex digits up to the first non-such, and ignore the rest, so\n    that, for example \\x{zz} matches a binary zero. This seems crazy, so PCRE\n    now gives an error. */\n\n    else\n      {\n      if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)\n        {\n        ptr++;\n        while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n\n#ifndef EBCDIC\n        COME_FROM_NU:\n#endif\n        if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)\n          {\n          *errorcodeptr = ERR78;\n          break;\n          }\n        c = 0;\n        overflow = FALSE;\n\n        while (ptr < ptrend && (cc = XDIGIT(*ptr)) != 0xff)\n          {\n          ptr++;\n          if (c == 0 && cc == 0) continue;   /* Leading zeroes */\n#if PCRE2_CODE_UNIT_WIDTH == 32\n          if (c >= 0x10000000l) { overflow = TRUE; break; }\n#endif\n          c = (c << 4) | cc;\n          if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR))\n            {\n            overflow = TRUE;\n            break;\n            }\n          }\n\n        /* Perl ignores spaces and tabs before } */\n\n        while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n\n        /* On overflow, skip remaining hex digits */\n\n        if (overflow)\n          {\n          while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;\n          *errorcodeptr = ERR34;\n          }\n        else if (utf && c >= 0xd800 && c <= 0xdfff &&\n                 (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)\n          {\n          *errorcodeptr = ERR73;\n          }\n        else if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET)\n          {\n          ptr++;\n          }\n\n        /* If the sequence of hex digits (followed by optional space) does not\n        end with '}', give an error. We used just to recognize this construct\n        and fall through to the normal \\x handling, but nowadays Perl gives an\n        error, which seems much more sensible, so we do too. */\n\n        else\n          {\n          *errorcodeptr = ERR67;\n          goto ESCAPE_FAILED_FORWARD;\n          }\n        }   /* End of \\x{} processing */\n\n      /* Read a up to two hex digits after \\x */\n\n      else\n        {\n        /* Perl has the surprising/broken behaviour that \\x without following\n        hex digits is treated as an escape for NUL. Their source code laments\n        this but keeps it for backwards compatibility. A warning is printed\n        when \"use warnings\" is enabled. Because we don't have warnings, we\n        simply forbid it. */\n        if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff)\n          {\n          /* Not a hex digit */\n          *errorcodeptr = ERR78;\n          break;\n          }\n        ptr++;\n        c = cc;\n\n        /* With \"use re 'strict'\" Perl actually requires exactly two digits (error\n        for \\x, \\xA and \\xAAA). While \\x was already rejected, this seems overly\n        strict, and there seems little incentive to align with that, given the\n        backwards-compatibility cost.\n\n        For comparison, note that other engines disagree. For example:\n          - Java allows 1 or 2 hex digits. Error if 0 digits. No error if >2 digits\n          - .NET requires 2 hex digits. Error if 0, 1 digits. No error if >2 digits.\n        */\n        if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break;  /* Not a hex digit */\n        ptr++;\n        c = (c << 4) | cc;\n        }     /* End of \\xdd handling */\n      }       /* End of Perl-style \\x handling */\n    break;\n\n    /* The handling of \\c is different in ASCII and EBCDIC environments. In an\n    ASCII (or Unicode) environment, an error is given if the character\n    following \\c is not a printable ASCII character. Otherwise, the following\n    character is upper-cased if it is a letter, and after that the 0x40 bit is\n    flipped. The result is the value of the escape.\n\n    In an EBCDIC environment the handling of \\c is compatible with the\n    specification in the perlebcdic document. The following character must be\n    a letter or one of small number of special characters. These provide a\n    means of defining the character values 0-31.\n\n    For testing the EBCDIC handling of \\c in an ASCII environment, recognize\n    the EBCDIC value of 'c' explicitly. */\n\n    case CHAR_c:\n    if (ptr >= ptrend)\n      {\n      *errorcodeptr = ERR2;\n      break;\n      }\n    c = *ptr;\n    if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c);\n\n    /* Handle \\c in an ASCII/Unicode environment. */\n\n#ifndef EBCDIC    /* ASCII/UTF-8 coding */\n    if (c < 32 || c > 126)  /* Excludes all non-printable ASCII */\n      {\n      *errorcodeptr = ERR68;\n      goto ESCAPE_FAILED_FORWARD;\n      }\n    c ^= 0x40;\n\n    /* Handle \\c in an EBCDIC environment. The special case \\c? is converted to\n    255 (0xff) or 95 (0x5f) if other characters suggest we are using the\n    POSIX-BC encoding. (This is the way Perl indicates that it handles \\c?.)\n    The other valid sequences correspond to a list of specific characters. */\n\n#else\n    if (c == CHAR_QUESTION_MARK)\n      c = (CHAR_BACKSLASH == 188 && CHAR_GRAVE_ACCENT == 74)? 0x5f : 0xff;\n    else\n      {\n      for (i = 0; i < 32; i++)\n        {\n        if (c == ebcdic_escape_c[i]) break;\n        }\n      if (i < 32)\n        c = i;\n      else\n        {\n        *errorcodeptr = ERR68;\n        goto ESCAPE_FAILED_FORWARD;\n        }\n      }\n#endif  /* EBCDIC */\n\n    ptr++;\n    break;\n\n    /* Any other alphanumeric following \\ is an error. Perl gives an error only\n    if in warning mode, but PCRE doesn't have a warning mode. */\n\n    default:\n    *errorcodeptr = ERR3;\n    break;\n    }\n  }\n\n/* Set the pointer to the next character before returning. */\n\nEXIT:\n*ptrptr = ptr;\n*chptr = c;\nreturn escape;\n\n/* Some errors need to indicate the next character. */\n\nESCAPE_FAILED_FORWARD:\nptr++;\n#ifdef SUPPORT_UNICODE\nif (utf) FORWARDCHARTEST(ptr, ptrend);\n#endif\ngoto EXIT;\n}\n\n\n\n#ifdef SUPPORT_UNICODE\n/*************************************************\n*               Handle \\P and \\p                 *\n*************************************************/\n\n/* This function is called after \\P or \\p has been encountered, provided that\nPCRE2 is compiled with support for UTF and Unicode properties. On entry, the\ncontents of ptrptr are pointing after the P or p. On exit, it is left pointing\nafter the final code unit of the escape sequence.\n\nArguments:\n  ptrptr         the pattern position pointer\n  utf            true if the input is UTF-encoded\n  negptr         a boolean that is set TRUE for negation else FALSE\n  ptypeptr       an unsigned int that is set to the type value\n  pdataptr       an unsigned int that is set to the detailed property value\n  errorcodeptr   the error code variable\n  cb             the compile data\n\nReturns:         TRUE if the type value was found, or FALSE for an invalid type\n*/\n\nstatic BOOL\nget_ucp(PCRE2_SPTR *ptrptr, BOOL utf, BOOL *negptr, uint16_t *ptypeptr,\n  uint16_t *pdataptr, int *errorcodeptr, compile_block *cb)\n{\nuint32_t c;\nptrdiff_t i;\nPCRE2_SIZE bot, top;\nPCRE2_SPTR ptr = *ptrptr;\nPCRE2_UCHAR name[50];\nPCRE2_UCHAR *vptr = NULL;\nuint16_t ptscript = PT_NOTSCRIPT;\n\n#ifndef MAYBE_UTF_MULTI\n(void)utf;  /* Avoid compiler warning */\n#endif\n\nif (ptr >= cb->end_pattern) goto ERROR_RETURN;\nGETCHARINCTEST(c, ptr);\n*negptr = FALSE;\n\n/* \\P or \\p can be followed by a name in {}, optionally preceded by ^ for\nnegation. We must be handling Unicode encoding here, though we may be compiling\nfor UTF-8 input in an EBCDIC environment. (PCRE2 does not support both EBCDIC\ninput and Unicode input in the same build.) In accordance with Unicode's \"loose\nmatching\" rules, ASCII white space, hyphens, and underscores are ignored. We\ndon't use isspace() or tolower() because (a) code points may be greater than\n255, and (b) they wouldn't work when compiling for Unicode in an EBCDIC\nenvironment. */\n\nif (c == CHAR_LEFT_CURLY_BRACKET)\n  {\n  if (ptr >= cb->end_pattern) goto ERROR_RETURN;\n\n  for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++)\n    {\n    REDO:\n\n    if (ptr >= cb->end_pattern) goto ERROR_RETURN;\n    GETCHARINCTEST(c, ptr);\n\n    /* Skip ignorable Unicode characters. */\n\n    if (c == CHAR_UNDERSCORE || c == CHAR_MINUS || c == CHAR_SPACE ||\n        (c >= CHAR_HT && c <= CHAR_CR))\n      {\n      goto REDO;\n      }\n\n    /* The first significant character being circumflex negates the meaning of\n    the item. */\n\n    if (i == 0 && !*negptr && c == CHAR_CIRCUMFLEX_ACCENT)\n      {\n      *negptr = TRUE;\n      goto REDO;\n      }\n\n    if (c == CHAR_RIGHT_CURLY_BRACKET) break;\n\n    /* Names consist of ASCII letters and digits, but equals and colon may also\n    occur as a name/value separator. We must also allow for \\p{L&}. A simple\n    check for a value between '&' and 'z' suffices because anything else in a\n    name or value will cause an \"unknown property\" error anyway. */\n\n    if (c < CHAR_AMPERSAND || c > CHAR_z) goto ERROR_RETURN;\n\n    /* Lower case a capital letter or remember where the name/value separator\n    is. */\n\n    if (c >= CHAR_A && c <= CHAR_Z) c |= 0x20;\n    else if ((c == CHAR_COLON || c == CHAR_EQUALS_SIGN) && vptr == NULL)\n      vptr = name + i;\n\n    name[i] = c;\n    }\n\n  /* Error if the loop didn't end with '}' - either we hit the end of the\n  pattern or the name was longer than any legal property name. */\n\n  if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;\n  name[i] = 0;\n  }\n\n/* If { doesn't follow \\p or \\P there is just one following character, which\nmust be an ASCII letter. */\n\nelse if (c >= CHAR_A && c <= CHAR_Z)\n  {\n  name[0] = c | 0x20;  /* Lower case */\n  name[1] = 0;\n  }\nelse if (c >= CHAR_a && c <= CHAR_z)\n  {\n  name[0] = c;\n  name[1] = 0;\n  }\nelse goto ERROR_RETURN;\n\n*ptrptr = ptr;   /* Update pattern pointer */\n\n/* If the property contains ':' or '=' we have class name and value separately\nspecified. The following are supported:\n\n  . Bidi_Class (synonym bc), for which the property names are \"bidi<name>\".\n  . Script (synonym sc) for which the property name is the script name\n  . Script_Extensions (synonym scx), ditto\n\nAs this is a small number, we currently just check the names directly. If this\ngrows, a sorted table and a switch will be neater.\n\nFor both the script properties, set a PT_xxx value so that (1) they can be\ndistinguished and (2) invalid script names that happen to be the name of\nanother property can be diagnosed. */\n\nif (vptr != NULL)\n  {\n  int offset = 0;\n  PCRE2_UCHAR sname[8];\n\n  *vptr = 0;   /* Terminate property name */\n  if (PRIV(strcmp_c8)(name, STRING_bidiclass) == 0 ||\n      PRIV(strcmp_c8)(name, STRING_bc) == 0)\n    {\n    offset = 4;\n    sname[0] = CHAR_b;\n    sname[1] = CHAR_i;  /* There is no strcpy_c8 function */\n    sname[2] = CHAR_d;\n    sname[3] = CHAR_i;\n    }\n\n  else if (PRIV(strcmp_c8)(name, STRING_script) == 0 ||\n           PRIV(strcmp_c8)(name, STRING_sc) == 0)\n    ptscript = PT_SC;\n\n  else if (PRIV(strcmp_c8)(name, STRING_scriptextensions) == 0 ||\n           PRIV(strcmp_c8)(name, STRING_scx) == 0)\n    ptscript = PT_SCX;\n\n  else\n    {\n    *errorcodeptr = ERR47;\n    return FALSE;\n    }\n\n  /* Adjust the string in name[] as needed */\n\n  memmove(name + offset, vptr + 1, (name + i - vptr)*sizeof(PCRE2_UCHAR));\n  if (offset != 0) memmove(name, sname, offset*sizeof(PCRE2_UCHAR));\n  }\n\n/* Search for a recognized property using binary chop. */\n\nbot = 0;\ntop = PRIV(utt_size);\n\nwhile (bot < top)\n  {\n  int r;\n  i = (bot + top) >> 1;\n  r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);\n\n  /* When a matching property is found, some extra checking is needed when the\n  \\p{xx:yy} syntax is used and xx is either sc or scx. */\n\n  if (r == 0)\n    {\n    *pdataptr = PRIV(utt)[i].value;\n    if (vptr == NULL || ptscript == PT_NOTSCRIPT)\n      {\n      *ptypeptr = PRIV(utt)[i].type;\n      return TRUE;\n      }\n\n    switch (PRIV(utt)[i].type)\n      {\n      case PT_SC:\n      *ptypeptr = PT_SC;\n      return TRUE;\n\n      case PT_SCX:\n      *ptypeptr = ptscript;\n      return TRUE;\n      }\n\n    break;  /* Non-script found */\n    }\n\n  if (r > 0) bot = i + 1; else top = i;\n  }\n\n*errorcodeptr = ERR47;   /* Unrecognized property */\nreturn FALSE;\n\nERROR_RETURN:            /* Malformed \\P or \\p */\n*errorcodeptr = ERR46;\n*ptrptr = ptr;\nreturn FALSE;\n}\n#endif\n\n\n\n/*************************************************\n*           Check for POSIX class syntax         *\n*************************************************/\n\n/* This function is called when the sequence \"[:\" or \"[.\" or \"[=\" is\nencountered in a character class. It checks whether this is followed by a\nsequence of characters terminated by a matching \":]\" or \".]\" or \"=]\". If we\nreach an unescaped ']' without the special preceding character, return FALSE.\n\nOriginally, this function only recognized a sequence of letters between the\nterminators, but it seems that Perl recognizes any sequence of characters,\nthough of course unknown POSIX names are subsequently rejected. Perl gives an\n\"Unknown POSIX class\" error for [:f\\oo:] for example, where previously PCRE\ndidn't consider this to be a POSIX class. Likewise for [:1234:].\n\nThe problem in trying to be exactly like Perl is in the handling of escapes. We\nhave to be sure that [abc[:x\\]pqr] is *not* treated as containing a POSIX\nclass, but [abc[:x\\]pqr:]] is (so that an error can be generated). The code\nbelow handles the special cases \\\\ and \\], but does not try to do any other\nescape processing. This makes it different from Perl for cases such as\n[:l\\ower:] where Perl recognizes it as the POSIX class \"lower\" but PCRE does\nnot recognize \"l\\ower\". This is a lesser evil than not diagnosing bad classes\nwhen Perl does, I think.\n\nA user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.\nIt seems that the appearance of a nested POSIX class supersedes an apparent\nexternal class. For example, [:a[:digit:]b:] matches \"a\", \"b\", \":\", or\na digit. This is handled by returning FALSE if the start of a new group with\nthe same terminator is encountered, since the next closing sequence must close\nthe nested group, not the outer one.\n\nIn Perl, unescaped square brackets may also appear as part of class names. For\nexample, [:a[:abc]b:] gives unknown POSIX class \"[:abc]b:]\". However, for\n[:a[:abc]b][b:] it gives unknown POSIX class \"[:abc]b][b:]\", which does not\nseem right at all. PCRE does not allow closing square brackets in POSIX class\nnames.\n\nArguments:\n  ptr      pointer to the character after the initial [ (colon, dot, equals)\n  ptrend   pointer to the end of the pattern\n  endptr   where to return a pointer to the terminating ':', '.', or '='\n\nReturns:   TRUE or FALSE\n*/\n\nstatic BOOL\ncheck_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, PCRE2_SPTR *endptr)\n{\nPCRE2_UCHAR terminator;  /* Don't combine these lines; the Solaris cc */\nterminator = *ptr++;     /* compiler warns about \"non-constant\" initializer. */\n\nfor (; ptrend - ptr >= 2; ptr++)\n  {\n  if (*ptr == CHAR_BACKSLASH &&\n      (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH))\n    ptr++;\n\n  else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||\n            *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;\n\n  else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)\n    {\n    *endptr = ptr;\n    return TRUE;\n    }\n  }\n\nreturn FALSE;\n}\n\n\n\n/*************************************************\n*          Check POSIX class name                *\n*************************************************/\n\n/* This function is called to check the name given in a POSIX-style class entry\nsuch as [:alnum:].\n\nArguments:\n  ptr        points to the first letter\n  len        the length of the name\n\nReturns:     a value representing the name, or -1 if unknown\n*/\n\nstatic int\ncheck_posix_name(PCRE2_SPTR ptr, int len)\n{\nconst char *pn = posix_names;\nint yield = 0;\nwhile (posix_name_lengths[yield] != 0)\n  {\n  if (len == posix_name_lengths[yield] &&\n    PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield;\n  pn += posix_name_lengths[yield] + 1;\n  yield++;\n  }\nreturn -1;\n}\n\n\n\n/*************************************************\n*       Read a subpattern or VERB name           *\n*************************************************/\n\n/* This function is called from parse_regex() below whenever it needs to read\nthe name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial\npointer must be to the preceding character. If that character is '*' we are\nreading a verb or alpha assertion name. The pointer is updated to point after\nthe name, for a VERB or alpha assertion name, or after the name's terminator\nfor a subpattern name. Returning both the offset and the name pointer is\nredundant information, but some callers use one and some the other, so it is\nsimplest just to return both. When the name is in braces, spaces and tabs are\nallowed (and ignored) at either end.\n\nArguments:\n  ptrptr      points to the character pointer variable\n  ptrend      points to the end of the input string\n  utf         true if the input is UTF-encoded\n  terminator  the terminator of a subpattern name must be this\n  offsetptr   where to put the offset from the start of the pattern\n  nameptr     where to put a pointer to the name in the input\n  namelenptr  where to put the length of the name\n  errcodeptr  where to put an error code\n  cb          pointer to the compile data block\n\nReturns:    TRUE if a name was read\n            FALSE otherwise, with error code set\n*/\n\nstatic BOOL\nread_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, uint32_t terminator,\n  PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr,\n  int *errorcodeptr, compile_block *cb)\n{\nPCRE2_SPTR ptr = *ptrptr;\nBOOL is_group = (*ptr++ != CHAR_ASTERISK);\nBOOL is_braced = terminator == CHAR_RIGHT_CURLY_BRACKET;\n\nif (is_braced)\n  while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n\nif (ptr >= ptrend)                 /* No characters in name */\n  {\n  *errorcodeptr = is_group? ERR62: /* Subpattern name expected */\n                            ERR60; /* Verb not recognized or malformed */\n  goto FAILED;\n  }\n\n*nameptr = ptr;\n*offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern);\n\n/* If this logic were ever to change, the matching function in pcre2_substitute.c\nought to be updated to match. */\n\n/* In UTF mode, a group name may contain letters and decimal digits as defined\nby Unicode properties, and underscores, but must not start with a digit. */\n\n#ifdef SUPPORT_UNICODE\nif (utf && is_group)\n  {\n  uint32_t c, type;\n  PCRE2_SPTR p = ptr;\n\n  GETCHARINC(c, p);  /* Peek at next character */\n  type = UCD_CHARTYPE(c);\n\n  if (type == ucp_Nd)\n    {\n    ptr = p;\n    *errorcodeptr = ERR44;\n    goto FAILED;\n    }\n\n  for(;;)\n    {\n    if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L &&\n        c != CHAR_UNDERSCORE) break;\n    ptr = p;  /* Accept character and peek again */\n    if (p >= ptrend) break;\n    GETCHARINC(c, p);\n    type = UCD_CHARTYPE(c);\n    }\n  }\nelse\n#else\n(void)utf;  /* Avoid compiler warning */\n#endif      /* SUPPORT_UNICODE */\n\n/* Handle non-group names and group names in non-UTF modes. A group name must\nnot start with a digit. If either of the others start with a digit it just\nwon't be recognized. */\n\n  {\n  if (is_group && IS_DIGIT(*ptr))\n    {\n    ++ptr;\n    *errorcodeptr = ERR44;\n    goto FAILED;\n    }\n\n  while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0)\n    {\n    ptr++;\n    }\n  }\n\n/* Check name length */\n\nif (ptr - *nameptr > MAX_NAME_SIZE)\n  {\n  *errorcodeptr = ERR48;\n  goto FAILED;\n  }\n*namelenptr = (uint32_t)(ptr - *nameptr);\n\n/* Subpattern names must not be empty, and their terminator is checked here.\n(What follows a verb or alpha assertion name is checked separately.) */\n\nif (is_group)\n  {\n  if (ptr == *nameptr)\n    {\n    *errorcodeptr = ERR62;   /* Subpattern name expected */\n    goto FAILED;\n    }\n  if (is_braced)\n    while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;\n  if (terminator != 0)\n    {\n    if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)\n      {\n      *errorcodeptr = ERR42;\n      goto FAILED;\n      }\n    ptr++;\n    }\n  }\n\n*ptrptr = ptr;\nreturn TRUE;\n\nFAILED:\n*ptrptr = ptr;\nreturn FALSE;\n}\n\n\n\n/**************************************************\n*        Parse capturing bracket argument list    *\n**************************************************/\n\n/* Reads a list of capture references. The references\ncan be numbers or names.\n\nArguments:\n  ptrptr           points to the character pointer variable\n  ptrend           points to the end of the input string\n  utf              true if the input is UTF-encoded\n  parsed_pattern   the parsed pattern pointer\n  offset           last known offset\n  errcodeptr       where to put an error code\n  cb               pointer to the compile data block\n\nReturns: updated parsed_pattern pointer on success\n         NULL otherwise\n*/\n\nstatic uint32_t *\nparse_capture_list(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,\n  BOOL utf, uint32_t *parsed_pattern, PCRE2_SIZE offset,\n  int *errorcodeptr, compile_block *cb)\n{\nPCRE2_SIZE next_offset;\nPCRE2_SPTR ptr = *ptrptr;\nPCRE2_SPTR name;\nPCRE2_UCHAR terminator;\nuint32_t meta, namelen;\nint i;\n\nif (ptr >= ptrend || *ptr != CHAR_LEFT_PARENTHESIS)\n  {\n  *errorcodeptr = ERR118;\n  goto FAILED;\n  }\n\nfor (;;)\n  {\n  ptr++;\n  next_offset = (PCRE2_SIZE)(ptr - cb->start_pattern);\n\n  if (ptr >= ptrend)\n    {\n    *errorcodeptr = ERR117;\n    goto FAILED;\n    }\n\n  /* Handle [+-]number cases */\n  if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61,\n      &i, errorcodeptr))\n    {\n    PCRE2_ASSERT(i >= 0);\n    if (i <= 0)\n      {\n      *errorcodeptr = ERR15;\n      goto FAILED;\n      }\n    meta = META_CAPTURE_NUMBER;\n    namelen = (uint32_t)i;\n    }\n  else if (*errorcodeptr != 0) goto FAILED; /* Number too big */\n  else\n    {\n    /* Handle 'name' or <name> cases. */\n    if (*ptr == CHAR_LESS_THAN_SIGN)\n      terminator = CHAR_GREATER_THAN_SIGN;\n    else if (*ptr == CHAR_APOSTROPHE)\n      terminator = CHAR_APOSTROPHE;\n    else\n      {\n      *errorcodeptr = ERR117;\n      goto FAILED;\n      }\n\n    if (!read_name(&ptr, ptrend, utf, terminator, &next_offset,\n        &name, &namelen, errorcodeptr, cb)) goto FAILED;\n\n    meta = META_CAPTURE_NAME;\n    }\n\n  PCRE2_ASSERT(next_offset > 0);\n  if (offset == 0 || (next_offset - offset) >= 0x10000)\n    {\n    *parsed_pattern++ = META_OFFSET;\n    PUTOFFSET(next_offset, parsed_pattern);\n    offset = next_offset;\n    }\n\n  /* The offset is encoded as a relative offset, because for some\n  inputs such as \",2\" in (1,2,3), we only have space for two uint32_t\n  values, and an opcode and absolute offset may require three uint32_t\n  values. */\n  *parsed_pattern++ = meta | (uint32_t)(next_offset - offset);\n  *parsed_pattern++ = namelen;\n  offset = next_offset;\n\n  if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n\n  if (*ptr == CHAR_RIGHT_PARENTHESIS) break;\n\n  if (*ptr != CHAR_COMMA)\n    {\n    *errorcodeptr = ERR24;\n    goto FAILED;\n    }\n  }\n\n*ptrptr = ptr + 1;\nreturn parsed_pattern;\n\nUNCLOSED_PARENTHESIS:\n*errorcodeptr = ERR14;\n\nFAILED:\n*ptrptr = ptr;\nreturn NULL;\n}\n\n\n\n/*************************************************\n*          Manage callouts at start of cycle     *\n*************************************************/\n\n/* At the start of a new item in parse_regex() we are able to record the\ndetails of the previous item in a prior callout, and also to set up an\nautomatic callout if enabled. Avoid having two adjacent automatic callouts,\nwhich would otherwise happen for items such as \\Q that contribute nothing to\nthe parsed pattern.\n\nArguments:\n  ptr              current pattern pointer\n  pcalloutptr      points to a pointer to previous callout, or NULL\n  auto_callout     TRUE if auto_callouts are enabled\n  parsed_pattern   the parsed pattern pointer\n  cb               compile block\n\nReturns: possibly updated parsed_pattern pointer.\n*/\n\nstatic uint32_t *\nmanage_callouts(PCRE2_SPTR ptr, uint32_t **pcalloutptr, BOOL auto_callout,\n  uint32_t *parsed_pattern, compile_block *cb)\n{\nuint32_t *previous_callout = *pcalloutptr;\n\nif (previous_callout != NULL) previous_callout[2] = (uint32_t)(ptr -\n  cb->start_pattern - (PCRE2_SIZE)previous_callout[1]);\n\nif (!auto_callout) previous_callout = NULL; else\n  {\n  if (previous_callout == NULL ||\n      previous_callout != parsed_pattern - 4 ||\n      previous_callout[3] != 255)\n    {\n    previous_callout = parsed_pattern;  /* Set up new automatic callout */\n    parsed_pattern += 4;\n    previous_callout[0] = META_CALLOUT_NUMBER;\n    previous_callout[2] = 0;\n    previous_callout[3] = 255;\n    }\n  previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);\n  }\n\n*pcalloutptr = previous_callout;\nreturn parsed_pattern;\n}\n\n\n\n/*************************************************\n*          Handle \\d, \\D, \\s, \\S, \\w, \\W         *\n*************************************************/\n\n/* This function is called from parse_regex() below, both for freestanding\nescapes, and those within classes, to handle those escapes that may change when\nUnicode property support is requested. Note that PCRE2_UCP will never be set\nwithout Unicode support because that is checked when pcre2_compile() is called.\n\nArguments:\n  escape          the ESC_... value\n  parsed_pattern  where to add the code\n  options         options bits\n  xoptions        extra options bits\n\nReturns:          updated value of parsed_pattern\n*/\nstatic uint32_t *\nhandle_escdsw(int escape, uint32_t *parsed_pattern, uint32_t options,\n  uint32_t xoptions)\n{\nuint32_t ascii_option = 0;\nuint32_t prop = ESC_p;\n\nswitch(escape)\n  {\n  case ESC_D:\n  prop = ESC_P;\n  PCRE2_FALLTHROUGH /* Fall through */\n  case ESC_d:\n  ascii_option = PCRE2_EXTRA_ASCII_BSD;\n  break;\n\n  case ESC_S:\n  prop = ESC_P;\n  PCRE2_FALLTHROUGH /* Fall through */\n  case ESC_s:\n  ascii_option = PCRE2_EXTRA_ASCII_BSS;\n  break;\n\n  case ESC_W:\n  prop = ESC_P;\n  PCRE2_FALLTHROUGH /* Fall through */\n  case ESC_w:\n  ascii_option = PCRE2_EXTRA_ASCII_BSW;\n  break;\n  }\n\nif ((options & PCRE2_UCP) == 0 || (xoptions & ascii_option) != 0)\n  {\n  *parsed_pattern++ = META_ESCAPE + escape;\n  }\nelse\n  {\n  *parsed_pattern++ = META_ESCAPE + prop;\n  switch(escape)\n    {\n    case ESC_d:\n    case ESC_D:\n    *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;\n    break;\n\n    case ESC_s:\n    case ESC_S:\n    *parsed_pattern++ = PT_SPACE << 16;\n    break;\n\n    case ESC_w:\n    case ESC_W:\n    *parsed_pattern++ = PT_WORD << 16;\n    break;\n    }\n  }\n\nreturn parsed_pattern;\n}\n\n\n\n/*************************************************\n* Maximum size of parsed_pattern for given input *\n*************************************************/\n\n/* This function is called from parse_regex() below, to determine the amount\nof memory to allocate for parsed_pattern. It is also called to check whether\nthe amount of data written respects the amount of memory allocated.\n\nArguments:\n  ptr             points to the start of the pattern\n  ptrend          points to the end of the pattern\n  utf             TRUE in UTF mode\n  options         the options bits\n\nReturns:          the number of uint32_t units for parsed_pattern\n*/\nstatic ptrdiff_t\nmax_parsed_pattern(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, BOOL utf,\n  uint32_t options)\n{\nPCRE2_SIZE big32count = 0;\nptrdiff_t parsed_size_needed;\n\n/* When PCRE2_AUTO_CALLOUT is not set, in all but one case the number of\nunsigned 32-bit ints written out to the parsed pattern is bounded by the length\nof the pattern. The exceptional case is when running in 32-bit, non-UTF mode,\nwhen literal characters greater than META_END (0x80000000) have to be coded as\ntwo units. In this case, therefore, we scan the pattern to check for such\nvalues. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (!utf)\n  {\n  PCRE2_SPTR p;\n  for (p = ptr; p < ptrend; p++) if (*p >= META_END) big32count++;\n  }\n#else\n(void)utf;  /* Avoid compiler warning */\n#endif\n\nparsed_size_needed = (ptrend - ptr) + big32count;\n\n/* When PCRE2_AUTO_CALLOUT is set we have to assume a numerical callout (4\nelements) for each character. This is overkill, but memory is plentiful these\ndays. */\n\nif ((options & PCRE2_AUTO_CALLOUT) != 0)\n  parsed_size_needed += (ptrend - ptr) * 4;\n\nreturn parsed_size_needed;\n}\n\n\n\n/*************************************************\n*      Parse regex and identify named groups     *\n*************************************************/\n\n/* This function is called first of all. It scans the pattern and does two\nthings: (1) It identifies capturing groups and makes a table of named capturing\ngroups so that information about them is fully available to both the compiling\nscans. (2) It writes a parsed version of the pattern with comments omitted and\nescapes processed into the parsed_pattern vector.\n\nArguments:\n  ptr             points to the start of the pattern\n  options         compiling dynamic options (may change during the scan)\n  has_lookbehind  points to a boolean, set TRUE if a lookbehind is found\n  cb              pointer to the compile data block\n\nReturns:   zero on success or a non-zero error code, with the\n             error offset placed in the cb field\n*/\n\n/* A structure and some flags for dealing with nested groups. */\n\ntypedef struct nest_save {\n  uint16_t  nest_depth;\n  uint16_t  reset_group;\n  uint16_t  max_group;\n  uint16_t  flags;\n  uint32_t  options;\n  uint32_t  xoptions;\n} nest_save;\n\n#define NSF_RESET          0x0001u\n#define NSF_CONDASSERT     0x0002u\n#define NSF_ATOMICSR       0x0004u\n\n/* Options that are changeable within the pattern must be tracked during\nparsing. Some (e.g. PCRE2_EXTENDED) are implemented entirely during parsing,\nbut all must be tracked so that META_OPTIONS items set the correct values for\nthe main compiling phase. */\n\n#define PARSE_TRACKED_OPTIONS (PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_DUPNAMES| \\\n  PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \\\n  PCRE2_UNGREEDY)\n\n#define PARSE_TRACKED_EXTRA_OPTIONS (PCRE2_EXTRA_CASELESS_RESTRICT| \\\n  PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW| \\\n  PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX)\n\n/* States used for analyzing ranges in character classes. The two OK values\nmust be last. */\n\nenum {\n  RANGE_NO, /* State after '[' (initial), or '[a-z'; hyphen is literal */\n  RANGE_STARTED, /* State after '[1-'; last-emitted code is META_RANGE_XYZ */\n  RANGE_FORBID_NO, /* State after '[\\d'; '-]' is allowed but not '-1]' */\n  RANGE_FORBID_STARTED, /* State after '[\\d-'*/\n  RANGE_OK_ESCAPED, /* State after '[\\1'; hyphen may be a range */\n  RANGE_OK_LITERAL /* State after '[1'; hyphen may be a range */\n};\n\n/* States used for analyzing operators and operands in extended character\nclasses. */\n\nenum {\n  CLASS_OP_EMPTY, /* At start of an expression; empty previous contents */\n  CLASS_OP_OPERAND, /* Have preceding operand; after \"z\" a \"--\" can follow */\n  CLASS_OP_OPERATOR /* Have preceding operator; after \"--\" operand must follow */\n};\n\n/* States used for determining the parse mode in character classes. The two\nPERL_EXT values must be last. */\n\nenum {\n  CLASS_MODE_NORMAL, /* Ordinary PCRE2 '[...]' class. */\n  CLASS_MODE_ALT_EXT, /* UTS#18-style extended '[...]' class. */\n  CLASS_MODE_PERL_EXT, /* Perl extended '(?[...])' class. */\n  CLASS_MODE_PERL_EXT_LEAF /* Leaf within extended '(?[ [...] ])' class. */\n};\n\n/* Only in 32-bit mode can there be literals > META_END. A macro encapsulates\nthe storing of literal values in the main parsed pattern, where they can always\nbe quantified. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n#define PARSED_LITERAL(c, p) \\\n  { \\\n  if (c >= META_END) *p++ = META_BIGVALUE; \\\n  *p++ = c; \\\n  okquantifier = TRUE; \\\n  }\n#else\n#define PARSED_LITERAL(c, p) *p++ = c; okquantifier = TRUE;\n#endif\n\n/* Here's the actual function. */\n\nstatic int parse_regex(PCRE2_SPTR ptr, uint32_t options, uint32_t xoptions,\n  BOOL *has_lookbehind, compile_block *cb)\n{\nuint32_t c;\nuint32_t delimiter;\nuint32_t namelen;\nuint32_t class_range_state;\nuint32_t class_op_state;\nuint32_t class_mode_state;\nuint32_t *class_start;\nuint32_t *verblengthptr = NULL;     /* Value avoids compiler warning */\nuint32_t *verbstartptr = NULL;\nuint32_t *previous_callout = NULL;\nuint32_t *parsed_pattern = cb->parsed_pattern;\nuint32_t *parsed_pattern_end = cb->parsed_pattern_end;\nuint32_t *this_parsed_item = NULL;\nuint32_t *prev_parsed_item = NULL;\nuint32_t meta_quantifier = 0;\nuint32_t add_after_mark = 0;\nuint16_t nest_depth = 0;\nint16_t class_depth_m1 = -1; /* The m1 means minus 1. */\nint16_t class_maxdepth_m1 = -1;\nuint16_t hash;\nint after_manual_callout = 0;\nint expect_cond_assert = 0;\nint errorcode = 0;\nint escape;\nint i;\nBOOL inescq = FALSE;\nBOOL inverbname = FALSE;\nBOOL utf = (options & PCRE2_UTF) != 0;\nBOOL auto_callout = (options & PCRE2_AUTO_CALLOUT) != 0;\nBOOL is_dupname;\nBOOL negate_class;\nBOOL okquantifier = FALSE;\nPCRE2_SPTR thisptr;\nPCRE2_SPTR name;\nPCRE2_SPTR ptrend = cb->end_pattern;\nPCRE2_SPTR verbnamestart = NULL;    /* Value avoids compiler warning */\nPCRE2_SPTR class_range_forbid_ptr = NULL;\nnamed_group *ng;\nnest_save *top_nest, *end_nests;\n#ifdef PCRE2_DEBUG\nuint32_t *parsed_pattern_check;\nptrdiff_t parsed_pattern_extra = 0;\nptrdiff_t parsed_pattern_extra_check = 0;\nPCRE2_SPTR ptr_check;\n#endif\n\nPCRE2_ASSERT(parsed_pattern != NULL);\n\n/* Insert leading items for word and line matching (features provided for the\nbenefit of pcre2grep). */\n\nif ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0)\n  {\n  *parsed_pattern++ = META_CIRCUMFLEX;\n  *parsed_pattern++ = META_NOCAPTURE;\n  }\nelse if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0)\n  {\n  *parsed_pattern++ = META_ESCAPE + ESC_b;\n  *parsed_pattern++ = META_NOCAPTURE;\n  }\n\n#ifdef PCRE2_DEBUG\nparsed_pattern_check = parsed_pattern;\nptr_check = ptr;\n#endif\n\n/* If the pattern is actually a literal string, process it separately to avoid\ncluttering up the main loop. */\n\nif ((options & PCRE2_LITERAL) != 0)\n  {\n  while (ptr < ptrend)\n    {\n    /* LCOV_EXCL_START */\n    if (parsed_pattern >= parsed_pattern_end)\n      {\n      PCRE2_DEBUG_UNREACHABLE();\n      errorcode = ERR63;  /* Internal error (parsed pattern overflow) */\n      goto FAILED;\n      }\n    /* LCOV_EXCL_STOP */\n\n    thisptr = ptr;\n    GETCHARINCTEST(c, ptr);\n    if (auto_callout)\n      parsed_pattern = manage_callouts(thisptr, &previous_callout,\n        auto_callout, parsed_pattern, cb);\n    PARSED_LITERAL(c, parsed_pattern);\n    }\n  goto PARSED_END;\n  }\n\n/* Process a real regex which may contain meta-characters. */\n\ntop_nest = NULL;\nend_nests = (nest_save *)(cb->start_workspace + cb->workspace_size);\n\n/* The size of the nest_save structure might not be a factor of the size of the\nworkspace. Therefore we must round down end_nests so as to correctly avoid\ncreating a nest_save that spans the end of the workspace. */\n\nend_nests = (nest_save *)((char *)end_nests -\n  ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save)));\n\n/* PCRE2_EXTENDED_MORE implies PCRE2_EXTENDED */\n\nif ((options & PCRE2_EXTENDED_MORE) != 0) options |= PCRE2_EXTENDED;\n\n/* Now scan the pattern */\n\nwhile (ptr < ptrend)\n  {\n  int prev_expect_cond_assert;\n  uint32_t min_repeat = 0, max_repeat = 0;\n  uint32_t set, unset, *optset;\n  uint32_t xset, xunset, *xoptset;\n  uint32_t terminator;\n  uint32_t prev_meta_quantifier;\n  BOOL prev_okquantifier;\n  PCRE2_SPTR tempptr;\n  PCRE2_SIZE offset;\n\n  if (nest_depth > cb->cx->parens_nest_limit)\n    {\n    errorcode = ERR19;\n    goto FAILED;        /* Parentheses too deeply nested */\n    }\n\n  /* Check that we haven't emitted too much into parsed_pattern. We allocate\n  a suitably-sized buffer upfront, then do unchecked writes to it. If we only\n  write a little bit too much, everything will appear to be OK, because the\n  upfront size is an overestimate... but a malicious pattern could end up\n  forcing a write past the buffer end. We must catch this during\n  development. */\n\n#ifdef PCRE2_DEBUG\n  /* Strong post-write check. Won't help in release builds - at this point\n  the write has already occurred so it's too late. However, should stop us\n  committing unsafe code. */\n  PCRE2_ASSERT((parsed_pattern - parsed_pattern_check) +\n               (parsed_pattern_extra - parsed_pattern_extra_check) <=\n                 max_parsed_pattern(ptr_check, ptr, utf, options));\n  parsed_pattern_check = parsed_pattern;\n  parsed_pattern_extra_check = parsed_pattern_extra;\n  ptr_check = ptr;\n#endif\n\n  /* LCOV_EXCL_START */\n  if (parsed_pattern >= parsed_pattern_end)\n    {\n    /* Weak pre-write check; only ensures parsed_pattern[0] is writeable\n    (but the code below can write many chars). Better than nothing. */\n    PCRE2_DEBUG_UNREACHABLE();\n    errorcode = ERR63;  /* Internal error (parsed pattern overflow) */\n    goto FAILED;\n    }\n  /* LCOV_EXCL_STOP */\n\n  /* If the last time round this loop something was added, parsed_pattern will\n  no longer be equal to this_parsed_item. Remember where the previous item\n  started and reset for the next item. Note that sometimes round the loop,\n  nothing gets added (e.g. for ignored white space). */\n\n  if (this_parsed_item != parsed_pattern)\n    {\n    prev_parsed_item = this_parsed_item;\n    this_parsed_item = parsed_pattern;\n    }\n\n  /* Get next input character, save its position for callout handling. */\n\n  thisptr = ptr;\n  GETCHARINCTEST(c, ptr);\n\n  /* Copy quoted literals until \\E, allowing for the possibility of automatic\n  callouts, except when processing a (*VERB) \"name\".  */\n\n  if (inescq)\n    {\n    if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)\n      {\n      inescq = FALSE;\n      ptr++;   /* Skip E */\n      }\n    else\n      {\n      if (inverbname)\n        {                          /* Don't use PARSED_LITERAL() because it */\n#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */\n        if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;\n#endif\n        *parsed_pattern++ = c;\n        }\n      else\n        {\n        if (after_manual_callout-- <= 0)\n          parsed_pattern = manage_callouts(thisptr, &previous_callout,\n            auto_callout, parsed_pattern, cb);\n        PARSED_LITERAL(c, parsed_pattern);\n        }\n      meta_quantifier = 0;\n      }\n    continue;  /* Next character */\n    }\n\n  /* If we are processing the \"name\" part of a (*VERB:NAME) item, all\n  characters up to the closing parenthesis are literals except when\n  PCRE2_ALT_VERBNAMES is set. That causes backslash interpretation, but only \\Q\n  and \\E and escaped characters are allowed (no character types such as \\d). If\n  PCRE2_EXTENDED is also set, we must ignore white space and # comments. Do\n  this by not entering the special (*VERB:NAME) processing - they are then\n  picked up below. Note that c is a character, not a code unit, so we must not\n  use MAX_255 to test its size because MAX_255 tests code units and is assumed\n  TRUE in 8-bit mode. */\n\n  if (inverbname &&\n       (\n        /* EITHER: not both options set */\n        ((options & (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) !=\n                    (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) ||\n#ifdef SUPPORT_UNICODE\n        /* OR: character > 255 AND not Unicode Pattern White Space */\n        (c > 255 && (c|1) != 0x200f && (c|1) != 0x2029) ||\n#endif\n        /* OR: not a # comment or isspace() white space */\n        (c < 256 && c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0\n#ifdef SUPPORT_UNICODE\n        /* and not CHAR_NEL when Unicode is supported */\n          && c != CHAR_NEL\n#endif\n       )))\n    {\n    PCRE2_SIZE verbnamelength;\n\n    switch(c)\n      {\n      default:                     /* Don't use PARSED_LITERAL() because it */\n#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */\n      if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;\n#endif\n      *parsed_pattern++ = c;\n      break;\n\n      case CHAR_RIGHT_PARENTHESIS:\n      inverbname = FALSE;\n      /* This is the length in characters */\n      verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1);\n      /* But the limit on the length is in code units */\n      if (ptr - verbnamestart - 1 > (int)MAX_MARK)\n        {\n        ptr--;\n        errorcode = ERR76;\n        goto FAILED;\n        }\n      *verblengthptr = (uint32_t)verbnamelength;\n\n      /* If this name was on a verb such as (*ACCEPT) which does not continue,\n      a (*MARK) was generated for the name. We now add the original verb as the\n      next item. */\n\n      if (add_after_mark != 0)\n        {\n        *parsed_pattern++ = add_after_mark;\n        add_after_mark = 0;\n        }\n      break;\n\n      case CHAR_BACKSLASH:\n      if ((options & PCRE2_ALT_VERBNAMES) != 0)\n        {\n        escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,\n          xoptions, cb->bracount, FALSE, cb);\n        if (errorcode != 0) goto FAILED;\n        }\n      else escape = 0;   /* Treat all as literal */\n\n      switch(escape)\n        {\n        case 0:                    /* Don't use PARSED_LITERAL() because it */\n#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */\n        if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;\n#endif\n        *parsed_pattern++ = c;\n        break;\n\n        case ESC_ub:\n        *parsed_pattern++ = CHAR_u;\n        PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern);\n        break;\n\n        case ESC_Q:\n        inescq = TRUE;\n        break;\n\n        case ESC_E:           /* Ignore */\n        break;\n\n        default:\n        errorcode = ERR40;    /* Invalid in verb name */\n        goto FAILED;\n        }\n      }\n    continue;   /* Next character in pattern */\n    }\n\n  /* Not a verb name character. At this point we must process everything that\n  must not change the quantification state. This is mainly comments, but we\n  handle \\Q and \\E here as well, so that an item such as A\\Q\\E+ is treated as\n  A+, as in Perl. An isolated \\E is ignored. */\n\n  if (c == CHAR_BACKSLASH && ptr < ptrend)\n    {\n    if (*ptr == CHAR_Q || *ptr == CHAR_E)\n      {\n      /* A literal inside a \\Q...\\E is not allowed if we are expecting a\n      conditional assertion, but an empty \\Q\\E sequence is OK. */\n      if (expect_cond_assert > 0 && *ptr == CHAR_Q &&\n          !(ptrend - ptr >= 3 && ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E))\n        {\n        ptr--;\n        errorcode = ERR28;\n        goto FAILED;\n        }\n      inescq = *ptr == CHAR_Q;\n      ptr++;\n      continue;\n      }\n    }\n\n  /* Skip over whitespace and # comments in extended mode. Note that c is a\n  character, not a code unit, so we must not use MAX_255 to test its size\n  because MAX_255 tests code units and is assumed TRUE in 8-bit mode. The\n  whitespace characters are those designated as \"Pattern White Space\" by\n  Unicode, which are the isspace() characters plus CHAR_NEL (newline), which is\n  U+0085 in Unicode, plus U+200E, U+200F, U+2028, and U+2029. These are a\n  subset of space characters that match \\h and \\v. */\n\n  if ((options & PCRE2_EXTENDED) != 0)\n    {\n    if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue;\n#ifdef SUPPORT_UNICODE\n    if (c == CHAR_NEL || (c|1) == 0x200f || (c|1) == 0x2029) continue;\n#endif\n    if (c == CHAR_NUMBER_SIGN)\n      {\n      while (ptr < ptrend)\n        {\n        if (IS_NEWLINE(ptr))      /* For non-fixed-length newline cases, */\n          {                       /* IS_NEWLINE sets cb->nllen. */\n          ptr += cb->nllen;\n          break;\n          }\n        ptr++;\n#ifdef SUPPORT_UNICODE\n        if (utf) FORWARDCHARTEST(ptr, ptrend);\n#endif\n        }\n      continue;  /* Next character in pattern */\n      }\n    }\n\n  /* Skip over bracketed comments */\n\n  if (c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 2 &&\n      ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)\n    {\n    while (++ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS);\n    if (ptr >= ptrend)\n      {\n      errorcode = ERR18;  /* A special error for missing ) in a comment */\n      goto FAILED;        /* to make it easier to debug. */\n      }\n    ptr++;\n    continue;  /* Next character in pattern */\n    }\n\n  /* If the next item is not a quantifier, fill in length of any previous\n  callout and create an auto callout if required. */\n\n  if (c != CHAR_ASTERISK && c != CHAR_PLUS && c != CHAR_QUESTION_MARK &&\n       (c != CHAR_LEFT_CURLY_BRACKET ||\n         (tempptr = ptr,\n         !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode))))\n    {\n    if (after_manual_callout-- <= 0)\n      {\n      parsed_pattern = manage_callouts(thisptr, &previous_callout, auto_callout,\n        parsed_pattern, cb);\n      this_parsed_item = parsed_pattern;  /* New start for current item */\n      }\n    }\n\n  /* If expect_cond_assert is 2, we have just passed (?( and are expecting an\n  assertion, possibly preceded by a callout. If the value is 1, we have just\n  had the callout and expect an assertion. There must be at least 3 more\n  characters in all cases. When expect_cond_assert is 2, we know that the\n  current character is an opening parenthesis, as otherwise we wouldn't be\n  here. However, when it is 1, we need to check, and it's easiest just to check\n  always. Note that expect_cond_assert may be negative, since all callouts just\n  decrement it. */\n\n  if (expect_cond_assert > 0)\n    {\n    BOOL ok = c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 3 &&\n              (ptr[0] == CHAR_QUESTION_MARK || ptr[0] == CHAR_ASTERISK);\n    if (ok)\n      {\n      if (ptr[0] == CHAR_ASTERISK)  /* New alpha assertion format, possibly */\n        {\n        ok = MAX_255(ptr[1]) && (cb->ctypes[ptr[1]] & ctype_lcletter) != 0;\n        }\n      else switch(ptr[1])  /* Traditional symbolic format */\n        {\n        case CHAR_C:\n        ok = expect_cond_assert == 2;\n        break;\n\n        case CHAR_EQUALS_SIGN:\n        case CHAR_EXCLAMATION_MARK:\n        break;\n\n        case CHAR_LESS_THAN_SIGN:\n        ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK;\n        break;\n\n        default:\n        ok = FALSE;\n        }\n      }\n\n    if (!ok)\n      {\n      errorcode = ERR28;\n      if (expect_cond_assert == 2) goto FAILED;\n      goto FAILED_BACK;\n      }\n    }\n\n  /* Remember whether we are expecting a conditional assertion, and set the\n  default for this item. */\n\n  prev_expect_cond_assert = expect_cond_assert;\n  expect_cond_assert = 0;\n\n  /* Remember quantification status for the previous significant item, then set\n  default for this item. */\n\n  prev_okquantifier = okquantifier;\n  prev_meta_quantifier = meta_quantifier;\n  okquantifier = FALSE;\n  meta_quantifier = 0;\n\n  /* If the previous significant item was a quantifier, adjust the parsed code\n  if there is a following modifier. The base meta value is always followed by\n  the PLUS and QUERY values, in that order. We do this here rather than after\n  reading a quantifier so that intervening comments and /x whitespace can be\n  ignored without having to replicate code. */\n\n  if (prev_meta_quantifier != 0 && (c == CHAR_QUESTION_MARK || c == CHAR_PLUS))\n    {\n    parsed_pattern[(prev_meta_quantifier == META_MINMAX)? -3 : -1] =\n      prev_meta_quantifier + ((c == CHAR_QUESTION_MARK)?\n        0x00020000u : 0x00010000u);\n    continue;  /* Next character in pattern */\n    }\n\n  /* Process the next item in the main part of a pattern. */\n\n  switch(c)\n    {\n    default:              /* Non-special character */\n    PARSED_LITERAL(c, parsed_pattern);\n    break;\n\n\n    /* ---- Escape sequence ---- */\n\n    case CHAR_BACKSLASH:\n    tempptr = ptr;\n    escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,\n      xoptions, cb->bracount, FALSE, cb);\n    if (errorcode != 0)\n      {\n      ESCAPE_FAILED:\n      if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0)\n        goto FAILED;\n      ptr = tempptr;\n      if (ptr >= ptrend) c = CHAR_BACKSLASH; else\n        {\n        GETCHARINCTEST(c, ptr);   /* Get character value, increment pointer */\n        }\n      escape = 0;                 /* Treat as literal character */\n      }\n\n    /* The escape was a data escape or literal character. */\n\n    if (escape == 0)\n      {\n      PARSED_LITERAL(c, parsed_pattern);\n      }\n\n    /* The escape was a back (or forward) reference. We keep the offset in\n    order to give a more useful diagnostic for a bad forward reference. For\n    references to groups numbered less than 10 we can't use more than two items\n    in parsed_pattern because they may be just two characters in the input (and\n    in a 64-bit world an offset may need two elements). So for them, the offset\n    of the first occurrent is held in a special vector. */\n\n    else if (escape < 0)\n      {\n      offset = (PCRE2_SIZE)(ptr - cb->start_pattern);\n      escape = -escape - 1;\n      *parsed_pattern++ = META_BACKREF | (uint32_t)escape;\n      if (escape < 10)\n        {\n        if (cb->small_ref_offset[escape] == PCRE2_UNSET)\n          cb->small_ref_offset[escape] = offset;\n        }\n      else\n        {\n        PUTOFFSET(offset, parsed_pattern);\n        }\n      okquantifier = TRUE;\n      }\n\n    /* The escape was a character class such as \\d etc. or other special\n    escape indicator such as \\A or \\X. Most of them generate just a single\n    parsed item, but \\P and \\p are followed by a 16-bit type and a 16-bit\n    value. They are supported only when Unicode is available. The type and\n    value are packed into a single 32-bit value so that the whole sequences\n    uses only two elements in the parsed_vector. This is because the same\n    coding is used if \\d (for example) is turned into \\p{Nd} when PCRE2_UCP is\n    set.\n\n    There are also some cases where the escape sequence is followed by a name:\n    \\k{name}, \\k<name>, and \\k'name' are backreferences by name, and \\g<name>\n    and \\g'name' are subroutine calls by name; \\g{name} is a synonym for\n    \\k{name}. Note that \\g<number> and \\g'number' are handled by check_escape()\n    and returned as a negative value (handled above). A name is coded as an\n    offset into the pattern and a length. */\n\n    else switch (escape)\n      {\n      case ESC_C:\n#ifdef NEVER_BACKSLASH_C\n      errorcode = ERR85;\n      goto ESCAPE_FAILED;\n#else\n      if ((options & PCRE2_NEVER_BACKSLASH_C) != 0)\n        {\n        errorcode = ERR83;\n        goto ESCAPE_FAILED;\n        }\n#endif\n      okquantifier = TRUE;\n      *parsed_pattern++ = META_ESCAPE + escape;\n      break;\n\n      /* This is a special return that happens only in EXTRA_ALT_BSUX mode,\n      when \\u{ is not followed by hex digits and }. It requests two literal\n      characters, u and { and we need this, as otherwise \\u{ 12} (for example)\n      would be treated as u{12} now that spaces are allowed in quantifiers. */\n\n      case ESC_ub:\n      *parsed_pattern++ = CHAR_u;\n      PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern);\n      break;\n\n      case ESC_X:\n#ifndef SUPPORT_UNICODE\n      errorcode = ERR45;   /* Supported only with Unicode support */\n      goto ESCAPE_FAILED;\n#endif\n      case ESC_H:\n      case ESC_h:\n      case ESC_N:\n      case ESC_R:\n      case ESC_V:\n      case ESC_v:\n      okquantifier = TRUE;\n      *parsed_pattern++ = META_ESCAPE + escape;\n      break;\n\n      default:  /* \\A, \\B, \\b, \\G, \\K, \\Z, \\z cannot be quantified. */\n      *parsed_pattern++ = META_ESCAPE + escape;\n      break;\n\n      /* Escapes that may change in UCP mode. */\n\n      case ESC_d:\n      case ESC_D:\n      case ESC_s:\n      case ESC_S:\n      case ESC_w:\n      case ESC_W:\n      okquantifier = TRUE;\n      parsed_pattern = handle_escdsw(escape, parsed_pattern, options,\n        xoptions);\n      break;\n\n      /* Unicode property matching */\n\n      case ESC_P:\n      case ESC_p:\n#ifdef SUPPORT_UNICODE\n        {\n        BOOL negated;\n        uint16_t ptype = 0, pdata = 0;\n        if (!get_ucp(&ptr, utf, &negated, &ptype, &pdata, &errorcode, cb))\n          goto ESCAPE_FAILED;\n        if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;\n        *parsed_pattern++ = META_ESCAPE + escape;\n        *parsed_pattern++ = (ptype << 16) | pdata;\n        okquantifier = TRUE;\n        }\n#else\n      errorcode = ERR45;\n      goto ESCAPE_FAILED;\n#endif\n      break;  /* End \\P and \\p */\n\n      /* When \\g is used with quotes or angle brackets as delimiters, it is a\n      numerical or named subroutine call, and control comes here. When used\n      with brace delimiters it is a numerical back reference and does not come\n      here because check_escape() returns it directly as a reference. \\k is\n      always a named back reference. */\n\n      case ESC_g:\n      case ESC_k:\n      if (ptr >= ptrend || (*ptr != CHAR_LEFT_CURLY_BRACKET &&\n          *ptr != CHAR_LESS_THAN_SIGN && *ptr != CHAR_APOSTROPHE))\n        {\n        errorcode = (escape == ESC_g)? ERR57 : ERR69;\n        goto ESCAPE_FAILED;\n        }\n      terminator = (*ptr == CHAR_LESS_THAN_SIGN)?\n        CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?\n        CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;\n\n      /* For a non-braced \\g, check for a numerical recursion. */\n\n      if (escape == ESC_g && terminator != CHAR_RIGHT_CURLY_BRACKET)\n        {\n        PCRE2_SPTR p = ptr + 1;\n\n        if (read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,\n            &errorcode))\n          {\n          if (p >= ptrend || *p != terminator)\n            {\n            ptr = p;\n            errorcode = ERR119;  /* Missing terminator for number */\n            goto ESCAPE_FAILED;\n            }\n          ptr = p + 1;\n          goto SET_RECURSION;\n          }\n        if (errorcode != 0) goto ESCAPE_FAILED;\n        }\n\n      /* Not a numerical recursion. Perl allows spaces and tabs after { and\n      before } but not for other delimiters. */\n\n      if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,\n          &errorcode, cb)) goto ESCAPE_FAILED;\n\n      /* \\k and \\g when used with braces are back references, whereas \\g used\n      with quotes or angle brackets is a recursion */\n\n      *parsed_pattern++ =\n        (escape == ESC_k || terminator == CHAR_RIGHT_CURLY_BRACKET)?\n          META_BACKREF_BYNAME : META_RECURSE_BYNAME;\n      *parsed_pattern++ = namelen;\n\n      PUTOFFSET(offset, parsed_pattern);\n      okquantifier = TRUE;\n      break;  /* End special escape processing */\n      }\n    break;    /* End escape sequence processing */\n\n\n    /* ---- Single-character special items ---- */\n\n    case CHAR_CIRCUMFLEX_ACCENT:\n    *parsed_pattern++ = META_CIRCUMFLEX;\n    break;\n\n    case CHAR_DOLLAR_SIGN:\n    *parsed_pattern++ = META_DOLLAR;\n    break;\n\n    case CHAR_DOT:\n    *parsed_pattern++ = META_DOT;\n    okquantifier = TRUE;\n    break;\n\n\n    /* ---- Single-character quantifiers ---- */\n\n    case CHAR_ASTERISK:\n    meta_quantifier = META_ASTERISK;\n    goto CHECK_QUANTIFIER;\n\n    case CHAR_PLUS:\n    meta_quantifier = META_PLUS;\n    goto CHECK_QUANTIFIER;\n\n    case CHAR_QUESTION_MARK:\n    meta_quantifier = META_QUERY;\n    goto CHECK_QUANTIFIER;\n\n\n    /* ---- Potential {n,m} quantifier ---- */\n\n    case CHAR_LEFT_CURLY_BRACKET:\n    if (!read_repeat_counts(&ptr, ptrend, &min_repeat, &max_repeat,\n        &errorcode))\n      {\n      if (errorcode != 0) goto FAILED;     /* Error in quantifier. */\n      PARSED_LITERAL(c, parsed_pattern);   /* Not a quantifier */\n      break;                               /* No more quantifier processing */\n      }\n    meta_quantifier = META_MINMAX;\n    /* Fall through */\n\n\n    /* ---- Quantifier post-processing ---- */\n\n    /* Check that a quantifier is allowed after the previous item. This\n    guarantees that there is a previous item. */\n\n    CHECK_QUANTIFIER:\n    if (!prev_okquantifier)\n      {\n      errorcode = ERR9;\n      goto FAILED;\n      }\n\n    /* Most (*VERB)s are not allowed to be quantified, but an ungreedy\n    quantifier can be useful for (*ACCEPT) - meaning \"succeed on backtrack\", a\n    sort of negated (*COMMIT). We therefore allow (*ACCEPT) to be quantified by\n    wrapping it in non-capturing brackets, but we have to allow for a preceding\n    (*MARK) for when (*ACCEPT) has an argument. */\n\n    if (*prev_parsed_item == META_ACCEPT)\n      {\n      uint32_t *p;\n      for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0];\n      *verbstartptr = META_NOCAPTURE;\n      parsed_pattern[1] = META_KET;\n      parsed_pattern += 2;\n\n#ifdef PCRE2_DEBUG\n      PCRE2_ASSERT(parsed_pattern_extra >= 2);\n      parsed_pattern_extra -= 2;\n#endif\n      }\n\n    /* Now we can put the quantifier into the parsed pattern vector. At this\n    stage, we have only the basic quantifier. The check for a following + or ?\n    modifier happens at the top of the loop, after any intervening comments\n    have been removed. */\n\n    *parsed_pattern++ = meta_quantifier;\n    if (c == CHAR_LEFT_CURLY_BRACKET)\n      {\n      *parsed_pattern++ = min_repeat;\n      *parsed_pattern++ = max_repeat;\n      }\n    break;\n\n\n    /* ---- Character class ---- */\n\n    case CHAR_LEFT_SQUARE_BRACKET:\n\n    /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is\n    used for \"start of word\" and \"end of word\". As these are otherwise illegal\n    sequences, we don't break anything by recognizing them. They are replaced\n    by \\b(?=\\w) and \\b(?<=\\w) respectively. Sequences like [a[:<:]] are\n    erroneous and are handled by the normal code below. */\n\n    if (ptrend - ptr >= 6 &&\n         (PRIV(strncmp_c8)(ptr, STRING_WEIRD_STARTWORD, 6) == 0 ||\n          PRIV(strncmp_c8)(ptr, STRING_WEIRD_ENDWORD, 6) == 0))\n      {\n      *parsed_pattern++ = META_ESCAPE + ESC_b;\n\n      if (ptr[2] == CHAR_LESS_THAN_SIGN)\n        {\n        *parsed_pattern++ = META_LOOKAHEAD;\n        }\n      else\n        {\n        *parsed_pattern++ = META_LOOKBEHIND;\n        *has_lookbehind = TRUE;\n\n        /* The offset is used only for the \"non-fixed length\" error; this won't\n        occur here, so just store zero. */\n\n        PUTOFFSET((PCRE2_SIZE)0, parsed_pattern);\n        }\n\n      if ((options & PCRE2_UCP) == 0)\n        *parsed_pattern++ = META_ESCAPE + ESC_w;\n      else\n        {\n        *parsed_pattern++ = META_ESCAPE + ESC_p;\n        *parsed_pattern++ = PT_WORD << 16;\n        }\n      *parsed_pattern++ = META_KET;\n      ptr += 6;\n      okquantifier = TRUE;\n      break;\n      }\n\n    /* PCRE supports POSIX class stuff inside a class. Perl gives an error if\n    they are encountered at the top level, so we'll do that too. */\n\n    if (ptr < ptrend && (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||\n         *ptr == CHAR_EQUALS_SIGN) &&\n        check_posix_syntax(ptr, ptrend, &tempptr))\n      {\n      errorcode = (*ptr-- == CHAR_COLON)? ERR12 : ERR13;\n      ptr = tempptr + 2;\n      goto FAILED;\n      }\n\n    class_mode_state = ((options & PCRE2_ALT_EXTENDED_CLASS) != 0)?\n        CLASS_MODE_ALT_EXT : CLASS_MODE_NORMAL;\n\n    /* Jump here from '(?[...])'. That jump must initialize class_mode_state,\n    set c to the '[' character, and ptr to just after the '['. */\n\n    FROM_PERL_EXTENDED_CLASS:\n    okquantifier = TRUE;\n\n    /* In an EBCDIC environment, Perl treats alphabetic ranges specially\n    because there are holes in the encoding, and simply using the range A-Z\n    (for example) would include the characters in the holes. This applies only\n    to ranges where both values are literal; [\\xC1-\\xE9] is different to [A-Z]\n    in this respect. In order to accommodate this, we keep track of whether\n    character values are literal or not, and a state variable for handling\n    ranges. */\n\n    /* Loop for the contents of the class. Classes may be nested, if\n    PCRE2_ALT_EXTENDED_CLASS is set, or the class is of the form (?[...]). */\n\n    /* c is still set to '[' so the loop will handle the start of the class. */\n\n    class_depth_m1 = -1;\n    class_maxdepth_m1 = -1;\n    class_range_state = RANGE_NO;\n    class_op_state = CLASS_OP_EMPTY;\n    class_start = NULL;\n\n    for (;;)\n      {\n      BOOL char_is_literal = TRUE;\n\n      /* Inside \\Q...\\E everything is literal except \\E */\n\n      if (inescq)\n        {\n        if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)\n          {\n          inescq = FALSE;                   /* Reset literal state */\n          ptr++;                            /* Skip the 'E' */\n          goto CLASS_CONTINUE;\n          }\n\n        /* Surprisingly, you cannot use \\Q..\\E to escape a character inside a\n        Perl extended class. However, empty \\Q\\E sequences are allowed, so here\n        were're only giving an error if the \\Q..\\E is non-empty. */\n\n        if (class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          errorcode = ERR116;\n          goto FAILED;\n          }\n\n        goto CLASS_LITERAL;\n        }\n\n      /* Skip over space and tab (only) in extended-more mode, or anywhere\n      inside a Perl extended class (which implies /xx). */\n\n      if ((c == CHAR_SPACE || c == CHAR_HT) &&\n          ((options & PCRE2_EXTENDED_MORE) != 0 ||\n           class_mode_state >= CLASS_MODE_PERL_EXT))\n        goto CLASS_CONTINUE;\n\n      /* Handle POSIX class names. Perl allows a negation extension of the\n      form [:^name:]. A square bracket that doesn't match the syntax is\n      treated as a literal. We also recognize the POSIX constructions\n      [.ch.] and [=ch=] (\"collating elements\") and fault them, as Perl\n      5.6 and 5.8 do. */\n\n      if (class_depth_m1 >= 0 &&\n          c == CHAR_LEFT_SQUARE_BRACKET &&\n          ptrend - ptr >= 3 &&\n          (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||\n           *ptr == CHAR_EQUALS_SIGN) &&\n          check_posix_syntax(ptr, ptrend, &tempptr))\n        {\n        BOOL posix_negate = FALSE;\n        int posix_class;\n\n        /* Perl treats a hyphen before a POSIX class as a literal, not the\n        start of a range. However, it gives a warning in its warning mode. PCRE\n        does not have a warning mode, so we give an error, because this is\n        likely an error on the user's part. */\n\n        if (class_range_state == RANGE_STARTED)\n          {\n          ptr = tempptr + 2;\n          errorcode = ERR50;\n          goto FAILED;\n          }\n\n        /* Perl treats a hyphen after a POSIX class as a literal, not the\n        start of a range. However, it gives a warning in its warning mode\n        unless the hyphen is the last character in the class. PCRE does not\n        have a warning mode, so we give an error, because this is likely an\n        error on the user's part.\n\n        Roll back to the hyphen for the error position. */\n\n        if (class_range_state == RANGE_FORBID_STARTED)\n          {\n          ptr = class_range_forbid_ptr;\n          errorcode = ERR50;\n          goto FAILED;\n          }\n\n        /* Disallow implicit union in Perl extended classes. */\n\n        if (class_op_state == CLASS_OP_OPERAND &&\n            class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          ptr = tempptr + 2;\n          errorcode = ERR113;\n          goto FAILED;\n          }\n\n        if (*ptr != CHAR_COLON)\n          {\n          ptr = tempptr + 2;\n          errorcode = ERR13;\n          goto FAILED;\n          }\n\n        if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT)\n          {\n          posix_negate = TRUE;\n          ptr++;\n          }\n\n        posix_class = check_posix_name(ptr, (int)(tempptr - ptr));\n        ptr = tempptr + 2;\n        if (posix_class < 0)\n          {\n          errorcode = ERR30;\n          goto FAILED;\n          }\n\n        /* Set \"a hyphen is forbidden to be the start of a range\". For the '-]'\n        case, the hyphen is treated as a literal, but for '-1' it is disallowed\n        (because it would be interpreted as range). */\n\n        class_range_state = RANGE_FORBID_NO;\n        class_op_state = CLASS_OP_OPERAND;\n\n        /* When PCRE2_UCP is set, unless PCRE2_EXTRA_ASCII_POSIX is set, some\n        of the POSIX classes are converted to use Unicode properties \\p or \\P\n        or, in one case, \\h or \\H. The substitutes table has two values per\n        class, containing the type and value of a \\p or \\P item. The special\n        cases are specified with a negative type: a non-zero value causes \\h or\n        \\H to be used, and a zero value falls through to behave like a non-UCP\n        POSIX class. There are now also some extra options that force ASCII for\n        some classes. */\n\n#ifdef SUPPORT_UNICODE\n        if ((options & PCRE2_UCP) != 0 &&\n            (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0 &&\n            !((xoptions & PCRE2_EXTRA_ASCII_DIGIT) != 0 &&\n              (posix_class == PC_DIGIT || posix_class == PC_XDIGIT)))\n          {\n          int ptype = posix_substitutes[2*posix_class];\n          int pvalue = posix_substitutes[2*posix_class + 1];\n\n          if (ptype >= 0)\n            {\n            *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p);\n            *parsed_pattern++ = (ptype << 16) | pvalue;\n            goto CLASS_CONTINUE;\n            }\n\n          if (pvalue != 0)\n            {\n            *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_H : ESC_h);\n            goto CLASS_CONTINUE;\n            }\n\n          /* Fall through */\n          }\n#endif  /* SUPPORT_UNICODE */\n\n        /* Non-UCP POSIX class */\n\n        *parsed_pattern++ = posix_negate? META_POSIX_NEG : META_POSIX;\n        *parsed_pattern++ = posix_class;\n        }\n\n      /* Check for the start of the outermost class, or the start of a nested class. */\n\n      else if ((c == CHAR_LEFT_SQUARE_BRACKET &&\n                (class_depth_m1 < 0 || class_mode_state == CLASS_MODE_ALT_EXT ||\n                 class_mode_state == CLASS_MODE_PERL_EXT)) ||\n               (c == CHAR_LEFT_PARENTHESIS &&\n                class_mode_state == CLASS_MODE_PERL_EXT))\n        {\n        uint32_t start_c = c;\n        uint32_t new_class_mode_state;\n\n        /* Update the class mode, if moving into a 'leaf' inside a Perl extended\n        class. */\n\n        if (start_c == CHAR_LEFT_SQUARE_BRACKET &&\n            class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 >= 0)\n          new_class_mode_state = CLASS_MODE_PERL_EXT_LEAF;\n        else\n          new_class_mode_state = class_mode_state;\n\n        /* Tidy up the other class before starting the nested class. */\n        /* -[ beginning a nested class is a literal '-' */\n\n        if (class_range_state == RANGE_STARTED)\n          parsed_pattern[-1] = CHAR_MINUS;\n\n        /* Disallow implicit union in Perl extended classes. */\n\n        if (class_op_state == CLASS_OP_OPERAND &&\n            class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          errorcode = ERR113;\n          goto FAILED;\n          }\n\n        /* Validate nesting depth */\n        if (class_depth_m1 >= ECLASS_NEST_LIMIT - 1)\n          {\n          ptr--;  /* Point rightwards at the paren, same as ERR19. */\n          errorcode = ERR107;  /* Classes too deeply nested */\n          goto FAILED;\n          }\n\n        /* Process the character class start. If the first character is '^', set\n        the negation flag. If the first few characters (either before or after ^)\n        are \\Q\\E or \\E or space or tab in extended-more mode, we skip them too.\n        This makes for compatibility with Perl. */\n\n        negate_class = FALSE;\n        for (;;)\n          {\n          if (ptr >= ptrend)\n            {\n            if (start_c == CHAR_LEFT_PARENTHESIS)\n              errorcode = ERR14;  /* Missing terminating ')' */\n            else\n              errorcode = ERR6;   /* Missing terminating ']' */\n            goto FAILED;\n            }\n\n          GETCHARINCTEST(c, ptr);\n          if (new_class_mode_state == CLASS_MODE_PERL_EXT) break;\n          else if (c == CHAR_BACKSLASH)\n            {\n            if (ptr < ptrend && *ptr == CHAR_E) ptr++;\n            else if (ptrend - ptr >= 3 &&\n                PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0)\n              ptr += 3;\n            else\n              break;\n            }\n          else if ((c == CHAR_SPACE || c == CHAR_HT) &&  /* Note: just these two */\n                   ((options & PCRE2_EXTENDED_MORE) != 0 ||\n                    new_class_mode_state >= CLASS_MODE_PERL_EXT))\n            continue;\n          else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)\n            negate_class = TRUE;\n          else break;\n          }\n\n        /* Now the real contents of the class; c has the first \"real\" character.\n        Empty classes are permitted only if the option is set, and if it's not\n        a Perl-extended class. */\n\n        if (c == CHAR_RIGHT_SQUARE_BRACKET &&\n            (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0 &&\n            new_class_mode_state < CLASS_MODE_PERL_EXT)\n          {\n          PCRE2_ASSERT(start_c == CHAR_LEFT_SQUARE_BRACKET);\n\n          if (class_start != NULL)\n            {\n            PCRE2_ASSERT(class_depth_m1 >= 0);\n            /* Represents that the class is an extended class. */\n            *class_start |= CLASS_IS_ECLASS;\n            class_start = NULL;\n            }\n\n          *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY;\n\n          /* Leave nesting depth unchanged; but check for zero depth to handle the\n          very first (top-level) class being empty. */\n          if (class_depth_m1 < 0) break;\n\n          class_range_state = RANGE_NO; /* for processing the containing class */\n          class_op_state = CLASS_OP_OPERAND;\n          goto CLASS_CONTINUE;\n          }\n\n        /* Enter a non-empty class. */\n\n        if (class_start != NULL)\n          {\n          PCRE2_ASSERT(class_depth_m1 >= 0);\n          /* Represents that the class is an extended class. */\n          *class_start |= CLASS_IS_ECLASS;\n          class_start = NULL;\n          }\n\n        class_start = parsed_pattern;\n        *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS;\n        class_range_state = RANGE_NO;\n        class_op_state = CLASS_OP_EMPTY;\n        class_mode_state = new_class_mode_state;\n        ++class_depth_m1;\n        if (class_maxdepth_m1 < class_depth_m1)\n          class_maxdepth_m1 = class_depth_m1;\n        /* Reset; no op seen yet at new depth. */\n        cb->class_op_used[class_depth_m1] = 0;\n\n        /* Implement the special start-of-class literal meaning of ']'. */\n        if (c == CHAR_RIGHT_SQUARE_BRACKET &&\n            new_class_mode_state != CLASS_MODE_PERL_EXT)\n          {\n          class_range_state = RANGE_OK_LITERAL;\n          class_op_state = CLASS_OP_OPERAND;\n          PARSED_LITERAL(c, parsed_pattern);\n          goto CLASS_CONTINUE;\n          }\n\n        continue;  /* We have already loaded c with the next character */\n        }\n\n      /* Check for the end of the class. */\n\n      else if (c == CHAR_RIGHT_SQUARE_BRACKET ||\n               (c == CHAR_RIGHT_PARENTHESIS && class_mode_state == CLASS_MODE_PERL_EXT))\n        {\n        /* In Perl extended mode, the ']' can only be used to match the\n        opening '[', and ')' must match an opening parenthesis. */\n        if (class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          if (c == CHAR_RIGHT_SQUARE_BRACKET && class_depth_m1 != 0)\n            {\n            errorcode = ERR14;\n            ptr--;  /* Correct the offset */\n            goto FAILED;\n            }\n          if (c == CHAR_RIGHT_PARENTHESIS && class_depth_m1 < 1)\n            {\n            errorcode = ERR22;\n            goto FAILED;\n            }\n          }\n\n        /* Check no trailing operator. */\n        if (class_op_state == CLASS_OP_OPERATOR)\n          {\n          errorcode = ERR110;\n          goto FAILED;\n          }\n\n        /* Check no empty expression for Perl extended expressions. */\n        if (class_mode_state == CLASS_MODE_PERL_EXT &&\n            class_op_state == CLASS_OP_EMPTY)\n          {\n          errorcode = ERR114;\n          goto FAILED;\n          }\n\n        /* -] at the end of a class is a literal '-' */\n        if (class_range_state == RANGE_STARTED)\n          parsed_pattern[-1] = CHAR_MINUS;\n\n        *parsed_pattern++ = META_CLASS_END;\n\n        if (--class_depth_m1 < 0)\n          {\n          /* Check for and consume ')' after '(?[...]'. */\n          PCRE2_ASSERT(class_mode_state != CLASS_MODE_PERL_EXT_LEAF);\n          if (class_mode_state == CLASS_MODE_PERL_EXT)\n            {\n            if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)\n              {\n              errorcode = ERR115;\n              goto FAILED;\n              }\n\n            ptr++;\n            }\n\n          break;\n          }\n\n        class_range_state = RANGE_NO; /* for processing the containing class */\n        class_op_state = CLASS_OP_OPERAND;\n        if (class_mode_state == CLASS_MODE_PERL_EXT_LEAF)\n          class_mode_state = CLASS_MODE_PERL_EXT;\n        /* The extended class flag has already\n        been set for the parent class. */\n        class_start = NULL;\n        }\n\n      /* Handle a Perl set binary operator */\n\n      else if (class_mode_state == CLASS_MODE_PERL_EXT &&\n               (c == CHAR_PLUS || c == CHAR_VERTICAL_LINE || c == CHAR_MINUS ||\n                c == CHAR_AMPERSAND || c == CHAR_CIRCUMFLEX_ACCENT))\n        {\n        /* Check that there was a preceding operand. */\n        if (class_op_state != CLASS_OP_OPERAND)\n          {\n          errorcode = ERR109;\n          goto FAILED;\n          }\n\n        if (class_start != NULL)\n          {\n          PCRE2_ASSERT(class_depth_m1 >= 0);\n          /* Represents that the class is an extended class. */\n          *class_start |= CLASS_IS_ECLASS;\n          class_start = NULL;\n          }\n\n        PCRE2_ASSERT(class_range_state != RANGE_STARTED &&\n                     class_range_state != RANGE_FORBID_STARTED);\n\n        *parsed_pattern++ = c == CHAR_PLUS? META_ECLASS_OR :\n                            c == CHAR_VERTICAL_LINE? META_ECLASS_OR :\n                            c == CHAR_MINUS? META_ECLASS_SUB :\n                            c == CHAR_AMPERSAND? META_ECLASS_AND :\n                            META_ECLASS_XOR;\n        class_range_state = RANGE_NO;\n        class_op_state = CLASS_OP_OPERATOR;\n        }\n\n      /* Handle a Perl set unary operator */\n\n      else if (class_mode_state == CLASS_MODE_PERL_EXT &&\n               c == CHAR_EXCLAMATION_MARK)\n        {\n        /* Check that the \"!\" has not got a preceding operand (i.e. it's the\n        start of the class, or follows an operator). */\n        if (class_op_state == CLASS_OP_OPERAND)\n          {\n          errorcode = ERR113;\n          goto FAILED;\n          }\n\n        if (class_start != NULL)\n          {\n          PCRE2_ASSERT(class_depth_m1 >= 0);\n          /* Represents that the class is an extended class. */\n          *class_start |= CLASS_IS_ECLASS;\n          class_start = NULL;\n          }\n\n        PCRE2_ASSERT(class_range_state != RANGE_STARTED &&\n                     class_range_state != RANGE_FORBID_STARTED);\n\n        *parsed_pattern++ = META_ECLASS_NOT;\n        class_range_state = RANGE_NO;\n        class_op_state = CLASS_OP_OPERATOR;\n        }\n\n      /* Handle a UTS#18 set operator */\n\n      else if (class_mode_state == CLASS_MODE_ALT_EXT &&\n               (c == CHAR_VERTICAL_LINE || c == CHAR_MINUS ||\n                c == CHAR_AMPERSAND || c == CHAR_TILDE) &&\n               ptr < ptrend && *ptr == c)\n        {\n        ++ptr;\n\n        /* Check there isn't a triple-repetition. */\n        if (ptr < ptrend && *ptr == c)\n          {\n          while (ptr < ptrend && *ptr == c) ++ptr;  /* Improve error offset. */\n          errorcode = ERR108;\n          goto FAILED;\n          }\n\n        /* Check for a preceding operand. */\n        if (class_op_state != CLASS_OP_OPERAND)\n          {\n          errorcode = ERR109;\n          goto FAILED;\n          }\n\n        /* Check for mixed precedence. Forbid [A--B&&C]. */\n        if (cb->class_op_used[class_depth_m1] != 0 &&\n            cb->class_op_used[class_depth_m1] != (uint8_t)c)\n          {\n          errorcode = ERR111;\n          goto FAILED;\n          }\n\n        if (class_start != NULL)\n          {\n          PCRE2_ASSERT(class_depth_m1 >= 0);\n          /* Represents that the class is an extended class. */\n          *class_start |= CLASS_IS_ECLASS;\n          class_start = NULL;\n          }\n\n        /* Dangling '-' before an operator is a literal */\n        if (class_range_state == RANGE_STARTED)\n          parsed_pattern[-1] = CHAR_MINUS;\n\n        *parsed_pattern++ = c == CHAR_VERTICAL_LINE? META_ECLASS_OR :\n                            c == CHAR_MINUS? META_ECLASS_SUB :\n                            c == CHAR_AMPERSAND? META_ECLASS_AND :\n                            META_ECLASS_XOR;\n        class_range_state = RANGE_NO;\n        class_op_state = CLASS_OP_OPERATOR;\n        cb->class_op_used[class_depth_m1] = (uint8_t)c;\n        }\n\n      /* Handle escapes in a class */\n\n      else if (c == CHAR_BACKSLASH)\n        {\n        tempptr = ptr;\n        escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,\n          xoptions, cb->bracount, TRUE, cb);\n\n        if (errorcode != 0)\n          {\n          if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0 ||\n              class_mode_state >= CLASS_MODE_PERL_EXT)\n            goto FAILED;\n          ptr = tempptr;\n          if (ptr >= ptrend) c = CHAR_BACKSLASH; else\n            {\n            GETCHARINCTEST(c, ptr);   /* Get character value, increment pointer */\n            }\n          escape = 0;                 /* Treat as literal character */\n          }\n\n        switch(escape)\n          {\n          case 0:  /* Escaped character code point is in c */\n          char_is_literal = FALSE;\n          goto CLASS_LITERAL;      /* (a few lines above) */\n\n          case ESC_b:\n          c = CHAR_BS;    /* \\b is backspace in a class */\n          char_is_literal = FALSE;\n          goto CLASS_LITERAL;\n\n          case ESC_k:\n          c = CHAR_k;     /* \\k is not special in a class, just like \\g */\n          char_is_literal = FALSE;\n          goto CLASS_LITERAL;\n\n          case ESC_Q:\n          inescq = TRUE;  /* Enter literal mode */\n          goto CLASS_CONTINUE;\n\n          case ESC_E:     /* Ignore orphan \\E */\n          goto CLASS_CONTINUE;\n\n          case ESC_B:     /* Always an error in a class */\n          case ESC_R:\n          case ESC_X:\n          errorcode = ERR7;\n          goto FAILED;\n\n          case ESC_N:     /* Not permitted by Perl either */\n          errorcode = ERR71;\n          goto FAILED;\n\n          case ESC_H:\n          case ESC_h:\n          case ESC_V:\n          case ESC_v:\n          *parsed_pattern++ = META_ESCAPE + escape;\n          break;\n\n          /* These escapes may be converted to Unicode property tests when\n          PCRE2_UCP is set. */\n\n          case ESC_d:\n          case ESC_D:\n          case ESC_s:\n          case ESC_S:\n          case ESC_w:\n          case ESC_W:\n          parsed_pattern = handle_escdsw(escape, parsed_pattern, options,\n            xoptions);\n          break;\n\n          /* Explicit Unicode property matching */\n\n          case ESC_P:\n          case ESC_p:\n#ifdef SUPPORT_UNICODE\n            {\n            BOOL negated;\n            uint16_t ptype = 0, pdata = 0;\n            if (!get_ucp(&ptr, utf, &negated, &ptype, &pdata, &errorcode, cb))\n              goto FAILED;\n\n            /* In caseless matching, particular characteristics Lu, Ll, and Lt\n            get converted to the general characteristic L&. That is, upper,\n            lower, and title case letters are all conflated. */\n\n            if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC &&\n                (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt))\n              {\n              ptype = PT_LAMP;\n              pdata = 0;\n              }\n\n            if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;\n            *parsed_pattern++ = META_ESCAPE + escape;\n            *parsed_pattern++ = (ptype << 16) | pdata;\n            }\n#else\n          errorcode = ERR45;\n          goto FAILED;\n#endif\n          break;  /* End \\P and \\p */\n\n          /* All others are not allowed in a class */\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          PCRE2_FALLTHROUGH /* Fall through */\n          /* LCOV_EXCL_STOP */\n\n          case ESC_A:\n          case ESC_Z:\n          case ESC_z:\n          case ESC_G:\n          case ESC_K:\n          case ESC_C:\n          errorcode = ERR7;\n          goto FAILED;\n          }\n\n        /* All the switch-cases above which end in \"break\" describe a set\n        of characters. None may start a range. */\n\n        /* The second part of a range can be a single-character escape\n        sequence (detected above), but not any of the other escapes. Perl\n        treats a hyphen as a literal in such circumstances. However, in Perl's\n        warning mode, a warning is given, so PCRE now faults it, as it is\n        almost certainly a mistake on the user's part. */\n\n        if (class_range_state == RANGE_STARTED)\n          {\n          errorcode = ERR50;\n          goto FAILED;\n          }\n\n        /* Perl gives a warning unless the hyphen following a multi-character\n        escape is the last character in the class. PCRE throws an error. */\n\n        if (class_range_state == RANGE_FORBID_STARTED)\n          {\n          ptr = class_range_forbid_ptr;\n          errorcode = ERR50;\n          goto FAILED;\n          }\n\n        /* Disallow implicit union in Perl extended classes. */\n\n        if (class_op_state == CLASS_OP_OPERAND &&\n            class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          errorcode = ERR113;\n          goto FAILED;\n          }\n\n        class_range_state = RANGE_FORBID_NO;\n        class_op_state = CLASS_OP_OPERAND;\n        }\n\n      /* Forbid unescaped literals, and the special meaning of '-', inside a\n      Perl extended class. */\n\n      else if (class_mode_state == CLASS_MODE_PERL_EXT)\n        {\n        errorcode = ERR116;\n        goto FAILED;\n        }\n\n      /* Handle potential start of range */\n\n      else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED)\n        {\n        *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)?\n          META_RANGE_LITERAL : META_RANGE_ESCAPED;\n        class_range_state = RANGE_STARTED;\n        }\n\n      /* Handle forbidden start of range */\n\n      else if (c == CHAR_MINUS && class_range_state == RANGE_FORBID_NO)\n        {\n        *parsed_pattern++ = CHAR_MINUS;\n        class_range_state = RANGE_FORBID_STARTED;\n        class_range_forbid_ptr = ptr;\n        }\n\n      /* Handle a literal character */\n\n      else\n        {\n        CLASS_LITERAL:\n\n        /* Disallow implicit union in Perl extended classes. */\n\n        if (class_op_state == CLASS_OP_OPERAND &&\n            class_mode_state == CLASS_MODE_PERL_EXT)\n          {\n          errorcode = ERR113;\n          goto FAILED;\n          }\n\n        if (class_range_state == RANGE_STARTED)\n          {\n          if (c == parsed_pattern[-2])       /* Optimize one-char range */\n            parsed_pattern--;\n          else if (parsed_pattern[-2] > c)   /* Check range is in order */\n            {\n            errorcode = ERR8;\n            goto FAILED;\n            }\n          else\n            {\n            if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL)\n              parsed_pattern[-1] = META_RANGE_ESCAPED;\n            PARSED_LITERAL(c, parsed_pattern);\n            }\n          class_range_state = RANGE_NO;\n          class_op_state = CLASS_OP_OPERAND;\n          }\n        else if (class_range_state == RANGE_FORBID_STARTED)\n          {\n          ptr = class_range_forbid_ptr;\n          errorcode = ERR50;\n          goto FAILED;\n          }\n        else  /* Potential start of range */\n          {\n          class_range_state = char_is_literal?\n            RANGE_OK_LITERAL : RANGE_OK_ESCAPED;\n          class_op_state = CLASS_OP_OPERAND;\n          PARSED_LITERAL(c, parsed_pattern);\n          }\n        }\n\n      /* Proceed to next thing in the class. */\n\n      CLASS_CONTINUE:\n      if (ptr >= ptrend)\n        {\n        if (class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 > 0)\n          errorcode = ERR14;   /* Missing terminating ')' */\n        if (class_mode_state == CLASS_MODE_ALT_EXT &&\n            class_depth_m1 == 0 && class_maxdepth_m1 == 1)\n          errorcode = ERR112;  /* Missing terminating ']', but we saw '[ [ ]...' */\n        else\n          errorcode = ERR6;    /* Missing terminating ']' */\n        goto FAILED;\n        }\n      GETCHARINCTEST(c, ptr);\n      }     /* End of class-processing loop */\n\n    break;  /* End of character class */\n\n\n    /* ---- Opening parenthesis ---- */\n\n    case CHAR_LEFT_PARENTHESIS:\n    if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n\n    /* If ( is not followed by ? it is either a capture or a special verb or an\n    alpha assertion or a positive non-atomic lookahead. */\n\n    if (*ptr != CHAR_QUESTION_MARK)\n      {\n      const char *vn;\n\n      /* Handle capturing brackets (or non-capturing if auto-capture is turned\n      off). */\n\n      if (*ptr != CHAR_ASTERISK)\n        {\n        nest_depth++;\n        if ((options & PCRE2_NO_AUTO_CAPTURE) == 0)\n          {\n          if (cb->bracount >= MAX_GROUP_NUMBER)\n            {\n            errorcode = ERR97;\n            goto FAILED;\n            }\n          cb->bracount++;\n          *parsed_pattern++ = META_CAPTURE | cb->bracount;\n          }\n        else *parsed_pattern++ = META_NOCAPTURE;\n        }\n\n      /* Do nothing for (* followed by end of pattern or ) so it gives a \"bad\n      quantifier\" error rather than \"(*MARK) must have an argument\". */\n\n      else if (ptrend - ptr <= 1 || (c = ptr[1]) == CHAR_RIGHT_PARENTHESIS)\n        break;\n\n      /* Handle \"alpha assertions\" such as (*pla:...). Most of these are\n      synonyms for the historical symbolic assertions, but the script run and\n      non-atomic lookaround ones are new. They are distinguished by starting\n      with a lower case letter. Checking both ends of the alphabet makes this\n      work in all character codes. */\n\n      else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0)\n        {\n        uint32_t meta;\n\n        vn = alasnames;\n        if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,\n          &errorcode, cb)) goto FAILED;\n        if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n        if (*ptr != CHAR_COLON)\n          {\n          errorcode = ERR95;  /* Malformed */\n          goto FAILED_FORWARD;\n          }\n\n        /* Scan the table of alpha assertion names */\n\n        for (i = 0; i < alascount; i++)\n          {\n          if (namelen == alasmeta[i].len &&\n              PRIV(strncmp_c8)(name, vn, namelen) == 0)\n            break;\n          vn += alasmeta[i].len + 1;\n          }\n\n        if (i >= alascount)\n          {\n          errorcode = ERR95;  /* Alpha assertion not recognized */\n          goto FAILED;\n          }\n\n        /* Check for expecting an assertion condition. If so, only atomic\n        lookaround assertions are valid. */\n\n        meta = alasmeta[i].meta;\n        if (prev_expect_cond_assert > 0 &&\n            (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT))\n          {\n          errorcode = ERR28;  /* Atomic assertion expected */\n          goto FAILED;\n          }\n\n        /* The lookaround alphabetic synonyms can mostly be handled by jumping\n        to the code that handles the traditional symbolic forms. */\n\n        switch(meta)\n          {\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          errorcode = ERR89;  /* Unknown code; should never occur because */\n          goto FAILED;        /* the meta values come from a table above. */\n          /* LCOV_EXCL_STOP */\n\n          case META_ATOMIC:\n          goto ATOMIC_GROUP;\n\n          case META_LOOKAHEAD:\n          goto POSITIVE_LOOK_AHEAD;\n\n          case META_LOOKAHEAD_NA:\n          goto POSITIVE_NONATOMIC_LOOK_AHEAD;\n\n          case META_LOOKAHEADNOT:\n          goto NEGATIVE_LOOK_AHEAD;\n\n          case META_SCS:\n          ptr++;\n          *parsed_pattern++ = META_SCS;\n\n          parsed_pattern = parse_capture_list(&ptr, ptrend, utf, parsed_pattern,\n                                              0, &errorcode, cb);\n          if (parsed_pattern == NULL) goto FAILED;\n          goto POST_ASSERTION;\n\n          case META_LOOKBEHIND:\n          case META_LOOKBEHINDNOT:\n          case META_LOOKBEHIND_NA:\n          *parsed_pattern++ = meta;\n          ptr--;\n          goto POST_LOOKBEHIND;\n\n          /* The script run facilities are handled here. Unicode support is\n          required (give an error if not, as this is a security issue). Always\n          record a META_SCRIPT_RUN item. Then, for the atomic version, insert\n          META_ATOMIC and remember that we need two META_KETs at the end. */\n\n          case META_SCRIPT_RUN:\n          case META_ATOMIC_SCRIPT_RUN:\n#ifdef SUPPORT_UNICODE\n          *parsed_pattern++ = META_SCRIPT_RUN;\n          nest_depth++;\n          ptr++;\n          if (meta == META_ATOMIC_SCRIPT_RUN)\n            {\n            *parsed_pattern++ = META_ATOMIC;\n            if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);\n            else if (++top_nest >= end_nests)\n              {\n              errorcode = ERR84;\n              goto FAILED;\n              }\n            top_nest->nest_depth = nest_depth;\n            top_nest->flags = NSF_ATOMICSR;\n            top_nest->options = options & PARSE_TRACKED_OPTIONS;\n            top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS;\n\n#ifdef PCRE2_DEBUG\n            /* We'll write out two META_KETs for a single \")\" in the input\n            pattern, so we reserve space for that in our bounds check. */\n            parsed_pattern_extra++;\n#endif\n            }\n          break;\n#else  /* SUPPORT_UNICODE */\n          errorcode = ERR96;\n          goto FAILED;\n#endif\n          }\n        }\n\n\n      /* ---- Handle (*VERB) and (*VERB:NAME) ---- */\n\n      else\n        {\n        vn = verbnames;\n        if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,\n          &errorcode, cb)) goto FAILED;\n        if (ptr >= ptrend || (*ptr != CHAR_COLON &&\n                              *ptr != CHAR_RIGHT_PARENTHESIS))\n          {\n          errorcode = ERR60;  /* Malformed */\n          goto FAILED;\n          }\n\n        /* Scan the table of verb names */\n\n        for (i = 0; i < verbcount; i++)\n          {\n          if (namelen == verbs[i].len &&\n              PRIV(strncmp_c8)(name, vn, namelen) == 0)\n            break;\n          vn += verbs[i].len + 1;\n          }\n\n        if (i >= verbcount)\n          {\n          errorcode = ERR60;  /* Verb not recognized */\n          goto FAILED;\n          }\n\n        /* An empty argument is treated as no argument. */\n\n        if (*ptr == CHAR_COLON && ptr + 1 < ptrend &&\n             ptr[1] == CHAR_RIGHT_PARENTHESIS)\n          ptr++;    /* Advance to the closing parens */\n\n        /* Check for mandatory non-empty argument; this is (*MARK) */\n\n        if (verbs[i].has_arg > 0 && *ptr != CHAR_COLON)\n          {\n          errorcode = ERR66;\n          goto FAILED;\n          }\n\n        /* Remember where this verb, possibly with a preceding (*MARK), starts,\n        for handling quantified (*ACCEPT). */\n\n        verbstartptr = parsed_pattern;\n        okquantifier = (verbs[i].meta == META_ACCEPT);\n#ifdef PCRE2_DEBUG\n        /* Reserve space in our bounds check for optionally wrapping the (*ACCEPT)\n        with a non-capturing bracket, if there is a following quantifier. */\n        if (okquantifier) parsed_pattern_extra += 2;\n#endif\n\n        /* It appears that Perl allows any characters whatsoever, other than a\n        closing parenthesis, to appear in arguments (\"names\"), so we no longer\n        insist on letters, digits, and underscores. Perl does not, however, do\n        any interpretation within arguments, and has no means of including a\n        closing parenthesis. PCRE supports escape processing but only when it\n        is requested by an option. We set inverbname TRUE here, and let the\n        main loop take care of this so that escape and \\x processing is done by\n        the main code above. */\n\n        if (*ptr++ == CHAR_COLON)   /* Skip past : or ) */\n          {\n          /* Some optional arguments can be treated as a preceding (*MARK) */\n\n          if (verbs[i].has_arg < 0)\n            {\n            add_after_mark = verbs[i].meta;\n            *parsed_pattern++ = META_MARK;\n            }\n\n          /* The remaining verbs with arguments (except *MARK) need a different\n          opcode. */\n\n          else\n            {\n            *parsed_pattern++ = verbs[i].meta +\n              ((verbs[i].meta != META_MARK)? 0x00010000u:0);\n            }\n\n          /* Set up for reading the name in the main loop. */\n\n          verblengthptr = parsed_pattern++;\n          verbnamestart = ptr;\n          inverbname = TRUE;\n          }\n        else  /* No verb \"name\" argument */\n          {\n          *parsed_pattern++ = verbs[i].meta;\n          }\n        }     /* End of (*VERB) handling */\n      break;  /* Done with this parenthesis */\n      }       /* End of groups that don't start with (? */\n\n\n    /* ---- Items starting (? ---- */\n\n    /* The type of item is determined by what follows (?. Handle (?| and option\n    changes under \"default\" because both need a new block on the nest stack.\n    Comments starting with (?# are handled above. Note that there is some\n    ambiguity about the sequence (?- because if a digit follows it's a relative\n    recursion or subroutine call whereas otherwise it's an option unsetting. */\n\n    if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n\n    switch(*ptr)\n      {\n      default:\n      if (*ptr == CHAR_MINUS && ptrend - ptr > 1 && IS_DIGIT(ptr[1]))\n        goto RECURSION_BYNUMBER;  /* The + case is handled by CHAR_PLUS */\n\n      /* We now have either (?| or a (possibly empty) option setting,\n      optionally followed by a non-capturing group. */\n\n      nest_depth++;\n      if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);\n      else if (++top_nest >= end_nests)\n        {\n        errorcode = ERR84;\n        goto FAILED;\n        }\n      top_nest->nest_depth = nest_depth;\n      top_nest->flags = 0;\n      top_nest->options = options & PARSE_TRACKED_OPTIONS;\n      top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS;\n\n      /* Start of non-capturing group that resets the capture count for each\n      branch. */\n\n      if (*ptr == CHAR_VERTICAL_LINE)\n        {\n        top_nest->reset_group = (uint16_t)cb->bracount;\n        top_nest->max_group = (uint16_t)cb->bracount;\n        top_nest->flags |= NSF_RESET;\n        cb->external_flags |= PCRE2_DUPCAPUSED;\n        *parsed_pattern++ = META_NOCAPTURE;\n        ptr++;\n        }\n\n      /* Scan for options imnrsxJU to be set or unset. */\n\n      else\n        {\n        BOOL hyphenok = TRUE;\n        uint32_t oldoptions = options;\n        uint32_t oldxoptions = xoptions;\n\n        top_nest->reset_group = 0;\n        top_nest->max_group = 0;\n        set = unset = 0;\n        optset = &set;\n        xset = xunset = 0;\n        xoptset = &xset;\n\n        /* ^ at the start unsets irmnsx and disables the subsequent use of - */\n\n        if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT)\n          {\n          options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE|\n                       PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE);\n          xoptions &= ~(PCRE2_EXTRA_CASELESS_RESTRICT);\n          hyphenok = FALSE;\n          ptr++;\n          }\n\n        while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS &&\n                               *ptr != CHAR_COLON)\n          {\n          switch (*ptr++)\n            {\n            case CHAR_MINUS:\n            if (!hyphenok)\n              {\n              errorcode = ERR94;\n              goto FAILED;\n              }\n            optset = &unset;\n            xoptset = &xunset;\n            hyphenok = FALSE;\n            break;\n\n            /* There are some two-character sequences that start with 'a'. */\n\n            case CHAR_a:\n            if (ptr < ptrend)\n              {\n              if (*ptr == CHAR_D)\n                {\n                *xoptset |= PCRE2_EXTRA_ASCII_BSD;\n                ptr++;\n                break;\n                }\n              if (*ptr == CHAR_P)\n                {\n                *xoptset |= (PCRE2_EXTRA_ASCII_POSIX|PCRE2_EXTRA_ASCII_DIGIT);\n                ptr++;\n                break;\n                }\n              if (*ptr == CHAR_S)\n                {\n                *xoptset |= PCRE2_EXTRA_ASCII_BSS;\n                ptr++;\n                break;\n                }\n              if (*ptr == CHAR_T)\n                {\n                *xoptset |= PCRE2_EXTRA_ASCII_DIGIT;\n                ptr++;\n                break;\n                }\n              if (*ptr == CHAR_W)\n                {\n                *xoptset |= PCRE2_EXTRA_ASCII_BSW;\n                ptr++;\n                break;\n                }\n              }\n            *xoptset |= PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS|\n                        PCRE2_EXTRA_ASCII_BSW|\n                        PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX;\n            break;\n\n            case CHAR_J:  /* Record that it changed in the external options */\n            *optset |= PCRE2_DUPNAMES;\n            cb->external_flags |= PCRE2_JCHANGED;\n            break;\n\n            case CHAR_i: *optset |= PCRE2_CASELESS; break;\n            case CHAR_m: *optset |= PCRE2_MULTILINE; break;\n            case CHAR_n: *optset |= PCRE2_NO_AUTO_CAPTURE; break;\n            case CHAR_r: *xoptset|= PCRE2_EXTRA_CASELESS_RESTRICT; break;\n            case CHAR_s: *optset |= PCRE2_DOTALL; break;\n            case CHAR_U: *optset |= PCRE2_UNGREEDY; break;\n\n            /* If x appears twice it sets the extended extended option. */\n\n            case CHAR_x:\n            *optset |= PCRE2_EXTENDED;\n            if (ptr < ptrend && *ptr == CHAR_x)\n              {\n              *optset |= PCRE2_EXTENDED_MORE;\n              ptr++;\n              }\n            break;\n\n            default:\n            errorcode = ERR11;\n            goto FAILED;\n            }\n          }\n\n        /* If we are setting extended without extended-more, ensure that any\n        existing extended-more gets unset. Also, unsetting extended must also\n        unset extended-more. */\n\n        if ((set & (PCRE2_EXTENDED|PCRE2_EXTENDED_MORE)) == PCRE2_EXTENDED ||\n            (unset & PCRE2_EXTENDED) != 0)\n          unset |= PCRE2_EXTENDED_MORE;\n\n        options = (options | set) & (~unset);\n        xoptions = (xoptions | xset) & (~xunset);\n\n        /* If the options ended with ')' this is not the start of a nested\n        group with option changes, so the options change at this level.\n        In this case, if the previous level set up a nest block, discard the\n        one we have just created. Otherwise adjust it for the previous level.\n        If the options ended with ':' we are starting a non-capturing group,\n        possibly with an options setting. */\n\n        if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n        if (*ptr++ == CHAR_RIGHT_PARENTHESIS)\n          {\n          nest_depth--;  /* This is not a nested group after all. */\n          if (top_nest > (nest_save *)(cb->start_workspace) &&\n              (top_nest-1)->nest_depth == nest_depth) top_nest--;\n          else top_nest->nest_depth = nest_depth;\n          }\n        else *parsed_pattern++ = META_NOCAPTURE;\n\n        /* If nothing changed, no need to record. */\n\n        if (options != oldoptions || xoptions != oldxoptions)\n          {\n          *parsed_pattern++ = META_OPTIONS;\n          *parsed_pattern++ = options;\n          *parsed_pattern++ = xoptions;\n          }\n        }     /* End options processing */\n      break;  /* End default case after (? */\n\n\n      /* ---- Python syntax support ---- */\n\n      case CHAR_P:\n      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n\n      /* (?P<name> is the same as (?<name>, which defines a named group. */\n\n      if (*ptr == CHAR_LESS_THAN_SIGN)\n        {\n        terminator = CHAR_GREATER_THAN_SIGN;\n        goto DEFINE_NAME;\n        }\n\n      /* (?P>name) is the same as (?&name), which is a recursion or subroutine\n      call. */\n\n      if (*ptr == CHAR_GREATER_THAN_SIGN) goto RECURSE_BY_NAME;\n\n      /* (?P=name) is the same as \\k<name>, a back reference by name. Anything\n      else after (?P is an error. */\n\n      if (*ptr != CHAR_EQUALS_SIGN)\n        {\n        errorcode = ERR41;\n        goto FAILED_FORWARD;\n        }\n      if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name,\n          &namelen, &errorcode, cb)) goto FAILED;\n      *parsed_pattern++ = META_BACKREF_BYNAME;\n      *parsed_pattern++ = namelen;\n      PUTOFFSET(offset, parsed_pattern);\n      okquantifier = TRUE;\n      break;   /* End of (?P processing */\n\n\n      /* ---- Recursion/subroutine calls by number ---- */\n\n      case CHAR_R:\n      i = 0;         /* (?R) == (?R0) */\n      ptr++;\n      if (ptr >= ptrend || (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_LEFT_PARENTHESIS))\n        {\n        errorcode = ERR58;\n        goto FAILED;\n        }\n      terminator = CHAR_NUL;\n      goto SET_RECURSION;\n\n      /* An item starting (?- followed by a digit comes here via the \"default\"\n      case because (?- followed by a non-digit is an options setting. */\n\n      case CHAR_PLUS:\n      if (ptr + 1 >= ptrend)\n        {\n        ++ptr;\n        goto UNCLOSED_PARENTHESIS;\n        }\n      if (!IS_DIGIT(ptr[1]))\n        {\n        errorcode = ERR29;   /* Missing number */\n        ++ptr;\n        goto FAILED_FORWARD;\n        }\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:\n      case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:\n      RECURSION_BYNUMBER:\n      if (!read_number(&ptr, ptrend,\n          (IS_DIGIT(*ptr))? -1:(int)(cb->bracount), /* + and - are relative */\n          MAX_GROUP_NUMBER, ERR61,\n          &i, &errorcode)) goto FAILED;\n      PCRE2_ASSERT(i >= 0);  /* NB (?0) is permitted, represented by i=0 */\n      terminator = CHAR_NUL;\n\n      SET_RECURSION:\n      *parsed_pattern++ = META_RECURSE | (uint32_t)i;\n      offset = (PCRE2_SIZE)(ptr - cb->start_pattern);\n      /* End of recursive call by number handling */\n      goto READ_RECURSION_ARGUMENTS;\n\n\n      /* ---- Recursion/subroutine calls by name ---- */\n\n      case CHAR_AMPERSAND:\n      RECURSE_BY_NAME:\n      if (!read_name(&ptr, ptrend, utf, 0, &offset, &name,\n          &namelen, &errorcode, cb)) goto FAILED;\n      *parsed_pattern++ = META_RECURSE_BYNAME;\n      *parsed_pattern++ = namelen;\n      terminator = CHAR_NUL;\n\n      READ_RECURSION_ARGUMENTS:\n      PUTOFFSET(offset, parsed_pattern);\n      okquantifier = TRUE;\n\n      /* Arguments are not supported for \\g construct. */\n      if (terminator != CHAR_NUL) break;\n\n      if (ptr < ptrend && *ptr == CHAR_LEFT_PARENTHESIS)\n        {\n        parsed_pattern = parse_capture_list(&ptr, ptrend, utf, parsed_pattern,\n                                            offset, &errorcode, cb);\n        if (parsed_pattern == NULL) goto FAILED;\n        }\n\n      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)\n        goto UNCLOSED_PARENTHESIS;\n\n      ptr++;\n      break;\n\n      /* ---- Callout with numerical or string argument ---- */\n\n      case CHAR_C:\n      if ((xoptions & PCRE2_EXTRA_NEVER_CALLOUT) != 0)\n        {\n        ptr++;\n        errorcode = ERR103;\n        goto FAILED;\n        }\n\n      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n\n      /* If the previous item was a condition starting (?(? an assertion,\n      optionally preceded by a callout, is expected. This is checked later on,\n      during actual compilation. However we need to identify this kind of\n      assertion in this pass because it must not be qualified. The value of\n      expect_cond_assert is set to 2 after (?(? is processed. We decrement it\n      for a callout - still leaving a positive value that identifies the\n      assertion. Multiple callouts or any other items will make it zero or\n      less, which doesn't matter because they will cause an error later. */\n\n      expect_cond_assert = prev_expect_cond_assert - 1;\n\n      /* If previous_callout is not NULL, it means this follows a previous\n      callout. If it was a manual callout, do nothing; this means its \"length\n      of next pattern item\" field will remain zero. If it was an automatic\n      callout, abolish it. */\n\n      if (previous_callout != NULL && (options & PCRE2_AUTO_CALLOUT) != 0 &&\n          previous_callout == parsed_pattern - 4 &&\n          parsed_pattern[-1] == 255)\n        parsed_pattern = previous_callout;\n\n      /* Save for updating next pattern item length, and skip one item before\n      completing. */\n\n      previous_callout = parsed_pattern;\n      after_manual_callout = 1;\n\n      /* Handle a string argument; specific delimiter is required. */\n\n      if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr))\n        {\n        PCRE2_SIZE calloutlength;\n        PCRE2_SPTR startptr = ptr;\n\n        delimiter = 0;\n        for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)\n          {\n          if (*ptr == PRIV(callout_start_delims)[i])\n            {\n            delimiter = PRIV(callout_end_delims)[i];\n            break;\n            }\n          }\n        if (delimiter == 0)\n          {\n          errorcode = ERR82;\n          goto FAILED_FORWARD;\n          }\n\n        *parsed_pattern = META_CALLOUT_STRING;\n        parsed_pattern += 3;   /* Skip pattern info */\n\n        for (;;)\n          {\n          if (++ptr >= ptrend)\n            {\n            errorcode = ERR81;\n            ptr = startptr;   /* To give a more useful message */\n            goto FAILED;\n            }\n          if (*ptr == delimiter && (++ptr >= ptrend || *ptr != delimiter))\n            break;\n          }\n\n        calloutlength = (PCRE2_SIZE)(ptr - startptr);\n        if (calloutlength > UINT32_MAX)\n          {\n          errorcode = ERR72;\n          goto FAILED;\n          }\n        *parsed_pattern++ = (uint32_t)calloutlength;\n        offset = (PCRE2_SIZE)(startptr - cb->start_pattern);\n        PUTOFFSET(offset, parsed_pattern);\n        }\n\n      /* Handle a callout with an optional numerical argument, which must be\n      less than or equal to 255. A missing argument gives 0. */\n\n      else\n        {\n        int n = 0;\n        *parsed_pattern = META_CALLOUT_NUMBER;     /* Numerical callout */\n        parsed_pattern += 3;                       /* Skip pattern info */\n        while (ptr < ptrend && IS_DIGIT(*ptr))\n          {\n          n = n * 10 + (*ptr++ - CHAR_0);\n          if (n > 255)\n            {\n            errorcode = ERR38;\n            goto FAILED;\n            }\n          }\n        *parsed_pattern++ = n;\n        }\n\n      /* Both formats must have a closing parenthesis */\n\n      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)\n        {\n        errorcode = ERR39;\n        goto FAILED;\n        }\n      ptr++;\n\n      /* Remember the offset to the next item in the pattern, and set a default\n      length. This should get updated after the next item is read. */\n\n      previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);\n      previous_callout[2] = 0;\n      break;                  /* End callout */\n\n\n      /* ---- Conditional group ---- */\n\n      /* A condition can be an assertion, a number (referring to a numbered\n      group's having been set), a name (referring to a named group), or 'R',\n      referring to overall recursion. R<digits> and R&name are also permitted\n      for recursion state tests. Numbers may be preceded by + or - to specify a\n      relative group number.\n\n      There are several syntaxes for testing a named group: (?(name)) is used\n      by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).\n\n      There are two unfortunate ambiguities. 'R' can be the recursive thing or\n      the name 'R' (and similarly for 'R' followed by digits). 'DEFINE' can be\n      the Perl DEFINE feature or the Python named test. We look for a name\n      first; if not found, we try the other case.\n\n      For compatibility with auto-callouts, we allow a callout to be specified\n      before a condition that is an assertion. */\n\n      case CHAR_LEFT_PARENTHESIS:\n      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;\n      nest_depth++;\n\n      /* If the next character is ? or * there must be an assertion next\n      (optionally preceded by a callout). We do not check this here, but\n      instead we set expect_cond_assert to 2. If this is still greater than\n      zero (callouts decrement it) when the next assertion is read, it will be\n      marked as a condition that must not be repeated. A value greater than\n      zero also causes checking that an assertion (possibly with callout)\n      follows. */\n\n      if (*ptr == CHAR_QUESTION_MARK || *ptr == CHAR_ASTERISK)\n        {\n        *parsed_pattern++ = META_COND_ASSERT;\n        ptr--;   /* Pull pointer back to the opening parenthesis. */\n        expect_cond_assert = 2;\n        break;  /* End of conditional */\n        }\n\n      /* Handle (?([+-]number)... */\n\n      if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,\n          &errorcode))\n        {\n        PCRE2_ASSERT(i >= 0);\n        if (i <= 0)\n          {\n          errorcode = ERR15;\n          goto FAILED;\n          }\n        *parsed_pattern++ = META_COND_NUMBER;\n        offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);\n        PUTOFFSET(offset, parsed_pattern);\n        *parsed_pattern++ = i;\n        }\n      else if (errorcode != 0) goto FAILED;   /* Number too big */\n\n      /* No number found. Handle the special case (?(VERSION[>]=n.m)... */\n\n      else if (ptrend - ptr >= 10 &&\n               PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 &&\n               ptr[7] != CHAR_RIGHT_PARENTHESIS)\n        {\n        uint32_t ge = 0;\n        int major = 0;\n        int minor = 0;\n\n        ptr += 7;\n        if (*ptr == CHAR_GREATER_THAN_SIGN)\n          {\n          ge = 1;\n          ptr++;\n          }\n\n        /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT\n        references its argument twice. */\n\n        if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))\n          {\n          errorcode = ERR79;\n          if (!ge) goto FAILED_FORWARD;\n          goto FAILED;\n          }\n\n        if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &major, &errorcode))\n          goto FAILED;\n\n        if (ptr < ptrend && *ptr == CHAR_DOT)\n          {\n          if (++ptr >= ptrend || !IS_DIGIT(*ptr))\n            {\n            errorcode = ERR79;\n            if (ptr < ptrend) goto FAILED_FORWARD;\n            goto FAILED;\n            }\n          if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &minor, &errorcode))\n            goto FAILED;\n          }\n        if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)\n          {\n          errorcode = ERR79;\n          if (ptr < ptrend) goto FAILED_FORWARD;\n          goto FAILED;\n          }\n\n        *parsed_pattern++ = META_COND_VERSION;\n        *parsed_pattern++ = ge;\n        *parsed_pattern++ = major;\n        *parsed_pattern++ = minor;\n        }\n\n      /* All the remaining cases now require us to read a name. We cannot at\n      this stage distinguish ambiguous cases such as (?(R12) which might be a\n      recursion test by number or a name, because the named groups have not yet\n      all been identified. Those cases are treated as names, but given a\n      different META code. */\n\n      else\n        {\n        BOOL was_r_ampersand = FALSE;\n\n        if (*ptr == CHAR_R && ptrend - ptr > 1 && ptr[1] == CHAR_AMPERSAND)\n          {\n          terminator = CHAR_RIGHT_PARENTHESIS;\n          was_r_ampersand = TRUE;\n          ptr++;\n          }\n        else if (*ptr == CHAR_LESS_THAN_SIGN)\n          terminator = CHAR_GREATER_THAN_SIGN;\n        else if (*ptr == CHAR_APOSTROPHE)\n          terminator = CHAR_APOSTROPHE;\n        else\n          {\n          terminator = CHAR_RIGHT_PARENTHESIS;\n          ptr--;   /* Point to char before name */\n          }\n\n        if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,\n            &errorcode, cb)) goto FAILED;\n\n        /* Handle (?(R&name) */\n\n        if (was_r_ampersand)\n          {\n          *parsed_pattern = META_COND_RNAME;\n          ptr--;   /* Back to closing parens */\n          }\n\n        /* Handle (?(name). If the name is \"DEFINE\" we identify it with a\n        special code. Likewise if the name consists of R followed only by\n        digits. Otherwise, handle it like a quoted name. */\n\n        else if (terminator == CHAR_RIGHT_PARENTHESIS)\n          {\n          if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0)\n            *parsed_pattern = META_COND_DEFINE;\n          else\n            {\n            for (i = 1; i < (int)namelen; i++)\n              if (!IS_DIGIT(name[i])) break;\n            *parsed_pattern = (*name == CHAR_R && i >= (int)namelen)?\n              META_COND_RNUMBER : META_COND_NAME;\n            }\n          ptr--;   /* Back to closing parens */\n          }\n\n        /* Handle (?('name') or (?(<name>) */\n\n        else *parsed_pattern = META_COND_NAME;\n\n        /* All these cases except DEFINE end with the name length and offset;\n        DEFINE just has an offset (for the \"too many branches\" error). */\n\n        if (*parsed_pattern++ != META_COND_DEFINE) *parsed_pattern++ = namelen;\n        PUTOFFSET(offset, parsed_pattern);\n        }  /* End cases that read a name */\n\n      /* Check the closing parenthesis of the condition */\n\n      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)\n        {\n        errorcode = ERR24;\n        goto FAILED;\n        }\n      ptr++;\n      break;  /* End of condition processing */\n\n\n      /* ---- Atomic group ---- */\n\n      case CHAR_GREATER_THAN_SIGN:\n      ATOMIC_GROUP:                          /* Come from (*atomic: */\n      *parsed_pattern++ = META_ATOMIC;\n      nest_depth++;\n      ptr++;\n      break;\n\n\n      /* ---- Lookahead assertions ---- */\n\n      case CHAR_EQUALS_SIGN:\n      POSITIVE_LOOK_AHEAD:                   /* Come from (*pla: */\n      *parsed_pattern++ = META_LOOKAHEAD;\n      ptr++;\n      goto POST_ASSERTION;\n\n      case CHAR_ASTERISK:\n      POSITIVE_NONATOMIC_LOOK_AHEAD:         /* Come from (*napla: */\n      *parsed_pattern++ = META_LOOKAHEAD_NA;\n      ptr++;\n      goto POST_ASSERTION;\n\n      case CHAR_EXCLAMATION_MARK:\n      NEGATIVE_LOOK_AHEAD:                   /* Come from (*nla: */\n      *parsed_pattern++ = META_LOOKAHEADNOT;\n      ptr++;\n      goto POST_ASSERTION;\n\n\n      /* ---- Lookbehind assertions ---- */\n\n      /* (?< followed by = or ! or * is a lookbehind assertion. Otherwise (?<\n      is the start of the name of a capturing group. */\n\n      case CHAR_LESS_THAN_SIGN:\n      if (ptrend - ptr <= 1 ||\n         (ptr[1] != CHAR_EQUALS_SIGN &&\n          ptr[1] != CHAR_EXCLAMATION_MARK &&\n          ptr[1] != CHAR_ASTERISK))\n        {\n        terminator = CHAR_GREATER_THAN_SIGN;\n        goto DEFINE_NAME;\n        }\n      *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?\n        META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)?\n        META_LOOKBEHINDNOT : META_LOOKBEHIND_NA;\n\n      POST_LOOKBEHIND:           /* Come from (*plb: (*naplb: and (*nlb: */\n      *has_lookbehind = TRUE;\n      offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);\n      PUTOFFSET(offset, parsed_pattern);\n      ptr += 2;\n      /* Fall through */\n\n      /* If the previous item was a condition starting (?(? an assertion,\n      optionally preceded by a callout, is expected. This is checked later on,\n      during actual compilation. However we need to identify this kind of\n      assertion in this pass because it must not be qualified. The value of\n      expect_cond_assert is set to 2 after (?(? is processed. We decrement it\n      for a callout - still leaving a positive value that identifies the\n      assertion. Multiple callouts or any other items will make it zero or\n      less, which doesn't matter because they will cause an error later. */\n\n      POST_ASSERTION:\n      nest_depth++;\n      if (prev_expect_cond_assert > 0)\n        {\n        if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);\n        else if (++top_nest >= end_nests)\n          {\n          errorcode = ERR84;\n          goto FAILED;\n          }\n        top_nest->nest_depth = nest_depth;\n        top_nest->flags = NSF_CONDASSERT;\n        top_nest->options = options & PARSE_TRACKED_OPTIONS;\n        top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS;\n        }\n      break;\n\n\n      /* ---- Define a named group ---- */\n\n      /* A named group may be defined as (?'name') or (?<name>). In the latter\n      case we jump to DEFINE_NAME from the disambiguation of (?< above with the\n      terminator set to '>'. */\n\n      case CHAR_APOSTROPHE:\n      terminator = CHAR_APOSTROPHE;    /* Terminator */\n\n      DEFINE_NAME:\n      if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,\n          &errorcode, cb)) goto FAILED;\n\n      /* We have a name for this capturing group. It is also assigned a number,\n      which is its primary means of identification. */\n\n      if (cb->bracount >= MAX_GROUP_NUMBER)\n        {\n        errorcode = ERR97;\n        goto FAILED;\n        }\n      cb->bracount++;\n      *parsed_pattern++ = META_CAPTURE | cb->bracount;\n      nest_depth++;\n\n      /* Check not too many names */\n\n      if (cb->names_found >= MAX_NAME_COUNT)\n        {\n        errorcode = ERR49;\n        goto FAILED;\n        }\n\n      /* Adjust the entry size to accommodate the longest name found. */\n\n      if (namelen + IMM2_SIZE + 1 > cb->name_entry_size)\n        cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1);\n\n      /* Scan the list to check for duplicates. For duplicate names, if the\n      number is the same, break the loop, which causes the name to be\n      discarded; otherwise, if DUPNAMES is not set, give an error.\n      If it is set, allow the name with a different number, but continue\n      scanning in case this is a duplicate with the same number. For\n      non-duplicate names, give an error if the number is duplicated. */\n\n      is_dupname = FALSE;\n      hash = PRIV(compile_get_hash_from_name)(name, namelen);\n      ng = cb->named_groups;\n      for (i = 0; i < cb->names_found; i++, ng++)\n        {\n        if (namelen == ng->length && hash == NAMED_GROUP_GET_HASH(ng) &&\n            PRIV(strncmp)(name, ng->name, (PCRE2_SIZE)namelen) == 0)\n          {\n          /* When a bracket is referenced by the same name multiple\n          times, is not considered as a duplicate and ignored. */\n          if (ng->number == cb->bracount) break;\n          if ((options & PCRE2_DUPNAMES) == 0)\n            {\n            errorcode = ERR43;\n            goto FAILED;\n            }\n\n          ng->hash_dup |= NAMED_GROUP_IS_DUPNAME;\n          is_dupname = TRUE;                /* Mark as a duplicate */\n          cb->dupnames = TRUE;              /* Duplicate names exist */\n\n          /* The entry represents a duplicate. */\n          name = ng->name;\n          namelen = 0;\n\n          /* Even duplicated names may refer to the same\n          capture index. These references are also ignored. */\n          for (; i < cb->names_found; i++, ng++)\n            if (ng->name == name && ng->number == cb->bracount)\n              break;\n          break;\n          }\n        else if (ng->number == cb->bracount)\n          {\n          errorcode = ERR65;\n          goto FAILED;\n          }\n        }\n\n      /* Ignore duplicate with same number. */\n      if (i < cb->names_found) break;\n\n      /* Increase the list size if necessary */\n\n      if (cb->names_found >= cb->named_group_list_size)\n        {\n        uint32_t newsize = cb->named_group_list_size * 2;\n        named_group *newspace =\n          cb->cx->memctl.malloc(newsize * sizeof(named_group),\n          cb->cx->memctl.memory_data);\n        if (newspace == NULL)\n          {\n          errorcode = ERR21;\n          goto FAILED;\n          }\n\n        memcpy(newspace, cb->named_groups,\n          cb->named_group_list_size * sizeof(named_group));\n        if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE)\n          cb->cx->memctl.free((void *)cb->named_groups,\n          cb->cx->memctl.memory_data);\n        cb->named_groups = newspace;\n        cb->named_group_list_size = newsize;\n        }\n\n      /* Add this name to the list */\n      if (is_dupname)\n        hash |= NAMED_GROUP_IS_DUPNAME;\n\n      cb->named_groups[cb->names_found].name = name;\n      cb->named_groups[cb->names_found].length = (uint16_t)namelen;\n      cb->named_groups[cb->names_found].number = cb->bracount;\n      cb->named_groups[cb->names_found].hash_dup = hash;\n      cb->names_found++;\n      break;\n\n\n      /* ---- Perl extended character class ---- */\n\n      /* These are of the form '(?[...])'. We handle these via the same parser\n      that consumes ordinary '[...]' classes, but with a flag set to activate\n      the extended behaviour. */\n\n      case CHAR_LEFT_SQUARE_BRACKET:\n      class_mode_state = CLASS_MODE_PERL_EXT;\n      c = *ptr++;\n      goto FROM_PERL_EXTENDED_CLASS;\n      }        /* End of (? switch */\n    break;     /* End of ( handling */\n\n\n    /* ---- Branch terminators ---- */\n\n    /* Alternation: reset the capture count if we are in a (?| group. */\n\n    case CHAR_VERTICAL_LINE:\n    if (top_nest != NULL && top_nest->nest_depth == nest_depth &&\n        (top_nest->flags & NSF_RESET) != 0)\n      {\n      if (cb->bracount > top_nest->max_group)\n        top_nest->max_group = (uint16_t)cb->bracount;\n      cb->bracount = top_nest->reset_group;\n      }\n    *parsed_pattern++ = META_ALT;\n    break;\n\n    /* End of group; reset the capture count to the maximum if we are in a (?|\n    group and/or reset the options that are tracked during parsing. Disallow\n    quantifier for a condition that is an assertion. */\n\n    case CHAR_RIGHT_PARENTHESIS:\n    okquantifier = TRUE;\n    if (top_nest != NULL && top_nest->nest_depth == nest_depth)\n      {\n      options = (options & ~PARSE_TRACKED_OPTIONS) | top_nest->options;\n      xoptions = (xoptions & ~PARSE_TRACKED_EXTRA_OPTIONS) | top_nest->xoptions;\n      if ((top_nest->flags & NSF_RESET) != 0 &&\n          top_nest->max_group > cb->bracount)\n        cb->bracount = top_nest->max_group;\n      if ((top_nest->flags & NSF_CONDASSERT) != 0)\n        okquantifier = FALSE;\n\n      if ((top_nest->flags & NSF_ATOMICSR) != 0)\n        {\n        *parsed_pattern++ = META_KET;\n\n#ifdef PCRE2_DEBUG\n        PCRE2_ASSERT(parsed_pattern_extra > 0);\n        parsed_pattern_extra--;\n#endif\n        }\n\n      if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;\n        else top_nest--;\n      }\n    if (nest_depth == 0)    /* Unmatched closing parenthesis */\n      {\n      errorcode = ERR22;\n      goto FAILED;\n      }\n    nest_depth--;\n    *parsed_pattern++ = META_KET;\n    break;\n    }  /* End of switch on pattern character */\n  }    /* End of main character scan loop */\n\n/* End of pattern reached. Check for missing ) at the end of a verb name. */\n\nif (inverbname && ptr >= ptrend)\n  {\n  errorcode = ERR60;\n  goto FAILED;\n  }\n\n\nPARSED_END:\n\nPCRE2_ASSERT((parsed_pattern - parsed_pattern_check) +\n             (parsed_pattern_extra - parsed_pattern_extra_check) <=\n               max_parsed_pattern(ptr_check, ptr, utf, options));\n\n/* Manage callout for the final item */\n\nparsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout,\n  parsed_pattern, cb);\n\n/* Insert trailing items for word and line matching (features provided for the\nbenefit of pcre2grep). */\n\nif ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0)\n  {\n  *parsed_pattern++ = META_KET;\n  *parsed_pattern++ = META_DOLLAR;\n  }\nelse if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0)\n  {\n  *parsed_pattern++ = META_KET;\n  *parsed_pattern++ = META_ESCAPE + ESC_b;\n  }\n\n/* Terminate the parsed pattern, then return success if all groups are closed.\nOtherwise we have unclosed parentheses. */\n\n/* LCOV_EXCL_START */\nif (parsed_pattern >= parsed_pattern_end)\n  {\n  PCRE2_DEBUG_UNREACHABLE();\n  errorcode = ERR63;  /* Internal error (parsed pattern overflow) */\n  goto FAILED;\n  }\n/* LCOV_EXCL_STOP */\n\n*parsed_pattern = META_END;\nif (nest_depth == 0) return 0;\n\nUNCLOSED_PARENTHESIS:\nerrorcode = ERR14;\n\n/* Come here for all failures. */\n\nFAILED:\ncb->erroroffset = (PCRE2_SIZE)(ptr - cb->start_pattern);\nreturn errorcode;\n\n/* Some errors need to indicate the previous character. */\n\nFAILED_BACK:\nptr--;\n#ifdef SUPPORT_UNICODE\nif (utf) BACKCHAR(ptr);\n#endif\ngoto FAILED;\n\n/* Some errors need to indicate the next character. */\n\nFAILED_FORWARD:\nptr++;\n#ifdef SUPPORT_UNICODE\nif (utf) FORWARDCHARTEST(ptr, ptrend);\n#endif\ngoto FAILED;\n}\n\n\n\n/*************************************************\n*       Find first significant opcode            *\n*************************************************/\n\n/* This is called by several functions that scan a compiled expression looking\nfor a fixed first character, or an anchoring opcode etc. It skips over things\nthat do not influence this. For some calls, it makes sense to skip negative\nforward and all backward assertions, and also the \\b assertion; for others it\ndoes not.\n\nArguments:\n  code         pointer to the start of the group\n  skipassert   TRUE if certain assertions are to be skipped\n\nReturns:       pointer to the first significant opcode\n*/\n\nstatic const PCRE2_UCHAR*\nfirst_significant_code(PCRE2_SPTR code, BOOL skipassert)\n{\nfor (;;)\n  {\n  switch ((int)*code)\n    {\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERTBACK_NA:\n    if (!skipassert) return code;\n    do code += GET(code, 1); while (*code == OP_ALT);\n    code += PRIV(OP_lengths)[*code];\n    break;\n\n    case OP_WORD_BOUNDARY:\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    if (!skipassert) return code;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_CALLOUT:\n    case OP_CREF:\n    case OP_DNCREF:\n    case OP_RREF:\n    case OP_DNRREF:\n    case OP_FALSE:\n    case OP_TRUE:\n    code += PRIV(OP_lengths)[*code];\n    break;\n\n    case OP_CALLOUT_STR:\n    code += GET(code, 1 + 2*LINK_SIZE);\n    break;\n\n    case OP_SKIPZERO:\n    code += 2 + GET(code, 2) + LINK_SIZE;\n    break;\n\n    case OP_COND:\n    case OP_SCOND:\n    if (code[1+LINK_SIZE] != OP_FALSE ||   /* Not DEFINE */\n        code[GET(code, 1)] != OP_KET)      /* More than one branch */\n      return code;\n    code += GET(code, 1) + 1 + LINK_SIZE;\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_SKIP_ARG:\n    case OP_THEN_ARG:\n    code += code[1] + PRIV(OP_lengths)[*code];\n    break;\n\n    default:\n    return code;\n    }\n  }\n\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*           Compile one branch                   *\n*************************************************/\n\n/* Scan the parsed pattern, compiling it into the a vector of PCRE2_UCHAR. If\nthe options are changed during the branch, the pointer is used to change the\nexternal options bits. This function is used during the pre-compile phase when\nwe are trying to find out the amount of memory needed, as well as during the\nreal compile phase. The value of lengthptr distinguishes the two phases.\n\nArguments:\n  optionsptr        pointer to the option bits\n  xoptionsptr       pointer to the extra option bits\n  codeptr           points to the pointer to the current code point\n  pptrptr           points to the current parsed pattern pointer\n  errorcodeptr      points to error code variable\n  firstcuptr        place to put the first required code unit\n  firstcuflagsptr   place to put the first code unit flags\n  reqcuptr          place to put the last required code unit\n  reqcuflagsptr     place to put the last required code unit flags\n  bcptr             points to current branch chain\n  open_caps         points to current capitem\n  cb                contains pointers to tables etc.\n  lengthptr         NULL during the real compile phase\n                    points to length accumulator during pre-compile phase\n\nReturns:            0 There's been an error, *errorcodeptr is non-zero\n                   +1 Success, this branch must match at least one character\n                   -1 Success, this branch may match an empty string\n*/\n\nstatic int\ncompile_branch(uint32_t *optionsptr, uint32_t *xoptionsptr,\n  PCRE2_UCHAR **codeptr, uint32_t **pptrptr, int *errorcodeptr,\n  uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr,\n  uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps,\n  compile_block *cb, PCRE2_SIZE *lengthptr)\n{\nint bravalue = 0;\nint okreturn = -1;\nint group_return = 0;\nuint32_t repeat_min = 0, repeat_max = 0;      /* To please picky compilers */\nuint32_t greedy_default, greedy_non_default;\nuint32_t repeat_type, op_type;\nuint32_t options = *optionsptr;               /* May change dynamically */\nuint32_t xoptions = *xoptionsptr;             /* May change dynamically */\nuint32_t firstcu, reqcu;\nuint32_t zeroreqcu, zerofirstcu;\nuint32_t *pptr = *pptrptr;\nuint32_t meta, meta_arg;\nuint32_t firstcuflags, reqcuflags;\nuint32_t zeroreqcuflags, zerofirstcuflags;\nuint32_t req_caseopt, reqvary, tempreqvary;\n/* Some opcodes, such as META_CAPTURE_NUMBER or META_CAPTURE_NAME,\ndepends on the previous value of offset. */\nPCRE2_SIZE offset = 0;\nPCRE2_SIZE length_prevgroup = 0;\nPCRE2_UCHAR *code = *codeptr;\nPCRE2_UCHAR *last_code = code;\nPCRE2_UCHAR *orig_code = code;\nPCRE2_UCHAR *tempcode;\nPCRE2_UCHAR *previous = NULL;\nPCRE2_UCHAR op_previous;\nBOOL groupsetfirstcu = FALSE;\nBOOL had_accept = FALSE;\nBOOL matched_char = FALSE;\nBOOL previous_matched_char = FALSE;\nBOOL reset_caseful = FALSE;\n\n/* We can fish out the UTF setting once and for all into a BOOL, but we must\nnot do this for other options (e.g. PCRE2_EXTENDED) that may change dynamically\nas we process the pattern. */\n\n#ifdef SUPPORT_UNICODE\nBOOL utf = (options & PCRE2_UTF) != 0;\nBOOL ucp = (options & PCRE2_UCP) != 0;\n#else  /* No Unicode support */\nBOOL utf = FALSE;\n#endif\n\n/* Set up the default and non-default settings for greediness */\n\ngreedy_default = ((options & PCRE2_UNGREEDY) != 0);\ngreedy_non_default = greedy_default ^ 1;\n\n/* Initialize no first unit, no required unit. REQ_UNSET means \"no char\nmatching encountered yet\". It gets changed to REQ_NONE if we hit something that\nmatches a non-fixed first unit; reqcu just remains unset if we never find one.\n\nWhen we hit a repeat whose minimum is zero, we may have to adjust these values\nto take the zero repeat into account. This is implemented by setting them to\nzerofirstcu and zeroreqcu when such a repeat is encountered. The individual\nitem types that can be repeated set these backoff variables appropriately. */\n\nfirstcu = reqcu = zerofirstcu = zeroreqcu = 0;\nfirstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET;\n\n/* The variable req_caseopt contains either the REQ_CASELESS bit or zero,\naccording to the current setting of the caseless flag. The REQ_CASELESS value\nleaves the lower 28 bit empty. It is added into the firstcu or reqcu variables\nto record the case status of the value. This is used only for ASCII characters.\n*/\n\nreq_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;\n\n/* Switch on next META item until the end of the branch */\n\nfor (;; pptr++)\n  {\n  BOOL possessive_quantifier;\n  BOOL note_group_empty;\n  uint32_t mclength;\n  uint32_t skipunits;\n  uint32_t subreqcu, subfirstcu;\n  uint32_t groupnumber;\n  uint32_t verbarglen, verbculen;\n  uint32_t subreqcuflags, subfirstcuflags;\n  open_capitem *oc;\n  PCRE2_UCHAR mcbuffer[8];\n\n  /* Get next META item in the pattern and its potential argument. */\n\n  meta = META_CODE(*pptr);\n  meta_arg = META_DATA(*pptr);\n\n  /* If we are in the pre-compile phase, accumulate the length used for the\n  previous cycle of this loop, unless the next item is a quantifier. */\n\n  if (lengthptr != NULL)\n    {\n    /* LCOV_EXCL_START */\n    if (code >= cb->start_workspace + cb->workspace_size)\n      {\n      PCRE2_DEBUG_UNREACHABLE();\n      *errorcodeptr = ERR52;  /* Over-ran workspace - internal error */\n      cb->erroroffset = 0;\n      return 0;\n      }\n    /* LCOV_EXCL_STOP */\n\n    if (code > cb->start_workspace + cb->workspace_size -\n        WORK_SIZE_SAFETY_MARGIN)                       /* Check for overrun */\n      {\n      *errorcodeptr = ERR86;  /* Pattern too complicated */\n      cb->erroroffset = 0;\n      return 0;\n      }\n\n    /* There is at least one situation where code goes backwards: this is the\n    case of a zero quantifier after a class (e.g. [ab]{0}). When the quantifier\n    is processed, the whole class is eliminated. However, it is created first,\n    so we have to allow memory for it. Therefore, don't ever reduce the length\n    at this point. */\n\n    if (code < last_code) code = last_code;\n\n    /* If the next thing is not a quantifier, we add the length of the previous\n    item into the total, and reset the code pointer to the start of the\n    workspace. Otherwise leave the previous item available to be quantified. */\n\n    if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)\n      {\n      if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))\n        {\n        *errorcodeptr = ERR20;   /* Integer overflow */\n        cb->erroroffset = 0;\n        return 0;\n        }\n      *lengthptr += (PCRE2_SIZE)(code - orig_code);\n      if (*lengthptr > MAX_PATTERN_SIZE)\n        {\n        *errorcodeptr = ERR20;   /* Pattern is too large */\n        cb->erroroffset = 0;\n        return 0;\n        }\n      code = orig_code;\n      }\n\n    /* Remember where this code item starts so we can catch the \"backwards\"\n    case above next time round. */\n\n    last_code = code;\n    }\n\n  /* Process the next parsed pattern item. If it is not a quantifier, remember\n  where it starts so that it can be quantified when a quantifier follows.\n  Checking for the legality of quantifiers happens in parse_regex(), except for\n  a quantifier after an assertion that is a condition. */\n\n  if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)\n    {\n    previous = code;\n    if (matched_char && !had_accept) okreturn = 1;\n    }\n\n  previous_matched_char = matched_char;\n  matched_char = FALSE;\n  note_group_empty = FALSE;\n  skipunits = 0;         /* Default value for most subgroups */\n\n  switch(meta)\n    {\n    /* ===================================================================*/\n    /* The branch terminates at pattern end or | or ) */\n\n    case META_END:\n    case META_ALT:\n    case META_KET:\n    *firstcuptr = firstcu;\n    *firstcuflagsptr = firstcuflags;\n    *reqcuptr = reqcu;\n    *reqcuflagsptr = reqcuflags;\n    *codeptr = code;\n    *pptrptr = pptr;\n    return okreturn;\n\n\n    /* ===================================================================*/\n    /* Handle single-character metacharacters. In multiline mode, ^ disables\n    the setting of any following char as a first character. */\n\n    case META_CIRCUMFLEX:\n    if ((options & PCRE2_MULTILINE) != 0)\n      {\n      if (firstcuflags == REQ_UNSET)\n        zerofirstcuflags = firstcuflags = REQ_NONE;\n      *code++ = OP_CIRCM;\n      }\n    else *code++ = OP_CIRC;\n    break;\n\n    case META_DOLLAR:\n    *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;\n    break;\n\n    /* There can never be a first char if '.' is first, whatever happens about\n    repeats. The value of reqcu doesn't change either. */\n\n    case META_DOT:\n    matched_char = TRUE;\n    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    zeroreqcu = reqcu;\n    zeroreqcuflags = reqcuflags;\n    *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY;\n    break;\n\n\n    /* ===================================================================*/\n    /* Empty character classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set.\n    Otherwise, an initial ']' is taken as a data character. When empty classes\n    are allowed, [] must generate an empty class - we have no dedicated opcode\n    to optimise the representation, but it's a rare case (the '(*FAIL)'\n    construct would be a clearer way for a pattern author to represent a\n    non-matching branch, but it does have different semantics to '[]' if both\n    are followed by a quantifier). The empty-negated [^] matches any character,\n    so is useful: generate OP_ALLANY for this. */\n\n    case META_CLASS_EMPTY:\n    case META_CLASS_EMPTY_NOT:\n    matched_char = TRUE;\n    if (meta == META_CLASS_EMPTY_NOT) *code++ = OP_ALLANY;\n    else\n      {\n      *code++ = OP_CLASS;\n      memset(code, 0, 32);\n      code += 32 / sizeof(PCRE2_UCHAR);\n      }\n\n    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    break;\n\n\n    /* ===================================================================*/\n    /* Non-empty character class. If the included characters are all < 256, we\n    build a 32-byte bitmap of the permitted characters, except in the special\n    case where there is only one such character. For negated classes, we build\n    the map as usual, then invert it at the end. However, we use a different\n    opcode so that data characters > 255 can be handled correctly.\n\n    If the class contains characters outside the 0-255 range, a different\n    opcode is compiled. It may optionally have a bit map for characters < 256,\n    but those above are explicitly listed afterwards. A flag code unit tells\n    whether the bitmap is present, and whether this is a negated class or\n    not. */\n\n    case META_CLASS_NOT:\n    case META_CLASS:\n    matched_char = TRUE;\n\n    /* Check for complex extended classes and handle them separately. */\n\n    if ((*pptr & CLASS_IS_ECLASS) != 0)\n      {\n      if (!PRIV(compile_class_nested)(options, xoptions, &pptr, &code,\n                                      errorcodeptr, cb, lengthptr))\n        return 0;\n      goto CLASS_END_PROCESSING;\n      }\n\n    /* We can optimize the case of a single character in a class by generating\n    OP_CHAR or OP_CHARI if it's positive, or OP_NOT or OP_NOTI if it's\n    negative. In the negative case there can be no first char if this item is\n    first, whatever repeat count may follow. In the case of reqcu, save the\n    previous value for reinstating. */\n\n    /* NOTE: at present this optimization is not effective if the only\n    character in a class in 32-bit, non-UCP mode has its top bit set. */\n\n    if (pptr[1] < META_END && pptr[2] == META_CLASS_END)\n      {\n      uint32_t c = pptr[1];\n\n      pptr += 2;                 /* Move on to class end */\n      if (meta == META_CLASS)    /* A positive one-char class can be */\n        {                        /* handled as a normal literal character. */\n        meta = c;                /* Set up the character */\n        goto NORMAL_CHAR_SET;\n        }\n\n      /* Handle a negative one-character class */\n\n      zeroreqcu = reqcu;\n      zeroreqcuflags = reqcuflags;\n      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n      zerofirstcu = firstcu;\n      zerofirstcuflags = firstcuflags;\n\n      /* For caseless UTF or UCP mode, check whether this character has more\n      than one other case. If so, generate a special OP_NOTPROP item instead of\n      OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any\n      caseless set that starts with an ASCII character. If the character is\n      affected by the special Turkish rules, hardcode the not-matching\n      characters using a caseset. */\n\n#ifdef SUPPORT_UNICODE\n      if ((utf||ucp) && (options & PCRE2_CASELESS) != 0)\n        {\n        uint32_t caseset;\n\n        if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) ==\n              PCRE2_EXTRA_TURKISH_CASING &&\n            UCD_ANY_I(c))\n          {\n          caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3);\n          }\n        else if ((caseset = UCD_CASESET(c)) != 0 &&\n                 (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 &&\n                 PRIV(ucd_caseless_sets)[caseset] < 128)\n          {\n          caseset = 0;  /* Ignore the caseless set if it's restricted. */\n          }\n\n        if (caseset != 0)\n          {\n          *code++ = OP_NOTPROP;\n          *code++ = PT_CLIST;\n          *code++ = caseset;\n          break;   /* We are finished with this class */\n          }\n        }\n#endif\n      /* Char has only one other (usable) case, or UCP not available */\n\n      *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT;\n      code += PUTCHAR(c, code);\n      break;   /* We are finished with this class */\n      }        /* End of 1-char optimization */\n\n    /* Handle character classes that contain more than just one literal\n    character. If there are exactly two characters in a positive class, see if\n    they are case partners. This can be optimized to generate a caseless single\n    character match (which also sets first/required code units if relevant).\n    When casing restrictions apply, ignore a caseless set if both characters\n    are ASCII. When Turkish casing applies, an 'i' does not match its normal\n    Unicode \"othercase\". */\n\n    if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END &&\n        pptr[3] == META_CLASS_END)\n      {\n      uint32_t c = pptr[1];\n\n#ifdef SUPPORT_UNICODE\n      if ((UCD_CASESET(c) == 0 ||\n           ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 &&\n            c < 128 && pptr[2] < 128)) &&\n          !((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) ==\n              PCRE2_EXTRA_TURKISH_CASING &&\n            UCD_ANY_I(c)))\n#endif\n        {\n        uint32_t d;\n\n#ifdef SUPPORT_UNICODE\n        if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else\n#endif\n          {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          if (c > 255) d = c; else\n#endif\n          d = TABLE_GET(c, cb->fcc, c);\n          }\n\n        if (c != d && pptr[2] == d)\n          {\n          pptr += 3;                 /* Move on to class end */\n          meta = c;\n          if ((options & PCRE2_CASELESS) == 0)\n            {\n            reset_caseful = TRUE;\n            options |= PCRE2_CASELESS;\n            req_caseopt = REQ_CASELESS;\n            }\n          goto CLASS_CASELESS_CHAR;\n          }\n        }\n      }\n\n    /* Now emit the OP_CLASS/OP_NCLASS/OP_XCLASS/OP_ALLANY opcode. */\n\n    pptr = PRIV(compile_class_not_nested)(options, xoptions, pptr + 1,\n                                          &code, meta == META_CLASS_NOT, NULL,\n                                          errorcodeptr, cb, lengthptr);\n    if (pptr == NULL) return 0;\n    PCRE2_ASSERT(*pptr == META_CLASS_END);\n\n    CLASS_END_PROCESSING:\n\n    /* If this class is the first thing in the branch, there can be no first\n    char setting, whatever the repeat count. Any reqcu setting must remain\n    unchanged after any kind of repeat. */\n\n    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    zeroreqcu = reqcu;\n    zeroreqcuflags = reqcuflags;\n    break;  /* End of class processing */\n\n\n    /* ===================================================================*/\n    /* Deal with (*VERB)s. */\n\n    /* Check for open captures before ACCEPT and close those that are within\n    the same assertion level, also converting ACCEPT to ASSERT_ACCEPT in an\n    assertion. In the first pass, just accumulate the length required;\n    otherwise hitting (*ACCEPT) inside many nested parentheses can cause\n    workspace overflow. Do not set firstcu after *ACCEPT. */\n\n    case META_ACCEPT:\n    cb->had_accept = had_accept = TRUE;\n    for (oc = open_caps;\n         oc != NULL && oc->assert_depth >= cb->assert_depth;\n         oc = oc->next)\n      {\n      if (lengthptr != NULL)\n        {\n        *lengthptr += CU2BYTES(1) + IMM2_SIZE;\n        }\n      else\n        {\n        *code++ = OP_CLOSE;\n        PUT2INC(code, 0, oc->number);\n        }\n      }\n    *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;\n    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n    break;\n\n    case META_PRUNE:\n    case META_SKIP:\n    cb->had_pruneorskip = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case META_COMMIT:\n    case META_FAIL:\n    *code++ = verbops[(meta - META_MARK) >> 16];\n    break;\n\n    case META_THEN:\n    cb->external_flags |= PCRE2_HASTHEN;\n    *code++ = OP_THEN;\n    break;\n\n    /* Handle verbs with arguments. Arguments can be very long, especially in\n    16- and 32-bit modes, and can overflow the workspace in the first pass.\n    However, the argument length is constrained to be small enough to fit in\n    one code unit. This check happens in parse_regex(). In the first pass,\n    instead of putting the argument into memory, we just update the length\n    counter and set up an empty argument. */\n\n    case META_THEN_ARG:\n    cb->external_flags |= PCRE2_HASTHEN;\n    goto VERB_ARG;\n\n    case META_PRUNE_ARG:\n    case META_SKIP_ARG:\n    cb->had_pruneorskip = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case META_MARK:\n    case META_COMMIT_ARG:\n    VERB_ARG:\n    *code++ = verbops[(meta - META_MARK) >> 16];\n    /* The length is in characters. */\n    verbarglen = *(++pptr);\n    verbculen = 0;\n    tempcode = code++;\n    for (int i = 0; i < (int)verbarglen; i++)\n      {\n      meta = *(++pptr);\n#ifdef SUPPORT_UNICODE\n      if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else\n#endif\n        {\n        mclength = 1;\n        mcbuffer[0] = meta;\n        }\n      if (lengthptr != NULL) *lengthptr += mclength; else\n        {\n        memcpy(code, mcbuffer, CU2BYTES(mclength));\n        code += mclength;\n        verbculen += mclength;\n        }\n      }\n\n    *tempcode = verbculen;   /* Fill in the code unit length */\n    *code++ = 0;             /* Terminating zero */\n    break;\n\n\n    /* ===================================================================*/\n    /* Handle options change. The new setting must be passed back for use in\n    subsequent branches. Reset the greedy defaults and the case value for\n    firstcu and reqcu. */\n\n    case META_OPTIONS:\n    *optionsptr = options = *(++pptr);\n    *xoptionsptr = xoptions = *(++pptr);\n    greedy_default = ((options & PCRE2_UNGREEDY) != 0);\n    greedy_non_default = greedy_default ^ 1;\n    req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;\n    break;\n\n    /* ===================================================================*/\n    /* Handle scan substring. Scan substring assertion starts with META_SCS,\n    which recursively calls compile_branch. The first opcode processed by\n    this recursive call is always META_OFFSET. */\n\n    case META_OFFSET:\n    if (lengthptr != NULL)\n      {\n      pptr = PRIV(compile_parse_scan_substr_args)(pptr, errorcodeptr, cb, lengthptr);\n      if (pptr == NULL)\n        return 0;\n      break;\n      }\n\n    while (TRUE)\n      {\n      int count, index;\n      named_group *ng;\n\n      switch (META_CODE(*pptr))\n        {\n        case META_OFFSET:\n        pptr++;\n        SKIPOFFSET(pptr);\n        continue;\n\n        case META_CAPTURE_NAME:\n        ng = cb->named_groups + pptr[1];\n        pptr += 2;\n        count = 0;\n        index = 0;\n\n        if (!PRIV(compile_find_dupname_details)(ng->name, ng->length, &index,\n          &count, errorcodeptr, cb)) return 0;\n\n        code[0] = OP_DNCREF;\n        PUT2(code, 1, index);\n        PUT2(code, 1 + IMM2_SIZE, count);\n        code += 1 + 2 * IMM2_SIZE;\n        continue;\n\n        case META_CAPTURE_NUMBER:\n        pptr += 2;\n        if (pptr[-1] == 0) continue;\n\n        code[0] = OP_CREF;\n        PUT2(code, 1, pptr[-1]);\n        code += 1 + IMM2_SIZE;\n        continue;\n\n        default:\n        break;\n        }\n\n      break;\n      }\n    --pptr;\n    break;\n\n    case META_SCS:\n    bravalue = OP_ASSERT_SCS;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n\n    /* ===================================================================*/\n    /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous\n    because it could be a numerical check on recursion, or a name check on a\n    group's being set. The pre-pass sets up META_COND_RNUMBER as a name so that\n    we can handle it either way. We first try for a name; if not found, process\n    the number. */\n\n    case META_COND_RNUMBER:   /* (?(Rdigits) */\n    case META_COND_NAME:      /* (?(name) or (?'name') or ?(<name>) */\n    case META_COND_RNAME:     /* (?(R&name) - test for recursion */\n    bravalue = OP_COND;\n\n    if (lengthptr != NULL)\n      {\n      uint32_t i;\n      PCRE2_SPTR name;\n      named_group *ng;\n      uint32_t *start_pptr = pptr;\n      uint32_t length = *(++pptr);\n\n      GETPLUSOFFSET(offset, pptr);\n      name = cb->start_pattern + offset;\n\n      /* In the first pass, the names generated in the pre-pass are available,\n      but the main name table has not yet been created. Scan the list of names\n      generated in the pre-pass in order to get a number and whether or not\n      this name is duplicated. If it is not duplicated, we can handle it as a\n      numerical group. */\n\n      ng = PRIV(compile_find_named_group)(name, length, cb);\n\n      if (ng == NULL)\n        {\n        /* If the name was not found we have a bad reference, unless we are\n        dealing with R<digits>, which is treated as a recursion test by\n        number. */\n\n        groupnumber = 0;\n        if (meta == META_COND_RNUMBER)\n          {\n          for (i = 1; i < length; i++)\n            {\n            groupnumber = groupnumber * 10 + (name[i] - CHAR_0);\n            if (groupnumber > MAX_GROUP_NUMBER)\n              {\n              *errorcodeptr = ERR61;\n              cb->erroroffset = offset + i;\n              return 0;\n              }\n            }\n          }\n\n        if (meta != META_COND_RNUMBER || groupnumber > cb->bracount)\n          {\n          *errorcodeptr = ERR15;\n          cb->erroroffset = offset;\n          return 0;\n          }\n\n        /* (?Rdigits) treated as a recursion reference by number. A value of\n        zero (which is the result of both (?R) and (?R0)) means \"any\", and is\n        translated into RREF_ANY (which is 0xffff). */\n\n        if (groupnumber == 0) groupnumber = RREF_ANY;\n        PCRE2_ASSERT(start_pptr[0] == META_COND_RNUMBER);\n        start_pptr[1] = groupnumber;\n        skipunits = 1+IMM2_SIZE;\n        goto GROUP_PROCESS_NOTE_EMPTY;\n        }\n\n      /* From here on, we know we have a name (not a number),\n      so treat META_COND_RNUMBER the same as META_COND_NAME. */\n      if (meta == META_COND_RNUMBER) meta = META_COND_NAME;\n\n      if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)\n        {\n        /* Found a non-duplicated name. Since it is a global,\n        it is enough to update it in the pre-processing phase. */\n        if (ng->number > cb->top_backref) cb->top_backref = ng->number;\n\n        start_pptr[0] = meta;\n        start_pptr[1] = ng->number;\n\n        skipunits = 1 + IMM2_SIZE;\n        goto GROUP_PROCESS_NOTE_EMPTY;\n        }\n\n      /* We have a duplicated name. In the compile pass we have to search the\n      main table in order to get the index and count values. */\n\n      start_pptr[0] = meta | 1;\n      start_pptr[1] = (uint32_t)(ng - cb->named_groups);\n\n      /* A duplicated name was found. Note that if an R<digits> name is found\n      (META_COND_RNUMBER), it is a reference test, not a recursion test. */\n      skipunits = 1 + 2 * IMM2_SIZE;\n      }\n    else\n      {\n      /* Otherwise lengthptr equals to NULL,\n      which is the second phase of compilation. */\n      int count, index;\n      named_group *ng;\n\n      /* Generate code using the data\n      collected in the pre-processing phase. */\n\n      if (meta == META_COND_RNUMBER)\n        {\n        code[1+LINK_SIZE] = OP_RREF;\n        PUT2(code, 2 + LINK_SIZE, pptr[1]);\n        skipunits = 1 + IMM2_SIZE;\n        pptr += 1 + SIZEOFFSET;\n        goto GROUP_PROCESS_NOTE_EMPTY;\n        }\n\n      if (meta_arg == 0)\n        {\n        code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;\n        PUT2(code, 2 + LINK_SIZE, pptr[1]);\n        skipunits = 1 + IMM2_SIZE;\n        pptr += 1 + SIZEOFFSET;\n        goto GROUP_PROCESS_NOTE_EMPTY;\n        }\n\n      ng = cb->named_groups + pptr[1];\n      count = 0;  /* Values for first pass (avoids compiler warning) */\n      index = 0;\n\n      /* The failed case is an internal error. */\n      if (!PRIV(compile_find_dupname_details)(ng->name, ng->length, &index,\n            &count, errorcodeptr, cb)) return 0;\n\n      /* A duplicated name was found. Note that if an R<digits> name is found\n      (META_COND_RNUMBER), it is a reference test, not a recursion test. */\n\n      code[1 + LINK_SIZE] = (meta == META_COND_RNAME)? OP_DNRREF : OP_DNCREF;\n\n      /* Insert appropriate data values. */\n      PUT2(code, 2 + LINK_SIZE, index);\n      PUT2(code, 2 + LINK_SIZE + IMM2_SIZE, count);\n      skipunits = 1 + 2 * IMM2_SIZE;\n      pptr += 1 + SIZEOFFSET;\n      }\n\n    PCRE2_ASSERT(meta != META_CAPTURE_NAME);\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n    /* The DEFINE condition is always false. Its internal groups may never\n    be called, so matched_char must remain false, hence the jump to\n    GROUP_PROCESS rather than GROUP_PROCESS_NOTE_EMPTY. */\n\n    case META_COND_DEFINE:\n    bravalue = OP_COND;\n    GETPLUSOFFSET(offset, pptr);\n    code[1+LINK_SIZE] = OP_DEFINE;\n    skipunits = 1;\n    goto GROUP_PROCESS;\n\n    /* Conditional test of a group's being set. */\n\n    case META_COND_NUMBER:\n    bravalue = OP_COND;\n    GETPLUSOFFSET(offset, pptr);\n\n    groupnumber = *(++pptr);\n    if (groupnumber > cb->bracount)\n      {\n      *errorcodeptr = ERR15;\n      cb->erroroffset = offset;\n      return 0;\n      }\n    if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;\n\n    /* Point at initial ( for too many branches error */\n    offset -= 2;\n    code[1+LINK_SIZE] = OP_CREF;\n    skipunits = 1+IMM2_SIZE;\n    PUT2(code, 2+LINK_SIZE, groupnumber);\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n    /* Test for the PCRE2 version. */\n\n    case META_COND_VERSION:\n    bravalue = OP_COND;\n    if (pptr[1] > 0)\n      code[1+LINK_SIZE] = ((PCRE2_MAJOR > pptr[2]) ||\n        (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR >= pptr[3]))?\n          OP_TRUE : OP_FALSE;\n    else\n      code[1+LINK_SIZE] = (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR == pptr[3])?\n        OP_TRUE : OP_FALSE;\n    skipunits = 1;\n    pptr += 3;\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n    /* The condition is an assertion, possibly preceded by a callout. */\n\n    case META_COND_ASSERT:\n    bravalue = OP_COND;\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n\n    /* ===================================================================*/\n    /* Handle all kinds of nested bracketed groups. The non-capturing,\n    non-conditional cases are here; others come to GROUP_PROCESS via goto. */\n\n    case META_LOOKAHEAD:\n    bravalue = OP_ASSERT;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n    case META_LOOKAHEAD_NA:\n    bravalue = OP_ASSERT_NA;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n    /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird\n    thing to do, but Perl allows all assertions to be quantified, and when\n    they contain capturing parentheses there may be a potential use for\n    this feature. Not that that applies to a quantified (?!) but we allow\n    it for uniformity. */\n\n    case META_LOOKAHEADNOT:\n    if (pptr[1] == META_KET &&\n         (pptr[2] < META_ASTERISK || pptr[2] > META_MINMAX_QUERY))\n      {\n      *code++ = OP_FAIL;\n      pptr++;\n      }\n    else\n      {\n      bravalue = OP_ASSERT_NOT;\n      cb->assert_depth += 1;\n      goto GROUP_PROCESS;\n      }\n    break;\n\n    case META_LOOKBEHIND:\n    bravalue = OP_ASSERTBACK;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n    case META_LOOKBEHINDNOT:\n    bravalue = OP_ASSERTBACK_NOT;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n    case META_LOOKBEHIND_NA:\n    bravalue = OP_ASSERTBACK_NA;\n    cb->assert_depth += 1;\n    goto GROUP_PROCESS;\n\n    case META_ATOMIC:\n    bravalue = OP_ONCE;\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n    case META_SCRIPT_RUN:\n    bravalue = OP_SCRIPT_RUN;\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n    case META_NOCAPTURE:\n    bravalue = OP_BRA;\n    /* Fall through */\n\n    /* Process nested bracketed regex. The nesting depth is maintained for the\n    benefit of the stackguard function. The test for too deep nesting is now\n    done in parse_regex(). Assertion and DEFINE groups come to GROUP_PROCESS;\n    others come to GROUP_PROCESS_NOTE_EMPTY, to indicate that we need to take\n    note of whether or not they may match an empty string. */\n\n    GROUP_PROCESS_NOTE_EMPTY:\n    note_group_empty = TRUE;\n\n    GROUP_PROCESS:\n    cb->parens_depth += 1;\n    *code = bravalue;\n    pptr++;\n    tempcode = code;\n    tempreqvary = cb->req_varyopt;        /* Save value before group */\n    length_prevgroup = 0;                 /* Initialize for pre-compile phase */\n\n    if ((group_return =\n         compile_regex(\n         options,                         /* The options state */\n         xoptions,                        /* The extra options state */\n         &tempcode,                       /* Where to put code (updated) */\n         &pptr,                           /* Input pointer (updated) */\n         errorcodeptr,                    /* Where to put an error message */\n         skipunits,                       /* Skip over bracket number */\n         &subfirstcu,                     /* For possible first char */\n         &subfirstcuflags,\n         &subreqcu,                       /* For possible last char */\n         &subreqcuflags,\n         bcptr,                           /* Current branch chain */\n         open_caps,                       /* Pointer to capture stack */\n         cb,                              /* Compile data block */\n         (lengthptr == NULL)? NULL :      /* Actual compile phase */\n           &length_prevgroup              /* Pre-compile phase */\n         )) == 0)\n      return 0;  /* Error */\n\n    cb->parens_depth -= 1;\n\n    /* If that was a non-conditional significant group (not an assertion, not a\n    DEFINE) that matches at least one character, then the current item matches\n    a character. Conditionals are handled below. */\n\n    if (note_group_empty && bravalue != OP_COND && group_return > 0)\n      matched_char = TRUE;\n\n    /* If we've just compiled an assertion, pop the assert depth. */\n\n    if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERT_SCS)\n      cb->assert_depth -= 1;\n\n    /* At the end of compiling, code is still pointing to the start of the\n    group, while tempcode has been updated to point past the end of the group.\n    The parsed pattern pointer (pptr) is on the closing META_KET.\n\n    If this is a conditional bracket, check that there are no more than\n    two branches in the group, or just one if it's a DEFINE group. We do this\n    in the real compile phase, not in the pre-pass, where the whole group may\n    not be available. */\n\n    if (bravalue == OP_COND && lengthptr == NULL)\n      {\n      PCRE2_UCHAR *tc = code;\n      int condcount = 0;\n\n      do {\n         condcount++;\n         tc += GET(tc,1);\n         }\n      while (*tc != OP_KET);\n\n      /* A DEFINE group is never obeyed inline (the \"condition\" is always\n      false). It must have only one branch. Having checked this, change the\n      opcode to OP_FALSE. */\n\n      if (code[LINK_SIZE+1] == OP_DEFINE)\n        {\n        if (condcount > 1)\n          {\n          cb->erroroffset = offset;\n          *errorcodeptr = ERR54;\n          return 0;\n          }\n        code[LINK_SIZE+1] = OP_FALSE;\n        bravalue = OP_DEFINE;   /* A flag to suppress char handling below */\n        }\n\n      /* A \"normal\" conditional group. If there is just one branch, we must not\n      make use of its firstcu or reqcu, because this is equivalent to an\n      empty second branch. Also, it may match an empty string. If there are two\n      branches, this item must match a character if the group must. */\n\n      else\n        {\n        if (condcount > 2)\n          {\n          cb->erroroffset = offset;\n          *errorcodeptr = ERR27;\n          return 0;\n          }\n        if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE;\n          else if (group_return > 0) matched_char = TRUE;\n        }\n      }\n\n    /* In the pre-compile phase, update the length by the length of the group,\n    less the brackets at either end. Then reduce the compiled code to just a\n    set of non-capturing brackets so that it doesn't use much memory if it is\n    duplicated by a quantifier.*/\n\n    if (lengthptr != NULL)\n      {\n      if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)\n        {\n        *errorcodeptr = ERR20;\n        return 0;\n        }\n      *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;\n      code++;   /* This already contains bravalue */\n      PUTINC(code, 0, 1 + LINK_SIZE);\n      *code++ = OP_KET;\n      PUTINC(code, 0, 1 + LINK_SIZE);\n      break;    /* No need to waste time with special character handling */\n      }\n\n    /* Otherwise update the main code pointer to the end of the group. */\n\n    code = tempcode;\n\n    /* For a DEFINE group, required and first character settings are not\n    relevant. */\n\n    if (bravalue == OP_DEFINE) break;\n\n    /* Handle updating of the required and first code units for other types of\n    group. Update for normal brackets of all kinds, and conditions with two\n    branches (see code above). If the bracket is followed by a quantifier with\n    zero repeat, we have to back off. Hence the definition of zeroreqcu and\n    zerofirstcu outside the main loop so that they can be accessed for the back\n    off. */\n\n    zeroreqcu = reqcu;\n    zeroreqcuflags = reqcuflags;\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    groupsetfirstcu = FALSE;\n\n    if (bravalue >= OP_ONCE)  /* Not an assertion */\n      {\n      /* If we have not yet set a firstcu in this branch, take it from the\n      subpattern, remembering that it was set here so that a repeat of more\n      than one can replicate it as reqcu if necessary. If the subpattern has\n      no firstcu, set \"none\" for the whole branch. In both cases, a zero\n      repeat forces firstcu to \"none\". */\n\n      if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET)\n        {\n        if (subfirstcuflags < REQ_NONE)\n          {\n          firstcu = subfirstcu;\n          firstcuflags = subfirstcuflags;\n          groupsetfirstcu = TRUE;\n          }\n        else firstcuflags = REQ_NONE;\n        zerofirstcuflags = REQ_NONE;\n        }\n\n      /* If firstcu was previously set, convert the subpattern's firstcu\n      into reqcu if there wasn't one, using the vary flag that was in\n      existence beforehand. */\n\n      else if (subfirstcuflags < REQ_NONE && subreqcuflags >= REQ_NONE)\n        {\n        subreqcu = subfirstcu;\n        subreqcuflags = subfirstcuflags | tempreqvary;\n        }\n\n      /* If the subpattern set a required code unit (or set a first code unit\n      that isn't really the first code unit - see above), set it. */\n\n      if (subreqcuflags < REQ_NONE)\n        {\n        reqcu = subreqcu;\n        reqcuflags = subreqcuflags;\n        }\n      }\n\n    /* For a forward assertion, we take the reqcu, if set, provided that the\n    group has also set a firstcu. This can be helpful if the pattern that\n    follows the assertion doesn't set a different char. For example, it's\n    useful for /(?=abcde).+/. We can't set firstcu for an assertion, however\n    because it leads to incorrect effect for patterns such as /(?=a)a.+/ when\n    the \"real\" \"a\" would then become a reqcu instead of a firstcu. This is\n    overcome by a scan at the end if there's no firstcu, looking for an\n    asserted first char. A similar effect for patterns like /(?=.*X)X$/ means\n    we must only take the reqcu when the group also set a firstcu. Otherwise,\n    in that example, 'X' ends up set for both. */\n\n    else if ((bravalue == OP_ASSERT || bravalue == OP_ASSERT_NA) &&\n             subreqcuflags < REQ_NONE && subfirstcuflags < REQ_NONE)\n      {\n      reqcu = subreqcu;\n      reqcuflags = subreqcuflags;\n      }\n\n    break;  /* End of nested group handling */\n\n\n    /* ===================================================================*/\n    /* Handle named backreferences and recursions. */\n\n    case META_BACKREF_BYNAME:\n    case META_RECURSE_BYNAME:\n      {\n      int count, index;\n      PCRE2_SPTR name;\n      named_group *ng;\n      uint32_t length = *(++pptr);\n\n      GETPLUSOFFSET(offset, pptr);\n      name = cb->start_pattern + offset;\n\n      /* In the first pass, the names generated in the pre-pass are available,\n      but the main name table has not yet been created. Scan the list of names\n      generated in the pre-pass in order to get a number and whether or not\n      this name is duplicated. */\n\n      ng = PRIV(compile_find_named_group)(name, length, cb);\n\n      if (ng == NULL)\n        {\n        /* If the name was not found we have a bad reference. */\n        *errorcodeptr = ERR15;\n        cb->erroroffset = offset;\n        return 0;\n        }\n\n      groupnumber = ng->number;\n\n      /* For a recursion, that's all that is needed. We can now go to\n      the code that handles numerical recursion, applying it to the first\n      group with the given name. */\n\n      if (meta == META_RECURSE_BYNAME)\n        {\n        meta_arg = groupnumber;\n        goto HANDLE_NUMERICAL_RECURSION;\n        }\n\n      /* For a back reference, update the back reference map and the\n      maximum back reference. */\n\n      cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;\n      if (groupnumber > cb->top_backref)\n        cb->top_backref = groupnumber;\n\n      /* If a back reference name is not duplicated, we can handle it as\n      a numerical reference. */\n\n      if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)\n        {\n        meta_arg = groupnumber;\n        goto HANDLE_SINGLE_REFERENCE;\n        }\n\n      /* If a back reference name is duplicated, we generate a different\n      opcode to a numerical back reference. In the second pass we must\n      search for the index and count in the final name table. */\n\n      count = 0;  /* Values for first pass (avoids compiler warning) */\n      index = 0;\n      if (lengthptr == NULL && !PRIV(compile_find_dupname_details)(name, length,\n            &index, &count, errorcodeptr, cb)) return 0;\n\n      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n      *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;\n      PUT2INC(code, 0, index);\n      PUT2INC(code, 0, count);\n      if ((options & PCRE2_CASELESS) != 0)\n        *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)?\n                   REFI_FLAG_CASELESS_RESTRICT : 0) |\n                  (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)?\n                   REFI_FLAG_TURKISH_CASING : 0);\n      }\n    break;\n\n\n    /* ===================================================================*/\n    /* Handle a numerical callout. */\n\n    case META_CALLOUT_NUMBER:\n    code[0] = OP_CALLOUT;\n    PUT(code, 1, pptr[1]);               /* Offset to next pattern item */\n    PUT(code, 1 + LINK_SIZE, pptr[2]);   /* Length of next pattern item */\n    code[1 + 2*LINK_SIZE] = pptr[3];\n    pptr += 3;\n    code += PRIV(OP_lengths)[OP_CALLOUT];\n    break;\n\n\n    /* ===================================================================*/\n    /* Handle a callout with a string argument. In the pre-pass we just compute\n    the length without generating anything. The length in pptr[3] includes both\n    delimiters; in the actual compile only the first one is copied, but a\n    terminating zero is added. Any doubled delimiters within the string make\n    this an overestimate, but it is not worth bothering about. */\n\n    case META_CALLOUT_STRING:\n    if (lengthptr != NULL)\n      {\n      *lengthptr += pptr[3] + (1 + 4*LINK_SIZE);\n      pptr += 3;\n      SKIPOFFSET(pptr);\n      }\n\n    /* In the real compile we can copy the string. The starting delimiter is\n     included so that the client can discover it if they want. We also pass the\n     start offset to help a script language give better error messages. */\n\n    else\n      {\n      PCRE2_SPTR pp;\n      uint32_t delimiter;\n      uint32_t length = pptr[3];\n      PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE);\n\n      code[0] = OP_CALLOUT_STR;\n      PUT(code, 1, pptr[1]);               /* Offset to next pattern item */\n      PUT(code, 1 + LINK_SIZE, pptr[2]);   /* Length of next pattern item */\n\n      pptr += 3;\n      GETPLUSOFFSET(offset, pptr);         /* Offset to string in pattern */\n      pp = cb->start_pattern + offset;\n      delimiter = *callout_string++ = *pp++;\n      if (delimiter == CHAR_LEFT_CURLY_BRACKET)\n        delimiter = CHAR_RIGHT_CURLY_BRACKET;\n      PUT(code, 1 + 3*LINK_SIZE, (int)(offset + 1));  /* One after delimiter */\n\n      /* The syntax of the pattern was checked in the parsing scan. The length\n      includes both delimiters, but we have passed the opening one just above,\n      so we reduce length before testing it. The test is for > 1 because we do\n      not want to copy the final delimiter. This also ensures that pp[1] is\n      accessible. */\n\n      while (--length > 1)\n        {\n        if (*pp == delimiter && pp[1] == delimiter)\n          {\n          *callout_string++ = delimiter;\n          pp += 2;\n          length--;\n          }\n        else *callout_string++ = *pp++;\n        }\n      *callout_string++ = CHAR_NUL;\n\n      /* Set the length of the entire item, the advance to its end. */\n\n      PUT(code, 1 + 2*LINK_SIZE, (int)(callout_string - code));\n      code = callout_string;\n      }\n    break;\n\n\n    /* ===================================================================*/\n    /* Handle repetition. The different types are all sorted out in the parsing\n    pass. */\n\n    case META_MINMAX_PLUS:\n    case META_MINMAX_QUERY:\n    case META_MINMAX:\n    repeat_min = *(++pptr);\n    repeat_max = *(++pptr);\n    goto REPEAT;\n\n    case META_ASTERISK:\n    case META_ASTERISK_PLUS:\n    case META_ASTERISK_QUERY:\n    repeat_min = 0;\n    repeat_max = REPEAT_UNLIMITED;\n    goto REPEAT;\n\n    case META_PLUS:\n    case META_PLUS_PLUS:\n    case META_PLUS_QUERY:\n    repeat_min = 1;\n    repeat_max = REPEAT_UNLIMITED;\n    goto REPEAT;\n\n    case META_QUERY:\n    case META_QUERY_PLUS:\n    case META_QUERY_QUERY:\n    repeat_min = 0;\n    repeat_max = 1;\n\n    REPEAT:\n    if (previous_matched_char && repeat_min > 0) matched_char = TRUE;\n\n    /* Remember whether this is a variable length repeat, and default to\n    single-char opcodes. */\n\n    reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;\n\n    /* Adjust first and required code units for a zero repeat. */\n\n    if (repeat_min == 0)\n      {\n      firstcu = zerofirstcu;\n      firstcuflags = zerofirstcuflags;\n      reqcu = zeroreqcu;\n      reqcuflags = zeroreqcuflags;\n      }\n\n    /* Note the greediness and possessiveness. */\n\n    switch (meta)\n      {\n      case META_MINMAX_PLUS:\n      case META_ASTERISK_PLUS:\n      case META_PLUS_PLUS:\n      case META_QUERY_PLUS:\n      repeat_type = 0;                  /* Force greedy */\n      possessive_quantifier = TRUE;\n      break;\n\n      case META_MINMAX_QUERY:\n      case META_ASTERISK_QUERY:\n      case META_PLUS_QUERY:\n      case META_QUERY_QUERY:\n      repeat_type = greedy_non_default;\n      possessive_quantifier = FALSE;\n      break;\n\n      default:\n      repeat_type = greedy_default;\n      possessive_quantifier = FALSE;\n      break;\n      }\n\n    /* Save start of previous item, in case we have to move it up in order to\n    insert something before it, and remember what it was. */\n\n    PCRE2_ASSERT(previous != NULL);\n    tempcode = previous;\n    op_previous = *previous;\n\n    /* Now handle repetition for the different types of item. If the repeat\n    minimum and the repeat maximum are both 1, we can ignore the quantifier for\n    non-parenthesized items, as they have only one alternative. For anything in\n    parentheses, we must not ignore if {1} is possessive. */\n\n    switch (op_previous)\n      {\n      /* If previous was a character or negated character match, abolish the\n      item and generate a repeat item instead. If a char item has a minimum of\n      more than one, ensure that it is set in reqcu - it might not be if a\n      sequence such as x{3} is the first thing in a branch because the x will\n      have gone into firstcu instead.  */\n\n      case OP_CHAR:\n      case OP_CHARI:\n      case OP_NOT:\n      case OP_NOTI:\n      if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;\n      op_type = chartypeoffset[op_previous - OP_CHAR];\n\n      /* Deal with UTF characters that take up more than one code unit. */\n\n#ifdef MAYBE_UTF_MULTI\n      if (utf && NOT_FIRSTCU(code[-1]))\n        {\n        PCRE2_UCHAR *lastchar = code - 1;\n        BACKCHAR(lastchar);\n        mclength = (uint32_t)(code - lastchar);   /* Length of UTF character */\n        memcpy(mcbuffer, lastchar, CU2BYTES(mclength));  /* Save the char */\n        }\n      else\n#endif  /* MAYBE_UTF_MULTI */\n\n      /* Handle the case of a single code unit - either with no UTF support, or\n      with UTF disabled, or for a single-code-unit UTF character. In the latter\n      case, for a repeated positive match, get the caseless flag for the\n      required code unit from the previous character, because a class like [Aa]\n      sets a caseless A but by now the req_caseopt flag has been reset. */\n\n        {\n        mcbuffer[0] = code[-1];\n        mclength = 1;\n        if (op_previous <= OP_CHARI && repeat_min > 1)\n          {\n          reqcu = mcbuffer[0];\n          reqcuflags = cb->req_varyopt;\n          if (op_previous == OP_CHARI) reqcuflags |= REQ_CASELESS;\n          }\n        }\n      goto OUTPUT_SINGLE_REPEAT;  /* Code shared with single character types */\n\n      /* If previous was a character class or a back reference, we put the\n      repeat stuff after it, but just skip the item if the repeat was {0,0}. */\n\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_XCLASS:\n      case OP_ECLASS:\n#endif\n      case OP_CLASS:\n      case OP_NCLASS:\n      case OP_REF:\n      case OP_REFI:\n      case OP_DNREF:\n      case OP_DNREFI:\n\n      if (repeat_max == 0)\n        {\n        code = previous;\n        goto END_REPEAT;\n        }\n      if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;\n\n      if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED)\n        *code++ = OP_CRSTAR + repeat_type;\n      else if (repeat_min == 1 && repeat_max == REPEAT_UNLIMITED)\n        *code++ = OP_CRPLUS + repeat_type;\n      else if (repeat_min == 0 && repeat_max == 1)\n        *code++ = OP_CRQUERY + repeat_type;\n      else\n        {\n        *code++ = OP_CRRANGE + repeat_type;\n        PUT2INC(code, 0, repeat_min);\n        if (repeat_max == REPEAT_UNLIMITED) repeat_max = 0;  /* 2-byte encoding for max */\n        PUT2INC(code, 0, repeat_max);\n        }\n      break;\n\n      /* Prior to 10.30, repeated recursions were wrapped in OP_ONCE brackets\n      because pcre2_match() could not handle backtracking into recursively\n      called groups. Now that this backtracking is available, we no longer need\n      to do this. However, we still need to replicate recursions as we do for\n      groups so as to have independent backtracking points. We can replicate\n      for the minimum number of repeats directly. For optional repeats we now\n      wrap the recursion in OP_BRA brackets and make use of the bracket\n      repetition. */\n\n      case OP_RECURSE:\n      if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)\n        goto END_REPEAT;\n\n      /* Generate unwrapped repeats for a non-zero minimum, except when the\n      minimum is 1 and the maximum unlimited, because that can be handled with\n      OP_BRA terminated by OP_KETRMAX/MIN. When the maximum is equal to the\n      minimum, we just need to generate the appropriate additional copies.\n      Otherwise we need to generate one more, to simulate the situation when\n      the minimum is zero. */\n\n      if (repeat_min > 0 && (repeat_min != 1 || repeat_max != REPEAT_UNLIMITED))\n        {\n        int replicate = repeat_min;\n\n        if (repeat_min == repeat_max) replicate--;\n\n        /* In the pre-compile phase, we don't actually do the replication. We\n        just adjust the length as if we had. Do some paranoid checks for\n        potential integer overflow. */\n\n        if (lengthptr != NULL)\n          {\n          PCRE2_SIZE delta;\n          if (PRIV(ckd_smul)(&delta, replicate, (int)length_prevgroup) ||\n              OFLOW_MAX - *lengthptr < delta)\n            {\n            *errorcodeptr = ERR20;\n            return 0;\n            }\n          *lengthptr += delta;\n          }\n        else for (int i = 0; i < replicate; i++)\n          {\n          memcpy(code, previous, CU2BYTES(length_prevgroup));\n          previous = code;\n          code += length_prevgroup;\n          }\n\n        /* If the number of repeats is fixed, we are done. Otherwise, adjust\n        the counts and fall through. */\n\n        if (repeat_min == repeat_max) break;\n        if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;\n        repeat_min = 0;\n        }\n\n      /* Wrap the recursion call in OP_BRA brackets. */\n        {\n        PCRE2_SIZE length = (lengthptr != NULL) ? 1 + LINK_SIZE : length_prevgroup;\n\n        (void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(length));\n        op_previous = *previous = OP_BRA;\n        PUT(previous, 1, 1 + LINK_SIZE + length);\n        previous[1 + LINK_SIZE + length] = OP_KET;\n        PUT(previous, 2 + LINK_SIZE + length, 1 + LINK_SIZE + length);\n        }\n      code += 2 + 2 * LINK_SIZE;\n      length_prevgroup += 2 + 2 * LINK_SIZE;\n      group_return = -1;  /* Set \"may match empty string\" */\n\n      /* Now treat as a repeated OP_BRA. */\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      /* If previous was a bracket group, we may have to replicate it in\n      certain cases. Note that at this point we can encounter only the \"basic\"\n      bracket opcodes such as BRA and CBRA, as this is the place where they get\n      converted into the more special varieties such as BRAPOS and SBRA.\n      Originally, PCRE did not allow repetition of assertions, but now it does,\n      for Perl compatibility. */\n\n      case OP_ASSERT:\n      case OP_ASSERT_NOT:\n      case OP_ASSERT_NA:\n      case OP_ASSERTBACK:\n      case OP_ASSERTBACK_NOT:\n      case OP_ASSERTBACK_NA:\n      case OP_ASSERT_SCS:\n      case OP_ONCE:\n      case OP_SCRIPT_RUN:\n      case OP_BRA:\n      case OP_CBRA:\n      case OP_COND:\n        {\n        int len = (int)(code - previous);\n        PCRE2_UCHAR *bralink = NULL;\n        PCRE2_UCHAR *brazeroptr = NULL;\n\n        if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)\n          goto END_REPEAT;\n\n        /* Repeating a DEFINE group (or any group where the condition is always\n        FALSE and there is only one branch) is pointless, but Perl allows the\n        syntax, so we just ignore the repeat. */\n\n        if (op_previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE &&\n            previous[GET(previous, 1)] != OP_ALT)\n          goto END_REPEAT;\n\n        /* Perl allows all assertions to be quantified, and when they contain\n        capturing parentheses and/or are optional there are potential uses for\n        this feature. PCRE2 used to force the maximum quantifier to 1 on the\n        invalid grounds that further repetition was never useful. This was\n        always a bit pointless, since an assertion could be wrapped with a\n        repeated group to achieve the effect. General repetition is now\n        permitted, but if the maximum is unlimited it is set to one more than\n        the minimum. */\n\n        if (op_previous < OP_ONCE)    /* Assertion */\n          {\n          if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 1;\n          }\n\n        /* The case of a zero minimum is special because of the need to stick\n        OP_BRAZERO in front of it, and because the group appears once in the\n        data, whereas in other cases it appears the minimum number of times. For\n        this reason, it is simplest to treat this case separately, as otherwise\n        the code gets far too messy. There are several special subcases when the\n        minimum is zero. */\n\n        if (repeat_min == 0)\n          {\n          /* If the maximum is also zero, we used to just omit the group from\n          the output altogether, like this:\n\n          ** if (repeat_max == 0)\n          **   {\n          **   code = previous;\n          **   goto END_REPEAT;\n          **   }\n\n          However, that fails when a group or a subgroup within it is\n          referenced as a subroutine from elsewhere in the pattern, so now we\n          stick in OP_SKIPZERO in front of it so that it is skipped on\n          execution. As we don't have a list of which groups are referenced, we\n          cannot do this selectively.\n\n          If the maximum is 1 or unlimited, we just have to stick in the\n          BRAZERO and do no more at this point. */\n\n          if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)\n            {\n            (void)memmove(previous + 1, previous, CU2BYTES(len));\n            code++;\n            if (repeat_max == 0)\n              {\n              *previous++ = OP_SKIPZERO;\n              goto END_REPEAT;\n              }\n            brazeroptr = previous;    /* Save for possessive optimizing */\n            *previous++ = OP_BRAZERO + repeat_type;\n            }\n\n          /* If the maximum is greater than 1 and limited, we have to replicate\n          in a nested fashion, sticking OP_BRAZERO before each set of brackets.\n          The first one has to be handled carefully because it's the original\n          copy, which has to be moved up. The remainder can be handled by code\n          that is common with the non-zero minimum case below. We have to\n          adjust the value or repeat_max, since one less copy is required. */\n\n          else\n            {\n            int linkoffset;\n            (void)memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));\n            code += 2 + LINK_SIZE;\n            *previous++ = OP_BRAZERO + repeat_type;\n            *previous++ = OP_BRA;\n\n            /* We chain together the bracket link offset fields that have to be\n            filled in later when the ends of the brackets are reached. */\n\n            linkoffset = (bralink == NULL)? 0 : (int)(previous - bralink);\n            bralink = previous;\n            PUTINC(previous, 0, linkoffset);\n            }\n\n          if (repeat_max != REPEAT_UNLIMITED) repeat_max--;\n          }\n\n        /* If the minimum is greater than zero, replicate the group as many\n        times as necessary, and adjust the maximum to the number of subsequent\n        copies that we need. */\n\n        else\n          {\n          if (repeat_min > 1)\n            {\n            /* In the pre-compile phase, we don't actually do the replication.\n            We just adjust the length as if we had. Do some paranoid checks for\n            potential integer overflow. */\n\n            if (lengthptr != NULL)\n              {\n              PCRE2_SIZE delta;\n              if (PRIV(ckd_smul)(&delta, repeat_min - 1,\n                                 (int)length_prevgroup) ||\n                  OFLOW_MAX - *lengthptr < delta)\n                {\n                *errorcodeptr = ERR20;\n                return 0;\n                }\n              *lengthptr += delta;\n              }\n\n            /* This is compiling for real. If there is a set first code unit\n            for the group, and we have not yet set a \"required code unit\", set\n            it. */\n\n            else\n              {\n              if (groupsetfirstcu && reqcuflags >= REQ_NONE)\n                {\n                reqcu = firstcu;\n                reqcuflags = firstcuflags;\n                }\n              for (uint32_t i = 1; i < repeat_min; i++)\n                {\n                memcpy(code, previous, CU2BYTES(len));\n                code += len;\n                }\n              }\n            }\n\n          if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;\n          }\n\n        /* This code is common to both the zero and non-zero minimum cases. If\n        the maximum is limited, it replicates the group in a nested fashion,\n        remembering the bracket starts on a stack. In the case of a zero\n        minimum, the first one was set up above. In all cases the repeat_max\n        now specifies the number of additional copies needed. Again, we must\n        remember to replicate entries on the forward reference list. */\n\n        if (repeat_max != REPEAT_UNLIMITED)\n          {\n          /* In the pre-compile phase, we don't actually do the replication. We\n          just adjust the length as if we had. For each repetition we must add\n          1 to the length for BRAZERO and for all but the last repetition we\n          must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some\n          paranoid checks to avoid integer overflow. */\n\n          if (lengthptr != NULL && repeat_max > 0)\n            {\n            PCRE2_SIZE delta;\n            if (PRIV(ckd_smul)(&delta, repeat_max,\n                               (int)length_prevgroup + 1 + 2 + 2*LINK_SIZE) ||\n                OFLOW_MAX + (2 + 2*LINK_SIZE) - *lengthptr < delta)\n              {\n              *errorcodeptr = ERR20;\n              return 0;\n              }\n            delta -= (2 + 2*LINK_SIZE);   /* Last one doesn't nest */\n            *lengthptr += delta;\n            }\n\n          /* This is compiling for real */\n\n          else for (uint32_t i = repeat_max; i >= 1; i--)\n            {\n            *code++ = OP_BRAZERO + repeat_type;\n\n            /* All but the final copy start a new nesting, maintaining the\n            chain of brackets outstanding. */\n\n            if (i != 1)\n              {\n              int linkoffset;\n              *code++ = OP_BRA;\n              linkoffset = (bralink == NULL)? 0 : (int)(code - bralink);\n              bralink = code;\n              PUTINC(code, 0, linkoffset);\n              }\n\n            memcpy(code, previous, CU2BYTES(len));\n            code += len;\n            }\n\n          /* Now chain through the pending brackets, and fill in their length\n          fields (which are holding the chain links pro tem). */\n\n          while (bralink != NULL)\n            {\n            int oldlinkoffset;\n            int linkoffset = (int)(code - bralink + 1);\n            PCRE2_UCHAR *bra = code - linkoffset;\n            oldlinkoffset = GET(bra, 1);\n            bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;\n            *code++ = OP_KET;\n            PUTINC(code, 0, linkoffset);\n            PUT(bra, 1, linkoffset);\n            }\n          }\n\n        /* If the maximum is unlimited, set a repeater in the final copy. For\n        SCRIPT_RUN and ONCE brackets, that's all we need to do. However,\n        possessively repeated ONCE brackets can be converted into non-capturing\n        brackets, as the behaviour of (?:xx)++ is the same as (?>xx)++ and this\n        saves having to deal with possessive ONCEs specially.\n\n        Otherwise, when we are doing the actual compile phase, check to see\n        whether this group is one that could match an empty string. If so,\n        convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so\n        that runtime checking can be done. [This check is also applied to ONCE\n        and SCRIPT_RUN groups at runtime, but in a different way.]\n\n        Then, if the quantifier was possessive and the bracket is not a\n        conditional, we convert the BRA code to the POS form, and the KET code\n        to KETRPOS. (It turns out to be convenient at runtime to detect this\n        kind of subpattern at both the start and at the end.) The use of\n        special opcodes makes it possible to reduce greatly the stack usage in\n        pcre2_match(). If the group is preceded by OP_BRAZERO, convert this to\n        OP_BRAPOSZERO.\n\n        Then, if the minimum number of matches is 1 or 0, cancel the possessive\n        flag so that the default action below, of wrapping everything inside\n        atomic brackets, does not happen. When the minimum is greater than 1,\n        there will be earlier copies of the group, and so we still have to wrap\n        the whole thing. */\n\n        else\n          {\n          PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE;\n          PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1);\n\n          /* Convert possessive ONCE brackets to non-capturing */\n\n          if (*bracode == OP_ONCE && possessive_quantifier) *bracode = OP_BRA;\n\n          /* For non-possessive ONCE and for SCRIPT_RUN brackets, all we need\n          to do is to set the KET. */\n\n          if (*bracode == OP_ONCE || *bracode == OP_SCRIPT_RUN)\n            *ketcode = OP_KETRMAX + repeat_type;\n\n          /* Handle non-SCRIPT_RUN and non-ONCE brackets and possessive ONCEs\n          (which have been converted to non-capturing above). */\n\n          else\n            {\n            /* In the compile phase, adjust the opcode if the group can match\n            an empty string. For a conditional group with only one branch, the\n            value of group_return will not show \"could be empty\", so we must\n            check that separately. */\n\n            if (lengthptr == NULL)\n              {\n              if (group_return < 0) *bracode += OP_SBRA - OP_BRA;\n              if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)\n                *bracode = OP_SCOND;\n              }\n\n            /* Handle possessive quantifiers. */\n\n            if (possessive_quantifier)\n              {\n              /* For COND brackets, we wrap the whole thing in a possessively\n              repeated non-capturing bracket, because we have not invented POS\n              versions of the COND opcodes. */\n\n              if (*bracode == OP_COND || *bracode == OP_SCOND)\n                {\n                int nlen = (int)(code - bracode);\n                (void)memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));\n                code += 1 + LINK_SIZE;\n                nlen += 1 + LINK_SIZE;\n                *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;\n                *code++ = OP_KETRPOS;\n                PUTINC(code, 0, nlen);\n                PUT(bracode, 1, nlen);\n                }\n\n              /* For non-COND brackets, we modify the BRA code and use KETRPOS. */\n\n              else\n                {\n                *bracode += 1;              /* Switch to xxxPOS opcodes */\n                *ketcode = OP_KETRPOS;\n                }\n\n              /* If the minimum is zero, mark it as possessive, then unset the\n              possessive flag when the minimum is 0 or 1. */\n\n              if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;\n              if (repeat_min < 2) possessive_quantifier = FALSE;\n              }\n\n            /* Non-possessive quantifier */\n\n            else *ketcode = OP_KETRMAX + repeat_type;\n            }\n          }\n        }\n      break;\n\n      /* If previous was a character type match (\\d or similar), abolish it and\n      create a suitable repeat item. The code is shared with single-character\n      repeats by setting op_type to add a suitable offset into repeat_type.\n      Note the the Unicode property types will be present only when\n      SUPPORT_UNICODE is defined, but we don't wrap the little bits of code\n      here because it just makes it horribly messy. */\n\n      default:\n\n      /* LCOV_EXCL_START */\n      if (op_previous >= OP_EODN || op_previous <= OP_WORD_BOUNDARY)\n        {\n        PCRE2_DEBUG_UNREACHABLE();\n        *errorcodeptr = ERR10;  /* Not a character type - internal error */\n        return 0;\n        }\n      /* LCOV_EXCL_STOP */\n\n        {\n        int prop_type, prop_value;\n        PCRE2_UCHAR *oldcode;\n\n        if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;\n\n        op_type = OP_TYPESTAR - OP_STAR;      /* Use type opcodes */\n        mclength = 0;                         /* Not a character */\n\n        if (op_previous == OP_PROP || op_previous == OP_NOTPROP)\n          {\n          prop_type = previous[1];\n          prop_value = previous[2];\n          }\n        else\n          {\n          /* Come here from just above with a character in mcbuffer/mclength.\n          You must also set op_type before the jump. */\n          OUTPUT_SINGLE_REPEAT:\n          prop_type = prop_value = -1;\n          }\n\n        /* At this point, if prop_type == prop_value == -1 we either have a\n        character in mcbuffer when mclength is greater than zero, or we have\n        mclength zero, in which case there is a non-property character type in\n        op_previous. If prop_type/value are not negative, we have a property\n        character type in op_previous. */\n\n        oldcode = code;                   /* Save where we were */\n        code = previous;                  /* Usually overwrite previous item */\n\n        /* If the maximum is zero then the minimum must also be zero; Perl allows\n        this case, so we do too - by simply omitting the item altogether. */\n\n        if (repeat_max == 0) goto END_REPEAT;\n\n        /* Combine the op_type with the repeat_type */\n\n        repeat_type += op_type;\n\n        /* A minimum of zero is handled either as the special case * or ?, or as\n        an UPTO, with the maximum given. */\n\n        if (repeat_min == 0)\n          {\n          if (repeat_max == REPEAT_UNLIMITED) *code++ = OP_STAR + repeat_type;\n            else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;\n          else\n            {\n            *code++ = OP_UPTO + repeat_type;\n            PUT2INC(code, 0, repeat_max);\n            }\n          }\n\n        /* A repeat minimum of 1 is optimized into some special cases. If the\n        maximum is unlimited, we use OP_PLUS. Otherwise, the original item is\n        left in place and, if the maximum is greater than 1, we use OP_UPTO with\n        one less than the maximum. */\n\n        else if (repeat_min == 1)\n          {\n          if (repeat_max == REPEAT_UNLIMITED)\n            *code++ = OP_PLUS + repeat_type;\n          else\n            {\n            code = oldcode;  /* Leave previous item in place */\n            if (repeat_max == 1) goto END_REPEAT;\n            *code++ = OP_UPTO + repeat_type;\n            PUT2INC(code, 0, repeat_max - 1);\n            }\n          }\n\n        /* The case {n,n} is just an EXACT, while the general case {n,m} is\n        handled as an EXACT followed by an UPTO or STAR or QUERY. */\n\n        else\n          {\n          *code++ = OP_EXACT + op_type;  /* NB EXACT doesn't have repeat_type */\n          PUT2INC(code, 0, repeat_min);\n\n          /* Unless repeat_max equals repeat_min, fill in the data for EXACT,\n          and then generate the second opcode. For a repeated Unicode property\n          match, there are two extra values that define the required property,\n          and mclength is set zero to indicate this. */\n\n          if (repeat_max != repeat_min)\n            {\n            if (mclength > 0)\n              {\n              memcpy(code, mcbuffer, CU2BYTES(mclength));\n              code += mclength;\n              }\n            else\n              {\n              *code++ = op_previous;\n              if (prop_type >= 0)\n                {\n                *code++ = prop_type;\n                *code++ = prop_value;\n                }\n              }\n\n            /* Now set up the following opcode */\n\n            if (repeat_max == REPEAT_UNLIMITED)\n              *code++ = OP_STAR + repeat_type;\n            else\n              {\n              repeat_max -= repeat_min;\n              if (repeat_max == 1)\n                {\n                *code++ = OP_QUERY + repeat_type;\n                }\n              else\n                {\n                *code++ = OP_UPTO + repeat_type;\n                PUT2INC(code, 0, repeat_max);\n                }\n              }\n            }\n          }\n\n        /* Fill in the character or character type for the final opcode. */\n\n        if (mclength > 0)\n          {\n          memcpy(code, mcbuffer, CU2BYTES(mclength));\n          code += mclength;\n          }\n        else\n          {\n          *code++ = op_previous;\n          if (prop_type >= 0)\n            {\n            *code++ = prop_type;\n            *code++ = prop_value;\n            }\n          }\n        }\n      break;\n      }  /* End of switch on different op_previous values */\n\n\n    /* If the character following a repeat is '+', possessive_quantifier is\n    TRUE. For some opcodes, there are special alternative opcodes for this\n    case. For anything else, we wrap the entire repeated item inside OP_ONCE\n    brackets. Logically, the '+' notation is just syntactic sugar, taken from\n    Sun's Java package, but the special opcodes can optimize it.\n\n    Some (but not all) possessively repeated subpatterns have already been\n    completely handled in the code just above. For them, possessive_quantifier\n    is always FALSE at this stage. Note that the repeated item starts at\n    tempcode, not at previous, which might be the first part of a string whose\n    (former) last char we repeated. */\n\n    if (possessive_quantifier)\n      {\n      int len;\n\n      /* Possessifying an EXACT quantifier has no effect, so we can ignore it.\n      However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},\n      {5,}, or {5,10}). We skip over an EXACT item; if the length of what\n      remains is greater than zero, there's a further opcode that can be\n      handled. If not, do nothing, leaving the EXACT alone. */\n\n      switch(*tempcode)\n        {\n        case OP_TYPEEXACT:\n        tempcode += PRIV(OP_lengths)[*tempcode] +\n          ((tempcode[1 + IMM2_SIZE] == OP_PROP\n          || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);\n        break;\n\n        /* CHAR opcodes are used for exacts whose count is 1. */\n\n        case OP_CHAR:\n        case OP_CHARI:\n        case OP_NOT:\n        case OP_NOTI:\n        case OP_EXACT:\n        case OP_EXACTI:\n        case OP_NOTEXACT:\n        case OP_NOTEXACTI:\n        tempcode += PRIV(OP_lengths)[*tempcode];\n#ifdef SUPPORT_UNICODE\n        if (utf && HAS_EXTRALEN(tempcode[-1]))\n          tempcode += GET_EXTRALEN(tempcode[-1]);\n#endif\n        break;\n\n        /* For the class opcodes, the repeat operator appears at the end;\n        adjust tempcode to point to it. */\n\n        case OP_CLASS:\n        case OP_NCLASS:\n        tempcode += 1 + 32/sizeof(PCRE2_UCHAR);\n        break;\n\n#ifdef SUPPORT_WIDE_CHARS\n        case OP_XCLASS:\n        case OP_ECLASS:\n        tempcode += GET(tempcode, 1);\n        break;\n#endif\n        }\n\n      /* If tempcode is equal to code (which points to the end of the repeated\n      item), it means we have skipped an EXACT item but there is no following\n      QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In\n      all other cases, tempcode will be pointing to the repeat opcode, and will\n      be less than code, so the value of len will be greater than 0. */\n\n      len = (int)(code - tempcode);\n      if (len > 0)\n        {\n        unsigned int repcode = *tempcode;\n\n        /* There is a table for possessifying opcodes, all of which are less\n        than OP_CALLOUT. A zero entry means there is no possessified version.\n        */\n\n        if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)\n          *tempcode = opcode_possessify[repcode];\n\n        /* For opcode without a special possessified version, wrap the item in\n        ONCE brackets. */\n\n        else\n          {\n          (void)memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));\n          code += 1 + LINK_SIZE;\n          len += 1 + LINK_SIZE;\n          tempcode[0] = OP_ONCE;\n          *code++ = OP_KET;\n          PUTINC(code, 0, len);\n          PUT(tempcode, 1, len);\n          }\n        }\n      }\n\n    /* We set the \"follows varying string\" flag for subsequently encountered\n    reqcus if it isn't already set and we have just passed a varying length\n    item. */\n\n    END_REPEAT:\n    cb->req_varyopt |= reqvary;\n    break;\n\n\n    /* ===================================================================*/\n    /* Handle a 32-bit data character with a value greater than META_END. */\n\n    case META_BIGVALUE:\n    pptr++;\n    goto NORMAL_CHAR;\n\n\n    /* ===============================================================*/\n    /* Handle a back reference by number, which is the meta argument. The\n    pattern offsets for back references to group numbers less than 10 are held\n    in a special vector, to avoid using more than two parsed pattern elements\n    in 64-bit environments. We only need the offset to the first occurrence,\n    because if that doesn't fail, subsequent ones will also be OK. */\n\n    case META_BACKREF:\n    if (meta_arg < 10) offset = cb->small_ref_offset[meta_arg];\n      else GETPLUSOFFSET(offset, pptr);\n\n    if (meta_arg > cb->bracount)\n      {\n      cb->erroroffset = offset;\n      *errorcodeptr = ERR15;  /* Non-existent subpattern */\n      return 0;\n      }\n\n    /* Come here from named backref handling when the reference is to a\n    single group (that is, not to a duplicated name). The back reference\n    data will have already been updated. We must disable firstcu if not\n    set, to cope with cases like (?=(\\w+))\\1: which would otherwise set ':'\n    later. */\n\n    HANDLE_SINGLE_REFERENCE:\n    if (firstcuflags == REQ_UNSET) zerofirstcuflags = firstcuflags = REQ_NONE;\n    *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;\n    PUT2INC(code, 0, meta_arg);\n    if ((options & PCRE2_CASELESS) != 0)\n      *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)?\n                 REFI_FLAG_CASELESS_RESTRICT : 0) |\n                (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)?\n                 REFI_FLAG_TURKISH_CASING : 0);\n\n    /* Update the map of back references, and keep the highest one. We\n    could do this in parse_regex() for numerical back references, but not\n    for named back references, because we don't know the numbers to which\n    named back references refer. So we do it all in this function. */\n\n    cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;\n    if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;\n    break;\n\n\n    /* ===============================================================*/\n    /* Handle recursion by inserting the number of the called group (which is\n    the meta argument) after OP_RECURSE. At the end of compiling the pattern is\n    scanned and these numbers are replaced by offsets within the pattern. It is\n    done like this to avoid problems with forward references and adjusting\n    offsets when groups are duplicated and moved (as discovered in previous\n    implementations). Note that a recursion does not have a set first\n    character. */\n\n    case META_RECURSE:\n    GETPLUSOFFSET(offset, pptr);\n    if (meta_arg > cb->bracount)\n      {\n      cb->erroroffset = offset;\n      *errorcodeptr = ERR15;  /* Non-existent subpattern */\n      return 0;\n      }\n    HANDLE_NUMERICAL_RECURSION:\n    *code = OP_RECURSE;\n    PUT(code, 1, meta_arg);\n    code += 1 + LINK_SIZE;\n    /* Repeat processing requires this information to\n    determine the real length in pre-compile phase. */\n    length_prevgroup = 1 + LINK_SIZE;\n\n    if (META_CODE(pptr[1]) == META_OFFSET ||\n        META_CODE(pptr[1]) == META_CAPTURE_NAME ||\n        META_CODE(pptr[1]) == META_CAPTURE_NUMBER)\n      {\n      recurse_arguments *args;\n\n      if (lengthptr != NULL)\n        {\n        if (!PRIV(compile_parse_recurse_args)(pptr, offset, errorcodeptr, cb))\n          return 0;\n\n        args = (recurse_arguments*)cb->last_data;\n        length_prevgroup += (args->size * (1 + IMM2_SIZE));\n        *lengthptr += (args->size * (1 + IMM2_SIZE));\n        pptr += args->skip_size;\n        }\n      else\n        {\n        uint16_t *current, *end;\n\n        args = (recurse_arguments*)cb->first_data;\n        PCRE2_ASSERT(args != NULL && args->header.type == CDATA_RECURSE_ARGS);\n\n        current = (uint16_t*)(args + 1);\n        end = current + args->size;\n        PCRE2_ASSERT(end > current);\n\n        do\n          {\n          code[0] = OP_CREF;\n          PUT2(code, 1, *current);\n          code += 1 + IMM2_SIZE;\n          }\n        while (++current < end);\n\n        length_prevgroup += (args->size * (1 + IMM2_SIZE));\n        pptr += args->skip_size;\n        cb->first_data = args->header.next;\n        cb->cx->memctl.free(args, cb->cx->memctl.memory_data);\n        }\n      }\n\n    groupsetfirstcu = FALSE;\n    cb->had_recurse = TRUE;\n    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    break;\n\n\n    /* ===============================================================*/\n    /* Handle capturing parentheses; the number is the meta argument. */\n\n    case META_CAPTURE:\n    bravalue = OP_CBRA;\n    skipunits = IMM2_SIZE;\n    PUT2(code, 1+LINK_SIZE, meta_arg);\n    cb->lastcapture = meta_arg;\n    goto GROUP_PROCESS_NOTE_EMPTY;\n\n\n    /* ===============================================================*/\n    /* Handle escape sequence items. For ones like \\d, the ESC_values are\n    arranged to be the same as the corresponding OP_values in the default case\n    when PCRE2_UCP is not set (which is the only case in which they will appear\n    here).\n\n    Note: \\Q and \\E are never seen here, as they were dealt with in\n    parse_pattern(). Neither are numerical back references or recursions, which\n    were turned into META_BACKREF or META_RECURSE items, respectively. \\k and\n    \\g, when followed by names, are turned into META_BACKREF_BYNAME or\n    META_RECURSE_BYNAME. */\n\n    case META_ESCAPE:\n\n    /* We can test for escape sequences that consume a character because their\n    values lie between ESC_b and ESC_Z; this may have to change if any new ones\n    are ever created. For these sequences, we disable the setting of a first\n    character if it hasn't already been set. */\n\n    if (meta_arg > ESC_b && meta_arg < ESC_Z)\n      {\n      matched_char = TRUE;\n      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;\n      }\n\n    /* Set values to reset to if this is followed by a zero repeat. */\n\n    zerofirstcu = firstcu;\n    zerofirstcuflags = firstcuflags;\n    zeroreqcu = reqcu;\n    zeroreqcuflags = reqcuflags;\n\n    /* If Unicode is not supported, \\P and \\p are not allowed and are\n    faulted at parse time, so will never appear here. */\n\n#ifdef SUPPORT_UNICODE\n    if (meta_arg == ESC_P || meta_arg == ESC_p)\n      {\n      uint32_t ptype = *(++pptr) >> 16;\n      uint32_t pdata = *pptr & 0xffff;\n\n      /* In caseless matching, particular characteristics Lu, Ll, and Lt get\n      converted to the general characteristic L&. That is, upper, lower, and\n      title case letters are all conflated. */\n\n      if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC &&\n          (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt))\n        {\n        ptype = PT_LAMP;\n        pdata = 0;\n        }\n\n      /* The special case of \\p{Any} is compiled to OP_ALLANY and \\P{Any}\n      is compiled to [] so as to benefit from the auto-anchoring code. */\n\n      if (ptype == PT_ANY)\n        {\n        if (meta_arg == ESC_P)\n          {\n          *code++ = OP_CLASS;\n          memset(code, 0, 32);\n          code += 32 / sizeof(PCRE2_UCHAR);\n          }\n        else\n          *code++ = OP_ALLANY;\n        }\n      else\n        {\n        *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP;\n        *code++ = ptype;\n        *code++ = pdata;\n        }\n      break;  /* End META_ESCAPE */\n      }\n#endif\n\n    /* \\K is forbidden in lookarounds since 10.38 because that's what Perl has\n    done. However, there's an option, in case anyone was relying on it. */\n\n    if (cb->assert_depth > 0 && meta_arg == ESC_K &&\n        (xoptions & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0)\n      {\n      *errorcodeptr = ERR99;\n      return 0;\n      }\n\n    /* For the rest (including \\X when Unicode is supported - if not it's\n    faulted at parse time), the OP value is the escape value when PCRE2_UCP is\n    not set; if it is set, most of them do not show up here because they are\n    converted into Unicode property tests in parse_regex().\n\n    In non-UTF mode, and for both 32-bit modes, we turn \\C into OP_ALLANY\n    instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds.\n    There are special UCP codes for \\B and \\b which are used in UCP mode unless\n    \"word\" matching is being forced to ASCII.\n\n    Note that \\b and \\B do a one-character lookbehind, and \\A also behaves as\n    if it does. */\n\n    switch(meta_arg)\n      {\n      case ESC_C:\n      cb->external_flags |= PCRE2_HASBKC;  /* Record */\n#if PCRE2_CODE_UNIT_WIDTH == 32\n      meta_arg = OP_ALLANY;\n      (void)utf; /* Avoid compiler warning. */\n#else\n      if (!utf) meta_arg = OP_ALLANY;\n#endif\n      break;\n\n      case ESC_B:\n      case ESC_b:\n      if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0)\n        meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY :\n          OP_UCP_WORD_BOUNDARY;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case ESC_A:\n      if (cb->max_lookbehind == 0) cb->max_lookbehind = 1;\n      break;\n\n      case ESC_K:\n      cb->external_flags |= PCRE2_HASBSK;  /* Record */\n      break;\n      }\n\n    *code++ = meta_arg;\n    break;  /* End META_ESCAPE */\n\n\n    /* ===================================================================*/\n    /* Handle an unrecognized meta value. A parsed pattern value less than\n    META_END is a literal. Otherwise we have a problem. */\n\n    default:\n    /* LCOV_EXCL_START */\n    if (meta >= META_END)\n      {\n      PCRE2_DEBUG_UNREACHABLE();\n      *errorcodeptr = ERR89;  /* Internal error - unrecognized. */\n      return 0;\n      }\n    /* LCOV_EXCL_STOP */\n\n    /* Handle a literal character. We come here by goto in the case of a\n    32-bit, non-UTF character whose value is greater than META_END. */\n\n    NORMAL_CHAR:\n    meta = *pptr;     /* Get the full 32 bits */\n    NORMAL_CHAR_SET:  /* Character is already in meta */\n    matched_char = TRUE;\n\n    /* For caseless UTF or UCP mode, check whether this character has more than\n    one other case. If so, generate a special OP_PROP item instead of OP_CHARI.\n    When casing restrictions apply, ignore caseless sets that start with an\n    ASCII character. If the character is affected by the special Turkish rules,\n    hardcode the matching characters using a caseset. */\n\n#ifdef SUPPORT_UNICODE\n    if ((utf||ucp) && (options & PCRE2_CASELESS) != 0)\n      {\n      uint32_t caseset;\n\n      if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) ==\n            PCRE2_EXTRA_TURKISH_CASING &&\n          UCD_ANY_I(meta))\n        {\n        caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(meta)? 0 : 3);\n        }\n      else if ((caseset = UCD_CASESET(meta)) != 0 &&\n               (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 &&\n               PRIV(ucd_caseless_sets)[caseset] < 128)\n        {\n        caseset = 0;  /* Ignore the caseless set if it's restricted. */\n        }\n\n      if (caseset != 0)\n        {\n        *code++ = OP_PROP;\n        *code++ = PT_CLIST;\n        *code++ = caseset;\n        if (firstcuflags == REQ_UNSET)\n          firstcuflags = zerofirstcuflags = REQ_NONE;\n        break;  /* End handling this meta item */\n        }\n      }\n#endif\n\n    /* Caseful matches, or caseless and not one of the multicase characters. We\n    come here by goto in the case of a positive class that contains only\n    case-partners of a character with just two cases; matched_char has already\n    been set TRUE and options fudged if necessary. */\n\n    CLASS_CASELESS_CHAR:\n\n    /* Get the character's code units into mcbuffer, with the length in\n    mclength. When not in UTF mode, the length is always 1. */\n\n#ifdef SUPPORT_UNICODE\n    if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else\n#endif\n      {\n      mclength = 1;\n      mcbuffer[0] = meta;\n      }\n\n    /* Generate the appropriate code */\n\n    *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR;\n    memcpy(code, mcbuffer, CU2BYTES(mclength));\n    code += mclength;\n\n    /* Remember if \\r or \\n were seen */\n\n    if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)\n      cb->external_flags |= PCRE2_HASCRORLF;\n\n    /* Set the first and required code units appropriately. If no previous\n    first code unit, set it from this character, but revert to none on a zero\n    repeat. Otherwise, leave the firstcu value alone, and don't change it on\n    a zero repeat. */\n\n    if (firstcuflags == REQ_UNSET)\n      {\n      zerofirstcuflags = REQ_NONE;\n      zeroreqcu = reqcu;\n      zeroreqcuflags = reqcuflags;\n\n      /* If the character is more than one code unit long, we can set a single\n      firstcu only if it is not to be matched caselessly. Multiple possible\n      starting code units may be picked up later in the studying code. */\n\n      if (mclength == 1 || req_caseopt == 0)\n        {\n        firstcu = mcbuffer[0];\n        firstcuflags = req_caseopt;\n        if (mclength != 1)\n          {\n          reqcu = code[-1];\n          reqcuflags = cb->req_varyopt;\n          }\n        }\n      else firstcuflags = reqcuflags = REQ_NONE;\n      }\n\n    /* firstcu was previously set; we can set reqcu only if the length is\n    1 or the matching is caseful. */\n\n    else\n      {\n      zerofirstcu = firstcu;\n      zerofirstcuflags = firstcuflags;\n      zeroreqcu = reqcu;\n      zeroreqcuflags = reqcuflags;\n      if (mclength == 1 || req_caseopt == 0)\n        {\n        reqcu = code[-1];\n        reqcuflags = req_caseopt | cb->req_varyopt;\n        }\n      }\n\n    /* If caselessness was temporarily instated, reset it. */\n\n    if (reset_caseful)\n      {\n      options &= ~PCRE2_CASELESS;\n      req_caseopt = 0;\n      reset_caseful = FALSE;\n      }\n\n    break;    /* End literal character handling */\n    }         /* End of big switch */\n  }           /* End of big loop */\n\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\nreturn 0;                  /* Avoid compiler warnings */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*   Compile regex: a sequence of alternatives    *\n*************************************************/\n\n/* On entry, pptr is pointing past the bracket meta, but on return it points to\nthe closing bracket or META_END. The code variable is pointing at the code unit\ninto which the BRA operator has been stored. This function is used during the\npre-compile phase when we are trying to find out the amount of memory needed,\nas well as during the real compile phase. The value of lengthptr distinguishes\nthe two phases.\n\nArguments:\n  options           option bits, including any changes for this subpattern\n  xoptions          extra option bits, ditto\n  codeptr           -> the address of the current code pointer\n  pptrptr           -> the address of the current parsed pattern pointer\n  errorcodeptr      -> pointer to error code variable\n  skipunits         skip this many code units at start (for brackets and OP_COND)\n  firstcuptr        place to put the first required code unit\n  firstcuflagsptr   place to put the first code unit flags\n  reqcuptr          place to put the last required code unit\n  reqcuflagsptr     place to put the last required code unit flags\n  bcptr             pointer to the chain of currently open branches\n  cb                points to the data block with tables pointers etc.\n  lengthptr         NULL during the real compile phase\n                    points to length accumulator during pre-compile phase\n\nReturns:            0 There has been an error\n                   +1 Success, this group must match at least one character\n                   -1 Success, this group may match an empty string\n*/\n\nstatic int\ncompile_regex(uint32_t options, uint32_t xoptions, PCRE2_UCHAR **codeptr,\n  uint32_t **pptrptr, int *errorcodeptr, uint32_t skipunits,\n  uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr,\n  uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps,\n  compile_block *cb, PCRE2_SIZE *lengthptr)\n{\nPCRE2_UCHAR *code = *codeptr;\nPCRE2_UCHAR *last_branch = code;\nPCRE2_UCHAR *start_bracket = code;\nBOOL lookbehind;\nopen_capitem capitem;\nint capnumber = 0;\nint okreturn = 1;\nuint32_t *pptr = *pptrptr;\nuint32_t firstcu, reqcu;\nuint32_t lookbehindlength;\nuint32_t lookbehindminlength;\nuint32_t firstcuflags, reqcuflags;\nPCRE2_SIZE length;\nbranch_chain bc;\n\n/* If set, call the external function that checks for stack availability. */\n\nif (cb->cx->stack_guard != NULL &&\n    cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))\n  {\n  *errorcodeptr= ERR33;\n  cb->erroroffset = 0;\n  return 0;\n  }\n\n/* Miscellaneous initialization */\n\nbc.outer = bcptr;\nbc.current_branch = code;\n\nfirstcu = reqcu = 0;\nfirstcuflags = reqcuflags = REQ_UNSET;\n\n/* Accumulate the length for use in the pre-compile phase. Start with the\nlength of the BRA and KET and any extra code units that are required at the\nbeginning. We accumulate in a local variable to save frequent testing of\nlengthptr for NULL. We cannot do this by looking at the value of 'code' at the\nstart and end of each alternative, because compiled items are discarded during\nthe pre-compile phase so that the workspace is not exceeded. */\n\nlength = 2 + 2*LINK_SIZE + skipunits;\n\n/* Remember if this is a lookbehind assertion, and if it is, save its length\nand skip over the pattern offset. */\n\nlookbehind = *code == OP_ASSERTBACK ||\n             *code == OP_ASSERTBACK_NOT ||\n             *code == OP_ASSERTBACK_NA;\n\nif (lookbehind)\n  {\n  lookbehindlength = META_DATA(pptr[-1]);\n  lookbehindminlength = *pptr;\n  pptr += SIZEOFFSET;\n  }\nelse lookbehindlength = lookbehindminlength = 0;\n\n/* If this is a capturing subpattern, add to the chain of open capturing items\nso that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA\nneed be tested here; changing this opcode to one of its variants, e.g.\nOP_SCBRAPOS, happens later, after the group has been compiled. */\n\nif (*code == OP_CBRA)\n  {\n  capnumber = GET2(code, 1 + LINK_SIZE);\n  capitem.number = capnumber;\n  capitem.next = open_caps;\n  capitem.assert_depth = cb->assert_depth;\n  open_caps = &capitem;\n  }\n\n/* Offset is set zero to mark that this bracket is still open */\n\nPUT(code, 1, 0);\ncode += 1 + LINK_SIZE + skipunits;\n\n/* Loop for each alternative branch */\n\nfor (;;)\n  {\n  int branch_return;\n  uint32_t branchfirstcu = 0, branchreqcu = 0;\n  uint32_t branchfirstcuflags = REQ_UNSET, branchreqcuflags = REQ_UNSET;\n\n  /* Insert OP_REVERSE or OP_VREVERSE if this is a lookbehind assertion. There\n  is only a single minimum length for the whole assertion. When the minimum\n  length is LOOKBEHIND_MAX it means that all branches are of fixed length,\n  though not necessarily the same length. In this case, the original OP_REVERSE\n  can be used. It can also be used if a branch in a variable length lookbehind\n  has the same maximum and minimum. Otherwise, use OP_VREVERSE, which has both\n  maximum and minimum values. */\n\n  if (lookbehind && lookbehindlength > 0)\n    {\n    if (lookbehindminlength == LOOKBEHIND_MAX ||\n        lookbehindminlength == lookbehindlength)\n      {\n      *code++ = OP_REVERSE;\n      PUT2INC(code, 0, lookbehindlength);\n      length += 1 + IMM2_SIZE;\n      }\n    else\n      {\n      *code++ = OP_VREVERSE;\n      PUT2INC(code, 0, lookbehindminlength);\n      PUT2INC(code, 0, lookbehindlength);\n      length += 1 + 2*IMM2_SIZE;\n      }\n    }\n\n  /* Now compile the branch; in the pre-compile phase its length gets added\n  into the length. */\n\n  if ((branch_return =\n        compile_branch(&options, &xoptions, &code, &pptr, errorcodeptr,\n          &branchfirstcu, &branchfirstcuflags, &branchreqcu, &branchreqcuflags,\n          &bc, open_caps, cb, (lengthptr == NULL)? NULL : &length)) == 0)\n    return 0;\n\n  /* If a branch can match an empty string, so can the whole group. */\n\n  if (branch_return < 0) okreturn = -1;\n\n  /* In the real compile phase, there is some post-processing to be done. */\n\n  if (lengthptr == NULL)\n    {\n    /* If this is the first branch, the firstcu and reqcu values for the\n    branch become the values for the regex. */\n\n    if (*last_branch != OP_ALT)\n      {\n      firstcu = branchfirstcu;\n      firstcuflags = branchfirstcuflags;\n      reqcu = branchreqcu;\n      reqcuflags = branchreqcuflags;\n      }\n\n    /* If this is not the first branch, the first char and reqcu have to\n    match the values from all the previous branches, except that if the\n    previous value for reqcu didn't have REQ_VARY set, it can still match,\n    and we set REQ_VARY for the group from this branch's value. */\n\n    else\n      {\n      /* If we previously had a firstcu, but it doesn't match the new branch,\n      we have to abandon the firstcu for the regex, but if there was\n      previously no reqcu, it takes on the value of the old firstcu. */\n\n      if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu)\n        {\n        if (firstcuflags < REQ_NONE)\n          {\n          if (reqcuflags >= REQ_NONE)\n            {\n            reqcu = firstcu;\n            reqcuflags = firstcuflags;\n            }\n          }\n        firstcuflags = REQ_NONE;\n        }\n\n      /* If we (now or from before) have no firstcu, a firstcu from the\n      branch becomes a reqcu if there isn't a branch reqcu. */\n\n      if (firstcuflags >= REQ_NONE && branchfirstcuflags < REQ_NONE &&\n          branchreqcuflags >= REQ_NONE)\n        {\n        branchreqcu = branchfirstcu;\n        branchreqcuflags = branchfirstcuflags;\n        }\n\n      /* Now ensure that the reqcus match */\n\n      if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) ||\n          reqcu != branchreqcu)\n        reqcuflags = REQ_NONE;\n      else\n        {\n        reqcu = branchreqcu;\n        reqcuflags |= branchreqcuflags; /* To \"or\" REQ_VARY if present */\n        }\n      }\n    }\n\n  /* Handle reaching the end of the expression, either ')' or end of pattern.\n  In the real compile phase, go back through the alternative branches and\n  reverse the chain of offsets, with the field in the BRA item now becoming an\n  offset to the first alternative. If there are no alternatives, it points to\n  the end of the group. The length in the terminating ket is always the length\n  of the whole bracketed item. Return leaving the pointer at the terminating\n  char. */\n\n  if (META_CODE(*pptr) != META_ALT)\n    {\n    if (lengthptr == NULL)\n      {\n      uint32_t branch_length = (uint32_t)(code - last_branch);\n      do\n        {\n        uint32_t prev_length = GET(last_branch, 1);\n        PUT(last_branch, 1, branch_length);\n        branch_length = prev_length;\n        last_branch -= branch_length;\n        }\n      while (branch_length > 0);\n      }\n\n    /* Fill in the ket */\n\n    *code = OP_KET;\n    PUT(code, 1, (uint32_t)(code - start_bracket));\n    code += 1 + LINK_SIZE;\n\n    /* Set values to pass back */\n\n    *codeptr = code;\n    *pptrptr = pptr;\n    *firstcuptr = firstcu;\n    *firstcuflagsptr = firstcuflags;\n    *reqcuptr = reqcu;\n    *reqcuflagsptr = reqcuflags;\n    if (lengthptr != NULL)\n      {\n      if (OFLOW_MAX - *lengthptr < length)\n        {\n        *errorcodeptr = ERR20;\n        return 0;\n        }\n      *lengthptr += length;\n      }\n    return okreturn;\n    }\n\n  /* Another branch follows. In the pre-compile phase, we can move the code\n  pointer back to where it was for the start of the first branch. (That is,\n  pretend that each branch is the only one.)\n\n  In the real compile phase, insert an ALT node. Its length field points back\n  to the previous branch while the bracket remains open. At the end the chain\n  is reversed. It's done like this so that the start of the bracket has a\n  zero offset until it is closed, making it possible to detect recursion. */\n\n  if (lengthptr != NULL)\n    {\n    code = *codeptr + 1 + LINK_SIZE + skipunits;\n    length += 1 + LINK_SIZE;\n    }\n  else\n    {\n    *code = OP_ALT;\n    PUT(code, 1, (int)(code - last_branch));\n    bc.current_branch = last_branch = code;\n    code += 1 + LINK_SIZE;\n    }\n\n  /* Set the maximum lookbehind length for the next branch (if not in a\n  lookbehind the value will be zero) and then advance past the vertical bar. */\n\n  lookbehindlength = META_DATA(*pptr);\n  pptr++;\n  }\n\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\nreturn 0;                  /* Avoid compiler warnings */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*          Check for anchored pattern            *\n*************************************************/\n\n/* Try to find out if this is an anchored regular expression. Consider each\nalternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket\nall of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then\nit's anchored. However, if this is a multiline pattern, then only OP_SOD will\nbe found, because ^ generates OP_CIRCM in that mode.\n\nWe can also consider a regex to be anchored if OP_SOM starts all its branches.\nThis is the code for \\G, which means \"match at start of match position, taking\ninto account the match offset\".\n\nA branch is also implicitly anchored if it starts with .* and DOTALL is set,\nbecause that will try the rest of the pattern at all possible matching points,\nso there is no point trying again.... er ....\n\n.... except when the .* appears inside capturing parentheses, and there is a\nsubsequent back reference to those parentheses. We haven't enough information\nto catch that case precisely.\n\nAt first, the best we could do was to detect when .* was in capturing brackets\nand the highest back reference was greater than or equal to that level.\nHowever, by keeping a bitmap of the first 31 back references, we can catch some\nof the more common cases more precisely.\n\n... A second exception is when the .* appears inside an atomic group, because\nthis prevents the number of characters it matches from being adjusted.\n\nArguments:\n  code           points to start of the compiled pattern\n  bracket_map    a bitmap of which brackets we are inside while testing; this\n                   handles up to substring 31; after that we just have to take\n                   the less precise approach\n  cb             points to the compile data block\n  atomcount      atomic group level\n  inassert       TRUE if in an assertion\n  dotstar_anchor TRUE if automatic anchoring optimization is enabled\n\nReturns:     TRUE or FALSE\n*/\n\nstatic BOOL\nis_anchored(PCRE2_SPTR code, uint32_t bracket_map, compile_block *cb,\n  int atomcount, BOOL inassert, BOOL dotstar_anchor)\n{\ndo {\n   PCRE2_SPTR scode = first_significant_code(\n     code + PRIV(OP_lengths)[*code], FALSE);\n   int op = *scode;\n\n   /* Non-capturing brackets */\n\n   if (op == OP_BRA  || op == OP_BRAPOS ||\n       op == OP_SBRA || op == OP_SBRAPOS)\n     {\n     if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* Capturing brackets */\n\n   else if (op == OP_CBRA  || op == OP_CBRAPOS ||\n            op == OP_SCBRA || op == OP_SCBRAPOS)\n     {\n     int n = GET2(scode, 1+LINK_SIZE);\n     uint32_t new_map = bracket_map | ((n < 32)? (1u << n) : 1);\n     if (!is_anchored(scode, new_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE;\n     }\n\n   /* Positive forward assertion */\n\n   else if (op == OP_ASSERT || op == OP_ASSERT_NA)\n     {\n     if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) return FALSE;\n     }\n\n   /* Condition. If there is no second branch, it can't be anchored. */\n\n   else if (op == OP_COND || op == OP_SCOND)\n     {\n     if (scode[GET(scode,1)] != OP_ALT) return FALSE;\n     if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* Atomic groups */\n\n   else if (op == OP_ONCE)\n     {\n     if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and\n   it isn't in brackets that are or may be referenced or inside an atomic\n   group or an assertion. Also the pattern must not contain *PRUNE or *SKIP,\n   because these break the feature. Consider, for example, /(?s).*?(*PRUNE)b/\n   with the subject \"aab\", which matches \"b\", i.e. not at the start of a line.\n   There is also an option that disables auto-anchoring. */\n\n   else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||\n             op == OP_TYPEPOSSTAR))\n     {\n     if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 ||\n         atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor)\n       return FALSE;\n     }\n\n   /* Check for explicit anchoring */\n\n   else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;\n\n   code += GET(code, 1);\n   }\nwhile (*code == OP_ALT);   /* Loop for each alternative */\nreturn TRUE;\n}\n\n\n\n/*************************************************\n*         Check for starting with ^ or .*        *\n*************************************************/\n\n/* This is called to find out if every branch starts with ^ or .* so that\n\"first char\" processing can be done to speed things up in multiline\nmatching and for non-DOTALL patterns that start with .* (which must start at\nthe beginning or after \\n). As in the case of is_anchored() (see above), we\nhave to take account of back references to capturing brackets that contain .*\nbecause in that case we can't make the assumption. Also, the appearance of .*\ninside atomic brackets or in an assertion, or in a pattern that contains *PRUNE\nor *SKIP does not count, because once again the assumption no longer holds.\n\nArguments:\n  code           points to start of the compiled pattern or a group\n  bracket_map    a bitmap of which brackets we are inside while testing; this\n                   handles up to substring 31; after that we just have to take\n                   the less precise approach\n  cb             points to the compile data\n  atomcount      atomic group level\n  inassert       TRUE if in an assertion\n  dotstar_anchor TRUE if automatic anchoring optimization is enabled\n\nReturns:         TRUE or FALSE\n*/\n\nstatic BOOL\nis_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,\n  int atomcount, BOOL inassert, BOOL dotstar_anchor)\n{\ndo {\n   PCRE2_SPTR scode = first_significant_code(\n     code + PRIV(OP_lengths)[*code], FALSE);\n   int op = *scode;\n\n   /* If we are at the start of a conditional assertion group, *both* the\n   conditional assertion *and* what follows the condition must satisfy the test\n   for start of line. Other kinds of condition fail. Note that there may be an\n   auto-callout at the start of a condition. */\n\n   if (op == OP_COND)\n     {\n     scode += 1 + LINK_SIZE;\n\n     if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];\n       else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE);\n\n     switch (*scode)\n       {\n       case OP_CREF:\n       case OP_DNCREF:\n       case OP_RREF:\n       case OP_DNRREF:\n       case OP_FAIL:\n       case OP_FALSE:\n       case OP_TRUE:\n       return FALSE;\n\n       default:     /* Assertion */\n       if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor))\n         return FALSE;\n       do scode += GET(scode, 1); while (*scode == OP_ALT);\n       scode += 1 + LINK_SIZE;\n       break;\n       }\n     scode = first_significant_code(scode, FALSE);\n     op = *scode;\n     }\n\n   /* Non-capturing brackets */\n\n   if (op == OP_BRA  || op == OP_BRAPOS ||\n       op == OP_SBRA || op == OP_SBRAPOS)\n     {\n     if (!is_startline(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* Capturing brackets */\n\n   else if (op == OP_CBRA  || op == OP_CBRAPOS ||\n            op == OP_SCBRA || op == OP_SCBRAPOS)\n     {\n     int n = GET2(scode, 1+LINK_SIZE);\n     unsigned int new_map = bracket_map | ((n < 32)? (1u << n) : 1);\n     if (!is_startline(scode, new_map, cb, atomcount, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* Positive forward assertions */\n\n   else if (op == OP_ASSERT || op == OP_ASSERT_NA)\n     {\n     if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* Atomic brackets */\n\n   else if (op == OP_ONCE)\n     {\n     if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor))\n       return FALSE;\n     }\n\n   /* .* means \"start at start or after \\n\" if it isn't in atomic brackets or\n   brackets that may be referenced or an assertion, and as long as the pattern\n   does not contain *PRUNE or *SKIP, because these break the feature. Consider,\n   for example, /.*?a(*PRUNE)b/ with the subject \"aab\", which matches \"ab\",\n   i.e. not at the start of a line. There is also an option that disables this\n   optimization. */\n\n   else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)\n     {\n     if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 ||\n         atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor)\n       return FALSE;\n     }\n\n   /* Check for explicit circumflex; anything else gives a FALSE result. Note\n   in particular that this includes atomic brackets OP_ONCE because the number\n   of characters matched by .* cannot be adjusted inside them. */\n\n   else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;\n\n   /* Move on to the next alternative */\n\n   code += GET(code, 1);\n   }\nwhile (*code == OP_ALT);  /* Loop for each alternative */\nreturn TRUE;\n}\n\n\n\n/*************************************************\n*   Scan compiled regex for recursion reference  *\n*************************************************/\n\n/* This function scans through a compiled pattern until it finds an instance of\nOP_RECURSE.\n\nArguments:\n  code        points to start of expression\n  utf         TRUE in UTF mode\n\nReturns:      pointer to the opcode for OP_RECURSE, or NULL if not found\n*/\n\nstatic PCRE2_UCHAR *\nfind_recurse(PCRE2_UCHAR *code, BOOL utf)\n{\nfor (;;)\n  {\n  PCRE2_UCHAR c = *code;\n  if (c == OP_END) return NULL;\n  if (c == OP_RECURSE) return code;\n\n  /* XCLASS is used for classes that cannot be represented just by a bit map.\n  This includes negated single high-valued characters. ECLASS is used for\n  classes that use set operations internally. CALLOUT_STR is used for\n  callouts with string arguments. In each case the length in the table is\n  zero; the actual length is stored in the compiled code. */\n\n  if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1);\n  else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);\n\n  /* Otherwise, we can get the item's length from the table, except that for\n  repeated character types, we have to test for \\p and \\P, which have an extra\n  two code units of parameters, and for MARK/PRUNE/SKIP/THEN with an argument,\n  we must add in its length. */\n\n  else\n    {\n    switch(c)\n      {\n      case OP_TYPESTAR:\n      case OP_TYPEMINSTAR:\n      case OP_TYPEPLUS:\n      case OP_TYPEMINPLUS:\n      case OP_TYPEQUERY:\n      case OP_TYPEMINQUERY:\n      case OP_TYPEPOSSTAR:\n      case OP_TYPEPOSPLUS:\n      case OP_TYPEPOSQUERY:\n      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;\n      break;\n\n      case OP_TYPEPOSUPTO:\n      case OP_TYPEUPTO:\n      case OP_TYPEMINUPTO:\n      case OP_TYPEEXACT:\n      if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)\n        code += 2;\n      break;\n\n      case OP_MARK:\n      case OP_COMMIT_ARG:\n      case OP_PRUNE_ARG:\n      case OP_SKIP_ARG:\n      case OP_THEN_ARG:\n      code += code[1];\n      break;\n      }\n\n    /* Add in the fixed length from the table */\n\n    code += PRIV(OP_lengths)[c];\n\n    /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may\n    be followed by a multi-unit character. The length in the table is a\n    minimum, so we have to arrange to skip the extra units. */\n\n#ifdef MAYBE_UTF_MULTI\n    if (utf) switch(c)\n      {\n      case OP_CHAR:\n      case OP_CHARI:\n      case OP_NOT:\n      case OP_NOTI:\n      case OP_EXACT:\n      case OP_EXACTI:\n      case OP_NOTEXACT:\n      case OP_NOTEXACTI:\n      case OP_UPTO:\n      case OP_UPTOI:\n      case OP_NOTUPTO:\n      case OP_NOTUPTOI:\n      case OP_MINUPTO:\n      case OP_MINUPTOI:\n      case OP_NOTMINUPTO:\n      case OP_NOTMINUPTOI:\n      case OP_POSUPTO:\n      case OP_POSUPTOI:\n      case OP_NOTPOSUPTO:\n      case OP_NOTPOSUPTOI:\n      case OP_STAR:\n      case OP_STARI:\n      case OP_NOTSTAR:\n      case OP_NOTSTARI:\n      case OP_MINSTAR:\n      case OP_MINSTARI:\n      case OP_NOTMINSTAR:\n      case OP_NOTMINSTARI:\n      case OP_POSSTAR:\n      case OP_POSSTARI:\n      case OP_NOTPOSSTAR:\n      case OP_NOTPOSSTARI:\n      case OP_PLUS:\n      case OP_PLUSI:\n      case OP_NOTPLUS:\n      case OP_NOTPLUSI:\n      case OP_MINPLUS:\n      case OP_MINPLUSI:\n      case OP_NOTMINPLUS:\n      case OP_NOTMINPLUSI:\n      case OP_POSPLUS:\n      case OP_POSPLUSI:\n      case OP_NOTPOSPLUS:\n      case OP_NOTPOSPLUSI:\n      case OP_QUERY:\n      case OP_QUERYI:\n      case OP_NOTQUERY:\n      case OP_NOTQUERYI:\n      case OP_MINQUERY:\n      case OP_MINQUERYI:\n      case OP_NOTMINQUERY:\n      case OP_NOTMINQUERYI:\n      case OP_POSQUERY:\n      case OP_POSQUERYI:\n      case OP_NOTPOSQUERY:\n      case OP_NOTPOSQUERYI:\n      if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);\n      break;\n      }\n#else\n    (void)(utf);  /* Keep compiler happy by referencing function argument */\n#endif  /* MAYBE_UTF_MULTI */\n    }\n  }\n}\n\n\n\n/*************************************************\n*    Check for asserted fixed first code unit    *\n*************************************************/\n\n/* During compilation, the \"first code unit\" settings from forward assertions\nare discarded, because they can cause conflicts with actual literals that\nfollow. However, if we end up without a first code unit setting for an\nunanchored pattern, it is worth scanning the regex to see if there is an\ninitial asserted first code unit. If all branches start with the same asserted\ncode unit, or with a non-conditional bracket all of whose alternatives start\nwith the same asserted code unit (recurse ad lib), then we return that code\nunit, with the flags set to zero or REQ_CASELESS; otherwise return zero with\nREQ_NONE in the flags.\n\nArguments:\n  code       points to start of compiled pattern\n  flags      points to the first code unit flags\n  inassert   non-zero if in an assertion\n\nReturns:     the fixed first code unit, or 0 with REQ_NONE in flags\n*/\n\nstatic uint32_t\nfind_firstassertedcu(PCRE2_SPTR code, uint32_t *flags, uint32_t inassert)\n{\nuint32_t c = 0;\nuint32_t cflags = REQ_NONE;\n\n*flags = REQ_NONE;\ndo {\n   uint32_t d;\n   uint32_t dflags;\n   int xl = (*code == OP_CBRA || *code == OP_SCBRA ||\n             *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;\n   PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE);\n   PCRE2_UCHAR op = *scode;\n\n   switch(op)\n     {\n     default:\n     return 0;\n\n     case OP_BRA:\n     case OP_BRAPOS:\n     case OP_CBRA:\n     case OP_SCBRA:\n     case OP_CBRAPOS:\n     case OP_SCBRAPOS:\n     case OP_ASSERT:\n     case OP_ASSERT_NA:\n     case OP_ONCE:\n     case OP_SCRIPT_RUN:\n     d = find_firstassertedcu(scode, &dflags, inassert +\n       ((op == OP_ASSERT || op == OP_ASSERT_NA)?1:0));\n     if (dflags >= REQ_NONE) return 0;\n     if (cflags >= REQ_NONE) { c = d; cflags = dflags; }\n       else if (c != d || cflags != dflags) return 0;\n     break;\n\n     case OP_EXACT:\n     scode += IMM2_SIZE;\n     PCRE2_FALLTHROUGH /* Fall through */\n\n     case OP_CHAR:\n     case OP_PLUS:\n     case OP_MINPLUS:\n     case OP_POSPLUS:\n     if (inassert == 0) return 0;\n     if (cflags >= REQ_NONE) { c = scode[1]; cflags = 0; }\n       else if (c != scode[1]) return 0;\n     break;\n\n     case OP_EXACTI:\n     scode += IMM2_SIZE;\n     PCRE2_FALLTHROUGH /* Fall through */\n\n     case OP_CHARI:\n     case OP_PLUSI:\n     case OP_MINPLUSI:\n     case OP_POSPLUSI:\n     if (inassert == 0) return 0;\n\n     /* If the character is more than one code unit long, we cannot set its\n     first code unit when matching caselessly. Later scanning may pick up\n     multiple code units. */\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n     if (scode[1] >= 0x80) return 0;\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n     if (scode[1] >= 0xd800 && scode[1] <= 0xdfff) return 0;\n#endif\n#endif\n\n     if (cflags >= REQ_NONE) { c = scode[1]; cflags = REQ_CASELESS; }\n       else if (c != scode[1]) return 0;\n     break;\n     }\n\n   code += GET(code, 1);\n   }\nwhile (*code == OP_ALT);\n\n*flags = cflags;\nreturn c;\n}\n\n\n\n/*************************************************\n*             Skip in parsed pattern             *\n*************************************************/\n\n/* This function is called to skip parts of the parsed pattern when finding the\nlength of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find\nthe end of the branch, it is called to skip over an internal lookaround or\n(DEFINE) group, and it is also called to skip to the end of a class, during\nwhich it will never encounter nested groups (but there's no need to have\nspecial code for that).\n\nWhen called to find the end of a branch or group, pptr must point to the first\nmeta code inside the branch, not the branch-starting code. In other cases it\ncan point to the item that causes the function to be called.\n\nArguments:\n  pptr       current pointer to skip from\n  skiptype   PSKIP_CLASS when skipping to end of class\n             PSKIP_ALT when META_ALT ends the skip\n             PSKIP_KET when only META_KET ends the skip\n\nReturns:     new value of pptr\n             NULL if META_END is reached - should never occur\n               or for an unknown meta value - likewise\n*/\n\nstatic uint32_t *\nparsed_skip(uint32_t *pptr, uint32_t skiptype)\n{\nuint32_t nestlevel = 0;\n\nfor (;; pptr++)\n  {\n  uint32_t meta = META_CODE(*pptr);\n\n  switch(meta)\n    {\n    default:  /* Just skip over most items */\n    if (meta < META_END) continue;  /* Literal */\n    break;\n\n    /* The parsed regex is malformed; we have reached the end and did\n    not find the end of the construct which we are skipping over. */\n\n    /* LCOV_EXCL_START */\n    case META_END:\n    PCRE2_DEBUG_UNREACHABLE();\n    return NULL;\n    /* LCOV_EXCL_STOP */\n\n    /* The data for these items is variable in length. */\n\n    case META_BACKREF:  /* Offset is present only if group >= 10 */\n    if (META_DATA(*pptr) >= 10) pptr += SIZEOFFSET;\n    break;\n\n    case META_ESCAPE:\n    if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)\n      pptr += 1;     /* Skip prop data */\n    break;\n\n    case META_MARK:     /* Add the length of the name. */\n    case META_COMMIT_ARG:\n    case META_PRUNE_ARG:\n    case META_SKIP_ARG:\n    case META_THEN_ARG:\n    pptr += pptr[1];\n    break;\n\n    /* These are the \"active\" items in this loop. */\n\n    case META_CLASS_END:\n    if (skiptype == PSKIP_CLASS) return pptr;\n    break;\n\n    case META_ATOMIC:\n    case META_CAPTURE:\n    case META_COND_ASSERT:\n    case META_COND_DEFINE:\n    case META_COND_NAME:\n    case META_COND_NUMBER:\n    case META_COND_RNAME:\n    case META_COND_RNUMBER:\n    case META_COND_VERSION:\n    case META_SCS:\n    case META_LOOKAHEAD:\n    case META_LOOKAHEADNOT:\n    case META_LOOKAHEAD_NA:\n    case META_LOOKBEHIND:\n    case META_LOOKBEHINDNOT:\n    case META_LOOKBEHIND_NA:\n    case META_NOCAPTURE:\n    case META_SCRIPT_RUN:\n    nestlevel++;\n    break;\n\n    case META_ALT:\n    if (nestlevel == 0 && skiptype == PSKIP_ALT) return pptr;\n    break;\n\n    case META_KET:\n    if (nestlevel == 0) return pptr;\n    nestlevel--;\n    break;\n    }\n\n  /* The extra data item length for each meta is in a table. */\n\n  meta = (meta >> 16) & 0x7fff;\n  if (meta >= sizeof(meta_extra_lengths)) return NULL;\n  pptr += meta_extra_lengths[meta];\n  }\n\n/* LCOV_EXCL_START */\nPCRE2_UNREACHABLE(); /* Control never reaches here */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*       Find length of a parsed group            *\n*************************************************/\n\n/* This is called for nested groups within a branch of a lookbehind whose\nlength is being computed. On entry, the pointer must be at the first element\nafter the group initializing code. On exit it points to OP_KET. Caching is used\nto improve processing speed when the same capturing group occurs many times.\n\nArguments:\n  pptrptr     pointer to pointer in the parsed pattern\n  minptr      where to return the minimum length\n  isinline    FALSE if a reference or recursion; TRUE for inline group\n  errcodeptr  pointer to the errorcode\n  lcptr       pointer to the loop counter\n  group       number of captured group or -1 for a non-capturing group\n  recurses    chain of recurse_check to catch mutual recursion\n  cb          pointer to the compile data\n\nReturns:      the maximum group length or a negative number\n*/\n\nstatic int\nget_grouplength(uint32_t **pptrptr, int *minptr, BOOL isinline, int *errcodeptr,\n  int *lcptr, int group, parsed_recurse_check *recurses, compile_block *cb)\n{\nuint32_t *gi = cb->groupinfo + 2 * group;\nint branchlength, branchminlength;\nint grouplength = -1;\nint groupminlength = INT_MAX;\n\n/* The cache can be used only if there is no possibility of there being two\ngroups with the same number. We do not need to set the end pointer for a group\nthat is being processed as a back reference or recursion, but we must do so for\nan inline group. */\n\nif (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0)\n  {\n  uint32_t groupinfo = gi[0];\n  if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1;\n  if ((groupinfo & GI_SET_FIXED_LENGTH) != 0)\n    {\n    if (isinline) *pptrptr = parsed_skip(*pptrptr, PSKIP_KET);\n    *minptr = gi[1];\n    return groupinfo & GI_FIXED_LENGTH_MASK;\n    }\n  }\n\n/* Scan the group. In this case we find the end pointer of necessity. */\n\nfor(;;)\n  {\n  branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr,\n    recurses, cb);\n  if (branchlength < 0) goto ISNOTFIXED;\n  if (branchlength > grouplength) grouplength = branchlength;\n  if (branchminlength < groupminlength) groupminlength = branchminlength;\n  if (**pptrptr == META_KET) break;\n  *pptrptr += 1;   /* Skip META_ALT */\n  }\n\nif (group > 0)\n  {\n  gi[0] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength);\n  gi[1] = groupminlength;\n  }\n\n*minptr = groupminlength;\nreturn grouplength;\n\nISNOTFIXED:\nif (group > 0) gi[0] |= GI_NOT_FIXED_LENGTH;\nreturn -1;\n}\n\n\n\n/*************************************************\n*        Find length of a parsed branch          *\n*************************************************/\n\n/* Return fixed maximum and minimum lengths for a branch in a lookbehind,\ngiving an error if the length is not limited. On entry, *pptrptr points to the\nfirst element inside the branch. On exit it is set to point to the ALT or KET.\n\nArguments:\n  pptrptr     pointer to pointer in the parsed pattern\n  minptr      where to return the minimum length\n  errcodeptr  pointer to error code\n  lcptr       pointer to loop counter\n  recurses    chain of recurse_check to catch mutual recursion\n  cb          pointer to compile block\n\nReturns:      the maximum length, or a negative value on error\n*/\n\nstatic int\nget_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr,\n  parsed_recurse_check *recurses, compile_block *cb)\n{\nint branchlength = 0;\nint branchminlength = 0;\nint grouplength, groupminlength;\nuint32_t lastitemlength = 0;\nuint32_t lastitemminlength = 0;\nuint32_t *pptr = *pptrptr;\nPCRE2_SIZE offset;\nparsed_recurse_check this_recurse;\n\n/* A large and/or complex regex can take too long to process. This can happen\nmore often when (?| groups are present in the pattern because their length\ncannot be cached. */\n\nif ((*lcptr)++ > 2000)\n  {\n  *errcodeptr = ERR35;  /* Lookbehind is too complicated */\n  return -1;\n  }\n\n/* Scan the branch, accumulating the length. */\n\nfor (;; pptr++)\n  {\n  parsed_recurse_check *r;\n  uint32_t *gptr, *gptrend;\n  uint32_t escape;\n  uint32_t min, max;\n  uint32_t group = 0;\n  uint32_t itemlength = 0;\n  uint32_t itemminlength = 0;\n\n  if (*pptr < META_END)\n    {\n    itemlength = itemminlength = 1;\n    }\n\n  else switch (META_CODE(*pptr))\n    {\n    case META_KET:\n    case META_ALT:\n    goto EXIT;\n\n    /* (*ACCEPT) and (*FAIL) terminate the branch, but we must skip to the\n    actual termination. */\n\n    case META_ACCEPT:\n    case META_FAIL:\n    pptr = parsed_skip(pptr, PSKIP_ALT);\n    if (pptr == NULL) goto PARSED_SKIP_FAILED;\n    goto EXIT;\n\n    case META_MARK:\n    case META_COMMIT_ARG:\n    case META_PRUNE_ARG:\n    case META_SKIP_ARG:\n    case META_THEN_ARG:\n    pptr += pptr[1] + 1;\n    break;\n\n    case META_CIRCUMFLEX:\n    case META_COMMIT:\n    case META_DOLLAR:\n    case META_PRUNE:\n    case META_SKIP:\n    case META_THEN:\n    break;\n\n    case META_OPTIONS:\n    pptr += 2;\n    break;\n\n    case META_BIGVALUE:\n    itemlength = itemminlength = 1;\n    pptr += 1;\n    break;\n\n    case META_CLASS:\n    case META_CLASS_NOT:\n    itemlength = itemminlength = 1;\n    pptr = parsed_skip(pptr, PSKIP_CLASS);\n    if (pptr == NULL) goto PARSED_SKIP_FAILED;\n    break;\n\n    case META_CLASS_EMPTY_NOT:\n    case META_DOT:\n    itemlength = itemminlength = 1;\n    break;\n\n    case META_CALLOUT_NUMBER:\n    pptr += 3;\n    break;\n\n    case META_CALLOUT_STRING:\n    pptr += 3 + SIZEOFFSET;\n    break;\n\n    /* Only some escapes consume a character. Of those, \\R can match one or two\n    characters, but \\X is never allowed because it matches an unknown number of\n    characters. \\C is allowed only in 32-bit and non-UTF 8/16-bit modes. */\n\n    case META_ESCAPE:\n    escape = META_DATA(*pptr);\n    if (escape == ESC_X) return -1;\n    if (escape == ESC_R)\n      {\n      itemminlength = 1;\n      itemlength = 2;\n      }\n    else if (escape > ESC_b && escape < ESC_Z)\n      {\n#if PCRE2_CODE_UNIT_WIDTH != 32\n      if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C)\n        {\n        *errcodeptr = ERR36;\n        return -1;\n        }\n#endif\n      itemlength = itemminlength = 1;\n      if (escape == ESC_p || escape == ESC_P) pptr++;  /* Skip prop data */\n      }\n    break;\n\n    /* Lookaheads do not contribute to the length of this branch, but they may\n    contain lookbehinds within them whose lengths need to be set. */\n\n    case META_LOOKAHEAD:\n    case META_LOOKAHEADNOT:\n    case META_LOOKAHEAD_NA:\n    case META_SCS:\n    *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb, lcptr);\n    if (*errcodeptr != 0) return -1;\n\n    /* Ignore any qualifiers that follow a lookahead assertion. */\n\n    switch (pptr[1])\n      {\n      case META_ASTERISK:\n      case META_ASTERISK_PLUS:\n      case META_ASTERISK_QUERY:\n      case META_PLUS:\n      case META_PLUS_PLUS:\n      case META_PLUS_QUERY:\n      case META_QUERY:\n      case META_QUERY_PLUS:\n      case META_QUERY_QUERY:\n      pptr++;\n      break;\n\n      case META_MINMAX:\n      case META_MINMAX_PLUS:\n      case META_MINMAX_QUERY:\n      pptr += 3;\n      break;\n\n      default:\n      break;\n      }\n    break;\n\n    /* A nested lookbehind does not contribute any length to this lookbehind,\n    but must itself be checked and have its lengths set. Note that\n    set_lookbehind_lengths() updates pptr, leaving it pointing to the final ket\n    of the group, so no need to update it here. */\n\n    case META_LOOKBEHIND:\n    case META_LOOKBEHINDNOT:\n    case META_LOOKBEHIND_NA:\n    if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb))\n      return -1;\n    break;\n\n    /* Back references and recursions are handled by very similar code. At this\n    stage, the names generated in the parsing pass are available, but the main\n    name table has not yet been created. So for the named varieties, scan the\n    list of names in order to get the number of the first one in the pattern,\n    and whether or not this name is duplicated. */\n\n    case META_BACKREF_BYNAME:\n    if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0)\n      goto ISNOTFIXED;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case META_RECURSE_BYNAME:\n      {\n      PCRE2_SPTR name;\n      BOOL is_dupname = FALSE;\n      named_group *ng;\n      uint32_t meta_code = META_CODE(*pptr);\n      uint32_t length = *(++pptr);\n\n      GETPLUSOFFSET(offset, pptr);\n      name = cb->start_pattern + offset;\n      ng = PRIV(compile_find_named_group)(name, length, cb);\n\n      if (ng == NULL)\n        {\n        *errcodeptr = ERR15;  /* Non-existent subpattern */\n        cb->erroroffset = offset;\n        return -1;\n        }\n\n      group = ng->number;\n      is_dupname = (ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0;\n\n      /* A numerical back reference can be fixed length if duplicate capturing\n      groups are not being used. A non-duplicate named back reference can also\n      be handled. */\n\n      if (meta_code == META_RECURSE_BYNAME ||\n          (!is_dupname && (cb->external_flags & PCRE2_DUPCAPUSED) == 0))\n        goto RECURSE_OR_BACKREF_LENGTH;  /* Handle as a numbered version. */\n      }\n    goto ISNOTFIXED;                     /* Duplicate name or number */\n\n    /* The offset values for back references < 10 are in a separate vector\n    because otherwise they would use more than two parsed pattern elements on\n    64-bit systems. */\n\n    case META_BACKREF:\n    if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0 ||\n        (cb->external_flags & PCRE2_DUPCAPUSED) != 0)\n      goto ISNOTFIXED;\n    group = META_DATA(*pptr);\n    if (group < 10)\n      {\n      offset = cb->small_ref_offset[group];\n      goto RECURSE_OR_BACKREF_LENGTH;\n      }\n\n    PCRE2_FALLTHROUGH /* Fall through */\n    /* For groups >= 10 - picking up group twice does no harm. */\n\n    /* A true recursion implies not fixed length, but a subroutine call may\n    be OK. Back reference \"recursions\" are also failed. */\n\n    case META_RECURSE:\n    group = META_DATA(*pptr);\n    GETPLUSOFFSET(offset, pptr);\n\n    RECURSE_OR_BACKREF_LENGTH:\n    if (group > cb->bracount)\n      {\n      cb->erroroffset = offset;\n      *errcodeptr = ERR15;  /* Non-existent subpattern */\n      return -1;\n      }\n    if (group == 0) goto ISNOTFIXED;  /* Local recursion */\n    for (gptr = cb->parsed_pattern; *gptr != META_END; gptr++)\n      {\n      if (META_CODE(*gptr) == META_BIGVALUE) gptr++;\n        else if (*gptr == (META_CAPTURE | group)) break;\n      }\n\n    /* We must start the search for the end of the group at the first meta code\n    inside the group. Otherwise it will be treated as an enclosed group. */\n\n    gptrend = parsed_skip(gptr + 1, PSKIP_KET);\n    if (gptrend == NULL) goto PARSED_SKIP_FAILED;\n    if (pptr > gptr && pptr < gptrend) goto ISNOTFIXED;  /* Local recursion */\n    for (r = recurses; r != NULL; r = r->prev) if (r->groupptr == gptr) break;\n    if (r != NULL) goto ISNOTFIXED;   /* Mutual recursion */\n    this_recurse.prev = recurses;\n    this_recurse.groupptr = gptr;\n\n    /* We do not need to know the position of the end of the group, that is,\n    gptr is not used after the call to get_grouplength(). Setting the second\n    argument FALSE stops it scanning for the end when the length can be found\n    in the cache. */\n\n    gptr++;\n    grouplength = get_grouplength(&gptr, &groupminlength, FALSE, errcodeptr,\n      lcptr, group, &this_recurse, cb);\n    if (grouplength < 0)\n      {\n      if (*errcodeptr == 0) goto ISNOTFIXED;\n      return -1;  /* Error already set */\n      }\n    itemlength = grouplength;\n    itemminlength = groupminlength;\n    break;\n\n    /* A (DEFINE) group is never obeyed inline and so it does not contribute to\n    the length of this branch. Skip from the following item to the next\n    unpaired ket. */\n\n    case META_COND_DEFINE:\n    pptr = parsed_skip(pptr + 1, PSKIP_KET);\n    break;\n\n    /* Check other nested groups - advance past the initial data for each type\n    and then seek a fixed length with get_grouplength(). */\n\n    case META_COND_NAME:\n    case META_COND_NUMBER:\n    case META_COND_RNAME:\n    case META_COND_RNUMBER:\n    pptr += 2 + SIZEOFFSET;\n    goto CHECK_GROUP;\n\n    case META_COND_ASSERT:\n    pptr += 1;\n    goto CHECK_GROUP;\n\n    case META_COND_VERSION:\n    pptr += 4;\n    goto CHECK_GROUP;\n\n    case META_CAPTURE:\n    group = META_DATA(*pptr);\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case META_ATOMIC:\n    case META_NOCAPTURE:\n    case META_SCRIPT_RUN:\n    pptr++;\n    CHECK_GROUP:\n    grouplength = get_grouplength(&pptr, &groupminlength, TRUE, errcodeptr,\n      lcptr, group, recurses, cb);\n    if (grouplength < 0) return -1;\n    itemlength = grouplength;\n    itemminlength = groupminlength;\n    break;\n\n    case META_QUERY:\n    case META_QUERY_PLUS:\n    case META_QUERY_QUERY:\n    min = 0;\n    max = 1;\n    goto REPETITION;\n\n    /* Exact repetition is OK; variable repetition is not. A repetition of zero\n    must subtract the length that has already been added. */\n\n    case META_MINMAX:\n    case META_MINMAX_PLUS:\n    case META_MINMAX_QUERY:\n    min = pptr[1];\n    max = pptr[2];\n    pptr += 2;\n\n    REPETITION:\n    if (max != REPEAT_UNLIMITED)\n      {\n      if (lastitemlength != 0 &&  /* Should not occur, but just in case */\n          max != 0 &&\n          (INT_MAX - branchlength)/lastitemlength < max - 1)\n        {\n        *errcodeptr = ERR87;  /* Integer overflow; lookbehind too big */\n        return -1;\n        }\n      if (min == 0) branchminlength -= lastitemminlength;\n        else itemminlength = (min - 1) * lastitemminlength;\n      if (max == 0) branchlength -= lastitemlength;\n        else itemlength = (max - 1) * lastitemlength;\n      break;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* Any other item means this branch does not have a fixed length. */\n\n    default:\n    ISNOTFIXED:\n    *errcodeptr = ERR25;   /* Not fixed length */\n    return -1;\n    }\n\n  /* Add the item length to the branchlength, checking for integer overflow and\n  for the branch length exceeding the overall limit. Later, if there is at\n  least one variable-length branch in the group, there is a test for the\n  (smaller) variable-length branch length limit. */\n\n  if (INT_MAX - branchlength < (int)itemlength ||\n      (branchlength += itemlength) > LOOKBEHIND_MAX)\n    {\n    *errcodeptr = ERR87;\n    return -1;\n    }\n\n  branchminlength += itemminlength;\n\n  /* Save this item length for use if the next item is a quantifier. */\n\n  lastitemlength = itemlength;\n  lastitemminlength = itemminlength;\n  }\n\nEXIT:\n*pptrptr = pptr;\n*minptr = branchminlength;\nreturn branchlength;\n\n/* LCOV_EXCL_START */\nPARSED_SKIP_FAILED:\nPCRE2_DEBUG_UNREACHABLE();\n*errcodeptr = ERR90;  /* Unhandled META code - internal error */\nreturn -1;\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*        Set lengths in a lookbehind             *\n*************************************************/\n\n/* This function is called for each lookbehind, to set the lengths in its\nbranches. An error occurs if any branch does not have a limited maximum length\nthat is less than the limit (65535). On exit, the pointer must be left on the\nfinal ket.\n\nThe function also maintains the max_lookbehind value. Any lookbehind branch\nthat contains a nested lookbehind may actually look further back than the\nlength of the branch. The additional amount is passed back from\nget_branchlength() as an \"extra\" value.\n\nArguments:\n  pptrptr     pointer to pointer in the parsed pattern\n  errcodeptr  pointer to error code\n  lcptr       pointer to loop counter\n  recurses    chain of recurse_check to catch mutual recursion\n  cb          pointer to compile block\n\nReturns:      TRUE if all is well\n              FALSE otherwise, with error code and offset set\n*/\n\nstatic BOOL\nset_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr,\n  parsed_recurse_check *recurses, compile_block *cb)\n{\nPCRE2_SIZE offset;\nuint32_t *bptr = *pptrptr;\nuint32_t *gbptr = bptr;\nint maxlength = 0;\nint minlength = INT_MAX;\nBOOL variable = FALSE;\n\nREADPLUSOFFSET(offset, bptr);  /* Offset for error messages */\n*pptrptr += SIZEOFFSET;\n\n/* Each branch can have a different maximum length, but we can keep only a\nsingle minimum for the whole group, because there's nowhere to save individual\nvalues in the META_ALT item. */\n\ndo\n  {\n  int branchlength, branchminlength;\n\n  *pptrptr += 1;\n  branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr,\n    recurses, cb);\n\n  if (branchlength < 0)\n    {\n    /* The errorcode and offset may already be set from a nested lookbehind. */\n    if (*errcodeptr == 0) *errcodeptr = ERR25;\n    if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset;\n    return FALSE;\n    }\n\n  if (branchlength != branchminlength) variable = TRUE;\n  if (branchminlength < minlength) minlength = branchminlength;\n  if (branchlength > maxlength) maxlength = branchlength;\n  if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;\n  *bptr |= branchlength;  /* branchlength never more than 65535 */\n  bptr = *pptrptr;\n  }\nwhile (META_CODE(*bptr) == META_ALT);\n\n/* If any branch is of variable length, the whole lookbehind is of variable\nlength. If the maximum length of any branch exceeds the maximum for variable\nlookbehinds, give an error. Otherwise, the minimum length is set in the word\nthat follows the original group META value. For a fixed-length lookbehind, this\nis set to LOOKBEHIND_MAX, to indicate that each branch is of a fixed (but\npossibly different) length. */\n\nif (variable)\n  {\n  gbptr[1] = minlength;\n  if ((PCRE2_SIZE)maxlength > cb->max_varlookbehind)\n    {\n    *errcodeptr = ERR100;\n    cb->erroroffset = offset;\n    return FALSE;\n    }\n  }\nelse gbptr[1] = LOOKBEHIND_MAX;\n\nreturn TRUE;\n}\n\n\n\n/*************************************************\n*         Check parsed pattern lookbehinds       *\n*************************************************/\n\n/* This function is called at the end of parsing a pattern if any lookbehinds\nwere encountered. It scans the parsed pattern for them, calling\nset_lookbehind_lengths() for each one. At the start, the errorcode is zero and\nthe error offset is marked unset. The enables the functions above not to\noverride settings from deeper nestings.\n\nThis function is called recursively from get_branchlength() for lookaheads in\norder to process any lookbehinds that they may contain. It stops when it hits a\nnon-nested closing parenthesis in this case, returning a pointer to it.\n\nArguments\n  pptr      points to where to start (start of pattern or start of lookahead)\n  retptr    if not NULL, return the ket pointer here\n  recurses  chain of recurse_check to catch mutual recursion\n  cb        points to the compile block\n  lcptr     points to loop counter\n\nReturns:    0 on success, or an errorcode (cb->erroroffset will be set)\n*/\n\nstatic int\ncheck_lookbehinds(uint32_t *pptr, uint32_t **retptr,\n  parsed_recurse_check *recurses, compile_block *cb, int *lcptr)\n{\nint errorcode = 0;\nint nestlevel = 0;\n\ncb->erroroffset = PCRE2_UNSET;\n\nfor (; *pptr != META_END; pptr++)\n  {\n  if (*pptr < META_END) continue;  /* Literal */\n\n  switch (META_CODE(*pptr))\n    {\n    /* The following erroroffset is a bogus but safe value. This branch should\n    be avoided by providing a proper implementation for all supported cases\n    below. */\n\n    /* LCOV_EXCL_START */\n    default:\n    PCRE2_DEBUG_UNREACHABLE();\n    cb->erroroffset = 0;\n    return ERR70;  /* Unrecognized meta code */\n    /* LCOV_EXCL_STOP */\n\n    case META_ESCAPE:\n    if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)\n      pptr += 1;    /* Skip prop data */\n    break;\n\n    case META_KET:\n    if (--nestlevel < 0)\n      {\n      if (retptr != NULL) *retptr = pptr;\n      return 0;\n      }\n    break;\n\n    case META_ATOMIC:\n    case META_CAPTURE:\n    case META_COND_ASSERT:\n    case META_SCS:\n    case META_LOOKAHEAD:\n    case META_LOOKAHEADNOT:\n    case META_LOOKAHEAD_NA:\n    case META_NOCAPTURE:\n    case META_SCRIPT_RUN:\n    nestlevel++;\n    break;\n\n    case META_ACCEPT:\n    case META_ALT:\n    case META_ASTERISK:\n    case META_ASTERISK_PLUS:\n    case META_ASTERISK_QUERY:\n    case META_BACKREF:\n    case META_CIRCUMFLEX:\n    case META_CLASS:\n    case META_CLASS_EMPTY:\n    case META_CLASS_EMPTY_NOT:\n    case META_CLASS_END:\n    case META_CLASS_NOT:\n    case META_COMMIT:\n    case META_DOLLAR:\n    case META_DOT:\n    case META_FAIL:\n    case META_PLUS:\n    case META_PLUS_PLUS:\n    case META_PLUS_QUERY:\n    case META_PRUNE:\n    case META_QUERY:\n    case META_QUERY_PLUS:\n    case META_QUERY_QUERY:\n    case META_RANGE_ESCAPED:\n    case META_RANGE_LITERAL:\n    case META_SKIP:\n    case META_THEN:\n    break;\n\n    case META_OFFSET:\n    case META_RECURSE:\n    pptr += SIZEOFFSET;\n    break;\n\n    case META_BACKREF_BYNAME:\n    case META_RECURSE_BYNAME:\n    pptr += 1 + SIZEOFFSET;\n    break;\n\n    case META_COND_DEFINE:\n    pptr += SIZEOFFSET;\n    nestlevel++;\n    break;\n\n    case META_COND_NAME:\n    case META_COND_NUMBER:\n    case META_COND_RNAME:\n    case META_COND_RNUMBER:\n    pptr += 1 + SIZEOFFSET;\n    nestlevel++;\n    break;\n\n    case META_COND_VERSION:\n    pptr += 3;\n    nestlevel++;\n    break;\n\n    case META_CALLOUT_STRING:\n    pptr += 3 + SIZEOFFSET;\n    break;\n\n    case META_BIGVALUE:\n    case META_POSIX:\n    case META_POSIX_NEG:\n    case META_CAPTURE_NAME:\n    case META_CAPTURE_NUMBER:\n    pptr += 1;\n    break;\n\n    case META_MINMAX:\n    case META_MINMAX_QUERY:\n    case META_MINMAX_PLUS:\n    case META_OPTIONS:\n    pptr += 2;\n    break;\n\n    case META_CALLOUT_NUMBER:\n    pptr += 3;\n    break;\n\n    case META_MARK:\n    case META_COMMIT_ARG:\n    case META_PRUNE_ARG:\n    case META_SKIP_ARG:\n    case META_THEN_ARG:\n    pptr += 1 + pptr[1];\n    break;\n\n    /* Note that set_lookbehind_lengths() updates pptr, leaving it pointing to\n    the final ket of the group, so no need to update it here. */\n\n    case META_LOOKBEHIND:\n    case META_LOOKBEHINDNOT:\n    case META_LOOKBEHIND_NA:\n    if (!set_lookbehind_lengths(&pptr, &errorcode, lcptr, recurses, cb))\n      return errorcode;\n    break;\n    }\n  }\n\nreturn 0;\n}\n\n\n\n/*************************************************\n*     External function to compile a pattern     *\n*************************************************/\n\n/* This function reads a regular expression in the form of a string and returns\na pointer to a block of store holding a compiled version of the expression.\n\nArguments:\n  pattern       the regular expression\n  patlen        the length of the pattern, or PCRE2_ZERO_TERMINATED\n  options       option bits\n  errorptr      pointer to errorcode\n  erroroffset   pointer to error offset\n  ccontext      points to a compile context or is NULL\n\nReturns:        pointer to compiled data block, or NULL on error,\n                with errorcode and erroroffset set\n*/\n\nPCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION\npcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,\n   int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)\n{\nBOOL utf;                             /* Set TRUE for UTF mode */\nBOOL ucp;                             /* Set TRUE for UCP mode */\nBOOL has_lookbehind = FALSE;          /* Set TRUE if a lookbehind is found */\nBOOL zero_terminated;                 /* Set TRUE for zero-terminated pattern */\npcre2_real_code *re = NULL;           /* What we will return */\ncompile_block cb;                     /* \"Static\" compile-time data */\nconst uint8_t *tables;                /* Char tables base pointer */\n\nPCRE2_UCHAR null_str[1] = { 0xcd };   /* Dummy for handling null inputs */\nPCRE2_UCHAR *code;                    /* Current pointer in compiled code */\nPCRE2_UCHAR *codestart;               /* Start of compiled code */\nPCRE2_SPTR ptr;                       /* Current pointer in pattern */\nuint32_t *pptr;                       /* Current pointer in parsed pattern */\n\nPCRE2_SIZE length = 1;                /* Allow for final END opcode */\nPCRE2_SIZE usedlength;                /* Actual length used */\nPCRE2_SIZE re_blocksize;              /* Size of memory block */\nPCRE2_SIZE parsed_size_needed;        /* Needed for parsed pattern */\n\nuint32_t firstcuflags, reqcuflags;    /* Type of first/req code unit */\nuint32_t firstcu, reqcu;              /* Value of first/req code unit */\nuint32_t setflags = 0;                /* NL and BSR set flags */\nuint32_t xoptions;                    /* Flags from context, modified */\n\nuint32_t skipatstart;                 /* When checking (*UTF) etc */\nuint32_t limit_heap  = UINT32_MAX;\nuint32_t limit_match = UINT32_MAX;    /* Unset match limits */\nuint32_t limit_depth = UINT32_MAX;\n\nint newline = 0;                      /* Unset; can be set by the pattern */\nint bsr = 0;                          /* Unset; can be set by the pattern */\nint errorcode = 0;                    /* Initialize to avoid compiler warn */\nint regexrc;                          /* Return from compile */\n\nuint32_t i;                           /* Local loop counter */\n\n/* Enable all optimizations by default. */\nuint32_t optim_flags = ccontext != NULL ? ccontext->optimization_flags :\n                                          PCRE2_OPTIMIZATION_ALL;\n\n/* Comments at the head of this file explain about these variables. */\n\nuint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE];\nuint32_t stack_parsed_pattern[PARSED_PATTERN_DEFAULT_SIZE];\nnamed_group named_groups[NAMED_GROUP_LIST_SIZE];\n\n/* The workspace is used in different ways in the different compiling phases.\nIt needs to be 16-bit aligned for the preliminary parsing scan. */\n\nuint32_t c16workspace[C16_WORK_SIZE];\nPCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;\n\n\n/* -------------- Check arguments and set up the pattern ----------------- */\n\n/* There must be error code and offset pointers. */\n\nif (errorptr == NULL)\n  {\n  if (erroroffset != NULL) *erroroffset = 0;\n  return NULL;\n  }\nif (erroroffset == NULL)\n  {\n  if (errorptr != NULL) *errorptr = ERR120;\n  return NULL;\n  }\n*errorptr = ERR0;\n*erroroffset = 0;\n\n/* There must be a pattern, but NULL is allowed with zero length. */\n\nif (pattern == NULL)\n  {\n  if (patlen == 0)\n    pattern = null_str;\n  else\n    {\n    *errorptr = ERR16;\n    return NULL;\n    }\n  }\n\n/* A NULL compile context means \"use a default context\" */\n\nif (ccontext == NULL)\n  ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));\n\n/* PCRE2_MATCH_INVALID_UTF implies UTF */\n\nif ((options & PCRE2_MATCH_INVALID_UTF) != 0) options |= PCRE2_UTF;\n\n/* Check that all undefined public option bits are zero. */\n\nif ((options & ~PUBLIC_COMPILE_OPTIONS) != 0 ||\n    (ccontext->extra_options & ~PUBLIC_COMPILE_EXTRA_OPTIONS) != 0)\n  {\n  *errorptr = ERR17;\n  return NULL;\n  }\n\nif ((options & PCRE2_LITERAL) != 0 &&\n    ((options & ~PUBLIC_LITERAL_COMPILE_OPTIONS) != 0 ||\n     (ccontext->extra_options & ~PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS) != 0))\n  {\n  *errorptr = ERR92;\n  return NULL;\n  }\n\n/* A zero-terminated pattern is indicated by the special length value\nPCRE2_ZERO_TERMINATED. Check for an overlong pattern. */\n\nif ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED)))\n  patlen = PRIV(strlen)(pattern);\n(void)zero_terminated; /* Silence compiler; only used if Valgrind enabled */\n\nif (patlen > ccontext->max_pattern_length)\n  {\n  *errorptr = ERR88;\n  return NULL;\n  }\n\n/* Optimization flags in 'options' can override those in the compile context.\nThis is because some options to disable optimizations were added before the\noptimization flags word existed, and we need to continue supporting them\nfor backwards compatibility. */\n\nif ((options & PCRE2_NO_AUTO_POSSESS) != 0)\n  optim_flags &= ~PCRE2_OPTIM_AUTO_POSSESS;\nif ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)\n  optim_flags &= ~PCRE2_OPTIM_DOTSTAR_ANCHOR;\nif ((options & PCRE2_NO_START_OPTIMIZE) != 0)\n  optim_flags &= ~PCRE2_OPTIM_START_OPTIMIZE;\n\n/* From here on, all returns from this function should end up going via the\nEXIT label. */\n\n\n/* ------------ Initialize the \"static\" compile data -------------- */\n\ntables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables);\n\ncb.lcc = tables + lcc_offset;          /* Individual */\ncb.fcc = tables + fcc_offset;          /*   character */\ncb.cbits = tables + cbits_offset;      /*      tables */\ncb.ctypes = tables + ctypes_offset;\n\ncb.assert_depth = 0;\ncb.bracount = 0;\ncb.cx = ccontext;\ncb.dupnames = FALSE;\ncb.end_pattern = pattern + patlen;\ncb.erroroffset = 0;\ncb.external_flags = 0;\ncb.external_options = options;\ncb.groupinfo = stack_groupinfo;\ncb.had_recurse = FALSE;\ncb.lastcapture = 0;\ncb.max_lookbehind = 0;                               /* Max encountered */\ncb.max_varlookbehind = ccontext->max_varlookbehind;  /* Limit */\ncb.name_entry_size = 0;\ncb.name_table = NULL;\ncb.named_groups = named_groups;\ncb.named_group_list_size = NAMED_GROUP_LIST_SIZE;\ncb.names_found = 0;\ncb.parens_depth = 0;\ncb.parsed_pattern = stack_parsed_pattern;\ncb.req_varyopt = 0;\ncb.start_code = cworkspace;\ncb.start_pattern = pattern;\ncb.start_workspace = cworkspace;\ncb.workspace_size = COMPILE_WORK_SIZE;\ncb.first_data = NULL;\ncb.last_data = NULL;\n#ifdef SUPPORT_WIDE_CHARS\ncb.char_lists_size = 0;\n#endif\n\n/* Maximum back reference and backref bitmap. The bitmap records up to 31 back\nreferences to help in deciding whether (.*) can be treated as anchored or not.\n*/\n\ncb.top_backref = 0;\ncb.backref_map = 0;\n\n/* Escape sequences \\1 to \\9 are always back references, but as they are only\ntwo characters long, only two elements can be used in the parsed_pattern\nvector. The first contains the reference, and we'd like to use the second to\nrecord the offset in the pattern, so that forward references to non-existent\ngroups can be diagnosed later with an offset. However, on 64-bit systems,\nPCRE2_SIZE won't fit. Instead, we have a vector of offsets for the first\noccurrence of \\1 to \\9, indexed by the second parsed_pattern value. All other\nreferences have enough space for the offset to be put into the parsed pattern.\n*/\n\nfor (i = 0; i < 10; i++) cb.small_ref_offset[i] = PCRE2_UNSET;\n\n\n/* --------------- Start looking at the pattern --------------- */\n\n/* Unless PCRE2_LITERAL is set, check for global one-time option settings at\nthe start of the pattern, and remember the offset to the actual regex. With\nvalgrind support, make the terminator of a zero-terminated pattern\ninaccessible. This catches bugs that would otherwise only show up for\nnon-zero-terminated patterns. */\n\n#ifdef SUPPORT_VALGRIND\nif (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1));\n#endif\n\nxoptions = ccontext->extra_options;\nptr = pattern;\nskipatstart = 0;\n\nif ((options & PCRE2_LITERAL) == 0)\n  {\n  while (patlen - skipatstart >= 2 &&\n         ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&\n         ptr[skipatstart+1] == CHAR_ASTERISK)\n    {\n    for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)\n      {\n      const pso *p = pso_list + i;\n\n      if (patlen - skipatstart - 2 >= p->length &&\n          PRIV(strncmp_c8)(ptr + skipatstart + 2, p->name, p->length) == 0)\n        {\n        uint32_t c, pp;\n\n        skipatstart += p->length + 2;\n        switch(p->type)\n          {\n          case PSO_OPT:\n          cb.external_options |= p->value;\n          break;\n\n          case PSO_XOPT:\n          xoptions |= p->value;\n          break;\n\n          case PSO_FLG:\n          setflags |= p->value;\n          break;\n\n          case PSO_NL:\n          newline = p->value;\n          setflags |= PCRE2_NL_SET;\n          break;\n\n          case PSO_BSR:\n          bsr = p->value;\n          setflags |= PCRE2_BSR_SET;\n          break;\n\n          case PSO_LIMM:\n          case PSO_LIMD:\n          case PSO_LIMH:\n          c = 0;\n          pp = skipatstart;\n          while (pp < patlen && IS_DIGIT(ptr[pp]))\n            {\n            if (c > UINT32_MAX / 10 - 1) break;   /* Integer overflow */\n            c = c*10 + (ptr[pp++] - CHAR_0);\n            }\n          if (pp >= patlen || pp == skipatstart || ptr[pp] != CHAR_RIGHT_PARENTHESIS)\n            {\n            errorcode = ERR60;\n            ptr += pp;\n            utf = FALSE;  /* Used by HAD_EARLY_ERROR */\n            goto HAD_EARLY_ERROR;\n            }\n          if (p->type == PSO_LIMH) limit_heap = c;\n            else if (p->type == PSO_LIMM) limit_match = c;\n            else limit_depth = c;\n          skipatstart = ++pp;\n          break;\n\n          case PSO_OPTMZ:\n          optim_flags &= ~(p->value);\n\n          /* For backward compatibility the three original VERBs to disable\n          optimizations need to also update the corresponding bit in the\n          external options. */\n\n          switch(p->value)\n            {\n            case PCRE2_OPTIM_AUTO_POSSESS:\n            cb.external_options |= PCRE2_NO_AUTO_POSSESS;\n            break;\n\n            case PCRE2_OPTIM_DOTSTAR_ANCHOR:\n            cb.external_options |= PCRE2_NO_DOTSTAR_ANCHOR;\n            break;\n\n            case PCRE2_OPTIM_START_OPTIMIZE:\n            cb.external_options |= PCRE2_NO_START_OPTIMIZE;\n            break;\n            }\n\n          break;\n\n          /* LCOV_EXCL_START */\n          default:\n          /* All values in the enum need an explicit entry for this switch\n          but until a better way to prevent coding mistakes is invented keep\n          a catch all that triggers a debug build assert as a failsafe */\n          PCRE2_DEBUG_UNREACHABLE();\n          /* LCOV_EXCL_STOP */\n          }\n        break;   /* Out of the table scan loop */\n        }\n      }\n    if (i >= sizeof(pso_list)/sizeof(pso)) break;   /* Out of pso loop */\n    }\n    PCRE2_ASSERT(skipatstart <= patlen);\n  }\n\n/* End of pattern-start options; advance to start of real regex. */\n\nptr += skipatstart;\n\n/* Can't support UTF or UCP if PCRE2 was built without Unicode support. */\n\n#ifndef SUPPORT_UNICODE\nif ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)\n  {\n  errorcode = ERR32;\n  goto HAD_EARLY_ERROR;\n  }\n#endif\n\n/* Check UTF. We have the original options in 'options', with that value as\nmodified by (*UTF) etc in cb->external_options. The extra option\nPCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not permitted in UTF-16 mode because the\nsurrogate code points cannot be represented in UTF-16. */\n\nutf = (cb.external_options & PCRE2_UTF) != 0;\nif (utf)\n  {\n  if ((options & PCRE2_NEVER_UTF) != 0)\n    {\n    errorcode = ERR74;\n    goto HAD_EARLY_ERROR;\n    }\n  if ((options & PCRE2_NO_UTF_CHECK) == 0 &&\n       (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0)\n    goto HAD_ERROR;  /* Offset was set by valid_utf() */\n\n#if PCRE2_CODE_UNIT_WIDTH == 16\n  if ((ccontext->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) != 0)\n    {\n    errorcode = ERR91;\n    goto HAD_EARLY_ERROR;\n    }\n#endif\n  }\n\n/* Check UCP lockout. */\n\nucp = (cb.external_options & PCRE2_UCP) != 0;\nif (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0)\n  {\n  errorcode = ERR75;\n  goto HAD_EARLY_ERROR;\n  }\n\n/* PCRE2_EXTRA_TURKISH_CASING checks */\n\nif ((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)\n  {\n  if (!utf && !ucp)\n    {\n    errorcode = ERR104;\n    goto HAD_EARLY_ERROR;\n    }\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  if (!utf)\n    {\n    errorcode = ERR105;\n    goto HAD_EARLY_ERROR;\n    }\n#endif\n\n  if ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)\n    {\n    errorcode = ERR106;\n    goto HAD_EARLY_ERROR;\n    }\n  }\n\n/* Process the BSR setting. */\n\nif (bsr == 0) bsr = ccontext->bsr_convention;\n\n/* Process the newline setting. */\n\nif (newline == 0) newline = ccontext->newline_convention;\ncb.nltype = NLTYPE_FIXED;\nswitch(newline)\n  {\n  case PCRE2_NEWLINE_CR:\n  cb.nllen = 1;\n  cb.nl[0] = CHAR_CR;\n  break;\n\n  case PCRE2_NEWLINE_LF:\n  cb.nllen = 1;\n  cb.nl[0] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_NUL:\n  cb.nllen = 1;\n  cb.nl[0] = CHAR_NUL;\n  break;\n\n  case PCRE2_NEWLINE_CRLF:\n  cb.nllen = 2;\n  cb.nl[0] = CHAR_CR;\n  cb.nl[1] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_ANY:\n  cb.nltype = NLTYPE_ANY;\n  break;\n\n  case PCRE2_NEWLINE_ANYCRLF:\n  cb.nltype = NLTYPE_ANYCRLF;\n  break;\n\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  errorcode = ERR56;\n  goto HAD_EARLY_ERROR;\n  /* LCOV_EXCL_STOP */\n  }\n\n/* Pre-scan the pattern to do two things: (1) Discover the named groups and\ntheir numerical equivalents, so that this information is always available for\nthe remaining processing. (2) At the same time, parse the pattern and put a\nprocessed version into the parsed_pattern vector. This has escapes interpreted\nand comments removed (amongst other things). */\n\n/* Ensure that the parsed pattern buffer is big enough. For many smaller\npatterns the vector on the stack (which was set up above) can be used. */\n\nparsed_size_needed = max_parsed_pattern(ptr, cb.end_pattern, utf, options);\n\n/* Allow for 2x uint32_t at the start and 2 at the end, for\nPCRE2_EXTRA_MATCH_WORD or PCRE2_EXTRA_MATCH_LINE (which are exclusive). */\n\nif ((ccontext->extra_options &\n     (PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_MATCH_LINE)) != 0)\n  parsed_size_needed += 4;\n\n/* When PCRE2_AUTO_CALLOUT is set we allow for one callout at the end. */\n\nif ((options & PCRE2_AUTO_CALLOUT) != 0)\n  parsed_size_needed += 4;\n\nparsed_size_needed += 1;  /* For the final META_END */\n\nif (parsed_size_needed > PARSED_PATTERN_DEFAULT_SIZE)\n  {\n  uint32_t *heap_parsed_pattern = ccontext->memctl.malloc(\n    parsed_size_needed * sizeof(uint32_t), ccontext->memctl.memory_data);\n  if (heap_parsed_pattern == NULL)\n    {\n    *errorptr = ERR21;\n    goto EXIT;\n    }\n  cb.parsed_pattern = heap_parsed_pattern;\n  }\ncb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed;\n\n/* Do the parsing scan. */\n\nerrorcode = parse_regex(ptr, cb.external_options, xoptions, &has_lookbehind, &cb);\nif (errorcode != 0) goto HAD_CB_ERROR;\n\n/* If there are any lookbehinds, scan the parsed pattern to figure out their\nlengths. Workspace is needed to remember whether numbered groups are or are not\nof limited length, and if limited, what the minimum and maximum lengths are.\nThis caching saves re-computing the length of any group that is referenced more\nthan once, which is particularly relevant when recursion is involved.\nUnnumbered groups do not have this exposure because they cannot be referenced.\nIf there are sufficiently few groups, the default index vector on the stack, as\nset up above, can be used. Otherwise we have to get/free some heap memory. The\nvector must be initialized to zero. */\n\nif (has_lookbehind)\n  {\n  int loopcount = 0;\n  if (cb.bracount >= GROUPINFO_DEFAULT_SIZE/2)\n    {\n    cb.groupinfo = ccontext->memctl.malloc(\n      (2 * (cb.bracount + 1))*sizeof(uint32_t), ccontext->memctl.memory_data);\n    if (cb.groupinfo == NULL)\n      {\n      errorcode = ERR21;\n      cb.erroroffset = 0;\n      goto HAD_CB_ERROR;\n      }\n    }\n  memset(cb.groupinfo, 0, (2 * cb.bracount + 1) * sizeof(uint32_t));\n  errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb, &loopcount);\n  if (errorcode != 0) goto HAD_CB_ERROR;\n  }\n\n/* For debugging, there is a function that shows the parsed pattern vector. */\n\n#ifdef DEBUG_SHOW_PARSED\nfprintf(stderr, \"+++ Pre-scan complete:\\n\");\nshow_parsed(&cb);\n#endif\n\n/* For debugging capturing information this code can be enabled. */\n\n#ifdef DEBUG_SHOW_CAPTURES\n  {\n  named_group *ng = cb.named_groups;\n  fprintf(stderr, \"+++Captures: %d\\n\", cb.bracount);\n  for (i = 0; i < cb.names_found; i++, ng++)\n    {\n    fprintf(stderr, \"+++%3d %.*s\\n\", ng->number, ng->length, ng->name);\n    }\n  }\n#endif\n\n/* Pretend to compile the pattern while actually just accumulating the amount\nof memory required in the 'length' variable. This behaviour is triggered by\npassing a non-NULL final argument to compile_regex(). We pass a block of\nworkspace (cworkspace) for it to compile parts of the pattern into; the\ncompiled code is discarded when it is no longer needed, so hopefully this\nworkspace will never overflow, though there is a test for its doing so.\n\nOn error, errorcode will be set non-zero, so we don't need to look at the\nresult of the function. The initial options have been put into the cb block,\nbut we still have to pass a separate options variable (the first argument)\nbecause the options may change as the pattern is processed. */\n\ncb.erroroffset = patlen;   /* For any subsequent errors that do not set it */\npptr = cb.parsed_pattern;\ncode = cworkspace;\n*code = OP_BRA;\n\n(void)compile_regex(cb.external_options, xoptions, &code, &pptr,\n   &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL,\n   &cb, &length);\n\nif (errorcode != 0) goto HAD_CB_ERROR;  /* Offset is in cb.erroroffset */\n\n/* This should be caught in compile_regex(), but just in case... */\n\n#if defined SUPPORT_WIDE_CHARS\nPCRE2_ASSERT((cb.char_lists_size & 0x3) == 0);\nif (length > MAX_PATTERN_SIZE ||\n    MAX_PATTERN_SIZE - length < (cb.char_lists_size / sizeof(PCRE2_UCHAR)))\n#else\nif (length > MAX_PATTERN_SIZE)\n#endif\n  {\n  errorcode = ERR20;\n  cb.erroroffset = 0;\n  goto HAD_CB_ERROR;\n  }\n\n/* Compute the size of, then, if not too large, get and initialize the data\nblock for storing the compiled pattern and names table. Integer overflow should\nno longer be possible because nowadays we limit the maximum value of\ncb.names_found and cb.name_entry_size. */\n\nre_blocksize =\n  CU2BYTES((PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);\n\n#if defined SUPPORT_WIDE_CHARS\nif (cb.char_lists_size != 0)\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 32\n  /* Align to 32 bit first. This ensures the\n  allocated area will also be 32 bit aligned. */\n  re_blocksize = (PCRE2_SIZE)CLIST_ALIGN_TO(re_blocksize, sizeof(uint32_t));\n#endif\n  re_blocksize += cb.char_lists_size;\n  }\n#endif\n\nre_blocksize += CU2BYTES(length);\n\nif (re_blocksize > ccontext->max_pattern_compiled_length)\n  {\n  errorcode = ERR101;\n  cb.erroroffset = 0;\n  goto HAD_CB_ERROR;\n  }\n\nre_blocksize += sizeof(pcre2_real_code);\nre = (pcre2_real_code *)\n  ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);\nif (re == NULL)\n  {\n  errorcode = ERR21;\n  cb.erroroffset = 0;\n  goto HAD_CB_ERROR;\n  }\n\n/* The compiler may put padding at the end of the pcre2_real_code structure in\norder to round it up to a multiple of 4 or 8 bytes. This means that when a\ncompiled pattern is copied (for example, when serialized) undefined bytes are\nread, and this annoys debuggers such as valgrind. To avoid this, we explicitly\nwrite to the last 8 bytes of the structure before setting the fields. */\n\nmemset((char *)re + sizeof(pcre2_real_code) - 8, 0, 8);\nre->memctl = ccontext->memctl;\nre->tables = tables;\nre->executable_jit = NULL;\nmemset(re->start_bitmap, 0, 32 * sizeof(uint8_t));\nre->blocksize = re_blocksize;\nre->code_start = re_blocksize - CU2BYTES(length);\nre->magic_number = MAGIC_NUMBER;\nre->compile_options = options;\nre->overall_options = cb.external_options;\nre->extra_options = xoptions;\nre->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags;\nre->limit_heap = limit_heap;\nre->limit_match = limit_match;\nre->limit_depth = limit_depth;\nre->first_codeunit = 0;\nre->last_codeunit = 0;\nre->bsr_convention = bsr;\nre->newline_convention = newline;\nre->max_lookbehind = 0;\nre->minlength = 0;\nre->top_bracket = 0;\nre->top_backref = 0;\nre->name_entry_size = cb.name_entry_size;\nre->name_count = cb.names_found;\nre->optimization_flags = optim_flags;\n\n/* The basic block is immediately followed by the name table, and the compiled\ncode follows after that. */\n\ncodestart = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start);\n\n/* Update the compile data block for the actual compile. The starting points of\nthe name/number translation table and of the code are passed around in the\ncompile data block. The start/end pattern and initial options are already set\nfrom the pre-compile phase, as is the name_entry_size field. */\n\ncb.parens_depth = 0;\ncb.assert_depth = 0;\ncb.lastcapture = 0;\ncb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));\ncb.start_code = codestart;\ncb.req_varyopt = 0;\ncb.had_accept = FALSE;\ncb.had_pruneorskip = FALSE;\n#ifdef SUPPORT_WIDE_CHARS\ncb.char_lists_size = 0;\n#endif\n\n\n/* If any named groups were found, create the name/number table from the list\ncreated in the pre-pass. */\n\nif (cb.names_found > 0)\n  {\n  named_group *ng = cb.named_groups;\n  uint32_t tablecount = 0;\n\n  /* Length 0 represents duplicates, and they have already been handled. */\n  for (i = 0; i < cb.names_found; i++, ng++)\n    if (ng->length > 0)\n      tablecount = PRIV(compile_add_name_to_table)(&cb, ng, tablecount);\n\n  PCRE2_ASSERT(tablecount == cb.names_found);\n  }\n\n/* Set up a starting, non-extracting bracket, then compile the expression. On\nerror, errorcode will be set non-zero, so we don't need to look at the result\nof the function here. */\n\npptr = cb.parsed_pattern;\ncode = (PCRE2_UCHAR *)codestart;\n*code = OP_BRA;\nregexrc = compile_regex(re->overall_options, re->extra_options, &code,\n  &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL,\n  NULL, &cb, NULL);\nif (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY;\nre->top_bracket = cb.bracount;\nre->top_backref = cb.top_backref;\nre->max_lookbehind = cb.max_lookbehind;\n\nif (cb.had_accept)\n  {\n  reqcu = 0;                     /* Must disable after (*ACCEPT) */\n  reqcuflags = REQ_NONE;\n  re->flags |= PCRE2_HASACCEPT;  /* Disables minimum length */\n  }\n\n/* Fill in the final opcode and check for disastrous overflow. If no overflow,\nbut the estimated length exceeds the really used length, adjust the value of\nre->blocksize, and if valgrind support is configured, mark the extra allocated\nmemory as unaddressable, so that any out-of-bound reads can be detected. */\n\n*code++ = OP_END;\nusedlength = code - codestart;\n/* LCOV_EXCL_START */\nif (usedlength > length)\n  {\n  PCRE2_DEBUG_UNREACHABLE();\n  errorcode = ERR23;  /* Overflow of code block - internal error */\n  cb.erroroffset = 0;\n  goto HAD_CB_ERROR;\n  }\n/* LCOV_EXCL_STOP */\n\nre->blocksize -= CU2BYTES(length - usedlength);\n#ifdef SUPPORT_VALGRIND\nVALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));\n#endif\n\n/* Scan the pattern for recursion/subroutine calls and convert the group\nnumbers into offsets. Maintain a small cache so that repeated groups containing\nrecursions are efficiently handled. */\n\n#define RSCAN_CACHE_SIZE 8\n\nif (errorcode == 0 && cb.had_recurse)\n  {\n  PCRE2_UCHAR *rcode;\n  PCRE2_SPTR rgroup;\n  unsigned int ccount = 0;\n  int start = RSCAN_CACHE_SIZE;\n  recurse_cache rc[RSCAN_CACHE_SIZE];\n\n  for (rcode = find_recurse(codestart, utf);\n       rcode != NULL;\n       rcode = find_recurse(rcode + 1 + LINK_SIZE, utf))\n    {\n    int p, groupnumber;\n\n    groupnumber = (int)GET(rcode, 1);\n    if (groupnumber == 0) rgroup = codestart; else\n      {\n      PCRE2_SPTR search_from = codestart;\n      rgroup = NULL;\n      for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7)\n        {\n        if (groupnumber == rc[p].groupnumber)\n          {\n          rgroup = rc[p].group;\n          break;\n          }\n\n        /* Group n+1 must always start to the right of group n, so we can save\n        search time below when the new group number is greater than any of the\n        previously found groups. */\n\n        if (groupnumber > rc[p].groupnumber) search_from = rc[p].group;\n        }\n\n      if (rgroup == NULL)\n        {\n        rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);\n        /* LCOV_EXCL_START */\n        if (rgroup == NULL)\n          {\n          PCRE2_DEBUG_UNREACHABLE();\n          errorcode = ERR53;\n          break;\n          }\n        /* LCOV_EXCL_STOP */\n\n        if (--start < 0) start = RSCAN_CACHE_SIZE - 1;\n        rc[start].groupnumber = groupnumber;\n        rc[start].group = rgroup;\n        if (ccount < RSCAN_CACHE_SIZE) ccount++;\n        }\n      }\n\n    PUT(rcode, 1, (uint32_t)(rgroup - codestart));\n    }\n  }\n\n/* In rare debugging situations we sometimes need to look at the compiled code\nat this stage. */\n\n#ifdef DEBUG_CALL_PRINTINT\npcre2_printint(re, stderr, TRUE);\nfprintf(stderr, \"Length=%lu Used=%lu\\n\", length, usedlength);\n#endif\n\n/* Unless disabled, check whether any single character iterators can be\nauto-possessified. The function overwrites the appropriate opcode values, so\nthe type of the pointer must be cast. NOTE: the intermediate variable \"temp\" is\nused in this code because at least one compiler gives a warning about loss of\n\"const\" attribute if the cast (PCRE2_UCHAR *)codestart is used directly in the\nfunction call. */\n\nif (errorcode == 0 && (optim_flags & PCRE2_OPTIM_AUTO_POSSESS) != 0)\n  {\n  PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;\n  int possessify_rc = PRIV(auto_possessify)(temp, &cb);\n  /* LCOV_EXCL_START */\n  if (possessify_rc != 0)\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    errorcode = ERR80;\n    cb.erroroffset = 0;\n    }\n  /* LCOV_EXCL_STOP */\n  }\n\n/* Failed to compile, or error while post-processing. */\n\nif (errorcode != 0) goto HAD_CB_ERROR;\n\n/* Successful compile. If the anchored option was not passed, set it if\nwe can determine that the pattern is anchored by virtue of ^ characters or \\A\nor anything else, such as starting with non-atomic .* when DOTALL is set and\nthere are no occurrences of *PRUNE or *SKIP (though there is an option to\ndisable this case). */\n\nif ((re->overall_options & PCRE2_ANCHORED) == 0)\n  {\n  BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0);\n  if (is_anchored(codestart, 0, &cb, 0, FALSE, dotstar_anchor))\n    re->overall_options |= PCRE2_ANCHORED;\n  }\n\n/* Set up the first code unit or startline flag, the required code unit, and\nthen study the pattern. This code need not be obeyed if PCRE2_OPTIM_START_OPTIMIZE\nis disabled, as the data it would create will not be used. Note that a first code\nunit (but not the startline flag) is useful for anchored patterns because it\ncan still give a quick \"no match\" and also avoid searching for a last code\nunit. */\n\nif ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n  {\n  int minminlength = 0;  /* For minimal minlength from first/required CU */\n  int study_rc;\n\n  /* If we do not have a first code unit, see if there is one that is asserted\n  (these are not saved during the compile because they can cause conflicts with\n  actual literals that follow). */\n\n  if (firstcuflags >= REQ_NONE) {\n    uint32_t assertedcuflags = 0;\n    uint32_t assertedcu = find_firstassertedcu(codestart, &assertedcuflags, 0);\n    /* It would be wrong to use the asserted first code unit as `firstcu` for\n     * regexes which are able to match a 1-character string (e.g. /(?=a)b?a/)\n     * For that example, if we set both firstcu and reqcu to 'a', it would mean\n     * the subject string needs to be at least 2 characters long, which is wrong.\n     * With more analysis, we would be able to set firstcu in more cases. */\n    if (assertedcuflags < REQ_NONE && assertedcu != reqcu) {\n      firstcu = assertedcu;\n      firstcuflags = assertedcuflags;\n    }\n  }\n\n  /* Save the data for a first code unit. The existence of one means the\n  minimum length must be at least 1. */\n\n  if (firstcuflags < REQ_NONE)\n    {\n    re->first_codeunit = firstcu;\n    re->flags |= PCRE2_FIRSTSET;\n    minminlength++;\n\n    /* Handle caseless first code units. */\n\n    if ((firstcuflags & REQ_CASELESS) != 0)\n      {\n      if (firstcu < 128 || (!utf && !ucp && firstcu < 255))\n        {\n        if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;\n        }\n\n      /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise.\n      In 8-bit UTF mode, code units in the range 128-255 are introductory code\n      units and cannot have another case, but if UCP is set they may do. */\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu)\n        re->flags |= PCRE2_FIRSTCASELESS;\n#else\n      else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT &&\n               UCD_OTHERCASE(firstcu) != firstcu)\n        re->flags |= PCRE2_FIRSTCASELESS;\n#endif\n#endif  /* SUPPORT_UNICODE */\n      }\n    }\n\n  /* When there is no first code unit, for non-anchored patterns, see if we can\n  set the PCRE2_STARTLINE flag. This is helpful for multiline matches when all\n  branches start with ^ and also when all branches start with non-atomic .* for\n  non-DOTALL matches when *PRUNE and SKIP are not present. (There is an option\n  that disables this case.) */\n\n  else if ((re->overall_options & PCRE2_ANCHORED) == 0)\n    {\n    BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0);\n    if (is_startline(codestart, 0, &cb, 0, FALSE, dotstar_anchor))\n      re->flags |= PCRE2_STARTLINE;\n    }\n\n  /* Handle the \"required code unit\", if one is set. In the UTF case we can\n  increment the minimum minimum length only if we are sure this really is a\n  different character and not a non-starting code unit of the first character,\n  because the minimum length count is in characters, not code units. */\n\n  if (reqcuflags < REQ_NONE)\n    {\n#if PCRE2_CODE_UNIT_WIDTH == 16\n    if ((re->overall_options & PCRE2_UTF) == 0 ||   /* Not UTF */\n        firstcuflags >= REQ_NONE ||                 /* First not set */\n        (firstcu & 0xf800) != 0xd800 ||             /* First not surrogate */\n        (reqcu & 0xfc00) != 0xdc00)                 /* Req not low surrogate */\n#elif PCRE2_CODE_UNIT_WIDTH == 8\n    if ((re->overall_options & PCRE2_UTF) == 0 ||   /* Not UTF */\n        firstcuflags >= REQ_NONE ||                 /* First not set */\n        (firstcu & 0x80) == 0 ||                    /* First is ASCII */\n        (reqcu & 0x80) == 0)                        /* Req is ASCII */\n#endif\n      {\n      minminlength++;\n      }\n\n    /* In the case of an anchored pattern, set up the value only if it follows\n    a variable length item in the pattern. */\n\n    if ((re->overall_options & PCRE2_ANCHORED) == 0 ||\n        (reqcuflags & REQ_VARY) != 0)\n      {\n      re->last_codeunit = reqcu;\n      re->flags |= PCRE2_LASTSET;\n\n      /* Handle caseless required code units as for first code units (above). */\n\n      if ((reqcuflags & REQ_CASELESS) != 0)\n        {\n        if (reqcu < 128 || (!utf && !ucp && reqcu < 255))\n          {\n          if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;\n          }\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu)\n        re->flags |= PCRE2_LASTCASELESS;\n#else\n      else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT &&\n               UCD_OTHERCASE(reqcu) != reqcu)\n        re->flags |= PCRE2_LASTCASELESS;\n#endif\n#endif  /* SUPPORT_UNICODE */\n        }\n      }\n    }\n\n  /* Study the compiled pattern to set up information such as a bitmap of\n  starting code units and a minimum matching length. */\n\n  study_rc = PRIV(study)(re);\n  /* LCOV_EXCL_START */\n  if (study_rc != 0)\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    errorcode = ERR31;\n    cb.erroroffset = 0;\n    goto HAD_CB_ERROR;\n    }\n  /* LCOV_EXCL_STOP */\n\n  /* If study() set a bitmap of starting code units, it implies a minimum\n  length of at least one. */\n\n  if ((re->flags & PCRE2_FIRSTMAPSET) != 0 && minminlength == 0)\n    minminlength = 1;\n\n  /* If the minimum length set (or not set) by study() is less than the minimum\n  implied by required code units, override it. */\n\n  if (re->minlength < minminlength) re->minlength = minminlength;\n  }   /* End of start-of-match optimizations. */\n\n/* Control ends up here in all cases. When running under valgrind, make a\npattern's terminating zero defined again. If memory was obtained for the parsed\nversion of the pattern, free it before returning. Also free the list of named\ngroups if a larger one had to be obtained, and likewise the group information\nvector. */\n\n#ifdef SUPPORT_UNICODE\n/* All items must be freed. */\nPCRE2_ASSERT(cb.first_data == NULL);\n#endif\n\nEXIT:\n#ifdef SUPPORT_VALGRIND\nif (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1));\n#endif\nif (cb.parsed_pattern != stack_parsed_pattern)\n  ccontext->memctl.free(cb.parsed_pattern, ccontext->memctl.memory_data);\nif (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE)\n  ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data);\nif (cb.groupinfo != stack_groupinfo)\n  ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data);\n\nreturn re;    /* Will be NULL after an error */\n\n/* Errors discovered in parse_regex() set the offset value in the compile\nblock. Errors discovered before it is called must compute it from the ptr\nvalue. After parse_regex() is called, the offset in the compile block is set to\nthe end of the pattern, but certain errors in compile_regex() may reset it if\nan offset is available in the parsed pattern. */\n\nHAD_CB_ERROR:\nptr = pattern + cb.erroroffset;\n\nHAD_EARLY_ERROR:\n/* Ensure we don't return out-of-range erroroffset. */\nPCRE2_ASSERT(ptr >= pattern);\nPCRE2_ASSERT(ptr <= (pattern + patlen));\n/* Ensure that the erroroffset never slices a UTF-encoded character in half.\nIf the input is invalid, then we return an offset just before the first invalid\ncharacter, so the text to the left of the offset must always be valid. */\n#if defined PCRE2_DEBUG && defined SUPPORT_UNICODE\nif (ptr > pattern && utf)\n  {\n  PCRE2_SPTR prev = ptr - 1;\n  PCRE2_SIZE dummyoffset;\n  BACKCHAR(prev);\n  PCRE2_ASSERT(prev >= pattern);\n  PCRE2_ASSERT(PRIV(valid_utf)(prev, ptr - prev, &dummyoffset) == 0);\n  }\n#endif\n*erroroffset = ptr - pattern;\n\nHAD_ERROR:\n*errorptr = errorcode;\npcre2_code_free(re);\nre = NULL;\n\nif (cb.first_data != NULL)\n  {\n  compile_data* current_data = cb.first_data;\n  do\n    {\n    compile_data* next_data = current_data->next;\n    cb.cx->memctl.free(current_data, cb.cx->memctl.memory_data);\n    current_data = next_data;\n    }\n  while (current_data != NULL);\n  }\n\ngoto EXIT;\n}\n\n/* These #undefs are here to enable unity builds with CMake. */\n\n#undef NLBLOCK /* Block containing newline information */\n#undef PSSTART /* Field containing processed string start */\n#undef PSEND   /* Field containing processed string end */\n\n/* End of pcre2_compile.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_compile.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_COMPILE_H_IDEMPOTENT_GUARD\n#define PCRE2_COMPILE_H_IDEMPOTENT_GUARD\n\n#include \"pcre2_internal.h\"\n\n/* Compile time error code numbers. They are given names so that they can more\neasily be tracked. When a new number is added, the tables called eint1 and\neint2 in pcre2posix.c may need to be updated, and a new error text must be\nadded to compile_error_texts in pcre2_error.c. Also, the error codes in\npcre2.h.in must be updated - their values are exactly 100 greater than these\nvalues. */\n\nenum { ERR0 = COMPILE_ERROR_BASE,\n       ERR1,   ERR2,   ERR3,   ERR4,   ERR5,   ERR6,   ERR7,   ERR8,   ERR9,   ERR10,\n       ERR11,  ERR12,  ERR13,  ERR14,  ERR15,  ERR16,  ERR17,  ERR18,  ERR19,  ERR20,\n       ERR21,  ERR22,  ERR23,  ERR24,  ERR25,  ERR26,  ERR27,  ERR28,  ERR29,  ERR30,\n       ERR31,  ERR32,  ERR33,  ERR34,  ERR35,  ERR36,  ERR37,  ERR38,  ERR39,  ERR40,\n       ERR41,  ERR42,  ERR43,  ERR44,  ERR45,  ERR46,  ERR47,  ERR48,  ERR49,  ERR50,\n       ERR51,  ERR52,  ERR53,  ERR54,  ERR55,  ERR56,  ERR57,  ERR58,  ERR59,  ERR60,\n       ERR61,  ERR62,  ERR63,  ERR64,  ERR65,  ERR66,  ERR67,  ERR68,  ERR69,  ERR70,\n       ERR71,  ERR72,  ERR73,  ERR74,  ERR75,  ERR76,  ERR77,  ERR78,  ERR79,  ERR80,\n       ERR81,  ERR82,  ERR83,  ERR84,  ERR85,  ERR86,  ERR87,  ERR88,  ERR89,  ERR90,\n       ERR91,  ERR92,  ERR93,  ERR94,  ERR95,  ERR96,  ERR97,  ERR98,  ERR99,  ERR100,\n       ERR101, ERR102, ERR103, ERR104, ERR105, ERR106, ERR107, ERR108, ERR109, ERR110,\n       ERR111, ERR112, ERR113, ERR114, ERR115, ERR116, ERR117, ERR118, ERR119, ERR120 };\n\n/* Code values for parsed patterns, which are stored in a vector of 32-bit\nunsigned ints. Values less than META_END are literal data values. The coding\nfor identifying the item is in the top 16-bits, leaving 16 bits for the\nadditional data that some of them need. The META_CODE, META_DATA, and META_DIFF\nmacros are used to manipulate parsed pattern elements.\n\nNOTE: When these definitions are changed, the table of extra lengths for each\ncode (meta_extra_lengths) must be updated to remain in step. */\n\n#define META_END              0x80000000u  /* End of pattern */\n\n#define META_ALT              0x80010000u  /* alternation */\n#define META_ATOMIC           0x80020000u  /* atomic group */\n#define META_BACKREF          0x80030000u  /* Back ref */\n#define META_BACKREF_BYNAME   0x80040000u  /* \\k'name' */\n#define META_BIGVALUE         0x80050000u  /* Next is a literal > META_END */\n#define META_CALLOUT_NUMBER   0x80060000u  /* (?C with numerical argument */\n#define META_CALLOUT_STRING   0x80070000u  /* (?C with string argument */\n#define META_CAPTURE          0x80080000u  /* Capturing parenthesis */\n#define META_CIRCUMFLEX       0x80090000u  /* ^ metacharacter */\n#define META_CLASS            0x800a0000u  /* start non-empty class */\n#define META_CLASS_EMPTY      0x800b0000u  /* empty class */\n#define META_CLASS_EMPTY_NOT  0x800c0000u  /* negative empty class */\n#define META_CLASS_END        0x800d0000u  /* end of non-empty class */\n#define META_CLASS_NOT        0x800e0000u  /* start non-empty negative class */\n#define META_COND_ASSERT      0x800f0000u  /* (?(?assertion)... */\n#define META_COND_DEFINE      0x80100000u  /* (?(DEFINE)... */\n#define META_COND_NAME        0x80110000u  /* (?(<name>)... */\n#define META_COND_NUMBER      0x80120000u  /* (?(digits)... */\n#define META_COND_RNAME       0x80130000u  /* (?(R&name)... */\n#define META_COND_RNUMBER     0x80140000u  /* (?(Rdigits)... */\n#define META_COND_VERSION     0x80150000u  /* (?(VERSION<op>x.y)... */\n#define META_OFFSET           0x80160000u  /* Setting offset for various META\n                                              codes (e.g. META_CAPTURE_NAME) */\n#define META_SCS              0x80170000u  /* (*scan_substring:... */\n#define META_CAPTURE_NAME     0x80180000u  /* Next <name> in capture lists */\n#define META_CAPTURE_NUMBER   0x80190000u  /* Next digits in capture lists */\n#define META_DOLLAR           0x801a0000u  /* $ metacharacter */\n#define META_DOT              0x801b0000u  /* . metacharacter */\n#define META_ESCAPE           0x801c0000u  /* \\d and friends */\n#define META_KET              0x801d0000u  /* closing parenthesis */\n#define META_NOCAPTURE        0x801e0000u  /* no capture parens */\n#define META_OPTIONS          0x801f0000u  /* (?i) and friends */\n#define META_POSIX            0x80200000u  /* POSIX class item */\n#define META_POSIX_NEG        0x80210000u  /* negative POSIX class item */\n#define META_RANGE_ESCAPED    0x80220000u  /* range with at least one escape */\n#define META_RANGE_LITERAL    0x80230000u  /* range defined literally */\n#define META_RECURSE          0x80240000u  /* Recursion */\n#define META_RECURSE_BYNAME   0x80250000u  /* (?&name) */\n#define META_SCRIPT_RUN       0x80260000u  /* (*script_run:...) */\n\n/* These must be kept together to make it easy to check that an assertion\nis present where expected in a conditional group. */\n\n#define META_LOOKAHEAD        0x80270000u  /* (?= */\n#define META_LOOKAHEADNOT     0x80280000u  /* (?! */\n#define META_LOOKBEHIND       0x80290000u  /* (?<= */\n#define META_LOOKBEHINDNOT    0x802a0000u  /* (?<! */\n\n/* These cannot be conditions */\n\n#define META_LOOKAHEAD_NA     0x802b0000u  /* (*napla: */\n#define META_LOOKBEHIND_NA    0x802c0000u  /* (*naplb: */\n\n/* These must be kept in this order, with consecutive values, and the _ARG\nversions of COMMIT, PRUNE, SKIP, and THEN immediately after their non-argument\nversions. */\n\n#define META_MARK             0x802d0000u  /* (*MARK) */\n#define META_ACCEPT           0x802e0000u  /* (*ACCEPT) */\n#define META_FAIL             0x802f0000u  /* (*FAIL) */\n#define META_COMMIT           0x80300000u  /* These               */\n#define META_COMMIT_ARG       0x80310000u  /*   pairs             */\n#define META_PRUNE            0x80320000u  /*     must            */\n#define META_PRUNE_ARG        0x80330000u  /*       be            */\n#define META_SKIP             0x80340000u  /*         kept        */\n#define META_SKIP_ARG         0x80350000u  /*           in        */\n#define META_THEN             0x80360000u  /*             this    */\n#define META_THEN_ARG         0x80370000u  /*               order */\n\n/* These must be kept in groups of adjacent 3 values, and all together. */\n\n#define META_ASTERISK         0x80380000u  /* *  */\n#define META_ASTERISK_PLUS    0x80390000u  /* *+ */\n#define META_ASTERISK_QUERY   0x803a0000u  /* *? */\n#define META_PLUS             0x803b0000u  /* +  */\n#define META_PLUS_PLUS        0x803c0000u  /* ++ */\n#define META_PLUS_QUERY       0x803d0000u  /* +? */\n#define META_QUERY            0x803e0000u  /* ?  */\n#define META_QUERY_PLUS       0x803f0000u  /* ?+ */\n#define META_QUERY_QUERY      0x80400000u  /* ?? */\n#define META_MINMAX           0x80410000u  /* {n,m}  repeat */\n#define META_MINMAX_PLUS      0x80420000u  /* {n,m}+ repeat */\n#define META_MINMAX_QUERY     0x80430000u  /* {n,m}? repeat */\n\n/* These meta codes must be kept in a group, with the OR/SUB/XOR in\nthis order, and AND/NOT at the start/end. */\n\n#define META_ECLASS_AND       0x80440000u  /* && (or &) in a class */\n#define META_ECLASS_OR        0x80450000u  /* || (or |, +) in a class */\n#define META_ECLASS_SUB       0x80460000u  /* -- (or -) in a class */\n#define META_ECLASS_XOR       0x80470000u  /* ~~ (or ^) in a class */\n#define META_ECLASS_NOT       0x80480000u  /* ! in a class */\n\n/* Convenience aliases. */\n\n#define META_FIRST_QUANTIFIER META_ASTERISK\n#define META_LAST_QUANTIFIER  META_MINMAX_QUERY\n\n/* This is a special \"meta code\" that is used only to distinguish (*asr: from\n(*sr: in the table of alphabetic assertions. It is never stored in the parsed\npattern because (*asr: is turned into (*sr:(*atomic: at that stage. There is\ntherefore no need for it to have a length entry, so use a high value. */\n\n#define META_ATOMIC_SCRIPT_RUN 0x8fff0000u\n\n/* Macros for manipulating elements of the parsed pattern vector. */\n\n#define META_CODE(x)   (x & 0xffff0000u)\n#define META_DATA(x)   (x & 0x0000ffffu)\n#define META_DIFF(x,y) ((x-y)>>16)\n\n/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which\nconsists of uint32_t elements. Assume that if uint32_t can't hold it, two of\nthem will be able to (i.e. assume a 64-bit world). */\n\n#if PCRE2_SIZE_MAX <= UINT32_MAX\n#define PUTOFFSET(s,p) *p++ = s\n#define GETOFFSET(s,p) s = *p++\n#define GETPLUSOFFSET(s,p) s = *(++p)\n#define READPLUSOFFSET(s,p) s = p[1]\n#define SKIPOFFSET(p) p++\n#define SIZEOFFSET 1\n#else\n#define PUTOFFSET(s,p) \\\n  { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }\n#define GETOFFSET(s,p) \\\n  { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }\n#define GETPLUSOFFSET(s,p) \\\n  { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }\n#define READPLUSOFFSET(s,p) \\\n  { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }\n#define SKIPOFFSET(p) p += 2\n#define SIZEOFFSET 2\n#endif\n\n#ifdef PCRE2_DEBUG\n/* Compile data types. */\n#define CDATA_RECURSE_ARGS       0 /* Argument list for recurse */\n#define CDATA_CRANGE             1 /* Character range list */\n#endif\n\n/* Extended class management flags. */\n\n#define CLASS_IS_ECLASS 0x1\n\n/* Macro for the highest character value. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define MAX_UCHAR_VALUE 0xffu\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define MAX_UCHAR_VALUE 0xffffu\n#else\n#define MAX_UCHAR_VALUE 0xffffffffu\n#endif\n\n#define GET_MAX_CHAR_VALUE(utf) \\\n  ((utf) ? MAX_UTF_CODE_POINT : MAX_UCHAR_VALUE)\n\n/* Macro for setting individual bits in class bitmaps. */\n\n#define SETBIT(a,b) a[(b) >> 3] |= (uint8_t)(1u << ((b) & 0x7))\n\n/* Macro for 8 bit specific checks. */\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define SELECT_VALUE8(value8, value) (value8)\n#else\n#define SELECT_VALUE8(value8, value) (value)\n#endif\n\n/* Macro for aligning data. */\n#define CLIST_ALIGN_TO(base, align) \\\n  ((base + ((size_t)(align) - 1)) & ~((size_t)(align) - 1))\n\n/* Structure for holding information about an OP_ECLASS internal operand.\nAn \"operand\" here could be just a single OP_[X]CLASS, or it could be some\ncomplex expression; but it's some sequence of ECL_* codes which pushes one\nvalue to the stack. */\ntypedef struct {\n  /* The position of the operand - or NULL if (lengthptr != NULL). */\n  PCRE2_UCHAR *code_start;\n  PCRE2_SIZE length;\n  /* The operand's type if it is a single code (ECL_XCLASS, ECL_ANY, ECL_NONE);\n  otherwise zero if the operand is not atomic. */\n  uint8_t op_single_type;\n  /* Regardless of whether it's a single code or not, we fully constant-fold\n  the bitmap for code points < 256. */\n  class_bits_storage bits;\n} eclass_op_info;\n\n/* Macros for the definitions below, to prevent name collisions. */\n\n#define _pcre2_posix_class_maps                PCRE2_SUFFIX(_pcre2_posix_class_maps)\n#define _pcre2_update_classbits                PCRE2_SUFFIX(_pcre2_update_classbits_)\n#define _pcre2_compile_class_nested            PCRE2_SUFFIX(_pcre2_compile_class_nested_)\n#define _pcre2_compile_class_not_nested        PCRE2_SUFFIX(_pcre2_compile_class_not_nested_)\n#define _pcre2_compile_get_hash_from_name      PCRE2_SUFFIX(_pcre2_compile_get_hash_from_name)\n#define _pcre2_compile_find_named_group        PCRE2_SUFFIX(_pcre2_compile_find_named_group)\n#define _pcre2_compile_find_dupname_details    PCRE2_SUFFIX(_pcre2_compile_find_dupname_details)\n#define _pcre2_compile_add_name_to_table       PCRE2_SUFFIX(_pcre2_compile_add_name_to_table)\n#define _pcre2_compile_parse_scan_substr_args  PCRE2_SUFFIX(_pcre2_compile_parse_scan_substr_args)\n#define _pcre2_compile_parse_recurse_args      PCRE2_SUFFIX(_pcre2_compile_parse_recurse_args)\n\n\n/* Indices of the POSIX classes in posix_names, posix_name_lengths,\nposix_class_maps, and posix_substitutes. They must be kept in sync. */\n\n#define PC_DIGIT   7\n#define PC_GRAPH   8\n#define PC_PRINT   9\n#define PC_PUNCT  10\n#define PC_XDIGIT 13\n\nextern const int PRIV(posix_class_maps)[];\n\n/* Defines for hash_dup member in named_group structure. */\n\n#define NAMED_GROUP_HASH_MASK      ((uint16_t)0x7fff)\n#define NAMED_GROUP_IS_DUPNAME     ((uint16_t)0x8000)\n\n#define NAMED_GROUP_GET_HASH(ng)   ((ng)->hash_dup & NAMED_GROUP_HASH_MASK)\n\n/* Exported functions from pcre2_compile_class.c file: */\n\n/* Set bits in classbits according to the property type */\n\nvoid PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated,\n  uint8_t *classbits);\n\n/* Compile the META codes from start_ptr...end_ptr, writing a single OP_CLASS\nOP_CLASS, OP_NCLASS, OP_XCLASS, or OP_ALLANY into pcode. */\n\nuint32_t *PRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions,\n  uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap,\n  int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr);\n\n/* Compile the META codes in pptr into opcodes written to pcode. The pptr must\nstart at a META_CLASS or META_CLASS_NOT.\n\nThe pptr will be left pointing at the matching META_CLASS_END. */\n\nBOOL PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr,\n  compile_block *cb, PCRE2_SIZE *lengthptr);\n\n/* Exported functions from pcre2_compile_cgroup.c file: */\n\n/* Compute hash from a capture name. */\n\nuint16_t PRIV(compile_get_hash_from_name)(PCRE2_SPTR name, uint32_t length);\n\n/* Get the descriptor of a known named capture. */\n\nnamed_group *PRIV(compile_find_named_group)(PCRE2_SPTR name,\n  uint32_t length, compile_block *cb);\n\n/* Add entires to name table in alphabetical order. */\n\nuint32_t PRIV(compile_add_name_to_table)(compile_block *cb,\n  named_group *ng, uint32_t tablecount);\n\n/* Searches the properties of duplicated names, and returns them\nin indexptr and countptr. */\n\nBOOL PRIV(compile_find_dupname_details)(PCRE2_SPTR name, uint32_t length,\n  int *indexptr, int *countptr, int *errorcodeptr, compile_block *cb);\n\n/* Parse the arguments of recurse operations. */\n\nuint32_t * PRIV(compile_parse_scan_substr_args)(uint32_t *pptr,\n  int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr);\n\n/* Parse the arguments of recurse operations. */\n\nBOOL PRIV(compile_parse_recurse_args)(uint32_t *pptr_start,\n  PCRE2_SIZE offset, int *errorcodeptr, compile_block *cb);\n\n#endif  /* PCRE2_COMPILE_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2_compile.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_compile_cgroup.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_compile.h\"\n\n/*************************************************\n*   Compute the hash code from a capture name    *\n*************************************************/\n\n/* This function returns with a simple hash code\ncomputed from the name of a capture group.\n\nArguments:\n  name         name of the capture group\n  length       the length of the name\n\nReturns:       hash code\n*/\n\nuint16_t\nPRIV(compile_get_hash_from_name)(PCRE2_SPTR name, uint32_t length)\n{\nuint16_t hash;\n\nPCRE2_ASSERT(length > 0);\n\nhash = (uint16_t)((name[0] & 0x7f) | ((name[length - 1] & 0xff) << 7));\nPCRE2_ASSERT(hash <= NAMED_GROUP_HASH_MASK);\nreturn hash;\n}\n\n\n/*************************************************\n*   Get the descriptor of a known named capture  *\n*************************************************/\n\n/* This function returns the descriptor in the\nnamed group list of a known capture group.\n\nArguments:\n  name         name of the capture group\n  length       the length of the name\n\nReturns:       pointer to the descriptor when found,\n               NULL otherwise\n */\n\nnamed_group *\nPRIV(compile_find_named_group)(PCRE2_SPTR name,\n  uint32_t length, compile_block *cb)\n{\nuint16_t hash = PRIV(compile_get_hash_from_name)(name, length);\nnamed_group *ng;\nnamed_group *end = cb->named_groups + cb->names_found;\n\nfor (ng = cb->named_groups; ng < end; ng++)\n  if (length == ng->length && hash == NAMED_GROUP_GET_HASH(ng) &&\n      PRIV(strncmp)(name, ng->name, length) == 0) return ng;\n\nreturn NULL;\n}\n\n\n/*************************************************\n*     Add an entry to the name/number table      *\n*************************************************/\n\n/* This function is called between compiling passes to add an entry to the\nname/number table, maintaining alphabetical order. Checking for permitted\nand forbidden duplicates has already been done.\n\nArguments:\n  cb           the compile data block\n  nb           named group entry\n  tablecount   the count of names in the table so far\n\nReturns:       new tablecount\n*/\n\nuint32_t\nPRIV(compile_add_name_to_table)(compile_block *cb,\n  named_group *ng, uint32_t tablecount)\n{\nuint32_t i;\nPCRE2_SPTR name = ng->name;\nint length = ng->length;\nuint32_t duplicate_count = 1;\n\nPCRE2_UCHAR *slot = cb->name_table;\n\nPCRE2_ASSERT(length > 0);\n\nif ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0)\n  {\n  named_group *ng_it;\n  named_group *end = cb->named_groups + cb->names_found;\n\n  for (ng_it = ng + 1; ng_it < end; ng_it++)\n    if (ng_it->name == name) duplicate_count++;\n  }\n\nfor (i = 0; i < tablecount; i++)\n  {\n  int crc = memcmp(name, slot + IMM2_SIZE, CU2BYTES(length));\n  if (crc == 0 && slot[IMM2_SIZE + length] != 0)\n    crc = -1; /* Current name is a substring */\n\n  /* Make space in the table and break the loop for an earlier name. For a\n  duplicate or later name, carry on. We do this for duplicates so that in the\n  simple case (when ?(| is not used) they are in order of their numbers. In all\n  cases they are in the order in which they appear in the pattern. */\n\n  if (crc < 0)\n    {\n    (void)memmove(slot + cb->name_entry_size * duplicate_count, slot,\n      CU2BYTES((tablecount - i) * cb->name_entry_size));\n    break;\n    }\n\n  /* Continue the loop for a later or duplicate name */\n\n  slot += cb->name_entry_size;\n  }\n\ntablecount += duplicate_count;\n\nwhile (TRUE)\n  {\n  PUT2(slot, 0, ng->number);\n  memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));\n\n  /* Add a terminating zero and fill the rest of the slot with zeroes so that\n  the memory is all initialized. Otherwise valgrind moans about uninitialized\n  memory when saving serialized compiled patterns. */\n\n  memset(slot + IMM2_SIZE + length, 0,\n    CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));\n\n  if (--duplicate_count == 0) break;\n\n  while (TRUE)\n    {\n    ++ng;\n    if (ng->name == name) break;\n    }\n\n  slot += cb->name_entry_size;\n  }\n\nreturn tablecount;\n}\n\n\n/*************************************************\n*    Find details of duplicate group names       *\n*************************************************/\n\n/* This is called from compile_branch() when it needs to know the index and\ncount of duplicates in the names table when processing named backreferences,\neither directly, or as conditions.\n\nArguments:\n  name          points to the name\n  length        the length of the name\n  indexptr      where to put the index\n  countptr      where to put the count of duplicates\n  errorcodeptr  where to put an error code\n  cb            the compile block\n\nReturns:        TRUE if OK, FALSE if not, error code set\n*/\n\nBOOL\nPRIV(compile_find_dupname_details)(PCRE2_SPTR name, uint32_t length,\n  int *indexptr, int *countptr, int *errorcodeptr, compile_block *cb)\n{\nuint32_t i, groupnumber;\nint count;\nPCRE2_UCHAR *slot = cb->name_table;\n\n/* Find the first entry in the table */\n\nfor (i = 0; i < cb->names_found; i++)\n  {\n  if (PRIV(strncmp)(name, slot + IMM2_SIZE, length) == 0 &&\n      slot[IMM2_SIZE + length] == 0) break;\n  slot += cb->name_entry_size;\n  }\n\n/* This should not occur, because this function is called only when we know we\nhave duplicate names. Give an internal error. */\n\n/* LCOV_EXCL_START */\nif (i >= cb->names_found)\n  {\n  PCRE2_DEBUG_UNREACHABLE();\n  *errorcodeptr = ERR53;\n  cb->erroroffset = name - cb->start_pattern;\n  return FALSE;\n  }\n/* LCOV_EXCL_STOP */\n\n/* Record the index and then see how many duplicates there are, updating the\nbackref map and maximum back reference as we do. */\n\n*indexptr = i;\ncount = 0;\n\nfor (;;)\n  {\n  count++;\n  groupnumber = GET2(slot, 0);\n  cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;\n  if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;\n  if (++i >= cb->names_found) break;\n  slot += cb->name_entry_size;\n  if (PRIV(strncmp)(name, slot + IMM2_SIZE, length) != 0 ||\n    (slot + IMM2_SIZE)[length] != 0) break;\n  }\n\n*countptr = count;\nreturn TRUE;\n}\n\n\n/* Process the capture list of scan substring and recurse\noperations. Since at least one argument must be present,\na 0 return value represents error. */\n\nstatic size_t\nPRIV(compile_process_capture_list)(uint32_t *pptr, PCRE2_SIZE offset,\n  int *errorcodeptr, compile_block *cb)\n{\nsize_t i, size = 0;\nnamed_group *ng;\nPCRE2_SPTR name;\nuint32_t length;\nnamed_group *end = cb->named_groups + cb->names_found;\n\nwhile (TRUE)\n  {\n  ++pptr;\n\n  switch (META_CODE(*pptr))\n    {\n    case META_OFFSET:\n    GETPLUSOFFSET(offset, pptr);\n    continue;\n\n    case META_CAPTURE_NAME:\n    offset += META_DATA(*pptr);\n    length = *(++pptr);\n    name = cb->start_pattern + offset;\n\n    ng = PRIV(compile_find_named_group)(name, length, cb);\n\n    if (ng == NULL)\n      {\n      *errorcodeptr = ERR15;\n      cb->erroroffset = offset;\n      return 0;\n      }\n\n    if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)\n      {\n      pptr[-1] = META_CAPTURE_NUMBER;\n      pptr[0] = ng->number;\n      size++;\n      continue;\n      }\n\n    /* Remains only for duplicated names. */\n    pptr[-1] = META_CAPTURE_NAME;\n    pptr[0] = (uint32_t)(ng - cb->named_groups);\n    size++;\n    name = ng->name;\n\n    while (++ng < end)\n      if (ng->name == name) size++;\n    continue;\n\n    case META_CAPTURE_NUMBER:\n    offset += META_DATA(*pptr);\n\n    i = *(++pptr);\n    if (i > cb->bracount)\n      {\n      *errorcodeptr = ERR15;\n      cb->erroroffset = offset;\n      return 0;\n      }\n    if (i > cb->top_backref) cb->top_backref = (uint16_t)i;\n    size++;\n    continue;\n\n    default:\n    break;\n    }\n\n  PCRE2_ASSERT(size > 0);\n  return size;\n  }\n}\n\n\n/*******************************************************\n*   Parse the arguments of scan substring operations   *\n********************************************************/\n\n/* This function parses the arguments of scan substring operations.\n\nArguments:\n  pptr_start    points to the current parsed pattern pointer\n  offset        argument starting offset in the pattern\n  errorcodeptr  where to put an error code\n  cb            the compile block\n  lengthptr     NULL during the real compile phase\n                points to length accumulator during pre-compile phase\n\nReturns:        TRUE if OK, FALSE if not, error code set\n*/\n\nuint32_t *\nPRIV(compile_parse_scan_substr_args)(uint32_t *pptr,\n  int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr)\n{\nuint8_t *captures;\nuint8_t *capture_ptr;\nuint8_t bit;\nPCRE2_SPTR name;\nnamed_group *ng;\nnamed_group *end = cb->named_groups + cb->names_found;\nBOOL all_found;\nsize_t size;\n\nPCRE2_ASSERT(*pptr == META_OFFSET);\nif (PRIV(compile_process_capture_list)(pptr - 1, 0, errorcodeptr, cb) == 0)\n  return NULL;\n\n/* Align to bytes. Since the highest capture can\nbe equal to bracount, +1 is added before the aligning. */\nsize = (cb->bracount + 1 + 7) >> 3;\ncaptures = (uint8_t*)cb->cx->memctl.malloc(size, cb->cx->memctl.memory_data);\nif (captures == NULL)\n  {\n  *errorcodeptr = ERR21;\n  READPLUSOFFSET(cb->erroroffset, pptr);\n  return NULL;\n  }\n\nmemset(captures, 0, size);\n\nwhile (TRUE)\n  {\n  switch (META_CODE(*pptr))\n    {\n    case META_OFFSET:\n    pptr++;\n    SKIPOFFSET(pptr);\n    continue;\n\n    case META_CAPTURE_NAME:\n    ng = cb->named_groups + pptr[1];\n    PCRE2_ASSERT((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0);\n    pptr += 2;\n    name = ng->name;\n\n    all_found = TRUE;\n    do\n      {\n      if (ng->name != name) continue;\n\n      capture_ptr = captures + (ng->number >> 3);\n      PCRE2_ASSERT(capture_ptr < captures + size);\n      bit = (uint8_t)(1 << (ng->number & 0x7));\n\n      if ((*capture_ptr & bit) == 0)\n        {\n        *capture_ptr |= bit;\n        all_found = FALSE;\n        }\n      }\n    while (++ng < end);\n\n    if (!all_found)\n      {\n      *lengthptr += 1 + 2 * IMM2_SIZE;\n      continue;\n      }\n\n    pptr[-2] = META_CAPTURE_NUMBER;\n    pptr[-1] = 0;\n    continue;\n\n    case META_CAPTURE_NUMBER:\n    pptr += 2;\n\n    capture_ptr = captures + (pptr[-1] >> 3);\n    PCRE2_ASSERT(capture_ptr < captures + size);\n    bit = (uint8_t)(1 << (pptr[-1] & 0x7));\n\n    if ((*capture_ptr & bit) != 0)\n      {\n      pptr[-1] = 0;\n      continue;\n      }\n\n    *capture_ptr |= bit;\n    *lengthptr += 1 + IMM2_SIZE;\n    continue;\n\n    default:\n    break;\n    }\n\n  break;\n  }\n\ncb->cx->memctl.free(captures, cb->cx->memctl.memory_data);\nreturn pptr - 1;\n}\n\n\n/* Implement heapsort heapify algorithm. */\n\nstatic void do_heapify_u16(uint16_t *captures, size_t size, size_t i)\n{\nsize_t max;\nsize_t left;\nsize_t right;\nuint16_t tmp;\n\nwhile (TRUE)\n  {\n  max = i;\n  left = (i << 1) + 1;\n  right = left + 1;\n\n  if (left < size && captures[left] > captures[max]) max = left;\n  if (right < size && captures[right] > captures[max]) max = right;\n  if (i == max) return;\n\n  tmp = captures[i];\n  captures[i] = captures[max];\n  captures[max] = tmp;\n  i = max;\n  }\n}\n\n\n/*************************************************\n*   Parse the arguments of recurse operations    *\n*************************************************/\n\n/* This function parses the arguments of recurse operations.\n\nArguments:\n  pptr_start    the current parsed pattern pointer\n  offset        argument starting offset in the pattern\n  errorcodeptr  where to put an error code\n  cb            the compile block\n  lengthptr     NULL during the real compile phase\n                points to length accumulator during pre-compile phase\n\nReturns:        TRUE if OK, FALSE if not, error code set\n*/\n\nBOOL\nPRIV(compile_parse_recurse_args)(uint32_t *pptr_start,\n  PCRE2_SIZE offset, int *errorcodeptr, compile_block *cb)\n{\nuint32_t *pptr = pptr_start;\nsize_t i, size;\nPCRE2_SPTR name;\nnamed_group *ng;\nnamed_group *end = cb->named_groups + cb->names_found;\nrecurse_arguments *args;\nuint16_t *captures;\nuint16_t *current;\nuint16_t *captures_end;\nuint16_t tmp;\n\n/* Process all arguments, compute the required size. */\n\nsize = PRIV(compile_process_capture_list)(pptr, offset, errorcodeptr, cb);\nif (size == 0) return FALSE;\n\nargs = cb->cx->memctl.malloc(\n  sizeof(recurse_arguments) + size * sizeof(uint16_t), cb->cx->memctl.memory_data);\n\nif (args == NULL)\n  {\n  *errorcodeptr = ERR21;\n  cb->erroroffset = offset;\n  return FALSE;\n  }\n\nargs->header.next = NULL;\n#ifdef PCRE2_DEBUG\nargs->header.type = CDATA_RECURSE_ARGS;\n#endif\nargs->size = size;\n\n/* Caching the pre-processed capture list. */\nif (cb->last_data != NULL)\n  cb->last_data->next = &args->header;\nelse\n  cb->first_data = &args->header;\n\ncb->last_data = &args->header;\n\n/* Create the capture list size. */\n\ncaptures = (uint16_t*)(args + 1);\n\nwhile (TRUE)\n  {\n  ++pptr;\n\n  switch (META_CODE(*pptr))\n    {\n    case META_OFFSET:\n    SKIPOFFSET(pptr);\n    continue;\n\n    case META_CAPTURE_NAME:\n    ng = cb->named_groups + *(++pptr);\n    PCRE2_ASSERT((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0);\n    *captures++ = (uint16_t)(ng->number);\n\n    name = ng->name;\n\n    while (++ng < end)\n      if (ng->name == name) *captures++ = (uint16_t)(ng->number);\n    continue;\n\n    case META_CAPTURE_NUMBER:\n    *captures++ = *(++pptr);\n    continue;\n\n    default:\n    break;\n    }\n\n  break;\n  }\n\nPCRE2_ASSERT(size == (size_t)(captures - (uint16_t*)(args + 1)));\nargs->skip_size = (size_t)(pptr - pptr_start) - 1;\n\nif (size == 1) return TRUE;\n\n/* Sort captures. */\n\ncaptures = (uint16_t*)(args + 1);\ni = (size >> 1) - 1;\nwhile (TRUE)\n  {\n  do_heapify_u16(captures, size, i);\n  if (i == 0) break;\n  i--;\n  }\n\nfor (i = size - 1; i > 0; i--)\n  {\n  tmp = captures[0];\n  captures[0] = captures[i];\n  captures[i] = tmp;\n\n  do_heapify_u16(captures, i, 0);\n  }\n\n/* Remove duplicates. */\n\ncaptures_end = captures + size;\ntmp = *captures++;\ncurrent = captures;\n\nwhile (current < captures_end)\n  {\n  if (*current != tmp)\n    {\n    tmp = *current;\n    *captures++ = tmp;\n    }\n\n  current++;\n  }\n\nargs->size = (size_t)(captures - (uint16_t*)(args + 1));\nreturn TRUE;\n}\n\n/* End of pcre2_compile_cgroup.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_compile_class.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_compile.h\"\n\n\n\ntypedef struct {\n  /* Option bits for eclass. */\n  uint32_t options;\n  uint32_t xoptions;\n  /* Rarely used members. */\n  int *errorcodeptr;\n  compile_block *cb;\n  /* Bitmap is needed. */\n  BOOL needs_bitmap;\n} eclass_context;\n\n/* Checks the allowed tokens at the end of a class structure in debug mode.\nWhen a new token is not processed by all loops, and the token is equals to\na) one of the cases here:\n   the compiler will complain about a duplicated case value.\nb) none of the cases here:\n   the loop without the handler will stop with an assertion failure. */\n\n#ifdef PCRE2_DEBUG\n#define CLASS_END_CASES(meta) \\\n  default: \\\n  PCRE2_ASSERT((meta) <= META_END); \\\n  PCRE2_FALLTHROUGH /* Fall through */ \\\n  case META_CLASS: \\\n  case META_CLASS_NOT: \\\n  case META_CLASS_EMPTY: \\\n  case META_CLASS_EMPTY_NOT: \\\n  case META_CLASS_END: \\\n  case META_ECLASS_AND: \\\n  case META_ECLASS_OR: \\\n  case META_ECLASS_SUB: \\\n  case META_ECLASS_XOR: \\\n  case META_ECLASS_NOT:\n#else\n#define CLASS_END_CASES(meta) \\\n  default:\n#endif\n\n#ifdef SUPPORT_WIDE_CHARS\n\n/* Heapsort algorithm. */\n\nstatic void do_heapify(uint32_t *buffer, size_t size, size_t i)\n{\nsize_t max;\nsize_t left;\nsize_t right;\nuint32_t tmp1, tmp2;\n\nwhile (TRUE)\n  {\n  max = i;\n  left = (i << 1) + 2;\n  right = left + 2;\n\n  if (left < size && buffer[left] > buffer[max]) max = left;\n  if (right < size && buffer[right] > buffer[max]) max = right;\n  if (i == max) return;\n\n  /* Swap items. */\n  tmp1 = buffer[i];\n  tmp2 = buffer[i + 1];\n  buffer[i] = buffer[max];\n  buffer[i + 1] = buffer[max + 1];\n  buffer[max] = tmp1;\n  buffer[max + 1] = tmp2;\n  i = max;\n  }\n}\n\n#ifdef SUPPORT_UNICODE\n\n#define PARSE_CLASS_UTF               0x1\n#define PARSE_CLASS_CASELESS_UTF      0x2\n#define PARSE_CLASS_RESTRICTED_UTF    0x4\n#define PARSE_CLASS_TURKISH_UTF       0x8\n\n/* Get the range of nocase characters which includes the\n'c' character passed as argument, or directly follows 'c'. */\n\nstatic const uint32_t*\nget_nocase_range(uint32_t c)\n{\nuint32_t left = 0;\nuint32_t right = PRIV(ucd_nocase_ranges_size);\nuint32_t middle;\n\nif (c > MAX_UTF_CODE_POINT) return PRIV(ucd_nocase_ranges) + right;\n\nwhile (TRUE)\n  {\n  /* Range end of the middle element. */\n  middle = ((left + right) >> 1) | 0x1;\n\n  if (PRIV(ucd_nocase_ranges)[middle] <= c)\n    left = middle + 1;\n  else if (middle > 1 && PRIV(ucd_nocase_ranges)[middle - 2] > c)\n    right = middle - 1;\n  else\n    return PRIV(ucd_nocase_ranges) + (middle - 1);\n  }\n}\n\n/* Get the list of othercase characters, which belongs to the passed range.\nCreate ranges from these characters, and append them to the buffer argument. */\n\nstatic size_t\nutf_caseless_extend(uint32_t start, uint32_t end, uint32_t options,\n  uint32_t *buffer)\n{\nuint32_t new_start = start;\nuint32_t new_end = end;\nuint32_t c = start;\nconst uint32_t *list;\nuint32_t tmp[3];\nsize_t result = 2;\nconst uint32_t *skip_range = get_nocase_range(c);\nuint32_t skip_start = skip_range[0];\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nPCRE2_ASSERT(options & PARSE_CLASS_UTF);\n#endif\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (end > MAX_UTF_CODE_POINT) end = MAX_UTF_CODE_POINT;\n#endif\n\nwhile (c <= end)\n  {\n  uint32_t co;\n\n  if (c > skip_start)\n    {\n    c = skip_range[1];\n    skip_range += 2;\n    skip_start = skip_range[0];\n    continue;\n    }\n\n  /* Compute caseless set. */\n\n  if ((options & (PARSE_CLASS_TURKISH_UTF|PARSE_CLASS_RESTRICTED_UTF)) ==\n        PARSE_CLASS_TURKISH_UTF &&\n      UCD_ANY_I(c))\n    {\n    co = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3);\n    }\n  else if ((co = UCD_CASESET(c)) != 0 &&\n           (options & PARSE_CLASS_RESTRICTED_UTF) != 0 &&\n           PRIV(ucd_caseless_sets)[co] < 128)\n    {\n    co = 0;  /* Ignore the caseless set if it's restricted. */\n    }\n\n  if (co != 0)\n    list = PRIV(ucd_caseless_sets) + co;\n  else\n    {\n    co = UCD_OTHERCASE(c);\n    list = tmp;\n    tmp[0] = c;\n    tmp[1] = NOTACHAR;\n\n    if (co != c)\n      {\n      tmp[1] = co;\n      tmp[2] = NOTACHAR;\n      }\n    }\n  c++;\n\n  /* Add characters. */\n  do\n    {\n#if PCRE2_CODE_UNIT_WIDTH == 16\n    if (!(options & PARSE_CLASS_UTF) && *list > 0xffff) continue;\n#endif\n\n    if (*list < new_start)\n      {\n      if (*list + 1 == new_start)\n        {\n        new_start--;\n        continue;\n        }\n      }\n    else if (*list > new_end)\n      {\n      if (*list - 1 == new_end)\n        {\n        new_end++;\n        continue;\n        }\n      }\n    else continue;\n\n    result += 2;\n    if (buffer != NULL)\n      {\n      buffer[0] = *list;\n      buffer[1] = *list;\n      buffer += 2;\n      }\n    }\n  while (*(++list) != NOTACHAR);\n  }\n\n  if (buffer != NULL)\n    {\n    buffer[0] = new_start;\n    buffer[1] = new_end;\n    buffer += 2;\n    (void)buffer;\n    }\n  return result;\n}\n\n#endif\n\n/* Add a character list to a buffer. */\n\nstatic size_t\nappend_char_list(const uint32_t *p, uint32_t *buffer)\n{\nconst uint32_t *n;\nsize_t result = 0;\n\nwhile (*p != NOTACHAR)\n  {\n  n = p;\n  while (n[0] == n[1] - 1) n++;\n\n  PCRE2_ASSERT(*p < 0xffff);\n\n  if (buffer != NULL)\n    {\n    buffer[0] = *p;\n    buffer[1] = *n;\n    buffer += 2;\n    }\n\n  result += 2;\n  p = n + 1;\n  }\n\n  return result;\n}\n\nstatic uint32_t\nget_highest_char(uint32_t options)\n{\n(void)options; /* Avoid compiler warning. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nreturn MAX_UTF_CODE_POINT;\n#else\n#ifdef SUPPORT_UNICODE\nreturn GET_MAX_CHAR_VALUE((options & PARSE_CLASS_UTF) != 0);\n#else\nreturn MAX_UCHAR_VALUE;\n#endif\n#endif\n}\n\n/* Add a negated character list to a buffer. */\nstatic size_t\nappend_negated_char_list(const uint32_t *p, uint32_t options, uint32_t *buffer)\n{\nconst uint32_t *n;\nuint32_t start = 0;\nsize_t result = 2;\n\nPCRE2_ASSERT(*p > 0);\n\nwhile (*p != NOTACHAR)\n  {\n  n = p;\n  while (n[0] == n[1] - 1) n++;\n\n  PCRE2_ASSERT(*p < 0xffff);\n\n  if (buffer != NULL)\n    {\n    buffer[0] = start;\n    buffer[1] = *p - 1;\n    buffer += 2;\n    }\n\n  result += 2;\n  start = *n + 1;\n  p = n + 1;\n  }\n\n  if (buffer != NULL)\n    {\n    buffer[0] = start;\n    buffer[1] = get_highest_char(options);\n    buffer += 2;\n    (void)buffer;\n    }\n\n  return result;\n}\n\nstatic uint32_t *\nappend_non_ascii_range(uint32_t options, uint32_t *buffer)\n{\n  if (buffer == NULL) return NULL;\n\n  buffer[0] = 0x100;\n  buffer[1] = get_highest_char(options);\n  return buffer + 2;\n}\n\nstatic size_t\nparse_class(uint32_t *ptr, uint32_t options, uint32_t *buffer)\n{\nsize_t total_size = 0;\nsize_t size;\nuint32_t meta_arg;\nuint32_t start_char;\n\nwhile (TRUE)\n  {\n  switch (META_CODE(*ptr))\n    {\n    case META_ESCAPE:\n      meta_arg = META_DATA(*ptr);\n      switch (meta_arg)\n        {\n        case ESC_D:\n        case ESC_W:\n        case ESC_S:\n        buffer = append_non_ascii_range(options, buffer);\n        total_size += 2;\n        break;\n\n        case ESC_h:\n        size = append_char_list(PRIV(hspace_list), buffer);\n        total_size += size;\n        if (buffer != NULL) buffer += size;\n        break;\n\n        case ESC_H:\n        size = append_negated_char_list(PRIV(hspace_list), options, buffer);\n        total_size += size;\n        if (buffer != NULL) buffer += size;\n        break;\n\n        case ESC_v:\n        size = append_char_list(PRIV(vspace_list), buffer);\n        total_size += size;\n        if (buffer != NULL) buffer += size;\n        break;\n\n        case ESC_V:\n        size = append_negated_char_list(PRIV(vspace_list), options, buffer);\n        total_size += size;\n        if (buffer != NULL) buffer += size;\n        break;\n\n        case ESC_p:\n        case ESC_P:\n        ptr++;\n        if (meta_arg == ESC_p && (*ptr >> 16) == PT_ANY)\n          {\n          if (buffer != NULL)\n            {\n            buffer[0] = 0;\n            buffer[1] = get_highest_char(options);\n            buffer += 2;\n            }\n          total_size += 2;\n          }\n        break;\n        }\n      ptr++;\n      continue;\n    case META_POSIX_NEG:\n      buffer = append_non_ascii_range(options, buffer);\n      total_size += 2;\n      ptr += 2;\n      continue;\n    case META_POSIX:\n      ptr += 2;\n      continue;\n    case META_BIGVALUE:\n      /* Character literal */\n      ptr++;\n      break;\n    CLASS_END_CASES(*ptr)\n      if (*ptr >= META_END) return total_size;\n      break;\n    }\n\n    start_char = *ptr;\n\n    if (ptr[1] == META_RANGE_LITERAL || ptr[1] == META_RANGE_ESCAPED)\n      {\n      ptr += 2;\n      PCRE2_ASSERT(*ptr < META_END || *ptr == META_BIGVALUE);\n\n      if (*ptr == META_BIGVALUE) ptr++;\n\n#ifdef EBCDIC\n#error \"Missing EBCDIC support\"\n#endif\n      }\n\n#ifdef SUPPORT_UNICODE\n    if (options & PARSE_CLASS_CASELESS_UTF)\n      {\n      size = utf_caseless_extend(start_char, *ptr++, options, buffer);\n      if (buffer != NULL) buffer += size;\n      total_size += size;\n      continue;\n      }\n#endif\n\n    if (buffer != NULL)\n      {\n      buffer[0] = start_char;\n      buffer[1] = *ptr;\n      buffer += 2;\n      }\n\n    ptr++;\n    total_size += 2;\n  }\n\n  return total_size;\n}\n\n/* Extra uint32_t values for storing the lengths of range lists in\nthe worst case. Two uint32_t lengths and a range end for a range\nstarting before 255 */\n#define CHAR_LIST_EXTRA_SIZE 3\n\n/* Starting character values for each character list. */\n\nstatic const uint32_t char_list_starts[] = {\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  XCL_CHAR_LIST_HIGH_32_START,\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 32 || defined SUPPORT_UNICODE\n  XCL_CHAR_LIST_LOW_32_START,\n#endif\n  XCL_CHAR_LIST_HIGH_16_START,\n  /* Must be terminated by XCL_CHAR_LIST_LOW_16_START,\n  which also represents the end of the bitset. */\n  XCL_CHAR_LIST_LOW_16_START,\n};\n\nstatic class_ranges *\ncompile_optimize_class(uint32_t *start_ptr, uint32_t options,\n  uint32_t xoptions, compile_block *cb)\n{\nclass_ranges* cranges;\nuint32_t *ptr;\nuint32_t *buffer;\nuint32_t *dst;\nuint32_t class_options = 0;\nsize_t range_list_size = 0, total_size, i;\nuint32_t tmp1, tmp2;\nconst uint32_t *char_list_next;\nuint16_t *next_char;\nuint32_t char_list_start, char_list_end;\nuint32_t range_start, range_end;\n\n#ifdef SUPPORT_UNICODE\nif (options & PCRE2_UTF)\n  class_options |= PARSE_CLASS_UTF;\n\nif ((options & PCRE2_CASELESS) && (options & (PCRE2_UTF|PCRE2_UCP)))\n  class_options |= PARSE_CLASS_CASELESS_UTF;\n\nif (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT)\n  class_options |= PARSE_CLASS_RESTRICTED_UTF;\n\nif (xoptions & PCRE2_EXTRA_TURKISH_CASING)\n  class_options |= PARSE_CLASS_TURKISH_UTF;\n#else\n(void)options;   /* Avoid compiler warning. */\n(void)xoptions;  /* Avoid compiler warning. */\n#endif\n\n/* Compute required space for the range. */\n\nrange_list_size = parse_class(start_ptr, class_options, NULL);\nPCRE2_ASSERT((range_list_size & 0x1) == 0);\n\n/* Allocate buffer. The total_size also represents the end of the buffer. */\n\ntotal_size = range_list_size +\n   ((range_list_size >= 2) ? CHAR_LIST_EXTRA_SIZE : 0);\n\ncranges = cb->cx->memctl.malloc(\n  sizeof(class_ranges) + total_size * sizeof(uint32_t),\n  cb->cx->memctl.memory_data);\n\nif (cranges == NULL) return NULL;\n\ncranges->header.next = NULL;\n#ifdef PCRE2_DEBUG\ncranges->header.type = CDATA_CRANGE;\n#endif\ncranges->range_list_size = (uint16_t)range_list_size;\ncranges->char_lists_types = 0;\ncranges->char_lists_size = 0;\ncranges->char_lists_start = 0;\n\nif (range_list_size == 0) return cranges;\n\nbuffer = (uint32_t*)(cranges + 1);\nparse_class(start_ptr, class_options, buffer);\n\n/* Using <= instead of == to help static analysis. */\nif (range_list_size <= 2) return cranges;\n\n/* In-place sorting of ranges. */\n\ni = (((range_list_size >> 2) - 1) << 1);\nwhile (TRUE)\n  {\n  do_heapify(buffer, range_list_size, i);\n  if (i == 0) break;\n  i -= 2;\n  }\n\ni = range_list_size - 2;\nwhile (TRUE)\n  {\n  tmp1 = buffer[i];\n  tmp2 = buffer[i + 1];\n  buffer[i] = buffer[0];\n  buffer[i + 1] = buffer[1];\n  buffer[0] = tmp1;\n  buffer[1] = tmp2;\n\n  do_heapify(buffer, i, 0);\n  if (i == 0) break;\n  i -= 2;\n  }\n\n/* Merge ranges whenever possible. */\ndst = buffer;\nptr = buffer + 2;\nrange_list_size -= 2;\n\n/* The second condition is a very rare corner case, where the end of the last\nrange is the maximum character. This range cannot be extended further. */\n\nwhile (range_list_size > 0 && dst[1] != ~(uint32_t)0)\n  {\n  if (dst[1] + 1 < ptr[0])\n    {\n    dst += 2;\n    dst[0] = ptr[0];\n    dst[1] = ptr[1];\n    }\n  else if (dst[1] < ptr[1]) dst[1] = ptr[1];\n\n  ptr += 2;\n  range_list_size -= 2;\n  }\n\nPCRE2_ASSERT(dst[1] <= get_highest_char(class_options));\n\n/* When the number of ranges are less than six,\nthey are not converted to range lists. */\n\nptr = buffer;\nwhile (ptr < dst && ptr[1] < 0x100) ptr += 2;\nif (dst - ptr < (2 * (6 - 1)))\n  {\n  cranges->range_list_size = (uint16_t)(dst + 2 - buffer);\n  return cranges;\n  }\n\n/* Compute character lists structures. */\n\nchar_list_next = char_list_starts;\nchar_list_start = *char_list_next++;\n#if PCRE2_CODE_UNIT_WIDTH == 32\nchar_list_end = XCL_CHAR_LIST_HIGH_32_END;\n#elif defined SUPPORT_UNICODE\nchar_list_end = XCL_CHAR_LIST_LOW_32_END;\n#else\nchar_list_end = XCL_CHAR_LIST_HIGH_16_END;\n#endif\nnext_char = (uint16_t*)(buffer + total_size);\n\ntmp1 = 0;\ntmp2 = ((sizeof(char_list_starts) / sizeof(uint32_t)) - 1) * XCL_TYPE_BIT_LEN;\nPCRE2_ASSERT(tmp2 <= 3 * XCL_TYPE_BIT_LEN && tmp2 >= XCL_TYPE_BIT_LEN);\nrange_start = dst[0];\nrange_end = dst[1];\n\nwhile (TRUE)\n  {\n  if (range_start >= char_list_start)\n    {\n    if (range_start == range_end || range_end < char_list_end)\n      {\n      tmp1++;\n      next_char--;\n\n      if (char_list_start < XCL_CHAR_LIST_LOW_32_START)\n        *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END);\n      else\n        *(uint32_t*)(--next_char) =\n          (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END;\n      }\n\n    if (range_start < range_end)\n      {\n      if (range_start > char_list_start)\n        {\n        tmp1++;\n        next_char--;\n\n        if (char_list_start < XCL_CHAR_LIST_LOW_32_START)\n          *next_char = (uint16_t)(range_start << XCL_CHAR_SHIFT);\n        else\n          *(uint32_t*)(--next_char) = (range_start << XCL_CHAR_SHIFT);\n        }\n      else\n        cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2;\n      }\n\n    PCRE2_ASSERT((uint32_t*)next_char >= dst + 2);\n\n    if (dst > buffer)\n      {\n      dst -= 2;\n      range_start = dst[0];\n      range_end = dst[1];\n      continue;\n      }\n\n    range_start = 0;\n    range_end = 0;\n    }\n\n  if (range_end >= char_list_start)\n    {\n    PCRE2_ASSERT(range_start < char_list_start);\n\n    if (range_end < char_list_end)\n      {\n      tmp1++;\n      next_char--;\n\n      if (char_list_start < XCL_CHAR_LIST_LOW_32_START)\n        *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END);\n      else\n        *(uint32_t*)(--next_char) =\n          (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END;\n\n      PCRE2_ASSERT((uint32_t*)next_char >= dst + 2);\n      }\n\n    cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2;\n    }\n\n  if (tmp1 >= XCL_ITEM_COUNT_MASK)\n    {\n    cranges->char_lists_types |= XCL_ITEM_COUNT_MASK << tmp2;\n    next_char--;\n\n    if (char_list_start < XCL_CHAR_LIST_LOW_32_START)\n      *next_char = (uint16_t)tmp1;\n    else\n      *(uint32_t*)(--next_char) = tmp1;\n    }\n  else\n    cranges->char_lists_types |= tmp1 << tmp2;\n\n  if (range_start < XCL_CHAR_LIST_LOW_16_START) break;\n\n  PCRE2_ASSERT(tmp2 >= XCL_TYPE_BIT_LEN);\n  char_list_end = char_list_start - 1;\n  char_list_start = *char_list_next++;\n  tmp1 = 0;\n  tmp2 -= XCL_TYPE_BIT_LEN;\n  }\n\nif (dst[0] < XCL_CHAR_LIST_LOW_16_START) dst += 2;\nPCRE2_ASSERT((uint16_t*)dst <= next_char);\n\ncranges->char_lists_size =\n  (size_t)((uint8_t*)(buffer + total_size) - (uint8_t*)next_char);\ncranges->char_lists_start = (size_t)((uint8_t*)next_char - (uint8_t*)buffer);\ncranges->range_list_size = (uint16_t)(dst - buffer);\nreturn cranges;\n}\n\n#endif /* SUPPORT_WIDE_CHARS */\n\n#ifdef SUPPORT_UNICODE\n\nvoid PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated,\n  uint8_t *classbits)\n{\n/* Update PRIV(xclass) when this function is changed. */\nint c, chartype;\nconst ucd_record *prop;\nuint32_t gentype;\nBOOL set_bit;\n\nif (ptype == PT_ANY)\n  {\n  if (!negated) memset(classbits, 0xff, 32);\n  return;\n  }\n\nfor (c = 0; c < 256; c++)\n  {\n  prop = GET_UCD(c);\n  set_bit = FALSE;\n  (void)set_bit;\n\n  switch (ptype)\n    {\n    case PT_LAMP:\n    chartype = prop->chartype;\n    set_bit = (chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt);\n    break;\n\n    case PT_GC:\n    set_bit = (PRIV(ucp_gentype)[prop->chartype] == pdata);\n    break;\n\n    case PT_PC:\n    set_bit = (prop->chartype == pdata);\n    break;\n\n    case PT_SC:\n    set_bit = (prop->script == pdata);\n    break;\n\n    case PT_SCX:\n    set_bit = (prop->script == pdata ||\n      MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), pdata) != 0);\n    break;\n\n    case PT_ALNUM:\n    gentype = PRIV(ucp_gentype)[prop->chartype];\n    set_bit = (gentype == ucp_L || gentype == ucp_N);\n    break;\n\n    case PT_SPACE:    /* Perl space */\n    case PT_PXSPACE:  /* POSIX space */\n    switch(c)\n      {\n      HSPACE_BYTE_CASES:\n      VSPACE_BYTE_CASES:\n      set_bit = TRUE;\n      break;\n\n      default:\n      set_bit = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z);\n      break;\n      }\n    break;\n\n    case PT_WORD:\n    chartype = prop->chartype;\n    gentype = PRIV(ucp_gentype)[chartype];\n    set_bit = (gentype == ucp_L || gentype == ucp_N ||\n               chartype == ucp_Mn || chartype == ucp_Pc);\n    break;\n\n    case PT_UCNC:\n    set_bit = (c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n               c == CHAR_GRAVE_ACCENT || c >= 0xa0);\n    break;\n\n    case PT_BIDICL:\n    set_bit = (UCD_BIDICLASS_PROP(prop) == pdata);\n    break;\n\n    case PT_BOOL:\n    set_bit = MAPBIT(PRIV(ucd_boolprop_sets) +\n                     UCD_BPROPS_PROP(prop), pdata) != 0;\n    break;\n\n    case PT_PXGRAPH:\n    chartype = prop->chartype;\n    gentype = PRIV(ucp_gentype)[chartype];\n    set_bit = (gentype != ucp_Z && (gentype != ucp_C || chartype == ucp_Cf));\n    break;\n\n    case PT_PXPRINT:\n    chartype = prop->chartype;\n    set_bit = (chartype != ucp_Zl && chartype != ucp_Zp &&\n       (PRIV(ucp_gentype)[chartype] != ucp_C || chartype == ucp_Cf));\n    break;\n\n    case PT_PXPUNCT:\n    gentype = PRIV(ucp_gentype)[prop->chartype];\n    set_bit = (gentype == ucp_P || (c < 128 && gentype == ucp_S));\n    break;\n\n    default:\n    PCRE2_ASSERT(ptype == PT_PXXDIGIT);\n    set_bit = (c >= CHAR_0 && c <= CHAR_9) ||\n              (c >= CHAR_A && c <= CHAR_F) ||\n              (c >= CHAR_a && c <= CHAR_f);\n    break;\n    }\n\n  if (negated) set_bit = !set_bit;\n  if (set_bit) *classbits |= (uint8_t)(1 << (c & 0x7));\n  if ((c & 0x7) == 0x7) classbits++;\n  }\n}\n\n#endif /* SUPPORT_UNICODE */\n\n\n\n#ifdef SUPPORT_WIDE_CHARS\n\n/*************************************************\n*           XClass related properties            *\n*************************************************/\n\n/* XClass needs to be generated. */\n#define XCLASS_REQUIRED 0x1\n/* XClass has 8 bit character. */\n#define XCLASS_HAS_8BIT_CHARS 0x2\n/* XClass has properties. */\n#define XCLASS_HAS_PROPS 0x4\n/* XClass has character lists. */\n#define XCLASS_HAS_CHAR_LISTS 0x8\n/* XClass matches to all >= 256 characters. */\n#define XCLASS_HIGH_ANY 0x10\n\n#endif\n\n\n/*************************************************\n*   Internal entry point for add range to class  *\n*************************************************/\n\n/* This function sets the overall range for characters < 256.\nIt also handles non-utf case folding.\n\nArguments:\n  options       the options bits\n  xoptions      the extra options bits\n  cb            compile data\n  start         start of range character\n  end           end of range character\n\nReturns:        cb->classbits is updated\n*/\n\nstatic void\nadd_to_class(uint32_t options, uint32_t xoptions, compile_block *cb,\n  uint32_t start, uint32_t end)\n{\nuint8_t *classbits = cb->classbits.classbits;\nuint32_t c, byte_start, byte_end;\nuint32_t classbits_end = (end <= 0xff ? end : 0xff);\n\n#ifndef SUPPORT_UNICODE\n(void)xoptions; /* Avoid compiler warning. */\n#endif\n\n/* If caseless matching is required, scan the range and process alternate\ncases. In Unicode, there are 8-bit characters that have alternate cases that\nare greater than 255 and vice-versa (though these may be ignored if caseless\nrestriction is in force). Sometimes we can just extend the original range. */\n\nif ((options & PCRE2_CASELESS) != 0)\n  {\n#ifdef SUPPORT_UNICODE\n  /* UTF mode. This branch is taken if we don't support wide characters (e.g.\n  8-bit library, without UTF), but we do treat those characters as Unicode\n  (if UCP flag is set). In this case, we only need to expand the character class\n  set to include the case pairs which are in the 0-255 codepoint range. */\n  if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0)\n    {\n      BOOL turkish_i = (xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) ==\n        PCRE2_EXTRA_TURKISH_CASING;\n      if (start < 128)\n        {\n        uint32_t lo_end = (classbits_end < 127 ? classbits_end : 127);\n        for (c = start; c <= lo_end; c++)\n          {\n          if (turkish_i && UCD_ANY_I(c)) continue;\n          SETBIT(classbits, cb->fcc[c]);\n          }\n        }\n      if (classbits_end >= 128)\n        {\n        uint32_t hi_start = (start > 128 ? start : 128);\n        for (c = hi_start; c <= classbits_end; c++)\n          {\n          uint32_t co = UCD_OTHERCASE(c);\n          if (co <= 0xff) SETBIT(classbits, co);\n          }\n        }\n    }\n\n  else\n#endif  /* SUPPORT_UNICODE */\n\n  /* Not UTF mode */\n    {\n    for (c = start; c <= classbits_end; c++)\n      SETBIT(classbits, cb->fcc[c]);\n    }\n  }\n\n/* Use the bitmap for characters < 256. Otherwise use extra data. */\n\nbyte_start = (start + 7) >> 3;\nbyte_end = (classbits_end + 1) >> 3;\n\nif (byte_start >= byte_end)\n  {\n  for (c = start; c <= classbits_end; c++)\n    /* Regardless of start, c will always be <= 255. */\n    SETBIT(classbits, c);\n  return;\n  }\n\nfor (c = byte_start; c < byte_end; c++)\n  classbits[c] = 0xff;\n\nbyte_start <<= 3;\nbyte_end <<= 3;\n\nfor (c = start; c < byte_start; c++)\n  SETBIT(classbits, c);\n\nfor (c = byte_end; c <= classbits_end; c++)\n  SETBIT(classbits, c);\n}\n\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n/*************************************************\n*   Internal entry point for add list to class   *\n*************************************************/\n\n/* This function is used for adding a list of horizontal or vertical whitespace\ncharacters to a class. The list must be in order so that ranges of characters\ncan be detected and handled appropriately. This function sets the overall range\nso that the internal functions can try to avoid duplication when handling\ncase-independence.\n\nArguments:\n  options       the options bits\n  xoptions      the extra options bits\n  cb            contains pointers to tables etc.\n  p             points to row of 32-bit values, terminated by NOTACHAR\n\nReturns:        cb->classbits is updated\n*/\n\nstatic void\nadd_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb,\n  const uint32_t *p)\n{\nwhile (p[0] < 256)\n  {\n  unsigned int n = 0;\n\n  while(p[n+1] == p[0] + n + 1) n++;\n  add_to_class(options, xoptions, cb, p[0], p[n]);\n\n  p += n + 1;\n  }\n}\n\n\n\n/*************************************************\n*    Add characters not in a list to a class     *\n*************************************************/\n\n/* This function is used for adding the complement of a list of horizontal or\nvertical whitespace to a class. The list must be in order.\n\nArguments:\n  options       the options bits\n  xoptions      the extra options bits\n  cb            contains pointers to tables etc.\n  p             points to row of 32-bit values, terminated by NOTACHAR\n\nReturns:        cb->classbits is updated\n*/\n\nstatic void\nadd_not_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb,\n  const uint32_t *p)\n{\nif (p[0] > 0)\n  add_to_class(options, xoptions, cb, 0, p[0] - 1);\nwhile (p[0] < 256)\n  {\n  while (p[1] == p[0] + 1) p++;\n  add_to_class(options, xoptions, cb, p[0] + 1, (p[1] > 255) ? 255 : p[1] - 1);\n  p++;\n  }\n}\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n\n\n\n/*************************************************\n*  Main entry-point to compile a character class *\n*************************************************/\n\n/* This function consumes a \"leaf\", which is a set of characters that will\nbecome a single OP_CLASS OP_NCLASS, OP_XCLASS, or OP_ALLANY. */\n\nuint32_t *\nPRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions,\n  uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap,\n  int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr)\n{\nuint32_t *pptr = start_ptr;\nPCRE2_UCHAR *code = *pcode;\nBOOL should_flip_negation;\nconst uint8_t *cbits = cb->cbits;\n/* Some functions such as add_to_class() or eclass processing\nexpects that the bitset is stored in cb->classbits.classbits. */\nuint8_t *const classbits = cb->classbits.classbits;\n\n#ifdef SUPPORT_UNICODE\nBOOL utf = (options & PCRE2_UTF) != 0;\n#else  /* No Unicode support */\nBOOL utf = FALSE;\n#endif\n\n/* Helper variables for OP_XCLASS opcode (for characters > 255). */\n\n#ifdef SUPPORT_WIDE_CHARS\nuint32_t xclass_props;\nPCRE2_UCHAR *class_uchardata;\nclass_ranges* cranges;\n#else\n(void)has_bitmap;    /* Avoid compiler warning. */\n(void)errorcodeptr;  /* Avoid compiler warning. */\n(void)lengthptr;     /* Avoid compiler warning. */\n#endif\n\n/* If an XClass contains a negative special such as \\S, we need to flip the\nnegation flag at the end, so that support for characters > 255 works correctly\n(they are all included in the class). An XClass may need to insert specific\nmatching or non-matching code for wide characters.\n*/\n\nshould_flip_negation = FALSE;\n\n/* XClass will be used when characters > 255 might match. */\n\n#ifdef SUPPORT_WIDE_CHARS\nxclass_props = 0;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\ncranges = NULL;\n\nif (utf)\n#endif\n  {\n  if (lengthptr != NULL)\n    {\n    cranges = compile_optimize_class(pptr, options, xoptions, cb);\n\n    if (cranges == NULL)\n      {\n      *errorcodeptr = ERR21;\n      return NULL;\n      }\n\n    /* Caching the pre-processed character ranges. */\n    if (cb->last_data != NULL)\n      cb->last_data->next = &cranges->header;\n    else\n      cb->first_data = &cranges->header;\n\n    cb->last_data = &cranges->header;\n    }\n  else\n    {\n    /* Reuse the pre-processed character ranges. */\n    cranges = (class_ranges*)cb->first_data;\n    PCRE2_ASSERT(cranges != NULL && cranges->header.type == CDATA_CRANGE);\n    cb->first_data = cranges->header.next;\n    }\n\n  if (cranges->range_list_size > 0)\n    {\n    const uint32_t *ranges = (const uint32_t*)(cranges + 1);\n\n    if (ranges[0] <= 255)\n      xclass_props |= XCLASS_HAS_8BIT_CHARS;\n\n    if (ranges[cranges->range_list_size - 1] == GET_MAX_CHAR_VALUE(utf) &&\n        ranges[cranges->range_list_size - 2] <= 256)\n      xclass_props |= XCLASS_HIGH_ANY;\n    }\n  }\n\nclass_uchardata = code + LINK_SIZE + 2;   /* For XCLASS items */\n#endif /* SUPPORT_WIDE_CHARS */\n\n/* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map\nin a temporary bit of memory, in case the class contains fewer than two\n8-bit characters because in that case the compiled code doesn't use the bit\nmap. */\n\nmemset(classbits, 0, 32);\n\n/* Process items until end_ptr is reached. */\n\nwhile (TRUE)\n  {\n  uint32_t meta = *(pptr++);\n  BOOL local_negate;\n  int posix_class;\n  int taboffset, tabopt;\n  class_bits_storage pbits;\n  uint32_t escape, c;\n\n  /* Handle POSIX classes such as [:alpha:] etc. */\n  switch (META_CODE(meta))\n    {\n    case META_POSIX:\n    case META_POSIX_NEG:\n\n    local_negate = (meta == META_POSIX_NEG);\n    posix_class = *(pptr++);\n\n    if (local_negate) should_flip_negation = TRUE;  /* Note negative special */\n\n    /* If matching is caseless, upper and lower are converted to alpha.\n    This relies on the fact that the class table starts with alpha,\n    lower, upper as the first 3 entries. */\n\n    if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2)\n      posix_class = 0;\n\n    /* When PCRE2_UCP is set, some of the POSIX classes are converted to\n    different escape sequences that use Unicode properties \\p or \\P.\n    Others that are not available via \\p or \\P have to generate\n    XCL_PROP/XCL_NOTPROP directly, which is done here. */\n\n#ifdef SUPPORT_UNICODE\n    /* TODO This entire block of code here appears to be unreachable!? I simply\n    can't see how it can be hit, given that the frontend parser doesn't emit\n    META_POSIX for GRAPH/PRINT/PUNCT when UCP is set. */\n    if ((options & PCRE2_UCP) != 0 &&\n        (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0)\n      {\n      uint32_t ptype;\n\n      switch(posix_class)\n        {\n        case PC_GRAPH:\n        case PC_PRINT:\n        case PC_PUNCT:\n        ptype = (posix_class == PC_GRAPH)? PT_PXGRAPH :\n                (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT;\n\n        PRIV(update_classbits)(ptype, 0, local_negate, classbits);\n\n        if ((xclass_props & XCLASS_HIGH_ANY) == 0)\n          {\n          if (lengthptr != NULL)\n            *lengthptr += 3;\n          else\n            {\n            *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;\n            *class_uchardata++ = (PCRE2_UCHAR)ptype;\n            *class_uchardata++ = 0;\n            }\n          xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS;\n          }\n        continue;\n\n        /* For the other POSIX classes (ex: ascii) we are going to\n        fall through to the non-UCP case and build a bit map for\n        characters with code points less than 256. However, if we are in\n        a negated POSIX class, characters with code points greater than\n        255 must either all match or all not match, depending on whether\n        the whole class is not or is negated. For example, for\n        [[:^ascii:]... they must all match, whereas for [^[:^ascii:]...\n        they must not.\n\n        In the special case where there are no xclass items, this is\n        automatically handled by the use of OP_CLASS or OP_NCLASS, but an\n        explicit range is needed for OP_XCLASS. Setting a flag here\n        causes the range to be generated later when it is known that\n        OP_XCLASS is required. In the 8-bit library this is relevant only in\n        utf mode, since no wide characters can exist otherwise. */\n\n        default:\n        break;\n        }\n      }\n#endif  /* SUPPORT_UNICODE */\n\n    /* In the non-UCP case, or when UCP makes no difference, we build the\n    bit map for the POSIX class in a chunk of local store because we may\n    be adding and subtracting from it, and we don't want to subtract bits\n    that may be in the main map already. At the end we or the result into\n    the bit map that is being built. */\n\n    posix_class *= 3;\n\n    /* Copy in the first table (always present) */\n\n    memcpy(pbits.classbits, cbits + PRIV(posix_class_maps)[posix_class], 32);\n\n    /* If there is a second table, add or remove it as required. */\n\n    taboffset = PRIV(posix_class_maps)[posix_class + 1];\n    tabopt = PRIV(posix_class_maps)[posix_class + 2];\n\n    if (taboffset >= 0)\n      {\n      if (tabopt >= 0)\n        for (int i = 0; i < 32; i++)\n          pbits.classbits[i] |= cbits[i + taboffset];\n      else\n        for (int i = 0; i < 32; i++)\n          pbits.classbits[i] &= (uint8_t)(~cbits[i + taboffset]);\n      }\n\n    /* Now see if we need to remove any special characters. An option\n    value of 1 removes vertical space and 2 removes underscore. */\n\n    if (tabopt < 0) tabopt = -tabopt;\n#ifdef EBCDIC\n      {\n      uint8_t posix_vertical[4] = { CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR };\n      uint8_t posix_underscore = CHAR_UNDERSCORE;\n      uint8_t *chars = NULL;\n      int n = 0;\n\n      if (tabopt == 1) { chars = posix_vertical; n = 4; }\n      else if (tabopt == 2) { chars = &posix_underscore; n = 1; }\n\n      for (; n > 0; ++chars, --n)\n        pbits.classbits[*chars/8] &= ~(1u << (*chars&7));\n      }\n#else\n    if (tabopt == 1) pbits.classbits[1] &= ~0x3c;\n    else if (tabopt == 2) pbits.classbits[11] &= 0x7f;\n#endif\n\n    /* Add the POSIX table or its complement into the main table that is\n    being built and we are done. */\n\n      {\n      uint32_t *classwords = cb->classbits.classwords;\n\n      if (local_negate)\n        for (int i = 0; i < 8; i++)\n          classwords[i] |= (uint32_t)(~pbits.classwords[i]);\n      else\n        for (int i = 0; i < 8; i++)\n          classwords[i] |= pbits.classwords[i];\n      }\n\n#ifdef SUPPORT_WIDE_CHARS\n    /* Every class contains at least one < 256 character. */\n    xclass_props |= XCLASS_HAS_8BIT_CHARS;\n#endif\n    continue;               /* End of POSIX handling */\n\n    /* Other than POSIX classes, the only items we should encounter are\n    \\d-type escapes and literal characters (possibly as ranges). */\n    case META_BIGVALUE:\n    meta = *(pptr++);\n    break;\n\n    case META_ESCAPE:\n    escape = META_DATA(meta);\n\n    switch(escape)\n      {\n      case ESC_d:\n      for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit];\n      break;\n\n      case ESC_D:\n      should_flip_negation = TRUE;\n      for (int i = 0; i < 32; i++)\n        classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]);\n      break;\n\n      case ESC_w:\n      for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word];\n      break;\n\n      case ESC_W:\n      should_flip_negation = TRUE;\n      for (int i = 0; i < 32; i++)\n        classbits[i] |= (uint8_t)(~cbits[i+cbit_word]);\n      break;\n\n      /* Perl 5.004 onwards omitted VT from \\s, but restored it at Perl\n      5.18. Before PCRE 8.34, we had to preserve the VT bit if it was\n      previously set by something earlier in the character class.\n      Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so\n      we could just adjust the appropriate bit. From PCRE 8.34 we no\n      longer treat \\s and \\S specially. */\n\n      case ESC_s:\n      for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space];\n      break;\n\n      case ESC_S:\n      should_flip_negation = TRUE;\n      for (int i = 0; i < 32; i++)\n        classbits[i] |= (uint8_t)(~cbits[i+cbit_space]);\n      break;\n\n      /* When adding the horizontal or vertical space lists to a class, or\n      their complements, disable PCRE2_CASELESS, because it justs wastes\n      time, and in the \"not-x\" UTF cases can create unwanted duplicates in\n      the XCLASS list (provoked by characters that have more than one other\n      case and by both cases being in the same \"not-x\" sublist). */\n\n      case ESC_h:\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n      if (cranges != NULL) break;\n#endif\n      add_list_to_class(options & ~PCRE2_CASELESS, xoptions,\n        cb, PRIV(hspace_list));\n#else\n      PCRE2_ASSERT(cranges != NULL);\n#endif\n      break;\n\n      case ESC_H:\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n      if (cranges != NULL) break;\n#endif\n      add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions,\n        cb, PRIV(hspace_list));\n#else\n      PCRE2_ASSERT(cranges != NULL);\n#endif\n      break;\n\n      case ESC_v:\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n      if (cranges != NULL) break;\n#endif\n      add_list_to_class(options & ~PCRE2_CASELESS, xoptions,\n        cb, PRIV(vspace_list));\n#else\n      PCRE2_ASSERT(cranges != NULL);\n#endif\n      break;\n\n      case ESC_V:\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n      if (cranges != NULL) break;\n#endif\n      add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions,\n        cb, PRIV(vspace_list));\n#else\n      PCRE2_ASSERT(cranges != NULL);\n#endif\n      break;\n\n      /* If Unicode is not supported, \\P and \\p are not allowed and are\n      faulted at parse time, so will never appear here. */\n\n#ifdef SUPPORT_UNICODE\n      case ESC_p:\n      case ESC_P:\n        {\n        uint32_t ptype = *pptr >> 16;\n        uint32_t pdata = *(pptr++) & 0xffff;\n\n        /* The \"Any\" is processed by PRIV(update_classbits)(). */\n        if (ptype == PT_ANY)\n          {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n          if (!utf && escape == ESC_p) memset(classbits, 0xff, 32);\n#endif\n          continue;\n          }\n\n        PRIV(update_classbits)(ptype, pdata, (escape == ESC_P), classbits);\n\n        if ((xclass_props & XCLASS_HIGH_ANY) == 0)\n          {\n          if (lengthptr != NULL)\n            *lengthptr += 3;\n          else\n            {\n            *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP;\n            *class_uchardata++ = ptype;\n            *class_uchardata++ = pdata;\n            }\n          xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS;\n          }\n        }\n      continue;\n#endif\n      }\n\n#ifdef SUPPORT_WIDE_CHARS\n    /* Every non-property class contains at least one < 256 character. */\n    xclass_props |= XCLASS_HAS_8BIT_CHARS;\n#endif\n    /* End handling \\d-type escapes */\n    continue;\n\n    CLASS_END_CASES(meta)\n    /* Literals. */\n    if (meta < META_END) break;\n    /* Non-literals: end of class contents. */\n    goto END_PROCESSING;\n    }\n\n  /* A literal character may be followed by a range meta. At parse time\n  there are checks for out-of-order characters, for ranges where the two\n  characters are equal, and for hyphens that cannot indicate a range. At\n  this point, therefore, no checking is needed. */\n\n  c = meta;\n\n  /* Remember if \\r or \\n were explicitly used */\n\n  if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;\n\n  /* Process a character range */\n\n  if (*pptr == META_RANGE_LITERAL || *pptr == META_RANGE_ESCAPED)\n    {\n    uint32_t d;\n\n#ifdef EBCDIC\n    BOOL range_is_literal = (*pptr == META_RANGE_LITERAL);\n#endif\n    ++pptr;\n    d = *(pptr++);\n    if (d == META_BIGVALUE) d = *(pptr++);\n\n    /* Remember an explicit \\r or \\n, and add the range to the class. */\n\n    if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n    if (cranges != NULL) continue;\n    xclass_props |= XCLASS_HAS_8BIT_CHARS;\n#endif\n\n    /* In an EBCDIC environment, Perl treats alphabetic ranges specially\n    because there are holes in the encoding, and simply using the range\n    A-Z (for example) would include the characters in the holes. This\n    applies only to literal ranges; [\\xC1-\\xE9] is different to [A-Z]. */\n\n#ifdef EBCDIC\n    if (range_is_literal &&\n         (cb->ctypes[c] & ctype_letter) != 0 &&\n         (cb->ctypes[d] & ctype_letter) != 0 &&\n         (c <= CHAR_z) == (d <= CHAR_z))\n      {\n      uint32_t uc = (d <= CHAR_z)? 0 : 64;\n      uint32_t C = c - uc;\n      uint32_t D = d - uc;\n\n      if (C <= CHAR_i)\n        {\n        add_to_class(options, xoptions, cb, C + uc,\n          ((D < CHAR_i)? D : CHAR_i) + uc);\n        C = CHAR_j;\n        }\n\n      if (C <= D && C <= CHAR_r)\n        {\n        add_to_class(options, xoptions, cb, C + uc,\n          ((D < CHAR_r)? D : CHAR_r) + uc);\n        C = CHAR_s;\n        }\n\n      if (C <= D)\n        add_to_class(options, xoptions, cb, C + uc, D + uc);\n      }\n    else\n#endif\n    /* Not an EBCDIC special range */\n\n    add_to_class(options, xoptions, cb, c, d);\n#else\n    PCRE2_ASSERT(cranges != NULL);\n#endif\n    continue;\n    }  /* End of range handling */\n\n  /* Character ranges are ignored when class_ranges is present. */\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n  if (cranges != NULL) continue;\n  xclass_props |= XCLASS_HAS_8BIT_CHARS;\n#endif\n  /* Handle a single character. */\n\n  add_to_class(options, xoptions, cb, meta, meta);\n#else\n  PCRE2_ASSERT(cranges != NULL);\n#endif\n  }   /* End of main class-processing loop */\n\nEND_PROCESSING:\n\n#ifdef SUPPORT_WIDE_CHARS\nPCRE2_ASSERT((xclass_props & XCLASS_HAS_PROPS) == 0 ||\n             (xclass_props & XCLASS_HIGH_ANY) == 0);\n\nif (cranges != NULL)\n  {\n  uint32_t *range = (uint32_t*)(cranges + 1);\n  uint32_t *end = range + cranges->range_list_size;\n\n  while (range < end && range[0] < 256)\n    {\n    PCRE2_ASSERT((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0);\n    /* Add range to bitset. If we are in UTF or UCP mode, then clear the\n    caseless bit, because the cranges handle caselessness (only) in this\n    condition; see the condition for PARSE_CLASS_CASELESS_UTF in\n    compile_optimize_class(). */\n    add_to_class(((options & (PCRE2_UTF|PCRE2_UCP)) != 0)?\n        (options & ~PCRE2_CASELESS) : options, xoptions, cb, range[0], range[1]);\n\n    if (range[1] > 255) break;\n    range += 2;\n    }\n\n  if (cranges->char_lists_size > 0)\n    {\n    /* The cranges structure is still used and freed later. */\n    PCRE2_ASSERT((xclass_props & XCLASS_HIGH_ANY) == 0);\n    xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_CHAR_LISTS;\n    }\n  else\n    {\n    if ((xclass_props & XCLASS_HIGH_ANY) != 0)\n      {\n      PCRE2_ASSERT(range + 2 == end && range[0] <= 256 &&\n        range[1] >= GET_MAX_CHAR_VALUE(utf));\n      should_flip_negation = TRUE;\n      range = end;\n      }\n\n    while (range < end)\n      {\n      uint32_t range_start = range[0];\n      uint32_t range_end = range[1];\n\n      range += 2;\n      xclass_props |= XCLASS_REQUIRED;\n\n      if (range_start < 256) range_start = 256;\n\n      if (lengthptr != NULL)\n        {\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          *lengthptr += 1;\n\n          if (range_start < range_end)\n            *lengthptr += PRIV(ord2utf)(range_start, class_uchardata);\n\n          *lengthptr += PRIV(ord2utf)(range_end, class_uchardata);\n          continue;\n          }\n#endif  /* SUPPORT_UNICODE */\n\n        *lengthptr += range_start < range_end ? 3 : 2;\n        continue;\n        }\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        if (range_start < range_end)\n          {\n          *class_uchardata++ = XCL_RANGE;\n          class_uchardata += PRIV(ord2utf)(range_start, class_uchardata);\n          }\n        else\n          *class_uchardata++ = XCL_SINGLE;\n\n        class_uchardata += PRIV(ord2utf)(range_end, class_uchardata);\n        continue;\n        }\n#endif  /* SUPPORT_UNICODE */\n\n      /* Without UTF support, character values are constrained\n      by the bit length, and can only be > 256 for 16-bit and\n      32-bit libraries. */\n#if PCRE2_CODE_UNIT_WIDTH != 8\n      if (range_start < range_end)\n        {\n        *class_uchardata++ = XCL_RANGE;\n        *class_uchardata++ = range_start;\n        }\n      else\n        *class_uchardata++ = XCL_SINGLE;\n\n      *class_uchardata++ = range_end;\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */\n      }\n\n    if (lengthptr == NULL)\n      cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data);\n    }\n  }\n#endif /* SUPPORT_WIDE_CHARS */\n\n/* If there are characters with values > 255, or Unicode property settings\n(\\p or \\P), we have to compile an extended class, with its own opcode,\nunless there were no property settings and there was a negated special such\nas \\S in the class, and PCRE2_UCP is not set, because in that case all\ncharacters > 255 are in or not in the class, so any that were explicitly\ngiven as well can be ignored.\n\nIn the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were\nwere present in a class, we either have to match or not match all wide\ncharacters (depending on whether the whole class is or is not negated).\nThis requirement is indicated by match_all_or_no_wide_chars being true.\nWe do this by including an explicit range, which works in both cases.\nThis applies only in UTF and 16-bit and 32-bit non-UTF modes, since there\ncannot be any wide characters in 8-bit non-UTF mode.\n\nWhen there *are* properties in a positive UTF-8 or any 16-bit or 32_bit\nclass where \\S etc is present without PCRE2_UCP, causing an extended class\nto be compiled, we make sure that all characters > 255 are included by\nforcing match_all_or_no_wide_chars to be true.\n\nIf, when generating an xclass, there are no characters < 256, we can omit\nthe bitmap in the actual compiled code. */\n\n#ifdef SUPPORT_WIDE_CHARS  /* Defined for 16/32 bits, or 8-bit with Unicode */\nif ((xclass_props & XCLASS_REQUIRED) != 0)\n  {\n  PCRE2_UCHAR *previous = code;\n\n  if ((xclass_props & XCLASS_HAS_CHAR_LISTS) == 0)\n    *class_uchardata++ = XCL_END;    /* Marks the end of extra data */\n  *code++ = OP_XCLASS;\n  code += LINK_SIZE;\n  *code = negate_class? XCL_NOT:0;\n  if ((xclass_props & XCLASS_HAS_PROPS) != 0) *code |= XCL_HASPROP;\n\n  /* If the map is required, move up the extra data to make room for it;\n  otherwise just move the code pointer to the end of the extra data. */\n\n  if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0 || has_bitmap != NULL)\n    {\n    if (negate_class)\n      {\n      uint32_t *classwords = cb->classbits.classwords;\n      for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i];\n      }\n\n    if (has_bitmap == NULL)\n      {\n      *code++ |= XCL_MAP;\n      (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,\n        CU2BYTES(class_uchardata - code));\n      memcpy(code, classbits, 32);\n      code = class_uchardata + (32 / sizeof(PCRE2_UCHAR));\n      }\n    else\n      {\n      code = class_uchardata;\n      if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0)\n        *has_bitmap = TRUE;\n      }\n    }\n  else code = class_uchardata;\n\n  if ((xclass_props & XCLASS_HAS_CHAR_LISTS) != 0)\n    {\n    /* Char lists size is an even number, because all items are 16 or 32\n    bit values. The character list data is always aligned to 32 bits. */\n    size_t char_lists_size = cranges->char_lists_size;\n    PCRE2_ASSERT((char_lists_size & 0x1) == 0 &&\n                 (cb->char_lists_size & 0x3) == 0);\n\n    if (lengthptr != NULL)\n      {\n      char_lists_size = CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t));\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      *lengthptr += 2 + LINK_SIZE;\n#else\n      *lengthptr += 1 + LINK_SIZE;\n#endif\n\n      cb->char_lists_size += char_lists_size;\n\n      char_lists_size /= sizeof(PCRE2_UCHAR);\n\n      /* Storage space for character lists is included\n      in the maximum pattern size. */\n      if (*lengthptr > MAX_PATTERN_SIZE ||\n          MAX_PATTERN_SIZE - *lengthptr < char_lists_size)\n        {\n        *errorcodeptr = ERR20;   /* Pattern is too large */\n        return NULL;\n        }\n      }\n    else\n      {\n      uint8_t *data;\n\n      PCRE2_ASSERT(cranges->char_lists_types <= XCL_TYPE_MASK);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      /* Encode as high / low bytes. */\n      code[0] = (uint8_t)(XCL_LIST |\n        (cranges->char_lists_types >> 8));\n      code[1] = (uint8_t)cranges->char_lists_types;\n      code += 2;\n#else\n      *code++ = (PCRE2_UCHAR)(XCL_LIST | cranges->char_lists_types);\n#endif\n\n      /* Character lists are stored in backwards direction from\n      byte code start. The non-dfa/dfa matchers can access these\n      lists using the byte code start stored in match blocks.\n      Each list is aligned to 32 bit with an optional unused\n      16 bit value at the beginning of the character list. */\n\n      cb->char_lists_size += char_lists_size;\n      data = (uint8_t*)cb->start_code - cb->char_lists_size;\n\n      memcpy(data, (uint8_t*)(cranges + 1) + cranges->char_lists_start,\n        char_lists_size);\n\n      /* Since character lists total size is less than MAX_PATTERN_SIZE,\n      their starting offset fits into a value which size is LINK_SIZE. */\n\n      char_lists_size = cb->char_lists_size;\n      PUT(code, 0, (uint32_t)(char_lists_size >> 1));\n      code += LINK_SIZE;\n\n#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND\n      if ((char_lists_size & 0x2) != 0)\n        {\n        /* In debug the unused 16 bit value is set\n        to a fixed value and marked unused. */\n        ((uint16_t*)data)[-1] = 0x5555;\n#ifdef SUPPORT_VALGRIND\n        VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2);\n#endif\n        }\n#endif\n\n      cb->char_lists_size =\n        CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t));\n\n      cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data);\n      }\n    }\n\n  /* Now fill in the complete length of the item */\n\n  PUT(previous, 1, (int)(code - previous));\n  goto DONE;   /* End of class handling */\n  }\n#endif  /* SUPPORT_WIDE_CHARS */\n\n/* If there are no characters > 255, or they are all to be included or\nexcluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the\nwhole class was negated and whether there were negative specials such as \\S\n(non-UCP) in the class. Then copy the 32-byte map into the code vector,\nnegating it if necessary. */\n\nif (negate_class)\n  {\n  uint32_t *classwords = cb->classbits.classwords;\n\n  for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i];\n  }\n\nif ((SELECT_VALUE8(!utf, 0) || negate_class != should_flip_negation) &&\n    cb->classbits.classwords[0] == ~(uint32_t)0)\n  {\n  const uint32_t *classwords = cb->classbits.classwords;\n  int i;\n\n  for (i = 0; i < 8; i++)\n    if (classwords[i] != ~(uint32_t)0) break;\n\n  if (i == 8)\n    {\n    *code++ = OP_ALLANY;\n    goto DONE;   /* End of class handling */\n    }\n  }\n\n*code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;\nmemcpy(code, classbits, 32);\ncode += 32 / sizeof(PCRE2_UCHAR);\n\nDONE:\n*pcode = code;\nreturn pptr - 1;\n}\n\n\n\n/* ===================================================================*/\n/* Here follows a block of ECLASS-compiling functions. You may well want to\nread them from top to bottom; they are ordered from leafmost (at the top) to\noutermost parser (at the bottom of the file). */\n\n/* This function folds one operand using the negation operator.\nThe new, combined chunk of stack code is written out to *pop_info. */\n\nstatic void\nfold_negation(eclass_op_info *pop_info, PCRE2_SIZE *lengthptr,\n  BOOL preserve_classbits)\n{\n/* If the chunk of stack code is already composed of multiple ops, we won't\ndescend in and try and propagate the negation down the tree. (That would lead\nto O(n^2) compile-time, which could be exploitable with a malicious regex -\nalthough maybe that's not really too much of a worry in a library that offers\nan exponential-time matching function!) */\n\nif (pop_info->op_single_type == 0)\n  {\n  if (lengthptr != NULL)\n    *lengthptr += 1;\n  else\n    pop_info->code_start[pop_info->length] = ECL_NOT;\n  pop_info->length += 1;\n  }\n\n/* Otherwise, it's a nice single-op item, so we can easily fold in the negation\nwithout needing to produce an ECL_NOT. */\n\nelse if (pop_info->op_single_type == ECL_ANY ||\n         pop_info->op_single_type == ECL_NONE)\n  {\n  pop_info->op_single_type = (pop_info->op_single_type == ECL_NONE)?\n      ECL_ANY : ECL_NONE;\n  if (lengthptr == NULL)\n    *(pop_info->code_start) = pop_info->op_single_type;\n  }\nelse\n  {\n  PCRE2_ASSERT(pop_info->op_single_type == ECL_XCLASS &&\n               pop_info->length >= 1 + LINK_SIZE + 1);\n  if (lengthptr == NULL)\n    pop_info->code_start[1 + LINK_SIZE] ^= XCL_NOT;\n  }\n\nif (!preserve_classbits)\n  {\n  for (int i = 0; i < 8; i++)\n    pop_info->bits.classwords[i] = ~pop_info->bits.classwords[i];\n  }\n}\n\n\n\n/* This function folds together two operands using a binary operator.\nThe new, combined chunk of stack code is written out to *lhs_op_info. */\n\nstatic void\nfold_binary(int op, eclass_op_info *lhs_op_info, eclass_op_info *rhs_op_info,\n  PCRE2_SIZE *lengthptr)\n{\nswitch (op)\n  {\n  /* ECL_AND truth table:\n\n     LHS  RHS  RESULT\n     ----------------\n     ANY  *    RHS\n     *    ANY  LHS\n     NONE *    NONE\n     *    NONE NONE\n     X    Y    X & Y\n  */\n\n  case ECL_AND:\n  if (rhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* no-op: drop the RHS */\n    }\n  else if (lhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* no-op: drop the LHS, and memmove the RHS into its place */\n    if (lengthptr == NULL)\n      memmove(lhs_op_info->code_start, rhs_op_info->code_start,\n              CU2BYTES(rhs_op_info->length));\n    lhs_op_info->length = rhs_op_info->length;\n    lhs_op_info->op_single_type = rhs_op_info->op_single_type;\n    }\n  else if (rhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* the result is ECL_NONE: write into the LHS */\n    if (lengthptr == NULL)\n      lhs_op_info->code_start[0] = ECL_NONE;\n    lhs_op_info->length = 1;\n    lhs_op_info->op_single_type = ECL_NONE;\n    }\n  else if (lhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* the result is ECL_NONE: drop the RHS */\n    }\n  else\n    {\n    /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */\n    if (lengthptr != NULL)\n      *lengthptr += 1;\n    else\n      {\n      PCRE2_ASSERT(rhs_op_info->code_start ==\n          lhs_op_info->code_start + lhs_op_info->length);\n      rhs_op_info->code_start[rhs_op_info->length] = ECL_AND;\n      }\n    lhs_op_info->length += rhs_op_info->length + 1;\n    lhs_op_info->op_single_type = 0;\n    }\n\n  for (int i = 0; i < 8; i++)\n    lhs_op_info->bits.classwords[i] &= rhs_op_info->bits.classwords[i];\n  break;\n\n  /* ECL_OR truth table:\n\n     LHS  RHS  RESULT\n     ----------------\n     ANY  *    ANY\n     *    ANY  ANY\n     NONE *    RHS\n     *    NONE LHS\n     X    Y    X | Y\n  */\n\n  case ECL_OR:\n  if (rhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* no-op: drop the RHS */\n    }\n  else if (lhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* no-op: drop the LHS, and memmove the RHS into its place */\n    if (lengthptr == NULL)\n      memmove(lhs_op_info->code_start, rhs_op_info->code_start,\n              CU2BYTES(rhs_op_info->length));\n    lhs_op_info->length = rhs_op_info->length;\n    lhs_op_info->op_single_type = rhs_op_info->op_single_type;\n    }\n  else if (rhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* the result is ECL_ANY: write into the LHS */\n    if (lengthptr == NULL)\n      lhs_op_info->code_start[0] = ECL_ANY;\n    lhs_op_info->length = 1;\n    lhs_op_info->op_single_type = ECL_ANY;\n    }\n  else if (lhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* the result is ECL_ANY: drop the RHS */\n    }\n  else\n    {\n    /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */\n    if (lengthptr != NULL)\n      *lengthptr += 1;\n    else\n      {\n      PCRE2_ASSERT(rhs_op_info->code_start ==\n          lhs_op_info->code_start + lhs_op_info->length);\n      rhs_op_info->code_start[rhs_op_info->length] = ECL_OR;\n      }\n    lhs_op_info->length += rhs_op_info->length + 1;\n    lhs_op_info->op_single_type = 0;\n    }\n\n  for (int i = 0; i < 8; i++)\n    lhs_op_info->bits.classwords[i] |= rhs_op_info->bits.classwords[i];\n  break;\n\n  /* ECL_XOR truth table:\n\n     LHS  RHS  RESULT\n     ----------------\n     ANY  *    !RHS\n     *    ANY  !LHS\n     NONE *    RHS\n     *    NONE LHS\n     X    Y    X ^ Y\n  */\n\n  case ECL_XOR:\n  if (rhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* no-op: drop the RHS */\n    }\n  else if (lhs_op_info->op_single_type == ECL_NONE)\n    {\n    /* no-op: drop the LHS, and memmove the RHS into its place */\n    if (lengthptr == NULL)\n      memmove(lhs_op_info->code_start, rhs_op_info->code_start,\n              CU2BYTES(rhs_op_info->length));\n    lhs_op_info->length = rhs_op_info->length;\n    lhs_op_info->op_single_type = rhs_op_info->op_single_type;\n    }\n  else if (rhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* the result is !LHS: fold in the negation, and drop the RHS */\n    /* Preserve the classbits, because we promise to deal with them later. */\n    fold_negation(lhs_op_info, lengthptr, TRUE);\n    }\n  else if (lhs_op_info->op_single_type == ECL_ANY)\n    {\n    /* the result is !RHS: drop the LHS, memmove the RHS into its place, and\n    fold in the negation */\n    if (lengthptr == NULL)\n      memmove(lhs_op_info->code_start, rhs_op_info->code_start,\n              CU2BYTES(rhs_op_info->length));\n    lhs_op_info->length = rhs_op_info->length;\n    lhs_op_info->op_single_type = rhs_op_info->op_single_type;\n\n    /* Preserve the classbits, because we promise to deal with them later. */\n    fold_negation(lhs_op_info, lengthptr, TRUE);\n    }\n  else\n    {\n    /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */\n    if (lengthptr != NULL)\n      *lengthptr += 1;\n    else\n      {\n      PCRE2_ASSERT(rhs_op_info->code_start ==\n          lhs_op_info->code_start + lhs_op_info->length);\n      rhs_op_info->code_start[rhs_op_info->length] = ECL_XOR;\n      }\n    lhs_op_info->length += rhs_op_info->length + 1;\n    lhs_op_info->op_single_type = 0;\n    }\n\n  for (int i = 0; i < 8; i++)\n    lhs_op_info->bits.classwords[i] ^= rhs_op_info->bits.classwords[i];\n  break;\n\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  break;\n  /* LCOV_EXCL_STOP */\n  }\n}\n\n\n\nstatic BOOL\ncompile_eclass_nested(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode,\n  eclass_op_info *pop_info, PCRE2_SIZE *lengthptr);\n\n/* This function consumes a group of implicitly-unioned class elements.\nThese can be characters, ranges, properties, or nested classes, as long\nas they are all joined by being placed adjacently. */\n\nstatic BOOL\ncompile_class_operand(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info,\n  PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\nuint32_t *prev_ptr;\nPCRE2_UCHAR *code = *pcode;\nPCRE2_UCHAR *code_start = code;\nPCRE2_SIZE prev_length = (lengthptr != NULL)? *lengthptr : 0;\nPCRE2_SIZE extra_length;\nuint32_t meta = META_CODE(*ptr);\n\nswitch (meta)\n  {\n  case META_CLASS_EMPTY_NOT:\n  case META_CLASS_EMPTY:\n  ++ptr;\n  pop_info->length = 1;\n  if ((meta == META_CLASS_EMPTY) == negated)\n    {\n    *code++ = pop_info->op_single_type = ECL_ANY;\n    memset(pop_info->bits.classbits, 0xff, 32);\n    }\n  else\n    {\n    *code++ = pop_info->op_single_type = ECL_NONE;\n    memset(pop_info->bits.classbits, 0, 32);\n    }\n  break;\n\n  case META_CLASS:\n  case META_CLASS_NOT:\n  if ((*ptr & CLASS_IS_ECLASS) != 0)\n    {\n    if (!compile_eclass_nested(context, negated, &ptr, &code,\n                               pop_info, lengthptr))\n      return FALSE;\n\n    PCRE2_ASSERT(*ptr == META_CLASS_END);\n    ptr++;\n    goto DONE;\n    }\n\n  ptr++;\n  PCRE2_FALLTHROUGH /* Fall through */\n\n  default:\n  /* Scan forward characters, ranges, and properties.\n  For example: inside [a-z_ -- m] we don't have brackets around \"a-z_\" but\n  we still need to collect that fragment up into a \"leaf\" OP_CLASS. */\n\n  prev_ptr = ptr;\n  ptr = PRIV(compile_class_not_nested)(\n    context->options, context->xoptions, ptr, &code,\n    (meta != META_CLASS_NOT) == negated, &context->needs_bitmap,\n    context->errorcodeptr, context->cb, lengthptr);\n  if (ptr == NULL) return FALSE;\n\n  /* We must have a 100% guarantee that ptr increases when\n  compile_class_operand() returns, even on Release builds, so that we can\n  statically prove our loops terminate. */\n  /* LCOV_EXCL_START */\n  if (ptr <= prev_ptr)\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    return FALSE;\n    }\n  /* LCOV_EXCL_STOP */\n\n  /* If we fell through above, consume the closing ']'. */\n  if (meta == META_CLASS || meta == META_CLASS_NOT)\n    {\n    PCRE2_ASSERT(*ptr == META_CLASS_END);\n    ptr++;\n    }\n\n  /* Regardless of whether (lengthptr == NULL), some data will still be written\n  out to *pcode, which we need: we have to peek at it, to transform the opcode\n  into the ECLASS version (since we need to hoist up the bitmaps). */\n  PCRE2_ASSERT(code > code_start);\n  extra_length = (lengthptr != NULL)? *lengthptr - prev_length : 0;\n\n  /* Easiest case: convert OP_ALLANY to ECL_ANY */\n\n  if (*code_start == OP_ALLANY)\n    {\n    PCRE2_ASSERT(code - code_start == 1 && extra_length == 0);\n    pop_info->length = 1;\n    *code_start = pop_info->op_single_type = ECL_ANY;\n    memset(pop_info->bits.classbits, 0xff, 32);\n    }\n\n  /* For OP_CLASS and OP_NCLASS, we hoist out the bitmap and convert to\n  ECL_NONE / ECL_ANY respectively. */\n\n  else if (*code_start == OP_CLASS || *code_start == OP_NCLASS)\n    {\n    PCRE2_ASSERT(code - code_start == 1 + 32 / sizeof(PCRE2_UCHAR) &&\n                 extra_length == 0);\n    pop_info->length = 1;\n    *code_start = pop_info->op_single_type =\n        (*code_start == OP_CLASS)? ECL_NONE : ECL_ANY;\n    memcpy(pop_info->bits.classbits, code_start + 1, 32);\n    /* Rewind the code pointer, but make sure we adjust *lengthptr, because we\n    do need to reserve that space (even though we only use it temporarily). */\n    if (lengthptr != NULL)\n      *lengthptr += code - (code_start + 1);\n    code = code_start + 1;\n\n    if (!context->needs_bitmap && *code_start == ECL_NONE)\n      {\n      uint32_t *classwords = pop_info->bits.classwords;\n\n      for (int i = 0; i < 8; i++)\n        if (classwords[i] != 0)\n          {\n          context->needs_bitmap = TRUE;\n          break;\n          }\n      }\n    else\n      context->needs_bitmap = TRUE;\n    }\n\n  /* Finally, for OP_XCLASS we hoist out the bitmap (if any), and convert to\n  ECL_XCLASS. */\n\n  else\n    {\n    PCRE2_ASSERT(*code_start == OP_XCLASS);\n    *code_start = pop_info->op_single_type = ECL_XCLASS;\n\n    PCRE2_ASSERT(code - code_start >= 1 + LINK_SIZE + 1);\n\n    memcpy(pop_info->bits.classbits, context->cb->classbits.classbits, 32);\n    pop_info->length = (code - code_start) + extra_length;\n    }\n\n  break;\n  }  /* End of switch(meta) */\n\npop_info->code_start = (lengthptr == NULL)? code_start : NULL;\n\nif (lengthptr != NULL)\n  {\n  *lengthptr += code - code_start;\n  code = code_start;\n  }\n\nDONE:\nPCRE2_ASSERT(lengthptr == NULL || (code == code_start));\n\n*pptr = ptr;\n*pcode = code;\nreturn TRUE;\n}\n\n\n\n/* This function consumes a group of implicitly-unioned class elements.\nThese can be characters, ranges, properties, or nested classes, as long\nas they are all joined by being placed adjacently. */\n\nstatic BOOL\ncompile_class_juxtaposition(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info,\n  PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\nPCRE2_UCHAR *code = *pcode;\n#ifdef PCRE2_DEBUG\nPCRE2_UCHAR *start_code = *pcode;\n#endif\n\n/* See compile_class_binary_loose() for comments on compile-time folding of\nthe \"negated\" flag. */\n\n/* Because it's a non-empty class, there must be an operand at the start. */\nif (!compile_class_operand(context, negated, &ptr, &code, pop_info, lengthptr))\n  return FALSE;\n\nwhile (*ptr != META_CLASS_END &&\n       !(*ptr >= META_ECLASS_AND && *ptr <= META_ECLASS_NOT))\n  {\n  uint32_t op;\n  BOOL rhs_negated;\n  eclass_op_info rhs_op_info;\n\n  if (negated)\n    {\n    /* !(A juxtapose B)  ->  !A && !B */\n    op = ECL_AND;\n    rhs_negated = TRUE;\n    }\n  else\n    {\n    /* A juxtapose B  ->  A || B */\n    op = ECL_OR;\n    rhs_negated = FALSE;\n    }\n\n  /* An operand must follow the operator. */\n  if (!compile_class_operand(context, rhs_negated, &ptr, &code,\n                             &rhs_op_info, lengthptr))\n    return FALSE;\n\n  /* Convert infix to postfix (RPN). */\n  fold_binary(op, pop_info, &rhs_op_info, lengthptr);\n  if (lengthptr == NULL)\n    code = pop_info->code_start + pop_info->length;\n  }\n\nPCRE2_ASSERT(lengthptr == NULL || code == start_code);\n\n*pptr = ptr;\n*pcode = code;\nreturn TRUE;\n}\n\n\n\n/* This function consumes unary prefix operators. */\n\nstatic BOOL\ncompile_class_unary(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info,\n  PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\n#ifdef PCRE2_DEBUG\nPCRE2_UCHAR *start_code = *pcode;\n#endif\n\nwhile (*ptr == META_ECLASS_NOT)\n  {\n  ++ptr;\n  negated = !negated;\n  }\n\n*pptr = ptr;\n/* Because it's a non-empty class, there must be an operand. */\nif (!compile_class_juxtaposition(context, negated, pptr, pcode,\n                                 pop_info, lengthptr))\n  return FALSE;\n\nPCRE2_ASSERT(lengthptr == NULL || *pcode == start_code);\nreturn TRUE;\n}\n\n\n\n/* This function consumes tightly-binding binary operators. */\n\nstatic BOOL\ncompile_class_binary_tight(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info,\n  PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\nPCRE2_UCHAR *code = *pcode;\n#ifdef PCRE2_DEBUG\nPCRE2_UCHAR *start_code = *pcode;\n#endif\n\n/* See compile_class_binary_loose() for comments on compile-time folding of\nthe \"negated\" flag. */\n\n/* Because it's a non-empty class, there must be an operand at the start. */\nif (!compile_class_unary(context, negated, &ptr, &code, pop_info, lengthptr))\n  return FALSE;\n\nwhile (*ptr == META_ECLASS_AND)\n  {\n  uint32_t op;\n  BOOL rhs_negated;\n  eclass_op_info rhs_op_info;\n\n  if (negated)\n    {\n    /* !(A && B)  ->  !A || !B */\n    op = ECL_OR;\n    rhs_negated = TRUE;\n    }\n  else\n    {\n    /* A && B  ->  A && B */\n    op = ECL_AND;\n    rhs_negated = FALSE;\n    }\n\n  ++ptr;\n\n  /* An operand must follow the operator. */\n  if (!compile_class_unary(context, rhs_negated, &ptr, &code,\n                           &rhs_op_info, lengthptr))\n    return FALSE;\n\n  /* Convert infix to postfix (RPN). */\n  fold_binary(op, pop_info, &rhs_op_info, lengthptr);\n  if (lengthptr == NULL)\n    code = pop_info->code_start + pop_info->length;\n  }\n\nPCRE2_ASSERT(lengthptr == NULL || code == start_code);\n\n*pptr = ptr;\n*pcode = code;\nreturn TRUE;\n}\n\n\n\n/* This function consumes loosely-binding binary operators. */\n\nstatic BOOL\ncompile_class_binary_loose(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info,\n  PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\nPCRE2_UCHAR *code = *pcode;\n#ifdef PCRE2_DEBUG\nPCRE2_UCHAR *start_code = *pcode;\n#endif\n\n/* We really want to fold the negation operator, if at all possible, so that\nsimple cases can be reduced down. In particular, in 8-bit no-UTF mode, we want\nto produce a fully-folded expression, so that we can guarantee not to emit any\nOP_ECLASS codes (in the same way that we never emit OP_XCLASS in this mode).\n\nThis has the consequence that with a little ingenuity, we can in fact avoid\nemitting (nearly...) all cases of the \"NOT\" operator. Imagine that we have:\n    !(A ...\nWe have parsed the preceding \"!\", and we are about to parse the \"A\" operand. We\ndon't know yet whether there will even be a following binary operand! Both of\nthese are possibilities for what follows:\n    !(A && B)\n    !(A)\nHowever, we can still fold the \"!\" into the \"A\" operand, because no matter what\nthe following binary operator will be, we can produce an expression which is\nequivalent. */\n\n/* Because it's a non-empty class, there must be an operand at the start. */\nif (!compile_class_binary_tight(context, negated, &ptr, &code,\n                                pop_info, lengthptr))\n  return FALSE;\n\nwhile (*ptr >= META_ECLASS_OR && *ptr <= META_ECLASS_XOR)\n  {\n  uint32_t op;\n  BOOL op_neg;\n  BOOL rhs_negated;\n  eclass_op_info rhs_op_info;\n\n  if (negated)\n    {\n    /* The whole expression is being negated; we respond by unconditionally\n    negating the LHS A, before seeing what follows. And hooray! We can recover,\n    no matter what follows. */\n    /* !(A || B)   ->  !A && !B                     */\n    /* !(A -- B)   ->  !(A && !B)    ->  !A || B    */\n    /* !(A XOR B)  ->  !(!A XOR !B)  ->  !A XNOR !B */\n    op = (*ptr == META_ECLASS_OR )? ECL_AND :\n         (*ptr == META_ECLASS_SUB)? ECL_OR  :\n         /*ptr == META_ECLASS_XOR*/ ECL_XOR;\n    op_neg = (*ptr == META_ECLASS_XOR);\n    rhs_negated = *ptr != META_ECLASS_SUB;\n    }\n  else\n    {\n    /* A || B   ->  A || B  */\n    /* A -- B   ->  A && !B */\n    /* A XOR B  ->  A XOR B */\n    op = (*ptr == META_ECLASS_OR )? ECL_OR  :\n         (*ptr == META_ECLASS_SUB)? ECL_AND :\n         /*ptr == META_ECLASS_XOR*/ ECL_XOR;\n    op_neg = FALSE;\n    rhs_negated = *ptr == META_ECLASS_SUB;\n    }\n\n  ++ptr;\n\n  /* An operand must follow the operator. */\n  if (!compile_class_binary_tight(context, rhs_negated, &ptr, &code,\n                                  &rhs_op_info, lengthptr))\n    return FALSE;\n\n  /* Convert infix to postfix (RPN). */\n  fold_binary(op, pop_info, &rhs_op_info, lengthptr);\n  if (op_neg) fold_negation(pop_info, lengthptr, FALSE);\n  if (lengthptr == NULL)\n    code = pop_info->code_start + pop_info->length;\n  }\n\nPCRE2_ASSERT(lengthptr == NULL || code == start_code);\n\n*pptr = ptr;\n*pcode = code;\nreturn TRUE;\n}\n\n\n\n/* This function converts the META codes in pptr into opcodes written to\npcode. The pptr must start at a META_CLASS or META_CLASS_NOT.\n\nThe class is compiled as a left-associative sequence of operator\napplications.\n\nThe pptr will be left pointing at the matching META_CLASS_END. */\n\nstatic BOOL\ncompile_eclass_nested(eclass_context *context, BOOL negated,\n  uint32_t **pptr, PCRE2_UCHAR **pcode,\n  eclass_op_info *pop_info, PCRE2_SIZE *lengthptr)\n{\nuint32_t *ptr = *pptr;\n#ifdef PCRE2_DEBUG\nPCRE2_UCHAR *start_code = *pcode;\n#endif\n\n/* The CLASS_IS_ECLASS bit must be set since it is a nested class. */\nPCRE2_ASSERT(*ptr == (META_CLASS | CLASS_IS_ECLASS) ||\n             *ptr == (META_CLASS_NOT | CLASS_IS_ECLASS));\n\nif (*ptr++ == (META_CLASS_NOT | CLASS_IS_ECLASS))\n  negated = !negated;\n\n(*pptr)++;\n\n/* Because it's a non-empty class, there must be an operand at the start. */\nif (!compile_class_binary_loose(context, negated, pptr, pcode,\n                                pop_info, lengthptr))\n  return FALSE;\n\nPCRE2_ASSERT(**pptr == META_CLASS_END);\nPCRE2_ASSERT(lengthptr == NULL || *pcode == start_code);\nreturn TRUE;\n}\n\nBOOL\nPRIV(compile_class_nested)(uint32_t options, uint32_t xoptions,\n  uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr,\n  compile_block *cb, PCRE2_SIZE *lengthptr)\n{\neclass_context context;\neclass_op_info op_info;\nPCRE2_SIZE previous_length = (lengthptr != NULL)? *lengthptr : 0;\nPCRE2_UCHAR *code = *pcode;\nPCRE2_UCHAR *previous;\nBOOL allbitsone = TRUE;\n\ncontext.needs_bitmap = FALSE;\ncontext.options = options;\ncontext.xoptions = xoptions;\ncontext.errorcodeptr = errorcodeptr;\ncontext.cb = cb;\n\nprevious = code;\n*code++ = OP_ECLASS;\ncode += LINK_SIZE;\n*code++ = 0;  /* Flags, currently zero. */\nif (!compile_eclass_nested(&context, FALSE, pptr, &code, &op_info, lengthptr))\n  return FALSE;\n\nif (lengthptr != NULL)\n  {\n  *lengthptr += code - previous;\n  code = previous;\n  /* (*lengthptr - previous_length) now holds the amount of buffer that\n  we require to make the call to compile_class_nested() with\n  lengthptr = NULL, and including the (1+LINK_SIZE+1) that we write out\n  before that call. */\n  }\n\n/* Do some useful counting of what's in the bitmap. */\nfor (int i = 0; i < 8; i++)\n  if (op_info.bits.classwords[i] != 0xffffffff)\n    {\n    allbitsone = FALSE;\n    break;\n    }\n\n/* After constant-folding the extended class syntax, it may turn out to be\na simple class after all. In that case, we can unwrap it from the\nOP_ECLASS container - and in fact, we must do so, because in 8-bit\nno-Unicode mode the matcher is compiled without support for OP_ECLASS. */\n\n#ifndef SUPPORT_WIDE_CHARS\nPCRE2_ASSERT(op_info.op_single_type != 0);\n#else\nif (op_info.op_single_type != 0)\n#endif\n  {\n  /* Rewind back over the OP_ECLASS. */\n  code = previous;\n\n  /* If the bits are all ones, and the \"high characters\" are all matched\n  too, we use a special-cased encoding of OP_ALLANY. */\n\n  if (op_info.op_single_type == ECL_ANY && allbitsone)\n    {\n    /* Advancing code means rewinding lengthptr, at this point. */\n    if (lengthptr != NULL) *lengthptr -= 1;\n    *code++ = OP_ALLANY;\n    }\n\n  /* If the high bits are all matched / all not-matched, then we emit an\n  OP_NCLASS/OP_CLASS respectively. */\n\n  else if (op_info.op_single_type == ECL_ANY ||\n           op_info.op_single_type == ECL_NONE)\n    {\n    PCRE2_SIZE required_len = 1 + (32 / sizeof(PCRE2_UCHAR));\n\n    if (lengthptr != NULL)\n      {\n      if (required_len > (*lengthptr - previous_length))\n      *lengthptr = previous_length + required_len;\n      }\n\n    /* Advancing code means rewinding lengthptr, at this point. */\n    if (lengthptr != NULL) *lengthptr -= required_len;\n    *code++ = (op_info.op_single_type == ECL_ANY)? OP_NCLASS : OP_CLASS;\n    memcpy(code, op_info.bits.classbits, 32);\n    code += 32 / sizeof(PCRE2_UCHAR);\n    }\n\n  /* Otherwise, we have an ECL_XCLASS, so we have the OP_XCLASS data\n  there, but, we pulled out its bitmap into op_info, so now we have to\n  put that back into the OP_XCLASS. */\n\n  else\n    {\n#ifndef SUPPORT_WIDE_CHARS\n    PCRE2_DEBUG_UNREACHABLE();\n#else\n    BOOL need_map = context.needs_bitmap;\n    PCRE2_SIZE required_len;\n\n    PCRE2_ASSERT(op_info.op_single_type == ECL_XCLASS);\n    required_len = op_info.length + (need_map? 32/sizeof(PCRE2_UCHAR) : 0);\n\n    if (lengthptr != NULL)\n      {\n      /* Don't unconditionally request all the space we need - we may\n      already have asked for more during processing of the ECLASS. */\n      if (required_len > (*lengthptr - previous_length))\n        *lengthptr = previous_length + required_len;\n\n      /* The code we write out here won't be ignored, even during the\n      (lengthptr != NULL) phase, because if there's a following quantifier\n      it will peek backwards. So we do have to write out a (truncated)\n      OP_XCLASS, even on this branch. */\n      *lengthptr -= 1 + LINK_SIZE + 1;\n      *code++ = OP_XCLASS;\n      PUT(code, 0, 1 + LINK_SIZE + 1);\n      code += LINK_SIZE;\n      *code++ = 0;\n      }\n    else\n      {\n      PCRE2_UCHAR *rest;\n      PCRE2_SIZE rest_len;\n      PCRE2_UCHAR flags;\n\n      /* 1 unit: OP_XCLASS | LINK_SIZE units | 1 unit: flags | ...rest */\n      PCRE2_ASSERT(op_info.length >= 1 + LINK_SIZE + 1);\n      rest = op_info.code_start + 1 + LINK_SIZE + 1;\n      rest_len = (op_info.code_start + op_info.length) - rest;\n\n      /* First read any data we use, before memmove splats it. */\n      flags = op_info.code_start[1 + LINK_SIZE];\n      PCRE2_ASSERT((flags & XCL_MAP) == 0);\n\n      /* Next do the memmove before any writes. */\n      memmove(code + 1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0),\n              rest, CU2BYTES(rest_len));\n\n      /* Finally write the header data. */\n      *code++ = OP_XCLASS;\n      PUT(code, 0, (int)required_len);\n      code += LINK_SIZE;\n      *code++ = flags | (need_map? XCL_MAP : 0);\n      if (need_map)\n        {\n        memcpy(code, op_info.bits.classbits, 32);\n        code += 32 / sizeof(PCRE2_UCHAR);\n        }\n      code += rest_len;\n      }\n#endif /* SUPPORT_WIDE_CHARS */\n    }\n  }\n\n/* Otherwise, we're going to keep the OP_ECLASS. However, again we need\nto do some adjustment to insert the bitmap if we have one. */\n\n#ifdef SUPPORT_WIDE_CHARS\nelse\n  {\n  BOOL need_map = context.needs_bitmap;\n  PCRE2_SIZE required_len =\n    1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0) + op_info.length;\n\n  if (lengthptr != NULL)\n    {\n    if (required_len > (*lengthptr - previous_length))\n      *lengthptr = previous_length + required_len;\n\n    /* As for the XCLASS branch above, we do have to write out a dummy\n    OP_ECLASS, because of the backwards peek by the quantifier code. Write\n    out a (truncated) OP_ECLASS, even on this branch. */\n    *lengthptr -= 1 + LINK_SIZE + 1;\n    *code++ = OP_ECLASS;\n    PUT(code, 0, 1 + LINK_SIZE + 1);\n    code += LINK_SIZE;\n    *code++ = 0;\n    }\n  else\n    {\n    if (need_map)\n      {\n      PCRE2_UCHAR *map_start = previous + 1 + LINK_SIZE + 1;\n      previous[1 + LINK_SIZE] |= ECL_MAP;\n      memmove(map_start + 32/sizeof(PCRE2_UCHAR), map_start,\n              CU2BYTES(code - map_start));\n      memcpy(map_start, op_info.bits.classbits, 32);\n      code += 32 / sizeof(PCRE2_UCHAR);\n      }\n    PUT(previous, 1, (int)(code - previous));\n    }\n  }\n#endif /* SUPPORT_WIDE_CHARS */\n\n*pcode = code;\nreturn TRUE;\n}\n\n/* End of pcre2_compile_class.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_config.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2020 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* These macros are the standard way of turning unquoted text into C strings.\nThey allow macros like PCRE2_MAJOR to be defined without quotes, which is\nconvenient for user programs that want to test their values. */\n\n#define STRING(a)  # a\n#define XSTRING(s) STRING(s)\n\n\n/*************************************************\n* Return info about what features are configured *\n*************************************************/\n\n/* If where is NULL, the length of memory required is returned.\n\nArguments:\n  what             what information is required\n  where            where to put the information\n\nReturns:           0 if a numerical value is returned\n                   >= 0 if a string value\n                   PCRE2_ERROR_BADOPTION if \"where\" not recognized\n                     or JIT target requested when JIT not enabled\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_config(uint32_t what, void *where)\n{\nif (where == NULL)  /* Requests a length */\n  {\n  switch (what)\n    {\n    default:\n    return PCRE2_ERROR_BADOPTION;\n\n    case PCRE2_CONFIG_BSR:\n    case PCRE2_CONFIG_COMPILED_WIDTHS:\n    case PCRE2_CONFIG_DEPTHLIMIT:\n    case PCRE2_CONFIG_EFFECTIVE_LINKSIZE:\n    case PCRE2_CONFIG_HEAPLIMIT:\n    case PCRE2_CONFIG_JIT:\n    case PCRE2_CONFIG_LINKSIZE:\n    case PCRE2_CONFIG_MATCHLIMIT:\n    case PCRE2_CONFIG_NEVER_BACKSLASH_C:\n    case PCRE2_CONFIG_NEWLINE:\n    case PCRE2_CONFIG_PARENSLIMIT:\n    case PCRE2_CONFIG_STACKRECURSE:    /* Obsolete */\n    case PCRE2_CONFIG_TABLES_LENGTH:\n    case PCRE2_CONFIG_UNICODE:\n    return sizeof(uint32_t);\n\n    /* These are handled below */\n\n    case PCRE2_CONFIG_JITTARGET:\n    case PCRE2_CONFIG_UNICODE_VERSION:\n    case PCRE2_CONFIG_VERSION:\n    break;\n    }\n  }\n\nswitch (what)\n  {\n  default:\n  return PCRE2_ERROR_BADOPTION;\n\n  case PCRE2_CONFIG_BSR:\n#ifdef BSR_ANYCRLF\n  *((uint32_t *)where) = PCRE2_BSR_ANYCRLF;\n#else\n  *((uint32_t *)where) = PCRE2_BSR_UNICODE;\n#endif\n  break;\n\n  case PCRE2_CONFIG_COMPILED_WIDTHS:\n  *((uint32_t *)where) = 0\n#ifdef SUPPORT_PCRE2_8\n  + (1 << 0)\n#endif\n#ifdef SUPPORT_PCRE2_16\n  + (1 << 1)\n#endif\n#ifdef SUPPORT_PCRE2_32\n  + (1 << 2)\n#endif\n  ;\n  break;\n\n  case PCRE2_CONFIG_DEPTHLIMIT:\n  *((uint32_t *)where) = MATCH_LIMIT_DEPTH;\n  break;\n\n  case PCRE2_CONFIG_EFFECTIVE_LINKSIZE:\n  *((uint32_t *)where) = LINK_SIZE * sizeof(PCRE2_UCHAR);\n  break;\n\n  case PCRE2_CONFIG_HEAPLIMIT:\n  *((uint32_t *)where) = HEAP_LIMIT;\n  break;\n\n  case PCRE2_CONFIG_JIT:\n#ifdef SUPPORT_JIT\n  *((uint32_t *)where) = 1;\n#else\n  *((uint32_t *)where) = 0;\n#endif\n  break;\n\n  case PCRE2_CONFIG_JITTARGET:\n#ifdef SUPPORT_JIT\n    {\n    const char *v = PRIV(jit_get_target)();\n    return (int)(1 + ((where == NULL)?\n      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));\n    }\n#else\n  return PCRE2_ERROR_BADOPTION;\n#endif\n\n  case PCRE2_CONFIG_LINKSIZE:\n  *((uint32_t *)where) = (uint32_t)CONFIGURED_LINK_SIZE;\n  break;\n\n  case PCRE2_CONFIG_MATCHLIMIT:\n  *((uint32_t *)where) = MATCH_LIMIT;\n  break;\n\n  case PCRE2_CONFIG_NEWLINE:\n  *((uint32_t *)where) = NEWLINE_DEFAULT;\n  break;\n\n  case PCRE2_CONFIG_NEVER_BACKSLASH_C:\n#ifdef NEVER_BACKSLASH_C\n  *((uint32_t *)where) = 1;\n#else\n  *((uint32_t *)where) = 0;\n#endif\n  break;\n\n  case PCRE2_CONFIG_PARENSLIMIT:\n  *((uint32_t *)where) = PARENS_NEST_LIMIT;\n  break;\n\n  /* This is now obsolete. The stack is no longer used via recursion for\n  handling backtracking in pcre2_match(). */\n\n  case PCRE2_CONFIG_STACKRECURSE:\n  *((uint32_t *)where) = 0;\n  break;\n\n  case PCRE2_CONFIG_TABLES_LENGTH:\n  *((uint32_t *)where) = TABLES_LENGTH;\n  break;\n\n  case PCRE2_CONFIG_UNICODE_VERSION:\n    {\n#if defined SUPPORT_UNICODE\n    const char *v = PRIV(unicode_version);\n#else\n    const char *v = \"Unicode not supported\";\n#endif\n    return (int)(1 + ((where == NULL)?\n      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));\n    }\n\n  case PCRE2_CONFIG_UNICODE:\n#if defined SUPPORT_UNICODE\n  *((uint32_t *)where) = 1;\n#else\n  *((uint32_t *)where) = 0;\n#endif\n  break;\n\n  /* The hackery in setting \"v\" below is to cope with the case when\n  PCRE2_PRERELEASE is set to an empty string (which it is for real releases).\n  If the second alternative is used in this case, it does not leave a space\n  before the date. On the other hand, if all four macros are put into a single\n  XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted.\n  There are problems using an \"obvious\" approach like this:\n\n     XSTRING(PCRE2_MAJOR) \".\" XSTRING(PCRE2_MINOR)\n     XSTRING(PCRE2_PRERELEASE) \" \" XSTRING(PCRE2_DATE)\n\n  because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion\n  of STRING(). The C standard states: \"If (before argument substitution) any\n  argument consists of no preprocessing tokens, the behavior is undefined.\" It\n  turns out the gcc treats this case as a single empty string - which is what\n  we really want - but Visual C grumbles about the lack of an argument for the\n  macro. Unfortunately, both are within their rights. As there seems to be no\n  way to test for a macro's value being empty at compile time, we have to\n  resort to a runtime test. */\n\n  case PCRE2_CONFIG_VERSION:\n    {\n    const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)?\n      XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) :\n      XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE);\n    return (int)(1 + ((where == NULL)?\n      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));\n    }\n\n  }\n\nreturn 0;\n}\n\n/* End of pcre2_config.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_context.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*          Default malloc/free functions         *\n*************************************************/\n\n/* Ignore the \"user data\" argument in each case. */\n\nstatic void *default_malloc(size_t size, void *data)\n{\n(void)data;\nreturn malloc(size);\n}\n\n\nstatic void default_free(void *block, void *data)\n{\n(void)data;\nfree(block);\n}\n\n\n\n/*************************************************\n*        Get a block and save memory control     *\n*************************************************/\n\n/* This internal function is called to get a block of memory in which the\nmemory control data is to be stored at the start for future use.\n\nArguments:\n  size        amount of memory required\n  memctl      pointer to a memctl block or NULL\n\nReturns:      pointer to memory or NULL on failure\n*/\n\nextern void *\nPRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)\n{\npcre2_memctl *newmemctl;\nvoid *yield = (memctl == NULL)? malloc(size) :\n  memctl->malloc(size, memctl->memory_data);\nif (yield == NULL) return NULL;\nnewmemctl = (pcre2_memctl *)yield;\nif (memctl == NULL)\n  {\n  newmemctl->malloc = default_malloc;\n  newmemctl->free = default_free;\n  newmemctl->memory_data = NULL;\n  }\nelse *newmemctl = *memctl;\nreturn yield;\n}\n\n\n\n/*************************************************\n*          Create and initialize contexts        *\n*************************************************/\n\n/* Initializing for compile and match contexts is done in separate, private\nfunctions so that these can be called from functions such as pcre2_compile()\nwhen an external context is not supplied. The initializing functions have an\noption to set up default memory management. */\n\nPCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION\npcre2_general_context_create(void *(*private_malloc)(size_t, void *),\n  void (*private_free)(void *, void *), void *memory_data)\n{\npcre2_general_context *gcontext;\nif (private_malloc == NULL) private_malloc = default_malloc;\nif (private_free == NULL) private_free = default_free;\ngcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);\nif (gcontext == NULL) return NULL;\ngcontext->memctl.malloc = private_malloc;\ngcontext->memctl.free = private_free;\ngcontext->memctl.memory_data = memory_data;\nreturn gcontext;\n}\n\n\n/* A default compile context is set up to save having to initialize at run time\nwhen no context is supplied to the compile function. */\n\npcre2_compile_context PRIV(default_compile_context) = {\n  { default_malloc, default_free, NULL },    /* Default memory handling */\n  NULL,                                      /* Stack guard */\n  NULL,                                      /* Stack guard data */\n  PRIV(default_tables),                      /* Character tables */\n  PCRE2_UNSET,                               /* Max pattern length */\n  PCRE2_UNSET,                               /* Max pattern compiled length */\n  BSR_DEFAULT,                               /* Backslash R default */\n  NEWLINE_DEFAULT,                           /* Newline convention */\n  PARENS_NEST_LIMIT,                         /* As it says */\n  0,                                         /* Extra options */\n  MAX_VARLOOKBEHIND,                         /* As it says */\n  PCRE2_OPTIMIZATION_ALL                     /* All optimizations enabled */\n  };\n\n/* The create function copies the default into the new memory, but must\noverride the default memory handling functions if a gcontext was provided. */\n\nPCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION\npcre2_compile_context_create(pcre2_general_context *gcontext)\n{\npcre2_compile_context *ccontext = PRIV(memctl_malloc)(\n  sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);\nif (ccontext == NULL) return NULL;\n*ccontext = PRIV(default_compile_context);\nif (gcontext != NULL)\n  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);\nreturn ccontext;\n}\n\n\n/* A default match context is set up to save having to initialize at run time\nwhen no context is supplied to a match function. */\n\npcre2_match_context PRIV(default_match_context) = {\n  { default_malloc, default_free, NULL },\n#ifdef SUPPORT_JIT\n  NULL,          /* JIT callback */\n  NULL,          /* JIT callback data */\n#endif\n  NULL,          /* Callout function */\n  NULL,          /* Callout data */\n  NULL,          /* Substitute callout function */\n  NULL,          /* Substitute callout data */\n  NULL,          /* Substitute case callout function */\n  NULL,          /* Substitute case callout data */\n  PCRE2_UNSET,   /* Offset limit */\n  HEAP_LIMIT,\n  MATCH_LIMIT,\n  MATCH_LIMIT_DEPTH };\n\n/* The create function copies the default into the new memory, but must\noverride the default memory handling functions if a gcontext was provided. */\n\nPCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION\npcre2_match_context_create(pcre2_general_context *gcontext)\n{\npcre2_match_context *mcontext = PRIV(memctl_malloc)(\n  sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);\nif (mcontext == NULL) return NULL;\n*mcontext = PRIV(default_match_context);\nif (gcontext != NULL)\n  *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);\nreturn mcontext;\n}\n\n\n/* A default convert context is set up to save having to initialize at run time\nwhen no context is supplied to the convert function. */\n\npcre2_convert_context PRIV(default_convert_context) = {\n  { default_malloc, default_free, NULL },    /* Default memory handling */\n#ifdef _WIN32\n  CHAR_BACKSLASH,                            /* Default path separator */\n  CHAR_GRAVE_ACCENT                          /* Default escape character */\n#else  /* Not Windows */\n  CHAR_SLASH,                                /* Default path separator */\n  CHAR_BACKSLASH                             /* Default escape character */\n#endif\n  };\n\n/* The create function copies the default into the new memory, but must\noverride the default memory handling functions if a gcontext was provided. */\n\nPCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION\npcre2_convert_context_create(pcre2_general_context *gcontext)\n{\npcre2_convert_context *ccontext = PRIV(memctl_malloc)(\n  sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);\nif (ccontext == NULL) return NULL;\n*ccontext = PRIV(default_convert_context);\nif (gcontext != NULL)\n  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);\nreturn ccontext;\n}\n\n\n/*************************************************\n*              Context copy functions            *\n*************************************************/\n\nPCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION\npcre2_general_context_copy(pcre2_general_context *gcontext)\n{\npcre2_general_context *newcontext =\n  gcontext->memctl.malloc(sizeof(pcre2_real_general_context),\n  gcontext->memctl.memory_data);\nif (newcontext == NULL) return NULL;\nmemcpy(newcontext, gcontext, sizeof(pcre2_real_general_context));\nreturn newcontext;\n}\n\n\nPCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION\npcre2_compile_context_copy(pcre2_compile_context *ccontext)\n{\npcre2_compile_context *newcontext =\n  ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),\n  ccontext->memctl.memory_data);\nif (newcontext == NULL) return NULL;\nmemcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context));\nreturn newcontext;\n}\n\n\nPCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION\npcre2_match_context_copy(pcre2_match_context *mcontext)\n{\npcre2_match_context *newcontext =\n  mcontext->memctl.malloc(sizeof(pcre2_real_match_context),\n  mcontext->memctl.memory_data);\nif (newcontext == NULL) return NULL;\nmemcpy(newcontext, mcontext, sizeof(pcre2_real_match_context));\nreturn newcontext;\n}\n\n\nPCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION\npcre2_convert_context_copy(pcre2_convert_context *ccontext)\n{\npcre2_convert_context *newcontext =\n  ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),\n  ccontext->memctl.memory_data);\nif (newcontext == NULL) return NULL;\nmemcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context));\nreturn newcontext;\n}\n\n\n/*************************************************\n*              Context free functions            *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_general_context_free(pcre2_general_context *gcontext)\n{\nif (gcontext != NULL)\n  gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);\n}\n\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_compile_context_free(pcre2_compile_context *ccontext)\n{\nif (ccontext != NULL)\n  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);\n}\n\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_match_context_free(pcre2_match_context *mcontext)\n{\nif (mcontext != NULL)\n  mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);\n}\n\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_convert_context_free(pcre2_convert_context *ccontext)\n{\nif (ccontext != NULL)\n  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);\n}\n\n\n/*************************************************\n*             Set values in contexts             *\n*************************************************/\n\n/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid\ndata is given. Only some of the functions are able to test the validity of the\ndata. */\n\n\n/* ------------ Compile context ------------ */\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_character_tables(pcre2_compile_context *ccontext,\n  const uint8_t *tables)\n{\nccontext->tables = tables;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)\n{\nswitch(value)\n  {\n  case PCRE2_BSR_ANYCRLF:\n  case PCRE2_BSR_UNICODE:\n  ccontext->bsr_convention = value;\n  return 0;\n\n  default:\n  return PCRE2_ERROR_BADDATA;\n  }\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)\n{\nccontext->max_pattern_length = length;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_max_pattern_compiled_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)\n{\nccontext->max_pattern_compiled_length = length;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)\n{\nswitch(newline)\n  {\n  case PCRE2_NEWLINE_CR:\n  case PCRE2_NEWLINE_LF:\n  case PCRE2_NEWLINE_CRLF:\n  case PCRE2_NEWLINE_ANY:\n  case PCRE2_NEWLINE_ANYCRLF:\n  case PCRE2_NEWLINE_NUL:\n  ccontext->newline_convention = newline;\n  return 0;\n\n  default:\n  return PCRE2_ERROR_BADDATA;\n  }\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit)\n{\nccontext->max_varlookbehind = limit;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)\n{\nccontext->parens_nest_limit = limit;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)\n{\nccontext->extra_options = options;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,\n  int (*guard)(uint32_t, void *), void *user_data)\n{\nccontext->stack_guard = guard;\nccontext->stack_guard_data = user_data;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_optimize(pcre2_compile_context *ccontext, uint32_t directive)\n{\nif (ccontext == NULL)\n  return PCRE2_ERROR_NULL;\n\nswitch (directive)\n  {\n  case PCRE2_OPTIMIZATION_NONE:\n  ccontext->optimization_flags = 0;\n  break;\n\n  case PCRE2_OPTIMIZATION_FULL:\n  ccontext->optimization_flags = PCRE2_OPTIMIZATION_ALL;\n  break;\n\n  default:\n  if (directive >= PCRE2_AUTO_POSSESS && directive <= PCRE2_START_OPTIMIZE_OFF)\n    {\n    /* Even directive numbers starting from 64 switch a bit on;\n     * Odd directive numbers starting from 65 switch a bit off */\n    if ((directive & 1) != 0)\n      ccontext->optimization_flags &= ~(1u << ((directive >> 1) - 32));\n    else\n      ccontext->optimization_flags |= 1u << ((directive >> 1) - 32);\n    return 0;\n    }\n  return PCRE2_ERROR_BADOPTION;\n  }\n\nreturn 0;\n}\n\n/* ------------ Match context ------------ */\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_callout(pcre2_match_context *mcontext,\n  int (*callout)(pcre2_callout_block *, void *), void *callout_data)\n{\nmcontext->callout = callout;\nmcontext->callout_data = callout_data;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_substitute_callout(pcre2_match_context *mcontext,\n  int (*substitute_callout)(pcre2_substitute_callout_block *, void *),\n  void *substitute_callout_data)\n{\nmcontext->substitute_callout = substitute_callout;\nmcontext->substitute_callout_data = substitute_callout_data;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_substitute_case_callout(pcre2_match_context *mcontext,\n  PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,\n                                        PCRE2_SIZE, int, void *),\n  void *substitute_case_callout_data)\n{\nmcontext->substitute_case_callout = substitute_case_callout;\nmcontext->substitute_case_callout_data = substitute_case_callout_data;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)\n{\nmcontext->heap_limit = limit;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)\n{\nmcontext->match_limit = limit;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)\n{\nmcontext->depth_limit = limit;\nreturn 0;\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)\n{\nmcontext->offset_limit = limit;\nreturn 0;\n}\n\n/* These functions became obsolete at release 10.30. The first is kept as a\nsynonym for backwards compatibility. The second now does nothing. */\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)\n{\nreturn pcre2_set_depth_limit(mcontext, limit);\n}\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_recursion_memory_management(pcre2_match_context *mcontext,\n  void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),\n  void *mydata)\n{\n(void)mcontext;\n(void)mymalloc;\n(void)myfree;\n(void)mydata;\nreturn 0;\n}\n\n\n/* ------------ Convert context ------------ */\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)\n{\nif (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&\n    separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;\nccontext->glob_separator = separator;\nreturn 0;\n}\n\nstatic const char *globpunct =\n  STR_EXCLAMATION_MARK STR_QUOTATION_MARK STR_NUMBER_SIGN STR_DOLLAR_SIGN\n  STR_PERCENT_SIGN STR_AMPERSAND STR_APOSTROPHE STR_LEFT_PARENTHESIS\n  STR_RIGHT_PARENTHESIS STR_ASTERISK STR_PLUS STR_COMMA STR_MINUS STR_DOT\n  STR_SLASH STR_COLON STR_SEMICOLON STR_LESS_THAN_SIGN STR_EQUALS_SIGN\n  STR_GREATER_THAN_SIGN STR_QUESTION_MARK STR_COMMERCIAL_AT\n  STR_LEFT_SQUARE_BRACKET STR_BACKSLASH STR_RIGHT_SQUARE_BRACKET\n  STR_CIRCUMFLEX_ACCENT STR_UNDERSCORE STR_GRAVE_ACCENT STR_LEFT_CURLY_BRACKET\n  STR_VERTICAL_LINE STR_RIGHT_CURLY_BRACKET STR_TILDE;\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)\n{\nif (escape > 255 || (escape != 0 && strchr(globpunct, escape) == NULL))\n  return PCRE2_ERROR_BADDATA;\nccontext->glob_escape = escape;\nreturn 0;\n}\n\n/* End of pcre2_context.c */\n\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_convert.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n#define TYPE_OPTIONS (PCRE2_CONVERT_GLOB| \\\n  PCRE2_CONVERT_POSIX_BASIC|PCRE2_CONVERT_POSIX_EXTENDED)\n\n#define ALL_OPTIONS (PCRE2_CONVERT_UTF|PCRE2_CONVERT_NO_UTF_CHECK| \\\n  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR| \\\n  PCRE2_CONVERT_GLOB_NO_STARSTAR| \\\n  TYPE_OPTIONS)\n\n#define DUMMY_BUFFER_SIZE 100\n\n/* Generated pattern fragments */\n\n#define STR_BACKSLASH_A STR_BACKSLASH STR_A\n#define STR_BACKSLASH_z STR_BACKSLASH STR_z\n#define STR_COLON_RIGHT_SQUARE_BRACKET STR_COLON STR_RIGHT_SQUARE_BRACKET\n#define STR_DOT_STAR_LOOKBEHIND STR_DOT STR_ASTERISK STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_LESS_THAN_SIGN STR_EQUALS_SIGN\n#define STR_LOOKAHEAD_NOT_DOT STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_EXCLAMATION_MARK STR_BACKSLASH STR_DOT STR_RIGHT_PARENTHESIS\n#define STR_QUERY_s STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_s STR_RIGHT_PARENTHESIS\n#define STR_STAR_NUL STR_LEFT_PARENTHESIS STR_ASTERISK STR_N STR_U STR_L STR_RIGHT_PARENTHESIS\n\n/* States for POSIX processing */\n\nenum { POSIX_START_REGEX, POSIX_ANCHORED, POSIX_NOT_BRACKET,\n       POSIX_CLASS_NOT_STARTED, POSIX_CLASS_STARTING, POSIX_CLASS_STARTED };\n\n/* Macro to add a character string to the output buffer, checking for overflow. */\n\n#define PUTCHARS(string) \\\n  { \\\n  for (const char *s = string; *s != 0; s++) \\\n    { \\\n    if (p >= endp) return PCRE2_ERROR_NOMEMORY; \\\n    *p++ = *s; \\\n    } \\\n  }\n\n/* Macro to check for lowercase characters. */\n\n#ifdef EBCDIC\n#define ISLOWER(c)  (((c) >= CHAR_a && (c) <= CHAR_i) || \\\n                     ((c) >= CHAR_j && (c) <= CHAR_r) || \\\n                     ((c) >= CHAR_s && (c) <= CHAR_z))\n#else\n#define ISLOWER(c)  ((c) >= CHAR_a && (c) <= CHAR_z)\n#endif\n\n/* Literals that must be escaped: \\ ? * + | . ^ $ { } [ ] ( ) */\n\nstatic const char *pcre2_escaped_literals =\n  STR_BACKSLASH STR_QUESTION_MARK STR_ASTERISK STR_PLUS\n  STR_VERTICAL_LINE STR_DOT STR_CIRCUMFLEX_ACCENT STR_DOLLAR_SIGN\n  STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET\n  STR_LEFT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET\n  STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS;\n\n/* Recognized escaped metacharacters in POSIX basic patterns. */\n\nstatic const char *posix_meta_escapes =\n  STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS\n  STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET\n  STR_1 STR_2 STR_3 STR_4 STR_5 STR_6 STR_7 STR_8 STR_9;\n\n/* Recognized POSIX classes, colon-separated. */\n\nstatic const char *posix_classes =\n  STR_a STR_l STR_p STR_h STR_a STR_COLON\n  STR_l STR_o STR_w STR_e STR_r STR_COLON\n  STR_u STR_p STR_p STR_e STR_r STR_COLON\n  STR_a STR_l STR_n STR_u STR_m STR_COLON\n  STR_a STR_s STR_c STR_i STR_i STR_COLON\n  STR_b STR_l STR_a STR_n STR_k STR_COLON\n  STR_c STR_n STR_t STR_r STR_l STR_COLON\n  STR_d STR_i STR_g STR_i STR_t STR_COLON\n  STR_g STR_r STR_a STR_p STR_h STR_COLON\n  STR_p STR_r STR_i STR_n STR_t STR_COLON\n  STR_p STR_u STR_n STR_c STR_t STR_COLON\n  STR_s STR_p STR_a STR_c STR_e STR_COLON\n  STR_w STR_o STR_r STR_d STR_COLON\n  STR_x STR_d STR_i STR_g STR_i STR_t STR_COLON;\n\n\n\n/*************************************************\n*           Convert a POSIX pattern              *\n*************************************************/\n\n/* This function handles both basic and extended POSIX patterns.\n\nArguments:\n  pattype        the pattern type\n  pattern        the pattern\n  plength        length in code units\n  utf            TRUE if UTF\n  use_buffer     where to put the output\n  use_length     length of use_buffer\n  bufflenptr     where to put the used length\n  dummyrun       TRUE if a dummy run\n  ccontext       the convert context\n\nReturns:         0 => success\n                !0 => error code\n*/\n\nstatic int\nconvert_posix(uint32_t pattype, PCRE2_SPTR pattern, PCRE2_SIZE plength,\n  BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length,\n  PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext)\n{\nPCRE2_SPTR posix = pattern;\nPCRE2_UCHAR *p = use_buffer;\nPCRE2_UCHAR *pp = p;\nPCRE2_UCHAR *endp = p + use_length - 1;  /* Allow for trailing zero */\nPCRE2_SIZE convlength = 0;\n\nuint32_t bracount = 0;\nuint32_t posix_state = POSIX_START_REGEX;\nuint32_t lastspecial = 0;\nBOOL extended = (pattype & PCRE2_CONVERT_POSIX_EXTENDED) != 0;\nBOOL nextisliteral = FALSE;\n\n(void)utf;       /* Not used when Unicode not supported */\n(void)ccontext;  /* Not currently used */\n\n/* Initialize default for error offset as end of input. */\n\n*bufflenptr = plength;\nPUTCHARS(STR_STAR_NUL);\n\n/* Now scan the input. */\n\nwhile (plength > 0)\n  {\n  uint32_t c, sc;\n  int clength = 1;\n\n  /* Add in the length of the last item, then, if in the dummy run, pull the\n  pointer back to the start of the (temporary) buffer and then remember the\n  start of the next item. */\n\n  convlength += p - pp;\n  if (dummyrun) p = use_buffer;\n  pp = p;\n\n  /* Pick up the next character */\n\n#ifndef SUPPORT_UNICODE\n  c = *posix;\n#else\n  GETCHARLENTEST(c, posix, clength);\n#endif\n  posix += clength;\n  plength -= clength;\n\n  sc = nextisliteral? 0 : c;\n  nextisliteral = FALSE;\n\n  /* Handle a character within a class. */\n\n  if (posix_state >= POSIX_CLASS_NOT_STARTED)\n    {\n    if (c == CHAR_RIGHT_SQUARE_BRACKET)\n      {\n      PUTCHARS(STR_RIGHT_SQUARE_BRACKET);\n      posix_state = POSIX_NOT_BRACKET;\n      }\n\n    /* Not the end of the class */\n\n    else\n      {\n      switch (posix_state)\n        {\n        case POSIX_CLASS_STARTED:\n        if (ISLOWER(c)) break;  /* Remain in started state */\n        posix_state = POSIX_CLASS_NOT_STARTED;\n        if (c == CHAR_COLON  && plength > 0 &&\n            *posix == CHAR_RIGHT_SQUARE_BRACKET)\n          {\n          PUTCHARS(STR_COLON_RIGHT_SQUARE_BRACKET);\n          plength--;\n          posix++;\n          continue;    /* With next character after :] */\n          }\n        PCRE2_FALLTHROUGH /* Fall through */\n\n        case POSIX_CLASS_NOT_STARTED:\n        if (c == CHAR_LEFT_SQUARE_BRACKET)\n          posix_state = POSIX_CLASS_STARTING;\n        break;\n\n        case POSIX_CLASS_STARTING:\n        if (c == CHAR_COLON) posix_state = POSIX_CLASS_STARTED;\n        break;\n        }\n\n      if (c == CHAR_BACKSLASH) PUTCHARS(STR_BACKSLASH);\n      if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;\n      memcpy(p, posix - clength, CU2BYTES(clength));\n      p += clength;\n      }\n    }\n\n  /* Handle a character not within a class. */\n\n  else switch(sc)\n    {\n    case CHAR_LEFT_SQUARE_BRACKET:\n    PUTCHARS(STR_LEFT_SQUARE_BRACKET);\n\n#ifdef NEVER\n    /* We could handle special cases [[:<:]] and [[:>:]] (which PCRE does\n    support) but they are not part of POSIX 1003.1. */\n\n    if (plength >= 6)\n      {\n      if (posix[0] == CHAR_LEFT_SQUARE_BRACKET &&\n          posix[1] == CHAR_COLON &&\n          (posix[2] == CHAR_LESS_THAN_SIGN ||\n           posix[2] == CHAR_GREATER_THAN_SIGN) &&\n          posix[3] == CHAR_COLON &&\n          posix[4] == CHAR_RIGHT_SQUARE_BRACKET &&\n          posix[5] == CHAR_RIGHT_SQUARE_BRACKET)\n        {\n        if (p + 6 > endp) return PCRE2_ERROR_NOMEMORY;\n        memcpy(p, posix, CU2BYTES(6));\n        p += 6;\n        posix += 6;\n        plength -= 6;\n        continue;  /* With next character */\n        }\n      }\n#endif\n\n    /* Handle start of \"normal\" character classes */\n\n    posix_state = POSIX_CLASS_NOT_STARTED;\n\n    /* Handle ^ and ] as first characters */\n\n    if (plength > 0)\n      {\n      if (*posix == CHAR_CIRCUMFLEX_ACCENT)\n        {\n        posix++;\n        plength--;\n        PUTCHARS(STR_CIRCUMFLEX_ACCENT);\n        }\n      if (plength > 0 && *posix == CHAR_RIGHT_SQUARE_BRACKET)\n        {\n        posix++;\n        plength--;\n        PUTCHARS(STR_RIGHT_SQUARE_BRACKET);\n        }\n      }\n    break;\n\n    case CHAR_BACKSLASH:\n    if (plength == 0) return PCRE2_ERROR_END_BACKSLASH;\n    if (extended) nextisliteral = TRUE; else\n      {\n      if (*posix < 255 && strchr(posix_meta_escapes, *posix) != NULL)\n        {\n        if (*posix >= CHAR_0 && *posix <= CHAR_9) PUTCHARS(STR_BACKSLASH);\n        if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;\n        lastspecial = *p++ = *posix++;\n        plength--;\n        }\n      else nextisliteral = TRUE;\n      }\n    break;\n\n    case CHAR_RIGHT_PARENTHESIS:\n    if (!extended || bracount == 0) goto ESCAPE_LITERAL;\n    bracount--;\n    goto COPY_SPECIAL;\n\n    case CHAR_LEFT_PARENTHESIS:\n    bracount++;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case CHAR_QUESTION_MARK:\n    case CHAR_PLUS:\n    case CHAR_LEFT_CURLY_BRACKET:\n    case CHAR_RIGHT_CURLY_BRACKET:\n    case CHAR_VERTICAL_LINE:\n    if (!extended) goto ESCAPE_LITERAL;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case CHAR_DOT:\n    case CHAR_DOLLAR_SIGN:\n    posix_state = POSIX_NOT_BRACKET;\n    COPY_SPECIAL:\n    lastspecial = c;\n    if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;\n    *p++ = c;\n    break;\n\n    case CHAR_ASTERISK:\n    if (lastspecial != CHAR_ASTERISK)\n      {\n      if (!extended && (posix_state < POSIX_NOT_BRACKET ||\n          lastspecial == CHAR_LEFT_PARENTHESIS))\n        goto ESCAPE_LITERAL;\n      goto COPY_SPECIAL;\n      }\n    break;   /* Ignore second and subsequent asterisks */\n\n    case CHAR_CIRCUMFLEX_ACCENT:\n    if (extended) goto COPY_SPECIAL;\n    if (posix_state == POSIX_START_REGEX ||\n        lastspecial == CHAR_LEFT_PARENTHESIS)\n      {\n      posix_state = POSIX_ANCHORED;\n      goto COPY_SPECIAL;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    default:\n    if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL)\n      {\n      ESCAPE_LITERAL:\n      PUTCHARS(STR_BACKSLASH);\n      }\n    lastspecial = 0xff;  /* Indicates nothing special */\n    if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;\n    memcpy(p, posix - clength, CU2BYTES(clength));\n    p += clength;\n    posix_state = POSIX_NOT_BRACKET;\n    break;\n    }\n  }\n\nif (posix_state >= POSIX_CLASS_NOT_STARTED)\n  return PCRE2_ERROR_MISSING_SQUARE_BRACKET;\nconvlength += p - pp;        /* Final segment */\n*bufflenptr = convlength;\n*p++ = 0;\nreturn 0;\n}\n\n\n/*************************************************\n*           Convert a glob pattern               *\n*************************************************/\n\n/* Context for writing the output into a buffer. */\n\ntypedef struct pcre2_output_context {\n  PCRE2_UCHAR *output;                  /* current output position */\n  PCRE2_SPTR output_end;                /* output end */\n  PCRE2_SIZE output_size;               /* size of the output */\n  uint8_t out_str[8];                   /* string copied to the output */\n} pcre2_output_context;\n\n\n/* Write a character into the output.\n\nArguments:\n  out            output context\n  chr            the next character\n*/\n\nstatic void\nconvert_glob_write(pcre2_output_context *out, PCRE2_UCHAR chr)\n{\nout->output_size++;\n\nif (out->output < out->output_end)\n  *out->output++ = chr;\n}\n\n\n/* Write a string into the output.\n\nArguments:\n  out            output context\n  length         length of out->out_str\n*/\n\nstatic void\nconvert_glob_write_str(pcre2_output_context *out, PCRE2_SIZE length)\n{\nuint8_t *out_str = out->out_str;\nPCRE2_UCHAR *output = out->output;\nPCRE2_SPTR output_end = out->output_end;\nPCRE2_SIZE output_size = out->output_size;\n\ndo\n  {\n  output_size++;\n\n  if (output < output_end)\n    *output++ = *out_str++;\n  }\nwhile (--length != 0);\n\nout->output = output;\nout->output_size = output_size;\n}\n\n\n/* Prints the separator into the output.\n\nArguments:\n  out            output context\n  separator      glob separator\n  with_escape    backslash is needed before separator\n*/\n\nstatic void\nconvert_glob_print_separator(pcre2_output_context *out,\n  PCRE2_UCHAR separator, BOOL with_escape)\n{\nif (with_escape)\n  convert_glob_write(out, CHAR_BACKSLASH);\n\nconvert_glob_write(out, separator);\n}\n\n\n/* Prints a wildcard into the output.\n\nArguments:\n  out            output context\n  separator      glob separator\n  with_escape    backslash is needed before separator\n*/\n\nstatic void\nconvert_glob_print_wildcard(pcre2_output_context *out,\n  PCRE2_UCHAR separator, BOOL with_escape)\n{\nout->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;\nout->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;\nconvert_glob_write_str(out, 2);\n\nconvert_glob_print_separator(out, separator, with_escape);\n\nconvert_glob_write(out, CHAR_RIGHT_SQUARE_BRACKET);\n}\n\n\n/* Parse a posix class.\n\nArguments:\n  from           starting point of scanning the range\n  pattern_end    end of pattern\n  out            output context\n\nReturns:  >0 => class index\n          0  => malformed class\n*/\n\nstatic int\nconvert_glob_parse_class(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,\n  pcre2_output_context *out)\n{\nPCRE2_SPTR start = *from + 1;\nPCRE2_SPTR pattern = start;\nconst char *class_ptr;\nPCRE2_UCHAR c;\nint class_index;\n\nwhile (TRUE)\n  {\n  if (pattern >= pattern_end) return 0;\n\n  c = *pattern++;\n\n  if (c < CHAR_a || c > CHAR_z) break;\n  }\n\nif (c != CHAR_COLON || pattern >= pattern_end ||\n    *pattern != CHAR_RIGHT_SQUARE_BRACKET)\n  return 0;\n\nclass_ptr = posix_classes;\nclass_index = 1;\n\nwhile (TRUE)\n  {\n  if (*class_ptr == 0) return 0;\n\n  pattern = start;\n\n  while (*pattern == (PCRE2_UCHAR) *class_ptr)\n    {\n    if (*pattern == CHAR_COLON)\n      {\n      pattern += 2;\n      start -= 2;\n\n      do convert_glob_write(out, *start++); while (start < pattern);\n\n      *from = pattern;\n      return class_index;\n      }\n    pattern++;\n    class_ptr++;\n    }\n\n  while (*class_ptr != CHAR_COLON) class_ptr++;\n  class_ptr++;\n  class_index++;\n  }\n}\n\n/* Checks whether the character is in the class.\n\nArguments:\n  class_index    class index\n  c              character\n\nReturns:   !0 => character is found in the class\n            0 => otherwise\n*/\n\nstatic BOOL\nconvert_glob_char_in_class(int class_index, PCRE2_UCHAR c)\n{\nconst uint8_t *cbits = PRIV(default_tables) + cbits_offset;\nint cbit;\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\nif (c > 0xff)\n  {\n  /* Can't access the character tables for c > 0xff */\n  return FALSE;\n  }\n#endif\n\n/* See posix_class_maps. This is a small local clone of that.\nNote that we don't know exactly what character tables will be used at\nmatch time, but, for the purposes of pattern conversion, it should be\nsufficient to use PCRE2's built-in default tables. */\n\nswitch (class_index)\n  {\n  case 1:                              /* alpha */\n  if (c == CHAR_UNDERSCORE) return FALSE;\n  if (((cbits + cbit_digit)[c/8] & (1u << (c&7))) != 0) return FALSE;\n  cbit = cbit_word;\n  break;\n\n  case 2: cbit = cbit_lower; break;    /* lower */\n  case 3: cbit = cbit_upper; break;    /* upper */\n\n  case 4:                              /* alnum */\n  if (c == CHAR_UNDERSCORE) return FALSE;\n  cbit = cbit_word;\n  break;\n\n  case 5:                              /* ascii */\n  if (((cbits + cbit_cntrl)[c/8] & (1u << (c&7))) != 0) return TRUE;\n  cbit = cbit_print;\n  break;\n\n  case 6:                              /* blank */\n  if (c == CHAR_LF || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)\n    return FALSE;\n  cbit = cbit_space;\n  break;\n\n  case 7: cbit = cbit_cntrl; break;    /* cntrl */\n  case 8: cbit = cbit_digit; break;    /* digit */\n  case 9: cbit = cbit_graph; break;    /* graph */\n  case 10: cbit = cbit_print; break;   /* print */\n  case 11: cbit = cbit_punct; break;   /* punct */\n  case 12: cbit = cbit_space; break;   /* space */\n  case 13: cbit = cbit_word; break;    /* word */\n  case 14: cbit = cbit_xdigit; break;  /* xdigit */\n  default: return FALSE;\n  }\n\nreturn ((cbits + cbit)[c/8] & (1u << (c&7))) != 0;\n}\n\n/* Parse a range of characters.\n\nArguments:\n  from           starting point of scanning the range\n  pattern_end    end of pattern\n  out            output context\n  separator      glob separator\n  with_escape    backslash is needed before separator\n\nReturns:         0 => success\n                !0 => error code\n*/\n\nstatic int\nconvert_glob_parse_range(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,\n  pcre2_output_context *out, BOOL utf, PCRE2_UCHAR separator,\n  BOOL with_escape, PCRE2_UCHAR escape, BOOL no_wildsep)\n{\nBOOL is_negative = FALSE;\nBOOL separator_seen = FALSE;\nBOOL has_prev_c;\nPCRE2_SPTR pattern = *from;\nPCRE2_SPTR char_start = NULL;\nuint32_t c, prev_c;\nint len, class_index;\n\n(void)utf; /* Avoid compiler warning. */\n\nif (pattern >= pattern_end)\n  {\n  *from = pattern;\n  return PCRE2_ERROR_MISSING_SQUARE_BRACKET;\n  }\n\nif (*pattern == CHAR_EXCLAMATION_MARK\n    || *pattern == CHAR_CIRCUMFLEX_ACCENT)\n  {\n  pattern++;\n\n  if (pattern >= pattern_end)\n    {\n    *from = pattern;\n    return PCRE2_ERROR_MISSING_SQUARE_BRACKET;\n    }\n\n  is_negative = TRUE;\n\n  out->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;\n  out->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;\n  len = 2;\n\n  if (!no_wildsep)\n    {\n    if (with_escape)\n      {\n      out->out_str[len] = CHAR_BACKSLASH;\n      len++;\n      }\n    out->out_str[len] = (uint8_t) separator;\n    }\n\n  convert_glob_write_str(out, len + 1);\n  }\nelse\n  convert_glob_write(out, CHAR_LEFT_SQUARE_BRACKET);\n\nhas_prev_c = FALSE;\nprev_c = 0;\n\nif (*pattern == CHAR_RIGHT_SQUARE_BRACKET)\n  {\n  out->out_str[0] = CHAR_BACKSLASH;\n  out->out_str[1] = CHAR_RIGHT_SQUARE_BRACKET;\n  convert_glob_write_str(out, 2);\n  has_prev_c = TRUE;\n  prev_c = CHAR_RIGHT_SQUARE_BRACKET;\n  pattern++;\n  }\n\nwhile (pattern < pattern_end)\n  {\n  char_start = pattern;\n  GETCHARINCTEST(c, pattern);\n\n  if (c == CHAR_RIGHT_SQUARE_BRACKET)\n    {\n    convert_glob_write(out, c);\n\n    if (!is_negative && !no_wildsep && separator_seen)\n      {\n      out->out_str[0] = CHAR_LEFT_PARENTHESIS;\n      out->out_str[1] = CHAR_QUESTION_MARK;\n      out->out_str[2] = CHAR_LESS_THAN_SIGN;\n      out->out_str[3] = CHAR_EXCLAMATION_MARK;\n      convert_glob_write_str(out, 4);\n\n      convert_glob_print_separator(out, separator, with_escape);\n      convert_glob_write(out, CHAR_RIGHT_PARENTHESIS);\n      }\n\n    *from = pattern;\n    return 0;\n    }\n\n  if (pattern >= pattern_end) break;\n\n  if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)\n    {\n    *from = pattern;\n    class_index = convert_glob_parse_class(from, pattern_end, out);\n\n    if (class_index != 0)\n      {\n      pattern = *from;\n\n      has_prev_c = FALSE;\n      prev_c = 0;\n\n      if (!is_negative &&\n          convert_glob_char_in_class (class_index, separator))\n        separator_seen = TRUE;\n      continue;\n      }\n    }\n  else if (c == CHAR_MINUS && has_prev_c &&\n           *pattern != CHAR_RIGHT_SQUARE_BRACKET)\n    {\n    convert_glob_write(out, CHAR_MINUS);\n\n    char_start = pattern;\n    GETCHARINCTEST(c, pattern);\n\n    if (pattern >= pattern_end) break;\n\n    if (escape != 0 && c == escape)\n      {\n      char_start = pattern;\n      GETCHARINCTEST(c, pattern);\n      }\n    else if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)\n      {\n      *from = pattern;\n      return PCRE2_ERROR_CONVERT_SYNTAX;\n      }\n\n    if (prev_c > c)\n      {\n      *from = pattern;\n      return PCRE2_ERROR_CONVERT_SYNTAX;\n      }\n\n    if (prev_c < separator && separator < c) separator_seen = TRUE;\n\n    has_prev_c = FALSE;\n    prev_c = 0;\n    }\n  else\n    {\n    if (escape != 0 && c == escape)\n      {\n      char_start = pattern;\n      GETCHARINCTEST(c, pattern);\n\n      if (pattern >= pattern_end) break;\n      }\n\n    has_prev_c = TRUE;\n    prev_c = c;\n    }\n\n  if (c == CHAR_LEFT_SQUARE_BRACKET || c == CHAR_RIGHT_SQUARE_BRACKET ||\n      c == CHAR_BACKSLASH || c == CHAR_MINUS)\n    convert_glob_write(out, CHAR_BACKSLASH);\n\n  if (c == separator) separator_seen = TRUE;\n\n  do convert_glob_write(out, *char_start++); while (char_start < pattern);\n  }\n\n*from = pattern;\nreturn PCRE2_ERROR_MISSING_SQUARE_BRACKET;\n}\n\n\n/* Prints a (*COMMIT) into the output.\n\nArguments:\n  out            output context\n*/\n\nstatic void\nconvert_glob_print_commit(pcre2_output_context *out)\n{\nout->out_str[0] = CHAR_LEFT_PARENTHESIS;\nout->out_str[1] = CHAR_ASTERISK;\nout->out_str[2] = CHAR_C;\nout->out_str[3] = CHAR_O;\nout->out_str[4] = CHAR_M;\nout->out_str[5] = CHAR_M;\nout->out_str[6] = CHAR_I;\nout->out_str[7] = CHAR_T;\nconvert_glob_write_str(out, 8);\nconvert_glob_write(out, CHAR_RIGHT_PARENTHESIS);\n}\n\n\n/* Bash glob converter.\n\nArguments:\n  pattype        the pattern type\n  pattern        the pattern\n  plength        length in code units\n  utf            TRUE if UTF\n  use_buffer     where to put the output\n  use_length     length of use_buffer\n  bufflenptr     where to put the used length\n  dummyrun       TRUE if a dummy run\n  ccontext       the convert context\n\nReturns:         0 => success\n                !0 => error code\n*/\n\nstatic int\nconvert_glob(uint32_t options, PCRE2_SPTR pattern, PCRE2_SIZE plength,\n  BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length,\n  PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext)\n{\npcre2_output_context out;\nPCRE2_SPTR pattern_start = pattern;\nPCRE2_SPTR pattern_end = pattern + plength;\nPCRE2_UCHAR separator = ccontext->glob_separator;\nPCRE2_UCHAR escape = ccontext->glob_escape;\nPCRE2_UCHAR c;\nBOOL no_wildsep = (options & PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR) != 0;\nBOOL no_starstar = (options & PCRE2_CONVERT_GLOB_NO_STARSTAR) != 0;\nBOOL in_atomic = FALSE;\nBOOL after_starstar = FALSE;\nBOOL no_slash_z = FALSE;\nBOOL with_escape, is_start, after_separator;\nint result = 0;\n\n(void)utf; /* Avoid compiler warning. */\n\n#ifdef SUPPORT_UNICODE\nif (utf && (separator >= 128 || escape >= 128))\n  {\n  /* Currently only ASCII characters are supported. */\n  *bufflenptr = 0;\n  return PCRE2_ERROR_CONVERT_SYNTAX;\n  }\n#endif\n\nwith_escape = strchr(pcre2_escaped_literals, separator) != NULL;\n\n/* Initialize default for error offset as end of input. */\nout.output = use_buffer;\nout.output_end = use_buffer + use_length;\nout.output_size = 0;\n\nout.out_str[0] = CHAR_LEFT_PARENTHESIS;\nout.out_str[1] = CHAR_QUESTION_MARK;\nout.out_str[2] = CHAR_s;\nout.out_str[3] = CHAR_RIGHT_PARENTHESIS;\nconvert_glob_write_str(&out, 4);\n\nis_start = TRUE;\n\nif (pattern < pattern_end && pattern[0] == CHAR_ASTERISK)\n  {\n  if (no_wildsep)\n    is_start = FALSE;\n  else if (!no_starstar && pattern + 1 < pattern_end &&\n           pattern[1] == CHAR_ASTERISK)\n    is_start = FALSE;\n  }\n\nif (is_start)\n  {\n  out.out_str[0] = CHAR_BACKSLASH;\n  out.out_str[1] = CHAR_A;\n  convert_glob_write_str(&out, 2);\n  }\n\nwhile (pattern < pattern_end)\n  {\n  c = *pattern++;\n\n  if (c == CHAR_ASTERISK)\n    {\n    is_start = pattern == pattern_start + 1;\n\n    if (in_atomic)\n      {\n      convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);\n      in_atomic = FALSE;\n      }\n\n    if (!no_starstar && pattern < pattern_end && *pattern == CHAR_ASTERISK)\n      {\n      after_separator = is_start || (pattern[-2] == separator);\n\n      do pattern++; while (pattern < pattern_end &&\n                           *pattern == CHAR_ASTERISK);\n\n      if (pattern >= pattern_end)\n        {\n        no_slash_z = TRUE;\n        break;\n        }\n\n      after_starstar = TRUE;\n\n      if (after_separator && escape != 0 && *pattern == escape &&\n          pattern + 1 < pattern_end && pattern[1] == separator)\n        pattern++;\n\n      if (is_start)\n        {\n        if (*pattern != separator) continue;\n\n        out.out_str[0] = CHAR_LEFT_PARENTHESIS;\n        out.out_str[1] = CHAR_QUESTION_MARK;\n        out.out_str[2] = CHAR_COLON;\n        out.out_str[3] = CHAR_BACKSLASH;\n        out.out_str[4] = CHAR_A;\n        out.out_str[5] = CHAR_VERTICAL_LINE;\n        convert_glob_write_str(&out, 6);\n\n        convert_glob_print_separator(&out, separator, with_escape);\n        convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);\n\n        pattern++;\n        continue;\n        }\n\n      convert_glob_print_commit(&out);\n\n      if (!after_separator || *pattern != separator)\n        {\n        out.out_str[0] = CHAR_DOT;\n        out.out_str[1] = CHAR_ASTERISK;\n        out.out_str[2] = CHAR_QUESTION_MARK;\n        convert_glob_write_str(&out, 3);\n        continue;\n        }\n\n      out.out_str[0] = CHAR_LEFT_PARENTHESIS;\n      out.out_str[1] = CHAR_QUESTION_MARK;\n      out.out_str[2] = CHAR_COLON;\n      out.out_str[3] = CHAR_DOT;\n      out.out_str[4] = CHAR_ASTERISK;\n      out.out_str[5] = CHAR_QUESTION_MARK;\n\n      convert_glob_write_str(&out, 6);\n\n      convert_glob_print_separator(&out, separator, with_escape);\n\n      out.out_str[0] = CHAR_RIGHT_PARENTHESIS;\n      out.out_str[1] = CHAR_QUESTION_MARK;\n      out.out_str[2] = CHAR_QUESTION_MARK;\n      convert_glob_write_str(&out, 3);\n\n      pattern++;\n      continue;\n      }\n\n    if (pattern < pattern_end && *pattern == CHAR_ASTERISK)\n      {\n      do pattern++; while (pattern < pattern_end &&\n                           *pattern == CHAR_ASTERISK);\n      }\n\n    if (no_wildsep)\n      {\n      if (pattern >= pattern_end)\n        {\n        no_slash_z = TRUE;\n        break;\n        }\n\n      /* Start check must be after the end check. */\n      if (is_start) continue;\n      }\n\n    if (!is_start)\n      {\n      if (after_starstar)\n        {\n        out.out_str[0] = CHAR_LEFT_PARENTHESIS;\n        out.out_str[1] = CHAR_QUESTION_MARK;\n        out.out_str[2] = CHAR_GREATER_THAN_SIGN;\n        convert_glob_write_str(&out, 3);\n        in_atomic = TRUE;\n        }\n      else\n        convert_glob_print_commit(&out);\n      }\n\n    if (no_wildsep)\n      convert_glob_write(&out, CHAR_DOT);\n    else\n      convert_glob_print_wildcard(&out, separator, with_escape);\n\n    out.out_str[0] = CHAR_ASTERISK;\n    out.out_str[1] = CHAR_QUESTION_MARK;\n    if (pattern >= pattern_end)\n      out.out_str[1] = CHAR_PLUS;\n    convert_glob_write_str(&out, 2);\n    continue;\n    }\n\n  if (c == CHAR_QUESTION_MARK)\n    {\n    if (no_wildsep)\n      convert_glob_write(&out, CHAR_DOT);\n    else\n      convert_glob_print_wildcard(&out, separator, with_escape);\n    continue;\n    }\n\n  if (c == CHAR_LEFT_SQUARE_BRACKET)\n    {\n    result = convert_glob_parse_range(&pattern, pattern_end,\n      &out, utf, separator, with_escape, escape, no_wildsep);\n    if (result != 0) break;\n    continue;\n    }\n\n  if (escape != 0 && c == escape)\n    {\n    if (pattern >= pattern_end)\n      {\n      result = PCRE2_ERROR_CONVERT_SYNTAX;\n      break;\n      }\n    c = *pattern++;\n    }\n\n  if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL)\n    convert_glob_write(&out, CHAR_BACKSLASH);\n\n  convert_glob_write(&out, c);\n  }\n\nif (result == 0)\n  {\n  if (!no_slash_z)\n    {\n    out.out_str[0] = CHAR_BACKSLASH;\n    out.out_str[1] = CHAR_z;\n    convert_glob_write_str(&out, 2);\n    }\n\n  if (in_atomic)\n    convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);\n\n  convert_glob_write(&out, CHAR_NUL);\n\n  if (!dummyrun && out.output_size != (PCRE2_SIZE) (out.output - use_buffer))\n    result = PCRE2_ERROR_NOMEMORY;\n  }\n\nif (result != 0)\n  {\n  *bufflenptr = pattern - pattern_start;\n  return result;\n  }\n\n*bufflenptr = out.output_size - 1;\nreturn 0;\n}\n\n\n/*************************************************\n*                Convert pattern                 *\n*************************************************/\n\n/* This is the external-facing function for converting other forms of pattern\ninto PCRE2 regular expression patterns. On error, the bufflenptr argument is\nused to return an offset in the original pattern.\n\nArguments:\n  pattern     the input pattern\n  plength     length of input, or PCRE2_ZERO_TERMINATED\n  options     options bits\n  buffptr     pointer to pointer to output buffer\n  bufflenptr  pointer to length of output buffer\n  ccontext    convert context or NULL\n\nReturns:      0 for success, else an error code (+ve or -ve)\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_pattern_convert(PCRE2_SPTR pattern, PCRE2_SIZE plength, uint32_t options,\n  PCRE2_UCHAR **buffptr, PCRE2_SIZE *bufflenptr,\n  pcre2_convert_context *ccontext)\n{\nint rc;\nPCRE2_UCHAR null_str[1] = { 0xcd };\nPCRE2_UCHAR dummy_buffer[DUMMY_BUFFER_SIZE];\nPCRE2_UCHAR *use_buffer = dummy_buffer;\nPCRE2_SIZE use_length = DUMMY_BUFFER_SIZE;\nBOOL utf = (options & PCRE2_CONVERT_UTF) != 0;\nuint32_t pattype = options & TYPE_OPTIONS;\n\nif (pattern == NULL && plength == 0)\n  pattern = null_str;\n\nif (pattern == NULL || bufflenptr == NULL)\n  {\n  if (bufflenptr != NULL) *bufflenptr = 0;  /* Error offset */\n  return PCRE2_ERROR_NULL;\n  }\n\nif ((options & ~ALL_OPTIONS) != 0 ||        /* Undefined bit set */\n    (pattype & (~pattype+1)) != pattype ||  /* More than one type set */\n    pattype == 0)                           /* No type set */\n  {\n  *bufflenptr = 0;                          /* Error offset */\n  return PCRE2_ERROR_BADOPTION;\n  }\n\nif (plength == PCRE2_ZERO_TERMINATED) plength = PRIV(strlen)(pattern);\nif (ccontext == NULL) ccontext =\n  (pcre2_convert_context *)(&PRIV(default_convert_context));\n\n/* Check UTF if required. */\n\n#ifndef SUPPORT_UNICODE\nif (utf)\n  {\n  *bufflenptr = 0;  /* Error offset */\n  return PCRE2_ERROR_UNICODE_NOT_SUPPORTED;\n  }\n#else\nif (utf && (options & PCRE2_CONVERT_NO_UTF_CHECK) == 0)\n  {\n  PCRE2_SIZE erroroffset;\n  rc = PRIV(valid_utf)(pattern, plength, &erroroffset);\n  if (rc != 0)\n    {\n    *bufflenptr = erroroffset;\n    return rc;\n    }\n  }\n#endif\n\n/* If buffptr is not NULL, and what it points to is not NULL, we are being\nprovided with a buffer and a length, so set them as the buffer to use. */\n\nif (buffptr != NULL && *buffptr != NULL)\n  {\n  use_buffer = *buffptr;\n  use_length = *bufflenptr;\n  }\n\n/* Call an individual converter, either just once (if a buffer was provided or\njust the length is needed), or twice (if a memory allocation is required). */\n\nfor (int i = 0; i < 2; i++)\n  {\n  PCRE2_UCHAR *allocated;\n  BOOL dummyrun = buffptr == NULL || *buffptr == NULL;\n\n  switch(pattype)\n    {\n    case PCRE2_CONVERT_GLOB:\n    rc = convert_glob(options & ~PCRE2_CONVERT_GLOB, pattern, plength, utf,\n      use_buffer, use_length, bufflenptr, dummyrun, ccontext);\n    break;\n\n    case PCRE2_CONVERT_POSIX_BASIC:\n    case PCRE2_CONVERT_POSIX_EXTENDED:\n    rc = convert_posix(pattype, pattern, plength, utf, use_buffer, use_length,\n      bufflenptr, dummyrun, ccontext);\n    break;\n\n    /* We have already validated pattype. */\n    /* LCOV_EXCL_START */\n    default:\n    PCRE2_DEBUG_UNREACHABLE();\n    *bufflenptr = 0;  /* Error offset */\n    return PCRE2_ERROR_INTERNAL;\n    /* LCOV_EXCL_STOP */\n    }\n\n  if (rc != 0 ||           /* Error */\n      buffptr == NULL ||   /* Just the length is required */\n      *buffptr != NULL)    /* Buffer was provided or allocated */\n    return rc;\n\n  /* Allocate memory for the buffer, with hidden space for an allocator at\n  the start. The next time round the loop runs the conversion for real. */\n\n  allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +\n    (*bufflenptr + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)ccontext);\n  if (allocated == NULL)\n    {\n    *bufflenptr = 0;  /* Error offset */\n    return PCRE2_ERROR_NOMEMORY;\n    }\n  *buffptr = (PCRE2_UCHAR *)(((char *)allocated) + sizeof(pcre2_memctl));\n\n  use_buffer = *buffptr;\n  use_length = *bufflenptr + 1;\n  }\n\n/* Running the loop above ought to have succeeded the second time. */\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE();\n*bufflenptr = 0;  /* Error offset */\nreturn PCRE2_ERROR_INTERNAL;\n/* LCOV_EXCL_STOP */\n}\n\n\n/*************************************************\n*            Free converted pattern              *\n*************************************************/\n\n/* This frees a converted pattern that was put in newly-allocated memory.\n\nArgument:   the converted pattern\nReturns:    nothing\n*/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_converted_pattern_free(PCRE2_UCHAR *converted)\n{\nif (converted != NULL)\n  {\n  pcre2_memctl *memctl =\n    (pcre2_memctl *)((char *)converted - sizeof(pcre2_memctl));\n  memctl->free(memctl, memctl->memory_data);\n  }\n}\n\n/* End of pcre2_convert.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_dfa_match.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains the external function pcre2_dfa_match(), which is an\nalternative matching function that uses a sort of DFA algorithm (not a true\nFSM). This is NOT Perl-compatible, but it has advantages in certain\napplications. */\n\n\n/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved\nthe performance of his patterns greatly. I could not use it as it stood, as it\nwas not thread safe, and made assumptions about pattern sizes. Also, it caused\ntest 7 to loop, and test 9 to crash with a segfault.\n\nThe issue is the check for duplicate states, which is done by a simple linear\nsearch up the state list. (Grep for \"duplicate\" below to find the code.) For\nmany patterns, there will never be many states active at one time, so a simple\nlinear search is fine. In patterns that have many active states, it might be a\nbottleneck. The suggested code used an indexing scheme to remember which states\nhad previously been used for each character, and avoided the linear search when\nit knew there was no chance of a duplicate. This was implemented when adding\nstates to the state lists.\n\nI wrote some thread-safe, not-limited code to try something similar at the time\nof checking for duplicates (instead of when adding states), using index vectors\non the stack. It did give a 13% improvement with one specially constructed\npattern for certain subject strings, but on other strings and on many of the\nsimpler patterns in the test suite it did worse. The major problem, I think,\nwas the extra time to initialize the index. This had to be done for each call\nof internal_dfa_match(). (The supplied patch used a static vector, initialized\nonly once - I suspect this was the cause of the problems with the tests.)\n\nOverall, I concluded that the gains in some cases did not outweigh the losses\nin others, so I abandoned this code. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n#define NLBLOCK mb             /* Block containing newline information */\n#define PSSTART start_subject  /* Field containing processed string start */\n#define PSEND   end_subject    /* Field containing processed string end */\n\n#define PUBLIC_DFA_MATCH_OPTIONS \\\n  (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \\\n   PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \\\n   PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART| \\\n   PCRE2_COPY_MATCHED_SUBJECT)\n\n\n/*************************************************\n*      Code parameters and static tables         *\n*************************************************/\n\n/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes\ninto others, under special conditions. A gap of 20 between the blocks should be\nenough. The resulting opcodes don't have to be less than 256 because they are\nnever stored, so we push them well clear of the normal opcodes. */\n\n#define OP_PROP_EXTRA       300\n#define OP_EXTUNI_EXTRA     320\n#define OP_ANYNL_EXTRA      340\n#define OP_HSPACE_EXTRA     360\n#define OP_VSPACE_EXTRA     380\n\n\n/* This table identifies those opcodes that are followed immediately by a\ncharacter that is to be tested in some way. This makes it possible to\ncentralize the loading of these characters. In the case of Type * etc, the\n\"character\" is the opcode for \\D, \\d, \\S, \\s, \\W, or \\w, which will always be a\nsmall value. Non-zero values in the table are the offsets from the opcode where\nthe character is to be found. ***NOTE*** If the start of this table is\nmodified, the three tables that follow must also be modified. */\n\nstatic const uint8_t coptable[] = {\n  0,                             /* End                                    */\n  0, 0, 0, 0, 0,                 /* \\A, \\G, \\K, \\B, \\b                     */\n  0, 0, 0, 0, 0, 0,              /* \\D, \\d, \\S, \\s, \\W, \\w                 */\n  0, 0, 0,                       /* Any, AllAny, Anybyte                   */\n  0, 0,                          /* \\P, \\p                                 */\n  0, 0, 0, 0, 0,                 /* \\R, \\H, \\h, \\V, \\v                     */\n  0,                             /* \\X                                     */\n  0, 0, 0, 0, 0, 0,              /* \\Z, \\z, $, $M, ^, ^M                   */\n  1,                             /* Char                                   */\n  1,                             /* Chari                                  */\n  1,                             /* not                                    */\n  1,                             /* noti                                   */\n  /* Positive single-char repeats                                          */\n  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */\n  1+IMM2_SIZE, 1+IMM2_SIZE,      /* upto, minupto                          */\n  1+IMM2_SIZE,                   /* exact                                  */\n  1, 1, 1, 1+IMM2_SIZE,          /* *+, ++, ?+, upto+                      */\n  1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */\n  1+IMM2_SIZE, 1+IMM2_SIZE,      /* upto I, minupto I                      */\n  1+IMM2_SIZE,                   /* exact I                                */\n  1, 1, 1, 1+IMM2_SIZE,          /* *+I, ++I, ?+I, upto+I                  */\n  /* Negative single-char repeats - only for chars < 256                   */\n  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */\n  1+IMM2_SIZE, 1+IMM2_SIZE,      /* NOT upto, minupto                      */\n  1+IMM2_SIZE,                   /* NOT exact                              */\n  1, 1, 1, 1+IMM2_SIZE,          /* NOT *+, ++, ?+, upto+                  */\n  1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */\n  1+IMM2_SIZE, 1+IMM2_SIZE,      /* NOT upto I, minupto I                  */\n  1+IMM2_SIZE,                   /* NOT exact I                            */\n  1, 1, 1, 1+IMM2_SIZE,          /* NOT *+I, ++I, ?+I, upto+I              */\n  /* Positive type repeats                                                 */\n  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */\n  1+IMM2_SIZE, 1+IMM2_SIZE,      /* Type upto, minupto                     */\n  1+IMM2_SIZE,                   /* Type exact                             */\n  1, 1, 1, 1+IMM2_SIZE,          /* Type *+, ++, ?+, upto+                 */\n  /* Character class & ref repeats                                         */\n  0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */\n  0, 0,                          /* CRRANGE, CRMINRANGE                    */\n  0, 0, 0, 0,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */\n  0,                             /* CLASS                                  */\n  0,                             /* NCLASS                                 */\n  0,                             /* XCLASS - variable length               */\n  0,                             /* ECLASS - variable length               */\n  0,                             /* REF                                    */\n  0,                             /* REFI                                   */\n  0,                             /* DNREF                                  */\n  0,                             /* DNREFI                                 */\n  0,                             /* RECURSE                                */\n  0,                             /* CALLOUT                                */\n  0,                             /* CALLOUT_STR                            */\n  0,                             /* Alt                                    */\n  0,                             /* Ket                                    */\n  0,                             /* KetRmax                                */\n  0,                             /* KetRmin                                */\n  0,                             /* KetRpos                                */\n  0, 0,                          /* Reverse, Vreverse                      */\n  0,                             /* Assert                                 */\n  0,                             /* Assert not                             */\n  0,                             /* Assert behind                          */\n  0,                             /* Assert behind not                      */\n  0,                             /* NA assert                              */\n  0,                             /* NA assert behind                       */\n  0,                             /* Assert scan substring                  */\n  0,                             /* ONCE                                   */\n  0,                             /* SCRIPT_RUN                             */\n  0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */\n  0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */\n  0, 0,                          /* CREF, DNCREF                           */\n  0, 0,                          /* RREF, DNRREF                           */\n  0, 0,                          /* FALSE, TRUE                            */\n  0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */\n  0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */\n  0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG         */\n  0, 0,                          /* COMMIT, COMMIT_ARG                     */\n  0, 0, 0,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */\n  0, 0, 0,                       /* CLOSE, SKIPZERO, DEFINE                */\n  0, 0,                          /* \\B and \\b in UCP mode                  */\n};\n\n/* This table identifies those opcodes that inspect a character. It is used to\nremember the fact that a character could have been inspected when the end of\nthe subject is reached. ***NOTE*** If the start of this table is modified, the\ntwo tables that follow must also be modified. */\n\nstatic const uint8_t poptable[] = {\n  0,                             /* End                                    */\n  0, 0, 0, 1, 1,                 /* \\A, \\G, \\K, \\B, \\b                     */\n  1, 1, 1, 1, 1, 1,              /* \\D, \\d, \\S, \\s, \\W, \\w                 */\n  1, 1, 1,                       /* Any, AllAny, Anybyte                   */\n  1, 1,                          /* \\P, \\p                                 */\n  1, 1, 1, 1, 1,                 /* \\R, \\H, \\h, \\V, \\v                     */\n  1,                             /* \\X                                     */\n  0, 0, 0, 0, 0, 0,              /* \\Z, \\z, $, $M, ^, ^M                   */\n  1,                             /* Char                                   */\n  1,                             /* Chari                                  */\n  1,                             /* not                                    */\n  1,                             /* noti                                   */\n  /* Positive single-char repeats                                          */\n  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */\n  1, 1, 1,                       /* upto, minupto, exact                   */\n  1, 1, 1, 1,                    /* *+, ++, ?+, upto+                      */\n  1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */\n  1, 1, 1,                       /* upto I, minupto I, exact I             */\n  1, 1, 1, 1,                    /* *+I, ++I, ?+I, upto+I                  */\n  /* Negative single-char repeats - only for chars < 256                   */\n  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */\n  1, 1, 1,                       /* NOT upto, minupto, exact               */\n  1, 1, 1, 1,                    /* NOT *+, ++, ?+, upto+                  */\n  1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */\n  1, 1, 1,                       /* NOT upto I, minupto I, exact I         */\n  1, 1, 1, 1,                    /* NOT *+I, ++I, ?+I, upto+I              */\n  /* Positive type repeats                                                 */\n  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */\n  1, 1, 1,                       /* Type upto, minupto, exact              */\n  1, 1, 1, 1,                    /* Type *+, ++, ?+, upto+                 */\n  /* Character class & ref repeats                                         */\n  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */\n  1, 1,                          /* CRRANGE, CRMINRANGE                    */\n  1, 1, 1, 1,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */\n  1,                             /* CLASS                                  */\n  1,                             /* NCLASS                                 */\n  1,                             /* XCLASS - variable length               */\n  1,                             /* ECLASS - variable length               */\n  0,                             /* REF                                    */\n  0,                             /* REFI                                   */\n  0,                             /* DNREF                                  */\n  0,                             /* DNREFI                                 */\n  0,                             /* RECURSE                                */\n  0,                             /* CALLOUT                                */\n  0,                             /* CALLOUT_STR                            */\n  0,                             /* Alt                                    */\n  0,                             /* Ket                                    */\n  0,                             /* KetRmax                                */\n  0,                             /* KetRmin                                */\n  0,                             /* KetRpos                                */\n  0, 0,                          /* Reverse, Vreverse                      */\n  0,                             /* Assert                                 */\n  0,                             /* Assert not                             */\n  0,                             /* Assert behind                          */\n  0,                             /* Assert behind not                      */\n  0,                             /* NA assert                              */\n  0,                             /* NA assert behind                       */\n  0,                             /* Assert scan substring                  */\n  0,                             /* ONCE                                   */\n  0,                             /* SCRIPT_RUN                             */\n  0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */\n  0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */\n  0, 0,                          /* CREF, DNCREF                           */\n  0, 0,                          /* RREF, DNRREF                           */\n  0, 0,                          /* FALSE, TRUE                            */\n  0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */\n  0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */\n  0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG         */\n  0, 0,                          /* COMMIT, COMMIT_ARG                     */\n  0, 0, 0,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */\n  0, 0, 0,                       /* CLOSE, SKIPZERO, DEFINE                */\n  1, 1,                          /* \\B and \\b in UCP mode                  */\n};\n\n/* Compile-time check that these tables have the correct size. */\nSTATIC_ASSERT(sizeof(coptable) == OP_TABLE_LENGTH, coptable);\nSTATIC_ASSERT(sizeof(poptable) == OP_TABLE_LENGTH, poptable);\n\n/* These 2 tables allow for compact code for testing for \\D, \\d, \\S, \\s, \\W,\nand \\w */\n\nstatic const uint8_t toptable1[] = {\n  0, 0, 0, 0, 0, 0,\n  ctype_digit, ctype_digit,\n  ctype_space, ctype_space,\n  ctype_word,  ctype_word,\n  0, 0                            /* OP_ANY, OP_ALLANY */\n};\n\nstatic const uint8_t toptable2[] = {\n  0, 0, 0, 0, 0, 0,\n  ctype_digit, 0,\n  ctype_space, 0,\n  ctype_word,  0,\n  1, 1                            /* OP_ANY, OP_ALLANY */\n};\n\n\n/* Structure for holding data about a particular state, which is in effect the\ncurrent data for an active path through the match tree. It must consist\nentirely of ints because the working vector we are passed, and which we put\nthese structures in, is a vector of ints. */\n\ntypedef struct stateblock {\n  int offset;                     /* Offset to opcode (-ve has meaning) */\n  int count;                      /* Count for repeats */\n  int data;                       /* Some use extra data */\n} stateblock;\n\n#define INTS_PER_STATEBLOCK  (int)(sizeof(stateblock)/sizeof(int))\n\n\n/* Before version 10.32 the recursive calls of internal_dfa_match() were passed\nlocal working space and output vectors that were created on the stack. This has\ncaused issues for some patterns, especially in small-stack environments such as\nWindows. A new scheme is now in use which sets up a vector on the stack, but if\nthis is too small, heap memory is used, up to the heap_limit. The main\nparameters are all numbers of ints because the workspace is a vector of ints.\n\nThe size of the starting stack vector, DFA_START_RWS_SIZE, is in bytes, and is\ndefined in pcre2_internal.h so as to be available to pcre2test when it is\nfinding the minimum heap requirement for a match. */\n\n#define OVEC_UNIT  (sizeof(PCRE2_SIZE)/sizeof(int))\n\n#define RWS_BASE_SIZE   (DFA_START_RWS_SIZE/sizeof(int))  /* Stack vector */\n#define RWS_RSIZE       1000                    /* Work size for recursion */\n#define RWS_OVEC_RSIZE  (1000*OVEC_UNIT)        /* Ovector for recursion */\n#define RWS_OVEC_OSIZE  (2*OVEC_UNIT)           /* Ovector in other cases */\n\n/* This structure is at the start of each workspace block. */\n\ntypedef struct RWS_anchor {\n  struct RWS_anchor *next;\n  uint32_t size;  /* Number of ints */\n  uint32_t free;  /* Number of ints */\n} RWS_anchor;\n\n#define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int))\n\n\n\n/*************************************************\n*               Process a callout                *\n*************************************************/\n\n/* This function is called to perform a callout.\n\nArguments:\n  code              current code pointer\n  offsets           points to current capture offsets\n  current_subject   start of current subject match\n  ptr               current position in subject\n  mb                the match block\n  extracode         extra code offset when called from condition\n  lengthptr         where to return the callout length\n\nReturns:            the return from the callout\n*/\n\nstatic int\ndo_callout_dfa(PCRE2_SPTR code, PCRE2_SIZE *offsets, PCRE2_SPTR current_subject,\n  PCRE2_SPTR ptr, dfa_match_block *mb, PCRE2_SIZE extracode,\n  PCRE2_SIZE *lengthptr)\n{\npcre2_callout_block *cb = mb->cb;\n\n*lengthptr = (code[extracode] == OP_CALLOUT)?\n  (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :\n  (PCRE2_SIZE)GET(code, 1 + 2*LINK_SIZE + extracode);\n\nif (mb->callout == NULL) return 0;    /* No callout provided */\n\n/* Fixed fields in the callout block are set once and for all at the start of\nmatching. */\n\ncb->offset_vector    = offsets;\ncb->start_match      = (PCRE2_SIZE)(current_subject - mb->start_subject);\ncb->current_position = (PCRE2_SIZE)(ptr - mb->start_subject);\ncb->pattern_position = GET(code, 1 + extracode);\ncb->next_item_length = GET(code, 1 + LINK_SIZE + extracode);\n\nif (code[extracode] == OP_CALLOUT)\n  {\n  cb->callout_number = code[1 + 2*LINK_SIZE + extracode];\n  cb->callout_string_offset = 0;\n  cb->callout_string = NULL;\n  cb->callout_string_length = 0;\n  }\nelse\n  {\n  cb->callout_number = 0;\n  cb->callout_string_offset = GET(code, 1 + 3*LINK_SIZE + extracode);\n  cb->callout_string = code + (1 + 4*LINK_SIZE + extracode) + 1;\n  cb->callout_string_length = *lengthptr - (1 + 4*LINK_SIZE) - 2;\n  }\n\nreturn (mb->callout)(cb, mb->callout_data);\n}\n\n\n\n/*************************************************\n*         Expand local workspace memory          *\n*************************************************/\n\n/* This function is called when internal_dfa_match() is about to be called\nrecursively and there is insufficient working space left in the current\nworkspace block. If there's an existing next block, use it; otherwise get a new\nblock unless the heap limit is reached.\n\nArguments:\n  rwsptr     pointer to block pointer (updated)\n  ovecsize   space needed for an ovector\n  mb         the match block\n\nReturns:     0 rwsptr has been updated\n            !0 an error code\n*/\n\nstatic int\nmore_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)\n{\nRWS_anchor *rws = *rwsptr;\nRWS_anchor *new;\n\nif (rws->next != NULL)\n  {\n  new = rws->next;\n  }\n\n/* Sizes in the RWS_anchor blocks are in units of sizeof(int), but\nmb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid\noverflow. */\n\nelse\n  {\n  uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2;\n  uint32_t newsizeK = newsize/(1024/sizeof(int));\n\n  if (newsizeK + mb->heap_used > mb->heap_limit)\n    newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);\n  newsize = newsizeK*(1024/sizeof(int));\n\n  if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)\n    return PCRE2_ERROR_HEAPLIMIT;\n  new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);\n  if (new == NULL) return PCRE2_ERROR_NOMEMORY;\n  mb->heap_used += newsizeK;\n  new->next = NULL;\n  new->size = newsize;\n  rws->next = new;\n  }\n\nnew->free = new->size - RWS_ANCHOR_SIZE;\n*rwsptr = new;\nreturn 0;\n}\n\n\n\n/*************************************************\n*     Match a Regular Expression - DFA engine    *\n*************************************************/\n\n/* This internal function applies a compiled pattern to a subject string,\nstarting at a given point, using a DFA engine. This function is called from the\nexternal one, possibly multiple times if the pattern is not anchored. The\nfunction calls itself recursively for some kinds of subpattern.\n\nArguments:\n  mb                the match_data block with fixed information\n  this_start_code   the opening bracket of this subexpression's code\n  current_subject   where we currently are in the subject string\n  start_offset      start offset in the subject string\n  offsets           vector to contain the matching string offsets\n  offsetcount       size of same\n  workspace         vector of workspace\n  wscount           size of same\n  rlevel            function call recursion level\n\nReturns:            > 0 => number of match offset pairs placed in offsets\n                    = 0 => offsets overflowed; longest matches are present\n                     -1 => failed to match\n                   < -1 => some kind of unexpected problem\n\nThe following macros are used for adding states to the two state vectors (one\nfor the current character, one for the following character). */\n\n#define ADD_ACTIVE(x,y) \\\n  if (active_count++ < wscount) \\\n    { \\\n    next_active_state->offset = (x); \\\n    next_active_state->count  = (y); \\\n    next_active_state++; \\\n    } \\\n  else return PCRE2_ERROR_DFA_WSSIZE\n\n#define ADD_ACTIVE_DATA(x,y,z) \\\n  if (active_count++ < wscount) \\\n    { \\\n    next_active_state->offset = (x); \\\n    next_active_state->count  = (y); \\\n    next_active_state->data   = (z); \\\n    next_active_state++; \\\n    } \\\n  else return PCRE2_ERROR_DFA_WSSIZE\n\n#define ADD_NEW(x,y) \\\n  if (new_count++ < wscount) \\\n    { \\\n    next_new_state->offset = (x); \\\n    next_new_state->count  = (y); \\\n    next_new_state++; \\\n    } \\\n  else return PCRE2_ERROR_DFA_WSSIZE\n\n#define ADD_NEW_DATA(x,y,z) \\\n  if (new_count++ < wscount) \\\n    { \\\n    next_new_state->offset = (x); \\\n    next_new_state->count  = (y); \\\n    next_new_state->data   = (z); \\\n    next_new_state++; \\\n    } \\\n  else return PCRE2_ERROR_DFA_WSSIZE\n\n/* And now, here is the code */\n\nstatic int\ninternal_dfa_match(\n  dfa_match_block *mb,\n  PCRE2_SPTR this_start_code,\n  PCRE2_SPTR current_subject,\n  PCRE2_SIZE start_offset,\n  PCRE2_SIZE *offsets,\n  uint32_t offsetcount,\n  int *workspace,\n  int wscount,\n  uint32_t rlevel,\n  int *RWS)\n{\nstateblock *active_states, *new_states, *temp_states;\nstateblock *next_active_state, *next_new_state;\nconst uint8_t *ctypes, *lcc, *fcc;\nPCRE2_SPTR ptr;\nPCRE2_SPTR end_code;\ndfa_recursion_info new_recursive;\nint active_count, new_count, match_count;\n\n/* Some fields in the mb block are frequently referenced, so we load them into\nindependent variables in the hope that this will perform better. */\n\nPCRE2_SPTR start_subject = mb->start_subject;\nPCRE2_SPTR end_subject = mb->end_subject;\nPCRE2_SPTR start_code = mb->start_code;\n\n#ifdef SUPPORT_UNICODE\nBOOL utf = (mb->poptions & PCRE2_UTF) != 0;\nBOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;\n#else\nBOOL utf = FALSE;\n#endif\n\nBOOL reset_could_continue = FALSE;\n\nif (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;\nif (rlevel++ > mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;\noffsetcount &= (uint32_t)(-2);  /* Round down */\n\nwscount -= 2;\nwscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /\n          (2 * INTS_PER_STATEBLOCK);\n\nctypes = mb->tables + ctypes_offset;\nlcc = mb->tables + lcc_offset;\nfcc = mb->tables + fcc_offset;\n\nmatch_count = PCRE2_ERROR_NOMATCH;   /* A negative number */\n\nactive_states = (stateblock *)(workspace + 2);\nnext_new_state = new_states = active_states + wscount;\nnew_count = 0;\n\n/* The first thing in any (sub) pattern is a bracket of some sort. Push all\nthe alternative states onto the list, and find out where the end is. This\nmakes is possible to use this function recursively, when we want to stop at a\nmatching internal ket rather than at the end.\n\nIf we are dealing with a backward assertion we have to find out the maximum\namount to move back, and set up each alternative appropriately. */\n\nif (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)\n  {\n  size_t max_back = 0;\n  size_t gone_back;\n\n  end_code = this_start_code;\n  do\n    {\n    size_t back = (size_t)GET2(end_code, 2+LINK_SIZE);\n    if (back > max_back) max_back = back;\n    end_code += GET(end_code, 1);\n    }\n  while (*end_code == OP_ALT);\n\n  /* If we can't go back the amount required for the longest lookbehind\n  pattern, go back as far as we can; some alternatives may still be viable. */\n\n#ifdef SUPPORT_UNICODE\n  /* In character mode we have to step back character by character */\n\n  if (utf)\n    {\n    for (gone_back = 0; gone_back < max_back; gone_back++)\n      {\n      if (current_subject <= start_subject) break;\n      current_subject--;\n      ACROSSCHAR(current_subject > start_subject, current_subject,\n        current_subject--);\n      }\n    }\n  else\n#endif\n\n  /* In byte-mode we can do this quickly. */\n\n    {\n    size_t current_offset = (size_t)(current_subject - start_subject);\n    gone_back = (current_offset < max_back)? current_offset : max_back;\n    current_subject -= gone_back;\n    }\n\n  /* Save the earliest consulted character */\n\n  if (current_subject < mb->start_used_ptr)\n    mb->start_used_ptr = current_subject;\n\n  /* Now we can process the individual branches. There will be an OP_REVERSE at\n  the start of each branch, except when the length of the branch is zero. */\n\n  end_code = this_start_code;\n  do\n    {\n    uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + IMM2_SIZE : 0;\n    size_t back = (revlen == 0)? 0 : (size_t)GET2(end_code, 2+LINK_SIZE);\n    if (back <= gone_back)\n      {\n      int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen);\n      ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));\n      }\n    end_code += GET(end_code, 1);\n    }\n  while (*end_code == OP_ALT);\n }\n\n/* This is the code for a \"normal\" subpattern (not a backward assertion). The\nstart of a whole pattern is always one of these. If we are at the top level,\nwe may be asked to restart matching from the same point that we reached for a\nprevious partial match. We still have to scan through the top-level branches to\nfind the end state. */\n\nelse\n  {\n  end_code = this_start_code;\n\n  /* Restarting */\n\n  if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0)\n    {\n    do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);\n    new_count = workspace[1];\n    if (!workspace[0])\n      memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock));\n    }\n\n  /* Not restarting */\n\n  else\n    {\n    int length = 1 + LINK_SIZE +\n      ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||\n        *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)\n        ? IMM2_SIZE:0);\n    do\n      {\n      ADD_NEW((int)(end_code - start_code + length), 0);\n      end_code += GET(end_code, 1);\n      length = 1 + LINK_SIZE;\n      }\n    while (*end_code == OP_ALT);\n    }\n  }\n\nworkspace[0] = 0;    /* Bit indicating which vector is current */\n\n/* Loop for scanning the subject */\n\nptr = current_subject;\nfor (;;)\n  {\n  int i, j;\n  int clen, dlen;\n  uint32_t c, d;\n  BOOL partial_newline = FALSE;\n  BOOL could_continue = reset_could_continue;\n  reset_could_continue = FALSE;\n\n  if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr;\n\n  /* Make the new state list into the active state list and empty the\n  new state list. */\n\n  temp_states = active_states;\n  active_states = new_states;\n  new_states = temp_states;\n  active_count = new_count;\n  new_count = 0;\n\n  workspace[0] ^= 1;              /* Remember for the restarting feature */\n  workspace[1] = active_count;\n\n  /* Set the pointers for adding new states */\n\n  next_active_state = active_states + active_count;\n  next_new_state = new_states;\n\n  /* Load the current character from the subject outside the loop, as many\n  different states may want to look at it, and we assume that at least one\n  will. */\n\n  if (ptr < end_subject)\n    {\n    clen = 1;        /* Number of data items in the character */\n#ifdef SUPPORT_UNICODE\n    GETCHARLENTEST(c, ptr, clen);\n#else\n    c = *ptr;\n#endif  /* SUPPORT_UNICODE */\n    }\n  else\n    {\n    clen = 0;        /* This indicates the end of the subject */\n    c = NOTACHAR;    /* This value should never actually be used */\n    }\n\n  /* Scan up the active states and act on each one. The result of an action\n  may be to add more states to the currently active list (e.g. on hitting a\n  parenthesis) or it may be to put states on the new list, for considering\n  when we move the character pointer on. */\n\n  for (i = 0; i < active_count; i++)\n    {\n    stateblock *current_state = active_states + i;\n    BOOL caseless = FALSE;\n    PCRE2_SPTR code;\n    uint32_t codevalue;\n    int state_offset = current_state->offset;\n    int rrc;\n    int count;\n\n    /* A negative offset is a special case meaning \"hold off going to this\n    (negated) state until the number of characters in the data field have\n    been skipped\". If the could_continue flag was passed over from a previous\n    state, arrange for it to passed on. */\n\n    if (state_offset < 0)\n      {\n      if (current_state->data > 0)\n        {\n        ADD_NEW_DATA(state_offset, current_state->count,\n          current_state->data - 1);\n        if (could_continue) reset_could_continue = TRUE;\n        continue;\n        }\n      else\n        {\n        current_state->offset = state_offset = -state_offset;\n        }\n      }\n\n    /* Check for a duplicate state with the same count, and skip if found.\n    See the note at the head of this module about the possibility of improving\n    performance here. */\n\n    for (j = 0; j < i; j++)\n      {\n      if (active_states[j].offset == state_offset &&\n          active_states[j].count == current_state->count)\n        goto NEXT_ACTIVE_STATE;\n      }\n\n    /* The state offset is the offset to the opcode */\n\n    code = start_code + state_offset;\n    codevalue = *code;\n\n    /* If this opcode inspects a character, but we are at the end of the\n    subject, remember the fact for use when testing for a partial match. */\n\n    if (clen == 0 && poptable[codevalue] != 0)\n      could_continue = TRUE;\n\n    /* If this opcode is followed by an inline character, load it. It is\n    tempting to test for the presence of a subject character here, but that\n    is wrong, because sometimes zero repetitions of the subject are\n    permitted.\n\n    We also use this mechanism for opcodes such as OP_TYPEPLUS that take an\n    argument that is not a data character - but is always one byte long because\n    the values are small. We have to take special action to deal with  \\P, \\p,\n    \\H, \\h, \\V, \\v and \\X in this case. To keep the other cases fast, convert\n    these ones to new opcodes. */\n\n    if (coptable[codevalue] > 0)\n      {\n      dlen = 1;\n#ifdef SUPPORT_UNICODE\n      if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else\n#endif  /* SUPPORT_UNICODE */\n      d = code[coptable[codevalue]];\n      if (codevalue >= OP_TYPESTAR)\n        {\n        switch(d)\n          {\n          case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM;\n          case OP_NOTPROP:\n          case OP_PROP: codevalue += OP_PROP_EXTRA; break;\n          case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;\n          case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;\n          case OP_NOT_HSPACE:\n          case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;\n          case OP_NOT_VSPACE:\n          case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;\n          default: break;\n          }\n        }\n      }\n    else\n      {\n      dlen = 0;         /* Not strictly necessary, but compilers moan */\n      d = NOTACHAR;     /* if these variables are not set. */\n      }\n\n\n    /* Now process the individual opcodes */\n\n    switch (codevalue)\n      {\n/* ========================================================================== */\n      /* Reached a closing bracket. If not at the end of the pattern, carry\n      on with the next opcode. For repeating opcodes, also add the repeat\n      state. Note that KETRPOS will always be encountered at the end of the\n      subpattern, because the possessive subpattern repeats are always handled\n      using recursive calls. Thus, it never adds any new states.\n\n      At the end of the (sub)pattern, unless we have an empty string and\n      PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the\n      start of the subject, save the match data, shifting up all previous\n      matches so we always have the longest first. */\n\n      case OP_KET:\n      case OP_KETRMIN:\n      case OP_KETRMAX:\n      case OP_KETRPOS:\n      if (code != end_code)\n        {\n        ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);\n        if (codevalue != OP_KET)\n          {\n          ADD_ACTIVE(state_offset - (int)GET(code, 1), 0);\n          }\n        }\n      else\n        {\n        if (ptr > current_subject ||\n            ((mb->moptions & PCRE2_NOTEMPTY) == 0 &&\n              ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 ||\n                current_subject > start_subject + mb->start_offset)))\n          {\n          if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;\n            else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)\n              match_count = 0;\n          count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;\n          if (count > 0) (void)memmove(offsets + 2, offsets,\n            (size_t)count * sizeof(PCRE2_SIZE));\n          if (offsetcount >= 2)\n            {\n            offsets[0] = (PCRE2_SIZE)(current_subject - start_subject);\n            offsets[1] = (PCRE2_SIZE)(ptr - start_subject);\n            }\n          if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count;\n          }\n        }\n      break;\n\n/* ========================================================================== */\n      /* These opcodes add to the current list of states without looking\n      at the current character. */\n\n      /*-----------------------------------------------------------------*/\n      case OP_ALT:\n      do { code += GET(code, 1); } while (*code == OP_ALT);\n      ADD_ACTIVE((int)(code - start_code), 0);\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_BRA:\n      case OP_SBRA:\n      do\n        {\n        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);\n        code += GET(code, 1);\n        }\n      while (*code == OP_ALT);\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_CBRA:\n      case OP_SCBRA:\n      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE),  0);\n      code += GET(code, 1);\n      while (*code == OP_ALT)\n        {\n        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE),  0);\n        code += GET(code, 1);\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_BRAZERO:\n      case OP_BRAMINZERO:\n      ADD_ACTIVE(state_offset + 1, 0);\n      code += 1 + GET(code, 2);\n      while (*code == OP_ALT) code += GET(code, 1);\n      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_SKIPZERO:\n      code += 1 + GET(code, 2);\n      while (*code == OP_ALT) code += GET(code, 1);\n      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_CIRC:\n      if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0)\n        { ADD_ACTIVE(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_CIRCM:\n      if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) ||\n          ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 )\n            && WAS_NEWLINE(ptr)))\n        { ADD_ACTIVE(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EOD:\n      if (ptr >= end_subject)\n        {\n        if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n          return PCRE2_ERROR_PARTIAL;\n        else { ADD_ACTIVE(state_offset + 1, 0); }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_SOD:\n      if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_SOM:\n      if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }\n      break;\n\n\n/* ========================================================================== */\n      /* These opcodes inspect the next subject character, and sometimes\n      the previous one as well, but do not have an argument. The variable\n      clen contains the length of the current character and is zero if we are\n      at the end of the subject. */\n\n      /*-----------------------------------------------------------------*/\n      case OP_ANY:\n      if (clen > 0 && !IS_NEWLINE(ptr))\n        {\n        if (ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else\n          {\n          ADD_NEW(state_offset + 1, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_ALLANY:\n      if (clen > 0)\n        { ADD_NEW(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EODN:\n      if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))\n        {\n        if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n          return PCRE2_ERROR_PARTIAL;\n        ADD_ACTIVE(state_offset + 1, 0);\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_DOLL:\n      if ((mb->moptions & PCRE2_NOTEOL) == 0)\n        {\n        if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n          could_continue = TRUE;\n        else if (clen == 0 ||\n            ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&\n               (ptr == end_subject - mb->nllen)\n            ))\n          { ADD_ACTIVE(state_offset + 1, 0); }\n        else if (ptr + 1 >= mb->end_subject &&\n                 (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&\n                 NLBLOCK->nltype == NLTYPE_FIXED &&\n                 NLBLOCK->nllen == 2 &&\n                 c == NLBLOCK->nl[0])\n          {\n          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n            {\n            reset_could_continue = TRUE;\n            ADD_NEW_DATA(-(state_offset + 1), 0, 1);\n            }\n          else could_continue = partial_newline = TRUE;\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_DOLLM:\n      if ((mb->moptions & PCRE2_NOTEOL) == 0)\n        {\n        if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n          could_continue = TRUE;\n        else if (clen == 0 ||\n            ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))\n          { ADD_ACTIVE(state_offset + 1, 0); }\n        else if (ptr + 1 >= mb->end_subject &&\n                 (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&\n                 NLBLOCK->nltype == NLTYPE_FIXED &&\n                 NLBLOCK->nllen == 2 &&\n                 c == NLBLOCK->nl[0])\n          {\n          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n            {\n            reset_could_continue = TRUE;\n            ADD_NEW_DATA(-(state_offset + 1), 0, 1);\n            }\n          else could_continue = partial_newline = TRUE;\n          }\n        }\n      else if (IS_NEWLINE(ptr))\n        { ADD_ACTIVE(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n\n      case OP_DIGIT:\n      case OP_WHITESPACE:\n      case OP_WORDCHAR:\n      if (clen > 0 && c < 256 &&\n            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)\n        { ADD_NEW(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_NOT_DIGIT:\n      case OP_NOT_WHITESPACE:\n      case OP_NOT_WORDCHAR:\n      if (clen > 0 && (c >= 256 ||\n            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))\n        { ADD_NEW(state_offset + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_WORD_BOUNDARY:\n      case OP_NOT_WORD_BOUNDARY:\n      case OP_NOT_UCP_WORD_BOUNDARY:\n      case OP_UCP_WORD_BOUNDARY:\n        {\n        int left_word, right_word;\n\n        if (ptr > start_subject)\n          {\n          PCRE2_SPTR temp = ptr - 1;\n          if (temp < mb->start_used_ptr) mb->start_used_ptr = temp;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n          if (utf) { BACKCHAR(temp); }\n#endif\n          GETCHARTEST(d, temp);\n#ifdef SUPPORT_UNICODE\n          if (codevalue == OP_UCP_WORD_BOUNDARY ||\n              codevalue == OP_NOT_UCP_WORD_BOUNDARY)\n            {\n            int chartype = UCD_CHARTYPE(d);\n            int category = PRIV(ucp_gentype)[chartype];\n            left_word = (category == ucp_L || category == ucp_N ||\n              chartype == ucp_Mn || chartype == ucp_Pc);\n            }\n          else\n#endif\n          left_word = d < 256 && (ctypes[d] & ctype_word) != 0;\n          }\n        else left_word = FALSE;\n\n        if (clen > 0)\n          {\n          if (ptr >= mb->last_used_ptr)\n            {\n            PCRE2_SPTR temp = ptr + 1;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n            if (utf) { FORWARDCHARTEST(temp, mb->end_subject); }\n#endif\n            mb->last_used_ptr = temp;\n            }\n#ifdef SUPPORT_UNICODE\n          if (codevalue == OP_UCP_WORD_BOUNDARY ||\n              codevalue == OP_NOT_UCP_WORD_BOUNDARY)\n            {\n            int chartype = UCD_CHARTYPE(c);\n            int category = PRIV(ucp_gentype)[chartype];\n            right_word = (category == ucp_L || category == ucp_N ||\n              chartype == ucp_Mn || chartype == ucp_Pc);\n            }\n          else\n#endif\n          right_word = c < 256 && (ctypes[c] & ctype_word) != 0;\n          }\n        else right_word = FALSE;\n\n        if ((left_word == right_word) ==\n            (codevalue == OP_NOT_WORD_BOUNDARY ||\n             codevalue == OP_NOT_UCP_WORD_BOUNDARY))\n          { ADD_ACTIVE(state_offset + 1, 0); }\n        }\n      break;\n\n\n      /*-----------------------------------------------------------------*/\n      /* Check the next character by Unicode property. We will get here only\n      if the support is in the binary; otherwise a compile-time error occurs.\n      */\n\n#ifdef SUPPORT_UNICODE\n      case OP_PROP:\n      case OP_NOTPROP:\n      if (clen > 0)\n        {\n        BOOL OK;\n        int chartype;\n        const uint32_t *cp;\n        const ucd_record * prop = GET_UCD(c);\n        switch(code[1])\n          {\n          case PT_LAMP:\n          chartype = prop->chartype;\n          OK = chartype == ucp_Lu || chartype == ucp_Ll ||\n               chartype == ucp_Lt;\n          break;\n\n          case PT_GC:\n          OK = PRIV(ucp_gentype)[prop->chartype] == code[2];\n          break;\n\n          case PT_PC:\n          OK = prop->chartype == code[2];\n          break;\n\n          case PT_SC:\n          OK = prop->script == code[2];\n          break;\n\n          case PT_SCX:\n          OK = (prop->script == code[2] ||\n                MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[2]) != 0);\n          break;\n\n          /* These are specials for combination cases. */\n\n          case PT_ALNUM:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N;\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          switch(c)\n            {\n            HSPACE_CASES:\n            VSPACE_CASES:\n            OK = TRUE;\n            break;\n\n            default:\n            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;\n            break;\n            }\n          break;\n\n          case PT_WORD:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N ||\n               chartype == ucp_Mn || chartype == ucp_Pc;\n          break;\n\n          case PT_CLIST:\n#if PCRE2_CODE_UNIT_WIDTH == 32\n          if (c > MAX_UTF_CODE_POINT)\n            {\n            OK = FALSE;\n            break;\n            }\n#endif\n          cp = PRIV(ucd_caseless_sets) + code[2];\n          for (;;)\n            {\n            if (c < *cp) { OK = FALSE; break; }\n            if (c == *cp++) { OK = TRUE; break; }\n            }\n          break;\n\n          case PT_UCNC:\n          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||\n               c >= 0xe000;\n          break;\n\n          case PT_BIDICL:\n          OK = UCD_BIDICLASS(c) == code[2];\n          break;\n\n          case PT_BOOL:\n          OK = MAPBIT(PRIV(ucd_boolprop_sets) +\n            UCD_BPROPS_PROP(prop), code[2]) != 0;\n          break;\n\n          /* Should never occur, but keep compilers from grumbling. */\n\n          default:\n          OK = codevalue != OP_PROP;\n          break;\n          }\n\n        if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }\n        }\n      break;\n#endif\n\n\n\n/* ========================================================================== */\n      /* These opcodes likewise inspect the subject character, but have an\n      argument that is not a data character. It is one of these opcodes:\n      OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,\n      OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */\n\n      case OP_TYPEPLUS:\n      case OP_TYPEMINPLUS:\n      case OP_TYPEPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }\n      if (clen > 0)\n        {\n        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||\n            (c < 256 &&\n              (d != OP_ANY || !IS_NEWLINE(ptr)) &&\n              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))\n          {\n          if (count > 0 && codevalue == OP_TYPEPOSPLUS)\n            {\n            active_count--;            /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW(state_offset, count);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_TYPEQUERY:\n      case OP_TYPEMINQUERY:\n      case OP_TYPEPOSQUERY:\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||\n            (c < 256 &&\n              (d != OP_ANY || !IS_NEWLINE(ptr)) &&\n              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))\n          {\n          if (codevalue == OP_TYPEPOSQUERY)\n            {\n            active_count--;            /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW(state_offset + 2, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_TYPESTAR:\n      case OP_TYPEMINSTAR:\n      case OP_TYPEPOSSTAR:\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||\n            (c < 256 &&\n              (d != OP_ANY || !IS_NEWLINE(ptr)) &&\n              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))\n          {\n          if (codevalue == OP_TYPEPOSSTAR)\n            {\n            active_count--;            /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW(state_offset, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_TYPEEXACT:\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||\n            (c < 256 &&\n              (d != OP_ANY || !IS_NEWLINE(ptr)) &&\n              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))\n          {\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }\n          else\n            { ADD_NEW(state_offset, count); }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_TYPEUPTO:\n      case OP_TYPEMINUPTO:\n      case OP_TYPEPOSUPTO:\n      ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&\n            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            c == NLBLOCK->nl[0])\n          {\n          could_continue = partial_newline = TRUE;\n          }\n        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||\n            (c < 256 &&\n              (d != OP_ANY || !IS_NEWLINE(ptr)) &&\n              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))\n          {\n          if (codevalue == OP_TYPEPOSUPTO)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }\n          else\n            { ADD_NEW(state_offset, count); }\n          }\n        }\n      break;\n\n/* ========================================================================== */\n      /* These are virtual opcodes that are used when something like\n      OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its\n      argument. It keeps the code above fast for the other cases. The argument\n      is in the d variable. */\n\n#ifdef SUPPORT_UNICODE\n      case OP_PROP_EXTRA + OP_TYPEPLUS:\n      case OP_PROP_EXTRA + OP_TYPEMINPLUS:\n      case OP_PROP_EXTRA + OP_TYPEPOSPLUS:\n      count = current_state->count;           /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }\n      if (clen > 0)\n        {\n        BOOL OK;\n        int chartype;\n        const uint32_t *cp;\n        const ucd_record * prop = GET_UCD(c);\n        switch(code[2])\n          {\n          case PT_LAMP:\n          chartype = prop->chartype;\n          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;\n          break;\n\n          case PT_GC:\n          OK = PRIV(ucp_gentype)[prop->chartype] == code[3];\n          break;\n\n          case PT_PC:\n          OK = prop->chartype == code[3];\n          break;\n\n          case PT_SC:\n          OK = prop->script == code[3];\n          break;\n\n          case PT_SCX:\n          OK = (prop->script == code[3] ||\n                MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);\n          break;\n\n          /* These are specials for combination cases. */\n\n          case PT_ALNUM:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N;\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          switch(c)\n            {\n            HSPACE_CASES:\n            VSPACE_CASES:\n            OK = TRUE;\n            break;\n\n            default:\n            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;\n            break;\n            }\n          break;\n\n          case PT_WORD:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N ||\n               chartype == ucp_Mn || chartype == ucp_Pc;\n          break;\n\n          case PT_CLIST:\n#if PCRE2_CODE_UNIT_WIDTH == 32\n          if (c > MAX_UTF_CODE_POINT)\n            {\n            OK = FALSE;\n            break;\n            }\n#endif\n          cp = PRIV(ucd_caseless_sets) + code[3];\n          for (;;)\n            {\n            if (c < *cp) { OK = FALSE; break; }\n            if (c == *cp++) { OK = TRUE; break; }\n            }\n          break;\n\n          case PT_UCNC:\n          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||\n               c >= 0xe000;\n          break;\n\n          case PT_BIDICL:\n          OK = UCD_BIDICLASS(c) == code[3];\n          break;\n\n          case PT_BOOL:\n          OK = MAPBIT(PRIV(ucd_boolprop_sets) +\n            UCD_BPROPS_PROP(prop), code[3]) != 0;\n          break;\n\n          /* Should never occur, but keep compilers from grumbling. */\n\n          default:\n          OK = codevalue != OP_PROP;\n          break;\n          }\n\n        if (OK == (d == OP_PROP))\n          {\n          if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW(state_offset, count);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EXTUNI_EXTRA + OP_TYPEPLUS:\n      case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:\n      case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }\n      if (clen > 0)\n        {\n        int ncount = 0;\n        if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)\n          {\n          active_count--;           /* Remove non-match possibility */\n          next_active_state--;\n          }\n        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,\n          &ncount);\n        count++;\n        ADD_NEW_DATA(-state_offset, count, ncount);\n        }\n      break;\n#endif\n\n      /*-----------------------------------------------------------------*/\n      case OP_ANYNL_EXTRA + OP_TYPEPLUS:\n      case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:\n      case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }\n      if (clen > 0)\n        {\n        int ncount = 0;\n        switch (c)\n          {\n          case CHAR_VT:\n          case CHAR_FF:\n          case CHAR_NEL:\n#ifndef EBCDIC\n          case 0x2028:\n          case 0x2029:\n#endif  /* Not EBCDIC */\n          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;\n          goto ANYNL01;\n\n          case CHAR_CR:\n          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;\n          /* Fall through */\n\n          ANYNL01:\n          case CHAR_LF:\n          if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW_DATA(-state_offset, count, ncount);\n          break;\n\n          default:\n          break;\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_VSPACE_EXTRA + OP_TYPEPLUS:\n      case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:\n      case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          VSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          break;\n          }\n\n        if (OK == (d == OP_VSPACE))\n          {\n          if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW_DATA(-state_offset, count, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_HSPACE_EXTRA + OP_TYPEPLUS:\n      case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:\n      case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          HSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          break;\n          }\n\n        if (OK == (d == OP_HSPACE))\n          {\n          if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW_DATA(-state_offset, count, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n#ifdef SUPPORT_UNICODE\n      case OP_PROP_EXTRA + OP_TYPEQUERY:\n      case OP_PROP_EXTRA + OP_TYPEMINQUERY:\n      case OP_PROP_EXTRA + OP_TYPEPOSQUERY:\n      count = 4;\n      goto QS1;\n\n      case OP_PROP_EXTRA + OP_TYPESTAR:\n      case OP_PROP_EXTRA + OP_TYPEMINSTAR:\n      case OP_PROP_EXTRA + OP_TYPEPOSSTAR:\n      count = 0;\n\n      QS1:\n\n      ADD_ACTIVE(state_offset + 4, 0);\n      if (clen > 0)\n        {\n        BOOL OK;\n        int chartype;\n        const uint32_t *cp;\n        const ucd_record * prop = GET_UCD(c);\n        switch(code[2])\n          {\n          case PT_LAMP:\n          chartype = prop->chartype;\n          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;\n          break;\n\n          case PT_GC:\n          OK = PRIV(ucp_gentype)[prop->chartype] == code[3];\n          break;\n\n          case PT_PC:\n          OK = prop->chartype == code[3];\n          break;\n\n          case PT_SC:\n          OK = prop->script == code[3];\n          break;\n\n          case PT_SCX:\n          OK = (prop->script == code[3] ||\n                MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);\n          break;\n\n          /* These are specials for combination cases. */\n\n          case PT_ALNUM:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N;\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          switch(c)\n            {\n            HSPACE_CASES:\n            VSPACE_CASES:\n            OK = TRUE;\n            break;\n\n            default:\n            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;\n            break;\n            }\n          break;\n\n          case PT_WORD:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N ||\n               chartype == ucp_Mn || chartype == ucp_Pc;\n          break;\n\n          case PT_CLIST:\n#if PCRE2_CODE_UNIT_WIDTH == 32\n          if (c > MAX_UTF_CODE_POINT)\n            {\n            OK = FALSE;\n            break;\n            }\n#endif\n          cp = PRIV(ucd_caseless_sets) + code[3];\n          for (;;)\n            {\n            if (c < *cp) { OK = FALSE; break; }\n            if (c == *cp++) { OK = TRUE; break; }\n            }\n          break;\n\n          case PT_UCNC:\n          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||\n               c >= 0xe000;\n          break;\n\n          case PT_BIDICL:\n          OK = UCD_BIDICLASS(c) == code[3];\n          break;\n\n          case PT_BOOL:\n          OK = MAPBIT(PRIV(ucd_boolprop_sets) +\n            UCD_BPROPS_PROP(prop), code[3]) != 0;\n          break;\n\n          /* Should never occur, but keep compilers from grumbling. */\n\n          default:\n          OK = codevalue != OP_PROP;\n          break;\n          }\n\n        if (OK == (d == OP_PROP))\n          {\n          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||\n              codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW(state_offset + count, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EXTUNI_EXTRA + OP_TYPEQUERY:\n      case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:\n      case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:\n      count = 2;\n      goto QS2;\n\n      case OP_EXTUNI_EXTRA + OP_TYPESTAR:\n      case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:\n      case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:\n      count = 0;\n\n      QS2:\n\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        int ncount = 0;\n        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||\n            codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)\n          {\n          active_count--;           /* Remove non-match possibility */\n          next_active_state--;\n          }\n        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,\n          &ncount);\n        ADD_NEW_DATA(-(state_offset + count), 0, ncount);\n        }\n      break;\n#endif\n\n      /*-----------------------------------------------------------------*/\n      case OP_ANYNL_EXTRA + OP_TYPEQUERY:\n      case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:\n      case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:\n      count = 2;\n      goto QS3;\n\n      case OP_ANYNL_EXTRA + OP_TYPESTAR:\n      case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:\n      case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:\n      count = 0;\n\n      QS3:\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        int ncount = 0;\n        switch (c)\n          {\n          case CHAR_VT:\n          case CHAR_FF:\n          case CHAR_NEL:\n#ifndef EBCDIC\n          case 0x2028:\n          case 0x2029:\n#endif  /* Not EBCDIC */\n          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;\n          goto ANYNL02;\n\n          case CHAR_CR:\n          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;\n          /* Fall through */\n\n          ANYNL02:\n          case CHAR_LF:\n          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||\n              codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);\n          break;\n\n          default:\n          break;\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_VSPACE_EXTRA + OP_TYPEQUERY:\n      case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:\n      case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:\n      count = 2;\n      goto QS4;\n\n      case OP_VSPACE_EXTRA + OP_TYPESTAR:\n      case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:\n      case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:\n      count = 0;\n\n      QS4:\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          VSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          break;\n          }\n        if (OK == (d == OP_VSPACE))\n          {\n          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||\n              codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_HSPACE_EXTRA + OP_TYPEQUERY:\n      case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:\n      case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:\n      count = 2;\n      goto QS5;\n\n      case OP_HSPACE_EXTRA + OP_TYPESTAR:\n      case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:\n      case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:\n      count = 0;\n\n      QS5:\n      ADD_ACTIVE(state_offset + 2, 0);\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          HSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          break;\n          }\n\n        if (OK == (d == OP_HSPACE))\n          {\n          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||\n              codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n#ifdef SUPPORT_UNICODE\n      case OP_PROP_EXTRA + OP_TYPEEXACT:\n      case OP_PROP_EXTRA + OP_TYPEUPTO:\n      case OP_PROP_EXTRA + OP_TYPEMINUPTO:\n      case OP_PROP_EXTRA + OP_TYPEPOSUPTO:\n      if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)\n        { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        BOOL OK;\n        int chartype;\n        const uint32_t *cp;\n        const ucd_record * prop = GET_UCD(c);\n        switch(code[1 + IMM2_SIZE + 1])\n          {\n          case PT_LAMP:\n          chartype = prop->chartype;\n          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;\n          break;\n\n          case PT_GC:\n          OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];\n          break;\n\n          case PT_PC:\n          OK = prop->chartype == code[1 + IMM2_SIZE + 2];\n          break;\n\n          case PT_SC:\n          OK = prop->script == code[1 + IMM2_SIZE + 2];\n          break;\n\n          case PT_SCX:\n          OK = (prop->script == code[1 + IMM2_SIZE + 2] ||\n                MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop),\n                  code[1 + IMM2_SIZE + 2]) != 0);\n          break;\n\n          /* These are specials for combination cases. */\n\n          case PT_ALNUM:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N;\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          switch(c)\n            {\n            HSPACE_CASES:\n            VSPACE_CASES:\n            OK = TRUE;\n            break;\n\n            default:\n            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;\n            break;\n            }\n          break;\n\n          case PT_WORD:\n          chartype = prop->chartype;\n          OK = PRIV(ucp_gentype)[chartype] == ucp_L ||\n               PRIV(ucp_gentype)[chartype] == ucp_N ||\n               chartype == ucp_Mn || chartype == ucp_Pc;\n          break;\n\n          case PT_CLIST:\n#if PCRE2_CODE_UNIT_WIDTH == 32\n          if (c > MAX_UTF_CODE_POINT)\n            {\n            OK = FALSE;\n            break;\n            }\n#endif\n          cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];\n          for (;;)\n            {\n            if (c < *cp) { OK = FALSE; break; }\n            if (c == *cp++) { OK = TRUE; break; }\n            }\n          break;\n\n          case PT_UCNC:\n          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||\n               c >= 0xe000;\n          break;\n\n          case PT_BIDICL:\n          OK = UCD_BIDICLASS(c) == code[1 + IMM2_SIZE + 2];\n          break;\n\n          case PT_BOOL:\n          OK = MAPBIT(PRIV(ucd_boolprop_sets) +\n            UCD_BPROPS_PROP(prop), code[1 + IMM2_SIZE + 2]) != 0;\n          break;\n\n          /* Should never occur, but keep compilers from grumbling. */\n\n          default:\n          OK = codevalue != OP_PROP;\n          break;\n          }\n\n        if (OK == (d == OP_PROP))\n          {\n          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }\n          else\n            { ADD_NEW(state_offset, count); }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EXTUNI_EXTRA + OP_TYPEEXACT:\n      case OP_EXTUNI_EXTRA + OP_TYPEUPTO:\n      case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:\n      case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:\n      if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)\n        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        PCRE2_SPTR nptr;\n        int ncount = 0;\n        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)\n          {\n          active_count--;           /* Remove non-match possibility */\n          next_active_state--;\n          }\n        nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,\n          &ncount);\n        if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n            reset_could_continue = TRUE;\n        if (++count >= (int)GET2(code, 1))\n          { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }\n        else\n          { ADD_NEW_DATA(-state_offset, count, ncount); }\n        }\n      break;\n#endif\n\n      /*-----------------------------------------------------------------*/\n      case OP_ANYNL_EXTRA + OP_TYPEEXACT:\n      case OP_ANYNL_EXTRA + OP_TYPEUPTO:\n      case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:\n      case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:\n      if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)\n        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        int ncount = 0;\n        switch (c)\n          {\n          case CHAR_VT:\n          case CHAR_FF:\n          case CHAR_NEL:\n#ifndef EBCDIC\n          case 0x2028:\n          case 0x2029:\n#endif  /* Not EBCDIC */\n          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;\n          goto ANYNL03;\n\n          case CHAR_CR:\n          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;\n          /* Fall through */\n\n          ANYNL03:\n          case CHAR_LF:\n          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }\n          else\n            { ADD_NEW_DATA(-state_offset, count, ncount); }\n          break;\n\n          default:\n          break;\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_VSPACE_EXTRA + OP_TYPEEXACT:\n      case OP_VSPACE_EXTRA + OP_TYPEUPTO:\n      case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:\n      case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:\n      if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)\n        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          VSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          }\n\n        if (OK == (d == OP_VSPACE))\n          {\n          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }\n          else\n            { ADD_NEW_DATA(-state_offset, count, 0); }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_HSPACE_EXTRA + OP_TYPEEXACT:\n      case OP_HSPACE_EXTRA + OP_TYPEUPTO:\n      case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:\n      case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:\n      if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)\n        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        BOOL OK;\n        switch (c)\n          {\n          HSPACE_CASES:\n          OK = TRUE;\n          break;\n\n          default:\n          OK = FALSE;\n          break;\n          }\n\n        if (OK == (d == OP_HSPACE))\n          {\n          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)\n            {\n            active_count--;           /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }\n          else\n            { ADD_NEW_DATA(-state_offset, count, 0); }\n          }\n        }\n      break;\n\n/* ========================================================================== */\n      /* These opcodes are followed by a character that is usually compared\n      to the current subject character; it is loaded into d. We still get\n      here even if there is no subject character, because in some cases zero\n      repetitions are permitted. */\n\n      /*-----------------------------------------------------------------*/\n      case OP_CHAR:\n      if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_CHARI:\n      if (clen == 0) break;\n\n#ifdef SUPPORT_UNICODE\n      if (utf_or_ucp)\n        {\n        if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else\n          {\n          unsigned int othercase;\n          if (c < 128)\n            othercase = fcc[c];\n          else\n            othercase = UCD_OTHERCASE(c);\n          if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }\n          }\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n      /* Not UTF or UCP mode */\n        {\n        if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))\n          { ADD_NEW(state_offset + 2, 0); }\n        }\n      break;\n\n\n#ifdef SUPPORT_UNICODE\n      /*-----------------------------------------------------------------*/\n      /* This is a tricky one because it can match more than one character.\n      Find out how many characters to skip, and then set up a negative state\n      to wait for them to pass before continuing. */\n\n      case OP_EXTUNI:\n      if (clen > 0)\n        {\n        int ncount = 0;\n        PCRE2_SPTR nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject,\n          end_subject, utf, &ncount);\n        if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n            reset_could_continue = TRUE;\n        ADD_NEW_DATA(-(state_offset + 1), 0, ncount);\n        }\n      break;\n#endif\n\n      /*-----------------------------------------------------------------*/\n      /* This is a tricky like EXTUNI because it too can match more than one\n      character (when CR is followed by LF). In this case, set up a negative\n      state to wait for one character to pass before continuing. */\n\n      case OP_ANYNL:\n      if (clen > 0) switch(c)\n        {\n        case CHAR_VT:\n        case CHAR_FF:\n        case CHAR_NEL:\n#ifndef EBCDIC\n        case 0x2028:\n        case 0x2029:\n#endif  /* Not EBCDIC */\n        if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;\n        PCRE2_FALLTHROUGH /* Fall through */\n\n        case CHAR_LF:\n        ADD_NEW(state_offset + 1, 0);\n        break;\n\n        case CHAR_CR:\n        if (ptr + 1 >= end_subject)\n          {\n          ADD_NEW(state_offset + 1, 0);\n          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)\n            reset_could_continue = TRUE;\n          }\n        else if (UCHAR21TEST(ptr + 1) == CHAR_LF)\n          {\n          ADD_NEW_DATA(-(state_offset + 1), 0, 1);\n          }\n        else\n          {\n          ADD_NEW(state_offset + 1, 0);\n          }\n        break;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_NOT_VSPACE:\n      if (clen > 0) switch(c)\n        {\n        VSPACE_CASES:\n        break;\n\n        default:\n        ADD_NEW(state_offset + 1, 0);\n        break;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_VSPACE:\n      if (clen > 0) switch(c)\n        {\n        VSPACE_CASES:\n        ADD_NEW(state_offset + 1, 0);\n        break;\n\n        default:\n        break;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_NOT_HSPACE:\n      if (clen > 0) switch(c)\n        {\n        HSPACE_CASES:\n        break;\n\n        default:\n        ADD_NEW(state_offset + 1, 0);\n        break;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_HSPACE:\n      if (clen > 0) switch(c)\n        {\n        HSPACE_CASES:\n        ADD_NEW(state_offset + 1, 0);\n        break;\n\n        default:\n        break;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      /* Match a negated single character casefully. */\n\n      case OP_NOT:\n      if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      /* Match a negated single character caselessly. */\n\n      case OP_NOTI:\n      if (clen > 0)\n        {\n        uint32_t otherd;\n#ifdef SUPPORT_UNICODE\n        if (utf_or_ucp && d >= 128)\n          otherd = UCD_OTHERCASE(d);\n        else\n#endif  /* SUPPORT_UNICODE */\n        otherd = TABLE_GET(d, fcc, d);\n        if (c != d && c != otherd)\n          { ADD_NEW(state_offset + dlen + 1, 0); }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_PLUSI:\n      case OP_MINPLUSI:\n      case OP_POSPLUSI:\n      case OP_NOTPLUSI:\n      case OP_NOTMINPLUSI:\n      case OP_NOTPOSPLUSI:\n      caseless = TRUE;\n      codevalue -= OP_STARI - OP_STAR;\n\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_PLUS:\n      case OP_MINPLUS:\n      case OP_POSPLUS:\n      case OP_NOTPLUS:\n      case OP_NOTMINPLUS:\n      case OP_NOTPOSPLUS:\n      count = current_state->count;  /* Already matched */\n      if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }\n      if (clen > 0)\n        {\n        uint32_t otherd = NOTACHAR;\n        if (caseless)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf_or_ucp && d >= 128)\n            otherd = UCD_OTHERCASE(d);\n          else\n#endif  /* SUPPORT_UNICODE */\n          otherd = TABLE_GET(d, fcc, d);\n          }\n        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))\n          {\n          if (count > 0 &&\n              (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))\n            {\n            active_count--;             /* Remove non-match possibility */\n            next_active_state--;\n            }\n          count++;\n          ADD_NEW(state_offset, count);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_QUERYI:\n      case OP_MINQUERYI:\n      case OP_POSQUERYI:\n      case OP_NOTQUERYI:\n      case OP_NOTMINQUERYI:\n      case OP_NOTPOSQUERYI:\n      caseless = TRUE;\n      codevalue -= OP_STARI - OP_STAR;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_QUERY:\n      case OP_MINQUERY:\n      case OP_POSQUERY:\n      case OP_NOTQUERY:\n      case OP_NOTMINQUERY:\n      case OP_NOTPOSQUERY:\n      ADD_ACTIVE(state_offset + dlen + 1, 0);\n      if (clen > 0)\n        {\n        uint32_t otherd = NOTACHAR;\n        if (caseless)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf_or_ucp && d >= 128)\n            otherd = UCD_OTHERCASE(d);\n          else\n#endif  /* SUPPORT_UNICODE */\n          otherd = TABLE_GET(d, fcc, d);\n          }\n        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))\n          {\n          if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)\n            {\n            active_count--;            /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW(state_offset + dlen + 1, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_STARI:\n      case OP_MINSTARI:\n      case OP_POSSTARI:\n      case OP_NOTSTARI:\n      case OP_NOTMINSTARI:\n      case OP_NOTPOSSTARI:\n      caseless = TRUE;\n      codevalue -= OP_STARI - OP_STAR;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_STAR:\n      case OP_MINSTAR:\n      case OP_POSSTAR:\n      case OP_NOTSTAR:\n      case OP_NOTMINSTAR:\n      case OP_NOTPOSSTAR:\n      ADD_ACTIVE(state_offset + dlen + 1, 0);\n      if (clen > 0)\n        {\n        uint32_t otherd = NOTACHAR;\n        if (caseless)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf_or_ucp && d >= 128)\n            otherd = UCD_OTHERCASE(d);\n          else\n#endif  /* SUPPORT_UNICODE */\n          otherd = TABLE_GET(d, fcc, d);\n          }\n        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))\n          {\n          if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)\n            {\n            active_count--;            /* Remove non-match possibility */\n            next_active_state--;\n            }\n          ADD_NEW(state_offset, 0);\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_EXACTI:\n      case OP_NOTEXACTI:\n      caseless = TRUE;\n      codevalue -= OP_STARI - OP_STAR;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_EXACT:\n      case OP_NOTEXACT:\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        uint32_t otherd = NOTACHAR;\n        if (caseless)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf_or_ucp && d >= 128)\n            otherd = UCD_OTHERCASE(d);\n          else\n#endif  /* SUPPORT_UNICODE */\n          otherd = TABLE_GET(d, fcc, d);\n          }\n        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))\n          {\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }\n          else\n            { ADD_NEW(state_offset, count); }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_UPTOI:\n      case OP_MINUPTOI:\n      case OP_POSUPTOI:\n      case OP_NOTUPTOI:\n      case OP_NOTMINUPTOI:\n      case OP_NOTPOSUPTOI:\n      caseless = TRUE;\n      codevalue -= OP_STARI - OP_STAR;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_UPTO:\n      case OP_MINUPTO:\n      case OP_POSUPTO:\n      case OP_NOTUPTO:\n      case OP_NOTMINUPTO:\n      case OP_NOTPOSUPTO:\n      ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);\n      count = current_state->count;  /* Number already matched */\n      if (clen > 0)\n        {\n        uint32_t otherd = NOTACHAR;\n        if (caseless)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf_or_ucp && d >= 128)\n            otherd = UCD_OTHERCASE(d);\n          else\n#endif  /* SUPPORT_UNICODE */\n          otherd = TABLE_GET(d, fcc, d);\n          }\n        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))\n          {\n          if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)\n            {\n            active_count--;             /* Remove non-match possibility */\n            next_active_state--;\n            }\n          if (++count >= (int)GET2(code, 1))\n            { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }\n          else\n            { ADD_NEW(state_offset, count); }\n          }\n        }\n      break;\n\n\n/* ========================================================================== */\n      /* These are the class-handling opcodes */\n\n      case OP_CLASS:\n      case OP_NCLASS:\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_XCLASS:\n      case OP_ECLASS:\n#endif\n        {\n        BOOL isinclass = FALSE;\n        int next_state_offset;\n        PCRE2_SPTR ecode;\n\n#ifdef SUPPORT_WIDE_CHARS\n        /* An extended class may have a table or a list of single characters,\n        ranges, or both, and it may be positive or negative. There's a\n        function that sorts all this out. */\n\n        if (codevalue == OP_XCLASS)\n         {\n         ecode = code + GET(code, 1);\n         if (clen > 0)\n           isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE,\n             (const uint8_t*)mb->start_code, utf);\n         }\n\n        /* A nested set-based class has internal opcodes for performing\n        set operations. */\n\n        else if (codevalue == OP_ECLASS)\n         {\n         ecode = code + GET(code, 1);\n         if (clen > 0)\n           isinclass = PRIV(eclass)(c, code + 1 + LINK_SIZE, ecode,\n             (const uint8_t*)mb->start_code, utf);\n         }\n\n        else\n#endif /* SUPPORT_WIDE_CHARS */\n\n        /* For a simple class, there is always just a 32-byte table, and we\n        can set isinclass from it. */\n\n          {\n          ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));\n          if (clen > 0)\n            {\n            isinclass = (c > 255)? (codevalue == OP_NCLASS) :\n              ((((const uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0);\n            }\n          }\n\n        /* At this point, isinclass is set for all kinds of class, and ecode\n        points to the byte after the end of the class. If there is a\n        quantifier, this is where it will be. */\n\n        next_state_offset = (int)(ecode - start_code);\n\n        switch (*ecode)\n          {\n          case OP_CRSTAR:\n          case OP_CRMINSTAR:\n          case OP_CRPOSSTAR:\n          ADD_ACTIVE(next_state_offset + 1, 0);\n          if (isinclass)\n            {\n            if (*ecode == OP_CRPOSSTAR)\n              {\n              active_count--;           /* Remove non-match possibility */\n              next_active_state--;\n              }\n            ADD_NEW(state_offset, 0);\n            }\n          break;\n\n          case OP_CRPLUS:\n          case OP_CRMINPLUS:\n          case OP_CRPOSPLUS:\n          count = current_state->count;  /* Already matched */\n          if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }\n          if (isinclass)\n            {\n            if (count > 0 && *ecode == OP_CRPOSPLUS)\n              {\n              active_count--;           /* Remove non-match possibility */\n              next_active_state--;\n              }\n            count++;\n            ADD_NEW(state_offset, count);\n            }\n          break;\n\n          case OP_CRQUERY:\n          case OP_CRMINQUERY:\n          case OP_CRPOSQUERY:\n          ADD_ACTIVE(next_state_offset + 1, 0);\n          if (isinclass)\n            {\n            if (*ecode == OP_CRPOSQUERY)\n              {\n              active_count--;           /* Remove non-match possibility */\n              next_active_state--;\n              }\n            ADD_NEW(next_state_offset + 1, 0);\n            }\n          break;\n\n          case OP_CRRANGE:\n          case OP_CRMINRANGE:\n          case OP_CRPOSRANGE:\n          count = current_state->count;  /* Already matched */\n          if (count >= (int)GET2(ecode, 1))\n            { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }\n          if (isinclass)\n            {\n            int max = (int)GET2(ecode, 1 + IMM2_SIZE);\n\n            if (*ecode == OP_CRPOSRANGE && count >= (int)GET2(ecode, 1))\n              {\n              active_count--;           /* Remove non-match possibility */\n              next_active_state--;\n              }\n\n            if (++count >= max && max != 0)   /* Max 0 => no limit */\n              { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }\n            else\n              { ADD_NEW(state_offset, count); }\n            }\n          break;\n\n          default:\n          if (isinclass) { ADD_NEW(next_state_offset, 0); }\n          break;\n          }\n        }\n      break;\n\n/* ========================================================================== */\n      /* These are the opcodes for fancy brackets of various kinds. We have\n      to use recursion in order to handle them. The \"always failing\" assertion\n      (?!) is optimised to OP_FAIL when compiling, so we have to support that,\n      though the other \"backtracking verbs\" are not supported. */\n\n      case OP_FAIL:\n      break;\n\n      case OP_ASSERT:\n      case OP_ASSERT_NOT:\n      case OP_ASSERTBACK:\n      case OP_ASSERTBACK_NOT:\n        {\n        int rc;\n        int *local_workspace;\n        PCRE2_SIZE *local_offsets;\n        PCRE2_SPTR endasscode = code + GET(code, 1);\n        RWS_anchor *rws = (RWS_anchor *)RWS;\n\n        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)\n          {\n          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);\n          if (rc != 0) return rc;\n          RWS = (int *)rws;\n          }\n\n        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);\n        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;\n        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);\n\n        rc = internal_dfa_match(\n          mb,                                   /* static match data */\n          code,                                 /* this subexpression's code */\n          ptr,                                  /* where we currently are */\n          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */\n          local_offsets,                        /* offset vector */\n          RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */\n          local_workspace,                      /* workspace vector */\n          RWS_RSIZE,                            /* size of same */\n          rlevel,                               /* function recursion level */\n          RWS);                                 /* recursion workspace */\n\n        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;\n        if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))\n            { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_COND:\n      case OP_SCOND:\n        {\n        int codelink = (int)GET(code, 1);\n        PCRE2_UCHAR condcode;\n\n        /* Because of the way auto-callout works during compile, a callout item\n        is inserted between OP_COND and an assertion condition. This does not\n        happen for the other conditions. */\n\n        if (code[LINK_SIZE + 1] == OP_CALLOUT\n            || code[LINK_SIZE + 1] == OP_CALLOUT_STR)\n          {\n          PCRE2_SIZE callout_length;\n          rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb,\n            1 + LINK_SIZE, &callout_length);\n          if (rrc < 0) return rrc;                 /* Abandon */\n          if (rrc > 0) break;                      /* Fail this thread */\n          code += callout_length;                  /* Skip callout data */\n          }\n\n        condcode = code[LINK_SIZE+1];\n\n        /* Back reference conditions and duplicate named recursion conditions\n        are not supported */\n\n        if (condcode == OP_CREF || condcode == OP_DNCREF ||\n            condcode == OP_DNRREF)\n          return PCRE2_ERROR_DFA_UCOND;\n\n        /* The DEFINE condition is always false, and the assertion (?!) is\n        converted to OP_FAIL. */\n\n        if (condcode == OP_FALSE || condcode == OP_FAIL)\n          { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }\n\n        /* There is also an always-true condition */\n\n        else if (condcode == OP_TRUE)\n          { ADD_ACTIVE(state_offset + LINK_SIZE + 2, 0); }\n\n        /* The only supported version of OP_RREF is for the value RREF_ANY,\n        which means \"test if in any recursion\". We can't test for specifically\n        recursed groups. */\n\n        else if (condcode == OP_RREF)\n          {\n          unsigned int value = GET2(code, LINK_SIZE + 2);\n          if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND;\n          if (mb->recursive != NULL)\n            { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }\n          else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }\n          }\n\n        /* Otherwise, the condition is an assertion */\n\n        else\n          {\n          int rc;\n          int *local_workspace;\n          PCRE2_SIZE *local_offsets;\n          PCRE2_SPTR asscode = code + LINK_SIZE + 1;\n          PCRE2_SPTR endasscode = asscode + GET(asscode, 1);\n          RWS_anchor *rws = (RWS_anchor *)RWS;\n\n          if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)\n            {\n            rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);\n            if (rc != 0) return rc;\n            RWS = (int *)rws;\n            }\n\n          local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);\n          local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;\n          rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;\n\n          while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);\n\n          rc = internal_dfa_match(\n            mb,                                   /* fixed match data */\n            asscode,                              /* this subexpression's code */\n            ptr,                                  /* where we currently are */\n            (PCRE2_SIZE)(ptr - start_subject),    /* start offset */\n            local_offsets,                        /* offset vector */\n            RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */\n            local_workspace,                      /* workspace vector */\n            RWS_RSIZE,                            /* size of same */\n            rlevel,                               /* function recursion level */\n            RWS);                                 /* recursion workspace */\n\n          rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;\n\n          if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;\n          if ((rc >= 0) ==\n                (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))\n            { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }\n          else\n            { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_RECURSE:\n        {\n        int rc;\n        int *local_workspace;\n        PCRE2_SIZE *local_offsets;\n        RWS_anchor *rws = (RWS_anchor *)RWS;\n        PCRE2_SPTR callpat = start_code + GET(code, 1);\n        uint32_t recno = (callpat == mb->start_code)? 0 :\n          GET2(callpat, 1 + LINK_SIZE);\n\n        /* Argument list has not been supported yet. */\n        if (code[1 + LINK_SIZE] == OP_CREF) return PCRE2_ERROR_DFA_UITEM;\n\n        if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE)\n          {\n          rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb);\n          if (rc != 0) return rc;\n          RWS = (int *)rws;\n          }\n\n        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);\n        local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;\n        rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;\n\n        /* Check for repeating a recursion without advancing the subject\n        pointer or last used character. This should catch convoluted mutual\n        recursions. (Some simple cases are caught at compile time.) */\n\n        for (dfa_recursion_info *ri = mb->recursive;\n             ri != NULL;\n             ri = ri->prevrec)\n          {\n          if (recno == ri->group_num && ptr == ri->subject_position &&\n              mb->last_used_ptr == ri->last_used_ptr)\n            return PCRE2_ERROR_RECURSELOOP;\n          }\n\n        /* Remember this recursion and where we started it so as to\n        catch infinite loops. */\n\n        new_recursive.group_num = recno;\n        new_recursive.subject_position = ptr;\n        new_recursive.last_used_ptr = mb->last_used_ptr;\n        new_recursive.prevrec = mb->recursive;\n        mb->recursive = &new_recursive;\n\n        rc = internal_dfa_match(\n          mb,                                   /* fixed match data */\n          callpat,                              /* this subexpression's code */\n          ptr,                                  /* where we currently are */\n          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */\n          local_offsets,                        /* offset vector */\n          RWS_OVEC_RSIZE/OVEC_UNIT,             /* size of same */\n          local_workspace,                      /* workspace vector */\n          RWS_RSIZE,                            /* size of same */\n          rlevel,                               /* function recursion level */\n          RWS);                                 /* recursion workspace */\n\n        rws->free += RWS_RSIZE + RWS_OVEC_RSIZE;\n        mb->recursive = new_recursive.prevrec;  /* Done this recursion */\n\n        /* Ran out of internal offsets */\n\n        if (rc == 0) return PCRE2_ERROR_DFA_RECURSE;\n\n        /* For each successful matched substring, set up the next state with a\n        count of characters to skip before trying it. Note that the count is in\n        characters, not bytes. */\n\n        if (rc > 0)\n          {\n          for (rc = rc*2 - 2; rc >= 0; rc -= 2)\n            {\n            PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc];\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n            if (utf)\n              {\n              PCRE2_SPTR p = start_subject + local_offsets[rc];\n              PCRE2_SPTR pp = start_subject + local_offsets[rc+1];\n              while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;\n              }\n#endif\n            if (charcount > 0)\n              {\n              ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0,\n                (int)(charcount - 1));\n              }\n            else\n              {\n              ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);\n              }\n            }\n          }\n        else if (rc != PCRE2_ERROR_NOMATCH) return rc;\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_BRAPOS:\n      case OP_SBRAPOS:\n      case OP_CBRAPOS:\n      case OP_SCBRAPOS:\n      case OP_BRAPOSZERO:\n        {\n        int rc;\n        int *local_workspace;\n        PCRE2_SIZE *local_offsets;\n        PCRE2_SIZE charcount, matched_count;\n        PCRE2_SPTR local_ptr = ptr;\n        RWS_anchor *rws = (RWS_anchor *)RWS;\n        BOOL allow_zero;\n\n        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)\n          {\n          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);\n          if (rc != 0) return rc;\n          RWS = (int *)rws;\n          }\n\n        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);\n        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;\n        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        if (codevalue == OP_BRAPOSZERO)\n          {\n          allow_zero = TRUE;\n          ++code;  /* The following opcode will be one of the above BRAs */\n          }\n        else allow_zero = FALSE;\n\n        /* Loop to match the subpattern as many times as possible as if it were\n        a complete pattern. */\n\n        for (matched_count = 0;; matched_count++)\n          {\n          rc = internal_dfa_match(\n            mb,                                   /* fixed match data */\n            code,                                 /* this subexpression's code */\n            local_ptr,                            /* where we currently are */\n            (PCRE2_SIZE)(ptr - start_subject),    /* start offset */\n            local_offsets,                        /* offset vector */\n            RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */\n            local_workspace,                      /* workspace vector */\n            RWS_RSIZE,                            /* size of same */\n            rlevel,                               /* function recursion level */\n            RWS);                                 /* recursion workspace */\n\n          /* Failed to match */\n\n          if (rc < 0)\n            {\n            if (rc != PCRE2_ERROR_NOMATCH) return rc;\n            break;\n            }\n\n          /* Matched: break the loop if zero characters matched. */\n\n          charcount = local_offsets[1] - local_offsets[0];\n          if (charcount == 0) break;\n          local_ptr += charcount;    /* Advance temporary position ptr */\n          }\n\n        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        /* At this point we have matched the subpattern matched_count\n        times, and local_ptr is pointing to the character after the end of the\n        last match. */\n\n        if (matched_count > 0 || allow_zero)\n          {\n          PCRE2_SPTR end_subpattern = code;\n          int next_state_offset;\n\n          do { end_subpattern += GET(end_subpattern, 1); }\n            while (*end_subpattern == OP_ALT);\n          next_state_offset =\n            (int)(end_subpattern - start_code + LINK_SIZE + 1);\n\n          /* Optimization: if there are no more active states, and there\n          are no new states yet set up, then skip over the subject string\n          right here, to save looping. Otherwise, set up the new state to swing\n          into action when the end of the matched substring is reached. */\n\n          if (i + 1 >= active_count && new_count == 0)\n            {\n            ptr = local_ptr;\n            clen = 0;\n            ADD_NEW(next_state_offset, 0);\n            }\n          else\n            {\n            PCRE2_SPTR p = ptr;\n            PCRE2_SPTR pp = local_ptr;\n            charcount = (PCRE2_SIZE)(pp - p);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n            if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;\n#endif\n            ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));\n            }\n          }\n        }\n      break;\n\n      /*-----------------------------------------------------------------*/\n      case OP_ONCE:\n        {\n        int rc;\n        int *local_workspace;\n        PCRE2_SIZE *local_offsets;\n        RWS_anchor *rws = (RWS_anchor *)RWS;\n\n        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)\n          {\n          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);\n          if (rc != 0) return rc;\n          RWS = (int *)rws;\n          }\n\n        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);\n        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;\n        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        rc = internal_dfa_match(\n          mb,                                   /* fixed match data */\n          code,                                 /* this subexpression's code */\n          ptr,                                  /* where we currently are */\n          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */\n          local_offsets,                        /* offset vector */\n          RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */\n          local_workspace,                      /* workspace vector */\n          RWS_RSIZE,                            /* size of same */\n          rlevel,                               /* function recursion level */\n          RWS);                                 /* recursion workspace */\n\n        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;\n\n        if (rc >= 0)\n          {\n          PCRE2_SPTR end_subpattern = code;\n          PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0];\n          int next_state_offset, repeat_state_offset;\n\n          do { end_subpattern += GET(end_subpattern, 1); }\n            while (*end_subpattern == OP_ALT);\n          next_state_offset =\n            (int)(end_subpattern - start_code + LINK_SIZE + 1);\n\n          /* If the end of this subpattern is KETRMAX or KETRMIN, we must\n          arrange for the repeat state also to be added to the relevant list.\n          Calculate the offset, or set -1 for no repeat. */\n\n          repeat_state_offset = (*end_subpattern == OP_KETRMAX ||\n                                 *end_subpattern == OP_KETRMIN)?\n            (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;\n\n          /* If we have matched an empty string, add the next state at the\n          current character pointer. This is important so that the duplicate\n          checking kicks in, which is what breaks infinite loops that match an\n          empty string. */\n\n          if (charcount == 0)\n            {\n            ADD_ACTIVE(next_state_offset, 0);\n            }\n\n          /* Optimization: if there are no more active states, and there\n          are no new states yet set up, then skip over the subject string\n          right here, to save looping. Otherwise, set up the new state to swing\n          into action when the end of the matched substring is reached. */\n\n          else if (i + 1 >= active_count && new_count == 0)\n            {\n            ptr += charcount;\n            clen = 0;\n            ADD_NEW(next_state_offset, 0);\n\n            /* If we are adding a repeat state at the new character position,\n            we must fudge things so that it is the only current state.\n            Otherwise, it might be a duplicate of one we processed before, and\n            that would cause it to be skipped. */\n\n            if (repeat_state_offset >= 0)\n              {\n              next_active_state = active_states;\n              active_count = 0;\n              i = -1;\n              ADD_ACTIVE(repeat_state_offset, 0);\n              }\n            }\n          else\n            {\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n            if (utf)\n              {\n              PCRE2_SPTR p = start_subject + local_offsets[0];\n              PCRE2_SPTR pp = start_subject + local_offsets[1];\n              while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;\n              }\n#endif\n            ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));\n            if (repeat_state_offset >= 0)\n              { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); }\n            }\n          }\n        else if (rc != PCRE2_ERROR_NOMATCH) return rc;\n        }\n      break;\n\n\n/* ========================================================================== */\n      /* Handle callouts */\n\n      case OP_CALLOUT:\n      case OP_CALLOUT_STR:\n        {\n        PCRE2_SIZE callout_length;\n        rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb, 0,\n          &callout_length);\n        if (rrc < 0) return rrc;   /* Abandon */\n        if (rrc == 0)\n          { ADD_ACTIVE(state_offset + (int)callout_length, 0); }\n        }\n      break;\n\n\n/* ========================================================================== */\n      default:        /* Unsupported opcode */\n      return PCRE2_ERROR_DFA_UITEM;\n      }\n\n    NEXT_ACTIVE_STATE: continue;\n\n    }      /* End of loop scanning active states */\n\n  /* We have finished the processing at the current subject character. If no\n  new states have been set for the next character, we have found all the\n  matches that we are going to find. If partial matching has been requested,\n  check for appropriate conditions.\n\n  The \"could_continue\" variable is true if a state could have continued but\n  for the fact that the end of the subject was reached. */\n\n  if (new_count <= 0)\n    {\n    if (could_continue &&                            /* Some could go on, and */\n        (                                            /* either... */\n        (mb->moptions & PCRE2_PARTIAL_HARD) != 0      /* Hard partial */\n        ||                                           /* or... */\n        ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 &&  /* Soft partial and */\n         match_count < 0)                             /* no matches */\n        ) &&                                         /* And... */\n        (\n        partial_newline ||                   /* Either partial NL */\n          (                                  /* or ... */\n          ptr >= end_subject &&              /* End of subject and */\n            (                                  /* either */\n            ptr > mb->start_used_ptr ||        /* Inspected non-empty string */\n            mb->allowemptypartial              /* or pattern has lookbehind */\n            )                                  /* or could match empty */\n          )\n        ))\n      match_count = PCRE2_ERROR_PARTIAL;\n    break;  /* Exit from loop along the subject string */\n    }\n\n  /* One or more states are active for the next character. */\n\n  ptr += clen;    /* Advance to next subject character */\n  }               /* Loop to move along the subject string */\n\n/* Control gets here from \"break\" a few lines above. If we have a match and\nPCRE2_ENDANCHORED is set, the match fails. */\n\nif (match_count >= 0 &&\n    ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0 &&\n    ptr < end_subject)\n  match_count = PCRE2_ERROR_NOMATCH;\n\nreturn match_count;\n}\n\n\n\n/*************************************************\n*     Match a pattern using the DFA algorithm    *\n*************************************************/\n\n/* This function matches a compiled pattern to a subject string, using the\nalternate matching algorithm that finds all matches at once.\n\nArguments:\n  code          points to the compiled pattern\n  subject       subject string\n  length        length of subject string\n  startoffset   where to start matching in the subject\n  options       option bits\n  match_data    points to a match data structure\n  gcontext      points to a match context\n  workspace     pointer to workspace\n  wscount       size of workspace\n\nReturns:        > 0 => number of match offset pairs placed in offsets\n                = 0 => offsets overflowed; longest matches are present\n                 -1 => failed to match\n               < -1 => some kind of unexpected problem\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,\n  PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,\n  pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)\n{\nint rc;\n\nconst pcre2_real_code *re = (const pcre2_real_code *)code;\nuint32_t original_options = options;\n\nPCRE2_UCHAR null_str[1] = { 0xcd };\nPCRE2_SPTR original_subject = subject;\nPCRE2_SPTR start_match;\nPCRE2_SPTR end_subject;\nPCRE2_SPTR bumpalong_limit;\nPCRE2_SPTR req_cu_ptr;\n\nBOOL utf, anchored, startline, firstline;\nBOOL has_first_cu = FALSE;\nBOOL has_req_cu = FALSE;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nPCRE2_SPTR memchr_found_first_cu = NULL;\nPCRE2_SPTR memchr_found_first_cu2 = NULL;\n#endif\n\nPCRE2_UCHAR first_cu = 0;\nPCRE2_UCHAR first_cu2 = 0;\nPCRE2_UCHAR req_cu = 0;\nPCRE2_UCHAR req_cu2 = 0;\n\nconst uint8_t *start_bits = NULL;\n\n/* We need to have mb pointing to a match block, because the IS_NEWLINE macro\nis used below, and it expects NLBLOCK to be defined as a pointer. */\n\npcre2_callout_block cb;\ndfa_match_block actual_match_block;\ndfa_match_block *mb = &actual_match_block;\n\n/* Set up a starting block of memory for use during recursive calls to\ninternal_dfa_match(). By putting this on the stack, it minimizes resource use\nin the case when it is not needed. If this is too small, more memory is\nobtained from the heap. At the start of each block is an anchor structure.*/\n\nint base_recursion_workspace[RWS_BASE_SIZE];\nRWS_anchor *rws = (RWS_anchor *)base_recursion_workspace;\nrws->next = NULL;\nrws->size = RWS_BASE_SIZE;\nrws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;\n\n/* Recognize NULL, length 0 as an empty string. */\n\nif (subject == NULL && length == 0) subject = null_str;\n\n/* Plausibility checks */\n\nif (match_data == NULL) return PCRE2_ERROR_NULL;\nif (re == NULL || subject == NULL || workspace == NULL)\n  { rc = PCRE2_ERROR_NULL; goto EXIT; }\nif ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0)\n  { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }\n\nif (length == PCRE2_ZERO_TERMINATED)\n  {\n  length = PRIV(strlen)(subject);\n  }\n\nif (wscount < 20) { rc = PCRE2_ERROR_DFA_WSSIZE; goto EXIT; }\nif (start_offset > length) { rc = PCRE2_ERROR_BADOFFSET; goto EXIT; }\n\n/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same\ntime. */\n\nif ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&\n   ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)\n  { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }\n\n/* Invalid UTF support is not available for DFA matching. */\n\nif ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)\n  { rc = PCRE2_ERROR_DFA_UINVALID_UTF; goto EXIT; }\n\n/* Check that the first field in the block is the magic number. If it is not,\nreturn with PCRE2_ERROR_BADMAGIC. */\n\nif (re->magic_number != MAGIC_NUMBER)\n  { rc = PCRE2_ERROR_BADMAGIC; goto EXIT; }\n\n/* Check the code unit width. */\n\nif ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)\n  { rc = PCRE2_ERROR_BADMODE; goto EXIT; }\n\n/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the\noptions variable for this function. Users of PCRE2 who are not calling the\nfunction directly would like to have a way of setting these flags, in the same\nway that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with\nconstructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and\n(*NOTEMPTY_ATSTART) set bits in the pattern's \"flag\" function which can now be\ntransferred to the options for this function. The bits are guaranteed to be\nadjacent, but do not have the same values. This bit of Boolean trickery assumes\nthat the match-time bits are not more significant than the flag bits. If by\naccident this is not the case, a compile-time division by zero error will\noccur. */\n\n#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)\n#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)\noptions |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));\n#undef FF\n#undef OO\n\n/* If restarting after a partial match, do some sanity checks on the contents\nof the workspace. */\n\nif ((options & PCRE2_DFA_RESTART) != 0)\n  {\n  if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||\n      workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))\n    { rc = PCRE2_ERROR_DFA_BADRESTART; goto EXIT; }\n  }\n\n/* Set some local values */\n\nutf = (re->overall_options & PCRE2_UTF) != 0;\nstart_match = subject + start_offset;\nend_subject = subject + length;\nreq_cu_ptr = start_match - 1;\nanchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||\n  (re->overall_options & PCRE2_ANCHORED) != 0;\n\n/* The \"must be at the start of a line\" flags are used in a loop when finding\nwhere to start. */\n\nstartline = (re->flags & PCRE2_STARTLINE) != 0;\nfirstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;\nbumpalong_limit = end_subject;\n\n/* Initialize and set up the fixed fields in the callout block, with a pointer\nin the match block. */\n\nmb->cb = &cb;\ncb.version = 2;\ncb.subject = subject;\ncb.subject_length = (PCRE2_SIZE)(end_subject - subject);\ncb.callout_flags = 0;\ncb.capture_top      = 1;      /* No capture support */\ncb.capture_last     = 0;\ncb.mark             = NULL;   /* No (*MARK) support */\n\n/* Get data from the match context, if present, and fill in the remaining\nfields in the match block. It is an error to set an offset limit without\nsetting the flag at compile time. */\n\nif (mcontext == NULL)\n  {\n  mb->callout = NULL;\n  mb->memctl = re->memctl;\n  mb->match_limit = PRIV(default_match_context).match_limit;\n  mb->match_limit_depth = PRIV(default_match_context).depth_limit;\n  mb->heap_limit = PRIV(default_match_context).heap_limit;\n  }\nelse\n  {\n  if (mcontext->offset_limit != PCRE2_UNSET)\n    {\n    if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)\n      { rc = PCRE2_ERROR_BADOFFSETLIMIT; goto EXIT; }\n    bumpalong_limit = subject + mcontext->offset_limit;\n    }\n  mb->callout = mcontext->callout;\n  mb->callout_data = mcontext->callout_data;\n  mb->memctl = mcontext->memctl;\n  mb->match_limit = mcontext->match_limit;\n  mb->match_limit_depth = mcontext->depth_limit;\n  mb->heap_limit = mcontext->heap_limit;\n  }\n\nif (mb->match_limit > re->limit_match)\n  mb->match_limit = re->limit_match;\n\nif (mb->match_limit_depth > re->limit_depth)\n  mb->match_limit_depth = re->limit_depth;\n\nif (mb->heap_limit > re->limit_heap)\n  mb->heap_limit = re->limit_heap;\n\nmb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start);\nmb->tables = re->tables;\nmb->start_subject = subject;\nmb->end_subject = end_subject;\nmb->start_offset = start_offset;\nmb->allowemptypartial = (re->max_lookbehind > 0) ||\n  (re->flags & PCRE2_MATCH_EMPTY) != 0;\nmb->moptions = options;\nmb->poptions = re->overall_options;\nmb->match_call_count = 0;\nmb->heap_used = 0;\n\n/* Process the \\R and newline settings. */\n\nmb->bsr_convention = re->bsr_convention;\nmb->nltype = NLTYPE_FIXED;\nswitch(re->newline_convention)\n  {\n  case PCRE2_NEWLINE_CR:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_CR;\n  break;\n\n  case PCRE2_NEWLINE_LF:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_NUL:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_NUL;\n  break;\n\n  case PCRE2_NEWLINE_CRLF:\n  mb->nllen = 2;\n  mb->nl[0] = CHAR_CR;\n  mb->nl[1] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_ANY:\n  mb->nltype = NLTYPE_ANY;\n  break;\n\n  case PCRE2_NEWLINE_ANYCRLF:\n  mb->nltype = NLTYPE_ANYCRLF;\n  break;\n\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  rc = PCRE2_ERROR_INTERNAL;\n  goto EXIT;\n  /* LCOV_EXCL_STOP */\n  }\n\n/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,\nwe must also check that a starting offset does not point into the middle of a\nmultiunit character. We check only the portion of the subject that is going to\nbe inspected during matching - from the offset minus the maximum back reference\nto the given length. This saves time when a small part of a large subject is\nbeing matched by the use of a starting offset. Note that the maximum lookbehind\nis a number of characters, not code units. */\n\n#ifdef SUPPORT_UNICODE\nif (utf && (options & PCRE2_NO_UTF_CHECK) == 0)\n  {\n  PCRE2_SPTR check_subject = start_match;  /* start_match includes offset */\n\n  if (start_offset > 0)\n    {\n#if PCRE2_CODE_UNIT_WIDTH != 32\n    unsigned int i;\n    if (start_match < end_subject && NOT_FIRSTCU(*start_match))\n      { rc = PCRE2_ERROR_BADUTFOFFSET; goto EXIT; }\n    for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)\n      {\n      check_subject--;\n      while (check_subject > subject &&\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      (*check_subject & 0xc0) == 0x80)\n#else  /* 16-bit */\n      (*check_subject & 0xfc00) == 0xdc00)\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n        check_subject--;\n      }\n#else   /* In the 32-bit library, one code unit equals one character. */\n    check_subject -= re->max_lookbehind;\n    if (check_subject < subject) check_subject = subject;\n#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */\n    }\n\n  /* Validate the relevant portion of the subject. After an error, adjust the\n  offset to be an absolute offset in the whole string. */\n\n  rc = PRIV(valid_utf)(check_subject,\n    length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));\n  if (rc != 0)\n    {\n    match_data->startchar += (PCRE2_SIZE)(check_subject - subject);\n    goto EXIT;\n    }\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* Set up the first code unit to match, if available. If there's no first code\nunit there may be a bitmap of possible first characters. */\n\nif ((re->flags & PCRE2_FIRSTSET) != 0)\n  {\n  has_first_cu = TRUE;\n  first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);\n  if ((re->flags & PCRE2_FIRSTCASELESS) != 0)\n    {\n    first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)\n      first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);\n#else\n    if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))\n      first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);\n#endif\n#endif  /* SUPPORT_UNICODE */\n    }\n  }\nelse\n  if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)\n    start_bits = re->start_bitmap;\n\n/* There may be a \"last known required code unit\" set. */\n\nif ((re->flags & PCRE2_LASTSET) != 0)\n  {\n  has_req_cu = TRUE;\n  req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);\n  if ((re->flags & PCRE2_LASTCASELESS) != 0)\n    {\n    req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)\n      req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);\n#else\n    if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))\n      req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);\n#endif\n#endif  /* SUPPORT_UNICODE */\n    }\n  }\n\n/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,\nfree the memory that was obtained. */\n\nif ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)\n  {\n  match_data->memctl.free((void *)match_data->subject,\n    match_data->memctl.memory_data);\n  match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;\n  }\n\n/* Fill in fields that are always returned in the match data. */\n\nmatch_data->code = re;\nmatch_data->subject = NULL;  /* Default for match error */\nmatch_data->mark = NULL;\nmatch_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;\nmatch_data->options = original_options;\n\n/* Call the main matching function, looping for a non-anchored regex after a\nfailed match. If not restarting, perform certain optimizations at the start of\na match. */\n\nfor (;;)\n  {\n  /* ----------------- Start of match optimizations ---------------- */\n\n  /* There are some optimizations that avoid running the match if a known\n  starting point is not found, or if a known later code unit is not present.\n  However, there is an option (settable at compile time) that disables\n  these, for testing and for ensuring that all callouts do actually occur.\n  The optimizations must also be avoided when restarting a DFA match. */\n\n  if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 &&\n      (options & PCRE2_DFA_RESTART) == 0)\n    {\n    /* If firstline is TRUE, the start of the match is constrained to the first\n    line of a multiline string. That is, the match must be before or at the\n    first newline following the start of matching. Temporarily adjust\n    end_subject so that we stop the optimization scans for a first code unit\n    immediately after the first character of a newline (the first code unit can\n    legitimately be a newline). If the match fails at the newline, later code\n    breaks this loop. */\n\n    if (firstline)\n      {\n      PCRE2_SPTR t = start_match;\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        while (t < end_subject && !IS_NEWLINE(t))\n          {\n          t++;\n          ACROSSCHAR(t < end_subject, t, t++);\n          }\n        }\n      else\n#endif\n      while (t < end_subject && !IS_NEWLINE(t)) t++;\n      end_subject = t;\n      }\n\n    /* Anchored: check the first code unit if one is recorded. This may seem\n    pointless but it can help in detecting a no match case without scanning for\n    the required code unit. */\n\n    if (anchored)\n      {\n      if (has_first_cu || start_bits != NULL)\n        {\n        BOOL ok = start_match < end_subject;\n        if (ok)\n          {\n          PCRE2_UCHAR c = UCHAR21TEST(start_match);\n          ok = has_first_cu && (c == first_cu || c == first_cu2);\n          if (!ok && start_bits != NULL)\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            if (c > 255) c = 255;\n#endif\n            ok = (start_bits[c/8] & (1u << (c&7))) != 0;\n            }\n          }\n        if (!ok) break;\n        }\n      }\n\n    /* Not anchored. Advance to a unique first code unit if there is one. */\n\n    else\n      {\n      if (has_first_cu)\n        {\n        if (first_cu != first_cu2)  /* Caseless */\n          {\n          /* In 16-bit and 32_bit modes we have to do our own search, so can\n          look for both cases at once. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          PCRE2_UCHAR smc;\n          while (start_match < end_subject &&\n                (smc = UCHAR21TEST(start_match)) != first_cu &&\n                 smc != first_cu2)\n            start_match++;\n#else\n          /* In 8-bit mode, the use of memchr() gives a big speed up, even\n          though we have to call it twice in order to find the earliest\n          occurrence of the code unit in either of its cases. Caching is used\n          to remember the positions of previously found code units. This can\n          make a huge difference when the strings are very long and only one\n          case is actually present. */\n\n          PCRE2_SPTR pp1 = NULL;\n          PCRE2_SPTR pp2 = NULL;\n          PCRE2_SIZE searchlength = end_subject - start_match;\n\n          /* If we haven't got a previously found position for first_cu, or if\n          the current starting position is later, we need to do a search. If\n          the code unit is not found, set it to the end. */\n\n          if (memchr_found_first_cu == NULL ||\n              start_match > memchr_found_first_cu)\n            {\n            pp1 = memchr(start_match, first_cu, searchlength);\n            memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;\n            }\n\n          /* If the start is before a previously found position, use the\n          previous position, or NULL if a previous search failed. */\n\n          else pp1 = (memchr_found_first_cu == end_subject)? NULL :\n            memchr_found_first_cu;\n\n          /* Do the same thing for the other case. */\n\n          if (memchr_found_first_cu2 == NULL ||\n              start_match > memchr_found_first_cu2)\n            {\n            pp2 = memchr(start_match, first_cu2, searchlength);\n            memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;\n            }\n\n          else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :\n            memchr_found_first_cu2;\n\n          /* Set the start to the end of the subject if neither case was found.\n          Otherwise, use the earlier found point. */\n\n          if (pp1 == NULL)\n            start_match = (pp2 == NULL)? end_subject : pp2;\n          else\n            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;\n\n#endif  /* 8-bit handling */\n          }\n\n        /* The caseful case is much simpler. */\n\n        else\n          {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          while (start_match < end_subject && UCHAR21TEST(start_match) !=\n                 first_cu)\n            start_match++;\n#else  /* 8-bit code units */\n          start_match = memchr(start_match, first_cu, end_subject - start_match);\n          if (start_match == NULL) start_match = end_subject;\n#endif\n          }\n\n        /* If we can't find the required code unit, having reached the true end\n        of the subject, break the bumpalong loop, to force a match failure,\n        except when doing partial matching, when we let the next cycle run at\n        the end of the subject. To see why, consider the pattern /(?<=abc)def/,\n        which partially matches \"abc\", even though the string does not contain\n        the starting character \"d\". If we have not reached the true end of the\n        subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)\n        we also let the cycle run, because the matching string is legitimately\n        allowed to start with the first code unit of a newline. */\n\n        if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&\n            start_match >= mb->end_subject)\n          break;\n        }\n\n      /* If there's no first code unit, advance to just after a linebreak for a\n      multiline match if required. */\n\n      else if (startline)\n        {\n        if (start_match > mb->start_subject + start_offset)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf)\n            {\n            while (start_match < end_subject && !WAS_NEWLINE(start_match))\n              {\n              start_match++;\n              ACROSSCHAR(start_match < end_subject, start_match, start_match++);\n              }\n            }\n          else\n#endif\n          while (start_match < end_subject && !WAS_NEWLINE(start_match))\n            start_match++;\n\n          /* If we have just passed a CR and the newline option is ANY or\n          ANYCRLF, and we are now at a LF, advance the match position by one\n          more code unit. */\n\n          if (start_match[-1] == CHAR_CR &&\n               (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&\n               start_match < end_subject &&\n               UCHAR21TEST(start_match) == CHAR_NL)\n            start_match++;\n          }\n        }\n\n      /* If there's no first code unit or a requirement for a multiline line\n      start, advance to a non-unique first code unit if any have been\n      identified. The bitmap contains only 256 bits. When code units are 16 or\n      32 bits wide, all code units greater than 254 set the 255 bit. */\n\n      else if (start_bits != NULL)\n        {\n        while (start_match < end_subject)\n          {\n          uint32_t c = UCHAR21TEST(start_match);\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          if (c > 255) c = 255;\n#endif\n          if ((start_bits[c/8] & (1u << (c&7))) != 0) break;\n          start_match++;\n          }\n\n        /* See comment above in first_cu checking about the next line. */\n\n        if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&\n            start_match >= mb->end_subject)\n          break;\n        }\n      }  /* End of first code unit handling */\n\n    /* Restore fudged end_subject */\n\n    end_subject = mb->end_subject;\n\n    /* The following two optimizations are disabled for partial matching. */\n\n    if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)\n      {\n      PCRE2_SPTR p;\n\n      /* The minimum matching length is a lower bound; no actual string of that\n      length may actually match the pattern. Although the value is, strictly,\n      in characters, we treat it as code units to avoid spending too much time\n      in this optimization. */\n\n      if (end_subject - start_match < re->minlength) goto NOMATCH_EXIT;\n\n      /* If req_cu is set, we know that that code unit must appear in the\n      subject for the match to succeed. If the first code unit is set, req_cu\n      must be later in the subject; otherwise the test starts at the match\n      point. This optimization can save a huge amount of backtracking in\n      patterns with nested unlimited repeats that aren't going to match.\n      Writing separate code for cased/caseless versions makes it go faster, as\n      does using an autoincrement and backing off on a match. As in the case of\n      the first code unit, using memchr() in the 8-bit library gives a big\n      speed up. Unlike the first_cu check above, we do not need to call\n      memchr() twice in the caseless case because we only need to check for the\n      presence of the character in either case, not find the first occurrence.\n\n      The search can be skipped if the code unit was found later than the\n      current starting point in a previous iteration of the bumpalong loop.\n\n      HOWEVER: when the subject string is very, very long, searching to its end\n      can take a long time, and give bad performance on quite ordinary\n      patterns. This showed up when somebody was matching something like\n      /^\\d+C/ on a 32-megabyte string... so we don't do this when the string is\n      sufficiently long, but it's worth searching a lot more for unanchored\n      patterns. */\n\n      p = start_match + (has_first_cu? 1:0);\n      if (has_req_cu && p > req_cu_ptr)\n        {\n        PCRE2_SIZE check_length = end_subject - start_match;\n\n        if (check_length < REQ_CU_MAX ||\n              (!anchored && check_length < REQ_CU_MAX * 1000))\n          {\n          if (req_cu != req_cu2)  /* Caseless */\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            while (p < end_subject)\n              {\n              uint32_t pp = UCHAR21INCTEST(p);\n              if (pp == req_cu || pp == req_cu2) { p--; break; }\n              }\n#else  /* 8-bit code units */\n            PCRE2_SPTR pp = p;\n            p = memchr(pp, req_cu, end_subject - pp);\n            if (p == NULL)\n              {\n              p = memchr(pp, req_cu2, end_subject - pp);\n              if (p == NULL) p = end_subject;\n              }\n#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */\n            }\n\n          /* The caseful case */\n\n          else\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            while (p < end_subject)\n              {\n              if (UCHAR21INCTEST(p) == req_cu) { p--; break; }\n              }\n\n#else  /* 8-bit code units */\n            p = memchr(p, req_cu, end_subject - p);\n            if (p == NULL) p = end_subject;\n#endif\n            }\n\n          /* If we can't find the required code unit, break the matching loop,\n          forcing a match failure. */\n\n          if (p >= end_subject) break;\n\n          /* If we have found the required code unit, save the point where we\n          found it, so that we don't search again next time round the loop if\n          the start hasn't passed this code unit yet. */\n\n          req_cu_ptr = p;\n          }\n        }\n      }\n    }\n\n  /* ------------ End of start of match optimizations ------------ */\n\n  /* Give no match if we have passed the bumpalong limit. */\n\n  if (start_match > bumpalong_limit) break;\n\n  /* OK, now we can do the business */\n\n  mb->start_used_ptr = start_match;\n  mb->last_used_ptr = start_match;\n  mb->recursive = NULL;\n\n  rc = internal_dfa_match(\n    mb,                           /* fixed match data */\n    mb->start_code,               /* this subexpression's code */\n    start_match,                  /* where we currently are */\n    start_offset,                 /* start offset in subject */\n    match_data->ovector,          /* offset vector */\n    (uint32_t)match_data->oveccount * 2,  /* actual size of same */\n    workspace,                    /* workspace vector */\n    (int)wscount,                 /* size of same */\n    0,                            /* function recurse level */\n    base_recursion_workspace);    /* initial workspace for recursion */\n\n  /* Anything other than \"no match\" means we are done, always; otherwise, carry\n  on only if not anchored. */\n\n  if (rc != PCRE2_ERROR_NOMATCH || anchored)\n    {\n    if (rc == PCRE2_ERROR_NOMATCH) goto NOMATCH_EXIT;\n\n    if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)\n      {\n      match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);\n      match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);\n      }\n\n    if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)\n      {\n      match_data->subject_length = length;\n      match_data->start_offset = start_offset;\n      match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);\n      match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);\n      match_data->startchar = (PCRE2_SIZE)(start_match - subject);\n      }\n\n    if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)\n      {\n      if (length != 0)\n        {\n        match_data->subject = match_data->memctl.malloc(CU2BYTES(length),\n          match_data->memctl.memory_data);\n        if (match_data->subject == NULL)\n          { rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }\n        memcpy((void *)match_data->subject, subject, CU2BYTES(length));\n        }\n      else\n        match_data->subject = NULL;\n      match_data->flags |= PCRE2_MD_COPIED_SUBJECT;\n      }\n    else if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)\n      {\n      match_data->subject = original_subject;\n      }\n    goto EXIT;\n    }\n\n  /* Advance to the next subject character unless we are at the end of a line\n  and firstline is set. */\n\n  if (firstline && IS_NEWLINE(start_match)) break;\n  start_match++;\n#ifdef SUPPORT_UNICODE\n  if (utf)\n    {\n    ACROSSCHAR(start_match < end_subject, start_match, start_match++);\n    }\n#endif\n  if (start_match > end_subject) break;\n\n  /* If we have just passed a CR and we are now at a LF, and the pattern does\n  not contain any explicit matches for \\r or \\n, and the newline option is CRLF\n  or ANY or ANYCRLF, advance the match position by one more character. */\n\n  if (UCHAR21TEST(start_match - 1) == CHAR_CR &&\n      start_match < end_subject &&\n      UCHAR21TEST(start_match) == CHAR_NL &&\n      (re->flags & PCRE2_HASCRORLF) == 0 &&\n        (mb->nltype == NLTYPE_ANY ||\n         mb->nltype == NLTYPE_ANYCRLF ||\n         mb->nllen == 2))\n    start_match++;\n\n  }   /* \"Bumpalong\" loop */\n\nNOMATCH_EXIT:\nmatch_data->subject = original_subject;\nmatch_data->subject_length = length;\nmatch_data->start_offset = start_offset;\nrc = PCRE2_ERROR_NOMATCH;\n\nEXIT:\nwhile (rws->next != NULL)\n  {\n  RWS_anchor *next = rws->next;\n  rws->next = next->next;\n  mb->memctl.free(next, mb->memctl.memory_data);\n  }\n\nmatch_data->rc = rc;\nreturn rc;\n}\n\n/* These #undefs are here to enable unity builds with CMake. */\n\n#undef NLBLOCK /* Block containing newline information */\n#undef PSSTART /* Field containing processed string start */\n#undef PSEND   /* Field containing processed string end */\n\n/* End of pcre2_dfa_match.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_error.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n#define STRING(a)  # a\n#define XSTRING(s) STRING(s)\n\n/* The texts of compile-time error messages. Compile-time error numbers start\nat COMPILE_ERROR_BASE (100).\n\nThis used to be a table of strings, but in order to reduce the number of\nrelocations needed when a shared library is loaded dynamically, it is now one\nlong string. We cannot use a table of offsets, because the lengths of inserts\nsuch as XSTRING(MAX_NAME_SIZE) are not known. Instead,\npcre2_get_error_message() counts through to the one it wants - this isn't a\nperformance issue because these strings are used only when there is an error.\n\nEach substring ends with \\0 to insert a null character. This includes the final\nsubstring, so that the whole string ends with \\0\\0, which can be detected when\ncounting through. */\n\nstatic const unsigned char compile_error_texts[] =\n  \"no error\\0\"\n  \"\\\\ at end of pattern\\0\"\n  \"\\\\c at end of pattern\\0\"\n  \"unrecognized character follows \\\\\\0\"\n  \"numbers out of order in {} quantifier\\0\"\n  /* 5 */\n  \"number too big in {} quantifier\\0\"\n  \"missing terminating ] for character class\\0\"\n  \"escape sequence is invalid in character class\\0\"\n  \"range out of order in character class\\0\"\n  \"quantifier does not follow a repeatable item\\0\"\n  /* 10 */\n  \"internal error: unexpected repeat\\0\"\n  \"unrecognized character after (? or (?-\\0\"\n  \"POSIX named classes are supported only within a class\\0\"\n  \"POSIX collating elements are not supported\\0\"\n  \"missing closing parenthesis\\0\"\n  /* 15 */\n  \"reference to non-existent subpattern\\0\"\n  \"pattern passed as NULL with non-zero length\\0\"\n  \"unrecognised compile-time option bit(s)\\0\"\n  \"missing ) after (?# comment\\0\"\n  \"parentheses are too deeply nested\\0\"\n  /* 20 */\n  \"regular expression is too large\\0\"\n  \"failed to allocate heap memory\\0\"\n  \"unmatched closing parenthesis\\0\"\n  \"internal error: code overflow\\0\"\n  \"missing closing parenthesis for condition\\0\"\n  /* 25 */\n  \"length of lookbehind assertion is not limited\\0\"\n  \"a relative value of zero is not allowed\\0\"\n  \"conditional subpattern contains more than two branches\\0\"\n  \"atomic assertion expected after (?( or (?(?C)\\0\"\n  \"digit expected after (?+\\0\"\n  /* 30 */\n  \"unknown POSIX class name\\0\"\n  \"internal error in pcre2_study(): should not occur\\0\"\n  \"this version of PCRE2 does not have Unicode support\\0\"\n  \"parentheses are too deeply nested (stack check)\\0\"\n  \"character code point value in \\\\x{} or \\\\o{} is too large\\0\"\n  /* 35 */\n  \"lookbehind is too complicated\\0\"\n  \"\\\\C is not allowed in a lookbehind assertion in UTF-\" XSTRING(PCRE2_CODE_UNIT_WIDTH) \" mode\\0\"\n  \"PCRE2 does not support \\\\F, \\\\L, \\\\l, \\\\N{name}, \\\\U, or \\\\u\\0\"\n  \"number after (?C is greater than 255\\0\"\n  \"closing parenthesis for (?C expected\\0\"\n  /* 40 */\n  \"invalid escape sequence in (*VERB) name\\0\"\n  \"unrecognized character after (?P\\0\"\n  \"syntax error in subpattern name (missing terminator?)\\0\"\n  \"two named subpatterns have the same name (PCRE2_DUPNAMES not set)\\0\"\n  \"subpattern name must start with a non-digit\\0\"\n  /* 45 */\n  \"this version of PCRE2 does not have support for \\\\P, \\\\p, or \\\\X\\0\"\n  \"malformed \\\\P or \\\\p sequence\\0\"\n  \"unknown property after \\\\P or \\\\p\\0\"\n  \"subpattern name is too long (maximum \" XSTRING(MAX_NAME_SIZE) \" code units)\\0\"\n  \"too many named subpatterns (maximum \" XSTRING(MAX_NAME_COUNT) \")\\0\"\n  /* 50 */\n  \"invalid range in character class\\0\"\n  \"octal value is greater than \\\\377 in 8-bit non-UTF-8 mode\\0\"\n  \"internal error: overran compiling workspace\\0\"\n  \"internal error: previously-checked referenced subpattern not found\\0\"\n  \"DEFINE subpattern contains more than one branch\\0\"\n  /* 55 */\n  \"missing opening brace after \\\\o\\0\"\n  \"internal error: unknown newline setting\\0\"\n  \"\\\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\\0\"\n  \"(?R (recursive pattern call) must be followed by a closing parenthesis\\0\"\n  /* \"an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\\0\" */\n  \"obsolete error (should not occur)\\0\"  /* Was the above */\n  /* 60 */\n  \"(*VERB) not recognized or malformed\\0\"\n  \"subpattern number is too big\\0\"\n  \"subpattern name expected\\0\"\n  \"internal error: parsed pattern overflow\\0\"\n  \"non-octal character in \\\\o{} (closing brace missing?)\\0\"\n  /* 65 */\n  \"different names for subpatterns of the same number are not allowed\\0\"\n  \"(*MARK) must have an argument\\0\"\n  \"non-hex character in \\\\x{} (closing brace missing?)\\0\"\n#ifndef EBCDIC\n  \"\\\\c must be followed by a printable ASCII character\\0\"\n#else\n  \"\\\\c must be followed by a letter or one of @[\\\\]^_?\\0\"\n#endif\n  \"\\\\k is not followed by a braced, angle-bracketed, or quoted name\\0\"\n  /* 70 */\n  \"internal error: unknown meta code in check_lookbehinds()\\0\"\n  \"\\\\N is not supported in a class\\0\"\n  \"callout string is too long\\0\"\n  \"disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\\0\"\n  \"using UTF is disabled by the application\\0\"\n  /* 75 */\n  \"using UCP is disabled by the application\\0\"\n  \"name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\\0\"\n  \"character code point value in \\\\u.... sequence is too large\\0\"\n  \"digits missing after \\\\x or in \\\\x{} or \\\\o{} or \\\\N{U+}\\0\"\n  \"syntax error or number too big in (?(VERSION condition\\0\"\n  /* 80 */\n  \"internal error: unknown opcode in auto_possessify()\\0\"\n  \"missing terminating delimiter for callout with string argument\\0\"\n  \"unrecognized string delimiter follows (?C\\0\"\n  \"using \\\\C is disabled by the application\\0\"\n  \"(?| and/or (?J: or (?x: parentheses are too deeply nested\\0\"\n  /* 85 */\n  \"using \\\\C is disabled in this PCRE2 library\\0\"\n  \"regular expression is too complicated\\0\"\n  \"lookbehind assertion is too long\\0\"\n  \"pattern string is longer than the limit set by the application\\0\"\n  \"internal error: unknown code in parsed pattern\\0\"\n  /* 90 */\n  \"internal error: bad code value in parsed_skip()\\0\"\n  \"PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode\\0\"\n  \"invalid option bits with PCRE2_LITERAL\\0\"\n  \"\\\\N{U+dddd} is supported only in Unicode (UTF) mode\\0\"\n  \"invalid hyphen in option setting\\0\"\n  /* 95 */\n  \"(*alpha_assertion) not recognized\\0\"\n  \"script runs require Unicode support, which this version of PCRE2 does not have\\0\"\n  \"too many capturing groups (maximum 65535)\\0\"\n  \"octal digit missing after \\\\0 (PCRE2_EXTRA_NO_BS0 is set)\\0\"\n  \"\\\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\\0\"\n  /* 100 */\n  \"branch too long in variable-length lookbehind assertion\\0\"\n  \"compiled pattern would be longer than the limit set by the application\\0\"\n  \"octal value given by \\\\ddd is greater than \\\\377 (forbidden by PCRE2_EXTRA_PYTHON_OCTAL)\\0\"\n  \"using callouts is disabled by the application\\0\"\n  \"PCRE2_EXTRA_TURKISH_CASING require Unicode (UTF or UCP) mode\\0\"\n  /* 105 */\n  \"PCRE2_EXTRA_TURKISH_CASING requires UTF in 8-bit mode\\0\"\n  \"PCRE2_EXTRA_TURKISH_CASING and PCRE2_EXTRA_CASELESS_RESTRICT are not compatible\\0\"\n  \"extended character class nesting is too deep\\0\"\n  \"invalid operator in extended character class\\0\"\n  \"unexpected operator in extended character class (no preceding operand)\\0\"\n  /* 110 */\n  \"expected operand after operator in extended character class\\0\"\n  \"square brackets needed to clarify operator precedence in extended character class\\0\"\n  \"missing terminating ] for extended character class (note '[' must be escaped under PCRE2_ALT_EXTENDED_CLASS)\\0\"\n  \"unexpected expression in extended character class (no preceding operator)\\0\"\n  \"empty expression in extended character class\\0\"\n  /* 115 */\n  \"terminating ] with no following closing parenthesis in (?[...]\\0\"\n  \"unexpected character in (?[...]) extended character class\\0\"\n  \"expected capture group number or name\\0\"\n  \"missing opening parenthesis\\0\"\n  \"syntax error in subpattern number (missing terminator?)\\0\"\n  /* 120 */\n  \"erroroffset passed as NULL\\0\"\n  ;\n\n/* Match-time and UTF error texts are in the same format. */\n\nstatic const unsigned char match_error_texts[] =\n  \"no error\\0\"\n  \"no match\\0\"\n  \"partial match\\0\"\n  \"UTF-8 error: 1 byte missing at end\\0\"\n  \"UTF-8 error: 2 bytes missing at end\\0\"\n  /* 5 */\n  \"UTF-8 error: 3 bytes missing at end\\0\"\n  \"UTF-8 error: 4 bytes missing at end\\0\"\n  \"UTF-8 error: 5 bytes missing at end\\0\"\n  \"UTF-8 error: byte 2 top bits not 0x80\\0\"\n  \"UTF-8 error: byte 3 top bits not 0x80\\0\"\n  /* 10 */\n  \"UTF-8 error: byte 4 top bits not 0x80\\0\"\n  \"UTF-8 error: byte 5 top bits not 0x80\\0\"\n  \"UTF-8 error: byte 6 top bits not 0x80\\0\"\n  \"UTF-8 error: 5-byte character is not allowed (RFC 3629)\\0\"\n  \"UTF-8 error: 6-byte character is not allowed (RFC 3629)\\0\"\n  /* 15 */\n  \"UTF-8 error: code points greater than 0x10ffff are not defined\\0\"\n  \"UTF-8 error: code points 0xd800-0xdfff are not defined\\0\"\n  \"UTF-8 error: overlong 2-byte sequence\\0\"\n  \"UTF-8 error: overlong 3-byte sequence\\0\"\n  \"UTF-8 error: overlong 4-byte sequence\\0\"\n  /* 20 */\n  \"UTF-8 error: overlong 5-byte sequence\\0\"\n  \"UTF-8 error: overlong 6-byte sequence\\0\"\n  \"UTF-8 error: isolated byte with 0x80 bit set\\0\"\n  \"UTF-8 error: illegal byte (0xfe or 0xff)\\0\"\n  \"UTF-16 error: missing low surrogate at end\\0\"\n  /* 25 */\n  \"UTF-16 error: invalid low surrogate\\0\"\n  \"UTF-16 error: isolated low surrogate\\0\"\n  \"UTF-32 error: code points 0xd800-0xdfff are not defined\\0\"\n  \"UTF-32 error: code points greater than 0x10ffff are not defined\\0\"\n  \"bad data value\\0\"\n  /* 30 */\n  \"patterns do not all use the same character tables\\0\"\n  \"magic number missing\\0\"\n  \"pattern compiled in wrong mode: 8/16/32-bit error\\0\"\n  \"bad offset value\\0\"\n  \"bad option value\\0\"\n  /* 35 */\n  \"invalid replacement string\\0\"\n  \"bad offset into UTF string\\0\"\n  \"callout error code\\0\"              /* Never returned by PCRE2 itself */\n  \"invalid data in workspace for DFA restart\\0\"\n  \"too much recursion for DFA matching\\0\"\n  /* 40 */\n  \"backreference condition or recursion test is not supported for DFA matching\\0\"\n  \"function is not supported for DFA matching\\0\"\n  \"pattern contains an item that is not supported for DFA matching\\0\"\n  \"workspace size exceeded in DFA matching\\0\"\n  \"internal error - pattern overwritten?\\0\"\n  /* 45 */\n  \"bad JIT option\\0\"\n  \"JIT stack limit reached\\0\"\n  \"match limit exceeded\\0\"\n  \"no more memory\\0\"\n  \"unknown substring\\0\"\n  /* 50 */\n  \"non-unique substring name\\0\"\n  \"NULL argument passed with non-zero length\\0\"\n  \"nested recursion at the same subject position\\0\"\n  \"matching depth limit exceeded\\0\"\n  \"requested value is not available\\0\"\n  /* 55 */\n  \"requested value is not set\\0\"\n  \"offset limit set without PCRE2_USE_OFFSET_LIMIT\\0\"\n  \"bad escape sequence in replacement string\\0\"\n  \"expected closing curly bracket in replacement string\\0\"\n  \"bad substitution in replacement string\\0\"\n  /* 60 */\n  \"match with end before start or start moved backwards is not supported\\0\"\n  \"too many replacements (more than INT_MAX)\\0\"\n  \"bad serialized data\\0\"\n  \"heap limit exceeded\\0\"\n  \"invalid syntax\\0\"\n  /* 65 */\n  \"internal error: duplicate substitution match\\0\"\n  \"PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\\0\"\n  \"internal error: invalid substring offset\\0\"\n  \"feature is not supported by the JIT compiler\\0\"\n  \"error performing replacement case transformation\\0\"\n  /* 70 */\n  \"replacement too large (longer than PCRE2_SIZE)\\0\"\n  \"substitute pattern differs from prior match call\\0\"\n  \"substitute subject differs from prior match call\\0\"\n  \"substitute start offset differs from prior match call\\0\"\n  \"substitute options differ from prior match call\\0\"\n  \"disallowed use of \\\\K in lookaround\\0\"\n  ;\n\n\n/*************************************************\n*            Return error message                *\n*************************************************/\n\n/* This function copies an error message into a buffer whose units are of an\nappropriate width. Error numbers are positive for compile-time errors, and\nnegative for match-time errors (except for UTF errors), but the numbers are all\ndistinct.\n\nArguments:\n  enumber       error number\n  buffer        where to put the message (zero terminated)\n  size          size of the buffer in code units\n\nReturns:        length of message if all is well\n                negative on error\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, PCRE2_SIZE size)\n{\nconst unsigned char *message;\nPCRE2_SIZE i;\nint n, rc = 0;\n\nif (size == 0) return PCRE2_ERROR_NOMEMORY;\n\nif (enumber >= COMPILE_ERROR_BASE)  /* Compile error */\n  {\n  message = compile_error_texts;\n  n = enumber - COMPILE_ERROR_BASE;\n  }\nelse if (enumber < 0)               /* Match or UTF error */\n  {\n  message = match_error_texts;\n  n = -enumber;\n  }\nelse                                /* Invalid error number */\n  {\n  message = (const unsigned char *)\"\\0\";  /* Empty message list */\n  n = 1;\n  }\n\nfor (; n > 0; n--)\n  {\n  while (*message++ != CHAR_NUL) {}\n  if (*message == CHAR_NUL) return PCRE2_ERROR_BADDATA;\n  }\n\nfor (i = 0; *message != 0; i++)\n  {\n  if (i >= size - 1)\n    {\n    rc = PCRE2_ERROR_NOMEMORY;\n    break;\n    }\n  buffer[i] = *message++;\n  }\n\n#if defined EBCDIC && 'a' != 0x81\n/* If compiling for EBCDIC, but the compiler's string literals are not EBCDIC,\nthen we are in the \"force EBCDIC 1047\" mode. I have chosen to add a few lines\nhere to translate the error strings on the fly, rather than require the string\nliterals above to be written out arduously using the \"STR_XYZ\" macros. */\nfor (PCRE2_SIZE j = 0; j < i; ++j)\n  buffer[j] = PRIV(ascii_to_ebcdic_1047)[buffer[j]];\n#endif\n\nbuffer[i] = 0;     /* Terminate message, even if truncated. */\nreturn rc? rc : (int)i;\n}\n\n/* End of pcre2_error.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_extuni.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains an internal function that is used to match a Unicode\nextended grapheme sequence. It is used by both pcre2_match() and\npcre2_dfa_match(). However, it is called only when Unicode support is being\ncompiled. Nevertheless, we provide a dummy function when there is no Unicode\nsupport, because some compilers do not like functionless source files. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* Dummy function */\n\n#ifndef SUPPORT_UNICODE\nPCRE2_SPTR\nPRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,\n  PCRE2_SPTR end_subject, BOOL utf, int *xcount)\n{\n(void)c;\n(void)eptr;\n(void)start_subject;\n(void)end_subject;\n(void)utf;\n(void)xcount;\nreturn NULL;\n}\n#else\n\n\n/*************************************************\n*      Match an extended grapheme sequence       *\n*************************************************/\n\n/* NOTE: The logic contained in this function is replicated in three special-\npurpose functions in the pcre2_jit_compile.c module. If the logic below is\nchanged, they must be kept in step so that the interpreter and the JIT have the\nsame behaviour.\n\nArguments:\n  c              the first character\n  eptr           pointer to next character\n  start_subject  pointer to start of subject\n  end_subject    pointer to end of subject\n  utf            TRUE if in UTF mode\n  xcount         pointer to count of additional characters,\n                   or NULL if count not needed\n\nReturns:         pointer after the end of the sequence\n*/\n\nPCRE2_SPTR\nPRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,\n  PCRE2_SPTR end_subject, BOOL utf, int *xcount)\n{\nBOOL was_ep_ZWJ = FALSE;\nint lgb = UCD_GRAPHBREAK(c);\n\nwhile (eptr < end_subject)\n  {\n  int rgb;\n  int len = 1;\n  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }\n  rgb = UCD_GRAPHBREAK(c);\n  if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;\n\n  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was\n  preceded by Extended Pictographic. */\n\n  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)\n    break;\n\n  /* Not breaking between Regional Indicators is allowed only if there\n  are an even number of preceding RIs. */\n\n  if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)\n    {\n    int ricount = 0;\n    PCRE2_SPTR bptr = eptr - 1;\n    if (utf) BACKCHAR(bptr);\n\n    /* bptr is pointing to the left-hand character */\n\n    while (bptr > start_subject)\n      {\n      bptr--;\n      if (utf)\n        {\n        BACKCHAR(bptr);\n        GETCHAR(c, bptr);\n        }\n      else\n      c = *bptr;\n      if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break;\n      ricount++;\n      }\n    if ((ricount & 1) != 0) break;  /* Grapheme break required */\n    }\n\n  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in\n  between; see next statement). */\n\n  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);\n\n  /* If Extend follows Extended_Pictographic, do not update lgb; this allows\n  any number of them before a following ZWJ. */\n\n  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) lgb = rgb;\n\n  eptr += len;\n  if (xcount != NULL) *xcount += 1;\n  }\n\nreturn eptr;\n}\n\n#endif  /* SUPPORT_UNICODE */\n\n/* End of pcre2_extuni.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_find_bracket.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains a single function that scans through a compiled pattern\nuntil it finds a capturing bracket with the given number, or, if the number is\nnegative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The\nfunction is called from pcre2_compile.c and also from pcre2_study.c when\nfinding the minimum matching length. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*    Scan compiled regex for specific bracket    *\n*************************************************/\n\n/*\nArguments:\n  code        points to start of expression\n  utf         TRUE in UTF mode\n  number      the required bracket number or negative to find a lookbehind\n\nReturns:      pointer to the opcode for the bracket, or NULL if not found\n*/\n\nPCRE2_SPTR\nPRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number)\n{\nfor (;;)\n  {\n  PCRE2_UCHAR c = *code;\n\n  if (c == OP_END) return NULL;\n\n  /* XCLASS is used for classes that cannot be represented just by a bit map.\n  This includes negated single high-valued characters. ECLASS is used for\n  classes that use set operations internally. CALLOUT_STR is used for\n  callouts with string arguments. In each case the length in the table is\n  zero; the actual length is stored in the compiled code. */\n\n  if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1);\n  else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);\n\n  /* Handle lookbehind */\n\n  else if (c == OP_REVERSE || c == OP_VREVERSE)\n    {\n    if (number < 0) return code;\n    code += PRIV(OP_lengths)[c];\n    }\n\n  /* Handle capturing bracket */\n\n  else if (c == OP_CBRA || c == OP_SCBRA ||\n           c == OP_CBRAPOS || c == OP_SCBRAPOS)\n    {\n    int n = (int)GET2(code, 1+LINK_SIZE);\n    if (n == number) return code;\n    code += PRIV(OP_lengths)[c];\n    }\n\n  /* Otherwise, we can get the item's length from the table, except that for\n  repeated character types, we have to test for \\p and \\P, which have an extra\n  two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we\n  must add in its length. */\n\n  else\n    {\n    switch(c)\n      {\n      case OP_TYPESTAR:\n      case OP_TYPEMINSTAR:\n      case OP_TYPEPLUS:\n      case OP_TYPEMINPLUS:\n      case OP_TYPEQUERY:\n      case OP_TYPEMINQUERY:\n      case OP_TYPEPOSSTAR:\n      case OP_TYPEPOSPLUS:\n      case OP_TYPEPOSQUERY:\n      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;\n      break;\n\n      case OP_TYPEUPTO:\n      case OP_TYPEMINUPTO:\n      case OP_TYPEEXACT:\n      case OP_TYPEPOSUPTO:\n      if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)\n        code += 2;\n      break;\n\n      case OP_MARK:\n      case OP_COMMIT_ARG:\n      case OP_PRUNE_ARG:\n      case OP_SKIP_ARG:\n      case OP_THEN_ARG:\n      code += code[1];\n      break;\n      }\n\n    /* Add in the fixed length from the table */\n\n    code += PRIV(OP_lengths)[c];\n\n  /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be\n  followed by a multi-byte character. The length in the table is a minimum, so\n  we have to arrange to skip the extra bytes. */\n\n#ifdef MAYBE_UTF_MULTI\n    if (utf) switch(c)\n      {\n      case OP_CHAR:\n      case OP_CHARI:\n      case OP_NOT:\n      case OP_NOTI:\n      case OP_EXACT:\n      case OP_EXACTI:\n      case OP_NOTEXACT:\n      case OP_NOTEXACTI:\n      case OP_UPTO:\n      case OP_UPTOI:\n      case OP_NOTUPTO:\n      case OP_NOTUPTOI:\n      case OP_MINUPTO:\n      case OP_MINUPTOI:\n      case OP_NOTMINUPTO:\n      case OP_NOTMINUPTOI:\n      case OP_POSUPTO:\n      case OP_POSUPTOI:\n      case OP_NOTPOSUPTO:\n      case OP_NOTPOSUPTOI:\n      case OP_STAR:\n      case OP_STARI:\n      case OP_NOTSTAR:\n      case OP_NOTSTARI:\n      case OP_MINSTAR:\n      case OP_MINSTARI:\n      case OP_NOTMINSTAR:\n      case OP_NOTMINSTARI:\n      case OP_POSSTAR:\n      case OP_POSSTARI:\n      case OP_NOTPOSSTAR:\n      case OP_NOTPOSSTARI:\n      case OP_PLUS:\n      case OP_PLUSI:\n      case OP_NOTPLUS:\n      case OP_NOTPLUSI:\n      case OP_MINPLUS:\n      case OP_MINPLUSI:\n      case OP_NOTMINPLUS:\n      case OP_NOTMINPLUSI:\n      case OP_POSPLUS:\n      case OP_POSPLUSI:\n      case OP_NOTPOSPLUS:\n      case OP_NOTPOSPLUSI:\n      case OP_QUERY:\n      case OP_QUERYI:\n      case OP_NOTQUERY:\n      case OP_NOTQUERYI:\n      case OP_MINQUERY:\n      case OP_MINQUERYI:\n      case OP_NOTMINQUERY:\n      case OP_NOTMINQUERYI:\n      case OP_POSQUERY:\n      case OP_POSQUERYI:\n      case OP_NOTPOSQUERY:\n      case OP_NOTPOSQUERYI:\n      if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);\n      break;\n      }\n#else\n    (void)(utf);  /* Keep compiler happy by referencing function argument */\n#endif  /* MAYBE_UTF_MULTI */\n    }\n  }\n}\n\n/* End of pcre2_find_bracket.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_internal.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_INTERNAL_H_IDEMPOTENT_GUARD\n#define PCRE2_INTERNAL_H_IDEMPOTENT_GUARD\n\n/* We do not assume that the config.h file has an idempotent include guard,\nsince it may well be written by clients. The standard Autoheader config.h does\nnot have an include guard (although we could customise that). */\n\n#if defined HAVE_CONFIG_H && !defined PCRE2_CONFIG_H_IDEMPOTENT_GUARD\n#define PCRE2_CONFIG_H_IDEMPOTENT_GUARD\n#include \"config.h\"\n#endif\n\n/* We do not support both EBCDIC and Unicode at the same time. The \"configure\"\nscript prevents both being selected, but not everybody uses \"configure\". EBCDIC\nis only supported for the 8-bit library, but the check for this has to be later\nin this file, because the first part is not width-dependent, and is included by\npcre2test.c with CODE_UNIT_WIDTH == 0. */\n\n#if defined EBCDIC && defined SUPPORT_UNICODE\n#error The use of both EBCDIC and SUPPORT_UNICODE is not supported.\n#endif\n\n/* When compiling one of the libraries, the value of PCRE2_CODE_UNIT_WIDTH must\nbe 8, 16, or 32. AutoTools and CMake ensure that this is always the case, but\nother other building methods may not, so here is a check. It is cut out when\nbuilding pcre2test, bcause that sets the value to zero. No other source should\nbe including this file. There is no explicit way of forcing a compile to be\nabandoned, but trying to include a non-existent file seems cleanest. Otherwise\nthere will be many irrelevant consequential errors. */\n\n#if (!defined PCRE2_PCRE2TEST && !defined PCRE2_DFTABLES) && \\\n  (!defined PCRE2_CODE_UNIT_WIDTH ||     \\\n    (PCRE2_CODE_UNIT_WIDTH != 8 &&       \\\n     PCRE2_CODE_UNIT_WIDTH != 16 &&      \\\n     PCRE2_CODE_UNIT_WIDTH != 32))\n#error PCRE2_CODE_UNIT_WIDTH must be defined as 8, 16, or 32.\n#endif\n\n\n/* Standard C headers */\n\n#include <ctype.h>\n#include <limits.h>\n#include <stddef.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/* Macros to make boolean values more obvious. The #ifndef is to pacify\ncompiler warnings in environments where these macros are defined elsewhere.\nUnfortunately, there is no way to do the same for the typedef. */\n\ntypedef int BOOL;\n#ifndef FALSE\n#define FALSE   0\n#define TRUE    1\n#endif\n\n/* Helper macro for static (compile-time) assertions. Can be used inside\nfunctions, or at the top-level of a file. */\n#define STATIC_ASSERT_JOIN(a,b) a ## b\n#define STATIC_ASSERT(cond, msg) \\\n  typedef int STATIC_ASSERT_JOIN(static_assertion_,msg)[(cond)?1:-1]\n\n/* Valgrind (memcheck) support */\n\n#ifdef SUPPORT_VALGRIND\n#include <valgrind/memcheck.h>\n#endif\n\n/* -ftrivial-auto-var-init support supports initializing all local variables\nto avoid some classes of bug, but this can cause an unacceptable slowdown\nfor large on-stack arrays in hot functions. This macro lets us annotate\nsuch arrays. */\n\n#ifdef HAVE_ATTRIBUTE_UNINITIALIZED\n#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized))\n#else\n#define PCRE2_KEEP_UNINITIALIZED\n#endif\n\n/* Older versions of MSVC lack snprintf(). This define allows for\nwarning/error-free compilation and testing with MSVC compilers back to at least\nMSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */\n\n#if defined(_MSC_VER) && (_MSC_VER < 1900)\n#define snprintf _snprintf\n#endif\n\n/* When compiling a DLL for Windows, the exported symbols have to be declared\nusing some MS magic, as documented here:\nhttps://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport\n\nIn pcre2.h (which is included below), we define only PCRE2_EXP_DECL,\nwhich is all that is needed for applications (they just import the symbols). To\ncompile the library, we use:\n\n  PCRE2_EXP_DECL    for declarations\n  PCRE2_EXP_DEFN    for definitions\n\nThe reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test,\nwhich is an application, but needs to import this file in order to \"peek\" at\ninternals, can #include pcre2.h first to get an application's-eye view.\n\nIn principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,\nspecial-purpose environments) might want to stick other stuff in front of\nexported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN\nonly if it is not already set. */\n\n#if defined __cplusplus\n#error This project uses C99. C++ is not supported.\n#endif\n\n#ifndef PCRE2_EXP_DECL\n#  if defined(_WIN32) && !defined(PCRE2_STATIC)\n#    define PCRE2_EXP_DECL  extern __declspec(dllexport)\n#  else\n#    define PCRE2_EXP_DECL  extern PCRE2_EXPORT\n#  endif\n#endif\n\n#ifndef PCRE2_EXP_DEFN\n#  if defined(_WIN32) && !defined(PCRE2_STATIC)\n#    define PCRE2_EXP_DEFN  extern __declspec(dllexport)\n#  else\n#    define PCRE2_EXP_DEFN  extern PCRE2_EXPORT\n#  endif\n#endif\n\n/* Include the public PCRE2 header and the definitions of UCP character\nproperty values. This must follow the setting of PCRE2_EXP_DECL above. */\n\n#include \"pcre2.h\"\n#include \"pcre2_ucp.h\"\n\n/* When checking for integer overflow, we need to handle large integers.\nIf a 64-bit integer type is available, we can use that.\nOtherwise we have to cast to double, which of course requires floating point\narithmetic. Handle this by defining a macro for the appropriate type. */\n\n#if defined INT64_MAX || defined int64_t\n#define INT64_OR_DOUBLE int64_t\n#else\n#define INT64_OR_DOUBLE double\n#endif\n\n/* External (in the C sense) functions and tables that are private to the\nlibraries are always referenced using the PRIV macro. This makes it possible\nfor pcre2test.c to include some of the source files from the libraries using a\ndifferent PRIV definition to avoid name clashes. It also makes it clear in the\ncode that a non-static object is being referenced. */\n\n#ifndef PRIV\n#define PRIV(name) _pcre2_##name\n#endif\n\n/* This is an unsigned int value that no UTF character can ever have, as\nUnicode doesn't go beyond 0x0010ffff. */\n\n#define NOTACHAR 0xffffffff\n\n/* This is the largest valid UTF/Unicode code point. */\n\n#define MAX_UTF_CODE_POINT 0x10ffff\n\n/* Compile-time positive error numbers (all except UTF errors, which are\nnegative) start at this value. It should probably never be changed, in case\nsome application is checking for specific numbers. There is a copy of this\n#define in pcre2posix.c (which now no longer includes this file). Ideally, a\nway of having a single definition should be found, but as the number is\nunlikely to change, this is not a pressing issue. The original reason for\nhaving a base other than 0 was to keep the absolute values of compile-time and\nrun-time error numbers numerically different, but in the event the code does\nnot rely on this. */\n\n#define COMPILE_ERROR_BASE 100\n\n/* The initial frames vector for remembering pcre2_match() backtracking points\nis allocated on the heap, of this size (bytes) or ten times the frame size if\nlarger, unless the heap limit is smaller. Typical frame sizes are a few hundred\nbytes (it depends on the number of capturing parentheses) so 20KiB handles\nquite a few frames. A larger vector on the heap is obtained for matches that\nneed more frames, subject to the heap limit. */\n\n#define START_FRAMES_SIZE 20480\n\n/* For DFA matching, an initial internal workspace vector is allocated on the\nstack. The heap is used only if this turns out to be too small. */\n\n#define DFA_START_RWS_SIZE 30720\n\n/* Define the default BSR convention. */\n\n#ifdef BSR_ANYCRLF\n#define BSR_DEFAULT PCRE2_BSR_ANYCRLF\n#else\n#define BSR_DEFAULT PCRE2_BSR_UNICODE\n#endif\n\n\n/* ---------------- Basic UTF-8 macros ---------------- */\n\n/* These UTF-8 macros are always defined because they are used in pcre2test for\nhandling wide characters in 16-bit and 32-bit modes, even if an 8-bit library\nis not supported. */\n\n/* Tests whether a UTF-8 code point needs extra bytes to decode. */\n\n#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)\n\n/* The following macros were originally written in the form of loops that used\ndata from the tables whose names start with PRIV(utf8_table). They were\nrewritten by a user so as not to use loops, because in some environments this\ngives a significant performance advantage, and it seems never to do any harm.\n*/\n\n/* Base macro to pick up the remaining bytes of a UTF-8 character, not\nadvancing the pointer. */\n\n#define GETUTF8(c, eptr) \\\n    { \\\n    if ((c & 0x20u) == 0) \\\n      c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \\\n    else if ((c & 0x10u) == 0) \\\n      c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \\\n    else if ((c & 0x08u) == 0) \\\n      c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \\\n      ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \\\n    else if ((c & 0x04u) == 0) \\\n      c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \\\n          ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \\\n          (eptr[4] & 0x3fu); \\\n    else \\\n      c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \\\n          ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \\\n          ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \\\n    }\n\n/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing\nthe pointer. */\n\n#define GETUTF8INC(c, eptr) \\\n    { \\\n    if ((c & 0x20u) == 0) \\\n      c = ((c & 0x1fu) << 6) | (*eptr++ & 0x3fu); \\\n    else if ((c & 0x10u) == 0) \\\n      { \\\n      c = ((c & 0x0fu) << 12) | ((*eptr & 0x3fu) << 6) | (eptr[1] & 0x3fu); \\\n      eptr += 2; \\\n      } \\\n    else if ((c & 0x08u) == 0) \\\n      { \\\n      c = ((c & 0x07u) << 18) | ((*eptr & 0x3fu) << 12) | \\\n          ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \\\n      eptr += 3; \\\n      } \\\n    else if ((c & 0x04u) == 0) \\\n      { \\\n      c = ((c & 0x03u) << 24) | ((*eptr & 0x3fu) << 18) | \\\n          ((eptr[1] & 0x3fu) << 12) | ((eptr[2] & 0x3fu) << 6) | \\\n          (eptr[3] & 0x3fu); \\\n      eptr += 4; \\\n      } \\\n    else \\\n      { \\\n      c = ((c & 0x01u) << 30) | ((*eptr & 0x3fu) << 24) | \\\n          ((eptr[1] & 0x3fu) << 18) | ((eptr[2] & 0x3fu) << 12) | \\\n          ((eptr[3] & 0x3fu) << 6) | (eptr[4] & 0x3fu); \\\n      eptr += 5; \\\n      } \\\n    }\n\n/* Base macro to pick up the remaining bytes of a UTF-8 character, not\nadvancing the pointer, incrementing the length. */\n\n#define GETUTF8LEN(c, eptr, len) \\\n    { \\\n    if ((c & 0x20u) == 0) \\\n      { \\\n      c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \\\n      len++; \\\n      } \\\n    else if ((c & 0x10u)  == 0) \\\n      { \\\n      c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \\\n      len += 2; \\\n      } \\\n    else if ((c & 0x08u)  == 0) \\\n      {\\\n      c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \\\n          ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \\\n      len += 3; \\\n      } \\\n    else if ((c & 0x04u)  == 0) \\\n      { \\\n      c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \\\n          ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \\\n          (eptr[4] & 0x3fu); \\\n      len += 4; \\\n      } \\\n    else \\\n      {\\\n      c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \\\n          ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \\\n          ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \\\n      len += 5; \\\n      } \\\n    }\n\n/* --------------- Whitespace macros ---------------- */\n\n/* Tests for Unicode horizontal and vertical whitespace characters must check a\nnumber of different values. Using a switch statement for this generates the\nfastest code (no loop, no memory access), and there are several places in the\ninterpreter code where this happens. In order to ensure that all the case lists\nremain in step, we use macros so that there is only one place where the lists\nare defined.\n\nThese values are also required as lists in pcre2_compile.c when processing \\h,\n\\H, \\v and \\V in a character class. The lists are defined in pcre2_tables.c,\nbut macros that define the values are here so that all the definitions are\ntogether. The lists must be in ascending character order, terminated by\nNOTACHAR (which is 0xffffffff).\n\nAny changes should ensure that the various macros are kept in step with each\nother. NOTE: The values also appear in pcre2_jit_compile.c. */\n\n/* -------------- ASCII/Unicode environments -------------- */\n\n#ifndef EBCDIC\n\n/* Character U+180E (Mongolian Vowel Separator) is not included in the list of\nspaces in the Unicode file PropList.txt, and Perl does not recognize it as a\nspace. However, in many other sources it is listed as a space and has been in\nPCRE (both APIs) for a long time. */\n\n#define HSPACE_LIST \\\n  CHAR_HT, CHAR_SPACE, CHAR_NBSP, \\\n  0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \\\n  0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x202f, 0x205f, 0x3000, \\\n  NOTACHAR\n\n#define HSPACE_MULTIBYTE_CASES \\\n  case 0x1680:  /* OGHAM SPACE MARK */ \\\n  case 0x180e:  /* MONGOLIAN VOWEL SEPARATOR */ \\\n  case 0x2000:  /* EN QUAD */ \\\n  case 0x2001:  /* EM QUAD */ \\\n  case 0x2002:  /* EN SPACE */ \\\n  case 0x2003:  /* EM SPACE */ \\\n  case 0x2004:  /* THREE-PER-EM SPACE */ \\\n  case 0x2005:  /* FOUR-PER-EM SPACE */ \\\n  case 0x2006:  /* SIX-PER-EM SPACE */ \\\n  case 0x2007:  /* FIGURE SPACE */ \\\n  case 0x2008:  /* PUNCTUATION SPACE */ \\\n  case 0x2009:  /* THIN SPACE */ \\\n  case 0x200a:  /* HAIR SPACE */ \\\n  case 0x202f:  /* NARROW NO-BREAK SPACE */ \\\n  case 0x205f:  /* MEDIUM MATHEMATICAL SPACE */ \\\n  case 0x3000   /* IDEOGRAPHIC SPACE */\n\n#define HSPACE_BYTE_CASES \\\n  case CHAR_HT: \\\n  case CHAR_SPACE: \\\n  case CHAR_NBSP\n\n#define HSPACE_CASES \\\n  HSPACE_BYTE_CASES: \\\n  HSPACE_MULTIBYTE_CASES\n\n#define VSPACE_LIST \\\n  CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR\n\n#define VSPACE_MULTIBYTE_CASES \\\n  case 0x2028:    /* LINE SEPARATOR */ \\\n  case 0x2029     /* PARAGRAPH SEPARATOR */\n\n#define VSPACE_BYTE_CASES \\\n  case CHAR_LF: \\\n  case CHAR_VT: \\\n  case CHAR_FF: \\\n  case CHAR_CR: \\\n  case CHAR_NEL\n\n#define VSPACE_CASES \\\n  VSPACE_BYTE_CASES: \\\n  VSPACE_MULTIBYTE_CASES\n\n/* -------------- EBCDIC environments -------------- */\n\n#else\n#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR\n\n#define HSPACE_BYTE_CASES \\\n  case CHAR_HT: \\\n  case CHAR_SPACE: \\\n  case CHAR_NBSP\n\n#define HSPACE_CASES HSPACE_BYTE_CASES\n\n#ifdef EBCDIC_NL25\n#define VSPACE_LIST \\\n  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR\n#else\n#define VSPACE_LIST \\\n  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR\n#endif\n\n#define VSPACE_BYTE_CASES \\\n  case CHAR_LF: \\\n  case CHAR_VT: \\\n  case CHAR_FF: \\\n  case CHAR_CR: \\\n  case CHAR_NEL\n\n#define VSPACE_CASES VSPACE_BYTE_CASES\n#endif  /* EBCDIC */\n\n/* -------------- End of whitespace macros -------------- */\n\n\n/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF,\n\"any\" and \"anycrlf\" at present). The following macros are used to package up\ntesting for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various\nmodules to indicate in which datablock the parameters exist, and what the\nstart/end of string field names are. */\n\n#define NLTYPE_FIXED    0     /* Newline is a fixed length string */\n#define NLTYPE_ANY      1     /* Newline is any Unicode line ending */\n#define NLTYPE_ANYCRLF  2     /* Newline is CR, LF, or CRLF */\n\n/* This macro checks for a newline at the given position */\n\n#define IS_NEWLINE(p) \\\n  ((NLBLOCK->nltype != NLTYPE_FIXED)? \\\n    ((p) < NLBLOCK->PSEND && \\\n     PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \\\n       &(NLBLOCK->nllen), utf)) \\\n    : \\\n    ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \\\n     UCHAR21TEST(p) == NLBLOCK->nl[0] && \\\n     (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1])       \\\n    ) \\\n  )\n\n/* This macro checks for a newline immediately preceding the given position */\n\n#define WAS_NEWLINE(p) \\\n  ((NLBLOCK->nltype != NLTYPE_FIXED)? \\\n    ((p) > NLBLOCK->PSSTART && \\\n     PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \\\n       &(NLBLOCK->nllen), utf)) \\\n    : \\\n    ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \\\n     UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] &&              \\\n     (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \\\n    ) \\\n  )\n\n/* Private flags containing information about the compiled pattern. The first\nthree must not be changed, because whichever is set is actually the number of\nbytes in a code unit in that mode. */\n\n#define PCRE2_MODE8         0x00000001u /* compiled in 8 bit mode */\n#define PCRE2_MODE16        0x00000002u /* compiled in 16 bit mode */\n#define PCRE2_MODE32        0x00000004u /* compiled in 32 bit mode */\n#define PCRE2_FIRSTSET      0x00000010u /* first_code unit is set */\n#define PCRE2_FIRSTCASELESS 0x00000020u /* caseless first code unit */\n#define PCRE2_FIRSTMAPSET   0x00000040u /* bitmap of first code units is set */\n#define PCRE2_LASTSET       0x00000080u /* last code unit is set */\n#define PCRE2_LASTCASELESS  0x00000100u /* caseless last code unit */\n#define PCRE2_STARTLINE     0x00000200u /* start after \\n for multiline */\n#define PCRE2_JCHANGED      0x00000400u /* j option used in pattern */\n#define PCRE2_HASCRORLF     0x00000800u /* explicit \\r or \\n in pattern */\n#define PCRE2_HASTHEN       0x00001000u /* pattern contains (*THEN) */\n#define PCRE2_MATCH_EMPTY   0x00002000u /* pattern can match empty string */\n#define PCRE2_BSR_SET       0x00004000u /* BSR was set in the pattern */\n#define PCRE2_NL_SET        0x00008000u /* newline was set in the pattern */\n#define PCRE2_NOTEMPTY_SET  0x00010000u /* (*NOTEMPTY) used        ) keep */\n#define PCRE2_NE_ATST_SET   0x00020000u /* (*NOTEMPTY_ATSTART) used) together */\n#define PCRE2_DEREF_TABLES  0x00040000u /* release character tables */\n#define PCRE2_NOJIT         0x00080000u /* (*NOJIT) used */\n#define PCRE2_HASBKPORX     0x00100000u /* contains \\P, \\p, or \\X */\n#define PCRE2_DUPCAPUSED    0x00200000u /* contains (?| */\n#define PCRE2_HASBKC        0x00400000u /* contains \\C */\n#define PCRE2_HASACCEPT     0x00800000u /* contains (*ACCEPT) */\n#define PCRE2_HASBSK        0x01000000u /* contains \\K */\n\n#define PCRE2_MODE_MASK     (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)\n\n/* Values for the matchedby field in a match data block. */\n\nenum { PCRE2_MATCHEDBY_INTERPRETER,     /* pcre2_match() */\n       PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */\n       PCRE2_MATCHEDBY_JIT };           /* pcre2_jit_match() */\n\n/* Values for the flags field in a match data block. */\n\n#define PCRE2_MD_COPIED_SUBJECT  0x01u\n\n/* Magic number to provide a small check against being handed junk. */\n\n#define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */\n\n/* The maximum remaining length of subject we are prepared to search for a\nreq_unit match from an anchored pattern. In 8-bit mode, memchr() is used and is\nmuch faster than the search loop that has to be used in 16-bit and 32-bit\nmodes. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define REQ_CU_MAX       5000\n#else\n#define REQ_CU_MAX       2000\n#endif\n\n/* The maximum nesting depth for Unicode character class sets.\nCurrently fixed. Warning: the interpreter relies on this so it can encode\nthe operand stack in a uint32_t. A nesting limit of 15 implies (15*2+1)=31\nstack operands required, due to the fact that we have two (and only two)\nlevels of operator precedence. In the UTS#18 syntax, you can write 'x&&y[z]'\nand in Perl syntax you can write '(?[ x - y & (z) ])', both of which imply\npushing the match results for x & y to the stack. */\n\n#define ECLASS_NEST_LIMIT  15\n\n/* Offsets for the bitmap tables in the cbits set of tables. Each table\ncontains a set of bits for a class map. Some classes are built by combining\nthese tables. */\n\n#define cbit_space     0      /* [:space:] or \\s */\n#define cbit_xdigit   32      /* [:xdigit:] */\n#define cbit_digit    64      /* [:digit:] or \\d */\n#define cbit_upper    96      /* [:upper:] */\n#define cbit_lower   128      /* [:lower:] */\n#define cbit_word    160      /* [:word:] or \\w */\n#define cbit_graph   192      /* [:graph:] */\n#define cbit_print   224      /* [:print:] */\n#define cbit_punct   256      /* [:punct:] */\n#define cbit_cntrl   288      /* [:cntrl:] */\n#define cbit_length  320      /* Length of the cbits table */\n\n/* Bit definitions for entries in the ctypes table. Do not change these values\nwithout checking pcre2_jit_compile.c, which has an assertion to ensure that\nctype_word has the value 16. */\n\n#define ctype_space    0x01\n#define ctype_letter   0x02\n#define ctype_lcletter 0x04\n#define ctype_digit    0x08\n#define ctype_word     0x10    /* alphanumeric or '_' */\n\n/* Offsets of the various tables from the base tables pointer, and\ntotal length of the tables. */\n\n#define lcc_offset      0                           /* Lower case */\n#define fcc_offset    256                           /* Flip case */\n#define cbits_offset  512                           /* Character classes */\n#define ctypes_offset (cbits_offset + cbit_length)  /* Character types */\n#define TABLES_LENGTH (ctypes_offset + 256)\n\n/* Private flags used in compile_context.optimization_flags */\n\n#define PCRE2_OPTIM_AUTO_POSSESS    0x00000001u\n#define PCRE2_OPTIM_DOTSTAR_ANCHOR  0x00000002u\n#define PCRE2_OPTIM_START_OPTIMIZE  0x00000004u\n\n#define PCRE2_OPTIMIZATION_ALL      0x00000007u\n\n/* -------------------- Character and string names ------------------------ */\n\n/* If PCRE2 is to support UTF-8 on EBCDIC platforms, we cannot use normal\ncharacter constants like '*' because the compiler would emit their EBCDIC code,\nwhich is different from their ASCII/UTF-8 code. Instead we define macros for\nthe characters so that they always use the ASCII/UTF-8 code when UTF-8 support\nis enabled. When UTF-8 support is not enabled, the definitions use character\nliterals. Both character and string versions of each character are needed, and\nthere are some longer strings as well.\n\nThis means that, on EBCDIC platforms, the PCRE2 library can handle either\nEBCDIC, or UTF-8, but not both. To support both in the same compiled library\nwould need different lookups depending on whether PCRE2_UTF was set or not.\nThis would make it impossible to use characters in switch/case statements,\nwhich would reduce performance. For a theoretical use (which nobody has asked\nfor) in a minority area (EBCDIC platforms), this is not sensible. Any\napplication that did need both could compile two versions of the library, using\nmacros to give the functions distinct names. */\n\n#ifndef SUPPORT_UNICODE\n\n/* UTF-8 support is not enabled; use the platform-dependent character literals\nso that PCRE2 works in both ASCII and EBCDIC environments, but only in non-UTF\nmode. Newline characters are problematic in EBCDIC. Though it has CR and LF\ncharacters, a common practice has been to use its NL (0x15) character as the\nline terminator in C-like processing environments. However, sometimes the LF\n(0x25) character is used instead, according to this Unicode document:\n\nhttp://unicode.org/standard/reports/tr13/tr13-5.html\n\nPCRE2 defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25\ninstead. Whichever is *not* chosen is defined as NEL.\n\nIn both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the\nsame code point. */\n\n#ifdef EBCDIC\n\n#ifndef EBCDIC_NL25\n#define CHAR_NL                     '\\x15'\n#define CHAR_NEL                    '\\x25'\n#define STR_NL                      \"\\x15\"\n#define STR_NEL                     \"\\x25\"\n#else\n#define CHAR_NL                     '\\x25'\n#define CHAR_NEL                    '\\x15'\n#define STR_NL                      \"\\x25\"\n#define STR_NEL                     \"\\x15\"\n#endif\n\n#define CHAR_LF                     CHAR_NL\n#define STR_LF                      STR_NL\n\n#define CHAR_ESC                    '\\047'\n#define CHAR_DEL                    '\\007'\n#define CHAR_NBSP                   ((unsigned char)'\\x41')\n#define STR_ESC                     \"\\047\"\n#define STR_DEL                     \"\\007\"\n\n#else  /* Not EBCDIC */\n\n/* In ASCII/Unicode, linefeed is '\\n' and we equate this to NL for\ncompatibility. NEL is the Unicode newline character; make sure it is\na positive value. */\n\n#if '\\n' != 0x0a\n#error \"ASCII character '\\n' is not 0x0a\"\n#endif\n\n#define CHAR_LF                     '\\n'\n#define CHAR_NL                     CHAR_LF\n#define CHAR_NEL                    ((unsigned char)'\\x85')\n#define CHAR_ESC                    '\\033'\n#define CHAR_DEL                    '\\177'\n#define CHAR_NBSP                   ((unsigned char)'\\xa0')\n\n#define STR_LF                      \"\\n\"\n#define STR_NL                      STR_LF\n#define STR_NEL                     \"\\x85\"\n#define STR_ESC                     \"\\033\"\n#define STR_DEL                     \"\\177\"\n\n#endif  /* EBCDIC */\n\n/* When we want to use EBCDIC with an ASCII compiler, for testing EBCDIC on\nASCII platforms, then we can hardcode an EBCDIC codepage (IBM-1047). */\n\n#ifdef EBCDIC_IGNORING_COMPILER\n\n#define CHAR_NUL                    '\\000'\n#define CHAR_HT                     '\\005'\n#define CHAR_VT                     '\\013'\n#define CHAR_FF                     '\\014'\n#define CHAR_CR                     '\\015'\n#define CHAR_BS                     '\\026'\n#define CHAR_BEL                    '\\057'\n\n#define CHAR_SPACE                  '\\100'\n#define CHAR_EXCLAMATION_MARK       '\\132'\n#define CHAR_QUOTATION_MARK         '\\177'\n#define CHAR_NUMBER_SIGN            '\\173'\n#define CHAR_DOLLAR_SIGN            '\\133'\n#define CHAR_PERCENT_SIGN           '\\154'\n#define CHAR_AMPERSAND              '\\120'\n#define CHAR_APOSTROPHE             '\\175'\n#define CHAR_LEFT_PARENTHESIS       '\\115'\n#define CHAR_RIGHT_PARENTHESIS      '\\135'\n#define CHAR_ASTERISK               '\\134'\n#define CHAR_PLUS                   '\\116'\n#define CHAR_COMMA                  '\\153'\n#define CHAR_MINUS                  '\\140'\n#define CHAR_DOT                    '\\113'\n#define CHAR_SLASH                  '\\141'\n#define CHAR_0                      ((unsigned char)'\\xf0')\n#define CHAR_1                      ((unsigned char)'\\xf1')\n#define CHAR_2                      ((unsigned char)'\\xf2')\n#define CHAR_3                      ((unsigned char)'\\xf3')\n#define CHAR_4                      ((unsigned char)'\\xf4')\n#define CHAR_5                      ((unsigned char)'\\xf5')\n#define CHAR_6                      ((unsigned char)'\\xf6')\n#define CHAR_7                      ((unsigned char)'\\xf7')\n#define CHAR_8                      ((unsigned char)'\\xf8')\n#define CHAR_9                      ((unsigned char)'\\xf9')\n#define CHAR_COLON                  '\\172'\n#define CHAR_SEMICOLON              '\\136'\n#define CHAR_LESS_THAN_SIGN         '\\114'\n#define CHAR_EQUALS_SIGN            '\\176'\n#define CHAR_GREATER_THAN_SIGN      '\\156'\n#define CHAR_QUESTION_MARK          '\\157'\n#define CHAR_COMMERCIAL_AT          '\\174'\n#define CHAR_A                      ((unsigned char)'\\xc1')\n#define CHAR_B                      ((unsigned char)'\\xc2')\n#define CHAR_C                      ((unsigned char)'\\xc3')\n#define CHAR_D                      ((unsigned char)'\\xc4')\n#define CHAR_E                      ((unsigned char)'\\xc5')\n#define CHAR_F                      ((unsigned char)'\\xc6')\n#define CHAR_G                      ((unsigned char)'\\xc7')\n#define CHAR_H                      ((unsigned char)'\\xc8')\n#define CHAR_I                      ((unsigned char)'\\xc9')\n#define CHAR_J                      ((unsigned char)'\\xd1')\n#define CHAR_K                      ((unsigned char)'\\xd2')\n#define CHAR_L                      ((unsigned char)'\\xd3')\n#define CHAR_M                      ((unsigned char)'\\xd4')\n#define CHAR_N                      ((unsigned char)'\\xd5')\n#define CHAR_O                      ((unsigned char)'\\xd6')\n#define CHAR_P                      ((unsigned char)'\\xd7')\n#define CHAR_Q                      ((unsigned char)'\\xd8')\n#define CHAR_R                      ((unsigned char)'\\xd9')\n#define CHAR_S                      ((unsigned char)'\\xe2')\n#define CHAR_T                      ((unsigned char)'\\xe3')\n#define CHAR_U                      ((unsigned char)'\\xe4')\n#define CHAR_V                      ((unsigned char)'\\xe5')\n#define CHAR_W                      ((unsigned char)'\\xe6')\n#define CHAR_X                      ((unsigned char)'\\xe7')\n#define CHAR_Y                      ((unsigned char)'\\xe8')\n#define CHAR_Z                      ((unsigned char)'\\xe9')\n#define CHAR_LEFT_SQUARE_BRACKET    ((unsigned char)'\\xad')\n#define CHAR_BACKSLASH              ((unsigned char)'\\xe0')\n#define CHAR_RIGHT_SQUARE_BRACKET   ((unsigned char)'\\xbd')\n#define CHAR_CIRCUMFLEX_ACCENT      '\\137'\n#define CHAR_UNDERSCORE             '\\155'\n#define CHAR_GRAVE_ACCENT           '\\171'\n#define CHAR_a                      ((unsigned char)'\\x81')\n#define CHAR_b                      ((unsigned char)'\\x82')\n#define CHAR_c                      ((unsigned char)'\\x83')\n#define CHAR_d                      ((unsigned char)'\\x84')\n#define CHAR_e                      ((unsigned char)'\\x85')\n#define CHAR_f                      ((unsigned char)'\\x86')\n#define CHAR_g                      ((unsigned char)'\\x87')\n#define CHAR_h                      ((unsigned char)'\\x88')\n#define CHAR_i                      ((unsigned char)'\\x89')\n#define CHAR_j                      ((unsigned char)'\\x91')\n#define CHAR_k                      ((unsigned char)'\\x92')\n#define CHAR_l                      ((unsigned char)'\\x93')\n#define CHAR_m                      ((unsigned char)'\\x94')\n#define CHAR_n                      ((unsigned char)'\\x95')\n#define CHAR_o                      ((unsigned char)'\\x96')\n#define CHAR_p                      ((unsigned char)'\\x97')\n#define CHAR_q                      ((unsigned char)'\\x98')\n#define CHAR_r                      ((unsigned char)'\\x99')\n#define CHAR_s                      ((unsigned char)'\\xa2')\n#define CHAR_t                      ((unsigned char)'\\xa3')\n#define CHAR_u                      ((unsigned char)'\\xa4')\n#define CHAR_v                      ((unsigned char)'\\xa5')\n#define CHAR_w                      ((unsigned char)'\\xa6')\n#define CHAR_x                      ((unsigned char)'\\xa7')\n#define CHAR_y                      ((unsigned char)'\\xa8')\n#define CHAR_z                      ((unsigned char)'\\xa9')\n#define CHAR_LEFT_CURLY_BRACKET     ((unsigned char)'\\xc0')\n#define CHAR_VERTICAL_LINE          '\\117'\n#define CHAR_RIGHT_CURLY_BRACKET    ((unsigned char)'\\xd0')\n#define CHAR_TILDE                  ((unsigned char)'\\xa1')\n\n#define STR_HT                      \"\\005\"\n#define STR_VT                      \"\\013\"\n#define STR_FF                      \"\\014\"\n#define STR_CR                      \"\\015\"\n#define STR_BS                      \"\\026\"\n#define STR_BEL                     \"\\057\"\n\n#define STR_SPACE                   \"\\100\"\n#define STR_EXCLAMATION_MARK        \"\\132\"\n#define STR_QUOTATION_MARK          \"\\177\"\n#define STR_NUMBER_SIGN             \"\\173\"\n#define STR_DOLLAR_SIGN             \"\\133\"\n#define STR_PERCENT_SIGN            \"\\154\"\n#define STR_AMPERSAND               \"\\120\"\n#define STR_APOSTROPHE              \"\\175\"\n#define STR_LEFT_PARENTHESIS        \"\\115\"\n#define STR_RIGHT_PARENTHESIS       \"\\135\"\n#define STR_ASTERISK                \"\\134\"\n#define STR_PLUS                    \"\\116\"\n#define STR_COMMA                   \"\\153\"\n#define STR_MINUS                   \"\\140\"\n#define STR_DOT                     \"\\113\"\n#define STR_SLASH                   \"\\141\"\n#define STR_0                       \"\\360\"\n#define STR_1                       \"\\361\"\n#define STR_2                       \"\\362\"\n#define STR_3                       \"\\363\"\n#define STR_4                       \"\\364\"\n#define STR_5                       \"\\365\"\n#define STR_6                       \"\\366\"\n#define STR_7                       \"\\367\"\n#define STR_8                       \"\\370\"\n#define STR_9                       \"\\371\"\n#define STR_COLON                   \"\\172\"\n#define STR_SEMICOLON               \"\\136\"\n#define STR_LESS_THAN_SIGN          \"\\114\"\n#define STR_EQUALS_SIGN             \"\\176\"\n#define STR_GREATER_THAN_SIGN       \"\\156\"\n#define STR_QUESTION_MARK           \"\\157\"\n#define STR_COMMERCIAL_AT           \"\\174\"\n#define STR_A                       \"\\301\"\n#define STR_B                       \"\\302\"\n#define STR_C                       \"\\303\"\n#define STR_D                       \"\\304\"\n#define STR_E                       \"\\305\"\n#define STR_F                       \"\\306\"\n#define STR_G                       \"\\307\"\n#define STR_H                       \"\\310\"\n#define STR_I                       \"\\311\"\n#define STR_J                       \"\\321\"\n#define STR_K                       \"\\322\"\n#define STR_L                       \"\\323\"\n#define STR_M                       \"\\324\"\n#define STR_N                       \"\\325\"\n#define STR_O                       \"\\326\"\n#define STR_P                       \"\\327\"\n#define STR_Q                       \"\\330\"\n#define STR_R                       \"\\331\"\n#define STR_S                       \"\\342\"\n#define STR_T                       \"\\343\"\n#define STR_U                       \"\\344\"\n#define STR_V                       \"\\345\"\n#define STR_W                       \"\\346\"\n#define STR_X                       \"\\347\"\n#define STR_Y                       \"\\350\"\n#define STR_Z                       \"\\351\"\n#define STR_LEFT_SQUARE_BRACKET     \"\\255\"\n#define STR_BACKSLASH               \"\\340\"\n#define STR_RIGHT_SQUARE_BRACKET    \"\\275\"\n#define STR_CIRCUMFLEX_ACCENT       \"\\137\"\n#define STR_UNDERSCORE              \"\\155\"\n#define STR_GRAVE_ACCENT            \"\\171\"\n#define STR_a                       \"\\201\"\n#define STR_b                       \"\\202\"\n#define STR_c                       \"\\203\"\n#define STR_d                       \"\\204\"\n#define STR_e                       \"\\205\"\n#define STR_f                       \"\\206\"\n#define STR_g                       \"\\207\"\n#define STR_h                       \"\\210\"\n#define STR_i                       \"\\211\"\n#define STR_j                       \"\\221\"\n#define STR_k                       \"\\222\"\n#define STR_l                       \"\\223\"\n#define STR_m                       \"\\224\"\n#define STR_n                       \"\\225\"\n#define STR_o                       \"\\226\"\n#define STR_p                       \"\\227\"\n#define STR_q                       \"\\230\"\n#define STR_r                       \"\\231\"\n#define STR_s                       \"\\242\"\n#define STR_t                       \"\\243\"\n#define STR_u                       \"\\244\"\n#define STR_v                       \"\\245\"\n#define STR_w                       \"\\246\"\n#define STR_x                       \"\\247\"\n#define STR_y                       \"\\250\"\n#define STR_z                       \"\\251\"\n#define STR_LEFT_CURLY_BRACKET      \"\\300\"\n#define STR_VERTICAL_LINE           \"\\117\"\n#define STR_RIGHT_CURLY_BRACKET     \"\\320\"\n#define STR_TILDE                   \"\\241\"\n\n#else  /* EBCDIC_IGNORING_COMPILER */\n\n/* Otherwise, on a real EBCDIC compiler or an ASCII compiler, we can use simple\nstring and character literals. */\n\n#ifdef EBCDIC\n#if 'a' != 0x81\n#error \"EBCDIC character 'a' is not 0x81\"\n#endif\n#else\n#if 'a' != 0x61\n#error \"ASCII character 'a' is not 0x61\"\n#endif\n#endif\n\n#define CHAR_NUL                    '\\0'\n#define CHAR_HT                     '\\t'\n#define CHAR_VT                     '\\v'\n#define CHAR_FF                     '\\f'\n#define CHAR_CR                     '\\r'\n#define CHAR_BS                     '\\b'\n#define CHAR_BEL                    '\\a'\n\n#define CHAR_SPACE                  ' '\n#define CHAR_EXCLAMATION_MARK       '!'\n#define CHAR_QUOTATION_MARK         '\"'\n#define CHAR_NUMBER_SIGN            '#'\n#define CHAR_DOLLAR_SIGN            '$'\n#define CHAR_PERCENT_SIGN           '%'\n#define CHAR_AMPERSAND              '&'\n#define CHAR_APOSTROPHE             '\\''\n#define CHAR_LEFT_PARENTHESIS       '('\n#define CHAR_RIGHT_PARENTHESIS      ')'\n#define CHAR_ASTERISK               '*'\n#define CHAR_PLUS                   '+'\n#define CHAR_COMMA                  ','\n#define CHAR_MINUS                  '-'\n#define CHAR_DOT                    '.'\n#define CHAR_SLASH                  '/'\n#define CHAR_0                      '0'\n#define CHAR_1                      '1'\n#define CHAR_2                      '2'\n#define CHAR_3                      '3'\n#define CHAR_4                      '4'\n#define CHAR_5                      '5'\n#define CHAR_6                      '6'\n#define CHAR_7                      '7'\n#define CHAR_8                      '8'\n#define CHAR_9                      '9'\n#define CHAR_COLON                  ':'\n#define CHAR_SEMICOLON              ';'\n#define CHAR_LESS_THAN_SIGN         '<'\n#define CHAR_EQUALS_SIGN            '='\n#define CHAR_GREATER_THAN_SIGN      '>'\n#define CHAR_QUESTION_MARK          '?'\n#define CHAR_COMMERCIAL_AT          '@'\n#define CHAR_A                      'A'\n#define CHAR_B                      'B'\n#define CHAR_C                      'C'\n#define CHAR_D                      'D'\n#define CHAR_E                      'E'\n#define CHAR_F                      'F'\n#define CHAR_G                      'G'\n#define CHAR_H                      'H'\n#define CHAR_I                      'I'\n#define CHAR_J                      'J'\n#define CHAR_K                      'K'\n#define CHAR_L                      'L'\n#define CHAR_M                      'M'\n#define CHAR_N                      'N'\n#define CHAR_O                      'O'\n#define CHAR_P                      'P'\n#define CHAR_Q                      'Q'\n#define CHAR_R                      'R'\n#define CHAR_S                      'S'\n#define CHAR_T                      'T'\n#define CHAR_U                      'U'\n#define CHAR_V                      'V'\n#define CHAR_W                      'W'\n#define CHAR_X                      'X'\n#define CHAR_Y                      'Y'\n#define CHAR_Z                      'Z'\n#define CHAR_LEFT_SQUARE_BRACKET    '['\n#define CHAR_BACKSLASH              '\\\\'\n#define CHAR_RIGHT_SQUARE_BRACKET   ']'\n#define CHAR_CIRCUMFLEX_ACCENT      '^'\n#define CHAR_UNDERSCORE             '_'\n#define CHAR_GRAVE_ACCENT           '`'\n#define CHAR_a                      'a'\n#define CHAR_b                      'b'\n#define CHAR_c                      'c'\n#define CHAR_d                      'd'\n#define CHAR_e                      'e'\n#define CHAR_f                      'f'\n#define CHAR_g                      'g'\n#define CHAR_h                      'h'\n#define CHAR_i                      'i'\n#define CHAR_j                      'j'\n#define CHAR_k                      'k'\n#define CHAR_l                      'l'\n#define CHAR_m                      'm'\n#define CHAR_n                      'n'\n#define CHAR_o                      'o'\n#define CHAR_p                      'p'\n#define CHAR_q                      'q'\n#define CHAR_r                      'r'\n#define CHAR_s                      's'\n#define CHAR_t                      't'\n#define CHAR_u                      'u'\n#define CHAR_v                      'v'\n#define CHAR_w                      'w'\n#define CHAR_x                      'x'\n#define CHAR_y                      'y'\n#define CHAR_z                      'z'\n#define CHAR_LEFT_CURLY_BRACKET     '{'\n#define CHAR_VERTICAL_LINE          '|'\n#define CHAR_RIGHT_CURLY_BRACKET    '}'\n#define CHAR_TILDE                  '~'\n\n#define STR_HT                      \"\\t\"\n#define STR_VT                      \"\\v\"\n#define STR_FF                      \"\\f\"\n#define STR_CR                      \"\\r\"\n#define STR_BS                      \"\\b\"\n#define STR_BEL                     \"\\a\"\n\n#define STR_SPACE                   \" \"\n#define STR_EXCLAMATION_MARK        \"!\"\n#define STR_QUOTATION_MARK          \"\\\"\"\n#define STR_NUMBER_SIGN             \"#\"\n#define STR_DOLLAR_SIGN             \"$\"\n#define STR_PERCENT_SIGN            \"%\"\n#define STR_AMPERSAND               \"&\"\n#define STR_APOSTROPHE              \"'\"\n#define STR_LEFT_PARENTHESIS        \"(\"\n#define STR_RIGHT_PARENTHESIS       \")\"\n#define STR_ASTERISK                \"*\"\n#define STR_PLUS                    \"+\"\n#define STR_COMMA                   \",\"\n#define STR_MINUS                   \"-\"\n#define STR_DOT                     \".\"\n#define STR_SLASH                   \"/\"\n#define STR_0                       \"0\"\n#define STR_1                       \"1\"\n#define STR_2                       \"2\"\n#define STR_3                       \"3\"\n#define STR_4                       \"4\"\n#define STR_5                       \"5\"\n#define STR_6                       \"6\"\n#define STR_7                       \"7\"\n#define STR_8                       \"8\"\n#define STR_9                       \"9\"\n#define STR_COLON                   \":\"\n#define STR_SEMICOLON               \";\"\n#define STR_LESS_THAN_SIGN          \"<\"\n#define STR_EQUALS_SIGN             \"=\"\n#define STR_GREATER_THAN_SIGN       \">\"\n#define STR_QUESTION_MARK           \"?\"\n#define STR_COMMERCIAL_AT           \"@\"\n#define STR_A                       \"A\"\n#define STR_B                       \"B\"\n#define STR_C                       \"C\"\n#define STR_D                       \"D\"\n#define STR_E                       \"E\"\n#define STR_F                       \"F\"\n#define STR_G                       \"G\"\n#define STR_H                       \"H\"\n#define STR_I                       \"I\"\n#define STR_J                       \"J\"\n#define STR_K                       \"K\"\n#define STR_L                       \"L\"\n#define STR_M                       \"M\"\n#define STR_N                       \"N\"\n#define STR_O                       \"O\"\n#define STR_P                       \"P\"\n#define STR_Q                       \"Q\"\n#define STR_R                       \"R\"\n#define STR_S                       \"S\"\n#define STR_T                       \"T\"\n#define STR_U                       \"U\"\n#define STR_V                       \"V\"\n#define STR_W                       \"W\"\n#define STR_X                       \"X\"\n#define STR_Y                       \"Y\"\n#define STR_Z                       \"Z\"\n#define STR_LEFT_SQUARE_BRACKET     \"[\"\n#define STR_BACKSLASH               \"\\\\\"\n#define STR_RIGHT_SQUARE_BRACKET    \"]\"\n#define STR_CIRCUMFLEX_ACCENT       \"^\"\n#define STR_UNDERSCORE              \"_\"\n#define STR_GRAVE_ACCENT            \"`\"\n#define STR_a                       \"a\"\n#define STR_b                       \"b\"\n#define STR_c                       \"c\"\n#define STR_d                       \"d\"\n#define STR_e                       \"e\"\n#define STR_f                       \"f\"\n#define STR_g                       \"g\"\n#define STR_h                       \"h\"\n#define STR_i                       \"i\"\n#define STR_j                       \"j\"\n#define STR_k                       \"k\"\n#define STR_l                       \"l\"\n#define STR_m                       \"m\"\n#define STR_n                       \"n\"\n#define STR_o                       \"o\"\n#define STR_p                       \"p\"\n#define STR_q                       \"q\"\n#define STR_r                       \"r\"\n#define STR_s                       \"s\"\n#define STR_t                       \"t\"\n#define STR_u                       \"u\"\n#define STR_v                       \"v\"\n#define STR_w                       \"w\"\n#define STR_x                       \"x\"\n#define STR_y                       \"y\"\n#define STR_z                       \"z\"\n#define STR_LEFT_CURLY_BRACKET      \"{\"\n#define STR_VERTICAL_LINE           \"|\"\n#define STR_RIGHT_CURLY_BRACKET     \"}\"\n#define STR_TILDE                   \"~\"\n\n#endif  /* EBCDIC_WITH_ASCII_COMPILER */\n\n#else  /* SUPPORT_UNICODE */\n\n/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This\nworks in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode\nonly. */\n\n#define CHAR_HT                     '\\011'\n#define CHAR_VT                     '\\013'\n#define CHAR_FF                     '\\014'\n#define CHAR_CR                     '\\015'\n#define CHAR_LF                     '\\012'\n#define CHAR_NL                     CHAR_LF\n#define CHAR_NEL                    ((unsigned char)'\\x85')\n#define CHAR_BS                     '\\010'\n#define CHAR_BEL                    '\\007'\n#define CHAR_ESC                    '\\033'\n#define CHAR_DEL                    '\\177'\n\n#define CHAR_NUL                    '\\0'\n#define CHAR_SPACE                  '\\040'\n#define CHAR_EXCLAMATION_MARK       '\\041'\n#define CHAR_QUOTATION_MARK         '\\042'\n#define CHAR_NUMBER_SIGN            '\\043'\n#define CHAR_DOLLAR_SIGN            '\\044'\n#define CHAR_PERCENT_SIGN           '\\045'\n#define CHAR_AMPERSAND              '\\046'\n#define CHAR_APOSTROPHE             '\\047'\n#define CHAR_LEFT_PARENTHESIS       '\\050'\n#define CHAR_RIGHT_PARENTHESIS      '\\051'\n#define CHAR_ASTERISK               '\\052'\n#define CHAR_PLUS                   '\\053'\n#define CHAR_COMMA                  '\\054'\n#define CHAR_MINUS                  '\\055'\n#define CHAR_DOT                    '\\056'\n#define CHAR_SLASH                  '\\057'\n#define CHAR_0                      '\\060'\n#define CHAR_1                      '\\061'\n#define CHAR_2                      '\\062'\n#define CHAR_3                      '\\063'\n#define CHAR_4                      '\\064'\n#define CHAR_5                      '\\065'\n#define CHAR_6                      '\\066'\n#define CHAR_7                      '\\067'\n#define CHAR_8                      '\\070'\n#define CHAR_9                      '\\071'\n#define CHAR_COLON                  '\\072'\n#define CHAR_SEMICOLON              '\\073'\n#define CHAR_LESS_THAN_SIGN         '\\074'\n#define CHAR_EQUALS_SIGN            '\\075'\n#define CHAR_GREATER_THAN_SIGN      '\\076'\n#define CHAR_QUESTION_MARK          '\\077'\n#define CHAR_COMMERCIAL_AT          '\\100'\n#define CHAR_A                      '\\101'\n#define CHAR_B                      '\\102'\n#define CHAR_C                      '\\103'\n#define CHAR_D                      '\\104'\n#define CHAR_E                      '\\105'\n#define CHAR_F                      '\\106'\n#define CHAR_G                      '\\107'\n#define CHAR_H                      '\\110'\n#define CHAR_I                      '\\111'\n#define CHAR_J                      '\\112'\n#define CHAR_K                      '\\113'\n#define CHAR_L                      '\\114'\n#define CHAR_M                      '\\115'\n#define CHAR_N                      '\\116'\n#define CHAR_O                      '\\117'\n#define CHAR_P                      '\\120'\n#define CHAR_Q                      '\\121'\n#define CHAR_R                      '\\122'\n#define CHAR_S                      '\\123'\n#define CHAR_T                      '\\124'\n#define CHAR_U                      '\\125'\n#define CHAR_V                      '\\126'\n#define CHAR_W                      '\\127'\n#define CHAR_X                      '\\130'\n#define CHAR_Y                      '\\131'\n#define CHAR_Z                      '\\132'\n#define CHAR_LEFT_SQUARE_BRACKET    '\\133'\n#define CHAR_BACKSLASH              '\\134'\n#define CHAR_RIGHT_SQUARE_BRACKET   '\\135'\n#define CHAR_CIRCUMFLEX_ACCENT      '\\136'\n#define CHAR_UNDERSCORE             '\\137'\n#define CHAR_GRAVE_ACCENT           '\\140'\n#define CHAR_a                      '\\141'\n#define CHAR_b                      '\\142'\n#define CHAR_c                      '\\143'\n#define CHAR_d                      '\\144'\n#define CHAR_e                      '\\145'\n#define CHAR_f                      '\\146'\n#define CHAR_g                      '\\147'\n#define CHAR_h                      '\\150'\n#define CHAR_i                      '\\151'\n#define CHAR_j                      '\\152'\n#define CHAR_k                      '\\153'\n#define CHAR_l                      '\\154'\n#define CHAR_m                      '\\155'\n#define CHAR_n                      '\\156'\n#define CHAR_o                      '\\157'\n#define CHAR_p                      '\\160'\n#define CHAR_q                      '\\161'\n#define CHAR_r                      '\\162'\n#define CHAR_s                      '\\163'\n#define CHAR_t                      '\\164'\n#define CHAR_u                      '\\165'\n#define CHAR_v                      '\\166'\n#define CHAR_w                      '\\167'\n#define CHAR_x                      '\\170'\n#define CHAR_y                      '\\171'\n#define CHAR_z                      '\\172'\n#define CHAR_LEFT_CURLY_BRACKET     '\\173'\n#define CHAR_VERTICAL_LINE          '\\174'\n#define CHAR_RIGHT_CURLY_BRACKET    '\\175'\n#define CHAR_TILDE                  '\\176'\n#define CHAR_NBSP                   ((unsigned char)'\\xa0')\n\n#define STR_HT                      \"\\011\"\n#define STR_VT                      \"\\013\"\n#define STR_FF                      \"\\014\"\n#define STR_CR                      \"\\015\"\n#define STR_NL                      \"\\012\"\n#define STR_BS                      \"\\010\"\n#define STR_BEL                     \"\\007\"\n#define STR_ESC                     \"\\033\"\n#define STR_DEL                     \"\\177\"\n\n#define STR_SPACE                   \"\\040\"\n#define STR_EXCLAMATION_MARK        \"\\041\"\n#define STR_QUOTATION_MARK          \"\\042\"\n#define STR_NUMBER_SIGN             \"\\043\"\n#define STR_DOLLAR_SIGN             \"\\044\"\n#define STR_PERCENT_SIGN            \"\\045\"\n#define STR_AMPERSAND               \"\\046\"\n#define STR_APOSTROPHE              \"\\047\"\n#define STR_LEFT_PARENTHESIS        \"\\050\"\n#define STR_RIGHT_PARENTHESIS       \"\\051\"\n#define STR_ASTERISK                \"\\052\"\n#define STR_PLUS                    \"\\053\"\n#define STR_COMMA                   \"\\054\"\n#define STR_MINUS                   \"\\055\"\n#define STR_DOT                     \"\\056\"\n#define STR_SLASH                   \"\\057\"\n#define STR_0                       \"\\060\"\n#define STR_1                       \"\\061\"\n#define STR_2                       \"\\062\"\n#define STR_3                       \"\\063\"\n#define STR_4                       \"\\064\"\n#define STR_5                       \"\\065\"\n#define STR_6                       \"\\066\"\n#define STR_7                       \"\\067\"\n#define STR_8                       \"\\070\"\n#define STR_9                       \"\\071\"\n#define STR_COLON                   \"\\072\"\n#define STR_SEMICOLON               \"\\073\"\n#define STR_LESS_THAN_SIGN          \"\\074\"\n#define STR_EQUALS_SIGN             \"\\075\"\n#define STR_GREATER_THAN_SIGN       \"\\076\"\n#define STR_QUESTION_MARK           \"\\077\"\n#define STR_COMMERCIAL_AT           \"\\100\"\n#define STR_A                       \"\\101\"\n#define STR_B                       \"\\102\"\n#define STR_C                       \"\\103\"\n#define STR_D                       \"\\104\"\n#define STR_E                       \"\\105\"\n#define STR_F                       \"\\106\"\n#define STR_G                       \"\\107\"\n#define STR_H                       \"\\110\"\n#define STR_I                       \"\\111\"\n#define STR_J                       \"\\112\"\n#define STR_K                       \"\\113\"\n#define STR_L                       \"\\114\"\n#define STR_M                       \"\\115\"\n#define STR_N                       \"\\116\"\n#define STR_O                       \"\\117\"\n#define STR_P                       \"\\120\"\n#define STR_Q                       \"\\121\"\n#define STR_R                       \"\\122\"\n#define STR_S                       \"\\123\"\n#define STR_T                       \"\\124\"\n#define STR_U                       \"\\125\"\n#define STR_V                       \"\\126\"\n#define STR_W                       \"\\127\"\n#define STR_X                       \"\\130\"\n#define STR_Y                       \"\\131\"\n#define STR_Z                       \"\\132\"\n#define STR_LEFT_SQUARE_BRACKET     \"\\133\"\n#define STR_BACKSLASH               \"\\134\"\n#define STR_RIGHT_SQUARE_BRACKET    \"\\135\"\n#define STR_CIRCUMFLEX_ACCENT       \"\\136\"\n#define STR_UNDERSCORE              \"\\137\"\n#define STR_GRAVE_ACCENT            \"\\140\"\n#define STR_a                       \"\\141\"\n#define STR_b                       \"\\142\"\n#define STR_c                       \"\\143\"\n#define STR_d                       \"\\144\"\n#define STR_e                       \"\\145\"\n#define STR_f                       \"\\146\"\n#define STR_g                       \"\\147\"\n#define STR_h                       \"\\150\"\n#define STR_i                       \"\\151\"\n#define STR_j                       \"\\152\"\n#define STR_k                       \"\\153\"\n#define STR_l                       \"\\154\"\n#define STR_m                       \"\\155\"\n#define STR_n                       \"\\156\"\n#define STR_o                       \"\\157\"\n#define STR_p                       \"\\160\"\n#define STR_q                       \"\\161\"\n#define STR_r                       \"\\162\"\n#define STR_s                       \"\\163\"\n#define STR_t                       \"\\164\"\n#define STR_u                       \"\\165\"\n#define STR_v                       \"\\166\"\n#define STR_w                       \"\\167\"\n#define STR_x                       \"\\170\"\n#define STR_y                       \"\\171\"\n#define STR_z                       \"\\172\"\n#define STR_LEFT_CURLY_BRACKET      \"\\173\"\n#define STR_VERTICAL_LINE           \"\\174\"\n#define STR_RIGHT_CURLY_BRACKET     \"\\175\"\n#define STR_TILDE                   \"\\176\"\n\n#endif  /* SUPPORT_UNICODE */\n\n\n#define STRING_ACCEPT0               STR_A STR_C STR_C STR_E STR_P STR_T \"\\0\"\n#define STRING_COMMIT0               STR_C STR_O STR_M STR_M STR_I STR_T \"\\0\"\n#define STRING_F0                    STR_F \"\\0\"\n#define STRING_FAIL0                 STR_F STR_A STR_I STR_L \"\\0\"\n#define STRING_MARK0                 STR_M STR_A STR_R STR_K \"\\0\"\n#define STRING_PRUNE0                STR_P STR_R STR_U STR_N STR_E \"\\0\"\n#define STRING_SKIP0                 STR_S STR_K STR_I STR_P \"\\0\"\n#define STRING_THEN                  STR_T STR_H STR_E STR_N\n\n#define STRING_atomic0               STR_a STR_t STR_o STR_m STR_i STR_c \"\\0\"\n#define STRING_pla0                  STR_p STR_l STR_a \"\\0\"\n#define STRING_plb0                  STR_p STR_l STR_b \"\\0\"\n#define STRING_napla0                STR_n STR_a STR_p STR_l STR_a \"\\0\"\n#define STRING_naplb0                STR_n STR_a STR_p STR_l STR_b \"\\0\"\n#define STRING_nla0                  STR_n STR_l STR_a \"\\0\"\n#define STRING_nlb0                  STR_n STR_l STR_b \"\\0\"\n#define STRING_scs0                  STR_s STR_c STR_s \"\\0\"\n#define STRING_sr0                   STR_s STR_r \"\\0\"\n#define STRING_asr0                  STR_a STR_s STR_r \"\\0\"\n#define STRING_positive_lookahead0   STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d \"\\0\"\n#define STRING_positive_lookbehind0  STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d \"\\0\"\n#define STRING_non_atomic_positive_lookahead0   STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d \"\\0\"\n#define STRING_non_atomic_positive_lookbehind0  STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d \"\\0\"\n#define STRING_negative_lookahead0   STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d \"\\0\"\n#define STRING_negative_lookbehind0  STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d \"\\0\"\n#define STRING_script_run0           STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n \"\\0\"\n#define STRING_atomic_script_run     STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n\n#define STRING_scan_substring0       STR_s STR_c STR_a STR_n STR_UNDERSCORE STR_s STR_u STR_b STR_s STR_t STR_r STR_i STR_n STR_g \"\\0\"\n\n#define STRING_alpha0                STR_a STR_l STR_p STR_h STR_a \"\\0\"\n#define STRING_lower0                STR_l STR_o STR_w STR_e STR_r \"\\0\"\n#define STRING_upper0                STR_u STR_p STR_p STR_e STR_r \"\\0\"\n#define STRING_alnum0                STR_a STR_l STR_n STR_u STR_m \"\\0\"\n#define STRING_ascii0                STR_a STR_s STR_c STR_i STR_i \"\\0\"\n#define STRING_blank0                STR_b STR_l STR_a STR_n STR_k \"\\0\"\n#define STRING_cntrl0                STR_c STR_n STR_t STR_r STR_l \"\\0\"\n#define STRING_digit0                STR_d STR_i STR_g STR_i STR_t \"\\0\"\n#define STRING_graph0                STR_g STR_r STR_a STR_p STR_h \"\\0\"\n#define STRING_print0                STR_p STR_r STR_i STR_n STR_t \"\\0\"\n#define STRING_punct0                STR_p STR_u STR_n STR_c STR_t \"\\0\"\n#define STRING_space0                STR_s STR_p STR_a STR_c STR_e \"\\0\"\n#define STRING_word0                 STR_w STR_o STR_r STR_d       \"\\0\"\n#define STRING_xdigit                STR_x STR_d STR_i STR_g STR_i STR_t\n\n#define STRING_DEFINE                STR_D STR_E STR_F STR_I STR_N STR_E\n#define STRING_VERSION               STR_V STR_E STR_R STR_S STR_I STR_O STR_N\n#define STRING_WEIRD_STARTWORD       STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET\n#define STRING_WEIRD_ENDWORD         STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET\n\n#define STRING_CR_RIGHTPAR                STR_C STR_R STR_RIGHT_PARENTHESIS\n#define STRING_LF_RIGHTPAR                STR_L STR_F STR_RIGHT_PARENTHESIS\n#define STRING_CRLF_RIGHTPAR              STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS\n#define STRING_ANY_RIGHTPAR               STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS\n#define STRING_ANYCRLF_RIGHTPAR           STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS\n#define STRING_NUL_RIGHTPAR               STR_N STR_U STR_L STR_RIGHT_PARENTHESIS\n#define STRING_BSR_ANYCRLF_RIGHTPAR       STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS\n#define STRING_BSR_UNICODE_RIGHTPAR       STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS\n#define STRING_UTF8_RIGHTPAR              STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS\n#define STRING_UTF16_RIGHTPAR             STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS\n#define STRING_UTF32_RIGHTPAR             STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS\n#define STRING_UTF_RIGHTPAR               STR_U STR_T STR_F STR_RIGHT_PARENTHESIS\n#define STRING_UCP_RIGHTPAR               STR_U STR_C STR_P STR_RIGHT_PARENTHESIS\n#define STRING_NO_AUTO_POSSESS_RIGHTPAR   STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS\n#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS\n#define STRING_NO_JIT_RIGHTPAR            STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS\n#define STRING_NO_START_OPT_RIGHTPAR      STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS\n#define STRING_NOTEMPTY_RIGHTPAR          STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS\n#define STRING_NOTEMPTY_ATSTART_RIGHTPAR  STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS\n#define STRING_CASELESS_RESTRICT_RIGHTPAR STR_C STR_A STR_S STR_E STR_L STR_E STR_S STR_S STR_UNDERSCORE STR_R STR_E STR_S STR_T STR_R STR_I STR_C STR_T STR_RIGHT_PARENTHESIS\n#define STRING_TURKISH_CASING_RIGHTPAR    STR_T STR_U STR_R STR_K STR_I STR_S STR_H STR_UNDERSCORE STR_C STR_A STR_S STR_I STR_N STR_G STR_RIGHT_PARENTHESIS\n#define STRING_LIMIT_HEAP_EQ              STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_H STR_E STR_A STR_P STR_EQUALS_SIGN\n#define STRING_LIMIT_MATCH_EQ             STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN\n#define STRING_LIMIT_DEPTH_EQ             STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_D STR_E STR_P STR_T STR_H STR_EQUALS_SIGN\n#define STRING_LIMIT_RECURSION_EQ         STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN\n#define STRING_MARK                       STR_M STR_A STR_R STR_K\n\n#define STRING_bc                         STR_b STR_c\n#define STRING_bidiclass                  STR_b STR_i STR_d STR_i STR_c STR_l STR_a STR_s STR_s\n#define STRING_sc                         STR_s STR_c\n#define STRING_script                     STR_s STR_c STR_r STR_i STR_p STR_t\n#define STRING_scriptextensions           STR_s STR_c STR_r STR_i STR_p STR_t STR_e STR_x STR_t STR_e STR_n STR_s STR_i STR_o STR_n STR_s\n#define STRING_scx                        STR_s STR_c STR_x\n\n\n/* -------------------- End of character and string names -------------------*/\n\n/* -------------------- Definitions for compiled patterns -------------------*/\n\n/* Codes for different types of Unicode property. If these definitions are\nchanged, the autopossessifying table in pcre2_auto_possess.c must be updated to\nmatch. */\n\n#define PT_LAMP       0    /* L& - the union of Lu, Ll, Lt */\n#define PT_GC         1    /* Specified general characteristic (e.g. L) */\n#define PT_PC         2    /* Specified particular characteristic (e.g. Lu) */\n#define PT_SC         3    /* Script only (e.g. Han) */\n#define PT_SCX        4    /* Script extensions (includes SC) */\n#define PT_ALNUM      5    /* Alphanumeric - the union of L and N */\n#define PT_SPACE      6    /* Perl space - general category Z plus 9,10,12,13 */\n#define PT_PXSPACE    7    /* POSIX space - Z plus 9,10,11,12,13 */\n#define PT_WORD       8    /* Word - L, N, Mn, or Pc */\n#define PT_CLIST      9    /* Pseudo-property: match character list */\n#define PT_UCNC      10    /* Universal Character nameable character */\n#define PT_BIDICL    11    /* Specified bidi class */\n#define PT_BOOL      12    /* Boolean property */\n#define PT_ANY       13    /* Must be the last entry!\n                              Any property - matches all chars */\n#define PT_TABSIZE PT_ANY  /* Size of square table for autopossessify tests */\n\n/* The following special properties are used only in XCLASS items, when POSIX\nclasses are specified and PCRE2_UCP is set - in other words, for Unicode\nhandling of these classes. They are not available via the \\p or \\P escapes like\nthose in the above list, and so they do not take part in the autopossessifying\ntable. */\n\n#define PT_PXGRAPH   14    /* [:graph:] - characters that mark the paper */\n#define PT_PXPRINT   15    /* [:print:] - [:graph:] plus non-control spaces */\n#define PT_PXPUNCT   16    /* [:punct:] - punctuation characters */\n#define PT_PXXDIGIT  17    /* [:xdigit:] - hex digits */\n\n/* This value is used when parsing \\p and \\P escapes to indicate that neither\n\\p{script:...} nor \\p{scx:...} has been encountered. */\n\n#define PT_NOTSCRIPT 255\n\n/* Flag bits and data types for the extended class (OP_XCLASS) for classes that\ncontain characters with values greater than 255. */\n\n#define XCL_NOT      0x01  /* Flag: this is a negative class */\n#define XCL_MAP      0x02  /* Flag: a 32-byte map is present */\n#define XCL_HASPROP  0x04  /* Flag: property checks are present. */\n\n#define XCL_END      0     /* Marks end of individual items */\n#define XCL_SINGLE   1     /* Single item (one multibyte char) follows */\n#define XCL_RANGE    2     /* A range (two multibyte chars) follows */\n#define XCL_PROP     3     /* Unicode property (2-byte property code follows) */\n#define XCL_NOTPROP  4     /* Unicode inverted property (ditto) */\n/* This value represents the beginning of character lists. The value\nis 16 bit long, and stored as a high and low byte pair in 8 bit mode.\nThe lower 12 bit contains information about character lists (see later). */\n#define XCL_LIST     (sizeof(PCRE2_UCHAR) == 1 ? 0x10 : 0x1000)\n\n/* When a character class contains many characters/ranges,\nthey are stored in character lists. There are four character\nlists which contain characters/ranges within a given range.\n\nThe name, character range and item size for each list:\nLow16    [0x100 - 0x7fff]            16 bit items\nHigh16   [0x8000 - 0xffff]           16 bit items\nLow32    [0x10000 - 0x7fffffff]      32 bit items\nHigh32   [0x80000000 - 0xffffffff]   32 bit items\n\nThe Low32 character list is used only when utf encoding or 32 bit\ncharacter width is enabled, and the High32 character is used only\nwhen 32 bit character width is enabled.\n\nEach character list contain items. The lowest bit represents that\nan item is the beginning of a range (bit is cleared), or not (bit\nis set). The other bits represent the character shifted left by\none, so its highest bit is discarded. Due to the layout of character\nlists, the highest bit of a character is always known:\n\nLow16 and Low32: the highest bit is always zero\nHigh16 and High32: the highest bit is always one\n\nThe items are ordered in increasing order, so binary search can be\nused to find the lower bound of an input character. The lower bound\nis the highest item, which value is less or equal than the input\ncharacter. If the lower bit of the item is cleard, or the character\nstored in the item equals to the input character, the input\ncharacter is in the character list. */\n\n/* Character list constants. */\n#define XCL_CHAR_LIST_LOW_16_START 0x100\n#define XCL_CHAR_LIST_LOW_16_END 0x7fff\n#define XCL_CHAR_LIST_LOW_16_ADD 0x0\n\n#define XCL_CHAR_LIST_HIGH_16_START 0x8000\n#define XCL_CHAR_LIST_HIGH_16_END 0xffff\n#define XCL_CHAR_LIST_HIGH_16_ADD 0x8000\n\n#define XCL_CHAR_LIST_LOW_32_START 0x10000\n#define XCL_CHAR_LIST_LOW_32_END 0x7fffffff\n#define XCL_CHAR_LIST_LOW_32_ADD 0x0\n\n#define XCL_CHAR_LIST_HIGH_32_START 0x80000000\n#define XCL_CHAR_LIST_HIGH_32_END 0xffffffff\n#define XCL_CHAR_LIST_HIGH_32_ADD 0x80000000\n\n/* Mask for getting the descriptors of character list ranges.\nEach descriptor has XCL_TYPE_BIT_LEN bits, and can be processed\nby XCL_BEGIN_WITH_RANGE and XCL_ITEM_COUNT_MASK macros. */\n#define XCL_TYPE_MASK 0xfff\n#define XCL_TYPE_BIT_LEN 3\n/* If this bit is set, the first item of the character list is the\nend of a range, which started before the starting character of the\ncharacter list. */\n#define XCL_BEGIN_WITH_RANGE 0x4\n/* Number of items in the character list: 0, 1, or 2. The value 3\nrepresents that the item count is stored at the begining of the\ncharacter list. The item count has the same width as the items\nin the character list (e.g. 16 bit for Low16 and High16 lists). */\n#define XCL_ITEM_COUNT_MASK 0x3\n/* Shift and flag for constructing character list items. The XCL_CHAR_END\nis set, when the item is not the beginning of a range. The XCL_CHAR_SHIFT\ncan be used to encode / decode the character value stored in an item. */\n#define XCL_CHAR_END 0x1\n#define XCL_CHAR_SHIFT 1\n\n/* Flag bits for an extended class (OP_ECLASS), which is used for complex\ncharacter matches such as [\\p{Greek} && \\p{Ll}]. */\n\n#define ECL_MAP     0x01  /* Flag: a 32-byte map is present */\n\n/* Type tags for the items stored in an extended class (OP_ECLASS). These items\nfollow the OP_ECLASS's flag char and bitmap, and represent a Reverse Polish\nNotation list of operands and operators manipulating a stack of bits. */\n\n#define ECL_AND     1 /* Pop two from the stack, AND, and push result. */\n#define ECL_OR      2 /* Pop two from the stack, OR, and push result. */\n#define ECL_XOR     3 /* Pop two from the stack, XOR, and push result. */\n#define ECL_NOT     4 /* Pop one from the stack, NOT, and push result. */\n#define ECL_XCLASS  5 /* XCLASS nested within ECLASS; match and push result. */\n#define ECL_ANY     6 /* Temporary, only used during compilation. */\n#define ECL_NONE    7 /* Temporary, only used during compilation. */\n\n/* These are escaped items that aren't just an encoding of a particular data\nvalue such as \\n. They must have non-zero values, as check_escape() returns 0\nfor a data character. In the escapes[] table in pcre2_compile.c their values\nare negated in order to distinguish them from data values.\n\nThey must appear here in the same order as in the opcode definitions below, up\nto ESC_z. There's a dummy for OP_ALLANY because it corresponds to \".\" in DOTALL\nmode rather than an escape sequence. It is also used for [^] in JavaScript\ncompatibility mode, and for \\C in non-utf mode. In non-DOTALL mode, \".\" behaves\nlike \\N.\n\nESC_ub is a special return from check_escape() when, in BSUX mode, \\u{ is not\nfollowed by hex digits and }, in which case it should mean a literal \"u\"\nfollowed by a literal \"{\". This hack is necessary for cases like \\u{ 12}\nbecause without it, this is interpreted as u{12} now that spaces are allowed in\nquantifiers.\n\nNegative numbers are used to encode a backreference (\\1, \\2, \\3, etc.) in\ncheck_escape(). There are tests in the code for an escape greater than ESC_b\nand less than ESC_Z to detect the types that may be repeated. These are the\ntypes that consume characters. If any new escapes are put in between that don't\nconsume a character, that code will have to change. */\n\nenum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,\n       ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,\n       ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,\n       ESC_E, ESC_Q, ESC_g, ESC_k, ESC_ub };\n\n\n/********************** Opcode definitions ******************/\n\n/****** NOTE NOTE NOTE ******\n\nStarting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in\norder to the list of escapes immediately above. Furthermore, values up to\nOP_DOLLM must not be changed without adjusting the table called autoposstab in\npcre2_auto_possess.c.\n\nWhenever this list is updated, the two macro definitions that follow must be\nupdated to match. The possessification table called \"opcode_possessify\" in\npcre2_compile.c must also be updated, and also the tables called \"coptable\"\nand \"poptable\" in pcre2_dfa_match.c.\n\n****** NOTE NOTE NOTE ******/\n\n\n/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,\nare used in a table for deciding whether a repeated character type can be\nauto-possessified. */\n\n#define FIRST_AUTOTAB_OP       OP_NOT_DIGIT\n#define LAST_AUTOTAB_LEFT_OP   OP_EXTUNI\n#define LAST_AUTOTAB_RIGHT_OP  OP_DOLLM\n\nenum {\n  OP_END,            /* 0 End of pattern */\n\n  /* Values corresponding to backslashed metacharacters */\n\n  OP_SOD,            /* 1 Start of data: \\A */\n  OP_SOM,            /* 2 Start of match (subject + offset): \\G */\n  OP_SET_SOM,        /* 3 Set start of match (\\K) */\n  OP_NOT_WORD_BOUNDARY,  /*  4 \\B -- see also OP_NOT_UCP_WORD_BOUNDARY */\n  OP_WORD_BOUNDARY,      /*  5 \\b -- see also OP_UCP_WORD_BOUNDARY */\n  OP_NOT_DIGIT,          /*  6 \\D */\n  OP_DIGIT,              /*  7 \\d */\n  OP_NOT_WHITESPACE,     /*  8 \\S */\n  OP_WHITESPACE,         /*  9 \\s */\n  OP_NOT_WORDCHAR,       /* 10 \\W */\n  OP_WORDCHAR,           /* 11 \\w */\n\n  OP_ANY,            /* 12 Match any character except newline (\\N) */\n  OP_ALLANY,         /* 13 Match any character */\n  OP_ANYBYTE,        /* 14 Match any byte (\\C); different to OP_ANY for UTF-8 */\n  OP_NOTPROP,        /* 15 \\P (not Unicode property) */\n  OP_PROP,           /* 16 \\p (Unicode property) */\n  OP_ANYNL,          /* 17 \\R (any newline sequence) */\n  OP_NOT_HSPACE,     /* 18 \\H (not horizontal whitespace) */\n  OP_HSPACE,         /* 19 \\h (horizontal whitespace) */\n  OP_NOT_VSPACE,     /* 20 \\V (not vertical whitespace) */\n  OP_VSPACE,         /* 21 \\v (vertical whitespace) */\n  OP_EXTUNI,         /* 22 \\X (extended Unicode sequence */\n  OP_EODN,           /* 23 End of data or \\n at end of data (\\Z) */\n  OP_EOD,            /* 24 End of data (\\z) */\n\n  /* Line end assertions */\n\n  OP_DOLL,           /* 25 End of line - not multiline */\n  OP_DOLLM,          /* 26 End of line - multiline */\n  OP_CIRC,           /* 27 Start of line - not multiline */\n  OP_CIRCM,          /* 28 Start of line - multiline */\n\n  /* Single characters; caseful must precede the caseless ones, and these\n  must remain in this order, and adjacent. */\n\n  OP_CHAR,           /* 29 Match one character, casefully */\n  OP_CHARI,          /* 30 Match one character, caselessly */\n  OP_NOT,            /* 31 Match one character, not the given one, casefully */\n  OP_NOTI,           /* 32 Match one character, not the given one, caselessly */\n\n  /* The following sets of 13 opcodes must always be kept in step because\n  the offset from the first one is used to generate the others. */\n\n  /* Repeated characters; caseful must precede the caseless ones */\n\n  OP_STAR,           /* 33 The maximizing and minimizing versions of */\n  OP_MINSTAR,        /* 34 these six opcodes must come in pairs, with */\n  OP_PLUS,           /* 35 the minimizing one second. */\n  OP_MINPLUS,        /* 36 */\n  OP_QUERY,          /* 37 */\n  OP_MINQUERY,       /* 38 */\n\n  OP_UPTO,           /* 39 From 0 to n matches of one character, caseful*/\n  OP_MINUPTO,        /* 40 */\n  OP_EXACT,          /* 41 Exactly n matches */\n\n  OP_POSSTAR,        /* 42 Possessified star, caseful */\n  OP_POSPLUS,        /* 43 Possessified plus, caseful */\n  OP_POSQUERY,       /* 44 Posesssified query, caseful */\n  OP_POSUPTO,        /* 45 Possessified upto, caseful */\n\n  /* Repeated characters; caseless must follow the caseful ones */\n\n  OP_STARI,          /* 46 */\n  OP_MINSTARI,       /* 47 */\n  OP_PLUSI,          /* 48 */\n  OP_MINPLUSI,       /* 49 */\n  OP_QUERYI,         /* 50 */\n  OP_MINQUERYI,      /* 51 */\n\n  OP_UPTOI,          /* 52 From 0 to n matches of one character, caseless */\n  OP_MINUPTOI,       /* 53 */\n  OP_EXACTI,         /* 54 */\n\n  OP_POSSTARI,       /* 55 Possessified star, caseless */\n  OP_POSPLUSI,       /* 56 Possessified plus, caseless */\n  OP_POSQUERYI,      /* 57 Posesssified query, caseless */\n  OP_POSUPTOI,       /* 58 Possessified upto, caseless */\n\n  /* The negated ones must follow the non-negated ones, and match them */\n  /* Negated repeated character, caseful; must precede the caseless ones */\n\n  OP_NOTSTAR,        /* 59 The maximizing and minimizing versions of */\n  OP_NOTMINSTAR,     /* 60 these six opcodes must come in pairs, with */\n  OP_NOTPLUS,        /* 61 the minimizing one second. They must be in */\n  OP_NOTMINPLUS,     /* 62 exactly the same order as those above. */\n  OP_NOTQUERY,       /* 63 */\n  OP_NOTMINQUERY,    /* 64 */\n\n  OP_NOTUPTO,        /* 65 From 0 to n matches, caseful */\n  OP_NOTMINUPTO,     /* 66 */\n  OP_NOTEXACT,       /* 67 Exactly n matches */\n\n  OP_NOTPOSSTAR,     /* 68 Possessified versions, caseful */\n  OP_NOTPOSPLUS,     /* 69 */\n  OP_NOTPOSQUERY,    /* 70 */\n  OP_NOTPOSUPTO,     /* 71 */\n\n  /* Negated repeated character, caseless; must follow the caseful ones */\n\n  OP_NOTSTARI,       /* 72 */\n  OP_NOTMINSTARI,    /* 73 */\n  OP_NOTPLUSI,       /* 74 */\n  OP_NOTMINPLUSI,    /* 75 */\n  OP_NOTQUERYI,      /* 76 */\n  OP_NOTMINQUERYI,   /* 77 */\n\n  OP_NOTUPTOI,       /* 78 From 0 to n matches, caseless */\n  OP_NOTMINUPTOI,    /* 79 */\n  OP_NOTEXACTI,      /* 80 Exactly n matches */\n\n  OP_NOTPOSSTARI,    /* 81 Possessified versions, caseless */\n  OP_NOTPOSPLUSI,    /* 82 */\n  OP_NOTPOSQUERYI,   /* 83 */\n  OP_NOTPOSUPTOI,    /* 84 */\n\n  /* Character types */\n\n  OP_TYPESTAR,       /* 85 The maximizing and minimizing versions of */\n  OP_TYPEMINSTAR,    /* 86 these six opcodes must come in pairs, with */\n  OP_TYPEPLUS,       /* 87 the minimizing one second. These codes must */\n  OP_TYPEMINPLUS,    /* 88 be in exactly the same order as those above. */\n  OP_TYPEQUERY,      /* 89 */\n  OP_TYPEMINQUERY,   /* 90 */\n\n  OP_TYPEUPTO,       /* 91 From 0 to n matches */\n  OP_TYPEMINUPTO,    /* 92 */\n  OP_TYPEEXACT,      /* 93 Exactly n matches */\n\n  OP_TYPEPOSSTAR,    /* 94 Possessified versions */\n  OP_TYPEPOSPLUS,    /* 95 */\n  OP_TYPEPOSQUERY,   /* 96 */\n  OP_TYPEPOSUPTO,    /* 97 */\n\n  /* These are used for character classes and back references; only the\n  first six are the same as the sets above. */\n\n  OP_CRSTAR,         /* 98 The maximizing and minimizing versions of */\n  OP_CRMINSTAR,      /* 99 all these opcodes must come in pairs, with */\n  OP_CRPLUS,         /* 100 the minimizing one second. These codes must */\n  OP_CRMINPLUS,      /* 101 be in exactly the same order as those above. */\n  OP_CRQUERY,        /* 102 */\n  OP_CRMINQUERY,     /* 103 */\n\n  OP_CRRANGE,        /* 104 These are different to the three sets above. */\n  OP_CRMINRANGE,     /* 105 */\n\n  OP_CRPOSSTAR,      /* 106 Possessified versions */\n  OP_CRPOSPLUS,      /* 107 */\n  OP_CRPOSQUERY,     /* 108 */\n  OP_CRPOSRANGE,     /* 109 */\n\n  /* End of quantifier opcodes */\n\n  OP_CLASS,          /* 110 Match a character class, chars < 256 only */\n  OP_NCLASS,         /* 111 Same, but the bitmap was created from a negative\n                              class - the difference is relevant only when a\n                              character > 255 is encountered. */\n  OP_XCLASS,         /* 112 Extended class for handling > 255 chars within the\n                              class. This does both positive and negative. */\n  OP_ECLASS,         /* 113 Really-extended class, for handling logical\n                              expressions computed over characters. */\n  OP_REF,            /* 114 Match a back reference, casefully */\n  OP_REFI,           /* 115 Match a back reference, caselessly */\n  OP_DNREF,          /* 116 Match a duplicate name backref, casefully */\n  OP_DNREFI,         /* 117 Match a duplicate name backref, caselessly */\n  OP_RECURSE,        /* 118 Match a numbered subpattern (possibly recursive) */\n  OP_CALLOUT,        /* 119 Call out to external function if provided */\n  OP_CALLOUT_STR,    /* 120 Call out with string argument */\n\n  OP_ALT,            /* 121 Start of alternation */\n  OP_KET,            /* 122 End of group that doesn't have an unbounded repeat */\n  OP_KETRMAX,        /* 123 These two must remain together and in this */\n  OP_KETRMIN,        /* 124 order. They are for groups the repeat for ever. */\n  OP_KETRPOS,        /* 125 Possessive unlimited repeat. */\n\n  /* The assertions must come before BRA, CBRA, ONCE, and COND. */\n\n  OP_REVERSE,        /* 126 Move pointer back - used in lookbehind assertions */\n  OP_VREVERSE,       /* 127 Move pointer back - variable */\n  OP_ASSERT,         /* 128 Positive lookahead */\n  OP_ASSERT_NOT,     /* 129 Negative lookahead */\n  OP_ASSERTBACK,     /* 130 Positive lookbehind */\n  OP_ASSERTBACK_NOT, /* 131 Negative lookbehind */\n  OP_ASSERT_NA,      /* 132 Positive non-atomic lookahead */\n  OP_ASSERTBACK_NA,  /* 133 Positive non-atomic lookbehind */\n  OP_ASSERT_SCS,     /* 134 Scan substring */\n\n  /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come\n  immediately after the assertions, with ONCE first, as there's a test for >=\n  ONCE for a subpattern that isn't an assertion. The POS versions must\n  immediately follow the non-POS versions in each case. */\n\n  OP_ONCE,           /* 135 Atomic group, contains captures */\n  OP_SCRIPT_RUN,     /* 136 Non-capture, but check characters' scripts */\n  OP_BRA,            /* 137 Start of non-capturing bracket */\n  OP_BRAPOS,         /* 138 Ditto, with unlimited, possessive repeat */\n  OP_CBRA,           /* 139 Start of capturing bracket */\n  OP_CBRAPOS,        /* 140 Ditto, with unlimited, possessive repeat */\n  OP_COND,           /* 141 Conditional group */\n\n  /* These five must follow the previous five, in the same order. There's a\n  check for >= SBRA to distinguish the two sets. */\n\n  OP_SBRA,           /* 142 Start of non-capturing bracket, check empty  */\n  OP_SBRAPOS,        /* 143 Ditto, with unlimited, possessive repeat */\n  OP_SCBRA,          /* 144 Start of capturing bracket, check empty */\n  OP_SCBRAPOS,       /* 145 Ditto, with unlimited, possessive repeat */\n  OP_SCOND,          /* 146 Conditional group, check empty */\n\n  /* The next two pairs must (respectively) be kept together. */\n\n  OP_CREF,           /* 147 Used to hold a capture number as condition */\n  OP_DNCREF,         /* 148 Used to point to duplicate names as a condition */\n  OP_RREF,           /* 149 Used to hold a recursion number as condition */\n  OP_DNRREF,         /* 150 Used to point to duplicate names as a condition */\n  OP_FALSE,          /* 151 Always false (used by DEFINE and VERSION) */\n  OP_TRUE,           /* 152 Always true (used by VERSION) */\n\n  OP_BRAZERO,        /* 153 These two must remain together and in this */\n  OP_BRAMINZERO,     /* 154 order. */\n  OP_BRAPOSZERO,     /* 155 */\n\n  /* These are backtracking control verbs */\n\n  OP_MARK,           /* 156 always has an argument */\n  OP_PRUNE,          /* 157 */\n  OP_PRUNE_ARG,      /* 158 same, but with argument */\n  OP_SKIP,           /* 159 */\n  OP_SKIP_ARG,       /* 160 same, but with argument */\n  OP_THEN,           /* 161 */\n  OP_THEN_ARG,       /* 162 same, but with argument */\n  OP_COMMIT,         /* 163 */\n  OP_COMMIT_ARG,     /* 164 same, but with argument */\n\n  /* These are forced failure and success verbs. FAIL and ACCEPT do accept an\n  argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL)\n  without the need for a special opcode. */\n\n  OP_FAIL,           /* 165 */\n  OP_ACCEPT,         /* 166 */\n  OP_ASSERT_ACCEPT,  /* 167 Used inside assertions */\n  OP_CLOSE,          /* 168 Used before OP_ACCEPT to close open captures */\n\n  /* This is used to skip a subpattern with a {0} quantifier */\n\n  OP_SKIPZERO,       /* 169 */\n\n  /* This is used to identify a DEFINE group during compilation so that it can\n  be checked for having only one branch. It is changed to OP_FALSE before\n  compilation finishes. */\n\n  OP_DEFINE,         /* 170 */\n\n  /* These opcodes replace their normal counterparts in UCP mode when\n  PCRE2_EXTRA_ASCII_BSW is not set. */\n\n  OP_NOT_UCP_WORD_BOUNDARY, /* 171 */\n  OP_UCP_WORD_BOUNDARY,     /* 172 */\n\n  /* This is not an opcode, but is used to check that tables indexed by opcode\n  are the correct length, in order to catch updating errors - there have been\n  some in the past. */\n\n  OP_TABLE_LENGTH\n\n};\n\n/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro\ndefinitions that follow must also be updated to match. There are also tables\ncalled \"opcode_possessify\" in pcre2_compile.c and \"coptable\" and \"poptable\" in\npcre2_dfa_match.c that must be updated. */\n\n\n/* This macro defines textual names for all the opcodes. These are used only\nfor debugging, and some of them are only partial names. The macro is referenced\nonly in pcre2_printint_inc.h, which fills out the full names in many cases (and in\nsome cases doesn't actually use these names at all). */\n\n#define OP_NAME_LIST \\\n  \"End\", \"\\\\A\", \"\\\\G\", \"\\\\K\", \"\\\\B\", \"\\\\b\", \"\\\\D\", \"\\\\d\",         \\\n  \"\\\\S\", \"\\\\s\", \"\\\\W\", \"\\\\w\", \"Any\", \"AllAny\", \"Anybyte\",         \\\n  \"notprop\", \"prop\", \"\\\\R\", \"\\\\H\", \"\\\\h\", \"\\\\V\", \"\\\\v\",           \\\n  \"extuni\",  \"\\\\Z\", \"\\\\z\",                                        \\\n  \"$\", \"$\", \"^\", \"^\", \"char\", \"chari\", \"not\", \"noti\",             \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\",                                \\\n  \"{\", \"{\", \"{\",                                                  \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\",                                \\\n  \"{\", \"{\", \"{\",                                                  \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\",                                \\\n  \"{\", \"{\", \"{\",                                                  \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\",                                \\\n  \"{\", \"{\", \"{\",                                                  \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\", \"{\", \"{\", \"{\",                 \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"*\", \"*?\", \"+\", \"+?\", \"?\", \"??\", \"{\", \"{\",                      \\\n  \"*+\",\"++\", \"?+\", \"{\",                                           \\\n  \"class\", \"nclass\", \"xclass\", \"eclass\",                          \\\n  \"Ref\", \"Refi\", \"DnRef\", \"DnRefi\",                               \\\n  \"Recurse\", \"Callout\", \"CalloutStr\",                             \\\n  \"Alt\", \"Ket\", \"KetRmax\", \"KetRmin\", \"KetRpos\",                  \\\n  \"Reverse\", \"VReverse\", \"Assert\", \"Assert not\",                  \\\n  \"Assert back\", \"Assert back not\",                               \\\n  \"Non-atomic assert\", \"Non-atomic assert back\",                  \\\n  \"Scan substring\",                                               \\\n  \"Once\",                                                         \\\n  \"Script run\",                                                   \\\n  \"Bra\", \"BraPos\", \"CBra\", \"CBraPos\",                             \\\n  \"Cond\",                                                         \\\n  \"SBra\", \"SBraPos\", \"SCBra\", \"SCBraPos\",                         \\\n  \"SCond\",                                                        \\\n  \"Capture ref\", \"Capture dnref\", \"Cond rec\", \"Cond dnrec\",       \\\n  \"Cond false\", \"Cond true\",                                      \\\n  \"Brazero\", \"Braminzero\", \"Braposzero\",                          \\\n  \"*MARK\", \"*PRUNE\", \"*PRUNE\", \"*SKIP\", \"*SKIP\",                  \\\n  \"*THEN\", \"*THEN\", \"*COMMIT\", \"*COMMIT\", \"*FAIL\",                \\\n  \"*ACCEPT\", \"*ASSERT_ACCEPT\",                                    \\\n  \"Close\", \"Skip zero\", \"Define\", \"\\\\B (ucp)\", \"\\\\b (ucp)\"\n\n\n/* This macro defines the length of fixed length operations in the compiled\nregex. The lengths are used when searching for specific things, and also in the\ndebugging printing of a compiled regex. We use a macro so that it can be\ndefined close to the definitions of the opcodes themselves.\n\nAs things have been extended, some of these are no longer fixed lenths, but are\nminima instead. For example, the length of a single-character repeat may vary\nin UTF-8 mode. The code that uses this table must know about such things. */\n\n#define OP_LENGTHS \\\n  1,                             /* End                                    */ \\\n  1, 1, 1, 1, 1,                 /* \\A, \\G, \\K, \\B, \\b                     */ \\\n  1, 1, 1, 1, 1, 1,              /* \\D, \\d, \\S, \\s, \\W, \\w                 */ \\\n  1, 1, 1,                       /* Any, AllAny, Anybyte                   */ \\\n  3, 3,                          /* \\P, \\p                                 */ \\\n  1, 1, 1, 1, 1,                 /* \\R, \\H, \\h, \\V, \\v                     */ \\\n  1,                             /* \\X                                     */ \\\n  1, 1, 1, 1, 1, 1,              /* \\Z, \\z, $, $M ^, ^M                    */ \\\n  2,                             /* Char  - the minimum length             */ \\\n  2,                             /* Chari  - the minimum length            */ \\\n  2,                             /* not                                    */ \\\n  2,                             /* noti                                   */ \\\n  /* Positive single-char repeats                             ** These are */ \\\n  2, 2, 2, 2, 2, 2,              /* *, *?, +, +?, ?, ??       ** minima in */ \\\n  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto, minupto             ** mode      */ \\\n  2+IMM2_SIZE,                   /* exact                                  */ \\\n  2, 2, 2, 2+IMM2_SIZE,          /* *+, ++, ?+, upto+                      */ \\\n  2, 2, 2, 2, 2, 2,              /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8     */ \\\n  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto I, minupto I                      */ \\\n  2+IMM2_SIZE,                   /* exact I                                */ \\\n  2, 2, 2, 2+IMM2_SIZE,          /* *+I, ++I, ?+I, upto+I                  */ \\\n  /* Negative single-char repeats - only for chars < 256                   */ \\\n  2, 2, 2, 2, 2, 2,              /* NOT *, *?, +, +?, ?, ??                */ \\\n  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto, minupto                      */ \\\n  2+IMM2_SIZE,                   /* NOT exact                              */ \\\n  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *, +, ?, upto           */ \\\n  2, 2, 2, 2, 2, 2,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */ \\\n  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto I, minupto I                  */ \\\n  2+IMM2_SIZE,                   /* NOT exact I                            */ \\\n  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *I, +I, ?I, upto I      */ \\\n  /* Positive type repeats                                                 */ \\\n  2, 2, 2, 2, 2, 2,              /* Type *, *?, +, +?, ?, ??               */ \\\n  2+IMM2_SIZE, 2+IMM2_SIZE,      /* Type upto, minupto                     */ \\\n  2+IMM2_SIZE,                   /* Type exact                             */ \\\n  2, 2, 2, 2+IMM2_SIZE,          /* Possessive *+, ++, ?+, upto+           */ \\\n  /* Character class & ref repeats                                         */ \\\n  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */ \\\n  1+2*IMM2_SIZE, 1+2*IMM2_SIZE,  /* CRRANGE, CRMINRANGE                    */ \\\n  1, 1, 1, 1+2*IMM2_SIZE,        /* Possessive *+, ++, ?+, CRPOSRANGE      */ \\\n  1+(32/sizeof(PCRE2_UCHAR)),    /* CLASS                                  */ \\\n  1+(32/sizeof(PCRE2_UCHAR)),    /* NCLASS                                 */ \\\n  0,                             /* XCLASS - variable length               */ \\\n  0,                             /* ECLASS - variable length               */ \\\n  1+IMM2_SIZE,                   /* REF                                    */ \\\n  1+IMM2_SIZE+1,                 /* REFI                                   */ \\\n  1+2*IMM2_SIZE,                 /* DNREF                                  */ \\\n  1+2*IMM2_SIZE+1,               /* DNREFI                                 */ \\\n  1+LINK_SIZE,                   /* RECURSE                                */ \\\n  1+2*LINK_SIZE+1,               /* CALLOUT                                */ \\\n  0,                             /* CALLOUT_STR - variable length          */ \\\n  1+LINK_SIZE,                   /* Alt                                    */ \\\n  1+LINK_SIZE,                   /* Ket                                    */ \\\n  1+LINK_SIZE,                   /* KetRmax                                */ \\\n  1+LINK_SIZE,                   /* KetRmin                                */ \\\n  1+LINK_SIZE,                   /* KetRpos                                */ \\\n  1+IMM2_SIZE,                   /* Reverse                                */ \\\n  1+2*IMM2_SIZE,                 /* VReverse                               */ \\\n  1+LINK_SIZE,                   /* Assert                                 */ \\\n  1+LINK_SIZE,                   /* Assert not                             */ \\\n  1+LINK_SIZE,                   /* Assert behind                          */ \\\n  1+LINK_SIZE,                   /* Assert behind not                      */ \\\n  1+LINK_SIZE,                   /* NA Assert                              */ \\\n  1+LINK_SIZE,                   /* NA Assert behind                       */ \\\n  1+LINK_SIZE,                   /* Scan substring                         */ \\\n  1+LINK_SIZE,                   /* ONCE                                   */ \\\n  1+LINK_SIZE,                   /* SCRIPT_RUN                             */ \\\n  1+LINK_SIZE,                   /* BRA                                    */ \\\n  1+LINK_SIZE,                   /* BRAPOS                                 */ \\\n  1+LINK_SIZE+IMM2_SIZE,         /* CBRA                                   */ \\\n  1+LINK_SIZE+IMM2_SIZE,         /* CBRAPOS                                */ \\\n  1+LINK_SIZE,                   /* COND                                   */ \\\n  1+LINK_SIZE,                   /* SBRA                                   */ \\\n  1+LINK_SIZE,                   /* SBRAPOS                                */ \\\n  1+LINK_SIZE+IMM2_SIZE,         /* SCBRA                                  */ \\\n  1+LINK_SIZE+IMM2_SIZE,         /* SCBRAPOS                               */ \\\n  1+LINK_SIZE,                   /* SCOND                                  */ \\\n  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* CREF, DNCREF                           */ \\\n  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* RREF, DNRREF                           */ \\\n  1, 1,                          /* FALSE, TRUE                            */ \\\n  1, 1, 1,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */ \\\n  3, 1, 3,                       /* MARK, PRUNE, PRUNE_ARG                 */ \\\n  1, 3,                          /* SKIP, SKIP_ARG                         */ \\\n  1, 3,                          /* THEN, THEN_ARG                         */ \\\n  1, 3,                          /* COMMIT, COMMIT_ARG                     */ \\\n  1, 1, 1,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */ \\\n  1+IMM2_SIZE, 1,                /* CLOSE, SKIPZERO                        */ \\\n  1,                             /* DEFINE                                 */ \\\n  1, 1                           /* \\B and \\b in UCP mode                  */\n\n/* A magic value for OP_RREF to indicate the \"any recursion\" condition. */\n\n#define RREF_ANY  0xffff\n\n/* Constants used by OP_REFI and OP_DNREFI to control matching behaviour. */\n\n#define REFI_FLAG_CASELESS_RESTRICT  0x1\n#define REFI_FLAG_TURKISH_CASING     0x2\n\n\n/* ---------- Private structures that are mode-independent. ---------- */\n\n/* Structure to hold data for custom memory management. */\n\ntypedef struct pcre2_memctl {\n  void *    (*malloc)(size_t, void *);\n  void      (*free)(void *, void *);\n  void      *memory_data;\n} pcre2_memctl;\n\n/* Structure for building a chain of open capturing subpatterns during\ncompiling, so that instructions to close them can be compiled when (*ACCEPT) is\nencountered. */\n\ntypedef struct open_capitem {\n  struct open_capitem *next;    /* Chain link */\n  uint16_t number;              /* Capture number */\n  uint16_t assert_depth;        /* Assertion depth when opened */\n} open_capitem;\n\n/* Layout of the UCP type table that translates property names into types and\ncodes. Each entry used to point directly to a name, but to reduce the number of\nrelocations in shared libraries, it now has an offset into a single string\ninstead. */\n\ntypedef struct {\n  uint16_t name_offset;\n  uint16_t type;\n  uint16_t value;\n} ucp_type_table;\n\n/* Unicode character database (UCD) record format */\n\ntypedef struct {\n  uint8_t script;     /* ucp_Arabic, etc. */\n  uint8_t chartype;   /* ucp_Cc, etc. (general categories) */\n  uint8_t gbprop;     /* ucp_gbControl, etc. (grapheme break property) */\n  uint8_t caseset;    /* offset to multichar other cases or zero */\n  int32_t other_case; /* offset to other case, or zero if none */\n  uint16_t scriptx_bidiclass; /* script extension (11 bit) and bidi class (5 bit) values */\n  uint16_t bprops;    /* binary properties offset */\n} ucd_record;\n\n/* UCD access macros */\n\n#define UCD_BLOCK_SIZE 128\n#define REAL_GET_UCD(ch) (PRIV(ucd_records) + \\\n        PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \\\n        UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n#define GET_UCD(ch) ((ch > MAX_UTF_CODE_POINT)? \\\n  PRIV(dummy_ucd_record) : REAL_GET_UCD(ch))\n#else\n#define GET_UCD(ch) REAL_GET_UCD(ch)\n#endif\n\n#define UCD_SCRIPTX_MASK 0x3ff\n#define UCD_BIDICLASS_SHIFT 11\n#define UCD_BPROPS_MASK 0xfff\n\n#define UCD_SCRIPTX_PROP(prop) ((prop)->scriptx_bidiclass & UCD_SCRIPTX_MASK)\n#define UCD_BIDICLASS_PROP(prop) ((prop)->scriptx_bidiclass >> UCD_BIDICLASS_SHIFT)\n#define UCD_BPROPS_PROP(prop) ((prop)->bprops & UCD_BPROPS_MASK)\n\n#define UCD_CHARTYPE(ch)    GET_UCD(ch)->chartype\n#define UCD_SCRIPT(ch)      GET_UCD(ch)->script\n#define UCD_CATEGORY(ch)    PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]\n#define UCD_GRAPHBREAK(ch)  GET_UCD(ch)->gbprop\n#define UCD_CASESET(ch)     GET_UCD(ch)->caseset\n#define UCD_OTHERCASE(ch)   ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case)))\n#define UCD_SCRIPTX(ch)     UCD_SCRIPTX_PROP(GET_UCD(ch))\n#define UCD_BPROPS(ch)      UCD_BPROPS_PROP(GET_UCD(ch))\n#define UCD_BIDICLASS(ch)   UCD_BIDICLASS_PROP(GET_UCD(ch))\n#define UCD_ANY_I(ch) \\\n  /* match any of the four characters 'i', 'I', U+0130, U+0131 */ \\\n  (((uint32_t)(ch) | 0x20u) == 0x69u || ((uint32_t)(ch) | 1u) == 0x0131u)\n#define UCD_DOTTED_I(ch) \\\n  ((uint32_t)(ch) == 0x69u || (uint32_t)(ch) == 0x0130u)\n#define UCD_FOLD_I_TURKISH(ch) \\\n  ((uint32_t)(ch) == 0x0130u ?   0x69u : \\\n   (uint32_t)(ch) ==   0x49u ? 0x0131u : (uint32_t)(ch))\n\n/* The \"scriptx\" and bprops fields contain offsets into vectors of 32-bit words\nthat form a bitmap representing a list of scripts or boolean properties. These\nmacros test or set a bit in the map by number. */\n\n#define MAPBIT(map,n) ((map)[(n)/32]&(1u<<((n)%32)))\n#define MAPSET(map,n) ((map)[(n)/32]|=(1u<<((n)%32)))\n\n/* Header for serialized pcre2 codes. */\n\ntypedef struct pcre2_serialized_data {\n  uint32_t magic;\n  uint32_t version;\n  uint32_t config;\n  int32_t  number_of_codes;\n} pcre2_serialized_data;\n\n\n\n/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */\n\n/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as\n0, so the following items are omitted. */\n\n#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0\n\n/* EBCDIC is supported only for the 8-bit library. */\n\n#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8\n#error EBCDIC is not supported for the 16-bit or 32-bit libraries\n#endif\n\n/* This is the largest non-UTF code point. */\n\n#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH))\n\n/* Internal shared data tables and variables. These are used by more than one\nof the exported public functions. They have to be \"external\" in the C sense,\nbut are not part of the PCRE2 public API. Although the data for some of them is\nidentical in all libraries, they must have different names so that multiple\nlibraries can be simultaneously linked to a single application. However, UTF-8\ntables are needed only when compiling the 8-bit library. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nextern const int              PRIV(utf8_table1)[];\nextern const unsigned         PRIV(utf8_table1_size);\nextern const int              PRIV(utf8_table2)[];\nextern const int              PRIV(utf8_table3)[];\nextern const uint8_t          PRIV(utf8_table4)[];\n#endif\n\n#define _pcre2_OP_lengths              PCRE2_SUFFIX(_pcre2_OP_lengths_)\n#define _pcre2_callout_end_delims      PCRE2_SUFFIX(_pcre2_callout_end_delims_)\n#define _pcre2_callout_start_delims    PCRE2_SUFFIX(_pcre2_callout_start_delims_)\n#define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_)\n#define _pcre2_default_convert_context PCRE2_SUFFIX(_pcre2_default_convert_context_)\n#define _pcre2_default_match_context   PCRE2_SUFFIX(_pcre2_default_match_context_)\n#define _pcre2_default_tables          PCRE2_SUFFIX(_pcre2_default_tables_)\n#if PCRE2_CODE_UNIT_WIDTH == 32\n#define _pcre2_dummy_ucd_record        PCRE2_SUFFIX(_pcre2_dummy_ucd_record_)\n#endif\n#define _pcre2_hspace_list             PCRE2_SUFFIX(_pcre2_hspace_list_)\n#define _pcre2_vspace_list             PCRE2_SUFFIX(_pcre2_vspace_list_)\n#define _pcre2_ucd_boolprop_sets       PCRE2_SUFFIX(_pcre2_ucd_boolprop_sets_)\n#define _pcre2_ucd_caseless_sets       PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_)\n#define _pcre2_ucd_turkish_dotted_i_caseset  PCRE2_SUFFIX(_pcre2_ucd_turkish_dotted_i_caseset_)\n#define _pcre2_ucd_nocase_ranges       PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_)\n#define _pcre2_ucd_nocase_ranges_size  PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_size_)\n#define _pcre2_ucd_digit_sets          PCRE2_SUFFIX(_pcre2_ucd_digit_sets_)\n#define _pcre2_ucd_script_sets         PCRE2_SUFFIX(_pcre2_ucd_script_sets_)\n#define _pcre2_ucd_records             PCRE2_SUFFIX(_pcre2_ucd_records_)\n#define _pcre2_ucd_stage1              PCRE2_SUFFIX(_pcre2_ucd_stage1_)\n#define _pcre2_ucd_stage2              PCRE2_SUFFIX(_pcre2_ucd_stage2_)\n#define _pcre2_ucp_gbtable             PCRE2_SUFFIX(_pcre2_ucp_gbtable_)\n#define _pcre2_ucp_gentype             PCRE2_SUFFIX(_pcre2_ucp_gentype_)\n#define _pcre2_ucp_typerange           PCRE2_SUFFIX(_pcre2_ucp_typerange_)\n#define _pcre2_unicode_version         PCRE2_SUFFIX(_pcre2_unicode_version_)\n#define _pcre2_utt                     PCRE2_SUFFIX(_pcre2_utt_)\n#define _pcre2_utt_names               PCRE2_SUFFIX(_pcre2_utt_names_)\n#define _pcre2_utt_size                PCRE2_SUFFIX(_pcre2_utt_size_)\n#define _pcre2_ebcdic_1047_to_ascii    PCRE2_SUFFIX(_pcre2_ebcdic_1047_to_ascii_)\n#define _pcre2_ascii_to_ebcdic_1047    PCRE2_SUFFIX(_pcre2_ascii_to_ebcdic_1047_)\n\nextern const uint8_t                   PRIV(OP_lengths)[];\nextern const uint32_t                  PRIV(callout_end_delims)[];\nextern const uint32_t                  PRIV(callout_start_delims)[];\nextern pcre2_compile_context           PRIV(default_compile_context);\nextern pcre2_convert_context           PRIV(default_convert_context);\nextern pcre2_match_context             PRIV(default_match_context);\nextern const uint8_t                   PRIV(default_tables)[];\nextern const uint32_t                  PRIV(hspace_list)[];\nextern const uint32_t                  PRIV(vspace_list)[];\nextern const uint32_t                  PRIV(ucd_boolprop_sets)[];\nextern const uint32_t                  PRIV(ucd_caseless_sets)[];\nextern const uint32_t                  PRIV(ucd_turkish_dotted_i_caseset);\nextern const uint32_t                  PRIV(ucd_nocase_ranges)[];\nextern const uint32_t                  PRIV(ucd_nocase_ranges_size);\nextern const uint32_t                  PRIV(ucd_digit_sets)[];\nextern const uint32_t                  PRIV(ucd_script_sets)[];\nextern const ucd_record                PRIV(ucd_records)[];\n#if PCRE2_CODE_UNIT_WIDTH == 32\nextern const ucd_record                PRIV(dummy_ucd_record)[];\n#endif\nextern const uint16_t                  PRIV(ucd_stage1)[];\nextern const uint16_t                  PRIV(ucd_stage2)[];\nextern const uint32_t                  PRIV(ucp_gbtable)[];\nextern const uint32_t                  PRIV(ucp_gentype)[];\n#ifdef SUPPORT_JIT\nextern const int                       PRIV(ucp_typerange)[];\n#endif\nextern const char                     *PRIV(unicode_version);\nextern const ucp_type_table            PRIV(utt)[];\nextern const char                      PRIV(utt_names)[];\nextern const size_t                    PRIV(utt_size);\nextern const uint8_t                   PRIV(ebcdic_1047_to_ascii)[];\nextern const uint8_t                   PRIV(ascii_to_ebcdic_1047)[];\n\n/* Mode-dependent macros and hidden and private structures are defined in a\nseparate file so that pcre2test can include them at all supported widths. When\ncompiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can\ninclude them at the appropriate width, after setting up suffix macros for the\nprivate structures. */\n\n#define branch_chain                 PCRE2_SUFFIX(branch_chain_)\n#define compile_block                PCRE2_SUFFIX(compile_block_)\n#define dfa_match_block              PCRE2_SUFFIX(dfa_match_block_)\n#define match_block                  PCRE2_SUFFIX(match_block_)\n#define named_group                  PCRE2_SUFFIX(named_group_)\n\n#include \"pcre2_intmodedep.h\"\n\n/* Private \"external\" functions. These are internal functions that are called\nfrom modules other than the one in which they are defined. They have to be\n\"external\" in the C sense, but are not part of the PCRE2 public API. They are\nnot referenced from pcre2test, and must not be defined when no code unit width\nis available. */\n\n#define _pcre2_auto_possessify       PCRE2_SUFFIX(_pcre2_auto_possessify_)\n#define _pcre2_check_escape          PCRE2_SUFFIX(_pcre2_check_escape_)\n#define _pcre2_ckd_smul              PCRE2_SUFFIX(_pcre2_ckd_smul_)\n#define _pcre2_extuni                PCRE2_SUFFIX(_pcre2_extuni_)\n#define _pcre2_find_bracket          PCRE2_SUFFIX(_pcre2_find_bracket_)\n#define _pcre2_is_newline            PCRE2_SUFFIX(_pcre2_is_newline_)\n#define _pcre2_jit_free_rodata       PCRE2_SUFFIX(_pcre2_jit_free_rodata_)\n#define _pcre2_jit_free              PCRE2_SUFFIX(_pcre2_jit_free_)\n#define _pcre2_jit_get_size          PCRE2_SUFFIX(_pcre2_jit_get_size_)\n#define _pcre2_jit_get_target        PCRE2_SUFFIX(_pcre2_jit_get_target_)\n#define _pcre2_memctl_malloc         PCRE2_SUFFIX(_pcre2_memctl_malloc_)\n#define _pcre2_ord2utf               PCRE2_SUFFIX(_pcre2_ord2utf_)\n#define _pcre2_script_run            PCRE2_SUFFIX(_pcre2_script_run_)\n#define _pcre2_strcmp                PCRE2_SUFFIX(_pcre2_strcmp_)\n#define _pcre2_strcmp_c8             PCRE2_SUFFIX(_pcre2_strcmp_c8_)\n#define _pcre2_strcpy_c8             PCRE2_SUFFIX(_pcre2_strcpy_c8_)\n#define _pcre2_strlen                PCRE2_SUFFIX(_pcre2_strlen_)\n#define _pcre2_strncmp               PCRE2_SUFFIX(_pcre2_strncmp_)\n#define _pcre2_strncmp_c8            PCRE2_SUFFIX(_pcre2_strncmp_c8_)\n#define _pcre2_study                 PCRE2_SUFFIX(_pcre2_study_)\n#define _pcre2_valid_utf             PCRE2_SUFFIX(_pcre2_valid_utf_)\n#define _pcre2_was_newline           PCRE2_SUFFIX(_pcre2_was_newline_)\n#define _pcre2_xclass                PCRE2_SUFFIX(_pcre2_xclass_)\n#define _pcre2_eclass                PCRE2_SUFFIX(_pcre2_eclass_)\n\nextern int          _pcre2_auto_possessify(PCRE2_UCHAR *,\n                      const compile_block *);\nextern int          _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,\n                      int *, uint32_t, uint32_t, uint32_t, BOOL, compile_block *);\nextern BOOL         _pcre2_ckd_smul(PCRE2_SIZE *, int, int);\nextern PCRE2_SPTR   _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR,\n                      BOOL, int *);\nextern PCRE2_SPTR   _pcre2_find_bracket(PCRE2_SPTR, BOOL, int);\nextern BOOL         _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,\n                      uint32_t *, BOOL);\nextern void         _pcre2_jit_free_rodata(void *, void *);\nextern void         _pcre2_jit_free(void *, pcre2_memctl *);\nextern size_t       _pcre2_jit_get_size(void *);\nconst char *        _pcre2_jit_get_target(void);\nextern void *       _pcre2_memctl_malloc(size_t, pcre2_memctl *);\nextern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *);\nextern BOOL         _pcre2_script_run(PCRE2_SPTR, PCRE2_SPTR, BOOL);\nextern int          _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR);\nextern int          _pcre2_strcmp_c8(PCRE2_SPTR, const char *);\nextern PCRE2_SIZE   _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *);\nextern PCRE2_SIZE   _pcre2_strlen(PCRE2_SPTR);\nextern int          _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t);\nextern int          _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t);\nextern int          _pcre2_study(pcre2_real_code *);\nextern int          _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *);\nextern BOOL         _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,\n                      uint32_t *, BOOL);\nextern BOOL         _pcre2_xclass(uint32_t, PCRE2_SPTR, const uint8_t *, BOOL);\nextern BOOL         _pcre2_eclass(uint32_t, PCRE2_SPTR, PCRE2_SPTR,\n                      const uint8_t *, BOOL);\n\n#endif  /* PCRE2_CODE_UNIT_WIDTH */\n\n#include \"pcre2_util.h\"\n\n#endif  /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2_internal.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_intmodedep.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains mode-dependent macro and structure definitions. The\nfile is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined.\nThese mode-dependent items are kept in a separate file so that they can also be\n#included multiple times for different code unit widths by pcre2test in order\nto have access to the hidden structures at all supported widths.\n\nSome of the mode-dependent macros are required at different widths for\ndifferent parts of the pcre2test code (in particular, the included\npcre2_printint_inc.h file). We undefine them here so that they can be re-defined\nfor multiple inclusions. Not all of these are used in pcre2test, but it's easier\njust to undefine them all.\n\nYou can also include pcre2_intmodedep.h with PCRE2_CODE_UNIT_WIDTH defined to\nzero in order to simply clear the previous macros. */\n\n#ifndef PCRE2_CODE_UNIT_WIDTH\n#error PCRE2_CODE_UNIT_WIDTH must be defined\n#endif\n\n#undef ACROSSCHAR\n#undef BACKCHAR\n#undef BYTES2CU\n#undef CHMAX_255\n#undef CU2BYTES\n#undef FORWARDCHAR\n#undef FORWARDCHARTEST\n#undef GET\n#undef GET2\n#undef GETCHAR\n#undef GETCHARINC\n#undef GETCHARINCTEST\n#undef GETCHARLEN\n#undef GETCHARLENTEST\n#undef GETCHARTEST\n#undef GET_EXTRALEN\n#undef HAS_EXTRALEN\n#undef IMM2_SIZE\n#undef MAX_255\n#undef MAX_MARK\n#undef MAX_PATTERN_SIZE\n#undef MAX_UTF_SINGLE_CU\n#undef NOT_FIRSTCU\n#undef PUT\n#undef PUT2\n#undef PUT2INC\n#undef PUTCHAR\n#undef PUTINC\n#undef TABLE_GET\n\n/*************************************************\n*                    MACROS                      *\n*************************************************/\n\n/* Macros may be undefined and re-defined if the same file handles multiple\nbit-widths. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 0\n\n/* PCRE keeps offsets in its compiled code as at least 16-bit quantities\n(always stored in big-endian order in 8-bit mode) by default. These are used,\nfor example, to link from the start of a subpattern to its alternatives and its\nend. The use of 16 bits per offset limits the size of an 8-bit compiled regex\nto around 64K, which is big enough for almost everybody. However, I received a\nrequest for an even bigger limit. For this reason, and also to make the code\neasier to maintain, the storing and loading of offsets from the compiled code\nunit string is now handled by the macros that are defined here.\n\nThe macros are controlled by the value of LINK_SIZE. This defaults to 2, but\nvalues of 3 or 4 are also supported. */\n\n#ifndef CONFIGURED_LINK_SIZE\n#if LINK_SIZE == 2\n#define CONFIGURED_LINK_SIZE 2\n#elif LINK_SIZE == 3\n#define CONFIGURED_LINK_SIZE 3\n#elif LINK_SIZE == 4\n#define CONFIGURED_LINK_SIZE 4\n#else\n#error LINK_SIZE must be 2, 3, or 4\n#endif\n#endif /* CONFIGURED_LINK_SIZE */\n\n/* ------------------- 8-bit support  ------------------ */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n\n#if CONFIGURED_LINK_SIZE == 2\n#define PUT(a,n,d)   \\\n  (a[n] = (PCRE2_UCHAR)((d) >> 8)), \\\n  (a[(n)+1] = (PCRE2_UCHAR)((d) & 255))\n#define GET(a,n) \\\n  (unsigned int)(((a)[n] << 8) | (a)[(n)+1])\n#define MAX_PATTERN_SIZE (1 << 16)\n\n#elif CONFIGURED_LINK_SIZE == 3\n#define PUT(a,n,d)       \\\n  (a[n] = (PCRE2_UCHAR)((d) >> 16)),    \\\n  (a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \\\n  (a[(n)+2] = (PCRE2_UCHAR)((d) & 255))\n#define GET(a,n) \\\n  (unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])\n#define MAX_PATTERN_SIZE (1 << 24)\n\n#elif CONFIGURED_LINK_SIZE == 4\n#define PUT(a,n,d)        \\\n  (a[n] = (PCRE2_UCHAR)((d) >> 24)),     \\\n  (a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \\\n  (a[(n)+2] = (PCRE2_UCHAR)((d) >> 8)),  \\\n  (a[(n)+3] = (PCRE2_UCHAR)((d) & 255))\n#define GET(a,n) \\\n  (unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])\n#define MAX_PATTERN_SIZE (1 << 30)   /* Keep it positive */\n\n#endif\n\n\n/* ------------------- 16-bit support  ------------------ */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n\n#if CONFIGURED_LINK_SIZE == 2\n#undef LINK_SIZE\n#define LINK_SIZE 1\n#define PUT(a,n,d)   \\\n  (a[n] = (PCRE2_UCHAR)(d))\n#define GET(a,n) \\\n  (a[n])\n#define MAX_PATTERN_SIZE (1 << 16)\n\n#elif CONFIGURED_LINK_SIZE == 3 || CONFIGURED_LINK_SIZE == 4\n#undef LINK_SIZE\n#define LINK_SIZE 2\n#define PUT(a,n,d)   \\\n  (a[n] = (PCRE2_UCHAR)((d) >> 16)), \\\n  (a[(n)+1] = (PCRE2_UCHAR)((d) & 65535))\n#define GET(a,n) \\\n  (unsigned int)(((a)[n] << 16) | (a)[(n)+1])\n#define MAX_PATTERN_SIZE (1 << 30)  /* Keep it positive */\n\n#endif\n\n\n/* ------------------- 32-bit support  ------------------ */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n#undef LINK_SIZE\n#define LINK_SIZE 1\n#define PUT(a,n,d)   \\\n  (a[n] = (d))\n#define GET(a,n) \\\n  (a[n])\n#define MAX_PATTERN_SIZE (1 << 30)  /* Keep it positive */\n\n#else\n#error Unsupported compiling mode\n#endif\n\n\n/* --------------- Other mode-specific macros ----------------- */\n\n/* PCRE uses some other (at least) 16-bit quantities that do not change when\nthe size of offsets changes. There are used for repeat counts and for other\nthings such as capturing parenthesis numbers in back references.\n\nDefine the number of code units required to hold a 16-bit count/offset, and\nmacros to load and store such a value. For reasons that I do not understand,\nthe expression in the 8-bit GET2 macro is treated by gcc as a signed\nexpression, even when a is declared as unsigned. It seems that any kind of\narithmetic results in a signed value. Hence the cast. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define IMM2_SIZE 2\n#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1])\n#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n#define IMM2_SIZE 1\n#define GET2(a,n) a[n]\n#define PUT2(a,n,d) a[n] = d\n#endif\n\n/* Other macros that are different for 8-bit mode. The MAX_255 macro checks\nwhether its argument, which is assumed to be one code unit, is less than 256.\nThe CHMAX_255 macro does not assume one code unit. The maximum length of a MARK\nname must fit in one code unit; currently it is set to 255 or 65535. The\nTABLE_GET macro is used to access elements of tables containing exactly 256\nitems. Its argument is a code unit. When code points can be greater than 255, a\ncheck is needed before accessing these tables. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define MAX_255(c) TRUE\n#define MAX_MARK ((1u << 8) - 1)\n#define TABLE_GET(c, table, default) ((table)[c])\n#ifdef SUPPORT_UNICODE\n#define SUPPORT_WIDE_CHARS\n#define CHMAX_255(c) ((c) <= 255u)\n#else\n#define CHMAX_255(c) TRUE\n#endif  /* SUPPORT_UNICODE */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n#define CHMAX_255(c) ((c) <= 255u)\n#define MAX_255(c) ((c) <= 255u)\n#define MAX_MARK ((1u << 16) - 1)\n#define SUPPORT_WIDE_CHARS\n#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))\n#endif\n\n\n/* ----------------- Character-handling macros ----------------- */\n\n/* There is a proposed future special \"UTF-21\" mode, in which only the lowest\n21 bits of a 32-bit character are interpreted as UTF, with the remaining 11\nhigh-order bits available to the application for other uses. In preparation for\nthe future implementation of this mode, there are macros that load a data item\nand, if in this special mode, mask it to 21 bits. These macros all have names\nstarting with UCHAR21. In all other modes, including the normal 32-bit\nlibrary, the macros all have the same simple definitions. When the new mode is\nimplemented, it is expected that these definitions will be varied appropriately\nusing #ifdef when compiling the library that supports the special mode. */\n\n#define UCHAR21(eptr)        (*(eptr))\n#define UCHAR21TEST(eptr)    (*(eptr))\n#define UCHAR21INC(eptr)     (*(eptr)++)\n#define UCHAR21INCTEST(eptr) (*(eptr)++)\n\n/* When UTF encoding is being used, a character is no longer just a single\nbyte in 8-bit mode or a single short in 16-bit mode. The macros for character\nhandling generate simple sequences when used in the basic mode, and more\ncomplicated ones for UTF characters. GETCHARLENTEST and other macros are not\nused when UTF is not supported. To make sure they can never even appear when\nUTF support is omitted, we don't even define them. */\n\n#ifndef SUPPORT_UNICODE\n\n/* #define MAX_UTF_SINGLE_CU */\n/* #define HAS_EXTRALEN(c) */\n/* #define GET_EXTRALEN(c) */\n/* #define NOT_FIRSTCU(c) */\n#define GETCHAR(c, eptr) c = *eptr;\n#define GETCHARTEST(c, eptr) c = *eptr;\n#define GETCHARINC(c, eptr) c = *eptr++;\n#define GETCHARINCTEST(c, eptr) c = *eptr++;\n#define GETCHARLEN(c, eptr, len) c = *eptr;\n#define PUTCHAR(c, p) (*p = c, 1)\n/* #define GETCHARLENTEST(c, eptr, len) */\n/* #define BACKCHAR(eptr) */\n/* #define FORWARDCHAR(eptr) */\n/* #define FORWARCCHARTEST(eptr,end) */\n/* #define ACROSSCHAR(condition, eptr, action) */\n\n#else   /* SUPPORT_UNICODE */\n\n/* ------------------- 8-bit support  ------------------ */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define MAYBE_UTF_MULTI          /* UTF chars may use multiple code units */\n\n/* The largest UTF code point that can be encoded as a single code unit. */\n\n#define MAX_UTF_SINGLE_CU 127\n\n/* Tests whether the code point needs extra characters to decode. */\n\n#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c)\n\n/* Returns with the additional number of characters if HAS_EXTRALEN(c) is TRUE.\nOtherwise it has an undefined behaviour. */\n\n#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu])\n\n/* Returns TRUE, if the given value is not the first code unit of a UTF\nsequence. */\n\n#define NOT_FIRSTCU(c) (((c) & 0xc0u) == 0x80u)\n\n/* Get the next UTF-8 character, not advancing the pointer. This is called when\nwe know we are in UTF-8 mode. */\n\n#define GETCHAR(c, eptr) \\\n  c = *eptr; \\\n  if (c >= 0xc0u) GETUTF8(c, eptr);\n\n/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the\npointer. */\n\n#define GETCHARTEST(c, eptr) \\\n  c = *eptr; \\\n  if (utf && c >= 0xc0u) GETUTF8(c, eptr);\n\n/* Get the next UTF-8 character, advancing the pointer. This is called when we\nknow we are in UTF-8 mode. */\n\n#define GETCHARINC(c, eptr) \\\n  c = *eptr++; \\\n  if (c >= 0xc0u) GETUTF8INC(c, eptr);\n\n/* Get the next character, testing for UTF-8 mode, and advancing the pointer.\nThis is called when we don't know if we are in UTF-8 mode. */\n\n#define GETCHARINCTEST(c, eptr) \\\n  c = *eptr++; \\\n  if (utf && c >= 0xc0u) GETUTF8INC(c, eptr);\n\n/* Get the next UTF-8 character, not advancing the pointer, incrementing length\nif there are extra bytes. This is called when we know we are in UTF-8 mode. */\n\n#define GETCHARLEN(c, eptr, len) \\\n  c = *eptr; \\\n  if (c >= 0xc0u) GETUTF8LEN(c, eptr, len);\n\n/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the\npointer, incrementing length if there are extra bytes. This is called when we\ndo not know if we are in UTF-8 mode. */\n\n#define GETCHARLENTEST(c, eptr, len) \\\n  c = *eptr; \\\n  if (utf && c >= 0xc0u) GETUTF8LEN(c, eptr, len);\n\n/* If the pointer is not at the start of a character, move it back until\nit is. This is called only in UTF-8 mode - we don't put a test within the macro\nbecause almost all calls are already within a block of UTF-8 only code. */\n\n#define BACKCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr--\n\n/* Same as above, just in the other direction. */\n#define FORWARDCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr++\n#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0u) == 0x80u) eptr++\n\n/* Same as above, but it allows a fully customizable form. */\n#define ACROSSCHAR(condition, eptr, action) \\\n  while((condition) && ((*eptr) & 0xc0u) == 0x80u) action\n\n/* Deposit a character into memory, returning the number of code units. */\n\n#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \\\n  PRIV(ord2utf)(c,p) : (*p = c, 1))\n\n\n/* ------------------- 16-bit support  ------------------ */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define MAYBE_UTF_MULTI          /* UTF chars may use multiple code units */\n\n/* The largest UTF code point that can be encoded as a single code unit. */\n\n#define MAX_UTF_SINGLE_CU 65535\n\n/* Tests whether the code point needs extra characters to decode. */\n\n#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u)\n\n/* Returns with the additional number of characters if HAS_EXTRALEN(c) is TRUE.\nOtherwise it has an undefined behaviour. */\n\n#define GET_EXTRALEN(c) 1\n\n/* Returns TRUE, if the given value is not the first code unit of a UTF\nsequence. */\n\n#define NOT_FIRSTCU(c) (((c) & 0xfc00u) == 0xdc00u)\n\n/* Base macro to pick up the low surrogate of a UTF-16 character, not\nadvancing the pointer. */\n\n#define GETUTF16(c, eptr) \\\n   { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; }\n\n/* Get the next UTF-16 character, not advancing the pointer. This is called when\nwe know we are in UTF-16 mode. */\n\n#define GETCHAR(c, eptr) \\\n  c = *eptr; \\\n  if ((c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);\n\n/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the\npointer. */\n\n#define GETCHARTEST(c, eptr) \\\n  c = *eptr; \\\n  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);\n\n/* Base macro to pick up the low surrogate of a UTF-16 character, advancing\nthe pointer. */\n\n#define GETUTF16INC(c, eptr) \\\n   { c = (((c & 0x3ffu) << 10) | (*eptr++ & 0x3ffu)) + 0x10000u; }\n\n/* Get the next UTF-16 character, advancing the pointer. This is called when we\nknow we are in UTF-16 mode. */\n\n#define GETCHARINC(c, eptr) \\\n  c = *eptr++; \\\n  if ((c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);\n\n/* Get the next character, testing for UTF-16 mode, and advancing the pointer.\nThis is called when we don't know if we are in UTF-16 mode. */\n\n#define GETCHARINCTEST(c, eptr) \\\n  c = *eptr++; \\\n  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);\n\n/* Base macro to pick up the low surrogate of a UTF-16 character, not\nadvancing the pointer, incrementing the length. */\n\n#define GETUTF16LEN(c, eptr, len) \\\n   { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; len++; }\n\n/* Get the next UTF-16 character, not advancing the pointer, incrementing\nlength if there is a low surrogate. This is called when we know we are in\nUTF-16 mode. */\n\n#define GETCHARLEN(c, eptr, len) \\\n  c = *eptr; \\\n  if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);\n\n/* Get the next UTF-16 character, testing for UTF-16 mode, not advancing the\npointer, incrementing length if there is a low surrogate. This is called when\nwe do not know if we are in UTF-16 mode. */\n\n#define GETCHARLENTEST(c, eptr, len) \\\n  c = *eptr; \\\n  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);\n\n/* If the pointer is not at the start of a character, move it back until\nit is. This is called only in UTF-16 mode - we don't put a test within the\nmacro because almost all calls are already within a block of UTF-16 only\ncode. */\n\n#define BACKCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr--\n\n/* Same as above, just in the other direction. */\n#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr++\n#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00u) == 0xdc00u) eptr++\n\n/* Same as above, but it allows a fully customizable form. */\n#define ACROSSCHAR(condition, eptr, action) \\\n  if ((condition) && ((*eptr) & 0xfc00u) == 0xdc00u) action\n\n/* Deposit a character into memory, returning the number of code units. */\n\n#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \\\n  PRIV(ord2utf)(c,p) : (*p = c, 1))\n\n\n/* ------------------- 32-bit support  ------------------ */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n\n/* These are trivial for the 32-bit library, since all UTF-32 characters fit\ninto one PCRE2_UCHAR unit. */\n\n#define MAX_UTF_SINGLE_CU (0x10ffffu)\n#define HAS_EXTRALEN(c) (0)\n#define GET_EXTRALEN(c) (0)\n#define NOT_FIRSTCU(c) (0)\n\n/* Get the next UTF-32 character, not advancing the pointer. This is called when\nwe know we are in UTF-32 mode. */\n\n#define GETCHAR(c, eptr) \\\n  c = *(eptr);\n\n/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the\npointer. */\n\n#define GETCHARTEST(c, eptr) \\\n  c = *(eptr);\n\n/* Get the next UTF-32 character, advancing the pointer. This is called when we\nknow we are in UTF-32 mode. */\n\n#define GETCHARINC(c, eptr) \\\n  c = *((eptr)++);\n\n/* Get the next character, testing for UTF-32 mode, and advancing the pointer.\nThis is called when we don't know if we are in UTF-32 mode. */\n\n#define GETCHARINCTEST(c, eptr) \\\n  c = *((eptr)++);\n\n/* Get the next UTF-32 character, not advancing the pointer, not incrementing\nlength (since all UTF-32 is of length 1). This is called when we know we are in\nUTF-32 mode. */\n\n#define GETCHARLEN(c, eptr, len) \\\n  GETCHAR(c, eptr)\n\n/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the\npointer, not incrementing the length (since all UTF-32 is of length 1).\nThis is called when we do not know if we are in UTF-32 mode. */\n\n#define GETCHARLENTEST(c, eptr, len) \\\n  GETCHARTEST(c, eptr)\n\n/* If the pointer is not at the start of a character, move it back until\nit is. This is called only in UTF-32 mode - we don't put a test within the\nmacro because almost all calls are already within a block of UTF-32 only\ncode.\n\nThese are all no-ops since all UTF-32 characters fit into one PCRE2_UCHAR. */\n\n#define BACKCHAR(eptr) do { } while (0)\n\n/* Same as above, just in the other direction. */\n\n#define FORWARDCHAR(eptr) do { } while (0)\n#define FORWARDCHARTEST(eptr,end) do { } while (0)\n\n/* Same as above, but it allows a fully customizable form. */\n\n#define ACROSSCHAR(condition, eptr, action) do { } while (0)\n\n/* Deposit a character into memory, returning the number of code units. */\n\n#define PUTCHAR(c, p) (*p = c, 1)\n\n#endif  /* UTF-32 character handling */\n#endif  /* SUPPORT_UNICODE */\n\n\n/* Mode-dependent macros that have the same definition in all modes. */\n\n#define CU2BYTES(x)     ((x)*((PCRE2_CODE_UNIT_WIDTH/8)))\n#define BYTES2CU(x)     ((x)/((PCRE2_CODE_UNIT_WIDTH/8)))\n#define PUTINC(a,n,d)   PUT(a,n,d), a += LINK_SIZE\n#define PUT2INC(a,n,d)  PUT2(a,n,d), a += IMM2_SIZE\n\n#endif /* PCRE2_CODE_UNIT_WIDTH != 0 */\n\n\n\n/*************************************************\n*                 STRUCTURES                     *\n*************************************************/\n\n/* We need a more complex include guard than usual, because the file can be\nincluded once for each bit-width to define the various structures. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_8\n#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_8\n#define PCRE2_INTMODEDEP_CAN_DEFINE\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 16 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_16\n#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_16\n#define PCRE2_INTMODEDEP_CAN_DEFINE\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 32 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_32\n#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_32\n#define PCRE2_INTMODEDEP_CAN_DEFINE\n#endif\n\n#ifdef PCRE2_INTMODEDEP_CAN_DEFINE\n#undef PCRE2_INTMODEDEP_CAN_DEFINE\n\n/* ----------------------- HIDDEN STRUCTURES ----------------------------- */\n\n/* NOTE: All these structures *must* start with a pcre2_memctl structure. The\ncode that uses them is simpler because it assumes this. */\n\n/* The real general context structure. At present it holds only data for custom\nmemory control. */\n\n/* WARNING: if this is ever changed, code in pcre2_substitute.c will have to be\nchanged because it builds a general context \"by hand\" in order to avoid the\nmalloc() call in pcre2_general_context)_create(). There is also code in\npcre2_match.c that makes the same assumption. */\n\ntypedef struct pcre2_real_general_context {\n  pcre2_memctl memctl;\n} pcre2_real_general_context;\n\n/* The real compile context structure */\n\ntypedef struct pcre2_real_compile_context {\n  pcre2_memctl memctl;\n  int (*stack_guard)(uint32_t, void *);\n  void *stack_guard_data;\n  const uint8_t *tables;\n  PCRE2_SIZE max_pattern_length;\n  PCRE2_SIZE max_pattern_compiled_length;\n  uint16_t bsr_convention;\n  uint16_t newline_convention;\n  uint32_t parens_nest_limit;\n  uint32_t extra_options;\n  uint32_t max_varlookbehind;\n  uint32_t optimization_flags;\n} pcre2_real_compile_context;\n\n/* The real match context structure. */\n\ntypedef struct pcre2_real_match_context {\n  pcre2_memctl memctl;\n#ifdef SUPPORT_JIT\n  pcre2_jit_callback jit_callback;\n  void *jit_callback_data;\n#endif\n  int        (*callout)(pcre2_callout_block *, void *);\n  void        *callout_data;\n  int        (*substitute_callout)(pcre2_substitute_callout_block *, void *);\n  void        *substitute_callout_data;\n  PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,\n                                        PCRE2_SIZE, int, void *);\n  void        *substitute_case_callout_data;\n  PCRE2_SIZE offset_limit;\n  uint32_t heap_limit;\n  uint32_t match_limit;\n  uint32_t depth_limit;\n} pcre2_real_match_context;\n\n/* The real convert context structure. */\n\ntypedef struct pcre2_real_convert_context {\n  pcre2_memctl memctl;\n  uint32_t glob_separator;\n  uint32_t glob_escape;\n} pcre2_real_convert_context;\n\n/* The real compiled code structure. The type for the blocksize field is\ndefined specially because it is required in pcre2_serialize_decode() when\ncopying the size from possibly unaligned memory into a variable of the same\ntype. Use a macro rather than a typedef to avoid compiler warnings when this\nfile is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the\nlargest lookbehind that is supported. (OP_REVERSE and OP_VREVERSE in a pattern\nhave 16-bit arguments in 8-bit and 16-bit modes, so we need no more than a\n16-bit field here.) */\n\n#undef  CODE_BLOCKSIZE_TYPE\n#define CODE_BLOCKSIZE_TYPE PCRE2_SIZE\n\n#undef  LOOKBEHIND_MAX\n#define LOOKBEHIND_MAX ((int)UINT16_MAX)\n\ntypedef struct pcre2_real_code {\n  pcre2_memctl memctl;            /* Memory control fields */\n  const uint8_t *tables;          /* The character tables */\n  void    *executable_jit;        /* Pointer to JIT code */\n  uint8_t  start_bitmap[32];      /* Bitmap for starting code unit < 256 */\n  CODE_BLOCKSIZE_TYPE blocksize;  /* Total (bytes) that was malloc-ed */\n  CODE_BLOCKSIZE_TYPE code_start; /* Byte code start offset */\n  uint32_t magic_number;          /* Paranoid and endianness check */\n  uint32_t compile_options;       /* Options passed to pcre2_compile() */\n  uint32_t overall_options;       /* Options after processing the pattern */\n  uint32_t extra_options;         /* Taken from compile_context */\n  uint32_t flags;                 /* Various state flags */\n  uint32_t limit_heap;            /* Limit set in the pattern */\n  uint32_t limit_match;           /* Limit set in the pattern */\n  uint32_t limit_depth;           /* Limit set in the pattern */\n  uint32_t first_codeunit;        /* Starting code unit */\n  uint32_t last_codeunit;         /* This codeunit must be seen */\n  uint16_t bsr_convention;        /* What \\R matches */\n  uint16_t newline_convention;    /* What is a newline? */\n  uint16_t max_lookbehind;        /* Longest lookbehind (characters) */\n  uint16_t minlength;             /* Minimum length of match */\n  uint16_t top_bracket;           /* Highest numbered group */\n  uint16_t top_backref;           /* Highest numbered back reference */\n  uint16_t name_entry_size;       /* Size (code units) of table entries */\n  uint16_t name_count;            /* Number of name entries in the table */\n  uint32_t optimization_flags;    /* Optimizations enabled at compile time */\n} pcre2_real_code;\n\n/* The real match data structure. Define ovector as large as it can ever\nactually be so that array bound checkers don't grumble. Memory for this\nstructure is obtained by calling pcre2_match_data_create(), which sets the size\nas the offset of ovector plus a pair of elements for each capturable string, so\nthe size varies from call to call. As the maximum number of capturing\nsubpatterns is 65535 we must allow for 65536 strings to include the overall\nmatch. (See also the heapframe structure below.) */\n\nstruct heapframe;  /* Forward reference */\n\ntypedef struct pcre2_real_match_data {\n  pcre2_memctl     memctl;           /* Memory control fields */\n  const pcre2_real_code *code;       /* The pattern used for the match */\n  PCRE2_SPTR       subject;          /* The subject that was matched */\n  PCRE2_SPTR       mark;             /* Pointer to last mark */\n  struct heapframe *heapframes;      /* Backtracking frames heap memory */\n  PCRE2_SIZE       heapframes_size;  /* Malloc-ed size */\n  PCRE2_SIZE       subject_length;   /* Subject length */\n  PCRE2_SIZE       start_offset;     /* Offset to start of search */\n  PCRE2_SIZE       leftchar;         /* Offset to leftmost code unit */\n  PCRE2_SIZE       rightchar;        /* Offset to rightmost code unit */\n  PCRE2_SIZE       startchar;        /* Offset to starting code unit */\n  uint8_t          matchedby;        /* Type of match (normal, JIT, DFA) */\n  uint8_t          flags;            /* Various flags */\n  uint16_t         oveccount;        /* Number of pairs */\n  uint32_t         options;          /* Options passed in to the match call */\n  int              rc;               /* The return code from the match */\n  PCRE2_SIZE       ovector[131072];  /* Must be last in the structure */\n} pcre2_real_match_data;\n\n\n/* ----------------------- PRIVATE STRUCTURES ----------------------------- */\n\n/* These structures are not needed for pcre2test. */\n\n#ifndef PCRE2_PCRE2TEST\n\n/* Structures for checking for mutual function recursion when scanning compiled\nor parsed code. */\n\ntypedef struct recurse_check {\n  struct recurse_check *prev;\n  PCRE2_SPTR group;\n} recurse_check;\n\ntypedef struct parsed_recurse_check {\n  struct parsed_recurse_check *prev;\n  uint32_t *groupptr;\n} parsed_recurse_check;\n\n/* Structure for building a cache when filling in pattern recursion offsets. */\n\ntypedef struct recurse_cache {\n  PCRE2_SPTR group;\n  int groupnumber;\n} recurse_cache;\n\n/* Structure for maintaining a chain of pointers to the currently incomplete\nbranches, for testing for left recursion while compiling. */\n\ntypedef struct branch_chain {\n  struct branch_chain *outer;\n  PCRE2_UCHAR *current_branch;\n} branch_chain;\n\n/* Structure for building a list of named groups during the first pass of\ncompiling. When a duplicate name is stored in the list, its name is set to\nthe name of the first entry with the same name, and its length is set to 0. */\n\ntypedef struct named_group {\n  PCRE2_SPTR   name;          /* Points to the name in the pattern */\n  uint32_t     number;        /* Group number */\n  uint16_t     length;        /* Length of the name */\n  uint16_t     hash_dup;      /* A concatenation of a 15 bit hash code and\n                                 a singe bit which represents duplication */\n} named_group;\n\n/* Structure for storing compile time data. */\n\ntypedef struct compile_data {\n  struct compile_data *next;      /* Next compile data */\n#ifdef PCRE2_DEBUG\n  uint8_t type;                   /* Debug only type of the data */\n#endif\n} compile_data;\n\n/* Structure for caching sorted ranges. This improves the performance\nof translating META code to byte code. */\n\ntypedef struct class_ranges {\n  compile_data header;             /* Common header */\n  size_t char_lists_size;          /* Total size of encoded char lists */\n  size_t char_lists_start;         /* Start offset of encoded char lists */\n  uint16_t range_list_size;        /* Size of ranges array */\n  uint16_t char_lists_types;       /* The XCL_LIST header of char lists */\n  /* Followed by the list of ranges (start/end pairs) */\n} class_ranges;\n\n/* Structure for sorted recurse arguments. */\n\ntypedef struct recurse_arguments {\n  compile_data header;             /* Common header */\n  size_t size;                     /* Total size */\n  size_t skip_size;                /* Space consumed by arguments */\n} recurse_arguments;\n\ntypedef union class_bits_storage {\n  uint8_t classbits[32];\n  uint32_t classwords[8];\n} class_bits_storage;\n\n/* Structure for passing \"static\" information around between the functions\ndoing the compiling, so that they are thread-safe. */\n\ntypedef struct compile_block {\n  pcre2_real_compile_context *cx;  /* Points to the compile context */\n  const uint8_t *lcc;              /* Points to lower casing table */\n  const uint8_t *fcc;              /* Points to case-flipping table */\n  const uint8_t *cbits;            /* Points to character type table */\n  const uint8_t *ctypes;           /* Points to table of type maps */\n  PCRE2_UCHAR *start_workspace;    /* The start of working space */\n  PCRE2_UCHAR *start_code;         /* The start of the compiled code */\n  PCRE2_SPTR start_pattern;        /* The start of the pattern */\n  PCRE2_SPTR end_pattern;          /* The end of the pattern */\n  PCRE2_UCHAR *name_table;         /* The name/number table */\n  PCRE2_SIZE workspace_size;       /* Size of workspace */\n  PCRE2_SIZE small_ref_offset[10]; /* Offsets for \\1 to \\9 */\n  PCRE2_SIZE erroroffset;          /* Offset of error in pattern */\n  class_bits_storage classbits;    /* Temporary store for classbits */\n  uint16_t names_found;            /* Number of entries so far */\n  uint16_t name_entry_size;        /* Size of each entry */\n  uint16_t parens_depth;           /* Depth of nested parentheses */\n  uint16_t assert_depth;           /* Depth of nested assertions */\n  named_group *named_groups;       /* Points to vector in pre-compile */\n  uint32_t named_group_list_size;  /* Number of entries in the list */\n  uint32_t external_options;       /* External (initial) options */\n  uint32_t external_flags;         /* External flag bits to be set */\n  uint32_t bracount;               /* Count of capturing parentheses */\n  uint32_t lastcapture;            /* Last capture encountered */\n  uint32_t *parsed_pattern;        /* Parsed pattern buffer */\n  uint32_t *parsed_pattern_end;    /* Parsed pattern should not get here */\n  uint32_t *groupinfo;             /* Group info vector */\n  uint32_t top_backref;            /* Maximum back reference */\n  uint32_t backref_map;            /* Bitmap of low back refs */\n  uint32_t nltype;                 /* Newline type */\n  uint32_t nllen;                  /* Newline string length */\n  PCRE2_UCHAR nl[4];               /* Newline string when fixed length */\n  uint8_t class_op_used[ECLASS_NEST_LIMIT]; /* Operation used for\n                                               extended classes */\n  uint32_t req_varyopt;            /* \"After variable item\" flag for reqbyte */\n  uint32_t max_varlookbehind;      /* Limit for variable lookbehinds */\n  int  max_lookbehind;             /* Maximum lookbehind encountered (characters) */\n  BOOL had_accept;                 /* (*ACCEPT) encountered */\n  BOOL had_pruneorskip;            /* (*PRUNE) or (*SKIP) encountered */\n  BOOL had_recurse;                /* Had a pattern recursion or subroutine call */\n  BOOL dupnames;                   /* Duplicate names exist */\n  compile_data *first_data;        /* First item in the compile data list */\n  compile_data *last_data;         /* Last item in the compile data list */\n#ifdef SUPPORT_WIDE_CHARS\n  size_t char_lists_size;          /* Current size of character lists */\n#endif\n} compile_block;\n\n/* Structure for keeping the properties of the in-memory stack used\nby the JIT matcher. */\n\ntypedef struct pcre2_real_jit_stack {\n  pcre2_memctl memctl;\n  void* stack;\n} pcre2_real_jit_stack;\n\n/* Structure for items in a linked list that represents an explicit recursive\ncall within the pattern when running pcre2_dfa_match(). */\n\ntypedef struct dfa_recursion_info {\n  struct dfa_recursion_info *prevrec;\n  PCRE2_SPTR subject_position;\n  PCRE2_SPTR last_used_ptr;\n  uint32_t group_num;\n} dfa_recursion_info;\n\n/* Structure for \"stack\" frames that are used for remembering backtracking\npositions during matching. As these are used in a vector, with the ovector item\nbeing extended, the size of the structure must be a multiple of PCRE2_SIZE. The\nonly way to check this at compile time is to force an error by generating an\narray with a negative size. By putting this in a typedef (which is never used),\nwe don't generate any code when all is well. */\n\ntypedef struct heapframe {\n\n  /* The first set of fields are variables that have to be preserved over calls\n  to RRMATCH(), but which do not need to be copied to new frames. */\n\n  PCRE2_SPTR ecode;          /* The current position in the pattern */\n  PCRE2_SPTR temp_sptr[2];   /* Used for short-term PCRE2_SPTR values */\n  PCRE2_SIZE length;         /* Used for character, string, or code lengths */\n  PCRE2_SIZE back_frame;     /* Amount to subtract on RRETURN */\n  PCRE2_SIZE temp_size;      /* Used for short-term PCRE2_SIZE values */\n  uint32_t rdepth;           /* Function \"recursion\" depth within pcre2_match() */\n  uint32_t group_frame_type; /* Type information for group frames */\n  uint32_t temp_32[4];       /* Used for short-term 32-bit or BOOL values */\n  uint8_t return_id;         /* Where to go on in internal \"return\" */\n  uint8_t op;                /* Processing opcode */\n\n  /* At this point, the structure is 16-bit aligned. On most architectures\n  the alignment requirement for a pointer will ensure that the eptr field below\n  is 32-bit or 64-bit aligned. However, on m68k it is fine to have a pointer\n  that is 16-bit aligned. We must therefore ensure that what comes between here\n  and eptr is an odd multiple of 16 bits so as to get back into 32-bit\n  alignment. This happens naturally when PCRE2_UCHAR is 8 bits wide, but needs\n  fudges in the other cases. In the 32-bit case the padding comes first so that\n  the occu field itself is 32-bit aligned. Without the padding, this structure\n  is no longer a multiple of PCRE2_SIZE on m68k, and the check below fails. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  PCRE2_UCHAR occu[6];       /* Used for other case code units */\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n  PCRE2_UCHAR occu[2];       /* Used for other case code units */\n  uint8_t unused[2];         /* Ensure 32-bit alignment (see above) */\n#else\n  uint8_t unused[2];         /* Ensure 32-bit alignment (see above) */\n  PCRE2_UCHAR occu[1];       /* Used for other case code units */\n#endif\n\n  /* The rest have to be copied from the previous frame whenever a new frame\n  becomes current. The final field is specified as a large vector so that\n  runtime array bound checks don't catch references to it. However, for any\n  specific call to pcre2_match() the memory allocated for each frame structure\n  allows for exactly the right size ovector for the number of capturing\n  parentheses. (See also the comment for pcre2_real_match_data above.) */\n\n  PCRE2_SPTR eptr;              /* MUST BE FIRST */\n  PCRE2_SPTR start_match;       /* Can be adjusted by \\K */\n  PCRE2_SPTR mark;              /* Most recent mark on the success path */\n  PCRE2_SPTR recurse_last_used; /* Last character used at time of pattern recursion */\n  uint32_t current_recurse;     /* Group number of current (deepest) pattern recursion */\n  uint32_t capture_last;        /* Most recent capture */\n  PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */\n  PCRE2_SIZE offset_top;        /* Offset after highest capture */\n  PCRE2_SIZE ovector[131072];   /* Must be last in the structure */\n} heapframe;\n\n/* Assert that the size of the heapframe structure is a multiple of PCRE2_SIZE.\nSee various comments above. */\n\nSTATIC_ASSERT((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0, heapframe_size);\n\n/* Structure for computing the alignment of heapframe. */\n\ntypedef struct heapframe_align {\n  char unalign;    /* Completely unalign the current offset */\n  heapframe frame; /* Offset is its alignment */\n} heapframe_align;\n\n/* This define is the minimum alignment required for a heapframe, in bytes. */\n\n#define HEAPFRAME_ALIGNMENT offsetof(heapframe_align, frame)\n\n/* Structure for passing \"static\" information around between the functions\ndoing traditional NFA matching (pcre2_match() and friends). */\n\ntypedef struct match_block {\n  pcre2_memctl memctl;            /* For general use */\n  uint32_t heap_limit;            /* As it says */\n  uint32_t match_limit;           /* As it says */\n  uint32_t match_limit_depth;     /* As it says */\n  uint32_t match_call_count;      /* Number of times a new frame is created */\n  BOOL hitend;                    /* Hit the end of the subject at some point */\n  BOOL hasthen;                   /* Pattern contains (*THEN) */\n  BOOL hasbsk;                    /* Pattern contains \\K */\n  BOOL allowemptypartial;         /* Allow empty hard partial */\n  BOOL allowlookaroundbsk;        /* Allow \\K within lookarounds */\n  const uint8_t *lcc;             /* Points to lower casing table */\n  const uint8_t *fcc;             /* Points to case-flipping table */\n  const uint8_t *ctypes;          /* Points to table of type maps */\n  PCRE2_SIZE start_offset;        /* The start offset value */\n  PCRE2_SIZE end_offset_top;      /* Highwater mark at end of match */\n  uint16_t partial;               /* PARTIAL options */\n  uint16_t bsr_convention;        /* \\R interpretation */\n  uint16_t name_count;            /* Number of names in name table */\n  uint16_t name_entry_size;       /* Size of entry in names table */\n  PCRE2_SPTR name_table;          /* Table of group names */\n  PCRE2_SPTR start_code;          /* For use in pattern recursion */\n  PCRE2_SPTR start_subject;       /* Start of the subject string */\n  PCRE2_SPTR check_subject;       /* Where UTF-checked from */\n  PCRE2_SPTR end_subject;         /* Usable end of the subject string */\n  PCRE2_SPTR true_end_subject;    /* Actual end of the subject string */\n  PCRE2_SPTR end_match_ptr;       /* Subject position at end match */\n  PCRE2_SPTR start_used_ptr;      /* Earliest consulted character */\n  PCRE2_SPTR last_used_ptr;       /* Latest consulted character */\n  PCRE2_SPTR mark;                /* Mark pointer to pass back on success */\n  PCRE2_SPTR nomatch_mark;        /* Mark pointer to pass back on failure */\n  PCRE2_SPTR verb_ecode_ptr;      /* For passing back info */\n  PCRE2_SPTR verb_skip_ptr;       /* For passing back a (*SKIP) name */\n  uint32_t verb_current_recurse;  /* Current recursion group when (*VERB) happens */\n  uint32_t moptions;              /* Match options */\n  uint32_t poptions;              /* Pattern options */\n  uint32_t skip_arg_count;        /* For counting SKIP_ARGs */\n  uint32_t ignore_skip_arg;       /* For re-run when SKIP arg name not found */\n  uint32_t nltype;                /* Newline type */\n  uint32_t nllen;                 /* Newline string length */\n  PCRE2_UCHAR nl[4];              /* Newline string when fixed */\n  pcre2_callout_block *cb;        /* Points to a callout block */\n  void  *callout_data;            /* To pass back to callouts */\n  int (*callout)(pcre2_callout_block *,void *);  /* Callout function or NULL */\n} match_block;\n\n/* A similar structure is used for the same purpose by the DFA matching\nfunctions. */\n\ntypedef struct dfa_match_block {\n  pcre2_memctl memctl;            /* For general use */\n  PCRE2_SPTR start_code;          /* Start of the compiled pattern */\n  PCRE2_SPTR start_subject ;      /* Start of the subject string */\n  PCRE2_SPTR end_subject;         /* End of subject string */\n  PCRE2_SPTR start_used_ptr;      /* Earliest consulted character */\n  PCRE2_SPTR last_used_ptr;       /* Latest consulted character */\n  const uint8_t *tables;          /* Character tables */\n  PCRE2_SIZE start_offset;        /* The start offset value */\n  uint32_t heap_limit;            /* As it says */\n  PCRE2_SIZE heap_used;           /* As it says */\n  uint32_t match_limit;           /* As it says */\n  uint32_t match_limit_depth;     /* As it says */\n  uint32_t match_call_count;      /* Number of calls of internal function */\n  uint32_t moptions;              /* Match options */\n  uint32_t poptions;              /* Pattern options */\n  uint32_t nltype;                /* Newline type */\n  uint32_t nllen;                 /* Newline string length */\n  BOOL allowemptypartial;         /* Allow empty hard partial */\n  PCRE2_UCHAR nl[4];              /* Newline string when fixed */\n  uint16_t bsr_convention;        /* \\R interpretation */\n  pcre2_callout_block *cb;        /* Points to a callout block */\n  void *callout_data;             /* To pass back to callouts */\n  int (*callout)(pcre2_callout_block *,void *);  /* Callout function or NULL */\n  dfa_recursion_info *recursive;  /* Linked list of pattern recursion data */\n} dfa_match_block;\n\n#endif  /* PCRE2_PCRE2TEST */\n\n#endif /* PCRE2_INTMODEDEP_CAN_DEFINE */\n\n/* End of pcre2_intmodedep.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_jit_char_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n                    This module by Zoltan Herczeg\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n/* XClass matching code. */\n\n#ifdef SUPPORT_WIDE_CHARS\n\n#define ECLASS_CHAR_DATA STACK_TOP\n#define ECLASS_STACK_DATA STACK_LIMIT\n\n#define SET_CHAR_OFFSET(value) \\\n  if ((value) != charoffset) \\\n    { \\\n    if ((value) < charoffset) \\\n      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \\\n    else \\\n      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \\\n    } \\\n  charoffset = (value);\n\n#define READ_FROM_CHAR_LIST(destination) \\\n  if (list_ind <= 1) \\\n    { \\\n    destination = *(const uint16_t*)next_char; \\\n    next_char += 2; \\\n    } \\\n  else \\\n    { \\\n    destination = *(const uint32_t*)next_char; \\\n    next_char += 4; \\\n    }\n\n#define XCLASS_LOCAL_RANGES_SIZE 32\n#define XCLASS_LOCAL_RANGES_LOG2_SIZE 5\n\ntypedef struct xclass_stack_item {\n  sljit_u32 first_item;\n  sljit_u32 last_item;\n  struct sljit_jump *jump;\n} xclass_stack_item;\n\ntypedef struct xclass_ranges {\n  size_t range_count;\n  /* Pointer to ranges. A stack area is provided when a small buffer is enough. */\n  uint32_t *ranges;\n  uint32_t local_ranges[XCLASS_LOCAL_RANGES_SIZE * 2];\n  /* Stack size must be log2(ranges / 2). */\n  xclass_stack_item *stack;\n  xclass_stack_item local_stack[XCLASS_LOCAL_RANGES_LOG2_SIZE];\n} xclass_ranges;\n\nstatic void xclass_compute_ranges(compiler_common *common, PCRE2_SPTR cc, xclass_ranges *ranges)\n{\nDEFINE_COMPILER;\nsize_t range_count = 0, est_range_count;\nsize_t est_stack_size, tmp;\nuint32_t type, list_ind;\nuint32_t est_type;\nuint32_t char_list_add, range_start, range_end;\nconst uint8_t *next_char;\nconst uint8_t *est_next_char;\n#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\nBOOL utf = common->utf;\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */\n\nif (*cc == XCL_SINGLE || *cc == XCL_RANGE)\n  {\n  /* Only a few ranges are present. */\n  do\n    {\n    type = *cc++;\n    SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE);\n    GETCHARINCTEST(range_end, cc);\n    ranges->ranges[range_count] = range_end;\n\n    if (type == XCL_RANGE)\n      {\n      GETCHARINCTEST(range_end, cc);\n      }\n\n    ranges->ranges[range_count + 1] = range_end;\n    range_count += 2;\n    }\n  while (*cc != XCL_END);\n\n  SLJIT_ASSERT(range_count <= XCLASS_LOCAL_RANGES_SIZE);\n  ranges->range_count = range_count;\n  return;\n  }\n\nSLJIT_ASSERT(cc[0] >= XCL_LIST);\n#if PCRE2_CODE_UNIT_WIDTH == 8\ntype = (uint32_t)(cc[0] << 8) | cc[1];\ncc += 2;\n#else\ntype = cc[0];\ncc++;\n#endif  /* CODE_UNIT_WIDTH */\n\n/* Align characters. */\nnext_char = (const uint8_t*)common->start - (GET(cc, 0) << 1);\ntype &= XCL_TYPE_MASK;\n\n/* Estimate size. */\nest_next_char = next_char;\nest_type = type;\nest_range_count = 0;\nlist_ind = 0;\n\nwhile (est_type > 0)\n  {\n  uint32_t item_count = est_type & XCL_ITEM_COUNT_MASK;\n\n  if (item_count == XCL_ITEM_COUNT_MASK)\n    {\n    if (list_ind <= 1)\n      {\n      item_count = *(const uint16_t*)est_next_char;\n      est_next_char += 2;\n      }\n    else\n      {\n      item_count = *(const uint32_t*)est_next_char;\n      est_next_char += 4;\n      }\n    }\n\n  est_type >>= XCL_TYPE_BIT_LEN;\n  est_next_char += (size_t)item_count << (list_ind <= 1 ? 1 : 2);\n  list_ind++;\n  est_range_count += item_count + 1;\n  }\n\nif (est_range_count > XCLASS_LOCAL_RANGES_SIZE)\n  {\n  est_stack_size = 0;\n  tmp = est_range_count - 1;\n\n  /* Compute log2(est_range_count) */\n  while (tmp > 0)\n    {\n    est_stack_size++;\n    tmp >>= 1;\n    }\n\n  ranges->stack = (xclass_stack_item*)SLJIT_MALLOC((sizeof(xclass_stack_item) * est_stack_size)\n    + ((sizeof(uint32_t) << 1) * (size_t)est_range_count), compiler->allocator_data);\n\n  if (ranges->stack == NULL)\n    {\n    sljit_set_compiler_memory_error(compiler);\n    ranges->ranges = NULL;\n    return;\n    }\n\n  ranges->ranges = (uint32_t*)(ranges->stack + est_stack_size);\n  }\n\nchar_list_add = XCL_CHAR_LIST_LOW_16_ADD;\nrange_start = ~(uint32_t)0;\nlist_ind = 0;\n\nif ((type & XCL_BEGIN_WITH_RANGE) != 0)\n  range_start = XCL_CHAR_LIST_LOW_16_START;\n\nwhile (type > 0)\n  {\n  uint32_t item_count = type & XCL_ITEM_COUNT_MASK;\n\n  if (item_count == XCL_ITEM_COUNT_MASK)\n    {\n    READ_FROM_CHAR_LIST(item_count);\n    SLJIT_ASSERT(item_count >= XCL_ITEM_COUNT_MASK);\n    }\n\n  while (item_count > 0)\n    {\n    READ_FROM_CHAR_LIST(range_end);\n\n    if ((range_end & XCL_CHAR_END) != 0)\n      {\n      range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n      if (range_start == ~(uint32_t)0)\n        range_start = range_end;\n\n      ranges->ranges[range_count] = range_start;\n      ranges->ranges[range_count + 1] = range_end;\n      range_count += 2;\n      range_start = ~(uint32_t)0;\n      }\n    else\n      range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n    item_count--;\n    }\n\n  list_ind++;\n  type >>= XCL_TYPE_BIT_LEN;\n\n  if (range_start == ~(uint32_t)0)\n    {\n    if ((type & XCL_BEGIN_WITH_RANGE) != 0)\n      {\n      if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n      else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START;\n      else range_start = XCL_CHAR_LIST_HIGH_32_START;\n#else\n      else range_start = XCL_CHAR_LIST_LOW_32_START;\n#endif\n      }\n    }\n  else if ((type & XCL_BEGIN_WITH_RANGE) == 0)\n    {\n    if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END;\n    else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n    else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END;\n    else range_end = XCL_CHAR_LIST_HIGH_32_END;\n#else\n    else range_end = XCL_CHAR_LIST_LOW_32_END;\n#endif\n\n    ranges->ranges[range_count] = range_start;\n    ranges->ranges[range_count + 1] = range_end;\n    range_count += 2;\n    range_start = ~(uint32_t)0;\n    }\n\n  if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n  else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD;\n#else\n  else char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n#endif\n  }\n\nSLJIT_ASSERT(range_count > 0 && range_count <= (est_range_count << 1));\nSLJIT_ASSERT(next_char <= (const uint8_t*)common->start);\nranges->range_count = range_count;\n}\n\nstatic void xclass_check_bitset(compiler_common *common, const sljit_u8 *bitset, jump_list **found, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\njump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\nif (!optimize_class(common, bitset, (bitset[31] & 0x80) != 0, TRUE, found))\n  {\n  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);\n  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)bitset);\n  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);\n  add_jump(compiler, found, JUMP(SLJIT_NOT_ZERO));\n  }\n\nadd_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\nJUMPHERE(jump);\n}\n\n#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\n\nstatic void xclass_update_min_max(compiler_common *common, PCRE2_SPTR cc, sljit_u32 *min_ptr, sljit_u32 *max_ptr)\n{\nuint32_t type, list_ind, c;\nsljit_u32 min = *min_ptr;\nsljit_u32 max = *max_ptr;\nuint32_t char_list_add;\nconst uint8_t *next_char;\nBOOL utf = TRUE;\n\n/* This function is pointless without utf 8/16. */\nSLJIT_ASSERT(common->utf);\nif (*cc == XCL_SINGLE || *cc == XCL_RANGE)\n  {\n  /* Only a few ranges are present. */\n  do\n    {\n    type = *cc++;\n    SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE);\n    GETCHARINCTEST(c, cc);\n\n    if (c < min)\n      min = c;\n\n    if (type == XCL_RANGE)\n      {\n      GETCHARINCTEST(c, cc);\n      }\n\n    if (c > max)\n      max = c;\n    }\n  while (*cc != XCL_END);\n\n  SLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max);\n  *min_ptr = min;\n  *max_ptr = max;\n  return;\n  }\n\nSLJIT_ASSERT(cc[0] >= XCL_LIST);\n#if PCRE2_CODE_UNIT_WIDTH == 8\ntype = (uint32_t)(cc[0] << 8) | cc[1];\ncc += 2;\n#else\ntype = cc[0];\ncc++;\n#endif  /* CODE_UNIT_WIDTH */\n\n/* Align characters. */\nnext_char = (const uint8_t*)common->start - (GET(cc, 0) << 1);\ntype &= XCL_TYPE_MASK;\n\nSLJIT_ASSERT(type != 0);\n\n/* Detect minimum. */\n\n/* Skip unused ranges. */\nlist_ind = 0;\nwhile ((type & (XCL_BEGIN_WITH_RANGE | XCL_ITEM_COUNT_MASK)) == 0)\n  {\n  type >>= XCL_TYPE_BIT_LEN;\n  list_ind++;\n  }\n\nSLJIT_ASSERT(list_ind <= 2);\nswitch (list_ind)\n  {\n  case 0:\n  char_list_add = XCL_CHAR_LIST_LOW_16_ADD;\n  c = XCL_CHAR_LIST_LOW_16_START;\n  break;\n\n  case 1:\n  char_list_add = XCL_CHAR_LIST_HIGH_16_ADD;\n  c = XCL_CHAR_LIST_HIGH_16_START;\n  break;\n\n  default:\n  char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n  c = XCL_CHAR_LIST_LOW_32_START;\n  break;\n  }\n\nif ((type & XCL_BEGIN_WITH_RANGE) != 0)\n  {\n  if (c < min)\n    min = c;\n  }\nelse\n  {\n  if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK)\n    {\n    if (list_ind <= 1)\n      c = *(const uint16_t*)(next_char + 2);\n    else\n      c = *(const uint32_t*)(next_char + 4);\n    }\n  else\n    {\n    if (list_ind <= 1)\n      c = *(const uint16_t*)next_char;\n    else\n      c = *(const uint32_t*)next_char;\n    }\n\n  c = char_list_add + (c >> XCL_CHAR_SHIFT);\n  if (c < min)\n    min = c;\n  }\n\n/* Detect maximum. */\n\n/* Skip intermediate ranges. */\nwhile (TRUE)\n  {\n  if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK)\n    {\n    if (list_ind <= 1)\n      {\n      c = *(const uint16_t*)next_char;\n      next_char += (c + 1) << 1;\n      }\n    else\n      {\n      c = *(const uint32_t*)next_char;\n      next_char += (c + 1) << 2;\n      }\n    }\n  else\n    next_char += (type & XCL_ITEM_COUNT_MASK) << (list_ind <= 1 ? 1 : 2);\n\n  if ((type >> XCL_TYPE_BIT_LEN) == 0)\n    break;\n\n  list_ind++;\n  type >>= XCL_TYPE_BIT_LEN;\n  }\n\nSLJIT_ASSERT(list_ind <= 2 && type != 0);\nswitch (list_ind)\n  {\n  case 0:\n  char_list_add = XCL_CHAR_LIST_LOW_16_ADD;\n  c = XCL_CHAR_LIST_LOW_16_END;\n  break;\n\n  case 1:\n  char_list_add = XCL_CHAR_LIST_HIGH_16_ADD;\n  c = XCL_CHAR_LIST_HIGH_16_END;\n  break;\n\n  default:\n  char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n  c = XCL_CHAR_LIST_LOW_32_END;\n  break;\n  }\n\nif ((type & XCL_ITEM_COUNT_MASK) != 0)\n  {\n  /* Type is reused as temporary. */\n  if (list_ind <= 1)\n    type = *(const uint16_t*)(next_char - 2);\n  else\n    type = *(const uint32_t*)(next_char - 4);\n\n  if (type & XCL_CHAR_END)\n    c = char_list_add + (type >> XCL_CHAR_SHIFT);\n  }\n\nif (c > max)\n  max = c;\n\nSLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max);\n*min_ptr = min;\n*max_ptr = max;\n}\n\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */\n\n#define XCLASS_IS_ECLASS 0x001\n#ifdef SUPPORT_UNICODE\n#define XCLASS_SAVE_CHAR 0x002\n#define XCLASS_HAS_TYPE 0x004\n#define XCLASS_HAS_SCRIPT 0x008\n#define XCLASS_HAS_SCRIPT_EXTENSION 0x010\n#define XCLASS_HAS_BOOL 0x020\n#define XCLASS_HAS_BIDICL 0x040\n#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL)\n#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080\n#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100\n#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0 0x200\n#endif /* SUPPORT_UNICODE */\n\nstatic PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr);\n\n/* TMP3 must be preserved because it is used by compile_iterator_matchingpath. */\nstatic void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, sljit_u32 status)\n{\nDEFINE_COMPILER;\njump_list *found = NULL;\njump_list *check_result = NULL;\njump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;\nsljit_uw c, charoffset;\nsljit_u32 max = READ_CHAR_MAX, min = 0;\nstruct sljit_jump *jump = NULL;\nPCRE2_UCHAR flags;\nPCRE2_SPTR ccbegin;\nsljit_u32 compares, invertcmp, depth;\nsljit_u32 first_item, last_item, mid_item;\nsljit_u32 range_start, range_end;\nxclass_ranges ranges;\nBOOL has_cmov, last_range_set;\n\n#ifdef SUPPORT_UNICODE\nsljit_u32 category_list = 0;\nsljit_u32 items;\nint typereg = TMP1;\n#else\n(void)c; /* Avoid compiler warning. */\n#endif /* SUPPORT_UNICODE */\n\nSLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw));\n/* Scanning the necessary info. */\nflags = *cc++;\nccbegin = cc;\ncompares = 0;\n\nif (flags & XCL_MAP)\n  cc += 32 / sizeof(PCRE2_UCHAR);\n\n#ifdef SUPPORT_UNICODE\nwhile (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n  {\n  compares++;\n  cc++;\n\n  items = 0;\n\n  switch(*cc)\n    {\n    case PT_LAMP:\n    items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt);\n    break;\n\n    case PT_GC:\n    items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]);\n    break;\n\n    case PT_PC:\n    items = UCPCAT(cc[1]);\n    break;\n\n    case PT_WORD:\n    items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N;\n    break;\n\n    case PT_ALNUM:\n    items = UCPCAT_L | UCPCAT_N;\n    break;\n\n    case PT_SCX:\n    status |= XCLASS_HAS_SCRIPT_EXTENSION;\n    if (cc[-1] == XCL_NOTPROP)\n      {\n      status |= XCLASS_SCRIPT_EXTENSION_NOTPROP;\n      break;\n      }\n    compares++;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case PT_SC:\n    status |= XCLASS_HAS_SCRIPT;\n    break;\n\n    case PT_SPACE:\n    case PT_PXSPACE:\n    case PT_PXGRAPH:\n    case PT_PXPRINT:\n    case PT_PXPUNCT:\n    status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE;\n    break;\n\n    case PT_UCNC:\n    case PT_PXXDIGIT:\n    status |= XCLASS_SAVE_CHAR;\n    break;\n\n    case PT_BOOL:\n    status |= XCLASS_HAS_BOOL;\n    break;\n\n    case PT_BIDICL:\n    status |= XCLASS_HAS_BIDICL;\n    break;\n\n    default:\n    SLJIT_UNREACHABLE();\n    break;\n    }\n\n  if (items > 0)\n    {\n    if (cc[-1] == XCL_NOTPROP)\n      items ^= UCPCAT_ALL;\n    category_list |= items;\n    status |= XCLASS_HAS_TYPE;\n    compares--;\n    }\n\n  cc += 2;\n  }\n\nif (category_list == UCPCAT_ALL)\n  {\n  /* All or no characters are accepted, same as dotall. */\n  if (status & XCLASS_IS_ECLASS)\n    {\n    if (list != backtracks)\n      OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    return;\n    }\n\n  compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);\n  if (list == backtracks)\n    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n  return;\n  }\n\nif (category_list != 0)\n  compares++;\n#endif\n\nif (*cc != XCL_END)\n  {\n#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\n  if (common->utf && compares == 0 && !(status & XCLASS_IS_ECLASS))\n    {\n    SLJIT_ASSERT(category_list == 0);\n    max = 0;\n    min = (flags & XCL_MAP) != 0 ? 0 : READ_CHAR_MAX;\n    xclass_update_min_max(common, cc, &min, &max);\n    }\n#endif\n  compares++;\n#ifdef SUPPORT_UNICODE\n  status |= XCLASS_SAVE_CHAR;\n#endif /* SUPPORT_UNICODE */\n  }\n\n#ifdef SUPPORT_UNICODE\nSLJIT_ASSERT(compares > 0 || category_list != 0);\n#else /* !SUPPORT_UNICODE */\nSLJIT_ASSERT(compares > 0);\n#endif /* SUPPORT_UNICODE */\n\n/* We are not necessary in utf mode even in 8 bit mode. */\ncc = ccbegin;\nif (!(status & XCLASS_IS_ECLASS))\n  {\n  if ((flags & XCL_NOT) != 0)\n    read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  else\n    {\n#ifdef SUPPORT_UNICODE\n    read_char(common, min, max, (status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0);\n#else /* !SUPPORT_UNICODE */\n    read_char(common, min, max, NULL, 0);\n#endif /* SUPPORT_UNICODE */\n    }\n  }\n\nif ((flags & XCL_MAP) != 0)\n  {\n  SLJIT_ASSERT(!(status & XCLASS_IS_ECLASS));\n  xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks);\n  cc += 32 / sizeof(PCRE2_UCHAR);\n  }\n\n#ifdef SUPPORT_UNICODE\nif (status & XCLASS_NEEDS_UCD)\n  {\n  if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR)\n    OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  if (!common->utf)\n    {\n    OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);\n    SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, UNASSIGNED_UTF_CHAR, TMP1);\n    }\n#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\n  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);\n  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);\n  OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));\n  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);\n  sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));\n  OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);\n  sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP2, 0, TMP2, 0, TMP2, 0, 1);\n  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);\n\n  ccbegin = cc;\n\n  if (status & XCLASS_HAS_BIDICL)\n    {\n    OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass));\n    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT);\n\n    while (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n      {\n      cc++;\n\n      if (*cc == PT_BIDICL)\n        {\n        compares--;\n        invertcmp = (compares == 0 && list != backtracks);\n        if (cc[-1] == XCL_NOTPROP)\n          invertcmp ^= 0x1;\n        jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);\n        add_jump(compiler, compares > 0 ? list : backtracks, jump);\n        }\n      cc += 2;\n      }\n\n    cc = ccbegin;\n    }\n\n  if (status & XCLASS_HAS_BOOL)\n    {\n    OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops));\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);\n\n    while (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n      {\n      cc++;\n      if (*cc == PT_BOOL)\n        {\n        compares--;\n        invertcmp = (compares == 0 && list != backtracks);\n        if (cc[-1] == XCL_NOTPROP)\n          invertcmp ^= 0x1;\n\n        OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f)));\n        add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));\n        }\n      cc += 2;\n      }\n\n    cc = ccbegin;\n    }\n\n  if (status & XCLASS_HAS_SCRIPT)\n    {\n    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));\n\n    while (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n      {\n      cc++;\n\n      switch (*cc)\n        {\n        case PT_SCX:\n        if (cc[-1] == XCL_NOTPROP)\n          break;\n        PCRE2_FALLTHROUGH /* Fall through */\n\n        case PT_SC:\n        compares--;\n        invertcmp = (compares == 0 && list != backtracks);\n        if (cc[-1] == XCL_NOTPROP)\n          invertcmp ^= 0x1;\n\n        add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]));\n        }\n      cc += 2;\n      }\n\n    cc = ccbegin;\n    }\n\n  if (status & XCLASS_HAS_SCRIPT_EXTENSION)\n    {\n    OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass));\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);\n\n    if (status & XCLASS_SCRIPT_EXTENSION_NOTPROP)\n      {\n      if (status & XCLASS_HAS_TYPE)\n        {\n        if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR)\n          {\n          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP2, 0);\n          status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0;\n          }\n        else\n          {\n          OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0);\n          status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR;\n          }\n        }\n      OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));\n      }\n\n    while (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n      {\n      cc++;\n\n      if (*cc == PT_SCX)\n        {\n        compares--;\n        invertcmp = (compares == 0 && list != backtracks);\n\n        jump = NULL;\n        if (cc[-1] == XCL_NOTPROP)\n          {\n          jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]);\n          if (invertcmp)\n            {\n            add_jump(compiler, backtracks, jump);\n            jump = NULL;\n            }\n          invertcmp ^= 0x1;\n          }\n\n        OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f)));\n        add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));\n\n        if (jump != NULL)\n          JUMPHERE(jump);\n        }\n      cc += 2;\n      }\n\n    if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0)\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n    else if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR)\n      OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0);\n    cc = ccbegin;\n    }\n\n  if (status & XCLASS_SAVE_CHAR)\n    OP1(SLJIT_MOV, TMP1, 0, (status & XCLASS_IS_ECLASS) ? ECLASS_CHAR_DATA : RETURN_ADDR, 0);\n\n  if (status & XCLASS_HAS_TYPE)\n    {\n    if (status & XCLASS_SAVE_CHAR)\n      typereg = RETURN_ADDR;\n\n    OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));\n    OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0);\n\n    if (category_list > 0)\n      {\n      compares--;\n      invertcmp = (compares == 0 && list != backtracks);\n      OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list);\n      add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));\n      }\n    }\n  }\n#endif /* SUPPORT_UNICODE */\n\n/* Generating code. */\ncharoffset = 0;\n\n#ifdef SUPPORT_UNICODE\nwhile (*cc == XCL_PROP || *cc == XCL_NOTPROP)\n  {\n  compares--;\n  invertcmp = (compares == 0 && list != backtracks);\n  jump = NULL;\n\n  if (*cc == XCL_NOTPROP)\n    invertcmp ^= 0x1;\n  cc++;\n  switch(*cc)\n    {\n    case PT_LAMP:\n    case PT_GC:\n    case PT_PC:\n    case PT_SC:\n    case PT_SCX:\n    case PT_BOOL:\n    case PT_BIDICL:\n    case PT_WORD:\n    case PT_ALNUM:\n    compares++;\n    /* Already handled. */\n    break;\n\n    case PT_SPACE:\n    case PT_PXSPACE:\n    SET_CHAR_OFFSET(9);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9);\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs));\n    OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO);\n    jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);\n    break;\n\n    case PT_UCNC:\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    SET_CHAR_OFFSET(0xa0);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n    SET_CHAR_OFFSET(0);\n    OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0);\n    OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL);\n    jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);\n    break;\n\n    case PT_PXGRAPH:\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs));\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);\n\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf));\n    jump = JUMP(SLJIT_ZERO);\n\n    c = charoffset;\n    /* In case of ucp_Cf, we overwrite the result. */\n    SET_CHAR_OFFSET(0x2066);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    /* Restore charoffset. */\n    SET_CHAR_OFFSET(c);\n\n    JUMPHERE(jump);\n    jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);\n    break;\n\n    case PT_PXPRINT:\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp));\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);\n\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf));\n    jump = JUMP(SLJIT_ZERO);\n\n    c = charoffset;\n    /* In case of ucp_Cf, we overwrite the result. */\n    SET_CHAR_OFFSET(0x2066);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n\n    /* Restore charoffset. */\n    SET_CHAR_OFFSET(c);\n\n    JUMPHERE(jump);\n    jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);\n    break;\n\n    case PT_PXPUNCT:\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So));\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);\n\n    SET_CHAR_OFFSET(0);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f);\n    OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps));\n    OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO);\n    jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);\n    break;\n\n    case PT_PXXDIGIT:\n    SET_CHAR_OFFSET(CHAR_A);\n    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A);\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    SET_CHAR_OFFSET(CHAR_0);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    SET_CHAR_OFFSET(0xff10);\n    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10);\n\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    SET_CHAR_OFFSET(0xff21);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    SET_CHAR_OFFSET(0xff41);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41);\n    OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n\n    SET_CHAR_OFFSET(0xff10);\n\n    JUMPHERE(jump);\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0);\n    jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);\n    break;\n\n    default:\n    SLJIT_UNREACHABLE();\n    break;\n    }\n\n  cc += 2;\n\n  if (jump != NULL)\n    add_jump(compiler, compares > 0 ? list : backtracks, jump);\n  }\n\nif (compares == 0)\n  {\n  if (found != NULL)\n    set_jumps(found, LABEL());\n\n  if (status & XCLASS_IS_ECLASS)\n    OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n  return;\n  }\n#endif /* SUPPORT_UNICODE */\n\nSLJIT_ASSERT(compares == 1);\nranges.range_count = 0;\nranges.ranges = ranges.local_ranges;\nranges.stack = ranges.local_stack;\n\nxclass_compute_ranges(common, cc, &ranges);\n\n/* Memory error is set for the compiler. */\nif (ranges.stack == NULL)\n  return;\n\n#if (defined SLJIT_DEBUG && SLJIT_DEBUG) && \\\n  defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\nif (common->utf)\n  {\n  min = READ_CHAR_MAX;\n  max = 0;\n  xclass_update_min_max(common, cc, &min, &max);\n  SLJIT_ASSERT(ranges.ranges[0] == min && ranges.ranges[ranges.range_count - 1] == max);\n  }\n#endif /* SLJIT_DEBUG && SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */\n\ninvertcmp = (list != backtracks);\n\nif (ranges.range_count == 2)\n  {\n  range_start = ranges.ranges[0];\n  range_end = ranges.ranges[1];\n\n  if (range_start < range_end)\n    {\n    SET_CHAR_OFFSET(range_start);\n    jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start));\n    }\n  else\n    jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset));\n\n  add_jump(compiler, backtracks, jump);\n\n  SLJIT_ASSERT(ranges.stack == ranges.local_stack);\n  if (found != NULL)\n    set_jumps(found, LABEL());\n\n  if (status & XCLASS_IS_ECLASS)\n    OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n  return;\n  }\n\nrange_start = ranges.ranges[0];\nSET_CHAR_OFFSET(range_start);\nif (ranges.range_count >= 6)\n  {\n  /* Early fail. */\n  range_end = ranges.ranges[ranges.range_count - 1];\n  add_jump(compiler, (flags & XCL_NOT) == 0 ? backtracks : &found,\n    CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)));\n  }\n\ndepth = 0;\nfirst_item = 0;\nlast_item = (sljit_u32)(ranges.range_count - 2);\nhas_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0;\n\nwhile (TRUE)\n  {\n  /* At least two items are present. */\n  SLJIT_ASSERT(first_item < last_item && charoffset == ranges.ranges[0]);\n  last_range_set = FALSE;\n\n  if (first_item + 6 <= last_item)\n    {\n    mid_item = ((first_item + last_item) >> 1) & ~(sljit_u32)1;\n    SLJIT_ASSERT(last_item >= mid_item + 4);\n\n    range_end = ranges.ranges[mid_item + 1];\n    if (first_item + 6 > mid_item && ranges.ranges[mid_item] == range_end)\n      {\n      OP2U(SLJIT_SUB | SLJIT_SET_GREATER | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset));\n      ranges.stack[depth].jump = JUMP(SLJIT_GREATER);\n      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n      last_range_set = TRUE;\n      }\n    else\n      ranges.stack[depth].jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset));\n\n    ranges.stack[depth].first_item = (sljit_u32)(mid_item + 2);\n    ranges.stack[depth].last_item = (sljit_u32)last_item;\n\n    depth++;\n    SLJIT_ASSERT(ranges.stack == ranges.local_stack ?\n      depth <= XCLASS_LOCAL_RANGES_LOG2_SIZE : (ranges.stack + depth) <= (xclass_stack_item*)ranges.ranges);\n\n    last_item = mid_item;\n    if (!last_range_set)\n      continue;\n\n    last_item -= 2;\n    }\n\n  if (!last_range_set)\n    {\n    range_start = ranges.ranges[first_item];\n    range_end = ranges.ranges[first_item + 1];\n\n    if (range_start < range_end)\n      {\n      SET_CHAR_OFFSET(range_start);\n      OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start));\n      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\n      }\n    else\n      {\n      OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset));\n      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n      }\n    first_item += 2;\n    }\n\n  SLJIT_ASSERT(first_item <= last_item);\n\n  do\n    {\n    range_start = ranges.ranges[first_item];\n    range_end = ranges.ranges[first_item + 1];\n\n    if (range_start < range_end)\n      {\n      SET_CHAR_OFFSET(range_start);\n      OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start));\n\n      if (has_cmov)\n        SELECT(SLJIT_LESS_EQUAL, TMP2, STR_END, 0, TMP2);\n      else\n        OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_LESS_EQUAL);\n      }\n    else\n      {\n      OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset));\n\n      if (has_cmov)\n        SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2);\n      else\n        OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);\n      }\n\n    first_item += 2;\n    }\n  while (first_item <= last_item);\n\n  if (depth == 0) break;\n\n  add_jump(compiler, &check_result, JUMP(SLJIT_JUMP));\n\n  /* The charoffset resets after the end of a branch is reached. */\n  charoffset = ranges.ranges[0];\n  depth--;\n  first_item = ranges.stack[depth].first_item;\n  last_item = ranges.stack[depth].last_item;\n  JUMPHERE(ranges.stack[depth].jump);\n  }\n\nif (check_result != NULL)\n  set_jumps(check_result, LABEL());\n\nif (has_cmov)\n  jump = CMP(SLJIT_NOT_EQUAL ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);\nelse\n  {\n  sljit_set_current_flags(compiler, SLJIT_SET_Z);\n  jump = JUMP(SLJIT_NOT_EQUAL ^ invertcmp);\n  }\n\nadd_jump(compiler, backtracks, jump);\n\nif (found != NULL)\n  set_jumps(found, LABEL());\n\nif (status & XCLASS_IS_ECLASS)\n  OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n\nif (ranges.stack != ranges.local_stack)\n  SLJIT_FREE(ranges.stack, compiler->allocator_data);\n}\n\nstatic PCRE2_SPTR compile_eclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nPCRE2_SPTR end = cc + GET(cc, 0) - 1;\nPCRE2_SPTR begin;\njump_list *not_found;\njump_list *found = NULL;\n\ncc += LINK_SIZE;\n\n/* Should be optimized later. */\nread_char(common, 0, READ_CHAR_MAX, backtracks, 0);\n\nif (((*cc++) & ECL_MAP) != 0)\n  {\n  xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks);\n  cc += 32 / sizeof(PCRE2_UCHAR);\n  }\n\nbegin = cc;\n\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, ECLASS_CHAR_DATA, 0);\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, ECLASS_STACK_DATA, 0);\nOP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0);\nOP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, TMP1, 0);\n\n/* All eclass must start with an xclass. */\nSLJIT_ASSERT(*cc == ECL_XCLASS);\n\nwhile (cc < end)\n  {\n  switch (*cc)\n    {\n    case ECL_AND:\n    ++cc;\n    OP2(SLJIT_OR, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, ~(sljit_sw)1);\n    OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_AND, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0);\n    break;\n\n    case ECL_OR:\n    ++cc;\n    OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0);\n    break;\n\n    case ECL_XOR:\n    ++cc;\n    OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0);\n    break;\n\n    case ECL_NOT:\n    ++cc;\n    OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n    break;\n\n    default:\n    SLJIT_ASSERT(*cc == ECL_XCLASS);\n    if (cc != begin)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, ECLASS_CHAR_DATA, 0);\n      OP2(SLJIT_SHL, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1);\n      }\n\n    not_found = NULL;\n    compile_xclass_matchingpath(common, cc + 1 + LINK_SIZE, &not_found, XCLASS_IS_ECLASS);\n    set_jumps(not_found, LABEL());\n\n    cc += GET(cc, 1);\n    break;\n    }\n  }\n\nOP2U(SLJIT_SUB | SLJIT_SET_Z, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0);\nOP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nOP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\nadd_jump(compiler, backtracks, JUMP(SLJIT_EQUAL));\nset_jumps(found, LABEL());\nreturn end;\n}\n\n/* Generic character matching code. */\n\n#undef SET_CHAR_OFFSET\n#undef READ_FROM_CHAR_LIST\n#undef XCLASS_LOCAL_RANGES_SIZE\n#undef XCLASS_LOCAL_RANGES_LOG2_SIZE\n\n#endif /* SUPPORT_WIDE_CHARS */\n\nstatic PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,\n    compare_context *context, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nunsigned int othercasebit = 0;\nPCRE2_SPTR othercasechar = NULL;\n#ifdef SUPPORT_UNICODE\nint utflength;\n#endif\n\nif (caseless && char_has_othercase(common, cc))\n  {\n  othercasebit = char_get_othercase_bit(common, cc);\n  SLJIT_ASSERT(othercasebit);\n  /* Extracting bit difference info. */\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  othercasechar = cc + (othercasebit >> 8);\n  othercasebit &= 0xff;\n#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  /* Note that this code only handles characters in the BMP. If there\n  ever are characters outside the BMP whose othercase differs in only one\n  bit from itself (there currently are none), this code will need to be\n  revised for PCRE2_CODE_UNIT_WIDTH == 32. */\n  othercasechar = cc + (othercasebit >> 9);\n  if ((othercasebit & 0x100) != 0)\n    othercasebit = (othercasebit & 0xff) << 8;\n  else\n    othercasebit &= 0xff;\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n  }\n\nif (context->sourcereg == -1)\n  {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED\n  if (context->length >= 4)\n    OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n  else if (context->length >= 2)\n    OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n  else\n#endif\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED\n  if (context->length >= 4)\n    OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n  else\n#endif\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n  context->sourcereg = TMP2;\n  }\n\n#ifdef SUPPORT_UNICODE\nutflength = 1;\nif (common->utf && HAS_EXTRALEN(*cc))\n  utflength += GET_EXTRALEN(*cc);\n\ndo\n  {\n#endif\n\n  context->length -= IN_UCHARS(1);\n#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\n\n  /* Unaligned read is supported. */\n  if (othercasebit != 0 && othercasechar == cc)\n    {\n    context->c.asuchars[context->ucharptr] = *cc | othercasebit;\n    context->oc.asuchars[context->ucharptr] = othercasebit;\n    }\n  else\n    {\n    context->c.asuchars[context->ucharptr] = *cc;\n    context->oc.asuchars[context->ucharptr] = 0;\n    }\n  context->ucharptr++;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))\n#else\n  if (context->ucharptr >= 2 || context->length == 0)\n#endif\n    {\n    if (context->length >= 4)\n      OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);\n    else if (context->length >= 2)\n      OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    else if (context->length >= 1)\n      OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;\n\n    switch(context->ucharptr)\n      {\n      case 4 / sizeof(PCRE2_UCHAR):\n      if (context->oc.asint != 0)\n        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));\n      break;\n\n      case 2 / sizeof(PCRE2_UCHAR):\n      if (context->oc.asushort != 0)\n        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));\n      break;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      case 1:\n      if (context->oc.asbyte != 0)\n        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));\n      break;\n#endif\n\n      default:\n      SLJIT_UNREACHABLE();\n      break;\n      }\n    context->ucharptr = 0;\n    }\n\n#else\n\n  /* Unaligned read is unsupported or in 32 bit mode. */\n  if (context->length >= 1)\n    OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);\n\n  context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;\n\n  if (othercasebit != 0 && othercasechar == cc)\n    {\n    OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));\n    }\n  else\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));\n\n#endif\n\n  cc++;\n#ifdef SUPPORT_UNICODE\n  utflength--;\n  }\nwhile (utflength > 0);\n#endif\n\nreturn cc;\n}\n\n#ifdef SUPPORT_UNICODE\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n\n/* The code in this function copies the logic of the interpreter function that\nis defined in the pcre2_extuni.c source. If that code is updated, this\nfunction, and those below it, must be kept in step (note by PH, June 2024). */\n\nstatic PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)\n{\nPCRE2_SPTR start_subject = args->begin;\nPCRE2_SPTR end_subject = args->end;\nint lgb = 0, rgb, ricount;\nPCRE2_SPTR prevcc, endcc, bptr;\nBOOL first = TRUE;\nBOOL was_ep_ZWJ = FALSE;\nuint32_t c;\n\nprevcc = cc;\nendcc = NULL;\ndo\n  {\n  GETCHARINC(c, cc);\n  rgb = UCD_GRAPHBREAK(c);\n\n  if (first)\n    {\n    lgb = rgb;\n    endcc = cc;\n    first = FALSE;\n    continue;\n    }\n\n  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)\n    break;\n\n  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was\n  preceded by Extended Pictographic. */\n\n  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)\n    break;\n\n  /* Not breaking between Regional Indicators is allowed only if there\n  are an even number of preceding RIs. */\n\n  if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)\n    {\n    ricount = 0;\n    bptr = prevcc;\n\n    /* bptr is pointing to the left-hand character */\n    while (bptr > start_subject)\n      {\n      bptr--;\n      BACKCHAR(bptr);\n      GETCHAR(c, bptr);\n\n      if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator)\n        break;\n\n      ricount++;\n      }\n\n    if ((ricount & 1) != 0) break;  /* Grapheme break required */\n    }\n\n  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in\n  between; see next statement). */\n\n  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);\n\n  /* If Extend follows Extended_Pictographic, do not update lgb; this allows\n  any number of them before a following ZWJ. */\n\n  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)\n    lgb = rgb;\n\n  prevcc = endcc;\n  endcc = cc;\n  }\nwhile (cc < end_subject);\n\nreturn endcc;\n}\n\n#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n/* The code in this function copies the logic of the interpreter function that\nis defined in the pcre2_extuni.c source. If that code is updated, this\nfunction, and the one below it, must be kept in step (note by PH, June 2024). */\n\nstatic PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc)\n{\nPCRE2_SPTR start_subject = args->begin;\nPCRE2_SPTR end_subject = args->end;\nint lgb = 0, rgb, ricount;\nPCRE2_SPTR prevcc, endcc, bptr;\nBOOL first = TRUE;\nBOOL was_ep_ZWJ = FALSE;\nuint32_t c;\n\nprevcc = cc;\nendcc = NULL;\ndo\n  {\n  GETCHARINC_INVALID(c, cc, end_subject, break);\n  rgb = UCD_GRAPHBREAK(c);\n\n  if (first)\n    {\n    lgb = rgb;\n    endcc = cc;\n    first = FALSE;\n    continue;\n    }\n\n  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)\n    break;\n\n  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was\n  preceded by Extended Pictographic. */\n\n  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)\n    break;\n\n  /* Not breaking between Regional Indicators is allowed only if there\n  are an even number of preceding RIs. */\n\n  if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)\n    {\n    ricount = 0;\n    bptr = prevcc;\n\n    /* bptr is pointing to the left-hand character */\n    while (bptr > start_subject)\n      {\n      GETCHARBACK_INVALID(c, bptr, start_subject, break);\n\n      if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator)\n        break;\n\n      ricount++;\n      }\n\n    if ((ricount & 1) != 0)\n      break;  /* Grapheme break required */\n    }\n\n  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in\n  between; see next statement). */\n\n  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);\n\n  /* If Extend follows Extended_Pictographic, do not update lgb; this allows\n  any number of them before a following ZWJ. */\n\n  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)\n    lgb = rgb;\n\n  prevcc = endcc;\n  endcc = cc;\n  }\nwhile (cc < end_subject);\n\nreturn endcc;\n}\n\n/* The code in this function copies the logic of the interpreter function that\nis defined in the pcre2_extuni.c source. If that code is updated, this\nfunction must be kept in step (note by PH, June 2024). */\n\nstatic PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)\n{\nPCRE2_SPTR start_subject = args->begin;\nPCRE2_SPTR end_subject = args->end;\nint lgb, rgb, ricount;\nPCRE2_SPTR bptr;\nuint32_t c;\nBOOL was_ep_ZWJ = FALSE;\n\n/* Patch by PH */\n/* GETCHARINC(c, cc); */\nc = *cc++;\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (c >= 0x110000)\n  return cc;\n#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */\nlgb = UCD_GRAPHBREAK(c);\n\nwhile (cc < end_subject)\n  {\n  c = *cc;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  if (c >= 0x110000)\n    break;\n#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */\n  rgb = UCD_GRAPHBREAK(c);\n\n  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)\n    break;\n\n  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was\n  preceded by Extended Pictographic. */\n\n  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)\n    break;\n\n  /* Not breaking between Regional Indicators is allowed only if there\n  are an even number of preceding RIs. */\n\n  if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator)\n    {\n    ricount = 0;\n    bptr = cc - 1;\n\n    /* bptr is pointing to the left-hand character */\n    while (bptr > start_subject)\n      {\n      bptr--;\n      c = *bptr;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n      if (c >= 0x110000)\n        break;\n#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\n      if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break;\n\n      ricount++;\n      }\n\n    if ((ricount & 1) != 0)\n      break;  /* Grapheme break required */\n    }\n\n  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in\n  between; see next statement). */\n\n  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);\n\n  /* If Extend follows Extended_Pictographic, do not update lgb; this allows\n  any number of them before a following ZWJ. */\n\n  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)\n    lgb = rgb;\n\n  cc++;\n  }\n\nreturn cc;\n}\n\nstatic void compile_clist(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nconst sljit_u32 *other_cases;\nstruct sljit_jump *jump;\nsljit_u32 min = 0, max = READ_CHAR_MAX;\nBOOL has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0;\n\nSLJIT_ASSERT(cc[1] == PT_CLIST);\n\nif (cc[0] == OP_PROP)\n  {\n  other_cases = PRIV(ucd_caseless_sets) + cc[2];\n\n  min = *other_cases++;\n  max = min;\n\n  while (*other_cases != NOTACHAR)\n    {\n    if (*other_cases > max) max = *other_cases;\n    if (*other_cases < min) min = *other_cases;\n    other_cases++;\n    }\n  }\n\nother_cases = PRIV(ucd_caseless_sets) + cc[2];\nSLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR);\n/* The NOTACHAR is higher than any character. */\nSLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);\n\nread_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR);\n\n/* At least two characters are required.\n   Otherwise this case would be handled by the normal code path. */\n/* NOTACHAR is the unsigned maximum. */\n\n/* Optimizing character pairs, if their difference is power of 2. */\nif (is_powerof2(other_cases[1] ^ other_cases[0]))\n  {\n  OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[1] ^ other_cases[0]));\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]);\n  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n  other_cases += 2;\n  }\nelse if (is_powerof2(other_cases[2] ^ other_cases[1]))\n  {\n  SLJIT_ASSERT(other_cases[2] != NOTACHAR);\n\n  OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[2] ^ other_cases[1]));\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]);\n  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)other_cases[0]);\n\n  if (has_cmov)\n    SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2);\n  else\n    OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);\n\n  other_cases += 3;\n  }\nelse\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++));\n  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\n  }\n\nwhile (*other_cases != NOTACHAR)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++));\n\n  if (has_cmov)\n    SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2);\n  else\n    OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);\n  }\n\nif (has_cmov)\n  jump = CMP(cc[0] == OP_PROP ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0);\nelse\n  jump = JUMP(cc[0] == OP_PROP ? SLJIT_ZERO : SLJIT_NOT_ZERO);\n\nadd_jump(compiler, backtracks, jump);\n}\n\n#endif /* SUPPORT_UNICODE */\n\nstatic PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)\n{\nDEFINE_COMPILER;\nint length;\nunsigned int c, oc, bit;\ncompare_context context;\nstruct sljit_jump *jump[3];\njump_list *end_list;\n#ifdef SUPPORT_UNICODE\nPCRE2_UCHAR propdata[5];\n#endif /* SUPPORT_UNICODE */\n\nswitch(type)\n  {\n  case OP_NOT_DIGIT:\n  case OP_DIGIT:\n  /* Digits are usually 0-9, so it is worth to optimize them. */\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE))\n    read_char7_type(common, backtracks, type == OP_NOT_DIGIT);\n  else\n#endif\n    read_char8_type(common, backtracks, type == OP_NOT_DIGIT);\n    /* Flip the starting bit in the negative case. */\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit);\n  add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));\n  return cc;\n\n  case OP_NOT_WHITESPACE:\n  case OP_WHITESPACE:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE))\n    read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE);\n  else\n#endif\n    read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space);\n  add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));\n  return cc;\n\n  case OP_NOT_WORDCHAR:\n  case OP_WORDCHAR:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE))\n    read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR);\n  else\n#endif\n    read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word);\n  add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));\n  return cc;\n\n  case OP_ANY:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  if (common->nltype == NLTYPE_FIXED && common->newline > 255)\n    {\n    jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);\n    end_list = NULL;\n    if (common->mode != PCRE2_JIT_PARTIAL_HARD)\n      add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n    else\n      check_str_end(common, &end_list);\n\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));\n    set_jumps(end_list, LABEL());\n    JUMPHERE(jump[0]);\n    }\n  else\n    check_newlinechar(common, common->nltype, backtracks, TRUE);\n  return cc;\n\n  case OP_ALLANY:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n#ifdef SUPPORT_UNICODE\n  if (common->utf && common->invalid_utf)\n    {\n    read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR);\n    return cc;\n    }\n#endif /* SUPPORT_UNICODE */\n\n  skip_valid_char(common);\n  return cc;\n\n  case OP_ANYBYTE:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  return cc;\n\n#ifdef SUPPORT_UNICODE\n  case OP_NOTPROP:\n  case OP_PROP:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  if (cc[0] == PT_CLIST)\n    {\n    compile_clist(common, cc - 1, backtracks);\n    return cc + 2;\n    }\n\n  propdata[0] = 0;\n  propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;\n  propdata[2] = cc[0];\n  propdata[3] = cc[1];\n  propdata[4] = XCL_END;\n  compile_xclass_matchingpath(common, propdata, backtracks, 0);\n  return cc + 2;\n#endif\n\n  case OP_ANYNL:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0);\n  jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);\n  /* We don't need to handle soft partial matching case. */\n  end_list = NULL;\n  if (common->mode != PCRE2_JIT_PARTIAL_HARD)\n    add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  else\n    check_str_end(common, &end_list);\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL);\n  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  jump[1] = JUMP(SLJIT_JUMP);\n  JUMPHERE(jump[0]);\n  check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);\n  set_jumps(end_list, LABEL());\n  JUMPHERE(jump[1]);\n  return cc;\n\n  case OP_NOT_HSPACE:\n  case OP_HSPACE:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n\n  if (type == OP_NOT_HSPACE)\n    read_char(common, 0x1, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  else\n    read_char(common, 0x1, 0x3000, NULL, 0);\n\n  add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));\n  sljit_set_current_flags(compiler, SLJIT_SET_Z);\n  add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));\n  return cc;\n\n  case OP_NOT_VSPACE:\n  case OP_VSPACE:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n\n  if (type == OP_NOT_VSPACE)\n    read_char(common, 0x1, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  else\n    read_char(common, 0x1, 0x2029, NULL, 0);\n\n  add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));\n  sljit_set_current_flags(compiler, SLJIT_SET_Z);\n  add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));\n  return cc;\n\n#ifdef SUPPORT_UNICODE\n  case OP_EXTUNI:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n\n  SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);\n  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,\n    common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf));\n  if (common->invalid_utf)\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));\n#else\n  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,\n    common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf));\n  if (common->invalid_utf)\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));\n#endif\n\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);\n\n  if (common->mode == PCRE2_JIT_PARTIAL_HARD)\n    {\n    jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0);\n    /* Since we successfully read a char above, partial matching must occur. */\n    check_partial(common, TRUE);\n    JUMPHERE(jump[0]);\n    }\n  return cc;\n#endif\n\n  case OP_CHAR:\n  case OP_CHARI:\n  length = 1;\n#ifdef SUPPORT_UNICODE\n  if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);\n#endif\n\n  if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE)\n    detect_partial_match(common, backtracks);\n\n  if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)\n    {\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));\n    if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE))\n      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));\n\n    context.length = IN_UCHARS(length);\n    context.sourcereg = -1;\n#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED\n    context.ucharptr = 0;\n#endif\n    return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);\n    }\n\n#ifdef SUPPORT_UNICODE\n  if (common->utf)\n    {\n    GETCHAR(c, cc);\n    }\n  else\n#endif\n    c = *cc;\n\n  SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc));\n\n  if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n  oc = char_othercase(common, c);\n  read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0);\n\n  SLJIT_ASSERT(!is_powerof2(c ^ oc));\n\n  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))\n    {\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc);\n    SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1);\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));\n    }\n  else\n    {\n    jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));\n    JUMPHERE(jump[0]);\n    }\n  return cc + length;\n\n  case OP_NOT:\n  case OP_NOTI:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n\n  length = 1;\n#ifdef SUPPORT_UNICODE\n  if (common->utf)\n    {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    c = *cc;\n    if (c < 128 && !common->invalid_utf)\n      {\n      OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n      if (type == OP_NOT || !char_has_othercase(common, cc))\n        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));\n      else\n        {\n        /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */\n        OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);\n        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));\n        }\n      /* Skip the variable-length character. */\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n      jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);\n      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n      JUMPHERE(jump[0]);\n      return cc + 1;\n      }\n    else\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n      {\n      GETCHARLEN(c, cc, length);\n      }\n    }\n  else\n#endif /* SUPPORT_UNICODE */\n    c = *cc;\n\n  if (type == OP_NOT || !char_has_othercase(common, cc))\n    {\n    read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR);\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));\n    }\n  else\n    {\n    oc = char_othercase(common, c);\n    read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR);\n    bit = c ^ oc;\n    if (is_powerof2(bit))\n      {\n      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));\n      }\n    else\n      {\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));\n      }\n    }\n  return cc + length;\n\n  case OP_CLASS:\n  case OP_NCLASS:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n  bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;\n  if (type == OP_NCLASS)\n    read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  else\n    read_char(common, 0, bit, NULL, 0);\n#else\n  if (type == OP_NCLASS)\n    read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR);\n  else\n    read_char(common, 0, 255, NULL, 0);\n#endif\n\n  if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))\n    return cc + 32 / sizeof(PCRE2_UCHAR);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n  jump[0] = NULL;\n  if (common->utf)\n    {\n    jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);\n    if (type == OP_CLASS)\n      {\n      add_jump(compiler, backtracks, jump[0]);\n      jump[0] = NULL;\n      }\n    }\n#elif PCRE2_CODE_UNIT_WIDTH != 8\n  jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\n  if (type == OP_CLASS)\n    {\n    add_jump(compiler, backtracks, jump[0]);\n    jump[0] = NULL;\n    }\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */\n\n  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);\n  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);\n  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);\n  add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n  if (jump[0] != NULL)\n    JUMPHERE(jump[0]);\n#endif\n  return cc + 32 / sizeof(PCRE2_UCHAR);\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  case OP_XCLASS:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks, 0);\n  return cc + GET(cc, 0) - 1;\n\n  case OP_ECLASS:\n  if (check_str_ptr)\n    detect_partial_match(common, backtracks);\n  return compile_eclass_matchingpath(common, cc, backtracks);\n#endif\n  }\nSLJIT_UNREACHABLE();\nreturn cc;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks)\n{\n/* This function consumes at least one input character. */\n/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */\nDEFINE_COMPILER;\nPCRE2_SPTR ccbegin = cc;\ncompare_context context;\nint size;\n\ncontext.length = 0;\ndo\n  {\n  if (cc >= ccend)\n    break;\n\n  if (*cc == OP_CHAR)\n    {\n    size = 1;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[1]))\n      size += GET_EXTRALEN(cc[1]);\n#endif\n    }\n  else if (*cc == OP_CHARI)\n    {\n    size = 1;\n#ifdef SUPPORT_UNICODE\n    if (common->utf)\n      {\n      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)\n        size = 0;\n      else if (HAS_EXTRALEN(cc[1]))\n        size += GET_EXTRALEN(cc[1]);\n      }\n    else\n#endif\n    if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)\n      size = 0;\n    }\n  else\n    size = 0;\n\n  cc += 1 + size;\n  context.length += IN_UCHARS(size);\n  }\nwhile (size > 0 && context.length <= 128);\n\ncc = ccbegin;\nif (context.length > 0)\n  {\n  /* We have a fixed-length byte sequence. */\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));\n\n  context.sourcereg = -1;\n#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED\n  context.ucharptr = 0;\n#endif\n  do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);\n  return cc;\n  }\n\n/* A non-fixed length character will be checked if length == 0. */\nreturn compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);\n}\n\n\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_jit_compile.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n                    This module by Zoltan Herczeg\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#if defined(__has_feature)\n#if __has_feature(memory_sanitizer)\n#include <sanitizer/msan_interface.h>\n#endif /* __has_feature(memory_sanitizer) */\n#endif /* defined(__has_feature) */\n\n#include \"pcre2_internal.h\"\n\n#ifdef SUPPORT_JIT\n\n/* All-in-one: Since we use the JIT compiler only from here,\nwe just include it. This way we don't need to touch the build\nsystem files. */\n\n#define SLJIT_CONFIG_AUTO 1\n#define SLJIT_CONFIG_STATIC 1\n#define SLJIT_VERBOSE 0\n\n#ifdef PCRE2_DEBUG\n#define SLJIT_DEBUG 1\n#else\n#define SLJIT_DEBUG 0\n#endif\n\n#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)\n#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)\n\nstatic void * pcre2_jit_malloc(size_t size, void *allocator_data)\n{\npcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);\nreturn allocator->malloc(size, allocator->memory_data);\n}\n\nstatic void pcre2_jit_free(void *ptr, void *allocator_data)\n{\npcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);\nallocator->free(ptr, allocator->memory_data);\n}\n\n#include \"../deps/sljit/sljit_src/sljitLir.c\"\n\n#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED\n#error Unsupported architecture\n#endif\n\n/* Defines for debugging purposes. */\n\n/* 1 - Use unoptimized capturing brackets.\n   2 - Enable capture_last_ptr (includes option 1). */\n/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */\n\n/* 1 - Always have a control head. */\n/* #define DEBUG_FORCE_CONTROL_HEAD 1 */\n\n/* Allocate memory for the regex stack on the real machine stack.\nFast, but limited size. */\n#define MACHINE_STACK_SIZE 32768\n\n/* Growth rate for stack allocated by the OS. Should be the multiply\nof page size. */\n#define STACK_GROWTH_RATE 8192\n\n/* Enable to check that the allocation could destroy temporaries. */\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\n#define DESTROY_REGISTERS 1\n#endif\n\n/*\nShort summary about the backtracking mechanism empolyed by the jit code generator:\n\nThe code generator follows the recursive nature of the PERL compatible regular\nexpressions. The basic blocks of regular expressions are condition checkers\nwhose execute different commands depending on the result of the condition check.\nThe relationship between the operators can be horizontal (concatenation) and\nvertical (sub-expression) (See struct backtrack_common for more details).\n\n  'ab' - 'a' and 'b' regexps are concatenated\n  'a+' - 'a' is the sub-expression of the '+' operator\n\nThe condition checkers are boolean (true/false) checkers. Machine code is generated\nfor the checker itself and for the actions depending on the result of the checker.\nThe 'true' case is called as the matching path (expected path), and the other is called as\nthe 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken\nbranches on the matching path.\n\n Greedy star operator (*) :\n   Matching path: match happens.\n   Backtrack path: match failed.\n Non-greedy star operator (*?) :\n   Matching path: no need to perform a match.\n   Backtrack path: match is required.\n\nThe following example shows how the code generated for a capturing bracket\nwith two alternatives. Let A, B, C, D are arbirary regular expressions, and\nwe have the following regular expression:\n\n   A(B|C)D\n\nThe generated code will be the following:\n\n A matching path\n '(' matching path (pushing arguments to the stack)\n B matching path\n ')' matching path (pushing arguments to the stack)\n D matching path\n return with successful match\n\n D backtrack path\n ')' backtrack path (If we arrived from \"C\" jump to the backtrack of \"C\")\n B backtrack path\n C expected path\n jump to D matching path\n C backtrack path\n A backtrack path\n\n Notice, that the order of backtrack code paths are the opposite of the fast\n code paths. In this way the topmost value on the stack is always belong\n to the current backtrack code path. The backtrack path must check\n whether there is a next alternative. If so, it needs to jump back to\n the matching path eventually. Otherwise it needs to clear out its own stack\n frame and continue the execution on the backtrack code paths.\n*/\n\n/*\nSaved stack frames:\n\nAtomic blocks and asserts require reloading the values of private data\nwhen the backtrack mechanism performed. Because of OP_RECURSE, the data\nare not necessarly known in compile time, thus we need a dynamic restore\nmechanism.\n\nThe stack frames are stored in a chain list, and have the following format:\n([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]\n\nThus we can restore the private data to a particular point in the stack.\n*/\n\ntypedef struct jit_arguments {\n  /* Pointers first. */\n  struct sljit_stack *stack;\n  PCRE2_SPTR str;\n  PCRE2_SPTR begin;\n  PCRE2_SPTR end;\n  pcre2_match_data *match_data;\n  PCRE2_SPTR startchar_ptr;\n  PCRE2_UCHAR *mark_ptr;\n  int (*callout)(pcre2_callout_block *, void *);\n  void *callout_data;\n  /* Everything else after. */\n  sljit_uw offset_limit;\n  sljit_u32 limit_match;\n  sljit_u32 oveccount;\n  sljit_u32 options;\n} jit_arguments;\n\n#define JIT_NUMBER_OF_COMPILE_MODES 3\n\ntypedef struct executable_functions {\n  void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];\n  void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];\n  sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];\n  sljit_u32 top_bracket;\n  sljit_u32 limit_match;\n} executable_functions;\n\ntypedef struct jump_list {\n  struct sljit_jump *jump;\n  struct jump_list *next;\n} jump_list;\n\ntypedef struct stub_list {\n  struct sljit_jump *start;\n  struct sljit_label *quit;\n  struct stub_list *next;\n} stub_list;\n\nenum frame_types {\n  no_frame = -1,\n  no_stack = -2\n};\n\nenum control_types {\n  type_mark = 0,\n  type_then_trap = 1\n};\n\nenum  early_fail_types {\n  type_skip = 0,\n  type_fail = 1,\n  type_fail_range = 2\n};\n\ntypedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);\n\n/* The following structure is the key data type for the recursive\ncode generator. It is allocated by compile_matchingpath, and contains\nthe arguments for compile_backtrackingpath. Must be the first member\nof its descendants. */\ntypedef struct backtrack_common {\n  /* Backtracking path of an opcode, which falls back\n     to our opcode, if it cannot resume matching. */\n  struct backtrack_common *prev;\n  /* Backtracks for opcodes without backtracking path.\n     These opcodes are between 'prev' and the current\n     opcode, and they never resume the match. */\n  jump_list *simple_backtracks;\n  /* Internal backtracking list for block constructs\n     which contains other opcodes, such as brackets,\n     asserts, conditionals, etc. */\n  struct backtrack_common *top;\n  /* Backtracks used internally by the opcode. For component\n     opcodes, this list is also used by those opcodes without\n     backtracking path which follows the 'top' backtrack. */\n  jump_list *own_backtracks;\n  /* Opcode pointer. */\n  PCRE2_SPTR cc;\n} backtrack_common;\n\ntypedef struct assert_backtrack {\n  backtrack_common common;\n  jump_list *condfailed;\n  /* Less than 0 if a frame is not needed. */\n  int framesize;\n  /* Points to our private memory word on the stack. */\n  int private_data_ptr;\n  /* For iterators. */\n  struct sljit_label *matchingpath;\n} assert_backtrack;\n\ntypedef struct bracket_backtrack {\n  backtrack_common common;\n  /* Where to coninue if an alternative is successfully matched. */\n  struct sljit_label *alternative_matchingpath;\n  /* For rmin and rmax iterators. */\n  struct sljit_label *recursive_matchingpath;\n  /* For greedy ? operator. */\n  struct sljit_label *zero_matchingpath;\n  /* Contains the branches of a failed condition. */\n  union {\n    /* Both for OP_COND, OP_SCOND, OP_ASSERT_SCS. */\n    jump_list *no_capture;\n    assert_backtrack *assert;\n    /* For OP_ONCE. Less than 0 if not needed. */\n    int framesize;\n  } u;\n  /* For brackets with >3 alternatives. */\n  struct sljit_jump *matching_mov_addr;\n  /* Points to our private memory word on the stack. */\n  int private_data_ptr;\n} bracket_backtrack;\n\ntypedef struct bracketpos_backtrack {\n  backtrack_common common;\n  /* Points to our private memory word on the stack. */\n  int private_data_ptr;\n  /* Reverting stack is needed. */\n  int framesize;\n  /* Allocated stack size. */\n  int stacksize;\n} bracketpos_backtrack;\n\ntypedef struct braminzero_backtrack {\n  backtrack_common common;\n  struct sljit_label *matchingpath;\n} braminzero_backtrack;\n\ntypedef struct char_iterator_backtrack {\n  backtrack_common common;\n  /* Next iteration. */\n  struct sljit_label *matchingpath;\n  /* Creating a range based on the next character. */\n  struct {\n    unsigned int othercasebit;\n    PCRE2_UCHAR chr;\n    BOOL charpos_enabled;\n  } charpos;\n} char_iterator_backtrack;\n\ntypedef struct ref_iterator_backtrack {\n  backtrack_common common;\n  /* Next iteration. */\n  struct sljit_label *matchingpath;\n} ref_iterator_backtrack;\n\ntypedef struct recurse_entry {\n  struct recurse_entry *next;\n  /* Contains the function entry label. */\n  struct sljit_label *entry_label;\n  /* Contains the function entry label. */\n  struct sljit_label *backtrack_label;\n  /* Collects the entry calls until the function is not created. */\n  jump_list *entry_calls;\n  /* Collects the backtrack calls until the function is not created. */\n  jump_list *backtrack_calls;\n  /* Points to the starting opcode. */\n  sljit_sw start;\n  /* Start of caller arguments. */\n  PCRE2_SPTR arg_start;\n  /* Size of caller arguments in bytes. */\n  sljit_uw arg_size;\n} recurse_entry;\n\ntypedef struct recurse_backtrack {\n  backtrack_common common;\n  /* Return to the matching path. */\n  struct sljit_label *matchingpath;\n  /* Recursive pattern. */\n  recurse_entry *entry;\n  /* Pattern is inlined. */\n  BOOL inlined_pattern;\n} recurse_backtrack;\n\ntypedef struct vreverse_backtrack {\n  backtrack_common common;\n  /* Return to the matching path. */\n  struct sljit_label *matchingpath;\n} vreverse_backtrack;\n\n#define OP_THEN_TRAP OP_TABLE_LENGTH\n\ntypedef struct then_trap_backtrack {\n  backtrack_common common;\n  /* If then_trap is not NULL, this structure contains the real\n  then_trap for the backtracking path. */\n  struct then_trap_backtrack *then_trap;\n  /* Points to the starting opcode. */\n  sljit_sw start;\n  /* Exit point for the then opcodes of this alternative. */\n  jump_list *quit;\n  /* Frame size of the current alternative. */\n  int framesize;\n} then_trap_backtrack;\n\n#define MAX_N_CHARS 12\n#define MAX_DIFF_CHARS 5\n\ntypedef struct fast_forward_char_data {\n  /* Number of characters in the chars array, 255 for any character. */\n  sljit_u8 count;\n  /* Number of last UTF-8 characters in the chars array. */\n  sljit_u8 last_count;\n  /* Available characters in the current position. */\n  PCRE2_UCHAR chars[MAX_DIFF_CHARS];\n} fast_forward_char_data;\n\n#define MAX_CLASS_RANGE_SIZE 4\n#define MAX_CLASS_CHARS_SIZE 3\n\ntypedef struct compiler_common {\n  /* The sljit ceneric compiler. */\n  struct sljit_compiler *compiler;\n  /* Compiled regular expression. */\n  pcre2_real_code *re;\n  /* First byte code. */\n  PCRE2_SPTR start;\n  /* Maps private data offset to each opcode. */\n  sljit_s32 *private_data_ptrs;\n  /* Chain list of read-only data ptrs. */\n  void *read_only_data_head;\n  /* Bitset which tells which capture brackets can be optimized. */\n  sljit_u8 *optimized_cbrackets;\n  /* Bitset for tracking capture bracket status. */\n  sljit_u8 *cbracket_bitset;\n  /* Tells whether the starting offset is a target of then. */\n  sljit_u8 *then_offsets;\n  /* Current position where a THEN must jump. */\n  then_trap_backtrack *then_trap;\n  /* Starting offset of private data for capturing brackets. */\n  sljit_s32 cbra_ptr;\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\n  /* End offset of locals for assertions. */\n  sljit_s32 locals_size;\n#endif\n  /* Output vector starting point. Must be divisible by 2. */\n  sljit_s32 ovector_start;\n  /* Points to the starting character of the current match. */\n  sljit_s32 start_ptr;\n  /* Last known position of the requested byte. */\n  sljit_s32 req_char_ptr;\n  /* Head of the last recursion. */\n  sljit_s32 recursive_head_ptr;\n  /* First inspected character for partial matching.\n     (Needed for avoiding zero length partial matches.) */\n  sljit_s32 start_used_ptr;\n  /* Starting pointer for partial soft matches. */\n  sljit_s32 hit_start;\n  /* Pointer of the match end position. */\n  sljit_s32 match_end_ptr;\n  /* Points to the marked string. */\n  sljit_s32 mark_ptr;\n  /* Head of the recursive control verb management chain.\n     Each item must have a previous offset and type\n     (see control_types) values. See do_search_mark. */\n  sljit_s32 control_head_ptr;\n  /* The offset of the saved STR_END in the outermost\n     scan substring block. Since scan substring restores\n     STR_END after a match, it is enough to restore\n     STR_END inside a scan substring block. */\n  sljit_s32 restore_end_ptr;\n  /* Points to the last matched capture block index. */\n  sljit_s32 capture_last_ptr;\n  /* Fast forward skipping byte code pointer. */\n  PCRE2_SPTR fast_forward_bc_ptr;\n  /* Locals used by fast fail optimization. */\n  sljit_s32 early_fail_start_ptr;\n  sljit_s32 early_fail_end_ptr;\n  /* Byte length of optimized_cbrackets and cbracket_bitset. */\n  sljit_u32 cbracket_bitset_length;\n  /* Variables used by recursive call generator. */\n  sljit_s32 recurse_bitset_size;\n  uint8_t *recurse_bitset;\n\n  /* Flipped and lower case tables. */\n  const sljit_u8 *fcc;\n  sljit_sw lcc;\n  /* Mode can be PCRE2_JIT_COMPLETE and others. */\n  int mode;\n  /* TRUE, when empty match is accepted for partial matching. */\n  BOOL allow_empty_partial;\n  /* TRUE, when minlength is greater than 0. */\n  BOOL might_be_empty;\n  /* \\K is found in the pattern. */\n  BOOL has_set_som;\n  /* (*SKIP:arg) is found in the pattern. */\n  BOOL has_skip_arg;\n  /* (*THEN) is found in the pattern. */\n  BOOL has_then;\n  /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */\n  BOOL has_skip_in_assert_back;\n  /* Quit is redirected by recurse, negative assertion, or positive assertion in conditional block. */\n  BOOL local_quit_available;\n  /* Currently in a positive assertion. */\n  BOOL in_positive_assertion;\n  /* Newline control. */\n  int nltype;\n  sljit_u32 nlmax;\n  sljit_u32 nlmin;\n  int newline;\n  int bsr_nltype;\n  sljit_u32 bsr_nlmax;\n  sljit_u32 bsr_nlmin;\n  /* Dollar endonly. */\n  int endonly;\n  /* Tables. */\n  sljit_sw ctypes;\n  /* Named capturing brackets. */\n  PCRE2_SPTR name_table;\n  sljit_sw name_count;\n  sljit_sw name_entry_size;\n\n  /* Labels and jump lists. */\n  struct sljit_label *partialmatchlabel;\n  struct sljit_label *quit_label;\n  struct sljit_label *abort_label;\n  struct sljit_label *accept_label;\n  struct sljit_label *ff_newline_shortcut;\n  stub_list *stubs;\n  recurse_entry *entries;\n  recurse_entry *currententry;\n  jump_list *partialmatch;\n  jump_list *quit;\n  jump_list *positive_assertion_quit;\n  jump_list *abort;\n  jump_list *failed_match;\n  jump_list *accept;\n  jump_list *calllimit;\n  jump_list *stackalloc;\n  jump_list *revertframes;\n  jump_list *wordboundary;\n  jump_list *ucp_wordboundary;\n  jump_list *anynewline;\n  jump_list *hspace;\n  jump_list *vspace;\n  jump_list *casefulcmp;\n  jump_list *caselesscmp;\n  jump_list *reset_match;\n  /* Same as reset_match, but resets the STR_PTR as well. */\n  jump_list *restart_match;\n  BOOL unset_backref;\n  BOOL alt_circumflex;\n#ifdef SUPPORT_UNICODE\n  BOOL utf;\n  BOOL invalid_utf;\n  BOOL ucp;\n  /* Points to saving area for iref. */\n  jump_list *getucd;\n  jump_list *getucdtype;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  jump_list *utfreadchar;\n  jump_list *utfreadtype8;\n  jump_list *utfpeakcharback;\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16\n  jump_list *utfreadchar_invalid;\n  jump_list *utfreadnewline_invalid;\n  jump_list *utfmoveback_invalid;\n  jump_list *utfpeakcharback_invalid;\n#endif\n#endif /* SUPPORT_UNICODE */\n} compiler_common;\n\n/* For byte_sequence_compare. */\n\ntypedef struct compare_context {\n  int length;\n  int sourcereg;\n#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED\n  int ucharptr;\n  union {\n    sljit_s32 asint;\n    sljit_u16 asushort;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    sljit_u8 asbyte;\n    sljit_u8 asuchars[4];\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n    sljit_u16 asuchars[2];\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n    sljit_u32 asuchars[1];\n#endif\n  } c;\n  union {\n    sljit_s32 asint;\n    sljit_u16 asushort;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    sljit_u8 asbyte;\n    sljit_u8 asuchars[4];\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n    sljit_u16 asuchars[2];\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n    sljit_u32 asuchars[1];\n#endif\n  } oc;\n#endif\n} compare_context;\n\n/* Undefine sljit macros. */\n#undef CMP\n\n/* Used for accessing the elements of the stack. */\n#define STACK(i)      ((i) * SSIZE_OF(sw))\n\n#ifdef SLJIT_PREF_SHIFT_REG\n#if SLJIT_PREF_SHIFT_REG == SLJIT_R2\n/* Nothing. */\n#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3\n#define SHIFT_REG_IS_R3\n#else\n#error \"Unsupported shift register\"\n#endif\n#endif\n\n#define TMP1          SLJIT_R0\n#ifdef SHIFT_REG_IS_R3\n#define TMP2          SLJIT_R3\n#define TMP3          SLJIT_R2\n#else\n#define TMP2          SLJIT_R2\n#define TMP3          SLJIT_R3\n#endif\n#define STR_PTR       SLJIT_R1\n#define STR_END       SLJIT_S0\n#define STACK_TOP     SLJIT_S1\n#define STACK_LIMIT   SLJIT_S2\n#define COUNT_MATCH   SLJIT_S3\n#define ARGUMENTS     SLJIT_S4\n#define RETURN_ADDR   SLJIT_R4\n\n#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)\n#define HAS_VIRTUAL_REGISTERS 1\n#else\n#define HAS_VIRTUAL_REGISTERS 0\n#endif\n\n/* Local space layout. */\n/* Max limit of recursions. */\n#define LIMIT_MATCH      (0 * sizeof(sljit_sw))\n/* Local variables. Their number is computed by check_opcode_types. */\n#define LOCAL0           (1 * sizeof(sljit_sw))\n#define LOCAL1           (2 * sizeof(sljit_sw))\n#define LOCAL2           (3 * sizeof(sljit_sw))\n#define LOCAL3           (4 * sizeof(sljit_sw))\n#define LOCAL4           (5 * sizeof(sljit_sw))\n/* The output vector is stored on the stack, and contains pointers\nto characters. The vector data is divided into two groups: the first\ngroup contains the start / end character pointers, and the second is\nthe start pointers when the end of the capturing group has not yet reached. */\n#define OVECTOR_START    (common->ovector_start)\n#define OVECTOR(i)       (OVECTOR_START + (i) * SSIZE_OF(sw))\n#define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * SSIZE_OF(sw))\n#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define MOV_UCHAR  SLJIT_MOV_U8\n#define IN_UCHARS(x) (x)\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define MOV_UCHAR  SLJIT_MOV_U16\n#define UCHAR_SHIFT (1)\n#define IN_UCHARS(x) ((x) * 2)\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n#define MOV_UCHAR  SLJIT_MOV_U32\n#define UCHAR_SHIFT (2)\n#define IN_UCHARS(x) ((x) * 4)\n#else\n#error Unsupported compiling mode\n#endif\n\n/* Shortcuts. */\n#define DEFINE_COMPILER \\\n  struct sljit_compiler *compiler = common->compiler\n#define OP1(op, dst, dstw, src, srcw) \\\n  sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))\n#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \\\n  sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))\n#define OP2U(op, src1, src1w, src2, src2w) \\\n  sljit_emit_op2u(compiler, (op), (src1), (src1w), (src2), (src2w))\n#define OP_SRC(op, src, srcw) \\\n  sljit_emit_op_src(compiler, (op), (src), (srcw))\n#define LABEL() \\\n  sljit_emit_label(compiler)\n#define JUMP(type) \\\n  sljit_emit_jump(compiler, (type))\n#define JUMPTO(type, label) \\\n  sljit_set_label(sljit_emit_jump(compiler, (type)), (label))\n#define JUMPHERE(jump) \\\n  sljit_set_label((jump), sljit_emit_label(compiler))\n#define SET_LABEL(jump, label) \\\n  sljit_set_label((jump), (label))\n#define CMP(type, src1, src1w, src2, src2w) \\\n  sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))\n#define CMPTO(type, src1, src1w, src2, src2w, label) \\\n  sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))\n#define OP_FLAGS(op, dst, dstw, type) \\\n  sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type))\n#define SELECT(type, dst_reg, src1, src1w, src2_reg) \\\n  sljit_emit_select(compiler, (type), (dst_reg), (src1), (src1w), (src2_reg))\n#define GET_LOCAL_BASE(dst, dstw, offset) \\\n  sljit_get_local_base(compiler, (dst), (dstw), (offset))\n\n#define READ_CHAR_MAX ((sljit_u32)0xffffffff)\n\n#define INVALID_UTF_CHAR -1\n#define UNASSIGNED_UTF_CHAR 888\n\n#if defined SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n\n#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \\\n  { \\\n  if (ptr[0] <= 0x7f) \\\n    c = *ptr++; \\\n  else if (ptr + 1 < end && ptr[1] >= 0x80 && ptr[1] < 0xc0) \\\n    { \\\n    c = ptr[1] - 0x80; \\\n    \\\n    if (ptr[0] >= 0xc2 && ptr[0] <= 0xdf) \\\n      { \\\n      c |= (ptr[0] - 0xc0) << 6; \\\n      ptr += 2; \\\n      } \\\n    else if (ptr + 2 < end && ptr[2] >= 0x80 && ptr[2] < 0xc0) \\\n      { \\\n      c = c << 6 | (ptr[2] - 0x80); \\\n      \\\n      if (ptr[0] >= 0xe0 && ptr[0] <= 0xef) \\\n        { \\\n        c |= (ptr[0] - 0xe0) << 12; \\\n        ptr += 3; \\\n        \\\n        if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \\\n          { \\\n          invalid_action; \\\n          } \\\n        } \\\n      else if (ptr + 3 < end && ptr[3] >= 0x80 && ptr[3] < 0xc0) \\\n        { \\\n        c = c << 6 | (ptr[3] - 0x80); \\\n        \\\n        if (ptr[0] >= 0xf0 && ptr[0] <= 0xf4) \\\n          { \\\n          c |= (ptr[0] - 0xf0) << 18; \\\n          ptr += 4; \\\n          \\\n          if (c >= 0x110000 || c < 0x10000) \\\n            { \\\n            invalid_action; \\\n            } \\\n          } \\\n        else \\\n          { \\\n          invalid_action; \\\n          } \\\n        } \\\n      else \\\n        { \\\n        invalid_action; \\\n        } \\\n      } \\\n    else \\\n      { \\\n      invalid_action; \\\n      } \\\n    } \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \\\n  { \\\n  c = ptr[-1]; \\\n  if (c <= 0x7f) \\\n    ptr--; \\\n  else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \\\n    { \\\n    c -= 0x80; \\\n    \\\n    if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \\\n      { \\\n      c |= (ptr[-2] - 0xc0) << 6; \\\n      ptr -= 2; \\\n      } \\\n    else if (ptr - 2 > start && ptr[-2] >= 0x80 && ptr[-2] < 0xc0) \\\n      { \\\n      c = c << 6 | (ptr[-2] - 0x80); \\\n      \\\n      if (ptr[-3] >= 0xe0 && ptr[-3] <= 0xef) \\\n        { \\\n        c |= (ptr[-3] - 0xe0) << 12; \\\n        ptr -= 3; \\\n        \\\n        if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \\\n          { \\\n          invalid_action; \\\n          } \\\n        } \\\n      else if (ptr - 3 > start && ptr[-3] >= 0x80 && ptr[-3] < 0xc0) \\\n        { \\\n        c = c << 6 | (ptr[-3] - 0x80); \\\n        \\\n        if (ptr[-4] >= 0xf0 && ptr[-4] <= 0xf4) \\\n          { \\\n          c |= (ptr[-4] - 0xf0) << 18; \\\n          ptr -= 4; \\\n          \\\n          if (c >= 0x110000 || c < 0x10000) \\\n            { \\\n            invalid_action; \\\n            } \\\n          } \\\n        else \\\n          { \\\n          invalid_action; \\\n          } \\\n        } \\\n      else \\\n        { \\\n        invalid_action; \\\n        } \\\n      } \\\n    else \\\n      { \\\n      invalid_action; \\\n      } \\\n    } \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n\n#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \\\n  { \\\n  if (ptr[0] < 0xd800 || ptr[0] >= 0xe000) \\\n    c = *ptr++; \\\n  else if (ptr[0] < 0xdc00 && ptr + 1 < end && ptr[1] >= 0xdc00 && ptr[1] < 0xe000) \\\n    { \\\n    c = (((ptr[0] - 0xd800) << 10) | (ptr[1] - 0xdc00)) + 0x10000; \\\n    ptr += 2; \\\n    } \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \\\n  { \\\n  c = ptr[-1]; \\\n  if (c < 0xd800 || c >= 0xe000) \\\n    ptr--; \\\n  else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \\\n    { \\\n    c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \\\n    ptr -= 2; \\\n    } \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n\n#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \\\n  { \\\n  if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \\\n    c = *ptr++; \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \\\n  { \\\n  c = ptr[-1]; \\\n  if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \\\n    ptr--; \\\n  else \\\n    { \\\n    invalid_action; \\\n    } \\\n  }\n\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n#endif /* SUPPORT_UNICODE */\n\nstatic PCRE2_SPTR bracketend(PCRE2_SPTR cc)\n{\nSLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND));\ndo cc += GET(cc, 1); while (*cc == OP_ALT);\nSLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);\ncc += 1 + LINK_SIZE;\nreturn cc;\n}\n\nstatic int no_alternatives(PCRE2_SPTR cc)\n{\nint count = 0;\nSLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND));\ndo\n  {\n  cc += GET(cc, 1);\n  count++;\n  }\nwhile (*cc == OP_ALT);\nSLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);\nreturn count;\n}\n\nstatic BOOL find_vreverse(PCRE2_SPTR cc)\n{\n  SLJIT_ASSERT(*cc == OP_ASSERTBACK || *cc == OP_ASSERTBACK_NOT ||  *cc == OP_ASSERTBACK_NA);\n\n  do\n    {\n    if (cc[1 + LINK_SIZE] == OP_VREVERSE)\n      return TRUE;\n    cc += GET(cc, 1);\n    }\n  while (*cc == OP_ALT);\n\n  return FALSE;\n}\n\n/* Functions whose might need modification for all new supported opcodes:\n next_opcode\n check_opcode_types\n set_private_data_ptrs\n get_framesize\n init_frame\n get_recurse_data_length\n copy_recurse_data\n compile_matchingpath\n compile_backtrackingpath\n*/\n\nstatic PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc)\n{\nSLJIT_UNUSED_ARG(common);\nswitch(*cc)\n  {\n  case OP_SOD:\n  case OP_SOM:\n  case OP_SET_SOM:\n  case OP_NOT_WORD_BOUNDARY:\n  case OP_WORD_BOUNDARY:\n  case OP_NOT_DIGIT:\n  case OP_DIGIT:\n  case OP_NOT_WHITESPACE:\n  case OP_WHITESPACE:\n  case OP_NOT_WORDCHAR:\n  case OP_WORDCHAR:\n  case OP_ANY:\n  case OP_ALLANY:\n  case OP_NOTPROP:\n  case OP_PROP:\n  case OP_ANYNL:\n  case OP_NOT_HSPACE:\n  case OP_HSPACE:\n  case OP_NOT_VSPACE:\n  case OP_VSPACE:\n  case OP_EXTUNI:\n  case OP_EODN:\n  case OP_EOD:\n  case OP_CIRC:\n  case OP_CIRCM:\n  case OP_DOLL:\n  case OP_DOLLM:\n  case OP_CRSTAR:\n  case OP_CRMINSTAR:\n  case OP_CRPLUS:\n  case OP_CRMINPLUS:\n  case OP_CRQUERY:\n  case OP_CRMINQUERY:\n  case OP_CRRANGE:\n  case OP_CRMINRANGE:\n  case OP_CRPOSSTAR:\n  case OP_CRPOSPLUS:\n  case OP_CRPOSQUERY:\n  case OP_CRPOSRANGE:\n  case OP_CLASS:\n  case OP_NCLASS:\n  case OP_REF:\n  case OP_REFI:\n  case OP_DNREF:\n  case OP_DNREFI:\n  case OP_RECURSE:\n  case OP_CALLOUT:\n  case OP_ALT:\n  case OP_KET:\n  case OP_KETRMAX:\n  case OP_KETRMIN:\n  case OP_KETRPOS:\n  case OP_REVERSE:\n  case OP_VREVERSE:\n  case OP_ASSERT:\n  case OP_ASSERT_NOT:\n  case OP_ASSERTBACK:\n  case OP_ASSERTBACK_NOT:\n  case OP_ASSERT_NA:\n  case OP_ASSERTBACK_NA:\n  case OP_ASSERT_SCS:\n  case OP_ONCE:\n  case OP_SCRIPT_RUN:\n  case OP_BRA:\n  case OP_BRAPOS:\n  case OP_CBRA:\n  case OP_CBRAPOS:\n  case OP_COND:\n  case OP_SBRA:\n  case OP_SBRAPOS:\n  case OP_SCBRA:\n  case OP_SCBRAPOS:\n  case OP_SCOND:\n  case OP_CREF:\n  case OP_DNCREF:\n  case OP_RREF:\n  case OP_DNRREF:\n  case OP_FALSE:\n  case OP_TRUE:\n  case OP_BRAZERO:\n  case OP_BRAMINZERO:\n  case OP_BRAPOSZERO:\n  case OP_PRUNE:\n  case OP_SKIP:\n  case OP_THEN:\n  case OP_COMMIT:\n  case OP_FAIL:\n  case OP_ACCEPT:\n  case OP_ASSERT_ACCEPT:\n  case OP_CLOSE:\n  case OP_SKIPZERO:\n  case OP_NOT_UCP_WORD_BOUNDARY:\n  case OP_UCP_WORD_BOUNDARY:\n  return cc + PRIV(OP_lengths)[*cc];\n\n  case OP_CHAR:\n  case OP_CHARI:\n  case OP_NOT:\n  case OP_NOTI:\n  case OP_STAR:\n  case OP_MINSTAR:\n  case OP_PLUS:\n  case OP_MINPLUS:\n  case OP_QUERY:\n  case OP_MINQUERY:\n  case OP_UPTO:\n  case OP_MINUPTO:\n  case OP_EXACT:\n  case OP_POSSTAR:\n  case OP_POSPLUS:\n  case OP_POSQUERY:\n  case OP_POSUPTO:\n  case OP_STARI:\n  case OP_MINSTARI:\n  case OP_PLUSI:\n  case OP_MINPLUSI:\n  case OP_QUERYI:\n  case OP_MINQUERYI:\n  case OP_UPTOI:\n  case OP_MINUPTOI:\n  case OP_EXACTI:\n  case OP_POSSTARI:\n  case OP_POSPLUSI:\n  case OP_POSQUERYI:\n  case OP_POSUPTOI:\n  case OP_NOTSTAR:\n  case OP_NOTMINSTAR:\n  case OP_NOTPLUS:\n  case OP_NOTMINPLUS:\n  case OP_NOTQUERY:\n  case OP_NOTMINQUERY:\n  case OP_NOTUPTO:\n  case OP_NOTMINUPTO:\n  case OP_NOTEXACT:\n  case OP_NOTPOSSTAR:\n  case OP_NOTPOSPLUS:\n  case OP_NOTPOSQUERY:\n  case OP_NOTPOSUPTO:\n  case OP_NOTSTARI:\n  case OP_NOTMINSTARI:\n  case OP_NOTPLUSI:\n  case OP_NOTMINPLUSI:\n  case OP_NOTQUERYI:\n  case OP_NOTMINQUERYI:\n  case OP_NOTUPTOI:\n  case OP_NOTMINUPTOI:\n  case OP_NOTEXACTI:\n  case OP_NOTPOSSTARI:\n  case OP_NOTPOSPLUSI:\n  case OP_NOTPOSQUERYI:\n  case OP_NOTPOSUPTOI:\n  cc += PRIV(OP_lengths)[*cc];\n#ifdef SUPPORT_UNICODE\n  if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n  return cc;\n\n  /* Special cases. */\n  case OP_TYPESTAR:\n  case OP_TYPEMINSTAR:\n  case OP_TYPEPLUS:\n  case OP_TYPEMINPLUS:\n  case OP_TYPEQUERY:\n  case OP_TYPEMINQUERY:\n  case OP_TYPEUPTO:\n  case OP_TYPEMINUPTO:\n  case OP_TYPEEXACT:\n  case OP_TYPEPOSSTAR:\n  case OP_TYPEPOSPLUS:\n  case OP_TYPEPOSQUERY:\n  case OP_TYPEPOSUPTO:\n  return cc + PRIV(OP_lengths)[*cc] - 1;\n\n  case OP_ANYBYTE:\n#ifdef SUPPORT_UNICODE\n  if (common->utf) return NULL;\n#endif\n  return cc + 1;\n\n  case OP_CALLOUT_STR:\n  return cc + GET(cc, 1 + 2*LINK_SIZE);\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n  case OP_ECLASS:\n  case OP_XCLASS:\n  SLJIT_COMPILE_ASSERT(OP_XCLASS + 1 == OP_ECLASS && OP_CLASS + 1 == OP_NCLASS && OP_NCLASS < OP_XCLASS, class_byte_code_order);\n  return cc + GET(cc, 1);\n#endif\n\n  case OP_MARK:\n  case OP_COMMIT_ARG:\n  case OP_PRUNE_ARG:\n  case OP_SKIP_ARG:\n  case OP_THEN_ARG:\n  return cc + 1 + 2 + cc[1];\n\n  default:\n  SLJIT_UNREACHABLE();\n  return NULL;\n  }\n}\n\nstatic sljit_s32 ref_update_local_size(compiler_common *common, PCRE2_SPTR cc, sljit_s32 current_locals_size)\n{\n/* Depends on do_casefulcmp(), do_caselesscmp(), and compile_ref_matchingpath() */\nint locals_size = 2 * SSIZE_OF(sw);\nSLJIT_UNUSED_ARG(common);\n\n#ifdef SUPPORT_UNICODE\nif ((*cc == OP_REFI || *cc == OP_DNREFI) && (common->utf || common->ucp))\n  locals_size = 3 * SSIZE_OF(sw);\n#endif\n\ncc += PRIV(OP_lengths)[*cc];\n/* Although do_casefulcmp() uses only one local, the allocate_stack()\ncalls during the repeat destroys LOCAL1 variables. */\nif (*cc >= OP_CRSTAR && *cc <= OP_CRPOSRANGE)\n  locals_size += 2 * SSIZE_OF(sw);\n\nreturn (current_locals_size >= locals_size) ? current_locals_size : locals_size;\n}\n\nstatic SLJIT_INLINE BOOL is_optimized_cbracket(compiler_common *common, sljit_s32 capture_index)\n{\nsljit_u8 bit = (sljit_u8)(1 << (capture_index & 0x7));\nreturn (common->optimized_cbrackets[capture_index >> 3] & bit) != 0;\n}\n\nstatic SLJIT_INLINE void clear_optimized_cbracket(compiler_common *common, sljit_s32 capture_index)\n{\nsljit_u8 mask = (sljit_u8)~(1 << (capture_index & 0x7));\ncommon->optimized_cbrackets[capture_index >> 3] &= mask;\n}\n\nstatic BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)\n{\nint count;\nPCRE2_SPTR slot;\nPCRE2_SPTR assert_back_end = cc - 1;\nPCRE2_SPTR assert_na_end = cc - 1;\nsljit_s32 locals_size = 2 * SSIZE_OF(sw);\nBOOL set_recursive_head = FALSE;\nBOOL set_capture_last = FALSE;\nBOOL set_mark = FALSE;\n\n/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */\nwhile (cc < ccend)\n  {\n  switch(*cc)\n    {\n    case OP_SET_SOM:\n    common->has_set_som = TRUE;\n    common->might_be_empty = TRUE;\n    cc += 1;\n    break;\n\n    case OP_TYPEUPTO:\n    case OP_TYPEEXACT:\n    if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n    cc += (2 + IMM2_SIZE) - 1;\n    break;\n\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    if (cc[1] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n    cc += 2 - 1;\n    break;\n\n    case OP_TYPEPOSUPTO:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n#endif\n    if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n    cc += (2 + IMM2_SIZE) - 1;\n    break;\n\n    case OP_REFI:\n    case OP_REF:\n    locals_size = ref_update_local_size(common, cc, locals_size);\n    clear_optimized_cbracket(common, GET2(cc, 1));\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ASSERT_SCS:\n    slot = bracketend(cc);\n    if (slot > assert_na_end)\n      assert_na_end = slot;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    clear_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE));\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_COND:\n    case OP_SCOND:\n    /* Only AUTO_CALLOUT can insert this opcode. We do\n       not intend to support this case. */\n    if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR)\n      return FALSE;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CREF:\n    clear_optimized_cbracket(common, GET2(cc, 1));\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_DNREFI:\n    case OP_DNREF:\n    locals_size = ref_update_local_size(common, cc, locals_size);\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_DNCREF:\n    count = GET2(cc, 1 + IMM2_SIZE);\n    slot = common->name_table + GET2(cc, 1) * common->name_entry_size;\n    while (count-- > 0)\n      {\n      clear_optimized_cbracket(common, GET2(slot, 0));\n      slot += common->name_entry_size;\n      }\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n\n    case OP_RECURSE:\n    /* Set its value only once. */\n    set_recursive_head = TRUE;\n    cc += 1 + LINK_SIZE;\n    while (*cc == OP_CREF)\n      {\n      clear_optimized_cbracket(common, GET2(cc, 1));\n      cc += 1 + IMM2_SIZE;\n      }\n    break;\n\n    case OP_CALLOUT:\n    case OP_CALLOUT_STR:\n    set_capture_last = TRUE;\n    cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);\n    break;\n\n    case OP_ASSERTBACK:\n    slot = bracketend(cc);\n    if (slot > assert_back_end)\n      assert_back_end = slot;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_THEN_ARG:\n    common->has_then = TRUE;\n    common->control_head_ptr = 1;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_MARK:\n    set_mark = TRUE;\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_THEN:\n    common->has_then = TRUE;\n    common->control_head_ptr = 1;\n    cc += 1;\n    break;\n\n    case OP_SKIP:\n    if (cc < assert_back_end)\n      common->has_skip_in_assert_back = TRUE;\n    cc += 1;\n    break;\n\n    case OP_SKIP_ARG:\n    common->control_head_ptr = 1;\n    common->has_skip_arg = TRUE;\n    if (cc < assert_back_end)\n      common->has_skip_in_assert_back = TRUE;\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_ASSERT_ACCEPT:\n    if (cc < assert_na_end)\n      return FALSE;\n    cc++;\n    break;\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    case OP_CRPOSRANGE:\n    /* The second value can be 0 for infinite repeats. */\n    if (common->utf && GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE) && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n    cc += 1 + 2 * IMM2_SIZE;\n    break;\n\n    case OP_POSUPTO:\n    case OP_POSUPTOI:\n    case OP_NOTPOSUPTO:\n    case OP_NOTPOSUPTOI:\n    if (common->utf && locals_size <= 3 * SSIZE_OF(sw))\n      locals_size = 3 * SSIZE_OF(sw);\n#endif\n    PCRE2_FALLTHROUGH /* Fall through */\n    default:\n    cc = next_opcode(common, cc);\n    if (cc == NULL)\n      return FALSE;\n    break;\n    }\n  }\n\nSLJIT_ASSERT((locals_size & (SSIZE_OF(sw) - 1)) == 0);\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\ncommon->locals_size = locals_size;\n#endif\n\nif (locals_size > 0)\n  common->ovector_start += locals_size;\n\nif (set_mark)\n  {\n  SLJIT_ASSERT(common->mark_ptr == 0);\n  common->mark_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\nif (set_recursive_head)\n  {\n  SLJIT_ASSERT(common->recursive_head_ptr == 0);\n  common->recursive_head_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\nif (set_capture_last)\n  {\n  SLJIT_ASSERT(common->capture_last_ptr == 0);\n  common->capture_last_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\nreturn TRUE;\n}\n\n#define EARLY_FAIL_ENHANCE_MAX (3 + 3)\n\n/*\n  Start represent the number of allowed early fail enhancements\n\n  The 0-2 values has a special meaning:\n    0 - skip is allowed for all iterators\n    1 - fail is allowed for all iterators\n    2 - fail is allowed for greedy iterators\n    3 - only ranged early fail is allowed\n  >3 - (start - 3) number of remaining ranged early fails allowed\n\nreturn: the updated value of start\n*/\nstatic int detect_early_fail(compiler_common *common, PCRE2_SPTR cc,\n   int *private_data_start, sljit_s32 depth, int start)\n{\nPCRE2_SPTR begin = cc;\nPCRE2_SPTR next_alt;\nPCRE2_SPTR end;\nPCRE2_SPTR accelerated_start;\nint result = 0;\nint count, prev_count;\n\nSLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);\nSLJIT_ASSERT(*cc != OP_CBRA || is_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE)));\nSLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);\n\nnext_alt = cc + GET(cc, 1);\nif (*next_alt == OP_ALT && start < 1)\n  start = 1;\n\ndo\n  {\n  count = start;\n  cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);\n\n  while (TRUE)\n    {\n    accelerated_start = NULL;\n\n    switch(*cc)\n      {\n      case OP_SOD:\n      case OP_SOM:\n      case OP_SET_SOM:\n      case OP_NOT_WORD_BOUNDARY:\n      case OP_WORD_BOUNDARY:\n      case OP_EODN:\n      case OP_EOD:\n      case OP_CIRC:\n      case OP_CIRCM:\n      case OP_DOLL:\n      case OP_DOLLM:\n      case OP_NOT_UCP_WORD_BOUNDARY:\n      case OP_UCP_WORD_BOUNDARY:\n      /* Zero width assertions. */\n      cc++;\n      continue;\n\n      case OP_NOT_DIGIT:\n      case OP_DIGIT:\n      case OP_NOT_WHITESPACE:\n      case OP_WHITESPACE:\n      case OP_NOT_WORDCHAR:\n      case OP_WORDCHAR:\n      case OP_ANY:\n      case OP_ALLANY:\n      case OP_ANYBYTE:\n      case OP_NOT_HSPACE:\n      case OP_HSPACE:\n      case OP_NOT_VSPACE:\n      case OP_VSPACE:\n      if (count < 1)\n        count = 1;\n      cc++;\n      continue;\n\n      case OP_ANYNL:\n      case OP_EXTUNI:\n      if (count < 3)\n        count = 3;\n      cc++;\n      continue;\n\n      case OP_NOTPROP:\n      case OP_PROP:\n      if (count < 1)\n        count = 1;\n      cc += 1 + 2;\n      continue;\n\n      case OP_CHAR:\n      case OP_CHARI:\n      case OP_NOT:\n      case OP_NOTI:\n      if (count < 1)\n        count = 1;\n      cc += 2;\n#ifdef SUPPORT_UNICODE\n      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n      continue;\n\n      case OP_TYPEMINSTAR:\n      case OP_TYPEMINPLUS:\n      if (count == 2)\n        count = 3;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_TYPESTAR:\n      case OP_TYPEPLUS:\n      case OP_TYPEPOSSTAR:\n      case OP_TYPEPOSPLUS:\n      /* The type or prop opcode is skipped in the next iteration. */\n      cc += 1;\n\n      if (cc[0] != OP_ANYNL && cc[0] != OP_EXTUNI)\n        {\n        accelerated_start = cc - 1;\n        break;\n        }\n\n      if (count < 3)\n        count = 3;\n      continue;\n\n      case OP_TYPEEXACT:\n      if (count < 1)\n        count = 1;\n      cc += 1 + IMM2_SIZE;\n      continue;\n\n      case OP_TYPEUPTO:\n      case OP_TYPEMINUPTO:\n      case OP_TYPEPOSUPTO:\n      cc += IMM2_SIZE;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_TYPEQUERY:\n      case OP_TYPEMINQUERY:\n      case OP_TYPEPOSQUERY:\n      /* The type or prop opcode is skipped in the next iteration. */\n      if (count < 3)\n        count = 3;\n      cc += 1;\n      continue;\n\n      case OP_MINSTAR:\n      case OP_MINPLUS:\n      case OP_MINSTARI:\n      case OP_MINPLUSI:\n      case OP_NOTMINSTAR:\n      case OP_NOTMINPLUS:\n      case OP_NOTMINSTARI:\n      case OP_NOTMINPLUSI:\n      if (count == 2)\n        count = 3;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_STAR:\n      case OP_PLUS:\n      case OP_POSSTAR:\n      case OP_POSPLUS:\n\n      case OP_STARI:\n      case OP_PLUSI:\n      case OP_POSSTARI:\n      case OP_POSPLUSI:\n\n      case OP_NOTSTAR:\n      case OP_NOTPLUS:\n      case OP_NOTPOSSTAR:\n      case OP_NOTPOSPLUS:\n\n      case OP_NOTSTARI:\n      case OP_NOTPLUSI:\n      case OP_NOTPOSSTARI:\n      case OP_NOTPOSPLUSI:\n      accelerated_start = cc;\n      cc += 2;\n#ifdef SUPPORT_UNICODE\n      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n      break;\n\n      case OP_EXACT:\n      if (count < 1)\n        count = 1;\n      cc += 2 + IMM2_SIZE;\n#ifdef SUPPORT_UNICODE\n      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n      continue;\n\n      case OP_UPTO:\n      case OP_MINUPTO:\n      case OP_POSUPTO:\n      case OP_UPTOI:\n      case OP_MINUPTOI:\n      case OP_EXACTI:\n      case OP_POSUPTOI:\n      case OP_NOTUPTO:\n      case OP_NOTMINUPTO:\n      case OP_NOTEXACT:\n      case OP_NOTPOSUPTO:\n      case OP_NOTUPTOI:\n      case OP_NOTMINUPTOI:\n      case OP_NOTEXACTI:\n      case OP_NOTPOSUPTOI:\n      cc += IMM2_SIZE;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_QUERY:\n      case OP_MINQUERY:\n      case OP_POSQUERY:\n      case OP_QUERYI:\n      case OP_MINQUERYI:\n      case OP_POSQUERYI:\n      case OP_NOTQUERY:\n      case OP_NOTMINQUERY:\n      case OP_NOTPOSQUERY:\n      case OP_NOTQUERYI:\n      case OP_NOTMINQUERYI:\n      case OP_NOTPOSQUERYI:\n      if (count < 3)\n        count = 3;\n      cc += 2;\n#ifdef SUPPORT_UNICODE\n      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n      continue;\n\n      case OP_CLASS:\n      case OP_NCLASS:\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n      case OP_XCLASS:\n      case OP_ECLASS:\n      accelerated_start = cc;\n      cc += (*cc >= OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR)));\n#else\n      accelerated_start = cc;\n      cc += (1 + (32 / sizeof(PCRE2_UCHAR)));\n#endif\n\n      switch (*cc)\n        {\n        case OP_CRMINSTAR:\n        case OP_CRMINPLUS:\n        if (count == 2)\n          count = 3;\n        PCRE2_FALLTHROUGH /* Fall through */\n\n        case OP_CRSTAR:\n        case OP_CRPLUS:\n        case OP_CRPOSSTAR:\n        case OP_CRPOSPLUS:\n        cc++;\n        break;\n\n        case OP_CRRANGE:\n        case OP_CRMINRANGE:\n        case OP_CRPOSRANGE:\n        if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))\n          {\n          /* Exact repeat. */\n          cc += 1 + 2 * IMM2_SIZE;\n          if (count < 1)\n            count = 1;\n          continue;\n          }\n\n        cc += 2 * IMM2_SIZE;\n        PCRE2_FALLTHROUGH /* Fall through */\n        case OP_CRQUERY:\n        case OP_CRMINQUERY:\n        case OP_CRPOSQUERY:\n        cc++;\n        if (count < 3)\n          count = 3;\n        continue;\n\n        default:\n        /* No repeat. */\n        if (count < 1)\n          count = 1;\n        continue;\n        }\n      break;\n\n      case OP_BRA:\n      case OP_CBRA:\n      prev_count = count;\n      if (count < 1)\n        count = 1;\n\n      if (depth >= 4)\n        break;\n\n      if (count < 3 && cc[GET(cc, 1)] == OP_ALT)\n        count = 3;\n\n      end = bracketend(cc);\n      if (end[-1 - LINK_SIZE] != OP_KET || (*cc == OP_CBRA && !is_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE))))\n        break;\n\n      prev_count = detect_early_fail(common, cc, private_data_start, depth + 1, prev_count);\n\n      if (prev_count > count)\n        count = prev_count;\n\n      if (PRIVATE_DATA(cc) != 0)\n        common->private_data_ptrs[begin - common->start] = 1;\n\n      if (count < EARLY_FAIL_ENHANCE_MAX)\n        {\n        cc = end;\n        continue;\n        }\n      break;\n\n      case OP_KET:\n      SLJIT_ASSERT(PRIVATE_DATA(cc) == 0);\n      if (cc >= next_alt)\n        break;\n      cc += 1 + LINK_SIZE;\n      continue;\n      }\n\n    if (accelerated_start == NULL)\n      break;\n\n    if (count == 0)\n      {\n      common->fast_forward_bc_ptr = accelerated_start;\n      common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;\n      *private_data_start += sizeof(sljit_sw);\n      count = 4;\n      }\n    else if (count < 3)\n      {\n      common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail;\n\n      if (common->early_fail_start_ptr == 0)\n        common->early_fail_start_ptr = *private_data_start;\n\n      *private_data_start += sizeof(sljit_sw);\n      common->early_fail_end_ptr = *private_data_start;\n\n      if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)\n        return EARLY_FAIL_ENHANCE_MAX;\n\n      count = 4;\n      }\n    else\n      {\n      common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range;\n\n      if (common->early_fail_start_ptr == 0)\n        common->early_fail_start_ptr = *private_data_start;\n\n      *private_data_start += 2 * sizeof(sljit_sw);\n      common->early_fail_end_ptr = *private_data_start;\n\n      if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)\n        return EARLY_FAIL_ENHANCE_MAX;\n\n      count++;\n      }\n\n    /* Cannot be part of a repeat. */\n    common->private_data_ptrs[begin - common->start] = 1;\n\n    if (count >= EARLY_FAIL_ENHANCE_MAX)\n      break;\n    }\n\n  if (*cc != OP_ALT && *cc != OP_KET)\n    result = EARLY_FAIL_ENHANCE_MAX;\n  else if (result < count)\n    result = count;\n\n  cc = next_alt;\n  next_alt = cc + GET(cc, 1);\n  }\nwhile (*cc == OP_ALT);\n\nreturn result;\n}\n\nstatic int get_class_iterator_size(PCRE2_SPTR cc)\n{\nsljit_u32 min;\nsljit_u32 max;\nswitch(*cc)\n  {\n  case OP_CRSTAR:\n  case OP_CRPLUS:\n  return 2;\n\n  case OP_CRMINSTAR:\n  case OP_CRMINPLUS:\n  case OP_CRQUERY:\n  case OP_CRMINQUERY:\n  return 1;\n\n  case OP_CRRANGE:\n  case OP_CRMINRANGE:\n  min = GET2(cc, 1);\n  max = GET2(cc, 1 + IMM2_SIZE);\n  if (max == 0)\n    return (*cc == OP_CRRANGE) ? 2 : 1;\n  max -= min;\n  if (max > (sljit_u32)(*cc == OP_CRRANGE ? 0 : 1))\n    max = 2;\n  return max;\n\n  default:\n  return 0;\n  }\n}\n\nstatic BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin)\n{\nPCRE2_SPTR end = bracketend(begin);\nPCRE2_SPTR next;\nPCRE2_SPTR next_end;\nPCRE2_SPTR max_end;\nPCRE2_UCHAR type;\nsljit_sw length = end - begin;\nsljit_s32 min, max, i;\n\n/* Detect fixed iterations first. */\nif (end[-(1 + LINK_SIZE)] != OP_KET || PRIVATE_DATA(begin) != 0)\n  return FALSE;\n\n/* /(?:AB){4,6}/ is currently converted to /(?:AB){3}(?AB){1,3}/\n * Skip the check of the second part. */\nif (PRIVATE_DATA(end - LINK_SIZE) != 0)\n  return TRUE;\n\nnext = end;\nmin = 1;\nwhile (1)\n  {\n  if (*next != *begin)\n    break;\n  next_end = bracketend(next);\n  if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)\n    break;\n  next = next_end;\n  min++;\n  }\n\nif (min == 2)\n  return FALSE;\n\nmax = 0;\nmax_end = next;\nif (*next == OP_BRAZERO || *next == OP_BRAMINZERO)\n  {\n  type = *next;\n  while (1)\n    {\n    if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)\n      break;\n    next_end = bracketend(next + 2 + LINK_SIZE);\n    if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)\n      break;\n    next = next_end;\n    max++;\n    }\n\n  if (next[0] == type && next[1] == *begin && max >= 1)\n    {\n    next_end = bracketend(next + 1);\n    if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)\n      {\n      for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)\n        if (*next_end != OP_KET)\n          break;\n\n      if (i == max)\n        {\n        /* Patterns must fit into an int32 even for link-size=4. */\n        common->private_data_ptrs[max_end - common->start - LINK_SIZE] = (sljit_s32)(next_end - max_end);\n        common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;\n        /* +2 the original and the last. */\n        common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;\n        if (min == 1)\n          return TRUE;\n        min--;\n        max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);\n        }\n      }\n    }\n  }\n\nif (min >= 3)\n  {\n  common->private_data_ptrs[end - common->start - LINK_SIZE] = (sljit_s32)(max_end - end);\n  common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;\n  common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;\n  return TRUE;\n  }\n\nreturn FALSE;\n}\n\n#define CASE_ITERATOR_PRIVATE_DATA_1 \\\n    case OP_MINSTAR: \\\n    case OP_MINPLUS: \\\n    case OP_QUERY: \\\n    case OP_MINQUERY: \\\n    case OP_MINSTARI: \\\n    case OP_MINPLUSI: \\\n    case OP_QUERYI: \\\n    case OP_MINQUERYI: \\\n    case OP_NOTMINSTAR: \\\n    case OP_NOTMINPLUS: \\\n    case OP_NOTQUERY: \\\n    case OP_NOTMINQUERY: \\\n    case OP_NOTMINSTARI: \\\n    case OP_NOTMINPLUSI: \\\n    case OP_NOTQUERYI: \\\n    case OP_NOTMINQUERYI:\n\n#define CASE_ITERATOR_PRIVATE_DATA_2A \\\n    case OP_STAR: \\\n    case OP_PLUS: \\\n    case OP_STARI: \\\n    case OP_PLUSI: \\\n    case OP_NOTSTAR: \\\n    case OP_NOTPLUS: \\\n    case OP_NOTSTARI: \\\n    case OP_NOTPLUSI:\n\n#define CASE_ITERATOR_PRIVATE_DATA_2B \\\n    case OP_UPTO: \\\n    case OP_MINUPTO: \\\n    case OP_UPTOI: \\\n    case OP_MINUPTOI: \\\n    case OP_NOTUPTO: \\\n    case OP_NOTMINUPTO: \\\n    case OP_NOTUPTOI: \\\n    case OP_NOTMINUPTOI:\n\n#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \\\n    case OP_TYPEMINSTAR: \\\n    case OP_TYPEMINPLUS: \\\n    case OP_TYPEQUERY: \\\n    case OP_TYPEMINQUERY:\n\n#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \\\n    case OP_TYPESTAR: \\\n    case OP_TYPEPLUS:\n\n#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \\\n    case OP_TYPEUPTO: \\\n    case OP_TYPEMINUPTO:\n\nstatic void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend)\n{\nPCRE2_SPTR cc = common->start;\nPCRE2_SPTR alternative;\nPCRE2_SPTR end = NULL;\nint private_data_ptr = *private_data_start;\nint space, size, bracketlen;\nBOOL repeat_check = TRUE;\n\nwhile (cc < ccend)\n  {\n  space = 0;\n  size = 0;\n  bracketlen = 0;\n  if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)\n    break;\n\n  /* When the bracket is prefixed by a zero iteration, skip the repeat check (at this point). */\n  if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))\n    {\n    if (detect_repeat(common, cc))\n      {\n      /* These brackets are converted to repeats, so no global\n      based single character repeat is allowed. */\n      if (cc >= end)\n        end = bracketend(cc);\n      }\n    }\n  repeat_check = TRUE;\n\n  switch(*cc)\n    {\n    case OP_KET:\n    if (common->private_data_ptrs[cc + 1 - common->start] != 0)\n      {\n      common->private_data_ptrs[cc - common->start] = private_data_ptr;\n      private_data_ptr += sizeof(sljit_sw);\n      cc += common->private_data_ptrs[cc + 1 - common->start];\n      }\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_BRAPOS:\n    case OP_SBRA:\n    case OP_SBRAPOS:\n    case OP_SCOND:\n    common->private_data_ptrs[cc - common->start] = private_data_ptr;\n    private_data_ptr += sizeof(sljit_sw);\n    bracketlen = 1 + LINK_SIZE;\n    break;\n\n    case OP_ASSERTBACK_NA:\n    common->private_data_ptrs[cc - common->start] = private_data_ptr;\n    private_data_ptr += sizeof(sljit_sw);\n\n    if (find_vreverse(cc))\n      {\n      common->private_data_ptrs[cc + 1 - common->start] = 1;\n      private_data_ptr += sizeof(sljit_sw);\n      }\n\n    bracketlen = 1 + LINK_SIZE;\n    break;\n\n    case OP_ASSERT_SCS:\n    common->private_data_ptrs[cc - common->start] = private_data_ptr;\n    private_data_ptr += 2 * sizeof(sljit_sw);\n    bracketlen = 1 + LINK_SIZE;\n    break;\n\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    common->private_data_ptrs[cc - common->start] = private_data_ptr;\n    private_data_ptr += sizeof(sljit_sw);\n    bracketlen = 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_COND:\n    /* Might be a hidden SCOND. */\n    common->private_data_ptrs[cc - common->start] = 0;\n    alternative = cc + GET(cc, 1);\n    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)\n      {\n      common->private_data_ptrs[cc - common->start] = private_data_ptr;\n      private_data_ptr += sizeof(sljit_sw);\n      }\n    bracketlen = 1 + LINK_SIZE;\n    break;\n\n    case OP_BRA:\n    bracketlen = 1 + LINK_SIZE;\n    break;\n\n    case OP_CBRA:\n    case OP_SCBRA:\n    bracketlen = 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_BRAZERO:\n    case OP_BRAMINZERO:\n    case OP_BRAPOSZERO:\n    size = 1;\n    repeat_check = FALSE;\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_1\n    size = -2;\n    space = 1;\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2A\n    size = -2;\n    space = 2;\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2B\n    size = -(2 + IMM2_SIZE);\n    space = 2;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_1\n    size = 1;\n    space = 1;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A\n    size = 1;\n    if (cc[1] != OP_EXTUNI)\n      space = 2;\n    break;\n\n    case OP_TYPEUPTO:\n    size = 1 + IMM2_SIZE;\n    if (cc[1 + IMM2_SIZE] != OP_EXTUNI)\n      space = 2;\n    break;\n\n    case OP_TYPEMINUPTO:\n    size = 1 + IMM2_SIZE;\n    space = 2;\n    break;\n\n    case OP_CLASS:\n    case OP_NCLASS:\n    size = 1 + 32 / sizeof(PCRE2_UCHAR);\n    space = get_class_iterator_size(cc + size);\n    break;\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n    case OP_XCLASS:\n    case OP_ECLASS:\n    size = GET(cc, 1);\n    space = get_class_iterator_size(cc + size);\n    break;\n#endif\n\n    default:\n    cc = next_opcode(common, cc);\n    SLJIT_ASSERT(cc != NULL);\n    break;\n    }\n\n  /* Character iterators, which are not inside a repeated bracket,\n     gets a private slot instead of allocating it on the stack. */\n  if (space > 0 && cc >= end)\n    {\n    common->private_data_ptrs[cc - common->start] = private_data_ptr;\n    private_data_ptr += sizeof(sljit_sw) * space;\n    }\n\n  if (size != 0)\n    {\n    if (size < 0)\n      {\n      cc += -size;\n#ifdef SUPPORT_UNICODE\n      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n      }\n    else\n      cc += size;\n    }\n\n  if (bracketlen > 0)\n    {\n    if (cc >= end)\n      {\n      end = bracketend(cc);\n      if (end[-1 - LINK_SIZE] == OP_KET)\n        end = NULL;\n      }\n    cc += bracketlen;\n    }\n  }\n*private_data_start = private_data_ptr;\n}\n\nstatic SLJIT_INLINE BOOL is_cbracket_processed(compiler_common *common, sljit_s32 capture_index)\n{\nsljit_u8 bit = (sljit_u8)(1 << (capture_index & 0x7));\nsljit_u8 *ptr = common->cbracket_bitset + (capture_index >> 3);\nsljit_u8 value = *ptr;\n\n*ptr |= bit;\nreturn (value & bit) != 0;\n}\n\n/* Returns with a frame_types (always < 0) if no need for frame. */\nstatic int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)\n{\nint length = 0;\nint possessive = 0;\nint offset;\nBOOL stack_restore = FALSE;\nBOOL setsom_found = recursive;\nBOOL setmark_found = recursive;\n/* The last capture is a local variable even for recursions. */\nBOOL capture_last_found = FALSE;\n\n#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD\nSLJIT_ASSERT(common->control_head_ptr != 0);\n*needs_control_head = TRUE;\n#else\n*needs_control_head = FALSE;\n#endif\n\nmemset(common->cbracket_bitset, 0, common->cbracket_bitset_length);\n\nif (ccend == NULL)\n  {\n  ccend = bracketend(cc) - (1 + LINK_SIZE);\n  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))\n    {\n    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;\n    /* This is correct regardless of common->capture_last_ptr. */\n    capture_last_found = TRUE;\n    }\n  cc = next_opcode(common, cc);\n  }\n\nSLJIT_ASSERT(cc != NULL);\nwhile (cc < ccend)\n  switch(*cc)\n    {\n    case OP_SET_SOM:\n    SLJIT_ASSERT(common->has_set_som);\n    stack_restore = TRUE;\n    if (!setsom_found)\n      {\n      length += 2;\n      setsom_found = TRUE;\n      }\n    cc += 1;\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_THEN_ARG:\n    SLJIT_ASSERT(common->mark_ptr != 0);\n    stack_restore = TRUE;\n    if (!setmark_found)\n      {\n      length += 2;\n      setmark_found = TRUE;\n      }\n    if (common->control_head_ptr != 0)\n      *needs_control_head = TRUE;\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_RECURSE:\n    stack_restore = TRUE;\n    if (common->has_set_som && !setsom_found)\n      {\n      length += 2;\n      setsom_found = TRUE;\n      }\n    if (common->mark_ptr != 0 && !setmark_found)\n      {\n      length += 2;\n      setmark_found = TRUE;\n      }\n    if (common->capture_last_ptr != 0 && !capture_last_found)\n      {\n      length += 2;\n      capture_last_found = TRUE;\n      }\n\n    cc += 1 + LINK_SIZE;\n    while (*cc == OP_CREF)\n      {\n      offset = GET2(cc, 1);\n      if (!is_cbracket_processed(common, offset))\n        length += 3;\n      cc += 1 + IMM2_SIZE;\n      }\n    break;\n\n    case OP_CBRA:\n    case OP_CBRAPOS:\n    case OP_SCBRA:\n    case OP_SCBRAPOS:\n    stack_restore = TRUE;\n    if (common->capture_last_ptr != 0 && !capture_last_found)\n      {\n      length += 2;\n      capture_last_found = TRUE;\n      }\n\n    offset = GET2(cc, 1 + LINK_SIZE);\n    if (!is_cbracket_processed(common, offset))\n      length += 3;\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_THEN:\n    stack_restore = TRUE;\n    if (common->control_head_ptr != 0)\n      *needs_control_head = TRUE;\n    cc ++;\n    break;\n\n    default:\n    stack_restore = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_NOT_DIGIT:\n    case OP_DIGIT:\n    case OP_NOT_WHITESPACE:\n    case OP_WHITESPACE:\n    case OP_NOT_WORDCHAR:\n    case OP_WORDCHAR:\n    case OP_ANY:\n    case OP_ALLANY:\n    case OP_ANYBYTE:\n    case OP_NOTPROP:\n    case OP_PROP:\n    case OP_ANYNL:\n    case OP_NOT_HSPACE:\n    case OP_HSPACE:\n    case OP_NOT_VSPACE:\n    case OP_VSPACE:\n    case OP_EXTUNI:\n    case OP_EODN:\n    case OP_EOD:\n    case OP_CIRC:\n    case OP_CIRCM:\n    case OP_DOLL:\n    case OP_DOLLM:\n    case OP_CHAR:\n    case OP_CHARI:\n    case OP_NOT:\n    case OP_NOTI:\n\n    case OP_EXACT:\n    case OP_POSSTAR:\n    case OP_POSPLUS:\n    case OP_POSQUERY:\n    case OP_POSUPTO:\n\n    case OP_EXACTI:\n    case OP_POSSTARI:\n    case OP_POSPLUSI:\n    case OP_POSQUERYI:\n    case OP_POSUPTOI:\n\n    case OP_NOTEXACT:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSUPTO:\n\n    case OP_NOTEXACTI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTPOSQUERYI:\n    case OP_NOTPOSUPTOI:\n\n    case OP_TYPEEXACT:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    case OP_TYPEPOSUPTO:\n\n    case OP_CLASS:\n    case OP_NCLASS:\n    case OP_XCLASS:\n    case OP_ECLASS:\n\n    case OP_CALLOUT:\n    case OP_CALLOUT_STR:\n\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n\n    cc = next_opcode(common, cc);\n    SLJIT_ASSERT(cc != NULL);\n    break;\n    }\n\n/* Possessive quantifiers can use a special case. */\nif (SLJIT_UNLIKELY(possessive == length))\n  return stack_restore ? no_frame : no_stack;\n\nif (length > 0)\n  return length + 1;\nreturn stack_restore ? no_frame : no_stack;\n}\n\nstatic void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop)\n{\nDEFINE_COMPILER;\nBOOL setsom_found = FALSE;\nBOOL setmark_found = FALSE;\n/* The last capture is a local variable even for recursions. */\nBOOL capture_last_found = FALSE;\nint offset;\n\n/* >= 1 + shortest item size (2) */\nSLJIT_UNUSED_ARG(stacktop);\nSLJIT_ASSERT(stackpos >= stacktop + 2);\n\nmemset(common->cbracket_bitset, 0, common->cbracket_bitset_length);\n\nstackpos = STACK(stackpos);\nif (ccend == NULL)\n  {\n  ccend = bracketend(cc) - (1 + LINK_SIZE);\n  if (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)\n    cc = next_opcode(common, cc);\n  }\n\n/* The data is restored by do_revertframes(). */\nSLJIT_ASSERT(cc != NULL);\nwhile (cc < ccend)\n  switch(*cc)\n    {\n    case OP_SET_SOM:\n    SLJIT_ASSERT(common->has_set_som);\n    if (!setsom_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      setsom_found = TRUE;\n      }\n    cc += 1;\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_THEN_ARG:\n    SLJIT_ASSERT(common->mark_ptr != 0);\n    if (!setmark_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      setmark_found = TRUE;\n      }\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_RECURSE:\n    if (common->has_set_som && !setsom_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      setsom_found = TRUE;\n      }\n    if (common->mark_ptr != 0 && !setmark_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      setmark_found = TRUE;\n      }\n    if (common->capture_last_ptr != 0 && !capture_last_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      capture_last_found = TRUE;\n      }\n    cc += 1 + LINK_SIZE;\n    while (*cc == OP_CREF)\n      {\n      offset = GET2(cc, 1);\n      if (!is_cbracket_processed(common, offset))\n        {\n        offset <<= 1;\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));\n        stackpos -= SSIZE_OF(sw);\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n        stackpos -= SSIZE_OF(sw);\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);\n        stackpos -= SSIZE_OF(sw);\n        }\n      cc += 1 + IMM2_SIZE;\n      }\n    break;\n\n    case OP_CBRA:\n    case OP_CBRAPOS:\n    case OP_SCBRA:\n    case OP_SCBRAPOS:\n    if (common->capture_last_ptr != 0 && !capture_last_found)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      capture_last_found = TRUE;\n      }\n\n    offset = GET2(cc, 1 + LINK_SIZE);\n    if (!is_cbracket_processed(common, offset))\n      {\n      offset <<= 1;\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);\n      stackpos -= SSIZE_OF(sw);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);\n      stackpos -= SSIZE_OF(sw);\n      }\n\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    default:\n    cc = next_opcode(common, cc);\n    SLJIT_ASSERT(cc != NULL);\n    break;\n    }\n\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);\nSLJIT_ASSERT(stackpos == STACK(stacktop));\n}\n\n#define RECURSE_TMP_REG_COUNT 3\n\ntypedef struct delayed_mem_copy_status {\n  struct sljit_compiler *compiler;\n  int store_bases[RECURSE_TMP_REG_COUNT];\n  sljit_s32 store_offsets[RECURSE_TMP_REG_COUNT];\n  int tmp_regs[RECURSE_TMP_REG_COUNT];\n  int saved_tmp_regs[RECURSE_TMP_REG_COUNT];\n  int next_tmp_reg;\n} delayed_mem_copy_status;\n\nstatic void delayed_mem_copy_init(delayed_mem_copy_status *status, compiler_common *common)\n{\nint i;\n\nfor (i = 0; i < RECURSE_TMP_REG_COUNT; i++)\n  {\n  SLJIT_ASSERT(status->tmp_regs[i] >= 0);\n  SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]);\n\n  status->store_bases[i] = -1;\n  }\nstatus->next_tmp_reg = 0;\nstatus->compiler = common->compiler;\n}\n\nstatic void delayed_mem_copy_move(delayed_mem_copy_status *status, int load_base, sljit_sw load_offset,\n  int store_base, sljit_s32 store_offset)\n{\nstruct sljit_compiler *compiler = status->compiler;\nint next_tmp_reg = status->next_tmp_reg;\nint tmp_reg = status->tmp_regs[next_tmp_reg];\n\nSLJIT_ASSERT(load_base > 0 && store_base > 0);\n\nif (status->store_bases[next_tmp_reg] == -1)\n  {\n  /* Preserve virtual registers. */\n  if (sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[next_tmp_reg]) < 0)\n    OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0);\n  }\nelse\n  OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);\n\nOP1(SLJIT_MOV, tmp_reg, 0, SLJIT_MEM1(load_base), load_offset);\nstatus->store_bases[next_tmp_reg] = store_base;\nstatus->store_offsets[next_tmp_reg] = store_offset;\n\nstatus->next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;\n}\n\nstatic void delayed_mem_copy_finish(delayed_mem_copy_status *status)\n{\nstruct sljit_compiler *compiler = status->compiler;\nint next_tmp_reg = status->next_tmp_reg;\nint tmp_reg, saved_tmp_reg, i;\n\nfor (i = 0; i < RECURSE_TMP_REG_COUNT; i++)\n  {\n  if (status->store_bases[next_tmp_reg] != -1)\n    {\n    tmp_reg = status->tmp_regs[next_tmp_reg];\n    saved_tmp_reg = status->saved_tmp_regs[next_tmp_reg];\n\n    OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);\n\n    /* Restore virtual registers. */\n    if (sljit_get_register_index(SLJIT_GP_REGISTER, saved_tmp_reg) < 0)\n      OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0);\n    }\n\n  next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;\n  }\n}\n\n#undef RECURSE_TMP_REG_COUNT\n\nstatic BOOL recurse_check_bit(compiler_common *common, sljit_sw bit_index)\n{\nuint8_t *byte;\nuint8_t mask;\n\nSLJIT_ASSERT((bit_index & (sizeof(sljit_sw) - 1)) == 0);\n\nbit_index >>= SLJIT_WORD_SHIFT;\n\nSLJIT_ASSERT((bit_index >> 3) < common->recurse_bitset_size);\n\nmask = 1 << (bit_index & 0x7);\nbyte = common->recurse_bitset + (bit_index >> 3);\n\nif (*byte & mask)\n  return FALSE;\n\n*byte |= mask;\nreturn TRUE;\n}\n\nenum get_recurse_flags {\n  recurse_flag_quit_found = (1 << 0),\n  recurse_flag_accept_found = (1 << 1),\n  recurse_flag_setsom_found = (1 << 2),\n  recurse_flag_setmark_found = (1 << 3),\n  recurse_flag_control_head_found = (1 << 4),\n  recurse_flag_recurse_arg = (1 << 5),\n};\n\nstatic int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, uint32_t *result_flags)\n{\nint length = 1;\nint size, offset;\nPCRE2_SPTR alternative, cref;\nuint32_t recurse_flags = 0;\n\nmemset(common->recurse_bitset, 0, common->recurse_bitset_size);\n\nif (common->currententry->arg_size > 0)\n  {\n  cref = common->currententry->arg_start;\n\n  do\n    {\n    offset = GET2(cref, 1);\n    recurse_check_bit(common, OVECTOR(offset << 1));\n    cref += 1 + IMM2_SIZE;\n    }\n  while (*cref == OP_CREF);\n  }\n\n#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD\nSLJIT_ASSERT(common->control_head_ptr != 0);\nrecurse_flags |= recurse_flag_control_head_found;\n#endif\n\n/* Calculate the sum of the private machine words. */\nwhile (cc < ccend)\n  {\n  size = 0;\n  switch(*cc)\n    {\n    case OP_SET_SOM:\n    SLJIT_ASSERT(common->has_set_som);\n    recurse_flags |= recurse_flag_setsom_found;\n    cc += 1;\n    break;\n\n    case OP_RECURSE:\n    if (common->has_set_som)\n      recurse_flags |= recurse_flag_setsom_found;\n    if (common->mark_ptr != 0)\n      recurse_flags |= recurse_flag_setmark_found;\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      length++;\n    cc += 1 + LINK_SIZE;\n    if (*cc == OP_CREF)\n      recurse_flags |= recurse_flag_recurse_arg;\n    break;\n\n    case OP_KET:\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0)\n      {\n      if (recurse_check_bit(common, offset))\n        length++;\n      SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);\n      cc += PRIVATE_DATA(cc + 1);\n      }\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_BRAPOS:\n    case OP_SBRA:\n    case OP_SBRAPOS:\n    case OP_SCOND:\n    SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);\n    if (recurse_check_bit(common, PRIVATE_DATA(cc)))\n      length++;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CREF:\n    if ((recurse_flags & recurse_flag_recurse_arg) != 0)\n      {\n      offset = GET2(cc, 1);\n      if (recurse_check_bit(common, OVECTOR(offset << 1)))\n        {\n        SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));\n        length += 2;\n        }\n\n      if (cc[1 + IMM2_SIZE] != OP_CREF)\n        recurse_flags &= ~(uint32_t)recurse_flag_recurse_arg;\n      }\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_ASSERT_SCS:\n    SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);\n    if (recurse_check_bit(common, PRIVATE_DATA(cc)))\n      length += 2;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CBRA:\n    case OP_SCBRA:\n    offset = GET2(cc, 1 + LINK_SIZE);\n    if (recurse_check_bit(common, OVECTOR(offset << 1)))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));\n      length += 2;\n      }\n    if (!is_optimized_cbracket(common, offset) && recurse_check_bit(common, OVECTOR_PRIV(offset)))\n      length++;\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      length++;\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    offset = GET2(cc, 1 + LINK_SIZE);\n    if (recurse_check_bit(common, OVECTOR(offset << 1)))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));\n      length += 2;\n      }\n    if (recurse_check_bit(common, OVECTOR_PRIV(offset)))\n      length++;\n    if (recurse_check_bit(common, PRIVATE_DATA(cc)))\n      length++;\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      length++;\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_COND:\n    /* Might be a hidden SCOND. */\n    alternative = cc + GET(cc, 1);\n    if ((*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) && recurse_check_bit(common, PRIVATE_DATA(cc)))\n      length++;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_1\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      length++;\n    cc += 2;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2A\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));\n      length += 2;\n      }\n    cc += 2;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2B\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));\n      length += 2;\n      }\n    cc += 2 + IMM2_SIZE;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_1\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      length++;\n    cc += 1;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));\n      length += 2;\n      }\n    cc += 1;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_2B\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      {\n      SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));\n      length += 2;\n      }\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_CLASS:\n    case OP_NCLASS:\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n    case OP_XCLASS:\n    case OP_ECLASS:\n    size = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);\n#else\n    size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);\n#endif\n\n    offset = PRIVATE_DATA(cc);\n    if (offset != 0 && recurse_check_bit(common, offset))\n      length += get_class_iterator_size(cc + size);\n    cc += size;\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_THEN_ARG:\n    SLJIT_ASSERT(common->mark_ptr != 0);\n    recurse_flags |= recurse_flag_setmark_found;\n    if (common->control_head_ptr != 0)\n      recurse_flags |= recurse_flag_control_head_found;\n    if (*cc != OP_MARK)\n      recurse_flags |= recurse_flag_quit_found;\n\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_PRUNE:\n    case OP_SKIP:\n    case OP_COMMIT:\n    recurse_flags |= recurse_flag_quit_found;\n    cc++;\n    break;\n\n    case OP_SKIP_ARG:\n    recurse_flags |= recurse_flag_quit_found;\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_THEN:\n    SLJIT_ASSERT(common->control_head_ptr != 0);\n    recurse_flags |= recurse_flag_quit_found | recurse_flag_control_head_found;\n    cc++;\n    break;\n\n    case OP_ACCEPT:\n    case OP_ASSERT_ACCEPT:\n    recurse_flags |= recurse_flag_accept_found;\n    cc++;\n    break;\n\n    default:\n    cc = next_opcode(common, cc);\n    SLJIT_ASSERT(cc != NULL);\n    break;\n    }\n  }\nSLJIT_ASSERT(cc == ccend);\n\nif (recurse_flags & recurse_flag_control_head_found)\n  length++;\nif (recurse_flags & recurse_flag_quit_found)\n  {\n  if (recurse_flags & recurse_flag_setsom_found)\n    length++;\n  if (recurse_flags & recurse_flag_setmark_found)\n    length++;\n  }\n\n*result_flags = recurse_flags;\nreturn length;\n}\n\nenum copy_recurse_data_types {\n  recurse_copy_from_global,\n  recurse_copy_private_to_global,\n  recurse_copy_shared_to_global,\n  recurse_copy_kept_shared_to_global,\n  recurse_swap_global\n};\n\nstatic void copy_recurse_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,\n  int type, int stackptr, int stacktop, uint32_t recurse_flags)\n{\ndelayed_mem_copy_status status;\nPCRE2_SPTR alternative, cref;\nsljit_sw private_srcw[2];\nsljit_sw shared_srcw[3];\nsljit_sw kept_shared_srcw[2];\nint private_count, shared_count, kept_shared_count;\nint from_sp, base_reg, offset, i;\n\nmemset(common->recurse_bitset, 0, common->recurse_bitset_size);\n\nif (common->currententry->arg_size > 0)\n  {\n  cref = common->currententry->arg_start;\n\n  do\n    {\n    offset = GET2(cref, 1);\n    recurse_check_bit(common, OVECTOR(offset << 1));\n    cref += 1 + IMM2_SIZE;\n    }\n  while (*cref == OP_CREF);\n  }\n\n#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD\nSLJIT_ASSERT(common->control_head_ptr != 0);\nrecurse_check_bit(common, common->control_head_ptr);\n#endif\n\nswitch (type)\n  {\n  case recurse_copy_from_global:\n  from_sp = TRUE;\n  base_reg = STACK_TOP;\n  break;\n\n  case recurse_copy_private_to_global:\n  case recurse_copy_shared_to_global:\n  case recurse_copy_kept_shared_to_global:\n  from_sp = FALSE;\n  base_reg = STACK_TOP;\n  break;\n\n  default:\n  SLJIT_ASSERT(type == recurse_swap_global);\n  from_sp = FALSE;\n  base_reg = TMP2;\n  break;\n  }\n\nstackptr = STACK(stackptr);\nstacktop = STACK(stacktop);\n\nstatus.tmp_regs[0] = TMP1;\nstatus.saved_tmp_regs[0] = TMP1;\n\nif (base_reg != TMP2)\n  {\n  status.tmp_regs[1] = TMP2;\n  status.saved_tmp_regs[1] = TMP2;\n  }\nelse\n  {\n  status.saved_tmp_regs[1] = RETURN_ADDR;\n  if (HAS_VIRTUAL_REGISTERS)\n    status.tmp_regs[1] = STR_PTR;\n  else\n    status.tmp_regs[1] = RETURN_ADDR;\n  }\n\nstatus.saved_tmp_regs[2] = TMP3;\nif (HAS_VIRTUAL_REGISTERS)\n  status.tmp_regs[2] = STR_END;\nelse\n  status.tmp_regs[2] = TMP3;\n\ndelayed_mem_copy_init(&status, common);\n\nif (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)\n  {\n  SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);\n\n  if (!from_sp)\n    delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->recursive_head_ptr);\n\n  if (from_sp || type == recurse_swap_global)\n    delayed_mem_copy_move(&status, SLJIT_SP, common->recursive_head_ptr, base_reg, stackptr);\n  }\n\nstackptr += sizeof(sljit_sw);\n\n#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD\nif (type != recurse_copy_shared_to_global)\n  {\n  if (!from_sp)\n    delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->control_head_ptr);\n\n  if (from_sp || type == recurse_swap_global)\n    delayed_mem_copy_move(&status, SLJIT_SP, common->control_head_ptr, base_reg, stackptr);\n  }\n\nstackptr += sizeof(sljit_sw);\n#endif\n\nwhile (cc < ccend)\n  {\n  private_count = 0;\n  shared_count = 0;\n  kept_shared_count = 0;\n\n  switch(*cc)\n    {\n    case OP_SET_SOM:\n    SLJIT_ASSERT(common->has_set_som);\n    if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, OVECTOR(0)))\n      {\n      kept_shared_srcw[0] = OVECTOR(0);\n      kept_shared_count = 1;\n      }\n    cc += 1;\n    break;\n\n    case OP_RECURSE:\n    if (recurse_flags & recurse_flag_quit_found)\n      {\n      if (common->has_set_som && recurse_check_bit(common, OVECTOR(0)))\n        {\n        kept_shared_srcw[0] = OVECTOR(0);\n        kept_shared_count = 1;\n        }\n      if (common->mark_ptr != 0 && recurse_check_bit(common, common->mark_ptr))\n        {\n        kept_shared_srcw[kept_shared_count] = common->mark_ptr;\n        kept_shared_count++;\n        }\n      }\n\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      {\n      shared_srcw[0] = common->capture_last_ptr;\n      shared_count = 1;\n      }\n\n    cc += 1 + LINK_SIZE;\n    if (*cc == OP_CREF)\n      recurse_flags |= recurse_flag_recurse_arg;\n    break;\n\n    case OP_KET:\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0)\n      {\n      if (recurse_check_bit(common, private_srcw[0]))\n        private_count = 1;\n      SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);\n      cc += PRIVATE_DATA(cc + 1);\n      }\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_BRAPOS:\n    case OP_SBRA:\n    case OP_SBRAPOS:\n    case OP_SCOND:\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (recurse_check_bit(common, private_srcw[0]))\n      private_count = 1;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CREF:\n    if ((recurse_flags & recurse_flag_recurse_arg) != 0)\n      {\n      offset = GET2(cc, 1);\n      shared_srcw[0] = OVECTOR(offset << 1);\n      if (recurse_check_bit(common, shared_srcw[0]))\n        {\n        shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);\n        SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));\n        shared_count = 2;\n        }\n\n      if (cc[1 + IMM2_SIZE] != OP_CREF)\n        recurse_flags &= ~(uint32_t)recurse_flag_recurse_arg;\n      }\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_ASSERT_SCS:\n    private_srcw[0] = PRIVATE_DATA(cc);\n    private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n    if (recurse_check_bit(common, private_srcw[0]))\n      private_count = 2;\n    cc += 1 + LINK_SIZE;\n    break;\n\n    case OP_CBRA:\n    case OP_SCBRA:\n    offset = GET2(cc, 1 + LINK_SIZE);\n    shared_srcw[0] = OVECTOR(offset << 1);\n    if (recurse_check_bit(common, shared_srcw[0]))\n      {\n      shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));\n      shared_count = 2;\n      }\n\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      {\n      shared_srcw[shared_count] = common->capture_last_ptr;\n      shared_count++;\n      }\n\n    if (!is_optimized_cbracket(common, offset))\n      {\n      private_srcw[0] = OVECTOR_PRIV(offset);\n      if (recurse_check_bit(common, private_srcw[0]))\n        private_count = 1;\n      }\n\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    offset = GET2(cc, 1 + LINK_SIZE);\n    shared_srcw[0] = OVECTOR(offset << 1);\n    if (recurse_check_bit(common, shared_srcw[0]))\n      {\n      shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));\n      shared_count = 2;\n      }\n\n    if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))\n      {\n      shared_srcw[shared_count] = common->capture_last_ptr;\n      shared_count++;\n      }\n\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (recurse_check_bit(common, private_srcw[0]))\n      private_count = 1;\n\n    offset = OVECTOR_PRIV(offset);\n    if (recurse_check_bit(common, offset))\n      {\n      private_srcw[private_count] = offset;\n      private_count++;\n      }\n    cc += 1 + LINK_SIZE + IMM2_SIZE;\n    break;\n\n    case OP_COND:\n    /* Might be a hidden SCOND. */\n    alternative = cc + GET(cc, 1);\n    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)\n      {\n      private_srcw[0] = PRIVATE_DATA(cc);\n      if (recurse_check_bit(common, private_srcw[0]))\n        private_count = 1;\n      }\n    cc += 1 + LINK_SIZE;\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_1\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      private_count = 1;\n    cc += 2;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2A\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      {\n      private_count = 2;\n      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));\n      }\n    cc += 2;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_PRIVATE_DATA_2B\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      {\n      private_count = 2;\n      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));\n      }\n    cc += 2 + IMM2_SIZE;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_1\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      private_count = 1;\n    cc += 1;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      {\n      private_count = 2;\n      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));\n      }\n    cc += 1;\n    break;\n\n    CASE_ITERATOR_TYPE_PRIVATE_DATA_2B\n    private_srcw[0] = PRIVATE_DATA(cc);\n    if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))\n      {\n      private_count = 2;\n      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n      SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));\n      }\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_CLASS:\n    case OP_NCLASS:\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n    case OP_XCLASS:\n    case OP_ECLASS:\n    i = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);\n#else\n    i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);\n#endif\n    if (PRIVATE_DATA(cc) != 0)\n      {\n      private_count = 1;\n      private_srcw[0] = PRIVATE_DATA(cc);\n      switch(get_class_iterator_size(cc + i))\n        {\n        case 1:\n        break;\n\n        case 2:\n        if (recurse_check_bit(common, private_srcw[0]))\n          {\n          private_count = 2;\n          private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);\n          SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));\n          }\n        break;\n\n        default:\n        SLJIT_UNREACHABLE();\n        break;\n        }\n      }\n    cc += i;\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_THEN_ARG:\n    SLJIT_ASSERT(common->mark_ptr != 0);\n    if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, common->mark_ptr))\n      {\n      kept_shared_srcw[0] = common->mark_ptr;\n      kept_shared_count = 1;\n      }\n    if (common->control_head_ptr != 0 && recurse_check_bit(common, common->control_head_ptr))\n      {\n      private_srcw[0] = common->control_head_ptr;\n      private_count = 1;\n      }\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_THEN:\n    SLJIT_ASSERT(common->control_head_ptr != 0);\n    if (recurse_check_bit(common, common->control_head_ptr))\n      {\n      private_srcw[0] = common->control_head_ptr;\n      private_count = 1;\n      }\n    cc++;\n    break;\n\n    default:\n    cc = next_opcode(common, cc);\n    SLJIT_ASSERT(cc != NULL);\n    continue;\n    }\n\n  if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)\n    {\n    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);\n\n    for (i = 0; i < private_count; i++)\n      {\n      SLJIT_ASSERT(private_srcw[i] != 0);\n\n      if (!from_sp)\n        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)private_srcw[i]);\n\n      if (from_sp || type == recurse_swap_global)\n        delayed_mem_copy_move(&status, SLJIT_SP, private_srcw[i], base_reg, stackptr);\n\n      stackptr += sizeof(sljit_sw);\n      }\n    }\n  else\n    stackptr += sizeof(sljit_sw) * private_count;\n\n  if (type != recurse_copy_private_to_global && type != recurse_copy_kept_shared_to_global)\n    {\n    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_swap_global);\n\n    for (i = 0; i < shared_count; i++)\n      {\n      SLJIT_ASSERT(shared_srcw[i] != 0);\n\n      if (!from_sp)\n        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)shared_srcw[i]);\n\n      if (from_sp || type == recurse_swap_global)\n        delayed_mem_copy_move(&status, SLJIT_SP, shared_srcw[i], base_reg, stackptr);\n\n      stackptr += sizeof(sljit_sw);\n      }\n    }\n  else\n    stackptr += sizeof(sljit_sw) * shared_count;\n\n  if (type != recurse_copy_private_to_global && type != recurse_swap_global)\n    {\n    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_copy_kept_shared_to_global);\n\n    for (i = 0; i < kept_shared_count; i++)\n      {\n      SLJIT_ASSERT(kept_shared_srcw[i] != 0);\n\n      if (!from_sp)\n        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)kept_shared_srcw[i]);\n\n      if (from_sp || type == recurse_swap_global)\n        delayed_mem_copy_move(&status, SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);\n\n      stackptr += sizeof(sljit_sw);\n      }\n    }\n  else\n    stackptr += sizeof(sljit_sw) * kept_shared_count;\n  }\n\nSLJIT_ASSERT(cc == ccend && stackptr == stacktop);\n\ndelayed_mem_copy_finish(&status);\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)\n{\nPCRE2_SPTR end = bracketend(cc);\nBOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;\n\n/* Assert captures *THEN verb even if it has no alternatives. */\nif (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)\n  current_offset = NULL;\nelse if (*cc >= OP_ASSERT_NA && *cc <= OP_ASSERT_SCS)\n  has_alternatives = TRUE;\n/* Conditional block does never capture. */\nelse if (*cc == OP_COND || *cc == OP_SCOND)\n  has_alternatives = FALSE;\n\ncc = next_opcode(common, cc);\n\nif (has_alternatives)\n  {\n  switch (*cc)\n    {\n    case OP_REVERSE:\n    case OP_CREF:\n      cc += 1 + IMM2_SIZE;\n      break;\n    case OP_VREVERSE:\n    case OP_DNCREF:\n      cc += 1 + 2 * IMM2_SIZE;\n      break;\n    }\n\n  current_offset = common->then_offsets + (cc - common->start);\n  }\n\nwhile (cc < end)\n  {\n  if (*cc >= OP_ASSERT && *cc <= OP_SCOND)\n    {\n    cc = set_then_offsets(common, cc, current_offset);\n    continue;\n    }\n\n  if (*cc == OP_ALT && has_alternatives)\n    {\n    cc += 1 + LINK_SIZE;\n\n    if (*cc == OP_REVERSE)\n      cc += 1 + IMM2_SIZE;\n    else if (*cc == OP_VREVERSE)\n      cc += 1 + 2 * IMM2_SIZE;\n\n    current_offset = common->then_offsets + (cc - common->start);\n    continue;\n    }\n\n  if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)\n    *current_offset = 1;\n  cc = next_opcode(common, cc);\n  }\n\ncc = end - 1 - LINK_SIZE;\n\n/* Ignore repeats. */\nif (*cc == OP_KET && PRIVATE_DATA(cc) != 0)\n  end += PRIVATE_DATA(cc + 1);\n\nreturn end;\n}\n\n#undef CASE_ITERATOR_PRIVATE_DATA_1\n#undef CASE_ITERATOR_PRIVATE_DATA_2A\n#undef CASE_ITERATOR_PRIVATE_DATA_2B\n#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1\n#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A\n#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B\n\nstatic SLJIT_INLINE BOOL is_powerof2(unsigned int value)\n{\nreturn (value & (value - 1)) == 0;\n}\n\nstatic SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)\n{\nwhile (list != NULL)\n  {\n  /* sljit_set_label is clever enough to do nothing\n  if either the jump or the label is NULL. */\n  SET_LABEL(list->jump, label);\n  list = list->next;\n  }\n}\n\nstatic SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)\n{\njump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));\nif (list_item)\n  {\n  list_item->next = *list;\n  list_item->jump = jump;\n  *list = list_item;\n  }\n}\n\nstatic void add_stub(compiler_common *common, struct sljit_jump *start)\n{\nDEFINE_COMPILER;\nstub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));\n\nif (list_item)\n  {\n  list_item->start = start;\n  list_item->quit = LABEL();\n  list_item->next = common->stubs;\n  common->stubs = list_item;\n  }\n}\n\nstatic void flush_stubs(compiler_common *common)\n{\nDEFINE_COMPILER;\nstub_list *list_item = common->stubs;\n\nwhile (list_item)\n  {\n  JUMPHERE(list_item->start);\n  add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));\n  JUMPTO(SLJIT_JUMP, list_item->quit);\n  list_item = list_item->next;\n  }\ncommon->stubs = NULL;\n}\n\nstatic SLJIT_INLINE void count_match(compiler_common *common)\n{\nDEFINE_COMPILER;\n\nOP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);\nadd_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));\n}\n\nstatic SLJIT_INLINE void allocate_stack(compiler_common *common, sljit_s32 size)\n{\n/* May destroy all locals and registers except TMP2. */\nDEFINE_COMPILER;\n\nSLJIT_ASSERT(size > 0);\nOP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw));\n#ifdef DESTROY_REGISTERS\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);\nOP1(SLJIT_MOV, TMP3, 0, TMP1, 0);\nOP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\nSLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw));\n/* These two are also used by the stackalloc calls. */\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP1, 0);\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP1, 0);\n#endif\n#endif\nadd_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));\n}\n\nstatic SLJIT_INLINE void free_stack(compiler_common *common, sljit_s32 size)\n{\nDEFINE_COMPILER;\n\nSLJIT_ASSERT(size > 0);\nOP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw));\n}\n\nstatic sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)\n{\nDEFINE_COMPILER;\nsljit_uw *result;\n\nif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n  return NULL;\n\nresult = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);\nif (SLJIT_UNLIKELY(result == NULL))\n  {\n  sljit_set_compiler_memory_error(compiler);\n  return NULL;\n  }\n\n*(void**)result = common->read_only_data_head;\ncommon->read_only_data_head = (void *)result;\nreturn result + 1;\n}\n\nstatic SLJIT_INLINE void reset_ovector(compiler_common *common, int length)\n{\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nsljit_s32 i;\n\n/* At this point we can freely use all temporary registers. */\nSLJIT_ASSERT(length > 1);\n/* TMP1 returns with begin - 1. */\nOP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));\nif (length < 8)\n  {\n  for (i = 1; i < length; i++)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);\n  }\nelse\n  {\n  if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)\n    {\n    GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);\n    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);\n    loop = LABEL();\n    sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));\n    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, loop);\n    }\n  else\n    {\n    GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);\n    loop = LABEL();\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);\n    OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));\n    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, loop);\n    }\n  }\n}\n\nstatic SLJIT_INLINE void reset_early_fail(compiler_common *common)\n{\nDEFINE_COMPILER;\nsljit_u32 size = (sljit_u32)(common->early_fail_end_ptr - common->early_fail_start_ptr);\nsljit_u32 uncleared_size;\nsljit_s32 src = SLJIT_IMM;\nsljit_s32 i;\nstruct sljit_label *loop;\n\nSLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr);\n\nif (size == sizeof(sljit_sw))\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->early_fail_start_ptr, SLJIT_IMM, 0);\n  return;\n  }\n\nif (sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER))\n  {\n  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);\n  src = TMP3;\n  }\n\nif (size <= 6 * sizeof(sljit_sw))\n  {\n  for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i += sizeof(sljit_sw))\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0);\n  return;\n  }\n\nGET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr);\n\nuncleared_size = ((size / sizeof(sljit_sw)) % 3) * sizeof(sljit_sw);\n\nOP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - uncleared_size);\n\nloop = LABEL();\nOP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));\nOP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * SSIZE_OF(sw), src, 0);\nOP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * SSIZE_OF(sw), src, 0);\nCMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop);\n\nif (uncleared_size >= sizeof(sljit_sw))\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);\n\nif (uncleared_size >= 2 * sizeof(sljit_sw))\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0);\n}\n\nstatic SLJIT_INLINE void do_reset_match(compiler_common *common, int length)\n{\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nint i;\n\nSLJIT_ASSERT(length > 1);\n/* OVECTOR(1) contains the \"string begin - 1\" constant. */\nif (length > 2)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));\nif (length < 8)\n  {\n  for (i = 2; i < length; i++)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);\n  }\nelse\n  {\n  if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)\n    {\n    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);\n    loop = LABEL();\n    sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n    OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, loop);\n    }\n  else\n    {\n    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);\n    loop = LABEL();\n    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);\n    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));\n    OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, loop);\n    }\n  }\n\nif (!HAS_VIRTUAL_REGISTERS)\n  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, stack));\nelse\n  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);\n\nif (common->mark_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);\nif (common->control_head_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);\nif (HAS_VIRTUAL_REGISTERS)\n  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);\nOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));\n}\n\nstatic sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)\n{\nwhile (current != NULL)\n  {\n  switch (current[1])\n    {\n    case type_then_trap:\n    break;\n\n    case type_mark:\n    if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[2]) == 0)\n      return current[3];\n    break;\n\n    default:\n    SLJIT_UNREACHABLE();\n    break;\n    }\n  SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);\n  current = (sljit_sw*)current[0];\n  }\nreturn 0;\n}\n\nstatic SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)\n{\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nBOOL has_pre;\n\n/* At this point we can freely use all registers. */\nOP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);\n  if (common->mark_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);\n  OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);\n  if (common->mark_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);\n  OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),\n    SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));\n  }\nelse\n  {\n  OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);\n  OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, match_data));\n  if (common->mark_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);\n  OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, oveccount));\n  OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);\n  if (common->mark_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R0, 0);\n  OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));\n  }\n\nhas_pre = sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;\n\nGET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));\nOP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? SLJIT_R0 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n\nloop = LABEL();\n\nif (has_pre)\n  sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));\nelse\n  {\n  OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);\n  OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));\n  }\n\nOP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(PCRE2_SIZE));\nOP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);\n/* Copy the integer value to the output buffer */\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\nOP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\n\nSLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8);\nOP1(((sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV), SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);\n\nOP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);\nJUMPTO(SLJIT_NOT_ZERO, loop);\n\n/* Calculate the return value, which is the maximum ovector value. */\nif (topbracket > 1)\n  {\n  if (sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * SSIZE_OF(sw))) == SLJIT_SUCCESS)\n    {\n    GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);\n\n    /* OVECTOR(0) is never equal to SLJIT_S2. */\n    loop = LABEL();\n    sljit_emit_mem_update(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * SSIZE_OF(sw)));\n    OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);\n    CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);\n    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);\n    }\n  else\n    {\n    GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);\n\n    /* OVECTOR(0) is never equal to SLJIT_S2. */\n    loop = LABEL();\n    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);\n    OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));\n    OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);\n    CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);\n    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);\n    }\n  }\nelse\n  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);\n}\n\nstatic SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)\n{\nDEFINE_COMPILER;\nsljit_s32 mov_opcode;\nsljit_s32 arguments_reg = !HAS_VIRTUAL_REGISTERS ? ARGUMENTS : SLJIT_R1;\n\nSLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);\nSLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0\n  && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));\n\nif (arguments_reg != ARGUMENTS)\n  OP1(SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0);\nOP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),\n  common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);\nOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);\n\n/* Store match begin and end. */\nOP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, begin));\nOP1(SLJIT_MOV, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);\nOP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, match_data));\n\nmov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;\n\nOP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S1, 0);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\nOP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\nOP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);\n\nOP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S1, 0);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\nOP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\nOP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0);\n\nJUMPTO(SLJIT_JUMP, quit);\n}\n\nstatic SLJIT_INLINE void check_start_used_ptr(compiler_common *common)\n{\n/* May destroy TMP1. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nif (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  /* The value of -1 must be kept for start_used_ptr! */\n  OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);\n  /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting\n  is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */\n  jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n  JUMPHERE(jump);\n  }\nelse if (common->mode == PCRE2_JIT_PARTIAL_HARD)\n  {\n  jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n  JUMPHERE(jump);\n  }\n}\n\nstatic SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc)\n{\n/* Detects if the character has an othercase. */\nunsigned int c;\n\n#ifdef SUPPORT_UNICODE\nif (common->utf || common->ucp)\n  {\n  if (common->utf)\n    {\n    GETCHAR(c, cc);\n    }\n  else\n    c = *cc;\n\n  if (c > 127)\n    return c != UCD_OTHERCASE(c);\n\n  return common->fcc[c] != c;\n  }\nelse\n#endif\n  c = *cc;\nreturn MAX_255(c) ? common->fcc[c] != c : FALSE;\n}\n\nstatic SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)\n{\n/* Returns with the othercase. */\n#ifdef SUPPORT_UNICODE\nif ((common->utf || common->ucp) && c > 127)\n  return UCD_OTHERCASE(c);\n#endif\nreturn TABLE_GET(c, common->fcc, c);\n}\n\nstatic unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc)\n{\n/* Detects if the character and its othercase has only 1 bit difference. */\nunsigned int c, oc, bit;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nint n;\n#endif\n\n#ifdef SUPPORT_UNICODE\nif (common->utf || common->ucp)\n  {\n  if (common->utf)\n    {\n    GETCHAR(c, cc);\n    }\n  else\n    c = *cc;\n\n  if (c <= 127)\n    oc = common->fcc[c];\n  else\n    oc = UCD_OTHERCASE(c);\n  }\nelse\n  {\n  c = *cc;\n  oc = TABLE_GET(c, common->fcc, c);\n  }\n#else\nc = *cc;\noc = TABLE_GET(c, common->fcc, c);\n#endif\n\nSLJIT_ASSERT(c != oc);\n\nbit = c ^ oc;\n\n#ifndef EBCDIC\n/* Optimized for English alphabet. */\nif (c <= 127 && bit == 0x20)\n  return (0 << 8) | 0x20;\n#endif\n\n/* Since c != oc, they must have at least 1 bit difference. */\nif (!is_powerof2(bit))\n  return 0;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n\n#ifdef SUPPORT_UNICODE\nif (common->utf && c > 127)\n  {\n  n = GET_EXTRALEN(*cc);\n  while ((bit & 0x3f) == 0)\n    {\n    n--;\n    bit >>= 6;\n    }\n  return (n << 8) | bit;\n  }\n#endif /* SUPPORT_UNICODE */\nreturn (0 << 8) | bit;\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n\n#ifdef SUPPORT_UNICODE\nif (common->utf && c > 65535)\n  {\n  if (bit >= (1u << 10))\n    bit >>= 10;\n  else\n    return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));\n  }\n#endif /* SUPPORT_UNICODE */\nreturn (bit < 256) ? ((0u << 8) | bit) : ((1u << 8) | (bit >> 8));\n\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n}\n\nstatic void check_partial(compiler_common *common, BOOL force)\n{\n/* Checks whether a partial matching is occurred. Does not modify registers. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump = NULL;\n\nSLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);\n\nif (common->mode == PCRE2_JIT_COMPLETE)\n  return;\n\nif (!force && !common->allow_empty_partial)\n  jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\nelse if (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);\n\nif (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);\nelse\n  {\n  if (common->partialmatchlabel != NULL)\n    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);\n  else\n    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));\n  }\n\nif (jump != NULL)\n  JUMPHERE(jump);\n}\n\nstatic void check_str_end(compiler_common *common, jump_list **end_reached)\n{\n/* Does not affect registers. Usually used in a tight spot. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nif (common->mode == PCRE2_JIT_COMPLETE)\n  {\n  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  return;\n  }\n\njump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);\n  add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));\n  }\nelse\n  {\n  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));\n  if (common->partialmatchlabel != NULL)\n    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);\n  else\n    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));\n  }\nJUMPHERE(jump);\n}\n\nstatic void detect_partial_match(compiler_common *common, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nif (common->mode == PCRE2_JIT_COMPLETE)\n  {\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  return;\n  }\n\n/* Partial matching mode. */\njump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);\nif (!common->allow_empty_partial)\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));\nelse if (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1));\n\nif (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);\n  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n  }\nelse\n  {\n  if (common->partialmatchlabel != NULL)\n    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);\n  else\n    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));\n  }\nJUMPHERE(jump);\n}\n\nstatic void process_partial_match(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\n/* Partial matching mode. */\nif (common->mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);\n  JUMPHERE(jump);\n  }\nelse if (common->mode == PCRE2_JIT_PARTIAL_HARD)\n  {\n  if (common->partialmatchlabel != NULL)\n    CMPTO(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0, common->partialmatchlabel);\n  else\n    add_jump(compiler, &common->partialmatch, CMP(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));\n  }\n}\n\nstatic void detect_partial_match_to(compiler_common *common, struct sljit_label *label)\n{\nDEFINE_COMPILER;\n\nCMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, label);\nprocess_partial_match(common);\n}\n\nstatic void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks)\n{\n/* Reads the character into TMP1, keeps STR_PTR.\nDoes not check STR_END. TMP2, dst, RETURN_ADDR Destroyed. */\nDEFINE_COMPILER;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_jump *jump;\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */\n\nSLJIT_UNUSED_ARG(max);\nSLJIT_UNUSED_ARG(dst);\nSLJIT_UNUSED_ARG(dstw);\nSLJIT_UNUSED_ARG(backtracks);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n  if (max < 128) return;\n\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);\n  OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, common->invalid_utf ? &common->utfreadchar_invalid : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));\n  OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);\n  if (backtracks && common->invalid_utf)\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n  JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utf)\n  {\n  if (max < 0xd800) return;\n\n  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n\n  if (common->invalid_utf)\n    {\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);\n    OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));\n    OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);\n    if (backtracks && common->invalid_utf)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    }\n  else\n    {\n    /* TMP2 contains the high surrogate. */\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\n    }\n\n  JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nif (common->invalid_utf)\n  {\n  if (max < 0xd800) return;\n\n  if (backtracks != NULL)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));\n    }\n  else\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);\n    SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);\n    SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n    }\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n#endif /* SUPPORT_UNICODE */\n}\n\nstatic void peek_char_back(compiler_common *common, sljit_u32 max, jump_list **backtracks)\n{\n/* Reads one character back without moving STR_PTR. TMP2 must\ncontain the start of the subject buffer. Affects TMP1, TMP2, and RETURN_ADDR. */\nDEFINE_COMPILER;\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_jump *jump;\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */\n\nSLJIT_UNUSED_ARG(max);\nSLJIT_UNUSED_ARG(backtracks);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n  if (max < 128) return;\n\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);\n  if (common->invalid_utf)\n    {\n    add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    }\n  else\n    add_jump(compiler, &common->utfpeakcharback, JUMP(SLJIT_FAST_CALL));\n  JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utf)\n  {\n  if (max < 0xd800) return;\n\n  if (common->invalid_utf)\n    {\n    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);\n    add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    }\n  else\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xdc00);\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xdc00);\n    /* TMP2 contains the low surrogate. */\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\n    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\n    }\n    JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nif (common->invalid_utf)\n  {\n  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));\n  add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n#endif /* SUPPORT_UNICODE */\n}\n\n#define READ_CHAR_UPDATE_STR_PTR 0x1\n#define READ_CHAR_UTF8_NEWLINE 0x2\n#define READ_CHAR_NEWLINE (READ_CHAR_UPDATE_STR_PTR | READ_CHAR_UTF8_NEWLINE)\n#define READ_CHAR_VALID_UTF 0x4\n\nstatic void read_char(compiler_common *common, sljit_u32 min, sljit_u32 max,\n  jump_list **backtracks, sljit_u32 options)\n{\n/* Reads the precise value of a character into TMP1, if the character is\nbetween min and max (c >= min && c <= max). Otherwise it returns with a value\noutside the range. Does not check STR_END. */\nDEFINE_COMPILER;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_jump *jump;\n#endif\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nstruct sljit_jump *jump2;\n#endif\n\nSLJIT_UNUSED_ARG(min);\nSLJIT_UNUSED_ARG(max);\nSLJIT_UNUSED_ARG(backtracks);\nSLJIT_UNUSED_ARG(options);\nSLJIT_ASSERT(min <= max);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n  if (max < 128 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;\n\n  if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))\n    {\n    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);\n\n    if (options & READ_CHAR_UTF8_NEWLINE)\n      add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));\n    else\n      add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));\n\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    JUMPHERE(jump);\n    return;\n    }\n\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);\n  if (min >= 0x10000)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));\n    if (!(options & READ_CHAR_UPDATE_STR_PTR))\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    JUMPHERE(jump2);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);\n    }\n  else if (min >= 0x800 && max <= 0xffff)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    if (!(options & READ_CHAR_UPDATE_STR_PTR))\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    JUMPHERE(jump2);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);\n    }\n  else if (max >= 0x800)\n    {\n    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));\n    }\n  else if (max < 128)\n    {\n    OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n    }\n  else\n    {\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    if (!(options & READ_CHAR_UPDATE_STR_PTR))\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    else\n      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);\n    }\n  JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utf)\n  {\n  if (max < 0xd800 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;\n\n  if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);\n\n    if (options & READ_CHAR_UTF8_NEWLINE)\n      add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));\n    else\n      add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));\n\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    JUMPHERE(jump);\n    return;\n    }\n\n  if (max >= 0x10000)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);\n    /* TMP2 contains the high surrogate. */\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\n    JUMPHERE(jump);\n    return;\n    }\n\n  /* Skip low surrogate if necessary. */\n  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n\n  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)\n    {\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR);\n    if (max >= 0xd800)\n      SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000, TMP1);\n    }\n  else\n    {\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);\n    if (options & READ_CHAR_UPDATE_STR_PTR)\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    if (max >= 0xd800)\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);\n    JUMPHERE(jump);\n    }\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nif (common->invalid_utf)\n  {\n  if (backtracks != NULL)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));\n    }\n  else\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);\n    SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);\n    SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n    }\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n#endif /* SUPPORT_UNICODE */\n}\n\nstatic void skip_valid_char(compiler_common *common)\n{\nDEFINE_COMPILER;\n#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\nstruct sljit_jump *jump;\n#endif\n\n#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)\n  if (common->utf)\n    {\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);\n    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);\n    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800);\n    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n    JUMPHERE(jump);\n    return;\n    }\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n}\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n\nstatic BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)\n{\n/* Tells whether the character codes below 128 are enough\nto determine a match. */\nconst sljit_u8 value = nclass ? 0xff : 0;\nconst sljit_u8 *end = bitset + 32;\n\nbitset += 16;\ndo\n  {\n  if (*bitset++ != value)\n    return FALSE;\n  }\nwhile (bitset < end);\nreturn TRUE;\n}\n\nstatic void read_char7_type(compiler_common *common, jump_list **backtracks, BOOL negated)\n{\n/* Reads the precise character type of a character into TMP1, if the character\nis less than 128. Otherwise it returns with zero. Does not check STR_END. The\nfull_read argument tells whether characters above max are accepted or not. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nSLJIT_ASSERT(common->utf);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n/* All values > 127 are zero in ctypes. */\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\n\nif (negated)\n  {\n  jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);\n\n  if (common->invalid_utf)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, TMP2, 0);\n    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\n    }\n  else\n    {\n    OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n    }\n  JUMPHERE(jump);\n  }\n}\n\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */\n\nstatic void read_char8_type(compiler_common *common, jump_list **backtracks, BOOL negated)\n{\n/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */\nDEFINE_COMPILER;\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\nstruct sljit_jump *jump;\n#endif\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nstruct sljit_jump *jump2;\n#endif\n\nSLJIT_UNUSED_ARG(backtracks);\nSLJIT_UNUSED_ARG(negated);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n  /* The result of this read may be unused, but saves an \"else\" part. */\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\n  jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);\n\n  if (!negated)\n    {\n    if (common->invalid_utf)\n      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);\n    if (common->invalid_utf)\n      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe0 - 0xc2));\n\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\n    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);\n    if (common->invalid_utf)\n      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40));\n\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\n    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);\n    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\n    JUMPHERE(jump2);\n    }\n  else if (common->invalid_utf)\n    {\n    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));\n    OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));\n\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\n    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);\n    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\n    JUMPHERE(jump2);\n    }\n  else\n    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));\n\n  JUMPHERE(jump);\n  return;\n  }\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32\nif (common->invalid_utf && negated)\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x110000));\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n/* The ctypes array contains only 256 values. */\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\njump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);\n#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\n#if PCRE2_CODE_UNIT_WIDTH != 8\nJUMPHERE(jump);\n#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utf && negated)\n  {\n  /* Skip low surrogate if necessary. */\n  if (!common->invalid_utf)\n    {\n    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);\n\n    if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)\n      {\n      OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n      OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);\n      SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR);\n      }\n    else\n      {\n      jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n      JUMPHERE(jump);\n      }\n    return;\n    }\n\n  OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);\n  jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));\n\n  JUMPHERE(jump);\n  return;\n  }\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */\n}\n\nstatic void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid)\n{\n/* Goes one character back. Affects STR_PTR and TMP1. If must_be_valid is TRUE,\nTMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer,\nand it is destroyed. Does not modify STR_PTR for invalid character sequences. */\nDEFINE_COMPILER;\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_jump *jump;\n#endif\n\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\nstruct sljit_label *label;\n\nif (common->utf)\n  {\n  if (!must_be_valid && common->invalid_utf)\n    {\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);\n    add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));\n    JUMPHERE(jump);\n    return;\n    }\n\n  label = LABEL();\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);\n  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);\n  return;\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utf)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  if (!must_be_valid && common->invalid_utf)\n    {\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n    jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0xd800);\n    add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));\n    if (backtracks != NULL)\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));\n    JUMPHERE(jump);\n    return;\n    }\n\n  /* Skip low surrogate if necessary. */\n  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xdc00);\n  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  return;\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nif (common->invalid_utf && !must_be_valid)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));\n  if (backtracks != NULL)\n    {\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    return;\n    }\n\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x110000);\n  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);\n  OP2(SLJIT_SHL,  TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  return;\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */\n#endif /* SUPPORT_UNICODE */\n\nSLJIT_UNUSED_ARG(backtracks);\nSLJIT_UNUSED_ARG(must_be_valid);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n}\n\nstatic void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)\n{\n/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nif (nltype == NLTYPE_ANY)\n  {\n  add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));\n  sljit_set_current_flags(compiler, SLJIT_SET_Z);\n  add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));\n  }\nelse if (nltype == NLTYPE_ANYCRLF)\n  {\n  if (jumpifmatch)\n    {\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));\n    }\n  else\n    {\n    jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));\n    JUMPHERE(jump);\n    }\n  }\nelse\n  {\n  SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);\n  add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));\n  }\n}\n\n#ifdef SUPPORT_UNICODE\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nstatic void do_utfreadchar(compiler_common *common)\n{\n/* Fast decoding a UTF-8 character. TMP1 contains the first byte\nof the character (>= 0xc0). Return char value in TMP1. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\n/* Searching for the first zero. */\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);\njump = JUMP(SLJIT_NOT_ZERO);\n/* Two byte sequence. */\nOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);\njump = JUMP(SLJIT_NOT_ZERO);\n/* Three byte sequence. */\nOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Four byte sequence. */\nJUMPHERE(jump);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));\nOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0000);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfreadtype8(compiler_common *common)\n{\n/* Fast decoding a UTF-8 character type. TMP2 contains the first byte\nof the character (>= 0xc0). Return value in TMP1. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_jump *compare;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0x20);\njump = JUMP(SLJIT_NOT_ZERO);\n/* Two byte sequence. */\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);\n/* The upper 5 bits are known at this point. */\ncompare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\nOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);\nOP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(compare);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* We only have types for characters less than 256. */\nJUMPHERE(jump);\nOP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfreadchar_invalid(compiler_common *common)\n{\n/* Slow decoding a UTF-8 character. TMP1 contains the first byte\nof the character (>= 0xc0). Return char value in TMP1. STR_PTR is\nundefined for invalid characters. */\nDEFINE_COMPILER;\nsljit_s32 i;\nsljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);\nstruct sljit_jump *jump;\nstruct sljit_jump *buffer_end_close;\nstruct sljit_label *three_byte_entry;\nstruct sljit_label *exit_invalid_label;\nstruct sljit_jump *exit_invalid[11];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2);\n\n/* Usually more than 3 characters remained in the subject buffer. */\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));\n\n/* Not a valid start of a multi-byte sequence, no more bytes read. */\nexit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xf5 - 0xc2);\n\nbuffer_end_close = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);\njump = JUMP(SLJIT_NOT_ZERO);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump);\n\n/* Three-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n  SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000, TMP1);\n  exit_invalid[2] = NULL;\n  }\nelse\n  exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);\njump = JUMP(SLJIT_NOT_ZERO);\n\nthree_byte_entry = LABEL();\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n  SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800, TMP1);\n  exit_invalid[3] = NULL;\n  }\nelse\n  exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n  SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n  exit_invalid[4] = NULL;\n  }\nelse\n  exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump);\n\n/* Four-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n  SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0, TMP1);\n  exit_invalid[5] = NULL;\n  }\nelse\n  exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);\n  SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1);\n  exit_invalid[6] = NULL;\n  }\nelse\n  exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(buffer_end_close);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\nexit_invalid[7] = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);\n\n/* Two-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\n/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nexit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);\njump = JUMP(SLJIT_NOT_ZERO);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Three-byte sequence. */\nJUMPHERE(jump);\nexit_invalid[9] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n  SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n  exit_invalid[10] = NULL;\n  }\nelse\n  exit_invalid[10] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\n\n/* One will be substracted from STR_PTR later. */\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n\n/* Four byte sequences are not possible. */\nCMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x30000, three_byte_entry);\n\nexit_invalid_label = LABEL();\nfor (i = 0; i < 11; i++)\n  sljit_set_label(exit_invalid[i], exit_invalid_label);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfreadnewline_invalid(compiler_common *common)\n{\n/* Slow decoding a UTF-8 character, specialized for newlines.\nTMP1 contains the first byte of the character (>= 0xc0). Return\nchar value in TMP1. */\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nstruct sljit_label *skip_start;\nstruct sljit_label *three_byte_exit;\nstruct sljit_jump *jump[5];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nif (common->nltype != NLTYPE_ANY)\n  {\n  SLJIT_ASSERT(common->nltype != NLTYPE_FIXED || common->newline < 128);\n\n  /* All newlines are ascii, just skip intermediate octets. */\n  jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  loop = LABEL();\n  if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS)\n    sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n  else\n    {\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    }\n\n  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);\n  CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  JUMPHERE(jump[0]);\n\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\n  OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n  return;\n  }\n\njump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\njump[1] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xc2);\njump[2] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xe2);\n\nskip_start = LABEL();\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);\njump[3] = CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80);\n\n/* Skip intermediate octets. */\nloop = LABEL();\njump[4] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);\nCMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);\n\nJUMPHERE(jump[3]);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nthree_byte_exit = LABEL();\nJUMPHERE(jump[0]);\nJUMPHERE(jump[4]);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Two byte long newline: 0x85. */\nJUMPHERE(jump[1]);\nCMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x85, skip_start);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x85);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Three byte long newlines: 0x2028 and 0x2029. */\nJUMPHERE(jump[2]);\nCMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, skip_start);\nCMPTO(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0, three_byte_exit);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 0x80);\nCMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40, skip_start);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0x2000);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfmoveback_invalid(compiler_common *common)\n{\n/* Goes one character back. */\nDEFINE_COMPILER;\nsljit_s32 i;\nstruct sljit_jump *jump;\nstruct sljit_jump *buffer_start_close;\nstruct sljit_label *exit_ok_label;\nstruct sljit_label *exit_invalid_label;\nstruct sljit_jump *exit_invalid[7];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));\nexit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);\n\n/* Two-byte sequence. */\nbuffer_start_close = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);\njump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x20);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Three-byte sequence. */\nJUMPHERE(jump);\nexit_invalid[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);\njump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x10);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Four-byte sequence. */\nJUMPHERE(jump);\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);\nexit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0);\nexit_invalid[3] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x05);\n\nexit_ok_label = LABEL();\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\n/* Two-byte sequence. */\nJUMPHERE(buffer_start_close);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n\nexit_invalid[4] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);\nCMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20, exit_ok_label);\n\n/* Three-byte sequence. */\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nexit_invalid[5] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);\nexit_invalid[6] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);\nCMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10, exit_ok_label);\n\n/* Four-byte sequences are not possible. */\n\nexit_invalid_label = LABEL();\nsljit_set_label(exit_invalid[5], exit_invalid_label);\nsljit_set_label(exit_invalid[6], exit_invalid_label);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(exit_invalid[4]);\n/* -2 + 4 = 2 */\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n\nexit_invalid_label = LABEL();\nfor (i = 0; i < 4; i++)\n  sljit_set_label(exit_invalid[i], exit_invalid_label);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(4));\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfpeakcharback(compiler_common *common)\n{\n/* Peak a character back. Does not modify STR_PTR. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump[2];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);\njump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);\njump[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nJUMPHERE(jump[1]);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nJUMPHERE(jump[0]);\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfpeakcharback_invalid(compiler_common *common)\n{\n/* Peak a character back. Does not modify STR_PTR. */\nDEFINE_COMPILER;\nsljit_s32 i;\nsljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);\nstruct sljit_jump *jump[2];\nstruct sljit_label *two_byte_entry;\nstruct sljit_label *three_byte_entry;\nstruct sljit_label *exit_invalid_label;\nstruct sljit_jump *exit_invalid[8];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));\nexit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);\njump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);\n\n/* Two-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);\njump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x1e);\n\ntwo_byte_entry = LABEL();\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\n/* If TMP1 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump[1]);\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\n/* Three-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);\njump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x10);\n\nthree_byte_entry = LABEL();\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n  SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800, TMP1);\n  exit_invalid[2] = NULL;\n  }\nelse\n  exit_invalid[2] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n  SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1);\n  exit_invalid[3] = NULL;\n  }\nelse\n  exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump[1]);\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80);\nexit_invalid[4] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\n/* Four-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);\n/* ADD is used instead of OR because of the SUB 0x10000 above. */\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\n\nif (has_cmov)\n  {\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);\n  SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1);\n  exit_invalid[5] = NULL;\n  }\nelse\n  exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump[0]);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\njump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);\n\n/* Two-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);\nCMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);\n\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);\nexit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);\n\n/* Three-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);\nCMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x10, three_byte_entry);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump[0]);\nexit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0);\n\n/* Two-byte sequence. */\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);\nCMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);\n\nexit_invalid_label = LABEL();\nfor (i = 0; i < 8; i++)\n  sljit_set_label(exit_invalid[i], exit_invalid_label);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n\n#if PCRE2_CODE_UNIT_WIDTH == 16\n\nstatic void do_utfreadchar_invalid(compiler_common *common)\n{\n/* Slow decoding a UTF-16 character. TMP1 contains the first half\nof the character (>= 0xd800). Return char value in TMP1. STR_PTR is\nundefined for invalid characters. */\nDEFINE_COMPILER;\nstruct sljit_jump *exit_invalid[3];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n/* TMP2 contains the high surrogate. */\nexit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);\nexit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(exit_invalid[0]);\nJUMPHERE(exit_invalid[1]);\nJUMPHERE(exit_invalid[2]);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfreadnewline_invalid(compiler_common *common)\n{\n/* Slow decoding a UTF-16 character, specialized for newlines.\nTMP1 contains the first half of the character (>= 0xd800). Return\nchar value in TMP1. */\n\nDEFINE_COMPILER;\nstruct sljit_jump *exit_invalid[2];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n/* TMP2 contains the high surrogate. */\nexit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);\n\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);\nOP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(exit_invalid[0]);\nJUMPHERE(exit_invalid[1]);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfmoveback_invalid(compiler_common *common)\n{\n/* Goes one character back. */\nDEFINE_COMPILER;\nstruct sljit_jump *exit_invalid[3];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nexit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400);\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\nexit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(exit_invalid[0]);\nJUMPHERE(exit_invalid[1]);\nJUMPHERE(exit_invalid[2]);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_utfpeakcharback_invalid(compiler_common *common)\n{\n/* Peak a character back. Does not modify STR_PTR. */\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_jump *exit_invalid[3];\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\njump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000);\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\nexit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);\nexit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);\n\nOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);\nOP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);\nexit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);\n\nJUMPHERE(jump);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(exit_invalid[0]);\nJUMPHERE(exit_invalid[1]);\nJUMPHERE(exit_invalid[2]);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\n#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */\n\n/* UCD_BLOCK_SIZE must be 128 (see the assert below). */\n#define UCD_BLOCK_MASK 127\n#define UCD_BLOCK_SHIFT 7\n\nstatic void do_getucd(compiler_common *common)\n{\n/* Search the UCD record for the character comes in TMP1.\nReturns chartype in TMP1 and UCD offset in TMP2. */\nDEFINE_COMPILER;\n#if PCRE2_CODE_UNIT_WIDTH == 32\nstruct sljit_jump *jump;\n#endif\n\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\n/* dummy_ucd_record */\nconst ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR);\nSLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);\nSLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);\n#endif\n\nSLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12);\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (!common->utf)\n  {\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR);\n  JUMPHERE(jump);\n  }\n#endif\n\nOP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);\nOP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));\nOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);\nsljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));\nOP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_getucdtype(compiler_common *common)\n{\n/* Search the UCD record for the character comes in TMP1.\nReturns chartype in TMP1 and UCD offset in TMP2. */\nDEFINE_COMPILER;\n#if PCRE2_CODE_UNIT_WIDTH == 32\nstruct sljit_jump *jump;\n#endif\n\n#if defined SLJIT_DEBUG && SLJIT_DEBUG\n/* dummy_ucd_record */\nconst ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR);\nSLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);\nSLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);\n#endif\n\nSLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12);\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (!common->utf)\n  {\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR);\n  JUMPHERE(jump);\n  }\n#endif\n\nOP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);\nOP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));\nOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);\nsljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));\nOP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);\n\n/* TMP2 is multiplied by 12. Same as (TMP2 + (TMP2 << 1)) << 2. */\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));\nsljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP2, 0, TMP2, 0, TMP2, 0, 1);\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 2);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\n#endif /* SUPPORT_UNICODE */\n\nstatic SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_label *mainloop;\nstruct sljit_label *newlinelabel = NULL;\nstruct sljit_jump *start;\nstruct sljit_jump *end = NULL;\nstruct sljit_jump *end2 = NULL;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *loop;\nstruct sljit_jump *jump;\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */\njump_list *newline = NULL;\nsljit_u32 overall_options = common->re->overall_options;\nBOOL hascrorlf = (common->re->flags & PCRE2_HASCRORLF) != 0;\nBOOL newlinecheck = FALSE;\nBOOL readuchar = FALSE;\n\nif (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0)\n    && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))\n  newlinecheck = TRUE;\n\nSLJIT_ASSERT(common->abort_label == NULL);\n\nif ((overall_options & PCRE2_FIRSTLINE) != 0)\n  {\n  /* Search for the end of the first line. */\n  SLJIT_ASSERT(common->match_end_ptr != 0);\n  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n\n  if (common->nltype == NLTYPE_FIXED && common->newline > 255)\n    {\n    mainloop = LABEL();\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);\n    CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);\n    JUMPHERE(end);\n    OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    }\n  else\n    {\n    end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n    mainloop = LABEL();\n    /* Continual stores does not cause data dependency. */\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);\n    read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);\n    check_newlinechar(common, common->nltype, &newline, TRUE);\n    CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);\n    JUMPHERE(end);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);\n    set_jumps(newline, LABEL());\n    }\n\n  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n  }\nelse if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)\n  {\n  /* Check whether offset limit is set and valid. */\n  SLJIT_ASSERT(common->match_end_ptr != 0);\n\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));\n    }\n  else\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, offset_limit));\n\n  OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);\n  end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);\n  if (HAS_VIRTUAL_REGISTERS)\n    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);\n  else\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */\n  if (HAS_VIRTUAL_REGISTERS)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));\n\n  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);\n  end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);\n  OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);\n  JUMPHERE(end2);\n  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);\n  add_jump(compiler, &common->abort, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));\n  JUMPHERE(end);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);\n  }\n\nstart = JUMP(SLJIT_JUMP);\n\nif (newlinecheck)\n  {\n  newlinelabel = LABEL();\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, common->newline & 0xff);\n  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  end2 = JUMP(SLJIT_JUMP);\n  }\n\nmainloop = LABEL();\n\n/* Increasing the STR_PTR here requires one less jump in the most common case. */\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && !common->invalid_utf) readuchar = TRUE;\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */\nif (newlinecheck) readuchar = TRUE;\n\nif (readuchar)\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n\nif (newlinecheck)\n  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->invalid_utf)\n  {\n  /* Skip continuation code units. */\n  loop = LABEL();\n  jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);\n  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x40, loop);\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPHERE(jump);\n  }\nelse if (common->utf)\n  {\n  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  JUMPHERE(jump);\n  }\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (common->invalid_utf)\n  {\n  /* Skip continuation code units. */\n  loop = LABEL();\n  jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);\n  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400, loop);\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPHERE(jump);\n  }\nelse if (common->utf)\n  {\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);\n\n  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))\n    {\n    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);\n    SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR);\n    }\n  else\n    {\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);\n    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n    }\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */\n#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */\nJUMPHERE(start);\n\nif (newlinecheck)\n  {\n  JUMPHERE(end);\n  JUMPHERE(end2);\n  }\n\nreturn mainloop;\n}\n\n\nstatic SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, fast_forward_char_data *chars, BOOL last)\n{\nsljit_u32 i, count = chars->count;\n\nif (count == 255)\n  return;\n\nif (count == 0)\n  {\n  chars->count = 1;\n  chars->chars[0] = chr;\n\n  if (last)\n    chars->last_count = 1;\n  return;\n  }\n\nfor (i = 0; i < count; i++)\n  if (chars->chars[i] == chr)\n    return;\n\nif (count >= MAX_DIFF_CHARS)\n  {\n  chars->count = 255;\n  return;\n  }\n\nchars->chars[count] = chr;\nchars->count = count + 1;\n\nif (last)\n  chars->last_count++;\n}\n\n/* Value can be increased if needed. Patterns\nsuch as /(a|){33}b/ can exhaust the stack.\n\nNote: /(a|){29}b/ already stops scan_prefix()\nbecause it reaches the maximum step_count. */\n#define SCAN_PREFIX_STACK_END 32\n\n/*\nScan prefix stores the prefix string in the chars array.\nThe elements of the chars array is either small character\nsets or \"any\" (count is set to 255).\n\nExamples (the chars array is represented by a simple regex):\n\n/(abc|xbyd)/ prefix: /[ax]b[cy]/ (length: 3)\n/a[a-z]b+c/ prefix: a.b (length: 3)\n/ab?cd/ prefix: a[bc][cd] (length: 3)\n/(ab|cd)|(ef|gh)/ prefix: [aceg][bdfh] (length: 2)\n\nThe length is returned by scan_prefix(). The length is\nless than or equal than the minimum length of the pattern.\n*/\n\nstatic int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars)\n{\nfast_forward_char_data *chars_start = chars;\nfast_forward_char_data *chars_end = chars + MAX_N_CHARS;\nPCRE2_SPTR cc_stack[SCAN_PREFIX_STACK_END];\nfast_forward_char_data *chars_stack[SCAN_PREFIX_STACK_END];\nsljit_u8 next_alternative_stack[SCAN_PREFIX_STACK_END];\nBOOL last, any, class, caseless;\nint stack_ptr, step_count, repeat, len, len_save;\nsljit_u32 chr; /* Any unicode character. */\nsljit_u8 *bytes, *bytes_end, byte;\nPCRE2_SPTR alternative, cc_save, oc;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nPCRE2_UCHAR othercase[4];\n#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16\nPCRE2_UCHAR othercase[2];\n#else\nPCRE2_UCHAR othercase[1];\n#endif\n\nrepeat = 1;\nstack_ptr = 0;\nstep_count = 10000;\nwhile (TRUE)\n  {\n  if (--step_count == 0)\n    return 0;\n\n  SLJIT_ASSERT(chars <= chars_start + MAX_N_CHARS);\n\n  if (chars >= chars_end)\n    {\n    if (stack_ptr == 0)\n      return (int)(chars_end - chars_start);\n\n    --stack_ptr;\n    cc = cc_stack[stack_ptr];\n    chars = chars_stack[stack_ptr];\n\n    if (chars >= chars_end)\n      continue;\n\n    if (next_alternative_stack[stack_ptr] != 0)\n      {\n      /* When an alternative is processed, the\n      next alternative is pushed onto the stack. */\n      SLJIT_ASSERT(*cc == OP_ALT);\n      alternative = cc + GET(cc, 1);\n      if (*alternative == OP_ALT)\n        {\n        SLJIT_ASSERT(stack_ptr < SCAN_PREFIX_STACK_END);\n        SLJIT_ASSERT(chars_stack[stack_ptr] == chars);\n        SLJIT_ASSERT(next_alternative_stack[stack_ptr] == 1);\n        cc_stack[stack_ptr] = alternative;\n        stack_ptr++;\n        }\n      cc += 1 + LINK_SIZE;\n      }\n    }\n\n  last = TRUE;\n  any = FALSE;\n  class = FALSE;\n  caseless = FALSE;\n\n  switch (*cc)\n    {\n    case OP_CHARI:\n    caseless = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_CHAR:\n    last = FALSE;\n    cc++;\n    break;\n\n    case OP_SOD:\n    case OP_SOM:\n    case OP_SET_SOM:\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_EODN:\n    case OP_EOD:\n    case OP_CIRC:\n    case OP_CIRCM:\n    case OP_DOLL:\n    case OP_DOLLM:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    /* Zero width assertions. */\n    cc++;\n    continue;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ASSERT_SCS:\n    cc = bracketend(cc);\n    continue;\n\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_POSPLUSI:\n    caseless = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_POSPLUS:\n    cc++;\n    break;\n\n    case OP_EXACTI:\n    caseless = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_EXACT:\n    repeat = GET2(cc, 1);\n    last = FALSE;\n    cc += 1 + IMM2_SIZE;\n    break;\n\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_POSQUERYI:\n    caseless = TRUE;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_POSQUERY:\n    len = 1;\n    cc++;\n#ifdef SUPPORT_UNICODE\n    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);\n#endif\n    if (stack_ptr >= SCAN_PREFIX_STACK_END)\n      {\n      chars_end = chars;\n      continue;\n      }\n\n    cc_stack[stack_ptr] = cc + len;\n    chars_stack[stack_ptr] = chars;\n    next_alternative_stack[stack_ptr] = 0;\n    stack_ptr++;\n\n    last = FALSE;\n    break;\n\n    case OP_KET:\n    cc += 1 + LINK_SIZE;\n    continue;\n\n    case OP_ALT:\n    cc += GET(cc, 1);\n    continue;\n\n    case OP_ONCE:\n    case OP_BRA:\n    case OP_BRAPOS:\n    case OP_CBRA:\n    case OP_CBRAPOS:\n    alternative = cc + GET(cc, 1);\n    if (*alternative == OP_ALT)\n      {\n      if (stack_ptr >= SCAN_PREFIX_STACK_END)\n        {\n        chars_end = chars;\n        continue;\n        }\n\n      cc_stack[stack_ptr] = alternative;\n      chars_stack[stack_ptr] = chars;\n      next_alternative_stack[stack_ptr] = 1;\n      stack_ptr++;\n      }\n\n    if (*cc == OP_CBRA || *cc == OP_CBRAPOS)\n      cc += IMM2_SIZE;\n    cc += 1 + LINK_SIZE;\n    continue;\n\n    case OP_CLASS:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n    if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    class = TRUE;\n    break;\n\n    case OP_NCLASS:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    class = TRUE;\n    break;\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n    case OP_XCLASS:\n    case OP_ECLASS:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc += GET(cc, 1);\n    break;\n#endif\n\n    case OP_DIGIT:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc++;\n    break;\n\n    case OP_WHITESPACE:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc++;\n    break;\n\n    case OP_WORDCHAR:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc++;\n    break;\n\n    case OP_NOT:\n    case OP_NOTI:\n    cc++;\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_NOT_DIGIT:\n    case OP_NOT_WHITESPACE:\n    case OP_NOT_WORDCHAR:\n    case OP_ANY:\n    case OP_ALLANY:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc++;\n    break;\n\n#ifdef SUPPORT_UNICODE\n    case OP_NOTPROP:\n    case OP_PROP:\n#if PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    cc += 1 + 2;\n    break;\n#endif\n\n    case OP_TYPEEXACT:\n    repeat = GET2(cc, 1);\n    cc += 1 + IMM2_SIZE;\n    continue;\n\n    case OP_NOTEXACT:\n    case OP_NOTEXACTI:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      {\n      chars_end = chars;\n      continue;\n      }\n#endif\n    any = TRUE;\n    repeat = GET2(cc, 1);\n    cc += 1 + IMM2_SIZE + 1;\n    break;\n\n    default:\n    chars_end = chars;\n    continue;\n    }\n\n  SLJIT_ASSERT(chars < chars_end);\n\n  if (any)\n    {\n    do\n      {\n      chars->count = 255;\n      chars++;\n      }\n    while (--repeat > 0 && chars < chars_end);\n\n    repeat = 1;\n    continue;\n    }\n\n  if (class)\n    {\n    bytes = (sljit_u8*) (cc + 1);\n    cc += 1 + 32 / sizeof(PCRE2_UCHAR);\n\n    SLJIT_ASSERT(last == TRUE && repeat == 1);\n    switch (*cc)\n      {\n      case OP_CRQUERY:\n      case OP_CRMINQUERY:\n      case OP_CRPOSQUERY:\n      last = FALSE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_CRSTAR:\n      case OP_CRMINSTAR:\n      case OP_CRPOSSTAR:\n      if (stack_ptr >= SCAN_PREFIX_STACK_END)\n        {\n        chars_end = chars;\n        continue;\n        }\n\n      cc_stack[stack_ptr] = ++cc;\n      chars_stack[stack_ptr] = chars;\n      next_alternative_stack[stack_ptr] = 0;\n      stack_ptr++;\n      break;\n\n      default:\n      case OP_CRPLUS:\n      case OP_CRMINPLUS:\n      case OP_CRPOSPLUS:\n      break;\n\n      case OP_CRRANGE:\n      case OP_CRMINRANGE:\n      case OP_CRPOSRANGE:\n      repeat = GET2(cc, 1);\n      if (repeat <= 0)\n        {\n        chars_end = chars;\n        continue;\n        }\n\n      last = (repeat != (int)GET2(cc, 1 + IMM2_SIZE));\n      cc += 1 + 2 * IMM2_SIZE;\n      break;\n      }\n\n    do\n      {\n      if (bytes[31] & 0x80)\n        chars->count = 255;\n      else if (chars->count != 255)\n        {\n        bytes_end = bytes + 32;\n        chr = 0;\n        do\n          {\n          byte = *bytes++;\n          SLJIT_ASSERT((chr & 0x7) == 0);\n          if (byte == 0)\n            chr += 8;\n          else\n            {\n            do\n              {\n              if ((byte & 0x1) != 0)\n                add_prefix_char(chr, chars, TRUE);\n              byte >>= 1;\n              chr++;\n              }\n            while (byte != 0);\n            chr = (chr + 7) & (sljit_u32)(~7);\n            }\n          }\n        while (chars->count != 255 && bytes < bytes_end);\n        bytes = bytes_end - 32;\n        }\n\n      chars++;\n      }\n    while (--repeat > 0 && chars < chars_end);\n\n    repeat = 1;\n    if (last)\n      chars_end = chars;\n    continue;\n    }\n\n  len = 1;\n#ifdef SUPPORT_UNICODE\n  if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);\n#endif\n\n  if (caseless && char_has_othercase(common, cc))\n    {\n#ifdef SUPPORT_UNICODE\n    if (common->utf)\n      {\n      GETCHAR(chr, cc);\n      if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)\n        {\n        chars_end = chars;\n        continue;\n        }\n      }\n    else\n#endif\n      {\n      chr = *cc;\n#ifdef SUPPORT_UNICODE\n      if (common->ucp && chr > 127)\n        {\n        chr = UCD_OTHERCASE(chr);\n        othercase[0] = (chr == (PCRE2_UCHAR)chr) ? chr : *cc;\n        }\n      else\n#endif\n        othercase[0] = TABLE_GET(chr, common->fcc, chr);\n      }\n    }\n  else\n    {\n    caseless = FALSE;\n    othercase[0] = 0; /* Stops compiler warning - PH */\n    }\n\n  len_save = len;\n  cc_save = cc;\n  while (TRUE)\n    {\n    oc = othercase;\n    do\n      {\n      len--;\n\n      chr = *cc;\n      add_prefix_char(*cc, chars, len == 0);\n\n      if (caseless)\n        add_prefix_char(*oc, chars, len == 0);\n\n      chars++;\n      cc++;\n      oc++;\n      }\n    while (len > 0 && chars < chars_end);\n\n    if (--repeat == 0 || chars >= chars_end)\n      break;\n\n    len = len_save;\n    cc = cc_save;\n    }\n\n  repeat = 1;\n  if (last)\n    chars_end = chars;\n  }\n}\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstatic void jumpto_if_not_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg, struct sljit_label *label)\n{\n#if PCRE2_CODE_UNIT_WIDTH == 8\nOP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);\nCMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0x80, label);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nOP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);\nCMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label);\n#else\n#error \"Unknown code width\"\n#endif\n}\n#endif\n\n#include \"pcre2_jit_simd_inc.h\"\n\n#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD\n\nstatic BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars, int max)\n{\n  sljit_s32 i, j, max_i = 0, max_j = 0;\n  sljit_u32 max_pri = 0;\n  sljit_s32 max_offset = max_fast_forward_char_pair_offset();\n  PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri;\n\n  for (i = max - 1; i >= 1; i--)\n    {\n    if (chars[i].last_count > 2)\n      {\n      a1 = chars[i].chars[0];\n      a2 = chars[i].chars[1];\n      a_pri = chars[i].last_count;\n\n      j = i - max_offset;\n      if (j < 0)\n        j = 0;\n\n      while (j < i)\n        {\n        b_pri = chars[j].last_count;\n        if (b_pri > 2 && (sljit_u32)a_pri + (sljit_u32)b_pri >= max_pri)\n          {\n          b1 = chars[j].chars[0];\n          b2 = chars[j].chars[1];\n\n          if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)\n            {\n            max_pri = a_pri + b_pri;\n            max_i = i;\n            max_j = j;\n            }\n          }\n        j++;\n        }\n      }\n    }\n\nif (max_pri == 0)\n  return FALSE;\n\nfast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]);\nreturn TRUE;\n}\n\n#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */\n\nstatic void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)\n{\nDEFINE_COMPILER;\nstruct sljit_label *start;\nstruct sljit_jump *match;\nstruct sljit_jump *partial_quit;\nPCRE2_UCHAR mask;\nBOOL has_match_end = (common->match_end_ptr != 0);\n\nSLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);\n\nif (has_match_end)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n\nif (offset > 0)\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));\n\nif (has_match_end)\n  {\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1));\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);\n  SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END);\n  }\n\n#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD\n\nif (JIT_HAS_FAST_FORWARD_CHAR_SIMD)\n  {\n  fast_forward_char_simd(common, char1, char2, offset);\n\n  if (offset > 0)\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));\n\n  if (has_match_end)\n    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n  return;\n  }\n\n#endif\n\nstart = LABEL();\n\npartial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (char1 == char2)\n  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start);\nelse\n  {\n  mask = char1 ^ char2;\n  if (is_powerof2(mask))\n    {\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);\n    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start);\n    }\n  else\n    {\n    match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);\n    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start);\n    JUMPHERE(match);\n    }\n  }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset > 0)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1)));\n  jumpto_if_not_utf_char_start(compiler, TMP1, start);\n  }\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1));\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  JUMPHERE(partial_quit);\n\nif (has_match_end)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\nstatic SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_label *start;\nstruct sljit_jump *match;\nfast_forward_char_data chars[MAX_N_CHARS];\nsljit_s32 offset;\nPCRE2_UCHAR mask;\nPCRE2_UCHAR *char_set, *char_set_end;\nint i, max, from;\nint range_right = -1, range_len;\nsljit_u8 *update_table = NULL;\nBOOL in_range;\n\nfor (i = 0; i < MAX_N_CHARS; i++)\n  {\n  chars[i].count = 0;\n  chars[i].last_count = 0;\n  }\n\nmax = scan_prefix(common, common->start, chars);\n\nif (max < 1)\n  return FALSE;\n\n/* Convert last_count to priority. */\nfor (i = 0; i < max; i++)\n  {\n  SLJIT_ASSERT(chars[i].last_count <= chars[i].count);\n\n  switch (chars[i].count)\n    {\n    case 0:\n    chars[i].count = 255;\n    chars[i].last_count = 0;\n    break;\n\n    case 1:\n    chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;\n    /* Simplifies algorithms later. */\n    chars[i].chars[1] = chars[i].chars[0];\n    break;\n\n    case 2:\n    SLJIT_ASSERT(chars[i].chars[0] != chars[i].chars[1]);\n\n    if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))\n      chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;\n    else\n      chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;\n    break;\n\n    default:\n    chars[i].last_count = (chars[i].count == 255) ? 0 : 1;\n    break;\n    }\n  }\n\n#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD\nif (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(common, chars, max))\n  return TRUE;\n#endif\n\nin_range = FALSE;\n/* Prevent compiler \"uninitialized\" warning */\nfrom = 0;\nrange_len = 4 /* minimum length */ - 1;\nfor (i = 0; i <= max; i++)\n  {\n  if (in_range && (i - from) > range_len && (chars[i - 1].count < 255))\n    {\n    range_len = i - from;\n    range_right = i - 1;\n    }\n\n  if (i < max && chars[i].count < 255)\n    {\n    SLJIT_ASSERT(chars[i].count > 0);\n    if (!in_range)\n      {\n      in_range = TRUE;\n      from = i;\n      }\n    }\n  else\n    in_range = FALSE;\n  }\n\nif (range_right >= 0)\n  {\n  update_table = (sljit_u8 *)allocate_read_only_data(common, 256);\n  if (update_table == NULL)\n    return TRUE;\n  memset(update_table, IN_UCHARS(range_len), 256);\n\n  for (i = 0; i < range_len; i++)\n    {\n    SLJIT_ASSERT(chars[range_right - i].count > 0 && chars[range_right - i].count < 255);\n\n    char_set = chars[range_right - i].chars;\n    char_set_end = char_set + chars[range_right - i].count;\n    do\n      {\n      if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))\n        update_table[(*char_set) & 0xff] = IN_UCHARS(i);\n      char_set++;\n      }\n    while (char_set < char_set_end);\n    }\n  }\n\noffset = -1;\n/* Scan forward. */\nfor (i = 0; i < max; i++)\n  {\n  if (range_right == i)\n    continue;\n\n  if (offset == -1)\n    {\n    if (chars[i].last_count >= 2)\n      offset = i;\n    }\n  else if (chars[offset].last_count < chars[i].last_count)\n    offset = i;\n  }\n\nSLJIT_ASSERT(offset == -1 || (chars[offset].count >= 1 && chars[offset].count <= 2));\n\nif (range_right < 0)\n  {\n  if (offset < 0)\n    return FALSE;\n  /* Works regardless the value is 1 or 2. */\n  fast_forward_first_char2(common, chars[offset].chars[0], chars[offset].chars[1], offset);\n  return TRUE;\n  }\n\nSLJIT_ASSERT(range_right != offset);\n\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n  OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));\n  add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);\n  SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END);\n  }\nelse\n  {\n  OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));\n  add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));\n  }\n\nSLJIT_ASSERT(range_right >= 0);\n\nif (!HAS_VIRTUAL_REGISTERS)\n  OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);\n\nstart = LABEL();\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));\n\n#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));\n#else\nOP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);\n#endif\n\nif (!HAS_VIRTUAL_REGISTERS)\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);\nelse\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\nCMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);\n\nif (offset >= 0)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  if (chars[offset].count == 1)\n    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0], start);\n  else\n    {\n    mask = chars[offset].chars[0] ^ chars[offset].chars[1];\n    if (is_powerof2(mask))\n      {\n      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);\n      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0] | mask, start);\n      }\n    else\n      {\n      match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0]);\n      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[1], start);\n      JUMPHERE(match);\n      }\n    }\n  }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset != 0)\n  {\n  if (offset < 0)\n    {\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    }\n  else\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\n\n  jumpto_if_not_utf_char_start(compiler, TMP1, start);\n\n  if (offset < 0)\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  }\n#endif\n\nif (offset >= 0)\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\nelse\n  OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));\nreturn TRUE;\n}\n\nstatic SLJIT_INLINE void fast_forward_first_char(compiler_common *common)\n{\nPCRE2_UCHAR first_char = (PCRE2_UCHAR)(common->re->first_codeunit);\nPCRE2_UCHAR oc;\n\noc = first_char;\nif ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)\n  {\n  oc = TABLE_GET(first_char, common->fcc, first_char);\n#if defined SUPPORT_UNICODE\n  if (first_char > 127 && (common->utf || common->ucp))\n    oc = UCD_OTHERCASE(first_char);\n#endif\n  }\n\nfast_forward_first_char2(common, first_char, oc, 0);\n}\n\nstatic SLJIT_INLINE void fast_forward_newline(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nstruct sljit_jump *lastchar = NULL;\nstruct sljit_jump *firstchar;\nstruct sljit_jump *quit = NULL;\nstruct sljit_jump *foundcr = NULL;\nstruct sljit_jump *notfoundnl;\njump_list *newline = NULL;\n\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  }\n\nif (common->nltype == NLTYPE_FIXED && common->newline > 255)\n  {\n#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD\n  if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE)\n    {\n    if (HAS_VIRTUAL_REGISTERS)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\n      }\n    else\n      {\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n      }\n    firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, STR_PTR, 0, TMP1, 0);\n    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\n    fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    }\n  else\n#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */\n    {\n    lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n    if (HAS_VIRTUAL_REGISTERS)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\n      }\n    else\n      {\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n      }\n    firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));\n    OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, STR_PTR, 0, TMP1, 0);\n    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n    loop = LABEL();\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\n    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);\n    CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);\n\n    JUMPHERE(quit);\n    JUMPHERE(lastchar);\n    }\n\n  JUMPHERE(firstchar);\n\n  if (common->match_end_ptr != 0)\n    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n  return;\n  }\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n  }\nelse\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\n\n/* Example: match /^/ to \\r\\n from offset 1. */\nfirstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n\nif (common->nltype == NLTYPE_ANY)\n  move_back(common, NULL, FALSE);\nelse\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nloop = LABEL();\ncommon->ff_newline_shortcut = loop;\n\n#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD\nif (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF))\n  {\n  if (common->nltype == NLTYPE_ANYCRLF)\n    {\n    fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0);\n    if (common->mode != PCRE2_JIT_COMPLETE)\n      lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);\n    }\n  else\n    {\n    fast_forward_char_simd(common, common->newline, common->newline, 0);\n\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    if (common->mode != PCRE2_JIT_COMPLETE)\n      {\n      OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n      SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n      }\n    }\n  }\nelse\n#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */\n  {\n  read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);\n  lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)\n    foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);\n  check_newlinechar(common, common->nltype, &newline, FALSE);\n  set_jumps(newline, loop);\n  }\n\nif (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)\n  {\n  if (quit == NULL)\n    {\n    quit = JUMP(SLJIT_JUMP);\n    JUMPHERE(foundcr);\n    }\n\n  notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL);\n  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n  JUMPHERE(notfoundnl);\n  JUMPHERE(quit);\n  }\n\nif (lastchar)\n  JUMPHERE(lastchar);\nJUMPHERE(firstchar);\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\nstatic BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);\n\nstatic SLJIT_INLINE void fast_forward_start_bits(compiler_common *common)\n{\nDEFINE_COMPILER;\nconst sljit_u8 *start_bits = common->re->start_bitmap;\nstruct sljit_label *start;\nstruct sljit_jump *partial_quit;\n#if PCRE2_CODE_UNIT_WIDTH != 8\nstruct sljit_jump *found = NULL;\n#endif\njump_list *matches = NULL;\n\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);\n  SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END);\n  }\n\nstart = LABEL();\n\npartial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit);\n\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &matches))\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  if ((start_bits[31] & 0x80) != 0)\n    found = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255);\n  else\n    CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255, start);\n#elif defined SUPPORT_UNICODE\n  if (common->utf && is_char7_bitset(start_bits, FALSE))\n    CMPTO(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 127, start);\n#endif\n  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);\n  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);\n  if (!HAS_VIRTUAL_REGISTERS)\n    {\n    OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);\n    OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP3, 0);\n    }\n  else\n    {\n    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);\n    OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);\n    }\n  JUMPTO(SLJIT_ZERO, start);\n  }\nelse\n  set_jumps(matches, start);\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\nif (found != NULL)\n  JUMPHERE(found);\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  JUMPHERE(partial_quit);\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);\n}\n\nstatic SLJIT_INLINE jump_list *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)\n{\nDEFINE_COMPILER;\nstruct sljit_label *loop;\nstruct sljit_jump *toolong;\nstruct sljit_jump *already_found;\nstruct sljit_jump *found;\nstruct sljit_jump *found_oc = NULL;\njump_list *not_found = NULL;\nsljit_u32 oc, bit;\n\nSLJIT_ASSERT(common->req_char_ptr != 0);\nOP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(REQ_CU_MAX) * 100);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);\ntoolong = CMP(SLJIT_LESS, TMP2, 0, STR_END, 0);\nalready_found = CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0);\n\nif (has_firstchar)\n  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\nelse\n  OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);\n\noc = req_char;\nif (caseless)\n  {\n  oc = TABLE_GET(req_char, common->fcc, req_char);\n#if defined SUPPORT_UNICODE\n  if (req_char > 127 && (common->utf || common->ucp))\n    oc = UCD_OTHERCASE(req_char);\n#endif\n  }\n\n#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD\nif (JIT_HAS_FAST_REQUESTED_CHAR_SIMD)\n  {\n  not_found = fast_requested_char_simd(common, req_char, oc);\n  }\nelse\n#endif\n  {\n  loop = LABEL();\n  add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\n  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);\n\n  if (req_char == oc)\n    found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);\n  else\n    {\n    bit = req_char ^ oc;\n    if (is_powerof2(bit))\n      {\n       OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);\n      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);\n      }\n    else\n      {\n      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);\n      found_oc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);\n      }\n    }\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPTO(SLJIT_JUMP, loop);\n\n  JUMPHERE(found);\n  if (found_oc)\n    JUMPHERE(found_oc);\n  }\n\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);\n\nJUMPHERE(already_found);\nJUMPHERE(toolong);\nreturn not_found;\n}\n\nstatic void do_revertframes(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_label *mainloop;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\nGET_LOCAL_BASE(TMP1, 0, 0);\n\n/* Drop frames until we reach STACK_TOP. */\nmainloop = LABEL();\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -SSIZE_OF(sw));\nOP2U(SLJIT_SUB | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0);\njump = JUMP(SLJIT_SIG_LESS_EQUAL);\n\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * SSIZE_OF(sw)));\n  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * SSIZE_OF(sw));\n  }\nelse\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));\n  OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(3 * SSIZE_OF(sw)));\n  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * SSIZE_OF(sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);\n  GET_LOCAL_BASE(TMP1, 0, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP3, 0);\n  }\nJUMPTO(SLJIT_JUMP, mainloop);\n\nJUMPHERE(jump);\nsljit_set_current_flags(compiler, SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z);\njump = JUMP(SLJIT_NOT_ZERO /* SIG_LESS */);\n/* End of reverting values. */\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n\nJUMPHERE(jump);\nOP2(SLJIT_SUB, TMP2, 0, TMP1, 0, TMP2, 0);\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));\n  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));\n  }\nelse\n  {\n  OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw)));\n  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * SSIZE_OF(sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP3, 0);\n  }\nJUMPTO(SLJIT_JUMP, mainloop);\n}\n\n#ifdef SUPPORT_UNICODE\n#define UCPCAT(bit) (1 << (bit))\n#define UCPCAT2(bit1, bit2) (UCPCAT(bit1) | UCPCAT(bit2))\n#define UCPCAT3(bit1, bit2, bit3) (UCPCAT(bit1) | UCPCAT(bit2) | UCPCAT(bit3))\n#define UCPCAT_RANGE(start, end) (((1 << ((end) + 1)) - 1) - ((1 << (start)) - 1))\n#define UCPCAT_L UCPCAT_RANGE(ucp_Ll, ucp_Lu)\n#define UCPCAT_N UCPCAT_RANGE(ucp_Nd, ucp_No)\n#define UCPCAT_ALL ((1 << (ucp_Zs + 1)) - 1)\n#endif\n\nstatic void check_wordboundary(compiler_common *common, BOOL ucp)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *skipread;\njump_list *skipread_list = NULL;\n#ifdef SUPPORT_UNICODE\nstruct sljit_label *valid_utf;\njump_list *invalid_utf1 = NULL;\n#endif /* SUPPORT_UNICODE */\njump_list *invalid_utf2 = NULL;\n#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE\nstruct sljit_jump *jump;\n#endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */\n\nSLJIT_UNUSED_ARG(ucp);\nSLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);\n\nSLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw));\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n/* Get type of the previous char, and put it to TMP3. */\nOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\nOP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);\nskipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n\n#ifdef SUPPORT_UNICODE\nif (common->invalid_utf)\n  {\n  peek_char_back(common, READ_CHAR_MAX, &invalid_utf1);\n\n  if (common->mode != PCRE2_JIT_COMPLETE)\n    {\n    OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);\n    OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n    move_back(common, NULL, TRUE);\n    check_start_used_ptr(common);\n    OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);\n    }\n  }\nelse\n#endif /* SUPPORT_UNICODE */\n  {\n  if (common->mode == PCRE2_JIT_COMPLETE)\n    peek_char_back(common, READ_CHAR_MAX, NULL);\n  else\n    {\n    move_back(common, NULL, TRUE);\n    check_start_used_ptr(common);\n    read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR);\n    }\n  }\n\n/* Testing char type. */\n#ifdef SUPPORT_UNICODE\nif (ucp)\n  {\n  add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));\n  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N);\n  OP_FLAGS(SLJIT_MOV, TMP3, 0, SLJIT_NOT_ZERO);\n  }\nelse\n#endif /* SUPPORT_UNICODE */\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\n#elif defined SUPPORT_UNICODE\n  /* Here TMP3 has already been zeroed. */\n  jump = NULL;\n  if (common->utf)\n    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);\n  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);\n  OP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, 1);\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  JUMPHERE(jump);\n#elif defined SUPPORT_UNICODE\n  if (jump != NULL)\n    JUMPHERE(jump);\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n  }\nJUMPHERE(skipread);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);\ncheck_str_end(common, &skipread_list);\npeek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, &invalid_utf2);\n\n/* Testing char type. This is a code duplication. */\n#ifdef SUPPORT_UNICODE\n\nvalid_utf = LABEL();\n\nif (ucp)\n  {\n  add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));\n  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N);\n  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);\n  }\nelse\n#endif /* SUPPORT_UNICODE */\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  /* TMP2 may be destroyed by peek_char. */\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);\n  jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\n#elif defined SUPPORT_UNICODE\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);\n  jump = NULL;\n  if (common->utf)\n    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);\n#endif\n  OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);\n  OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);\n  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  JUMPHERE(jump);\n#elif defined SUPPORT_UNICODE\n  if (jump != NULL)\n    JUMPHERE(jump);\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n  }\nset_jumps(skipread_list, LABEL());\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nOP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0);\nOP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n\n#ifdef SUPPORT_UNICODE\nif (common->invalid_utf)\n  {\n  set_jumps(invalid_utf1, LABEL());\n\n  peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, NULL);\n  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf);\n\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1);\n  OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n\n  set_jumps(invalid_utf2, LABEL());\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);\n  OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n  }\n#endif /* SUPPORT_UNICODE */\n}\n\nstatic BOOL optimize_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)\n{\n/* May destroy TMP1. */\nDEFINE_COMPILER;\nint ranges[MAX_CLASS_RANGE_SIZE];\nsljit_u8 bit, cbit, all;\nint i, byte, length = 0;\n\nbit = bits[0] & 0x1;\n/* All bits will be zero or one (since bit is zero or one). */\nall = (sljit_u8)-bit;\n\nfor (i = 0; i < 256; )\n  {\n  byte = i >> 3;\n  if ((i & 0x7) == 0 && bits[byte] == all)\n    i += 8;\n  else\n    {\n    cbit = (bits[byte] >> (i & 0x7)) & 0x1;\n    if (cbit != bit)\n      {\n      if (length >= MAX_CLASS_RANGE_SIZE)\n        return FALSE;\n      ranges[length] = i;\n      length++;\n      bit = cbit;\n      all = (sljit_u8)-cbit; /* sign extend bit into byte */\n      }\n    i++;\n    }\n  }\n\nif (((bit == 0) && nclass) || ((bit == 1) && !nclass))\n  {\n  if (length >= MAX_CLASS_RANGE_SIZE)\n    return FALSE;\n  ranges[length] = 256;\n  length++;\n  }\n\nif (length < 0 || length > 4)\n  return FALSE;\n\nbit = bits[0] & 0x1;\nif (invert) bit ^= 0x1;\n\n/* No character is accepted. */\nif (length == 0 && bit == 0)\n  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n\nswitch(length)\n  {\n  case 0:\n  /* When bit != 0, all characters are accepted. */\n  return TRUE;\n\n  case 1:\n  add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));\n  return TRUE;\n\n  case 2:\n  if (ranges[0] + 1 != ranges[1])\n    {\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);\n    add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));\n    }\n  else\n    add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));\n  return TRUE;\n\n  case 3:\n  if (bit != 0)\n    {\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));\n    if (ranges[0] + 1 != ranges[1])\n      {\n      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);\n      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));\n      }\n    else\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));\n    return TRUE;\n    }\n\n  add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));\n  if (ranges[1] + 1 != ranges[2])\n    {\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));\n    }\n  else\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));\n  return TRUE;\n\n  case 4:\n  if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])\n      && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]\n      && (ranges[1] & (ranges[2] - ranges[0])) == 0\n      && is_powerof2(ranges[2] - ranges[0]))\n    {\n    SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);\n    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);\n    if (ranges[2] + 1 != ranges[3])\n      {\n      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);\n      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));\n      }\n    else\n      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));\n    return TRUE;\n    }\n\n  if (bit != 0)\n    {\n    i = 0;\n    if (ranges[0] + 1 != ranges[1])\n      {\n      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);\n      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));\n      i = ranges[0];\n      }\n    else\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));\n\n    if (ranges[2] + 1 != ranges[3])\n      {\n      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);\n      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));\n      }\n    else\n      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));\n    return TRUE;\n    }\n\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);\n  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));\n  if (ranges[1] + 1 != ranges[2])\n    {\n    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));\n    }\n  else\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));\n  return TRUE;\n\n  default:\n  SLJIT_UNREACHABLE();\n  return FALSE;\n  }\n}\n\nstatic BOOL optimize_class_chars(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)\n{\n/* May destroy TMP1. */\nDEFINE_COMPILER;\nuint16_t char_list[MAX_CLASS_CHARS_SIZE];\nuint8_t byte;\nsljit_s32 type;\nint i, j, k, len, c;\n\nif (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))\n  return FALSE;\n\nlen = 0;\n\nfor (i = 0; i < 32; i++)\n  {\n  byte = bits[i];\n\n  if (nclass)\n    byte = (sljit_u8)~byte;\n\n  j = 0;\n  while (byte != 0)\n    {\n    if (byte & 0x1)\n      {\n      c = i * 8 + j;\n\n      k = len;\n\n      if ((c & 0x20) != 0)\n        {\n        for (k = 0; k < len; k++)\n          if (char_list[k] == c - 0x20)\n            {\n            char_list[k] |= 0x120;\n            break;\n            }\n        }\n\n      if (k == len)\n        {\n        if (len >= MAX_CLASS_CHARS_SIZE)\n          return FALSE;\n\n        char_list[len++] = (uint16_t) c;\n        }\n      }\n\n    byte >>= 1;\n    j++;\n    }\n  }\n\nif (len == 0) return FALSE;  /* Should never occur, but stops analyzers complaining. */\n\ni = 0;\nj = 0;\n\nif (char_list[0] == 0)\n  {\n  i++;\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0);\n  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_ZERO);\n  }\nelse\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);\n\nwhile (i < len)\n  {\n  if ((char_list[i] & 0x100) != 0)\n    j++;\n  else\n    {\n    OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i]);\n    SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2);\n    }\n  i++;\n  }\n\nif (j != 0)\n  {\n  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);\n\n  for (i = 0; i < len; i++)\n    if ((char_list[i] & 0x100) != 0)\n      {\n      j--;\n      OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);\n      SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2);\n      }\n  }\n\nif (invert)\n  nclass = !nclass;\n\ntype = nclass ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;\nadd_jump(compiler, backtracks, CMP(type, TMP2, 0, SLJIT_IMM, 0));\nreturn TRUE;\n}\n\nstatic BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)\n{\n/* May destroy TMP1. */\nif (optimize_class_ranges(common, bits, nclass, invert, backtracks))\n  return TRUE;\nreturn optimize_class_chars(common, bits, nclass, invert, backtracks);\n}\n\nstatic void check_anynewline(compiler_common *common)\n{\n/* Check whether TMP1 contains a newline character. TMP2 destroyed. */\nDEFINE_COMPILER;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n#ifdef EBCDIC\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_LF);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_VT);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_FF);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL);\n#else\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, CHAR_LF);\nOP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR - CHAR_LF);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL - CHAR_LF);\n#endif\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n#endif\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - CHAR_LF);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  }\n#endif\n#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */\nOP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void check_hspace(compiler_common *common)\n{\n/* Check whether TMP1 contains a newline character. TMP2 destroyed. */\nDEFINE_COMPILER;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_HT);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_SPACE);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NBSP);\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n#endif\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x1680);\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e);\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x200a - 0x2000);\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  }\n#endif\n#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */\nOP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void check_vspace(compiler_common *common)\n{\n/* Check whether TMP1 contains a newline character. TMP2 destroyed. */\nDEFINE_COMPILER;\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);\n\n#ifdef EBCDIC\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_LF);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_VT);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_FF);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR);\nOP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL);\n#else\nOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, CHAR_LF);\nOP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR - CHAR_LF);\nOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL - CHAR_LF);\n#endif\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utf)\n  {\n#endif\n  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);\n  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);\n  OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - CHAR_LF);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  }\n#endif\n#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */\nOP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);\n\nOP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);\n}\n\nstatic void do_casefulcmp(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_label *label;\nint char1_reg;\nint char2_reg;\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  char1_reg = STR_END;\n  char2_reg = STACK_TOP;\n  }\nelse\n  {\n  char1_reg = TMP3;\n  char2_reg = RETURN_ADDR;\n  }\n\n/* Update ref_update_local_size() when this changes. */\nSLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw));\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\nif (char1_reg == STR_END)\n  {\n  OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);\n  OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);\n  }\n\nif (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)\n  {\n  label = LABEL();\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);\n  OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPTO(SLJIT_NOT_ZERO, label);\n\n  JUMPHERE(jump);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  }\nelse if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)\n  {\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  label = LABEL();\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);\n  OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPTO(SLJIT_NOT_ZERO, label);\n\n  JUMPHERE(jump);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  }\nelse\n  {\n  label = LABEL();\n  OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);\n  OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);\n  OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\n  JUMPTO(SLJIT_NOT_ZERO, label);\n\n  JUMPHERE(jump);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  }\n\nif (char1_reg == STR_END)\n  {\n  OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);\n  OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);\n  }\n\nOP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n}\n\nstatic void do_caselesscmp(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_label *label;\nint char1_reg = STR_END;\nint char2_reg;\nint lcc_table;\nint opt_type = 0;\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  char2_reg = STACK_TOP;\n  lcc_table = STACK_LIMIT;\n  }\nelse\n  {\n  char2_reg = RETURN_ADDR;\n  lcc_table = TMP3;\n  }\n\nif (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)\n  opt_type = 1;\nelse if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)\n  opt_type = 2;\n\n/* Update ref_update_local_size() when this changes. */\nSLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw));\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, char1_reg, 0);\n\nif (char2_reg == STACK_TOP)\n  {\n  OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);\n  OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);\n  }\n\nOP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);\n\nif (opt_type == 1)\n  {\n  label = LABEL();\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n  }\nelse if (opt_type == 2)\n  {\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  label = LABEL();\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));\n  sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n  }\nelse\n  {\n  label = LABEL();\n  OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);\n  OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));\n  }\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\njump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);\n#endif\nOP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);\n#if PCRE2_CODE_UNIT_WIDTH != 8\nJUMPHERE(jump);\njump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);\n#endif\nOP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);\n#if PCRE2_CODE_UNIT_WIDTH != 8\nJUMPHERE(jump);\n#endif\n\nif (opt_type == 0)\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\njump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);\nOP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));\nJUMPTO(SLJIT_NOT_ZERO, label);\n\nJUMPHERE(jump);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n\nif (opt_type == 2)\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\nif (char2_reg == STACK_TOP)\n  {\n  OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);\n  OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);\n  }\n\nOP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\nOP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n}\n\n#include \"pcre2_jit_char_inc.h\"\n\nstatic PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump[4];\n\nswitch(type)\n  {\n  case OP_SOD:\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\n    }\n  else\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));\n  return cc;\n\n  case OP_SOM:\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n    }\n  else\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\n  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));\n  return cc;\n\n  case OP_NOT_WORD_BOUNDARY:\n  case OP_WORD_BOUNDARY:\n  case OP_NOT_UCP_WORD_BOUNDARY:\n  case OP_UCP_WORD_BOUNDARY:\n  add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL));\n#ifdef SUPPORT_UNICODE\n  if (common->invalid_utf)\n    {\n    add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0));\n    return cc;\n    }\n#endif /* SUPPORT_UNICODE */\n  sljit_set_current_flags(compiler, SLJIT_SET_Z);\n  add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO));\n  return cc;\n\n  case OP_EODN:\n  /* Requires rather complex checks. */\n  jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n  if (common->nltype == NLTYPE_FIXED && common->newline > 255)\n    {\n    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    if (common->mode == PCRE2_JIT_COMPLETE)\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));\n    else\n      {\n      jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);\n      OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0);\n      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);\n      OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);\n      OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL);\n      add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));\n      check_partial(common, TRUE);\n      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n      JUMPHERE(jump[1]);\n      }\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));\n    }\n  else if (common->nltype == NLTYPE_FIXED)\n    {\n    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));\n    }\n  else\n    {\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);\n    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0);\n    jump[2] = JUMP(SLJIT_GREATER);\n    add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */);\n    /* Equal. */\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);\n    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n\n    JUMPHERE(jump[1]);\n    if (common->nltype == NLTYPE_ANYCRLF)\n      {\n      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));\n      }\n    else\n      {\n      OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n      read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));\n      add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));\n      sljit_set_current_flags(compiler, SLJIT_SET_Z);\n      add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));\n      OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n      }\n    JUMPHERE(jump[2]);\n    JUMPHERE(jump[3]);\n    }\n  JUMPHERE(jump[0]);\n  if (common->mode != PCRE2_JIT_COMPLETE)\n    check_partial(common, TRUE);\n  return cc;\n\n  case OP_EOD:\n  add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));\n  if (common->mode != PCRE2_JIT_COMPLETE)\n    check_partial(common, TRUE);\n  return cc;\n\n  case OP_DOLL:\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);\n    }\n  else\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);\n  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));\n\n  if (!common->endonly)\n    compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);\n  else\n    {\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));\n    check_partial(common, FALSE);\n    }\n  return cc;\n\n  case OP_DOLLM:\n  jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);\n    }\n  else\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);\n  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));\n  check_partial(common, FALSE);\n  jump[0] = JUMP(SLJIT_JUMP);\n  JUMPHERE(jump[1]);\n\n  if (common->nltype == NLTYPE_FIXED && common->newline > 255)\n    {\n    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n    if (common->mode == PCRE2_JIT_COMPLETE)\n      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));\n    else\n      {\n      jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);\n      /* STR_PTR = STR_END - IN_UCHARS(1) */\n      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));\n      check_partial(common, TRUE);\n      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n      JUMPHERE(jump[1]);\n      }\n\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));\n    }\n  else\n    {\n    peek_char(common, common->nlmax, TMP3, 0, NULL);\n    check_newlinechar(common, common->nltype, backtracks, FALSE);\n    }\n  JUMPHERE(jump[0]);\n  return cc;\n\n  case OP_CIRC:\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);\n    add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);\n    add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));\n    }\n  return cc;\n\n  case OP_CIRCM:\n  /* TMP2 might be used by peek_char_back. */\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\n    jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n    jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);\n    OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);\n    }\n  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));\n  jump[0] = JUMP(SLJIT_JUMP);\n  JUMPHERE(jump[1]);\n\n  if (!common->alt_circumflex)\n    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n  if (common->nltype == NLTYPE_FIXED && common->newline > 255)\n    {\n    OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));\n    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0));\n    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\n    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));\n    }\n  else\n    {\n    peek_char_back(common, common->nlmax, backtracks);\n    check_newlinechar(common, common->nltype, backtracks, FALSE);\n    }\n  JUMPHERE(jump[0]);\n  return cc;\n  }\nSLJIT_UNREACHABLE();\nreturn cc;\n}\n\n/* Forward definitions. */\nstatic void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *);\nstatic void compile_backtrackingpath(compiler_common *, struct backtrack_common *);\n\n#define PUSH_BACKTRACK(size, ccstart, error) \\\n  do \\\n    { \\\n    backtrack = sljit_alloc_memory(compiler, (size)); \\\n    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \\\n      return error; \\\n    memset(backtrack, 0, size); \\\n    backtrack->prev = parent->top; \\\n    backtrack->cc = (ccstart); \\\n    parent->top = backtrack; \\\n    } \\\n  while (0)\n\n#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \\\n  do \\\n    { \\\n    backtrack = sljit_alloc_memory(compiler, (size)); \\\n    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \\\n      return; \\\n    memset(backtrack, 0, size); \\\n    backtrack->prev = parent->top; \\\n    backtrack->cc = (ccstart); \\\n    parent->top = backtrack; \\\n    } \\\n  while (0)\n\n#define BACKTRACK_AS(type) ((type *)backtrack)\n\nstatic void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)\n{\n/* The OVECTOR offset goes to TMP2. */\nDEFINE_COMPILER;\nint count = GET2(cc, 1 + IMM2_SIZE);\nPCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size;\nunsigned int offset;\njump_list *found = NULL;\n\nSLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));\n\ncount--;\nwhile (count-- > 0)\n  {\n  offset = GET2(slot, 0) << 1;\n  GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));\n  add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));\n  slot += common->name_entry_size;\n  }\n\noffset = GET2(slot, 0) << 1;\nGET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));\nif (backtracks != NULL && !common->unset_backref)\n  add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));\n\nset_jumps(found, LABEL());\n}\n\nstatic void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)\n{\nDEFINE_COMPILER;\nBOOL ref = (*cc == OP_REF || *cc == OP_REFI);\nint offset = 0;\nstruct sljit_jump *jump = NULL;\nstruct sljit_jump *partial;\nstruct sljit_jump *nopartial;\n#if defined SUPPORT_UNICODE\nstruct sljit_label *loop;\nstruct sljit_label *caseless_loop;\nstruct sljit_jump *turkish_ascii_i = NULL;\nstruct sljit_jump *turkish_non_ascii_i = NULL;\njump_list *no_match = NULL;\nint source_reg = COUNT_MATCH;\nint source_end_reg = ARGUMENTS;\nint char1_reg = STACK_LIMIT;\nPCRE2_UCHAR refi_flag = 0;\n\nif (*cc == OP_REFI || *cc == OP_DNREFI)\n  refi_flag = cc[PRIV(OP_lengths)[*cc] - 1];\n#endif /* SUPPORT_UNICODE */\n\nif (ref)\n  {\n  offset = GET2(cc, 1) << 1;\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n  /* OVECTOR(1) contains the \"string begin - 1\" constant. */\n  if (withchecks && !common->unset_backref)\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));\n  }\nelse\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n\n#if defined SUPPORT_UNICODE\nif ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI))\n  {\n  /* Update ref_update_local_size() when this changes. */\n  SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw));\n\n  if (ref)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n  else\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n\n  if (withchecks && emptyfail)\n    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0));\n\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, source_reg, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, source_end_reg, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, char1_reg, 0);\n\n  OP1(SLJIT_MOV, source_reg, 0, TMP1, 0);\n  OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0);\n\n  loop = LABEL();\n  jump = CMP(SLJIT_GREATER_EQUAL, source_reg, 0, source_end_reg, 0);\n  partial = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\n\n  /* Read original character. It must be a valid UTF character. */\n  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n  OP1(SLJIT_MOV, STR_PTR, 0, source_reg, 0);\n\n  read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR | READ_CHAR_VALID_UTF);\n\n  OP1(SLJIT_MOV, source_reg, 0, STR_PTR, 0);\n  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n  OP1(SLJIT_MOV, char1_reg, 0, TMP1, 0);\n\n  /* Read second character. */\n  read_char(common, 0, READ_CHAR_MAX, &no_match, READ_CHAR_UPDATE_STR_PTR);\n\n  CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);\n\n  if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) ==\n        REFI_FLAG_TURKISH_CASING)\n    {\n    OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x20);\n    turkish_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x69);\n\n    OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x1);\n    turkish_non_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x131);\n    }\n\n  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);\n\n  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));\n\n  OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);\n  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);\n  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);\n\n  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records));\n\n  OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, other_case));\n  OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, caseset));\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);\n  CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);\n\n  add_jump(compiler, &no_match, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0));\n  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);\n  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets));\n\n  if (refi_flag & REFI_FLAG_CASELESS_RESTRICT)\n    add_jump(compiler, &no_match, CMP(SLJIT_LESS | SLJIT_32, SLJIT_MEM1(TMP2), 0, SLJIT_IMM, 128));\n\n  caseless_loop = LABEL();\n  OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t));\n  OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, TMP1, 0, char1_reg, 0);\n  JUMPTO(SLJIT_EQUAL, loop);\n  JUMPTO(SLJIT_LESS, caseless_loop);\n\n  if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) ==\n        REFI_FLAG_TURKISH_CASING)\n    {\n    add_jump(compiler, &no_match, JUMP(SLJIT_JUMP));\n    JUMPHERE(turkish_ascii_i);\n\n    OP2(SLJIT_LSHR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5);\n    OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x130);\n    CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);\n\n    add_jump(compiler, &no_match, JUMP(SLJIT_JUMP));\n    JUMPHERE(turkish_non_ascii_i);\n\n    OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1);\n    OP2(SLJIT_SHL, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5);\n    OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x49);\n    CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);\n    }\n\n  set_jumps(no_match, LABEL());\n  if (common->mode == PCRE2_JIT_COMPLETE)\n    JUMPHERE(partial);\n\n  OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\n  OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n\n  if (common->mode != PCRE2_JIT_COMPLETE)\n    {\n    JUMPHERE(partial);\n    OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n    OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\n    OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n\n    check_partial(common, FALSE);\n    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n    }\n\n  JUMPHERE(jump);\n  OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n  OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\n  OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n  return;\n  }\nelse\n#endif /* SUPPORT_UNICODE */\n  {\n  if (ref)\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);\n  else\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);\n\n  if (withchecks)\n    jump = JUMP(SLJIT_ZERO);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n  partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);\n  if (common->mode == PCRE2_JIT_COMPLETE)\n    add_jump(compiler, backtracks, partial);\n\n  add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));\n  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));\n\n  if (common->mode != PCRE2_JIT_COMPLETE)\n    {\n    nopartial = JUMP(SLJIT_JUMP);\n    JUMPHERE(partial);\n    /* TMP2 -= STR_END - STR_PTR */\n    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);\n    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);\n    partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);\n    add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));\n    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));\n    JUMPHERE(partial);\n    check_partial(common, FALSE);\n    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));\n    JUMPHERE(nopartial);\n    }\n  }\n\nif (jump != NULL)\n  {\n  if (emptyfail)\n    add_jump(compiler, backtracks, jump);\n  else\n    JUMPHERE(jump);\n  }\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nBOOL ref = (*cc == OP_REF || *cc == OP_REFI);\nbacktrack_common *backtrack;\nPCRE2_UCHAR type;\nint local_start = LOCAL2;\nint offset = 0;\nstruct sljit_label *label;\nstruct sljit_jump *zerolength;\nstruct sljit_jump *jump = NULL;\nPCRE2_SPTR ccbegin = cc;\nint min = 0, max = 0;\nBOOL minimize;\n\nPUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);\n\nif (ref)\n  offset = GET2(cc, 1) << 1;\nelse\n  cc += IMM2_SIZE;\n\nif (*ccbegin == OP_REFI || *ccbegin == OP_DNREFI)\n  {\n  cc += 1;\n#ifdef SUPPORT_UNICODE\n  if (common->utf || common->ucp)\n    local_start = LOCAL3;\n#endif\n  }\n\ntype = cc[1 + IMM2_SIZE];\n\nSLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);\n/* Update ref_update_local_size() when this changes. */\nSLJIT_ASSERT(local_start + 2 * SSIZE_OF(sw) <= (int)LOCAL0 + common->locals_size);\nminimize = (type & 0x1) != 0;\nswitch(type)\n  {\n  case OP_CRSTAR:\n  case OP_CRMINSTAR:\n  min = 0;\n  max = 0;\n  cc += 1 + IMM2_SIZE + 1;\n  break;\n  case OP_CRPLUS:\n  case OP_CRMINPLUS:\n  min = 1;\n  max = 0;\n  cc += 1 + IMM2_SIZE + 1;\n  break;\n  case OP_CRQUERY:\n  case OP_CRMINQUERY:\n  min = 0;\n  max = 1;\n  cc += 1 + IMM2_SIZE + 1;\n  break;\n  case OP_CRRANGE:\n  case OP_CRMINRANGE:\n  min = GET2(cc, 1 + IMM2_SIZE + 1);\n  max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);\n  cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;\n  break;\n  default:\n  SLJIT_UNREACHABLE();\n  break;\n  }\n\nif (!minimize)\n  {\n  if (min == 0)\n    {\n    allocate_stack(common, 2);\n    if (ref)\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);\n    /* Temporary release of STR_PTR. */\n    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n    /* Handles both invalid and empty cases. Since the minimum repeat,\n    is zero the invalid case is basically the same as an empty case. */\n    if (ref)\n      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n    else\n      {\n      compile_dnref_search(common, ccbegin, NULL);\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0);\n      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n      }\n    /* Restore if not zero length. */\n    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n    }\n  else\n    {\n    allocate_stack(common, 1);\n    if (ref)\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n\n    if (ref)\n      {\n      if (!common->unset_backref)\n        add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));\n      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n      }\n    else\n      {\n      compile_dnref_search(common, ccbegin, &backtrack->own_backtracks);\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0);\n      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n      }\n    }\n\n  if (min > 1 || max > 1)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, SLJIT_IMM, 0);\n\n  label = LABEL();\n  if (!ref)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw));\n  compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, FALSE, FALSE);\n\n  if (min > 1 || max > 1)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), local_start);\n    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, TMP1, 0);\n    if (min > 1)\n      CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);\n    if (max > 1)\n      {\n      jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);\n      allocate_stack(common, 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n      JUMPTO(SLJIT_JUMP, label);\n      JUMPHERE(jump);\n      }\n    }\n\n  if (max == 0)\n    {\n    /* Includes min > 1 case as well. */\n    allocate_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n    JUMPTO(SLJIT_JUMP, label);\n    }\n\n  JUMPHERE(zerolength);\n  BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();\n\n  count_match(common);\n  return cc;\n  }\n\nallocate_stack(common, ref ? 2 : 3);\nif (ref)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\nif (type != OP_CRMINSTAR)\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);\n\nif (min == 0)\n  {\n  /* Handles both invalid and empty cases. Since the minimum repeat,\n  is zero the invalid case is basically the same as an empty case. */\n  if (ref)\n    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n  else\n    {\n    compile_dnref_search(common, ccbegin, NULL);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);\n    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n    }\n  /* Length is non-zero, we can match real repeats. */\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n  jump = JUMP(SLJIT_JUMP);\n  }\nelse\n  {\n  if (ref)\n    {\n    if (!common->unset_backref)\n      add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));\n    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n    }\n  else\n    {\n    compile_dnref_search(common, ccbegin, &backtrack->own_backtracks);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);\n    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n    }\n  }\n\nBACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();\nif (max > 0)\n  add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));\n\nif (!ref)\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));\ncompile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, TRUE, TRUE);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n\nif (min > 1)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);\n  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);\n  }\nelse if (max > 0)\n  OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);\n\nif (jump != NULL)\n  JUMPHERE(jump);\nJUMPHERE(zerolength);\n\ncount_match(common);\nreturn cc;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nrecurse_entry *entry = common->entries;\nrecurse_entry *prev = NULL;\nPCRE2_SPTR end;\nsljit_sw start = GET(cc, 1);\nsljit_uw arg_size;\nPCRE2_SPTR start_cc;\nBOOL needs_control_head;\n\nend = cc + 1 + LINK_SIZE;\n\nwhile (*end == OP_CREF)\n  end += 1 + IMM2_SIZE;\n\nPUSH_BACKTRACK(sizeof(recurse_backtrack), cc, end);\n\n/* Inlining simple patterns. */\nif (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)\n  {\n  start_cc = common->start + start;\n  compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);\n  BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;\n  return end;\n  }\n\ncc += 1 + LINK_SIZE;\narg_size = (sljit_uw)IN_UCHARS(end - cc);\nwhile (entry != NULL)\n  {\n  if (entry->start == start && entry->arg_size == arg_size\n      && (arg_size == 0 || memcmp(cc, entry->arg_start, arg_size) == 0))\n    break;\n  prev = entry;\n  entry = entry->next;\n  }\n\nif (entry == NULL)\n  {\n  entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    return end;\n  entry->next = NULL;\n  entry->entry_label = NULL;\n  entry->backtrack_label = NULL;\n  entry->entry_calls = NULL;\n  entry->backtrack_calls = NULL;\n  entry->start = start;\n  entry->arg_start = cc;\n  entry->arg_size = arg_size;\n\n  if (prev != NULL)\n    prev->next = entry;\n  else\n    common->entries = entry;\n  }\n\nBACKTRACK_AS(recurse_backtrack)->entry = entry;\n\nif (entry->entry_label == NULL)\n  add_jump(compiler, &entry->entry_calls, JUMP(SLJIT_FAST_CALL));\nelse\n  JUMPTO(SLJIT_FAST_CALL, entry->entry_label);\n/* Leave if the match is failed. */\nadd_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));\nBACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();\nreturn end;\n}\n\nstatic sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)\n{\nPCRE2_SPTR begin;\nPCRE2_SIZE *ovector;\nsljit_u32 oveccount, capture_top;\n\nif (arguments->callout == NULL)\n  return 0;\n\nSLJIT_COMPILE_ASSERT(sizeof (PCRE2_SIZE) <= sizeof (sljit_sw), pcre2_size_must_be_lower_than_sljit_sw_size);\n\nbegin = arguments->begin;\novector = (PCRE2_SIZE*)(callout_block + 1);\noveccount = callout_block->capture_top;\n\nSLJIT_ASSERT(oveccount >= 1);\n\ncallout_block->version = 2;\ncallout_block->callout_flags = 0;\n\n/* Offsets in subject. */\ncallout_block->subject_length = arguments->end - arguments->begin;\ncallout_block->start_match = jit_ovector[0] - begin;\ncallout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - begin;\ncallout_block->subject = begin;\n\n/* Convert and copy the JIT offset vector to the ovector array. */\ncallout_block->capture_top = 1;\ncallout_block->offset_vector = ovector;\n\novector[0] = PCRE2_UNSET;\novector[1] = PCRE2_UNSET;\novector += 2;\njit_ovector += 2;\ncapture_top = 1;\n\n/* Convert pointers to sizes. */\nwhile (--oveccount != 0)\n  {\n  capture_top++;\n\n  ovector[0] = (PCRE2_SIZE)(jit_ovector[0] - begin);\n  ovector[1] = (PCRE2_SIZE)(jit_ovector[1] - begin);\n\n  if (ovector[0] != PCRE2_UNSET)\n    callout_block->capture_top = capture_top;\n\n  ovector += 2;\n  jit_ovector += 2;\n  }\n\nreturn (arguments->callout)(callout_block, arguments->callout_data);\n}\n\n#define CALLOUT_ARG_OFFSET(arg) \\\n    SLJIT_OFFSETOF(pcre2_callout_block, arg)\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nsljit_s32 mov_opcode;\nunsigned int callout_length = (*cc == OP_CALLOUT)\n    ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE);\nsljit_sw value1;\nsljit_sw value2;\nsljit_sw value3;\nsljit_s32 callout_arg_size = (common->re->top_bracket + 1) * 2 * SSIZE_OF(sw); /* top_bracket is uint16 so maximum is 1MiB */\n\nPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);\n\ncallout_arg_size = (sizeof(pcre2_callout_block) + callout_arg_size + sizeof(sljit_sw) - 1) / sizeof(sljit_sw);\n\nallocate_stack(common, callout_arg_size);\n\nSLJIT_ASSERT(common->capture_last_ptr != 0);\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);\nOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\nvalue1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0;\nOP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1);\nOP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);\nOP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_top), SLJIT_IMM, common->re->top_bracket + 1);\n\n/* These pointer sized fields temporarly stores internal variables. */\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);\n\nif (common->mark_ptr != 0)\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));\nmov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;\nOP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1));\nOP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE));\n\nif (*cc == OP_CALLOUT)\n  {\n  value1 = 0;\n  value2 = 0;\n  value3 = 0;\n  }\nelse\n  {\n  value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1);\n  value2 = (callout_length - (1 + 4*LINK_SIZE + 2));\n  value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE));\n  }\n\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1);\nOP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2);\nOP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);\n\nSLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);\n\n/* Needed to save important temporary registers. */\nSLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw));\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0);\n/* SLJIT_R0 = arguments */\nOP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);\nGET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);\nsljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_callout_jit));\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nfree_stack(common, callout_arg_size);\n\n/* Check return value. */\nOP2U(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);\nadd_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_SIG_GREATER));\nif (common->abort_label == NULL)\n  add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);\nelse\n  JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->abort_label);\nreturn cc + callout_length;\n}\n\n#undef CALLOUT_ARG_SIZE\n#undef CALLOUT_ARG_OFFSET\n\nstatic PCRE2_SPTR compile_reverse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack = NULL;\njump_list **reverse_failed;\nunsigned int lmin, lmax;\n#ifdef SUPPORT_UNICODE\nstruct sljit_jump *jump;\nstruct sljit_label *label;\n#endif\n\nSLJIT_ASSERT(parent->top == NULL);\n\nif (*cc == OP_REVERSE)\n  {\n  reverse_failed = &parent->own_backtracks;\n  lmin = GET2(cc, 1);\n  lmax = lmin;\n  cc += 1 + IMM2_SIZE;\n\n  SLJIT_ASSERT(lmin > 0);\n  }\nelse\n  {\n  SLJIT_ASSERT(*cc == OP_VREVERSE);\n  PUSH_BACKTRACK(sizeof(vreverse_backtrack), cc, cc + 1 + 2 * IMM2_SIZE);\n\n  reverse_failed = &backtrack->own_backtracks;\n  lmin = GET2(cc, 1);\n  lmax = GET2(cc, 1 + IMM2_SIZE);\n  cc += 1 + 2 * IMM2_SIZE;\n\n  SLJIT_ASSERT(lmin < lmax);\n  }\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));\n  }\nelse\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));\n\n#ifdef SUPPORT_UNICODE\nif (common->utf)\n  {\n  if (lmin > 0)\n    {\n    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmin);\n    label = LABEL();\n    add_jump(compiler, reverse_failed, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0));\n    move_back(common, reverse_failed, FALSE);\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, label);\n    }\n\n  if (lmin < lmax)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);\n\n    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmax - lmin);\n    label = LABEL();\n    jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n    move_back(common, reverse_failed, FALSE);\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, label);\n\n    JUMPHERE(jump);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);\n    }\n  }\nelse\n#endif\n  {\n  if (lmin > 0)\n    {\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmin));\n    add_jump(compiler, reverse_failed, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0));\n    }\n\n  if (lmin < lmax)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);\n\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmax - lmin));\n    OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_PTR, 0, TMP2, 0);\n    SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR);\n\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);\n    }\n  }\n\ncheck_start_used_ptr(common);\n\nif (lmin < lmax)\n  BACKTRACK_AS(vreverse_backtrack)->matchingpath = LABEL();\n\nreturn cc;\n}\n\nstatic SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc)\n{\nwhile (TRUE)\n  {\n  switch (*cc)\n    {\n    case OP_CALLOUT_STR:\n    cc += GET(cc, 1 + 2*LINK_SIZE);\n    break;\n\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_CIRC:\n    case OP_CIRCM:\n    case OP_DOLL:\n    case OP_DOLLM:\n    case OP_CALLOUT:\n    case OP_ALT:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n\n    case OP_KET:\n    return FALSE;\n\n    default:\n    return TRUE;\n    }\n  }\n}\n\nstatic PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional)\n{\nDEFINE_COMPILER;\nint framesize;\nint extrasize;\nBOOL local_quit_available = FALSE;\nBOOL needs_control_head;\nBOOL end_block_size = 0;\nBOOL has_vreverse;\nint private_data_ptr;\nbacktrack_common altbacktrack;\nPCRE2_SPTR ccbegin;\nPCRE2_UCHAR opcode;\nPCRE2_UCHAR bra = OP_BRA;\njump_list *tmp = NULL;\njump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.own_backtracks;\njump_list **found;\n/* Saving previous accept variables. */\nBOOL save_local_quit_available = common->local_quit_available;\nBOOL save_in_positive_assertion = common->in_positive_assertion;\nsljit_s32 save_restore_end_ptr = common->restore_end_ptr;\nthen_trap_backtrack *save_then_trap = common->then_trap;\nstruct sljit_label *save_quit_label = common->quit_label;\nstruct sljit_label *save_accept_label = common->accept_label;\njump_list *save_quit = common->quit;\njump_list *save_positive_assertion_quit = common->positive_assertion_quit;\njump_list *save_accept = common->accept;\nstruct sljit_jump *jump;\nstruct sljit_jump *brajump = NULL;\n\n/* Assert captures then. */\ncommon->then_trap = NULL;\n\nif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)\n  {\n  SLJIT_ASSERT(!conditional);\n  bra = *cc;\n  cc++;\n  }\n\nprivate_data_ptr = PRIVATE_DATA(cc);\nSLJIT_ASSERT(private_data_ptr != 0);\nframesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);\nbacktrack->framesize = framesize;\nbacktrack->private_data_ptr = private_data_ptr;\nopcode = *cc;\nSLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);\nfound = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;\nccbegin = cc;\ncc += GET(cc, 1);\n\nif (bra == OP_BRAMINZERO)\n  {\n  /* This is a braminzero backtrack path. */\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n  brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n  }\n\nif ((opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NOT) && find_vreverse(ccbegin))\n  end_block_size = 3;\n\nif (framesize < 0)\n  {\n  extrasize = 1;\n  if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))\n    extrasize = 0;\n\n  extrasize += end_block_size;\n\n  if (needs_control_head)\n    extrasize++;\n\n  if (framesize == no_frame)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);\n\n  if (extrasize > 0)\n    allocate_stack(common, extrasize);\n\n  if (needs_control_head)\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n\n  if (extrasize > 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n\n  if (needs_control_head)\n    {\n    SLJIT_ASSERT(extrasize == end_block_size + 2);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0);\n    }\n  }\nelse\n  {\n  extrasize = (needs_control_head ? 3 : 2) + end_block_size;\n\n  OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);\n  allocate_stack(common, framesize + extrasize);\n\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);\n  if (needs_control_head)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n\n  if (needs_control_head)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 2), TMP1, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP2, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);\n    }\n  else\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0);\n\n  init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize);\n  }\n\nif (end_block_size > 0)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_END, 0);\n  OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0);\n  }\n\nmemset(&altbacktrack, 0, sizeof(backtrack_common));\nif (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))\n  {\n  /* Control verbs cannot escape from these asserts. */\n  local_quit_available = TRUE;\n  common->restore_end_ptr = 0;\n  common->local_quit_available = TRUE;\n  common->quit_label = NULL;\n  common->quit = NULL;\n  }\n\ncommon->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);\ncommon->positive_assertion_quit = NULL;\n\nwhile (1)\n  {\n  common->accept_label = NULL;\n  common->accept = NULL;\n  altbacktrack.top = NULL;\n  altbacktrack.own_backtracks = NULL;\n\n  if (*ccbegin == OP_ALT && extrasize > 0)\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n\n  altbacktrack.cc = ccbegin;\n  ccbegin += 1 + LINK_SIZE;\n\n  has_vreverse = (*ccbegin == OP_VREVERSE);\n  if (*ccbegin == OP_REVERSE || has_vreverse)\n    ccbegin = compile_reverse_matchingpath(common, ccbegin, &altbacktrack);\n\n  compile_matchingpath(common, ccbegin, cc, &altbacktrack);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    {\n    if (local_quit_available)\n      {\n      common->local_quit_available = save_local_quit_available;\n      common->quit_label = save_quit_label;\n      common->quit = save_quit;\n      }\n    common->in_positive_assertion = save_in_positive_assertion;\n    common->restore_end_ptr = save_restore_end_ptr;\n    common->then_trap = save_then_trap;\n    common->accept_label = save_accept_label;\n    common->positive_assertion_quit = save_positive_assertion_quit;\n    common->accept = save_accept;\n    return NULL;\n    }\n\n  if (has_vreverse)\n    {\n    SLJIT_ASSERT(altbacktrack.top != NULL);\n    add_jump(compiler, &altbacktrack.top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));\n    }\n\n  common->accept_label = LABEL();\n  if (common->accept != NULL)\n    set_jumps(common->accept, common->accept_label);\n\n  /* Reset stack. */\n  if (framesize < 0)\n    {\n    if (framesize == no_frame)\n      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    else if (extrasize > 0)\n      free_stack(common, extrasize);\n\n    if (end_block_size > 0)\n      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1));\n\n    if (needs_control_head)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));\n    }\n  else\n    {\n    if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)\n      {\n      /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */\n      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));\n\n      if (end_block_size > 0)\n        OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 2));\n\n      if (needs_control_head)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));\n      }\n    else\n      {\n      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n\n      if (end_block_size > 0)\n        OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize + 1));\n\n      if (needs_control_head)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2));\n      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));\n      }\n    }\n\n  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)\n    {\n    /* We know that STR_PTR was stored on the top of the stack. */\n    if (conditional)\n      {\n      if (extrasize > 0)\n        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-end_block_size - (needs_control_head ? 2 : 1)));\n      }\n    else if (bra == OP_BRAZERO)\n      {\n      if (framesize < 0)\n        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));\n      else\n        {\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));\n        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize));\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n        }\n      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else if (framesize >= 0)\n      {\n      /* For OP_BRA and OP_BRAMINZERO. */\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));\n      }\n    }\n  add_jump(compiler, found, JUMP(SLJIT_JUMP));\n\n  compile_backtrackingpath(common, altbacktrack.top);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    {\n    if (local_quit_available)\n      {\n      common->local_quit_available = save_local_quit_available;\n      common->quit_label = save_quit_label;\n      common->quit = save_quit;\n      }\n    common->in_positive_assertion = save_in_positive_assertion;\n    common->restore_end_ptr = save_restore_end_ptr;\n    common->then_trap = save_then_trap;\n    common->accept_label = save_accept_label;\n    common->positive_assertion_quit = save_positive_assertion_quit;\n    common->accept = save_accept;\n    return NULL;\n    }\n  set_jumps(altbacktrack.own_backtracks, LABEL());\n\n  if (*cc != OP_ALT)\n    break;\n\n  ccbegin = cc;\n  cc += GET(cc, 1);\n  }\n\nif (local_quit_available)\n  {\n  SLJIT_ASSERT(common->positive_assertion_quit == NULL);\n  /* Makes the check less complicated below. */\n  common->positive_assertion_quit = common->quit;\n  }\n\n/* None of them matched. */\nif (common->positive_assertion_quit != NULL)\n  {\n  jump = JUMP(SLJIT_JUMP);\n  set_jumps(common->positive_assertion_quit, LABEL());\n  SLJIT_ASSERT(framesize != no_stack);\n  if (framesize < 0)\n    OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));\n  else\n    {\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (extrasize + 1) * sizeof(sljit_sw));\n    }\n  JUMPHERE(jump);\n  }\n\nif (end_block_size > 0)\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n\nif (needs_control_head)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1));\n\nif (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)\n  {\n  /* Assert is failed. */\n  if ((conditional && extrasize > 0) || bra == OP_BRAZERO)\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n\n  if (framesize < 0)\n    {\n    /* The topmost item should be 0. */\n    if (bra == OP_BRAZERO)\n      {\n      if (extrasize >= 2)\n        free_stack(common, extrasize - 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else if (extrasize > 0)\n      free_stack(common, extrasize);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));\n    /* The topmost item should be 0. */\n    if (bra == OP_BRAZERO)\n      {\n      free_stack(common, framesize + extrasize - 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else\n      free_stack(common, framesize + extrasize);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n    }\n  jump = JUMP(SLJIT_JUMP);\n  if (bra != OP_BRAZERO)\n    add_jump(compiler, target, jump);\n\n  /* Assert is successful. */\n  set_jumps(tmp, LABEL());\n  if (framesize < 0)\n    {\n    /* We know that STR_PTR was stored on the top of the stack. */\n    if (extrasize > 0)\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));\n\n    /* Keep the STR_PTR on the top of the stack. */\n    if (bra == OP_BRAZERO)\n      {\n      /* This allocation is always successful. */\n      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n      if (extrasize >= 2)\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n      }\n    else if (bra == OP_BRAMINZERO)\n      {\n      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    }\n  else\n    {\n    if (bra == OP_BRA)\n      {\n      /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */\n      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1));\n      }\n    else\n      {\n      /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */\n      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + end_block_size + 2) * sizeof(sljit_sw));\n\n      if (extrasize == 2 + end_block_size)\n        {\n        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n        if (bra == OP_BRAMINZERO)\n          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n        }\n      else\n        {\n        SLJIT_ASSERT(extrasize == 3 + end_block_size);\n        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);\n        }\n      }\n    }\n\n  if (bra == OP_BRAZERO)\n    {\n    backtrack->matchingpath = LABEL();\n    SET_LABEL(jump, backtrack->matchingpath);\n    }\n  else if (bra == OP_BRAMINZERO)\n    {\n    JUMPTO(SLJIT_JUMP, backtrack->matchingpath);\n    JUMPHERE(brajump);\n    SLJIT_ASSERT(framesize != 0);\n    if (framesize > 0)\n      {\n      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));\n      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n      }\n    set_jumps(backtrack->common.own_backtracks, LABEL());\n    }\n  }\nelse\n  {\n  /* AssertNot is successful. */\n  if (framesize < 0)\n    {\n    if (extrasize > 0)\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n\n    if (bra != OP_BRA)\n      {\n      if (extrasize >= 2)\n        free_stack(common, extrasize - 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else if (extrasize > 0)\n      free_stack(common, extrasize);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));\n    /* The topmost item should be 0. */\n    if (bra != OP_BRA)\n      {\n      free_stack(common, framesize + extrasize - 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else\n      free_stack(common, framesize + extrasize);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n    }\n\n  if (bra == OP_BRAZERO)\n    backtrack->matchingpath = LABEL();\n  else if (bra == OP_BRAMINZERO)\n    {\n    JUMPTO(SLJIT_JUMP, backtrack->matchingpath);\n    JUMPHERE(brajump);\n    }\n\n  if (bra != OP_BRA)\n    {\n    SLJIT_ASSERT(found == &backtrack->common.own_backtracks);\n    set_jumps(backtrack->common.own_backtracks, LABEL());\n    backtrack->common.own_backtracks = NULL;\n    }\n  }\n\nif (local_quit_available)\n  {\n  common->local_quit_available = save_local_quit_available;\n  common->quit_label = save_quit_label;\n  common->quit = save_quit;\n  }\n\ncommon->in_positive_assertion = save_in_positive_assertion;\ncommon->restore_end_ptr = save_restore_end_ptr;\ncommon->then_trap = save_then_trap;\ncommon->accept_label = save_accept_label;\ncommon->positive_assertion_quit = save_positive_assertion_quit;\ncommon->accept = save_accept;\nreturn cc + 1 + LINK_SIZE;\n}\n\nstatic SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)\n{\nDEFINE_COMPILER;\nint stacksize;\n\nif (framesize < 0)\n  {\n  if (framesize == no_frame)\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  else\n    {\n    stacksize = needs_control_head ? 1 : 0;\n    if (ket != OP_KET || has_alternatives)\n      stacksize++;\n\n    if (stacksize > 0)\n      free_stack(common, stacksize);\n    }\n\n  if (needs_control_head)\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? STACK(-2) : STACK(-1));\n\n  /* TMP2 which is set here used by OP_KETRMAX below. */\n  if (ket == OP_KETRMAX)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));\n  else if (ket == OP_KETRMIN)\n    {\n    /* Move the STR_PTR to the private_data_ptr. */\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));\n    }\n  }\nelse\n  {\n  stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;\n  OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));\n  if (needs_control_head)\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));\n\n  if (ket == OP_KETRMAX)\n    {\n    /* TMP2 which is set here used by OP_KETRMAX below. */\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    }\n  }\nif (needs_control_head)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);\n}\n\nstatic SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)\n{\nDEFINE_COMPILER;\n\nif (common->capture_last_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);\n  stacksize++;\n  }\nif (!is_optimized_cbracket(common, offset >> 1))\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n  stacksize += 2;\n  }\nreturn stacksize;\n}\n\nstatic PCRE2_SPTR SLJIT_FUNC do_script_run(PCRE2_SPTR ptr, PCRE2_SPTR endptr)\n{\n  if (PRIV(script_run)(ptr, endptr, FALSE))\n    return endptr;\n  return NULL;\n}\n\n#ifdef SUPPORT_UNICODE\n\nstatic PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr)\n{\n  if (PRIV(script_run)(ptr, endptr, TRUE))\n    return endptr;\n  return NULL;\n}\n\n#endif /* SUPPORT_UNICODE */\n\nstatic void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent)\n{\nDEFINE_COMPILER;\n\nSLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n#ifdef SUPPORT_UNICODE\nsljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,\n  common->utf ? SLJIT_FUNC_ADDR(do_script_run_utf) : SLJIT_FUNC_ADDR(do_script_run));\n#else\nsljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_script_run));\n#endif\n\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);\nadd_jump(compiler, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));\n}\n\n/*\n  Handling bracketed expressions is probably the most complex part.\n\n  Stack layout naming characters:\n    S - Push the current STR_PTR\n    0 - Push a 0 (NULL)\n    A - Push the current STR_PTR. Needed for restoring the STR_PTR\n        before the next alternative. Not pushed if there are no alternatives.\n    M - Any values pushed by the current alternative. Can be empty, or anything.\n    C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.\n    L - Push the previous local (pointed by localptr) to the stack\n   () - opional values stored on the stack\n  ()* - optonal, can be stored multiple times\n\n  The following list shows the regular expression templates, their PCRE byte codes\n  and stack layout supported by pcre-sljit.\n\n  (?:)                     OP_BRA     | OP_KET                A M\n  ()                       OP_CBRA    | OP_KET                C M\n  (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*\n                           OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*\n  (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*\n                           OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*\n  ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*\n                           OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*\n  ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*\n                           OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*\n  (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )\n  (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )\n  ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )\n  ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )\n  (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*\n           OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*\n  (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*\n           OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*\n  ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*\n           OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*\n  ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*\n           OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*\n\n\n  Stack layout naming characters:\n    A - Push the alternative index (starting from 0) on the stack.\n        Not pushed if there is no alternatives.\n    M - Any values pushed by the current alternative. Can be empty, or anything.\n\n  The next list shows the possible content of a bracket:\n  (|)     OP_*BRA    | OP_ALT ...         M A\n  (?()|)  OP_*COND   | OP_ALT             M A\n  (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A\n                                          Or nothing, if trace is unnecessary\n*/\n\nstatic PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nPCRE2_UCHAR opcode;\nint private_data_ptr = 0;\nint offset = 0;\nint i, stacksize;\nint repeat_ptr = 0, repeat_length = 0;\nint repeat_type = 0, repeat_count = 0;\nPCRE2_SPTR ccbegin;\nPCRE2_SPTR matchingpath;\nPCRE2_SPTR slot;\nPCRE2_UCHAR bra = OP_BRA;\nPCRE2_UCHAR ket;\nassert_backtrack *assert;\nBOOL has_alternatives;\nBOOL needs_control_head = FALSE;\nBOOL has_vreverse = FALSE;\nstruct sljit_jump *jump;\nstruct sljit_jump *skip;\njump_list *jumplist;\nstruct sljit_label *rmax_label = NULL;\nstruct sljit_jump *braminzero = NULL;\n\nPUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);\n\nif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)\n  {\n  bra = *cc;\n  cc++;\n  opcode = *cc;\n  }\n\nopcode = *cc;\nccbegin = cc;\nmatchingpath = bracketend(cc) - 1 - LINK_SIZE;\nket = *matchingpath;\nif (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)\n  {\n  repeat_ptr = PRIVATE_DATA(matchingpath);\n  repeat_length = PRIVATE_DATA(matchingpath + 1);\n  repeat_type = PRIVATE_DATA(matchingpath + 2);\n  repeat_count = PRIVATE_DATA(matchingpath + 3);\n  SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);\n  if (repeat_type == OP_UPTO)\n    ket = OP_KETRMAX;\n  if (repeat_type == OP_MINUPTO)\n    ket = OP_KETRMIN;\n  }\n\nmatchingpath = ccbegin + 1 + LINK_SIZE;\nSLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);\nSLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));\ncc += GET(cc, 1);\n\nhas_alternatives = *cc == OP_ALT;\nif (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))\n  {\n  SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3,\n    compile_time_checks_must_be_grouped_together);\n  has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE;\n  }\n\nif (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))\n  opcode = OP_SCOND;\n\nif (opcode == OP_CBRA || opcode == OP_SCBRA)\n  {\n  /* Capturing brackets has a pre-allocated space. */\n  offset = GET2(ccbegin, 1 + LINK_SIZE);\n  if (!is_optimized_cbracket(common, offset))\n    {\n    private_data_ptr = OVECTOR_PRIV(offset);\n    offset <<= 1;\n    }\n  else\n    {\n    offset <<= 1;\n    private_data_ptr = OVECTOR(offset);\n    }\n  BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;\n  matchingpath += IMM2_SIZE;\n  }\nelse if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE\n         || opcode == OP_ASSERT_SCS || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)\n  {\n  /* Other brackets simply allocate the next entry. */\n  private_data_ptr = PRIVATE_DATA(ccbegin);\n  SLJIT_ASSERT(private_data_ptr != 0);\n  BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;\n  if (opcode == OP_ONCE)\n    BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);\n  }\n\n/* Instructions before the first alternative. */\nstacksize = 0;\nif (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))\n  stacksize++;\nif (bra == OP_BRAZERO)\n  stacksize++;\n\nif (stacksize > 0)\n  allocate_stack(common, stacksize);\n\nstacksize = 0;\nif (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);\n  stacksize++;\n  }\n\nif (bra == OP_BRAZERO)\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n\nif (bra == OP_BRAMINZERO)\n  {\n  /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  if (ket != OP_KETRMIN)\n    {\n    free_stack(common, 1);\n    braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n    }\n  else if (opcode == OP_ONCE || opcode >= OP_SBRA)\n    {\n    jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    /* Nothing stored during the first run. */\n    skip = JUMP(SLJIT_JUMP);\n    JUMPHERE(jump);\n    /* Checking zero-length iteration. */\n    if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)\n      {\n      /* When we come from outside, private_data_ptr contains the previous STR_PTR. */\n      braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      }\n    else\n      {\n      /* Except when the whole stack frame must be saved. */\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2));\n      }\n    JUMPHERE(skip);\n    }\n  else\n    {\n    jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    JUMPHERE(jump);\n    }\n  }\n\nif (repeat_type != 0)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);\n  if (repeat_type == OP_EXACT)\n    rmax_label = LABEL();\n  }\n\nif (ket == OP_KETRMIN)\n  BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();\n\nif (ket == OP_KETRMAX)\n  {\n  rmax_label = LABEL();\n  if (has_alternatives && opcode >= OP_BRA && opcode < OP_SBRA && repeat_type == 0)\n    BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;\n  }\n\n/* Handling capturing brackets and alternatives. */\nif (opcode == OP_ONCE)\n  {\n  stacksize = 0;\n  if (needs_control_head)\n    {\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n    stacksize++;\n    }\n\n  if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)\n    {\n    /* Neither capturing brackets nor recursions are found in the block. */\n    if (ket == OP_KETRMIN)\n      {\n      stacksize += 2;\n      if (!needs_control_head)\n        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      }\n    else\n      {\n      if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);\n      if (ket == OP_KETRMAX || has_alternatives)\n        stacksize++;\n      }\n\n    if (stacksize > 0)\n      allocate_stack(common, stacksize);\n\n    stacksize = 0;\n    if (needs_control_head)\n      {\n      stacksize++;\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n      }\n\n    if (ket == OP_KETRMIN)\n      {\n      if (needs_control_head)\n        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n      if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)\n        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);\n      }\n    else if (ket == OP_KETRMAX || has_alternatives)\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n    }\n  else\n    {\n    if (ket != OP_KET || has_alternatives)\n      stacksize++;\n\n    stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;\n    allocate_stack(common, stacksize);\n\n    if (needs_control_head)\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));\n\n    stacksize = needs_control_head ? 1 : 0;\n    if (ket != OP_KET || has_alternatives)\n      {\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);\n      stacksize++;\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);\n      }\n    else\n      {\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);\n      }\n    init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1);\n    }\n  }\nelse if (opcode == OP_CBRA || opcode == OP_SCBRA)\n  {\n  /* Saving the previous values. */\n  if (is_optimized_cbracket(common, offset >> 1))\n    {\n    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));\n    allocate_stack(common, 2);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    allocate_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n    }\n  }\nelse if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1))\n  {\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  allocate_stack(common, 4);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);\n  OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0);\n\n  has_vreverse = (*matchingpath == OP_VREVERSE);\n  if (*matchingpath == OP_REVERSE || has_vreverse)\n    matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack);\n  }\nelse if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)\n  {\n  /* Saving the previous value. */\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  allocate_stack(common, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n\n  if (*matchingpath == OP_REVERSE)\n    matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack);\n  }\nelse if (opcode == OP_ASSERT_SCS)\n  {\n  /* Nested scs blocks will not update this variable. */\n  if (common->restore_end_ptr == 0)\n    common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw);\n\n  if (*matchingpath == OP_CREF && (matchingpath[1 + IMM2_SIZE] != OP_CREF && matchingpath[1 + IMM2_SIZE] != OP_DNCREF))\n    {\n    /* Optimized case for a single capture reference. */\n    i = OVECTOR(GET2(matchingpath, 1) << 1);\n\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), i);\n\n    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));\n    matchingpath += 1 + IMM2_SIZE;\n\n    allocate_stack(common, has_alternatives ? 3 : 2);\n\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0);\n    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), i + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));\n    jumplist = NULL;\n\n    while (TRUE)\n      {\n      if (*matchingpath == OP_CREF)\n        {\n        sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(matchingpath, 1) << 1));\n        matchingpath += 1 + IMM2_SIZE;\n        }\n      else\n        {\n        SLJIT_ASSERT(*matchingpath == OP_DNCREF);\n\n        i = GET2(matchingpath, 1 + IMM2_SIZE);\n        slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;\n\n        while (i-- > 1)\n          {\n          sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1));\n          add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0));\n          slot += common->name_entry_size;\n          }\n\n        sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1));\n        matchingpath += 1 + 2 * IMM2_SIZE;\n        }\n\n      if (*matchingpath != OP_CREF && *matchingpath != OP_DNCREF)\n        break;\n\n      add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0));\n      }\n\n    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture),\n      CMP(SLJIT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0));\n\n    set_jumps(jumplist, LABEL());\n\n    allocate_stack(common, has_alternatives ? 3 : 2);\n\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0);\n    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));\n    }\n\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_TMP_DEST_REG, 0);\n\n  if (has_alternatives)\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);\n  }\nelse if (has_alternatives)\n  {\n  /* Pushing the starting string pointer. */\n  allocate_stack(common, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n  }\n\n/* Generating code for the first alternative. */\nif (opcode == OP_COND || opcode == OP_SCOND)\n  {\n  if (*matchingpath == OP_CREF)\n    {\n    SLJIT_ASSERT(has_alternatives);\n    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture),\n      CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));\n    matchingpath += 1 + IMM2_SIZE;\n    }\n  else if (*matchingpath == OP_DNCREF)\n    {\n    SLJIT_ASSERT(has_alternatives);\n\n    i = GET2(matchingpath, 1 + IMM2_SIZE);\n    slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;\n    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);\n    slot += common->name_entry_size;\n    i--;\n    while (i-- > 0)\n      {\n      OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);\n      OP2(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, STR_PTR, 0);\n      slot += common->name_entry_size;\n      }\n    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), JUMP(SLJIT_ZERO));\n    matchingpath += 1 + 2 * IMM2_SIZE;\n    }\n  else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL)\n    {\n    /* Never has other case. */\n    BACKTRACK_AS(bracket_backtrack)->u.no_capture = NULL;\n    SLJIT_ASSERT(!has_alternatives);\n\n    if (*matchingpath == OP_TRUE)\n      {\n      stacksize = 1;\n      matchingpath++;\n      }\n    else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL)\n      stacksize = 0;\n    else if (*matchingpath == OP_RREF)\n      {\n      stacksize = GET2(matchingpath, 1);\n      if (common->currententry == NULL)\n        stacksize = 0;\n      else if (stacksize == RREF_ANY)\n        stacksize = 1;\n      else if (common->currententry->start == 0)\n        stacksize = stacksize == 0;\n      else\n        stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);\n\n      if (stacksize != 0)\n        matchingpath += 1 + IMM2_SIZE;\n      }\n    else\n      {\n      if (common->currententry == NULL || common->currententry->start == 0)\n        stacksize = 0;\n      else\n        {\n        stacksize = GET2(matchingpath, 1 + IMM2_SIZE);\n        slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;\n        i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);\n        while (stacksize > 0)\n          {\n          if ((int)GET2(slot, 0) == i)\n            break;\n          slot += common->name_entry_size;\n          stacksize--;\n          }\n        }\n\n      if (stacksize != 0)\n        matchingpath += 1 + 2 * IMM2_SIZE;\n      }\n\n      /* The stacksize == 0 is a common \"else\" case. */\n      if (stacksize == 0)\n        {\n        if (*cc == OP_ALT)\n          {\n          matchingpath = cc + 1 + LINK_SIZE;\n          cc += GET(cc, 1);\n          }\n        else\n          matchingpath = cc;\n        }\n    }\n  else\n    {\n    SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);\n    /* Similar code as PUSH_BACKTRACK macro. */\n    assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));\n    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n      return NULL;\n    memset(assert, 0, sizeof(assert_backtrack));\n    assert->common.cc = matchingpath;\n    BACKTRACK_AS(bracket_backtrack)->u.assert = assert;\n    matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);\n    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n      return NULL;\n    }\n  }\n\ncompile_matchingpath(common, matchingpath, cc, backtrack);\nif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n  return NULL;\n\nswitch (opcode)\n  {\n  case OP_ASSERTBACK_NA:\n    if (has_vreverse)\n      {\n      SLJIT_ASSERT(backtrack->top != NULL && PRIVATE_DATA(ccbegin + 1));\n      add_jump(compiler, &backtrack->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));\n      }\n\n    if (PRIVATE_DATA(ccbegin + 1))\n      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n    break;\n  case OP_ONCE:\n    match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);\n    break;\n  case OP_SCRIPT_RUN:\n    match_script_run_common(common, private_data_ptr, backtrack);\n    break;\n  }\n\nstacksize = 0;\nif (repeat_type == OP_MINUPTO)\n  {\n  /* We need to preserve the counter. TMP2 will be used below. */\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);\n  stacksize++;\n  }\nif (ket != OP_KET || bra != OP_BRA)\n  stacksize++;\nif (offset != 0)\n  {\n  if (common->capture_last_ptr != 0)\n    stacksize++;\n  if (!is_optimized_cbracket(common, offset >> 1))\n    stacksize += 2;\n  }\nif (has_alternatives && opcode != OP_ONCE)\n  stacksize++;\n\nif (stacksize > 0)\n  allocate_stack(common, stacksize);\n\nstacksize = 0;\nif (repeat_type == OP_MINUPTO)\n  {\n  /* TMP2 was set above. */\n  OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);\n  stacksize++;\n  }\n\nif (ket != OP_KET || bra != OP_BRA)\n  {\n  if (ket != OP_KET)\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n  else\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);\n  stacksize++;\n  }\n\nif (offset != 0)\n  stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);\n\n/* Skip and count the other alternatives. */\ni = 1;\nwhile (*cc == OP_ALT)\n  {\n  cc += GET(cc, 1);\n  i++;\n  }\n\nif (has_alternatives)\n  {\n  if (opcode != OP_ONCE)\n    {\n    if (i <= 3)\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);\n    else\n      BACKTRACK_AS(bracket_backtrack)->matching_mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(stacksize));\n    }\n  if (ket != OP_KETRMAX)\n    BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();\n  }\n\n/* Must be after the matchingpath label. */\nif (offset != 0 && is_optimized_cbracket(common, offset >> 1))\n  {\n  SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\n  }\nelse switch (opcode)\n  {\n  case OP_ASSERT_NA:\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    break;\n  case OP_ASSERT_SCS:\n    OP1(SLJIT_MOV, TMP1, 0, STR_END, 0);\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0);\n\n    /* Nested scs blocks will not update this variable. */\n    if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw))\n      common->restore_end_ptr = 0;\n    break;\n  }\n\nif (ket == OP_KETRMAX)\n  {\n  if (repeat_type != 0)\n    {\n    if (has_alternatives)\n      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();\n    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, rmax_label);\n    /* Drop STR_PTR for greedy plus quantifier. */\n    if (opcode != OP_ONCE)\n      free_stack(common, 1);\n    }\n  else if (opcode < OP_BRA || opcode >= OP_SBRA)\n    {\n    if (has_alternatives)\n      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();\n\n    /* Checking zero-length iteration. */\n    if (opcode != OP_ONCE)\n      {\n      /* This case includes opcodes such as OP_SCRIPT_RUN. */\n      CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);\n      /* Drop STR_PTR for greedy plus quantifier. */\n      if (bra != OP_BRAZERO)\n        free_stack(common, 1);\n      }\n    else\n      /* TMP2 must contain the starting STR_PTR. */\n      CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);\n    }\n  else\n    JUMPTO(SLJIT_JUMP, rmax_label);\n  BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();\n  }\n\nif (repeat_type == OP_EXACT)\n  {\n  count_match(common);\n  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);\n  JUMPTO(SLJIT_NOT_ZERO, rmax_label);\n  }\nelse if (repeat_type == OP_UPTO)\n  {\n  /* We need to preserve the counter. */\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);\n  allocate_stack(common, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n  }\n\nif (bra == OP_BRAZERO)\n  BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();\n\nif (bra == OP_BRAMINZERO)\n  {\n  /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */\n  JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);\n  if (braminzero != NULL)\n    {\n    JUMPHERE(braminzero);\n    /* We need to release the end pointer to perform the\n    backtrack for the zero-length iteration. When\n    framesize is < 0, OP_ONCE will do the release itself. */\n    if (opcode == OP_ONCE)\n      {\n      int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize;\n\n      SLJIT_ASSERT(framesize != 0);\n      if (framesize > 0)\n        {\n        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));\n        }\n      }\n    else if (ket == OP_KETRMIN)\n      free_stack(common, 1);\n    }\n  /* Continue to the normal backtrack. */\n  }\n\nif ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO || (has_alternatives && repeat_type != OP_EXACT))\n  count_match(common);\n\ncc += 1 + LINK_SIZE;\n\nif (opcode == OP_ONCE)\n  {\n  int data;\n  int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize;\n\n  SLJIT_ASSERT(SHRT_MIN <= framesize && framesize < SHRT_MAX/2);\n  /* We temporarily encode the needs_control_head in the lowest bit.\n     The real value should be short enough for this operation to work\n     without triggering Undefined Behaviour. */\n  data = (int)((short)((unsigned short)framesize << 1) | (needs_control_head ? 1 : 0));\n  BACKTRACK_AS(bracket_backtrack)->u.framesize = data;\n  }\nreturn cc + repeat_length;\n}\n\nstatic PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nPCRE2_UCHAR opcode;\nint private_data_ptr;\nint cbraprivptr = 0;\nBOOL needs_control_head;\nint framesize;\nint stacksize;\nint offset = 0;\nBOOL zero = FALSE;\nPCRE2_SPTR ccbegin = NULL;\nint stack; /* Also contains the offset of control head. */\nstruct sljit_label *loop = NULL;\nstruct jump_list *emptymatch = NULL;\n\nPUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);\nif (*cc == OP_BRAPOSZERO)\n  {\n  zero = TRUE;\n  cc++;\n  }\n\nopcode = *cc;\nprivate_data_ptr = PRIVATE_DATA(cc);\nSLJIT_ASSERT(private_data_ptr != 0);\nBACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;\nswitch(opcode)\n  {\n  case OP_BRAPOS:\n  case OP_SBRAPOS:\n  ccbegin = cc + 1 + LINK_SIZE;\n  break;\n\n  case OP_CBRAPOS:\n  case OP_SCBRAPOS:\n  offset = GET2(cc, 1 + LINK_SIZE);\n  /* This case cannot be optimized in the same way as\n  normal capturing brackets. */\n  SLJIT_ASSERT(!is_optimized_cbracket(common, offset));\n  cbraprivptr = OVECTOR_PRIV(offset);\n  offset <<= 1;\n  ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;\n  break;\n\n  default:\n  SLJIT_UNREACHABLE();\n  break;\n  }\n\nframesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);\nBACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;\nif (framesize < 0)\n  {\n  if (offset != 0)\n    {\n    stacksize = 2;\n    if (common->capture_last_ptr != 0)\n      stacksize++;\n    }\n  else\n    stacksize = 1;\n\n  if (needs_control_head)\n    stacksize++;\n  if (!zero)\n    stacksize++;\n\n  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;\n  allocate_stack(common, stacksize);\n  if (framesize == no_frame)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);\n\n  stack = 0;\n  if (offset != 0)\n    {\n    stack = 2;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);\n    if (common->capture_last_ptr != 0)\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);\n    if (needs_control_head)\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n    if (common->capture_last_ptr != 0)\n      {\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);\n      stack = 3;\n      }\n    }\n  else\n    {\n    if (needs_control_head)\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n    stack = 1;\n    }\n\n  if (needs_control_head)\n    stack++;\n  if (!zero)\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);\n  if (needs_control_head)\n    {\n    stack--;\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);\n    }\n  }\nelse\n  {\n  stacksize = framesize + 1;\n  if (!zero)\n    stacksize++;\n  if (needs_control_head)\n    stacksize++;\n  if (offset == 0)\n    stacksize++;\n  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;\n\n  allocate_stack(common, stacksize);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n  if (needs_control_head)\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n  OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));\n\n  stack = 0;\n  if (!zero)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);\n    stack = 1;\n    }\n  if (needs_control_head)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);\n    stack++;\n    }\n  if (offset == 0)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);\n    stack++;\n    }\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);\n  init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize);\n  stack -= 1 + (offset == 0);\n  }\n\nif (offset != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);\n\nloop = LABEL();\nwhile (*cc != OP_KETRPOS)\n  {\n  backtrack->top = NULL;\n  backtrack->own_backtracks = NULL;\n  cc += GET(cc, 1);\n\n  compile_matchingpath(common, ccbegin, cc, backtrack);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    return NULL;\n\n  if (framesize < 0)\n    {\n    if (framesize == no_frame)\n      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n\n    if (offset != 0)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);\n      if (common->capture_last_ptr != 0)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n      }\n    else\n      {\n      if (opcode == OP_SBRAPOS)\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n      }\n\n    /* Even if the match is empty, we need to reset the control head. */\n    if (needs_control_head)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));\n\n    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)\n      add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));\n\n    if (!zero)\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);\n    }\n  else\n    {\n    if (offset != 0)\n      {\n      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);\n      if (common->capture_last_ptr != 0)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n      }\n    else\n      {\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      OP2(SLJIT_SUB, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));\n      if (opcode == OP_SBRAPOS)\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));\n      OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(-framesize - 2), STR_PTR, 0);\n      }\n\n    /* Even if the match is empty, we need to reset the control head. */\n    if (needs_control_head)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));\n\n    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)\n      add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));\n\n    if (!zero)\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n    }\n\n  JUMPTO(SLJIT_JUMP, loop);\n  flush_stubs(common);\n\n  compile_backtrackingpath(common, backtrack->top);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    return NULL;\n  set_jumps(backtrack->own_backtracks, LABEL());\n\n  if (framesize < 0)\n    {\n    if (offset != 0)\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);\n    else\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    }\n  else\n    {\n    if (offset != 0)\n      {\n      /* Last alternative. */\n      if (*cc == OP_KETRPOS)\n        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);\n      }\n    else\n      {\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));\n      }\n    }\n\n  if (*cc == OP_KETRPOS)\n    break;\n  ccbegin = cc + 1 + LINK_SIZE;\n  }\n\n/* We don't have to restore the control head in case of a failed match. */\n\nbacktrack->own_backtracks = NULL;\nif (!zero)\n  {\n  if (framesize < 0)\n    add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));\n  else /* TMP2 is set to [private_data_ptr] above. */\n    add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0));\n  }\n\n/* None of them matched. */\nset_jumps(emptymatch, LABEL());\ncount_match(common);\nreturn cc + 1 + LINK_SIZE;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end)\n{\nint class_len;\n\n*opcode = *cc;\n*exact = 0;\n\nif (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)\n  {\n  cc++;\n  *type = OP_CHAR;\n  }\nelse if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)\n  {\n  cc++;\n  *type = OP_CHARI;\n  *opcode -= OP_STARI - OP_STAR;\n  }\nelse if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)\n  {\n  cc++;\n  *type = OP_NOT;\n  *opcode -= OP_NOTSTAR - OP_STAR;\n  }\nelse if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)\n  {\n  cc++;\n  *type = OP_NOTI;\n  *opcode -= OP_NOTSTARI - OP_STAR;\n  }\nelse if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)\n  {\n  cc++;\n  *opcode -= OP_TYPESTAR - OP_STAR;\n  *type = OP_END;\n  }\nelse\n  {\n  SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS || *opcode == OP_ECLASS);\n  *type = *opcode;\n  class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 1);\n  *opcode = cc[class_len];\n  cc++;\n\n  if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)\n    {\n    *opcode -= OP_CRSTAR - OP_STAR;\n    *end = cc + class_len;\n\n    if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)\n      {\n      *exact = 1;\n      *opcode -= OP_PLUS - OP_STAR;\n      }\n    return cc;\n    }\n\n  if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)\n    {\n    *opcode -= OP_CRPOSSTAR - OP_POSSTAR;\n    *end = cc + class_len;\n\n    if (*opcode == OP_POSPLUS)\n      {\n      *exact = 1;\n      *opcode = OP_POSSTAR;\n      }\n    return cc;\n    }\n\n  SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);\n  *max = GET2(cc, (class_len + IMM2_SIZE));\n  *exact = GET2(cc, class_len);\n  *end = cc + class_len + 2 * IMM2_SIZE;\n\n  if (*max == 0)\n    {\n    SLJIT_ASSERT(*exact > 1);\n    if (*opcode == OP_CRRANGE)\n      *opcode = OP_UPTO;\n    else if (*opcode == OP_CRPOSRANGE)\n      *opcode = OP_POSUPTO;\n    else\n      *opcode = OP_MINSTAR;\n    return cc;\n    }\n\n  *max -= *exact;\n  if (*max == 0)\n    *opcode = OP_EXACT;\n  else\n    {\n    SLJIT_ASSERT(*exact > 0 || *max > 1);\n    if (*opcode == OP_CRRANGE)\n      *opcode = OP_UPTO;\n    else if (*opcode == OP_CRPOSRANGE)\n      *opcode = OP_POSUPTO;\n    else if (*max == 1)\n      *opcode = OP_MINQUERY;\n    else\n      *opcode = OP_MINUPTO;\n    }\n  return cc;\n  }\n\nswitch(*opcode)\n  {\n  case OP_EXACT:\n  *exact = GET2(cc, 0);\n  cc += IMM2_SIZE;\n  break;\n\n  case OP_PLUS:\n  case OP_MINPLUS:\n  *exact = 1;\n  *opcode -= OP_PLUS - OP_STAR;\n  break;\n\n  case OP_POSPLUS:\n  *exact = 1;\n  *opcode = OP_POSSTAR;\n  break;\n\n  case OP_UPTO:\n  case OP_MINUPTO:\n  case OP_POSUPTO:\n  *max = GET2(cc, 0);\n  cc += IMM2_SIZE;\n  break;\n  }\n\nif (*type == OP_END)\n  {\n  *type = *cc;\n  *end = next_opcode(common, cc);\n  cc++;\n  return cc;\n  }\n\n*end = cc + 1;\n#ifdef SUPPORT_UNICODE\nif (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);\n#endif\nreturn cc;\n}\n\nstatic PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent, jump_list **prev_backtracks)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack = NULL;\nPCRE2_SPTR begin = cc;\nPCRE2_UCHAR opcode;\nPCRE2_UCHAR type;\nsljit_u32 max = 0, exact;\nsljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1);\nsljit_s32 early_fail_type;\nBOOL charpos_enabled, use_tmp;\nPCRE2_UCHAR charpos_char;\nunsigned int charpos_othercasebit;\nPCRE2_SPTR end;\njump_list *no_match = NULL;\njump_list *no_char1_match = NULL;\nstruct sljit_jump *jump = NULL;\nstruct sljit_label *label;\nint private_data_ptr = PRIVATE_DATA(cc);\nint base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);\nint offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;\nint offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);\nint tmp_base, tmp_offset;\n\nearly_fail_type = (early_fail_ptr & 0x7);\nearly_fail_ptr >>= 3;\n\n/* During recursion, these optimizations are disabled. */\nif (common->early_fail_start_ptr == 0 && common->fast_forward_bc_ptr == NULL)\n  {\n  early_fail_ptr = 0;\n  early_fail_type = type_skip;\n  }\n\nSLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0\n  || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr));\n\nif (early_fail_type == type_fail)\n  add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr));\n\ncc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);\n\nif (type != OP_EXTUNI)\n  {\n  tmp_base = TMP3;\n  tmp_offset = 0;\n  }\nelse\n  {\n  tmp_base = SLJIT_MEM1(SLJIT_SP);\n  tmp_offset = LOCAL2;\n  }\n\nif (opcode == OP_EXACT)\n  {\n  SLJIT_ASSERT(early_fail_ptr == 0 && exact >= 2);\n\n  if (common->mode == PCRE2_JIT_COMPLETE\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n      && !common->utf\n#endif\n      && type != OP_ANYNL && type != OP_EXTUNI)\n    {\n    OP2(SLJIT_SUB, TMP1, 0, STR_END, 0, STR_PTR, 0);\n    add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, IN_UCHARS(exact)));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32\n    if (type == OP_ALLANY && !common->invalid_utf)\n#else\n    if (type == OP_ALLANY)\n#endif\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));\n    else\n      {\n      OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);\n      label = LABEL();\n      compile_char1_matchingpath(common, type, cc, prev_backtracks, FALSE);\n      OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);\n      JUMPTO(SLJIT_NOT_ZERO, label);\n      }\n    }\n  else\n    {\n    SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw));\n    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);\n    label = LABEL();\n    compile_char1_matchingpath(common, type, cc, prev_backtracks, TRUE);\n    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, label);\n    }\n  }\n\nif (early_fail_type == type_fail_range)\n  {\n  /* Range end first, followed by range start. */\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw));\n  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);\n  OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);\n  add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));\n\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0);\n  }\n\nif (opcode < OP_EXACT)\n  PUSH_BACKTRACK(sizeof(char_iterator_backtrack), begin, NULL);\n\nswitch(opcode)\n  {\n  case OP_STAR:\n  case OP_UPTO:\n  SLJIT_ASSERT(backtrack != NULL && (early_fail_ptr == 0 || opcode == OP_STAR));\n  max += exact;\n\n  if (type == OP_EXTUNI)\n    {\n    SLJIT_ASSERT(private_data_ptr == 0);\n    SLJIT_ASSERT(early_fail_ptr == 0);\n\n    if (exact == 1)\n      {\n      SLJIT_ASSERT(opcode == OP_STAR);\n      allocate_stack(common, 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      }\n    else\n      {\n      /* If OP_EXTUNI is present, it has a separate EXACT opcode. */\n      SLJIT_ASSERT(exact == 0);\n\n      allocate_stack(common, 2);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);\n      }\n\n    if (opcode == OP_UPTO)\n      {\n      SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, SLJIT_IMM, max);\n      }\n\n    label = LABEL();\n    compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE);\n    if (opcode == OP_UPTO)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n      OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\n      jump = JUMP(SLJIT_ZERO);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, TMP1, 0);\n      }\n\n    /* We cannot use TMP3 because of allocate_stack. */\n    allocate_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n    JUMPTO(SLJIT_JUMP, label);\n    if (jump != NULL)\n      JUMPHERE(jump);\n    BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n    break;\n    }\n#ifdef SUPPORT_UNICODE\n  else if (type == OP_ALLANY && !common->invalid_utf)\n#else\n  else if (type == OP_ALLANY)\n#endif\n    {\n    if (opcode == OP_STAR)\n      {\n      if (exact == 1)\n        detect_partial_match(common, prev_backtracks);\n\n      if (private_data_ptr == 0)\n        allocate_stack(common, 2);\n\n      OP1(SLJIT_MOV, base, offset0, STR_END, 0);\n      OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);\n\n      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);\n      process_partial_match(common);\n\n      if (early_fail_ptr != 0)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);\n      BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n      break;\n      }\n#ifdef SUPPORT_UNICODE\n    else if (!common->utf)\n#else\n    else\n#endif\n      {\n      /* If OP_ALLANY is present, it has a separate EXACT opcode. */\n      SLJIT_ASSERT(exact == 0);\n\n      if (private_data_ptr == 0)\n        allocate_stack(common, 2);\n\n      OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));\n\n      if (common->mode == PCRE2_JIT_COMPLETE)\n        {\n        OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n        SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n        }\n      else\n        {\n        jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);\n        process_partial_match(common);\n        JUMPHERE(jump);\n        }\n\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n\n      if (early_fail_ptr != 0)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n      BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n      break;\n      }\n    }\n\n  charpos_enabled = FALSE;\n  charpos_char = 0;\n  charpos_othercasebit = 0;\n\n  SLJIT_ASSERT(tmp_base == TMP3);\n  if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))\n    {\n#ifdef SUPPORT_UNICODE\n    charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);\n#else\n    charpos_enabled = TRUE;\n#endif\n    if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))\n      {\n      charpos_othercasebit = char_get_othercase_bit(common, end + 1);\n      if (charpos_othercasebit == 0)\n        charpos_enabled = FALSE;\n      }\n\n    if (charpos_enabled)\n      {\n      charpos_char = end[1];\n      /* Consume the OP_CHAR opcode. */\n      end += 2;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);\n#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n      SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);\n      if ((charpos_othercasebit & 0x100) != 0)\n        charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;\n#endif\n      if (charpos_othercasebit != 0)\n        charpos_char |= charpos_othercasebit;\n\n      BACKTRACK_AS(char_iterator_backtrack)->charpos.charpos_enabled = TRUE;\n      BACKTRACK_AS(char_iterator_backtrack)->charpos.chr = charpos_char;\n      BACKTRACK_AS(char_iterator_backtrack)->charpos.othercasebit = charpos_othercasebit;\n\n      if (private_data_ptr == 0)\n        allocate_stack(common, 2);\n\n      use_tmp = (opcode == OP_STAR);\n\n      if (use_tmp)\n        {\n        OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);\n        OP1(SLJIT_MOV, base, offset0, TMP3, 0);\n        }\n      else\n        {\n        OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0);\n        OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, 0);\n        OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0);\n        OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : (max + 1));\n        }\n\n      /* Search the first instance of charpos_char. */\n      if (exact > 0)\n        detect_partial_match(common, &no_match);\n      else\n        jump = JUMP(SLJIT_JUMP);\n\n      label = LABEL();\n\n      if (opcode == OP_UPTO)\n        {\n        if (exact == max)\n          OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n        else\n          {\n          OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n          add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));\n          }\n        }\n\n      compile_char1_matchingpath(common, type, cc, &no_match, FALSE);\n\n      if (early_fail_ptr != 0)\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n\n      if (exact == 0)\n        JUMPHERE(jump);\n\n      detect_partial_match(common, &no_match);\n\n      if (opcode == OP_UPTO && exact > 0)\n        {\n        if (exact == max)\n          CMPTO(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact, label);\n        else\n          CMPTO(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, (max + 1) - exact, label);\n        }\n\n      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n      if (charpos_othercasebit != 0)\n        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);\n      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);\n\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n      if (use_tmp)\n        {\n        OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, SLJIT_IMM, 0);\n        SELECT(SLJIT_EQUAL, TMP3, STR_PTR, 0, TMP3);\n        }\n      else\n        {\n        OP2U(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, SLJIT_IMM, 0);\n        SELECT(SLJIT_EQUAL, COUNT_MATCH, STR_PTR, 0, COUNT_MATCH);\n        }\n      JUMPTO(SLJIT_JUMP, label);\n\n      set_jumps(no_match, LABEL());\n      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n      if (use_tmp)\n        OP1(SLJIT_MOV, base, offset1, TMP3, 0);\n      else\n        {\n        OP1(SLJIT_MOV, TMP1, 0, base, offset1);\n        OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0);\n        OP1(SLJIT_MOV, COUNT_MATCH, 0, TMP1, 0);\n        }\n\n      add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0));\n\n      BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n      break;\n      }\n    }\n\n  if (private_data_ptr == 0)\n    allocate_stack(common, 2);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n  use_tmp = (opcode == OP_STAR);\n\n  if (common->utf)\n    {\n    if (!use_tmp)\n      OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0);\n\n    OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0);\n    }\n#endif\n\n  if (opcode == OP_UPTO)\n    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? -(sljit_sw)exact : (sljit_sw)max);\n\n  if (opcode == OP_UPTO && exact > 0)\n    {\n    label = LABEL();\n    detect_partial_match(common, &no_match);\n    compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0);\n#endif\n\n    if (exact == max)\n      {\n      OP2(SLJIT_ADD | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n      JUMPTO(SLJIT_NOT_ZERO, label);\n      }\n    else\n      {\n      OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n      add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));\n      CMPTO(SLJIT_NOT_EQUAL, TMP3, 0, SLJIT_IMM, max - exact, label);\n      }\n\n    OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);\n    JUMPTO(SLJIT_JUMP, label);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);\n\n    detect_partial_match(common, &no_match);\n    label = LABEL();\n    compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n    if (common->utf)\n      OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0);\n#endif\n\n    if (opcode == OP_UPTO)\n      {\n      OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n      add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));\n      }\n\n    detect_partial_match_to(common, label);\n    }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n  if (common->utf)\n    {\n    set_jumps(no_char1_match, LABEL());\n    set_jumps(no_match, LABEL());\n    if (use_tmp)\n      {\n      OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n      OP1(SLJIT_MOV, base, offset0, TMP3, 0);\n      }\n    else\n      {\n      OP1(SLJIT_MOV, STR_PTR, 0, COUNT_MATCH, 0);\n      OP1(SLJIT_MOV, COUNT_MATCH, 0, base, offset0);\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n      }\n    }\n  else\n#endif\n    {\n    if (opcode != OP_UPTO || exact == 0)\n      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    set_jumps(no_char1_match, LABEL());\n\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n    set_jumps(no_match, LABEL());\n    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    }\n\n  if (opcode == OP_UPTO)\n    {\n    if (exact > 0)\n      {\n      if (max == exact)\n        jump = CMP(SLJIT_GREATER_EQUAL, TMP3, 0, SLJIT_IMM, -(sljit_sw)exact);\n      else\n        jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact);\n\n      add_jump(compiler, &backtrack->own_backtracks, jump);\n      }\n    }\n  else if (exact == 1)\n    add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, base, offset1, STR_PTR, 0));\n\n  if (early_fail_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n\n  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n  break;\n\n  case OP_QUERY:\n  SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0);\n  if (private_data_ptr == 0)\n    allocate_stack(common, 1);\n  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n  compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE);\n  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n  break;\n\n  case OP_MINSTAR:\n  case OP_MINQUERY:\n  SLJIT_ASSERT(backtrack != NULL && (opcode == OP_MINSTAR || early_fail_ptr == 0));\n  if (private_data_ptr == 0)\n    allocate_stack(common, 1);\n\n  if (exact >= 1)\n    {\n    if (exact >= 2)\n      {\n      /* Extuni has a separate exact opcode. */\n      SLJIT_ASSERT(tmp_base == TMP3 && early_fail_ptr == 0);\n      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact);\n      }\n\n    if (opcode == OP_MINQUERY)\n      OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, -1);\n\n    label = LABEL();\n    BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label;\n\n    compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE);\n\n    if (exact >= 2)\n      {\n      OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n      JUMPTO(SLJIT_NOT_ZERO, label);\n      }\n\n    if (opcode == OP_MINQUERY)\n      OP2(SLJIT_AND, base, offset0, base, offset0, STR_PTR, 0);\n    else\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n    }\n\n  if (early_fail_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n  break;\n\n  case OP_MINUPTO:\n  SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0);\n  if (private_data_ptr == 0)\n    allocate_stack(common, 2);\n\n  OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);\n\n  if (exact == 0)\n    {\n    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();\n    break;\n    }\n\n  if (exact >= 2)\n    {\n    /* Extuni has a separate exact opcode. */\n    SLJIT_ASSERT(tmp_base == TMP3);\n    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact);\n    }\n\n  label = LABEL();\n  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label;\n\n  compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE);\n\n  if (exact >= 2)\n    {\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n    JUMPTO(SLJIT_NOT_ZERO, label);\n    }\n\n  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n  break;\n\n  case OP_EXACT:\n  SLJIT_ASSERT(backtrack == NULL);\n  break;\n\n  case OP_POSSTAR:\n  SLJIT_ASSERT(backtrack == NULL);\n#if defined SUPPORT_UNICODE\n  if (type == OP_ALLANY && !common->invalid_utf)\n#else\n  if (type == OP_ALLANY)\n#endif\n    {\n    if (exact == 1)\n      detect_partial_match(common, prev_backtracks);\n\n    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);\n    process_partial_match(common);\n    if (early_fail_ptr != 0)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);\n    break;\n    }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n  if (common->utf)\n    {\n    SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw));\n\n    if (tmp_base != TMP3)\n      {\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0);\n      tmp_base = COUNT_MATCH;\n      }\n\n    OP1(SLJIT_MOV, tmp_base, 0, exact == 1 ? SLJIT_IMM : STR_PTR, 0);\n    detect_partial_match(common, &no_match);\n    label = LABEL();\n    compile_char1_matchingpath(common, type, cc, &no_match, FALSE);\n    OP1(SLJIT_MOV, tmp_base, 0, STR_PTR, 0);\n    detect_partial_match_to(common, label);\n\n    set_jumps(no_match, LABEL());\n    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, 0);\n\n    if (tmp_base != TMP3)\n      OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n\n    if (exact == 1)\n      add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0));\n\n    if (early_fail_ptr != 0)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n    break;\n    }\n#endif\n\n  if (exact == 1)\n    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);\n\n  detect_partial_match(common, &no_match);\n  label = LABEL();\n  /* Extuni never fails, so no_char1_match is not used in that case.\n     Anynl optionally reads an extra character on success. */\n  compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);\n  detect_partial_match_to(common, label);\n  if (type != OP_EXTUNI)\n    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  set_jumps(no_char1_match, LABEL());\n  if (type != OP_EXTUNI)\n    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  set_jumps(no_match, LABEL());\n\n  if (exact == 1)\n    add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, tmp_base, tmp_offset, STR_PTR, 0));\n\n  if (early_fail_ptr != 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);\n  break;\n\n  case OP_POSUPTO:\n  SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0);\n  max += exact;\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\n  if (type == OP_EXTUNI || common->utf)\n#else\n  if (type == OP_EXTUNI)\n#endif\n    {\n    SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw));\n\n    /* Count match is not modified by compile_char1_matchingpath. */\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0);\n    OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, exact == max ? 0 : max);\n\n    label = LABEL();\n    /* Extuni only modifies TMP3 on successful match. */\n    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n    compile_char1_matchingpath(common, type, cc, &no_match, TRUE);\n\n    if (exact == max)\n      {\n      OP2(SLJIT_ADD, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);\n      JUMPTO(SLJIT_JUMP, label);\n      }\n    else\n      {\n      OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);\n      JUMPTO(SLJIT_NOT_ZERO, label);\n      OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n      }\n\n    set_jumps(no_match, LABEL());\n\n    if (exact > 0)\n      {\n      if (exact == max)\n        OP2U(SLJIT_SUB | SLJIT_SET_LESS, COUNT_MATCH, 0, SLJIT_IMM, exact);\n      else\n        OP2U(SLJIT_SUB | SLJIT_SET_GREATER, COUNT_MATCH, 0, SLJIT_IMM, max - exact);\n      }\n\n    OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2);\n\n    if (exact > 0)\n      add_jump(compiler, prev_backtracks, JUMP(exact == max ? SLJIT_LESS : SLJIT_GREATER));\n    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\n    break;\n    }\n\n  SLJIT_ASSERT(tmp_base == TMP3);\n\n  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : max);\n\n  detect_partial_match(common, &no_match);\n  label = LABEL();\n  compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);\n\n  if (exact == max)\n    OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n  else\n    {\n    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);\n    add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));\n    }\n  detect_partial_match_to(common, label);\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n\n  set_jumps(no_char1_match, LABEL());\n  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  set_jumps(no_match, LABEL());\n\n  if (exact > 0)\n    {\n    if (exact == max)\n      jump = CMP(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact);\n    else\n      jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact);\n\n    add_jump(compiler, prev_backtracks, jump);\n    }\n  break;\n\n  case OP_POSQUERY:\n  SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0);\n  SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw));\n  OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);\n  compile_char1_matchingpath(common, type, cc, &no_match, TRUE);\n  OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);\n  set_jumps(no_match, LABEL());\n  OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);\n  break;\n\n  default:\n  SLJIT_UNREACHABLE();\n  break;\n  }\n\ncount_match(common);\nreturn end;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\n\nPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);\n\nif (*cc == OP_FAIL)\n  {\n  add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP));\n  return cc + 1;\n  }\n\nif (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0)\n  add_jump(compiler, &common->restart_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));\n\nif (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)\n  {\n  /* No need to check notempty conditions. */\n  if (common->accept_label == NULL)\n    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));\n  else\n    JUMPTO(SLJIT_JUMP, common->accept_label);\n  return cc + 1;\n  }\n\nif (common->accept_label == NULL)\n  add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));\nelse\n  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);\n\nif (HAS_VIRTUAL_REGISTERS)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));\n  }\nelse\n  OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options));\n\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);\nadd_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_NOT_ZERO));\nOP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);\nif (common->accept_label == NULL)\n  add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));\nelse\n  JUMPTO(SLJIT_ZERO, common->accept_label);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\nif (common->accept_label == NULL)\n  add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));\nelse\n  CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);\nadd_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP));\nreturn cc + 1;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc)\n{\nDEFINE_COMPILER;\nint offset = GET2(cc, 1);\nBOOL optimized_cbracket = is_optimized_cbracket(common, offset);\n\n/* Data will be discarded anyway... */\nif (common->currententry != NULL)\n  return cc + 1 + IMM2_SIZE;\n\nif (!optimized_cbracket)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));\noffset <<= 1;\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\nif (!optimized_cbracket)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\nreturn cc + 1 + IMM2_SIZE;\n}\n\nstatic SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nPCRE2_UCHAR opcode = *cc;\nPCRE2_SPTR ccend = cc + 1;\n\nif (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG ||\n    opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)\n  ccend += 2 + cc[1];\n\nPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);\n\nif (opcode == OP_SKIP)\n  {\n  allocate_stack(common, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n  return ccend;\n  }\n\nif (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)\n  {\n  if (HAS_VIRTUAL_REGISTERS)\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);\n  }\n\nreturn ccend;\n}\n\nstatic PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };\n\nstatic SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nBOOL needs_control_head;\nint size;\n\nPUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);\ncommon->then_trap = BACKTRACK_AS(then_trap_backtrack);\nBACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;\nBACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);\nBACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);\n\nsize = BACKTRACK_AS(then_trap_backtrack)->framesize;\nsize = 3 + (size < 0 ? 0 : size);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\nallocate_stack(common, size);\nif (size > 3)\n  OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));\nelse\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);\n\nsize = BACKTRACK_AS(then_trap_backtrack)->framesize;\nif (size >= 0)\n  init_frame(common, cc, ccend, size - 1, 0);\n}\n\nstatic void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)\n{\nDEFINE_COMPILER;\nbacktrack_common *backtrack;\nBOOL has_then_trap = FALSE;\nthen_trap_backtrack *save_then_trap = NULL;\nsize_t op_len;\n\nSLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));\n\nif (common->has_then && common->then_offsets[cc - common->start] != 0)\n  {\n  SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);\n  has_then_trap = TRUE;\n  save_then_trap = common->then_trap;\n  /* Tail item on backtrack. */\n  compile_then_trap_matchingpath(common, cc, ccend, parent);\n  }\n\nwhile (cc < ccend)\n  {\n  switch(*cc)\n    {\n    case OP_SOD:\n    case OP_SOM:\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_EODN:\n    case OP_EOD:\n    case OP_DOLL:\n    case OP_DOLLM:\n    case OP_CIRC:\n    case OP_CIRCM:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n    break;\n\n    case OP_NOT_DIGIT:\n    case OP_DIGIT:\n    case OP_NOT_WHITESPACE:\n    case OP_WHITESPACE:\n    case OP_NOT_WORDCHAR:\n    case OP_WORDCHAR:\n    case OP_ANY:\n    case OP_ALLANY:\n    case OP_ANYBYTE:\n    case OP_NOTPROP:\n    case OP_PROP:\n    case OP_ANYNL:\n    case OP_NOT_HSPACE:\n    case OP_HSPACE:\n    case OP_NOT_VSPACE:\n    case OP_VSPACE:\n    case OP_EXTUNI:\n    case OP_NOT:\n    case OP_NOTI:\n    cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE);\n    break;\n\n    case OP_SET_SOM:\n    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));\n    allocate_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n    cc++;\n    break;\n\n    case OP_CHAR:\n    case OP_CHARI:\n    if (common->mode == PCRE2_JIT_COMPLETE)\n      cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n    else\n      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE);\n    break;\n\n    case OP_STAR:\n    case OP_MINSTAR:\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_UPTO:\n    case OP_MINUPTO:\n    case OP_EXACT:\n    case OP_POSSTAR:\n    case OP_POSPLUS:\n    case OP_POSQUERY:\n    case OP_POSUPTO:\n    case OP_STARI:\n    case OP_MINSTARI:\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_UPTOI:\n    case OP_MINUPTOI:\n    case OP_EXACTI:\n    case OP_POSSTARI:\n    case OP_POSPLUSI:\n    case OP_POSQUERYI:\n    case OP_POSUPTOI:\n    case OP_NOTSTAR:\n    case OP_NOTMINSTAR:\n    case OP_NOTPLUS:\n    case OP_NOTMINPLUS:\n    case OP_NOTQUERY:\n    case OP_NOTMINQUERY:\n    case OP_NOTUPTO:\n    case OP_NOTMINUPTO:\n    case OP_NOTEXACT:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSUPTO:\n    case OP_NOTSTARI:\n    case OP_NOTMINSTARI:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUSI:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERYI:\n    case OP_NOTUPTOI:\n    case OP_NOTMINUPTOI:\n    case OP_NOTEXACTI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTPOSQUERYI:\n    case OP_NOTPOSUPTOI:\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEEXACT:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    case OP_TYPEPOSUPTO:\n    cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n    break;\n\n    case OP_CLASS:\n    case OP_NCLASS:\n    if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE)\n      cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n    else\n      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE);\n    break;\n\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n    case OP_XCLASS:\n    case OP_ECLASS:\n    op_len = GET(cc, 1);\n    if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE)\n      cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n    else\n      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE);\n    break;\n#endif\n\n    case OP_REF:\n    case OP_REFI:\n    op_len = PRIV(OP_lengths)[*cc];\n    if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE)\n      cc = compile_ref_iterator_matchingpath(common, cc, parent);\n    else\n      {\n      compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE);\n      cc += op_len;\n      }\n    break;\n\n    case OP_DNREF:\n    case OP_DNREFI:\n    op_len = PRIV(OP_lengths)[*cc];\n    if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE)\n      cc = compile_ref_iterator_matchingpath(common, cc, parent);\n    else\n      {\n      compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);\n      compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE);\n      cc += op_len;\n      }\n    break;\n\n    case OP_RECURSE:\n    cc = compile_recurse_matchingpath(common, cc, parent);\n    break;\n\n    case OP_CALLOUT:\n    case OP_CALLOUT_STR:\n    cc = compile_callout_matchingpath(common, cc, parent);\n    break;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);\n    cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);\n    break;\n\n    case OP_BRAMINZERO:\n    PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);\n    cc = bracketend(cc + 1);\n    if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)\n      {\n      allocate_stack(common, 1);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n      }\n    else\n      {\n      allocate_stack(common, 2);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);\n      }\n    BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();\n    count_match(common);\n    break;\n\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ASSERT_SCS:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_BRA:\n    case OP_CBRA:\n    case OP_COND:\n    case OP_SBRA:\n    case OP_SCBRA:\n    case OP_SCOND:\n    cc = compile_bracket_matchingpath(common, cc, parent);\n    break;\n\n    case OP_BRAZERO:\n    if (cc[1] > OP_ASSERTBACK_NOT)\n      cc = compile_bracket_matchingpath(common, cc, parent);\n    else\n      {\n      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);\n      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);\n      }\n    break;\n\n    case OP_BRAPOS:\n    case OP_CBRAPOS:\n    case OP_SBRAPOS:\n    case OP_SCBRAPOS:\n    case OP_BRAPOSZERO:\n    cc = compile_bracketpos_matchingpath(common, cc, parent);\n    break;\n\n    case OP_MARK:\n    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);\n    SLJIT_ASSERT(common->mark_ptr != 0);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);\n    allocate_stack(common, common->has_skip_arg ? 5 : 1);\n    if (HAS_VIRTUAL_REGISTERS)\n      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);\n    if (common->has_skip_arg)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);\n      }\n    cc += 1 + 2 + cc[1];\n    break;\n\n    case OP_PRUNE:\n    case OP_PRUNE_ARG:\n    case OP_SKIP:\n    case OP_SKIP_ARG:\n    case OP_THEN:\n    case OP_THEN_ARG:\n    case OP_COMMIT:\n    case OP_COMMIT_ARG:\n    cc = compile_control_verb_matchingpath(common, cc, parent);\n    break;\n\n    case OP_FAIL:\n    case OP_ACCEPT:\n    case OP_ASSERT_ACCEPT:\n    cc = compile_fail_accept_matchingpath(common, cc, parent);\n    break;\n\n    case OP_CLOSE:\n    cc = compile_close_matchingpath(common, cc);\n    break;\n\n    case OP_SKIPZERO:\n    cc = bracketend(cc + 1);\n    break;\n\n    default:\n    SLJIT_UNREACHABLE();\n    return;\n    }\n  if (cc == NULL)\n    return;\n  }\n\nif (has_then_trap)\n  {\n  /* Head item on backtrack. */\n  PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);\n  BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;\n  BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;\n  common->then_trap = save_then_trap;\n  }\nSLJIT_ASSERT(cc == ccend);\n}\n\n#undef PUSH_BACKTRACK\n#undef PUSH_BACKTRACK_NOVALUE\n#undef BACKTRACK_AS\n\n#define COMPILE_BACKTRACKINGPATH(current) \\\n  do \\\n    { \\\n    compile_backtrackingpath(common, (current)); \\\n    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \\\n      return; \\\n    } \\\n  while (0)\n\n#define CURRENT_AS(type) ((type *)current)\n\nstatic void compile_newline_move_back(compiler_common *common)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\njump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, TMP2, 0);\n/* All newlines are single byte, or their last byte\nis not equal to CHAR_NL/CHAR_CR even if UTF is enabled. */\nOP1(MOV_UCHAR, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));\nOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));\nOP2(SLJIT_SHL, SLJIT_TMP_DEST_REG, 0, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 8);\nOP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_TMP_DEST_REG, 0);\nOP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR << 8 | CHAR_NL);\nOP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);\n#endif\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\nJUMPHERE(jump);\n}\n\nstatic void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nPCRE2_SPTR cc = current->cc;\nPCRE2_UCHAR opcode;\nPCRE2_UCHAR type;\nsljit_u32 max = 0, exact;\nstruct sljit_label *label = NULL;\nstruct sljit_jump *jump = NULL;\njump_list *jumplist = NULL;\nPCRE2_SPTR end;\nint private_data_ptr = PRIVATE_DATA(cc);\nint base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);\nint offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;\nint offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);\n\ncc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);\n\nswitch(opcode)\n  {\n  case OP_STAR:\n  case OP_UPTO:\n  if (type == OP_EXTUNI)\n    {\n    SLJIT_ASSERT(private_data_ptr == 0);\n    set_jumps(current->own_backtracks, LABEL());\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, 1);\n    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n    }\n  else\n    {\n    if (CURRENT_AS(char_iterator_backtrack)->charpos.charpos_enabled)\n      {\n      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n      OP1(SLJIT_MOV, TMP2, 0, base, offset1);\n\n      jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n      label = LABEL();\n      if (type == OP_ANYNL)\n        compile_newline_move_back(common);\n      move_back(common, NULL, TRUE);\n\n      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));\n      if (CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit != 0)\n        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit);\n      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n      /* The range beginning must match, no need to compare. */\n      JUMPTO(SLJIT_JUMP, label);\n\n      set_jumps(current->own_backtracks, LABEL());\n      current->own_backtracks = NULL;\n      }\n    else\n      {\n      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n\n      if (opcode == OP_STAR && exact == 1)\n        {\n        if (type == OP_ANYNL)\n          {\n          OP1(SLJIT_MOV, TMP2, 0, base, offset1);\n          compile_newline_move_back(common);\n          }\n\n        move_back(common, NULL, TRUE);\n        jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);\n        }\n      else\n        {\n        if (type == OP_ANYNL)\n          {\n          OP1(SLJIT_MOV, TMP2, 0, base, offset1);\n          jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);\n          compile_newline_move_back(common);\n          }\n        else\n          jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);\n\n        move_back(common, NULL, TRUE);\n        }\n\n      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n      JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n\n      set_jumps(current->own_backtracks, LABEL());\n      }\n\n    JUMPHERE(jump);\n    if (private_data_ptr == 0)\n      free_stack(common, 2);\n    }\n  break;\n\n  case OP_QUERY:\n  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);\n  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n  jump = JUMP(SLJIT_JUMP);\n  set_jumps(current->own_backtracks, LABEL());\n  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);\n  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n  JUMPHERE(jump);\n  if (private_data_ptr == 0)\n    free_stack(common, 1);\n  break;\n\n  case OP_MINSTAR:\n  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n  if (exact == 0)\n    {\n    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);\n    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    }\n  else if (exact > 1)\n    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);\n\n  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n  set_jumps(exact > 0 ? current->own_backtracks : jumplist, LABEL());\n  if (private_data_ptr == 0)\n    free_stack(common, 1);\n  break;\n\n  case OP_MINUPTO:\n  OP1(SLJIT_MOV, TMP1, 0, base, offset1);\n  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n  OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\n\n  if (exact == 0)\n    {\n    add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));\n\n    OP1(SLJIT_MOV, base, offset1, TMP1, 0);\n    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);\n    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);\n    JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n\n    set_jumps(jumplist, LABEL());\n    }\n  else\n    {\n    if (exact > 1)\n      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);\n    OP1(SLJIT_MOV, base, offset1, TMP1, 0);\n    JUMPTO(SLJIT_NOT_ZERO, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n\n    set_jumps(current->own_backtracks, LABEL());\n    }\n\n  if (private_data_ptr == 0)\n    free_stack(common, 2);\n  break;\n\n  case OP_MINQUERY:\n  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);\n  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);\n\n  if (exact >= 1)\n    {\n    if (exact >= 2)\n      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);\n    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n    set_jumps(current->own_backtracks, LABEL());\n    }\n  else\n    {\n    jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);\n    JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);\n    set_jumps(jumplist, LABEL());\n    JUMPHERE(jump);\n    }\n\n  if (private_data_ptr == 0)\n    free_stack(common, 1);\n  break;\n\n  default:\n  SLJIT_UNREACHABLE();\n  break;\n  }\n}\n\nstatic SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nPCRE2_SPTR cc = current->cc;\nBOOL ref = (*cc == OP_REF || *cc == OP_REFI);\nPCRE2_UCHAR type;\n\ntype = cc[PRIV(OP_lengths)[*cc]];\n\nif ((type & 0x1) == 0)\n  {\n  /* Maximize case. */\n  set_jumps(current->own_backtracks, LABEL());\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);\n  return;\n  }\n\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\nCMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);\nset_jumps(current->own_backtracks, LABEL());\nfree_stack(common, ref ? 2 : 3);\n}\n\nstatic SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nrecurse_entry *entry;\n\nif (!CURRENT_AS(recurse_backtrack)->inlined_pattern)\n  {\n  entry = CURRENT_AS(recurse_backtrack)->entry;\n  if (entry->backtrack_label == NULL)\n    add_jump(compiler, &entry->backtrack_calls, JUMP(SLJIT_FAST_CALL));\n  else\n    JUMPTO(SLJIT_FAST_CALL, entry->backtrack_label);\n  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(recurse_backtrack)->matchingpath);\n  }\nelse\n  compile_backtrackingpath(common, current->top);\n\nset_jumps(current->own_backtracks, LABEL());\n}\n\nstatic void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nPCRE2_SPTR cc = current->cc;\nPCRE2_UCHAR bra = OP_BRA;\nstruct sljit_jump *brajump = NULL;\n\nSLJIT_ASSERT(*cc != OP_BRAMINZERO);\nif (*cc == OP_BRAZERO)\n  {\n  bra = *cc;\n  cc++;\n  }\n\nif (bra == OP_BRAZERO)\n  {\n  SLJIT_ASSERT(current->own_backtracks == NULL);\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  }\n\nif (CURRENT_AS(assert_backtrack)->framesize < 0)\n  {\n  set_jumps(current->own_backtracks, LABEL());\n\n  if (bra == OP_BRAZERO)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);\n    free_stack(common, 1);\n    }\n  return;\n  }\n\nif (bra == OP_BRAZERO)\n  {\n  if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)\n    {\n    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);\n    free_stack(common, 1);\n    return;\n    }\n  free_stack(common, 1);\n  brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);\n  }\n\nif (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)\n  {\n  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);\n  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));\n  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0);\n\n  set_jumps(current->own_backtracks, LABEL());\n  }\nelse\n  set_jumps(current->own_backtracks, LABEL());\n\nif (bra == OP_BRAZERO)\n  {\n  /* We know there is enough place on the stack. */\n  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);\n  JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);\n  JUMPHERE(brajump);\n  }\n}\n\nstatic void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nint opcode, stacksize, alt_count, alt_max;\nint offset = 0;\nint private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;\nint repeat_ptr = 0, repeat_type = 0, repeat_count = 0;\nPCRE2_SPTR cc = current->cc;\nPCRE2_SPTR ccbegin;\nPCRE2_SPTR ccprev;\nPCRE2_UCHAR bra = OP_BRA;\nPCRE2_UCHAR ket;\nconst assert_backtrack *assert;\nBOOL has_alternatives;\nBOOL needs_control_head = FALSE;\nBOOL has_vreverse;\nstruct sljit_jump *brazero = NULL;\nstruct sljit_jump *next_alt = NULL;\nstruct sljit_jump *once = NULL;\nstruct sljit_jump *cond = NULL;\nstruct sljit_label *rmin_label = NULL;\nstruct sljit_label *exact_label = NULL;\nstruct sljit_jump *mov_addr = NULL;\n\nif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)\n  {\n  bra = *cc;\n  cc++;\n  }\n\nopcode = *cc;\nccbegin = bracketend(cc) - 1 - LINK_SIZE;\nket = *ccbegin;\nif (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)\n  {\n  repeat_ptr = PRIVATE_DATA(ccbegin);\n  repeat_type = PRIVATE_DATA(ccbegin + 2);\n  repeat_count = PRIVATE_DATA(ccbegin + 3);\n  SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);\n  if (repeat_type == OP_UPTO)\n    ket = OP_KETRMAX;\n  if (repeat_type == OP_MINUPTO)\n    ket = OP_KETRMIN;\n  }\nccbegin = cc;\ncc += GET(cc, 1);\nhas_alternatives = *cc == OP_ALT;\nif (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))\n  has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.no_capture != NULL;\nif (opcode == OP_CBRA || opcode == OP_SCBRA)\n  offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;\nif (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))\n  opcode = OP_SCOND;\n\nalt_max = has_alternatives ? no_alternatives(ccbegin) : 0;\n\n/* Decoding the needs_control_head in framesize. */\nif (opcode == OP_ONCE)\n  {\n  needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;\n  CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;\n  }\n\nif (ket != OP_KET && repeat_type != 0)\n  {\n  /* TMP1 is used in OP_KETRMIN below. */\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n  if (repeat_type == OP_UPTO)\n    OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);\n  else\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);\n  }\n\nif (ket == OP_KETRMAX)\n  {\n  if (bra == OP_BRAZERO)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, 1);\n    brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);\n    }\n  }\nelse if (ket == OP_KETRMIN)\n  {\n  if (bra != OP_BRAMINZERO)\n    {\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    if (repeat_type != 0)\n      {\n      /* TMP1 was set a few lines above. */\n      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);\n      /* Drop STR_PTR for non-greedy plus quantifier. */\n      if (opcode != OP_ONCE)\n        free_stack(common, 1);\n      }\n    else if (opcode >= OP_SBRA || opcode == OP_ONCE)\n      {\n      /* Checking zero-length iteration. */\n      if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)\n        CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);\n      else\n        {\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n        CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 2), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);\n        }\n      /* Drop STR_PTR for non-greedy plus quantifier. */\n      if (opcode != OP_ONCE)\n        free_stack(common, 1);\n      }\n    else\n      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);\n    }\n  rmin_label = LABEL();\n  if (repeat_type != 0)\n    OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);\n  }\nelse if (bra == OP_BRAZERO)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n  brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);\n  }\nelse if (repeat_type == OP_EXACT)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);\n  exact_label = LABEL();\n  }\n\nif (offset != 0)\n  {\n  if (common->capture_last_ptr != 0)\n    {\n    SLJIT_ASSERT(!is_optimized_cbracket(common, offset >> 1));\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));\n    free_stack(common, 3);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);\n    }\n  else if (!is_optimized_cbracket(common, offset >> 1))\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    free_stack(common, 2);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);\n    }\n  }\nelse if (SLJIT_UNLIKELY(opcode == OP_ASSERT_SCS))\n  {\n  OP1(SLJIT_MOV, TMP1, 0, STR_END, 0);\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0);\n\n  /* Nested scs blocks will not update this variable. */\n  if (common->restore_end_ptr == 0)\n    common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw);\n  }\n\nif (SLJIT_UNLIKELY(opcode == OP_ONCE))\n  {\n  int framesize = CURRENT_AS(bracket_backtrack)->u.framesize;\n\n  SLJIT_ASSERT(framesize != 0);\n  if (framesize > 0)\n    {\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));\n    }\n  once = JUMP(SLJIT_JUMP);\n  }\nelse if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))\n  {\n  if (has_alternatives)\n    {\n    /* Always exactly one alternative. */\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, 1);\n\n    alt_max = 2;\n    next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);\n    }\n  }\nelse if (has_alternatives)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n\n  if (alt_max > 3)\n    {\n    sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);\n\n    SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->matching_mov_addr != NULL);\n    sljit_set_label(CURRENT_AS(bracket_backtrack)->matching_mov_addr, LABEL());\n    sljit_emit_op0(compiler, SLJIT_ENDBR);\n    }\n  else\n    next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);\n  }\n\nCOMPILE_BACKTRACKINGPATH(current->top);\nif (current->own_backtracks)\n  set_jumps(current->own_backtracks, LABEL());\n\nif (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))\n  {\n  /* Conditional block always has at most one alternative. */\n  if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)\n    {\n    SLJIT_ASSERT(has_alternatives);\n    assert = CURRENT_AS(bracket_backtrack)->u.assert;\n    SLJIT_ASSERT(assert->framesize != 0);\n    if (assert->framesize > 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))\n      {\n      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);\n      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));\n      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);\n      }\n    cond = JUMP(SLJIT_JUMP);\n    set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());\n    }\n  else if (CURRENT_AS(bracket_backtrack)->u.no_capture != NULL)\n    {\n    SLJIT_ASSERT(has_alternatives);\n    cond = JUMP(SLJIT_JUMP);\n    set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL());\n    }\n  else\n    SLJIT_ASSERT(!has_alternatives);\n  }\n\nif (has_alternatives)\n  {\n  alt_count = 1;\n  do\n    {\n    current->top = NULL;\n    current->own_backtracks = NULL;\n    current->simple_backtracks = NULL;\n    /* Conditional blocks always have an additional alternative, even if it is empty. */\n    if (*cc == OP_ALT)\n      {\n      ccprev = cc + 1 + LINK_SIZE;\n      cc += GET(cc, 1);\n\n      has_vreverse = FALSE;\n\n      switch (opcode)\n        {\n        case OP_ASSERTBACK:\n        case OP_ASSERTBACK_NA:\n          SLJIT_ASSERT(private_data_ptr != 0);\n          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n\n          has_vreverse = (*ccprev == OP_VREVERSE);\n          if (*ccprev == OP_REVERSE || has_vreverse)\n            ccprev = compile_reverse_matchingpath(common, ccprev, current);\n          break;\n        case OP_ASSERT_SCS:\n          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2));\n          break;\n        case OP_ONCE:\n          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));\n          break;\n        case OP_COND:\n        case OP_SCOND:\n          break;\n        default:\n          if (private_data_ptr != 0)\n            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n          else\n            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n          break;\n        }\n\n      compile_matchingpath(common, ccprev, cc, current);\n      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n        return;\n\n      switch (opcode)\n        {\n        case OP_ASSERTBACK_NA:\n          if (has_vreverse)\n            {\n            SLJIT_ASSERT(current->top != NULL && PRIVATE_DATA(ccbegin + 1));\n            add_jump(compiler, &current->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));\n            }\n\n          if (PRIVATE_DATA(ccbegin + 1))\n            OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n          break;\n        case OP_ASSERT_NA:\n          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);\n          break;\n        case OP_SCRIPT_RUN:\n          match_script_run_common(common, private_data_ptr, current);\n          break;\n        }\n      }\n\n    /* Instructions after the current alternative is successfully matched. */\n    /* There is a similar code in compile_bracket_matchingpath. */\n    if (opcode == OP_ONCE)\n      match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);\n\n    stacksize = 0;\n    if (repeat_type == OP_MINUPTO)\n      {\n      /* We need to preserve the counter. TMP2 will be used below. */\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);\n      stacksize++;\n      }\n    if (ket != OP_KET || bra != OP_BRA)\n      stacksize++;\n    if (offset != 0)\n      {\n      if (common->capture_last_ptr != 0)\n        stacksize++;\n      if (!is_optimized_cbracket(common, offset >> 1))\n        stacksize += 2;\n      }\n    if (opcode != OP_ONCE)\n      stacksize++;\n\n    if (stacksize > 0)\n      allocate_stack(common, stacksize);\n\n    stacksize = 0;\n    if (repeat_type == OP_MINUPTO)\n      {\n      /* TMP2 was set above. */\n      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);\n      stacksize++;\n      }\n\n    if (ket != OP_KET || bra != OP_BRA)\n      {\n      if (ket != OP_KET)\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);\n      else\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);\n      stacksize++;\n      }\n\n    if (offset != 0)\n      stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);\n\n    if (opcode != OP_ONCE)\n      {\n      if (alt_max <= 3)\n        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);\n      else\n        mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(stacksize));\n      }\n\n    if (offset != 0 && ket == OP_KETRMAX && is_optimized_cbracket(common, offset >> 1))\n      {\n      /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */\n      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);\n      }\n\n    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);\n\n    if (opcode != OP_ONCE)\n      {\n      if (alt_max <= 3)\n        {\n        JUMPHERE(next_alt);\n        alt_count++;\n        if (alt_count < alt_max)\n          {\n          SLJIT_ASSERT(alt_count == 2 && alt_max == 3);\n          next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);\n          }\n        }\n      else\n        {\n        sljit_set_label(mov_addr, LABEL());\n        sljit_emit_op0(compiler, SLJIT_ENDBR);\n        }\n      }\n\n    COMPILE_BACKTRACKINGPATH(current->top);\n    if (current->own_backtracks)\n      set_jumps(current->own_backtracks, LABEL());\n    SLJIT_ASSERT(!current->simple_backtracks);\n    }\n  while (*cc == OP_ALT);\n\n  if (cond != NULL)\n    {\n    SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);\n    if (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT)\n      {\n      assert = CURRENT_AS(bracket_backtrack)->u.assert;\n      SLJIT_ASSERT(assert->framesize != 0);\n      if (assert->framesize > 0)\n        {\n        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);\n        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));\n        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));\n        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);\n        }\n      }\n    JUMPHERE(cond);\n    }\n\n  /* Free the STR_PTR. */\n  if (private_data_ptr == 0)\n    free_stack(common, 1);\n  }\n\nif (offset != 0)\n  {\n  /* Using both tmp register is better for instruction scheduling. */\n  if (is_optimized_cbracket(common, offset >> 1))\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    free_stack(common, 2);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n    }\n  }\nelse if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1))\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0);\n  free_stack(common, 4);\n  }\nelse if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)\n  {\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));\n  free_stack(common, 1);\n  }\nelse if (opcode == OP_ASSERT_SCS)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0);\n  free_stack(common, has_alternatives ? 3 : 2);\n\n  set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL());\n\n  /* Nested scs blocks will not update this variable. */\n  if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw))\n    common->restore_end_ptr = 0;\n  }\nelse if (opcode == OP_ONCE)\n  {\n  cc = ccbegin + GET(ccbegin, 1);\n  stacksize = needs_control_head ? 1 : 0;\n\n  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)\n    {\n    /* Reset head and drop saved frame. */\n    stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);\n    }\n  else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))\n    {\n    /* The STR_PTR must be released. */\n    stacksize++;\n    }\n\n  if (stacksize > 0)\n    free_stack(common, stacksize);\n\n  JUMPHERE(once);\n  /* Restore previous private_data_ptr */\n  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 1));\n  else if (ket == OP_KETRMIN)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    /* See the comment below. */\n    free_stack(common, 2);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);\n    }\n  }\n\nif (repeat_type == OP_EXACT)\n  {\n  OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);\n  CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);\n  }\nelse if (ket == OP_KETRMAX)\n  {\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  if (bra != OP_BRAZERO)\n    free_stack(common, 1);\n\n  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);\n  if (bra == OP_BRAZERO)\n    {\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);\n    JUMPHERE(brazero);\n    free_stack(common, 1);\n    }\n  }\nelse if (ket == OP_KETRMIN)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n\n  /* OP_ONCE removes everything in case of a backtrack, so we don't\n  need to explicitly release the STR_PTR. The extra release would\n  affect badly the free_stack(2) above. */\n  if (opcode != OP_ONCE)\n    free_stack(common, 1);\n  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);\n  if (opcode == OP_ONCE)\n    free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);\n  else if (bra == OP_BRAMINZERO)\n    free_stack(common, 1);\n  }\nelse if (bra == OP_BRAZERO)\n  {\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n  JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);\n  JUMPHERE(brazero);\n  }\n}\n\nstatic SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nint offset;\nstruct sljit_jump *jump;\nPCRE2_SPTR cc;\n\n/* No retry on backtrack, just drop everything. */\nif (CURRENT_AS(bracketpos_backtrack)->framesize < 0)\n  {\n  cc = current->cc;\n\n  if (*cc == OP_BRAPOSZERO)\n    cc++;\n\n  if (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)\n    {\n    offset = (GET2(cc, 1 + LINK_SIZE)) << 1;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);\n    if (common->capture_last_ptr != 0)\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);\n    if (common->capture_last_ptr != 0)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);\n    }\n  set_jumps(current->own_backtracks, LABEL());\n  free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);\n  return;\n  }\n\nOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);\nadd_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\nOP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw));\n\nif (current->own_backtracks)\n  {\n  jump = JUMP(SLJIT_JUMP);\n  set_jumps(current->own_backtracks, LABEL());\n  /* Drop the stack frame. */\n  free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);\n  JUMPHERE(jump);\n  }\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracketpos_backtrack)->framesize - 1));\n}\n\nstatic SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nassert_backtrack backtrack;\n\ncurrent->top = NULL;\ncurrent->own_backtracks = NULL;\ncurrent->simple_backtracks = NULL;\nif (current->cc[1] > OP_ASSERTBACK_NOT)\n  {\n  /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */\n  compile_bracket_matchingpath(common, current->cc, current);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(common->compiler)))\n    return;\n  compile_bracket_backtrackingpath(common, current->top);\n  }\nelse\n  {\n  memset(&backtrack, 0, sizeof(backtrack));\n  backtrack.common.cc = current->cc;\n  backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;\n  /* Manual call of compile_assert_matchingpath. */\n  compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(common->compiler)))\n    return;\n  }\nSLJIT_ASSERT(!current->simple_backtracks && !current->own_backtracks);\n}\n\nstatic SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nPCRE2_UCHAR opcode = *current->cc;\nstruct sljit_label *loop;\nstruct sljit_jump *jump;\n\nif (opcode == OP_THEN || opcode == OP_THEN_ARG)\n  {\n  if (common->then_trap != NULL)\n    {\n    SLJIT_ASSERT(common->control_head_ptr != 0);\n\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);\n    jump = JUMP(SLJIT_JUMP);\n\n    loop = LABEL();\n    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    JUMPHERE(jump);\n    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, loop);\n    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0, loop);\n    add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));\n    return;\n    }\n  else if (!common->local_quit_available && common->in_positive_assertion)\n    {\n    add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));\n    return;\n    }\n  }\n\nif (common->restore_end_ptr != 0 && opcode != OP_SKIP_ARG)\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr);\n\nif (common->local_quit_available)\n  {\n  /* Abort match with a fail. */\n  if (common->quit_label == NULL)\n    add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));\n  else\n    JUMPTO(SLJIT_JUMP, common->quit_label);\n  return;\n  }\n\nif (opcode == OP_SKIP_ARG)\n  {\n  SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);\n  OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));\n  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_search_mark));\n\n  if (common->restore_end_ptr == 0)\n    {\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);\n    add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));\n    return;\n    }\n\n  jump = CMP(SLJIT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0);\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);\n  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr);\n  add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));\n  JUMPHERE(jump);\n  return;\n  }\n\nif (opcode == OP_SKIP)\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\nelse\n  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);\nadd_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));\n}\n\nstatic SLJIT_INLINE void compile_vreverse_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nstruct sljit_label *label;\n\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2));\njump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(3));\nskip_valid_char(common);\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);\nJUMPTO(SLJIT_JUMP, CURRENT_AS(vreverse_backtrack)->matchingpath);\n\nlabel = LABEL();\nsljit_set_label(jump, label);\nset_jumps(current->own_backtracks, label);\n}\n\nstatic SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nstruct sljit_jump *jump;\nint framesize;\nint size;\n\nif (CURRENT_AS(then_trap_backtrack)->then_trap)\n  {\n  common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;\n  return;\n  }\n\nsize = CURRENT_AS(then_trap_backtrack)->framesize;\nsize = 3 + (size < 0 ? 0 : size);\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));\nfree_stack(common, size);\njump = JUMP(SLJIT_JUMP);\n\nset_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());\n\nframesize = CURRENT_AS(then_trap_backtrack)->framesize;\nSLJIT_ASSERT(framesize != 0);\n\n/* STACK_TOP is set by THEN. */\nif (framesize > 0)\n  {\n  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));\n  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));\n  }\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\nfree_stack(common, 3);\n\nJUMPHERE(jump);\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);\n}\n\nstatic void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)\n{\nDEFINE_COMPILER;\nthen_trap_backtrack *save_then_trap = common->then_trap;\n\nwhile (current)\n  {\n  if (current->simple_backtracks != NULL)\n    set_jumps(current->simple_backtracks, LABEL());\n  switch(*current->cc)\n    {\n    case OP_SET_SOM:\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);\n    break;\n\n    case OP_STAR:\n    case OP_MINSTAR:\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_UPTO:\n    case OP_MINUPTO:\n    case OP_EXACT:\n    case OP_POSSTAR:\n    case OP_POSPLUS:\n    case OP_POSQUERY:\n    case OP_POSUPTO:\n    case OP_STARI:\n    case OP_MINSTARI:\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_UPTOI:\n    case OP_MINUPTOI:\n    case OP_EXACTI:\n    case OP_POSSTARI:\n    case OP_POSPLUSI:\n    case OP_POSQUERYI:\n    case OP_POSUPTOI:\n    case OP_NOTSTAR:\n    case OP_NOTMINSTAR:\n    case OP_NOTPLUS:\n    case OP_NOTMINPLUS:\n    case OP_NOTQUERY:\n    case OP_NOTMINQUERY:\n    case OP_NOTUPTO:\n    case OP_NOTMINUPTO:\n    case OP_NOTEXACT:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSUPTO:\n    case OP_NOTSTARI:\n    case OP_NOTMINSTARI:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUSI:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERYI:\n    case OP_NOTUPTOI:\n    case OP_NOTMINUPTOI:\n    case OP_NOTEXACTI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTPOSQUERYI:\n    case OP_NOTPOSUPTOI:\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEEXACT:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    case OP_TYPEPOSUPTO:\n    /* Since classes has no backtracking path, this\n    backtrackingpath was pushed by an iterator. */\n    case OP_CLASS:\n    case OP_NCLASS:\n#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8\n    case OP_XCLASS:\n    case OP_ECLASS:\n#endif\n    compile_iterator_backtrackingpath(common, current);\n    break;\n\n    case OP_REF:\n    case OP_REFI:\n    case OP_DNREF:\n    case OP_DNREFI:\n    compile_ref_iterator_backtrackingpath(common, current);\n    break;\n\n    case OP_RECURSE:\n    compile_recurse_backtrackingpath(common, current);\n    break;\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    compile_assert_backtrackingpath(common, current);\n    break;\n\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ASSERT_SCS:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_BRA:\n    case OP_CBRA:\n    case OP_COND:\n    case OP_SBRA:\n    case OP_SCBRA:\n    case OP_SCOND:\n    compile_bracket_backtrackingpath(common, current);\n    break;\n\n    case OP_BRAZERO:\n    if (current->cc[1] > OP_ASSERTBACK_NOT)\n      compile_bracket_backtrackingpath(common, current);\n    else\n      compile_assert_backtrackingpath(common, current);\n    break;\n\n    case OP_BRAPOS:\n    case OP_CBRAPOS:\n    case OP_SBRAPOS:\n    case OP_SCBRAPOS:\n    case OP_BRAPOSZERO:\n    compile_bracketpos_backtrackingpath(common, current);\n    break;\n\n    case OP_BRAMINZERO:\n    compile_braminzero_backtrackingpath(common, current);\n    break;\n\n    case OP_MARK:\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));\n    if (common->has_skip_arg)\n      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    free_stack(common, common->has_skip_arg ? 5 : 1);\n    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);\n    if (common->has_skip_arg)\n      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);\n    break;\n\n    case OP_THEN:\n    case OP_THEN_ARG:\n    case OP_PRUNE:\n    case OP_PRUNE_ARG:\n    case OP_SKIP:\n    case OP_SKIP_ARG:\n    compile_control_verb_backtrackingpath(common, current);\n    break;\n\n    case OP_COMMIT:\n    case OP_COMMIT_ARG:\n    if (common->restore_end_ptr != 0)\n      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr);\n\n    if (!common->local_quit_available)\n      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);\n\n    if (common->quit_label == NULL)\n      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));\n    else\n      JUMPTO(SLJIT_JUMP, common->quit_label);\n    break;\n\n    case OP_CALLOUT:\n    case OP_CALLOUT_STR:\n    case OP_FAIL:\n    case OP_ACCEPT:\n    case OP_ASSERT_ACCEPT:\n    set_jumps(current->own_backtracks, LABEL());\n    break;\n\n    case OP_VREVERSE:\n    compile_vreverse_backtrackingpath(common, current);\n    break;\n\n    case OP_THEN_TRAP:\n    /* A virtual opcode for then traps. */\n    compile_then_trap_backtrackingpath(common, current);\n    break;\n\n    default:\n    SLJIT_UNREACHABLE();\n    break;\n    }\n  current = current->prev;\n  }\ncommon->then_trap = save_then_trap;\n}\n\nstatic SLJIT_INLINE void compile_recurse(compiler_common *common)\n{\nDEFINE_COMPILER;\nPCRE2_SPTR cc = common->start + common->currententry->start;\nPCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);\nPCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE);\nuint32_t recurse_flags = 0;\nint private_data_size = get_recurse_data_length(common, ccbegin, ccend, &recurse_flags);\nint alt_count, alt_max, local_size;\nbacktrack_common altbacktrack;\njump_list *match = NULL;\nstruct sljit_jump *next_alt = NULL;\nstruct sljit_jump *accept_exit = NULL;\nstruct sljit_label *quit;\nstruct sljit_jump *mov_addr = NULL;\n\n/* Recurse captures then. */\ncommon->then_trap = NULL;\n\nSLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);\n\nalt_max = no_alternatives(cc);\nalt_count = 0;\n\n/* Matching path. */\nSLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head_ptr != 0);\ncommon->currententry->entry_label = LABEL();\nset_jumps(common->currententry->entry_calls, common->currententry->entry_label);\n\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP2, 0);\ncount_match(common);\n\nlocal_size = (alt_max > 1) ? 2 : 1;\n\n/* (Reversed) stack layout:\n   [private data][return address][optional: str ptr] ... [optional: alternative index][recursive_head_ptr] */\n\nallocate_stack(common, private_data_size + local_size);\n/* Save return address. */\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP2, 0);\n\ncopy_recurse_data(common, ccbegin, ccend, recurse_copy_from_global, local_size, private_data_size + local_size, recurse_flags);\n\n/* This variable is saved and restored all time when we enter or exit from a recursive context. */\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);\n\nif (recurse_flags & recurse_flag_control_head_found)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);\n\nif (alt_max > 1)\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);\n\nmemset(&altbacktrack, 0, sizeof(backtrack_common));\ncommon->quit_label = NULL;\ncommon->accept_label = NULL;\ncommon->quit = NULL;\ncommon->accept = NULL;\naltbacktrack.cc = ccbegin;\ncc += GET(cc, 1);\nwhile (1)\n  {\n  altbacktrack.top = NULL;\n  altbacktrack.own_backtracks = NULL;\n\n  if (altbacktrack.cc != ccbegin)\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n\n  compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    return;\n\n  allocate_stack(common, (alt_max > 1 || (recurse_flags & recurse_flag_accept_found)) ? 2 : 1);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);\n\n  if (alt_max > 1 || (recurse_flags & recurse_flag_accept_found))\n    {\n    if (alt_max > 3)\n      mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(1));\n    else\n      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);\n    }\n\n  add_jump(compiler, &match, JUMP(SLJIT_JUMP));\n\n  if (alt_count == 0)\n    {\n    /* Backtracking path entry. */\n    SLJIT_ASSERT(common->currententry->backtrack_label == NULL);\n    common->currententry->backtrack_label = LABEL();\n    set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label);\n\n    sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP1, 0);\n\n    if (recurse_flags & recurse_flag_accept_found)\n      accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);\n\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));\n    /* Save return address. */\n    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(local_size - 1), TMP1, 0);\n\n    copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);\n\n    if (alt_max > 1)\n      {\n      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));\n      free_stack(common, 2);\n\n      if (alt_max > 3)\n        {\n        sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);\n        sljit_set_label(mov_addr, LABEL());\n        sljit_emit_op0(compiler, SLJIT_ENDBR);\n        }\n      else\n        next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);\n      }\n    else\n      free_stack(common, (recurse_flags & recurse_flag_accept_found) ? 2 : 1);\n    }\n  else if (alt_max > 3)\n    {\n    sljit_set_label(mov_addr, LABEL());\n    sljit_emit_op0(compiler, SLJIT_ENDBR);\n    }\n  else\n    {\n    JUMPHERE(next_alt);\n    if (alt_count + 1 < alt_max)\n      {\n      SLJIT_ASSERT(alt_count == 1 && alt_max == 3);\n      next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);\n      }\n    }\n\n  alt_count++;\n\n  compile_backtrackingpath(common, altbacktrack.top);\n  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n    return;\n  set_jumps(altbacktrack.own_backtracks, LABEL());\n\n  if (*cc != OP_ALT)\n    break;\n\n  altbacktrack.cc = cc + 1 + LINK_SIZE;\n  cc += GET(cc, 1);\n  }\n\n/* No alternative is matched. */\n\nquit = LABEL();\n\ncopy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_size, private_data_size + local_size, recurse_flags);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));\nfree_stack(common, private_data_size + local_size);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\nOP_SRC(SLJIT_FAST_RETURN, TMP2, 0);\n\nif (common->quit != NULL)\n  {\n  SLJIT_ASSERT(recurse_flags & recurse_flag_quit_found);\n\n  set_jumps(common->quit, LABEL());\n  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);\n  copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, recurse_flags);\n  JUMPTO(SLJIT_JUMP, quit);\n  }\n\nif (recurse_flags & recurse_flag_accept_found)\n  {\n  JUMPHERE(accept_exit);\n  free_stack(common, 2);\n\n  /* Save return address. */\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP1, 0);\n\n  copy_recurse_data(common, ccbegin, ccend, recurse_copy_kept_shared_to_global, local_size, private_data_size + local_size, recurse_flags);\n\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));\n  free_stack(common, private_data_size + local_size);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);\n  OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);\n  }\n\nif (common->accept != NULL)\n  {\n  SLJIT_ASSERT(recurse_flags & recurse_flag_accept_found);\n\n  set_jumps(common->accept, LABEL());\n\n  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);\n  OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);\n\n  allocate_stack(common, 2);\n  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);\n  }\n\nset_jumps(match, LABEL());\n\nOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);\n\ncopy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);\n\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1));\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);\nOP_SRC(SLJIT_FAST_RETURN, TMP2, 0);\n}\n\n#undef COMPILE_BACKTRACKINGPATH\n#undef CURRENT_AS\n\n#define PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS \\\n  (PCRE2_JIT_INVALID_UTF)\n\nstatic int jit_compile(pcre2_code *code, sljit_u32 mode)\n{\npcre2_real_code *re = (pcre2_real_code *)code;\nstruct sljit_compiler *compiler;\nbacktrack_common rootbacktrack;\ncompiler_common common_data;\ncompiler_common *common = &common_data;\nconst sljit_u8 *tables = re->tables;\nvoid *allocator_data = &re->memctl;\nint private_data_size;\nPCRE2_SPTR ccend;\nexecutable_functions *functions;\nvoid *executable_func;\nsljit_uw executable_size, private_data_length, total_length;\nstruct sljit_label *mainloop_label = NULL;\nstruct sljit_label *continue_match_label;\nstruct sljit_label *empty_match_found_label = NULL;\nstruct sljit_label *empty_match_backtrack_label = NULL;\nstruct sljit_label *reset_match_label;\nstruct sljit_label *quit_label;\nstruct sljit_jump *jump;\nstruct sljit_jump *minlength_check_failed = NULL;\nstruct sljit_jump *empty_match = NULL;\nstruct sljit_jump *end_anchor_failed = NULL;\njump_list *reqcu_not_found = NULL;\n\nSLJIT_ASSERT(tables);\n\n#if HAS_VIRTUAL_REGISTERS == 1\nSLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) < 0);\n#elif HAS_VIRTUAL_REGISTERS == 0\nSLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) >= 0);\n#else\n#error \"Invalid value for HAS_VIRTUAL_REGISTERS\"\n#endif\n\nmemset(&rootbacktrack, 0, sizeof(backtrack_common));\nmemset(common, 0, sizeof(compiler_common));\ncommon->re = re;\ncommon->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));\nrootbacktrack.cc = (PCRE2_SPTR)((uint8_t *)re + re->code_start);\n\n#ifdef SUPPORT_UNICODE\ncommon->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0;\n#endif /* SUPPORT_UNICODE */\nmode &= ~PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS;\n\ncommon->start = rootbacktrack.cc;\ncommon->read_only_data_head = NULL;\ncommon->fcc = tables + fcc_offset;\ncommon->lcc = (sljit_sw)(tables + lcc_offset);\ncommon->mode = mode;\ncommon->might_be_empty = (re->minlength == 0) || (re->flags & PCRE2_MATCH_EMPTY);\ncommon->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY);\ncommon->nltype = NLTYPE_FIXED;\nswitch(re->newline_convention)\n  {\n  case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break;\n  case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break;\n  case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;\n  case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;\n  case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;\n  case PCRE2_NEWLINE_NUL: common->newline = CHAR_NUL; break;\n  default: return PCRE2_ERROR_INTERNAL;\n  }\ncommon->nlmax = READ_CHAR_MAX;\ncommon->nlmin = 0;\nif (re->bsr_convention == PCRE2_BSR_UNICODE)\n  common->bsr_nltype = NLTYPE_ANY;\nelse if (re->bsr_convention == PCRE2_BSR_ANYCRLF)\n  common->bsr_nltype = NLTYPE_ANYCRLF;\nelse\n  {\n#ifdef BSR_ANYCRLF\n  common->bsr_nltype = NLTYPE_ANYCRLF;\n#else\n  common->bsr_nltype = NLTYPE_ANY;\n#endif\n  }\ncommon->bsr_nlmax = READ_CHAR_MAX;\ncommon->bsr_nlmin = 0;\ncommon->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0;\ncommon->ctypes = (sljit_sw)(tables + ctypes_offset);\ncommon->name_count = re->name_count;\ncommon->name_entry_size = re->name_entry_size;\ncommon->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0;\ncommon->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;\n#ifdef SUPPORT_UNICODE\n/* PCRE2_UTF[16|32] have the same value as PCRE2_UTF8. */\ncommon->utf = (re->overall_options & PCRE2_UTF) != 0;\ncommon->ucp = (re->overall_options & PCRE2_UCP) != 0;\nif (common->utf)\n  {\n  if (common->nltype == NLTYPE_ANY)\n    common->nlmax = 0x2029;\n  else if (common->nltype == NLTYPE_ANYCRLF)\n    common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;\n  else\n    {\n    /* We only care about the first newline character. */\n    common->nlmax = common->newline & 0xff;\n    }\n\n  if (common->nltype == NLTYPE_FIXED)\n    common->nlmin = common->newline & 0xff;\n  else\n    common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;\n\n  if (common->bsr_nltype == NLTYPE_ANY)\n    common->bsr_nlmax = 0x2029;\n  else\n    common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;\n  common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;\n  }\nelse\n  common->invalid_utf = FALSE;\n#endif /* SUPPORT_UNICODE */\nccend = bracketend(common->start);\n\n/* Calculate the local space size on the stack. */\ncommon->ovector_start = LOCAL0;\n/* Allocate space for temporary data structures. */\nprivate_data_length = ccend - common->start;\n/* The chance of overflow is very low, but might happen on 32 bit. */\nif (private_data_length > ~(sljit_uw)0 / sizeof(sljit_s32))\n  return PCRE2_ERROR_NOMEMORY;\n\nprivate_data_length *= sizeof(sljit_s32);\n/* Align to 32 bit. */\ncommon->cbracket_bitset_length = ((re->top_bracket + 1) + (sljit_u32)7) & ~(sljit_u32)7;\ntotal_length = common->cbracket_bitset_length << 1;\nif (~(sljit_uw)0 - private_data_length < total_length)\n  return PCRE2_ERROR_NOMEMORY;\n\ntotal_length += private_data_length;\ncommon->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length, allocator_data);\nif (!common->private_data_ptrs)\n  return PCRE2_ERROR_NOMEMORY;\n\nmemset(common->private_data_ptrs, 0, private_data_length);\ncommon->optimized_cbrackets = ((sljit_u8 *)common->private_data_ptrs) + private_data_length;\n#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1\nmemset(common->optimized_cbrackets, 0, common->cbracket_bitset_length);\n#else\nmemset(common->optimized_cbrackets, 0xff, common->cbracket_bitset_length);\n#endif\ncommon->cbracket_bitset = common->optimized_cbrackets + common->cbracket_bitset_length;\n\nSLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);\n#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2\ncommon->capture_last_ptr = common->ovector_start;\ncommon->ovector_start += sizeof(sljit_sw);\n#endif\nif (!check_opcode_types(common, common->start, ccend))\n  {\n  SLJIT_FREE(common->private_data_ptrs, allocator_data);\n  return PCRE2_ERROR_JIT_UNSUPPORTED;\n  }\n\n/* Checking flags and updating ovector_start. */\nif (mode == PCRE2_JIT_COMPLETE &&\n    (re->flags & PCRE2_LASTSET) != 0 &&\n    (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n  {\n  common->req_char_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\nif (mode != PCRE2_JIT_COMPLETE)\n  {\n  common->start_used_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  if (mode == PCRE2_JIT_PARTIAL_SOFT)\n    {\n    common->hit_start = common->ovector_start;\n    common->ovector_start += sizeof(sljit_sw);\n    }\n  }\n\nif ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0)\n  {\n  common->match_end_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\n#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD\ncommon->control_head_ptr = 1;\n#endif\n\nif (common->control_head_ptr != 0)\n  {\n  common->control_head_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\nif (common->has_set_som)\n  {\n  /* Saving the real start pointer is necessary. */\n  common->start_ptr = common->ovector_start;\n  common->ovector_start += sizeof(sljit_sw);\n  }\n\n/* Aligning ovector to even number of sljit words. */\nif ((common->ovector_start & sizeof(sljit_sw)) != 0)\n  common->ovector_start += sizeof(sljit_sw);\n\nif (common->start_ptr == 0)\n  common->start_ptr = OVECTOR(0);\n\n/* Capturing brackets cannot be optimized if callouts are allowed. */\nif (common->capture_last_ptr != 0)\n  memset(common->optimized_cbrackets, 0, common->cbracket_bitset_length);\n\nSLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));\ncommon->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);\nprivate_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);\n\nif ((re->overall_options & PCRE2_ANCHORED) == 0 &&\n    (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 &&\n    !common->has_skip_in_assert_back)\n  detect_early_fail(common, common->start, &private_data_size, 0, 0);\n\nset_private_data_ptrs(common, &private_data_size, ccend);\n\nSLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);\n\nif (private_data_size > 65536)\n  {\n  SLJIT_FREE(common->private_data_ptrs, allocator_data);\n  return PCRE2_ERROR_JIT_UNSUPPORTED;\n  }\n\nif (common->has_then)\n  {\n  total_length = ccend - common->start;\n  common->then_offsets = (sljit_u8 *)SLJIT_MALLOC(total_length, allocator_data);\n  if (!common->then_offsets)\n    {\n    SLJIT_FREE(common->private_data_ptrs, allocator_data);\n    return PCRE2_ERROR_NOMEMORY;\n    }\n  memset(common->then_offsets, 0, total_length);\n  set_then_offsets(common, common->start, NULL);\n  }\n\ncompiler = sljit_create_compiler(allocator_data);\nif (!compiler)\n  {\n  SLJIT_FREE(common->private_data_ptrs, allocator_data);\n  if (common->has_then)\n    SLJIT_FREE(common->then_offsets, allocator_data);\n  return PCRE2_ERROR_NOMEMORY;\n  }\ncommon->compiler = compiler;\n\n/* Main pcre2_jit_exec entry. */\nSLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0);\nsljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5 | SLJIT_ENTER_VECTOR(SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS), 5, private_data_size);\n\n/* Register init. */\nreset_ovector(common, (re->top_bracket + 1) * 2);\nif (common->req_char_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);\n\nOP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\nOP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));\nOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));\nOP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));\nOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));\nOP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);\n\nif (common->early_fail_start_ptr < common->early_fail_end_ptr)\n  reset_early_fail(common);\n\nif (mode == PCRE2_JIT_PARTIAL_SOFT)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);\nif (common->mark_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);\nif (common->control_head_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);\n\n/* Main part of the matching */\nif ((re->overall_options & PCRE2_ANCHORED) == 0)\n  {\n  mainloop_label = mainloop_entry(common);\n  continue_match_label = LABEL();\n  /* Forward search if possible. */\n  if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n    {\n    if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))\n      ;\n    else if ((re->flags & PCRE2_FIRSTSET) != 0)\n      fast_forward_first_char(common);\n    else if ((re->flags & PCRE2_STARTLINE) != 0)\n      fast_forward_newline(common);\n    else if ((re->flags & PCRE2_FIRSTMAPSET) != 0)\n      fast_forward_start_bits(common);\n    }\n  }\nelse\n  continue_match_label = LABEL();\n\nif (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 &&\n    (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n  {\n  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);\n  OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength));\n  minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);\n  }\nif (common->req_char_ptr != 0)\n  reqcu_not_found = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);\n\n/* Store the current STR_PTR in OVECTOR(0). */\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);\n/* Copy the limit of allowed recursions. */\nOP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);\nif (common->capture_last_ptr != 0)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);\nif (common->fast_forward_bc_ptr != NULL)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3, STR_PTR, 0);\n\nif (common->start_ptr != OVECTOR(0))\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);\n\n/* Copy the beginning of the string. */\nif (mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n  JUMPHERE(jump);\n  }\nelse if (mode == PCRE2_JIT_PARTIAL_HARD)\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);\n\ncompile_matchingpath(common, common->start, ccend, &rootbacktrack);\nif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n  {\n  sljit_free_compiler(compiler);\n  SLJIT_FREE(common->private_data_ptrs, allocator_data);\n  if (common->has_then)\n    SLJIT_FREE(common->then_offsets, allocator_data);\n  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);\n  return PCRE2_ERROR_NOMEMORY;\n  }\n\nif ((re->overall_options & PCRE2_ENDANCHORED) != 0)\n  end_anchor_failed = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0);\n\nif (common->might_be_empty)\n  {\n  empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));\n  empty_match_found_label = LABEL();\n  }\n\ncommon->accept_label = LABEL();\nif (common->accept != NULL)\n  set_jumps(common->accept, common->accept_label);\n\n/* Fail if we detect that the start position was moved to be either after\nthe end position (\\K in lookahead) or before the start offset (\\K in\nlookbehind). */\n\nif (common->has_set_som &&\n    (common->re->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0)\n  {\n  if (HAS_VIRTUAL_REGISTERS)\n    {\n    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n    }\n  else\n    {\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));\n    }\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));\n\n  /* (ovector[0] < jit_arguments->str)? */\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, TMP1, 0);\n  /* Unconditionally set R0 (aka TMP1), in between the comparison that needs to\n  use TMP1, but before the jump. */\n  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_BAD_BACKSLASH_K);\n  add_jump(compiler, &common->abort, JUMP(SLJIT_LESS));\n  /* (ovector[0] > STR_PTR)?  NB. ovector[1] hasn't yet been set to STR_PTR. */\n  add_jump(compiler, &common->abort, CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0));\n  }\n\n/* This means we have a match. Update the ovector. */\ncopy_ovector(common, re->top_bracket + 1);\ncommon->quit_label = common->abort_label = LABEL();\nif (common->quit != NULL)\n  set_jumps(common->quit, common->quit_label);\nif (common->abort != NULL)\n  set_jumps(common->abort, common->abort_label);\nif (minlength_check_failed != NULL)\n  SET_LABEL(minlength_check_failed, common->abort_label);\n\nsljit_emit_op0(compiler, SLJIT_SKIP_FRAMES_BEFORE_RETURN);\nsljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);\n\nif (common->failed_match != NULL)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n  set_jumps(common->failed_match, LABEL());\n  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);\n  JUMPTO(SLJIT_JUMP, common->abort_label);\n  }\n\nif ((re->overall_options & PCRE2_ENDANCHORED) != 0)\n  JUMPHERE(end_anchor_failed);\n\nif (mode != PCRE2_JIT_COMPLETE)\n  {\n  common->partialmatchlabel = LABEL();\n  set_jumps(common->partialmatch, common->partialmatchlabel);\n  return_with_partial_match(common, common->quit_label);\n  }\n\nif (common->might_be_empty)\n  empty_match_backtrack_label = LABEL();\ncompile_backtrackingpath(common, rootbacktrack.top);\nif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n  {\n  sljit_free_compiler(compiler);\n  SLJIT_FREE(common->private_data_ptrs, allocator_data);\n  if (common->has_then)\n    SLJIT_FREE(common->then_offsets, allocator_data);\n  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);\n  return PCRE2_ERROR_NOMEMORY;\n  }\n\nSLJIT_ASSERT(rootbacktrack.prev == NULL);\nreset_match_label = LABEL();\n\nif (mode == PCRE2_JIT_PARTIAL_SOFT)\n  {\n  /* Update hit_start only in the first time. */\n  jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);\n  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);\n  JUMPHERE(jump);\n  }\n\n/* Check we have remaining characters. */\nif ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  }\n\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),\n    (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr);\n\nif ((re->overall_options & PCRE2_ANCHORED) == 0)\n  {\n  if (common->ff_newline_shortcut != NULL)\n    {\n    /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */\n    if ((re->overall_options & PCRE2_FIRSTLINE) == 0)\n      {\n      if (common->match_end_ptr != 0)\n        {\n        OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n        OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);\n        CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);\n        OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n        }\n      else\n        CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);\n      }\n    }\n  else\n    CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);\n  }\n\n/* No more remaining characters. */\nif (reqcu_not_found != NULL)\n  set_jumps(reqcu_not_found, LABEL());\n\nif (mode == PCRE2_JIT_PARTIAL_SOFT)\n  CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);\n\nOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);\nJUMPTO(SLJIT_JUMP, common->quit_label);\n\nflush_stubs(common);\n\nif (common->might_be_empty)\n  {\n  JUMPHERE(empty_match);\n  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);\n  OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);\n  JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);\n  OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);\n  JUMPTO(SLJIT_ZERO, empty_match_found_label);\n  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));\n  CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);\n  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);\n  }\n\ncommon->fast_forward_bc_ptr = NULL;\ncommon->early_fail_start_ptr = 0;\ncommon->early_fail_end_ptr = 0;\ncommon->currententry = common->entries;\ncommon->local_quit_available = TRUE;\nquit_label = common->quit_label;\nSLJIT_ASSERT(common->restore_end_ptr == 0);\n\nif (common->currententry != NULL)\n  {\n  /* A free bit for each private data. */\n  common->recurse_bitset_size = ((private_data_size / SSIZE_OF(sw)) + 7) >> 3;\n  SLJIT_ASSERT(common->recurse_bitset_size > 0);\n  common->recurse_bitset = (sljit_u8*)SLJIT_MALLOC(common->recurse_bitset_size, allocator_data);;\n\n  if (common->recurse_bitset != NULL)\n    {\n    do\n      {\n      /* Might add new entries. */\n      compile_recurse(common);\n      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))\n        break;\n      flush_stubs(common);\n      common->currententry = common->currententry->next;\n      }\n    while (common->currententry != NULL);\n\n    SLJIT_FREE(common->recurse_bitset, allocator_data);\n    }\n\n  if (common->currententry != NULL)\n    {\n    /* The common->recurse_bitset has been freed. */\n    SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL);\n\n    sljit_free_compiler(compiler);\n    SLJIT_FREE(common->private_data_ptrs, allocator_data);\n    if (common->has_then)\n      SLJIT_FREE(common->then_offsets, allocator_data);\n    PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);\n    return PCRE2_ERROR_NOMEMORY;\n    }\n  }\n\ncommon->local_quit_available = FALSE;\ncommon->quit_label = quit_label;\nSLJIT_ASSERT(common->restore_end_ptr == 0);\n\n/* Allocating stack, returns with PCRE2_ERROR_JIT_STACKLIMIT if fails. */\n/* This is a (really) rare case. */\nset_jumps(common->stackalloc, LABEL());\n/* RETURN_ADDR is not a saved register. */\nSLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw));\nsljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0);\n\nSLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);\n\nOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, STR_PTR, 0);\nOP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);\nOP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);\nOP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));\nOP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);\n\nsljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(sljit_stack_resize));\n\njump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);\nOP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);\nOP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);\nOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);\nOP_SRC(SLJIT_FAST_RETURN, TMP1, 0);\n\n/* Allocation failed. */\nJUMPHERE(jump);\n/* We break the return address cache here, but this is a really rare case. */\nOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT);\nJUMPTO(SLJIT_JUMP, common->quit_label);\n\n/* Call limit reached. */\nset_jumps(common->calllimit, LABEL());\nOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT);\nJUMPTO(SLJIT_JUMP, common->quit_label);\n\nif (common->revertframes != NULL)\n  {\n  set_jumps(common->revertframes, LABEL());\n  do_revertframes(common);\n  }\nif (common->wordboundary != NULL)\n  {\n  set_jumps(common->wordboundary, LABEL());\n  check_wordboundary(common, FALSE);\n  }\nif (common->ucp_wordboundary != NULL)\n  {\n  set_jumps(common->ucp_wordboundary, LABEL());\n  check_wordboundary(common, TRUE);\n  }\nif (common->anynewline != NULL)\n  {\n  set_jumps(common->anynewline, LABEL());\n  check_anynewline(common);\n  }\nif (common->hspace != NULL)\n  {\n  set_jumps(common->hspace, LABEL());\n  check_hspace(common);\n  }\nif (common->vspace != NULL)\n  {\n  set_jumps(common->vspace, LABEL());\n  check_vspace(common);\n  }\nif (common->casefulcmp != NULL)\n  {\n  set_jumps(common->casefulcmp, LABEL());\n  do_casefulcmp(common);\n  }\nif (common->caselesscmp != NULL)\n  {\n  set_jumps(common->caselesscmp, LABEL());\n  do_caselesscmp(common);\n  }\nif (common->reset_match != NULL || common->restart_match != NULL)\n  {\n  if (common->restart_match != NULL)\n    {\n    set_jumps(common->restart_match, LABEL());\n    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);\n    }\n\n  set_jumps(common->reset_match, LABEL());\n  do_reset_match(common, (re->top_bracket + 1) * 2);\n  /* The value of restart_match is in TMP1. */\n  CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);\n  OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);\n  JUMPTO(SLJIT_JUMP, reset_match_label);\n  }\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif (common->utfreadchar != NULL)\n  {\n  set_jumps(common->utfreadchar, LABEL());\n  do_utfreadchar(common);\n  }\nif (common->utfreadtype8 != NULL)\n  {\n  set_jumps(common->utfreadtype8, LABEL());\n  do_utfreadtype8(common);\n  }\nif (common->utfpeakcharback != NULL)\n  {\n  set_jumps(common->utfpeakcharback, LABEL());\n  do_utfpeakcharback(common);\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */\n#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16\nif (common->utfreadchar_invalid != NULL)\n  {\n  set_jumps(common->utfreadchar_invalid, LABEL());\n  do_utfreadchar_invalid(common);\n  }\nif (common->utfreadnewline_invalid != NULL)\n  {\n  set_jumps(common->utfreadnewline_invalid, LABEL());\n  do_utfreadnewline_invalid(common);\n  }\nif (common->utfmoveback_invalid)\n  {\n  set_jumps(common->utfmoveback_invalid, LABEL());\n  do_utfmoveback_invalid(common);\n  }\nif (common->utfpeakcharback_invalid)\n  {\n  set_jumps(common->utfpeakcharback_invalid, LABEL());\n  do_utfpeakcharback_invalid(common);\n  }\n#endif /* PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 */\nif (common->getucd != NULL)\n  {\n  set_jumps(common->getucd, LABEL());\n  do_getucd(common);\n  }\nif (common->getucdtype != NULL)\n  {\n  set_jumps(common->getucdtype, LABEL());\n  do_getucdtype(common);\n  }\n#endif /* SUPPORT_UNICODE */\n\nSLJIT_FREE(common->private_data_ptrs, allocator_data);\nif (common->has_then)\n  SLJIT_FREE(common->then_offsets, allocator_data);\n\nexecutable_func = sljit_generate_code(compiler, 0, NULL);\nexecutable_size = sljit_get_generated_code_size(compiler);\nsljit_free_compiler(compiler);\n\nif (executable_func == NULL)\n  {\n  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);\n  return PCRE2_ERROR_NOMEMORY;\n  }\n\n/* Reuse the function descriptor if possible. */\nif (re->executable_jit != NULL)\n  functions = (executable_functions *)re->executable_jit;\nelse\n  {\n  functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data);\n  if (functions == NULL)\n    {\n    /* This case is highly unlikely since we just recently\n    freed a lot of memory. Not impossible though. */\n    sljit_free_code(executable_func, NULL);\n    PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);\n    return PCRE2_ERROR_NOMEMORY;\n    }\n  memset(functions, 0, sizeof(executable_functions));\n  functions->top_bracket = re->top_bracket + 1;\n  functions->limit_match = re->limit_match;\n  re->executable_jit = functions;\n  }\n\n/* Turn mode into an index. */\nif (mode == PCRE2_JIT_COMPLETE)\n  mode = 0;\nelse\n  mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2;\n\nSLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES);\nfunctions->executable_funcs[mode] = executable_func;\nfunctions->read_only_data_heads[mode] = common->read_only_data_head;\nfunctions->executable_sizes[mode] = executable_size;\nreturn 0;\n}\n\n#endif\n\n/*************************************************\n*        JIT compile a Regular Expression        *\n*************************************************/\n\n/* This function used JIT to convert a previously-compiled pattern into machine\ncode.\n\nArguments:\n  code          a compiled pattern\n  options       JIT option bits\n\nReturns:        0: success or (*NOJIT) was used\n               <0: an error code\n*/\n\n#define PUBLIC_JIT_COMPILE_OPTIONS \\\n  (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD|PCRE2_JIT_INVALID_UTF)\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_jit_compile(pcre2_code *code, uint32_t options)\n{\npcre2_real_code *re = (pcre2_real_code *)code;\n#ifdef SUPPORT_JIT\nvoid *exec_memory;\nexecutable_functions *functions;\nstatic int executable_allocator_is_working = -1;\n\nif (executable_allocator_is_working == -1)\n  {\n  /* Checks whether the executable allocator is working. This check\n     might run multiple times in multi-threaded environments, but the\n     result should not be affected by it. */\n  exec_memory = SLJIT_MALLOC_EXEC(32, NULL);\n  if (exec_memory != NULL)\n    {\n    SLJIT_FREE_EXEC(((sljit_u8*)(exec_memory)) + SLJIT_EXEC_OFFSET(exec_memory), NULL);\n    executable_allocator_is_working = 1;\n    }\n  else executable_allocator_is_working = 0;\n  }\n#endif\n\nif (options & PCRE2_JIT_TEST_ALLOC)\n  {\n  if (options != PCRE2_JIT_TEST_ALLOC)\n    return PCRE2_ERROR_JIT_BADOPTION;\n\n#ifdef SUPPORT_JIT\n  return executable_allocator_is_working ? 0 : PCRE2_ERROR_NOMEMORY;\n#else\n  return PCRE2_ERROR_JIT_UNSUPPORTED;\n#endif\n  }\n\nif (code == NULL)\n  return PCRE2_ERROR_NULL;\n\nif ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)\n  return PCRE2_ERROR_JIT_BADOPTION;\n\n/* Support for invalid UTF was first introduced in JIT, with the option\nPCRE2_JIT_INVALID_UTF. Later, support was added to the interpreter, and the\ncompile-time option PCRE2_MATCH_INVALID_UTF was created. This is now the\npreferred feature, with the earlier option deprecated. However, for backward\ncompatibility, if the earlier option is set, it forces the new option so that\nif JIT matching falls back to the interpreter, there is still support for\ninvalid UTF. However, if this function has already been successfully called\nwithout PCRE2_JIT_INVALID_UTF and without PCRE2_MATCH_INVALID_UTF (meaning that\nnon-invalid-supporting JIT code was compiled), give an error.\n\nIf in the future support for PCRE2_JIT_INVALID_UTF is withdrawn, the following\nactions are needed:\n\n  1. Remove the definition from pcre2.h.in and from the list in\n     PUBLIC_JIT_COMPILE_OPTIONS above.\n\n  2. Replace PCRE2_JIT_INVALID_UTF with a local flag in this module.\n\n  3. Replace PCRE2_JIT_INVALID_UTF in pcre2_jit_test.c.\n\n  4. Delete the following short block of code. The setting of \"re\" and\n     \"functions\" can be moved into the JIT-only block below, but if that is\n     done, (void)re and (void)functions will be needed in the non-JIT case, to\n     avoid compiler warnings.\n*/\n\n#ifdef SUPPORT_JIT\nfunctions = (executable_functions *)re->executable_jit;\n#endif\n\nif ((options & PCRE2_JIT_INVALID_UTF) != 0)\n  {\n  if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0)\n    {\n#ifdef SUPPORT_JIT\n    if (functions != NULL) return PCRE2_ERROR_JIT_BADOPTION;\n#endif\n    re->overall_options |= PCRE2_MATCH_INVALID_UTF;\n    }\n  }\n\n/* The above tests are run with and without JIT support. This means that\nPCRE2_JIT_INVALID_UTF propagates back into the regex options (ensuring\ninterpreter support) even in the absence of JIT. But now, if there is no JIT\nsupport, give an error return. */\n\n#ifndef SUPPORT_JIT\nreturn PCRE2_ERROR_JIT_BADOPTION;\n#else  /* SUPPORT_JIT */\n\n/* There is JIT support. Do the necessary. */\n\nif ((re->flags & PCRE2_NOJIT) != 0) return 0;\n\nif (!executable_allocator_is_working)\n  return PCRE2_ERROR_NOMEMORY;\n\nif ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)\n  options |= PCRE2_JIT_INVALID_UTF;\n\nif ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL\n    || functions->executable_funcs[0] == NULL)) {\n  uint32_t excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);\n  int result = jit_compile(code, options & ~excluded_options);\n  if (result != 0)\n    return result;\n  }\n\nif ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL\n    || functions->executable_funcs[1] == NULL)) {\n  uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD);\n  int result = jit_compile(code, options & ~excluded_options);\n  if (result != 0)\n    return result;\n  }\n\nif ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL\n    || functions->executable_funcs[2] == NULL)) {\n  uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);\n  int result = jit_compile(code, options & ~excluded_options);\n  if (result != 0)\n    return result;\n  }\n\nreturn 0;\n\n#endif  /* SUPPORT_JIT */\n}\n\n/* JIT compiler uses an all-in-one approach. This improves security,\n   since the code generator functions are not exported. */\n\n#define INCLUDED_FROM_PCRE2_JIT_COMPILE\n\n#include \"pcre2_jit_match_inc.h\"\n#include \"pcre2_jit_misc_inc.h\"\n\n/* End of pcre2_jit_compile.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_jit_match_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2023 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE\n#error This file must be included from pcre2_jit_compile.c.\n#endif\n\n#if defined(__has_feature)\n#if __has_feature(memory_sanitizer)\n#include <sanitizer/msan_interface.h>\n#endif /* __has_feature(memory_sanitizer) */\n#endif /* defined(__has_feature) */\n\n#ifdef SUPPORT_JIT\n\nstatic SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)\n{\nsljit_u8 local_space[MACHINE_STACK_SIZE];\nstruct sljit_stack local_stack;\n\nlocal_stack.min_start = local_space;\nlocal_stack.start = local_space;\nlocal_stack.end = local_space + MACHINE_STACK_SIZE;\nlocal_stack.top = local_space + MACHINE_STACK_SIZE;\narguments->stack = &local_stack;\nreturn executable_func(arguments);\n}\n\n#endif\n\n\n/*************************************************\n*              Do a JIT pattern match            *\n*************************************************/\n\n/* This function runs a JIT pattern match.\n\nArguments:\n  code            points to the compiled expression\n  subject         points to the subject string\n  length          length of subject string (may contain binary zeros)\n  start_offset    where to start in the subject string\n  options         option bits\n  match_data      points to a match_data block\n  mcontext        points to a match context\n\nReturns:          > 0 => success; value is the number of ovector pairs filled\n                  = 0 => success, but ovector is not big enough\n                   -1 => failed to match (PCRE2_ERROR_NOMATCH)\n                 < -1 => some kind of unexpected problem\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,\n  PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,\n  pcre2_match_context *mcontext)\n{\n#ifndef SUPPORT_JIT\n\n(void)code;\n(void)subject;\n(void)length;\n(void)start_offset;\n(void)options;\n(void)mcontext;\nreturn match_data->rc = PCRE2_ERROR_JIT_BADOPTION;\n\n#else  /* SUPPORT_JIT */\n\npcre2_real_code *re = (pcre2_real_code *)code;\nexecutable_functions *functions = (executable_functions *)re->executable_jit;\npcre2_jit_stack *jit_stack;\nuint32_t oveccount = match_data->oveccount;\nuint32_t max_oveccount;\nunion {\n   void *executable_func;\n   jit_function call_executable_func;\n} convert_executable_func;\njit_arguments arguments;\nint rc;\nint index = 0;\n\nif ((options & PCRE2_PARTIAL_HARD) != 0)\n  index = 2;\nelse if ((options & PCRE2_PARTIAL_SOFT) != 0)\n  index = 1;\n\nif (functions == NULL || functions->executable_funcs[index] == NULL)\n  return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;\n\n/* Sanity checks should be handled by pcre2_match. */\narguments.str = subject + start_offset;\narguments.begin = subject;\narguments.end = subject + length;\narguments.match_data = match_data;\narguments.startchar_ptr = subject;\narguments.mark_ptr = NULL;\narguments.options = options;\n\nif (mcontext != NULL)\n  {\n  arguments.callout = mcontext->callout;\n  arguments.callout_data = mcontext->callout_data;\n  arguments.offset_limit = mcontext->offset_limit;\n  arguments.limit_match = (mcontext->match_limit < re->limit_match)?\n    mcontext->match_limit : re->limit_match;\n  if (mcontext->jit_callback != NULL)\n    jit_stack = mcontext->jit_callback(mcontext->jit_callback_data);\n  else\n    jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data;\n  }\nelse\n  {\n  arguments.callout = NULL;\n  arguments.callout_data = NULL;\n  arguments.offset_limit = PCRE2_UNSET;\n  arguments.limit_match = (MATCH_LIMIT < re->limit_match)?\n    MATCH_LIMIT : re->limit_match;\n  jit_stack = NULL;\n  }\n\n\nmax_oveccount = functions->top_bracket;\nif (oveccount > max_oveccount)\n  oveccount = max_oveccount;\narguments.oveccount = oveccount << 1;\n\n\nconvert_executable_func.executable_func = functions->executable_funcs[index];\nif (jit_stack != NULL)\n  {\n  arguments.stack = (struct sljit_stack *)(jit_stack->stack);\n  rc = convert_executable_func.call_executable_func(&arguments);\n  }\nelse\n  rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func);\n\nif (rc > (int)oveccount)\n  rc = 0;\nmatch_data->code = re;\nmatch_data->subject =\n  (rc >= 0 || rc == PCRE2_ERROR_NOMATCH || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;\nmatch_data->subject_length = length;\nmatch_data->start_offset = start_offset;\nmatch_data->rc = rc;\nmatch_data->startchar = arguments.startchar_ptr - subject;\nmatch_data->leftchar = 0;\nmatch_data->rightchar = 0;\nmatch_data->mark = arguments.mark_ptr;\nmatch_data->matchedby = PCRE2_MATCHEDBY_JIT;\nmatch_data->options = options;\n\n#if defined(__has_feature)\n#if __has_feature(memory_sanitizer)\nif (rc > 0)\n  __msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0]));\n#endif /* __has_feature(memory_sanitizer) */\n#endif /* defined(__has_feature) */\n\nreturn match_data->rc;\n\n#endif  /* SUPPORT_JIT */\n}\n\n/* End of pcre2_jit_match_inc.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_jit_misc_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n         New API code Copyright (c) 2016 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE\n#error This file must be included from pcre2_jit_compile.c.\n#endif\n\n\n\n/*************************************************\n*           Free JIT read-only data              *\n*************************************************/\n\nvoid\nPRIV(jit_free_rodata)(void *current, void *allocator_data)\n{\n#ifndef SUPPORT_JIT\n(void)current;\n(void)allocator_data;\n#else  /* SUPPORT_JIT */\nvoid *next;\n\nSLJIT_UNUSED_ARG(allocator_data);\n\nwhile (current != NULL)\n  {\n  next = *(void**)current;\n  SLJIT_FREE(current, allocator_data);\n  current = next;\n  }\n\n#endif /* SUPPORT_JIT */\n}\n\n/*************************************************\n*           Free JIT compiled code               *\n*************************************************/\n\nvoid\nPRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl)\n{\n#ifndef SUPPORT_JIT\n(void)executable_jit;\n(void)memctl;\n#else  /* SUPPORT_JIT */\n\nexecutable_functions *functions = (executable_functions *)executable_jit;\nvoid *allocator_data = memctl;\nint i;\n\nfor (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)\n  {\n  if (functions->executable_funcs[i] != NULL)\n    sljit_free_code(functions->executable_funcs[i], NULL);\n  PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);\n  }\n\nSLJIT_FREE(functions, allocator_data);\n\n#endif /* SUPPORT_JIT */\n}\n\n\n/*************************************************\n*            Free unused JIT memory              *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_jit_free_unused_memory(pcre2_general_context *gcontext)\n{\n#ifndef SUPPORT_JIT\n(void)gcontext;     /* Suppress warning */\n#else  /* SUPPORT_JIT */\nSLJIT_UNUSED_ARG(gcontext);\n#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)\nsljit_free_unused_memory_exec();\n#endif /* SLJIT_EXECUTABLE_ALLOCATOR */\n#endif /* SUPPORT_JIT */\n}\n\n\n\n/*************************************************\n*            Allocate a JIT stack                *\n*************************************************/\n\nPCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION\npcre2_jit_stack_create(size_t startsize, size_t maxsize,\n  pcre2_general_context *gcontext)\n{\n#ifndef SUPPORT_JIT\n\n(void)gcontext;\n(void)startsize;\n(void)maxsize;\nreturn NULL;\n\n#else  /* SUPPORT_JIT */\n\npcre2_jit_stack *jit_stack;\n\nif (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE)\n  return NULL;\nif (startsize > maxsize)\n  startsize = maxsize;\nstartsize = (startsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));\nmaxsize = (maxsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));\n\njit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);\nif (jit_stack == NULL) return NULL;\njit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);\nif (jit_stack->stack == NULL)\n  {\n  jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);\n  return NULL;\n  }\nreturn jit_stack;\n\n#endif\n}\n\n\n/*************************************************\n*         Assign a JIT stack to a pattern        *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback,\n  void *callback_data)\n{\n#ifndef SUPPORT_JIT\n(void)mcontext;\n(void)callback;\n(void)callback_data;\n#else  /* SUPPORT_JIT */\n\nif (mcontext == NULL) return;\nmcontext->jit_callback = callback;\nmcontext->jit_callback_data = callback_data;\n\n#endif  /* SUPPORT_JIT */\n}\n\n\n/*************************************************\n*               Free a JIT stack                 *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_jit_stack_free(pcre2_jit_stack *jit_stack)\n{\n#ifndef SUPPORT_JIT\n(void)jit_stack;\n#else  /* SUPPORT_JIT */\nif (jit_stack != NULL)\n  {\n  sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);\n  jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);\n  }\n#endif  /* SUPPORT_JIT */\n}\n\n\n/*************************************************\n*               Get target CPU type              *\n*************************************************/\n\nconst char*\nPRIV(jit_get_target)(void)\n{\n#ifndef SUPPORT_JIT\nreturn \"JIT is not supported\";\n#else  /* SUPPORT_JIT */\nreturn sljit_get_platform_name();\n#endif  /* SUPPORT_JIT */\n}\n\n\n/*************************************************\n*              Get size of JIT code              *\n*************************************************/\n\nsize_t\nPRIV(jit_get_size)(void *executable_jit)\n{\n#ifndef SUPPORT_JIT\n(void)executable_jit;\nreturn 0;\n#else  /* SUPPORT_JIT */\nsljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes;\nSLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed);\nreturn executable_sizes[0] + executable_sizes[1] + executable_sizes[2];\n#endif\n}\n\n/* End of pcre2_jit_misc_inc.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_jit_simd_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n                    This module by Zoltan Herczeg\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2019 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#if !(defined SUPPORT_VALGRIND)\n\n#if ((defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \\\n     || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \\\n     || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \\\n     || (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64))\n\ntypedef enum {\n  vector_compare_match1,\n  vector_compare_match1i,\n  vector_compare_match2,\n} vector_compare_type;\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\nstatic SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void)\n{\n#if PCRE2_CODE_UNIT_WIDTH == 8\n/* The AVX2 code path is currently disabled. */\n/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 31 : 15; */\nreturn 15;\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n/* The AVX2 code path is currently disabled. */\n/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 15 : 7; */\nreturn 7;\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n/* The AVX2 code path is currently disabled. */\n/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 7 : 3; */\nreturn 3;\n#else\n#error \"Unsupported unit width\"\n#endif\n}\n#else /* !SLJIT_CONFIG_X86 */\nstatic SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void)\n{\n#if PCRE2_CODE_UNIT_WIDTH == 8\nreturn 15;\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nreturn 7;\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nreturn 3;\n#else\n#error \"Unsupported unit width\"\n#endif\n}\n#endif /* SLJIT_CONFIG_X86 */\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstatic struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)\n{\n#if PCRE2_CODE_UNIT_WIDTH == 8\nOP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);\nreturn CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nOP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);\nreturn CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);\n#else\n#error \"Unknown code width\"\n#endif\n}\n#endif\n\n#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM_64 || SLJIT_CONFIG_S390X || SLJIT_CONFIG_LOONGARCH_64 */\n\n#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)\n\nstatic sljit_s32 character_to_int32(PCRE2_UCHAR chr)\n{\nsljit_u32 value = chr;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define SIMD_COMPARE_TYPE_INDEX 0\nreturn (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define SIMD_COMPARE_TYPE_INDEX 1\nreturn (sljit_s32)((value << 16) | value);\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n#define SIMD_COMPARE_TYPE_INDEX 2\nreturn (sljit_s32)(value);\n#else\n#error \"Unsupported unit width\"\n#endif\n}\n\nstatic void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,\n  sljit_s32 reg_type, int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)\n{\nsljit_u8 instruction[4];\n\nif (reg_type == SLJIT_SIMD_REG_128)\n  {\n  instruction[0] = 0x66;\n  instruction[1] = 0x0f;\n  }\nelse\n  {\n  /* Two byte VEX prefix. */\n  instruction[0] = 0xc5;\n  instruction[1] = 0xfd;\n  }\n\nSLJIT_ASSERT(step >= 0 && step <= 3);\n\nif (compare_type != vector_compare_match2)\n  {\n  if (step == 0)\n    {\n    if (compare_type == vector_compare_match1i)\n      {\n      /* POR xmm1, xmm2/m128 */\n      if (reg_type == SLJIT_SIMD_REG_256)\n        instruction[1] ^= (dst_ind << 3);\n\n      /* Prefix is filled. */\n      instruction[2] = 0xeb;\n      instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;\n      sljit_emit_op_custom(compiler, instruction, 4);\n      }\n    return;\n    }\n\n  if (step != 2)\n    return;\n\n  /* PCMPEQB/W/D xmm1, xmm2/m128 */\n  if (reg_type == SLJIT_SIMD_REG_256)\n    instruction[1] ^= (dst_ind << 3);\n\n  /* Prefix is filled. */\n  instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX;\n  instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n  return;\n  }\n\nif (reg_type == SLJIT_SIMD_REG_256)\n  {\n  if (step == 2)\n    return;\n\n  if (step == 0)\n    {\n    step = 2;\n    instruction[1] ^= (dst_ind << 3);\n    }\n  }\n\nswitch (step)\n  {\n  case 0:\n  SLJIT_ASSERT(reg_type == SLJIT_SIMD_REG_128);\n\n  /* MOVDQA xmm1, xmm2/m128 */\n  /* Prefix is filled. */\n  instruction[2] = 0x6f;\n  instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n  return;\n\n  case 1:\n  /* PCMPEQB/W/D xmm1, xmm2/m128 */\n  if (reg_type == SLJIT_SIMD_REG_256)\n    instruction[1] ^= (dst_ind << 3);\n\n  /* Prefix is filled. */\n  instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX;\n  instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n  return;\n\n  case 2:\n  /* PCMPEQB/W/D xmm1, xmm2/m128 */\n  /* Prefix is filled. */\n  instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX;\n  instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n  return;\n\n  case 3:\n  /* POR xmm1, xmm2/m128 */\n  if (reg_type == SLJIT_SIMD_REG_256)\n    instruction[1] ^= (dst_ind << 3);\n\n  /* Prefix is filled. */\n  instruction[2] = 0xeb;\n  instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n  return;\n  }\n}\n\n/* The AVX2 code path is currently disabled.\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))\n*/\n#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1\n#else\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))\n#endif\n\nstatic void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)\n{\nDEFINE_COMPILER;\nsljit_u8 instruction[8];\n/* The AVX2 code path is currently disabled. */\n/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */\nsljit_s32 reg_type = SLJIT_SIMD_REG_128;\nsljit_s32 value;\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *quit;\nstruct sljit_jump *partial_quit[2];\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 data_ind = sljit_get_register_index(reg_type, SLJIT_VR0);\nsljit_s32 cmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR1);\nsljit_s32 cmp2_ind = sljit_get_register_index(reg_type, SLJIT_VR2);\nsljit_s32 tmp_ind = sljit_get_register_index(reg_type, SLJIT_VR3);\nsljit_u32 bit = 0;\nint i;\n\nSLJIT_UNUSED_ARG(offset);\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\npartial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[0]);\n\n/* First part (unaligned start) */\nvalue = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO;\nsljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit));\n\nif (char1 != char2)\n  sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));\n\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n\nsljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0);\n\nif (char1 != char2)\n  sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf;\nOP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\nfor (i = 0; i < 4; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16;\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value);\n\npartial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[1]);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\nfor (i = 0; i < 4; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\nSLJIT_ASSERT(tmp1_reg_ind < 8);\n/* BSF r32, r/m32 */\ninstruction[0] = 0x0f;\ninstruction[1] = 0xbc;\ninstruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;\nsljit_emit_op_custom(compiler, instruction, 3);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  {\n  JUMPHERE(partial_quit[0]);\n  JUMPHERE(partial_quit[1]);\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n  SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n  }\nelse\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset > 0)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));\n\n  quit = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n  JUMPTO(SLJIT_JUMP, restart);\n\n  JUMPHERE(quit);\n  }\n#endif\n}\n\n/* The AVX2 code path is currently disabled.\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))\n*/\n#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1\n#else\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))\n#endif\n\nstatic jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)\n{\nDEFINE_COMPILER;\nsljit_u8 instruction[8];\n/* The AVX2 code path is currently disabled. */\n/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */\nsljit_s32 reg_type = SLJIT_SIMD_REG_128;\nsljit_s32 value;\nstruct sljit_label *start;\nstruct sljit_jump *quit;\njump_list *not_found = NULL;\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 data_ind = sljit_get_register_index(reg_type, SLJIT_VR0);\nsljit_s32 cmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR1);\nsljit_s32 cmp2_ind = sljit_get_register_index(reg_type, SLJIT_VR2);\nsljit_s32 tmp_ind = sljit_get_register_index(reg_type, SLJIT_VR3);\nsljit_u32 bit = 0;\nint i;\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\nOP1(SLJIT_MOV, TMP2, 0, TMP1, 0);\nOP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n\n/* First part (unaligned start) */\n\nvalue = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO;\nsljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit));\n\nif (char1 != char2)\n  sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));\n\nOP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);\n\nsljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0);\n\nif (char1 != char2)\n  sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf;\nOP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\nfor (i = 0; i < 4; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16;\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value);\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\nfor (i = 0; i < 4; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\nSLJIT_ASSERT(tmp1_reg_ind < 8);\n/* BSF r32, r/m32 */\ninstruction[0] = 0x0f;\ninstruction[1] = 0xbc;\ninstruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;\nsljit_emit_op_custom(compiler, instruction, 3);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\nOP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\nreturn not_found;\n}\n\n#ifndef _WIN64\n\n/* The AVX2 code path is currently disabled.\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))\n*/\n#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1\n#else\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))\n#endif\n\nstatic void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,\n  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)\n{\nDEFINE_COMPILER;\nsljit_u8 instruction[8];\n/* The AVX2 code path is currently disabled. */\n/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */\nsljit_s32 reg_type = SLJIT_SIMD_REG_128;\nsljit_s32 value;\nvector_compare_type compare1_type = vector_compare_match1;\nvector_compare_type compare2_type = vector_compare_match1;\nsljit_u32 bit1 = 0;\nsljit_u32 bit2 = 0;\nsljit_u32 diff = IN_UCHARS(offs1 - offs2);\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 data1_ind = sljit_get_register_index(reg_type, SLJIT_VR0);\nsljit_s32 data2_ind = sljit_get_register_index(reg_type, SLJIT_VR1);\nsljit_s32 cmp1a_ind = sljit_get_register_index(reg_type, SLJIT_VR2);\nsljit_s32 cmp2a_ind = sljit_get_register_index(reg_type, SLJIT_VR3);\nsljit_s32 cmp1b_ind = sljit_get_register_index(reg_type, SLJIT_VR4);\nsljit_s32 cmp2b_ind = sljit_get_register_index(reg_type, SLJIT_VR5);\nsljit_s32 tmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR6);\nsljit_s32 tmp2_ind = sljit_get_register_index(reg_type, SLJIT_TMP_DEST_VREG);\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *jump[2];\nint i;\n\nSLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2 && offs2 >= 0);\nSLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset()));\n\n/* Initialize. */\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));\n\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);\n  SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END);\n  }\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nif (char1a == char1b)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));\nelse\n  {\n  bit1 = char1a ^ char1b;\n  if (is_powerof2(bit1))\n    {\n    compare1_type = vector_compare_match1i;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));\n    }\n  else\n    {\n    compare1_type = vector_compare_match2;\n    bit1 = 0;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));\n    }\n  }\n\nvalue = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO;\nsljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, TMP1, 0);\n\nif (char1a != char1b)\n  sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR4, 0, TMP2, 0);\n\nif (char2a == char2b)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));\nelse\n  {\n  bit2 = char2a ^ char2b;\n  if (is_powerof2(bit2))\n    {\n    compare2_type = vector_compare_match1i;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));\n    }\n  else\n    {\n    compare2_type = vector_compare_match2;\n    bit2 = 0;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));\n    }\n  }\n\nsljit_emit_simd_lane_mov(compiler, value, SLJIT_VR3, 0, TMP1, 0);\n\nif (char2a != char2b)\n  sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR5, 0, TMP2, 0);\n\nsljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0);\nif (char1a != char1b)\n  sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR4, SLJIT_VR4, 0);\n\nsljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR3, SLJIT_VR3, 0);\nif (char2a != char2b)\n  sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR5, SLJIT_VR5, 0);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? ~0x1f : ~0xf;\nOP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\njump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);\n\nsljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);\njump[1] = JUMP(SLJIT_JUMP);\n\nJUMPHERE(jump[0]);\n\nif (reg_type == SLJIT_SIMD_REG_256)\n  {\n  if (diff != 16)\n    {\n    /* PSLLDQ ymm1, ymm2, imm8 */\n    instruction[0] = 0xc5;\n    instruction[1] = (sljit_u8)(0xf9 ^ (data2_ind << 3));\n    instruction[2] = 0x73;\n    instruction[3] = 0xc0 | (7 << 3) | data1_ind;\n    instruction[4] = diff & 0xf;\n    sljit_emit_op_custom(compiler, instruction, 5);\n    }\n\n  instruction[0] = 0xc4;\n  instruction[1] = 0xe3;\n  if (diff < 16)\n    {\n    /* VINSERTI128 xmm1, xmm2, xmm3/m128 */\n    /* instruction[0] = 0xc4; */\n    /* instruction[1] = 0xe3; */\n    instruction[2] = (sljit_u8)(0x7d ^ (data2_ind << 3));\n    instruction[3] = 0x38;\n    SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR) <= 7);\n    instruction[4] = 0x40 | (data2_ind << 3) | sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\n    instruction[5] = (sljit_u8)(16 - diff);\n    instruction[6] = 1;\n    sljit_emit_op_custom(compiler, instruction, 7);\n    }\n  else\n    {\n    /* VPERM2I128 xmm1, xmm2, xmm3/m128 */\n    /* instruction[0] = 0xc4; */\n    /* instruction[1] = 0xe3; */\n    value = (diff == 16) ? data1_ind : data2_ind;\n    instruction[2] = (sljit_u8)(0x7d ^ (value << 3));\n    instruction[3] = 0x46;\n    instruction[4] = 0xc0 | (data2_ind << 3) | value;\n    instruction[5] = 0x08;\n    sljit_emit_op_custom(compiler, instruction, 6);\n    }\n  }\nelse\n  {\n  /* MOVDQA xmm1, xmm2/m128 */\n  instruction[0] = 0x66;\n  instruction[1] = 0x0f;\n  instruction[2] = 0x6f;\n  instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;\n  sljit_emit_op_custom(compiler, instruction, 4);\n\n  /* PSLLDQ xmm1, imm8 */\n  /* instruction[0] = 0x66; */\n  /* instruction[1] = 0x0f; */\n  instruction[2] = 0x73;\n  instruction[3] = 0xc0 | (7 << 3) | data2_ind;\n  instruction[4] = diff;\n  sljit_emit_op_custom(compiler, instruction, 5);\n  }\n\nJUMPHERE(jump[1]);\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf;\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value);\n\nfor (i = 0; i < 4; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  }\n\nsljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\n\n/* Ignore matches before the first STR_PTR. */\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\njump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Main loop. */\nstart = LABEL();\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16;\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value);\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nvalue = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128;\nsljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\nsljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);\n\nfor (i = 0; i < 4; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  }\n\nsljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);\nsljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0);\n\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(jump[0]);\n\nSLJIT_ASSERT(tmp1_reg_ind < 8);\n/* BSF r32, r/m32 */\ninstruction[0] = 0x0f;\ninstruction[1] = 0xbc;\ninstruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;\nsljit_emit_op_custom(compiler, instruction, 3);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));\n\n  jump[0] = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);\n\n  add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));\n\n  JUMPHERE(jump[0]);\n  }\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\n#endif /* !_WIN64 */\n\n#undef SIMD_COMPARE_TYPE_INDEX\n\n#endif /* SLJIT_CONFIG_X86 */\n\n#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__))\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_8)\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_16)\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32)\n#else\n#error \"Unsupported unit width\"\n#endif\n\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1\n\nstatic void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,\n  int step, sljit_u32 dst_ind, sljit_u32 cmp1_ind, sljit_u32 cmp2_ind, sljit_u32 tmp_ind)\n{\nsljit_u32 instruction;\n#if PCRE2_CODE_UNIT_WIDTH == 8\nsljit_u32 size = 0 << 22;\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nsljit_u32 size = 1 << 22;\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nsljit_u32 size = 2 << 22;\n#else\n#error \"Unsupported unit width\"\n#endif\n\nSLJIT_ASSERT(step >= 0 && step <= 2);\n\nif (step == 1)\n  {\n  /* CMEQ */\n  instruction = 0x6e208c00 | size | (cmp1_ind << 16) | (dst_ind << 5) | dst_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n  return;\n  }\n\nif (compare_type != vector_compare_match2)\n  {\n  if (step == 0 && compare_type == vector_compare_match1i)\n    {\n    /* ORR */\n    instruction = 0x4ea01c00 | (cmp2_ind << 16) | (dst_ind << 5) | dst_ind;\n    sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n    }\n  return;\n  }\n\nswitch (step)\n  {\n  case 0:\n  /* CMEQ */\n  instruction = 0x6e208c00 | size | (cmp2_ind << 16) | (dst_ind << 5) | tmp_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n  return;\n\n  case 2:\n  /* ORR */\n  instruction = 0x4ea01c00 | (tmp_ind << 16) | (dst_ind << 5) | dst_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n  return;\n  }\n}\n\nstatic void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)\n{\nDEFINE_COMPILER;\nsljit_u32 instruction;\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *quit;\nstruct sljit_jump *partial_quit[2];\nvector_compare_type compare_type = vector_compare_match1;\nsljit_u32 data_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);\nsljit_u32 cmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);\nsljit_u32 cmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);\nsljit_u32 tmp_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);\nsljit_u32 bit = 0;\nint i;\n\nSLJIT_UNUSED_ARG(offset);\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\npartial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[0]);\n\n/* First part (unaligned start) */\nif (char1 != char2)\n  sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit != 0 ? bit : char2);\nsljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);\n\nif (char1 != char2)\n  sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP2, 0);\nsljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR1, TMP1, 0);\n\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nOP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~(sljit_sw)0xf);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\nfor (i = 0; i < 3; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data_ind << 5) | data_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\n\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\n\npartial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[1]);\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\nfor (i = 0; i < 3; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data_ind << 5) | data_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\nsljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  {\n  JUMPHERE(partial_quit[0]);\n  JUMPHERE(partial_quit[1]);\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n  SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n  }\nelse\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset > 0)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));\n\n  quit = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n  JUMPTO(SLJIT_JUMP, restart);\n\n  JUMPHERE(quit);\n  }\n#endif\n}\n\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1\n\nstatic jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)\n{\nDEFINE_COMPILER;\nsljit_u32 instruction;\nstruct sljit_label *start;\nstruct sljit_jump *quit;\njump_list *not_found = NULL;\nvector_compare_type compare_type = vector_compare_match1;\nsljit_u32 data_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);\nsljit_u32 cmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);\nsljit_u32 cmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);\nsljit_u32 tmp_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);\nsljit_u32 bit = 0;\nint i;\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\n/* First part (unaligned start) */\n\nif (char1 != char2)\n  sljit_emit_op1(compiler, SLJIT_MOV, TMP3, 0, SLJIT_IMM, bit != 0 ? bit : char2);\nsljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, char1 | bit);\n\nif (char1 != char2)\n  sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP3, 0);\nsljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR1, TMP2, 0);\n\nOP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, ~(sljit_sw)0xf);\nOP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf);\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(TMP3), 0);\n\nfor (i = 0; i < 3; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data_ind << 5) | data_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\n\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 16);\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP3, 0, STR_END, 0));\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(TMP3), 0);\n\nfor (i = 0; i < 3; i++)\n  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data_ind << 5) | data_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\nsljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\nreturn not_found;\n}\n\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1\n\nstatic void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,\n  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)\n{\nDEFINE_COMPILER;\nsljit_u32 instruction;\nvector_compare_type compare1_type = vector_compare_match1;\nvector_compare_type compare2_type = vector_compare_match1;\nsljit_u32 bit1 = 0;\nsljit_u32 bit2 = 0;\nsljit_u32 diff = IN_UCHARS(offs1 - offs2);\nsljit_u32 data1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);\nsljit_u32 data2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);\nsljit_u32 cmp1a_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);\nsljit_u32 cmp2a_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);\nsljit_u32 cmp1b_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR4);\nsljit_u32 cmp2b_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR5);\nsljit_u32 tmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR6);\nsljit_u32 tmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR7);\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *jump[2];\nint i;\n\nSLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2 && offs2 >= 0);\nSLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset()));\n\nif (char1a != char1b)\n  {\n  bit1 = char1a ^ char1b;\n  compare1_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit1))\n    {\n    bit1 = 0;\n    compare1_type = vector_compare_match2;\n    }\n  }\n\nif (char2a != char2b)\n  {\n  bit2 = char2a ^ char2b;\n  compare2_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit2))\n    {\n    bit2 = 0;\n    compare2_type = vector_compare_match2;\n    }\n  }\n\n/* Initialize. */\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));\n\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);\n  SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END);\n  }\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nsljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a | bit1);\nsljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, char2a | bit2);\nsljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP1, 0);\nsljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR3, TMP2, 0);\n\nif (char1a != char1b)\n  sljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit1 != 0 ? bit1 : char1b);\n\nif (char2a != char2b)\n  sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit2 != 0 ? bit2 : char2b);\n\nif (char1a != char1b)\n  sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR4, TMP1, 0);\n\nif (char2a != char2b)\n  sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR5, TMP2, 0);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\nOP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~(sljit_sw)0xf);\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\n\njump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);\njump[1] = JUMP(SLJIT_JUMP);\n\nJUMPHERE(jump[0]);\n\nif (diff >= 8)\n  {\n  /* MOV (element) */\n  instruction = 0x6e180400 | (data1_ind << 5) | data2_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\n  if (diff > 8)\n    {\n    /* SHL */\n    instruction = 0x4f405400 | ((diff - 8) << 19) | (data2_ind << 5) | data2_ind;\n    sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n    }\n  }\nelse\n  {\n  /* MOV (element) */\n  instruction = 0x6e180400 | (data1_ind << 5) | tmp1_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\n  /* SHL */\n  instruction = 0x4f405400 | (diff << 19) | (data1_ind << 5) | data2_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\n  /* USHR */\n  instruction = 0x6f400400 | (diff << 19) | (tmp1_ind << 5) | tmp1_ind;\n  sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\n  sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_OR | SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_VR1, SLJIT_VR6, 0);\n  }\n\nJUMPHERE(jump[1]);\n\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);\n\nfor (i = 0; i < 3; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  }\n\nsljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | SLJIT_SIMD_REG_128, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data1_ind << 5) | data1_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\n\n/* Ignore matches before the first STR_PTR. */\nOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\nOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);\n\njump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\n/* Main loop. */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);\nsljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);\n\nfor (i = 0; i < 3; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  }\n\nsljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | SLJIT_SIMD_REG_128, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);\n\n/* SHRN */\ninstruction = 0x0f0c8400 | (data1_ind << 5) | data1_ind;\nsljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));\n\nsljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);\n\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(jump[0]);\n\nsljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));\n\n  jump[0] = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);\n\n  add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));\n\n  JUMPHERE(jump[0]);\n  }\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\n#undef PCRE2_REPLICATE_TYPE\n\n#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */\n\n#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define VECTOR_ELEMENT_SIZE 0\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define VECTOR_ELEMENT_SIZE 1\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n#define VECTOR_ELEMENT_SIZE 2\n#else\n#error \"Unsupported unit width\"\n#endif\n\nstatic void load_from_mem_vector(struct sljit_compiler *compiler, BOOL vlbb, sljit_s32 dst_vreg,\n  sljit_s32 base_reg, sljit_s32 index_reg)\n{\nsljit_u16 instruction[3];\n\ninstruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | index_reg);\ninstruction[1] = (sljit_u16)(base_reg << 12);\ninstruction[2] = (sljit_u16)((0x8 << 8) | (vlbb ? 0x07 : 0x06));\n\nsljit_emit_op_custom(compiler, instruction, 6);\n}\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n\nstatic void replicate_imm_vector(struct sljit_compiler *compiler, int step, sljit_s32 dst_vreg,\n  PCRE2_UCHAR chr, sljit_s32 tmp_general_reg)\n{\nsljit_u16 instruction[3];\n\nSLJIT_ASSERT(step >= 0 && step <= 1);\n\nif (chr < 0x7fff)\n  {\n  if (step == 1)\n    return;\n\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4));\n  instruction[1] = (sljit_u16)chr;\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  return;\n  }\n\nif (step == 0)\n  {\n  OP1(SLJIT_MOV, tmp_general_reg, 0, SLJIT_IMM, chr);\n\n  /* VLVG */\n  instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(SLJIT_GP_REGISTER, tmp_general_reg));\n  instruction[1] = 0;\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x22);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  return;\n  }\n\n/* VREP */\ninstruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | dst_vreg);\ninstruction[1] = 0;\ninstruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xc << 8) | 0x4d);\nsljit_emit_op_custom(compiler, instruction, 6);\n}\n\n#endif\n\nstatic void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,\n  int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)\n{\nsljit_u16 instruction[3];\n\nSLJIT_ASSERT(step >= 0 && step <= 2);\n\nif (step == 1)\n  {\n  /* VCEQ */\n  instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);\n  instruction[1] = (sljit_u16)(cmp1_ind << 12);\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0xf8);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  return;\n  }\n\nif (compare_type != vector_compare_match2)\n  {\n  if (step == 0 && compare_type == vector_compare_match1i)\n    {\n    /* VO */\n    instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);\n    instruction[1] = (sljit_u16)(cmp2_ind << 12);\n    instruction[2] = (sljit_u16)((0xe << 8) | 0x6a);\n    sljit_emit_op_custom(compiler, instruction, 6);\n    }\n  return;\n  }\n\nswitch (step)\n  {\n  case 0:\n  /* VCEQ */\n  instruction[0] = (sljit_u16)(0xe700 | (tmp_ind << 4) | dst_ind);\n  instruction[1] = (sljit_u16)(cmp2_ind << 12);\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0xf8);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  return;\n\n  case 2:\n  /* VO */\n  instruction[0] = (sljit_u16)(0xe700 | (dst_ind << 4) | dst_ind);\n  instruction[1] = (sljit_u16)(tmp_ind << 12);\n  instruction[2] = (sljit_u16)((0xe << 8) | 0x6a);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  return;\n  }\n}\n\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1\n\nstatic void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)\n{\nDEFINE_COMPILER;\nsljit_u16 instruction[3];\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *quit;\nstruct sljit_jump *partial_quit[2];\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\nsljit_s32 data_ind = 0;\nsljit_s32 tmp_ind = 1;\nsljit_s32 cmp1_ind = 2;\nsljit_s32 cmp2_ind = 3;\nsljit_s32 zero_ind = 4;\nsljit_u32 bit = 0;\nint i;\n\nSLJIT_UNUSED_ARG(offset);\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\npartial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[0]);\n\n/* First part (unaligned start) */\n\nOP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 16);\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n\n/* VREPI */\ninstruction[0] = (sljit_u16)(0xe700 | (cmp1_ind << 4));\ninstruction[1] = (sljit_u16)(char1 | bit);\ninstruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nif (char1 != char2)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (cmp2_ind << 4));\n  instruction[1] = (sljit_u16)(bit != 0 ? bit : char2);\n  /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n#else /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\nfor (i = 0; i < 2; i++)\n  {\n  replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP1);\n\n  if (char1 != char2)\n    replicate_imm_vector(compiler, i, cmp2_ind, bit != 0 ? bit : char2, TMP1);\n  }\n\n#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\nif (compare_type == vector_compare_match2)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));\n  instruction[1] = 0;\n  instruction[2] = (sljit_u16)((0x8 << 8) | 0x45);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nload_from_mem_vector(compiler, TRUE, data_ind, str_ptr_reg_ind, 0);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, ~15);\n\nif (compare_type != vector_compare_match2)\n  {\n  if (compare_type == vector_compare_match1i)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFEE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\nelse\n  {\n  for (i = 0; i < 3; i++)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFENE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((0xe << 8) | 0x81);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\nquit = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, TMP2, 0, SLJIT_IMM, 16);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\n\npartial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[1]);\n\nload_from_mem_vector(compiler, TRUE, data_ind, str_ptr_reg_ind, 0);\n\nif (compare_type != vector_compare_match2)\n  {\n  if (compare_type == vector_compare_match1i)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFEE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\nelse\n  {\n  for (i = 0; i < 3; i++)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFENE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((0xe << 8) | 0x81);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\nsljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);\nJUMPTO(SLJIT_OVERFLOW, start);\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nJUMPHERE(quit);\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  {\n  JUMPHERE(partial_quit[0]);\n  JUMPHERE(partial_quit[1]);\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n  SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n  }\nelse\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset > 0)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));\n\n  quit = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n  OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 16);\n  JUMPTO(SLJIT_JUMP, restart);\n\n  JUMPHERE(quit);\n  }\n#endif\n}\n\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1\n\nstatic jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)\n{\nDEFINE_COMPILER;\nsljit_u16 instruction[3];\nstruct sljit_label *start;\nstruct sljit_jump *quit;\njump_list *not_found = NULL;\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 tmp3_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP3);\nsljit_s32 data_ind = 0;\nsljit_s32 tmp_ind = 1;\nsljit_s32 cmp1_ind = 2;\nsljit_s32 cmp2_ind = 3;\nsljit_s32 zero_ind = 4;\nsljit_u32 bit = 0;\nint i;\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\n/* First part (unaligned start) */\n\nOP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, 16);\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n\n/* VREPI */\ninstruction[0] = (sljit_u16)(0xe700 | (cmp1_ind << 4));\ninstruction[1] = (sljit_u16)(char1 | bit);\ninstruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nif (char1 != char2)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (cmp2_ind << 4));\n  instruction[1] = (sljit_u16)(bit != 0 ? bit : char2);\n  /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n#else /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\nfor (i = 0; i < 2; i++)\n  {\n  replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP3);\n\n  if (char1 != char2)\n    replicate_imm_vector(compiler, i, cmp2_ind, bit != 0 ? bit : char2, TMP3);\n  }\n\n#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\nif (compare_type == vector_compare_match2)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));\n  instruction[1] = 0;\n  instruction[2] = (sljit_u16)((0x8 << 8) | 0x45);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\nload_from_mem_vector(compiler, TRUE, data_ind, tmp1_reg_ind, 0);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, ~15);\n\nif (compare_type != vector_compare_match2)\n  {\n  if (compare_type == vector_compare_match1i)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFEE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\nelse\n  {\n  for (i = 0; i < 3; i++)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFENE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((0xe << 8) | 0x81);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp3_reg_ind << 4) | data_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);\nquit = CMP(SLJIT_LESS, TMP1, 0, TMP2, 0);\n\nOP2(SLJIT_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 16);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 16);\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\nload_from_mem_vector(compiler, TRUE, data_ind, tmp1_reg_ind, 0);\n\nif (compare_type != vector_compare_match2)\n  {\n  if (compare_type == vector_compare_match1i)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, 0, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFEE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((cmp1_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0xe << 8) | 0x80);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\nelse\n  {\n  for (i = 0; i < 3; i++)\n    fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n  /* VFENE */\n  instruction[0] = (sljit_u16)(0xe700 | (data_ind << 4) | data_ind);\n  instruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\n  instruction[2] = (sljit_u16)((0xe << 8) | 0x81);\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\nsljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);\nJUMPTO(SLJIT_OVERFLOW, start);\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp3_reg_ind << 4) | data_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);\n\nJUMPHERE(quit);\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\nreturn not_found;\n}\n\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1\n\nstatic void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,\n  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)\n{\nDEFINE_COMPILER;\nsljit_u16 instruction[3];\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *quit;\nstruct sljit_jump *jump[2];\nvector_compare_type compare1_type = vector_compare_match1;\nvector_compare_type compare2_type = vector_compare_match1;\nsljit_u32 bit1 = 0;\nsljit_u32 bit2 = 0;\nsljit_s32 diff = IN_UCHARS(offs2 - offs1);\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2);\nsljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\nsljit_s32 data1_ind = 0;\nsljit_s32 data2_ind = 1;\nsljit_s32 tmp1_ind = 2;\nsljit_s32 tmp2_ind = 3;\nsljit_s32 cmp1a_ind = 4;\nsljit_s32 cmp1b_ind = 5;\nsljit_s32 cmp2a_ind = 6;\nsljit_s32 cmp2b_ind = 7;\nsljit_s32 zero_ind = 8;\nint i;\n\nSLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);\nSLJIT_ASSERT(-diff <= (sljit_s32)IN_UCHARS(max_fast_forward_char_pair_offset()));\nSLJIT_ASSERT(tmp1_reg_ind != 0 && tmp2_reg_ind != 0);\n\nif (char1a != char1b)\n  {\n  bit1 = char1a ^ char1b;\n  compare1_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit1))\n    {\n    bit1 = 0;\n    compare1_type = vector_compare_match2;\n    }\n  }\n\nif (char2a != char2b)\n  {\n  bit2 = char2a ^ char2b;\n  compare2_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit2))\n    {\n    bit2 = 0;\n    compare2_type = vector_compare_match2;\n    }\n  }\n\n/* Initialize. */\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));\n\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);\n  SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END);\n  }\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\nOP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, ~15);\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);\n\n/* VREPI */\ninstruction[0] = (sljit_u16)(0xe700 | (cmp1a_ind << 4));\ninstruction[1] = (sljit_u16)(char1a | bit1);\ninstruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nif (char1a != char1b)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (cmp1b_ind << 4));\n  instruction[1] = (sljit_u16)(bit1 != 0 ? bit1 : char1b);\n  /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n/* VREPI */\ninstruction[0] = (sljit_u16)(0xe700 | (cmp2a_ind << 4));\ninstruction[1] = (sljit_u16)(char2a | bit2);\n/* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */\nsljit_emit_op_custom(compiler, instruction, 6);\n\nif (char2a != char2b)\n  {\n  /* VREPI */\n  instruction[0] = (sljit_u16)(0xe700 | (cmp2b_ind << 4));\n  instruction[1] = (sljit_u16)(bit2 != 0 ? bit2 : char2b);\n  /* instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x45); */\n  sljit_emit_op_custom(compiler, instruction, 6);\n  }\n\n#else /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\nfor (i = 0; i < 2; i++)\n  {\n  replicate_imm_vector(compiler, i, cmp1a_ind, char1a | bit1, TMP1);\n\n  if (char1a != char1b)\n    replicate_imm_vector(compiler, i, cmp1b_ind, bit1 != 0 ? bit1 : char1b, TMP1);\n\n  replicate_imm_vector(compiler, i, cmp2a_ind, char2a | bit2, TMP1);\n\n  if (char2a != char2b)\n    replicate_imm_vector(compiler, i, cmp2b_ind, bit2 != 0 ? bit2 : char2b, TMP1);\n  }\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);\n\n#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n/* VREPI */\ninstruction[0] = (sljit_u16)(0xe700 | (zero_ind << 4));\ninstruction[1] = 0;\ninstruction[2] = (sljit_u16)((0x8 << 8) | 0x45);\nsljit_emit_op_custom(compiler, instruction, 6);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\njump[0] = CMP(SLJIT_LESS, TMP1, 0, TMP2, 0);\nload_from_mem_vector(compiler, TRUE, data2_ind, tmp1_reg_ind, 0);\njump[1] = JUMP(SLJIT_JUMP);\nJUMPHERE(jump[0]);\nload_from_mem_vector(compiler, FALSE, data2_ind, tmp1_reg_ind, 0);\nJUMPHERE(jump[1]);\n\nload_from_mem_vector(compiler, TRUE, data1_ind, str_ptr_reg_ind, 0);\nOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);\n\nfor (i = 0; i < 3; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  }\n\n/* VN */\ninstruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);\ninstruction[1] = (sljit_u16)(data2_ind << 12);\ninstruction[2] = (sljit_u16)((0xe << 8) | 0x68);\nsljit_emit_op_custom(compiler, instruction, 6);\n\n/* VFENE */\ninstruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);\ninstruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\ninstruction[2] = (sljit_u16)((0xe << 8) | 0x81);\nsljit_emit_op_custom(compiler, instruction, 6);\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp1_reg_ind << 4) | data1_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\nquit = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, TMP2, 0, SLJIT_IMM, 16);\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, diff);\n\n/* Main loop. */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nload_from_mem_vector(compiler, FALSE, data1_ind, str_ptr_reg_ind, 0);\nload_from_mem_vector(compiler, FALSE, data2_ind, str_ptr_reg_ind, tmp1_reg_ind);\n\nfor (i = 0; i < 3; i++)\n  {\n  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\n  }\n\n/* VN */\ninstruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);\ninstruction[1] = (sljit_u16)(data2_ind << 12);\ninstruction[2] = (sljit_u16)((0xe << 8) | 0x68);\nsljit_emit_op_custom(compiler, instruction, 6);\n\n/* VFENE */\ninstruction[0] = (sljit_u16)(0xe700 | (data1_ind << 4) | data1_ind);\ninstruction[1] = (sljit_u16)((zero_ind << 12) | (1 << 4));\ninstruction[2] = (sljit_u16)((0xe << 8) | 0x81);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nsljit_set_current_flags(compiler, SLJIT_SET_OVERFLOW);\nJUMPTO(SLJIT_OVERFLOW, start);\n\n/* VLGVB */\ninstruction[0] = (sljit_u16)(0xe700 | (tmp2_reg_ind << 4) | data1_ind);\ninstruction[1] = 7;\ninstruction[2] = (sljit_u16)((0x4 << 8) | 0x21);\nsljit_emit_op_custom(compiler, instruction, 6);\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\nJUMPHERE(quit);\n\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));\n\n  quit = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n  /* TMP1 contains diff. */\n  OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, ~15);\n  OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, -diff);\n  JUMPTO(SLJIT_JUMP, restart);\n\n  JUMPHERE(quit);\n  }\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\n#endif /* SLJIT_CONFIG_S390X */\n\n#if (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)\n\n#ifdef __linux__\n/* Using getauxval(AT_HWCAP) under Linux for detecting whether LSX is available */\n#include <sys/auxv.h>\n#define LOONGARCH_HWCAP_LSX  (1 << 4)\n#define HAS_LSX_SUPPORT ((getauxval(AT_HWCAP) & LOONGARCH_HWCAP_LSX) != 0)\n#else\n#define HAS_LSX_SUPPORT 0\n#endif\n\ntypedef sljit_ins sljit_u32;\n\n#define SI12_IMM_MASK   0x003ffc00\n#define UI5_IMM_MASK    0x00007c00\n#define UI2_IMM_MASK    0x00000c00\n\n#define VD(vd)      ((sljit_ins)vd << 0)\n#define VJ(vj)      ((sljit_ins)vj << 5)\n#define VK(vk)      ((sljit_ins)vk << 10)\n#define RD_V(rd)    ((sljit_ins)rd << 0)\n#define RJ_V(rj)    ((sljit_ins)rj << 5)\n\n#define IMM_SI12(imm)   (((sljit_ins)(imm) << 10) & SI12_IMM_MASK)\n#define IMM_UI5(imm)    (((sljit_ins)(imm) << 10) & UI5_IMM_MASK)\n#define IMM_UI2(imm)    (((sljit_ins)(imm) << 10) & UI2_IMM_MASK)\n\n// LSX OPCODES:\n#define VBSLL_V       0x728e0000\n#define VMSKLTZ_B     0x729c4000\n#define VPICKVE2GR_WU 0x72f3e000\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#define VREPLGR2VR_X  0x729f0000\n#define VSEQ        0x70000000\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n#define VREPLGR2VR_X  0x729f0400\n#define VSEQ        0x70008000\n#else\n#define VREPLGR2VR_X  0x729f0800\n#define VSEQ        0x70010000\n#endif\n\nstatic void fast_forward_char_pair_lsx_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,\n  sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)\n{\nif (compare_type != vector_compare_match2)\n  {\n  if (compare_type == vector_compare_match1i)\n    {\n    /* VOR.V vd, vj, vk */\n    push_inst(compiler, VOR_V | VD(dst_ind) | VJ(cmp2_ind) | VK(dst_ind));\n    }\n\n  /* VSEQ.B/H/W vd, vj, vk */\n  push_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind));\n  return;\n  }\n\n/* VBSLL.V vd, vj, ui5 */\npush_inst(compiler, VBSLL_V | VD(tmp_ind) | VJ(dst_ind) | IMM_UI5(0));\n\n/* VSEQ.B/H/W vd, vj, vk */\npush_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind));\n\n/* VSEQ.B/H/W vd, vj, vk */\npush_inst(compiler, VSEQ | VD(tmp_ind) | VJ(tmp_ind) | VK(cmp2_ind));\n\n/* VOR vd, vj, vk */\npush_inst(compiler, VOR_V | VD(dst_ind) | VJ(tmp_ind) | VK(dst_ind));\nreturn;\n}\n\n#define JIT_HAS_FAST_FORWARD_CHAR_SIMD HAS_LSX_SUPPORT\n\nstatic void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)\n{\nDEFINE_COMPILER;\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *quit;\nstruct sljit_jump *partial_quit[2];\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\nsljit_s32 data_ind = 0;\nsljit_s32 tmp_ind = 1;\nsljit_s32 cmp1_ind = 2;\nsljit_s32 cmp2_ind = 3;\nsljit_u32 bit = 0;\n\nSLJIT_UNUSED_ARG(offset);\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\npartial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[0]);\n\n/* First part (unaligned start) */\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);\n\n/* VREPLGR2VR.B/H/W vd, rj */\npush_inst(compiler, VREPLGR2VR_X | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));\n\nif (char1 != char2)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2);\n\n  /* VREPLGR2VR.B/H/W vd, rj */\n  push_inst(compiler, VREPLGR2VR_X | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));\n  }\n\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\nfast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0));\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\n\npartial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);\nif (common->mode == PCRE2_JIT_COMPLETE)\n  add_jump(compiler, &common->failed_match, partial_quit[1]);\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\nfast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0));\n\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\n/* CTZ.W rd, rj */\npush_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind));\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nif (common->mode != PCRE2_JIT_COMPLETE)\n  {\n  JUMPHERE(partial_quit[0]);\n  JUMPHERE(partial_quit[1]);\n  OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);\n  SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);\n  }\nelse\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf && offset > 0)\n  {\n  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);\n\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));\n\n  quit = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n  OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\n  JUMPTO(SLJIT_JUMP, restart);\n\n  JUMPHERE(quit);\n  }\n#endif\n}\n\n#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD HAS_LSX_SUPPORT\n\nstatic jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)\n{\nDEFINE_COMPILER;\nstruct sljit_label *start;\nstruct sljit_jump *quit;\njump_list *not_found = NULL;\nvector_compare_type compare_type = vector_compare_match1;\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\nsljit_s32 data_ind = 0;\nsljit_s32 tmp_ind = 1;\nsljit_s32 cmp1_ind = 2;\nsljit_s32 cmp2_ind = 3;\nsljit_u32 bit = 0;\n\nif (char1 != char2)\n  {\n  bit = char1 ^ char2;\n  compare_type = vector_compare_match1i;\n\n  if (!is_powerof2(bit))\n    {\n    bit = 0;\n    compare_type = vector_compare_match2;\n    }\n  }\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\nOP1(SLJIT_MOV, TMP2, 0, TMP1, 0);\nOP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);\n\n/* First part (unaligned start) */\n\nOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);\n\n/* VREPLGR2VR.B/H/W vd, rj */\npush_inst(compiler, VREPLGR2VR_X | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));\n\nif (char1 != char2)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2);\n  /* VREPLGR2VR.B/H/W vd, rj */\n  push_inst(compiler, VREPLGR2VR_X | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));\n  }\n\nOP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\nfast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0));\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\nquit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Second part (aligned) */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\n\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\nfast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind);\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0));\n\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(quit);\n\n/* CTZ.W rd, rj */\npush_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind));\n\nOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);\nadd_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));\n\nOP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);\nreturn not_found;\n}\n\n#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD HAS_LSX_SUPPORT\n\nstatic void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,\n  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)\n{\nDEFINE_COMPILER;\nvector_compare_type compare1_type = vector_compare_match1;\nvector_compare_type compare2_type = vector_compare_match1;\nsljit_u32 bit1 = 0;\nsljit_u32 bit2 = 0;\nsljit_u32 diff = IN_UCHARS(offs1 - offs2);\nsljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);\nsljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2);\nsljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR);\nsljit_s32 data1_ind = 0;\nsljit_s32 data2_ind = 1;\nsljit_s32 tmp1_ind = 2;\nsljit_s32 tmp2_ind = 3;\nsljit_s32 cmp1a_ind = 4;\nsljit_s32 cmp1b_ind = 5;\nsljit_s32 cmp2a_ind = 6;\nsljit_s32 cmp2b_ind = 7;\nstruct sljit_label *start;\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nstruct sljit_label *restart;\n#endif\nstruct sljit_jump *jump[2];\n\nSLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);\nSLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset()));\n\n/* Initialize. */\nif (common->match_end_ptr != 0)\n  {\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);\n  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));\n  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);\n\n  OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);\n  SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END);\n  }\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\nif (char1a == char1b)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a);\nelse\n  {\n  bit1 = char1a ^ char1b;\n  if (is_powerof2(bit1))\n    {\n    compare1_type = vector_compare_match1i;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a | bit1);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit1);\n    }\n  else\n    {\n    compare1_type = vector_compare_match2;\n    bit1 = 0;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char1b);\n    }\n  }\n\n/* VREPLGR2VR.B/H/W vd, rj */\npush_inst(compiler, VREPLGR2VR_X | VD(cmp1a_ind) | RJ_V(tmp1_reg_ind));\n\nif (char1a != char1b)\n  {\n  /* VREPLGR2VR.B/H/W vd, rj */\n  push_inst(compiler, VREPLGR2VR_X | VD(cmp1b_ind) | RJ_V(tmp2_reg_ind));\n  }\n\nif (char2a == char2b)\n  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a);\nelse\n  {\n  bit2 = char2a ^ char2b;\n  if (is_powerof2(bit2))\n    {\n    compare2_type = vector_compare_match1i;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a | bit2);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit2);\n    }\n  else\n    {\n    compare2_type = vector_compare_match2;\n    bit2 = 0;\n    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a);\n    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char2b);\n    }\n  }\n\n/* VREPLGR2VR.B/H/W vd, rj */\npush_inst(compiler, VREPLGR2VR_X | VD(cmp2a_ind) | RJ_V(tmp1_reg_ind));\n\nif (char2a != char2b)\n  {\n  /* VREPLGR2VR.B/H/W vd, rj */\n  push_inst(compiler, VREPLGR2VR_X | VD(cmp2b_ind) | RJ_V(tmp2_reg_ind));\n  }\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nrestart = LABEL();\n#endif\n\nOP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);\nOP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);\nOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\n\njump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff));\njump[1] = JUMP(SLJIT_JUMP);\n\nJUMPHERE(jump[0]);\n\n/* VBSLL.V vd, vj, ui5 */\npush_inst(compiler, VBSLL_V | VD(data2_ind) | VJ(data1_ind) | IMM_UI5(diff));\n\nJUMPHERE(jump[1]);\n\nfast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);\nfast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);\n\n/* VAND vd, vj, vk */\npush_inst(compiler, VOR_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind));\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0));\n\n/* Ignore matches before the first STR_PTR. */\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\nOP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);\n\njump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);\n\n/* Main loop. */\nstart = LABEL();\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n/* VLD vd, rj, si12 */\npush_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0));\npush_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff));\n\nfast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind);\nfast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind);\n\n/* VAND.V vd, vj, vk */\npush_inst(compiler, VAND_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind));\n\n/* VMSKLTZ.B vd, vj */\npush_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind));\n\n/* VPICKVE2GR.WU rd, vj, ui2 */\npush_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0));\n\nCMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);\n\nJUMPHERE(jump[0]);\n\n/* CTZ.W rd, rj */\npush_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind));\n\nOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);\n\nadd_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32\nif (common->utf)\n  {\n  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));\n\n  jump[0] = jump_if_utf_char_start(compiler, TMP1);\n\n  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));\n  CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);\n\n  add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));\n\n  JUMPHERE(jump[0]);\n  }\n#endif\n\nOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));\n\nif (common->match_end_ptr != 0)\n  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);\n}\n\n#endif /* SLJIT_CONFIG_LOONGARCH_64 */\n\n#endif /* !SUPPORT_VALGRIND */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_maketables.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains the external function pcre2_maketables(), which builds\ncharacter tables for PCRE2 in the current locale. The file is compiled on its\nown as part of the PCRE2 library. It is also included in the compilation of\npcre2_dftables.c as a freestanding program, in which case the macro\nPCRE2_DFTABLES is defined. */\n\n\n#ifndef PCRE2_DFTABLES    /* Compiling the library */\n#include \"pcre2_internal.h\"\n#endif\n\n\n\n/*************************************************\n*           Create PCRE2 character tables        *\n*************************************************/\n\n/* This function builds a set of character tables for use by PCRE2 and returns\na pointer to them. They are build using the ctype functions, and consequently\ntheir contents will depend upon the current locale setting. When compiled as\npart of the library, the store is obtained via a general context malloc, if\nsupplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables\nfreestanding auxiliary program) malloc() is used, and the function has a\ndifferent name so as not to clash with the prototype in pcre2.h.\n\nArguments:   pointers to character-transforming functions when PCRE2_DFTABLES is\n             defined;\n               else a PCRE2 general context or NULL\nReturns:     pointer to the contiguous block of data;\n               else NULL if memory allocation failed\n*/\n\n#ifdef PCRE2_DFTABLES  /* Included in freestanding pcre2_dftables program */\nstatic const uint8_t *maketables(int (*charfn_to)(int), int (*charfn_from)(int))\n{\nuint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);\n\n#else  /* Not PCRE2_DFTABLES, that is, compiling the library */\nPCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION\npcre2_maketables(pcre2_general_context *gcontext)\n{\nuint8_t *yield = (uint8_t *)((gcontext != NULL)?\n  gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :\n  malloc(TABLES_LENGTH));\n\n#define charfn_to(c)    (c)\n#define charfn_from(c)  (c)\n#endif  /* PCRE2_DFTABLES */\n\nint i;\nuint8_t *p;\n\nif (yield == NULL) return NULL;\np = yield;\n\n/* First comes the lower casing table */\n\nfor (i = 0; i < 256; i++)\n  {\n  int c = charfn_from(tolower(charfn_to(i)));\n  *p++ = (c < 256)? c : i;\n  }\n\n/* Next the case-flipping table */\n\nfor (i = 0; i < 256; i++)\n  {\n  int c = charfn_from(islower(charfn_to(i))? toupper(charfn_to(i))\n                                           : tolower(charfn_to(i)));\n  *p++ = (c < 256)? c : i;\n  }\n\n/* Then the character class tables. Don't try to be clever and save effort on\nexclusive ones - in some locales things may be different.\n\nNote that the table for \"space\" includes everything \"isspace\" gives, including\nVT in the default locale. This makes it work for the POSIX class [:space:].\nFrom PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl\nspace, because Perl added VT at release 5.18.\n\nNote also that it is possible for a character to be alnum or alpha without\nbeing lower or upper, such as \"male and female ordinals\" (\\xAA and \\xBA) in the\nfr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must\ntest for alnum specially. */\n\nmemset(p, 0, cbit_length);\nfor (i = 0; i < 256; i++)\n  {\n  if (isdigit(charfn_to(i)))  p[cbit_digit  + i/8] |= 1u << (i&7);\n  if (isupper(charfn_to(i)))  p[cbit_upper  + i/8] |= 1u << (i&7);\n  if (islower(charfn_to(i)))  p[cbit_lower  + i/8] |= 1u << (i&7);\n  if (isalnum(charfn_to(i)))  p[cbit_word   + i/8] |= 1u << (i&7);\n  if (i == CHAR_UNDERSCORE)   p[cbit_word   + i/8] |= 1u << (i&7);\n  if (isspace(charfn_to(i)))  p[cbit_space  + i/8] |= 1u << (i&7);\n  if (isxdigit(charfn_to(i))) p[cbit_xdigit + i/8] |= 1u << (i&7);\n  if (isgraph(charfn_to(i)))  p[cbit_graph  + i/8] |= 1u << (i&7);\n  if (isprint(charfn_to(i)))  p[cbit_print  + i/8] |= 1u << (i&7);\n  if (ispunct(charfn_to(i)))  p[cbit_punct  + i/8] |= 1u << (i&7);\n  if (iscntrl(charfn_to(i)))  p[cbit_cntrl  + i/8] |= 1u << (i&7);\n  }\np += cbit_length;\n\n/* Finally, the character type table. In this, we used to exclude VT from the\nwhite space chars, because Perl didn't recognize it as such for \\s and for\ncomments within regexes. However, Perl changed at release 5.18, so PCRE1\nchanged at release 8.34 and it's always been this way for PCRE2. */\n\nfor (i = 0; i < 256; i++)\n  {\n  int x = 0;\n  if (isspace(charfn_to(i))) x += ctype_space;\n  if (isalpha(charfn_to(i))) x += ctype_letter;\n  if (islower(charfn_to(i))) x += ctype_lcletter;\n  if (isdigit(charfn_to(i))) x += ctype_digit;\n  if (isalnum(charfn_to(i)) || i == CHAR_UNDERSCORE) x += ctype_word;\n  *p++ = x;\n  }\n\nreturn yield;\n}\n\n#ifndef PCRE2_DFTABLES   /* Compiling the library */\n#undef charfn_to\n#undef charfn_from\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)\n{\nif (gcontext != NULL)\n  gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data);\nelse\n  free((void *)tables);\n}\n#endif\n\n/* End of pcre2_maketables.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_match.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2015-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* These defines enable debugging code */\n\n/* #define DEBUG_FRAMES_DISPLAY */\n/* #define DEBUG_SHOW_OPS */\n/* #define DEBUG_SHOW_RMATCH */\n\n#ifdef DEBUG_FRAMES_DISPLAY\n#include <stdarg.h>\n#endif\n\n#ifdef DEBUG_SHOW_OPS\nstatic const char *OP_names[] = { OP_NAME_LIST };\n#endif\n\n/* These defines identify the name of the block containing \"static\"\ninformation, and fields within it. */\n\n#define NLBLOCK mb              /* Block containing newline information */\n#define PSSTART start_subject   /* Field containing processed string start */\n#define PSEND   end_subject     /* Field containing processed string end */\n\n#define RECURSE_UNSET 0xffffffffu  /* Bigger than max group number */\n\n/* Masks for identifying the public options that are permitted at match time. */\n\n#define PUBLIC_MATCH_OPTIONS \\\n  (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \\\n   PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \\\n   PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT| \\\n   PCRE2_DISABLE_RECURSELOOP_CHECK)\n\n#define PUBLIC_JIT_MATCH_OPTIONS \\\n   (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\\\n    PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD|\\\n    PCRE2_COPY_MATCHED_SUBJECT)\n\n/* Non-error returns from and within the match() function. Error returns are\nexternally defined PCRE2_ERROR_xxx codes, which are all negative. */\n\n#define MATCH_MATCH        1\n#define MATCH_NOMATCH      0\n\n/* Special internal returns used in the match() function. Make them\nsufficiently negative to avoid the external error codes. */\n\n#define MATCH_ACCEPT       (-999)\n#define MATCH_KETRPOS      (-998)\n/* The next 5 must be kept together and in sequence so that a test that checks\nfor any one of them can use a range. */\n#define MATCH_COMMIT       (-997)\n#define MATCH_PRUNE        (-996)\n#define MATCH_SKIP         (-995)\n#define MATCH_SKIP_ARG     (-994)\n#define MATCH_THEN         (-993)\n#define MATCH_BACKTRACK_MAX MATCH_THEN\n#define MATCH_BACKTRACK_MIN MATCH_COMMIT\n\n/* Group frame type values. Zero means the frame is not a group frame. The\nlower 16 bits are used for data (e.g. the capture number). Group frames are\nused for most groups so that information about the start is easily available at\nthe end without having to scan back through intermediate frames (backtrack\npoints). */\n\n#define GF_CAPTURE     0x00010000u\n#define GF_NOCAPTURE   0x00020000u\n#define GF_CONDASSERT  0x00030000u\n#define GF_RECURSE     0x00040000u\n\n/* Masks for the identity and data parts of the group frame type. */\n\n#define GF_IDMASK(a)   ((a) & 0xffff0000u)\n#define GF_DATAMASK(a) ((a) & 0x0000ffffu)\n\n/* Repetition types */\n\nenum { REPTYPE_MIN, REPTYPE_MAX, REPTYPE_POS };\n\n/* Min and max values for the common repeats; a maximum of UINT32_MAX =>\ninfinity. */\n\nstatic const uint32_t rep_min[] = {\n  0, 0,       /* * and *? */\n  1, 1,       /* + and +? */\n  0, 0,       /* ? and ?? */\n  0, 0,       /* dummy placefillers for OP_CR[MIN]RANGE */\n  0, 1, 0 };  /* OP_CRPOS{STAR, PLUS, QUERY} */\n\nstatic const uint32_t rep_max[] = {\n  UINT32_MAX, UINT32_MAX,      /* * and *? */\n  UINT32_MAX, UINT32_MAX,      /* + and +? */\n  1, 1,                        /* ? and ?? */\n  0, 0,                        /* dummy placefillers for OP_CR[MIN]RANGE */\n  UINT32_MAX, UINT32_MAX, 1 }; /* OP_CRPOS{STAR, PLUS, QUERY} */\n\n/* Repetition types - must include OP_CRPOSRANGE (not needed above) */\n\nstatic const uint32_t rep_typ[] = {\n  REPTYPE_MAX, REPTYPE_MIN,    /* * and *? */\n  REPTYPE_MAX, REPTYPE_MIN,    /* + and +? */\n  REPTYPE_MAX, REPTYPE_MIN,    /* ? and ?? */\n  REPTYPE_MAX, REPTYPE_MIN,    /* OP_CRRANGE and OP_CRMINRANGE */\n  REPTYPE_POS, REPTYPE_POS,    /* OP_CRPOSSTAR, OP_CRPOSPLUS */\n  REPTYPE_POS, REPTYPE_POS };  /* OP_CRPOSQUERY, OP_CRPOSRANGE */\n\n/* Numbers for RMATCH calls at backtracking points. When these lists are\nchanged, the code at RETURN_SWITCH below must be updated in sync.  */\n\nenum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,\n       RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,\n       RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,\n       RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39 };\n\n#ifdef SUPPORT_WIDE_CHARS\nenum { RM100=100, RM101, RM102, RM103 };\n#endif\n\n#ifdef SUPPORT_UNICODE\nenum { RM200=200, RM201, RM202, RM203, RM204, RM205, RM206, RM207,\n       RM208,     RM209, RM210, RM211, RM212, RM213, RM214, RM215,\n       RM216,     RM217, RM218, RM219, RM220, RM221, RM222, RM223,\n       RM224 };\n#endif\n\n/* Define short names for general fields in the current backtrack frame, which\nis always pointed to by the F variable. Occasional references to fields in\nother frames are written out explicitly. There are also some fields in the\ncurrent frame whose names start with \"temp\" that are used for short-term,\nlocalised backtracking memory. These are #defined with Lxxx names at the point\nof use and undefined afterwards. */\n\n#define Fback_frame        F->back_frame\n#define Fcapture_last      F->capture_last\n#define Fcurrent_recurse   F->current_recurse\n#define Fecode             F->ecode\n#define Feptr              F->eptr\n#define Fgroup_frame_type  F->group_frame_type\n#define Flast_group_offset F->last_group_offset\n#define Flength            F->length\n#define Fmark              F->mark\n#define Frdepth            F->rdepth\n#define Fstart_match       F->start_match\n#define Foffset_top        F->offset_top\n#define Foccu              F->occu\n#define Fop                F->op\n#define Fovector           F->ovector\n#define Freturn_id         F->return_id\n\n\n#ifdef DEBUG_FRAMES_DISPLAY\n/*************************************************\n*      Display current frames and contents       *\n*************************************************/\n\n/* This debugging function displays the current set of frames and their\ncontents. It is not called automatically from anywhere, the intention being\nthat calls can be inserted where necessary when debugging frame-related\nproblems.\n\nArguments:\n  f           the file to write to\n  F           the current top frame\n  P           a previous frame of interest\n  frame_size  the frame size\n  mb          points to the match block\n  match_data  points to the match data block\n  s           identification text\n\nReturns:    nothing\n*/\n\nstatic void\ndisplay_frames(FILE *f, heapframe *F, heapframe *P, PCRE2_SIZE frame_size,\n  match_block *mb, pcre2_match_data *match_data, const char *s, ...)\n{\nuint32_t i;\nheapframe *Q;\nva_list ap;\nva_start(ap, s);\n\nfprintf(f, \"FRAMES \");\nvfprintf(f, s, ap);\nva_end(ap);\n\nif (P != NULL) fprintf(f, \" P=%lu\",\n  ((char *)P - (char *)(match_data->heapframes))/frame_size);\nfprintf(f, \"\\n\");\n\nfor (i = 0, Q = match_data->heapframes;\n     Q <= F;\n     i++, Q = (heapframe *)((char *)Q + frame_size))\n  {\n  fprintf(f, \"Frame %d type=%x subj=%lu code=%d back=%lu id=%d\",\n    i, Q->group_frame_type, Q->eptr - mb->start_subject, *(Q->ecode),\n    Q->back_frame, Q->return_id);\n\n  if (Q->last_group_offset == PCRE2_UNSET)\n    fprintf(f, \" lgoffset=unset\\n\");\n  else\n    fprintf(f, \" lgoffset=%lu\\n\",  Q->last_group_offset/frame_size);\n  }\n}\n\n#endif\n\n\n\n/*************************************************\n*                Process a callout               *\n*************************************************/\n\n/* This function is called for all callouts, whether \"standalone\" or at the\nstart of a conditional group. Feptr will be pointing to either OP_CALLOUT or\nOP_CALLOUT_STR. A callout block is allocated in pcre2_match() and initialized\nwith fixed values.\n\nArguments:\n  F          points to the current backtracking frame\n  mb         points to the match block\n  lengthptr  where to return the length of the callout item\n\nReturns:     the return from the callout\n             or 0 if no callout function exists\n*/\n\nstatic int\ndo_callout(heapframe *F, match_block *mb, PCRE2_SIZE *lengthptr)\n{\nint rc;\nPCRE2_SIZE save0, save1;\nPCRE2_SIZE *callout_ovector;\npcre2_callout_block *cb;\n\n*lengthptr = (*Fecode == OP_CALLOUT)?\n  PRIV(OP_lengths)[OP_CALLOUT] : GET(Fecode, 1 + 2*LINK_SIZE);\n\nif (mb->callout == NULL) return 0;   /* No callout function provided */\n\n/* The original matching code (pre 10.30) worked directly with the ovector\npassed by the user, and this was passed to callouts. Now that the working\novector is in the backtracking frame, it no longer needs to reserve space for\nthe overall match offsets (which would waste space in the frame). For backward\ncompatibility, however, we pass capture_top and offset_vector to the callout as\nif for the extended ovector, and we ensure that the first two slots are unset\nby preserving and restoring their current contents. Picky compilers complain if\nreferences such as Fovector[-2] are use directly, so we set up a separate\npointer. */\n\ncallout_ovector = (PCRE2_SIZE *)(Fovector) - 2;\n\n/* The cb->version, cb->subject, cb->subject_length, and cb->start_match fields\nare set externally. The first 3 never change; the last is updated for each\nbumpalong. */\n\ncb = mb->cb;\ncb->capture_top      = (uint32_t)Foffset_top/2 + 1;\ncb->capture_last     = Fcapture_last;\ncb->offset_vector    = callout_ovector;\ncb->mark             = mb->nomatch_mark;\ncb->current_position = (PCRE2_SIZE)(Feptr - mb->start_subject);\ncb->pattern_position = GET(Fecode, 1);\ncb->next_item_length = GET(Fecode, 1 + LINK_SIZE);\n\nif (*Fecode == OP_CALLOUT)  /* Numerical callout */\n  {\n  cb->callout_number = Fecode[1 + 2*LINK_SIZE];\n  cb->callout_string_offset = 0;\n  cb->callout_string = NULL;\n  cb->callout_string_length = 0;\n  }\nelse  /* String callout */\n  {\n  cb->callout_number = 0;\n  cb->callout_string_offset = GET(Fecode, 1 + 3*LINK_SIZE);\n  cb->callout_string = Fecode + (1 + 4*LINK_SIZE) + 1;\n  cb->callout_string_length =\n    *lengthptr - (1 + 4*LINK_SIZE) - 2;\n  }\n\nsave0 = callout_ovector[0];\nsave1 = callout_ovector[1];\ncallout_ovector[0] = callout_ovector[1] = PCRE2_UNSET;\nrc = mb->callout(cb, mb->callout_data);\ncallout_ovector[0] = save0;\ncallout_ovector[1] = save1;\ncb->callout_flags = 0;\nreturn rc;\n}\n\n\n\n/*************************************************\n*          Match a back-reference                *\n*************************************************/\n\n/* This function is called only when it is known that the offset lies within\nthe offsets that have so far been used in the match. Note that in caseless\nUTF-8 mode, the number of subject bytes matched may be different to the number\nof reference bytes. (In theory this could also happen in UTF-16 mode, but it\nseems unlikely.)\n\nArguments:\n  offset      index into the offset vector\n  caseless    TRUE if caseless\n  caseopts    bitmask of REFI_FLAG_XYZ values\n  F           the current backtracking frame pointer\n  mb          points to match block\n  lengthptr   pointer for returning the length matched\n\nReturns:      = 0 sucessful match; number of code units matched is set\n              < 0 no match\n              > 0 partial match\n*/\n\nstatic int\nmatch_ref(PCRE2_SIZE offset, BOOL caseless, int caseopts, heapframe *F,\n  match_block *mb, PCRE2_SIZE *lengthptr)\n{\nPCRE2_SPTR p;\nPCRE2_SIZE length;\nPCRE2_SPTR eptr;\nPCRE2_SPTR eptr_start;\n\n#ifndef SUPPORT_UNICODE\n(void)caseopts; /* Avoid compiler warning. */\n#endif\n\n/* Deal with an unset group. The default is no match, but there is an option to\nmatch an empty string. */\n\nif (offset >= Foffset_top || Fovector[offset] == PCRE2_UNSET)\n  {\n  if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)\n    {\n    *lengthptr = 0;\n    return 0;      /* Match */\n    }\n  else return -1;  /* No match */\n  }\n\n/* Separate the caseless and UTF cases for speed. */\n\neptr = eptr_start = Feptr;\np = mb->start_subject + Fovector[offset];\nlength = Fovector[offset+1] - Fovector[offset];\nPCRE2_ASSERT(eptr <= mb->end_subject);\n\nif (caseless)\n  {\n#if defined SUPPORT_UNICODE\n  BOOL utf = (mb->poptions & PCRE2_UTF) != 0;\n  BOOL caseless_restrict = (caseopts & REFI_FLAG_CASELESS_RESTRICT) != 0;\n  BOOL turkish_casing = !caseless_restrict && (caseopts & REFI_FLAG_TURKISH_CASING) != 0;\n\n  if (utf || (mb->poptions & PCRE2_UCP) != 0)\n    {\n    PCRE2_SPTR endptr = p + length;\n\n    /* Match characters up to the end of the reference. NOTE: the number of\n    code units matched may differ, because in UTF-8 there are some characters\n    whose upper and lower case codes have different numbers of bytes. For\n    example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 (3\n    bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a\n    sequence of two of the latter. It is important, therefore, to check the\n    length along the reference, not along the subject (earlier code did this\n    wrong). UCP uses Unicode properties but without UTF encoding. */\n\n    while (p < endptr)\n      {\n      uint32_t c, d;\n      const ucd_record *ur;\n      if (eptr >= mb->end_subject) return 1;   /* Partial match */\n\n      if (utf)\n        {\n        GETCHARINC(c, eptr);\n        GETCHARINC(d, p);\n        }\n      else\n        {\n        c = *eptr++;\n        d = *p++;\n        }\n\n      if (turkish_casing && UCD_ANY_I(d))\n        {\n        c = UCD_FOLD_I_TURKISH(c);\n        d = UCD_FOLD_I_TURKISH(d);\n        if (c != d) return -1;  /* No match */\n        }\n      else if (c != d && c != (uint32_t)((int)d + (ur = GET_UCD(d))->other_case))\n        {\n        const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset;\n\n        /* When PCRE2_EXTRA_CASELESS_RESTRICT is set, ignore any caseless sets\n        that start with an ASCII character. */\n        if (caseless_restrict && *pp < 128) return -1;  /* No match */\n\n        for (;;)\n          {\n          if (c < *pp) return -1;  /* No match */\n          if (c == *pp++) break;\n          }\n        }\n      }\n    }\n  else\n#endif\n\n  /* Not in UTF or UCP mode */\n    {\n    for (; length > 0; length--)\n      {\n      uint32_t cc, cp;\n      if (eptr >= mb->end_subject) return 1;   /* Partial match */\n      cc = UCHAR21TEST(eptr);\n      cp = UCHAR21TEST(p);\n      if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc))\n        return -1;  /* No match */\n      p++;\n      eptr++;\n      }\n    }\n  }\n\n/* In the caseful case, we can just compare the code units, whether or not we\nare in UTF and/or UCP mode. When partial matching, we have to do this unit by\nunit. */\n\nelse\n  {\n  if (mb->partial != 0)\n    {\n    for (; length > 0; length--)\n      {\n      if (eptr >= mb->end_subject) return 1;   /* Partial match */\n      if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1;  /* No match */\n      }\n    }\n\n  /* Not partial matching */\n\n  else\n    {\n    if ((PCRE2_SIZE)(mb->end_subject - eptr) < length ||\n        memcmp(p, eptr, CU2BYTES(length)) != 0) return -1;  /* No match */\n    eptr += length;\n    }\n  }\n\n*lengthptr = eptr - eptr_start;\nreturn 0;  /* Match */\n}\n\n\n\n/*************************************************\n*     Restore offsets after a recurse            *\n*************************************************/\n\n/* This function restores the ovector values when\na recursive block reaches its end, and the triggering\nrecurse has and argument list.\n\nArguments:\n  F           the current backtracking frame pointer\n  P           the previous backtracking frame pointer\n*/\n\nstatic void\nrecurse_update_offsets(heapframe *F, heapframe *P)\n{\nPCRE2_SIZE *dst = F->ovector;\nPCRE2_SIZE *src = P->ovector;\n/* The first bracket has offset 2, because\noffset 0 is reserved for the full match. */\nPCRE2_SIZE offset = 2;\nPCRE2_SIZE offset_top = Foffset_top + 2;\nPCRE2_SIZE diff;\nPCRE2_SPTR ecode = Fecode;\n\ndo\n  {\n  diff = (GET2(ecode, 1) << 1) - offset;\n  ecode += 1 + IMM2_SIZE;\n\n  if (offset + diff >= offset_top)\n    {\n    /* Some OP_CREF opcodes are not\n    processed, they must be skipped. */\n    while (*ecode == OP_CREF) ecode += 1 + IMM2_SIZE;\n    break;\n    }\n\n  if (diff == 2)\n    {\n    dst[0] = src[0];\n    dst[1] = src[1];\n    }\n  else if (diff >= 4)\n    memcpy(dst, src, diff * sizeof(PCRE2_SIZE));\n\n  /* Skip the unmodified entry. */\n  diff += 2;\n  offset += diff;\n  dst += diff;\n  src += diff;\n  }\nwhile (*ecode == OP_CREF);\n\ndiff = offset_top - offset;\nif (diff == 2)\n  {\n  dst[0] = src[0];\n  dst[1] = src[1];\n  }\nelse if (diff >= 4)\n  memcpy(dst, src, diff * sizeof(PCRE2_SIZE));\n\nFecode = ecode;\nFoffset_top = (offset <= P->offset_top) ? P->offset_top : (offset - 2);\n}\n\n\n\n/******************************************************************************\n*******************************************************************************\n                   \"Recursion\" in the match() function\n\nThe original match() function was highly recursive, but this proved to be the\nsource of a number of problems over the years, mostly because of the relatively\nsmall system stacks that are commonly found. As new features were added to\npatterns, various kludges were invented to reduce the amount of stack used,\nmaking the code hard to understand in places.\n\nA version did exist that used individual frames on the heap instead of calling\nmatch() recursively, but this ran substantially slower. The current version is\na refactoring that uses a vector of frames to remember backtracking points.\nThis runs no slower, and possibly even a bit faster than the original recursive\nimplementation.\n\nAt first, an initial vector of size START_FRAMES_SIZE (enough for maybe 50\nframes) was allocated on the system stack. If this was not big enough, the heap\nwas used for a larger vector. However, it turns out that there are environments\nwhere taking as little as 20KiB from the system stack is an embarrassment.\nAfter another refactoring, the heap is used exclusively, but a pointer the\nframes vector and its size are cached in the match_data block, so that there is\nno new memory allocation if the same match_data block is used for multiple\nmatches (unless the frames vector has to be extended).\n*******************************************************************************\n******************************************************************************/\n\n\n\n\n/*************************************************\n*       Macros for the match() function          *\n*************************************************/\n\n/* These macros pack up tests that are used for partial matching several times\nin the code. The second one is used when we already know we are past the end of\nthe subject. We set the \"hit end\" flag if the pointer is at the end of the\nsubject and either (a) the pointer is past the earliest inspected character\n(i.e. something has been matched, even if not part of the actual matched\nstring), or (b) the pattern contains a lookbehind. These are the conditions for\nwhich adding more characters may allow the current match to continue.\n\nFor hard partial matching, we immediately return a partial match. Otherwise,\ncarrying on means that a complete match on the current subject will be sought.\nA partial match is returned only if no complete match can be found. */\n\n#define CHECK_PARTIAL() \\\n  do { \\\n     if (Feptr >= mb->end_subject) \\\n       { \\\n       SCHECK_PARTIAL(); \\\n       } \\\n     } \\\n  while (0)\n\n#define SCHECK_PARTIAL() \\\n  do { \\\n     if (mb->partial != 0 && \\\n         (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \\\n       { \\\n       mb->hitend = TRUE; \\\n       if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \\\n       } \\\n     } \\\n  while (0)\n\n\n/* These macros are used to implement backtracking. They simulate a recursive\ncall to the match() function by means of a local vector of frames which\nremember the backtracking points. */\n\n#define RMATCH(ra,rb) \\\n  do { \\\n     start_ecode = ra; \\\n     Freturn_id = rb; \\\n     goto MATCH_RECURSE; \\\n     L_##rb:; \\\n     } \\\n  while (0)\n\n#define RRETURN(ra) \\\n  do { \\\n     rrc = ra; \\\n     goto RETURN_SWITCH; \\\n     } \\\n  while (0)\n\n\n\n/*************************************************\n*         Match from current position            *\n*************************************************/\n\n/* This function is called to run one match attempt at a single starting point\nin the subject.\n\nPerformance note: It might be tempting to extract commonly used fields from the\nmb structure (e.g. end_subject) into individual variables to improve\nperformance. Tests using gcc on a SPARC disproved this; in the first case, it\nmade performance worse.\n\nArguments:\n   start_eptr   starting character in subject\n   start_ecode  starting position in compiled code\n   top_bracket  number of capturing parentheses in the pattern\n   frame_size   size of each backtracking frame\n   match_data   pointer to the match_data block\n   mb           pointer to \"static\" variables block\n\nReturns:        MATCH_MATCH if matched            )  these values are >= 0\n                MATCH_NOMATCH if failed to match  )\n                negative MATCH_xxx value for PRUNE, SKIP, etc\n                negative PCRE2_ERROR_xxx value if aborted by an error condition\n                (e.g. stopped by repeated call or depth limit)\n*/\n\nstatic int\nmatch(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, uint16_t top_bracket,\n  PCRE2_SIZE frame_size, pcre2_match_data *match_data, match_block *mb)\n{\n/* Frame-handling variables */\n\nheapframe *F;           /* Current frame pointer */\nheapframe *N = NULL;    /* Temporary frame pointers */\nheapframe *P = NULL;\n\nheapframe *frames_top;  /* End of frames vector */\nheapframe *assert_accept_frame = NULL;  /* For passing back a frame with captures */\nPCRE2_SIZE frame_copy_size;   /* Amount to copy when creating a new frame */\n\n/* Local variables that do not need to be preserved over calls to RRMATCH(). */\n\nPCRE2_SPTR branch_end = NULL;\nPCRE2_SPTR branch_start;\nPCRE2_SPTR bracode;     /* Temp pointer to start of group */\nPCRE2_SIZE offset;      /* Used for group offsets */\nPCRE2_SIZE length;      /* Used for various length calculations */\n\nint rrc;                /* Return from functions & backtracking \"recursions\" */\n#ifdef SUPPORT_UNICODE\nint proptype;           /* Type of character property */\n#endif\n\nuint32_t i;             /* Used for local loops */\nuint32_t fc;            /* Character values */\nuint32_t number;        /* Used for group and other numbers */\nuint32_t reptype = 0;   /* Type of repetition (0 to avoid compiler warning) */\nuint32_t group_frame_type;  /* Specifies type for new group frames */\n\nBOOL condition;         /* Used in conditional groups */\nBOOL cur_is_word;       /* Used in \"word\" tests */\nBOOL prev_is_word;      /* Used in \"word\" tests */\n\n/* UTF and UCP flags */\n\n#ifdef SUPPORT_UNICODE\nBOOL utf = (mb->poptions & PCRE2_UTF) != 0;\nBOOL ucp = (mb->poptions & PCRE2_UCP) != 0;\n#else\nBOOL utf = FALSE;  /* Required for convenience even when no Unicode support */\n#endif\n\n/* This is the length of the last part of a backtracking frame that must be\ncopied when a new frame is created. */\n\nframe_copy_size = frame_size - offsetof(heapframe, eptr);\n\n/* Set up the first frame and the end of the frames vector. */\n\nF = match_data->heapframes;\nframes_top = (heapframe *)((char *)F + match_data->heapframes_size);\n\nFrdepth = 0;                        /* \"Recursion\" depth */\nFcapture_last = 0;                  /* Number of most recent capture */\nFcurrent_recurse = RECURSE_UNSET;   /* Not pattern recursing. */\nFstart_match = Feptr = start_eptr;  /* Current data pointer and start match */\nFmark = NULL;                       /* Most recent mark */\nFoffset_top = 0;                    /* End of captures within the frame */\nFlast_group_offset = PCRE2_UNSET;   /* Saved frame of most recent group */\ngroup_frame_type = 0;               /* Not a start of group frame */\ngoto NEW_FRAME;                     /* Start processing with this frame */\n\n/* Come back here when we want to create a new frame for remembering a\nbacktracking point. */\n\nMATCH_RECURSE:\n\n/* Set up a new backtracking frame. If the vector is full, get a new one,\ndoubling the size, but constrained by the heap limit (which is in KiB). */\n\nN = (heapframe *)((char *)F + frame_size);\nif ((heapframe *)((char *)N + frame_size) >= frames_top)\n  {\n  heapframe *new;\n  PCRE2_SIZE newsize;\n  PCRE2_SIZE usedsize = (char *)N - (char *)(match_data->heapframes);\n\n  if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2)\n    {\n    if (match_data->heapframes_size == PCRE2_SIZE_MAX - 1)\n      return PCRE2_ERROR_NOMEMORY;\n    newsize = PCRE2_SIZE_MAX - 1;\n    }\n  else\n    newsize = match_data->heapframes_size * 2;\n\n  if (newsize / 1024 >= mb->heap_limit)\n    {\n    PCRE2_SIZE old_size = match_data->heapframes_size / 1024;\n    if (mb->heap_limit <= old_size)\n      return PCRE2_ERROR_HEAPLIMIT;\n    else\n      {\n      PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size);\n      int over_bytes = match_data->heapframes_size % 1024;\n      if (over_bytes) max_delta -= (1024 - over_bytes);\n      newsize = match_data->heapframes_size + max_delta;\n      }\n    }\n\n  /* With a heap limit set, the permitted additional size may not be enough for\n  another frame, so do a final check. */\n\n  if (newsize - usedsize < frame_size) return PCRE2_ERROR_HEAPLIMIT;\n  new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data);\n  if (new == NULL) return PCRE2_ERROR_NOMEMORY;\n  memcpy(new, match_data->heapframes, usedsize);\n\n  N = (heapframe *)((char *)new + usedsize);\n  F = (heapframe *)((char *)N - frame_size);\n\n  match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data);\n  match_data->heapframes = new;\n  match_data->heapframes_size = newsize;\n  frames_top = (heapframe *)((char *)new + newsize);\n  }\n\n#ifdef DEBUG_SHOW_RMATCH\nfprintf(stderr, \"++ RMATCH %d frame=%d\", Freturn_id, Frdepth + 1);\nif (group_frame_type != 0)\n  {\n  fprintf(stderr, \" type=%x \", group_frame_type);\n  switch (GF_IDMASK(group_frame_type))\n    {\n    case GF_CAPTURE:\n    fprintf(stderr, \"capture=%d\", GF_DATAMASK(group_frame_type));\n    break;\n\n    case GF_NOCAPTURE:\n    fprintf(stderr, \"nocapture op=%d\", GF_DATAMASK(group_frame_type));\n    break;\n\n    case GF_CONDASSERT:\n    fprintf(stderr, \"condassert op=%d\", GF_DATAMASK(group_frame_type));\n    break;\n\n    case GF_RECURSE:\n    fprintf(stderr, \"recurse=%d\", GF_DATAMASK(group_frame_type));\n    break;\n\n    default:\n    fprintf(stderr, \"*** unknown ***\");\n    break;\n    }\n  }\nfprintf(stderr, \"\\n\");\n#endif\n\n/* Copy those fields that must be copied into the new frame, increase the\n\"recursion\" depth (i.e. the new frame's index) and then make the new frame\ncurrent. */\n\nmemcpy((char *)N + offsetof(heapframe, eptr),\n       (char *)F + offsetof(heapframe, eptr),\n       frame_copy_size);\n\nN->rdepth = Frdepth + 1;\nF = N;\n\n/* Carry on processing with a new frame. */\n\nNEW_FRAME:\nFgroup_frame_type = group_frame_type;\nFecode = start_ecode;      /* Starting code pointer */\nFback_frame = frame_size;  /* Default is go back one frame */\n\n/* If this is a special type of group frame, remember its offset for quick\naccess at the end of the group. If this is a recursion, set a new current\nrecursion value. */\n\nif (group_frame_type != 0)\n  {\n  Flast_group_offset = (char *)F - (char *)match_data->heapframes;\n  if (GF_IDMASK(group_frame_type) == GF_RECURSE)\n    Fcurrent_recurse = GF_DATAMASK(group_frame_type);\n  group_frame_type = 0;\n  }\n\n\n/* ========================================================================= */\n/* This is the main processing loop. First check that we haven't recorded too\nmany backtracks (search tree is too large), or that we haven't exceeded the\nrecursive depth limit (used too many backtracking frames). If not, process the\nopcodes. */\n\nif (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;\nif (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;\n\n#ifdef DEBUG_SHOW_OPS\nfprintf(stderr, \"\\n++ New frame: type=0x%x subject offset %ld\\n\",\n  GF_IDMASK(Fgroup_frame_type), Feptr - mb->start_subject);\n#endif\n\nfor (;;)\n  {\n#ifdef DEBUG_SHOW_OPS\nfprintf(stderr, \"++ %2ld op=%3d %s\\n\", Fecode - mb->start_code, *Fecode,\n  OP_names[*Fecode]);\n#endif\n\n  Fop = (uint8_t)(*Fecode);  /* Cast needed for 16-bit and 32-bit modes */\n  switch(Fop)\n    {\n    /* ===================================================================== */\n    /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, to close\n    any currently open capturing brackets. Unlike reaching the end of a group,\n    where we know the starting frame is at the top of the chained frames, in\n    this case we have to search back for the relevant frame in case other types\n    of group that use chained frames have intervened. Multiple OP_CLOSEs always\n    come innermost first, which matches the chain order. We can ignore this in\n    a recursion, because captures are not passed out of recursions. */\n\n    case OP_CLOSE:\n    if (Fcurrent_recurse == RECURSE_UNSET)\n      {\n      number = GET2(Fecode, 1);\n      offset = Flast_group_offset;\n      for(;;)\n        {\n        /* Corrupted heapframes?. Trigger an assert and return an error */\n        PCRE2_ASSERT(offset != PCRE2_UNSET);\n        if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;\n\n        N = (heapframe *)((char *)match_data->heapframes + offset);\n        P = (heapframe *)((char *)N - frame_size);\n        if (N->group_frame_type == (GF_CAPTURE | number)) break;\n        offset = P->last_group_offset;\n        }\n      offset = (number << 1) - 2;\n      Fcapture_last = number;\n      Fovector[offset] = P->eptr - mb->start_subject;\n      Fovector[offset+1] = Feptr - mb->start_subject;\n      if (offset >= Foffset_top) Foffset_top = offset + 2;\n      }\n    Fecode += PRIV(OP_lengths)[*Fecode];\n    break;\n\n\n    /* ===================================================================== */\n    /* Real or forced end of the pattern, assertion, or recursion. In an\n    assertion ACCEPT, update the last used pointer and remember the current\n    frame so that the captures and mark can be fished out of it. */\n\n    case OP_ASSERT_ACCEPT:\n    if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;\n    assert_accept_frame = F;\n    RRETURN(MATCH_ACCEPT);\n\n    /* For ACCEPT within a recursion, we have to find the most recent\n    recursion. If not in a recursion, fall through to code that is common with\n    OP_END. */\n\n    case OP_ACCEPT:\n    if (Fcurrent_recurse != RECURSE_UNSET)\n      {\n#ifdef DEBUG_SHOW_OPS\n      fprintf(stderr, \"++ Accept within recursion\\n\");\n#endif\n      offset = Flast_group_offset;\n      for(;;)\n        {\n        /* Corrupted heapframes?. Trigger an assert and return an error */\n        PCRE2_ASSERT(offset != PCRE2_UNSET);\n        if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;\n\n        N = (heapframe *)((char *)match_data->heapframes + offset);\n        P = (heapframe *)((char *)N - frame_size);\n        if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break;\n        offset = P->last_group_offset;\n        }\n\n      /* N is now the frame of the recursion; the previous frame is at the\n      OP_RECURSE position. Go back there, copying the current subject position\n      and mark, and the start_match position (\\K might have changed it), and\n      then move on past the OP_RECURSE. */\n\n      P->eptr = Feptr;\n      P->mark = Fmark;\n      P->start_match = Fstart_match;\n      F = P;\n      Fecode += 1 + LINK_SIZE;\n      continue;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* OP_END itself can never be reached within a recursion because that is\n    picked up when the OP_KET that always precedes OP_END is reached. */\n\n    case OP_END:\n\n    /* Fail for an empty string match if either PCRE2_NOTEMPTY is set, or if\n    PCRE2_NOTEMPTY_ATSTART is set and we have matched at the start of the\n    subject. In both cases, backtracking will then try other alternatives, if\n    any. */\n\n    if (Feptr == Fstart_match &&\n         ((mb->moptions & PCRE2_NOTEMPTY) != 0 ||\n           ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&\n             Fstart_match == mb->start_subject + mb->start_offset)))\n      {\n#ifdef DEBUG_SHOW_OPS\n      fprintf(stderr, \"++ Backtrack because empty string\\n\");\n#endif\n      RRETURN(MATCH_NOMATCH);\n      }\n\n    /* Fail if PCRE2_ENDANCHORED is set and the end of the match is not\n    the end of the subject. After (*ACCEPT) we fail the entire match (at this\n    position) but backtrack if we've reached the end of the pattern. This\n    applies whether or not we are in a recursion. */\n\n    if (Feptr < mb->end_subject &&\n        ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)\n      {\n      if (Fop == OP_END)\n        {\n#ifdef DEBUG_SHOW_OPS\n        fprintf(stderr, \"++ Backtrack because not at end (endanchored set)\\n\");\n#endif\n        RRETURN(MATCH_NOMATCH);\n        }\n\n#ifdef DEBUG_SHOW_OPS\n      fprintf(stderr, \"++ Failed ACCEPT not at end (endanchored set)\\n\");\n#endif\n      return MATCH_NOMATCH;   /* (*ACCEPT) */\n      }\n\n    /* Fail if we detect that the start position was moved to be either after\n    the end position (\\K in lookahead) or before the start offset (\\K in\n    lookbehind). If this occurs, the pattern must have used \\K in a somewhat\n    sneaky way (e.g. by pattern recursion), because if the \\K is actually\n    syntactically inside the lookaround, it's blocked at compile-time. */\n\n    if (Fstart_match < mb->start_subject + mb->start_offset ||\n        Fstart_match > Feptr)\n      {\n      /* The \\K expression is fairly rare. We assert it was used so that we\n      catch any unexpected invalid data in start_match. */\n      PCRE2_ASSERT(mb->hasbsk);\n\n      if (!mb->allowlookaroundbsk)\n        return PCRE2_ERROR_BAD_BACKSLASH_K;\n      }\n\n    /* We have a successful match of the whole pattern. Record the result and\n    then do a direct return from the function. If there is space in the offset\n    vector, set any pairs that follow the highest-numbered captured string but\n    are less than the number of capturing groups in the pattern to PCRE2_UNSET.\n    It is documented that this happens. \"Gaps\" are set to PCRE2_UNSET\n    dynamically. It is only those at the end that need setting here. */\n\n    mb->end_match_ptr = Feptr;           /* Record where we ended */\n    mb->end_offset_top = Foffset_top;    /* and how many extracts were taken */\n    mb->mark = Fmark;                    /* and the last success mark */\n    if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;\n\n    match_data->ovector[0] = Fstart_match - mb->start_subject;\n    match_data->ovector[1] = Feptr - mb->start_subject;\n\n    /* Set i to the smaller of the sizes of the external and frame ovectors. */\n\n    i = 2 * ((top_bracket + 1 > match_data->oveccount)?\n      match_data->oveccount : top_bracket + 1);\n    memcpy(match_data->ovector + 2, Fovector, (i - 2) * sizeof(PCRE2_SIZE));\n    while (--i >= Foffset_top + 2) match_data->ovector[i] = PCRE2_UNSET;\n    return MATCH_MATCH;  /* Note: NOT RRETURN */\n\n\n    /*===================================================================== */\n    /* Match any single character type except newline; have to take care with\n    CRLF newlines and partial matching. */\n\n    case OP_ANY:\n    if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);\n    if (mb->partial != 0 &&\n        Feptr == mb->end_subject - 1 &&\n        NLBLOCK->nltype == NLTYPE_FIXED &&\n        NLBLOCK->nllen == 2 &&\n        UCHAR21TEST(Feptr) == NLBLOCK->nl[0])\n      {\n      mb->hitend = TRUE;\n      if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* Match any single character whatsoever. */\n\n    case OP_ALLANY:\n    if (Feptr >= mb->end_subject)  /* DO NOT merge the Feptr++ here; it must */\n      {                            /* not be updated before SCHECK_PARTIAL. */\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    Feptr++;\n#ifdef SUPPORT_UNICODE\n    if (utf) ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n#endif\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Match a single code unit, even in UTF mode. This opcode really does\n    match any code unit, even newline. (It really should be called ANYCODEUNIT,\n    of course - the byte name is from pre-16 bit days.) */\n\n    case OP_ANYBYTE:\n    if (Feptr >= mb->end_subject)   /* DO NOT merge the Feptr++ here; it must */\n      {                             /* not be updated before SCHECK_PARTIAL. */\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    Feptr++;\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Match a single character, casefully */\n\n    case OP_CHAR:\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      Flength = 1;\n      Fecode++;\n      GETCHARLEN(fc, Fecode, Flength);\n      if (Flength > (PCRE2_SIZE)(mb->end_subject - Feptr))\n        {\n        CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */\n        RRETURN(MATCH_NOMATCH);\n        }\n      for (; Flength > 0; Flength--)\n        {\n        if (*Fecode++ != UCHAR21INC(Feptr)) RRETURN(MATCH_NOMATCH);\n        }\n      }\n    else\n#endif\n\n    /* Not UTF mode */\n      {\n      if (mb->end_subject - Feptr < 1)\n        {\n        SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */\n        RRETURN(MATCH_NOMATCH);\n        }\n      if (Fecode[1] != *Feptr++) RRETURN(MATCH_NOMATCH);\n      Fecode += 2;\n      }\n    break;\n\n\n    /* ===================================================================== */\n    /* Match a single character, caselessly. If we are at the end of the\n    subject, give up immediately. We get here only when the pattern character\n    has at most one other case. Characters with more than two cases are coded\n    as OP_PROP with the pseudo-property PT_CLIST. */\n\n    case OP_CHARI:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      Flength = 1;\n      Fecode++;\n      GETCHARLEN(fc, Fecode, Flength);\n\n      /* If the pattern character's value is < 128, we know that its other case\n      (if any) is also < 128 (and therefore only one code unit long in all\n      code-unit widths), so we can use the fast lookup table. We checked above\n      that there is at least one character left in the subject. */\n\n      if (fc < 128)\n        {\n        uint32_t cc = UCHAR21(Feptr);\n        if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);\n        Fecode++;\n        Feptr++;\n        }\n\n      /* Otherwise we must pick up the subject character and use Unicode\n      property support to test its other case. Note that we cannot use the\n      value of \"Flength\" to check for sufficient bytes left, because the other\n      case of the character may have more or fewer code units. */\n\n      else\n        {\n        uint32_t dc;\n        GETCHARINC(dc, Feptr);\n        Fecode += Flength;\n        if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);\n        }\n      }\n\n    /* If UCP is set without UTF we must do the same as above, but with one\n    character per code unit. */\n\n    else if (ucp)\n      {\n      uint32_t cc = UCHAR21(Feptr);\n      fc = Fecode[1];\n      if (fc < 128)\n        {\n        if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);\n        }\n      else\n        {\n        if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);\n        }\n      Feptr++;\n      Fecode += 2;\n      }\n\n    else\n#endif   /* SUPPORT_UNICODE */\n\n    /* Not UTF or UCP mode; use the table for characters < 256. */\n      {\n      if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])\n          != TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);\n      Feptr++;\n      Fecode += 2;\n      }\n    break;\n\n\n    /* ===================================================================== */\n    /* Match not a single character. */\n\n    case OP_NOT:\n    case OP_NOTI:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      uint32_t ch;\n      Fecode++;\n      GETCHARINC(ch, Fecode);\n      GETCHARINC(fc, Feptr);\n      if (ch == fc)\n        {\n        RRETURN(MATCH_NOMATCH);  /* Caseful match */\n        }\n      else if (Fop == OP_NOTI)   /* If caseless */\n        {\n        if (ch > 127)\n          ch = UCD_OTHERCASE(ch);\n        else\n          ch = (mb->fcc)[ch];\n        if (ch == fc) RRETURN(MATCH_NOMATCH);\n        }\n      }\n\n    /* UCP without UTF is as above, but with one character per code unit. */\n\n    else if (ucp)\n      {\n      uint32_t ch;\n      fc = UCHAR21INC(Feptr);\n      ch = Fecode[1];\n      Fecode += 2;\n\n      if (ch == fc)\n        {\n        RRETURN(MATCH_NOMATCH);  /* Caseful match */\n        }\n      else if (Fop == OP_NOTI)   /* If caseless */\n        {\n        if (ch > 127)\n          ch = UCD_OTHERCASE(ch);\n        else\n          ch = (mb->fcc)[ch];\n        if (ch == fc) RRETURN(MATCH_NOMATCH);\n        }\n      }\n\n    else\n#endif  /* SUPPORT_UNICODE */\n\n    /* Neither UTF nor UCP is set */\n\n      {\n      uint32_t ch = Fecode[1];\n      fc = UCHAR21INC(Feptr);\n      if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))\n        RRETURN(MATCH_NOMATCH);\n      Fecode += 2;\n      }\n    break;\n\n\n    /* ===================================================================== */\n    /* Match a single character repeatedly. */\n\n#define Loclength    F->temp_size\n#define Lstart_eptr  F->temp_sptr[0]\n#define Lcharptr     F->temp_sptr[1]\n#define Lmin         F->temp_32[0]\n#define Lmax         F->temp_32[1]\n#define Lc           F->temp_32[2]\n#define Loc          F->temp_32[3]\n\n    case OP_EXACT:\n    case OP_EXACTI:\n    Lmin = Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATCHAR;\n\n    case OP_POSUPTO:\n    case OP_POSUPTOI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATCHAR;\n\n    case OP_UPTO:\n    case OP_UPTOI:\n    reptype = REPTYPE_MAX;\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATCHAR;\n\n    case OP_MINUPTO:\n    case OP_MINUPTOI:\n    reptype = REPTYPE_MIN;\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATCHAR;\n\n    case OP_POSSTAR:\n    case OP_POSSTARI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATCHAR;\n\n    case OP_POSPLUS:\n    case OP_POSPLUSI:\n    reptype = REPTYPE_POS;\n    Lmin = 1;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATCHAR;\n\n    case OP_POSQUERY:\n    case OP_POSQUERYI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = 1;\n    Fecode++;\n    goto REPEATCHAR;\n\n    case OP_STAR:\n    case OP_STARI:\n    case OP_MINSTAR:\n    case OP_MINSTARI:\n    case OP_PLUS:\n    case OP_PLUSI:\n    case OP_MINPLUS:\n    case OP_MINPLUSI:\n    case OP_QUERY:\n    case OP_QUERYI:\n    case OP_MINQUERY:\n    case OP_MINQUERYI:\n    fc = *Fecode++ - ((Fop < OP_STARI)? OP_STAR : OP_STARI);\n    Lmin = rep_min[fc];\n    Lmax = rep_max[fc];\n    reptype = rep_typ[fc];\n\n    /* Common code for all repeated single-character matches. We first check\n    for the minimum number of characters. If the minimum equals the maximum, we\n    are done. Otherwise, if minimizing, check the rest of the pattern for a\n    match; if there isn't one, advance up to the maximum, one character at a\n    time.\n\n    If maximizing, advance up to the maximum number of matching characters,\n    until Feptr is past the end of the maximum run. If possessive, we are\n    then done (no backing up). Otherwise, match at this position; anything\n    other than no match is immediately returned. For nomatch, back up one\n    character, unless we are matching \\R and the last thing matched was\n    \\r\\n, in which case, back up two code units until we reach the first\n    optional character position.\n\n    The various UTF/non-UTF and caseful/caseless cases are handled separately,\n    for speed. */\n\n    REPEATCHAR:\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      Flength = 1;\n      Lcharptr = Fecode;\n      GETCHARLEN(fc, Fecode, Flength);\n      Fecode += Flength;\n\n      /* Handle multi-code-unit character matching, caseful and caseless. */\n\n      if (Flength > 1)\n        {\n        uint32_t othercase;\n\n        if (Fop >= OP_STARI &&     /* Caseless */\n            (othercase = UCD_OTHERCASE(fc)) != fc)\n          Loclength = PRIV(ord2utf)(othercase, Foccu);\n        else Loclength = 0;\n\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr <= mb->end_subject - Flength &&\n            memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;\n          else if (Loclength > 0 &&\n                   Feptr <= mb->end_subject - Loclength &&\n                   memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)\n            Feptr += Loclength;\n          else\n            {\n            CHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          }\n\n        if (Lmin == Lmax) continue;\n\n        if (reptype == REPTYPE_MIN)\n          {\n          for (;;)\n            {\n            RMATCH(Fecode, RM202);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr <= mb->end_subject - Flength &&\n              memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;\n            else if (Loclength > 0 &&\n                     Feptr <= mb->end_subject - Loclength &&\n                     memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)\n              Feptr += Loclength;\n            else\n              {\n              CHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n          }\n\n        else  /* Maximize */\n          {\n          Lstart_eptr = Feptr;\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr <= mb->end_subject - Flength &&\n                memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0)\n              Feptr += Flength;\n            else if (Loclength > 0 &&\n                     Feptr <= mb->end_subject - Loclength &&\n                     memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)\n              Feptr += Loclength;\n            else\n              {\n              CHECK_PARTIAL();\n              break;\n              }\n            }\n\n          /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n          Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n          go too far. */\n\n          if (reptype != REPTYPE_POS) for(;;)\n            {\n            if (Feptr <= Lstart_eptr) break;\n            RMATCH(Fecode, RM203);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            BACKCHAR(Feptr);\n            }\n          }\n        break;   /* End of repeated wide character handling */\n        }\n\n      /* Length of UTF character is 1. Put it into the preserved variable and\n      fall through to the non-UTF code. */\n\n      Lc = fc;\n      }\n    else\n#endif  /* SUPPORT_UNICODE */\n\n    /* When not in UTF mode, load a single-code-unit character. Then proceed as\n    above, using Unicode casing if either UTF or UCP is set. */\n\n    Lc = *Fecode++;\n\n    /* Caseless comparison */\n\n    if (Fop >= OP_STARI)\n      {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n#ifdef SUPPORT_UNICODE\n      if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);\n      else\n#endif  /* SUPPORT_UNICODE */\n      /* Lc will be < 128 in UTF-8 mode. */\n      Loc = mb->fcc[Lc];\n#else /* 16-bit & 32-bit */\n#ifdef SUPPORT_UNICODE\n      if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc);\n      else\n#endif  /* SUPPORT_UNICODE */\n      Loc = TABLE_GET(Lc, mb->fcc, Lc);\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */\n\n      for (i = 1; i <= Lmin; i++)\n        {\n        uint32_t cc;                 /* Faster than PCRE2_UCHAR */\n        if (Feptr >= mb->end_subject)\n          {\n          SCHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        cc = UCHAR21TEST(Feptr);\n        if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);\n        Feptr++;\n        }\n      if (Lmin == Lmax) continue;\n\n      if (reptype == REPTYPE_MIN)\n        {\n        for (;;)\n          {\n          uint32_t cc;               /* Faster than PCRE2_UCHAR */\n          RMATCH(Fecode, RM25);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21TEST(Feptr);\n          if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      else  /* Maximize */\n        {\n        Lstart_eptr = Feptr;\n        for (i = Lmin; i < Lmax; i++)\n          {\n          uint32_t cc;               /* Faster than PCRE2_UCHAR */\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            break;\n            }\n          cc = UCHAR21TEST(Feptr);\n          if (Lc != cc && Loc != cc) break;\n          Feptr++;\n          }\n        if (reptype != REPTYPE_POS) for (;;)\n          {\n          if (Feptr == Lstart_eptr) break;\n          RMATCH(Fecode, RM26);\n          Feptr--;\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          }\n        }\n      }\n\n    /* Caseful comparisons (includes all multi-byte characters) */\n\n    else\n      {\n      for (i = 1; i <= Lmin; i++)\n        {\n        if (Feptr >= mb->end_subject)\n          {\n          SCHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);\n        }\n\n      if (Lmin == Lmax) continue;\n\n      if (reptype == REPTYPE_MIN)\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM27);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n      else  /* Maximize */\n        {\n        Lstart_eptr = Feptr;\n        for (i = Lmin; i < Lmax; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            break;\n            }\n\n          if (Lc != UCHAR21TEST(Feptr)) break;\n          Feptr++;\n          }\n\n        if (reptype != REPTYPE_POS) for (;;)\n          {\n          if (Feptr <= Lstart_eptr) break;\n          RMATCH(Fecode, RM28);\n          Feptr--;\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          }\n        }\n      }\n    break;\n\n#undef Loclength\n#undef Lstart_eptr\n#undef Lcharptr\n#undef Lmin\n#undef Lmax\n#undef Lc\n#undef Loc\n\n\n    /* ===================================================================== */\n    /* Match a negated single one-byte character repeatedly. This is almost a\n    repeat of the code for a repeated single character, but I haven't found a\n    nice way of commoning these up that doesn't require a test of the\n    positive/negative option for each character match. Maybe that wouldn't add\n    very much to the time taken, but character matching *is* what this is all\n    about... */\n\n#define Lstart_eptr  F->temp_sptr[0]\n#define Lmin         F->temp_32[0]\n#define Lmax         F->temp_32[1]\n#define Lc           F->temp_32[2]\n#define Loc          F->temp_32[3]\n\n    case OP_NOTEXACT:\n    case OP_NOTEXACTI:\n    Lmin = Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTUPTO:\n    case OP_NOTUPTOI:\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    reptype = REPTYPE_MAX;\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTMINUPTO:\n    case OP_NOTMINUPTOI:\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    reptype = REPTYPE_MIN;\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSSTARI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSPLUSI:\n    reptype = REPTYPE_POS;\n    Lmin = 1;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSQUERYI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = 1;\n    Fecode++;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTPOSUPTO:\n    case OP_NOTPOSUPTOI:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATNOTCHAR;\n\n    case OP_NOTSTAR:\n    case OP_NOTSTARI:\n    case OP_NOTMINSTAR:\n    case OP_NOTMINSTARI:\n    case OP_NOTPLUS:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUS:\n    case OP_NOTMINPLUSI:\n    case OP_NOTQUERY:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERY:\n    case OP_NOTMINQUERYI:\n    fc = *Fecode++ - ((Fop >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);\n    Lmin = rep_min[fc];\n    Lmax = rep_max[fc];\n    reptype = rep_typ[fc];\n\n    /* Common code for all repeated single-character non-matches. */\n\n    REPEATNOTCHAR:\n    GETCHARINCTEST(Lc, Fecode);\n\n    /* The code is duplicated for the caseless and caseful cases, for speed,\n    since matching characters is likely to be quite common. First, ensure the\n    minimum number of matches are present. If Lmin = Lmax, we are done.\n    Otherwise, if minimizing, keep trying the rest of the expression and\n    advancing one matching character if failing, up to the maximum.\n    Alternatively, if maximizing, find the maximum number of characters and\n    work backwards. */\n\n    if (Fop >= OP_NOTSTARI)     /* Caseless */\n      {\n#ifdef SUPPORT_UNICODE\n      if ((utf || ucp) && Lc > 127)\n        Loc = UCD_OTHERCASE(Lc);\n      else\n#endif /* SUPPORT_UNICODE */\n\n      Loc = TABLE_GET(Lc, mb->fcc, Lc);  /* Other case from table */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        uint32_t d;\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(d, Feptr);\n          if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);\n          }\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n\n      /* Not UTF mode */\n        {\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        }\n\n      if (Lmin == Lmax) continue;  /* Finished for exact count */\n\n      if (reptype == REPTYPE_MIN)\n        {\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          uint32_t d;\n          for (;;)\n            {\n            RMATCH(Fecode, RM204);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINC(d, Feptr);\n            if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);\n            }\n          }\n        else\n#endif  /*SUPPORT_UNICODE */\n\n        /* Not UTF mode */\n          {\n          for (;;)\n            {\n            RMATCH(Fecode, RM29);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);\n            Feptr++;\n            }\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      /* Maximize case */\n\n      else\n        {\n        Lstart_eptr = Feptr;\n\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          uint32_t d;\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(d, Feptr, len);\n            if (Lc == d || Loc == d) break;\n            Feptr += len;\n            }\n\n          /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n          Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n          go too far. */\n\n          if (reptype != REPTYPE_POS) for(;;)\n            {\n            if (Feptr <= Lstart_eptr) break;\n            RMATCH(Fecode, RM205);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            BACKCHAR(Feptr);\n            }\n          }\n        else\n#endif  /* SUPPORT_UNICODE */\n\n        /* Not UTF mode */\n          {\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (Lc == *Feptr || Loc == *Feptr) break;\n            Feptr++;\n            }\n          if (reptype != REPTYPE_POS) for (;;)\n            {\n            if (Feptr == Lstart_eptr) break;\n            RMATCH(Fecode, RM30);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            }\n          }\n        }\n      }\n\n    /* Caseful comparisons */\n\n    else\n      {\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        uint32_t d;\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(d, Feptr);\n          if (Lc == d) RRETURN(MATCH_NOMATCH);\n          }\n        }\n      else\n#endif\n      /* Not UTF mode */\n        {\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);\n          }\n        }\n\n      if (Lmin == Lmax) continue;\n\n      if (reptype == REPTYPE_MIN)\n        {\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          uint32_t d;\n          for (;;)\n            {\n            RMATCH(Fecode, RM206);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINC(d, Feptr);\n            if (Lc == d) RRETURN(MATCH_NOMATCH);\n            }\n          }\n        else\n#endif\n        /* Not UTF mode */\n          {\n          for (;;)\n            {\n            RMATCH(Fecode, RM31);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);\n            }\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      /* Maximize case */\n\n      else\n        {\n        Lstart_eptr = Feptr;\n\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          uint32_t d;\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(d, Feptr, len);\n            if (Lc == d) break;\n            Feptr += len;\n            }\n\n          /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n          Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n          go too far. */\n\n          if (reptype != REPTYPE_POS) for(;;)\n            {\n            if (Feptr <= Lstart_eptr) break;\n            RMATCH(Fecode, RM207);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            BACKCHAR(Feptr);\n            }\n          }\n        else\n#endif\n        /* Not UTF mode */\n          {\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (Lc == *Feptr) break;\n            Feptr++;\n            }\n          if (reptype != REPTYPE_POS) for (;;)\n            {\n            if (Feptr == Lstart_eptr) break;\n            RMATCH(Fecode, RM32);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            }\n          }\n        }\n      }\n    break;\n\n#undef Lstart_eptr\n#undef Lmin\n#undef Lmax\n#undef Lc\n#undef Loc\n\n\n    /* ===================================================================== */\n    /* Match a bit-mapped character class, possibly repeatedly. These opcodes\n    are used when all the characters in the class have values in the range\n    0-255, and either the matching is caseful, or the characters are in the\n    range 0-127 when UTF processing is enabled. The only difference between\n    OP_CLASS and OP_NCLASS occurs when a data character outside the range is\n    encountered. */\n\n#define Lmin               F->temp_32[0]\n#define Lmax               F->temp_32[1]\n#define Lstart_eptr        F->temp_sptr[0]\n#define Lbyte_map_address  F->temp_sptr[1]\n#define Lbyte_map          ((const unsigned char *)Lbyte_map_address)\n\n    case OP_NCLASS:\n    case OP_CLASS:\n      {\n      Lbyte_map_address = Fecode + 1;           /* Save for matching */\n      Fecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */\n\n      /* Look past the end of the item to see if there is repeat information\n      following. Then obey similar code to character type repeats. */\n\n      switch (*Fecode)\n        {\n        case OP_CRSTAR:\n        case OP_CRMINSTAR:\n        case OP_CRPLUS:\n        case OP_CRMINPLUS:\n        case OP_CRQUERY:\n        case OP_CRMINQUERY:\n        case OP_CRPOSSTAR:\n        case OP_CRPOSPLUS:\n        case OP_CRPOSQUERY:\n        fc = *Fecode++ - OP_CRSTAR;\n        Lmin = rep_min[fc];\n        Lmax = rep_max[fc];\n        reptype = rep_typ[fc];\n        break;\n\n        case OP_CRRANGE:\n        case OP_CRMINRANGE:\n        case OP_CRPOSRANGE:\n        Lmin = GET2(Fecode, 1);\n        Lmax = GET2(Fecode, 1 + IMM2_SIZE);\n        if (Lmax == 0) Lmax = UINT32_MAX;       /* Max 0 => infinity */\n        reptype = rep_typ[*Fecode - OP_CRSTAR];\n        Fecode += 1 + 2 * IMM2_SIZE;\n        break;\n\n        default:               /* No repeat follows */\n        Lmin = Lmax = 1;\n        break;\n        }\n\n      /* First, ensure the minimum number of matches are present. */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          if (fc > 255)\n            {\n            if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);\n            }\n          else\n            if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);\n          }\n        }\n      else\n#endif\n      /* Not UTF mode */\n        {\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          fc = *Feptr++;\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          if (fc > 255)\n            {\n            if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);\n            }\n          else\n#endif\n          if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);\n          }\n        }\n\n      /* If Lmax == Lmin we are done. Continue with main loop. */\n\n      if (Lmin == Lmax) continue;\n\n      /* If minimizing, keep testing the rest of the expression and advancing\n      the pointer while it matches the class. */\n\n      if (reptype == REPTYPE_MIN)\n        {\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          for (;;)\n            {\n            RMATCH(Fecode, RM200);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINC(fc, Feptr);\n            if (fc > 255)\n              {\n              if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);\n              }\n            else\n              if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);\n            }\n          }\n        else\n#endif\n        /* Not UTF mode */\n          {\n          for (;;)\n            {\n            RMATCH(Fecode, RM23);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            fc = *Feptr++;\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            if (fc > 255)\n              {\n              if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);\n              }\n            else\n#endif\n            if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);\n            }\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      /* If maximizing, find the longest possible run, then work backwards. */\n\n      else\n        {\n        Lstart_eptr = Feptr;\n\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc > 255)\n              {\n              if (Fop == OP_CLASS) break;\n              }\n            else\n              if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;\n            Feptr += len;\n            }\n\n          if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n          /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n          Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n          go too far. */\n\n          for (;;)\n            {\n            RMATCH(Fecode, RM201);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Feptr-- <= Lstart_eptr) break;  /* Tried at original position */\n            BACKCHAR(Feptr);\n            }\n          }\n        else\n#endif\n          /* Not UTF mode */\n          {\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            fc = *Feptr;\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            if (fc > 255)\n              {\n              if (Fop == OP_CLASS) break;\n              }\n            else\n#endif\n            if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;\n            Feptr++;\n            }\n\n          if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n          while (Feptr >= Lstart_eptr)\n            {\n            RMATCH(Fecode, RM24);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            Feptr--;\n            }\n          }\n\n        RRETURN(MATCH_NOMATCH);\n        }\n      }\n\n    PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n#undef Lbyte_map_address\n#undef Lbyte_map\n#undef Lstart_eptr\n#undef Lmin\n#undef Lmax\n\n\n    /* ===================================================================== */\n    /* Match an extended character class. In the 8-bit library, this opcode is\n    encountered only when UTF-8 mode mode is supported. In the 16-bit and\n    32-bit libraries, codepoints greater than 255 may be encountered even when\n    UTF is not supported. */\n\n#define Lstart_eptr  F->temp_sptr[0]\n#define Lxclass_data F->temp_sptr[1]\n#define Lmin         F->temp_32[0]\n#define Lmax         F->temp_32[1]\n\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_XCLASS:\n      {\n      Lxclass_data = Fecode + 1 + LINK_SIZE;  /* Save for matching */\n      Fecode += GET(Fecode, 1);               /* Advance past the item */\n\n      switch (*Fecode)\n        {\n        case OP_CRSTAR:\n        case OP_CRMINSTAR:\n        case OP_CRPLUS:\n        case OP_CRMINPLUS:\n        case OP_CRQUERY:\n        case OP_CRMINQUERY:\n        case OP_CRPOSSTAR:\n        case OP_CRPOSPLUS:\n        case OP_CRPOSQUERY:\n        fc = *Fecode++ - OP_CRSTAR;\n        Lmin = rep_min[fc];\n        Lmax = rep_max[fc];\n        reptype = rep_typ[fc];\n        break;\n\n        case OP_CRRANGE:\n        case OP_CRMINRANGE:\n        case OP_CRPOSRANGE:\n        Lmin = GET2(Fecode, 1);\n        Lmax = GET2(Fecode, 1 + IMM2_SIZE);\n        if (Lmax == 0) Lmax = UINT32_MAX;  /* Max 0 => infinity */\n        reptype = rep_typ[*Fecode - OP_CRSTAR];\n        Fecode += 1 + 2 * IMM2_SIZE;\n        break;\n\n        default:               /* No repeat follows */\n        Lmin = Lmax = 1;\n        break;\n        }\n\n      /* First, ensure the minimum number of matches are present. */\n\n      for (i = 1; i <= Lmin; i++)\n        {\n        if (Feptr >= mb->end_subject)\n          {\n          SCHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        GETCHARINCTEST(fc, Feptr);\n        if (!PRIV(xclass)(fc, Lxclass_data,\n            (const uint8_t*)mb->start_code, utf))\n          RRETURN(MATCH_NOMATCH);\n        }\n\n      /* If Lmax == Lmin we can just continue with the main loop. */\n\n      if (Lmin == Lmax) continue;\n\n      /* If minimizing, keep testing the rest of the expression and advancing\n      the pointer while it matches the class. */\n\n      if (reptype == REPTYPE_MIN)\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM100);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINCTEST(fc, Feptr);\n          if (!PRIV(xclass)(fc, Lxclass_data,\n              (const uint8_t*)mb->start_code, utf))\n            RRETURN(MATCH_NOMATCH);\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      /* If maximizing, find the longest possible run, then work backwards. */\n\n      else\n        {\n        Lstart_eptr = Feptr;\n        for (i = Lmin; i < Lmax; i++)\n          {\n          int len = 1;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            break;\n            }\n#ifdef SUPPORT_UNICODE\n          GETCHARLENTEST(fc, Feptr, len);\n#else\n          fc = *Feptr;\n#endif\n          if (!PRIV(xclass)(fc, Lxclass_data,\n              (const uint8_t*)mb->start_code, utf)) break;\n          Feptr += len;\n          }\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n        go too far. */\n\n        for(;;)\n          {\n          RMATCH(Fecode, RM101);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Feptr-- <= Lstart_eptr) break;  /* Tried at original position */\n#ifdef SUPPORT_UNICODE\n          if (utf) BACKCHAR(Feptr);\n#endif\n          }\n        RRETURN(MATCH_NOMATCH);\n        }\n\n      PCRE2_UNREACHABLE(); /* Control never reaches here */\n      }\n#endif  /* SUPPORT_WIDE_CHARS: end of XCLASS */\n\n#undef Lstart_eptr\n#undef Lxclass_data\n#undef Lmin\n#undef Lmax\n\n\n    /* ===================================================================== */\n    /* Match a complex, set-based character class. This opcodes are used when\n    there is complex nesting or logical operations within the character\n    class. */\n\n#define Lstart_eptr  F->temp_sptr[0]\n#define Leclass_data F->temp_sptr[1]\n#define Leclass_len  F->temp_size\n#define Lmin         F->temp_32[0]\n#define Lmax         F->temp_32[1]\n\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_ECLASS:\n      {\n      Leclass_data = Fecode + 1 + LINK_SIZE;  /* Save for matching */\n      Fecode += GET(Fecode, 1);               /* Advance past the item */\n      Leclass_len = (PCRE2_SIZE)(Fecode - Leclass_data);\n\n      switch (*Fecode)\n        {\n        case OP_CRSTAR:\n        case OP_CRMINSTAR:\n        case OP_CRPLUS:\n        case OP_CRMINPLUS:\n        case OP_CRQUERY:\n        case OP_CRMINQUERY:\n        case OP_CRPOSSTAR:\n        case OP_CRPOSPLUS:\n        case OP_CRPOSQUERY:\n        fc = *Fecode++ - OP_CRSTAR;\n        Lmin = rep_min[fc];\n        Lmax = rep_max[fc];\n        reptype = rep_typ[fc];\n        break;\n\n        case OP_CRRANGE:\n        case OP_CRMINRANGE:\n        case OP_CRPOSRANGE:\n        Lmin = GET2(Fecode, 1);\n        Lmax = GET2(Fecode, 1 + IMM2_SIZE);\n        if (Lmax == 0) Lmax = UINT32_MAX;  /* Max 0 => infinity */\n        reptype = rep_typ[*Fecode - OP_CRSTAR];\n        Fecode += 1 + 2 * IMM2_SIZE;\n        break;\n\n        default:               /* No repeat follows */\n        Lmin = Lmax = 1;\n        break;\n        }\n\n      /* First, ensure the minimum number of matches are present. */\n\n      for (i = 1; i <= Lmin; i++)\n        {\n        if (Feptr >= mb->end_subject)\n          {\n          SCHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        GETCHARINCTEST(fc, Feptr);\n        if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len,\n                          (const uint8_t*)mb->start_code, utf))\n          RRETURN(MATCH_NOMATCH);\n        }\n\n      /* If Lmax == Lmin we can just continue with the main loop. */\n\n      if (Lmin == Lmax) continue;\n\n      /* If minimizing, keep testing the rest of the expression and advancing\n      the pointer while it matches the class. */\n\n      if (reptype == REPTYPE_MIN)\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM102);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINCTEST(fc, Feptr);\n          if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len,\n                            (const uint8_t*)mb->start_code, utf))\n            RRETURN(MATCH_NOMATCH);\n          }\n        PCRE2_UNREACHABLE(); /* Control never reaches here */\n        }\n\n      /* If maximizing, find the longest possible run, then work backwards. */\n\n      else\n        {\n        Lstart_eptr = Feptr;\n        for (i = Lmin; i < Lmax; i++)\n          {\n          int len = 1;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            break;\n            }\n#ifdef SUPPORT_UNICODE\n          GETCHARLENTEST(fc, Feptr, len);\n#else\n          fc = *Feptr;\n#endif\n          if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len,\n                            (const uint8_t*)mb->start_code, utf))\n            break;\n          Feptr += len;\n          }\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n        go too far. */\n\n        for(;;)\n          {\n          RMATCH(Fecode, RM103);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Feptr-- <= Lstart_eptr) break;  /* Tried at original position */\n#ifdef SUPPORT_UNICODE\n          if (utf) BACKCHAR(Feptr);\n#endif\n          }\n        RRETURN(MATCH_NOMATCH);\n        }\n\n      PCRE2_UNREACHABLE(); /* Control never reaches here */\n      }\n#endif  /* SUPPORT_WIDE_CHARS: end of ECLASS */\n\n#undef Lstart_eptr\n#undef Leclass_data\n#undef Leclass_len\n#undef Lmin\n#undef Lmax\n\n\n    /* ===================================================================== */\n    /* Match various character types when PCRE2_UCP is not set. These opcodes\n    are not generated when PCRE2_UCP is set - instead appropriate property\n    tests are compiled. */\n\n    case OP_NOT_DIGIT:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_DIGIT:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_NOT_WHITESPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_WHITESPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_NOT_WORDCHAR:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_WORDCHAR:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_ANYNL:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    switch(fc)\n      {\n      default: RRETURN(MATCH_NOMATCH);\n\n      case CHAR_CR:\n      if (Feptr >= mb->end_subject)\n        {\n        SCHECK_PARTIAL();\n        }\n      else if (UCHAR21TEST(Feptr) == CHAR_LF) Feptr++;\n      break;\n\n      case CHAR_LF:\n      break;\n\n      case CHAR_VT:\n      case CHAR_FF:\n      case CHAR_NEL:\n#ifndef EBCDIC\n      case 0x2028:\n      case 0x2029:\n#endif  /* Not EBCDIC */\n      if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);\n      break;\n      }\n    Fecode++;\n    break;\n\n    case OP_NOT_HSPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    switch(fc)\n      {\n      HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */\n      default: break;\n      }\n    Fecode++;\n    break;\n\n    case OP_HSPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    switch(fc)\n      {\n      HSPACE_CASES: break;  /* Byte and multibyte cases */\n      default: RRETURN(MATCH_NOMATCH);\n      }\n    Fecode++;\n    break;\n\n    case OP_NOT_VSPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    switch(fc)\n      {\n      VSPACE_CASES: RRETURN(MATCH_NOMATCH);\n      default: break;\n      }\n    Fecode++;\n    break;\n\n    case OP_VSPACE:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n    switch(fc)\n      {\n      VSPACE_CASES: break;\n      default: RRETURN(MATCH_NOMATCH);\n      }\n    Fecode++;\n    break;\n\n\n#ifdef SUPPORT_UNICODE\n\n    /* ===================================================================== */\n    /* Check the next character by Unicode property. We will get here only\n    if the support is in the binary; otherwise a compile-time error occurs. */\n\n    case OP_PROP:\n    case OP_NOTPROP:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    GETCHARINCTEST(fc, Feptr);\n      {\n      const uint32_t *cp;\n      uint32_t chartype;\n      const ucd_record *prop = GET_UCD(fc);\n      BOOL notmatch = Fop == OP_NOTPROP;\n\n      switch(Fecode[1])\n        {\n        case PT_LAMP:\n        chartype = prop->chartype;\n        if ((chartype == ucp_Lu ||\n             chartype == ucp_Ll ||\n             chartype == ucp_Lt) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_GC:\n        if ((Fecode[2] == PRIV(ucp_gentype)[prop->chartype]) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_PC:\n        if ((Fecode[2] == prop->chartype) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_SC:\n        if ((Fecode[2] == prop->script) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_SCX:\n          {\n          BOOL ok = (Fecode[2] == prop->script ||\n                     MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Fecode[2]) != 0);\n          if (ok == notmatch) RRETURN(MATCH_NOMATCH);\n          }\n        break;\n\n        /* These are specials */\n\n        case PT_ALNUM:\n        chartype = prop->chartype;\n        if ((PRIV(ucp_gentype)[chartype] == ucp_L ||\n             PRIV(ucp_gentype)[chartype] == ucp_N) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n        which means that Perl space and POSIX space are now identical. PCRE\n        was changed at release 8.34. */\n\n        case PT_SPACE:    /* Perl space */\n        case PT_PXSPACE:  /* POSIX space */\n        switch(fc)\n          {\n          HSPACE_CASES:\n          VSPACE_CASES:\n          if (notmatch) RRETURN(MATCH_NOMATCH);\n          break;\n\n          default:\n          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == notmatch)\n            RRETURN(MATCH_NOMATCH);\n          break;\n          }\n        break;\n\n        case PT_WORD:\n        chartype = prop->chartype;\n        if ((PRIV(ucp_gentype)[chartype] == ucp_L ||\n             PRIV(ucp_gentype)[chartype] == ucp_N ||\n             chartype == ucp_Mn ||\n             chartype == ucp_Pc) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_CLIST:\n#if PCRE2_CODE_UNIT_WIDTH == 32\n            if (fc > MAX_UTF_CODE_POINT)\n              {\n              if (notmatch) break;;\n              RRETURN(MATCH_NOMATCH);\n              }\n#endif\n        cp = PRIV(ucd_caseless_sets) + Fecode[2];\n        for (;;)\n          {\n          if (fc < *cp)\n            { if (notmatch) break; else { RRETURN(MATCH_NOMATCH); } }\n          if (fc == *cp++)\n            { if (notmatch) { RRETURN(MATCH_NOMATCH); } else break; }\n          }\n        break;\n\n        case PT_UCNC:\n        if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||\n             fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||\n             fc >= 0xe000) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_BIDICL:\n        if ((UCD_BIDICLASS_PROP(prop) == Fecode[2]) == notmatch)\n          RRETURN(MATCH_NOMATCH);\n        break;\n\n        case PT_BOOL:\n          {\n          BOOL ok = MAPBIT(PRIV(ucd_boolprop_sets) +\n            UCD_BPROPS_PROP(prop), Fecode[2]) != 0;\n          if (ok == notmatch) RRETURN(MATCH_NOMATCH);\n          }\n        break;\n\n        /* This should never occur */\n\n        /* LCOV_EXCL_START */\n        default:\n        PCRE2_DEBUG_UNREACHABLE();\n        return PCRE2_ERROR_INTERNAL;\n        /* LCOV_EXCL_STOP */\n        }\n\n      Fecode += 3;\n      }\n    break;\n\n\n    /* ===================================================================== */\n    /* Match an extended Unicode sequence. We will get here only if the support\n    is in the binary; otherwise a compile-time error occurs. */\n\n    case OP_EXTUNI:\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      RRETURN(MATCH_NOMATCH);\n      }\n    else\n      {\n      GETCHARINCTEST(fc, Feptr);\n      Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,\n        NULL);\n      }\n    CHECK_PARTIAL();\n    Fecode++;\n    break;\n\n#endif  /* SUPPORT_UNICODE */\n\n\n    /* ===================================================================== */\n    /* Match a single character type repeatedly. Note that the property type\n    does not need to be in a stack frame as it is not used within an RMATCH()\n    loop. */\n\n#define Lstart_eptr  F->temp_sptr[0]\n#define Lmin         F->temp_32[0]\n#define Lmax         F->temp_32[1]\n#define Lctype       F->temp_32[2]\n#define Lpropvalue   F->temp_32[3]\n\n    case OP_TYPEEXACT:\n    Lmin = Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATTYPE;\n\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    reptype = (*Fecode == OP_TYPEMINUPTO)? REPTYPE_MIN : REPTYPE_MAX;\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATTYPE;\n\n    case OP_TYPEPOSSTAR:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATTYPE;\n\n    case OP_TYPEPOSPLUS:\n    reptype = REPTYPE_POS;\n    Lmin = 1;\n    Lmax = UINT32_MAX;\n    Fecode++;\n    goto REPEATTYPE;\n\n    case OP_TYPEPOSQUERY:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = 1;\n    Fecode++;\n    goto REPEATTYPE;\n\n    case OP_TYPEPOSUPTO:\n    reptype = REPTYPE_POS;\n    Lmin = 0;\n    Lmax = GET2(Fecode, 1);\n    Fecode += 1 + IMM2_SIZE;\n    goto REPEATTYPE;\n\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    fc = *Fecode++ - OP_TYPESTAR;\n    Lmin = rep_min[fc];\n    Lmax = rep_max[fc];\n    reptype = rep_typ[fc];\n\n    /* Common code for all repeated character type matches. */\n\n    REPEATTYPE:\n    Lctype = *Fecode++;      /* Code for the character type */\n\n#ifdef SUPPORT_UNICODE\n    if (Lctype == OP_PROP || Lctype == OP_NOTPROP)\n      {\n      proptype = *Fecode++;\n      Lpropvalue = *Fecode++;\n      }\n    else proptype = -1;\n#endif\n\n    /* First, ensure the minimum number of matches are present. Use inline\n    code for maximizing the speed, and do the type test once at the start\n    (i.e. keep it out of the loops). As there are no calls to RMATCH in the\n    loops, we can use an ordinary variable for \"notmatch\". The code for UTF\n    mode is separated out for tidiness, except for Unicode property tests. */\n\n    if (Lmin > 0)\n      {\n#ifdef SUPPORT_UNICODE\n      if (proptype >= 0)  /* Property tests in all modes */\n        {\n        BOOL notmatch = Lctype == OP_NOTPROP;\n        switch(proptype)\n          {\n          case PT_LAMP:\n          for (i = 1; i <= Lmin; i++)\n            {\n            int chartype;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            chartype = UCD_CHARTYPE(fc);\n            if ((chartype == ucp_Lu ||\n                 chartype == ucp_Ll ||\n                 chartype == ucp_Lt) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_GC:\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_PC:\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_SC:\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_SCX:\n          for (i = 1; i <= Lmin; i++)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            prop = GET_UCD(fc);\n            ok = (prop->script == Lpropvalue ||\n                  MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);\n            if (ok == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_ALNUM:\n          for (i = 1; i <= Lmin; i++)\n            {\n            int category;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            category = UCD_CATEGORY(fc);\n            if ((category == ucp_L || category == ucp_N) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            switch(fc)\n              {\n              HSPACE_CASES:\n              VSPACE_CASES:\n              if (notmatch) RRETURN(MATCH_NOMATCH);\n              break;\n\n              default:\n              if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)\n                RRETURN(MATCH_NOMATCH);\n              break;\n              }\n            }\n          break;\n\n          case PT_WORD:\n          for (i = 1; i <= Lmin; i++)\n            {\n            int chartype, category;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            chartype = UCD_CHARTYPE(fc);\n            category = PRIV(ucp_gentype)[chartype];\n            if ((category == ucp_L || category == ucp_N ||\n                 chartype == ucp_Mn || chartype == ucp_Pc) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_CLIST:\n          for (i = 1; i <= Lmin; i++)\n            {\n            const uint32_t *cp;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n#if PCRE2_CODE_UNIT_WIDTH == 32\n            if (fc > MAX_UTF_CODE_POINT)\n              {\n              if (notmatch) continue;\n              RRETURN(MATCH_NOMATCH);\n              }\n#endif\n            cp = PRIV(ucd_caseless_sets) + Lpropvalue;\n            for (;;)\n              {\n              if (fc < *cp)\n                {\n                if (notmatch) break;\n                RRETURN(MATCH_NOMATCH);\n                }\n              if (fc == *cp++)\n                {\n                if (notmatch) RRETURN(MATCH_NOMATCH);\n                break;\n                }\n              }\n            }\n          break;\n\n          case PT_UCNC:\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||\n                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||\n                 fc >= 0xe000) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_BIDICL:\n          for (i = 1; i <= Lmin; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          case PT_BOOL:\n          for (i = 1; i <= Lmin; i++)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            prop = GET_UCD(fc);\n            ok = MAPBIT(PRIV(ucd_boolprop_sets) +\n              UCD_BPROPS_PROP(prop), Lpropvalue) != 0;\n            if (ok == notmatch)\n              RRETURN(MATCH_NOMATCH);\n            }\n          break;\n\n          /* This should not occur */\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return PCRE2_ERROR_INTERNAL;\n          /* LCOV_EXCL_STOP */\n          }\n        }\n\n      /* Match extended Unicode sequences. We will get here only if the\n      support is in the binary; otherwise a compile-time error occurs. */\n\n      else if (Lctype == OP_EXTUNI)\n        {\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          else\n            {\n            GETCHARINCTEST(fc, Feptr);\n            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,\n              mb->end_subject, utf, NULL);\n            }\n          CHECK_PARTIAL();\n          }\n        }\n      else\n#endif     /* SUPPORT_UNICODE */\n\n/* Handle all other cases in UTF mode */\n\n#ifdef SUPPORT_UNICODE\n      if (utf) switch(Lctype)\n        {\n        case OP_ANY:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);\n          if (mb->partial != 0 &&\n              Feptr + 1 >= mb->end_subject &&\n              NLBLOCK->nltype == NLTYPE_FIXED &&\n              NLBLOCK->nllen == 2 &&\n              UCHAR21(Feptr) == NLBLOCK->nl[0])\n            {\n            mb->hitend = TRUE;\n            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n            }\n          Feptr++;\n          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n          }\n        break;\n\n        case OP_ALLANY:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          Feptr++;\n          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n          }\n        break;\n\n        case OP_ANYBYTE:\n        if (Feptr > mb->end_subject - Lmin) RRETURN(MATCH_NOMATCH);\n        Feptr += Lmin;\n        break;\n\n        case OP_ANYNL:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          switch(fc)\n            {\n            default: RRETURN(MATCH_NOMATCH);\n\n            case CHAR_CR:\n            if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;\n            break;\n\n            case CHAR_LF:\n            break;\n\n            case CHAR_VT:\n            case CHAR_FF:\n            case CHAR_NEL:\n#ifndef EBCDIC\n            case 0x2028:\n            case 0x2029:\n#endif  /* Not EBCDIC */\n            if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);\n            break;\n            }\n          }\n        break;\n\n        case OP_NOT_HSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          switch(fc)\n            {\n            HSPACE_CASES: RRETURN(MATCH_NOMATCH);\n            default: break;\n            }\n          }\n        break;\n\n        case OP_HSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          switch(fc)\n            {\n            HSPACE_CASES: break;\n            default: RRETURN(MATCH_NOMATCH);\n            }\n          }\n        break;\n\n        case OP_NOT_VSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          switch(fc)\n            {\n            VSPACE_CASES: RRETURN(MATCH_NOMATCH);\n            default: break;\n            }\n          }\n        break;\n\n        case OP_VSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          switch(fc)\n            {\n            VSPACE_CASES: break;\n            default: RRETURN(MATCH_NOMATCH);\n            }\n          }\n        break;\n\n        case OP_NOT_DIGIT:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          GETCHARINC(fc, Feptr);\n          if (fc < 128 && (mb->ctypes[fc] & ctype_digit) != 0)\n            RRETURN(MATCH_NOMATCH);\n          }\n        break;\n\n        case OP_DIGIT:\n        for (i = 1; i <= Lmin; i++)\n          {\n          uint32_t cc;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21(Feptr);\n          if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          /* No need to skip more code units - we know it has only one. */\n          }\n        break;\n\n        case OP_NOT_WHITESPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          uint32_t cc;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21(Feptr);\n          if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n          }\n        break;\n\n        case OP_WHITESPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          uint32_t cc;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21(Feptr);\n          if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          /* No need to skip more code units - we know it has only one. */\n          }\n        break;\n\n        case OP_NOT_WORDCHAR:\n        for (i = 1; i <= Lmin; i++)\n          {\n          uint32_t cc;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21(Feptr);\n          if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n          }\n        break;\n\n        case OP_WORDCHAR:\n        for (i = 1; i <= Lmin; i++)\n          {\n          uint32_t cc;\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          cc = UCHAR21(Feptr);\n          if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          /* No need to skip more code units - we know it has only one. */\n          }\n        break;\n\n        /* LCOV_EXCL_START */\n        default:\n        PCRE2_DEBUG_UNREACHABLE();\n        return PCRE2_ERROR_INTERNAL;\n        /* LCOV_EXCL_STOP */\n        }  /* End switch(Lctype) */\n\n      else\n#endif     /* SUPPORT_UNICODE */\n\n      /* Code for the non-UTF case for minimum matching of operators other\n      than OP_PROP and OP_NOTPROP. */\n\n      switch(Lctype)\n        {\n        case OP_ANY:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);\n          if (mb->partial != 0 &&\n              Feptr + 1 >= mb->end_subject &&\n              NLBLOCK->nltype == NLTYPE_FIXED &&\n              NLBLOCK->nllen == 2 &&\n              *Feptr == NLBLOCK->nl[0])\n            {\n            mb->hitend = TRUE;\n            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n            }\n          Feptr++;\n          }\n        break;\n\n        case OP_ALLANY:\n        if (Feptr > mb->end_subject - Lmin)\n          {\n          SCHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        Feptr += Lmin;\n        break;\n\n        /* This OP_ANYBYTE case will never be reached because \\C gets turned\n        into OP_ALLANY in non-UTF mode. Cut out the code so that coverage\n        reports don't complain about it's never being used. */\n\n/*        case OP_ANYBYTE:\n*        if (Feptr > mb->end_subject - Lmin)\n*          {\n*          SCHECK_PARTIAL();\n*          RRETURN(MATCH_NOMATCH);\n*          }\n*        Feptr += Lmin;\n*        break;\n*/\n        case OP_ANYNL:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          switch(*Feptr++)\n            {\n            default: RRETURN(MATCH_NOMATCH);\n\n            case CHAR_CR:\n            if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;\n            break;\n\n            case CHAR_LF:\n            break;\n\n            case CHAR_VT:\n            case CHAR_FF:\n            case CHAR_NEL:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            case 0x2028:\n            case 0x2029:\n#endif\n            if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);\n            break;\n            }\n          }\n        break;\n\n        case OP_NOT_HSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          switch(*Feptr++)\n            {\n            default: break;\n            HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            HSPACE_MULTIBYTE_CASES:\n#endif\n            RRETURN(MATCH_NOMATCH);\n            }\n          }\n        break;\n\n        case OP_HSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          switch(*Feptr++)\n            {\n            default: RRETURN(MATCH_NOMATCH);\n            HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            HSPACE_MULTIBYTE_CASES:\n#endif\n            break;\n            }\n          }\n        break;\n\n        case OP_NOT_VSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          switch(*Feptr++)\n            {\n            VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            VSPACE_MULTIBYTE_CASES:\n#endif\n            RRETURN(MATCH_NOMATCH);\n            default: break;\n            }\n          }\n        break;\n\n        case OP_VSPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          switch(*Feptr++)\n            {\n            default: RRETURN(MATCH_NOMATCH);\n            VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            VSPACE_MULTIBYTE_CASES:\n#endif\n            break;\n            }\n          }\n        break;\n\n        case OP_NOT_DIGIT:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        case OP_DIGIT:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        case OP_NOT_WHITESPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        case OP_WHITESPACE:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        case OP_NOT_WORDCHAR:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        case OP_WORDCHAR:\n        for (i = 1; i <= Lmin; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)\n            RRETURN(MATCH_NOMATCH);\n          Feptr++;\n          }\n        break;\n\n        /* LCOV_EXCL_START */\n        default:\n        PCRE2_DEBUG_UNREACHABLE();\n        return PCRE2_ERROR_INTERNAL;\n        /* LCOV_EXCL_STOP */\n        }\n      }\n\n    /* If Lmin = Lmax we are done. Continue with the main loop. */\n\n    if (Lmin == Lmax) continue;\n\n    /* If minimizing, we have to test the rest of the pattern before each\n    subsequent match. This means we cannot use a local \"notmatch\" variable as\n    in the other cases. As all 4 temporary 32-bit values in the frame are\n    already in use, just test the type each time. */\n\n    if (reptype == REPTYPE_MIN)\n      {\n#ifdef SUPPORT_UNICODE\n      if (proptype >= 0)\n        {\n        switch(proptype)\n          {\n          case PT_LAMP:\n          for (;;)\n            {\n            int chartype;\n            RMATCH(Fecode, RM208);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            chartype = UCD_CHARTYPE(fc);\n            if ((chartype == ucp_Lu ||\n                 chartype == ucp_Ll ||\n                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_GC:\n          for (;;)\n            {\n            RMATCH(Fecode, RM209);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_PC:\n          for (;;)\n            {\n            RMATCH(Fecode, RM210);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_SC:\n          for (;;)\n            {\n            RMATCH(Fecode, RM211);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_SCX:\n          for (;;)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            RMATCH(Fecode, RM224);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            prop = GET_UCD(fc);\n            ok = (prop->script == Lpropvalue\n                  || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);\n            if (ok == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_ALNUM:\n          for (;;)\n            {\n            int category;\n            RMATCH(Fecode, RM212);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            category = UCD_CATEGORY(fc);\n            if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          for (;;)\n            {\n            RMATCH(Fecode, RM213);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            switch(fc)\n              {\n              HSPACE_CASES:\n              VSPACE_CASES:\n              if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);\n              break;\n\n              default:\n              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))\n                RRETURN(MATCH_NOMATCH);\n              break;\n              }\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_WORD:\n          for (;;)\n            {\n            int chartype, category;\n            RMATCH(Fecode, RM214);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            chartype = UCD_CHARTYPE(fc);\n            category = PRIV(ucp_gentype)[chartype];\n            if ((category == ucp_L ||\n                 category == ucp_N ||\n                 chartype == ucp_Mn ||\n                 chartype == ucp_Pc) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_CLIST:\n          for (;;)\n            {\n            const uint32_t *cp;\n            RMATCH(Fecode, RM215);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n#if PCRE2_CODE_UNIT_WIDTH == 32\n            if (fc > MAX_UTF_CODE_POINT)\n              {\n              if (Lctype == OP_NOTPROP) continue;\n              RRETURN(MATCH_NOMATCH);\n              }\n#endif\n            cp = PRIV(ucd_caseless_sets) + Lpropvalue;\n            for (;;)\n              {\n              if (fc < *cp)\n                {\n                if (Lctype == OP_NOTPROP) break;\n                RRETURN(MATCH_NOMATCH);\n                }\n              if (fc == *cp++)\n                {\n                if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);\n                break;\n                }\n              }\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_UCNC:\n          for (;;)\n            {\n            RMATCH(Fecode, RM216);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||\n                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||\n                 fc >= 0xe000) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_BIDICL:\n          for (;;)\n            {\n            RMATCH(Fecode, RM223);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            if ((UCD_BIDICLASS(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          case PT_BOOL:\n          for (;;)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            RMATCH(Fecode, RM222);\n            if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              RRETURN(MATCH_NOMATCH);\n              }\n            GETCHARINCTEST(fc, Feptr);\n            prop = GET_UCD(fc);\n            ok = MAPBIT(PRIV(ucd_boolprop_sets) +\n              UCD_BPROPS_PROP(prop), Lpropvalue) != 0;\n            if (ok == (Lctype == OP_NOTPROP))\n              RRETURN(MATCH_NOMATCH);\n            }\n          PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n          /* This should never occur */\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return PCRE2_ERROR_INTERNAL;\n          /* LCOV_EXCL_STOP */\n          }\n        }\n\n      /* Match extended Unicode sequences. We will get here only if the\n      support is in the binary; otherwise a compile-time error occurs. */\n\n      else if (Lctype == OP_EXTUNI)\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM217);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          else\n            {\n            GETCHARINCTEST(fc, Feptr);\n            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,\n              utf, NULL);\n            }\n          CHECK_PARTIAL();\n          }\n        }\n      else\n#endif     /* SUPPORT_UNICODE */\n\n      /* UTF mode for non-property testing character types. */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM218);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (Lctype == OP_ANY && IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);\n          GETCHARINC(fc, Feptr);\n          switch(Lctype)\n            {\n            case OP_ANY:               /* This is the non-NL case */\n            if (mb->partial != 0 &&    /* Take care with CRLF partial */\n                Feptr >= mb->end_subject &&\n                NLBLOCK->nltype == NLTYPE_FIXED &&\n                NLBLOCK->nllen == 2 &&\n                fc == NLBLOCK->nl[0])\n              {\n              mb->hitend = TRUE;\n              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n              }\n            break;\n\n            case OP_ALLANY:\n            case OP_ANYBYTE:\n            break;\n\n            case OP_ANYNL:\n            switch(fc)\n              {\n              default: RRETURN(MATCH_NOMATCH);\n\n              case CHAR_CR:\n              if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;\n              break;\n\n              case CHAR_LF:\n              break;\n\n              case CHAR_VT:\n              case CHAR_FF:\n              case CHAR_NEL:\n#ifndef EBCDIC\n              case 0x2028:\n              case 0x2029:\n#endif  /* Not EBCDIC */\n              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)\n                RRETURN(MATCH_NOMATCH);\n              break;\n              }\n            break;\n\n            case OP_NOT_HSPACE:\n            switch(fc)\n              {\n              HSPACE_CASES: RRETURN(MATCH_NOMATCH);\n              default: break;\n              }\n            break;\n\n            case OP_HSPACE:\n            switch(fc)\n              {\n              HSPACE_CASES: break;\n              default: RRETURN(MATCH_NOMATCH);\n              }\n            break;\n\n            case OP_NOT_VSPACE:\n            switch(fc)\n              {\n              VSPACE_CASES: RRETURN(MATCH_NOMATCH);\n              default: break;\n              }\n            break;\n\n            case OP_VSPACE:\n            switch(fc)\n              {\n              VSPACE_CASES: break;\n              default: RRETURN(MATCH_NOMATCH);\n              }\n            break;\n\n            case OP_NOT_DIGIT:\n            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_DIGIT:\n            if (fc >= 256 || (mb->ctypes[fc] & ctype_digit) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_NOT_WHITESPACE:\n            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_WHITESPACE:\n            if (fc >= 256 || (mb->ctypes[fc] & ctype_space) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_NOT_WORDCHAR:\n            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_WORDCHAR:\n            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            /* LCOV_EXCL_START */\n            default:\n            PCRE2_DEBUG_UNREACHABLE();\n            return PCRE2_ERROR_INTERNAL;\n            /* LCOV_EXCL_STOP */\n            }\n          }\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n\n      /* Not UTF mode */\n        {\n        for (;;)\n          {\n          RMATCH(Fecode, RM33);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            RRETURN(MATCH_NOMATCH);\n            }\n          if (Lctype == OP_ANY && IS_NEWLINE(Feptr))\n            RRETURN(MATCH_NOMATCH);\n          fc = *Feptr++;\n          switch(Lctype)\n            {\n            case OP_ANY:               /* This is the non-NL case */\n            if (mb->partial != 0 &&    /* Take care with CRLF partial */\n                Feptr >= mb->end_subject &&\n                NLBLOCK->nltype == NLTYPE_FIXED &&\n                NLBLOCK->nllen == 2 &&\n                fc == NLBLOCK->nl[0])\n              {\n              mb->hitend = TRUE;\n              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n              }\n            break;\n\n            case OP_ALLANY:\n            case OP_ANYBYTE:\n            break;\n\n            case OP_ANYNL:\n            switch(fc)\n              {\n              default: RRETURN(MATCH_NOMATCH);\n\n              case CHAR_CR:\n              if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;\n              break;\n\n              case CHAR_LF:\n              break;\n\n              case CHAR_VT:\n              case CHAR_FF:\n              case CHAR_NEL:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              case 0x2028:\n              case 0x2029:\n#endif\n              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)\n                RRETURN(MATCH_NOMATCH);\n              break;\n              }\n            break;\n\n            case OP_NOT_HSPACE:\n            switch(fc)\n              {\n              default: break;\n              HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              HSPACE_MULTIBYTE_CASES:\n#endif\n              RRETURN(MATCH_NOMATCH);\n              }\n            break;\n\n            case OP_HSPACE:\n            switch(fc)\n              {\n              default: RRETURN(MATCH_NOMATCH);\n              HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              HSPACE_MULTIBYTE_CASES:\n#endif\n              break;\n              }\n            break;\n\n            case OP_NOT_VSPACE:\n            switch(fc)\n              {\n              default: break;\n              VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              VSPACE_MULTIBYTE_CASES:\n#endif\n              RRETURN(MATCH_NOMATCH);\n              }\n            break;\n\n            case OP_VSPACE:\n            switch(fc)\n              {\n              default: RRETURN(MATCH_NOMATCH);\n              VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              VSPACE_MULTIBYTE_CASES:\n#endif\n              break;\n              }\n            break;\n\n            case OP_NOT_DIGIT:\n            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_DIGIT:\n            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_NOT_WHITESPACE:\n            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_WHITESPACE:\n            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_NOT_WORDCHAR:\n            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            case OP_WORDCHAR:\n            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)\n              RRETURN(MATCH_NOMATCH);\n            break;\n\n            /* LCOV_EXCL_START */\n            default:\n            PCRE2_DEBUG_UNREACHABLE();\n            return PCRE2_ERROR_INTERNAL;\n            /* LCOV_EXCL_STOP */\n            }\n          }\n        }\n\n      PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\n      }\n\n    /* If maximizing, it is worth using inline code for speed, doing the type\n    test once at the start (i.e. keep it out of the loops). Once again,\n    \"notmatch\" can be an ordinary local variable because the loops do not call\n    RMATCH. */\n\n    else\n      {\n      Lstart_eptr = Feptr;  /* Remember where we started */\n\n#ifdef SUPPORT_UNICODE\n      if (proptype >= 0)\n        {\n        BOOL notmatch = Lctype == OP_NOTPROP;\n        switch(proptype)\n          {\n          case PT_LAMP:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int chartype;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            chartype = UCD_CHARTYPE(fc);\n            if ((chartype == ucp_Lu ||\n                 chartype == ucp_Ll ||\n                 chartype == ucp_Lt) == notmatch)\n              break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_GC:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_PC:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_SC:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_SCX:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            prop = GET_UCD(fc);\n            ok = (prop->script == Lpropvalue ||\n                  MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);\n            if (ok == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_ALNUM:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int category;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            category = UCD_CATEGORY(fc);\n            if ((category == ucp_L || category == ucp_N) == notmatch)\n              break;\n            Feptr+= len;\n            }\n          break;\n\n          /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n          which means that Perl space and POSIX space are now identical. PCRE\n          was changed at release 8.34. */\n\n          case PT_SPACE:    /* Perl space */\n          case PT_PXSPACE:  /* POSIX space */\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            switch(fc)\n              {\n              HSPACE_CASES:\n              VSPACE_CASES:\n              if (notmatch) goto ENDLOOP99;  /* Break the loop */\n              break;\n\n              default:\n              if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)\n                goto ENDLOOP99;   /* Break the loop */\n              break;\n              }\n            Feptr+= len;\n            }\n          ENDLOOP99:\n          break;\n\n          case PT_WORD:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int chartype, category;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            chartype = UCD_CHARTYPE(fc);\n            category = PRIV(ucp_gentype)[chartype];\n            if ((category == ucp_L ||\n                 category == ucp_N ||\n                 chartype == ucp_Mn ||\n                 chartype == ucp_Pc) == notmatch)\n              break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_CLIST:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            const uint32_t *cp;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n#if PCRE2_CODE_UNIT_WIDTH == 32\n            if (fc > MAX_UTF_CODE_POINT)\n              {\n              if (!notmatch) goto GOT_MAX;\n              }\n            else\n#endif\n              {\n              cp = PRIV(ucd_caseless_sets) + Lpropvalue;\n              for (;;)\n                {\n                if (fc < *cp)\n                  { if (notmatch) break; else goto GOT_MAX; }\n                if (fc == *cp++)\n                  { if (notmatch) goto GOT_MAX; else break; }\n                }\n              }\n\n            Feptr += len;\n            }\n          GOT_MAX:\n          break;\n\n          case PT_UCNC:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||\n                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||\n                 fc >= 0xe000) == notmatch)\n              break;\n            Feptr += len;\n            }\n          break;\n\n          case PT_BIDICL:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          case PT_BOOL:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            BOOL ok;\n            const ucd_record *prop;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLENTEST(fc, Feptr, len);\n            prop = GET_UCD(fc);\n            ok = MAPBIT(PRIV(ucd_boolprop_sets) +\n              UCD_BPROPS_PROP(prop), Lpropvalue) != 0;\n            if (ok == notmatch) break;\n            Feptr+= len;\n            }\n          break;\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return PCRE2_ERROR_INTERNAL;\n          /* LCOV_EXCL_STOP */\n          }\n\n        /* Feptr is now past the end of the maximum run */\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't\n        go too far. */\n\n        for(;;)\n          {\n          if (Feptr <= Lstart_eptr) break;\n          RMATCH(Fecode, RM221);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          Feptr--;\n          if (utf) BACKCHAR(Feptr);\n          }\n        }\n\n      /* Match extended Unicode grapheme clusters. We will get here only if the\n      support is in the binary; otherwise a compile-time error occurs. */\n\n      else if (Lctype == OP_EXTUNI)\n        {\n        for (i = Lmin; i < Lmax; i++)\n          {\n          if (Feptr >= mb->end_subject)\n            {\n            SCHECK_PARTIAL();\n            break;\n            }\n          else\n            {\n            GETCHARINCTEST(fc, Feptr);\n            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,\n              utf, NULL);\n            }\n          CHECK_PARTIAL();\n          }\n\n        /* Feptr is now past the end of the maximum run */\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        /* We use <= Lstart_eptr rather than == Lstart_eptr to detect the start\n        of the run while backtracking because the use of \\C in UTF mode can\n        cause BACKCHAR to move back past Lstart_eptr. This is just palliative;\n        the use of \\C in UTF mode is fraught with danger. */\n\n        for(;;)\n          {\n          int lgb, rgb;\n          PCRE2_SPTR fptr;\n\n          if (Feptr <= Lstart_eptr) break;   /* At start of char run */\n          RMATCH(Fecode, RM219);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n\n          /* Backtracking over an extended grapheme cluster involves inspecting\n          the previous two characters (if present) to see if a break is\n          permitted between them. */\n\n          Feptr--;\n          if (!utf) fc = *Feptr; else\n            {\n            BACKCHAR(Feptr);\n            GETCHAR(fc, Feptr);\n            }\n          rgb = UCD_GRAPHBREAK(fc);\n\n          for (;;)\n            {\n            if (Feptr <= Lstart_eptr) break;   /* At start of char run */\n            fptr = Feptr - 1;\n            if (!utf) fc = *fptr; else\n              {\n              BACKCHAR(fptr);\n              GETCHAR(fc, fptr);\n              }\n            lgb = UCD_GRAPHBREAK(fc);\n            if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;\n            Feptr = fptr;\n            rgb = lgb;\n            }\n          }\n        }\n\n      else\n#endif   /* SUPPORT_UNICODE */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        switch(Lctype)\n          {\n          case OP_ANY:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (IS_NEWLINE(Feptr)) break;\n            if (mb->partial != 0 &&    /* Take care with CRLF partial */\n                Feptr + 1 >= mb->end_subject &&\n                NLBLOCK->nltype == NLTYPE_FIXED &&\n                NLBLOCK->nllen == 2 &&\n                UCHAR21(Feptr) == NLBLOCK->nl[0])\n              {\n              mb->hitend = TRUE;\n              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n              }\n            Feptr++;\n            ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n            }\n          break;\n\n          case OP_ALLANY:\n          if (Lmax < UINT32_MAX)\n            {\n            for (i = Lmin; i < Lmax; i++)\n              {\n              if (Feptr >= mb->end_subject)\n                {\n                SCHECK_PARTIAL();\n                break;\n                }\n              Feptr++;\n              ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);\n              }\n            }\n          else\n            {\n            Feptr = mb->end_subject;   /* Unlimited UTF-8 repeat */\n            SCHECK_PARTIAL();\n            }\n          break;\n\n          /* The \"byte\" (i.e. \"code unit\") case is the same as non-UTF */\n\n          case OP_ANYBYTE:\n          fc = Lmax - Lmin;\n          if (fc > (uint32_t)(mb->end_subject - Feptr))\n            {\n            Feptr = mb->end_subject;\n            SCHECK_PARTIAL();\n            }\n          else Feptr += fc;\n          break;\n\n          case OP_ANYNL:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc == CHAR_CR)\n              {\n              if (++Feptr >= mb->end_subject) break;\n              if (UCHAR21(Feptr) == CHAR_LF) Feptr++;\n              }\n            else\n              {\n              if (fc != CHAR_LF &&\n                  (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||\n                   (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL\n#ifndef EBCDIC\n                    && fc != 0x2028 && fc != 0x2029\n#endif  /* Not EBCDIC */\n                    )))\n                break;\n              Feptr += len;\n              }\n            }\n          break;\n\n          case OP_NOT_HSPACE:\n          case OP_HSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            BOOL gotspace;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            switch(fc)\n              {\n              HSPACE_CASES: gotspace = TRUE; break;\n              default: gotspace = FALSE; break;\n              }\n            if (gotspace == (Lctype == OP_NOT_HSPACE)) break;\n            Feptr += len;\n            }\n          break;\n\n          case OP_NOT_VSPACE:\n          case OP_VSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            BOOL gotspace;\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            switch(fc)\n              {\n              VSPACE_CASES: gotspace = TRUE; break;\n              default: gotspace = FALSE; break;\n              }\n            if (gotspace == (Lctype == OP_NOT_VSPACE)) break;\n            Feptr += len;\n            }\n          break;\n\n          case OP_NOT_DIGIT:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          case OP_DIGIT:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc >= 256 ||(mb->ctypes[fc] & ctype_digit) == 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          case OP_NOT_WHITESPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          case OP_WHITESPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc >= 256 ||(mb->ctypes[fc] & ctype_space) == 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          case OP_NOT_WORDCHAR:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          case OP_WORDCHAR:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            int len = 1;\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            GETCHARLEN(fc, Feptr, len);\n            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0) break;\n            Feptr+= len;\n            }\n          break;\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return PCRE2_ERROR_INTERNAL;\n          /* LCOV_EXCL_STOP */\n          }\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        /* After \\C in UTF mode, Lstart_eptr might be in the middle of a\n        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't go\n        too far. */\n\n        for(;;)\n          {\n          if (Feptr <= Lstart_eptr) break;\n          RMATCH(Fecode, RM220);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          Feptr--;\n          BACKCHAR(Feptr);\n          if (Lctype == OP_ANYNL && Feptr > Lstart_eptr &&\n              UCHAR21(Feptr) == CHAR_NL && UCHAR21(Feptr - 1) == CHAR_CR)\n            Feptr--;\n          }\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n\n      /* Not UTF mode */\n        {\n        switch(Lctype)\n          {\n          case OP_ANY:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (IS_NEWLINE(Feptr)) break;\n            if (mb->partial != 0 &&    /* Take care with CRLF partial */\n                Feptr + 1 >= mb->end_subject &&\n                NLBLOCK->nltype == NLTYPE_FIXED &&\n                NLBLOCK->nllen == 2 &&\n                *Feptr == NLBLOCK->nl[0])\n              {\n              mb->hitend = TRUE;\n              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n              }\n            Feptr++;\n            }\n          break;\n\n          case OP_ALLANY:\n          case OP_ANYBYTE:\n          fc = Lmax - Lmin;\n          if (fc > (uint32_t)(mb->end_subject - Feptr))\n            {\n            Feptr = mb->end_subject;\n            SCHECK_PARTIAL();\n            }\n          else Feptr += fc;\n          break;\n\n          case OP_ANYNL:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            fc = *Feptr;\n            if (fc == CHAR_CR)\n              {\n              if (++Feptr >= mb->end_subject) break;\n              if (*Feptr == CHAR_LF) Feptr++;\n              }\n            else\n              {\n              if (fc != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||\n                 (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL\n#if PCRE2_CODE_UNIT_WIDTH != 8\n                 && fc != 0x2028 && fc != 0x2029\n#endif\n                 ))) break;\n              Feptr++;\n              }\n            }\n          break;\n\n          case OP_NOT_HSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            switch(*Feptr)\n              {\n              default: Feptr++; break;\n              HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              HSPACE_MULTIBYTE_CASES:\n#endif\n              goto ENDLOOP00;\n              }\n            }\n          ENDLOOP00:\n          break;\n\n          case OP_HSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            switch(*Feptr)\n              {\n              default: goto ENDLOOP01;\n              HSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              HSPACE_MULTIBYTE_CASES:\n#endif\n              Feptr++; break;\n              }\n            }\n          ENDLOOP01:\n          break;\n\n          case OP_NOT_VSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            switch(*Feptr)\n              {\n              default: Feptr++; break;\n              VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              VSPACE_MULTIBYTE_CASES:\n#endif\n              goto ENDLOOP02;\n              }\n            }\n          ENDLOOP02:\n          break;\n\n          case OP_VSPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            switch(*Feptr)\n              {\n              default: goto ENDLOOP03;\n              VSPACE_BYTE_CASES:\n#if PCRE2_CODE_UNIT_WIDTH != 8\n              VSPACE_MULTIBYTE_CASES:\n#endif\n              Feptr++; break;\n              }\n            }\n          ENDLOOP03:\n          break;\n\n          case OP_NOT_DIGIT:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          case OP_DIGIT:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          case OP_NOT_WHITESPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          case OP_WHITESPACE:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          case OP_NOT_WORDCHAR:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          case OP_WORDCHAR:\n          for (i = Lmin; i < Lmax; i++)\n            {\n            if (Feptr >= mb->end_subject)\n              {\n              SCHECK_PARTIAL();\n              break;\n              }\n            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)\n              break;\n            Feptr++;\n            }\n          break;\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return PCRE2_ERROR_INTERNAL;\n          /* LCOV_EXCL_STOP */\n          }\n\n        if (reptype == REPTYPE_POS) continue;    /* No backtracking */\n\n        for (;;)\n          {\n          if (Feptr == Lstart_eptr) break;\n          RMATCH(Fecode, RM34);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          Feptr--;\n          if (Lctype == OP_ANYNL && Feptr > Lstart_eptr && *Feptr == CHAR_LF &&\n              Feptr[-1] == CHAR_CR) Feptr--;\n          }\n        }\n      }\n    break;  /* End of repeat character type processing */\n\n#undef Lstart_eptr\n#undef Lmin\n#undef Lmax\n#undef Lctype\n#undef Lpropvalue\n\n\n    /* ===================================================================== */\n    /* Match a back reference, possibly repeatedly. Look past the end of the\n    item to see if there is repeat information following. The OP_REF and\n    OP_REFI opcodes are used for a reference to a numbered group or to a\n    non-duplicated named group. For a duplicated named group, OP_DNREF and\n    OP_DNREFI are used. In this case we must scan the list of groups to which\n    the name refers, and use the first one that is set. */\n\n#define Lmin      F->temp_32[0]\n#define Lmax      F->temp_32[1]\n#define Lcaseless F->temp_32[2]\n#define Lcaseopts F->temp_32[3]\n#define Lstart    F->temp_sptr[0]\n#define Loffset   F->temp_size\n\n    case OP_DNREF:\n    case OP_DNREFI:\n    Lcaseless = (Fop == OP_DNREFI);\n    Lcaseopts = (Fop == OP_DNREFI)? Fecode[1 + 2*IMM2_SIZE] : 0;\n      {\n      int count = GET2(Fecode, 1+IMM2_SIZE);\n      PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;\n      Fecode += 1 + 2*IMM2_SIZE + (Fop == OP_DNREFI? 1 : 0);\n\n      while (count-- > 0)\n        {\n        Loffset = (GET2(slot, 0) << 1) - 2;\n        if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET) break;\n        slot += mb->name_entry_size;\n        }\n      }\n    goto REF_REPEAT;\n\n    case OP_REF:\n    case OP_REFI:\n    Lcaseless = (Fop == OP_REFI);\n    Lcaseopts = (Fop == OP_REFI)? Fecode[1 + IMM2_SIZE] : 0;\n    Loffset = (GET2(Fecode, 1) << 1) - 2;\n    Fecode += 1 + IMM2_SIZE + (Fop == OP_REFI? 1 : 0);\n\n    /* Set up for repetition, or handle the non-repeated case. The maximum and\n    minimum must be in the heap frame, but as they are short-term values, we\n    use temporary fields. */\n\n    REF_REPEAT:\n    switch (*Fecode)\n      {\n      case OP_CRSTAR:\n      case OP_CRMINSTAR:\n      case OP_CRPLUS:\n      case OP_CRMINPLUS:\n      case OP_CRQUERY:\n      case OP_CRMINQUERY:\n      fc = *Fecode++ - OP_CRSTAR;\n      Lmin = rep_min[fc];\n      Lmax = rep_max[fc];\n      reptype = rep_typ[fc];\n      break;\n\n      case OP_CRRANGE:\n      case OP_CRMINRANGE:\n      Lmin = GET2(Fecode, 1);\n      Lmax = GET2(Fecode, 1 + IMM2_SIZE);\n      reptype = rep_typ[*Fecode - OP_CRSTAR];\n      if (Lmax == 0) Lmax = UINT32_MAX;  /* Max 0 => infinity */\n      Fecode += 1 + 2 * IMM2_SIZE;\n      break;\n\n      default:                  /* No repeat follows */\n        {\n        rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &length);\n        if (rrc != 0)\n          {\n          if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */\n          CHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        }\n      Feptr += length;\n      continue;              /* With the main loop */\n      }\n\n    /* Handle repeated back references. If a set group has length zero, just\n    continue with the main loop, because it matches however many times. For an\n    unset reference, if the minimum is zero, we can also just continue. We can\n    also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset\n    group behave as a zero-length group. For any other unset cases, carrying\n    on will result in NOMATCH. */\n\n    if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET)\n      {\n      if (Fovector[Loffset] == Fovector[Loffset + 1]) continue;\n      }\n    else  /* Group is not set */\n      {\n      if (Lmin == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)\n        continue;\n      }\n\n    /* First, ensure the minimum number of matches are present. */\n\n    for (i = 1; i <= Lmin; i++)\n      {\n      PCRE2_SIZE slength;\n      rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength);\n      if (rrc != 0)\n        {\n        if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */\n        CHECK_PARTIAL();\n        RRETURN(MATCH_NOMATCH);\n        }\n      Feptr += slength;\n      }\n\n    /* If min = max, we are done. They are not both allowed to be zero. */\n\n    if (Lmin == Lmax) continue;\n\n    /* If minimizing, keep trying and advancing the pointer. */\n\n    if (reptype == REPTYPE_MIN)\n      {\n      for (;;)\n        {\n        PCRE2_SIZE slength;\n        RMATCH(Fecode, RM20);\n        if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n        if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);\n        rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength);\n        if (rrc != 0)\n          {\n          if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */\n          CHECK_PARTIAL();\n          RRETURN(MATCH_NOMATCH);\n          }\n        Feptr += slength;\n        }\n\n      PCRE2_UNREACHABLE(); /* Control never reaches here */\n      }\n\n    /* If maximizing, find the longest string and work backwards, as long as\n    the matched lengths for each iteration are the same. */\n\n    else\n      {\n      BOOL samelengths = TRUE;\n      Lstart = Feptr;     /* Starting position */\n      Flength = Fovector[Loffset+1] - Fovector[Loffset];\n\n      for (i = Lmin; i < Lmax; i++)\n        {\n        PCRE2_SIZE slength;\n        rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength);\n        if (rrc != 0)\n          {\n          /* Can't use CHECK_PARTIAL because we don't want to update Feptr in\n          the soft partial matching case. */\n\n          if (rrc > 0 && mb->partial != 0 &&\n              mb->end_subject > mb->start_used_ptr)\n            {\n            mb->hitend = TRUE;\n            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n            }\n          break;\n          }\n\n        if (slength != Flength) samelengths = FALSE;\n        Feptr += slength;\n        }\n\n      /* If the length matched for each repetition is the same as the length of\n      the captured group, we can easily work backwards. This is the normal\n      case. However, in caseless UTF-8 mode there are pairs of case-equivalent\n      characters whose lengths (in terms of code units) differ. However, this\n      is very rare, so we handle it by re-matching fewer and fewer times. */\n\n      if (samelengths)\n        {\n        while (Feptr >= Lstart)\n          {\n          RMATCH(Fecode, RM21);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          Feptr -= Flength;\n          }\n        }\n\n      /* The rare case of non-matching lengths. Re-scan the repetition for each\n      iteration. We know that match_ref() will succeed every time. */\n\n      else\n        {\n        Lmax = i;\n        for (;;)\n          {\n          RMATCH(Fecode, RM22);\n          if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n          if (Feptr == Lstart) break; /* Failed after minimal repetition */\n          Feptr = Lstart;\n          Lmax--;\n          for (i = Lmin; i < Lmax; i++)\n            {\n            PCRE2_SIZE slength;\n            (void)match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength);\n            Feptr += slength;\n            }\n          }\n        }\n\n      RRETURN(MATCH_NOMATCH);\n      }\n\n    PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\n\n#undef Lcaseless\n#undef Lmin\n#undef Lmax\n#undef Lstart\n#undef Loffset\n\n\n\n/* ========================================================================= */\n/*           Opcodes for the start of various parenthesized items            */\n/* ========================================================================= */\n\n    /* In all cases, if the result of RMATCH() is MATCH_THEN, check whether the\n    (*THEN) is within the current branch by comparing the address of OP_THEN\n    that is passed back with the end of the branch. If (*THEN) is within the\n    current branch, and the branch is one of two or more alternatives (it\n    either starts or ends with OP_ALT), we have reached the limit of THEN's\n    action, so convert the return code to NOMATCH, which will cause normal\n    backtracking to happen from now on. Otherwise, THEN is passed back to an\n    outer alternative. This implements Perl's treatment of parenthesized\n    groups, where a group not containing | does not affect the current\n    alternative, that is, (X) is NOT the same as (X|(*F)). */\n\n\n    /* ===================================================================== */\n    /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a non-possessive\n    bracket group, indicating that it may occur zero times. It may repeat\n    infinitely, or not at all - i.e. it could be ()* or ()? or even (){0} in\n    the pattern. Brackets with fixed upper repeat limits are compiled as a\n    number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO.\n    Possessive groups with possible zero repeats are preceded by BRAPOSZERO. */\n\n#define Lnext_ecode F->temp_sptr[0]\n\n    case OP_BRAZERO:\n    Lnext_ecode = Fecode + 1;\n    RMATCH(Lnext_ecode, RM9);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);\n    Fecode = Lnext_ecode + 1 + LINK_SIZE;\n    break;\n\n    case OP_BRAMINZERO:\n    Lnext_ecode = Fecode + 1;\n    do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);\n    RMATCH(Lnext_ecode + 1 + LINK_SIZE, RM10);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    Fecode++;\n    break;\n\n#undef Lnext_ecode\n\n    case OP_SKIPZERO:\n    Fecode++;\n    do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);\n    Fecode += 1 + LINK_SIZE;\n    break;\n\n\n    /* ===================================================================== */\n    /* Handle possessive brackets with an unlimited repeat. The end of these\n    brackets will always be OP_KETRPOS, which returns MATCH_KETRPOS without\n    going further in the pattern. */\n\n#define Lframe_type    F->temp_32[0]\n#define Lmatched_once  F->temp_32[1]\n#define Lzero_allowed  F->temp_32[2]\n#define Lstart_eptr    F->temp_sptr[0]\n#define Lstart_group   F->temp_sptr[1]\n\n    case OP_BRAPOSZERO:\n    Lzero_allowed = TRUE;                /* Zero repeat is allowed */\n    Fecode += 1;\n    if (*Fecode == OP_CBRAPOS || *Fecode == OP_SCBRAPOS)\n      goto POSSESSIVE_CAPTURE;\n    goto POSSESSIVE_NON_CAPTURE;\n\n    case OP_BRAPOS:\n    case OP_SBRAPOS:\n    Lzero_allowed = FALSE;               /* Zero repeat not allowed */\n\n    POSSESSIVE_NON_CAPTURE:\n    Lframe_type = GF_NOCAPTURE;          /* Remembered frame type */\n    goto POSSESSIVE_GROUP;\n\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    Lzero_allowed = FALSE;               /* Zero repeat not allowed */\n\n    POSSESSIVE_CAPTURE:\n    number = GET2(Fecode, 1+LINK_SIZE);\n    Lframe_type = GF_CAPTURE | number;   /* Remembered frame type */\n\n    POSSESSIVE_GROUP:\n    Lmatched_once = FALSE;               /* Never matched */\n    Lstart_group = Fecode;               /* Start of this group */\n\n    for (;;)\n      {\n      Lstart_eptr = Feptr;               /* Position at group start */\n      group_frame_type = Lframe_type;\n      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM8);\n      if (rrc == MATCH_KETRPOS)\n        {\n        Lmatched_once = TRUE;            /* Matched at least once */\n        if (Feptr == Lstart_eptr)        /* Empty match; skip to end */\n          {\n          do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);\n          break;\n          }\n\n        Fecode = Lstart_group;\n        continue;\n        }\n\n      /* See comment above about handling THEN. */\n\n      if (rrc == MATCH_THEN)\n        {\n        PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);\n        if (mb->verb_ecode_ptr < next_ecode &&\n            (*Fecode == OP_ALT || *next_ecode == OP_ALT))\n          rrc = MATCH_NOMATCH;\n        }\n\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      Fecode += GET(Fecode, 1);\n      if (*Fecode != OP_ALT) break;\n      }\n\n    /* Success if matched something or zero repeat allowed */\n\n    if (Lmatched_once || Lzero_allowed)\n      {\n      Fecode += 1 + LINK_SIZE;\n      break;\n      }\n\n    RRETURN(MATCH_NOMATCH);\n\n#undef Lmatched_once\n#undef Lzero_allowed\n#undef Lframe_type\n#undef Lstart_eptr\n#undef Lstart_group\n\n\n    /* ===================================================================== */\n    /* Handle non-capturing brackets that cannot match an empty string. When we\n    get to the final alternative within the brackets, as long as there are no\n    THEN's in the pattern, we can optimize by not recording a new backtracking\n    point. (Ideally we should test for a THEN within this group, but we don't\n    have that information.) Don't do this if we are at the very top level,\n    however, because that would make handling assertions and once-only brackets\n    messier when there is nothing to go back to. */\n\n#define Lframe_type F->temp_32[0]     /* Set for all that use GROUPLOOP */\n#define Lnext_branch F->temp_sptr[0]  /* Used only in OP_BRA handling */\n\n    case OP_BRA:\n    if (mb->hasthen || Frdepth == 0)\n      {\n      Lframe_type = 0;\n      goto GROUPLOOP;\n      }\n\n    for (;;)\n      {\n      Lnext_branch = Fecode + GET(Fecode, 1);\n      if (*Lnext_branch != OP_ALT) break;\n\n      /* This is never the final branch. We do not need to test for MATCH_THEN\n      here because this code is not used when there is a THEN in the pattern. */\n\n      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1);\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      Fecode = Lnext_branch;\n      }\n\n    /* Hit the start of the final branch. Continue at this level. */\n\n    Fecode += PRIV(OP_lengths)[*Fecode];\n    break;\n\n#undef Lnext_branch\n\n\n    /* ===================================================================== */\n    /* Handle a capturing bracket, other than those that are possessive with an\n    unlimited repeat. */\n\n    case OP_CBRA:\n    case OP_SCBRA:\n    Lframe_type = GF_CAPTURE | GET2(Fecode, 1+LINK_SIZE);\n    goto GROUPLOOP;\n\n\n    /* ===================================================================== */\n    /* Atomic groups and non-capturing brackets that can match an empty string\n    must record a backtracking point and also set up a chained frame. */\n\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_SBRA:\n    Lframe_type = GF_NOCAPTURE | Fop;\n\n    GROUPLOOP:\n    for (;;)\n      {\n      group_frame_type = Lframe_type;\n      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM2);\n      if (rrc == MATCH_THEN)\n        {\n        PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);\n        if (mb->verb_ecode_ptr < next_ecode &&\n            (*Fecode == OP_ALT || *next_ecode == OP_ALT))\n          rrc = MATCH_NOMATCH;\n        }\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      Fecode += GET(Fecode, 1);\n      if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);\n      }\n    PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n#undef Lframe_type\n\n\n    /* ===================================================================== */\n    /* Pattern recursion either matches the current regex, or some\n    subexpression. The offset data is the offset to the starting bracket from\n    the start of the whole pattern. This is so that it works from duplicated\n    subpatterns. For a whole-pattern recursion, we have to infer the number\n    zero. */\n\n#define Lframe_type F->temp_32[0]\n#define Lstart_branch F->temp_sptr[0]\n\n    case OP_RECURSE:\n    bracode = mb->start_code + GET(Fecode, 1);\n    number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE);\n\n    /* If we are already in a pattern recursion, check for repeating the same\n    one without changing the subject pointer or the last referenced character\n    in the subject. This should catch convoluted mutual recursions; some\n    simple cases are caught at compile time. However, there are rare cases when\n    this check needs to be turned off. In this case, actual recursion loops\n    will be caught by the match or heap limits. */\n\n    if (Fcurrent_recurse != RECURSE_UNSET)\n      {\n      offset = Flast_group_offset;\n      while (offset != PCRE2_UNSET)\n        {\n        N = (heapframe *)((char *)match_data->heapframes + offset);\n        P = (heapframe *)((char *)N - frame_size);\n        if (N->group_frame_type == (GF_RECURSE | number))\n          {\n          if (Feptr == P->eptr && mb->last_used_ptr == P->recurse_last_used &&\n               (mb->moptions & PCRE2_DISABLE_RECURSELOOP_CHECK) == 0)\n            return PCRE2_ERROR_RECURSELOOP;\n          break;\n          }\n        offset = P->last_group_offset;\n        }\n      }\n\n    /* Remember the current last referenced character and then run the\n    recursion branch by branch. */\n\n    F->recurse_last_used = mb->last_used_ptr;\n    Lstart_branch = bracode;\n    Lframe_type = GF_RECURSE | number;\n\n    for (;;)\n      {\n      PCRE2_SPTR next_ecode;\n\n      group_frame_type = Lframe_type;\n      RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM11);\n      next_ecode = Lstart_branch + GET(Lstart_branch,1);\n\n      /* Handle backtracking verbs, which are defined in a range that can\n      easily be tested for. PCRE does not allow THEN, SKIP, PRUNE or COMMIT to\n      escape beyond a recursion; they cause a NOMATCH for the entire recursion.\n\n      When one of these verbs triggers, the current recursion group number is\n      recorded. If it matches the recursion we are processing, the verb\n      happened within the recursion and we must deal with it. Otherwise it must\n      have happened after the recursion completed, and so has to be passed\n      back. See comment above about handling THEN. */\n\n      if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX &&\n          mb->verb_current_recurse == (Lframe_type ^ GF_RECURSE))\n        {\n        if (rrc == MATCH_THEN && mb->verb_ecode_ptr < next_ecode &&\n            (*Lstart_branch == OP_ALT || *next_ecode == OP_ALT))\n          rrc = MATCH_NOMATCH;\n        else RRETURN(MATCH_NOMATCH);\n        }\n\n      /* Note that carrying on after (*ACCEPT) in a recursion is handled in the\n      OP_ACCEPT code. Nothing needs to be done here. */\n\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      Lstart_branch = next_ecode;\n      if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH);\n      }\n    PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n#undef Lframe_type\n#undef Lstart_branch\n\n\n    /* ===================================================================== */\n    /* Positive assertions are like other groups except that PCRE doesn't allow\n    the effect of (*THEN) to escape beyond an assertion; it is therefore\n    treated as NOMATCH. (*ACCEPT) is treated as successful assertion, with its\n    captures and mark retained. Any other return is an error. */\n\n#define Lframe_type  F->temp_32[0]\n\n    case OP_ASSERT:\n    case OP_ASSERTBACK:\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    Lframe_type = GF_NOCAPTURE | Fop;\n    for (;;)\n      {\n      group_frame_type = Lframe_type;\n      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM3);\n      if (rrc == MATCH_ACCEPT)\n        {\n        memcpy(Fovector,\n              (char *)assert_accept_frame + offsetof(heapframe, ovector),\n              assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));\n        Foffset_top = assert_accept_frame->offset_top;\n        Fmark = assert_accept_frame->mark;\n        break;\n        }\n      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);\n      Fecode += GET(Fecode, 1);\n      if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);\n      }\n\n    do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);\n    Fecode += 1 + LINK_SIZE;\n    break;\n\n#undef Lframe_type\n\n\n    /* ===================================================================== */\n    /* Handle negative assertions. Loop for each non-matching branch as for\n    positive assertions. */\n\n#define Lframe_type  F->temp_32[0]\n\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK_NOT:\n    Lframe_type  = GF_NOCAPTURE | Fop;\n\n    for (;;)\n      {\n      group_frame_type = Lframe_type;\n      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM4);\n      switch(rrc)\n        {\n        case MATCH_ACCEPT:   /* Assertion matched, therefore it fails. */\n        case MATCH_MATCH:\n        RRETURN (MATCH_NOMATCH);\n\n        case MATCH_NOMATCH:  /* Branch failed, try next if present. */\n        case MATCH_THEN:\n        Fecode += GET(Fecode, 1);\n        if (*Fecode != OP_ALT) goto ASSERT_NOT_FAILED;\n        break;\n\n        case MATCH_COMMIT:   /* Assertion forced to fail, therefore continue. */\n        case MATCH_SKIP:\n        case MATCH_PRUNE:\n        do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);\n        goto ASSERT_NOT_FAILED;\n\n        default:             /* Pass back any other return */\n        RRETURN(rrc);\n        }\n      }\n\n    /* None of the branches have matched or there was a backtrack to (*COMMIT),\n    (*SKIP), (*PRUNE), or (*THEN) in the last branch. This is success for a\n    negative assertion, so carry on. */\n\n    ASSERT_NOT_FAILED:\n    Fecode += 1 + LINK_SIZE;\n    break;\n\n#undef Lframe_type\n\n    /* ===================================================================== */\n    /* Handle scan substring operation. */\n\n#define Lframe_type          F->temp_32[0]\n#define Lextra_size          F->temp_32[1]\n#define Lsaved_moptions      F->temp_32[2]\n#define Lsaved_end_subject   F->temp_sptr[0]\n#define Lsaved_eptr          F->temp_sptr[1]\n#define Ltrue_end_extra      F->temp_size\n\n    case OP_ASSERT_SCS:\n      {\n      PCRE2_SPTR ecode = Fecode + 1 + LINK_SIZE;\n      uint32_t extra_size = 0;\n      int count;\n      PCRE2_SPTR slot;\n\n      /* Disable compiler warning. */\n      offset = 0;\n      (void)offset;\n\n      for (;;)\n        {\n        if (*ecode == OP_CREF)\n          {\n          extra_size += 1+IMM2_SIZE;\n          offset = (GET2(ecode, 1) << 1) - 2;\n          ecode += 1+IMM2_SIZE;\n          if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET)\n            goto SCS_OFFSET_FOUND;\n          continue;\n          }\n\n        if (*ecode != OP_DNCREF) RRETURN(MATCH_NOMATCH);\n\n        count = GET2(ecode, 1 + IMM2_SIZE);\n        slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;\n        extra_size += 1+2*IMM2_SIZE;\n        ecode += 1+2*IMM2_SIZE;\n\n        while (count > 0)\n          {\n          offset = (GET2(slot, 0) << 1) - 2;\n          if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET)\n            goto SCS_OFFSET_FOUND;\n          slot += mb->name_entry_size;\n          count--;\n          }\n        }\n\n      SCS_OFFSET_FOUND:\n\n      /* Skip remaining options. */\n      for (;;)\n        {\n        if (*ecode == OP_CREF)\n          {\n          extra_size += 1+IMM2_SIZE;\n          ecode += 1+IMM2_SIZE;\n          }\n        else if (*ecode == OP_DNCREF)\n          {\n          extra_size += 1+2*IMM2_SIZE;\n          ecode += 1+2*IMM2_SIZE;\n          }\n        else break;\n        }\n\n      Lextra_size = extra_size;\n      }\n\n    Lsaved_end_subject = mb->end_subject;\n    Ltrue_end_extra = mb->true_end_subject - mb->end_subject;\n    Lsaved_eptr = Feptr;\n    Lsaved_moptions = mb->moptions;\n\n    Feptr = mb->start_subject + Fovector[offset];\n    mb->true_end_subject = mb->end_subject =\n      mb->start_subject + Fovector[offset + 1];\n    mb->moptions &= ~PCRE2_NOTEOL;\n\n    Lframe_type = GF_NOCAPTURE | Fop;\n    for (;;)\n      {\n      group_frame_type = Lframe_type;\n      RMATCH(Fecode + 1 + LINK_SIZE + Lextra_size, RM38);\n      if (rrc == MATCH_ACCEPT)\n        {\n        memcpy(Fovector,\n              (char *)assert_accept_frame + offsetof(heapframe, ovector),\n              assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));\n        Foffset_top = assert_accept_frame->offset_top;\n        Fmark = assert_accept_frame->mark;\n        mb->end_subject = Lsaved_end_subject;\n        mb->true_end_subject = mb->end_subject + Ltrue_end_extra;\n        mb->moptions = Lsaved_moptions;\n        break;\n        }\n\n      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)\n        {\n        mb->end_subject = Lsaved_end_subject;\n        mb->true_end_subject = mb->end_subject + Ltrue_end_extra;\n        mb->moptions = Lsaved_moptions;\n        RRETURN(rrc);\n        }\n\n      Fecode += GET(Fecode, 1);\n      if (*Fecode != OP_ALT)\n        {\n        mb->end_subject = Lsaved_end_subject;\n        mb->true_end_subject = mb->end_subject + Ltrue_end_extra;\n        mb->moptions = Lsaved_moptions;\n        RRETURN(MATCH_NOMATCH);\n        }\n      Lextra_size = 0;\n      }\n\n    do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);\n    Fecode += 1 + LINK_SIZE;\n    Feptr = Lsaved_eptr;\n    break;\n\n#undef Lframe_type\n#undef Lextra_size\n#undef Lsaved_end_subject\n#undef Lsaved_eptr\n#undef Ltrue_end_extra\n#undef Lsave_moptions\n\n    /* ===================================================================== */\n    /* The callout item calls an external function, if one is provided, passing\n    details of the match so far. This is mainly for debugging, though the\n    function is able to force a failure. */\n\n    case OP_CALLOUT:\n    case OP_CALLOUT_STR:\n    rrc = do_callout(F, mb, &length);\n    if (rrc > 0) RRETURN(MATCH_NOMATCH);\n    if (rrc < 0) RRETURN(rrc);\n    Fecode += length;\n    break;\n\n\n    /* ===================================================================== */\n    /* Conditional group: compilation checked that there are no more than two\n    branches. If the condition is false, skipping the first branch takes us\n    past the end of the item if there is only one branch, but that's exactly\n    what we want. */\n\n    case OP_COND:\n    case OP_SCOND:\n\n    /* The variable Flength will be added to Fecode when the condition is\n    false, to get to the second branch. Setting it to the offset to the ALT or\n    KET, then incrementing Fecode achieves this effect. However, if the second\n    branch is non-existent, we must point to the KET so that the end of the\n    group is correctly processed. We now have Fecode pointing to the condition\n    or callout. */\n\n    Flength = GET(Fecode, 1);    /* Offset to the second branch */\n    if (Fecode[Flength] != OP_ALT) Flength -= 1 + LINK_SIZE;\n    Fecode += 1 + LINK_SIZE;     /* From this opcode */\n\n    /* Because of the way auto-callout works during compile, a callout item is\n    inserted between OP_COND and an assertion condition. Such a callout can\n    also be inserted manually. */\n\n    if (*Fecode == OP_CALLOUT || *Fecode == OP_CALLOUT_STR)\n      {\n      rrc = do_callout(F, mb, &length);\n      if (rrc > 0) RRETURN(MATCH_NOMATCH);\n      if (rrc < 0) RRETURN(rrc);\n\n      /* Advance Fecode past the callout, so it now points to the condition. We\n      must adjust Flength so that the value of Fecode+Flength is unchanged. */\n\n      Fecode += length;\n      Flength -= length;\n      }\n\n    /* Test the various possible conditions */\n\n    condition = FALSE;\n    switch(*Fecode)\n      {\n      case OP_RREF:                  /* Group recursion test */\n      if (Fcurrent_recurse != RECURSE_UNSET)\n        {\n        number = GET2(Fecode, 1);\n        condition = (number == RREF_ANY || number == Fcurrent_recurse);\n        }\n      break;\n\n      case OP_DNRREF:       /* Duplicate named group recursion test */\n      if (Fcurrent_recurse != RECURSE_UNSET)\n        {\n        int count = GET2(Fecode, 1 + IMM2_SIZE);\n        PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;\n        while (count-- > 0)\n          {\n          number = GET2(slot, 0);\n          condition = number == Fcurrent_recurse;\n          if (condition) break;\n          slot += mb->name_entry_size;\n          }\n        }\n      break;\n\n      case OP_CREF:                         /* Numbered group used test */\n      offset = (GET2(Fecode, 1) << 1) - 2;  /* Doubled ref number */\n      condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;\n      break;\n\n      case OP_DNCREF:      /* Duplicate named group used test */\n        {\n        int count = GET2(Fecode, 1 + IMM2_SIZE);\n        PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;\n        while (count-- > 0)\n          {\n          offset = (GET2(slot, 0) << 1) - 2;\n          condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;\n          if (condition) break;\n          slot += mb->name_entry_size;\n          }\n        }\n      break;\n\n      case OP_FALSE:\n      case OP_FAIL:   /* The assertion (?!) becomes OP_FAIL */\n      break;\n\n      case OP_TRUE:\n      condition = TRUE;\n      break;\n\n      /* The condition is an assertion. Run code similar to the assertion code\n      above. */\n\n#define Lpositive      F->temp_32[0]\n#define Lstart_branch  F->temp_sptr[0]\n\n      default:\n      Lpositive = (*Fecode == OP_ASSERT || *Fecode == OP_ASSERTBACK);\n      Lstart_branch = Fecode;\n\n      for (;;)\n        {\n        group_frame_type = GF_CONDASSERT | *Fecode;\n        RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM5);\n\n        switch(rrc)\n          {\n          case MATCH_ACCEPT:  /* Save captures */\n          memcpy(Fovector,\n                (char *)assert_accept_frame + offsetof(heapframe, ovector),\n                assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));\n          Foffset_top = assert_accept_frame->offset_top;\n\n          PCRE2_FALLTHROUGH /* Fall through */\n          /* In the case of a match, the captures have already been put into\n          the current frame. */\n\n          case MATCH_MATCH:\n          condition = Lpositive;   /* TRUE for positive assertion */\n          break;\n\n          /* PCRE doesn't allow the effect of (*THEN) to escape beyond an\n          assertion; it is therefore always treated as NOMATCH. */\n\n          case MATCH_NOMATCH:\n          case MATCH_THEN:\n          Lstart_branch += GET(Lstart_branch, 1);\n          if (*Lstart_branch == OP_ALT) continue;  /* Try next branch */\n          condition = !Lpositive;  /* TRUE for negative assertion */\n          break;\n\n          /* These force no match without checking other branches. */\n\n          case MATCH_COMMIT:\n          case MATCH_SKIP:\n          case MATCH_PRUNE:\n          condition = !Lpositive;\n          break;\n\n          default:\n          RRETURN(rrc);\n          }\n        break;  /* Out of the branch loop */\n        }\n\n      /* If the condition is true, find the end of the assertion so that\n      advancing past it gets us to the start of the first branch. */\n\n      if (condition)\n        {\n        do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);\n        }\n      break;  /* End of assertion condition */\n      }\n\n#undef Lpositive\n#undef Lstart_branch\n\n    /* Choose branch according to the condition. */\n\n    Fecode += condition? PRIV(OP_lengths)[*Fecode] : Flength;\n\n    /* If the opcode is OP_SCOND it means we are at a repeated conditional\n    group that might match an empty string. We must therefore descend a level\n    so that the start is remembered for checking. For OP_COND we can just\n    continue at this level. */\n\n    if (Fop == OP_SCOND)\n      {\n      group_frame_type  = GF_NOCAPTURE | Fop;\n      RMATCH(Fecode, RM35);\n      RRETURN(rrc);\n      }\n    break;\n\n\n\n/* ========================================================================= */\n/*                  End of start of parenthesis opcodes                      */\n/* ========================================================================= */\n\n\n    /* ===================================================================== */\n    /* Move the subject pointer back by one fixed amount. This occurs at the\n    start of each branch that has a fixed length in a lookbehind assertion. If\n    we are too close to the start to move back, fail. When working with UTF-8\n    we move back a number of characters, not bytes. */\n\n    case OP_REVERSE:\n    number = GET2(Fecode, 1);\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      /* We used to do a simpler `while (number-- > 0)` but that triggers\n      clang's unsigned integer overflow sanitizer. */\n      while (number > 0)\n        {\n        --number;\n        if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH);\n        Feptr--;\n        BACKCHAR(Feptr);\n        }\n      }\n    else\n#endif\n\n    /* No UTF support, or not in UTF mode: count is code unit count */\n\n      {\n      if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);\n      Feptr -= number;\n      }\n\n    /* Save the earliest consulted character, then skip to next opcode */\n\n    if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr;\n    Fecode += 1 + IMM2_SIZE;\n    break;\n\n\n    /* ===================================================================== */\n    /* Move the subject pointer back by a variable amount. This occurs at the\n    start of each branch of a lookbehind assertion when the branch has a\n    variable, but limited, length. A loop is needed to try matching the branch\n    after moving back different numbers of characters. If we are too close to\n    the start to move back even the minimum amount, fail. When working with\n    UTF-8 we move back a number of characters, not bytes. */\n\n#define Lmin F->temp_32[0]\n#define Lmax F->temp_32[1]\n#define Leptr F->temp_sptr[0]\n\n    case OP_VREVERSE:\n    Lmin = GET2(Fecode, 1);\n    Lmax = GET2(Fecode, 1 + IMM2_SIZE);\n    Leptr = Feptr;\n\n    /* Move back by the maximum branch length and then work forwards. This\n    ensures that items such as \\d{3,5} get the maximum length, which is\n    relevant for captures, and makes for Perl compatibility. */\n\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      for (i = 0; i < Lmax; i++)\n        {\n        if (Feptr == mb->start_subject)\n          {\n          if (i < Lmin) RRETURN(MATCH_NOMATCH);\n          Lmax = i;\n          break;\n          }\n        Feptr--;\n        BACKCHAR(Feptr);\n        }\n      }\n    else\n#endif\n\n    /* No UTF support or not in UTF mode */\n\n      {\n      ptrdiff_t diff = Feptr - mb->start_subject;\n      uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? (int)diff : 0);\n      if (Lmin > available) RRETURN(MATCH_NOMATCH);\n      if (Lmax > available) Lmax = available;\n      Feptr -= Lmax;\n      }\n\n    /* Now try matching, moving forward one character on failure, until we\n    reach the minimum back length. */\n\n    for (;;)\n      {\n      RMATCH(Fecode + 1 + 2 * IMM2_SIZE, RM37);\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      if (Lmax-- <= Lmin) RRETURN(MATCH_NOMATCH);\n      Feptr++;\n#ifdef SUPPORT_UNICODE\n      if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); }\n#endif\n      }\n    PCRE2_UNREACHABLE(); /* Control never reaches here */\n\n#undef Lmin\n#undef Lmax\n#undef Leptr\n\n    /* ===================================================================== */\n    /* An alternation is the end of a branch; scan along to find the end of the\n    bracketed group. */\n\n    case OP_ALT:\n    branch_end = Fecode;\n    do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);\n    break;\n\n\n    /* ===================================================================== */\n    /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the\n    starting frame was added to the chained frames in order to remember the\n    starting subject position for the group. (Not true for OP_BRA when it's a\n    whole pattern recursion, but that is handled separately below.)*/\n\n    case OP_KET:\n    case OP_KETRMIN:\n    case OP_KETRMAX:\n    case OP_KETRPOS:\n\n    bracode = Fecode - GET(Fecode, 1);\n\n    if (branch_end == NULL) branch_end = Fecode;\n    branch_start = bracode;\n    while (branch_start + GET(branch_start, 1) != branch_end)\n      branch_start += GET(branch_start, 1);\n    branch_end = NULL;\n\n    /* Point N to the frame at the start of the most recent group, and P to its\n    predecessor. Remember the subject pointer at the start of the group. */\n\n    if (*bracode != OP_BRA && *bracode != OP_COND)\n      {\n      N = (heapframe *)((char *)match_data->heapframes + Flast_group_offset);\n      P = (heapframe *)((char *)N - frame_size);\n      Flast_group_offset = P->last_group_offset;\n\n#ifdef DEBUG_SHOW_RMATCH\n      fprintf(stderr, \"++ KET for frame=%d type=%x prev char offset=%lu\\n\",\n        N->rdepth, N->group_frame_type,\n        (char *)P->eptr - (char *)mb->start_subject);\n#endif\n\n      /* If we are at the end of an assertion that is a condition, first check\n      to see if we are at the end of a variable-length branch in a lookbehind.\n      If this is the case and we have not landed on the current character,\n      return no match. Compare code below for non-condition lookbehinds. In\n      other cases, return a match, discarding any intermediate backtracking\n      points. Copy back the mark setting and the captures into the frame before\n      N so that they are set on return. Doing this for all assertions, both\n      positive and negative, seems to match what Perl does. */\n\n      if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT)\n        {\n        if ((*bracode == OP_ASSERTBACK || *bracode == OP_ASSERTBACK_NOT) &&\n            branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)\n          RRETURN(MATCH_NOMATCH);\n        memcpy((char *)P + offsetof(heapframe, ovector), Fovector,\n          Foffset_top * sizeof(PCRE2_SIZE));\n        P->offset_top = Foffset_top;\n        P->mark = Fmark;\n        Fback_frame = (char *)F - (char *)P;\n        RRETURN(MATCH_MATCH);\n        }\n      }\n    else P = NULL;   /* Indicates starting frame not recorded */\n\n    /* The group was not a conditional assertion. */\n\n    switch (*bracode)\n      {\n      /* Whole pattern recursion is handled as a recursion into group 0, but\n      the entire pattern is wrapped in OP_BRA/OP_KET rather than a capturing\n      group - a design mistake: it should perhaps have been capture group 0.\n      Anyway, that means the end of such recursion must be handled here. It is\n      detected by checking for an immediately following OP_END when we are\n      recursing in group 0. If this is not the end of a whole-pattern\n      recursion, there is nothing to be done. */\n\n      case OP_BRA:\n      if (Fcurrent_recurse != 0 || Fecode[1+LINK_SIZE] != OP_END) break;\n\n      /* It is the end of whole-pattern recursion. */\n\n      offset = Flast_group_offset;\n\n      /* Corrupted heapframes?. Trigger an assert and return an error */\n      PCRE2_ASSERT(offset != PCRE2_UNSET);\n      if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;\n\n      N = (heapframe *)((char *)match_data->heapframes + offset);\n      P = (heapframe *)((char *)N - frame_size);\n      Flast_group_offset = P->last_group_offset;\n\n      /* Reinstate the previous set of captures and then carry on after the\n      recursion call. */\n\n      Fecode = P->ecode + 1 + LINK_SIZE;\n\n      if (*Fecode != OP_CREF)\n        {\n        memcpy(F->ovector, P->ovector, Foffset_top * sizeof(PCRE2_SIZE));\n        Foffset_top = P->offset_top;\n        }\n      else\n        recurse_update_offsets(F, P);\n\n      Fcapture_last = P->capture_last;\n      Fcurrent_recurse = P->current_recurse;\n      continue;  /* With next opcode */\n\n      case OP_COND:     /* No need to do anything for these */\n      case OP_SCOND:\n      break;\n\n      /* Non-atomic positive assertions are like OP_BRA, except that the\n      subject pointer must be put back to where it was at the start of the\n      assertion. For a variable lookbehind, check its end point. */\n\n      case OP_ASSERTBACK_NA:\n      if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)\n        RRETURN(MATCH_NOMATCH);\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_ASSERT_NA:\n      if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;\n      Feptr = P->eptr;\n      break;\n\n      /* Atomic positive assertions are like OP_ONCE, except that in addition\n      the subject pointer must be put back to where it was at the start of the\n      assertion. For a variable lookbehind, check its end point. */\n\n      case OP_ASSERTBACK:\n      if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)\n        RRETURN(MATCH_NOMATCH);\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_ASSERT:\n      if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;\n      Feptr = P->eptr;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      /* For an atomic group, discard internal backtracking points. We must\n      also ensure that any remaining branches within the top-level of the group\n      are not tried. Do this by adjusting the code pointer within the backtrack\n      frame so that it points to the final branch. */\n\n      case OP_ONCE:\n      Fback_frame = ((char *)F - (char *)P);\n      for (;;)\n        {\n        uint32_t y = GET(P->ecode,1);\n        if ((P->ecode)[y] != OP_ALT) break;\n        P->ecode += y;\n        }\n      break;\n\n      /* A matching negative assertion returns MATCH, which is turned into\n      NOMATCH at the assertion level. For a variable lookbehind, check its end\n      point. */\n\n      case OP_ASSERTBACK_NOT:\n      if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)\n        RRETURN(MATCH_NOMATCH);\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_ASSERT_NOT:\n      RRETURN(MATCH_MATCH);\n\n      /* A scan substring group must preserve the current end_subject,\n      and restore it before the backtracking is performed into its sub\n      pattern. */\n\n      case OP_ASSERT_SCS:\n      F->temp_sptr[0] = mb->end_subject;\n      mb->end_subject = P->temp_sptr[0];\n      mb->true_end_subject = mb->end_subject + P->temp_size;\n      Feptr = P->temp_sptr[1];\n\n      RMATCH(Fecode + 1 + LINK_SIZE, RM39);\n\n      mb->end_subject = F->temp_sptr[0];\n      mb->true_end_subject = mb->end_subject;\n      RRETURN(rrc);\n      break;\n\n      /* At the end of a script run, apply the script-checking rules. This code\n      will never by exercised if Unicode support it not compiled, because in\n      that environment script runs cause an error at compile time. */\n\n      case OP_SCRIPT_RUN:\n      if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH);\n      break;\n\n      /* Whole-pattern recursion is coded as a recurse into group 0, and is\n      handled with OP_BRA above. Other recursion is handled here. */\n\n      case OP_CBRA:\n      case OP_CBRAPOS:\n      case OP_SCBRA:\n      case OP_SCBRAPOS:\n      number = GET2(bracode, 1+LINK_SIZE);\n\n      /* Handle a recursively called group. We reinstate the previous set of\n      captures and then carry on after the recursion call. */\n\n      if (Fcurrent_recurse == number)\n        {\n        P = (heapframe *)((char *)N - frame_size);\n        Fecode = P->ecode + 1 + LINK_SIZE;\n\n        if (*Fecode != OP_CREF)\n          {\n          memcpy(F->ovector, P->ovector, Foffset_top * sizeof(PCRE2_SIZE));\n          Foffset_top = P->offset_top;\n          }\n        else\n          recurse_update_offsets(F, P);\n\n        Fcapture_last = P->capture_last;\n        Fcurrent_recurse = P->current_recurse;\n        continue;  /* With next opcode */\n        }\n\n      /* Deal with actual capturing. */\n\n      offset = (number << 1) - 2;\n      Fcapture_last = number;\n      Fovector[offset] = P->eptr - mb->start_subject;\n      Fovector[offset+1] = Feptr - mb->start_subject;\n      if (offset >= Foffset_top) Foffset_top = offset + 2;\n      break;\n      }  /* End actions relating to the starting opcode */\n\n    /* OP_KETRPOS is a possessive repeating ket. Remember the current position,\n    and return the MATCH_KETRPOS. This makes it possible to do the repeats one\n    at a time from the outer level. This must precede the empty string test -\n    in this case that test is done at the outer level. */\n\n    if (*Fecode == OP_KETRPOS)\n      {\n      memcpy((char *)P + offsetof(heapframe, eptr),\n             (char *)F + offsetof(heapframe, eptr),\n             frame_copy_size);\n      RRETURN(MATCH_KETRPOS);\n      }\n\n    /* Handle the different kinds of closing brackets. A non-repeating ket\n    needs no special action, just continuing at this level. This also happens\n    for the repeating kets if the group matched no characters, in order to\n    forcibly break infinite loops. Otherwise, the repeating kets try the rest\n    of the pattern or restart from the preceding bracket, in the appropriate\n    order. */\n\n    if (Fop != OP_KET && (P == NULL || Feptr != P->eptr))\n      {\n      if (Fop == OP_KETRMIN)\n        {\n        RMATCH(Fecode + 1 + LINK_SIZE, RM6);\n        if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n        Fecode -= GET(Fecode, 1);\n        break;   /* End of ket processing */\n        }\n\n      /* Repeat the maximum number of times (KETRMAX) */\n\n      RMATCH(bracode, RM7);\n      if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n      }\n\n    /* Carry on at this level for a non-repeating ket, or after matching an\n    empty string, or after repeating for a maximum number of times. */\n\n    Fecode += 1 + LINK_SIZE;\n    break;\n\n\n    /* ===================================================================== */\n    /* Start and end of line assertions, not multiline mode. */\n\n    case OP_CIRC:   /* Start of line, unless PCRE2_NOTBOL is set. */\n    if (Feptr != mb->start_subject || (mb->moptions & PCRE2_NOTBOL) != 0)\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    case OP_SOD:    /* Unconditional start of subject */\n    if (Feptr != mb->start_subject) RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    /* When PCRE2_NOTEOL is unset, assert before the subject end, or a\n    terminating newline unless PCRE2_DOLLAR_ENDONLY is set. */\n\n    case OP_DOLL:\n    if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);\n    if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;\n\n    PCRE2_FALLTHROUGH /* Fall through */\n    /* Unconditional end of subject assertion (\\z). */\n\n    case OP_EOD:\n    if (Feptr < mb->true_end_subject) RRETURN(MATCH_NOMATCH);\n    if (mb->partial != 0)\n      {\n      mb->hitend = TRUE;\n      if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n      }\n    Fecode++;\n    break;\n\n    /* End of subject or ending \\n assertion (\\Z) */\n\n    case OP_EODN:\n    ASSERT_NL_OR_EOS:\n    if (Feptr < mb->true_end_subject &&\n        (!IS_NEWLINE(Feptr) || Feptr != mb->true_end_subject - mb->nllen))\n      {\n      if (mb->partial != 0 &&\n          Feptr + 1 >= mb->end_subject &&\n          NLBLOCK->nltype == NLTYPE_FIXED &&\n          NLBLOCK->nllen == 2 &&\n          UCHAR21TEST(Feptr) == NLBLOCK->nl[0])\n        {\n        mb->hitend = TRUE;\n        if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n        }\n      RRETURN(MATCH_NOMATCH);\n      }\n\n    /* Either at end of string or \\n before end. */\n\n    if (mb->partial != 0)\n      {\n      mb->hitend = TRUE;\n      if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n      }\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Start and end of line assertions, multiline mode. */\n\n    /* Start of subject unless notbol, or after any newline except for one at\n    the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */\n\n    case OP_CIRCM:\n    if ((mb->moptions & PCRE2_NOTBOL) != 0 && Feptr == mb->start_subject)\n      RRETURN(MATCH_NOMATCH);\n    if (Feptr != mb->start_subject &&\n        ((Feptr == mb->end_subject &&\n           (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||\n         !WAS_NEWLINE(Feptr)))\n      RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n    /* Assert before any newline, or before end of subject unless noteol is\n    set. */\n\n    case OP_DOLLM:\n    if (Feptr < mb->end_subject)\n      {\n      if (!IS_NEWLINE(Feptr))\n        {\n        if (mb->partial != 0 &&\n            Feptr + 1 >= mb->end_subject &&\n            NLBLOCK->nltype == NLTYPE_FIXED &&\n            NLBLOCK->nllen == 2 &&\n            UCHAR21TEST(Feptr) == NLBLOCK->nl[0])\n          {\n          mb->hitend = TRUE;\n          if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;\n          }\n        RRETURN(MATCH_NOMATCH);\n        }\n      }\n    else\n      {\n      if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);\n      SCHECK_PARTIAL();\n      }\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Start of match assertion */\n\n    case OP_SOM:\n    if (Feptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Reset the start of match point */\n\n    case OP_SET_SOM:\n    Fstart_match = Feptr;\n    Fecode++;\n    break;\n\n\n    /* ===================================================================== */\n    /* Word boundary assertions. Find out if the previous and current\n    characters are \"word\" characters. It takes a bit more work in UTF mode.\n    Characters > 255 are assumed to be \"non-word\" characters when PCRE2_UCP is\n    not set. When it is set, use Unicode properties if available, even when not\n    in UTF mode. Remember the earliest and latest consulted characters. */\n\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    if (Feptr == mb->check_subject) prev_is_word = FALSE; else\n      {\n      PCRE2_SPTR lastptr = Feptr - 1;\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        BACKCHAR(lastptr);\n        GETCHAR(fc, lastptr);\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n      fc = *lastptr;\n      if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;\n#ifdef SUPPORT_UNICODE\n      if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)\n        {\n        int chartype = UCD_CHARTYPE(fc);\n        int category = PRIV(ucp_gentype)[chartype];\n        prev_is_word = (category == ucp_L || category == ucp_N ||\n          chartype == ucp_Mn || chartype == ucp_Pc);\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n      prev_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;\n      }\n\n    /* Get status of next character */\n\n    if (Feptr >= mb->end_subject)\n      {\n      SCHECK_PARTIAL();\n      cur_is_word = FALSE;\n      }\n    else\n      {\n      PCRE2_SPTR nextptr = Feptr + 1;\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        FORWARDCHARTEST(nextptr, mb->end_subject);\n        GETCHAR(fc, Feptr);\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n      fc = *Feptr;\n      if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;\n#ifdef SUPPORT_UNICODE\n      if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)\n        {\n        int chartype = UCD_CHARTYPE(fc);\n        int category = PRIV(ucp_gentype)[chartype];\n        cur_is_word = (category == ucp_L || category == ucp_N ||\n          chartype == ucp_Mn || chartype == ucp_Pc);\n        }\n      else\n#endif  /* SUPPORT_UNICODE */\n      cur_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;\n      }\n\n    /* Now see if the situation is what we want */\n\n    if ((*Fecode++ == OP_WORD_BOUNDARY || Fop == OP_UCP_WORD_BOUNDARY)?\n         cur_is_word == prev_is_word : cur_is_word != prev_is_word)\n      RRETURN(MATCH_NOMATCH);\n    break;\n\n\n    /* ===================================================================== */\n    /* Backtracking (*VERB)s, with and without arguments. Note that if the\n    pattern is successfully matched, we do not come back from RMATCH. */\n\n    case OP_MARK:\n    Fmark = mb->nomatch_mark = Fecode + 2;\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM12);\n\n    /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an\n    argument, and we must check whether that argument matches this MARK's\n    argument. It is passed back in mb->verb_skip_ptr. If it does match, we\n    return MATCH_SKIP with mb->verb_skip_ptr now pointing to the subject\n    position that corresponds to this mark. Otherwise, pass back the return\n    code unaltered. */\n\n    if (rrc == MATCH_SKIP_ARG &&\n             PRIV(strcmp)(Fecode + 2, mb->verb_skip_ptr) == 0)\n      {\n      mb->verb_skip_ptr = Feptr;   /* Pass back current position */\n      RRETURN(MATCH_SKIP);\n      }\n    RRETURN(rrc);\n\n    case OP_FAIL:\n    RRETURN(MATCH_NOMATCH);\n\n    /* Record the current recursing group number in mb->verb_current_recurse\n    when a backtracking return such as MATCH_COMMIT is given. This enables the\n    recurse processing to catch verbs from within the recursion. */\n\n    case OP_COMMIT:\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM13);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_COMMIT);\n\n    case OP_COMMIT_ARG:\n    Fmark = mb->nomatch_mark = Fecode + 2;\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM36);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_COMMIT);\n\n    case OP_PRUNE:\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM14);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_PRUNE);\n\n    case OP_PRUNE_ARG:\n    Fmark = mb->nomatch_mark = Fecode + 2;\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM15);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_PRUNE);\n\n    case OP_SKIP:\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM16);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_skip_ptr = Feptr;   /* Pass back current position */\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_SKIP);\n\n    /* Note that, for Perl compatibility, SKIP with an argument does NOT set\n    nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was\n    not a matching mark, we have to re-run the match, ignoring the SKIP_ARG\n    that failed and any that precede it (either they also failed, or were not\n    triggered). To do this, we maintain a count of executed SKIP_ARGs. If a\n    SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg\n    set to the count of the one that failed. */\n\n    case OP_SKIP_ARG:\n    mb->skip_arg_count++;\n    if (mb->skip_arg_count <= mb->ignore_skip_arg)\n      {\n      Fecode += PRIV(OP_lengths)[*Fecode] + Fecode[1];\n      break;\n      }\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM17);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n\n    /* Pass back the current skip name and return the special MATCH_SKIP_ARG\n    return code. This will either be caught by a matching MARK, or get to the\n    top, where it causes a rematch with mb->ignore_skip_arg set to the value of\n    mb->skip_arg_count. */\n\n    mb->verb_skip_ptr = Fecode + 2;\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_SKIP_ARG);\n\n    /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that\n    the branch in which it occurs can be determined. */\n\n    case OP_THEN:\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM18);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_ecode_ptr = Fecode;\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_THEN);\n\n    case OP_THEN_ARG:\n    Fmark = mb->nomatch_mark = Fecode + 2;\n    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM19);\n    if (rrc != MATCH_NOMATCH) RRETURN(rrc);\n    mb->verb_ecode_ptr = Fecode;\n    mb->verb_current_recurse = Fcurrent_recurse;\n    RRETURN(MATCH_THEN);\n\n\n    /* ===================================================================== */\n    /* There's been some horrible disaster. Arrival here can only mean there is\n    something seriously wrong in the code above or the OP_xxx definitions. */\n\n    /* LCOV_EXCL_START */\n    default:\n    PCRE2_DEBUG_UNREACHABLE();\n    return PCRE2_ERROR_INTERNAL;\n    /* LCOV_EXCL_STOP */\n    }\n\n  /* Do not insert any code in here without much thought; it is assumed\n  that \"continue\" in the code above comes out to here to repeat the main\n  loop. */\n\n  }  /* End of main loop */\n\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\n\n/* ========================================================================= */\n/* The RRETURN() macro jumps here. The number that is saved in Freturn_id\nindicates which label we actually want to return to. The value in Frdepth is\nthe index number of the frame in the vector. The return value has been placed\nin rrc. */\n\n#define LBL(val) case val: goto L_RM##val;\n\nRETURN_SWITCH:\nif (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;\nif (Frdepth == 0) return rrc;                     /* Exit from the top level */\nF = (heapframe *)((char *)F - Fback_frame);       /* Backtrack */\nmb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */\n\n#ifdef DEBUG_SHOW_RMATCH\nfprintf(stderr, \"++ RETURN %d to RM%d\\n\", rrc, Freturn_id);\n#endif\n\nswitch (Freturn_id)\n  {\n  LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)\n  LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)\n  LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)\n  LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)\n  LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39)\n\n#ifdef SUPPORT_WIDE_CHARS\n  LBL(100) LBL(101) LBL(102) LBL(103)\n#endif\n\n#ifdef SUPPORT_UNICODE\n  LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206)\n  LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213)\n  LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220)\n  LBL(221) LBL(222) LBL(223) LBL(224)\n#endif\n\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  return PCRE2_ERROR_INTERNAL;\n  /* LCOV_EXCL_STOP */\n  }\n#undef LBL\n}\n\n\n/*************************************************\n*           Match a Regular Expression           *\n*************************************************/\n\n/* This function applies a compiled pattern to a subject string and picks out\nportions of the string if it matches. Two elements in the vector are set for\neach substring: the offsets to the start and end of the substring.\n\nArguments:\n  code            points to the compiled expression\n  subject         points to the subject string\n  length          length of subject string (may contain binary zeros)\n  start_offset    where to start in the subject string\n  options         option bits\n  match_data      points to a match_data block\n  mcontext        points a PCRE2 context\n\nReturns:          > 0 => success; value is the number of ovector pairs filled\n                  = 0 => success, but ovector is not big enough\n                  = -1 => failed to match (PCRE2_ERROR_NOMATCH)\n                  = -2 => partial match (PCRE2_ERROR_PARTIAL)\n                  < -2 => some kind of unexpected problem\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,\n  PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,\n  pcre2_match_context *mcontext)\n{\nint rc;\nconst uint8_t *start_bits = NULL;\nconst pcre2_real_code *re = (const pcre2_real_code *)code;\nuint32_t original_options = options;\n\nBOOL anchored;\nBOOL firstline;\nBOOL has_first_cu = FALSE;\nBOOL has_req_cu = FALSE;\nBOOL startline;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nPCRE2_SPTR memchr_found_first_cu;\nPCRE2_SPTR memchr_found_first_cu2;\n#endif\n\nPCRE2_UCHAR first_cu = 0;\nPCRE2_UCHAR first_cu2 = 0;\nPCRE2_UCHAR req_cu = 0;\nPCRE2_UCHAR req_cu2 = 0;\n\nPCRE2_UCHAR null_str[1] = { 0xcd };\nPCRE2_SPTR original_subject = subject;\nPCRE2_SPTR bumpalong_limit;\nPCRE2_SPTR end_subject;\nPCRE2_SPTR true_end_subject;\nPCRE2_SPTR start_match;\nPCRE2_SPTR req_cu_ptr;\nPCRE2_SPTR start_partial;\nPCRE2_SPTR match_partial;\n\n#ifdef SUPPORT_JIT\nBOOL use_jit;\n#endif\n\n/* This flag is needed even when Unicode is not supported for convenience\n(it is used by the IS_NEWLINE macro). */\n\nBOOL utf = FALSE;\n\n#ifdef SUPPORT_UNICODE\nBOOL ucp = FALSE;\nBOOL allow_invalid;\nuint32_t fragment_options = 0;\n#ifdef SUPPORT_JIT\nBOOL jit_checked_utf = FALSE;\n#endif\n#endif  /* SUPPORT_UNICODE */\n\nPCRE2_SIZE frame_size;\nPCRE2_SIZE heapframes_size;\n\n/* We need to have mb as a pointer to a match block, because the IS_NEWLINE\nmacro is used below, and it expects NLBLOCK to be defined as a pointer. */\n\npcre2_callout_block cb;\nmatch_block actual_match_block;\nmatch_block *mb = &actual_match_block;\n\n/* Recognize NULL, length 0 as an empty string. */\n\nif (subject == NULL && length == 0) subject = null_str;\n\n/* Plausibility checks */\n\nif (match_data == NULL) return PCRE2_ERROR_NULL;\nif (code == NULL || subject == NULL)\n  return match_data->rc = PCRE2_ERROR_NULL;\nif ((options & ~PUBLIC_MATCH_OPTIONS) != 0)\n  return match_data->rc = PCRE2_ERROR_BADOPTION;\n\nstart_match = subject + start_offset;\nreq_cu_ptr = start_match - 1;\nif (length == PCRE2_ZERO_TERMINATED)\n  {\n  length = PRIV(strlen)(subject);\n  }\ntrue_end_subject = end_subject = subject + length;\n\nif (start_offset > length) return match_data->rc = PCRE2_ERROR_BADOFFSET;\n\n/* Check that the first field in the block is the magic number. */\n\nif (re->magic_number != MAGIC_NUMBER)\n  return match_data->rc = PCRE2_ERROR_BADMAGIC;\n\n/* Check the code unit width. */\n\nif ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)\n  return match_data->rc = PCRE2_ERROR_BADMODE;\n\n/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the\noptions variable for this function. Users of PCRE2 who are not calling the\nfunction directly would like to have a way of setting these flags, in the same\nway that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with\nconstructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and\n(*NOTEMPTY_ATSTART) set bits in the pattern's \"flag\" function which we now\ntransfer to the options for this function. The bits are guaranteed to be\nadjacent, but do not have the same values. This bit of Boolean trickery assumes\nthat the match-time bits are not more significant than the flag bits. If by\naccident this is not the case, a compile-time division by zero error will\noccur. */\n\n#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)\n#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)\noptions |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));\n#undef FF\n#undef OO\n\n/* If the pattern was successfully studied with JIT support, we will run the\nJIT executable instead of the rest of this function. Most options must be set\nat compile time for the JIT code to be usable. */\n\n#ifdef SUPPORT_JIT\nuse_jit = (re->executable_jit != NULL &&\n          (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);\n#endif\n\n/* Initialize UTF/UCP parameters. */\n\n#ifdef SUPPORT_UNICODE\nutf = (re->overall_options & PCRE2_UTF) != 0;\nallow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;\nucp = (re->overall_options & PCRE2_UCP) != 0;\n#endif  /* SUPPORT_UNICODE */\n\n/* Convert the partial matching flags into an integer. */\n\nmb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :\n              ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;\n\n/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same\ntime. */\n\nif (mb->partial != 0 &&\n   ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)\n  return match_data->rc = PCRE2_ERROR_BADOPTION;\n\n/* It is an error to set an offset limit without setting the flag at compile\ntime. */\n\nif (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&\n     (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)\n  return match_data->rc = PCRE2_ERROR_BADOFFSETLIMIT;\n\n/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,\nfree the memory that was obtained. Set the field to NULL for match error\ncases. */\n\nif ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)\n  {\n  match_data->memctl.free((void *)match_data->subject,\n    match_data->memctl.memory_data);\n  match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;\n  }\nmatch_data->subject = NULL;\n\n/* Zero the error offset in case the first code unit is invalid UTF. */\n\nmatch_data->startchar = 0;\n\n\n/* ============================= JIT matching ============================== */\n\n/* Prepare for JIT matching. Check a UTF string for validity unless no check is\nrequested or invalid UTF can be handled. We check only the portion of the\nsubject that might be be inspected during matching - from the offset minus the\nmaximum lookbehind to the given length. This saves time when a small part of a\nlarge subject is being matched by the use of a starting offset. Note that the\nmaximum lookbehind is a number of characters, not code units. */\n\n#ifdef SUPPORT_JIT\nif (use_jit)\n  {\n#ifdef SUPPORT_UNICODE\n  if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)\n    {\n\n    /* For 8-bit and 16-bit UTF, check that the first code unit is a valid\n    character start. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n    if (start_match < end_subject && NOT_FIRSTCU(*start_match))\n      {\n      if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      return match_data->rc = PCRE2_ERROR_UTF8_ERR20;  /* Isolated 0x80 byte */\n#else\n      return match_data->rc = PCRE2_ERROR_UTF16_ERR3;  /* Isolated low surrogate */\n#endif\n      }\n#endif  /* WIDTH != 32 */\n\n    /* Move back by the maximum lookbehind, just in case it happens at the very\n    start of matching. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n    for (unsigned int i = re->max_lookbehind; i > 0 && start_match > subject; i--)\n      {\n      start_match--;\n      while (start_match > subject &&\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      (*start_match & 0xc0) == 0x80)\n#else  /* 16-bit */\n      (*start_match & 0xfc00) == 0xdc00)\n#endif\n        start_match--;\n      }\n#else  /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n    /* In the 32-bit library, one code unit equals one character. However,\n    we cannot just subtract the lookbehind and then compare pointers, because\n    a very large lookbehind could create an invalid pointer. */\n\n    if (start_offset >= re->max_lookbehind)\n      start_match -= re->max_lookbehind;\n    else\n      start_match = subject;\n#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n    /* Validate the relevant portion of the subject. Adjust the offset of an\n    invalid code point to be an absolute offset in the whole string. */\n\n    rc = PRIV(valid_utf)(start_match,\n      length - (start_match - subject), &(match_data->startchar));\n    if (rc != 0)\n      {\n      match_data->startchar += start_match - subject;\n      return match_data->rc = rc;\n      }\n    jit_checked_utf = TRUE;\n    }\n#endif  /* SUPPORT_UNICODE */\n\n  /* If JIT returns BADOPTION, which means that the selected complete or\n  partial matching mode was not compiled, fall through to the interpreter. */\n\n  rc = pcre2_jit_match(code, subject, length, start_offset, options,\n    match_data, mcontext);\n  if (rc != PCRE2_ERROR_JIT_BADOPTION)\n    {\n    match_data->options = original_options;\n    if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)\n      {\n      if (length != 0)\n        {\n        match_data->subject = match_data->memctl.malloc(CU2BYTES(length),\n          match_data->memctl.memory_data);\n        if (match_data->subject == NULL)\n          return match_data->rc = PCRE2_ERROR_NOMEMORY;\n        memcpy((void *)match_data->subject, subject, CU2BYTES(length));\n        }\n      else\n        match_data->subject = NULL;\n      match_data->flags |= PCRE2_MD_COPIED_SUBJECT;\n      }\n    else\n      {\n      /* When pcre2_jit_match sets the subject, it doesn't know what the\n      original passed-in pointer was. */\n      if (match_data->subject != NULL) match_data->subject = original_subject;\n      }\n    return rc;\n    }\n  }\n#endif  /* SUPPORT_JIT */\n\n/* ========================= End of JIT matching ========================== */\n\n\n/* Proceed with non-JIT matching. The default is to allow lookbehinds to the\nstart of the subject. A UTF check when there is a non-zero offset may change\nthis. */\n\nmb->check_subject = subject;\n\n/* If a UTF subject string was not checked for validity in the JIT code above,\ncheck it here, and handle support for invalid UTF strings. The check above\nhappens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.\nIf we get here in those circumstances, it means the subject string is valid,\nbut for some reason JIT matching was not successful. There is no need to check\nthe subject again.\n\nWe check only the portion of the subject that might be be inspected during\nmatching - from the offset minus the maximum lookbehind to the given length.\nThis saves time when a small part of a large subject is being matched by the\nuse of a starting offset. Note that the maximum lookbehind is a number of\ncharacters, not code units.\n\nNote also that support for invalid UTF forces a check, overriding the setting\nof PCRE2_NO_CHECK_UTF. */\n\n#ifdef SUPPORT_UNICODE\nif (utf &&\n#ifdef SUPPORT_JIT\n    !jit_checked_utf &&\n#endif\n    ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 32\n  BOOL skipped_bad_start = FALSE;\n#endif\n\n  /* For 8-bit and 16-bit UTF, check that the first code unit is a valid\n  character start. If we are handling invalid UTF, just skip over such code\n  units. Otherwise, give an appropriate error. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n  if (allow_invalid)\n    {\n    while (start_match < end_subject && NOT_FIRSTCU(*start_match))\n      {\n      start_match++;\n      skipped_bad_start = TRUE;\n      }\n    }\n  else if (start_match < end_subject && NOT_FIRSTCU(*start_match))\n    {\n    if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    return match_data->rc = PCRE2_ERROR_UTF8_ERR20;  /* Isolated 0x80 byte */\n#else\n    return match_data->rc = PCRE2_ERROR_UTF16_ERR3;  /* Isolated low surrogate */\n#endif\n    }\n#endif  /* WIDTH != 32 */\n\n  /* The mb->check_subject field points to the start of UTF checking;\n  lookbehinds can go back no further than this. */\n\n  mb->check_subject = start_match;\n\n  /* Move back by the maximum lookbehind, just in case it happens at the very\n  start of matching, but don't do this if we skipped bad 8-bit or 16-bit code\n  units above. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n  if (!skipped_bad_start)\n    {\n    unsigned int i;\n    for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--)\n      {\n      mb->check_subject--;\n      while (mb->check_subject > subject &&\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      (*mb->check_subject & 0xc0) == 0x80)\n#else  /* 16-bit */\n      (*mb->check_subject & 0xfc00) == 0xdc00)\n#endif\n        mb->check_subject--;\n      }\n    }\n#else  /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n  /* In the 32-bit library, one code unit equals one character. However,\n  we cannot just subtract the lookbehind and then compare pointers, because\n  a very large lookbehind could create an invalid pointer. */\n\n  if (start_offset >= re->max_lookbehind)\n    mb->check_subject -= re->max_lookbehind;\n  else\n    mb->check_subject = subject;\n#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */\n\n  /* Validate the relevant portion of the subject. There's a loop in case we\n  encounter bad UTF in the characters preceding start_match which we are\n  scanning because of a lookbehind. */\n\n  for (;;)\n    {\n    rc = PRIV(valid_utf)(mb->check_subject,\n      length - (mb->check_subject - subject), &(match_data->startchar));\n\n    if (rc == 0) break;   /* Valid UTF string */\n\n    /* Invalid UTF string. Adjust the offset to be an absolute offset in the\n    whole string. If we are handling invalid UTF strings, set end_subject to\n    stop before the bad code unit, and set the options to \"not end of line\".\n    Otherwise return the error. */\n\n    match_data->startchar += mb->check_subject - subject;\n    if (!allow_invalid || rc > 0) return match_data->rc = rc;\n    end_subject = subject + match_data->startchar;\n\n    /* If the end precedes start_match, it means there is invalid UTF in the\n    extra code units we reversed over because of a lookbehind. Advance past the\n    first bad code unit, and then skip invalid character starting code units in\n    8-bit and 16-bit modes, and try again with the original end point. */\n\n    if (end_subject < start_match)\n      {\n      mb->check_subject = end_subject + 1;\n#if PCRE2_CODE_UNIT_WIDTH != 32\n      while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject))\n        mb->check_subject++;\n#endif\n      end_subject = true_end_subject;\n      }\n\n    /* Otherwise, set the not end of line option, and do the match. */\n\n    else\n      {\n      fragment_options = PCRE2_NOTEOL;\n      break;\n      }\n    }\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* A NULL match context means \"use a default context\", but we take the memory\ncontrol functions from the pattern. */\n\nif (mcontext == NULL)\n  {\n  mcontext = (pcre2_match_context *)(&PRIV(default_match_context));\n  mb->memctl = re->memctl;\n  }\nelse mb->memctl = mcontext->memctl;\n\nanchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;\nfirstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;\nstartline = (re->flags & PCRE2_STARTLINE) != 0;\nbumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?\n  true_end_subject : subject + mcontext->offset_limit;\n\n/* Initialize and set up the fixed fields in the callout block, with a pointer\nin the match block. */\n\nmb->cb = &cb;\ncb.version = 2;\ncb.subject = subject;\ncb.subject_length = (PCRE2_SIZE)(end_subject - subject);\ncb.callout_flags = 0;\n\n/* Fill in the remaining fields in the match block, except for moptions, which\ngets set later. */\n\nmb->callout = mcontext->callout;\nmb->callout_data = mcontext->callout_data;\n\nmb->start_subject = subject;\nmb->start_offset = start_offset;\nmb->end_subject = end_subject;\nmb->true_end_subject = true_end_subject;\nmb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;\nmb->hasbsk = (re->flags & PCRE2_HASBSK) != 0;\nmb->allowemptypartial = (re->max_lookbehind > 0) ||\n    (re->flags & PCRE2_MATCH_EMPTY) != 0;\nmb->allowlookaroundbsk =\n  (re->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) != 0;\nmb->poptions = re->overall_options;          /* Pattern options */\nmb->ignore_skip_arg = 0;\nmb->mark = mb->nomatch_mark = NULL;          /* In case never set */\n\n/* The name table is needed for finding all the numbers associated with a\ngiven name, for condition testing. The code follows the name table. */\n\nmb->name_table = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code));\nmb->name_count = re->name_count;\nmb->name_entry_size = re->name_entry_size;\nmb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start);\n\n/* Process the \\R and newline settings. */\n\nmb->bsr_convention = re->bsr_convention;\nmb->nltype = NLTYPE_FIXED;\nswitch(re->newline_convention)\n  {\n  case PCRE2_NEWLINE_CR:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_CR;\n  break;\n\n  case PCRE2_NEWLINE_LF:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_NUL:\n  mb->nllen = 1;\n  mb->nl[0] = CHAR_NUL;\n  break;\n\n  case PCRE2_NEWLINE_CRLF:\n  mb->nllen = 2;\n  mb->nl[0] = CHAR_CR;\n  mb->nl[1] = CHAR_NL;\n  break;\n\n  case PCRE2_NEWLINE_ANY:\n  mb->nltype = NLTYPE_ANY;\n  break;\n\n  case PCRE2_NEWLINE_ANYCRLF:\n  mb->nltype = NLTYPE_ANYCRLF;\n  break;\n\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  return match_data->rc = PCRE2_ERROR_INTERNAL;\n  /* LCOV_EXCL_STOP */\n  }\n\n/* The backtracking frames have fixed data at the front, and a PCRE2_SIZE\nvector at the end, whose size depends on the number of capturing parentheses in\nthe pattern. It is not used at all if there are no capturing parentheses.\n\n  frame_size                   is the total size of each frame\n  match_data->heapframes       is the pointer to the frames vector\n  match_data->heapframes_size  is the allocated size of the vector\n\nWe must pad the frame_size for alignment to ensure subsequent frames are as\naligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE\narray, that does not guarantee it is suitably aligned for pointers, as some\narchitectures have pointers that are larger than a size_t. */\n\nframe_size = (offsetof(heapframe, ovector) +\n  re->top_bracket * 2 * sizeof(PCRE2_SIZE) + HEAPFRAME_ALIGNMENT - 1) &\n  ~(HEAPFRAME_ALIGNMENT - 1);\n\n/* Limits set in the pattern override the match context only if they are\nsmaller. */\n\nmb->heap_limit = ((mcontext->heap_limit < re->limit_heap)?\n  mcontext->heap_limit : re->limit_heap);\n\nmb->match_limit = (mcontext->match_limit < re->limit_match)?\n  mcontext->match_limit : re->limit_match;\n\nmb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?\n  mcontext->depth_limit : re->limit_depth;\n\n/* If a pattern has very many capturing parentheses, the frame size may be very\nlarge. Set the initial frame vector size to ensure that there are at least 10\navailable frames, but enforce a minimum of START_FRAMES_SIZE. If this is\ngreater than the heap limit, get as large a vector as possible. */\n\nheapframes_size = frame_size * 10;\nif (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;\nif (heapframes_size / 1024 > mb->heap_limit)\n  {\n  PCRE2_SIZE max_size = 1024 * mb->heap_limit;\n  if (max_size < frame_size) return match_data->rc = PCRE2_ERROR_HEAPLIMIT;\n  heapframes_size = max_size;\n  }\n\n/* If an existing frame vector in the match_data block is large enough, we can\nuse it. Otherwise, free any pre-existing vector and get a new one. */\n\nif (match_data->heapframes_size < heapframes_size)\n  {\n  match_data->memctl.free(match_data->heapframes,\n    match_data->memctl.memory_data);\n  match_data->heapframes = match_data->memctl.malloc(heapframes_size,\n    match_data->memctl.memory_data);\n  if (match_data->heapframes == NULL)\n    {\n    match_data->heapframes_size = 0;\n    return match_data->rc = PCRE2_ERROR_NOMEMORY;\n    }\n  match_data->heapframes_size = heapframes_size;\n  }\n\n/* Write to the ovector within the first frame to mark every capture unset and\nto avoid uninitialized memory read errors when it is copied to a new frame. */\n\nmemset((char *)(match_data->heapframes) + offsetof(heapframe, ovector), 0xff,\n  frame_size - offsetof(heapframe, ovector));\n\n/* Pointers to the individual character tables */\n\nmb->lcc = re->tables + lcc_offset;\nmb->fcc = re->tables + fcc_offset;\nmb->ctypes = re->tables + ctypes_offset;\n\n/* Set up the first code unit to match, if available. If there's no first code\nunit there may be a bitmap of possible first characters. */\n\nif ((re->flags & PCRE2_FIRSTSET) != 0)\n  {\n  has_first_cu = TRUE;\n  first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);\n  if ((re->flags & PCRE2_FIRSTCASELESS) != 0)\n    {\n    first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);\n#else\n    if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);\n#endif\n#endif  /* SUPPORT_UNICODE */\n    }\n  }\nelse\n  if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)\n    start_bits = re->start_bitmap;\n\n/* There may also be a \"last known required character\" set. */\n\nif ((re->flags & PCRE2_LASTSET) != 0)\n  {\n  has_req_cu = TRUE;\n  req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);\n  if ((re->flags & PCRE2_LASTCASELESS) != 0)\n    {\n    req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);\n#ifdef SUPPORT_UNICODE\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);\n#else\n    if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);\n#endif\n#endif  /* SUPPORT_UNICODE */\n    }\n  }\n\n\n/* ==========================================================================*/\n\n/* Loop for handling unanchored repeated matching attempts; for anchored regexs\nthe loop runs just once. */\n\n#ifdef SUPPORT_UNICODE\nFRAGMENT_RESTART:\n#endif\n\nstart_partial = match_partial = NULL;\nmb->hitend = FALSE;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nmemchr_found_first_cu = NULL;\nmemchr_found_first_cu2 = NULL;\n#endif\n\nfor(;;)\n  {\n  PCRE2_SPTR new_start_match;\n\n  /* ----------------- Start of match optimizations ---------------- */\n\n  /* There are some optimizations that avoid running the match if a known\n  starting point is not found, or if a known later code unit is not present.\n  However, there is an option (settable at compile time) that disables these,\n  for testing and for ensuring that all callouts do actually occur. */\n\n  if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n    {\n    /* If firstline is TRUE, the start of the match is constrained to the first\n    line of a multiline string. That is, the match must be before or at the\n    first newline following the start of matching. Temporarily adjust\n    end_subject so that we stop the scans for a first code unit at a newline.\n    If the match fails at the newline, later code breaks the loop. */\n\n    if (firstline)\n      {\n      PCRE2_SPTR t = start_match;\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        while (t < end_subject && !IS_NEWLINE(t))\n          {\n          t++;\n          ACROSSCHAR(t < end_subject, t, t++);\n          }\n        }\n      else\n#endif\n      while (t < end_subject && !IS_NEWLINE(t)) t++;\n      end_subject = t;\n      }\n\n    /* Anchored: check the first code unit if one is recorded. This may seem\n    pointless but it can help in detecting a no match case without scanning for\n    the required code unit. */\n\n    if (anchored)\n      {\n      if (has_first_cu || start_bits != NULL)\n        {\n        BOOL ok = start_match < end_subject;\n        if (ok)\n          {\n          PCRE2_UCHAR c = UCHAR21TEST(start_match);\n          ok = has_first_cu && (c == first_cu || c == first_cu2);\n          if (!ok && start_bits != NULL)\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            if (c > 255) c = 255;\n#endif\n            ok = (start_bits[c/8] & (1u << (c&7))) != 0;\n            }\n          }\n        if (!ok)\n          {\n          rc = MATCH_NOMATCH;\n          break;\n          }\n        }\n      }\n\n    /* Not anchored. Advance to a unique first code unit if there is one. */\n\n    else\n      {\n      if (has_first_cu)\n        {\n        if (first_cu != first_cu2)  /* Caseless */\n          {\n          /* In 16-bit and 32_bit modes we have to do our own search, so can\n          look for both cases at once. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          PCRE2_UCHAR smc;\n          while (start_match < end_subject &&\n                (smc = UCHAR21TEST(start_match)) != first_cu &&\n                 smc != first_cu2)\n            start_match++;\n#else\n          /* In 8-bit mode, the use of memchr() gives a big speed up, even\n          though we have to call it twice in order to find the earliest\n          occurrence of the code unit in either of its cases. Caching is used\n          to remember the positions of previously found code units. This can\n          make a huge difference when the strings are very long and only one\n          case is actually present. */\n\n          PCRE2_SPTR pp1 = NULL;\n          PCRE2_SPTR pp2 = NULL;\n          PCRE2_SIZE searchlength = end_subject - start_match;\n\n          /* If we haven't got a previously found position for first_cu, or if\n          the current starting position is later, we need to do a search. If\n          the code unit is not found, set it to the end. */\n\n          if (memchr_found_first_cu == NULL ||\n              start_match > memchr_found_first_cu)\n            {\n            pp1 = memchr(start_match, first_cu, searchlength);\n            memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;\n            }\n\n          /* If the start is before a previously found position, use the\n          previous position, or NULL if a previous search failed. */\n\n          else pp1 = (memchr_found_first_cu == end_subject)? NULL :\n            memchr_found_first_cu;\n\n          /* Do the same thing for the other case. */\n\n          if (memchr_found_first_cu2 == NULL ||\n              start_match > memchr_found_first_cu2)\n            {\n            pp2 = memchr(start_match, first_cu2, searchlength);\n            memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;\n            }\n\n          else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :\n            memchr_found_first_cu2;\n\n          /* Set the start to the end of the subject if neither case was found.\n          Otherwise, use the earlier found point. */\n\n          if (pp1 == NULL)\n            start_match = (pp2 == NULL)? end_subject : pp2;\n          else\n            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;\n\n#endif  /* 8-bit handling */\n          }\n\n        /* The caseful case is much simpler. */\n\n        else\n          {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          while (start_match < end_subject && UCHAR21TEST(start_match) !=\n                 first_cu)\n            start_match++;\n#else\n          start_match = memchr(start_match, first_cu, end_subject - start_match);\n          if (start_match == NULL) start_match = end_subject;\n#endif\n          }\n\n        /* If we can't find the required first code unit, having reached the\n        true end of the subject, break the bumpalong loop, to force a match\n        failure, except when doing partial matching, when we let the next cycle\n        run at the end of the subject. To see why, consider the pattern\n        /(?<=abc)def/, which partially matches \"abc\", even though the string\n        does not contain the starting character \"d\". If we have not reached the\n        true end of the subject (PCRE2_FIRSTLINE caused end_subject to be\n        temporarily modified) we also let the cycle run, because the matching\n        string is legitimately allowed to start with the first code unit of a\n        newline. */\n\n        if (mb->partial == 0 && start_match >= mb->end_subject)\n          {\n          rc = MATCH_NOMATCH;\n          break;\n          }\n        }\n\n      /* If there's no first code unit, advance to just after a linebreak for a\n      multiline match if required. */\n\n      else if (startline)\n        {\n        if (start_match > mb->start_subject + start_offset)\n          {\n#ifdef SUPPORT_UNICODE\n          if (utf)\n            {\n            while (start_match < end_subject && !WAS_NEWLINE(start_match))\n              {\n              start_match++;\n              ACROSSCHAR(start_match < end_subject, start_match, start_match++);\n              }\n            }\n          else\n#endif\n          while (start_match < end_subject && !WAS_NEWLINE(start_match))\n            start_match++;\n\n          /* If we have just passed a CR and the newline option is ANY or\n          ANYCRLF, and we are now at a LF, advance the match position by one\n          more code unit. */\n\n          if (start_match[-1] == CHAR_CR &&\n               (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&\n               start_match < end_subject &&\n               UCHAR21TEST(start_match) == CHAR_NL)\n            start_match++;\n          }\n        }\n\n      /* If there's no first code unit or a requirement for a multiline line\n      start, advance to a non-unique first code unit if any have been\n      identified. The bitmap contains only 256 bits. When code units are 16 or\n      32 bits wide, all code units greater than 254 set the 255 bit. */\n\n      else if (start_bits != NULL)\n        {\n        while (start_match < end_subject)\n          {\n          uint32_t c = UCHAR21TEST(start_match);\n#if PCRE2_CODE_UNIT_WIDTH != 8\n          if (c > 255) c = 255;\n#endif\n          if ((start_bits[c/8] & (1u << (c&7))) != 0) break;\n          start_match++;\n          }\n\n        /* See comment above in first_cu checking about the next few lines. */\n\n        if (mb->partial == 0 && start_match >= mb->end_subject)\n          {\n          rc = MATCH_NOMATCH;\n          break;\n          }\n        }\n      }   /* End first code unit handling */\n\n    /* Restore fudged end_subject */\n\n    end_subject = mb->end_subject;\n\n    /* The following two optimizations must be disabled for partial matching. */\n\n    if (mb->partial == 0)\n      {\n      PCRE2_SPTR p;\n\n      /* The minimum matching length is a lower bound; no string of that length\n      may actually match the pattern. Although the value is, strictly, in\n      characters, we treat it as code units to avoid spending too much time in\n      this optimization. */\n\n      if (end_subject - start_match < re->minlength)\n        {\n        rc = MATCH_NOMATCH;\n        break;\n        }\n\n      /* If req_cu is set, we know that that code unit must appear in the\n      subject for the (non-partial) match to succeed. If the first code unit is\n      set, req_cu must be later in the subject; otherwise the test starts at\n      the match point. This optimization can save a huge amount of backtracking\n      in patterns with nested unlimited repeats that aren't going to match.\n      Writing separate code for caseful/caseless versions makes it go faster,\n      as does using an autoincrement and backing off on a match. As in the case\n      of the first code unit, using memchr() in the 8-bit library gives a big\n      speed up. Unlike the first_cu check above, we do not need to call\n      memchr() twice in the caseless case because we only need to check for the\n      presence of the character in either case, not find the first occurrence.\n\n      The search can be skipped if the code unit was found later than the\n      current starting point in a previous iteration of the bumpalong loop.\n\n      HOWEVER: when the subject string is very, very long, searching to its end\n      can take a long time, and give bad performance on quite ordinary\n      anchored patterns. This showed up when somebody was matching something\n      like /^\\d+C/ on a 32-megabyte string... so we don't do this when the\n      string is sufficiently long, but it's worth searching a lot more for\n      unanchored patterns. */\n\n      p = start_match + (has_first_cu? 1:0);\n      if (has_req_cu && p > req_cu_ptr)\n        {\n        PCRE2_SIZE check_length = end_subject - start_match;\n\n        if (check_length < REQ_CU_MAX ||\n              (!anchored && check_length < REQ_CU_MAX * 1000))\n          {\n          if (req_cu != req_cu2)  /* Caseless */\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            while (p < end_subject)\n              {\n              uint32_t pp = UCHAR21INCTEST(p);\n              if (pp == req_cu || pp == req_cu2) { p--; break; }\n              }\n#else  /* 8-bit code units */\n            PCRE2_SPTR pp = p;\n            p = memchr(pp, req_cu, end_subject - pp);\n            if (p == NULL)\n              {\n              p = memchr(pp, req_cu2, end_subject - pp);\n              if (p == NULL) p = end_subject;\n              }\n#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */\n            }\n\n          /* The caseful case */\n\n          else\n            {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n            while (p < end_subject)\n              {\n              if (UCHAR21INCTEST(p) == req_cu) { p--; break; }\n              }\n\n#else  /* 8-bit code units */\n            p = memchr(p, req_cu, end_subject - p);\n            if (p == NULL) p = end_subject;\n#endif\n            }\n\n          /* If we can't find the required code unit, break the bumpalong loop,\n          forcing a match failure. */\n\n          if (p >= end_subject)\n            {\n            rc = MATCH_NOMATCH;\n            break;\n            }\n\n          /* If we have found the required code unit, save the point where we\n          found it, so that we don't search again next time round the bumpalong\n          loop if the start hasn't yet passed this code unit. */\n\n          req_cu_ptr = p;\n          }\n        }\n      }\n    }\n\n  /* ------------ End of start of match optimizations ------------ */\n\n  /* Give no match if we have passed the bumpalong limit. */\n\n  if (start_match > bumpalong_limit)\n    {\n    rc = MATCH_NOMATCH;\n    break;\n    }\n\n  /* OK, we can now run the match. If \"hitend\" is set afterwards, remember the\n  first starting point for which a partial match was found. */\n\n  cb.start_match = (PCRE2_SIZE)(start_match - subject);\n  cb.callout_flags |= PCRE2_CALLOUT_STARTMATCH;\n\n  mb->start_used_ptr = start_match;\n  mb->last_used_ptr = start_match;\n#ifdef SUPPORT_UNICODE\n  mb->moptions = options | fragment_options;\n#else\n  mb->moptions = options;\n#endif\n  mb->match_call_count = 0;\n  mb->end_offset_top = 0;\n  mb->skip_arg_count = 0;\n\n#ifdef DEBUG_SHOW_OPS\n  fprintf(stderr, \"++ Calling match()\\n\");\n#endif\n\n  rc = match(start_match, mb->start_code, re->top_bracket, frame_size,\n    match_data, mb);\n\n#ifdef DEBUG_SHOW_OPS\n  fprintf(stderr, \"++ match() returned %d\\n\\n\", rc);\n#endif\n\n  if (mb->hitend && start_partial == NULL)\n    {\n    start_partial = mb->start_used_ptr;\n    match_partial = start_match;\n    }\n\n  switch(rc)\n    {\n    /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched\n    the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP\n    entirely. The only way we can do that is to re-do the match at the same\n    point, with a flag to force SKIP with an argument to be ignored. Just\n    treating this case as NOMATCH does not work because it does not check other\n    alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */\n\n    case MATCH_SKIP_ARG:\n    new_start_match = start_match;\n    mb->ignore_skip_arg = mb->skip_arg_count;\n    break;\n\n    /* SKIP passes back the next starting point explicitly, but if it is no\n    greater than the match we have just done, treat it as NOMATCH. */\n\n    case MATCH_SKIP:\n    if (mb->verb_skip_ptr > start_match)\n      {\n      new_start_match = mb->verb_skip_ptr;\n      break;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* NOMATCH and PRUNE advance by one character. THEN at this level acts\n    exactly like PRUNE. Unset ignore SKIP-with-argument. */\n\n    case MATCH_NOMATCH:\n    case MATCH_PRUNE:\n    case MATCH_THEN:\n    mb->ignore_skip_arg = 0;\n    new_start_match = start_match + 1;\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      ACROSSCHAR(new_start_match < end_subject, new_start_match,\n        new_start_match++);\n#endif\n    break;\n\n    /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */\n\n    case MATCH_COMMIT:\n    rc = MATCH_NOMATCH;\n    goto ENDLOOP;\n\n    /* Any other return is either a match, or some kind of error. */\n\n    default:\n    goto ENDLOOP;\n    }\n\n  /* Control reaches here for the various types of \"no match at this point\"\n  result. Reset the code to MATCH_NOMATCH for subsequent checking. */\n\n  rc = MATCH_NOMATCH;\n\n  /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first\n  newline in the subject (though it may continue over the newline). Therefore,\n  if we have just failed to match, starting at a newline, do not continue. */\n\n  if (firstline && IS_NEWLINE(start_match)) break;\n\n  /* Advance to new matching position */\n\n  start_match = new_start_match;\n\n  /* Break the loop if the pattern is anchored or if we have passed the end of\n  the subject. */\n\n  if (anchored || start_match > end_subject) break;\n\n  /* If we have just passed a CR and we are now at a LF, and the pattern does\n  not contain any explicit matches for \\r or \\n, and the newline option is CRLF\n  or ANY or ANYCRLF, advance the match position by one more code unit. In\n  normal matching start_match will aways be greater than the first position at\n  this stage, but a failed *SKIP can cause a return at the same point, which is\n  why the first test exists. */\n\n  if (start_match > subject + start_offset &&\n      start_match[-1] == CHAR_CR &&\n      start_match < end_subject &&\n      *start_match == CHAR_NL &&\n      (re->flags & PCRE2_HASCRORLF) == 0 &&\n        (mb->nltype == NLTYPE_ANY ||\n         mb->nltype == NLTYPE_ANYCRLF ||\n         mb->nllen == 2))\n    start_match++;\n\n  mb->mark = NULL;   /* Reset for start of next match attempt */\n  }                  /* End of for(;;) \"bumpalong\" loop */\n\n/* ==========================================================================*/\n\n/* When we reach here, one of the following stopping conditions is true:\n\n(1) The match succeeded, either completely, or partially;\n\n(2) The pattern is anchored or the match was failed after (*COMMIT);\n\n(3) We are past the end of the subject or the bumpalong limit;\n\n(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because\n    this option requests that a match occur at or before the first newline in\n    the subject.\n\n(5) Some kind of error occurred.\n\n*/\n\nENDLOOP:\n\n/* If end_subject != true_end_subject, it means we are handling invalid UTF,\nand have just processed a non-terminal fragment. If this resulted in no match\nor a partial match we must carry on to the next fragment (a partial match is\nreturned to the caller only at the very end of the subject). A loop is used to\navoid trying to match against empty fragments; if the pattern can match an\nempty string it would have done so already. */\n\n#ifdef SUPPORT_UNICODE\nif (utf && end_subject != true_end_subject &&\n    (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL))\n  {\n  for (;;)\n    {\n    /* Advance past the first bad code unit, and then skip invalid character\n    starting code units in 8-bit and 16-bit modes. */\n\n    start_match = end_subject + 1;\n\n#if PCRE2_CODE_UNIT_WIDTH != 32\n    while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))\n      start_match++;\n#endif\n\n    /* If we have hit the end of the subject, there isn't another non-empty\n    fragment, so give up. */\n\n    if (start_match >= true_end_subject)\n      {\n      rc = MATCH_NOMATCH;  /* In case it was partial */\n      match_partial = NULL;\n      break;\n      }\n\n    /* Check the rest of the subject */\n\n    mb->check_subject = start_match;\n    rc = PRIV(valid_utf)(start_match, length - (start_match - subject),\n      &(match_data->startchar));\n\n    /* The rest of the subject is valid UTF. */\n\n    if (rc == 0)\n      {\n      mb->end_subject = end_subject = true_end_subject;\n      fragment_options = PCRE2_NOTBOL;\n      goto FRAGMENT_RESTART;\n      }\n\n    /* A subsequent UTF error has been found; if the next fragment is\n    non-empty, set up to process it. Otherwise, let the loop advance. */\n\n    else if (rc < 0)\n      {\n      mb->end_subject = end_subject = start_match + match_data->startchar;\n      if (end_subject > start_match)\n        {\n        fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL;\n        goto FRAGMENT_RESTART;\n        }\n      }\n    }\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* Fill in fields that are always returned in the match data. */\n\nmatch_data->code = re;\nmatch_data->mark = mb->mark;\nmatch_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;\nmatch_data->options = original_options;\n\n/* Handle a fully successful match. Set the return code to the number of\ncaptured strings, or 0 if there were too many to fit into the ovector, and then\nset the remaining returned values before returning. Make a copy of the subject\nstring if requested. */\n\nif (rc == MATCH_MATCH)\n  {\n  match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?\n    0 : (int)mb->end_offset_top/2 + 1;\n  match_data->subject_length = length;\n  match_data->start_offset = start_offset;\n  match_data->startchar = start_match - subject;\n  match_data->leftchar = mb->start_used_ptr - subject;\n  match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?\n    mb->last_used_ptr : mb->end_match_ptr) - subject;\n  if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)\n    {\n    if (length != 0)\n      {\n      match_data->subject = match_data->memctl.malloc(CU2BYTES(length),\n        match_data->memctl.memory_data);\n      if (match_data->subject == NULL)\n        return match_data->rc = PCRE2_ERROR_NOMEMORY;\n      memcpy((void *)match_data->subject, subject, CU2BYTES(length));\n      }\n    else\n      match_data->subject = NULL;\n    match_data->flags |= PCRE2_MD_COPIED_SUBJECT;\n    }\n  else match_data->subject = original_subject;\n\n  return match_data->rc;\n  }\n\n/* Control gets here if there has been a partial match, an error, or if the\noverall match attempt has failed at all permitted starting positions. Any mark\ndata is in the nomatch_mark field. */\n\nmatch_data->mark = mb->nomatch_mark;\n\n/* For anything other than nomatch or partial match, just return the code. */\n\nif (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc;\n\n/* Handle a partial match. If a \"soft\" partial match was requested, searching\nfor a complete match will have continued, and the value of rc at this point\nwill be MATCH_NOMATCH. For a \"hard\" partial match, it will already be\nPCRE2_ERROR_PARTIAL. */\n\nelse if (match_partial != NULL)\n  {\n  match_data->subject = original_subject;\n  match_data->subject_length = length;\n  match_data->start_offset = start_offset;\n  match_data->ovector[0] = match_partial - subject;\n  match_data->ovector[1] = end_subject - subject;\n  match_data->startchar = match_partial - subject;\n  match_data->leftchar = start_partial - subject;\n  match_data->rightchar = end_subject - subject;\n  match_data->rc = PCRE2_ERROR_PARTIAL;\n  }\n\n/* Else this is the classic nomatch case. */\n\nelse\n  {\n  match_data->subject = original_subject;\n  match_data->subject_length = length;\n  match_data->start_offset = start_offset;\n  match_data->rc = PCRE2_ERROR_NOMATCH;\n  }\n\nreturn match_data->rc;\n}\n\n/* These #undefs are here to enable unity builds with CMake. */\n\n#undef NLBLOCK /* Block containing newline information */\n#undef PSSTART /* Field containing processed string start */\n#undef PSEND   /* Field containing processed string end */\n\n/* End of pcre2_match.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_match_data.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*  Create a match data block given ovector size  *\n*************************************************/\n\n/* A minimum of 1 is imposed on the number of ovector pairs. A maximum is also\nimposed because the oveccount field in a match data block is uintt6_t. */\n\nPCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION\npcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext)\n{\npcre2_match_data *yield;\nif (oveccount < 1) oveccount = 1;\nif (oveccount > UINT16_MAX) oveccount = UINT16_MAX;\nyield = PRIV(memctl_malloc)(\n  offsetof(pcre2_match_data, ovector) + 2*oveccount*sizeof(PCRE2_SIZE),\n  (pcre2_memctl *)gcontext);\nif (yield == NULL) return NULL;\nyield->oveccount = oveccount;\nyield->flags = 0;\nyield->heapframes = NULL;\nyield->heapframes_size = 0;\nreturn yield;\n}\n\n\n\n/*************************************************\n*  Create a match data block using pattern data  *\n*************************************************/\n\n/* If no context is supplied, use the memory allocator from the code. This code\nassumes that a general context contains nothing other than a memory allocator.\nIf that ever changes, this code will need fixing. */\n\nPCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION\npcre2_match_data_create_from_pattern(const pcre2_code *code,\n  pcre2_general_context *gcontext)\n{\nif (code == NULL) return NULL;\nif (gcontext == NULL) gcontext = (pcre2_general_context *)code;\nreturn pcre2_match_data_create(((const pcre2_real_code *)code)->top_bracket + 1,\n  gcontext);\n}\n\n\n\n/*************************************************\n*            Free a match data block             *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_match_data_free(pcre2_match_data *match_data)\n{\nif (match_data != NULL)\n  {\n  if (match_data->heapframes != NULL)\n    match_data->memctl.free(match_data->heapframes,\n      match_data->memctl.memory_data);\n  if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)\n    match_data->memctl.free((void *)match_data->subject,\n      match_data->memctl.memory_data);\n  match_data->memctl.free(match_data, match_data->memctl.memory_data);\n  }\n}\n\n\n\n/*************************************************\n*         Get last mark in match                 *\n*************************************************/\n\nPCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION\npcre2_get_mark(pcre2_match_data *match_data)\n{\nreturn match_data->mark;\n}\n\n\n\n/*************************************************\n*          Get pointer to ovector                *\n*************************************************/\n\nPCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION\npcre2_get_ovector_pointer(pcre2_match_data *match_data)\n{\nreturn match_data->ovector;\n}\n\n\n\n/*************************************************\n*          Get number of ovector slots           *\n*************************************************/\n\nPCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION\npcre2_get_ovector_count(pcre2_match_data *match_data)\n{\nreturn match_data->oveccount;\n}\n\n\n\n/*************************************************\n*         Get starting code unit in match        *\n*************************************************/\n\nPCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION\npcre2_get_startchar(pcre2_match_data *match_data)\n{\nreturn match_data->startchar;\n}\n\n\n\n/*************************************************\n*         Get size of match data block           *\n*************************************************/\n\nPCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION\npcre2_get_match_data_size(pcre2_match_data *match_data)\n{\nreturn offsetof(pcre2_match_data, ovector) +\n  2 * (match_data->oveccount) * sizeof(PCRE2_SIZE);\n}\n\n\n\n/*************************************************\n*             Get heapframes size                *\n*************************************************/\n\nPCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION\npcre2_get_match_data_heapframes_size(pcre2_match_data *match_data)\n{\nreturn match_data->heapframes_size;\n}\n\n/* End of pcre2_match_data.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_match_next.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* Advance the offset by one code unit, and return the new value.\nIt is only called when the offset is not at the end of the subject. */\n\nstatic PCRE2_SIZE do_bumpalong(pcre2_match_data *match_data,\n  PCRE2_SIZE offset)\n{\nPCRE2_SPTR subject = match_data->subject;\nPCRE2_SIZE subject_length = match_data->subject_length;\n#ifdef SUPPORT_UNICODE\nBOOL utf = (match_data->code->overall_options & PCRE2_UTF) != 0;\n#endif\n\n/* Skip over CRLF as an atomic sequence, if CRLF is configured as a newline\nsequence. */\n\nif (subject[offset] == CHAR_CR && offset + 1 < subject_length &&\n    subject[offset + 1] == CHAR_LF)\n  {\n  switch(match_data->code->newline_convention)\n    {\n    case PCRE2_NEWLINE_CRLF:\n    case PCRE2_NEWLINE_ANY:\n    case PCRE2_NEWLINE_ANYCRLF:\n    return offset + 2;\n    }\n  }\n\n/* Advance by one full character if in UTF mode. */\n\n#ifdef SUPPORT_UNICODE\nif (utf)\n  {\n  PCRE2_SPTR next = subject + offset + 1;\n  PCRE2_SPTR subject_end = subject + subject_length;\n\n  (void)subject_end; /* Suppress warning; 32-bit FORWARDCHARTEST ignores this */\n  FORWARDCHARTEST(next, subject_end);\n  return next - subject;\n  }\n#endif\n\nreturn offset + 1;\n}\n\n\n\n/*************************************************\n*                Advance the match               *\n*************************************************/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_next_match(pcre2_match_data *match_data, PCRE2_SIZE *pstart_offset,\n  uint32_t *poptions)\n{\nint rc = match_data->rc;\nPCRE2_SIZE start_offset = match_data->start_offset;\nPCRE2_SIZE *ovector = match_data->ovector;\n\n/* Match error, or no match: no further iteration possible. In previous versions\nof PCRE2, we recommended that clients use a strategy which involved retrying in\ncertain cases after PCRE2_ERROR_NOMATCH, but this is no longer required. */\n\nif (rc < 0)\n  return FALSE;\n\n/* Match succeeded: get the start offset for the next match */\n\n/* Although \\K can affect the position of ovector[0], there are no ways to do\nanything surprising with ovector[1], which must always be >= start_offset. */\n\nPCRE2_ASSERT(ovector[1] >= start_offset);\n\n/* Special handling for patterns which contain \\K in a lookaround, which enables\nthe match start to be pushed back to before the starting search offset\n(ovector[0] < start_offset) or after the match ends (ovector[0] > ovector[1]).\nThis is not a problem if ovector[1] > start_offset, because in this case, we can\njust attempt the next match at ovector[1]: we are making progress, which is all\nthat we require.\n\nHowever, if we have ovector[1] == start_offset, then we have a very rare case\nwhich must be handled specially, because it's a non-empty match which\nnonetheless fails to make progress through the subject. */\n\nif (ovector[0] != start_offset && ovector[1] == start_offset)\n  {\n  /* If the match end is at the end of the subject, we are done. */\n\n  if (start_offset >= match_data->subject_length)\n    return FALSE;\n\n  /* Otherwise, bump along by one code unit, and do a normal search. */\n\n  *pstart_offset = do_bumpalong(match_data, ovector[1]);\n  *poptions = 0;\n  return TRUE;\n  }\n\n/* If the previous match was for an empty string, we are finished if we are at\nthe end of the subject. Otherwise, arrange to run another match at the same\npoint to see if a non-empty match can be found. */\n\nif (ovector[0] == ovector[1])\n  {\n  /* If the match is at the end of the subject, we are done. */\n\n  if (ovector[0] >= match_data->subject_length)\n    return FALSE;\n\n  /* Otherwise, continue at this exact same point, but we must set the flag\n  which ensures that we don't return the exact same empty match again. */\n\n  *pstart_offset = ovector[1];\n  *poptions = PCRE2_NOTEMPTY_ATSTART;\n  return TRUE;\n  }\n\n/* Finally, we must be in the happy state of a non-empty match, where the end of\nthe match is further on in the subject than start_offset, so we are easily able\nto continue and make progress. */\n\n*pstart_offset = ovector[1];\n*poptions = 0;\nreturn TRUE;\n}\n\n/* End of pcre2_match_next.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_newline.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n         New API code Copyright (c) 2016 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains internal functions for testing newlines when more than\none kind of newline is to be recognized. When a newline is found, its length is\nreturned. In principle, we could implement several newline \"types\", each\nreferring to a different set of newline characters. At present, PCRE2 supports\nonly NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,\nand NLTYPE_ANY. The full list of Unicode newline characters is taken from\nhttp://unicode.org/unicode/reports/tr18/. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*      Check for newline at given position       *\n*************************************************/\n\n/* This function is called only via the IS_NEWLINE macro, which does so only\nwhen the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed\nnewline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit\npointed to by ptr is less than the end of the string.\n\nArguments:\n  ptr          pointer to possible newline\n  type         the newline type\n  endptr       pointer to the end of the string\n  lenptr       where to return the length\n  utf          TRUE if in utf mode\n\nReturns:       TRUE or FALSE\n*/\n\nBOOL\nPRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr,\n  uint32_t *lenptr, BOOL utf)\n{\nuint32_t c;\n\n#ifdef SUPPORT_UNICODE\nif (utf) { GETCHAR(c, ptr); } else c = *ptr;\n#else\n(void)utf;\nc = *ptr;\n#endif  /* SUPPORT_UNICODE */\n\nif (type == NLTYPE_ANYCRLF) switch(c)\n  {\n  case CHAR_LF:\n  *lenptr = 1;\n  return TRUE;\n\n  case CHAR_CR:\n  *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;\n  return TRUE;\n\n  default:\n  return FALSE;\n  }\n\n/* NLTYPE_ANY */\n\nelse switch(c)\n  {\n#ifdef EBCDIC\n  case CHAR_NEL:\n#endif\n  case CHAR_LF:\n  case CHAR_VT:\n  case CHAR_FF:\n  *lenptr = 1;\n  return TRUE;\n\n  case CHAR_CR:\n  *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;\n  return TRUE;\n\n#ifndef EBCDIC\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  case CHAR_NEL:\n  *lenptr = utf? 2 : 1;\n  return TRUE;\n\n  case 0x2028:   /* LS */\n  case 0x2029:   /* PS */\n  *lenptr = 3;\n  return TRUE;\n\n#else  /* 16-bit or 32-bit code units */\n  case CHAR_NEL:\n  case 0x2028:   /* LS */\n  case 0x2029:   /* PS */\n  *lenptr = 1;\n  return TRUE;\n#endif\n#endif /* Not EBCDIC */\n\n  default:\n  return FALSE;\n  }\n}\n\n\n\n/*************************************************\n*     Check for newline at previous position     *\n*************************************************/\n\n/* This function is called only via the WAS_NEWLINE macro, which does so only\nwhen the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed\nnewline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial\nvalue of ptr is greater than the start of the string that is being processed.\n\nArguments:\n  ptr          pointer to possible newline\n  type         the newline type\n  startptr     pointer to the start of the string\n  lenptr       where to return the length\n  utf          TRUE if in utf mode\n\nReturns:       TRUE or FALSE\n*/\n\nBOOL\nPRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr,\n  uint32_t *lenptr, BOOL utf)\n{\nuint32_t c;\nptr--;\n\n#ifdef SUPPORT_UNICODE\nif (utf)\n  {\n  BACKCHAR(ptr);\n  GETCHAR(c, ptr);\n  }\nelse c = *ptr;\n#else\n(void)utf;\nc = *ptr;\n#endif  /* SUPPORT_UNICODE */\n\nif (type == NLTYPE_ANYCRLF) switch(c)\n  {\n  case CHAR_LF:\n  *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;\n  return TRUE;\n\n  case CHAR_CR:\n  *lenptr = 1;\n  return TRUE;\n\n  default:\n  return FALSE;\n  }\n\n/* NLTYPE_ANY */\n\nelse switch(c)\n  {\n  case CHAR_LF:\n  *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;\n  return TRUE;\n\n#ifdef EBCDIC\n  case CHAR_NEL:\n#endif\n  case CHAR_VT:\n  case CHAR_FF:\n  case CHAR_CR:\n  *lenptr = 1;\n  return TRUE;\n\n#ifndef EBCDIC\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  case CHAR_NEL:\n  *lenptr = utf? 2 : 1;\n  return TRUE;\n\n  case 0x2028:   /* LS */\n  case 0x2029:   /* PS */\n  *lenptr = 3;\n  return TRUE;\n\n#else /* 16-bit or 32-bit code units */\n  case CHAR_NEL:\n  case 0x2028:   /* LS */\n  case 0x2029:   /* PS */\n  *lenptr = 1;\n  return TRUE;\n#endif\n#endif /* Not EBCDIC */\n\n  default:\n  return FALSE;\n  }\n}\n\n/* End of pcre2_newline.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_ord2utf.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n         New API code Copyright (c) 2016 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This file contains a function that converts a Unicode character code point\ninto a UTF string. The behaviour is different for each code unit width. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* If SUPPORT_UNICODE is not defined, this function will never be called.\nSupply a dummy function because some compilers do not like empty source\nmodules. */\n\n#ifndef SUPPORT_UNICODE\nunsigned int\nPRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)\n{\n(void)(cvalue);\n(void)(buffer);\nreturn 0;\n}\n#else  /* SUPPORT_UNICODE */\n\n\n/*************************************************\n*          Convert code point to UTF             *\n*************************************************/\n\n/*\nArguments:\n  cvalue     the character value\n  buffer     pointer to buffer for result\n\nReturns:     number of code units placed in the buffer\n*/\n\nunsigned int\nPRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)\n{\n/* Convert to UTF-8 */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nunsigned int i;\n\nfor (i = 0; i < PRIV(utf8_table1_size); i++)\n  if ((int)cvalue <= PRIV(utf8_table1)[i]) break;\nbuffer += i;\nfor (unsigned int j = i; j != 0; j--)\n {\n *buffer-- = 0x80 | (cvalue & 0x3f);\n cvalue >>= 6;\n }\n*buffer = (PCRE2_UCHAR)(PRIV(utf8_table2)[i] | (int)cvalue);\nreturn i + 1;\n\n/* Convert to UTF-16 */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nif (cvalue <= 0xffff)\n  {\n  *buffer = (PCRE2_UCHAR)cvalue;\n  return 1;\n  }\ncvalue -= 0x10000;\n*buffer++ = 0xd800 | (cvalue >> 10);\n*buffer = 0xdc00 | (cvalue & 0x3ff);\nreturn 2;\n\n/* Convert to UTF-32 */\n\n#else\n*buffer = (PCRE2_UCHAR)cvalue;\nreturn 1;\n#endif\n}\n#endif  /* SUPPORT_UNICODE */\n\n/* End of pcre2_ord2utf.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_pattern_info.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*        Return info about compiled pattern      *\n*************************************************/\n\n/*\nArguments:\n  code          points to compiled code\n  what          what information is required\n  where         where to put the information; if NULL, return length\n\nReturns:        0 when data returned\n                > 0 when length requested\n                < 0 on error or unset value\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)\n{\nconst pcre2_real_code *re = (const pcre2_real_code *)code;\n\nif (where == NULL)   /* Requests field length */\n  {\n  switch(what)\n    {\n    case PCRE2_INFO_ALLOPTIONS:\n    case PCRE2_INFO_ARGOPTIONS:\n    case PCRE2_INFO_BACKREFMAX:\n    case PCRE2_INFO_BSR:\n    case PCRE2_INFO_CAPTURECOUNT:\n    case PCRE2_INFO_DEPTHLIMIT:\n    case PCRE2_INFO_EXTRAOPTIONS:\n    case PCRE2_INFO_FIRSTCODETYPE:\n    case PCRE2_INFO_FIRSTCODEUNIT:\n    case PCRE2_INFO_HASBACKSLASHC:\n    case PCRE2_INFO_HASCRORLF:\n    case PCRE2_INFO_HEAPLIMIT:\n    case PCRE2_INFO_JCHANGED:\n    case PCRE2_INFO_LASTCODETYPE:\n    case PCRE2_INFO_LASTCODEUNIT:\n    case PCRE2_INFO_MATCHEMPTY:\n    case PCRE2_INFO_MATCHLIMIT:\n    case PCRE2_INFO_MAXLOOKBEHIND:\n    case PCRE2_INFO_MINLENGTH:\n    case PCRE2_INFO_NAMEENTRYSIZE:\n    case PCRE2_INFO_NAMECOUNT:\n    case PCRE2_INFO_NEWLINE:\n    return sizeof(uint32_t);\n\n    case PCRE2_INFO_FIRSTBITMAP:\n    return sizeof(const uint8_t *);\n\n    case PCRE2_INFO_JITSIZE:\n    case PCRE2_INFO_SIZE:\n    case PCRE2_INFO_FRAMESIZE:\n    return sizeof(size_t);\n\n    case PCRE2_INFO_NAMETABLE:\n    return sizeof(PCRE2_SPTR);\n    }\n  }\n\nif (re == NULL) return PCRE2_ERROR_NULL;\n\n/* Check that the first field in the block is the magic number. If it is not,\nreturn with PCRE2_ERROR_BADMAGIC. */\n\nif (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;\n\n/* Check that this pattern was compiled in the correct bit mode */\n\nif ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;\n\nswitch(what)\n  {\n  case PCRE2_INFO_ALLOPTIONS:\n  *((uint32_t *)where) = re->overall_options;\n  break;\n\n  case PCRE2_INFO_ARGOPTIONS:\n  *((uint32_t *)where) = re->compile_options;\n  break;\n\n  case PCRE2_INFO_BACKREFMAX:\n  *((uint32_t *)where) = re->top_backref;\n  break;\n\n  case PCRE2_INFO_BSR:\n  *((uint32_t *)where) = re->bsr_convention;\n  break;\n\n  case PCRE2_INFO_CAPTURECOUNT:\n  *((uint32_t *)where) = re->top_bracket;\n  break;\n\n  case PCRE2_INFO_DEPTHLIMIT:\n  *((uint32_t *)where) = re->limit_depth;\n  if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;\n  break;\n\n  case PCRE2_INFO_EXTRAOPTIONS:\n  *((uint32_t *)where) = re->extra_options;\n  break;\n\n  case PCRE2_INFO_FIRSTCODETYPE:\n  *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :\n                         ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;\n  break;\n\n  case PCRE2_INFO_FIRSTCODEUNIT:\n  *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?\n    re->first_codeunit : 0;\n  break;\n\n  case PCRE2_INFO_FIRSTBITMAP:\n  *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?\n    &(re->start_bitmap[0]) : NULL;\n  break;\n\n  case PCRE2_INFO_FRAMESIZE:\n  *((size_t *)where) = offsetof(heapframe, ovector) +\n    re->top_bracket * 2 * sizeof(PCRE2_SIZE);\n  break;\n\n  case PCRE2_INFO_HASBACKSLASHC:\n  *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;\n  break;\n\n  case PCRE2_INFO_HASCRORLF:\n  *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;\n  break;\n\n  case PCRE2_INFO_HEAPLIMIT:\n  *((uint32_t *)where) = re->limit_heap;\n  if (re->limit_heap == UINT32_MAX) return PCRE2_ERROR_UNSET;\n  break;\n\n  case PCRE2_INFO_JCHANGED:\n  *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;\n  break;\n\n  case PCRE2_INFO_JITSIZE:\n#ifdef SUPPORT_JIT\n  *((size_t *)where) = (re->executable_jit != NULL)?\n    PRIV(jit_get_size)(re->executable_jit) : 0;\n#else\n  *((size_t *)where) = 0;\n#endif\n  break;\n\n  case PCRE2_INFO_LASTCODETYPE:\n  *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;\n  break;\n\n  case PCRE2_INFO_LASTCODEUNIT:\n  *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?\n    re->last_codeunit : 0;\n  break;\n\n  case PCRE2_INFO_MATCHEMPTY:\n  *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;\n  break;\n\n  case PCRE2_INFO_MATCHLIMIT:\n  *((uint32_t *)where) = re->limit_match;\n  if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;\n  break;\n\n  case PCRE2_INFO_MAXLOOKBEHIND:\n  *((uint32_t *)where) = re->max_lookbehind;\n  break;\n\n  case PCRE2_INFO_MINLENGTH:\n  *((uint32_t *)where) = re->minlength;\n  break;\n\n  case PCRE2_INFO_NAMEENTRYSIZE:\n  *((uint32_t *)where) = re->name_entry_size;\n  break;\n\n  case PCRE2_INFO_NAMECOUNT:\n  *((uint32_t *)where) = re->name_count;\n  break;\n\n  case PCRE2_INFO_NAMETABLE:\n  *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((const char *)re +\n    sizeof(pcre2_real_code));\n  break;\n\n  case PCRE2_INFO_NEWLINE:\n  *((uint32_t *)where) = re->newline_convention;\n  break;\n\n  case PCRE2_INFO_SIZE:\n  *((size_t *)where) = re->blocksize;\n  break;\n\n  default: return PCRE2_ERROR_BADOPTION;\n  }\n\nreturn 0;\n}\n\n\n\n/*************************************************\n*              Callout enumerator                *\n*************************************************/\n\n/*\nArguments:\n  code          points to compiled code\n  callback      function called for each callout block\n  callout_data  user data passed to the callback\n\nReturns:        0 when successfully completed\n                < 0 on local error\n               != 0 for callback error\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_callout_enumerate(const pcre2_code *code,\n  int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)\n{\nconst pcre2_real_code *re = (const pcre2_real_code *)code;\npcre2_callout_enumerate_block cb;\nPCRE2_SPTR cc;\n#ifdef SUPPORT_UNICODE\nBOOL utf;\n#endif\n\nif (re == NULL) return PCRE2_ERROR_NULL;\n\n#ifdef SUPPORT_UNICODE\nutf = (re->overall_options & PCRE2_UTF) != 0;\n#endif\n\n/* Check that the first field in the block is the magic number. If it is not,\nreturn with PCRE2_ERROR_BADMAGIC. */\n\nif (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;\n\n/* Check that this pattern was compiled in the correct bit mode */\n\nif ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;\n\ncb.version = 0;\ncc = (PCRE2_SPTR)((uint8_t *)re + re->code_start);\n\nwhile (TRUE)\n  {\n  int rc;\n  switch (*cc)\n    {\n    case OP_END:\n    return 0;\n\n    case OP_CHAR:\n    case OP_CHARI:\n    case OP_NOT:\n    case OP_NOTI:\n    case OP_STAR:\n    case OP_MINSTAR:\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_UPTO:\n    case OP_MINUPTO:\n    case OP_EXACT:\n    case OP_POSSTAR:\n    case OP_POSPLUS:\n    case OP_POSQUERY:\n    case OP_POSUPTO:\n    case OP_STARI:\n    case OP_MINSTARI:\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_UPTOI:\n    case OP_MINUPTOI:\n    case OP_EXACTI:\n    case OP_POSSTARI:\n    case OP_POSPLUSI:\n    case OP_POSQUERYI:\n    case OP_POSUPTOI:\n    case OP_NOTSTAR:\n    case OP_NOTMINSTAR:\n    case OP_NOTPLUS:\n    case OP_NOTMINPLUS:\n    case OP_NOTQUERY:\n    case OP_NOTMINQUERY:\n    case OP_NOTUPTO:\n    case OP_NOTMINUPTO:\n    case OP_NOTEXACT:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSUPTO:\n    case OP_NOTSTARI:\n    case OP_NOTMINSTARI:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUSI:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERYI:\n    case OP_NOTUPTOI:\n    case OP_NOTMINUPTOI:\n    case OP_NOTEXACTI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTPOSQUERYI:\n    case OP_NOTPOSUPTOI:\n    cc += PRIV(OP_lengths)[*cc];\n#ifdef SUPPORT_UNICODE\n    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEEXACT:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEPOSQUERY:\n    case OP_TYPEPOSUPTO:\n    cc += PRIV(OP_lengths)[*cc];\n#ifdef SUPPORT_UNICODE\n    if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;\n#endif\n    break;\n\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_XCLASS:\n    case OP_ECLASS:\n    cc += GET(cc, 1);\n    break;\n#endif\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_SKIP_ARG:\n    case OP_THEN_ARG:\n    cc += PRIV(OP_lengths)[*cc] + cc[1];\n    break;\n\n    case OP_CALLOUT:\n    cb.pattern_position = GET(cc, 1);\n    cb.next_item_length = GET(cc, 1 + LINK_SIZE);\n    cb.callout_number = cc[1 + 2*LINK_SIZE];\n    cb.callout_string_offset = 0;\n    cb.callout_string_length = 0;\n    cb.callout_string = NULL;\n    rc = callback(&cb, callout_data);\n    if (rc != 0) return rc;\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n\n    case OP_CALLOUT_STR:\n    cb.pattern_position = GET(cc, 1);\n    cb.next_item_length = GET(cc, 1 + LINK_SIZE);\n    cb.callout_number = 0;\n    cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);\n    cb.callout_string_length =\n      GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;\n    cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;\n    rc = callback(&cb, callout_data);\n    if (rc != 0) return rc;\n    cc += GET(cc, 1 + 2*LINK_SIZE);\n    break;\n\n    default:\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n    }\n  }\n}\n\n/* End of pcre2_pattern_info.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_printint_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains a PCRE private debugging function for printing out the\ninternal form of a compiled regular expression, along with some supporting\nlocal functions. This source file is #included in pcre2test.c at each supported\ncode unit width, with PCRE2_SUFFIX set appropriately, just like the functions\nthat comprise the library. It can also optionally be included in\npcre2_compile.c for detailed debugging in error situations. */\n\n\n\n/* Tables of operator names. The same 8-bit table is used for all code unit\nwidths, so it must be defined only once. The list itself is defined in\npcre2_internal.h, which is #included by pcre2test before this file. */\n\n#ifndef OP_LISTS_DEFINED\nstatic const char *OP_names[] = { OP_NAME_LIST };\nSTATIC_ASSERT(sizeof(OP_names)/sizeof(*OP_names) == OP_TABLE_LENGTH, OP_names);\n#define OP_LISTS_DEFINED\n#endif\n\n/* The functions and tables herein must all have mode-dependent names. */\n\n#define OP_lengths            PCRE2_SUFFIX(OP_lengths_)\n#define get_ucpname           PCRE2_SUFFIX(get_ucpname_)\n#define pcre2_printint        PCRE2_SUFFIX(pcre2_printint_)\n#define print_char            PCRE2_SUFFIX(print_char_)\n#define print_custring        PCRE2_SUFFIX(print_custring_)\n#define print_custring_bylen  PCRE2_SUFFIX(print_custring_bylen_)\n#define print_prop            PCRE2_SUFFIX(print_prop_)\n#define print_char_list       PCRE2_SUFFIX(print_char_list_)\n#define print_map             PCRE2_SUFFIX(print_map_)\n#define print_class           PCRE2_SUFFIX(print_class_)\n\n/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that\nthe definition is next to the definition of the opcodes in pcre2_internal.h.\nThe contents of the table are, however, mode-dependent. */\n\nstatic const uint8_t OP_lengths[] = { OP_LENGTHS };\nSTATIC_ASSERT(sizeof(OP_lengths)/sizeof(*OP_lengths) == OP_TABLE_LENGTH,\n              PCRE2_SUFFIX(OP_lengths_));\n\n\n/*************************************************\n*       Print one character from a string        *\n*************************************************/\n\n/* In UTF mode the character may occupy more than one code unit.\n\nArguments:\n  f           file to write to\n  ptr         pointer to first code unit of the character\n  utf         TRUE if string is UTF (will be FALSE if UTF is not supported)\n\nReturns:      number of additional code units used\n*/\n\nstatic unsigned int\nprint_char(FILE *f, PCRE2_SPTR ptr, BOOL utf)\n{\nuint32_t c = *ptr;\nBOOL one_code_unit = !utf;\n\n/* If UTF is supported and requested, check for a valid single code unit. */\n\n#ifdef SUPPORT_UNICODE\nif (utf)\n  {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  one_code_unit = c < 0x80;\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n  one_code_unit = (c & 0xfc00) != 0xd800;\n#else\n  one_code_unit = (c & 0xfffff800u) != 0xd800u;\n#endif  /* CODE_UNIT_WIDTH */\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* Handle a valid one-code-unit character at any width. */\n\nif (one_code_unit)\n  {\n  if (PRINTABLE(c))\n    fprintf(f, \"%c\", CHAR_OUTPUT(c));\n  else\n    {\n    c = CHAR_OUTPUT_HEX(c);\n    if (c < 0x80) fprintf(f, \"\\\\x%02x\", c);\n    else fprintf(f, \"\\\\x{%02x}\", c);\n    }\n  return 0;\n  }\n\n/* Code for invalid UTF code units and multi-unit UTF characters is different\nfor each width. If UTF is not supported, control should never get here, but we\nneed a return statement to keep the compiler happy. */\n\n#ifndef SUPPORT_UNICODE\nreturn 0;\n#else\n\n/* Malformed UTF-8 should occur only if the sanity check has been turned off.\nRather than swallow random bytes, just stop if we hit a bad one. Print it with\n\\X instead of \\x as an indication. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif ((c & 0xc0) != 0xc0)\n  {\n  fprintf(f, \"\\\\X{%x}\", c);       /* Invalid starting byte */\n  return 0;\n  }\nelse\n  {\n  int i;\n  int a = PRIV(utf8_table4)[c & 0x3f];  /* Number of additional bytes */\n  int s = 6*a;\n  c = (c & PRIV(utf8_table3)[a]) << s;\n  for (i = 1; i <= a; i++)\n    {\n    if ((ptr[i] & 0xc0) != 0x80)\n      {\n      fprintf(f, \"\\\\X{%x}\", c);   /* Invalid secondary byte */\n      return i - 1;\n      }\n    s -= 6;\n    c |= (ptr[i] & 0x3f) << s;\n    }\n  fprintf(f, \"\\\\x{%x}\", c);\n  return a;\n}\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */\n\n/* UTF-16: rather than swallow a low surrogate, just stop if we hit a bad one.\nPrint it with \\X instead of \\x as an indication. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 16\nif ((ptr[1] & 0xfc00) != 0xdc00)\n  {\n  fprintf(f, \"\\\\X{%x}\", c);\n  return 0;\n  }\nc = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;\nfprintf(f, \"\\\\x{%x}\", c);\nreturn 1;\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 16 */\n\n/* For UTF-32 we get here only for a malformed code unit, which should only\noccur if the sanity check has been turned off. Print it with \\X instead of \\x\nas an indication. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nfprintf(f, \"\\\\X{%x}\", c);\nreturn 0;\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 32 */\n#endif  /* SUPPORT_UNICODE */\n}\n\n\n\n/*************************************************\n*     Print string as a list of code units       *\n*************************************************/\n\n/* These take no account of UTF as they always print each individual code unit.\nThe string is zero-terminated for print_custring(); the length is given for\nprint_custring_bylen().\n\nArguments:\n  f          file to write to\n  ptr        point to the string\n  len        length for print_custring_bylen()\n\nReturns:     nothing\n*/\n\nstatic void\nprint_custring(FILE *f, PCRE2_SPTR ptr)\n{\nwhile (*ptr != '\\0')\n  {\n  uint32_t c = *ptr++;\n  if (PRINTABLE(c)) fprintf(f, \"%c\", CHAR_OUTPUT(c));\n  else fprintf(f, \"\\\\x{%x}\", CHAR_OUTPUT_HEX(c));\n  }\n}\n\nstatic void\nprint_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len)\n{\nfor (; len > 0; len--)\n  {\n  uint32_t c = *ptr++;\n  if (PRINTABLE(c)) fprintf(f, \"%c\", CHAR_OUTPUT(c));\n  else fprintf(f, \"\\\\x{%x}\", CHAR_OUTPUT_HEX(c));\n  }\n}\n\n\n\n/*************************************************\n*          Find Unicode property name            *\n*************************************************/\n\n/* When there is no UTF/UCP support, the table of names does not exist. This\nfunction should not be called in such configurations, because a pattern that\ntries to use Unicode properties won't compile. Rather than put lots of #ifdefs\ninto the main code, however, we just put one into this function.\n\nNow that the table contains both full names and their abbreviations, we do some\nfiddling to try to get the full name, which is either the longer of two found\nnames, or a 3-character script name. */\n\nstatic const char *\nget_ucpname(unsigned int ptype, unsigned int pvalue)\n{\n#ifdef SUPPORT_UNICODE\nint count = 0;\nconst char *yield = \"??\";\nsize_t len = 0;\nunsigned int ptypex = (ptype == PT_SC)? PT_SCX : ptype;\n\nfor (ptrdiff_t i = PRIV(utt_size) - 1; i >= 0; i--)\n  {\n  const ucp_type_table *u = PRIV(utt) + i;\n\n  if ((ptype == u->type || ptypex == u->type) && pvalue == u->value)\n    {\n    const char *s = PRIV(utt_names) + u->name_offset;\n    size_t sl = strlen(s);\n\n    if (sl == 3 && (u->type == PT_SC || u->type == PT_SCX))\n      {\n      yield = s;\n      break;\n      }\n\n    if (sl > len)\n      {\n      yield = s;\n      len = sl;\n      }\n\n    if (++count >= 2) break;\n    }\n  }\n\nreturn yield;\n\n#else   /* No UTF support */\n(void)ptype;\n(void)pvalue;\nreturn \"??\";\n#endif  /* SUPPORT_UNICODE */\n}\n\n\n\n/*************************************************\n*       Print Unicode property value             *\n*************************************************/\n\n/* \"Normal\" properties can be printed from tables. The PT_CLIST property is a\npseudo-property that contains a pointer to a list of case-equivalent\ncharacters.\n\nArguments:\n  f            file to write to\n  code         pointer in the compiled code\n  before       text to print before\n  after        text to print after\n\nReturns:       nothing\n*/\n\nstatic void\nprint_prop(FILE *f, PCRE2_SPTR code, const char *before, const char *after)\n{\nif (code[1] != PT_CLIST)\n  {\n  const char *sc = (code[1] == PT_SC)? \"script:\" : \"\";\n  const char *s = get_ucpname(code[1], code[2]);\n  fprintf(f, \"%s%s %s%c%s%s\", before, OP_names[*code], sc, toupper(s[0]), s+1, after);\n  }\nelse\n  {\n  const uint32_t *p = PRIV(ucd_caseless_sets) + code[2];\n  fprintf (f, \"%s%sclist\", before, (*code == OP_PROP)? \"\" : \"not \");\n  while (*p < NOTACHAR) fprintf(f, \" %04x\", *p++);\n  fprintf(f, \"%s\", after);\n  }\n}\n\n\n\n/*************************************************\n*              Print character list              *\n*************************************************/\n\n/* Prints the characters and character ranges in a character list.\n\nArguments:\n  f            file to write to\n  code         pointer in the compiled code\n*/\n\nstatic PCRE2_SPTR\nprint_char_list(FILE *f, PCRE2_SPTR code, const uint8_t *char_lists_end)\n{\nuint32_t type, list_ind;\nuint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD;\nuint32_t range_start = ~(uint32_t)0, range_end = 0;\nconst uint8_t *next_char;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\ntype = (uint32_t)(code[0] << 8) | code[1];\ncode += 2;\n#else\ntype = code[0];\ncode++;\n#endif  /* CODE_UNIT_WIDTH */\n\n/* Align characters. */\nnext_char = char_lists_end - (GET(code, 0) << 1);\ntype &= XCL_TYPE_MASK;\nlist_ind = 0;\n\nif ((type & XCL_BEGIN_WITH_RANGE) != 0)\n  range_start = XCL_CHAR_LIST_LOW_16_START;\n\nwhile (type > 0)\n  {\n  uint32_t item_count = type & XCL_ITEM_COUNT_MASK;\n\n  if (item_count == XCL_ITEM_COUNT_MASK)\n    {\n    if (list_ind <= 1)\n      {\n      item_count = *(const uint16_t*)next_char;\n      next_char += 2;\n      }\n    else\n      {\n      item_count = *(const uint32_t*)next_char;\n      next_char += 4;\n      }\n    }\n\n  while (item_count > 0)\n    {\n    if (list_ind <= 1)\n      {\n      range_end = *(const uint16_t*)next_char;\n      next_char += 2;\n      }\n    else\n      {\n      range_end = *(const uint32_t*)next_char;\n      next_char += 4;\n      }\n\n    if ((range_end & XCL_CHAR_END) != 0)\n      {\n      range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n      if (range_start < range_end)\n        fprintf(f, \"\\\\x{%x}-\", range_start);\n\n      fprintf(f, \"\\\\x{%x}\", range_end);\n      range_start = ~(uint32_t)0;\n      }\n    else\n      range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n    item_count--;\n    }\n\n  list_ind++;\n  type >>= XCL_TYPE_BIT_LEN;\n\n  /* The following code could be optimized to 8/16/32 bit,\n  but it is not worth it for a debugging function. */\n\n  if (range_start == ~(uint32_t)0)\n    {\n    if ((type & XCL_BEGIN_WITH_RANGE) != 0)\n      {\n      if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START;\n      else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START;\n      else range_start = XCL_CHAR_LIST_HIGH_32_START;\n      }\n    }\n  else if ((type & XCL_BEGIN_WITH_RANGE) == 0)\n    {\n    fprintf(f, \"\\\\x{%x}-\", range_start);\n\n    if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END;\n    else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END;\n    else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END;\n    else range_end = XCL_CHAR_LIST_HIGH_32_END;\n\n    fprintf(f, \"\\\\x{%x}\", range_end);\n    range_start = ~(uint32_t)0;\n    }\n\n  if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD;\n  else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n  else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD;\n  }\n\nreturn code + LINK_SIZE;\n}\n\n\n\n/*************************************************\n*       Print a character bitmap                 *\n*************************************************/\n\n/* Prints a 32-byte bitmap, which occurs within a character class opcode.\n\nArguments:\n  f            file to write to\n  map          pointer to the bitmap\n  negated      TRUE if the bitmap will be printed as negated\n\nReturns:       nothing\n*/\n\nstatic void\nprint_map(FILE *f, const uint8_t *map, BOOL negated)\n{\nBOOL first = TRUE;\nuint8_t inverted_map[32];\nint i, input;\n\nif (negated)\n  {\n  /* Using 255 ^ instead of ~ avoids clang sanitize warning. */\n  for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i];\n  map = inverted_map;\n  }\n\nfor (input = 0; input < 256; input++)\n  {\n  i = CHAR_INPUT_HEX(input);\n  if ((map[i/8] & (1u << (i&7))) != 0)\n    {\n    int j, jinput;\n    for (jinput = input; jinput+1 < 256; jinput++)\n      {\n      j = CHAR_INPUT_HEX(jinput+1);\n      if ((map[j/8] & (1u << (j&7))) == 0) break;\n      }\n    j = CHAR_INPUT_HEX(jinput);\n    if (i == CHAR_MINUS || i == CHAR_BACKSLASH ||\n        i == CHAR_RIGHT_SQUARE_BRACKET ||\n        (first && i == CHAR_CIRCUMFLEX_ACCENT))\n      fprintf(f, \"\\\\\");\n    if (PRINTABLE(i)) fprintf(f, \"%c\", CHAR_OUTPUT(i));\n    else fprintf(f, \"\\\\x%02x\", CHAR_OUTPUT_HEX(i));\n    first = FALSE;\n    if (jinput > input)\n      {\n      if (jinput != input + 1) fprintf(f, \"-\");\n      if (j == CHAR_MINUS || j == CHAR_BACKSLASH ||\n          j == CHAR_RIGHT_SQUARE_BRACKET)\n        fprintf(f, \"\\\\\");\n      if (PRINTABLE(j)) fprintf(f, \"%c\", CHAR_OUTPUT(j));\n      else fprintf(f, \"\\\\x%02x\", CHAR_OUTPUT_HEX(j));\n      }\n    input = jinput;\n    }\n  }\n}\n\n\n\n/*************************************************\n*       Print character class                    *\n*************************************************/\n\n/* Prints a character class, which must be either an OP_CLASS, OP_NCLASS, or\nOP_XCLASS.\n\nArguments:\n  f            file to write to\n  type         OP_CLASS, OP_NCLASS, or OP_XCLASS\n  code         pointer in the compiled code (after the OP tag)\n  utf          TRUE if re is UTF (will be FALSE if UTF is not supported)\n  before       text to print before\n  after        text to print after\n\nReturns:       nothing\n*/\n\nstatic void\nprint_class(FILE *f, int type, PCRE2_SPTR code, const uint8_t *char_lists_end,\n  BOOL utf, const char *before, const char *after)\n{\nBOOL printmap, negated;\nPCRE2_SPTR ccode;\n\n/* Negative XCLASS and NCLASS both have a bitmap indicating which characters\nare accepted. For clarity we print this inverted and prefixed by \"^\". */\nif (type == OP_XCLASS)\n  {\n  ccode = code + LINK_SIZE;\n  printmap = (*ccode & XCL_MAP) != 0;\n  negated = (*ccode & XCL_NOT) != 0;\n  ccode++;\n  }\nelse  /* CLASS or NCLASS */\n  {\n  printmap = TRUE;\n  negated = type == OP_NCLASS;\n  ccode = code;\n  }\n\nfprintf(f, \"%s[%s\", before, negated? \"^\" : \"\");\n\n/* Print a bit map */\nif (printmap)\n  {\n  print_map(f, (const uint8_t *)ccode, negated);\n  ccode += 32 / sizeof(PCRE2_UCHAR);\n  }\n\n/* For an XCLASS there is always some additional data */\nif (type == OP_XCLASS)\n  {\n  PCRE2_UCHAR ch;\n\n  while ((ch = *ccode++) != XCL_END)\n    {\n    const char *notch = \"\";\n\n    if (ch >= XCL_LIST)\n      {\n      ccode = print_char_list(f, ccode - 1, char_lists_end);\n      break;\n      }\n\n    switch(ch)\n      {\n      case XCL_NOTPROP:\n      notch = \"^\";\n      PCRE2_FALLTHROUGH /* Fall through */\n      case XCL_PROP:\n        {\n        unsigned int ptype = *ccode++;\n        unsigned int pvalue = *ccode++;\n        const char *s;\n        switch(ptype)\n          {\n          case PT_PXGRAPH:\n          fprintf(f, \"[:%sgraph:]\", notch);\n          break;\n          case PT_PXPRINT:\n          fprintf(f, \"[:%sprint:]\", notch);\n          break;\n          case PT_PXPUNCT:\n          fprintf(f, \"[:%spunct:]\", notch);\n          break;\n          case PT_PXXDIGIT:\n          fprintf(f, \"[:%sxdigit:]\", notch);\n          break;\n          default:\n          s = get_ucpname(ptype, pvalue);\n          fprintf(f, \"\\\\%c{%c%s}\", ((notch[0] == '^')? 'P':'p'),\n            toupper(s[0]), s+1);\n          break;\n          }\n        }\n      break;\n\n      default:\n      ccode += 1 + print_char(f, ccode, utf);\n      if (ch == XCL_RANGE)\n        {\n        fprintf(f, \"-\");\n        ccode += 1 + print_char(f, ccode, utf);\n        }\n      break;\n      }\n    }\n\n  PCRE2_ASSERT(ccode == code + (GET(code, 0) - 1));\n  }\n\n/* Indicate a non-UTF class which was created by negation */\nfprintf(f, \"]%s\", after);\n}\n\n\n\n/*************************************************\n*            Print compiled pattern              *\n*************************************************/\n\n/* The print_lengths flag controls whether offsets and lengths of items are\nprinted. Lenths can be turned off from pcre2test so that automatic tests on\nbytecode can be written that do not depend on the value of LINK_SIZE.\n\nArguments:\n  re              a compiled pattern\n  f               the file to write to\n  print_lengths   show various lengths\n\nReturns:          nothing\n*/\n\nstatic void\npcre2_printint(pcre2_code *re, FILE *f, BOOL print_lengths)\n{\nPCRE2_SPTR codestart, nametable, code;\nuint32_t nesize = re->name_entry_size;\nBOOL utf = (re->overall_options & PCRE2_UTF) != 0;\n\nnametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));\ncode = codestart = (PCRE2_SPTR)((uint8_t *)re + re->code_start);\n\nfor(;;)\n  {\n  PCRE2_SPTR ccode;\n  uint32_t c;\n  int i;\n  const char *flag = \"  \";\n  unsigned int extra = 0;\n\n  if (print_lengths)\n    fprintf(f, \"%3d \", (int)(code - codestart));\n  else\n    fprintf(f, \"    \");\n\n  switch(*code)\n    {\n    case OP_END:\n    fprintf(f, \"    %s\\n\", OP_names[*code]);\n    fprintf(f, \"------------------------------------------------------------------\\n\");\n    return;\n\n    case OP_CHAR:\n    fprintf(f, \"    \");\n    do\n      {\n      code++;\n      code += 1 + print_char(f, code, utf);\n      }\n    while (*code == OP_CHAR);\n    fprintf(f, \"\\n\");\n    continue;\n\n    case OP_CHARI:\n    fprintf(f, \" /i \");\n    do\n      {\n      code++;\n      code += 1 + print_char(f, code, utf);\n      }\n    while (*code == OP_CHARI);\n    fprintf(f, \"\\n\");\n    continue;\n\n    case OP_CBRA:\n    case OP_CBRAPOS:\n    case OP_SCBRA:\n    case OP_SCBRAPOS:\n    if (print_lengths) fprintf(f, \"%3d \", GET(code, 1));\n      else fprintf(f, \"    \");\n    fprintf(f, \"%s %d\", OP_names[*code], GET2(code, 1+LINK_SIZE));\n    break;\n\n    case OP_BRA:\n    case OP_BRAPOS:\n    case OP_SBRA:\n    case OP_SBRAPOS:\n    case OP_KETRMAX:\n    case OP_KETRMIN:\n    case OP_KETRPOS:\n    case OP_ALT:\n    case OP_KET:\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ASSERTBACK_NA:\n    case OP_ASSERT_SCS:\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_COND:\n    case OP_SCOND:\n    if (print_lengths) fprintf(f, \"%3d \", GET(code, 1));\n      else fprintf(f, \"    \");\n    fprintf(f, \"%s\", OP_names[*code]);\n    break;\n\n    case OP_CLOSE:\n    fprintf(f, \"    %s %d\", OP_names[*code], GET2(code, 1));\n    break;\n\n    case OP_CREF:\n    case OP_REVERSE:\n    case OP_VREVERSE:\n    fprintf(f, \"%3d %s\", GET2(code, 1), OP_names[*code]);\n    if (*code == OP_VREVERSE) fprintf(f, \" %d\", GET2(code, 1 + IMM2_SIZE));\n    break;\n\n    case OP_DNCREF:\n    case OP_DNRREF:\n      {\n      PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;\n      fprintf(f, \" %s %s<\", flag, OP_names[*code]);\n      print_custring(f, entry);\n      fprintf(f, \">%d\", GET2(code, 1 + IMM2_SIZE));\n      }\n    break;\n\n    case OP_RREF:\n    c = GET2(code, 1);\n    if (c == RREF_ANY)\n      fprintf(f, \"    %s any\", OP_names[*code]);\n    else\n      fprintf(f, \"    %s %d\", OP_names[*code], c);\n    break;\n\n    case OP_STARI:\n    case OP_MINSTARI:\n    case OP_POSSTARI:\n    case OP_PLUSI:\n    case OP_MINPLUSI:\n    case OP_POSPLUSI:\n    case OP_QUERYI:\n    case OP_MINQUERYI:\n    case OP_POSQUERYI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_STAR:\n    case OP_MINSTAR:\n    case OP_POSSTAR:\n    case OP_PLUS:\n    case OP_MINPLUS:\n    case OP_POSPLUS:\n    case OP_QUERY:\n    case OP_MINQUERY:\n    case OP_POSQUERY:\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEPOSPLUS:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEPOSQUERY:\n    fprintf(f, \" %s \", flag);\n\n    if (*code >= OP_TYPESTAR)\n      {\n      if (code[1] == OP_PROP || code[1] == OP_NOTPROP)\n        {\n        print_prop(f, code + 1, \"\", \" \");\n        extra = 2;\n        }\n      else fprintf(f, \"%s\", OP_names[code[1]]);\n      }\n    else extra = print_char(f, code+1, utf);\n    fprintf(f, \"%s\", OP_names[*code]);\n    break;\n\n    case OP_EXACTI:\n    case OP_UPTOI:\n    case OP_MINUPTOI:\n    case OP_POSUPTOI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_EXACT:\n    case OP_UPTO:\n    case OP_MINUPTO:\n    case OP_POSUPTO:\n    fprintf(f, \" %s \", flag);\n    extra = print_char(f, code + 1 + IMM2_SIZE, utf);\n    fprintf(f, \"{\");\n    if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, \"0,\");\n    fprintf(f, \"%d}\", GET2(code,1));\n    if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, \"?\");\n      else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, \"+\");\n    break;\n\n    case OP_TYPEEXACT:\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEPOSUPTO:\n    if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)\n      {\n      print_prop(f, code + IMM2_SIZE + 1, \"    \", \" \");\n      extra = 2;\n      }\n    else fprintf(f, \"    %s\", OP_names[code[1 + IMM2_SIZE]]);\n    fprintf(f, \"{\");\n    if (*code != OP_TYPEEXACT) fprintf(f, \"0,\");\n    fprintf(f, \"%d}\", GET2(code,1));\n    if (*code == OP_TYPEMINUPTO) fprintf(f, \"?\");\n      else if (*code == OP_TYPEPOSUPTO) fprintf(f, \"+\");\n    break;\n\n    case OP_NOTI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_NOT:\n    fprintf(f, \" %s [^\", flag);\n    extra = print_char(f, code + 1, utf);\n    fprintf(f, \"] (not)\");\n    break;\n\n    case OP_NOTSTARI:\n    case OP_NOTMINSTARI:\n    case OP_NOTPOSSTARI:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUSI:\n    case OP_NOTPOSPLUSI:\n    case OP_NOTQUERYI:\n    case OP_NOTMINQUERYI:\n    case OP_NOTPOSQUERYI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_NOTSTAR:\n    case OP_NOTMINSTAR:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPLUS:\n    case OP_NOTMINPLUS:\n    case OP_NOTPOSPLUS:\n    case OP_NOTQUERY:\n    case OP_NOTMINQUERY:\n    case OP_NOTPOSQUERY:\n    fprintf(f, \" %s [^\", flag);\n    extra = print_char(f, code + 1, utf);\n    fprintf(f, \"]%s (not)\", OP_names[*code]);\n    break;\n\n    case OP_NOTEXACTI:\n    case OP_NOTUPTOI:\n    case OP_NOTMINUPTOI:\n    case OP_NOTPOSUPTOI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_NOTEXACT:\n    case OP_NOTUPTO:\n    case OP_NOTMINUPTO:\n    case OP_NOTPOSUPTO:\n    fprintf(f, \" %s [^\", flag);\n    extra = print_char(f, code + 1 + IMM2_SIZE, utf);\n    fprintf(f, \"]{\");\n    if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, \"0,\");\n    fprintf(f, \"%d}\", GET2(code,1));\n    if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, \"?\");\n      else\n    if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, \"+\");\n    fprintf(f, \" (not)\");\n    break;\n\n    case OP_RECURSE:\n    if (print_lengths) fprintf(f, \"%3d \", GET(code, 1));\n      else fprintf(f, \"    \");\n    fprintf(f, \"%s\", OP_names[*code]);\n    break;\n\n    case OP_REFI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_REF:\n    fprintf(f, \" %s \\\\g{%d}\", flag, GET2(code, 1));\n    i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0;\n    if (i != 0) fprintf(f, \" 0x%02x\", i);\n    ccode = code + OP_lengths[*code];\n    goto CLASS_REF_REPEAT;\n\n    case OP_DNREFI:\n    flag = \"/i\";\n    PCRE2_FALLTHROUGH /* Fall through */\n    case OP_DNREF:\n      {\n      PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;\n      fprintf(f, \" %s \\\\k<\", flag);\n      print_custring(f, entry);\n      fprintf(f, \">%d\", GET2(code, 1 + IMM2_SIZE));\n      i = (*code == OP_DNREFI)? code[1 + 2*IMM2_SIZE] : 0;\n      if (i != 0) fprintf(f, \" 0x%02x\", i);\n      }\n    ccode = code + OP_lengths[*code];\n    goto CLASS_REF_REPEAT;\n\n    case OP_CALLOUT:\n    fprintf(f, \"    %s %d %d %d\", OP_names[*code], code[1 + 2*LINK_SIZE],\n      GET(code, 1), GET(code, 1 + LINK_SIZE));\n    break;\n\n    case OP_CALLOUT_STR:\n    c = code[1 + 4*LINK_SIZE];\n    fprintf(f, \"    %s %c\", OP_names[*code], CHAR_OUTPUT(c));\n    extra = GET(code, 1 + 2*LINK_SIZE);\n    print_custring_bylen(f, code + 2 + 4*LINK_SIZE, extra - 3 - 4*LINK_SIZE);\n    for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)\n      if (c == PRIV(callout_start_delims)[i])\n        {\n        c = PRIV(callout_end_delims)[i];\n        break;\n        }\n    fprintf(f, \"%c %d %d %d\", CHAR_OUTPUT(c), GET(code, 1 + 3*LINK_SIZE),\n      GET(code, 1), GET(code, 1 + LINK_SIZE));\n    break;\n\n    case OP_PROP:\n    case OP_NOTPROP:\n    print_prop(f, code, \"    \", \"\");\n    break;\n\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_ECLASS:\n    extra = GET(code, 1);\n    fprintf(f, \"    eclass[\\n\");\n    /* We print the opcodes contained inside as well. */\n    ccode = code + 1 + LINK_SIZE + 1;\n    if ((ccode[-1] & ECL_MAP) != 0)\n      {\n      const uint8_t *map = (const uint8_t *)ccode;\n      /* The first 6 ASCII characters (SOH...ACK) are totally, utterly useless.\n      If they're set in the bitmap, then it's clearly been formed by negation.*/\n      BOOL print_negated = (map[0] & 0x7e) == 0x7e;\n\n      fprintf(f, \"          bitmap: [%s\", print_negated? \"^\" : \"\");\n      print_map(f, map, print_negated);\n      fprintf(f, \"]\\n\");\n      ccode += 32 / sizeof(PCRE2_UCHAR);\n      }\n    else\n      fprintf(f, \"          no bitmap\\n\");\n    while (ccode < code + extra)\n      {\n      if (print_lengths)\n        fprintf(f, \"%3d \", (int)(ccode - codestart));\n      else\n        fprintf(f, \"    \");\n\n      switch (*ccode)\n        {\n        case ECL_AND:\n        fprintf(f, \"      AND\\n\");\n        ccode += 1;\n        break;\n        case ECL_OR:\n        fprintf(f, \"      OR\\n\");\n        ccode += 1;\n        break;\n        case ECL_XOR:\n        fprintf(f, \"      XOR\\n\");\n        ccode += 1;\n        break;\n        case ECL_NOT:\n        fprintf(f, \"      NOT\\n\");\n        ccode += 1;\n        break;\n\n        case ECL_XCLASS:\n        print_class(f, OP_XCLASS, ccode+1, (uint8_t*)codestart, utf,\n                    \"      xclass: \", \"\\n\");\n        ccode += GET(ccode, 1);\n        break;\n\n        default:\n        fprintf(f, \"      UNEXPECTED\\n\");\n        ccode += 1;\n        break;\n        }\n      }\n    fprintf(f, \"        ]\");\n    goto CLASS_REF_REPEAT;\n#endif  /* SUPPORT_WIDE_CHARS */\n\n    case OP_CLASS:\n    case OP_NCLASS:\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_XCLASS:\n    if (*code == OP_XCLASS)\n      extra = GET(code, 1);\n#endif\n    print_class(f, *code, code+1, (uint8_t*)codestart, utf, \"    \", \"\");\n    ccode = code + OP_lengths[*code] + extra;\n\n    /* Handle repeats after a class or a back reference */\n\n    CLASS_REF_REPEAT:\n    switch(*ccode)\n      {\n      unsigned int min, max;\n\n      case OP_CRSTAR:\n      case OP_CRMINSTAR:\n      case OP_CRPLUS:\n      case OP_CRMINPLUS:\n      case OP_CRQUERY:\n      case OP_CRMINQUERY:\n      case OP_CRPOSSTAR:\n      case OP_CRPOSPLUS:\n      case OP_CRPOSQUERY:\n      fprintf(f, \"%s\", OP_names[*ccode]);\n      extra += OP_lengths[*ccode];\n      break;\n\n      case OP_CRRANGE:\n      case OP_CRMINRANGE:\n      case OP_CRPOSRANGE:\n      min = GET2(ccode,1);\n      max = GET2(ccode,1 + IMM2_SIZE);\n      if (max == 0) fprintf(f, \"{%u,}\", min);\n      else fprintf(f, \"{%u,%u}\", min, max);\n      if (*ccode == OP_CRMINRANGE) fprintf(f, \"?\");\n      else if (*ccode == OP_CRPOSRANGE) fprintf(f, \"+\");\n      extra += OP_lengths[*ccode];\n      break;\n\n      /* Do nothing if it's not a repeat; this code stops picky compilers\n      warning about the lack of a default code path. */\n\n      default:\n      break;\n      }\n    break;\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_SKIP_ARG:\n    case OP_THEN_ARG:\n    fprintf(f, \"    %s \", OP_names[*code]);\n    print_custring_bylen(f, code + 2, code[1]);\n    extra += code[1];\n    break;\n\n    case OP_CIRCM:\n    case OP_DOLLM:\n    flag = \"/m\";\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* Anything else is just an item with no data, but possibly a flag. */\n\n    default:\n    fprintf(f, \" %s %s\", flag, OP_names[*code]);\n    break;\n    }\n\n  code += OP_lengths[*code] + extra;\n  putc('\\n', f);\n  }\n}\n\n/* End of pcre2_printint_inc.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_script_run.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2021 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains the function for checking a script run. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*                Check script run                *\n*************************************************/\n\n/* A script run is conceptually a sequence of characters all in the same\nUnicode script. However, it isn't quite that simple. There are special rules\nfor scripts that are commonly used together, and also special rules for digits.\nThis function implements the appropriate checks, which is possible only when\nPCRE2 is compiled with Unicode support. The function returns TRUE if there is\nno Unicode support; however, it should never be called in that circumstance\nbecause an error is given by pcre2_compile() if a script run is called for in a\nversion of PCRE2 compiled without Unicode support.\n\nArguments:\n  pgr       point to the first character\n  endptr    point after the last character\n  utf       TRUE if in UTF mode\n\nReturns:    TRUE if this is a valid script run\n*/\n\n/* These are states in the checking process. */\n\nenum { SCRIPT_UNSET,          /* Requirement as yet unknown */\n       SCRIPT_MAP,            /* Bitmap contains acceptable scripts */\n       SCRIPT_HANPENDING,     /* Have had only Han characters */\n       SCRIPT_HANHIRAKATA,    /* Expect Han or Hirikata */\n       SCRIPT_HANBOPOMOFO,    /* Expect Han or Bopomofo */\n       SCRIPT_HANHANGUL       /* Expect Han or Hangul */\n       };\n\n#define UCD_MAPSIZE (ucp_Unknown/32 + 1)\n#define FULL_MAPSIZE (ucp_Script_Count/32 + 1)\n\nBOOL\nPRIV(script_run)(PCRE2_SPTR ptr, PCRE2_SPTR endptr, BOOL utf)\n{\n#ifdef SUPPORT_UNICODE\nuint32_t require_state = SCRIPT_UNSET;\nuint32_t require_map[FULL_MAPSIZE];\nuint32_t map[FULL_MAPSIZE];\nuint32_t require_digitset = 0;\nuint32_t c;\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n(void)utf;    /* Avoid compiler warning */\n#endif\n\n/* Any string containing fewer than 2 characters is a valid script run. */\n\nif (ptr >= endptr) return TRUE;\nGETCHARINCTEST(c, ptr);\nif (ptr >= endptr) return TRUE;\n\n/* Initialize the require map. This is a full-size bitmap that has a bit for\nevery script, as opposed to the maps in ucd_script_sets, which only have bits\nfor scripts less than ucp_Unknown - those that appear in script extension\nlists. */\n\nfor (int i = 0; i < FULL_MAPSIZE; i++) require_map[i] = 0;\n\n/* Scan strings of two or more characters, checking the Unicode characteristics\nof each code point. There is special code for scripts that can be combined with\ncharacters from the Han Chinese script. This may be used in conjunction with\nfour other scripts in these combinations:\n\n. Han with Hiragana and Katakana is allowed (for Japanese).\n. Han with Bopomofo is allowed (for Taiwanese Mandarin).\n. Han with Hangul is allowed (for Korean).\n\nIf the first significant character's script is one of the four, the required\nscript type is immediately known. However, if the first significant\ncharacter's script is Han, we have to keep checking for a non-Han character.\nHence the SCRIPT_HANPENDING state. */\n\nfor (;;)\n  {\n  const ucd_record *ucd = GET_UCD(c);\n  uint32_t script = ucd->script;\n\n  /* If the script is Unknown, the string is not a valid script run. Such\n  characters can only form script runs of length one (see test above). */\n\n  if (script == ucp_Unknown) return FALSE;\n\n  /* A character without any script extensions whose script is Inherited or\n  Common is always accepted with any script. If there are extensions, the\n  following processing happens for all scripts. */\n\n  if (UCD_SCRIPTX_PROP(ucd) != 0 || (script != ucp_Inherited && script != ucp_Common))\n    {\n    BOOL OK;\n\n    /* Set up a full-sized map for this character that can include bits for all\n    scripts. Copy the scriptx map for this character (which covers those\n    scripts that appear in script extension lists), set the remaining values to\n    zero, and then, except for Common or Inherited, add this script's bit to\n    the map. */\n\n    memcpy(map, PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(ucd), UCD_MAPSIZE * sizeof(uint32_t));\n    memset(map + UCD_MAPSIZE, 0, (FULL_MAPSIZE - UCD_MAPSIZE) * sizeof(uint32_t));\n    if (script != ucp_Common && script != ucp_Inherited) MAPSET(map, script);\n\n    /* Handle the different checking states */\n\n    switch(require_state)\n      {\n      /* First significant character - it might follow Common or Inherited\n      characters that do not have any script extensions. */\n\n      case SCRIPT_UNSET:\n      switch(script)\n        {\n        case ucp_Han:\n        require_state = SCRIPT_HANPENDING;\n        break;\n\n        case ucp_Hiragana:\n        case ucp_Katakana:\n        require_state = SCRIPT_HANHIRAKATA;\n        break;\n\n        case ucp_Bopomofo:\n        require_state = SCRIPT_HANBOPOMOFO;\n        break;\n\n        case ucp_Hangul:\n        require_state = SCRIPT_HANHANGUL;\n        break;\n\n        default:\n        memcpy(require_map, map, FULL_MAPSIZE * sizeof(uint32_t));\n        require_state = SCRIPT_MAP;\n        break;\n        }\n      break;\n\n      /* The first significant character was Han. An inspection of the Unicode\n      11.0.0 files shows that there are the following types of Script Extension\n      list that involve the Han, Bopomofo, Hiragana, Katakana, and Hangul\n      scripts:\n\n      . Bopomofo + Han\n      . Han + Hiragana + Katakana\n      . Hiragana + Katakana\n      . Bopopmofo + Hangul + Han + Hiragana + Katakana\n\n      The following code tries to make sense of this. */\n\n#define FOUND_BOPOMOFO 1\n#define FOUND_HIRAGANA 2\n#define FOUND_KATAKANA 4\n#define FOUND_HANGUL   8\n\n      case SCRIPT_HANPENDING:\n      if (script != ucp_Han)   /* Another Han does nothing */\n        {\n        uint32_t chspecial = 0;\n\n        if (MAPBIT(map, ucp_Bopomofo) != 0) chspecial |= FOUND_BOPOMOFO;\n        if (MAPBIT(map, ucp_Hiragana) != 0) chspecial |= FOUND_HIRAGANA;\n        if (MAPBIT(map, ucp_Katakana) != 0) chspecial |= FOUND_KATAKANA;\n        if (MAPBIT(map, ucp_Hangul) != 0)   chspecial |= FOUND_HANGUL;\n\n        if (chspecial == 0) return FALSE;   /* Not allowed with Han */\n\n        if (chspecial == FOUND_BOPOMOFO)\n          require_state = SCRIPT_HANBOPOMOFO;\n        else if (chspecial == (FOUND_HIRAGANA|FOUND_KATAKANA))\n          require_state = SCRIPT_HANHIRAKATA;\n\n        /* Otherwise this character must be allowed with all of them, so remain\n        in the pending state. */\n        }\n      break;\n\n      /* Previously encountered one of the \"with Han\" scripts. Check that\n      this character is appropriate. */\n\n      case SCRIPT_HANHIRAKATA:\n      if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Hiragana) +\n          MAPBIT(map, ucp_Katakana) == 0) return FALSE;\n      break;\n\n      case SCRIPT_HANBOPOMOFO:\n      if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Bopomofo) == 0) return FALSE;\n      break;\n\n      case SCRIPT_HANHANGUL:\n      if (MAPBIT(map, ucp_Han) + MAPBIT(map, ucp_Hangul) == 0) return FALSE;\n      break;\n\n      /* Previously encountered one or more characters that are allowed with a\n      list of scripts. */\n\n      case SCRIPT_MAP:\n      OK = FALSE;\n\n      for (int i = 0; i < FULL_MAPSIZE; i++)\n        {\n        if ((require_map[i] & map[i]) != 0)\n          {\n          OK = TRUE;\n          break;\n          }\n        }\n\n      if (!OK) return FALSE;\n\n      /* The rest of the string must be in this script, but we have to\n      allow for the Han complications. */\n\n      switch(script)\n        {\n        case ucp_Han:\n        require_state = SCRIPT_HANPENDING;\n        break;\n\n        case ucp_Hiragana:\n        case ucp_Katakana:\n        require_state = SCRIPT_HANHIRAKATA;\n        break;\n\n        case ucp_Bopomofo:\n        require_state = SCRIPT_HANBOPOMOFO;\n        break;\n\n        case ucp_Hangul:\n        require_state = SCRIPT_HANHANGUL;\n        break;\n\n        /* Compute the intersection of the required list of scripts and the\n        allowed scripts for this character. */\n\n        default:\n        for (int i = 0; i < FULL_MAPSIZE; i++) require_map[i] &= map[i];\n        break;\n        }\n\n      break;\n      }\n    }   /* End checking character's script and extensions. */\n\n  /* The character is in an acceptable script. We must now ensure that all\n  decimal digits in the string come from the same set. Some scripts (e.g.\n  Common, Arabic) have more than one set of decimal digits. This code does\n  not allow mixing sets, even within the same script. The vector called\n  PRIV(ucd_digit_sets)[] contains, in its first element, the number of\n  following elements, and then, in ascending order, the code points of the\n  '9' characters in every set of 10 digits. Each set is identified by the\n  offset in the vector of its '9' character. An initial check of the first\n  value picks up ASCII digits quickly. Otherwise, a binary chop is used. */\n\n  if (ucd->chartype == ucp_Nd)\n    {\n    uint32_t digitset;\n\n    if (c <= PRIV(ucd_digit_sets)[1]) digitset = 1; else\n      {\n      int mid;\n      int bot = 1;\n      int top = PRIV(ucd_digit_sets)[0];\n      for (;;)\n        {\n        if (top <= bot + 1)    /* <= rather than == is paranoia */\n          {\n          digitset = top;\n          break;\n          }\n        mid = (top + bot) / 2;\n        if (c <= PRIV(ucd_digit_sets)[mid]) top = mid; else bot = mid;\n        }\n      }\n\n    /* A required value of 0 means \"unset\". */\n\n    if (require_digitset == 0) require_digitset = digitset;\n      else if (digitset != require_digitset) return FALSE;\n    }   /* End digit handling */\n\n  /* If we haven't yet got to the end, pick up the next character. */\n\n  if (ptr >= endptr) return TRUE;\n  GETCHARINCTEST(c, ptr);\n  }  /* End checking loop */\n\n#else   /* NOT SUPPORT_UNICODE */\n(void)ptr;\n(void)endptr;\n(void)utf;\nreturn TRUE;\n#endif  /* SUPPORT_UNICODE */\n}\n\n/* End of pcre2_script_run.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_serialize.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains functions for serializing and deserializing\na sequence of compiled codes. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* Magic number to provide a small check against being handed junk. */\n\n#define SERIALIZED_DATA_MAGIC 0x50523253u\n\n/* Deserialization is limited to the current PCRE version and\ncharacter width. */\n\n#define SERIALIZED_DATA_VERSION \\\n  ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16))\n\n#define SERIALIZED_DATA_CONFIG \\\n  (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16))\n\n\n\n/*************************************************\n*           Serialize compiled patterns          *\n*************************************************/\n\nPCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION\npcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes,\n   uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size,\n   pcre2_general_context *gcontext)\n{\nuint8_t *bytes;\nuint8_t *dst_bytes;\nint32_t i;\nPCRE2_SIZE total_size;\nconst pcre2_real_code *re;\nconst uint8_t *tables;\npcre2_serialized_data *data;\n\nconst pcre2_memctl *memctl = (gcontext != NULL) ?\n  &gcontext->memctl : &PRIV(default_compile_context).memctl;\n\nif (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)\n  return PCRE2_ERROR_NULL;\n\nif (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;\n\n/* Compute total size. */\ntotal_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH;\ntables = NULL;\n\nfor (i = 0; i < number_of_codes; i++)\n  {\n  if (codes[i] == NULL) return PCRE2_ERROR_NULL;\n  re = (const pcre2_real_code *)(codes[i]);\n  if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;\n  if (tables == NULL)\n    tables = re->tables;\n  else if (tables != re->tables)\n    return PCRE2_ERROR_MIXEDTABLES;\n  total_size += re->blocksize;\n  }\n\n/* Initialize the byte stream. */\nbytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data);\nif (bytes == NULL) return PCRE2_ERROR_NOMEMORY;\n\n/* The controller is stored as a hidden parameter. */\nmemcpy(bytes, memctl, sizeof(pcre2_memctl));\nbytes += sizeof(pcre2_memctl);\n\ndata = (pcre2_serialized_data *)bytes;\ndata->magic = SERIALIZED_DATA_MAGIC;\ndata->version = SERIALIZED_DATA_VERSION;\ndata->config = SERIALIZED_DATA_CONFIG;\ndata->number_of_codes = number_of_codes;\n\n/* Copy all compiled code data. */\ndst_bytes = bytes + sizeof(pcre2_serialized_data);\nmemcpy(dst_bytes, tables, TABLES_LENGTH);\ndst_bytes += TABLES_LENGTH;\n\nfor (i = 0; i < number_of_codes; i++)\n  {\n  re = (const pcre2_real_code *)(codes[i]);\n  (void)memcpy(dst_bytes, (const char *)re, re->blocksize);\n\n  /* Certain fields in the compiled code block are re-set during\n  deserialization. In order to ensure that the serialized data stream is always\n  the same for the same pattern, set them to zero here. We can't assume the\n  copy of the pattern is correctly aligned for accessing the fields as part of\n  a structure. Note the use of sizeof(void *) in the second of these, to\n  specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a\n  pointer to uint8_t), gcc gives a warning because the first argument is also a\n  pointer to uint8_t. Casting the first argument to (void *) can stop this, but\n  it didn't stop Coverity giving the same complaint. */\n\n  (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0,\n    sizeof(pcre2_memctl));\n  (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0,\n    sizeof(void *));\n  (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0,\n    sizeof(void *));\n\n  dst_bytes += re->blocksize;\n  }\n\n*serialized_bytes = bytes;\n*serialized_size = total_size;\nreturn number_of_codes;\n}\n\n\n/*************************************************\n*          Deserialize compiled patterns         *\n*************************************************/\n\nPCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION\npcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes,\n   const uint8_t *bytes, pcre2_general_context *gcontext)\n{\nconst pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;\nconst pcre2_memctl *memctl = (gcontext != NULL) ?\n  &gcontext->memctl : &PRIV(default_compile_context).memctl;\n\nconst uint8_t *src_bytes;\npcre2_real_code *dst_re;\nuint8_t *tables;\nint32_t i, j;\n\n/* Sanity checks. */\n\nif (data == NULL || codes == NULL) return PCRE2_ERROR_NULL;\nif (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;\nif (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA;\nif (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;\nif (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;\nif (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;\n\nif (number_of_codes > data->number_of_codes)\n  number_of_codes = data->number_of_codes;\n\nsrc_bytes = bytes + sizeof(pcre2_serialized_data);\n\n/* Decode tables. The reference count for the tables is stored immediately\nfollowing them. */\n\ntables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data);\nif (tables == NULL) return PCRE2_ERROR_NOMEMORY;\n\nmemcpy(tables, src_bytes, TABLES_LENGTH);\n*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes;\nsrc_bytes += TABLES_LENGTH;\n\n/* Decode the byte stream. We must not try to read the size from the compiled\ncode block in the stream, because it might be unaligned, which causes errors on\nhardware such as Sparc-64 that doesn't like unaligned memory accesses. The type\nof the blocksize field is given its own name to ensure that it is the same here\nas in the block. */\n\nfor (i = 0; i < number_of_codes; i++)\n  {\n  CODE_BLOCKSIZE_TYPE blocksize;\n  memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize),\n    sizeof(CODE_BLOCKSIZE_TYPE));\n  if (blocksize <= sizeof(pcre2_real_code))\n    return PCRE2_ERROR_BADSERIALIZEDDATA;\n\n  /* The allocator provided by gcontext replaces the original one. */\n\n  dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize,\n    (pcre2_memctl *)gcontext);\n  if (dst_re == NULL)\n    {\n    memctl->free(tables, memctl->memory_data);\n    for (j = 0; j < i; j++)\n      {\n      memctl->free(codes[j], memctl->memory_data);\n      codes[j] = NULL;\n      }\n    return PCRE2_ERROR_NOMEMORY;\n    }\n\n  /* The new allocator must be preserved. */\n\n  memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl),\n    src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl));\n  if (dst_re->magic_number != MAGIC_NUMBER ||\n      dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 ||\n      dst_re->name_count > MAX_NAME_COUNT)\n    {\n    memctl->free(dst_re, memctl->memory_data);\n    return PCRE2_ERROR_BADSERIALIZEDDATA;\n    }\n\n  /* At the moment only one table is supported. */\n\n  dst_re->tables = tables;\n  dst_re->executable_jit = NULL;\n  dst_re->flags |= PCRE2_DEREF_TABLES;\n\n  codes[i] = dst_re;\n  src_bytes += blocksize;\n  }\n\nreturn number_of_codes;\n}\n\n\n/*************************************************\n*    Get the number of serialized patterns       *\n*************************************************/\n\nPCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION\npcre2_serialize_get_number_of_codes(const uint8_t *bytes)\n{\nconst pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;\n\nif (data == NULL) return PCRE2_ERROR_NULL;\nif (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;\nif (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;\nif (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;\n\nreturn data->number_of_codes;\n}\n\n\n/*************************************************\n*            Free the allocated stream           *\n*************************************************/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_serialize_free(uint8_t *bytes)\n{\nif (bytes != NULL)\n  {\n  pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl));\n  memctl->free(memctl, memctl->memory_data);\n  }\n}\n\n/* End of pcre2_serialize.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_string_utils.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2018-2021 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains internal functions for comparing and finding the length\nof strings. These are used instead of strcmp() etc because the standard\nfunctions work only on 8-bit data. */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*    Compare two zero-terminated PCRE2 strings   *\n*************************************************/\n\n/*\nArguments:\n  str1        first string\n  str2        second string\n\nReturns:      0, 1, or -1\n*/\n\nint\nPRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2)\n{\nPCRE2_UCHAR c1, c2;\nwhile (*str1 != '\\0' || *str2 != '\\0')\n  {\n  c1 = *str1++;\n  c2 = *str2++;\n  if (c1 != c2) return ((c1 > c2) << 1) - 1;\n  }\nreturn 0;\n}\n\n\n/*************************************************\n*  Compare zero-terminated PCRE2 & 8-bit strings *\n*************************************************/\n\n/* As the 8-bit string is almost always a literal, its type is specified as\nconst char *.\n\nArguments:\n  str1        first string\n  str2        second string\n\nReturns:      0, 1, or -1\n*/\n\nint\nPRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2)\n{\nPCRE2_UCHAR c1, c2;\nwhile (*str1 != '\\0' || *str2 != '\\0')\n  {\n  c1 = *str1++;\n  c2 = *str2++;\n  if (c1 != c2) return ((c1 > c2) << 1) - 1;\n  }\nreturn 0;\n}\n\n\n/*************************************************\n*    Compare two PCRE2 strings, given a length   *\n*************************************************/\n\n/*\nArguments:\n  str1        first string\n  str2        second string\n  len         the length\n\nReturns:      0, 1, or -1\n*/\n\nint\nPRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len)\n{\nPCRE2_UCHAR c1, c2;\nfor (; len > 0; len--)\n  {\n  c1 = *str1++;\n  c2 = *str2++;\n  if (c1 != c2) return ((c1 > c2) << 1) - 1;\n  }\nreturn 0;\n}\n\n\n/*************************************************\n* Compare PCRE2 string to 8-bit string by length *\n*************************************************/\n\n/* As the 8-bit string is almost always a literal, its type is specified as\nconst char *.\n\nArguments:\n  str1        first string\n  str2        second string\n  len         the length\n\nReturns:      0, 1, or -1\n*/\n\nint\nPRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len)\n{\nPCRE2_UCHAR c1, c2;\nfor (; len > 0; len--)\n  {\n  c1 = *str1++;\n  c2 = *str2++;\n  if (c1 != c2) return ((c1 > c2) << 1) - 1;\n  }\nreturn 0;\n}\n\n\n/*************************************************\n*        Find the length of a PCRE2 string       *\n*************************************************/\n\n/*\nArgument:    the string\nReturns:     the length\n*/\n\nPCRE2_SIZE\nPRIV(strlen)(PCRE2_SPTR str)\n{\nPCRE2_SIZE c = 0;\nwhile (*str++ != 0) c++;\nreturn c;\n}\n\n\n/*************************************************\n* Copy 8-bit 0-terminated string to PCRE2 string *\n*************************************************/\n\n/* Arguments:\n  str1     buffer to receive the string\n  str2     8-bit string to be copied\n\nReturns:   the number of code units used (excluding trailing zero)\n*/\n\nPCRE2_SIZE\nPRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2)\n{\nPCRE2_UCHAR *t = str1;\nwhile (*str2 != 0) *t++ = *str2++;\n*t = 0;\nreturn t - str1;\n}\n\n/* End of pcre2_string_utils.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_study.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains functions for scanning a compiled pattern and\ncollecting data (e.g. minimum matching length). */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/* The maximum remembered capturing brackets minimum. */\n\n#define MAX_CACHE_BACKREF 128\n\n/* Set a bit in the starting code unit bit map. */\n\n#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1u << ((c)&7))\n\n/* Returns from set_start_bits() */\n\nenum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP };\n\n\n/*************************************************\n*   Find the minimum subject length for a group  *\n*************************************************/\n\n/* Scan a parenthesized group and compute the minimum length of subject that\nis needed to match it. This is a lower bound; it does not mean there is a\nstring of that length that matches. In UTF mode, the result is in characters\nrather than code units. The field in a compiled pattern for storing the minimum\nlength is 16-bits long (on the grounds that anything longer than that is\npathological), so we give up when we reach that amount. This also means that\ninteger overflow for really crazy patterns cannot happen.\n\nBackreference minimum lengths are cached to speed up multiple references. This\nfunction is called only when the highest back reference in the pattern is less\nthan or equal to MAX_CACHE_BACKREF, which is one less than the size of the\ncaching vector. The zeroth element contains the number of the highest set\nvalue.\n\nArguments:\n  re              compiled pattern block\n  code            pointer to start of group (the bracket)\n  startcode       pointer to start of the whole pattern's code\n  utf             UTF flag\n  recurses        chain of recurse_check to catch mutual recursion\n  countptr        pointer to call count (to catch over complexity)\n  backref_cache   vector for caching back references.\n\nThis function is no longer called when the pattern contains (*ACCEPT); however,\nthe old code for returning -1 is retained, just in case.\n\nReturns:   the minimum length\n           -1 \\C in UTF-8 mode\n              or (*ACCEPT)\n              or pattern too complicated\n           -2 internal error (missing capturing bracket)\n           -3 internal error (opcode not listed)\n*/\n\nstatic int\nfind_minlength(const pcre2_real_code *re, PCRE2_SPTR code,\n  PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr,\n  int *backref_cache)\n{\nint length = -1;\nint branchlength = 0;\nint prev_cap_recno = -1;\nint prev_cap_d = 0;\nint prev_recurse_recno = -1;\nint prev_recurse_d = 0;\nuint32_t once_fudge = 0;\nBOOL had_recurse = FALSE;\nBOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;\nPCRE2_SPTR nextbranch = code + GET(code, 1);\nPCRE2_SPTR cc = code + 1 + LINK_SIZE;\nrecurse_check this_recurse;\n\n/* If this is a \"could be empty\" group, its minimum length is 0. */\n\nif (*code >= OP_SBRA && *code <= OP_SCOND) return 0;\n\n/* Skip over capturing bracket number */\n\nif (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE;\n\n/* A large and/or complex regex can take too long to process. */\n\nif ((*countptr)++ > 1000) return -1;\n\n/* Scan along the opcodes for this branch. If we get to the end of the branch,\ncheck the length against that of the other branches. If the accumulated length\npasses 16-bits, reset to that value and skip the rest of the branch. */\n\nfor (;;)\n  {\n  int d, min, recno;\n  PCRE2_UCHAR op;\n  PCRE2_SPTR cs, ce;\n\n  if (branchlength >= (int)UINT16_MAX)\n    {\n    branchlength = UINT16_MAX;\n    cc = nextbranch;\n    }\n\n  op = *cc;\n  switch (op)\n    {\n    case OP_COND:\n    case OP_SCOND:\n\n    /* If there is only one branch in a condition, the implied branch has zero\n    length, so we don't add anything. This covers the DEFINE \"condition\"\n    automatically. If there are two branches we can treat it the same as any\n    other non-capturing subpattern. */\n\n    cs = cc + GET(cc, 1);\n    if (*cs != OP_ALT)\n      {\n      cc = cs + 1 + LINK_SIZE;\n      break;\n      }\n    goto PROCESS_NON_CAPTURE;\n\n    case OP_BRA:\n    /* There's a special case of OP_BRA, when it is wrapped round a repeated\n    OP_RECURSE. We'd like to process the latter at this level so that\n    remembering the value works for repeated cases. So we do nothing, but\n    set a fudge value to skip over the OP_KET after the recurse. */\n\n    if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET)\n      {\n      once_fudge = 1 + LINK_SIZE;\n      cc += 1 + LINK_SIZE;\n      break;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_ONCE:\n    case OP_SCRIPT_RUN:\n    case OP_SBRA:\n    case OP_BRAPOS:\n    case OP_SBRAPOS:\n    PROCESS_NON_CAPTURE:\n    d = find_minlength(re, cc, startcode, utf, recurses, countptr,\n      backref_cache);\n    if (d < 0) return d;\n    branchlength += d;\n    do cc += GET(cc, 1); while (*cc == OP_ALT);\n    cc += 1 + LINK_SIZE;\n    break;\n\n    /* To save time for repeated capturing subpatterns, we remember the\n    length of the previous one. Unfortunately we can't do the same for\n    the unnumbered ones above. Nor can we do this if (?| is present in the\n    pattern because captures with the same number are not then identical. */\n\n    case OP_CBRA:\n    case OP_SCBRA:\n    case OP_CBRAPOS:\n    case OP_SCBRAPOS:\n    recno = (int)GET2(cc, 1+LINK_SIZE);\n    if (dupcapused || recno != prev_cap_recno)\n      {\n      prev_cap_recno = recno;\n      prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr,\n        backref_cache);\n      if (prev_cap_d < 0) return prev_cap_d;\n      }\n    branchlength += prev_cap_d;\n    do cc += GET(cc, 1); while (*cc == OP_ALT);\n    cc += 1 + LINK_SIZE;\n    break;\n\n    /* ACCEPT makes things far too complicated; we have to give up. In fact,\n    from 10.34 onwards, if a pattern contains (*ACCEPT), this function is not\n    used. However, leave the code in place, just in case. */\n\n    case OP_ACCEPT:\n    case OP_ASSERT_ACCEPT:\n    return -1;\n\n    /* Reached end of a branch; if it's a ket it is the end of a nested\n    call. If it's ALT it is an alternation in a nested call. If it is END it's\n    the end of the outer call. All can be handled by the same code. If the\n    length of any branch is zero, there is no need to scan any subsequent\n    branches. */\n\n    case OP_ALT:\n    case OP_KET:\n    case OP_KETRMAX:\n    case OP_KETRMIN:\n    case OP_KETRPOS:\n    case OP_END:\n    if (length < 0 || (!had_recurse && branchlength < length))\n      length = branchlength;\n    if (op != OP_ALT || length == 0) return length;\n    nextbranch = cc + GET(cc, 1);\n    cc += 1 + LINK_SIZE;\n    branchlength = 0;\n    had_recurse = FALSE;\n    break;\n\n    /* Skip over assertive subpatterns */\n\n    case OP_ASSERT:\n    case OP_ASSERT_NOT:\n    case OP_ASSERTBACK:\n    case OP_ASSERTBACK_NOT:\n    case OP_ASSERT_NA:\n    case OP_ASSERT_SCS:\n    case OP_ASSERTBACK_NA:\n    do cc += GET(cc, 1); while (*cc == OP_ALT);\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    /* Skip over things that don't match chars */\n\n    case OP_REVERSE:\n    case OP_VREVERSE:\n    case OP_CREF:\n    case OP_DNCREF:\n    case OP_RREF:\n    case OP_DNRREF:\n    case OP_FALSE:\n    case OP_TRUE:\n    case OP_CALLOUT:\n    case OP_SOD:\n    case OP_SOM:\n    case OP_EOD:\n    case OP_EODN:\n    case OP_CIRC:\n    case OP_CIRCM:\n    case OP_DOLL:\n    case OP_DOLLM:\n    case OP_NOT_WORD_BOUNDARY:\n    case OP_WORD_BOUNDARY:\n    case OP_NOT_UCP_WORD_BOUNDARY:\n    case OP_UCP_WORD_BOUNDARY:\n    cc += PRIV(OP_lengths)[*cc];\n    break;\n\n    case OP_CALLOUT_STR:\n    cc += GET(cc, 1 + 2*LINK_SIZE);\n    break;\n\n    /* Skip over a subpattern that has a {0} or {0,x} quantifier */\n\n    case OP_BRAZERO:\n    case OP_BRAMINZERO:\n    case OP_BRAPOSZERO:\n    case OP_SKIPZERO:\n    cc += PRIV(OP_lengths)[*cc];\n    do cc += GET(cc, 1); while (*cc == OP_ALT);\n    cc += 1 + LINK_SIZE;\n    break;\n\n    /* Handle literal characters and + repetitions */\n\n    case OP_CHAR:\n    case OP_CHARI:\n    case OP_NOT:\n    case OP_NOTI:\n    case OP_PLUS:\n    case OP_PLUSI:\n    case OP_MINPLUS:\n    case OP_MINPLUSI:\n    case OP_POSPLUS:\n    case OP_POSPLUSI:\n    case OP_NOTPLUS:\n    case OP_NOTPLUSI:\n    case OP_NOTMINPLUS:\n    case OP_NOTMINPLUSI:\n    case OP_NOTPOSPLUS:\n    case OP_NOTPOSPLUSI:\n    branchlength++;\n    cc += 2;\n#ifdef SUPPORT_UNICODE\n    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    case OP_TYPEPLUS:\n    case OP_TYPEMINPLUS:\n    case OP_TYPEPOSPLUS:\n    branchlength++;\n    cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;\n    break;\n\n    /* Handle exact repetitions. The count is already in characters, but we\n    may need to skip over a multibyte character in UTF mode.  */\n\n    case OP_EXACT:\n    case OP_EXACTI:\n    case OP_NOTEXACT:\n    case OP_NOTEXACTI:\n    branchlength += GET2(cc,1);\n    cc += 2 + IMM2_SIZE;\n#ifdef SUPPORT_UNICODE\n    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    case OP_TYPEEXACT:\n    branchlength += GET2(cc,1);\n    cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP\n      || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);\n    break;\n\n    /* Handle single-char non-literal matchers */\n\n    case OP_PROP:\n    case OP_NOTPROP:\n    cc += 2;\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case OP_NOT_DIGIT:\n    case OP_DIGIT:\n    case OP_NOT_WHITESPACE:\n    case OP_WHITESPACE:\n    case OP_NOT_WORDCHAR:\n    case OP_WORDCHAR:\n    case OP_ANY:\n    case OP_ALLANY:\n    case OP_EXTUNI:\n    case OP_HSPACE:\n    case OP_NOT_HSPACE:\n    case OP_VSPACE:\n    case OP_NOT_VSPACE:\n    branchlength++;\n    cc++;\n    break;\n\n    /* \"Any newline\" might match two characters, but it also might match just\n    one. */\n\n    case OP_ANYNL:\n    branchlength += 1;\n    cc++;\n    break;\n\n    /* The single-byte matcher means we can't proceed in UTF mode. (In\n    non-UTF mode \\C will actually be turned into OP_ALLANY, so won't ever\n    appear, but leave the code, just in case.) */\n\n    case OP_ANYBYTE:\n#ifdef SUPPORT_UNICODE\n    if (utf) return -1;\n#endif\n    branchlength++;\n    cc++;\n    break;\n\n    /* For repeated character types, we have to test for \\p and \\P, which have\n    an extra two bytes of parameters. */\n\n    case OP_TYPESTAR:\n    case OP_TYPEMINSTAR:\n    case OP_TYPEQUERY:\n    case OP_TYPEMINQUERY:\n    case OP_TYPEPOSSTAR:\n    case OP_TYPEPOSQUERY:\n    if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;\n    cc += PRIV(OP_lengths)[op];\n    break;\n\n    case OP_TYPEUPTO:\n    case OP_TYPEMINUPTO:\n    case OP_TYPEPOSUPTO:\n    if (cc[1 + IMM2_SIZE] == OP_PROP\n      || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;\n    cc += PRIV(OP_lengths)[op];\n    break;\n\n    /* Check a class for variable quantification */\n\n    case OP_CLASS:\n    case OP_NCLASS:\n#ifdef SUPPORT_WIDE_CHARS\n    case OP_XCLASS:\n    case OP_ECLASS:\n    /* The original code caused an unsigned overflow in 64 bit systems,\n    so now we use a conditional statement. */\n    if (op == OP_XCLASS || op == OP_ECLASS)\n      cc += GET(cc, 1);\n    else\n#endif\n      cc += PRIV(OP_lengths)[OP_CLASS];\n\n    switch (*cc)\n      {\n      case OP_CRPLUS:\n      case OP_CRMINPLUS:\n      case OP_CRPOSPLUS:\n      branchlength++;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_CRSTAR:\n      case OP_CRMINSTAR:\n      case OP_CRQUERY:\n      case OP_CRMINQUERY:\n      case OP_CRPOSSTAR:\n      case OP_CRPOSQUERY:\n      cc++;\n      break;\n\n      case OP_CRRANGE:\n      case OP_CRMINRANGE:\n      case OP_CRPOSRANGE:\n      branchlength += GET2(cc,1);\n      cc += 1 + 2 * IMM2_SIZE;\n      break;\n\n      default:\n      branchlength++;\n      break;\n      }\n    break;\n\n    /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same\n    way: we find the minimum length for the subpattern. A recursion\n    (backreference or subroutine) causes an a flag to be set that causes the\n    length of this branch to be ignored. The logic is that a recursion can only\n    make sense if there is another alternative that stops the recursing. That\n    will provide the minimum length (when no recursion happens).\n\n    If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket\n    matches an empty string (by default it causes a matching failure), so in\n    that case we must set the minimum length to zero.\n\n    For backreferenes, if duplicate numbers are present in the pattern we check\n    for a reference to a duplicate. If it is, we don't know which version will\n    be referenced, so we have to set the minimum length to zero. */\n\n    /* Duplicate named pattern back reference. */\n\n    case OP_DNREF:\n    case OP_DNREFI:\n    if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)\n      {\n      int count = GET2(cc, 1+IMM2_SIZE);\n      PCRE2_SPTR slot =\n        (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)) +\n          GET2(cc, 1) * re->name_entry_size;\n\n      d = INT_MAX;\n\n      /* Scan all groups with the same name; find the shortest. */\n\n      while (count-- > 0)\n        {\n        int dd, i;\n        recno = GET2(slot, 0);\n\n        if (recno <= backref_cache[0] && backref_cache[recno] >= 0)\n          dd = backref_cache[recno];\n        else\n          {\n          ce = cs = PRIV(find_bracket)(startcode, utf, recno);\n          if (cs == NULL) return -2;\n          do ce += GET(ce, 1); while (*ce == OP_ALT);\n\n          dd = 0;\n          if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL)\n            {\n            if (cc > cs && cc < ce)    /* Simple recursion */\n              {\n              had_recurse = TRUE;\n              }\n            else\n              {\n              recurse_check *r = recurses;\n              for (r = recurses; r != NULL; r = r->prev)\n                if (r->group == cs) break;\n              if (r != NULL)           /* Mutual recursion */\n                {\n                had_recurse = TRUE;\n                }\n              else\n                {\n                this_recurse.prev = recurses;  /* No recursion */\n                this_recurse.group = cs;\n                dd = find_minlength(re, cs, startcode, utf, &this_recurse,\n                  countptr, backref_cache);\n                if (dd < 0) return dd;\n                }\n              }\n            }\n\n          backref_cache[recno] = dd;\n          for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;\n          backref_cache[0] = recno;\n          }\n\n        if (dd < d) d = dd;\n        if (d <= 0) break;    /* No point looking at any more */\n        slot += re->name_entry_size;\n        }\n      }\n    else d = 0;\n    cc += PRIV(OP_lengths)[*cc];\n    goto REPEAT_BACK_REFERENCE;\n\n    /* Single back reference by number. References by name are converted to by\n    number when there is no duplication. */\n\n    case OP_REF:\n    case OP_REFI:\n    recno = GET2(cc, 1);\n    if (recno <= backref_cache[0] && backref_cache[recno] >= 0)\n      d = backref_cache[recno];\n    else\n      {\n      int i;\n      d = 0;\n\n      if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)\n        {\n        ce = cs = PRIV(find_bracket)(startcode, utf, recno);\n        if (cs == NULL) return -2;\n        do ce += GET(ce, 1); while (*ce == OP_ALT);\n\n        if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL)\n          {\n          if (cc > cs && cc < ce)    /* Simple recursion */\n            {\n            had_recurse = TRUE;\n            }\n          else\n            {\n            recurse_check *r = recurses;\n            for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;\n            if (r != NULL)           /* Mutual recursion */\n              {\n              had_recurse = TRUE;\n              }\n            else                     /* No recursion */\n              {\n              this_recurse.prev = recurses;\n              this_recurse.group = cs;\n              d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,\n                backref_cache);\n              if (d < 0) return d;\n              }\n            }\n          }\n        }\n\n      backref_cache[recno] = d;\n      for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;\n      backref_cache[0] = recno;\n      }\n\n    cc += PRIV(OP_lengths)[*cc];\n\n    /* Handle repeated back references */\n\n    REPEAT_BACK_REFERENCE:\n    switch (*cc)\n      {\n      case OP_CRSTAR:\n      case OP_CRMINSTAR:\n      case OP_CRQUERY:\n      case OP_CRMINQUERY:\n      case OP_CRPOSSTAR:\n      case OP_CRPOSQUERY:\n      min = 0;\n      cc++;\n      break;\n\n      case OP_CRPLUS:\n      case OP_CRMINPLUS:\n      case OP_CRPOSPLUS:\n      min = 1;\n      cc++;\n      break;\n\n      case OP_CRRANGE:\n      case OP_CRMINRANGE:\n      case OP_CRPOSRANGE:\n      min = GET2(cc, 1);\n      cc += 1 + 2 * IMM2_SIZE;\n      break;\n\n      default:\n      min = 1;\n      break;\n      }\n\n    /* Take care not to overflow: (1) min and d are ints, so check that their\n    product is not greater than INT_MAX. (2) branchlength is limited to\n    UINT16_MAX (checked at the top of the loop). */\n\n    if ((d > 0 && (INT_MAX/d) < min) || (int)UINT16_MAX - branchlength < min*d)\n      branchlength = UINT16_MAX;\n    else branchlength += min * d;\n    break;\n\n    /* Recursion always refers to the first occurrence of a subpattern with a\n    given number. Therefore, we can always make use of caching, even when the\n    pattern contains multiple subpatterns with the same number. */\n\n    case OP_RECURSE:\n    cs = ce = startcode + GET(cc, 1);\n    recno = GET2(cs, 1+LINK_SIZE);\n    if (recno == prev_recurse_recno)\n      {\n      branchlength += prev_recurse_d;\n      }\n    else\n      {\n      do ce += GET(ce, 1); while (*ce == OP_ALT);\n      if (cc > cs && cc < ce)    /* Simple recursion */\n        had_recurse = TRUE;\n      else\n        {\n        recurse_check *r = recurses;\n        for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;\n        if (r != NULL)          /* Mutual recursion */\n          had_recurse = TRUE;\n        else\n          {\n          this_recurse.prev = recurses;\n          this_recurse.group = cs;\n          prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse,\n            countptr, backref_cache);\n          if (prev_recurse_d < 0) return prev_recurse_d;\n          prev_recurse_recno = recno;\n          branchlength += prev_recurse_d;\n          }\n        }\n      }\n    cc += 1 + LINK_SIZE + once_fudge;\n    once_fudge = 0;\n    break;\n\n    /* Anything else does not or need not match a character. We can get the\n    item's length from the table, but for those that can match zero occurrences\n    of a character, we must take special action for UTF-8 characters. As it\n    happens, the \"NOT\" versions of these opcodes are used at present only for\n    ASCII characters, so they could be omitted from this list. However, in\n    future that may change, so we include them here so as not to leave a\n    gotcha for a future maintainer. */\n\n    case OP_UPTO:\n    case OP_UPTOI:\n    case OP_NOTUPTO:\n    case OP_NOTUPTOI:\n    case OP_MINUPTO:\n    case OP_MINUPTOI:\n    case OP_NOTMINUPTO:\n    case OP_NOTMINUPTOI:\n    case OP_POSUPTO:\n    case OP_POSUPTOI:\n    case OP_NOTPOSUPTO:\n    case OP_NOTPOSUPTOI:\n\n    case OP_STAR:\n    case OP_STARI:\n    case OP_NOTSTAR:\n    case OP_NOTSTARI:\n    case OP_MINSTAR:\n    case OP_MINSTARI:\n    case OP_NOTMINSTAR:\n    case OP_NOTMINSTARI:\n    case OP_POSSTAR:\n    case OP_POSSTARI:\n    case OP_NOTPOSSTAR:\n    case OP_NOTPOSSTARI:\n\n    case OP_QUERY:\n    case OP_QUERYI:\n    case OP_NOTQUERY:\n    case OP_NOTQUERYI:\n    case OP_MINQUERY:\n    case OP_MINQUERYI:\n    case OP_NOTMINQUERY:\n    case OP_NOTMINQUERYI:\n    case OP_POSQUERY:\n    case OP_POSQUERYI:\n    case OP_NOTPOSQUERY:\n    case OP_NOTPOSQUERYI:\n\n    cc += PRIV(OP_lengths)[op];\n#ifdef SUPPORT_UNICODE\n    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);\n#endif\n    break;\n\n    /* Skip these, but we need to add in the name length. */\n\n    case OP_MARK:\n    case OP_COMMIT_ARG:\n    case OP_PRUNE_ARG:\n    case OP_SKIP_ARG:\n    case OP_THEN_ARG:\n    cc += PRIV(OP_lengths)[op] + cc[1];\n    break;\n\n    /* The remaining opcodes are just skipped over. */\n\n    case OP_CLOSE:\n    case OP_COMMIT:\n    case OP_FAIL:\n    case OP_PRUNE:\n    case OP_SET_SOM:\n    case OP_SKIP:\n    case OP_THEN:\n    cc += PRIV(OP_lengths)[op];\n    break;\n\n    /* This should not occur: we list all opcodes explicitly so that when\n    new ones get added they are properly considered. */\n\n    /* LCOV_EXCL_START */\n    default:\n    PCRE2_DEBUG_UNREACHABLE();\n    return -3;\n    /* LCOV_EXCL_STOP */\n    }\n  }\n\n/* LCOV_EXCL_START */\nPCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */\nreturn -3;                 /* Avoid compiler warnings */\n/* LCOV_EXCL_STOP */\n}\n\n\n\n/*************************************************\n*      Set a bit and maybe its alternate case    *\n*************************************************/\n\n/* Given a character, set its first code unit's bit in the table, and also the\ncorresponding bit for the other version of a letter if we are caseless.\n\nArguments:\n  re            points to the regex block\n  p             points to the first code unit of the character\n  caseless      TRUE if caseless\n  utf           TRUE for UTF mode\n  ucp           TRUE for UCP mode\n\nReturns:        pointer after the character\n*/\n\nstatic PCRE2_SPTR\nset_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf,\n  BOOL ucp)\n{\nuint32_t c = *p++;   /* First code unit */\n\n(void)utf;           /* Stop compiler warnings when UTF not supported */\n(void)ucp;\n\n/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for\n0xff. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\nif (c > 0xff) SET_BIT(0xff); else\n#endif\n\nSET_BIT(c);\n\n/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find\nthe end of the character, even when caseless. */\n\n#ifdef SUPPORT_UNICODE\nif (utf)\n  {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  if (c >= 0xc0) GETUTF8INC(c, p);\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n  if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p);\n#endif\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* If caseless, handle the other case of the character. */\n\nif (caseless)\n  {\n#ifdef SUPPORT_UNICODE\n  if (utf || ucp)\n    {\n    c = UCD_OTHERCASE(c);\n#if PCRE2_CODE_UNIT_WIDTH == 8\n    if (utf)\n      {\n      PCRE2_UCHAR buff[6];\n      (void)PRIV(ord2utf)(c, buff);\n      SET_BIT(buff[0]);\n      }\n    else if (c < 256) SET_BIT(c);\n#else  /* 16-bit or 32-bit mode */\n    if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);\n#endif\n    }\n\n  else\n#endif  /* SUPPORT_UNICODE */\n\n  /* Not UTF or UCP */\n\n  if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);\n  }\n\nreturn p;\n}\n\n\n\n/*************************************************\n*     Set bits for a positive character type     *\n*************************************************/\n\n/* This function sets starting bits for a character type. In UTF-8 mode, we can\nonly do a direct setting for bytes less than 128, as otherwise there can be\nconfusion with bytes in the middle of UTF-8 characters. In a \"traditional\"\nenvironment, the tables will only recognize ASCII characters anyway, but in at\nleast one Windows environment, some higher bytes bits were set in the tables.\nSo we deal with that case by considering the UTF-8 encoding.\n\nArguments:\n  re             the regex block\n  cbit type      the type of character wanted\n  table_limit    32 for non-UTF-8; 16 for UTF-8\n\nReturns:         nothing\n*/\n\nstatic void\nset_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)\n{\nuint32_t c;\nfor (c = 0; c < table_limit; c++)\n  re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type];\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nif (table_limit == 32) return;\nfor (c = 128; c < 256; c++)\n  {\n  if ((re->tables[cbits_offset + c/8] & (1u << (c&7))) != 0)\n    {\n    PCRE2_UCHAR buff[6];\n    (void)PRIV(ord2utf)(c, buff);\n    SET_BIT(buff[0]);\n    }\n  }\n#endif  /* UTF-8 */\n}\n\n\n/*************************************************\n*     Set bits for a negative character type     *\n*************************************************/\n\n/* This function sets starting bits for a negative character type such as \\D.\nIn UTF-8 mode, we can only do a direct setting for bytes less than 128, as\notherwise there can be confusion with bytes in the middle of UTF-8 characters.\nUnlike in the positive case, where we can set appropriate starting bits for\nspecific high-valued UTF-8 characters, in this case we have to set the bits for\nall high-valued characters. The lowest is 0xc2, but we overkill by starting at\n0xc0 (192) for simplicity.\n\nArguments:\n  re             the regex block\n  cbit type      the type of character wanted\n  table_limit    32 for non-UTF-8; 16 for UTF-8\n\nReturns:         nothing\n*/\n\nstatic void\nset_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)\n{\nuint32_t c;\nfor (c = 0; c < table_limit; c++)\n  re->start_bitmap[c] |= (uint8_t)(~(re->tables[c+cbits_offset+cbit_type]));\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nif (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff;\n#endif\n}\n\n\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n/*************************************************\n*     Set starting bits for a character list.    *\n*************************************************/\n\n/* This function sets starting bits for a character list. It enumerates\nall characters and character ranges in the character list, and sets\nthe starting bits accordingly.\n\nArguments:\n  code           pointer to the code\n  start_bitmap   pointer to the starting bitmap\n\nReturns:         nothing\n*/\nstatic void\nstudy_char_list(PCRE2_SPTR code, uint8_t *start_bitmap,\n  const uint8_t *char_lists_end)\n{\nuint32_t type, list_ind;\nuint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD;\nuint32_t range_start = ~(uint32_t)0, range_end = 0;\nconst uint8_t *next_char;\nPCRE2_UCHAR start_buffer[6], end_buffer[6];\nPCRE2_UCHAR start, end;\n\n/* Only needed in 8-bit mode at the moment. */\ntype = (uint32_t)(code[0] << 8) | code[1];\ncode += 2;\n\n/* Align characters. */\nnext_char = char_lists_end - (GET(code, 0) << 1);\ntype &= XCL_TYPE_MASK;\nlist_ind = 0;\n\nif ((type & XCL_BEGIN_WITH_RANGE) != 0)\n  range_start = XCL_CHAR_LIST_LOW_16_START;\n\nwhile (type > 0)\n  {\n  uint32_t item_count = type & XCL_ITEM_COUNT_MASK;\n\n  if (item_count == XCL_ITEM_COUNT_MASK)\n    {\n    if (list_ind <= 1)\n      {\n      item_count = *(const uint16_t*)next_char;\n      next_char += 2;\n      }\n    else\n      {\n      item_count = *(const uint32_t*)next_char;\n      next_char += 4;\n      }\n    }\n\n  while (item_count > 0)\n    {\n    if (list_ind <= 1)\n      {\n      range_end = *(const uint16_t*)next_char;\n      next_char += 2;\n      }\n    else\n      {\n      range_end = *(const uint32_t*)next_char;\n      next_char += 4;\n      }\n\n    if ((range_end & XCL_CHAR_END) != 0)\n      {\n      range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n      PRIV(ord2utf)(range_end, end_buffer);\n      end = end_buffer[0];\n\n      if (range_start < range_end)\n        {\n        PRIV(ord2utf)(range_start, start_buffer);\n        for (start = start_buffer[0]; start <= end; start++)\n          start_bitmap[start / 8] |= (1u << (start & 7));\n        }\n      else\n        start_bitmap[end / 8] |= (1u << (end & 7));\n\n      range_start = ~(uint32_t)0;\n      }\n    else\n      range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT);\n\n    item_count--;\n    }\n\n  list_ind++;\n  type >>= XCL_TYPE_BIT_LEN;\n\n  if (range_start == ~(uint32_t)0)\n    {\n    if ((type & XCL_BEGIN_WITH_RANGE) != 0)\n      {\n      /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_START is not possible. */\n      if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START;\n      else range_start = XCL_CHAR_LIST_LOW_32_START;\n      }\n    }\n  else if ((type & XCL_BEGIN_WITH_RANGE) == 0)\n    {\n    PRIV(ord2utf)(range_start, start_buffer);\n\n    /* In 8 bit mode XCL_CHAR_LIST_LOW_32_END and\n    XCL_CHAR_LIST_HIGH_32_END are not possible. */\n    if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END;\n    else range_end = XCL_CHAR_LIST_HIGH_16_END;\n\n    PRIV(ord2utf)(range_end, end_buffer);\n    end = end_buffer[0];\n\n    for (start = start_buffer[0]; start <= end; start++)\n      start_bitmap[start / 8] |= (1u << (start & 7));\n\n    range_start = ~(uint32_t)0;\n    }\n\n  /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_ADD is not possible. */\n  if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD;\n  else char_list_add = XCL_CHAR_LIST_LOW_32_ADD;\n  }\n}\n#endif\n\n\n\n/*************************************************\n*      Create bitmap of starting code units      *\n*************************************************/\n\n/* This function scans a compiled unanchored expression recursively and\nattempts to build a bitmap of the set of possible starting code units whose\nvalues are less than 256. In 16-bit and 32-bit mode, values above 255 all cause\nthe 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode\nwe pass a value of 16 rather than 32 as the final argument. (See comments in\nthose functions for the reason.)\n\nThe SSB_CONTINUE return is useful for parenthesized groups in patterns such as\n(a*)b where the group provides some optional starting code units but scanning\nmust continue at the outer level to find at least one mandatory code unit. At\nthe outermost level, this function fails unless the result is SSB_DONE.\n\nWe restrict recursion (for nested groups) to 1000 to avoid stack overflow\nissues.\n\nArguments:\n  re           points to the compiled regex block\n  code         points to an expression\n  utf          TRUE if in UTF mode\n  ucp          TRUE if in UCP mode\n  depthptr     pointer to recurse depth\n\nReturns:       SSB_FAIL     => Failed to find any starting code units\n               SSB_DONE     => Found mandatory starting code units\n               SSB_CONTINUE => Found optional starting code units\n               SSB_UNKNOWN  => Hit an unrecognized opcode\n               SSB_TOODEEP  => Recursion is too deep\n*/\n\nstatic int\nset_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp,\n  int *depthptr)\n{\nuint32_t c;\nint yield = SSB_DONE;\n\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\nint table_limit = utf? 16:32;\n#else\nint table_limit = 32;\n#endif\n\n*depthptr += 1;\nif (*depthptr > 1000) return SSB_TOODEEP;\n\ndo\n  {\n  BOOL try_next = TRUE;\n  PCRE2_SPTR tcode = code + 1 + LINK_SIZE;\n\n  if (*code == OP_CBRA || *code == OP_SCBRA ||\n      *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;\n\n  while (try_next)    /* Loop for items in this branch */\n    {\n    int rc;\n    PCRE2_SPTR ncode;\n    const uint8_t *classmap = NULL;\n#ifdef SUPPORT_WIDE_CHARS\n    PCRE2_UCHAR xclassflags;\n#endif\n\n    switch(*tcode)\n      {\n      /* If we reach something we don't understand, it means a new opcode has\n      been created that hasn't been added to this function. Hopefully this\n      problem will be discovered during testing. */\n\n      default:\n      return SSB_UNKNOWN;\n\n      /* Fail for a valid opcode that implies no starting bits. */\n\n      case OP_ACCEPT:\n      case OP_ASSERT_ACCEPT:\n      case OP_ALLANY:\n      case OP_ANY:\n      case OP_ANYBYTE:\n      case OP_CIRCM:\n      case OP_CLOSE:\n      case OP_COMMIT:\n      case OP_COMMIT_ARG:\n      case OP_COND:\n      case OP_CREF:\n      case OP_FALSE:\n      case OP_TRUE:\n      case OP_DNCREF:\n      case OP_DNREF:\n      case OP_DNREFI:\n      case OP_DNRREF:\n      case OP_DOLL:\n      case OP_DOLLM:\n      case OP_END:\n      case OP_EOD:\n      case OP_EODN:\n      case OP_EXTUNI:\n      case OP_FAIL:\n      case OP_MARK:\n      case OP_NOT:\n      case OP_NOTEXACT:\n      case OP_NOTEXACTI:\n      case OP_NOTI:\n      case OP_NOTMINPLUS:\n      case OP_NOTMINPLUSI:\n      case OP_NOTMINQUERY:\n      case OP_NOTMINQUERYI:\n      case OP_NOTMINSTAR:\n      case OP_NOTMINSTARI:\n      case OP_NOTMINUPTO:\n      case OP_NOTMINUPTOI:\n      case OP_NOTPLUS:\n      case OP_NOTPLUSI:\n      case OP_NOTPOSPLUS:\n      case OP_NOTPOSPLUSI:\n      case OP_NOTPOSQUERY:\n      case OP_NOTPOSQUERYI:\n      case OP_NOTPOSSTAR:\n      case OP_NOTPOSSTARI:\n      case OP_NOTPOSUPTO:\n      case OP_NOTPOSUPTOI:\n      case OP_NOTPROP:\n      case OP_NOTQUERY:\n      case OP_NOTQUERYI:\n      case OP_NOTSTAR:\n      case OP_NOTSTARI:\n      case OP_NOTUPTO:\n      case OP_NOTUPTOI:\n      case OP_NOT_HSPACE:\n      case OP_NOT_VSPACE:\n      case OP_PRUNE:\n      case OP_PRUNE_ARG:\n      case OP_RECURSE:\n      case OP_REF:\n      case OP_REFI:\n      case OP_REVERSE:\n      case OP_VREVERSE:\n      case OP_RREF:\n      case OP_SCOND:\n      case OP_SET_SOM:\n      case OP_SKIP:\n      case OP_SKIP_ARG:\n      case OP_SOD:\n      case OP_SOM:\n      case OP_THEN:\n      case OP_THEN_ARG:\n      return SSB_FAIL;\n\n      /* OP_CIRC happens only at the start of an anchored branch (multiline ^\n      uses OP_CIRCM). Skip over it. */\n\n      case OP_CIRC:\n      tcode += PRIV(OP_lengths)[OP_CIRC];\n      break;\n\n      /* A \"real\" property test implies no starting bits, but the fake property\n      PT_CLIST identifies a list of characters. These lists are short, as they\n      are used for characters with more than one \"other case\", so there is no\n      point in recognizing them for OP_NOTPROP. */\n\n      case OP_PROP:\n      if (tcode[1] != PT_CLIST) return SSB_FAIL;\n        {\n        const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2];\n        while ((c = *p++) < NOTACHAR)\n          {\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n          if (utf)\n            {\n            PCRE2_UCHAR buff[6];\n            (void)PRIV(ord2utf)(c, buff);\n            c = buff[0];\n            }\n#endif\n          if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);\n          }\n        }\n      try_next = FALSE;\n      break;\n\n      /* We can ignore word boundary tests. */\n\n      case OP_WORD_BOUNDARY:\n      case OP_NOT_WORD_BOUNDARY:\n      case OP_UCP_WORD_BOUNDARY:\n      case OP_NOT_UCP_WORD_BOUNDARY:\n      tcode++;\n      break;\n\n      /* For a positive lookahead assertion, inspect what immediately follows,\n      ignoring intermediate assertions and callouts. If the next item is one\n      that sets a mandatory character, skip this assertion. Otherwise, treat it\n      the same as other bracket groups. */\n\n      case OP_ASSERT:\n      case OP_ASSERT_NA:\n      ncode = tcode + GET(tcode, 1);\n      while (*ncode == OP_ALT) ncode += GET(ncode, 1);\n      ncode += 1 + LINK_SIZE;\n\n      /* Skip irrelevant items */\n\n      for (BOOL done = FALSE; !done;)\n        {\n        switch (*ncode)\n          {\n          case OP_ASSERT:\n          case OP_ASSERT_NOT:\n          case OP_ASSERTBACK:\n          case OP_ASSERTBACK_NOT:\n          case OP_ASSERT_NA:\n          case OP_ASSERTBACK_NA:\n          case OP_ASSERT_SCS:\n          ncode += GET(ncode, 1);\n          while (*ncode == OP_ALT) ncode += GET(ncode, 1);\n          ncode += 1 + LINK_SIZE;\n          break;\n\n          case OP_WORD_BOUNDARY:\n          case OP_NOT_WORD_BOUNDARY:\n          case OP_UCP_WORD_BOUNDARY:\n          case OP_NOT_UCP_WORD_BOUNDARY:\n          ncode++;\n          break;\n\n          case OP_CALLOUT:\n          ncode += PRIV(OP_lengths)[OP_CALLOUT];\n          break;\n\n          case OP_CALLOUT_STR:\n          ncode += GET(ncode, 1 + 2*LINK_SIZE);\n          break;\n\n          default:\n          done = TRUE;\n          break;\n          }\n        }\n\n      /* Now check the next significant item. */\n\n      switch(*ncode)\n        {\n        default:\n        break;\n\n        case OP_PROP:\n        if (ncode[1] != PT_CLIST) break;\n        PCRE2_FALLTHROUGH /* Fall through */\n        case OP_ANYNL:\n        case OP_CHAR:\n        case OP_CHARI:\n        case OP_EXACT:\n        case OP_EXACTI:\n        case OP_HSPACE:\n        case OP_MINPLUS:\n        case OP_MINPLUSI:\n        case OP_PLUS:\n        case OP_PLUSI:\n        case OP_POSPLUS:\n        case OP_POSPLUSI:\n        case OP_VSPACE:\n        /* Note that these types will only be present in non-UCP mode. */\n        case OP_DIGIT:\n        case OP_NOT_DIGIT:\n        case OP_WORDCHAR:\n        case OP_NOT_WORDCHAR:\n        case OP_WHITESPACE:\n        case OP_NOT_WHITESPACE:\n        tcode = ncode;\n        continue;   /* With the following significant opcode */\n        }\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      /* For a group bracket or a positive assertion without an immediately\n      following mandatory setting, recurse to set bits from within the\n      subpattern. If it can't find anything, we have to give up. If it finds\n      some mandatory character(s), we are done for this branch. Otherwise,\n      carry on scanning after the subpattern. */\n\n      case OP_BRA:\n      case OP_SBRA:\n      case OP_CBRA:\n      case OP_SCBRA:\n      case OP_BRAPOS:\n      case OP_SBRAPOS:\n      case OP_CBRAPOS:\n      case OP_SCBRAPOS:\n      case OP_ONCE:\n      case OP_SCRIPT_RUN:\n      rc = set_start_bits(re, tcode, utf, ucp, depthptr);\n      if (rc == SSB_DONE)\n        {\n        try_next = FALSE;\n        }\n      else if (rc == SSB_CONTINUE)\n        {\n        do tcode += GET(tcode, 1); while (*tcode == OP_ALT);\n        tcode += 1 + LINK_SIZE;\n        }\n      else return rc;   /* FAIL, UNKNOWN, or TOODEEP */\n      break;\n\n      /* If we hit ALT or KET, it means we haven't found anything mandatory in\n      this branch, though we might have found something optional. For ALT, we\n      continue with the next alternative, but we have to arrange that the final\n      result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,\n      return SSB_CONTINUE: if this is the top level, that indicates failure,\n      but after a nested subpattern, it causes scanning to continue. */\n\n      case OP_ALT:\n      yield = SSB_CONTINUE;\n      try_next = FALSE;\n      break;\n\n      case OP_KET:\n      case OP_KETRMAX:\n      case OP_KETRMIN:\n      case OP_KETRPOS:\n      return SSB_CONTINUE;\n\n      /* Skip over callout */\n\n      case OP_CALLOUT:\n      tcode += PRIV(OP_lengths)[OP_CALLOUT];\n      break;\n\n      case OP_CALLOUT_STR:\n      tcode += GET(tcode, 1 + 2*LINK_SIZE);\n      break;\n\n      /* Skip over lookbehind, negative lookahead, and scan substring\n      assertions */\n\n      case OP_ASSERT_NOT:\n      case OP_ASSERTBACK:\n      case OP_ASSERTBACK_NOT:\n      case OP_ASSERTBACK_NA:\n      case OP_ASSERT_SCS:\n      do tcode += GET(tcode, 1); while (*tcode == OP_ALT);\n      tcode += 1 + LINK_SIZE;\n      break;\n\n      /* BRAZERO does the bracket, but carries on. */\n\n      case OP_BRAZERO:\n      case OP_BRAMINZERO:\n      case OP_BRAPOSZERO:\n      rc = set_start_bits(re, ++tcode, utf, ucp, depthptr);\n      if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc;\n      do tcode += GET(tcode,1); while (*tcode == OP_ALT);\n      tcode += 1 + LINK_SIZE;\n      break;\n\n      /* SKIPZERO skips the bracket. */\n\n      case OP_SKIPZERO:\n      tcode++;\n      do tcode += GET(tcode,1); while (*tcode == OP_ALT);\n      tcode += 1 + LINK_SIZE;\n      break;\n\n      /* Single-char * or ? sets the bit and tries the next item */\n\n      case OP_STAR:\n      case OP_MINSTAR:\n      case OP_POSSTAR:\n      case OP_QUERY:\n      case OP_MINQUERY:\n      case OP_POSQUERY:\n      tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp);\n      break;\n\n      case OP_STARI:\n      case OP_MINSTARI:\n      case OP_POSSTARI:\n      case OP_QUERYI:\n      case OP_MINQUERYI:\n      case OP_POSQUERYI:\n      tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp);\n      break;\n\n      /* Single-char upto sets the bit and tries the next */\n\n      case OP_UPTO:\n      case OP_MINUPTO:\n      case OP_POSUPTO:\n      tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp);\n      break;\n\n      case OP_UPTOI:\n      case OP_MINUPTOI:\n      case OP_POSUPTOI:\n      tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp);\n      break;\n\n      /* At least one single char sets the bit and stops */\n\n      case OP_EXACT:\n      tcode += IMM2_SIZE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_CHAR:\n      case OP_PLUS:\n      case OP_MINPLUS:\n      case OP_POSPLUS:\n      (void)set_table_bit(re, tcode + 1, FALSE, utf, ucp);\n      try_next = FALSE;\n      break;\n\n      case OP_EXACTI:\n      tcode += IMM2_SIZE;\n      PCRE2_FALLTHROUGH /* Fall through */\n      case OP_CHARI:\n      case OP_PLUSI:\n      case OP_MINPLUSI:\n      case OP_POSPLUSI:\n      (void)set_table_bit(re, tcode + 1, TRUE, utf, ucp);\n      try_next = FALSE;\n      break;\n\n      /* Special spacing and line-terminating items. These recognize specific\n      lists of characters. The difference between VSPACE and ANYNL is that the\n      latter can match the two-character CRLF sequence, but that is not\n      relevant for finding the first character, so their code here is\n      identical. */\n\n      case OP_HSPACE:\n      SET_BIT(CHAR_HT);\n      SET_BIT(CHAR_SPACE);\n\n      /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set\n      the bits for NBSP and for code units >= 255, independently of UTF. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n      SET_BIT(CHAR_NBSP);\n      SET_BIT(0xFF);\n#else\n      /* For the 8-bit library in UTF-8 mode, set the bits for the first code\n      units of horizontal space characters. */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        SET_BIT(0xC2);  /* For U+00A0 */\n        SET_BIT(0xE1);  /* For U+1680, U+180E */\n        SET_BIT(0xE2);  /* For U+2000 - U+200A, U+202F, U+205F */\n        SET_BIT(0xE3);  /* For U+3000 */\n        }\n      else\n#endif\n      /* For the 8-bit library not in UTF-8 mode, set the bit for NBSP. */\n        {\n        SET_BIT(CHAR_NBSP);\n        }\n#endif  /* 8-bit support */\n\n      try_next = FALSE;\n      break;\n\n      case OP_ANYNL:\n      case OP_VSPACE:\n      SET_BIT(CHAR_LF);\n      SET_BIT(CHAR_VT);\n      SET_BIT(CHAR_FF);\n      SET_BIT(CHAR_CR);\n\n      /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set\n      the bits for NEL and for code units >= 255, independently of UTF. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n      SET_BIT(CHAR_NEL);\n      SET_BIT(0xFF);\n#else\n      /* For the 8-bit library in UTF-8 mode, set the bits for the first code\n      units of vertical space characters. */\n\n#ifdef SUPPORT_UNICODE\n      if (utf)\n        {\n        SET_BIT(0xC2);  /* For U+0085 (NEL) */\n        SET_BIT(0xE2);  /* For U+2028, U+2029 */\n        }\n      else\n#endif\n      /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */\n        {\n        SET_BIT(CHAR_NEL);\n        }\n#endif  /* 8-bit support */\n\n      try_next = FALSE;\n      break;\n\n      /* Single character types set the bits and stop. Note that if PCRE2_UCP\n      is set, we do not see these opcodes because \\d etc are converted to\n      properties. Therefore, these apply in the case when only characters less\n      than 256 are recognized to match the types. */\n\n      case OP_NOT_DIGIT:\n      set_nottype_bits(re, cbit_digit, table_limit);\n      try_next = FALSE;\n      break;\n\n      case OP_DIGIT:\n      set_type_bits(re, cbit_digit, table_limit);\n      try_next = FALSE;\n      break;\n\n      case OP_NOT_WHITESPACE:\n      set_nottype_bits(re, cbit_space, table_limit);\n      try_next = FALSE;\n      break;\n\n      case OP_WHITESPACE:\n      set_type_bits(re, cbit_space, table_limit);\n      try_next = FALSE;\n      break;\n\n      case OP_NOT_WORDCHAR:\n      set_nottype_bits(re, cbit_word, table_limit);\n      try_next = FALSE;\n      break;\n\n      case OP_WORDCHAR:\n      set_type_bits(re, cbit_word, table_limit);\n      try_next = FALSE;\n      break;\n\n      /* One or more character type fudges the pointer and restarts, knowing\n      it will hit a single character type and stop there. */\n\n      case OP_TYPEPLUS:\n      case OP_TYPEMINPLUS:\n      case OP_TYPEPOSPLUS:\n      tcode++;\n      break;\n\n      case OP_TYPEEXACT:\n      tcode += 1 + IMM2_SIZE;\n      break;\n\n      /* Zero or more repeats of character types set the bits and then\n      try again. */\n\n      case OP_TYPEUPTO:\n      case OP_TYPEMINUPTO:\n      case OP_TYPEPOSUPTO:\n      tcode += IMM2_SIZE;\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      case OP_TYPESTAR:\n      case OP_TYPEMINSTAR:\n      case OP_TYPEPOSSTAR:\n      case OP_TYPEQUERY:\n      case OP_TYPEMINQUERY:\n      case OP_TYPEPOSQUERY:\n      switch(tcode[1])\n        {\n        default:\n        case OP_ANY:\n        case OP_ALLANY:\n        return SSB_FAIL;\n\n        case OP_HSPACE:\n        SET_BIT(CHAR_HT);\n        SET_BIT(CHAR_SPACE);\n\n        /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set\n        the bits for NBSP and for code units >= 255, independently of UTF. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n        SET_BIT(CHAR_NBSP);\n        SET_BIT(0xFF);\n#else\n        /* For the 8-bit library in UTF-8 mode, set the bits for the first code\n        units of horizontal space characters. */\n\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          SET_BIT(0xC2);  /* For U+00A0 */\n          SET_BIT(0xE1);  /* For U+1680, U+180E */\n          SET_BIT(0xE2);  /* For U+2000 - U+200A, U+202F, U+205F */\n          SET_BIT(0xE3);  /* For U+3000 */\n          }\n        else\n#endif\n        /* For the 8-bit library not in UTF-8 mode, set the bit for NBSP. */\n          {\n          SET_BIT(CHAR_NBSP);\n          }\n#endif  /* 8-bit support */\n        break;\n\n        case OP_ANYNL:\n        case OP_VSPACE:\n        SET_BIT(CHAR_LF);\n        SET_BIT(CHAR_VT);\n        SET_BIT(CHAR_FF);\n        SET_BIT(CHAR_CR);\n\n        /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set\n        the bits for NEL and for code units >= 255, independently of UTF. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n        SET_BIT(CHAR_NEL);\n        SET_BIT(0xFF);\n#else\n        /* For the 8-bit library in UTF-8 mode, set the bits for the first code\n        units of vertical space characters. */\n\n#ifdef SUPPORT_UNICODE\n        if (utf)\n          {\n          SET_BIT(0xC2);  /* For U+0085 (NEL) */\n          SET_BIT(0xE2);  /* For U+2028, U+2029 */\n          }\n        else\n#endif\n        /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */\n          {\n          SET_BIT(CHAR_NEL);\n          }\n#endif  /* 8-bit support */\n        break;\n\n        case OP_NOT_DIGIT:\n        set_nottype_bits(re, cbit_digit, table_limit);\n        break;\n\n        case OP_DIGIT:\n        set_type_bits(re, cbit_digit, table_limit);\n        break;\n\n        case OP_NOT_WHITESPACE:\n        set_nottype_bits(re, cbit_space, table_limit);\n        break;\n\n        case OP_WHITESPACE:\n        set_type_bits(re, cbit_space, table_limit);\n        break;\n\n        case OP_NOT_WORDCHAR:\n        set_nottype_bits(re, cbit_word, table_limit);\n        break;\n\n        case OP_WORDCHAR:\n        set_type_bits(re, cbit_word, table_limit);\n        break;\n        }\n\n      tcode += 2;\n      break;\n\n      /* Set-based ECLASS: treat it the same as a \"complex\" XCLASS; give up. */\n\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_ECLASS:\n      return SSB_FAIL;\n#endif\n\n      /* Extended class: if there are any property checks, or if this is a\n      negative XCLASS without a map, give up. If there are no property checks,\n      there must be wide characters on the XCLASS list, because otherwise an\n      XCLASS would not have been created. This means that code points >= 255\n      are potential starters. In the UTF-8 case we can scan them and set bits\n      for the relevant leading bytes. */\n\n#ifdef SUPPORT_WIDE_CHARS\n      case OP_XCLASS:\n      xclassflags = tcode[1 + LINK_SIZE];\n      if ((xclassflags & XCL_HASPROP) != 0 ||\n          (xclassflags & (XCL_MAP|XCL_NOT)) == XCL_NOT)\n        return SSB_FAIL;\n\n      /* We have a positive XCLASS or a negative one without a map. Set up the\n      map pointer if there is one, and fall through. */\n\n      classmap = ((xclassflags & XCL_MAP) == 0)? NULL :\n        (const uint8_t *)(tcode + 1 + LINK_SIZE + 1);\n\n      /* In UTF-8 mode, scan the character list and set bits for leading bytes,\n      then jump to handle the map. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      if (utf && (xclassflags & XCL_NOT) == 0)\n        {\n        PCRE2_UCHAR b, e;\n        PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32);\n        tcode += GET(tcode, 1);\n\n        if (*p >= XCL_LIST)\n          {\n          study_char_list(p, re->start_bitmap,\n            ((const uint8_t *)re + re->code_start));\n          goto HANDLE_CLASSMAP;\n          }\n\n        for (;;) switch (*p++)\n          {\n          case XCL_SINGLE:\n          b = *p++;\n          while ((*p & 0xc0) == 0x80) p++;\n          re->start_bitmap[b/8] |= (1u << (b&7));\n          break;\n\n          case XCL_RANGE:\n          b = *p++;\n          while ((*p & 0xc0) == 0x80) p++;\n          e = *p++;\n          while ((*p & 0xc0) == 0x80) p++;\n          for (; b <= e; b++)\n            re->start_bitmap[b/8] |= (1u << (b&7));\n          break;\n\n          case XCL_END:\n          goto HANDLE_CLASSMAP;\n\n          /* LCOV_EXCL_START */\n          default:\n          PCRE2_DEBUG_UNREACHABLE();\n          return SSB_UNKNOWN;   /* Internal error, should not occur */\n          /* LCOV_EXCL_STOP */\n          }\n        }\n#endif  /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */\n#endif  /* SUPPORT_WIDE_CHARS */\n\n      /* It seems that the fall through comment must be outside the #ifdef if\n      it is to avoid the gcc compiler warning. */\n\n      PCRE2_FALLTHROUGH /* Fall through */\n\n      /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are\n      in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter\n      because it starts a character with a value > 255. In 8-bit non-UTF mode,\n      there is no difference between CLASS and NCLASS. In all other wide\n      character modes, set the 0xFF bit to indicate code units >= 255. */\n\n      case OP_NCLASS:\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n      if (utf)\n        {\n        re->start_bitmap[24] |= 0xf0;            /* Bits for 0xc4 - 0xc8 */\n        memset(re->start_bitmap+25, 0xff, 7);    /* Bits for 0xc9 - 0xff */\n        }\n      PCRE2_FALLTHROUGH /* Fall through */\n#elif PCRE2_CODE_UNIT_WIDTH != 8\n      SET_BIT(0xFF);                             /* For characters >= 255 */\n      PCRE2_FALLTHROUGH /* Fall through */\n#endif\n\n      /* Enter here for a positive non-XCLASS. If we have fallen through from\n      an XCLASS, classmap will already be set; just advance the code pointer.\n      Otherwise, set up classmap for a non-XCLASS and advance past it. */\n\n      case OP_CLASS:\n      if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else\n        {\n        classmap = (const uint8_t *)(++tcode);\n        tcode += 32 / sizeof(PCRE2_UCHAR);\n        }\n\n      /* When wide characters are supported, classmap may be NULL. In UTF-8\n      (sic) mode, the bits in a class bit map correspond to character values,\n      not to byte values. However, the bit map we are constructing is for byte\n      values. So we have to do a conversion for characters whose code point is\n      greater than 127. In fact, there are only two possible starting bytes for\n      characters in the range 128 - 255. */\n\n#if defined SUPPORT_WIDE_CHARS && PCRE2_CODE_UNIT_WIDTH == 8\n      HANDLE_CLASSMAP:\n#endif\n      if (classmap != NULL)\n        {\n#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8\n        if (utf)\n          {\n          for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c];\n          for (c = 128; c < 256; c++)\n            {\n            if ((classmap[c/8] & (1u << (c&7))) != 0)\n              {\n              int d = (c >> 6) | 0xc0;                 /* Set bit for this starter */\n              re->start_bitmap[d/8] |= (1u << (d&7));  /* and then skip on to the */\n              c = (c & 0xc0) + 0x40 - 1;               /* next relevant character. */\n              }\n            }\n          }\n        else\n#endif\n        /* In all modes except UTF-8, the two bit maps are compatible. */\n\n          {\n          for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c];\n          }\n        }\n\n      /* Act on what follows the class. For a zero minimum repeat, continue;\n      otherwise stop processing. */\n\n      switch (*tcode)\n        {\n        case OP_CRSTAR:\n        case OP_CRMINSTAR:\n        case OP_CRQUERY:\n        case OP_CRMINQUERY:\n        case OP_CRPOSSTAR:\n        case OP_CRPOSQUERY:\n        tcode++;\n        break;\n\n        case OP_CRRANGE:\n        case OP_CRMINRANGE:\n        case OP_CRPOSRANGE:\n        if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;\n          else try_next = FALSE;\n        break;\n\n        default:\n        try_next = FALSE;\n        break;\n        }\n      break; /* End of class handling case */\n      }      /* End of switch for opcodes */\n    }        /* End of try_next loop */\n\n  code += GET(code, 1);   /* Advance to next branch */\n  }\nwhile (*code == OP_ALT);\n\nreturn yield;\n}\n\n\n\n/*************************************************\n*          Study a compiled expression           *\n*************************************************/\n\n/* This function is handed a compiled expression that it must study to produce\ninformation that will speed up the matching.\n\nArgument:\n  re       points to the compiled expression\n\nReturns:   0 normally; non-zero should never normally occur\n           1 unknown opcode in set_start_bits\n           2 missing capturing bracket\n           3 unknown opcode in find_minlength\n*/\n\nint\nPRIV(study)(pcre2_real_code *re)\n{\nint count = 0;\nPCRE2_UCHAR *code;\nBOOL utf = (re->overall_options & PCRE2_UTF) != 0;\nBOOL ucp = (re->overall_options & PCRE2_UCP) != 0;\n\n/* Find start of compiled code */\n\ncode = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start);\n\n/* For a pattern that has a first code unit, or a multiline pattern that\nmatches only at \"line start\", there is no point in seeking a list of starting\ncode units. */\n\nif ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)\n  {\n  int depth = 0;\n  int rc = set_start_bits(re, code, utf, ucp, &depth);\n  /* LCOV_EXCL_START */\n  if (rc == SSB_UNKNOWN)\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    return 1;\n    }\n  /* LCOV_EXCL_STOP */\n\n  /* If a list of starting code units was set up, scan the list to see if only\n  one or two were listed. Having only one listed is rare because usually a\n  single starting code unit will have been recognized and PCRE2_FIRSTSET set.\n  If two are listed, see if they are caseless versions of the same character;\n  if so we can replace the list with a caseless first code unit. This gives\n  better performance and is plausibly worth doing for patterns such as [Ww]ord\n  or (word|WORD). */\n\n  if (rc == SSB_DONE)\n    {\n    int i;\n    int a = -1;\n    int b = -1;\n    uint8_t *p = re->start_bitmap;\n    uint32_t flags = PCRE2_FIRSTMAPSET;\n\n    for (i = 0; i < 256; p++, i += 8)\n      {\n      uint8_t x = *p;\n      if (x != 0)\n        {\n        int c;\n        uint8_t y = x & (~x + 1);   /* Least significant bit */\n        if (y != x) goto DONE;      /* More than one bit set */\n\n        /* In the 16-bit and 32-bit libraries, the bit for 0xff means \"0xff and\n        all wide characters\", so we cannot use it here. */\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\n        if (i == 248 && x == 0x80) goto DONE;\n#endif\n\n        /* Compute the character value */\n\n        c = i;\n        switch (x)\n          {\n          case 1:   break;\n          case 2:   c += 1; break;  case 4:  c += 2; break;\n          case 8:   c += 3; break;  case 16: c += 4; break;\n          case 32:  c += 5; break;  case 64: c += 6; break;\n          case 128: c += 7; break;\n          }\n\n        /* c contains the code unit value, in the range 0-255. In 8-bit UTF\n        mode, only values < 128 can be used. In all the other cases, c is a\n        character value. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n        if (utf && c > 127) goto DONE;\n#endif\n        if (a < 0) a = c;   /* First one found, save in a */\n        else if (b < 0)     /* Second one found */\n          {\n          int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);\n\n#ifdef SUPPORT_UNICODE\n          if (utf || ucp)\n            {\n            if (UCD_CASESET(c) != 0) goto DONE;     /* Multiple case set */\n            if (c > 127) d = UCD_OTHERCASE(c);\n            }\n#endif  /* SUPPORT_UNICODE */\n\n          if (d != a) goto DONE;   /* Not the other case of a */\n          b = c;                   /* Save second in b */\n\n#ifdef EBCDIC\n          /* To match ASCII (which puts the uppercase one in a), swap a & b\n          if needed. This doesn't really matter, but neatens the tests. */\n          if (TABLE_GET((unsigned int)a, re->tables + lcc_offset, a) == a)\n            {\n            b = a;\n            a = c;\n            }\n#endif\n          }\n        else goto DONE;   /* More than two characters found */\n        }\n      }\n\n    /* Replace the start code unit bits with a first code unit. If it is the\n    same as a required later code unit, then clear the required later code\n    unit. This is because a search for a required code unit starts after an\n    explicit first code unit, but at a code unit found from the bitmap.\n    Patterns such as /a*a/ don't work if both the start unit and required\n    unit are the same. */\n\n    if (a >= 0) {\n      if ((re->flags & PCRE2_LASTSET) && (re->last_codeunit == (uint32_t)a || (b >= 0 && re->last_codeunit == (uint32_t)b))) {\n        re->flags &= ~(PCRE2_LASTSET | PCRE2_LASTCASELESS);\n        re->last_codeunit = 0;\n      }\n      re->first_codeunit = a;\n      flags = PCRE2_FIRSTSET;\n      if (b >= 0) flags |= PCRE2_FIRSTCASELESS;\n    }\n\n    DONE:\n    re->flags |= flags;\n    }\n  }\n\n/* Find the minimum length of subject string. If the pattern can match an empty\nstring, the minimum length is already known. If the pattern contains (*ACCEPT)\nall bets are off, and we don't even try to find a minimum length. If there are\nmore back references than the size of the vector we are going to cache them in,\ndo nothing. A pattern that complicated will probably take a long time to\nanalyze and may in any case turn out to be too complicated. Note that back\nreference minima are held as 16-bit numbers. */\n\nif ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 &&\n     re->top_backref <= MAX_CACHE_BACKREF)\n  {\n  int min;\n  int backref_cache[MAX_CACHE_BACKREF+1];\n  backref_cache[0] = 0;    /* Highest one that is set */\n  min = find_minlength(re, code, code, utf, NULL, &count, backref_cache);\n  switch(min)\n    {\n    case -1:  /* \\C in UTF mode or over-complex regex */\n    break;    /* Leave minlength unchanged (will be zero) */\n\n    /* LCOV_EXCL_START */\n    case -2:\n    PCRE2_DEBUG_UNREACHABLE();\n    return 2; /* missing capturing bracket */\n    /* LCOV_EXCL_STOP */\n\n    /* LCOV_EXCL_START */\n    case -3:\n    PCRE2_DEBUG_UNREACHABLE();\n    return 3; /* unrecognized opcode */\n    /* LCOV_EXCL_STOP */\n\n    default:\n    re->minlength = (min > (int)UINT16_MAX)? (int)UINT16_MAX : min;\n    break;\n    }\n  }\n\nreturn 0;\n}\n\n/* End of pcre2_study.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_substitute.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n#define PTR_STACK_SIZE 20\n\n#define SUBSTITUTE_OPTIONS \\\n  (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \\\n   PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \\\n   PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \\\n   PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY)\n\n\n\n/*************************************************\n*           Find end of substitute text          *\n*************************************************/\n\n/* In extended mode, we recognize ${name:+set text:unset text} and similar\nconstructions. This requires the identification of unescaped : and }\ncharacters. This function scans for such. It must deal with nested ${\nconstructions. The pointer to the text is updated, either to the required end\ncharacter, or to where an error was detected.\n\nArguments:\n  code      points to the compiled expression (for options)\n  ptrptr    points to the pointer to the start of the text (updated)\n  ptrend    end of the whole string\n  last      TRUE if the last expected string (only } recognized)\n\nReturns:    0 on success\n            negative error code on failure\n*/\n\nstatic int\nfind_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,\n  BOOL last)\n{\nint rc = 0;\nuint32_t nestlevel = 0;\nBOOL literal = FALSE;\nPCRE2_SPTR ptr = *ptrptr;\n\nfor (; ptr < ptrend; ptr++)\n  {\n  if (literal)\n    {\n    if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E)\n      {\n      literal = FALSE;\n      ptr += 1;\n      }\n    }\n\n  else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)\n    {\n    if (nestlevel == 0) goto EXIT;\n    nestlevel--;\n    }\n\n  else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT;\n\n  else if (*ptr == CHAR_DOLLAR_SIGN)\n    {\n    if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET)\n      {\n      nestlevel++;\n      ptr += 1;\n      }\n    }\n\n  else if (*ptr == CHAR_BACKSLASH)\n    {\n    int erc;\n    int errorcode;\n    uint32_t ch;\n\n    if (ptr < ptrend - 1) switch (ptr[1])\n      {\n      case CHAR_L:\n      case CHAR_l:\n      case CHAR_U:\n      case CHAR_u:\n      ptr += 1;\n      continue;\n      }\n\n    ptr += 1;  /* Must point after \\ */\n    erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,\n      code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL);\n    if (errorcode != 0)\n      {\n      /* errorcode from check_escape is positive, so must not be returned by\n      pcre2_substitute(). */\n      rc = PCRE2_ERROR_BADREPESCAPE;\n      goto EXIT;\n      }\n\n    switch(erc)\n      {\n      case 0:      /* Data character */\n      case ESC_b:  /* Data character */\n      case ESC_v:  /* Data character */\n      case ESC_E:  /* Isolated \\E is ignored */\n      break;\n\n      case ESC_Q:\n      literal = TRUE;\n      break;\n\n      case ESC_g:\n      /* The \\g<name> form (\\g<number> already handled by check_escape)\n\n      Don't worry about finding the matching \">\". We are super, super lenient\n      about validating ${} replacements inside find_text_end(), so we certainly\n      don't need to worry about other syntax. Importantly, a \\g<..> or $<...>\n      sequence can't contain a '}' character. */\n      break;\n\n      default:\n      if (erc < 0)\n          break;  /* capture group reference */\n      rc = PCRE2_ERROR_BADREPESCAPE;\n      goto EXIT;\n      }\n    }\n  }\n\nrc = PCRE2_ERROR_REPMISSINGBRACE;   /* Terminator not found */\n\nEXIT:\n*ptrptr = ptr;\nreturn rc;\n}\n\n\n/*************************************************\n*           Validate group name                  *\n*************************************************/\n\n/* This function scans for a capture group name, validating it\nconsists of legal characters, is not empty, and does not exceed\nMAX_NAME_SIZE.\n\nArguments:\n  ptrptr    points to the pointer to the start of the text (updated)\n  ptrend    end of the whole string\n  utf       true if the input is UTF-encoded\n  ctypes    pointer to the character types table\n\nReturns:    TRUE if a name was read\n            FALSE otherwise\n*/\n\nstatic BOOL\nread_name_subst(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf,\n    const uint8_t* ctypes)\n{\nPCRE2_SPTR ptr = *ptrptr;\nPCRE2_SPTR nameptr = ptr;\n\nif (ptr >= ptrend)                 /* No characters in name */\n  goto FAILED;\n\n/* We do not need to check whether the name starts with a non-digit.\nWe are simply referencing names here, not defining them. */\n\n/* See read_name in the pcre2_compile.c for the corresponding logic\nrestricting group names inside the pattern itself. */\n\n#ifdef SUPPORT_UNICODE\nif (utf)\n  {\n  uint32_t c, type;\n\n  while (ptr < ptrend)\n    {\n    GETCHAR(c, ptr);\n    type = UCD_CHARTYPE(c);\n    if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L &&\n        c != CHAR_UNDERSCORE) break;\n    ptr++;\n    FORWARDCHARTEST(ptr, ptrend);\n    }\n  }\nelse\n#else\n(void)utf;  /* Avoid compiler warning */\n#endif      /* SUPPORT_UNICODE */\n\n/* Handle group names in non-UTF modes. */\n\n  {\n  while (ptr < ptrend && MAX_255(*ptr) && (ctypes[*ptr] & ctype_word) != 0)\n    {\n    ptr++;\n    }\n  }\n\n/* Check name length */\n\nif (ptr - nameptr > MAX_NAME_SIZE)\n  goto FAILED;\n\n/* Subpattern names must not be empty */\nif (ptr == nameptr)\n  goto FAILED;\n\n*ptrptr = ptr;\nreturn TRUE;\n\nFAILED:\n*ptrptr = ptr;\nreturn FALSE;\n}\n\n\n/*************************************************\n*              Case transformations              *\n*************************************************/\n\n#define PCRE2_SUBSTITUTE_CASE_NONE                 0\n// 1, 2, 3 are PCRE2_SUBSTITUTE_CASE_LOWER, UPPER, TITLE_FIRST.\n#define PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST  4\n\ntypedef struct {\n  int to_case; /* One of PCRE2_SUBSTITUTE_CASE_xyz */\n  BOOL single_char;\n} case_state;\n\n/* Helper to guess how much a string is likely to increase in size when\ncase-transformed. Usually, strings don't change size at all, but some rare\ncharacters do grow. Estimate +10%, plus another few characters.\n\nPerforming this estimation is unfortunate, but inevitable, since we can't call\nthe callout if we ran out of buffer space to prepare its input.\n\nBecause this estimate is inexact (and in pathological cases, underestimates the\nrequired buffer size) we must document that when you have a\nsubstitute_case_callout, and you are using PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, you\nmay need more than two calls to determine the final buffer size. */\n\nstatic PCRE2_SIZE\npessimistic_case_inflation(PCRE2_SIZE len)\n{\nreturn (len >> 3u) + 10;\n}\n\n/* Case transformation behaviour if no callout is passed. */\n\nstatic PCRE2_SIZE\ndefault_substitute_case_callout(\n  PCRE2_SPTR input, PCRE2_SIZE input_len,\n  PCRE2_UCHAR *output, PCRE2_SIZE output_cap,\n  case_state *state, const pcre2_code *code)\n{\nPCRE2_SPTR input_end = input + input_len;\n#ifdef SUPPORT_UNICODE\nBOOL utf;\nBOOL ucp;\n#endif\nPCRE2_UCHAR temp[6];\nBOOL next_to_upper;\nBOOL rest_to_upper;\nBOOL single_char;\nBOOL overflow = FALSE;\nPCRE2_SIZE written = 0;\n\n/* Helpful simplifying invariant: input and output are disjoint buffers.\nI believe that this code is technically undefined behaviour, because the two\npointers input/output are \"unrelated\" pointers and hence not comparable. Casting\nvia char* bypasses some but not all of those technical rules. It is not included\nin release builds, in any case. */\nPCRE2_ASSERT((char *)(input + input_len) <= (char *)output ||\n             (char *)(output + output_cap) <= (char *)input);\n\n#ifdef SUPPORT_UNICODE\nutf = (code->overall_options & PCRE2_UTF) != 0;\nucp = (code->overall_options & PCRE2_UCP) != 0;\n#endif\n\nif (input_len == 0) return 0;\n\nswitch (state->to_case)\n  {\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  return 0;\n  /* LCOV_EXCL_STOP */\n\n  case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE\n  case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE\n  next_to_upper = rest_to_upper = (state->to_case == PCRE2_SUBSTITUTE_CASE_UPPER);\n  break;\n\n  case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE\n  next_to_upper = TRUE;\n  rest_to_upper = FALSE;\n  state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n  break;\n\n  case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE\n  next_to_upper = FALSE;\n  rest_to_upper = TRUE;\n  state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER;\n  break;\n  }\n\nsingle_char = state->single_char;\nif (single_char)\n  state->to_case = PCRE2_SUBSTITUTE_CASE_NONE;\n\nwhile (input < input_end)\n  {\n  uint32_t ch;\n  unsigned int chlen;\n\n  GETCHARINCTEST(ch, input);\n\n#ifdef SUPPORT_UNICODE\n  if ((utf || ucp) && ch >= 128)\n    {\n    uint32_t type = UCD_CHARTYPE(ch);\n    if (PRIV(ucp_gentype)[type] == ucp_L &&\n        type != (next_to_upper? ucp_Lu : ucp_Ll))\n      ch = UCD_OTHERCASE(ch);\n\n    /* TODO This is far from correct... it doesn't support the SpecialCasing.txt\n    mappings, but worse, it's not even correct for all the ordinary case\n    mappings. We should add support for those (at least), and then add the\n    SpecialCasing.txt mappings for Esszet and ligatures, and finally use the\n    Turkish casing flag on the match context. */\n    }\n  else\n#endif\n  if (MAX_255(ch))\n    {\n    if (((code->tables + cbits_offset +\n        (next_to_upper? cbit_upper:cbit_lower)\n        )[ch/8] & (1u << (ch%8))) == 0)\n      ch = (code->tables + fcc_offset)[ch];\n    }\n\n#ifdef SUPPORT_UNICODE\n  if (utf) chlen = PRIV(ord2utf)(ch, temp); else\n#endif\n    {\n    temp[0] = ch;\n    chlen = 1;\n    }\n\n  if (!overflow && chlen <= output_cap)\n    {\n    memcpy(output, temp, CU2BYTES(chlen));\n    output += chlen;\n    output_cap -= chlen;\n    }\n  else\n    {\n    overflow = TRUE;\n    }\n\n  if (chlen > ~(PCRE2_SIZE)0 - written)  /* Integer overflow */\n    return ~(PCRE2_SIZE)0;\n  written += chlen;\n\n  next_to_upper = rest_to_upper;\n\n  /* memcpy the remainder, if only transforming a single character. */\n\n  if (single_char)\n    {\n    PCRE2_SIZE rest_len = input_end - input;\n\n    if (!overflow && rest_len <= output_cap)\n      memcpy(output, input, CU2BYTES(rest_len));\n\n    if (rest_len > ~(PCRE2_SIZE)0 - written)  /* Integer overflow */\n      return ~(PCRE2_SIZE)0;\n    written += rest_len;\n\n    return written;\n    }\n  }\n\nreturn written;\n}\n\n/* Helper to perform the call to the substitute_case_callout. We wrap the\nuser-provided callout because our internal arguments are slightly extended. We\ndon't want the user callout to handle the case of \"\\l\" (first character only to\nlowercase) or \"\\l\\U\" (first character to lowercase, rest to uppercase) because\nthose are not operations defined by Unicode. Instead the user callout simply\nneeds to provide the three Unicode primitives: lower, upper, titlecase. */\n\nstatic PCRE2_SIZE\ndo_case_copy(\n  PCRE2_UCHAR *input_output, PCRE2_SIZE input_len, PCRE2_SIZE output_cap,\n  case_state *state, BOOL utf,\n  PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,\n                                        PCRE2_SIZE, int, void *),\n  void *substitute_case_callout_data)\n{\nPCRE2_SPTR input = input_output;\nPCRE2_UCHAR *output = input_output;\nPCRE2_SIZE rc;\nPCRE2_SIZE rc2;\nint ch1_to_case;\nint rest_to_case;\nPCRE2_UCHAR ch1[6];\nPCRE2_SIZE ch1_len;\nPCRE2_SPTR rest;\nPCRE2_SIZE rest_len;\nBOOL ch1_overflow = FALSE;\nBOOL rest_overflow = FALSE;\n\n#if PCRE2_CODE_UNIT_WIDTH == 32 || !defined(SUPPORT_UNICODE)\n(void)utf; /* Avoid compiler warning. */\n#endif\n\nPCRE2_ASSERT(input_len != 0);\n\nswitch (state->to_case)\n  {\n  /* LCOV_EXCL_START */\n  default:\n  PCRE2_DEBUG_UNREACHABLE();\n  return 0;\n  /* LCOV_EXCL_STOP */\n\n  case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE\n  case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE\n  case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE\n\n  /* The easy case, where our internal casing operations align with those of\n  the callout. */\n\n  if (state->single_char == FALSE)\n    {\n    rc = substitute_case_callout(input, input_len, output, output_cap,\n                                 state->to_case, substitute_case_callout_data);\n\n    if (state->to_case == PCRE2_SUBSTITUTE_CASE_TITLE_FIRST)\n      state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n\n    return rc;\n    }\n\n  ch1_to_case = state->to_case;\n  rest_to_case = PCRE2_SUBSTITUTE_CASE_NONE;\n  break;\n\n  case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE\n  ch1_to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n  rest_to_case = PCRE2_SUBSTITUTE_CASE_UPPER;\n  break;\n  }\n\n/* Identify the leading character. Take copy, because its storage overlaps with\n`output`, and hence may be scrambled by the callout. */\n\n  {\n  PCRE2_SPTR ch_end = input;\n  uint32_t ch;\n\n  GETCHARINCTEST(ch, ch_end);\n  (void) ch;\n  PCRE2_ASSERT(ch_end <= input + input_len && ch_end - input <= 6);\n  ch1_len = ch_end - input;\n  memcpy(ch1, input, CU2BYTES(ch1_len));\n  }\n\nrest = input + ch1_len;\nrest_len = input_len - ch1_len;\n\n/* Transform just ch1. The buffers are always in-place (input == output). With a\ncustom callout, we need a loop to discover its required buffer size. The loop\nwouldn't be required if the callout were well-behaved, but it might be naughty\nand return \"5\" the first time, then \"10\" the next time we call it using the\nexact same input! */\n\n  {\n  PCRE2_SIZE ch1_cap;\n  PCRE2_SIZE max_ch1_cap;\n\n  ch1_cap = ch1_len;  /* First attempt uses the space vacated by ch1. */\n  PCRE2_ASSERT(output_cap >= input_len && input_len >= rest_len);\n  max_ch1_cap = output_cap - rest_len;\n\n  while (TRUE)\n    {\n    rc = substitute_case_callout(ch1, ch1_len, output, ch1_cap, ch1_to_case,\n                                 substitute_case_callout_data);\n    if (rc == ~(PCRE2_SIZE)0) return rc;\n\n    if (rc <= ch1_cap) break;\n\n    if (rc > max_ch1_cap)\n      {\n      ch1_overflow = TRUE;\n      break;\n      }\n\n    /* Move the rest to the right, to make room for expanding ch1. */\n\n    memmove(input_output + rc, rest, CU2BYTES(rest_len));\n    rest = input + rc;\n\n    ch1_cap = rc;\n\n    /* Proof of loop termination: `ch1_cap` is growing on each iteration, but\n    the loop ends if `rc` reaches the (unchanging) upper bound of output_cap. */\n    }\n  }\n\nif (rest_to_case == PCRE2_SUBSTITUTE_CASE_NONE)\n  {\n  if (!ch1_overflow)\n    {\n    PCRE2_ASSERT(rest_len <= output_cap - rc);\n    memmove(output + rc, rest, CU2BYTES(rest_len));\n    }\n  rc2 = rest_len;\n\n  state->to_case = PCRE2_SUBSTITUTE_CASE_NONE;\n  }\nelse\n  {\n  PCRE2_UCHAR dummy[1];\n\n  rc2 = substitute_case_callout(rest, rest_len,\n                                ch1_overflow? dummy : output + rc,\n                                ch1_overflow? 0u : output_cap - rc,\n                                rest_to_case, substitute_case_callout_data);\n  if (rc2 == ~(PCRE2_SIZE)0) return rc2;\n\n  if (!ch1_overflow && rc2 > output_cap - rc) rest_overflow = TRUE;\n\n  /* If ch1 grows so that `xform(ch1)+rest` can't fit in the buffer, but then\n  `rest` shrinks, it's actually possible for the total calculated length of\n  `xform(ch1)+xform(rest)` to come out at less than output_cap. But we can't\n  report that, because it would make it seem that the operation succeeded.\n  If either of xform(ch1) or xform(rest) won't fit in the buffer, our final\n  result must be > output_cap. */\n  if (ch1_overflow && rc2 < rest_len)\n    rc2 = rest_len;\n\n  state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER;\n  }\n\nif (rc2 > ~(PCRE2_SIZE)0 - rc)  /* Integer overflow */\n  return ~(PCRE2_SIZE)0;\n\nPCRE2_ASSERT(!(ch1_overflow || rest_overflow) || rc + rc2 > output_cap);\n(void)rest_overflow;\n\nreturn rc + rc2;\n}\n\n\n/*************************************************\n*              Match and substitute              *\n*************************************************/\n\n/* This function applies a compiled re to a subject string and creates a new\nstring with substitutions. The first 7 arguments are the same as for\npcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.\n\nArguments:\n  code            points to the compiled expression\n  subject         points to the subject string\n  length          length of subject string (may contain binary zeros)\n  start_offset    where to start in the subject string\n  options         option bits\n  match_data      points to a match_data block, or is NULL\n  context         points a PCRE2 context\n  replacement     points to the replacement string\n  rlength         length of replacement string\n  buffer          where to put the substituted string\n  blength         points to length of buffer; updated to length of string\n\nReturns:          >= 0 number of substitutions made\n                  < 0 an error code\n                  PCRE2_ERROR_BADREPLACEMENT means invalid use of $\n*/\n\n/* This macro checks for space in the buffer before copying into it. On\noverflow, either give an error immediately, or keep on, accumulating the\nlength. */\n\n#define CHECKMEMCPY(from, length_) \\\n  do {    \\\n     PCRE2_SIZE chkmc_length = length_; \\\n     if (overflowed) \\\n       {  \\\n       if (chkmc_length > ~(PCRE2_SIZE)0 - extra_needed)  /* Integer overflow */ \\\n         goto TOOLARGEREPLACE; \\\n       extra_needed += chkmc_length; \\\n       }  \\\n     else if (lengthleft < chkmc_length) \\\n       {  \\\n       if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \\\n       overflowed = TRUE; \\\n       extra_needed = chkmc_length - lengthleft; \\\n       }  \\\n     else \\\n       {  \\\n       memcpy(buffer + buff_offset, from, CU2BYTES(chkmc_length)); \\\n       buff_offset += chkmc_length; \\\n       lengthleft -= chkmc_length; \\\n       }  \\\n     }    \\\n  while (0)\n\n/* This macro checks for space and copies characters with casing modifications.\nOn overflow, it behaves as for CHECKMEMCPY().\n\nWhen substitute_case_callout is NULL, the source and destination buffers must\nnot overlap, because our default handler does not support this. */\n\n#define CHECKCASECPY_BASE(length_, do_call) \\\n  do {    \\\n     PCRE2_SIZE chkcc_length = (PCRE2_SIZE)(length_); \\\n     PCRE2_SIZE chkcc_rc; \\\n     do_call \\\n     if (lengthleft < chkcc_rc) \\\n       {  \\\n       if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \\\n       overflowed = TRUE; \\\n       extra_needed = chkcc_rc - lengthleft; \\\n       }  \\\n     else \\\n       {  \\\n       buff_offset += chkcc_rc; \\\n       lengthleft -= chkcc_rc; \\\n       }  \\\n     }    \\\n  while (0)\n\n#define CHECKCASECPY_DEFAULT(from, length_) \\\n  CHECKCASECPY_BASE(length_, { \\\n    chkcc_rc = default_substitute_case_callout(from, chkcc_length,         \\\n                                               buffer + buff_offset,       \\\n                                               overflowed? 0 : lengthleft, \\\n                                               &forcecase, code);          \\\n    if (overflowed) \\\n      { \\\n      if (chkcc_rc > ~(PCRE2_SIZE)0 - extra_needed)  /* Integer overflow */ \\\n        goto TOOLARGEREPLACE; \\\n      extra_needed += chkcc_rc; \\\n      break; \\\n      } \\\n  })\n\n#define CHECKCASECPY_CALLOUT(length_) \\\n  CHECKCASECPY_BASE(length_, { \\\n    chkcc_rc = do_case_copy(buffer + buff_offset, chkcc_length, \\\n                            lengthleft, &forcecase, utf,        \\\n                            substitute_case_callout,            \\\n                            substitute_case_callout_data);      \\\n    if (chkcc_rc == ~(PCRE2_SIZE)0) goto CASEERROR; \\\n  })\n\n/* This macro does a delayed case transformation, for the situation when we have\na case-forcing callout. */\n\n#define DELAYEDFORCECASE() \\\n  do {      \\\n     PCRE2_SIZE chars_outstanding = (buff_offset - casestart_offset) + \\\n            (extra_needed - casestart_extra_needed); \\\n     if (chars_outstanding > 0) \\\n       {    \\\n       if (overflowed) \\\n         {  \\\n         PCRE2_SIZE guess = pessimistic_case_inflation(chars_outstanding); \\\n         if (guess > ~(PCRE2_SIZE)0 - extra_needed)  /* Integer overflow */ \\\n           goto TOOLARGEREPLACE; \\\n         extra_needed += guess; \\\n         }  \\\n       else \\\n         {  \\\n         /* Rewind the buffer */ \\\n         lengthleft += (buff_offset - casestart_offset); \\\n         buff_offset = casestart_offset; \\\n         /* Care! In-place case transformation */ \\\n         CHECKCASECPY_CALLOUT(chars_outstanding); \\\n         }  \\\n       }    \\\n     }      \\\n  while (0)\n\n\n/* Here's the function */\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,\n  PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,\n  pcre2_match_context *mcontext, PCRE2_SPTR replacement, PCRE2_SIZE rlength,\n  PCRE2_UCHAR *buffer, PCRE2_SIZE *blength)\n{\nint rc;\nint subs;\nuint32_t ovector_count;\nuint32_t goptions = 0;\nuint32_t suboptions;\npcre2_match_data *internal_match_data = NULL;\nBOOL escaped_literal = FALSE;\nBOOL overflowed = FALSE;\nBOOL use_existing_match;\nBOOL replacement_only;\nBOOL utf = (code->overall_options & PCRE2_UTF) != 0;\nPCRE2_UCHAR temp[6];\nPCRE2_UCHAR null_str[1] = { 0xcd };\nPCRE2_SPTR original_subject = subject;\nPCRE2_SPTR ptr;\nPCRE2_SPTR repend = NULL;\nPCRE2_SIZE extra_needed = 0;\nPCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength;\nPCRE2_SIZE *ovector;\nPCRE2_SIZE ovecsave[2] = { 0, 0 };\npcre2_substitute_callout_block scb;\nPCRE2_SIZE sub_start_extra_needed;\nPCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,\n                                      PCRE2_SIZE, int, void *) = NULL;\nvoid *substitute_case_callout_data = NULL;\n\n/* General initialization */\n\nbuff_offset = 0;\nlengthleft = buff_length = *blength;\n*blength = PCRE2_UNSET;\n\nif (mcontext != NULL)\n  {\n  substitute_case_callout = mcontext->substitute_case_callout;\n  substitute_case_callout_data = mcontext->substitute_case_callout_data;\n  }\n\n/* Partial matching is not valid. This must come after setting *blength to\nPCRE2_UNSET, so as not to imply an offset in the replacement. */\n\nif ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)\n  return PCRE2_ERROR_BADOPTION;\n\n/* Validate length and find the end of the replacement. A NULL replacement of\nzero length is interpreted as an empty string. */\n\nif (replacement == NULL)\n  {\n  if (rlength != 0) return PCRE2_ERROR_NULL;\n  replacement = null_str;\n  }\n\nif (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);\nrepend = replacement + rlength;\n\n/* A NULL subject of zero length is treated as an empty string. */\n\nif (subject == NULL)\n  {\n  if (length != 0) return PCRE2_ERROR_NULL;\n  subject = null_str;\n  }\n\nif (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);\n\n/* Check for using a match that has already happened. Note that the subject\npointer in the match data may be NULL after a no-match. */\n\nuse_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);\nreplacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);\n\nif (use_existing_match && match_data == NULL) return PCRE2_ERROR_NULL;\n\n/* If an existing match is being passed in, we should check that it matches\nthe passed-in subject pointer, length, and match options. We don't currently\nhave a use-case for someone to match on one subject, then try and use that\nmatch data on a different subject. In a UTF-encoded string, a simple change\nlike replacing one character for another won't preserve the code unit offsets,\nso it's hard to see, in the general case, how it would be safe or useful to\nsupport swapping or mutating the subject string.\n\nSimilarly, using different match options between the first (external) and\nsubsequent (internal, global) matches is hard to justify. */\n\nif (use_existing_match)\n  {\n  /* Return early, as the rest of the match_data may not have been\n  initialised. This duplicates and must be in sync with the check below that\n  aborts substitution on any result other than success or no-match. */\n  if (match_data->rc < 0 && match_data->rc != PCRE2_ERROR_NOMATCH)\n    return match_data->rc;\n\n  /* Not supported if the passed-in match was from the DFA interpreter. */\n  if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)\n    return PCRE2_ERROR_DFA_UFUNC;\n\n  if (code != match_data->code)\n    return PCRE2_ERROR_DIFFSUBSPATTERN;\n\n  /* We want the passed-in subject strings to match. This implies the effective\n  length must match, and either: the pointers are equal (with strict matching\n  of NULL against NULL); or, the special case of PCRE2_COPY_MATCHED_SUBJECT\n  where we cannot compare pointers but we can verify the contents. */\n  if (length != match_data->subject_length ||\n      !(original_subject == match_data->subject ||\n        ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0 &&\n         (length == 0 ||\n          memcmp(subject, match_data->subject, CU2BYTES(length)) == 0))))\n    return PCRE2_ERROR_DIFFSUBSSUBJECT;\n\n  if (start_offset != match_data->start_offset)\n    return PCRE2_ERROR_DIFFSUBSOFFSET;\n\n  if ((options & ~SUBSTITUTE_OPTIONS) != match_data->options)\n    return PCRE2_ERROR_DIFFSUBSOPTIONS;\n  }\n\n/* If starting from an existing match, there must be an externally provided\nmatch data block. We create an internal match_data block in two cases: (a) an\nexternal one is not supplied (and we are not starting from an existing match);\n(b) an existing match is to be used for the first substitution. In the latter\ncase, we copy the existing match into the internal block, except for any cached\nheap frame size and pointer. This ensures that no changes are made to the\nexternal match data block. */\n\n/* WARNING: In both cases below a general context is constructed \"by hand\"\nbecause calling pcre2_general_context_create() involves a memory allocation. If\nthe contents of a general context control block are ever changed there will\nhave to be changes below. */\n\nif (match_data == NULL)\n  {\n  pcre2_general_context gcontext;\n  gcontext.memctl = (mcontext == NULL)?\n    ((pcre2_real_code *)code)->memctl :\n    ((pcre2_real_match_context *)mcontext)->memctl;\n  match_data = internal_match_data =\n    pcre2_match_data_create_from_pattern(code, &gcontext);\n  if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;\n  }\n\nelse if (use_existing_match)\n  {\n  int pairs;\n  pcre2_general_context gcontext;\n  gcontext.memctl = (mcontext == NULL)?\n    ((pcre2_real_code *)code)->memctl :\n    ((pcre2_real_match_context *)mcontext)->memctl;\n  pairs = (code->top_bracket + 1 < match_data->oveccount)?\n    code->top_bracket + 1 : match_data->oveccount;\n  internal_match_data = pcre2_match_data_create(match_data->oveccount,\n    &gcontext);\n  if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;\n  memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector)\n    + 2*pairs*sizeof(PCRE2_SIZE));\n  internal_match_data->heapframes = NULL;\n  internal_match_data->heapframes_size = 0;\n  /* Ensure that the subject is not freed when internal_match_data is */\n  internal_match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;\n  match_data = internal_match_data;\n  }\n\n/* If using an internal match data, there's no need to copy the subject. */\n\nif (internal_match_data != NULL) options &= ~PCRE2_COPY_MATCHED_SUBJECT;\n\n/* Remember ovector details */\n\novector = pcre2_get_ovector_pointer(match_data);\novector_count = pcre2_get_ovector_count(match_data);\n\n/* Fixed things in the callout block */\n\nscb.version = 0;\nscb.input = subject;\nscb.output = (PCRE2_SPTR)buffer;\nscb.ovector = ovector;\n\n/* Check UTF replacement string if necessary. */\n\n#ifdef SUPPORT_UNICODE\nif (utf && (options & PCRE2_NO_UTF_CHECK) == 0)\n  {\n  rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar));\n  if (rc != 0)\n    {\n    match_data->leftchar = 0;\n    goto EXIT;\n    }\n  }\n#endif  /* SUPPORT_UNICODE */\n\n/* Save the substitute options and remove them from the match options. */\n\nsuboptions = options & SUBSTITUTE_OPTIONS;\noptions &= ~SUBSTITUTE_OPTIONS;\n\n/* Error if the start match offset is greater than the length of the subject. */\n\nif (start_offset > length)\n  {\n  match_data->leftchar = 0;\n  rc = PCRE2_ERROR_BADOFFSET;\n  goto EXIT;\n  }\n\n/* Copy up to the start offset, unless only the replacement is required. */\n\nif (!replacement_only) CHECKMEMCPY(subject, start_offset);\n\n/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first\nmatch is taken from the match_data that was passed in. */\n\nsubs = 0;\nfor (;;)\n  {\n  PCRE2_SPTR ptrstack[PTR_STACK_SIZE];\n  uint32_t ptrstackptr = 0;\n  case_state forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE };\n  PCRE2_SIZE casestart_offset = 0;\n  PCRE2_SIZE casestart_extra_needed = 0;\n\n  if (use_existing_match)\n    {\n    rc = match_data->rc;\n    use_existing_match = FALSE;\n    }\n  else rc = pcre2_match(code, subject, length, start_offset, options|goptions,\n    match_data, mcontext);\n\n#ifdef SUPPORT_UNICODE\n  if (utf) options |= PCRE2_NO_UTF_CHECK;  /* Only need to check once */\n#endif\n\n  /* Any error other than no match returns the error code. No match breaks the\n  global loop. */\n\n  if (rc == PCRE2_ERROR_NOMATCH) break;\n\n  if (rc < 0) goto EXIT;\n\n  /* Handle a successful match. Matches that use \\K to end before they start\n  or start before the current point in the subject are not supported. */\n\n  if (ovector[1] < ovector[0] || ovector[0] < start_offset)\n    {\n    rc = PCRE2_ERROR_BADSUBSPATTERN;\n    goto EXIT;\n    }\n\n  /* Assert that our replacement loop is making progress, checked even in\n  release builds. This should be impossible to hit, however, an infinite loop\n  would be fairly catastrophic.\n\n  \"Progress\" is measured as ovector[1] strictly advancing, or, an empty match\n  after a non-empty match. */\n\n  /* LCOV_EXCL_START */\n  if (subs > 0 &&\n      !(ovector[1] > ovecsave[1] ||\n        (ovector[1] == ovector[0] && ovecsave[1] > ovecsave[0] &&\n         ovector[1] == ovecsave[1])))\n    {\n    PCRE2_DEBUG_UNREACHABLE();\n    rc = PCRE2_ERROR_INTERNAL_DUPMATCH;\n    goto EXIT;\n    }\n  /* LCOV_EXCL_STOP */\n\n  ovecsave[0] = ovector[0];\n  ovecsave[1] = ovector[1];\n\n  /* Count substitutions with a paranoid check for integer overflow; surely no\n  real call to this function would ever hit this! */\n\n  if (subs == INT_MAX)\n    {\n    rc = PCRE2_ERROR_TOOMANYREPLACE;\n    goto EXIT;\n    }\n  subs++;\n\n  /* Copy the text leading up to the match (unless not required); remember\n  where the insert begins and how many ovector pairs are set; and remember how\n  much space we have requested in extra_needed. */\n\n  if (rc == 0) rc = ovector_count;\n  fraglength = ovector[0] - start_offset;\n  if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength);\n  scb.output_offsets[0] = buff_offset;\n  scb.oveccount = rc;\n  sub_start_extra_needed = extra_needed;\n\n  /* Process the replacement string. If the entire replacement is literal, just\n  copy it with length check. */\n\n  ptr = replacement;\n  if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0)\n    {\n    CHECKMEMCPY(ptr, rlength);\n    }\n\n  /* Within a non-literal replacement, which must be scanned character by\n  character, local literal mode can be set by \\Q, but only in extended mode\n  when backslashes are being interpreted. In extended mode we must handle\n  nested substrings that are to be reprocessed. */\n\n  else for (;;)\n    {\n    uint32_t ch;\n    unsigned int chlen;\n    int group;\n    uint32_t special;\n    PCRE2_SPTR text1_start = NULL;\n    PCRE2_SPTR text1_end = NULL;\n    PCRE2_SPTR text2_start = NULL;\n    PCRE2_SPTR text2_end = NULL;\n    PCRE2_UCHAR name[MAX_NAME_SIZE + 1];\n\n    /* If at the end of a nested substring, pop the stack. */\n\n    if (ptr >= repend)\n      {\n      if (ptrstackptr == 0) break;       /* End of replacement string */\n      repend = ptrstack[--ptrstackptr];\n      ptr = ptrstack[--ptrstackptr];\n      continue;\n      }\n\n    /* Handle the next character */\n\n    if (escaped_literal)\n      {\n      if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)\n        {\n        escaped_literal = FALSE;\n        ptr += 2;\n        continue;\n        }\n      goto LOADLITERAL;\n      }\n\n    /* Not in literal mode. */\n\n    if (*ptr == CHAR_DOLLAR_SIGN)\n      {\n      BOOL inparens;\n      BOOL inangle;\n      BOOL star;\n      PCRE2_SIZE sublength;\n      PCRE2_UCHAR next;\n      PCRE2_SPTR subptr, subptrend;\n\n      if (++ptr >= repend) goto BAD;\n      if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL;\n\n      special = 0;\n      text1_start = NULL;\n      text1_end = NULL;\n      text2_start = NULL;\n      text2_end = NULL;\n      group = -1;\n      inparens = FALSE;\n      inangle = FALSE;\n      star = FALSE;\n      subptr = NULL;\n      subptrend = NULL;\n\n      /* Special $ sequences, as supported by Perl, JavaScript, .NET and others. */\n      if (next == CHAR_AMPERSAND)\n        {\n        ++ptr;\n        group = 0;\n        goto GROUP_SUBSTITUTE;\n        }\n      if (next == CHAR_GRAVE_ACCENT || next == CHAR_APOSTROPHE)\n        {\n        ++ptr;\n        rc = pcre2_substring_length_bynumber(match_data, 0, &sublength);\n        if (rc < 0) goto PTREXIT; /* (Sanity-check ovector before reading from it.) */\n\n        if (next == CHAR_GRAVE_ACCENT)\n          {\n          subptr = subject;\n          subptrend = subject + ovector[0];\n          }\n        else\n          {\n          subptr = subject + ovector[1];\n          subptrend = subject + length;\n          }\n\n        goto SUBPTR_SUBSTITUTE;\n        }\n      if (next == CHAR_UNDERSCORE)\n        {\n        /* Java, .NET support $_ for \"entire input string\". */\n        ++ptr;\n        subptr = subject;\n        subptrend = subject + length;\n        goto SUBPTR_SUBSTITUTE;\n        }\n      else if (next == CHAR_PLUS &&\n               !(ptr+1 < repend && ptr[1] == CHAR_LEFT_CURLY_BRACKET))\n        {\n        /* Perl supports $+ for \"highest captured group\" (not the same as $^N\n        which is mainly only useful inside Perl's match callbacks). We also\n        don't accept \"$+{...\" since that's Perl syntax for our ${name}. */\n        ++ptr;\n        if (code->top_bracket == 0)\n          {\n          /* Treat either as \"no such group\" or \"all groups unset\" based on the\n          PCRE2_SUBSTITUTE_UNKNOWN_UNSET option. */\n          if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) == 0)\n            {\n            rc = PCRE2_ERROR_NOSUBSTRING;\n            goto PTREXIT;\n            }\n          group = 0;\n          }\n        else\n          {\n          /* If we have any capture groups, then the ovector needs to be large\n          enough for all of them, or the result won't be accurate. */\n          if (match_data->oveccount < code->top_bracket + 1)\n            {\n            rc = PCRE2_ERROR_UNAVAILABLE;\n            goto PTREXIT;\n            }\n          for (group = code->top_bracket; group > 0; group--)\n            if (ovector[2*group] != PCRE2_UNSET) break;\n          }\n        if (group == 0)\n          {\n          if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;\n          rc = PCRE2_ERROR_UNSET;\n          goto PTREXIT;\n          }\n        goto GROUP_SUBSTITUTE;\n        }\n\n      if (next == CHAR_LEFT_CURLY_BRACKET)\n        {\n        if (++ptr >= repend) goto BAD;\n        next = *ptr;\n        inparens = TRUE;\n        }\n      else if (next == CHAR_LESS_THAN_SIGN)\n        {\n        /* JavaScript compatibility syntax, $<name>. Processes only named\n        groups (not numbered) and does not support extensions such as star\n        (you can do ${name} and ${*name}, but not $<*name>). */\n        if (++ptr >= repend) goto BAD;\n        next = *ptr;\n        inangle = TRUE;\n        }\n\n      if (!inangle && next == CHAR_ASTERISK)\n        {\n        if (++ptr >= repend) goto BAD;\n        next = *ptr;\n        star = TRUE;\n        }\n\n      if (!star && !inangle && next >= CHAR_0 && next <= CHAR_9)\n        {\n        group = next - CHAR_0;\n        while (++ptr < repend)\n          {\n          next = *ptr;\n          if (next < CHAR_0 || next > CHAR_9) break;\n          group = group * 10 + (next - CHAR_0);\n\n          /* A check for a number greater than the hightest captured group\n          is sufficient here; no need for a separate overflow check. If unknown\n          groups are to be treated as unset, just skip over any remaining\n          digits and carry on. */\n\n          if (group > code->top_bracket)\n            {\n            if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)\n              {\n              while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9);\n              break;\n              }\n            else\n              {\n              rc = PCRE2_ERROR_NOSUBSTRING;\n              goto PTREXIT;\n              }\n            }\n          }\n        }\n      else\n        {\n        PCRE2_SIZE name_len;\n        PCRE2_SPTR name_start = ptr;\n        if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset))\n          goto BAD;\n        name_len = ptr - name_start;\n        memcpy(name, name_start, CU2BYTES(name_len));\n        name[name_len] = 0;\n        }\n\n      next = 0; /* not used or updated after this point */\n      (void)next;\n\n      /* In extended mode we recognize ${name:+set text:unset text} and\n      ${name:-default text}. */\n\n      if (inparens)\n        {\n        if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&\n             !star && ptr < repend - 2 && *ptr == CHAR_COLON)\n          {\n          special = *(++ptr);\n          if (special != CHAR_PLUS && special != CHAR_MINUS)\n            {\n            rc = PCRE2_ERROR_BADSUBSTITUTION;\n            goto PTREXIT;\n            }\n\n          text1_start = ++ptr;\n          rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS);\n          if (rc != 0) goto PTREXIT;\n          text1_end = ptr;\n\n          if (special == CHAR_PLUS && *ptr == CHAR_COLON)\n            {\n            text2_start = ++ptr;\n            rc = find_text_end(code, &ptr, repend, TRUE);\n            if (rc != 0) goto PTREXIT;\n            text2_end = ptr;\n            }\n          }\n\n        else\n          {\n          if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET)\n            {\n            rc = PCRE2_ERROR_REPMISSINGBRACE;\n            goto PTREXIT;\n            }\n          }\n\n        ptr++;\n        }\n\n      if (inangle)\n        {\n        if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN)\n          goto BAD;\n        ptr++;\n        }\n\n      /* Have found a syntactically correct group number or name, or *name.\n      Only *MARK is currently recognized. */\n\n      if (star)\n        {\n        if (PRIV(strcmp_c8)(name, STRING_MARK) == 0)\n          {\n          PCRE2_SPTR mark = pcre2_get_mark(match_data);\n          if (mark != NULL)\n            {\n            /* Peek backwards one code unit to obtain the length of the mark.\n            It can (theoretically) contain an embedded NUL. */\n            fraglength = mark[-1];\n            if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE &&\n                substitute_case_callout == NULL)\n              CHECKCASECPY_DEFAULT(mark, fraglength);\n            else\n              CHECKMEMCPY(mark, fraglength);\n            }\n          }\n        else goto BAD;\n        }\n\n      /* Substitute the contents of a group. We don't use substring_copy\n      functions any more, in order to support case forcing. */\n\n      else\n        {\n        GROUP_SUBSTITUTE:\n        /* Find a number for a named group. In case there are duplicate names,\n        search for the first one that is set. If the name is not found when\n        PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a\n        non-existent group. */\n\n        if (group < 0)\n          {\n          PCRE2_SPTR first, last, entry;\n          rc = pcre2_substring_nametable_scan(code, name, &first, &last);\n          if (rc == PCRE2_ERROR_NOSUBSTRING &&\n              (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)\n            {\n            group = code->top_bracket + 1;\n            }\n          else\n            {\n            if (rc < 0) goto PTREXIT;\n            for (entry = first; entry <= last; entry += rc)\n              {\n              uint32_t ng = GET2(entry, 0);\n              if (ng < ovector_count)\n                {\n                if (group < 0) group = ng;          /* First in ovector */\n                if (ovector[ng*2] != PCRE2_UNSET)\n                  {\n                  group = ng;                       /* First that is set */\n                  break;\n                  }\n                }\n              }\n\n            /* If group is still negative, it means we did not find a group\n            that is in the ovector. Just set the first group. */\n\n            if (group < 0) group = GET2(first, 0);\n            }\n          }\n\n        /* We now have a group that is identified by number. Find the length of\n        the captured string. If a group in a non-special substitution is unset\n        when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */\n\n        rc = pcre2_substring_length_bynumber(match_data, group, &sublength);\n        if (rc < 0)\n          {\n          if (rc == PCRE2_ERROR_NOSUBSTRING &&\n              (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)\n            {\n            rc = PCRE2_ERROR_UNSET;\n            }\n          if (rc != PCRE2_ERROR_UNSET) goto PTREXIT;  /* Non-unset errors */\n          if (special == 0)                           /* Plain substitution */\n            {\n            if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;\n            goto PTREXIT;                             /* Else error */\n            }\n          }\n\n        /* If special is '+' we have a 'set' and possibly an 'unset' text,\n        both of which are reprocessed when used. If special is '-' we have a\n        default text for when the group is unset; it must be reprocessed. */\n\n        if (special != 0)\n          {\n          if (special == CHAR_MINUS)\n            {\n            if (rc == 0) goto LITERAL_SUBSTITUTE;\n            text2_start = text1_start;\n            text2_end = text1_end;\n            }\n\n          if (ptrstackptr >= PTR_STACK_SIZE) goto BAD;\n          ptrstack[ptrstackptr++] = ptr;\n          ptrstack[ptrstackptr++] = repend;\n\n          if (rc == 0)\n            {\n            ptr = text1_start;\n            repend = text1_end;\n            }\n          else\n            {\n            ptr = text2_start;\n            repend = text2_end;\n            }\n          continue;\n          }\n\n        /* Otherwise we have a literal substitution of a group's contents. */\n\n        LITERAL_SUBSTITUTE:\n        subptr = subject + ovector[group*2];\n        subptrend = subject + ovector[group*2 + 1];\n\n        /* Substitute a literal string, possibly forcing alphabetic case. */\n\n        SUBPTR_SUBSTITUTE:\n        if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE &&\n            substitute_case_callout == NULL)\n          CHECKCASECPY_DEFAULT(subptr, subptrend - subptr);\n        else\n          CHECKMEMCPY(subptr, subptrend - subptr);\n        }\n      }   /* End of $ processing */\n\n    /* Handle an escape sequence in extended mode. We can use check_escape()\n    to process \\Q, \\E, \\c, \\o, \\x and \\ followed by non-alphanumerics, but\n    the case-forcing escapes are not supported in pcre2_compile() so must be\n    recognized here. */\n\n    else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&\n              *ptr == CHAR_BACKSLASH)\n      {\n      int errorcode;\n      case_state new_forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE };\n\n      if (ptr < repend - 1) switch (ptr[1])\n        {\n        case CHAR_L:\n        new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n        new_forcecase.single_char = FALSE;\n        ptr += 2;\n        break;\n\n        case CHAR_l:\n        new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n        new_forcecase.single_char = TRUE;\n        ptr += 2;\n        if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_U)\n          {\n          /* Perl reverse-title-casing feature for \\l\\U */\n          new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST;\n          new_forcecase.single_char = FALSE;\n          ptr += 2;\n          }\n        break;\n\n        case CHAR_U:\n        new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_UPPER;\n        new_forcecase.single_char = FALSE;\n        ptr += 2;\n        break;\n\n        case CHAR_u:\n        new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST;\n        new_forcecase.single_char = TRUE;\n        ptr += 2;\n        if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_L)\n          {\n          /* Perl title-casing feature for \\u\\L */\n          new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST;\n          new_forcecase.single_char = FALSE;\n          ptr += 2;\n          }\n        break;\n\n        default:\n        break;\n        }\n\n      if (new_forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE)\n        {\n        SETFORCECASE:\n\n        /* If the substitute_case_callout is unset, our case-forcing is done\n        immediately. If there is a callout however, then its action is delayed\n        until all the characters have been collected.\n\n        Apply the callout now, before we set the new casing mode. */\n\n        if (substitute_case_callout != NULL &&\n            forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE)\n          DELAYEDFORCECASE();\n\n        forcecase = new_forcecase;\n        casestart_offset = buff_offset;\n        casestart_extra_needed = extra_needed;\n        continue;\n        }\n\n      ptr++;  /* Point after \\ */\n      rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode,\n        code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL);\n      if (errorcode != 0) goto BADESCAPE;\n\n      switch(rc)\n        {\n        case ESC_E:\n        goto SETFORCECASE;\n\n        case ESC_Q:\n        escaped_literal = TRUE;\n        continue;\n\n        case 0:      /* Data character */\n        case ESC_b:  /* \\b is backspace in a substitution */\n        case ESC_v:  /* \\v is vertical tab in a substitution */\n\n        if (rc == ESC_b) ch = CHAR_BS;\n        if (rc == ESC_v) ch = CHAR_VT;\n\n#ifdef SUPPORT_UNICODE\n        if (utf) chlen = PRIV(ord2utf)(ch, temp); else\n#endif\n          {\n          temp[0] = ch;\n          chlen = 1;\n          }\n\n        if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE &&\n            substitute_case_callout == NULL)\n          CHECKCASECPY_DEFAULT(temp, chlen);\n        else\n          CHECKMEMCPY(temp, chlen);\n        continue;\n\n        case ESC_g:\n          {\n          PCRE2_SIZE name_len;\n          PCRE2_SPTR name_start;\n\n          /* Parse the \\g<name> form (\\g<number> already handled by check_escape) */\n          if (ptr >= repend || *ptr != CHAR_LESS_THAN_SIGN)\n            goto BADESCAPE;\n          ++ptr;\n\n          name_start = ptr;\n          if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset))\n            goto BADESCAPE;\n          name_len = ptr - name_start;\n\n          if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN)\n            goto BADESCAPE;\n          ++ptr;\n\n          special = 0;\n          group = -1;\n          memcpy(name, name_start, CU2BYTES(name_len));\n          name[name_len] = 0;\n          goto GROUP_SUBSTITUTE;\n          }\n\n        default:\n        if (rc < 0)\n          {\n          special = 0;\n          group = -rc - 1;\n          goto GROUP_SUBSTITUTE;\n          }\n        goto BADESCAPE;\n        }\n      }   /* End of backslash processing */\n\n    /* Handle a literal code unit */\n\n    else\n      {\n      PCRE2_SPTR ch_start;\n\n      LOADLITERAL:\n      ch_start = ptr;\n      GETCHARINCTEST(ch, ptr);    /* Get character value, increment pointer */\n      (void) ch;\n\n      if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE &&\n          substitute_case_callout == NULL)\n        CHECKCASECPY_DEFAULT(ch_start, ptr - ch_start);\n      else\n        CHECKMEMCPY(ch_start, ptr - ch_start);\n      } /* End handling a literal code unit */\n    }   /* End of loop for scanning the replacement. */\n\n  /* If the substitute_case_callout is unset, our case-forcing is done\n  immediately. If there is a callout however, then its action is delayed\n  until all the characters have been collected.\n\n  We now clean up any trailing section of the replacement for which we deferred\n  the case-forcing. */\n\n  if (substitute_case_callout != NULL &&\n      forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE)\n    DELAYEDFORCECASE();\n\n  /* The replacement has been copied to the output, or its size has been\n  remembered. Handle the callout if there is one. */\n\n  if (mcontext != NULL && mcontext->substitute_callout != NULL)\n    {\n    /* If we an actual (non-simulated) replacement, do the callout. */\n\n    if (!overflowed)\n      {\n      scb.subscount = subs;\n      scb.output_offsets[1] = buff_offset;\n      rc = mcontext->substitute_callout(&scb,\n                                        mcontext->substitute_callout_data);\n\n      /* A non-zero return means cancel this substitution. Instead, copy the\n      matched string fragment. */\n\n      if (rc != 0)\n        {\n        PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0];\n        PCRE2_SIZE oldlength = ovector[1] - ovector[0];\n\n        buff_offset -= newlength;\n        lengthleft += newlength;\n        if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength);\n\n        /* A negative return means do not do any more. */\n\n        if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL);\n        }\n      }\n\n    /* In this interesting case, we cannot do the callout, so it's hard to\n    estimate the required buffer size. What callers want is to be able to make\n    two calls to pcre2_substitute(), once with PCRE2_SUBSTITUTE_OVERFLOW_LENGTH\n    to discover the buffer size, and then a second and final call. Older\n    versions of PCRE2 violated this assumption, by proceding as if the callout\n    had returned zero - but on the second call to pcre2_substitute() it could\n    return non-zero and then overflow the buffer again. Callers probably don't\n    want to keep on looping to incrementally discover the buffer size. */\n\n    else\n      {\n      PCRE2_SIZE newlength_buf = buff_offset - scb.output_offsets[0];\n      PCRE2_SIZE newlength_extra = extra_needed - sub_start_extra_needed;\n      PCRE2_SIZE newlength =\n        (newlength_extra > ~(PCRE2_SIZE)0 - newlength_buf)?  /* Integer overflow */\n        ~(PCRE2_SIZE)0 : newlength_buf + newlength_extra;    /* Cap the addition */\n      PCRE2_SIZE oldlength = ovector[1] - ovector[0];\n\n      /* Be pessimistic: request whichever buffer size is larger out of\n      accepting or rejecting the substitution. */\n\n      if (oldlength > newlength)\n        {\n        PCRE2_SIZE additional = oldlength - newlength;\n        if (additional > ~(PCRE2_SIZE)0 - extra_needed)  /* Integer overflow */\n          goto TOOLARGEREPLACE;\n        extra_needed += additional;\n        }\n\n      /* Proceed as if the callout did not return a negative. A negative\n      effectively rejects all future substitutions, but we want to examine them\n      pessimistically. */\n      }\n    }\n\n  /* Exit the global loop if we are not in global mode, or if pcre2_next_match()\n  indicates we have reached the end of the subject. */\n\n  if ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) == 0 ||\n      !pcre2_next_match(match_data, &start_offset, &goptions))\n    {\n    start_offset = ovector[1];\n    break;\n    }\n\n  /* Verify that pcre2_next_match() has not done a bumpalong (because we have\n  already returned PCRE2_ERROR_BADSUBSPATTERN for \\K in lookarounds).\n\n  We would otherwise have to memcpy the fragment spanning from ovector[1] to the\n  new start_offset.*/\n\n  PCRE2_ASSERT(start_offset == ovector[1]);\n\n  }  /* End of global loop */\n\n/* Copy the rest of the subject unless not required, and terminate the output\nwith a binary zero. */\n\nif (!replacement_only)\n  {\n  fraglength = length - start_offset;\n  CHECKMEMCPY(subject + start_offset, fraglength);\n  }\n\ntemp[0] = 0;\nCHECKMEMCPY(temp, 1);\n\n/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,\nand matching has carried on after a full buffer, in order to compute the length\nneeded. Otherwise, an overflow generates an immediate error return. */\n\nif (overflowed)\n  {\n  rc = PCRE2_ERROR_NOMEMORY;\n\n  if (extra_needed > ~(PCRE2_SIZE)0 - buff_length)  /* Integer overflow */\n    goto TOOLARGEREPLACE;\n  *blength = buff_length + extra_needed;\n  }\n\n/* After a successful execution, return the number of substitutions and set the\nlength of buffer used, excluding the trailing zero. */\n\nelse\n  {\n  rc = subs;\n  *blength = buff_offset - 1;\n  }\n\nEXIT:\nif (internal_match_data != NULL) pcre2_match_data_free(internal_match_data);\n  else match_data->rc = rc;\nreturn rc;\n\nNOROOM:\nrc = PCRE2_ERROR_NOMEMORY;\ngoto EXIT;\n\nCASEERROR:\nrc = PCRE2_ERROR_REPLACECASE;\ngoto EXIT;\n\nTOOLARGEREPLACE:\nrc = PCRE2_ERROR_TOOLARGEREPLACE;\ngoto EXIT;\n\nBAD:\nrc = PCRE2_ERROR_BADREPLACEMENT;\ngoto PTREXIT;\n\nBADESCAPE:\nrc = PCRE2_ERROR_BADREPESCAPE;\n\nPTREXIT:\n*blength = (PCRE2_SIZE)(ptr - replacement);\ngoto EXIT;\n}\n\n/* End of pcre2_substitute.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_substring.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*   Copy named captured string to given buffer   *\n*************************************************/\n\n/* This function copies a single captured substring into a given buffer,\nidentifying it by name. If the regex permits duplicate names, the first\nsubstring that is set is chosen.\n\nArguments:\n  match_data     points to the match data\n  stringname     the name of the required substring\n  buffer         where to put the substring\n  sizeptr        the size of the buffer, updated to the size of the substring\n\nReturns:         if successful: zero\n                 if not successful, a negative error code:\n                   (1) an error from nametable_scan()\n                   (2) an error from copy_bynumber()\n                   (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector\n                   (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname,\n  PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)\n{\nPCRE2_SPTR first, last, entry;\nint failrc, entrysize;\nif (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)\n  return PCRE2_ERROR_DFA_UFUNC;\nentrysize = pcre2_substring_nametable_scan(match_data->code, stringname,\n  &first, &last);\nif (entrysize < 0) return entrysize;\nfailrc = PCRE2_ERROR_UNAVAILABLE;\nfor (entry = first; entry <= last; entry += entrysize)\n  {\n  uint32_t n = GET2(entry, 0);\n  if (n < match_data->oveccount)\n    {\n    if (match_data->ovector[n*2] != PCRE2_UNSET)\n      return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr);\n    failrc = PCRE2_ERROR_UNSET;\n    }\n  }\nreturn failrc;\n}\n\n\n\n/*************************************************\n*  Copy numbered captured string to given buffer *\n*************************************************/\n\n/* This function copies a single captured substring into a given buffer,\nidentifying it by number.\n\nArguments:\n  match_data     points to the match data\n  stringnumber   the number of the required substring\n  buffer         where to put the substring\n  sizeptr        the size of the buffer, updated to the size of the substring\n\nReturns:         if successful: 0\n                 if not successful, a negative error code:\n                   PCRE2_ERROR_NOMEMORY: buffer too small\n                   PCRE2_ERROR_NOSUBSTRING: no such substring\n                   PCRE2_ERROR_UNAVAILABLE: ovector too small\n                   PCRE2_ERROR_UNSET: substring is not set\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_copy_bynumber(pcre2_match_data *match_data,\n  uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)\n{\nint rc;\nPCRE2_SIZE size;\nrc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);\nif (rc < 0) return rc;\nif (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;\nif (size != 0) memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],\n  CU2BYTES(size));\nbuffer[size] = 0;\n*sizeptr = size;\nreturn 0;\n}\n\n\n\n/*************************************************\n*          Extract named captured string         *\n*************************************************/\n\n/* This function copies a single captured substring, identified by name, into\nnew memory. If the regex permits duplicate names, the first substring that is\nset is chosen.\n\nArguments:\n  match_data     pointer to match_data\n  stringname     the name of the required substring\n  stringptr      where to put the pointer to the new memory\n  sizeptr        where to put the length of the substring\n\nReturns:         if successful: zero\n                 if not successful, a negative value:\n                   (1) an error from nametable_scan()\n                   (2) an error from get_bynumber()\n                   (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector\n                   (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_get_byname(pcre2_match_data *match_data,\n  PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)\n{\nPCRE2_SPTR first, last, entry;\nint failrc, entrysize;\nif (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)\n  return PCRE2_ERROR_DFA_UFUNC;\nentrysize = pcre2_substring_nametable_scan(match_data->code, stringname,\n  &first, &last);\nif (entrysize < 0) return entrysize;\nfailrc = PCRE2_ERROR_UNAVAILABLE;\nfor (entry = first; entry <= last; entry += entrysize)\n  {\n  uint32_t n = GET2(entry, 0);\n  if (n < match_data->oveccount)\n    {\n    if (match_data->ovector[n*2] != PCRE2_UNSET)\n      return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr);\n    failrc = PCRE2_ERROR_UNSET;\n    }\n  }\nreturn failrc;\n}\n\n\n\n/*************************************************\n*      Extract captured string to new memory     *\n*************************************************/\n\n/* This function copies a single captured substring into a piece of new\nmemory.\n\nArguments:\n  match_data     points to match data\n  stringnumber   the number of the required substring\n  stringptr      where to put a pointer to the new memory\n  sizeptr        where to put the size of the substring\n\nReturns:         if successful: 0\n                 if not successful, a negative error code:\n                   PCRE2_ERROR_NOMEMORY: failed to get memory\n                   PCRE2_ERROR_NOSUBSTRING: no such substring\n                   PCRE2_ERROR_UNAVAILABLE: ovector too small\n                   PCRE2_ERROR_UNSET: substring is not set\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_get_bynumber(pcre2_match_data *match_data,\n  uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)\n{\nint rc;\nPCRE2_SIZE size;\nPCRE2_UCHAR *yield;\nrc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);\nif (rc < 0) return rc;\nyield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +\n  (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);\nif (yield == NULL) return PCRE2_ERROR_NOMEMORY;\nyield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));\nif (size != 0) memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],\n  CU2BYTES(size));\nyield[size] = 0;\n*stringptr = yield;\n*sizeptr = size;\nreturn 0;\n}\n\n\n\n/*************************************************\n*       Free memory obtained by get_substring    *\n*************************************************/\n\n/*\nArgument:     the result of a previous pcre2_substring_get_byxxx()\nReturns:      nothing\n*/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_substring_free(PCRE2_UCHAR *string)\n{\nif (string != NULL)\n  {\n  pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl));\n  memctl->free(memctl, memctl->memory_data);\n  }\n}\n\n\n\n/*************************************************\n*         Get length of a named substring        *\n*************************************************/\n\n/* This function returns the length of a named captured substring. If the regex\npermits duplicate names, the first substring that is set is chosen.\n\nArguments:\n  match_data      pointer to match data\n  stringname      the name of the required substring\n  sizeptr         where to put the length, if not NULL\n\nReturns:          0 if successful, else a negative error number\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_length_byname(pcre2_match_data *match_data,\n  PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr)\n{\nPCRE2_SPTR first, last, entry;\nint failrc, entrysize;\nif (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)\n  return PCRE2_ERROR_DFA_UFUNC;\nentrysize = pcre2_substring_nametable_scan(match_data->code, stringname,\n  &first, &last);\nif (entrysize < 0) return entrysize;\nfailrc = PCRE2_ERROR_UNAVAILABLE;\nfor (entry = first; entry <= last; entry += entrysize)\n  {\n  uint32_t n = GET2(entry, 0);\n  if (n < match_data->oveccount)\n    {\n    if (match_data->ovector[n*2] != PCRE2_UNSET)\n      return pcre2_substring_length_bynumber(match_data, n, sizeptr);\n    failrc = PCRE2_ERROR_UNSET;\n    }\n  }\nreturn failrc;\n}\n\n\n\n/*************************************************\n*        Get length of a numbered substring      *\n*************************************************/\n\n/* This function returns the length of a captured substring. If the start is\nbeyond the end (which can happen when \\K is used in an assertion), it sets the\nlength to zero.\n\nArguments:\n  match_data      pointer to match data\n  stringnumber    the number of the required substring\n  sizeptr         where to put the length, if not NULL\n\nReturns:         if successful: 0\n                 if not successful, a negative error code:\n                   PCRE2_ERROR_NOSUBSTRING: no such substring\n                   PCRE2_ERROR_UNAVAILABLE: ovector is too small\n                   PCRE2_ERROR_UNSET: substring is not set\n                   PCRE2_ERROR_INVALIDOFFSET: internal error, should not occur\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_length_bynumber(pcre2_match_data *match_data,\n  uint32_t stringnumber, PCRE2_SIZE *sizeptr)\n{\nPCRE2_SIZE left, right;\nint count = match_data->rc;\nif (count == PCRE2_ERROR_PARTIAL)\n  {\n  if (stringnumber > 0) return PCRE2_ERROR_PARTIAL;\n  count = 0;\n  }\nelse if (count < 0) return count;            /* Match failed */\n\nif (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER)\n  {\n  if (stringnumber > match_data->code->top_bracket)\n    return PCRE2_ERROR_NOSUBSTRING;\n  if (stringnumber >= match_data->oveccount)\n    return PCRE2_ERROR_UNAVAILABLE;\n  if (match_data->ovector[stringnumber*2] == PCRE2_UNSET)\n    return PCRE2_ERROR_UNSET;\n  }\nelse  /* Matched using pcre2_dfa_match() */\n  {\n  if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE;\n  if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET;\n  }\n\nleft = match_data->ovector[stringnumber*2];\nright = match_data->ovector[stringnumber*2+1];\n/* LCOV_EXCL_START - this appears to be unreachable, as the ovector and\nsubject_length should always be set consistently, no matter what misbehaviour\nthe caller has committed. */\nif (left > match_data->subject_length || right > match_data->subject_length)\n  {\n  PCRE2_DEBUG_UNREACHABLE();\n  return PCRE2_ERROR_INVALIDOFFSET;\n  }\n/* LCOV_EXCL_STOP */\nif (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;\nreturn 0;\n}\n\n\n\n/*************************************************\n*    Extract all captured strings to new memory  *\n*************************************************/\n\n/* This function gets one chunk of memory and builds a list of pointers and all\nthe captured substrings in it. A NULL pointer is put on the end of the list.\nThe substrings are zero-terminated, but also, if the final argument is\nnon-NULL, a list of lengths is also returned. This allows binary data to be\nhandled.\n\nArguments:\n  match_data     points to the match data\n  listptr        set to point to the list of pointers\n  lengthsptr     set to point to the list of lengths (may be NULL)\n\nReturns:         if successful: 0\n                 if not successful, a negative error code:\n                   PCRE2_ERROR_NOMEMORY: failed to get memory,\n                   or a match failure code\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr,\n  PCRE2_SIZE **lengthsptr)\n{\nint i, count, count2;\nPCRE2_SIZE size;\nPCRE2_SIZE *lensp;\npcre2_memctl *memp;\nPCRE2_UCHAR **listp;\nPCRE2_UCHAR *sp;\nPCRE2_SIZE *ovector;\n\nif ((count = match_data->rc) < 0) return count;   /* Match failed */\nif (count == 0) count = match_data->oveccount;    /* Ovector too small */\n\ncount2 = 2*count;\novector = match_data->ovector;\nsize = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *);      /* For final NULL */\nif (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count;  /* For lengths */\n\nfor (i = 0; i < count2; i += 2)\n  {\n  size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1);\n  if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]);\n  }\n\nmemp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data);\nif (memp == NULL) return PCRE2_ERROR_NOMEMORY;\n\n*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl));\nlensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1));\n\nif (lengthsptr == NULL)\n  {\n  sp = (PCRE2_UCHAR *)lensp;\n  lensp = NULL;\n  }\nelse\n  {\n  *lengthsptr = lensp;\n  sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count);\n  }\n\nfor (i = 0; i < count2; i += 2)\n  {\n  size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;\n\n  /* Size == 0 includes the case when the capture is unset. Avoid adding\n  PCRE2_UNSET to match_data->subject because it overflows, even though with\n  zero size calling memcpy() is harmless. */\n\n  if (size != 0) memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size));\n  *listp++ = sp;\n  if (lensp != NULL) *lensp++ = size;\n  sp += size;\n  *sp++ = 0;\n  }\n\n*listp = NULL;\nreturn 0;\n}\n\n\n\n/*************************************************\n*   Free memory obtained by substring_list_get   *\n*************************************************/\n\n/*\nArgument:     the result of a previous pcre2_substring_list_get()\nReturns:      nothing\n*/\n\nPCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION\npcre2_substring_list_free(PCRE2_UCHAR **list)\n{\nif (list != NULL)\n  {\n  pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl));\n  memctl->free(memctl, memctl->memory_data);\n  }\n}\n\n\n\n/*************************************************\n*     Find (multiple) entries for named string   *\n*************************************************/\n\n/* This function scans the nametable for a given name, using binary chop. It\nreturns either two pointers to the entries in the table, or, if no pointers are\ngiven, the number of a unique group with the given name. If duplicate names are\npermitted, and the name is not unique, an error is generated.\n\nArguments:\n  code        the compiled regex\n  stringname  the name whose entries required\n  firstptr    where to put the pointer to the first entry\n  lastptr     where to put the pointer to the last entry\n\nReturns:      PCRE2_ERROR_NOSUBSTRING if the name is not found\n              otherwise, if firstptr and lastptr are NULL:\n                a group number for a unique substring\n                else PCRE2_ERROR_NOUNIQUESUBSTRING\n              otherwise:\n                the length of each entry, having set firstptr and lastptr\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname,\n  PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr)\n{\nuint16_t bot = 0;\nuint16_t top = code->name_count;\nuint16_t entrysize = code->name_entry_size;\nPCRE2_SPTR nametable = (PCRE2_SPTR)((const char *)code + sizeof(pcre2_real_code));\n\nwhile (top > bot)\n  {\n  uint16_t mid = (top + bot) / 2;\n  PCRE2_SPTR entry = nametable + entrysize*mid;\n  int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE);\n  if (c == 0)\n    {\n    PCRE2_SPTR first;\n    PCRE2_SPTR last;\n    PCRE2_SPTR lastentry;\n    lastentry = nametable + entrysize * (code->name_count - 1);\n    first = last = entry;\n    while (first > nametable)\n      {\n      if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break;\n      first -= entrysize;\n      }\n    while (last < lastentry)\n      {\n      if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break;\n      last += entrysize;\n      }\n    if (firstptr == NULL) return (first == last)?\n      (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING;\n    *firstptr = first;\n    *lastptr = last;\n    return entrysize;\n    }\n  if (c > 0) bot = mid + 1; else top = mid;\n  }\n\nreturn PCRE2_ERROR_NOSUBSTRING;\n}\n\n\n/*************************************************\n*           Find number for named string         *\n*************************************************/\n\n/* This function is a convenience wrapper for pcre2_substring_nametable_scan()\nwhen it is known that names are unique. If there are duplicate names, it is not\ndefined which number is returned.\n\nArguments:\n  code        the compiled regex\n  stringname  the name whose number is required\n\nReturns:      the number of the named parenthesis, or a negative number\n                PCRE2_ERROR_NOSUBSTRING if not found\n                PCRE2_ERROR_NOUNIQUESUBSTRING if not unique\n*/\n\nPCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION\npcre2_substring_number_from_name(const pcre2_code *code,\n  PCRE2_SPTR stringname)\n{\nreturn pcre2_substring_nametable_scan(code, stringname, NULL, NULL);\n}\n\n/* End of pcre2_substring.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_tables.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains some fixed tables that are used by more than one of the\nPCRE2 code modules. The tables are also #included by the pcre2test program,\nwhich uses macros to change their names from _pcre2_xxx to xxxx, thereby\navoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is\ndefined. */\n\n\n#if !defined(PCRE2_PCRE2TEST) && !defined(PCRE2_DFTABLES) && \\\n    !defined(PCRE2_PCRE2POSIX) /* We're compiling the library */\n#include \"pcre2_internal.h\"\n#endif\n\n\n/* Utility macros */\n#define ARR_SIZE(x) sizeof(x)/sizeof(x[0])\n\n\n#if !defined(PCRE2_PCRE2TEST) && !defined(PCRE2_DFTABLES) && \\\n    !defined(PCRE2_PCRE2POSIX)\n\n/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that\nthe definition is next to the definition of the opcodes in pcre2_internal.h.\nThis is mode-dependent, so it is skipped when this file is included by\npcre2test. */\n\nconst uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS };\n\n/* Tables of horizontal and vertical whitespace characters, suitable for\nadding to classes. */\n\nconst uint32_t PRIV(hspace_list)[] = { HSPACE_LIST };\nconst uint32_t PRIV(vspace_list)[] = { VSPACE_LIST };\n\n#endif /* !PCRE2_PCRE2TEST && !PCRE2_DFTABLES && !PCRE2_PCRE2POSIX */\n\n\n#if !defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX)\n\n/* These tables are the pairs of delimiters that are valid for callout string\narguments. For each starting delimiter there must be a matching ending\ndelimiter, which in fact is different only for bracket-like delimiters. */\n\nconst uint32_t PRIV(callout_start_delims)[] = {\n  CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,\n  CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,\n  CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 };\n\nconst uint32_t PRIV(callout_end_delims[]) = {\n  CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,\n  CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,\n  CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 };\n\n#endif /* !PCRE2_DFTABLES && !PCRE2_PCRE2POSIX */\n\n\n/*************************************************\n*           Tables for UTF-8 support             *\n*************************************************/\n\n/* These tables are required by pcre2test in 16- or 32-bit mode, as well\nas for the library in 8-bit mode, because pcre2test uses UTF-8 internally for\nhandling wide characters. */\n\n#if defined PCRE2_PCRE2TEST || \\\n    (!defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX) && \\\n     defined SUPPORT_UNICODE && \\\n     defined PCRE2_CODE_UNIT_WIDTH && \\\n     PCRE2_CODE_UNIT_WIDTH == 8)\n\n/* These are the breakpoints for different numbers of bytes in a UTF-8\ncharacter. */\n\nconst int PRIV(utf8_table1)[] =\n  { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff };\n\nconst unsigned PRIV(utf8_table1_size) = ARR_SIZE(PRIV(utf8_table1));\n\n/* These are the indicator bits and the mask for the data bits to set in the\nfirst byte of a character, indexed by the number of additional bytes. */\n\nconst int PRIV(utf8_table2)[] = { 0,    0xc0, 0xe0, 0xf0, 0xf8, 0xfc };\nconst int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01 };\n\n/* Table of the number of extra bytes, indexed by the first byte masked with\n0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */\n\nconst uint8_t PRIV(utf8_table4)[] = {\n  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };\n\n#endif /* UTF-8 support needed */\n\n/* Tables concerned with Unicode properties are relevant only when Unicode\nsupport is enabled. See also the pcre2_ucptables_inc.h file, which is generated by\na Python script from Unicode data files. */\n\n#if !defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX) && \\\n    defined(SUPPORT_UNICODE)\n\n/* Table to translate from particular type value to the general value. */\n\nconst uint32_t PRIV(ucp_gentype)[] = {\n  ucp_C, ucp_C, ucp_C, ucp_C, ucp_C,  /* Cc, Cf, Cn, Co, Cs */\n  ucp_L, ucp_L, ucp_L, ucp_L, ucp_L,  /* Ll, Lu, Lm, Lo, Lt */\n  ucp_M, ucp_M, ucp_M,                /* Mc, Me, Mn */\n  ucp_N, ucp_N, ucp_N,                /* Nd, Nl, No */\n  ucp_P, ucp_P, ucp_P, ucp_P, ucp_P,  /* Pc, Pd, Pe, Pf, Pi */\n  ucp_P, ucp_P,                       /* Ps, Po */\n  ucp_S, ucp_S, ucp_S, ucp_S,         /* Sc, Sk, Sm, So */\n  ucp_Z, ucp_Z, ucp_Z                 /* Zl, Zp, Zs */\n};\n\n/* This table encodes the rules for finding the end of an extended grapheme\ncluster. Every code point has a grapheme break property which is one of the\nucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions\n10 and 11. The 2-dimensional table is indexed by the properties of two adjacent\ncode points. The left property selects a word from the table, and the right\nproperty selects a bit from that word like this:\n\n  PRIV(ucp_gbtable)[left-property] & (1u << right-property)\n\nThe value is non-zero if a grapheme break is NOT permitted between the relevant\ntwo code points. The breaking rules are as follows:\n\n1. Break at the start and end of text (pretty obviously).\n\n2. Do not break between a CR and LF; otherwise, break before and after\n   controls.\n\n3. Do not break Hangul syllable sequences, the rules for which are:\n\n    L may be followed by L, V, LV or LVT\n    LV or V may be followed by V or T\n    LVT or T may be followed by T\n\n4. Do not break before extending characters or zero-width-joiner (ZWJ).\n\nThe following rules are only for extended grapheme clusters (but that's what we\nare implementing).\n\n5. Do not break before SpacingMarks.\n\n6. Do not break after Prepend characters.\n\n7. Do not break within emoji modifier sequences or emoji zwj sequences. That\n   is, do not break between characters with the Extended_Pictographic property\n   if a ZWJ intervenes. Extend characters are allowed between the characters;\n   this cannot be represented in this table, the code has to deal with it.\n\n8. Do not break within emoji flag sequences. That is, do not break between\n   regional indicator (RI) symbols if there are an odd number of RI characters\n   before the break point. This table encodes \"join RI characters\"; the code\n   has to deal with checking for previous adjoining RIs.\n\n9. Otherwise, break everywhere.\n*/\n\n#define ESZ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbZWJ)\n\nconst uint32_t PRIV(ucp_gbtable)[] = {\n   (1u<<ucp_gbLF),                                      /*  0 CR */\n   0,                                                   /*  1 LF */\n   0,                                                   /*  2 Control */\n   ESZ,                                                 /*  3 Extend */\n   ESZ|(1u<<ucp_gbPrepend)|                             /*  4 Prepend */\n       (1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbT)|\n       (1u<<ucp_gbLV)|(1u<<ucp_gbLVT)|(1u<<ucp_gbOther)|\n       (1u<<ucp_gbRegional_Indicator),\n   ESZ,                                                 /*  5 SpacingMark */\n   ESZ|(1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbLV)|      /*  6 L */\n       (1u<<ucp_gbLVT),\n   ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT),                     /*  7 V */\n   ESZ|(1u<<ucp_gbT),                                   /*  8 T */\n   ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT),                     /*  9 LV */\n   ESZ|(1u<<ucp_gbT),                                   /* 10 LVT */\n   (1u<<ucp_gbRegional_Indicator),                      /* 11 Regional Indicator */\n   ESZ,                                                 /* 12 Other */\n   ESZ|(1u<<ucp_gbExtended_Pictographic),               /* 13 ZWJ */\n   ESZ                                                  /* 14 Extended Pictographic */\n};\n\n#undef ESZ\n\n#ifdef SUPPORT_JIT\n/* This table reverses PRIV(ucp_gentype). We can save the cost\nof a memory load. */\n\nconst int PRIV(ucp_typerange)[] = {\n  ucp_Cc, ucp_Cs,\n  ucp_Ll, ucp_Lu,\n  ucp_Mc, ucp_Mn,\n  ucp_Nd, ucp_No,\n  ucp_Pc, ucp_Ps,\n  ucp_Sc, ucp_So,\n  ucp_Zl, ucp_Zs,\n};\n#endif /* SUPPORT_JIT */\n\n/* Finally, include the tables that are auto-generated from the Unicode data\nfiles. */\n\n#include \"pcre2_ucptables_inc.h\"\n\n#endif /* Unicode support needed */\n\n\n/*************************************************\n*          Tables for EBCDIC support             *\n*************************************************/\n\n#if defined(EBCDIC) && \\\n  (defined(PCRE2_PCRE2TEST) || defined(PCRE2_DFTABLES) || 'a' != 0x81)\n\nconst uint8_t PRIV(ebcdic_1047_to_ascii)[256] = {\n  0x00,0x01,0x02,0x03,0x9c,0x09,0x86,0x7f,0x97,0x8d,0x8e,0x0b,0x0c,0x0d,0x0e,0x0f,\n#ifdef EBCDIC_NL25\n  0x10,0x11,0x12,0x13,0x9d,0x85,0x08,0x87,0x18,0x19,0x92,0x8f,0x1c,0x1d,0x1e,0x1f,\n  0x80,0x81,0x82,0x83,0x84,0x0a,0x17,0x1b,0x88,0x89,0x8a,0x8b,0x8c,0x05,0x06,0x07,\n#else\n  0x10,0x11,0x12,0x13,0x9d,0x0a,0x08,0x87,0x18,0x19,0x92,0x8f,0x1c,0x1d,0x1e,0x1f,\n  0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1b,0x88,0x89,0x8a,0x8b,0x8c,0x05,0x06,0x07,\n#endif\n  0x90,0x91,0x16,0x93,0x94,0x95,0x96,0x04,0x98,0x99,0x9a,0x9b,0x14,0x15,0x9e,0x1a,\n  0x20,0xa0,0xe2,0xe4,0xe0,0xe1,0xe3,0xe5,0xe7,0xf1,0xa2,0x2e,0x3c,0x28,0x2b,0x7c,\n  0x26,0xe9,0xea,0xeb,0xe8,0xed,0xee,0xef,0xec,0xdf,0x21,0x24,0x2a,0x29,0x3b,0x5e,\n  0x2d,0x2f,0xc2,0xc4,0xc0,0xc1,0xc3,0xc5,0xc7,0xd1,0xa6,0x2c,0x25,0x5f,0x3e,0x3f,\n  0xf8,0xc9,0xca,0xcb,0xc8,0xcd,0xce,0xcf,0xcc,0x60,0x3a,0x23,0x40,0x27,0x3d,0x22,\n  0xd8,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0xab,0xbb,0xf0,0xfd,0xfe,0xb1,\n  0xb0,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0xaa,0xba,0xe6,0xb8,0xc6,0xa4,\n  0xb5,0x7e,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0xa1,0xbf,0xd0,0x5b,0xde,0xae,\n  0xac,0xa3,0xa5,0xb7,0xa9,0xa7,0xb6,0xbc,0xbd,0xbe,0xdd,0xa8,0xaf,0x5d,0xb4,0xd7,\n  0x7b,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0xad,0xf4,0xf6,0xf2,0xf3,0xf5,\n  0x7d,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xb9,0xfb,0xfc,0xf9,0xfa,0xff,\n  0x5c,0xf7,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0xb2,0xd4,0xd6,0xd2,0xd3,0xd5,\n  0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xb3,0xdb,0xdc,0xd9,0xda,0x9f,\n};\n\nconst uint8_t PRIV(ascii_to_ebcdic_1047)[256] = {\n#ifdef EBCDIC_NL25\n  0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f,0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,\n#else\n  0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f,0x16,0x05,0x15,0x0b,0x0c,0x0d,0x0e,0x0f,\n#endif\n  0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26,0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,\n  0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d,0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,\n  0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,\n  0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,\n  0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xad,0xe0,0xbd,0x5f,0x6d,\n  0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,\n  0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,\n#ifdef EBCDIC_NL25\n  0x20,0x21,0x22,0x23,0x24,0x15,0x06,0x17,0x28,0x29,0x2a,0x2b,0x2c,0x09,0x0a,0x1b,\n#else\n  0x20,0x21,0x22,0x23,0x24,0x25,0x06,0x17,0x28,0x29,0x2a,0x2b,0x2c,0x09,0x0a,0x1b,\n#endif\n  0x30,0x31,0x1a,0x33,0x34,0x35,0x36,0x08,0x38,0x39,0x3a,0x3b,0x04,0x14,0x3e,0xff,\n  0x41,0xaa,0x4a,0xb1,0x9f,0xb2,0x6a,0xb5,0xbb,0xb4,0x9a,0x8a,0xb0,0xca,0xaf,0xbc,\n  0x90,0x8f,0xea,0xfa,0xbe,0xa0,0xb6,0xb3,0x9d,0xda,0x9b,0x8b,0xb7,0xb8,0xb9,0xab,\n  0x64,0x65,0x62,0x66,0x63,0x67,0x9e,0x68,0x74,0x71,0x72,0x73,0x78,0x75,0x76,0x77,\n  0xac,0x69,0xed,0xee,0xeb,0xef,0xec,0xbf,0x80,0xfd,0xfe,0xfb,0xfc,0xba,0xae,0x59,\n  0x44,0x45,0x42,0x46,0x43,0x47,0x9c,0x48,0x54,0x51,0x52,0x53,0x58,0x55,0x56,0x57,\n  0x8c,0x49,0xcd,0xce,0xcb,0xcf,0xcc,0xe1,0x70,0xdd,0xde,0xdb,0xdc,0x8d,0x8e,0xdf,\n};\n\n#endif /* EBCDIC support needed */\n\n/* End of pcre2_tables.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_ucd.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2022 University of Cambridge\n\nThis module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!\nInstead, modify the maint/GenerateUcd.py script and run it to generate\na new version of this code.\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This file contains tables of Unicode properties that are extracted from\nUnicode data files. See the comments at the start of maint/GenerateUcd.py for\ndetails.\n\nAs well as being part of the PCRE2 library, this file is #included by the\npcre2test program, which redefines the PRIV macro to change table names from\n_pcre2_xxx to xxxx, thereby avoiding name clashes with the library. At present,\njust one of these tables is actually needed. When compiling the library, some\nheaders are needed. */\n\n\n#ifndef PCRE2_PCRE2TEST\n#include \"pcre2_internal.h\"\n#endif /* PCRE2_PCRE2TEST */\n\n\n\n/* The tables herein are needed only when UCP support is built, and in PCRE2\nthat happens automatically with UTF support. This module should not be\nreferenced otherwise, so it should not matter whether it is compiled or not.\nHowever a comment was received about space saving - maybe the guy linked all\nthe modules rather than using a library - so we include a condition to cut out\nthe tables when not needed. But don't leave a totally empty module because some\ncompilers barf at that. Instead, just supply some small dummy tables. */\n\n#ifndef SUPPORT_UNICODE\nconst ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0}};\nconst uint16_t PRIV(ucd_stage1)[] = {0};\nconst uint16_t PRIV(ucd_stage2)[] = {0};\nconst uint32_t PRIV(ucd_caseless_sets)[] = {0};\nconst uint32_t PRIV(ucd_nocase_ranges)[] = {0};\nconst uint32_t PRIV(ucd_nocase_ranges_size) = 0;\n#else\n\n/* Total size: 116564 bytes, block size: 128. */\n\nconst char *PRIV(unicode_version) = \"16.0.0\";\n\n/* When recompiling tables with a new Unicode version, please check the types\nin this structure definition with those in pcre2_internal.h (the actual field\nnames will be different).\n\ntypedef struct {\nuint8_t property_0;\nuint8_t property_1;\nuint8_t property_2;\nuint8_t property_3;\nint32_t property_4;\nuint16_t property_5;\nuint16_t property_6;\n} ucd_record;\n*/\n\n/* If the 32-bit library is run in non-32-bit mode, character values greater\nthan 0x10ffff may be encountered. For these we set up a special record. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nconst ucd_record PRIV(dummy_ucd_record)[] = {{\n  ucp_Unknown,    /* script */\n  ucp_Cn,         /* type unassigned */\n  ucp_gbOther,    /* grapheme break property */\n  0,              /* case set */\n  0,              /* other case */\n  0 | (ucp_bidiL << UCD_BIDICLASS_SHIFT), /* script extension and bidi class */\n  0,              /* bool properties offset */\n  }};\n#endif\n\n/* This table contains lists of characters that are caseless sets of\nmore than one character. Each list is terminated by NOTACHAR. */\n\nconst uint32_t PRIV(ucd_caseless_sets)[] = {\n  NOTACHAR,\n  0x0053,  0x0073,  0x017f,  NOTACHAR,\n  0x01c4,  0x01c5,  0x01c6,  NOTACHAR,\n  0x01c7,  0x01c8,  0x01c9,  NOTACHAR,\n  0x01ca,  0x01cb,  0x01cc,  NOTACHAR,\n  0x01f1,  0x01f2,  0x01f3,  NOTACHAR,\n  0x0345,  0x0399,  0x03b9,  0x1fbe,  NOTACHAR,\n  0x00b5,  0x039c,  0x03bc,  NOTACHAR,\n  0x03a3,  0x03c2,  0x03c3,  NOTACHAR,\n  0x0392,  0x03b2,  0x03d0,  NOTACHAR,\n  0x0398,  0x03b8,  0x03d1,  0x03f4,  NOTACHAR,\n  0x03a6,  0x03c6,  0x03d5,  NOTACHAR,\n  0x03a0,  0x03c0,  0x03d6,  NOTACHAR,\n  0x039a,  0x03ba,  0x03f0,  NOTACHAR,\n  0x03a1,  0x03c1,  0x03f1,  NOTACHAR,\n  0x0395,  0x03b5,  0x03f5,  NOTACHAR,\n  0x0412,  0x0432,  0x1c80,  NOTACHAR,\n  0x0414,  0x0434,  0x1c81,  NOTACHAR,\n  0x041e,  0x043e,  0x1c82,  NOTACHAR,\n  0x0421,  0x0441,  0x1c83,  NOTACHAR,\n  0x0422,  0x0442,  0x1c84,  0x1c85,  NOTACHAR,\n  0x042a,  0x044a,  0x1c86,  NOTACHAR,\n  0x0462,  0x0463,  0x1c87,  NOTACHAR,\n  0x1e60,  0x1e61,  0x1e9b,  NOTACHAR,\n  0x03a9,  0x03c9,  0x2126,  NOTACHAR,\n  0x004b,  0x006b,  0x212a,  NOTACHAR,\n  0x00c5,  0x00e5,  0x212b,  NOTACHAR,\n  0x1c88,  0xa64a,  0xa64b,  NOTACHAR,\n  0x0069,  0x0130,  NOTACHAR,\n  0x0049,  0x0131,  NOTACHAR,\n};\n\n/* This is the index, within ucd_caseless_sets, of the additional\nTurkish case-equivalences. The dotted I ones are this offset; the\ndotless I are +3 from here. */\n\nconst uint32_t PRIV(ucd_turkish_dotted_i_caseset) = 112;\n\n/* When #included in pcre2test, we don't need the table of digit sets, nor the\nthe large main UCD tables. */\n\n#ifndef PCRE2_PCRE2TEST\n\n/* This table contains character ranges, where the characters in the range have\nno other case. Both start and end values are excluded from the range. */\n\nconst uint32_t PRIV(ucd_nocase_ranges)[] = {\n  0x0000, 0x0041, /* 64 */\n  0x007a, 0x00b5, /* 58 */\n  0x00b5, 0x00c0, /* 10 */\n  0x0292, 0x029d, /* 10 */\n  0x029e, 0x0345, /* 166 */\n  0x0345, 0x0370, /* 42 */\n  0x0481, 0x048a, /* 8 */\n  0x0556, 0x0561, /* 10 */\n  0x0586, 0x10a0, /* 2841 */\n  0x10ff, 0x13a0, /* 672 */\n  0x13fd, 0x1c80, /* 2178 */\n  0x1cbf, 0x1d79, /* 185 */\n  0x1d7d, 0x1d8e, /* 16 */\n  0x1d8e, 0x1e00, /* 113 */\n  0x1ffc, 0x2126, /* 297 */\n  0x2132, 0x214e, /* 27 */\n  0x214e, 0x2160, /* 17 */\n  0x2184, 0x24b6, /* 817 */\n  0x24e9, 0x2c00, /* 1814 */\n  0x2cf3, 0x2d00, /* 12 */\n  0x2d2d, 0xa640, /* 30994 */\n  0xa66d, 0xa680, /* 18 */\n  0xa69b, 0xa722, /* 134 */\n  0xa76f, 0xa779, /* 9 */\n  0xa7dc, 0xa7f5, /* 24 */\n  0xa7f6, 0xab53, /* 860 */\n  0xab53, 0xab70, /* 28 */\n  0xabbf, 0xfb05, /* 20293 */\n  0xfb06, 0xff21, /* 1050 */\n  0xff5a, 0x10400, /* 1189 */\n  0x1044f, 0x104b0, /* 96 */\n  0x104fb, 0x10570, /* 116 */\n  0x105bc, 0x10c80, /* 1731 */\n  0x10cb2, 0x10cc0, /* 13 */\n  0x10cf2, 0x10d50, /* 93 */\n  0x10d65, 0x10d70, /* 10 */\n  0x10d85, 0x118a0, /* 2842 */\n  0x118df, 0x16e40, /* 21856 */\n  0x16e7f, 0x1e900, /* 31360 */\n  0x1e943, 0x110000, /* 988860 */\n  0xffffffff, 0xffffffff /* terminator */\n};\n\n/* Total: 1110933 characters. */\nconst uint32_t PRIV(ucd_nocase_ranges_size) = 80;\n\n/* This table lists the code points for the '9' characters in each set of\ndecimal digits. It is used to ensure that all the digits in a script run come\nfrom the same set. */\n\nconst uint32_t PRIV(ucd_digit_sets)[] = {\n  76,  /* Number of subsequent values */\n  0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef,\n  0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9,\n  0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89,\n  0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909,\n  0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x10d49,\n  0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659,\n  0x116c9, 0x116d9, 0x116e3, 0x11739, 0x118e9, 0x11959, 0x11bf9, 0x11c59,\n  0x11d59, 0x11da9, 0x11f59, 0x16139, 0x16a69, 0x16ac9, 0x16b59, 0x16d79,\n  0x1ccf9, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9,\n  0x1e4f9, 0x1e5fa, 0x1e959, 0x1fbf9,\n};\n\n/* This vector is a list of script bitsets for the Script Extension property.\nThe number of 32-bit words in each bitset is #defined in pcre2_ucp.h as\nucd_script_sets_item_size. */\n\nconst uint32_t PRIV(ucd_script_sets)[] = {\n 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x40200003u, 0x00381901u, 0x00100246u, 0x00000000u,\n 0x00040305u, 0x00800000u, 0x08000000u, 0x00000000u,\n 0x20000001u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000001u, 0x00800000u, 0x00000000u, 0x00000000u,\n 0x00040001u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x01000007u, 0x00000840u, 0x80000200u, 0x00000000u,\n 0x01000007u, 0x00000040u, 0x80010000u, 0x00000001u,\n 0x01000005u, 0x00002000u, 0x00000000u, 0x00000000u,\n 0x00040041u, 0x00001000u, 0x80000000u, 0x00000000u,\n 0x01000047u, 0x00002801u, 0x00010001u, 0x00000001u,\n 0x10000001u, 0x00001801u, 0x00000004u, 0x00000000u,\n 0x00000007u, 0x00000000u, 0x00000200u, 0x00000000u,\n 0x00000051u, 0x00002840u, 0x00000202u, 0x00000001u,\n 0x0000005fu, 0x00000041u, 0x00000202u, 0x00000000u,\n 0x00000001u, 0x00002000u, 0x00000000u, 0x00000000u,\n 0x00000041u, 0x00000000u, 0x00000002u, 0x00000000u,\n 0x01000005u, 0x00000000u, 0x00010000u, 0x00000000u,\n 0x01000001u, 0x00000040u, 0x00000000u, 0x00000000u,\n 0x00000001u, 0x00000000u, 0x80000000u, 0x00000000u,\n 0x00800001u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000005u, 0x00000000u, 0x00000000u, 0x00000001u,\n 0x00000003u, 0x00000000u, 0x00000200u, 0x00000001u,\n 0x00000041u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x11000041u, 0x00000000u, 0x00000002u, 0x00000000u,\n 0x01000041u, 0x00000000u, 0x00000002u, 0x00000000u,\n 0x00000041u, 0x00000000u, 0x80000000u, 0x00000000u,\n 0x01000041u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x01040001u, 0x00000001u, 0x80000001u, 0x00000000u,\n 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000001u, 0x00000000u, 0x00010000u, 0x00000000u,\n 0x00000001u, 0x00000000u, 0x00000001u, 0x00000001u,\n 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000002u, 0x00000800u, 0x00000000u, 0x00000000u,\n 0x00000004u, 0x00000000u, 0x00000200u, 0x00000000u,\n 0x00000004u, 0x00001000u, 0x00000000u, 0x00000000u,\n 0x00000005u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00200008u, 0x00001000u, 0x00000000u, 0x00000000u,\n 0x000000e0u, 0x00010000u, 0x11200000u, 0x00000000u,\n 0x000000e0u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x000000e0u, 0x00010000u, 0x11208000u, 0x00000000u,\n 0x00000060u, 0x08000000u, 0x04608480u, 0x00000000u,\n 0x00000060u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x000000a0u, 0x00000000u, 0x01000000u, 0x00000000u,\n 0x00000020u, 0x00000000u, 0x00200000u, 0x00000000u,\n 0x0001ff01u, 0x40000000u, 0x00001008u, 0x00000000u,\n 0x0001ff01u, 0x00000000u, 0x00001008u, 0x00000000u,\n 0x0003ff00u, 0x80004000u, 0x409c1848u, 0x00000000u,\n 0x0003ff00u, 0x80004020u, 0x609c1848u, 0x00000000u,\n 0x00000100u, 0x04000000u, 0x00080040u, 0x00000000u,\n 0x00000200u, 0x10004000u, 0x00000000u, 0x00000000u,\n 0x00000400u, 0x00000000u, 0x00002000u, 0x00000000u,\n 0x00000800u, 0x00000000u, 0x00000010u, 0x00000000u,\n 0x00002000u, 0x00000000u, 0x00000008u, 0x00000000u,\n 0x00008000u, 0x00000000u, 0x00800000u, 0x00000002u,\n 0x00100000u, 0x10000040u, 0x00000000u, 0x00000000u,\n 0x00200001u, 0x00001000u, 0x00000000u, 0x00000000u,\n 0x02000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x0000001eu, 0x00000000u, 0x00000000u,\n 0x04000000u, 0x00008000u, 0x00000000u, 0x00000000u,\n 0x00008300u, 0x00000000u, 0x00000008u, 0x00000000u,\n 0x00000100u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00008100u, 0x00000000u, 0x00000008u, 0x00000000u,\n 0x00000300u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000100u, 0x40000000u, 0x00000000u, 0x00000000u,\n 0x0001f100u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000100u, 0x00000000u, 0x00800000u, 0x00000000u,\n 0x0003d300u, 0x00000000u, 0x00801008u, 0x00000002u,\n 0x00000100u, 0x00000000u, 0x00000008u, 0x00000000u,\n 0x00008100u, 0x00000000u, 0x00000008u, 0x00000002u,\n 0x00000200u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x00000000u, 0x00800000u, 0x00000000u,\n 0x00000045u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000040u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x04000001u, 0x00008000u, 0x00000000u, 0x00000000u,\n 0x00000020u, 0x00000000u, 0x00008000u, 0x00000000u,\n 0x00200000u, 0x020c1000u, 0x00004000u, 0x00000000u,\n 0x00000002u, 0x20080000u, 0x00004000u, 0x00000000u,\n 0x00000101u, 0x00000000u, 0x00000008u, 0x00000000u,\n 0x00000001u, 0x00000800u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x02200000u, 0x00000000u, 0x00000000u,\n 0x00200000u, 0x04780000u, 0x00004000u, 0x00000000u,\n 0x00000000u, 0x00000000u, 0x00000002u, 0x00000000u,\n 0x00000020u, 0x00000000u, 0x0000c000u, 0x00000000u,\n 0x40000000u, 0x00000000u, 0x00020000u, 0x00000000u,\n 0xfc400000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0xfc400000u, 0x00008000u, 0x00000000u, 0x00000000u,\n 0x78400000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x40000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0xfc480000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0xfc480000u, 0x00800000u, 0x00000000u, 0x00000000u,\n 0xf8400000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x60000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x18000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x58000000u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x40000001u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00018d00u, 0xc4000000u, 0x00881950u, 0x00000002u,\n 0x00008d00u, 0xc4000000u, 0x00881950u, 0x00000002u,\n 0x00000d00u, 0x84000000u, 0x00081950u, 0x00000000u,\n 0x00000d00u, 0xc4000000u, 0x00081950u, 0x00000000u,\n 0x00000300u, 0x00000000u, 0x00000000u, 0x00000002u,\n 0x00002100u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00100001u, 0x00020000u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x01000400u, 0x00000000u, 0x00000000u,\n 0x00000020u, 0x00010000u, 0x00000000u, 0x00000000u,\n 0x000000a0u, 0x00000000u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x00000280u, 0x02000000u, 0x00000000u,\n 0x00000000u, 0x00000280u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x00000280u, 0x00000020u, 0x00000000u,\n 0x00000020u, 0x00000800u, 0x00000000u, 0x00000000u,\n 0x00000000u, 0x00000000u, 0x04000080u, 0x00000000u,\n};\n\n/* This vector is a list of bitsets for Boolean properties. The number of\n32_bit words in each bitset is #defined as ucd_boolprop_sets_item_size in\npcre2_ucp.h. */\n\nconst uint32_t PRIV(ucd_boolprop_sets)[] = {\n 0x00000000u, 0x00000000u,\n 0x00000001u, 0x00000000u,\n 0x00000001u, 0x00400800u,\n 0x00800001u, 0x00400800u,\n 0x00800001u, 0x00050400u,\n 0x00800001u, 0x00002400u,\n 0x00830001u, 0x00000400u,\n 0x00800001u, 0x00000400u,\n 0x00800021u, 0x00002400u,\n 0x00800011u, 0x00000400u,\n 0x00800001u, 0x00000480u,\n 0x00800001u, 0x00040400u,\n 0x00801001u, 0x00000400u,\n 0x00800021u, 0x00050400u,\n 0x04830003u, 0x00800001u,\n 0x00800021u, 0x00040400u,\n 0x00800011u, 0x00000480u,\n 0x048003c7u, 0x01900003u,\n 0x008003c5u, 0x01900003u,\n 0x00808021u, 0x00000480u,\n 0x00800001u, 0x00800001u,\n 0x00808021u, 0x00000400u,\n 0x04800d47u, 0x01800043u,\n 0x00800d45u, 0x01800043u,\n 0x00800d45u, 0x01820043u,\n 0x00000000u, 0x00400800u,\n 0x00800000u, 0x00400000u,\n 0x00800000u, 0x00000400u,\n 0x00808020u, 0x00000000u,\n 0x00a10000u, 0x00000400u,\n 0x00800044u, 0x01800043u,\n 0x00800010u, 0x00002400u,\n 0x00800000u, 0x00000480u,\n 0x00002020u, 0x00000000u,\n 0x40800000u, 0x00000000u,\n 0x00800dc4u, 0x01800043u,\n 0x00c08020u, 0x00800001u,\n 0x00800000u, 0x00000000u,\n 0x008003c4u, 0x01900003u,\n 0x00800d44u, 0x01800043u,\n 0x00800d44u, 0x01820043u,\n 0x00804dc4u, 0x01800043u,\n 0x00800004u, 0x01800003u,\n 0x008007c4u, 0x01900003u,\n 0x00800bc4u, 0x01800003u,\n 0x00808064u, 0x01800043u,\n 0x00808064u, 0x01820043u,\n 0x00808024u, 0x01800003u,\n 0x00c08024u, 0x01800003u,\n 0x01008020u, 0x00800009u,\n 0x01008de4u, 0x00800049u,\n 0x01002020u, 0x00800009u,\n 0x01000020u, 0x00800009u,\n 0x01000024u, 0x00800009u,\n 0x00808064u, 0x00000043u,\n 0x00800000u, 0x00040000u,\n 0x00800020u, 0x00840001u,\n 0x00800dc4u, 0x018000c3u,\n 0x00800044u, 0x01900083u,\n 0x00800044u, 0x01900003u,\n 0x008003c4u, 0x01900083u,\n 0x00800000u, 0x00000080u,\n 0x01000020u, 0x00000008u,\n 0x00800020u, 0x00000000u,\n 0x00800000u, 0x00050000u,\n 0x00801000u, 0x00000000u,\n 0x01008024u, 0x00800009u,\n 0x00000020u, 0x00001000u,\n 0x00002028u, 0x00000000u,\n 0x00c00024u, 0x01800003u,\n 0x01000024u, 0x00800109u,\n 0x01008020u, 0x00800109u,\n 0x00800000u, 0x00800001u,\n 0x00804004u, 0x01800003u,\n 0x00800024u, 0x01800003u,\n 0x01000020u, 0x00800109u,\n 0x01008024u, 0x00800109u,\n 0x00800004u, 0x00800001u,\n 0x00800004u, 0x0180000bu,\n 0x03008020u, 0x00800009u,\n 0x01000004u, 0x00800009u,\n 0x01400024u, 0x00800009u,\n 0x01408020u, 0x00800009u,\n 0x00800004u, 0x00800003u,\n 0x03008024u, 0x00800009u,\n 0x00800004u, 0x01800023u,\n 0x00800010u, 0x00000000u,\n 0x00808000u, 0x00800001u,\n 0x01004024u, 0x00800009u,\n 0x00808004u, 0x00800001u,\n 0x00800944u, 0x01800043u,\n 0x00800064u, 0x01800043u,\n 0x00802004u, 0x01800003u,\n 0x00800344u, 0x01900003u,\n 0x03008000u, 0x00800009u,\n 0x00c00000u, 0x00000000u,\n 0x01002020u, 0x00a00009u,\n 0x01000024u, 0x0180000bu,\n 0x01008020u, 0x00000008u,\n 0x01408024u, 0x00800009u,\n 0x00808000u, 0x00000000u,\n 0x00800044u, 0x01820043u,\n 0x00800064u, 0x01820043u,\n 0x01002020u, 0x00800011u,\n 0x00022020u, 0x00800019u,\n 0x00002028u, 0x00000800u,\n 0x00801000u, 0x00000400u,\n 0x00800020u, 0x00002400u,\n 0x00800000u, 0x00002400u,\n 0x00800020u, 0x00050400u,\n 0x00800020u, 0x00000400u,\n 0x00a10000u, 0x00050400u,\n 0x00800000u, 0x00050400u,\n 0x00800000u, 0x00800081u,\n 0x00800010u, 0x00000400u,\n 0x00002020u, 0x00000080u,\n 0x00002000u, 0x00000000u,\n 0x00006020u, 0x00000000u,\n 0x40800000u, 0x00000080u,\n 0x40801000u, 0x00000080u,\n 0x40800010u, 0x00000080u,\n 0x01000020u, 0x00800089u,\n 0x01020020u, 0x00000008u,\n 0x00800044u, 0x018000c3u,\n 0x00800000u, 0x01800083u,\n 0x00a10000u, 0x00000000u,\n 0x00800000u, 0x01800003u,\n 0x00800004u, 0x01800083u,\n 0x00a10044u, 0x01800043u,\n 0x00800044u, 0x018200c3u,\n 0x00a10000u, 0x00000480u,\n 0xc0800000u, 0x00000480u,\n 0x00800010u, 0x00000480u,\n 0x00801000u, 0x00000480u,\n 0x00b10000u, 0x00000400u,\n 0x00804010u, 0x00000400u,\n 0x00a00000u, 0x00000400u,\n 0x00000000u, 0x00000400u,\n 0x008003c4u, 0x00100000u,\n 0x00a103c4u, 0x00100000u,\n 0x00800d44u, 0x00000040u,\n 0x00b10000u, 0x00000480u,\n 0x00a00000u, 0x00000480u,\n 0x00a90000u, 0x00000400u,\n 0x00b90000u, 0x00000400u,\n 0x03000020u, 0x00800009u,\n 0x00808024u, 0x00000400u,\n 0x00800000u, 0x00040400u,\n 0x00800000u, 0x00004000u,\n 0x08800000u, 0x00000000u,\n 0x10800000u, 0x00000000u,\n 0x20800000u, 0x00000000u,\n 0x00800004u, 0x01800007u,\n 0x01008000u, 0x00800009u,\n 0x00a11000u, 0x00000400u,\n 0x00808020u, 0x00000003u,\n 0x00800004u, 0x01880007u,\n 0x00808004u, 0x01800003u,\n 0x00800004u, 0x00000003u,\n 0x00000000u, 0x00000200u,\n 0x01022020u, 0x00a00009u,\n 0x00800000u, 0x00002000u,\n 0x00800020u, 0x00050000u,\n 0x00800020u, 0x00040000u,\n 0x00801000u, 0x00000080u,\n 0x00800010u, 0x00000080u,\n 0x00800020u, 0x00002000u,\n 0x04800000u, 0x00800001u,\n 0x048003c4u, 0x01900003u,\n 0x00808020u, 0x00000080u,\n 0x04800d44u, 0x01800043u,\n 0x00800010u, 0x00002000u,\n 0x01008024u, 0x0080000bu,\n 0x00000020u, 0x00000000u,\n 0x00c00004u, 0x01800003u,\n 0x00c08004u, 0x01800003u,\n 0x01400020u, 0x00800009u,\n 0x01000020u, 0x0080000du,\n 0x01008004u, 0x00800009u,\n 0x01000000u, 0x00800009u,\n 0xc0800000u, 0x00000080u,\n 0x00a00000u, 0x00000000u,\n 0x00b10000u, 0x00000000u,\n 0x00200000u, 0x00000000u,\n 0x00800044u, 0x00100000u,\n 0x00a10044u, 0x00100000u,\n 0x00930000u, 0x00008000u,\n 0x00b90000u, 0x00000000u,\n 0x00a90000u, 0x00000000u,\n 0x00970020u, 0x00000008u,\n 0x00b30000u, 0x00000000u,\n 0x01022020u, 0x00000008u,\n};\n\n/* These are the main two-stage UCD tables. The fields in each record are:\nscript (8 bits), character type (8 bits), grapheme break property (8 bits),\noffset to multichar other cases or zero (8 bits), offset to other case or zero\n(32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed\ninto a 16-bit field, and offset in binary properties table (16 bits). */\n\nconst ucd_record PRIV(ucd_records)[] = { /* 18516 bytes, record size 12 */\n  {    99,      0,      2,      0,      0,   6144,      2, }, /*   0 */\n  {    99,      0,      2,      0,      0,  43008,      4, }, /*   1 */\n  {    99,      0,      1,      0,      0,   4096,      4, }, /*   2 */\n  {    99,      0,      2,      0,      0,  45056,      4, }, /*   3 */\n  {    99,      0,      0,      0,      0,   4096,      4, }, /*   4 */\n  {    99,      0,      2,      0,      0,   4096,      2, }, /*   5 */\n  {    99,      0,      2,      0,      0,  43008,      2, }, /*   6 */\n  {    99,     29,     12,      0,      0,  45056,      6, }, /*   7 */\n  {    99,     21,     12,      0,      0,  28672,      8, }, /*   8 */\n  {    99,     21,     12,      0,      0,  28672,     10, }, /*   9 */\n  {    99,     21,     12,      0,      0,  14336,     12, }, /*  10 */\n  {    99,     23,     12,      0,      0,  14336,     14, }, /*  11 */\n  {    99,     21,     12,      0,      0,  14336,     14, }, /*  12 */\n  {    99,     21,     12,      0,      0,  28672,     14, }, /*  13 */\n  {    99,     21,     12,      0,      0,  28672,     16, }, /*  14 */\n  {    99,     22,     12,      0,      0,  28672,     18, }, /*  15 */\n  {    99,     18,     12,      0,      0,  28672,     18, }, /*  16 */\n  {    99,     21,     12,      0,      0,  28672,     12, }, /*  17 */\n  {    99,     25,     12,      0,      0,  12288,     20, }, /*  18 */\n  {    99,     21,     12,      0,      0,   8192,     22, }, /*  19 */\n  {    99,     17,     12,      0,      0,  12288,     24, }, /*  20 */\n  {    99,     21,     12,      0,      0,   8192,     26, }, /*  21 */\n  {    99,     21,     12,      0,      0,   8192,     14, }, /*  22 */\n  {    99,     13,     12,      0,      0,  10240,     28, }, /*  23 */\n  {    99,     21,     12,      0,      0,   8192,     30, }, /*  24 */\n  {    99,     21,     12,      0,      0,  28672,     22, }, /*  25 */\n  {    99,     25,     12,      0,      0,  28672,     32, }, /*  26 */\n  {    99,     25,     12,      0,      0,  28672,     20, }, /*  27 */\n  {     0,      9,     12,      0,     32,  18432,     34, }, /*  28 */\n  {     0,      9,     12,      0,     32,  18432,     36, }, /*  29 */\n  {     0,      9,     12,    100,     32,  18432,     36, }, /*  30 */\n  {     0,      9,     12,      1,     32,  18432,     36, }, /*  31 */\n  {    99,     24,     12,      0,      0,  28672,     38, }, /*  32 */\n  {    99,     16,     12,      0,      0,  28672,     40, }, /*  33 */\n  {    99,     24,     12,      0,      0,  28672,     42, }, /*  34 */\n  {     0,      5,     12,      0,    -32,  18432,     44, }, /*  35 */\n  {     0,      5,     12,      0,    -32,  18432,     46, }, /*  36 */\n  {     0,      5,     12,      0,    -32,  18432,     48, }, /*  37 */\n  {     0,      5,     12,    100,    -32,  18432,     46, }, /*  38 */\n  {     0,      5,     12,      1,    -32,  18432,     46, }, /*  39 */\n  {    99,      0,      2,      0,      0,   6144,      0, }, /*  40 */\n  {    99,      0,      2,      0,      0,   4096,     50, }, /*  41 */\n  {    99,     29,     12,      0,      0,   8192,     52, }, /*  42 */\n  {    99,     21,     12,      0,      0,  28672,     54, }, /*  43 */\n  {    99,     23,     12,      0,      0,  14336,     54, }, /*  44 */\n  {    99,     26,     12,      0,      0,  28672,     54, }, /*  45 */\n  {    99,     24,     12,      0,      0,  28672,     56, }, /*  46 */\n  {    99,     26,     14,      0,      0,  28672,     58, }, /*  47 */\n  {     0,      7,     12,      0,      0,  18432,     60, }, /*  48 */\n  {    99,     20,     12,      0,      0,  28672,     62, }, /*  49 */\n  {    99,     25,     12,      0,      0,  28672,     64, }, /*  50 */\n  {    99,      1,      2,      0,      0,   6144,     66, }, /*  51 */\n  {    99,     26,     12,      0,      0,  14336,     54, }, /*  52 */\n  {    99,     25,     12,      0,      0,  14336,     64, }, /*  53 */\n  {    99,     15,     12,      0,      0,  10240,     68, }, /*  54 */\n  {    99,      5,     12,     26,    775,  18432,     70, }, /*  55 */\n  {    99,     21,     12,      0,      0,  28676,     72, }, /*  56 */\n  {    99,     19,     12,      0,      0,  28672,     62, }, /*  57 */\n  {    99,     15,     12,      0,      0,  28672,     74, }, /*  58 */\n  {     0,      9,     12,      0,     32,  18432,     76, }, /*  59 */\n  {     0,      9,     12,    104,     32,  18432,     76, }, /*  60 */\n  {     0,      5,     12,      0,   7615,  18432,     70, }, /*  61 */\n  {     0,      5,     12,      0,    -32,  18432,     78, }, /*  62 */\n  {     0,      5,     12,    104,    -32,  18432,     78, }, /*  63 */\n  {     0,      5,     12,      0,    121,  18432,     78, }, /*  64 */\n  {     0,      9,     12,      0,      1,  18432,     76, }, /*  65 */\n  {     0,      5,     12,      0,     -1,  18432,     78, }, /*  66 */\n  {     0,      5,     12,      0,     -1,  18432,     80, }, /*  67 */\n  {     0,      9,     12,      0,      0,  18432,     76, }, /*  68 */\n  {     0,      5,     12,      0,      0,  18432,     78, }, /*  69 */\n  {     0,      5,     12,      0,      0,  18432,     60, }, /*  70 */\n  {     0,      5,     12,      0,      0,  18432,     82, }, /*  71 */\n  {     0,      9,     12,      0,   -121,  18432,     76, }, /*  72 */\n  {     0,      5,     12,      1,      0,  18432,     70, }, /*  73 */\n  {     0,      5,     12,      0,    195,  18432,     78, }, /*  74 */\n  {     0,      9,     12,      0,    210,  18432,     76, }, /*  75 */\n  {     0,      9,     12,      0,    206,  18432,     76, }, /*  76 */\n  {     0,      9,     12,      0,    205,  18432,     76, }, /*  77 */\n  {     0,      9,     12,      0,     79,  18432,     76, }, /*  78 */\n  {     0,      9,     12,      0,    202,  18432,     76, }, /*  79 */\n  {     0,      9,     12,      0,    203,  18432,     76, }, /*  80 */\n  {     0,      9,     12,      0,    207,  18432,     76, }, /*  81 */\n  {     0,      5,     12,      0,     97,  18432,     78, }, /*  82 */\n  {     0,      9,     12,      0,    211,  18432,     76, }, /*  83 */\n  {     0,      9,     12,      0,    209,  18432,     76, }, /*  84 */\n  {     0,      5,     12,      0,    163,  18432,     78, }, /*  85 */\n  {     0,      5,     12,      0,  42561,  18432,     78, }, /*  86 */\n  {     0,      9,     12,      0,    213,  18432,     76, }, /*  87 */\n  {     0,      5,     12,      0,    130,  18432,     78, }, /*  88 */\n  {     0,      9,     12,      0,    214,  18432,     76, }, /*  89 */\n  {     0,      9,     12,      0,    218,  18432,     76, }, /*  90 */\n  {     0,      9,     12,      0,    217,  18432,     76, }, /*  91 */\n  {     0,      9,     12,      0,    219,  18432,     76, }, /*  92 */\n  {     0,      7,     12,      0,      0,  18432,     84, }, /*  93 */\n  {     0,      5,     12,      0,     56,  18432,     78, }, /*  94 */\n  {     0,      9,     12,      5,      2,  18432,     86, }, /*  95 */\n  {     0,      8,     12,      5,      1,  18432,     88, }, /*  96 */\n  {     0,      5,     12,      5,     -2,  18432,     78, }, /*  97 */\n  {     0,      9,     12,      9,      2,  18432,     86, }, /*  98 */\n  {     0,      8,     12,      9,      1,  18432,     88, }, /*  99 */\n  {     0,      5,     12,      9,     -2,  18432,     78, }, /* 100 */\n  {     0,      9,     12,     13,      2,  18432,     86, }, /* 101 */\n  {     0,      8,     12,     13,      1,  18432,     88, }, /* 102 */\n  {     0,      5,     12,     13,     -2,  18432,     78, }, /* 103 */\n  {     0,      5,     12,      0,    -79,  18432,     78, }, /* 104 */\n  {     0,      9,     12,     17,      2,  18432,     86, }, /* 105 */\n  {     0,      8,     12,     17,      1,  18432,     88, }, /* 106 */\n  {     0,      5,     12,     17,     -2,  18432,     78, }, /* 107 */\n  {     0,      9,     12,      0,    -97,  18432,     76, }, /* 108 */\n  {     0,      9,     12,      0,    -56,  18432,     76, }, /* 109 */\n  {     0,      9,     12,      0,   -130,  18432,     76, }, /* 110 */\n  {     0,      9,     12,      0,  10795,  18432,     76, }, /* 111 */\n  {     0,      9,     12,      0,   -163,  18432,     76, }, /* 112 */\n  {     0,      9,     12,      0,  10792,  18432,     76, }, /* 113 */\n  {     0,      5,     12,      0,  10815,  18432,     78, }, /* 114 */\n  {     0,      9,     12,      0,   -195,  18432,     76, }, /* 115 */\n  {     0,      9,     12,      0,     69,  18432,     76, }, /* 116 */\n  {     0,      9,     12,      0,     71,  18432,     76, }, /* 117 */\n  {     0,      5,     12,      0,  10783,  18432,     78, }, /* 118 */\n  {     0,      5,     12,      0,  10780,  18432,     78, }, /* 119 */\n  {     0,      5,     12,      0,  10782,  18432,     78, }, /* 120 */\n  {     0,      5,     12,      0,   -210,  18432,     78, }, /* 121 */\n  {     0,      5,     12,      0,   -206,  18432,     78, }, /* 122 */\n  {     0,      5,     12,      0,   -205,  18432,     78, }, /* 123 */\n  {     0,      5,     12,      0,   -202,  18432,     78, }, /* 124 */\n  {     0,      5,     12,      0,   -203,  18432,     78, }, /* 125 */\n  {     0,      5,     12,      0,  42319,  18432,     78, }, /* 126 */\n  {     0,      5,     12,      0,  42315,  18432,     78, }, /* 127 */\n  {     0,      5,     12,      0,   -207,  18432,     78, }, /* 128 */\n  {     0,      5,     12,      0,  42343,  18432,     78, }, /* 129 */\n  {     0,      5,     12,      0,  42280,  18432,     78, }, /* 130 */\n  {     0,      5,     12,      0,  42308,  18432,     78, }, /* 131 */\n  {     0,      5,     12,      0,   -209,  18432,     80, }, /* 132 */\n  {     0,      5,     12,      0,   -211,  18432,     78, }, /* 133 */\n  {     0,      5,     12,      0,  10743,  18432,     78, }, /* 134 */\n  {     0,      5,     12,      0,  42305,  18432,     78, }, /* 135 */\n  {     0,      5,     12,      0,  10749,  18432,     78, }, /* 136 */\n  {     0,      5,     12,      0,   -213,  18432,     78, }, /* 137 */\n  {     0,      5,     12,      0,   -214,  18432,     78, }, /* 138 */\n  {     0,      5,     12,      0,  10727,  18432,     78, }, /* 139 */\n  {     0,      5,     12,      0,   -218,  18432,     78, }, /* 140 */\n  {     0,      5,     12,      0,  42307,  18432,     78, }, /* 141 */\n  {     0,      5,     12,      0,  42282,  18432,     78, }, /* 142 */\n  {     0,      5,     12,      0,    -69,  18432,     78, }, /* 143 */\n  {     0,      5,     12,      0,   -217,  18432,     78, }, /* 144 */\n  {     0,      5,     12,      0,    -71,  18432,     78, }, /* 145 */\n  {     0,      5,     12,      0,   -219,  18432,     78, }, /* 146 */\n  {     0,      5,     12,      0,  42261,  18432,     80, }, /* 147 */\n  {     0,      5,     12,      0,  42258,  18432,     78, }, /* 148 */\n  {     0,      6,     12,      0,      0,  18432,     90, }, /* 149 */\n  {     0,      6,     12,      0,      0,  18432,     92, }, /* 150 */\n  {    99,      6,     12,      0,      0,  28672,     94, }, /* 151 */\n  {    99,      6,     12,      0,      0,  18432,     94, }, /* 152 */\n  {    99,      6,     12,      0,      0,  18440,     94, }, /* 153 */\n  {    99,      6,     12,      0,      0,  18432,     90, }, /* 154 */\n  {    99,      6,     12,      0,      0,  28684,     94, }, /* 155 */\n  {    99,      6,     12,      0,      0,  28688,     94, }, /* 156 */\n  {    99,      6,     12,      0,      0,  18432,     96, }, /* 157 */\n  {    99,     24,     12,      0,      0,  28692,     56, }, /* 158 */\n  {    99,     24,     12,      0,      0,  28684,     56, }, /* 159 */\n  {    29,     24,     12,      0,      0,  28672,     56, }, /* 160 */\n  {   106,     12,      3,      0,      0,  26648,     98, }, /* 161 */\n  {   106,     12,      3,      0,      0,  26652,     98, }, /* 162 */\n  {   106,     12,      3,      0,      0,  26656,     98, }, /* 163 */\n  {   106,     12,      3,      0,      0,  26660,     98, }, /* 164 */\n  {   106,     12,      3,      0,      0,  26664,     98, }, /* 165 */\n  {   106,     12,      3,      0,      0,  26668,     98, }, /* 166 */\n  {   106,     12,      3,      0,      0,  26672,     98, }, /* 167 */\n  {   106,     12,      3,      0,      0,  26676,     98, }, /* 168 */\n  {   106,     12,      3,      0,      0,  26680,     98, }, /* 169 */\n  {   106,     12,      3,      0,      0,  26684,     98, }, /* 170 */\n  {   106,     12,      3,      0,      0,  26688,     98, }, /* 171 */\n  {   106,     12,      3,      0,      0,  26692,     98, }, /* 172 */\n  {   106,     12,      3,      0,      0,  26696,     98, }, /* 173 */\n  {   106,     12,      3,      0,      0,  26700,     98, }, /* 174 */\n  {   106,     12,      3,      0,      0,  26704,     98, }, /* 175 */\n  {   106,     12,      3,      0,      0,  26624,     98, }, /* 176 */\n  {   106,     12,      3,      0,      0,  26708,     98, }, /* 177 */\n  {   106,     12,      3,      0,      0,  26712,     98, }, /* 178 */\n  {   106,     12,      3,      0,      0,  26716,     98, }, /* 179 */\n  {   106,     12,      3,      0,      0,  26720,     98, }, /* 180 */\n  {   106,     12,      3,      0,      0,  26724,     98, }, /* 181 */\n  {   106,     12,      3,      0,      0,  26728,     98, }, /* 182 */\n  {   106,     12,      3,      0,      0,  26732,     98, }, /* 183 */\n  {   106,     12,      3,      0,      0,  26736,     98, }, /* 184 */\n  {   106,     12,      3,      0,      0,  26740,     98, }, /* 185 */\n  {   106,     12,      3,     21,    116,  26740,    100, }, /* 186 */\n  {   106,     12,      3,      0,      0,  26624,    102, }, /* 187 */\n  {   106,     12,      3,      0,      0,  26744,    104, }, /* 188 */\n  {   106,     12,      3,      0,      0,  26624,    104, }, /* 189 */\n  {   106,     12,      3,      0,      0,  26748,     98, }, /* 190 */\n  {   106,     12,      3,      0,      0,  26752,    106, }, /* 191 */\n  {     1,      9,     12,      0,      1,  18432,     76, }, /* 192 */\n  {     1,      5,     12,      0,     -1,  18432,     78, }, /* 193 */\n  {    99,      6,     12,      0,      0,  28804,     94, }, /* 194 */\n  {     1,     24,     12,      0,      0,  28804,     56, }, /* 195 */\n  {    98,      2,     12,      0,      0,  18432,      0, }, /* 196 */\n  {     1,      6,     12,      0,      0,  18432,    108, }, /* 197 */\n  {     1,      5,     12,      0,    130,  18432,     78, }, /* 198 */\n  {    99,     21,     12,      0,      0,  28672,    110, }, /* 199 */\n  {     1,      9,     12,      0,    116,  18432,     76, }, /* 200 */\n  {     1,     24,     12,      0,      0,  28672,     56, }, /* 201 */\n  {     1,      9,     12,      0,     38,  18432,     76, }, /* 202 */\n  {    99,     21,     12,      0,      0,  28672,    112, }, /* 203 */\n  {     1,      9,     12,      0,     37,  18432,     76, }, /* 204 */\n  {     1,      9,     12,      0,     64,  18432,     76, }, /* 205 */\n  {     1,      9,     12,      0,     63,  18432,     76, }, /* 206 */\n  {     1,      5,     12,      0,   7235,  18432,     78, }, /* 207 */\n  {     1,      9,     12,      0,     32,  18432,     76, }, /* 208 */\n  {     1,      9,     12,     34,     32,  18432,     76, }, /* 209 */\n  {     1,      9,     12,     59,     32,  18432,     76, }, /* 210 */\n  {     1,      9,     12,     38,     32,  18432,     76, }, /* 211 */\n  {     1,      9,     12,     21,     32,  18432,     76, }, /* 212 */\n  {     1,      9,     12,     51,     32,  18432,     76, }, /* 213 */\n  {     1,      9,     12,     26,     32,  18432,     76, }, /* 214 */\n  {     1,      9,     12,     47,     32,  18432,     76, }, /* 215 */\n  {     1,      9,     12,     55,     32,  18432,     76, }, /* 216 */\n  {     1,      9,     12,     30,     32,  18432,     76, }, /* 217 */\n  {     1,      9,     12,     43,     32,  18432,     76, }, /* 218 */\n  {     1,      9,     12,     96,     32,  18432,     76, }, /* 219 */\n  {     1,      5,     12,      0,    -38,  18432,     78, }, /* 220 */\n  {     1,      5,     12,      0,    -37,  18432,     78, }, /* 221 */\n  {     1,      5,     12,      0,   7219,  18432,     78, }, /* 222 */\n  {     1,      5,     12,      0,    -32,  18432,     78, }, /* 223 */\n  {     1,      5,     12,     34,    -32,  18432,     78, }, /* 224 */\n  {     1,      5,     12,     59,    -32,  18432,     78, }, /* 225 */\n  {     1,      5,     12,     38,    -32,  18432,     78, }, /* 226 */\n  {     1,      5,     12,     21,   -116,  18432,     78, }, /* 227 */\n  {     1,      5,     12,     51,    -32,  18432,     78, }, /* 228 */\n  {     1,      5,     12,     26,   -775,  18432,     78, }, /* 229 */\n  {     1,      5,     12,     47,    -32,  18432,     78, }, /* 230 */\n  {     1,      5,     12,     55,    -32,  18432,     78, }, /* 231 */\n  {     1,      5,     12,     30,      1,  18432,     70, }, /* 232 */\n  {     1,      5,     12,     30,    -32,  18432,     78, }, /* 233 */\n  {     1,      5,     12,     43,    -32,  18432,     78, }, /* 234 */\n  {     1,      5,     12,     96,    -32,  18432,     78, }, /* 235 */\n  {     1,      5,     12,      0,    -64,  18432,     78, }, /* 236 */\n  {     1,      5,     12,      0,    -63,  18432,     78, }, /* 237 */\n  {     1,      9,     12,      0,      8,  18432,     76, }, /* 238 */\n  {     1,      5,     12,     34,    -30,  18432,    114, }, /* 239 */\n  {     1,      5,     12,     38,    -25,  18432,    114, }, /* 240 */\n  {     1,      9,     12,      0,      0,  18432,    116, }, /* 241 */\n  {     1,      9,     12,      0,      0,  18432,    118, }, /* 242 */\n  {     1,      5,     12,     43,    -15,  18432,    114, }, /* 243 */\n  {     1,      5,     12,     47,    -22,  18432,     70, }, /* 244 */\n  {     1,      5,     12,      0,     -8,  18432,     78, }, /* 245 */\n  {    43,      9,     12,      0,      1,  18432,     76, }, /* 246 */\n  {    43,      5,     12,      0,     -1,  18432,     78, }, /* 247 */\n  {     1,      5,     12,     51,    -54,  18432,    114, }, /* 248 */\n  {     1,      5,     12,     55,    -48,  18432,    114, }, /* 249 */\n  {     1,      5,     12,      0,      7,  18432,     78, }, /* 250 */\n  {     1,      5,     12,      0,   -116,  18432,     80, }, /* 251 */\n  {     1,      9,     12,     38,    -60,  18432,    120, }, /* 252 */\n  {     1,      5,     12,     59,    -64,  18432,    114, }, /* 253 */\n  {     1,     25,     12,      0,      0,  28672,    122, }, /* 254 */\n  {     1,      9,     12,      0,     -7,  18432,     76, }, /* 255 */\n  {     1,      5,     12,      0,      0,  18432,     60, }, /* 256 */\n  {     1,      9,     12,      0,   -130,  18432,     76, }, /* 257 */\n  {     2,      9,     12,      0,     80,  18432,     76, }, /* 258 */\n  {     2,      9,     12,      0,     32,  18432,     76, }, /* 259 */\n  {     2,      9,     12,     63,     32,  18432,     76, }, /* 260 */\n  {     2,      9,     12,     67,     32,  18432,     76, }, /* 261 */\n  {     2,      9,     12,     71,     32,  18432,     76, }, /* 262 */\n  {     2,      9,     12,     75,     32,  18432,     76, }, /* 263 */\n  {     2,      9,     12,     79,     32,  18432,     76, }, /* 264 */\n  {     2,      9,     12,     84,     32,  18432,     76, }, /* 265 */\n  {     2,      5,     12,      0,    -32,  18432,     78, }, /* 266 */\n  {     2,      5,     12,     63,    -32,  18432,     78, }, /* 267 */\n  {     2,      5,     12,     67,    -32,  18432,     78, }, /* 268 */\n  {     2,      5,     12,     71,    -32,  18432,     78, }, /* 269 */\n  {     2,      5,     12,     75,    -32,  18432,     78, }, /* 270 */\n  {     2,      5,     12,     79,    -32,  18432,     78, }, /* 271 */\n  {     2,      5,     12,     84,    -32,  18432,     78, }, /* 272 */\n  {     2,      5,     12,      0,    -80,  18432,     78, }, /* 273 */\n  {     2,      5,     12,      0,    -80,  18432,     80, }, /* 274 */\n  {     2,      9,     12,      0,      1,  18432,     76, }, /* 275 */\n  {     2,      5,     12,      0,     -1,  18432,     78, }, /* 276 */\n  {     2,      9,     12,     88,      1,  18432,     76, }, /* 277 */\n  {     2,      5,     12,     88,     -1,  18432,     78, }, /* 278 */\n  {     2,     26,     12,      0,      0,  18432,     74, }, /* 279 */\n  {     2,     12,      3,      0,      0,  26760,     98, }, /* 280 */\n  {     2,     12,      3,      0,      0,  26764,     98, }, /* 281 */\n  {   106,     12,      3,      0,      0,  26768,     98, }, /* 282 */\n  {     2,     11,      3,      0,      0,  26624,    124, }, /* 283 */\n  {     2,      9,     12,      0,     15,  18432,     76, }, /* 284 */\n  {     2,      5,     12,      0,    -15,  18432,     78, }, /* 285 */\n  {     3,      9,     12,      0,     48,  18432,     76, }, /* 286 */\n  {     3,      6,     12,      0,      0,  18432,     94, }, /* 287 */\n  {     3,     21,     12,      0,      0,  18432,     74, }, /* 288 */\n  {     3,     21,     12,      0,      0,  18432,    126, }, /* 289 */\n  {     3,      5,     12,      0,      0,  18432,     60, }, /* 290 */\n  {     3,      5,     12,      0,    -48,  18432,     78, }, /* 291 */\n  {     3,      5,     12,      0,      0,  18432,     70, }, /* 292 */\n  {     3,     21,     12,      0,      0,  18580,    128, }, /* 293 */\n  {     3,     17,     12,      0,      0,  28672,    130, }, /* 294 */\n  {     3,     26,     12,      0,      0,  28672,     74, }, /* 295 */\n  {     3,     23,     12,      0,      0,  14336,     74, }, /* 296 */\n  {    98,      2,     12,      0,      0,  34816,      0, }, /* 297 */\n  {     4,     12,      3,      0,      0,  26624,     98, }, /* 298 */\n  {     4,     12,      3,      0,      0,  26624,    104, }, /* 299 */\n  {     4,     12,      3,      0,      0,  26624,    132, }, /* 300 */\n  {     4,     17,     12,      0,      0,  34816,    130, }, /* 301 */\n  {     4,     21,     12,      0,      0,  34816,     74, }, /* 302 */\n  {     4,     21,     12,      0,      0,  34816,    110, }, /* 303 */\n  {     4,     12,      3,      0,      0,  26624,    106, }, /* 304 */\n  {     4,      7,     12,      0,      0,  34816,     84, }, /* 305 */\n  {     4,     21,     12,      0,      0,  34816,    126, }, /* 306 */\n  {     5,      1,      4,      0,      0,   2048,    134, }, /* 307 */\n  {    99,      1,      4,      0,      0,   2048,    134, }, /* 308 */\n  {     5,     25,     12,      0,      0,  28672,    122, }, /* 309 */\n  {     5,     25,     12,      0,      0,      0,    122, }, /* 310 */\n  {     5,     21,     12,      0,      0,  14336,     74, }, /* 311 */\n  {     5,     23,     12,      0,      0,      0,     74, }, /* 312 */\n  {    99,     21,     12,      0,      0,   8344,    110, }, /* 313 */\n  {     5,     21,     12,      0,      0,      0,     74, }, /* 314 */\n  {     5,     26,     12,      0,      0,  28672,     74, }, /* 315 */\n  {     5,     12,      3,      0,      0,  26624,    106, }, /* 316 */\n  {    99,     21,     12,      0,      0,    152,    110, }, /* 317 */\n  {     5,      1,      2,      0,      0,    156,    136, }, /* 318 */\n  {     5,     21,     12,      0,      0,      0,    128, }, /* 319 */\n  {    99,     21,     12,      0,      0,    160,    128, }, /* 320 */\n  {     5,      7,     12,      0,      0,      0,     84, }, /* 321 */\n  {    99,      6,     12,      0,      0,    164,    138, }, /* 322 */\n  {   106,     12,      3,      0,      0,  26792,    132, }, /* 323 */\n  {   106,     12,      3,      0,      0,  26792,    106, }, /* 324 */\n  {   106,     12,      3,      0,      0,  26792,    140, }, /* 325 */\n  {     5,     12,      3,      0,      0,  26624,    132, }, /* 326 */\n  {     5,     12,      3,      0,      0,  26624,    142, }, /* 327 */\n  {     5,     13,     12,      0,      0,   2220,    144, }, /* 328 */\n  {     5,     21,     12,      0,      0,   2048,     74, }, /* 329 */\n  {     5,      7,     12,      0,      0,      0,    146, }, /* 330 */\n  {     5,     21,     12,      0,      0,    176,    128, }, /* 331 */\n  {     5,     12,      3,      0,      0,  26624,    140, }, /* 332 */\n  {     5,     12,      3,      0,      0,  26624,     98, }, /* 333 */\n  {     5,      6,     12,      0,      0,      0,     94, }, /* 334 */\n  {     5,     13,     12,      0,      0,  10240,    144, }, /* 335 */\n  {     5,     26,     12,      0,      0,      0,     74, }, /* 336 */\n  {     6,     21,     12,      0,      0,      0,    128, }, /* 337 */\n  {     6,     21,     12,      0,      0,      0,    110, }, /* 338 */\n  {     6,     21,     12,      0,      0,      0,     74, }, /* 339 */\n  {    98,      2,     12,      0,      0,      0,      0, }, /* 340 */\n  {     6,      1,      4,      0,      0,      0,    134, }, /* 341 */\n  {     6,      7,     12,      0,      0,      0,     84, }, /* 342 */\n  {     6,     12,      3,      0,      0,  26624,    106, }, /* 343 */\n  {     6,     12,      3,      0,      0,  26624,    132, }, /* 344 */\n  {     6,     12,      3,      0,      0,  26624,     98, }, /* 345 */\n  {     7,      7,     12,      0,      0,      0,     84, }, /* 346 */\n  {     7,     12,      3,      0,      0,  26624,    132, }, /* 347 */\n  {    48,     13,     12,      0,      0,  34816,    144, }, /* 348 */\n  {    48,      7,     12,      0,      0,  34816,     84, }, /* 349 */\n  {    48,     12,      3,      0,      0,  26624,     98, }, /* 350 */\n  {    48,      6,     12,      0,      0,  34816,     94, }, /* 351 */\n  {    48,     26,     12,      0,      0,  28672,     74, }, /* 352 */\n  {    48,     21,     12,      0,      0,  28672,     74, }, /* 353 */\n  {    48,     21,     12,      0,      0,  28672,    110, }, /* 354 */\n  {    48,     21,     12,      0,      0,  28672,    128, }, /* 355 */\n  {    48,      6,     12,      0,      0,  34816,    138, }, /* 356 */\n  {    48,     12,      3,      0,      0,  26624,    104, }, /* 357 */\n  {    48,     23,     12,      0,      0,  34816,     74, }, /* 358 */\n  {    54,      7,     12,      0,      0,  34816,     84, }, /* 359 */\n  {    54,     12,      3,      0,      0,  26624,    106, }, /* 360 */\n  {    54,     12,      3,      0,      0,  26624,     98, }, /* 361 */\n  {    54,      6,     12,      0,      0,  34816,    148, }, /* 362 */\n  {    54,     12,      3,      0,      0,  26624,    104, }, /* 363 */\n  {    54,     21,     12,      0,      0,  34816,    110, }, /* 364 */\n  {    54,     21,     12,      0,      0,  34816,     74, }, /* 365 */\n  {    54,     21,     12,      0,      0,  34816,    128, }, /* 366 */\n  {    59,      7,     12,      0,      0,  34816,     84, }, /* 367 */\n  {    59,     12,      3,      0,      0,  26624,    104, }, /* 368 */\n  {    59,     21,     12,      0,      0,  34816,    110, }, /* 369 */\n  {     5,     24,     12,      0,      0,      0,    126, }, /* 370 */\n  {     5,     12,      3,      0,      0,  26624,    150, }, /* 371 */\n  {     5,     12,      3,      0,      0,  26624,    104, }, /* 372 */\n  {     5,     12,      3,      0,      0,  26624,    152, }, /* 373 */\n  {     8,     12,      3,      0,      0,  26624,    106, }, /* 374 */\n  {     8,     10,      5,      0,      0,  18432,    154, }, /* 375 */\n  {     8,      7,     12,      0,      0,  18432,     84, }, /* 376 */\n  {     8,      7,     12,      0,      0,  18432,    156, }, /* 377 */\n  {     8,     12,      3,      0,      0,  26624,     98, }, /* 378 */\n  {     8,     12,      3,      0,      0,  26624,    158, }, /* 379 */\n  {   106,     12,      3,      0,      0,  26804,     98, }, /* 380 */\n  {   106,     12,      3,      0,      0,  26808,     98, }, /* 381 */\n  {    99,     21,     12,      0,      0,  18620,    128, }, /* 382 */\n  {    99,     21,     12,      0,      0,  18624,    128, }, /* 383 */\n  {     8,     13,     12,      0,      0,  18628,    144, }, /* 384 */\n  {     8,     21,     12,      0,      0,  18432,     74, }, /* 385 */\n  {     8,      6,     12,      0,      0,  18432,     94, }, /* 386 */\n  {     9,      7,     12,      0,      0,  18432,     84, }, /* 387 */\n  {     9,     12,      3,      0,      0,  26624,    106, }, /* 388 */\n  {     9,     10,      5,      0,      0,  18432,    154, }, /* 389 */\n  {     9,      7,     12,      0,      0,  18432,    156, }, /* 390 */\n  {     9,     12,      3,      0,      0,  26624,     98, }, /* 391 */\n  {     9,     10,      3,      0,      0,  18432,    160, }, /* 392 */\n  {     9,     12,      3,      0,      0,  26624,    158, }, /* 393 */\n  {     9,     13,     12,      0,      0,  18632,    144, }, /* 394 */\n  {     9,     23,     12,      0,      0,  14336,     74, }, /* 395 */\n  {     9,     15,     12,      0,      0,  18432,     74, }, /* 396 */\n  {     9,     26,     12,      0,      0,  18432,     74, }, /* 397 */\n  {     9,     21,     12,      0,      0,  18432,     74, }, /* 398 */\n  {     9,     12,      3,      0,      0,  26624,    104, }, /* 399 */\n  {    10,     12,      3,      0,      0,  26624,    106, }, /* 400 */\n  {    10,     10,      5,      0,      0,  18432,    154, }, /* 401 */\n  {    10,      7,     12,      0,      0,  18432,     84, }, /* 402 */\n  {    10,     12,      3,      0,      0,  26624,     98, }, /* 403 */\n  {    10,     12,      3,      0,      0,  26624,    158, }, /* 404 */\n  {    10,     13,     12,      0,      0,  18636,    144, }, /* 405 */\n  {    10,     12,      3,      0,      0,  26624,    162, }, /* 406 */\n  {    10,     21,     12,      0,      0,  18432,     74, }, /* 407 */\n  {    11,     12,      3,      0,      0,  26624,    106, }, /* 408 */\n  {    11,     10,      5,      0,      0,  18432,    154, }, /* 409 */\n  {    11,      7,     12,      0,      0,  18432,     84, }, /* 410 */\n  {    11,      7,     12,      0,      0,  18432,    156, }, /* 411 */\n  {    11,     12,      3,      0,      0,  26624,     98, }, /* 412 */\n  {    11,     12,      3,      0,      0,  26624,    158, }, /* 413 */\n  {    11,     13,     12,      0,      0,  18640,    144, }, /* 414 */\n  {    11,     21,     12,      0,      0,  18432,     74, }, /* 415 */\n  {    11,     23,     12,      0,      0,  14336,     74, }, /* 416 */\n  {    11,     12,      3,      0,      0,  26624,    162, }, /* 417 */\n  {    12,     12,      3,      0,      0,  26624,    106, }, /* 418 */\n  {    12,     10,      5,      0,      0,  18432,    154, }, /* 419 */\n  {    12,      7,     12,      0,      0,  18432,     84, }, /* 420 */\n  {    12,      7,     12,      0,      0,  18432,    156, }, /* 421 */\n  {    12,     12,      3,      0,      0,  26624,     98, }, /* 422 */\n  {    12,     10,      3,      0,      0,  18432,    160, }, /* 423 */\n  {    12,     12,      3,      0,      0,  26624,    158, }, /* 424 */\n  {    12,     12,      3,      0,      0,  26624,    164, }, /* 425 */\n  {    12,     13,     12,      0,      0,  18432,    144, }, /* 426 */\n  {    12,     26,     12,      0,      0,  18432,     74, }, /* 427 */\n  {    12,     15,     12,      0,      0,  18432,     74, }, /* 428 */\n  {    13,     12,      3,      0,      0,  26624,    106, }, /* 429 */\n  {    13,      7,     12,      0,      0,  18432,     84, }, /* 430 */\n  {    13,     10,      3,      0,      0,  18432,    160, }, /* 431 */\n  {    13,     10,      5,      0,      0,  18432,    154, }, /* 432 */\n  {    13,     12,      3,      0,      0,  26624,    158, }, /* 433 */\n  {    13,     13,     12,      0,      0,  18644,    144, }, /* 434 */\n  {    13,     15,     12,      0,      0,  18644,     74, }, /* 435 */\n  {    13,     26,     12,      0,      0,  28884,     74, }, /* 436 */\n  {    13,     26,     12,      0,      0,  28672,     74, }, /* 437 */\n  {    13,     23,     12,      0,      0,  14336,     74, }, /* 438 */\n  {    14,     12,      3,      0,      0,  26624,    106, }, /* 439 */\n  {    14,     10,      5,      0,      0,  18432,    154, }, /* 440 */\n  {    14,      7,     12,      0,      0,  18432,     84, }, /* 441 */\n  {    14,      7,     12,      0,      0,  18432,    156, }, /* 442 */\n  {    14,     12,      3,      0,      0,  26624,     98, }, /* 443 */\n  {    14,     12,      3,      0,      0,  26624,    158, }, /* 444 */\n  {    14,     13,     12,      0,      0,  18432,    144, }, /* 445 */\n  {    14,     21,     12,      0,      0,  18432,     74, }, /* 446 */\n  {    14,     15,     12,      0,      0,  28672,     74, }, /* 447 */\n  {    14,     26,     12,      0,      0,  18432,     74, }, /* 448 */\n  {    15,      7,     12,      0,      0,  18432,     84, }, /* 449 */\n  {    15,     12,      3,      0,      0,  26624,    106, }, /* 450 */\n  {    15,     10,      5,      0,      0,  18432,    154, }, /* 451 */\n  {    15,     21,     12,      0,      0,  18432,     74, }, /* 452 */\n  {    15,     12,      3,      0,      0,  26624,     98, }, /* 453 */\n  {    15,     12,      3,      0,      0,  18432,    106, }, /* 454 */\n  {    15,     10,      3,      0,      0,  18432,    160, }, /* 455 */\n  {    15,     12,      3,      0,      0,  26624,    158, }, /* 456 */\n  {    15,     13,     12,      0,      0,  18648,    144, }, /* 457 */\n  {    16,     12,      3,      0,      0,  26624,    106, }, /* 458 */\n  {    16,     10,      5,      0,      0,  18432,    154, }, /* 459 */\n  {    16,      7,     12,      0,      0,  18432,     84, }, /* 460 */\n  {    16,      7,     12,      0,      0,  18432,    156, }, /* 461 */\n  {    16,     12,      3,      0,      0,  26624,    158, }, /* 462 */\n  {    16,     10,      3,      0,      0,  18432,    160, }, /* 463 */\n  {    16,      7,      4,      0,      0,  18432,     84, }, /* 464 */\n  {    16,     26,     12,      0,      0,  18432,     74, }, /* 465 */\n  {    16,     15,     12,      0,      0,  18432,     74, }, /* 466 */\n  {    16,     13,     12,      0,      0,  18432,    144, }, /* 467 */\n  {    17,     12,      3,      0,      0,  26624,    106, }, /* 468 */\n  {    17,     10,      5,      0,      0,  18432,    154, }, /* 469 */\n  {    17,      7,     12,      0,      0,  18432,     84, }, /* 470 */\n  {    17,     12,      3,      0,      0,  26624,    158, }, /* 471 */\n  {    17,     10,      3,      0,      0,  18432,    160, }, /* 472 */\n  {    17,     13,     12,      0,      0,  18432,    144, }, /* 473 */\n  {    17,     21,     12,      0,      0,  18432,     74, }, /* 474 */\n  {    18,      7,     12,      0,      0,  18432,     84, }, /* 475 */\n  {    18,     12,      3,      0,      0,  26624,    106, }, /* 476 */\n  {    18,      7,      5,      0,      0,  18432,    166, }, /* 477 */\n  {    18,     12,      3,      0,      0,  26624,    168, }, /* 478 */\n  {    99,     23,     12,      0,      0,  14336,     74, }, /* 479 */\n  {    18,      7,     12,      0,      0,  18432,    170, }, /* 480 */\n  {    18,      6,     12,      0,      0,  18432,    138, }, /* 481 */\n  {    18,     12,      3,      0,      0,  26624,     98, }, /* 482 */\n  {    18,     21,     12,      0,      0,  18432,     74, }, /* 483 */\n  {    18,     13,     12,      0,      0,  18432,    144, }, /* 484 */\n  {    18,     21,     12,      0,      0,  18432,    110, }, /* 485 */\n  {   100,      7,     12,      0,      0,  18432,     84, }, /* 486 */\n  {   100,     12,      3,      0,      0,  26624,    106, }, /* 487 */\n  {   100,      7,      5,      0,      0,  18432,    166, }, /* 488 */\n  {   100,     12,      3,      0,      0,  26624,    158, }, /* 489 */\n  {   100,      7,     12,      0,      0,  18432,    170, }, /* 490 */\n  {   100,      6,     12,      0,      0,  18432,    138, }, /* 491 */\n  {   100,     12,      3,      0,      0,  26624,     98, }, /* 492 */\n  {   100,     12,      3,      0,      0,  26624,    104, }, /* 493 */\n  {   100,     13,     12,      0,      0,  18432,    144, }, /* 494 */\n  {    19,      7,     12,      0,      0,  18432,     84, }, /* 495 */\n  {    19,     26,     12,      0,      0,  18432,     74, }, /* 496 */\n  {    19,     21,     12,      0,      0,  18432,     74, }, /* 497 */\n  {    19,     21,     12,      0,      0,  18432,    110, }, /* 498 */\n  {    19,     12,      3,      0,      0,  26624,     98, }, /* 499 */\n  {    19,     13,     12,      0,      0,  18432,    144, }, /* 500 */\n  {    19,     15,     12,      0,      0,  18432,     74, }, /* 501 */\n  {    19,     22,     12,      0,      0,  28672,    172, }, /* 502 */\n  {    19,     18,     12,      0,      0,  28672,    172, }, /* 503 */\n  {    19,     10,      5,      0,      0,  18432,    174, }, /* 504 */\n  {    19,     12,      3,      0,      0,  26624,    106, }, /* 505 */\n  {    19,     12,      3,      0,      0,  26624,    176, }, /* 506 */\n  {    19,     10,      5,      0,      0,  18432,    154, }, /* 507 */\n  {    19,     12,      3,      0,      0,  26624,    132, }, /* 508 */\n  {    19,     12,      3,      0,      0,  26624,    158, }, /* 509 */\n  {    99,     26,     12,      0,      0,  18432,     74, }, /* 510 */\n  {    20,      7,     12,      0,      0,  18432,     84, }, /* 511 */\n  {    20,     10,     12,      0,      0,  18432,    154, }, /* 512 */\n  {    20,     12,      3,      0,      0,  26624,    106, }, /* 513 */\n  {    20,     10,      5,      0,      0,  18432,    154, }, /* 514 */\n  {    20,     12,      3,      0,      0,  26624,     98, }, /* 515 */\n  {    20,     12,      3,      0,      0,  26624,    158, }, /* 516 */\n  {    20,     13,     12,      0,      0,  18652,    144, }, /* 517 */\n  {    20,     21,     12,      0,      0,  18432,    128, }, /* 518 */\n  {    20,     21,     12,      0,      0,  18432,     74, }, /* 519 */\n  {    20,     10,     12,      0,      0,  18432,    178, }, /* 520 */\n  {    20,     12,      3,      0,      0,  26624,    132, }, /* 521 */\n  {    20,     13,     12,      0,      0,  18432,    144, }, /* 522 */\n  {    20,     26,     12,      0,      0,  18432,     74, }, /* 523 */\n  {    21,      9,     12,      0,   7264,  18432,     76, }, /* 524 */\n  {    21,      5,     12,      0,   3008,  18432,    180, }, /* 525 */\n  {    99,     21,     12,      0,      0,  18656,     74, }, /* 526 */\n  {    21,      6,     12,      0,      0,  18432,    182, }, /* 527 */\n  {    22,      7,      6,      0,      0,  18432,     84, }, /* 528 */\n  {    22,      7,      6,      0,      0,  18432,    184, }, /* 529 */\n  {    22,      7,      7,      0,      0,  18432,    184, }, /* 530 */\n  {    22,      7,      7,      0,      0,  18432,     84, }, /* 531 */\n  {    22,      7,      8,      0,      0,  18432,     84, }, /* 532 */\n  {    23,      7,     12,      0,      0,  18432,     84, }, /* 533 */\n  {    23,     12,      3,      0,      0,  26624,     98, }, /* 534 */\n  {    23,     21,     12,      0,      0,  18432,     74, }, /* 535 */\n  {    23,     21,     12,      0,      0,  18432,    110, }, /* 536 */\n  {    23,     21,     12,      0,      0,  18432,    128, }, /* 537 */\n  {    23,     15,     12,      0,      0,  18432,    144, }, /* 538 */\n  {    23,     15,     12,      0,      0,  18432,     74, }, /* 539 */\n  {    23,     26,     12,      0,      0,  28672,     74, }, /* 540 */\n  {    24,      9,     12,      0,  38864,  18432,    186, }, /* 541 */\n  {    24,      9,     12,      0,      8,  18432,    186, }, /* 542 */\n  {    24,      5,     12,      0,     -8,  18432,     70, }, /* 543 */\n  {   101,     17,     12,      0,      0,  28672,    130, }, /* 544 */\n  {   101,      7,     12,      0,      0,  18432,     84, }, /* 545 */\n  {   101,     26,     12,      0,      0,  18432,     74, }, /* 546 */\n  {   101,     21,     12,      0,      0,  18432,    128, }, /* 547 */\n  {   102,     29,     12,      0,      0,  45056,     52, }, /* 548 */\n  {   102,      7,     12,      0,      0,  18432,     84, }, /* 549 */\n  {   102,     22,     12,      0,      0,  28672,    172, }, /* 550 */\n  {   102,     18,     12,      0,      0,  28672,    172, }, /* 551 */\n  {    25,      7,     12,      0,      0,  18432,     84, }, /* 552 */\n  {    99,     21,     12,      0,      0,  18660,    110, }, /* 553 */\n  {    25,     14,     12,      0,      0,  18432,     84, }, /* 554 */\n  {    33,      7,     12,      0,      0,  18432,     84, }, /* 555 */\n  {    33,     12,      3,      0,      0,  26624,    106, }, /* 556 */\n  {    33,     12,      3,      0,      0,  26624,    158, }, /* 557 */\n  {    33,     10,      3,      0,      0,  18432,    188, }, /* 558 */\n  {    34,      7,     12,      0,      0,  18432,     84, }, /* 559 */\n  {    34,     12,      3,      0,      0,  26624,    106, }, /* 560 */\n  {    34,     10,      3,      0,      0,  18432,    188, }, /* 561 */\n  {    99,     21,     12,      0,      0,  18664,    128, }, /* 562 */\n  {    35,      7,     12,      0,      0,  18432,     84, }, /* 563 */\n  {    35,     12,      3,      0,      0,  26624,    106, }, /* 564 */\n  {    36,      7,     12,      0,      0,  18432,     84, }, /* 565 */\n  {    36,     12,      3,      0,      0,  26624,    106, }, /* 566 */\n  {   103,      7,     12,      0,      0,  18432,     84, }, /* 567 */\n  {   103,      7,     12,      0,      0,  18432,    146, }, /* 568 */\n  {   103,     12,      3,      0,      0,  26624,    102, }, /* 569 */\n  {   103,     10,      5,      0,      0,  18432,    154, }, /* 570 */\n  {   103,     12,      3,      0,      0,  26624,    106, }, /* 571 */\n  {   103,     12,      3,      0,      0,  26624,     98, }, /* 572 */\n  {   103,     12,      3,      0,      0,  26624,    158, }, /* 573 */\n  {   103,     21,     12,      0,      0,  18432,    128, }, /* 574 */\n  {   103,     21,     12,      0,      0,  18432,    110, }, /* 575 */\n  {   103,      6,     12,      0,      0,  18432,    148, }, /* 576 */\n  {   103,     21,     12,      0,      0,  18432,     74, }, /* 577 */\n  {   103,     23,     12,      0,      0,  14336,     74, }, /* 578 */\n  {   103,     13,     12,      0,      0,  18432,    144, }, /* 579 */\n  {   103,     15,     12,      0,      0,  28672,     74, }, /* 580 */\n  {    26,     21,     12,      0,      0,  28672,     74, }, /* 581 */\n  {    99,     21,     12,      0,      0,  28908,    110, }, /* 582 */\n  {    99,     21,     12,      0,      0,  28908,    128, }, /* 583 */\n  {    26,     21,     12,      0,      0,  28672,    110, }, /* 584 */\n  {    26,     17,     12,      0,      0,  28672,    130, }, /* 585 */\n  {    26,     21,     12,      0,      0,  28672,    128, }, /* 586 */\n  {    26,     21,     12,      0,      0,  28672,    190, }, /* 587 */\n  {    26,     12,      3,      0,      0,  26624,    192, }, /* 588 */\n  {    26,      1,      2,      0,      0,   6144,     66, }, /* 589 */\n  {    26,     13,     12,      0,      0,  18432,    144, }, /* 590 */\n  {    26,      7,     12,      0,      0,  18432,     84, }, /* 591 */\n  {    26,      6,     12,      0,      0,  18432,    138, }, /* 592 */\n  {    26,     12,      3,      0,      0,  26624,    194, }, /* 593 */\n  {    26,     12,      3,      0,      0,  26624,    106, }, /* 594 */\n  {    37,      7,     12,      0,      0,  18432,     84, }, /* 595 */\n  {    37,     12,      3,      0,      0,  26624,    106, }, /* 596 */\n  {    37,     10,      5,      0,      0,  18432,    154, }, /* 597 */\n  {    37,     12,      3,      0,      0,  26624,     98, }, /* 598 */\n  {    37,     26,     12,      0,      0,  28672,     74, }, /* 599 */\n  {    37,     21,     12,      0,      0,  28672,    128, }, /* 600 */\n  {    37,     13,     12,      0,      0,  18432,    144, }, /* 601 */\n  {    38,      7,     12,      0,      0,  18432,     84, }, /* 602 */\n  {   110,      7,     12,      0,      0,  18432,     84, }, /* 603 */\n  {   110,      7,     12,      0,      0,  18432,    170, }, /* 604 */\n  {   110,     13,     12,      0,      0,  18432,    144, }, /* 605 */\n  {   110,     15,     12,      0,      0,  18432,    144, }, /* 606 */\n  {   110,     26,     12,      0,      0,  28672,     74, }, /* 607 */\n  {   103,     26,     12,      0,      0,  28672,     74, }, /* 608 */\n  {    42,      7,     12,      0,      0,  18432,     84, }, /* 609 */\n  {    42,     12,      3,      0,      0,  26624,    106, }, /* 610 */\n  {    42,     10,      5,      0,      0,  18432,    154, }, /* 611 */\n  {    42,     21,     12,      0,      0,  18432,     74, }, /* 612 */\n  {   123,      7,     12,      0,      0,  18432,     84, }, /* 613 */\n  {   123,     10,      5,      0,      0,  18432,    154, }, /* 614 */\n  {   123,     12,      3,      0,      0,  26624,    106, }, /* 615 */\n  {   123,     12,      3,      0,      0,  26624,    158, }, /* 616 */\n  {   123,     10,     12,      0,      0,  18432,    154, }, /* 617 */\n  {   123,     12,      3,      0,      0,  26624,     98, }, /* 618 */\n  {   123,     13,     12,      0,      0,  18432,    144, }, /* 619 */\n  {   123,     21,     12,      0,      0,  18432,     74, }, /* 620 */\n  {   123,      6,     12,      0,      0,  18432,    138, }, /* 621 */\n  {   123,     21,     12,      0,      0,  18432,    128, }, /* 622 */\n  {   106,     11,      3,      0,      0,  26624,    196, }, /* 623 */\n  {   106,     12,      3,      0,      0,  26624,    106, }, /* 624 */\n  {   113,     12,      3,      0,      0,  26624,    106, }, /* 625 */\n  {   113,     10,      5,      0,      0,  18432,    154, }, /* 626 */\n  {   113,      7,     12,      0,      0,  18432,     84, }, /* 627 */\n  {   113,     12,      3,      0,      0,  26624,     98, }, /* 628 */\n  {   113,     10,      3,      0,      0,  18432,    160, }, /* 629 */\n  {   113,     10,      3,      0,      0,  18432,    188, }, /* 630 */\n  {   113,     21,     12,      0,      0,  18432,    128, }, /* 631 */\n  {   113,     13,     12,      0,      0,  18432,    144, }, /* 632 */\n  {   113,     21,     12,      0,      0,  18432,     74, }, /* 633 */\n  {   113,     21,     12,      0,      0,  18432,    110, }, /* 634 */\n  {   113,     26,     12,      0,      0,  18432,     74, }, /* 635 */\n  {   116,     12,      3,      0,      0,  26624,    106, }, /* 636 */\n  {   116,     10,      5,      0,      0,  18432,    154, }, /* 637 */\n  {   116,      7,     12,      0,      0,  18432,     84, }, /* 638 */\n  {   116,     10,      3,      0,      0,  18432,    188, }, /* 639 */\n  {   116,     12,      3,      0,      0,  26624,    158, }, /* 640 */\n  {   116,     13,     12,      0,      0,  18432,    144, }, /* 641 */\n  {   132,      7,     12,      0,      0,  18432,     84, }, /* 642 */\n  {   132,     12,      3,      0,      0,  26624,     98, }, /* 643 */\n  {   132,     10,      5,      0,      0,  18432,    154, }, /* 644 */\n  {   132,     12,      3,      0,      0,  26624,    106, }, /* 645 */\n  {   132,     10,      3,      0,      0,  18432,    188, }, /* 646 */\n  {   132,     21,     12,      0,      0,  18432,     74, }, /* 647 */\n  {   117,      7,     12,      0,      0,  18432,     84, }, /* 648 */\n  {   117,     10,      5,      0,      0,  18432,    154, }, /* 649 */\n  {   117,     12,      3,      0,      0,  26624,    106, }, /* 650 */\n  {   117,     12,      3,      0,      0,  26624,    198, }, /* 651 */\n  {   117,     12,      3,      0,      0,  26624,     98, }, /* 652 */\n  {   117,     21,     12,      0,      0,  18432,    128, }, /* 653 */\n  {   117,     21,     12,      0,      0,  18432,    110, }, /* 654 */\n  {   117,     13,     12,      0,      0,  18432,    144, }, /* 655 */\n  {   118,     13,     12,      0,      0,  18432,    144, }, /* 656 */\n  {   118,      7,     12,      0,      0,  18432,     84, }, /* 657 */\n  {   118,      6,     12,      0,      0,  18432,     94, }, /* 658 */\n  {   118,      6,     12,      0,      0,  18432,     96, }, /* 659 */\n  {   118,     21,     12,      0,      0,  18432,    128, }, /* 660 */\n  {     2,      5,     12,     63,  -6222,  18432,     70, }, /* 661 */\n  {     2,      5,     12,     67,  -6221,  18432,     70, }, /* 662 */\n  {     2,      5,     12,     71,  -6212,  18432,     70, }, /* 663 */\n  {     2,      5,     12,     75,  -6210,  18432,     70, }, /* 664 */\n  {     2,      5,     12,     79,  -6210,  18432,     70, }, /* 665 */\n  {     2,      5,     12,     79,  -6211,  18432,     70, }, /* 666 */\n  {     2,      5,     12,     84,  -6204,  18432,     70, }, /* 667 */\n  {     2,      5,     12,     88,  -6180,  18432,     70, }, /* 668 */\n  {     2,      5,     12,    108,  35267,  18432,     70, }, /* 669 */\n  {    21,      9,     12,      0,  -3008,  18432,     76, }, /* 670 */\n  {   116,     21,     12,      0,      0,  18432,     74, }, /* 671 */\n  {   106,     12,      3,      0,      0,  26864,     98, }, /* 672 */\n  {   106,     12,      3,      0,      0,  26868,     98, }, /* 673 */\n  {    99,     21,     12,      0,      0,  18680,    200, }, /* 674 */\n  {   106,     12,      3,      0,      0,  26876,     98, }, /* 675 */\n  {   106,     12,      3,      0,      0,  26880,     98, }, /* 676 */\n  {   106,     12,      3,      0,      0,  26884,     98, }, /* 677 */\n  {    99,     10,      5,      0,      0,  18684,    174, }, /* 678 */\n  {    99,      7,     12,      0,      0,  18696,     84, }, /* 679 */\n  {    99,      7,     12,      0,      0,  18684,     84, }, /* 680 */\n  {    99,      7,     12,      0,      0,  18676,     84, }, /* 681 */\n  {    99,      7,     12,      0,      0,  18700,     84, }, /* 682 */\n  {    99,      7,     12,      0,      0,  18704,     84, }, /* 683 */\n  {   106,     12,      3,      0,      0,  26900,     98, }, /* 684 */\n  {    99,     10,      5,      0,      0,  18712,    174, }, /* 685 */\n  {   106,     12,      3,      0,      0,  26896,     98, }, /* 686 */\n  {    99,      7,     12,      0,      0,  18716,     84, }, /* 687 */\n  {     2,      5,     12,      0,      0,  18432,     60, }, /* 688 */\n  {     1,      6,     12,      0,      0,  18432,     90, }, /* 689 */\n  {     2,      6,     12,      0,      0,  18432,    182, }, /* 690 */\n  {     0,      5,     12,      0,  35332,  18432,     78, }, /* 691 */\n  {     0,      5,     12,      0,   3814,  18432,     78, }, /* 692 */\n  {     0,      5,     12,      0,  35384,  18432,     78, }, /* 693 */\n  {     0,      5,     12,      0,      0,  18432,    202, }, /* 694 */\n  {     0,      6,     12,      0,      0,  18432,    182, }, /* 695 */\n  {     0,      6,     12,      0,      0,  18432,    204, }, /* 696 */\n  {     1,      6,     12,      0,      0,  18432,    182, }, /* 697 */\n  {   106,     12,      3,      0,      0,  26740,    104, }, /* 698 */\n  {   106,     12,      3,      0,      0,  26912,     98, }, /* 699 */\n  {   106,     12,      3,      0,      0,  26916,     98, }, /* 700 */\n  {     0,      9,     12,     92,      1,  18432,     76, }, /* 701 */\n  {     0,      5,     12,     92,     -1,  18432,     78, }, /* 702 */\n  {     0,      5,     12,      0,      0,  18432,     70, }, /* 703 */\n  {     0,      5,     12,     92,    -58,  18432,     70, }, /* 704 */\n  {     0,      9,     12,      0,  -7615,  18432,     76, }, /* 705 */\n  {     1,      5,     12,      0,      8,  18432,     78, }, /* 706 */\n  {     1,      9,     12,      0,     -8,  18432,     76, }, /* 707 */\n  {     1,      5,     12,      0,      0,  18432,     78, }, /* 708 */\n  {     1,      5,     12,      0,     74,  18432,     78, }, /* 709 */\n  {     1,      5,     12,      0,     86,  18432,     78, }, /* 710 */\n  {     1,      5,     12,      0,    100,  18432,     78, }, /* 711 */\n  {     1,      5,     12,      0,    128,  18432,     78, }, /* 712 */\n  {     1,      5,     12,      0,    112,  18432,     78, }, /* 713 */\n  {     1,      5,     12,      0,    126,  18432,     78, }, /* 714 */\n  {     1,      5,     12,      0,      8,  18432,     70, }, /* 715 */\n  {     1,      8,     12,      0,     -8,  18432,     88, }, /* 716 */\n  {     1,      5,     12,      0,      0,  18432,     70, }, /* 717 */\n  {     1,      5,     12,      0,      9,  18432,     70, }, /* 718 */\n  {     1,      9,     12,      0,    -74,  18432,     76, }, /* 719 */\n  {     1,      8,     12,      0,     -9,  18432,     88, }, /* 720 */\n  {     1,      5,     12,     21,  -7173,  18432,     78, }, /* 721 */\n  {     1,      9,     12,      0,    -86,  18432,     76, }, /* 722 */\n  {     1,      5,     12,      0,  -7235,  18432,     78, }, /* 723 */\n  {     1,      9,     12,      0,   -100,  18432,     76, }, /* 724 */\n  {     1,      5,     12,      0,  -7219,  18432,     78, }, /* 725 */\n  {     1,      9,     12,      0,   -112,  18432,     76, }, /* 726 */\n  {     1,      9,     12,      0,   -128,  18432,     76, }, /* 727 */\n  {     1,      9,     12,      0,   -126,  18432,     76, }, /* 728 */\n  {    99,     29,     12,      0,      0,  45056,     52, }, /* 729 */\n  {   106,      1,      3,      0,      0,   6144,    206, }, /* 730 */\n  {   106,      1,     13,      0,      0,   6144,    208, }, /* 731 */\n  {    99,      1,      2,      0,      0,  18432,    210, }, /* 732 */\n  {    99,      1,      2,      0,      0,  34816,    210, }, /* 733 */\n  {    99,     17,     12,      0,      0,  28672,    212, }, /* 734 */\n  {    99,     21,     12,      0,      0,  28672,     64, }, /* 735 */\n  {    99,     20,     12,      0,      0,  28672,    214, }, /* 736 */\n  {    99,     19,     12,      0,      0,  28672,    214, }, /* 737 */\n  {    99,     22,     12,      0,      0,  28672,    216, }, /* 738 */\n  {    99,     20,     12,      0,      0,  28672,    216, }, /* 739 */\n  {    99,     19,     12,      0,      0,  28672,    216, }, /* 740 */\n  {    99,     21,     12,      0,      0,  28672,    218, }, /* 741 */\n  {    99,     21,     12,      0,      0,  28672,    220, }, /* 742 */\n  {    99,     27,      2,      0,      0,  45056,     50, }, /* 743 */\n  {    99,     28,      2,      0,      0,   4096,     50, }, /* 744 */\n  {    99,      1,      2,      0,      0,  20480,    136, }, /* 745 */\n  {    99,      1,      2,      0,      0,  36864,    136, }, /* 746 */\n  {    99,      1,      2,      0,      0,  30720,    136, }, /* 747 */\n  {    99,      1,      2,      0,      0,  24576,    136, }, /* 748 */\n  {    99,      1,      2,      0,      0,  40960,    136, }, /* 749 */\n  {    99,     29,     12,      0,      0,   8488,     52, }, /* 750 */\n  {    99,     21,     12,      0,      0,  14336,     54, }, /* 751 */\n  {    99,     21,     12,      0,      0,  14336,     64, }, /* 752 */\n  {    99,     21,     14,      0,      0,  28672,    222, }, /* 753 */\n  {    99,     21,     12,      0,      0,  28672,    224, }, /* 754 */\n  {    99,     16,     12,      0,      0,  28672,    144, }, /* 755 */\n  {    99,     16,     12,      0,      0,  28672,    226, }, /* 756 */\n  {    99,     25,     12,      0,      0,   8192,     64, }, /* 757 */\n  {    99,     22,     12,      0,      0,  28672,    228, }, /* 758 */\n  {    99,     18,     12,      0,      0,  28672,    228, }, /* 759 */\n  {    99,     21,     12,      0,      0,  28972,     54, }, /* 760 */\n  {    99,     21,     12,      0,      0,  28672,    212, }, /* 761 */\n  {    99,     21,     12,      0,      0,  28976,     54, }, /* 762 */\n  {    99,     21,     12,      0,      0,  28980,     54, }, /* 763 */\n  {    99,      1,      2,      0,      0,   6144,    230, }, /* 764 */\n  {    98,      2,      2,      0,      0,   6144,    232, }, /* 765 */\n  {    99,      1,      2,      0,      0,  22528,    136, }, /* 766 */\n  {    99,      1,      2,      0,      0,  38912,    136, }, /* 767 */\n  {    99,      1,      2,      0,      0,  16384,    136, }, /* 768 */\n  {    99,      1,      2,      0,      0,  32768,    136, }, /* 769 */\n  {    99,      1,      2,      0,      0,   6144,    234, }, /* 770 */\n  {    99,     25,     12,      0,      0,  12288,    236, }, /* 771 */\n  {    99,     25,     12,      0,      0,  12288,    238, }, /* 772 */\n  {    99,     25,     12,      0,      0,  28672,    236, }, /* 773 */\n  {    99,     22,     12,      0,      0,  28672,    240, }, /* 774 */\n  {    99,     18,     12,      0,      0,  28672,    240, }, /* 775 */\n  {    98,      2,     12,      0,      0,  14336,      0, }, /* 776 */\n  {   106,     12,      3,      0,      0,  26624,    242, }, /* 777 */\n  {   106,     11,      3,      0,      0,  26624,    124, }, /* 778 */\n  {   106,     11,      3,      0,      0,  26624,    244, }, /* 779 */\n  {   106,     12,      3,      0,      0,  26936,    104, }, /* 780 */\n  {    99,     26,     12,      0,      0,  28672,     74, }, /* 781 */\n  {    99,      9,     12,      0,      0,  18432,    116, }, /* 782 */\n  {    99,      5,     12,      0,      0,  18432,    246, }, /* 783 */\n  {    99,     25,     12,      0,      0,  28672,    248, }, /* 784 */\n  {    99,     26,     14,      0,      0,  28672,    250, }, /* 785 */\n  {     1,      9,     12,     96,  -7517,  18432,     76, }, /* 786 */\n  {    99,     26,     12,      0,      0,  28672,    122, }, /* 787 */\n  {     0,      9,     12,    100,      0,  18432,     76, }, /* 788 */\n  {     0,      9,     12,    104,  -8262,  18432,     76, }, /* 789 */\n  {    99,     26,     12,      0,      0,  14336,    252, }, /* 790 */\n  {     0,      9,     12,      0,     28,  18432,     76, }, /* 791 */\n  {    99,      7,     12,      0,      0,  18432,    254, }, /* 792 */\n  {    99,      5,     14,      0,      0,  18432,    256, }, /* 793 */\n  {    99,     25,     12,      0,      0,  28672,    122, }, /* 794 */\n  {    99,      5,     12,      0,      0,  18432,    258, }, /* 795 */\n  {     0,      5,     12,      0,    -28,  18432,     78, }, /* 796 */\n  {     0,     14,     12,      0,     16,  18432,     76, }, /* 797 */\n  {     0,     14,     12,      0,    -16,  18432,     78, }, /* 798 */\n  {     0,     14,     12,      0,      0,  18432,     84, }, /* 799 */\n  {    99,     25,     14,      0,      0,  28672,    260, }, /* 800 */\n  {    99,     26,     14,      0,      0,  28672,    260, }, /* 801 */\n  {    99,     26,     12,      0,      0,  28672,     64, }, /* 802 */\n  {    99,     25,     12,      0,      0,  28672,    262, }, /* 803 */\n  {    99,     25,     12,      0,      0,  28672,    264, }, /* 804 */\n  {    99,     25,     12,      0,      0,  12288,    266, }, /* 805 */\n  {    99,     22,     12,      0,      0,  28672,    264, }, /* 806 */\n  {    99,     18,     12,      0,      0,  28672,    264, }, /* 807 */\n  {    99,     26,     14,      0,      0,  28672,    268, }, /* 808 */\n  {    99,     22,     12,      0,      0,  28672,    270, }, /* 809 */\n  {    99,     18,     12,      0,      0,  28672,    270, }, /* 810 */\n  {    99,     26,     12,      0,      0,  18432,     54, }, /* 811 */\n  {    99,     26,     14,      0,      0,  28672,    272, }, /* 812 */\n  {    98,      2,     12,      0,      0,  18432,    274, }, /* 813 */\n  {    99,     15,     12,      0,      0,  10240,     74, }, /* 814 */\n  {    99,     26,     12,      0,     26,  18432,    276, }, /* 815 */\n  {    99,     26,     14,      0,     26,  18432,    278, }, /* 816 */\n  {    99,     26,     12,      0,    -26,  18432,    280, }, /* 817 */\n  {    99,     25,     14,      0,      0,  28672,    282, }, /* 818 */\n  {    99,     26,     14,      0,      0,  28672,    284, }, /* 819 */\n  {    99,     26,     14,      0,      0,  28672,    286, }, /* 820 */\n  {    99,     25,     14,      0,      0,  28672,    284, }, /* 821 */\n  {    99,     26,     14,      0,      0,  18432,    272, }, /* 822 */\n  {    99,     26,     14,      0,      0,  28672,    288, }, /* 823 */\n  {   109,     26,     12,      0,      0,  18432,     54, }, /* 824 */\n  {    99,     26,     12,      0,      0,  28672,    228, }, /* 825 */\n  {    44,      9,     12,      0,     48,  18432,     76, }, /* 826 */\n  {    44,      5,     12,      0,    -48,  18432,     78, }, /* 827 */\n  {     0,      9,     12,      0, -10743,  18432,     76, }, /* 828 */\n  {     0,      9,     12,      0,  -3814,  18432,     76, }, /* 829 */\n  {     0,      9,     12,      0, -10727,  18432,     76, }, /* 830 */\n  {     0,      5,     12,      0, -10795,  18432,     78, }, /* 831 */\n  {     0,      5,     12,      0, -10792,  18432,     78, }, /* 832 */\n  {     0,      9,     12,      0, -10780,  18432,     76, }, /* 833 */\n  {     0,      9,     12,      0, -10749,  18432,     76, }, /* 834 */\n  {     0,      9,     12,      0, -10783,  18432,     76, }, /* 835 */\n  {     0,      9,     12,      0, -10782,  18432,     76, }, /* 836 */\n  {     0,      9,     12,      0, -10815,  18432,     76, }, /* 837 */\n  {    43,      5,     12,      0,      0,  18432,     60, }, /* 838 */\n  {    43,     26,     12,      0,      0,  28672,     74, }, /* 839 */\n  {    43,     12,      3,      0,      0,  26624,     98, }, /* 840 */\n  {    43,     21,     12,      0,      0,  28672,    128, }, /* 841 */\n  {    43,     21,     12,      0,      0,  28672,     74, }, /* 842 */\n  {    43,     15,     12,      0,      0,  28672,     74, }, /* 843 */\n  {    21,      5,     12,      0,  -7264,  18432,     78, }, /* 844 */\n  {    45,      7,     12,      0,      0,  18432,     84, }, /* 845 */\n  {    45,      6,     12,      0,      0,  18432,    148, }, /* 846 */\n  {    45,     21,     12,      0,      0,  18432,     74, }, /* 847 */\n  {    45,     12,      3,      0,      0,  26624,    290, }, /* 848 */\n  {     2,     12,      3,      0,      0,  26624,    106, }, /* 849 */\n  {    99,     20,     12,      0,      0,  28672,    228, }, /* 850 */\n  {    99,     19,     12,      0,      0,  28672,    228, }, /* 851 */\n  {    99,     17,     12,      0,      0,  28988,    212, }, /* 852 */\n  {    99,      6,     12,      0,      0,  28672,    292, }, /* 853 */\n  {    99,     21,     12,      0,      0,  28992,     54, }, /* 854 */\n  {    99,     21,     12,      0,      0,  28996,     54, }, /* 855 */\n  {    99,     21,     12,      0,      0,  29000,    224, }, /* 856 */\n  {    99,     21,     12,      0,      0,  29004,    294, }, /* 857 */\n  {    99,     21,     12,      0,      0,  28812,     54, }, /* 858 */\n  {    99,     21,     12,      0,      0,  28672,    294, }, /* 859 */\n  {    30,     26,     12,      0,      0,  28672,    296, }, /* 860 */\n  {    99,     26,     12,      0,      0,  29008,    298, }, /* 861 */\n  {    99,     26,     12,      0,      0,  29008,    300, }, /* 862 */\n  {    99,     26,     12,      0,      0,  29008,    302, }, /* 863 */\n  {    99,     21,     12,      0,      0,  29012,    294, }, /* 864 */\n  {    99,     21,     12,      0,      0,  29016,    224, }, /* 865 */\n  {    99,     21,     12,      0,      0,  29020,     54, }, /* 866 */\n  {    30,      6,     12,      0,      0,  18432,    138, }, /* 867 */\n  {    99,      7,     12,      0,      0,  18784,    304, }, /* 868 */\n  {    30,     14,     12,      0,      0,  18432,    304, }, /* 869 */\n  {    99,     22,     12,      0,      0,  29028,    228, }, /* 870 */\n  {    99,     18,     12,      0,      0,  29028,    228, }, /* 871 */\n  {    99,     22,     12,      0,      0,  29032,    228, }, /* 872 */\n  {    99,     18,     12,      0,      0,  29032,    228, }, /* 873 */\n  {    99,     22,     12,      0,      0,  29036,     62, }, /* 874 */\n  {    99,     18,     12,      0,      0,  29036,     62, }, /* 875 */\n  {    99,     22,     12,      0,      0,  29036,    228, }, /* 876 */\n  {    99,     18,     12,      0,      0,  29036,    228, }, /* 877 */\n  {    99,     26,     12,      0,      0,  29020,     54, }, /* 878 */\n  {    99,     17,     12,      0,      0,  29020,    212, }, /* 879 */\n  {    99,     22,     12,      0,      0,  29020,    216, }, /* 880 */\n  {    99,     18,     12,      0,      0,  29020,    216, }, /* 881 */\n  {   106,     12,      3,      0,      0,  26992,     98, }, /* 882 */\n  {    22,     10,      3,      0,      0,  18432,    306, }, /* 883 */\n  {    99,     17,     14,      0,      0,  29020,    308, }, /* 884 */\n  {    99,      6,     12,      0,      0,  18804,    138, }, /* 885 */\n  {    99,     26,     12,      0,      0,  29020,     74, }, /* 886 */\n  {    30,      6,     12,      0,      0,  18432,    148, }, /* 887 */\n  {    99,      7,     12,      0,      0,  18808,     84, }, /* 888 */\n  {    99,     21,     14,      0,      0,  29048,    250, }, /* 889 */\n  {    99,     26,     12,      0,      0,  29024,     74, }, /* 890 */\n  {    27,      7,     12,      0,      0,  18432,     84, }, /* 891 */\n  {   106,     12,      3,      0,      0,  26996,     98, }, /* 892 */\n  {    99,     24,     12,      0,      0,  29044,    310, }, /* 893 */\n  {    27,      6,     12,      0,      0,  18432,    138, }, /* 894 */\n  {    99,     17,     12,      0,      0,  29044,    130, }, /* 895 */\n  {    28,      7,     12,      0,      0,  18432,     84, }, /* 896 */\n  {    99,     21,     12,      0,      0,  29036,    144, }, /* 897 */\n  {    99,      6,     12,      0,      0,  18804,     96, }, /* 898 */\n  {    28,      6,     12,      0,      0,  18432,    138, }, /* 899 */\n  {    29,      7,     12,      0,      0,  18432,     84, }, /* 900 */\n  {    22,      7,     12,      0,      0,  18432,     84, }, /* 901 */\n  {    22,      7,     12,      0,      0,  18432,    184, }, /* 902 */\n  {    99,     26,     12,      0,      0,  18784,     74, }, /* 903 */\n  {    99,     15,     12,      0,      0,  18784,     74, }, /* 904 */\n  {    22,     26,     12,      0,      0,  18432,     74, }, /* 905 */\n  {    22,     26,     12,      0,      0,  28672,     74, }, /* 906 */\n  {    99,     15,     12,      0,      0,  18432,     74, }, /* 907 */\n  {    99,     26,     14,      0,      0,  18784,    250, }, /* 908 */\n  {    28,     26,     12,      0,      0,  18432,     74, }, /* 909 */\n  {    30,      7,     12,      0,      0,  18432,    312, }, /* 910 */\n  {    31,      7,     12,      0,      0,  18432,     84, }, /* 911 */\n  {    31,      6,     12,      0,      0,  18432,    138, }, /* 912 */\n  {    31,     26,     12,      0,      0,  28672,     74, }, /* 913 */\n  {    55,      7,     12,      0,      0,  18432,     84, }, /* 914 */\n  {    55,      6,     12,      0,      0,  18432,    148, }, /* 915 */\n  {    55,     21,     12,      0,      0,  18432,    110, }, /* 916 */\n  {    55,     21,     12,      0,      0,  18432,    128, }, /* 917 */\n  {   119,      7,     12,      0,      0,  18432,     84, }, /* 918 */\n  {   119,      6,     12,      0,      0,  18432,    138, }, /* 919 */\n  {   119,     21,     12,      0,      0,  28672,    110, }, /* 920 */\n  {   119,     21,     12,      0,      0,  28672,    128, }, /* 921 */\n  {   119,     13,     12,      0,      0,  18432,    144, }, /* 922 */\n  {     2,      9,     12,    108,      1,  18432,     76, }, /* 923 */\n  {     2,      5,     12,    108, -35267,  18432,     78, }, /* 924 */\n  {     2,      7,     12,      0,      0,  18432,     84, }, /* 925 */\n  {     2,     21,     12,      0,      0,  28672,     74, }, /* 926 */\n  {     2,     12,      3,      0,      0,  26624,     98, }, /* 927 */\n  {     2,      6,     12,      0,      0,  28672,     94, }, /* 928 */\n  {     2,      6,     12,      0,      0,  18432,     90, }, /* 929 */\n  {   126,      7,     12,      0,      0,  18432,     84, }, /* 930 */\n  {   126,     14,     12,      0,      0,  18432,     84, }, /* 931 */\n  {   126,     12,      3,      0,      0,  26624,     98, }, /* 932 */\n  {   126,     21,     12,      0,      0,  18432,     74, }, /* 933 */\n  {   126,     21,     12,      0,      0,  18432,    128, }, /* 934 */\n  {   126,     21,     12,      0,      0,  18432,    110, }, /* 935 */\n  {    99,     24,     12,      0,      0,  29052,     56, }, /* 936 */\n  {     0,      9,     12,      0, -35332,  18432,     76, }, /* 937 */\n  {    99,     24,     12,      0,      0,  18432,     56, }, /* 938 */\n  {     0,      9,     12,      0, -42280,  18432,     76, }, /* 939 */\n  {     0,      5,     12,      0,     48,  18432,     78, }, /* 940 */\n  {     0,      9,     12,      0, -42308,  18432,     76, }, /* 941 */\n  {     0,      9,     12,      0, -42319,  18432,     76, }, /* 942 */\n  {     0,      9,     12,      0, -42315,  18432,     76, }, /* 943 */\n  {     0,      9,     12,      0, -42305,  18432,     76, }, /* 944 */\n  {     0,      9,     12,      0, -42258,  18432,     76, }, /* 945 */\n  {     0,      9,     12,      0, -42282,  18432,     76, }, /* 946 */\n  {     0,      9,     12,      0, -42261,  18432,     76, }, /* 947 */\n  {     0,      9,     12,      0,    928,  18432,     76, }, /* 948 */\n  {     0,      9,     12,      0,    -48,  18432,     76, }, /* 949 */\n  {     0,      9,     12,      0, -42307,  18432,     76, }, /* 950 */\n  {     0,      9,     12,      0, -35384,  18432,     76, }, /* 951 */\n  {     0,      9,     12,      0, -42343,  18432,     76, }, /* 952 */\n  {     0,      9,     12,      0, -42561,  18432,     76, }, /* 953 */\n  {    46,      7,     12,      0,      0,  18432,     84, }, /* 954 */\n  {    46,     12,      3,      0,      0,  26624,    106, }, /* 955 */\n  {    46,     12,      3,      0,      0,  26624,    158, }, /* 956 */\n  {    46,     10,      5,      0,      0,  18432,    154, }, /* 957 */\n  {    46,     26,     12,      0,      0,  28672,     74, }, /* 958 */\n  {    99,     15,     12,      0,      0,  18816,     74, }, /* 959 */\n  {    99,     15,     12,      0,      0,  18820,     74, }, /* 960 */\n  {    99,     26,     12,      0,      0,  18824,     74, }, /* 961 */\n  {    99,     23,     12,      0,      0,  14732,     74, }, /* 962 */\n  {    99,     26,     12,      0,      0,  14728,     74, }, /* 963 */\n  {    47,      7,     12,      0,      0,  18432,     84, }, /* 964 */\n  {    47,     21,     12,      0,      0,  28672,     74, }, /* 965 */\n  {    47,     21,     12,      0,      0,  28672,    128, }, /* 966 */\n  {   120,     10,      5,      0,      0,  18432,    154, }, /* 967 */\n  {   120,      7,     12,      0,      0,  18432,     84, }, /* 968 */\n  {   120,     12,      3,      0,      0,  26624,    158, }, /* 969 */\n  {   120,     12,      3,      0,      0,  26624,    106, }, /* 970 */\n  {   120,     21,     12,      0,      0,  18432,    128, }, /* 971 */\n  {   120,     13,     12,      0,      0,  18432,    144, }, /* 972 */\n  {     8,     12,      3,      0,      0,  27024,     98, }, /* 973 */\n  {     8,      7,     12,      0,      0,  18836,     84, }, /* 974 */\n  {    49,     13,     12,      0,      0,  18432,    144, }, /* 975 */\n  {    49,      7,     12,      0,      0,  18432,     84, }, /* 976 */\n  {    49,     12,      3,      0,      0,  26624,    106, }, /* 977 */\n  {    49,     12,      3,      0,      0,  26624,     98, }, /* 978 */\n  {    99,     21,     12,      0,      0,  18840,    200, }, /* 979 */\n  {    49,     21,     12,      0,      0,  18432,    128, }, /* 980 */\n  {   121,      7,     12,      0,      0,  18432,     84, }, /* 981 */\n  {   121,     12,      3,      0,      0,  26624,    106, }, /* 982 */\n  {   121,     10,      5,      0,      0,  18432,    154, }, /* 983 */\n  {   121,     10,      3,      0,      0,  18432,    188, }, /* 984 */\n  {   121,     21,     12,      0,      0,  18432,     74, }, /* 985 */\n  {    56,     12,      3,      0,      0,  26624,    106, }, /* 986 */\n  {    56,     10,      5,      0,      0,  18432,    154, }, /* 987 */\n  {    56,      7,     12,      0,      0,  18432,     84, }, /* 988 */\n  {    56,     12,      3,      0,      0,  26624,     98, }, /* 989 */\n  {    56,     10,      3,      0,      0,  18432,    188, }, /* 990 */\n  {    56,     21,     12,      0,      0,  18432,     74, }, /* 991 */\n  {    56,     21,     12,      0,      0,  18432,    110, }, /* 992 */\n  {    56,     21,     12,      0,      0,  18432,    128, }, /* 993 */\n  {    99,      6,     12,      0,      0,  18844,    138, }, /* 994 */\n  {    56,     13,     12,      0,      0,  18432,    144, }, /* 995 */\n  {    20,      6,     12,      0,      0,  18432,    138, }, /* 996 */\n  {   122,      7,     12,      0,      0,  18432,     84, }, /* 997 */\n  {   122,     12,      3,      0,      0,  26624,    106, }, /* 998 */\n  {   122,     10,      5,      0,      0,  18432,    154, }, /* 999 */\n  {   122,     13,     12,      0,      0,  18432,    144, }, /* 1000 */\n  {   122,     21,     12,      0,      0,  18432,     74, }, /* 1001 */\n  {   122,     21,     12,      0,      0,  18432,    128, }, /* 1002 */\n  {   124,      7,     12,      0,      0,  18432,     84, }, /* 1003 */\n  {   124,     12,      3,      0,      0,  26624,    106, }, /* 1004 */\n  {   124,      7,     12,      0,      0,  18432,    170, }, /* 1005 */\n  {   124,     12,      3,      0,      0,  26624,     98, }, /* 1006 */\n  {   124,      7,     12,      0,      0,  18432,    314, }, /* 1007 */\n  {   124,      6,     12,      0,      0,  18432,    138, }, /* 1008 */\n  {   124,     21,     12,      0,      0,  18432,     74, }, /* 1009 */\n  {   124,     21,     12,      0,      0,  18432,    110, }, /* 1010 */\n  {   127,      7,     12,      0,      0,  18432,     84, }, /* 1011 */\n  {   127,     10,      5,      0,      0,  18432,    154, }, /* 1012 */\n  {   127,     12,      3,      0,      0,  26624,    106, }, /* 1013 */\n  {   127,     21,     12,      0,      0,  18432,    128, }, /* 1014 */\n  {   127,      6,     12,      0,      0,  18432,    138, }, /* 1015 */\n  {   127,     12,      3,      0,      0,  26624,    158, }, /* 1016 */\n  {     0,      5,     12,      0,   -928,  18432,     78, }, /* 1017 */\n  {    24,      5,     12,      0, -38864,  18432,     70, }, /* 1018 */\n  {   127,     10,      5,      0,      0,  18432,    174, }, /* 1019 */\n  {   127,     13,     12,      0,      0,  18432,    144, }, /* 1020 */\n  {    22,      7,      9,      0,      0,  18432,     84, }, /* 1021 */\n  {    22,      7,     10,      0,      0,  18432,     84, }, /* 1022 */\n  {    98,      4,     12,      0,      0,  18432,      0, }, /* 1023 */\n  {    98,      3,     12,      0,      0,  18432,      0, }, /* 1024 */\n  {    30,      7,     12,      0,      0,  18432,    304, }, /* 1025 */\n  {     0,      5,     12,      0,      1,  18432,     70, }, /* 1026 */\n  {     0,      5,     12,      0,     -1,  18432,     70, }, /* 1027 */\n  {     4,     25,     12,      0,      0,  12288,    122, }, /* 1028 */\n  {     5,      7,     12,      0,      0,      0,    316, }, /* 1029 */\n  {    99,     18,     12,      0,      0,  29088,     54, }, /* 1030 */\n  {    99,     22,     12,      0,      0,  29088,     54, }, /* 1031 */\n  {    98,      2,     12,      0,      0,   6144,    318, }, /* 1032 */\n  {     5,      7,     12,      0,      0,    420,     84, }, /* 1033 */\n  {     5,     26,     12,      0,      0,  29092,     74, }, /* 1034 */\n  {   106,     12,      3,      0,      0,  26624,    192, }, /* 1035 */\n  {   106,     12,      3,      0,      0,  26624,    320, }, /* 1036 */\n  {    99,     21,     12,      0,      0,  28672,     74, }, /* 1037 */\n  {    99,     21,     12,      0,      0,  28672,    128, }, /* 1038 */\n  {    99,     21,     12,      0,      0,  28672,    126, }, /* 1039 */\n  {    99,     22,     12,      0,      0,  28672,     74, }, /* 1040 */\n  {    99,     18,     12,      0,      0,  28672,     74, }, /* 1041 */\n  {    99,     17,     12,      0,      0,  28672,    130, }, /* 1042 */\n  {    99,     22,     12,      0,      0,  28672,    322, }, /* 1043 */\n  {    99,     18,     12,      0,      0,  28672,    322, }, /* 1044 */\n  {    99,     21,     12,      0,      0,   8192,    110, }, /* 1045 */\n  {    99,     21,     12,      0,      0,   8192,    324, }, /* 1046 */\n  {    99,     21,     12,      0,      0,   8192,    326, }, /* 1047 */\n  {    99,     22,     12,      0,      0,  28672,    172, }, /* 1048 */\n  {    99,     18,     12,      0,      0,  28672,    172, }, /* 1049 */\n  {    99,     21,     12,      0,      0,  14336,     74, }, /* 1050 */\n  {    99,     21,     12,      0,      0,  28672,    122, }, /* 1051 */\n  {    99,     25,     12,      0,      0,  12288,    122, }, /* 1052 */\n  {    99,     17,     12,      0,      0,  12288,    328, }, /* 1053 */\n  {    99,     25,     12,      0,      0,  28672,    330, }, /* 1054 */\n  {    99,     21,     12,      0,      0,  28672,    322, }, /* 1055 */\n  {    99,     21,     12,      0,      0,  28672,    332, }, /* 1056 */\n  {    99,     17,     12,      0,      0,  12288,    130, }, /* 1057 */\n  {    99,     21,     12,      0,      0,   8192,     74, }, /* 1058 */\n  {    99,     13,     12,      0,      0,  10240,    334, }, /* 1059 */\n  {     0,      9,     12,      0,     32,  18432,    336, }, /* 1060 */\n  {    99,     24,     12,      0,      0,  28672,    338, }, /* 1061 */\n  {     0,      5,     12,      0,    -32,  18432,    340, }, /* 1062 */\n  {    99,     21,     12,      0,      0,  29036,    128, }, /* 1063 */\n  {    99,     22,     12,      0,      0,  29036,    342, }, /* 1064 */\n  {    99,     18,     12,      0,      0,  29036,    342, }, /* 1065 */\n  {    99,     21,     12,      0,      0,  29036,    110, }, /* 1066 */\n  {    99,      6,      3,      0,      0,  18804,    344, }, /* 1067 */\n  {    99,      1,      2,      0,      0,  28672,    346, }, /* 1068 */\n  {    39,      7,     12,      0,      0,  18432,     84, }, /* 1069 */\n  {    99,     21,     12,      0,      0,  18856,     74, }, /* 1070 */\n  {    99,     21,     12,      0,      0,  29096,     74, }, /* 1071 */\n  {    99,     21,     12,      0,      0,  18860,     74, }, /* 1072 */\n  {    99,     15,     12,      0,      0,  18864,     74, }, /* 1073 */\n  {    99,     26,     12,      0,      0,  18860,     74, }, /* 1074 */\n  {     1,     14,     12,      0,      0,  28672,     84, }, /* 1075 */\n  {     1,     15,     12,      0,      0,  28672,     74, }, /* 1076 */\n  {     1,     26,     12,      0,      0,  28672,     74, }, /* 1077 */\n  {     1,     26,     12,      0,      0,  18432,     74, }, /* 1078 */\n  {    50,      7,     12,      0,      0,  18432,     84, }, /* 1079 */\n  {    51,      7,     12,      0,      0,  18432,     84, }, /* 1080 */\n  {   106,     12,      3,      0,      0,  27060,     98, }, /* 1081 */\n  {    99,     15,     12,      0,      0,  10676,     74, }, /* 1082 */\n  {   104,      7,     12,      0,      0,  18432,     84, }, /* 1083 */\n  {   104,     15,     12,      0,      0,  18432,     74, }, /* 1084 */\n  {    32,      7,     12,      0,      0,  18432,     84, }, /* 1085 */\n  {    32,     14,     12,      0,      0,  18432,     84, }, /* 1086 */\n  {    73,      7,     12,      0,      0,  18432,     84, }, /* 1087 */\n  {    73,     12,      3,      0,      0,  26624,    106, }, /* 1088 */\n  {   107,      7,     12,      0,      0,  18432,     84, }, /* 1089 */\n  {   107,     21,     12,      0,      0,  18432,    110, }, /* 1090 */\n  {   111,      7,     12,      0,      0,  18432,     84, }, /* 1091 */\n  {   111,     21,     12,      0,      0,  18432,    110, }, /* 1092 */\n  {   111,     14,     12,      0,      0,  18432,     84, }, /* 1093 */\n  {   105,      9,     12,      0,     40,  18432,     76, }, /* 1094 */\n  {   105,      5,     12,      0,    -40,  18432,     78, }, /* 1095 */\n  {    40,      7,     12,      0,      0,  18432,     84, }, /* 1096 */\n  {   108,      7,     12,      0,      0,  18432,     84, }, /* 1097 */\n  {   108,     13,     12,      0,      0,  18432,    144, }, /* 1098 */\n  {    80,      9,     12,      0,     40,  18432,     76, }, /* 1099 */\n  {    80,      5,     12,      0,    -40,  18432,     78, }, /* 1100 */\n  {    66,      7,     12,      0,      0,  18432,     84, }, /* 1101 */\n  {    64,      7,     12,      0,      0,  18432,     84, }, /* 1102 */\n  {    64,     21,     12,      0,      0,  18432,     74, }, /* 1103 */\n  {   167,      9,     12,      0,     39,  18432,     76, }, /* 1104 */\n  {   167,      5,     12,      0,    -39,  18432,     78, }, /* 1105 */\n  {    96,      7,     12,      0,      0,  18432,     84, }, /* 1106 */\n  {    69,      7,     12,      0,      0,  18432,     84, }, /* 1107 */\n  {     0,      6,     12,      0,      0,  18432,     96, }, /* 1108 */\n  {    41,      7,     12,      0,      0,  34816,     84, }, /* 1109 */\n  {   128,      7,     12,      0,      0,  34816,     84, }, /* 1110 */\n  {   128,     21,     12,      0,      0,  34816,    110, }, /* 1111 */\n  {   128,     15,     12,      0,      0,  34816,     74, }, /* 1112 */\n  {   143,      7,     12,      0,      0,  34816,     84, }, /* 1113 */\n  {   143,     26,     12,      0,      0,  34816,     74, }, /* 1114 */\n  {   143,     15,     12,      0,      0,  34816,     74, }, /* 1115 */\n  {   142,      7,     12,      0,      0,  34816,     84, }, /* 1116 */\n  {   142,     15,     12,      0,      0,  34816,     74, }, /* 1117 */\n  {   149,      7,     12,      0,      0,  34816,     84, }, /* 1118 */\n  {   149,     15,     12,      0,      0,  34816,     74, }, /* 1119 */\n  {   115,      7,     12,      0,      0,  34816,     84, }, /* 1120 */\n  {   115,     15,     12,      0,      0,  34816,     74, }, /* 1121 */\n  {   115,     21,     12,      0,      0,  28672,    110, }, /* 1122 */\n  {    52,      7,     12,      0,      0,  34816,     84, }, /* 1123 */\n  {    52,     21,     12,      0,      0,  34816,     74, }, /* 1124 */\n  {    61,      7,     12,      0,      0,  34816,     84, }, /* 1125 */\n  {   134,      7,     12,      0,      0,  34816,     84, }, /* 1126 */\n  {   134,     15,     12,      0,      0,  34816,     74, }, /* 1127 */\n  {   112,      7,     12,      0,      0,  34816,     84, }, /* 1128 */\n  {   112,     12,      3,      0,      0,  26624,    106, }, /* 1129 */\n  {   112,     12,      3,      0,      0,  26624,     98, }, /* 1130 */\n  {   112,     12,      3,      0,      0,  26624,    158, }, /* 1131 */\n  {   112,     15,     12,      0,      0,  34816,     74, }, /* 1132 */\n  {   112,     21,     12,      0,      0,  34816,     74, }, /* 1133 */\n  {   112,     21,     12,      0,      0,  34816,    128, }, /* 1134 */\n  {   129,      7,     12,      0,      0,  34816,     84, }, /* 1135 */\n  {   129,     15,     12,      0,      0,  34816,     74, }, /* 1136 */\n  {   129,     21,     12,      0,      0,  34816,     74, }, /* 1137 */\n  {   141,      7,     12,      0,      0,  34816,     84, }, /* 1138 */\n  {   141,     15,     12,      0,      0,  34816,     74, }, /* 1139 */\n  {    71,      7,     12,      0,      0,  34816,     84, }, /* 1140 */\n  {    71,     26,     12,      0,      0,  34816,     74, }, /* 1141 */\n  {    71,     12,      3,      0,      0,  26624,     98, }, /* 1142 */\n  {    71,     15,     12,      0,      0,  34816,     74, }, /* 1143 */\n  {    71,     21,     12,      0,      0,  34816,    110, }, /* 1144 */\n  {    71,     21,     12,      0,      0,  35256,    110, }, /* 1145 */\n  {    71,     21,     12,      0,      0,  34816,     74, }, /* 1146 */\n  {    53,      7,     12,      0,      0,  34816,     84, }, /* 1147 */\n  {    53,     21,     12,      0,      0,  28672,     74, }, /* 1148 */\n  {    53,     21,     12,      0,      0,  28672,    110, }, /* 1149 */\n  {   130,      7,     12,      0,      0,  34816,     84, }, /* 1150 */\n  {   130,     15,     12,      0,      0,  34816,     74, }, /* 1151 */\n  {   131,      7,     12,      0,      0,  34816,     84, }, /* 1152 */\n  {   131,     15,     12,      0,      0,  34816,     74, }, /* 1153 */\n  {    74,      7,     12,      0,      0,  34816,     84, }, /* 1154 */\n  {    74,     21,     12,      0,      0,  34816,    110, }, /* 1155 */\n  {    74,     15,     12,      0,      0,  34816,     74, }, /* 1156 */\n  {    57,      7,     12,      0,      0,  34816,     84, }, /* 1157 */\n  {    78,      9,     12,      0,     64,  34816,     76, }, /* 1158 */\n  {    78,      5,     12,      0,    -64,  34816,     78, }, /* 1159 */\n  {    78,     15,     12,      0,      0,  34816,     74, }, /* 1160 */\n  {    85,      7,     12,      0,      0,      0,     84, }, /* 1161 */\n  {    85,      7,     12,      0,      0,      0,    314, }, /* 1162 */\n  {    85,     12,      3,      0,      0,  26624,    132, }, /* 1163 */\n  {    85,     13,     12,      0,      0,   2048,    144, }, /* 1164 */\n  {    92,     13,     12,      0,      0,   2048,    144, }, /* 1165 */\n  {    92,      7,     12,      0,      0,  34816,     84, }, /* 1166 */\n  {    92,      6,     12,      0,      0,  34816,     96, }, /* 1167 */\n  {    92,      9,     12,      0,     32,  34816,     76, }, /* 1168 */\n  {    92,     12,      3,      0,      0,  26624,    132, }, /* 1169 */\n  {    92,     12,      3,      0,      0,  26624,    164, }, /* 1170 */\n  {    92,     12,      3,      0,      0,  26624,     98, }, /* 1171 */\n  {    92,     17,     12,      0,      0,  28672,    130, }, /* 1172 */\n  {    92,      6,     12,      0,      0,  34816,    138, }, /* 1173 */\n  {    92,      5,     12,      0,    -32,  34816,     78, }, /* 1174 */\n  {    92,     25,     12,      0,      0,  34816,    122, }, /* 1175 */\n  {     5,     15,     12,      0,      0,   2048,     74, }, /* 1176 */\n  {    88,      7,     12,      0,      0,  34816,     84, }, /* 1177 */\n  {    88,     12,      3,      0,      0,  26624,    106, }, /* 1178 */\n  {    88,     17,     12,      0,      0,  34816,    130, }, /* 1179 */\n  {   159,      7,     12,      0,      0,  34816,     84, }, /* 1180 */\n  {   159,     15,     12,      0,      0,  34816,     74, }, /* 1181 */\n  {    86,      7,     12,      0,      0,      0,     84, }, /* 1182 */\n  {    86,     12,      3,      0,      0,  26624,     98, }, /* 1183 */\n  {    86,     15,     12,      0,      0,      0,     74, }, /* 1184 */\n  {    86,     21,     12,      0,      0,      0,    128, }, /* 1185 */\n  {    90,      7,     12,      0,      0,  34816,     84, }, /* 1186 */\n  {    90,     12,      3,      0,      0,  26624,     98, }, /* 1187 */\n  {    90,     21,     12,      0,      0,  34816,    128, }, /* 1188 */\n  {   163,      7,     12,      0,      0,  34816,     84, }, /* 1189 */\n  {   163,     15,     12,      0,      0,  34816,     74, }, /* 1190 */\n  {   160,      7,     12,      0,      0,  34816,     84, }, /* 1191 */\n  {   133,     10,      5,      0,      0,  18432,    154, }, /* 1192 */\n  {   133,     12,      3,      0,      0,  26624,    106, }, /* 1193 */\n  {   133,      7,     12,      0,      0,  18432,     84, }, /* 1194 */\n  {   133,     12,      3,      0,      0,  26624,    158, }, /* 1195 */\n  {   133,     21,     12,      0,      0,  18432,    128, }, /* 1196 */\n  {   133,     21,     12,      0,      0,  18432,    110, }, /* 1197 */\n  {   133,     15,     12,      0,      0,  28672,     74, }, /* 1198 */\n  {   133,     13,     12,      0,      0,  18432,    144, }, /* 1199 */\n  {   133,     12,      3,      0,      0,  26624,    290, }, /* 1200 */\n  {    58,     12,      3,      0,      0,  26624,    106, }, /* 1201 */\n  {    58,     10,      5,      0,      0,  18432,    154, }, /* 1202 */\n  {    58,      7,     12,      0,      0,  18432,     84, }, /* 1203 */\n  {    58,     12,      3,      0,      0,  26624,    158, }, /* 1204 */\n  {    58,     12,      3,      0,      0,  26624,     98, }, /* 1205 */\n  {    58,     21,     12,      0,      0,  18432,     74, }, /* 1206 */\n  {    58,      1,      4,      0,      0,  18432,    134, }, /* 1207 */\n  {    58,     21,     12,      0,      0,  18432,    128, }, /* 1208 */\n  {   136,      7,     12,      0,      0,  18432,     84, }, /* 1209 */\n  {   136,     13,     12,      0,      0,  18432,    144, }, /* 1210 */\n  {    60,     12,      3,      0,      0,  26624,    106, }, /* 1211 */\n  {    60,      7,     12,      0,      0,  18432,     84, }, /* 1212 */\n  {    60,     10,      5,      0,      0,  18432,    154, }, /* 1213 */\n  {    60,     12,      3,      0,      0,  26624,    158, }, /* 1214 */\n  {    60,     13,     12,      0,      0,  18432,    144, }, /* 1215 */\n  {    60,     21,     12,      0,      0,  18432,     74, }, /* 1216 */\n  {    60,     21,     12,      0,      0,  18432,    128, }, /* 1217 */\n  {    70,      7,     12,      0,      0,  18432,     84, }, /* 1218 */\n  {    70,     12,      3,      0,      0,  26624,     98, }, /* 1219 */\n  {    70,     21,     12,      0,      0,  18432,     74, }, /* 1220 */\n  {    62,     12,      3,      0,      0,  26624,    106, }, /* 1221 */\n  {    62,     10,      5,      0,      0,  18432,    154, }, /* 1222 */\n  {    62,      7,     12,      0,      0,  18432,     84, }, /* 1223 */\n  {    62,     10,      3,      0,      0,  18432,    188, }, /* 1224 */\n  {    62,      7,      4,      0,      0,  18432,     84, }, /* 1225 */\n  {    62,     21,     12,      0,      0,  18432,    128, }, /* 1226 */\n  {    62,     21,     12,      0,      0,  18432,     74, }, /* 1227 */\n  {    62,     12,      3,      0,      0,  26624,    104, }, /* 1228 */\n  {    62,     12,      3,      0,      0,  26624,     98, }, /* 1229 */\n  {    62,     13,     12,      0,      0,  18432,    144, }, /* 1230 */\n  {    17,     15,     12,      0,      0,  18432,     74, }, /* 1231 */\n  {    68,      7,     12,      0,      0,  18432,     84, }, /* 1232 */\n  {    68,     10,      5,      0,      0,  18432,    154, }, /* 1233 */\n  {    68,     12,      3,      0,      0,  26624,    106, }, /* 1234 */\n  {    68,     10,      3,      0,      0,  18432,    188, }, /* 1235 */\n  {    68,     12,      3,      0,      0,  26624,     98, }, /* 1236 */\n  {    68,     12,      3,      0,      0,  26624,    162, }, /* 1237 */\n  {    68,     21,     12,      0,      0,  18432,    128, }, /* 1238 */\n  {    68,     21,     12,      0,      0,  18432,    110, }, /* 1239 */\n  {    68,     21,     12,      0,      0,  18432,     74, }, /* 1240 */\n  {    77,      7,     12,      0,      0,  18432,     84, }, /* 1241 */\n  {    77,     21,     12,      0,      0,  18432,    128, }, /* 1242 */\n  {    75,      7,     12,      0,      0,  18432,     84, }, /* 1243 */\n  {    75,     12,      3,      0,      0,  26624,    106, }, /* 1244 */\n  {    75,     10,      5,      0,      0,  18432,    154, }, /* 1245 */\n  {    75,     12,      3,      0,      0,  26624,     98, }, /* 1246 */\n  {    75,     12,      3,      0,      0,  26624,    158, }, /* 1247 */\n  {    75,     13,     12,      0,      0,  18432,    144, }, /* 1248 */\n  {    67,     12,      3,      0,      0,  26624,    106, }, /* 1249 */\n  {    67,     12,      3,      0,      0,  26836,    106, }, /* 1250 */\n  {    67,     10,      5,      0,      0,  18432,    154, }, /* 1251 */\n  {    67,     10,      5,      0,      0,  18644,    154, }, /* 1252 */\n  {    67,      7,     12,      0,      0,  18432,     84, }, /* 1253 */\n  {   106,     12,      3,      0,      0,  26836,     98, }, /* 1254 */\n  {    67,     12,      3,      0,      0,  26836,     98, }, /* 1255 */\n  {    67,     10,      3,      0,      0,  18432,    160, }, /* 1256 */\n  {    67,     10,      3,      0,      0,  18432,    188, }, /* 1257 */\n  {    67,      7,     12,      0,      0,  18432,    348, }, /* 1258 */\n  {    67,     12,      3,      0,      0,  26624,     98, }, /* 1259 */\n  {    97,      7,     12,      0,      0,  18432,     84, }, /* 1260 */\n  {    97,     10,      3,      0,      0,  18432,    160, }, /* 1261 */\n  {    97,     10,      5,      0,      0,  18432,    154, }, /* 1262 */\n  {    97,     12,      3,      0,      0,  26624,    106, }, /* 1263 */\n  {    97,     12,      3,      0,      0,  26624,    158, }, /* 1264 */\n  {    97,     10,      3,      0,      0,  18432,    188, }, /* 1265 */\n  {    97,      7,      4,      0,      0,  18432,     84, }, /* 1266 */\n  {    97,     12,      3,      0,      0,  26624,    164, }, /* 1267 */\n  {    97,      7,     12,      0,      0,  18432,    350, }, /* 1268 */\n  {    97,     21,     12,      0,      0,  18432,    128, }, /* 1269 */\n  {    97,     21,     12,      0,      0,  18432,     74, }, /* 1270 */\n  {    97,     12,      3,      0,      0,  26624,     98, }, /* 1271 */\n  {   153,      7,     12,      0,      0,  18432,     84, }, /* 1272 */\n  {   153,     10,      5,      0,      0,  18432,    154, }, /* 1273 */\n  {   153,     12,      3,      0,      0,  26624,    106, }, /* 1274 */\n  {   153,     12,      3,      0,      0,  26624,    158, }, /* 1275 */\n  {   153,     12,      3,      0,      0,  26624,     98, }, /* 1276 */\n  {   153,     21,     12,      0,      0,  18432,    128, }, /* 1277 */\n  {   153,     21,     12,      0,      0,  18432,    110, }, /* 1278 */\n  {   153,     21,     12,      0,      0,  18432,     74, }, /* 1279 */\n  {   153,     13,     12,      0,      0,  18432,    144, }, /* 1280 */\n  {   153,     12,      3,      0,      0,  26624,    104, }, /* 1281 */\n  {    76,      7,     12,      0,      0,  18432,     84, }, /* 1282 */\n  {    76,     10,      3,      0,      0,  18432,    160, }, /* 1283 */\n  {    76,     10,      5,      0,      0,  18432,    154, }, /* 1284 */\n  {    76,     12,      3,      0,      0,  26624,    106, }, /* 1285 */\n  {    76,     12,      3,      0,      0,  26624,    158, }, /* 1286 */\n  {    76,     12,      3,      0,      0,  26624,     98, }, /* 1287 */\n  {    76,     21,     12,      0,      0,  18432,     74, }, /* 1288 */\n  {    76,     13,     12,      0,      0,  18432,    144, }, /* 1289 */\n  {   145,      7,     12,      0,      0,  18432,     84, }, /* 1290 */\n  {   145,     10,      3,      0,      0,  18432,    160, }, /* 1291 */\n  {   145,     10,      5,      0,      0,  18432,    154, }, /* 1292 */\n  {   145,     12,      3,      0,      0,  26624,    106, }, /* 1293 */\n  {   145,     12,      3,      0,      0,  26624,    158, }, /* 1294 */\n  {   145,     12,      3,      0,      0,  26624,     98, }, /* 1295 */\n  {   145,     21,     12,      0,      0,  18432,     74, }, /* 1296 */\n  {   145,     21,     12,      0,      0,  18432,    128, }, /* 1297 */\n  {   145,     21,     12,      0,      0,  18432,    110, }, /* 1298 */\n  {   145,     21,     12,      0,      0,  18432,    190, }, /* 1299 */\n  {    72,      7,     12,      0,      0,  18432,     84, }, /* 1300 */\n  {    72,     10,      5,      0,      0,  18432,    154, }, /* 1301 */\n  {    72,     12,      3,      0,      0,  26624,    106, }, /* 1302 */\n  {    72,     12,      3,      0,      0,  26624,    158, }, /* 1303 */\n  {    72,     21,     12,      0,      0,  18432,    128, }, /* 1304 */\n  {    72,     21,     12,      0,      0,  18432,     74, }, /* 1305 */\n  {    72,     13,     12,      0,      0,  18432,    144, }, /* 1306 */\n  {    63,      7,     12,      0,      0,  18432,     84, }, /* 1307 */\n  {    63,     12,      3,      0,      0,  26624,    106, }, /* 1308 */\n  {    63,     10,      5,      0,      0,  18432,    154, }, /* 1309 */\n  {    63,     10,      3,      0,      0,  18432,    188, }, /* 1310 */\n  {    63,     12,      3,      0,      0,  26624,     98, }, /* 1311 */\n  {    63,     21,     12,      0,      0,  18432,     74, }, /* 1312 */\n  {    63,     13,     12,      0,      0,  18432,    144, }, /* 1313 */\n  {   147,      7,     12,      0,      0,  18432,     84, }, /* 1314 */\n  {   147,     12,      3,      0,      0,  26624,    106, }, /* 1315 */\n  {   147,     10,      5,      0,      0,  18432,    154, }, /* 1316 */\n  {   147,     10,     12,      0,      0,  18432,    154, }, /* 1317 */\n  {   147,     12,      3,      0,      0,  26624,    158, }, /* 1318 */\n  {   147,     13,     12,      0,      0,  18432,    144, }, /* 1319 */\n  {   147,     15,     12,      0,      0,  18432,     74, }, /* 1320 */\n  {   147,     21,     12,      0,      0,  18432,    128, }, /* 1321 */\n  {   147,     26,     12,      0,      0,  18432,     74, }, /* 1322 */\n  {    83,      7,     12,      0,      0,  18432,     84, }, /* 1323 */\n  {    83,     10,      5,      0,      0,  18432,    154, }, /* 1324 */\n  {    83,     12,      3,      0,      0,  26624,    106, }, /* 1325 */\n  {    83,     12,      3,      0,      0,  26624,    158, }, /* 1326 */\n  {    83,     12,      3,      0,      0,  26624,     98, }, /* 1327 */\n  {    83,     21,     12,      0,      0,  18432,     74, }, /* 1328 */\n  {   146,      9,     12,      0,     32,  18432,     76, }, /* 1329 */\n  {   146,      5,     12,      0,    -32,  18432,     78, }, /* 1330 */\n  {   146,     13,     12,      0,      0,  18432,    144, }, /* 1331 */\n  {   146,     15,     12,      0,      0,  18432,     74, }, /* 1332 */\n  {   146,      7,     12,      0,      0,  18432,     84, }, /* 1333 */\n  {   164,      7,     12,      0,      0,  18432,     84, }, /* 1334 */\n  {   164,     10,      3,      0,      0,  18432,    160, }, /* 1335 */\n  {   164,     10,      5,      0,      0,  18432,    154, }, /* 1336 */\n  {   164,     12,      3,      0,      0,  26624,    106, }, /* 1337 */\n  {   164,     10,      3,      0,      0,  18432,    188, }, /* 1338 */\n  {   164,     12,      3,      0,      0,  26624,    158, }, /* 1339 */\n  {   164,      7,      4,      0,      0,  18432,     84, }, /* 1340 */\n  {   164,     12,      3,      0,      0,  26624,     98, }, /* 1341 */\n  {   164,     21,     12,      0,      0,  18432,    128, }, /* 1342 */\n  {   164,     21,     12,      0,      0,  18432,     74, }, /* 1343 */\n  {   164,     13,     12,      0,      0,  18432,    144, }, /* 1344 */\n  {    87,      7,     12,      0,      0,  18432,     84, }, /* 1345 */\n  {    87,     10,      5,      0,      0,  18432,    154, }, /* 1346 */\n  {    87,     12,      3,      0,      0,  26624,    106, }, /* 1347 */\n  {    87,     12,      3,      0,      0,  26624,    158, }, /* 1348 */\n  {    87,     21,     12,      0,      0,  18432,     74, }, /* 1349 */\n  {   156,      7,     12,      0,      0,  18432,     84, }, /* 1350 */\n  {   156,     12,      3,      0,      0,  26624,    106, }, /* 1351 */\n  {   156,     12,      3,      0,      0,  18432,    106, }, /* 1352 */\n  {   156,     12,      3,      0,      0,  26624,    104, }, /* 1353 */\n  {   156,     12,      3,      0,      0,  26624,    158, }, /* 1354 */\n  {   156,     10,      5,      0,      0,  18432,    154, }, /* 1355 */\n  {   156,      7,      4,      0,      0,  18432,     84, }, /* 1356 */\n  {   156,     21,     12,      0,      0,  18432,     74, }, /* 1357 */\n  {   156,     21,     12,      0,      0,  18432,    128, }, /* 1358 */\n  {   155,      7,     12,      0,      0,  18432,     84, }, /* 1359 */\n  {   155,     12,      3,      0,      0,  26624,    106, }, /* 1360 */\n  {   155,     10,      5,      0,      0,  18432,    154, }, /* 1361 */\n  {   155,      7,      4,      0,      0,  18432,     84, }, /* 1362 */\n  {   155,     12,      3,      0,      0,  26624,    352, }, /* 1363 */\n  {   155,     12,      3,      0,      0,  26624,    158, }, /* 1364 */\n  {   155,     21,     12,      0,      0,  18432,     74, }, /* 1365 */\n  {   155,     21,     12,      0,      0,  18432,    128, }, /* 1366 */\n  {   155,     21,     12,      0,      0,  18432,    110, }, /* 1367 */\n  {   144,      7,     12,      0,      0,  18432,     84, }, /* 1368 */\n  {    95,      7,     12,      0,      0,  18432,     84, }, /* 1369 */\n  {    95,     21,     12,      0,      0,  18432,     74, }, /* 1370 */\n  {    95,     13,     12,      0,      0,  18432,    144, }, /* 1371 */\n  {   151,      7,     12,      0,      0,  18432,     84, }, /* 1372 */\n  {   151,     10,      5,      0,      0,  18432,    154, }, /* 1373 */\n  {   151,     12,      3,      0,      0,  26624,    106, }, /* 1374 */\n  {   151,     12,      3,      0,      0,  18432,    158, }, /* 1375 */\n  {   151,     21,     12,      0,      0,  18432,    128, }, /* 1376 */\n  {   151,     21,     12,      0,      0,  18432,    110, }, /* 1377 */\n  {   151,     21,     12,      0,      0,  18432,     74, }, /* 1378 */\n  {   151,     13,     12,      0,      0,  18432,    144, }, /* 1379 */\n  {   151,     15,     12,      0,      0,  18432,     74, }, /* 1380 */\n  {   152,     21,     12,      0,      0,  18432,     74, }, /* 1381 */\n  {   152,     21,     12,      0,      0,  18432,    110, }, /* 1382 */\n  {   152,      7,     12,      0,      0,  18432,     84, }, /* 1383 */\n  {   152,     12,      3,      0,      0,  26624,    106, }, /* 1384 */\n  {   152,     10,      5,      0,      0,  18432,    154, }, /* 1385 */\n  {    82,      7,     12,      0,      0,  18432,     84, }, /* 1386 */\n  {    82,     12,      3,      0,      0,  26624,    106, }, /* 1387 */\n  {    82,     12,      3,      0,      0,  26624,     98, }, /* 1388 */\n  {    82,     12,      3,      0,      0,  26624,    158, }, /* 1389 */\n  {    82,      7,      4,      0,      0,  18432,     84, }, /* 1390 */\n  {    82,     13,     12,      0,      0,  18432,    144, }, /* 1391 */\n  {    84,      7,     12,      0,      0,  18432,     84, }, /* 1392 */\n  {    84,     10,      5,      0,      0,  18432,    154, }, /* 1393 */\n  {    84,     12,      3,      0,      0,  26624,    106, }, /* 1394 */\n  {    84,     12,      3,      0,      0,  26624,    158, }, /* 1395 */\n  {    84,     13,     12,      0,      0,  18432,    144, }, /* 1396 */\n  {   157,      7,     12,      0,      0,  18432,     84, }, /* 1397 */\n  {   157,     12,      3,      0,      0,  26624,    106, }, /* 1398 */\n  {   157,     10,      5,      0,      0,  18432,    154, }, /* 1399 */\n  {   157,     21,     12,      0,      0,  18432,    128, }, /* 1400 */\n  {   168,     12,      3,      0,      0,  26624,    106, }, /* 1401 */\n  {   168,      7,      4,      0,      0,  18432,     84, }, /* 1402 */\n  {   168,     10,      5,      0,      0,  18432,    154, }, /* 1403 */\n  {   168,      7,     12,      0,      0,  18432,     84, }, /* 1404 */\n  {   168,     10,      3,      0,      0,  18432,    188, }, /* 1405 */\n  {   168,     12,      3,      0,      0,  26624,    158, }, /* 1406 */\n  {   168,     21,     12,      0,      0,  18432,    128, }, /* 1407 */\n  {   168,     21,     12,      0,      0,  18432,     74, }, /* 1408 */\n  {   168,     13,     12,      0,      0,  18432,    144, }, /* 1409 */\n  {   168,     12,      3,      0,      0,  26624,     98, }, /* 1410 */\n  {    13,     15,     12,      0,      0,  18432,     74, }, /* 1411 */\n  {    13,     21,     12,      0,      0,  18432,     74, }, /* 1412 */\n  {   114,      7,     12,      0,      0,  18432,     84, }, /* 1413 */\n  {   114,     14,     12,      0,      0,  18432,     84, }, /* 1414 */\n  {   114,     21,     12,      0,      0,  18432,    110, }, /* 1415 */\n  {    89,      7,     12,      0,      0,  18432,     84, }, /* 1416 */\n  {    89,     21,     12,      0,      0,  18432,     74, }, /* 1417 */\n  {   125,      7,     12,      0,      0,  18432,     84, }, /* 1418 */\n  {   125,      1,      2,      0,      0,  18432,    346, }, /* 1419 */\n  {   125,     12,      3,      0,      0,  26624,    104, }, /* 1420 */\n  {   125,     12,      3,      0,      0,  26624,     98, }, /* 1421 */\n  {   148,      7,     12,      0,      0,  18432,     84, }, /* 1422 */\n  {    93,      7,     12,      0,      0,  18432,     84, }, /* 1423 */\n  {    93,     12,      3,      0,      0,  26624,    106, }, /* 1424 */\n  {    93,     10,      5,      0,      0,  18432,    154, }, /* 1425 */\n  {    93,     12,      3,      0,      0,  26624,    158, }, /* 1426 */\n  {    93,     13,     12,      0,      0,  18432,    144, }, /* 1427 */\n  {   140,      7,     12,      0,      0,  18432,     84, }, /* 1428 */\n  {   140,     13,     12,      0,      0,  18432,    144, }, /* 1429 */\n  {   140,     21,     12,      0,      0,  18432,    128, }, /* 1430 */\n  {   166,      7,     12,      0,      0,  18432,     84, }, /* 1431 */\n  {   166,     13,     12,      0,      0,  18432,    144, }, /* 1432 */\n  {   137,      7,     12,      0,      0,  18432,     84, }, /* 1433 */\n  {   137,     12,      3,      0,      0,  26624,     98, }, /* 1434 */\n  {   137,     21,     12,      0,      0,  18432,    128, }, /* 1435 */\n  {   138,      7,     12,      0,      0,  18432,     84, }, /* 1436 */\n  {   138,     12,      3,      0,      0,  26624,     98, }, /* 1437 */\n  {   138,     21,     12,      0,      0,  18432,    128, }, /* 1438 */\n  {   138,     21,     12,      0,      0,  18432,    110, }, /* 1439 */\n  {   138,     21,     12,      0,      0,  18432,     74, }, /* 1440 */\n  {   138,     26,     12,      0,      0,  18432,     74, }, /* 1441 */\n  {   138,      6,     12,      0,      0,  18432,    148, }, /* 1442 */\n  {   138,      6,     12,      0,      0,  18432,    138, }, /* 1443 */\n  {   138,     13,     12,      0,      0,  18432,    144, }, /* 1444 */\n  {   138,     15,     12,      0,      0,  18432,     74, }, /* 1445 */\n  {   170,      6,     12,      0,      0,  18432,    148, }, /* 1446 */\n  {   170,      7,     12,      0,      0,  18432,     84, }, /* 1447 */\n  {   170,      7,      7,      0,      0,  18432,     84, }, /* 1448 */\n  {   170,      6,     12,      0,      0,  18432,     94, }, /* 1449 */\n  {   170,     21,     12,      0,      0,  18432,     74, }, /* 1450 */\n  {   170,     21,     12,      0,      0,  18432,    128, }, /* 1451 */\n  {   170,     13,     12,      0,      0,  18432,    144, }, /* 1452 */\n  {   158,      9,     12,      0,     32,  18432,     76, }, /* 1453 */\n  {   158,      5,     12,      0,    -32,  18432,     78, }, /* 1454 */\n  {   158,     15,     12,      0,      0,  18432,     74, }, /* 1455 */\n  {   158,     21,     12,      0,      0,  18432,    110, }, /* 1456 */\n  {   158,     21,     12,      0,      0,  18432,    128, }, /* 1457 */\n  {   158,     21,     12,      0,      0,  18432,     74, }, /* 1458 */\n  {   135,      7,     12,      0,      0,  18432,     84, }, /* 1459 */\n  {   135,     12,      3,      0,      0,  26624,    106, }, /* 1460 */\n  {   135,     10,      5,      0,      0,  18432,    154, }, /* 1461 */\n  {   135,     12,      3,      0,      0,  26624,    132, }, /* 1462 */\n  {   135,      6,     12,      0,      0,  18432,     94, }, /* 1463 */\n  {    81,      6,     12,      0,      0,  18432,    138, }, /* 1464 */\n  {   154,      6,     12,      0,      0,  18432,    138, }, /* 1465 */\n  {    30,     21,     12,      0,      0,  28672,     74, }, /* 1466 */\n  {   165,     12,      3,      0,      0,  26624,    354, }, /* 1467 */\n  {    30,     10,      3,      0,      0,  18432,    356, }, /* 1468 */\n  {    81,      7,     12,      0,      0,  18432,    304, }, /* 1469 */\n  {   165,      7,     12,      0,      0,  18432,    304, }, /* 1470 */\n  {    28,      6,     12,      0,      0,  18432,     94, }, /* 1471 */\n  {   154,      7,     12,      0,      0,  18432,    304, }, /* 1472 */\n  {    65,      7,     12,      0,      0,  18432,     84, }, /* 1473 */\n  {    65,     26,     12,      0,      0,  18432,     74, }, /* 1474 */\n  {    65,     12,      3,      0,      0,  26624,    104, }, /* 1475 */\n  {    65,     12,      3,      0,      0,  26624,    106, }, /* 1476 */\n  {    65,     21,     12,      0,      0,  18432,    128, }, /* 1477 */\n  {    99,      1,      2,      0,      0,   6472,     66, }, /* 1478 */\n  {    99,     13,     12,      0,      0,  10240,    144, }, /* 1479 */\n  {    99,     10,      3,      0,      0,  18432,    358, }, /* 1480 */\n  {    99,     10,      3,      0,      0,  18432,    306, }, /* 1481 */\n  {     1,     12,      3,      0,      0,  26624,    104, }, /* 1482 */\n  {    99,     25,     12,      0,      0,  28672,    360, }, /* 1483 */\n  {    99,     13,     12,      0,      0,  10240,    226, }, /* 1484 */\n  {   150,     26,     12,      0,      0,  18432,     74, }, /* 1485 */\n  {   150,     12,      3,      0,      0,  26624,    104, }, /* 1486 */\n  {   150,     21,     12,      0,      0,  18432,    110, }, /* 1487 */\n  {   150,     21,     12,      0,      0,  18432,    128, }, /* 1488 */\n  {   150,     21,     12,      0,      0,  18432,     74, }, /* 1489 */\n  {    44,     12,      3,      0,      0,  26624,    106, }, /* 1490 */\n  {     2,      6,     12,      0,      0,  18432,     92, }, /* 1491 */\n  {   161,      7,     12,      0,      0,  18432,     84, }, /* 1492 */\n  {   161,     12,      3,      0,      0,  26624,     98, }, /* 1493 */\n  {   161,      6,     12,      0,      0,  18432,    148, }, /* 1494 */\n  {   161,      6,     12,      0,      0,  18432,    138, }, /* 1495 */\n  {   161,     13,     12,      0,      0,  18432,    144, }, /* 1496 */\n  {   161,     26,     12,      0,      0,  18432,     74, }, /* 1497 */\n  {    91,      7,     12,      0,      0,  18432,     84, }, /* 1498 */\n  {    91,     12,      3,      0,      0,  26624,     98, }, /* 1499 */\n  {   162,      7,     12,      0,      0,  18432,     84, }, /* 1500 */\n  {   162,     12,      3,      0,      0,  26624,     98, }, /* 1501 */\n  {   162,     13,     12,      0,      0,  18432,    144, }, /* 1502 */\n  {   162,     23,     12,      0,      0,  14336,     74, }, /* 1503 */\n  {   169,      7,     12,      0,      0,  18432,     84, }, /* 1504 */\n  {   169,      6,     12,      0,      0,  18432,    148, }, /* 1505 */\n  {   169,     12,      3,      0,      0,  26624,    104, }, /* 1506 */\n  {   169,     13,     12,      0,      0,  18432,    144, }, /* 1507 */\n  {    94,      7,     12,      0,      0,  18432,     84, }, /* 1508 */\n  {    94,     12,      3,      0,      0,  26624,     98, }, /* 1509 */\n  {    94,     12,      3,      0,      0,  26624,    164, }, /* 1510 */\n  {    94,     13,     12,      0,      0,  18432,    144, }, /* 1511 */\n  {    94,     21,     12,      0,      0,  18432,     74, }, /* 1512 */\n  {   139,      7,     12,      0,      0,  34816,     84, }, /* 1513 */\n  {   139,     15,     12,      0,      0,  34816,     74, }, /* 1514 */\n  {   139,     12,      3,      0,      0,  26624,     98, }, /* 1515 */\n  {    79,      9,     12,      0,     34,  34816,     76, }, /* 1516 */\n  {    79,      5,     12,      0,    -34,  34816,     78, }, /* 1517 */\n  {    79,     12,      3,      0,      0,  26624,    164, }, /* 1518 */\n  {    79,     12,      3,      0,      0,  26624,    106, }, /* 1519 */\n  {    79,     12,      3,      0,      0,  26624,     98, }, /* 1520 */\n  {    79,      6,     12,      0,      0,  34816,    148, }, /* 1521 */\n  {    79,     13,     12,      0,      0,  34816,    144, }, /* 1522 */\n  {    79,     21,     12,      0,      0,  34816,     74, }, /* 1523 */\n  {    99,     15,     12,      0,      0,      0,     74, }, /* 1524 */\n  {    99,     26,     12,      0,      0,      0,     74, }, /* 1525 */\n  {    99,     23,     12,      0,      0,      0,     74, }, /* 1526 */\n  {     5,      7,     12,      0,      0,      0,    254, }, /* 1527 */\n  {    99,     26,     14,      0,      0,  28672,    362, }, /* 1528 */\n  {    99,     26,     14,      0,      0,  28672,    364, }, /* 1529 */\n  {    98,      2,     14,      0,      0,  18432,    366, }, /* 1530 */\n  {    99,     26,     12,      0,      0,  18432,    368, }, /* 1531 */\n  {    99,     26,     14,      0,      0,  18432,    370, }, /* 1532 */\n  {    99,     26,     14,      0,      0,  18432,    364, }, /* 1533 */\n  {    99,     26,     11,      0,      0,  18432,    372, }, /* 1534 */\n  {    27,     26,     12,      0,      0,  18432,     74, }, /* 1535 */\n  {    99,     26,     14,      0,      0,  18432,    250, }, /* 1536 */\n  {    99,     26,     14,      0,      0,  18784,    364, }, /* 1537 */\n  {    99,     26,     14,      0,      0,  28672,    374, }, /* 1538 */\n  {    99,     26,     14,      0,      0,  28672,    376, }, /* 1539 */\n  {    99,     24,      3,      0,      0,  28672,    378, }, /* 1540 */\n  {    99,     26,     14,      0,      0,  28672,    380, }, /* 1541 */\n  {    99,      1,      3,      0,      0,   6144,    382, }, /* 1542 */\n};\n\nconst uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */\n  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* U+0000 */\n 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */\n 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, /* U+1000 */\n 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */\n 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, /* U+2000 */\n 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, /* U+2800 */\n 93, 94, 95, 96, 97, 98, 99,100,101,101,101,101,101,101,101,101, /* U+3000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+3800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+4000 */\n101,101,101,101,101,101,101,101,101,101,101,102,101,101,101,101, /* U+4800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+5000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+5800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+6000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+6800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+7000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+7800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+8000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+8800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+9000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+9800 */\n103,104,104,104,104,104,104,104,104,105,106,106,107,108,109,110, /* U+A000 */\n111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,119, /* U+A800 */\n120,121,122,123,124,125,119,120,121,122,123,124,125,119,120,121, /* U+B000 */\n122,123,124,125,119,120,121,122,123,124,125,119,120,121,122,123, /* U+B800 */\n124,125,119,120,121,122,123,124,125,119,120,121,122,123,124,125, /* U+C000 */\n119,120,121,122,123,124,125,119,120,121,122,123,124,125,119,120, /* U+C800 */\n121,122,123,124,125,119,120,121,122,123,124,125,119,120,121,126, /* U+D000 */\n127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, /* U+D800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+E000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+E800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F000 */\n128,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141, /* U+F800 */\n142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */\n157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */\n173,174,175,176,177,178,179,180,181,182,146,183,184,185,186,146, /* U+11000 */\n187,188,189,190,191,192,193,194,195,196,197,198,146,199,200,201, /* U+11800 */\n202,202,202,202,202,202,202,203,204,202,205,146,146,146,146,146, /* U+12000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,206, /* U+12800 */\n207,207,207,207,207,207,207,207,208,207,207,207,207,207,207,207, /* U+13000 */\n207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, /* U+13800 */\n207,207,207,207,207,207,207,209,210,210,210,210,211,146,146,146, /* U+14000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */\n146,146,212,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */\n213,213,213,213,214,215,216,217,146,146,218,146,219,220,221,222, /* U+16800 */\n223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17000 */\n223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17800 */\n223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, /* U+18000 */\n223,223,223,223,223,223,225,225,225,226,227,146,146,146,146,146, /* U+18800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,228, /* U+1A800 */\n229,230,231,232,232,233,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */\n146,146,146,146,146,146,146,146,234,235,146,146,146,146,146,146, /* U+1B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */\n146,146,146,146,146,146,146,146,236,237,236,236,236,238,239,240, /* U+1C800 */\n241,242,243,244,245,246,247,146,248,249,250,251,252,253,254,255, /* U+1D000 */\n256,256,256,256,257,258,146,146,146,146,146,146,146,146,259,146, /* U+1D800 */\n260,261,262,146,146,263,146,146,146,264,146,265,146,146,146,266, /* U+1E000 */\n267,268,269,270,270,270,270,270,271,272,273,270,274,275,270,270, /* U+1E800 */\n276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291, /* U+1F000 */\n292,293,294,295,296,297,236,298,281,281,281,281,281,281,281,299, /* U+1F800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+22000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+22800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+23000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+23800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+24000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+24800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+25000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+25800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+26000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+26800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+27000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+27800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,300,101,101, /* U+2A000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,301,101, /* U+2B000 */\n302,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,303,101,101, /* U+2C800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */\n101,101,101,101,101,101,101,304,101,101,101,101,305,146,146,146, /* U+2E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */\n129,129,129,129,306,146,146,146,146,146,146,146,146,146,146,307, /* U+2F800 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */\n101,101,101,101,101,101,308,101,101,101,101,101,101,101,101,101, /* U+31000 */\n101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+31800 */\n101,101,101,101,101,101,101,309,146,146,146,146,146,146,146,146, /* U+32000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+34000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+34800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+35000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+35800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+36000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+36800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+37000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+37800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+38000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+38800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+39000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+39800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+3F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+42000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+42800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+43000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+43800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+44000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+44800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+45000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+45800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+46000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+46800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+47000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+47800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+48000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+48800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+49000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+49800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+4F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+52000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+52800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+53000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+53800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+54000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+54800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+55000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+55800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+56000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+56800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+57000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+57800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+58000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+58800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+59000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+59800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+5F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+62000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+62800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+63000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+63800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+64000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+64800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+65000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+65800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+66000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+66800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+67000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+67800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+68000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+68800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+69000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+69800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+6F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+72000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+72800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+73000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+73800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+74000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+74800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+75000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+75800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+76000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+76800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+77000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+77800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+78000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+78800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+79000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+79800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+7F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+82000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+82800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+83000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+83800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+84000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+84800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+85000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+85800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+86000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+86800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+87000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+87800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+88000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+88800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+89000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+89800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+8F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+92000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+92800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+93000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+93800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+94000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+94800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+95000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+95800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+96000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+96800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+97000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+97800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+98000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+98800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+99000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+99800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9A000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9A800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9B000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9B800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9C000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9C800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9D000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9D800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+9F800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A2000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A2800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A3000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A3800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A4000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A4800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A5000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A5800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A6000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A6800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A7000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A7800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A8000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A8800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A9000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A9800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AA000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AA800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AB000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AB800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AC000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AC800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AD000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AD800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+AF800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B2000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B2800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B3000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B3800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B4000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B4800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B5000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B5800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B6000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B6800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B7000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B7800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B8000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B8800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B9000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B9800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BA000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BA800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BB000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BB800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BC000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BC800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BD000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BD800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+BF800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C2000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C2800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C3000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C3800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C4000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C4800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C5000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C5800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C6000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C6800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C7000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C7800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C8000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C8800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C9000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C9800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CA000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CA800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CB000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CB800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CC000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CC800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CD000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CD800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+CF800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D2000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D2800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D3000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D3800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D4000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D4800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D5000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D5800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D6000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D6800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D7000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D7800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D8000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D8800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D9000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D9800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DA000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DA800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DB000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DB800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DC000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DC800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DD000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DD800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+DF800 */\n310,311,312,313,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0000 */\n311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E3000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E3800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E4000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E4800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E5000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E5800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E6000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E6800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E7000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E7800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E8000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E8800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E9000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E9800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EA000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EA800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EB000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EB800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EC000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EC800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+ED000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+ED800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */\n146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+EF800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F2000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F2800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F3000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F3800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F4000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F4800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F5000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F5800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F6000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F6800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F7000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F7800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F8000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F8800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F9000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F9800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FA000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FA800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FB000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FB800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FC000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FC800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FD000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FD800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+FF800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+102000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+102800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+103000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+103800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+104000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+104800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+105000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+105800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+106000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+106800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+107000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+107800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+108000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+108800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+109000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+109800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10A000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10A800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10B000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10B800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10C000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10C800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10D000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10D800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */\n128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+10F800 */\n};\n\nconst uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */\n\n/* block 0 */\n  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  3,  4,  0,  0,\n  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  5,  5,  6,\n  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25, 26, 27, 26,  8,\n 13, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 30, 29, 29, 29, 29,\n 29, 29, 29, 31, 29, 29, 29, 29, 29, 29, 29, 15, 13, 16, 32, 33,\n 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 38, 36, 36, 36, 36,\n 36, 36, 36, 39, 36, 36, 36, 36, 36, 36, 36, 15, 27, 16, 27,  0,\n\n/* block 1 */\n 40, 40, 40, 40, 40, 41, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n 42, 43, 44, 44, 44, 44, 45, 43, 46, 47, 48, 49, 50, 51, 47, 46,\n 52, 53, 54, 54, 46, 55, 43, 56, 46, 54, 48, 57, 58, 58, 58, 43,\n 59, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n 59, 59, 59, 59, 59, 59, 59, 50, 59, 59, 59, 59, 59, 59, 59, 61,\n 62, 62, 62, 62, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,\n 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, 62, 62, 62, 62, 62, 64,\n\n/* block 2 */\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67,\n 68, 69, 65, 66, 65, 66, 65, 66, 70, 65, 66, 65, 66, 65, 66, 65,\n 66, 65, 66, 65, 66, 65, 66, 65, 66, 71, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 72, 65, 66, 65, 66, 65, 66, 73,\n\n/* block 3 */\n 74, 75, 65, 66, 65, 66, 76, 65, 66, 77, 77, 65, 66, 70, 78, 79,\n 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 86, 83, 87, 88, 89,\n 65, 66, 65, 66, 65, 66, 90, 65, 66, 90, 70, 70, 65, 66, 90, 65,\n 66, 91, 91, 65, 66, 65, 66, 92, 65, 66, 70, 93, 65, 66, 70, 94,\n 93, 93, 93, 93, 95, 96, 97, 98, 99,100,101,102,103, 65, 66, 65,\n 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,104, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 69,105,106,107, 65, 66,108,109, 65, 66, 65, 66, 65, 66, 65, 66,\n\n/* block 4 */\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n110, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,111, 65, 66,112,113,114,\n114, 65, 66,115,116,117, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66,\n118,119,120,121,122, 70,123,123, 70,124, 70,125,126, 70, 70, 70,\n123,127, 70,128,129,130,131, 70,132,133,131,134,135, 70, 70,133,\n 70,136,137, 70, 70,138, 70, 70, 70, 70, 70, 70, 70,139, 70, 70,\n\n/* block 5 */\n140, 70,141,140, 70, 70, 70,142,140,143,144,144,145, 70, 70, 70,\n 70, 70,146, 70, 93, 70, 70, 70, 70, 70, 70, 70, 70,147,148, 70,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\n149,149,150,149,149,149,149,149,149,151,151,152,153,152,152,152,\n154,154, 46, 46, 46, 46,151,155,151,155,155,155,151,156,151,151,\n157,157, 46, 46, 46, 46, 46,158, 46,159, 46, 46, 46, 46, 46, 46,\n149,149,149,149,149, 46, 46, 46, 46, 46,160,160,151, 46,152, 46,\n 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,\n\n/* block 6 */\n161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,\n174,177,176,178,176,176,176,176,176,176,176,176,176,176,176,176,\n179,176,176,180,181,179,176,176,176,176,176,176,176,182,179,176,\n183,184,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n176,176,185,176,176,186,176,176,176,176,176,176,176,176,176,187,\n176,176,176,176,176,176,176,176,188,189,189,189,189,176,190,176,\n176,176,176,191,191,191,191,191,191,191,191,191,191,191,191,191,\n192,193,192,193,194,195,192,193,196,196,197,198,198,198,199,200,\n\n/* block 7 */\n196,196,196,196,201, 46,202,203,204,204,204,196,205,196,206,206,\n207,208,209,208,208,210,208,208,211,212,213,208,214,208,208,208,\n215,216,196,217,208,208,218,208,208,219,208,208,220,221,221,221,\n222,223,224,223,223,225,223,223,226,227,228,223,229,223,223,223,\n230,231,232,233,223,223,234,223,223,235,223,223,236,237,237,238,\n239,240,241,242,242,243,244,245,192,193,192,193,192,193,192,193,\n192,193,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n248,249,250,251,252,253,254,192,193,255,192,193,256,257,257,257,\n\n/* block 8 */\n258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,\n259,259,260,259,261,259,259,259,259,259,259,259,259,259,262,259,\n259,263,264,259,259,259,259,259,259,259,265,259,259,259,259,259,\n266,266,267,266,268,266,266,266,266,266,266,266,266,266,269,266,\n266,270,271,266,266,266,266,266,266,266,272,266,266,266,266,266,\n273,273,273,273,273,273,274,273,274,273,273,273,273,273,273,273,\n275,276,277,278,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n\n/* block 9 */\n275,276,279,280,281,282,282,281,283,283,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n284,275,276,275,276,275,276,275,276,275,276,275,276,275,276,285,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n\n/* block 10 */\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n196,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,\n286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,\n286,286,286,286,286,286,286,196,196,287,288,288,288,288,288,289,\n290,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,\n291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,\n\n/* block 11 */\n291,291,291,291,291,291,291,292,290,293,294,196,196,295,295,296,\n297,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,\n298,298,299,298,298,298,298,298,298,298,298,298,298,298,298,298,\n300,300,300,300,300,300,300,300,300,300,300,300,300,300,301,300,\n302,300,300,303,300,304,302,304,297,297,297,297,297,297,297,297,\n305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,\n305,305,305,305,305,305,305,305,305,305,305,297,297,297,297,305,\n305,305,305,302,306,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 12 */\n307,307,307,307,307,308,309,309,310,311,311,312,313,314,315,315,\n316,316,316,316,316,316,316,316,316,316,316,317,318,319,319,320,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n322,321,321,321,321,321,321,321,321,321,321,323,323,323,323,323,\n323,323,323,324,325,325,316,326,327,316,316,316,316,316,316,316,\n328,328,328,328,328,328,328,328,328,328,311,329,329,314,321,321,\n324,321,321,330,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 13 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,331,321,316,316,316,316,316,316,332,308,315,333,\n333,316,316,332,316,334,334,332,332,315,333,333,333,316,321,321,\n335,335,335,335,335,335,335,335,335,335,321,321,321,336,336,321,\n\n/* block 14 */\n337,337,337,338,338,338,338,338,338,338,338,339,338,339,340,341,\n342,343,342,342,342,342,342,342,342,342,342,342,342,342,342,342,\n342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,\n344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,\n345,345,345,345,345,345,345,345,345,345,345,340,340,342,342,342,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 15 */\n346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,\n346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,\n346,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347,\n347,346,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349,\n349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,\n349,349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,\n350,350,350,350,351,351,352,353,354,355,356,297,297,357,358,358,\n\n/* block 16 */\n359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,\n359,359,359,359,359,359,360,360,361,361,362,360,360,360,360,360,\n360,360,360,360,362,360,360,360,362,360,360,360,360,363,297,297,\n364,364,364,364,364,364,365,366,364,366,364,364,364,366,366,297,\n367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,\n367,367,367,367,367,367,367,367,367,368,368,368,297,297,369,297,\n342,342,342,342,342,342,342,342,342,342,342,340,340,340,340,340,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 17 */\n321,321,321,321,321,321,321,321,370,321,321,321,321,321,321,340,\n307,307,340,340,340,340,340,316,333,333,333,333,333,333,333,333,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,334,327,327,333,327,327,327,\n333,333,333,371,316,316,316,316,316,316,316,316,316,316,316,316,\n372,372,308,326,326,326,326,326,326,326,333,333,333,333,333,333,\n326,326,326,373,326,326,326,326,326,326,326,326,326,326,326,316,\n\n/* block 18 */\n374,374,374,375,376,376,376,376,376,376,376,376,376,376,376,376,\n376,376,376,376,376,377,377,377,377,377,377,377,377,377,377,377,\n377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,\n377,377,377,377,377,377,377,377,377,377,374,375,378,376,375,375,\n375,374,374,374,374,374,374,374,374,375,375,375,375,379,375,375,\n376,380,381,176,176,374,374,374,377,377,377,377,377,377,377,377,\n376,376,374,374,382,383,384,384,384,384,384,384,384,384,384,384,\n385,386,376,376,376,376,376,376,377,377,377,377,377,377,377,377,\n\n/* block 19 */\n387,388,389,389,196,387,387,387,387,387,387,387,387,196,196,387,\n387,196,196,387,387,390,390,390,390,390,390,390,390,390,390,390,\n390,390,390,390,390,390,390,390,390,196,390,390,390,390,390,390,\n390,196,390,196,196,196,390,390,390,390,196,196,391,387,392,389,\n389,388,388,388,388,196,196,389,389,196,196,389,389,393,387,196,\n196,196,196,196,196,196,196,392,196,196,196,196,390,390,196,390,\n387,387,388,388,196,196,394,394,394,394,394,394,394,394,394,394,\n390,390,395,395,396,396,396,396,396,396,397,395,387,398,399,196,\n\n/* block 20 */\n196,400,400,401,196,402,402,402,402,402,402,196,196,196,196,402,\n402,196,196,402,402,402,402,402,402,402,402,402,402,402,402,402,\n402,402,402,402,402,402,402,402,402,196,402,402,402,402,402,402,\n402,196,402,402,196,402,402,196,402,402,196,196,403,196,401,401,\n401,400,400,196,196,196,196,400,400,196,196,400,400,404,196,196,\n196,400,196,196,196,196,196,196,196,402,402,402,402,196,402,196,\n196,196,196,196,196,196,405,405,405,405,405,405,405,405,405,405,\n400,406,402,402,402,400,407,196,196,196,196,196,196,196,196,196,\n\n/* block 21 */\n196,408,408,409,196,410,410,410,410,410,410,410,410,410,196,410,\n410,410,196,410,410,411,411,411,411,411,411,411,411,411,411,411,\n411,411,411,411,411,411,411,411,411,196,411,411,411,411,411,411,\n411,196,411,411,196,411,411,411,411,411,196,196,412,410,409,409,\n409,408,408,408,408,408,196,408,408,409,196,409,409,413,196,196,\n410,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n410,410,408,408,196,196,414,414,414,414,414,414,414,414,414,414,\n415,416,196,196,196,196,196,196,196,411,408,417,408,412,412,412,\n\n/* block 22 */\n196,418,419,419,196,420,420,420,420,420,420,420,420,196,196,420,\n420,196,196,420,420,421,421,421,421,421,421,421,421,421,421,421,\n421,421,421,421,421,421,421,421,421,196,421,421,421,421,421,421,\n421,196,421,421,196,421,421,421,421,421,196,196,422,420,423,418,\n419,418,418,418,418,196,196,419,419,196,196,419,419,424,196,196,\n196,196,196,196,196,425,418,423,196,196,196,196,421,421,196,421,\n420,420,418,418,196,196,426,426,426,426,426,426,426,426,426,426,\n427,421,428,428,428,428,428,428,196,196,196,196,196,196,196,196,\n\n/* block 23 */\n196,196,429,430,196,430,430,430,430,430,430,196,196,196,430,430,\n430,196,430,430,430,430,196,196,196,430,430,196,430,196,430,430,\n196,196,196,430,430,196,196,196,430,430,430,196,196,196,430,430,\n430,430,430,430,430,430,430,430,430,430,196,196,196,196,431,432,\n429,432,432,196,196,196,432,432,432,196,432,432,432,433,196,196,\n430,196,196,196,196,196,196,431,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,434,434,434,434,434,434,434,434,434,434,\n435,435,435,436,437,437,437,437,437,438,437,196,196,196,196,196,\n\n/* block 24 */\n439,440,440,440,439,441,441,441,441,441,441,441,441,196,441,441,\n441,196,441,441,441,442,442,442,442,442,442,442,442,442,442,442,\n442,442,442,442,442,442,442,442,442,196,442,442,442,442,442,442,\n442,442,442,442,442,442,442,442,442,442,196,196,443,441,439,439,\n439,440,440,440,440,196,439,439,439,196,439,439,439,444,196,196,\n196,196,196,196,196,439,439,196,442,442,442,196,196,441,196,196,\n441,441,439,439,196,196,445,445,445,445,445,445,445,445,445,445,\n196,196,196,196,196,196,196,446,447,447,447,447,447,447,447,448,\n\n/* block 25 */\n449,450,451,451,452,449,449,449,449,449,449,449,449,196,449,449,\n449,196,449,449,449,449,449,449,449,449,449,449,449,449,449,449,\n449,449,449,449,449,449,449,449,449,196,449,449,449,449,449,449,\n449,449,449,449,196,449,449,449,449,449,196,196,453,449,451,454,\n455,451,455,451,451,196,454,455,455,196,455,455,450,456,196,196,\n196,196,196,196,196,455,455,196,196,196,196,196,196,449,449,196,\n449,449,450,450,196,196,457,457,457,457,457,457,457,457,457,457,\n196,449,449,451,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 26 */\n458,458,459,459,460,460,460,460,460,460,460,460,460,196,460,460,\n460,196,460,460,460,461,461,461,461,461,461,461,461,461,461,461,\n461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,\n461,461,461,461,461,461,461,461,461,461,461,462,462,460,463,459,\n459,458,458,458,458,196,459,459,459,196,459,459,459,462,464,465,\n196,196,196,196,460,460,460,463,466,466,466,466,466,466,466,460,\n460,460,458,458,196,196,467,467,467,467,467,467,467,467,467,467,\n466,466,466,466,466,466,466,466,466,465,460,460,460,460,460,460,\n\n/* block 27 */\n196,468,469,469,196,470,470,470,470,470,470,470,470,470,470,470,\n470,470,470,470,470,470,470,196,196,196,470,470,470,470,470,470,\n470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,\n470,470,196,470,470,470,470,470,470,470,470,470,196,470,196,196,\n470,470,470,470,470,470,470,196,196,196,471,196,196,196,196,472,\n469,469,468,468,468,196,468,196,469,469,469,469,469,469,469,472,\n196,196,196,196,196,196,473,473,473,473,473,473,473,473,473,473,\n196,196,469,469,474,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 28 */\n196,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,\n475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,\n475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,\n475,476,475,477,476,476,476,476,476,476,478,196,196,196,196,479,\n480,480,480,480,480,475,481,482,482,482,482,482,482,476,482,483,\n484,484,484,484,484,484,484,484,484,484,485,485,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 29 */\n196,486,486,196,486,196,486,486,486,486,486,196,486,486,486,486,\n486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,\n486,486,486,486,196,486,196,486,486,486,486,486,486,486,486,486,\n486,487,486,488,487,487,487,487,487,487,489,487,487,486,196,196,\n490,490,490,490,490,196,491,196,492,492,492,492,492,487,493,196,\n494,494,494,494,494,494,494,494,494,494,196,196,486,486,486,486,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 30 */\n495,496,496,496,497,497,497,497,498,497,497,497,497,498,498,498,\n498,498,498,496,497,496,496,496,499,499,496,496,496,496,496,496,\n500,500,500,500,500,500,500,500,500,500,501,501,501,501,501,501,\n501,501,501,501,496,499,496,499,496,499,502,503,502,503,504,504,\n495,495,495,495,495,495,495,495,196,495,495,495,495,495,495,495,\n495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,\n495,495,495,495,495,495,495,495,495,495,495,495,495,196,196,196,\n196,505,505,505,505,505,505,506,505,506,505,505,505,505,505,507,\n\n/* block 31 */\n505,505,508,508,509,497,499,499,495,495,495,495,495,505,505,505,\n505,505,505,505,505,505,505,505,196,505,505,505,505,505,505,505,\n505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,\n505,505,505,505,505,505,505,505,505,505,505,505,505,196,496,496,\n496,496,496,496,496,496,499,496,496,496,496,496,496,196,496,496,\n497,497,497,497,497,510,510,510,510,497,497,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 32 */\n511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,\n511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,\n511,511,511,511,511,511,511,511,511,511,511,512,512,513,513,513,\n513,514,513,513,513,513,513,515,512,516,516,514,514,513,513,511,\n517,517,517,517,517,517,517,517,517,517,518,518,519,519,519,519,\n511,511,511,511,511,511,514,514,513,513,511,511,511,511,513,513,\n513,511,512,520,520,511,511,512,512,520,520,520,520,520,511,511,\n511,513,513,513,513,511,511,511,511,511,511,511,511,511,511,511,\n\n/* block 33 */\n511,511,513,512,514,513,513,520,520,520,520,520,520,521,511,520,\n522,522,522,522,522,522,522,522,522,522,520,520,512,513,523,523,\n524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,\n524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,\n524,524,524,524,524,524,196,524,196,196,196,196,196,524,196,196,\n525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,\n525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,\n525,525,525,525,525,525,525,525,525,525,525,526,527,525,525,525,\n\n/* block 34 */\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,529,\n530,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,\n531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,\n\n/* block 35 */\n531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,\n531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,\n531,531,531,531,531,531,531,531,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n\n/* block 36 */\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196,\n533,533,533,533,533,533,533,196,533,196,533,533,533,533,196,196,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n\n/* block 37 */\n533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,196,\n533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n\n/* block 38 */\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,533,533,533,533,196,196,534,534,534,\n535,536,537,536,536,536,536,537,537,538,538,538,538,538,538,538,\n538,538,539,539,539,539,539,539,539,539,539,539,539,196,196,196,\n\n/* block 39 */\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n540,540,540,540,540,540,540,540,540,540,196,196,196,196,196,196,\n541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,\n541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,\n541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,\n541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,\n541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,\n542,542,542,542,542,542,196,196,543,543,543,543,543,543,196,196,\n\n/* block 40 */\n544,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n\n/* block 41 */\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n\n/* block 42 */\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,546,547,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n\n/* block 43 */\n548,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,\n549,549,549,549,549,549,549,549,549,549,549,550,551,196,196,196,\n552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,\n552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,\n552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,\n552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,\n552,552,552,552,552,552,552,552,552,552,552,553,553,553,554,554,\n554,552,552,552,552,552,552,552,552,196,196,196,196,196,196,196,\n\n/* block 44 */\n555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,\n555,555,556,556,557,558,196,196,196,196,196,196,196,196,196,555,\n559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,\n559,559,560,560,561,562,562,196,196,196,196,196,196,196,196,196,\n563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,\n563,563,564,564,196,196,196,196,196,196,196,196,196,196,196,196,\n565,565,565,565,565,565,565,565,565,565,565,565,565,196,565,565,\n565,196,566,566,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 45 */\n567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,\n567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,\n567,567,567,568,568,567,567,567,567,567,567,567,567,567,567,567,\n567,567,567,567,569,569,570,571,571,571,571,571,571,571,570,570,\n570,570,570,570,570,570,571,570,570,572,572,572,572,572,572,572,\n572,572,573,572,574,574,575,576,577,577,575,578,567,572,196,196,\n579,579,579,579,579,579,579,579,579,579,196,196,196,196,196,196,\n580,580,580,580,580,580,580,580,580,580,196,196,196,196,196,196,\n\n/* block 46 */\n581,581,582,583,584,582,585,581,584,586,587,588,588,588,589,588,\n590,590,590,590,590,590,590,590,590,590,196,196,196,196,196,196,\n591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,592,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,196,196,196,196,196,196,196,\n\n/* block 47 */\n591,591,591,591,591,593,593,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,\n591,591,591,591,591,591,591,591,591,594,591,196,196,196,196,196,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n545,545,545,545,545,545,196,196,196,196,196,196,196,196,196,196,\n\n/* block 48 */\n595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,\n595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,196,\n596,596,596,597,597,597,597,596,596,597,597,597,196,196,196,196,\n597,597,596,597,597,597,597,597,597,598,598,598,196,196,196,196,\n599,196,196,196,600,600,601,601,601,601,601,601,601,601,601,601,\n602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,\n602,602,602,602,602,602,602,602,602,602,602,602,602,602,196,196,\n602,602,602,602,602,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 49 */\n603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,\n603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,\n603,603,603,603,603,603,603,603,603,603,603,603,196,196,196,196,\n603,603,603,603,603,604,604,604,603,603,604,603,603,603,603,603,\n603,603,603,603,603,603,603,603,603,603,196,196,196,196,196,196,\n605,605,605,605,605,605,605,605,605,605,606,196,196,196,607,607,\n608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,\n608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,\n\n/* block 50 */\n609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,\n609,609,609,609,609,609,609,610,610,611,611,610,196,196,612,612,\n613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,\n613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,\n613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,\n613,613,613,613,613,614,615,614,615,615,615,615,615,615,615,196,\n616,617,615,617,617,615,615,615,615,615,615,615,615,614,614,614,\n614,614,614,615,615,618,618,618,618,618,618,618,618,196,196,618,\n\n/* block 51 */\n619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196,\n619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196,\n620,620,620,620,620,620,620,621,622,622,622,622,620,620,196,196,\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,623,624,\n624,176,176,176,176,176,176,176,176,176,176,176,624,624,624,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 52 */\n625,625,625,625,626,627,627,627,627,627,627,627,627,627,627,627,\n627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,\n627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,\n627,627,627,627,628,629,625,625,625,625,625,629,625,629,626,626,\n626,626,625,629,630,627,627,627,627,627,627,627,627,196,631,631,\n632,632,632,632,632,632,632,632,632,632,631,631,633,634,631,631,\n633,635,635,635,635,635,635,635,635,635,635,628,628,628,628,628,\n628,628,628,628,635,635,635,635,635,635,635,635,635,631,631,631,\n\n/* block 53 */\n636,636,637,638,638,638,638,638,638,638,638,638,638,638,638,638,\n638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,\n638,637,636,636,636,636,637,637,636,636,639,640,636,636,638,638,\n641,641,641,641,641,641,641,641,641,641,638,638,638,638,638,638,\n642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,\n642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,\n642,642,642,642,642,642,643,644,645,645,644,644,644,645,644,645,\n645,645,646,646,196,196,196,196,196,196,196,196,647,647,647,647,\n\n/* block 54 */\n648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,\n648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,\n648,648,648,648,649,649,649,649,649,649,649,649,650,650,650,650,\n650,650,650,650,649,649,651,652,196,196,196,653,653,654,654,654,\n655,655,655,655,655,655,655,655,655,655,196,196,196,648,648,648,\n656,656,656,656,656,656,656,656,656,656,657,657,657,657,657,657,\n657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,\n657,657,657,657,657,657,657,657,658,658,658,659,658,658,660,660,\n\n/* block 55 */\n661,662,663,664,665,666,667,668,669,275,276,196,196,196,196,196,\n670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,\n670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,\n670,670,670,670,670,670,670,670,670,670,670,196,196,670,670,670,\n671,671,671,671,671,671,671,671,196,196,196,196,196,196,196,196,\n672,673,672,674,673,675,675,676,675,676,677,673,676,676,673,673,\n676,678,673,673,673,673,673,673,673,679,680,681,681,675,681,681,\n681,681,682,683,684,680,680,685,686,686,687,196,196,196,196,196,\n\n/* block 56 */\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\n 70, 70, 70, 70, 70, 70,256,256,256,256,256,688,149,149,149,149,\n149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,\n149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,\n149,149,149,149,149,149,149,149,149,149,149,149,149,689,689,689,\n689,689,150,149,149,149,689,689,689,689,689, 70, 70, 70, 70, 70,\n 70, 70, 70, 70, 70, 70, 70, 70,690,691, 70, 70, 70,692, 70, 70,\n\n/* block 57 */\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,693, 70,\n 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,695,695,695,695,695,\n695,695,695,695,696,695,695,695,696,695,695,695,695,695,695,695,\n695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,697,\n698,698,189,189,176,176,176,176,176,176,176,176,176,176,176,176,\n189,189,189,624,624,624,624,624,624,624,624,624,624,624,624,624,\n624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,\n624,624,624,624,624,176,176,176,699,176,700,176,176,176,176,176,\n\n/* block 58 */\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n701,702, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n\n/* block 59 */\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,703,704, 70, 70,705, 70,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n\n/* block 60 */\n706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707,\n706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196,\n706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707,\n706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707,\n706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196,\n708,706,708,706,708,706,708,706,196,707,196,707,196,707,196,707,\n706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707,\n709,709,710,710,710,710,711,711,712,712,713,713,714,714,196,196,\n\n/* block 61 */\n715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716,\n715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716,\n715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716,\n706,706,717,718,717,196,708,717,707,707,719,719,720,201,721,201,\n201,201,717,718,717,196,708,717,722,722,722,722,720,201,201,201,\n706,706,708,723,196,196,708,708,707,707,724,724,196,201,201,201,\n706,706,708,725,708,250,708,708,707,707,726,726,255,201,201,201,\n196,196,717,718,717,196,708,717,727,727,728,728,720,201,201,196,\n\n/* block 62 */\n729,729,729,729,729,729,729,729,729,729,729, 51,730,731,732,733,\n734,734,734,734,734,734,735, 43,736,737,738,739,739,740,738,739,\n 43, 43, 43, 43,741, 43, 43,742,743,744,745,746,747,748,749,750,\n751,751,752,752,752, 43, 43, 43, 43, 49, 57, 43,753,754, 43,755,\n756, 43, 43, 43,757,758,759,754,754,753, 43, 43, 43, 43, 43,760,\n 43, 43, 50,761,755, 43, 43, 43, 43, 43,762, 43, 43,763, 43,729,\n 51,764,764,764,764,765,766,767,768,769,770,770,770,770,770,770,\n 54,696,196,196, 54, 54, 54, 54, 54, 54,771,772,773,774,775,695,\n\n/* block 63 */\n 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,771,772,773,774,775,196,\n695,695,695,695,695,695,695,695,695,695,695,695,695,196,196,196,\n479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,\n479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,\n479,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,\n777,777,777,777,777,777,777,777,777,777,777,777,777,778,778,778,\n778,777,778,779,778,777,777,189,189,189,189,777,777,777,777,777,\n780,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 64 */\n781,781,782,781,781,781,781,782,781,781,783,782,782,782,783,783,\n782,782,782,783,781,782,781,781,784,782,782,782,782,782,781,781,\n781,781,785,781,782,781,786,781,782,787,788,789,782,782,790,783,\n782,782,791,782,783,792,792,792,792,793,781,781,783,783,782,782,\n794,794,794,794,794,782,783,783,795,795,781,794,781,781,796,510,\n 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,\n798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,\n\n/* block 65 */\n799,799,799, 65, 66,799,799,799,799, 58,781,781,196,196,196,196,\n 50, 50, 50, 50,800,801,801,801,801,801, 50, 50,802,802,802,802,\n 50,802,802, 50,802,802, 50,802, 45,801,801,802,802,802, 50, 45,\n802,802, 45, 45, 45, 45,802,802, 45, 45, 45, 45,802,802,802,802,\n802,802,802,802,802,802,802,802,802,802,802,802,802,802, 50, 50,\n802,802, 50,802, 50,802,802,802,802,802,802,802, 45,802, 45, 45,\n 45, 45, 45, 45,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n\n/* block 66 */\n 50, 50,803, 50, 50, 50, 50,803,804,804,804,804,804,804, 50, 50,\n 50, 50,805, 53, 50,804, 50, 50, 50, 50, 50, 50, 50, 50,803,804,\n804,804,804, 50,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50,\n 50, 50, 50,804, 50,804, 50, 50, 50, 50, 50, 50,804, 50, 50, 50,\n 50, 50,804,804,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50,804,804,804,804,804,804,804,804, 50, 50,804,804,\n804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,\n\n/* block 67 */\n804,804,804,804,804,804,804,804,804,804,804,804, 50, 50, 50,804,\n804,804,804, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50,\n 50, 50,804,804, 50, 50,804, 50,804,804, 50,804, 50, 50, 50, 50,\n804,804,804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804, 50, 50,\n804,804, 50, 50, 50, 50,804,804,804,804,804,804,804,804,804,804,\n804,804,804,804,804,804,804,804,804,804,804,804,804,804, 50, 50,\n804,804,804,804,804, 50,804,804, 50, 50,804,804,804,804,804, 50,\n\n/* block 68 */\n 45, 45, 45, 45, 45, 45, 45, 45,806,807,806,807, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45, 45,\n 50, 50, 45, 45, 45, 45, 45, 45, 47,809,810, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45,811,811,811,811,811,811,811,811,811,811,\n811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,\n811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,\n811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,\n811,811,811,811,811,811,811,811,811,811,811, 45, 50, 45, 45, 45,\n\n/* block 69 */\n 45, 45, 45, 45, 45, 45, 45, 45,812, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45,811, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50,802,802, 45,802, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47,\n802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50,\n 50, 50,802, 45, 45, 45, 45, 45, 45,808,808,808,808, 47, 47, 47,\n808, 47, 47,808, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45,\n\n/* block 70 */\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813,813,\n813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813,\n813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,\n 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n\n/* block 71 */\n 58, 58, 58, 58, 58, 58, 58, 58,814,814,814,814,814,814,814,814,\n814,814,814,814,814,814,814,814,814,814,814,814,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,815,815,815,815,815,815,815,815,815,815,\n815,815,816,815,815,815,815,815,815,815,815,815,815,815,815,815,\n817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,\n817,817,817,817,817,817,817,817,817,817, 58, 58, 58, 58, 58, 58,\n 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n\n/* block 72 */\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\n/* block 73 */\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n802,802, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,802,802,\n802,802,802,802,802,802,801, 50, 45, 45, 45, 45,802,802,802,802,\n801, 50, 45, 45, 45, 45,802,802, 45, 45,802,802, 45, 45, 45,802,\n802,802,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45,802, 45,802, 45, 45,802,802,802,802,802,802, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,800,800,818,818, 50,\n\n/* block 74 */\n 47, 47, 47, 47, 47,819,802,812,812,812,812,812,812,812, 47,812,\n812, 47,812, 45,808,808,812,812, 47,812,812,812,812,820,812,812,\n 47,812, 47, 47,812,812, 47,812,812,812, 47,812,812,812, 47, 47,\n812,812,812,812,812,812,812,812, 47, 47, 47,812,812,812,812,812,\n801,812,801,812,812,812,812,812,808,808,808,808,808,808,808,808,\n808,808,808,808,812,812,812,812,812,812,812,812,812,812,812, 47,\n801,819,819,801,812, 47, 47,812, 47,812,812,812,812,819,819,821,\n812,812,812,812,812,812,812,812,812,812,812, 47,812,812, 47,808,\n\n/* block 75 */\n812,812,812,812,812,812, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n812,812, 47,808, 47, 47, 47, 47,812, 47,812, 47, 47,812,812,812,\n 47,808,812,812,812,812,812, 47,812,812,808,808,822,812,812,812,\n 47, 47,812,812,812,812,812,812,812,812,812,812,812,808,808,812,\n812,812,812,812,808,808,812,812, 47,812,812,812,812,812,808, 47,\n812, 47,812, 47,808,812,812,812,812,812,812,812,812,812,812,812,\n812,812,812,812,812,812,812,812,812, 47,808,812,812,812,812,812,\n 47, 47,808,808, 47,808,812, 47, 47,820,808,812,812,808,812,812,\n\n/* block 76 */\n812,812, 47,812,812,808, 45, 45, 47, 47,823,823,820,820,812, 47,\n812,812, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45,\n 45, 47, 45, 45, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,808, 45,808, 45,\n 45, 45, 45,808,808,808, 45,808, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 47, 47,812,812,812,758,759,758,759,758,759,758,759,\n758,759,758,759,758,759, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n\n/* block 77 */\n 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n 58, 58, 58, 58, 45,808,808,808, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,\n 50, 50, 50,804,804,806,807, 50,804,804, 50,804, 50,804, 50, 50,\n 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50,804,804,804, 50,\n 50, 50,804,804,804,804,806,807,806,807,806,807,806,807,806,807,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n\n/* block 78 */\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,\n\n/* block 79 */\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50,800,800, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n\n/* block 80 */\n 50, 50, 50,806,807,806,807,806,807,806,807,806,807,806,807,806,\n807,806,807,806,807,806,807,806,807, 50, 50,804, 50, 50, 50, 50,\n804, 50, 50,804,804,804, 50, 50,804,804,804,804,804,804,804,804,\n 50, 50, 50, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50,\n804,804, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,\n804,804,804, 50,804,804, 50, 50,806,807,806,807, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50,804, 50, 50,804,804, 50, 50,806,807, 50, 50,\n\n/* block 81 */\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50,\n 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50,804,804, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804,804,804,\n\n/* block 82 */\n804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,\n804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,\n804,804,804, 50, 50, 50,804,804,804,804,804,804,804,804, 50,804,\n804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,\n804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,\n804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50,804, 50,\n 50, 50, 50,804,804,804, 50, 50, 50, 50, 50, 50,804,804,804, 50,\n 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50, 50, 50, 50, 50,\n\n/* block 83 */\n 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,\n 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45,\n808, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45,813,813, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n\n/* block 84 */\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45,813, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,\n 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,825, 45,\n\n/* block 85 */\n826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,\n826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,\n826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,\n827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,\n827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,\n827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,\n 65, 66,828,829,830,831,832, 65, 66, 65, 66, 65, 66,833,834,835,\n836, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,696,695,837,837,\n\n/* block 86 */\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247,\n246,247,246,247,838,839,839,839,839,839,839,246,247,246,247,840,\n840,840,246,247,196,196,196,196,196,841,841,841,842,843,842,842,\n\n/* block 87 */\n844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,\n844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,\n844,844,844,844,844,844,196,844,196,196,196,196,196,844,196,196,\n845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,\n845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,\n845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,\n845,845,845,845,845,845,845,845,196,196,196,196,196,196,196,846,\n847,196,196,196,196,196,196,196,196,196,196,196,196,196,196,848,\n\n/* block 88 */\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,\n533,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196,\n849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,\n849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,\n\n/* block 89 */\n 43, 43,850,851,850,851, 43, 43, 43,850,851, 43,850,851, 43, 43,\n 43, 43, 43, 43, 43, 43, 43,852, 43, 43,734, 43,850,851, 43, 43,\n850,851,758,759,758,759,758,759,758,759, 43, 43, 43, 43,754,853,\n854,855, 43, 43, 43, 43, 43, 43, 43, 43,734,734,856, 43, 43, 43,\n734,857,738,858, 43, 43, 43, 43, 43, 43, 43, 43,859, 43,859,859,\n 45, 45, 43,754,754,758,759,758,759,758,759,758,759,734,813,813,\n813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,\n813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,\n\n/* block 90 */\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,196,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 91 */\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n\n/* block 92 */\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,\n860,860,860,860,860,860,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n861,861,862,862,861,861,861,861,861,861,861,861,861,861,863,863,\n\n/* block 93 */\n729,864,865,866,781,867,868,869,870,871,872,873,874,875,874,875,\n876,877, 45,878,876,877,876,877,876,877,876,877,879,880,881,881,\n 45,869,869,869,869,869,869,869,869,869,882,882,882,882,883,883,\n884,885,885,885,885,885,781,886,869,869,869,887,888,889,890,890,\n196,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n\n/* block 94 */\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,196,196,892,892,893,893,894,894,891,\n895,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,897,898,899,899,896,\n\n/* block 95 */\n196,196,196,196,196,900,900,900,900,900,900,900,900,900,900,900,\n900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,\n900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,\n196,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,\n901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,\n901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,\n901,901,901,901,902,901,901,901,901,901,901,901,901,901,901,901,\n901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,\n\n/* block 96 */\n901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196,\n903,903,904,904,904,904,903,903,903,903,903,903,903,903,903,903,\n900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,\n900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,\n890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,\n890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,\n890,890,890,890,890,890,196,196,196,196,196,196,196,196,196,861,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n\n/* block 97 */\n905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,\n905,905,905,905,905,905,905,905,905,905,905,905,905,906,906,196,\n904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903,\n903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,\n903,903,903,903,903,903,903,903,907,907,907,907,907,907,907,907,\n781, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,\n905,905,905,905,905,905,905,905,905,905,905,905,906,906,906,510,\n\n/* block 98 */\n904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903,\n903,903,903,903,903,903,903,908,903,908,903,903,903,903,903,903,\n903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,\n903, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,\n903,903,903,903,903,903,903,903,903,903,903,903,781,781,781,781,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,903,\n\n/* block 99 */\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,\n909,909,909,909,909,909,909,909,903,903,903,903,903,903,903,903,\n903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,\n903,510,510,510,510,510,510,781,781,781,781,903,903,903,903,903,\n\n/* block 100 */\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,781,781,\n903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,\n903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,781,\n\n/* block 101 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 102 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n\n/* block 103 */\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n\n/* block 104 */\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,\n\n/* block 105 */\n911,911,911,911,911,911,911,911,911,911,911,911,911,196,196,196,\n913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,\n913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,\n913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,\n913,913,913,913,913,913,913,196,196,196,196,196,196,196,196,196,\n914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,\n914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,\n914,914,914,914,914,914,914,914,915,915,915,915,915,915,916,917,\n\n/* block 106 */\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n\n/* block 107 */\n918,918,918,918,918,918,918,918,918,918,918,918,919,920,921,921,\n918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,\n922,922,922,922,922,922,922,922,922,922,918,918,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n275,276,275,276,275,276,275,276,275,276,923,924,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,925,281,\n283,283,283,926,849,849,849,849,849,849,849,849,927,927,926,928,\n\n/* block 108 */\n275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276,\n275,276,275,276,275,276,275,276,275,276,275,276,929,929,849,849,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,931,931,931,931,931,931,931,931,931,931,\n932,932,933,934,935,935,935,934,196,196,196,196,196,196,196,196,\n\n/* block 109 */\n936,936,936,936,936,936,936,936, 46, 46, 46, 46, 46, 46, 46, 46,\n 46, 46, 46, 46, 46, 46, 46,151,151,151,151,151,151,151,151,151,\n 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n695, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,937, 65, 66,\n\n/* block 110 */\n 65, 66, 65, 66, 65, 66, 65, 66,151,938,938, 65, 66,939, 70, 93,\n 65, 66, 65, 66,940, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,941,942,943,944,941, 70,\n945,946,947,948, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,\n 65, 66, 65, 66,949,950,951, 65, 66, 65, 66,952, 65, 66,196,196,\n 65, 66,196, 70,196, 70, 65, 66, 65, 66, 65, 66,953,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,695,695,695, 65, 66, 93,149,149, 70, 93, 93, 93, 93, 93,\n\n/* block 111 */\n954,954,955,954,954,954,956,954,954,954,954,955,954,954,954,954,\n954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,\n954,954,954,957,957,955,955,957,958,958,958,958,956,196,196,196,\n959,959,959,960,960,960,961,961,962,963,196,196,196,196,196,196,\n964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,\n964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,\n964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,\n964,964,964,964,965,965,966,966,196,196,196,196,196,196,196,196,\n\n/* block 112 */\n967,967,968,968,968,968,968,968,968,968,968,968,968,968,968,968,\n968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,\n968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,\n968,968,968,968,967,967,967,967,967,967,967,967,967,967,967,967,\n967,967,967,967,969,970,196,196,196,196,196,196,196,196,971,971,\n972,972,972,972,972,972,972,972,972,972,196,196,196,196,196,196,\n378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,\n378,973,376,974,376,376,376,376,385,385,385,376,385,376,376,374,\n\n/* block 113 */\n975,975,975,975,975,975,975,975,975,975,976,976,976,976,976,976,\n976,976,976,976,976,976,976,976,976,976,976,976,976,976,976,976,\n976,976,976,976,976,976,977,977,977,977,977,978,978,978,979,980,\n981,981,981,981,981,981,981,981,981,981,981,981,981,981,981,981,\n981,981,981,981,981,981,981,982,982,982,982,982,982,982,982,982,\n982,982,983,984,196,196,196,196,196,196,196,196,196,196,196,985,\n528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,\n528,528,528,528,528,528,528,528,528,528,528,528,528,196,196,196,\n\n/* block 114 */\n986,986,986,987,988,988,988,988,988,988,988,988,988,988,988,988,\n988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,\n988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,\n988,988,988,989,987,987,986,986,986,986,987,987,986,986,987,987,\n990,991,991,991,991,991,991,992,993,993,991,991,991,991,196,994,\n995,995,995,995,995,995,995,995,995,995,196,196,196,196,991,991,\n511,511,511,511,511,521,996,511,511,511,511,511,511,511,511,511,\n522,522,522,522,522,522,522,522,522,522,511,511,511,511,511,196,\n\n/* block 115 */\n997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,\n997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,\n997,997,997,997,997,997,997,997,997,998,998,998,998,998,998,999,\n999,998,998,999,999,998,998,196,196,196,196,196,196,196,196,196,\n997,997,997,998,997,997,997,997,997,997,997,997,998,999,196,196,\n1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,196,196,1001,1002,1002,1002,\n511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,\n996,511,511,511,511,511,511,523,523,523,511,520,521,520,511,511,\n\n/* block 116 */\n1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,\n1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,\n1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,\n1004,1003,1004,1004,1004,1005,1005,1004,1004,1005,1003,1005,1005,1003,1004,1006,\n1007,1006,1007,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,1003,1003,1008,1009,1010,\n1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1012,1013,1013,1012,1012,\n1014,1014,1011,1015,1015,1012,1016,196,196,196,196,196,196,196,196,196,\n\n/* block 117 */\n196,533,533,533,533,533,533,196,196,533,533,533,533,533,533,196,\n196,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196,\n533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,\n 70, 70, 70,1017, 70, 70, 70, 70, 70, 70, 70,938,149,149,149,149,\n 70, 70, 70, 70, 70,256, 70, 70, 70,149, 46, 46,196,196,196,196,\n1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,\n\n/* block 118 */\n1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,\n1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,\n1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,\n1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,\n1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,\n1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,\n1011,1011,1011,1012,1012,1013,1012,1012,1013,1012,1012,1014,1019,1016,196,196,\n1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,196,196,196,196,196,196,\n\n/* block 119 */\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 120 */\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n\n/* block 121 */\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 122 */\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 123 */\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 124 */\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 125 */\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n\n/* block 126 */\n1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,\n1022,1022,1022,1022,196,196,196,196,196,196,196,196,196,196,196,196,\n531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,\n531,531,531,531,531,531,531,196,196,196,196,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,\n532,532,532,532,532,532,532,532,532,532,532,532,196,196,196,196,\n\n/* block 127 */\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,\n\n/* block 128 */\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n\n/* block 129 */\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n\n/* block 130 */\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910,910,\n1025,910,1025,910,910,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910,\n1025,910,1025,910,910,1025,1025,910,910,910,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n\n/* block 131 */\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 132 */\n703,703,703,703,703,1026,1027,196,196,196,196,196,196,196,196,196,\n196,196,196,292,292,292,292,292,196,196,196,196,196,305,300,305,\n305,305,305,305,305,305,305,305,305,1028,305,305,305,305,305,305,\n305,305,305,305,305,305,305,297,305,305,305,305,305,297,305,297,\n305,305,297,305,305,297,305,305,305,305,305,305,305,305,305,305,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 133 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,370,370,370,370,370,370,370,370,370,370,370,370,370,370,\n370,370,370,340,340,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 134 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,1029,1029,\n1029,1029,1029,1029,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 135 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 136 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,1030,1031,\n315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n\n/* block 137 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n340,340,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,340,340,340,340,340,340,340,315,\n1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,\n1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,\n321,321,1033,321,321,321,321,321,321,321,1029,1029,312,1034,315,315,\n\n/* block 138 */\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1036,\n1037,1037,1038,1039,1037,1038,1038,1040,1041,1037,196,196,196,196,196,196,\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,927,927,\n1037,1042,1042,755,755,1040,1041,1040,1041,1040,1041,1040,1041,1040,1041,1040,\n1041,1043,1044,1043,1044,866,866,1040,1041,1037,1037,1037,1037,755,755,755,\n1045,199,1046,196,199,1047,1038,1038,1042,1048,1049,1048,1049,1048,1049,1050,\n1037,1051,1052,1053,1054,1054,794,196,1051,479,1050,1037,196,196,196,196,\n1029,321,1029,321,1029,340,1029,321,1029,321,1029,321,1029,321,1029,321,\n\n/* block 139 */\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,\n321,321,321,321,321,321,321,321,321,321,321,321,321,340,340, 51,\n\n/* block 140 */\n196,1038,1055,1050,479,1050,1037,1056,1048,1049,1037,1052,1045,1057,1046,1058,\n1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1047,199,1054,794,1054,1038,\n1037,1060,1060,1060,1060,1060,1060, 59, 59, 59, 59, 59, 59, 59, 59, 59,\n 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,1048,1051,1049,1061,755,\n 46,1062,1062,1062,1062,1062,1062, 62, 62, 62, 62, 62, 62, 62, 62, 62,\n 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,1048,794,1049,794,1048,\n1049,1063,1064,1065,1066,897,896,896,896,896,896,896,896,896,896,896,\n898,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n\n/* block 141 */\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,\n896,896,896,896,896,896,896,896,896,896,896,896,896,896,1067,1067,\n902,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,\n901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196,\n196,196,901,901,901,901,901,901,196,196,901,901,901,901,901,901,\n196,196,901,901,901,901,901,901,196,196,901,901,901,196,196,196,\n479,479,794, 46,781,479,479,196,781,794,794,794,794,781,781,196,\n765,765,765,765,765,765,765,765,765,1068,1068,1068,781,781,1032,1032,\n\n/* block 142 */\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,196,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 143 */\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,\n1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196,196,196,196,\n\n/* block 144 */\n1070,1071,1072,196,196,196,196,1073,1073,1073,1073,1073,1073,1073,1073,1073,\n1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,\n1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,\n1073,1073,1073,1073,196,196,196,1074,1074,1074,1074,1074,1074,1074,1074,1074,\n1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,\n1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,\n1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,\n1075,1075,1075,1075,1075,1076,1076,1076,1076,1077,1077,1077,1077,1077,1077,1077,\n\n/* block 145 */\n1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1076,1076,1077,1078,1078,196,\n781,781,781,781,781,781,781,781,781,781,781,781,781,196,196,196,\n1077,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,189,196,196,\n\n/* block 146 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 147 */\n1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,\n1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,196,196,196,\n1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,\n1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,\n1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,\n1080,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1081,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,\n1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,196,196,196,196,\n\n/* block 148 */\n1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,\n1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,\n1084,1084,1084,1084,196,196,196,196,196,196,196,196,196,1083,1083,1083,\n1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,\n1085,1086,1085,1085,1085,1085,1085,1085,1085,1085,1086,196,196,196,196,196,\n1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,\n1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,\n1087,1087,1087,1087,1087,1087,1088,1088,1088,1088,1088,196,196,196,196,196,\n\n/* block 149 */\n1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,\n1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,196,1090,\n1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,\n1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,\n1091,1091,1091,1091,196,196,196,196,1091,1091,1091,1091,1091,1091,1091,1091,\n1092,1093,1093,1093,1093,1093,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 150 */\n1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,\n1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,\n1094,1094,1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095,\n1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,\n1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,\n1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,\n1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,\n1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,\n\n/* block 151 */\n1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,\n1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,196,196,\n1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,196,196,196,196,196,196,\n1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,\n1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,\n1099,1099,1099,1099,196,196,196,196,1100,1100,1100,1100,1100,1100,1100,1100,\n1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,\n1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,196,196,196,196,\n\n/* block 152 */\n1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,\n1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,\n1101,1101,1101,1101,1101,1101,1101,1101,196,196,196,196,196,196,196,196,\n1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,\n1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,\n1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,\n1102,1102,1102,1102,196,196,196,196,196,196,196,196,196,196,196,1103,\n1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104,\n\n/* block 153 */\n1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104,\n1104,1104,1104,196,1104,1104,196,1105,1105,1105,1105,1105,1105,1105,1105,1105,\n1105,1105,196,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,\n1105,1105,196,1105,1105,1105,1105,1105,1105,1105,196,1105,1105,196,196,196,\n1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,\n1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,\n1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,\n1106,1106,1106,1106,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 154 */\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n\n/* block 155 */\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196,\n1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,\n1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196,196,\n1107,1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 156 */\n149,1108,1108,149,149,149,196,149,149,149,149,149,149,149,149,149,\n149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,\n149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,\n149,196,149,149,149,149,149,149,149,149,149,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 157 */\n1109,1109,1109,1109,1109,1109,297,297,1109,297,1109,1109,1109,1109,1109,1109,\n1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,\n1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,\n1109,1109,1109,1109,1109,1109,297,1109,1109,297,297,297,1109,297,297,1109,\n1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,\n1110,1110,1110,1110,1110,1110,297,1111,1112,1112,1112,1112,1112,1112,1112,1112,\n1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,\n1113,1113,1113,1113,1113,1113,1113,1114,1114,1115,1115,1115,1115,1115,1115,1115,\n\n/* block 158 */\n1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,\n1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,297,\n297,297,297,297,297,297,297,1117,1117,1117,1117,1117,1117,1117,1117,1117,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,\n1118,1118,1118,297,1118,1118,297,297,297,297,297,1119,1119,1119,1119,1119,\n\n/* block 159 */\n1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,\n1120,1120,1120,1120,1120,1120,1121,1121,1121,1121,1121,1121,297,297,297,1122,\n1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,\n1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,297,297,297,297,297,1124,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 160 */\n1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,\n1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,\n1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,\n1126,1126,1126,1126,1126,1126,1126,1126,297,297,297,297,1127,1127,1126,1126,\n1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,\n297,297,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,\n1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,\n1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,\n\n/* block 161 */\n1128,1129,1129,1129,297,1129,1129,297,297,297,297,297,1129,1129,1129,1129,\n1128,1128,1128,1128,297,1128,1128,1128,297,1128,1128,1128,1128,1128,1128,1128,\n1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,\n1128,1128,1128,1128,1128,1128,297,297,1130,1130,1130,297,297,297,297,1131,\n1132,1132,1132,1132,1132,1132,1132,1132,1132,297,297,297,297,297,297,297,\n1133,1133,1133,1133,1133,1133,1134,1134,1133,297,297,297,297,297,297,297,\n1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,\n1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136,1136,1137,\n\n/* block 162 */\n1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,\n1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1139,1139,1139,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1140,1140,1140,1140,1140,1140,1140,1140,1141,1140,1140,1140,1140,1140,1140,1140,\n1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,\n1140,1140,1140,1140,1140,1142,1142,297,297,297,297,1143,1143,1143,1143,1143,\n1144,1144,1145,1144,1144,1144,1146,297,297,297,297,297,297,297,297,297,\n\n/* block 163 */\n1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,\n1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,\n1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,\n1147,1147,1147,1147,1147,1147,297,297,297,1148,1149,1149,1149,1149,1149,1149,\n1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,\n1150,1150,1150,1150,1150,1150,297,297,1151,1151,1151,1151,1151,1151,1151,1151,\n1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,\n1152,1152,1152,297,297,297,297,297,1153,1153,1153,1153,1153,1153,1153,1153,\n\n/* block 164 */\n1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,\n1154,1154,297,297,297,297,297,297,297,1155,1155,1155,1155,297,297,297,\n297,297,297,297,297,297,297,297,297,1156,1156,1156,1156,1156,1156,1156,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 165 */\n1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,\n1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,\n1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,\n1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,\n1157,1157,1157,1157,1157,1157,1157,1157,1157,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 166 */\n1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,\n1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,\n1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,\n1158,1158,1158,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,\n1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,\n1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,\n1159,1159,1159,297,297,297,297,297,297,297,1160,1160,1160,1160,1160,1160,\n\n/* block 167 */\n1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,\n1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,\n1161,1161,1162,1162,1163,1163,1163,1163,340,340,340,340,340,340,340,340,\n1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,340,340,340,340,340,340,\n1165,1165,1165,1165,1165,1165,1165,1165,1165,1165,1166,1166,1166,1166,1167,1166,\n1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,\n1168,1168,1168,1168,1168,1168,297,297,297,1169,1170,1171,1171,1171,1172,1173,\n1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,\n\n/* block 168 */\n1174,1174,1174,1174,1174,1174,297,297,297,297,297,297,297,297,1175,1175,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 169 */\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,\n1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,297,\n\n/* block 170 */\n1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,\n1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,\n1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,297,1178,1178,1179,297,297,\n1177,1177,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n340,340,321,321,321,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,316,333,333,333,\n\n/* block 171 */\n1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,\n1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1181,1181,1181,\n1181,1181,1181,1181,1181,1181,1181,1180,297,297,297,297,297,297,297,297,\n1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,\n1182,1182,1182,1182,1182,1182,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,\n1183,1184,1184,1184,1184,1185,1185,1185,1185,1185,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,\n\n/* block 172 */\n1186,1186,1187,1187,1187,1187,1188,1188,1188,1188,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,\n1189,1189,1189,1189,1189,1190,1190,1190,1190,1190,1190,1190,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,\n1191,1191,1191,1191,1191,1191,1191,297,297,297,297,297,297,297,297,297,\n\n/* block 173 */\n1192,1193,1192,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,\n1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,\n1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,\n1194,1194,1194,1194,1194,1194,1194,1194,1193,1193,1193,1193,1193,1193,1193,1193,\n1193,1193,1193,1193,1193,1193,1195,1196,1196,1197,1197,1197,1197,1197,196,196,\n196,196,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,\n1198,1198,1198,1198,1198,1198,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,\n1195,1194,1194,1193,1193,1194,196,196,196,196,196,196,196,196,196,1200,\n\n/* block 174 */\n1201,1201,1202,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,\n1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,\n1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,\n1202,1202,1202,1201,1201,1201,1201,1202,1202,1204,1205,1206,1206,1207,1208,1208,\n1208,1208,1201,196,196,196,196,196,196,196,196,196,196,1207,196,196,\n1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,\n1209,1209,1209,1209,1209,1209,1209,1209,1209,196,196,196,196,196,196,196,\n1210,1210,1210,1210,1210,1210,1210,1210,1210,1210,196,196,196,196,196,196,\n\n/* block 175 */\n1211,1211,1211,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,\n1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,\n1212,1212,1212,1212,1212,1212,1212,1211,1211,1211,1211,1211,1213,1211,1211,1211,\n1211,1211,1211,1214,1214,196,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,\n1216,1217,1217,1217,1212,1213,1213,1212,196,196,196,196,196,196,196,196,\n1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,\n1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,\n1218,1218,1218,1219,1220,1220,1218,196,196,196,196,196,196,196,196,196,\n\n/* block 176 */\n1221,1221,1222,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,\n1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,\n1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,\n1223,1223,1223,1222,1222,1222,1221,1221,1221,1221,1221,1221,1221,1221,1221,1222,\n1224,1223,1225,1225,1223,1226,1226,1227,1227,1228,1229,1229,1229,1226,1222,1221,\n1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1223,1227,1223,1227,1226,1226,\n196,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,\n1231,1231,1231,1231,1231,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 177 */\n1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,\n1232,1232,196,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,\n1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1234,\n1234,1234,1233,1233,1234,1235,1236,1237,1238,1238,1239,1238,1238,1240,1234,1232,\n1232,1234,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 178 */\n1241,1241,1241,1241,1241,1241,1241,196,1241,196,1241,1241,1241,1241,196,1241,\n1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,196,1241,\n1241,1241,1241,1241,1241,1241,1241,1241,1241,1242,196,196,196,196,196,196,\n1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,\n1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,\n1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1244,\n1245,1245,1245,1244,1244,1244,1244,1244,1244,1246,1247,196,196,196,196,196,\n1248,1248,1248,1248,1248,1248,1248,1248,1248,1248,196,196,196,196,196,196,\n\n/* block 179 */\n1249,1250,1251,1252,196,1253,1253,1253,1253,1253,1253,1253,1253,196,196,1253,\n1253,196,196,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,\n1253,1253,1253,1253,1253,1253,1253,1253,1253,196,1253,1253,1253,1253,1253,1253,\n1253,196,1253,1253,196,1253,1253,1253,1253,1253,196,1254,1255,1253,1256,1251,\n1249,1251,1251,1251,1251,196,196,1251,1251,196,196,1251,1251,1257,196,196,\n1253,196,196,196,196,196,196,1256,196,196,196,196,196,1258,1253,1253,\n1253,1253,1251,1251,196,196,1259,1259,1259,1259,1259,1259,1259,196,196,196,\n1259,1259,1259,1259,1259,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 180 */\n1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,196,1260,196,196,1260,196,\n1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,\n1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,\n1260,1260,1260,1260,1260,1260,196,1260,1261,1262,1262,1263,1263,1263,1263,1263,\n1263,196,1261,196,196,1261,196,1261,1261,1261,1262,196,1262,1262,1264,1265,\n1264,1266,1267,1268,1269,1269,196,1270,1270,196,196,196,196,196,196,196,\n196,1271,1271,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 181 */\n1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,\n1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,\n1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,\n1272,1272,1272,1272,1272,1273,1273,1273,1274,1274,1274,1274,1274,1274,1274,1274,\n1273,1273,1275,1274,1274,1273,1276,1272,1272,1272,1272,1277,1277,1278,1279,1279,\n1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1278,1278,196,1279,1281,1272,\n1272,1272,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 182 */\n1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,\n1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,\n1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,\n1283,1284,1284,1285,1285,1285,1285,1285,1285,1284,1285,1284,1284,1283,1284,1285,\n1285,1284,1286,1287,1282,1282,1288,1282,196,196,196,196,196,196,196,196,\n1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 183 */\n1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,\n1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,\n1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291,\n1292,1292,1293,1293,1293,1293,196,196,1292,1292,1292,1292,1293,1293,1292,1294,\n1295,1296,1297,1297,1298,1298,1299,1299,1299,1297,1297,1297,1297,1297,1297,1297,\n1297,1297,1297,1297,1297,1297,1297,1297,1290,1290,1290,1290,1293,1293,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 184 */\n1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,\n1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,\n1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,\n1301,1301,1301,1302,1302,1302,1302,1302,1302,1302,1302,1301,1301,1302,1301,1303,\n1302,1304,1304,1305,1300,196,196,196,196,196,196,196,196,196,196,196,\n1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,196,196,196,196,196,196,\n581,581,581,581,581,581,581,581,581,581,581,581,581,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 185 */\n1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,\n1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,\n1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1308,1309,1308,1309,1309,\n1308,1308,1308,1308,1308,1308,1310,1311,1307,1312,196,196,196,196,196,196,\n1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,196,196,196,196,196,196,\n522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,\n522,522,522,522,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 186 */\n1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,\n1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,196,196,1315,1316,1315,\n1317,1317,1315,1315,1315,1315,1316,1315,1315,1315,1315,1318,196,196,196,196,\n1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,1320,1320,1321,1321,1321,1322,\n1314,1314,1314,1314,1314,1314,1314,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 187 */\n1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,\n1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,\n1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1324,1324,1324,1325,\n1325,1325,1325,1325,1325,1325,1325,1325,1324,1326,1327,1328,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 188 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,\n1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,\n1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,\n1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,\n1331,1331,1331,1331,1331,1331,1331,1331,1331,1331,1332,1332,1332,1332,1332,1332,\n1332,1332,1332,196,196,196,196,196,196,196,196,196,196,196,196,1333,\n\n/* block 189 */\n1334,1334,1334,1334,1334,1334,1334,196,196,1334,196,196,1334,1334,1334,1334,\n1334,1334,1334,1334,196,1334,1334,196,1334,1334,1334,1334,1334,1334,1334,1334,\n1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,\n1335,1336,1336,1336,1336,1336,196,1336,1336,196,196,1337,1337,1338,1339,1340,\n1336,1340,1336,1341,1342,1343,1342,196,196,196,196,196,196,196,196,196,\n1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 190 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1345,1345,1345,1345,1345,1345,1345,1345,196,196,1345,1345,1345,1345,1345,1345,\n1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,\n1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,\n1345,1346,1346,1346,1347,1347,1347,1347,196,196,1347,1347,1346,1346,1346,1346,\n1348,1345,1349,1345,1346,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 191 */\n1350,1351,1351,1351,1351,1351,1351,1352,1352,1351,1351,1350,1350,1350,1350,1350,\n1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,\n1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,\n1350,1350,1350,1353,1354,1351,1351,1351,1351,1355,1356,1351,1351,1351,1351,1357,\n1357,1357,1358,1358,1357,1357,1357,1354,196,196,196,196,196,196,196,196,\n1359,1360,1360,1360,1360,1360,1360,1361,1361,1360,1360,1360,1359,1359,1359,1359,\n1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,\n1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,\n\n/* block 192 */\n1359,1359,1359,1359,1362,1362,1362,1362,1362,1362,1360,1360,1360,1360,1360,1360,\n1360,1360,1360,1360,1360,1360,1360,1361,1363,1364,1365,1366,1366,1359,1365,1365,\n1365,1367,1367,196,196,196,196,196,196,196,196,196,196,196,196,196,\n545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,\n1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,\n1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,\n1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,\n1368,1368,1368,1368,1368,1368,1368,1368,1368,196,196,196,196,196,196,196,\n\n/* block 193 */\n385,385,385,385,385,385,385,385,385,385,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 194 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,\n1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,\n1369,1370,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1371,1371,1371,1371,1371,1371,1371,1371,1371,1371,196,196,196,196,196,196,\n\n/* block 195 */\n1372,1372,1372,1372,1372,1372,1372,1372,1372,196,1372,1372,1372,1372,1372,1372,\n1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,\n1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373,\n1374,1374,1374,1374,1374,1374,1374,196,1374,1374,1374,1374,1374,1374,1373,1375,\n1372,1376,1376,1377,1378,1378,196,196,196,196,196,196,196,196,196,196,\n1379,1379,1379,1379,1379,1379,1379,1379,1379,1379,1380,1380,1380,1380,1380,1380,\n1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,196,196,196,\n1381,1382,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,\n\n/* block 196 */\n1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,\n196,196,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,\n1384,1384,1384,1384,1384,1384,1384,1384,196,1385,1384,1384,1384,1384,1384,1384,\n1384,1385,1384,1384,1385,1384,1384,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 197 */\n1386,1386,1386,1386,1386,1386,1386,196,1386,1386,196,1386,1386,1386,1386,1386,\n1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,\n1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,\n1386,1387,1387,1387,1387,1387,1387,196,196,196,1387,196,1387,1387,196,1387,\n1387,1387,1388,1387,1389,1389,1390,1387,196,196,196,196,196,196,196,196,\n1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,196,196,196,196,196,196,\n1392,1392,1392,1392,1392,1392,196,1392,1392,196,1392,1392,1392,1392,1392,1392,\n1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,\n\n/* block 198 */\n1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1393,1393,1393,1393,1393,196,\n1394,1394,196,1393,1393,1394,1393,1395,1392,196,196,196,196,196,196,196,\n1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 199 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,\n1397,1397,1397,1398,1398,1399,1399,1400,1400,196,196,196,196,196,196,196,\n\n/* block 200 */\n1401,1401,1402,1403,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,\n1404,196,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,\n1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,\n1404,1404,1404,1404,1403,1403,1401,1401,1401,1401,1401,196,196,196,1403,1403,\n1401,1405,1406,1407,1407,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,\n1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1410,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 201 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n914,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,\n435,435,1411,435,1411,437,437,437,437,437,437,437,437,438,438,438,\n438,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,\n437,437,196,196,196,196,196,196,196,196,196,196,196,196,196,1412,\n\n/* block 202 */\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n\n/* block 203 */\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 204 */\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,\n1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,196,\n1415,1415,1415,1415,1415,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 205 */\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,\n1413,1413,1413,1413,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 206 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,\n1416,1417,1417,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 207 */\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n\n/* block 208 */\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,\n1420,1418,1418,1418,1418,1418,1418,1421,1421,1421,1421,1421,1421,1421,1421,1421,\n1421,1421,1421,1421,1421,1421,196,196,196,196,196,196,196,196,196,196,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n\n/* block 209 */\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,\n1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,196,196,196,196,196,\n\n/* block 210 */\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n\n/* block 211 */\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,\n1422,1422,1422,1422,1422,1422,1422,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 212 */\n1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,\n1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1424,1424,\n1424,1424,1424,1424,1424,1424,1424,1424,1424,1424,1425,1425,1425,1424,1424,1426,\n1427,1427,1427,1427,1427,1427,1427,1427,1427,1427,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 213 */\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n\n/* block 214 */\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,\n930,930,930,930,930,930,930,930,930,196,196,196,196,196,196,196,\n1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,\n1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,196,\n1429,1429,1429,1429,1429,1429,1429,1429,1429,1429,196,196,196,196,1430,1430,\n1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,\n\n/* block 215 */\n1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,\n1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,\n1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,\n1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,196,\n1432,1432,1432,1432,1432,1432,1432,1432,1432,1432,196,196,196,196,196,196,\n1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,\n1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,196,196,\n1434,1434,1434,1434,1434,1435,196,196,196,196,196,196,196,196,196,196,\n\n/* block 216 */\n1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,\n1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,\n1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,\n1437,1437,1437,1437,1437,1437,1437,1438,1438,1439,1440,1440,1441,1441,1441,1441,\n1442,1442,1443,1443,1438,1441,196,196,196,196,196,196,196,196,196,196,\n1444,1444,1444,1444,1444,1444,1444,1444,1444,1444,196,1445,1445,1445,1445,1445,\n1445,1445,196,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,\n1436,1436,1436,1436,1436,1436,1436,1436,196,196,196,196,196,1436,1436,1436,\n\n/* block 217 */\n1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 218 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1446,1446,1446,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,\n1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,\n1447,1447,1447,1448,1447,1447,1447,1448,1448,1448,1448,1449,1449,1450,1451,1451,\n1452,1452,1452,1452,1452,1452,1452,1452,1452,1452,196,196,196,196,196,196,\n\n/* block 219 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,\n1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,\n1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,\n1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,\n\n/* block 220 */\n1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,\n1455,1455,1455,1455,1455,1455,1455,1456,1457,1458,1458,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 221 */\n1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,\n1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,\n1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,\n1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,\n1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,196,196,196,196,1460,\n1459,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,\n1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,\n1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,\n\n/* block 222 */\n1461,1461,1461,1461,1461,1461,1461,1461,196,196,196,196,196,196,196,1462,\n1462,1462,1462,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1464,1465,1466,867,1467,196,196,196,196,196,196,196,196,196,196,196,\n1468,1468,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 223 */\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n\n/* block 224 */\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,\n1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196,196,\n\n/* block 225 */\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n\n/* block 226 */\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,\n1470,1470,1470,1470,1470,1470,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,1470,\n\n/* block 227 */\n1469,1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 228 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1471,1471,1471,1471,196,1471,1471,1471,1471,1471,1471,1471,196,1471,1471,196,\n\n/* block 229 */\n896,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n\n/* block 230 */\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n\n/* block 231 */\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,\n896,896,896,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,891,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n891,891,891,196,196,896,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,896,896,896,896,196,196,196,196,196,196,196,196,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n\n/* block 232 */\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n\n/* block 233 */\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,\n1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,196,196,196,196,\n\n/* block 234 */\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,\n\n/* block 235 */\n1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196,196,196,\n1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,1474,1475,1476,1477,\n1478,1478,1478,1478,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 236 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n\n/* block 237 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196,\n\n/* block 238 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 239 */\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,196,196,\n176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,\n176,176,176,176,176,176,176,196,196,196,196,196,196,196,196,196,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n\n/* block 240 */\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 241 */\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n\n/* block 242 */\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,196,196,196,196,196,196,196,196,196,196,\n\n/* block 243 */\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,196,196,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,1480,1480,176,176,176,510,510,510,1481,1481,1481,\n1481,1481,1481, 51, 51, 51, 51, 51, 51, 51, 51,176,176,176,176,176,\n\n/* block 244 */\n176,176,176,510,510,176,176,176,176,176,176,176,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,176,176,176,176,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,781,781,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 245 */\n1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,\n1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,\n1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,\n1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,\n1077,1077,1482,1482,1482,1077,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 246 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,\n907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196,\n907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,\n907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 247 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,196,196,196,196,196,196,196,196,196,\n904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,\n904,904,907,907,907,907,907,907,907,196,196,196,196,196,196,196,\n\n/* block 248 */\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783,\n783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783,\n783,783,783,783,783,196,795,795,783,783,783,783,783,783,783,783,\n783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n\n/* block 249 */\n782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,783,782,196,782,782,\n196,196,782,196,196,782,782,196,196,782,782,782,782,196,782,782,\n782,782,782,782,782,782,783,783,783,783,196,783,196,783,795,795,\n783,783,783,783,196,783,783,783,783,783,783,783,783,783,783,783,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783,\n783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783,\n\n/* block 250 */\n783,783,783,783,782,782,196,782,782,782,782,196,196,782,782,782,\n782,782,782,782,782,196,782,782,782,782,782,782,782,196,783,783,\n783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783,\n783,783,783,783,783,783,783,783,782,782,196,782,782,782,782,196,\n782,782,782,782,782,196,782,196,196,196,782,782,782,782,782,782,\n782,196,783,783,783,783,783,783,783,783,795,795,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n\n/* block 251 */\n782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795,\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783,\n783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783,\n783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783,\n\n/* block 252 */\n783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795,\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n\n/* block 253 */\n782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783,\n783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,783,783,196,196,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,1483,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,1483,783,783,783,783,\n783,783,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,1483,783,783,783,783,\n\n/* block 254 */\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,783,1483,783,783,783,783,783,783,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,1483,783,783,783,783,783,783,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,1483,\n783,783,783,783,783,783,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,1483,\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n\n/* block 255 */\n783,783,783,783,783,783,783,783,783,1483,783,783,783,783,783,783,\n782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,\n782,782,782,782,782,782,782,782,782,1483,783,783,783,783,783,783,\n783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,\n783,783,783,1483,783,783,783,783,783,783,782,783,196,196,1484,1484,\n1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,\n1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,\n1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,\n\n/* block 256 */\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n\n/* block 257 */\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1485,1485,1485,1485,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1485,1485,1485,\n1485,1485,1485,1485,1485,1486,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,\n\n/* block 258 */\n1485,1485,1485,1485,1486,1485,1485,1487,1488,1487,1487,1489,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,1486,1486,1486,1486,1486,\n196,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 259 */\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 93, 70, 70, 70, 70, 70,\n 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,196,\n196,196,196,196,196, 70, 70, 70, 70, 70, 70,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 260 */\n1490,1490,1490,1490,1490,1490,1490,196,1490,1490,1490,1490,1490,1490,1490,1490,\n1490,1490,1490,1490,1490,1490,1490,1490,1490,196,196,1490,1490,1490,1490,1490,\n1490,1490,196,1490,1490,196,1490,1490,1490,1490,1490,196,196,196,196,196,\n929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,\n929,929,929,929,929,929,929,929,929,929,929,929,1491,1491,929,929,\n929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,\n929,929,929,929,929,929,929,929,1491,929,929,929,929,929,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 261 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,849,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 262 */\n1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,\n1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,\n1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,196,196,196,\n1493,1493,1493,1493,1493,1493,1493,1494,1494,1494,1494,1494,1495,1495,196,196,\n1496,1496,1496,1496,1496,1496,1496,1496,1496,1496,196,196,196,196,1492,1497,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 263 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,\n1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1499,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,\n1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,\n1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1501,1501,1501,1501,\n1502,1502,1502,1502,1502,1502,1502,1502,1502,1502,196,196,196,196,196,1503,\n\n/* block 264 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,\n1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1505,1506,1506,1506,1506,\n1507,1507,1507,1507,1507,1507,1507,1507,1507,1507,196,196,196,196,196,196,\n\n/* block 265 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,\n1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1509,1510,\n1508,1511,1511,1511,1511,1511,1511,1511,1511,1511,1511,196,196,196,196,1512,\n\n/* block 266 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n533,533,533,533,533,533,533,196,533,533,533,533,196,533,533,196,\n533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,196,\n\n/* block 267 */\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n\n/* block 268 */\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,\n1513,1513,1513,1513,1513,297,297,1514,1514,1514,1514,1514,1514,1514,1514,1514,\n1515,1515,1515,1515,1515,1515,1515,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 269 */\n1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,\n1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,\n1516,1516,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,\n1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,\n1517,1517,1517,1517,1518,1518,1518,1519,1520,1520,1520,1521,297,297,297,297,\n1522,1522,1522,1522,1522,1522,1522,1522,1522,1522,297,297,297,297,1523,1523,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 270 */\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 271 */\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,\n\n/* block 272 */\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524,1524,1524,\n1526,1524,1524,1524,1524,340,340,340,340,340,340,340,340,340,340,340,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 273 */\n340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524,\n1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,\n\n/* block 274 */\n1527,1527,1527,1527,340,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,\n1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,\n340,1527,1527,340,1527,340,340,1527,340,1527,1527,1527,1527,1527,1527,1527,\n1527,1527,1527,340,1527,1527,1527,1527,340,1527,340,1527,340,340,340,340,\n340,340,1527,340,340,340,340,1527,340,1527,340,1527,340,1527,1527,1527,\n340,1527,1527,340,1527,340,340,1527,340,1527,340,1527,340,1527,340,1527,\n340,1527,1527,340,1527,340,340,1527,1527,1527,1527,340,1527,1527,1527,1527,\n1527,1527,1527,340,1527,1527,1527,1527,340,1527,1527,1527,1527,340,1527,340,\n\n/* block 275 */\n1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527,\n1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340,\n340,1527,1527,1527,340,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527,\n1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n309,309,340,340,340,340,340,340,340,340,340,340,340,340,340,340,\n\n/* block 276 */\n1528,1528,1528,1528,1529,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n\n/* block 277 */\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,\n1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1529,\n1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 278 */\n814,814,814,814,814,814,814,814,814,814,814, 58, 58,1528,1528,1528,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1528,\n1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,\n1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,510,510,\n1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,\n1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,781,781,1528,1528,1528,1528,\n1532,1532,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1532,1532,\n\n/* block 279 */\n1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,1533,510,\n510,1533,1533,1533,1533,1533,1533,1533,1533,1533,1533,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,1528,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,\n1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,\n\n/* block 280 */\n1535,1533,1536,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n510,510,510,510,510,510,510,510,510,510,1533,510,510,510,510,510,\n510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1533,\n510,510,1533,1533,1533,1533,1533,1536,1533,1533,1533,510,1530,1530,1530,1530,\n510,510,510,510,510,510,510,510,510,1530,1530,1530,1530,1530,1530,1530,\n1537,1537,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 281 */\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 282 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,785,1528,1528,785,785,785,785,785,785,785,785,785,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,785,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1529,1529,\n\n/* block 283 */\n1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1528,1528,785,785,1528,785,785,785,1528,1528,785,785,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1538,1538,1538,1529,1529,1538,1529,1529,1538,1539,1539,785,785,1529,\n1529,1529,1529,1529,785,785,785,785,785,785,785,785,785,785,785,785,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1528,1528,785,1529,785,1528,785,1529,1529,1529,1540,1540,1540,1540,1540,\n\n/* block 284 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,\n1529,785,1538,1538,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,\n1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,\n1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529,1529,1538,1529,1529,1529,\n\n/* block 285 */\n1529,1538,1538,1538,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1538,\n1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1528,1529,\n\n/* block 286 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,781,781,\n781,781,781,781,781,781,1528,1528,1528,785,785,1529,1529,1529,1529,1528,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,1528,1528,785,\n785,1528,1528,785,1539,1539,785,785,785,785,1538,1528,1528,1528,1528,1528,\n\n/* block 287 */\n1528,1528,1528,1528,1528,1528,1528,785,1528,1528,785,785,785,785,1528,1528,\n1539,1528,1528,1528,1528,1538,1538,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1529,785,1528,1528,785,1528,1528,1528,1528,1528,1528,1528,\n1528,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,785,1528,1528,1528,\n1528,1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,785,785,785,1528,\n1528,785,1528,785,1528,1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785,\n1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785,1529,1529,1529,1529,1529,\n\n/* block 288 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1538,1538,1538,1538,1538,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n\n/* block 289 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1538,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,785,1538,785,785,785,\n1529,1529,1529,1528,1528,1529,1529,1529,1530,1530,1530,1530,1529,1529,1529,1529,\n785,785,785,785,785,785,1528,1528,1528,785,1528,1529,1529,1530,1530,1530,\n785,1528,1528,785,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,\n\n/* block 290 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,1528,1528,1528,1530,1530,1530,1530,1528,1528,1528,1528,1528,\n\n/* block 291 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,\n1529,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 292 */\n781,781,781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530,\n781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n\n/* block 293 */\n781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,1530,1530,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,\n1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 294 */\n781,781,781,781,781,781,781,781,781,781,781,781,1538,1529,1529,1538,\n1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,\n1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,781,1538,1538,1538,1529,\n1529,1529,1529,1529,1529,1529,781,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,\n\n/* block 295 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1541,1541,1541,1541,1529,1538,1538,1529,1538,1538,1529,1538,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538,\n1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n\n/* block 296 */\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,\n1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,\n\n/* block 297 */\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,\n1529,1529,1529,1538,1538,1538,1529,1530,1530,1530,1530,1530,1530,1530,1529,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1529,\n1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1530,\n1538,1538,1538,1538,1538,1538,1538,1538,1538,1530,1530,1530,1530,1530,1530,1530,\n\n/* block 298 */\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,196,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,\n1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196,\n\n/* block 299 */\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,\n1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1032,1032,\n\n/* block 300 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 301 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,196,196,196,196,196,196,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 302 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 303 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 304 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 305 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 306 */\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,\n1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 307 */\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,1032,1032,\n\n/* block 308 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,196,196,196,196,196,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n\n/* block 309 */\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,\n\n/* block 310 */\n765,770,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,\n\n/* block 311 */\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n\n/* block 312 */\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n\n/* block 313 */\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,\n765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,\n\n/* block 314 */\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,\n1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1032,1032,\n};\n\n#if UCD_BLOCK_SIZE != 128\n#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h\n#endif\n#endif  /* SUPPORT_UNICODE */\n\n#endif  /* PCRE2_PCRE2TEST */\n\n/* End of pcre2_ucd.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_ucp.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2022 University of Cambridge\n\nThis module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!\nInstead, modify the maint/GenerateUcpHeader.py script and run it to generate\na new version of this code.\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_UCP_H_IDEMPOTENT_GUARD\n#define PCRE2_UCP_H_IDEMPOTENT_GUARD\n\n/* This file contains definitions of the Unicode property values that are\nreturned by the UCD access macros and used throughout PCRE2.\n\nIMPORTANT: The specific values of the first two enums (general and particular\ncharacter categories) are assumed by the table called catposstab in the file\npcre2_auto_possess.c. They are unlikely to change, but should be checked after\nan update. */\n\n/* These are the general character categories. */\n\nenum {\n  ucp_C,\n  ucp_L,\n  ucp_M,\n  ucp_N,\n  ucp_P,\n  ucp_S,\n  ucp_Z,\n};\n\n/* These are the particular character categories. */\n\nenum {\n  ucp_Cc,    /* Control */\n  ucp_Cf,    /* Format */\n  ucp_Cn,    /* Unassigned */\n  ucp_Co,    /* Private use */\n  ucp_Cs,    /* Surrogate */\n  ucp_Ll,    /* Lower case letter */\n  ucp_Lm,    /* Modifier letter */\n  ucp_Lo,    /* Other letter */\n  ucp_Lt,    /* Title case letter */\n  ucp_Lu,    /* Upper case letter */\n  ucp_Mc,    /* Spacing mark */\n  ucp_Me,    /* Enclosing mark */\n  ucp_Mn,    /* Non-spacing mark */\n  ucp_Nd,    /* Decimal number */\n  ucp_Nl,    /* Letter number */\n  ucp_No,    /* Other number */\n  ucp_Pc,    /* Connector punctuation */\n  ucp_Pd,    /* Dash punctuation */\n  ucp_Pe,    /* Close punctuation */\n  ucp_Pf,    /* Final punctuation */\n  ucp_Pi,    /* Initial punctuation */\n  ucp_Po,    /* Other punctuation */\n  ucp_Ps,    /* Open punctuation */\n  ucp_Sc,    /* Currency symbol */\n  ucp_Sk,    /* Modifier symbol */\n  ucp_Sm,    /* Mathematical symbol */\n  ucp_So,    /* Other symbol */\n  ucp_Zl,    /* Line separator */\n  ucp_Zp,    /* Paragraph separator */\n  ucp_Zs,    /* Space separator */\n};\n\n/* These are Boolean properties. */\n\nenum {\n  ucp_ASCII,\n  ucp_ASCII_Hex_Digit,\n  ucp_Alphabetic,\n  ucp_Bidi_Control,\n  ucp_Bidi_Mirrored,\n  ucp_Case_Ignorable,\n  ucp_Cased,\n  ucp_Changes_When_Casefolded,\n  ucp_Changes_When_Casemapped,\n  ucp_Changes_When_Lowercased,\n  ucp_Changes_When_Titlecased,\n  ucp_Changes_When_Uppercased,\n  ucp_Dash,\n  ucp_Default_Ignorable_Code_Point,\n  ucp_Deprecated,\n  ucp_Diacritic,\n  ucp_Emoji,\n  ucp_Emoji_Component,\n  ucp_Emoji_Modifier,\n  ucp_Emoji_Modifier_Base,\n  ucp_Emoji_Presentation,\n  ucp_Extended_Pictographic,\n  ucp_Extender,\n  ucp_Grapheme_Base,\n  ucp_Grapheme_Extend,\n  ucp_Grapheme_Link,\n  ucp_Hex_Digit,\n  ucp_IDS_Binary_Operator,\n  ucp_IDS_Trinary_Operator,\n  ucp_IDS_Unary_Operator,\n  ucp_ID_Compat_Math_Continue,\n  ucp_ID_Compat_Math_Start,\n  ucp_ID_Continue,\n  ucp_ID_Start,\n  ucp_Ideographic,\n  ucp_InCB,\n  ucp_Join_Control,\n  ucp_Logical_Order_Exception,\n  ucp_Lowercase,\n  ucp_Math,\n  ucp_Modifier_Combining_Mark,\n  ucp_Noncharacter_Code_Point,\n  ucp_Pattern_Syntax,\n  ucp_Pattern_White_Space,\n  ucp_Prepended_Concatenation_Mark,\n  ucp_Quotation_Mark,\n  ucp_Radical,\n  ucp_Regional_Indicator,\n  ucp_Sentence_Terminal,\n  ucp_Soft_Dotted,\n  ucp_Terminal_Punctuation,\n  ucp_Unified_Ideograph,\n  ucp_Uppercase,\n  ucp_Variation_Selector,\n  ucp_White_Space,\n  ucp_XID_Continue,\n  ucp_XID_Start,\n  /* This must be last */\n  ucp_Bprop_Count\n};\n\n/* Size of entries in ucd_boolprop_sets[] */\n\n#define ucd_boolprop_sets_item_size 2\n\n/* These are the bidi class values. */\n\nenum {\n  ucp_bidiAL,   /* Arabic_Letter */\n  ucp_bidiAN,   /* Arabic_Number */\n  ucp_bidiB,    /* Paragraph_Separator */\n  ucp_bidiBN,   /* Boundary_Neutral */\n  ucp_bidiCS,   /* Common_Separator */\n  ucp_bidiEN,   /* European_Number */\n  ucp_bidiES,   /* European_Separator */\n  ucp_bidiET,   /* European_Terminator */\n  ucp_bidiFSI,  /* First_Strong_Isolate */\n  ucp_bidiL,    /* Left_To_Right */\n  ucp_bidiLRE,  /* Left_To_Right_Embedding */\n  ucp_bidiLRI,  /* Left_To_Right_Isolate */\n  ucp_bidiLRO,  /* Left_To_Right_Override */\n  ucp_bidiNSM,  /* Nonspacing_Mark */\n  ucp_bidiON,   /* Other_Neutral */\n  ucp_bidiPDF,  /* Pop_Directional_Format */\n  ucp_bidiPDI,  /* Pop_Directional_Isolate */\n  ucp_bidiR,    /* Right_To_Left */\n  ucp_bidiRLE,  /* Right_To_Left_Embedding */\n  ucp_bidiRLI,  /* Right_To_Left_Isolate */\n  ucp_bidiRLO,  /* Right_To_Left_Override */\n  ucp_bidiS,    /* Segment_Separator */\n  ucp_bidiWS,   /* White_Space */\n};\n\n/* These are grapheme break properties. The Extended Pictographic property\ncomes from the emoji-data.txt file. */\n\nenum {\n  ucp_gbCR,                    /*  0 */\n  ucp_gbLF,                    /*  1 */\n  ucp_gbControl,               /*  2 */\n  ucp_gbExtend,                /*  3 */\n  ucp_gbPrepend,               /*  4 */\n  ucp_gbSpacingMark,           /*  5 */\n  ucp_gbL,                     /*  6 Hangul syllable type L */\n  ucp_gbV,                     /*  7 Hangul syllable type V */\n  ucp_gbT,                     /*  8 Hangul syllable type T */\n  ucp_gbLV,                    /*  9 Hangul syllable type LV */\n  ucp_gbLVT,                   /* 10 Hangul syllable type LVT */\n  ucp_gbRegional_Indicator,    /* 11 */\n  ucp_gbOther,                 /* 12 */\n  ucp_gbZWJ,                   /* 13 */\n  ucp_gbExtended_Pictographic, /* 14 */\n};\n\n/* These are the script identifications. */\n\nenum {\n  /* Scripts which has characters in other scripts. */\n  ucp_Latin,\n  ucp_Greek,\n  ucp_Cyrillic,\n  ucp_Armenian,\n  ucp_Hebrew,\n  ucp_Arabic,\n  ucp_Syriac,\n  ucp_Thaana,\n  ucp_Devanagari,\n  ucp_Bengali,\n  ucp_Gurmukhi,\n  ucp_Gujarati,\n  ucp_Oriya,\n  ucp_Tamil,\n  ucp_Telugu,\n  ucp_Kannada,\n  ucp_Malayalam,\n  ucp_Sinhala,\n  ucp_Thai,\n  ucp_Tibetan,\n  ucp_Myanmar,\n  ucp_Georgian,\n  ucp_Hangul,\n  ucp_Ethiopic,\n  ucp_Cherokee,\n  ucp_Runic,\n  ucp_Mongolian,\n  ucp_Hiragana,\n  ucp_Katakana,\n  ucp_Bopomofo,\n  ucp_Han,\n  ucp_Yi,\n  ucp_Gothic,\n  ucp_Tagalog,\n  ucp_Hanunoo,\n  ucp_Buhid,\n  ucp_Tagbanwa,\n  ucp_Limbu,\n  ucp_Tai_Le,\n  ucp_Linear_B,\n  ucp_Shavian,\n  ucp_Cypriot,\n  ucp_Buginese,\n  ucp_Coptic,\n  ucp_Glagolitic,\n  ucp_Tifinagh,\n  ucp_Syloti_Nagri,\n  ucp_Phags_Pa,\n  ucp_Nko,\n  ucp_Kayah_Li,\n  ucp_Lycian,\n  ucp_Carian,\n  ucp_Lydian,\n  ucp_Avestan,\n  ucp_Samaritan,\n  ucp_Lisu,\n  ucp_Javanese,\n  ucp_Old_Turkic,\n  ucp_Kaithi,\n  ucp_Mandaic,\n  ucp_Chakma,\n  ucp_Meroitic_Hieroglyphs,\n  ucp_Sharada,\n  ucp_Takri,\n  ucp_Caucasian_Albanian,\n  ucp_Duployan,\n  ucp_Elbasan,\n  ucp_Grantha,\n  ucp_Khojki,\n  ucp_Linear_A,\n  ucp_Mahajani,\n  ucp_Manichaean,\n  ucp_Modi,\n  ucp_Old_Permic,\n  ucp_Psalter_Pahlavi,\n  ucp_Khudawadi,\n  ucp_Tirhuta,\n  ucp_Multani,\n  ucp_Old_Hungarian,\n  ucp_Adlam,\n  ucp_Osage,\n  ucp_Tangut,\n  ucp_Masaram_Gondi,\n  ucp_Dogra,\n  ucp_Gunjala_Gondi,\n  ucp_Hanifi_Rohingya,\n  ucp_Sogdian,\n  ucp_Nandinagari,\n  ucp_Yezidi,\n  ucp_Cypro_Minoan,\n  ucp_Old_Uyghur,\n  ucp_Toto,\n  ucp_Garay,\n  ucp_Gurung_Khema,\n  ucp_Ol_Onal,\n  ucp_Sunuwar,\n  ucp_Todhri,\n  ucp_Tulu_Tigalari,\n\n  /* Scripts which has no characters in other scripts. */\n  ucp_Unknown,\n  ucp_Common,\n  ucp_Lao,\n  ucp_Canadian_Aboriginal,\n  ucp_Ogham,\n  ucp_Khmer,\n  ucp_Old_Italic,\n  ucp_Deseret,\n  ucp_Inherited,\n  ucp_Ugaritic,\n  ucp_Osmanya,\n  ucp_Braille,\n  ucp_New_Tai_Lue,\n  ucp_Old_Persian,\n  ucp_Kharoshthi,\n  ucp_Balinese,\n  ucp_Cuneiform,\n  ucp_Phoenician,\n  ucp_Sundanese,\n  ucp_Lepcha,\n  ucp_Ol_Chiki,\n  ucp_Vai,\n  ucp_Saurashtra,\n  ucp_Rejang,\n  ucp_Cham,\n  ucp_Tai_Tham,\n  ucp_Tai_Viet,\n  ucp_Egyptian_Hieroglyphs,\n  ucp_Bamum,\n  ucp_Meetei_Mayek,\n  ucp_Imperial_Aramaic,\n  ucp_Old_South_Arabian,\n  ucp_Inscriptional_Parthian,\n  ucp_Inscriptional_Pahlavi,\n  ucp_Batak,\n  ucp_Brahmi,\n  ucp_Meroitic_Cursive,\n  ucp_Miao,\n  ucp_Sora_Sompeng,\n  ucp_Bassa_Vah,\n  ucp_Pahawh_Hmong,\n  ucp_Mende_Kikakui,\n  ucp_Mro,\n  ucp_Old_North_Arabian,\n  ucp_Nabataean,\n  ucp_Palmyrene,\n  ucp_Pau_Cin_Hau,\n  ucp_Siddham,\n  ucp_Warang_Citi,\n  ucp_Ahom,\n  ucp_Anatolian_Hieroglyphs,\n  ucp_Hatran,\n  ucp_SignWriting,\n  ucp_Bhaiksuki,\n  ucp_Marchen,\n  ucp_Newa,\n  ucp_Nushu,\n  ucp_Soyombo,\n  ucp_Zanabazar_Square,\n  ucp_Makasar,\n  ucp_Medefaidrin,\n  ucp_Old_Sogdian,\n  ucp_Elymaic,\n  ucp_Nyiakeng_Puachue_Hmong,\n  ucp_Wancho,\n  ucp_Chorasmian,\n  ucp_Dives_Akuru,\n  ucp_Khitan_Small_Script,\n  ucp_Tangsa,\n  ucp_Vithkuqi,\n  ucp_Kawi,\n  ucp_Nag_Mundari,\n  ucp_Kirat_Rai,\n\n  /* This must be last */\n  ucp_Script_Count\n};\n\n/* Size of entries in ucd_script_sets[] */\n\n#define ucd_script_sets_item_size 4\n\n#endif  /* PCRE2_UCP_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2_ucp.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_ucptables_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2022 University of Cambridge\n\nThis module is auto-generated from Unicode data files. DO NOT EDIT MANUALLY!\nInstead, modify the maint/GenerateUcpTables.py script and run it to generate\na new version of this code.\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifdef SUPPORT_UNICODE\n\n/* The PRIV(utt)[] table below translates Unicode property names into type and\ncode values. It is searched by binary chop, so must be in collating sequence of\nname. Originally, the table contained pointers to the name strings in the first\nfield of each entry. However, that leads to a large number of relocations when\na shared library is dynamically loaded. A significant reduction is made by\nputting all the names into a single, large string and using offsets instead.\nAll letters are lower cased, and underscores are removed, in accordance with\nthe \"loose matching\" rules that Unicode advises and Perl uses. */\n\n#define STRING_adlam0 STR_a STR_d STR_l STR_a STR_m \"\\0\"\n#define STRING_adlm0 STR_a STR_d STR_l STR_m \"\\0\"\n#define STRING_aghb0 STR_a STR_g STR_h STR_b \"\\0\"\n#define STRING_ahex0 STR_a STR_h STR_e STR_x \"\\0\"\n#define STRING_ahom0 STR_a STR_h STR_o STR_m \"\\0\"\n#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a \"\\0\"\n#define STRING_alphabetic0 STR_a STR_l STR_p STR_h STR_a STR_b STR_e STR_t STR_i STR_c \"\\0\"\n#define STRING_anatolianhieroglyphs0 STR_a STR_n STR_a STR_t STR_o STR_l STR_i STR_a STR_n STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s \"\\0\"\n#define STRING_any0 STR_a STR_n STR_y \"\\0\"\n#define STRING_arab0 STR_a STR_r STR_a STR_b \"\\0\"\n#define STRING_arabic0 STR_a STR_r STR_a STR_b STR_i STR_c \"\\0\"\n#define STRING_armenian0 STR_a STR_r STR_m STR_e STR_n STR_i STR_a STR_n \"\\0\"\n#define STRING_armi0 STR_a STR_r STR_m STR_i \"\\0\"\n#define STRING_armn0 STR_a STR_r STR_m STR_n \"\\0\"\n#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i \"\\0\"\n#define STRING_asciihexdigit0 STR_a STR_s STR_c STR_i STR_i STR_h STR_e STR_x STR_d STR_i STR_g STR_i STR_t \"\\0\"\n#define STRING_avestan0 STR_a STR_v STR_e STR_s STR_t STR_a STR_n \"\\0\"\n#define STRING_avst0 STR_a STR_v STR_s STR_t \"\\0\"\n#define STRING_bali0 STR_b STR_a STR_l STR_i \"\\0\"\n#define STRING_balinese0 STR_b STR_a STR_l STR_i STR_n STR_e STR_s STR_e \"\\0\"\n#define STRING_bamu0 STR_b STR_a STR_m STR_u \"\\0\"\n#define STRING_bamum0 STR_b STR_a STR_m STR_u STR_m \"\\0\"\n#define STRING_bass0 STR_b STR_a STR_s STR_s \"\\0\"\n#define STRING_bassavah0 STR_b STR_a STR_s STR_s STR_a STR_v STR_a STR_h \"\\0\"\n#define STRING_batak0 STR_b STR_a STR_t STR_a STR_k \"\\0\"\n#define STRING_batk0 STR_b STR_a STR_t STR_k \"\\0\"\n#define STRING_beng0 STR_b STR_e STR_n STR_g \"\\0\"\n#define STRING_bengali0 STR_b STR_e STR_n STR_g STR_a STR_l STR_i \"\\0\"\n#define STRING_bhaiksuki0 STR_b STR_h STR_a STR_i STR_k STR_s STR_u STR_k STR_i \"\\0\"\n#define STRING_bhks0 STR_b STR_h STR_k STR_s \"\\0\"\n#define STRING_bidial0 STR_b STR_i STR_d STR_i STR_a STR_l \"\\0\"\n#define STRING_bidian0 STR_b STR_i STR_d STR_i STR_a STR_n \"\\0\"\n#define STRING_bidib0 STR_b STR_i STR_d STR_i STR_b \"\\0\"\n#define STRING_bidibn0 STR_b STR_i STR_d STR_i STR_b STR_n \"\\0\"\n#define STRING_bidic0 STR_b STR_i STR_d STR_i STR_c \"\\0\"\n#define STRING_bidicontrol0 STR_b STR_i STR_d STR_i STR_c STR_o STR_n STR_t STR_r STR_o STR_l \"\\0\"\n#define STRING_bidics0 STR_b STR_i STR_d STR_i STR_c STR_s \"\\0\"\n#define STRING_bidien0 STR_b STR_i STR_d STR_i STR_e STR_n \"\\0\"\n#define STRING_bidies0 STR_b STR_i STR_d STR_i STR_e STR_s \"\\0\"\n#define STRING_bidiet0 STR_b STR_i STR_d STR_i STR_e STR_t \"\\0\"\n#define STRING_bidifsi0 STR_b STR_i STR_d STR_i STR_f STR_s STR_i \"\\0\"\n#define STRING_bidil0 STR_b STR_i STR_d STR_i STR_l \"\\0\"\n#define STRING_bidilre0 STR_b STR_i STR_d STR_i STR_l STR_r STR_e \"\\0\"\n#define STRING_bidilri0 STR_b STR_i STR_d STR_i STR_l STR_r STR_i \"\\0\"\n#define STRING_bidilro0 STR_b STR_i STR_d STR_i STR_l STR_r STR_o \"\\0\"\n#define STRING_bidim0 STR_b STR_i STR_d STR_i STR_m \"\\0\"\n#define STRING_bidimirrored0 STR_b STR_i STR_d STR_i STR_m STR_i STR_r STR_r STR_o STR_r STR_e STR_d \"\\0\"\n#define STRING_bidinsm0 STR_b STR_i STR_d STR_i STR_n STR_s STR_m \"\\0\"\n#define STRING_bidion0 STR_b STR_i STR_d STR_i STR_o STR_n \"\\0\"\n#define STRING_bidipdf0 STR_b STR_i STR_d STR_i STR_p STR_d STR_f \"\\0\"\n#define STRING_bidipdi0 STR_b STR_i STR_d STR_i STR_p STR_d STR_i \"\\0\"\n#define STRING_bidir0 STR_b STR_i STR_d STR_i STR_r \"\\0\"\n#define STRING_bidirle0 STR_b STR_i STR_d STR_i STR_r STR_l STR_e \"\\0\"\n#define STRING_bidirli0 STR_b STR_i STR_d STR_i STR_r STR_l STR_i \"\\0\"\n#define STRING_bidirlo0 STR_b STR_i STR_d STR_i STR_r STR_l STR_o \"\\0\"\n#define STRING_bidis0 STR_b STR_i STR_d STR_i STR_s \"\\0\"\n#define STRING_bidiws0 STR_b STR_i STR_d STR_i STR_w STR_s \"\\0\"\n#define STRING_bopo0 STR_b STR_o STR_p STR_o \"\\0\"\n#define STRING_bopomofo0 STR_b STR_o STR_p STR_o STR_m STR_o STR_f STR_o \"\\0\"\n#define STRING_brah0 STR_b STR_r STR_a STR_h \"\\0\"\n#define STRING_brahmi0 STR_b STR_r STR_a STR_h STR_m STR_i \"\\0\"\n#define STRING_brai0 STR_b STR_r STR_a STR_i \"\\0\"\n#define STRING_braille0 STR_b STR_r STR_a STR_i STR_l STR_l STR_e \"\\0\"\n#define STRING_bugi0 STR_b STR_u STR_g STR_i \"\\0\"\n#define STRING_buginese0 STR_b STR_u STR_g STR_i STR_n STR_e STR_s STR_e \"\\0\"\n#define STRING_buhd0 STR_b STR_u STR_h STR_d \"\\0\"\n#define STRING_buhid0 STR_b STR_u STR_h STR_i STR_d \"\\0\"\n#define STRING_c0 STR_c \"\\0\"\n#define STRING_cakm0 STR_c STR_a STR_k STR_m \"\\0\"\n#define STRING_canadianaboriginal0 STR_c STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_a STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l \"\\0\"\n#define STRING_cans0 STR_c STR_a STR_n STR_s \"\\0\"\n#define STRING_cari0 STR_c STR_a STR_r STR_i \"\\0\"\n#define STRING_carian0 STR_c STR_a STR_r STR_i STR_a STR_n \"\\0\"\n#define STRING_cased0 STR_c STR_a STR_s STR_e STR_d \"\\0\"\n#define STRING_caseignorable0 STR_c STR_a STR_s STR_e STR_i STR_g STR_n STR_o STR_r STR_a STR_b STR_l STR_e \"\\0\"\n#define STRING_caucasianalbanian0 STR_c STR_a STR_u STR_c STR_a STR_s STR_i STR_a STR_n STR_a STR_l STR_b STR_a STR_n STR_i STR_a STR_n \"\\0\"\n#define STRING_cc0 STR_c STR_c \"\\0\"\n#define STRING_cf0 STR_c STR_f \"\\0\"\n#define STRING_chakma0 STR_c STR_h STR_a STR_k STR_m STR_a \"\\0\"\n#define STRING_cham0 STR_c STR_h STR_a STR_m \"\\0\"\n#define STRING_changeswhencasefolded0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_c STR_a STR_s STR_e STR_f STR_o STR_l STR_d STR_e STR_d \"\\0\"\n#define STRING_changeswhencasemapped0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_c STR_a STR_s STR_e STR_m STR_a STR_p STR_p STR_e STR_d \"\\0\"\n#define STRING_changeswhenlowercased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_l STR_o STR_w STR_e STR_r STR_c STR_a STR_s STR_e STR_d \"\\0\"\n#define STRING_changeswhentitlecased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_t STR_i STR_t STR_l STR_e STR_c STR_a STR_s STR_e STR_d \"\\0\"\n#define STRING_changeswhenuppercased0 STR_c STR_h STR_a STR_n STR_g STR_e STR_s STR_w STR_h STR_e STR_n STR_u STR_p STR_p STR_e STR_r STR_c STR_a STR_s STR_e STR_d \"\\0\"\n#define STRING_cher0 STR_c STR_h STR_e STR_r \"\\0\"\n#define STRING_cherokee0 STR_c STR_h STR_e STR_r STR_o STR_k STR_e STR_e \"\\0\"\n#define STRING_chorasmian0 STR_c STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n \"\\0\"\n#define STRING_chrs0 STR_c STR_h STR_r STR_s \"\\0\"\n#define STRING_ci0 STR_c STR_i \"\\0\"\n#define STRING_cn0 STR_c STR_n \"\\0\"\n#define STRING_co0 STR_c STR_o \"\\0\"\n#define STRING_common0 STR_c STR_o STR_m STR_m STR_o STR_n \"\\0\"\n#define STRING_copt0 STR_c STR_o STR_p STR_t \"\\0\"\n#define STRING_coptic0 STR_c STR_o STR_p STR_t STR_i STR_c \"\\0\"\n#define STRING_cpmn0 STR_c STR_p STR_m STR_n \"\\0\"\n#define STRING_cprt0 STR_c STR_p STR_r STR_t \"\\0\"\n#define STRING_cs0 STR_c STR_s \"\\0\"\n#define STRING_cuneiform0 STR_c STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m \"\\0\"\n#define STRING_cwcf0 STR_c STR_w STR_c STR_f \"\\0\"\n#define STRING_cwcm0 STR_c STR_w STR_c STR_m \"\\0\"\n#define STRING_cwl0 STR_c STR_w STR_l \"\\0\"\n#define STRING_cwt0 STR_c STR_w STR_t \"\\0\"\n#define STRING_cwu0 STR_c STR_w STR_u \"\\0\"\n#define STRING_cypriot0 STR_c STR_y STR_p STR_r STR_i STR_o STR_t \"\\0\"\n#define STRING_cyprominoan0 STR_c STR_y STR_p STR_r STR_o STR_m STR_i STR_n STR_o STR_a STR_n \"\\0\"\n#define STRING_cyrillic0 STR_c STR_y STR_r STR_i STR_l STR_l STR_i STR_c \"\\0\"\n#define STRING_cyrl0 STR_c STR_y STR_r STR_l \"\\0\"\n#define STRING_dash0 STR_d STR_a STR_s STR_h \"\\0\"\n#define STRING_defaultignorablecodepoint0 STR_d STR_e STR_f STR_a STR_u STR_l STR_t STR_i STR_g STR_n STR_o STR_r STR_a STR_b STR_l STR_e STR_c STR_o STR_d STR_e STR_p STR_o STR_i STR_n STR_t \"\\0\"\n#define STRING_dep0 STR_d STR_e STR_p \"\\0\"\n#define STRING_deprecated0 STR_d STR_e STR_p STR_r STR_e STR_c STR_a STR_t STR_e STR_d \"\\0\"\n#define STRING_deseret0 STR_d STR_e STR_s STR_e STR_r STR_e STR_t \"\\0\"\n#define STRING_deva0 STR_d STR_e STR_v STR_a \"\\0\"\n#define STRING_devanagari0 STR_d STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i \"\\0\"\n#define STRING_di0 STR_d STR_i \"\\0\"\n#define STRING_dia0 STR_d STR_i STR_a \"\\0\"\n#define STRING_diacritic0 STR_d STR_i STR_a STR_c STR_r STR_i STR_t STR_i STR_c \"\\0\"\n#define STRING_diak0 STR_d STR_i STR_a STR_k \"\\0\"\n#define STRING_divesakuru0 STR_d STR_i STR_v STR_e STR_s STR_a STR_k STR_u STR_r STR_u \"\\0\"\n#define STRING_dogr0 STR_d STR_o STR_g STR_r \"\\0\"\n#define STRING_dogra0 STR_d STR_o STR_g STR_r STR_a \"\\0\"\n#define STRING_dsrt0 STR_d STR_s STR_r STR_t \"\\0\"\n#define STRING_dupl0 STR_d STR_u STR_p STR_l \"\\0\"\n#define STRING_duployan0 STR_d STR_u STR_p STR_l STR_o STR_y STR_a STR_n \"\\0\"\n#define STRING_ebase0 STR_e STR_b STR_a STR_s STR_e \"\\0\"\n#define STRING_ecomp0 STR_e STR_c STR_o STR_m STR_p \"\\0\"\n#define STRING_egyp0 STR_e STR_g STR_y STR_p \"\\0\"\n#define STRING_egyptianhieroglyphs0 STR_e STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s \"\\0\"\n#define STRING_elba0 STR_e STR_l STR_b STR_a \"\\0\"\n#define STRING_elbasan0 STR_e STR_l STR_b STR_a STR_s STR_a STR_n \"\\0\"\n#define STRING_elym0 STR_e STR_l STR_y STR_m \"\\0\"\n#define STRING_elymaic0 STR_e STR_l STR_y STR_m STR_a STR_i STR_c \"\\0\"\n#define STRING_emod0 STR_e STR_m STR_o STR_d \"\\0\"\n#define STRING_emoji0 STR_e STR_m STR_o STR_j STR_i \"\\0\"\n#define STRING_emojicomponent0 STR_e STR_m STR_o STR_j STR_i STR_c STR_o STR_m STR_p STR_o STR_n STR_e STR_n STR_t \"\\0\"\n#define STRING_emojimodifier0 STR_e STR_m STR_o STR_j STR_i STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r \"\\0\"\n#define STRING_emojimodifierbase0 STR_e STR_m STR_o STR_j STR_i STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r STR_b STR_a STR_s STR_e \"\\0\"\n#define STRING_emojipresentation0 STR_e STR_m STR_o STR_j STR_i STR_p STR_r STR_e STR_s STR_e STR_n STR_t STR_a STR_t STR_i STR_o STR_n \"\\0\"\n#define STRING_epres0 STR_e STR_p STR_r STR_e STR_s \"\\0\"\n#define STRING_ethi0 STR_e STR_t STR_h STR_i \"\\0\"\n#define STRING_ethiopic0 STR_e STR_t STR_h STR_i STR_o STR_p STR_i STR_c \"\\0\"\n#define STRING_ext0 STR_e STR_x STR_t \"\\0\"\n#define STRING_extendedpictographic0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_d STR_p STR_i STR_c STR_t STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c \"\\0\"\n#define STRING_extender0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_r \"\\0\"\n#define STRING_extpict0 STR_e STR_x STR_t STR_p STR_i STR_c STR_t \"\\0\"\n#define STRING_gara0 STR_g STR_a STR_r STR_a \"\\0\"\n#define STRING_garay0 STR_g STR_a STR_r STR_a STR_y \"\\0\"\n#define STRING_geor0 STR_g STR_e STR_o STR_r \"\\0\"\n#define STRING_georgian0 STR_g STR_e STR_o STR_r STR_g STR_i STR_a STR_n \"\\0\"\n#define STRING_glag0 STR_g STR_l STR_a STR_g \"\\0\"\n#define STRING_glagolitic0 STR_g STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c \"\\0\"\n#define STRING_gong0 STR_g STR_o STR_n STR_g \"\\0\"\n#define STRING_gonm0 STR_g STR_o STR_n STR_m \"\\0\"\n#define STRING_goth0 STR_g STR_o STR_t STR_h \"\\0\"\n#define STRING_gothic0 STR_g STR_o STR_t STR_h STR_i STR_c \"\\0\"\n#define STRING_gran0 STR_g STR_r STR_a STR_n \"\\0\"\n#define STRING_grantha0 STR_g STR_r STR_a STR_n STR_t STR_h STR_a \"\\0\"\n#define STRING_graphemebase0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_b STR_a STR_s STR_e \"\\0\"\n#define STRING_graphemeextend0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_e STR_x STR_t STR_e STR_n STR_d \"\\0\"\n#define STRING_graphemelink0 STR_g STR_r STR_a STR_p STR_h STR_e STR_m STR_e STR_l STR_i STR_n STR_k \"\\0\"\n#define STRING_grbase0 STR_g STR_r STR_b STR_a STR_s STR_e \"\\0\"\n#define STRING_greek0 STR_g STR_r STR_e STR_e STR_k \"\\0\"\n#define STRING_grek0 STR_g STR_r STR_e STR_k \"\\0\"\n#define STRING_grext0 STR_g STR_r STR_e STR_x STR_t \"\\0\"\n#define STRING_grlink0 STR_g STR_r STR_l STR_i STR_n STR_k \"\\0\"\n#define STRING_gujarati0 STR_g STR_u STR_j STR_a STR_r STR_a STR_t STR_i \"\\0\"\n#define STRING_gujr0 STR_g STR_u STR_j STR_r \"\\0\"\n#define STRING_gukh0 STR_g STR_u STR_k STR_h \"\\0\"\n#define STRING_gunjalagondi0 STR_g STR_u STR_n STR_j STR_a STR_l STR_a STR_g STR_o STR_n STR_d STR_i \"\\0\"\n#define STRING_gurmukhi0 STR_g STR_u STR_r STR_m STR_u STR_k STR_h STR_i \"\\0\"\n#define STRING_guru0 STR_g STR_u STR_r STR_u \"\\0\"\n#define STRING_gurungkhema0 STR_g STR_u STR_r STR_u STR_n STR_g STR_k STR_h STR_e STR_m STR_a \"\\0\"\n#define STRING_han0 STR_h STR_a STR_n \"\\0\"\n#define STRING_hang0 STR_h STR_a STR_n STR_g \"\\0\"\n#define STRING_hangul0 STR_h STR_a STR_n STR_g STR_u STR_l \"\\0\"\n#define STRING_hani0 STR_h STR_a STR_n STR_i \"\\0\"\n#define STRING_hanifirohingya0 STR_h STR_a STR_n STR_i STR_f STR_i STR_r STR_o STR_h STR_i STR_n STR_g STR_y STR_a \"\\0\"\n#define STRING_hano0 STR_h STR_a STR_n STR_o \"\\0\"\n#define STRING_hanunoo0 STR_h STR_a STR_n STR_u STR_n STR_o STR_o \"\\0\"\n#define STRING_hatr0 STR_h STR_a STR_t STR_r \"\\0\"\n#define STRING_hatran0 STR_h STR_a STR_t STR_r STR_a STR_n \"\\0\"\n#define STRING_hebr0 STR_h STR_e STR_b STR_r \"\\0\"\n#define STRING_hebrew0 STR_h STR_e STR_b STR_r STR_e STR_w \"\\0\"\n#define STRING_hex0 STR_h STR_e STR_x \"\\0\"\n#define STRING_hexdigit0 STR_h STR_e STR_x STR_d STR_i STR_g STR_i STR_t \"\\0\"\n#define STRING_hira0 STR_h STR_i STR_r STR_a \"\\0\"\n#define STRING_hiragana0 STR_h STR_i STR_r STR_a STR_g STR_a STR_n STR_a \"\\0\"\n#define STRING_hluw0 STR_h STR_l STR_u STR_w \"\\0\"\n#define STRING_hmng0 STR_h STR_m STR_n STR_g \"\\0\"\n#define STRING_hmnp0 STR_h STR_m STR_n STR_p \"\\0\"\n#define STRING_hung0 STR_h STR_u STR_n STR_g \"\\0\"\n#define STRING_idc0 STR_i STR_d STR_c \"\\0\"\n#define STRING_idcompatmathcontinue0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e \"\\0\"\n#define STRING_idcompatmathstart0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_s STR_t STR_a STR_r STR_t \"\\0\"\n#define STRING_idcontinue0 STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e \"\\0\"\n#define STRING_ideo0 STR_i STR_d STR_e STR_o \"\\0\"\n#define STRING_ideographic0 STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c \"\\0\"\n#define STRING_ids0 STR_i STR_d STR_s \"\\0\"\n#define STRING_idsb0 STR_i STR_d STR_s STR_b \"\\0\"\n#define STRING_idsbinaryoperator0 STR_i STR_d STR_s STR_b STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r \"\\0\"\n#define STRING_idst0 STR_i STR_d STR_s STR_t \"\\0\"\n#define STRING_idstart0 STR_i STR_d STR_s STR_t STR_a STR_r STR_t \"\\0\"\n#define STRING_idstrinaryoperator0 STR_i STR_d STR_s STR_t STR_r STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r \"\\0\"\n#define STRING_idsu0 STR_i STR_d STR_s STR_u \"\\0\"\n#define STRING_idsunaryoperator0 STR_i STR_d STR_s STR_u STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r \"\\0\"\n#define STRING_imperialaramaic0 STR_i STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_a STR_r STR_a STR_m STR_a STR_i STR_c \"\\0\"\n#define STRING_incb0 STR_i STR_n STR_c STR_b \"\\0\"\n#define STRING_inherited0 STR_i STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d \"\\0\"\n#define STRING_inscriptionalpahlavi0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_h STR_l STR_a STR_v STR_i \"\\0\"\n#define STRING_inscriptionalparthian0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_r STR_t STR_h STR_i STR_a STR_n \"\\0\"\n#define STRING_ital0 STR_i STR_t STR_a STR_l \"\\0\"\n#define STRING_java0 STR_j STR_a STR_v STR_a \"\\0\"\n#define STRING_javanese0 STR_j STR_a STR_v STR_a STR_n STR_e STR_s STR_e \"\\0\"\n#define STRING_joinc0 STR_j STR_o STR_i STR_n STR_c \"\\0\"\n#define STRING_joincontrol0 STR_j STR_o STR_i STR_n STR_c STR_o STR_n STR_t STR_r STR_o STR_l \"\\0\"\n#define STRING_kaithi0 STR_k STR_a STR_i STR_t STR_h STR_i \"\\0\"\n#define STRING_kali0 STR_k STR_a STR_l STR_i \"\\0\"\n#define STRING_kana0 STR_k STR_a STR_n STR_a \"\\0\"\n#define STRING_kannada0 STR_k STR_a STR_n STR_n STR_a STR_d STR_a \"\\0\"\n#define STRING_katakana0 STR_k STR_a STR_t STR_a STR_k STR_a STR_n STR_a \"\\0\"\n#define STRING_kawi0 STR_k STR_a STR_w STR_i \"\\0\"\n#define STRING_kayahli0 STR_k STR_a STR_y STR_a STR_h STR_l STR_i \"\\0\"\n#define STRING_khar0 STR_k STR_h STR_a STR_r \"\\0\"\n#define STRING_kharoshthi0 STR_k STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i \"\\0\"\n#define STRING_khitansmallscript0 STR_k STR_h STR_i STR_t STR_a STR_n STR_s STR_m STR_a STR_l STR_l STR_s STR_c STR_r STR_i STR_p STR_t \"\\0\"\n#define STRING_khmer0 STR_k STR_h STR_m STR_e STR_r \"\\0\"\n#define STRING_khmr0 STR_k STR_h STR_m STR_r \"\\0\"\n#define STRING_khoj0 STR_k STR_h STR_o STR_j \"\\0\"\n#define STRING_khojki0 STR_k STR_h STR_o STR_j STR_k STR_i \"\\0\"\n#define STRING_khudawadi0 STR_k STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i \"\\0\"\n#define STRING_kiratrai0 STR_k STR_i STR_r STR_a STR_t STR_r STR_a STR_i \"\\0\"\n#define STRING_kits0 STR_k STR_i STR_t STR_s \"\\0\"\n#define STRING_knda0 STR_k STR_n STR_d STR_a \"\\0\"\n#define STRING_krai0 STR_k STR_r STR_a STR_i \"\\0\"\n#define STRING_kthi0 STR_k STR_t STR_h STR_i \"\\0\"\n#define STRING_l0 STR_l \"\\0\"\n#define STRING_l_AMPERSAND0 STR_l STR_AMPERSAND \"\\0\"\n#define STRING_lana0 STR_l STR_a STR_n STR_a \"\\0\"\n#define STRING_lao0 STR_l STR_a STR_o \"\\0\"\n#define STRING_laoo0 STR_l STR_a STR_o STR_o \"\\0\"\n#define STRING_latin0 STR_l STR_a STR_t STR_i STR_n \"\\0\"\n#define STRING_latn0 STR_l STR_a STR_t STR_n \"\\0\"\n#define STRING_lc0 STR_l STR_c \"\\0\"\n#define STRING_lepc0 STR_l STR_e STR_p STR_c \"\\0\"\n#define STRING_lepcha0 STR_l STR_e STR_p STR_c STR_h STR_a \"\\0\"\n#define STRING_limb0 STR_l STR_i STR_m STR_b \"\\0\"\n#define STRING_limbu0 STR_l STR_i STR_m STR_b STR_u \"\\0\"\n#define STRING_lina0 STR_l STR_i STR_n STR_a \"\\0\"\n#define STRING_linb0 STR_l STR_i STR_n STR_b \"\\0\"\n#define STRING_lineara0 STR_l STR_i STR_n STR_e STR_a STR_r STR_a \"\\0\"\n#define STRING_linearb0 STR_l STR_i STR_n STR_e STR_a STR_r STR_b \"\\0\"\n#define STRING_lisu0 STR_l STR_i STR_s STR_u \"\\0\"\n#define STRING_ll0 STR_l STR_l \"\\0\"\n#define STRING_lm0 STR_l STR_m \"\\0\"\n#define STRING_lo0 STR_l STR_o \"\\0\"\n#define STRING_loe0 STR_l STR_o STR_e \"\\0\"\n#define STRING_logicalorderexception0 STR_l STR_o STR_g STR_i STR_c STR_a STR_l STR_o STR_r STR_d STR_e STR_r STR_e STR_x STR_c STR_e STR_p STR_t STR_i STR_o STR_n \"\\0\"\n#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r \"\\0\"\n#define STRING_lowercase0 STR_l STR_o STR_w STR_e STR_r STR_c STR_a STR_s STR_e \"\\0\"\n#define STRING_lt0 STR_l STR_t \"\\0\"\n#define STRING_lu0 STR_l STR_u \"\\0\"\n#define STRING_lyci0 STR_l STR_y STR_c STR_i \"\\0\"\n#define STRING_lycian0 STR_l STR_y STR_c STR_i STR_a STR_n \"\\0\"\n#define STRING_lydi0 STR_l STR_y STR_d STR_i \"\\0\"\n#define STRING_lydian0 STR_l STR_y STR_d STR_i STR_a STR_n \"\\0\"\n#define STRING_m0 STR_m \"\\0\"\n#define STRING_mahajani0 STR_m STR_a STR_h STR_a STR_j STR_a STR_n STR_i \"\\0\"\n#define STRING_mahj0 STR_m STR_a STR_h STR_j \"\\0\"\n#define STRING_maka0 STR_m STR_a STR_k STR_a \"\\0\"\n#define STRING_makasar0 STR_m STR_a STR_k STR_a STR_s STR_a STR_r \"\\0\"\n#define STRING_malayalam0 STR_m STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m \"\\0\"\n#define STRING_mand0 STR_m STR_a STR_n STR_d \"\\0\"\n#define STRING_mandaic0 STR_m STR_a STR_n STR_d STR_a STR_i STR_c \"\\0\"\n#define STRING_mani0 STR_m STR_a STR_n STR_i \"\\0\"\n#define STRING_manichaean0 STR_m STR_a STR_n STR_i STR_c STR_h STR_a STR_e STR_a STR_n \"\\0\"\n#define STRING_marc0 STR_m STR_a STR_r STR_c \"\\0\"\n#define STRING_marchen0 STR_m STR_a STR_r STR_c STR_h STR_e STR_n \"\\0\"\n#define STRING_masaramgondi0 STR_m STR_a STR_s STR_a STR_r STR_a STR_m STR_g STR_o STR_n STR_d STR_i \"\\0\"\n#define STRING_math0 STR_m STR_a STR_t STR_h \"\\0\"\n#define STRING_mc0 STR_m STR_c \"\\0\"\n#define STRING_mcm0 STR_m STR_c STR_m \"\\0\"\n#define STRING_me0 STR_m STR_e \"\\0\"\n#define STRING_medefaidrin0 STR_m STR_e STR_d STR_e STR_f STR_a STR_i STR_d STR_r STR_i STR_n \"\\0\"\n#define STRING_medf0 STR_m STR_e STR_d STR_f \"\\0\"\n#define STRING_meeteimayek0 STR_m STR_e STR_e STR_t STR_e STR_i STR_m STR_a STR_y STR_e STR_k \"\\0\"\n#define STRING_mend0 STR_m STR_e STR_n STR_d \"\\0\"\n#define STRING_mendekikakui0 STR_m STR_e STR_n STR_d STR_e STR_k STR_i STR_k STR_a STR_k STR_u STR_i \"\\0\"\n#define STRING_merc0 STR_m STR_e STR_r STR_c \"\\0\"\n#define STRING_mero0 STR_m STR_e STR_r STR_o \"\\0\"\n#define STRING_meroiticcursive0 STR_m STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_c STR_u STR_r STR_s STR_i STR_v STR_e \"\\0\"\n#define STRING_meroitichieroglyphs0 STR_m STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_h STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s \"\\0\"\n#define STRING_miao0 STR_m STR_i STR_a STR_o \"\\0\"\n#define STRING_mlym0 STR_m STR_l STR_y STR_m \"\\0\"\n#define STRING_mn0 STR_m STR_n \"\\0\"\n#define STRING_modi0 STR_m STR_o STR_d STR_i \"\\0\"\n#define STRING_modifiercombiningmark0 STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r STR_c STR_o STR_m STR_b STR_i STR_n STR_i STR_n STR_g STR_m STR_a STR_r STR_k \"\\0\"\n#define STRING_mong0 STR_m STR_o STR_n STR_g \"\\0\"\n#define STRING_mongolian0 STR_m STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n \"\\0\"\n#define STRING_mro0 STR_m STR_r STR_o \"\\0\"\n#define STRING_mroo0 STR_m STR_r STR_o STR_o \"\\0\"\n#define STRING_mtei0 STR_m STR_t STR_e STR_i \"\\0\"\n#define STRING_mult0 STR_m STR_u STR_l STR_t \"\\0\"\n#define STRING_multani0 STR_m STR_u STR_l STR_t STR_a STR_n STR_i \"\\0\"\n#define STRING_myanmar0 STR_m STR_y STR_a STR_n STR_m STR_a STR_r \"\\0\"\n#define STRING_mymr0 STR_m STR_y STR_m STR_r \"\\0\"\n#define STRING_n0 STR_n \"\\0\"\n#define STRING_nabataean0 STR_n STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n \"\\0\"\n#define STRING_nagm0 STR_n STR_a STR_g STR_m \"\\0\"\n#define STRING_nagmundari0 STR_n STR_a STR_g STR_m STR_u STR_n STR_d STR_a STR_r STR_i \"\\0\"\n#define STRING_nand0 STR_n STR_a STR_n STR_d \"\\0\"\n#define STRING_nandinagari0 STR_n STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i \"\\0\"\n#define STRING_narb0 STR_n STR_a STR_r STR_b \"\\0\"\n#define STRING_nbat0 STR_n STR_b STR_a STR_t \"\\0\"\n#define STRING_nchar0 STR_n STR_c STR_h STR_a STR_r \"\\0\"\n#define STRING_nd0 STR_n STR_d \"\\0\"\n#define STRING_newa0 STR_n STR_e STR_w STR_a \"\\0\"\n#define STRING_newtailue0 STR_n STR_e STR_w STR_t STR_a STR_i STR_l STR_u STR_e \"\\0\"\n#define STRING_nko0 STR_n STR_k STR_o \"\\0\"\n#define STRING_nkoo0 STR_n STR_k STR_o STR_o \"\\0\"\n#define STRING_nl0 STR_n STR_l \"\\0\"\n#define STRING_no0 STR_n STR_o \"\\0\"\n#define STRING_noncharactercodepoint0 STR_n STR_o STR_n STR_c STR_h STR_a STR_r STR_a STR_c STR_t STR_e STR_r STR_c STR_o STR_d STR_e STR_p STR_o STR_i STR_n STR_t \"\\0\"\n#define STRING_nshu0 STR_n STR_s STR_h STR_u \"\\0\"\n#define STRING_nushu0 STR_n STR_u STR_s STR_h STR_u \"\\0\"\n#define STRING_nyiakengpuachuehmong0 STR_n STR_y STR_i STR_a STR_k STR_e STR_n STR_g STR_p STR_u STR_a STR_c STR_h STR_u STR_e STR_h STR_m STR_o STR_n STR_g \"\\0\"\n#define STRING_ogam0 STR_o STR_g STR_a STR_m \"\\0\"\n#define STRING_ogham0 STR_o STR_g STR_h STR_a STR_m \"\\0\"\n#define STRING_olchiki0 STR_o STR_l STR_c STR_h STR_i STR_k STR_i \"\\0\"\n#define STRING_olck0 STR_o STR_l STR_c STR_k \"\\0\"\n#define STRING_oldhungarian0 STR_o STR_l STR_d STR_h STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n \"\\0\"\n#define STRING_olditalic0 STR_o STR_l STR_d STR_i STR_t STR_a STR_l STR_i STR_c \"\\0\"\n#define STRING_oldnortharabian0 STR_o STR_l STR_d STR_n STR_o STR_r STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n \"\\0\"\n#define STRING_oldpermic0 STR_o STR_l STR_d STR_p STR_e STR_r STR_m STR_i STR_c \"\\0\"\n#define STRING_oldpersian0 STR_o STR_l STR_d STR_p STR_e STR_r STR_s STR_i STR_a STR_n \"\\0\"\n#define STRING_oldsogdian0 STR_o STR_l STR_d STR_s STR_o STR_g STR_d STR_i STR_a STR_n \"\\0\"\n#define STRING_oldsoutharabian0 STR_o STR_l STR_d STR_s STR_o STR_u STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n \"\\0\"\n#define STRING_oldturkic0 STR_o STR_l STR_d STR_t STR_u STR_r STR_k STR_i STR_c \"\\0\"\n#define STRING_olduyghur0 STR_o STR_l STR_d STR_u STR_y STR_g STR_h STR_u STR_r \"\\0\"\n#define STRING_olonal0 STR_o STR_l STR_o STR_n STR_a STR_l \"\\0\"\n#define STRING_onao0 STR_o STR_n STR_a STR_o \"\\0\"\n#define STRING_oriya0 STR_o STR_r STR_i STR_y STR_a \"\\0\"\n#define STRING_orkh0 STR_o STR_r STR_k STR_h \"\\0\"\n#define STRING_orya0 STR_o STR_r STR_y STR_a \"\\0\"\n#define STRING_osage0 STR_o STR_s STR_a STR_g STR_e \"\\0\"\n#define STRING_osge0 STR_o STR_s STR_g STR_e \"\\0\"\n#define STRING_osma0 STR_o STR_s STR_m STR_a \"\\0\"\n#define STRING_osmanya0 STR_o STR_s STR_m STR_a STR_n STR_y STR_a \"\\0\"\n#define STRING_ougr0 STR_o STR_u STR_g STR_r \"\\0\"\n#define STRING_p0 STR_p \"\\0\"\n#define STRING_pahawhhmong0 STR_p STR_a STR_h STR_a STR_w STR_h STR_h STR_m STR_o STR_n STR_g \"\\0\"\n#define STRING_palm0 STR_p STR_a STR_l STR_m \"\\0\"\n#define STRING_palmyrene0 STR_p STR_a STR_l STR_m STR_y STR_r STR_e STR_n STR_e \"\\0\"\n#define STRING_patsyn0 STR_p STR_a STR_t STR_s STR_y STR_n \"\\0\"\n#define STRING_patternsyntax0 STR_p STR_a STR_t STR_t STR_e STR_r STR_n STR_s STR_y STR_n STR_t STR_a STR_x \"\\0\"\n#define STRING_patternwhitespace0 STR_p STR_a STR_t STR_t STR_e STR_r STR_n STR_w STR_h STR_i STR_t STR_e STR_s STR_p STR_a STR_c STR_e \"\\0\"\n#define STRING_patws0 STR_p STR_a STR_t STR_w STR_s \"\\0\"\n#define STRING_pauc0 STR_p STR_a STR_u STR_c \"\\0\"\n#define STRING_paucinhau0 STR_p STR_a STR_u STR_c STR_i STR_n STR_h STR_a STR_u \"\\0\"\n#define STRING_pc0 STR_p STR_c \"\\0\"\n#define STRING_pcm0 STR_p STR_c STR_m \"\\0\"\n#define STRING_pd0 STR_p STR_d \"\\0\"\n#define STRING_pe0 STR_p STR_e \"\\0\"\n#define STRING_perm0 STR_p STR_e STR_r STR_m \"\\0\"\n#define STRING_pf0 STR_p STR_f \"\\0\"\n#define STRING_phag0 STR_p STR_h STR_a STR_g \"\\0\"\n#define STRING_phagspa0 STR_p STR_h STR_a STR_g STR_s STR_p STR_a \"\\0\"\n#define STRING_phli0 STR_p STR_h STR_l STR_i \"\\0\"\n#define STRING_phlp0 STR_p STR_h STR_l STR_p \"\\0\"\n#define STRING_phnx0 STR_p STR_h STR_n STR_x \"\\0\"\n#define STRING_phoenician0 STR_p STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n \"\\0\"\n#define STRING_pi0 STR_p STR_i \"\\0\"\n#define STRING_plrd0 STR_p STR_l STR_r STR_d \"\\0\"\n#define STRING_po0 STR_p STR_o \"\\0\"\n#define STRING_prependedconcatenationmark0 STR_p STR_r STR_e STR_p STR_e STR_n STR_d STR_e STR_d STR_c STR_o STR_n STR_c STR_a STR_t STR_e STR_n STR_a STR_t STR_i STR_o STR_n STR_m STR_a STR_r STR_k \"\\0\"\n#define STRING_prti0 STR_p STR_r STR_t STR_i \"\\0\"\n#define STRING_ps0 STR_p STR_s \"\\0\"\n#define STRING_psalterpahlavi0 STR_p STR_s STR_a STR_l STR_t STR_e STR_r STR_p STR_a STR_h STR_l STR_a STR_v STR_i \"\\0\"\n#define STRING_qaac0 STR_q STR_a STR_a STR_c \"\\0\"\n#define STRING_qaai0 STR_q STR_a STR_a STR_i \"\\0\"\n#define STRING_qmark0 STR_q STR_m STR_a STR_r STR_k \"\\0\"\n#define STRING_quotationmark0 STR_q STR_u STR_o STR_t STR_a STR_t STR_i STR_o STR_n STR_m STR_a STR_r STR_k \"\\0\"\n#define STRING_radical0 STR_r STR_a STR_d STR_i STR_c STR_a STR_l \"\\0\"\n#define STRING_regionalindicator0 STR_r STR_e STR_g STR_i STR_o STR_n STR_a STR_l STR_i STR_n STR_d STR_i STR_c STR_a STR_t STR_o STR_r \"\\0\"\n#define STRING_rejang0 STR_r STR_e STR_j STR_a STR_n STR_g \"\\0\"\n#define STRING_ri0 STR_r STR_i \"\\0\"\n#define STRING_rjng0 STR_r STR_j STR_n STR_g \"\\0\"\n#define STRING_rohg0 STR_r STR_o STR_h STR_g \"\\0\"\n#define STRING_runic0 STR_r STR_u STR_n STR_i STR_c \"\\0\"\n#define STRING_runr0 STR_r STR_u STR_n STR_r \"\\0\"\n#define STRING_s0 STR_s \"\\0\"\n#define STRING_samaritan0 STR_s STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n \"\\0\"\n#define STRING_samr0 STR_s STR_a STR_m STR_r \"\\0\"\n#define STRING_sarb0 STR_s STR_a STR_r STR_b \"\\0\"\n#define STRING_saur0 STR_s STR_a STR_u STR_r \"\\0\"\n#define STRING_saurashtra0 STR_s STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a \"\\0\"\n#define STRING_sc0 STR_s STR_c \"\\0\"\n#define STRING_sd0 STR_s STR_d \"\\0\"\n#define STRING_sentenceterminal0 STR_s STR_e STR_n STR_t STR_e STR_n STR_c STR_e STR_t STR_e STR_r STR_m STR_i STR_n STR_a STR_l \"\\0\"\n#define STRING_sgnw0 STR_s STR_g STR_n STR_w \"\\0\"\n#define STRING_sharada0 STR_s STR_h STR_a STR_r STR_a STR_d STR_a \"\\0\"\n#define STRING_shavian0 STR_s STR_h STR_a STR_v STR_i STR_a STR_n \"\\0\"\n#define STRING_shaw0 STR_s STR_h STR_a STR_w \"\\0\"\n#define STRING_shrd0 STR_s STR_h STR_r STR_d \"\\0\"\n#define STRING_sidd0 STR_s STR_i STR_d STR_d \"\\0\"\n#define STRING_siddham0 STR_s STR_i STR_d STR_d STR_h STR_a STR_m \"\\0\"\n#define STRING_signwriting0 STR_s STR_i STR_g STR_n STR_w STR_r STR_i STR_t STR_i STR_n STR_g \"\\0\"\n#define STRING_sind0 STR_s STR_i STR_n STR_d \"\\0\"\n#define STRING_sinh0 STR_s STR_i STR_n STR_h \"\\0\"\n#define STRING_sinhala0 STR_s STR_i STR_n STR_h STR_a STR_l STR_a \"\\0\"\n#define STRING_sk0 STR_s STR_k \"\\0\"\n#define STRING_sm0 STR_s STR_m \"\\0\"\n#define STRING_so0 STR_s STR_o \"\\0\"\n#define STRING_softdotted0 STR_s STR_o STR_f STR_t STR_d STR_o STR_t STR_t STR_e STR_d \"\\0\"\n#define STRING_sogd0 STR_s STR_o STR_g STR_d \"\\0\"\n#define STRING_sogdian0 STR_s STR_o STR_g STR_d STR_i STR_a STR_n \"\\0\"\n#define STRING_sogo0 STR_s STR_o STR_g STR_o \"\\0\"\n#define STRING_sora0 STR_s STR_o STR_r STR_a \"\\0\"\n#define STRING_sorasompeng0 STR_s STR_o STR_r STR_a STR_s STR_o STR_m STR_p STR_e STR_n STR_g \"\\0\"\n#define STRING_soyo0 STR_s STR_o STR_y STR_o \"\\0\"\n#define STRING_soyombo0 STR_s STR_o STR_y STR_o STR_m STR_b STR_o \"\\0\"\n#define STRING_space0 STR_s STR_p STR_a STR_c STR_e \"\\0\"\n#define STRING_sterm0 STR_s STR_t STR_e STR_r STR_m \"\\0\"\n#define STRING_sund0 STR_s STR_u STR_n STR_d \"\\0\"\n#define STRING_sundanese0 STR_s STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e \"\\0\"\n#define STRING_sunu0 STR_s STR_u STR_n STR_u \"\\0\"\n#define STRING_sunuwar0 STR_s STR_u STR_n STR_u STR_w STR_a STR_r \"\\0\"\n#define STRING_sylo0 STR_s STR_y STR_l STR_o \"\\0\"\n#define STRING_sylotinagri0 STR_s STR_y STR_l STR_o STR_t STR_i STR_n STR_a STR_g STR_r STR_i \"\\0\"\n#define STRING_syrc0 STR_s STR_y STR_r STR_c \"\\0\"\n#define STRING_syriac0 STR_s STR_y STR_r STR_i STR_a STR_c \"\\0\"\n#define STRING_tagalog0 STR_t STR_a STR_g STR_a STR_l STR_o STR_g \"\\0\"\n#define STRING_tagb0 STR_t STR_a STR_g STR_b \"\\0\"\n#define STRING_tagbanwa0 STR_t STR_a STR_g STR_b STR_a STR_n STR_w STR_a \"\\0\"\n#define STRING_taile0 STR_t STR_a STR_i STR_l STR_e \"\\0\"\n#define STRING_taitham0 STR_t STR_a STR_i STR_t STR_h STR_a STR_m \"\\0\"\n#define STRING_taiviet0 STR_t STR_a STR_i STR_v STR_i STR_e STR_t \"\\0\"\n#define STRING_takr0 STR_t STR_a STR_k STR_r \"\\0\"\n#define STRING_takri0 STR_t STR_a STR_k STR_r STR_i \"\\0\"\n#define STRING_tale0 STR_t STR_a STR_l STR_e \"\\0\"\n#define STRING_talu0 STR_t STR_a STR_l STR_u \"\\0\"\n#define STRING_tamil0 STR_t STR_a STR_m STR_i STR_l \"\\0\"\n#define STRING_taml0 STR_t STR_a STR_m STR_l \"\\0\"\n#define STRING_tang0 STR_t STR_a STR_n STR_g \"\\0\"\n#define STRING_tangsa0 STR_t STR_a STR_n STR_g STR_s STR_a \"\\0\"\n#define STRING_tangut0 STR_t STR_a STR_n STR_g STR_u STR_t \"\\0\"\n#define STRING_tavt0 STR_t STR_a STR_v STR_t \"\\0\"\n#define STRING_telu0 STR_t STR_e STR_l STR_u \"\\0\"\n#define STRING_telugu0 STR_t STR_e STR_l STR_u STR_g STR_u \"\\0\"\n#define STRING_term0 STR_t STR_e STR_r STR_m \"\\0\"\n#define STRING_terminalpunctuation0 STR_t STR_e STR_r STR_m STR_i STR_n STR_a STR_l STR_p STR_u STR_n STR_c STR_t STR_u STR_a STR_t STR_i STR_o STR_n \"\\0\"\n#define STRING_tfng0 STR_t STR_f STR_n STR_g \"\\0\"\n#define STRING_tglg0 STR_t STR_g STR_l STR_g \"\\0\"\n#define STRING_thaa0 STR_t STR_h STR_a STR_a \"\\0\"\n#define STRING_thaana0 STR_t STR_h STR_a STR_a STR_n STR_a \"\\0\"\n#define STRING_thai0 STR_t STR_h STR_a STR_i \"\\0\"\n#define STRING_tibetan0 STR_t STR_i STR_b STR_e STR_t STR_a STR_n \"\\0\"\n#define STRING_tibt0 STR_t STR_i STR_b STR_t \"\\0\"\n#define STRING_tifinagh0 STR_t STR_i STR_f STR_i STR_n STR_a STR_g STR_h \"\\0\"\n#define STRING_tirh0 STR_t STR_i STR_r STR_h \"\\0\"\n#define STRING_tirhuta0 STR_t STR_i STR_r STR_h STR_u STR_t STR_a \"\\0\"\n#define STRING_tnsa0 STR_t STR_n STR_s STR_a \"\\0\"\n#define STRING_todhri0 STR_t STR_o STR_d STR_h STR_r STR_i \"\\0\"\n#define STRING_todr0 STR_t STR_o STR_d STR_r \"\\0\"\n#define STRING_toto0 STR_t STR_o STR_t STR_o \"\\0\"\n#define STRING_tulutigalari0 STR_t STR_u STR_l STR_u STR_t STR_i STR_g STR_a STR_l STR_a STR_r STR_i \"\\0\"\n#define STRING_tutg0 STR_t STR_u STR_t STR_g \"\\0\"\n#define STRING_ugar0 STR_u STR_g STR_a STR_r \"\\0\"\n#define STRING_ugaritic0 STR_u STR_g STR_a STR_r STR_i STR_t STR_i STR_c \"\\0\"\n#define STRING_uideo0 STR_u STR_i STR_d STR_e STR_o \"\\0\"\n#define STRING_unifiedideograph0 STR_u STR_n STR_i STR_f STR_i STR_e STR_d STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h \"\\0\"\n#define STRING_unknown0 STR_u STR_n STR_k STR_n STR_o STR_w STR_n \"\\0\"\n#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r \"\\0\"\n#define STRING_uppercase0 STR_u STR_p STR_p STR_e STR_r STR_c STR_a STR_s STR_e \"\\0\"\n#define STRING_vai0 STR_v STR_a STR_i \"\\0\"\n#define STRING_vaii0 STR_v STR_a STR_i STR_i \"\\0\"\n#define STRING_variationselector0 STR_v STR_a STR_r STR_i STR_a STR_t STR_i STR_o STR_n STR_s STR_e STR_l STR_e STR_c STR_t STR_o STR_r \"\\0\"\n#define STRING_vith0 STR_v STR_i STR_t STR_h \"\\0\"\n#define STRING_vithkuqi0 STR_v STR_i STR_t STR_h STR_k STR_u STR_q STR_i \"\\0\"\n#define STRING_vs0 STR_v STR_s \"\\0\"\n#define STRING_wancho0 STR_w STR_a STR_n STR_c STR_h STR_o \"\\0\"\n#define STRING_wara0 STR_w STR_a STR_r STR_a \"\\0\"\n#define STRING_warangciti0 STR_w STR_a STR_r STR_a STR_n STR_g STR_c STR_i STR_t STR_i \"\\0\"\n#define STRING_wcho0 STR_w STR_c STR_h STR_o \"\\0\"\n#define STRING_whitespace0 STR_w STR_h STR_i STR_t STR_e STR_s STR_p STR_a STR_c STR_e \"\\0\"\n#define STRING_wspace0 STR_w STR_s STR_p STR_a STR_c STR_e \"\\0\"\n#define STRING_xan0 STR_x STR_a STR_n \"\\0\"\n#define STRING_xidc0 STR_x STR_i STR_d STR_c \"\\0\"\n#define STRING_xidcontinue0 STR_x STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e \"\\0\"\n#define STRING_xids0 STR_x STR_i STR_d STR_s \"\\0\"\n#define STRING_xidstart0 STR_x STR_i STR_d STR_s STR_t STR_a STR_r STR_t \"\\0\"\n#define STRING_xpeo0 STR_x STR_p STR_e STR_o \"\\0\"\n#define STRING_xps0 STR_x STR_p STR_s \"\\0\"\n#define STRING_xsp0 STR_x STR_s STR_p \"\\0\"\n#define STRING_xsux0 STR_x STR_s STR_u STR_x \"\\0\"\n#define STRING_xuc0 STR_x STR_u STR_c \"\\0\"\n#define STRING_xwd0 STR_x STR_w STR_d \"\\0\"\n#define STRING_yezi0 STR_y STR_e STR_z STR_i \"\\0\"\n#define STRING_yezidi0 STR_y STR_e STR_z STR_i STR_d STR_i \"\\0\"\n#define STRING_yi0 STR_y STR_i \"\\0\"\n#define STRING_yiii0 STR_y STR_i STR_i STR_i \"\\0\"\n#define STRING_z0 STR_z \"\\0\"\n#define STRING_zanabazarsquare0 STR_z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_s STR_q STR_u STR_a STR_r STR_e \"\\0\"\n#define STRING_zanb0 STR_z STR_a STR_n STR_b \"\\0\"\n#define STRING_zinh0 STR_z STR_i STR_n STR_h \"\\0\"\n#define STRING_zl0 STR_z STR_l \"\\0\"\n#define STRING_zp0 STR_z STR_p \"\\0\"\n#define STRING_zs0 STR_z STR_s \"\\0\"\n#define STRING_zyyy0 STR_z STR_y STR_y STR_y \"\\0\"\n#define STRING_zzzz0 STR_z STR_z STR_z STR_z \"\\0\"\n\nconst char PRIV(utt_names)[] =\n  STRING_adlam0\n  STRING_adlm0\n  STRING_aghb0\n  STRING_ahex0\n  STRING_ahom0\n  STRING_alpha0\n  STRING_alphabetic0\n  STRING_anatolianhieroglyphs0\n  STRING_any0\n  STRING_arab0\n  STRING_arabic0\n  STRING_armenian0\n  STRING_armi0\n  STRING_armn0\n  STRING_ascii0\n  STRING_asciihexdigit0\n  STRING_avestan0\n  STRING_avst0\n  STRING_bali0\n  STRING_balinese0\n  STRING_bamu0\n  STRING_bamum0\n  STRING_bass0\n  STRING_bassavah0\n  STRING_batak0\n  STRING_batk0\n  STRING_beng0\n  STRING_bengali0\n  STRING_bhaiksuki0\n  STRING_bhks0\n  STRING_bidial0\n  STRING_bidian0\n  STRING_bidib0\n  STRING_bidibn0\n  STRING_bidic0\n  STRING_bidicontrol0\n  STRING_bidics0\n  STRING_bidien0\n  STRING_bidies0\n  STRING_bidiet0\n  STRING_bidifsi0\n  STRING_bidil0\n  STRING_bidilre0\n  STRING_bidilri0\n  STRING_bidilro0\n  STRING_bidim0\n  STRING_bidimirrored0\n  STRING_bidinsm0\n  STRING_bidion0\n  STRING_bidipdf0\n  STRING_bidipdi0\n  STRING_bidir0\n  STRING_bidirle0\n  STRING_bidirli0\n  STRING_bidirlo0\n  STRING_bidis0\n  STRING_bidiws0\n  STRING_bopo0\n  STRING_bopomofo0\n  STRING_brah0\n  STRING_brahmi0\n  STRING_brai0\n  STRING_braille0\n  STRING_bugi0\n  STRING_buginese0\n  STRING_buhd0\n  STRING_buhid0\n  STRING_c0\n  STRING_cakm0\n  STRING_canadianaboriginal0\n  STRING_cans0\n  STRING_cari0\n  STRING_carian0\n  STRING_cased0\n  STRING_caseignorable0\n  STRING_caucasianalbanian0\n  STRING_cc0\n  STRING_cf0\n  STRING_chakma0\n  STRING_cham0\n  STRING_changeswhencasefolded0\n  STRING_changeswhencasemapped0\n  STRING_changeswhenlowercased0\n  STRING_changeswhentitlecased0\n  STRING_changeswhenuppercased0\n  STRING_cher0\n  STRING_cherokee0\n  STRING_chorasmian0\n  STRING_chrs0\n  STRING_ci0\n  STRING_cn0\n  STRING_co0\n  STRING_common0\n  STRING_copt0\n  STRING_coptic0\n  STRING_cpmn0\n  STRING_cprt0\n  STRING_cs0\n  STRING_cuneiform0\n  STRING_cwcf0\n  STRING_cwcm0\n  STRING_cwl0\n  STRING_cwt0\n  STRING_cwu0\n  STRING_cypriot0\n  STRING_cyprominoan0\n  STRING_cyrillic0\n  STRING_cyrl0\n  STRING_dash0\n  STRING_defaultignorablecodepoint0\n  STRING_dep0\n  STRING_deprecated0\n  STRING_deseret0\n  STRING_deva0\n  STRING_devanagari0\n  STRING_di0\n  STRING_dia0\n  STRING_diacritic0\n  STRING_diak0\n  STRING_divesakuru0\n  STRING_dogr0\n  STRING_dogra0\n  STRING_dsrt0\n  STRING_dupl0\n  STRING_duployan0\n  STRING_ebase0\n  STRING_ecomp0\n  STRING_egyp0\n  STRING_egyptianhieroglyphs0\n  STRING_elba0\n  STRING_elbasan0\n  STRING_elym0\n  STRING_elymaic0\n  STRING_emod0\n  STRING_emoji0\n  STRING_emojicomponent0\n  STRING_emojimodifier0\n  STRING_emojimodifierbase0\n  STRING_emojipresentation0\n  STRING_epres0\n  STRING_ethi0\n  STRING_ethiopic0\n  STRING_ext0\n  STRING_extendedpictographic0\n  STRING_extender0\n  STRING_extpict0\n  STRING_gara0\n  STRING_garay0\n  STRING_geor0\n  STRING_georgian0\n  STRING_glag0\n  STRING_glagolitic0\n  STRING_gong0\n  STRING_gonm0\n  STRING_goth0\n  STRING_gothic0\n  STRING_gran0\n  STRING_grantha0\n  STRING_graphemebase0\n  STRING_graphemeextend0\n  STRING_graphemelink0\n  STRING_grbase0\n  STRING_greek0\n  STRING_grek0\n  STRING_grext0\n  STRING_grlink0\n  STRING_gujarati0\n  STRING_gujr0\n  STRING_gukh0\n  STRING_gunjalagondi0\n  STRING_gurmukhi0\n  STRING_guru0\n  STRING_gurungkhema0\n  STRING_han0\n  STRING_hang0\n  STRING_hangul0\n  STRING_hani0\n  STRING_hanifirohingya0\n  STRING_hano0\n  STRING_hanunoo0\n  STRING_hatr0\n  STRING_hatran0\n  STRING_hebr0\n  STRING_hebrew0\n  STRING_hex0\n  STRING_hexdigit0\n  STRING_hira0\n  STRING_hiragana0\n  STRING_hluw0\n  STRING_hmng0\n  STRING_hmnp0\n  STRING_hung0\n  STRING_idc0\n  STRING_idcompatmathcontinue0\n  STRING_idcompatmathstart0\n  STRING_idcontinue0\n  STRING_ideo0\n  STRING_ideographic0\n  STRING_ids0\n  STRING_idsb0\n  STRING_idsbinaryoperator0\n  STRING_idst0\n  STRING_idstart0\n  STRING_idstrinaryoperator0\n  STRING_idsu0\n  STRING_idsunaryoperator0\n  STRING_imperialaramaic0\n  STRING_incb0\n  STRING_inherited0\n  STRING_inscriptionalpahlavi0\n  STRING_inscriptionalparthian0\n  STRING_ital0\n  STRING_java0\n  STRING_javanese0\n  STRING_joinc0\n  STRING_joincontrol0\n  STRING_kaithi0\n  STRING_kali0\n  STRING_kana0\n  STRING_kannada0\n  STRING_katakana0\n  STRING_kawi0\n  STRING_kayahli0\n  STRING_khar0\n  STRING_kharoshthi0\n  STRING_khitansmallscript0\n  STRING_khmer0\n  STRING_khmr0\n  STRING_khoj0\n  STRING_khojki0\n  STRING_khudawadi0\n  STRING_kiratrai0\n  STRING_kits0\n  STRING_knda0\n  STRING_krai0\n  STRING_kthi0\n  STRING_l0\n  STRING_l_AMPERSAND0\n  STRING_lana0\n  STRING_lao0\n  STRING_laoo0\n  STRING_latin0\n  STRING_latn0\n  STRING_lc0\n  STRING_lepc0\n  STRING_lepcha0\n  STRING_limb0\n  STRING_limbu0\n  STRING_lina0\n  STRING_linb0\n  STRING_lineara0\n  STRING_linearb0\n  STRING_lisu0\n  STRING_ll0\n  STRING_lm0\n  STRING_lo0\n  STRING_loe0\n  STRING_logicalorderexception0\n  STRING_lower0\n  STRING_lowercase0\n  STRING_lt0\n  STRING_lu0\n  STRING_lyci0\n  STRING_lycian0\n  STRING_lydi0\n  STRING_lydian0\n  STRING_m0\n  STRING_mahajani0\n  STRING_mahj0\n  STRING_maka0\n  STRING_makasar0\n  STRING_malayalam0\n  STRING_mand0\n  STRING_mandaic0\n  STRING_mani0\n  STRING_manichaean0\n  STRING_marc0\n  STRING_marchen0\n  STRING_masaramgondi0\n  STRING_math0\n  STRING_mc0\n  STRING_mcm0\n  STRING_me0\n  STRING_medefaidrin0\n  STRING_medf0\n  STRING_meeteimayek0\n  STRING_mend0\n  STRING_mendekikakui0\n  STRING_merc0\n  STRING_mero0\n  STRING_meroiticcursive0\n  STRING_meroitichieroglyphs0\n  STRING_miao0\n  STRING_mlym0\n  STRING_mn0\n  STRING_modi0\n  STRING_modifiercombiningmark0\n  STRING_mong0\n  STRING_mongolian0\n  STRING_mro0\n  STRING_mroo0\n  STRING_mtei0\n  STRING_mult0\n  STRING_multani0\n  STRING_myanmar0\n  STRING_mymr0\n  STRING_n0\n  STRING_nabataean0\n  STRING_nagm0\n  STRING_nagmundari0\n  STRING_nand0\n  STRING_nandinagari0\n  STRING_narb0\n  STRING_nbat0\n  STRING_nchar0\n  STRING_nd0\n  STRING_newa0\n  STRING_newtailue0\n  STRING_nko0\n  STRING_nkoo0\n  STRING_nl0\n  STRING_no0\n  STRING_noncharactercodepoint0\n  STRING_nshu0\n  STRING_nushu0\n  STRING_nyiakengpuachuehmong0\n  STRING_ogam0\n  STRING_ogham0\n  STRING_olchiki0\n  STRING_olck0\n  STRING_oldhungarian0\n  STRING_olditalic0\n  STRING_oldnortharabian0\n  STRING_oldpermic0\n  STRING_oldpersian0\n  STRING_oldsogdian0\n  STRING_oldsoutharabian0\n  STRING_oldturkic0\n  STRING_olduyghur0\n  STRING_olonal0\n  STRING_onao0\n  STRING_oriya0\n  STRING_orkh0\n  STRING_orya0\n  STRING_osage0\n  STRING_osge0\n  STRING_osma0\n  STRING_osmanya0\n  STRING_ougr0\n  STRING_p0\n  STRING_pahawhhmong0\n  STRING_palm0\n  STRING_palmyrene0\n  STRING_patsyn0\n  STRING_patternsyntax0\n  STRING_patternwhitespace0\n  STRING_patws0\n  STRING_pauc0\n  STRING_paucinhau0\n  STRING_pc0\n  STRING_pcm0\n  STRING_pd0\n  STRING_pe0\n  STRING_perm0\n  STRING_pf0\n  STRING_phag0\n  STRING_phagspa0\n  STRING_phli0\n  STRING_phlp0\n  STRING_phnx0\n  STRING_phoenician0\n  STRING_pi0\n  STRING_plrd0\n  STRING_po0\n  STRING_prependedconcatenationmark0\n  STRING_prti0\n  STRING_ps0\n  STRING_psalterpahlavi0\n  STRING_qaac0\n  STRING_qaai0\n  STRING_qmark0\n  STRING_quotationmark0\n  STRING_radical0\n  STRING_regionalindicator0\n  STRING_rejang0\n  STRING_ri0\n  STRING_rjng0\n  STRING_rohg0\n  STRING_runic0\n  STRING_runr0\n  STRING_s0\n  STRING_samaritan0\n  STRING_samr0\n  STRING_sarb0\n  STRING_saur0\n  STRING_saurashtra0\n  STRING_sc0\n  STRING_sd0\n  STRING_sentenceterminal0\n  STRING_sgnw0\n  STRING_sharada0\n  STRING_shavian0\n  STRING_shaw0\n  STRING_shrd0\n  STRING_sidd0\n  STRING_siddham0\n  STRING_signwriting0\n  STRING_sind0\n  STRING_sinh0\n  STRING_sinhala0\n  STRING_sk0\n  STRING_sm0\n  STRING_so0\n  STRING_softdotted0\n  STRING_sogd0\n  STRING_sogdian0\n  STRING_sogo0\n  STRING_sora0\n  STRING_sorasompeng0\n  STRING_soyo0\n  STRING_soyombo0\n  STRING_space0\n  STRING_sterm0\n  STRING_sund0\n  STRING_sundanese0\n  STRING_sunu0\n  STRING_sunuwar0\n  STRING_sylo0\n  STRING_sylotinagri0\n  STRING_syrc0\n  STRING_syriac0\n  STRING_tagalog0\n  STRING_tagb0\n  STRING_tagbanwa0\n  STRING_taile0\n  STRING_taitham0\n  STRING_taiviet0\n  STRING_takr0\n  STRING_takri0\n  STRING_tale0\n  STRING_talu0\n  STRING_tamil0\n  STRING_taml0\n  STRING_tang0\n  STRING_tangsa0\n  STRING_tangut0\n  STRING_tavt0\n  STRING_telu0\n  STRING_telugu0\n  STRING_term0\n  STRING_terminalpunctuation0\n  STRING_tfng0\n  STRING_tglg0\n  STRING_thaa0\n  STRING_thaana0\n  STRING_thai0\n  STRING_tibetan0\n  STRING_tibt0\n  STRING_tifinagh0\n  STRING_tirh0\n  STRING_tirhuta0\n  STRING_tnsa0\n  STRING_todhri0\n  STRING_todr0\n  STRING_toto0\n  STRING_tulutigalari0\n  STRING_tutg0\n  STRING_ugar0\n  STRING_ugaritic0\n  STRING_uideo0\n  STRING_unifiedideograph0\n  STRING_unknown0\n  STRING_upper0\n  STRING_uppercase0\n  STRING_vai0\n  STRING_vaii0\n  STRING_variationselector0\n  STRING_vith0\n  STRING_vithkuqi0\n  STRING_vs0\n  STRING_wancho0\n  STRING_wara0\n  STRING_warangciti0\n  STRING_wcho0\n  STRING_whitespace0\n  STRING_wspace0\n  STRING_xan0\n  STRING_xidc0\n  STRING_xidcontinue0\n  STRING_xids0\n  STRING_xidstart0\n  STRING_xpeo0\n  STRING_xps0\n  STRING_xsp0\n  STRING_xsux0\n  STRING_xuc0\n  STRING_xwd0\n  STRING_yezi0\n  STRING_yezidi0\n  STRING_yi0\n  STRING_yiii0\n  STRING_z0\n  STRING_zanabazarsquare0\n  STRING_zanb0\n  STRING_zinh0\n  STRING_zl0\n  STRING_zp0\n  STRING_zs0\n  STRING_zyyy0\n  STRING_zzzz0;\n\nconst ucp_type_table PRIV(utt)[] = {\n  {   0, PT_SCX, ucp_Adlam },\n  {   6, PT_SCX, ucp_Adlam },\n  {  11, PT_SCX, ucp_Caucasian_Albanian },\n  {  16, PT_BOOL, ucp_ASCII_Hex_Digit },\n  {  21, PT_SC, ucp_Ahom },\n  {  26, PT_BOOL, ucp_Alphabetic },\n  {  32, PT_BOOL, ucp_Alphabetic },\n  {  43, PT_SC, ucp_Anatolian_Hieroglyphs },\n  {  64, PT_ANY, 0 },\n  {  68, PT_SCX, ucp_Arabic },\n  {  73, PT_SCX, ucp_Arabic },\n  {  80, PT_SCX, ucp_Armenian },\n  {  89, PT_SC, ucp_Imperial_Aramaic },\n  {  94, PT_SCX, ucp_Armenian },\n  {  99, PT_BOOL, ucp_ASCII },\n  { 105, PT_BOOL, ucp_ASCII_Hex_Digit },\n  { 119, PT_SCX, ucp_Avestan },\n  { 127, PT_SCX, ucp_Avestan },\n  { 132, PT_SC, ucp_Balinese },\n  { 137, PT_SC, ucp_Balinese },\n  { 146, PT_SC, ucp_Bamum },\n  { 151, PT_SC, ucp_Bamum },\n  { 157, PT_SC, ucp_Bassa_Vah },\n  { 162, PT_SC, ucp_Bassa_Vah },\n  { 171, PT_SC, ucp_Batak },\n  { 177, PT_SC, ucp_Batak },\n  { 182, PT_SCX, ucp_Bengali },\n  { 187, PT_SCX, ucp_Bengali },\n  { 195, PT_SC, ucp_Bhaiksuki },\n  { 205, PT_SC, ucp_Bhaiksuki },\n  { 210, PT_BIDICL, ucp_bidiAL },\n  { 217, PT_BIDICL, ucp_bidiAN },\n  { 224, PT_BIDICL, ucp_bidiB },\n  { 230, PT_BIDICL, ucp_bidiBN },\n  { 237, PT_BOOL, ucp_Bidi_Control },\n  { 243, PT_BOOL, ucp_Bidi_Control },\n  { 255, PT_BIDICL, ucp_bidiCS },\n  { 262, PT_BIDICL, ucp_bidiEN },\n  { 269, PT_BIDICL, ucp_bidiES },\n  { 276, PT_BIDICL, ucp_bidiET },\n  { 283, PT_BIDICL, ucp_bidiFSI },\n  { 291, PT_BIDICL, ucp_bidiL },\n  { 297, PT_BIDICL, ucp_bidiLRE },\n  { 305, PT_BIDICL, ucp_bidiLRI },\n  { 313, PT_BIDICL, ucp_bidiLRO },\n  { 321, PT_BOOL, ucp_Bidi_Mirrored },\n  { 327, PT_BOOL, ucp_Bidi_Mirrored },\n  { 340, PT_BIDICL, ucp_bidiNSM },\n  { 348, PT_BIDICL, ucp_bidiON },\n  { 355, PT_BIDICL, ucp_bidiPDF },\n  { 363, PT_BIDICL, ucp_bidiPDI },\n  { 371, PT_BIDICL, ucp_bidiR },\n  { 377, PT_BIDICL, ucp_bidiRLE },\n  { 385, PT_BIDICL, ucp_bidiRLI },\n  { 393, PT_BIDICL, ucp_bidiRLO },\n  { 401, PT_BIDICL, ucp_bidiS },\n  { 407, PT_BIDICL, ucp_bidiWS },\n  { 414, PT_SCX, ucp_Bopomofo },\n  { 419, PT_SCX, ucp_Bopomofo },\n  { 428, PT_SC, ucp_Brahmi },\n  { 433, PT_SC, ucp_Brahmi },\n  { 440, PT_SC, ucp_Braille },\n  { 445, PT_SC, ucp_Braille },\n  { 453, PT_SCX, ucp_Buginese },\n  { 458, PT_SCX, ucp_Buginese },\n  { 467, PT_SCX, ucp_Buhid },\n  { 472, PT_SCX, ucp_Buhid },\n  { 478, PT_GC, ucp_C },\n  { 480, PT_SCX, ucp_Chakma },\n  { 485, PT_SC, ucp_Canadian_Aboriginal },\n  { 504, PT_SC, ucp_Canadian_Aboriginal },\n  { 509, PT_SCX, ucp_Carian },\n  { 514, PT_SCX, ucp_Carian },\n  { 521, PT_BOOL, ucp_Cased },\n  { 527, PT_BOOL, ucp_Case_Ignorable },\n  { 541, PT_SCX, ucp_Caucasian_Albanian },\n  { 559, PT_PC, ucp_Cc },\n  { 562, PT_PC, ucp_Cf },\n  { 565, PT_SCX, ucp_Chakma },\n  { 572, PT_SC, ucp_Cham },\n  { 577, PT_BOOL, ucp_Changes_When_Casefolded },\n  { 599, PT_BOOL, ucp_Changes_When_Casemapped },\n  { 621, PT_BOOL, ucp_Changes_When_Lowercased },\n  { 643, PT_BOOL, ucp_Changes_When_Titlecased },\n  { 665, PT_BOOL, ucp_Changes_When_Uppercased },\n  { 687, PT_SCX, ucp_Cherokee },\n  { 692, PT_SCX, ucp_Cherokee },\n  { 701, PT_SC, ucp_Chorasmian },\n  { 712, PT_SC, ucp_Chorasmian },\n  { 717, PT_BOOL, ucp_Case_Ignorable },\n  { 720, PT_PC, ucp_Cn },\n  { 723, PT_PC, ucp_Co },\n  { 726, PT_SC, ucp_Common },\n  { 733, PT_SCX, ucp_Coptic },\n  { 738, PT_SCX, ucp_Coptic },\n  { 745, PT_SCX, ucp_Cypro_Minoan },\n  { 750, PT_SCX, ucp_Cypriot },\n  { 755, PT_PC, ucp_Cs },\n  { 758, PT_SC, ucp_Cuneiform },\n  { 768, PT_BOOL, ucp_Changes_When_Casefolded },\n  { 773, PT_BOOL, ucp_Changes_When_Casemapped },\n  { 778, PT_BOOL, ucp_Changes_When_Lowercased },\n  { 782, PT_BOOL, ucp_Changes_When_Titlecased },\n  { 786, PT_BOOL, ucp_Changes_When_Uppercased },\n  { 790, PT_SCX, ucp_Cypriot },\n  { 798, PT_SCX, ucp_Cypro_Minoan },\n  { 810, PT_SCX, ucp_Cyrillic },\n  { 819, PT_SCX, ucp_Cyrillic },\n  { 824, PT_BOOL, ucp_Dash },\n  { 829, PT_BOOL, ucp_Default_Ignorable_Code_Point },\n  { 855, PT_BOOL, ucp_Deprecated },\n  { 859, PT_BOOL, ucp_Deprecated },\n  { 870, PT_SC, ucp_Deseret },\n  { 878, PT_SCX, ucp_Devanagari },\n  { 883, PT_SCX, ucp_Devanagari },\n  { 894, PT_BOOL, ucp_Default_Ignorable_Code_Point },\n  { 897, PT_BOOL, ucp_Diacritic },\n  { 901, PT_BOOL, ucp_Diacritic },\n  { 911, PT_SC, ucp_Dives_Akuru },\n  { 916, PT_SC, ucp_Dives_Akuru },\n  { 927, PT_SCX, ucp_Dogra },\n  { 932, PT_SCX, ucp_Dogra },\n  { 938, PT_SC, ucp_Deseret },\n  { 943, PT_SCX, ucp_Duployan },\n  { 948, PT_SCX, ucp_Duployan },\n  { 957, PT_BOOL, ucp_Emoji_Modifier_Base },\n  { 963, PT_BOOL, ucp_Emoji_Component },\n  { 969, PT_SC, ucp_Egyptian_Hieroglyphs },\n  { 974, PT_SC, ucp_Egyptian_Hieroglyphs },\n  { 994, PT_SCX, ucp_Elbasan },\n  { 999, PT_SCX, ucp_Elbasan },\n  { 1007, PT_SC, ucp_Elymaic },\n  { 1012, PT_SC, ucp_Elymaic },\n  { 1020, PT_BOOL, ucp_Emoji_Modifier },\n  { 1025, PT_BOOL, ucp_Emoji },\n  { 1031, PT_BOOL, ucp_Emoji_Component },\n  { 1046, PT_BOOL, ucp_Emoji_Modifier },\n  { 1060, PT_BOOL, ucp_Emoji_Modifier_Base },\n  { 1078, PT_BOOL, ucp_Emoji_Presentation },\n  { 1096, PT_BOOL, ucp_Emoji_Presentation },\n  { 1102, PT_SCX, ucp_Ethiopic },\n  { 1107, PT_SCX, ucp_Ethiopic },\n  { 1116, PT_BOOL, ucp_Extender },\n  { 1120, PT_BOOL, ucp_Extended_Pictographic },\n  { 1141, PT_BOOL, ucp_Extender },\n  { 1150, PT_BOOL, ucp_Extended_Pictographic },\n  { 1158, PT_SCX, ucp_Garay },\n  { 1163, PT_SCX, ucp_Garay },\n  { 1169, PT_SCX, ucp_Georgian },\n  { 1174, PT_SCX, ucp_Georgian },\n  { 1183, PT_SCX, ucp_Glagolitic },\n  { 1188, PT_SCX, ucp_Glagolitic },\n  { 1199, PT_SCX, ucp_Gunjala_Gondi },\n  { 1204, PT_SCX, ucp_Masaram_Gondi },\n  { 1209, PT_SCX, ucp_Gothic },\n  { 1214, PT_SCX, ucp_Gothic },\n  { 1221, PT_SCX, ucp_Grantha },\n  { 1226, PT_SCX, ucp_Grantha },\n  { 1234, PT_BOOL, ucp_Grapheme_Base },\n  { 1247, PT_BOOL, ucp_Grapheme_Extend },\n  { 1262, PT_BOOL, ucp_Grapheme_Link },\n  { 1275, PT_BOOL, ucp_Grapheme_Base },\n  { 1282, PT_SCX, ucp_Greek },\n  { 1288, PT_SCX, ucp_Greek },\n  { 1293, PT_BOOL, ucp_Grapheme_Extend },\n  { 1299, PT_BOOL, ucp_Grapheme_Link },\n  { 1306, PT_SCX, ucp_Gujarati },\n  { 1315, PT_SCX, ucp_Gujarati },\n  { 1320, PT_SCX, ucp_Gurung_Khema },\n  { 1325, PT_SCX, ucp_Gunjala_Gondi },\n  { 1338, PT_SCX, ucp_Gurmukhi },\n  { 1347, PT_SCX, ucp_Gurmukhi },\n  { 1352, PT_SCX, ucp_Gurung_Khema },\n  { 1364, PT_SCX, ucp_Han },\n  { 1368, PT_SCX, ucp_Hangul },\n  { 1373, PT_SCX, ucp_Hangul },\n  { 1380, PT_SCX, ucp_Han },\n  { 1385, PT_SCX, ucp_Hanifi_Rohingya },\n  { 1400, PT_SCX, ucp_Hanunoo },\n  { 1405, PT_SCX, ucp_Hanunoo },\n  { 1413, PT_SC, ucp_Hatran },\n  { 1418, PT_SC, ucp_Hatran },\n  { 1425, PT_SCX, ucp_Hebrew },\n  { 1430, PT_SCX, ucp_Hebrew },\n  { 1437, PT_BOOL, ucp_Hex_Digit },\n  { 1441, PT_BOOL, ucp_Hex_Digit },\n  { 1450, PT_SCX, ucp_Hiragana },\n  { 1455, PT_SCX, ucp_Hiragana },\n  { 1464, PT_SC, ucp_Anatolian_Hieroglyphs },\n  { 1469, PT_SC, ucp_Pahawh_Hmong },\n  { 1474, PT_SC, ucp_Nyiakeng_Puachue_Hmong },\n  { 1479, PT_SCX, ucp_Old_Hungarian },\n  { 1484, PT_BOOL, ucp_ID_Continue },\n  { 1488, PT_BOOL, ucp_ID_Compat_Math_Continue },\n  { 1509, PT_BOOL, ucp_ID_Compat_Math_Start },\n  { 1527, PT_BOOL, ucp_ID_Continue },\n  { 1538, PT_BOOL, ucp_Ideographic },\n  { 1543, PT_BOOL, ucp_Ideographic },\n  { 1555, PT_BOOL, ucp_ID_Start },\n  { 1559, PT_BOOL, ucp_IDS_Binary_Operator },\n  { 1564, PT_BOOL, ucp_IDS_Binary_Operator },\n  { 1582, PT_BOOL, ucp_IDS_Trinary_Operator },\n  { 1587, PT_BOOL, ucp_ID_Start },\n  { 1595, PT_BOOL, ucp_IDS_Trinary_Operator },\n  { 1614, PT_BOOL, ucp_IDS_Unary_Operator },\n  { 1619, PT_BOOL, ucp_IDS_Unary_Operator },\n  { 1636, PT_SC, ucp_Imperial_Aramaic },\n  { 1652, PT_BOOL, ucp_InCB },\n  { 1657, PT_SC, ucp_Inherited },\n  { 1667, PT_SC, ucp_Inscriptional_Pahlavi },\n  { 1688, PT_SC, ucp_Inscriptional_Parthian },\n  { 1710, PT_SC, ucp_Old_Italic },\n  { 1715, PT_SCX, ucp_Javanese },\n  { 1720, PT_SCX, ucp_Javanese },\n  { 1729, PT_BOOL, ucp_Join_Control },\n  { 1735, PT_BOOL, ucp_Join_Control },\n  { 1747, PT_SCX, ucp_Kaithi },\n  { 1754, PT_SCX, ucp_Kayah_Li },\n  { 1759, PT_SCX, ucp_Katakana },\n  { 1764, PT_SCX, ucp_Kannada },\n  { 1772, PT_SCX, ucp_Katakana },\n  { 1781, PT_SC, ucp_Kawi },\n  { 1786, PT_SCX, ucp_Kayah_Li },\n  { 1794, PT_SC, ucp_Kharoshthi },\n  { 1799, PT_SC, ucp_Kharoshthi },\n  { 1810, PT_SC, ucp_Khitan_Small_Script },\n  { 1828, PT_SC, ucp_Khmer },\n  { 1834, PT_SC, ucp_Khmer },\n  { 1839, PT_SCX, ucp_Khojki },\n  { 1844, PT_SCX, ucp_Khojki },\n  { 1851, PT_SCX, ucp_Khudawadi },\n  { 1861, PT_SC, ucp_Kirat_Rai },\n  { 1870, PT_SC, ucp_Khitan_Small_Script },\n  { 1875, PT_SCX, ucp_Kannada },\n  { 1880, PT_SC, ucp_Kirat_Rai },\n  { 1885, PT_SCX, ucp_Kaithi },\n  { 1890, PT_GC, ucp_L },\n  { 1892, PT_LAMP, 0 },\n  { 1895, PT_SC, ucp_Tai_Tham },\n  { 1900, PT_SC, ucp_Lao },\n  { 1904, PT_SC, ucp_Lao },\n  { 1909, PT_SCX, ucp_Latin },\n  { 1915, PT_SCX, ucp_Latin },\n  { 1920, PT_LAMP, 0 },\n  { 1923, PT_SC, ucp_Lepcha },\n  { 1928, PT_SC, ucp_Lepcha },\n  { 1935, PT_SCX, ucp_Limbu },\n  { 1940, PT_SCX, ucp_Limbu },\n  { 1946, PT_SCX, ucp_Linear_A },\n  { 1951, PT_SCX, ucp_Linear_B },\n  { 1956, PT_SCX, ucp_Linear_A },\n  { 1964, PT_SCX, ucp_Linear_B },\n  { 1972, PT_SCX, ucp_Lisu },\n  { 1977, PT_PC, ucp_Ll },\n  { 1980, PT_PC, ucp_Lm },\n  { 1983, PT_PC, ucp_Lo },\n  { 1986, PT_BOOL, ucp_Logical_Order_Exception },\n  { 1990, PT_BOOL, ucp_Logical_Order_Exception },\n  { 2012, PT_BOOL, ucp_Lowercase },\n  { 2018, PT_BOOL, ucp_Lowercase },\n  { 2028, PT_PC, ucp_Lt },\n  { 2031, PT_PC, ucp_Lu },\n  { 2034, PT_SCX, ucp_Lycian },\n  { 2039, PT_SCX, ucp_Lycian },\n  { 2046, PT_SCX, ucp_Lydian },\n  { 2051, PT_SCX, ucp_Lydian },\n  { 2058, PT_GC, ucp_M },\n  { 2060, PT_SCX, ucp_Mahajani },\n  { 2069, PT_SCX, ucp_Mahajani },\n  { 2074, PT_SC, ucp_Makasar },\n  { 2079, PT_SC, ucp_Makasar },\n  { 2087, PT_SCX, ucp_Malayalam },\n  { 2097, PT_SCX, ucp_Mandaic },\n  { 2102, PT_SCX, ucp_Mandaic },\n  { 2110, PT_SCX, ucp_Manichaean },\n  { 2115, PT_SCX, ucp_Manichaean },\n  { 2126, PT_SC, ucp_Marchen },\n  { 2131, PT_SC, ucp_Marchen },\n  { 2139, PT_SCX, ucp_Masaram_Gondi },\n  { 2152, PT_BOOL, ucp_Math },\n  { 2157, PT_PC, ucp_Mc },\n  { 2160, PT_BOOL, ucp_Modifier_Combining_Mark },\n  { 2164, PT_PC, ucp_Me },\n  { 2167, PT_SC, ucp_Medefaidrin },\n  { 2179, PT_SC, ucp_Medefaidrin },\n  { 2184, PT_SC, ucp_Meetei_Mayek },\n  { 2196, PT_SC, ucp_Mende_Kikakui },\n  { 2201, PT_SC, ucp_Mende_Kikakui },\n  { 2214, PT_SC, ucp_Meroitic_Cursive },\n  { 2219, PT_SCX, ucp_Meroitic_Hieroglyphs },\n  { 2224, PT_SC, ucp_Meroitic_Cursive },\n  { 2240, PT_SCX, ucp_Meroitic_Hieroglyphs },\n  { 2260, PT_SC, ucp_Miao },\n  { 2265, PT_SCX, ucp_Malayalam },\n  { 2270, PT_PC, ucp_Mn },\n  { 2273, PT_SCX, ucp_Modi },\n  { 2278, PT_BOOL, ucp_Modifier_Combining_Mark },\n  { 2300, PT_SCX, ucp_Mongolian },\n  { 2305, PT_SCX, ucp_Mongolian },\n  { 2315, PT_SC, ucp_Mro },\n  { 2319, PT_SC, ucp_Mro },\n  { 2324, PT_SC, ucp_Meetei_Mayek },\n  { 2329, PT_SCX, ucp_Multani },\n  { 2334, PT_SCX, ucp_Multani },\n  { 2342, PT_SCX, ucp_Myanmar },\n  { 2350, PT_SCX, ucp_Myanmar },\n  { 2355, PT_GC, ucp_N },\n  { 2357, PT_SC, ucp_Nabataean },\n  { 2367, PT_SC, ucp_Nag_Mundari },\n  { 2372, PT_SC, ucp_Nag_Mundari },\n  { 2383, PT_SCX, ucp_Nandinagari },\n  { 2388, PT_SCX, ucp_Nandinagari },\n  { 2400, PT_SC, ucp_Old_North_Arabian },\n  { 2405, PT_SC, ucp_Nabataean },\n  { 2410, PT_BOOL, ucp_Noncharacter_Code_Point },\n  { 2416, PT_PC, ucp_Nd },\n  { 2419, PT_SC, ucp_Newa },\n  { 2424, PT_SC, ucp_New_Tai_Lue },\n  { 2434, PT_SCX, ucp_Nko },\n  { 2438, PT_SCX, ucp_Nko },\n  { 2443, PT_PC, ucp_Nl },\n  { 2446, PT_PC, ucp_No },\n  { 2449, PT_BOOL, ucp_Noncharacter_Code_Point },\n  { 2471, PT_SC, ucp_Nushu },\n  { 2476, PT_SC, ucp_Nushu },\n  { 2482, PT_SC, ucp_Nyiakeng_Puachue_Hmong },\n  { 2503, PT_SC, ucp_Ogham },\n  { 2508, PT_SC, ucp_Ogham },\n  { 2514, PT_SC, ucp_Ol_Chiki },\n  { 2522, PT_SC, ucp_Ol_Chiki },\n  { 2527, PT_SCX, ucp_Old_Hungarian },\n  { 2540, PT_SC, ucp_Old_Italic },\n  { 2550, PT_SC, ucp_Old_North_Arabian },\n  { 2566, PT_SCX, ucp_Old_Permic },\n  { 2576, PT_SC, ucp_Old_Persian },\n  { 2587, PT_SC, ucp_Old_Sogdian },\n  { 2598, PT_SC, ucp_Old_South_Arabian },\n  { 2614, PT_SCX, ucp_Old_Turkic },\n  { 2624, PT_SCX, ucp_Old_Uyghur },\n  { 2634, PT_SCX, ucp_Ol_Onal },\n  { 2641, PT_SCX, ucp_Ol_Onal },\n  { 2646, PT_SCX, ucp_Oriya },\n  { 2652, PT_SCX, ucp_Old_Turkic },\n  { 2657, PT_SCX, ucp_Oriya },\n  { 2662, PT_SCX, ucp_Osage },\n  { 2668, PT_SCX, ucp_Osage },\n  { 2673, PT_SC, ucp_Osmanya },\n  { 2678, PT_SC, ucp_Osmanya },\n  { 2686, PT_SCX, ucp_Old_Uyghur },\n  { 2691, PT_GC, ucp_P },\n  { 2693, PT_SC, ucp_Pahawh_Hmong },\n  { 2705, PT_SC, ucp_Palmyrene },\n  { 2710, PT_SC, ucp_Palmyrene },\n  { 2720, PT_BOOL, ucp_Pattern_Syntax },\n  { 2727, PT_BOOL, ucp_Pattern_Syntax },\n  { 2741, PT_BOOL, ucp_Pattern_White_Space },\n  { 2759, PT_BOOL, ucp_Pattern_White_Space },\n  { 2765, PT_SC, ucp_Pau_Cin_Hau },\n  { 2770, PT_SC, ucp_Pau_Cin_Hau },\n  { 2780, PT_PC, ucp_Pc },\n  { 2783, PT_BOOL, ucp_Prepended_Concatenation_Mark },\n  { 2787, PT_PC, ucp_Pd },\n  { 2790, PT_PC, ucp_Pe },\n  { 2793, PT_SCX, ucp_Old_Permic },\n  { 2798, PT_PC, ucp_Pf },\n  { 2801, PT_SCX, ucp_Phags_Pa },\n  { 2806, PT_SCX, ucp_Phags_Pa },\n  { 2814, PT_SC, ucp_Inscriptional_Pahlavi },\n  { 2819, PT_SCX, ucp_Psalter_Pahlavi },\n  { 2824, PT_SC, ucp_Phoenician },\n  { 2829, PT_SC, ucp_Phoenician },\n  { 2840, PT_PC, ucp_Pi },\n  { 2843, PT_SC, ucp_Miao },\n  { 2848, PT_PC, ucp_Po },\n  { 2851, PT_BOOL, ucp_Prepended_Concatenation_Mark },\n  { 2878, PT_SC, ucp_Inscriptional_Parthian },\n  { 2883, PT_PC, ucp_Ps },\n  { 2886, PT_SCX, ucp_Psalter_Pahlavi },\n  { 2901, PT_SCX, ucp_Coptic },\n  { 2906, PT_SC, ucp_Inherited },\n  { 2911, PT_BOOL, ucp_Quotation_Mark },\n  { 2917, PT_BOOL, ucp_Quotation_Mark },\n  { 2931, PT_BOOL, ucp_Radical },\n  { 2939, PT_BOOL, ucp_Regional_Indicator },\n  { 2957, PT_SC, ucp_Rejang },\n  { 2964, PT_BOOL, ucp_Regional_Indicator },\n  { 2967, PT_SC, ucp_Rejang },\n  { 2972, PT_SCX, ucp_Hanifi_Rohingya },\n  { 2977, PT_SCX, ucp_Runic },\n  { 2983, PT_SCX, ucp_Runic },\n  { 2988, PT_GC, ucp_S },\n  { 2990, PT_SCX, ucp_Samaritan },\n  { 3000, PT_SCX, ucp_Samaritan },\n  { 3005, PT_SC, ucp_Old_South_Arabian },\n  { 3010, PT_SC, ucp_Saurashtra },\n  { 3015, PT_SC, ucp_Saurashtra },\n  { 3026, PT_PC, ucp_Sc },\n  { 3029, PT_BOOL, ucp_Soft_Dotted },\n  { 3032, PT_BOOL, ucp_Sentence_Terminal },\n  { 3049, PT_SC, ucp_SignWriting },\n  { 3054, PT_SCX, ucp_Sharada },\n  { 3062, PT_SCX, ucp_Shavian },\n  { 3070, PT_SCX, ucp_Shavian },\n  { 3075, PT_SCX, ucp_Sharada },\n  { 3080, PT_SC, ucp_Siddham },\n  { 3085, PT_SC, ucp_Siddham },\n  { 3093, PT_SC, ucp_SignWriting },\n  { 3105, PT_SCX, ucp_Khudawadi },\n  { 3110, PT_SCX, ucp_Sinhala },\n  { 3115, PT_SCX, ucp_Sinhala },\n  { 3123, PT_PC, ucp_Sk },\n  { 3126, PT_PC, ucp_Sm },\n  { 3129, PT_PC, ucp_So },\n  { 3132, PT_BOOL, ucp_Soft_Dotted },\n  { 3143, PT_SCX, ucp_Sogdian },\n  { 3148, PT_SCX, ucp_Sogdian },\n  { 3156, PT_SC, ucp_Old_Sogdian },\n  { 3161, PT_SC, ucp_Sora_Sompeng },\n  { 3166, PT_SC, ucp_Sora_Sompeng },\n  { 3178, PT_SC, ucp_Soyombo },\n  { 3183, PT_SC, ucp_Soyombo },\n  { 3191, PT_BOOL, ucp_White_Space },\n  { 3197, PT_BOOL, ucp_Sentence_Terminal },\n  { 3203, PT_SC, ucp_Sundanese },\n  { 3208, PT_SC, ucp_Sundanese },\n  { 3218, PT_SCX, ucp_Sunuwar },\n  { 3223, PT_SCX, ucp_Sunuwar },\n  { 3231, PT_SCX, ucp_Syloti_Nagri },\n  { 3236, PT_SCX, ucp_Syloti_Nagri },\n  { 3248, PT_SCX, ucp_Syriac },\n  { 3253, PT_SCX, ucp_Syriac },\n  { 3260, PT_SCX, ucp_Tagalog },\n  { 3268, PT_SCX, ucp_Tagbanwa },\n  { 3273, PT_SCX, ucp_Tagbanwa },\n  { 3282, PT_SCX, ucp_Tai_Le },\n  { 3288, PT_SC, ucp_Tai_Tham },\n  { 3296, PT_SC, ucp_Tai_Viet },\n  { 3304, PT_SCX, ucp_Takri },\n  { 3309, PT_SCX, ucp_Takri },\n  { 3315, PT_SCX, ucp_Tai_Le },\n  { 3320, PT_SC, ucp_New_Tai_Lue },\n  { 3325, PT_SCX, ucp_Tamil },\n  { 3331, PT_SCX, ucp_Tamil },\n  { 3336, PT_SCX, ucp_Tangut },\n  { 3341, PT_SC, ucp_Tangsa },\n  { 3348, PT_SCX, ucp_Tangut },\n  { 3355, PT_SC, ucp_Tai_Viet },\n  { 3360, PT_SCX, ucp_Telugu },\n  { 3365, PT_SCX, ucp_Telugu },\n  { 3372, PT_BOOL, ucp_Terminal_Punctuation },\n  { 3377, PT_BOOL, ucp_Terminal_Punctuation },\n  { 3397, PT_SCX, ucp_Tifinagh },\n  { 3402, PT_SCX, ucp_Tagalog },\n  { 3407, PT_SCX, ucp_Thaana },\n  { 3412, PT_SCX, ucp_Thaana },\n  { 3419, PT_SCX, ucp_Thai },\n  { 3424, PT_SCX, ucp_Tibetan },\n  { 3432, PT_SCX, ucp_Tibetan },\n  { 3437, PT_SCX, ucp_Tifinagh },\n  { 3446, PT_SCX, ucp_Tirhuta },\n  { 3451, PT_SCX, ucp_Tirhuta },\n  { 3459, PT_SC, ucp_Tangsa },\n  { 3464, PT_SCX, ucp_Todhri },\n  { 3471, PT_SCX, ucp_Todhri },\n  { 3476, PT_SCX, ucp_Toto },\n  { 3481, PT_SCX, ucp_Tulu_Tigalari },\n  { 3494, PT_SCX, ucp_Tulu_Tigalari },\n  { 3499, PT_SC, ucp_Ugaritic },\n  { 3504, PT_SC, ucp_Ugaritic },\n  { 3513, PT_BOOL, ucp_Unified_Ideograph },\n  { 3519, PT_BOOL, ucp_Unified_Ideograph },\n  { 3536, PT_SC, ucp_Unknown },\n  { 3544, PT_BOOL, ucp_Uppercase },\n  { 3550, PT_BOOL, ucp_Uppercase },\n  { 3560, PT_SC, ucp_Vai },\n  { 3564, PT_SC, ucp_Vai },\n  { 3569, PT_BOOL, ucp_Variation_Selector },\n  { 3587, PT_SC, ucp_Vithkuqi },\n  { 3592, PT_SC, ucp_Vithkuqi },\n  { 3601, PT_BOOL, ucp_Variation_Selector },\n  { 3604, PT_SC, ucp_Wancho },\n  { 3611, PT_SC, ucp_Warang_Citi },\n  { 3616, PT_SC, ucp_Warang_Citi },\n  { 3627, PT_SC, ucp_Wancho },\n  { 3632, PT_BOOL, ucp_White_Space },\n  { 3643, PT_BOOL, ucp_White_Space },\n  { 3650, PT_ALNUM, 0 },\n  { 3654, PT_BOOL, ucp_XID_Continue },\n  { 3659, PT_BOOL, ucp_XID_Continue },\n  { 3671, PT_BOOL, ucp_XID_Start },\n  { 3676, PT_BOOL, ucp_XID_Start },\n  { 3685, PT_SC, ucp_Old_Persian },\n  { 3690, PT_PXSPACE, 0 },\n  { 3694, PT_SPACE, 0 },\n  { 3698, PT_SC, ucp_Cuneiform },\n  { 3703, PT_UCNC, 0 },\n  { 3707, PT_WORD, 0 },\n  { 3711, PT_SCX, ucp_Yezidi },\n  { 3716, PT_SCX, ucp_Yezidi },\n  { 3723, PT_SCX, ucp_Yi },\n  { 3726, PT_SCX, ucp_Yi },\n  { 3731, PT_GC, ucp_Z },\n  { 3733, PT_SC, ucp_Zanabazar_Square },\n  { 3749, PT_SC, ucp_Zanabazar_Square },\n  { 3754, PT_SC, ucp_Inherited },\n  { 3759, PT_PC, ucp_Zl },\n  { 3762, PT_PC, ucp_Zp },\n  { 3765, PT_PC, ucp_Zs },\n  { 3768, PT_SC, ucp_Common },\n  { 3773, PT_SC, ucp_Unknown }\n};\n\nconst size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);\n\n#endif /* SUPPORT_UNICODE */\n\n/* End of pcre2_ucptables_inc.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_util.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2_UTIL_H_IDEMPOTENT_GUARD\n#define PCRE2_UTIL_H_IDEMPOTENT_GUARD\n\n/* Assertion macros */\n\n#ifdef PCRE2_DEBUG\n\n#if defined(HAVE_ASSERT_H) && !defined(NDEBUG)\n#include <assert.h>\n#endif\n\n/* PCRE2_ASSERT(x) can be used to inject an assert() for conditions\nthat the code below doesn't support. It is a NOP for non debug builds\nbut in debug builds will print information about the location of the\ncode where it triggered and crash.\n\nIt is meant to work like assert(), and therefore the expression used\nshould indicate what the expected state is, and shouldn't have any\nside-effects. */\n\n#if defined(HAVE_ASSERT_H) && !defined(NDEBUG)\n#define PCRE2_ASSERT(x) assert(x)\n#else\n#define PCRE2_ASSERT(x) do                                            \\\n{                                                                     \\\n  if (!(x))                                                           \\\n  {                                                                   \\\n  fprintf(stderr, \"Assertion failed at \" __FILE__ \":%d\\n\", __LINE__); \\\n  abort();                                                            \\\n  }                                                                   \\\n} while(0)\n#endif\n\n/* LCOV_EXCL_START */\n\n/* PCRE2_UNREACHABLE() can be used to mark locations on the code that\nshouldn't be reached. In non debug builds is defined as a hint for\nthe compiler to eliminate any code after it, so it is useful also for\nperformance reasons, but should be used with care because if it is\never reached will trigger Undefined Behaviour and if you are lucky a\ncrash. In debug builds it will report the location where it was triggered\nand crash. One important point to consider when using this macro, is\nthat it is only implemented for a few compilers, and therefore can't\nbe relied on to always be active either, so if it is followed by some\ncode it is important to make sure that the whole thing is safe to\nuse even if the macro is not there (ex: make sure there is a `break`\nafter it if used at the end of a `case`) and to test your code also\nwith a configuration where the macro will be a NOP. */\n\n#if defined(HAVE_ASSERT_H) && !defined(NDEBUG)\n#define PCRE2_UNREACHABLE()                                         \\\nassert(((void)\"Execution reached unexpected point\", 0))\n#else\n#define PCRE2_UNREACHABLE() do                                      \\\n{                                                                   \\\nfprintf(stderr, \"Execution reached unexpected point at \" __FILE__   \\\n                \":%d\\n\", __LINE__);                                 \\\nabort();                                                            \\\n} while(0)\n#endif\n\n/* PCRE2_DEBUG_UNREACHABLE() is a debug only version of the previous\nmacro. It is meant to be used in places where the code is handling\nan error situation in code that shouldn't be reached, but that has\nsome sort of fallback code to normally handle the error. When in\ndoubt you should use this instead of the previous macro. Like in\nthe previous case, it is a good idea to document as much as possible\nthe reason and the actions that should be taken if it ever triggers. */\n\n#define PCRE2_DEBUG_UNREACHABLE() PCRE2_UNREACHABLE()\n\n/* LCOV_EXCL_STOP */\n\n#endif /* PCRE2_DEBUG */\n\n#ifndef PCRE2_ASSERT\n#define PCRE2_ASSERT(x) do {} while(0)\n#endif\n\n/* LCOV_EXCL_START */\n\n#ifndef PCRE2_DEBUG_UNREACHABLE\n#define PCRE2_DEBUG_UNREACHABLE() do {} while(0)\n#endif\n\n#ifndef PCRE2_UNREACHABLE\n#ifdef HAVE_BUILTIN_UNREACHABLE\n#define PCRE2_UNREACHABLE() __builtin_unreachable()\n#elif defined(HAVE_BUILTIN_ASSUME)\n#define PCRE2_UNREACHABLE() __assume(0)\n#else\n#define PCRE2_UNREACHABLE() do {} while(0)\n#endif\n#endif /* !PCRE2_UNREACHABLE */\n\n/* LCOV_EXCL_STOP */\n\n/* We define this fallthrough macro for suppressing -Wimplicit-fallthrough warnings.\nClang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes\nand also specially-formatted comments.\n\nThis macro should be used with no following semicolon, and ideally with a comment: */\n\n//  PCRE2_FALLTHROUGH /* Fall through */\n\n#ifndef PCRE2_FALLTHROUGH\n\n#if defined(__cplusplus) && __cplusplus >= 202002L && \\\n    defined(__has_cpp_attribute)\n/* Standards-compatible C++ variant. */\n#if __has_cpp_attribute(fallthrough)\n#define PCRE2_FALLTHROUGH [[fallthrough]];\n#endif\n#elif !defined(__cplusplus) && \\\n      defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \\\n      defined(__has_c_attribute)\n/* Standards-compatible C variant. */\n#if __has_c_attribute(fallthrough)\n#define PCRE2_FALLTHROUGH [[fallthrough]];\n#endif\n#elif ((defined(__clang__) && __clang_major__ >= 10) || \\\n       (defined(__GNUC__) && __GNUC__ >= 7)) && \\\n      defined(__has_attribute)\n/* Clang and GCC syntax. Rule out old versions because apparently Clang at\n   least has a broken implementation of __has_attribute. */\n#if __has_attribute(fallthrough)\n#define PCRE2_FALLTHROUGH __attribute__((fallthrough));\n#endif\n#endif\n\n#endif /* !PCRE2_FALLTHROUGH */\n\n#ifndef PCRE2_FALLTHROUGH\n#define PCRE2_FALLTHROUGH\n#endif\n\n#endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2_util.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_valid_utf.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2020 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains an internal function for validating UTF character\nstrings. This file is also #included by the pcre2test program, which uses\nmacros to change names from _pcre2_xxx to xxxx, thereby avoiding name clashes\nwith the library. In this case, PCRE2_PCRE2TEST is defined. */\n\n\n#ifndef PCRE2_PCRE2TEST           /* We're compiling the library */\n#include \"pcre2_internal.h\"\n#endif /* PCRE2_PCRE2TEST */\n\n\n\n#ifndef SUPPORT_UNICODE\n/*************************************************\n*  Dummy function when Unicode is not supported  *\n*************************************************/\n\n/* This function should never be called when Unicode is not supported. */\n\nint\nPRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)\n{\n(void)string;\n(void)length;\n(void)erroroffset;\nreturn 0;\n}\n#else  /* UTF is supported */\n\n\n\n/*************************************************\n*           Validate a UTF string                *\n*************************************************/\n\n/* This function is called (optionally) at the start of compile or match, to\ncheck that a supposed UTF string is actually valid. The early check means\nthat subsequent code can assume it is dealing with a valid string. The check\ncan be turned off for maximum performance, but the consequences of supplying an\ninvalid string are then undefined.\n\nArguments:\n  string       points to the string\n  length       length of string\n  errp         pointer to an error position offset variable\n\nReturns:       == 0    if the string is a valid UTF string\n               != 0    otherwise, setting the offset of the bad character\n*/\n\nint\nPRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)\n{\nPCRE2_SPTR p;\nuint32_t c;\n\n/* ----------------- Check a UTF-8 string ----------------- */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n\n/* Originally, this function checked according to RFC 2279, allowing for values\nin the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were\nin the canonical format. Once somebody had pointed out RFC 3629 to me (it\nobsoletes 2279), additional restrictions were applied. The values are now\nlimited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the\nsubrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte\ncharacters is still checked. Error returns are as follows:\n\nPCRE2_ERROR_UTF8_ERR1   Missing 1 byte at the end of the string\nPCRE2_ERROR_UTF8_ERR2   Missing 2 bytes at the end of the string\nPCRE2_ERROR_UTF8_ERR3   Missing 3 bytes at the end of the string\nPCRE2_ERROR_UTF8_ERR4   Missing 4 bytes at the end of the string\nPCRE2_ERROR_UTF8_ERR5   Missing 5 bytes at the end of the string\nPCRE2_ERROR_UTF8_ERR6   2nd-byte's two top bits are not 0x80\nPCRE2_ERROR_UTF8_ERR7   3rd-byte's two top bits are not 0x80\nPCRE2_ERROR_UTF8_ERR8   4th-byte's two top bits are not 0x80\nPCRE2_ERROR_UTF8_ERR9   5th-byte's two top bits are not 0x80\nPCRE2_ERROR_UTF8_ERR10  6th-byte's two top bits are not 0x80\nPCRE2_ERROR_UTF8_ERR11  5-byte character is not permitted by RFC 3629\nPCRE2_ERROR_UTF8_ERR12  6-byte character is not permitted by RFC 3629\nPCRE2_ERROR_UTF8_ERR13  4-byte character with value > 0x10ffff is not permitted\nPCRE2_ERROR_UTF8_ERR14  3-byte character with value 0xd800-0xdfff is not permitted\nPCRE2_ERROR_UTF8_ERR15  Overlong 2-byte sequence\nPCRE2_ERROR_UTF8_ERR16  Overlong 3-byte sequence\nPCRE2_ERROR_UTF8_ERR17  Overlong 4-byte sequence\nPCRE2_ERROR_UTF8_ERR18  Overlong 5-byte sequence (won't ever occur)\nPCRE2_ERROR_UTF8_ERR19  Overlong 6-byte sequence (won't ever occur)\nPCRE2_ERROR_UTF8_ERR20  Isolated 0x80 byte (not within UTF-8 character)\nPCRE2_ERROR_UTF8_ERR21  Byte with the illegal value 0xfe or 0xff\n*/\n\nfor (p = string; length > 0; p++)\n  {\n  uint32_t ab, d;\n\n  c = *p;\n  length--;\n\n  if (c < 128) continue;                /* ASCII character */\n\n  if (c < 0xc0)                         /* Isolated 10xx xxxx byte */\n    {\n    *erroroffset = (PCRE2_SIZE)(p - string);\n    return PCRE2_ERROR_UTF8_ERR20;\n    }\n\n  if (c >= 0xfe)                        /* Invalid 0xfe or 0xff bytes */\n    {\n    *erroroffset = (PCRE2_SIZE)(p - string);\n    return PCRE2_ERROR_UTF8_ERR21;\n    }\n\n  ab = PRIV(utf8_table4)[c & 0x3f];     /* Number of additional bytes (1-5) */\n  if (length < ab)                      /* Missing bytes */\n    {\n    *erroroffset = (PCRE2_SIZE)(p - string);\n    switch(ab - length)\n      {\n      case 1: return PCRE2_ERROR_UTF8_ERR1;\n      case 2: return PCRE2_ERROR_UTF8_ERR2;\n      case 3: return PCRE2_ERROR_UTF8_ERR3;\n      case 4: return PCRE2_ERROR_UTF8_ERR4;\n      case 5: return PCRE2_ERROR_UTF8_ERR5;\n      }\n    }\n  length -= ab;                         /* Length remaining */\n\n  /* Check top bits in the second byte */\n\n  if (((d = *(++p)) & 0xc0) != 0x80)\n    {\n    *erroroffset = (PCRE2_SIZE)(p - string) - 1;\n    return PCRE2_ERROR_UTF8_ERR6;\n    }\n\n  /* For each length, check that the remaining bytes start with the 0x80 bit\n  set and not the 0x40 bit. Then check for an overlong sequence, and for the\n  excluded range 0xd800 to 0xdfff. */\n\n  switch (ab)\n    {\n    /* 2-byte character. No further bytes to check for 0x80. Check first byte\n    for for xx00 000x (overlong sequence). */\n\n    case 1: if ((c & 0x3e) == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 1;\n      return PCRE2_ERROR_UTF8_ERR15;\n      }\n    break;\n\n    /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes\n      for 1110 0000, xx0x xxxx (overlong sequence) or\n          1110 1101, 1010 xxxx (0xd800 - 0xdfff) */\n\n    case 2:\n    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR7;\n      }\n    if (c == 0xe0 && (d & 0x20) == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR16;\n      }\n    if (c == 0xed && d >= 0xa0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR14;\n      }\n    break;\n\n    /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2\n       bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a\n       character greater than 0x0010ffff (f4 8f bf bf) */\n\n    case 3:\n    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR7;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 3;\n      return PCRE2_ERROR_UTF8_ERR8;\n      }\n    if (c == 0xf0 && (d & 0x30) == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 3;\n      return PCRE2_ERROR_UTF8_ERR17;\n      }\n    if (c > 0xf4 || (c == 0xf4 && d > 0x8f))\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 3;\n      return PCRE2_ERROR_UTF8_ERR13;\n      }\n    break;\n\n    /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be\n    rejected by the length test below. However, we do the appropriate tests\n    here so that overlong sequences get diagnosed, and also in case there is\n    ever an option for handling these larger code points. */\n\n    /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for\n    1111 1000, xx00 0xxx */\n\n    case 4:\n    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR7;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 3;\n      return PCRE2_ERROR_UTF8_ERR8;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Fifth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 4;\n      return PCRE2_ERROR_UTF8_ERR9;\n      }\n    if (c == 0xf8 && (d & 0x38) == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 4;\n      return PCRE2_ERROR_UTF8_ERR18;\n      }\n    break;\n\n    /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for\n    1111 1100, xx00 00xx. */\n\n    case 5:\n    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 2;\n      return PCRE2_ERROR_UTF8_ERR7;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 3;\n      return PCRE2_ERROR_UTF8_ERR8;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Fifth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 4;\n      return PCRE2_ERROR_UTF8_ERR9;\n      }\n    if ((*(++p) & 0xc0) != 0x80)     /* Sixth byte */\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 5;\n      return PCRE2_ERROR_UTF8_ERR10;\n      }\n    if (c == 0xfc && (d & 0x3c) == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 5;\n      return PCRE2_ERROR_UTF8_ERR19;\n      }\n    break;\n    }\n\n  /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are\n  excluded by RFC 3629. The pointer p is currently at the last byte of the\n  character. */\n\n  if (ab > 3)\n    {\n    *erroroffset = (PCRE2_SIZE)(p - string) - ab;\n    return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12;\n    }\n  }\nreturn 0;\n\n\n/* ----------------- Check a UTF-16 string ----------------- */\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n\n/* There's not so much work, nor so many errors, for UTF-16.\nPCRE2_ERROR_UTF16_ERR1  Missing low surrogate at the end of the string\nPCRE2_ERROR_UTF16_ERR2  Invalid low surrogate\nPCRE2_ERROR_UTF16_ERR3  Isolated low surrogate\n*/\n\nfor (p = string; length > 0; p++)\n  {\n  c = *p;\n  length--;\n\n  if ((c & 0xf800) != 0xd800)\n    {\n    /* Normal UTF-16 code point. Neither high nor low surrogate. */\n    }\n  else if ((c & 0x0400) == 0)\n    {\n    /* High surrogate. Must be a followed by a low surrogate. */\n    if (length == 0)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string);\n      return PCRE2_ERROR_UTF16_ERR1;\n      }\n    p++;\n    length--;\n    if ((*p & 0xfc00) != 0xdc00)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string) - 1;\n      return PCRE2_ERROR_UTF16_ERR2;\n      }\n    }\n  else\n    {\n    /* Isolated low surrogate. Always an error. */\n    *erroroffset = (PCRE2_SIZE)(p - string);\n    return PCRE2_ERROR_UTF16_ERR3;\n    }\n  }\nreturn 0;\n\n\n\n/* ----------------- Check a UTF-32 string ----------------- */\n\n#else\n\n/* There is very little to do for a UTF-32 string.\nPCRE2_ERROR_UTF32_ERR1  Surrogate character\nPCRE2_ERROR_UTF32_ERR2  Character > 0x10ffff\n*/\n\nfor (p = string; length > 0; length--, p++)\n  {\n  c = *p;\n  if ((c & 0xfffff800u) != 0xd800u)\n    {\n    /* Normal UTF-32 code point. Neither high nor low surrogate. */\n    if (c > 0x10ffffu)\n      {\n      *erroroffset = (PCRE2_SIZE)(p - string);\n      return PCRE2_ERROR_UTF32_ERR2;\n      }\n    }\n  else\n    {\n    /* A surrogate */\n    *erroroffset = (PCRE2_SIZE)(p - string);\n    return PCRE2_ERROR_UTF32_ERR1;\n    }\n  }\nreturn 0;\n#endif  /* CODE_UNIT_WIDTH */\n}\n#endif  /* SUPPORT_UNICODE */\n\n/* End of pcre2_valid_utf.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2_xclass.c",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains two internal functions that are used to match\nOP_XCLASS and OP_ECLASS. It is used by pcre2_auto_possessify() and by both\npcre2_match() and pcre2_dfa_match(). */\n\n\n#include \"pcre2_internal.h\"\n\n\n\n/*************************************************\n*       Match character against an XCLASS        *\n*************************************************/\n\n/* This function is called to match a character against an extended class that\nmight contain codepoints above 255 and/or Unicode properties.\n\nArguments:\n  c           the character\n  data        points to the flag code unit of the XCLASS data\n  utf         TRUE if in UTF mode\n\nReturns:      TRUE if character matches, else FALSE\n*/\n\nBOOL\nPRIV(xclass)(uint32_t c, PCRE2_SPTR data, const uint8_t *char_lists_end, BOOL utf)\n{\n/* Update PRIV(update_classbits) when this function is changed. */\nPCRE2_UCHAR t;\nBOOL not_negated = (*data & XCL_NOT) == 0;\nuint32_t type, max_index, min_index, value;\nconst uint8_t *next_char;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */\nutf = TRUE;\n#endif\n\n/* Code points < 256 are matched against a bitmap, if one is present. */\n\nif ((*data++ & XCL_MAP) != 0)\n  {\n  if (c < 256)\n    return (((const uint8_t *)data)[c/8] & (1u << (c&7))) != 0;\n  /* Skip bitmap. */\n  data += 32 / sizeof(PCRE2_UCHAR);\n  }\n\n/* Match against the list of Unicode properties. We won't ever\nencounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */\n#ifdef SUPPORT_UNICODE\nif (*data == XCL_PROP || *data == XCL_NOTPROP)\n  {\n  /* The UCD record is the same for all properties. */\n  const ucd_record *prop = GET_UCD(c);\n\n  do\n    {\n    int chartype;\n    BOOL isprop = (*data++) == XCL_PROP;\n    BOOL ok;\n\n    switch(*data)\n      {\n      case PT_LAMP:\n      chartype = prop->chartype;\n      if ((chartype == ucp_Lu || chartype == ucp_Ll ||\n           chartype == ucp_Lt) == isprop) return not_negated;\n      break;\n\n      case PT_GC:\n      if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)\n        return not_negated;\n      break;\n\n      case PT_PC:\n      if ((data[1] == prop->chartype) == isprop) return not_negated;\n      break;\n\n      case PT_SC:\n      if ((data[1] == prop->script) == isprop) return not_negated;\n      break;\n\n      case PT_SCX:\n      ok = (data[1] == prop->script ||\n            MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), data[1]) != 0);\n      if (ok == isprop) return not_negated;\n      break;\n\n      case PT_ALNUM:\n      chartype = prop->chartype;\n      if ((PRIV(ucp_gentype)[chartype] == ucp_L ||\n           PRIV(ucp_gentype)[chartype] == ucp_N) == isprop)\n        return not_negated;\n      break;\n\n      /* Perl space used to exclude VT, but from Perl 5.18 it is included,\n      which means that Perl space and POSIX space are now identical. PCRE\n      was changed at release 8.34. */\n\n      case PT_SPACE:    /* Perl space */\n      case PT_PXSPACE:  /* POSIX space */\n      switch(c)\n        {\n        HSPACE_CASES:\n        VSPACE_CASES:\n        if (isprop) return not_negated;\n        break;\n\n        default:\n        if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)\n          return not_negated;\n        break;\n        }\n      break;\n\n      case PT_WORD:\n      chartype = prop->chartype;\n      if ((PRIV(ucp_gentype)[chartype] == ucp_L ||\n           PRIV(ucp_gentype)[chartype] == ucp_N ||\n           chartype == ucp_Mn || chartype == ucp_Pc) == isprop)\n        return not_negated;\n      break;\n\n      case PT_UCNC:\n      if (c < 0xa0)\n        {\n        if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||\n             c == CHAR_GRAVE_ACCENT) == isprop)\n          return not_negated;\n        }\n      else\n        {\n        if ((c < 0xd800 || c > 0xdfff) == isprop)\n          return not_negated;\n        }\n      break;\n\n      case PT_BIDICL:\n      if ((UCD_BIDICLASS_PROP(prop) == data[1]) == isprop)\n        return not_negated;\n      break;\n\n      case PT_BOOL:\n      ok = MAPBIT(PRIV(ucd_boolprop_sets) +\n        UCD_BPROPS_PROP(prop), data[1]) != 0;\n      if (ok == isprop) return not_negated;\n      break;\n\n      /* The following three properties can occur only in an XCLASS, as there\n      is no \\p or \\P coding for them. */\n\n      /* Graphic character. Implement this as not Z (space or separator) and\n      not C (other), except for Cf (format) with a few exceptions. This seems\n      to be what Perl does. The exceptional characters are:\n\n      U+061C           Arabic Letter Mark\n      U+180E           Mongolian Vowel Separator\n      U+2066 - U+2069  Various \"isolate\"s\n      */\n\n      case PT_PXGRAPH:\n      chartype = prop->chartype;\n      if ((PRIV(ucp_gentype)[chartype] != ucp_Z &&\n            (PRIV(ucp_gentype)[chartype] != ucp_C ||\n              (chartype == ucp_Cf &&\n                c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))\n         )) == isprop)\n        return not_negated;\n      break;\n\n      /* Printable character: same as graphic, with the addition of Zs, i.e.\n      not Zl and not Zp, and U+180E. */\n\n      case PT_PXPRINT:\n      chartype = prop->chartype;\n      if ((chartype != ucp_Zl &&\n           chartype != ucp_Zp &&\n            (PRIV(ucp_gentype)[chartype] != ucp_C ||\n              (chartype == ucp_Cf &&\n                c != 0x061c && (c < 0x2066 || c > 0x2069))\n         )) == isprop)\n        return not_negated;\n      break;\n\n      /* Punctuation: all Unicode punctuation, plus ASCII characters that\n      Unicode treats as symbols rather than punctuation, for Perl\n      compatibility (these are $+<=>^`|~). */\n\n      case PT_PXPUNCT:\n      chartype = prop->chartype;\n      if ((PRIV(ucp_gentype)[chartype] == ucp_P ||\n            (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop)\n        return not_negated;\n      break;\n\n      /* Perl has two sets of hex digits */\n\n      case PT_PXXDIGIT:\n      if (((c >= CHAR_0 && c <= CHAR_9) ||\n           (c >= CHAR_A && c <= CHAR_F) ||\n           (c >= CHAR_a && c <= CHAR_f) ||\n           (c >= 0xff10 && c <= 0xff19) ||  /* Fullwidth digits */\n           (c >= 0xff21 && c <= 0xff26) ||  /* Fullwidth letters */\n           (c >= 0xff41 && c <= 0xff46)) == isprop)\n        return not_negated;\n      break;\n\n      /* This should never occur, but compilers may mutter if there is no\n      default. */\n\n      /* LCOV_EXCL_START */\n      default:\n      PCRE2_DEBUG_UNREACHABLE();\n      return FALSE;\n      /* LCOV_EXCL_STOP */\n      }\n\n    data += 2;\n    }\n  while (*data == XCL_PROP || *data == XCL_NOTPROP);\n  }\n#else\n  (void)utf;  /* Avoid compiler warning */\n#endif  /* SUPPORT_UNICODE */\n\n/* Match against large chars or ranges that end with a large char. */\nif (*data < XCL_LIST)\n  {\n  while ((t = *data++) != XCL_END)\n    {\n    uint32_t x, y;\n\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      GETCHARINC(x, data); /* macro generates multiple statements */\n      }\n    else\n#endif\n      x = *data++;\n\n    if (t == XCL_SINGLE)\n      {\n      /* Since character ranges follow the properties, and they are\n      sorted, early return is possible for all characters <= x. */\n      if (c <= x) return (c == x) ? not_negated : !not_negated;\n      continue;\n      }\n\n    PCRE2_ASSERT(t == XCL_RANGE);\n#ifdef SUPPORT_UNICODE\n    if (utf)\n      {\n      GETCHARINC(y, data); /* macro generates multiple statements */\n      }\n    else\n#endif\n      y = *data++;\n\n    /* Since character ranges follow the properties, and they are\n    sorted, early return is possible for all characters <= y. */\n    if (c <= y) return (c >= x) ? not_negated : !not_negated;\n    }\n\n  return !not_negated;   /* char did not match */\n  }\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\ntype = (uint32_t)(data[0] << 8) | data[1];\ndata += 2;\n#else\ntype = data[0];\ndata++;\n#endif  /* CODE_UNIT_WIDTH */\n\n/* Align characters. */\nnext_char = char_lists_end - (GET(data, 0) << 1);\ntype &= XCL_TYPE_MASK;\n\n/* Alignment check. */\nPCRE2_ASSERT(((uintptr_t)next_char & 0x1) == 0);\n\nif (c >= XCL_CHAR_LIST_HIGH_16_START)\n  {\n  max_index = type & XCL_ITEM_COUNT_MASK;\n  if (max_index == XCL_ITEM_COUNT_MASK)\n    {\n    max_index = *(const uint16_t*)next_char;\n    PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK);\n    next_char += 2;\n    }\n\n  next_char += max_index << 1;\n  type >>= XCL_TYPE_BIT_LEN;\n  }\n\nif (c < XCL_CHAR_LIST_LOW_32_START)\n  {\n  max_index = type & XCL_ITEM_COUNT_MASK;\n\n  c = (uint16_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END);\n\n  if (max_index == XCL_ITEM_COUNT_MASK)\n    {\n    max_index = *(const uint16_t*)next_char;\n    PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK);\n    next_char += 2;\n    }\n\n  if (max_index == 0 || c < *(const uint16_t*)next_char)\n    return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated;\n\n  min_index = 0;\n  value = ((const uint16_t*)next_char)[--max_index];\n  if (c >= value)\n    return (value == c || (value & XCL_CHAR_END) == 0) == not_negated;\n\n  max_index--;\n\n  /* Binary search of a range. */\n  while (TRUE)\n    {\n    uint32_t mid_index = (min_index + max_index) >> 1;\n    value = ((const uint16_t*)next_char)[mid_index];\n\n    if (c < value)\n      max_index = mid_index - 1;\n    else if (((const uint16_t*)next_char)[mid_index + 1] <= c)\n      min_index = mid_index + 1;\n    else\n      return (value == c || (value & XCL_CHAR_END) == 0) == not_negated;\n    }\n  }\n\n/* Skip the 16 bit ranges. */\nmax_index = type & XCL_ITEM_COUNT_MASK;\nif (max_index == XCL_ITEM_COUNT_MASK)\n  {\n  max_index = *(const uint16_t*)next_char;\n  PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK);\n  next_char += 2;\n  }\n\nnext_char += (max_index << 1);\ntype >>= XCL_TYPE_BIT_LEN;\n\n/* Alignment check. */\nPCRE2_ASSERT(((uintptr_t)next_char & 0x3) == 0);\n\nmax_index = type & XCL_ITEM_COUNT_MASK;\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\nif (c >= XCL_CHAR_LIST_HIGH_32_START)\n  {\n  if (max_index == XCL_ITEM_COUNT_MASK)\n    {\n    max_index = *(const uint32_t*)next_char;\n    PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK);\n    next_char += 4;\n    }\n\n  next_char += max_index << 2;\n  type >>= XCL_TYPE_BIT_LEN;\n  max_index = type & XCL_ITEM_COUNT_MASK;\n  }\n#endif\n\nc = (uint32_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END);\n\nif (max_index == XCL_ITEM_COUNT_MASK)\n  {\n  max_index = *(const uint32_t*)next_char;\n  next_char += 4;\n  }\n\nif (max_index == 0 || c < *(const uint32_t*)next_char)\n  return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated;\n\nmin_index = 0;\nvalue = ((const uint32_t*)next_char)[--max_index];\nif (c >= value)\n  return (value == c || (value & XCL_CHAR_END) == 0) == not_negated;\n\nmax_index--;\n\n/* Binary search of a range. */\nwhile (TRUE)\n  {\n  uint32_t mid_index = (min_index + max_index) >> 1;\n  value = ((const uint32_t*)next_char)[mid_index];\n\n  if (c < value)\n    max_index = mid_index - 1;\n  else if (((const uint32_t*)next_char)[mid_index + 1] <= c)\n    min_index = mid_index + 1;\n  else\n    return (value == c || (value & XCL_CHAR_END) == 0) == not_negated;\n  }\n}\n\n\n\n/*************************************************\n*       Match character against an ECLASS        *\n*************************************************/\n\n/* This function is called to match a character against an extended class\nused for describing characters using boolean operations on sets.\n\nArguments:\n  c           the character\n  data_start  points to the start of the ECLASS data\n  data_end    points one-past-the-last of the ECLASS data\n  utf         TRUE if in UTF mode\n\nReturns:      TRUE if character matches, else FALSE\n*/\n\nBOOL\nPRIV(eclass)(uint32_t c, PCRE2_SPTR data_start, PCRE2_SPTR data_end,\n  const uint8_t *char_lists_end, BOOL utf)\n{\nPCRE2_SPTR ptr = data_start;\nPCRE2_UCHAR flags;\nuint32_t stack = 0;\nint stack_depth = 0;\n\nPCRE2_ASSERT(data_start < data_end);\nflags = *ptr++;\nPCRE2_ASSERT((flags & ECL_MAP) == 0 ||\n             (data_end - ptr) >= 32 / (int)sizeof(PCRE2_UCHAR));\n\n/* Code points < 256 are matched against a bitmap, if one is present.\nOtherwise all codepoints are checked later. */\n\nif ((flags & ECL_MAP) != 0)\n  {\n  if (c < 256)\n    return (((const uint8_t *)ptr)[c/8] & (1u << (c&7))) != 0;\n\n  /* Skip the bitmap. */\n  ptr += 32 / sizeof(PCRE2_UCHAR);\n  }\n\n/* Do a little loop, until we reach the end of the ECLASS. */\nwhile (ptr < data_end)\n  {\n  switch (*ptr)\n    {\n    case ECL_AND:\n    ++ptr;\n    stack = (stack >> 1) & (stack | ~(uint32_t)1u);\n    PCRE2_ASSERT(stack_depth >= 2);\n    --stack_depth;\n    break;\n\n    case ECL_OR:\n    ++ptr;\n    stack = (stack >> 1) | (stack & (uint32_t)1u);\n    PCRE2_ASSERT(stack_depth >= 2);\n    --stack_depth;\n    break;\n\n    case ECL_XOR:\n    ++ptr;\n    stack = (stack >> 1) ^ (stack & (uint32_t)1u);\n    PCRE2_ASSERT(stack_depth >= 2);\n    --stack_depth;\n    break;\n\n    case ECL_NOT:\n    ++ptr;\n    stack ^= (uint32_t)1u;\n    PCRE2_ASSERT(stack_depth >= 1);\n    break;\n\n    case ECL_XCLASS:\n      {\n      uint32_t matched = PRIV(xclass)(c, ptr + 1 + LINK_SIZE, char_lists_end, utf);\n\n      ptr += GET(ptr, 1);\n      stack = (stack << 1) | matched;\n      ++stack_depth;\n      break;\n      }\n\n    /* This should never occur, but compilers may mutter if there is no\n    default. */\n\n    /* LCOV_EXCL_START */\n    default:\n    PCRE2_DEBUG_UNREACHABLE();\n    return FALSE;\n    /* LCOV_EXCL_STOP */\n    }\n  }\n\nPCRE2_ASSERT(stack_depth == 1);\n(void)stack_depth;  /* Ignore unused variable, if assertions are disabled. */\n\n/* The final bit left on the stack now holds the match result. */\nreturn (stack & 1u) != 0;\n}\n\n/* End of pcre2_xclass.c */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2posix.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language. This is\nthe public header file to be #included by applications that call PCRE2 via the\nPOSIX wrapper interface.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2023 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n#ifndef PCRE2POSIX_H_IDEMPOTENT_GUARD\n#define PCRE2POSIX_H_IDEMPOTENT_GUARD\n\n/* Have to include stdlib.h in order to ensure that size_t is defined. */\n\n#include <stdlib.h>\n\n/* Allow for C++ users */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Options, mostly defined by POSIX, but with some extras. */\n\n#define REG_ICASE     0x0001  /* Maps to PCRE2_CASELESS */\n#define REG_NEWLINE   0x0002  /* Maps to PCRE2_MULTILINE */\n#define REG_NOTBOL    0x0004  /* Maps to PCRE2_NOTBOL */\n#define REG_NOTEOL    0x0008  /* Maps to PCRE2_NOTEOL */\n#define REG_DOTALL    0x0010  /* NOT defined by POSIX; maps to PCRE2_DOTALL */\n#define REG_NOSUB     0x0020  /* Do not report what was matched */\n#define REG_UTF       0x0040  /* NOT defined by POSIX; maps to PCRE2_UTF */\n#define REG_STARTEND  0x0080  /* BSD feature: pass subject string by so,eo */\n#define REG_NOTEMPTY  0x0100  /* NOT defined by POSIX; maps to PCRE2_NOTEMPTY */\n#define REG_UNGREEDY  0x0200  /* NOT defined by POSIX; maps to PCRE2_UNGREEDY */\n#define REG_UCP       0x0400  /* NOT defined by POSIX; maps to PCRE2_UCP */\n#define REG_PEND      0x0800  /* GNU feature: pass end pattern by re_endp */\n#define REG_NOSPEC    0x1000  /* Maps to PCRE2_LITERAL */\n\n/* This is not used by PCRE2, but by defining it we make it easier\nto slot PCRE2 into existing programs that make POSIX calls. */\n\n#define REG_EXTENDED  0\n\n/* Error values. Not all these are relevant or used by the wrapper. */\n\nenum {\n  REG_ASSERT = 1,  /* internal error ? */\n  REG_BADBR,       /* invalid repeat counts in {} */\n  REG_BADPAT,      /* pattern error */\n  REG_BADRPT,      /* ? * + invalid */\n  REG_EBRACE,      /* unbalanced {} */\n  REG_EBRACK,      /* unbalanced [] */\n  REG_ECOLLATE,    /* collation error - not relevant */\n  REG_ECTYPE,      /* bad class */\n  REG_EESCAPE,     /* bad escape sequence */\n  REG_EMPTY,       /* empty expression */\n  REG_EPAREN,      /* unbalanced () */\n  REG_ERANGE,      /* bad range inside [] */\n  REG_ESIZE,       /* expression too big */\n  REG_ESPACE,      /* failed to get memory */\n  REG_ESUBREG,     /* bad back reference */\n  REG_INVARG,      /* bad argument */\n  REG_NOMATCH      /* match failed */\n};\n\n\n/* The structure representing a compiled regular expression. It is also used\nfor passing the pattern end pointer when REG_PEND is set. */\n\ntypedef struct {\n  void *re_pcre2_code;\n  void *re_match_data;\n  const char *re_endp;\n  size_t re_nsub;\n  size_t re_erroffset;\n  int re_cflags;\n} regex_t;\n\n/* The structure in which a captured offset is returned. */\n\ntypedef int regoff_t;\n\ntypedef struct {\n  regoff_t rm_so;\n  regoff_t rm_eo;\n} regmatch_t;\n\n/* When an application links to a PCRE2 DLL in Windows, the symbols that are\nimported have to be identified as such. When building PCRE2, the appropriate\nexport settings are needed, and are set in pcre2posix.c before including this\nfile. So, we don't change existing definitions of PCRE2POSIX_EXP_DECL.\n\nBy default, we use the standard \"extern\" declarations. */\n\n#ifndef PCRE2POSIX_EXP_DECL\n#  if defined(_WIN32) && defined(PCRE2POSIX_SHARED)\n#    define PCRE2POSIX_EXP_DECL  extern __declspec(dllimport)\n#  elif defined __cplusplus\n#    define PCRE2POSIX_EXP_DECL  extern \"C\"\n#  else\n#    define PCRE2POSIX_EXP_DECL  extern\n#  endif\n#endif\n\n/* When compiling with the MSVC compiler, it is sometimes necessary to include\na \"calling convention\" before exported function names. For example:\n\n  void __cdecl function(....)\n\nmight be needed. In order to make this easy, all the exported functions have\nPCRE2_CALL_CONVENTION just before their names.\n\nPCRE2 normally uses the platform's standard calling convention, so this should\nnot be set unless you know you need it. */\n\n#ifndef PCRE2_CALL_CONVENTION\n#define PCRE2_CALL_CONVENTION\n#endif\n\n/* The functions. The actual code is in functions with pcre2_xxx names for\nuniqueness. POSIX names are provided as macros for API compatibility with POSIX\nregex functions. It's done this way to ensure to they are always linked from\nthe PCRE2 library and not by accident from elsewhere (regex_t differs in size\nelsewhere). */\n\nPCRE2POSIX_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_regcomp(regex_t *, const char *, int);\nPCRE2POSIX_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_regexec(const regex_t *, const char *, size_t,\n                     regmatch_t *, int);\nPCRE2POSIX_EXP_DECL size_t PCRE2_CALL_CONVENTION pcre2_regerror(int, const regex_t *, char *, size_t);\nPCRE2POSIX_EXP_DECL void PCRE2_CALL_CONVENTION pcre2_regfree(regex_t *);\n\n#define regcomp  pcre2_regcomp\n#define regexec  pcre2_regexec\n#define regerror pcre2_regerror\n#define regfree  pcre2_regfree\n\n/* Debian had a patch that used different names. These are now here to save\nthem having to maintain their own patch, but are not documented by PCRE2. */\n\n#define PCRE2regcomp  pcre2_regcomp\n#define PCRE2regexec  pcre2_regexec\n#define PCRE2regerror pcre2_regerror\n#define PCRE2regfree  pcre2_regfree\n\n#ifdef __cplusplus\n}   /* extern \"C\" */\n#endif\n\n#endif /* PCRE2POSIX_H_IDEMPOTENT_GUARD */\n\n/* End of pcre2posix.h */\n"
  },
  {
    "path": "vendor/core/vendor/pcre2/src/pcre2test_inc.h",
    "content": "/*************************************************\n*      Perl-Compatible Regular Expressions       *\n*************************************************/\n\n/* PCRE is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\n                       Written by Philip Hazel\n     Original API code Copyright (c) 1997-2012 University of Cambridge\n          New API code Copyright (c) 2016-2024 University of Cambridge\n\n-----------------------------------------------------------------------------\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of its\n      contributors may be used to endorse or promote products derived from\n      this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n-----------------------------------------------------------------------------\n*/\n\n\n/* This module contains the mode-dependent code which is used by pcre2test.c.\nIt is #included in pcre2test.c at each supported code unit width, with\nPCRE2_SUFFIX set appropriately, just like the functions that comprise the\nlibrary. */\n\n\n/* ------- Macros for hiding the bit width of this file's members ---------- */\n\n#define pbuffer               PCRE2_SUFFIX(pbuffer)\n#define pbuffer_size          G(pbuffer,_size)\n\n#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16\n#define utf_to_ord            G(G(utf,PCRE2_CODE_UNIT_WIDTH),_to_ord)\n#endif\n\n#define compiled_code         PCRE2_SUFFIX(compiled_code_)\n#define general_context       PCRE2_SUFFIX(general_context_)\n#define general_context_copy  PCRE2_SUFFIX(general_context_copy_)\n#define pat_context           PCRE2_SUFFIX(pat_context_)\n#define default_pat_context   PCRE2_SUFFIX(default_pat_context_)\n#define con_context           PCRE2_SUFFIX(con_context_)\n#define default_con_context   PCRE2_SUFFIX(default_con_context_)\n#define dat_context           PCRE2_SUFFIX(dat_context_)\n#define default_dat_context   PCRE2_SUFFIX(default_dat_context_)\n#define match_data            PCRE2_SUFFIX(match_data_)\n#define jit_stack             PCRE2_SUFFIX(jit_stack_)\n#define jit_stack_size        PCRE2_SUFFIX(jit_stack_size_)\n#define patstack              PCRE2_SUFFIX(patstack_)\n#define patstacknext          PCRE2_SUFFIX(patstacknext_)\n#define rep_in_buffer         PCRE2_SUFFIX(rep_in_buffer_)\n#define rep_in_buffer_size    PCRE2_SUFFIX(rep_in_buffer_size_)\n#define rep_out_buffer        PCRE2_SUFFIX(rep_out_buffer_)\n#define rep_out_buffer_size   PCRE2_SUFFIX(rep_out_buffer_size_)\n\n#define jit_callback                      PCRE2_SUFFIX(jit_callback_)\n#define pcre2_strcmp_c8                   PCRE2_SUFFIX(pcre2_strcmp_c8_)\n#define pcre2_strlen                      PCRE2_SUFFIX(pcre2_strlen_)\n#define pchars                            PCRE2_SUFFIX(pchars_)\n#define ptrunc                            PCRE2_SUFFIX(ptrunc_)\n#define config_str                        PCRE2_SUFFIX(config_str_)\n#define check_modifier                    PCRE2_SUFFIX(check_modifier_)\n#define decode_modifiers                  PCRE2_SUFFIX(decode_modifiers_)\n#define pattern_info                      PCRE2_SUFFIX(pattern_info_)\n#define show_memory_info                  PCRE2_SUFFIX(show_memory_info_)\n#define show_framesize                    PCRE2_SUFFIX(show_framesize_)\n#define show_heapframes_size              PCRE2_SUFFIX(show_heapframes_size_)\n#define print_error_message_file          PCRE2_SUFFIX(print_error_message_file_)\n#define print_error_message               PCRE2_SUFFIX(print_error_message_)\n#define callout_enumerate_function        PCRE2_SUFFIX(callout_enumerate_function_)\n#define callout_enumerate_function_void   PCRE2_SUFFIX(callout_enumerate_function_void_)\n#define callout_enumerate_function_fail   PCRE2_SUFFIX(callout_enumerate_function_fail_)\n#define show_pattern_info                 PCRE2_SUFFIX(show_pattern_info_)\n#define serial_error                      PCRE2_SUFFIX(serial_error_)\n#define process_command                   PCRE2_SUFFIX(process_command_)\n#define process_pattern                   PCRE2_SUFFIX(process_pattern_)\n#define have_active_pattern               PCRE2_SUFFIX(have_active_pattern_)\n#define free_active_pattern               PCRE2_SUFFIX(free_active_pattern_)\n#define check_match_limit                 PCRE2_SUFFIX(check_match_limit_)\n#define substitute_callout_function       PCRE2_SUFFIX(substitute_callout_function_)\n#define substitute_case_callout_function  PCRE2_SUFFIX(substitute_case_callout_function_)\n#define callout_function                  PCRE2_SUFFIX(callout_function_)\n#define copy_and_get                      PCRE2_SUFFIX(copy_and_get_)\n#define copy_substitute_string            PCRE2_SUFFIX(copy_substitute_string_)\n#define process_data                      PCRE2_SUFFIX(process_data_)\n#define init_globals                      PCRE2_SUFFIX(init_globals_)\n#define free_globals                      PCRE2_SUFFIX(free_globals_)\n#define unittest                          PCRE2_SUFFIX(unittest_)\n\n\n/* ---------------------- Mode-dependent variables ------------------------- */\n\nstatic pcre2_code             *compiled_code = NULL;\nstatic pcre2_general_context  *general_context = NULL, *general_context_copy = NULL;\nstatic pcre2_compile_context  *pat_context = NULL, *default_pat_context = NULL;\nstatic pcre2_convert_context  *con_context = NULL, *default_con_context = NULL;\nstatic pcre2_match_context    *dat_context = NULL, *default_dat_context = NULL;\nstatic pcre2_match_data       *match_data = NULL;\n\nstatic pcre2_jit_stack *jit_stack = NULL;\nstatic size_t           jit_stack_size = 0;\n\nstatic pcre2_code *patstack[PATSTACKSIZE];\nstatic int         patstacknext = 0;\n\nstatic PCRE2_UCHAR *rep_in_buffer = NULL;\nstatic size_t       rep_in_buffer_size = REPLACE_MODSIZE;    /* Code units */\nstatic PCRE2_UCHAR *rep_out_buffer = NULL;\nstatic size_t       rep_out_buffer_size = REPLACE_BUFFSIZE;  /* Code units */\n\n\n\n/*************************************************\n*         JIT memory callback                    *\n*************************************************/\n\nstatic pcre2_jit_stack*\njit_callback(void *arg)\n{\njit_was_used = TRUE;\nreturn (pcre2_jit_stack *)arg;\n}\n\n\n\n/*************************************************\n*  Compare zero-terminated PCRE2 & 8-bit strings *\n*************************************************/\n\nstatic int\npcre2_strcmp_c8(PCRE2_SPTR str1, const char *str2)\n{\nPCRE2_UCHAR c1, c2;\nwhile (*str1 != '\\0' || *str2 != '\\0')\n  {\n  c1 = *str1++;\n  c2 = *str2++;\n  if (c1 != c2) return ((c1 > c2) << 1) - 1;\n  }\nreturn 0;\n}\n\n\n\n/*************************************************\n*        Find the length of a PCRE2 string       *\n*************************************************/\n\nstatic size_t\npcre2_strlen(PCRE2_SPTR str)\n{\nsize_t c = 0;\nwhile (*str++ != 0) c++;\nreturn c;\n}\n\n\n\n/*************************************************\n*           Print character string               *\n*************************************************/\n\n/* Must handle Unicode strings in UTF mode. Yields number of characters printed.\nFor printing *MARK strings, a negative length is given, indicating that the\nlength is in the first code unit. If handed a NULL file, this function just\ncounts chars without printing (because pchar() does that). */\n\nstatic int pchars(int clr, PCRE2_SPTR p, ptrdiff_t length, BOOL utf, FILE *f)\n{\n#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16\nPCRE2_SPTR end;\nuint32_t c = 0;\nint yield = 0;\n\ncolour_begin(clr, f);\n\nif (length < 0) length = *p++;\nend = p + length;\nwhile (length-- > 0)\n  {\n  if (utf)\n    {\n    int rc = utf_to_ord(p, end, &c);\n    if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */\n      {\n      length -= rc - 1;\n      p += rc;\n      yield += pchar(c, utf, f);\n      continue;\n      }\n    }\n  c = *p++;\n  yield += pchar(c, utf, f);\n  }\n\ncolour_end(f);\nreturn yield;\n\n#else\nint yield = 0;\n\ncolour_begin(clr, f);\n\nif (length < 0) length = *p++;\nwhile (length-- > 0)\n  {\n  uint32_t c = *p++;\n  yield += pchar(c, utf, f);\n  }\n\ncolour_end(f);\nreturn yield;\n\n#endif\n}\n\n\n\n/*************************************************\n*        Print truncated character string        *\n*************************************************/\n\n/* Must handle Unicode strings in UTF mode. Passed the total input string, and\nthe offset to print from/to. If left is true, prints up to the offset,\ntruncated; otherwise prints from the offset to the right, truncated. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nstatic void ptrunc_8(int clr, PCRE2_SPTR p, size_t p_len, size_t offset,\n  BOOL left, BOOL utf, FILE *f)\n{\nPCRE2_SPTR start = p + offset;\nPCRE2_SPTR end = p + offset;\nsize_t printed = 0;\n\ncolour_begin(clr, f);\n\nif (left)\n  {\n  while (start > p && printed < 10)\n    {\n    printed++;\n    start--;\n    if (utf)\n      { while(start > p && (*start & 0xc0u) == 0x80u) start--; }\n    }\n  }\nelse\n  {\n  while (end < p + p_len && printed < 10)\n    {\n    printed++;\n    end++;\n    if (utf)\n      { while(end < p + p_len && (*end & 0xc0u) == 0x80u) end++; }\n    }\n  }\n\nif (left && start > p) fprintf(f, \"...\");\nfor (; start < end; start++) fprintf(f, \"%c\", CHAR_OUTPUT(*start));\nif (!left && end < p + p_len) fprintf(f, \"...\");\n\ncolour_end(f);\n}\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\nstatic void ptrunc_16(int clr, PCRE2_SPTR p, size_t p_len, size_t offset,\n  BOOL left, BOOL utf, FILE *f)\n{\nPCRE2_SPTR start = p + offset;\nPCRE2_SPTR end = p + offset;\nsize_t printed = 0;\n\ncolour_begin(clr, f);\n\nif (left)\n  {\n  while (start > p && printed < 10)\n    {\n    printed++;\n    start--;\n    if (utf)\n      { while(start > p && (*start & 0xfc00u) == 0xdc00u) start--; }\n    }\n  }\nelse\n  {\n  while (end < p + p_len && printed < 10)\n    {\n    printed++;\n    end++;\n    if (utf)\n      { while(end < p + p_len && (*end & 0xfc00u) == 0xdc00u) end++; }\n    }\n  }\n\nif (left && start > p) fprintf(f, \"...\");\nwhile (start < end)\n  {\n  uint32_t c;\n  int rc = utf16_to_ord(start, end, &c);\n  if (rc < 0) c = *start++;\n  else start += rc;\n  if (c > 0xff || (utf && c > 0x7f))\n    {\n    uint8_t u8buff[6];\n    int clen = ord_to_utf8(c, u8buff);\n    fprintf(f, \"%.*s\", clen, u8buff);\n    continue;\n    }\n  fputc((int)c, f);\n  }\nif (!left && end < p + p_len) fprintf(f, \"...\");\n\ncolour_end(f);\n}\n\n#elif PCRE2_CODE_UNIT_WIDTH == 32\nstatic void ptrunc_32(int clr, PCRE2_SPTR p, size_t p_len, size_t offset,\n  BOOL left, BOOL utf, FILE *f)\n{\nPCRE2_SPTR start = p + offset;\nPCRE2_SPTR end = p + offset;\n\ncolour_begin(clr, f);\n\nif (left)\n  {\n  start -= (offset > 10)? 10 : offset;\n  }\nelse\n  {\n  end += (p + p_len - end > 10)? 10 : p + p_len - end;\n  }\n\nif (left && start > p) fprintf(f, \"...\");\nwhile (start < end)\n  {\n  uint32_t c = *start++;\n  if (c > 0xff || (utf && c > 0x7f))\n    {\n    uint8_t u8buff[6];\n    int clen = ord_to_utf8(c, u8buff);\n    fprintf(f, \"%.*s\", clen, u8buff);\n    continue;\n    }\n  fputc((int)c, f);\n  }\nif (!left && end < p + p_len) fprintf(f, \"...\");\n\ncolour_end(f);\n}\n#endif\n\n#if PCRE2_CODE_UNIT_WIDTH == 16\n/*************************************************\n*           Convert string to 16-bit             *\n*************************************************/\n\n/* In UTF mode the input is always interpreted as a string of UTF-8 bytes using\nthe original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and\ncode values from 0 to 0x7fffffff. However, values greater than the later UTF\nlimit of 0x10ffff cause an error. In non-UTF mode the input is interpreted as\nUTF-8 if the utf8_input modifier is set, but an error is generated for values\ngreater than 0xffff.\n\nIf all the input bytes are ASCII, the space needed for a 16-bit string is\nexactly double the 8-bit size. Otherwise, the size needed for a 16-bit string\nis no more than double, because up to 0xffff uses no more than 3 bytes in UTF-8\nbut possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes\nin UTF-16. The result is always left in pbuffer16. Impose a minimum size to\nsave repeated re-sizing.\n\nNote that this function does not object to surrogate values. This is\ndeliberate; it makes it possible to construct UTF-16 strings that are invalid,\nfor the purpose of testing that they are correctly faulted.\n\nArguments:\n  p          points to a byte string\n  utf        true in UTF mode\n  lenptr     points to number of bytes in the string (excluding trailing zero)\n\nReturns:     0 on success, with the length updated to the number of 16-bit\n               data items used (excluding the trailing zero)\n             OR -1 if a UTF-8 string is malformed\n             OR -2 if a value > 0x10ffff is encountered in UTF mode\n             OR -3 if a value > 0xffff is encountered when not in UTF mode\n*/\n\nstatic int\nto16(uint8_t *p, int utf, PCRE2_SIZE *lenptr)\n{\nuint16_t *pp;\nPCRE2_SIZE len = *lenptr;\n\nif (pbuffer16_size < 2*len + 2)\n  {\n  if (pbuffer16 != NULL) free(pbuffer16);\n  pbuffer16_size = 2*len + 2;\n  if (pbuffer16_size < 4096) pbuffer16_size = 4096;\n  pbuffer16 = (uint16_t *)malloc(pbuffer16_size);\n  if (pbuffer16 == NULL)\n    {\n    cfprintf(clr_test_error, stderr, \"pcre2test: malloc(%\" SIZ_FORM \") failed for pbuffer16\\n\",\n      pbuffer16_size);\n    exit(1);\n    }\n  }\n\npp = pbuffer16;\nif (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)\n  {\n  for (; len > 0; len--) *pp++ = *p++;\n  }\n\nelse while (len > 0)\n  {\n  uint32_t c;\n  const uint8_t *end = p + len;\n  int chlen = utf8_to_ord(p, end, &c);\n  if (chlen <= 0) return -1;\n  if (!utf && c > 0xffff) return -3;\n  if (c > 0x10ffff) return -2;\n  p += chlen;\n  len -= chlen;\n  if (c < 0x10000) *pp++ = c; else\n    {\n    c -= 0x10000;\n    *pp++ = 0xd800 | (c >> 10);\n    *pp++ = 0xdc00 | (c & 0x3ff);\n    }\n  }\n\n*pp = 0;\n*lenptr = pp - pbuffer16;\nreturn 0;\n}\n#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */\n\n\n\n#if PCRE2_CODE_UNIT_WIDTH == 32\n/*************************************************\n*           Convert string to 32-bit             *\n*************************************************/\n\n/* In UTF mode the input is always interpreted as a string of UTF-8 bytes using\nthe original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and\ncode values from 0 to 0x7fffffff. However, values greater than the later UTF\nlimit of 0x10ffff cause an error.\n\nIn non-UTF mode the input is interpreted as UTF-8 if the utf8_input modifier\nis set, and no limit is imposed. There is special interpretation of the 0xff\nbyte (which is illegal in UTF-8) in this case: it causes the top bit of the\nnext character to be set. This provides a way of generating 32-bit characters\ngreater than 0x7fffffff.\n\nIf all the input bytes are ASCII, the space needed for a 32-bit string is\nexactly four times the 8-bit size. Otherwise, the size needed for a 32-bit\nstring is no more than four times, because the number of characters must be\nless than the number of bytes. The result is always left in pbuffer32. Impose a\nminimum size to save repeated re-sizing.\n\nNote that this function does not object to surrogate values. This is\ndeliberate; it makes it possible to construct UTF-32 strings that are invalid,\nfor the purpose of testing that they are correctly faulted.\n\nArguments:\n  p          points to a byte string\n  utf        true in UTF mode\n  lenptr     points to number of bytes in the string (excluding trailing zero)\n\nReturns:     0 on success, with the length updated to the number of 32-bit\n               data items used (excluding the trailing zero)\n             OR -1 if a UTF-8 string is malformed\n             OR -2 if a value > 0x10ffff is encountered in UTF mode\n*/\n\nstatic int\nto32(uint8_t *p, int utf, PCRE2_SIZE *lenptr)\n{\nuint32_t *pp;\nPCRE2_SIZE len = *lenptr;\n\nif (pbuffer32_size < 4*len + 4)\n  {\n  if (pbuffer32 != NULL) free(pbuffer32);\n  pbuffer32_size = 4*len + 4;\n  if (pbuffer32_size < 8192) pbuffer32_size = 8192;\n  pbuffer32 = (uint32_t *)malloc(pbuffer32_size);\n  if (pbuffer32 == NULL)\n    {\n    cfprintf(clr_test_error, stderr, \"pcre2test: malloc(%\" SIZ_FORM \") failed for pbuffer32\\n\",\n      pbuffer32_size);\n    exit(1);\n    }\n  }\n\npp = pbuffer32;\nif (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)\n  {\n  for (; len > 0; len--) *pp++ = *p++;\n  }\n\nelse while (len > 0)\n  {\n  int chlen;\n  uint32_t c;\n  uint32_t topbit = 0;\n  const uint8_t *end = p + len;\n  if (!utf && *p == 0xff && len > 1)\n    {\n    topbit = 0x80000000u;\n    p++;\n    len--;\n    }\n  chlen = utf8_to_ord(p, end, &c);\n  if (chlen <= 0) return -1;\n  if (utf && c > 0x10ffff) return -2;\n  p += chlen;\n  len -= chlen;\n  *pp++ = c | topbit;\n  }\n\n*pp = 0;\n*lenptr = pp - pbuffer32;\nreturn 0;\n}\n#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */\n\n\n\n/*************************************************\n*        Read a string from pcre2_config()       *\n*************************************************/\n\n/* Read out a version string from pcre2_config(), transcoding it into an\n8-bit buffer.\n\nArguments:\n  what       the item to read\n  where      the 8-bit buffer to receive the string\n*/\n\nstatic void\nconfig_str(uint32_t what, char *where)\n{\nint r1, r2;\nPCRE2_UCHAR buf[VERSION_SIZE];\n\nr1 = pcre2_config(what, NULL);\nr2 = pcre2_config(what, buf);\nif (r1 < 0 || r1 != r2 || r1 >= VERSION_SIZE)\n  {\n  cfprintf(clr_test_error, stderr, \"pcre2test: Error in pcre2_config(%d)\\n\", what);\n  exit(1);\n  }\n\nwhile (r1-- > 0) where[r1] = (char)buf[r1];\n}\n\n\n\n/*************************************************\n*       Check a modifier and find its field      *\n*************************************************/\n\n/* This function is called when a modifier has been identified. We check that\nit is allowed here and find the field that is to be changed.\n\nArguments:\n  m          the modifier list entry\n  ctx        CTX_PAT     => pattern context\n             CTX_POPPAT  => pattern context for popped pattern\n             CTX_DEFPAT  => default pattern context\n             CTX_DAT     => data context\n             CTX_DEFDAT  => default data context\n  pctl       point to pattern control block\n  dctl       point to data control block\n  c          a single character or 0\n\nReturns:     a field pointer or NULL\n*/\n\nstatic void *\ncheck_modifier(modstruct *m, int ctx, patctl *pctl, datctl *dctl, uint32_t c)\n{\nvoid *field = NULL;\nPCRE2_SIZE offset = m->offset;\n\nif (restrict_for_perl_test) switch(m->which)\n  {\n  case MOD_PNDP:\n  case MOD_PATP:\n  case MOD_DATP:\n  case MOD_PDP:\n  break;\n\n  default:\n  cfprintf(clr_test_error, outfile, \"** \\\"%s\\\" is not allowed in a Perl-compatible test\\n\",\n    m->name);\n  return NULL;\n  }\n\nswitch (m->which)\n  {\n  case MOD_CTC:  /* Compile context modifier */\n  if (ctx == CTX_DEFPAT) field = default_pat_context;\n    else if (ctx == CTX_PAT) field = pat_context;\n  break;\n\n  case MOD_CTM:  /* Match context modifier */\n  if (ctx == CTX_DEFDAT) field = default_dat_context;\n    else if (ctx == CTX_DAT) field = dat_context;\n  break;\n\n  case MOD_DAT:    /* Data line modifier */\n  case MOD_DATP:   /* Allowed for Perl test */\n  if (dctl != NULL) field = dctl;\n  break;\n\n  case MOD_PAT:    /* Pattern modifier */\n  case MOD_PATP:   /* Allowed for Perl test */\n  if (pctl != NULL) field = pctl;\n  break;\n\n  case MOD_PD:   /* Pattern or data line modifier */\n  case MOD_PDP:  /* Ditto, allowed for Perl test */\n  case MOD_PND:  /* Ditto, but not default pattern */\n  case MOD_PNDP: /* Ditto, allowed for Perl test */\n  if (dctl != NULL) field = dctl;\n    else if (pctl != NULL && (m->which == MOD_PD || m->which == MOD_PDP ||\n             ctx != CTX_DEFPAT))\n      field = pctl;\n  break;\n  }\n\nif (field == NULL)\n  {\n  if (c == 0)\n    cfprintf(clr_test_error, outfile, \"** \\\"%s\\\" is not valid here\\n\", m->name);\n  else\n    cfprintf(clr_test_error, outfile, \"** /%c is not valid here\\n\", c);\n  return NULL;\n  }\n\nreturn (char *)field + offset;\n}\n\n\n\n/*************************************************\n*            Decode a modifier list              *\n*************************************************/\n\n/* A pointer to a control block is NULL when called in cases when that block is\nnot relevant. They are never all relevant in one call. At least one of patctl\nand datctl is NULL. The second argument specifies which context to use for\nmodifiers that apply to contexts.\n\nArguments:\n  p          point to modifier string\n  ctx        CTX_PAT     => pattern context\n             CTX_POPPAT  => pattern context for popped pattern\n             CTX_DEFPAT  => default pattern context\n             CTX_DAT     => data context\n             CTX_DEFDAT  => default data context\n  pctl       point to pattern control block\n  dctl       point to data control block\n\nReturns: TRUE if successful decode, FALSE otherwise\n*/\n\nstatic BOOL\ndecode_modifiers(uint8_t *p, int ctx, patctl *pctl, datctl *dctl)\n{\nuint8_t *ep, *pp;\nlong li;\nunsigned long uli;\nBOOL first = TRUE;\n\nfor (;;)\n  {\n  void *field;\n  modstruct *m;\n  BOOL off = FALSE;\n  unsigned int i;\n  size_t len;\n  int index;\n  char *endptr;\n\n  /* Skip white space and commas. */\n\n  while (isspace(*p) || *p == ',') p++;\n  if (*p == 0) break;\n\n  /* Find the end of the item; lose trailing whitespace at end of line. */\n\n  for (ep = p; *ep != 0 && *ep != ','; ep++);\n  if (*ep == 0)\n    {\n    while (ep > p && isspace(ep[-1])) ep--;\n    *ep = 0;\n    }\n\n  /* Remember if the first character is '-'. */\n\n  if (*p == '-')\n    {\n    off = TRUE;\n    p++;\n    }\n\n  /* Find the length of a full-length modifier name, and scan for it. */\n\n  pp = p;\n  while (pp < ep && *pp != '=') pp++;\n  index = scan_modifiers(p, pp - p);\n\n  /* If the first modifier is unrecognized, try to interpret it as a sequence\n  of single-character abbreviated modifiers. None of these modifiers have any\n  associated data. They just set options or control bits. */\n\n  if (index < 0)\n    {\n    uint32_t cc;\n    uint8_t *mp = p;\n\n    if (!first)\n      {\n      cfprintf(clr_test_error, outfile, \"** Unrecognized modifier \\\"%.*s\\\"\\n\", (int)(ep-p), p);\n      if (ep - p == 1)\n        cfprintf(clr_test_error, outfile, \"** Single-character modifiers must come first\\n\");\n      return FALSE;\n      }\n\n    first = FALSE;\n\n    for (cc = *p; cc != ',' && cc != '\\n' && cc != 0; cc = *(++p))\n      {\n      for (i = 0; i < C1MODLISTCOUNT; i++)\n        if (cc == c1modlist[i].onechar) break;\n\n      if (i >= C1MODLISTCOUNT)\n        {\n        cfprintf(clr_test_error, outfile, \"** Unrecognized modifier '%c' in modifier string \"\n          \"\\\"%.*s\\\"\\n\", *p, (int)(ep-mp), mp);\n        return FALSE;\n        }\n\n      if (c1modlist[i].index >= 0)\n        {\n        index = c1modlist[i].index;\n        }\n\n      else\n        {\n        index = scan_modifiers((const uint8_t *)(c1modlist[i].fullname),\n          strlen(c1modlist[i].fullname));\n        if (index < 0)\n          {\n          cfprintf(clr_test_error, outfile, \"** Internal error: single-character equivalent \"\n            \"modifier \\\"%s\\\" not found\\n\", c1modlist[i].fullname);\n          return FALSE;\n          }\n        c1modlist[i].index = index;     /* Cache for next time */\n        }\n\n      field = check_modifier(modlist + index, ctx, pctl, dctl, *p);\n      if (field == NULL) return FALSE;\n\n      /* /x is a special case; a second appearance changes PCRE2_EXTENDED to\n      PCRE2_EXTENDED_MORE. */\n\n      if (cc == 'x' && (*((uint32_t *)field) & PCRE2_EXTENDED) != 0)\n        {\n        *((uint32_t *)field) &= ~PCRE2_EXTENDED;\n        *((uint32_t *)field) |= PCRE2_EXTENDED_MORE;\n        }\n      else\n        *((uint32_t *)field) |= modlist[index].value;\n      }\n\n    continue;    /* With the next (fullname) modifier */\n    }\n\n  /* We have a match on a full-name modifier. Check for the existence of data\n  when needed. */\n\n  m = modlist + index;      /* Save typing */\n  if (m->type != MOD_CTL && m->type != MOD_OPT && m->type != MOD_OPTMZ &&\n      (m->type != MOD_IND || *pp == '='))\n    {\n    if (*pp++ != '=')\n      {\n      cfprintf(clr_test_error, outfile, \"** '=' expected after \\\"%s\\\"\\n\", m->name);\n      return FALSE;\n      }\n    if (off)\n      {\n      cfprintf(clr_test_error, outfile, \"** '-' is not valid for \\\"%s\\\"\\n\", m->name);\n      return FALSE;\n      }\n    }\n\n  /* These on/off types have no data. */\n\n  else if (*pp != ',' && *pp != '\\n' && *pp != ' ' && *pp != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Unrecognized modifier '%.*s'\\n\", (int)(ep-p), p);\n    return FALSE;\n    }\n\n  /* Set the data length for those types that have data. Then find the field\n  that is to be set. If check_modifier() returns NULL, it has already output an\n  error message. */\n\n  len = ep - pp;\n  field = check_modifier(m, ctx, pctl, dctl, 0);\n  if (field == NULL) return FALSE;\n\n  /* Process according to data type. */\n\n  switch (m->type)\n    {\n    case MOD_CTL:\n    case MOD_OPT:\n    if (off) *((uint32_t *)field) &= ~m->value;\n      else *((uint32_t *)field) |= m->value;\n    break;\n\n    case MOD_OPTMZ:\n    pcre2_set_optimize(field, m->value);\n    break;\n\n    case MOD_BSR:\n    if (len == 7 && strncmpic(pp, (const uint8_t *)\"default\", 7) == 0)\n      {\n#ifdef BSR_ANYCRLF\n      *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;\n#else\n      *((uint16_t *)field) = PCRE2_BSR_UNICODE;\n#endif\n      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_BSR_SET;\n        else dctl->control2 &= ~CTL2_BSR_SET;\n      }\n    else\n      {\n      if (len == 7 && strncmpic(pp, (const uint8_t *)\"anycrlf\", 7) == 0)\n        *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;\n      else if (len == 7 && strncmpic(pp, (const uint8_t *)\"unicode\", 7) == 0)\n        *((uint16_t *)field) = PCRE2_BSR_UNICODE;\n      else goto INVALID_VALUE;\n      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_BSR_SET;\n        else dctl->control2 |= CTL2_BSR_SET;\n      }\n    pp = ep;\n    break;\n\n    case MOD_CHR:  /* A single character */\n    *((uint32_t *)field) = *pp++;\n    break;\n\n    case MOD_CON:  /* A convert type/options list */\n    for (;; pp++)\n      {\n      uint8_t *colon = (uint8_t *)strchr((const char *)pp, ':');\n      len = ((colon != NULL && colon < ep)? colon:ep) - pp;\n      for (i = 0; i < convertlistcount; i++)\n        {\n        if (strncmpic(pp, (const uint8_t *)convertlist[i].name, len) == 0)\n          {\n          if (*((uint32_t *)field) == CONVERT_UNSET)\n            *((uint32_t *)field) = convertlist[i].option;\n          else\n            *((uint32_t *)field) |= convertlist[i].option;\n          break;\n          }\n        }\n      if (i >= convertlistcount) goto INVALID_VALUE;\n      pp += len;\n      if (*pp != ':') break;\n      }\n    break;\n\n    case MOD_IN2:    /* One or two unsigned integers */\n    if (!isdigit(*pp)) goto INVALID_VALUE;\n    uli = strtoul((const char *)pp, &endptr, 10);\n    if (U32OVERFLOW(uli)) goto INVALID_VALUE;\n    ((uint32_t *)field)[0] = (uint32_t)uli;\n    if (*endptr == ':')\n      {\n      uli = strtoul((const char *)endptr+1, &endptr, 10);\n      if (U32OVERFLOW(uli)) goto INVALID_VALUE;\n      ((uint32_t *)field)[1] = (uint32_t)uli;\n      }\n    else ((uint32_t *)field)[1] = 0;\n    pp = (uint8_t *)endptr;\n    break;\n\n    /* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or\n    less than ULONG_MAX. So first test for overflowing the long int, and then\n    test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */\n\n    case MOD_SIZ:    /* PCRE2_SIZE value */\n    if (!isdigit(*pp)) goto INVALID_VALUE;\n    uli = strtoul((const char *)pp, &endptr, 10);\n    if (uli == ULONG_MAX) goto INVALID_VALUE;\n#if ULONG_MAX > PCRE2_SIZE_MAX\n    if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE;\n#endif\n    *((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli;\n    pp = (uint8_t *)endptr;\n    break;\n\n    case MOD_IND:    /* Unsigned integer with default */\n    if (len == 0)\n      {\n      *((uint32_t *)field) = (uint32_t)(m->value);\n      break;\n      }\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case MOD_INT:    /* Unsigned integer */\n    if (!isdigit(*pp)) goto INVALID_VALUE;\n    uli = strtoul((const char *)pp, &endptr, 10);\n    if (U32OVERFLOW(uli)) goto INVALID_VALUE;\n    *((uint32_t *)field) = (uint32_t)uli;\n    pp = (uint8_t *)endptr;\n    break;\n\n    case MOD_INS:   /* Signed integer */\n    if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE;\n    li = strtol((const char *)pp, &endptr, 10);\n    if (S32OVERFLOW(li)) goto INVALID_VALUE;\n    *((int32_t *)field) = (int32_t)li;\n    pp = (uint8_t *)endptr;\n    break;\n\n    case MOD_NL:\n    for (i = 0; i < sizeof(newlines)/sizeof(char *); i++)\n      if (len == strlen(newlines[i]) &&\n        strncmpic(pp, (const uint8_t *)newlines[i], len) == 0) break;\n    if (i >= sizeof(newlines)/sizeof(char *)) goto INVALID_VALUE;\n    if (i == 0)\n      {\n      pcre2_set_newline(field, NEWLINE_DEFAULT);\n      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_NL_SET;\n        else dctl->control2 &= ~CTL2_NL_SET;\n      }\n    else\n      {\n      pcre2_set_newline(field, i);\n      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_NL_SET;\n        else dctl->control2 |= CTL2_NL_SET;\n      }\n    pp = ep;\n    break;\n\n    case MOD_NN:              /* Name or (signed) number; may be several */\n    if (isdigit(*pp) || *pp == '-')\n      {\n      int ct = MAXCPYGET - 1;\n      int32_t value;\n      li = strtol((const char *)pp, &endptr, 10);\n      if (S32OVERFLOW(li)) goto INVALID_VALUE;\n      value = (int32_t)li;\n      field = (char *)field - m->offset + m->value;      /* Adjust field ptr */\n      if (value >= 0)                                    /* Add new number */\n        {\n        while (*((int32_t *)field) >= 0 && ct-- > 0)   /* Skip previous */\n          field = (char *)field + sizeof(int32_t);\n        if (ct <= 0)\n          {\n          cfprintf(clr_test_error, outfile, \"** Too many numeric \\\"%s\\\" modifiers\\n\", m->name);\n          return FALSE;\n          }\n        }\n      *((int32_t *)field) = value;\n      if (ct > 0) ((int32_t *)field)[1] = -1;\n      pp = (uint8_t *)endptr;\n      }\n\n    /* Multiple strings are put end to end. */\n\n    else\n      {\n      char *nn = (char *)field;\n      if (len > 0)                    /* Add new name */\n        {\n        if (len > MAX_NAME_SIZE)\n          {\n          cfprintf(clr_test_error, outfile, \"** Group name in \\\"%s\\\" is too long\\n\", m->name);\n          return FALSE;\n          }\n        while (*nn != 0) nn += strlen(nn) + 1;\n        if (nn + len + 2 - (char *)field > LENCPYGET)\n          {\n          cfprintf(clr_test_error, outfile, \"** Too many characters in named \\\"%s\\\" modifiers\\n\",\n            m->name);\n          return FALSE;\n          }\n        memcpy(nn, pp, len);\n        }\n      nn[len] = 0 ;\n      nn[len+1] = 0;\n      pp = ep;\n      }\n    break;\n\n    case MOD_STR:\n    if (len + 1 > m->value)\n      {\n      cfprintf(clr_test_error, outfile, \"** Overlong value for \\\"%s\\\" (max %d code units)\\n\",\n        m->name, m->value - 1);\n      return FALSE;\n      }\n    ((uint8_t *)field)[0] = len;\n    memcpy(((uint8_t *)field)+1, pp, len);\n    ((uint8_t *)field)[len+1] = 0;\n    pp = ep;\n    break;\n    }\n\n  if (*pp != ',' && *pp != '\\n' && *pp != ' ' && *pp != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Comma expected after modifier item \\\"%s\\\"\\n\", m->name);\n    return FALSE;\n    }\n\n  p = pp;\n\n  if (ctx == CTX_POPPAT &&\n     (pctl->options != 0 ||\n      pctl->tables_id != 0 ||\n      pctl->locale[0] != MOD_STR_UNSET ||\n      (pctl->control & NOTPOP_CONTROLS) != 0))\n    {\n    cfprintf(clr_test_error, outfile, \"** \\\"%s\\\" is not valid here\\n\", m->name);\n    return FALSE;\n    }\n  }\n\nreturn TRUE;\n\nINVALID_VALUE:\ncfprintf(clr_test_error, outfile, \"** Invalid value in \\\"%.*s\\\"\\n\", (int)(ep-p), p);\nreturn FALSE;\n}\n\n\n\n/*************************************************\n*             Get info from a pattern            *\n*************************************************/\n\n/* A wrapped call to pcre2_pattern_info(), applied to the current compiled\npattern.\n\nArguments:\n  what        code for the required information\n  where       where to put the answer\n  unsetok     PCRE2_ERROR_UNSET is an \"expected\" result\n\nReturns:      the return from pcre2_pattern_info()\n*/\n\nstatic int\npattern_info(int what, void *where, BOOL unsetok)\n{\nint rc;\n(void)pcre2_pattern_info(compiled_code, what, NULL);  /* Exercise the code */\nrc = pcre2_pattern_info(compiled_code, what, where);\nif (rc >= 0) return 0;\nif (rc != PCRE2_ERROR_UNSET || !unsetok)\n  {\n  cfprintf(clr_api_error, outfile, \"Error %d from \"\n    \"pcre2_pattern_info_\" STR(PCRE2_CODE_UNIT_WIDTH) \"(%d)\\n\", rc, what);\n  }\nreturn rc;\n}\n\n\n\n/*************************************************\n*      Show memory usage info for a pattern      *\n*************************************************/\n\nstatic void\nshow_memory_info(void)\n{\nuint32_t name_count, name_entry_size;\nPCRE2_SIZE size, cblock_size, data_size;\n\ncblock_size = sizeof(pcre2_real_code);\n\n(void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE);\n(void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE);\n(void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE);\n\n/* The uint32_t variables are cast before multiplying to avoid potential\n integer overflow. */\ndata_size = CU2BYTES((PCRE2_SIZE)name_count * (PCRE2_SIZE)name_entry_size);\n\ncfprintf(clr_profiling, outfile, \"Memory allocation - code size : %\" SIZ_FORM \"\\n\", size -\n  cblock_size - data_size);\nif (data_size != 0)\n  cfprintf(clr_profiling, outfile, \"Memory allocation - data size : %\" SIZ_FORM \"\\n\", data_size);\n\nif (pat_patctl.jit != 0)\n  {\n  (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE);\n  cfprintf(clr_profiling, outfile, \"Memory allocation - JIT code  : %\" SIZ_FORM \"\\n\", size);\n  }\n}\n\n\n\n/*************************************************\n*       Show frame size info for a pattern       *\n*************************************************/\n\nstatic void\nshow_framesize(void)\n{\nPCRE2_SIZE frame_size;\n(void)pattern_info(PCRE2_INFO_FRAMESIZE, &frame_size, FALSE);\ncfprintf(clr_profiling, outfile, \"Frame size for pcre2_match(): %\" SIZ_FORM \"\\n\", frame_size);\n}\n\n\n\n/*************************************************\n*   Show heapframes size info for a match_data   *\n*************************************************/\n\nstatic void\nshow_heapframes_size(void)\n{\nPCRE2_SIZE heapframes_size;\nheapframes_size = pcre2_get_match_data_heapframes_size(match_data);\ncfprintf(clr_profiling, outfile, \"Heapframes size in match_data: %\" SIZ_FORM \"\\n\",\n  heapframes_size);\n}\n\n\n\n/*************************************************\n*         Get and output an error message        *\n*************************************************/\n\nstatic BOOL\nprint_error_message_file(FILE *file, int errorcode, const char *before,\n  const char *after, BOOL badcode_ok)\n{\nint len;\nPCRE2_UCHAR buf[128];\n\nlen = pcre2_get_error_message(errorcode, buf, sizeof(buf)/sizeof(*buf));\nif (len == PCRE2_ERROR_BADDATA && badcode_ok)\n  {\n  cfprintf(clr_api_error, file, \"%sPCRE2_ERROR_BADDATA (unknown error number)%s\", before,\n    after);\n  }\nelse if (len < 0)\n  {\n  cfprintf(clr_test_error, file, \"\\n** pcre2test internal error: cannot interpret error \"\n    \"number\\n** Unexpected return (%d) from pcre2_get_error_message()\\n\", len);\n  }\nelse if ((unsigned)len != pcre2_strlen(buf))\n  {\n  cfprintf(clr_test_error, file, \"\\n** pcre2test: unexpected length %d from pcre2_get_error_message()\\n\", len);\n  return FALSE;\n  }\nelse\n  {\n  cfprintf(clr_api_error, file, \"%s\", before);\n  pchars(clr_api_error, buf, len, FALSE, file);\n  cfprintf(clr_api_error, file, \"%s\", after);\n  }\nreturn len >= 0;\n}\n\nstatic BOOL\nprint_error_message(int errorcode, const char *before, const char *after)\n{\nreturn print_error_message_file(outfile, errorcode, before, after, FALSE);\n}\n\n\n/*************************************************\n*     Callback function for callout enumeration  *\n*************************************************/\n\n/* Testing function to log data inside callout enumeration callbacks.\n\nArgument:\n  cb            pointer to enumerate block\n  callout_data  user data\n\nReturns:    0\n*/\n\nstatic int callout_enumerate_function(pcre2_callout_enumerate_block *cb,\n  void *callout_data)\n{\nuint32_t i;\nPCRE2_SPTR pattern_string = pbuffer;\nBOOL utf = (compiled_code->overall_options & PCRE2_UTF) != 0;\nPCRE2_SIZE next_item_length = cb->next_item_length;\n\n(void)callout_data;  /* Not currently displayed */\n\nfprintf(outfile, \"Callout \");\nif (cb->callout_string != NULL)\n  {\n  uint32_t delimiter = cb->callout_string[-1];\n  fprintf(outfile, \"%c\", CHAR_OUTPUT(delimiter));\n  pchars(clr_none, cb->callout_string, cb->callout_string_length, utf, outfile);\n  for (i = 0; callout_start_delims[i] != 0; i++)\n    if (delimiter == callout_start_delims[i])\n      {\n      delimiter = callout_end_delims[i];\n      break;\n      }\n  fprintf(outfile, \"%c  \", CHAR_OUTPUT(delimiter));\n  }\nelse fprintf(outfile, \"%d  \", cb->callout_number);\n\nif (next_item_length == 0 && pattern_string[cb->pattern_position] != 0)\n  next_item_length = 1;\npchars(clr_none, pattern_string+cb->pattern_position, next_item_length, utf, outfile);\nfprintf(outfile, \"\\n\");\n\nreturn 0;\n}\n\nstatic int callout_enumerate_function_void(pcre2_callout_enumerate_block *cb,\n  void *callout_data)\n{\n(void)cb;\n(void)callout_data;\nreturn 0;\n}\n\nstatic int callout_enumerate_function_fail(pcre2_callout_enumerate_block *cb,\n  void *callout_data)\n{\n(void)cb;\nreturn *(int *)callout_data;\n}\n\n\n\n/*************************************************\n*        Show information about a pattern        *\n*************************************************/\n\n/* This function is called after a pattern has been compiled if any of the\ninformation-requesting controls have been set.\n\nArguments:  none\n\nReturns:    PR_OK     continue processing next line\n            PR_SKIP   skip to a blank line\n            PR_ABEND  abort the pcre2test run\n*/\n\nstatic int\nshow_pattern_info(void)\n{\nint rc;\nuint32_t compile_options, overall_options, extra_options;\nBOOL utf = (compiled_code->overall_options & PCRE2_UTF) != 0;\n\nif ((pat_patctl.control & CTL_MEMORY) != 0)\n  show_memory_info();\n\nif ((pat_patctl.control2 & CTL2_FRAMESIZE) != 0)\n  show_framesize();\n\nif ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)\n  {\n  fprintf(outfile, \"------------------------------------------------------------------\\n\");\n  pcre2_printint(compiled_code, outfile,\n    (pat_patctl.control & CTL_FULLBINCODE) != 0);\n  }\n\nif ((pat_patctl.control & CTL_INFO) != 0)\n  {\n  PCRE2_SPTR nametable;\n  uint8_t *start_bits;\n  BOOL heap_limit_set, match_limit_set, depth_limit_set;\n  uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit,\n    hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty,\n    depth_limit, heap_limit, match_limit, minlength, nameentrysize, namecount,\n    newline_convention;\n\n  /* These info requests may return PCRE2_ERROR_UNSET. */\n\n  switch(pattern_info(PCRE2_INFO_HEAPLIMIT, &heap_limit, TRUE))\n    {\n    case 0:\n    heap_limit_set = TRUE;\n    break;\n\n    case PCRE2_ERROR_UNSET:\n    heap_limit_set = FALSE;\n    break;\n\n    default:\n    return PR_ABEND;\n    }\n\n  switch(pattern_info(PCRE2_INFO_MATCHLIMIT, &match_limit, TRUE))\n    {\n    case 0:\n    match_limit_set = TRUE;\n    break;\n\n    case PCRE2_ERROR_UNSET:\n    match_limit_set = FALSE;\n    break;\n\n    default:\n    return PR_ABEND;\n    }\n\n  switch(pattern_info(PCRE2_INFO_DEPTHLIMIT, &depth_limit, TRUE))\n    {\n    case 0:\n    depth_limit_set = TRUE;\n    break;\n\n    case PCRE2_ERROR_UNSET:\n    depth_limit_set = FALSE;\n    break;\n\n    default:\n    return PR_ABEND;\n    }\n\n  /* These info requests should always succeed. */\n\n  if (pattern_info(PCRE2_INFO_BACKREFMAX, &backrefmax, FALSE) +\n      pattern_info(PCRE2_INFO_BSR, &bsr_convention, FALSE) +\n      pattern_info(PCRE2_INFO_CAPTURECOUNT, &capture_count, FALSE) +\n      pattern_info(PCRE2_INFO_FIRSTBITMAP, &start_bits, FALSE) +\n      pattern_info(PCRE2_INFO_FIRSTCODEUNIT, &first_cunit, FALSE) +\n      pattern_info(PCRE2_INFO_FIRSTCODETYPE, &first_ctype, FALSE) +\n      pattern_info(PCRE2_INFO_HASBACKSLASHC, &hasbackslashc, FALSE) +\n      pattern_info(PCRE2_INFO_HASCRORLF, &hascrorlf, FALSE) +\n      pattern_info(PCRE2_INFO_JCHANGED, &jchanged, FALSE) +\n      pattern_info(PCRE2_INFO_LASTCODEUNIT, &last_cunit, FALSE) +\n      pattern_info(PCRE2_INFO_LASTCODETYPE, &last_ctype, FALSE) +\n      pattern_info(PCRE2_INFO_MATCHEMPTY, &match_empty, FALSE) +\n      pattern_info(PCRE2_INFO_MINLENGTH, &minlength, FALSE) +\n      pattern_info(PCRE2_INFO_NAMECOUNT, &namecount, FALSE) +\n      pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize, FALSE) +\n      pattern_info(PCRE2_INFO_NAMETABLE, &nametable, FALSE) +\n      pattern_info(PCRE2_INFO_NEWLINE, &newline_convention, FALSE)\n      != 0)\n    return PR_ABEND;\n\n  fprintf(outfile, \"Capture group count = %d\\n\", capture_count);\n\n  if (backrefmax > 0)\n    fprintf(outfile, \"Max back reference = %d\\n\", backrefmax);\n\n  if (maxlookbehind > 0)\n    fprintf(outfile, \"Max lookbehind = %d\\n\", maxlookbehind);\n\n  if (heap_limit_set)\n    fprintf(outfile, \"Heap limit = %u\\n\", heap_limit);\n\n  if (match_limit_set)\n    fprintf(outfile, \"Match limit = %u\\n\", match_limit);\n\n  if (depth_limit_set)\n    fprintf(outfile, \"Depth limit = %u\\n\", depth_limit);\n\n  if (namecount > 0)\n    {\n    fprintf(outfile, \"Named capture groups:\\n\");\n    for (; namecount > 0; namecount--)\n      {\n      size_t length = pcre2_strlen(nametable + IMM2_SIZE);\n      fprintf(outfile, \"  \");\n\n      /* In UTF mode the name may be a UTF string containing non-ASCII\n      letters and digits. We must output it as a UTF-8 string. In non-UTF mode,\n      use the normal string printing functions, which use escapes for all\n      non-ASCII characters. */\n\n      if (utf)\n        {\n#if PCRE2_CODE_UNIT_WIDTH == 32\n        PCRE2_SPTR nameptr = nametable + IMM2_SIZE;\n        while (*nameptr != 0)\n          {\n          uint8_t u8buff[6];\n          int len = ord_to_utf8(*nameptr++, u8buff);\n          fprintf(outfile, \"%.*s\", len, u8buff);\n          }\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 16\n        PCRE2_SPTR nameptr = nametable + IMM2_SIZE;\n        PCRE2_SPTR nameptr_end = nameptr + pcre2_strlen(nameptr);\n        while (*nameptr != 0)\n          {\n          int len;\n          uint8_t u8buff[6];\n          uint32_t c;\n          int ord_rc = utf16_to_ord(nameptr, nameptr_end, &c);\n          if (ord_rc > 0) nameptr += ord_rc;\n          else c = *nameptr++;\n          len = ord_to_utf8(c, u8buff);\n          fprintf(outfile, \"%.*s\", len, u8buff);\n          }\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 8\n        fprintf(outfile, \"%s\", nametable + IMM2_SIZE);\n#endif\n        }\n      else  /* Not UTF mode */\n        {\n        pchars(clr_none, nametable + IMM2_SIZE, length, FALSE, outfile);\n        }\n\n      while (length++ < nameentrysize - IMM2_SIZE) putc(' ', outfile);\n\n      fprintf(outfile, \"%3d\\n\", GET2(nametable, 0));\n\n      nametable = nametable + nameentrysize;\n      }\n    }\n\n  if (hascrorlf)     fprintf(outfile, \"Contains explicit CR or LF match\\n\");\n  if (hasbackslashc) fprintf(outfile, \"Contains \\\\C\\n\");\n  if (match_empty)   fprintf(outfile, \"May match empty string\\n\");\n\n  pattern_info(PCRE2_INFO_ARGOPTIONS, &compile_options, FALSE);\n  pattern_info(PCRE2_INFO_ALLOPTIONS, &overall_options, FALSE);\n  pattern_info(PCRE2_INFO_EXTRAOPTIONS, &extra_options, FALSE);\n\n  /* Remove UTF/UCP if they were there only because of forbid_utf. This saves\n  cluttering up the verification output of non-UTF test files. */\n\n  if ((pat_patctl.options & PCRE2_NEVER_UTF) == 0)\n    {\n    compile_options &= ~PCRE2_NEVER_UTF;\n    overall_options &= ~PCRE2_NEVER_UTF;\n    }\n\n  if ((pat_patctl.options & PCRE2_NEVER_UCP) == 0)\n    {\n    compile_options &= ~PCRE2_NEVER_UCP;\n    overall_options &= ~PCRE2_NEVER_UCP;\n    }\n\n  if ((compile_options|overall_options) != 0)\n    {\n    if (compile_options == overall_options)\n      show_compile_options(clr_none, compile_options, \"Options:\", \"\\n\");\n    else\n      {\n      show_compile_options(clr_none, compile_options, \"Compile options:\", \"\\n\");\n      show_compile_options(clr_none, overall_options, \"Overall options:\", \"\\n\");\n      }\n    }\n\n  if (extra_options != 0)\n    show_compile_extra_options(clr_none, extra_options, \"Extra options:\", \"\\n\");\n\n  if (compiled_code->optimization_flags != PCRE2_OPTIMIZATION_ALL)\n    show_optimize_flags(clr_none, compiled_code->optimization_flags, \"Optimizations: \", \"\\n\");\n\n  if (jchanged) fprintf(outfile, \"Duplicate name status changes\\n\");\n\n  if ((pat_patctl.control2 & CTL2_BSR_SET) != 0 ||\n      (compiled_code->flags & PCRE2_BSR_SET) != 0)\n    fprintf(outfile, \"\\\\R matches %s\\n\", (bsr_convention == PCRE2_BSR_UNICODE)?\n      \"any Unicode newline\" : \"CR, LF, or CRLF\");\n\n  if ((compiled_code->flags & PCRE2_NL_SET) != 0)\n    {\n    switch (newline_convention)\n      {\n      case PCRE2_NEWLINE_CR:\n      fprintf(outfile, \"Forced newline is CR\\n\");\n      break;\n\n      case PCRE2_NEWLINE_LF:\n      fprintf(outfile, \"Forced newline is LF\\n\");\n      break;\n\n      case PCRE2_NEWLINE_CRLF:\n      fprintf(outfile, \"Forced newline is CRLF\\n\");\n      break;\n\n      case PCRE2_NEWLINE_ANYCRLF:\n      fprintf(outfile, \"Forced newline is CR, LF, or CRLF\\n\");\n      break;\n\n      case PCRE2_NEWLINE_ANY:\n      fprintf(outfile, \"Forced newline is any Unicode newline\\n\");\n      break;\n\n      case PCRE2_NEWLINE_NUL:\n      fprintf(outfile, \"Forced newline is NUL\\n\");\n      break;\n\n      default:\n      break;\n      }\n    }\n\n  if (first_ctype == 2)\n    {\n    fprintf(outfile, \"First code unit at start or follows newline\\n\");\n    }\n  else if (first_ctype == 1)\n    {\n    const char *caseless =\n      ((compiled_code->flags & PCRE2_FIRSTCASELESS) == 0)?\n      \"\" : \" (caseless)\";\n    if (first_cunit != 0xff && PRINTABLE(first_cunit))\n      fprintf(outfile, \"First code unit = \\'%c\\'%s\\n\", CHAR_OUTPUT(first_cunit),\n              caseless);\n    else\n      {\n      fprintf(outfile, \"First code unit = \");\n      if (first_cunit == 0xff)\n        fprintf(outfile, \"\\\\xff\");\n      else\n        pchar(first_cunit, FALSE, outfile);\n      fprintf(outfile, \"%s\\n\", caseless);\n      }\n    }\n  else if (start_bits != NULL)\n    {\n    int input;\n    int c = 24;\n    fprintf(outfile, \"Starting code units:\");\n    for (input = 0; input < 256; input++)\n      {\n      int i = CHAR_INPUT_HEX(input);\n      if ((start_bits[i/8] & (1u << (i&7))) != 0)\n        {\n        if (c > 75)\n          {\n          fprintf(outfile, \"\\n \");\n          c = 2;\n          }\n        if (PRINTABLE(i) && i != CHAR_SPACE)\n          {\n          fprintf(outfile, \" %c\", CHAR_OUTPUT(i));\n          c += 2;\n          }\n        else\n          {\n          fprintf(outfile, \" \\\\x%02x\", CHAR_OUTPUT_HEX(i));\n          c += 5;\n          }\n        }\n      }\n    fprintf(outfile, \"\\n\");\n    }\n\n  if (last_ctype != 0)\n    {\n    const char *caseless =\n      ((compiled_code->flags & PCRE2_LASTCASELESS) == 0)?\n      \"\" : \" (caseless)\";\n    if (PRINTABLE(last_cunit))\n      fprintf(outfile, \"Last code unit = \\'%c\\'%s\\n\", CHAR_OUTPUT(last_cunit),\n              caseless);\n    else\n      {\n      fprintf(outfile, \"Last code unit = \");\n      pchar(last_cunit, FALSE, outfile);\n      fprintf(outfile, \"%s\\n\", caseless);\n      }\n    }\n\n  if ((compiled_code->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)\n    fprintf(outfile, \"Subject length lower bound = %d\\n\", minlength);\n\n  if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)\n    {\n#ifdef SUPPORT_JIT\n    if (compiled_code->executable_jit != NULL)\n      fprintf(outfile, \"JIT compilation was successful\\n\");\n    else\n      {\n      cfprintf(clr_api_error, outfile, \"JIT compilation was not successful\");\n      if (jitrc != 0 && !print_error_message(jitrc, \" (\", \")\"))\n        return PR_ABEND;\n      fprintf(outfile, \"\\n\");\n      }\n#else\n      cfprintf(clr_api_error, outfile, \"JIT support is not available in this version of PCRE2\\n\");\n#endif\n    }\n  }\n\nrc = pcre2_callout_enumerate(compiled_code,\n  ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)? callout_enumerate_function :\n  /* Exercise the callout enumeration code with a dummy callback to make sure\n  it works. */\n  callout_enumerate_function_void, NULL);\nif (rc != 0)\n  {\n  cfprintf(clr_api_error, outfile, \"Callout enumerate failed: error %d: \", rc);\n  if (rc < 0 && !print_error_message(rc, \"\", \"\\n\"))\n    return PR_ABEND;\n  return PR_SKIP;\n  }\n\nreturn PR_OK;\n}\n\n\n\n/*************************************************\n*              Handle serialization error        *\n*************************************************/\n\n/* Print an error message after a serialization failure.\n\nArguments:\n  rc         the error code\n  msg        an initial message for what failed\n\nReturns:     FALSE if print_error_message() fails\n*/\n\nstatic BOOL\nserial_error(int rc, const char *msg)\n{\ncfprintf(clr_api_error, outfile, \"%s failed: error %d: \", msg, rc);\nreturn print_error_message(rc, \"\", \"\\n\");\n}\n\n\n\n/*************************************************\n*               Process command line             *\n*************************************************/\n\n/* This function is called for lines beginning with # and a character that is\nnot ! or whitespace, when encountered between tests, which means that there is\nno compiled pattern (compiled_code is NULL). The line is in buffer.\n\nArguments:  none\n\nReturns:    PR_OK     continue processing next line\n            PR_SKIP   skip to a blank line\n            PR_ABEND  abort the pcre2test run\n*/\n\nstatic int\nprocess_command(void)\n{\nFILE *f;\nPCRE2_SIZE serial_size;\nsize_t i;\nint rc, cmd, yield;\nuint16_t first_listed_newline;\nconst char *cmdname;\nsize_t cmdlen;\nuint8_t *argptr, *serial;\nBOOL if_inverted;\n\nyield = PR_OK;\ncmd = CMD_UNKNOWN;\ncmdlen = 0;\n\nfor (i = 0; i < cmdlistcount; i++)\n  {\n  cmdname = cmdlist[i].name;\n  cmdlen = strlen(cmdname);\n  if (strncmp((char *)(buffer+1), cmdname, cmdlen) == 0 &&\n      (buffer[cmdlen+1] == 0 || isspace(buffer[cmdlen+1])))\n    {\n    cmd = cmdlist[i].value;\n    break;\n    }\n  }\n\nif (preprocess_only && cmd != CMD_IF && cmd != CMD_ENDIF)\n  return PR_OK;\n\nargptr = buffer + cmdlen + 1;\n\nif (restrict_for_perl_test && cmd != CMD_PATTERN && cmd != CMD_SUBJECT &&\n    cmd != CMD_IF && cmd != CMD_ENDIF)\n  {\n  cfprintf(clr_test_error, outfile, \"** #%s is not allowed after #perltest\\n\", cmdname);\n  return PR_ABEND;\n  }\n\nswitch(cmd)\n  {\n  case CMD_UNKNOWN:\n  cfprintf(clr_test_error, outfile, \"** Unknown command: %s\", buffer);\n  break;\n\n  case CMD_FORBID_UTF:\n  forbid_utf = PCRE2_NEVER_UTF|PCRE2_NEVER_UCP;\n  break;\n\n  case CMD_PERLTEST:\n  restrict_for_perl_test = TRUE;\n  break;\n\n  /* Set default pattern modifiers */\n\n  case CMD_PATTERN:\n  (void)decode_modifiers(argptr, CTX_DEFPAT, &def_patctl, NULL);\n  if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0)\n    def_patctl.jit = JIT_DEFAULT;\n  break;\n\n  /* Set default subject modifiers */\n\n  case CMD_SUBJECT:\n  (void)decode_modifiers(argptr, CTX_DEFDAT, NULL, &def_datctl);\n  break;\n\n  /* Check the default newline, and if not one of those listed, set up the\n  first one to be forced. An empty list unsets. */\n\n  case CMD_NEWLINE_DEFAULT:\n  local_newline_default = 0;   /* Unset */\n  first_listed_newline = 0;\n  for (;;)\n    {\n    while (isspace(*argptr)) argptr++;\n    if (*argptr == 0) break;\n    for (uint16_t j = 1; j < sizeof(newlines)/sizeof(char *); j++)\n      {\n      size_t nlen = strlen(newlines[j]);\n      if (strncmpic(argptr, (const uint8_t *)newlines[j], nlen) == 0 &&\n          isspace(argptr[nlen]))\n        {\n        if (j == NEWLINE_DEFAULT) return PR_OK;  /* Default is valid */\n        if (first_listed_newline == 0) first_listed_newline = j;\n        }\n      }\n    while (*argptr != 0 && !isspace(*argptr)) argptr++;\n    }\n  local_newline_default = first_listed_newline;\n  break;\n\n  /* Pop or copy a compiled pattern off the stack. Modifiers that do not affect\n  the compiled pattern (e.g. to give information) are permitted. The default\n  pattern modifiers are ignored. */\n\n  case CMD_POP:\n  case CMD_POPCOPY:\n  if (patstacknext <= 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Can't pop off an empty stack\\n\");\n    return PR_SKIP;\n    }\n  patctl_zero(&pat_patctl);  /* Completely unset */\n  if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL))\n    return PR_SKIP;\n\n  if (cmd == CMD_POP)\n    {\n    compiled_code = patstack[--patstacknext];\n    }\n  else\n    {\n    compiled_code = pcre2_code_copy(patstack[patstacknext - 1]);\n    }\n\n  if (pat_patctl.jit != 0)\n    {\n    jitrc = pcre2_jit_compile(compiled_code, pat_patctl.jit);\n    }\n\n  rc = show_pattern_info();\n  if (rc != PR_OK) return rc;\n  break;\n\n  /* Save the stack of compiled patterns to a file, then empty the stack. */\n\n  case CMD_SAVE:\n  if (patstacknext <= 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** No stacked patterns to save\\n\");\n    return PR_OK;\n    }\n\n  rc = open_file(argptr+1, BINARY_OUTPUT_MODE, &f, \"#save\");\n  if (rc != PR_OK) return rc;\n\n  rc = pcre2_serialize_encode((const pcre2_code **)patstack, patstacknext,\n    &serial, &serial_size, general_context);\n  if (rc < 0)\n    {\n    fclose(f);\n    if (!serial_error(rc, \"Serialization\")) return PR_ABEND;\n    break;\n    }\n\n  /* Write the length at the start of the file to make it straightforward to\n  get the right memory when re-loading. This saves having to read the file size\n  in different operating systems. To allow for different endianness (even\n  though reloading with the opposite endianness does not work), write the\n  length byte-by-byte. */\n\n  for (i = 0; i < 4; i++) fputc((serial_size >> (i*8)) & 255, f);\n  if (fwrite(serial, 1, serial_size, f) != serial_size)\n    {\n    cfprintf(clr_test_error, outfile, \"** Wrong return from fwrite()\\n\");\n    fclose(f);\n    return PR_ABEND;\n    }\n\n  fclose(f);\n  pcre2_serialize_free(serial);\n  while(patstacknext > 0)\n    {\n    compiled_code = patstack[--patstacknext];\n    pcre2_code_free(compiled_code);\n    }\n  compiled_code = NULL;\n  break;\n\n  /* Load a set of compiled patterns from a file onto the stack */\n\n  case CMD_LOAD:\n  rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, \"#load\");\n  if (rc != PR_OK) return rc;\n\n  serial_size = 0;\n  for (i = 0; i < 4; i++) serial_size |= fgetc(f) << (i*8);\n\n  serial = malloc(serial_size);\n  if (serial == NULL)\n    {\n    cfprintf(clr_test_error, outfile, \"** Failed to get memory (size %\" SIZ_FORM \") for #load\\n\",\n      serial_size);\n    fclose(f);\n    return PR_ABEND;\n    }\n\n  i = fread(serial, 1, serial_size, f);\n  fclose(f);\n\n  if (i != serial_size)\n    {\n    cfprintf(clr_test_error, outfile, \"** Wrong return from fread()\\n\");\n    yield = PR_ABEND;\n    }\n  else\n    {\n    rc = pcre2_serialize_get_number_of_codes(serial);\n    if (rc < 0)\n      {\n      if (!serial_error(rc, \"Get number of codes\")) yield = PR_ABEND;\n      }\n    else\n      {\n      if (rc + patstacknext > PATSTACKSIZE)\n        {\n        cfprintf(clr_test_error, outfile, \"** Not enough space on pattern stack for %d pattern%s\\n\",\n          rc, (rc == 1)? \"\" : \"s\");\n        rc = PATSTACKSIZE - patstacknext;\n        cfprintf(clr_test_error, outfile, \"** Decoding %d pattern%s\\n\", rc,\n          (rc == 1)? \"\" : \"s\");\n        }\n      rc = pcre2_serialize_decode(patstack + patstacknext, rc, serial,\n        general_context);\n      if (rc < 0)\n        {\n        if (!serial_error(rc, \"Deserialization\")) yield = PR_ABEND;\n        }\n      else patstacknext += rc;\n      }\n    }\n\n  free(serial);\n  break;\n\n  /* Load a set of binary tables into tables3. */\n\n  case CMD_LOADTABLES:\n  rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, \"#loadtables\");\n  if (rc != PR_OK) return rc;\n\n  if (tables3 == NULL)\n    {\n    int r;\n    r = pcre2_config(PCRE2_CONFIG_TABLES_LENGTH, &loadtables_length);\n    if (r >= 0) tables3 = malloc(loadtables_length);\n    }\n\n  if (tables3 == NULL)\n    {\n    cfprintf(clr_test_error, outfile, \"** Failed: malloc/config for #loadtables\\n\");\n    yield = PR_ABEND;\n    }\n  else if (fread(tables3, 1, loadtables_length, f) != loadtables_length)\n    {\n    cfprintf(clr_test_error, outfile, \"** Wrong return from fread()\\n\");\n    yield = PR_ABEND;\n    }\n\n  fclose(f);\n  break;\n\n  case CMD_IF:\n  if (inside_if)\n    {\n    cfprintf(clr_test_error, outfile, \"** Nested #if not supported\\n\");\n    return PR_ABEND;\n    }\n\n  while (isspace(*argptr)) argptr++;\n  if_inverted = FALSE;\n  if (*argptr == '!')\n    {\n    argptr++;\n    if_inverted = TRUE;\n    }\n  while (isspace(*argptr)) argptr++;\n  for (i = 0; i < COPTLISTCOUNT; i++)\n    {\n    size_t optlen = strlen(coptlist[i].name);\n    const uint8_t *argptr_trail;\n    if (coptlist[i].type != CONF_FIX)\n      continue;\n    if (strncmp((const char*)argptr, coptlist[i].name, optlen) != 0)\n      continue;\n    argptr_trail = argptr + optlen;\n    while (isspace(*argptr_trail)) argptr_trail++;\n    if (*argptr_trail == 0 || *argptr_trail == '\\n')\n      break;\n    }\n  if (i == COPTLISTCOUNT)\n    {\n    cfprintf(clr_test_error, outfile, \"** Unknown condition: %s\\n\", buffer);\n    return PR_ABEND;\n    }\n\n  /* Condition FALSE - skip this line and everything until #endif. */\n  if ((coptlist[i].value != 0) == if_inverted)\n    yield = PR_ENDIF;\n\n  inside_if = TRUE;\n  break;\n\n  case CMD_ENDIF:\n  if (!inside_if)\n    {\n    cfprintf(clr_test_error, outfile, \"** Unexpected #endif\\n\");\n    return PR_ABEND;\n    }\n  inside_if = FALSE;\n  break;\n  }\n\nreturn yield;\n}\n\n\n\n/*************************************************\n*               Process pattern line             *\n*************************************************/\n\n/* This function is called when the input buffer contains the start of a\npattern. The first character is known to be a valid delimiter. The pattern is\nread, modifiers are interpreted, and a suitable local context is set up for\nthis test. The pattern is then compiled.\n\nArguments:  none\n\nReturns:    PR_OK     continue processing next line\n            PR_SKIP   skip to a blank line\n            PR_ABEND  abort the pcre2test run\n*/\n\nstatic int\nprocess_pattern(void)\n{\nBOOL utf;\nuint32_t k;\nuint8_t *p = buffer;\nunsigned int delimiter = *p++;\nint rc, errorcode;\npcre2_compile_context *use_pat_context;\nPCRE2_SPTR use_pbuffer;\nuint32_t use_forbid_utf = forbid_utf;\nPCRE2_SIZE patlen, full_patlen;\nPCRE2_SIZE valgrind_access_length;\nPCRE2_SIZE erroroffset;\n\n/* The perltest.sh script supports only / as a delimiter. */\n\nif (restrict_for_perl_test && delimiter != '/')\n  {\n  cfprintf(clr_test_error, outfile, \"** The only allowed delimiter after #perltest is '/'\\n\");\n  return PR_ABEND;\n  }\n\n/* Initialize the context and pattern/data controls for this test from the\ndefaults. */\n\nmemcpy(pat_context, default_pat_context, sizeof(pcre2_compile_context));\nmemcpy(&pat_patctl, &def_patctl, sizeof(patctl));\n\n/* Find the end of the pattern, reading more lines if necessary. */\n\nfor(;;)\n  {\n  while (*p != 0)\n    {\n    if (*p == '\\\\' && p[1] != 0) p++;\n      else if (*p == delimiter) break;\n    p++;\n    }\n  if (*p != 0) break;\n  if ((p = extend_inputline(infile, p, \"    > \")) == NULL)\n    {\n    cfprintf(clr_test_error, outfile, \"** Unexpected EOF\\n\");\n    return PR_ABEND;\n    }\n  if (!INTERACTIVE(infile)) cfprintf(clr_input, outfile, \"%s\", (char *)p);\n  }\n\n/* If the first character after the delimiter is backslash, make the pattern\nend with backslash. This is purely to provide a way of testing for the error\nmessage when a pattern ends with backslash. */\n\nif (p[1] == '\\\\') *p++ = '\\\\';\n\n/* Terminate the pattern at the delimiter, and compute the length. */\n\n*p++ = 0;\npatlen = p - buffer - 2;\n\n/* Look for modifiers and options after the final delimiter. */\n\nif (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP;\n\n/* Note that the match_invalid_utf option also sets utf when passed to\npcre2_compile(). */\n\nutf = (pat_patctl.options & (PCRE2_UTF|PCRE2_MATCH_INVALID_UTF)) != 0;\n\n/* The utf8_input modifier is not allowed in 8-bit mode, and is mutually\nexclusive with the utf modifier. */\n\nif ((pat_patctl.control & CTL_UTF8_INPUT) != 0)\n  {\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  cfprintf(clr_test_error, outfile, \"** The utf8_input modifier is not allowed in 8-bit mode\\n\");\n  return PR_SKIP;\n#else\n  if (utf)\n    {\n    cfprintf(clr_test_error, outfile, \"** The utf and utf8_input modifiers are mutually exclusive\\n\");\n    return PR_SKIP;\n    }\n#endif\n  }\n\n/* The convert and posix modifiers are mutually exclusive. */\n\nif (pat_patctl.convert_type != CONVERT_UNSET &&\n    (pat_patctl.control & CTL_POSIX) != 0)\n  {\n  cfprintf(clr_test_error, outfile, \"** The convert and posix modifiers are mutually exclusive\\n\");\n  return PR_SKIP;\n  }\n\n/* Check for mutually exclusive control modifiers. At present, these are all in\nthe first control word. */\n\nfor (k = 0; k < sizeof(exclusive_pat_controls)/sizeof(uint32_t); k++)\n  {\n  uint32_t c = pat_patctl.control & exclusive_pat_controls[k];\n  if (c != 0 && c != (c & (~c+1)))\n    {\n    show_controls(clr_test_error, c, 0, \"** Not allowed together:\");\n    fprintf(outfile, \"\\n\");\n    return PR_SKIP;\n    }\n  }\n\n/* Assume full JIT compile for jitverify and/or jitfast if nothing else was\nspecified. */\n\nif (pat_patctl.jit == 0 &&\n    (pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0)\n  pat_patctl.jit = JIT_DEFAULT;\n\n/* Now copy the pattern to pbuffer8 for use in 8-bit testing. Convert from hex\nif requested (literal strings in quotes may be present within the hexadecimal\npairs). The result must necessarily be fewer characters so will always fit in\npbuffer8. */\n\nif ((pat_patctl.control & CTL_HEXPAT) != 0)\n  {\n  uint8_t *pp, *pt;\n  uint32_t c, d;\n\n  pt = pbuffer8;\n  for (pp = buffer + 1; *pp != 0; pp++)\n    {\n    if (isspace(*pp)) continue;\n    c = *pp++;\n\n    /* Handle a literal substring */\n\n    if (c == '\\'' || c == '\"')\n      {\n      uint8_t *pq = pp;\n      for (;; pp++)\n        {\n        d = *pp;\n        if (d == 0)\n          {\n          cfprintf(clr_test_error, outfile, \"** Missing closing quote in hex pattern: \"\n            \"opening quote is at offset %\" PTR_FORM \".\\n\", pq - buffer - 2);\n          return PR_SKIP;\n          }\n        if (d == c) break;\n        *pt++ = d;\n        }\n      }\n\n    /* Expect a hex pair */\n\n    else\n      {\n      if (!isxdigit(c))\n        {\n        cfprintf(clr_test_error, outfile, \"** Unexpected non-hex-digit '%c' at offset %\"\n          PTR_FORM \" in hex pattern: quote missing?\\n\", c, pp - buffer - 2);\n        return PR_SKIP;\n        }\n      if (*pp == 0)\n        {\n        cfprintf(clr_test_error, outfile, \"** Odd number of digits in hex pattern\\n\");\n        return PR_SKIP;\n        }\n      d = *pp;\n      if (!isxdigit(d))\n        {\n        cfprintf(clr_test_error, outfile, \"** Unexpected non-hex-digit '%c' at offset %\"\n          PTR_FORM \" in hex pattern: quote missing?\\n\", d, pp - buffer - 1);\n        return PR_SKIP;\n        }\n      c = toupper(c);\n      d = toupper(d);\n      c = isdigit(c)? (c - '0') : (c - 'A' + 10);\n      d = isdigit(d)? (d - '0') : (d - 'A' + 10);\n      *pt++ = CHAR_OUTPUT(CHAR_INPUT_HEX((c << 4) + d));\n      }\n    }\n  *pt = 0;\n  patlen = pt - pbuffer8;\n  }\n\n/* If not a hex string, process for repetition expansion if requested. */\n\nelse if ((pat_patctl.control & CTL_EXPAND) != 0)\n  {\n  uint8_t *pp, *pt;\n\n  pt = pbuffer8;\n  for (pp = buffer + 1; *pp != 0; pp++)\n    {\n    uint8_t *pc = pp;\n    uint32_t count = 1;\n    size_t length = 1;\n\n    /* Check for replication syntax; if not found, the defaults just set will\n    prevail and one character will be copied. */\n\n    if (pp[0] == '\\\\' && pp[1] == '[')\n      {\n      uint8_t *pe;\n      for (pe = pp + 2; *pe != 0; pe++)\n        {\n        if (pe[0] == ']' && pe[1] == '{')\n          {\n          size_t clen = pe - pc - 2;\n          uint32_t i = 0;\n          unsigned long uli;\n          char *endptr;\n\n          pe += 2;\n          uli = strtoul((const char *)pe, &endptr, 10);\n          if (U32OVERFLOW(uli))\n            {\n            cfprintf(clr_test_error, outfile, \"** Pattern repeat count too large\\n\");\n            return PR_SKIP;\n            }\n\n          i = (uint32_t)uli;\n          pe = (uint8_t *)endptr;\n          if (*pe == '}')\n            {\n            if (i == 0)\n              {\n              cfprintf(clr_test_error, outfile, \"** Zero repeat not allowed\\n\");\n              return PR_SKIP;\n              }\n            pc += 2;\n            count = i;\n            length = clen;\n            pp = pe;\n            break;\n            }\n          }\n        }\n      }\n\n    /* Add to output. If the buffer is too small expand it. The function for\n    expanding buffers always keeps buffer and pbuffer8 in step as far as their\n    size goes. */\n\n    while (pt + count * length > pbuffer8 + pbuffer8_size)\n      {\n      size_t pc_offset = pc - buffer;\n      size_t pp_offset = pp - buffer;\n      size_t pt_offset = pt - pbuffer8;\n      expand_input_buffers();\n      pc = buffer + pc_offset;\n      pp = buffer + pp_offset;\n      pt = pbuffer8 + pt_offset;\n      }\n\n    for (; count > 0; count--)\n      {\n      memcpy(pt, pc, length);\n      pt += length;\n      }\n    }\n\n  *pt = 0;\n  patlen = pt - pbuffer8;\n\n  if ((pat_patctl.control & CTL_INFO) != 0)\n    fprintf(outfile, \"Expanded: %s\\n\", pbuffer8);\n  }\n\n/* Neither hex nor expanded, just copy the input verbatim. */\n\nelse\n  {\n  strncpy((char *)pbuffer8, (char *)(buffer+1), patlen + 1);\n  }\n\n/* Sort out character tables */\n\nif (pat_patctl.locale[0] != MOD_STR_UNSET)\n  {\n  if (pat_patctl.tables_id != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** 'Locale' and 'tables' must not both be set\\n\");\n    return PR_SKIP;\n    }\n  if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale+1) == NULL)\n    {\n    cfprintf(clr_test_error, outfile, \"** Failed to set locale \\\"%s\\\"\\n\", pat_patctl.locale+1);\n    return PR_SKIP;\n    }\n  if (strcmp((const char *)pat_patctl.locale+1, (const char *)locale_name) != 0)\n    {\n    strncpy((char *)locale_name, (char *)pat_patctl.locale + 1, sizeof(locale_name));\n    locale_name[sizeof(locale_name) - 1] = '\\0';\n    if (locale_tables != NULL)\n      {\n      pcre2_maketables_free(general_context, locale_tables);\n      }\n    locale_tables = pcre2_maketables(general_context);\n    }\n  use_tables = locale_tables;\n  }\n\nelse switch (pat_patctl.tables_id)\n  {\n  case 0: use_tables = NULL; break;\n  case 1: use_tables = tables1; break;\n  case 2: use_tables = tables2; break;\n\n  case 3:\n  if (tables3 == NULL)\n    {\n    cfprintf(clr_test_error, outfile, \"** 'Tables = 3' is invalid: binary tables have not \"\n      \"been loaded\\n\");\n    return PR_SKIP;\n    }\n  use_tables = tables3;\n  break;\n\n  default:\n  cfprintf(clr_test_error, outfile, \"** 'Tables' must specify 0, 1, 2, or 3.\\n\");\n  return PR_SKIP;\n  }\n\npcre2_set_character_tables(pat_context, use_tables);\n\n/* Set up for the stackguard test. */\n\nif (pat_patctl.stackguard_test != 0)\n  {\n  pcre2_set_compile_recursion_guard(pat_context, stack_guard, NULL);\n  }\n\n/* Handle compiling via the POSIX interface, which doesn't support the\ntiming, showing, or debugging options, nor the ability to pass over\nlocal character tables. Neither does it have 16-bit or 32-bit support. */\n\nif ((pat_patctl.control & CTL_POSIX) != 0)\n  {\n#if PCRE2_CODE_UNIT_WIDTH != 8\n  cfprintf(clr_test_error, outfile, \"** The POSIX interface is available only in 8-bit mode\\n\");\n  return PR_SKIP;\n\n#else\n  int cflags = 0;\n  const char *msg = \"** Ignored with POSIX interface:\";\n\n  /* Check for features that the POSIX interface does not support. */\n\n  if (pat_patctl.locale[0] != MOD_STR_UNSET) prmsg(&msg, \"locale\");\n  if (pat_patctl.replacement[0] != MOD_STR_UNSET) prmsg(&msg, \"replace\");\n  if (pat_patctl.tables_id != 0) prmsg(&msg, \"tables\");\n  if (pat_patctl.stackguard_test != 0) prmsg(&msg, \"stackguard\");\n  if (timeit > 0) prmsg(&msg, \"timing\");\n  if (pat_patctl.jit != 0) prmsg(&msg, \"JIT\");\n\n  if ((pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS) != 0)\n    {\n    show_compile_options(\n      clr_test_error,\n      pat_patctl.options & (uint32_t)(~POSIX_SUPPORTED_COMPILE_OPTIONS),\n      msg, \"\");\n    msg = \"\";\n    }\n\n  if ((pat_context->extra_options &\n       (uint32_t)(~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS)) != 0)\n    {\n    show_compile_extra_options(\n      clr_test_error,\n      pat_context->extra_options &\n        (uint32_t)(~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS),\n      msg, \"\");\n    msg = \"\";\n    }\n\n  if ((pat_patctl.control & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS)) != 0 ||\n      (pat_patctl.control2 & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS2)) != 0)\n    {\n    show_controls(\n      clr_test_error,\n      pat_patctl.control & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS),\n      pat_patctl.control2 & (uint32_t)(~POSIX_SUPPORTED_COMPILE_CONTROLS2),\n      msg);\n    msg = \"\";\n\n    /* Remove ignored options so as not to get a repeated message for those\n    that are actually subject controls. */\n\n    pat_patctl.control &= (uint32_t)(POSIX_SUPPORTED_COMPILE_CONTROLS);\n    pat_patctl.control2 &= (uint32_t)(POSIX_SUPPORTED_COMPILE_CONTROLS2);\n    }\n\n  if (local_newline_default != 0) prmsg(&msg, \"#newline_default\");\n  if (pat_context->max_pattern_length != PCRE2_UNSET)\n    prmsg(&msg, \"max_pattern_length\");\n  if (pat_context->max_pattern_compiled_length != PCRE2_UNSET)\n    prmsg(&msg, \"max_pattern_compiled_length\");\n  if (pat_context->parens_nest_limit != PARENS_NEST_DEFAULT)\n    prmsg(&msg, \"parens_nest_limit\");\n\n  if (msg[0] == 0) fprintf(outfile, \"\\n\");\n\n  /* Translate PCRE2 options to POSIX options and then compile. */\n\n  if (utf) cflags |= REG_UTF;\n  if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) cflags |= REG_NOSUB;\n  if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP;\n  if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE;\n  if ((pat_patctl.options & PCRE2_LITERAL) != 0) cflags |= REG_NOSPEC;\n  if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE;\n  if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL;\n  if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY;\n\n  if ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) != 0)\n    {\n    preg.re_endp = (char *)pbuffer8 + patlen;\n    cflags |= REG_PEND;\n    }\n\n#if defined(EBCDIC) && !EBCDIC_IO\n  ascii_to_ebcdic_str(pbuffer8, patlen);\n#endif\n\n  rc = regcomp(&preg, (char *)pbuffer8, cflags);\n\n  /* Compiling failed */\n\n  if (rc != 0)\n    {\n    char *regbuffer;\n    size_t bsize, usize, strsize;\n\n    preg.re_pcre2_code = NULL;     /* In case something was left in there */\n    preg.re_match_data = NULL;\n\n    bsize = (pat_patctl.regerror_buffsize >= 0 &&\n             (unsigned)pat_patctl.regerror_buffsize <= pbuffer8_size)?\n      (unsigned)pat_patctl.regerror_buffsize : pbuffer8_size;\n    regbuffer = (char *)pbuffer8 + (pbuffer8_size - bsize);\n    usize = regerror(rc, &preg, regbuffer, bsize);\n    strsize = ((usize > bsize)? bsize : usize) - 1;\n\n    cfprintf(clr_api_error, outfile, \"Failed: POSIX code %d: \", rc);\n    if (bsize > 0) pchars(clr_api_error, (PCRE2_SPTR8)regbuffer, strsize, utf, outfile);\n    fputs(\"\\n\", outfile);\n    if (usize > bsize)\n      {\n      cfprintf(clr_test_error, outfile, \"** regerror() message truncated\\n\");\n      }\n    if (bsize > 0 && strlen(regbuffer) != strsize)\n      {\n      cfprintf(clr_test_error, outfile, \"** regerror() strlen incorrect\\n\");\n      return PR_ABEND;\n      }\n    return PR_SKIP;\n    }\n\n  /* Compiling succeeded. Check that the values in the preg block are sensible.\n  It can happen that pcre2test is accidentally linked with a different POSIX\n  library which succeeds, but of course puts different things into preg. In\n  this situation, calling regfree() may cause a segfault (or invalid free() in\n  valgrind), so ensure that preg.re_pcre2_code is NULL, which suppresses the\n  calling of regfree() on exit. */\n\n  if (preg.re_pcre2_code == NULL ||\n      ((pcre2_real_code_8 *)preg.re_pcre2_code)->magic_number != MAGIC_NUMBER ||\n      ((pcre2_real_code_8 *)preg.re_pcre2_code)->top_bracket != preg.re_nsub ||\n      preg.re_match_data == NULL ||\n      preg.re_cflags != cflags)\n    {\n    cfprintf(clr_test_error, outfile,\n      \"** The regcomp() function returned zero (success), but the values set\\n\"\n      \"** in the preg block are not valid for PCRE2. Check that pcre2test is\\n\"\n      \"** linked with PCRE2's pcre2posix module (-lpcre2-posix) and not with\\n\"\n      \"** some other POSIX regex library.\\n**\\n\");\n    preg.re_pcre2_code = NULL;\n    return PR_ABEND;\n    }\n\n  return PR_OK;\n#endif  /* PCRE2_CODE_UNIT_WIDTH != 8 */\n  }\n\n/* Handle compiling via the native interface. Controls that act later are\nignored with \"push\". Replacements are locked out. */\n\nif ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)\n  {\n  if (pat_patctl.replacement[0] != MOD_STR_UNSET)\n    {\n    cfprintf(clr_test_error, outfile, \"** Replacement text is not supported with 'push'.\\n\");\n    return PR_OK;\n    }\n  if ((pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS) != 0 ||\n      (pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2) != 0)\n    {\n    show_controls(clr_test_error, pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS,\n                  pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2,\n      \"** Ignored when compiled pattern is stacked with 'push':\");\n    fprintf(outfile, \"\\n\");\n    }\n  if ((pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS) != 0 ||\n      (pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2) != 0)\n    {\n    show_controls(clr_test_error, pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS,\n                  pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2,\n      \"** Applies only to compile when pattern is stacked with 'push':\");\n    fprintf(outfile, \"\\n\");\n    }\n  }\n\n/* Convert the input in non-8-bit modes. */\n\nerrorcode = 0;\n\n#if defined(EBCDIC) && !EBCDIC_IO\nascii_to_ebcdic_str(pbuffer8, patlen);\n#endif\n\n#if PCRE2_CODE_UNIT_WIDTH != 8\nerrorcode = G(to,PCRE2_CODE_UNIT_WIDTH)(pbuffer8, utf, &patlen);\nswitch(errorcode)\n  {\n  case -1:\n  cfprintf(clr_test_error, outfile, \"** Failed: invalid UTF-8 string cannot be \"\n    \"converted to \" STR(PCRE2_CODE_UNIT_WIDTH) \"-bit string\\n\");\n  return PR_SKIP;\n\n  case -2:\n  cfprintf(clr_test_error, outfile, \"** Failed: character value greater than 0x10ffff \"\n    \"cannot be converted to UTF\\n\");\n  return PR_SKIP;\n\n  case -3:\n  cfprintf(clr_test_error, outfile, \"** Failed: character value greater than 0xffff \"\n    \"cannot be converted to 16-bit in non-UTF mode\\n\");\n  return PR_SKIP;\n\n  default:\n  break;\n  }\n#endif\n\n/* When valgrind is supported, detect accesses to the 8-bit buffer now that we\nhave finished with it. */\n\n#if defined SUPPORT_VALGRIND && PCRE2_CODE_UNIT_WIDTH != 8\nVALGRIND_MAKE_MEM_UNDEFINED(pbuffer8, pbuffer8_size);\n#endif\n\n/* The pattern is now in pbuffer[8|16|32], with the length in code units in\npatlen. If it is to be converted, copy the result back afterwards so that it\nends up back in the usual place. */\n\nif (pat_patctl.convert_type != CONVERT_UNSET)\n  {\n  int convert_return = PR_OK;\n  uint32_t convert_options = pat_patctl.convert_type;\n  PCRE2_UCHAR *converted_pattern;\n  PCRE2_SIZE converted_length = JUNK_OFFSET;\n  BOOL zero_terminate;\n\n  if (pat_patctl.convert_length != CONVERT_UNSET)\n    {\n    converted_length = pat_patctl.convert_length;\n    converted_pattern = malloc(converted_length? CU2BYTES(converted_length) : 1);\n    if (converted_pattern == NULL)\n      {\n      cfprintf(clr_test_error, outfile, \"** Failed: malloc failed for converted pattern\\n\");\n      return PR_ABEND;\n      }\n    }\n  else converted_pattern = NULL;  /* Let the library allocate */\n\n  if (utf) convert_options |= PCRE2_CONVERT_UTF;\n  if ((pat_patctl.options & PCRE2_NO_UTF_CHECK) != 0)\n    convert_options |= PCRE2_CONVERT_NO_UTF_CHECK;\n\n  memcpy(con_context, default_con_context, sizeof(pcre2_convert_context));\n\n  if (pat_patctl.convert_glob_escape != 0)\n    {\n    uint32_t escape = (pat_patctl.convert_glob_escape == '0')? 0 :\n      pat_patctl.convert_glob_escape;\n    rc = pcre2_set_glob_escape(con_context, CHAR_INPUT(escape));\n    if (rc != 0)\n      {\n      cfprintf(clr_test_error, outfile, \"** Invalid glob escape '%c'\\n\",\n        pat_patctl.convert_glob_escape);\n      convert_return = PR_SKIP;\n      goto CONVERT_FINISH;\n      }\n    }\n\n  if (pat_patctl.convert_glob_separator != 0)\n    {\n    uint32_t separator = pat_patctl.convert_glob_separator;\n    rc = pcre2_set_glob_separator(con_context, CHAR_INPUT(separator));\n    if (rc != 0)\n      {\n      cfprintf(clr_test_error, outfile, \"** Invalid glob separator '%c'\\n\",\n        pat_patctl.convert_glob_separator);\n      convert_return = PR_SKIP;\n      goto CONVERT_FINISH;\n      }\n    }\n\n  /* Set up the input buffer in the same way as for pcre2_compile() below. */\n\n  zero_terminate = (pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) == 0;\n\n#ifdef SUPPORT_VALGRIND\n  VALGRIND_MAKE_MEM_NOACCESS(pbuffer + CU2BYTES(patlen + zero_terminate),\n    pbuffer_size - CU2BYTES(patlen + zero_terminate));\n#endif\n\n  if (zero_terminate) patlen = PCRE2_ZERO_TERMINATED;\n  use_pbuffer = ((pat_patctl.control2 & CTL2_NULL_PATTERN) == 0)? pbuffer : NULL;\n\n  rc = pcre2_pattern_convert(use_pbuffer, patlen, convert_options,\n    &converted_pattern, &converted_length, con_context);\n\n#ifdef SUPPORT_VALGRIND\n  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer, pbuffer_size);\n#endif\n\n  if (rc != 0)\n    {\n    cfprintf(clr_api_error, outfile, \"** Pattern conversion error at offset %\" SIZ_FORM \": \",\n      converted_length);\n    convert_return = print_error_message(rc, \"\", \"\\n\")? PR_SKIP:PR_ABEND;\n    }\n\n  /* Output the converted pattern, then copy it. */\n\n  else\n    {\n    pchars(clr_none, converted_pattern, converted_length, utf, outfile);\n    fprintf(outfile, \"\\n\");\n\n    if (CU2BYTES(converted_length + 1) > pbuffer_size)\n      {\n      // TODO This seems... unfortunate? There must be some patterns that can\n      // expand when converted from glob to regex, but we aren't allowing for\n      // that here. Presumably we should expand the buffer rather than moan.\n      cfprintf(clr_test_error, outfile, \"** Pattern conversion is too long for the buffer\\n\");\n      convert_return = PR_SKIP;\n      }\n    else\n      {\n      memcpy(pbuffer, converted_pattern, CU2BYTES(converted_length + 1));\n      patlen = converted_length;\n      }\n    }\n\n  /* Free the converted pattern. */\n\n  CONVERT_FINISH:\n  if (pat_patctl.convert_length != CONVERT_UNSET)\n    free(converted_pattern);\n  else\n    pcre2_converted_pattern_free(converted_pattern);\n\n  /* Return if conversion was unsuccessful. */\n\n  if (convert_return != PR_OK) return convert_return;\n  }\n\n/* By default we pass a zero-terminated pattern, but a length is passed if\n\"use_length\" was specified or this is a hex pattern (which might contain binary\nzeros). When valgrind is supported, arrange for the unused part of the buffer\nto be marked as no-access. */\n\nfull_patlen = patlen;\nvalgrind_access_length = patlen;\nif ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) == 0)\n  {\n  patlen = PCRE2_ZERO_TERMINATED;\n  valgrind_access_length += 1;  /* For the terminating zero */\n  }\n\n#ifdef SUPPORT_VALGRIND\nVALGRIND_MAKE_MEM_NOACCESS(pbuffer + valgrind_access_length,\n  pbuffer_size - CU2BYTES(valgrind_access_length));\n#else  /* Valgrind not supported */\n(void)valgrind_access_length;  /* Avoid compiler warning */\n#endif\n\n/* If #newline_default has been used and the library was not compiled with an\nappropriate default newline setting, local_newline_default will be non-zero. We\nuse this if there is no explicit newline modifier. */\n\nif ((pat_patctl.control2 & CTL2_NL_SET) == 0 && local_newline_default != 0)\n  {\n  pcre2_set_newline(pat_context, local_newline_default);\n  }\n\n/* The null_context modifier is used to test calling pcre2_compile() with a\nNULL context. */\n\nuse_pat_context = ((pat_patctl.control & CTL_NULLCONTEXT) != 0)?\n  NULL : pat_context;\n\n/* If PCRE2_LITERAL is set, set use_forbid_utf zero because PCRE2_NEVER_UTF\nand PCRE2_NEVER_UCP are invalid with it. */\n\nif ((pat_patctl.options & PCRE2_LITERAL) != 0) use_forbid_utf = 0;\n\n/* Set use_pbuffer to the input buffer or NULL as requested. */\n\nuse_pbuffer = ((pat_patctl.control2 & CTL2_NULL_PATTERN) == 0)? pbuffer : NULL;\n\n/* Compile many times when timing. */\n\nif (timeit > 0)\n  {\n  int i;\n  clock_t time_taken = 0;\n  for (i = 0; i < timeit; i++)\n    {\n    clock_t start_time = clock();\n    compiled_code = pcre2_compile(use_pbuffer, patlen,\n      pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,\n        use_pat_context);\n    time_taken += clock() - start_time;\n    if (compiled_code != NULL)\n      pcre2_code_free(compiled_code);\n    }\n  total_compile_time += time_taken;\n  cfprintf(clr_profiling, outfile, \"Compile time %8.4f microseconds\\n\",\n    ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);\n  }\n\n/* A final compile that is used \"for real\". */\n\nmallocs_called = 0;\ncompiled_code = pcre2_compile(use_pbuffer, patlen,\n  pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset, use_pat_context);\n\n/* For malloc testing, we repeat the compilation. */\n\nif (malloc_testing)\n  {\n  for (int i = 0, target_mallocs = mallocs_called; i <= target_mallocs; i++)\n    {\n    if (compiled_code != NULL)\n      pcre2_code_free(compiled_code);\n\n    errorcode = 0;\n    erroroffset = 0;\n    mallocs_until_failure = i;\n    compiled_code = pcre2_compile(use_pbuffer, patlen,\n      pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset, use_pat_context);\n    mallocs_until_failure = INT_MAX;\n\n    if (i < target_mallocs &&\n        !(compiled_code == NULL && errorcode == PCRE2_ERROR_HEAP_FAILED))\n      {\n      cfprintf(clr_test_error, outfile, \"** malloc() compile test did not fail as expected (%d)\\n\",\n              errorcode);\n      return PR_ABEND;\n      }\n    }\n  }\n\n/* If valgrind is supported, mark the pbuffer as accessible again. We leave the\npattern in the test-mode's buffer defined because it may be read from a callout\nduring matching. */\n\n#ifdef SUPPORT_VALGRIND\nVALGRIND_MAKE_MEM_UNDEFINED(pbuffer + valgrind_access_length,\n  pbuffer_size - CU2BYTES(valgrind_access_length));\n#endif\n\n/* Call the JIT compiler if requested. When timing, or testing malloc failures,\nwe must free and recompile the pattern each time because that is the only way to\nfree the JIT compiled code. We know that compilation will always succeed. */\n\nif (compiled_code != NULL && pat_patctl.jit != 0)\n  {\n  if (timeit > 0)\n    {\n    int i;\n    clock_t time_taken = 0;\n\n    for (i = 0; i < timeit; i++)\n      {\n      clock_t start_time = clock();\n      jitrc = pcre2_jit_compile(compiled_code, pat_patctl.jit);\n      time_taken += clock() - start_time;\n\n      pcre2_code_free(compiled_code);\n      compiled_code = pcre2_compile(use_pbuffer, patlen,\n        pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,\n        use_pat_context);\n      if (compiled_code == NULL)\n        {\n        cfprintf(clr_test_error, outfile, \"** Unexpected - pattern compilation not successful\\n\");\n        return PR_ABEND;\n        }\n\n      if (jitrc != 0)\n        {\n        cfprintf(clr_api_error, outfile, \"JIT compilation was not successful\");\n        if (!print_error_message(jitrc, \" (\", \")\\n\")) return PR_ABEND;\n        break;\n        }\n      }\n    total_jit_compile_time += time_taken;\n    if (jitrc == 0)\n      cfprintf(clr_profiling, outfile, \"JIT compile  %8.4f microseconds\\n\",\n        ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);\n    }\n\n  mallocs_called = 0;\n  jitrc = pcre2_jit_compile(compiled_code, pat_patctl.jit);\n\n  /* For malloc testing, we repeat the compilation. */\n\n  if (malloc_testing)\n    {\n    for (int i = 0, target_mallocs = mallocs_called; i <= target_mallocs; i++)\n      {\n      pcre2_code_free(compiled_code);\n      compiled_code = pcre2_compile(use_pbuffer, patlen,\n        pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,\n        use_pat_context);\n      if (compiled_code == NULL)\n        {\n        cfprintf(clr_test_error, outfile, \"** Unexpected - pattern compilation not successful\\n\");\n        return PR_ABEND;\n        }\n\n      mallocs_until_failure = i;\n      jitrc = pcre2_jit_compile(compiled_code, pat_patctl.jit);\n      mallocs_until_failure = INT_MAX;\n\n      if (i < target_mallocs && jitrc != PCRE2_ERROR_NOMEMORY)\n        {\n        cfprintf(clr_test_error, outfile, \"** malloc() JIT compile test did not fail as expected (%d)\\n\",\n                jitrc);\n        return PR_ABEND;\n        }\n      }\n    }\n\n  /* Check whether JIT compilation failed; but continue with an error message\n  if not. */\n\n  if (jitrc != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)\n    {\n    cfprintf(clr_api_error, outfile, \"JIT compilation was not successful\");\n    if (!print_error_message(jitrc, \" (\", \")\\n\")) return PR_ABEND;\n    }\n  }\n\n/* Compilation failed; go back for another re, skipping to blank line\nif non-interactive. */\n\nif (compiled_code == NULL)\n  {\n  int direction = error_direction(errorcode, erroroffset);\n\n  cfprintf(clr_api_error, outfile, \"Failed: error %d at offset %d: \", errorcode,\n    (int)erroroffset);\n  if (!print_error_message(errorcode, \"\", \"\\n\")) return PR_ABEND;\n\n  /* It's important that the erroroffset doesn't slice halfway through a UTF-8\n  or UTF-16 character. We can verify this by checking that the input left of the\n  erroroffset is valid. Note that if the input is invalid (which is exercised in\n  some tests) then the offset will be positioned with the valid part to the left\n  of erroroffset. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16\n  if (utf)\n    {\n    uint32_t cc;\n    int n = 1;\n    for (PCRE2_UCHAR *q = pbuffer, *q_end = q + erroroffset; q < q_end && n > 0; q += n)\n      n = utf_to_ord(q, q_end, &cc);\n    if (n <= 0)\n      {\n      cfprintf(clr_test_error, outfile, \"** Erroroffset %d splits a UTF character\\n\", (int)erroroffset);\n      return PR_ABEND;\n      }\n    }\n#endif\n\n  /* Print the surrounding context around the erroroffset. */\n\n  if (direction < 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Error code %d not implemented in error_direction().\\n\", errorcode);\n    cfprintf(clr_test_error, outfile, \"   error_direction() should usually return '1' for newly-added errors,\\n\");\n    cfprintf(clr_test_error, outfile, \"   and the offset should be just to the right of the bad character.\\n\");\n    return PR_ABEND;\n    }\n\n  else if (direction != 0)\n    {\n    cfprintf(clr_api_error, outfile, \"        here: \");\n    if (erroroffset > 0)\n      {\n      ptrunc(clr_input, pbuffer, full_patlen, erroroffset, TRUE, utf, outfile);\n      fprintf(outfile, \" \");\n      }\n    cfprintf(clr_api_error, outfile, (direction == 1)? \"|<--|\" : (direction == 2)? \"|-->|\" : \"|<-->|\");\n    if (erroroffset < full_patlen)\n      {\n      fprintf(outfile, \" \");\n      ptrunc(clr_input, pbuffer, full_patlen, erroroffset, FALSE, utf, outfile);\n      }\n    fprintf(outfile, \"\\n\");\n    }\n\n  else if (erroroffset != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Unexpected non-zero erroroffset %d for error code %d\\n\",\n      (int)erroroffset, errorcode);\n    return PR_ABEND;\n    }\n\n  return PR_SKIP;\n  }\n\n/* If forbid_utf is non-zero, we are running a non-UTF test. UTF and UCP are\nlocked out at compile time, but we must also check for occurrences of \\P, \\p,\nand \\X, which are only supported when Unicode is supported. */\n\nif (forbid_utf != 0)\n  {\n  if ((compiled_code->flags & PCRE2_HASBKPORX) != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** \\\\P, \\\\p, and \\\\X are not allowed after the \"\n      \"#forbid_utf command\\n\");\n    return PR_SKIP;\n    }\n  }\n\n/* Remember the maximum lookbehind, for partial matching. */\n\nif (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0)\n  return PR_ABEND;\n\n/* Remember the number of captures. */\n\nif (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0)\n  return PR_ABEND;\n\n/* If an explicit newline modifier was given, set the information flag in the\npattern so that it is preserved over push/pop. */\n\nif ((pat_patctl.control2 & CTL2_NL_SET) != 0)\n  {\n  compiled_code->flags |= PCRE2_NL_SET;\n  }\n\n/* Output code size and other information if requested. */\n\nrc = show_pattern_info();\nif (rc != PR_OK) return rc;\n\n/* The \"push\" control requests that the compiled pattern be remembered on a\nstack. This is mainly for testing the serialization functionality. */\n\nif ((pat_patctl.control & CTL_PUSH) != 0)\n  {\n  if (patstacknext >= PATSTACKSIZE)\n    {\n    cfprintf(clr_test_error, outfile, \"** Too many pushed patterns (max %d)\\n\", PATSTACKSIZE);\n    return PR_ABEND;\n    }\n  patstack[patstacknext++] = compiled_code;\n  compiled_code = NULL;\n  }\n\n/* The \"pushcopy\" and \"pushtablescopy\" controls are similar, but push a\ncopy of the pattern, the latter with a copy of its character tables. This tests\nthe pcre2_code_copy() and pcre2_code_copy_with_tables() functions. */\n\nif ((pat_patctl.control & (CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)\n  {\n  if (patstacknext >= PATSTACKSIZE)\n    {\n    cfprintf(clr_test_error, outfile, \"** Too many pushed patterns (max %d)\\n\", PATSTACKSIZE);\n    return PR_ABEND;\n    }\n  if ((pat_patctl.control & CTL_PUSHCOPY) != 0)\n    {\n    patstack[patstacknext++] = pcre2_code_copy(compiled_code);\n    }\n  else\n    {\n    patstack[patstacknext++] = pcre2_code_copy_with_tables(compiled_code);\n    }\n  }\n\nreturn PR_OK;\n}\n\n\n\n/* Helper to test for an active pattern. */\n\nstatic BOOL\nhave_active_pattern(void)\n{\nreturn compiled_code != NULL;\n}\n\n\n/* Helper to free (and null-out) the active pattern. Safe to call even if there\nis no active pattern. */\n\nstatic void\nfree_active_pattern(void)\n{\npcre2_code_free(compiled_code);\ncompiled_code = NULL;\n}\n\n\n\n/*************************************************\n*          Check heap, match or depth limit      *\n*************************************************/\n\n/* This is used for DFA, normal, and JIT fast matching. For DFA matching it\nshould only be called with the third argument set to PCRE2_ERROR_DEPTHLIMIT.\n\nArguments:\n  pp        the subject string\n  ulen      length of subject or PCRE2_ZERO_TERMINATED\n  errnumber defines which limit to test\n  msg       string to include in final message\n\nReturns:    the return from the final match function call\n*/\n\nstatic int\ncheck_match_limit(PCRE2_SPTR pp, PCRE2_SIZE ulen, int errnumber, const char *msg)\n{\nint capcount;\nuint32_t min = 0;\nuint32_t mid = 64;\nuint32_t max = UINT32_MAX;\nFILE *saved_outfile = outfile;\n\npcre2_set_match_limit(dat_context, max);\npcre2_set_depth_limit(dat_context, max);\npcre2_set_heap_limit(dat_context, max);\n\nfor (;;)\n  {\n  uint32_t stack_start = 0;\n\n  /* If we are checking the heap limit, free any frames vector that is cached\n  in the match_data so we always start without one. */\n\n  if (errnumber == PCRE2_ERROR_HEAPLIMIT)\n    {\n    pcre2_set_heap_limit(dat_context, mid);\n\n    match_data->memctl.free(match_data->heapframes,\n      match_data->memctl.memory_data);\n    match_data->heapframes = NULL;\n    match_data->heapframes_size = 0;\n    }\n\n  /* No need to mess with the frames vector for match or depth limits. */\n\n  else if (errnumber == PCRE2_ERROR_MATCHLIMIT)\n    {\n    pcre2_set_match_limit(dat_context, mid);\n    }\n  else\n    {\n    pcre2_set_depth_limit(dat_context, mid);\n    }\n\n  /* Do the appropriate match */\n\n  reset_callout_state();\n  outfile = NULL;  /* Suppress callout output during the repeated search */\n\n  if ((dat_datctl.control & CTL_DFA) != 0)\n    {\n    stack_start = DFA_START_RWS_SIZE/1024;\n    if (dfa_workspace == NULL)\n      dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));\n    if (dfa_matched++ == 0)\n      dfa_workspace[0] = -1;  /* To catch bad restart */\n    capcount = pcre2_dfa_match(compiled_code, pp, ulen, dat_datctl.offset,\n      dat_datctl.options, match_data,\n      dat_context, dfa_workspace, DFA_WS_DIMENSION);\n    }\n\n  else if ((pat_patctl.control & CTL_JITFAST) != 0)\n    capcount = pcre2_jit_match(compiled_code, pp, ulen, dat_datctl.offset,\n      dat_datctl.options, match_data, dat_context);\n\n  else\n    {\n    capcount = pcre2_match(compiled_code, pp, ulen, dat_datctl.offset,\n      dat_datctl.options, match_data, dat_context);\n    }\n\n  outfile = saved_outfile;\n\n  if (capcount == errnumber)\n    {\n    if ((mid & 0x80000000u) != 0)\n      {\n      cfprintf(clr_test_error, outfile, \"** Can't find minimum %s limit: check pattern for \"\n        \"restriction\\n\", msg);\n      break;\n      }\n\n    min = mid;\n    mid = (mid == max - 1)? max : (max != UINT32_MAX)? (min + max)/2 : mid*2;\n    }\n  else if (capcount >= 0 ||\n           capcount == PCRE2_ERROR_NOMATCH ||\n           capcount == PCRE2_ERROR_PARTIAL)\n    {\n    /* If we've not hit the error with a heap limit less than the size of the\n    initial stack frame vector (for pcre2_match()) or the initial stack\n    workspace vector (for pcre2_dfa_match()), the heap is not being used, so\n    the minimum limit is zero; there's no need to go on. The other limits are\n    always greater than zero. */\n\n    if (errnumber == PCRE2_ERROR_HEAPLIMIT && mid < stack_start)\n      {\n      fprintf(outfile, \"Minimum %s limit = 0\\n\", msg);\n      break;\n      }\n    if (mid == min + 1)\n      {\n      fprintf(outfile, \"Minimum %s limit = %d\\n\", msg, mid);\n      break;\n      }\n    max = mid;\n    mid = (min + max)/2;\n    }\n  else break;    /* Some other error */\n  }\n\nreturn capcount;\n}\n\n\n\n/*************************************************\n*        Substitute callout function             *\n*************************************************/\n\n/* Called from pcre2_substitute() when the substitute_callout modifier is set.\nPrint out the data that is passed back.\n\nArguments:\n  scb         pointer to substitute callout block\n  data_ptr    callout data\n\nReturns:      nothing\n*/\n\nstatic int\nsubstitute_callout_function(pcre2_substitute_callout_block *scb,\n  void *data_ptr)\n{\nint yield = 0;\nBOOL utf = (compiled_code->overall_options & PCRE2_UTF) != 0;\n(void)data_ptr;   /* Not used */\n\nif (outfile == NULL) goto YIELD;\n\nfprintf(outfile, \"%2d(%d) Old %\" SIZ_FORM \" %\" SIZ_FORM \" \\\"\",\n  scb->subscount, scb->oveccount,\n  scb->ovector[0], scb->ovector[1]);\n\npchars(clr_none, scb->input + scb->ovector[0], scb->ovector[1] - scb->ovector[0],\n  utf, outfile);\n\nfprintf(outfile, \"\\\" New %\" SIZ_FORM \" %\" SIZ_FORM \" \\\"\",\n  scb->output_offsets[0], scb->output_offsets[1]);\n\npchars(clr_none, scb->output + scb->output_offsets[0],\n  scb->output_offsets[1] - scb->output_offsets[0], utf, outfile);\n\nYIELD:\n\nif (scb->subscount == dat_datctl.substitute_stop)\n  {\n  yield = -1;\n  if (outfile != NULL) fprintf(outfile, \" STOPPED\");\n  }\nelse if (scb->subscount == dat_datctl.substitute_skip)\n  {\n  yield = +1;\n  if (outfile != NULL) fprintf(outfile, \" SKIPPED\");\n  }\n\nif (outfile != NULL) fprintf(outfile, \"\\\"\\n\");\nreturn yield;\n}\n\n\n\n/*************************************************\n*        Substitute case callout function        *\n*************************************************/\n\n/* Called from pcre2_substitute() when the substitute_case_callout\nmodifier is set. The substitute callout block is not identical for all code unit\nwidths, so we have to duplicate the function for each supported width.\n\nArguments:\n  input          the input character\n  input_len      the length of the input\n  output         the output buffer\n  output_cap     the output buffer capacity\n  to_case        the case conversion type\n  data_ptr       callout data (unused)\n\nReturns:         the number of code units of the output\n*/\n\nstatic PCRE2_SIZE\nsubstitute_case_callout_function(\n  PCRE2_SPTR input, PCRE2_SIZE input_len,\n  PCRE2_UCHAR *output, PCRE2_SIZE output_cap,\n  int to_case, void *data_ptr)\n{\nPCRE2_UCHAR buf[16];\nPCRE2_SPTR input_copy;\nPCRE2_SIZE written = 0;\n\n(void)data_ptr;   /* Not used */\n\nif (input_len > sizeof(buf)/sizeof(*buf))\n  {\n  PCRE2_UCHAR *input_buf = malloc(CU2BYTES(input_len));\n  if (input_buf == NULL) return ~(PCRE2_SIZE)0;\n  memcpy(input_buf, input, CU2BYTES(input_len));\n  input_copy = input_buf;\n  }\nelse\n  {\n  memcpy(buf, input, CU2BYTES(input_len));\n  input_copy = buf;\n  }\n\nfor (PCRE2_SIZE i = 0; i < input_len; )\n  {\n  int num_in = i + 1 < input_len ? 2 : 1;\n  uint32_t c1 = input_copy[i];\n  uint32_t c2 = i + 1 < input_len ? input_copy[i + 1] : 0;\n  int num_read;\n  int num_write;\n\n  if (!case_transform(to_case, num_in, &num_read, &num_write, &c1, &c2))\n    {\n    written = ~(PCRE2_SIZE)0;\n    goto END;\n    }\n\n  i += num_read;\n  if (to_case == PCRE2_SUBSTITUTE_CASE_TITLE_FIRST)\n    to_case = PCRE2_SUBSTITUTE_CASE_LOWER;\n\n  if (written + num_write > output_cap)\n    {\n    written += num_write;\n    }\n  else\n    {\n    if (num_write > 0) output[written++] = c1;\n    if (num_write > 1) output[written++] = c2;\n    }\n  }\n\nEND:\nif (input_copy != buf) free((PCRE2_UCHAR *)input_copy);\n\n/* Let's be maximally cruel. The case callout is allowed to leave the output\nbuffer in any state at all if it overflows, so let's use random garbage. */\nif (written > output_cap)\n  memset(output, time(NULL) & 1 ? 0xcd : 0xdc,\n         CU2BYTES(output_cap));\n\nreturn written;\n}\n\n\n\n/*************************************************\n*              Callout function                  *\n*************************************************/\n\n/* Called from a PCRE2 library as a result of the (?C) item. We print out where\nwe are in the match (unless suppressed). Yield zero unless more callouts than\nthe fail count, or the callout data is not zero. The only differences in the\ncallout block for different code unit widths are that the pointers to the\nsubject, the most recent MARK, and a callout argument string point to strings\nof the appropriate width. Casts can be used to deal with this.\n\nArguments:\n  cb                a pointer to a callout block\n  callout_data_ptr  the provided callout data\n\nReturns:            0 or 1 or an error, as determined by settings\n*/\n\nstatic int\ncallout_function(pcre2_callout_block *cb, void *callout_data_ptr)\n{\nFILE *f, *fdefault;\nuint32_t i, pre_start, post_start, subject_length;\nPCRE2_SIZE current_position;\nBOOL utf = (compiled_code->overall_options & PCRE2_UTF) != 0;\nBOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0;\nBOOL callout_where = (dat_datctl.control2 & CTL2_CALLOUT_NO_WHERE) == 0;\n\nif (outfile == NULL) goto YIELD;\n\n/* The FILE f is used for echoing the subject string if it is non-NULL. This\nhappens only once in simple cases, but we want to repeat after any additional\noutput caused by CALLOUT_EXTRA. */\n\nfdefault = (!first_callout && !callout_capture && cb->callout_string == NULL)?\n  NULL : outfile;\n\nif ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0)\n  {\n  f = outfile;\n  switch (cb->callout_flags)\n    {\n    case PCRE2_CALLOUT_BACKTRACK:\n    fprintf(f, \"Backtrack\\n\");\n    break;\n\n    case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK:\n    fprintf(f, \"Backtrack\\nNo other matching paths\\n\");\n    PCRE2_FALLTHROUGH /* Fall through */\n\n    case PCRE2_CALLOUT_STARTMATCH:\n    fprintf(f, \"New match attempt\\n\");\n    break;\n\n    default:\n    f = fdefault;\n    break;\n    }\n  }\nelse f = fdefault;\n\n/* For a callout with a string argument, show the string first because there\nisn't a tidy way to fit it in the rest of the data. */\n\nif (cb->callout_string != NULL)\n  {\n  uint32_t delimiter = cb->callout_string[-1];\n  fprintf(outfile, \"Callout (%\" SIZ_FORM \"): %c\",\n    cb->callout_string_offset, CHAR_OUTPUT(delimiter));\n  pchars(clr_none, cb->callout_string, cb->callout_string_length, utf, outfile);\n  for (i = 0; callout_start_delims[i] != 0; i++)\n    if (delimiter == callout_start_delims[i])\n      {\n      delimiter = callout_end_delims[i];\n      break;\n      }\n  fprintf(outfile, \"%c\", CHAR_OUTPUT(delimiter));\n  if (!callout_capture) fprintf(outfile, \"\\n\");\n  }\n\n/* Show captured strings if required */\n\nif (callout_capture)\n  {\n  if (cb->callout_string == NULL)\n    fprintf(outfile, \"Callout %d:\", cb->callout_number);\n  fprintf(outfile, \" last capture = %d\\n\", cb->capture_last);\n  for (i = 2; i < cb->capture_top * 2; i += 2)\n    {\n    fprintf(outfile, \"%2d: \", i/2);\n    if (cb->offset_vector[i] == PCRE2_UNSET)\n      fprintf(outfile, \"<unset>\");\n    else\n      {\n      pchars(clr_none, cb->subject + cb->offset_vector[i],\n        cb->offset_vector[i+1] - cb->offset_vector[i], utf, f);\n      }\n    fprintf(outfile, \"\\n\");\n    }\n  }\n\n/* Unless suppressed, re-print the subject in canonical form (with escapes for\nnon-printing characters), the first time, or if giving full details. On\nsubsequent calls in the same match, we use pchars() just to find the printed\nlengths of the substrings. */\n\nif (callout_where)\n  {\n  if (f != NULL) fprintf(f, \"--->\");\n\n  /* The subject before the match start. */\n\n  pre_start = pchars(clr_none, cb->subject, cb->start_match, utf, f);\n\n  /* If a lookbehind is involved, the current position may be earlier than the\n  match start. If so, use the match start instead. */\n\n  current_position = (cb->current_position >= cb->start_match)?\n    cb->current_position : cb->start_match;\n\n  /* The subject between the match start and the current position. */\n\n  post_start = pchars(clr_none, cb->subject + cb->start_match,\n    current_position - cb->start_match, utf, f);\n\n  /* Print from the current position to the end. */\n\n  pchars(clr_none, cb->subject + current_position, cb->subject_length - current_position,\n    utf, f);\n\n  /* Calculate the total subject printed length (no print). */\n\n  subject_length = pchars(clr_none, cb->subject, cb->subject_length, utf, NULL);\n\n  if (f != NULL) fprintf(f, \"\\n\");\n\n  /* For automatic callouts, show the pattern offset. Otherwise, for a\n  numerical callout whose number has not already been shown with captured\n  strings, show the number here. A callout with a string argument has been\n  displayed above. */\n\n  if (cb->callout_number == 255)\n    {\n    fprintf(outfile, \"%+3d \", (int)cb->pattern_position);\n    if (cb->pattern_position > 99) fprintf(outfile, \"\\n    \");\n    }\n  else\n    {\n    if (callout_capture || cb->callout_string != NULL) fprintf(outfile, \"    \");\n      else fprintf(outfile, \"%3d \", cb->callout_number);\n    }\n\n  /* Now show position indicators */\n\n  for (i = 0; i < pre_start; i++) fprintf(outfile, \" \");\n  fprintf(outfile, \"^\");\n\n  if (post_start > 0)\n    {\n    for (i = 0; i < post_start - 1; i++) fprintf(outfile, \" \");\n    fprintf(outfile, \"^\");\n    }\n\n  for (i = 0; i < subject_length - pre_start - post_start + 4; i++)\n    fprintf(outfile, \" \");\n\n  if (cb->next_item_length != 0)\n    {\n    pchars(clr_none, pbuffer + cb->pattern_position, cb->next_item_length, utf, outfile);\n    }\n  else\n    fprintf(outfile, \"End of pattern\");\n\n  fprintf(outfile, \"\\n\");\n  }\n\n/* Show any mark info */\n\nif (cb->mark != last_callout_mark)\n  {\n  if (cb->mark == NULL)\n    fprintf(outfile, \"Latest Mark: <unset>\\n\");\n  else\n    {\n    fprintf(outfile, \"Latest Mark: \");\n    pchars(clr_none, cb->mark - 1, -1, utf, outfile);\n    putc('\\n', outfile);\n    }\n  }\n\nYIELD:\n\n/* Keep count */\n\nfirst_callout = FALSE;\nlast_callout_mark = cb->mark;\ncallout_count++;\n\n/* Show callout data if that determines the return code */\n\nif (callout_data_ptr != NULL)\n  {\n  int callout_data = *((int32_t *)callout_data_ptr);\n  if (callout_data != 0)\n    {\n    if (outfile != NULL) fprintf(outfile, \"Callout data = %d\\n\", callout_data);\n    return callout_data;\n    }\n  }\n\n/* Otherwise, the callout_error and callout_fail settings provide the return\ncode. */\n\nif (cb->callout_number == dat_datctl.cerror[0] &&\n    callout_count >= dat_datctl.cerror[1])\n  return PCRE2_ERROR_CALLOUT;\n\nif (cb->callout_number == dat_datctl.cfail[0] &&\n    callout_count >= dat_datctl.cfail[1])\n  return 1;\n\nreturn 0;\n}\n\n\n\n/*************************************************\n*       Handle *MARK and copy/get tests          *\n*************************************************/\n\n/* This function is called after complete and partial matches. It runs the\ntests for substring extraction.\n\nArguments:\n  utf       TRUE for utf\n  capcount  return from pcre2_match()\n\nReturns:    FALSE if print_error_message() fails\n*/\n\nstatic BOOL\ncopy_and_get(BOOL utf, int capcount)\n{\nint i;\nuint8_t *nptr;\n\n/* Test copy strings by number */\n\nfor (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++)\n  {\n  int rc, rc2;\n  PCRE2_SIZE length, length2;\n  PCRE2_UCHAR copybuffer[256];\n  uint32_t n = (uint32_t)(dat_datctl.copy_numbers[i]);\n  length = sizeof(copybuffer)/sizeof(*copybuffer);\n  rc = pcre2_substring_copy_bynumber(match_data, n, copybuffer, &length);\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Copy substring %d failed (%d): \", n, rc);\n    if (!print_error_message(rc, \"\", \"\\n\")) return FALSE;\n    }\n  else\n    {\n    fprintf(outfile, \"%2dC \", n);\n    pchars(clr_none, copybuffer, length, utf, outfile);\n    fprintf(outfile, \" (%\" SIZ_FORM \")\\n\", length);\n    }\n  rc2 = pcre2_substring_length_bynumber(match_data, n, &length2);\n  if (rc2 < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Get substring %d length failed (%d): \", n, rc2);\n    if (!print_error_message(rc2, \"\", \"\\n\")) return FALSE;\n    }\n  else if (rc >= 0 && length2 != length)\n    {\n    cfprintf(clr_test_error, outfile, \"** Mismatched substring lengths: %\"\n      SIZ_FORM \" %\" SIZ_FORM \"\\n\", length, length2);\n    }\n  }\n\n/* Test copy strings by name */\n\nnptr = dat_datctl.copy_names;\nfor (;;)\n  {\n  int rc, rc2;\n  int groupnumber;\n  PCRE2_SIZE length, length2;\n  PCRE2_UCHAR copybuffer[256];\n  size_t namelen = strlen((const char *)nptr);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  PCRE2_SIZE cnl = namelen;\n#endif\n  if (namelen == 0) break;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  strcpy((char *)pbuffer8, (char *)nptr);\n#endif\n#if defined(EBCDIC) && !EBCDIC_IO\n  ascii_to_ebcdic_str(pbuffer8, namelen);\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 16\n  (void)to16(nptr, utf, &cnl);\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  (void)to32(nptr, utf, &cnl);\n#endif\n\n  groupnumber = pcre2_substring_number_from_name(compiled_code, pbuffer);\n  if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)\n    cfprintf(clr_api_error, outfile, \"Number not found for group \\\"%s\\\"\\n\", nptr);\n\n  length = sizeof(copybuffer)/sizeof(*copybuffer);\n  rc = pcre2_substring_copy_byname(match_data, pbuffer, copybuffer, &length);\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Copy substring \\\"%s\\\" failed (%d): \", nptr, rc);\n    if (!print_error_message(rc, \"\", \"\\n\")) return FALSE;\n    }\n  else\n    {\n    fprintf(outfile, \"  C \");\n    pchars(clr_none, copybuffer, length, utf, outfile);\n    fprintf(outfile, \" (%\" SIZ_FORM \") %s\", length, nptr);\n    if (groupnumber >= 0) fprintf(outfile, \" (group %d)\\n\", groupnumber);\n      else fprintf(outfile, \" (non-unique)\\n\");\n    }\n  rc2 = pcre2_substring_length_byname(match_data, pbuffer, &length2);\n  if (rc2 < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Get substring \\\"%s\\\" length failed (%d): \", nptr, rc2);\n    if (!print_error_message(rc2, \"\", \"\\n\")) return FALSE;\n    }\n  else if (rc >= 0 && length2 != length)\n    {\n    cfprintf(clr_test_error, outfile, \"** Mismatched substring lengths: %\"\n      SIZ_FORM \" %\" SIZ_FORM \"\\n\", length, length2);\n    }\n  nptr += namelen + 1;\n  }\n\n/* Test get strings by number */\n\nfor (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++)\n  {\n  int rc;\n  PCRE2_SIZE length;\n  PCRE2_UCHAR *gotbuffer;\n  uint32_t n = (uint32_t)(dat_datctl.get_numbers[i]);\n  rc = pcre2_substring_get_bynumber(match_data, n, &gotbuffer, &length);\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Get substring %d failed (%d): \", n, rc);\n    if (!print_error_message(rc, \"\", \"\\n\")) return FALSE;\n    }\n  else\n    {\n    fprintf(outfile, \"%2dG \", n);\n    pchars(clr_none, gotbuffer, length, utf, outfile);\n    fprintf(outfile, \" (%\" SIZ_FORM \")\\n\", length);\n    pcre2_substring_free(gotbuffer);\n    }\n  }\n\n/* Test get strings by name */\n\nnptr = dat_datctl.get_names;\nfor (;;)\n  {\n  PCRE2_SIZE length;\n  PCRE2_UCHAR *gotbuffer;\n  int rc;\n  int groupnumber;\n  size_t namelen = strlen((const char *)nptr);\n#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32\n  PCRE2_SIZE cnl = namelen;\n#endif\n  if (namelen == 0) break;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  strcpy((char *)pbuffer8, (char *)nptr);\n#endif\n#if defined(EBCDIC) && !EBCDIC_IO\n  ascii_to_ebcdic_str(pbuffer8, namelen);\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 16\n  (void)to16(nptr, utf, &cnl);\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  (void)to32(nptr, utf, &cnl);\n#endif\n\n  groupnumber = pcre2_substring_number_from_name(compiled_code, pbuffer);\n  if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)\n    cfprintf(clr_api_error, outfile, \"Number not found for group \\\"%s\\\"\\n\", nptr);\n\n  rc = pcre2_substring_get_byname(match_data, pbuffer, &gotbuffer, &length);\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Get substring \\\"%s\\\" failed (%d): \", nptr, rc);\n    if (!print_error_message(rc, \"\", \"\\n\")) return FALSE;\n    }\n  else\n    {\n    fprintf(outfile, \"  G \");\n    pchars(clr_none, gotbuffer, length, utf, outfile);\n    fprintf(outfile, \" (%\" SIZ_FORM \") %s\", length, nptr);\n    if (groupnumber >= 0) fprintf(outfile, \" (group %d)\\n\", groupnumber);\n      else fprintf(outfile, \" (non-unique)\\n\");\n    pcre2_substring_free(gotbuffer);\n    }\n  nptr += namelen + 1;\n  }\n\n/* Test getting the complete list of captured strings. */\n\nif ((dat_datctl.control & CTL_GETALL) != 0)\n  {\n  int rc;\n  PCRE2_UCHAR **stringlist;\n  PCRE2_SIZE *lengths;\n  rc = pcre2_substring_list_get(match_data, &stringlist, &lengths);\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"get substring list failed (%d): \", rc);\n    if (!print_error_message(rc, \"\", \"\\n\")) return FALSE;\n    }\n  else\n    {\n    for (i = 0; i < capcount; i++)\n      {\n      fprintf(outfile, \"%2dL \", i);\n      pchars(clr_none, stringlist[i], lengths[i], utf, outfile);\n      putc('\\n', outfile);\n      }\n    if (stringlist[i] != NULL)\n      cfprintf(clr_test_error, outfile, \"** string list not terminated by NULL\\n\");\n    pcre2_substring_list_free(stringlist);\n    }\n  }\n\nreturn TRUE;\n}\n\n\n\n/*************************************************\n*          Copy a substitution string            *\n*************************************************/\n\n/* Copy one of the string arguments to pcre2_substitute() from its uint8_t\ntest input to the appropriate width buffer.\n*/\n\nstatic void\ncopy_substitute_string(BOOL utf, uint8_t *input, PCRE2_SIZE inlen,\n  PCRE2_UCHAR *output, PCRE2_SIZE *outlen)\n{\nuint32_t c;\nuint8_t *input_end = input + inlen;\nPCRE2_UCHAR *output_start = output;\nPCRE2_SIZE erroroffset;\nBOOL badutf = FALSE;\n\n/* When copying the replacement string to a buffer of the appropriate width, no\nescape processing is done.\n\nIn UTF mode, check for an invalid UTF-8 input string, and if it is invalid, just\ncopy its code units without UTF interpretation. This provides a means of\nchecking that an invalid string is detected. Otherwise, UTF-8 can be used to\ninclude wide characters in a replacement. */\n\nif (utf) badutf = valid_utf(input, inlen, &erroroffset);\n\n/* Not UTF or invalid UTF-8: just copy the code units. */\n\nif (!utf || badutf)\n  {\n  while (input < input_end)\n    {\n    c = *input++;\n#if defined(EBCDIC) && !EBCDIC_IO\n    c = ascii_to_ebcdic(c);\n#endif\n    *output++ = c;\n    }\n  }\n\n/* Valid UTF-8 replacement string */\n\nelse while (input < input_end)\n  {\n  c = *input++;\n  if (HASUTF8EXTRALEN(c)) { GETUTF8INC(c, input); }\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  output += ord_to_utf8(c, output);\n\n#elif PCRE2_CODE_UNIT_WIDTH == 16\n  if (c >= 0x10000u)\n    {\n    c-= 0x10000u;\n    *output++ = 0xd800 | (c >> 10);\n    *output++ = 0xdc00 | (c & 0x3ff);\n    }\n  else *output++ = c;\n\n#elif PCRE2_CODE_UNIT_WIDTH == 32\n  *output++ = c;\n#endif\n  }\n\n*output = 0;\n*outlen = output - output_start;\n}\n\n\n\n/*************************************************\n*               Process a data line              *\n*************************************************/\n\n/* The line is in buffer; it will not be empty.\n\nArguments:  none\n\nReturns:    PR_OK     continue processing next line\n            PR_SKIP   skip to a blank line\n            PR_ABEND  abort the pcre2test run\n*/\n\nstatic int\nprocess_data(void)\n{\nPCRE2_SIZE ulen, arg_ulen;\nuint32_t gmatched;\nuint32_t c, k;\nuint32_t g_notempty = 0;\nuint8_t *p; /* Position within buffer (raw input line) */\nsize_t len;\nsize_t needlen;  /* Bytes, for sizing dbuffer */\npcre2_match_context *use_dat_context;\nBOOL utf;\nBOOL subject_literal;\n\nPCRE2_SIZE *ovector;\nPCRE2_SPTR ovecsave[2] = { NULL, NULL };\nuint32_t oveccount;\n\nPCRE2_UCHAR *q = NULL;   /* Typed pointer within dbuffer */\nPCRE2_UCHAR *start_rep;  /* Position within dbuffer; stashed value of q */\nPCRE2_UCHAR *pp;         /* Subject pointer within dbuffer */\n\nsubject_literal = (pat_patctl.control2 & CTL2_SUBJECT_LITERAL) != 0;\n\n/* Copy the default context and data control blocks to the active ones. Then\ncopy from the pattern the controls that can be set in either the pattern or the\ndata. This allows them to be overridden in the data line. We do not do this for\noptions because those that are common apply separately to compiling and\nmatching. */\n\nmemcpy(dat_context, default_dat_context, sizeof(pcre2_match_context));\nmemcpy(&dat_datctl, &def_datctl, sizeof(datctl));\ndat_datctl.control |= (pat_patctl.control & CTL_ALLPD);\ndat_datctl.control2 |= (pat_patctl.control2 & CTL2_ALLPD);\ndat_datctl.replacement[0] = pat_patctl.replacement[0];\nif (pat_patctl.replacement[0] != MOD_STR_UNSET)\n  memcpy(dat_datctl.replacement + 1, pat_patctl.replacement + 1,\n    pat_patctl.replacement[0] + 1);\nif (dat_datctl.jitstack == 0) dat_datctl.jitstack = pat_patctl.jitstack;\n\nif (dat_datctl.substitute_skip == 0)\n    dat_datctl.substitute_skip = pat_patctl.substitute_skip;\nif (dat_datctl.substitute_stop == 0)\n    dat_datctl.substitute_stop = pat_patctl.substitute_stop;\n\n/* Initialize for scanning the data line. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nutf = ((((pat_patctl.control & CTL_POSIX) != 0)?\n  ((pcre2_real_code *)preg.re_pcre2_code)->overall_options :\n  compiled_code->overall_options) & PCRE2_UTF) != 0;\n#else\nutf = (compiled_code->overall_options & PCRE2_UTF) != 0;\n#endif\n\nstart_rep = NULL;\nlen = strlen((const char *)buffer);\nwhile (len > 0 && isspace(buffer[len-1])) len--;\nbuffer[len] = 0;\np = buffer;\nwhile (isspace(*p))\n  {\n  p++;\n  len--;\n  }\n\n/* Check that the data is well-formed UTF-8 if we're in UTF mode. To create\ninvalid input to pcre2_match(), you must use \\x?? or \\x{} sequences. */\n\nif (utf)\n  {\n  uint8_t *ptmp;\n  uint32_t cc;\n  int n = 1;\n  uint8_t *ptmp_end = p + len;\n\n  for (ptmp = p; n > 0 && *ptmp; ptmp += n)\n    n = utf8_to_ord(ptmp, ptmp_end, &cc);\n  if (n <= 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Failed: invalid UTF-8 string cannot be used as input \"\n      \"in UTF mode\\n\");\n    return PR_OK;\n    }\n  }\n\n#ifdef SUPPORT_VALGRIND\n/* Mark the dbuffer as addressable but undefined again. */\nif (dbuffer != NULL)\n  {\n  VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size);\n  }\n#endif\n\n/* Allocate a buffer to hold the data line; len+1 is an upper bound on\nthe number of code units that will be needed (though the buffer may have to be\nextended if replication is involved). */\n\nneedlen = CU2BYTES(len+1);\nif (dbuffer == NULL || needlen >= dbuffer_size)\n  {\n  while (needlen >= dbuffer_size)\n    {\n    if (dbuffer_size < SIZE_MAX/2) dbuffer_size *= 2;\n      else dbuffer_size = needlen + 1;\n    }\n  dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);\n  if (dbuffer == NULL)\n    {\n    cfprintf(clr_test_error, stderr, \"pcre2test: realloc(%\" SIZ_FORM \") failed\\n\", dbuffer_size);\n    exit(1);\n    }\n  }\nq = (PCRE2_UCHAR *)dbuffer;\n\n/* Scan the data line, interpreting data escapes, and put the result into a\nbuffer of the appropriate width. In UTF mode, input is always UTF-8; otherwise,\nin 16- and 32-bit modes, it can be forced to UTF-8 by the utf8_input modifier.\n*/\n\nwhile ((c = *p++) != 0)\n  {\n  int i = 0;\n  size_t replen;  /* Bytes, for sizing dbuffer */\n  enum force_encoding encoding = FORCE_NONE;\n\n  /* ] may mark the end of a replicated sequence */\n\n  if (c == ']' && start_rep != NULL)\n    {\n    long li;\n    char *endptr;\n\n    if (*p++ != '{')\n      {\n      cfprintf(clr_test_error, outfile, \"** Expected '{' after \\\\[....]\\n\");\n      return PR_OK;\n      }\n\n    li = strtol((const char *)p, &endptr, 10);\n    if (S32OVERFLOW(li))\n      {\n      cfprintf(clr_test_error, outfile, \"** Repeat count too large\\n\");\n      return PR_OK;\n      }\n    i = (int)li;\n\n    p = (uint8_t *)endptr;\n    if (*p++ != '}')\n      {\n      cfprintf(clr_test_error, outfile, \"** Expected '}' after \\\\[...]{...\\n\");\n      return PR_OK;\n      }\n\n    if (i-- <= 0)\n      {\n      cfprintf(clr_test_error, outfile, \"** Zero or negative repeat not allowed\\n\");\n      return PR_OK;\n      }\n\n    replen = (uint8_t *)q - (uint8_t *)start_rep;\n    if (i > 0 && replen > (SIZE_MAX - needlen) / i)\n      {\n      cfprintf(clr_test_error, outfile, \"** Expanded content too large\\n\");\n      return PR_OK;\n      }\n    needlen += replen * i;\n\n    if (needlen >= dbuffer_size)\n      {\n      size_t qoffset = (uint8_t *)q - dbuffer;\n      size_t rep_offset = (uint8_t *)start_rep - dbuffer;\n      while (needlen >= dbuffer_size)\n        {\n        if (dbuffer_size < SIZE_MAX/2) dbuffer_size *= 2;\n          else dbuffer_size = needlen + 1;\n        }\n      dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);\n      if (dbuffer == NULL)\n        {\n        cfprintf(clr_test_error, stderr, \"pcre2test: realloc(%\" SIZ_FORM \") failed\\n\",\n          dbuffer_size);\n        exit(1);\n        }\n      q = (PCRE2_UCHAR *)(dbuffer + qoffset);\n      start_rep = (PCRE2_UCHAR *)(dbuffer + rep_offset);\n      }\n\n    while (i-- > 0)\n      {\n      memcpy(q, start_rep, replen);\n      q += BYTES2CU(replen);\n      }\n\n    start_rep = NULL;\n    continue;\n    }\n\n  /* Handle a non-escaped character. In non-UTF 32-bit mode with utf8_input\n  set, do the fudge for setting the top bit. */\n\n  if (c != '\\\\' || subject_literal)\n    {\n    uint32_t topbit = 0;\n#if PCRE2_CODE_UNIT_WIDTH == 32\n    if (c == 0xff && *p != 0)\n      {\n      topbit = 0x80000000;\n      c = *p++;\n      }\n#endif\n    if ((utf || (pat_patctl.control & CTL_UTF8_INPUT) != 0) &&\n        HASUTF8EXTRALEN(c))\n      {\n      GETUTF8INC(c, p);\n      }\n    c |= topbit;\n    }\n\n  /* Handle backslash escapes */\n\n  else switch ((c = *p++))\n    {\n    case '\\\\': break;\n    case 'a': c = '\\a'; break;\n    case 'b': c = '\\b'; break;\n#if defined(EBCDIC) && !EBCDIC_IO\n    /* \\e is the odd one out since it's not defined in the C standard,\n    precisely because of EBCDIC (apparently EBCDIC 'ESC' character isn't\n    an exact match to Latin-1 'ESC', hence '\\e' isn't necessarily\n    supported by EBCDIC compilers). */\n    case 'e': c = '\\x1b'; break;\n#else\n    case 'e': c = CHAR_ESC; break;\n#endif\n    case 'f': c = '\\f'; break;\n    case 'n': c = '\\n'; break;\n    case 'r': c = '\\r'; break;\n    case 't': c = '\\t'; break;\n    case 'v': c = '\\v'; break;\n\n    case '0': case '1': case '2': case '3':\n    case '4': case '5': case '6': case '7':\n    c -= '0';\n    while (i++ < 2 && *p >= '0' && *p < '8')\n      c = c * 8 + (*p++ - '0');\n    c = CHAR_OUTPUT(CHAR_INPUT_HEX(c));\n\n    encoding = (utf && c > 255)? FORCE_UTF : FORCE_RAW;\n    break;\n\n    case 'o':\n    if (*p == '{')\n      {\n      uint8_t *pt = p;\n      c = 0;\n      for (pt++; isdigit(*pt) && *pt < '8'; ++i, pt++)\n        {\n        if (c >= 0x20000000u)\n          {\n          cfprintf(clr_test_error, outfile, \"** \\\\o{ escape too large\\n\");\n          return PR_OK;\n          }\n        else c = c * 8 + (*pt - '0');\n        }\n      c = CHAR_OUTPUT(CHAR_INPUT_HEX(c));\n      if (i == 0 || *pt != '}')\n        {\n        cfprintf(clr_test_error, outfile, \"** Malformed \\\\o{ escape\\n\");\n        return PR_OK;\n        }\n      else p = pt + 1;\n      }\n    break;\n\n    case 'x':\n    c = 0;\n    if (*p == '{')\n      {\n      uint8_t *pt = p;\n\n      /* We used to have \"while (isxdigit(*(++pt)))\" here, but it fails\n      when isxdigit() is a macro that refers to its argument more than\n      once. This is banned by the C Standard, but apparently happens in at\n      least one macOS environment. */\n\n      for (pt++; isxdigit(*pt); pt++)\n        {\n        if (++i == 9)\n          {\n          cfprintf(clr_test_error, outfile, \"** Too many hex digits in \\\\x{...} item; \"\n                           \"using only the first eight.\\n\");\n          while (isxdigit(*pt)) pt++;\n          break;\n          }\n        else c = c * 16 + (tolower(*pt) - (isdigit(*pt)? '0' : 'a' - 10));\n        }\n      c = CHAR_OUTPUT(CHAR_INPUT_HEX(c));\n      if (i == 0 || *pt != '}')\n        {\n        cfprintf(clr_test_error, outfile, \"** Malformed \\\\x{ escape\\n\");\n        return PR_OK;\n        }\n      else p = pt + 1;\n      }\n    else\n      {\n      /* \\x without {} always defines just one byte in 8-bit mode. This\n      allows UTF-8 characters to be constructed byte by byte, and also allows\n      invalid UTF-8 sequences to be made. Just copy the byte in UTF-8 mode.\n      Otherwise, pass it down as data. */\n\n      while (i++ < 2 && isxdigit(*p))\n        {\n        c = c * 16 + (tolower(*p) - (isdigit(*p)? '0' : 'a' - 10));\n        p++;\n        }\n      c = CHAR_OUTPUT(CHAR_INPUT_HEX(c));\n#if PCRE2_CODE_UNIT_WIDTH == 8\n      if (utf) encoding = FORCE_RAW;\n#endif\n      }\n    break;\n\n    case 'N':\n#ifndef EBCDIC\n    if (memcmp(p, \"{U+\", 3) == 0 && isxdigit(p[3]))\n      {\n      char *endptr;\n      unsigned long uli;\n\n      p += 3;\n      errno = 0;\n      uli = strtoul((const char *)p, &endptr, 16);\n      if (errno == 0 && *endptr == '}' && uli <= UINT32_MAX)\n        {\n        c = (uint32_t)uli;\n        p = (uint8_t *)endptr + 1;\n        encoding = FORCE_UTF;\n        break;\n        }\n      }\n#endif\n    cfprintf(clr_test_error, outfile, \"** Malformed \\\\N{U+ escape\\n\");\n    return PR_OK;\n\n    case 0:     /* \\ followed by EOF allows for an empty line */\n    p--;\n    continue;\n\n    case '=':   /* \\= terminates the data, starts modifiers */\n    goto ENDSTRING;\n\n    case '[':   /* \\[ introduces a replicated character sequence */\n    if (start_rep != NULL)\n      {\n      cfprintf(clr_test_error, outfile, \"** Nested replication is not supported\\n\");\n      return PR_OK;\n      }\n    start_rep = q;\n    continue;\n\n    default:\n    if (isalnum(c))\n      {\n      cfprintf(clr_test_error, outfile, \"** Unrecognized escape sequence \\\"\\\\%c\\\"\\n\", c);\n      return PR_OK;\n      }\n    }\n\n  /* We now have a character value in c that may be greater than 255.\n  Depending of how we got it, the encoding enum could be set to tell\n  us how to encode it, otherwise follow the utf modifier. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n  if (encoding == FORCE_RAW || !(utf || encoding == FORCE_UTF))\n    {\n    if (c > 0xffu)\n      {\n      cfprintf(clr_test_error, outfile, \"** Character \\\\x{%x} is greater than 255 \"\n        \"and UTF-8 mode is not enabled.\\n\", c);\n      cfprintf(clr_test_error, outfile, \"** Truncation will probably give the wrong \"\n        \"result.\\n\");\n      }\n    *q++ = (uint8_t)c;\n    }\n  else\n    {\n    if (c > 0x7fffffff)\n      {\n      cfprintf(clr_test_error, outfile, \"** Character \\\\N{U+%x} is greater than 0x7fffffff \"\n                        \"and therefore cannot be encoded as UTF-8\\n\", c);\n      return PR_OK;\n      }\n    else if (encoding == FORCE_UTF && c > MAX_UTF_CODE_POINT)\n      cfprintf(clr_test_error, outfile, \"** Warning: character \\\\N{U+%x} is greater than \"\n                        \"0x%x and should not be encoded as UTF-8\\n\",\n                        c, MAX_UTF_CODE_POINT);\n    q += ord_to_utf8(c, q);\n    }\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 16\n  /* Unlike the 8-bit code, there are no forced raw suggestions for the\n  16-bit mode, so assume raw unless utf is preferred */\n\n  if (!(encoding == FORCE_UTF || utf))\n    {\n    if (c > 0xffffu)\n      {\n      cfprintf(clr_test_error, outfile, \"** Character \\\\x{%x} is greater than 0xffff \"\n        \"and UTF-16 mode is not enabled.\\n\", c);\n      cfprintf(clr_test_error, outfile, \"** Truncation will probably give the wrong \"\n        \"result.\\n\");\n      }\n    *q++ = (uint16_t)c;\n    }\n  else\n    {\n    if (c > MAX_UTF_CODE_POINT)\n      {\n      cfprintf(clr_test_error, outfile, \"** Failed: character \\\\N{U+%x} is greater than \"\n                        \"0x%x and therefore cannot be encoded as UTF-16\\n\",\n              c, MAX_UTF_CODE_POINT);\n      return PR_OK;\n      }\n    else if (c >= 0x10000u)\n      {\n      c -= 0x10000u;\n      *q++ = 0xd800 | (c >> 10);\n      *q++ = 0xdc00 | (c & 0x3ff);\n      }\n    else\n      {\n      if (encoding == FORCE_UTF && 0xe000u > c && c >= 0xd800u)\n        cfprintf(clr_test_error, outfile, \"** Warning: character \\\\N{U+%x} is a surrogate \"\n                          \"and should not be encoded as UTF-16\\n\", c);\n      *q++ = c;\n      }\n    }\n#endif\n#if PCRE2_CODE_UNIT_WIDTH == 32\n  if (encoding == FORCE_UTF && c > MAX_UTF_CODE_POINT)\n    cfprintf(clr_test_error, outfile, \"** Warning: character \\\\N{U+%x} is greater than \"\n                      \"0x%x and should not be encoded as UTF-32\\n\",\n                      c, MAX_UTF_CODE_POINT);\n  *q++ = c;\n#endif\n  }\n\nENDSTRING:\n*q = 0;\nlen = (uint8_t *)q - dbuffer;             /* Length in bytes */\nulen = BYTES2CU(len);                     /* Length in code units */\narg_ulen = ulen;                          /* Value to use in match arg */\n\n/* If the string was terminated by \\= we must now interpret modifiers. */\n\nif (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl))\n  return PR_OK;\n\n/* Setting substitute_{skip,fail} implies a substitute callout. */\n\nif (dat_datctl.substitute_skip != 0 || dat_datctl.substitute_stop != 0)\n  dat_datctl.control2 |= CTL2_SUBSTITUTE_CALLOUT;\n\n/* Check for mutually exclusive modifiers. At present, these are all in the\nfirst control word. */\n\nfor (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++)\n  {\n  c = dat_datctl.control & exclusive_dat_controls[k];\n  if (c != 0 && c != (c & (~c+1)))\n    {\n    show_controls(clr_test_error, c, 0, \"** Not allowed together:\");\n    fprintf(outfile, \"\\n\");\n    return PR_OK;\n    }\n  }\n\nif (dat_datctl.replacement[0] != MOD_STR_UNSET)\n  {\n  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0 &&\n      (dat_datctl.control & CTL_NULLCONTEXT) != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Replacement callouts are not supported with null_context.\\n\");\n    return PR_OK;\n    }\n\n  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CASE_CALLOUT) != 0 &&\n      (dat_datctl.control & CTL_NULLCONTEXT) != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** Replacement case callouts are not supported with null_context.\\n\");\n    return PR_OK;\n    }\n\n  if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)\n    cfprintf(clr_test_error, outfile, \"** Ignored with replacement text: allcaptures\\n\");\n\n  if (dat_datctl.substitute_subject[0] != MOD_STR_UNSET &&\n      (dat_datctl.control2 & CTL2_SUBSTITUTE_MATCHED) == 0)\n    {\n    cfprintf(clr_test_error, outfile, \"** substitute_subject requires substitute_matched.\\n\");\n    return PR_OK;\n    }\n  }\n\nelse\n  {\n  if (dat_datctl.substitute_subject[0] != MOD_STR_UNSET)\n    {\n    cfprintf(clr_test_error, outfile, \"** substitute_subject requires replacement text.\\n\");\n    return PR_OK;\n    }\n  }\n\n/* Warn for modifiers that are ignored for DFA. */\n\nif ((dat_datctl.control & CTL_DFA) != 0)\n  {\n  if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)\n    cfprintf(clr_test_error, outfile, \"** Ignored for DFA matching: allcaptures\\n\");\n  if ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0)\n    cfprintf(clr_test_error, outfile, \"** Ignored for DFA matching: heapframes_size\\n\");\n  }\n\n/* We now have the subject in dbuffer, with len containing the byte length, and\nulen containing the code unit length, with a copy in arg_ulen for use in match\nfunction arguments (this gets changed to PCRE2_ZERO_TERMINATED when the\nzero_terminate modifier is present).\n\nMove the data to the end of the buffer so that a read over the end can be\ncaught by valgrind or other means. If we have explicit valgrind support, mark\nthe unused start of the buffer unaddressable. If we are using the POSIX\ninterface, or testing zero-termination, we must include the terminating zero in\nthe usable data. */\n\nc = ((pat_patctl.control & CTL_POSIX) != 0 ||\n     (dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? CU2BYTES(1) : 0;\npp = memmove(dbuffer + dbuffer_size - (len + c), dbuffer, len + c);\n#ifdef SUPPORT_VALGRIND\nVALGRIND_MAKE_MEM_NOACCESS(dbuffer, dbuffer_size - (len + c));\n#endif\n\n#if defined(EBCDIC) && !EBCDIC_IO\nascii_to_ebcdic_str(pp, len);\n#endif\n\n/* Now pp points to the subject string, but if null_subject was specified, set\nit to NULL to test PCRE2's behaviour. */\n\nif ((dat_datctl.control2 & CTL2_NULL_SUBJECT) != 0) pp = NULL;\n\n/* POSIX matching is only possible in 8-bit mode, and it does not support\ntiming or other fancy features. Some were checked at compile time, but we need\nto check the match-time settings here. */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nif ((pat_patctl.control & CTL_POSIX) != 0)\n  {\n  int rc;\n  int eflags = 0;\n  regmatch_t *pmatch = NULL;\n  regmatch_t startend_buf;\n  const char *msg = \"** Ignored with POSIX interface:\";\n\n  if (dat_datctl.cerror[0] != CFORE_UNSET || dat_datctl.cerror[1] != CFORE_UNSET)\n    prmsg(&msg, \"callout_error\");\n  if (dat_datctl.cfail[0] != CFORE_UNSET || dat_datctl.cfail[1] != CFORE_UNSET)\n    prmsg(&msg, \"callout_fail\");\n  if (dat_datctl.copy_numbers[0] >= 0 || dat_datctl.copy_names[0] != 0)\n    prmsg(&msg, \"copy\");\n  if (dat_datctl.get_numbers[0] >= 0 || dat_datctl.get_names[0] != 0)\n    prmsg(&msg, \"get\");\n  if (dat_datctl.jitstack != 0) prmsg(&msg, \"jitstack\");\n  if (dat_datctl.offset != 0) prmsg(&msg, \"offset\");\n\n  if ((dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS) != 0)\n    {\n    cfprintf(clr_test_error, outfile, \"%s\", msg);\n    show_match_options(clr_test_error, dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS);\n    msg = \"\";\n    }\n\n  if ((dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS) != 0 ||\n      (dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2) != 0)\n    {\n    show_controls(clr_test_error, dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS,\n                  dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2, msg);\n    msg = \"\";\n    }\n\n  if (msg[0] == 0) fprintf(outfile, \"\\n\");\n\n  if (dat_datctl.oveccount > 0)\n    {\n    pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount);\n    if (pmatch == NULL)\n      {\n      cfprintf(clr_test_error, outfile, \"** Failed to get memory for recording matching \"\n        \"information (size set = %du)\\n\", dat_datctl.oveccount);\n      return PR_ABEND;\n      }\n    }\n\n  if (dat_datctl.startend[0] != CFORE_UNSET)\n    {\n    if (pmatch == NULL) pmatch = &startend_buf;\n    pmatch[0].rm_so = (regoff_t)dat_datctl.startend[0];\n    pmatch[0].rm_eo = (dat_datctl.startend[1] != 0)?\n      (regoff_t)dat_datctl.startend[1] : (regoff_t)len;\n    eflags |= REG_STARTEND;\n    }\n\n  if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL;\n  if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL;\n  if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;\n\n  rc = regexec(&preg, (const char *)pp, dat_datctl.oveccount, pmatch, eflags);\n  if (rc != 0)\n    {\n    size_t usize = regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size);\n    cfprintf(clr_api_error, outfile, \"No match: POSIX code %d: \", rc);\n    pchars(clr_api_error, (PCRE2_SPTR8)pbuffer8, usize - 1, utf, outfile);\n    fputs(\"\\n\", outfile);\n    }\n  else if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0)\n    fprintf(outfile, \"Matched with REG_NOSUB\\n\");\n  else if (dat_datctl.oveccount == 0)\n    fprintf(outfile, \"Matched without capture\\n\");\n  else\n    {\n    size_t i, j;\n    size_t last_printed = (size_t)dat_datctl.oveccount;\n    for (i = 0; i < (size_t)dat_datctl.oveccount; i++)\n      {\n      if (pmatch[i].rm_so >= 0)\n        {\n        PCRE2_SIZE start = pmatch[i].rm_so;\n        PCRE2_SIZE end = pmatch[i].rm_eo;\n        for (j = last_printed + 1; j < i; j++)\n          fprintf(outfile, \"%2d: <unset>\\n\", (int)j);\n        last_printed = i;\n        if (start > end)\n          {\n          start = pmatch[i].rm_eo;\n          end = pmatch[i].rm_so;\n          cfprintf(clr_api_error, outfile, \"Start of matched string is beyond its end - \"\n            \"displaying from end to start.\\n\");\n          }\n        fprintf(outfile, \"%2d: \", (int)i);\n        pchars(clr_none, pp + start, end - start, utf, outfile);\n        fprintf(outfile, \"\\n\");\n\n        if ((i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0) ||\n            (dat_datctl.control & CTL_ALLAFTERTEXT) != 0)\n          {\n          fprintf(outfile, \"%2d+ \", (int)i);\n          /* Note: don't use the start/end variables here because we want to\n          show the text from what is reported as the end. */\n          pchars(clr_none, pp + pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf, outfile);\n          fprintf(outfile, \"\\n\");\n          }\n        }\n      }\n    }\n  if (pmatch != &startend_buf) free(pmatch);\n  return PR_OK;\n  }\n#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */\n\n /* Handle matching via the native interface. Check for consistency of\nmodifiers. */\n\nif (dat_datctl.startend[0] != CFORE_UNSET)\n  cfprintf(clr_test_error, outfile, \"** \\\\=posix_startend ignored for non-POSIX matching\\n\");\n\n/* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA\nmatching, even if the JIT compiler was used. */\n\nif ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT &&\n    compiled_code->executable_jit != NULL)\n  {\n  cfprintf(clr_test_error, outfile, \"** Showing all consulted text is not supported by JIT: ignored\\n\");\n  dat_datctl.control &= ~CTL_ALLUSEDTEXT;\n  }\n\n/* Handle passing the subject as zero-terminated. */\n\nif ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)\n  arg_ulen = PCRE2_ZERO_TERMINATED;\n\n/* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a\nNULL context. */\n\nuse_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?\n  NULL : dat_context;\n\n/* Enable display of malloc/free if wanted. We can do this only if either the\npattern or the subject is processed with a context. */\n\nshow_memory = (dat_datctl.control & CTL_MEMORY) != 0;\n\nif (show_memory &&\n    (pat_patctl.control & dat_datctl.control & CTL_NULLCONTEXT) != 0)\n  cfprintf(clr_test_error, outfile, \"** \\\\=memory requires either a pattern or a subject \"\n    \"context: ignored\\n\");\n\n/* Create and assign a JIT stack if requested. */\n\nif (dat_datctl.jitstack != 0)\n  {\n  if (dat_datctl.jitstack != jit_stack_size)\n    {\n    pcre2_jit_stack_free(jit_stack);\n    jit_stack = pcre2_jit_stack_create(1, dat_datctl.jitstack * 1024, NULL);\n    jit_stack_size = dat_datctl.jitstack;\n    }\n  pcre2_jit_stack_assign(dat_context, jit_callback, jit_stack);\n  }\n\n/* Or de-assign */\n\nelse if (jit_stack != NULL)\n  {\n  pcre2_jit_stack_assign(dat_context, NULL, NULL);\n  pcre2_jit_stack_free(jit_stack);\n  jit_stack = NULL;\n  jit_stack_size = 0;\n  }\n\n/* When no JIT stack is assigned, we must ensure that there is a JIT callback\nif we want to verify that JIT was actually used. */\n\nif ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL)\n   {\n   pcre2_jit_stack_assign(dat_context, jit_callback, NULL);\n   }\n\n/* Set up the match callout. The pattern remains in pbuffer8/16/32 after\ncompilation, for use by the callout. */\n\nif ((dat_datctl.control & CTL_CALLOUT_NONE) == 0)\n  {\n  pcre2_set_callout(dat_context, callout_function,\n    (void *)(&dat_datctl.callout_data));\n  }\nelse\n  {\n  pcre2_set_callout(dat_context, NULL, NULL);  /* No callout */\n  }\n\n/* Adjust match_data according to size of offsets required. A size of zero\ncauses a new match data block to be obtained that exactly fits the pattern. */\n\nif (dat_datctl.oveccount == 0)\n  {\n  pcre2_match_data_free(match_data);\n  match_data = pcre2_match_data_create_from_pattern(compiled_code,\n    general_context);\n  max_oveccount = pcre2_get_ovector_count(match_data);\n  }\nelse if (dat_datctl.oveccount <= max_oveccount)\n  {\n  match_data->oveccount = dat_datctl.oveccount;\n  }\nelse\n  {\n  max_oveccount = dat_datctl.oveccount;\n  pcre2_match_data_free(match_data);\n  match_data = pcre2_match_data_create(max_oveccount, general_context);\n  }\n\nif (match_data == NULL)\n  {\n  cfprintf(clr_test_error, outfile, \"** Failed to get memory for recording matching \"\n    \"information (size requested: %d)\\n\", dat_datctl.oveccount);\n  max_oveccount = 0;\n  return PR_ABEND;\n  }\n\novector = match_data->ovector;\noveccount = pcre2_get_ovector_count(match_data);\n\n/* Helper to clear any cached heap frames from the match_data. */\n\n#define CLEAR_HEAP_FRAMES() \\\n  do { \\\n     void *heapframes = (void *)(match_data->heapframes); \\\n     void *memory_data = match_data->memctl.memory_data; \\\n     match_data->memctl.free(heapframes, memory_data); \\\n     match_data->heapframes = NULL; \\\n     match_data->heapframes_size = 0; \\\n     } \\\n  while (0)\n\n/* Replacement processing is ignored for DFA matching. Allow this for\nreplacements with PCRE2_SUBSTITUTE_MATCHED, even though it won't work, in order\nto exercise the error condition. */\n\nif (dat_datctl.replacement[0] != MOD_STR_UNSET &&\n    (dat_datctl.control & CTL_DFA) != 0 &&\n    (dat_datctl.control2 & CTL2_SUBSTITUTE_MATCHED) == 0)\n  {\n  cfprintf(clr_test_error, outfile, \"** Ignored for DFA matching: replace\\n\");\n  dat_datctl.replacement[0] = MOD_STR_UNSET;\n  }\n\n/* If a replacement string is provided, call pcre2_substitute() instead of or\nafter one of the matching functions. First we have to convert the replacement\nstring to the appropriate width. */\n\nif (dat_datctl.replacement[0] != MOD_STR_UNSET)\n  {\n  int rc;\n  uint8_t *pr, *prend;\n  PCRE2_UCHAR sbuffer[SUBSTITUTE_SUBJECT_MODSIZE]; /* Staging, not seen by pcre2_substitute() */\n  PCRE2_UCHAR *rbptr;\n  PCRE2_UCHAR *sbptr;\n  uint32_t xoptions;\n  uint32_t emoption;  /* External match option */\n  PCRE2_SIZE j, rlen, full_rlen, nsize, nsize_input, slen;\n  pcre2_match_data *smatch_data;\n\n  /* Fill the ovector with junk to detect elements that do not get set\n  when they should be (relevant only when \"allvector\" is specified). */\n\n  for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;\n\n  if (timeitm)\n    cfprintf(clr_test_error, outfile, \"** Timing is not supported with replace: ignored\\n\");\n\n  if ((dat_datctl.control & CTL_ALTGLOBAL) != 0)\n    cfprintf(clr_test_error, outfile, \"** Altglobal is not supported with replace: ignored\\n\");\n\n  /* Check for a test that does substitution after an initial external match.\n  If this is set, we run the external match, but leave the interpretation of\n  its output to pcre2_substitute(). */\n\n  emoption = ((dat_datctl.control2 & CTL2_SUBSTITUTE_MATCHED) == 0)? 0 :\n    PCRE2_SUBSTITUTE_MATCHED;\n\n  if (emoption != 0)\n    {\n    reset_callout_state();\n    if ((dat_datctl.control & CTL_DFA) != 0)\n      {\n      if (dfa_workspace == NULL)\n        dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));\n      dfa_workspace[0] = -1;\n      (void)pcre2_dfa_match(compiled_code, pp, arg_ulen,\n        dat_datctl.offset, dat_datctl.options, match_data,\n        use_dat_context, dfa_workspace, DFA_WS_DIMENSION);\n      }\n    else if ((pat_patctl.control & CTL_JITFAST) != 0)\n      {\n      (void)pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n        dat_datctl.options, match_data, use_dat_context);\n      }\n    else\n      {\n      (void)pcre2_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n        dat_datctl.options, match_data, use_dat_context);\n      }\n    }\n\n  xoptions = emoption |\n             (((dat_datctl.control & CTL_GLOBAL) == 0)? 0 :\n                PCRE2_SUBSTITUTE_GLOBAL) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_EXTENDED) == 0)? 0 :\n                PCRE2_SUBSTITUTE_EXTENDED) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_LITERAL) == 0)? 0 :\n                PCRE2_SUBSTITUTE_LITERAL) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) == 0)? 0 :\n                PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_REPLACEMENT_ONLY) == 0)? 0 :\n                PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) == 0)? 0 :\n                PCRE2_SUBSTITUTE_UNKNOWN_UNSET) |\n             (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNSET_EMPTY) == 0)? 0 :\n                PCRE2_SUBSTITUTE_UNSET_EMPTY);\n\n  pr = dat_datctl.replacement+1;\n  prend = pr + dat_datctl.replacement[0];\n\n  /* If the replacement starts with '[<number>]' we interpret that as length\n  value for the replacement buffer. */\n\n  nsize = rep_out_buffer_size;\n  if (pr < prend && *pr == '[')\n    {\n    PCRE2_SIZE n = 0;\n    ++pr;\n    for (; pr < prend && (c = *pr) >= '0' && c <= '9'; ++pr)\n      n = n * 10 + (c - '0');\n    if (pr >= prend || *pr != ']')\n      {\n      cfprintf(clr_test_error, outfile, \"** Bad buffer size in replacement string\\n\");\n      return PR_OK;\n      }\n    ++pr;\n    if (n > nsize)\n      {\n      cfprintf(clr_test_error, outfile, \"** Replacement buffer setting (%\" SIZ_FORM \") is too \"\n        \"large (max %\" SIZ_FORM \")\\n\", n, nsize);\n      return PR_OK;\n      }\n    nsize = n;\n    }\n\n#ifdef SUPPORT_VALGRIND\n  VALGRIND_MAKE_MEM_UNDEFINED(rep_out_buffer, CU2BYTES(nsize));\n  VALGRIND_MAKE_MEM_NOACCESS(rep_out_buffer + nsize,\n    CU2BYTES(rep_out_buffer_size - nsize));\n#endif\n\n  /* Now copy the rest of the replacement string to the buffer. */\n\n#ifdef SUPPORT_VALGRIND\n  VALGRIND_MAKE_MEM_UNDEFINED(rep_in_buffer, CU2BYTES(rep_in_buffer_size));\n#endif\n\n  copy_substitute_string(utf, pr, prend-pr, rep_in_buffer, &rlen);\n\n#ifdef SUPPORT_VALGRIND\n  c = ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1 : 0;\n  VALGRIND_MAKE_MEM_NOACCESS(rep_in_buffer + rlen + c,\n    CU2BYTES(rep_in_buffer_size - rlen + c));\n#endif\n\n  full_rlen = rlen;\n  if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)\n    rlen = PCRE2_ZERO_TERMINATED;\n  rbptr = ((dat_datctl.control2 & CTL2_NULL_REPLACEMENT) == 0)? rep_in_buffer : NULL;\n\n  /* If the substitute_subject modifier is set, then we will modify the\n  subject in between the call to pcre2_match and pcre2_substitute. */\n\n  sbptr = pp;\n  slen = arg_ulen;\n\n  if (dat_datctl.substitute_subject[0] != MOD_STR_UNSET)\n    {\n    copy_substitute_string(utf, dat_datctl.substitute_subject+1,\n      dat_datctl.substitute_subject[0], sbuffer, &slen);\n\n    /* The buffer pointed to by pp has exactly the correct length (butted up\n    against the end of the memory allocation) so it would be possible but\n    awkward to extend the subject. However, since pcre2_substitute() won't allow\n    changing the length of the subject, and also early-exits if the subject\n    pointer changes, we can test all the branches just by supporting shrinking\n    the subject. */\n    if (slen > ulen)\n      {\n      cfprintf(clr_test_error, outfile, \"** substitute_subject is longer than match subject buffer\\n\");\n      return PR_OK;\n      }\n\n    /* In the null-subject case, there's no need to copy. */\n    if (pp != NULL)\n      {\n      memcpy(pp, sbuffer, CU2BYTES(slen));\n      if (slen < ulen) ((PCRE2_UCHAR *)pp)[slen] = 0;\n\n      /* If we shrank the subject, adjust the Valgrind readable area. */\n#ifdef SUPPORT_VALGRIND\n      c = ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1 : 0;\n      VALGRIND_MAKE_MEM_NOACCESS((uint8_t *)pp + CU2BYTES(slen+c),\n        (dbuffer + dbuffer_size) - ((uint8_t *)pp + CU2BYTES(slen+c)));\n#endif\n      }\n\n    if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)\n      slen = PCRE2_ZERO_TERMINATED;\n    }\n\n  /* Set up the required callouts and context, and call pcre2_substitute(). */\n\n  smatch_data = ((CTL2_NULL_SUBSTITUTE_MATCH_DATA & dat_datctl.control2) == 0)?\n    match_data : NULL;\n\n  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0)\n    {\n    pcre2_set_substitute_callout(dat_context, substitute_callout_function, NULL);\n    }\n  else\n    {\n    pcre2_set_substitute_callout(dat_context, NULL, NULL);  /* No callout */\n    }\n\n  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CASE_CALLOUT) != 0)\n    {\n    pcre2_set_substitute_case_callout(dat_context, substitute_case_callout_function, NULL);\n    }\n  else\n    {\n    pcre2_set_substitute_case_callout(dat_context, NULL, NULL);  /* No callout */\n    }\n\n  if (malloc_testing) CLEAR_HEAP_FRAMES();\n  reset_callout_state();\n  nsize_input = nsize;\n  rc = pcre2_substitute(compiled_code, sbptr, slen, dat_datctl.offset,\n    dat_datctl.options|xoptions, smatch_data, use_dat_context,\n    rbptr, rlen, rep_out_buffer, &nsize);\n\n  /* For malloc testing, we repeat the substitution. */\n\n  if (malloc_testing && (dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) == 0)\n    {\n    for (int i = 0, target_mallocs = mallocs_called; i <= target_mallocs; i++)\n      {\n      FILE *saved_outfile = outfile;\n      CLEAR_HEAP_FRAMES();\n      reset_callout_state();\n      mallocs_until_failure = i;\n      outfile = NULL;  /* Suppress callout output during the malloc repetitions */\n      nsize = nsize_input;\n      rc = pcre2_substitute(compiled_code, sbptr, slen, dat_datctl.offset,\n        dat_datctl.options|xoptions, smatch_data, use_dat_context,\n        rbptr, rlen, rep_out_buffer, &nsize);\n      mallocs_until_failure = INT_MAX;\n      outfile = saved_outfile;\n\n      if (i < target_mallocs && rc != PCRE2_ERROR_NOMEMORY)\n        {\n        cfprintf(clr_test_error, outfile, \"** malloc() Substitution test did not fail as expected (%d)\\n\",\n                rc);\n        return PR_ABEND;\n        }\n      }\n    }\n\n  if (rc < 0)\n    {\n    cfprintf(clr_api_error, outfile, \"Failed: error %d\", rc);\n    if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET)\n      cfprintf(clr_api_error, outfile, \" at offset %ld in replacement\", (long int)nsize);\n    cfprintf(clr_api_error, outfile, \": \");\n    if (!print_error_message(rc, \"\", \"\")) return PR_ABEND;\n    if (rc == PCRE2_ERROR_NOMEMORY &&\n        (xoptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)\n      cfprintf(clr_api_error, outfile, \": %ld code units are needed\", (long int)nsize);\n\n    if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET)\n      {\n      cfprintf(clr_api_error, outfile, \"\\n        here: \");\n      if (nsize > 0)\n        {\n        ptrunc(clr_input, rbptr, full_rlen, nsize, TRUE, utf, outfile);\n        fprintf(outfile, \" \");\n        }\n      cfprintf(clr_api_error, outfile, \"|<--|\");\n      if (nsize < full_rlen)\n        {\n        fprintf(outfile, \" \");\n        ptrunc(clr_input, rbptr, full_rlen, nsize, FALSE, utf, outfile);\n        }\n      }\n    }\n  else\n    {\n    cfprintf(clr_api_error, outfile, \"%2d: \", rc);\n    pchars(clr_api_error, rep_out_buffer, nsize, utf, outfile);\n    }\n\n  fprintf(outfile, \"\\n\");\n  show_memory = FALSE;\n\n  /* Show final ovector contents and resulting heapframe size if requested. */\n\n  if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)\n    show_ovector(ovector, oveccount);\n\n  if ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0 &&\n      (dat_datctl.control & CTL_DFA) == 0)\n    show_heapframes_size();\n\n  return PR_OK;\n  }   /* End of substitution handling */\n\n/* When a replacement string is not provided, run a loop for global matching\nwith one of the basic matching functions. */\n\nfor (gmatched = 0;; gmatched++)\n  {\n  PCRE2_SIZE j;\n  int capcount;\n\n  /* Fill the ovector with junk to detect elements that do not get set\n  when they should be. */\n\n  for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;\n\n  /* When matching is via pcre2_match(), we will detect the use of JIT via the\n  stack callback function. */\n\n  jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0;\n\n  /* Do timing if required. */\n\n  if (timeitm > 0)\n    {\n    int i;\n    clock_t start_time, time_taken;\n    FILE *saved_outfile = outfile;\n\n    outfile = NULL;  /* Suppress callout output during the timing repetitions */\n\n    if ((dat_datctl.control & CTL_DFA) != 0)\n      {\n      if ((dat_datctl.options & PCRE2_DFA_RESTART) != 0)\n        {\n        outfile = saved_outfile;\n        cfprintf(clr_test_error, outfile, \"** Timing DFA restarts is not supported\\n\");\n        return PR_ABEND;\n        }\n      if (dfa_workspace == NULL)\n        dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));\n      start_time = clock();\n      for (i = 0; i < timeitm; i++)\n        {\n        (void)pcre2_dfa_match(compiled_code, pp, arg_ulen,\n          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,\n          use_dat_context, dfa_workspace, DFA_WS_DIMENSION);\n        }\n      }\n\n    else if ((pat_patctl.control & CTL_JITFAST) != 0)\n      {\n      start_time = clock();\n      for (i = 0; i < timeitm; i++)\n        {\n        (void)pcre2_jit_match(compiled_code, pp, arg_ulen,\n          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,\n          use_dat_context);\n        }\n      }\n\n    else\n      {\n      start_time = clock();\n      for (i = 0; i < timeitm; i++)\n        {\n        (void)pcre2_match(compiled_code, pp, arg_ulen,\n          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,\n          use_dat_context);\n        }\n      }\n    total_match_time += (time_taken = clock() - start_time);\n\n    outfile = saved_outfile;\n    cfprintf(clr_profiling, outfile, \"Match time %7.4f microseconds\\n\",\n      ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeitm);\n    }\n\n  /* Find the heap, match and depth limits if requested. The depth and heap\n  limits are not relevant for JIT. The return from check_match_limit() is the\n  return from the final call to pcre2_match() or pcre2_dfa_match(). */\n\n  if ((dat_datctl.control & (CTL_FINDLIMITS|CTL_FINDLIMITS_NOHEAP)) != 0)\n    {\n    if ((dat_datctl.control & CTL_FINDLIMITS_NOHEAP) == 0 &&\n        (compiled_code->executable_jit == NULL ||\n          (dat_datctl.options & PCRE2_NO_JIT) != 0))\n      {\n      (void)check_match_limit(pp, arg_ulen, PCRE2_ERROR_HEAPLIMIT, \"heap\");\n      }\n\n    capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_MATCHLIMIT,\n      \"match\");\n\n    if (compiled_code->executable_jit == NULL ||\n        (dat_datctl.options & PCRE2_NO_JIT) != 0 ||\n        (dat_datctl.control & CTL_DFA) != 0)\n      {\n      capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_DEPTHLIMIT,\n        \"depth\");\n      }\n\n    if (capcount == 0)\n      {\n      cfprintf(clr_api_error, outfile, \"Matched, but offsets vector is too small to show all matches\\n\");\n      capcount = dat_datctl.oveccount;\n      }\n    }\n\n  /* Otherwise just run a single match. */\n\n  else\n    {\n    /* Run a single DFA or NFA match. */\n\n    if (malloc_testing) CLEAR_HEAP_FRAMES();\n    reset_callout_state();\n    if ((dat_datctl.control & CTL_DFA) != 0)\n      {\n      if (dfa_workspace == NULL)\n        dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));\n      if (dfa_matched++ == 0)\n        dfa_workspace[0] = -1;  /* To catch bad restart */\n      capcount = pcre2_dfa_match(compiled_code, pp, arg_ulen,\n        dat_datctl.offset, dat_datctl.options | g_notempty, match_data,\n        use_dat_context, dfa_workspace, DFA_WS_DIMENSION);\n      if (capcount == 0)\n        {\n        cfprintf(clr_api_error, outfile, \"Matched, but offsets vector is too small to show all matches\\n\");\n        capcount = dat_datctl.oveccount;\n        }\n      }\n    else\n      {\n      if ((pat_patctl.control & CTL_JITFAST) != 0)\n        capcount = pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n          dat_datctl.options | g_notempty, match_data, use_dat_context);\n      else\n        capcount = pcre2_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n          dat_datctl.options | g_notempty, match_data, use_dat_context);\n      if (capcount == 0)\n        {\n        cfprintf(clr_api_error, outfile, \"Matched, but too many substrings\\n\");\n        capcount = dat_datctl.oveccount;\n        }\n      }\n\n    /* For malloc testing, we repeat the matching. */\n\n    if (malloc_testing && (dat_datctl.control & CTL_CALLOUT_NONE) != 0)\n      {\n      for (int i = 0, target_mallocs = mallocs_called; i <= target_mallocs; i++)\n        {\n        FILE *saved_outfile = outfile;\n\n        CLEAR_HEAP_FRAMES();\n        reset_callout_state();\n\n        mallocs_until_failure = i;\n        outfile = NULL;  /* Suppress callout output during the malloc repetitions */\n\n        if ((dat_datctl.control & CTL_DFA) != 0)\n          {\n          if (dfa_matched++ == 0)\n            dfa_workspace[0] = -1;  /* To catch bad restart */\n          capcount = pcre2_dfa_match(compiled_code, pp, arg_ulen,\n            dat_datctl.offset, dat_datctl.options | g_notempty, match_data,\n            use_dat_context, dfa_workspace, DFA_WS_DIMENSION);\n          }\n        else\n          {\n          if ((pat_patctl.control & CTL_JITFAST) != 0)\n            capcount = pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n              dat_datctl.options | g_notempty, match_data, use_dat_context);\n          else\n            capcount = pcre2_match(compiled_code, pp, arg_ulen, dat_datctl.offset,\n              dat_datctl.options | g_notempty, match_data, use_dat_context);\n          }\n\n        mallocs_until_failure = INT_MAX;\n        outfile = saved_outfile;\n\n        if (capcount == 0)\n          capcount = dat_datctl.oveccount;\n\n        if (i < target_mallocs && capcount != PCRE2_ERROR_NOMEMORY)\n          {\n          cfprintf(clr_test_error, outfile, \"** malloc() match test did not fail as expected (%d)\\n\",\n                  capcount);\n          return PR_ABEND;\n          }\n        }\n      }\n    }\n\n  /* Verify that it's safe to call pcre2_next_match with rc < 0. */\n\n  if (capcount < 0 && (dat_datctl.control & CTL_ANYGLOB) != 0)\n    {\n      BOOL rc_nextmatch;\n      PCRE2_SIZE tmp_offset = 0xcd;\n      uint32_t tmp_options = 0xcd;\n      rc_nextmatch = pcre2_next_match(match_data, &tmp_offset, &tmp_options);\n      if (rc_nextmatch || tmp_offset != 0xcd || tmp_options != 0xcd)\n        {\n        cfprintf(clr_test_error, outfile, \"** unexpected pcre2_next_match() for rc < 0\\n\");\n        return PR_ABEND;\n        }\n    }\n\n  /* The result of the match is now in capcount. First handle a successful\n  match. If pp was forced to be NULL (to test NULL handling) it will have been\n  treated as an empty string if the length was zero. So, re-create that for\n  outputting, preserving the invariant that pp is a valid pointer to a region\n  of length len followed by a null. */\n\n  if (capcount >= 0)\n    {\n    if (pp == NULL)\n      {\n#ifdef SUPPORT_VALGRIND\n      /* Mark the start of dbuffer addressable again. */\n      VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, CU2BYTES(1));\n#endif\n      pp = (PCRE2_UCHAR *)dbuffer;\n      *pp = 0;\n      }\n\n    if ((unsigned)capcount > oveccount)   /* Check for lunatic return value */\n      {\n      cfprintf(clr_test_error, outfile,\n        \"** PCRE2 error: returned count %d is too big for ovector count %d\\n\",\n        capcount, oveccount);\n      return PR_ABEND;\n      }\n\n    /* If PCRE2_COPY_MATCHED_SUBJECT was set, check that things are as they\n    should be, but not for fast JIT, where it isn't supported. */\n\n    if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0 &&\n        (pat_patctl.control & CTL_JITFAST) == 0)\n      {\n      if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) == 0)\n        cfprintf(clr_test_error, outfile,\n          \"** PCRE2 error: flag not set after copy_matched_subject\\n\");\n\n      if (match_data->subject == pp)\n        cfprintf(clr_test_error, outfile,\n          \"** PCRE2 error: copy_matched_subject has not copied\\n\");\n\n      if (memcmp(match_data->subject, pp, ulen) != 0)\n        cfprintf(clr_test_error, outfile,\n          \"** PCRE2 error: copy_matched_subject mismatch\\n\");\n      }\n\n    /* If this is not the first time round a global loop, check that the\n    returned string has advanced.\n\n    There is one known case where this doesn't happen: when you have a\n    \"badly-behaved\" pattern which uses \\K in a lookaround, and breaks the core\n    sanity rule that start_offset <= ovector[0] <= ovector[1]. An example would\n    be /(?<=\\Ka)/g matching \"aaa\".\n      * first attempt, start_offset=0: ovector[0]=0, ovector[1]=1\n      * second attempt, start_offset=1: ovector[0]=0, ovector[1]=1\n\n    You can see that even though we *always* ensure that start_offset advances,\n    this doesn't guarantee to avoid duplicate matches.\n\n    The pcre2test behaviour is to return all the matches found, except in the\n    case where two adjacent matches are an exact duplicate. */\n\n    if (gmatched > 0 &&\n        !(dat_datctl.offset <= ovector[0] && ovector[0] <= ovector[1]) &&\n        pp + ovector[0] == ovecsave[0] && pp + ovector[1] == ovecsave[1])\n      {\n      cfprintf(clr_api_error, outfile, \"global repeat returned the same match as previous\\n\");\n      goto NEXT_MATCH;\n      }\n\n    /* Outside of this exceptional case, we check that either we have a\n    \"badly-behaved\" match (note that not all badly-behaved matches are caught\n    above, only *duplicate* ones); or else in the well-behaved case the match\n    must make progress.\n\n    \"Progress\" is measured as ovector[1] strictly advancing, or, an empty match\n    after a non-empty match. */\n\n    if (gmatched > 0 &&\n        (dat_datctl.offset <= ovector[0] && ovector[0] <= ovector[1]) &&\n        !(pp + ovector[1] > ovecsave[1] ||\n          (ovector[1] == ovector[0] && ovecsave[1] != ovecsave[0] &&\n           pp + ovector[1] == ovecsave[1])))\n      {\n      cfprintf(clr_test_error, outfile,\n        \"** PCRE2 error: global repeat did not make progress\\n\");\n      return PR_ABEND;\n      }\n\n    ovecsave[0] = pp + ovector[0];\n    ovecsave[1] = pp + ovector[1];\n\n    /* \"allcaptures\" requests showing of all captures in the pattern, to check\n    unset ones at the end. It may be set on the pattern or the data. Implement\n    by setting capcount to the maximum. This is not relevant for DFA matching,\n    so ignore it (warning given above). */\n\n    if ((dat_datctl.control & (CTL_ALLCAPTURES|CTL_DFA)) == CTL_ALLCAPTURES)\n      {\n      capcount = maxcapcount + 1;   /* Allow for full match */\n      if ((unsigned)capcount > oveccount) capcount = oveccount;\n      }\n\n    /* \"allvector\" request showing the entire ovector. */\n\n    if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0) capcount = oveccount;\n\n    /* Output the captured substrings. Note that, for the matched string,\n    the use of \\K in an assertion can make the start later than the end. */\n\n    for (int i = 0; i < 2*capcount; i += 2)\n      {\n      PCRE2_SIZE lleft, lmiddle, lright;\n      PCRE2_SIZE start = ovector[i];\n      PCRE2_SIZE end = ovector[i+1];\n\n      if (start > end)\n        {\n        start = ovector[i+1];\n        end = ovector[i];\n        cfprintf(clr_api_error, outfile, \"Start of matched string is beyond its end - \"\n          \"displaying from end to start.\\n\");\n        }\n\n      fprintf(outfile, \"%2d: \", i/2);\n\n      /* Check for an unset group */\n\n      if (start == PCRE2_UNSET && end == PCRE2_UNSET)\n        {\n        fprintf(outfile, \"<unset>\\n\");\n        continue;\n        }\n\n      /* Check for silly offsets, in particular, values that have not been\n      set when they should have been. However, if we are past the end of the\n      captures for this pattern (\"allvector\" causes this), or if we are DFA\n      matching, it isn't an error if the entry is unchanged. */\n\n      if (start > ulen || end > ulen)\n        {\n        if (((dat_datctl.control & CTL_DFA) != 0 ||\n              i >= (int)(2*maxcapcount + 2)) &&\n            start == JUNK_OFFSET && end == JUNK_OFFSET)\n          fprintf(outfile, \"<unchanged>\\n\");\n        else\n          cfprintf(clr_test_error, outfile, \"** ERROR: bad value(s) for offset(s): 0x%lx 0x%lx\\n\",\n            (unsigned long int)start, (unsigned long int)end);\n        continue;\n        }\n\n      /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with\n      JIT, it is disabled above, with a comment.) When the match is done by the\n      interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is\n      set, and if the leftmost consulted character is before the start of the\n      match or the rightmost consulted character is past the end of the match,\n      we want to show all consulted characters for the main matched string, and\n      indicate which were lookarounds. */\n\n      if (i == 0)\n        {\n        BOOL showallused;\n        PCRE2_SIZE leftchar, rightchar;\n\n        if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)\n          {\n          leftchar = match_data->leftchar;\n          rightchar = match_data->rightchar;\n          showallused = i == 0 && (leftchar < start || rightchar > end);\n          }\n        else showallused = FALSE;\n\n        if (showallused)\n          {\n          lleft = pchars(clr_none, pp + leftchar, start - leftchar, utf, outfile);\n          lmiddle = pchars(clr_none, pp + start, end - start, utf, outfile);\n          lright = pchars(clr_none, pp + end, rightchar - end, utf, outfile);\n          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)\n            fprintf(outfile, \" (JIT)\");\n          fprintf(outfile, \"\\n    \");\n          for (j = 0; j < lleft; j++) fprintf(outfile, \"<\");\n          for (j = 0; j < lmiddle; j++) fprintf(outfile, \" \");\n          for (j = 0; j < lright; j++) fprintf(outfile, \">\");\n          }\n\n        /* When a pattern contains \\K, the start of match position may be\n        different to the start of the matched string. When this is the case,\n        show it when requested. */\n\n        else if ((dat_datctl.control & CTL_STARTCHAR) != 0)\n          {\n          PCRE2_SIZE startchar;\n          startchar = pcre2_get_startchar(match_data);\n          lleft = pchars(clr_none, pp + startchar, start - startchar, utf, outfile);\n          pchars(clr_none, pp+start, end - start, utf, outfile);\n          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)\n            fprintf(outfile, \" (JIT)\");\n          if (startchar != start)\n            {\n            fprintf(outfile, \"\\n    \");\n            for (j = 0; j < lleft; j++) fprintf(outfile, \"^\");\n            }\n          }\n\n        /* Otherwise, just show the matched string. */\n\n        else\n          {\n          pchars(clr_none, pp + start, end - start, utf, outfile);\n          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)\n            fprintf(outfile, \" (JIT)\");\n          }\n        }\n\n      /* Not the main matched string. Just show it unadorned. */\n\n      else\n        {\n        pchars(clr_none, pp + start, end - start, utf, outfile);\n        }\n\n      fprintf(outfile, \"\\n\");\n\n      /* Note: don't use the start/end variables here because we want to\n      show the text from what is reported as the end. */\n\n      if ((dat_datctl.control & CTL_ALLAFTERTEXT) != 0 ||\n          (i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0))\n        {\n        fprintf(outfile, \"%2d+ \", i/2);\n        pchars(clr_none, pp + ovector[i+1], ulen - ovector[i+1], utf, outfile);\n        fprintf(outfile, \"\\n\");\n        }\n      }\n\n    /* Output (*MARK) data if requested */\n\n    if ((dat_datctl.control & CTL_MARK) != 0 &&\n         match_data->mark != NULL)\n      {\n      fprintf(outfile, \"MK: \");\n      pchars(clr_none, match_data->mark - 1, -1, utf, outfile);\n      fprintf(outfile, \"\\n\");\n      }\n\n    /* Process copy/get strings */\n\n    if (!copy_and_get(utf, capcount)) return PR_ABEND;\n\n    }    /* End of handling a successful match */\n\n  /* There was a partial match. The value of ovector[0] is the bumpalong point,\n  that is, startchar, not any \\K point that might have been passed. When JIT is\n  not in use, \"allusedtext\" may be set, in which case we indicate the leftmost\n  consulted character. */\n\n  else if (capcount == PCRE2_ERROR_PARTIAL)\n    {\n    PCRE2_SIZE leftchar;\n    int backlength;\n    int rubriclength = 0;\n\n    if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)\n      {\n      leftchar = match_data->leftchar;\n      }\n    else leftchar = ovector[0];\n\n    cfprintf(clr_api_error, outfile, \"Partial match\");\n    if ((dat_datctl.control & CTL_MARK) != 0 &&\n         match_data->mark != NULL)\n      {\n      fprintf(outfile, \", mark=\");\n      rubriclength = pchars(clr_none, match_data->mark - 1, -1, utf, outfile);\n      rubriclength += 7;\n      }\n    fprintf(outfile, \": \");\n    rubriclength += 15;\n\n    backlength = pchars(clr_input, pp + leftchar, ovector[0] - leftchar, utf, outfile);\n    pchars(clr_input, pp + ovector[0], ovector[1] - ovector[0], utf, outfile);\n\n    if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)\n      fprintf(outfile, \" (JIT)\");\n    fprintf(outfile, \"\\n\");\n\n    if (backlength != 0)\n      {\n      for (int i = 0; i < rubriclength; i++) fprintf(outfile, \" \");\n      for (int i = 0; i < backlength; i++) fprintf(outfile, \"<\");\n      fprintf(outfile, \"\\n\");\n      }\n\n    if (ulen != ovector[1])\n      cfprintf(clr_test_error, outfile, \"** ovector[1] is not equal to the subject length: \"\n        \"%ld != %ld\\n\", (unsigned long int)ovector[1], (unsigned long int)ulen);\n\n    /* Process copy/get strings */\n\n    if (!copy_and_get(utf, 1)) return PR_ABEND;\n\n    /* \"allvector\" outputs the entire vector */\n\n    if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)\n      show_ovector(ovector, oveccount);\n\n    break;  /* Out of the /g loop */\n    }       /* End of handling partial match */\n\n  /* A \"normal\" match failure. There will be a negative error number in\n  capcount. */\n\n  else\n    {\n    switch(capcount)\n      {\n      case PCRE2_ERROR_NOMATCH:\n      if (gmatched == 0)\n        {\n        cfprintf(clr_api_error, outfile, \"No match\");\n        if ((dat_datctl.control & CTL_MARK) != 0 &&\n             match_data->mark != NULL)\n          {\n          fprintf(outfile, \", mark = \");\n          pchars(clr_none, match_data->mark - 1, -1, utf, outfile);\n          }\n        if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)\n          fprintf(outfile, \" (JIT)\");\n        fprintf(outfile, \"\\n\");\n\n        /* \"allvector\" outputs the entire vector */\n\n        if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)\n          show_ovector(ovector, oveccount);\n        }\n      break;\n\n      case PCRE2_ERROR_BADUTFOFFSET:\n      cfprintf(clr_api_error, outfile, \"Error %d (bad UTF-\" STR(PCRE2_CODE_UNIT_WIDTH)\n        \" offset)\\n\", capcount);\n      break;\n\n      default:\n      cfprintf(clr_api_error, outfile, \"Failed: error %d: \", capcount);\n      if (!print_error_message(capcount, \"\", \"\")) return PR_ABEND;\n      if (capcount <= PCRE2_ERROR_UTF8_ERR1 &&\n          capcount >= PCRE2_ERROR_UTF32_ERR2)\n        {\n        PCRE2_SIZE startchar;\n        startchar = pcre2_get_startchar(match_data);\n        cfprintf(clr_api_error, outfile, \" at offset %\" SIZ_FORM, startchar);\n        }\n      fprintf(outfile, \"\\n\");\n      break;\n      }\n\n    break;  /* Out of the /g loop */\n    }       /* End of failed match handling */\n\n  /* Control reaches here after a match. If we are not doing a global search,\n  we are done. Otherwise, we adjust the parameters for the next match and\n  continue the matching loop. */\n\n  NEXT_MATCH:\n\n  if ((dat_datctl.control & CTL_ANYGLOB) == 0)\n    break;\n  else\n    {\n    PCRE2_SIZE new_start_offset = (PCRE2_SIZE)-1;\n    BOOL rc_nextmatch;\n\n    /* Use pcre2_next_match() to safely advance. This guarantees that the start\n    offset will advance, except after an empty match, in which case it sets\n    the PCRE2_NOTEMPTY_ATSTART flag to ensure the next match does not return a\n    duplicate. */\n\n    rc_nextmatch = pcre2_next_match(match_data, &new_start_offset, &g_notempty);\n    if (!rc_nextmatch) break;  /* Out of the /g loop */\n\n    /* For a normal global (/g) iteration, update the start offset, leaving\n    other parameters alone. */\n\n    if ((dat_datctl.control & CTL_GLOBAL) != 0)\n      {\n      dat_datctl.offset = new_start_offset;\n      }\n\n    /* For altglobal, just update the pointer and length. */\n\n    else\n      {\n      pp += new_start_offset;\n      len -= CU2BYTES(new_start_offset);\n      ulen -= new_start_offset;\n      if (arg_ulen != PCRE2_ZERO_TERMINATED) arg_ulen -= new_start_offset;\n      }\n    }\n  }  /* End of global loop */\n\n/* All matching is done; show the resulting heapframe size if requested. */\n\nif ((dat_datctl.control2 & CTL2_HEAPFRAMES_SIZE) != 0 &&\n    (dat_datctl.control & CTL_DFA) == 0)\n  show_heapframes_size();\n\nshow_memory = FALSE;\nreturn PR_OK;\n}\n\n\n\n/*************************************************\n*      Initialise the mode-dependent globals     *\n*************************************************/\n\n/* Sets up the global variables used for the current test mode. */\n\nstatic void\ninit_globals(void)\n{\ngeneral_context = pcre2_general_context_create(&my_malloc, &my_free, NULL);\ngeneral_context_copy = pcre2_general_context_copy(general_context);\ndefault_pat_context = pcre2_compile_context_create(general_context);\npat_context = pcre2_compile_context_copy(default_pat_context);\ndefault_dat_context = pcre2_match_context_create(general_context);\ndat_context = pcre2_match_context_copy(default_dat_context);\ndefault_con_context = pcre2_convert_context_create(general_context);\ncon_context = pcre2_convert_context_copy(default_con_context);\nmatch_data = pcre2_match_data_create(max_oveccount, general_context);\nrep_in_buffer = malloc(sizeof(PCRE2_UCHAR) * rep_in_buffer_size);\nrep_out_buffer = malloc(sizeof(PCRE2_UCHAR) * rep_out_buffer_size);\n\n/* Set a default parentheses nest limit that is large enough to run the\nstandard tests (this also exercises the function). */\n\npcre2_set_parens_nest_limit(default_pat_context, PARENS_NEST_DEFAULT);\n}\n\n/* Frees the global variables used for the current test mode. */\n\nstatic void\nfree_globals(void)\n{\npcre2_maketables_free(general_context, locale_tables);\npcre2_match_data_free(match_data);\npcre2_code_free(compiled_code);\n\nwhile(patstacknext-- > 0)\n  {\n  compiled_code = patstack[patstacknext];\n  pcre2_code_free(compiled_code);\n  }\n\npcre2_jit_free_unused_memory(general_context);\nif (jit_stack != NULL)\n  {\n  pcre2_jit_stack_free(jit_stack);\n  }\n\npcre2_general_context_free(general_context);\npcre2_general_context_free(general_context_copy);\npcre2_compile_context_free(pat_context);\npcre2_compile_context_free(default_pat_context);\npcre2_match_context_free(dat_context);\npcre2_match_context_free(default_dat_context);\npcre2_convert_context_free(default_con_context);\npcre2_convert_context_free(con_context);\nfree(rep_in_buffer);\nfree(rep_out_buffer);\n}\n\n\n\n/*************************************************\n*            Specific function tests             *\n*************************************************/\n\n/* For tests exercising a mismatched bitmode, identify a suitable API. */\n\n#if (defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + \\\n     defined(SUPPORT_PCRE2_32)) >= 2\n\n#if defined(SUPPORT_PCRE2_8) && PCRE2_CODE_UNIT_WIDTH != 8\n#define BITOTHER 8\n#elif defined(SUPPORT_PCRE2_16) && PCRE2_CODE_UNIT_WIDTH != 16\n#define BITOTHER 16\n#elif defined(SUPPORT_PCRE2_32) && PCRE2_CODE_UNIT_WIDTH != 32\n#define BITOTHER 32\n#else\n#error \"One other bit width must be supported\"\n#endif\n\n#endif\n\n/* These are tests of the public API functions in PCRE2, which wouldn't\notherwise be covered by pcre2test. This usually implies they are error cases,\nor edge cases that are hard to hit in the standard flow of compile-match or\ncompile-substitute.\n\nI think of them as perhaps more like unit tests, although they are still testing\nthe public API, rather than internal modules.\n\nInside pcre2test, which can be dynamically linked to lib-pcreX.so, we don't\nhave access to any non-exported functions. */\n\nstatic void\nunittest(void)\n{\nint rc;\nuint32_t uval;\nPCRE2_SIZE sizeval;\nPCRE2_UCHAR *sptrval;\nconst char *failure = NULL;\npcre2_general_context *test_gen_context = NULL, *test_gen_context_copy = NULL;\npcre2_compile_context *test_pat_context = NULL, *test_pat_context_copy = NULL;\npcre2_match_context *test_dat_context = NULL, *test_dat_context_copy = NULL;\npcre2_convert_context *test_con_context = NULL, *test_con_context_copy = NULL;\npcre2_match_data *test_match_data = NULL;\npcre2_code *test_compiled_code = NULL;\nPCRE2_UCHAR pattern[] = { CHAR_A, CHAR_B, CHAR_C, 0 };\nPCRE2_UCHAR callout_int_pattern[] = {\n  CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, CHAR_C, CHAR_RIGHT_PARENTHESIS, 0 };\nPCRE2_UCHAR callout_str_pattern[] = {\n  CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, CHAR_C, CHAR_QUOTATION_MARK,\n  CHAR_Z, CHAR_QUOTATION_MARK, CHAR_RIGHT_PARENTHESIS, 0 };\nPCRE2_UCHAR capture_pattern[] = {\n  CHAR_A, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, CHAR_LESS_THAN_SIGN,\n  CHAR_N, CHAR_GREATER_THAN_SIGN, CHAR_DOT, CHAR_ASTERISK,\n  CHAR_RIGHT_PARENTHESIS, CHAR_Z, 0 };\nPCRE2_UCHAR subject_abcz[] = {\n  CHAR_A, CHAR_B, CHAR_C, CHAR_Z, 0 };\nPCRE2_UCHAR substitute_subject[6];\nPCRE2_UCHAR name_n[] = { CHAR_N, 0 };\n#ifdef BITOTHER\nG(pcre2_code_,BITOTHER) *bitother_code = NULL;\nG(PCRE2_,G(UCHAR,BITOTHER)) bitother_pattern[] = { CHAR_A, CHAR_B, CHAR_C, 0 };\n#endif\nint errorcode;\nPCRE2_SIZE erroroffset;\nPCRE2_UCHAR errorbuffer[256];\n#if PCRE2_CODE_UNIT_WIDTH == 8\nchar errorbuffer8[256];\nregex_t test_preg;\n#endif\nvoid *invalid_code = NULL;\nconst uint8_t *test_tables = NULL;\nPCRE2_UCHAR copy_buf[64];\nPCRE2_UCHAR **stringlist;\nPCRE2_SIZE *lengthslist;\nPCRE2_UCHAR replace_buf[64];\npcre2_code *subs_other_code = NULL;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\nmemset(&test_preg, 0, sizeof(test_preg));\n#endif\n\n#if defined PCRE2_DEBUG && !defined NDEBUG\n#define ASSERT(cond, msg) \\\n  do { \\\n    if (!(cond)) { failure = msg \" at \" __FILE__ \":\" STR(__LINE__); goto EXIT; } \\\n  } while (0)\n#else\n#define ASSERT(cond, msg) \\\n  do { \\\n    if (!(cond)) { failure = msg; goto EXIT; } \\\n  } while (0)\n#endif\n\n/* -------------------------- pcre2_config --------------------------------- */\n\nrc = pcre2_config(PCRE2_CONFIG_BSR, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_COMPILED_WIDTHS, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_DEPTHLIMIT, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_EFFECTIVE_LINKSIZE, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_HEAPLIMIT, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_JIT, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_LINKSIZE, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_MATCHLIMIT, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_NEVER_BACKSLASH_C, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_NEWLINE, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_PARENSLIMIT, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_STACKRECURSE, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_TABLES_LENGTH, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_UNICODE, NULL);\nASSERT(rc == (int)sizeof(uint32_t), \"pcre2_config(NULL)\");\n\n#ifdef SUPPORT_JIT\nrc = pcre2_config(PCRE2_CONFIG_JITTARGET, NULL);\nASSERT(rc > 0, \"pcre2_config(NULL)\");\n#endif\nrc = pcre2_config(PCRE2_CONFIG_UNICODE_VERSION, NULL);\nASSERT(rc > 4, \"pcre2_config(NULL)\");\nrc = pcre2_config(PCRE2_CONFIG_VERSION, NULL);\nASSERT(rc > 4, \"pcre2_config(NULL)\");\n\nrc = pcre2_config(PCRE2_CONFIG_MATCHLIMIT, &uval);\nASSERT(rc == 0, \"pcre2_config(PCRE2_CONFIG_MATCHLIMIT)\");\n\nrc = pcre2_config(999, NULL);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_config(bad option)\");\n\nrc = pcre2_config(999, &uval);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_config(bad option)\");\n\nrc = pcre2_config(PCRE2_CONFIG_STACKRECURSE, &uval);\nASSERT(rc == 0, \"pcre2_config(PCRE2_CONFIG_STACKRECURSE)\");\n\nrc = pcre2_config(PCRE2_CONFIG_LINKSIZE, &uval);\nASSERT(rc == 0, \"pcre2_config(PCRE2_CONFIG_LINKSIZE)\");\n\n/* ------------------------ Context functions ------------------------------ */\n\ntest_gen_context = pcre2_general_context_create(NULL, NULL, NULL);\nASSERT(test_gen_context != NULL, \"pcre2_general_context_create(null)\");\npcre2_general_context_free(test_gen_context);\n\nmallocs_until_failure = 0;\ntest_gen_context = pcre2_general_context_create(&my_malloc, &my_free, NULL);\nASSERT(test_gen_context == NULL, \"pcre2_general_context_create(malloc)\");\n\nmallocs_until_failure = 1;\ntest_gen_context = pcre2_general_context_create(&my_malloc, &my_free, NULL);\nASSERT(test_gen_context != NULL, \"pcre2_general_context_create(malloc)\");\n\ntest_pat_context = pcre2_compile_context_create(test_gen_context);\nASSERT(test_pat_context == NULL, \"pcre2_compile_context_create()\");\ntest_dat_context = pcre2_match_context_create(test_gen_context);\nASSERT(test_dat_context == NULL, \"pcre2_match_context_create()\");\ntest_con_context = pcre2_convert_context_create(test_gen_context);\nASSERT(test_con_context == NULL, \"pcre2_convert_context_create()\");\n\ntest_pat_context = pcre2_compile_context_create(NULL);\nASSERT(test_pat_context != NULL, \"pcre2_compile_context_create(null)\");\npcre2_compile_context_free(test_pat_context);\ntest_dat_context = pcre2_match_context_create(NULL);\nASSERT(test_dat_context != NULL, \"pcre2_match_context_create(null)\");\npcre2_match_context_free(test_dat_context);\ntest_con_context = pcre2_convert_context_create(NULL);\nASSERT(test_con_context != NULL, \"pcre2_convert_context_create(null)\");\npcre2_convert_context_free(test_con_context);\n\nmallocs_until_failure = INT_MAX;\ntest_pat_context = pcre2_compile_context_create(test_gen_context);\nASSERT(test_pat_context != NULL, \"pcre2_compile_context_create()\");\ntest_dat_context = pcre2_match_context_create(test_gen_context);\nASSERT(test_dat_context != NULL, \"pcre2_match_context_create()\");\ntest_con_context = pcre2_convert_context_create(test_gen_context);\nASSERT(test_con_context != NULL, \"pcre2_convert_context_create()\");\n\nmallocs_until_failure = 0;\ntest_gen_context_copy = pcre2_general_context_copy(test_gen_context);\nASSERT(test_gen_context_copy == NULL, \"pcre2_general_context_copy()\");\ntest_pat_context_copy = pcre2_compile_context_copy(test_pat_context);\nASSERT(test_pat_context_copy == NULL, \"pcre2_compile_context_copy()\");\ntest_dat_context_copy = pcre2_match_context_copy(test_dat_context);\nASSERT(test_dat_context_copy == NULL, \"pcre2_match_context_copy()\");\ntest_con_context_copy = pcre2_convert_context_copy(test_con_context);\nASSERT(test_con_context_copy == NULL, \"pcre2_convert_context_copy()\");\n\nmallocs_until_failure = INT_MAX;\ntest_gen_context_copy = pcre2_general_context_copy(test_gen_context);\nASSERT(test_gen_context_copy != NULL, \"pcre2_general_context_copy()\");\ntest_pat_context_copy = pcre2_compile_context_copy(test_pat_context);\nASSERT(test_pat_context_copy != NULL, \"pcre2_compile_context_copy()\");\ntest_dat_context_copy = pcre2_match_context_copy(test_dat_context);\nASSERT(test_dat_context_copy != NULL, \"pcre2_match_context_copy()\");\ntest_con_context_copy = pcre2_convert_context_copy(test_con_context);\nASSERT(test_con_context_copy != NULL, \"pcre2_convert_context_copy()\");\n\nrc = pcre2_set_compile_extra_options(test_pat_context, 0);\nASSERT(rc == 0, \"pcre2_set_compile_extra_options()\");\n\nrc = pcre2_set_max_pattern_length(test_pat_context, 10);\nASSERT(rc == 0, \"pcre2_set_max_pattern_length()\");\n\nrc = pcre2_set_max_pattern_compiled_length(test_pat_context, 256);\nASSERT(rc == 0, \"pcre2_set_max_pattern_compiled_length()\");\n\nrc = pcre2_set_max_varlookbehind(test_pat_context, 0);\nASSERT(rc == 0, \"pcre2_set_max_varlookbehind()\");\n\nrc = pcre2_set_offset_limit(test_dat_context, 0);\nASSERT(rc == 0, \"pcre2_set_offset_limit()\");\n\nrc = pcre2_set_bsr(test_pat_context, 999);\nASSERT(rc == PCRE2_ERROR_BADDATA, \"pcre2_set_bsr()\");\n\nrc = pcre2_set_newline(test_pat_context, 999);\nASSERT(rc == PCRE2_ERROR_BADDATA, \"pcre2_set_newline()\");\n\nrc = pcre2_set_recursion_limit(test_dat_context, 10);\nASSERT(rc == 0, \"pcre2_set_recursion_limit()\");\n\nrc = pcre2_set_recursion_memory_management(test_dat_context, NULL, NULL, NULL);\nASSERT(rc == 0, \"pcre2_set_recursion_memory_management()\");\n\nrc = pcre2_set_optimize(NULL, PCRE2_OPTIMIZATION_NONE);\nASSERT(rc == PCRE2_ERROR_NULL, \"pcre2_set_optimize(null)\");\n\nrc = pcre2_set_optimize(test_pat_context, PCRE2_AUTO_POSSESS - 1);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_set_optimize(bad option)\");\n\nrc = pcre2_set_optimize(test_pat_context, PCRE2_START_OPTIMIZE_OFF + 1);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_set_optimize(bad option)\");\n\nrc = pcre2_set_glob_escape(test_con_context, 0);\nASSERT(rc == 0, \"pcre2_set_glob_escape(0)\");\n\nrc = pcre2_set_glob_escape(test_con_context, 1);\nASSERT(rc == PCRE2_ERROR_BADDATA, \"pcre2_set_glob_escape(1)\");\n\nrc = pcre2_set_glob_escape(test_con_context, 256);\nASSERT(rc == PCRE2_ERROR_BADDATA, \"pcre2_set_glob_escape(256)\");\n\n/* ----------------------- pcre2_compile ----------------------------------- */\n\ntest_compiled_code = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED,\n  0, NULL, &erroroffset, test_pat_context);\nASSERT(test_compiled_code == NULL, \"test pattern compilation\");\n\ntest_compiled_code = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, NULL, test_pat_context);\nASSERT(test_compiled_code == NULL && errorcode == PCRE2_ERROR_NULL_ERROROFFSET, \"test pattern compilation\");\n\ntest_compiled_code = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, test_pat_context);\nASSERT(test_compiled_code != NULL && errorcode == 100 && erroroffset == 0, \"test pattern compilation\");\n\n#ifdef BITOTHER\nbitother_code = G(pcre2_compile_,BITOTHER)(bitother_pattern,\n  PCRE2_ZERO_TERMINATED, 0, &errorcode, &erroroffset, NULL);\nASSERT(bitother_code != NULL, \"bitmode mismatch compile\");\n#endif\n\n/* ---------------------- Match data functions ----------------------------- */\n\nmallocs_until_failure = 0;\ntest_match_data = pcre2_match_data_create(10, test_gen_context);\nASSERT(test_match_data == NULL, \"pcre2_match_data_create()\");\n\ntest_match_data = pcre2_match_data_create(10, NULL);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create()\");\nASSERT(pcre2_get_ovector_count(test_match_data) == 10, \"pcre2_get_ovector_count()\");\n\nsizeval = pcre2_get_match_data_size(test_match_data);\nASSERT(sizeval >= 2, \"pcre2_get_match_data_size()\");\n\nmallocs_until_failure = INT_MAX;\n\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create(0, test_gen_context);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create()\");\nASSERT(pcre2_get_ovector_count(test_match_data) == 1, \"pcre2_get_ovector_count()\");\n\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create_from_pattern(NULL, NULL);\nASSERT(test_match_data == NULL, \"pcre2_match_data_create_from_pattern(null)\");\n\ntest_match_data = pcre2_match_data_create_from_pattern(test_compiled_code, NULL);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create_from_pattern()\");\nASSERT(pcre2_get_ovector_count(test_match_data) == 1, \"pcre2_get_ovector_count()\");\n\nmallocs_until_failure = 0;\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create_from_pattern(test_compiled_code,\n  test_gen_context);\nASSERT(test_match_data == NULL, \"pcre2_match_data_create_from_pattern()\");\n\nmallocs_until_failure = INT_MAX;\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create_from_pattern(test_compiled_code,\n  test_gen_context);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create_from_pattern()\");\n\nrc = pcre2_match(test_compiled_code, pattern, PCRE2_ZERO_TERMINATED, 0,\n  PCRE2_COPY_MATCHED_SUBJECT, test_match_data, NULL);\nASSERT(rc == 1, \"pcre2_match()\");\n\npcre2_match_data_free(test_match_data);\ntest_match_data = NULL;\n\n/* ----------------------- pcre2_pattern_info ------------------------------ */\n\nrc = pcre2_pattern_info(NULL, PCRE2_INFO_NEWLINE, &uval);\nASSERT(rc == PCRE2_ERROR_NULL, \"pcre2_pattern_info(null)\");\n\nrc = pcre2_pattern_info(test_compiled_code, 999, NULL);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_pattern_info(bad option)\");\n\nrc = pcre2_pattern_info(test_compiled_code, 999, &uval);\nASSERT(rc == PCRE2_ERROR_BADOPTION, \"pcre2_pattern_info(bad option)\");\n\ninvalid_code = malloc(1024);\nASSERT(invalid_code != NULL, \"malloc()\");\nmemset(invalid_code, 0, 1024);\nrc = pcre2_pattern_info(invalid_code, PCRE2_INFO_NEWLINE, &uval);\nASSERT(rc == PCRE2_ERROR_BADMAGIC, \"pcre2_pattern_info(bad magic)\");\n\n#ifdef BITOTHER\nrc = pcre2_pattern_info((pcre2_code *)bitother_code, PCRE2_INFO_NEWLINE, &uval);\nASSERT(rc == PCRE2_ERROR_BADMODE, \"pcre2_pattern_info(bitmode mismatch)\");\n#endif\n\n#ifdef SUPPORT_JIT\nsizeval = 0xcdcdcdcd;\nrc = pcre2_pattern_info(test_compiled_code, PCRE2_INFO_JITSIZE, &sizeval);\nASSERT(rc == 0 && sizeval == 0, \"pcre2_pattern_info(JIT)\");\n\nif (pcre2_jit_compile(test_compiled_code, PCRE2_JIT_COMPLETE) == 0)\n  {\n  rc = pcre2_pattern_info(test_compiled_code, PCRE2_INFO_JITSIZE, &sizeval);\n  ASSERT(rc == 0 && sizeval > 0, \"pcre2_pattern_info(JIT after compile)\");\n  }\n#endif\n\n/* ----------------------- POSIX functions --------------------------------- */\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\n\n#if defined(EBCDIC) && !EBCDIC_IO\n#define BUFFER_OUTPUT ebcdic_to_ascii_str((uint8_t *)errorbuffer8, sizeof(errorbuffer8));\n#else\n#define BUFFER_OUTPUT\n#endif\n\nrc = pcre2_regcomp(&test_preg, \"abc\", 0);\nASSERT(rc == 0, \"pcre2_regcomp()\");\n\nrc = pcre2_regexec(&test_preg, \"zabcz\", 0, NULL, 0);\nASSERT(rc == 0, \"pcre2_regexec(0)\");\n\nrc = pcre2_regexec(&test_preg, \"zabcz\", 0, NULL, REG_STARTEND);\nASSERT(rc == REG_INVARG, \"pcre2_regexec(REG_STARTEND)\");\n\nmemset(errorbuffer8, 0, sizeof(errorbuffer8));\nrc = regerror(REG_ASSERT, NULL, errorbuffer8, sizeof(errorbuffer8));\nBUFFER_OUTPUT\nASSERT(rc > 0 && rc <= (int)sizeof(errorbuffer8) && rc == (int)strlen(errorbuffer8) + 1, \"regerror()\");\n\nrc = regerror(REG_NOMATCH, NULL, errorbuffer8, sizeof(errorbuffer8));\nBUFFER_OUTPUT\nASSERT(rc > 0 && rc <= (int)sizeof(errorbuffer8) && rc == (int)strlen(errorbuffer8) + 1, \"regerror()\");\n\nrc = regerror(REG_ASSERT-1, NULL, errorbuffer8, sizeof(errorbuffer8));\nBUFFER_OUTPUT\nASSERT(rc == (int)strlen(\"unknown error code\")+1 && strcmp(errorbuffer8, \"unknown error code\") == 0, \"regerror(bad error code)\");\n\nrc = regerror(REG_NOMATCH+1, NULL, errorbuffer8, sizeof(errorbuffer8));\nBUFFER_OUTPUT\nASSERT(rc == (int)strlen(\"unknown error code\")+1 && strcmp(errorbuffer8, \"unknown error code\") == 0, \"regerror(bad error code)\");\n\n#undef BUFFER_OUTPUT\n\n#endif\n\n/* -------------------- pcre2_get_error_message ---------------------------- */\n\n#if defined(EBCDIC) && !EBCDIC_IO\n#define BUFFER_OUTPUT ebcdic_to_ascii_str(errorbuffer, sizeof(errorbuffer));\n#else\n#define BUFFER_OUTPUT\n#endif\n\nrc = pcre2_get_error_message(PCRE2_ERROR_BADDATA, NULL, 0);\nASSERT(rc == PCRE2_ERROR_NOMEMORY, \"pcre2_get_error_message(null)\");\n\nmemset(errorbuffer, 0, sizeof(errorbuffer));\nrc = pcre2_get_error_message(PCRE2_ERROR_BADDATA, errorbuffer, 0);\nBUFFER_OUTPUT\nASSERT(rc == PCRE2_ERROR_NOMEMORY, \"pcre2_get_error_message(null)\");\n\nrc = pcre2_get_error_message(PCRE2_ERROR_BADDATA, errorbuffer, 4);\nBUFFER_OUTPUT\nASSERT(rc == PCRE2_ERROR_NOMEMORY && pcre2_strcmp_c8(errorbuffer, \"bad\") == 0, \"pcre2_get_error_message(null)\");\n\nrc = pcre2_get_error_message(PCRE2_ERROR_BADDATA, errorbuffer, 14);\nBUFFER_OUTPUT\nASSERT(rc == PCRE2_ERROR_NOMEMORY && pcre2_strcmp_c8(errorbuffer, \"bad data valu\") == 0, \"pcre2_get_error_message(null)\");\n\nrc = pcre2_get_error_message(PCRE2_ERROR_BADDATA, errorbuffer, 15);\nBUFFER_OUTPUT\nASSERT(rc == 14 && pcre2_strcmp_c8(errorbuffer, \"bad data value\") == 0, \"pcre2_get_error_message(null)\");\n\n#undef BUFFER_OUTPUT\n\n/* ----------------------- pcre2_maketables -------------------------------- */\n\ntest_tables = pcre2_maketables(NULL);\nASSERT(test_tables != NULL, \"pcre2_maketables(null)\");\npcre2_maketables_free(NULL, test_tables);\n\ntest_tables = pcre2_maketables(test_gen_context);\nASSERT(test_tables != NULL, \"pcre2_maketables()\");\npcre2_maketables_free(test_gen_context, test_tables);\n\nmallocs_until_failure = 0;\ntest_tables = pcre2_maketables(test_gen_context);\nASSERT(test_tables == NULL, \"pcre2_maketables()\");\n\nmallocs_until_failure = INT_MAX;\n\n/* -------------------- pcre2_callout_enumerate ---------------------------- */\n\nrc = pcre2_callout_enumerate(NULL, callout_enumerate_function_void, NULL);\nASSERT(rc == PCRE2_ERROR_NULL, \"pcre2_callout_enumerate(null)\");\n\nrc = pcre2_callout_enumerate(invalid_code, callout_enumerate_function_void, NULL);\nASSERT(rc == PCRE2_ERROR_BADMAGIC, \"pcre2_callout_enumerate(invalid)\");\n\n#ifdef BITOTHER\nrc = pcre2_callout_enumerate((pcre2_code *)bitother_code, callout_enumerate_function_void, NULL);\nASSERT(rc == PCRE2_ERROR_BADMODE, \"pcre2_callout_enumerate(bitmode mismatch)\");\n#endif\n\npcre2_code_free(test_compiled_code);\ntest_compiled_code = pcre2_compile(callout_int_pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, NULL);\nASSERT(test_compiled_code != NULL, \"test pattern compilation\");\n\nrc = pcre2_callout_enumerate(test_compiled_code, callout_enumerate_function_void, &errorcode);\nASSERT(rc == 0, \"pcre2_callout_enumerate(void)\");\n\nerrorcode = -12;\nrc = pcre2_callout_enumerate(test_compiled_code, callout_enumerate_function_fail, &errorcode);\nASSERT(rc == -12, \"pcre2_callout_enumerate(fail)\");\n\npcre2_code_free(test_compiled_code);\ntest_compiled_code = pcre2_compile(callout_str_pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, NULL);\nASSERT(test_compiled_code != NULL, \"test pattern compilation\");\n\nerrorcode = -123;\nrc = pcre2_callout_enumerate(test_compiled_code, callout_enumerate_function_fail, &errorcode);\nASSERT(rc == -123, \"pcre2_callout_enumerate(fail)\");\n\n/* ---------------------- Substring functions ------------------------------ */\n\n/* Must handle NULL without crashing. */\npcre2_substring_free(NULL);\npcre2_substring_list_free(NULL);\n\npcre2_code_free(test_compiled_code);\ntest_compiled_code = pcre2_compile(capture_pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, NULL);\nASSERT(test_compiled_code != NULL, \"test pattern compilation\");\n\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create_from_pattern(\n  test_compiled_code, test_gen_context);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create()\");\n\nrc = pcre2_match(test_compiled_code, subject_abcz, PCRE2_ZERO_TERMINATED, 0,\n  0, test_match_data, NULL);\nASSERT(rc == 2, \"pcre2_match()\");\n\n/* Test the functions with insufficient buffer size. It hardly seems worth\nadding controls to the pcre2test input file format to exercise this case. */\n\nsizeval = 2;\nrc = pcre2_substring_copy_byname(test_match_data, name_n, copy_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMEMORY && sizeval == 2, \"pcre2_substring_copy_byname(small buffer)\");\nsizeval = 3;\nrc = pcre2_substring_copy_byname(test_match_data, name_n, copy_buf, &sizeval);\nASSERT(rc == 0 && sizeval == 2, \"pcre2_substring_copy_byname(small buffer)\");\nsizeval = 4;\nrc = pcre2_substring_copy_byname(test_match_data, name_n, copy_buf, &sizeval);\nASSERT(rc == 0 && sizeval == 2, \"pcre2_substring_copy_byname(small buffer)\");\n\nsizeval = 2;\nrc = pcre2_substring_copy_bynumber(test_match_data, 1, copy_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMEMORY && sizeval == 2, \"pcre2_substring_copy_bynumber(small buffer)\");\nsizeval = 3;\nrc = pcre2_substring_copy_bynumber(test_match_data, 1, copy_buf, &sizeval);\nASSERT(rc == 0 && sizeval == 2, \"pcre2_substring_copy_bynumber(small buffer)\");\n\nmallocs_until_failure = 0;\n\nsizeval = 0;\nsptrval = NULL;\nrc = pcre2_substring_get_byname(test_match_data, name_n, &sptrval, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMEMORY && sptrval == NULL, \"pcre2_substring_get_byname(small buffer)\");\n\nsizeval = 0;\nrc = pcre2_substring_get_bynumber(test_match_data, 1, &sptrval, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMEMORY && sptrval == NULL, \"pcre2_substring_get_bynumber(small buffer)\");\n\nmallocs_until_failure = INT_MAX;\n\n/* Test some unusual conditions, for which again it doesn't seem worth adding\npcre2test controls. */\n\nsizeval = 0;\nrc = pcre2_substring_length_bynumber(test_match_data, 1, &sizeval);\nASSERT(rc == 0 && sizeval == 2, \"pcre2_substring_length_bynumber()\");\nrc = pcre2_substring_length_bynumber(test_match_data, 1, NULL);\nASSERT(rc == 0, \"pcre2_substring_length_bynumber()\");\n\nsizeval = 0;\nrc = pcre2_substring_length_byname(test_match_data, name_n, &sizeval);\nASSERT(rc == 0 && sizeval == 2, \"pcre2_substring_length_byname()\");\nrc = pcre2_substring_length_byname(test_match_data, name_n, NULL);\nASSERT(rc == 0, \"pcre2_substring_length_byname()\");\n\n/* Test pcre2_substring_list_get() with some NULL inputs. */\n\nrc = pcre2_substring_list_get(test_match_data, &stringlist, &lengthslist);\nASSERT(rc == 0 && stringlist != NULL && lengthslist != NULL, \"pcre2_substring_list_get()\");\npcre2_substring_list_free(stringlist);\n\nstringlist = NULL;\nrc = pcre2_substring_list_get(test_match_data, &stringlist, NULL);\nASSERT(rc == 0 && stringlist != NULL, \"pcre2_substring_list_get()\");\npcre2_substring_list_free(stringlist);\n\nmallocs_until_failure = 0;\n\nstringlist = NULL;\nrc = pcre2_substring_list_get(test_match_data, &stringlist, &lengthslist);\nASSERT(rc == PCRE2_ERROR_NOMEMORY && stringlist == NULL, \"pcre2_substring_list_get()\");\n\nmallocs_until_failure = INT_MAX;\n\n/* Test after an unsuccessful match. */\n\nrc = pcre2_match(test_compiled_code, subject_abcz, PCRE2_ZERO_TERMINATED, 2,\n  0, test_match_data, NULL);\nASSERT(rc == PCRE2_ERROR_NOMATCH, \"pcre2_match()\");\n\nsizeval = 4;\nrc = pcre2_substring_copy_byname(test_match_data, name_n, copy_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMATCH, \"pcre2_substring_copy_byname(no match)\");\nrc = pcre2_substring_copy_bynumber(test_match_data, 1, copy_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMATCH, \"pcre2_substring_copy_bynumber(no match)\");\nrc = pcre2_substring_get_byname(test_match_data, name_n, &sptrval, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMATCH && sptrval == NULL, \"pcre2_substring_get_byname(no match)\");\nrc = pcre2_substring_get_bynumber(test_match_data, 1, &sptrval, &sizeval);\nASSERT(rc == PCRE2_ERROR_NOMATCH && sptrval == NULL, \"pcre2_substring_get_bynumber(no match)\");\n\n/* ------------- pcre2_substitute with PCRE2_SUBSTITUTE_MATCHED ------------ */\n\n/* There are some specific edge cases here that would be a pain to exercise via\nthe standard pcre2test modifiers. The documentation is clear that when you do\na match externally and pass it in with PCRE2_SUBSTITUTE_MATCHED, you must also\npass the same match options. Here we test what happens when you don't. */\n\npcre2_code_free(test_compiled_code);\ntest_compiled_code = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, NULL);\nASSERT(test_compiled_code != NULL, \"test pattern compilation\");\n\nsubs_other_code = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED,\n  0, &errorcode, &erroroffset, NULL);\nASSERT(subs_other_code != NULL, \"test pattern compilation\");\n\npcre2_match_data_free(test_match_data);\ntest_match_data = pcre2_match_data_create_from_pattern(\n  test_compiled_code, NULL);\nASSERT(test_match_data != NULL, \"pcre2_match_data_create()\");\n\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nrc = pcre2_match(test_compiled_code, substitute_subject, PCRE2_ZERO_TERMINATED,\n  0, 0, test_match_data, NULL);\nASSERT(rc == 1, \"pcre2_match()\");\n\n/* Baseline, should succeed */\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(test_compiled_code, substitute_subject,\n  PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_MATCHED, test_match_data, NULL,\n  NULL, 0, replace_buf, &sizeval);\nASSERT(rc == 1, \"pcre2_substitute(baseline)\");\n\n/* Move the subject pointer, but keep the contents and length the same */\nmemcpy(substitute_subject+1, subject_abcz, sizeof(subject_abcz));\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(test_compiled_code, substitute_subject+1,\n  PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_MATCHED, test_match_data, NULL,\n  NULL, 0, replace_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_DIFFSUBSSUBJECT, \"pcre2_substitute(moved)\");\n\n/* Keep the subject pointer the same but extend its length */\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nsubstitute_subject[4] = CHAR_Y;\nsubstitute_subject[5] = 0;\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(test_compiled_code, substitute_subject,\n  PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_MATCHED, test_match_data, NULL,\n  NULL, 0, replace_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_DIFFSUBSSUBJECT, \"pcre2_substitute(extended)\");\n\n/* Change the offset */\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(test_compiled_code, substitute_subject,\n  PCRE2_ZERO_TERMINATED, 1, PCRE2_SUBSTITUTE_MATCHED, test_match_data, NULL,\n  NULL, 0, replace_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_DIFFSUBSOFFSET, \"pcre2_substitute(offset)\");\n\n/* Change the options */\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(test_compiled_code, substitute_subject,\n  PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_MATCHED | PCRE2_NOTEMPTY,\n  test_match_data, NULL, NULL, 0, replace_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_DIFFSUBSOPTIONS, \"pcre2_substitute(options)\");\n\n/* Change the pattern */\nmemcpy(substitute_subject, subject_abcz, sizeof(subject_abcz));\nsizeval = sizeof(replace_buf)/sizeof(*replace_buf);\nrc = pcre2_substitute(subs_other_code, substitute_subject,\n  PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_MATCHED, test_match_data, NULL,\n  NULL, 0, replace_buf, &sizeval);\nASSERT(rc == PCRE2_ERROR_DIFFSUBSPATTERN, \"pcre2_substitute(pattern)\");\n\n/* ------------------------------------------------------------------------- */\n\n#undef ASSERT\nEXIT:\n\nmallocs_until_failure = INT_MAX;\n\n#if PCRE2_CODE_UNIT_WIDTH == 8\npcre2_regfree(&test_preg);\n#endif\n\nif (test_compiled_code != NULL) pcre2_code_free(test_compiled_code);\n#ifdef BITOTHER\nif (bitother_code != NULL) G(pcre2_code_free_,BITOTHER)(bitother_code);\n#endif\nif (subs_other_code != NULL) pcre2_code_free(subs_other_code);\n\nif (test_match_data != NULL) pcre2_match_data_free(test_match_data);\n\nif (test_con_context_copy != NULL) pcre2_convert_context_free(test_con_context_copy);\nif (test_dat_context_copy != NULL) pcre2_match_context_free(test_dat_context_copy);\nif (test_pat_context_copy != NULL) pcre2_compile_context_free(test_pat_context_copy);\nif (test_gen_context_copy != NULL) pcre2_general_context_free(test_gen_context_copy);\nif (test_con_context != NULL) pcre2_convert_context_free(test_con_context);\nif (test_dat_context != NULL) pcre2_match_context_free(test_dat_context);\nif (test_pat_context != NULL) pcre2_compile_context_free(test_pat_context);\nif (test_gen_context != NULL) pcre2_general_context_free(test_gen_context);\n\nfree(invalid_code);\n\nif (failure != NULL)\n  {\n  cfprintf(clr_test_error, stderr, \"pcre2test: Unit test error in %s\\n\", failure);\n  exit(1);\n  }\n}\n\n#undef BITOTHER\n\n\n/* -------------------- Undo the macro definitions --------------------------*/\n\n#undef pbuffer\n#undef pbuffer_size\n\n#undef utf_to_ord\n\n#undef compiled_code\n#undef general_context\n#undef general_context_copy\n#undef pat_context\n#undef default_pat_context\n#undef con_context\n#undef default_con_context\n#undef dat_context\n#undef default_dat_context\n#undef match_data\n#undef jit_stack\n#undef jit_stack_size\n#undef patstack\n#undef patstacknext\n#undef rep_in_buffer\n#undef rep_in_buffer_size\n#undef rep_out_buffer\n#undef rep_out_buffer_size\n\n#undef jit_callback\n#undef pcre2_strcmp_c8\n#undef pcre2_strlen\n#undef pchars\n#undef ptrunc\n#undef config_str\n#undef check_modifier\n#undef decode_modifiers\n#undef pattern_info\n#undef show_memory_info\n#undef show_framesize\n#undef show_heapframes_size\n#undef print_error_message_file\n#undef print_error_message\n#undef callout_enumerate_function\n#undef callout_enumerate_function_void\n#undef callout_enumerate_function_fail\n#undef show_pattern_info\n#undef serial_error\n#undef process_command\n#undef process_pattern\n#undef have_active_pattern\n#undef free_active_pattern\n#undef check_match_limit\n#undef substitute_callout_function\n#undef substitute_case_callout_function\n#undef callout_function\n#undef copy_and_get\n#undef copy_substitute_string\n#undef process_data\n#undef init_globals\n#undef free_globals\n#undef unittest\n\n\n\n/* End of pcre2test_inc.h */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/LICENSE",
    "content": "Copyright notice:\n\n (C) 1995-2026 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n"
  },
  {
    "path": "vendor/core/vendor/zlib/adler32.c",
    "content": "/* adler32.c -- compute the Adler-32 checksum of a data stream\n * Copyright (C) 1995-2011, 2016 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#include \"zutil.h\"\n\n#define BASE 65521U     /* largest prime smaller than 65536 */\n#define NMAX 5552\n/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */\n\n#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}\n#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);\n#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);\n#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);\n#define DO16(buf)   DO8(buf,0); DO8(buf,8);\n\n/* use NO_DIVIDE if your processor does not do division in hardware --\n   try it both ways to see which is faster */\n#ifdef NO_DIVIDE\n/* note that this assumes BASE is 65521, where 65536 % 65521 == 15\n   (thank you to John Reiser for pointing this out) */\n#  define CHOP(a) \\\n    do { \\\n        unsigned long tmp = a >> 16; \\\n        a &= 0xffffUL; \\\n        a += (tmp << 4) - tmp; \\\n    } while (0)\n#  define MOD28(a) \\\n    do { \\\n        CHOP(a); \\\n        if (a >= BASE) a -= BASE; \\\n    } while (0)\n#  define MOD(a) \\\n    do { \\\n        CHOP(a); \\\n        MOD28(a); \\\n    } while (0)\n#  define MOD63(a) \\\n    do { /* this assumes a is not negative */ \\\n        z_off64_t tmp = a >> 32; \\\n        a &= 0xffffffffL; \\\n        a += (tmp << 8) - (tmp << 5) + tmp; \\\n        tmp = a >> 16; \\\n        a &= 0xffffL; \\\n        a += (tmp << 4) - tmp; \\\n        tmp = a >> 16; \\\n        a &= 0xffffL; \\\n        a += (tmp << 4) - tmp; \\\n        if (a >= BASE) a -= BASE; \\\n    } while (0)\n#else\n#  define MOD(a) a %= BASE\n#  define MOD28(a) a %= BASE\n#  define MOD63(a) a %= BASE\n#endif\n\n/* ========================================================================= */\nuLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {\n    unsigned long sum2;\n    unsigned n;\n\n    /* split Adler-32 into component sums */\n    sum2 = (adler >> 16) & 0xffff;\n    adler &= 0xffff;\n\n    /* in case user likes doing a byte at a time, keep it fast */\n    if (len == 1) {\n        adler += buf[0];\n        if (adler >= BASE)\n            adler -= BASE;\n        sum2 += adler;\n        if (sum2 >= BASE)\n            sum2 -= BASE;\n        return adler | (sum2 << 16);\n    }\n\n    /* initial Adler-32 value (deferred check for len == 1 speed) */\n    if (buf == Z_NULL)\n        return 1L;\n\n    /* in case short lengths are provided, keep it somewhat fast */\n    if (len < 16) {\n        while (len--) {\n            adler += *buf++;\n            sum2 += adler;\n        }\n        if (adler >= BASE)\n            adler -= BASE;\n        MOD28(sum2);            /* only added so many BASE's */\n        return adler | (sum2 << 16);\n    }\n\n    /* do length NMAX blocks -- requires just one modulo operation */\n    while (len >= NMAX) {\n        len -= NMAX;\n        n = NMAX / 16;          /* NMAX is divisible by 16 */\n        do {\n            DO16(buf);          /* 16 sums unrolled */\n            buf += 16;\n        } while (--n);\n        MOD(adler);\n        MOD(sum2);\n    }\n\n    /* do remaining bytes (less than NMAX, still just one modulo) */\n    if (len) {                  /* avoid modulos if none remaining */\n        while (len >= 16) {\n            len -= 16;\n            DO16(buf);\n            buf += 16;\n        }\n        while (len--) {\n            adler += *buf++;\n            sum2 += adler;\n        }\n        MOD(adler);\n        MOD(sum2);\n    }\n\n    /* return recombined sums */\n    return adler | (sum2 << 16);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) {\n    return adler32_z(adler, buf, len);\n}\n\n/* ========================================================================= */\nlocal uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) {\n    unsigned long sum1;\n    unsigned long sum2;\n    unsigned rem;\n\n    /* for negative len, return invalid adler32 as a clue for debugging */\n    if (len2 < 0)\n        return 0xffffffffUL;\n\n    /* the derivation of this formula is left as an exercise for the reader */\n    MOD63(len2);                /* assumes len2 >= 0 */\n    rem = (unsigned)len2;\n    sum1 = adler1 & 0xffff;\n    sum2 = rem * sum1;\n    MOD(sum2);\n    sum1 += (adler2 & 0xffff) + BASE - 1;\n    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;\n    if (sum1 >= BASE) sum1 -= BASE;\n    if (sum1 >= BASE) sum1 -= BASE;\n    if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);\n    if (sum2 >= BASE) sum2 -= BASE;\n    return sum1 | (sum2 << 16);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) {\n    return adler32_combine_(adler1, adler2, len2);\n}\n\nuLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) {\n    return adler32_combine_(adler1, adler2, len2);\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/compress.c",
    "content": "/* compress.c -- compress a memory buffer\n * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#define ZLIB_INTERNAL\n#include \"zlib.h\"\n\n/* ===========================================================================\n     Compresses the source buffer into the destination buffer. The level\n   parameter has the same meaning as in deflateInit.  sourceLen is the byte\n   length of the source buffer. Upon entry, destLen is the total size of the\n   destination buffer, which must be at least 0.1% larger than sourceLen plus\n   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.\n\n     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer,\n   Z_STREAM_ERROR if the level parameter is invalid.\n\n     The _z versions of the functions take size_t length arguments.\n*/\nint ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source,\n                        z_size_t sourceLen, int level) {\n    z_stream stream;\n    int err;\n    const uInt max = (uInt)-1;\n    z_size_t left;\n\n    if ((sourceLen > 0 && source == NULL) ||\n        destLen == NULL || (*destLen > 0 && dest == NULL))\n        return Z_STREAM_ERROR;\n\n    left = *destLen;\n    *destLen = 0;\n\n    stream.zalloc = (alloc_func)0;\n    stream.zfree = (free_func)0;\n    stream.opaque = (voidpf)0;\n\n    err = deflateInit(&stream, level);\n    if (err != Z_OK) return err;\n\n    stream.next_out = dest;\n    stream.avail_out = 0;\n    stream.next_in = (z_const Bytef *)source;\n    stream.avail_in = 0;\n\n    do {\n        if (stream.avail_out == 0) {\n            stream.avail_out = left > (z_size_t)max ? max : (uInt)left;\n            left -= stream.avail_out;\n        }\n        if (stream.avail_in == 0) {\n            stream.avail_in = sourceLen > (z_size_t)max ? max :\n                                                          (uInt)sourceLen;\n            sourceLen -= stream.avail_in;\n        }\n        err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);\n    } while (err == Z_OK);\n\n    *destLen = (z_size_t)(stream.next_out - dest);\n    deflateEnd(&stream);\n    return err == Z_STREAM_END ? Z_OK : err;\n}\nint ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,\n                      uLong sourceLen, int level) {\n    int ret;\n    z_size_t got = *destLen;\n    ret = compress2_z(dest, &got, source, sourceLen, level);\n    *destLen = (uLong)got;\n    return ret;\n}\n/* ===========================================================================\n */\nint ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source,\n                       z_size_t sourceLen) {\n    return compress2_z(dest, destLen, source, sourceLen,\n                       Z_DEFAULT_COMPRESSION);\n}\nint ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,\n                     uLong sourceLen) {\n    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);\n}\n\n/* ===========================================================================\n     If the default memLevel or windowBits for deflateInit() is changed, then\n   this function needs to be updated.\n */\nz_size_t ZEXPORT compressBound_z(z_size_t sourceLen) {\n    z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +\n                     (sourceLen >> 25) + 13;\n    return bound < sourceLen ? (z_size_t)-1 : bound;\n}\nuLong ZEXPORT compressBound(uLong sourceLen) {\n    z_size_t bound = compressBound_z(sourceLen);\n    return (uLong)bound != bound ? (uLong)-1 : (uLong)bound;\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/crc32.c",
    "content": "/* crc32.c -- compute the CRC-32 of a data stream\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * This interleaved implementation of a CRC makes use of pipelined multiple\n * arithmetic-logic units, commonly found in modern CPU cores. It is due to\n * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution.\n */\n\n/* @(#) $Id$ */\n\n/*\n  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore\n  protection on the static variables used to control the first-use generation\n  of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should\n  first call get_crc_table() to initialize the tables before allowing more than\n  one thread to use crc32().\n\n  MAKECRCH can be #defined to write out crc32.h. A main() routine is also\n  produced, so that this one source file can be compiled to an executable.\n */\n\n#ifdef MAKECRCH\n#  include <stdio.h>\n#  ifndef DYNAMIC_CRC_TABLE\n#    define DYNAMIC_CRC_TABLE\n#  endif\n#endif\n#ifdef DYNAMIC_CRC_TABLE\n#  define Z_ONCE\n#endif\n\n#include \"zutil.h\"      /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */\n\n#ifdef HAVE_S390X_VX\n#  include \"contrib/crc32vx/crc32_vx_hooks.h\"\n#endif\n\n /*\n  A CRC of a message is computed on N braids of words in the message, where\n  each word consists of W bytes (4 or 8). If N is 3, for example, then three\n  running sparse CRCs are calculated respectively on each braid, at these\n  indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ...\n  This is done starting at a word boundary, and continues until as many blocks\n  of N * W bytes as are available have been processed. The results are combined\n  into a single CRC at the end. For this code, N must be in the range 1..6 and\n  W must be 4 or 8. The upper limit on N can be increased if desired by adding\n  more #if blocks, extending the patterns apparent in the code. In addition,\n  crc32.h would need to be regenerated, if the maximum N value is increased.\n\n  N and W are chosen empirically by benchmarking the execution time on a given\n  processor. The choices for N and W below were based on testing on Intel Kaby\n  Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64\n  Octeon II processors. The Intel, AMD, and ARM processors were all fastest\n  with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4.\n  They were all tested with either gcc or clang, all using the -O3 optimization\n  level. Your mileage may vary.\n */\n\n/* Define N */\n#ifdef Z_TESTN\n#  define N Z_TESTN\n#else\n#  define N 5\n#endif\n#if N < 1 || N > 6\n#  error N must be in 1..6\n#endif\n\n/*\n  z_crc_t must be at least 32 bits. z_word_t must be at least as long as\n  z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and\n  that bytes are eight bits.\n */\n\n/*\n  Define W and the associated z_word_t type. If W is not defined, then a\n  braided calculation is not used, and the associated tables and code are not\n  compiled.\n */\n#ifdef Z_TESTW\n#  if Z_TESTW-1 != -1\n#    define W Z_TESTW\n#  endif\n#else\n#  ifdef MAKECRCH\n#    define W 8         /* required for MAKECRCH */\n#  else\n#    if defined(__x86_64__) || defined(__aarch64__)\n#      define W 8\n#    else\n#      define W 4\n#    endif\n#  endif\n#endif\n#ifdef W\n#  if W == 8 && defined(Z_U8)\n     typedef Z_U8 z_word_t;\n#  elif defined(Z_U4)\n#    undef W\n#    define W 4\n     typedef Z_U4 z_word_t;\n#  else\n#    undef W\n#  endif\n#endif\n\n/* If available, use the ARM processor CRC32 instruction. */\n#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \\\n    defined(W) && W == 8\n#  define ARMCRC32\n#endif\n\n#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))\n/*\n  Swap the bytes in a z_word_t to convert between little and big endian. Any\n  self-respecting compiler will optimize this to a single machine byte-swap\n  instruction, if one is available. This assumes that word_t is either 32 bits\n  or 64 bits.\n */\nlocal z_word_t byte_swap(z_word_t word) {\n#  if W == 8\n    return\n        (word & 0xff00000000000000) >> 56 |\n        (word & 0xff000000000000) >> 40 |\n        (word & 0xff0000000000) >> 24 |\n        (word & 0xff00000000) >> 8 |\n        (word & 0xff000000) << 8 |\n        (word & 0xff0000) << 24 |\n        (word & 0xff00) << 40 |\n        (word & 0xff) << 56;\n#  else   /* W == 4 */\n    return\n        (word & 0xff000000) >> 24 |\n        (word & 0xff0000) >> 8 |\n        (word & 0xff00) << 8 |\n        (word & 0xff) << 24;\n#  endif\n}\n#endif\n\n#ifdef DYNAMIC_CRC_TABLE\n/* =========================================================================\n * Table of powers of x for combining CRC-32s, filled in by make_crc_table()\n * below.\n */\n   local z_crc_t FAR x2n_table[32];\n#else\n/* =========================================================================\n * Tables for byte-wise and braided CRC-32 calculations, and a table of powers\n * of x for combining CRC-32s, all made by make_crc_table().\n */\n#  include \"crc32.h\"\n#endif\n\n/* CRC polynomial. */\n#define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */\n\n/*\n  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,\n  reflected. For speed, this requires that a not be zero.\n */\nlocal uLong multmodp(uLong a, uLong b) {\n    uLong m, p;\n\n    m = (uLong)1 << 31;\n    p = 0;\n    for (;;) {\n        if (a & m) {\n            p ^= b;\n            if ((a & (m - 1)) == 0)\n                break;\n        }\n        m >>= 1;\n        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;\n    }\n    return p;\n}\n\n/*\n  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been\n  initialized. n must not be negative.\n */\nlocal uLong x2nmodp(z_off64_t n, unsigned k) {\n    uLong p;\n\n    p = (uLong)1 << 31;             /* x^0 == 1 */\n    while (n) {\n        if (n & 1)\n            p = multmodp(x2n_table[k & 31], p);\n        n >>= 1;\n        k++;\n    }\n    return p;\n}\n\n#ifdef DYNAMIC_CRC_TABLE\n/* =========================================================================\n * Build the tables for byte-wise and braided CRC-32 calculations, and a table\n * of powers of x for combining CRC-32s.\n */\nlocal z_crc_t FAR crc_table[256];\n#ifdef W\n   local z_word_t FAR crc_big_table[256];\n   local z_crc_t FAR crc_braid_table[W][256];\n   local z_word_t FAR crc_braid_big_table[W][256];\n   local void braid(z_crc_t [][256], z_word_t [][256], int, int);\n#endif\n#ifdef MAKECRCH\n   local void write_table(FILE *, const z_crc_t FAR *, int);\n   local void write_table32hi(FILE *, const z_word_t FAR *, int);\n   local void write_table64(FILE *, const z_word_t FAR *, int);\n#endif /* MAKECRCH */\n\n/* State for once(). */\nlocal z_once_t made = Z_ONCE_INIT;\n\n/*\n  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:\n  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.\n\n  Polynomials over GF(2) are represented in binary, one bit per coefficient,\n  with the lowest powers in the most significant bit. Then adding polynomials\n  is just exclusive-or, and multiplying a polynomial by x is a right shift by\n  one. If we call the above polynomial p, and represent a byte as the\n  polynomial q, also with the lowest power in the most significant bit (so the\n  byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,\n  where a mod b means the remainder after dividing a by b.\n\n  This calculation is done using the shift-register method of multiplying and\n  taking the remainder. The register is initialized to zero, and for each\n  incoming bit, x^32 is added mod p to the register if the bit is a one (where\n  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x\n  (which is shifting right by one and adding x^32 mod p if the bit shifted out\n  is a one). We start with the highest power (least significant bit) of q and\n  repeat for all eight bits of q.\n\n  The table is simply the CRC of all possible eight bit values. This is all the\n  information needed to generate CRCs on data a byte at a time for all\n  combinations of CRC register values and incoming bytes.\n */\n\nlocal void make_crc_table(void) {\n    unsigned i, j, n;\n    z_crc_t p;\n\n    /* initialize the CRC of bytes tables */\n    for (i = 0; i < 256; i++) {\n        p = i;\n        for (j = 0; j < 8; j++)\n            p = p & 1 ? (p >> 1) ^ POLY : p >> 1;\n        crc_table[i] = p;\n#ifdef W\n        crc_big_table[i] = byte_swap(p);\n#endif\n    }\n\n    /* initialize the x^2^n mod p(x) table */\n    p = (z_crc_t)1 << 30;         /* x^1 */\n    x2n_table[0] = p;\n    for (n = 1; n < 32; n++)\n        x2n_table[n] = p = (z_crc_t)multmodp(p, p);\n\n#ifdef W\n    /* initialize the braiding tables -- needs x2n_table[] */\n    braid(crc_braid_table, crc_braid_big_table, N, W);\n#endif\n\n#ifdef MAKECRCH\n    {\n        /*\n          The crc32.h header file contains tables for both 32-bit and 64-bit\n          z_word_t's, and so requires a 64-bit type be available. In that case,\n          z_word_t must be defined to be 64-bits. This code then also generates\n          and writes out the tables for the case that z_word_t is 32 bits.\n         */\n#if !defined(W) || W != 8\n#  error Need a 64-bit integer type in order to generate crc32.h.\n#endif\n        FILE *out;\n        int k, n;\n        z_crc_t ltl[8][256];\n        z_word_t big[8][256];\n\n        out = fopen(\"crc32.h\", \"w\");\n        if (out == NULL) return;\n\n        /* write out little-endian CRC table to crc32.h */\n        fprintf(out,\n            \"/* crc32.h -- tables for rapid CRC calculation\\n\"\n            \" * Generated automatically by crc32.c\\n */\\n\"\n            \"\\n\"\n            \"local const z_crc_t FAR crc_table[] = {\\n\"\n            \"    \");\n        write_table(out, crc_table, 256);\n        fprintf(out,\n            \"};\\n\");\n\n        /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */\n        fprintf(out,\n            \"\\n\"\n            \"#ifdef W\\n\"\n            \"\\n\"\n            \"#if W == 8\\n\"\n            \"\\n\"\n            \"local const z_word_t FAR crc_big_table[] = {\\n\"\n            \"    \");\n        write_table64(out, crc_big_table, 256);\n        fprintf(out,\n            \"};\\n\");\n\n        /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */\n        fprintf(out,\n            \"\\n\"\n            \"#else /* W == 4 */\\n\"\n            \"\\n\"\n            \"local const z_word_t FAR crc_big_table[] = {\\n\"\n            \"    \");\n        write_table32hi(out, crc_big_table, 256);\n        fprintf(out,\n            \"};\\n\"\n            \"\\n\"\n            \"#endif\\n\");\n\n        /* write out braid tables for each value of N */\n        for (n = 1; n <= 6; n++) {\n            fprintf(out,\n            \"\\n\"\n            \"#if N == %d\\n\", n);\n\n            /* compute braid tables for this N and 64-bit word_t */\n            braid(ltl, big, n, 8);\n\n            /* write out braid tables for 64-bit z_word_t to crc32.h */\n            fprintf(out,\n            \"\\n\"\n            \"#if W == 8\\n\"\n            \"\\n\"\n            \"local const z_crc_t FAR crc_braid_table[][256] = {\\n\");\n            for (k = 0; k < 8; k++) {\n                fprintf(out, \"   {\");\n                write_table(out, ltl[k], 256);\n                fprintf(out, \"}%s\", k < 7 ? \",\\n\" : \"\");\n            }\n            fprintf(out,\n            \"};\\n\"\n            \"\\n\"\n            \"local const z_word_t FAR crc_braid_big_table[][256] = {\\n\");\n            for (k = 0; k < 8; k++) {\n                fprintf(out, \"   {\");\n                write_table64(out, big[k], 256);\n                fprintf(out, \"}%s\", k < 7 ? \",\\n\" : \"\");\n            }\n            fprintf(out,\n            \"};\\n\");\n\n            /* compute braid tables for this N and 32-bit word_t */\n            braid(ltl, big, n, 4);\n\n            /* write out braid tables for 32-bit z_word_t to crc32.h */\n            fprintf(out,\n            \"\\n\"\n            \"#else /* W == 4 */\\n\"\n            \"\\n\"\n            \"local const z_crc_t FAR crc_braid_table[][256] = {\\n\");\n            for (k = 0; k < 4; k++) {\n                fprintf(out, \"   {\");\n                write_table(out, ltl[k], 256);\n                fprintf(out, \"}%s\", k < 3 ? \",\\n\" : \"\");\n            }\n            fprintf(out,\n            \"};\\n\"\n            \"\\n\"\n            \"local const z_word_t FAR crc_braid_big_table[][256] = {\\n\");\n            for (k = 0; k < 4; k++) {\n                fprintf(out, \"   {\");\n                write_table32hi(out, big[k], 256);\n                fprintf(out, \"}%s\", k < 3 ? \",\\n\" : \"\");\n            }\n            fprintf(out,\n            \"};\\n\"\n            \"\\n\"\n            \"#endif\\n\"\n            \"\\n\"\n            \"#endif\\n\");\n        }\n        fprintf(out,\n            \"\\n\"\n            \"#endif\\n\");\n\n        /* write out zeros operator table to crc32.h */\n        fprintf(out,\n            \"\\n\"\n            \"local const z_crc_t FAR x2n_table[] = {\\n\"\n            \"    \");\n        write_table(out, x2n_table, 32);\n        fprintf(out,\n            \"};\\n\");\n        fclose(out);\n    }\n#endif /* MAKECRCH */\n}\n\n#ifdef MAKECRCH\n\n/*\n   Write the 32-bit values in table[0..k-1] to out, five per line in\n   hexadecimal separated by commas.\n */\nlocal void write_table(FILE *out, const z_crc_t FAR *table, int k) {\n    int n;\n\n    for (n = 0; n < k; n++)\n        fprintf(out, \"%s0x%08lx%s\", n == 0 || n % 5 ? \"\" : \"    \",\n                (unsigned long)(table[n]),\n                n == k - 1 ? \"\" : (n % 5 == 4 ? \",\\n\" : \", \"));\n}\n\n/*\n   Write the high 32-bits of each value in table[0..k-1] to out, five per line\n   in hexadecimal separated by commas.\n */\nlocal void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {\n    int n;\n\n    for (n = 0; n < k; n++)\n        fprintf(out, \"%s0x%08lx%s\", n == 0 || n % 5 ? \"\" : \"    \",\n                (unsigned long)(table[n] >> 32),\n                n == k - 1 ? \"\" : (n % 5 == 4 ? \",\\n\" : \", \"));\n}\n\n/*\n  Write the 64-bit values in table[0..k-1] to out, three per line in\n  hexadecimal separated by commas. This assumes that if there is a 64-bit\n  type, then there is also a long long integer type, and it is at least 64\n  bits. If not, then the type cast and format string can be adjusted\n  accordingly.\n */\nlocal void write_table64(FILE *out, const z_word_t FAR *table, int k) {\n    int n;\n\n    for (n = 0; n < k; n++)\n        fprintf(out, \"%s0x%016llx%s\", n == 0 || n % 3 ? \"\" : \"    \",\n                (unsigned long long)(table[n]),\n                n == k - 1 ? \"\" : (n % 3 == 2 ? \",\\n\" : \", \"));\n}\n\n/* Actually do the deed. */\nint main(void) {\n    make_crc_table();\n    return 0;\n}\n\n#endif /* MAKECRCH */\n\n#ifdef W\n/*\n  Generate the little and big-endian braid tables for the given n and z_word_t\n  size w. Each array must have room for w blocks of 256 elements.\n */\nlocal void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {\n    int k;\n    z_crc_t i, p, q;\n    for (k = 0; k < w; k++) {\n        p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0);\n        ltl[k][0] = 0;\n        big[w - 1 - k][0] = 0;\n        for (i = 1; i < 256; i++) {\n            ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p);\n            big[w - 1 - k][i] = byte_swap(q);\n        }\n    }\n}\n#endif\n\n#endif /* DYNAMIC_CRC_TABLE */\n\n/* =========================================================================\n * This function can be used by asm versions of crc32(), and to force the\n * generation of the CRC tables in a threaded application.\n */\nconst z_crc_t FAR * ZEXPORT get_crc_table(void) {\n#ifdef DYNAMIC_CRC_TABLE\n    z_once(&made, make_crc_table);\n#endif /* DYNAMIC_CRC_TABLE */\n    return (const z_crc_t FAR *)crc_table;\n}\n\n/* =========================================================================\n * Use ARM machine instructions if available. This will compute the CRC about\n * ten times faster than the braided calculation. This code does not check for\n * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will\n * only be defined if the compilation specifies an ARM processor architecture\n * that has the instructions. For example, compiling with -march=armv8.1-a or\n * -march=armv8-a+crc, or -march=native if the compile machine has the crc32\n * instructions.\n */\n#ifdef ARMCRC32\n\n/*\n   Constants empirically determined to maximize speed. These values are from\n   measurements on a Cortex-A57. Your mileage may vary.\n */\n#define Z_BATCH 3990                /* number of words in a batch */\n#define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */\n#define Z_BATCH_MIN 800             /* fewest words in a final batch */\n\nuLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) {\n    uLong val;\n    z_word_t crc1, crc2;\n    const z_word_t *word;\n    z_word_t val0, val1, val2;\n    z_size_t last, last2, i;\n    z_size_t num;\n\n    /* Return initial CRC, if requested. */\n    if (buf == Z_NULL) return 0;\n\n#ifdef DYNAMIC_CRC_TABLE\n    z_once(&made, make_crc_table);\n#endif /* DYNAMIC_CRC_TABLE */\n\n    /* Pre-condition the CRC */\n    crc = (~crc) & 0xffffffff;\n\n    /* Compute the CRC up to a word boundary. */\n    while (len && ((z_size_t)buf & 7) != 0) {\n        len--;\n        val = *buf++;\n        __asm__ volatile(\"crc32b %w0, %w0, %w1\" : \"+r\"(crc) : \"r\"(val));\n    }\n\n    /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */\n    word = (z_word_t const *)buf;\n    num = len >> 3;\n    len &= 7;\n\n    /* Do three interleaved CRCs to realize the throughput of one crc32x\n       instruction per cycle. Each CRC is calculated on Z_BATCH words. The\n       three CRCs are combined into a single CRC after each set of batches. */\n    while (num >= 3 * Z_BATCH) {\n        crc1 = 0;\n        crc2 = 0;\n        for (i = 0; i < Z_BATCH; i++) {\n            val0 = word[i];\n            val1 = word[i + Z_BATCH];\n            val2 = word[i + 2 * Z_BATCH];\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc) : \"r\"(val0));\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc1) : \"r\"(val1));\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc2) : \"r\"(val2));\n        }\n        word += 3 * Z_BATCH;\n        num -= 3 * Z_BATCH;\n        crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1;\n        crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2;\n    }\n\n    /* Do one last smaller batch with the remaining words, if there are enough\n       to pay for the combination of CRCs. */\n    last = num / 3;\n    if (last >= Z_BATCH_MIN) {\n        last2 = last << 1;\n        crc1 = 0;\n        crc2 = 0;\n        for (i = 0; i < last; i++) {\n            val0 = word[i];\n            val1 = word[i + last];\n            val2 = word[i + last2];\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc) : \"r\"(val0));\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc1) : \"r\"(val1));\n            __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc2) : \"r\"(val2));\n        }\n        word += 3 * last;\n        num -= 3 * last;\n        val = x2nmodp((int)last, 6);\n        crc = multmodp(val, crc) ^ crc1;\n        crc = multmodp(val, crc) ^ crc2;\n    }\n\n    /* Compute the CRC on any remaining words. */\n    for (i = 0; i < num; i++) {\n        val0 = word[i];\n        __asm__ volatile(\"crc32x %w0, %w0, %x1\" : \"+r\"(crc) : \"r\"(val0));\n    }\n    word += num;\n\n    /* Complete the CRC on any remaining bytes. */\n    buf = (const unsigned char FAR *)word;\n    while (len) {\n        len--;\n        val = *buf++;\n        __asm__ volatile(\"crc32b %w0, %w0, %w1\" : \"+r\"(crc) : \"r\"(val));\n    }\n\n    /* Return the CRC, post-conditioned. */\n    return crc ^ 0xffffffff;\n}\n\n#else\n\n#ifdef W\n\n/*\n  Return the CRC of the W bytes in the word_t data, taking the\n  least-significant byte of the word as the first byte of data, without any pre\n  or post conditioning. This is used to combine the CRCs of each braid.\n */\nlocal z_crc_t crc_word(z_word_t data) {\n    int k;\n    for (k = 0; k < W; k++)\n        data = (data >> 8) ^ crc_table[data & 0xff];\n    return (z_crc_t)data;\n}\n\nlocal z_word_t crc_word_big(z_word_t data) {\n    int k;\n    for (k = 0; k < W; k++)\n        data = (data << 8) ^\n            crc_big_table[(data >> ((W - 1) << 3)) & 0xff];\n    return data;\n}\n\n#endif\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) {\n    /* Return initial CRC, if requested. */\n    if (buf == Z_NULL) return 0;\n\n#ifdef DYNAMIC_CRC_TABLE\n    z_once(&made, make_crc_table);\n#endif /* DYNAMIC_CRC_TABLE */\n\n    /* Pre-condition the CRC */\n    crc = (~crc) & 0xffffffff;\n\n#ifdef W\n\n    /* If provided enough bytes, do a braided CRC calculation. */\n    if (len >= N * W + W - 1) {\n        z_size_t blks;\n        z_word_t const *words;\n        unsigned endian;\n        int k;\n\n        /* Compute the CRC up to a z_word_t boundary. */\n        while (len && ((z_size_t)buf & (W - 1)) != 0) {\n            len--;\n            crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        }\n\n        /* Compute the CRC on as many N z_word_t blocks as are available. */\n        blks = len / (N * W);\n        len -= blks * N * W;\n        words = (z_word_t const *)buf;\n\n        /* Do endian check at execution time instead of compile time, since ARM\n           processors can change the endianness at execution time. If the\n           compiler knows what the endianness will be, it can optimize out the\n           check and the unused branch. */\n        endian = 1;\n        if (*(unsigned char *)&endian) {\n            /* Little endian. */\n\n            z_crc_t crc0;\n            z_word_t word0;\n#if N > 1\n            z_crc_t crc1;\n            z_word_t word1;\n#if N > 2\n            z_crc_t crc2;\n            z_word_t word2;\n#if N > 3\n            z_crc_t crc3;\n            z_word_t word3;\n#if N > 4\n            z_crc_t crc4;\n            z_word_t word4;\n#if N > 5\n            z_crc_t crc5;\n            z_word_t word5;\n#endif\n#endif\n#endif\n#endif\n#endif\n\n            /* Initialize the CRC for each braid. */\n            crc0 = crc;\n#if N > 1\n            crc1 = 0;\n#if N > 2\n            crc2 = 0;\n#if N > 3\n            crc3 = 0;\n#if N > 4\n            crc4 = 0;\n#if N > 5\n            crc5 = 0;\n#endif\n#endif\n#endif\n#endif\n#endif\n\n            /*\n              Process the first blks-1 blocks, computing the CRCs on each braid\n              independently.\n             */\n            while (--blks) {\n                /* Load the word for each braid into registers. */\n                word0 = crc0 ^ words[0];\n#if N > 1\n                word1 = crc1 ^ words[1];\n#if N > 2\n                word2 = crc2 ^ words[2];\n#if N > 3\n                word3 = crc3 ^ words[3];\n#if N > 4\n                word4 = crc4 ^ words[4];\n#if N > 5\n                word5 = crc5 ^ words[5];\n#endif\n#endif\n#endif\n#endif\n#endif\n                words += N;\n\n                /* Compute and update the CRC for each word. The loop should\n                   get unrolled. */\n                crc0 = crc_braid_table[0][word0 & 0xff];\n#if N > 1\n                crc1 = crc_braid_table[0][word1 & 0xff];\n#if N > 2\n                crc2 = crc_braid_table[0][word2 & 0xff];\n#if N > 3\n                crc3 = crc_braid_table[0][word3 & 0xff];\n#if N > 4\n                crc4 = crc_braid_table[0][word4 & 0xff];\n#if N > 5\n                crc5 = crc_braid_table[0][word5 & 0xff];\n#endif\n#endif\n#endif\n#endif\n#endif\n                for (k = 1; k < W; k++) {\n                    crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];\n#if N > 1\n                    crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];\n#if N > 2\n                    crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];\n#if N > 3\n                    crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];\n#if N > 4\n                    crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];\n#if N > 5\n                    crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];\n#endif\n#endif\n#endif\n#endif\n#endif\n                }\n            }\n\n            /*\n              Process the last block, combining the CRCs of the N braids at the\n              same time.\n             */\n            crc = crc_word(crc0 ^ words[0]);\n#if N > 1\n            crc = crc_word(crc1 ^ words[1] ^ crc);\n#if N > 2\n            crc = crc_word(crc2 ^ words[2] ^ crc);\n#if N > 3\n            crc = crc_word(crc3 ^ words[3] ^ crc);\n#if N > 4\n            crc = crc_word(crc4 ^ words[4] ^ crc);\n#if N > 5\n            crc = crc_word(crc5 ^ words[5] ^ crc);\n#endif\n#endif\n#endif\n#endif\n#endif\n            words += N;\n        }\n        else {\n            /* Big endian. */\n\n            z_word_t crc0, word0, comb;\n#if N > 1\n            z_word_t crc1, word1;\n#if N > 2\n            z_word_t crc2, word2;\n#if N > 3\n            z_word_t crc3, word3;\n#if N > 4\n            z_word_t crc4, word4;\n#if N > 5\n            z_word_t crc5, word5;\n#endif\n#endif\n#endif\n#endif\n#endif\n\n            /* Initialize the CRC for each braid. */\n            crc0 = byte_swap(crc);\n#if N > 1\n            crc1 = 0;\n#if N > 2\n            crc2 = 0;\n#if N > 3\n            crc3 = 0;\n#if N > 4\n            crc4 = 0;\n#if N > 5\n            crc5 = 0;\n#endif\n#endif\n#endif\n#endif\n#endif\n\n            /*\n              Process the first blks-1 blocks, computing the CRCs on each braid\n              independently.\n             */\n            while (--blks) {\n                /* Load the word for each braid into registers. */\n                word0 = crc0 ^ words[0];\n#if N > 1\n                word1 = crc1 ^ words[1];\n#if N > 2\n                word2 = crc2 ^ words[2];\n#if N > 3\n                word3 = crc3 ^ words[3];\n#if N > 4\n                word4 = crc4 ^ words[4];\n#if N > 5\n                word5 = crc5 ^ words[5];\n#endif\n#endif\n#endif\n#endif\n#endif\n                words += N;\n\n                /* Compute and update the CRC for each word. The loop should\n                   get unrolled. */\n                crc0 = crc_braid_big_table[0][word0 & 0xff];\n#if N > 1\n                crc1 = crc_braid_big_table[0][word1 & 0xff];\n#if N > 2\n                crc2 = crc_braid_big_table[0][word2 & 0xff];\n#if N > 3\n                crc3 = crc_braid_big_table[0][word3 & 0xff];\n#if N > 4\n                crc4 = crc_braid_big_table[0][word4 & 0xff];\n#if N > 5\n                crc5 = crc_braid_big_table[0][word5 & 0xff];\n#endif\n#endif\n#endif\n#endif\n#endif\n                for (k = 1; k < W; k++) {\n                    crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];\n#if N > 1\n                    crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];\n#if N > 2\n                    crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];\n#if N > 3\n                    crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];\n#if N > 4\n                    crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];\n#if N > 5\n                    crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];\n#endif\n#endif\n#endif\n#endif\n#endif\n                }\n            }\n\n            /*\n              Process the last block, combining the CRCs of the N braids at the\n              same time.\n             */\n            comb = crc_word_big(crc0 ^ words[0]);\n#if N > 1\n            comb = crc_word_big(crc1 ^ words[1] ^ comb);\n#if N > 2\n            comb = crc_word_big(crc2 ^ words[2] ^ comb);\n#if N > 3\n            comb = crc_word_big(crc3 ^ words[3] ^ comb);\n#if N > 4\n            comb = crc_word_big(crc4 ^ words[4] ^ comb);\n#if N > 5\n            comb = crc_word_big(crc5 ^ words[5] ^ comb);\n#endif\n#endif\n#endif\n#endif\n#endif\n            words += N;\n            crc = byte_swap(comb);\n        }\n\n        /*\n          Update the pointer to the remaining bytes to process.\n         */\n        buf = (unsigned char const *)words;\n    }\n\n#endif /* W */\n\n    /* Complete the computation of the CRC on any remaining bytes. */\n    while (len >= 8) {\n        len -= 8;\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n    }\n    while (len) {\n        len--;\n        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];\n    }\n\n    /* Return the CRC, post-conditioned. */\n    return crc ^ 0xffffffff;\n}\n\n#endif\n\n/* ========================================================================= */\nuLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) {\n    #ifdef HAVE_S390X_VX\n    return crc32_z_hook(crc, buf, len);\n    #endif\n    return crc32_z(crc, buf, len);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {\n    if (len2 < 0)\n        return 0;\n#ifdef DYNAMIC_CRC_TABLE\n    z_once(&made, make_crc_table);\n#endif /* DYNAMIC_CRC_TABLE */\n    return x2nmodp(len2, 3);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine_gen(z_off_t len2) {\n    return crc32_combine_gen64((z_off64_t)len2);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {\n    if (op == 0)\n        return 0;\n    return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff);\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {\n    return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2));\n}\n\n/* ========================================================================= */\nuLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {\n    return crc32_combine64(crc1, crc2, (z_off64_t)len2);\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/crc32.h",
    "content": "/* crc32.h -- tables for rapid CRC calculation\n * Generated automatically by crc32.c\n */\n\nlocal const z_crc_t FAR crc_table[] = {\n    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,\n    0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,\n    0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,\n    0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,\n    0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,\n    0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,\n    0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,\n    0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,\n    0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,\n    0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,\n    0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,\n    0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,\n    0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,\n    0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,\n    0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,\n    0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,\n    0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,\n    0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,\n    0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,\n    0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,\n    0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,\n    0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,\n    0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,\n    0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,\n    0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,\n    0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,\n    0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,\n    0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,\n    0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,\n    0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,\n    0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,\n    0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,\n    0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,\n    0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,\n    0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,\n    0x2d02ef8d};\n\n#ifdef W\n\n#if W == 8\n\nlocal const z_word_t FAR crc_big_table[] = {\n    0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,\n    0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,\n    0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,\n    0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,\n    0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,\n    0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,\n    0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,\n    0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,\n    0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,\n    0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,\n    0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,\n    0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,\n    0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,\n    0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,\n    0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,\n    0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,\n    0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,\n    0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,\n    0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,\n    0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,\n    0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,\n    0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,\n    0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,\n    0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,\n    0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,\n    0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,\n    0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,\n    0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,\n    0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,\n    0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,\n    0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,\n    0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,\n    0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,\n    0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,\n    0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,\n    0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,\n    0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,\n    0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,\n    0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,\n    0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,\n    0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,\n    0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,\n    0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,\n    0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,\n    0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,\n    0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,\n    0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,\n    0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,\n    0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,\n    0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,\n    0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,\n    0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,\n    0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,\n    0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,\n    0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,\n    0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,\n    0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,\n    0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,\n    0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,\n    0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,\n    0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,\n    0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,\n    0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,\n    0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,\n    0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,\n    0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,\n    0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,\n    0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,\n    0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,\n    0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,\n    0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,\n    0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,\n    0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,\n    0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,\n    0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,\n    0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,\n    0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,\n    0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,\n    0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,\n    0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,\n    0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,\n    0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,\n    0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,\n    0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,\n    0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,\n    0x8def022d00000000};\n\n#else /* W == 4 */\n\nlocal const z_word_t FAR crc_big_table[] = {\n    0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,\n    0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,\n    0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,\n    0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,\n    0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,\n    0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,\n    0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,\n    0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,\n    0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,\n    0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,\n    0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,\n    0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,\n    0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,\n    0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,\n    0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,\n    0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,\n    0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,\n    0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,\n    0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,\n    0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,\n    0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,\n    0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,\n    0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,\n    0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,\n    0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,\n    0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,\n    0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,\n    0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,\n    0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,\n    0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,\n    0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,\n    0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,\n    0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,\n    0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,\n    0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,\n    0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,\n    0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,\n    0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,\n    0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,\n    0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,\n    0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,\n    0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,\n    0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,\n    0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,\n    0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,\n    0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,\n    0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,\n    0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,\n    0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,\n    0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,\n    0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,\n    0x8def022d};\n\n#endif\n\n#if N == 1\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,\n    0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,\n    0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,\n    0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,\n    0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,\n    0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,\n    0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,\n    0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,\n    0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,\n    0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,\n    0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,\n    0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,\n    0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,\n    0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,\n    0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,\n    0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,\n    0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,\n    0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,\n    0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,\n    0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,\n    0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,\n    0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,\n    0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,\n    0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,\n    0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,\n    0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,\n    0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,\n    0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,\n    0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,\n    0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,\n    0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,\n    0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,\n    0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,\n    0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,\n    0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,\n    0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,\n    0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,\n    0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,\n    0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,\n    0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,\n    0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,\n    0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,\n    0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,\n    0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,\n    0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,\n    0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,\n    0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,\n    0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,\n    0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,\n    0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,\n    0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,\n    0x264b06e6},\n   {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,\n    0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,\n    0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,\n    0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,\n    0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,\n    0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,\n    0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,\n    0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,\n    0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,\n    0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,\n    0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,\n    0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,\n    0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,\n    0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,\n    0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,\n    0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,\n    0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,\n    0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,\n    0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,\n    0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,\n    0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,\n    0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,\n    0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,\n    0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,\n    0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,\n    0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,\n    0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,\n    0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,\n    0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,\n    0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,\n    0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,\n    0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,\n    0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,\n    0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,\n    0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,\n    0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,\n    0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,\n    0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,\n    0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,\n    0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,\n    0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,\n    0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,\n    0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,\n    0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,\n    0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,\n    0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,\n    0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,\n    0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,\n    0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,\n    0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,\n    0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,\n    0x92364a30},\n   {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,\n    0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,\n    0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,\n    0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,\n    0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,\n    0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,\n    0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,\n    0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,\n    0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,\n    0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,\n    0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,\n    0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,\n    0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,\n    0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,\n    0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,\n    0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,\n    0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,\n    0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,\n    0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,\n    0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,\n    0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,\n    0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,\n    0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,\n    0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,\n    0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,\n    0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,\n    0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,\n    0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,\n    0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,\n    0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,\n    0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,\n    0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,\n    0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,\n    0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,\n    0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,\n    0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,\n    0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,\n    0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,\n    0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,\n    0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,\n    0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,\n    0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,\n    0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,\n    0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,\n    0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,\n    0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,\n    0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,\n    0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,\n    0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,\n    0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,\n    0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,\n    0xe4c4abcc},\n   {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,\n    0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,\n    0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,\n    0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,\n    0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,\n    0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,\n    0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,\n    0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,\n    0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,\n    0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,\n    0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,\n    0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,\n    0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,\n    0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,\n    0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,\n    0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,\n    0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,\n    0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,\n    0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,\n    0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,\n    0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,\n    0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,\n    0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,\n    0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,\n    0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,\n    0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,\n    0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,\n    0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,\n    0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,\n    0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,\n    0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,\n    0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,\n    0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,\n    0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,\n    0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,\n    0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,\n    0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,\n    0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,\n    0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,\n    0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,\n    0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,\n    0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,\n    0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,\n    0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,\n    0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,\n    0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,\n    0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,\n    0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,\n    0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,\n    0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,\n    0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,\n    0xca64c78c},\n   {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,\n    0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,\n    0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,\n    0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,\n    0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,\n    0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,\n    0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,\n    0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,\n    0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,\n    0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,\n    0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,\n    0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,\n    0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,\n    0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,\n    0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,\n    0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,\n    0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,\n    0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,\n    0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,\n    0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,\n    0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,\n    0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,\n    0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,\n    0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,\n    0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,\n    0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,\n    0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,\n    0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,\n    0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,\n    0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,\n    0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,\n    0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,\n    0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,\n    0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,\n    0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,\n    0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,\n    0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,\n    0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,\n    0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,\n    0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,\n    0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,\n    0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,\n    0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,\n    0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,\n    0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,\n    0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,\n    0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,\n    0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,\n    0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,\n    0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,\n    0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,\n    0xde0506f1},\n   {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,\n    0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,\n    0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,\n    0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,\n    0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,\n    0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,\n    0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,\n    0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,\n    0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,\n    0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,\n    0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,\n    0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,\n    0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,\n    0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,\n    0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,\n    0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,\n    0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,\n    0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,\n    0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,\n    0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,\n    0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,\n    0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,\n    0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,\n    0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,\n    0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,\n    0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,\n    0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,\n    0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,\n    0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,\n    0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,\n    0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,\n    0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,\n    0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,\n    0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,\n    0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,\n    0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,\n    0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,\n    0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,\n    0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,\n    0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,\n    0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,\n    0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,\n    0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,\n    0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,\n    0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,\n    0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,\n    0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,\n    0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,\n    0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,\n    0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,\n    0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,\n    0xbe9834ed},\n   {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,\n    0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,\n    0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,\n    0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,\n    0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,\n    0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,\n    0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,\n    0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,\n    0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,\n    0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,\n    0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,\n    0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,\n    0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,\n    0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,\n    0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,\n    0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,\n    0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,\n    0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,\n    0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,\n    0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,\n    0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,\n    0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,\n    0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,\n    0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,\n    0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,\n    0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,\n    0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,\n    0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,\n    0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,\n    0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,\n    0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,\n    0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,\n    0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,\n    0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,\n    0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,\n    0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,\n    0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,\n    0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,\n    0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,\n    0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,\n    0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,\n    0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,\n    0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,\n    0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,\n    0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,\n    0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,\n    0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,\n    0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,\n    0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,\n    0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,\n    0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,\n    0x9324fd72},\n   {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,\n    0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,\n    0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,\n    0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,\n    0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,\n    0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,\n    0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,\n    0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,\n    0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,\n    0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,\n    0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,\n    0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,\n    0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,\n    0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,\n    0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,\n    0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,\n    0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,\n    0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,\n    0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,\n    0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,\n    0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,\n    0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,\n    0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,\n    0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,\n    0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,\n    0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,\n    0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,\n    0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,\n    0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,\n    0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,\n    0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,\n    0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,\n    0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,\n    0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,\n    0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,\n    0x2d02ef8d}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,\n    0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,\n    0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,\n    0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,\n    0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,\n    0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,\n    0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,\n    0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,\n    0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,\n    0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,\n    0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,\n    0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,\n    0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,\n    0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,\n    0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,\n    0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,\n    0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,\n    0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,\n    0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,\n    0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,\n    0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,\n    0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,\n    0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,\n    0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,\n    0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,\n    0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,\n    0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,\n    0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,\n    0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,\n    0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,\n    0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,\n    0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,\n    0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,\n    0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,\n    0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,\n    0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,\n    0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,\n    0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,\n    0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,\n    0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,\n    0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,\n    0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,\n    0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,\n    0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,\n    0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,\n    0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,\n    0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,\n    0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,\n    0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,\n    0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,\n    0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,\n    0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,\n    0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,\n    0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,\n    0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,\n    0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,\n    0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,\n    0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,\n    0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,\n    0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,\n    0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,\n    0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,\n    0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,\n    0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,\n    0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,\n    0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,\n    0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,\n    0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,\n    0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,\n    0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,\n    0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,\n    0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,\n    0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,\n    0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,\n    0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,\n    0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,\n    0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,\n    0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,\n    0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,\n    0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,\n    0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,\n    0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,\n    0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,\n    0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,\n    0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,\n    0x8def022d00000000},\n   {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000,\n    0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000,\n    0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000,\n    0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000,\n    0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000,\n    0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000,\n    0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000,\n    0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000,\n    0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000,\n    0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000,\n    0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000,\n    0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000,\n    0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000,\n    0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000,\n    0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000,\n    0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000,\n    0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000,\n    0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000,\n    0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000,\n    0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000,\n    0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000,\n    0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000,\n    0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000,\n    0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000,\n    0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000,\n    0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000,\n    0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000,\n    0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000,\n    0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000,\n    0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000,\n    0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000,\n    0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000,\n    0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000,\n    0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000,\n    0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000,\n    0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000,\n    0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000,\n    0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000,\n    0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000,\n    0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000,\n    0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000,\n    0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000,\n    0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000,\n    0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000,\n    0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000,\n    0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000,\n    0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000,\n    0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000,\n    0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000,\n    0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000,\n    0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000,\n    0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000,\n    0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000,\n    0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000,\n    0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000,\n    0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000,\n    0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000,\n    0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000,\n    0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000,\n    0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000,\n    0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000,\n    0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000,\n    0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000,\n    0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000,\n    0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000,\n    0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000,\n    0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000,\n    0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000,\n    0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000,\n    0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000,\n    0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000,\n    0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000,\n    0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000,\n    0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000,\n    0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000,\n    0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000,\n    0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000,\n    0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000,\n    0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000,\n    0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000,\n    0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000,\n    0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000,\n    0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000,\n    0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000,\n    0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000,\n    0x72fd249300000000},\n   {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000,\n    0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000,\n    0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000,\n    0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000,\n    0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000,\n    0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000,\n    0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000,\n    0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000,\n    0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000,\n    0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000,\n    0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000,\n    0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000,\n    0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000,\n    0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000,\n    0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000,\n    0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000,\n    0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000,\n    0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000,\n    0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000,\n    0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000,\n    0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000,\n    0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000,\n    0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000,\n    0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000,\n    0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000,\n    0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000,\n    0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000,\n    0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000,\n    0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000,\n    0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000,\n    0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000,\n    0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000,\n    0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000,\n    0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000,\n    0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000,\n    0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000,\n    0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000,\n    0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000,\n    0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000,\n    0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000,\n    0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000,\n    0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000,\n    0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000,\n    0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000,\n    0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000,\n    0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000,\n    0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000,\n    0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000,\n    0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000,\n    0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000,\n    0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000,\n    0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000,\n    0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000,\n    0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000,\n    0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000,\n    0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000,\n    0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000,\n    0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000,\n    0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000,\n    0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000,\n    0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000,\n    0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000,\n    0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000,\n    0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000,\n    0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000,\n    0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000,\n    0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000,\n    0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000,\n    0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000,\n    0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000,\n    0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000,\n    0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000,\n    0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000,\n    0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000,\n    0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000,\n    0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000,\n    0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000,\n    0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000,\n    0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000,\n    0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000,\n    0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000,\n    0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000,\n    0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000,\n    0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000,\n    0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000,\n    0xed3498be00000000},\n   {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000,\n    0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000,\n    0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000,\n    0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000,\n    0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000,\n    0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000,\n    0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000,\n    0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000,\n    0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000,\n    0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000,\n    0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000,\n    0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000,\n    0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000,\n    0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000,\n    0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000,\n    0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000,\n    0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000,\n    0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000,\n    0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000,\n    0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000,\n    0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000,\n    0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000,\n    0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000,\n    0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000,\n    0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000,\n    0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000,\n    0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000,\n    0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000,\n    0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000,\n    0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000,\n    0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000,\n    0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000,\n    0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000,\n    0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000,\n    0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000,\n    0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000,\n    0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000,\n    0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000,\n    0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000,\n    0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000,\n    0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000,\n    0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000,\n    0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000,\n    0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000,\n    0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000,\n    0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000,\n    0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000,\n    0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000,\n    0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000,\n    0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000,\n    0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000,\n    0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000,\n    0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000,\n    0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000,\n    0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000,\n    0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000,\n    0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000,\n    0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000,\n    0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000,\n    0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000,\n    0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000,\n    0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000,\n    0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000,\n    0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000,\n    0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000,\n    0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000,\n    0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000,\n    0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000,\n    0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000,\n    0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000,\n    0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000,\n    0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000,\n    0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000,\n    0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000,\n    0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000,\n    0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000,\n    0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000,\n    0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000,\n    0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000,\n    0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000,\n    0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000,\n    0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000,\n    0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000,\n    0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000,\n    0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000,\n    0xf10605de00000000},\n   {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000,\n    0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000,\n    0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000,\n    0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000,\n    0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000,\n    0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000,\n    0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000,\n    0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000,\n    0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000,\n    0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000,\n    0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000,\n    0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000,\n    0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000,\n    0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000,\n    0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000,\n    0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000,\n    0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000,\n    0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000,\n    0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000,\n    0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000,\n    0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000,\n    0x572f712300000000, 0x4958f35800000000, 0xf971936500000000,\n    0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000,\n    0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000,\n    0x8813836800000000, 0x383ae35500000000, 0xe840431200000000,\n    0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000,\n    0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000,\n    0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000,\n    0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000,\n    0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000,\n    0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000,\n    0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000,\n    0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000,\n    0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000,\n    0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000,\n    0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000,\n    0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000,\n    0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000,\n    0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000,\n    0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000,\n    0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000,\n    0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000,\n    0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000,\n    0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000,\n    0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000,\n    0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000,\n    0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000,\n    0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000,\n    0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000,\n    0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000,\n    0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000,\n    0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000,\n    0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000,\n    0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000,\n    0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000,\n    0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000,\n    0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000,\n    0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000,\n    0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000,\n    0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000,\n    0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000,\n    0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000,\n    0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000,\n    0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000,\n    0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000,\n    0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000,\n    0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000,\n    0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000,\n    0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000,\n    0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000,\n    0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000,\n    0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000,\n    0x983485b900000000, 0x281de58400000000, 0xf86745c300000000,\n    0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000,\n    0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000,\n    0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000,\n    0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000,\n    0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000,\n    0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000,\n    0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000,\n    0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000,\n    0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000,\n    0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000,\n    0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000,\n    0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000,\n    0x8cc764ca00000000},\n   {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000,\n    0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000,\n    0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000,\n    0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000,\n    0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000,\n    0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000,\n    0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000,\n    0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000,\n    0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000,\n    0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000,\n    0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000,\n    0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000,\n    0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000,\n    0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000,\n    0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000,\n    0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000,\n    0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000,\n    0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000,\n    0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000,\n    0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000,\n    0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000,\n    0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000,\n    0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000,\n    0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000,\n    0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000,\n    0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000,\n    0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000,\n    0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000,\n    0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000,\n    0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000,\n    0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000,\n    0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000,\n    0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000,\n    0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000,\n    0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000,\n    0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000,\n    0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000,\n    0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000,\n    0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000,\n    0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000,\n    0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000,\n    0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000,\n    0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000,\n    0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000,\n    0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000,\n    0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000,\n    0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000,\n    0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000,\n    0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000,\n    0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000,\n    0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000,\n    0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000,\n    0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000,\n    0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000,\n    0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000,\n    0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000,\n    0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000,\n    0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000,\n    0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000,\n    0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000,\n    0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000,\n    0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000,\n    0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000,\n    0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000,\n    0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000,\n    0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000,\n    0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000,\n    0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000,\n    0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000,\n    0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000,\n    0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000,\n    0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000,\n    0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000,\n    0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000,\n    0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000,\n    0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000,\n    0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000,\n    0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000,\n    0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000,\n    0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000,\n    0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000,\n    0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000,\n    0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000,\n    0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000,\n    0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000,\n    0xccabc4e400000000},\n   {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000,\n    0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000,\n    0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000,\n    0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000,\n    0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000,\n    0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000,\n    0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000,\n    0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000,\n    0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000,\n    0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000,\n    0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000,\n    0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000,\n    0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000,\n    0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000,\n    0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000,\n    0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000,\n    0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000,\n    0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000,\n    0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000,\n    0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000,\n    0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000,\n    0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000,\n    0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000,\n    0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000,\n    0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000,\n    0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000,\n    0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000,\n    0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000,\n    0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000,\n    0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000,\n    0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000,\n    0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000,\n    0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000,\n    0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000,\n    0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000,\n    0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000,\n    0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000,\n    0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000,\n    0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000,\n    0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000,\n    0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000,\n    0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000,\n    0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000,\n    0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000,\n    0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000,\n    0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000,\n    0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000,\n    0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000,\n    0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000,\n    0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000,\n    0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000,\n    0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000,\n    0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000,\n    0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000,\n    0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000,\n    0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000,\n    0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000,\n    0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000,\n    0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000,\n    0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000,\n    0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000,\n    0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000,\n    0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000,\n    0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000,\n    0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000,\n    0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000,\n    0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000,\n    0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000,\n    0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000,\n    0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000,\n    0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000,\n    0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000,\n    0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000,\n    0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000,\n    0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000,\n    0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000,\n    0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000,\n    0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000,\n    0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000,\n    0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000,\n    0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000,\n    0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000,\n    0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000,\n    0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000,\n    0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000,\n    0x304a369200000000},\n   {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000,\n    0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000,\n    0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000,\n    0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000,\n    0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000,\n    0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000,\n    0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000,\n    0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000,\n    0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000,\n    0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000,\n    0x1923316900000000, 0x87239ba500000000, 0x566276f900000000,\n    0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000,\n    0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000,\n    0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000,\n    0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000,\n    0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000,\n    0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000,\n    0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000,\n    0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000,\n    0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000,\n    0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000,\n    0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000,\n    0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000,\n    0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000,\n    0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000,\n    0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000,\n    0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000,\n    0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000,\n    0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000,\n    0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000,\n    0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000,\n    0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000,\n    0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000,\n    0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000,\n    0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000,\n    0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000,\n    0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000,\n    0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000,\n    0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000,\n    0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000,\n    0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000,\n    0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000,\n    0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000,\n    0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000,\n    0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000,\n    0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000,\n    0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000,\n    0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000,\n    0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000,\n    0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000,\n    0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000,\n    0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000,\n    0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000,\n    0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000,\n    0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000,\n    0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000,\n    0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000,\n    0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000,\n    0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000,\n    0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000,\n    0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000,\n    0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000,\n    0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000,\n    0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000,\n    0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000,\n    0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000,\n    0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000,\n    0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000,\n    0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000,\n    0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000,\n    0x6171384400000000, 0xff71928800000000, 0xe678578200000000,\n    0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000,\n    0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000,\n    0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000,\n    0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000,\n    0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000,\n    0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000,\n    0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000,\n    0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000,\n    0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000,\n    0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000,\n    0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000,\n    0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000,\n    0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000,\n    0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000,\n    0xe6064b2600000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,\n    0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,\n    0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,\n    0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,\n    0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,\n    0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,\n    0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,\n    0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,\n    0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,\n    0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,\n    0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,\n    0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,\n    0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,\n    0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,\n    0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,\n    0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,\n    0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,\n    0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,\n    0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,\n    0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,\n    0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,\n    0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,\n    0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,\n    0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,\n    0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,\n    0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,\n    0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,\n    0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,\n    0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,\n    0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,\n    0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,\n    0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,\n    0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,\n    0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,\n    0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,\n    0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,\n    0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,\n    0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,\n    0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,\n    0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,\n    0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,\n    0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,\n    0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,\n    0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,\n    0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,\n    0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,\n    0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,\n    0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,\n    0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,\n    0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,\n    0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,\n    0xde0506f1},\n   {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,\n    0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,\n    0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,\n    0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,\n    0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,\n    0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,\n    0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,\n    0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,\n    0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,\n    0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,\n    0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,\n    0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,\n    0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,\n    0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,\n    0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,\n    0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,\n    0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,\n    0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,\n    0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,\n    0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,\n    0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,\n    0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,\n    0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,\n    0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,\n    0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,\n    0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,\n    0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,\n    0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,\n    0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,\n    0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,\n    0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,\n    0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,\n    0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,\n    0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,\n    0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,\n    0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,\n    0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,\n    0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,\n    0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,\n    0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,\n    0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,\n    0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,\n    0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,\n    0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,\n    0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,\n    0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,\n    0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,\n    0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,\n    0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,\n    0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,\n    0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,\n    0xbe9834ed},\n   {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,\n    0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,\n    0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,\n    0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,\n    0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,\n    0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,\n    0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,\n    0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,\n    0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,\n    0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,\n    0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,\n    0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,\n    0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,\n    0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,\n    0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,\n    0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,\n    0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,\n    0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,\n    0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,\n    0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,\n    0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,\n    0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,\n    0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,\n    0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,\n    0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,\n    0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,\n    0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,\n    0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,\n    0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,\n    0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,\n    0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,\n    0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,\n    0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,\n    0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,\n    0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,\n    0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,\n    0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,\n    0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,\n    0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,\n    0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,\n    0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,\n    0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,\n    0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,\n    0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,\n    0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,\n    0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,\n    0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,\n    0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,\n    0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,\n    0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,\n    0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,\n    0x9324fd72},\n   {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,\n    0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,\n    0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,\n    0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,\n    0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,\n    0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,\n    0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,\n    0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,\n    0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,\n    0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,\n    0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,\n    0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,\n    0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,\n    0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,\n    0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,\n    0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,\n    0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,\n    0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,\n    0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,\n    0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,\n    0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,\n    0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,\n    0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,\n    0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,\n    0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,\n    0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,\n    0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,\n    0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,\n    0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,\n    0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,\n    0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,\n    0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,\n    0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,\n    0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,\n    0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,\n    0x2d02ef8d}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,\n    0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,\n    0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,\n    0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,\n    0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,\n    0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,\n    0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,\n    0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,\n    0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,\n    0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,\n    0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,\n    0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,\n    0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,\n    0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,\n    0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,\n    0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,\n    0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,\n    0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,\n    0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,\n    0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,\n    0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,\n    0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,\n    0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,\n    0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,\n    0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,\n    0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,\n    0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,\n    0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,\n    0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,\n    0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,\n    0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,\n    0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,\n    0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,\n    0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,\n    0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,\n    0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,\n    0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,\n    0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,\n    0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,\n    0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,\n    0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,\n    0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,\n    0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,\n    0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,\n    0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,\n    0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,\n    0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,\n    0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,\n    0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,\n    0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,\n    0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,\n    0x8def022d},\n   {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64,\n    0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1,\n    0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e,\n    0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61,\n    0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82,\n    0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff,\n    0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7,\n    0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da,\n    0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139,\n    0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6,\n    0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89,\n    0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c,\n    0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0,\n    0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d,\n    0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a,\n    0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177,\n    0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de,\n    0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b,\n    0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824,\n    0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e,\n    0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad,\n    0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0,\n    0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d,\n    0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60,\n    0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83,\n    0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822,\n    0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d,\n    0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8,\n    0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171,\n    0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c,\n    0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b,\n    0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6,\n    0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca,\n    0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f,\n    0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430,\n    0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf,\n    0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c,\n    0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51,\n    0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9,\n    0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84,\n    0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67,\n    0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398,\n    0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7,\n    0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62,\n    0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e,\n    0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923,\n    0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4,\n    0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9,\n    0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070,\n    0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5,\n    0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a,\n    0x72fd2493},\n   {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907,\n    0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f,\n    0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a,\n    0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e,\n    0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512,\n    0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14,\n    0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b,\n    0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d,\n    0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731,\n    0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925,\n    0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620,\n    0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28,\n    0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70,\n    0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176,\n    0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d,\n    0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b,\n    0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b,\n    0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63,\n    0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266,\n    0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a,\n    0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446,\n    0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40,\n    0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557,\n    0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51,\n    0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d,\n    0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0,\n    0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5,\n    0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed,\n    0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd,\n    0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb,\n    0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0,\n    0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6,\n    0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de,\n    0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6,\n    0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3,\n    0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7,\n    0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb,\n    0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd,\n    0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92,\n    0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094,\n    0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598,\n    0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c,\n    0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489,\n    0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81,\n    0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9,\n    0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af,\n    0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4,\n    0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2,\n    0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2,\n    0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba,\n    0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf,\n    0xed3498be},\n   {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f,\n    0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d,\n    0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0,\n    0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42,\n    0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95,\n    0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2,\n    0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a,\n    0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d,\n    0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea,\n    0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748,\n    0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5,\n    0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27,\n    0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b,\n    0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac,\n    0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4,\n    0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3,\n    0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44,\n    0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6,\n    0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b,\n    0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329,\n    0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe,\n    0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9,\n    0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1,\n    0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6,\n    0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921,\n    0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555,\n    0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8,\n    0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a,\n    0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd,\n    0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a,\n    0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2,\n    0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5,\n    0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2,\n    0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330,\n    0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad,\n    0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f,\n    0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8,\n    0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef,\n    0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc,\n    0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb,\n    0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c,\n    0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e,\n    0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03,\n    0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1,\n    0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6,\n    0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1,\n    0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9,\n    0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e,\n    0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409,\n    0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb,\n    0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966,\n    0xf10605de}};\n\n#endif\n\n#endif\n\n#if N == 2\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,\n    0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,\n    0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,\n    0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,\n    0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,\n    0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,\n    0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,\n    0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,\n    0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,\n    0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,\n    0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,\n    0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,\n    0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,\n    0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,\n    0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,\n    0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,\n    0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,\n    0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,\n    0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,\n    0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,\n    0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,\n    0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,\n    0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,\n    0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,\n    0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,\n    0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,\n    0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,\n    0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,\n    0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,\n    0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,\n    0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,\n    0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,\n    0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,\n    0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,\n    0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,\n    0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,\n    0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,\n    0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,\n    0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,\n    0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,\n    0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,\n    0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,\n    0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,\n    0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,\n    0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,\n    0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,\n    0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,\n    0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,\n    0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,\n    0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,\n    0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,\n    0x0d7139d7},\n   {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,\n    0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,\n    0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,\n    0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,\n    0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,\n    0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,\n    0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,\n    0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,\n    0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,\n    0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,\n    0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,\n    0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,\n    0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,\n    0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,\n    0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,\n    0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,\n    0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,\n    0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,\n    0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,\n    0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,\n    0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,\n    0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,\n    0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,\n    0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,\n    0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,\n    0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,\n    0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,\n    0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,\n    0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,\n    0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,\n    0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,\n    0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,\n    0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,\n    0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,\n    0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,\n    0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,\n    0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,\n    0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,\n    0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,\n    0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,\n    0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,\n    0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,\n    0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,\n    0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,\n    0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,\n    0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,\n    0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,\n    0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,\n    0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,\n    0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,\n    0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,\n    0x1c53e98a},\n   {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,\n    0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,\n    0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,\n    0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,\n    0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,\n    0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,\n    0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,\n    0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,\n    0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,\n    0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,\n    0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,\n    0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,\n    0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,\n    0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,\n    0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,\n    0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,\n    0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,\n    0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,\n    0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,\n    0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,\n    0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,\n    0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,\n    0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,\n    0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,\n    0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,\n    0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,\n    0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,\n    0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,\n    0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,\n    0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,\n    0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,\n    0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,\n    0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,\n    0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,\n    0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,\n    0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,\n    0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,\n    0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,\n    0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,\n    0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,\n    0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,\n    0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,\n    0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,\n    0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,\n    0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,\n    0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,\n    0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,\n    0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,\n    0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,\n    0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,\n    0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,\n    0x3f88e851},\n   {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,\n    0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,\n    0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,\n    0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,\n    0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,\n    0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,\n    0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,\n    0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,\n    0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,\n    0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,\n    0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,\n    0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,\n    0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,\n    0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,\n    0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,\n    0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,\n    0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,\n    0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,\n    0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,\n    0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,\n    0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,\n    0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,\n    0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,\n    0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,\n    0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,\n    0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,\n    0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,\n    0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,\n    0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,\n    0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,\n    0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,\n    0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,\n    0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,\n    0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,\n    0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,\n    0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,\n    0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,\n    0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,\n    0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,\n    0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,\n    0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,\n    0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,\n    0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,\n    0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,\n    0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,\n    0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,\n    0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,\n    0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,\n    0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,\n    0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,\n    0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,\n    0x3dee8ca6},\n   {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,\n    0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,\n    0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,\n    0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,\n    0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,\n    0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,\n    0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,\n    0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,\n    0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,\n    0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,\n    0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,\n    0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,\n    0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,\n    0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,\n    0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,\n    0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,\n    0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,\n    0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,\n    0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,\n    0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,\n    0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,\n    0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,\n    0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,\n    0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,\n    0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,\n    0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,\n    0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,\n    0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,\n    0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,\n    0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,\n    0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,\n    0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,\n    0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,\n    0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,\n    0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,\n    0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,\n    0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,\n    0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,\n    0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,\n    0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,\n    0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,\n    0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,\n    0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,\n    0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,\n    0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,\n    0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,\n    0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,\n    0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,\n    0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,\n    0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,\n    0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,\n    0x36197165},\n   {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,\n    0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,\n    0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,\n    0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,\n    0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,\n    0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,\n    0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,\n    0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,\n    0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,\n    0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,\n    0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,\n    0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,\n    0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,\n    0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,\n    0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,\n    0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,\n    0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,\n    0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,\n    0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,\n    0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,\n    0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,\n    0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,\n    0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,\n    0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,\n    0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,\n    0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,\n    0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,\n    0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,\n    0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,\n    0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,\n    0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,\n    0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,\n    0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,\n    0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,\n    0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,\n    0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,\n    0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,\n    0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,\n    0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,\n    0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,\n    0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,\n    0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,\n    0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,\n    0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,\n    0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,\n    0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,\n    0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,\n    0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,\n    0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,\n    0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,\n    0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,\n    0x1a3b93aa},\n   {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,\n    0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,\n    0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,\n    0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,\n    0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,\n    0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,\n    0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,\n    0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,\n    0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,\n    0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,\n    0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,\n    0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,\n    0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,\n    0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,\n    0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,\n    0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,\n    0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,\n    0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,\n    0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,\n    0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,\n    0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,\n    0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,\n    0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,\n    0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,\n    0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,\n    0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,\n    0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,\n    0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,\n    0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,\n    0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,\n    0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,\n    0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,\n    0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,\n    0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,\n    0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,\n    0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,\n    0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,\n    0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,\n    0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,\n    0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,\n    0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,\n    0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,\n    0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,\n    0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,\n    0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,\n    0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,\n    0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,\n    0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,\n    0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,\n    0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,\n    0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,\n    0xe147d714},\n   {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,\n    0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,\n    0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,\n    0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,\n    0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,\n    0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,\n    0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,\n    0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,\n    0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,\n    0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,\n    0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,\n    0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,\n    0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,\n    0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,\n    0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,\n    0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,\n    0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,\n    0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,\n    0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,\n    0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,\n    0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,\n    0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,\n    0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,\n    0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,\n    0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,\n    0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,\n    0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,\n    0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,\n    0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,\n    0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,\n    0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,\n    0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,\n    0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,\n    0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,\n    0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,\n    0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,\n    0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,\n    0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,\n    0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,\n    0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,\n    0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,\n    0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,\n    0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,\n    0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,\n    0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,\n    0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,\n    0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,\n    0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,\n    0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,\n    0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,\n    0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,\n    0x494f0c4b}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000,\n    0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000,\n    0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000,\n    0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000,\n    0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000,\n    0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000,\n    0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000,\n    0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000,\n    0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000,\n    0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000,\n    0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000,\n    0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000,\n    0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000,\n    0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000,\n    0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000,\n    0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000,\n    0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000,\n    0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000,\n    0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000,\n    0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000,\n    0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000,\n    0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000,\n    0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000,\n    0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000,\n    0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000,\n    0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000,\n    0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000,\n    0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000,\n    0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000,\n    0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000,\n    0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000,\n    0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000,\n    0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000,\n    0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000,\n    0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000,\n    0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000,\n    0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000,\n    0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000,\n    0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000,\n    0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000,\n    0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000,\n    0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000,\n    0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000,\n    0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000,\n    0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000,\n    0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000,\n    0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000,\n    0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000,\n    0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000,\n    0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000,\n    0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000,\n    0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000,\n    0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000,\n    0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000,\n    0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000,\n    0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000,\n    0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000,\n    0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000,\n    0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000,\n    0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000,\n    0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000,\n    0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000,\n    0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000,\n    0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000,\n    0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000,\n    0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000,\n    0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000,\n    0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000,\n    0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000,\n    0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000,\n    0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000,\n    0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000,\n    0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000,\n    0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000,\n    0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000,\n    0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000,\n    0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000,\n    0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000,\n    0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000,\n    0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000,\n    0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000,\n    0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000,\n    0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000,\n    0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000,\n    0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000,\n    0x4b0c4f4900000000},\n   {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000,\n    0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000,\n    0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000,\n    0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000,\n    0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000,\n    0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000,\n    0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000,\n    0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000,\n    0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000,\n    0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000,\n    0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000,\n    0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000,\n    0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000,\n    0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000,\n    0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000,\n    0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000,\n    0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000,\n    0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000,\n    0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000,\n    0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000,\n    0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000,\n    0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000,\n    0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000,\n    0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000,\n    0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000,\n    0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000,\n    0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000,\n    0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000,\n    0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000,\n    0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000,\n    0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000,\n    0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000,\n    0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000,\n    0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000,\n    0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000,\n    0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000,\n    0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000,\n    0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000,\n    0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000,\n    0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000,\n    0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000,\n    0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000,\n    0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000,\n    0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000,\n    0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000,\n    0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000,\n    0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000,\n    0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000,\n    0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000,\n    0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000,\n    0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000,\n    0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000,\n    0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000,\n    0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000,\n    0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000,\n    0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000,\n    0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000,\n    0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000,\n    0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000,\n    0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000,\n    0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000,\n    0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000,\n    0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000,\n    0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000,\n    0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000,\n    0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000,\n    0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000,\n    0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000,\n    0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000,\n    0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000,\n    0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000,\n    0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000,\n    0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000,\n    0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000,\n    0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000,\n    0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000,\n    0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000,\n    0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000,\n    0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000,\n    0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000,\n    0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000,\n    0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000,\n    0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000,\n    0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000,\n    0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000,\n    0x14d747e100000000},\n   {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000,\n    0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000,\n    0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000,\n    0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000,\n    0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000,\n    0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000,\n    0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000,\n    0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000,\n    0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000,\n    0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000,\n    0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000,\n    0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000,\n    0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000,\n    0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000,\n    0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000,\n    0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000,\n    0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000,\n    0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000,\n    0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000,\n    0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000,\n    0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000,\n    0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000,\n    0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000,\n    0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000,\n    0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000,\n    0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000,\n    0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000,\n    0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000,\n    0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000,\n    0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000,\n    0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000,\n    0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000,\n    0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000,\n    0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000,\n    0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000,\n    0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000,\n    0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000,\n    0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000,\n    0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000,\n    0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000,\n    0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000,\n    0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000,\n    0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000,\n    0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000,\n    0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000,\n    0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000,\n    0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000,\n    0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000,\n    0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000,\n    0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000,\n    0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000,\n    0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000,\n    0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000,\n    0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000,\n    0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000,\n    0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000,\n    0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000,\n    0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000,\n    0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000,\n    0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000,\n    0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000,\n    0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000,\n    0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000,\n    0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000,\n    0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000,\n    0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000,\n    0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000,\n    0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000,\n    0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000,\n    0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000,\n    0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000,\n    0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000,\n    0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000,\n    0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000,\n    0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000,\n    0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000,\n    0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000,\n    0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000,\n    0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000,\n    0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000,\n    0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000,\n    0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000,\n    0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000,\n    0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000,\n    0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000,\n    0xaa933b1a00000000},\n   {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000,\n    0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000,\n    0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000,\n    0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000,\n    0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000,\n    0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000,\n    0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000,\n    0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000,\n    0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000,\n    0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000,\n    0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000,\n    0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000,\n    0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000,\n    0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000,\n    0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000,\n    0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000,\n    0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000,\n    0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000,\n    0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000,\n    0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000,\n    0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000,\n    0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000,\n    0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000,\n    0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000,\n    0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000,\n    0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000,\n    0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000,\n    0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000,\n    0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000,\n    0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000,\n    0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000,\n    0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000,\n    0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000,\n    0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000,\n    0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000,\n    0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000,\n    0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000,\n    0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000,\n    0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000,\n    0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000,\n    0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000,\n    0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000,\n    0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000,\n    0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000,\n    0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000,\n    0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000,\n    0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000,\n    0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000,\n    0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000,\n    0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000,\n    0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000,\n    0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000,\n    0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000,\n    0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000,\n    0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000,\n    0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000,\n    0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000,\n    0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000,\n    0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000,\n    0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000,\n    0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000,\n    0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000,\n    0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000,\n    0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000,\n    0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000,\n    0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000,\n    0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000,\n    0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000,\n    0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000,\n    0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000,\n    0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000,\n    0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000,\n    0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000,\n    0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000,\n    0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000,\n    0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000,\n    0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000,\n    0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000,\n    0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000,\n    0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000,\n    0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000,\n    0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000,\n    0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000,\n    0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000,\n    0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000,\n    0x6571193600000000},\n   {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000,\n    0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000,\n    0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000,\n    0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000,\n    0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000,\n    0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000,\n    0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000,\n    0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000,\n    0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000,\n    0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000,\n    0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000,\n    0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000,\n    0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000,\n    0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000,\n    0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000,\n    0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000,\n    0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000,\n    0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000,\n    0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000,\n    0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000,\n    0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000,\n    0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000,\n    0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000,\n    0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000,\n    0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000,\n    0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000,\n    0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000,\n    0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000,\n    0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000,\n    0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000,\n    0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000,\n    0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000,\n    0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000,\n    0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000,\n    0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000,\n    0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000,\n    0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000,\n    0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000,\n    0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000,\n    0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000,\n    0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000,\n    0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000,\n    0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000,\n    0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000,\n    0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000,\n    0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000,\n    0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000,\n    0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000,\n    0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000,\n    0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000,\n    0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000,\n    0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000,\n    0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000,\n    0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000,\n    0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000,\n    0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000,\n    0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000,\n    0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000,\n    0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000,\n    0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000,\n    0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000,\n    0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000,\n    0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000,\n    0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000,\n    0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000,\n    0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000,\n    0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000,\n    0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000,\n    0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000,\n    0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000,\n    0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000,\n    0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000,\n    0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000,\n    0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000,\n    0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000,\n    0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000,\n    0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000,\n    0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000,\n    0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000,\n    0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000,\n    0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000,\n    0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000,\n    0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000,\n    0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000,\n    0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000,\n    0xa68cee3d00000000},\n   {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000,\n    0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000,\n    0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000,\n    0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000,\n    0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000,\n    0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000,\n    0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000,\n    0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000,\n    0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000,\n    0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000,\n    0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000,\n    0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000,\n    0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000,\n    0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000,\n    0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000,\n    0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000,\n    0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000,\n    0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000,\n    0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000,\n    0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000,\n    0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000,\n    0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000,\n    0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000,\n    0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000,\n    0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000,\n    0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000,\n    0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000,\n    0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000,\n    0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000,\n    0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000,\n    0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000,\n    0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000,\n    0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000,\n    0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000,\n    0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000,\n    0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000,\n    0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000,\n    0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000,\n    0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000,\n    0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000,\n    0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000,\n    0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000,\n    0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000,\n    0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000,\n    0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000,\n    0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000,\n    0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000,\n    0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000,\n    0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000,\n    0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000,\n    0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000,\n    0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000,\n    0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000,\n    0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000,\n    0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000,\n    0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000,\n    0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000,\n    0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000,\n    0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000,\n    0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000,\n    0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000,\n    0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000,\n    0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000,\n    0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000,\n    0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000,\n    0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000,\n    0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000,\n    0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000,\n    0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000,\n    0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000,\n    0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000,\n    0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000,\n    0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000,\n    0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000,\n    0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000,\n    0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000,\n    0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000,\n    0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000,\n    0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000,\n    0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000,\n    0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000,\n    0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000,\n    0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000,\n    0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000,\n    0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000,\n    0x51e8883f00000000},\n   {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000,\n    0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000,\n    0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000,\n    0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000,\n    0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000,\n    0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000,\n    0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000,\n    0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000,\n    0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000,\n    0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000,\n    0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000,\n    0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000,\n    0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000,\n    0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000,\n    0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000,\n    0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000,\n    0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000,\n    0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000,\n    0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000,\n    0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000,\n    0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000,\n    0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000,\n    0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000,\n    0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000,\n    0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000,\n    0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000,\n    0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000,\n    0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000,\n    0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000,\n    0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000,\n    0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000,\n    0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000,\n    0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000,\n    0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000,\n    0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000,\n    0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000,\n    0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000,\n    0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000,\n    0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000,\n    0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000,\n    0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000,\n    0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000,\n    0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000,\n    0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000,\n    0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000,\n    0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000,\n    0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000,\n    0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000,\n    0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000,\n    0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000,\n    0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000,\n    0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000,\n    0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000,\n    0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000,\n    0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000,\n    0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000,\n    0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000,\n    0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000,\n    0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000,\n    0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000,\n    0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000,\n    0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000,\n    0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000,\n    0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000,\n    0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000,\n    0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000,\n    0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000,\n    0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000,\n    0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000,\n    0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000,\n    0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000,\n    0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000,\n    0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000,\n    0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000,\n    0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000,\n    0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000,\n    0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000,\n    0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000,\n    0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000,\n    0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000,\n    0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000,\n    0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000,\n    0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000,\n    0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000,\n    0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000,\n    0x8ae9531c00000000},\n   {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000,\n    0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000,\n    0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000,\n    0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000,\n    0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000,\n    0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000,\n    0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000,\n    0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000,\n    0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000,\n    0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000,\n    0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000,\n    0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000,\n    0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000,\n    0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000,\n    0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000,\n    0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000,\n    0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000,\n    0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000,\n    0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000,\n    0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000,\n    0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000,\n    0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000,\n    0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000,\n    0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000,\n    0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000,\n    0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000,\n    0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000,\n    0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000,\n    0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000,\n    0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000,\n    0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000,\n    0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000,\n    0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000,\n    0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000,\n    0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000,\n    0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000,\n    0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000,\n    0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000,\n    0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000,\n    0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000,\n    0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000,\n    0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000,\n    0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000,\n    0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000,\n    0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000,\n    0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000,\n    0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000,\n    0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000,\n    0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000,\n    0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000,\n    0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000,\n    0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000,\n    0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000,\n    0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000,\n    0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000,\n    0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000,\n    0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000,\n    0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000,\n    0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000,\n    0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000,\n    0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000,\n    0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000,\n    0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000,\n    0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000,\n    0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000,\n    0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000,\n    0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000,\n    0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000,\n    0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000,\n    0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000,\n    0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000,\n    0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000,\n    0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000,\n    0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000,\n    0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000,\n    0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000,\n    0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000,\n    0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000,\n    0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000,\n    0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000,\n    0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000,\n    0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000,\n    0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000,\n    0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000,\n    0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000,\n    0xd739710d00000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,\n    0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,\n    0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,\n    0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,\n    0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,\n    0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,\n    0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,\n    0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,\n    0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,\n    0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,\n    0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,\n    0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,\n    0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,\n    0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,\n    0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,\n    0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,\n    0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,\n    0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,\n    0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,\n    0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,\n    0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,\n    0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,\n    0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,\n    0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,\n    0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,\n    0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,\n    0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,\n    0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,\n    0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,\n    0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,\n    0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,\n    0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,\n    0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,\n    0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,\n    0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,\n    0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,\n    0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,\n    0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,\n    0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,\n    0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,\n    0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,\n    0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,\n    0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,\n    0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,\n    0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,\n    0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,\n    0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,\n    0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,\n    0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,\n    0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,\n    0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,\n    0x264b06e6},\n   {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,\n    0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,\n    0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,\n    0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,\n    0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,\n    0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,\n    0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,\n    0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,\n    0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,\n    0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,\n    0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,\n    0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,\n    0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,\n    0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,\n    0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,\n    0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,\n    0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,\n    0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,\n    0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,\n    0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,\n    0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,\n    0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,\n    0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,\n    0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,\n    0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,\n    0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,\n    0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,\n    0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,\n    0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,\n    0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,\n    0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,\n    0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,\n    0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,\n    0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,\n    0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,\n    0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,\n    0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,\n    0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,\n    0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,\n    0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,\n    0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,\n    0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,\n    0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,\n    0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,\n    0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,\n    0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,\n    0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,\n    0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,\n    0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,\n    0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,\n    0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,\n    0x92364a30},\n   {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,\n    0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,\n    0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,\n    0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,\n    0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,\n    0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,\n    0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,\n    0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,\n    0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,\n    0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,\n    0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,\n    0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,\n    0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,\n    0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,\n    0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,\n    0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,\n    0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,\n    0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,\n    0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,\n    0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,\n    0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,\n    0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,\n    0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,\n    0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,\n    0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,\n    0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,\n    0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,\n    0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,\n    0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,\n    0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,\n    0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,\n    0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,\n    0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,\n    0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,\n    0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,\n    0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,\n    0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,\n    0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,\n    0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,\n    0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,\n    0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,\n    0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,\n    0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,\n    0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,\n    0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,\n    0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,\n    0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,\n    0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,\n    0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,\n    0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,\n    0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,\n    0xe4c4abcc},\n   {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,\n    0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,\n    0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,\n    0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,\n    0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,\n    0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,\n    0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,\n    0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,\n    0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,\n    0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,\n    0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,\n    0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,\n    0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,\n    0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,\n    0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,\n    0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,\n    0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,\n    0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,\n    0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,\n    0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,\n    0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,\n    0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,\n    0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,\n    0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,\n    0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,\n    0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,\n    0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,\n    0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,\n    0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,\n    0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,\n    0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,\n    0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,\n    0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,\n    0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,\n    0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,\n    0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,\n    0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,\n    0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,\n    0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,\n    0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,\n    0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,\n    0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,\n    0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,\n    0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,\n    0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,\n    0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,\n    0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,\n    0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,\n    0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,\n    0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,\n    0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,\n    0xca64c78c}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5,\n    0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d,\n    0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf,\n    0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027,\n    0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050,\n    0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098,\n    0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb,\n    0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173,\n    0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104,\n    0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c,\n    0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e,\n    0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6,\n    0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358,\n    0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390,\n    0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312,\n    0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da,\n    0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd,\n    0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335,\n    0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387,\n    0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de,\n    0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9,\n    0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261,\n    0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283,\n    0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b,\n    0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c,\n    0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c,\n    0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e,\n    0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6,\n    0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1,\n    0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619,\n    0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b,\n    0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653,\n    0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785,\n    0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d,\n    0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf,\n    0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757,\n    0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720,\n    0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8,\n    0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593,\n    0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b,\n    0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c,\n    0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4,\n    0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506,\n    0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe,\n    0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428,\n    0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0,\n    0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462,\n    0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa,\n    0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd,\n    0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445,\n    0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7,\n    0x8cc764ca},\n   {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b,\n    0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27,\n    0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a,\n    0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285,\n    0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef,\n    0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf,\n    0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a,\n    0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a,\n    0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70,\n    0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf,\n    0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2,\n    0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e,\n    0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f,\n    0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f,\n    0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae,\n    0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe,\n    0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97,\n    0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b,\n    0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436,\n    0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e,\n    0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4,\n    0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4,\n    0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46,\n    0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716,\n    0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c,\n    0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5,\n    0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8,\n    0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774,\n    0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d,\n    0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d,\n    0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc,\n    0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec,\n    0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82,\n    0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e,\n    0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623,\n    0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c,\n    0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6,\n    0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6,\n    0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c,\n    0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c,\n    0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66,\n    0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9,\n    0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4,\n    0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978,\n    0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416,\n    0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946,\n    0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7,\n    0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7,\n    0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e,\n    0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32,\n    0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f,\n    0xccabc4e4},\n   {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4,\n    0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895,\n    0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50,\n    0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656,\n    0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154,\n    0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906,\n    0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258,\n    0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a,\n    0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08,\n    0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e,\n    0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb,\n    0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa,\n    0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44,\n    0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316,\n    0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0,\n    0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2,\n    0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7,\n    0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6,\n    0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73,\n    0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba,\n    0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8,\n    0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea,\n    0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b,\n    0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29,\n    0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b,\n    0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e,\n    0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb,\n    0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a,\n    0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef,\n    0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd,\n    0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b,\n    0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019,\n    0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3,\n    0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2,\n    0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417,\n    0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11,\n    0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13,\n    0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241,\n    0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b,\n    0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09,\n    0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b,\n    0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d,\n    0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8,\n    0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9,\n    0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003,\n    0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851,\n    0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7,\n    0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5,\n    0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190,\n    0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1,\n    0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134,\n    0x304a3692},\n   {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84,\n    0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f,\n    0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15,\n    0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2,\n    0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf,\n    0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7,\n    0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb,\n    0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3,\n    0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae,\n    0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749,\n    0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243,\n    0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8,\n    0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29,\n    0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61,\n    0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8,\n    0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0,\n    0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1,\n    0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a,\n    0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40,\n    0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e,\n    0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03,\n    0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b,\n    0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee,\n    0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6,\n    0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb,\n    0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f,\n    0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495,\n    0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e,\n    0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f,\n    0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067,\n    0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be,\n    0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6,\n    0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e,\n    0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5,\n    0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf,\n    0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958,\n    0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305,\n    0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d,\n    0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338,\n    0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370,\n    0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d,\n    0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca,\n    0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0,\n    0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b,\n    0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083,\n    0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb,\n    0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012,\n    0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a,\n    0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b,\n    0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0,\n    0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea,\n    0xe6064b26}};\n\n#endif\n\n#endif\n\n#if N == 3\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,\n    0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,\n    0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,\n    0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,\n    0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,\n    0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,\n    0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,\n    0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,\n    0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,\n    0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,\n    0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,\n    0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,\n    0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,\n    0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,\n    0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,\n    0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,\n    0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,\n    0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,\n    0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,\n    0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,\n    0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,\n    0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,\n    0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,\n    0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,\n    0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,\n    0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,\n    0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,\n    0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,\n    0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,\n    0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,\n    0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,\n    0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,\n    0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,\n    0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,\n    0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,\n    0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,\n    0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,\n    0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,\n    0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,\n    0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,\n    0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,\n    0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,\n    0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,\n    0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,\n    0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,\n    0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,\n    0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,\n    0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,\n    0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,\n    0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,\n    0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,\n    0x09cd8551},\n   {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,\n    0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,\n    0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,\n    0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,\n    0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,\n    0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,\n    0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,\n    0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,\n    0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,\n    0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,\n    0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,\n    0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,\n    0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,\n    0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,\n    0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,\n    0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,\n    0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,\n    0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,\n    0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,\n    0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,\n    0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,\n    0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,\n    0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,\n    0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,\n    0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,\n    0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,\n    0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,\n    0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,\n    0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,\n    0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,\n    0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,\n    0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,\n    0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,\n    0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,\n    0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,\n    0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,\n    0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,\n    0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,\n    0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,\n    0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,\n    0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,\n    0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,\n    0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,\n    0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,\n    0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,\n    0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,\n    0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,\n    0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,\n    0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,\n    0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,\n    0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,\n    0x7bc97a0c},\n   {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,\n    0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,\n    0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,\n    0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,\n    0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,\n    0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,\n    0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,\n    0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,\n    0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,\n    0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,\n    0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,\n    0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,\n    0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,\n    0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,\n    0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,\n    0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,\n    0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,\n    0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,\n    0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,\n    0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,\n    0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,\n    0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,\n    0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,\n    0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,\n    0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,\n    0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,\n    0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,\n    0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,\n    0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,\n    0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,\n    0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,\n    0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,\n    0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,\n    0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,\n    0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,\n    0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,\n    0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,\n    0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,\n    0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,\n    0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,\n    0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,\n    0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,\n    0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,\n    0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,\n    0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,\n    0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,\n    0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,\n    0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,\n    0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,\n    0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,\n    0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,\n    0x7851a2ca},\n   {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,\n    0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,\n    0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,\n    0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,\n    0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,\n    0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,\n    0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,\n    0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,\n    0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,\n    0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,\n    0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,\n    0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,\n    0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,\n    0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,\n    0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,\n    0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,\n    0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,\n    0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,\n    0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,\n    0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,\n    0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,\n    0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,\n    0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,\n    0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,\n    0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,\n    0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,\n    0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,\n    0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,\n    0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,\n    0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,\n    0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,\n    0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,\n    0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,\n    0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,\n    0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,\n    0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,\n    0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,\n    0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,\n    0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,\n    0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,\n    0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,\n    0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,\n    0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,\n    0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,\n    0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,\n    0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,\n    0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,\n    0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,\n    0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,\n    0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,\n    0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,\n    0x566b6848},\n   {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,\n    0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,\n    0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,\n    0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,\n    0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,\n    0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,\n    0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,\n    0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,\n    0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,\n    0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,\n    0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,\n    0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,\n    0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,\n    0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,\n    0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,\n    0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,\n    0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,\n    0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,\n    0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,\n    0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,\n    0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,\n    0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,\n    0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,\n    0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,\n    0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,\n    0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,\n    0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,\n    0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,\n    0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,\n    0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,\n    0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,\n    0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,\n    0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,\n    0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,\n    0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,\n    0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,\n    0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,\n    0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,\n    0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,\n    0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,\n    0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,\n    0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,\n    0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,\n    0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,\n    0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,\n    0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,\n    0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,\n    0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,\n    0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,\n    0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,\n    0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,\n    0xd8ac6b35},\n   {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,\n    0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,\n    0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,\n    0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,\n    0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,\n    0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,\n    0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,\n    0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,\n    0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,\n    0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,\n    0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,\n    0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,\n    0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,\n    0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,\n    0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,\n    0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,\n    0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,\n    0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,\n    0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,\n    0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,\n    0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,\n    0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,\n    0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,\n    0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,\n    0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,\n    0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,\n    0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,\n    0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,\n    0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,\n    0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,\n    0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,\n    0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,\n    0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,\n    0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,\n    0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,\n    0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,\n    0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,\n    0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,\n    0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,\n    0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,\n    0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,\n    0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,\n    0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,\n    0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,\n    0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,\n    0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,\n    0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,\n    0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,\n    0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,\n    0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,\n    0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,\n    0xa140efa8},\n   {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,\n    0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,\n    0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,\n    0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,\n    0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,\n    0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,\n    0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,\n    0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,\n    0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,\n    0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,\n    0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,\n    0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,\n    0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,\n    0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,\n    0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,\n    0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,\n    0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,\n    0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,\n    0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,\n    0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,\n    0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,\n    0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,\n    0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,\n    0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,\n    0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,\n    0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,\n    0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,\n    0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,\n    0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,\n    0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,\n    0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,\n    0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,\n    0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,\n    0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,\n    0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,\n    0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,\n    0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,\n    0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,\n    0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,\n    0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,\n    0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,\n    0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,\n    0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,\n    0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,\n    0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,\n    0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,\n    0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,\n    0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,\n    0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,\n    0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,\n    0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,\n    0x917cd6a1},\n   {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,\n    0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,\n    0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,\n    0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,\n    0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,\n    0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,\n    0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,\n    0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,\n    0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,\n    0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,\n    0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,\n    0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,\n    0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,\n    0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,\n    0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,\n    0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,\n    0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,\n    0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,\n    0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,\n    0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,\n    0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,\n    0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,\n    0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,\n    0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,\n    0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,\n    0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,\n    0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,\n    0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,\n    0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,\n    0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,\n    0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,\n    0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,\n    0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,\n    0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,\n    0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,\n    0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,\n    0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,\n    0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,\n    0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,\n    0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,\n    0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,\n    0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,\n    0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,\n    0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,\n    0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,\n    0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,\n    0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,\n    0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,\n    0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,\n    0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,\n    0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,\n    0x18ba364e}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000,\n    0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000,\n    0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000,\n    0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000,\n    0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000,\n    0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000,\n    0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000,\n    0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000,\n    0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000,\n    0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000,\n    0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000,\n    0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000,\n    0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000,\n    0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000,\n    0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000,\n    0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000,\n    0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000,\n    0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000,\n    0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000,\n    0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000,\n    0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000,\n    0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000,\n    0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000,\n    0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000,\n    0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000,\n    0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000,\n    0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000,\n    0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000,\n    0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000,\n    0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000,\n    0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000,\n    0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000,\n    0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000,\n    0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000,\n    0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000,\n    0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000,\n    0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000,\n    0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000,\n    0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000,\n    0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000,\n    0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000,\n    0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000,\n    0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000,\n    0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000,\n    0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000,\n    0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000,\n    0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000,\n    0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000,\n    0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000,\n    0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000,\n    0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000,\n    0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000,\n    0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000,\n    0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000,\n    0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000,\n    0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000,\n    0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000,\n    0x08eda52100000000, 0x4391370100000000, 0x005a918600000000,\n    0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000,\n    0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000,\n    0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000,\n    0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000,\n    0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000,\n    0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000,\n    0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000,\n    0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000,\n    0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000,\n    0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000,\n    0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000,\n    0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000,\n    0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000,\n    0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000,\n    0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000,\n    0x7b23114500000000, 0x305f836500000000, 0x739425e200000000,\n    0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000,\n    0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000,\n    0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000,\n    0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000,\n    0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000,\n    0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000,\n    0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000,\n    0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000,\n    0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000,\n    0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000,\n    0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000,\n    0x4e36ba1800000000},\n   {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000,\n    0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000,\n    0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000,\n    0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000,\n    0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000,\n    0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000,\n    0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000,\n    0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000,\n    0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000,\n    0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000,\n    0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000,\n    0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000,\n    0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000,\n    0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000,\n    0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000,\n    0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000,\n    0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000,\n    0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000,\n    0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000,\n    0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000,\n    0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000,\n    0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000,\n    0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000,\n    0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000,\n    0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000,\n    0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000,\n    0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000,\n    0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000,\n    0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000,\n    0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000,\n    0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000,\n    0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000,\n    0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000,\n    0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000,\n    0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000,\n    0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000,\n    0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000,\n    0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000,\n    0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000,\n    0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000,\n    0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000,\n    0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000,\n    0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000,\n    0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000,\n    0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000,\n    0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000,\n    0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000,\n    0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000,\n    0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000,\n    0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000,\n    0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000,\n    0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000,\n    0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000,\n    0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000,\n    0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000,\n    0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000,\n    0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000,\n    0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000,\n    0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000,\n    0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000,\n    0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000,\n    0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000,\n    0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000,\n    0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000,\n    0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000,\n    0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000,\n    0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000,\n    0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000,\n    0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000,\n    0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000,\n    0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000,\n    0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000,\n    0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000,\n    0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000,\n    0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000,\n    0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000,\n    0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000,\n    0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000,\n    0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000,\n    0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000,\n    0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000,\n    0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000,\n    0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000,\n    0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000,\n    0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000,\n    0xa1d67c9100000000},\n   {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000,\n    0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000,\n    0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000,\n    0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000,\n    0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000,\n    0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000,\n    0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000,\n    0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000,\n    0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000,\n    0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000,\n    0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000,\n    0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000,\n    0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000,\n    0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000,\n    0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000,\n    0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000,\n    0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000,\n    0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000,\n    0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000,\n    0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000,\n    0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000,\n    0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000,\n    0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000,\n    0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000,\n    0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000,\n    0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000,\n    0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000,\n    0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000,\n    0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000,\n    0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000,\n    0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000,\n    0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000,\n    0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000,\n    0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000,\n    0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000,\n    0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000,\n    0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000,\n    0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000,\n    0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000,\n    0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000,\n    0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000,\n    0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000,\n    0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000,\n    0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000,\n    0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000,\n    0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000,\n    0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000,\n    0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000,\n    0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000,\n    0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000,\n    0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000,\n    0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000,\n    0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000,\n    0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000,\n    0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000,\n    0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000,\n    0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000,\n    0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000,\n    0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000,\n    0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000,\n    0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000,\n    0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000,\n    0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000,\n    0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000,\n    0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000,\n    0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000,\n    0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000,\n    0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000,\n    0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000,\n    0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000,\n    0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000,\n    0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000,\n    0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000,\n    0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000,\n    0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000,\n    0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000,\n    0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000,\n    0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000,\n    0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000,\n    0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000,\n    0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000,\n    0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000,\n    0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000,\n    0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000,\n    0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000,\n    0xa8ef40a100000000},\n   {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000,\n    0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000,\n    0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000,\n    0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000,\n    0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000,\n    0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000,\n    0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000,\n    0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000,\n    0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000,\n    0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000,\n    0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000,\n    0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000,\n    0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000,\n    0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000,\n    0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000,\n    0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000,\n    0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000,\n    0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000,\n    0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000,\n    0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000,\n    0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000,\n    0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000,\n    0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000,\n    0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000,\n    0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000,\n    0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000,\n    0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000,\n    0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000,\n    0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000,\n    0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000,\n    0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000,\n    0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000,\n    0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000,\n    0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000,\n    0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000,\n    0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000,\n    0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000,\n    0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000,\n    0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000,\n    0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000,\n    0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000,\n    0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000,\n    0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000,\n    0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000,\n    0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000,\n    0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000,\n    0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000,\n    0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000,\n    0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000,\n    0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000,\n    0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000,\n    0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000,\n    0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000,\n    0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000,\n    0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000,\n    0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000,\n    0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000,\n    0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000,\n    0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000,\n    0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000,\n    0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000,\n    0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000,\n    0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000,\n    0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000,\n    0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000,\n    0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000,\n    0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000,\n    0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000,\n    0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000,\n    0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000,\n    0x933d017400000000, 0xd506661100000000, 0x46a022f000000000,\n    0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000,\n    0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000,\n    0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000,\n    0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000,\n    0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000,\n    0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000,\n    0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000,\n    0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000,\n    0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000,\n    0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000,\n    0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000,\n    0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000,\n    0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000,\n    0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000,\n    0x356bacd800000000},\n   {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000,\n    0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000,\n    0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000,\n    0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000,\n    0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000,\n    0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000,\n    0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000,\n    0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000,\n    0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000,\n    0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000,\n    0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000,\n    0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000,\n    0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000,\n    0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000,\n    0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000,\n    0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000,\n    0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000,\n    0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000,\n    0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000,\n    0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000,\n    0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000,\n    0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000,\n    0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000,\n    0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000,\n    0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000,\n    0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000,\n    0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000,\n    0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000,\n    0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000,\n    0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000,\n    0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000,\n    0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000,\n    0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000,\n    0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000,\n    0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000,\n    0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000,\n    0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000,\n    0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000,\n    0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000,\n    0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000,\n    0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000,\n    0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000,\n    0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000,\n    0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000,\n    0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000,\n    0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000,\n    0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000,\n    0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000,\n    0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000,\n    0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000,\n    0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000,\n    0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000,\n    0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000,\n    0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000,\n    0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000,\n    0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000,\n    0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000,\n    0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000,\n    0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000,\n    0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000,\n    0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000,\n    0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000,\n    0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000,\n    0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000,\n    0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000,\n    0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000,\n    0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000,\n    0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000,\n    0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000,\n    0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000,\n    0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000,\n    0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000,\n    0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000,\n    0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000,\n    0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000,\n    0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000,\n    0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000,\n    0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000,\n    0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000,\n    0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000,\n    0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000,\n    0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000,\n    0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000,\n    0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000,\n    0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000,\n    0x48686b5600000000},\n   {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000,\n    0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000,\n    0x805af17200000000, 0x403ed96500000000, 0x002643b900000000,\n    0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000,\n    0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000,\n    0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000,\n    0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000,\n    0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000,\n    0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000,\n    0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000,\n    0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000,\n    0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000,\n    0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000,\n    0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000,\n    0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000,\n    0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000,\n    0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000,\n    0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000,\n    0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000,\n    0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000,\n    0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000,\n    0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000,\n    0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000,\n    0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000,\n    0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000,\n    0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000,\n    0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000,\n    0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000,\n    0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000,\n    0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000,\n    0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000,\n    0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000,\n    0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000,\n    0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000,\n    0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000,\n    0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000,\n    0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000,\n    0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000,\n    0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000,\n    0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000,\n    0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000,\n    0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000,\n    0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000,\n    0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000,\n    0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000,\n    0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000,\n    0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000,\n    0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000,\n    0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000,\n    0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000,\n    0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000,\n    0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000,\n    0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000,\n    0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000,\n    0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000,\n    0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000,\n    0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000,\n    0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000,\n    0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000,\n    0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000,\n    0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000,\n    0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000,\n    0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000,\n    0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000,\n    0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000,\n    0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000,\n    0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000,\n    0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000,\n    0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000,\n    0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000,\n    0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000,\n    0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000,\n    0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000,\n    0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000,\n    0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000,\n    0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000,\n    0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000,\n    0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000,\n    0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000,\n    0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000,\n    0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000,\n    0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000,\n    0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000,\n    0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000,\n    0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000,\n    0xcaa2517800000000},\n   {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000,\n    0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000,\n    0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000,\n    0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000,\n    0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000,\n    0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000,\n    0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000,\n    0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000,\n    0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000,\n    0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000,\n    0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000,\n    0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000,\n    0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000,\n    0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000,\n    0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000,\n    0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000,\n    0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000,\n    0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000,\n    0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000,\n    0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000,\n    0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000,\n    0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000,\n    0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000,\n    0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000,\n    0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000,\n    0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000,\n    0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000,\n    0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000,\n    0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000,\n    0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000,\n    0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000,\n    0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000,\n    0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000,\n    0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000,\n    0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000,\n    0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000,\n    0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000,\n    0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000,\n    0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000,\n    0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000,\n    0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000,\n    0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000,\n    0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000,\n    0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000,\n    0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000,\n    0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000,\n    0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000,\n    0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000,\n    0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000,\n    0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000,\n    0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000,\n    0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000,\n    0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000,\n    0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000,\n    0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000,\n    0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000,\n    0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000,\n    0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000,\n    0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000,\n    0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000,\n    0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000,\n    0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000,\n    0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000,\n    0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000,\n    0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000,\n    0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000,\n    0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000,\n    0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000,\n    0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000,\n    0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000,\n    0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000,\n    0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000,\n    0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000,\n    0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000,\n    0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000,\n    0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000,\n    0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000,\n    0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000,\n    0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000,\n    0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000,\n    0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000,\n    0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000,\n    0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000,\n    0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000,\n    0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000,\n    0x0c7ac97b00000000},\n   {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000,\n    0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000,\n    0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000,\n    0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000,\n    0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000,\n    0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000,\n    0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000,\n    0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000,\n    0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000,\n    0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000,\n    0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000,\n    0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000,\n    0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000,\n    0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000,\n    0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000,\n    0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000,\n    0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000,\n    0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000,\n    0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000,\n    0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000,\n    0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000,\n    0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000,\n    0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000,\n    0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000,\n    0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000,\n    0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000,\n    0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000,\n    0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000,\n    0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000,\n    0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000,\n    0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000,\n    0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000,\n    0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000,\n    0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000,\n    0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000,\n    0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000,\n    0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000,\n    0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000,\n    0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000,\n    0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000,\n    0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000,\n    0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000,\n    0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000,\n    0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000,\n    0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000,\n    0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000,\n    0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000,\n    0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000,\n    0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000,\n    0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000,\n    0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000,\n    0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000,\n    0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000,\n    0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000,\n    0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000,\n    0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000,\n    0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000,\n    0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000,\n    0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000,\n    0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000,\n    0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000,\n    0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000,\n    0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000,\n    0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000,\n    0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000,\n    0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000,\n    0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000,\n    0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000,\n    0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000,\n    0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000,\n    0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000,\n    0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000,\n    0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000,\n    0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000,\n    0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000,\n    0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000,\n    0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000,\n    0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000,\n    0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000,\n    0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000,\n    0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000,\n    0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000,\n    0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000,\n    0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000,\n    0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000,\n    0x5185cd0900000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,\n    0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,\n    0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,\n    0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,\n    0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,\n    0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,\n    0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,\n    0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,\n    0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,\n    0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,\n    0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,\n    0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,\n    0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,\n    0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,\n    0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,\n    0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,\n    0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,\n    0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,\n    0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,\n    0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,\n    0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,\n    0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,\n    0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,\n    0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,\n    0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,\n    0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,\n    0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,\n    0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,\n    0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,\n    0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,\n    0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,\n    0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,\n    0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,\n    0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,\n    0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,\n    0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,\n    0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,\n    0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,\n    0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,\n    0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,\n    0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,\n    0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,\n    0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,\n    0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,\n    0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,\n    0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,\n    0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,\n    0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,\n    0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,\n    0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,\n    0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,\n    0x36197165},\n   {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,\n    0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,\n    0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,\n    0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,\n    0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,\n    0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,\n    0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,\n    0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,\n    0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,\n    0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,\n    0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,\n    0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,\n    0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,\n    0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,\n    0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,\n    0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,\n    0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,\n    0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,\n    0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,\n    0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,\n    0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,\n    0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,\n    0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,\n    0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,\n    0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,\n    0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,\n    0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,\n    0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,\n    0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,\n    0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,\n    0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,\n    0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,\n    0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,\n    0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,\n    0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,\n    0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,\n    0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,\n    0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,\n    0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,\n    0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,\n    0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,\n    0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,\n    0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,\n    0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,\n    0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,\n    0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,\n    0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,\n    0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,\n    0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,\n    0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,\n    0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,\n    0x1a3b93aa},\n   {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,\n    0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,\n    0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,\n    0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,\n    0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,\n    0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,\n    0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,\n    0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,\n    0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,\n    0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,\n    0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,\n    0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,\n    0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,\n    0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,\n    0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,\n    0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,\n    0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,\n    0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,\n    0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,\n    0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,\n    0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,\n    0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,\n    0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,\n    0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,\n    0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,\n    0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,\n    0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,\n    0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,\n    0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,\n    0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,\n    0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,\n    0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,\n    0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,\n    0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,\n    0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,\n    0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,\n    0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,\n    0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,\n    0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,\n    0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,\n    0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,\n    0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,\n    0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,\n    0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,\n    0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,\n    0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,\n    0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,\n    0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,\n    0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,\n    0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,\n    0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,\n    0xe147d714},\n   {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,\n    0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,\n    0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,\n    0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,\n    0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,\n    0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,\n    0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,\n    0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,\n    0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,\n    0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,\n    0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,\n    0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,\n    0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,\n    0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,\n    0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,\n    0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,\n    0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,\n    0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,\n    0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,\n    0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,\n    0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,\n    0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,\n    0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,\n    0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,\n    0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,\n    0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,\n    0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,\n    0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,\n    0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,\n    0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,\n    0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,\n    0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,\n    0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,\n    0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,\n    0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,\n    0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,\n    0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,\n    0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,\n    0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,\n    0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,\n    0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,\n    0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,\n    0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,\n    0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,\n    0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,\n    0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,\n    0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,\n    0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,\n    0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,\n    0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,\n    0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,\n    0x494f0c4b}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d,\n    0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac,\n    0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8,\n    0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95,\n    0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817,\n    0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d,\n    0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac,\n    0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6,\n    0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564,\n    0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39,\n    0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d,\n    0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac,\n    0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de,\n    0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594,\n    0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b,\n    0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01,\n    0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f,\n    0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de,\n    0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba,\n    0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65,\n    0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7,\n    0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad,\n    0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de,\n    0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294,\n    0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716,\n    0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71,\n    0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15,\n    0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4,\n    0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca,\n    0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280,\n    0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f,\n    0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15,\n    0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9,\n    0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748,\n    0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c,\n    0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971,\n    0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3,\n    0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9,\n    0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196,\n    0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc,\n    0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e,\n    0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03,\n    0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67,\n    0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296,\n    0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a,\n    0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170,\n    0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af,\n    0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5,\n    0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb,\n    0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a,\n    0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e,\n    0x4b0c4f49},\n   {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09,\n    0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc,\n    0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e,\n    0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc,\n    0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934,\n    0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2,\n    0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b,\n    0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad,\n    0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155,\n    0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187,\n    0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65,\n    0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390,\n    0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e,\n    0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378,\n    0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889,\n    0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f,\n    0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0,\n    0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145,\n    0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7,\n    0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a,\n    0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2,\n    0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924,\n    0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2,\n    0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514,\n    0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec,\n    0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709,\n    0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb,\n    0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e,\n    0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1,\n    0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227,\n    0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6,\n    0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030,\n    0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0,\n    0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55,\n    0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7,\n    0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165,\n    0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d,\n    0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b,\n    0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c,\n    0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a,\n    0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362,\n    0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0,\n    0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52,\n    0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7,\n    0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237,\n    0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1,\n    0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020,\n    0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6,\n    0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719,\n    0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec,\n    0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e,\n    0x14d747e1},\n   {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0,\n    0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b,\n    0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652,\n    0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437,\n    0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514,\n    0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265,\n    0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de,\n    0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af,\n    0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c,\n    0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9,\n    0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0,\n    0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b,\n    0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6,\n    0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7,\n    0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734,\n    0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045,\n    0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8,\n    0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303,\n    0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a,\n    0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9,\n    0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea,\n    0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b,\n    0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6,\n    0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7,\n    0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4,\n    0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6,\n    0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f,\n    0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054,\n    0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9,\n    0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8,\n    0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b,\n    0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a,\n    0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441,\n    0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a,\n    0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3,\n    0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6,\n    0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5,\n    0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94,\n    0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9,\n    0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288,\n    0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab,\n    0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce,\n    0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7,\n    0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c,\n    0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527,\n    0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256,\n    0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5,\n    0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4,\n    0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39,\n    0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2,\n    0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db,\n    0xaa933b1a},\n   {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603,\n    0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d,\n    0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9,\n    0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b,\n    0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a,\n    0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792,\n    0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4,\n    0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c,\n    0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d,\n    0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f,\n    0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb,\n    0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65,\n    0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330,\n    0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8,\n    0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da,\n    0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742,\n    0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f,\n    0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1,\n    0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5,\n    0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f,\n    0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e,\n    0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6,\n    0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8,\n    0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250,\n    0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021,\n    0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb,\n    0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f,\n    0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511,\n    0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c,\n    0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4,\n    0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886,\n    0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e,\n    0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b,\n    0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5,\n    0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791,\n    0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003,\n    0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272,\n    0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea,\n    0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc,\n    0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24,\n    0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55,\n    0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7,\n    0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3,\n    0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d,\n    0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548,\n    0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0,\n    0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2,\n    0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a,\n    0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47,\n    0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9,\n    0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad,\n    0x65711936}};\n\n#endif\n\n#endif\n\n#if N == 4\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a,\n    0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe,\n    0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b,\n    0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656,\n    0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd,\n    0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d,\n    0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7,\n    0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47,\n    0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac,\n    0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691,\n    0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404,\n    0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0,\n    0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4,\n    0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424,\n    0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5,\n    0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65,\n    0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67,\n    0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3,\n    0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626,\n    0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9,\n    0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222,\n    0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2,\n    0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a,\n    0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a,\n    0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1,\n    0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2,\n    0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077,\n    0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3,\n    0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1,\n    0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621,\n    0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0,\n    0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60,\n    0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0,\n    0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64,\n    0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1,\n    0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc,\n    0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027,\n    0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7,\n    0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9,\n    0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79,\n    0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292,\n    0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af,\n    0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a,\n    0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee,\n    0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e,\n    0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe,\n    0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f,\n    0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff,\n    0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd,\n    0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29,\n    0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc,\n    0xe3c45916},\n   {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344,\n    0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59,\n    0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e,\n    0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463,\n    0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98,\n    0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d,\n    0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3,\n    0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656,\n    0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad,\n    0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0,\n    0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397,\n    0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a,\n    0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2,\n    0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357,\n    0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8,\n    0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d,\n    0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696,\n    0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b,\n    0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc,\n    0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0,\n    0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b,\n    0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be,\n    0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811,\n    0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384,\n    0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f,\n    0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955,\n    0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362,\n    0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f,\n    0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94,\n    0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701,\n    0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe,\n    0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b,\n    0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1,\n    0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc,\n    0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b,\n    0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986,\n    0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d,\n    0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8,\n    0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4,\n    0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371,\n    0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a,\n    0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87,\n    0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0,\n    0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad,\n    0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527,\n    0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2,\n    0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d,\n    0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998,\n    0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73,\n    0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e,\n    0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59,\n    0xa7520488},\n   {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20,\n    0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09,\n    0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431,\n    0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a,\n    0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203,\n    0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b,\n    0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14,\n    0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c,\n    0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25,\n    0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e,\n    0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36,\n    0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f,\n    0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649,\n    0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961,\n    0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58,\n    0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170,\n    0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b,\n    0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742,\n    0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a,\n    0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55,\n    0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c,\n    0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64,\n    0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f,\n    0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77,\n    0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e,\n    0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a,\n    0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2,\n    0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b,\n    0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090,\n    0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8,\n    0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881,\n    0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9,\n    0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6,\n    0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f,\n    0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7,\n    0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c,\n    0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695,\n    0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd,\n    0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb,\n    0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3,\n    0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa,\n    0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1,\n    0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9,\n    0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0,\n    0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df,\n    0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7,\n    0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace,\n    0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6,\n    0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd,\n    0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4,\n    0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec,\n    0x3522e9e4},\n   {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1,\n    0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86,\n    0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b,\n    0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669,\n    0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7,\n    0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352,\n    0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03,\n    0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6,\n    0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38,\n    0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a,\n    0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7,\n    0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80,\n    0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7,\n    0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522,\n    0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d,\n    0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8,\n    0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103,\n    0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54,\n    0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9,\n    0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0,\n    0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e,\n    0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb,\n    0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1,\n    0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624,\n    0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea,\n    0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a,\n    0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37,\n    0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360,\n    0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab,\n    0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e,\n    0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741,\n    0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4,\n    0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334,\n    0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63,\n    0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de,\n    0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c,\n    0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942,\n    0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7,\n    0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131,\n    0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4,\n    0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a,\n    0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758,\n    0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5,\n    0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2,\n    0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32,\n    0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7,\n    0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8,\n    0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d,\n    0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6,\n    0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1,\n    0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c,\n    0x97411e28},\n   {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474,\n    0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5,\n    0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6,\n    0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7,\n    0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938,\n    0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051,\n    0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a,\n    0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3,\n    0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c,\n    0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d,\n    0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e,\n    0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf,\n    0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740,\n    0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29,\n    0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592,\n    0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb,\n    0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4,\n    0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365,\n    0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036,\n    0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7,\n    0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08,\n    0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561,\n    0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a,\n    0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663,\n    0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac,\n    0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d,\n    0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce,\n    0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f,\n    0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50,\n    0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639,\n    0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82,\n    0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb,\n    0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954,\n    0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5,\n    0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86,\n    0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7,\n    0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418,\n    0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71,\n    0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa,\n    0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93,\n    0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c,\n    0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d,\n    0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e,\n    0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df,\n    0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60,\n    0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309,\n    0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2,\n    0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db,\n    0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4,\n    0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45,\n    0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16,\n    0x93c7a00b},\n   {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45,\n    0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb,\n    0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d,\n    0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696,\n    0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf,\n    0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb,\n    0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028,\n    0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c,\n    0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65,\n    0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be,\n    0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038,\n    0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6,\n    0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15,\n    0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11,\n    0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d,\n    0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19,\n    0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05,\n    0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b,\n    0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d,\n    0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c,\n    0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35,\n    0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31,\n    0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068,\n    0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c,\n    0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25,\n    0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a,\n    0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac,\n    0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22,\n    0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e,\n    0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a,\n    0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36,\n    0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32,\n    0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84,\n    0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a,\n    0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c,\n    0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057,\n    0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e,\n    0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a,\n    0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc,\n    0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8,\n    0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1,\n    0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a,\n    0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec,\n    0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62,\n    0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4,\n    0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0,\n    0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc,\n    0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8,\n    0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4,\n    0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a,\n    0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc,\n    0xce5f968d},\n   {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de,\n    0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b,\n    0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d,\n    0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680,\n    0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4,\n    0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d,\n    0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde,\n    0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97,\n    0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3,\n    0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e,\n    0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678,\n    0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d,\n    0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723,\n    0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a,\n    0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0,\n    0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9,\n    0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85,\n    0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770,\n    0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56,\n    0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a,\n    0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e,\n    0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67,\n    0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785,\n    0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc,\n    0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788,\n    0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90,\n    0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6,\n    0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843,\n    0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f,\n    0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336,\n    0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac,\n    0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5,\n    0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68,\n    0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d,\n    0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb,\n    0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36,\n    0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72,\n    0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b,\n    0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b,\n    0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402,\n    0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446,\n    0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb,\n    0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed,\n    0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418,\n    0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95,\n    0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc,\n    0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946,\n    0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f,\n    0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233,\n    0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6,\n    0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0,\n    0x3e721277},\n   {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb,\n    0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9,\n    0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11,\n    0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d,\n    0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9,\n    0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c,\n    0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881,\n    0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274,\n    0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790,\n    0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc,\n    0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514,\n    0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56,\n    0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9,\n    0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c,\n    0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13,\n    0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6,\n    0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c,\n    0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e,\n    0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386,\n    0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376,\n    0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692,\n    0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67,\n    0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416,\n    0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3,\n    0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07,\n    0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd,\n    0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15,\n    0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457,\n    0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd,\n    0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28,\n    0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337,\n    0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2,\n    0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594,\n    0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6,\n    0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e,\n    0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52,\n    0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6,\n    0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143,\n    0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17,\n    0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2,\n    0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306,\n    0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a,\n    0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182,\n    0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0,\n    0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496,\n    0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63,\n    0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c,\n    0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89,\n    0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903,\n    0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041,\n    0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9,\n    0x1c65ace7}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000,\n    0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000,\n    0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000,\n    0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000,\n    0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000,\n    0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000,\n    0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000,\n    0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000,\n    0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000,\n    0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000,\n    0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000,\n    0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000,\n    0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000,\n    0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000,\n    0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000,\n    0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000,\n    0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000,\n    0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000,\n    0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000,\n    0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000,\n    0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000,\n    0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000,\n    0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000,\n    0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000,\n    0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000,\n    0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000,\n    0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000,\n    0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000,\n    0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000,\n    0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000,\n    0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000,\n    0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000,\n    0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000,\n    0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000,\n    0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000,\n    0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000,\n    0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000,\n    0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000,\n    0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000,\n    0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000,\n    0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000,\n    0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000,\n    0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000,\n    0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000,\n    0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000,\n    0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000,\n    0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000,\n    0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000,\n    0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000,\n    0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000,\n    0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000,\n    0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000,\n    0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000,\n    0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000,\n    0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000,\n    0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000,\n    0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000,\n    0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000,\n    0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000,\n    0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000,\n    0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000,\n    0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000,\n    0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000,\n    0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000,\n    0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000,\n    0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000,\n    0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000,\n    0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000,\n    0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000,\n    0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000,\n    0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000,\n    0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000,\n    0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000,\n    0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000,\n    0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000,\n    0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000,\n    0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000,\n    0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000,\n    0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000,\n    0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000,\n    0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000,\n    0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000,\n    0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000,\n    0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000,\n    0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000,\n    0xe7ac651c00000000},\n   {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000,\n    0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000,\n    0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000,\n    0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000,\n    0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000,\n    0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000,\n    0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000,\n    0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000,\n    0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000,\n    0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000,\n    0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000,\n    0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000,\n    0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000,\n    0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000,\n    0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000,\n    0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000,\n    0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000,\n    0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000,\n    0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000,\n    0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000,\n    0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000,\n    0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000,\n    0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000,\n    0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000,\n    0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000,\n    0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000,\n    0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000,\n    0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000,\n    0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000,\n    0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000,\n    0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000,\n    0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000,\n    0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000,\n    0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000,\n    0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000,\n    0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000,\n    0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000,\n    0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000,\n    0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000,\n    0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000,\n    0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000,\n    0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000,\n    0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000,\n    0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000,\n    0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000,\n    0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000,\n    0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000,\n    0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000,\n    0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000,\n    0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000,\n    0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000,\n    0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000,\n    0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000,\n    0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000,\n    0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000,\n    0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000,\n    0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000,\n    0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000,\n    0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000,\n    0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000,\n    0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000,\n    0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000,\n    0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000,\n    0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000,\n    0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000,\n    0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000,\n    0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000,\n    0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000,\n    0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000,\n    0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000,\n    0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000,\n    0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000,\n    0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000,\n    0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000,\n    0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000,\n    0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000,\n    0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000,\n    0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000,\n    0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000,\n    0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000,\n    0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000,\n    0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000,\n    0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000,\n    0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000,\n    0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000,\n    0x7712723e00000000},\n   {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000,\n    0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000,\n    0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000,\n    0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000,\n    0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000,\n    0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000,\n    0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000,\n    0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000,\n    0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000,\n    0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000,\n    0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000,\n    0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000,\n    0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000,\n    0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000,\n    0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000,\n    0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000,\n    0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000,\n    0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000,\n    0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000,\n    0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000,\n    0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000,\n    0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000,\n    0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000,\n    0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000,\n    0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000,\n    0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000,\n    0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000,\n    0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000,\n    0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000,\n    0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000,\n    0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000,\n    0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000,\n    0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000,\n    0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000,\n    0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000,\n    0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000,\n    0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000,\n    0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000,\n    0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000,\n    0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000,\n    0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000,\n    0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000,\n    0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000,\n    0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000,\n    0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000,\n    0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000,\n    0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000,\n    0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000,\n    0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000,\n    0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000,\n    0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000,\n    0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000,\n    0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000,\n    0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000,\n    0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000,\n    0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000,\n    0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000,\n    0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000,\n    0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000,\n    0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000,\n    0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000,\n    0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000,\n    0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000,\n    0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000,\n    0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000,\n    0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000,\n    0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000,\n    0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000,\n    0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000,\n    0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000,\n    0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000,\n    0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000,\n    0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000,\n    0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000,\n    0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000,\n    0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000,\n    0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000,\n    0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000,\n    0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000,\n    0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000,\n    0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000,\n    0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000,\n    0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000,\n    0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000,\n    0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000,\n    0x8d965fce00000000},\n   {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000,\n    0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000,\n    0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000,\n    0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000,\n    0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000,\n    0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000,\n    0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000,\n    0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000,\n    0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000,\n    0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000,\n    0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000,\n    0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000,\n    0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000,\n    0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000,\n    0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000,\n    0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000,\n    0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000,\n    0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000,\n    0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000,\n    0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000,\n    0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000,\n    0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000,\n    0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000,\n    0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000,\n    0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000,\n    0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000,\n    0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000,\n    0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000,\n    0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000,\n    0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000,\n    0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000,\n    0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000,\n    0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000,\n    0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000,\n    0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000,\n    0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000,\n    0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000,\n    0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000,\n    0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000,\n    0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000,\n    0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000,\n    0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000,\n    0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000,\n    0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000,\n    0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000,\n    0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000,\n    0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000,\n    0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000,\n    0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000,\n    0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000,\n    0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000,\n    0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000,\n    0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000,\n    0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000,\n    0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000,\n    0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000,\n    0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000,\n    0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000,\n    0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000,\n    0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000,\n    0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000,\n    0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000,\n    0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000,\n    0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000,\n    0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000,\n    0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000,\n    0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000,\n    0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000,\n    0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000,\n    0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000,\n    0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000,\n    0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000,\n    0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000,\n    0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000,\n    0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000,\n    0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000,\n    0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000,\n    0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000,\n    0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000,\n    0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000,\n    0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000,\n    0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000,\n    0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000,\n    0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000,\n    0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000,\n    0x0ba0c79300000000},\n   {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000,\n    0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000,\n    0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000,\n    0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000,\n    0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000,\n    0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000,\n    0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000,\n    0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000,\n    0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000,\n    0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000,\n    0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000,\n    0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000,\n    0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000,\n    0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000,\n    0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000,\n    0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000,\n    0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000,\n    0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000,\n    0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000,\n    0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000,\n    0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000,\n    0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000,\n    0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000,\n    0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000,\n    0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000,\n    0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000,\n    0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000,\n    0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000,\n    0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000,\n    0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000,\n    0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000,\n    0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000,\n    0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000,\n    0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000,\n    0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000,\n    0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000,\n    0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000,\n    0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000,\n    0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000,\n    0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000,\n    0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000,\n    0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000,\n    0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000,\n    0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000,\n    0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000,\n    0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000,\n    0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000,\n    0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000,\n    0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000,\n    0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000,\n    0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000,\n    0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000,\n    0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000,\n    0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000,\n    0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000,\n    0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000,\n    0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000,\n    0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000,\n    0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000,\n    0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000,\n    0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000,\n    0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000,\n    0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000,\n    0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000,\n    0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000,\n    0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000,\n    0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000,\n    0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000,\n    0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000,\n    0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000,\n    0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000,\n    0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000,\n    0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000,\n    0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000,\n    0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000,\n    0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000,\n    0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000,\n    0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000,\n    0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000,\n    0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000,\n    0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000,\n    0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000,\n    0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000,\n    0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000,\n    0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000,\n    0x281e419700000000},\n   {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000,\n    0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000,\n    0x304a428900000000, 0x38a922b500000000, 0x011e763800000000,\n    0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000,\n    0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000,\n    0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000,\n    0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000,\n    0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000,\n    0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000,\n    0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000,\n    0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000,\n    0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000,\n    0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000,\n    0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000,\n    0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000,\n    0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000,\n    0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000,\n    0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000,\n    0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000,\n    0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000,\n    0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000,\n    0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000,\n    0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000,\n    0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000,\n    0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000,\n    0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000,\n    0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000,\n    0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000,\n    0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000,\n    0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000,\n    0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000,\n    0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000,\n    0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000,\n    0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000,\n    0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000,\n    0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000,\n    0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000,\n    0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000,\n    0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000,\n    0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000,\n    0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000,\n    0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000,\n    0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000,\n    0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000,\n    0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000,\n    0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000,\n    0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000,\n    0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000,\n    0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000,\n    0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000,\n    0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000,\n    0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000,\n    0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000,\n    0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000,\n    0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000,\n    0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000,\n    0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000,\n    0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000,\n    0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000,\n    0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000,\n    0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000,\n    0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000,\n    0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000,\n    0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000,\n    0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000,\n    0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000,\n    0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000,\n    0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000,\n    0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000,\n    0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000,\n    0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000,\n    0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000,\n    0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000,\n    0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000,\n    0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000,\n    0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000,\n    0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000,\n    0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000,\n    0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000,\n    0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000,\n    0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000,\n    0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000,\n    0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000,\n    0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000,\n    0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000,\n    0xe4e9223500000000},\n   {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000,\n    0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000,\n    0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000,\n    0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000,\n    0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000,\n    0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000,\n    0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000,\n    0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000,\n    0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000,\n    0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000,\n    0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000,\n    0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000,\n    0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000,\n    0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000,\n    0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000,\n    0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000,\n    0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000,\n    0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000,\n    0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000,\n    0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000,\n    0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000,\n    0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000,\n    0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000,\n    0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000,\n    0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000,\n    0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000,\n    0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000,\n    0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000,\n    0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000,\n    0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000,\n    0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000,\n    0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000,\n    0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000,\n    0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000,\n    0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000,\n    0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000,\n    0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000,\n    0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000,\n    0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000,\n    0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000,\n    0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000,\n    0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000,\n    0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000,\n    0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000,\n    0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000,\n    0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000,\n    0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000,\n    0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000,\n    0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000,\n    0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000,\n    0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000,\n    0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000,\n    0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000,\n    0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000,\n    0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000,\n    0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000,\n    0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000,\n    0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000,\n    0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000,\n    0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000,\n    0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000,\n    0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000,\n    0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000,\n    0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000,\n    0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000,\n    0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000,\n    0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000,\n    0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000,\n    0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000,\n    0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000,\n    0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000,\n    0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000,\n    0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000,\n    0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000,\n    0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000,\n    0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000,\n    0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000,\n    0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000,\n    0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000,\n    0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000,\n    0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000,\n    0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000,\n    0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000,\n    0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000,\n    0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000,\n    0x880452a700000000},\n   {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000,\n    0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000,\n    0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000,\n    0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000,\n    0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000,\n    0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000,\n    0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000,\n    0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000,\n    0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000,\n    0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000,\n    0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000,\n    0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000,\n    0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000,\n    0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000,\n    0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000,\n    0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000,\n    0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000,\n    0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000,\n    0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000,\n    0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000,\n    0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000,\n    0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000,\n    0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000,\n    0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000,\n    0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000,\n    0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000,\n    0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000,\n    0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000,\n    0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000,\n    0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000,\n    0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000,\n    0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000,\n    0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000,\n    0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000,\n    0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000,\n    0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000,\n    0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000,\n    0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000,\n    0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000,\n    0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000,\n    0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000,\n    0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000,\n    0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000,\n    0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000,\n    0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000,\n    0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000,\n    0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000,\n    0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000,\n    0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000,\n    0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000,\n    0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000,\n    0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000,\n    0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000,\n    0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000,\n    0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000,\n    0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000,\n    0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000,\n    0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000,\n    0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000,\n    0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000,\n    0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000,\n    0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000,\n    0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000,\n    0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000,\n    0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000,\n    0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000,\n    0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000,\n    0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000,\n    0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000,\n    0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000,\n    0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000,\n    0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000,\n    0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000,\n    0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000,\n    0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000,\n    0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000,\n    0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000,\n    0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000,\n    0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000,\n    0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000,\n    0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000,\n    0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000,\n    0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000,\n    0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000,\n    0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000,\n    0x1659c4e300000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,\n    0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,\n    0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,\n    0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,\n    0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,\n    0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,\n    0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,\n    0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,\n    0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,\n    0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,\n    0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,\n    0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,\n    0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,\n    0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,\n    0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,\n    0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,\n    0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,\n    0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,\n    0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,\n    0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,\n    0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,\n    0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,\n    0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,\n    0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,\n    0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,\n    0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,\n    0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,\n    0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,\n    0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,\n    0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,\n    0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,\n    0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,\n    0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,\n    0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,\n    0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,\n    0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,\n    0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,\n    0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,\n    0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,\n    0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,\n    0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,\n    0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,\n    0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,\n    0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,\n    0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,\n    0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,\n    0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,\n    0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,\n    0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,\n    0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,\n    0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,\n    0x0d7139d7},\n   {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,\n    0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,\n    0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,\n    0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,\n    0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,\n    0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,\n    0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,\n    0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,\n    0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,\n    0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,\n    0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,\n    0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,\n    0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,\n    0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,\n    0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,\n    0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,\n    0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,\n    0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,\n    0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,\n    0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,\n    0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,\n    0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,\n    0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,\n    0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,\n    0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,\n    0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,\n    0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,\n    0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,\n    0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,\n    0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,\n    0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,\n    0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,\n    0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,\n    0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,\n    0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,\n    0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,\n    0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,\n    0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,\n    0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,\n    0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,\n    0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,\n    0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,\n    0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,\n    0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,\n    0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,\n    0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,\n    0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,\n    0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,\n    0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,\n    0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,\n    0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,\n    0x1c53e98a},\n   {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,\n    0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,\n    0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,\n    0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,\n    0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,\n    0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,\n    0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,\n    0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,\n    0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,\n    0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,\n    0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,\n    0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,\n    0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,\n    0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,\n    0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,\n    0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,\n    0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,\n    0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,\n    0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,\n    0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,\n    0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,\n    0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,\n    0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,\n    0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,\n    0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,\n    0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,\n    0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,\n    0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,\n    0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,\n    0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,\n    0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,\n    0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,\n    0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,\n    0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,\n    0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,\n    0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,\n    0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,\n    0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,\n    0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,\n    0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,\n    0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,\n    0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,\n    0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,\n    0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,\n    0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,\n    0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,\n    0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,\n    0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,\n    0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,\n    0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,\n    0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,\n    0x3f88e851},\n   {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,\n    0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,\n    0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,\n    0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,\n    0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,\n    0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,\n    0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,\n    0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,\n    0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,\n    0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,\n    0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,\n    0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,\n    0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,\n    0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,\n    0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,\n    0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,\n    0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,\n    0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,\n    0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,\n    0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,\n    0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,\n    0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,\n    0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,\n    0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,\n    0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,\n    0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,\n    0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,\n    0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,\n    0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,\n    0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,\n    0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,\n    0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,\n    0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,\n    0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,\n    0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,\n    0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,\n    0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,\n    0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,\n    0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,\n    0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,\n    0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,\n    0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,\n    0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,\n    0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,\n    0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,\n    0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,\n    0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,\n    0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,\n    0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,\n    0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,\n    0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,\n    0x3dee8ca6}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0,\n    0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587,\n    0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa,\n    0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09,\n    0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee,\n    0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3,\n    0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3,\n    0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce,\n    0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429,\n    0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda,\n    0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7,\n    0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0,\n    0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd,\n    0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0,\n    0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287,\n    0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a,\n    0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9,\n    0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e,\n    0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3,\n    0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3,\n    0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054,\n    0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49,\n    0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da,\n    0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7,\n    0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20,\n    0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d,\n    0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00,\n    0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347,\n    0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14,\n    0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209,\n    0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e,\n    0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33,\n    0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3,\n    0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194,\n    0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9,\n    0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a,\n    0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd,\n    0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0,\n    0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d,\n    0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460,\n    0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87,\n    0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674,\n    0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509,\n    0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e,\n    0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae,\n    0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3,\n    0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694,\n    0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989,\n    0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da,\n    0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d,\n    0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0,\n    0xa68cee3d},\n   {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19,\n    0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae,\n    0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb,\n    0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a,\n    0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55,\n    0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1,\n    0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c,\n    0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8,\n    0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7,\n    0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936,\n    0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453,\n    0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4,\n    0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941,\n    0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5,\n    0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93,\n    0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17,\n    0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e,\n    0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89,\n    0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec,\n    0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0,\n    0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf,\n    0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b,\n    0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b,\n    0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f,\n    0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0,\n    0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e,\n    0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b,\n    0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc,\n    0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5,\n    0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261,\n    0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637,\n    0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3,\n    0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57,\n    0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0,\n    0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85,\n    0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454,\n    0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b,\n    0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f,\n    0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423,\n    0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7,\n    0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8,\n    0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739,\n    0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c,\n    0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb,\n    0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f,\n    0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b,\n    0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd,\n    0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59,\n    0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070,\n    0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7,\n    0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2,\n    0x51e8883f},\n   {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a,\n    0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276,\n    0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed,\n    0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55,\n    0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b,\n    0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8,\n    0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320,\n    0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413,\n    0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd,\n    0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75,\n    0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee,\n    0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312,\n    0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca,\n    0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9,\n    0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad,\n    0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e,\n    0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504,\n    0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8,\n    0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63,\n    0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353,\n    0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d,\n    0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be,\n    0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae,\n    0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d,\n    0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943,\n    0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7,\n    0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c,\n    0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390,\n    0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a,\n    0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239,\n    0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d,\n    0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e,\n    0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c,\n    0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0,\n    0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b,\n    0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93,\n    0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d,\n    0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e,\n    0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c,\n    0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f,\n    0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1,\n    0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579,\n    0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2,\n    0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e,\n    0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c,\n    0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f,\n    0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b,\n    0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158,\n    0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2,\n    0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e,\n    0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5,\n    0x8ae9531c},\n   {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4,\n    0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd,\n    0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220,\n    0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf,\n    0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495,\n    0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def,\n    0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90,\n    0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea,\n    0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0,\n    0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f,\n    0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2,\n    0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab,\n    0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e,\n    0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754,\n    0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda,\n    0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0,\n    0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c,\n    0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215,\n    0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8,\n    0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910,\n    0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a,\n    0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30,\n    0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658,\n    0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22,\n    0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478,\n    0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2,\n    0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f,\n    0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606,\n    0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba,\n    0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0,\n    0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e,\n    0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034,\n    0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f,\n    0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996,\n    0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b,\n    0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84,\n    0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de,\n    0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4,\n    0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5,\n    0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f,\n    0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5,\n    0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a,\n    0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7,\n    0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce,\n    0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65,\n    0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f,\n    0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91,\n    0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb,\n    0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57,\n    0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e,\n    0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3,\n    0xd739710d}};\n\n#endif\n\n#endif\n\n#if N == 5\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df,\n    0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8,\n    0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef,\n    0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376,\n    0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201,\n    0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399,\n    0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372,\n    0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea,\n    0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d,\n    0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004,\n    0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353,\n    0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334,\n    0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a,\n    0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2,\n    0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a,\n    0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2,\n    0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b,\n    0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c,\n    0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b,\n    0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f,\n    0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338,\n    0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0,\n    0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6,\n    0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e,\n    0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319,\n    0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3,\n    0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4,\n    0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783,\n    0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a,\n    0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492,\n    0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a,\n    0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2,\n    0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496,\n    0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1,\n    0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6,\n    0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f,\n    0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548,\n    0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0,\n    0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741,\n    0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9,\n    0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae,\n    0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437,\n    0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760,\n    0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707,\n    0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433,\n    0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab,\n    0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703,\n    0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b,\n    0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412,\n    0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475,\n    0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722,\n    0xe9947565},\n   {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5,\n    0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22,\n    0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c,\n    0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed,\n    0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d,\n    0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1,\n    0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e,\n    0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32,\n    0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142,\n    0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93,\n    0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d,\n    0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a,\n    0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58,\n    0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14,\n    0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81,\n    0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd,\n    0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab,\n    0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c,\n    0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72,\n    0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f,\n    0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff,\n    0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3,\n    0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30,\n    0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c,\n    0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c,\n    0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558,\n    0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146,\n    0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581,\n    0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7,\n    0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab,\n    0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e,\n    0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272,\n    0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838,\n    0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff,\n    0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1,\n    0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330,\n    0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840,\n    0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c,\n    0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb,\n    0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7,\n    0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7,\n    0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616,\n    0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208,\n    0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf,\n    0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85,\n    0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9,\n    0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c,\n    0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10,\n    0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76,\n    0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1,\n    0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf,\n    0xf7d05006},\n   {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b,\n    0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774,\n    0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58,\n    0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a,\n    0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb,\n    0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952,\n    0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e,\n    0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7,\n    0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746,\n    0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14,\n    0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338,\n    0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907,\n    0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777,\n    0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de,\n    0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064,\n    0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd,\n    0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951,\n    0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e,\n    0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42,\n    0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b,\n    0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a,\n    0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3,\n    0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904,\n    0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad,\n    0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c,\n    0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d,\n    0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861,\n    0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e,\n    0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2,\n    0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b,\n    0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1,\n    0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78,\n    0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f,\n    0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40,\n    0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c,\n    0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e,\n    0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf,\n    0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166,\n    0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d,\n    0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4,\n    0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805,\n    0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157,\n    0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b,\n    0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644,\n    0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43,\n    0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea,\n    0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850,\n    0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9,\n    0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165,\n    0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a,\n    0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676,\n    0xb2075b94},\n   {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf,\n    0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61,\n    0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be,\n    0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd,\n    0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3,\n    0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063,\n    0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105,\n    0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5,\n    0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb,\n    0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8,\n    0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07,\n    0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9,\n    0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5,\n    0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515,\n    0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4,\n    0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014,\n    0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7,\n    0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269,\n    0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6,\n    0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af,\n    0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1,\n    0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111,\n    0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d,\n    0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad,\n    0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3,\n    0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75,\n    0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa,\n    0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74,\n    0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7,\n    0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477,\n    0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6,\n    0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176,\n    0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af,\n    0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71,\n    0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae,\n    0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd,\n    0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3,\n    0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073,\n    0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0,\n    0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400,\n    0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e,\n    0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d,\n    0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2,\n    0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c,\n    0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5,\n    0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505,\n    0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4,\n    0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004,\n    0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7,\n    0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279,\n    0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6,\n    0xba50bcb9},\n   {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897,\n    0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb,\n    0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2,\n    0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2,\n    0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372,\n    0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70,\n    0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92,\n    0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190,\n    0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40,\n    0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430,\n    0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759,\n    0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75,\n    0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2,\n    0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0,\n    0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7,\n    0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5,\n    0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39,\n    0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215,\n    0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c,\n    0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5,\n    0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625,\n    0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27,\n    0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c,\n    0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e,\n    0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee,\n    0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71,\n    0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18,\n    0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134,\n    0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8,\n    0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba,\n    0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd,\n    0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff,\n    0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a,\n    0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6,\n    0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf,\n    0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf,\n    0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f,\n    0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d,\n    0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d,\n    0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f,\n    0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af,\n    0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df,\n    0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6,\n    0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a,\n    0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef,\n    0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed,\n    0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa,\n    0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8,\n    0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624,\n    0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08,\n    0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861,\n    0x808abcf4},\n   {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2,\n    0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd,\n    0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76,\n    0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52,\n    0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e,\n    0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124,\n    0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147,\n    0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d,\n    0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31,\n    0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15,\n    0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae,\n    0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1,\n    0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d,\n    0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307,\n    0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9,\n    0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3,\n    0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084,\n    0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb,\n    0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850,\n    0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2,\n    0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe,\n    0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94,\n    0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261,\n    0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b,\n    0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917,\n    0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53,\n    0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8,\n    0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787,\n    0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0,\n    0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba,\n    0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404,\n    0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e,\n    0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af,\n    0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0,\n    0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b,\n    0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f,\n    0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543,\n    0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129,\n    0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627,\n    0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d,\n    0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51,\n    0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75,\n    0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce,\n    0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1,\n    0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760,\n    0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a,\n    0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4,\n    0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde,\n    0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089,\n    0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6,\n    0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d,\n    0xefdb3f95},\n   {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8,\n    0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7,\n    0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945,\n    0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9,\n    0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652,\n    0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc,\n    0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a,\n    0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4,\n    0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f,\n    0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3,\n    0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51,\n    0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e,\n    0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c,\n    0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362,\n    0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11,\n    0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff,\n    0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7,\n    0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8,\n    0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a,\n    0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690,\n    0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b,\n    0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5,\n    0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05,\n    0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb,\n    0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740,\n    0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f,\n    0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded,\n    0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2,\n    0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa,\n    0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714,\n    0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67,\n    0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89,\n    0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7,\n    0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8,\n    0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a,\n    0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6,\n    0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d,\n    0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3,\n    0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9,\n    0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57,\n    0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc,\n    0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540,\n    0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2,\n    0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd,\n    0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93,\n    0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d,\n    0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e,\n    0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0,\n    0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8,\n    0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7,\n    0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75,\n    0x0e2fbf43},\n   {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc,\n    0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a,\n    0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3,\n    0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7,\n    0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b,\n    0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154,\n    0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3,\n    0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc,\n    0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330,\n    0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264,\n    0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd,\n    0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b,\n    0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a,\n    0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175,\n    0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275,\n    0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a,\n    0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234,\n    0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2,\n    0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b,\n    0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a,\n    0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6,\n    0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189,\n    0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b,\n    0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204,\n    0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8,\n    0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226,\n    0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff,\n    0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219,\n    0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167,\n    0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258,\n    0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158,\n    0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267,\n    0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c,\n    0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da,\n    0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003,\n    0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157,\n    0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b,\n    0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4,\n    0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179,\n    0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246,\n    0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a,\n    0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de,\n    0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107,\n    0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1,\n    0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba,\n    0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285,\n    0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185,\n    0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba,\n    0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4,\n    0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322,\n    0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb,\n    0xf4377108}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000,\n    0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000,\n    0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000,\n    0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000,\n    0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000,\n    0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000,\n    0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000,\n    0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000,\n    0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000,\n    0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000,\n    0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000,\n    0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000,\n    0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000,\n    0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000,\n    0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000,\n    0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000,\n    0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000,\n    0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000,\n    0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000,\n    0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000,\n    0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000,\n    0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000,\n    0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000,\n    0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000,\n    0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000,\n    0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000,\n    0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000,\n    0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000,\n    0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000,\n    0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000,\n    0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000,\n    0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000,\n    0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000,\n    0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000,\n    0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000,\n    0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000,\n    0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000,\n    0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000,\n    0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000,\n    0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000,\n    0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000,\n    0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000,\n    0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000,\n    0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000,\n    0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000,\n    0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000,\n    0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000,\n    0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000,\n    0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000,\n    0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000,\n    0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000,\n    0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000,\n    0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000,\n    0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000,\n    0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000,\n    0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000,\n    0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000,\n    0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000,\n    0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000,\n    0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000,\n    0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000,\n    0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000,\n    0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000,\n    0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000,\n    0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000,\n    0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000,\n    0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000,\n    0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000,\n    0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000,\n    0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000,\n    0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000,\n    0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000,\n    0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000,\n    0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000,\n    0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000,\n    0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000,\n    0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000,\n    0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000,\n    0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000,\n    0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000,\n    0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000,\n    0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000,\n    0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000,\n    0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000,\n    0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000,\n    0x087137f400000000},\n   {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000,\n    0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000,\n    0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000,\n    0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000,\n    0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000,\n    0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000,\n    0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000,\n    0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000,\n    0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000,\n    0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000,\n    0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000,\n    0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000,\n    0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000,\n    0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000,\n    0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000,\n    0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000,\n    0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000,\n    0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000,\n    0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000,\n    0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000,\n    0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000,\n    0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000,\n    0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000,\n    0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000,\n    0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000,\n    0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000,\n    0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000,\n    0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000,\n    0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000,\n    0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000,\n    0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000,\n    0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000,\n    0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000,\n    0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000,\n    0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000,\n    0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000,\n    0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000,\n    0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000,\n    0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000,\n    0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000,\n    0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000,\n    0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000,\n    0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000,\n    0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000,\n    0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000,\n    0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000,\n    0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000,\n    0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000,\n    0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000,\n    0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000,\n    0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000,\n    0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000,\n    0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000,\n    0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000,\n    0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000,\n    0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000,\n    0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000,\n    0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000,\n    0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000,\n    0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000,\n    0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000,\n    0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000,\n    0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000,\n    0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000,\n    0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000,\n    0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000,\n    0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000,\n    0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000,\n    0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000,\n    0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000,\n    0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000,\n    0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000,\n    0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000,\n    0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000,\n    0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000,\n    0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000,\n    0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000,\n    0x1129fad400000000, 0x621116d400000000, 0x544094f000000000,\n    0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000,\n    0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000,\n    0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000,\n    0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000,\n    0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000,\n    0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000,\n    0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000,\n    0x43bf2f0e00000000},\n   {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000,\n    0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000,\n    0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000,\n    0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000,\n    0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000,\n    0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000,\n    0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000,\n    0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000,\n    0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000,\n    0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000,\n    0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000,\n    0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000,\n    0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000,\n    0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000,\n    0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000,\n    0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000,\n    0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000,\n    0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000,\n    0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000,\n    0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000,\n    0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000,\n    0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000,\n    0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000,\n    0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000,\n    0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000,\n    0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000,\n    0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000,\n    0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000,\n    0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000,\n    0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000,\n    0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000,\n    0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000,\n    0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000,\n    0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000,\n    0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000,\n    0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000,\n    0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000,\n    0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000,\n    0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000,\n    0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000,\n    0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000,\n    0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000,\n    0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000,\n    0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000,\n    0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000,\n    0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000,\n    0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000,\n    0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000,\n    0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000,\n    0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000,\n    0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000,\n    0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000,\n    0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000,\n    0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000,\n    0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000,\n    0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000,\n    0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000,\n    0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000,\n    0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000,\n    0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000,\n    0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000,\n    0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000,\n    0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000,\n    0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000,\n    0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000,\n    0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000,\n    0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000,\n    0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000,\n    0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000,\n    0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000,\n    0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000,\n    0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000,\n    0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000,\n    0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000,\n    0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000,\n    0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000,\n    0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000,\n    0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000,\n    0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000,\n    0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000,\n    0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000,\n    0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000,\n    0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000,\n    0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000,\n    0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000,\n    0x953fdbef00000000},\n   {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000,\n    0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000,\n    0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000,\n    0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000,\n    0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000,\n    0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000,\n    0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000,\n    0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000,\n    0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000,\n    0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000,\n    0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000,\n    0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000,\n    0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000,\n    0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000,\n    0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000,\n    0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000,\n    0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000,\n    0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000,\n    0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000,\n    0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000,\n    0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000,\n    0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000,\n    0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000,\n    0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000,\n    0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000,\n    0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000,\n    0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000,\n    0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000,\n    0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000,\n    0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000,\n    0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000,\n    0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000,\n    0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000,\n    0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000,\n    0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000,\n    0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000,\n    0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000,\n    0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000,\n    0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000,\n    0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000,\n    0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000,\n    0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000,\n    0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000,\n    0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000,\n    0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000,\n    0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000,\n    0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000,\n    0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000,\n    0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000,\n    0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000,\n    0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000,\n    0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000,\n    0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000,\n    0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000,\n    0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000,\n    0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000,\n    0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000,\n    0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000,\n    0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000,\n    0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000,\n    0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000,\n    0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000,\n    0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000,\n    0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000,\n    0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000,\n    0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000,\n    0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000,\n    0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000,\n    0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000,\n    0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000,\n    0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000,\n    0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000,\n    0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000,\n    0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000,\n    0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000,\n    0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000,\n    0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000,\n    0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000,\n    0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000,\n    0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000,\n    0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000,\n    0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000,\n    0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000,\n    0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000,\n    0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000,\n    0xf4bc8a8000000000},\n   {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000,\n    0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000,\n    0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000,\n    0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000,\n    0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000,\n    0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000,\n    0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000,\n    0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000,\n    0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000,\n    0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000,\n    0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000,\n    0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000,\n    0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000,\n    0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000,\n    0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000,\n    0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000,\n    0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000,\n    0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000,\n    0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000,\n    0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000,\n    0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000,\n    0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000,\n    0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000,\n    0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000,\n    0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000,\n    0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000,\n    0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000,\n    0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000,\n    0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000,\n    0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000,\n    0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000,\n    0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000,\n    0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000,\n    0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000,\n    0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000,\n    0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000,\n    0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000,\n    0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000,\n    0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000,\n    0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000,\n    0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000,\n    0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000,\n    0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000,\n    0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000,\n    0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000,\n    0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000,\n    0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000,\n    0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000,\n    0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000,\n    0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000,\n    0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000,\n    0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000,\n    0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000,\n    0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000,\n    0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000,\n    0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000,\n    0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000,\n    0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000,\n    0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000,\n    0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000,\n    0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000,\n    0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000,\n    0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000,\n    0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000,\n    0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000,\n    0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000,\n    0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000,\n    0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000,\n    0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000,\n    0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000,\n    0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000,\n    0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000,\n    0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000,\n    0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000,\n    0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000,\n    0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000,\n    0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000,\n    0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000,\n    0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000,\n    0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000,\n    0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000,\n    0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000,\n    0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000,\n    0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000,\n    0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000,\n    0xb9bc50ba00000000},\n   {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000,\n    0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000,\n    0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000,\n    0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000,\n    0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000,\n    0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000,\n    0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000,\n    0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000,\n    0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000,\n    0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000,\n    0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000,\n    0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000,\n    0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000,\n    0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000,\n    0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000,\n    0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000,\n    0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000,\n    0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000,\n    0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000,\n    0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000,\n    0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000,\n    0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000,\n    0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000,\n    0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000,\n    0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000,\n    0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000,\n    0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000,\n    0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000,\n    0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000,\n    0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000,\n    0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000,\n    0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000,\n    0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000,\n    0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000,\n    0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000,\n    0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000,\n    0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000,\n    0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000,\n    0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000,\n    0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000,\n    0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000,\n    0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000,\n    0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000,\n    0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000,\n    0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000,\n    0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000,\n    0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000,\n    0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000,\n    0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000,\n    0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000,\n    0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000,\n    0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000,\n    0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000,\n    0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000,\n    0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000,\n    0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000,\n    0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000,\n    0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000,\n    0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000,\n    0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000,\n    0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000,\n    0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000,\n    0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000,\n    0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000,\n    0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000,\n    0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000,\n    0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000,\n    0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000,\n    0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000,\n    0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000,\n    0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000,\n    0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000,\n    0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000,\n    0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000,\n    0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000,\n    0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000,\n    0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000,\n    0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000,\n    0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000,\n    0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000,\n    0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000,\n    0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000,\n    0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000,\n    0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000,\n    0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000,\n    0x945b07b200000000},\n   {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000,\n    0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000,\n    0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000,\n    0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000,\n    0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000,\n    0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000,\n    0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000,\n    0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000,\n    0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000,\n    0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000,\n    0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000,\n    0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000,\n    0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000,\n    0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000,\n    0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000,\n    0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000,\n    0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000,\n    0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000,\n    0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000,\n    0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000,\n    0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000,\n    0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000,\n    0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000,\n    0x149f066100000000, 0xef839db200000000, 0x468814fc00000000,\n    0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000,\n    0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000,\n    0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000,\n    0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000,\n    0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000,\n    0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000,\n    0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000,\n    0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000,\n    0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000,\n    0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000,\n    0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000,\n    0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000,\n    0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000,\n    0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000,\n    0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000,\n    0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000,\n    0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000,\n    0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000,\n    0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000,\n    0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000,\n    0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000,\n    0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000,\n    0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000,\n    0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000,\n    0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000,\n    0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000,\n    0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000,\n    0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000,\n    0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000,\n    0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000,\n    0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000,\n    0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000,\n    0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000,\n    0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000,\n    0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000,\n    0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000,\n    0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000,\n    0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000,\n    0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000,\n    0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000,\n    0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000,\n    0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000,\n    0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000,\n    0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000,\n    0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000,\n    0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000,\n    0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000,\n    0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000,\n    0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000,\n    0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000,\n    0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000,\n    0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000,\n    0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000,\n    0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000,\n    0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000,\n    0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000,\n    0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000,\n    0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000,\n    0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000,\n    0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000,\n    0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000,\n    0x0650d0f700000000},\n   {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000,\n    0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000,\n    0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000,\n    0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000,\n    0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000,\n    0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000,\n    0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000,\n    0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000,\n    0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000,\n    0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000,\n    0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000,\n    0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000,\n    0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000,\n    0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000,\n    0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000,\n    0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000,\n    0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000,\n    0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000,\n    0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000,\n    0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000,\n    0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000,\n    0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000,\n    0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000,\n    0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000,\n    0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000,\n    0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000,\n    0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000,\n    0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000,\n    0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000,\n    0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000,\n    0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000,\n    0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000,\n    0xc702c15700000000, 0x809085f800000000, 0x082039d200000000,\n    0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000,\n    0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000,\n    0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000,\n    0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000,\n    0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000,\n    0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000,\n    0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000,\n    0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000,\n    0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000,\n    0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000,\n    0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000,\n    0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000,\n    0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000,\n    0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000,\n    0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000,\n    0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000,\n    0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000,\n    0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000,\n    0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000,\n    0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000,\n    0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000,\n    0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000,\n    0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000,\n    0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000,\n    0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000,\n    0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000,\n    0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000,\n    0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000,\n    0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000,\n    0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000,\n    0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000,\n    0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000,\n    0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000,\n    0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000,\n    0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000,\n    0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000,\n    0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000,\n    0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000,\n    0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000,\n    0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000,\n    0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000,\n    0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000,\n    0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000,\n    0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000,\n    0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000,\n    0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000,\n    0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000,\n    0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000,\n    0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000,\n    0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000,\n    0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000,\n    0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000,\n    0x657594e900000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,\n    0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,\n    0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,\n    0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,\n    0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,\n    0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,\n    0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,\n    0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,\n    0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,\n    0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,\n    0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,\n    0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,\n    0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,\n    0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,\n    0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,\n    0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,\n    0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,\n    0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,\n    0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,\n    0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,\n    0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,\n    0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,\n    0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,\n    0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,\n    0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,\n    0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,\n    0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,\n    0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,\n    0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,\n    0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,\n    0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,\n    0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,\n    0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,\n    0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,\n    0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,\n    0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,\n    0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,\n    0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,\n    0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,\n    0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,\n    0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,\n    0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,\n    0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,\n    0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,\n    0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,\n    0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,\n    0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,\n    0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,\n    0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,\n    0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,\n    0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,\n    0xd8ac6b35},\n   {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,\n    0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,\n    0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,\n    0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,\n    0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,\n    0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,\n    0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,\n    0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,\n    0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,\n    0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,\n    0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,\n    0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,\n    0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,\n    0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,\n    0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,\n    0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,\n    0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,\n    0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,\n    0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,\n    0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,\n    0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,\n    0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,\n    0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,\n    0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,\n    0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,\n    0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,\n    0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,\n    0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,\n    0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,\n    0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,\n    0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,\n    0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,\n    0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,\n    0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,\n    0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,\n    0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,\n    0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,\n    0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,\n    0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,\n    0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,\n    0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,\n    0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,\n    0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,\n    0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,\n    0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,\n    0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,\n    0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,\n    0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,\n    0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,\n    0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,\n    0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,\n    0xa140efa8},\n   {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,\n    0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,\n    0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,\n    0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,\n    0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,\n    0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,\n    0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,\n    0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,\n    0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,\n    0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,\n    0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,\n    0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,\n    0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,\n    0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,\n    0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,\n    0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,\n    0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,\n    0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,\n    0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,\n    0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,\n    0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,\n    0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,\n    0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,\n    0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,\n    0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,\n    0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,\n    0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,\n    0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,\n    0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,\n    0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,\n    0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,\n    0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,\n    0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,\n    0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,\n    0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,\n    0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,\n    0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,\n    0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,\n    0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,\n    0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,\n    0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,\n    0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,\n    0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,\n    0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,\n    0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,\n    0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,\n    0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,\n    0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,\n    0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,\n    0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,\n    0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,\n    0x917cd6a1},\n   {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,\n    0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,\n    0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,\n    0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,\n    0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,\n    0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,\n    0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,\n    0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,\n    0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,\n    0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,\n    0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,\n    0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,\n    0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,\n    0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,\n    0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,\n    0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,\n    0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,\n    0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,\n    0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,\n    0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,\n    0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,\n    0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,\n    0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,\n    0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,\n    0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,\n    0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,\n    0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,\n    0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,\n    0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,\n    0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,\n    0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,\n    0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,\n    0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,\n    0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,\n    0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,\n    0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,\n    0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,\n    0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,\n    0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,\n    0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,\n    0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,\n    0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,\n    0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,\n    0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,\n    0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,\n    0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,\n    0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,\n    0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,\n    0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,\n    0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,\n    0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,\n    0x18ba364e}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873,\n    0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661,\n    0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441,\n    0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44,\n    0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1,\n    0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05,\n    0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa,\n    0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e,\n    0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb,\n    0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be,\n    0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e,\n    0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c,\n    0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d,\n    0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9,\n    0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f,\n    0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b,\n    0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39,\n    0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b,\n    0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b,\n    0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20,\n    0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595,\n    0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61,\n    0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0,\n    0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644,\n    0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1,\n    0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d,\n    0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d,\n    0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f,\n    0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad,\n    0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359,\n    0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f,\n    0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b,\n    0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7,\n    0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5,\n    0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5,\n    0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0,\n    0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65,\n    0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091,\n    0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633,\n    0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7,\n    0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272,\n    0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77,\n    0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57,\n    0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145,\n    0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9,\n    0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d,\n    0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb,\n    0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f,\n    0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad,\n    0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf,\n    0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f,\n    0x4e36ba18},\n   {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b,\n    0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8,\n    0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19,\n    0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4,\n    0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239,\n    0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd,\n    0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258,\n    0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc,\n    0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41,\n    0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c,\n    0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d,\n    0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e,\n    0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba,\n    0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e,\n    0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8,\n    0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c,\n    0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f,\n    0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c,\n    0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d,\n    0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d,\n    0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0,\n    0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014,\n    0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc,\n    0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628,\n    0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5,\n    0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941,\n    0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0,\n    0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53,\n    0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880,\n    0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264,\n    0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92,\n    0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776,\n    0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8,\n    0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b,\n    0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea,\n    0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837,\n    0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca,\n    0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e,\n    0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211,\n    0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5,\n    0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08,\n    0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5,\n    0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934,\n    0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7,\n    0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049,\n    0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad,\n    0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b,\n    0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf,\n    0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c,\n    0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f,\n    0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e,\n    0xa1d67c91},\n   {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9,\n    0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de,\n    0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94,\n    0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0,\n    0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a,\n    0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924,\n    0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052,\n    0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c,\n    0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6,\n    0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2,\n    0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8,\n    0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f,\n    0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d,\n    0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273,\n    0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30,\n    0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e,\n    0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7,\n    0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980,\n    0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca,\n    0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8,\n    0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62,\n    0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c,\n    0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c,\n    0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032,\n    0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798,\n    0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d,\n    0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07,\n    0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630,\n    0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389,\n    0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7,\n    0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4,\n    0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca,\n    0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55,\n    0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662,\n    0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828,\n    0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c,\n    0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6,\n    0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98,\n    0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3,\n    0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d,\n    0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037,\n    0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913,\n    0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759,\n    0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e,\n    0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1,\n    0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf,\n    0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c,\n    0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2,\n    0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b,\n    0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c,\n    0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276,\n    0xa8ef40a1},\n   {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e,\n    0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8,\n    0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819,\n    0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f,\n    0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d,\n    0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756,\n    0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0,\n    0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb,\n    0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9,\n    0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f,\n    0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e,\n    0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8,\n    0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835,\n    0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e,\n    0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62,\n    0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749,\n    0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b,\n    0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d,\n    0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc,\n    0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80,\n    0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2,\n    0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599,\n    0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05,\n    0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e,\n    0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c,\n    0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e,\n    0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef,\n    0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359,\n    0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b,\n    0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0,\n    0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc,\n    0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7,\n    0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f,\n    0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189,\n    0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568,\n    0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e,\n    0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c,\n    0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27,\n    0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794,\n    0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf,\n    0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d,\n    0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db,\n    0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a,\n    0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c,\n    0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544,\n    0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f,\n    0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013,\n    0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38,\n    0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea,\n    0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c,\n    0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd,\n    0x356bacd8}};\n\n#endif\n\n#endif\n\n#if N == 6\n\n#if W == 8\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370,\n    0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d,\n    0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69,\n    0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426,\n    0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3,\n    0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f,\n    0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c,\n    0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490,\n    0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155,\n    0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a,\n    0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e,\n    0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603,\n    0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349,\n    0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5,\n    0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50,\n    0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc,\n    0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b,\n    0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76,\n    0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862,\n    0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9,\n    0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c,\n    0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0,\n    0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937,\n    0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b,\n    0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e,\n    0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e,\n    0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a,\n    0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357,\n    0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0,\n    0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c,\n    0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9,\n    0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165,\n    0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766,\n    0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b,\n    0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f,\n    0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030,\n    0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5,\n    0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59,\n    0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63,\n    0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf,\n    0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a,\n    0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845,\n    0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51,\n    0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c,\n    0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f,\n    0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3,\n    0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46,\n    0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea,\n    0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d,\n    0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60,\n    0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74,\n    0x8568a0a8},\n   {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5,\n    0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf,\n    0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5,\n    0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba,\n    0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf,\n    0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f,\n    0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0,\n    0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450,\n    0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55,\n    0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a,\n    0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620,\n    0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a,\n    0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454,\n    0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4,\n    0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534,\n    0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584,\n    0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694,\n    0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e,\n    0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4,\n    0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1,\n    0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4,\n    0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164,\n    0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1,\n    0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911,\n    0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314,\n    0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c,\n    0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6,\n    0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec,\n    0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc,\n    0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c,\n    0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c,\n    0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c,\n    0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716,\n    0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c,\n    0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676,\n    0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879,\n    0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c,\n    0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc,\n    0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77,\n    0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7,\n    0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2,\n    0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd,\n    0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7,\n    0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad,\n    0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897,\n    0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827,\n    0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7,\n    0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947,\n    0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57,\n    0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d,\n    0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37,\n    0x0d907052},\n   {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d,\n    0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89,\n    0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31,\n    0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81,\n    0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e,\n    0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0,\n    0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f,\n    0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291,\n    0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e,\n    0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e,\n    0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936,\n    0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2,\n    0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13,\n    0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d,\n    0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f,\n    0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1,\n    0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a,\n    0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae,\n    0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516,\n    0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f,\n    0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20,\n    0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe,\n    0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28,\n    0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6,\n    0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419,\n    0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5,\n    0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d,\n    0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889,\n    0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412,\n    0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c,\n    0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e,\n    0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0,\n    0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02,\n    0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986,\n    0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e,\n    0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e,\n    0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221,\n    0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf,\n    0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913,\n    0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d,\n    0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622,\n    0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592,\n    0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a,\n    0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae,\n    0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c,\n    0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82,\n    0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20,\n    0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe,\n    0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025,\n    0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1,\n    0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719,\n    0xfd1a6c8a},\n   {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3,\n    0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb,\n    0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d,\n    0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb,\n    0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9,\n    0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156,\n    0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045,\n    0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa,\n    0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8,\n    0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e,\n    0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8,\n    0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0,\n    0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38,\n    0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87,\n    0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46,\n    0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9,\n    0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585,\n    0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d,\n    0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb,\n    0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531,\n    0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03,\n    0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc,\n    0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33,\n    0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c,\n    0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be,\n    0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d,\n    0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b,\n    0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303,\n    0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f,\n    0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0,\n    0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801,\n    0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe,\n    0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e,\n    0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346,\n    0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620,\n    0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776,\n    0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844,\n    0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb,\n    0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0,\n    0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f,\n    0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d,\n    0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b,\n    0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d,\n    0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75,\n    0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795,\n    0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a,\n    0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb,\n    0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354,\n    0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28,\n    0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30,\n    0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856,\n    0x7895f01a},\n   {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188,\n    0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33,\n    0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d,\n    0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445,\n    0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2,\n    0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058,\n    0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43,\n    0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9,\n    0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e,\n    0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06,\n    0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228,\n    0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93,\n    0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e,\n    0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4,\n    0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b,\n    0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371,\n    0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265,\n    0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede,\n    0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0,\n    0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f,\n    0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8,\n    0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32,\n    0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae,\n    0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544,\n    0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3,\n    0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f,\n    0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911,\n    0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa,\n    0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be,\n    0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54,\n    0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b,\n    0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1,\n    0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652,\n    0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9,\n    0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7,\n    0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f,\n    0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68,\n    0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782,\n    0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797,\n    0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d,\n    0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a,\n    0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2,\n    0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc,\n    0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647,\n    0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4,\n    0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e,\n    0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41,\n    0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab,\n    0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf,\n    0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904,\n    0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a,\n    0x9239b848},\n   {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad,\n    0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0,\n    0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40,\n    0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b,\n    0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d,\n    0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b,\n    0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb,\n    0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d,\n    0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b,\n    0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0,\n    0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840,\n    0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d,\n    0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b,\n    0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d,\n    0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6,\n    0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0,\n    0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580,\n    0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd,\n    0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d,\n    0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b,\n    0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d,\n    0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b,\n    0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6,\n    0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0,\n    0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6,\n    0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c,\n    0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c,\n    0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461,\n    0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841,\n    0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317,\n    0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac,\n    0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa,\n    0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7,\n    0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba,\n    0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a,\n    0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161,\n    0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777,\n    0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21,\n    0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a,\n    0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc,\n    0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da,\n    0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1,\n    0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01,\n    0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c,\n    0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241,\n    0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917,\n    0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac,\n    0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa,\n    0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da,\n    0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397,\n    0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537,\n    0xeb36d3cc},\n   {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b,\n    0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059,\n    0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251,\n    0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d,\n    0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9,\n    0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c,\n    0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41,\n    0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4,\n    0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10,\n    0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c,\n    0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54,\n    0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476,\n    0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8,\n    0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d,\n    0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92,\n    0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307,\n    0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad,\n    0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f,\n    0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87,\n    0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17,\n    0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3,\n    0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46,\n    0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197,\n    0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02,\n    0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6,\n    0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e,\n    0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96,\n    0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4,\n    0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e,\n    0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b,\n    0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934,\n    0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1,\n    0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7,\n    0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5,\n    0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd,\n    0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1,\n    0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475,\n    0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0,\n    0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155,\n    0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0,\n    0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304,\n    0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348,\n    0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140,\n    0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862,\n    0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14,\n    0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181,\n    0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e,\n    0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab,\n    0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01,\n    0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523,\n    0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b,\n    0x38e5f3c5},\n   {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06,\n    0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad,\n    0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509,\n    0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba,\n    0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414,\n    0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3,\n    0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733,\n    0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994,\n    0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a,\n    0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889,\n    0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d,\n    0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386,\n    0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621,\n    0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886,\n    0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e,\n    0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389,\n    0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f,\n    0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294,\n    0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30,\n    0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3,\n    0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d,\n    0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba,\n    0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a,\n    0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad,\n    0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03,\n    0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2,\n    0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306,\n    0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad,\n    0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b,\n    0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc,\n    0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914,\n    0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3,\n    0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435,\n    0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e,\n    0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a,\n    0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589,\n    0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27,\n    0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080,\n    0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21,\n    0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586,\n    0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28,\n    0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b,\n    0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f,\n    0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94,\n    0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12,\n    0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5,\n    0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d,\n    0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba,\n    0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c,\n    0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7,\n    0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103,\n    0x3d3101a2}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000,\n    0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000,\n    0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000,\n    0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000,\n    0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000,\n    0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000,\n    0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000,\n    0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000,\n    0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000,\n    0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000,\n    0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000,\n    0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000,\n    0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000,\n    0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000,\n    0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000,\n    0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000,\n    0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000,\n    0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000,\n    0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000,\n    0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000,\n    0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000,\n    0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000,\n    0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000,\n    0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000,\n    0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000,\n    0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000,\n    0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000,\n    0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000,\n    0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000,\n    0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000,\n    0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000,\n    0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000,\n    0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000,\n    0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000,\n    0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000,\n    0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000,\n    0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000,\n    0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000,\n    0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000,\n    0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000,\n    0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000,\n    0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000,\n    0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000,\n    0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000,\n    0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000,\n    0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000,\n    0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000,\n    0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000,\n    0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000,\n    0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000,\n    0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000,\n    0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000,\n    0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000,\n    0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000,\n    0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000,\n    0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000,\n    0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000,\n    0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000,\n    0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000,\n    0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000,\n    0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000,\n    0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000,\n    0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000,\n    0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000,\n    0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000,\n    0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000,\n    0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000,\n    0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000,\n    0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000,\n    0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000,\n    0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000,\n    0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000,\n    0x3688267d00000000, 0x9718319500000000, 0x35af787600000000,\n    0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000,\n    0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000,\n    0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000,\n    0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000,\n    0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000,\n    0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000,\n    0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000,\n    0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000,\n    0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000,\n    0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000,\n    0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000,\n    0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000,\n    0xa201313d00000000},\n   {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000,\n    0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000,\n    0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000,\n    0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000,\n    0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000,\n    0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000,\n    0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000,\n    0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000,\n    0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000,\n    0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000,\n    0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000,\n    0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000,\n    0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000,\n    0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000,\n    0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000,\n    0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000,\n    0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000,\n    0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000,\n    0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000,\n    0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000,\n    0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000,\n    0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000,\n    0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000,\n    0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000,\n    0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000,\n    0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000,\n    0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000,\n    0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000,\n    0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000,\n    0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000,\n    0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000,\n    0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000,\n    0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000,\n    0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000,\n    0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000,\n    0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000,\n    0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000,\n    0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000,\n    0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000,\n    0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000,\n    0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000,\n    0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000,\n    0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000,\n    0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000,\n    0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000,\n    0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000,\n    0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000,\n    0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000,\n    0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000,\n    0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000,\n    0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000,\n    0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000,\n    0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000,\n    0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000,\n    0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000,\n    0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000,\n    0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000,\n    0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000,\n    0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000,\n    0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000,\n    0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000,\n    0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000,\n    0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000,\n    0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000,\n    0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000,\n    0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000,\n    0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000,\n    0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000,\n    0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000,\n    0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000,\n    0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000,\n    0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000,\n    0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000,\n    0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000,\n    0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000,\n    0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000,\n    0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000,\n    0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000,\n    0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000,\n    0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000,\n    0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000,\n    0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000,\n    0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000,\n    0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000,\n    0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000,\n    0xc5f3e53800000000},\n   {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000,\n    0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000,\n    0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000,\n    0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000,\n    0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000,\n    0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000,\n    0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000,\n    0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000,\n    0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000,\n    0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000,\n    0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000,\n    0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000,\n    0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000,\n    0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000,\n    0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000,\n    0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000,\n    0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000,\n    0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000,\n    0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000,\n    0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000,\n    0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000,\n    0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000,\n    0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000,\n    0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000,\n    0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000,\n    0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000,\n    0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000,\n    0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000,\n    0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000,\n    0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000,\n    0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000,\n    0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000,\n    0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000,\n    0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000,\n    0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000,\n    0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000,\n    0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000,\n    0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000,\n    0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000,\n    0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000,\n    0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000,\n    0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000,\n    0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000,\n    0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000,\n    0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000,\n    0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000,\n    0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000,\n    0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000,\n    0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000,\n    0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000,\n    0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000,\n    0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000,\n    0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000,\n    0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000,\n    0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000,\n    0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000,\n    0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000,\n    0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000,\n    0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000,\n    0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000,\n    0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000,\n    0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000,\n    0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000,\n    0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000,\n    0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000,\n    0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000,\n    0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000,\n    0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000,\n    0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000,\n    0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000,\n    0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000,\n    0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000,\n    0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000,\n    0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000,\n    0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000,\n    0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000,\n    0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000,\n    0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000,\n    0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000,\n    0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000,\n    0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000,\n    0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000,\n    0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000,\n    0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000,\n    0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000,\n    0xccd336eb00000000},\n   {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000,\n    0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000,\n    0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000,\n    0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000,\n    0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000,\n    0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000,\n    0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000,\n    0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000,\n    0xb249204500000000, 0xd071086f00000000, 0x7639701100000000,\n    0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000,\n    0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000,\n    0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000,\n    0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000,\n    0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000,\n    0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000,\n    0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000,\n    0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000,\n    0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000,\n    0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000,\n    0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000,\n    0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000,\n    0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000,\n    0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000,\n    0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000,\n    0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000,\n    0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000,\n    0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000,\n    0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000,\n    0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000,\n    0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000,\n    0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000,\n    0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000,\n    0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000,\n    0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000,\n    0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000,\n    0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000,\n    0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000,\n    0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000,\n    0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000,\n    0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000,\n    0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000,\n    0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000,\n    0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000,\n    0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000,\n    0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000,\n    0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000,\n    0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000,\n    0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000,\n    0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000,\n    0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000,\n    0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000,\n    0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000,\n    0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000,\n    0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000,\n    0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000,\n    0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000,\n    0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000,\n    0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000,\n    0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000,\n    0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000,\n    0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000,\n    0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000,\n    0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000,\n    0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000,\n    0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000,\n    0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000,\n    0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000,\n    0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000,\n    0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000,\n    0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000,\n    0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000,\n    0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000,\n    0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000,\n    0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000,\n    0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000,\n    0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000,\n    0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000,\n    0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000,\n    0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000,\n    0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000,\n    0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000,\n    0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000,\n    0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000,\n    0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000,\n    0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000,\n    0x48b8399200000000},\n   {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000,\n    0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000,\n    0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000,\n    0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000,\n    0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000,\n    0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000,\n    0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000,\n    0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000,\n    0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000,\n    0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000,\n    0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000,\n    0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000,\n    0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000,\n    0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000,\n    0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000,\n    0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000,\n    0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000,\n    0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000,\n    0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000,\n    0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000,\n    0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000,\n    0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000,\n    0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000,\n    0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000,\n    0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000,\n    0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000,\n    0xb521428400000000, 0xf909d42700000000, 0x762efede00000000,\n    0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000,\n    0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000,\n    0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000,\n    0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000,\n    0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000,\n    0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000,\n    0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000,\n    0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000,\n    0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000,\n    0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000,\n    0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000,\n    0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000,\n    0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000,\n    0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000,\n    0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000,\n    0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000,\n    0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000,\n    0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000,\n    0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000,\n    0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000,\n    0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000,\n    0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000,\n    0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000,\n    0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000,\n    0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000,\n    0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000,\n    0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000,\n    0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000,\n    0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000,\n    0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000,\n    0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000,\n    0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000,\n    0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000,\n    0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000,\n    0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000,\n    0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000,\n    0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000,\n    0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000,\n    0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000,\n    0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000,\n    0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000,\n    0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000,\n    0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000,\n    0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000,\n    0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000,\n    0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000,\n    0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000,\n    0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000,\n    0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000,\n    0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000,\n    0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000,\n    0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000,\n    0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000,\n    0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000,\n    0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000,\n    0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000,\n    0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000,\n    0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000,\n    0x1af0957800000000},\n   {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000,\n    0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000,\n    0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000,\n    0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000,\n    0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000,\n    0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000,\n    0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000,\n    0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000,\n    0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000,\n    0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000,\n    0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000,\n    0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000,\n    0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000,\n    0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000,\n    0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000,\n    0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000,\n    0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000,\n    0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000,\n    0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000,\n    0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000,\n    0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000,\n    0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000,\n    0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000,\n    0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000,\n    0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000,\n    0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000,\n    0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000,\n    0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000,\n    0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000,\n    0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000,\n    0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000,\n    0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000,\n    0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000,\n    0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000,\n    0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000,\n    0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000,\n    0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000,\n    0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000,\n    0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000,\n    0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000,\n    0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000,\n    0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000,\n    0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000,\n    0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000,\n    0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000,\n    0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000,\n    0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000,\n    0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000,\n    0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000,\n    0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000,\n    0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000,\n    0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000,\n    0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000,\n    0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000,\n    0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000,\n    0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000,\n    0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000,\n    0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000,\n    0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000,\n    0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000,\n    0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000,\n    0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000,\n    0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000,\n    0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000,\n    0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000,\n    0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000,\n    0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000,\n    0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000,\n    0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000,\n    0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000,\n    0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000,\n    0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000,\n    0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000,\n    0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000,\n    0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000,\n    0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000,\n    0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000,\n    0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000,\n    0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000,\n    0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000,\n    0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000,\n    0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000,\n    0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000,\n    0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000,\n    0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000,\n    0x8a6c1afd00000000},\n   {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000,\n    0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000,\n    0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000,\n    0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000,\n    0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000,\n    0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000,\n    0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000,\n    0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000,\n    0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000,\n    0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000,\n    0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000,\n    0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000,\n    0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000,\n    0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000,\n    0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000,\n    0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000,\n    0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000,\n    0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000,\n    0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000,\n    0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000,\n    0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000,\n    0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000,\n    0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000,\n    0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000,\n    0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000,\n    0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000,\n    0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000,\n    0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000,\n    0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000,\n    0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000,\n    0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000,\n    0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000,\n    0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000,\n    0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000,\n    0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000,\n    0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000,\n    0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000,\n    0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000,\n    0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000,\n    0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000,\n    0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000,\n    0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000,\n    0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000,\n    0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000,\n    0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000,\n    0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000,\n    0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000,\n    0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000,\n    0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000,\n    0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000,\n    0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000,\n    0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000,\n    0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000,\n    0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000,\n    0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000,\n    0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000,\n    0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000,\n    0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000,\n    0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000,\n    0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000,\n    0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000,\n    0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000,\n    0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000,\n    0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000,\n    0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000,\n    0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000,\n    0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000,\n    0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000,\n    0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000,\n    0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000,\n    0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000,\n    0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000,\n    0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000,\n    0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000,\n    0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000,\n    0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000,\n    0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000,\n    0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000,\n    0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000,\n    0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000,\n    0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000,\n    0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000,\n    0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000,\n    0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000,\n    0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000,\n    0x5270900d00000000},\n   {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000,\n    0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000,\n    0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000,\n    0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000,\n    0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000,\n    0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000,\n    0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000,\n    0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000,\n    0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000,\n    0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000,\n    0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000,\n    0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000,\n    0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000,\n    0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000,\n    0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000,\n    0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000,\n    0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000,\n    0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000,\n    0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000,\n    0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000,\n    0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000,\n    0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000,\n    0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000,\n    0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000,\n    0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000,\n    0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000,\n    0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000,\n    0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000,\n    0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000,\n    0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000,\n    0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000,\n    0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000,\n    0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000,\n    0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000,\n    0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000,\n    0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000,\n    0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000,\n    0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000,\n    0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000,\n    0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000,\n    0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000,\n    0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000,\n    0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000,\n    0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000,\n    0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000,\n    0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000,\n    0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000,\n    0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000,\n    0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000,\n    0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000,\n    0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000,\n    0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000,\n    0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000,\n    0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000,\n    0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000,\n    0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000,\n    0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000,\n    0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000,\n    0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000,\n    0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000,\n    0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000,\n    0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000,\n    0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000,\n    0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000,\n    0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000,\n    0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000,\n    0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000,\n    0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000,\n    0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000,\n    0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000,\n    0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000,\n    0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000,\n    0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000,\n    0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000,\n    0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000,\n    0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000,\n    0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000,\n    0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000,\n    0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000,\n    0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000,\n    0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000,\n    0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000,\n    0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000,\n    0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000,\n    0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000,\n    0xa8a0688500000000}};\n\n#else /* W == 4 */\n\nlocal const z_crc_t FAR crc_braid_table[][256] = {\n   {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,\n    0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,\n    0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,\n    0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,\n    0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,\n    0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,\n    0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,\n    0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,\n    0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,\n    0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,\n    0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,\n    0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,\n    0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,\n    0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,\n    0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,\n    0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,\n    0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,\n    0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,\n    0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,\n    0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,\n    0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,\n    0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,\n    0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,\n    0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,\n    0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,\n    0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,\n    0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,\n    0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,\n    0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,\n    0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,\n    0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,\n    0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,\n    0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,\n    0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,\n    0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,\n    0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,\n    0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,\n    0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,\n    0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,\n    0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,\n    0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,\n    0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,\n    0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,\n    0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,\n    0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,\n    0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,\n    0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,\n    0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,\n    0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,\n    0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,\n    0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,\n    0x09cd8551},\n   {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,\n    0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,\n    0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,\n    0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,\n    0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,\n    0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,\n    0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,\n    0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,\n    0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,\n    0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,\n    0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,\n    0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,\n    0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,\n    0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,\n    0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,\n    0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,\n    0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,\n    0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,\n    0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,\n    0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,\n    0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,\n    0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,\n    0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,\n    0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,\n    0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,\n    0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,\n    0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,\n    0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,\n    0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,\n    0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,\n    0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,\n    0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,\n    0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,\n    0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,\n    0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,\n    0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,\n    0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,\n    0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,\n    0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,\n    0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,\n    0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,\n    0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,\n    0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,\n    0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,\n    0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,\n    0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,\n    0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,\n    0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,\n    0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,\n    0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,\n    0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,\n    0x7bc97a0c},\n   {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,\n    0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,\n    0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,\n    0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,\n    0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,\n    0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,\n    0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,\n    0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,\n    0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,\n    0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,\n    0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,\n    0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,\n    0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,\n    0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,\n    0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,\n    0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,\n    0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,\n    0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,\n    0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,\n    0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,\n    0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,\n    0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,\n    0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,\n    0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,\n    0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,\n    0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,\n    0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,\n    0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,\n    0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,\n    0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,\n    0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,\n    0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,\n    0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,\n    0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,\n    0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,\n    0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,\n    0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,\n    0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,\n    0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,\n    0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,\n    0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,\n    0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,\n    0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,\n    0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,\n    0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,\n    0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,\n    0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,\n    0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,\n    0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,\n    0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,\n    0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,\n    0x7851a2ca},\n   {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,\n    0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,\n    0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,\n    0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,\n    0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,\n    0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,\n    0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,\n    0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,\n    0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,\n    0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,\n    0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,\n    0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,\n    0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,\n    0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,\n    0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,\n    0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,\n    0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,\n    0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,\n    0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,\n    0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,\n    0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,\n    0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,\n    0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,\n    0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,\n    0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,\n    0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,\n    0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,\n    0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,\n    0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,\n    0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,\n    0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,\n    0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,\n    0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,\n    0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,\n    0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,\n    0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,\n    0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,\n    0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,\n    0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,\n    0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,\n    0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,\n    0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,\n    0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,\n    0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,\n    0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,\n    0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,\n    0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,\n    0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,\n    0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,\n    0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,\n    0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,\n    0x566b6848}};\n\nlocal const z_word_t FAR crc_braid_big_table[][256] = {\n   {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912,\n    0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba,\n    0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3,\n    0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30,\n    0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e,\n    0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3,\n    0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73,\n    0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe,\n    0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0,\n    0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643,\n    0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a,\n    0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082,\n    0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4,\n    0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279,\n    0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735,\n    0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8,\n    0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad,\n    0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05,\n    0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c,\n    0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718,\n    0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46,\n    0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb,\n    0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc,\n    0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41,\n    0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f,\n    0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad,\n    0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4,\n    0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c,\n    0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779,\n    0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4,\n    0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8,\n    0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235,\n    0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7,\n    0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f,\n    0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476,\n    0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195,\n    0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb,\n    0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46,\n    0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622,\n    0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af,\n    0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1,\n    0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12,\n    0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b,\n    0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3,\n    0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51,\n    0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc,\n    0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90,\n    0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d,\n    0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708,\n    0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0,\n    0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9,\n    0x48686b56},\n   {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c,\n    0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae,\n    0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb,\n    0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90,\n    0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410,\n    0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b,\n    0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6,\n    0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed,\n    0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d,\n    0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036,\n    0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953,\n    0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1,\n    0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca,\n    0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781,\n    0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d,\n    0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416,\n    0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f,\n    0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd,\n    0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8,\n    0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b,\n    0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb,\n    0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0,\n    0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5,\n    0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e,\n    0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e,\n    0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558,\n    0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d,\n    0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf,\n    0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6,\n    0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad,\n    0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971,\n    0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a,\n    0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b,\n    0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969,\n    0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c,\n    0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57,\n    0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7,\n    0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c,\n    0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab,\n    0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0,\n    0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160,\n    0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b,\n    0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e,\n    0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac,\n    0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d,\n    0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546,\n    0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a,\n    0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1,\n    0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8,\n    0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a,\n    0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f,\n    0xcaa25178},\n   {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00,\n    0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b,\n    0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed,\n    0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777,\n    0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01,\n    0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a,\n    0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef,\n    0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74,\n    0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002,\n    0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498,\n    0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee,\n    0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75,\n    0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05,\n    0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e,\n    0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8,\n    0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73,\n    0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404,\n    0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f,\n    0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9,\n    0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71,\n    0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607,\n    0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c,\n    0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb,\n    0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470,\n    0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806,\n    0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790,\n    0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6,\n    0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d,\n    0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a,\n    0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991,\n    0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7,\n    0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c,\n    0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09,\n    0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92,\n    0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4,\n    0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e,\n    0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08,\n    0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593,\n    0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3,\n    0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778,\n    0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e,\n    0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94,\n    0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2,\n    0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079,\n    0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c,\n    0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497,\n    0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1,\n    0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a,\n    0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d,\n    0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396,\n    0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0,\n    0x0c7ac97b},\n   {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669,\n    0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853,\n    0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062,\n    0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527,\n    0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad,\n    0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545,\n    0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27,\n    0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf,\n    0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45,\n    0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800,\n    0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031,\n    0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b,\n    0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26,\n    0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce,\n    0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d,\n    0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5,\n    0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130,\n    0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a,\n    0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b,\n    0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480,\n    0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a,\n    0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2,\n    0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e,\n    0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996,\n    0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c,\n    0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc,\n    0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd,\n    0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7,\n    0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232,\n    0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da,\n    0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439,\n    0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1,\n    0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da,\n    0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0,\n    0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1,\n    0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94,\n    0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e,\n    0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6,\n    0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2,\n    0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a,\n    0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0,\n    0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95,\n    0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4,\n    0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e,\n    0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395,\n    0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d,\n    0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e,\n    0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676,\n    0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83,\n    0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9,\n    0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888,\n    0x5185cd09}};\n\n#endif\n\n#endif\n\n#endif\n\nlocal const z_crc_t FAR x2n_table[] = {\n    0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000,\n    0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467,\n    0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0,\n    0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169,\n    0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37,\n    0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a,\n    0xc40ba6d0, 0xc4e22c3c};\n"
  },
  {
    "path": "vendor/core/vendor/zlib/deflate.c",
    "content": "/* deflate.c -- compress data using the deflation algorithm\n * Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n *  ALGORITHM\n *\n *      The \"deflation\" process depends on being able to identify portions\n *      of the input text which are identical to earlier input (within a\n *      sliding window trailing behind the input currently being processed).\n *\n *      The most straightforward technique turns out to be the fastest for\n *      most input files: try all possible matches and select the longest.\n *      The key feature of this algorithm is that insertions into the string\n *      dictionary are very simple and thus fast, and deletions are avoided\n *      completely. Insertions are performed at each input character, whereas\n *      string matches are performed only when the previous match ends. So it\n *      is preferable to spend more time in matches to allow very fast string\n *      insertions and avoid deletions. The matching algorithm for small\n *      strings is inspired from that of Rabin & Karp. A brute force approach\n *      is used to find longer strings when a small match has been found.\n *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze\n *      (by Leonid Broukhis).\n *         A previous version of this file used a more sophisticated algorithm\n *      (by Fiala and Greene) which is guaranteed to run in linear amortized\n *      time, but has a larger average cost, uses more memory and is patented.\n *      However the F&G algorithm may be faster for some highly redundant\n *      files if the parameter max_chain_length (described below) is too large.\n *\n *  ACKNOWLEDGEMENTS\n *\n *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and\n *      I found it in 'freeze' written by Leonid Broukhis.\n *      Thanks to many people for bug reports and testing.\n *\n *  REFERENCES\n *\n *      Deutsch, L.P.,\"DEFLATE Compressed Data Format Specification\".\n *      Available at https://datatracker.ietf.org/doc/html/rfc1951\n *\n *      A description of the Rabin and Karp algorithm is given in the book\n *         \"Algorithms\" by R. Sedgewick, Addison-Wesley, p252.\n *\n *      Fiala,E.R., and Greene,D.H.\n *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595\n *\n */\n\n/* @(#) $Id$ */\n\n#include \"deflate.h\"\n\nconst char deflate_copyright[] =\n   \" deflate 1.3.2 Copyright 1995-2026 Jean-loup Gailly and Mark Adler \";\n/*\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n */\n\ntypedef enum {\n    need_more,      /* block not completed, need more input or more output */\n    block_done,     /* block flush performed */\n    finish_started, /* finish started, need only more output at next deflate */\n    finish_done     /* finish done, accept no more input or output */\n} block_state;\n\ntypedef block_state (*compress_func)(deflate_state *s, int flush);\n/* Compression function. Returns the block state after the call. */\n\nlocal block_state deflate_stored(deflate_state *s, int flush);\nlocal block_state deflate_fast(deflate_state *s, int flush);\n#ifndef FASTEST\nlocal block_state deflate_slow(deflate_state *s, int flush);\n#endif\nlocal block_state deflate_rle(deflate_state *s, int flush);\nlocal block_state deflate_huff(deflate_state *s, int flush);\n\n/* ===========================================================================\n * Local data\n */\n\n#define NIL 0\n/* Tail of hash chains */\n\n#ifndef TOO_FAR\n#  define TOO_FAR 4096\n#endif\n/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */\n\n/* Values for max_lazy_match, good_match and max_chain_length, depending on\n * the desired pack level (0..9). The values given below have been tuned to\n * exclude worst case performance for pathological files. Better values may be\n * found for specific files.\n */\ntypedef struct config_s {\n   ush good_length; /* reduce lazy search above this match length */\n   ush max_lazy;    /* do not perform lazy search above this match length */\n   ush nice_length; /* quit search above this match length */\n   ush max_chain;\n   compress_func func;\n} config;\n\n#ifdef FASTEST\nlocal const config configuration_table[2] = {\n/*      good lazy nice chain */\n/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */\n/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */\n#else\nlocal const config configuration_table[10] = {\n/*      good lazy nice chain */\n/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */\n/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */\n/* 2 */ {4,    5, 16,    8, deflate_fast},\n/* 3 */ {4,    6, 32,   32, deflate_fast},\n\n/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */\n/* 5 */ {8,   16, 32,   32, deflate_slow},\n/* 6 */ {8,   16, 128, 128, deflate_slow},\n/* 7 */ {8,   32, 128, 256, deflate_slow},\n/* 8 */ {32, 128, 258, 1024, deflate_slow},\n/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */\n#endif\n\n/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4\n * For deflate_fast() (levels <= 3) good is ignored and lazy has a different\n * meaning.\n */\n\n/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */\n#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))\n\n/* ===========================================================================\n * Update a hash value with the given input byte\n * IN  assertion: all calls to UPDATE_HASH are made with consecutive input\n *    characters, so that a running hash key can be computed from the previous\n *    key instead of complete recalculation each time.\n */\n#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask)\n\n\n/* ===========================================================================\n * Insert string str in the dictionary and set match_head to the previous head\n * of the hash chain (the most recent string with same hash key). Return\n * the previous length of the hash chain.\n * If this file is compiled with -DFASTEST, the compression level is forced\n * to 1, and no hash chains are maintained.\n * IN  assertion: all calls to INSERT_STRING are made with consecutive input\n *    characters and the first MIN_MATCH bytes of str are valid (except for\n *    the last MIN_MATCH-1 bytes of the input file).\n */\n#ifdef FASTEST\n#define INSERT_STRING(s, str, match_head) \\\n   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \\\n    match_head = s->head[s->ins_h], \\\n    s->head[s->ins_h] = (Pos)(str))\n#else\n#define INSERT_STRING(s, str, match_head) \\\n   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \\\n    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \\\n    s->head[s->ins_h] = (Pos)(str))\n#endif\n\n/* ===========================================================================\n * Initialize the hash table (avoiding 64K overflow for 16 bit systems).\n * prev[] will be initialized on the fly.\n */\n#define CLEAR_HASH(s) \\\n    do { \\\n        s->head[s->hash_size - 1] = NIL; \\\n        zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \\\n        s->slid = 0; \\\n    } while (0)\n\n/* ===========================================================================\n * Slide the hash table when sliding the window down (could be avoided with 32\n * bit values at the expense of memory usage). We slide even when level == 0 to\n * keep the hash table consistent if we switch back to level > 0 later.\n */\n#if defined(__has_feature)\n#  if __has_feature(memory_sanitizer)\n     __attribute__((no_sanitize(\"memory\")))\n#  endif\n#endif\nlocal void slide_hash(deflate_state *s) {\n    unsigned n, m;\n    Posf *p;\n    uInt wsize = s->w_size;\n\n    n = s->hash_size;\n    p = &s->head[n];\n    do {\n        m = *--p;\n        *p = (Pos)(m >= wsize ? m - wsize : NIL);\n    } while (--n);\n#ifndef FASTEST\n    n = wsize;\n    p = &s->prev[n];\n    do {\n        m = *--p;\n        *p = (Pos)(m >= wsize ? m - wsize : NIL);\n        /* If n is not on any hash chain, prev[n] is garbage but\n         * its value will never be used.\n         */\n    } while (--n);\n#endif\n    s->slid = 1;\n}\n\n/* ===========================================================================\n * Read a new buffer from the current input stream, update the adler32\n * and total number of bytes read.  All deflate() input goes through\n * this function so some applications may wish to modify it to avoid\n * allocating a large strm->next_in buffer and copying from it.\n * (See also flush_pending()).\n */\nlocal unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) {\n    unsigned len = strm->avail_in;\n\n    if (len > size) len = size;\n    if (len == 0) return 0;\n\n    strm->avail_in  -= len;\n\n    zmemcpy(buf, strm->next_in, len);\n    if (strm->state->wrap == 1) {\n        strm->adler = adler32(strm->adler, buf, len);\n    }\n#ifdef GZIP\n    else if (strm->state->wrap == 2) {\n        strm->adler = crc32(strm->adler, buf, len);\n    }\n#endif\n    strm->next_in  += len;\n    strm->total_in += len;\n\n    return len;\n}\n\n/* ===========================================================================\n * Fill the window when the lookahead becomes insufficient.\n * Updates strstart and lookahead.\n *\n * IN assertion: lookahead < MIN_LOOKAHEAD\n * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n *    At least one byte has been read, or avail_in == 0; reads are\n *    performed for at least two bytes (required for the zip translate_eol\n *    option -- not supported here).\n */\nlocal void fill_window(deflate_state *s) {\n    unsigned n;\n    unsigned more;    /* Amount of free space at the end of the window. */\n    uInt wsize = s->w_size;\n\n    Assert(s->lookahead < MIN_LOOKAHEAD, \"already enough lookahead\");\n\n    do {\n        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);\n\n        /* Deal with !@#$% 64K limit: */\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable: 4127)\n#endif\n        if (sizeof(int) <= 2) {\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {\n                more = wsize;\n\n            } else if (more == (unsigned)(-1)) {\n                /* Very unlikely, but possible on 16 bit machine if\n                 * strstart == 0 && lookahead == 1 (input done a byte at time)\n                 */\n                more--;\n            }\n        }\n\n        /* If the window is almost full and there is insufficient lookahead,\n         * move the upper half to the lower one to make room in the upper half.\n         */\n        if (s->strstart >= wsize + MAX_DIST(s)) {\n\n            zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);\n            s->match_start -= wsize;\n            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */\n            s->block_start -= (long) wsize;\n            if (s->insert > s->strstart)\n                s->insert = s->strstart;\n            slide_hash(s);\n            more += wsize;\n        }\n        if (s->strm->avail_in == 0) break;\n\n        /* If there was no sliding:\n         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n         *    more == window_size - lookahead - strstart\n         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n         * => more >= window_size - 2*WSIZE + 2\n         * In the BIG_MEM or MMAP case (not yet supported),\n         *   window_size == input_size + MIN_LOOKAHEAD  &&\n         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n         * Otherwise, window_size == 2*WSIZE so more >= 2.\n         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n         */\n        Assert(more >= 2, \"more < 2\");\n\n        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);\n        s->lookahead += n;\n\n        /* Initialize the hash value now that we have some input: */\n        if (s->lookahead + s->insert >= MIN_MATCH) {\n            uInt str = s->strstart - s->insert;\n            s->ins_h = s->window[str];\n            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);\n#if MIN_MATCH != 3\n            Call UPDATE_HASH() MIN_MATCH-3 more times\n#endif\n            while (s->insert) {\n                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);\n#ifndef FASTEST\n                s->prev[str & s->w_mask] = s->head[s->ins_h];\n#endif\n                s->head[s->ins_h] = (Pos)str;\n                str++;\n                s->insert--;\n                if (s->lookahead + s->insert < MIN_MATCH)\n                    break;\n            }\n        }\n        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n         * but this is not important since only literal bytes will be emitted.\n         */\n\n    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);\n\n    /* If the WIN_INIT bytes after the end of the current data have never been\n     * written, then zero those bytes in order to avoid memory check reports of\n     * the use of uninitialized (or uninitialised as Julian writes) bytes by\n     * the longest match routines.  Update the high water mark for the next\n     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match\n     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.\n     */\n    if (s->high_water < s->window_size) {\n        ulg curr = s->strstart + (ulg)(s->lookahead);\n        ulg init;\n\n        if (s->high_water < curr) {\n            /* Previous high water mark below current data -- zero WIN_INIT\n             * bytes or up to end of window, whichever is less.\n             */\n            init = s->window_size - curr;\n            if (init > WIN_INIT)\n                init = WIN_INIT;\n            zmemzero(s->window + curr, (unsigned)init);\n            s->high_water = curr + init;\n        }\n        else if (s->high_water < (ulg)curr + WIN_INIT) {\n            /* High water mark at or above current data, but below current data\n             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up\n             * to end of window, whichever is less.\n             */\n            init = (ulg)curr + WIN_INIT - s->high_water;\n            if (init > s->window_size - s->high_water)\n                init = s->window_size - s->high_water;\n            zmemzero(s->window + s->high_water, (unsigned)init);\n            s->high_water += init;\n        }\n    }\n\n    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n           \"not enough room for search\");\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateInit_(z_streamp strm, int level, const char *version,\n                         int stream_size) {\n    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,\n                         Z_DEFAULT_STRATEGY, version, stream_size);\n    /* To do: ignore strm->next_in if we use it as window */\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateInit2_(z_streamp strm, int level, int method,\n                          int windowBits, int memLevel, int strategy,\n                          const char *version, int stream_size) {\n    deflate_state *s;\n    int wrap = 1;\n    static const char my_version[] = ZLIB_VERSION;\n\n    if (version == Z_NULL || version[0] != my_version[0] ||\n        stream_size != sizeof(z_stream)) {\n        return Z_VERSION_ERROR;\n    }\n    if (strm == Z_NULL) return Z_STREAM_ERROR;\n\n    strm->msg = Z_NULL;\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zfree = zcfree;\n#endif\n\n#ifdef FASTEST\n    if (level != 0) level = 1;\n#else\n    if (level == Z_DEFAULT_COMPRESSION) level = 6;\n#endif\n\n    if (windowBits < 0) { /* suppress zlib wrapper */\n        wrap = 0;\n        if (windowBits < -15)\n            return Z_STREAM_ERROR;\n        windowBits = -windowBits;\n    }\n#ifdef GZIP\n    else if (windowBits > 15) {\n        wrap = 2;       /* write gzip wrapper instead */\n        windowBits -= 16;\n    }\n#endif\n    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||\n        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||\n        strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {\n        return Z_STREAM_ERROR;\n    }\n    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */\n    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));\n    if (s == Z_NULL) return Z_MEM_ERROR;\n    zmemzero(s, sizeof(deflate_state));\n    strm->state = (struct internal_state FAR *)s;\n    s->strm = strm;\n    s->status = INIT_STATE;     /* to pass state test in deflateReset() */\n\n    s->wrap = wrap;\n    s->gzhead = Z_NULL;\n    s->w_bits = (uInt)windowBits;\n    s->w_size = 1 << s->w_bits;\n    s->w_mask = s->w_size - 1;\n\n    s->hash_bits = (uInt)memLevel + 7;\n    s->hash_size = 1 << s->hash_bits;\n    s->hash_mask = s->hash_size - 1;\n    s->hash_shift =  ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH);\n\n    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));\n    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));\n    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));\n\n    s->high_water = 0;      /* nothing written to s->window yet */\n\n    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */\n\n    /* We overlay pending_buf and sym_buf. This works since the average size\n     * for length/distance pairs over any compressed block is assured to be 31\n     * bits or less.\n     *\n     * Analysis: The longest fixed codes are a length code of 8 bits plus 5\n     * extra bits, for lengths 131 to 257. The longest fixed distance codes are\n     * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest\n     * possible fixed-codes length/distance pair is then 31 bits total.\n     *\n     * sym_buf starts one-fourth of the way into pending_buf. So there are\n     * three bytes in sym_buf for every four bytes in pending_buf. Each symbol\n     * in sym_buf is three bytes -- two for the distance and one for the\n     * literal/length. As each symbol is consumed, the pointer to the next\n     * sym_buf value to read moves forward three bytes. From that symbol, up to\n     * 31 bits are written to pending_buf. The closest the written pending_buf\n     * bits gets to the next sym_buf symbol to read is just before the last\n     * code is written. At that time, 31*(n - 2) bits have been written, just\n     * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at\n     * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1\n     * symbols are written.) The closest the writing gets to what is unread is\n     * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and\n     * can range from 128 to 32768.\n     *\n     * Therefore, at a minimum, there are 142 bits of space between what is\n     * written and what is read in the overlain buffers, so the symbols cannot\n     * be overwritten by the compressed data. That space is actually 139 bits,\n     * due to the three-bit fixed-code block header.\n     *\n     * That covers the case where either Z_FIXED is specified, forcing fixed\n     * codes, or when the use of fixed codes is chosen, because that choice\n     * results in a smaller compressed block than dynamic codes. That latter\n     * condition then assures that the above analysis also covers all dynamic\n     * blocks. A dynamic-code block will only be chosen to be emitted if it has\n     * fewer bits than a fixed-code block would for the same set of symbols.\n     * Therefore its average symbol length is assured to be less than 31. So\n     * the compressed data for a dynamic block also cannot overwrite the\n     * symbols from which it is being constructed.\n     */\n\n    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS);\n    s->pending_buf_size = (ulg)s->lit_bufsize * 4;\n\n    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||\n        s->pending_buf == Z_NULL) {\n        s->status = FINISH_STATE;\n        strm->msg = ERR_MSG(Z_MEM_ERROR);\n        deflateEnd (strm);\n        return Z_MEM_ERROR;\n    }\n#ifdef LIT_MEM\n    s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));\n    s->l_buf = s->pending_buf + (s->lit_bufsize << 2);\n    s->sym_end = s->lit_bufsize - 1;\n#else\n    s->sym_buf = s->pending_buf + s->lit_bufsize;\n    s->sym_end = (s->lit_bufsize - 1) * 3;\n#endif\n    /* We avoid equality with lit_bufsize*3 because of wraparound at 64K\n     * on 16 bit machines and because stored blocks are restricted to\n     * 64K-1 bytes.\n     */\n\n    s->level = level;\n    s->strategy = strategy;\n    s->method = (Byte)method;\n\n    return deflateReset(strm);\n}\n\n/* =========================================================================\n * Check for a valid deflate stream state. Return 0 if ok, 1 if not.\n */\nlocal int deflateStateCheck(z_streamp strm) {\n    deflate_state *s;\n    if (strm == Z_NULL ||\n        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)\n        return 1;\n    s = strm->state;\n    if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&\n#ifdef GZIP\n                                           s->status != GZIP_STATE &&\n#endif\n                                           s->status != EXTRA_STATE &&\n                                           s->status != NAME_STATE &&\n                                           s->status != COMMENT_STATE &&\n                                           s->status != HCRC_STATE &&\n                                           s->status != BUSY_STATE &&\n                                           s->status != FINISH_STATE))\n        return 1;\n    return 0;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary,\n                                 uInt  dictLength) {\n    deflate_state *s;\n    uInt str, n;\n    int wrap;\n    unsigned avail;\n    z_const unsigned char *next;\n\n    if (deflateStateCheck(strm) || dictionary == Z_NULL)\n        return Z_STREAM_ERROR;\n    s = strm->state;\n    wrap = s->wrap;\n    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)\n        return Z_STREAM_ERROR;\n\n    /* when using zlib wrappers, compute Adler-32 for provided dictionary */\n    if (wrap == 1)\n        strm->adler = adler32(strm->adler, dictionary, dictLength);\n    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */\n\n    /* if dictionary would fill window, just replace the history */\n    if (dictLength >= s->w_size) {\n        if (wrap == 0) {            /* already empty otherwise */\n            CLEAR_HASH(s);\n            s->strstart = 0;\n            s->block_start = 0L;\n            s->insert = 0;\n        }\n        dictionary += dictLength - s->w_size;  /* use the tail */\n        dictLength = s->w_size;\n    }\n\n    /* insert dictionary into window and hash */\n    avail = strm->avail_in;\n    next = strm->next_in;\n    strm->avail_in = dictLength;\n    strm->next_in = (z_const Bytef *)dictionary;\n    fill_window(s);\n    while (s->lookahead >= MIN_MATCH) {\n        str = s->strstart;\n        n = s->lookahead - (MIN_MATCH-1);\n        do {\n            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);\n#ifndef FASTEST\n            s->prev[str & s->w_mask] = s->head[s->ins_h];\n#endif\n            s->head[s->ins_h] = (Pos)str;\n            str++;\n        } while (--n);\n        s->strstart = str;\n        s->lookahead = MIN_MATCH-1;\n        fill_window(s);\n    }\n    s->strstart += s->lookahead;\n    s->block_start = (long)s->strstart;\n    s->insert = s->lookahead;\n    s->lookahead = 0;\n    s->match_length = s->prev_length = MIN_MATCH-1;\n    s->match_available = 0;\n    strm->next_in = next;\n    strm->avail_in = avail;\n    s->wrap = wrap;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary,\n                                 uInt *dictLength) {\n    deflate_state *s;\n    uInt len;\n\n    if (deflateStateCheck(strm))\n        return Z_STREAM_ERROR;\n    s = strm->state;\n    len = s->strstart + s->lookahead;\n    if (len > s->w_size)\n        len = s->w_size;\n    if (dictionary != Z_NULL && len)\n        zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);\n    if (dictLength != Z_NULL)\n        *dictLength = len;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateResetKeep(z_streamp strm) {\n    deflate_state *s;\n\n    if (deflateStateCheck(strm)) {\n        return Z_STREAM_ERROR;\n    }\n\n    strm->total_in = strm->total_out = 0;\n    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */\n    strm->data_type = Z_UNKNOWN;\n\n    s = (deflate_state *)strm->state;\n    s->pending = 0;\n    s->pending_out = s->pending_buf;\n\n    if (s->wrap < 0) {\n        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */\n    }\n    s->status =\n#ifdef GZIP\n        s->wrap == 2 ? GZIP_STATE :\n#endif\n        INIT_STATE;\n    strm->adler =\n#ifdef GZIP\n        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :\n#endif\n        adler32(0L, Z_NULL, 0);\n    s->last_flush = -2;\n\n    _tr_init(s);\n\n    return Z_OK;\n}\n\n/* ===========================================================================\n * Initialize the \"longest match\" routines for a new zlib stream\n */\nlocal void lm_init(deflate_state *s) {\n    s->window_size = (ulg)2L*s->w_size;\n\n    CLEAR_HASH(s);\n\n    /* Set the default configuration parameters:\n     */\n    s->max_lazy_match   = configuration_table[s->level].max_lazy;\n    s->good_match       = configuration_table[s->level].good_length;\n    s->nice_match       = configuration_table[s->level].nice_length;\n    s->max_chain_length = configuration_table[s->level].max_chain;\n\n    s->strstart = 0;\n    s->block_start = 0L;\n    s->lookahead = 0;\n    s->insert = 0;\n    s->match_length = s->prev_length = MIN_MATCH-1;\n    s->match_available = 0;\n    s->ins_h = 0;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateReset(z_streamp strm) {\n    int ret;\n\n    ret = deflateResetKeep(strm);\n    if (ret == Z_OK)\n        lm_init(strm->state);\n    return ret;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {\n    if (deflateStateCheck(strm) || strm->state->wrap != 2)\n        return Z_STREAM_ERROR;\n    strm->state->gzhead = head;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n    if (bits != Z_NULL)\n        *bits = strm->state->bi_valid;\n    if (pending != Z_NULL) {\n        *pending = (unsigned)strm->state->pending;\n        if (*pending != strm->state->pending) {\n            *pending = (unsigned)-1;\n            return Z_BUF_ERROR;\n        }\n    }\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateUsed(z_streamp strm, int *bits) {\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n    if (bits != Z_NULL)\n        *bits = strm->state->bi_used;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {\n    deflate_state *s;\n    int put;\n\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n    s = strm->state;\n#ifdef LIT_MEM\n    if (bits < 0 || bits > 16 ||\n        (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))\n        return Z_BUF_ERROR;\n#else\n    if (bits < 0 || bits > 16 ||\n        s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))\n        return Z_BUF_ERROR;\n#endif\n    do {\n        put = Buf_size - s->bi_valid;\n        if (put > bits)\n            put = bits;\n        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);\n        s->bi_valid += put;\n        _tr_flush_bits(s);\n        value >>= put;\n        bits -= put;\n    } while (bits);\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateParams(z_streamp strm, int level, int strategy) {\n    deflate_state *s;\n    compress_func func;\n\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n    s = strm->state;\n\n#ifdef FASTEST\n    if (level != 0) level = 1;\n#else\n    if (level == Z_DEFAULT_COMPRESSION) level = 6;\n#endif\n    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {\n        return Z_STREAM_ERROR;\n    }\n    func = configuration_table[s->level].func;\n\n    if ((strategy != s->strategy || func != configuration_table[level].func) &&\n        s->last_flush != -2) {\n        /* Flush the last buffer: */\n        int err = deflate(strm, Z_BLOCK);\n        if (err == Z_STREAM_ERROR)\n            return err;\n        if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)\n            return Z_BUF_ERROR;\n    }\n    if (s->level != level) {\n        if (s->level == 0 && s->matches != 0) {\n            if (s->matches == 1)\n                slide_hash(s);\n            else\n                CLEAR_HASH(s);\n            s->matches = 0;\n        }\n        s->level = level;\n        s->max_lazy_match   = configuration_table[level].max_lazy;\n        s->good_match       = configuration_table[level].good_length;\n        s->nice_match       = configuration_table[level].nice_length;\n        s->max_chain_length = configuration_table[level].max_chain;\n    }\n    s->strategy = strategy;\n    return Z_OK;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy,\n                        int nice_length, int max_chain) {\n    deflate_state *s;\n\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n    s = strm->state;\n    s->good_match = (uInt)good_length;\n    s->max_lazy_match = (uInt)max_lazy;\n    s->nice_match = nice_length;\n    s->max_chain_length = (uInt)max_chain;\n    return Z_OK;\n}\n\n/* =========================================================================\n * For the default windowBits of 15 and memLevel of 8, this function returns a\n * close to exact, as well as small, upper bound on the compressed size. This\n * is an expansion of ~0.03%, plus a small constant.\n *\n * For any setting other than those defaults for windowBits and memLevel, one\n * of two worst case bounds is returned. This is at most an expansion of ~4% or\n * ~13%, plus a small constant.\n *\n * Both the 0.03% and 4% derive from the overhead of stored blocks. The first\n * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second\n * is for stored blocks of 127 bytes (the worst case memLevel == 1). The\n * expansion results from five bytes of header for each stored block.\n *\n * The larger expansion of 13% results from a window size less than or equal to\n * the symbols buffer size (windowBits <= memLevel + 7). In that case some of\n * the data being compressed may have slid out of the sliding window, impeding\n * a stored block from being emitted. Then the only choice is a fixed or\n * dynamic block, where a fixed block limits the maximum expansion to 9 bits\n * per 8-bit byte, plus 10 bits for every block. The smallest block size for\n * which this can occur is 255 (memLevel == 2).\n *\n * Shifts are used to approximate divisions, for speed.\n */\nz_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) {\n    deflate_state *s;\n    z_size_t fixedlen, storelen, wraplen, bound;\n\n    /* upper bound for fixed blocks with 9-bit literals and length 255\n       (memLevel == 2, which is the lowest that may not use stored blocks) --\n       ~13% overhead plus a small constant */\n    fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) +\n               (sourceLen >> 9) + 4;\n    if (fixedlen < sourceLen)\n        fixedlen = (z_size_t)-1;\n\n    /* upper bound for stored blocks with length 127 (memLevel == 1) --\n       ~4% overhead plus a small constant */\n    storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) +\n               (sourceLen >> 11) + 7;\n    if (storelen < sourceLen)\n        storelen = (z_size_t)-1;\n\n    /* if can't get parameters, return larger bound plus a wrapper */\n    if (deflateStateCheck(strm)) {\n        bound = fixedlen > storelen ? fixedlen : storelen;\n        return bound + 18 < bound ? (z_size_t)-1 : bound + 18;\n    }\n\n    /* compute wrapper length */\n    s = strm->state;\n    switch (s->wrap < 0 ? -s->wrap : s->wrap) {\n    case 0:                                 /* raw deflate */\n        wraplen = 0;\n        break;\n    case 1:                                 /* zlib wrapper */\n        wraplen = 6 + (s->strstart ? 4 : 0);\n        break;\n#ifdef GZIP\n    case 2:                                 /* gzip wrapper */\n        wraplen = 18;\n        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */\n            Bytef *str;\n            if (s->gzhead->extra != Z_NULL)\n                wraplen += 2 + s->gzhead->extra_len;\n            str = s->gzhead->name;\n            if (str != Z_NULL)\n                do {\n                    wraplen++;\n                } while (*str++);\n            str = s->gzhead->comment;\n            if (str != Z_NULL)\n                do {\n                    wraplen++;\n                } while (*str++);\n            if (s->gzhead->hcrc)\n                wraplen += 2;\n        }\n        break;\n#endif\n    default:                                /* for compiler happiness */\n        wraplen = 18;\n    }\n\n    /* if not default parameters, return one of the conservative bounds */\n    if (s->w_bits != 15 || s->hash_bits != 8 + 7) {\n        bound = s->w_bits <= s->hash_bits && s->level ? fixedlen :\n                                                        storelen;\n        return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen;\n    }\n\n    /* default settings: return tight bound for that case -- ~0.03% overhead\n       plus a small constant */\n    bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +\n            (sourceLen >> 25) + 13 - 6 + wraplen;\n    return bound < sourceLen ? (z_size_t)-1 : bound;\n}\nuLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {\n    z_size_t bound = deflateBound_z(strm, sourceLen);\n    return (uLong)bound != bound ? (uLong)-1 : (uLong)bound;\n}\n\n/* =========================================================================\n * Put a short in the pending buffer. The 16-bit value is put in MSB order.\n * IN assertion: the stream state is correct and there is enough room in\n * pending_buf.\n */\nlocal void putShortMSB(deflate_state *s, uInt b) {\n    put_byte(s, (Byte)(b >> 8));\n    put_byte(s, (Byte)(b & 0xff));\n}\n\n/* =========================================================================\n * Flush as much pending output as possible. All deflate() output, except for\n * some deflate_stored() output, goes through this function so some\n * applications may wish to modify it to avoid allocating a large\n * strm->next_out buffer and copying into it. (See also read_buf()).\n */\nlocal void flush_pending(z_streamp strm) {\n    unsigned len;\n    deflate_state *s = strm->state;\n\n    _tr_flush_bits(s);\n    len = s->pending > strm->avail_out ? strm->avail_out :\n                                         (unsigned)s->pending;\n    if (len == 0) return;\n\n    zmemcpy(strm->next_out, s->pending_out, len);\n    strm->next_out  += len;\n    s->pending_out  += len;\n    strm->total_out += len;\n    strm->avail_out -= len;\n    s->pending      -= len;\n    if (s->pending == 0) {\n        s->pending_out = s->pending_buf;\n    }\n}\n\n/* ===========================================================================\n * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].\n */\n#define HCRC_UPDATE(beg) \\\n    do { \\\n        if (s->gzhead->hcrc && s->pending > (beg)) \\\n            strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \\\n                                  s->pending - (beg)); \\\n    } while (0)\n\n/* ========================================================================= */\nint ZEXPORT deflate(z_streamp strm, int flush) {\n    int old_flush; /* value of flush param for previous deflate call */\n    deflate_state *s;\n\n    if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {\n        return Z_STREAM_ERROR;\n    }\n    s = strm->state;\n\n    if (strm->next_out == Z_NULL ||\n        (strm->avail_in != 0 && strm->next_in == Z_NULL) ||\n        (s->status == FINISH_STATE && flush != Z_FINISH)) {\n        ERR_RETURN(strm, Z_STREAM_ERROR);\n    }\n    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);\n\n    old_flush = s->last_flush;\n    s->last_flush = flush;\n\n    /* Flush as much pending output as possible */\n    if (s->pending != 0) {\n        flush_pending(strm);\n        if (strm->avail_out == 0) {\n            /* Since avail_out is 0, deflate will be called again with\n             * more output space, but possibly with both pending and\n             * avail_in equal to zero. There won't be anything to do,\n             * but this is not an error situation so make sure we\n             * return OK instead of BUF_ERROR at next call of deflate:\n             */\n            s->last_flush = -1;\n            return Z_OK;\n        }\n\n    /* Make sure there is something to do and avoid duplicate consecutive\n     * flushes. For repeated and useless calls with Z_FINISH, we keep\n     * returning Z_STREAM_END instead of Z_BUF_ERROR.\n     */\n    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&\n               flush != Z_FINISH) {\n        ERR_RETURN(strm, Z_BUF_ERROR);\n    }\n\n    /* User must not provide more input after the first FINISH: */\n    if (s->status == FINISH_STATE && strm->avail_in != 0) {\n        ERR_RETURN(strm, Z_BUF_ERROR);\n    }\n\n    /* Write the header */\n    if (s->status == INIT_STATE && s->wrap == 0)\n        s->status = BUSY_STATE;\n    if (s->status == INIT_STATE) {\n        /* zlib header */\n        uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8;\n        uInt level_flags;\n\n        if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)\n            level_flags = 0;\n        else if (s->level < 6)\n            level_flags = 1;\n        else if (s->level == 6)\n            level_flags = 2;\n        else\n            level_flags = 3;\n        header |= (level_flags << 6);\n        if (s->strstart != 0) header |= PRESET_DICT;\n        header += 31 - (header % 31);\n\n        putShortMSB(s, header);\n\n        /* Save the adler32 of the preset dictionary: */\n        if (s->strstart != 0) {\n            putShortMSB(s, (uInt)(strm->adler >> 16));\n            putShortMSB(s, (uInt)(strm->adler & 0xffff));\n        }\n        strm->adler = adler32(0L, Z_NULL, 0);\n        s->status = BUSY_STATE;\n\n        /* Compression must start with an empty pending buffer */\n        flush_pending(strm);\n        if (s->pending != 0) {\n            s->last_flush = -1;\n            return Z_OK;\n        }\n    }\n#ifdef GZIP\n    if (s->status == GZIP_STATE) {\n        /* gzip header */\n        strm->adler = crc32(0L, Z_NULL, 0);\n        put_byte(s, 31);\n        put_byte(s, 139);\n        put_byte(s, 8);\n        if (s->gzhead == Z_NULL) {\n            put_byte(s, 0);\n            put_byte(s, 0);\n            put_byte(s, 0);\n            put_byte(s, 0);\n            put_byte(s, 0);\n            put_byte(s, s->level == 9 ? 2 :\n                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?\n                      4 : 0));\n            put_byte(s, OS_CODE);\n            s->status = BUSY_STATE;\n\n            /* Compression must start with an empty pending buffer */\n            flush_pending(strm);\n            if (s->pending != 0) {\n                s->last_flush = -1;\n                return Z_OK;\n            }\n        }\n        else {\n            put_byte(s, (s->gzhead->text ? 1 : 0) +\n                     (s->gzhead->hcrc ? 2 : 0) +\n                     (s->gzhead->extra == Z_NULL ? 0 : 4) +\n                     (s->gzhead->name == Z_NULL ? 0 : 8) +\n                     (s->gzhead->comment == Z_NULL ? 0 : 16)\n                     );\n            put_byte(s, (Byte)(s->gzhead->time & 0xff));\n            put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));\n            put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));\n            put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));\n            put_byte(s, s->level == 9 ? 2 :\n                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?\n                      4 : 0));\n            put_byte(s, s->gzhead->os & 0xff);\n            if (s->gzhead->extra != Z_NULL) {\n                put_byte(s, s->gzhead->extra_len & 0xff);\n                put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);\n            }\n            if (s->gzhead->hcrc)\n                strm->adler = crc32_z(strm->adler, s->pending_buf,\n                                      s->pending);\n            s->gzindex = 0;\n            s->status = EXTRA_STATE;\n        }\n    }\n    if (s->status == EXTRA_STATE) {\n        if (s->gzhead->extra != Z_NULL) {\n            ulg beg = s->pending;   /* start of bytes to update crc */\n            ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex;\n            while (s->pending + left > s->pending_buf_size) {\n                ulg copy = s->pending_buf_size - s->pending;\n                zmemcpy(s->pending_buf + s->pending,\n                        s->gzhead->extra + s->gzindex, copy);\n                s->pending = s->pending_buf_size;\n                HCRC_UPDATE(beg);\n                s->gzindex += copy;\n                flush_pending(strm);\n                if (s->pending != 0) {\n                    s->last_flush = -1;\n                    return Z_OK;\n                }\n                beg = 0;\n                left -= copy;\n            }\n            zmemcpy(s->pending_buf + s->pending,\n                    s->gzhead->extra + s->gzindex, left);\n            s->pending += left;\n            HCRC_UPDATE(beg);\n            s->gzindex = 0;\n        }\n        s->status = NAME_STATE;\n    }\n    if (s->status == NAME_STATE) {\n        if (s->gzhead->name != Z_NULL) {\n            ulg beg = s->pending;   /* start of bytes to update crc */\n            int val;\n            do {\n                if (s->pending == s->pending_buf_size) {\n                    HCRC_UPDATE(beg);\n                    flush_pending(strm);\n                    if (s->pending != 0) {\n                        s->last_flush = -1;\n                        return Z_OK;\n                    }\n                    beg = 0;\n                }\n                val = s->gzhead->name[s->gzindex++];\n                put_byte(s, val);\n            } while (val != 0);\n            HCRC_UPDATE(beg);\n            s->gzindex = 0;\n        }\n        s->status = COMMENT_STATE;\n    }\n    if (s->status == COMMENT_STATE) {\n        if (s->gzhead->comment != Z_NULL) {\n            ulg beg = s->pending;   /* start of bytes to update crc */\n            int val;\n            do {\n                if (s->pending == s->pending_buf_size) {\n                    HCRC_UPDATE(beg);\n                    flush_pending(strm);\n                    if (s->pending != 0) {\n                        s->last_flush = -1;\n                        return Z_OK;\n                    }\n                    beg = 0;\n                }\n                val = s->gzhead->comment[s->gzindex++];\n                put_byte(s, val);\n            } while (val != 0);\n            HCRC_UPDATE(beg);\n        }\n        s->status = HCRC_STATE;\n    }\n    if (s->status == HCRC_STATE) {\n        if (s->gzhead->hcrc) {\n            if (s->pending + 2 > s->pending_buf_size) {\n                flush_pending(strm);\n                if (s->pending != 0) {\n                    s->last_flush = -1;\n                    return Z_OK;\n                }\n            }\n            put_byte(s, (Byte)(strm->adler & 0xff));\n            put_byte(s, (Byte)((strm->adler >> 8) & 0xff));\n            strm->adler = crc32(0L, Z_NULL, 0);\n        }\n        s->status = BUSY_STATE;\n\n        /* Compression must start with an empty pending buffer */\n        flush_pending(strm);\n        if (s->pending != 0) {\n            s->last_flush = -1;\n            return Z_OK;\n        }\n    }\n#endif\n\n    /* Start a new block or continue the current one.\n     */\n    if (strm->avail_in != 0 || s->lookahead != 0 ||\n        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {\n        block_state bstate;\n\n        bstate = s->level == 0 ? deflate_stored(s, flush) :\n                 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :\n                 s->strategy == Z_RLE ? deflate_rle(s, flush) :\n                 (*(configuration_table[s->level].func))(s, flush);\n\n        if (bstate == finish_started || bstate == finish_done) {\n            s->status = FINISH_STATE;\n        }\n        if (bstate == need_more || bstate == finish_started) {\n            if (strm->avail_out == 0) {\n                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */\n            }\n            return Z_OK;\n            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call\n             * of deflate should use the same flush parameter to make sure\n             * that the flush is complete. So we don't have to output an\n             * empty block here, this will be done at next call. This also\n             * ensures that for a very small output buffer, we emit at most\n             * one empty block.\n             */\n        }\n        if (bstate == block_done) {\n            if (flush == Z_PARTIAL_FLUSH) {\n                _tr_align(s);\n            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */\n                _tr_stored_block(s, (char*)0, 0L, 0);\n                /* For a full flush, this empty block will be recognized\n                 * as a special marker by inflate_sync().\n                 */\n                if (flush == Z_FULL_FLUSH) {\n                    CLEAR_HASH(s);             /* forget history */\n                    if (s->lookahead == 0) {\n                        s->strstart = 0;\n                        s->block_start = 0L;\n                        s->insert = 0;\n                    }\n                }\n            }\n            flush_pending(strm);\n            if (strm->avail_out == 0) {\n              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */\n              return Z_OK;\n            }\n        }\n    }\n\n    if (flush != Z_FINISH) return Z_OK;\n    if (s->wrap <= 0) return Z_STREAM_END;\n\n    /* Write the trailer */\n#ifdef GZIP\n    if (s->wrap == 2) {\n        put_byte(s, (Byte)(strm->adler & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));\n        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));\n        put_byte(s, (Byte)(strm->total_in & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));\n        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));\n    }\n    else\n#endif\n    {\n        putShortMSB(s, (uInt)(strm->adler >> 16));\n        putShortMSB(s, (uInt)(strm->adler & 0xffff));\n    }\n    flush_pending(strm);\n    /* If avail_out is zero, the application will call deflate again\n     * to flush the rest.\n     */\n    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */\n    return s->pending != 0 ? Z_OK : Z_STREAM_END;\n}\n\n/* ========================================================================= */\nint ZEXPORT deflateEnd(z_streamp strm) {\n    int status;\n\n    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;\n\n    status = strm->state->status;\n\n    /* Deallocate in reverse order of allocations: */\n    TRY_FREE(strm, strm->state->pending_buf);\n    TRY_FREE(strm, strm->state->head);\n    TRY_FREE(strm, strm->state->prev);\n    TRY_FREE(strm, strm->state->window);\n\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n\n    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;\n}\n\n/* =========================================================================\n * Copy the source state to the destination state.\n * To simplify the source, this is not supported for 16-bit MSDOS (which\n * doesn't have enough memory anyway to duplicate compression states).\n */\nint ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {\n#ifdef MAXSEG_64K\n    (void)dest;\n    (void)source;\n    return Z_STREAM_ERROR;\n#else\n    deflate_state *ds;\n    deflate_state *ss;\n\n\n    if (deflateStateCheck(source) || dest == Z_NULL) {\n        return Z_STREAM_ERROR;\n    }\n\n    ss = source->state;\n\n    zmemcpy(dest, source, sizeof(z_stream));\n\n    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));\n    if (ds == Z_NULL) return Z_MEM_ERROR;\n    zmemzero(ds, sizeof(deflate_state));\n    dest->state = (struct internal_state FAR *) ds;\n    zmemcpy(ds, ss, sizeof(deflate_state));\n    ds->strm = dest;\n\n    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));\n    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));\n    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));\n    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS);\n\n    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||\n        ds->pending_buf == Z_NULL) {\n        deflateEnd (dest);\n        return Z_MEM_ERROR;\n    }\n    /* following zmemcpy's do not work for 16-bit MSDOS */\n    zmemcpy(ds->window, ss->window, ss->high_water);\n    zmemcpy(ds->prev, ss->prev,\n            (ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size :\n                ss->strstart - ss->insert) * sizeof(Pos));\n    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));\n\n    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);\n    zmemcpy(ds->pending_out, ss->pending_out, ss->pending);\n#ifdef LIT_MEM\n    ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));\n    ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);\n    zmemcpy(ds->d_buf, ss->d_buf, ss->sym_next * sizeof(ush));\n    zmemcpy(ds->l_buf, ss->l_buf, ss->sym_next);\n#else\n    ds->sym_buf = ds->pending_buf + ds->lit_bufsize;\n    zmemcpy(ds->sym_buf, ss->sym_buf, ss->sym_next);\n#endif\n\n    ds->l_desc.dyn_tree = ds->dyn_ltree;\n    ds->d_desc.dyn_tree = ds->dyn_dtree;\n    ds->bl_desc.dyn_tree = ds->bl_tree;\n\n    return Z_OK;\n#endif /* MAXSEG_64K */\n}\n\n#ifndef FASTEST\n/* ===========================================================================\n * Set match_start to the longest match starting at the given string and\n * return its length. Matches shorter or equal to prev_length are discarded,\n * in which case the result is equal to prev_length and match_start is\n * garbage.\n * IN assertions: cur_match is the head of the hash chain for the current\n *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n * OUT assertion: the match length is not greater than s->lookahead.\n */\nlocal uInt longest_match(deflate_state *s, IPos cur_match) {\n    unsigned chain_length = s->max_chain_length;/* max hash chain length */\n    Bytef *scan = s->window + s->strstart;      /* current string */\n    Bytef *match;                               /* matched string */\n    int len;                                    /* length of current match */\n    int best_len = (int)s->prev_length;         /* best match length so far */\n    int nice_match = s->nice_match;             /* stop if match long enough */\n    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?\n        s->strstart - (IPos)MAX_DIST(s) : NIL;\n    /* Stop when cur_match becomes <= limit. To simplify the code,\n     * we prevent matches with the string of window index 0.\n     */\n    Posf *prev = s->prev;\n    uInt wmask = s->w_mask;\n\n#ifdef UNALIGNED_OK\n    /* Compare two bytes at a time. Note: this is not always beneficial.\n     * Try with and without -DUNALIGNED_OK to check.\n     */\n    Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;\n    ush scan_start = *(ushf*)scan;\n    ush scan_end   = *(ushf*)(scan + best_len - 1);\n#else\n    Bytef *strend = s->window + s->strstart + MAX_MATCH;\n    Byte scan_end1  = scan[best_len - 1];\n    Byte scan_end   = scan[best_len];\n#endif\n\n    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n     * It is easy to get rid of this optimization if necessary.\n     */\n    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n    /* Do not waste too much time if we already have a good match: */\n    if (s->prev_length >= s->good_match) {\n        chain_length >>= 2;\n    }\n    /* Do not look for matches beyond the end of the input. This is necessary\n     * to make deflate deterministic.\n     */\n    if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;\n\n    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n           \"need lookahead\");\n\n    do {\n        Assert(cur_match < s->strstart, \"no future\");\n        match = s->window + cur_match;\n\n        /* Skip to next match if the match length cannot increase\n         * or if the match length is less than 2.  Note that the checks below\n         * for insufficient lookahead only occur occasionally for performance\n         * reasons.  Therefore uninitialized memory will be accessed, and\n         * conditional jumps will be made that depend on those values.\n         * However the length of the match is limited to the lookahead, so\n         * the output of deflate is not affected by the uninitialized values.\n         */\n#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)\n        /* This code assumes sizeof(unsigned short) == 2. Do not use\n         * UNALIGNED_OK if your compiler uses a different size.\n         */\n        if (*(ushf*)(match + best_len - 1) != scan_end ||\n            *(ushf*)match != scan_start) continue;\n\n        /* It is not necessary to compare scan[2] and match[2] since they are\n         * always equal when the other bytes match, given that the hash keys\n         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at\n         * strstart + 3, + 5, up to strstart + 257. We check for insufficient\n         * lookahead only every 4th comparison; the 128th check will be made\n         * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is\n         * necessary to put more guard bytes at the end of the window, or\n         * to check more often for insufficient lookahead.\n         */\n        Assert(scan[2] == match[2], \"scan[2]?\");\n        scan++, match++;\n        do {\n        } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&\n                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&\n                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&\n                 *(ushf*)(scan += 2) == *(ushf*)(match += 2) &&\n                 scan < strend);\n        /* The funny \"do {}\" generates better code on most compilers */\n\n        /* Here, scan <= window + strstart + 257 */\n        Assert(scan <= s->window + (unsigned)(s->window_size - 1),\n               \"wild scan\");\n        if (*scan == *match) scan++;\n\n        len = (MAX_MATCH - 1) - (int)(strend - scan);\n        scan = strend - (MAX_MATCH-1);\n\n#else /* UNALIGNED_OK */\n\n        if (match[best_len]     != scan_end  ||\n            match[best_len - 1] != scan_end1 ||\n            *match              != *scan     ||\n            *++match            != scan[1])      continue;\n\n        /* The check at best_len - 1 can be removed because it will be made\n         * again later. (This heuristic is not always a win.)\n         * It is not necessary to compare scan[2] and match[2] since they\n         * are always equal when the other bytes match, given that\n         * the hash keys are equal and that HASH_BITS >= 8.\n         */\n        scan += 2, match++;\n        Assert(*scan == *match, \"match[2]?\");\n\n        /* We check for insufficient lookahead only every 8th comparison;\n         * the 256th check will be made at strstart + 258.\n         */\n        do {\n        } while (*++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 *++scan == *++match && *++scan == *++match &&\n                 scan < strend);\n\n        Assert(scan <= s->window + (unsigned)(s->window_size - 1),\n               \"wild scan\");\n\n        len = MAX_MATCH - (int)(strend - scan);\n        scan = strend - MAX_MATCH;\n\n#endif /* UNALIGNED_OK */\n\n        if (len > best_len) {\n            s->match_start = cur_match;\n            best_len = len;\n            if (len >= nice_match) break;\n#ifdef UNALIGNED_OK\n            scan_end = *(ushf*)(scan + best_len - 1);\n#else\n            scan_end1  = scan[best_len - 1];\n            scan_end   = scan[best_len];\n#endif\n        }\n    } while ((cur_match = prev[cur_match & wmask]) > limit\n             && --chain_length != 0);\n\n    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;\n    return s->lookahead;\n}\n\n#else /* FASTEST */\n\n/* ---------------------------------------------------------------------------\n * Optimized version for FASTEST only\n */\nlocal uInt longest_match(deflate_state *s, IPos cur_match) {\n    Bytef *scan = s->window + s->strstart;      /* current string */\n    Bytef *match;                               /* matched string */\n    int len;                                    /* length of current match */\n    Bytef *strend = s->window + s->strstart + MAX_MATCH;\n\n    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n     * It is easy to get rid of this optimization if necessary.\n     */\n    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n           \"need lookahead\");\n\n    Assert(cur_match < s->strstart, \"no future\");\n\n    match = s->window + cur_match;\n\n    /* Return failure if the match length is less than 2:\n     */\n    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;\n\n    /* The check at best_len - 1 can be removed because it will be made\n     * again later. (This heuristic is not always a win.)\n     * It is not necessary to compare scan[2] and match[2] since they\n     * are always equal when the other bytes match, given that\n     * the hash keys are equal and that HASH_BITS >= 8.\n     */\n    scan += 2, match += 2;\n    Assert(*scan == *match, \"match[2]?\");\n\n    /* We check for insufficient lookahead only every 8th comparison;\n     * the 256th check will be made at strstart + 258.\n     */\n    do {\n    } while (*++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             *++scan == *++match && *++scan == *++match &&\n             scan < strend);\n\n    Assert(scan <= s->window + (unsigned)(s->window_size - 1), \"wild scan\");\n\n    len = MAX_MATCH - (int)(strend - scan);\n\n    if (len < MIN_MATCH) return MIN_MATCH - 1;\n\n    s->match_start = cur_match;\n    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;\n}\n\n#endif /* FASTEST */\n\n#ifdef ZLIB_DEBUG\n\n#define EQUAL 0\n/* result of memcmp for equal strings */\n\n/* ===========================================================================\n * Check that the match at match_start is indeed a match.\n */\nlocal void check_match(deflate_state *s, IPos start, IPos match, int length) {\n    /* check that the match is indeed a match */\n    Bytef *back = s->window + (int)match, *here = s->window + start;\n    IPos len = (IPos)length;\n    if (match == (IPos)-1) {\n        /* match starts one byte before the current window -- just compare the\n           subsequent length-1 bytes */\n        back++;\n        here++;\n        len--;\n    }\n    if (zmemcmp(back, here, len) != EQUAL) {\n        fprintf(stderr, \" start %u, match %d, length %d\\n\",\n                start, (int)match, length);\n        do {\n            fprintf(stderr, \"(%02x %02x)\", *back++, *here++);\n        } while (--len != 0);\n        z_error(\"invalid match\");\n    }\n    if (z_verbose > 1) {\n        fprintf(stderr,\"\\\\[%d,%d]\", start - match, length);\n        do { putc(s->window[start++], stderr); } while (--length != 0);\n    }\n}\n#else\n#  define check_match(s, start, match, length)\n#endif /* ZLIB_DEBUG */\n\n/* ===========================================================================\n * Flush the current block, with given end-of-file flag.\n * IN assertion: strstart is set to the end of the current match.\n */\n#define FLUSH_BLOCK_ONLY(s, last) { \\\n   _tr_flush_block(s, (s->block_start >= 0L ? \\\n                   (charf *)&s->window[(unsigned)s->block_start] : \\\n                   (charf *)Z_NULL), \\\n                (ulg)((long)s->strstart - s->block_start), \\\n                (last)); \\\n   s->block_start = s->strstart; \\\n   flush_pending(s->strm); \\\n   Tracev((stderr,\"[FLUSH]\")); \\\n}\n\n/* Same but force premature exit if necessary. */\n#define FLUSH_BLOCK(s, last) { \\\n   FLUSH_BLOCK_ONLY(s, last); \\\n   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \\\n}\n\n/* Maximum stored block length in deflate format (not including header). */\n#define MAX_STORED 65535\n\n/* Minimum of a and b. */\n#define MIN(a, b) ((a) > (b) ? (b) : (a))\n\n/* ===========================================================================\n * Copy without compression as much as possible from the input stream, return\n * the current block state.\n *\n * In case deflateParams() is used to later switch to a non-zero compression\n * level, s->matches (otherwise unused when storing) keeps track of the number\n * of hash table slides to perform. If s->matches is 1, then one hash table\n * slide will be done when switching. If s->matches is 2, the maximum value\n * allowed here, then the hash table will be cleared, since two or more slides\n * is the same as a clear.\n *\n * deflate_stored() is written to minimize the number of times an input byte is\n * copied. It is most efficient with large input and output buffers, which\n * maximizes the opportunities to have a single copy from next_in to next_out.\n */\nlocal block_state deflate_stored(deflate_state *s, int flush) {\n    /* Smallest worthy block size when not flushing or finishing. By default\n     * this is 32K. This can be as small as 507 bytes for memLevel == 1. For\n     * large input and output buffers, the stored block size will be larger.\n     */\n    unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size));\n\n    /* Copy as many min_block or larger stored blocks directly to next_out as\n     * possible. If flushing, copy the remaining available input to next_out as\n     * stored blocks, if there is enough space.\n     */\n    int last = 0;\n    unsigned len, left, have;\n    unsigned used = s->strm->avail_in;\n    do {\n        /* Set len to the maximum size block that we can copy directly with the\n         * available input data and output space. Set left to how much of that\n         * would be copied from what's left in the window.\n         */\n        len = MAX_STORED;       /* maximum deflate stored block length */\n        have = ((unsigned)s->bi_valid + 42) >> 3;   /* bytes in header */\n        if (s->strm->avail_out < have)          /* need room for header */\n            break;\n            /* maximum stored block length that will fit in avail_out: */\n        have = s->strm->avail_out - have;\n        left = (unsigned)(s->strstart - s->block_start);    /* window bytes */\n        if (len > (ulg)left + s->strm->avail_in)\n            len = left + s->strm->avail_in;     /* limit len to the input */\n        if (len > have)\n            len = have;                         /* limit len to the output */\n\n        /* If the stored block would be less than min_block in length, or if\n         * unable to copy all of the available input when flushing, then try\n         * copying to the window and the pending buffer instead. Also don't\n         * write an empty block when flushing -- deflate() does that.\n         */\n        if (len < min_block && ((len == 0 && flush != Z_FINISH) ||\n                                flush == Z_NO_FLUSH ||\n                                len != left + s->strm->avail_in))\n            break;\n\n        /* Make a dummy stored block in pending to get the header bytes,\n         * including any pending bits. This also updates the debugging counts.\n         */\n        last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;\n        _tr_stored_block(s, (char *)0, 0L, last);\n\n        /* Replace the lengths in the dummy stored block with len. */\n        s->pending_buf[s->pending - 4] = (Bytef)len;\n        s->pending_buf[s->pending - 3] = (Bytef)(len >> 8);\n        s->pending_buf[s->pending - 2] = (Bytef)~len;\n        s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8);\n\n        /* Write the stored block header bytes. */\n        flush_pending(s->strm);\n\n#ifdef ZLIB_DEBUG\n        /* Update debugging counts for the data about to be copied. */\n        s->compressed_len += len << 3;\n        s->bits_sent += len << 3;\n#endif\n\n        /* Copy uncompressed bytes from the window to next_out. */\n        if (left) {\n            if (left > len)\n                left = len;\n            zmemcpy(s->strm->next_out, s->window + s->block_start, left);\n            s->strm->next_out += left;\n            s->strm->avail_out -= left;\n            s->strm->total_out += left;\n            s->block_start += left;\n            len -= left;\n        }\n\n        /* Copy uncompressed bytes directly from next_in to next_out, updating\n         * the check value.\n         */\n        if (len) {\n            read_buf(s->strm, s->strm->next_out, len);\n            s->strm->next_out += len;\n            s->strm->avail_out -= len;\n            s->strm->total_out += len;\n        }\n    } while (last == 0);\n\n    /* Update the sliding window with the last s->w_size bytes of the copied\n     * data, or append all of the copied data to the existing window if less\n     * than s->w_size bytes were copied. Also update the number of bytes to\n     * insert in the hash tables, in the event that deflateParams() switches to\n     * a non-zero compression level.\n     */\n    used -= s->strm->avail_in;      /* number of input bytes directly copied */\n    if (used) {\n        /* If any input was used, then no unused input remains in the window,\n         * therefore s->block_start == s->strstart.\n         */\n        if (used >= s->w_size) {    /* supplant the previous history */\n            s->matches = 2;         /* clear hash */\n            zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);\n            s->strstart = s->w_size;\n            s->insert = s->strstart;\n        }\n        else {\n            if (s->window_size - s->strstart <= used) {\n                /* Slide the window down. */\n                s->strstart -= s->w_size;\n                zmemcpy(s->window, s->window + s->w_size, s->strstart);\n                if (s->matches < 2)\n                    s->matches++;   /* add a pending slide_hash() */\n                if (s->insert > s->strstart)\n                    s->insert = s->strstart;\n            }\n            zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);\n            s->strstart += used;\n            s->insert += MIN(used, s->w_size - s->insert);\n        }\n        s->block_start = s->strstart;\n    }\n    if (s->high_water < s->strstart)\n        s->high_water = s->strstart;\n\n    /* If the last block was written to next_out, then done. */\n    if (last) {\n        s->bi_used = 8;\n        return finish_done;\n    }\n\n    /* If flushing and all input has been consumed, then done. */\n    if (flush != Z_NO_FLUSH && flush != Z_FINISH &&\n        s->strm->avail_in == 0 && (long)s->strstart == s->block_start)\n        return block_done;\n\n    /* Fill the window with any remaining input. */\n    have = (unsigned)(s->window_size - s->strstart);\n    if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {\n        /* Slide the window down. */\n        s->block_start -= s->w_size;\n        s->strstart -= s->w_size;\n        zmemcpy(s->window, s->window + s->w_size, s->strstart);\n        if (s->matches < 2)\n            s->matches++;           /* add a pending slide_hash() */\n        have += s->w_size;          /* more space now */\n        if (s->insert > s->strstart)\n            s->insert = s->strstart;\n    }\n    if (have > s->strm->avail_in)\n        have = s->strm->avail_in;\n    if (have) {\n        read_buf(s->strm, s->window + s->strstart, have);\n        s->strstart += have;\n        s->insert += MIN(have, s->w_size - s->insert);\n    }\n    if (s->high_water < s->strstart)\n        s->high_water = s->strstart;\n\n    /* There was not enough avail_out to write a complete worthy or flushed\n     * stored block to next_out. Write a stored block to pending instead, if we\n     * have enough input for a worthy block, or if flushing and there is enough\n     * room for the remaining input as a stored block in the pending buffer.\n     */\n    have = ((unsigned)s->bi_valid + 42) >> 3;   /* bytes in header */\n        /* maximum stored block length that will fit in pending: */\n    have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED);\n    min_block = MIN(have, s->w_size);\n    left = (unsigned)(s->strstart - s->block_start);\n    if (left >= min_block ||\n        ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&\n         s->strm->avail_in == 0 && left <= have)) {\n        len = MIN(left, have);\n        last = flush == Z_FINISH && s->strm->avail_in == 0 &&\n               len == left ? 1 : 0;\n        _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);\n        s->block_start += len;\n        flush_pending(s->strm);\n    }\n\n    /* We've done all we can with the available input and output. */\n    if (last)\n        s->bi_used = 8;\n    return last ? finish_started : need_more;\n}\n\n/* ===========================================================================\n * Compress as much as possible from the input stream, return the current\n * block state.\n * This function does not perform lazy evaluation of matches and inserts\n * new strings in the dictionary only for unmatched strings or for short\n * matches. It is used only for the fast compression options.\n */\nlocal block_state deflate_fast(deflate_state *s, int flush) {\n    IPos hash_head;       /* head of the hash chain */\n    int bflush;           /* set if current block must be flushed */\n\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the next match, plus MIN_MATCH bytes to insert the\n         * string following the next match.\n         */\n        if (s->lookahead < MIN_LOOKAHEAD) {\n            fill_window(s);\n            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* Insert the string window[strstart .. strstart + 2] in the\n         * dictionary, and set hash_head to the head of the hash chain:\n         */\n        hash_head = NIL;\n        if (s->lookahead >= MIN_MATCH) {\n            INSERT_STRING(s, s->strstart, hash_head);\n        }\n\n        /* Find the longest match, discarding those <= prev_length.\n         * At this point we have always match_length < MIN_MATCH\n         */\n        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {\n            /* To simplify the code, we prevent matches with the string\n             * of window index 0 (in particular we have to avoid a match\n             * of the string with itself at the start of the input file).\n             */\n            s->match_length = longest_match (s, hash_head);\n            /* longest_match() sets match_start */\n        }\n        if (s->match_length >= MIN_MATCH) {\n            check_match(s, s->strstart, s->match_start, (int)s->match_length);\n\n            _tr_tally_dist(s, s->strstart - s->match_start,\n                           s->match_length - MIN_MATCH, bflush);\n\n            s->lookahead -= s->match_length;\n\n            /* Insert new strings in the hash table only if the match length\n             * is not too large. This saves time but degrades compression.\n             */\n#ifndef FASTEST\n            if (s->match_length <= s->max_insert_length &&\n                s->lookahead >= MIN_MATCH) {\n                s->match_length--; /* string at strstart already in table */\n                do {\n                    s->strstart++;\n                    INSERT_STRING(s, s->strstart, hash_head);\n                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are\n                     * always MIN_MATCH bytes ahead.\n                     */\n                } while (--s->match_length != 0);\n                s->strstart++;\n            } else\n#endif\n            {\n                s->strstart += s->match_length;\n                s->match_length = 0;\n                s->ins_h = s->window[s->strstart];\n                UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]);\n#if MIN_MATCH != 3\n                Call UPDATE_HASH() MIN_MATCH-3 more times\n#endif\n                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n                 * matter since it will be recomputed at next deflate call.\n                 */\n            }\n        } else {\n            /* No match, output a literal byte */\n            Tracevv((stderr,\"%c\", s->window[s->strstart]));\n            _tr_tally_lit(s, s->window[s->strstart], bflush);\n            s->lookahead--;\n            s->strstart++;\n        }\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->sym_next)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n\n#ifndef FASTEST\n/* ===========================================================================\n * Same as above, but achieves better compression. We use a lazy\n * evaluation for matches: a match is finally adopted only if there is\n * no better match at the next window position.\n */\nlocal block_state deflate_slow(deflate_state *s, int flush) {\n    IPos hash_head;          /* head of hash chain */\n    int bflush;              /* set if current block must be flushed */\n\n    /* Process the input block. */\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the next match, plus MIN_MATCH bytes to insert the\n         * string following the next match.\n         */\n        if (s->lookahead < MIN_LOOKAHEAD) {\n            fill_window(s);\n            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* Insert the string window[strstart .. strstart + 2] in the\n         * dictionary, and set hash_head to the head of the hash chain:\n         */\n        hash_head = NIL;\n        if (s->lookahead >= MIN_MATCH) {\n            INSERT_STRING(s, s->strstart, hash_head);\n        }\n\n        /* Find the longest match, discarding those <= prev_length.\n         */\n        s->prev_length = s->match_length, s->prev_match = s->match_start;\n        s->match_length = MIN_MATCH-1;\n\n        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&\n            s->strstart - hash_head <= MAX_DIST(s)) {\n            /* To simplify the code, we prevent matches with the string\n             * of window index 0 (in particular we have to avoid a match\n             * of the string with itself at the start of the input file).\n             */\n            s->match_length = longest_match (s, hash_head);\n            /* longest_match() sets match_start */\n\n            if (s->match_length <= 5 && (s->strategy == Z_FILTERED\n#if TOO_FAR <= 32767\n                || (s->match_length == MIN_MATCH &&\n                    s->strstart - s->match_start > TOO_FAR)\n#endif\n                )) {\n\n                /* If prev_match is also MIN_MATCH, match_start is garbage\n                 * but we will ignore the current match anyway.\n                 */\n                s->match_length = MIN_MATCH-1;\n            }\n        }\n        /* If there was a match at the previous step and the current\n         * match is not better, output the previous match:\n         */\n        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {\n            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;\n            /* Do not insert strings in hash table beyond this. */\n\n            check_match(s, s->strstart - 1, s->prev_match, (int)s->prev_length);\n\n            _tr_tally_dist(s, s->strstart - 1 - s->prev_match,\n                           s->prev_length - MIN_MATCH, bflush);\n\n            /* Insert in hash table all strings up to the end of the match.\n             * strstart - 1 and strstart are already inserted. If there is not\n             * enough lookahead, the last two strings are not inserted in\n             * the hash table.\n             */\n            s->lookahead -= s->prev_length - 1;\n            s->prev_length -= 2;\n            do {\n                if (++s->strstart <= max_insert) {\n                    INSERT_STRING(s, s->strstart, hash_head);\n                }\n            } while (--s->prev_length != 0);\n            s->match_available = 0;\n            s->match_length = MIN_MATCH-1;\n            s->strstart++;\n\n            if (bflush) FLUSH_BLOCK(s, 0);\n\n        } else if (s->match_available) {\n            /* If there was no match at the previous position, output a\n             * single literal. If there was a match but the current match\n             * is longer, truncate the previous match to a single literal.\n             */\n            Tracevv((stderr,\"%c\", s->window[s->strstart - 1]));\n            _tr_tally_lit(s, s->window[s->strstart - 1], bflush);\n            if (bflush) {\n                FLUSH_BLOCK_ONLY(s, 0);\n            }\n            s->strstart++;\n            s->lookahead--;\n            if (s->strm->avail_out == 0) return need_more;\n        } else {\n            /* There is no previous match to compare with, wait for\n             * the next step to decide.\n             */\n            s->match_available = 1;\n            s->strstart++;\n            s->lookahead--;\n        }\n    }\n    Assert (flush != Z_NO_FLUSH, \"no flush?\");\n    if (s->match_available) {\n        Tracevv((stderr,\"%c\", s->window[s->strstart - 1]));\n        _tr_tally_lit(s, s->window[s->strstart - 1], bflush);\n        s->match_available = 0;\n    }\n    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->sym_next)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n#endif /* FASTEST */\n\n/* ===========================================================================\n * For Z_RLE, simply look for runs of bytes, generate matches only of distance\n * one.  Do not maintain a hash table.  (It will be regenerated if this run of\n * deflate switches away from Z_RLE.)\n */\nlocal block_state deflate_rle(deflate_state *s, int flush) {\n    int bflush;             /* set if current block must be flushed */\n    uInt prev;              /* byte at distance one to match */\n    Bytef *scan, *strend;   /* scan goes up to strend for length of run */\n\n    for (;;) {\n        /* Make sure that we always have enough lookahead, except\n         * at the end of the input file. We need MAX_MATCH bytes\n         * for the longest run, plus one for the unrolled loop.\n         */\n        if (s->lookahead <= MAX_MATCH) {\n            fill_window(s);\n            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {\n                return need_more;\n            }\n            if (s->lookahead == 0) break; /* flush the current block */\n        }\n\n        /* See how many times the previous byte repeats */\n        s->match_length = 0;\n        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {\n            scan = s->window + s->strstart - 1;\n            prev = *scan;\n            if (prev == *++scan && prev == *++scan && prev == *++scan) {\n                strend = s->window + s->strstart + MAX_MATCH;\n                do {\n                } while (prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         prev == *++scan && prev == *++scan &&\n                         scan < strend);\n                s->match_length = MAX_MATCH - (uInt)(strend - scan);\n                if (s->match_length > s->lookahead)\n                    s->match_length = s->lookahead;\n            }\n            Assert(scan <= s->window + (uInt)(s->window_size - 1),\n                   \"wild scan\");\n        }\n\n        /* Emit match if have run of MIN_MATCH or longer, else emit literal */\n        if (s->match_length >= MIN_MATCH) {\n            check_match(s, s->strstart, s->strstart - 1, (int)s->match_length);\n\n            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);\n\n            s->lookahead -= s->match_length;\n            s->strstart += s->match_length;\n            s->match_length = 0;\n        } else {\n            /* No match, output a literal byte */\n            Tracevv((stderr,\"%c\", s->window[s->strstart]));\n            _tr_tally_lit(s, s->window[s->strstart], bflush);\n            s->lookahead--;\n            s->strstart++;\n        }\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = 0;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->sym_next)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n\n/* ===========================================================================\n * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.\n * (It will be regenerated if this run of deflate switches away from Huffman.)\n */\nlocal block_state deflate_huff(deflate_state *s, int flush) {\n    int bflush;             /* set if current block must be flushed */\n\n    for (;;) {\n        /* Make sure that we have a literal to write. */\n        if (s->lookahead == 0) {\n            fill_window(s);\n            if (s->lookahead == 0) {\n                if (flush == Z_NO_FLUSH)\n                    return need_more;\n                break;      /* flush the current block */\n            }\n        }\n\n        /* Output a literal byte */\n        s->match_length = 0;\n        Tracevv((stderr,\"%c\", s->window[s->strstart]));\n        _tr_tally_lit(s, s->window[s->strstart], bflush);\n        s->lookahead--;\n        s->strstart++;\n        if (bflush) FLUSH_BLOCK(s, 0);\n    }\n    s->insert = 0;\n    if (flush == Z_FINISH) {\n        FLUSH_BLOCK(s, 1);\n        return finish_done;\n    }\n    if (s->sym_next)\n        FLUSH_BLOCK(s, 0);\n    return block_done;\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/deflate.h",
    "content": "/* deflate.h -- internal compression state\n * Copyright (C) 1995-2026 Jean-loup Gailly\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* @(#) $Id$ */\n\n#ifndef DEFLATE_H\n#define DEFLATE_H\n\n#include \"zutil.h\"\n\n/* define NO_GZIP when compiling if you want to disable gzip header and\n   trailer creation by deflate().  NO_GZIP would be used to avoid linking in\n   the crc code when it is not needed.  For shared libraries, gzip encoding\n   should be left enabled. */\n#ifndef NO_GZIP\n#  define GZIP\n#endif\n\n/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at\n   the cost of a larger memory footprint */\n/* #define LIT_MEM */\n\n/* ===========================================================================\n * Internal compression state.\n */\n\n#define LENGTH_CODES 29\n/* number of length codes, not counting the special END_BLOCK code */\n\n#define LITERALS  256\n/* number of literal bytes 0..255 */\n\n#define L_CODES (LITERALS+1+LENGTH_CODES)\n/* number of Literal or Length codes, including the END_BLOCK code */\n\n#define D_CODES   30\n/* number of distance codes */\n\n#define BL_CODES  19\n/* number of codes used to transfer the bit lengths */\n\n#define HEAP_SIZE (2*L_CODES+1)\n/* maximum heap size */\n\n#define MAX_BITS 15\n/* All codes must not exceed MAX_BITS bits */\n\n#define Buf_size 16\n/* size of bit buffer in bi_buf */\n\n#define INIT_STATE    42    /* zlib header -> BUSY_STATE */\n#ifdef GZIP\n#  define GZIP_STATE  57    /* gzip header -> BUSY_STATE | EXTRA_STATE */\n#endif\n#define EXTRA_STATE   69    /* gzip extra block -> NAME_STATE */\n#define NAME_STATE    73    /* gzip file name -> COMMENT_STATE */\n#define COMMENT_STATE 91    /* gzip comment -> HCRC_STATE */\n#define HCRC_STATE   103    /* gzip header CRC -> BUSY_STATE */\n#define BUSY_STATE   113    /* deflate -> FINISH_STATE */\n#define FINISH_STATE 666    /* stream complete */\n/* Stream status */\n\n\n/* Data structure describing a single value and its code string. */\ntypedef struct ct_data_s {\n    union {\n        ush  freq;       /* frequency count */\n        ush  code;       /* bit string */\n    } fc;\n    union {\n        ush  dad;        /* father node in Huffman tree */\n        ush  len;        /* length of bit string */\n    } dl;\n} FAR ct_data;\n\n#define Freq fc.freq\n#define Code fc.code\n#define Dad  dl.dad\n#define Len  dl.len\n\ntypedef struct static_tree_desc_s  static_tree_desc;\n\ntypedef struct tree_desc_s {\n    ct_data *dyn_tree;           /* the dynamic tree */\n    int     max_code;            /* largest code with non zero frequency */\n    const static_tree_desc *stat_desc;  /* the corresponding static tree */\n} FAR tree_desc;\n\ntypedef ush Pos;\ntypedef Pos FAR Posf;\ntypedef unsigned IPos;\n\n/* A Pos is an index in the character window. We use short instead of int to\n * save space in the various tables. IPos is used only for parameter passing.\n */\n\ntypedef struct internal_state {\n    z_streamp strm;      /* pointer back to this zlib stream */\n    int   status;        /* as the name implies */\n    Bytef *pending_buf;  /* output still pending */\n    ulg   pending_buf_size; /* size of pending_buf */\n    Bytef *pending_out;  /* next pending byte to output to the stream */\n    ulg   pending;       /* nb of bytes in the pending buffer */\n    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */\n    gz_headerp  gzhead;  /* gzip header information to write */\n    ulg   gzindex;       /* where in extra, name, or comment */\n    Byte  method;        /* can only be DEFLATED */\n    int   last_flush;    /* value of flush param for previous deflate call */\n\n                /* used by deflate.c: */\n\n    uInt  w_size;        /* LZ77 window size (32K by default) */\n    uInt  w_bits;        /* log2(w_size)  (8..16) */\n    uInt  w_mask;        /* w_size - 1 */\n\n    Bytef *window;\n    /* Sliding window. Input bytes are read into the second half of the window,\n     * and move to the first half later to keep a dictionary of at least wSize\n     * bytes. With this organization, matches are limited to a distance of\n     * wSize-MAX_MATCH bytes, but this ensures that IO is always\n     * performed with a length multiple of the block size. Also, it limits\n     * the window size to 64K, which is quite useful on MSDOS.\n     * To do: use the user input buffer as sliding window.\n     */\n\n    ulg window_size;\n    /* Actual size of window: 2*wSize, except when the user input buffer\n     * is directly used as sliding window.\n     */\n\n    Posf *prev;\n    /* Link to older string with same hash index. To limit the size of this\n     * array to 64K, this link is maintained only for the last 32K strings.\n     * An index in this array is thus a window index modulo 32K.\n     */\n\n    Posf *head; /* Heads of the hash chains or NIL. */\n\n    uInt  ins_h;          /* hash index of string to be inserted */\n    uInt  hash_size;      /* number of elements in hash table */\n    uInt  hash_bits;      /* log2(hash_size) */\n    uInt  hash_mask;      /* hash_size-1 */\n\n    uInt  hash_shift;\n    /* Number of bits by which ins_h must be shifted at each input\n     * step. It must be such that after MIN_MATCH steps, the oldest\n     * byte no longer takes part in the hash key, that is:\n     *   hash_shift * MIN_MATCH >= hash_bits\n     */\n\n    long block_start;\n    /* Window position at the beginning of the current output block. Gets\n     * negative when the window is moved backwards.\n     */\n\n    uInt match_length;           /* length of best match */\n    IPos prev_match;             /* previous match */\n    int match_available;         /* set if previous match exists */\n    uInt strstart;               /* start of string to insert */\n    uInt match_start;            /* start of matching string */\n    uInt lookahead;              /* number of valid bytes ahead in window */\n\n    uInt prev_length;\n    /* Length of the best match at previous step. Matches not greater than this\n     * are discarded. This is used in the lazy match evaluation.\n     */\n\n    uInt max_chain_length;\n    /* To speed up deflation, hash chains are never searched beyond this\n     * length.  A higher limit improves compression ratio but degrades the\n     * speed.\n     */\n\n    uInt max_lazy_match;\n    /* Attempt to find a better match only when the current match is strictly\n     * smaller than this value. This mechanism is used only for compression\n     * levels >= 4.\n     */\n#   define max_insert_length  max_lazy_match\n    /* Insert new strings in the hash table only if the match length is not\n     * greater than this length. This saves time but degrades compression.\n     * max_insert_length is used only for compression levels <= 3.\n     */\n\n    int level;    /* compression level (1..9) */\n    int strategy; /* favor or force Huffman coding*/\n\n    uInt good_match;\n    /* Use a faster search when the previous match is longer than this */\n\n    int nice_match; /* Stop searching when current match exceeds this */\n\n                /* used by trees.c: */\n    /* Didn't use ct_data typedef below to suppress compiler warning */\n    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */\n    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */\n    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */\n\n    struct tree_desc_s l_desc;               /* desc. for literal tree */\n    struct tree_desc_s d_desc;               /* desc. for distance tree */\n    struct tree_desc_s bl_desc;              /* desc. for bit length tree */\n\n    ush bl_count[MAX_BITS+1];\n    /* number of codes at each bit length for an optimal tree */\n\n    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */\n    int heap_len;               /* number of elements in the heap */\n    int heap_max;               /* element of largest frequency */\n    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n     * The same heap array is used to build all trees.\n     */\n\n    uch depth[2*L_CODES+1];\n    /* Depth of each subtree used as tie breaker for trees of equal frequency\n     */\n\n#ifdef LIT_MEM\n#   define LIT_BUFS 5\n    ushf *d_buf;          /* buffer for distances */\n    uchf *l_buf;          /* buffer for literals/lengths */\n#else\n#   define LIT_BUFS 4\n    uchf *sym_buf;        /* buffer for distances and literals/lengths */\n#endif\n\n    uInt  lit_bufsize;\n    /* Size of match buffer for literals/lengths.  There are 4 reasons for\n     * limiting lit_bufsize to 64K:\n     *   - frequencies can be kept in 16 bit counters\n     *   - if compression is not successful for the first block, all input\n     *     data is still in the window so we can still emit a stored block even\n     *     when input comes from standard input.  (This can also be done for\n     *     all blocks if lit_bufsize is not greater than 32K.)\n     *   - if compression is not successful for a file smaller than 64K, we can\n     *     even emit a stored file instead of a stored block (saving 5 bytes).\n     *     This is applicable only for zip (not gzip or zlib).\n     *   - creating new Huffman trees less frequently may not provide fast\n     *     adaptation to changes in the input data statistics. (Take for\n     *     example a binary file with poorly compressible code followed by\n     *     a highly compressible string table.) Smaller buffer sizes give\n     *     fast adaptation but have of course the overhead of transmitting\n     *     trees more frequently.\n     *   - I can't count above 4\n     */\n\n    uInt sym_next;      /* running index in symbol buffer */\n    uInt sym_end;       /* symbol table full when sym_next reaches this */\n\n    ulg opt_len;        /* bit length of current block with optimal trees */\n    ulg static_len;     /* bit length of current block with static trees */\n    uInt matches;       /* number of string matches in current block */\n    uInt insert;        /* bytes at end of window left to insert */\n\n#ifdef ZLIB_DEBUG\n    ulg compressed_len; /* total bit length of compressed file mod 2^32 */\n    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */\n#endif\n\n    ush bi_buf;\n    /* Output buffer. bits are inserted starting at the bottom (least\n     * significant bits).\n     */\n    int bi_valid;\n    /* Number of valid bits in bi_buf.  All bits above the last valid bit\n     * are always zero.\n     */\n    int bi_used;\n    /* Last number of used bits when going to a byte boundary.\n     */\n\n    ulg high_water;\n    /* High water mark offset in window for initialized bytes -- bytes above\n     * this are set to zero in order to avoid memory check warnings when\n     * longest match routines access bytes past the input.  This is then\n     * updated to the new high water mark.\n     */\n\n    int slid;\n    /* True if the hash table has been slid since it was cleared. */\n\n} FAR deflate_state;\n\n/* Output a byte on the stream.\n * IN assertion: there is enough room in pending_buf.\n */\n#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}\n\n\n#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)\n/* Minimum amount of lookahead, except at the end of the input file.\n * See deflate.c for comments about the MIN_MATCH+1.\n */\n\n#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)\n/* In order to simplify the code, particularly on 16 bit machines, match\n * distances are limited to MAX_DIST instead of WSIZE.\n */\n\n#define WIN_INIT MAX_MATCH\n/* Number of bytes after end of data in window to initialize in order to avoid\n   memory checker errors from longest match routines */\n\n        /* in trees.c */\nvoid ZLIB_INTERNAL _tr_init(deflate_state *s);\nint ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc);\nvoid ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,\n                                   ulg stored_len, int last);\nvoid ZLIB_INTERNAL _tr_flush_bits(deflate_state *s);\nvoid ZLIB_INTERNAL _tr_align(deflate_state *s);\nvoid ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,\n                                    ulg stored_len, int last);\n\n#define d_code(dist) \\\n   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])\n/* Mapping from a distance to a distance code. dist is the distance - 1 and\n * must not have side effects. _dist_code[256] and _dist_code[257] are never\n * used.\n */\n\n#ifndef ZLIB_DEBUG\n/* Inline versions of _tr_tally for speed: */\n\n#if defined(GEN_TREES_H) || !defined(STDC)\n  extern uch ZLIB_INTERNAL _length_code[];\n  extern uch ZLIB_INTERNAL _dist_code[];\n#else\n  extern const uch ZLIB_INTERNAL _length_code[];\n  extern const uch ZLIB_INTERNAL _dist_code[];\n#endif\n\n#ifdef LIT_MEM\n# define _tr_tally_lit(s, c, flush) \\\n  { uch cc = (c); \\\n    s->d_buf[s->sym_next] = 0; \\\n    s->l_buf[s->sym_next++] = cc; \\\n    s->dyn_ltree[cc].Freq++; \\\n    flush = (s->sym_next == s->sym_end); \\\n   }\n# define _tr_tally_dist(s, distance, length, flush) \\\n  { uch len = (uch)(length); \\\n    ush dist = (ush)(distance); \\\n    s->d_buf[s->sym_next] = dist; \\\n    s->l_buf[s->sym_next++] = len; \\\n    dist--; \\\n    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \\\n    s->dyn_dtree[d_code(dist)].Freq++; \\\n    flush = (s->sym_next == s->sym_end); \\\n  }\n#else\n# define _tr_tally_lit(s, c, flush) \\\n  { uch cc = (c); \\\n    s->sym_buf[s->sym_next++] = 0; \\\n    s->sym_buf[s->sym_next++] = 0; \\\n    s->sym_buf[s->sym_next++] = cc; \\\n    s->dyn_ltree[cc].Freq++; \\\n    flush = (s->sym_next == s->sym_end); \\\n   }\n# define _tr_tally_dist(s, distance, length, flush) \\\n  { uch len = (uch)(length); \\\n    ush dist = (ush)(distance); \\\n    s->sym_buf[s->sym_next++] = (uch)dist; \\\n    s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \\\n    s->sym_buf[s->sym_next++] = len; \\\n    dist--; \\\n    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \\\n    s->dyn_dtree[d_code(dist)].Freq++; \\\n    flush = (s->sym_next == s->sym_end); \\\n  }\n#endif\n#else\n# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)\n# define _tr_tally_dist(s, distance, length, flush) \\\n              flush = _tr_tally(s, distance, length)\n#endif\n\n#endif /* DEFLATE_H */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/gzclose.c",
    "content": "/* gzclose.c -- zlib gzclose() function\n * Copyright (C) 2004, 2010 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* gzclose() is in a separate file so that it is linked in only if it is used.\n   That way the other gzclose functions can be used instead to avoid linking in\n   unneeded compression or decompression routines. */\nint ZEXPORT gzclose(gzFile file) {\n#ifndef NO_GZCOMPRESS\n    gz_statep state;\n\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);\n#else\n    return gzclose_r(file);\n#endif\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/gzguts.h",
    "content": "/* gzguts.h -- zlib internal header definitions for gz* operations\n * Copyright (C) 2004-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#ifdef _LARGEFILE64_SOURCE\n#  ifndef _LARGEFILE_SOURCE\n#    define _LARGEFILE_SOURCE 1\n#  endif\n#  undef _FILE_OFFSET_BITS\n#  undef _TIME_BITS\n#endif\n\n#ifdef HAVE_HIDDEN\n#  define ZLIB_INTERNAL __attribute__((visibility (\"hidden\")))\n#else\n#  define ZLIB_INTERNAL\n#endif\n\n#if defined(_WIN32)\n#  ifndef WIN32_LEAN_AND_MEAN\n#    define WIN32_LEAN_AND_MEAN\n#  endif\n#  ifndef _CRT_SECURE_NO_WARNINGS\n#    define _CRT_SECURE_NO_WARNINGS\n#  endif\n#  ifndef _CRT_NONSTDC_NO_DEPRECATE\n#    define _CRT_NONSTDC_NO_DEPRECATE\n#  endif\n#endif\n\n#include <stdio.h>\n#include \"zlib.h\"\n#ifdef STDC\n#  include <string.h>\n#  include <stdlib.h>\n#  include <limits.h>\n#endif\n\n#ifndef _POSIX_C_SOURCE\n#  define _POSIX_C_SOURCE 200112L\n#endif\n#include <fcntl.h>\n\n#ifdef _WIN32\n#  include <stddef.h>\n#endif\n\n#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)\n#  include <io.h>\n#  include <sys/stat.h>\n#endif\n\n#if defined(_WIN32) && !defined(WIDECHAR)\n#  define WIDECHAR\n#endif\n\n#ifdef NO_DEFLATE       /* for compatibility with old definition */\n#  define NO_GZCOMPRESS\n#endif\n\n#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#if defined(__CYGWIN__)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)\n#  ifndef HAVE_VSNPRINTF\n#    define HAVE_VSNPRINTF\n#  endif\n#endif\n\n#ifndef HAVE_VSNPRINTF\n#  if !defined(NO_vsnprintf) && \\\n      (defined(MSDOS) || defined(__TURBOC__) || defined(__SASC) || \\\n       defined(VMS) || defined(__OS400) || defined(__MVS__))\n/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),\n   but for now we just assume it doesn't. */\n#    define NO_vsnprintf\n#  endif\n#  ifdef WIN32\n/* In Win32, vsnprintf is available as the \"non-ANSI\" _vsnprintf. */\n#    if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )\n#      ifndef vsnprintf\n#        define vsnprintf _vsnprintf\n#      endif\n#    endif\n#  elif !defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L\n/* Otherwise if C89/90, assume no C99 snprintf() or vsnprintf() */\n#    ifndef NO_snprintf\n#      define NO_snprintf\n#    endif\n#    ifndef NO_vsnprintf\n#      define NO_vsnprintf\n#    endif\n#  endif\n#endif\n\n/* unlike snprintf (which is required in C99), _snprintf does not guarantee\n   null termination of the result -- however this is only used in gzlib.c where\n   the result is assured to fit in the space provided */\n#if defined(_MSC_VER) && _MSC_VER < 1900\n#  define snprintf _snprintf\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* since \"static\" is used to mean two completely different things in C, we\n   define \"local\" for the non-static meaning of \"static\", for readability\n   (compile with -Dlocal if your debugger can't find static symbols) */\n\n/* gz* functions always use library allocation functions */\n#ifndef STDC\n  extern voidp  malloc(uInt size);\n  extern void   free(voidpf ptr);\n#endif\n\n/* get errno and strerror definition */\n#if defined UNDER_CE\n#  include <windows.h>\n#  define zstrerror() gz_strwinerror((DWORD)GetLastError())\n#else\n#  ifndef NO_STRERROR\n#    include <errno.h>\n#    define zstrerror() strerror(errno)\n#  else\n#    define zstrerror() \"stdio error (consult errno)\"\n#  endif\n#endif\n\n/* provide prototypes for these when building zlib without LFS */\n#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0\n    ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);\n    ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);\n    ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);\n    ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);\n#endif\n\n/* default memLevel */\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n\n/* default i/o buffer size -- double this for output when reading (this and\n   twice this must be able to fit in an unsigned type) */\n#define GZBUFSIZE 8192\n\n/* gzip modes, also provide a little integrity check on the passed structure */\n#define GZ_NONE 0\n#define GZ_READ 7247\n#define GZ_WRITE 31153\n#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */\n\n/* values for gz_state how */\n#define LOOK 0      /* look for a gzip header */\n#define COPY 1      /* copy input directly */\n#define GZIP 2      /* decompress a gzip stream */\n\n/* internal gzip file state data structure */\ntypedef struct {\n        /* exposed contents for gzgetc() macro */\n    struct gzFile_s x;      /* \"x\" for exposed */\n                            /* x.have: number of bytes available at x.next */\n                            /* x.next: next output data to deliver or write */\n                            /* x.pos: current position in uncompressed data */\n        /* used for both reading and writing */\n    int mode;               /* see gzip modes above */\n    int fd;                 /* file descriptor */\n    char *path;             /* path or fd for error messages */\n    unsigned size;          /* buffer size, zero if not allocated yet */\n    unsigned want;          /* requested buffer size, default is GZBUFSIZE */\n    unsigned char *in;      /* input buffer (double-sized when writing) */\n    unsigned char *out;     /* output buffer (double-sized when reading) */\n    int direct;             /* 0 if processing gzip, 1 if transparent */\n        /* just for reading */\n    int junk;               /* -1 = start, 1 = junk candidate, 0 = in gzip */\n    int how;                /* 0: get header, 1: copy, 2: decompress */\n    int again;              /* true if EAGAIN or EWOULDBLOCK on last i/o */\n    z_off64_t start;        /* where the gzip data started, for rewinding */\n    int eof;                /* true if end of input file reached */\n    int past;               /* true if read requested past end */\n        /* just for writing */\n    int level;              /* compression level */\n    int strategy;           /* compression strategy */\n    int reset;              /* true if a reset is pending after a Z_FINISH */\n        /* seek request */\n    z_off64_t skip;         /* amount to skip (already rewound if backwards) */\n        /* error information */\n    int err;                /* error code */\n    char *msg;              /* error message */\n        /* zlib inflate or deflate stream */\n    z_stream strm;          /* stream structure in-place (not a pointer) */\n} gz_state;\ntypedef gz_state FAR *gz_statep;\n\n/* shared functions */\nvoid ZLIB_INTERNAL gz_error(gz_statep, int, const char *);\n#if defined UNDER_CE\nchar ZLIB_INTERNAL *gz_strwinerror(DWORD error);\n#endif\n\n/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t\n   value -- needed when comparing unsigned to z_off64_t, which is signed\n   (possible z_off64_t types off_t, off64_t, and long are all signed) */\nunsigned ZLIB_INTERNAL gz_intmax(void);\n#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())\n"
  },
  {
    "path": "vendor/core/vendor/zlib/gzlib.c",
    "content": "/* gzlib.c -- zlib functions common to reading and writing gzip files\n * Copyright (C) 2004-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n#if defined(__DJGPP__)\n#  define LSEEK llseek\n#elif defined(_WIN32) && !defined(__BORLANDC__) && !defined(UNDER_CE)\n#  define LSEEK _lseeki64\n#elif defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0\n#  define LSEEK lseek64\n#else\n#  define LSEEK lseek\n#endif\n\n#if defined UNDER_CE\n\n/* Map the Windows error number in ERROR to a locale-dependent error message\n   string and return a pointer to it.  Typically, the values for ERROR come\n   from GetLastError.\n\n   The string pointed to shall not be modified by the application, but may be\n   overwritten by a subsequent call to gz_strwinerror\n\n   The gz_strwinerror function does not change the current setting of\n   GetLastError. */\nchar ZLIB_INTERNAL *gz_strwinerror(DWORD error) {\n    static char buf[1024];\n\n    wchar_t *msgbuf;\n    DWORD lasterr = GetLastError();\n    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM\n        | FORMAT_MESSAGE_ALLOCATE_BUFFER,\n        NULL,\n        error,\n        0, /* Default language */\n        (LPVOID)&msgbuf,\n        0,\n        NULL);\n    if (chars != 0) {\n        /* If there is an \\r\\n appended, zap it.  */\n        if (chars >= 2\n            && msgbuf[chars - 2] == '\\r' && msgbuf[chars - 1] == '\\n') {\n            chars -= 2;\n            msgbuf[chars] = 0;\n        }\n\n        if (chars > sizeof (buf) - 1) {\n            chars = sizeof (buf) - 1;\n            msgbuf[chars] = 0;\n        }\n\n        wcstombs(buf, msgbuf, chars + 1);       /* assumes buf is big enough */\n        LocalFree(msgbuf);\n    }\n    else {\n        sprintf(buf, \"unknown win32 error (%ld)\", error);\n    }\n\n    SetLastError(lasterr);\n    return buf;\n}\n\n#endif /* UNDER_CE */\n\n/* Reset gzip file state */\nlocal void gz_reset(gz_statep state) {\n    state->x.have = 0;              /* no output data available */\n    if (state->mode == GZ_READ) {   /* for reading ... */\n        state->eof = 0;             /* not at end of file */\n        state->past = 0;            /* have not read past end yet */\n        state->how = LOOK;          /* look for gzip header */\n        state->junk = -1;           /* mark first member */\n    }\n    else                            /* for writing ... */\n        state->reset = 0;           /* no deflateReset pending */\n    state->again = 0;               /* no stalled i/o yet */\n    state->skip = 0;                /* no seek request pending */\n    gz_error(state, Z_OK, NULL);    /* clear error */\n    state->x.pos = 0;               /* no uncompressed data yet */\n    state->strm.avail_in = 0;       /* no input data yet */\n}\n\n/* Open a gzip file either by name or file descriptor. */\nlocal gzFile gz_open(const void *path, int fd, const char *mode) {\n    gz_statep state;\n    z_size_t len;\n    int oflag = 0;\n#ifdef O_EXCL\n    int exclusive = 0;\n#endif\n\n    /* check input */\n    if (path == NULL || mode == NULL)\n        return NULL;\n\n    /* allocate gzFile structure to return */\n    state = (gz_statep)malloc(sizeof(gz_state));\n    if (state == NULL)\n        return NULL;\n    state->size = 0;            /* no buffers allocated yet */\n    state->want = GZBUFSIZE;    /* requested buffer size */\n    state->err = Z_OK;          /* no error yet */\n    state->msg = NULL;          /* no error message yet */\n\n    /* interpret mode */\n    state->mode = GZ_NONE;\n    state->level = Z_DEFAULT_COMPRESSION;\n    state->strategy = Z_DEFAULT_STRATEGY;\n    state->direct = 0;\n    while (*mode) {\n        if (*mode >= '0' && *mode <= '9')\n            state->level = *mode - '0';\n        else\n            switch (*mode) {\n            case 'r':\n                state->mode = GZ_READ;\n                break;\n#ifndef NO_GZCOMPRESS\n            case 'w':\n                state->mode = GZ_WRITE;\n                break;\n            case 'a':\n                state->mode = GZ_APPEND;\n                break;\n#endif\n            case '+':       /* can't read and write at the same time */\n                free(state);\n                return NULL;\n            case 'b':       /* ignore -- will request binary anyway */\n                break;\n#ifdef O_CLOEXEC\n            case 'e':\n                oflag |= O_CLOEXEC;\n                break;\n#endif\n#ifdef O_EXCL\n            case 'x':\n                exclusive = 1;\n                break;\n#endif\n            case 'f':\n                state->strategy = Z_FILTERED;\n                break;\n            case 'h':\n                state->strategy = Z_HUFFMAN_ONLY;\n                break;\n            case 'R':\n                state->strategy = Z_RLE;\n                break;\n            case 'F':\n                state->strategy = Z_FIXED;\n                break;\n            case 'G':\n                state->direct = -1;\n                break;\n#ifdef O_NONBLOCK\n            case 'N':\n                oflag |= O_NONBLOCK;\n                break;\n#endif\n            case 'T':\n                state->direct = 1;\n                break;\n            default:        /* could consider as an error, but just ignore */\n                ;\n            }\n        mode++;\n    }\n\n    /* must provide an \"r\", \"w\", or \"a\" */\n    if (state->mode == GZ_NONE) {\n        free(state);\n        return NULL;\n    }\n\n    /* direct is 0, 1 if \"T\", or -1 if \"G\" (last \"G\" or \"T\" wins) */\n    if (state->mode == GZ_READ) {\n        if (state->direct == 1) {\n            /* can't force a transparent read */\n            free(state);\n            return NULL;\n        }\n        if (state->direct == 0)\n            /* default when reading is auto-detect of gzip vs. transparent --\n               start with a transparent assumption in case of an empty file */\n            state->direct = 1;\n    }\n    else if (state->direct == -1) {\n        /* \"G\" has no meaning when writing -- disallow it */\n        free(state);\n        return NULL;\n    }\n    /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or\n       appending, direct == 0 for gzip, 1 for transparent (copy in to out) */\n\n    /* save the path name for error messages */\n#ifdef WIDECHAR\n    if (fd == -2)\n        len = wcstombs(NULL, path, 0);\n    else\n#endif\n        len = strlen((const char *)path);\n    state->path = (char *)malloc(len + 1);\n    if (state->path == NULL) {\n        free(state);\n        return NULL;\n    }\n#ifdef WIDECHAR\n    if (fd == -2) {\n        if (len)\n            wcstombs(state->path, path, len + 1);\n        else\n            *(state->path) = 0;\n    }\n    else\n#endif\n    {\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n        (void)snprintf(state->path, len + 1, \"%s\", (const char *)path);\n#else\n        strcpy(state->path, path);\n#endif\n    }\n\n    /* compute the flags for open() */\n    oflag |=\n#ifdef O_LARGEFILE\n        O_LARGEFILE |\n#endif\n#ifdef O_BINARY\n        O_BINARY |\n#endif\n        (state->mode == GZ_READ ?\n         O_RDONLY :\n         (O_WRONLY | O_CREAT |\n#ifdef O_EXCL\n          (exclusive ? O_EXCL : 0) |\n#endif\n          (state->mode == GZ_WRITE ?\n           O_TRUNC :\n           O_APPEND)));\n\n    /* open the file with the appropriate flags (or just use fd) */\n    if (fd == -1)\n        state->fd = open((const char *)path, oflag, 0666);\n#ifdef WIDECHAR\n    else if (fd == -2)\n        state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE);\n#endif\n    else {\n#ifdef O_NONBLOCK\n        if (oflag & O_NONBLOCK)\n            fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);\n#endif\n#ifdef O_CLOEXEC\n        if (oflag & O_CLOEXEC)\n            fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC);\n#endif\n        state->fd = fd;\n    }\n    if (state->fd == -1) {\n        free(state->path);\n        free(state);\n        return NULL;\n    }\n    if (state->mode == GZ_APPEND) {\n        LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */\n        state->mode = GZ_WRITE;         /* simplify later checks */\n    }\n\n    /* save the current position for rewinding (only if reading) */\n    if (state->mode == GZ_READ) {\n        state->start = LSEEK(state->fd, 0, SEEK_CUR);\n        if (state->start == -1) state->start = 0;\n    }\n\n    /* initialize stream */\n    gz_reset(state);\n\n    /* return stream */\n    return (gzFile)state;\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzopen(const char *path, const char *mode) {\n    return gz_open(path, -1, mode);\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzopen64(const char *path, const char *mode) {\n    return gz_open(path, -1, mode);\n}\n\n/* -- see zlib.h -- */\ngzFile ZEXPORT gzdopen(int fd, const char *mode) {\n    char *path;         /* identifier for error messages */\n    gzFile gz;\n\n    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)\n        return NULL;\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    (void)snprintf(path, 7 + 3 * sizeof(int), \"<fd:%d>\", fd);\n#else\n    sprintf(path, \"<fd:%d>\", fd);   /* for debugging */\n#endif\n    gz = gz_open(path, fd, mode);\n    free(path);\n    return gz;\n}\n\n/* -- see zlib.h -- */\n#ifdef WIDECHAR\ngzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {\n    return gz_open(path, -2, mode);\n}\n#endif\n\n/* -- see zlib.h -- */\nint ZEXPORT gzbuffer(gzFile file, unsigned size) {\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* make sure we haven't already allocated memory */\n    if (state->size != 0)\n        return -1;\n\n    /* check and set requested size */\n    if ((size << 1) < size)\n        return -1;              /* need to be able to double it */\n    if (size < 8)\n        size = 8;               /* needed to behave well with flushing */\n    state->want = size;\n    return 0;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzrewind(gzFile file) {\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're reading and that there's no error */\n    if (state->mode != GZ_READ ||\n            (state->err != Z_OK && state->err != Z_BUF_ERROR))\n        return -1;\n\n    /* back up and start over */\n    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)\n        return -1;\n    gz_reset(state);\n    return 0;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {\n    unsigned n;\n    z_off64_t ret;\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* check that there's no error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR)\n        return -1;\n\n    /* can only seek from start or relative to current position */\n    if (whence != SEEK_SET && whence != SEEK_CUR)\n        return -1;\n\n    /* normalize offset to a SEEK_CUR specification */\n    if (whence == SEEK_SET)\n        offset -= state->x.pos;\n    else {\n        offset += state->past ? 0 : state->skip;\n        state->skip = 0;\n    }\n\n    /* if within raw area while reading, just go there */\n    if (state->mode == GZ_READ && state->how == COPY &&\n            state->x.pos + offset >= 0) {\n        ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);\n        if (ret == -1)\n            return -1;\n        state->x.have = 0;\n        state->eof = 0;\n        state->past = 0;\n        state->skip = 0;\n        gz_error(state, Z_OK, NULL);\n        state->strm.avail_in = 0;\n        state->x.pos += offset;\n        return state->x.pos;\n    }\n\n    /* calculate skip amount, rewinding if needed for back seek when reading */\n    if (offset < 0) {\n        if (state->mode != GZ_READ)         /* writing -- can't go backwards */\n            return -1;\n        offset += state->x.pos;\n        if (offset < 0)                     /* before start of file! */\n            return -1;\n        if (gzrewind(file) == -1)           /* rewind, then skip to offset */\n            return -1;\n    }\n\n    /* if reading, skip what's in output buffer (one less gzgetc() check) */\n    if (state->mode == GZ_READ) {\n        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?\n            (unsigned)offset : state->x.have;\n        state->x.have -= n;\n        state->x.next += n;\n        state->x.pos += n;\n        offset -= n;\n    }\n\n    /* request skip (if not zero) */\n    state->skip = offset;\n    return state->x.pos + offset;\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {\n    z_off64_t ret;\n\n    ret = gzseek64(file, (z_off64_t)offset, whence);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gztell64(gzFile file) {\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* return position */\n    return state->x.pos + (state->past ? 0 : state->skip);\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gztell(gzFile file) {\n    z_off64_t ret;\n\n    ret = gztell64(file);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nz_off64_t ZEXPORT gzoffset64(gzFile file) {\n    z_off64_t offset;\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return -1;\n\n    /* compute and return effective offset in file */\n    offset = LSEEK(state->fd, 0, SEEK_CUR);\n    if (offset == -1)\n        return -1;\n    if (state->mode == GZ_READ)             /* reading */\n        offset -= state->strm.avail_in;     /* don't count buffered input */\n    return offset;\n}\n\n/* -- see zlib.h -- */\nz_off_t ZEXPORT gzoffset(gzFile file) {\n    z_off64_t ret;\n\n    ret = gzoffset64(file);\n    return ret == (z_off_t)ret ? (z_off_t)ret : -1;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzeof(gzFile file) {\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return 0;\n\n    /* return end-of-file state */\n    return state->mode == GZ_READ ? state->past : 0;\n}\n\n/* -- see zlib.h -- */\nconst char * ZEXPORT gzerror(gzFile file, int *errnum) {\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return NULL;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return NULL;\n\n    /* return error information */\n    if (errnum != NULL)\n        *errnum = state->err;\n    return state->err == Z_MEM_ERROR ? \"out of memory\" :\n                                       (state->msg == NULL ? \"\" : state->msg);\n}\n\n/* -- see zlib.h -- */\nvoid ZEXPORT gzclearerr(gzFile file) {\n    gz_statep state;\n\n    /* get internal structure and check integrity */\n    if (file == NULL)\n        return;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ && state->mode != GZ_WRITE)\n        return;\n\n    /* clear error and end-of-file */\n    if (state->mode == GZ_READ) {\n        state->eof = 0;\n        state->past = 0;\n    }\n    gz_error(state, Z_OK, NULL);\n}\n\n/* Create an error message in allocated memory and set state->err and\n   state->msg accordingly.  Free any previous error message already there.  Do\n   not try to free or allocate space if the error is Z_MEM_ERROR (out of\n   memory).  Simply save the error message as a static string.  If there is an\n   allocation failure constructing the error message, then convert the error to\n   out of memory. */\nvoid ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {\n    /* free previously allocated message and clear */\n    if (state->msg != NULL) {\n        if (state->err != Z_MEM_ERROR)\n            free(state->msg);\n        state->msg = NULL;\n    }\n\n    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */\n    if (err != Z_OK && err != Z_BUF_ERROR && !state->again)\n        state->x.have = 0;\n\n    /* set error code, and if no message, then done */\n    state->err = err;\n    if (msg == NULL)\n        return;\n\n    /* for an out of memory error, return literal string when requested */\n    if (err == Z_MEM_ERROR)\n        return;\n\n    /* construct error message with path */\n    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==\n            NULL) {\n        state->err = Z_MEM_ERROR;\n        return;\n    }\n#if !defined(NO_snprintf) && !defined(NO_vsnprintf)\n    (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,\n                   \"%s%s%s\", state->path, \": \", msg);\n#else\n    strcpy(state->msg, state->path);\n    strcat(state->msg, \": \");\n    strcat(state->msg, msg);\n#endif\n}\n\n/* portably return maximum value for an int (when limits.h presumed not\n   available) -- we need to do this to cover cases where 2's complement not\n   used, since C standard permits 1's complement and sign-bit representations,\n   otherwise we could just use ((unsigned)-1) >> 1 */\nunsigned ZLIB_INTERNAL gz_intmax(void) {\n#ifdef INT_MAX\n    return INT_MAX;\n#else\n    unsigned p = 1, q;\n\n    do {\n        q = p;\n        p <<= 1;\n        p++;\n    } while (p > q);\n    return q >> 1;\n#endif\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/gzread.c",
    "content": "/* gzread.c -- zlib functions for reading gzip files\n * Copyright (C) 2004-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from\n   state->fd, and update state->eof, state->err, and state->msg as appropriate.\n   This function needs to loop on read(), since read() is not guaranteed to\n   read the number of bytes requested, depending on the type of descriptor. It\n   also needs to loop to manage the fact that read() returns an int. If the\n   descriptor is non-blocking and read() returns with no data in order to avoid\n   blocking, then gz_load() will return 0 if some data has been read, or -1 if\n   no data has been read. Either way, state->again is set true to indicate a\n   non-blocking event. If errno is non-zero on return, then there was an error\n   signaled from read().  *have is set to the number of bytes read. */\nlocal int gz_load(gz_statep state, unsigned char *buf, unsigned len,\n                  unsigned *have) {\n    int ret;\n    unsigned get, max = ((unsigned)-1 >> 2) + 1;\n\n    state->again = 0;\n    errno = 0;\n    *have = 0;\n    do {\n        get = len - *have;\n        if (get > max)\n            get = max;\n        ret = (int)read(state->fd, buf + *have, get);\n        if (ret <= 0)\n            break;\n        *have += (unsigned)ret;\n    } while (*have < len);\n    if (ret < 0) {\n        if (errno == EAGAIN || errno == EWOULDBLOCK) {\n            state->again = 1;\n            if (*have != 0)\n                return 0;\n        }\n        gz_error(state, Z_ERRNO, zstrerror());\n        return -1;\n    }\n    if (ret == 0)\n        state->eof = 1;\n    return 0;\n}\n\n/* Load up input buffer and set eof flag if last data loaded -- return -1 on\n   error, 0 otherwise.  Note that the eof flag is set when the end of the input\n   file is reached, even though there may be unused data in the buffer.  Once\n   that data has been used, no more attempts will be made to read the file.\n   If strm->avail_in != 0, then the current data is moved to the beginning of\n   the input buffer, and then the remainder of the buffer is loaded with the\n   available data from the input file. */\nlocal int gz_avail(gz_statep state) {\n    unsigned got;\n    z_streamp strm = &(state->strm);\n\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR)\n        return -1;\n    if (state->eof == 0) {\n        if (strm->avail_in) {       /* copy what's there to the start */\n            unsigned char *p = state->in;\n            unsigned const char *q = strm->next_in;\n\n            if (q != p) {\n                unsigned n = strm->avail_in;\n\n                do {\n                    *p++ = *q++;\n                } while (--n);\n            }\n        }\n        if (gz_load(state, state->in + strm->avail_in,\n                    state->size - strm->avail_in, &got) == -1)\n            return -1;\n        strm->avail_in += got;\n        strm->next_in = state->in;\n    }\n    return 0;\n}\n\n/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.\n   If this is the first time in, allocate required memory.  state->how will be\n   left unchanged if there is no more input data available, will be set to COPY\n   if there is no gzip header and direct copying will be performed, or it will\n   be set to GZIP for decompression.  If direct copying, then leftover input\n   data from the input buffer will be copied to the output buffer.  In that\n   case, all further file reads will be directly to either the output buffer or\n   a user buffer.  If decompressing, the inflate state will be initialized.\n   gz_look() will return 0 on success or -1 on failure. */\nlocal int gz_look(gz_statep state) {\n    z_streamp strm = &(state->strm);\n\n    /* allocate read buffers and inflate memory */\n    if (state->size == 0) {\n        /* allocate buffers */\n        state->in = (unsigned char *)malloc(state->want);\n        state->out = (unsigned char *)malloc(state->want << 1);\n        if (state->in == NULL || state->out == NULL) {\n            free(state->out);\n            free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n        state->size = state->want;\n\n        /* allocate inflate memory */\n        state->strm.zalloc = Z_NULL;\n        state->strm.zfree = Z_NULL;\n        state->strm.opaque = Z_NULL;\n        state->strm.avail_in = 0;\n        state->strm.next_in = Z_NULL;\n        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */\n            free(state->out);\n            free(state->in);\n            state->size = 0;\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n    }\n\n    /* if transparent reading is disabled, which would only be at the start, or\n       if we're looking for a gzip member after the first one, which is not at\n       the start, then proceed directly to look for a gzip member next */\n    if (state->direct == -1 || state->junk == 0) {\n        inflateReset(strm);\n        state->how = GZIP;\n        state->junk = state->junk != -1;\n        state->direct = 0;\n        return 0;\n    }\n\n    /* otherwise we're at the start with auto-detect -- we check to see if the\n       first four bytes could be gzip header in order to decide whether or not\n       this will be a transparent read */\n\n    /* load any header bytes into the input buffer -- if the input is empty,\n       then it's not an error as this is a transparent read of zero bytes */\n    if (gz_avail(state) == -1)\n        return -1;\n    if (strm->avail_in == 0 || (state->again && strm->avail_in < 4))\n        /* if non-blocking input stalled before getting four bytes, then\n           return and wait until a later call has accumulated enough */\n        return 0;\n\n    /* see if this is (likely) gzip input -- if the first four bytes are\n       consistent with a gzip header, then go look for the first gzip member,\n       otherwise proceed to copy the input transparently */\n    if (strm->avail_in > 3 &&\n            strm->next_in[0] == 31 && strm->next_in[1] == 139 &&\n            strm->next_in[2] == 8 && strm->next_in[3] < 32) {\n        inflateReset(strm);\n        state->how = GZIP;\n        state->junk = 1;\n        state->direct = 0;\n        return 0;\n    }\n\n    /* doing raw i/o: copy any leftover input to output -- this assumes that\n       the output buffer is larger than the input buffer, which also assures\n       space for gzungetc() */\n    state->x.next = state->out;\n    memcpy(state->x.next, strm->next_in, strm->avail_in);\n    state->x.have = strm->avail_in;\n    strm->avail_in = 0;\n    state->how = COPY;\n    return 0;\n}\n\n/* Decompress from input to the provided next_out and avail_out in the state.\n   On return, state->x.have and state->x.next point to the just decompressed\n   data. If the gzip stream completes, state->how is reset to LOOK to look for\n   the next gzip stream or raw data, once state->x.have is depleted. Returns 0\n   on success, -1 on failure. If EOF is reached when looking for more input to\n   complete the gzip member, then an unexpected end of file error is raised.\n   If there is no more input, but state->again is true, then EOF has not been\n   reached, and no error is raised. */\nlocal int gz_decomp(gz_statep state) {\n    int ret = Z_OK;\n    unsigned had;\n    z_streamp strm = &(state->strm);\n\n    /* fill output buffer up to end of deflate stream */\n    had = strm->avail_out;\n    do {\n        /* get more input for inflate() */\n        if (strm->avail_in == 0 && gz_avail(state) == -1) {\n            ret = state->err;\n            break;\n        }\n        if (strm->avail_in == 0) {\n            if (!state->again)\n                gz_error(state, Z_BUF_ERROR, \"unexpected end of file\");\n            break;\n        }\n\n        /* decompress and handle errors */\n        ret = inflate(strm, Z_NO_FLUSH);\n        if (strm->avail_out < had)\n            /* any decompressed data marks this as a real gzip stream */\n            state->junk = 0;\n        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {\n            gz_error(state, Z_STREAM_ERROR,\n                     \"internal error: inflate stream corrupt\");\n            break;\n        }\n        if (ret == Z_MEM_ERROR) {\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            break;\n        }\n        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */\n            if (state->junk == 1) {             /* trailing garbage is ok */\n                strm->avail_in = 0;\n                state->eof = 1;\n                state->how = LOOK;\n                ret = Z_OK;\n                break;\n            }\n            gz_error(state, Z_DATA_ERROR,\n                     strm->msg == NULL ? \"compressed data error\" : strm->msg);\n            break;\n        }\n    } while (strm->avail_out && ret != Z_STREAM_END);\n\n    /* update available output */\n    state->x.have = had - strm->avail_out;\n    state->x.next = strm->next_out - state->x.have;\n\n    /* if the gzip stream completed successfully, look for another */\n    if (ret == Z_STREAM_END) {\n        state->junk = 0;\n        state->how = LOOK;\n        return 0;\n    }\n\n    /* return decompression status */\n    return ret != Z_OK ? -1 : 0;\n}\n\n/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.\n   Data is either copied from the input file or decompressed from the input\n   file depending on state->how.  If state->how is LOOK, then a gzip header is\n   looked for to determine whether to copy or decompress.  Returns -1 on error,\n   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the\n   end of the input file has been reached and all data has been processed.  */\nlocal int gz_fetch(gz_statep state) {\n    z_streamp strm = &(state->strm);\n\n    do {\n        switch(state->how) {\n        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */\n            if (gz_look(state) == -1)\n                return -1;\n            if (state->how == LOOK)\n                return 0;\n            break;\n        case COPY:      /* -> COPY */\n            if (gz_load(state, state->out, state->size << 1, &(state->x.have))\n                    == -1)\n                return -1;\n            state->x.next = state->out;\n            return 0;\n        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */\n            strm->avail_out = state->size << 1;\n            strm->next_out = state->out;\n            if (gz_decomp(state) == -1)\n                return -1;\n            break;\n        default:\n            gz_error(state, Z_STREAM_ERROR, \"state corrupt\");\n            return -1;\n        }\n    } while (state->x.have == 0 && (!state->eof || strm->avail_in));\n    return 0;\n}\n\n/* Skip state->skip (> 0) uncompressed bytes of output.  Return -1 on error, 0\n   on success. */\nlocal int gz_skip(gz_statep state) {\n    unsigned n;\n\n    /* skip over len bytes or reach end-of-file, whichever comes first */\n    do {\n        /* skip over whatever is in output buffer */\n        if (state->x.have) {\n            n = GT_OFF(state->x.have) ||\n                (z_off64_t)state->x.have > state->skip ?\n                (unsigned)state->skip : state->x.have;\n            state->x.have -= n;\n            state->x.next += n;\n            state->x.pos += n;\n            state->skip -= n;\n        }\n\n        /* output buffer empty -- return if we're at the end of the input */\n        else if (state->eof && state->strm.avail_in == 0)\n            break;\n\n        /* need more data to skip -- load up output buffer */\n        else {\n            /* get more output, looking for header if required */\n            if (gz_fetch(state) == -1)\n                return -1;\n        }\n    } while (state->skip);\n    return 0;\n}\n\n/* Read len bytes into buf from file, or less than len up to the end of the\n   input. Return the number of bytes read. If zero is returned, either the end\n   of file was reached, or there was an error. state->err must be consulted in\n   that case to determine which. If there was an error, but some uncompressed\n   bytes were read before the error, then that count is returned. The error is\n   still recorded, and so is deferred until the next call. */\nlocal z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {\n    z_size_t got;\n    unsigned n;\n    int err;\n\n    /* if len is zero, avoid unnecessary operations */\n    if (len == 0)\n        return 0;\n\n    /* process a skip request */\n    if (state->skip && gz_skip(state) == -1)\n        return 0;\n\n    /* get len bytes to buf, or less than len if at the end */\n    got = 0;\n    err = 0;\n    do {\n        /* set n to the maximum amount of len that fits in an unsigned int */\n        n = (unsigned)-1;\n        if (n > len)\n            n = (unsigned)len;\n\n        /* first just try copying data from the output buffer */\n        if (state->x.have) {\n            if (state->x.have < n)\n                n = state->x.have;\n            memcpy(buf, state->x.next, n);\n            state->x.next += n;\n            state->x.have -= n;\n            if (state->err != Z_OK)\n                /* caught deferred error from gz_fetch() */\n                err = -1;\n        }\n\n        /* output buffer empty -- return if we're at the end of the input */\n        else if (state->eof && state->strm.avail_in == 0)\n            break;\n\n        /* need output data -- for small len or new stream load up our output\n           buffer, so that gzgetc() can be fast */\n        else if (state->how == LOOK || n < (state->size << 1)) {\n            /* get more output, looking for header if required */\n            if (gz_fetch(state) == -1 && state->x.have == 0)\n                /* if state->x.have != 0, error will be caught after copy */\n                err = -1;\n            continue;       /* no progress yet -- go back to copy above */\n            /* the copy above assures that we will leave with space in the\n               output buffer, allowing at least one gzungetc() to succeed */\n        }\n\n        /* large len -- read directly into user buffer */\n        else if (state->how == COPY)        /* read directly */\n            err = gz_load(state, (unsigned char *)buf, n, &n);\n\n        /* large len -- decompress directly into user buffer */\n        else {  /* state->how == GZIP */\n            state->strm.avail_out = n;\n            state->strm.next_out = (unsigned char *)buf;\n            err = gz_decomp(state);\n            n = state->x.have;\n            state->x.have = 0;\n        }\n\n        /* update progress */\n        len -= n;\n        buf = (char *)buf + n;\n        got += n;\n        state->x.pos += n;\n    } while (len && !err);\n\n    /* note read past eof */\n    if (len && state->eof)\n        state->past = 1;\n\n    /* return number of bytes read into user buffer */\n    return got;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {\n    gz_statep state;\n\n    /* get internal structure and check that it's for reading */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return -1;\n\n    /* check that there was no (serious) error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)\n        return -1;\n    gz_error(state, Z_OK, NULL);\n\n    /* since an int is returned, make sure len fits in one, otherwise return\n       with an error (this avoids a flaw in the interface) */\n    if ((int)len < 0) {\n        gz_error(state, Z_STREAM_ERROR, \"request does not fit in an int\");\n        return -1;\n    }\n\n    /* read len or fewer bytes to buf */\n    len = (unsigned)gz_read(state, buf, len);\n\n    /* check for an error */\n    if (len == 0) {\n        if (state->err != Z_OK && state->err != Z_BUF_ERROR)\n            return -1;\n        if (state->again) {\n            /* non-blocking input stalled after some input was read, but no\n               uncompressed bytes were produced -- let the application know\n               this isn't EOF */\n            gz_error(state, Z_ERRNO, zstrerror());\n            return -1;\n        }\n    }\n\n    /* return the number of bytes read */\n    return (int)len;\n}\n\n/* -- see zlib.h -- */\nz_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,\n                         gzFile file) {\n    z_size_t len;\n    gz_statep state;\n\n    /* get internal structure and check that it's for reading */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return 0;\n\n    /* check that there was no (serious) error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)\n        return 0;\n    gz_error(state, Z_OK, NULL);\n\n    /* compute bytes to read -- error on overflow */\n    len = nitems * size;\n    if (size && len / size != nitems) {\n        gz_error(state, Z_STREAM_ERROR, \"request does not fit in a size_t\");\n        return 0;\n    }\n\n    /* read len or fewer bytes to buf, return the number of full items read */\n    return len ? gz_read(state, buf, len) / size : 0;\n}\n\n/* -- see zlib.h -- */\n#ifdef Z_PREFIX_SET\n#  undef z_gzgetc\n#else\n#  undef gzgetc\n#endif\nint ZEXPORT gzgetc(gzFile file) {\n    unsigned char buf[1];\n    gz_statep state;\n\n    /* get internal structure and check that it's for reading */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return -1;\n\n    /* check that there was no (serious) error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)\n        return -1;\n    gz_error(state, Z_OK, NULL);\n\n    /* try output buffer (no need to check for skip request) */\n    if (state->x.have) {\n        state->x.have--;\n        state->x.pos++;\n        return *(state->x.next)++;\n    }\n\n    /* nothing there -- try gz_read() */\n    return gz_read(state, buf, 1) < 1 ? -1 : buf[0];\n}\n\nint ZEXPORT gzgetc_(gzFile file) {\n    return gzgetc(file);\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzungetc(int c, gzFile file) {\n    gz_statep state;\n\n    /* get internal structure and check that it's for reading */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return -1;\n\n    /* in case this was just opened, set up the input buffer */\n    if (state->how == LOOK && state->x.have == 0)\n        (void)gz_look(state);\n\n    /* check that there was no (serious) error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)\n        return -1;\n    gz_error(state, Z_OK, NULL);\n\n    /* process a skip request */\n    if (state->skip && gz_skip(state) == -1)\n        return -1;\n\n    /* can't push EOF */\n    if (c < 0)\n        return -1;\n\n    /* if output buffer empty, put byte at end (allows more pushing) */\n    if (state->x.have == 0) {\n        state->x.have = 1;\n        state->x.next = state->out + (state->size << 1) - 1;\n        state->x.next[0] = (unsigned char)c;\n        state->x.pos--;\n        state->past = 0;\n        return c;\n    }\n\n    /* if no room, give up (must have already done a gzungetc()) */\n    if (state->x.have == (state->size << 1)) {\n        gz_error(state, Z_DATA_ERROR, \"out of room to push characters\");\n        return -1;\n    }\n\n    /* slide output data if needed and insert byte before existing data */\n    if (state->x.next == state->out) {\n        unsigned char *src = state->out + state->x.have;\n        unsigned char *dest = state->out + (state->size << 1);\n\n        while (src > state->out)\n            *--dest = *--src;\n        state->x.next = dest;\n    }\n    state->x.have++;\n    state->x.next--;\n    state->x.next[0] = (unsigned char)c;\n    state->x.pos--;\n    state->past = 0;\n    return c;\n}\n\n/* -- see zlib.h -- */\nchar * ZEXPORT gzgets(gzFile file, char *buf, int len) {\n    unsigned left, n;\n    char *str;\n    unsigned char *eol;\n    gz_statep state;\n\n    /* check parameters, get internal structure, and check that it's for\n       reading */\n    if (file == NULL || buf == NULL || len < 1)\n        return NULL;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return NULL;\n\n    /* check that there was no (serious) error */\n    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)\n        return NULL;\n    gz_error(state, Z_OK, NULL);\n\n    /* process a skip request */\n    if (state->skip && gz_skip(state) == -1)\n        return NULL;\n\n    /* copy output up to a new line, len-1 bytes, or there is no more output,\n       whichever comes first */\n    str = buf;\n    left = (unsigned)len - 1;\n    if (left) do {\n        /* assure that something is in the output buffer */\n        if (state->x.have == 0 && gz_fetch(state) == -1)\n            break;                      /* error */\n        if (state->x.have == 0) {       /* end of file */\n            state->past = 1;            /* read past end */\n            break;                      /* return what we have */\n        }\n\n        /* look for end-of-line in current output buffer */\n        n = state->x.have > left ? left : state->x.have;\n        eol = (unsigned char *)memchr(state->x.next, '\\n', n);\n        if (eol != NULL)\n            n = (unsigned)(eol - state->x.next) + 1;\n\n        /* copy through end-of-line, or remainder if not found */\n        memcpy(buf, state->x.next, n);\n        state->x.have -= n;\n        state->x.next += n;\n        state->x.pos += n;\n        left -= n;\n        buf += n;\n    } while (left && eol == NULL);\n\n    /* append a terminating zero to the string (we don't check for a zero in\n       the contents, let the user worry about that) -- return the terminated\n       string, or if nothing was read, NULL */\n    if (buf == str)\n        return NULL;\n    buf[0] = 0;\n    return str;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzdirect(gzFile file) {\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n\n    /* if the state is not known, but we can find out, then do so (this is\n       mainly for right after a gzopen() or gzdopen()) */\n    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)\n        (void)gz_look(state);\n\n    /* return 1 if transparent, 0 if processing a gzip stream */\n    return state->direct == 1;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzclose_r(gzFile file) {\n    int ret, err;\n    gz_statep state;\n\n    /* get internal structure and check that it's for reading */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n    if (state->mode != GZ_READ)\n        return Z_STREAM_ERROR;\n\n    /* free memory and close file */\n    if (state->size) {\n        inflateEnd(&(state->strm));\n        free(state->out);\n        free(state->in);\n    }\n    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;\n    gz_error(state, Z_OK, NULL);\n    free(state->path);\n    ret = close(state->fd);\n    free(state);\n    return ret ? Z_ERRNO : err;\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/gzwrite.c",
    "content": "/* gzwrite.c -- zlib functions for writing gzip files\n * Copyright (C) 2004-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"gzguts.h\"\n\n/* Initialize state for writing a gzip file.  Mark initialization by setting\n   state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on\n   success. */\nlocal int gz_init(gz_statep state) {\n    int ret;\n    z_streamp strm = &(state->strm);\n\n    /* allocate input buffer (double size for gzprintf) */\n    state->in = (unsigned char *)malloc(state->want << 1);\n    if (state->in == NULL) {\n        gz_error(state, Z_MEM_ERROR, \"out of memory\");\n        return -1;\n    }\n\n    /* only need output buffer and deflate state if compressing */\n    if (!state->direct) {\n        /* allocate output buffer */\n        state->out = (unsigned char *)malloc(state->want);\n        if (state->out == NULL) {\n            free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n\n        /* allocate deflate memory, set up for gzip compression */\n        strm->zalloc = Z_NULL;\n        strm->zfree = Z_NULL;\n        strm->opaque = Z_NULL;\n        ret = deflateInit2(strm, state->level, Z_DEFLATED,\n                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);\n        if (ret != Z_OK) {\n            free(state->out);\n            free(state->in);\n            gz_error(state, Z_MEM_ERROR, \"out of memory\");\n            return -1;\n        }\n        strm->next_in = NULL;\n    }\n\n    /* mark state as initialized */\n    state->size = state->want;\n\n    /* initialize write buffer if compressing */\n    if (!state->direct) {\n        strm->avail_out = state->size;\n        strm->next_out = state->out;\n        state->x.next = strm->next_out;\n    }\n    return 0;\n}\n\n/* Compress whatever is at avail_in and next_in and write to the output file.\n   Return -1 if there is an error writing to the output file or if gz_init()\n   fails to allocate memory, otherwise 0.  flush is assumed to be a valid\n   deflate() flush value.  If flush is Z_FINISH, then the deflate() state is\n   reset to start a new gzip stream.  If gz->direct is true, then simply write\n   to the output file without compressing, and ignore flush. */\nlocal int gz_comp(gz_statep state, int flush) {\n    int ret, writ;\n    unsigned have, put, max = ((unsigned)-1 >> 2) + 1;\n    z_streamp strm = &(state->strm);\n\n    /* allocate memory if this is the first time through */\n    if (state->size == 0 && gz_init(state) == -1)\n        return -1;\n\n    /* write directly if requested */\n    if (state->direct) {\n        while (strm->avail_in) {\n            errno = 0;\n            state->again = 0;\n            put = strm->avail_in > max ? max : strm->avail_in;\n            writ = (int)write(state->fd, strm->next_in, put);\n            if (writ < 0) {\n                if (errno == EAGAIN || errno == EWOULDBLOCK)\n                    state->again = 1;\n                gz_error(state, Z_ERRNO, zstrerror());\n                return -1;\n            }\n            strm->avail_in -= (unsigned)writ;\n            strm->next_in += writ;\n        }\n        return 0;\n    }\n\n    /* check for a pending reset */\n    if (state->reset) {\n        /* don't start a new gzip member unless there is data to write and\n           we're not flushing */\n        if (strm->avail_in == 0 && flush == Z_NO_FLUSH)\n            return 0;\n        deflateReset(strm);\n        state->reset = 0;\n    }\n\n    /* run deflate() on provided input until it produces no more output */\n    ret = Z_OK;\n    do {\n        /* write out current buffer contents if full, or if flushing, but if\n           doing Z_FINISH then don't write until we get to Z_STREAM_END */\n        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&\n            (flush != Z_FINISH || ret == Z_STREAM_END))) {\n            while (strm->next_out > state->x.next) {\n                errno = 0;\n                state->again = 0;\n                put = strm->next_out - state->x.next > (int)max ? max :\n                      (unsigned)(strm->next_out - state->x.next);\n                writ = (int)write(state->fd, state->x.next, put);\n                if (writ < 0) {\n                    if (errno == EAGAIN || errno == EWOULDBLOCK)\n                        state->again = 1;\n                    gz_error(state, Z_ERRNO, zstrerror());\n                    return -1;\n                }\n                state->x.next += writ;\n            }\n            if (strm->avail_out == 0) {\n                strm->avail_out = state->size;\n                strm->next_out = state->out;\n                state->x.next = state->out;\n            }\n        }\n\n        /* compress */\n        have = strm->avail_out;\n        ret = deflate(strm, flush);\n        if (ret == Z_STREAM_ERROR) {\n            gz_error(state, Z_STREAM_ERROR,\n                      \"internal error: deflate stream corrupt\");\n            return -1;\n        }\n        have -= strm->avail_out;\n    } while (have);\n\n    /* if that completed a deflate stream, allow another to start */\n    if (flush == Z_FINISH)\n        state->reset = 1;\n\n    /* all done, no errors */\n    return 0;\n}\n\n/* Compress state->skip (> 0) zeros to output.  Return -1 on a write error or\n   memory allocation failure by gz_comp(), or 0 on success. state->skip is\n   updated with the number of successfully written zeros, in case there is a\n   stall on a non-blocking write destination. */\nlocal int gz_zero(gz_statep state) {\n    int first, ret;\n    unsigned n;\n    z_streamp strm = &(state->strm);\n\n    /* consume whatever's left in the input buffer */\n    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n        return -1;\n\n    /* compress state->skip zeros */\n    first = 1;\n    do {\n        n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ?\n            (unsigned)state->skip : state->size;\n        if (first) {\n            memset(state->in, 0, n);\n            first = 0;\n        }\n        strm->avail_in = n;\n        strm->next_in = state->in;\n        ret = gz_comp(state, Z_NO_FLUSH);\n        n -= strm->avail_in;\n        state->x.pos += n;\n        state->skip -= n;\n        if (ret == -1)\n            return -1;\n    } while (state->skip);\n    return 0;\n}\n\n/* Write len bytes from buf to file.  Return the number of bytes written.  If\n   the returned value is less than len, then there was an error. If the error\n   was a non-blocking stall, then the number of bytes consumed is returned.\n   For any other error, 0 is returned. */\nlocal z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {\n    z_size_t put = len;\n    int ret;\n\n    /* if len is zero, avoid unnecessary operations */\n    if (len == 0)\n        return 0;\n\n    /* allocate memory if this is the first time through */\n    if (state->size == 0 && gz_init(state) == -1)\n        return 0;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return 0;\n\n    /* for small len, copy to input buffer, otherwise compress directly */\n    if (len < state->size) {\n        /* copy to input buffer, compress when full */\n        for (;;) {\n            unsigned have, copy;\n\n            if (state->strm.avail_in == 0)\n                state->strm.next_in = state->in;\n            have = (unsigned)((state->strm.next_in + state->strm.avail_in) -\n                              state->in);\n            copy = state->size - have;\n            if (copy > len)\n                copy = (unsigned)len;\n            memcpy(state->in + have, buf, copy);\n            state->strm.avail_in += copy;\n            state->x.pos += copy;\n            buf = (const char *)buf + copy;\n            len -= copy;\n            if (len == 0)\n                break;\n            if (gz_comp(state, Z_NO_FLUSH) == -1)\n                return state->again ? put - len : 0;\n        }\n    }\n    else {\n        /* consume whatever's left in the input buffer */\n        if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)\n            return 0;\n\n        /* directly compress user buffer to file */\n        state->strm.next_in = (z_const Bytef *)buf;\n        do {\n            unsigned n = (unsigned)-1;\n\n            if (n > len)\n                n = (unsigned)len;\n            state->strm.avail_in = n;\n            ret = gz_comp(state, Z_NO_FLUSH);\n            n -= state->strm.avail_in;\n            state->x.pos += n;\n            len -= n;\n            if (ret == -1)\n                return state->again ? put - len : 0;\n        } while (len);\n    }\n\n    /* input was all buffered or compressed */\n    return put;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return 0;\n    gz_error(state, Z_OK, NULL);\n\n    /* since an int is returned, make sure len fits in one, otherwise return\n       with an error (this avoids a flaw in the interface) */\n    if ((int)len < 0) {\n        gz_error(state, Z_DATA_ERROR, \"requested length does not fit in int\");\n        return 0;\n    }\n\n    /* write len bytes from buf (the return value will fit in an int) */\n    return (int)gz_write(state, buf, len);\n}\n\n/* -- see zlib.h -- */\nz_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,\n                          gzFile file) {\n    z_size_t len;\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return 0;\n    state = (gz_statep)file;\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return 0;\n    gz_error(state, Z_OK, NULL);\n\n    /* compute bytes to read -- error on overflow */\n    len = nitems * size;\n    if (size && len / size != nitems) {\n        gz_error(state, Z_STREAM_ERROR, \"request does not fit in a size_t\");\n        return 0;\n    }\n\n    /* write len bytes to buf, return the number of full items written */\n    return len ? gz_write(state, buf, len) / size : 0;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzputc(gzFile file, int c) {\n    unsigned have;\n    unsigned char buf[1];\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return -1;\n    gz_error(state, Z_OK, NULL);\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return -1;\n\n    /* try writing to input buffer for speed (state->size == 0 if buffer not\n       initialized) */\n    if (state->size) {\n        if (strm->avail_in == 0)\n            strm->next_in = state->in;\n        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);\n        if (have < state->size) {\n            state->in[have] = (unsigned char)c;\n            strm->avail_in++;\n            state->x.pos++;\n            return c & 0xff;\n        }\n    }\n\n    /* no room in buffer or not initialized, use gz_write() */\n    buf[0] = (unsigned char)c;\n    if (gz_write(state, buf, 1) != 1)\n        return -1;\n    return c & 0xff;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzputs(gzFile file, const char *s) {\n    z_size_t len, put;\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return -1;\n    state = (gz_statep)file;\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return -1;\n    gz_error(state, Z_OK, NULL);\n\n    /* write string */\n    len = strlen(s);\n    if ((int)len < 0 || (unsigned)len != len) {\n        gz_error(state, Z_STREAM_ERROR, \"string length does not fit in int\");\n        return -1;\n    }\n    put = gz_write(state, s, len);\n    return len && put == 0 ? -1 : (int)put;\n}\n\n#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \\\n     (defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \\\n    defined(ZLIB_INSECURE)\n/* If the second half of the input buffer is occupied, write out the contents.\n   If there is any input remaining due to a non-blocking stall on write, move\n   it to the start of the buffer. Return true if this did not open up the\n   second half of the buffer.  state->err should be checked after this to\n   handle a gz_comp() error. */\nlocal int gz_vacate(gz_statep state) {\n    z_streamp strm;\n\n    strm = &(state->strm);\n    if (strm->next_in + strm->avail_in <= state->in + state->size)\n        return 0;\n    (void)gz_comp(state, Z_NO_FLUSH);\n    if (strm->avail_in == 0) {\n        strm->next_in = state->in;\n        return 0;\n    }\n    memmove(state->in, strm->next_in, strm->avail_in);\n    strm->next_in = state->in;\n    return strm->avail_in > state->size;\n}\n#endif\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#include <stdarg.h>\n\n/* -- see zlib.h -- */\nint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {\n#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE)\n#warning \"vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR\"\n#warning \"you can recompile with ZLIB_INSECURE defined to use vsprintf()\"\n    /* prevent use of insecure vsprintf(), unless purposefully requested */\n    (void)file, (void)format, (void)va;\n    return Z_STREAM_ERROR;\n#else\n    int len, ret;\n    char *next;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return Z_STREAM_ERROR;\n    gz_error(state, Z_OK, NULL);\n\n    /* make sure we have some buffer space */\n    if (state->size == 0 && gz_init(state) == -1)\n        return state->err;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return state->err;\n\n    /* do the printf() into the input buffer, put length in len -- the input\n       buffer is double-sized just for this function, so there should be\n       state->size bytes available after the current contents */\n    ret = gz_vacate(state);\n    if (state->err) {\n        if (ret && state->again) {\n            /* There was a non-blocking stall on write, resulting in the part\n               of the second half of the output buffer being occupied.  Return\n               a Z_BUF_ERROR to let the application know that this gzprintf()\n               needs to be retried. */\n            gz_error(state, Z_BUF_ERROR, \"stalled write on gzprintf\");\n        }\n        if (!state->again)\n            return state->err;\n    }\n    if (strm->avail_in == 0)\n        strm->next_in = state->in;\n    next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);\n    next[state->size - 1] = 0;\n#ifdef NO_vsnprintf\n#  ifdef HAS_vsprintf_void\n    (void)vsprintf(next, format, va);\n    for (len = 0; len < state->size; len++)\n        if (next[len] == 0) break;\n#  else\n    len = vsprintf(next, format, va);\n#  endif\n#else\n#  ifdef HAS_vsnprintf_void\n    (void)vsnprintf(next, state->size, format, va);\n    len = strlen(next);\n#  else\n    len = vsnprintf(next, state->size, format, va);\n#  endif\n#endif\n\n    /* check that printf() results fit in buffer */\n    if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)\n        return 0;\n\n    /* update buffer and position */\n    strm->avail_in += (unsigned)len;\n    state->x.pos += len;\n\n    /* write out buffer if more than half is occupied */\n    ret = gz_vacate(state);\n    if (state->err && !state->again)\n        return state->err;\n    return len;\n#endif\n}\n\nint ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {\n    va_list va;\n    int ret;\n\n    va_start(va, format);\n    ret = gzvprintf(file, format, va);\n    va_end(va);\n    return ret;\n}\n\n#else /* !STDC && !Z_HAVE_STDARG_H */\n\n/* -- see zlib.h -- */\nint ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,\n                       int a4, int a5, int a6, int a7, int a8, int a9, int a10,\n                       int a11, int a12, int a13, int a14, int a15, int a16,\n                       int a17, int a18, int a19, int a20) {\n#if defined(NO_snprintf) && !defined(ZLIB_INSECURE)\n#warning \"snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR\"\n#warning \"you can recompile with ZLIB_INSECURE defined to use sprintf()\"\n    /* prevent use of insecure sprintf(), unless purposefully requested */\n    (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5,\n    (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12,\n    (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18,\n    (void)a19, (void)a20;\n    return Z_STREAM_ERROR;\n#else\n    int ret;\n    unsigned len, left;\n    char *next;\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that can really pass pointer in ints */\n    if (sizeof(int) != sizeof(void *))\n        return Z_STREAM_ERROR;\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return Z_STREAM_ERROR;\n    gz_error(state, Z_OK, NULL);\n\n    /* make sure we have some buffer space */\n    if (state->size == 0 && gz_init(state) == -1)\n        return state->err;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return state->err;\n\n    /* do the printf() into the input buffer, put length in len -- the input\n       buffer is double-sized just for this function, so there is guaranteed to\n       be state->size bytes available after the current contents */\n    ret = gz_vacate(state);\n    if (state->err) {\n        if (ret && state->again) {\n            /* There was a non-blocking stall on write, resulting in the part\n               of the second half of the output buffer being occupied.  Return\n               a Z_BUF_ERROR to let the application know that this gzprintf()\n               needs to be retried. */\n            gz_error(state, Z_BUF_ERROR, \"stalled write on gzprintf\");\n        }\n        if (!state->again)\n            return state->err;\n    }\n    if (strm->avail_in == 0)\n        strm->next_in = state->in;\n    next = (char *)(strm->next_in + strm->avail_in);\n    next[state->size - 1] = 0;\n#ifdef NO_snprintf\n#  ifdef HAS_sprintf_void\n    sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,\n            a13, a14, a15, a16, a17, a18, a19, a20);\n    for (len = 0; len < size; len++)\n        if (next[len] == 0)\n            break;\n#  else\n    len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,\n                  a12, a13, a14, a15, a16, a17, a18, a19, a20);\n#  endif\n#else\n#  ifdef HAS_snprintf_void\n    snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,\n             a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);\n    len = strlen(next);\n#  else\n    len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,\n                   a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);\n#  endif\n#endif\n\n    /* check that printf() results fit in buffer */\n    if (len == 0 || len >= state->size || next[state->size - 1] != 0)\n        return 0;\n\n    /* update buffer and position, compress first half if past that */\n    strm->avail_in += len;\n    state->x.pos += len;\n\n    /* write out buffer if more than half is occupied */\n    ret = gz_vacate(state);\n    if (state->err && !state->again)\n        return state->err;\n    return (int)len;\n#endif\n}\n\n#endif\n\n/* -- see zlib.h -- */\nint ZEXPORT gzflush(gzFile file, int flush) {\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    /* check that we're writing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))\n        return Z_STREAM_ERROR;\n    gz_error(state, Z_OK, NULL);\n\n    /* check flush parameter */\n    if (flush < 0 || flush > Z_FINISH)\n        return Z_STREAM_ERROR;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return state->err;\n\n    /* compress remaining data with requested flush */\n    (void)gz_comp(state, flush);\n    return state->err;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzsetparams(gzFile file, int level, int strategy) {\n    gz_statep state;\n    z_streamp strm;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n    strm = &(state->strm);\n\n    /* check that we're compressing and that there's no (serious) error */\n    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) ||\n            state->direct)\n        return Z_STREAM_ERROR;\n    gz_error(state, Z_OK, NULL);\n\n    /* if no change is requested, then do nothing */\n    if (level == state->level && strategy == state->strategy)\n        return Z_OK;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        return state->err;\n\n    /* change compression parameters for subsequent input */\n    if (state->size) {\n        /* flush previous input with previous parameters before changing */\n        if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)\n            return state->err;\n        deflateParams(strm, level, strategy);\n    }\n    state->level = level;\n    state->strategy = strategy;\n    return Z_OK;\n}\n\n/* -- see zlib.h -- */\nint ZEXPORT gzclose_w(gzFile file) {\n    int ret = Z_OK;\n    gz_statep state;\n\n    /* get internal structure */\n    if (file == NULL)\n        return Z_STREAM_ERROR;\n    state = (gz_statep)file;\n\n    /* check that we're writing */\n    if (state->mode != GZ_WRITE)\n        return Z_STREAM_ERROR;\n\n    /* check for seek request */\n    if (state->skip && gz_zero(state) == -1)\n        ret = state->err;\n\n    /* flush, free memory, and close file */\n    if (gz_comp(state, Z_FINISH) == -1)\n        ret = state->err;\n    if (state->size) {\n        if (!state->direct) {\n            (void)deflateEnd(&(state->strm));\n            free(state->out);\n        }\n        free(state->in);\n    }\n    gz_error(state, Z_OK, NULL);\n    free(state->path);\n    if (close(state->fd) == -1)\n        ret = Z_ERRNO;\n    free(state);\n    return ret;\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/infback.c",
    "content": "/* infback.c -- inflate using a call-back interface\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n   This code is largely copied from inflate.c.  Normally either infback.o or\n   inflate.o would be linked into an application--not both.  The interface\n   with inffast.c is retained so that optimized assembler-coded versions of\n   inflate_fast() can be used with either inflate.c or infback.c.\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n/*\n   strm provides memory allocation functions in zalloc and zfree, or\n   Z_NULL to use the library memory allocation functions.\n\n   windowBits is in the range 8..15, and window is a user-supplied\n   window and output buffer that is 2**windowBits bytes.\n */\nint ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,\n                             unsigned char FAR *window, const char *version,\n                             int stream_size) {\n    struct inflate_state FAR *state;\n\n    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||\n        stream_size != (int)(sizeof(z_stream)))\n        return Z_VERSION_ERROR;\n    if (strm == Z_NULL || window == Z_NULL ||\n        windowBits < 8 || windowBits > 15)\n        return Z_STREAM_ERROR;\n    strm->msg = Z_NULL;                 /* in case we return an error */\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zfree = zcfree;\n#endif\n    state = (struct inflate_state FAR *)ZALLOC(strm, 1,\n                                               sizeof(struct inflate_state));\n    if (state == Z_NULL) return Z_MEM_ERROR;\n    Tracev((stderr, \"inflate: allocated\\n\"));\n    strm->state = (struct internal_state FAR *)state;\n    state->dmax = 32768U;\n    state->wbits = (uInt)windowBits;\n    state->wsize = 1U << windowBits;\n    state->window = window;\n    state->wnext = 0;\n    state->whave = 0;\n    state->sane = 1;\n    return Z_OK;\n}\n\n/* Macros for inflateBack(): */\n\n/* Load returned state from inflate_fast() */\n#define LOAD() \\\n    do { \\\n        put = strm->next_out; \\\n        left = strm->avail_out; \\\n        next = strm->next_in; \\\n        have = strm->avail_in; \\\n        hold = state->hold; \\\n        bits = state->bits; \\\n    } while (0)\n\n/* Set state from registers for inflate_fast() */\n#define RESTORE() \\\n    do { \\\n        strm->next_out = put; \\\n        strm->avail_out = left; \\\n        strm->next_in = next; \\\n        strm->avail_in = have; \\\n        state->hold = hold; \\\n        state->bits = bits; \\\n    } while (0)\n\n/* Clear the input bit accumulator */\n#define INITBITS() \\\n    do { \\\n        hold = 0; \\\n        bits = 0; \\\n    } while (0)\n\n/* Assure that some input is available.  If input is requested, but denied,\n   then return a Z_BUF_ERROR from inflateBack(). */\n#define PULL() \\\n    do { \\\n        if (have == 0) { \\\n            have = in(in_desc, &next); \\\n            if (have == 0) { \\\n                next = Z_NULL; \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/* Get a byte of input into the bit accumulator, or return from inflateBack()\n   with an error if there is no input available. */\n#define PULLBYTE() \\\n    do { \\\n        PULL(); \\\n        have--; \\\n        hold += (unsigned long)(*next++) << bits; \\\n        bits += 8; \\\n    } while (0)\n\n/* Assure that there are at least n bits in the bit accumulator.  If there is\n   not enough available input to do that, then return from inflateBack() with\n   an error. */\n#define NEEDBITS(n) \\\n    do { \\\n        while (bits < (unsigned)(n)) \\\n            PULLBYTE(); \\\n    } while (0)\n\n/* Return the low n bits of the bit accumulator (n < 16) */\n#define BITS(n) \\\n    ((unsigned)hold & ((1U << (n)) - 1))\n\n/* Remove n bits from the bit accumulator */\n#define DROPBITS(n) \\\n    do { \\\n        hold >>= (n); \\\n        bits -= (unsigned)(n); \\\n    } while (0)\n\n/* Remove zero to seven bits as needed to go to a byte boundary */\n#define BYTEBITS() \\\n    do { \\\n        hold >>= bits & 7; \\\n        bits -= bits & 7; \\\n    } while (0)\n\n/* Assure that some output space is available, by writing out the window\n   if it's full.  If the write fails, return from inflateBack() with a\n   Z_BUF_ERROR. */\n#define ROOM() \\\n    do { \\\n        if (left == 0) { \\\n            put = state->window; \\\n            left = state->wsize; \\\n            state->whave = left; \\\n            if (out(out_desc, put, left)) { \\\n                ret = Z_BUF_ERROR; \\\n                goto inf_leave; \\\n            } \\\n        } \\\n    } while (0)\n\n/*\n   strm provides the memory allocation functions and window buffer on input,\n   and provides information on the unused input on return.  For Z_DATA_ERROR\n   returns, strm will also provide an error message.\n\n   in() and out() are the call-back input and output functions.  When\n   inflateBack() needs more input, it calls in().  When inflateBack() has\n   filled the window with output, or when it completes with data in the\n   window, it calls out() to write out the data.  The application must not\n   change the provided input until in() is called again or inflateBack()\n   returns.  The application must not change the window/output buffer until\n   inflateBack() returns.\n\n   in() and out() are called with a descriptor parameter provided in the\n   inflateBack() call.  This parameter can be a structure that provides the\n   information required to do the read or write, as well as accumulated\n   information on the input and output such as totals and check values.\n\n   in() should return zero on failure.  out() should return non-zero on\n   failure.  If either in() or out() fails, than inflateBack() returns a\n   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it\n   was in() or out() that caused in the error.  Otherwise,  inflateBack()\n   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format\n   error, or Z_MEM_ERROR if it could not allocate memory for the state.\n   inflateBack() can also return Z_STREAM_ERROR if the input parameters\n   are not correct, i.e. strm is Z_NULL or the state was not initialized.\n */\nint ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,\n                        out_func out, void FAR *out_desc) {\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *next;    /* next input */\n    unsigned char FAR *put;     /* next output */\n    unsigned have, left;        /* available input and output */\n    unsigned long hold;         /* bit buffer */\n    unsigned bits;              /* bits in bit buffer */\n    unsigned copy;              /* number of stored or match bytes to copy */\n    unsigned char FAR *from;    /* where to copy match bytes from */\n    code here;                  /* current decoding table entry */\n    code last;                  /* parent table entry */\n    unsigned len;               /* length to copy for repeats, bits to drop */\n    int ret;                    /* return code */\n    static const unsigned short order[19] = /* permutation of code lengths */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n\n    /* Check that the strm exists and that the state was initialized */\n    if (strm == Z_NULL || strm->state == Z_NULL)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* Reset the state */\n    strm->msg = Z_NULL;\n    state->mode = TYPE;\n    state->last = 0;\n    state->whave = 0;\n    next = strm->next_in;\n    have = next != Z_NULL ? strm->avail_in : 0;\n    hold = 0;\n    bits = 0;\n    put = state->window;\n    left = state->wsize;\n\n    /* Inflate until end of block marked as last */\n    for (;;)\n        switch (state->mode) {\n        case TYPE:\n            /* determine and dispatch block type */\n            if (state->last) {\n                BYTEBITS();\n                state->mode = DONE;\n                break;\n            }\n            NEEDBITS(3);\n            state->last = BITS(1);\n            DROPBITS(1);\n            switch (BITS(2)) {\n            case 0:                             /* stored block */\n                Tracev((stderr, \"inflate:     stored block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = STORED;\n                break;\n            case 1:                             /* fixed block */\n                inflate_fixed(state);\n                Tracev((stderr, \"inflate:     fixed codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = LEN;              /* decode codes */\n                break;\n            case 2:                             /* dynamic block */\n                Tracev((stderr, \"inflate:     dynamic codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = TABLE;\n                break;\n            default:\n                strm->msg = (z_const char *)\"invalid block type\";\n                state->mode = BAD;\n            }\n            DROPBITS(2);\n            break;\n\n        case STORED:\n            /* get and verify stored block length */\n            BYTEBITS();                         /* go to byte boundary */\n            NEEDBITS(32);\n            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {\n                strm->msg = (z_const char *)\"invalid stored block lengths\";\n                state->mode = BAD;\n                break;\n            }\n            state->length = (unsigned)hold & 0xffff;\n            Tracev((stderr, \"inflate:       stored length %u\\n\",\n                    state->length));\n            INITBITS();\n\n            /* copy stored block from input to output */\n            while (state->length != 0) {\n                copy = state->length;\n                PULL();\n                ROOM();\n                if (copy > have) copy = have;\n                if (copy > left) copy = left;\n                zmemcpy(put, next, copy);\n                have -= copy;\n                next += copy;\n                left -= copy;\n                put += copy;\n                state->length -= copy;\n            }\n            Tracev((stderr, \"inflate:       stored end\\n\"));\n            state->mode = TYPE;\n            break;\n\n        case TABLE:\n            /* get dynamic table entries descriptor */\n            NEEDBITS(14);\n            state->nlen = BITS(5) + 257;\n            DROPBITS(5);\n            state->ndist = BITS(5) + 1;\n            DROPBITS(5);\n            state->ncode = BITS(4) + 4;\n            DROPBITS(4);\n#ifndef PKZIP_BUG_WORKAROUND\n            if (state->nlen > 286 || state->ndist > 30) {\n                strm->msg = (z_const char *)\n                    \"too many length or distance symbols\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracev((stderr, \"inflate:       table sizes ok\\n\"));\n\n            /* get code length code lengths (not a typo) */\n            state->have = 0;\n            while (state->have < state->ncode) {\n                NEEDBITS(3);\n                state->lens[order[state->have++]] = (unsigned short)BITS(3);\n                DROPBITS(3);\n            }\n            while (state->have < 19)\n                state->lens[order[state->have++]] = 0;\n            state->next = state->codes;\n            state->lencode = (code const FAR *)(state->next);\n            state->lenbits = 7;\n            ret = inflate_table(CODES, state->lens, 19, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid code lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       code lengths ok\\n\"));\n\n            /* get length and distance code code lengths */\n            state->have = 0;\n            while (state->have < state->nlen + state->ndist) {\n                for (;;) {\n                    here = state->lencode[BITS(state->lenbits)];\n                    if ((unsigned)(here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                if (here.val < 16) {\n                    DROPBITS(here.bits);\n                    state->lens[state->have++] = here.val;\n                }\n                else {\n                    if (here.val == 16) {\n                        NEEDBITS(here.bits + 2);\n                        DROPBITS(here.bits);\n                        if (state->have == 0) {\n                            strm->msg = (z_const char *)\n                                \"invalid bit length repeat\";\n                            state->mode = BAD;\n                            break;\n                        }\n                        len = (unsigned)(state->lens[state->have - 1]);\n                        copy = 3 + BITS(2);\n                        DROPBITS(2);\n                    }\n                    else if (here.val == 17) {\n                        NEEDBITS(here.bits + 3);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 3 + BITS(3);\n                        DROPBITS(3);\n                    }\n                    else {\n                        NEEDBITS(here.bits + 7);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 11 + BITS(7);\n                        DROPBITS(7);\n                    }\n                    if (state->have + copy > state->nlen + state->ndist) {\n                        strm->msg = (z_const char *)\n                            \"invalid bit length repeat\";\n                        state->mode = BAD;\n                        break;\n                    }\n                    while (copy--)\n                        state->lens[state->have++] = (unsigned short)len;\n                }\n            }\n\n            /* handle error breaks in while */\n            if (state->mode == BAD) break;\n\n            /* check for end-of-block code (better have one) */\n            if (state->lens[256] == 0) {\n                strm->msg = (z_const char *)\n                    \"invalid code -- missing end-of-block\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* build code tables -- note: do not change the lenbits or distbits\n               values here (9 and 6) without reading the comments in inftrees.h\n               concerning the ENOUGH constants, which depend on those values */\n            state->next = state->codes;\n            state->lencode = (code const FAR *)(state->next);\n            state->lenbits = 9;\n            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid literal/lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            state->distcode = (code const FAR *)(state->next);\n            state->distbits = 6;\n            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,\n                            &(state->next), &(state->distbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid distances set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       codes ok\\n\"));\n            state->mode = LEN;\n                /* fallthrough */\n\n        case LEN:\n            /* use inflate_fast() if we have enough input and output */\n            if (have >= 6 && left >= 258) {\n                RESTORE();\n                if (state->whave < state->wsize)\n                    state->whave = state->wsize - left;\n                inflate_fast(strm, state->wsize);\n                LOAD();\n                break;\n            }\n\n            /* get a literal, length, or end-of-block code */\n            for (;;) {\n                here = state->lencode[BITS(state->lenbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if (here.op && (here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->lencode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            state->length = (unsigned)here.val;\n\n            /* process literal */\n            if (here.op == 0) {\n                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                        \"inflate:         literal '%c'\\n\" :\n                        \"inflate:         literal 0x%02x\\n\", here.val));\n                ROOM();\n                *put++ = (unsigned char)(state->length);\n                left--;\n                state->mode = LEN;\n                break;\n            }\n\n            /* process end of block */\n            if (here.op & 32) {\n                Tracevv((stderr, \"inflate:         end of block\\n\"));\n                state->mode = TYPE;\n                break;\n            }\n\n            /* invalid code */\n            if (here.op & 64) {\n                strm->msg = (z_const char *)\"invalid literal/length code\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* length code -- get extra bits, if any */\n            state->extra = (unsigned)(here.op) & 15;\n            if (state->extra != 0) {\n                NEEDBITS(state->extra);\n                state->length += BITS(state->extra);\n                DROPBITS(state->extra);\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", state->length));\n\n            /* get distance code */\n            for (;;) {\n                here = state->distcode[BITS(state->distbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if ((here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->distcode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n            }\n            DROPBITS(here.bits);\n            if (here.op & 64) {\n                strm->msg = (z_const char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n            state->offset = (unsigned)here.val;\n\n            /* get distance extra bits, if any */\n            state->extra = (unsigned)(here.op) & 15;\n            if (state->extra != 0) {\n                NEEDBITS(state->extra);\n                state->offset += BITS(state->extra);\n                DROPBITS(state->extra);\n            }\n            if (state->offset > state->wsize - (state->whave < state->wsize ?\n                                                left : 0)) {\n                strm->msg = (z_const char *)\"invalid distance too far back\";\n                state->mode = BAD;\n                break;\n            }\n            Tracevv((stderr, \"inflate:         distance %u\\n\", state->offset));\n\n            /* copy match from window to output */\n            do {\n                ROOM();\n                copy = state->wsize - state->offset;\n                if (copy < left) {\n                    from = put + copy;\n                    copy = left - copy;\n                }\n                else {\n                    from = put - state->offset;\n                    copy = left;\n                }\n                if (copy > state->length) copy = state->length;\n                state->length -= copy;\n                left -= copy;\n                do {\n                    *put++ = *from++;\n                } while (--copy);\n            } while (state->length != 0);\n            break;\n\n        case DONE:\n            /* inflate stream terminated properly */\n            ret = Z_STREAM_END;\n            goto inf_leave;\n\n        case BAD:\n            ret = Z_DATA_ERROR;\n            goto inf_leave;\n\n        default:\n            /* can't happen, but makes compilers happy */\n            ret = Z_STREAM_ERROR;\n            goto inf_leave;\n        }\n\n    /* Write leftover output and return unused input */\n  inf_leave:\n    if (left < state->wsize) {\n        if (out(out_desc, state->window, state->wsize - left) &&\n            ret == Z_STREAM_END)\n            ret = Z_BUF_ERROR;\n    }\n    strm->next_in = next;\n    strm->avail_in = have;\n    return ret;\n}\n\nint ZEXPORT inflateBackEnd(z_streamp strm) {\n    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)\n        return Z_STREAM_ERROR;\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n    Tracev((stderr, \"inflate: end\\n\"));\n    return Z_OK;\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inffast.c",
    "content": "/* inffast.c -- fast decoding\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\n#ifdef ASMINF\n#  pragma message(\"Assembler code may have bugs -- use at your own risk\")\n#else\n\n/*\n   Decode literal, length, and distance codes and write out the resulting\n   literal and match bytes until either not enough input or output is\n   available, an end-of-block is encountered, or a data error is encountered.\n   When large enough input and output buffers are supplied to inflate(), for\n   example, a 16K input buffer and a 64K output buffer, more than 95% of the\n   inflate execution time is spent in this routine.\n\n   Entry assumptions:\n\n        state->mode == LEN\n        strm->avail_in >= 6\n        strm->avail_out >= 258\n        start >= strm->avail_out\n        state->bits < 8\n\n   On return, state->mode is one of:\n\n        LEN -- ran out of enough output space or enough available input\n        TYPE -- reached end of block code, inflate() to interpret next block\n        BAD -- error in block data\n\n   Notes:\n\n    - The maximum input bits used by a length/distance pair is 15 bits for the\n      length code, 5 bits for the length extra, 15 bits for the distance code,\n      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.\n      Therefore if strm->avail_in >= 6, then there is enough input to avoid\n      checking for available input while decoding.\n\n    - The maximum bytes that a single length/distance pair can output is 258\n      bytes, which is the maximum length that can be coded.  inflate_fast()\n      requires strm->avail_out >= 258 for each loop to avoid checking for\n      output space.\n */\nvoid ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *in;      /* local strm->next_in */\n    z_const unsigned char FAR *last;    /* have enough input while in < last */\n    unsigned char FAR *out;     /* local strm->next_out */\n    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */\n    unsigned char FAR *end;     /* while out < end, enough space available */\n#ifdef INFLATE_STRICT\n    unsigned dmax;              /* maximum distance from zlib header */\n#endif\n    unsigned wsize;             /* window size or zero if not using window */\n    unsigned whave;             /* valid bytes in the window */\n    unsigned wnext;             /* window write index */\n    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */\n    unsigned long hold;         /* local strm->hold */\n    unsigned bits;              /* local strm->bits */\n    code const FAR *lcode;      /* local strm->lencode */\n    code const FAR *dcode;      /* local strm->distcode */\n    unsigned lmask;             /* mask for first level of length codes */\n    unsigned dmask;             /* mask for first level of distance codes */\n    code const *here;           /* retrieved table entry */\n    unsigned op;                /* code bits, operation, extra bits, or */\n                                /*  window position, window bytes to copy */\n    unsigned len;               /* match length, unused bytes */\n    unsigned dist;              /* match distance */\n    unsigned char FAR *from;    /* where to copy match from */\n\n    /* copy state to local variables */\n    state = (struct inflate_state FAR *)strm->state;\n    in = strm->next_in;\n    last = in + (strm->avail_in - 5);\n    out = strm->next_out;\n    beg = out - (start - strm->avail_out);\n    end = out + (strm->avail_out - 257);\n#ifdef INFLATE_STRICT\n    dmax = state->dmax;\n#endif\n    wsize = state->wsize;\n    whave = state->whave;\n    wnext = state->wnext;\n    window = state->window;\n    hold = state->hold;\n    bits = state->bits;\n    lcode = state->lencode;\n    dcode = state->distcode;\n    lmask = (1U << state->lenbits) - 1;\n    dmask = (1U << state->distbits) - 1;\n\n    /* decode literals and length/distances until end-of-block or not enough\n       input data or output space */\n    do {\n        if (bits < 15) {\n            hold += (unsigned long)(*in++) << bits;\n            bits += 8;\n            hold += (unsigned long)(*in++) << bits;\n            bits += 8;\n        }\n        here = lcode + (hold & lmask);\n      dolen:\n        op = (unsigned)(here->bits);\n        hold >>= op;\n        bits -= op;\n        op = (unsigned)(here->op);\n        if (op == 0) {                          /* literal */\n            Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?\n                    \"inflate:         literal '%c'\\n\" :\n                    \"inflate:         literal 0x%02x\\n\", here->val));\n            *out++ = (unsigned char)(here->val);\n        }\n        else if (op & 16) {                     /* length base */\n            len = (unsigned)(here->val);\n            op &= 15;                           /* number of extra bits */\n            if (op) {\n                if (bits < op) {\n                    hold += (unsigned long)(*in++) << bits;\n                    bits += 8;\n                }\n                len += (unsigned)hold & ((1U << op) - 1);\n                hold >>= op;\n                bits -= op;\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", len));\n            if (bits < 15) {\n                hold += (unsigned long)(*in++) << bits;\n                bits += 8;\n                hold += (unsigned long)(*in++) << bits;\n                bits += 8;\n            }\n            here = dcode + (hold & dmask);\n          dodist:\n            op = (unsigned)(here->bits);\n            hold >>= op;\n            bits -= op;\n            op = (unsigned)(here->op);\n            if (op & 16) {                      /* distance base */\n                dist = (unsigned)(here->val);\n                op &= 15;                       /* number of extra bits */\n                if (bits < op) {\n                    hold += (unsigned long)(*in++) << bits;\n                    bits += 8;\n                    if (bits < op) {\n                        hold += (unsigned long)(*in++) << bits;\n                        bits += 8;\n                    }\n                }\n                dist += (unsigned)hold & ((1U << op) - 1);\n#ifdef INFLATE_STRICT\n                if (dist > dmax) {\n                    strm->msg = (z_const char *)\n                        \"invalid distance too far back\";\n                    state->mode = BAD;\n                    break;\n                }\n#endif\n                hold >>= op;\n                bits -= op;\n                Tracevv((stderr, \"inflate:         distance %u\\n\", dist));\n                op = (unsigned)(out - beg);     /* max distance in output */\n                if (dist > op) {                /* see if copy from window */\n                    op = dist - op;             /* distance back in window */\n                    if (op > whave) {\n                        if (state->sane) {\n                            strm->msg = (z_const char *)\n                                \"invalid distance too far back\";\n                            state->mode = BAD;\n                            break;\n                        }\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n                        if (len <= op - whave) {\n                            do {\n                                *out++ = 0;\n                            } while (--len);\n                            continue;\n                        }\n                        len -= op - whave;\n                        do {\n                            *out++ = 0;\n                        } while (--op > whave);\n                        if (op == 0) {\n                            from = out - dist;\n                            do {\n                                *out++ = *from++;\n                            } while (--len);\n                            continue;\n                        }\n#endif\n                    }\n                    from = window;\n                    if (wnext == 0) {           /* very common case */\n                        from += wsize - op;\n                        if (op < len) {         /* some from window */\n                            len -= op;\n                            do {\n                                *out++ = *from++;\n                            } while (--op);\n                            from = out - dist;  /* rest from output */\n                        }\n                    }\n                    else if (wnext < op) {      /* wrap around window */\n                        from += wsize + wnext - op;\n                        op -= wnext;\n                        if (op < len) {         /* some from end of window */\n                            len -= op;\n                            do {\n                                *out++ = *from++;\n                            } while (--op);\n                            from = window;\n                            if (wnext < len) {  /* some from start of window */\n                                op = wnext;\n                                len -= op;\n                                do {\n                                    *out++ = *from++;\n                                } while (--op);\n                                from = out - dist;      /* rest from output */\n                            }\n                        }\n                    }\n                    else {                      /* contiguous in window */\n                        from += wnext - op;\n                        if (op < len) {         /* some from window */\n                            len -= op;\n                            do {\n                                *out++ = *from++;\n                            } while (--op);\n                            from = out - dist;  /* rest from output */\n                        }\n                    }\n                    while (len > 2) {\n                        *out++ = *from++;\n                        *out++ = *from++;\n                        *out++ = *from++;\n                        len -= 3;\n                    }\n                    if (len) {\n                        *out++ = *from++;\n                        if (len > 1)\n                            *out++ = *from++;\n                    }\n                }\n                else {\n                    from = out - dist;          /* copy direct from output */\n                    do {                        /* minimum length is three */\n                        *out++ = *from++;\n                        *out++ = *from++;\n                        *out++ = *from++;\n                        len -= 3;\n                    } while (len > 2);\n                    if (len) {\n                        *out++ = *from++;\n                        if (len > 1)\n                            *out++ = *from++;\n                    }\n                }\n            }\n            else if ((op & 64) == 0) {          /* 2nd level distance code */\n                here = dcode + here->val + (hold & ((1U << op) - 1));\n                goto dodist;\n            }\n            else {\n                strm->msg = (z_const char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n        }\n        else if ((op & 64) == 0) {              /* 2nd level length code */\n            here = lcode + here->val + (hold & ((1U << op) - 1));\n            goto dolen;\n        }\n        else if (op & 32) {                     /* end-of-block */\n            Tracevv((stderr, \"inflate:         end of block\\n\"));\n            state->mode = TYPE;\n            break;\n        }\n        else {\n            strm->msg = (z_const char *)\"invalid literal/length code\";\n            state->mode = BAD;\n            break;\n        }\n    } while (in < last && out < end);\n\n    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n    len = bits >> 3;\n    in -= len;\n    bits -= len << 3;\n    hold &= (1U << bits) - 1;\n\n    /* update state and return */\n    strm->next_in = in;\n    strm->next_out = out;\n    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));\n    strm->avail_out = (unsigned)(out < end ?\n                                 257 + (end - out) : 257 - (out - end));\n    state->hold = hold;\n    state->bits = bits;\n    return;\n}\n\n/*\n   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):\n   - Using bit fields for code structure\n   - Different op definition to avoid & for extra bits (do & for table bits)\n   - Three separate decoding do-loops for direct, window, and wnext == 0\n   - Special case for distance > 1 copies to do overlapped load and store copy\n   - Explicit branch predictions (based on measured branch probabilities)\n   - Deferring match copy and interspersed it with decoding subsequent codes\n   - Swapping literal/length else\n   - Swapping window/direct else\n   - Larger unrolled copy loops (three is about right)\n   - Moving len -= 3 statement into middle of loop\n */\n\n#endif /* !ASMINF */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inffast.h",
    "content": "/* inffast.h -- header to use inffast.c\n * Copyright (C) 1995-2003, 2010 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\nvoid ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start);\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inffixed.h",
    "content": "/* inffixed.h -- table for decoding fixed codes\n * Generated automatically by makefixed().\n */\n\n/* WARNING: this file should *not* be used by applications.\n   It is part of the implementation of this library and is\n   subject to change. Applications should only use zlib.h.\n */\n\nstatic const code lenfix[512] = {\n    {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},\n    {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},\n    {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},\n    {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},\n    {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},\n    {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},\n    {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},\n    {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},\n    {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},\n    {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},\n    {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},\n    {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},\n    {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},\n    {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},\n    {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},\n    {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},\n    {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},\n    {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},\n    {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},\n    {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},\n    {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},\n    {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},\n    {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},\n    {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},\n    {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},\n    {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},\n    {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},\n    {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},\n    {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},\n    {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},\n    {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},\n    {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},\n    {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},\n    {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},\n    {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},\n    {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},\n    {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},\n    {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},\n    {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},\n    {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},\n    {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},\n    {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},\n    {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},\n    {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},\n    {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},\n    {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},\n    {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},\n    {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},\n    {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},\n    {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},\n    {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},\n    {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},\n    {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},\n    {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},\n    {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},\n    {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},\n    {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},\n    {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},\n    {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},\n    {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},\n    {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},\n    {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},\n    {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},\n    {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},\n    {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},\n    {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},\n    {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},\n    {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},\n    {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},\n    {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},\n    {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},\n    {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},\n    {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},\n    {0,9,255}\n};\n\nstatic const code distfix[32] = {\n    {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},\n    {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},\n    {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},\n    {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},\n    {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},\n    {22,5,193},{64,5,0}\n};\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inflate.c",
    "content": "/* inflate.c -- zlib decompression\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n * Change history:\n *\n * 1.2.beta0    24 Nov 2002\n * - First version -- complete rewrite of inflate to simplify code, avoid\n *   creation of window when not needed, minimize use of window when it is\n *   needed, make inffast.c even faster, implement gzip decoding, and to\n *   improve code readability and style over the previous zlib inflate code\n *\n * 1.2.beta1    25 Nov 2002\n * - Use pointers for available input and output checking in inffast.c\n * - Remove input and output counters in inffast.c\n * - Change inffast.c entry and loop from avail_in >= 7 to >= 6\n * - Remove unnecessary second byte pull from length extra in inffast.c\n * - Unroll direct copy to three copies per loop in inffast.c\n *\n * 1.2.beta2    4 Dec 2002\n * - Change external routine names to reduce potential conflicts\n * - Correct filename to inffixed.h for fixed tables in inflate.c\n * - Make hbuf[] unsigned char to match parameter type in inflate.c\n * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)\n *   to avoid negation problem on Alphas (64 bit) in inflate.c\n *\n * 1.2.beta3    22 Dec 2002\n * - Add comments on state->bits assertion in inffast.c\n * - Add comments on op field in inftrees.h\n * - Fix bug in reuse of allocated window after inflateReset()\n * - Remove bit fields--back to byte structure for speed\n * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths\n * - Change post-increments to pre-increments in inflate_fast(), PPC biased?\n * - Add compile time option, POSTINC, to use post-increments instead (Intel?)\n * - Make MATCH copy in inflate() much faster for when inflate_fast() not used\n * - Use local copies of stream next and avail values, as well as local bit\n *   buffer and bit count in inflate()--for speed when inflate_fast() not used\n *\n * 1.2.beta4    1 Jan 2003\n * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings\n * - Move a comment on output buffer sizes from inffast.c to inflate.c\n * - Add comments in inffast.c to introduce the inflate_fast() routine\n * - Rearrange window copies in inflate_fast() for speed and simplification\n * - Unroll last copy for window match in inflate_fast()\n * - Use local copies of window variables in inflate_fast() for speed\n * - Pull out common wnext == 0 case for speed in inflate_fast()\n * - Make op and len in inflate_fast() unsigned for consistency\n * - Add FAR to lcode and dcode declarations in inflate_fast()\n * - Simplified bad distance check in inflate_fast()\n * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new\n *   source file infback.c to provide a call-back interface to inflate for\n *   programs like gzip and unzip -- uses window as output buffer to avoid\n *   window copying\n *\n * 1.2.beta5    1 Jan 2003\n * - Improved inflateBack() interface to allow the caller to provide initial\n *   input in strm.\n * - Fixed stored blocks bug in inflateBack()\n *\n * 1.2.beta6    4 Jan 2003\n * - Added comments in inffast.c on effectiveness of POSTINC\n * - Typecasting all around to reduce compiler warnings\n * - Changed loops from while (1) or do {} while (1) to for (;;), again to\n *   make compilers happy\n * - Changed type of window in inflateBackInit() to unsigned char *\n *\n * 1.2.beta7    27 Jan 2003\n * - Changed many types to unsigned or unsigned short to avoid warnings\n * - Added inflateCopy() function\n *\n * 1.2.0        9 Mar 2003\n * - Changed inflateBack() interface to provide separate opaque descriptors\n *   for the in() and out() functions\n * - Changed inflateBack() argument and in_func typedef to swap the length\n *   and buffer address return values for the input function\n * - Check next_in and next_out for Z_NULL on entry to inflate()\n *\n * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.\n */\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n#include \"inffast.h\"\n\nlocal int inflateStateCheck(z_streamp strm) {\n    struct inflate_state FAR *state;\n    if (strm == Z_NULL ||\n        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)\n        return 1;\n    state = (struct inflate_state FAR *)strm->state;\n    if (state == Z_NULL || state->strm != strm ||\n        state->mode < HEAD || state->mode > SYNC)\n        return 1;\n    return 0;\n}\n\nint ZEXPORT inflateResetKeep(z_streamp strm) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    strm->total_in = strm->total_out = state->total = 0;\n    strm->msg = Z_NULL;\n    strm->data_type = 0;\n    if (state->wrap)        /* to support ill-conceived Java test suite */\n        strm->adler = state->wrap & 1;\n    state->mode = HEAD;\n    state->last = 0;\n    state->havedict = 0;\n    state->flags = -1;\n    state->dmax = 32768U;\n    state->head = Z_NULL;\n    state->hold = 0;\n    state->bits = 0;\n    state->lencode = state->distcode = state->next = state->codes;\n    state->sane = 1;\n    state->back = -1;\n    Tracev((stderr, \"inflate: reset\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateReset(z_streamp strm) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    state->wsize = 0;\n    state->whave = 0;\n    state->wnext = 0;\n    return inflateResetKeep(strm);\n}\n\nint ZEXPORT inflateReset2(z_streamp strm, int windowBits) {\n    int wrap;\n    struct inflate_state FAR *state;\n\n    /* get the state */\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* extract wrap request from windowBits parameter */\n    if (windowBits < 0) {\n        if (windowBits < -15)\n            return Z_STREAM_ERROR;\n        wrap = 0;\n        windowBits = -windowBits;\n    }\n    else {\n        wrap = (windowBits >> 4) + 5;\n#ifdef GUNZIP\n        if (windowBits < 48)\n            windowBits &= 15;\n#endif\n    }\n\n    /* set number of window bits, free window if different */\n    if (windowBits && (windowBits < 8 || windowBits > 15))\n        return Z_STREAM_ERROR;\n    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {\n        ZFREE(strm, state->window);\n        state->window = Z_NULL;\n    }\n\n    /* update state and reset the rest of it */\n    state->wrap = wrap;\n    state->wbits = (unsigned)windowBits;\n    return inflateReset(strm);\n}\n\nint ZEXPORT inflateInit2_(z_streamp strm, int windowBits,\n                          const char *version, int stream_size) {\n    int ret;\n    struct inflate_state FAR *state;\n\n    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||\n        stream_size != (int)(sizeof(z_stream)))\n        return Z_VERSION_ERROR;\n    if (strm == Z_NULL) return Z_STREAM_ERROR;\n    strm->msg = Z_NULL;                 /* in case we return an error */\n    if (strm->zalloc == (alloc_func)0) {\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zalloc = zcalloc;\n        strm->opaque = (voidpf)0;\n#endif\n    }\n    if (strm->zfree == (free_func)0)\n#ifdef Z_SOLO\n        return Z_STREAM_ERROR;\n#else\n        strm->zfree = zcfree;\n#endif\n    state = (struct inflate_state FAR *)\n            ZALLOC(strm, 1, sizeof(struct inflate_state));\n    if (state == Z_NULL) return Z_MEM_ERROR;\n    zmemzero(state, sizeof(struct inflate_state));\n    Tracev((stderr, \"inflate: allocated\\n\"));\n    strm->state = (struct internal_state FAR *)state;\n    state->strm = strm;\n    state->window = Z_NULL;\n    state->mode = HEAD;     /* to pass state test in inflateReset2() */\n    ret = inflateReset2(strm, windowBits);\n    if (ret != Z_OK) {\n        ZFREE(strm, state);\n        strm->state = Z_NULL;\n    }\n    return ret;\n}\n\nint ZEXPORT inflateInit_(z_streamp strm, const char *version,\n                         int stream_size) {\n    return inflateInit2_(strm, DEF_WBITS, version, stream_size);\n}\n\nint ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    if (bits == 0)\n        return Z_OK;\n    state = (struct inflate_state FAR *)strm->state;\n    if (bits < 0) {\n        state->hold = 0;\n        state->bits = 0;\n        return Z_OK;\n    }\n    if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;\n    value &= (1L << bits) - 1;\n    state->hold += (unsigned long)value << state->bits;\n    state->bits += (uInt)bits;\n    return Z_OK;\n}\n\n/*\n   Update the window with the last wsize (normally 32K) bytes written before\n   returning.  If window does not exist yet, create it.  This is only called\n   when a window is already in use, or when output has been written during this\n   inflate call, but the end of the deflate stream has not been reached yet.\n   It is also called to create a window for dictionary data when a dictionary\n   is loaded.\n\n   Providing output buffers larger than 32K to inflate() should provide a speed\n   advantage, since only the last 32K of output is copied to the sliding window\n   upon return from inflate(), and since all distances after the first 32K of\n   output will fall in the output data, making match copies simpler and faster.\n   The advantage may be dependent on the size of the processor's data caches.\n */\nlocal int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {\n    struct inflate_state FAR *state;\n    unsigned dist;\n\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* if it hasn't been done already, allocate space for the window */\n    if (state->window == Z_NULL) {\n        state->window = (unsigned char FAR *)\n                        ZALLOC(strm, 1U << state->wbits,\n                               sizeof(unsigned char));\n        if (state->window == Z_NULL) return 1;\n    }\n\n    /* if window not in use yet, initialize */\n    if (state->wsize == 0) {\n        state->wsize = 1U << state->wbits;\n        state->wnext = 0;\n        state->whave = 0;\n    }\n\n    /* copy state->wsize or less output bytes into the circular window */\n    if (copy >= state->wsize) {\n        zmemcpy(state->window, end - state->wsize, state->wsize);\n        state->wnext = 0;\n        state->whave = state->wsize;\n    }\n    else {\n        dist = state->wsize - state->wnext;\n        if (dist > copy) dist = copy;\n        zmemcpy(state->window + state->wnext, end - copy, dist);\n        copy -= dist;\n        if (copy) {\n            zmemcpy(state->window, end - copy, copy);\n            state->wnext = copy;\n            state->whave = state->wsize;\n        }\n        else {\n            state->wnext += dist;\n            if (state->wnext == state->wsize) state->wnext = 0;\n            if (state->whave < state->wsize) state->whave += dist;\n        }\n    }\n    return 0;\n}\n\n/* Macros for inflate(): */\n\n/* check function to use adler32() for zlib or crc32() for gzip */\n#ifdef GUNZIP\n#  define UPDATE_CHECK(check, buf, len) \\\n    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))\n#else\n#  define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)\n#endif\n\n/* check macros for header crc */\n#ifdef GUNZIP\n#  define CRC2(check, word) \\\n    do { \\\n        hbuf[0] = (unsigned char)(word); \\\n        hbuf[1] = (unsigned char)((word) >> 8); \\\n        check = crc32(check, hbuf, 2); \\\n    } while (0)\n\n#  define CRC4(check, word) \\\n    do { \\\n        hbuf[0] = (unsigned char)(word); \\\n        hbuf[1] = (unsigned char)((word) >> 8); \\\n        hbuf[2] = (unsigned char)((word) >> 16); \\\n        hbuf[3] = (unsigned char)((word) >> 24); \\\n        check = crc32(check, hbuf, 4); \\\n    } while (0)\n#endif\n\n/* Load registers with state in inflate() for speed */\n#define LOAD() \\\n    do { \\\n        put = strm->next_out; \\\n        left = strm->avail_out; \\\n        next = strm->next_in; \\\n        have = strm->avail_in; \\\n        hold = state->hold; \\\n        bits = state->bits; \\\n    } while (0)\n\n/* Restore state from registers in inflate() */\n#define RESTORE() \\\n    do { \\\n        strm->next_out = put; \\\n        strm->avail_out = left; \\\n        strm->next_in = next; \\\n        strm->avail_in = have; \\\n        state->hold = hold; \\\n        state->bits = bits; \\\n    } while (0)\n\n/* Clear the input bit accumulator */\n#define INITBITS() \\\n    do { \\\n        hold = 0; \\\n        bits = 0; \\\n    } while (0)\n\n/* Get a byte of input into the bit accumulator, or return from inflate()\n   if there is no input available. */\n#define PULLBYTE() \\\n    do { \\\n        if (have == 0) goto inf_leave; \\\n        have--; \\\n        hold += (unsigned long)(*next++) << bits; \\\n        bits += 8; \\\n    } while (0)\n\n/* Assure that there are at least n bits in the bit accumulator.  If there is\n   not enough available input to do that, then return from inflate(). */\n#define NEEDBITS(n) \\\n    do { \\\n        while (bits < (unsigned)(n)) \\\n            PULLBYTE(); \\\n    } while (0)\n\n/* Return the low n bits of the bit accumulator (n < 16) */\n#define BITS(n) \\\n    ((unsigned)hold & ((1U << (n)) - 1))\n\n/* Remove n bits from the bit accumulator */\n#define DROPBITS(n) \\\n    do { \\\n        hold >>= (n); \\\n        bits -= (unsigned)(n); \\\n    } while (0)\n\n/* Remove zero to seven bits as needed to go to a byte boundary */\n#define BYTEBITS() \\\n    do { \\\n        hold >>= bits & 7; \\\n        bits -= bits & 7; \\\n    } while (0)\n\n/*\n   inflate() uses a state machine to process as much input data and generate as\n   much output data as possible before returning.  The state machine is\n   structured roughly as follows:\n\n    for (;;) switch (state) {\n    ...\n    case STATEn:\n        if (not enough input data or output space to make progress)\n            return;\n        ... make progress ...\n        state = STATEm;\n        break;\n    ...\n    }\n\n   so when inflate() is called again, the same case is attempted again, and\n   if the appropriate resources are provided, the machine proceeds to the\n   next state.  The NEEDBITS() macro is usually the way the state evaluates\n   whether it can proceed or should return.  NEEDBITS() does the return if\n   the requested bits are not available.  The typical use of the BITS macros\n   is:\n\n        NEEDBITS(n);\n        ... do something with BITS(n) ...\n        DROPBITS(n);\n\n   where NEEDBITS(n) either returns from inflate() if there isn't enough\n   input left to load n bits into the accumulator, or it continues.  BITS(n)\n   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops\n   the low n bits off the accumulator.  INITBITS() clears the accumulator\n   and sets the number of available bits to zero.  BYTEBITS() discards just\n   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()\n   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.\n\n   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return\n   if there is no input available.  The decoding of variable length codes uses\n   PULLBYTE() directly in order to pull just enough bytes to decode the next\n   code, and no more.\n\n   Some states loop until they get enough input, making sure that enough\n   state information is maintained to continue the loop where it left off\n   if NEEDBITS() returns in the loop.  For example, want, need, and keep\n   would all have to actually be part of the saved state in case NEEDBITS()\n   returns:\n\n    case STATEw:\n        while (want < need) {\n            NEEDBITS(n);\n            keep[want++] = BITS(n);\n            DROPBITS(n);\n        }\n        state = STATEx;\n    case STATEx:\n\n   As shown above, if the next state is also the next case, then the break\n   is omitted.\n\n   A state may also return if there is not enough output space available to\n   complete that state.  Those states are copying stored data, writing a\n   literal byte, and copying a matching string.\n\n   When returning, a \"goto inf_leave\" is used to update the total counters,\n   update the check value, and determine whether any progress has been made\n   during that inflate() call in order to return the proper return code.\n   Progress is defined as a change in either strm->avail_in or strm->avail_out.\n   When there is a window, goto inf_leave will update the window with the last\n   output written.  If a goto inf_leave occurs in the middle of decompression\n   and there is no window currently, goto inf_leave will create one and copy\n   output to the window for the next call of inflate().\n\n   In this implementation, the flush parameter of inflate() only affects the\n   return code (per zlib.h).  inflate() always writes as much as possible to\n   strm->next_out, given the space available and the provided input--the effect\n   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers\n   the allocation of and copying into a sliding window until necessary, which\n   provides the effect documented in zlib.h for Z_FINISH when the entire input\n   stream available.  So the only thing the flush parameter actually does is:\n   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it\n   will return Z_BUF_ERROR if it has not reached the end of the stream.\n */\n\nint ZEXPORT inflate(z_streamp strm, int flush) {\n    struct inflate_state FAR *state;\n    z_const unsigned char FAR *next;    /* next input */\n    unsigned char FAR *put;     /* next output */\n    unsigned have, left;        /* available input and output */\n    unsigned long hold;         /* bit buffer */\n    unsigned bits;              /* bits in bit buffer */\n    unsigned in, out;           /* save starting available input and output */\n    unsigned copy;              /* number of stored or match bytes to copy */\n    unsigned char FAR *from;    /* where to copy match bytes from */\n    code here;                  /* current decoding table entry */\n    code last;                  /* parent table entry */\n    unsigned len;               /* length to copy for repeats, bits to drop */\n    int ret;                    /* return code */\n#ifdef GUNZIP\n    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */\n#endif\n    static const unsigned short order[19] = /* permutation of code lengths */\n        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};\n\n    if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||\n        (strm->next_in == Z_NULL && strm->avail_in != 0))\n        return Z_STREAM_ERROR;\n\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */\n    LOAD();\n    in = have;\n    out = left;\n    ret = Z_OK;\n    for (;;)\n        switch (state->mode) {\n        case HEAD:\n            if (state->wrap == 0) {\n                state->mode = TYPEDO;\n                break;\n            }\n            NEEDBITS(16);\n#ifdef GUNZIP\n            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */\n                if (state->wbits == 0)\n                    state->wbits = 15;\n                state->check = crc32(0L, Z_NULL, 0);\n                CRC2(state->check, hold);\n                INITBITS();\n                state->mode = FLAGS;\n                break;\n            }\n            if (state->head != Z_NULL)\n                state->head->done = -1;\n            if (!(state->wrap & 1) ||   /* check if zlib header allowed */\n#else\n            if (\n#endif\n                ((BITS(8) << 8) + (hold >> 8)) % 31) {\n                strm->msg = (z_const char *)\"incorrect header check\";\n                state->mode = BAD;\n                break;\n            }\n            if (BITS(4) != Z_DEFLATED) {\n                strm->msg = (z_const char *)\"unknown compression method\";\n                state->mode = BAD;\n                break;\n            }\n            DROPBITS(4);\n            len = BITS(4) + 8;\n            if (state->wbits == 0)\n                state->wbits = len;\n            if (len > 15 || len > state->wbits) {\n                strm->msg = (z_const char *)\"invalid window size\";\n                state->mode = BAD;\n                break;\n            }\n            state->dmax = 1U << len;\n            state->flags = 0;               /* indicate zlib header */\n            Tracev((stderr, \"inflate:   zlib header ok\\n\"));\n            strm->adler = state->check = adler32(0L, Z_NULL, 0);\n            state->mode = hold & 0x200 ? DICTID : TYPE;\n            INITBITS();\n            break;\n#ifdef GUNZIP\n        case FLAGS:\n            NEEDBITS(16);\n            state->flags = (int)(hold);\n            if ((state->flags & 0xff) != Z_DEFLATED) {\n                strm->msg = (z_const char *)\"unknown compression method\";\n                state->mode = BAD;\n                break;\n            }\n            if (state->flags & 0xe000) {\n                strm->msg = (z_const char *)\"unknown header flags set\";\n                state->mode = BAD;\n                break;\n            }\n            if (state->head != Z_NULL)\n                state->head->text = (int)((hold >> 8) & 1);\n            if ((state->flags & 0x0200) && (state->wrap & 4))\n                CRC2(state->check, hold);\n            INITBITS();\n            state->mode = TIME;\n                /* fallthrough */\n        case TIME:\n            NEEDBITS(32);\n            if (state->head != Z_NULL)\n                state->head->time = hold;\n            if ((state->flags & 0x0200) && (state->wrap & 4))\n                CRC4(state->check, hold);\n            INITBITS();\n            state->mode = OS;\n                /* fallthrough */\n        case OS:\n            NEEDBITS(16);\n            if (state->head != Z_NULL) {\n                state->head->xflags = (int)(hold & 0xff);\n                state->head->os = (int)(hold >> 8);\n            }\n            if ((state->flags & 0x0200) && (state->wrap & 4))\n                CRC2(state->check, hold);\n            INITBITS();\n            state->mode = EXLEN;\n                /* fallthrough */\n        case EXLEN:\n            if (state->flags & 0x0400) {\n                NEEDBITS(16);\n                state->length = (unsigned)(hold);\n                if (state->head != Z_NULL)\n                    state->head->extra_len = (unsigned)hold;\n                if ((state->flags & 0x0200) && (state->wrap & 4))\n                    CRC2(state->check, hold);\n                INITBITS();\n            }\n            else if (state->head != Z_NULL)\n                state->head->extra = Z_NULL;\n            state->mode = EXTRA;\n                /* fallthrough */\n        case EXTRA:\n            if (state->flags & 0x0400) {\n                copy = state->length;\n                if (copy > have) copy = have;\n                if (copy) {\n                    if (state->head != Z_NULL &&\n                        state->head->extra != Z_NULL &&\n                        (len = state->head->extra_len - state->length) <\n                            state->head->extra_max) {\n                        zmemcpy(state->head->extra + len, next,\n                                len + copy > state->head->extra_max ?\n                                state->head->extra_max - len : copy);\n                    }\n                    if ((state->flags & 0x0200) && (state->wrap & 4))\n                        state->check = crc32(state->check, next, copy);\n                    have -= copy;\n                    next += copy;\n                    state->length -= copy;\n                }\n                if (state->length) goto inf_leave;\n            }\n            state->length = 0;\n            state->mode = NAME;\n                /* fallthrough */\n        case NAME:\n            if (state->flags & 0x0800) {\n                if (have == 0) goto inf_leave;\n                copy = 0;\n                do {\n                    len = (unsigned)(next[copy++]);\n                    if (state->head != Z_NULL &&\n                            state->head->name != Z_NULL &&\n                            state->length < state->head->name_max)\n                        state->head->name[state->length++] = (Bytef)len;\n                } while (len && copy < have);\n                if ((state->flags & 0x0200) && (state->wrap & 4))\n                    state->check = crc32(state->check, next, copy);\n                have -= copy;\n                next += copy;\n                if (len) goto inf_leave;\n            }\n            else if (state->head != Z_NULL)\n                state->head->name = Z_NULL;\n            state->length = 0;\n            state->mode = COMMENT;\n                /* fallthrough */\n        case COMMENT:\n            if (state->flags & 0x1000) {\n                if (have == 0) goto inf_leave;\n                copy = 0;\n                do {\n                    len = (unsigned)(next[copy++]);\n                    if (state->head != Z_NULL &&\n                            state->head->comment != Z_NULL &&\n                            state->length < state->head->comm_max)\n                        state->head->comment[state->length++] = (Bytef)len;\n                } while (len && copy < have);\n                if ((state->flags & 0x0200) && (state->wrap & 4))\n                    state->check = crc32(state->check, next, copy);\n                have -= copy;\n                next += copy;\n                if (len) goto inf_leave;\n            }\n            else if (state->head != Z_NULL)\n                state->head->comment = Z_NULL;\n            state->mode = HCRC;\n                /* fallthrough */\n        case HCRC:\n            if (state->flags & 0x0200) {\n                NEEDBITS(16);\n                if ((state->wrap & 4) && hold != (state->check & 0xffff)) {\n                    strm->msg = (z_const char *)\"header crc mismatch\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n            }\n            if (state->head != Z_NULL) {\n                state->head->hcrc = (int)((state->flags >> 9) & 1);\n                state->head->done = 1;\n            }\n            strm->adler = state->check = crc32(0L, Z_NULL, 0);\n            state->mode = TYPE;\n            break;\n#endif\n        case DICTID:\n            NEEDBITS(32);\n            strm->adler = state->check = ZSWAP32(hold);\n            INITBITS();\n            state->mode = DICT;\n                /* fallthrough */\n        case DICT:\n            if (state->havedict == 0) {\n                RESTORE();\n                return Z_NEED_DICT;\n            }\n            strm->adler = state->check = adler32(0L, Z_NULL, 0);\n            state->mode = TYPE;\n                /* fallthrough */\n        case TYPE:\n            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;\n                /* fallthrough */\n        case TYPEDO:\n            if (state->last) {\n                BYTEBITS();\n                state->mode = CHECK;\n                break;\n            }\n            NEEDBITS(3);\n            state->last = BITS(1);\n            DROPBITS(1);\n            switch (BITS(2)) {\n            case 0:                             /* stored block */\n                Tracev((stderr, \"inflate:     stored block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = STORED;\n                break;\n            case 1:                             /* fixed block */\n                inflate_fixed(state);\n                Tracev((stderr, \"inflate:     fixed codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = LEN_;             /* decode codes */\n                if (flush == Z_TREES) {\n                    DROPBITS(2);\n                    goto inf_leave;\n                }\n                break;\n            case 2:                             /* dynamic block */\n                Tracev((stderr, \"inflate:     dynamic codes block%s\\n\",\n                        state->last ? \" (last)\" : \"\"));\n                state->mode = TABLE;\n                break;\n            default:\n                strm->msg = (z_const char *)\"invalid block type\";\n                state->mode = BAD;\n            }\n            DROPBITS(2);\n            break;\n        case STORED:\n            BYTEBITS();                         /* go to byte boundary */\n            NEEDBITS(32);\n            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {\n                strm->msg = (z_const char *)\"invalid stored block lengths\";\n                state->mode = BAD;\n                break;\n            }\n            state->length = (unsigned)hold & 0xffff;\n            Tracev((stderr, \"inflate:       stored length %u\\n\",\n                    state->length));\n            INITBITS();\n            state->mode = COPY_;\n            if (flush == Z_TREES) goto inf_leave;\n                /* fallthrough */\n        case COPY_:\n            state->mode = COPY;\n                /* fallthrough */\n        case COPY:\n            copy = state->length;\n            if (copy) {\n                if (copy > have) copy = have;\n                if (copy > left) copy = left;\n                if (copy == 0) goto inf_leave;\n                zmemcpy(put, next, copy);\n                have -= copy;\n                next += copy;\n                left -= copy;\n                put += copy;\n                state->length -= copy;\n                break;\n            }\n            Tracev((stderr, \"inflate:       stored end\\n\"));\n            state->mode = TYPE;\n            break;\n        case TABLE:\n            NEEDBITS(14);\n            state->nlen = BITS(5) + 257;\n            DROPBITS(5);\n            state->ndist = BITS(5) + 1;\n            DROPBITS(5);\n            state->ncode = BITS(4) + 4;\n            DROPBITS(4);\n#ifndef PKZIP_BUG_WORKAROUND\n            if (state->nlen > 286 || state->ndist > 30) {\n                strm->msg = (z_const char *)\n                    \"too many length or distance symbols\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracev((stderr, \"inflate:       table sizes ok\\n\"));\n            state->have = 0;\n            state->mode = LENLENS;\n                /* fallthrough */\n        case LENLENS:\n            while (state->have < state->ncode) {\n                NEEDBITS(3);\n                state->lens[order[state->have++]] = (unsigned short)BITS(3);\n                DROPBITS(3);\n            }\n            while (state->have < 19)\n                state->lens[order[state->have++]] = 0;\n            state->next = state->codes;\n            state->lencode = state->distcode = (const code FAR *)(state->next);\n            state->lenbits = 7;\n            ret = inflate_table(CODES, state->lens, 19, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid code lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       code lengths ok\\n\"));\n            state->have = 0;\n            state->mode = CODELENS;\n                /* fallthrough */\n        case CODELENS:\n            while (state->have < state->nlen + state->ndist) {\n                for (;;) {\n                    here = state->lencode[BITS(state->lenbits)];\n                    if ((unsigned)(here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                if (here.val < 16) {\n                    DROPBITS(here.bits);\n                    state->lens[state->have++] = here.val;\n                }\n                else {\n                    if (here.val == 16) {\n                        NEEDBITS(here.bits + 2);\n                        DROPBITS(here.bits);\n                        if (state->have == 0) {\n                            strm->msg = (z_const char *)\n                                \"invalid bit length repeat\";\n                            state->mode = BAD;\n                            break;\n                        }\n                        len = state->lens[state->have - 1];\n                        copy = 3 + BITS(2);\n                        DROPBITS(2);\n                    }\n                    else if (here.val == 17) {\n                        NEEDBITS(here.bits + 3);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 3 + BITS(3);\n                        DROPBITS(3);\n                    }\n                    else {\n                        NEEDBITS(here.bits + 7);\n                        DROPBITS(here.bits);\n                        len = 0;\n                        copy = 11 + BITS(7);\n                        DROPBITS(7);\n                    }\n                    if (state->have + copy > state->nlen + state->ndist) {\n                        strm->msg = (z_const char *)\n                            \"invalid bit length repeat\";\n                        state->mode = BAD;\n                        break;\n                    }\n                    while (copy--)\n                        state->lens[state->have++] = (unsigned short)len;\n                }\n            }\n\n            /* handle error breaks in while */\n            if (state->mode == BAD) break;\n\n            /* check for end-of-block code (better have one) */\n            if (state->lens[256] == 0) {\n                strm->msg = (z_const char *)\n                    \"invalid code -- missing end-of-block\";\n                state->mode = BAD;\n                break;\n            }\n\n            /* build code tables -- note: do not change the lenbits or distbits\n               values here (9 and 6) without reading the comments in inftrees.h\n               concerning the ENOUGH constants, which depend on those values */\n            state->next = state->codes;\n            state->lencode = (const code FAR *)(state->next);\n            state->lenbits = 9;\n            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),\n                                &(state->lenbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid literal/lengths set\";\n                state->mode = BAD;\n                break;\n            }\n            state->distcode = (const code FAR *)(state->next);\n            state->distbits = 6;\n            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,\n                            &(state->next), &(state->distbits), state->work);\n            if (ret) {\n                strm->msg = (z_const char *)\"invalid distances set\";\n                state->mode = BAD;\n                break;\n            }\n            Tracev((stderr, \"inflate:       codes ok\\n\"));\n            state->mode = LEN_;\n            if (flush == Z_TREES) goto inf_leave;\n                /* fallthrough */\n        case LEN_:\n            state->mode = LEN;\n                /* fallthrough */\n        case LEN:\n            if (have >= 6 && left >= 258) {\n                RESTORE();\n                inflate_fast(strm, out);\n                LOAD();\n                if (state->mode == TYPE)\n                    state->back = -1;\n                break;\n            }\n            state->back = 0;\n            for (;;) {\n                here = state->lencode[BITS(state->lenbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if (here.op && (here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->lencode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n                state->back += last.bits;\n            }\n            DROPBITS(here.bits);\n            state->back += here.bits;\n            state->length = (unsigned)here.val;\n            if ((int)(here.op) == 0) {\n                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n                        \"inflate:         literal '%c'\\n\" :\n                        \"inflate:         literal 0x%02x\\n\", here.val));\n                state->mode = LIT;\n                break;\n            }\n            if (here.op & 32) {\n                Tracevv((stderr, \"inflate:         end of block\\n\"));\n                state->back = -1;\n                state->mode = TYPE;\n                break;\n            }\n            if (here.op & 64) {\n                strm->msg = (z_const char *)\"invalid literal/length code\";\n                state->mode = BAD;\n                break;\n            }\n            state->extra = (unsigned)(here.op) & 15;\n            state->mode = LENEXT;\n                /* fallthrough */\n        case LENEXT:\n            if (state->extra) {\n                NEEDBITS(state->extra);\n                state->length += BITS(state->extra);\n                DROPBITS(state->extra);\n                state->back += state->extra;\n            }\n            Tracevv((stderr, \"inflate:         length %u\\n\", state->length));\n            state->was = state->length;\n            state->mode = DIST;\n                /* fallthrough */\n        case DIST:\n            for (;;) {\n                here = state->distcode[BITS(state->distbits)];\n                if ((unsigned)(here.bits) <= bits) break;\n                PULLBYTE();\n            }\n            if ((here.op & 0xf0) == 0) {\n                last = here;\n                for (;;) {\n                    here = state->distcode[last.val +\n                            (BITS(last.bits + last.op) >> last.bits)];\n                    if ((unsigned)(last.bits + here.bits) <= bits) break;\n                    PULLBYTE();\n                }\n                DROPBITS(last.bits);\n                state->back += last.bits;\n            }\n            DROPBITS(here.bits);\n            state->back += here.bits;\n            if (here.op & 64) {\n                strm->msg = (z_const char *)\"invalid distance code\";\n                state->mode = BAD;\n                break;\n            }\n            state->offset = (unsigned)here.val;\n            state->extra = (unsigned)(here.op) & 15;\n            state->mode = DISTEXT;\n                /* fallthrough */\n        case DISTEXT:\n            if (state->extra) {\n                NEEDBITS(state->extra);\n                state->offset += BITS(state->extra);\n                DROPBITS(state->extra);\n                state->back += state->extra;\n            }\n#ifdef INFLATE_STRICT\n            if (state->offset > state->dmax) {\n                strm->msg = (z_const char *)\"invalid distance too far back\";\n                state->mode = BAD;\n                break;\n            }\n#endif\n            Tracevv((stderr, \"inflate:         distance %u\\n\", state->offset));\n            state->mode = MATCH;\n                /* fallthrough */\n        case MATCH:\n            if (left == 0) goto inf_leave;\n            copy = out - left;\n            if (state->offset > copy) {         /* copy from window */\n                copy = state->offset - copy;\n                if (copy > state->whave) {\n                    if (state->sane) {\n                        strm->msg = (z_const char *)\n                            \"invalid distance too far back\";\n                        state->mode = BAD;\n                        break;\n                    }\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n                    Trace((stderr, \"inflate.c too far\\n\"));\n                    copy -= state->whave;\n                    if (copy > state->length) copy = state->length;\n                    if (copy > left) copy = left;\n                    left -= copy;\n                    state->length -= copy;\n                    do {\n                        *put++ = 0;\n                    } while (--copy);\n                    if (state->length == 0) state->mode = LEN;\n                    break;\n#endif\n                }\n                if (copy > state->wnext) {\n                    copy -= state->wnext;\n                    from = state->window + (state->wsize - copy);\n                }\n                else\n                    from = state->window + (state->wnext - copy);\n                if (copy > state->length) copy = state->length;\n            }\n            else {                              /* copy from output */\n                from = put - state->offset;\n                copy = state->length;\n            }\n            if (copy > left) copy = left;\n            left -= copy;\n            state->length -= copy;\n            do {\n                *put++ = *from++;\n            } while (--copy);\n            if (state->length == 0) state->mode = LEN;\n            break;\n        case LIT:\n            if (left == 0) goto inf_leave;\n            *put++ = (unsigned char)(state->length);\n            left--;\n            state->mode = LEN;\n            break;\n        case CHECK:\n            if (state->wrap) {\n                NEEDBITS(32);\n                out -= left;\n                strm->total_out += out;\n                state->total += out;\n                if ((state->wrap & 4) && out)\n                    strm->adler = state->check =\n                        UPDATE_CHECK(state->check, put - out, out);\n                out = left;\n                if ((state->wrap & 4) && (\n#ifdef GUNZIP\n                     state->flags ? hold :\n#endif\n                     ZSWAP32(hold)) != state->check) {\n                    strm->msg = (z_const char *)\"incorrect data check\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n                Tracev((stderr, \"inflate:   check matches trailer\\n\"));\n            }\n#ifdef GUNZIP\n            state->mode = LENGTH;\n                /* fallthrough */\n        case LENGTH:\n            if (state->wrap && state->flags) {\n                NEEDBITS(32);\n                if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {\n                    strm->msg = (z_const char *)\"incorrect length check\";\n                    state->mode = BAD;\n                    break;\n                }\n                INITBITS();\n                Tracev((stderr, \"inflate:   length matches trailer\\n\"));\n            }\n#endif\n            state->mode = DONE;\n                /* fallthrough */\n        case DONE:\n            ret = Z_STREAM_END;\n            goto inf_leave;\n        case BAD:\n            ret = Z_DATA_ERROR;\n            goto inf_leave;\n        case MEM:\n            return Z_MEM_ERROR;\n        case SYNC:\n                /* fallthrough */\n        default:\n            return Z_STREAM_ERROR;\n        }\n\n    /*\n       Return from inflate(), updating the total counts and the check value.\n       If there was no progress during the inflate() call, return a buffer\n       error.  Call updatewindow() to create and/or update the window state.\n       Note: a memory error from inflate() is non-recoverable.\n     */\n  inf_leave:\n    RESTORE();\n    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&\n            (state->mode < CHECK || flush != Z_FINISH)))\n        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {\n            state->mode = MEM;\n            return Z_MEM_ERROR;\n        }\n    in -= strm->avail_in;\n    out -= strm->avail_out;\n    strm->total_in += in;\n    strm->total_out += out;\n    state->total += out;\n    if ((state->wrap & 4) && out)\n        strm->adler = state->check =\n            UPDATE_CHECK(state->check, strm->next_out - out, out);\n    strm->data_type = (int)state->bits + (state->last ? 64 : 0) +\n                      (state->mode == TYPE ? 128 : 0) +\n                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);\n    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)\n        ret = Z_BUF_ERROR;\n    return ret;\n}\n\nint ZEXPORT inflateEnd(z_streamp strm) {\n    struct inflate_state FAR *state;\n    if (inflateStateCheck(strm))\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->window != Z_NULL) ZFREE(strm, state->window);\n    ZFREE(strm, strm->state);\n    strm->state = Z_NULL;\n    Tracev((stderr, \"inflate: end\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,\n                                 uInt *dictLength) {\n    struct inflate_state FAR *state;\n\n    /* check state */\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n\n    /* copy dictionary */\n    if (state->whave && dictionary != Z_NULL) {\n        zmemcpy(dictionary, state->window + state->wnext,\n                state->whave - state->wnext);\n        zmemcpy(dictionary + state->whave - state->wnext,\n                state->window, state->wnext);\n    }\n    if (dictLength != Z_NULL)\n        *dictLength = state->whave;\n    return Z_OK;\n}\n\nint ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,\n                                 uInt dictLength) {\n    struct inflate_state FAR *state;\n    unsigned long dictid;\n    int ret;\n\n    /* check state */\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (state->wrap != 0 && state->mode != DICT)\n        return Z_STREAM_ERROR;\n\n    /* check for correct dictionary identifier */\n    if (state->mode == DICT) {\n        dictid = adler32(0L, Z_NULL, 0);\n        dictid = adler32(dictid, dictionary, dictLength);\n        if (dictid != state->check)\n            return Z_DATA_ERROR;\n    }\n\n    /* copy dictionary to window using updatewindow(), which will amend the\n       existing dictionary if appropriate */\n    ret = updatewindow(strm, dictionary + dictLength, dictLength);\n    if (ret) {\n        state->mode = MEM;\n        return Z_MEM_ERROR;\n    }\n    state->havedict = 1;\n    Tracev((stderr, \"inflate:   dictionary set\\n\"));\n    return Z_OK;\n}\n\nint ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {\n    struct inflate_state FAR *state;\n\n    /* check state */\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;\n\n    /* save header structure */\n    state->head = head;\n    head->done = 0;\n    return Z_OK;\n}\n\n/*\n   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found\n   or when out of input.  When called, *have is the number of pattern bytes\n   found in order so far, in 0..3.  On return *have is updated to the new\n   state.  If on return *have equals four, then the pattern was found and the\n   return value is how many bytes were read including the last byte of the\n   pattern.  If *have is less than four, then the pattern has not been found\n   yet and the return value is len.  In the latter case, syncsearch() can be\n   called again with more data and the *have state.  *have is initialized to\n   zero for the first call.\n */\nlocal unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,\n                          unsigned len) {\n    unsigned got;\n    unsigned next;\n\n    got = *have;\n    next = 0;\n    while (next < len && got < 4) {\n        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))\n            got++;\n        else if (buf[next])\n            got = 0;\n        else\n            got = 4 - got;\n        next++;\n    }\n    *have = got;\n    return next;\n}\n\nint ZEXPORT inflateSync(z_streamp strm) {\n    unsigned len;               /* number of bytes to look at or looked at */\n    int flags;                  /* temporary to save header status */\n    unsigned long in, out;      /* temporary to save total_in and total_out */\n    unsigned char buf[4];       /* to restore bit buffer to byte string */\n    struct inflate_state FAR *state;\n\n    /* check parameters */\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;\n\n    /* if first time, start search in bit buffer */\n    if (state->mode != SYNC) {\n        state->mode = SYNC;\n        state->hold >>= state->bits & 7;\n        state->bits -= state->bits & 7;\n        len = 0;\n        while (state->bits >= 8) {\n            buf[len++] = (unsigned char)(state->hold);\n            state->hold >>= 8;\n            state->bits -= 8;\n        }\n        state->have = 0;\n        syncsearch(&(state->have), buf, len);\n    }\n\n    /* search available input */\n    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);\n    strm->avail_in -= len;\n    strm->next_in += len;\n    strm->total_in += len;\n\n    /* return no joy or set up to restart inflate() on a new block */\n    if (state->have != 4) return Z_DATA_ERROR;\n    if (state->flags == -1)\n        state->wrap = 0;    /* if no header yet, treat as raw */\n    else\n        state->wrap &= ~4;  /* no point in computing a check value now */\n    flags = state->flags;\n    in = strm->total_in;  out = strm->total_out;\n    inflateReset(strm);\n    strm->total_in = in;  strm->total_out = out;\n    state->flags = flags;\n    state->mode = TYPE;\n    return Z_OK;\n}\n\n/*\n   Returns true if inflate is currently at the end of a block generated by\n   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP\n   implementation to provide an additional safety check. PPP uses\n   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored\n   block. When decompressing, PPP checks that at the end of input packet,\n   inflate is waiting for these length bytes.\n */\nint ZEXPORT inflateSyncPoint(z_streamp strm) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    return state->mode == STORED && state->bits == 0;\n}\n\nint ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {\n    struct inflate_state FAR *state;\n    struct inflate_state FAR *copy;\n    unsigned char FAR *window;\n\n    /* check input */\n    if (inflateStateCheck(source) || dest == Z_NULL)\n        return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)source->state;\n\n    /* allocate space */\n    copy = (struct inflate_state FAR *)\n           ZALLOC(source, 1, sizeof(struct inflate_state));\n    if (copy == Z_NULL) return Z_MEM_ERROR;\n    zmemzero(copy, sizeof(struct inflate_state));\n    window = Z_NULL;\n    if (state->window != Z_NULL) {\n        window = (unsigned char FAR *)\n                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));\n        if (window == Z_NULL) {\n            ZFREE(source, copy);\n            return Z_MEM_ERROR;\n        }\n    }\n\n    /* copy state */\n    zmemcpy(dest, source, sizeof(z_stream));\n    zmemcpy(copy, state, sizeof(struct inflate_state));\n    copy->strm = dest;\n    if (state->lencode >= state->codes &&\n        state->lencode <= state->codes + ENOUGH - 1) {\n        copy->lencode = copy->codes + (state->lencode - state->codes);\n        copy->distcode = copy->codes + (state->distcode - state->codes);\n    }\n    copy->next = copy->codes + (state->next - state->codes);\n    if (window != Z_NULL)\n        zmemcpy(window, state->window, state->whave);\n    copy->window = window;\n    dest->state = (struct internal_state FAR *)copy;\n    return Z_OK;\n}\n\nint ZEXPORT inflateUndermine(z_streamp strm, int subvert) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n    state->sane = !subvert;\n    return Z_OK;\n#else\n    (void)subvert;\n    state->sane = 1;\n    return Z_DATA_ERROR;\n#endif\n}\n\nint ZEXPORT inflateValidate(z_streamp strm, int check) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;\n    state = (struct inflate_state FAR *)strm->state;\n    if (check && state->wrap)\n        state->wrap |= 4;\n    else\n        state->wrap &= ~4;\n    return Z_OK;\n}\n\nlong ZEXPORT inflateMark(z_streamp strm) {\n    struct inflate_state FAR *state;\n\n    if (inflateStateCheck(strm))\n        return -(1L << 16);\n    state = (struct inflate_state FAR *)strm->state;\n    return (long)(((unsigned long)((long)state->back)) << 16) +\n        (state->mode == COPY ? state->length :\n            (state->mode == MATCH ? state->was - state->length : 0));\n}\n\nunsigned long ZEXPORT inflateCodesUsed(z_streamp strm) {\n    struct inflate_state FAR *state;\n    if (inflateStateCheck(strm)) return (unsigned long)-1;\n    state = (struct inflate_state FAR *)strm->state;\n    return (unsigned long)(state->next - state->codes);\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inflate.h",
    "content": "/* inflate.h -- internal inflate state definition\n * Copyright (C) 1995-2019 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* define NO_GZIP when compiling if you want to disable gzip header and\n   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in\n   the crc code when it is not needed.  For shared libraries, gzip decoding\n   should be left enabled. */\n#ifndef NO_GZIP\n#  define GUNZIP\n#endif\n\n/* Possible inflate modes between inflate() calls */\ntypedef enum {\n    HEAD = 16180,   /* i: waiting for magic header */\n    FLAGS,      /* i: waiting for method and flags (gzip) */\n    TIME,       /* i: waiting for modification time (gzip) */\n    OS,         /* i: waiting for extra flags and operating system (gzip) */\n    EXLEN,      /* i: waiting for extra length (gzip) */\n    EXTRA,      /* i: waiting for extra bytes (gzip) */\n    NAME,       /* i: waiting for end of file name (gzip) */\n    COMMENT,    /* i: waiting for end of comment (gzip) */\n    HCRC,       /* i: waiting for header crc (gzip) */\n    DICTID,     /* i: waiting for dictionary check value */\n    DICT,       /* waiting for inflateSetDictionary() call */\n        TYPE,       /* i: waiting for type bits, including last-flag bit */\n        TYPEDO,     /* i: same, but skip check to exit inflate on new block */\n        STORED,     /* i: waiting for stored size (length and complement) */\n        COPY_,      /* i/o: same as COPY below, but only first time in */\n        COPY,       /* i/o: waiting for input or output to copy stored block */\n        TABLE,      /* i: waiting for dynamic block table lengths */\n        LENLENS,    /* i: waiting for code length code lengths */\n        CODELENS,   /* i: waiting for length/lit and distance code lengths */\n            LEN_,       /* i: same as LEN below, but only first time in */\n            LEN,        /* i: waiting for length/lit/eob code */\n            LENEXT,     /* i: waiting for length extra bits */\n            DIST,       /* i: waiting for distance code */\n            DISTEXT,    /* i: waiting for distance extra bits */\n            MATCH,      /* o: waiting for output space to copy string */\n            LIT,        /* o: waiting for output space to write literal */\n    CHECK,      /* i: waiting for 32-bit check value */\n    LENGTH,     /* i: waiting for 32-bit length (gzip) */\n    DONE,       /* finished check, done -- remain here until reset */\n    BAD,        /* got a data error -- remain here until reset */\n    MEM,        /* got an inflate() memory error -- remain here until reset */\n    SYNC        /* looking for synchronization bytes to restart inflate() */\n} inflate_mode;\n\n/*\n    State transitions between above modes -\n\n    (most modes can go to BAD or MEM on error -- not shown for clarity)\n\n    Process header:\n        HEAD -> (gzip) or (zlib) or (raw)\n        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->\n                  HCRC -> TYPE\n        (zlib) -> DICTID or TYPE\n        DICTID -> DICT -> TYPE\n        (raw) -> TYPEDO\n    Read deflate blocks:\n            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK\n            STORED -> COPY_ -> COPY -> TYPE\n            TABLE -> LENLENS -> CODELENS -> LEN_\n            LEN_ -> LEN\n    Read deflate codes in fixed or dynamic block:\n                LEN -> LENEXT or LIT or TYPE\n                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN\n                LIT -> LEN\n    Process trailer:\n        CHECK -> LENGTH -> DONE\n */\n\n/* State maintained between inflate() calls -- approximately 7K bytes, not\n   including the allocated sliding window, which is up to 32K bytes. */\nstruct inflate_state {\n    z_streamp strm;             /* pointer back to this zlib stream */\n    inflate_mode mode;          /* current inflate mode */\n    int last;                   /* true if processing last block */\n    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip,\n                                   bit 2 true to validate check value */\n    int havedict;               /* true if dictionary provided */\n    int flags;                  /* gzip header method and flags, 0 if zlib, or\n                                   -1 if raw or no header yet */\n    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */\n    unsigned long check;        /* protected copy of check value */\n    unsigned long total;        /* protected copy of output count */\n    gz_headerp head;            /* where to save gzip header information */\n        /* sliding window */\n    unsigned wbits;             /* log base 2 of requested window size */\n    unsigned wsize;             /* window size or zero if not using window */\n    unsigned whave;             /* valid bytes in the window */\n    unsigned wnext;             /* window write index */\n    unsigned char FAR *window;  /* allocated sliding window, if needed */\n        /* bit accumulator */\n    unsigned long hold;         /* input bit accumulator */\n    unsigned bits;              /* number of bits in hold */\n        /* for string and stored block copying */\n    unsigned length;            /* literal or length of data to copy */\n    unsigned offset;            /* distance back to copy string from */\n        /* for table and code decoding */\n    unsigned extra;             /* extra bits needed */\n        /* fixed and dynamic code tables */\n    code const FAR *lencode;    /* starting table for length/literal codes */\n    code const FAR *distcode;   /* starting table for distance codes */\n    unsigned lenbits;           /* index bits for lencode */\n    unsigned distbits;          /* index bits for distcode */\n        /* dynamic table building */\n    unsigned ncode;             /* number of code length code lengths */\n    unsigned nlen;              /* number of length code lengths */\n    unsigned ndist;             /* number of distance code lengths */\n    unsigned have;              /* number of code lengths in lens[] */\n    code FAR *next;             /* next available space in codes[] */\n    unsigned short lens[320];   /* temporary storage for code lengths */\n    unsigned short work[288];   /* work area for code table building */\n    code codes[ENOUGH];         /* space for code tables */\n    int sane;                   /* if false, allow invalid distance too far */\n    int back;                   /* bits back of last unprocessed length/lit */\n    unsigned was;               /* initial length of match */\n};\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inftrees.c",
    "content": "/* inftrees.c -- generate Huffman trees for efficient decoding\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n#ifdef MAKEFIXED\n#  ifndef BUILDFIXED\n#    define BUILDFIXED\n#  endif\n#endif\n#ifdef BUILDFIXED\n#  define Z_ONCE\n#endif\n\n#include \"zutil.h\"\n#include \"inftrees.h\"\n#include \"inflate.h\"\n\n#ifndef NULL\n#  define NULL 0\n#endif\n\n#define MAXBITS 15\n\nconst char inflate_copyright[] =\n   \" inflate 1.3.2 Copyright 1995-2026 Mark Adler \";\n/*\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n */\n\n/*\n   Build a set of tables to decode the provided canonical Huffman code.\n   The code lengths are lens[0..codes-1].  The result starts at *table,\n   whose indices are 0..2^bits-1.  work is a writable array of at least\n   lens shorts, which is used as a work area.  type is the type of code\n   to be generated, CODES, LENS, or DISTS.  On return, zero is success,\n   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table\n   on return points to the next available entry's address.  bits is the\n   requested root table index bits, and on return it is the actual root\n   table index bits.  It will differ if the request is greater than the\n   longest code or if it is less than the shortest code.\n */\nint ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,\n                                unsigned codes, code FAR * FAR *table,\n                                unsigned FAR *bits, unsigned short FAR *work) {\n    unsigned len;               /* a code's length in bits */\n    unsigned sym;               /* index of code symbols */\n    unsigned min, max;          /* minimum and maximum code lengths */\n    unsigned root;              /* number of index bits for root table */\n    unsigned curr;              /* number of index bits for current table */\n    unsigned drop;              /* code bits to drop for sub-table */\n    int left;                   /* number of prefix codes available */\n    unsigned used;              /* code entries in table used */\n    unsigned huff;              /* Huffman code */\n    unsigned incr;              /* for incrementing code, index */\n    unsigned fill;              /* index for replicating entries */\n    unsigned low;               /* low bits for current root entry */\n    unsigned mask;              /* mask for low root bits */\n    code here;                  /* table entry for duplication */\n    code FAR *next;             /* next available space in table */\n    const unsigned short FAR *base = NULL;  /* base value table to use */\n    const unsigned short FAR *extra = NULL; /* extra bits table to use */\n    unsigned match = 0;         /* use base and extra for symbol >= match */\n    unsigned short count[MAXBITS+1];    /* number of codes of each length */\n    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */\n    static const unsigned short lbase[31] = { /* Length codes 257..285 base */\n        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};\n    static const unsigned short lext[31] = { /* Length codes 257..285 extra */\n        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 75};\n    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */\n        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n        8193, 12289, 16385, 24577, 0, 0};\n    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */\n        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,\n        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,\n        28, 28, 29, 29, 64, 64};\n\n    /*\n       Process a set of code lengths to create a canonical Huffman code.  The\n       code lengths are lens[0..codes-1].  Each length corresponds to the\n       symbols 0..codes-1.  The Huffman code is generated by first sorting the\n       symbols by length from short to long, and retaining the symbol order\n       for codes with equal lengths.  Then the code starts with all zero bits\n       for the first code of the shortest length, and the codes are integer\n       increments for the same length, and zeros are appended as the length\n       increases.  For the deflate format, these bits are stored backwards\n       from their more natural integer increment ordering, and so when the\n       decoding tables are built in the large loop below, the integer codes\n       are incremented backwards.\n\n       This routine assumes, but does not check, that all of the entries in\n       lens[] are in the range 0..MAXBITS.  The caller must assure this.\n       1..MAXBITS is interpreted as that code length.  zero means that that\n       symbol does not occur in this code.\n\n       The codes are sorted by computing a count of codes for each length,\n       creating from that a table of starting indices for each length in the\n       sorted table, and then entering the symbols in order in the sorted\n       table.  The sorted table is work[], with that space being provided by\n       the caller.\n\n       The length counts are used for other purposes as well, i.e. finding\n       the minimum and maximum length codes, determining if there are any\n       codes at all, checking for a valid set of lengths, and looking ahead\n       at length counts to determine sub-table sizes when building the\n       decoding tables.\n     */\n\n    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n    for (len = 0; len <= MAXBITS; len++)\n        count[len] = 0;\n    for (sym = 0; sym < codes; sym++)\n        count[lens[sym]]++;\n\n    /* bound code lengths, force root to be within code lengths */\n    root = *bits;\n    for (max = MAXBITS; max >= 1; max--)\n        if (count[max] != 0) break;\n    if (root > max) root = max;\n    if (max == 0) {                     /* no symbols to code at all */\n        here.op = (unsigned char)64;    /* invalid code marker */\n        here.bits = (unsigned char)1;\n        here.val = (unsigned short)0;\n        *(*table)++ = here;             /* make a table to force an error */\n        *(*table)++ = here;\n        *bits = 1;\n        return 0;     /* no symbols, but wait for decoding to report error */\n    }\n    for (min = 1; min < max; min++)\n        if (count[min] != 0) break;\n    if (root < min) root = min;\n\n    /* check for an over-subscribed or incomplete set of lengths */\n    left = 1;\n    for (len = 1; len <= MAXBITS; len++) {\n        left <<= 1;\n        left -= count[len];\n        if (left < 0) return -1;        /* over-subscribed */\n    }\n    if (left > 0 && (type == CODES || max != 1))\n        return -1;                      /* incomplete set */\n\n    /* generate offsets into symbol table for each length for sorting */\n    offs[1] = 0;\n    for (len = 1; len < MAXBITS; len++)\n        offs[len + 1] = offs[len] + count[len];\n\n    /* sort symbols by length, by symbol order within each length */\n    for (sym = 0; sym < codes; sym++)\n        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;\n\n    /*\n       Create and fill in decoding tables.  In this loop, the table being\n       filled is at next and has curr index bits.  The code being used is huff\n       with length len.  That code is converted to an index by dropping drop\n       bits off of the bottom.  For codes where len is less than drop + curr,\n       those top drop + curr - len bits are incremented through all values to\n       fill the table with replicated entries.\n\n       root is the number of index bits for the root table.  When len exceeds\n       root, sub-tables are created pointed to by the root entry with an index\n       of the low root bits of huff.  This is saved in low to check for when a\n       new sub-table should be started.  drop is zero when the root table is\n       being filled, and drop is root when sub-tables are being filled.\n\n       When a new sub-table is needed, it is necessary to look ahead in the\n       code lengths to determine what size sub-table is needed.  The length\n       counts are used for this, and so count[] is decremented as codes are\n       entered in the tables.\n\n       used keeps track of how many table entries have been allocated from the\n       provided *table space.  It is checked for LENS and DIST tables against\n       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n       the initial root table size constants.  See the comments in inftrees.h\n       for more information.\n\n       sym increments through all symbols, and the loop terminates when\n       all codes of length max, i.e. all codes, have been processed.  This\n       routine permits incomplete codes, so another loop after this one fills\n       in the rest of the decoding tables with invalid code markers.\n     */\n\n    /* set up for code type */\n    switch (type) {\n    case CODES:\n        match = 20;\n        break;\n    case LENS:\n        base = lbase;\n        extra = lext;\n        match = 257;\n        break;\n    case DISTS:\n        base = dbase;\n        extra = dext;\n    }\n\n    /* initialize state for loop */\n    huff = 0;                   /* starting code */\n    sym = 0;                    /* starting code symbol */\n    len = min;                  /* starting code length */\n    next = *table;              /* current table to fill in */\n    curr = root;                /* current table index bits */\n    drop = 0;                   /* current bits to drop from code for index */\n    low = (unsigned)(-1);       /* trigger new sub-table when len > root */\n    used = 1U << root;          /* use root table entries */\n    mask = used - 1;            /* mask for comparing low */\n\n    /* check available table space */\n    if ((type == LENS && used > ENOUGH_LENS) ||\n        (type == DISTS && used > ENOUGH_DISTS))\n        return 1;\n\n    /* process all codes and make table entries */\n    for (;;) {\n        /* create table entry */\n        here.bits = (unsigned char)(len - drop);\n        if (work[sym] + 1U < match) {\n            here.op = (unsigned char)0;\n            here.val = work[sym];\n        }\n        else if (work[sym] >= match) {\n            here.op = (unsigned char)(extra[work[sym] - match]);\n            here.val = base[work[sym] - match];\n        }\n        else {\n            here.op = (unsigned char)(32 + 64);         /* end of block */\n            here.val = 0;\n        }\n\n        /* replicate for those indices with low len bits equal to huff */\n        incr = 1U << (len - drop);\n        fill = 1U << curr;\n        min = fill;                 /* save offset to next table */\n        do {\n            fill -= incr;\n            next[(huff >> drop) + fill] = here;\n        } while (fill != 0);\n\n        /* backwards increment the len-bit code huff */\n        incr = 1U << (len - 1);\n        while (huff & incr)\n            incr >>= 1;\n        if (incr != 0) {\n            huff &= incr - 1;\n            huff += incr;\n        }\n        else\n            huff = 0;\n\n        /* go to next symbol, update count, len */\n        sym++;\n        if (--(count[len]) == 0) {\n            if (len == max) break;\n            len = lens[work[sym]];\n        }\n\n        /* create new sub-table if needed */\n        if (len > root && (huff & mask) != low) {\n            /* if first time, transition to sub-tables */\n            if (drop == 0)\n                drop = root;\n\n            /* increment past last table */\n            next += min;            /* here min is 1 << curr */\n\n            /* determine length of next table */\n            curr = len - drop;\n            left = (int)(1 << curr);\n            while (curr + drop < max) {\n                left -= count[curr + drop];\n                if (left <= 0) break;\n                curr++;\n                left <<= 1;\n            }\n\n            /* check for enough space */\n            used += 1U << curr;\n            if ((type == LENS && used > ENOUGH_LENS) ||\n                (type == DISTS && used > ENOUGH_DISTS))\n                return 1;\n\n            /* point entry in root table to sub-table */\n            low = huff & mask;\n            (*table)[low].op = (unsigned char)curr;\n            (*table)[low].bits = (unsigned char)root;\n            (*table)[low].val = (unsigned short)(next - *table);\n        }\n    }\n\n    /* fill in remaining table entry if code is incomplete (guaranteed to have\n       at most one remaining entry, since if the code is incomplete, the\n       maximum code length that was allowed to get this far is one bit) */\n    if (huff != 0) {\n        here.op = (unsigned char)64;            /* invalid code marker */\n        here.bits = (unsigned char)(len - drop);\n        here.val = (unsigned short)0;\n        next[huff] = here;\n    }\n\n    /* set return parameters */\n    *table += used;\n    *bits = root;\n    return 0;\n}\n\n#ifdef BUILDFIXED\n/*\n  If this is compiled with BUILDFIXED defined, and if inflate will be used in\n  multiple threads, and if atomics are not available, then inflate() must be\n  called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must\n  return before any other threads are allowed to call inflate.\n */\n\nstatic code *lenfix, *distfix;\nstatic code fixed[544];\n\n/* State for z_once(). */\nlocal z_once_t built = Z_ONCE_INIT;\n\nlocal void buildtables(void) {\n    unsigned sym, bits;\n    static code *next;\n    unsigned short lens[288], work[288];\n\n    /* literal/length table */\n    sym = 0;\n    while (sym < 144) lens[sym++] = 8;\n    while (sym < 256) lens[sym++] = 9;\n    while (sym < 280) lens[sym++] = 7;\n    while (sym < 288) lens[sym++] = 8;\n    next = fixed;\n    lenfix = next;\n    bits = 9;\n    inflate_table(LENS, lens, 288, &(next), &(bits), work);\n\n    /* distance table */\n    sym = 0;\n    while (sym < 32) lens[sym++] = 5;\n    distfix = next;\n    bits = 5;\n    inflate_table(DISTS, lens, 32, &(next), &(bits), work);\n}\n#else /* !BUILDFIXED */\n#  include \"inffixed.h\"\n#endif /* BUILDFIXED */\n\n/*\n   Return state with length and distance decoding tables and index sizes set to\n   fixed code decoding.  Normally this returns fixed tables from inffixed.h.\n   If BUILDFIXED is defined, then instead this routine builds the tables the\n   first time it's called, and returns those tables the first time and\n   thereafter.  This reduces the size of the code by about 2K bytes, in\n   exchange for a little execution time.  However, BUILDFIXED should not be\n   used for threaded applications if atomics are not available, as it will\n   not be thread-safe.\n */\nvoid inflate_fixed(struct inflate_state FAR *state) {\n#ifdef BUILDFIXED\n    z_once(&built, buildtables);\n#endif /* BUILDFIXED */\n    state->lencode = lenfix;\n    state->lenbits = 9;\n    state->distcode = distfix;\n    state->distbits = 5;\n}\n\n#ifdef MAKEFIXED\n#include <stdio.h>\n\n/*\n   Write out the inffixed.h that will be #include'd above.  Defining MAKEFIXED\n   also defines BUILDFIXED, so the tables are built on the fly.  main() writes\n   those tables to stdout, which would directed to inffixed.h. Compile this\n   along with zutil.c:\n\n       cc -DMAKEFIXED -o fix inftrees.c zutil.c\n       ./fix > inffixed.h\n */\nint main(void) {\n    unsigned low, size;\n    struct inflate_state state;\n\n    inflate_fixed(&state);\n    puts(\"/* inffixed.h -- table for decoding fixed codes\");\n    puts(\" * Generated automatically by makefixed().\");\n    puts(\" */\");\n    puts(\"\");\n    puts(\"/* WARNING: this file should *not* be used by applications.\");\n    puts(\"   It is part of the implementation of this library and is\");\n    puts(\"   subject to change. Applications should only use zlib.h.\");\n    puts(\" */\");\n    puts(\"\");\n    size = 1U << 9;\n    printf(\"static const code lenfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 7) == 0) printf(\"\\n    \");\n        printf(\"{%u,%u,%d}\", (low & 127) == 99 ? 64 : state.lencode[low].op,\n               state.lencode[low].bits, state.lencode[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n};\");\n    size = 1U << 5;\n    printf(\"\\nstatic const code distfix[%u] = {\", size);\n    low = 0;\n    for (;;) {\n        if ((low % 6) == 0) printf(\"\\n    \");\n        printf(\"{%u,%u,%d}\", state.distcode[low].op, state.distcode[low].bits,\n               state.distcode[low].val);\n        if (++low == size) break;\n        putchar(',');\n    }\n    puts(\"\\n};\");\n    return 0;\n}\n#endif /* MAKEFIXED */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/inftrees.h",
    "content": "/* inftrees.h -- header to use inftrees.c\n * Copyright (C) 1995-2026 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* Structure for decoding tables.  Each entry provides either the\n   information needed to do the operation requested by the code that\n   indexed that table entry, or it provides a pointer to another\n   table that indexes more bits of the code.  op indicates whether\n   the entry is a pointer to another table, a literal, a length or\n   distance, an end-of-block, or an invalid code.  For a table\n   pointer, the low four bits of op is the number of index bits of\n   that table.  For a length or distance, the low four bits of op\n   is the number of extra bits to get after the code.  bits is\n   the number of bits in this code or part of the code to drop off\n   of the bit buffer.  val is the actual byte to output in the case\n   of a literal, the base length or distance, or the offset from\n   the current table to the next table.  Each entry is four bytes. */\ntypedef struct {\n    unsigned char op;           /* operation, extra bits, table bits */\n    unsigned char bits;         /* bits in this part of the code */\n    unsigned short val;         /* offset in table or code value */\n} code;\n\n/* op values as set by inflate_table():\n    00000000 - literal\n    0000tttt - table link, tttt != 0 is the number of table index bits\n    0001eeee - length or distance, eeee is the number of extra bits\n    01100000 - end of block\n    01000000 - invalid code\n */\n\n/* Maximum size of the dynamic table.  The maximum number of code structures is\n   1444, which is the sum of 852 for literal/length codes and 592 for distance\n   codes.  These values were found by exhaustive searches using the program\n   examples/enough.c found in the zlib distribution.  The arguments to that\n   program are the number of symbols, the initial root table size, and the\n   maximum bit length of a code.  \"enough 286 9 15\" for literal/length codes\n   returns 852, and \"enough 30 6 15\" for distance codes returns 592. The\n   initial root table size (9 or 6) is found in the fifth argument of the\n   inflate_table() calls in inflate.c and infback.c.  If the root table size is\n   changed, then these maximum sizes would be need to be recalculated and\n   updated. */\n#define ENOUGH_LENS 852\n#define ENOUGH_DISTS 592\n#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)\n\n/* Type of code to build for inflate_table() */\ntypedef enum {\n    CODES,\n    LENS,\n    DISTS\n} codetype;\n\nint ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,\n                                unsigned codes, code FAR * FAR *table,\n                                unsigned FAR *bits, unsigned short FAR *work);\nstruct inflate_state;\nvoid ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state);\n"
  },
  {
    "path": "vendor/core/vendor/zlib/trees.c",
    "content": "/* trees.c -- output deflated data using Huffman coding\n * Copyright (C) 1995-2026 Jean-loup Gailly\n * detect_data_type() function provided freely by Cosmin Truta, 2006\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/*\n *  ALGORITHM\n *\n *      The \"deflation\" process uses several Huffman trees. The more\n *      common source values are represented by shorter bit sequences.\n *\n *      Each code tree is stored in a compressed form which is itself\n * a Huffman encoding of the lengths of all the code strings (in\n * ascending order by source values).  The actual code strings are\n * reconstructed from the lengths in the inflate process, as described\n * in the deflate specification.\n *\n *  REFERENCES\n *\n *      Deutsch, L.P.,\"'Deflate' Compressed Data Format Specification\".\n *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc\n *\n *      Storer, James A.\n *          Data Compression:  Methods and Theory, pp. 49-50.\n *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.\n *\n *      Sedgewick, R.\n *          Algorithms, p290.\n *          Addison-Wesley, 1983. ISBN 0-201-06672-6.\n */\n\n/* @(#) $Id$ */\n\n/* #define GEN_TREES_H */\n\n#include \"deflate.h\"\n\n#ifdef ZLIB_DEBUG\n#  include <ctype.h>\n#endif\n\n/* ===========================================================================\n * Constants\n */\n\n#define MAX_BL_BITS 7\n/* Bit length codes must not exceed MAX_BL_BITS bits */\n\n#define END_BLOCK 256\n/* end of block literal code */\n\n#define REP_3_6      16\n/* repeat previous bit length 3-6 times (2 bits of repeat count) */\n\n#define REPZ_3_10    17\n/* repeat a zero length 3-10 times  (3 bits of repeat count) */\n\n#define REPZ_11_138  18\n/* repeat a zero length 11-138 times  (7 bits of repeat count) */\n\nlocal const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */\n   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};\n\nlocal const int extra_dbits[D_CODES] /* extra bits for each distance code */\n   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};\n\nlocal const int extra_blbits[BL_CODES]/* extra bits for each bit length code */\n   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};\n\nlocal const uch bl_order[BL_CODES]\n   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};\n/* The lengths of the bit length codes are sent in order of decreasing\n * probability, to avoid transmitting the lengths for unused bit length codes.\n */\n\n/* ===========================================================================\n * Local data. These are initialized only once.\n */\n\n#define DIST_CODE_LEN  512 /* see definition of array dist_code below */\n\n#if defined(GEN_TREES_H) || !defined(STDC)\n/* non ANSI compilers may not accept trees.h */\n\nlocal ct_data static_ltree[L_CODES+2];\n/* The static literal tree. Since the bit lengths are imposed, there is no\n * need for the L_CODES extra codes used during heap construction. However\n * The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n * below).\n */\n\nlocal ct_data static_dtree[D_CODES];\n/* The static distance tree. (Actually a trivial tree since all codes use\n * 5 bits.)\n */\n\nuch _dist_code[DIST_CODE_LEN];\n/* Distance codes. The first 256 values correspond to the distances\n * 3 .. 258, the last 256 values correspond to the top 8 bits of\n * the 15 bit distances.\n */\n\nuch _length_code[MAX_MATCH-MIN_MATCH+1];\n/* length code for each normalized match length (0 == MIN_MATCH) */\n\nlocal int base_length[LENGTH_CODES];\n/* First normalized length for each code (0 = MIN_MATCH) */\n\nlocal int base_dist[D_CODES];\n/* First normalized distance for each code (0 = distance of 1) */\n\n#else\n#  include \"trees.h\"\n#endif /* defined(GEN_TREES_H) || !defined(STDC) */\n\nstruct static_tree_desc_s {\n    const ct_data *static_tree;  /* static tree or NULL */\n    const intf *extra_bits;      /* extra bits for each code or NULL */\n    int     extra_base;          /* base index for extra_bits */\n    int     elems;               /* max number of elements in the tree */\n    int     max_length;          /* max bit length for the codes */\n};\n\n#ifdef NO_INIT_GLOBAL_POINTERS\n#  define TCONST\n#else\n#  define TCONST const\n#endif\n\nlocal TCONST static_tree_desc static_l_desc =\n{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};\n\nlocal TCONST static_tree_desc static_d_desc =\n{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};\n\nlocal TCONST static_tree_desc static_bl_desc =\n{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};\n\n/* ===========================================================================\n * Output a short LSB first on the stream.\n * IN assertion: there is enough room in pendingBuf.\n */\n#define put_short(s, w) { \\\n    put_byte(s, (uch)((w) & 0xff)); \\\n    put_byte(s, (uch)((ush)(w) >> 8)); \\\n}\n\n/* ===========================================================================\n * Reverse the first len bits of a code, using straightforward code (a faster\n * method would use a table)\n * IN assertion: 1 <= len <= 15\n */\nlocal unsigned bi_reverse(unsigned code, int len) {\n    unsigned res = 0;\n    do {\n        res |= code & 1;\n        code >>= 1, res <<= 1;\n    } while (--len > 0);\n    return res >> 1;\n}\n\n/* ===========================================================================\n * Flush the bit buffer, keeping at most 7 bits in it.\n */\nlocal void bi_flush(deflate_state *s) {\n    if (s->bi_valid == 16) {\n        put_short(s, s->bi_buf);\n        s->bi_buf = 0;\n        s->bi_valid = 0;\n    } else if (s->bi_valid >= 8) {\n        put_byte(s, (Byte)s->bi_buf);\n        s->bi_buf >>= 8;\n        s->bi_valid -= 8;\n    }\n}\n\n/* ===========================================================================\n * Flush the bit buffer and align the output on a byte boundary\n */\nlocal void bi_windup(deflate_state *s) {\n    if (s->bi_valid > 8) {\n        put_short(s, s->bi_buf);\n    } else if (s->bi_valid > 0) {\n        put_byte(s, (Byte)s->bi_buf);\n    }\n    s->bi_used = ((s->bi_valid - 1) & 7) + 1;\n    s->bi_buf = 0;\n    s->bi_valid = 0;\n#ifdef ZLIB_DEBUG\n    s->bits_sent = (s->bits_sent + 7) & ~(ulg)7;\n#endif\n}\n\n/* ===========================================================================\n * Generate the codes for a given tree and bit counts (which need not be\n * optimal).\n * IN assertion: the array bl_count contains the bit length statistics for\n * the given tree and the field len is set for all tree elements.\n * OUT assertion: the field code is set for all tree elements of non\n *     zero code length.\n */\nlocal void gen_codes(ct_data *tree, int max_code, ushf *bl_count) {\n    ush next_code[MAX_BITS+1]; /* next code value for each bit length */\n    unsigned code = 0;         /* running code value */\n    int bits;                  /* bit index */\n    int n;                     /* code index */\n\n    /* The distribution counts are first used to generate the code values\n     * without bit reversal.\n     */\n    for (bits = 1; bits <= MAX_BITS; bits++) {\n        code = (code + bl_count[bits - 1]) << 1;\n        next_code[bits] = (ush)code;\n    }\n    /* Check that the bit counts in bl_count are consistent. The last code\n     * must be all ones.\n     */\n    Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,\n            \"inconsistent bit counts\");\n    Tracev((stderr,\"\\ngen_codes: max_code %d \", max_code));\n\n    for (n = 0;  n <= max_code; n++) {\n        int len = tree[n].Len;\n        if (len == 0) continue;\n        /* Now reverse the bits */\n        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);\n\n        Tracecv(tree != static_ltree, (stderr,\"\\nn %3d %c l %2d c %4x (%x) \",\n            n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));\n    }\n}\n\n#ifdef GEN_TREES_H\nlocal void gen_trees_header(void);\n#endif\n\n#ifndef ZLIB_DEBUG\n#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)\n   /* Send a code of the given tree. c and tree must not have side effects */\n\n#else /* !ZLIB_DEBUG */\n#  define send_code(s, c, tree) \\\n     { if (z_verbose>2) fprintf(stderr,\"\\ncd %3d \",(c)); \\\n       send_bits(s, tree[c].Code, tree[c].Len); }\n#endif\n\n/* ===========================================================================\n * Send a value on a given number of bits.\n * IN assertion: length <= 16 and value fits in length bits.\n */\n#ifdef ZLIB_DEBUG\nlocal void send_bits(deflate_state *s, int value, int length) {\n    Tracevv((stderr,\" l %2d v %4x \", length, value));\n    Assert(length > 0 && length <= 15, \"invalid length\");\n    s->bits_sent += (ulg)length;\n\n    /* If not enough room in bi_buf, use (valid) bits from bi_buf and\n     * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid))\n     * unused bits in value.\n     */\n    if (s->bi_valid > (int)Buf_size - length) {\n        s->bi_buf |= (ush)value << s->bi_valid;\n        put_short(s, s->bi_buf);\n        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);\n        s->bi_valid += length - Buf_size;\n    } else {\n        s->bi_buf |= (ush)value << s->bi_valid;\n        s->bi_valid += length;\n    }\n}\n#else /* !ZLIB_DEBUG */\n\n#define send_bits(s, value, length) \\\n{ int len = length;\\\n  if (s->bi_valid > (int)Buf_size - len) {\\\n    int val = (int)value;\\\n    s->bi_buf |= (ush)val << s->bi_valid;\\\n    put_short(s, s->bi_buf);\\\n    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\\\n    s->bi_valid += len - Buf_size;\\\n  } else {\\\n    s->bi_buf |= (ush)(value) << s->bi_valid;\\\n    s->bi_valid += len;\\\n  }\\\n}\n#endif /* ZLIB_DEBUG */\n\n\n/* the arguments must not have side effects */\n\n/* ===========================================================================\n * Initialize the various 'constant' tables.\n */\nlocal void tr_static_init(void) {\n#if defined(GEN_TREES_H) || !defined(STDC)\n    static int static_init_done = 0;\n    int n;        /* iterates over tree elements */\n    int bits;     /* bit counter */\n    int length;   /* length value */\n    int code;     /* code value */\n    int dist;     /* distance index */\n    ush bl_count[MAX_BITS+1];\n    /* number of codes at each bit length for an optimal tree */\n\n    if (static_init_done) return;\n\n    /* For some embedded targets, global variables are not initialized: */\n#ifdef NO_INIT_GLOBAL_POINTERS\n    static_l_desc.static_tree = static_ltree;\n    static_l_desc.extra_bits = extra_lbits;\n    static_d_desc.static_tree = static_dtree;\n    static_d_desc.extra_bits = extra_dbits;\n    static_bl_desc.extra_bits = extra_blbits;\n#endif\n\n    /* Initialize the mapping length (0..255) -> length code (0..28) */\n    length = 0;\n    for (code = 0; code < LENGTH_CODES-1; code++) {\n        base_length[code] = length;\n        for (n = 0; n < (1 << extra_lbits[code]); n++) {\n            _length_code[length++] = (uch)code;\n        }\n    }\n    Assert (length == 256, \"tr_static_init: length != 256\");\n    /* Note that the length 255 (match length 258) can be represented\n     * in two different ways: code 284 + 5 bits or code 285, so we\n     * overwrite length_code[255] to use the best encoding:\n     */\n    _length_code[length - 1] = (uch)code;\n\n    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */\n    dist = 0;\n    for (code = 0 ; code < 16; code++) {\n        base_dist[code] = dist;\n        for (n = 0; n < (1 << extra_dbits[code]); n++) {\n            _dist_code[dist++] = (uch)code;\n        }\n    }\n    Assert (dist == 256, \"tr_static_init: dist != 256\");\n    dist >>= 7; /* from now on, all distances are divided by 128 */\n    for ( ; code < D_CODES; code++) {\n        base_dist[code] = dist << 7;\n        for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {\n            _dist_code[256 + dist++] = (uch)code;\n        }\n    }\n    Assert (dist == 256, \"tr_static_init: 256 + dist != 512\");\n\n    /* Construct the codes of the static literal tree */\n    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;\n    n = 0;\n    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;\n    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;\n    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;\n    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;\n    /* Codes 286 and 287 do not exist, but we must include them in the\n     * tree construction to get a canonical Huffman tree (longest code\n     * all ones)\n     */\n    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);\n\n    /* The static distance tree is trivial: */\n    for (n = 0; n < D_CODES; n++) {\n        static_dtree[n].Len = 5;\n        static_dtree[n].Code = bi_reverse((unsigned)n, 5);\n    }\n    static_init_done = 1;\n\n#  ifdef GEN_TREES_H\n    gen_trees_header();\n#  endif\n#endif /* defined(GEN_TREES_H) || !defined(STDC) */\n}\n\n/* ===========================================================================\n * Generate the file trees.h describing the static trees.\n */\n#ifdef GEN_TREES_H\n#  ifndef ZLIB_DEBUG\n#    include <stdio.h>\n#  endif\n\n#  define SEPARATOR(i, last, width) \\\n      ((i) == (last)? \"\\n};\\n\\n\" :    \\\n       ((i) % (width) == (width) - 1 ? \",\\n\" : \", \"))\n\nvoid gen_trees_header(void) {\n    FILE *header = fopen(\"trees.h\", \"w\");\n    int i;\n\n    Assert (header != NULL, \"Can't open trees.h\");\n    fprintf(header,\n            \"/* header created automatically with -DGEN_TREES_H */\\n\\n\");\n\n    fprintf(header, \"local const ct_data static_ltree[L_CODES+2] = {\\n\");\n    for (i = 0; i < L_CODES+2; i++) {\n        fprintf(header, \"{{%3u},{%3u}}%s\", static_ltree[i].Code,\n                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));\n    }\n\n    fprintf(header, \"local const ct_data static_dtree[D_CODES] = {\\n\");\n    for (i = 0; i < D_CODES; i++) {\n        fprintf(header, \"{{%2u},{%2u}}%s\", static_dtree[i].Code,\n                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));\n    }\n\n    fprintf(header, \"const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\\n\");\n    for (i = 0; i < DIST_CODE_LEN; i++) {\n        fprintf(header, \"%2u%s\", _dist_code[i],\n                SEPARATOR(i, DIST_CODE_LEN-1, 20));\n    }\n\n    fprintf(header,\n        \"const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\\n\");\n    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {\n        fprintf(header, \"%2u%s\", _length_code[i],\n                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));\n    }\n\n    fprintf(header, \"local const int base_length[LENGTH_CODES] = {\\n\");\n    for (i = 0; i < LENGTH_CODES; i++) {\n        fprintf(header, \"%1u%s\", base_length[i],\n                SEPARATOR(i, LENGTH_CODES-1, 20));\n    }\n\n    fprintf(header, \"local const int base_dist[D_CODES] = {\\n\");\n    for (i = 0; i < D_CODES; i++) {\n        fprintf(header, \"%5u%s\", base_dist[i],\n                SEPARATOR(i, D_CODES-1, 10));\n    }\n\n    fclose(header);\n}\n#endif /* GEN_TREES_H */\n\n/* ===========================================================================\n * Initialize a new block.\n */\nlocal void init_block(deflate_state *s) {\n    int n; /* iterates over tree elements */\n\n    /* Initialize the trees. */\n    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;\n    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;\n    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;\n\n    s->dyn_ltree[END_BLOCK].Freq = 1;\n    s->opt_len = s->static_len = 0L;\n    s->sym_next = s->matches = 0;\n}\n\n/* ===========================================================================\n * Initialize the tree data structures for a new zlib stream.\n */\nvoid ZLIB_INTERNAL _tr_init(deflate_state *s) {\n    tr_static_init();\n\n    s->l_desc.dyn_tree = s->dyn_ltree;\n    s->l_desc.stat_desc = &static_l_desc;\n\n    s->d_desc.dyn_tree = s->dyn_dtree;\n    s->d_desc.stat_desc = &static_d_desc;\n\n    s->bl_desc.dyn_tree = s->bl_tree;\n    s->bl_desc.stat_desc = &static_bl_desc;\n\n    s->bi_buf = 0;\n    s->bi_valid = 0;\n    s->bi_used = 0;\n#ifdef ZLIB_DEBUG\n    s->compressed_len = 0L;\n    s->bits_sent = 0L;\n#endif\n\n    /* Initialize the first block of the first file: */\n    init_block(s);\n}\n\n#define SMALLEST 1\n/* Index within the heap array of least frequent node in the Huffman tree */\n\n\n/* ===========================================================================\n * Remove the smallest element from the heap and recreate the heap with\n * one less element. Updates heap and heap_len.\n */\n#define pqremove(s, tree, top) \\\n{\\\n    top = s->heap[SMALLEST]; \\\n    s->heap[SMALLEST] = s->heap[s->heap_len--]; \\\n    pqdownheap(s, tree, SMALLEST); \\\n}\n\n/* ===========================================================================\n * Compares to subtrees, using the tree depth as tie breaker when\n * the subtrees have equal frequency. This minimizes the worst case length.\n */\n#define smaller(tree, n, m, depth) \\\n   (tree[n].Freq < tree[m].Freq || \\\n   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))\n\n/* ===========================================================================\n * Restore the heap property by moving down the tree starting at node k,\n * exchanging a node with the smallest of its two sons if necessary, stopping\n * when the heap property is re-established (each father smaller than its\n * two sons).\n */\nlocal void pqdownheap(deflate_state *s, ct_data *tree, int k) {\n    int v = s->heap[k];\n    int j = k << 1;  /* left son of k */\n    while (j <= s->heap_len) {\n        /* Set j to the smallest of the two sons: */\n        if (j < s->heap_len &&\n            smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) {\n            j++;\n        }\n        /* Exit if v is smaller than both sons */\n        if (smaller(tree, v, s->heap[j], s->depth)) break;\n\n        /* Exchange v with the smallest son */\n        s->heap[k] = s->heap[j];  k = j;\n\n        /* And continue down the tree, setting j to the left son of k */\n        j <<= 1;\n    }\n    s->heap[k] = v;\n}\n\n/* ===========================================================================\n * Compute the optimal bit lengths for a tree and update the total bit length\n * for the current block.\n * IN assertion: the fields freq and dad are set, heap[heap_max] and\n *    above are the tree nodes sorted by increasing frequency.\n * OUT assertions: the field len is set to the optimal bit length, the\n *     array bl_count contains the frequencies for each bit length.\n *     The length opt_len is updated; static_len is also updated if stree is\n *     not null.\n */\nlocal void gen_bitlen(deflate_state *s, tree_desc *desc) {\n    ct_data *tree        = desc->dyn_tree;\n    int max_code         = desc->max_code;\n    const ct_data *stree = desc->stat_desc->static_tree;\n    const intf *extra    = desc->stat_desc->extra_bits;\n    int base             = desc->stat_desc->extra_base;\n    int max_length       = desc->stat_desc->max_length;\n    int h;              /* heap index */\n    int n, m;           /* iterate over the tree elements */\n    int bits;           /* bit length */\n    int xbits;          /* extra bits */\n    ush f;              /* frequency */\n    int overflow = 0;   /* number of elements with bit length too large */\n\n    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;\n\n    /* In a first pass, compute the optimal bit lengths (which may\n     * overflow in the case of the bit length tree).\n     */\n    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */\n\n    for (h = s->heap_max + 1; h < HEAP_SIZE; h++) {\n        n = s->heap[h];\n        bits = tree[tree[n].Dad].Len + 1;\n        if (bits > max_length) bits = max_length, overflow++;\n        tree[n].Len = (ush)bits;\n        /* We overwrite tree[n].Dad which is no longer needed */\n\n        if (n > max_code) continue; /* not a leaf node */\n\n        s->bl_count[bits]++;\n        xbits = 0;\n        if (n >= base) xbits = extra[n - base];\n        f = tree[n].Freq;\n        s->opt_len += (ulg)f * (unsigned)(bits + xbits);\n        if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);\n    }\n    if (overflow == 0) return;\n\n    Tracev((stderr,\"\\nbit length overflow\\n\"));\n    /* This happens for example on obj2 and pic of the Calgary corpus */\n\n    /* Find the first bit length which could increase: */\n    do {\n        bits = max_length - 1;\n        while (s->bl_count[bits] == 0) bits--;\n        s->bl_count[bits]--;        /* move one leaf down the tree */\n        s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */\n        s->bl_count[max_length]--;\n        /* The brother of the overflow item also moves one step up,\n         * but this does not affect bl_count[max_length]\n         */\n        overflow -= 2;\n    } while (overflow > 0);\n\n    /* Now recompute all bit lengths, scanning in increasing frequency.\n     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n     * lengths instead of fixing only the wrong ones. This idea is taken\n     * from 'ar' written by Haruhiko Okumura.)\n     */\n    for (bits = max_length; bits != 0; bits--) {\n        n = s->bl_count[bits];\n        while (n != 0) {\n            m = s->heap[--h];\n            if (m > max_code) continue;\n            if ((unsigned) tree[m].Len != (unsigned) bits) {\n                Tracev((stderr,\"code %d bits %d->%d\\n\", m, tree[m].Len, bits));\n                s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;\n                tree[m].Len = (ush)bits;\n            }\n            n--;\n        }\n    }\n}\n\n#ifdef DUMP_BL_TREE\n#  include <stdio.h>\n#endif\n\n/* ===========================================================================\n * Construct one Huffman tree and assigns the code bit strings and lengths.\n * Update the total bit length for the current block.\n * IN assertion: the field freq is set for all tree elements.\n * OUT assertions: the fields len and code are set to the optimal bit length\n *     and corresponding code. The length opt_len is updated; static_len is\n *     also updated if stree is not null. The field max_code is set.\n */\nlocal void build_tree(deflate_state *s, tree_desc *desc) {\n    ct_data *tree         = desc->dyn_tree;\n    const ct_data *stree  = desc->stat_desc->static_tree;\n    int elems             = desc->stat_desc->elems;\n    int n, m;          /* iterate over heap elements */\n    int max_code = -1; /* largest code with non zero frequency */\n    int node;          /* new node being created */\n\n    /* Construct the initial heap, with least frequent element in\n     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1].\n     * heap[0] is not used.\n     */\n    s->heap_len = 0, s->heap_max = HEAP_SIZE;\n\n    for (n = 0; n < elems; n++) {\n        if (tree[n].Freq != 0) {\n            s->heap[++(s->heap_len)] = max_code = n;\n            s->depth[n] = 0;\n        } else {\n            tree[n].Len = 0;\n        }\n    }\n\n    /* The pkzip format requires that at least one distance code exists,\n     * and that at least one bit should be sent even if there is only one\n     * possible code. So to avoid special checks later on we force at least\n     * two codes of non zero frequency.\n     */\n    while (s->heap_len < 2) {\n        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);\n        tree[node].Freq = 1;\n        s->depth[node] = 0;\n        s->opt_len--; if (stree) s->static_len -= stree[node].Len;\n        /* node is 0 or 1 so it does not have extra bits */\n    }\n    desc->max_code = max_code;\n\n    /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree,\n     * establish sub-heaps of increasing lengths:\n     */\n    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);\n\n    /* Construct the Huffman tree by repeatedly combining the least two\n     * frequent nodes.\n     */\n    node = elems;              /* next internal node of the tree */\n    do {\n        pqremove(s, tree, n);  /* n = node of least frequency */\n        m = s->heap[SMALLEST]; /* m = node of next least frequency */\n\n        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */\n        s->heap[--(s->heap_max)] = m;\n\n        /* Create a new node father of n and m */\n        tree[node].Freq = tree[n].Freq + tree[m].Freq;\n        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?\n                                s->depth[n] : s->depth[m]) + 1);\n        tree[n].Dad = tree[m].Dad = (ush)node;\n#ifdef DUMP_BL_TREE\n        if (tree == s->bl_tree) {\n            fprintf(stderr,\"\\nnode %d(%d), sons %d(%d) %d(%d)\",\n                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);\n        }\n#endif\n        /* and insert the new node in the heap */\n        s->heap[SMALLEST] = node++;\n        pqdownheap(s, tree, SMALLEST);\n\n    } while (s->heap_len >= 2);\n\n    s->heap[--(s->heap_max)] = s->heap[SMALLEST];\n\n    /* At this point, the fields freq and dad are set. We can now\n     * generate the bit lengths.\n     */\n    gen_bitlen(s, (tree_desc *)desc);\n\n    /* The field len is now set, we can generate the bit codes */\n    gen_codes ((ct_data *)tree, max_code, s->bl_count);\n}\n\n/* ===========================================================================\n * Scan a literal or distance tree to determine the frequencies of the codes\n * in the bit length tree.\n */\nlocal void scan_tree(deflate_state *s, ct_data *tree, int max_code) {\n    int n;                     /* iterates over all tree elements */\n    int prevlen = -1;          /* last emitted length */\n    int curlen;                /* length of current code */\n    int nextlen = tree[0].Len; /* length of next code */\n    int count = 0;             /* repeat count of the current code */\n    int max_count = 7;         /* max repeat count */\n    int min_count = 4;         /* min repeat count */\n\n    if (nextlen == 0) max_count = 138, min_count = 3;\n    tree[max_code + 1].Len = (ush)0xffff; /* guard */\n\n    for (n = 0; n <= max_code; n++) {\n        curlen = nextlen; nextlen = tree[n + 1].Len;\n        if (++count < max_count && curlen == nextlen) {\n            continue;\n        } else if (count < min_count) {\n            s->bl_tree[curlen].Freq += (ush)count;\n        } else if (curlen != 0) {\n            if (curlen != prevlen) s->bl_tree[curlen].Freq++;\n            s->bl_tree[REP_3_6].Freq++;\n        } else if (count <= 10) {\n            s->bl_tree[REPZ_3_10].Freq++;\n        } else {\n            s->bl_tree[REPZ_11_138].Freq++;\n        }\n        count = 0; prevlen = curlen;\n        if (nextlen == 0) {\n            max_count = 138, min_count = 3;\n        } else if (curlen == nextlen) {\n            max_count = 6, min_count = 3;\n        } else {\n            max_count = 7, min_count = 4;\n        }\n    }\n}\n\n/* ===========================================================================\n * Send a literal or distance tree in compressed form, using the codes in\n * bl_tree.\n */\nlocal void send_tree(deflate_state *s, ct_data *tree, int max_code) {\n    int n;                     /* iterates over all tree elements */\n    int prevlen = -1;          /* last emitted length */\n    int curlen;                /* length of current code */\n    int nextlen = tree[0].Len; /* length of next code */\n    int count = 0;             /* repeat count of the current code */\n    int max_count = 7;         /* max repeat count */\n    int min_count = 4;         /* min repeat count */\n\n    /* tree[max_code + 1].Len = -1; */  /* guard already set */\n    if (nextlen == 0) max_count = 138, min_count = 3;\n\n    for (n = 0; n <= max_code; n++) {\n        curlen = nextlen; nextlen = tree[n + 1].Len;\n        if (++count < max_count && curlen == nextlen) {\n            continue;\n        } else if (count < min_count) {\n            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);\n\n        } else if (curlen != 0) {\n            if (curlen != prevlen) {\n                send_code(s, curlen, s->bl_tree); count--;\n            }\n            Assert(count >= 3 && count <= 6, \" 3_6?\");\n            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2);\n\n        } else if (count <= 10) {\n            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3);\n\n        } else {\n            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7);\n        }\n        count = 0; prevlen = curlen;\n        if (nextlen == 0) {\n            max_count = 138, min_count = 3;\n        } else if (curlen == nextlen) {\n            max_count = 6, min_count = 3;\n        } else {\n            max_count = 7, min_count = 4;\n        }\n    }\n}\n\n/* ===========================================================================\n * Construct the Huffman tree for the bit lengths and return the index in\n * bl_order of the last bit length code to send.\n */\nlocal int build_bl_tree(deflate_state *s) {\n    int max_blindex;  /* index of last bit length code of non zero freq */\n\n    /* Determine the bit length frequencies for literal and distance trees */\n    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);\n    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);\n\n    /* Build the bit length tree: */\n    build_tree(s, (tree_desc *)(&(s->bl_desc)));\n    /* opt_len now includes the length of the tree representations, except the\n     * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts.\n     */\n\n    /* Determine the number of bit length codes to send. The pkzip format\n     * requires that at least 4 bit length codes be sent. (appnote.txt says\n     * 3 but the actual value used is 4.)\n     */\n    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {\n        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;\n    }\n    /* Update opt_len to include the bit length tree and counts */\n    s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4;\n    Tracev((stderr, \"\\ndyn trees: dyn %lu, stat %lu\",\n            s->opt_len, s->static_len));\n\n    return max_blindex;\n}\n\n/* ===========================================================================\n * Send the header for a block using dynamic Huffman trees: the counts, the\n * lengths of the bit length codes, the literal tree and the distance tree.\n * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n */\nlocal void send_all_trees(deflate_state *s, int lcodes, int dcodes,\n                          int blcodes) {\n    int rank;                    /* index in bl_order */\n\n    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, \"not enough codes\");\n    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,\n            \"too many codes\");\n    Tracev((stderr, \"\\nbl counts: \"));\n    send_bits(s, lcodes - 257, 5);  /* not +255 as stated in appnote.txt */\n    send_bits(s, dcodes - 1,   5);\n    send_bits(s, blcodes - 4,  4);  /* not -3 as stated in appnote.txt */\n    for (rank = 0; rank < blcodes; rank++) {\n        Tracev((stderr, \"\\nbl code %2d \", bl_order[rank]));\n        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);\n    }\n    Tracev((stderr, \"\\nbl tree: sent %lu\", s->bits_sent));\n\n    send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1);  /* literal tree */\n    Tracev((stderr, \"\\nlit tree: sent %lu\", s->bits_sent));\n\n    send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1);  /* distance tree */\n    Tracev((stderr, \"\\ndist tree: sent %lu\", s->bits_sent));\n}\n\n/* ===========================================================================\n * Send a stored block\n */\nvoid ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,\n                                    ulg stored_len, int last) {\n    send_bits(s, (STORED_BLOCK<<1) + last, 3);  /* send block type */\n    bi_windup(s);        /* align on byte boundary */\n    put_short(s, (ush)stored_len);\n    put_short(s, (ush)~stored_len);\n    if (stored_len)\n        zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);\n    s->pending += stored_len;\n#ifdef ZLIB_DEBUG\n    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;\n    s->compressed_len += (stored_len + 4) << 3;\n    s->bits_sent += 2*16;\n    s->bits_sent += stored_len << 3;\n#endif\n}\n\n/* ===========================================================================\n * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)\n */\nvoid ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) {\n    bi_flush(s);\n}\n\n/* ===========================================================================\n * Send one empty static block to give enough lookahead for inflate.\n * This takes 10 bits, of which 7 may remain in the bit buffer.\n */\nvoid ZLIB_INTERNAL _tr_align(deflate_state *s) {\n    send_bits(s, STATIC_TREES<<1, 3);\n    send_code(s, END_BLOCK, static_ltree);\n#ifdef ZLIB_DEBUG\n    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */\n#endif\n    bi_flush(s);\n}\n\n/* ===========================================================================\n * Send the block data compressed using the given Huffman trees\n */\nlocal void compress_block(deflate_state *s, const ct_data *ltree,\n                          const ct_data *dtree) {\n    unsigned dist;      /* distance of matched string */\n    int lc;             /* match length or unmatched char (if dist == 0) */\n    unsigned sx = 0;    /* running index in symbol buffers */\n    unsigned code;      /* the code to send */\n    int extra;          /* number of extra bits to send */\n\n    if (s->sym_next != 0) do {\n#ifdef LIT_MEM\n        dist = s->d_buf[sx];\n        lc = s->l_buf[sx++];\n#else\n        dist = s->sym_buf[sx++] & 0xff;\n        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;\n        lc = s->sym_buf[sx++];\n#endif\n        if (dist == 0) {\n            send_code(s, lc, ltree); /* send a literal byte */\n            Tracecv(isgraph(lc), (stderr,\" '%c' \", lc));\n        } else {\n            /* Here, lc is the match length - MIN_MATCH */\n            code = _length_code[lc];\n            send_code(s, code + LITERALS + 1, ltree);   /* send length code */\n            extra = extra_lbits[code];\n            if (extra != 0) {\n                lc -= base_length[code];\n                send_bits(s, lc, extra);       /* send the extra length bits */\n            }\n            dist--; /* dist is now the match distance - 1 */\n            code = d_code(dist);\n            Assert (code < D_CODES, \"bad d_code\");\n\n            send_code(s, code, dtree);       /* send the distance code */\n            extra = extra_dbits[code];\n            if (extra != 0) {\n                dist -= (unsigned)base_dist[code];\n                send_bits(s, (int)dist, extra); /* send the extra bits */\n            }\n        } /* literal or match pair ? */\n\n        /* Check for no overlay of pending_buf on needed symbols */\n#ifdef LIT_MEM\n        Assert(s->pending < 2 * (s->lit_bufsize + sx), \"pendingBuf overflow\");\n#else\n        Assert(s->pending < s->lit_bufsize + sx, \"pendingBuf overflow\");\n#endif\n\n    } while (sx < s->sym_next);\n\n    send_code(s, END_BLOCK, ltree);\n}\n\n/* ===========================================================================\n * Check if the data type is TEXT or BINARY, using the following algorithm:\n * - TEXT if the two conditions below are satisfied:\n *    a) There are no non-portable control characters belonging to the\n *       \"block list\" (0..6, 14..25, 28..31).\n *    b) There is at least one printable character belonging to the\n *       \"allow list\" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).\n * - BINARY otherwise.\n * - The following partially-portable control characters form a\n *   \"gray list\" that is ignored in this detection algorithm:\n *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).\n * IN assertion: the fields Freq of dyn_ltree are set.\n */\nlocal int detect_data_type(deflate_state *s) {\n    /* block_mask is the bit mask of block-listed bytes\n     * set bits 0..6, 14..25, and 28..31\n     * 0xf3ffc07f = binary 11110011111111111100000001111111\n     */\n    unsigned long block_mask = 0xf3ffc07fUL;\n    int n;\n\n    /* Check for non-textual (\"block-listed\") bytes. */\n    for (n = 0; n <= 31; n++, block_mask >>= 1)\n        if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))\n            return Z_BINARY;\n\n    /* Check for textual (\"allow-listed\") bytes. */\n    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0\n            || s->dyn_ltree[13].Freq != 0)\n        return Z_TEXT;\n    for (n = 32; n < LITERALS; n++)\n        if (s->dyn_ltree[n].Freq != 0)\n            return Z_TEXT;\n\n    /* There are no \"block-listed\" or \"allow-listed\" bytes:\n     * this stream either is empty or has tolerated (\"gray-listed\") bytes only.\n     */\n    return Z_BINARY;\n}\n\n/* ===========================================================================\n * Determine the best encoding for the current block: dynamic trees, static\n * trees or store, and write out the encoded block.\n */\nvoid ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,\n                                   ulg stored_len, int last) {\n    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */\n    int max_blindex = 0;  /* index of last bit length code of non zero freq */\n\n    /* Build the Huffman trees unless a stored block is forced */\n    if (s->level > 0) {\n\n        /* Check if the file is binary or text */\n        if (s->strm->data_type == Z_UNKNOWN)\n            s->strm->data_type = detect_data_type(s);\n\n        /* Construct the literal and distance trees */\n        build_tree(s, (tree_desc *)(&(s->l_desc)));\n        Tracev((stderr, \"\\nlit data: dyn %lu, stat %lu\", s->opt_len,\n                s->static_len));\n\n        build_tree(s, (tree_desc *)(&(s->d_desc)));\n        Tracev((stderr, \"\\ndist data: dyn %lu, stat %lu\", s->opt_len,\n                s->static_len));\n        /* At this point, opt_len and static_len are the total bit lengths of\n         * the compressed block data, excluding the tree representations.\n         */\n\n        /* Build the bit length tree for the above two trees, and get the index\n         * in bl_order of the last bit length code to send.\n         */\n        max_blindex = build_bl_tree(s);\n\n        /* Determine the best encoding. Compute the block lengths in bytes. */\n        opt_lenb = (s->opt_len + 3 + 7) >> 3;\n        static_lenb = (s->static_len + 3 + 7) >> 3;\n\n        Tracev((stderr, \"\\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u \",\n                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,\n                s->sym_next / 3));\n\n#ifndef FORCE_STATIC\n        if (static_lenb <= opt_lenb || s->strategy == Z_FIXED)\n#endif\n            opt_lenb = static_lenb;\n\n    } else {\n        Assert(buf != (char*)0, \"lost buf\");\n        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */\n    }\n\n#ifdef FORCE_STORED\n    if (buf != (char*)0) { /* force stored block */\n#else\n    if (stored_len + 4 <= opt_lenb && buf != (char*)0) {\n                       /* 4: two words for the lengths */\n#endif\n        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n         * Otherwise we can't have processed more than WSIZE input bytes since\n         * the last block flush, because compression would have been\n         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n         * transform a block into a stored block.\n         */\n        _tr_stored_block(s, buf, stored_len, last);\n\n    } else if (static_lenb == opt_lenb) {\n        send_bits(s, (STATIC_TREES<<1) + last, 3);\n        compress_block(s, (const ct_data *)static_ltree,\n                       (const ct_data *)static_dtree);\n#ifdef ZLIB_DEBUG\n        s->compressed_len += 3 + s->static_len;\n#endif\n    } else {\n        send_bits(s, (DYN_TREES<<1) + last, 3);\n        send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1,\n                       max_blindex + 1);\n        compress_block(s, (const ct_data *)s->dyn_ltree,\n                       (const ct_data *)s->dyn_dtree);\n#ifdef ZLIB_DEBUG\n        s->compressed_len += 3 + s->opt_len;\n#endif\n    }\n    Assert (s->compressed_len == s->bits_sent, \"bad compressed size\");\n    /* The above check is made mod 2^32, for files larger than 512 MB\n     * and uLong implemented on 32 bits.\n     */\n    init_block(s);\n\n    if (last) {\n        bi_windup(s);\n#ifdef ZLIB_DEBUG\n        s->compressed_len += 7;  /* align on byte boundary */\n#endif\n    }\n    Tracev((stderr,\"\\ncomprlen %lu(%lu) \", s->compressed_len >> 3,\n           s->compressed_len - 7*(ulg)last));\n}\n\n/* ===========================================================================\n * Save the match info and tally the frequency counts. Return true if\n * the current block must be flushed.\n */\nint ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {\n#ifdef LIT_MEM\n    s->d_buf[s->sym_next] = (ush)dist;\n    s->l_buf[s->sym_next++] = (uch)lc;\n#else\n    s->sym_buf[s->sym_next++] = (uch)dist;\n    s->sym_buf[s->sym_next++] = (uch)(dist >> 8);\n    s->sym_buf[s->sym_next++] = (uch)lc;\n#endif\n    if (dist == 0) {\n        /* lc is the unmatched char */\n        s->dyn_ltree[lc].Freq++;\n    } else {\n        s->matches++;\n        /* Here, lc is the match length - MIN_MATCH */\n        dist--;             /* dist = match distance - 1 */\n        Assert((ush)dist < (ush)MAX_DIST(s) &&\n               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&\n               (ush)d_code(dist) < (ush)D_CODES,  \"_tr_tally: bad match\");\n\n        s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++;\n        s->dyn_dtree[d_code(dist)].Freq++;\n    }\n    return (s->sym_next == s->sym_end);\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/trees.h",
    "content": "/* header created automatically with -DGEN_TREES_H */\n\nlocal const ct_data static_ltree[L_CODES+2] = {\n{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},\n{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},\n{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},\n{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},\n{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},\n{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},\n{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},\n{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},\n{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},\n{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},\n{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},\n{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},\n{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},\n{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},\n{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},\n{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},\n{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},\n{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},\n{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},\n{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},\n{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},\n{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},\n{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},\n{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},\n{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},\n{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},\n{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},\n{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},\n{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},\n{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},\n{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},\n{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},\n{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},\n{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},\n{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},\n{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},\n{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},\n{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},\n{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},\n{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},\n{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},\n{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},\n{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},\n{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},\n{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},\n{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},\n{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},\n{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},\n{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},\n{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},\n{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},\n{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},\n{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},\n{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},\n{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},\n{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},\n{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},\n{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}\n};\n\nlocal const ct_data static_dtree[D_CODES] = {\n{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},\n{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},\n{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},\n{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},\n{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},\n{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}\n};\n\nconst uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,\n 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,\n10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,\n18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29\n};\n\nconst uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,\n13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,\n19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,\n22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28\n};\n\nlocal const int base_length[LENGTH_CODES] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,\n64, 80, 96, 112, 128, 160, 192, 224, 0\n};\n\nlocal const int base_dist[D_CODES] = {\n    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,\n   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,\n 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576\n};\n\n"
  },
  {
    "path": "vendor/core/vendor/zlib/uncompr.c",
    "content": "/* uncompr.c -- decompress a memory buffer\n * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#define ZLIB_INTERNAL\n#include \"zlib.h\"\n\n/* ===========================================================================\n     Decompresses the source buffer into the destination buffer.  *sourceLen is\n   the byte length of the source buffer. Upon entry, *destLen is the total size\n   of the destination buffer, which must be large enough to hold the entire\n   uncompressed data. (The size of the uncompressed data must have been saved\n   previously by the compressor and transmitted to the decompressor by some\n   mechanism outside the scope of this compression library.) Upon exit,\n   *destLen is the size of the decompressed data and *sourceLen is the number\n   of source bytes consumed. Upon return, source + *sourceLen points to the\n   first unused input byte.\n\n     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer, or\n   Z_DATA_ERROR if the input data was corrupted, including if the input data is\n   an incomplete zlib stream.\n\n     The _z versions of the functions take size_t length arguments.\n*/\nint ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source,\n                          z_size_t *sourceLen) {\n    z_stream stream;\n    int err;\n    const uInt max = (uInt)-1;\n    z_size_t len, left;\n\n    if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) ||\n        destLen == NULL || (*destLen > 0 && dest == NULL))\n        return Z_STREAM_ERROR;\n\n    len = *sourceLen;\n    left = *destLen;\n    if (left == 0 && dest == Z_NULL)\n        dest = (Bytef *)&stream.reserved;       /* next_out cannot be NULL */\n\n    stream.next_in = (z_const Bytef *)source;\n    stream.avail_in = 0;\n    stream.zalloc = (alloc_func)0;\n    stream.zfree = (free_func)0;\n    stream.opaque = (voidpf)0;\n\n    err = inflateInit(&stream);\n    if (err != Z_OK) return err;\n\n    stream.next_out = dest;\n    stream.avail_out = 0;\n\n    do {\n        if (stream.avail_out == 0) {\n            stream.avail_out = left > (z_size_t)max ? max : (uInt)left;\n            left -= stream.avail_out;\n        }\n        if (stream.avail_in == 0) {\n            stream.avail_in = len > (z_size_t)max ? max : (uInt)len;\n            len -= stream.avail_in;\n        }\n        err = inflate(&stream, Z_NO_FLUSH);\n    } while (err == Z_OK);\n\n    /* Set len and left to the unused input data and unused output space. Set\n       *sourceLen to the amount of input consumed. Set *destLen to the amount\n       of data produced. */\n    len += stream.avail_in;\n    left += stream.avail_out;\n    *sourceLen -= len;\n    *destLen -= left;\n\n    inflateEnd(&stream);\n    return err == Z_STREAM_END ? Z_OK :\n           err == Z_NEED_DICT ? Z_DATA_ERROR  :\n           err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR :\n           err;\n}\nint ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,\n                        uLong *sourceLen) {\n    int ret;\n    z_size_t got = *destLen, used = *sourceLen;\n    ret = uncompress2_z(dest, &got, source, &used);\n    *sourceLen = (uLong)used;\n    *destLen = (uLong)got;\n    return ret;\n}\nint ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source,\n                         z_size_t sourceLen) {\n    z_size_t used = sourceLen;\n    return uncompress2_z(dest, destLen, source, &used);\n}\nint ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,\n                       uLong sourceLen) {\n    uLong used = sourceLen;\n    return uncompress2(dest, destLen, source, &used);\n}\n"
  },
  {
    "path": "vendor/core/vendor/zlib/zconf.h",
    "content": "/* zconf.h -- configuration of the zlib compression library\n * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZCONF_H\n#define ZCONF_H\n\n/*\n * If you *really* need a unique prefix for all types and library functions,\n * compile with -DZ_PREFIX. The \"standard\" zlib should be compiled without it.\n * Even better than compiling with -DZ_PREFIX would be to use configure to set\n * this permanently in zconf.h using \"./configure --zprefix\".\n */\n#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */\n#  define Z_PREFIX_SET\n\n/* all linked symbols and init macros */\n#  define _dist_code            z__dist_code\n#  define _length_code          z__length_code\n#  define _tr_align             z__tr_align\n#  define _tr_flush_bits        z__tr_flush_bits\n#  define _tr_flush_block       z__tr_flush_block\n#  define _tr_init              z__tr_init\n#  define _tr_stored_block      z__tr_stored_block\n#  define _tr_tally             z__tr_tally\n#  define adler32               z_adler32\n#  define adler32_combine       z_adler32_combine\n#  define adler32_combine64     z_adler32_combine64\n#  define adler32_z             z_adler32_z\n#  ifndef Z_SOLO\n#    define compress              z_compress\n#    define compress2             z_compress2\n#    define compress_z            z_compress_z\n#    define compress2_z           z_compress2_z\n#    define compressBound         z_compressBound\n#    define compressBound_z       z_compressBound_z\n#  endif\n#  define crc32                 z_crc32\n#  define crc32_combine         z_crc32_combine\n#  define crc32_combine64       z_crc32_combine64\n#  define crc32_combine_gen     z_crc32_combine_gen\n#  define crc32_combine_gen64   z_crc32_combine_gen64\n#  define crc32_combine_op      z_crc32_combine_op\n#  define crc32_z               z_crc32_z\n#  define deflate               z_deflate\n#  define deflateBound          z_deflateBound\n#  define deflateBound_z        z_deflateBound_z\n#  define deflateCopy           z_deflateCopy\n#  define deflateEnd            z_deflateEnd\n#  define deflateGetDictionary  z_deflateGetDictionary\n#  define deflateInit           z_deflateInit\n#  define deflateInit2          z_deflateInit2\n#  define deflateInit2_         z_deflateInit2_\n#  define deflateInit_          z_deflateInit_\n#  define deflateParams         z_deflateParams\n#  define deflatePending        z_deflatePending\n#  define deflatePrime          z_deflatePrime\n#  define deflateReset          z_deflateReset\n#  define deflateResetKeep      z_deflateResetKeep\n#  define deflateSetDictionary  z_deflateSetDictionary\n#  define deflateSetHeader      z_deflateSetHeader\n#  define deflateTune           z_deflateTune\n#  define deflateUsed           z_deflateUsed\n#  define deflate_copyright     z_deflate_copyright\n#  define get_crc_table         z_get_crc_table\n#  ifndef Z_SOLO\n#    define gz_error              z_gz_error\n#    define gz_intmax             z_gz_intmax\n#    define gz_strwinerror        z_gz_strwinerror\n#    define gzbuffer              z_gzbuffer\n#    define gzclearerr            z_gzclearerr\n#    define gzclose               z_gzclose\n#    define gzclose_r             z_gzclose_r\n#    define gzclose_w             z_gzclose_w\n#    define gzdirect              z_gzdirect\n#    define gzdopen               z_gzdopen\n#    define gzeof                 z_gzeof\n#    define gzerror               z_gzerror\n#    define gzflush               z_gzflush\n#    define gzfread               z_gzfread\n#    define gzfwrite              z_gzfwrite\n#    define gzgetc                z_gzgetc\n#    define gzgetc_               z_gzgetc_\n#    define gzgets                z_gzgets\n#    define gzoffset              z_gzoffset\n#    define gzoffset64            z_gzoffset64\n#    define gzopen                z_gzopen\n#    define gzopen64              z_gzopen64\n#    ifdef _WIN32\n#      define gzopen_w              z_gzopen_w\n#    endif\n#    define gzprintf              z_gzprintf\n#    define gzputc                z_gzputc\n#    define gzputs                z_gzputs\n#    define gzread                z_gzread\n#    define gzrewind              z_gzrewind\n#    define gzseek                z_gzseek\n#    define gzseek64              z_gzseek64\n#    define gzsetparams           z_gzsetparams\n#    define gztell                z_gztell\n#    define gztell64              z_gztell64\n#    define gzungetc              z_gzungetc\n#    define gzvprintf             z_gzvprintf\n#    define gzwrite               z_gzwrite\n#  endif\n#  define inflate               z_inflate\n#  define inflateBack           z_inflateBack\n#  define inflateBackEnd        z_inflateBackEnd\n#  define inflateBackInit       z_inflateBackInit\n#  define inflateBackInit_      z_inflateBackInit_\n#  define inflateCodesUsed      z_inflateCodesUsed\n#  define inflateCopy           z_inflateCopy\n#  define inflateEnd            z_inflateEnd\n#  define inflateGetDictionary  z_inflateGetDictionary\n#  define inflateGetHeader      z_inflateGetHeader\n#  define inflateInit           z_inflateInit\n#  define inflateInit2          z_inflateInit2\n#  define inflateInit2_         z_inflateInit2_\n#  define inflateInit_          z_inflateInit_\n#  define inflateMark           z_inflateMark\n#  define inflatePrime          z_inflatePrime\n#  define inflateReset          z_inflateReset\n#  define inflateReset2         z_inflateReset2\n#  define inflateResetKeep      z_inflateResetKeep\n#  define inflateSetDictionary  z_inflateSetDictionary\n#  define inflateSync           z_inflateSync\n#  define inflateSyncPoint      z_inflateSyncPoint\n#  define inflateUndermine      z_inflateUndermine\n#  define inflateValidate       z_inflateValidate\n#  define inflate_copyright     z_inflate_copyright\n#  define inflate_fast          z_inflate_fast\n#  define inflate_table         z_inflate_table\n#  define inflate_fixed         z_inflate_fixed\n#  ifndef Z_SOLO\n#    define uncompress            z_uncompress\n#    define uncompress2           z_uncompress2\n#    define uncompress_z          z_uncompress_z\n#    define uncompress2_z         z_uncompress2_z\n#  endif\n#  define zError                z_zError\n#  ifndef Z_SOLO\n#    define zcalloc               z_zcalloc\n#    define zcfree                z_zcfree\n#  endif\n#  define zlibCompileFlags      z_zlibCompileFlags\n#  define zlibVersion           z_zlibVersion\n\n/* all zlib typedefs in zlib.h and zconf.h */\n#  define Byte                  z_Byte\n#  define Bytef                 z_Bytef\n#  define alloc_func            z_alloc_func\n#  define charf                 z_charf\n#  define free_func             z_free_func\n#  ifndef Z_SOLO\n#    define gzFile                z_gzFile\n#  endif\n#  define gz_header             z_gz_header\n#  define gz_headerp            z_gz_headerp\n#  define in_func               z_in_func\n#  define intf                  z_intf\n#  define out_func              z_out_func\n#  define uInt                  z_uInt\n#  define uIntf                 z_uIntf\n#  define uLong                 z_uLong\n#  define uLongf                z_uLongf\n#  define voidp                 z_voidp\n#  define voidpc                z_voidpc\n#  define voidpf                z_voidpf\n\n/* all zlib structs in zlib.h and zconf.h */\n#  define gz_header_s           z_gz_header_s\n#  define internal_state        z_internal_state\n\n#endif\n\n#if defined(__MSDOS__) && !defined(MSDOS)\n#  define MSDOS\n#endif\n#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)\n#  define OS2\n#endif\n#if defined(_WINDOWS) && !defined(WINDOWS)\n#  define WINDOWS\n#endif\n#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)\n#  ifndef WIN32\n#    define WIN32\n#  endif\n#endif\n#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)\n#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)\n#    ifndef SYS16BIT\n#      define SYS16BIT\n#    endif\n#  endif\n#endif\n\n/*\n * Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n * than 64k bytes at a time (needed on systems with 16-bit int).\n */\n#ifdef SYS16BIT\n#  define MAXSEG_64K\n#endif\n#ifdef MSDOS\n#  define UNALIGNED_OK\n#endif\n\n#ifdef __STDC_VERSION__\n#  ifndef STDC\n#    define STDC\n#  endif\n#  if __STDC_VERSION__ >= 199901L\n#    ifndef STDC99\n#      define STDC99\n#    endif\n#  endif\n#endif\n#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))\n#  define STDC\n#endif\n#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))\n#  define STDC\n#endif\n\n#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */\n#  define STDC\n#endif\n\n#ifndef STDC\n#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */\n#    define const       /* note: need a more gentle solution here */\n#  endif\n#endif\n\n#ifndef z_const\n#  ifdef ZLIB_CONST\n#    define z_const const\n#  else\n#    define z_const\n#  endif\n#endif\n\n#ifdef Z_SOLO\n#  ifdef _WIN64\n     typedef unsigned long long z_size_t;\n#  else\n     typedef unsigned long z_size_t;\n#  endif\n#else\n#  define z_longlong long long\n#  if defined(NO_SIZE_T)\n     typedef unsigned NO_SIZE_T z_size_t;\n#  elif defined(STDC)\n#    include <stddef.h>\n     typedef size_t z_size_t;\n#  else\n     typedef unsigned long z_size_t;\n#  endif\n#  undef z_longlong\n#endif\n\n/* Maximum value for memLevel in deflateInit2 */\n#ifndef MAX_MEM_LEVEL\n#  ifdef MAXSEG_64K\n#    define MAX_MEM_LEVEL 8\n#  else\n#    define MAX_MEM_LEVEL 9\n#  endif\n#endif\n\n/* Maximum value for windowBits in deflateInit2 and inflateInit2.\n * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files\n * created by gzip. (Files created by minigzip can still be extracted by\n * gzip.)\n */\n#ifndef MAX_WBITS\n#  define MAX_WBITS   15 /* 32K LZ77 window */\n#endif\n\n/* The memory requirements for deflate are (in bytes):\n            (1 << (windowBits+2)) +  (1 << (memLevel+9))\n that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)\n plus a few kilobytes for small objects. For example, if you want to reduce\n the default memory requirements from 256K to 128K, compile with\n     make CFLAGS=\"-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7\"\n Of course this will generally degrade compression (there's no free lunch).\n\n   The memory requirements for inflate are (in bytes) 1 << windowBits\n that is, 32K for windowBits=15 (default value) plus about 7 kilobytes\n for small objects.\n*/\n\n                        /* Type declarations */\n\n#ifndef OF /* function prototypes */\n#  ifdef STDC\n#    define OF(args)  args\n#  else\n#    define OF(args)  ()\n#  endif\n#endif\n\n/* The following definitions for FAR are needed only for MSDOS mixed\n * model programming (small or medium model with some far allocations).\n * This was tested only with MSC; for other MSDOS compilers you may have\n * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,\n * just define FAR to be empty.\n */\n#ifdef SYS16BIT\n#  if defined(M_I86SM) || defined(M_I86MM)\n     /* MSC small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef _MSC_VER\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#  if (defined(__SMALL__) || defined(__MEDIUM__))\n     /* Turbo C small or medium model */\n#    define SMALL_MEDIUM\n#    ifdef __BORLANDC__\n#      define FAR _far\n#    else\n#      define FAR far\n#    endif\n#  endif\n#endif\n\n#if defined(WINDOWS) || defined(WIN32)\n   /* If building or using zlib as a DLL, define ZLIB_DLL.\n    * This is not mandatory, but it offers a little performance increase.\n    */\n#  ifdef ZLIB_DLL\n#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))\n#      ifdef ZLIB_INTERNAL\n#        define ZEXTERN extern __declspec(dllexport)\n#      else\n#        define ZEXTERN extern __declspec(dllimport)\n#      endif\n#    endif\n#  endif  /* ZLIB_DLL */\n   /* If building or using zlib with the WINAPI/WINAPIV calling convention,\n    * define ZLIB_WINAPI.\n    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.\n    */\n#  ifdef ZLIB_WINAPI\n#    ifdef FAR\n#      undef FAR\n#    endif\n#    ifndef WIN32_LEAN_AND_MEAN\n#      define WIN32_LEAN_AND_MEAN\n#    endif\n#    include <windows.h>\n     /* No need for _export, use ZLIB.DEF instead. */\n     /* For complete Windows compatibility, use WINAPI, not __stdcall. */\n#    define ZEXPORT WINAPI\n#    ifdef WIN32\n#      define ZEXPORTVA WINAPIV\n#    else\n#      define ZEXPORTVA FAR CDECL\n#    endif\n#  endif\n#endif\n\n#if defined (__BEOS__)\n#  ifdef ZLIB_DLL\n#    ifdef ZLIB_INTERNAL\n#      define ZEXPORT   __declspec(dllexport)\n#      define ZEXPORTVA __declspec(dllexport)\n#    else\n#      define ZEXPORT   __declspec(dllimport)\n#      define ZEXPORTVA __declspec(dllimport)\n#    endif\n#  endif\n#endif\n\n#ifndef ZEXTERN\n#  define ZEXTERN extern\n#endif\n#ifndef ZEXPORT\n#  define ZEXPORT\n#endif\n#ifndef ZEXPORTVA\n#  define ZEXPORTVA\n#endif\n\n#ifndef FAR\n#  define FAR\n#endif\n\n#if !defined(__MACTYPES__)\ntypedef unsigned char  Byte;  /* 8 bits */\n#endif\ntypedef unsigned int   uInt;  /* 16 bits or more */\ntypedef unsigned long  uLong; /* 32 bits or more */\n\n#ifdef SMALL_MEDIUM\n   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */\n#  define Bytef Byte FAR\n#else\n   typedef Byte  FAR Bytef;\n#endif\ntypedef char  FAR charf;\ntypedef int   FAR intf;\ntypedef uInt  FAR uIntf;\ntypedef uLong FAR uLongf;\n\n#ifdef STDC\n   typedef void const *voidpc;\n   typedef void FAR   *voidpf;\n   typedef void       *voidp;\n#else\n   typedef Byte const *voidpc;\n   typedef Byte FAR   *voidpf;\n   typedef Byte       *voidp;\n#endif\n\n#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)\n#  include <limits.h>\n#  if (UINT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned\n#  elif (ULONG_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned long\n#  elif (USHRT_MAX == 0xffffffffUL)\n#    define Z_U4 unsigned short\n#  endif\n#endif\n\n#ifdef Z_U4\n   typedef Z_U4 z_crc_t;\n#else\n   typedef unsigned long z_crc_t;\n#endif\n\n#if HAVE_UNISTD_H-0     /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_UNISTD_H\n#endif\n\n#if HAVE_STDARG_H-0     /* may be set to #if 1 by ./configure */\n#  define Z_HAVE_STDARG_H\n#endif\n\n#ifdef STDC\n#  ifndef Z_SOLO\n#    include <sys/types.h>      /* for off_t */\n#  endif\n#endif\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\n#    include <stdarg.h>         /* for va_list */\n#  endif\n#endif\n\n#ifdef _WIN32\n#  ifndef Z_SOLO\n#    include <stddef.h>         /* for wchar_t */\n#  endif\n#endif\n\n/* a little trick to accommodate both \"#define _LARGEFILE64_SOURCE\" and\n * \"#define _LARGEFILE64_SOURCE 1\" as requesting 64-bit operations, (even\n * though the former does not conform to the LFS document), but considering\n * both \"#undef _LARGEFILE64_SOURCE\" and \"#define _LARGEFILE64_SOURCE 0\" as\n * equivalently requesting no 64-bit operations\n */\n#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1\n#  undef _LARGEFILE64_SOURCE\n#endif\n\n#ifndef Z_HAVE_UNISTD_H\n#  if defined(__WATCOMC__) || defined(__GO32__) || \\\n      (defined(_LARGEFILE64_SOURCE) && !defined(_WIN32))\n#    define Z_HAVE_UNISTD_H\n#  endif\n#endif\n#ifndef Z_SOLO\n#  if defined(Z_HAVE_UNISTD_H)\n#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */\n#    ifdef VMS\n#      include <unixio.h>       /* for off_t */\n#    endif\n#    ifndef z_off_t\n#      define z_off_t off_t\n#    endif\n#  endif\n#endif\n\n#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0\n#  define Z_LFS64\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)\n#  define Z_LARGE64\n#endif\n\n#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)\n#  define Z_WANT64\n#endif\n\n#if !defined(SEEK_SET) && !defined(Z_SOLO)\n#  define SEEK_SET        0       /* Seek from beginning of file.  */\n#  define SEEK_CUR        1       /* Seek from current position.  */\n#  define SEEK_END        2       /* Set file pointer to EOF plus \"offset\" */\n#endif\n\n#ifndef z_off_t\n#  define z_off_t long long\n#endif\n\n#if !defined(_WIN32) && defined(Z_LARGE64)\n#  define z_off64_t off64_t\n#elif defined(__MINGW32__)\n#  define z_off64_t long long\n#elif defined(_WIN32) && !defined(__GNUC__)\n#  define z_off64_t __int64\n#elif defined(__GO32__)\n#  define z_off64_t offset_t\n#else\n#  define z_off64_t z_off_t\n#endif\n\n/* MVS linker does not support external names larger than 8 bytes */\n#if defined(__MVS__)\n  #pragma map(deflateInit_,\"DEIN\")\n  #pragma map(deflateInit2_,\"DEIN2\")\n  #pragma map(deflateEnd,\"DEEND\")\n  #pragma map(deflateBound,\"DEBND\")\n  #pragma map(inflateInit_,\"ININ\")\n  #pragma map(inflateInit2_,\"ININ2\")\n  #pragma map(inflateEnd,\"INEND\")\n  #pragma map(inflateSync,\"INSY\")\n  #pragma map(inflateSetDictionary,\"INSEDI\")\n  #pragma map(compressBound,\"CMBND\")\n  #pragma map(inflate_table,\"INTABL\")\n  #pragma map(inflate_fast,\"INFA\")\n  #pragma map(inflate_copyright,\"INCOPY\")\n#endif\n\n#endif /* ZCONF_H */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/zlib.h",
    "content": "/* zlib.h -- interface of the 'zlib' general purpose compression library\n  version 1.3.2, February 17th, 2026\n\n  Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\n\n  The data format used by the zlib library is described by RFCs (Request for\n  Comments) 1950 to 1952 at https://datatracker.ietf.org/doc/html/rfc1950\n  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).\n*/\n\n#ifndef ZLIB_H\n#define ZLIB_H\n\n#ifdef ZLIB_BUILD\n#  include <zconf.h>\n#else\n# include \"zconf.h\"\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define ZLIB_VERSION \"1.3.2\"\n#define ZLIB_VERNUM 0x1320\n#define ZLIB_VER_MAJOR 1\n#define ZLIB_VER_MINOR 3\n#define ZLIB_VER_REVISION 2\n#define ZLIB_VER_SUBREVISION 0\n\n/*\n    The 'zlib' compression library provides in-memory compression and\n  decompression functions, including integrity checks of the uncompressed data.\n  This version of the library supports only one compression method (deflation)\n  but other algorithms will be added later and will have the same stream\n  interface.\n\n    Compression can be done in a single step if the buffers are large enough,\n  or can be done by repeated calls of the compression function.  In the latter\n  case, the application must provide more input and/or consume the output\n  (providing more output space) before each call.\n\n    The compressed data format used by default by the in-memory functions is\n  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped\n  around a deflate stream, which is itself documented in RFC 1951.\n\n    The library also supports reading and writing files in gzip (.gz) format\n  with an interface similar to that of stdio using the functions that start\n  with \"gz\".  The gzip format is different from the zlib format.  gzip is a\n  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.\n\n    This library can optionally read and write gzip and raw deflate streams in\n  memory as well.\n\n    The zlib format was designed to be compact and fast for use in memory\n  and on communications channels.  The gzip format was designed for single-\n  file compression on file systems, has a larger header than zlib to maintain\n  directory information, and uses a different, slower check method than zlib.\n\n    The library does not install any signal handler.  The decoder checks\n  the consistency of the compressed data, so the library should never crash\n  even in the case of corrupted input.\n*/\n\ntypedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size);\ntypedef void   (*free_func)(voidpf opaque, voidpf address);\n\nstruct internal_state;\n\ntypedef struct z_stream_s {\n    z_const Bytef *next_in;     /* next input byte */\n    uInt     avail_in;  /* number of bytes available at next_in */\n    uLong    total_in;  /* total number of input bytes read so far */\n\n    Bytef    *next_out; /* next output byte will go here */\n    uInt     avail_out; /* remaining free space at next_out */\n    uLong    total_out; /* total number of bytes output so far */\n\n    z_const char *msg;  /* last error message, NULL if no error */\n    struct internal_state FAR *state; /* not visible by applications */\n\n    alloc_func zalloc;  /* used to allocate the internal state */\n    free_func  zfree;   /* used to free the internal state */\n    voidpf     opaque;  /* private data object passed to zalloc and zfree */\n\n    int     data_type;  /* best guess about the data type: binary or text\n                           for deflate, or the decoding state for inflate */\n    uLong   adler;      /* Adler-32 or CRC-32 value of the uncompressed data */\n    uLong   reserved;   /* reserved for future use */\n} z_stream;\n\ntypedef z_stream FAR *z_streamp;\n\n/*\n     gzip header information passed to and from zlib routines.  See RFC 1952\n  for more details on the meanings of these fields.\n*/\ntypedef struct gz_header_s {\n    int     text;       /* true if compressed data believed to be text */\n    uLong   time;       /* modification time */\n    int     xflags;     /* extra flags (not used when writing a gzip file) */\n    int     os;         /* operating system */\n    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */\n    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */\n    uInt    extra_max;  /* space at extra (only when reading header) */\n    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */\n    uInt    name_max;   /* space at name (only when reading header) */\n    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */\n    uInt    comm_max;   /* space at comment (only when reading header) */\n    int     hcrc;       /* true if there was or will be a header crc */\n    int     done;       /* true when done reading gzip header (not used\n                           when writing a gzip file) */\n} gz_header;\n\ntypedef gz_header FAR *gz_headerp;\n\n/*\n     The application must update next_in and avail_in when avail_in has dropped\n   to zero.  It must update next_out and avail_out when avail_out has dropped\n   to zero.  The application must initialize zalloc, zfree and opaque before\n   calling the init function.  All other fields are set by the compression\n   library and must not be updated by the application.\n\n     The opaque value provided by the application will be passed as the first\n   parameter for calls of zalloc and zfree.  This can be useful for custom\n   memory management.  The compression library attaches no meaning to the\n   opaque value.\n\n     zalloc must return Z_NULL if there is not enough memory for the object.\n   If zlib is used in a multi-threaded application, zalloc and zfree must be\n   thread safe.  In that case, zlib is thread-safe.  When zalloc and zfree are\n   Z_NULL on entry to the initialization function, they are set to internal\n   routines that use the standard library functions malloc() and free().\n\n     On 16-bit systems, the functions zalloc and zfree must be able to allocate\n   exactly 65536 bytes, but will not be required to allocate more than this if\n   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers\n   returned by zalloc for objects of exactly 65536 bytes *must* have their\n   offset normalized to zero.  The default allocation function provided by this\n   library ensures this (see zutil.c).  To reduce memory requirements and avoid\n   any allocation of 64K objects, at the expense of compression ratio, compile\n   the library with -DMAX_WBITS=14 (see zconf.h).\n\n     The fields total_in and total_out can be used for statistics or progress\n   reports.  After compression, total_in holds the total size of the\n   uncompressed data and may be saved for use by the decompressor (particularly\n   if the decompressor wants to decompress everything in a single step).\n*/\n\n                        /* constants */\n\n#define Z_NO_FLUSH      0\n#define Z_PARTIAL_FLUSH 1\n#define Z_SYNC_FLUSH    2\n#define Z_FULL_FLUSH    3\n#define Z_FINISH        4\n#define Z_BLOCK         5\n#define Z_TREES         6\n/* Allowed flush values; see deflate() and inflate() below for details */\n\n#define Z_OK            0\n#define Z_STREAM_END    1\n#define Z_NEED_DICT     2\n#define Z_ERRNO        (-1)\n#define Z_STREAM_ERROR (-2)\n#define Z_DATA_ERROR   (-3)\n#define Z_MEM_ERROR    (-4)\n#define Z_BUF_ERROR    (-5)\n#define Z_VERSION_ERROR (-6)\n/* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\n\n#define Z_NO_COMPRESSION         0\n#define Z_BEST_SPEED             1\n#define Z_BEST_COMPRESSION       9\n#define Z_DEFAULT_COMPRESSION  (-1)\n/* compression levels */\n\n#define Z_FILTERED            1\n#define Z_HUFFMAN_ONLY        2\n#define Z_RLE                 3\n#define Z_FIXED               4\n#define Z_DEFAULT_STRATEGY    0\n/* compression strategy; see deflateInit2() below for details */\n\n#define Z_BINARY   0\n#define Z_TEXT     1\n#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */\n#define Z_UNKNOWN  2\n/* Possible values of the data_type field for deflate() */\n\n#define Z_DEFLATED   8\n/* The deflate compression method (the only one supported in this version) */\n\n#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */\n\n#define zlib_version zlibVersion()\n/* for compatibility with versions < 1.0.2 */\n\n\n                        /* basic functions */\n\nZEXTERN const char * ZEXPORT zlibVersion(void);\n/* The application can compare zlibVersion and ZLIB_VERSION for consistency.\n   If the first character differs, the library code actually used is not\n   compatible with the zlib.h header file used by the application.  This check\n   is automatically made by deflateInit and inflateInit.\n */\n\n/*\nZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level);\n\n     Initializes the internal stream state for compression.  The fields\n   zalloc, zfree and opaque must be initialized before by the caller.  If\n   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default\n   allocation functions.  total_in, total_out, adler, and msg are initialized.\n\n     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:\n   1 gives best speed, 9 gives best compression, 0 gives no compression at all\n   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION\n   requests a default compromise between speed and compression (currently\n   equivalent to level 6).\n\n     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if level is not a valid compression level, or\n   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible\n   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null\n   if there is no error message.  deflateInit does not perform any compression:\n   this will be done by deflate().\n*/\n\n\nZEXTERN int ZEXPORT deflate(z_streamp strm, int flush);\n/*\n    deflate compresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n    The detailed semantics are as follows.  deflate performs one or both of the\n  following actions:\n\n  - Compress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), next_in and avail_in are updated and\n    processing will resume at this point for the next call of deflate().\n\n  - Generate more output starting at next_out and update next_out and avail_out\n    accordingly.  This action is forced if the parameter flush is non zero.\n    Forcing flush frequently degrades the compression ratio, so this parameter\n    should be set only when necessary.  Some output may be provided even if\n    flush is zero.\n\n    Before the call of deflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating avail_in or avail_out accordingly; avail_out should\n  never be zero before the call.  The application can consume the compressed\n  output when it wants, for example when the output buffer is full (avail_out\n  == 0), or after each call of deflate().  If deflate returns Z_OK and with\n  zero avail_out, it must be called again after making room in the output\n  buffer because there might be more output pending. See deflatePending(),\n  which can be used if desired to determine whether or not there is more output\n  in that case.\n\n    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to\n  decide how much data to accumulate before producing output, in order to\n  maximize compression.\n\n    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is\n  flushed to the output buffer and the output is aligned on a byte boundary, so\n  that the decompressor can get all input data available so far.  (In\n  particular avail_in is zero after the call if enough output space has been\n  provided before the call.) Flushing may degrade compression for some\n  compression algorithms and so it should be used only when necessary.  This\n  completes the current deflate block and follows it with an empty stored block\n  that is three bits plus filler bits to the next byte, followed by four bytes\n  (00 00 ff ff).\n\n    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the\n  output buffer, but the output is not aligned to a byte boundary.  All of the\n  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.\n  This completes the current deflate block and follows it with an empty fixed\n  codes block that is 10 bits long.  This assures that enough bytes are output\n  in order for the decompressor to finish the block before the empty fixed\n  codes block.\n\n    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as\n  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to\n  seven bits of the current block are held to be written as the next byte after\n  the next deflate block is completed.  In this case, the decompressor may not\n  be provided enough bits at this point in order to complete decompression of\n  the data provided so far to the compressor.  It may need to wait for the next\n  block to be emitted.  This is for advanced applications that need to control\n  the emission of deflate blocks.\n\n    If flush is set to Z_FULL_FLUSH, all output is flushed as with\n  Z_SYNC_FLUSH, and the compression state is reset so that decompression can\n  restart from this point if previous compressed data has been damaged or if\n  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade\n  compression.\n\n    If deflate returns with avail_out == 0, this function must be called again\n  with the same value of the flush parameter and more output space (updated\n  avail_out), until the flush is complete (deflate returns with non-zero\n  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that\n  avail_out is greater than six when the flush marker begins, in order to avoid\n  repeated flush markers upon calling deflate() again when avail_out == 0.\n\n    If the parameter flush is set to Z_FINISH, pending input is processed,\n  pending output is flushed and deflate returns with Z_STREAM_END if there was\n  enough output space.  If deflate returns with Z_OK or Z_BUF_ERROR, this\n  function must be called again with Z_FINISH and more output space (updated\n  avail_out) but no more input data, until it returns with Z_STREAM_END or an\n  error.  After deflate has returned Z_STREAM_END, the only possible operations\n  on the stream are deflateReset or deflateEnd.\n\n    Z_FINISH can be used in the first deflate call after deflateInit if all the\n  compression is to be done in a single step.  In order to complete in one\n  call, avail_out must be at least the value returned by deflateBound (see\n  below).  Then deflate is guaranteed to return Z_STREAM_END.  If not enough\n  output space is provided, deflate will not return Z_STREAM_END, and it must\n  be called again as described above.\n\n    deflate() sets strm->adler to the Adler-32 checksum of all input read\n  so far (that is, total_in bytes).  If a gzip stream is being generated, then\n  strm->adler will be the CRC-32 checksum of the input read so far.  (See\n  deflateInit2 below.)\n\n    deflate() may update strm->data_type if it can make a good guess about\n  the input data type (Z_BINARY or Z_TEXT).  If in doubt, the data is\n  considered binary.  This field is only for information purposes and does not\n  affect the compression algorithm in any manner.\n\n    deflate() returns Z_OK if some progress has been made (more input\n  processed or more output produced), Z_STREAM_END if all input has been\n  consumed and all output has been produced (only when flush is set to\n  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example\n  if next_in or next_out was Z_NULL or the state was inadvertently written over\n  by the application), or Z_BUF_ERROR if no progress is possible (for example\n  avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not fatal, and\n  deflate() can be called again with more input and more output space to\n  continue compressing.\n*/\n\n\nZEXTERN int ZEXPORT deflateEnd(z_streamp strm);\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the\n   stream state was inconsistent, Z_DATA_ERROR if the stream was freed\n   prematurely (some input or output was discarded).  In the error case, msg\n   may be set but then points to a static string (which must not be\n   deallocated).\n*/\n\n\n/*\nZEXTERN int ZEXPORT inflateInit(z_streamp strm);\n\n     Initializes the internal stream state for decompression.  The fields\n   next_in, avail_in, zalloc, zfree and opaque must be initialized before by\n   the caller.  In the current version of inflate, the provided input is not\n   read or consumed.  The allocation of a sliding window will be deferred to\n   the first call of inflate (if the decompression does not complete on the\n   first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates\n   them to use default allocation functions.  total_in, total_out, adler, and\n   msg are initialized.\n\n     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit does not perform any decompression.\n   Actual decompression will be done by inflate().  So next_in, and avail_in,\n   next_out, and avail_out are unused and unchanged.  The current\n   implementation of inflateInit() does not process any header information --\n   that is deferred until inflate() is called.\n*/\n\n\nZEXTERN int ZEXPORT inflate(z_streamp strm, int flush);\n/*\n    inflate decompresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full.  It may introduce\n  some output latency (reading input without producing any output) except when\n  forced to flush.\n\n  The detailed semantics are as follows.  inflate performs one or both of the\n  following actions:\n\n  - Decompress more input starting at next_in and update next_in and avail_in\n    accordingly.  If not all input can be processed (because there is not\n    enough room in the output buffer), then next_in and avail_in are updated\n    accordingly, and processing will resume at this point for the next call of\n    inflate().\n\n  - Generate more output starting at next_out and update next_out and avail_out\n    accordingly.  inflate() provides as much output as possible, until there is\n    no more input data or no more space in the output buffer (see below about\n    the flush parameter).\n\n    Before the call of inflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming more\n  output, and updating the next_* and avail_* values accordingly.  If the\n  caller of inflate() does not provide both available input and available\n  output space, it is possible that there will be no progress made.  The\n  application can consume the uncompressed output when it wants, for example\n  when the output buffer is full (avail_out == 0), or after each call of\n  inflate().  If inflate returns Z_OK and with zero avail_out, it must be\n  called again after making room in the output buffer because there might be\n  more output pending.\n\n    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,\n  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much\n  output as possible to the output buffer.  Z_BLOCK requests that inflate()\n  stop if and when it gets to the next deflate block boundary.  When decoding\n  the zlib or gzip format, this will cause inflate() to return immediately\n  after the header and before the first block.  When doing a raw inflate,\n  inflate() will go ahead and process the first block, and will return when it\n  gets to the end of that block, or when it runs out of data.\n\n    The Z_BLOCK option assists in appending to or combining deflate streams.\n  To assist in this, on return inflate() always sets strm->data_type to the\n  number of unused bits in the input taken from strm->next_in, plus 64 if\n  inflate() is currently decoding the last block in the deflate stream, plus\n  128 if inflate() returned immediately after decoding an end-of-block code or\n  decoding the complete header up to just before the first byte of the deflate\n  stream.  The end-of-block will not be indicated until all of the uncompressed\n  data from that block has been written to strm->next_out.  The number of\n  unused bits may in general be greater than seven, except when bit 7 of\n  data_type is set, in which case the number of unused bits will be less than\n  eight.  data_type is set as noted here every time inflate() returns for all\n  flush options, and so can be used to determine the amount of currently\n  consumed input in bits.\n\n    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the\n  end of each deflate block header is reached, before any actual data in that\n  block is decoded.  This allows the caller to determine the length of the\n  deflate block header for later use in random access within a deflate block.\n  256 is added to the value of strm->data_type when inflate() returns\n  immediately after reaching the end of the deflate block header.\n\n    inflate() should normally be called until it returns Z_STREAM_END or an\n  error.  However if all decompression is to be performed in a single step (a\n  single call of inflate), the parameter flush should be set to Z_FINISH.  In\n  this case all pending input is processed and all pending output is flushed;\n  avail_out must be large enough to hold all of the uncompressed data for the\n  operation to complete.  (The size of the uncompressed data may have been\n  saved by the compressor for this purpose.)  The use of Z_FINISH is not\n  required to perform an inflation in one step.  However it may be used to\n  inform inflate that a faster approach can be used for the single inflate()\n  call.  Z_FINISH also informs inflate to not maintain a sliding window if the\n  stream completes, which reduces inflate's memory footprint.  If the stream\n  does not complete, either because not all of the stream is provided or not\n  enough output space is provided, then a sliding window will be allocated and\n  inflate() can be called again to continue the operation as if Z_NO_FLUSH had\n  been used.\n\n     In this implementation, inflate() always flushes as much output as\n  possible to the output buffer, and always uses the faster approach on the\n  first call.  So the effects of the flush parameter in this implementation are\n  on the return value of inflate() as noted below, when inflate() returns early\n  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of\n  memory for a sliding window when Z_FINISH is used.\n\n     If a preset dictionary is needed after this call (see inflateSetDictionary\n  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary\n  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets\n  strm->adler to the Adler-32 checksum of all output produced so far (that is,\n  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described\n  below.  At the end of the stream, inflate() checks that its computed Adler-32\n  checksum is equal to that saved by the compressor and returns Z_STREAM_END\n  only if the checksum is correct.\n\n    inflate() can decompress and check either zlib-wrapped or gzip-wrapped\n  deflate data.  The header type is detected automatically, if requested when\n  initializing with inflateInit2().  Any information contained in the gzip\n  header is not retained unless inflateGetHeader() is used.  When processing\n  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output\n  produced so far.  The CRC-32 is checked against the gzip trailer, as is the\n  uncompressed length, modulo 2^32.\n\n    inflate() returns Z_OK if some progress has been made (more input processed\n  or more output produced), Z_STREAM_END if the end of the compressed data has\n  been reached and all uncompressed output has been produced, Z_NEED_DICT if a\n  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was\n  corrupted (input stream not conforming to the zlib format or incorrect check\n  value, in which case strm->msg points to a string with a more specific\n  error), Z_STREAM_ERROR if the stream structure was inconsistent (for example\n  next_in or next_out was Z_NULL, or the state was inadvertently written over\n  by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR\n  if no progress was possible or if there was not enough room in the output\n  buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and\n  inflate() can be called again with more input and more output space to\n  continue decompressing.  If Z_DATA_ERROR is returned, the application may\n  then call inflateSync() to look for a good compression block if a partial\n  recovery of the data is to be attempted.\n*/\n\n\nZEXTERN int ZEXPORT inflateEnd(z_streamp strm);\n/*\n     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any pending\n   output.\n\n     inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state\n   was inconsistent.\n*/\n\n\n                        /* Advanced functions */\n\n/*\n    The following functions are needed only in some special applications.\n*/\n\n/*\nZEXTERN int ZEXPORT deflateInit2(z_streamp strm,\n                                 int level,\n                                 int method,\n                                 int windowBits,\n                                 int memLevel,\n                                 int strategy);\n\n     This is another version of deflateInit with more compression options.  The\n   fields zalloc, zfree and opaque must be initialized before by the caller.\n\n     The method parameter is the compression method.  It must be Z_DEFLATED in\n   this version of the library.\n\n     The windowBits parameter is the base two logarithm of the window size\n   (the size of the history buffer).  It should be in the range 8..15 for this\n   version of the library.  Larger values of this parameter result in better\n   compression at the expense of memory usage.  The default value is 15 if\n   deflateInit is used instead.\n\n     For the current implementation of deflate(), a windowBits value of 8 (a\n   window size of 256 bytes) is not supported.  As a result, a request for 8\n   will result in 9 (a 512-byte window).  In that case, providing 8 to\n   inflateInit2() will result in an error when the zlib header with 9 is\n   checked against the initialization of inflate().  The remedy is to not use 8\n   with deflateInit2() with this initialization, or at least in that case use 9\n   with inflateInit2().\n\n     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits\n   determines the window size.  deflate() will then generate raw deflate data\n   with no zlib header or trailer, and will not compute a check value.\n\n     windowBits can also be greater than 15 for optional gzip encoding.  Add\n   16 to windowBits to write a simple gzip header and trailer around the\n   compressed data instead of a zlib wrapper.  The gzip header will have no\n   file name, no extra data, no comment, no modification time (set to zero), no\n   header crc, and the operating system will be set to the appropriate value,\n   if the operating system was determined at compile time.  If a gzip stream is\n   being written, strm->adler is a CRC-32 instead of an Adler-32.\n\n     For raw deflate or gzip encoding, a request for a 256-byte window is\n   rejected as invalid, since only the zlib header provides a means of\n   transmitting the window size to the decompressor.\n\n     The memLevel parameter specifies how much memory should be allocated\n   for the internal compression state.  memLevel=1 uses minimum memory but is\n   slow and reduces compression ratio; memLevel=9 uses maximum memory for\n   optimal speed.  The default value is 8.  See zconf.h for total memory usage\n   as a function of windowBits and memLevel.\n\n     The strategy parameter is used to tune the compression algorithm.  Use the\n   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a\n   filter (or predictor), Z_RLE to limit match distances to one (run-length\n   encoding), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string\n   matching).  Filtered data consists mostly of small values with a somewhat\n   random distribution, as produced by the PNG filters.  In this case, the\n   compression algorithm is tuned to compress them better.  The effect of\n   Z_FILTERED is to force more Huffman coding and less string matching than the\n   default; it is intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.\n   Z_RLE is almost as fast as Z_HUFFMAN_ONLY, but should give better\n   compression for PNG image data than Huffman only.  The degree of string\n   matching from most to none is: Z_DEFAULT_STRATEGY, Z_FILTERED, Z_RLE, then\n   Z_HUFFMAN_ONLY. The strategy parameter affects the compression ratio but\n   never the correctness of the compressed output, even if it is not set\n   optimally for the given data.  Z_FIXED uses the default string matching, but\n   prevents the use of dynamic Huffman codes, allowing for a simpler decoder\n   for special applications.\n\n     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid\n   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is\n   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is\n   set to null if there is no error message.  deflateInit2 does not perform any\n   compression: this will be done by deflate().\n*/\n\nZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm,\n                                         const Bytef *dictionary,\n                                         uInt  dictLength);\n/*\n     Initializes the compression dictionary from the given byte sequence\n   without producing any compressed output.  When using the zlib format, this\n   function must be called immediately after deflateInit, deflateInit2 or\n   deflateReset, and before any call of deflate.  When doing raw deflate, this\n   function must be called either before any call of deflate, or immediately\n   after the completion of a deflate block, i.e. after all input has been\n   consumed and all output has been delivered when using any of the flush\n   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The\n   compressor and decompressor must use exactly the same dictionary (see\n   inflateSetDictionary).\n\n     The dictionary should consist of strings (byte sequences) that are likely\n   to be encountered later in the data to be compressed, with the most commonly\n   used strings preferably put towards the end of the dictionary.  Using a\n   dictionary is most useful when the data to be compressed is short and can be\n   predicted with good accuracy; the data can then be compressed better than\n   with the default empty dictionary.\n\n     Depending on the size of the compression data structures selected by\n   deflateInit or deflateInit2, a part of the dictionary may in effect be\n   discarded, for example if the dictionary is larger than the window size\n   provided in deflateInit or deflateInit2.  Thus the strings most likely to be\n   useful should be put at the end of the dictionary, not at the front.  In\n   addition, the current implementation of deflate will use at most the window\n   size minus 262 bytes of the provided dictionary.\n\n     Upon return of this function, strm->adler is set to the Adler-32 value\n   of the dictionary; the decompressor may later use this value to determine\n   which dictionary has been used by the compressor.  (The Adler-32 value\n   applies to the whole dictionary even if only a subset of the dictionary is\n   actually used by the compressor.) If a raw deflate was requested, then the\n   Adler-32 value is not computed and strm->adler is not set.\n\n     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent (for example if deflate has already been called for this stream\n   or if not at a block boundary for raw deflate).  deflateSetDictionary does\n   not perform any compression: this will be done by deflate().\n*/\n\nZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm,\n                                         Bytef *dictionary,\n                                         uInt  *dictLength);\n/*\n     Returns the sliding dictionary being maintained by deflate.  dictLength is\n   set to the number of bytes in the dictionary, and that many bytes are copied\n   to dictionary.  dictionary must have enough space, where 32768 bytes is\n   always enough.  If deflateGetDictionary() is called with dictionary equal to\n   Z_NULL, then only the dictionary length is returned, and nothing is copied.\n   Similarly, if dictLength is Z_NULL, then it is not set.\n\n     deflateGetDictionary() may return a length less than the window size, even\n   when more than the window size in input has been provided. It may return up\n   to 258 bytes less in that case, due to how zlib's implementation of deflate\n   manages the sliding window and lookahead for matches, where matches can be\n   up to 258 bytes long. If the application needs the last window-size bytes of\n   input, then that would need to be saved by the application outside of zlib.\n\n     deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the\n   stream state is inconsistent.\n*/\n\nZEXTERN int ZEXPORT deflateCopy(z_streamp dest,\n                                z_streamp source);\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when several compression strategies will be\n   tried, for example when there are several ways of pre-processing the input\n   data with a filter.  The streams that will be discarded should then be freed\n   by calling deflateEnd.  Note that deflateCopy duplicates the internal\n   compression state which can be quite large, so this strategy is slow and can\n   consume lots of memory.\n\n     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nZEXTERN int ZEXPORT deflateReset(z_streamp strm);\n/*\n     This function is equivalent to deflateEnd followed by deflateInit, but\n   does not free and reallocate the internal compression state.  The stream\n   will leave the compression level and any other attributes that may have been\n   set unchanged.  total_in, total_out, adler, and msg are initialized.\n\n     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nZEXTERN int ZEXPORT deflateParams(z_streamp strm,\n                                  int level,\n                                  int strategy);\n/*\n     Dynamically update the compression level and compression strategy.  The\n   interpretation of level and strategy is as in deflateInit2().  This can be\n   used to switch between compression and straight copy of the input data, or\n   to switch to a different kind of input data requiring a different strategy.\n   If the compression approach (which is a function of the level) or the\n   strategy is changed, and if there have been any deflate() calls since the\n   state was initialized or reset, then the input available so far is\n   compressed with the old level and strategy using deflate(strm, Z_BLOCK).\n   There are three approaches for the compression levels 0, 1..3, and 4..9\n   respectively.  The new level and strategy will take effect at the next call\n   of deflate().\n\n     If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does\n   not have enough output space to complete, then the parameter change will not\n   take effect.  In this case, deflateParams() can be called again with the\n   same parameters and more output space to try again.\n\n     In order to assure a change in the parameters on the first try, the\n   deflate stream should be flushed using deflate() with Z_BLOCK or other flush\n   request until strm.avail_out is not zero, before calling deflateParams().\n   Then no more input data should be provided before the deflateParams() call.\n   If this is done, the old level and strategy will be applied to the data\n   compressed before deflateParams(), and the new level and strategy will be\n   applied to the data compressed after deflateParams().\n\n     deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream\n   state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if\n   there was not enough output space to complete the compression of the\n   available input data before a change in the strategy or approach.  Note that\n   in the case of a Z_BUF_ERROR, the parameters are not changed.  A return\n   value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be\n   retried with more output space.\n*/\n\nZEXTERN int ZEXPORT deflateTune(z_streamp strm,\n                                int good_length,\n                                int max_lazy,\n                                int nice_length,\n                                int max_chain);\n/*\n     Fine tune deflate's internal compression parameters.  This should only be\n   used by someone who understands the algorithm used by zlib's deflate for\n   searching for the best matching string, and even then only by the most\n   fanatic optimizer trying to squeeze out the last compressed bit for their\n   specific input data.  Read the deflate.c source code for the meaning of the\n   max_lazy, good_length, nice_length, and max_chain parameters.\n\n     deflateTune() can be called after deflateInit() or deflateInit2(), and\n   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.\n */\n\nZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen);\nZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen);\n/*\n     deflateBound() returns an upper bound on the compressed size after\n   deflation of sourceLen bytes.  It must be called after deflateInit() or\n   deflateInit2(), and after deflateSetHeader(), if used.  This would be used\n   to allocate an output buffer for deflation in a single pass, and so would be\n   called before deflate().  If that first deflate() call is provided the\n   sourceLen input bytes, an output buffer allocated to the size returned by\n   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed\n   to return Z_STREAM_END.  Note that it is possible for the compressed size to\n   be larger than the value returned by deflateBound() if flush options other\n   than Z_FINISH or Z_NO_FLUSH are used.\n\n     delfateBound_z() is the same, but takes and returns a size_t length.  Note\n   that a long is 32 bits on Windows.\n*/\n\nZEXTERN int ZEXPORT deflatePending(z_streamp strm,\n                                   unsigned *pending,\n                                   int *bits);\n/*\n     deflatePending() returns the number of bytes and bits of output that have\n   been generated, but not yet provided in the available output.  The bytes not\n   provided would be due to the available output space having being consumed.\n   The number of bits of output not provided are between 0 and 7, where they\n   await more bits to join them in order to fill out a full byte.  If pending\n   or bits are Z_NULL, then those values are not set.\n\n     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.  If an int is 16 bits and memLevel is 9, then\n   it is possible for the number of pending bytes to not fit in an unsigned. In\n   that case Z_BUF_ERROR is returned and *pending is set to the maximum value\n   of an unsigned.\n */\n\nZEXTERN int ZEXPORT deflateUsed(z_streamp strm,\n                                int *bits);\n/*\n     deflateUsed() returns in *bits the most recent number of deflate bits used\n   in the last byte when flushing to a byte boundary. The result is in 1..8, or\n   0 if there has not yet been a flush. This helps determine the location of\n   the last bit of a deflate stream.\n\n     deflateUsed returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n */\n\nZEXTERN int ZEXPORT deflatePrime(z_streamp strm,\n                                 int bits,\n                                 int value);\n/*\n     deflatePrime() inserts bits in the deflate output stream.  The intent\n   is that this function is used to start off the deflate output with the bits\n   leftover from a previous deflate stream when appending to it.  As such, this\n   function can only be used for raw deflate, and must be used before the first\n   deflate() call after a deflateInit2() or deflateReset().  bits must be less\n   than or equal to 16, and that many of the least significant bits of value\n   will be inserted in the output.\n\n     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough\n   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the\n   source stream state was inconsistent.\n*/\n\nZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm,\n                                     gz_headerp head);\n/*\n     deflateSetHeader() provides gzip header information for when a gzip\n   stream is requested by deflateInit2().  deflateSetHeader() may be called\n   after deflateInit2() or deflateReset() and before the first call of\n   deflate().  The text, time, os, extra field, name, and comment information\n   in the provided gz_header structure are written to the gzip header (xflag is\n   ignored -- the extra flags are set according to the compression level).  The\n   caller must assure that, if not Z_NULL, name and comment are terminated with\n   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are\n   available there.  If hcrc is true, a gzip header crc is included.  Note that\n   the current versions of the command-line version of gzip (up through version\n   1.3.x) do not support header crc's, and will report that it is a \"multi-part\n   gzip file\" and give up.\n\n     If deflateSetHeader is not used, the default gzip header has text false,\n   the time set to zero, and os set to the current operating system, with no\n   extra, name, or comment fields.  The gzip header is returned to the default\n   state by deflateReset().\n\n     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\n/*\nZEXTERN int ZEXPORT inflateInit2(z_streamp strm,\n                                 int windowBits);\n\n     This is another version of inflateInit with an extra parameter.  The\n   fields next_in, avail_in, zalloc, zfree and opaque must be initialized\n   before by the caller.\n\n     The windowBits parameter is the base two logarithm of the maximum window\n   size (the size of the history buffer).  It should be in the range 8..15 for\n   this version of the library.  The default value is 15 if inflateInit is used\n   instead.  windowBits must be greater than or equal to the windowBits value\n   provided to deflateInit2() while compressing, or it must be equal to 15 if\n   deflateInit2() was not used.  If a compressed stream with a larger window\n   size is given as input, inflate() will return with the error code\n   Z_DATA_ERROR instead of trying to allocate a larger window.\n\n     windowBits can also be zero to request that inflate use the window size in\n   the zlib header of the compressed stream.\n\n     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits\n   determines the window size.  inflate() will then process raw deflate data,\n   not looking for a zlib or gzip header, not generating a check value, and not\n   looking for any check values for comparison at the end of the stream.  This\n   is for use with other formats that use the deflate compressed data format\n   such as zip.  Those formats provide their own check values.  If a custom\n   format is developed using the raw deflate format for compressed data, it is\n   recommended that a check value such as an Adler-32 or a CRC-32 be applied to\n   the uncompressed data as is done in the zlib, gzip, and zip formats.  For\n   most applications, the zlib format should be used as is.  Note that comments\n   above on the use in deflateInit2() applies to the magnitude of windowBits.\n\n     windowBits can also be greater than 15 for optional gzip decoding.  Add\n   32 to windowBits to enable zlib and gzip decoding with automatic header\n   detection, or add 16 to decode only the gzip format (the zlib format will\n   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a\n   CRC-32 instead of an Adler-32.  Unlike the gunzip utility and gzread() (see\n   below), inflate() will *not* automatically decode concatenated gzip members.\n   inflate() will return Z_STREAM_END at the end of the gzip member.  The state\n   would need to be reset to continue decoding a subsequent gzip member.  This\n   *must* be done if there is more data after a gzip member, in order for the\n   decompression to be compliant with the gzip standard (RFC 1952).\n\n     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the\n   version assumed by the caller, or Z_STREAM_ERROR if the parameters are\n   invalid, such as a null pointer to the structure.  msg is set to null if\n   there is no error message.  inflateInit2 does not perform any decompression\n   apart from possibly reading the zlib header if present: actual decompression\n   will be done by inflate().  (So next_in and avail_in may be modified, but\n   next_out and avail_out are unused and unchanged.) The current implementation\n   of inflateInit2() does not process any header information -- that is\n   deferred until inflate() is called.\n*/\n\nZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm,\n                                         const Bytef *dictionary,\n                                         uInt  dictLength);\n/*\n     Initializes the decompression dictionary from the given uncompressed byte\n   sequence.  This function must be called immediately after a call of inflate,\n   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor\n   can be determined from the Adler-32 value returned by that call of inflate.\n   The compressor and decompressor must use exactly the same dictionary (see\n   deflateSetDictionary).  For raw inflate, this function can be called at any\n   time to set the dictionary.  If the provided dictionary is smaller than the\n   window and there is already data in the window, then the provided dictionary\n   will amend what's there.  The application must insure that the dictionary\n   that was used for compression is provided.\n\n     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a\n   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is\n   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the\n   expected one (incorrect Adler-32 value).  inflateSetDictionary does not\n   perform any decompression: this will be done by subsequent calls of\n   inflate().\n*/\n\nZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm,\n                                         Bytef *dictionary,\n                                         uInt  *dictLength);\n/*\n     Returns the sliding dictionary being maintained by inflate.  dictLength is\n   set to the number of bytes in the dictionary, and that many bytes are copied\n   to dictionary.  dictionary must have enough space, where 32768 bytes is\n   always enough.  If inflateGetDictionary() is called with dictionary equal to\n   Z_NULL, then only the dictionary length is returned, and nothing is copied.\n   Similarly, if dictLength is Z_NULL, then it is not set.\n\n     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the\n   stream state is inconsistent.\n*/\n\nZEXTERN int ZEXPORT inflateSync(z_streamp strm);\n/*\n     Skips invalid compressed data until a possible full flush point (see above\n   for the description of deflate with Z_FULL_FLUSH) can be found, or until all\n   available input is skipped.  No output is provided.\n\n     inflateSync searches for a 00 00 FF FF pattern in the compressed data.\n   All full flush points have this pattern, but not all occurrences of this\n   pattern are full flush points.\n\n     inflateSync returns Z_OK if a possible full flush point has been found,\n   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point\n   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.\n   In the success case, the application may save the current value of total_in\n   which indicates where valid compressed data was found.  In the error case,\n   the application may repeatedly call inflateSync, providing more input each\n   time, until success or end of the input data.\n*/\n\nZEXTERN int ZEXPORT inflateCopy(z_streamp dest,\n                                z_streamp source);\n/*\n     Sets the destination stream as a complete copy of the source stream.\n\n     This function can be useful when randomly accessing a large stream.  The\n   first pass through the stream can periodically record the inflate state,\n   allowing restarting inflate at those points when randomly accessing the\n   stream.\n\n     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being Z_NULL).  msg is left unchanged in both source and\n   destination.\n*/\n\nZEXTERN int ZEXPORT inflateReset(z_streamp strm);\n/*\n     This function is equivalent to inflateEnd followed by inflateInit,\n   but does not free and reallocate the internal decompression state.  The\n   stream will keep attributes that may have been set by inflateInit2.\n   total_in, total_out, adler, and msg are initialized.\n\n     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL).\n*/\n\nZEXTERN int ZEXPORT inflateReset2(z_streamp strm,\n                                  int windowBits);\n/*\n     This function is the same as inflateReset, but it also permits changing\n   the wrap and window size requests.  The windowBits parameter is interpreted\n   the same as it is for inflateInit2.  If the window size is changed, then the\n   memory allocated for the window is freed, and the window will be reallocated\n   by inflate() if needed.\n\n     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being Z_NULL), or if\n   the windowBits parameter is invalid.\n*/\n\nZEXTERN int ZEXPORT inflatePrime(z_streamp strm,\n                                 int bits,\n                                 int value);\n/*\n     This function inserts bits in the inflate input stream.  The intent is to\n   use inflatePrime() to start inflating at a bit position in the middle of a\n   byte.  The provided bits will be used before any bytes are used from\n   next_in.  This function should be used with raw inflate, before the first\n   inflate() call, after inflateInit2() or inflateReset().  It can also be used\n   after an inflate() return indicates the end of a deflate block or header\n   when using Z_BLOCK.  bits must be less than or equal to 16, and that many of\n   the least significant bits of value will be inserted in the input.  The\n   other bits in value can be non-zero, and will be ignored.\n\n     If bits is negative, then the input stream bit buffer is emptied.  Then\n   inflatePrime() can be called again to put bits in the buffer.  This is used\n   to clear out bits leftover after feeding inflate a block description prior\n   to feeding inflate codes.\n\n     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent, or if bits is out of range.  If inflate was\n   in the middle of processing a header, trailer, or stored block lengths, then\n   it is possible for there to be only eight bits available in the bit buffer.\n   In that case, bits > 8 is considered out of range.  However, when used as\n   outlined above, there will always be 16 bits available in the buffer for\n   insertion.  As noted in its documentation above, inflate records the number\n   of bits in the bit buffer on return in data_type. 32 minus that is the\n   number of bits available for insertion.  inflatePrime does not update\n   data_type with the new number of bits in buffer.\n*/\n\nZEXTERN long ZEXPORT inflateMark(z_streamp strm);\n/*\n     This function returns two values, one in the lower 16 bits of the return\n   value, and the other in the remaining upper bits, obtained by shifting the\n   return value down 16 bits.  If the upper value is -1 and the lower value is\n   zero, then inflate() is currently decoding information outside of a block.\n   If the upper value is -1 and the lower value is non-zero, then inflate is in\n   the middle of a stored block, with the lower value equaling the number of\n   bytes from the input remaining to copy.  If the upper value is not -1, then\n   it is the number of bits back from the current bit position in the input of\n   the code (literal or length/distance pair) currently being processed.  In\n   that case the lower value is the number of bytes already emitted for that\n   code.\n\n     A code is being processed if inflate is waiting for more input to complete\n   decoding of the code, or if it has completed decoding but is waiting for\n   more output space to write the literal or match data.\n\n     inflateMark() is used to mark locations in the input data for random\n   access, which may be at bit positions, and to note those cases where the\n   output of a code may span boundaries of random access blocks.  The current\n   location in the input stream can be determined from avail_in and data_type\n   as noted in the description for the Z_BLOCK flush parameter for inflate.\n\n     inflateMark returns the value noted above, or -65536 if the provided\n   source stream state was inconsistent.\n*/\n\nZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm,\n                                     gz_headerp head);\n/*\n     inflateGetHeader() requests that gzip header information be stored in the\n   provided gz_header structure.  inflateGetHeader() may be called after\n   inflateInit2() or inflateReset(), and before the first call of inflate().\n   As inflate() processes the gzip stream, head->done is zero until the header\n   is completed, at which time head->done is set to one.  If a zlib stream is\n   being decoded, then head->done is set to -1 to indicate that there will be\n   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be\n   used to force inflate() to return immediately after header processing is\n   complete and before any actual data is decompressed.\n\n     The text, time, xflags, and os fields are filled in with the gzip header\n   contents.  hcrc is set to true if there is a header CRC.  (The header CRC\n   was valid if done is set to one.)  The extra, name, and comment pointers\n   much each be either Z_NULL or point to space to store that information from\n   the header.  If extra is not Z_NULL, then extra_max contains the maximum\n   number of bytes that can be written to extra.  Once done is true, extra_len\n   contains the actual extra field length, and extra contains the extra field,\n   or that field truncated if extra_max is less than extra_len.  If name is not\n   Z_NULL, then up to name_max characters, including the terminating zero, are\n   written there.  If comment is not Z_NULL, then up to comm_max characters,\n   including the terminating zero, are written there.  The application can tell\n   that the name or comment did not fit in the provided space by the absence of\n   a terminating zero.  If any of extra, name, or comment are not present in\n   the header, then that field's pointer is set to Z_NULL.  This allows the use\n   of deflateSetHeader() with the returned structure to duplicate the header.\n   Note that if those fields initially pointed to allocated memory, then the\n   application will need to save them elsewhere so that they can be eventually\n   freed.\n\n     If inflateGetHeader is not used, then the header information is simply\n   discarded.  The header is always checked for validity, including the header\n   CRC if present.  inflateReset() will reset the process to discard the header\n   information.  The application would need to call inflateGetHeader() again to\n   retrieve the header from the next gzip stream.\n\n     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent.\n*/\n\n/*\nZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits,\n                                    unsigned char FAR *window);\n\n     Initialize the internal stream state for decompression using inflateBack()\n   calls.  The fields zalloc, zfree and opaque in strm must be initialized\n   before the call.  If zalloc and zfree are Z_NULL, then the default library-\n   derived memory allocation routines are used.  windowBits is the base two\n   logarithm of the window size, in the range 8..15.  window is a caller\n   supplied buffer of that size.  Except for special applications where it is\n   assured that deflate was used with small window sizes, windowBits must be 15\n   and a 32K byte window must be supplied to be able to decompress general\n   deflate streams.\n\n     See inflateBack() for the usage of these routines.\n\n     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of\n   the parameters are invalid, Z_MEM_ERROR if the internal state could not be\n   allocated, or Z_VERSION_ERROR if the version of the library does not match\n   the version of the header file.\n*/\n\ntypedef unsigned (*in_func)(void FAR *,\n                            z_const unsigned char FAR * FAR *);\ntypedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned);\n\nZEXTERN int ZEXPORT inflateBack(z_streamp strm,\n                                in_func in, void FAR *in_desc,\n                                out_func out, void FAR *out_desc);\n/*\n     inflateBack() does a raw inflate with a single call using a call-back\n   interface for input and output.  This is potentially more efficient than\n   inflate() for file i/o applications, in that it avoids copying between the\n   output and the sliding window by simply making the window itself the output\n   buffer.  inflate() can be faster on modern CPUs when used with large\n   buffers.  inflateBack() trusts the application to not change the output\n   buffer passed by the output function, at least until inflateBack() returns.\n\n     inflateBackInit() must be called first to allocate the internal state\n   and to initialize the state with the user-provided window buffer.\n   inflateBack() may then be used multiple times to inflate a complete, raw\n   deflate stream with each call.  inflateBackEnd() is then called to free the\n   allocated state.\n\n     A raw deflate stream is one with no zlib or gzip header or trailer.\n   This routine would normally be used in a utility that reads zip or gzip\n   files and writes out uncompressed files.  The utility would decode the\n   header and process the trailer on its own, hence this routine expects only\n   the raw deflate stream to decompress.  This is different from the default\n   behavior of inflate(), which expects a zlib header and trailer around the\n   deflate stream.\n\n     inflateBack() uses two subroutines supplied by the caller that are then\n   called by inflateBack() for input and output.  inflateBack() calls those\n   routines until it reads a complete deflate stream and writes out all of the\n   uncompressed data, or until it encounters an error.  The function's\n   parameters and return types are defined above in the in_func and out_func\n   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the\n   number of bytes of provided input, and a pointer to that input in buf.  If\n   there is no input available, in() must return zero -- buf is ignored in that\n   case -- and inflateBack() will return a buffer error.  inflateBack() will\n   call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].\n   out() should return zero on success, or non-zero on failure.  If out()\n   returns non-zero, inflateBack() will return with an error.  Neither in() nor\n   out() are permitted to change the contents of the window provided to\n   inflateBackInit(), which is also the buffer that out() uses to write from.\n   The length written by out() will be at most the window size.  Any non-zero\n   amount of input may be provided by in().\n\n     For convenience, inflateBack() can be provided input on the first call by\n   setting strm->next_in and strm->avail_in.  If that input is exhausted, then\n   in() will be called.  Therefore strm->next_in must be initialized before\n   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called\n   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in\n   must also be initialized, and then if strm->avail_in is not zero, input will\n   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].\n\n     The in_desc and out_desc parameters of inflateBack() is passed as the\n   first parameter of in() and out() respectively when they are called.  These\n   descriptors can be optionally used to pass any information that the caller-\n   supplied in() and out() functions need to do their job.\n\n     On return, inflateBack() will set strm->next_in and strm->avail_in to\n   pass back any unused input that was provided by the last in() call.  The\n   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR\n   if in() or out() returned an error, Z_DATA_ERROR if there was a format error\n   in the deflate stream (in which case strm->msg is set to indicate the nature\n   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.\n   In the case of Z_BUF_ERROR, an input or output error can be distinguished\n   using strm->next_in which will be Z_NULL only if in() returned an error.  If\n   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning\n   non-zero.  (in() will always be called before out(), so strm->next_in is\n   assured to be defined if out() returns non-zero.)  Note that inflateBack()\n   cannot return Z_OK.\n*/\n\nZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm);\n/*\n     All memory allocated by inflateBackInit() is freed.\n\n     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream\n   state was inconsistent.\n*/\n\nZEXTERN uLong ZEXPORT zlibCompileFlags(void);\n/* Return flags indicating compile-time options.\n\n    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:\n     1.0: size of uInt\n     3.2: size of uLong\n     5.4: size of voidpf (pointer)\n     7.6: size of z_off_t\n\n    Compiler, assembler, and debug options:\n     8: ZLIB_DEBUG\n     9: ASMV or ASMINF -- use ASM code\n     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention\n     11: 0 (reserved)\n\n    One-time table building (smaller code, but not thread-safe if true):\n     12: BUILDFIXED -- build static block decoding tables when needed\n     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed\n     14,15: 0 (reserved)\n\n    Library content (indicates missing functionality):\n     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking\n                          deflate code when not needed)\n     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect\n                    and decode gzip streams (to avoid linking crc code)\n     18-19: 0 (reserved)\n\n    Operation variations (changes in library functionality):\n     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate\n     21: FASTEST -- deflate algorithm with only one, lowest compression level\n     22,23: 0 (reserved)\n\n    The sprintf variant used by gzprintf (all zeros is best):\n     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format\n     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() is not secure!\n     26: 0 = returns value, 1 = void -- 1 means inferred string length returned\n     27: 0 = gzprintf() present, 1 = not -- 1 means gzprintf() returns an error\n\n    Remainder:\n     28-31: 0 (reserved)\n */\n\n#ifndef Z_SOLO\n\n                        /* utility functions */\n\n/*\n     The following utility functions are implemented on top of the basic\n   stream-oriented functions.  To simplify the interface, some default options\n   are assumed (compression level and memory usage, standard memory allocation\n   functions).  The source code of these utility functions can be modified if\n   you need special options.  The _z versions of the functions use the size_t\n   type for lengths.  Note that a long is 32 bits on Windows.\n*/\n\nZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen,\n                             const Bytef *source, uLong sourceLen);\nZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen,\n                               const Bytef *source, z_size_t sourceLen);\n/*\n     Compresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  Upon entry, destLen is the total size\n   of the destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed data.  compress() is equivalent to compress2() with a level\n   parameter of Z_DEFAULT_COMPRESSION.\n\n     compress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer.\n*/\n\nZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen,\n                              const Bytef *source, uLong sourceLen,\n                              int level);\nZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen,\n                                const Bytef *source, z_size_t sourceLen,\n                                int level);\n/*\n     Compresses the source buffer into the destination buffer.  The level\n   parameter has the same meaning as in deflateInit.  sourceLen is the byte\n   length of the source buffer.  Upon entry, destLen is the total size of the\n   destination buffer, which must be at least the value returned by\n   compressBound(sourceLen).  Upon exit, destLen is the actual size of the\n   compressed data.\n\n     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_BUF_ERROR if there was not enough room in the output buffer,\n   Z_STREAM_ERROR if the level parameter is invalid.\n*/\n\nZEXTERN uLong ZEXPORT compressBound(uLong sourceLen);\nZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen);\n/*\n     compressBound() returns an upper bound on the compressed size after\n   compress() or compress2() on sourceLen bytes.  It would be used before a\n   compress() or compress2() call to allocate the destination buffer.\n*/\n\nZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen,\n                               const Bytef *source, uLong sourceLen);\nZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen,\n                                 const Bytef *source, z_size_t sourceLen);\n/*\n     Decompresses the source buffer into the destination buffer.  sourceLen is\n   the byte length of the source buffer.  On entry, *destLen is the total size\n   of the destination buffer, which must be large enough to hold the entire\n   uncompressed data.  (The size of the uncompressed data must have been saved\n   previously by the compressor and transmitted to the decompressor by some\n   mechanism outside the scope of this compression library.)  On exit, *destLen\n   is the actual size of the uncompressed data.\n\n     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_BUF_ERROR if there was not enough room in the output\n   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In\n   the case where there is not enough room, uncompress() will fill the output\n   buffer with the uncompressed data up to that point.\n*/\n\nZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen,\n                                const Bytef *source, uLong *sourceLen);\nZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen,\n                                  const Bytef *source, z_size_t *sourceLen);\n/*\n     Same as uncompress, except that sourceLen is a pointer, where the\n   length of the source is *sourceLen.  On return, *sourceLen is the number of\n   source bytes consumed.\n*/\n\n                        /* gzip file access functions */\n\n/*\n     This library supports reading and writing files in gzip (.gz) format with\n   an interface similar to that of stdio, using the functions that start with\n   \"gz\".  The gzip format is different from the zlib format.  gzip is a gzip\n   wrapper, documented in RFC 1952, wrapped around a deflate stream.\n*/\n\ntypedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */\n\n/*\nZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);\n\n     Open the gzip (.gz) file at path for reading and decompressing, or\n   compressing and writing.  The mode parameter is as in fopen (\"rb\" or \"wb\")\n   but can also include a compression level (\"wb9\") or a strategy: 'f' for\n   filtered data as in \"wb6f\", 'h' for Huffman-only compression as in \"wb1h\",\n   'R' for run-length encoding as in \"wb1R\", or 'F' for fixed code compression\n   as in \"wb9F\".  (See the description of deflateInit2 for more information\n   about the strategy parameter.)  'T' will request transparent writing or\n   appending with no compression and not using the gzip format. 'T' cannot be\n   used to force transparent reading. Transparent reading is automatically\n   performed if there is no gzip header at the start. Transparent reading can\n   be disabled with the 'G' option, which will instead return an error if there\n   is no gzip header. 'N' will open the file in non-blocking mode.\n\n     'a' can be used instead of 'w' to request that the gzip stream that will\n   be written be appended to the file.  '+' will result in an error, since\n   reading and writing to the same gzip file is not supported.  The addition of\n   'x' when writing will create the file exclusively, which fails if the file\n   already exists.  On systems that support it, the addition of 'e' when\n   reading or writing will set the flag to close the file on an execve() call.\n\n     These functions, as well as gzip, will read and decode a sequence of gzip\n   streams in a file.  The append function of gzopen() can be used to create\n   such a file.  (Also see gzflush() for another way to do this.)  When\n   appending, gzopen does not test whether the file begins with a gzip stream,\n   nor does it look for the end of the gzip streams to begin appending.  gzopen\n   will simply append a gzip stream to the existing file.\n\n     gzopen can be used to read a file which is not in gzip format; in this\n   case gzread will directly read from the file without decompression.  When\n   reading, this will be detected automatically by looking for the magic two-\n   byte gzip header.\n\n     gzopen returns NULL if the file could not be opened, if there was\n   insufficient memory to allocate the gzFile state, or if an invalid mode was\n   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).\n   errno can be checked to determine if the reason gzopen failed was that the\n   file could not be opened. Note that if 'N' is in mode for non-blocking, the\n   open() itself can fail in order to not block. In that case gzopen() will\n   return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can\n   then be re-tried. If the application would like to block on opening the\n   file, then it can use open() without O_NONBLOCK, and then gzdopen() with the\n   resulting file descriptor and 'N' in the mode, which will set it to non-\n   blocking.\n*/\n\nZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode);\n/*\n     Associate a gzFile with the file descriptor fd.  File descriptors are\n   obtained from calls like open, dup, creat, pipe or fileno (if the file has\n   been previously opened with fopen).  The mode parameter is as in gzopen. An\n   'e' in mode will set fd's flag to close the file on an execve() call. An 'N'\n   in mode will set fd's non-blocking flag.\n\n     The next call of gzclose on the returned gzFile will also close the file\n   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor\n   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,\n   mode);.  The duplicated descriptor should be saved to avoid a leak, since\n   gzdopen does not close fd if it fails.  If you are using fileno() to get the\n   file descriptor from a FILE *, then you will have to use dup() to avoid\n   double-close()ing the file descriptor.  Both gzclose() and fclose() will\n   close the associated file descriptor, so they need to have different file\n   descriptors.\n\n     gzdopen returns NULL if there was insufficient memory to allocate the\n   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not\n   provided, or '+' was provided), or if fd is -1.  The file descriptor is not\n   used until the next gz* read, write, seek, or close operation, so gzdopen\n   will not detect if fd is invalid (unless fd is -1).\n*/\n\nZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size);\n/*\n     Set the internal buffer size used by this library's functions for file to\n   size.  The default buffer size is 8192 bytes.  This function must be called\n   after gzopen() or gzdopen(), and before any other calls that read or write\n   the file.  The buffer memory allocation is always deferred to the first read\n   or write.  Three times that size in buffer space is allocated.  A larger\n   buffer size of, for example, 64K or 128K bytes will noticeably increase the\n   speed of decompression (reading).\n\n     The new buffer size also affects the maximum length for gzprintf().\n\n     gzbuffer() returns 0 on success, or -1 on failure, such as being called\n   too late.\n*/\n\nZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy);\n/*\n     Dynamically update the compression level and strategy for file.  See the\n   description of deflateInit2 for the meaning of these parameters. Previously\n   provided data is flushed before applying the parameter changes.\n\n     gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not\n   opened for writing, Z_ERRNO if there is an error writing the flushed data,\n   or Z_MEM_ERROR if there is a memory allocation error.\n*/\n\nZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len);\n/*\n     Read and decompress up to len uncompressed bytes from file into buf.  If\n   the input file is not in gzip format, gzread copies the given number of\n   bytes into the buffer directly from the file.\n\n     After reaching the end of a gzip stream in the input, gzread will continue\n   to read, looking for another gzip stream.  Any number of gzip streams may be\n   concatenated in the input file, and will all be decompressed by gzread().\n   If something other than a gzip stream is encountered after a gzip stream,\n   that remaining trailing garbage is ignored (and no error is returned).\n\n     gzread can be used to read a gzip file that is being concurrently written.\n   Upon reaching the end of the input, gzread will return with the available\n   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then\n   gzclearerr can be used to clear the end of file indicator in order to permit\n   gzread to be tried again.  Z_OK indicates that a gzip stream was completed\n   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the\n   middle of a gzip stream.  Note that gzread does not return -1 in the event\n   of an incomplete gzip stream.  This error is deferred until gzclose(), which\n   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip\n   stream.  Alternatively, gzerror can be used before gzclose to detect this\n   case.\n\n     gzread can be used to read a gzip file on a non-blocking device. If the\n   input stalls and there is no uncompressed data to return, then gzread() will\n   return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be\n   called again.\n\n     gzread returns the number of uncompressed bytes actually read, less than\n   len for end of file, or -1 for error.  If len is too large to fit in an int,\n   then nothing is read, -1 is returned, and the error state is set to\n   Z_STREAM_ERROR. If some data was read before an error, then that data is\n   returned until exhausted, after which the next call will signal the error.\n*/\n\nZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,\n                                 gzFile file);\n/*\n     Read and decompress up to nitems items of size size from file into buf,\n   otherwise operating as gzread() does.  This duplicates the interface of\n   stdio's fread(), with size_t request and return types.  If the library\n   defines size_t, then z_size_t is identical to size_t.  If not, then z_size_t\n   is an unsigned integer type that can contain a pointer.\n\n     gzfread() returns the number of full items read of size size, or zero if\n   the end of the file was reached and a full item could not be read, or if\n   there was an error.  gzerror() must be consulted if zero is returned in\n   order to determine if there was an error.  If the multiplication of size and\n   nitems overflows, i.e. the product does not fit in a z_size_t, then nothing\n   is read, zero is returned, and the error state is set to Z_STREAM_ERROR.\n\n     In the event that the end of file is reached and only a partial item is\n   available at the end, i.e. the remaining uncompressed data length is not a\n   multiple of size, then the final partial item is nevertheless read into buf\n   and the end-of-file flag is set.  The length of the partial item read is not\n   provided, but could be inferred from the result of gztell().  This behavior\n   is the same as that of fread() implementations in common libraries. This\n   could result in data loss if used with size != 1 when reading a concurrently\n   written file or a non-blocking file. In that case, use size == 1 or gzread()\n   instead.\n*/\n\nZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len);\n/*\n     Compress and write the len uncompressed bytes at buf to file. gzwrite\n   returns the number of uncompressed bytes written, or 0 in case of error or\n   if len is 0.  If the write destination is non-blocking, then gzwrite() may\n   return a number of bytes written that is not 0 and less than len.\n\n     If len does not fit in an int, then 0 is returned and nothing is written.\n*/\n\nZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,\n                                  z_size_t nitems, gzFile file);\n/*\n     Compress and write nitems items of size size from buf to file, duplicating\n   the interface of stdio's fwrite(), with size_t request and return types.  If\n   the library defines size_t, then z_size_t is identical to size_t.  If not,\n   then z_size_t is an unsigned integer type that can contain a pointer.\n\n     gzfwrite() returns the number of full items written of size size, or zero\n   if there was an error.  If the multiplication of size and nitems overflows,\n   i.e. the product does not fit in a z_size_t, then nothing is written, zero\n   is returned, and the error state is set to Z_STREAM_ERROR.\n\n     If writing a concurrently read file or a non-blocking file with size != 1,\n   a partial item could be written, with no way of knowing how much of it was\n   not written, resulting in data loss.  In that case, use size == 1 or\n   gzwrite() instead.\n*/\n\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\nZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);\n#else\nZEXTERN int ZEXPORTVA gzprintf();\n#endif\n/*\n     Convert, format, compress, and write the arguments (...) to file under\n   control of the string format, as in fprintf.  gzprintf returns the number of\n   uncompressed bytes actually written, or a negative zlib error code in case\n   of error.  The number of uncompressed bytes written is limited to 8191, or\n   one less than the buffer size given to gzbuffer().  The caller should assure\n   that this limit is not exceeded.  If it is exceeded, then gzprintf() will\n   return an error (0) with nothing written.\n\n     In that last case, there may also be a buffer overflow with unpredictable\n   consequences, which is possible only if zlib was compiled with the insecure\n   functions sprintf() or vsprintf(), because the secure snprintf() and\n   vsnprintf() functions were not available. That would only be the case for\n   a non-ANSI C compiler. zlib may have been built without gzprintf() because\n   secure functions were not available and having gzprintf() be insecure was\n   not an option, in which case, gzprintf() returns Z_STREAM_ERROR. All of\n   these possibilities can be determined using zlibCompileFlags().\n\n     If a Z_BUF_ERROR is returned, then nothing was written due to a stall on\n   the non-blocking write destination.\n*/\n\nZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);\n/*\n     Compress and write the given null-terminated string s to file, excluding\n   the terminating null character.\n\n     gzputs returns the number of characters written, or -1 in case of error.\n   The number of characters written may be less than the length of the string\n   if the write destination is non-blocking.\n\n     If the length of the string does not fit in an int, then -1 is returned\n   and nothing is written.\n*/\n\nZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);\n/*\n     Read and decompress bytes from file into buf, until len-1 characters are\n   read, or until a newline character is read and transferred to buf, or an\n   end-of-file condition is encountered.  If any characters are read or if len\n   is one, the string is terminated with a null character.  If no characters\n   are read due to an end-of-file or len is less than one, then the buffer is\n   left untouched.\n\n     gzgets returns buf which is a null-terminated string, or it returns NULL\n   for end-of-file or in case of error. If some data was read before an error,\n   then that data is returned until exhausted, after which the next call will\n   return NULL to signal the error.\n\n     gzgets can be used on a file being concurrently written, and on a non-\n   blocking device, both as for gzread(). However lines may be broken in the\n   middle, leaving it up to the application to reassemble them as needed.\n*/\n\nZEXTERN int ZEXPORT gzputc(gzFile file, int c);\n/*\n     Compress and write c, converted to an unsigned char, into file.  gzputc\n   returns the value that was written, or -1 in case of error.\n*/\n\nZEXTERN int ZEXPORT gzgetc(gzFile file);\n/*\n     Read and decompress one byte from file. gzgetc returns this byte or -1 in\n   case of end of file or error. If some data was read before an error, then\n   that data is returned until exhausted, after which the next call will return\n   -1 to signal the error.\n\n     This is implemented as a macro for speed. As such, it does not do all of\n   the checking the other functions do. I.e. it does not check to see if file\n   is NULL, nor whether the structure file points to has been clobbered or not.\n\n     gzgetc can be used to read a gzip file on a non-blocking device. If the\n   input stalls and there is no uncompressed data to return, then gzgetc() will\n   return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be\n   called again.\n*/\n\nZEXTERN int ZEXPORT gzungetc(int c, gzFile file);\n/*\n     Push c back onto the stream for file to be read as the first character on\n   the next read.  At least one character of push-back is always allowed.\n   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will\n   fail if c is -1, and may fail if a character has been pushed but not read\n   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the\n   output buffer size of pushed characters is allowed.  (See gzbuffer above.)\n   The pushed character will be discarded if the stream is repositioned with\n   gzseek() or gzrewind().\n\n     gzungetc(-1, file) will force any pending seek to execute. Then gztell()\n   will report the position, even if the requested seek reached end of file.\n   This can be used to determine the number of uncompressed bytes in a gzip\n   file without having to read it into a buffer.\n*/\n\nZEXTERN int ZEXPORT gzflush(gzFile file, int flush);\n/*\n     Flush all pending output to file.  The parameter flush is as in the\n   deflate() function.  The return value is the zlib error number (see function\n   gzerror below).  gzflush is only permitted when writing.\n\n     If the flush parameter is Z_FINISH, the remaining data is written and the\n   gzip stream is completed in the output.  If gzwrite() is called again, a new\n   gzip stream will be started in the output.  gzread() is able to read such\n   concatenated gzip streams.\n\n     gzflush should be called only when strictly necessary because it will\n   degrade compression if called too often.\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT gzseek(gzFile file,\n                               z_off_t offset, int whence);\n\n     Set the starting position to offset relative to whence for the next gzread\n   or gzwrite on file.  The offset represents a number of bytes in the\n   uncompressed data stream.  The whence parameter is defined as in lseek(2);\n   the value SEEK_END is not supported.\n\n     If the file is opened for reading, this function is emulated but can be\n   extremely slow.  If the file is opened for writing, only forward seeks are\n   supported; gzseek then compresses a sequence of zeroes up to the new\n   starting position. For reading or writing, any actual seeking is deferred\n   until the next read or write operation, or close operation when writing.\n\n     gzseek returns the resulting offset location as measured in bytes from\n   the beginning of the uncompressed stream, or -1 in case of error, in\n   particular if the file is opened for writing and the new starting position\n   would be before the current position.\n*/\n\nZEXTERN int ZEXPORT gzrewind(gzFile file);\n/*\n     Rewind file. This function is supported only for reading.\n\n     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET).\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT gztell(gzFile file);\n\n     Return the starting position for the next gzread or gzwrite on file.\n   This position represents a number of bytes in the uncompressed data stream,\n   and is zero when starting, even if appending or reading a gzip stream from\n   the middle of a file using gzdopen().\n\n     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)\n*/\n\n/*\nZEXTERN z_off_t ZEXPORT gzoffset(gzFile file);\n\n     Return the current compressed (actual) read or write offset of file.  This\n   offset includes the count of bytes that precede the gzip stream, for example\n   when appending or when using gzdopen() for reading.  When reading, the\n   offset does not include as yet unused buffered input.  This information can\n   be used for a progress indicator.  On error, gzoffset() returns -1.\n*/\n\nZEXTERN int ZEXPORT gzeof(gzFile file);\n/*\n     Return true (1) if the end-of-file indicator for file has been set while\n   reading, false (0) otherwise.  Note that the end-of-file indicator is set\n   only if the read tried to go past the end of the input, but came up short.\n   Therefore, just like feof(), gzeof() may return false even if there is no\n   more data to read, in the event that the last read request was for the exact\n   number of bytes remaining in the input file.  This will happen if the input\n   file size is an exact multiple of the buffer size.\n\n     If gzeof() returns true, then the read functions will return no more data,\n   unless the end-of-file indicator is reset by gzclearerr() and the input file\n   has grown since the previous end of file was detected.\n*/\n\nZEXTERN int ZEXPORT gzdirect(gzFile file);\n/*\n     Return true (1) if file is being copied directly while reading, or false\n   (0) if file is a gzip stream being decompressed.\n\n     If the input file is empty, gzdirect() will return true, since the input\n   does not contain a gzip stream.\n\n     If gzdirect() is used immediately after gzopen() or gzdopen() it will\n   cause buffers to be allocated to allow reading the file to determine if it\n   is a gzip file. Therefore if gzbuffer() is used, it should be called before\n   gzdirect(). If the input is being written concurrently or the device is non-\n   blocking, then gzdirect() may give a different answer once four bytes of\n   input have been accumulated, which is what is needed to confirm or deny a\n   gzip header. Before this, gzdirect() will return true (1).\n\n     When writing, gzdirect() returns true (1) if transparent writing was\n   requested (\"wT\" for the gzopen() mode), or false (0) otherwise.  (Note:\n   gzdirect() is not needed when writing.  Transparent writing must be\n   explicitly requested, so the application already knows the answer.  When\n   linking statically, using gzdirect() will include all of the zlib code for\n   gzip file reading and decompression, which may not be desired.)\n*/\n\nZEXTERN int ZEXPORT gzclose(gzFile file);\n/*\n     Flush all pending output for file, if necessary, close file and\n   deallocate the (de)compression state.  Note that once file is closed, you\n   cannot call gzerror with file, since its structures have been deallocated.\n   gzclose must not be called more than once on the same file, just as free\n   must not be called more than once on the same allocation.\n\n     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a\n   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the\n   last read ended in the middle of a gzip stream, or Z_OK on success.\n*/\n\nZEXTERN int ZEXPORT gzclose_r(gzFile file);\nZEXTERN int ZEXPORT gzclose_w(gzFile file);\n/*\n     Same as gzclose(), but gzclose_r() is only for use when reading, and\n   gzclose_w() is only for use when writing or appending.  The advantage to\n   using these instead of gzclose() is that they avoid linking in zlib\n   compression or decompression code that is not used when only reading or only\n   writing respectively.  If gzclose() is used, then both compression and\n   decompression code will be included the application when linking to a static\n   zlib library.\n*/\n\nZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum);\n/*\n     Return the error message for the last error which occurred on file.\n   If errnum is not NULL, *errnum is set to zlib error number.  If an error\n   occurred in the file system and not in the compression library, *errnum is\n   set to Z_ERRNO and the application may consult errno to get the exact error\n   code.\n\n     The application must not modify the returned string.  Future calls to\n   this function may invalidate the previously returned string.  If file is\n   closed, then the string previously returned by gzerror will no longer be\n   available.\n\n     gzerror() should be used to distinguish errors from end-of-file for those\n   functions above that do not distinguish those cases in their return values.\n*/\n\nZEXTERN void ZEXPORT gzclearerr(gzFile file);\n/*\n     Clear the error and end-of-file flags for file.  This is analogous to the\n   clearerr() function in stdio.  This is useful for continuing to read a gzip\n   file that is being written concurrently.\n*/\n\n#endif /* !Z_SOLO */\n\n                        /* checksum functions */\n\n/*\n     These functions are not related to compression but are exported\n   anyway because they might be useful in applications using the compression\n   library.\n*/\n\nZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);\n/*\n     Update a running Adler-32 checksum with the bytes buf[0..len-1] and\n   return the updated checksum. An Adler-32 value is in the range of a 32-bit\n   unsigned integer. If buf is Z_NULL, this function returns the required\n   initial value for the checksum.\n\n     An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed\n   much faster.\n\n   Usage example:\n\n     uLong adler = adler32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF) {\n       adler = adler32(adler, buffer, length);\n     }\n     if (adler != original_adler) error();\n*/\n\nZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf,\n                                z_size_t len);\n/*\n     Same as adler32(), but with a size_t length.  Note that a long is 32 bits\n   on Windows.\n*/\n\n/*\nZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2,\n                                      z_off_t len2);\n\n     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1\n   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for\n   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of\n   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note\n   that the z_off_t type (like off_t) is a signed integer.  If len2 is\n   negative, the result has no meaning or utility.\n*/\n\nZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len);\n/*\n     Update a running CRC-32 with the bytes buf[0..len-1] and return the\n   updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.\n   If buf is Z_NULL, this function returns the required initial value for the\n   crc. Pre- and post-conditioning (one's complement) is performed within this\n   function so it shouldn't be done by the application.\n\n   Usage example:\n\n     uLong crc = crc32(0L, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) != EOF) {\n       crc = crc32(crc, buffer, length);\n     }\n     if (crc != original_crc) error();\n*/\n\nZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf,\n                              z_size_t len);\n/*\n     Same as crc32(), but with a size_t length.  Note that a long is 32 bits on\n   Windows.\n*/\n\n/*\nZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2);\n\n     Combine two CRC-32 check values into one.  For two sequences of bytes,\n   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were\n   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32\n   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and\n   len2. len2 must be non-negative, otherwise zero is returned.\n*/\n\n/*\nZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2);\n\n     Return the operator corresponding to length len2, to be used with\n   crc32_combine_op(). len2 must be non-negative, otherwise zero is returned.\n*/\n\nZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op);\n/*\n     Give the same result as crc32_combine(), using op in place of len2. op is\n   is generated from len2 by crc32_combine_gen(). This will be faster than\n   crc32_combine() if the generated op is used more than once.\n*/\n\n\n                        /* various hacks, don't look :) */\n\n/* deflateInit and inflateInit are macros to allow checking the zlib version\n * and the compiler's view of z_stream:\n */\nZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level,\n                                 const char *version, int stream_size);\nZEXTERN int ZEXPORT inflateInit_(z_streamp strm,\n                                 const char *version, int stream_size);\nZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int  level, int  method,\n                                  int windowBits, int memLevel,\n                                  int strategy, const char *version,\n                                  int stream_size);\nZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int  windowBits,\n                                  const char *version, int stream_size);\nZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,\n                                     unsigned char FAR *window,\n                                     const char *version,\n                                     int stream_size);\n#ifdef Z_PREFIX_SET\n#  define z_deflateInit(strm, level) \\\n          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define z_inflateInit(strm) \\\n          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \\\n          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\\\n                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define z_inflateInit2(strm, windowBits) \\\n          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \\\n                        (int)sizeof(z_stream))\n#  define z_inflateBackInit(strm, windowBits, window) \\\n          inflateBackInit_((strm), (windowBits), (window), \\\n                           ZLIB_VERSION, (int)sizeof(z_stream))\n#else\n#  define deflateInit(strm, level) \\\n          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define inflateInit(strm) \\\n          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \\\n          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\\\n                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))\n#  define inflateInit2(strm, windowBits) \\\n          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \\\n                        (int)sizeof(z_stream))\n#  define inflateBackInit(strm, windowBits, window) \\\n          inflateBackInit_((strm), (windowBits), (window), \\\n                           ZLIB_VERSION, (int)sizeof(z_stream))\n#endif\n\n#ifndef Z_SOLO\n\n/* gzgetc() macro and its supporting function and exposed data structure.  Note\n * that the real internal state is much larger than the exposed structure.\n * This abbreviated structure exposes just enough for the gzgetc() macro.  The\n * user should not mess with these exposed elements, since their names or\n * behavior could change in the future, perhaps even capriciously.  They can\n * only be used by the gzgetc() macro.  You have been warned.\n */\nstruct gzFile_s {\n    unsigned have;\n    unsigned char *next;\n    z_off64_t pos;\n};\nZEXTERN int ZEXPORT gzgetc_(gzFile file);       /* backward compatibility */\n#ifdef Z_PREFIX_SET\n#  undef z_gzgetc\n#  define z_gzgetc(g) \\\n          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))\n#else\n#  define gzgetc(g) \\\n          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))\n#endif\n\n/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or\n * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if\n * both are true, the application gets the *64 functions, and the regular\n * functions are changed to 64 bits) -- in case these are set on systems\n * without large file support, _LFS64_LARGEFILE must also be true\n */\n#ifdef Z_LARGE64\n   ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);\n   ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);\n   ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);\n   ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);\n   ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);\n   ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);\n   ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);\n#endif\n\n#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)\n#  ifdef Z_PREFIX_SET\n#    define z_gzopen z_gzopen64\n#    define z_gzseek z_gzseek64\n#    define z_gztell z_gztell64\n#    define z_gzoffset z_gzoffset64\n#    define z_adler32_combine z_adler32_combine64\n#    define z_crc32_combine z_crc32_combine64\n#    define z_crc32_combine_gen z_crc32_combine_gen64\n#  else\n#    define gzopen gzopen64\n#    define gzseek gzseek64\n#    define gztell gztell64\n#    define gzoffset gzoffset64\n#    define adler32_combine adler32_combine64\n#    define crc32_combine crc32_combine64\n#    define crc32_combine_gen crc32_combine_gen64\n#  endif\n#  ifndef Z_LARGE64\n     ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);\n     ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int);\n     ZEXTERN z_off_t ZEXPORT gztell64(gzFile);\n     ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile);\n     ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);\n     ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);\n     ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);\n#  endif\n#else\n   ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *);\n   ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int);\n   ZEXTERN z_off_t ZEXPORT gztell(gzFile);\n   ZEXTERN z_off_t ZEXPORT gzoffset(gzFile);\n   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);\n   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);\n   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);\n#endif\n\n#else /* Z_SOLO */\n\n   ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);\n   ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);\n   ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t);\n\n#endif /* !Z_SOLO */\n\n/* undocumented functions */\nZEXTERN const char   * ZEXPORT zError(int);\nZEXTERN int            ZEXPORT inflateSyncPoint(z_streamp);\nZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void);\nZEXTERN int            ZEXPORT inflateUndermine(z_streamp, int);\nZEXTERN int            ZEXPORT inflateValidate(z_streamp, int);\nZEXTERN unsigned long  ZEXPORT inflateCodesUsed(z_streamp);\nZEXTERN int            ZEXPORT inflateResetKeep(z_streamp);\nZEXTERN int            ZEXPORT deflateResetKeep(z_streamp);\n#if defined(_WIN32) && !defined(Z_SOLO)\nZEXTERN gzFile         ZEXPORT gzopen_w(const wchar_t *path,\n                                        const char *mode);\n#endif\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#  ifndef Z_SOLO\nZEXTERN int            ZEXPORTVA gzvprintf(gzFile file,\n                                           const char *format,\n                                           va_list va);\n#  endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* ZLIB_H */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/zutil.c",
    "content": "/* zutil.c -- target dependent utility functions for the compression library\n * Copyright (C) 1995-2026 Jean-loup Gailly\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* @(#) $Id$ */\n\n#include \"zutil.h\"\n#ifndef Z_SOLO\n#  include \"gzguts.h\"\n#endif\n\nz_const char * const z_errmsg[10] = {\n    (z_const char *)\"need dictionary\",     /* Z_NEED_DICT       2  */\n    (z_const char *)\"stream end\",          /* Z_STREAM_END      1  */\n    (z_const char *)\"\",                    /* Z_OK              0  */\n    (z_const char *)\"file error\",          /* Z_ERRNO         (-1) */\n    (z_const char *)\"stream error\",        /* Z_STREAM_ERROR  (-2) */\n    (z_const char *)\"data error\",          /* Z_DATA_ERROR    (-3) */\n    (z_const char *)\"insufficient memory\", /* Z_MEM_ERROR     (-4) */\n    (z_const char *)\"buffer error\",        /* Z_BUF_ERROR     (-5) */\n    (z_const char *)\"incompatible version\",/* Z_VERSION_ERROR (-6) */\n    (z_const char *)\"\"\n};\n\n\nconst char * ZEXPORT zlibVersion(void) {\n    return ZLIB_VERSION;\n}\n\nuLong ZEXPORT zlibCompileFlags(void) {\n    uLong flags;\n\n    flags = 0;\n    switch ((int)(sizeof(uInt))) {\n    case 2:     break;\n    case 4:     flags += 1;     break;\n    case 8:     flags += 2;     break;\n    default:    flags += 3;\n    }\n    switch ((int)(sizeof(uLong))) {\n    case 2:     break;\n    case 4:     flags += 1 << 2;        break;\n    case 8:     flags += 2 << 2;        break;\n    default:    flags += 3 << 2;\n    }\n    switch ((int)(sizeof(voidpf))) {\n    case 2:     break;\n    case 4:     flags += 1 << 4;        break;\n    case 8:     flags += 2 << 4;        break;\n    default:    flags += 3 << 4;\n    }\n    switch ((int)(sizeof(z_off_t))) {\n    case 2:     break;\n    case 4:     flags += 1 << 6;        break;\n    case 8:     flags += 2 << 6;        break;\n    default:    flags += 3 << 6;\n    }\n#ifdef ZLIB_DEBUG\n    flags += 1 << 8;\n#endif\n    /*\n#if defined(ASMV) || defined(ASMINF)\n    flags += 1 << 9;\n#endif\n     */\n#ifdef ZLIB_WINAPI\n    flags += 1 << 10;\n#endif\n#ifdef BUILDFIXED\n    flags += 1 << 12;\n#endif\n#ifdef DYNAMIC_CRC_TABLE\n    flags += 1 << 13;\n#endif\n#ifdef NO_GZCOMPRESS\n    flags += 1L << 16;\n#endif\n#ifdef NO_GZIP\n    flags += 1L << 17;\n#endif\n#ifdef PKZIP_BUG_WORKAROUND\n    flags += 1L << 20;\n#endif\n#ifdef FASTEST\n    flags += 1L << 21;\n#endif\n#if defined(STDC) || defined(Z_HAVE_STDARG_H)\n#   ifdef NO_vsnprintf\n#       ifdef ZLIB_INSECURE\n            flags += 1L << 25;\n#       else\n            flags += 1L << 27;\n#       endif\n#       ifdef HAS_vsprintf_void\n            flags += 1L << 26;\n#       endif\n#   else\n#       ifdef HAS_vsnprintf_void\n            flags += 1L << 26;\n#       endif\n#   endif\n#else\n    flags += 1L << 24;\n#   ifdef NO_snprintf\n#       ifdef ZLIB_INSECURE\n            flags += 1L << 25;\n#       else\n            flags += 1L << 27;\n#       endif\n#       ifdef HAS_sprintf_void\n            flags += 1L << 26;\n#       endif\n#   else\n#       ifdef HAS_snprintf_void\n            flags += 1L << 26;\n#       endif\n#   endif\n#endif\n    return flags;\n}\n\n#ifdef ZLIB_DEBUG\n#include <stdlib.h>\n#  ifndef verbose\n#    define verbose 0\n#  endif\nint ZLIB_INTERNAL z_verbose = verbose;\n\nvoid ZLIB_INTERNAL z_error(char *m) {\n    fprintf(stderr, \"%s\\n\", m);\n    exit(1);\n}\n#endif\n\n/* exported to allow conversion of error code to string for compress() and\n * uncompress()\n */\nconst char * ZEXPORT zError(int err) {\n    return ERR_MSG(err);\n}\n\n#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800\n    /* The older Microsoft C Run-Time Library for Windows CE doesn't have\n     * errno.  We define it as a global variable to simplify porting.\n     * Its value is always 0 and should not be used.\n     */\n    int errno = 0;\n#endif\n\n#ifndef HAVE_MEMCPY\n\nvoid ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) {\n    uchf *p = dst;\n    const uchf *q = src;\n    while (n) {\n        *p++ = *q++;\n        n--;\n    }\n}\n\nint ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) {\n    const uchf *p = s1, *q = s2;\n    while (n) {\n        if (*p++ != *q++)\n            return (int)p[-1] - (int)q[-1];\n        n--;\n    }\n    return 0;\n}\n\nvoid ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) {\n    uchf *p = b;\n    if (len == 0) return;\n    while (len) {\n        *p++ = 0;\n        len--;\n    }\n}\n\n#endif\n\n#ifndef Z_SOLO\n\n#ifdef SYS16BIT\n\n#ifdef __TURBOC__\n/* Turbo C in 16-bit mode */\n\n#  define MY_ZCALLOC\n\n/* Turbo C malloc() does not allow dynamic allocation of 64K bytes\n * and farmalloc(64K) returns a pointer with an offset of 8, so we\n * must fix the pointer. Warning: the pointer must be put back to its\n * original form in order to free it, use zcfree().\n */\n\n#define MAX_PTR 10\n/* 10*64K = 640K */\n\nlocal int next_ptr = 0;\n\ntypedef struct ptr_table_s {\n    voidpf org_ptr;\n    voidpf new_ptr;\n} ptr_table;\n\nlocal ptr_table table[MAX_PTR];\n/* This table is used to remember the original form of pointers\n * to large buffers (64K). Such pointers are normalized with a zero offset.\n * Since MSDOS is not a preemptive multitasking OS, this table is not\n * protected from concurrent access. This hack doesn't work anyway on\n * a protected system like OS/2. Use Microsoft C instead.\n */\n\nvoidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {\n    voidpf buf;\n    ulg bsize = (ulg)items*size;\n\n    (void)opaque;\n\n    /* If we allocate less than 65520 bytes, we assume that farmalloc\n     * will return a usable pointer which doesn't have to be normalized.\n     */\n    if (bsize < 65520L) {\n        buf = farmalloc(bsize);\n        if (*(ush*)&buf != 0) return buf;\n    } else {\n        buf = farmalloc(bsize + 16L);\n    }\n    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;\n    table[next_ptr].org_ptr = buf;\n\n    /* Normalize the pointer to seg:0 */\n    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;\n    *(ush*)&buf = 0;\n    table[next_ptr++].new_ptr = buf;\n    return buf;\n}\n\nvoid ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {\n    int n;\n\n    (void)opaque;\n\n    if (*(ush*)&ptr != 0) { /* object < 64K */\n        farfree(ptr);\n        return;\n    }\n    /* Find the original pointer */\n    for (n = 0; n < next_ptr; n++) {\n        if (ptr != table[n].new_ptr) continue;\n\n        farfree(table[n].org_ptr);\n        while (++n < next_ptr) {\n            table[n-1] = table[n];\n        }\n        next_ptr--;\n        return;\n    }\n    Assert(0, \"zcfree: ptr not found\");\n}\n\n#endif /* __TURBOC__ */\n\n\n#ifdef M_I86\n/* Microsoft C in 16-bit mode */\n\n#  define MY_ZCALLOC\n\n#if (!defined(_MSC_VER) || (_MSC_VER <= 600))\n#  define _halloc  halloc\n#  define _hfree   hfree\n#endif\n\nvoidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) {\n    (void)opaque;\n    return _halloc((long)items, size);\n}\n\nvoid ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {\n    (void)opaque;\n    _hfree(ptr);\n}\n\n#endif /* M_I86 */\n\n#endif /* SYS16BIT */\n\n\n#ifndef MY_ZCALLOC /* Any system without a special alloc function */\n\n#ifndef STDC\nextern voidp malloc(uInt size);\nextern voidp calloc(uInt items, uInt size);\nextern void free(voidpf ptr);\n#endif\n\nvoidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {\n    (void)opaque;\n    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :\n                              (voidpf)calloc(items, size);\n}\n\nvoid ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {\n    (void)opaque;\n    free(ptr);\n}\n\n#endif /* MY_ZCALLOC */\n\n#endif /* !Z_SOLO */\n"
  },
  {
    "path": "vendor/core/vendor/zlib/zutil.h",
    "content": "/* zutil.h -- internal interface and configuration of the compression library\n * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n */\n\n/* WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change. Applications should only use zlib.h.\n */\n\n/* @(#) $Id$ */\n\n#ifndef ZUTIL_H\n#define ZUTIL_H\n\n#ifdef HAVE_HIDDEN\n#  define ZLIB_INTERNAL __attribute__((visibility (\"hidden\")))\n#else\n#  define ZLIB_INTERNAL\n#endif\n\n#include \"zlib.h\"\n\n#if defined(STDC) && !defined(Z_SOLO)\n#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))\n#    include <stddef.h>\n#  endif\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* since \"static\" is used to mean two completely different things in C, we\n   define \"local\" for the non-static meaning of \"static\", for readability\n   (compile with -Dlocal if your debugger can't find static symbols) */\n\nextern const char deflate_copyright[];\nextern const char inflate_copyright[];\nextern const char inflate9_copyright[];\n\ntypedef unsigned char  uch;\ntypedef uch FAR uchf;\ntypedef unsigned short ush;\ntypedef ush FAR ushf;\ntypedef unsigned long  ulg;\n\n#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC)\n#  include <limits.h>\n#  if (ULONG_MAX == 0xffffffffffffffff)\n#    define Z_U8 unsigned long\n#  elif (ULLONG_MAX == 0xffffffffffffffff)\n#    define Z_U8 unsigned long long\n#  elif (ULONG_LONG_MAX == 0xffffffffffffffff)\n#    define Z_U8 unsigned long long\n#  elif (UINT_MAX == 0xffffffffffffffff)\n#    define Z_U8 unsigned\n#  endif\n#endif\n\nextern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */\n/* (size given to avoid silly warnings with Visual C++) */\n\n#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)]\n\n#define ERR_RETURN(strm,err) \\\n  return (strm->msg = ERR_MSG(err), (err))\n/* To be used only when the state is known to be valid */\n\n        /* common constants */\n#if MAX_WBITS < 9 || MAX_WBITS > 15\n#  error MAX_WBITS must be in 9..15\n#endif\n#ifndef DEF_WBITS\n#  define DEF_WBITS MAX_WBITS\n#endif\n/* default windowBits for decompression. MAX_WBITS is for compression only */\n\n#if MAX_MEM_LEVEL >= 8\n#  define DEF_MEM_LEVEL 8\n#else\n#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n/* default memLevel */\n\n#define STORED_BLOCK 0\n#define STATIC_TREES 1\n#define DYN_TREES    2\n/* The three kinds of block type */\n\n#define MIN_MATCH  3\n#define MAX_MATCH  258\n/* The minimum and maximum match lengths */\n\n#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */\n\n        /* target dependencies */\n\n#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))\n#  define OS_CODE  0x00\n#  ifndef Z_SOLO\n#    if defined(__TURBOC__) || defined(__BORLANDC__)\n#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))\n         /* Allow compilation with ANSI keywords only enabled */\n         void _Cdecl farfree( void *block );\n         void *_Cdecl farmalloc( unsigned long nbytes );\n#      else\n#        include <alloc.h>\n#      endif\n#    else /* MSC or DJGPP */\n#      include <malloc.h>\n#    endif\n#  endif\n#endif\n\n#ifdef AMIGA\n#  define OS_CODE  1\n#endif\n\n#if defined(VAXC) || defined(VMS)\n#  define OS_CODE  2\n#  define F_OPEN(name, mode) \\\n     fopen((name), (mode), \"mbc=60\", \"ctx=stm\", \"rfm=fix\", \"mrs=512\")\n#endif\n\n#ifdef __370__\n#  if __TARGET_LIB__ < 0x20000000\n#    define OS_CODE 4\n#  elif __TARGET_LIB__ < 0x40000000\n#    define OS_CODE 11\n#  else\n#    define OS_CODE 8\n#  endif\n#endif\n\n#if defined(ATARI) || defined(atarist)\n#  define OS_CODE  5\n#endif\n\n#ifdef OS2\n#  define OS_CODE  6\n#  if defined(M_I86) && !defined(Z_SOLO)\n#    include <malloc.h>\n#  endif\n#endif\n\n#if defined(MACOS)\n#  define OS_CODE  7\n#endif\n\n#if defined(__acorn) || defined(__riscos)\n#  define OS_CODE 13\n#endif\n\n#if defined(WIN32) && !defined(__CYGWIN__)\n#  define OS_CODE  10\n#endif\n\n#ifdef _BEOS_\n#  define OS_CODE  16\n#endif\n\n#ifdef __TOS_OS400__\n#  define OS_CODE 18\n#endif\n\n#ifdef __APPLE__\n#  define OS_CODE 19\n#endif\n\n#if defined(__BORLANDC__) && !defined(MSDOS)\n  #pragma warn -8004\n  #pragma warn -8008\n  #pragma warn -8066\n#endif\n\n/* provide prototypes for these when building zlib without LFS */\n#ifndef Z_LARGE64\n   ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);\n   ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);\n   ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);\n#endif\n\n        /* common defaults */\n\n#ifndef OS_CODE\n#  define OS_CODE  3     /* assume Unix */\n#endif\n\n#ifndef F_OPEN\n#  define F_OPEN(name, mode) fopen((name), (mode))\n#endif\n\n         /* functions */\n\n#if defined(pyr) || defined(Z_SOLO)\n#  define NO_MEMCPY\n#endif\n#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)\n /* Use our own functions for small and medium model with MSC <= 5.0.\n  * You may have to use the same strategy for Borland C (untested).\n  * The __SC__ check is for Symantec.\n  */\n#  define NO_MEMCPY\n#endif\n#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)\n#  define HAVE_MEMCPY\n#endif\n#ifdef HAVE_MEMCPY\n#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */\n#    define zmemcpy _fmemcpy\n#    define zmemcmp _fmemcmp\n#    define zmemzero(dest, len) _fmemset(dest, 0, len)\n#  else\n#    define zmemcpy memcpy\n#    define zmemcmp memcmp\n#    define zmemzero(dest, len) memset(dest, 0, len)\n#  endif\n#else\n   void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t);\n   int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t);\n   void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t);\n#endif\n\n/* Diagnostic functions */\n#ifdef ZLIB_DEBUG\n#  include <stdio.h>\n   extern int ZLIB_INTERNAL z_verbose;\n   extern void ZLIB_INTERNAL z_error(char *m);\n#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}\n#  define Trace(x) {if (z_verbose>=0) fprintf x ;}\n#  define Tracev(x) {if (z_verbose>0) fprintf x ;}\n#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}\n#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}\n#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}\n#else\n#  define Assert(cond,msg)\n#  define Trace(x)\n#  define Tracev(x)\n#  define Tracevv(x)\n#  define Tracec(c,x)\n#  define Tracecv(c,x)\n#endif\n\n#ifndef Z_SOLO\n   voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items,\n                                unsigned size);\n   void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr);\n#endif\n\n#define ZALLOC(strm, items, size) \\\n           (*((strm)->zalloc))((strm)->opaque, (items), (size))\n#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))\n#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}\n\n/* Reverse the bytes in a 32-bit value */\n#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \\\n                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))\n\n#ifdef Z_ONCE\n/*\n  Create a local z_once() function depending on the availability of atomics.\n */\n\n/* Check for the availability of atomics. */\n#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \\\n    !defined(__STDC_NO_ATOMICS__)\n\n#include <stdatomic.h>\ntypedef struct {\n    atomic_flag begun;\n    atomic_int done;\n} z_once_t;\n#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0}\n\n/*\n  Run the provided init() function exactly once, even if multiple threads\n  invoke once() at the same time. The state must be a once_t initialized with\n  Z_ONCE_INIT.\n */\nlocal void z_once(z_once_t *state, void (*init)(void)) {\n    if (!atomic_load(&state->done)) {\n        if (atomic_flag_test_and_set(&state->begun))\n            while (!atomic_load(&state->done))\n                ;\n        else {\n            init();\n            atomic_store(&state->done, 1);\n        }\n    }\n}\n\n#else   /* no atomics */\n\n#warning zlib not thread-safe\n\ntypedef struct z_once_s {\n    volatile int begun;\n    volatile int done;\n} z_once_t;\n#define Z_ONCE_INIT {0, 0}\n\n/* Test and set. Alas, not atomic, but tries to limit the period of\n   vulnerability. */\nlocal int test_and_set(int volatile *flag) {\n    int was;\n\n    was = *flag;\n    *flag = 1;\n    return was;\n}\n\n/* Run the provided init() function once. This is not thread-safe. */\nlocal void z_once(z_once_t *state, void (*init)(void)) {\n    if (!state->done) {\n        if (test_and_set(&state->begun))\n            while (!state->done)\n                ;\n        else {\n            init();\n            state->done = 1;\n        }\n    }\n}\n\n#endif /* ?atomics */\n\n#endif /* Z_ONCE */\n\n#endif /* ZUTIL_H */\n"
  },
  {
    "path": "vendor/core/vendor/zlib.mask",
    "content": "amiga\ncontrib\ndoc\nexamples\nmsdos\nnintendods\nold\nos400\nqnx\ntest\nwatcom\nwin32\nChangeLog\nconfigure\nFAQ\nINDEX\nmake_vms.com\nCMakeLists.txt\nMakefile\nMakefile.in\nzconf.h.in\nREADME\ntreebuild.xml\nzlib.3\nzlib.3.pdf\nzlib.map\nzlib.pc.cmakein\nzlib.pc.in\n.cmake-format.yaml\nBUILD.bazel\nMODULE.bazel\nREADME-cmake.md\nzlibConfig.cmake.in\n"
  },
  {
    "path": "vendor/noa/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(noa VERSION 0.0.0 LANGUAGES CXX\n  DESCRIPTION \"A set of re-usable and opinionated utilities for Sourcemeta projects\")\nlist(APPEND CMAKE_MODULE_PATH \"${PROJECT_SOURCE_DIR}/cmake\")\ninclude(noa)\n\n# Options\noption(NOA_HASH \"Build the Noa Hash library\" ON)\noption(NOA_FLAT_MAP \"Build the Noa Flat Map library\" ON)\noption(NOA_REGEX \"Build the Noa Regex library\" ON)\noption(NOA_GOOGLETEST \"Build the Google Test library\" ON)\noption(NOA_GOOGLEBENCHMARK \"Build the Google Benchmark library\" ON)\noption(NOA_TESTS \"Build the Noa tests\" OFF)\noption(NOA_BENCHMARK \"Build the Noa benchmarks\" OFF)\noption(NOA_DOCS \"Build the Noa docs\" OFF)\noption(NOA_INSTALL \"Install the Noa library\" ON)\noption(NOA_ADDRESS_SANITIZER \"Build Noa with an address sanitizer\" OFF)\noption(NOA_UNDEFINED_SANITIZER \"Build Noa with an undefined behavior sanitizer\" OFF)\n\nif(NOA_INSTALL)\n  include(GNUInstallDirs)\n  include(CMakePackageConfigHelpers)\n  configure_package_config_file(\n    config.cmake.in\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    INSTALL_DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n  write_basic_package_version_file(\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    COMPATIBILITY SameMajorVersion)\n  install(FILES\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake\"\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\"\n    COMPONENT sourcemeta_noa_dev)\nendif()\n\nif(NOA_HASH)\n  add_subdirectory(src/hash)\nendif()\n\nif(NOA_FLAT_MAP)\n  add_subdirectory(src/flat_map)\nendif()\n\nif(NOA_REGEX)\n  find_package(BoostRegex REQUIRED)\n  add_subdirectory(src/regex)\nendif()\n\nif(NOA_GOOGLETEST)\n  find_package(GoogleTest REQUIRED)\nendif()\n\nif(NOA_ADDRESS_SANITIZER)\n  noa_sanitizer(TYPE address)\nelseif(NOA_UNDEFINED_SANITIZER)\n  noa_sanitizer(TYPE undefined)\nendif()\n\nif(NOA_DOCS)\n  noa_target_doxygen(CONFIG \"${PROJECT_SOURCE_DIR}/doxygen/Doxyfile.in\"\n    OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/website\")\nendif()\n\nif(PROJECT_IS_TOP_LEVEL)\n  noa_target_clang_format(SOURCES\n    benchmark/*.h benchmark/*.cc\n    src/*.h src/*.cc\n    test/*.h test/*.cc)\n  noa_target_clang_tidy(SOURCES\n    src/*.h src/*.cc)\nendif()\n\nif(NOA_TESTS AND NOA_GOOGLETEST)\n  enable_testing()\n\n  if(NOA_HASH)\n    add_subdirectory(test/hash)\n  endif()\n\n  if(NOA_FLAT_MAP)\n    add_subdirectory(test/flat_map)\n  endif()\n\n  if(NOA_REGEX)\n    add_subdirectory(test/regex)\n  endif()\n\n  if(PROJECT_IS_TOP_LEVEL)\n    # Otherwise we need the child project to link\n    # against the sanitizers too.\n    if(NOT NOA_ADDRESS_SANITIZER AND NOT NOA_UNDEFINED_SANITIZER)\n      add_subdirectory(test/packaging)\n    endif()\n  endif()\nendif()\n\nif(NOA_GOOGLEBENCHMARK)\n  find_package(GoogleBenchmark REQUIRED)\nendif()\n\nif(NOA_BENCHMARK AND NOA_GOOGLEBENCHMARK)\n  add_subdirectory(benchmark)\nendif()\n"
  },
  {
    "path": "vendor/noa/LICENSE",
    "content": "This software is dual-licensed: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version. For the terms of this license, see\n<http://www.gnu.org/licenses/>.\n\nYou are free to use this software under the terms of the GNU Affero General\nPublic License WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\nAlternatively, you can use this software under a commercial license, as set out\nin <https://www.sourcemeta.com/licensing/>.\n"
  },
  {
    "path": "vendor/noa/cmake/FindBoostRegex.cmake",
    "content": "if(NOT BoostRegex_FOUND)\n  set(BOOST_REGEX_DIR \"${PROJECT_SOURCE_DIR}/vendor/boost-regex\")\n  set(BOOST_REGEX_PUBLIC_HEADER \"${BOOST_REGEX_DIR}/include/boost/regex.hpp\")\n\n  set(BOOST_REGEX_PRIVATE_HEADERS\n    \"${BOOST_REGEX_DIR}/include/boost/cregex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex.h\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex_fwd.hpp\")\n  set(BOOST_REGEX_PRIVATE_HEADERS_REGEX\n    \"${BOOST_REGEX_DIR}/include/boost/regex/concepts.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/config.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/icu.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/mfc.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/pattern_except.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/user.hpp\")\n  set(BOOST_REGEX_PRIVATE_HEADERS_REGEX_CONFIG\n    \"${BOOST_REGEX_DIR}/include/boost/regex/config/borland.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/config/cwchar.hpp\")\n  set(BOOST_REGEX_PRIVATE_HEADERS_REGEX_PENDING\n    \"${BOOST_REGEX_DIR}/include/boost/regex/pending/object_cache.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/pending/static_mutex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/pending/unicode_iterator.hpp\")\n  set(BOOST_REGEX_PRIVATE_HEADERS_REGEX_V4\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/basic_regex_parser.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/object_cache.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/cregex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/basic_regex_creator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_format.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/u32regex_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/states.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/perl_matcher_recursive.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/perl_matcher.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_grep.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/match_flags.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/w32_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_replace.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/perl_matcher_common.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/c_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_traits_defaults.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/cpp_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/syntax_type.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/protected_call.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regbase.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_raw_buffer.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/basic_regex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/error_type.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/icu.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_match.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/u32regex_token_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_search.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/indexed_bit_flag.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_token_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/iterator_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/perl_matcher_non_recursive.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_workaround.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/sub_match.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_merge.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_fwd.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/iterator_category.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/regex_split.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/unicode_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/primary_transform.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/char_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/mem_block_cache.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/pattern_except.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v4/match_results.hpp\")\n  set(BOOST_REGEX_PRIVATE_HEADERS_REGEX_V5\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/basic_regex_parser.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/object_cache.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/cregex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/basic_regex_creator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_format.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/u32regex_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/states.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/perl_matcher.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_grep.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/match_flags.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/w32_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_replace.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/perl_matcher_common.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/c_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_traits_defaults.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/cpp_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/syntax_type.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regbase.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_raw_buffer.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/basic_regex.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/error_type.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/icu.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_match.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/u32regex_token_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_search.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_token_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/iterator_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/perl_matcher_non_recursive.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_workaround.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/sub_match.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_merge.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_fwd.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/iterator_category.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/regex_split.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/unicode_iterator.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/primary_transform.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/char_regex_traits.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/mem_block_cache.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/pattern_except.hpp\"\n    \"${BOOST_REGEX_DIR}/include/boost/regex/v5/match_results.hpp\")\n\n  add_library(boost_regex INTERFACE\n    \"${BOOST_REGEX_PUBLIC_HEADER}\"\n    ${BOOST_REGEX_PRIVATE_HEADERS}\n    ${BOOST_REGEX_PRIVATE_HEADERS_REGEX}\n    ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_CONFIG}\n    ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_PENDING}\n    ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_V4}\n    ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_V5})\n\n  target_compile_definitions(boost_regex INTERFACE BOOST_REGEX_STANDALONE)\n\n  add_library(Boost::regex ALIAS boost_regex)\n\n  target_include_directories(boost_regex INTERFACE\n    \"$<BUILD_INTERFACE:${BOOST_REGEX_DIR}/include>\"\n    \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n  set_target_properties(boost_regex\n    PROPERTIES\n      OUTPUT_NAME boost_regex\n      PUBLIC_HEADER \"${BOOST_REGEX_PUBLIC_HEADER}\"\n      PRIVATE_HEADER \"${BOOST_REGEX_PRIVATE_HEADERS}\"\n      EXPORT_NAME boost_regex)\n\n  if(NOA_INSTALL)\n    include(GNUInstallDirs)\n    install(TARGETS boost_regex\n      EXPORT boost_regex\n      PUBLIC_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost\"\n        COMPONENT sourcemeta_noa\n      PRIVATE_HEADER DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost\"\n        COMPONENT sourcemeta_noa\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        COMPONENT sourcemeta_noa\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_noa\n        NAMELINK_COMPONENT sourcemeta_noa_dev\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        COMPONENT sourcemeta_noa_dev)\n    install(FILES ${BOOST_REGEX_PRIVATE_HEADERS_REGEX}\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost/regex\"\n        COMPONENT sourcemeta_noa)\n    install(FILES ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_CONFIG}\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost/regex/config\"\n        COMPONENT sourcemeta_noa)\n    install(FILES ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_PENDING}\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost/regex/pending\"\n        COMPONENT sourcemeta_noa)\n    install(FILES ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_V4}\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost/regex/v4\"\n        COMPONENT sourcemeta_noa)\n    install(FILES ${BOOST_REGEX_PRIVATE_HEADERS_REGEX_V5}\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/boost/regex/v5\"\n        COMPONENT sourcemeta_noa)\n    install(EXPORT boost_regex\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/boostregex\"\n      COMPONENT sourcemeta_noa_dev)\n\n    file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/boostregex-config.cmake\n      \"include(\\\"\\${CMAKE_CURRENT_LIST_DIR}/boost_regex.cmake\\\")\\n\"\n      \"check_required_components(\\\"boostregex\\\")\\n\")\n    install(FILES\n      \"${CMAKE_CURRENT_BINARY_DIR}/boostregex-config.cmake\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/boostregex\"\n      COMPONENT sourcemeta_noa_dev)\n  endif()\n\n  set(BoostRegex_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/FindGoogleBenchmark.cmake",
    "content": "if(NOT Benchmark_FOUND)\n  set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL \"Enable testing of the benchmark library.\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/googlebenchmark\")\n  set(Benchmark_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/FindGoogleTest.cmake",
    "content": "if(NOT GoogleTest_FOUND)\n  set(BUILD_GMOCK ON CACHE BOOL \"enable googlemock\")\n  set(INSTALL_GTEST OFF CACHE BOOL \"disable installation\")\n  add_subdirectory(\"${PROJECT_SOURCE_DIR}/vendor/googletest\")\n  set(GoogleTest_FOUND ON)\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/commands/copy-file.cmake",
    "content": "function(noa_command_copy_file)\n  cmake_parse_arguments(NOA_COMMAND_COPY_FILE \"\" \"FROM;TO\" \"\" ${ARGN})\n\n  if(NOT NOA_COMMAND_COPY_FILE_FROM)\n    message(FATAL_ERROR \"You must pass the file to copy using the FROM option\")\n  endif()\n  if(NOT NOA_COMMAND_COPY_FILE_TO)\n    message(FATAL_ERROR \"You must pass the destination to copy to using the TO option\")\n  endif()\n\n  add_custom_command(\n    OUTPUT \"${NOA_COMMAND_COPY_FILE_TO}\"\n    COMMAND \"${CMAKE_COMMAND}\" -E copy \"${NOA_COMMAND_COPY_FILE_FROM}\" \"${NOA_COMMAND_COPY_FILE_TO}\"\n    MAIN_DEPENDENCY \"${NOA_COMMAND_COPY_FILE_FROM}\"\n    DEPENDS \"${NOA_COMMAND_COPY_FILE_FROM}\"\n    COMMENT \"Copying ${NOA_COMMAND_COPY_FILE_FROM} ot ${NOA_COMMAND_COPY_FILE_TO}\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/compiler/options.cmake",
    "content": "function(noa_add_default_options visibility target)\n  if(NOA_COMPILER_MSVC)\n    # See https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category\n    target_compile_options(\"${target}\" ${visibility}\n      /options:strict\n      /permissive-\n      /W4\n      /WL\n      /MP\n      /sdl)\n  elseif(NOA_COMPILER_LLVM OR NOA_COMPILER_GCC)\n    target_compile_options(\"${target}\" ${visibility}\n      -Wall\n      -Wextra\n      -Wpedantic\n      -Wshadow\n      -Wdouble-promotion\n      -Wconversion\n      -Wunused-parameter\n      -Wtrigraphs\n      -Wunreachable-code\n      -Wmissing-braces\n      -Wparentheses\n      -Wswitch\n      -Wunused-function\n      -Wunused-label\n      -Wunused-parameter\n      -Wunused-variable\n      -Wunused-value\n      -Wempty-body\n      -Wuninitialized\n      -Wshadow\n      -Wconversion\n      -Wenum-conversion\n      -Wfloat-conversion\n      -Wimplicit-fallthrough\n      -Wsign-compare\n      -Wsign-conversion\n      -Wunknown-pragmas\n      -Wnon-virtual-dtor\n      -Woverloaded-virtual\n      -Winvalid-offsetof\n      -funroll-loops\n      -fstrict-aliasing\n      -ftree-vectorize\n\n      # To improve how much GCC/Clang will vectorize\n      -fno-math-errno\n\n      # Assume that signed arithmetic overflow of addition, subtraction and\n      # multiplication wraps around using twos-complement representation\n      # See https://users.cs.utah.edu/~regehr/papers/overflow12.pdf\n      # See https://www.postgresql.org/message-id/1689.1134422394@sss.pgh.pa.us\n      -fwrapv)\n  endif()\n\n  if(NOA_COMPILER_LLVM)\n    target_compile_options(\"${target}\" ${visibility}\n      -Wbool-conversion\n      -Wint-conversion\n      -Wpointer-sign\n      -Wconditional-uninitialized\n      -Wconstant-conversion\n      -Wnon-literal-null-conversion\n      -Wshorten-64-to-32\n      -Wdeprecated-implementations\n      -Winfinite-recursion\n      -Wnewline-eof\n      -Wfour-char-constants\n      -Wselector\n      -Wundeclared-selector\n      -Wdocumentation\n      -Wmove\n      -Wc++11-extensions\n      -Wcomma\n      -Wno-exit-time-destructors\n      -Wrange-loop-analysis\n\n      # Enable loop vectorization for performance reasons\n      -fvectorize\n      # Enable vectorization of straight-line code for performance\n      -fslp-vectorize)\n  elseif(NOA_COMPILER_GCC)\n    target_compile_options(\"${target}\" ${visibility}\n      -fno-trapping-math\n      # Newer versions of GCC (i.e. 14) seem to print a lot of false-positives here\n      -Wno-dangling-reference\n      # GCC seems to print a lot of false-positives here\n      -Wno-free-nonheap-object\n      # Disables runtime type information\n      -fno-rtti)\n  endif()\nendfunction()\n\n# For studying failed vectorization results\n# - On Clang , seems to only take effect on release shared builds\n# - On GCC, seems to only take effect on release shared builds\nfunction(noa_add_vectorization_diagnostics target)\n  if(NOA_COMPILER_LLVM)\n    # See https://llvm.org/docs/Vectorizers.html#id6\n    target_compile_options(\"${target}\" PRIVATE\n      -Rpass-analysis=loop-vectorize\n      -Rpass-missed=loop-vectorize)\n  elseif(NOA_COMPILER_GCC)\n    target_compile_options(\"${target}\" PRIVATE\n      -fopt-info-vec-missed\n      -fopt-info-loop-missed)\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/compiler/sanitizer.cmake",
    "content": "function(noa_sanitizer)\n  cmake_parse_arguments(NOA_SANITIZER \"\" \"TYPE\" \"\" ${ARGN})\n\n  if(NOT NOA_SANITIZER_TYPE)\n    message(FATAL_ERROR \"You must pass the intended sanitizer\")\n  endif()\n\n  if(NOA_COMPILER_LLVM AND \"${NOA_SANITIZER_TYPE}\" STREQUAL \"address\")\n    # See https://clang.llvm.org/docs/AddressSanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang AddressSanitizer\")\n    add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope)\n    add_link_options(-fsanitize=address)\n    # Get nicer stack traces with the Address sanitizer\n    add_compile_options(-fno-omit-frame-pointer -fno-optimize-sibling-calls)\n    add_compile_options(-O1)\n  elseif(NOA_COMPILER_LLVM AND \"${NOA_SANITIZER_TYPE}\" STREQUAL \"memory\")\n    if(APPLE)\n      message(FATAL_ERROR \"Clang MemorySanitizer is not available on Apple platforms\")\n    endif()\n\n    # See https://clang.llvm.org/docs/MemorySanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang MemorySanitizer\")\n    add_compile_options(-fsanitize=memory -fno-sanitize-memory-use-after-dtor)\n    add_link_options(-fsanitize=memory)\n    # Get nicer stack traces with the Memory sanitizer\n    add_compile_options(-fno-omit-frame-pointer -fno-optimize-sibling-calls)\n    add_compile_options(-O1)\n  elseif(NOA_COMPILER_LLVM AND \"${NOA_SANITIZER_TYPE}\" STREQUAL \"undefined\")\n    # See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html\n    message(STATUS \"Enabling sanitizer: Clang UndefinedBehaviorSanitizer\")\n    add_compile_options(-fsanitize=undefined,nullability,integer,implicit-conversion,local-bounds\n      -fno-sanitize=unsigned-integer-overflow)\n    add_link_options(-fsanitize=undefined,nullability,integer,implicit-conversion,local-bounds\n      -fno-sanitize=unsigned-integer-overflow)\n    # Exit after an error, otherwise this sanitizer only prints warnings\n    add_compile_options(-fno-sanitize-recover=all)\n  else()\n    message(FATAL_ERROR \"Unrecognized compiler and/or sanitizer combination\")\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/defaults.cmake",
    "content": "# Standards (sane modern defaults)\nif(\"CXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_CXX_STANDARD 20)\nendif()\nif(\"C\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_C_STANDARD 11)\nendif()\nif(\"OBJCXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_OBJCXX_STANDARD \"${CMAKE_CXX_STANDARD}\")\nendif()\n\n# Hide symbols from shared libraries by default\n# In certain compilers, like GCC and Clang,\n# symbols are visible by default.\nset(CMAKE_VISIBILITY_INLINES_HIDDEN YES)\nif(\"CXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_CXX_VISIBILITY_PRESET hidden)\nendif()\nif(\"C\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_C_VISIBILITY_PRESET hidden)\nendif()\nif(\"OBJCXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)\nendif()\n\n# By default, stay within ISO C++\nif(\"CXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_CXX_STANDARD_REQUIRED ON)\n  set(CMAKE_CXX_EXTENSIONS OFF)\nendif()\nif(\"C\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_C_STANDARD_REQUIRED ON)\n  set(CMAKE_C_EXTENSIONS OFF)\nendif()\nif(\"OBJCXX\" IN_LIST NOA_LANGUAGES)\n  set(CMAKE_OBJCXX_STANDARD_REQUIRED ON)\n  set(CMAKE_OBJCXX_EXTENSIONS OFF)\nendif()\n\n# Export compile commands by default.\n# It is very useful for IDE integration, linting, etc\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n# Prevent DT_RPATH/DT_RUNPATH problem\n# This problem is not present on Apple platforms.\n# See https://www.youtube.com/watch?v=m0DwB4OvDXk\nif(NOT APPLE)\n  set(CMAKE_INSTALL_RPATH $ORIGIN)\nendif()\n\n# Delay GoogleTest discovery until before running the tests\n# See https://discourse.cmake.org/t/default-value-for-new-discovery-mode-option-for-gtest-discover-tests/1422\nset(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE PRE_TEST)\n\n# Always use folders in IDE\n# See https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html\nset_property(GLOBAL PROPERTY USE_FOLDERS ON)\n\n# On Windows, during build, put executables and libraries in the same directory.\n# Otherwise, if there is any shared library being generated, the binaries\n# linking to it will not be able to find it and i.e. unit tests will fail.\n# Note that GoogleTest does this already to a non-configurable top-level\n# `bin` directory, so adopting that convention here.\n# See https://stackoverflow.com/q/39807664\n# See https://github.com/google/googletest/blob/e47544ad31cb3ceecd04cc13e8fe556f8df9fe0b/googletest/cmake/internal_utils.cmake#L173-L174\nif(WIN32)\n  # For EXE files\n  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\" CACHE STRING \"\")\n  # For DLL files\n  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\" CACHE STRING \"\")\nendif()\n\n# Enable IPO/LTO to help the compiler optimize across modules.\n# Only do so in release, given these optimizations can significantly\n# increase build times.\n\n# Note we don't use CheckIPOSupported and CMAKE_INTERPROCEDURAL_OPTIMIZATION,\n# as those CMake features can only enable thin LTO. For Fat LTO, see:\n# - https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html\n# - https://llvm.org/docs/FatLTO.html\n\nif(NOA_COMPILER_GCC AND CMAKE_BUILD_TYPE STREQUAL \"Release\" AND NOT BUILD_SHARED_LIBS)\n  message(STATUS \"Enabling Fat LTO\")\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -flto -ffat-lto-objects\")\n  set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -flto\")\n  set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -flto\")\nendif()\n\n# TODO: Make this work on Linux on LLVM\nif(NOA_COMPILER_LLVM AND CMAKE_BUILD_TYPE STREQUAL \"Release\" AND NOT BUILD_SHARED_LIBS AND APPLE)\n  message(STATUS \"Enabling Fat LTO\")\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -flto=full\")\n  set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -flto=full\")\n  set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -flto=full\")\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/options/enum.cmake",
    "content": "function(noa_option_enum)\n  cmake_parse_arguments(NOA_OPTION_ENUM \"\" \"NAME;DEFAULT;DESCRIPTION\" \"CHOICES\" ${ARGN})\n\n  if(NOT NOA_OPTION_ENUM_NAME)\n    message(FATAL_ERROR \"You must pass the option name as NAME\")\n  endif()\n  if(NOT NOA_OPTION_ENUM_DEFAULT)\n    message(FATAL_ERROR \"You must pass the option default value as DEFAULT\")\n  endif()\n  if(NOT \"${NOA_OPTION_ENUM_DEFAULT}\" IN_LIST NOA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"Default value of ${NOA_OPTION_ENUM_NAME} must be one of these: ${NOA_OPTION_ENUM_CHOICES}\")\n  endif()\n  if(NOT NOA_OPTION_ENUM_DESCRIPTION)\n    message(FATAL_ERROR \"You must pass the option description as DESCRIPTION\")\n  endif()\n  if(NOT NOA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"You must pass the option enum choices as CHOICES\")\n  endif()\n\n  # Declare the option\n  set(\"${NOA_OPTION_ENUM_NAME}\" \"${NOA_OPTION_ENUM_DEFAULT}\"\n    CACHE STRING \"${NOA_OPTION_ENUM_DESCRIPTION}\")\n\n  # Display a nice set of options in `cmake-gui`\n  set_property(CACHE \"${NOA_OPTION_ENUM_NAME}\"\n    PROPERTY STRINGS ${NOA_OPTION_ENUM_CHOICES})\n\n  # Perform validation\n  if(NOT \"${${NOA_OPTION_ENUM_NAME}}\" IN_LIST NOA_OPTION_ENUM_CHOICES)\n    message(FATAL_ERROR \"Value of ${NOA_OPTION_ENUM_NAME} must be one of these: ${NOA_OPTION_ENUM_CHOICES}\")\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/shim.cmake",
    "content": "# The PROJECT_IS_TOP_LEVEL handy variable is only\n# available on CMake >=3.21.\nif(NOT DEFINED PROJECT_IS_TOP_LEVEL AND \"${CMAKE_PROJECT_NAME}\" STREQUAL \"${PROJECT_NAME}\")\n  set(PROJECT_IS_TOP_LEVEL YES)\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/clang-format.cmake",
    "content": "function(noa_target_clang_format)\n  cmake_parse_arguments(NOA_TARGET_CLANG_FORMAT \"REQUIRED\" \"\" \"SOURCES\" ${ARGN})\n\n  if(NOA_TARGET_CLANG_FORMAT_REQUIRED)\n    find_program(CLANG_FORMAT_BIN NAMES clang-format REQUIRED)\n  else()\n    find_program(CLANG_FORMAT_BIN NAMES clang-format)\n  endif()\n\n  # This covers the empty list too\n  if(NOT NOA_TARGET_CLANG_FORMAT_SOURCES)\n    message(FATAL_ERROR \"You must pass file globs to format in the SOURCES option\")\n  endif()\n  file(GLOB_RECURSE NOA_TARGET_CLANG_FORMAT_FILES\n    ${NOA_TARGET_CLANG_FORMAT_SOURCES})\n\n  set(CLANG_FORMAT_CONFIG \"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-format.config\")\n  if(CLANG_FORMAT_BIN)\n    add_custom_target(clang_format\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CLANG_FORMAT_BIN}\" \"--style=file:${CLANG_FORMAT_CONFIG}\"\n        -i ${NOA_TARGET_CLANG_FORMAT_FILES}\n      COMMENT \"Formatting sources using ClangFormat\")\n    add_custom_target(clang_format_test\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CLANG_FORMAT_BIN}\" \"--style=file:${CLANG_FORMAT_CONFIG}\"\n        --dry-run -Werror\n        -i ${NOA_TARGET_CLANG_FORMAT_FILES}\n      COMMENT \"Checking for ClangFormat compliance\")\n  else()\n    add_custom_target(clang_format\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ClangFormat\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n    add_custom_target(clang_format_test\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ClangFormat\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\n\n  set_target_properties(clang_format clang_format_test PROPERTIES FOLDER \"Formatting\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/clang-format.config",
    "content": "---\nBasedOnStyle: LLVM\nIndentCaseLabels: true\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/clang-tidy.cmake",
    "content": "function(noa_target_clang_tidy)\n  cmake_parse_arguments(NOA_TARGET_CLANG_TIDY \"REQUIRED\" \"\" \"SOURCES\" ${ARGN})\n\n  set(CLANG_TIDY_FIND_PATHS \"\")\n\n  # Locate ClangTidy on default Homebrew installations,\n  # given that the LLVM formula won't symlink `clang-tidy`\n  # to any available path by default.\n  if(APPLE)\n    if(IS_DIRECTORY \"/opt/homebrew/Cellar/llvm\")\n      set(HOMEBREW_LLVM \"/opt/homebrew/Cellar/llvm\")\n    elseif(IS_DIRECTORY \"/usr/local/Cellar/llvm\")\n      set(HOMEBREW_LLVM \"/opt/local/Cellar/llvm\")\n    endif()\n    if(HOMEBREW_LLVM)\n      file(GLOB llvm_version_paths LIST_DIRECTORIES true \"${HOMEBREW_LLVM}/*\")\n      foreach(llvm_version_path ${llvm_version_paths})\n        list(APPEND CLANG_TIDY_FIND_PATHS \"${llvm_version_path}/bin\")\n      endforeach()\n    endif()\n  endif()\n\n  if(NOA_TARGET_CLANG_TIDY_REQUIRED)\n    find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED\n      PATHS ${CLANG_TIDY_FIND_PATHS})\n  else()\n    find_program(CLANG_TIDY_BIN NAMES clang-tidy\n      PATHS ${CLANG_TIDY_FIND_PATHS})\n  endif()\n\n  # This covers the empty list too\n  if(NOT NOA_TARGET_CLANG_TIDY_SOURCES)\n    message(FATAL_ERROR \"You must pass file globs to analyze in the SOURCES option\")\n  endif()\n  file(GLOB_RECURSE NOA_TARGET_CLANG_TIDY_FILES\n    ${NOA_TARGET_CLANG_TIDY_SOURCES})\n\n  set(CLANG_TIDY_CONFIG \"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.config\")\n  if(CLANG_TIDY_BIN)\n    add_custom_target(clang_tidy\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CLANG_TIDY_BIN}\" -p \"${PROJECT_BINARY_DIR}\"\n        --config-file \"${CLANG_TIDY_CONFIG}\"\n        ${NOA_TARGET_CLANG_TIDY_FILES}\n        COMMENT \"Analyzing sources using ClangTidy\")\n  else()\n    add_custom_target(clang_tidy\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ClangTidy\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\n\n  set_target_properties(clang_tidy PROPERTIES FOLDER \"Linting\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/clang-tidy.config",
    "content": "---\n# See https://clang.llvm.org/extra/clang-tidy/index.html\n# First disable all default checks (with -*)\nChecks: '-*,bugprone-*,clang-analyzer-*,clang-diagnostic-*,modernize-*,concurrency-*,cppcoreguidelines-*,performance-*,portability-*,objc-*,misc-*,-misc-no-recursion,-bugprone-easily-swappable-parameters'\nWarningsAsErrors: '*'\nHeaderFilterRegex: ''\nFormatStyle: none\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/doxygen.cmake",
    "content": "function(noa_target_doxygen)\n  cmake_parse_arguments(NOA_TARGET_DOXYGEN \"\" \"CONFIG;OUTPUT\" \"\" ${ARGN})\n\n  if(NOT NOA_TARGET_DOXYGEN_CONFIG)\n    message(FATAL_ERROR \"You must pass an input config file using the CONFIG option\")\n  endif()\n  if(NOT NOA_TARGET_DOXYGEN_OUTPUT)\n    message(FATAL_ERROR \"You must pass an output directory using the OUTPUT option\")\n  endif()\n\n  find_package(Doxygen)\n  if(DOXYGEN_FOUND)\n    set(DOXYGEN_IN \"${NOA_TARGET_DOXYGEN_CONFIG}\")\n    set(DOXYGEN_OUT \"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile\")\n    configure_file(\"${DOXYGEN_IN}\" \"${DOXYGEN_OUT}\" @ONLY)\n    add_custom_target(doxygen\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E make_directory \"${NOA_TARGET_DOXYGEN_OUTPUT}\"\n      COMMAND \"${DOXYGEN_EXECUTABLE}\" \"${DOXYGEN_OUT}\")\n  else()\n    add_custom_target(doxygen VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate Doxygen\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/executable.cmake",
    "content": "function(noa_executable)\n  cmake_parse_arguments(NOA_EXECUTABLE \"\"\n    \"NAMESPACE;PROJECT;NAME;FOLDER;VARIANT;OUTPUT\" \"SOURCES\" ${ARGN})\n\n  if(NOT NOA_EXECUTABLE_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT NOA_EXECUTABLE_NAME)\n    message(FATAL_ERROR \"You must pass the executable name using the NAME option\")\n  endif()\n  if(NOT NOA_EXECUTABLE_FOLDER)\n    message(FATAL_ERROR \"You must pass the folder name using the FOLDER option\")\n  endif()\n  if(NOT NOA_EXECUTABLE_SOURCES)\n    message(FATAL_ERROR \"You must pass the sources list using the SOURCES option\")\n  endif()\n\n  if(NOA_EXECUTABLE_NAMESPACE)\n    set(TARGET_NAME \"${NOA_EXECUTABLE_NAMESPACE}_${NOA_EXECUTABLE_PROJECT}_${NOA_EXECUTABLE_NAME}\")\n  else()\n    set(TARGET_NAME \"${NOA_EXECUTABLE_PROJECT}_${NOA_EXECUTABLE_NAME}\")\n  endif()\n\n  if(NOA_EXECUTABLE_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${NOA_EXECUTABLE_VARIANT}\")\n  endif()\n\n  if(NOA_EXECUTABLE_OUTPUT)\n    set(\"${NOA_EXECUTABLE_OUTPUT}\" \"${TARGET_NAME}\" PARENT_SCOPE)\n  endif()\n\n  add_executable(\"${TARGET_NAME}\" ${NOA_EXECUTABLE_SOURCES})\n  noa_add_default_options(PRIVATE ${TARGET_NAME})\n  set_target_properties(\"${TARGET_NAME}\" PROPERTIES FOLDER \"${NOA_EXECUTABLE_FOLDER}\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/googlebenchmark.cmake",
    "content": "function(noa_googlebenchmark)\n  cmake_parse_arguments(NOA_GOOGLEBENCHMARK \"\"\n    \"NAMESPACE;PROJECT;FOLDER\" \"SOURCES\" ${ARGN})\n\n  if(NOT NOA_GOOGLEBENCHMARK_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT NOA_GOOGLEBENCHMARK_FOLDER)\n    message(FATAL_ERROR \"You must pass the folder name using the FOLDER option\")\n  endif()\n  if(NOT NOA_GOOGLEBENCHMARK_SOURCES)\n    message(FATAL_ERROR \"You must pass the sources list using the SOURCES option\")\n  endif()\n\n  if(NOA_GOOGLEBENCHMARK_NAMESPACE)\n    set(TARGET_NAME \"${NOA_GOOGLEBENCHMARK_NAMESPACE}_${NOA_GOOGLEBENCHMARK_PROJECT}_benchmark\")\n  else()\n    set(TARGET_NAME \"${NOA_GOOGLEBENCHMARK_PROJECT}_benchmark\")\n  endif()\n\n  add_executable(\"${TARGET_NAME}\" ${NOA_GOOGLEBENCHMARK_SOURCES})\n  noa_add_default_options(PRIVATE ${TARGET_NAME})\n  set_target_properties(\"${TARGET_NAME}\" PROPERTIES FOLDER \"${NOA_GOOGLEBENCHMARK_FOLDER}\")\n  target_link_libraries(\"${TARGET_NAME}\" PRIVATE benchmark::benchmark)\n  target_link_libraries(\"${TARGET_NAME}\" PRIVATE benchmark::benchmark_main)\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/googletest.cmake",
    "content": "function(noa_googletest)\n  cmake_parse_arguments(NOA_GOOGLETEST \"\"\n    \"NAMESPACE;PROJECT;NAME;FOLDER;VARIANT\" \"SOURCES\" ${ARGN})\n\n  if(NOA_GOOGLETEST_VARIANT)\n    set(TARGET_VARIANT \"${NOA_GOOGLETEST_VARIANT}_unit\")\n  else()\n    set(TARGET_VARIANT \"unit\")\n  endif()\n\n  noa_executable(\n    NAMESPACE \"${NOA_GOOGLETEST_NAMESPACE}\"\n    PROJECT \"${NOA_GOOGLETEST_PROJECT}\"\n    NAME \"${NOA_GOOGLETEST_NAME}\"\n    FOLDER \"${NOA_GOOGLETEST_FOLDER}\"\n    VARIANT \"${TARGET_VARIANT}\"\n    SOURCES \"${NOA_GOOGLETEST_SOURCES}\"\n    OUTPUT TARGET_NAME)\n\n  target_link_libraries(\"${TARGET_NAME}\"\n    PRIVATE GTest::gtest GTest::gmock GTest::gtest_main)\n  add_test(NAME \"${NOA_GOOGLETEST_PROJECT}.${NOA_GOOGLETEST_NAME}\"\n    COMMAND \"${TARGET_NAME}\" --gtest_brief=1)\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/library.cmake",
    "content": "function(noa_library)\n  cmake_parse_arguments(NOA_LIBRARY \"\"\n    \"NAMESPACE;PROJECT;NAME;FOLDER;VARIANT\" \"PRIVATE_HEADERS;SOURCES\" ${ARGN})\n\n  if(NOT NOA_LIBRARY_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT NOA_LIBRARY_NAME)\n    message(FATAL_ERROR \"You must pass the library name using the NAME option\")\n  endif()\n  if(NOT NOA_LIBRARY_FOLDER)\n    message(FATAL_ERROR \"You must pass the folder name using the FOLDER option\")\n  endif()\n\n  if(NOA_LIBRARY_NAMESPACE)\n    set(INCLUDE_PREFIX \"include/${NOA_LIBRARY_NAMESPACE}/${NOA_LIBRARY_PROJECT}\")\n  else()\n    set(INCLUDE_PREFIX \"include/${NOA_LIBRARY_PROJECT}\")\n  endif()\n\n  set(EXPORT_HEADER_PATH \"${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_PREFIX}/${NOA_LIBRARY_NAME}_export.h\")\n  if(NOT NOA_LIBRARY_VARIANT)\n    set(PUBLIC_HEADER \"${INCLUDE_PREFIX}/${NOA_LIBRARY_NAME}.h\")\n  else()\n    set(PUBLIC_HEADER \"../${INCLUDE_PREFIX}/${NOA_LIBRARY_NAME}.h\")\n  endif()\n\n  if(NOA_LIBRARY_SOURCES)\n    set(ABSOLUTE_PRIVATE_HEADERS \"${EXPORT_HEADER_PATH}\")\n  else()\n    set(ABSOLUTE_PRIVATE_HEADERS)\n  endif()\n\n  foreach(private_header IN LISTS NOA_LIBRARY_PRIVATE_HEADERS)\n    if(NOA_LIBRARY_VARIANT)\n      list(APPEND ABSOLUTE_PRIVATE_HEADERS \"../${INCLUDE_PREFIX}/${NOA_LIBRARY_NAME}_${private_header}\")\n    else()\n      list(APPEND ABSOLUTE_PRIVATE_HEADERS \"${INCLUDE_PREFIX}/${NOA_LIBRARY_NAME}_${private_header}\")\n    endif()\n  endforeach()\n\n  if(NOA_LIBRARY_NAMESPACE)\n    set(TARGET_NAME \"${NOA_LIBRARY_NAMESPACE}_${NOA_LIBRARY_PROJECT}_${NOA_LIBRARY_NAME}\")\n    set(ALIAS_NAME \"${NOA_LIBRARY_NAMESPACE}::${NOA_LIBRARY_PROJECT}::${NOA_LIBRARY_NAME}\")\n  else()\n    set(TARGET_NAME \"${NOA_LIBRARY_PROJECT}_${NOA_LIBRARY_NAME}\")\n    set(ALIAS_NAME \"${NOA_LIBRARY_PROJECT}::${NOA_LIBRARY_NAME}\")\n  endif()\n\n  if(NOA_LIBRARY_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${NOA_LIBRARY_VARIANT}\")\n    set(ALIAS_NAME \"${ALIAS_NAME}::${NOA_LIBRARY_VARIANT}\")\n  endif()\n\n  if(NOA_LIBRARY_SOURCES)\n    add_library(${TARGET_NAME}\n      ${PUBLIC_HEADER} ${ABSOLUTE_PRIVATE_HEADERS} ${NOA_LIBRARY_SOURCES})\n    noa_add_default_options(PRIVATE ${TARGET_NAME})\n  else()\n    add_library(${TARGET_NAME} INTERFACE\n      ${PUBLIC_HEADER} ${ABSOLUTE_PRIVATE_HEADERS})\n    noa_add_default_options(INTERFACE ${TARGET_NAME})\n  endif()\n\n  add_library(${ALIAS_NAME} ALIAS ${TARGET_NAME})\n\n  if(NOT NOA_LIBRARY_VARIANT)\n    set(include_dir \"${CMAKE_CURRENT_SOURCE_DIR}/include\")\n  else()\n    set(include_dir \"${CMAKE_CURRENT_SOURCE_DIR}/../include\")\n  endif()\n  if(NOA_LIBRARY_SOURCES)\n    target_include_directories(${TARGET_NAME} PUBLIC\n      \"$<BUILD_INTERFACE:${include_dir}>\"\n      \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n  else()\n    target_include_directories(${TARGET_NAME} INTERFACE\n      \"$<BUILD_INTERFACE:${include_dir}>\"\n      \"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\")\n  endif()\n\n  if(NOA_LIBRARY_VARIANT)\n    set(export_name \"${NOA_LIBRARY_PROJECT}::${NOA_LIBRARY_NAME}::${NOA_LIBRARY_VARIANT}\")\n  else()\n    set(export_name \"${NOA_LIBRARY_PROJECT}::${NOA_LIBRARY_NAME}\")\n  endif()\n\n  if(NOA_LIBRARY_SOURCES)\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        OUTPUT_NAME ${TARGET_NAME}\n        PUBLIC_HEADER \"${PUBLIC_HEADER}\"\n        PRIVATE_HEADER \"${ABSOLUTE_PRIVATE_HEADERS}\"\n        EXPORT_NAME \"${export_name}\"\n        FOLDER \"${NOA_LIBRARY_FOLDER}\")\n  else()\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        OUTPUT_NAME ${TARGET_NAME}\n        PUBLIC_HEADER \"${PUBLIC_HEADER}\"\n        PRIVATE_HEADER \"${ABSOLUTE_PRIVATE_HEADERS}\"\n        EXPORT_NAME \"${export_name}\"\n        FOLDER \"${NOA_LIBRARY_FOLDER}\")\n  endif()\n\n  if(NOA_LIBRARY_SOURCES)\n    include(GenerateExportHeader)\n    generate_export_header(${TARGET_NAME}\n      EXPORT_FILE_NAME ${EXPORT_HEADER_PATH})\n    set_target_properties(${TARGET_NAME}\n      PROPERTIES\n        SOVERSION \"${PROJECT_VERSION_MAJOR}\"\n        VERSION \"${PROJECT_VERSION}\")\n\n    # To find the generated files\n    target_include_directories(${TARGET_NAME}\n      PUBLIC \"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>\")\n  endif()\nendfunction()\n\nfunction(noa_library_install)\n  cmake_parse_arguments(NOA_LIBRARY \"\" \"NAMESPACE;PROJECT;NAME;VARIANT\" \"\" ${ARGN})\n\n  if(NOT NOA_LIBRARY_PROJECT)\n    message(FATAL_ERROR \"You must pass the project name using the PROJECT option\")\n  endif()\n  if(NOT NOA_LIBRARY_NAME)\n    message(FATAL_ERROR \"You must pass the library name using the NAME option\")\n  endif()\n\n  if(NOA_LIBRARY_NAMESPACE)\n    set(COMPONENT_NAME \"${NOA_LIBRARY_NAMESPACE}_${NOA_LIBRARY_PROJECT}\")\n    set(TARGET_NAME \"${NOA_LIBRARY_NAMESPACE}_${NOA_LIBRARY_PROJECT}_${NOA_LIBRARY_NAME}\")\n    set(INCLUDE_PATH \"${CMAKE_INSTALL_INCLUDEDIR}/${NOA_LIBRARY_NAMESPACE}/${NOA_LIBRARY_PROJECT}\")\n    set(NAMESPACE_PREFIX \"${NOA_LIBRARY_NAMESPACE}::\")\n  else()\n    set(COMPONENT_NAME \"${NOA_LIBRARY_PROJECT}\")\n    set(TARGET_NAME \"${NOA_LIBRARY_PROJECT}_${NOA_LIBRARY_NAME}\")\n    set(INCLUDE_PATH \"${CMAKE_INSTALL_INCLUDEDIR}/${NOA_LIBRARY_PROJECT}\")\n    set(NAMESPACE_PREFIX \"\")\n  endif()\n\n  if(NOA_LIBRARY_VARIANT)\n    set(TARGET_NAME \"${TARGET_NAME}_${NOA_LIBRARY_VARIANT}\")\n  endif()\n\n  include(GNUInstallDirs)\n  install(TARGETS ${TARGET_NAME}\n    EXPORT ${TARGET_NAME}\n    PUBLIC_HEADER DESTINATION \"${INCLUDE_PATH}\"\n      COMPONENT ${COMPONENT_NAME}_dev\n    PRIVATE_HEADER DESTINATION \"${INCLUDE_PATH}\"\n      COMPONENT ${COMPONENT_NAME}_dev\n    RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n      COMPONENT ${COMPONENT_NAME}\n    LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n      COMPONENT ${COMPONENT_NAME}\n      NAMELINK_COMPONENT ${COMPONENT_NAME}_dev\n    ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n    COMPONENT ${COMPONENT_NAME}_dev)\n  install(EXPORT ${TARGET_NAME}\n    DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${NOA_LIBRARY_PROJECT}\"\n    NAMESPACE ${NAMESPACE_PREFIX}\n    COMPONENT ${COMPONENT_NAME}_dev)\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/targets/shellcheck.cmake",
    "content": "function(noa_target_shellcheck)\n  cmake_parse_arguments(NOA_TARGET_SHELLCHECK \"REQUIRED\" \"\" \"SOURCES\" ${ARGN})\n\n  if(NOA_TARGET_SHELLCHECK_REQUIRED)\n    find_program(SHELLCHECK_BIN NAMES shellcheck REQUIRED)\n  else()\n    find_program(SHELLCHECK_BIN NAMES shellcheck)\n  endif()\n\n  # This covers the empty list too\n  if(NOT NOA_TARGET_SHELLCHECK_SOURCES)\n    message(FATAL_ERROR \"You must pass file globs to lint in the SOURCES option\")\n  endif()\n  file(GLOB_RECURSE NOA_TARGET_SHELLCHECK_FILES\n    ${NOA_TARGET_SHELLCHECK_SOURCES})\n\n  if(SHELLCHECK_BIN)\n    add_custom_target(shellcheck\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${SHELLCHECK_BIN}\" ${NOA_TARGET_SHELLCHECK_FILES}\n      COMMENT \"Analyzing sources using ShellCheck\")\n  else()\n    add_custom_target(shellcheck\n      WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n      VERBATIM\n      COMMAND \"${CMAKE_COMMAND}\" -E echo \"Could not locate ShellCheck\"\n      COMMAND \"${CMAKE_COMMAND}\" -E false)\n  endif()\n\n  set_target_properties(shellcheck PROPERTIES FOLDER \"Linting\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/cmake/noa/variables.cmake",
    "content": "# Get the list of languages defined in the project\nget_property(NOA_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)\n\n# Compiler detection (C++)\n# TODO: Detect compilers on programming languages other than C++\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"AppleClang\")\n  set(NOA_COMPILER_LLVM ON)\nelseif(CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")\n  set(NOA_COMPILER_GCC ON)\nelseif(MSVC)\n  set(NOA_COMPILER_MSVC ON)\nendif()\n"
  },
  {
    "path": "vendor/noa/cmake/noa.cmake",
    "content": "set(NOA_DIRECTORY \"${CMAKE_CURRENT_LIST_DIR}/noa\")\ninclude(\"${NOA_DIRECTORY}/shim.cmake\")\ninclude(\"${NOA_DIRECTORY}/variables.cmake\")\ninclude(\"${NOA_DIRECTORY}/defaults.cmake\")\ninclude(\"${NOA_DIRECTORY}/compiler/sanitizer.cmake\")\ninclude(\"${NOA_DIRECTORY}/compiler/options.cmake\")\ninclude(\"${NOA_DIRECTORY}/options/enum.cmake\")\ninclude(\"${NOA_DIRECTORY}/commands/copy-file.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/library.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/executable.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/clang-format.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/clang-tidy.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/shellcheck.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/doxygen.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/googletest.cmake\")\ninclude(\"${NOA_DIRECTORY}/targets/googlebenchmark.cmake\")\n"
  },
  {
    "path": "vendor/noa/config.cmake.in",
    "content": "@PACKAGE_INIT@\n\n# Support both casing styles\nlist(APPEND NOA_COMPONENTS ${Noa_FIND_COMPONENTS})\nlist(APPEND NOA_COMPONENTS ${noa_FIND_COMPONENTS})\nif(NOT NOA_COMPONENTS)\n  list(APPEND NOA_COMPONENTS hash)\n  list(APPEND NOA_COMPONENTS flat_map)\n  list(APPEND NOA_COMPONENTS regex)\nendif()\n\ninclude(CMakeFindDependencyMacro)\n\nforeach(component ${NOA_COMPONENTS})\n  if(component STREQUAL \"hash\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_noa_hash.cmake\")\n  elseif(component STREQUAL \"flat_map\")\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_noa_flat_map.cmake\")\n  elseif(component STREQUAL \"regex\")\n    find_dependency(BoostRegex)\n    include(\"${CMAKE_CURRENT_LIST_DIR}/sourcemeta_noa_regex.cmake\")\n  else()\n    message(FATAL_ERROR \"Unknown Noa component: ${component}\")\n  endif()\nendforeach()\n\ncheck_required_components(\"@PROJECT_NAME@\")\n"
  },
  {
    "path": "vendor/noa/src/flat_map/CMakeLists.txt",
    "content": "noa_library(NAMESPACE sourcemeta PROJECT noa NAME flat_map FOLDER \"Noa/Flat Map\")\n\nif(NOA_INSTALL)\n  noa_library_install(NAMESPACE sourcemeta PROJECT noa NAME flat_map)\nendif()\n"
  },
  {
    "path": "vendor/noa/src/flat_map/include/sourcemeta/noa/flat_map.h",
    "content": "#ifndef SOURCEMETA_NOA_FLAT_MAP_H_\n#define SOURCEMETA_NOA_FLAT_MAP_H_\n\n#include <algorithm>        // std::swap\n#include <cassert>          // assert\n#include <initializer_list> // std::initializer_list\n#include <iterator>         // std::advance\n#include <utility>          // std::pair, std::move\n#include <vector>           // std::vector\n\n/// @defgroup flat_map Flat Map\n\nnamespace sourcemeta::noa {\n\n// TODO: Allow passing custom allocators\n/// @ingroup flat_map\ntemplate <typename Key, typename Value, typename Hash> class FlatMap {\npublic:\n  FlatMap() = default;\n\n  using key_type = Key;\n  using mapped_type = Value;\n  using hash_type = typename Hash::hash_type;\n  using value_type = std::pair<key_type, mapped_type>;\n\n  struct Entry {\n    key_type first;\n    mapped_type second;\n    hash_type hash;\n  };\n\n  using underlying_type = std::vector<Entry>;\n  using size_type = typename underlying_type::size_type;\n  using difference_type = typename underlying_type::difference_type;\n  using allocator_type = typename underlying_type::allocator_type;\n  using reference = typename underlying_type::reference;\n  using const_reference = typename underlying_type::const_reference;\n  using pointer = typename underlying_type::pointer;\n  using const_pointer = typename underlying_type::const_pointer;\n  using const_iterator = typename underlying_type::const_iterator;\n\n  FlatMap(std::initializer_list<value_type> entries) {\n    this->data.reserve(entries.size());\n    for (auto &&entry : entries) {\n      this->assign(std::move(entry.first), std::move(entry.second));\n    }\n  }\n\n  auto begin() const noexcept -> const_iterator { return this->data.begin(); }\n  auto end() const noexcept -> const_iterator { return this->data.end(); }\n  auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); }\n  auto cend() const noexcept -> const_iterator { return this->data.cend(); }\n\n  inline auto hash(const key_type &key) const noexcept -> hash_type {\n    return this->hasher(key);\n  }\n\n  auto assign(key_type &&key, mapped_type &&value) -> hash_type {\n    const auto key_hash{this->hash(key)};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          entry.second = std::move(value);\n          return key_hash;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          entry.second = std::move(value);\n          return key_hash;\n        }\n      }\n    }\n\n    this->data.push_back({std::move(key), std::move(value), key_hash});\n    return key_hash;\n  }\n\n  auto assign(const key_type &key, const mapped_type &value) -> hash_type {\n    const auto key_hash{this->hash(key)};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          entry.second = value;\n          return key_hash;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          entry.second = value;\n          return key_hash;\n        }\n      }\n    }\n\n    this->data.push_back({key, value, key_hash});\n    return key_hash;\n  }\n\n  // As a performance optimisation if the hash is known\n  inline auto find(const key_type &key, const hash_type key_hash) const\n      -> const_iterator {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (size_type index = 0; index < this->data.size(); index++) {\n        if (this->data[index].hash == key_hash) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    } else {\n      for (size_type index = 0; index < this->data.size(); index++) {\n        if (this->data[index].hash == key_hash &&\n            this->data[index].first == key) {\n          auto iterator{this->cbegin()};\n          std::advance(iterator, index);\n          return iterator;\n        }\n      }\n    }\n\n    return this->cend();\n  }\n\n  // As a performance optimisation if the hash is known\n  auto contains(const key_type &key, const hash_type key_hash) const -> bool {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (const auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          return true;\n        }\n      }\n    } else {\n      for (const auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  // As a performance optimisation if the hash is known\n\n  inline auto at(const key_type &key, const hash_type key_hash) const\n      -> const mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (const auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (const auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n// See https://en.cppreference.com/w/cpp/utility/unreachable\n#if defined(_MSC_VER) && !defined(__clang__)\n    __assume(false);\n#else\n    __builtin_unreachable();\n#endif\n  }\n\n  inline auto at(const key_type &key, const hash_type key_hash)\n      -> mapped_type & {\n    assert(this->hash(key) == key_hash);\n\n    // Move the perfect hash condition out of the loop for extra performance\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          return entry.second;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          return entry.second;\n        }\n      }\n    }\n\n// See https://en.cppreference.com/w/cpp/utility/unreachable\n#if defined(_MSC_VER) && !defined(__clang__)\n    __assume(false);\n#else\n    __builtin_unreachable();\n#endif\n  }\n\n  auto erase(const key_type &key, const hash_type key_hash) -> size_type {\n    const auto current_size{this->size()};\n\n    if (this->hasher.is_perfect(key_hash)) {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash) {\n          std::swap(entry, this->data.back());\n          this->data.pop_back();\n          return current_size - 1;\n        }\n      }\n    } else {\n      for (auto &entry : this->data) {\n        if (entry.hash == key_hash && entry.first == key) {\n          std::swap(entry, this->data.back());\n          this->data.pop_back();\n          return current_size - 1;\n        }\n      }\n    }\n\n    return current_size;\n  }\n\n  inline auto erase(const key_type &key) -> size_type {\n    return this->erase(key, this->hash(key));\n  }\n\n  inline auto size() const noexcept -> size_type { return this->data.size(); }\n\n  inline auto empty() const noexcept -> bool { return this->data.empty(); }\n\n  inline auto clear() noexcept -> void { this->data.clear(); }\n\n  auto operator!=(const FlatMap &other) const -> bool = default;\n\n  auto operator==(const FlatMap &other) const -> bool {\n    if (this->size() != other.size()) {\n      return false;\n    }\n\n    for (const auto &entry : this->data) {\n      const auto iterator{other.find(entry.first, entry.hash)};\n      if (iterator == other.cend()) {\n        return false;\n      } else if (iterator->second != entry.second) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\nprivate:\n  underlying_type data;\n  Hash hasher;\n};\n\n} // namespace sourcemeta::noa\n\n#endif\n"
  },
  {
    "path": "vendor/noa/src/hash/CMakeLists.txt",
    "content": "noa_library(NAMESPACE sourcemeta PROJECT noa NAME hash FOLDER \"Noa/Hash\")\n\nif(NOA_INSTALL)\n  noa_library_install(NAMESPACE sourcemeta PROJECT noa NAME hash)\nendif()\n"
  },
  {
    "path": "vendor/noa/src/hash/include/sourcemeta/noa/hash.h",
    "content": "#ifndef SOURCEMETA_NOA_HASH_H_\n#define SOURCEMETA_NOA_HASH_H_\n\n/// @defgroup hash Hash\n\nnamespace sourcemeta::noa {\n\n// @ingroup hash\ntemplate <typename T> struct StandardHash {\n  using hash_type = std::size_t;\n  inline auto operator()(const T &value) const -> hash_type {\n    return this->hasher(value);\n  }\n\n  inline auto is_perfect(const hash_type &) const noexcept -> bool {\n    return false;\n  }\n\nprivate:\n  std::hash<T> hasher;\n};\n\n} // namespace sourcemeta::noa\n\n#endif\n"
  },
  {
    "path": "vendor/noa/src/regex/CMakeLists.txt",
    "content": "noa_library(NAMESPACE sourcemeta PROJECT noa NAME regex\n  FOLDER \"Noa/Regex\")\n\nif(NOA_INSTALL)\n  noa_library_install(NAMESPACE sourcemeta PROJECT noa NAME regex)\nendif()\n\ntarget_link_libraries(sourcemeta_noa_regex INTERFACE Boost::regex)\n"
  },
  {
    "path": "vendor/noa/src/regex/include/sourcemeta/noa/regex.h",
    "content": "#ifndef SOURCEMETA_NOA_REGEX_H_\n#define SOURCEMETA_NOA_REGEX_H_\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdocumentation\"\n#pragma clang diagnostic ignored \"-Wsign-conversion\"\n#pragma clang diagnostic ignored \"-Wshorten-64-to-32\"\n#elif defined(__GNUC__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wsign-conversion\"\n#pragma GCC diagnostic ignored \"-Wconversion\"\n#endif\n#include <boost/regex.hpp>\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#elif defined(__GNUC__)\n#pragma GCC diagnostic pop\n#endif\n\n#include <cassert>  // assert\n#include <cstdint>  // std::uint8_t, std::uint64_t\n#include <optional> // std::optional\n#include <regex>    // std::regex\n#include <string>   // std::stoull\n#include <utility>  // std::pair\n#include <variant>  // std::variant\n\n/// @defgroup regex Regex\n\nnamespace sourcemeta::noa {\n\n/// @ingroup regex\ntemplate <typename T> using RegexTypeBoost = boost::basic_regex<T>;\n\n/// @ingroup regex\ntemplate <typename T> using RegexTypePrefix = T;\n\n/// @ingroup regex\nstruct RegexTypeNonEmpty {};\n\n/// @ingroup regex\nusing RegexTypeRange = std::pair<std::uint64_t, std::uint64_t>;\n\n/// @ingroup regex\ntemplate <typename T> using RegexTypeStd = std::basic_regex<T>;\n\n/// @ingroup regex\nstruct RegexTypeNoop {};\n\n/// @ingroup regex\ntemplate <typename T>\nusing Regex =\n    std::variant<RegexTypeBoost<typename T::value_type>, RegexTypePrefix<T>,\n                 RegexTypeNonEmpty, RegexTypeRange,\n                 RegexTypeStd<typename T::value_type>, RegexTypeNoop>;\n#if !defined(DOXYGEN)\n// For fast internal dispatching. It must stay in sync with the variant above\nenum class RegexIndex : std::uint8_t {\n  Boost = 0,\n  Prefix,\n  NonEmpty,\n  Range,\n  Std,\n  Noop\n};\n#endif\n\n/// @ingroup regex\n///\n/// Compile a regular expression from a string. If the regular expression is\n/// invalid, no value is returned. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/noa/regex.h>\n/// #include <cassert>\n///\n/// const sourcemeta::noa::Regex regex{\n///   sourcemeta::noa::to_regex(\"^foo\")};\n/// assert(regex.has_value());\n/// ```\ntemplate <typename T>\nauto to_regex(const T &pattern) -> std::optional<Regex<T>> {\n  if (pattern == \".*\" || pattern == \"^.*$\" || pattern == \"^(.*)$\" ||\n      pattern == \"(.*)\" || pattern == \"[\\\\s\\\\S]*\" || pattern == \"^[\\\\s\\\\S]*$\") {\n    return RegexTypeNoop{};\n  } else if (pattern == \".+\" || pattern == \"^.+$\" || pattern == \"^(.+)$\" ||\n             pattern == \".\") {\n    return RegexTypeNonEmpty{};\n  }\n\n  const std::regex PREFIX_REGEX{R\"(^\\^([a-zA-Z0-9-_/@]+)(\\.\\*)?)\"};\n  std::smatch matches_prefix;\n  if (std::regex_match(pattern, matches_prefix, PREFIX_REGEX)) {\n    return RegexTypePrefix<T>{matches_prefix[1].str()};\n  }\n\n  const std::regex RANGE_REGEX{R\"(^\\^\\.\\{(\\d+),(\\d+)\\}\\$$)\"};\n  std::smatch matches_range;\n  if (std::regex_match(pattern, matches_range, RANGE_REGEX)) {\n    const std::uint64_t minimum{std::stoull(matches_range[1].str())};\n    const std::uint64_t maximum{std::stoull(matches_range[2].str())};\n    assert(minimum <= maximum);\n    return RegexTypeRange{minimum, maximum};\n  }\n\n  RegexTypeBoost<typename T::value_type> result{\n      pattern,\n      boost::regex::no_except |\n          // See https://en.cppreference.com/w/cpp/regex/basic_regex/constants\n          boost::regex::ECMAScript |\n\n          // When performing matches, all marked sub-expressions (expr) are\n          // treated as non-marking sub-expressions (?:expr)\n          boost::regex::nosubs |\n\n          // Instructs the regular expression engine to make matching faster,\n          // with the potential cost of making construction slower\n          boost::regex::optimize};\n\n  // Returns zero if the expression contains a valid regular expression\n  // See\n  // https://www.boost.org/doc/libs/1_82_0/libs/regex/doc/html/boost_regex/ref/basic_regex.html\n  if (result.status() == 0) {\n    return result;\n  }\n\n  try {\n    // Boost seems to sometimes be overly strict, so we still default to\n    // the standard implementation\n    return RegexTypeStd<typename T::value_type>{\n        pattern,\n        // See https://en.cppreference.com/w/cpp/regex/basic_regex/constants\n        std::regex::ECMAScript |\n\n            // When performing matches, all marked sub-expressions (expr) are\n            // treated as non-marking sub-expressions (?:expr)\n            std::regex::nosubs |\n\n            // Instructs the regular expression engine to make matching\n            // faster, with the potential cost of making construction slower\n            std::regex::optimize};\n  } catch (const std::regex_error &) {\n    return std::nullopt;\n  }\n}\n\n/// @ingroup regex\n///\n/// Validate a string against a regular expression. For example:\n///\n/// ```cpp\n/// #include <sourcemeta/noa/regex.h>\n/// #include <cassert>\n///\n/// const sourcemeta::noa::Regex regex{\n///   sourcemeta::noa::to_regex(\"^foo\")};\n/// assert(regex.has_value());\n/// assert(sourcemeta::noa::matches(regex.value(), \"foo bar\"));\n/// ```\ntemplate <typename T>\nauto matches(const Regex<T> &regex, const T &value) -> bool {\n  switch (static_cast<RegexIndex>(regex.index())) {\n    case RegexIndex::Boost:\n      return boost::regex_search(\n          value, *std::get_if<RegexTypeBoost<typename T::value_type>>(&regex));\n    case RegexIndex::Prefix:\n      return value.starts_with(*std::get_if<RegexTypePrefix<T>>(&regex));\n    case RegexIndex::NonEmpty:\n      return !value.empty();\n    case RegexIndex::Range:\n      return value.size() >= std::get_if<RegexTypeRange>(&regex)->first &&\n             value.size() <= std::get_if<RegexTypeRange>(&regex)->second;\n    case RegexIndex::Std:\n      return std::regex_search(\n          value, *std::get_if<RegexTypeStd<typename T::value_type>>(&regex));\n    case RegexIndex::Noop:\n      return true;\n  }\n\n    // See https://en.cppreference.com/w/cpp/utility/unreachable\n#if defined(_MSC_VER) && !defined(__clang__)\n  __assume(false);\n#else\n  __builtin_unreachable();\n#endif\n}\n\n} // namespace sourcemeta::noa\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/cregex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org/libs/regex for most recent version.\n  *   FILE         cregex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares POSIX API functions\n  *                + boost::RegEx high level wrapper.\n  */\n\n#ifndef BOOST_RE_CREGEX_HPP\n#define BOOST_RE_CREGEX_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/cregex.hpp>\n#else\n#include <boost/regex/v5/cregex.hpp>\n#endif\n\n#endif /* include guard */\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/concepts.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         concepts.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression concepts.\n  */\n\n#ifndef BOOST_REGEX_CONCEPTS_HPP_INCLUDED\n#define BOOST_REGEX_CONCEPTS_HPP_INCLUDED\n\n#include <boost/concept_archetype.hpp>\n#include <boost/concept_check.hpp>\n#include <boost/type_traits/is_enum.hpp>\n#include <boost/type_traits/is_base_and_derived.hpp>\n#include <boost/static_assert.hpp>\n#ifndef BOOST_TEST_TR1_REGEX\n#include <boost/regex.hpp>\n#endif\n#include <bitset>\n#include <vector>\n#include <ostream>\n\n#ifdef BOOST_REGEX_CXX03\n#define RW_NS boost\n#else\n#define RW_NS std\n#endif\n\nnamespace boost{\n\n//\n// bitmask_archetype:\n// this can be either an integer type, an enum, or a std::bitset,\n// we use the latter as the architype as it offers the \"strictest\"\n// of the possible interfaces:\n//\ntypedef std::bitset<512> bitmask_archetype;\n//\n// char_architype:\n// A strict model for the character type interface.\n//\nstruct char_architype\n{\n   // default constructable:\n   char_architype();\n   // copy constructable / assignable:\n   char_architype(const char_architype&);\n   char_architype& operator=(const char_architype&);\n   // constructable from an integral value:\n   char_architype(unsigned long val);\n   // comparable:\n   bool operator==(const char_architype&)const;\n   bool operator!=(const char_architype&)const;\n   bool operator<(const char_architype&)const;\n   bool operator<=(const char_architype&)const;\n   bool operator>=(const char_architype&)const;\n   bool operator>(const char_architype&)const;\n   // conversion to integral type:\n   operator long()const;\n};\ninline long hash_value(char_architype val)\n{  return val;  }\n//\n// char_architype can not be used with basic_string:\n//\n} // namespace boost\nnamespace std{\n   template<> struct char_traits<boost::char_architype>\n   {\n      // The intent is that this template is not instantiated,\n      // but this typedef gives us a chance of compilation in\n      // case it is:\n      typedef boost::char_architype char_type;\n   };\n}\n//\n// Allocator architype:\n//\ntemplate <class T>\nclass allocator_architype\n{\npublic:\n   typedef T* pointer;\n   typedef const T* const_pointer;\n   typedef T& reference;\n   typedef const T& const_reference;\n   typedef T value_type;\n   typedef unsigned size_type;\n   typedef int difference_type;\n\n   template <class U>\n   struct rebind\n   {\n      typedef allocator_architype<U> other;\n   };\n\n   pointer address(reference r){ return &r; }\n   const_pointer address(const_reference r) { return &r; }\n   pointer allocate(size_type n) { return static_cast<pointer>(std::malloc(n)); }\n   pointer allocate(size_type n, pointer) { return static_cast<pointer>(std::malloc(n)); }\n   void deallocate(pointer p, size_type) { std::free(p); }\n   size_type max_size()const { return UINT_MAX; }\n\n   allocator_architype(){}\n   allocator_architype(const allocator_architype&){}\n\n   template <class Other>\n   allocator_architype(const allocator_architype<Other>&){}\n\n   void construct(pointer p, const_reference r) { new (p)T(r); }\n   void destroy(pointer p) { p->~T(); }\n};\n\ntemplate <class T>\nbool operator == (const allocator_architype<T>&, const allocator_architype<T>&) {return true; }\ntemplate <class T>\nbool operator != (const allocator_architype<T>&, const allocator_architype<T>&) { return false; }\n\nnamespace boost{\n//\n// regex_traits_architype:\n// A strict interpretation of the regular expression traits class requirements.\n//\ntemplate <class charT>\nstruct regex_traits_architype\n{\npublic:\n   regex_traits_architype(){}\n   typedef charT char_type;\n   // typedef std::size_t size_type;\n   typedef std::vector<char_type> string_type;\n   typedef copy_constructible_archetype<assignable_archetype<> > locale_type;\n   typedef bitmask_archetype char_class_type;\n\n   static std::size_t length(const char_type* ) { return 0; }\n\n   charT translate(charT ) const { return charT(); }\n   charT translate_nocase(charT ) const { return static_object<charT>::get(); }\n\n   template <class ForwardIterator>\n   string_type transform(ForwardIterator , ForwardIterator ) const\n   { return static_object<string_type>::get(); }\n   template <class ForwardIterator>\n   string_type transform_primary(ForwardIterator , ForwardIterator ) const\n   { return static_object<string_type>::get(); }\n\n   template <class ForwardIterator>\n   char_class_type lookup_classname(ForwardIterator , ForwardIterator ) const\n   { return static_object<char_class_type>::get(); }\n   template <class ForwardIterator>\n   string_type lookup_collatename(ForwardIterator , ForwardIterator ) const\n   { return static_object<string_type>::get(); }\n\n   bool isctype(charT, char_class_type) const\n   { return false; }\n   int value(charT, int) const\n   { return 0; }\n\n   locale_type imbue(locale_type l)\n   { return l; }\n   locale_type getloc()const\n   { return static_object<locale_type>::get(); }\n\nprivate:\n   // this type is not copyable:\n   regex_traits_architype(const regex_traits_architype&){}\n   regex_traits_architype& operator=(const regex_traits_architype&){ return *this; }\n};\n\n//\n// alter this to std::tr1, to test a std implementation:\n//\n#ifndef BOOST_TEST_TR1_REGEX\nnamespace global_regex_namespace = ::boost;\n#else\nnamespace global_regex_namespace = ::std::tr1;\n#endif\n\ntemplate <class Bitmask>\nstruct BitmaskConcept\n{\n   void constraints() \n   {\n      function_requires<CopyConstructibleConcept<Bitmask> >();\n      function_requires<AssignableConcept<Bitmask> >();\n\n      m_mask1 = m_mask2 | m_mask3;\n      m_mask1 = m_mask2 & m_mask3;\n      m_mask1 = m_mask2 ^ m_mask3;\n\n      m_mask1 = ~m_mask2;\n\n      m_mask1 |= m_mask2;\n      m_mask1 &= m_mask2;\n      m_mask1 ^= m_mask2;\n   }\n   Bitmask m_mask1, m_mask2, m_mask3;\n};\n\ntemplate <class traits>\nstruct RegexTraitsConcept\n{\n   RegexTraitsConcept();\n   // required typedefs:\n   typedef typename traits::char_type char_type;\n   // typedef typename traits::size_type size_type;\n   typedef typename traits::string_type string_type;\n   typedef typename traits::locale_type locale_type;\n   typedef typename traits::char_class_type char_class_type;\n\n   void constraints() \n   {\n      //function_requires<UnsignedIntegerConcept<size_type> >();\n      function_requires<RandomAccessContainerConcept<string_type> >();\n      function_requires<DefaultConstructibleConcept<locale_type> >();\n      function_requires<CopyConstructibleConcept<locale_type> >();\n      function_requires<AssignableConcept<locale_type> >();\n      function_requires<BitmaskConcept<char_class_type> >();\n\n      std::size_t n = traits::length(m_pointer);\n      ignore_unused_variable_warning(n);\n\n      char_type c = m_ctraits.translate(m_char);\n      ignore_unused_variable_warning(c);\n      c = m_ctraits.translate_nocase(m_char);\n      \n      //string_type::foobar bar;\n      string_type s1 = m_ctraits.transform(m_pointer, m_pointer);\n      ignore_unused_variable_warning(s1);\n\n      string_type s2 = m_ctraits.transform_primary(m_pointer, m_pointer);\n      ignore_unused_variable_warning(s2);\n\n      char_class_type cc = m_ctraits.lookup_classname(m_pointer, m_pointer);\n      ignore_unused_variable_warning(cc);\n\n      string_type s3 = m_ctraits.lookup_collatename(m_pointer, m_pointer);\n      ignore_unused_variable_warning(s3);\n\n      bool b = m_ctraits.isctype(m_char, cc);\n      ignore_unused_variable_warning(b);\n\n      int v = m_ctraits.value(m_char, 16);\n      ignore_unused_variable_warning(v);\n\n      locale_type l(m_ctraits.getloc());\n      m_traits.imbue(l);\n      ignore_unused_variable_warning(l);\n   }\n   traits m_traits;\n   const traits m_ctraits;\n   const char_type* m_pointer;\n   char_type m_char;\nprivate:\n   RegexTraitsConcept& operator=(RegexTraitsConcept&);\n};\n\n//\n// helper class to compute what traits class a regular expression type is using:\n//\ntemplate <class Regex>\nstruct regex_traits_computer;\n\ntemplate <class charT, class traits>\nstruct regex_traits_computer< global_regex_namespace::basic_regex<charT, traits> >\n{\n   typedef traits type;\n};\n\n//\n// BaseRegexConcept does not test anything dependent on basic_string,\n// in case our charT does not have an associated char_traits:\n//\ntemplate <class Regex>\nstruct BaseRegexConcept\n{\n   typedef typename Regex::value_type value_type;\n   //typedef typename Regex::size_type size_type;\n   typedef typename Regex::flag_type flag_type;\n   typedef typename Regex::locale_type locale_type;\n   typedef input_iterator_archetype<value_type> input_iterator_type;\n\n   // derived test types:\n   typedef const value_type* pointer_type;\n   typedef bidirectional_iterator_archetype<value_type> BidiIterator;\n   typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;\n   typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;\n   typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;\n   typedef output_iterator_archetype<value_type> OutIterator;\n   typedef typename regex_traits_computer<Regex>::type traits_type;\n   typedef global_regex_namespace::regex_iterator<BidiIterator, value_type, traits_type> regex_iterator_type;\n   typedef global_regex_namespace::regex_token_iterator<BidiIterator, value_type, traits_type> regex_token_iterator_type;\n\n   void global_constraints()\n   {\n      //\n      // test non-template components:\n      //\n      function_requires<BitmaskConcept<global_regex_namespace::regex_constants::syntax_option_type> >();\n      global_regex_namespace::regex_constants::syntax_option_type opts\n         = global_regex_namespace::regex_constants::icase\n         | global_regex_namespace::regex_constants::nosubs\n         | global_regex_namespace::regex_constants::optimize\n         | global_regex_namespace::regex_constants::collate\n         | global_regex_namespace::regex_constants::ECMAScript\n         | global_regex_namespace::regex_constants::basic\n         | global_regex_namespace::regex_constants::extended\n         | global_regex_namespace::regex_constants::awk\n         | global_regex_namespace::regex_constants::grep\n         | global_regex_namespace::regex_constants::egrep;\n      ignore_unused_variable_warning(opts);\n\n      function_requires<BitmaskConcept<global_regex_namespace::regex_constants::match_flag_type> >();\n      global_regex_namespace::regex_constants::match_flag_type mopts\n         = global_regex_namespace::regex_constants::match_default\n         | global_regex_namespace::regex_constants::match_not_bol\n         | global_regex_namespace::regex_constants::match_not_eol\n         | global_regex_namespace::regex_constants::match_not_bow\n         | global_regex_namespace::regex_constants::match_not_eow\n         | global_regex_namespace::regex_constants::match_any\n         | global_regex_namespace::regex_constants::match_not_null\n         | global_regex_namespace::regex_constants::match_continuous\n         | global_regex_namespace::regex_constants::match_prev_avail\n         | global_regex_namespace::regex_constants::format_default\n         | global_regex_namespace::regex_constants::format_sed\n         | global_regex_namespace::regex_constants::format_no_copy\n         | global_regex_namespace::regex_constants::format_first_only;\n      ignore_unused_variable_warning(mopts);\n\n      BOOST_STATIC_ASSERT((::boost::is_enum<global_regex_namespace::regex_constants::error_type>::value));\n      global_regex_namespace::regex_constants::error_type e1 = global_regex_namespace::regex_constants::error_collate;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_ctype;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_escape;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_backref;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_brack;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_paren;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_brace;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_badbrace;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_range;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_space;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_badrepeat;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_complexity;\n      ignore_unused_variable_warning(e1);\n      e1 = global_regex_namespace::regex_constants::error_stack;\n      ignore_unused_variable_warning(e1);\n\n      BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::runtime_error, global_regex_namespace::regex_error>::value  ));\n      const global_regex_namespace::regex_error except(e1);\n      e1 = except.code();\n\n      typedef typename Regex::value_type regex_value_type;\n      function_requires< RegexTraitsConcept<global_regex_namespace::regex_traits<char> > >();\n      function_requires< BaseRegexConcept<global_regex_namespace::basic_regex<char> > >();\n   }\n   void constraints() \n   {\n      global_constraints();\n\n      BOOST_STATIC_ASSERT((::boost::is_same< flag_type, global_regex_namespace::regex_constants::syntax_option_type>::value));\n      flag_type opts\n         = Regex::icase\n         | Regex::nosubs\n         | Regex::optimize\n         | Regex::collate\n         | Regex::ECMAScript\n         | Regex::basic\n         | Regex::extended\n         | Regex::awk\n         | Regex::grep\n         | Regex::egrep;\n      ignore_unused_variable_warning(opts);\n\n      function_requires<DefaultConstructibleConcept<Regex> >();\n      function_requires<CopyConstructibleConcept<Regex> >();\n\n      // Regex constructors:\n      Regex e1(m_pointer);\n      ignore_unused_variable_warning(e1);\n      Regex e2(m_pointer, m_flags);\n      ignore_unused_variable_warning(e2);\n      Regex e3(m_pointer, m_size, m_flags);\n      ignore_unused_variable_warning(e3);\n      Regex e4(in1, in2);\n      ignore_unused_variable_warning(e4);\n      Regex e5(in1, in2, m_flags);\n      ignore_unused_variable_warning(e5);\n\n      // assign etc:\n      Regex e;\n      e = m_pointer;\n      e = e1;\n      e.assign(e1);\n      e.assign(m_pointer);\n      e.assign(m_pointer, m_flags);\n      e.assign(m_pointer, m_size, m_flags);\n      e.assign(in1, in2);\n      e.assign(in1, in2, m_flags);\n\n      // access:\n      const Regex ce;\n      typename Regex::size_type i = ce.mark_count();\n      ignore_unused_variable_warning(i);\n      m_flags = ce.flags();\n      e.imbue(ce.getloc());\n      e.swap(e1);\n      \n      global_regex_namespace::swap(e, e1);\n\n      // sub_match:\n      BOOST_STATIC_ASSERT((::boost::is_base_and_derived<std::pair<BidiIterator, BidiIterator>, sub_match_type>::value));\n      typedef typename sub_match_type::value_type sub_value_type;\n      typedef typename sub_match_type::difference_type sub_diff_type;\n      typedef typename sub_match_type::iterator sub_iter_type;\n      BOOST_STATIC_ASSERT((::boost::is_same<sub_value_type, value_type>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<sub_iter_type, BidiIterator>::value));\n      bool b = m_sub.matched;\n      ignore_unused_variable_warning(b);\n      BidiIterator bi = m_sub.first;\n      ignore_unused_variable_warning(bi);\n      bi = m_sub.second;\n      ignore_unused_variable_warning(bi);\n      sub_diff_type diff = m_sub.length();\n      ignore_unused_variable_warning(diff);\n      // match_results tests - some typedefs are not used, however these\n      // guarante that they exist (some compilers may warn on non-usage)\n      typedef typename match_results_type::value_type mr_value_type;\n      typedef typename match_results_type::const_reference mr_const_reference;\n      typedef typename match_results_type::reference mr_reference;\n      typedef typename match_results_type::const_iterator mr_const_iterator;\n      typedef typename match_results_type::iterator mr_iterator;\n      typedef typename match_results_type::difference_type mr_difference_type;\n      typedef typename match_results_type::size_type mr_size_type;\n      typedef typename match_results_type::allocator_type mr_allocator_type;\n      typedef typename match_results_type::char_type mr_char_type;\n      typedef typename match_results_type::string_type mr_string_type;\n\n      match_results_type m1;\n      mr_allocator_type at;\n      match_results_type m2(at);\n      match_results_type m3(m1);\n      m1 = m2;\n\n      int ival = 0;\n\n      mr_size_type mrs = m_cresults.size();\n      ignore_unused_variable_warning(mrs);\n      mrs = m_cresults.max_size();\n      ignore_unused_variable_warning(mrs);\n      b = m_cresults.empty();\n      ignore_unused_variable_warning(b);\n      mr_difference_type mrd = m_cresults.length();\n      ignore_unused_variable_warning(mrd);\n      mrd = m_cresults.length(ival);\n      ignore_unused_variable_warning(mrd);\n      mrd = m_cresults.position();\n      ignore_unused_variable_warning(mrd);\n      mrd = m_cresults.position(mrs);\n      ignore_unused_variable_warning(mrd);\n\n      mr_const_reference mrcr = m_cresults[ival];\n      ignore_unused_variable_warning(mrcr);\n      mr_const_reference mrcr2 = m_cresults.prefix();\n      ignore_unused_variable_warning(mrcr2);\n      mr_const_reference mrcr3 = m_cresults.suffix();\n      ignore_unused_variable_warning(mrcr3);\n      mr_const_iterator mrci = m_cresults.begin();\n      ignore_unused_variable_warning(mrci);\n      mrci = m_cresults.end();\n      ignore_unused_variable_warning(mrci);\n\n      (void) m_cresults.get_allocator();\n      m_results.swap(m_results);\n      global_regex_namespace::swap(m_results, m_results);\n\n      // regex_match:\n      b = global_regex_namespace::regex_match(m_in, m_in, m_results, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_in, m_in, m_results, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_in, m_in, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_in, m_in, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_pointer, m_pmatch, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_pointer, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_pointer, e, m_mft);\n      ignore_unused_variable_warning(b);\n      // regex_search:\n      b = global_regex_namespace::regex_search(m_in, m_in, m_results, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_in, m_in, m_results, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_in, m_in, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_in, m_in, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_pointer, m_pmatch, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_pointer, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_pointer, e, m_mft);\n      ignore_unused_variable_warning(b);\n\n      // regex_iterator:\n      typedef typename regex_iterator_type::regex_type rit_regex_type;\n      typedef typename regex_iterator_type::value_type rit_value_type;\n      typedef typename regex_iterator_type::difference_type rit_difference_type;\n      typedef typename regex_iterator_type::pointer rit_pointer;\n      typedef typename regex_iterator_type::reference rit_reference;\n      typedef typename regex_iterator_type::iterator_category rit_iterator_category;\n      BOOST_STATIC_ASSERT((::boost::is_same<rit_regex_type, Regex>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rit_value_type, match_results_default_type>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rit_difference_type, std::ptrdiff_t>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rit_pointer, const match_results_default_type*>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rit_reference, const match_results_default_type&>::value));\n      BOOST_STATIC_ASSERT((::boost::is_convertible<rit_iterator_category*, std::forward_iterator_tag*>::value));\n      // this takes care of most of the checks needed:\n      function_requires<ForwardIteratorConcept<regex_iterator_type> >();\n      regex_iterator_type iter1(m_in, m_in, e);\n      ignore_unused_variable_warning(iter1);\n      regex_iterator_type iter2(m_in, m_in, e, m_mft);\n      ignore_unused_variable_warning(iter2);\n\n      // regex_token_iterator:\n      typedef typename regex_token_iterator_type::regex_type rtit_regex_type;\n      typedef typename regex_token_iterator_type::value_type rtit_value_type;\n      typedef typename regex_token_iterator_type::difference_type rtit_difference_type;\n      typedef typename regex_token_iterator_type::pointer rtit_pointer;\n      typedef typename regex_token_iterator_type::reference rtit_reference;\n      typedef typename regex_token_iterator_type::iterator_category rtit_iterator_category;\n      BOOST_STATIC_ASSERT((::boost::is_same<rtit_regex_type, Regex>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rtit_value_type, sub_match_type>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rtit_difference_type, std::ptrdiff_t>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rtit_pointer, const sub_match_type*>::value));\n      BOOST_STATIC_ASSERT((::boost::is_same<rtit_reference, const sub_match_type&>::value));\n      BOOST_STATIC_ASSERT((::boost::is_convertible<rtit_iterator_category*, std::forward_iterator_tag*>::value));\n      // this takes care of most of the checks needed:\n      function_requires<ForwardIteratorConcept<regex_token_iterator_type> >();\n      regex_token_iterator_type ti1(m_in, m_in, e);\n      ignore_unused_variable_warning(ti1);\n      regex_token_iterator_type ti2(m_in, m_in, e, 0);\n      ignore_unused_variable_warning(ti2);\n      regex_token_iterator_type ti3(m_in, m_in, e, 0, m_mft);\n      ignore_unused_variable_warning(ti3);\n      std::vector<int> subs;\n      regex_token_iterator_type ti4(m_in, m_in, e, subs);\n      ignore_unused_variable_warning(ti4);\n      regex_token_iterator_type ti5(m_in, m_in, e, subs, m_mft);\n      ignore_unused_variable_warning(ti5);\n      static const int i_array[3] = { 1, 2, 3, };\n      regex_token_iterator_type ti6(m_in, m_in, e, i_array);\n      ignore_unused_variable_warning(ti6);\n      regex_token_iterator_type ti7(m_in, m_in, e, i_array, m_mft);\n      ignore_unused_variable_warning(ti7);\n   }\n\n   pointer_type m_pointer;\n   flag_type m_flags;\n   std::size_t m_size;\n   input_iterator_type in1, in2;\n   const sub_match_type m_sub;\n   const value_type m_char;\n   match_results_type m_results;\n   const match_results_type m_cresults;\n   OutIterator m_out;\n   BidiIterator m_in;\n   global_regex_namespace::regex_constants::match_flag_type m_mft;\n   global_regex_namespace::match_results<\n      pointer_type, \n      allocator_architype<global_regex_namespace::sub_match<pointer_type> > > \n      m_pmatch;\n\n   BaseRegexConcept();\n   BaseRegexConcept(const BaseRegexConcept&);\n   BaseRegexConcept& operator=(const BaseRegexConcept&);\n};\n\n//\n// RegexConcept:\n// Test every interface in the std:\n//\ntemplate <class Regex>\nstruct RegexConcept\n{\n   typedef typename Regex::value_type value_type;\n   //typedef typename Regex::size_type size_type;\n   typedef typename Regex::flag_type flag_type;\n   typedef typename Regex::locale_type locale_type;\n\n   // derived test types:\n   typedef const value_type* pointer_type;\n   typedef std::basic_string<value_type> string_type;\n   typedef boost::bidirectional_iterator_archetype<value_type> BidiIterator;\n   typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;\n   typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;\n   typedef output_iterator_archetype<value_type> OutIterator;\n\n\n   void constraints() \n   {\n      function_requires<BaseRegexConcept<Regex> >();\n      // string based construct:\n      Regex e1(m_string);\n      ignore_unused_variable_warning(e1);\n      Regex e2(m_string, m_flags);\n      ignore_unused_variable_warning(e2);\n\n      // assign etc:\n      Regex e;\n      e = m_string;\n      e.assign(m_string);\n      e.assign(m_string, m_flags);\n\n      // sub_match:\n      string_type s(m_sub);\n      ignore_unused_variable_warning(s);\n      s = m_sub.str();\n      ignore_unused_variable_warning(s);\n      int i = m_sub.compare(m_string);\n      ignore_unused_variable_warning(i);\n\n      int i2 = m_sub.compare(m_sub);\n      ignore_unused_variable_warning(i2);\n      i2 = m_sub.compare(m_pointer);\n      ignore_unused_variable_warning(i2);\n\n      bool b = m_sub == m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_sub != m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_sub > m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_sub >= m_sub;\n      ignore_unused_variable_warning(b);\n\n      b = m_sub == m_pointer;\n      ignore_unused_variable_warning(b);\n      b = m_sub != m_pointer;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_pointer;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_pointer;\n      ignore_unused_variable_warning(b);\n      b = m_sub > m_pointer;\n      ignore_unused_variable_warning(b);\n      b = m_sub >= m_pointer;\n      ignore_unused_variable_warning(b);\n\n      b = m_pointer == m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_pointer != m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_pointer <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_pointer <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_pointer > m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_pointer >= m_sub;\n      ignore_unused_variable_warning(b);\n\n      b = m_sub == m_char;\n      ignore_unused_variable_warning(b);\n      b = m_sub != m_char;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_char;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_char;\n      ignore_unused_variable_warning(b);\n      b = m_sub > m_char;\n      ignore_unused_variable_warning(b);\n      b = m_sub >= m_char;\n      ignore_unused_variable_warning(b);\n\n      b = m_char == m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_char != m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_char <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_char <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_char > m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_char >= m_sub;\n      ignore_unused_variable_warning(b);\n\n      b = m_sub == m_string;\n      ignore_unused_variable_warning(b);\n      b = m_sub != m_string;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_string;\n      ignore_unused_variable_warning(b);\n      b = m_sub <= m_string;\n      ignore_unused_variable_warning(b);\n      b = m_sub > m_string;\n      ignore_unused_variable_warning(b);\n      b = m_sub >= m_string;\n      ignore_unused_variable_warning(b);\n\n      b = m_string == m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_string != m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_string <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_string <= m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_string > m_sub;\n      ignore_unused_variable_warning(b);\n      b = m_string >= m_sub;\n      ignore_unused_variable_warning(b);\n\n      // match results:\n      m_string = m_results.str();\n      ignore_unused_variable_warning(m_string);\n      m_string = m_results.str(0);\n      ignore_unused_variable_warning(m_string);\n      m_out = m_cresults.format(m_out, m_string);\n      m_out = m_cresults.format(m_out, m_string, m_mft);\n      m_string = m_cresults.format(m_string);\n      ignore_unused_variable_warning(m_string);\n      m_string = m_cresults.format(m_string, m_mft);\n      ignore_unused_variable_warning(m_string);\n\n      // regex_match:\n      b = global_regex_namespace::regex_match(m_string, m_smatch, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_string, m_smatch, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_string, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_match(m_string, e, m_mft);\n      ignore_unused_variable_warning(b);\n\n      // regex_search:\n      b = global_regex_namespace::regex_search(m_string, m_smatch, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_string, m_smatch, e, m_mft);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_string, e);\n      ignore_unused_variable_warning(b);\n      b = global_regex_namespace::regex_search(m_string, e, m_mft);\n      ignore_unused_variable_warning(b);\n\n      // regex_replace:\n      m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string, m_mft);\n      m_out = global_regex_namespace::regex_replace(m_out, m_in, m_in, e, m_string);\n      m_string = global_regex_namespace::regex_replace(m_string, e, m_string, m_mft);\n      ignore_unused_variable_warning(m_string);\n      m_string = global_regex_namespace::regex_replace(m_string, e, m_string);\n      ignore_unused_variable_warning(m_string);\n\n   }\n\n   flag_type m_flags;\n   string_type m_string;\n   const sub_match_type m_sub;\n   match_results_type m_results;\n   pointer_type m_pointer;\n   value_type m_char;\n   const match_results_type m_cresults;\n   OutIterator m_out;\n   BidiIterator m_in;\n   global_regex_namespace::regex_constants::match_flag_type m_mft;\n   global_regex_namespace::match_results<typename string_type::const_iterator, allocator_architype<global_regex_namespace::sub_match<typename string_type::const_iterator> > > m_smatch;\n\n   RegexConcept();\n   RegexConcept(const RegexConcept&);\n   RegexConcept& operator=(const RegexConcept&);\n};\n\n#ifndef BOOST_REGEX_TEST_STD\n\ntemplate <class M>\nstruct functor1\n{\n   typedef typename M::char_type char_type;\n   const char_type* operator()(const M&)const\n   {\n      static const char_type c = static_cast<char_type>(0);\n      return &c;\n   }\n};\ntemplate <class M>\nstruct functor1b\n{\n   typedef typename M::char_type char_type;\n   std::vector<char_type> operator()(const M&)const\n   {\n      static const std::vector<char_type> c;\n      return c;\n   }\n};\ntemplate <class M>\nstruct functor2\n{\n   template <class O>\n   O operator()(const M& /*m*/, O i)const\n   {\n      return i;\n   }\n};\ntemplate <class M>\nstruct functor3\n{\n   template <class O>\n   O operator()(const M& /*m*/, O i, regex_constants::match_flag_type)const\n   {\n      return i;\n   }\n};\n\n//\n// BoostRegexConcept:\n// Test every interface in the Boost implementation:\n//\ntemplate <class Regex>\nstruct BoostRegexConcept\n{\n   typedef typename Regex::value_type value_type;\n   typedef typename Regex::size_type size_type;\n   typedef typename Regex::flag_type flag_type;\n   typedef typename Regex::locale_type locale_type;\n\n   // derived test types:\n   typedef const value_type* pointer_type;\n   typedef std::basic_string<value_type> string_type;\n   typedef typename Regex::const_iterator const_iterator;\n   typedef bidirectional_iterator_archetype<value_type> BidiIterator;\n   typedef output_iterator_archetype<value_type> OutputIterator;\n   typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;\n   typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;\n   typedef global_regex_namespace::match_results<BidiIterator> match_results_default_type;\n\n   void constraints() \n   {\n      global_regex_namespace::regex_constants::match_flag_type mopts\n         = global_regex_namespace::regex_constants::match_default\n         | global_regex_namespace::regex_constants::match_not_bol\n         | global_regex_namespace::regex_constants::match_not_eol\n         | global_regex_namespace::regex_constants::match_not_bow\n         | global_regex_namespace::regex_constants::match_not_eow\n         | global_regex_namespace::regex_constants::match_any\n         | global_regex_namespace::regex_constants::match_not_null\n         | global_regex_namespace::regex_constants::match_continuous\n         | global_regex_namespace::regex_constants::match_partial\n         | global_regex_namespace::regex_constants::match_prev_avail\n         | global_regex_namespace::regex_constants::format_default\n         | global_regex_namespace::regex_constants::format_sed\n         | global_regex_namespace::regex_constants::format_perl\n         | global_regex_namespace::regex_constants::format_no_copy\n         | global_regex_namespace::regex_constants::format_first_only;\n\n      (void)mopts;\n\n      function_requires<RegexConcept<Regex> >();\n      const global_regex_namespace::regex_error except(global_regex_namespace::regex_constants::error_collate);\n      std::ptrdiff_t pt = except.position();\n      ignore_unused_variable_warning(pt);\n      const Regex ce, ce2;\n#ifndef BOOST_NO_STD_LOCALE\n      m_stream << ce;\n#endif\n      unsigned i = ce.error_code();\n      ignore_unused_variable_warning(i);\n      pointer_type p = ce.expression();\n      ignore_unused_variable_warning(p);\n      int i2 = ce.compare(ce2);\n      ignore_unused_variable_warning(i2);\n      bool b = ce == ce2;\n      ignore_unused_variable_warning(b);\n      b = ce.empty();\n      ignore_unused_variable_warning(b);\n      b = ce != ce2;\n      ignore_unused_variable_warning(b);\n      b = ce < ce2;\n      ignore_unused_variable_warning(b);\n      b = ce > ce2;\n      ignore_unused_variable_warning(b);\n      b = ce <= ce2;\n      ignore_unused_variable_warning(b);\n      b = ce >= ce2;\n      ignore_unused_variable_warning(b);\n      i = ce.status();\n      ignore_unused_variable_warning(i);\n      size_type s = ce.max_size();\n      ignore_unused_variable_warning(s);\n      s = ce.size();\n      ignore_unused_variable_warning(s);\n      const_iterator pi = ce.begin();\n      ignore_unused_variable_warning(pi);\n      pi = ce.end();\n      ignore_unused_variable_warning(pi);\n      string_type s2 = ce.str();\n      ignore_unused_variable_warning(s2);\n\n      m_string = m_sub + m_sub;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_sub + m_pointer;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_pointer + m_sub;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_sub + m_string;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_string + m_sub;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_sub + m_char;\n      ignore_unused_variable_warning(m_string);\n      m_string = m_char + m_sub;\n      ignore_unused_variable_warning(m_string);\n\n      // Named sub-expressions:\n      m_sub = m_cresults[&m_char];\n      ignore_unused_variable_warning(m_sub);\n      m_sub = m_cresults[m_string];\n      ignore_unused_variable_warning(m_sub);\n      m_sub = m_cresults[\"\"];\n      ignore_unused_variable_warning(m_sub);\n      m_sub = m_cresults[std::string(\"\")];\n      ignore_unused_variable_warning(m_sub);\n      m_string = m_cresults.str(&m_char);\n      ignore_unused_variable_warning(m_string);\n      m_string = m_cresults.str(m_string);\n      ignore_unused_variable_warning(m_string);\n      m_string = m_cresults.str(\"\");\n      ignore_unused_variable_warning(m_string);\n      m_string = m_cresults.str(std::string(\"\"));\n      ignore_unused_variable_warning(m_string);\n\n      typename match_results_type::difference_type diff;\n      diff = m_cresults.length(&m_char);\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.length(m_string);\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.length(\"\");\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.length(std::string(\"\"));\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.position(&m_char);\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.position(m_string);\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.position(\"\");\n      ignore_unused_variable_warning(diff);\n      diff = m_cresults.position(std::string(\"\"));\n      ignore_unused_variable_warning(diff);\n\n#ifndef BOOST_NO_STD_LOCALE\n      m_stream << m_sub;\n      m_stream << m_cresults;\n#endif\n      //\n      // Extended formatting with a functor:\n      //\n      regex_constants::match_flag_type f = regex_constants::match_default;\n      OutputIterator out = static_object<OutputIterator>::get();\n      \n      functor3<match_results_default_type> func3;\n      functor2<match_results_default_type> func2;\n      functor1<match_results_default_type> func1;\n      \n      functor3<match_results_type> func3b;\n      functor2<match_results_type> func2b;\n      functor1<match_results_type> func1b;\n\n      out = regex_format(out, m_cresults, func3b, f);\n      out = regex_format(out, m_cresults, func3b);\n      out = regex_format(out, m_cresults, func2b, f);\n      out = regex_format(out, m_cresults, func2b);\n      out = regex_format(out, m_cresults, func1b, f);\n      out = regex_format(out, m_cresults, func1b);\n      out = regex_format(out, m_cresults, RW_NS::ref(func3b), f);\n      out = regex_format(out, m_cresults, RW_NS::ref(func3b));\n      out = regex_format(out, m_cresults, RW_NS::ref(func2b), f);\n      out = regex_format(out, m_cresults, RW_NS::ref(func2b));\n      out = regex_format(out, m_cresults, RW_NS::ref(func1b), f);\n      out = regex_format(out, m_cresults, RW_NS::ref(func1b));\n      out = regex_format(out, m_cresults, RW_NS::cref(func3b), f);\n      out = regex_format(out, m_cresults, RW_NS::cref(func3b));\n      out = regex_format(out, m_cresults, RW_NS::cref(func2b), f);\n      out = regex_format(out, m_cresults, RW_NS::cref(func2b));\n      out = regex_format(out, m_cresults, RW_NS::cref(func1b), f);\n      out = regex_format(out, m_cresults, RW_NS::cref(func1b));\n      m_string += regex_format(m_cresults, func3b, f);\n      m_string += regex_format(m_cresults, func3b);\n      m_string += regex_format(m_cresults, func2b, f);\n      m_string += regex_format(m_cresults, func2b);\n      m_string += regex_format(m_cresults, func1b, f);\n      m_string += regex_format(m_cresults, func1b);\n      m_string += regex_format(m_cresults, RW_NS::ref(func3b), f);\n      m_string += regex_format(m_cresults, RW_NS::ref(func3b));\n      m_string += regex_format(m_cresults, RW_NS::ref(func2b), f);\n      m_string += regex_format(m_cresults, RW_NS::ref(func2b));\n      m_string += regex_format(m_cresults, RW_NS::ref(func1b), f);\n      m_string += regex_format(m_cresults, RW_NS::ref(func1b));\n      m_string += regex_format(m_cresults, RW_NS::cref(func3b), f);\n      m_string += regex_format(m_cresults, RW_NS::cref(func3b));\n      m_string += regex_format(m_cresults, RW_NS::cref(func2b), f);\n      m_string += regex_format(m_cresults, RW_NS::cref(func2b));\n      m_string += regex_format(m_cresults, RW_NS::cref(func1b), f);\n      m_string += regex_format(m_cresults, RW_NS::cref(func1b));\n\n      out = m_cresults.format(out, func3b, f);\n      out = m_cresults.format(out, func3b);\n      out = m_cresults.format(out, func2b, f);\n      out = m_cresults.format(out, func2b);\n      out = m_cresults.format(out, func1b, f);\n      out = m_cresults.format(out, func1b);\n      out = m_cresults.format(out, RW_NS::ref(func3b), f);\n      out = m_cresults.format(out, RW_NS::ref(func3b));\n      out = m_cresults.format(out, RW_NS::ref(func2b), f);\n      out = m_cresults.format(out, RW_NS::ref(func2b));\n      out = m_cresults.format(out, RW_NS::ref(func1b), f);\n      out = m_cresults.format(out, RW_NS::ref(func1b));\n      out = m_cresults.format(out, RW_NS::cref(func3b), f);\n      out = m_cresults.format(out, RW_NS::cref(func3b));\n      out = m_cresults.format(out, RW_NS::cref(func2b), f);\n      out = m_cresults.format(out, RW_NS::cref(func2b));\n      out = m_cresults.format(out, RW_NS::cref(func1b), f);\n      out = m_cresults.format(out, RW_NS::cref(func1b));\n\n      m_string += m_cresults.format(func3b, f);\n      m_string += m_cresults.format(func3b);\n      m_string += m_cresults.format(func2b, f);\n      m_string += m_cresults.format(func2b);\n      m_string += m_cresults.format(func1b, f);\n      m_string += m_cresults.format(func1b);\n      m_string += m_cresults.format(RW_NS::ref(func3b), f);\n      m_string += m_cresults.format(RW_NS::ref(func3b));\n      m_string += m_cresults.format(RW_NS::ref(func2b), f);\n      m_string += m_cresults.format(RW_NS::ref(func2b));\n      m_string += m_cresults.format(RW_NS::ref(func1b), f);\n      m_string += m_cresults.format(RW_NS::ref(func1b));\n      m_string += m_cresults.format(RW_NS::cref(func3b), f);\n      m_string += m_cresults.format(RW_NS::cref(func3b));\n      m_string += m_cresults.format(RW_NS::cref(func2b), f);\n      m_string += m_cresults.format(RW_NS::cref(func2b));\n      m_string += m_cresults.format(RW_NS::cref(func1b), f);\n      m_string += m_cresults.format(RW_NS::cref(func1b));\n\n      out = regex_replace(out, m_in, m_in, ce, func3, f);\n      out = regex_replace(out, m_in, m_in, ce, func3);\n      out = regex_replace(out, m_in, m_in, ce, func2, f);\n      out = regex_replace(out, m_in, m_in, ce, func2);\n      out = regex_replace(out, m_in, m_in, ce, func1, f);\n      out = regex_replace(out, m_in, m_in, ce, func1);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func3), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func3));\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func2), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func2));\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func1), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::ref(func1));\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func3), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func3));\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func2), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func2));\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func1), f);\n      out = regex_replace(out, m_in, m_in, ce, RW_NS::cref(func1));\n\n      functor3<match_results<typename string_type::const_iterator> > func3s;\n      functor2<match_results<typename string_type::const_iterator> > func2s;\n      functor1<match_results<typename string_type::const_iterator> > func1s;\n      m_string += regex_replace(m_string, ce, func3s, f);\n      m_string += regex_replace(m_string, ce, func3s);\n      m_string += regex_replace(m_string, ce, func2s, f);\n      m_string += regex_replace(m_string, ce, func2s);\n      m_string += regex_replace(m_string, ce, func1s, f);\n      m_string += regex_replace(m_string, ce, func1s);\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func3s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func3s));\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func2s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func2s));\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func1s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::ref(func1s));\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func3s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func3s));\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func2s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func2s));\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func1s), f);\n      m_string += regex_replace(m_string, ce, RW_NS::cref(func1s));\n   }\n\n   std::basic_ostream<value_type> m_stream;\n   sub_match_type m_sub;\n   pointer_type m_pointer;\n   string_type m_string;\n   const value_type m_char;\n   match_results_type m_results;\n   const match_results_type m_cresults;\n   BidiIterator m_in;\n\n   BoostRegexConcept();\n   BoostRegexConcept(const BoostRegexConcept&);\n   BoostRegexConcept& operator=(const BoostRegexConcept&);\n};\n\n#endif // BOOST_REGEX_TEST_STD\n\n}\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/config/borland.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         boost/regex/config/borland.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: regex borland-specific config setup.\n  */\n\n\n#if defined(__BORLANDC__) && !defined(__clang__)\n#  if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551)\n      // problems with std::basic_string and dll RTL:\n#     if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE)\n#        ifdef BOOST_REGEX_BUILD_DLL\n#           error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL\n#        else\n#           pragma message(\"Defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!!\")\n#        endif\n#     endif\n#     ifndef _RTLDLL\n         // this is harmless for a staic link:\n#        define _RWSTD_COMPILE_INSTANTIATE\n#     endif\n      // external templates cause problems for some reason:\n#     define BOOST_REGEX_NO_EXTERNAL_TEMPLATES\n#  endif\n#  if (__BORLANDC__ <= 0x540) && !defined(BOOST_REGEX_NO_LIB) && !defined(_NO_VCL)\n      // C++ Builder 4 and earlier, we can't tell whether we should be using\n      // the VCL runtime or not, do a static link instead:\n#     define BOOST_REGEX_STATIC_LINK\n#  endif\n   //\n   // VCL support:\n   // if we're building a console app then there can't be any VCL (can there?)\n#  if !defined(__CONSOLE__) && !defined(_NO_VCL)\n#     define BOOST_REGEX_USE_VCL\n#  endif\n   //\n   // if this isn't Win32 then don't automatically select link\n   // libraries:\n   //\n#  ifndef _Windows\n#     ifndef BOOST_REGEX_NO_LIB\n#        define BOOST_REGEX_NO_LIB\n#     endif\n#     ifndef BOOST_REGEX_STATIC_LINK\n#        define BOOST_REGEX_STATIC_LINK\n#     endif\n#  endif\n\n#if __BORLANDC__ < 0x600\n//\n// string workarounds:\n//\n#include <cstring>\n#undef strcmp\n#undef strcpy\n#endif\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/config/cwchar.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         boost/regex/config/cwchar.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: regex wide character string fixes.\n  */\n\n#ifndef BOOST_REGEX_CONFIG_CWCHAR_HPP\n#define BOOST_REGEX_CONFIG_CWCHAR_HPP\n\n#include <cwchar>\n#include <cwctype>\n#include <boost/config.hpp>\n\n#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)\n// apparently this is required for the RW STL on Linux:\n#undef iswalnum\n#undef iswalpha\n#undef iswblank\n#undef iswcntrl\n#undef iswdigit\n#undef iswgraph\n#undef iswlower\n#undef iswprint\n#undef iswprint\n#undef iswpunct\n#undef iswspace\n#undef iswupper\n#undef iswxdigit\n#undef iswctype\n#undef towlower\n#undef towupper\n#undef towctrans\n#undef wctrans\n#undef wctype\n#endif\n\nnamespace std{\n\n#ifndef BOOST_NO_STDC_NAMESPACE\nextern \"C\"{\n#endif\n\n#ifdef iswalnum\ninline int (iswalnum)(wint_t i)\n{ return iswalnum(i); }\n#undef iswalnum\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswalnum;\n#endif\n\n#ifdef iswalpha\ninline int (iswalpha)(wint_t i)\n{ return iswalpha(i); }\n#undef iswalpha\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswalpha;\n#endif\n\n#ifdef iswcntrl\ninline int (iswcntrl)(wint_t i)\n{ return iswcntrl(i); }\n#undef iswcntrl\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswcntrl;\n#endif\n\n#ifdef iswdigit\ninline int (iswdigit)(wint_t i)\n{ return iswdigit(i); }\n#undef iswdigit\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswdigit;\n#endif\n\n#ifdef iswgraph\ninline int (iswgraph)(wint_t i)\n{ return iswgraph(i); }\n#undef iswgraph\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswgraph;\n#endif\n\n#ifdef iswlower\ninline int (iswlower)(wint_t i)\n{ return iswlower(i); }\n#undef iswlower\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswlower;\n#endif\n\n#ifdef iswprint\ninline int (iswprint)(wint_t i)\n{ return iswprint(i); }\n#undef iswprint\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswprint;\n#endif\n\n#ifdef iswpunct\ninline int (iswpunct)(wint_t i)\n{ return iswpunct(i); }\n#undef iswpunct\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswpunct;\n#endif\n\n#ifdef iswspace\ninline int (iswspace)(wint_t i)\n{ return iswspace(i); }\n#undef iswspace\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswspace;\n#endif\n\n#ifdef iswupper\ninline int (iswupper)(wint_t i)\n{ return iswupper(i); }\n#undef iswupper\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswupper;\n#endif\n\n#ifdef iswxdigit\ninline int (iswxdigit)(wint_t i)\n{ return iswxdigit(i); }\n#undef iswxdigit\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::iswxdigit;\n#endif\n\n#ifdef towlower\ninline wint_t (towlower)(wint_t i)\n{ return towlower(i); }\n#undef towlower\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::towlower;\n#endif\n\n#ifdef towupper\ninline wint_t (towupper)(wint_t i)\n{ return towupper(i); }\n#undef towupper\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing :: towupper;\n#endif\n\n#ifdef wcscmp\ninline int (wcscmp)(const wchar_t *p1, const wchar_t *p2)\n{ return wcscmp(p1,p2); }\n#undef wcscmp\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::wcscmp;\n#endif\n\n#ifdef wcscoll\ninline int (wcscoll)(const wchar_t *p1, const wchar_t *p2)\n{ return wcscoll(p1,p2); }\n#undef wcscoll\n#elif defined(BOOST_NO_STDC_NAMESPACE) && !defined(UNDER_CE)\nusing ::wcscoll;\n#endif\n\n#ifdef wcscpy\ninline wchar_t *(wcscpy)(wchar_t *p1, const wchar_t *p2)\n{ return wcscpy(p1,p2); }\n#undef wcscpy\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::wcscpy;\n#endif\n\n#ifdef wcslen\ninline size_t (wcslen)(const wchar_t *p)\n{ return wcslen(p); }\n#undef wcslen\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::wcslen;\n#endif\n\n#ifdef wcsxfrm\nsize_t wcsxfrm(wchar_t *p1, const wchar_t *p2, size_t s)\n{ return wcsxfrm(p1,p2,s); }\n#undef wcsxfrm\n#elif defined(BOOST_NO_STDC_NAMESPACE)\nusing ::wcsxfrm;\n#endif\n\n\n#ifndef BOOST_NO_STDC_NAMESPACE\n} // extern \"C\"\n#endif\n\n} // namespace std\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/config.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         config.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: regex extended config setup.\n  */\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#define BOOST_REGEX_CONFIG_HPP\n\n#if !((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(BOOST_REGEX_CXX03))\n#  define BOOST_REGEX_CXX03\n#endif\n\n#if defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_CXX03)\n#  define BOOST_REGEX_CXX03\n#endif\n\n#if defined(__has_include)\n#if !defined(BOOST_REGEX_STANDALONE) && !__has_include(<boost/version.hpp>)\n#define BOOST_REGEX_STANDALONE\n#endif\n#endif\n\n/*\n * Borland C++ Fix/error check\n * this has to go *before* we include any std lib headers:\n */\n#if defined(__BORLANDC__) && !defined(__clang__)\n#  include <boost/regex/config/borland.hpp>\n#endif\n#ifndef BOOST_REGEX_STANDALONE\n#include <boost/version.hpp>\n#endif\n\n/*************************************************************************\n*\n* Asserts:\n*\n*************************************************************************/\n\n#ifdef BOOST_REGEX_STANDALONE\n#include <cassert>\n#  define BOOST_REGEX_ASSERT(x) assert(x)\n#else\n#include <boost/assert.hpp>\n#  define BOOST_REGEX_ASSERT(x) BOOST_ASSERT(x)\n#endif\n\n/*****************************************************************************\n *\n *  Include all the headers we need here:\n *\n ****************************************************************************/\n\n#ifdef __cplusplus\n\n#  ifndef BOOST_REGEX_USER_CONFIG\n#     define BOOST_REGEX_USER_CONFIG <boost/regex/user.hpp>\n#  endif\n\n#  include BOOST_REGEX_USER_CONFIG\n\n#ifndef BOOST_REGEX_STANDALONE\n#  include <boost/config.hpp>\n#  include <boost/predef.h>\n#endif\n\n#else\n   /*\n    * C build,\n    * don't include <boost/config.hpp> because that may\n    * do C++ specific things in future...\n    */\n#  include <stdlib.h>\n#  include <stddef.h>\n#  ifdef _MSC_VER\n#     define BOOST_MSVC _MSC_VER\n#  endif\n#endif\n\n\n/****************************************************************************\n*\n* Legacy support:\n*\n*******************************************************************************/\n\n#if defined(BOOST_NO_STD_LOCALE) || defined(BOOST_NO_CXX11_HDR_MUTEX) || defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) \\\n   || defined(BOOST_NO_CXX11_HDR_ATOMIC) || defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_CXX11_SMART_PTR) \\\n   || defined(BOOST_NO_CXX11_STATIC_ASSERT) || defined(BOOST_NO_NOEXCEPT)\n#ifndef BOOST_REGEX_CXX03\n#  define BOOST_REGEX_CXX03\n#endif\n#endif\n\n/*****************************************************************************\n *\n *  Boilerplate regex config options:\n *\n ****************************************************************************/\n\n/* Obsolete macro, use BOOST_VERSION instead: */\n#define BOOST_RE_VERSION 500\n\n/* fix: */\n#if defined(_UNICODE) && !defined(UNICODE)\n#define UNICODE\n#endif\n\n#define BOOST_REGEX_JOIN(X, Y) BOOST_REGEX_DO_JOIN(X, Y)\n#define BOOST_REGEX_DO_JOIN(X, Y) BOOST_REGEX_DO_JOIN2(X,Y)\n#define BOOST_REGEX_DO_JOIN2(X, Y) X##Y\n\n#ifdef BOOST_FALLTHROUGH\n#  define BOOST_REGEX_FALLTHROUGH BOOST_FALLTHROUGH\n#else\n\n#if defined(__clang__) && (__cplusplus >= 201103L) && defined(__has_warning)\n#  if __has_feature(cxx_attributes) && __has_warning(\"-Wimplicit-fallthrough\")\n#    define BOOST_REGEX_FALLTHROUGH [[clang::fallthrough]]\n#  endif\n#endif\n#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1800) && (__cplusplus >= 201703)\n#  define BOOST_REGEX_FALLTHROUGH [[fallthrough]]\n#endif\n#if !defined(BOOST_REGEX_FALLTHROUGH) && defined(__GNUC__) && (__GNUC__ >= 7)\n#  define BOOST_REGEX_FALLTHROUGH __attribute__((fallthrough))\n#endif\n\n#if !defined(BOOST_REGEX_FALLTHROUGH)\n#  define BOOST_REGEX_FALLTHROUGH\n#endif\n#endif\n\n#ifdef BOOST_NORETURN\n#  define BOOST_REGEX_NORETURN BOOST_NORETURN\n#else\n#  define BOOST_REGEX_NORETURN\n#endif\n\n\n/*\n* Define a macro for the namespace that details are placed in, this includes the Boost\n* version number to avoid mismatched header and library versions:\n*/\n#define BOOST_REGEX_DETAIL_NS BOOST_REGEX_JOIN(re_detail_, BOOST_RE_VERSION)\n\n/*\n * Fix for gcc prior to 3.4: std::ctype<wchar_t> doesn't allow\n * masks to be combined, for example:\n * std::use_facet<std::ctype<wchar_t> >.is(std::ctype_base::lower|std::ctype_base::upper, L'a');\n * returns *false*.\n */\n#if defined(__GLIBCPP__) && defined(BOOST_REGEX_CXX03)\n#  define BOOST_REGEX_BUGGY_CTYPE_FACET\n#endif\n\n/*\n * If there isn't good enough wide character support then there will\n * be no wide character regular expressions:\n */\n#if (defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_CWCTYPE) || defined(BOOST_NO_STD_WSTRING))\n#  if !defined(BOOST_NO_WREGEX)\n#     define BOOST_NO_WREGEX\n#  endif\n#else\n#  if defined(__sgi) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))\n      /* STLPort on IRIX is misconfigured: <cwctype> does not compile\n       * as a temporary fix include <wctype.h> instead and prevent inclusion\n       * of STLPort version of <cwctype> */\n#     include <wctype.h>\n#     define __STLPORT_CWCTYPE\n#     define _STLP_CWCTYPE\n#  endif\n\n#if defined(__cplusplus) && defined(BOOST_REGEX_CXX03)\n#  include <boost/regex/config/cwchar.hpp>\n#endif\n\n#endif\n\n/*\n * If Win32 support has been disabled for boost in general, then\n * it is for regex in particular:\n */\n#if defined(BOOST_DISABLE_WIN32) && !defined(BOOST_REGEX_NO_W32)\n#  define BOOST_REGEX_NO_W32\n#endif\n\n/* disable our own file-iterators and mapfiles if we can't\n * support them: */\n#if defined(_WIN32)\n#  if defined(BOOST_REGEX_NO_W32) || BOOST_PLAT_WINDOWS_RUNTIME\n#    define BOOST_REGEX_NO_FILEITER\n#  endif\n#else /* defined(_WIN32) */\n#  if !defined(BOOST_HAS_DIRENT_H)\n#    define BOOST_REGEX_NO_FILEITER\n#  endif\n#endif\n\n/* backwards compatibitity: */\n#if defined(BOOST_RE_NO_LIB)\n#  define BOOST_REGEX_NO_LIB\n#endif\n\n#if defined(__GNUC__) && !defined(_MSC_VER) && (defined(_WIN32) || defined(__CYGWIN__))\n/* gcc on win32 has problems if you include <windows.h>\n   (sporadically generates bad code). */\n#  define BOOST_REGEX_NO_W32\n#endif\n#if defined(__COMO__) && !defined(BOOST_REGEX_NO_W32) && !defined(_MSC_EXTENSIONS)\n#  define BOOST_REGEX_NO_W32\n#endif\n\n#ifdef BOOST_REGEX_STANDALONE\n#  if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)\n#     define BOOST_REGEX_MSVC _MSC_VER\n#endif\n#elif defined(BOOST_MSVC)\n#  define BOOST_REGEX_MSVC BOOST_MSVC\n#endif\n\n\n/*****************************************************************************\n *\n *  Set up dll import/export options:\n *\n ****************************************************************************/\n\n#if (defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_REGEX_STATIC_LINK) && defined(BOOST_SYMBOL_IMPORT)\n#  if defined(BOOST_REGEX_SOURCE)\n#     define BOOST_REGEX_BUILD_DLL\n#     define BOOST_REGEX_DECL BOOST_SYMBOL_EXPORT\n#  else\n#     define BOOST_REGEX_DECL BOOST_SYMBOL_IMPORT\n#  endif\n#else\n#  define BOOST_REGEX_DECL\n#endif\n\n#ifdef BOOST_REGEX_CXX03\n#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)\n#  define BOOST_LIB_NAME boost_regex\n#  if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)\n#     define BOOST_DYN_LINK\n#  endif\n#  ifdef BOOST_REGEX_DIAG\n#     define BOOST_LIB_DIAGNOSTIC\n#  endif\n#  include <boost/config/auto_link.hpp>\n#endif\n#endif\n\n/*****************************************************************************\n *\n *  Set up function call type:\n *\n ****************************************************************************/\n\n#if defined(_MSC_VER) && defined(_MSC_EXTENSIONS)\n#if defined(_DEBUG) || defined(__MSVC_RUNTIME_CHECKS) || defined(_MANAGED) || defined(BOOST_REGEX_NO_FASTCALL)\n#  define BOOST_REGEX_CALL __cdecl\n#else\n#  define BOOST_REGEX_CALL __fastcall\n#endif\n#  define BOOST_REGEX_CCALL __cdecl\n#endif\n\n#if defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)\n#if defined(__clang__)\n#  define BOOST_REGEX_CALL __cdecl\n#  define BOOST_REGEX_CCALL __cdecl\n#else\n#  define BOOST_REGEX_CALL __fastcall\n#  define BOOST_REGEX_CCALL __stdcall\n#endif\n#endif\n\n#ifndef BOOST_REGEX_CALL\n#  define BOOST_REGEX_CALL\n#endif\n#ifndef BOOST_REGEX_CCALL\n#define BOOST_REGEX_CCALL\n#endif\n\n/*****************************************************************************\n *\n *  Set up localisation model:\n *\n ****************************************************************************/\n\n/* backwards compatibility: */\n#ifdef BOOST_RE_LOCALE_C\n#  define BOOST_REGEX_USE_C_LOCALE\n#endif\n\n#ifdef BOOST_RE_LOCALE_CPP\n#  define BOOST_REGEX_USE_CPP_LOCALE\n#endif\n\n#if defined(__CYGWIN__)\n#  define BOOST_REGEX_USE_C_LOCALE\n#endif\n\n/* use C++ locale when targeting windows store */\n#if BOOST_PLAT_WINDOWS_RUNTIME\n#  define BOOST_REGEX_USE_CPP_LOCALE\n#  define BOOST_REGEX_NO_WIN32_LOCALE\n#endif\n\n/* Win32 defaults to native Win32 locale: */\n#if defined(_WIN32) && \\\n    !defined(BOOST_REGEX_USE_WIN32_LOCALE) && \\\n    !defined(BOOST_REGEX_USE_C_LOCALE) && \\\n    !defined(BOOST_REGEX_USE_CPP_LOCALE) && \\\n    !defined(BOOST_REGEX_NO_W32) && \\\n    !defined(BOOST_REGEX_NO_WIN32_LOCALE)\n#  define BOOST_REGEX_USE_WIN32_LOCALE\n#endif\n/* otherwise use C++ locale if supported: */\n#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE) && !defined(BOOST_NO_STD_LOCALE)\n#  define BOOST_REGEX_USE_CPP_LOCALE\n#endif\n/* otherwise use C locale: */\n#if !defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(BOOST_REGEX_USE_C_LOCALE) && !defined(BOOST_REGEX_USE_CPP_LOCALE)\n#  define BOOST_REGEX_USE_C_LOCALE\n#endif\n\n#ifndef BOOST_REGEX_MAX_STATE_COUNT\n#  define BOOST_REGEX_MAX_STATE_COUNT 100000000\n#endif\n\n\n/*****************************************************************************\n *\n *  Error Handling for exception free compilers:\n *\n ****************************************************************************/\n\n#ifdef BOOST_NO_EXCEPTIONS\n/*\n * If there are no exceptions then we must report critical-errors\n * the only way we know how; by terminating.\n */\n#include <stdexcept>\n#include <string>\n#include <boost/throw_exception.hpp>\n\n#  define BOOST_REGEX_NOEH_ASSERT(x)\\\nif(0 == (x))\\\n{\\\n   std::string s(\"Error: critical regex++ failure in: \");\\\n   s.append(#x);\\\n   std::runtime_error e(s);\\\n   boost::throw_exception(e);\\\n}\n#else\n/*\n * With exceptions then error handling is taken care of and\n * there is no need for these checks:\n */\n#  define BOOST_REGEX_NOEH_ASSERT(x)\n#endif\n\n\n/*****************************************************************************\n *\n *  Stack protection under MS Windows:\n *\n ****************************************************************************/\n\n#if !defined(BOOST_REGEX_NO_W32) && !defined(BOOST_REGEX_V3)\n#  if(defined(_WIN32) || defined(_WIN64) || defined(_WINCE)) \\\n        && !(defined(__GNUC__) || defined(__BORLANDC__) && defined(__clang__)) \\\n        && !(defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)) \\\n        && !(defined(__MWERKS__) && (__MWERKS__ <= 0x3003))\n#     define BOOST_REGEX_HAS_MS_STACK_GUARD\n#  endif\n#elif defined(BOOST_REGEX_HAS_MS_STACK_GUARD)\n#  undef BOOST_REGEX_HAS_MS_STACK_GUARD\n#endif\n\n#if defined(__cplusplus) && defined(BOOST_REGEX_HAS_MS_STACK_GUARD)\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\nBOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();\n\n}\n}\n\n#endif\n\n\n/*****************************************************************************\n *\n *  Algorithm selection and configuration.\n *  These options are now obsolete for C++11 and later (regex v5).\n *\n ****************************************************************************/\n\n#if !defined(BOOST_REGEX_RECURSIVE) && !defined(BOOST_REGEX_NON_RECURSIVE)\n#  if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && !defined(_STLP_DEBUG) && !defined(__STL_DEBUG) && !(defined(_MSC_VER) && (_MSC_VER >= 1400)) && defined(BOOST_REGEX_CXX03)\n#     define BOOST_REGEX_RECURSIVE\n#  else\n#     define BOOST_REGEX_NON_RECURSIVE\n#  endif\n#endif\n\n#ifdef BOOST_REGEX_NON_RECURSIVE\n#  ifdef BOOST_REGEX_RECURSIVE\n#     error \"Can't set both BOOST_REGEX_RECURSIVE and BOOST_REGEX_NON_RECURSIVE\"\n#  endif\n#  ifndef BOOST_REGEX_BLOCKSIZE\n#     define BOOST_REGEX_BLOCKSIZE 4096\n#  endif\n#  if BOOST_REGEX_BLOCKSIZE < 512\n#     error \"BOOST_REGEX_BLOCKSIZE must be at least 512\"\n#  endif\n#  ifndef BOOST_REGEX_MAX_BLOCKS\n#     define BOOST_REGEX_MAX_BLOCKS 1024\n#  endif\n#  ifdef BOOST_REGEX_HAS_MS_STACK_GUARD\n#     undef BOOST_REGEX_HAS_MS_STACK_GUARD\n#  endif\n#  ifndef BOOST_REGEX_MAX_CACHE_BLOCKS\n#     define BOOST_REGEX_MAX_CACHE_BLOCKS 16\n#  endif\n#endif\n\n\n/*****************************************************************************\n *\n *  Diagnostics:\n *\n ****************************************************************************/\n\n#ifdef BOOST_REGEX_CONFIG_INFO\nBOOST_REGEX_DECL void BOOST_REGEX_CALL print_regex_library_info();\n#endif\n\n#if defined(BOOST_REGEX_DIAG)\n#  pragma message (\"BOOST_REGEX_DECL\" BOOST_STRINGIZE(=BOOST_REGEX_DECL))\n#  pragma message (\"BOOST_REGEX_CALL\" BOOST_STRINGIZE(=BOOST_REGEX_CALL))\n#  pragma message (\"BOOST_REGEX_CCALL\" BOOST_STRINGIZE(=BOOST_REGEX_CCALL))\n#ifdef BOOST_REGEX_USE_C_LOCALE\n#  pragma message (\"Using C locale in regex traits class\")\n#elif BOOST_REGEX_USE_CPP_LOCALE\n#  pragma message (\"Using C++ locale in regex traits class\")\n#else\n#  pragma message (\"Using Win32 locale in regex traits class\")\n#endif\n#if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)\n#  pragma message (\"Dynamic linking enabled\")\n#endif\n#if defined(BOOST_REGEX_NO_LIB) || defined(BOOST_ALL_NO_LIB)\n#  pragma message (\"Auto-linking disabled\")\n#endif\n#ifdef BOOST_REGEX_NO_EXTERNAL_TEMPLATES\n#  pragma message (\"Extern templates disabled\")\n#endif\n\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/icu.hpp",
    "content": "/*\n *\n * Copyright (c) 2020\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         icu.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.\n  */\n\n#ifndef BOOST_REGEX_ICU_HPP\n#define BOOST_REGEX_ICU_HPP\n\n#include <boost/regex/config.hpp>\n\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/icu.hpp>\n#else\n#include <boost/regex/v5/icu.hpp>\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/mfc.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         mfc.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Overloads and helpers for using MFC/ATL string types with Boost.Regex.\n  */\n\n#ifndef BOOST_REGEX_MFC_HPP\n#define BOOST_REGEX_MFC_HPP\n\n#include <atlsimpstr.h>\n#include <boost/regex.hpp>\n\nnamespace boost{\n\n//\n// define the types used for TCHAR's:\ntypedef basic_regex<TCHAR> tregex;\ntypedef match_results<TCHAR const*> tmatch;\ntypedef regex_iterator<TCHAR const*> tregex_iterator;\ntypedef regex_token_iterator<TCHAR const*> tregex_token_iterator;\n\n// Obsolete. Remove\n#define SIMPLE_STRING_PARAM class B, bool b\n#define SIMPLE_STRING_ARG_LIST B, b\n\n//\n// define regex creation functions:\n//\ntemplate <class B, bool b>\ninline basic_regex<B> \nmake_regex(const ATL::CSimpleStringT<B, b>& s, ::boost::regex_constants::syntax_option_type f = boost::regex_constants::normal)\n{\n   basic_regex<B> result(s.GetString(), s.GetString() + s.GetLength(), f);\n   return result;\n}\n//\n// regex_match overloads:\n//\ntemplate <class B, bool b, class A, class T>\ninline bool regex_match(const ATL::CSimpleStringT<B, b>& s,\n                 match_results<const B*, A>& what,\n                 const basic_regex<B, T>& e,\n                 boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   return ::boost::regex_match(s.GetString(),\n                               s.GetString() + s.GetLength(),\n                               what,\n                               e,\n                               f);\n}\n\ntemplate <class B, bool b, class T>\ninline bool regex_match(const ATL::CSimpleStringT<B, b>& s,\n                 const basic_regex<B, T>& e,\n                 boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   return ::boost::regex_match(s.GetString(),\n                               s.GetString() + s.GetLength(),\n                               e,\n                               f);\n}\n//\n// regex_search overloads:\n//\ntemplate <class B, bool b, class A, class T>\ninline bool regex_search(const ATL::CSimpleStringT<B, b>& s,\n                 match_results<const B*, A>& what,\n                 const basic_regex<B, T>& e,\n                 boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   return ::boost::regex_search(s.GetString(),\n                               s.GetString() + s.GetLength(),\n                               what,\n                               e,\n                               f);\n}\n\ntemplate <class B, bool b, class T>\ninline bool regex_search(const ATL::CSimpleStringT<B, b>& s,\n                 const basic_regex<B, T>& e,\n                 boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   return ::boost::regex_search(s.GetString(),\n                               s.GetString() + s.GetLength(),\n                               e,\n                               f);\n}\n//\n// regex_iterator creation:\n//\ntemplate <class B, bool b>\ninline regex_iterator<B const*> \nmake_regex_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   regex_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, f);\n   return result;\n}\n\ntemplate <class B, bool b>\ninline regex_token_iterator<B const*> \n   make_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, int sub = 0, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, sub, f);\n   return result;\n}\n\ntemplate <class B, bool b>\ninline regex_token_iterator<B const*> \nmake_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, const std::vector<int>& subs, ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);\n   return result;\n}\n\ntemplate <class B, bool b, std::size_t N>\ninline regex_token_iterator<B const*> \nmake_regex_token_iterator(const ATL::CSimpleStringT<B, b>& s, const basic_regex<B>& e, const int (& subs)[N], ::boost::regex_constants::match_flag_type f = boost::regex_constants::match_default)\n{\n   regex_token_iterator<B const*> result(s.GetString(), s.GetString() + s.GetLength(), e, subs, f);\n   return result;\n}\n\ntemplate <class OutputIterator, class BidirectionalIterator, class traits,\n          class B, bool b>\nOutputIterator regex_replace(OutputIterator out,\n                           BidirectionalIterator first,\n                           BidirectionalIterator last,\n                           const basic_regex<B, traits>& e,\n                           const ATL::CSimpleStringT<B, b>& fmt,\n                           match_flag_type flags = match_default)\n{\n   return ::boost::regex_replace(out, first, last, e, fmt.GetString(), flags);\n}\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class B, bool b>\nclass mfc_string_out_iterator\n{\n   ATL::CSimpleStringT<B, b>* out;\npublic:\n   mfc_string_out_iterator(ATL::CSimpleStringT<B, b>& s) : out(&s) {}\n   mfc_string_out_iterator& operator++() { return *this; }\n   mfc_string_out_iterator& operator++(int) { return *this; }\n   mfc_string_out_iterator& operator*() { return *this; }\n   mfc_string_out_iterator& operator=(B v) \n   { \n      out->AppendChar(v); \n      return *this; \n   }\n   typedef std::ptrdiff_t difference_type;\n   typedef B value_type;\n   typedef value_type* pointer;\n   typedef value_type& reference;\n   typedef std::output_iterator_tag iterator_category;\n};\n\n}\n\ntemplate <class traits, class B, bool b>\nATL::CSimpleStringT<B, b> regex_replace(const ATL::CSimpleStringT<B, b>& s,\n                            const basic_regex<B, traits>& e,\n                            const ATL::CSimpleStringT<B, b>& fmt,\n                            match_flag_type flags = match_default)\n{\n   ATL::CSimpleStringT<B, b> result(s.GetManager());\n   BOOST_REGEX_DETAIL_NS::mfc_string_out_iterator<B, b> i(result);\n   regex_replace(i, s.GetString(), s.GetString() + s.GetLength(), e, fmt.GetString(), flags);\n   return result;\n}\n\n} // namespace boost.\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/pattern_except.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         pattern_except.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares pattern-matching exception classes.\n  */\n\n#ifndef BOOST_RE_PAT_EXCEPT_HPP\n#define BOOST_RE_PAT_EXCEPT_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/pattern_except.hpp>\n#else\n#include <boost/regex/v5/pattern_except.hpp>\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/pending/object_cache.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         object_cache.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Implements a generic object cache.\n  */\n\n#ifndef BOOST_REGEX_OBJECT_CACHE_HPP\n#define BOOST_REGEX_OBJECT_CACHE_HPP\n\n#include <boost/regex/config.hpp>\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/object_cache.hpp>\n#else\n#include <boost/regex/v5/object_cache.hpp>\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/pending/static_mutex.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         static_mutex.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares static_mutex lock type, there are three different\n  *                implementations: POSIX pthreads, WIN32 threads, and portable,\n  *                these are described in more detail below.\n  */\n\n#ifndef BOOST_REGEX_STATIC_MUTEX_HPP\n#define BOOST_REGEX_STATIC_MUTEX_HPP\n\n#include <boost/config.hpp>\n#include <boost/regex/config.hpp> // dll import/export options.\n\n#ifdef BOOST_HAS_PTHREADS\n#include <pthread.h>\n#endif\n\n#if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)\n//\n// pthreads version:\n// simple wrap around a pthread_mutex_t initialized with\n// PTHREAD_MUTEX_INITIALIZER.\n//\nnamespace boost{\n\nclass static_mutex;\n\n#define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }\n\nclass BOOST_REGEX_DECL scoped_static_mutex_lock\n{\npublic:\n   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);\n   ~scoped_static_mutex_lock();\n   inline bool locked()const\n   {\n      return m_have_lock;\n   }\n   inline operator void const*()const\n   {\n      return locked() ? this : 0;\n   }\n   void lock();\n   void unlock();\nprivate:\n   static_mutex& m_mutex;\n   bool m_have_lock;\n};\n\nclass static_mutex\n{\npublic:\n   typedef scoped_static_mutex_lock scoped_lock;\n   pthread_mutex_t m_mutex;\n};\n\n} // namespace boost\n#elif defined(BOOST_HAS_WINTHREADS)\n//\n// Win32 version:\n// Use a 32-bit int as a lock, along with a test-and-set\n// implementation using InterlockedCompareExchange.\n//\n\n#include <boost/cstdint.hpp>\n\nnamespace boost{\n\nclass BOOST_REGEX_DECL scoped_static_mutex_lock;\n\nclass static_mutex\n{\npublic:\n   typedef scoped_static_mutex_lock scoped_lock;\n   boost::int32_t m_mutex;\n};\n\n#define BOOST_STATIC_MUTEX_INIT { 0, }\n\nclass BOOST_REGEX_DECL scoped_static_mutex_lock\n{\npublic:\n   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);\n   ~scoped_static_mutex_lock();\n   operator void const*()const\n   {\n      return locked() ? this : 0;\n   }\n   bool locked()const\n   {\n      return m_have_lock;\n   }\n   void lock();\n   void unlock();\nprivate:\n   static_mutex& m_mutex;\n   bool m_have_lock;\n   scoped_static_mutex_lock(const scoped_static_mutex_lock&);\n   scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);\n};\n\n} // namespace\n\n#else\n//\n// Portable version of a static mutex based on Boost.Thread library:\n// This has to use a single mutex shared by all instances of static_mutex\n// because boost::call_once doesn't alow us to pass instance information\n// down to the initialisation proceedure.  In fact the initialisation routine\n// may need to be called more than once - but only once per instance.\n//\n// Since this preprocessor path is almost never taken, we hide these header\n// dependencies so that build tools don't find them.\n//\n#define BOOST_REGEX_H1 <boost/thread/once.hpp>\n#define BOOST_REGEX_H2 <boost/thread/recursive_mutex.hpp>\n#define BOOST_REGEX_H3 <boost/thread/lock_types.hpp>\n#include BOOST_REGEX_H1\n#include BOOST_REGEX_H2\n#include BOOST_REGEX_H3\n#undef BOOST_REGEX_H1\n#undef BOOST_REGEX_H2\n#undef BOOST_REGEX_H3\n\nnamespace boost{\n\nclass BOOST_REGEX_DECL scoped_static_mutex_lock;\nextern \"C\" BOOST_REGEX_DECL void boost_regex_free_static_mutex();\n\nclass BOOST_REGEX_DECL static_mutex\n{\npublic:\n   typedef scoped_static_mutex_lock scoped_lock;\n   static void init();\n   static boost::recursive_mutex* m_pmutex;\n   static boost::once_flag m_once;\n};\n\n#define BOOST_STATIC_MUTEX_INIT {  }\n\nclass BOOST_REGEX_DECL scoped_static_mutex_lock\n{\npublic:\n   scoped_static_mutex_lock(static_mutex& mut, bool lk = true);\n   ~scoped_static_mutex_lock();\n   operator void const*()const;\n   bool locked()const;\n   void lock();\n   void unlock();\nprivate:\n   boost::unique_lock<boost::recursive_mutex>* m_plock;\n   bool m_have_lock;\n};\n\ninline scoped_static_mutex_lock::operator void const*()const\n{\n   return locked() ? this : 0;\n}\n\ninline bool scoped_static_mutex_lock::locked()const\n{\n   return m_have_lock;\n}\n\n} // namespace\n\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/pending/unicode_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2020\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         unicode_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Iterator adapters for converting between different Unicode encodings.\n  */\n\n#ifndef BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP\n#define BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP\n\n#include <boost/regex/config.hpp>\n\n#if defined(BOOST_REGEX_CXX03)\n#include <boost/regex/v4/unicode_iterator.hpp>\n#else\n#include <boost/regex/v5/unicode_iterator.hpp>\n#endif\n\n\n#endif // BOOST_REGEX_PENDING_UNICODE_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits classes.\n  */\n\n#ifndef BOOST_REGEX_TRAITS_HPP\n#define BOOST_REGEX_TRAITS_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#  include <boost/regex/config.hpp>\n#endif\n\n#  ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED\n#ifdef BOOST_REGEX_CXX03\n#     include <boost/regex/v4/regex_traits.hpp>\n#else\n#     include <boost/regex/v5/regex_traits.hpp>\n#endif\n#  endif\n\n#endif // include\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/user.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         user.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: User settable options.\n  */\n\n// define if you want the regex library to use the C locale\n// even on Win32:\n// #define BOOST_REGEX_USE_C_LOCALE\n\n// define this is you want the regex library to use the C++\n// locale:\n// #define BOOST_REGEX_USE_CPP_LOCALE\n\n// define this if the runtime library is a dll, and you\n// want BOOST_REGEX_DYN_LINK to set up dll exports/imports\n// with __declspec(dllexport)/__declspec(dllimport.)\n// #define BOOST_REGEX_HAS_DLL_RUNTIME\n\n// define this if you want to dynamically link to regex,\n// if the runtime library is also a dll (Probably Win32 specific,\n// and has no effect unless BOOST_REGEX_HAS_DLL_RUNTIME is set):\n// #define BOOST_REGEX_DYN_LINK\n\n// define this if you don't want the lib to automatically\n// select its link libraries:\n// #define BOOST_REGEX_NO_LIB\n\n// define this if templates with switch statements cause problems:\n// #define BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE\n \n// define this to disable Win32 support when available:\n// #define BOOST_REGEX_NO_W32\n\n// define this if bool is not a real type:\n// #define BOOST_REGEX_NO_BOOL\n\n// define this if no template instances are to be placed in\n// the library rather than users object files:\n// #define BOOST_REGEX_NO_EXTERNAL_TEMPLATES\n\n// define this if the forward declarations in regex_fwd.hpp\n// cause more problems than they are worth:\n// #define BOOST_REGEX_NO_FWD\n\n// define this if your compiler supports MS Windows structured\n// exception handling.\n// #define BOOST_REGEX_HAS_MS_STACK_GUARD\n\n// define this if you want to use the recursive algorithm\n// even if BOOST_REGEX_HAS_MS_STACK_GUARD is not defined.\n// NOTE: OBSOLETE!!\n// #define BOOST_REGEX_RECURSIVE\n\n// define this if you want to use the non-recursive\n// algorithm, even if the recursive version would be the default.\n// NOTE: OBSOLETE!!\n// #define BOOST_REGEX_NON_RECURSIVE\n\n// define this if you want to set the size of the memory blocks\n// used by the non-recursive algorithm.\n// #define BOOST_REGEX_BLOCKSIZE 4096\n\n// define this if you want to set the maximum number of memory blocks\n// used by the non-recursive algorithm.\n// #define BOOST_REGEX_MAX_BLOCKS 1024\n\n// define this if you want to set the maximum number of memory blocks\n// cached by the non-recursive algorithm: Normally this is 16, but can be \n// higher if you have multiple threads all using boost.regex, or lower \n// if you don't want boost.regex to cache memory.\n// #define BOOST_REGEX_MAX_CACHE_BLOCKS 16\n\n// define this if you want to be able to access extended capture\n// information in your sub_match's (caution this will slow things\n// down quite a bit).\n// #define BOOST_REGEX_MATCH_EXTRA\n\n// define this if you want to enable support for Unicode via ICU.\n// #define BOOST_HAS_ICU\n\n// define this if you want regex to use __cdecl calling convensions, even when __fastcall is available:\n// #define BOOST_REGEX_NO_FASTCALL\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/basic_regex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2004 John Maddock\n * Copyright 2011 Garmin Ltd. or its subsidiaries\n *\n * Distributed under the Boost Software License, Version 1.0.\n * (See accompanying file LICENSE_1_0.txt or copy at\n * http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org/ for most recent version.\n  *   FILE         basic_regex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex.\n  */\n\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP\n#define BOOST_REGEX_V4_BASIC_REGEX_HPP\n\n#include <boost/type_traits/is_same.hpp>\n#include <boost/container_hash/hash.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#if BOOST_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#if BOOST_MSVC < 1600\n#pragma warning(disable : 4660)\n#endif\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// forward declaration, we will need this one later:\n//\ntemplate <class charT, class traits>\nclass basic_regex_parser;\n\ntemplate <class I>\nvoid bubble_down_one(I first, I last)\n{\n   if(first != last)\n   {\n      I next = last - 1;\n      while((next != first) && (*next < *(next-1)))\n      {\n         (next-1)->swap(*next);\n         --next;\n      }\n   }\n}\n\nstatic const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);\n\ntemplate <class Iterator>\ninline int hash_value_from_capture_name(Iterator i, Iterator j)\n{\n   std::size_t r = boost::hash_range(i, j);\n   r %= ((std::numeric_limits<int>::max)());\n   return static_cast<int>(r) | hash_value_mask;\n}\n\nclass named_subexpressions\n{\npublic:\n   struct name\n   {\n      template <class charT>\n      name(const charT* i, const charT* j, int idx)\n         : index(idx) \n      { \n         hash = hash_value_from_capture_name(i, j); \n      }\n      name(int h, int idx)\n         : index(idx), hash(h)\n      { \n      }\n      int index;\n      int hash;\n      bool operator < (const name& other)const\n      {\n         return hash < other.hash;\n      }\n      bool operator == (const name& other)const\n      {\n         return hash == other.hash; \n      }\n      void swap(name& other)\n      {\n         std::swap(index, other.index);\n         std::swap(hash, other.hash);\n      }\n   };\n\n   typedef std::vector<name>::const_iterator const_iterator;\n   typedef std::pair<const_iterator, const_iterator> range_type;\n\n   named_subexpressions(){}\n\n   template <class charT>\n   void set_name(const charT* i, const charT* j, int index)\n   {\n      m_sub_names.push_back(name(i, j, index));\n      bubble_down_one(m_sub_names.begin(), m_sub_names.end());\n   }\n   template <class charT>\n   int get_id(const charT* i, const charT* j)const\n   {\n      name t(i, j, 0);\n      typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);\n      if((pos != m_sub_names.end()) && (*pos == t))\n      {\n         return pos->index;\n      }\n      return -1;\n   }\n   template <class charT>\n   range_type equal_range(const charT* i, const charT* j)const\n   {\n      name t(i, j, 0);\n      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);\n   }\n   int get_id(int h)const\n   {\n      name t(h, 0);\n      std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);\n      if((pos != m_sub_names.end()) && (*pos == t))\n      {\n         return pos->index;\n      }\n      return -1;\n   }\n   range_type equal_range(int h)const\n   {\n      name t(h, 0);\n      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);\n   }\nprivate:\n   std::vector<name> m_sub_names;\n};\n\n//\n// class regex_data:\n// represents the data we wish to expose to the matching algorithms.\n//\ntemplate <class charT, class traits>\nstruct regex_data : public named_subexpressions\n{\n   typedef regex_constants::syntax_option_type   flag_type;\n   typedef std::size_t                           size_type;  \n\n   regex_data(const ::boost::shared_ptr<\n      ::boost::regex_traits_wrapper<traits> >& t) \n      : m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),\n         m_mark_count(0), m_first_state(0), m_restart_type(0),\n#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))\n         m_startmap{ 0 },\n#endif\n         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}\n   regex_data() \n      : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0), \n         m_mark_count(0), m_first_state(0), m_restart_type(0), \n#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !(defined(BOOST_MSVC) && (BOOST_MSVC < 1900))\n      m_startmap{ 0 },\n#endif\n         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}\n\n   ::boost::shared_ptr<\n      ::boost::regex_traits_wrapper<traits>\n      >                        m_ptraits;                 // traits class instance\n   flag_type                   m_flags;                   // flags with which we were compiled\n   int                         m_status;                  // error code (0 implies OK).\n   const charT*                m_expression;              // the original expression\n   std::ptrdiff_t              m_expression_len;          // the length of the original expression\n   size_type                   m_mark_count;              // the number of marked sub-expressions\n   BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine\n   unsigned                    m_restart_type;            // search optimisation type\n   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match\n   unsigned int                m_can_be_null;             // whether we can match a null string\n   BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed\n   typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character\n   std::vector<\n      std::pair<\n      std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.\n   bool                        m_has_recursions;          // whether we have recursive expressions;\n   bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.\n};\n//\n// class basic_regex_implementation\n// pimpl implementation class for basic_regex.\n//\ntemplate <class charT, class traits>\nclass basic_regex_implementation\n   : public regex_data<charT, traits>\n{\npublic:\n   typedef regex_constants::syntax_option_type   flag_type;\n   typedef std::ptrdiff_t                        difference_type;\n   typedef std::size_t                           size_type; \n   typedef typename traits::locale_type          locale_type;\n   typedef const charT*                          const_iterator;\n\n   basic_regex_implementation(){}\n   basic_regex_implementation(const ::boost::shared_ptr<\n      ::boost::regex_traits_wrapper<traits> >& t)\n      : regex_data<charT, traits>(t) {}\n   void assign(const charT* arg_first,\n                          const charT* arg_last,\n                          flag_type f)\n   {\n      regex_data<charT, traits>* pdat = this;\n      basic_regex_parser<charT, traits> parser(pdat);\n      parser.parse(arg_first, arg_last, f);\n   }\n\n   locale_type BOOST_REGEX_CALL imbue(locale_type l)\n   { \n      return this->m_ptraits->imbue(l); \n   }\n   locale_type BOOST_REGEX_CALL getloc()const\n   { \n      return this->m_ptraits->getloc(); \n   }\n   std::basic_string<charT> BOOST_REGEX_CALL str()const\n   {\n      std::basic_string<charT> result;\n      if(this->m_status == 0)\n         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);\n      return result;\n   }\n   const_iterator BOOST_REGEX_CALL expression()const\n   {\n      return this->m_expression;\n   }\n   std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const\n   {\n      const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);\n      std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);\n      return p;\n   }\n   //\n   // begin, end:\n   const_iterator BOOST_REGEX_CALL begin()const\n   { \n      return (this->m_status ? 0 : this->m_expression); \n   }\n   const_iterator BOOST_REGEX_CALL end()const\n   { \n      return (this->m_status ? 0 : this->m_expression + this->m_expression_len); \n   }\n   flag_type BOOST_REGEX_CALL flags()const\n   {\n      return this->m_flags;\n   }\n   size_type BOOST_REGEX_CALL size()const\n   {\n      return this->m_expression_len;\n   }\n   int BOOST_REGEX_CALL status()const\n   {\n      return this->m_status;\n   }\n   size_type BOOST_REGEX_CALL mark_count()const\n   {\n      return this->m_mark_count - 1;\n   }\n   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const\n   {\n      return this->m_first_state;\n   }\n   unsigned get_restart_type()const\n   {\n      return this->m_restart_type;\n   }\n   const unsigned char* get_map()const\n   {\n      return this->m_startmap;\n   }\n   const ::boost::regex_traits_wrapper<traits>& get_traits()const\n   {\n      return *(this->m_ptraits);\n   }\n   bool can_be_null()const\n   {\n      return this->m_can_be_null;\n   }\n   const regex_data<charT, traits>& get_data()const\n   {\n      basic_regex_implementation<charT, traits> const* p = this;\n      return *static_cast<const regex_data<charT, traits>*>(p);\n   }\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n//\n// class basic_regex:\n// represents the compiled\n// regular expression:\n//\n\n#ifdef BOOST_REGEX_NO_FWD\ntemplate <class charT, class traits = regex_traits<charT> >\n#else\ntemplate <class charT, class traits >\n#endif\nclass basic_regex : public regbase\n{\npublic:\n   // typedefs:\n   typedef std::size_t                           traits_size_type;\n   typedef typename traits::string_type          traits_string_type;\n   typedef charT                                 char_type;\n   typedef traits                                traits_type;\n\n   typedef charT                                 value_type;\n   typedef charT&                                reference;\n   typedef const charT&                          const_reference;\n   typedef const charT*                          const_iterator;\n   typedef const_iterator                        iterator;\n   typedef std::ptrdiff_t                        difference_type;\n   typedef std::size_t                           size_type;   \n   typedef regex_constants::syntax_option_type   flag_type;\n   // locale_type\n   // placeholder for actual locale type used by the\n   // traits class to localise *this.\n   typedef typename traits::locale_type          locale_type;\n   \npublic:\n   explicit basic_regex(){}\n   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)\n   {\n      assign(p, f);\n   }\n   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n   {\n      assign(p1, p2, f);\n   }\n   basic_regex(const charT* p, size_type len, flag_type f)\n   {\n      assign(p, len, f);\n   }\n   basic_regex(const basic_regex& that)\n      : m_pimpl(that.m_pimpl) {}\n   ~basic_regex(){}\n   basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)\n   {\n      return assign(that);\n   }\n   basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)\n   {\n      return assign(ptr);\n   }\n\n   //\n   // assign:\n   basic_regex& assign(const basic_regex& that)\n   { \n      m_pimpl = that.m_pimpl;\n      return *this; \n   }\n   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)\n   {\n      return assign(p, p + traits::length(p), f);\n   }\n   basic_regex& assign(const charT* p, size_type len, flag_type f)\n   {\n      return assign(p, p + len, f);\n   }\nprivate:\n   basic_regex& do_assign(const charT* p1,\n                          const charT* p2,\n                          flag_type f);\npublic:\n   basic_regex& assign(const charT* p1,\n                          const charT* p2,\n                          flag_type f = regex_constants::normal)\n   {\n      return do_assign(p1, p2, f);\n   }\n#if !defined(BOOST_NO_MEMBER_TEMPLATES)\n\n   template <class ST, class SA>\n   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   { \n      return set_expression(p.data(), p.data() + p.size(), f); \n   }\n\n   template <class ST, class SA>\n   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   { \n      assign(p, f); \n   }\n\n   template <class InputIterator>\n   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)\n   {\n      typedef typename traits::string_type seq_type;\n      seq_type a(arg_first, arg_last);\n      if(!a.empty())\n         assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);\n      else\n         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);\n   }\n\n   template <class ST, class SA>\n   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)\n   {\n      return assign(p.data(), p.data() + p.size(), regex_constants::normal);\n   }\n\n   template <class string_traits, class A>\n   basic_regex& BOOST_REGEX_CALL assign(\n       const std::basic_string<charT, string_traits, A>& s,\n       flag_type f = regex_constants::normal)\n   {\n      return assign(s.data(), s.data() + s.size(), f);\n   }\n\n   template <class InputIterator>\n   basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,\n                          InputIterator arg_last,\n                          flag_type f = regex_constants::normal)\n   {\n      typedef typename traits::string_type seq_type;\n      seq_type a(arg_first, arg_last);\n      if(a.size())\n      {\n         const charT* p1 = &*a.begin();\n         const charT* p2 = &*a.begin() + a.size();\n         return assign(p1, p2, f);\n      }\n      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);\n   }\n#else\n   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)\n   { \n      return set_expression(p.data(), p.data() + p.size(), f); \n   }\n\n   basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)\n   { \n      assign(p, f); \n   }\n\n   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)\n   {\n      return assign(p.data(), p.data() + p.size(), regex_constants::normal);\n   }\n\n   basic_regex& BOOST_REGEX_CALL assign(\n       const std::basic_string<charT>& s,\n       flag_type f = regex_constants::normal)\n   {\n      return assign(s.data(), s.data() + s.size(), f);\n   }\n\n#endif\n\n   //\n   // locale:\n   locale_type BOOST_REGEX_CALL imbue(locale_type l);\n   locale_type BOOST_REGEX_CALL getloc()const\n   { \n      return m_pimpl.get() ? m_pimpl->getloc() : locale_type(); \n   }\n   //\n   // getflags:\n   // retained for backwards compatibility only, \"flags\"\n   // is now the preferred name:\n   flag_type BOOST_REGEX_CALL getflags()const\n   { \n      return flags();\n   }\n   flag_type BOOST_REGEX_CALL flags()const\n   { \n      return m_pimpl.get() ? m_pimpl->flags() : 0;\n   }\n   //\n   // str:\n   std::basic_string<charT> BOOST_REGEX_CALL str()const\n   {\n      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();\n   }\n   //\n   // begin, end, subexpression:\n   std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const\n   {\n      if(!m_pimpl.get())\n         boost::throw_exception(std::logic_error(\"Can't access subexpressions in an invalid regex.\"));\n      return m_pimpl->subexpression(n);\n   }\n   const_iterator BOOST_REGEX_CALL begin()const\n   { \n      return (m_pimpl.get() ? m_pimpl->begin() : 0); \n   }\n   const_iterator BOOST_REGEX_CALL end()const\n   { \n      return (m_pimpl.get() ? m_pimpl->end() : 0); \n   }\n   //\n   // swap:\n   void BOOST_REGEX_CALL swap(basic_regex& that)throw()\n   {\n      m_pimpl.swap(that.m_pimpl);\n   }\n   //\n   // size:\n   size_type BOOST_REGEX_CALL size()const\n   { \n      return (m_pimpl.get() ? m_pimpl->size() : 0); \n   }\n   //\n   // max_size:\n   size_type BOOST_REGEX_CALL max_size()const\n   { \n      return UINT_MAX; \n   }\n   //\n   // empty:\n   bool BOOST_REGEX_CALL empty()const\n   { \n      return (m_pimpl.get() ? 0 != m_pimpl->status() : true); \n   }\n\n   size_type BOOST_REGEX_CALL mark_count()const \n   { \n      return (m_pimpl.get() ? m_pimpl->mark_count() : 0); \n   }\n\n   int status()const\n   {\n      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);\n   }\n\n   int BOOST_REGEX_CALL compare(const basic_regex& that) const\n   {\n      if(m_pimpl.get() == that.m_pimpl.get())\n         return 0;\n      if(!m_pimpl.get())\n         return -1;\n      if(!that.m_pimpl.get())\n         return 1;\n      if(status() != that.status())\n         return status() - that.status();\n      if(flags() != that.flags())\n         return flags() - that.flags();\n      return str().compare(that.str());\n   }\n   bool BOOST_REGEX_CALL operator==(const basic_regex& e)const\n   { \n      return compare(e) == 0; \n   }\n   bool BOOST_REGEX_CALL operator != (const basic_regex& e)const\n   { \n      return compare(e) != 0; \n   }\n   bool BOOST_REGEX_CALL operator<(const basic_regex& e)const\n   { \n      return compare(e) < 0; \n   }\n   bool BOOST_REGEX_CALL operator>(const basic_regex& e)const\n   { \n      return compare(e) > 0; \n   }\n   bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const\n   { \n      return compare(e) <= 0; \n   }\n   bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const\n   { \n      return compare(e) >= 0; \n   }\n\n   //\n   // The following are deprecated as public interfaces\n   // but are available for compatibility with earlier versions.\n   const charT* BOOST_REGEX_CALL expression()const \n   { \n      return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0); \n   }\n   unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n   {\n      assign(p1, p2, f | regex_constants::no_except);\n      return status();\n   }\n   unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal) \n   { \n      assign(p, f | regex_constants::no_except); \n      return status();\n   }\n   unsigned int BOOST_REGEX_CALL error_code()const\n   {\n      return status();\n   }\n   //\n   // private access methods:\n   //\n   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_first_state();\n   }\n   unsigned get_restart_type()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_restart_type();\n   }\n   const unsigned char* get_map()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_map();\n   }\n   const ::boost::regex_traits_wrapper<traits>& get_traits()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_traits();\n   }\n   bool can_be_null()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->can_be_null();\n   }\n   const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_data();\n   }\n   boost::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const\n   {\n      return m_pimpl;\n   }\n\nprivate:\n   shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;\n};\n\n//\n// out of line members;\n// these are the only members that mutate the basic_regex object,\n// and are designed to provide the strong exception guarantee\n// (in the event of a throw, the state of the object remains unchanged).\n//\ntemplate <class charT, class traits>\nbasic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,\n                        const charT* p2,\n                        flag_type f)\n{\n   shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;\n   if(!m_pimpl.get())\n   {\n      temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());\n   }\n   else\n   {\n      temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));\n   }\n   temp->assign(p1, p2, f);\n   temp.swap(m_pimpl);\n   return *this;\n}\n\ntemplate <class charT, class traits>\ntypename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)\n{ \n   shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());\n   locale_type result = temp->imbue(l);\n   temp.swap(m_pimpl);\n   return result;\n}\n\n//\n// non-members:\n//\ntemplate <class charT, class traits>\nvoid swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)\n{\n   e1.swap(e2);\n}\n\n#ifndef BOOST_NO_STD_LOCALE\ntemplate <class charT, class traits, class traits2>\nstd::basic_ostream<charT, traits>& \n   operator << (std::basic_ostream<charT, traits>& os, \n                const basic_regex<charT, traits2>& e)\n{\n   return (os << e.str());\n}\n#else\ntemplate <class traits>\nstd::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)\n{\n   return (os << e.str());\n}\n#endif\n\n//\n// class reg_expression:\n// this is provided for backwards compatibility only,\n// it is deprecated, no not use!\n//\n#ifdef BOOST_REGEX_NO_FWD\ntemplate <class charT, class traits = regex_traits<charT> >\n#else\ntemplate <class charT, class traits >\n#endif\nclass reg_expression : public basic_regex<charT, traits>\n{\npublic:\n   typedef typename basic_regex<charT, traits>::flag_type flag_type;\n   typedef typename basic_regex<charT, traits>::size_type size_type;\n   explicit reg_expression(){}\n   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)\n      : basic_regex<charT, traits>(p, f){}\n   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n      : basic_regex<charT, traits>(p1, p2, f){}\n   reg_expression(const charT* p, size_type len, flag_type f)\n      : basic_regex<charT, traits>(p, len, f){}\n   reg_expression(const reg_expression& that)\n      : basic_regex<charT, traits>(that) {}\n   ~reg_expression(){}\n   reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)\n   {\n      return this->assign(that);\n   }\n\n#if !defined(BOOST_NO_MEMBER_TEMPLATES)\n   template <class ST, class SA>\n   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   : basic_regex<charT, traits>(p, f)\n   { \n   }\n\n   template <class InputIterator>\n   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)\n   : basic_regex<charT, traits>(arg_first, arg_last, f)\n   {\n   }\n\n   template <class ST, class SA>\n   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)\n   {\n      this->assign(p);\n      return *this;\n   }\n#else\n   explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)\n   : basic_regex<charT, traits>(p, f)\n   { \n   }\n\n   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)\n   {\n      this->assign(p);\n      return *this;\n   }\n#endif\n\n};\n\n#ifdef BOOST_MSVC\n#pragma warning (pop)\n#endif\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/basic_regex_creator.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_creator.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_creator which fills in\n  *                the data members of a regex_data object.\n  */\n\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP\n#define BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP\n\n#include <boost/regex/v4/indexed_bit_flag.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class charT>\nstruct digraph : public std::pair<charT, charT>\n{\n   digraph() : std::pair<charT, charT>(charT(0), charT(0)){}\n   digraph(charT c1) : std::pair<charT, charT>(c1, charT(0)){}\n   digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)\n   {}\n   digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}\n#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS\n   digraph<charT>& operator=(const digraph<charT>&) = default;\n#endif\n   template <class Seq>\n   digraph(const Seq& s) : std::pair<charT, charT>()\n   {\n      BOOST_REGEX_ASSERT(s.size() <= 2);\n      BOOST_REGEX_ASSERT(s.size());\n      this->first = s[0];\n      this->second = (s.size() > 1) ? s[1] : 0;\n   }\n};\n\ntemplate <class charT, class traits>\nclass basic_char_set\n{\npublic:\n   typedef digraph<charT>                   digraph_type;\n   typedef typename traits::string_type     string_type;\n   typedef typename traits::char_class_type m_type;\n\n   basic_char_set()\n   {\n      m_negate = false;\n      m_has_digraphs = false;\n      m_classes = 0;\n      m_negated_classes = 0;\n      m_empty = true;\n   }\n\n   void add_single(const digraph_type& s)\n   {\n      m_singles.insert(s);\n      if(s.second)\n         m_has_digraphs = true;\n      m_empty = false;\n   }\n   void add_range(const digraph_type& first, const digraph_type& end)\n   {\n      m_ranges.push_back(first);\n      m_ranges.push_back(end);\n      if(first.second)\n      {\n         m_has_digraphs = true;\n         add_single(first);\n      }\n      if(end.second)\n      {\n         m_has_digraphs = true;\n         add_single(end);\n      }\n      m_empty = false;\n   }\n   void add_class(m_type m)\n   {\n      m_classes |= m;\n      m_empty = false;\n   }\n   void add_negated_class(m_type m)\n   {\n      m_negated_classes |= m;\n      m_empty = false;\n   }\n   void add_equivalent(const digraph_type& s)\n   {\n      m_equivalents.insert(s);\n      if(s.second)\n      {\n         m_has_digraphs = true;\n         add_single(s);\n      }\n      m_empty = false;\n   }\n   void negate()\n   { \n      m_negate = true;\n      //m_empty = false;\n   }\n\n   //\n   // accessor functions:\n   //\n   bool has_digraphs()const\n   {\n      return m_has_digraphs;\n   }\n   bool is_negated()const\n   {\n      return m_negate;\n   }\n   typedef typename std::vector<digraph_type>::const_iterator  list_iterator;\n   typedef typename std::set<digraph_type>::const_iterator     set_iterator;\n   set_iterator singles_begin()const\n   {\n      return m_singles.begin();\n   }\n   set_iterator singles_end()const\n   {\n      return m_singles.end();\n   }\n   list_iterator ranges_begin()const\n   {\n      return m_ranges.begin();\n   }\n   list_iterator ranges_end()const\n   {\n      return m_ranges.end();\n   }\n   set_iterator equivalents_begin()const\n   {\n      return m_equivalents.begin();\n   }\n   set_iterator equivalents_end()const\n   {\n      return m_equivalents.end();\n   }\n   m_type classes()const\n   {\n      return m_classes;\n   }\n   m_type negated_classes()const\n   {\n      return m_negated_classes;\n   }\n   bool empty()const\n   {\n      return m_empty;\n   }\nprivate:\n   std::set<digraph_type>    m_singles;         // a list of single characters to match\n   std::vector<digraph_type> m_ranges;          // a list of end points of our ranges\n   bool                      m_negate;          // true if the set is to be negated\n   bool                      m_has_digraphs;    // true if we have digraphs present\n   m_type                    m_classes;         // character classes to match\n   m_type                    m_negated_classes; // negated character classes to match\n   bool                      m_empty;           // whether we've added anything yet\n   std::set<digraph_type>    m_equivalents;     // a list of equivalence classes\n};\n   \ntemplate <class charT, class traits>\nclass basic_regex_creator\n{\npublic:\n   basic_regex_creator(regex_data<charT, traits>* data);\n   std::ptrdiff_t getoffset(void* addr)\n   {\n      return getoffset(addr, m_pdata->m_data.data());\n   }\n   std::ptrdiff_t getoffset(const void* addr, const void* base)\n   {\n      return static_cast<const char*>(addr) - static_cast<const char*>(base);\n   }\n   re_syntax_base* getaddress(std::ptrdiff_t off)\n   {\n      return getaddress(off, m_pdata->m_data.data());\n   }\n   re_syntax_base* getaddress(std::ptrdiff_t off, void* base)\n   {\n      return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));\n   }\n   void init(unsigned l_flags)\n   {\n      m_pdata->m_flags = l_flags;\n      m_icase = l_flags & regex_constants::icase;\n   }\n   regbase::flag_type flags()\n   {\n      return m_pdata->m_flags;\n   }\n   void flags(regbase::flag_type f)\n   {\n      m_pdata->m_flags = f;\n      if(m_icase != static_cast<bool>(f & regbase::icase))\n      {\n         m_icase = static_cast<bool>(f & regbase::icase);\n      }\n   }\n   re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));\n   re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));\n   re_literal* append_literal(charT c);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::false_*);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, mpl::true_*);\n   void finalize(const charT* p1, const charT* p2);\nprotected:\n   regex_data<charT, traits>*    m_pdata;              // pointer to the basic_regex_data struct we are filling in\n   const ::boost::regex_traits_wrapper<traits>&  \n                                 m_traits;             // convenience reference to traits class\n   re_syntax_base*               m_last_state;         // the last state we added\n   bool                          m_icase;              // true for case insensitive matches\n   unsigned                      m_repeater_id;        // the state_id of the next repeater\n   bool                          m_has_backrefs;       // true if there are actually any backrefs\n   indexed_bit_flag              m_backrefs;           // bitmask of permitted backrefs\n   boost::uintmax_t              m_bad_repeats;        // bitmask of repeats we can't deduce a startmap for;\n   bool                          m_has_recursions;     // set when we have recursive expressions to fixup\n   std::vector<unsigned char>    m_recursion_checks;   // notes which recursions we've followed while analysing this expression\n   typename traits::char_class_type m_word_mask;       // mask used to determine if a character is a word character\n   typename traits::char_class_type m_mask_space;      // mask used to determine if a character is a word character\n   typename traits::char_class_type m_lower_mask;       // mask used to determine if a character is a lowercase character\n   typename traits::char_class_type m_upper_mask;      // mask used to determine if a character is an uppercase character\n   typename traits::char_class_type m_alpha_mask;      // mask used to determine if a character is an alphabetic character\nprivate:\n   basic_regex_creator& operator=(const basic_regex_creator&);\n   basic_regex_creator(const basic_regex_creator&);\n\n   void fixup_pointers(re_syntax_base* state);\n   void fixup_recursions(re_syntax_base* state);\n   void create_startmaps(re_syntax_base* state);\n   int calculate_backstep(re_syntax_base* state);\n   void create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask);\n   unsigned get_restart_type(re_syntax_base* state);\n   void set_all_masks(unsigned char* bits, unsigned char);\n   bool is_bad_repeat(re_syntax_base* pt);\n   void set_bad_repeat(re_syntax_base* pt);\n   syntax_element_type get_repeat_type(re_syntax_base* state);\n   void probe_leading_repeat(re_syntax_base* state);\n};\n\ntemplate <class charT, class traits>\nbasic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)\n   : m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_icase(false), m_repeater_id(0), \n   m_has_backrefs(false), m_bad_repeats(0), m_has_recursions(false), m_word_mask(0), m_mask_space(0), m_lower_mask(0), m_upper_mask(0), m_alpha_mask(0)\n{\n   m_pdata->m_data.clear();\n   m_pdata->m_status = ::boost::regex_constants::error_ok;\n   static const charT w = 'w';\n   static const charT s = 's';\n   static const charT l[5] = { 'l', 'o', 'w', 'e', 'r', };\n   static const charT u[5] = { 'u', 'p', 'p', 'e', 'r', };\n   static const charT a[5] = { 'a', 'l', 'p', 'h', 'a', };\n   m_word_mask = m_traits.lookup_classname(&w, &w +1);\n   m_mask_space = m_traits.lookup_classname(&s, &s +1);\n   m_lower_mask = m_traits.lookup_classname(l, l + 5);\n   m_upper_mask = m_traits.lookup_classname(u, u + 5);\n   m_alpha_mask = m_traits.lookup_classname(a, a + 5);\n   m_pdata->m_word_mask = m_word_mask;\n   BOOST_REGEX_ASSERT(m_word_mask != 0); \n   BOOST_REGEX_ASSERT(m_mask_space != 0); \n   BOOST_REGEX_ASSERT(m_lower_mask != 0); \n   BOOST_REGEX_ASSERT(m_upper_mask != 0); \n   BOOST_REGEX_ASSERT(m_alpha_mask != 0); \n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)\n{\n   // if the state is a backref then make a note of it:\n   if(t == syntax_element_backref)\n      this->m_has_backrefs = true;\n   // append a new state, start by aligning our last one:\n   m_pdata->m_data.align();\n   // set the offset to the next state in our last one:\n   if(m_last_state)\n      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);\n   // now actually extend our data:\n   m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));\n   // fill in boilerplate options in the new state:\n   m_last_state->next.i = 0;\n   m_last_state->type = t;\n   return m_last_state;\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)\n{\n   // append a new state, start by aligning our last one:\n   m_pdata->m_data.align();\n   // set the offset to the next state in our last one:\n   if(m_last_state)\n      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);\n   // remember the last state position:\n   std::ptrdiff_t off = getoffset(m_last_state) + s;\n   // now actually insert our data:\n   re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));\n   // fill in boilerplate options in the new state:\n   new_state->next.i = s;\n   new_state->type = t;\n   m_last_state = getaddress(off);\n   return new_state;\n}\n\ntemplate <class charT, class traits>\nre_literal* basic_regex_creator<charT, traits>::append_literal(charT c)\n{\n   re_literal* result;\n   // start by seeing if we have an existing re_literal we can extend:\n   if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))\n   {\n      // no existing re_literal, create a new one:\n      result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));\n      result->length = 1;\n      *static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);\n   }\n   else\n   {\n      // we have an existing re_literal, extend it:\n      std::ptrdiff_t off = getoffset(m_last_state);\n      m_pdata->m_data.extend(sizeof(charT));\n      m_last_state = result = static_cast<re_literal*>(getaddress(off));\n      charT* characters = static_cast<charT*>(static_cast<void*>(result+1));\n      characters[result->length] = m_traits.translate(c, m_icase);\n      result->length += 1;\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\ninline re_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set)\n{\n   typedef mpl::bool_< (sizeof(charT) == 1) > truth_type;\n   return char_set.has_digraphs() \n      ? append_set(char_set, static_cast<mpl::false_*>(0))\n      : append_set(char_set, static_cast<truth_type*>(0));\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set, mpl::false_*)\n{\n   typedef typename traits::string_type string_type;\n   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;\n   typedef typename basic_char_set<charT, traits>::set_iterator  set_iterator;\n   typedef typename traits::char_class_type m_type;\n   \n   re_set_long<m_type>* result = static_cast<re_set_long<m_type>*>(append_state(syntax_element_long_set, sizeof(re_set_long<m_type>)));\n   //\n   // fill in the basics:\n   //\n   result->csingles = static_cast<unsigned int>(::boost::BOOST_REGEX_DETAIL_NS::distance(char_set.singles_begin(), char_set.singles_end()));\n   result->cranges = static_cast<unsigned int>(::boost::BOOST_REGEX_DETAIL_NS::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;\n   result->cequivalents = static_cast<unsigned int>(::boost::BOOST_REGEX_DETAIL_NS::distance(char_set.equivalents_begin(), char_set.equivalents_end()));\n   result->cclasses = char_set.classes();\n   result->cnclasses = char_set.negated_classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust classes as needed:\n      if(((result->cclasses & m_lower_mask) == m_lower_mask) || ((result->cclasses & m_upper_mask) == m_upper_mask))\n         result->cclasses |= m_alpha_mask;\n      if(((result->cnclasses & m_lower_mask) == m_lower_mask) || ((result->cnclasses & m_upper_mask) == m_upper_mask))\n         result->cnclasses |= m_alpha_mask;\n   }\n\n   result->isnot = char_set.is_negated();\n   result->singleton = !char_set.has_digraphs();\n   //\n   // remember where the state is for later:\n   //\n   std::ptrdiff_t offset = getoffset(result);\n   //\n   // now extend with all the singles:\n   //\n   item_iterator first, last;\n   set_iterator sfirst, slast;\n   sfirst = char_set.singles_begin();\n   slast = char_set.singles_end();\n   while(sfirst != slast)\n   {\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (sfirst->first == static_cast<charT>(0) ? 1 : sfirst->second ? 3 : 2)));\n      p[0] = m_traits.translate(sfirst->first, m_icase);\n      if(sfirst->first == static_cast<charT>(0))\n      {\n         p[0] = 0;\n      }\n      else if(sfirst->second)\n      {\n         p[1] = m_traits.translate(sfirst->second, m_icase);\n         p[2] = 0;\n      }\n      else\n         p[1] = 0;\n      ++sfirst;\n   }\n   //\n   // now extend with all the ranges:\n   //\n   first = char_set.ranges_begin();\n   last = char_set.ranges_end();\n   while(first != last)\n   {\n      // first grab the endpoints of the range:\n      digraph<charT> c1 = *first;\n      c1.first = this->m_traits.translate(c1.first, this->m_icase);\n      c1.second = this->m_traits.translate(c1.second, this->m_icase);\n      ++first;\n      digraph<charT> c2 = *first;\n      c2.first = this->m_traits.translate(c2.first, this->m_icase);\n      c2.second = this->m_traits.translate(c2.second, this->m_icase);\n      ++first;\n      string_type s1, s2;\n      // different actions now depending upon whether collation is turned on:\n      if(flags() & regex_constants::collate)\n      {\n         // we need to transform our range into sort keys:\n         charT a1[3] = { c1.first, c1.second, charT(0), };\n         charT a2[3] = { c2.first, c2.second, charT(0), };\n         s1 = this->m_traits.transform(a1, (a1[1] ? a1+2 : a1+1));\n         s2 = this->m_traits.transform(a2, (a2[1] ? a2+2 : a2+1));\n         if(s1.empty())\n            s1 = string_type(1, charT(0));\n         if(s2.empty())\n            s2 = string_type(1, charT(0));\n      }\n      else\n      {\n         if(c1.second)\n         {\n            s1.insert(s1.end(), c1.first);\n            s1.insert(s1.end(), c1.second);\n         }\n         else\n            s1 = string_type(1, c1.first);\n         if(c2.second)\n         {\n            s2.insert(s2.end(), c2.first);\n            s2.insert(s2.end(), c2.second);\n         }\n         else\n            s2.insert(s2.end(), c2.first);\n      }\n      if(s1 > s2)\n      {\n         // Oops error:\n         return 0;\n      }\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );\n      BOOST_REGEX_DETAIL_NS::copy(s1.begin(), s1.end(), p);\n      p[s1.size()] = charT(0);\n      p += s1.size() + 1;\n      BOOST_REGEX_DETAIL_NS::copy(s2.begin(), s2.end(), p);\n      p[s2.size()] = charT(0);\n   }\n   //\n   // now process the equivalence classes:\n   //\n   sfirst = char_set.equivalents_begin();\n   slast = char_set.equivalents_end();\n   while(sfirst != slast)\n   {\n      string_type s;\n      if(sfirst->second)\n      {\n         charT cs[3] = { sfirst->first, sfirst->second, charT(0), };\n         s = m_traits.transform_primary(cs, cs+2);\n      }\n      else\n         s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);\n      if(s.empty())\n         return 0;  // invalid or unsupported equivalence class\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );\n      BOOST_REGEX_DETAIL_NS::copy(s.begin(), s.end(), p);\n      p[s.size()] = charT(0);\n      ++sfirst;\n   }\n   //\n   // finally reset the address of our last state:\n   //\n   m_last_state = result = static_cast<re_set_long<m_type>*>(getaddress(offset));\n   return result;\n}\n\ntemplate<class T>\ninline bool char_less(T t1, T t2)\n{\n   return t1 < t2;\n}\ninline bool char_less(char t1, char t2)\n{\n   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);\n}\ninline bool char_less(signed char t1, signed char t2)\n{\n   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set, mpl::true_*)\n{\n   typedef typename traits::string_type string_type;\n   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;\n   typedef typename basic_char_set<charT, traits>::set_iterator set_iterator;\n\n   re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));\n   bool negate = char_set.is_negated();\n   std::memset(result->_map, 0, sizeof(result->_map));\n   //\n   // handle singles first:\n   //\n   item_iterator first, last;\n   set_iterator sfirst, slast;\n   sfirst = char_set.singles_begin();\n   slast = char_set.singles_end();\n   while(sfirst != slast)\n   {\n      for(unsigned int i = 0; i < (1 << CHAR_BIT); ++i)\n      {\n         if(this->m_traits.translate(static_cast<charT>(i), this->m_icase)\n            == this->m_traits.translate(sfirst->first, this->m_icase))\n            result->_map[i] = true;\n      }\n      ++sfirst;\n   }\n   //\n   // OK now handle ranges:\n   //\n   first = char_set.ranges_begin();\n   last = char_set.ranges_end();\n   while(first != last)\n   {\n      // first grab the endpoints of the range:\n      charT c1 = this->m_traits.translate(first->first, this->m_icase);\n      ++first;\n      charT c2 = this->m_traits.translate(first->first, this->m_icase);\n      ++first;\n      // different actions now depending upon whether collation is turned on:\n      if(flags() & regex_constants::collate)\n      {\n         // we need to transform our range into sort keys:\n         charT c3[2] = { c1, charT(0), };\n         string_type s1 = this->m_traits.transform(c3, c3+1);\n         c3[0] = c2;\n         string_type s2 = this->m_traits.transform(c3, c3+1);\n         if(s1 > s2)\n         {\n            // Oops error:\n            return 0;\n         }\n         BOOST_REGEX_ASSERT(c3[1] == charT(0));\n         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n         {\n            c3[0] = static_cast<charT>(i);\n            string_type s3 = this->m_traits.transform(c3, c3 +1);\n            if((s1 <= s3) && (s3 <= s2))\n               result->_map[i] = true;\n         }\n      }\n      else\n      {\n         if(char_less(c2, c1))\n         {\n            // Oops error:\n            return 0;\n         }\n         // everything in range matches:\n         std::memset(result->_map + static_cast<unsigned char>(c1), true, static_cast<unsigned char>(1u) + static_cast<unsigned char>(static_cast<unsigned char>(c2) - static_cast<unsigned char>(c1)));\n      }\n   }\n   //\n   // and now the classes:\n   //\n   typedef typename traits::char_class_type m_type;\n   m_type m = char_set.classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust m as needed:\n      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))\n         m |= m_alpha_mask;\n   }\n   if(m != 0)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         if(this->m_traits.isctype(static_cast<charT>(i), m))\n            result->_map[i] = true;\n      }\n   }\n   //\n   // and now the negated classes:\n   //\n   m = char_set.negated_classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust m as needed:\n      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))\n         m |= m_alpha_mask;\n   }\n   if(m != 0)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         if(0 == this->m_traits.isctype(static_cast<charT>(i), m))\n            result->_map[i] = true;\n      }\n   }\n   //\n   // now process the equivalence classes:\n   //\n   sfirst = char_set.equivalents_begin();\n   slast = char_set.equivalents_end();\n   while(sfirst != slast)\n   {\n      string_type s;\n      BOOST_REGEX_ASSERT(static_cast<charT>(0) == sfirst->second);\n      s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);\n      if(s.empty())\n         return 0;  // invalid or unsupported equivalence class\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         charT c[2] = { (static_cast<charT>(i)), charT(0), };\n         string_type s2 = this->m_traits.transform_primary(c, c+1);\n         if(s == s2)\n            result->_map[i] = true;\n      }\n      ++sfirst;\n   }\n   if(negate)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         result->_map[i] = !(result->_map[i]);\n      }\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)\n{\n   if(this->m_pdata->m_status)\n      return;\n   // we've added all the states we need, now finish things off.\n   // start by adding a terminating state:\n   append_state(syntax_element_match);\n   // extend storage to store original expression:\n   std::ptrdiff_t len = p2 - p1;\n   m_pdata->m_expression_len = len;\n   charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));\n   m_pdata->m_expression = ps;\n   BOOST_REGEX_DETAIL_NS::copy(p1, p2, ps);\n   ps[p2 - p1] = 0;\n   // fill in our other data...\n   // successful parsing implies a zero status:\n   m_pdata->m_status = 0;\n   // get the first state of the machine:\n   m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());\n   // fixup pointers in the machine:\n   fixup_pointers(m_pdata->m_first_state);\n   if(m_has_recursions)\n   {\n      m_pdata->m_has_recursions = true;\n      fixup_recursions(m_pdata->m_first_state);\n      if(this->m_pdata->m_status)\n         return;\n   }\n   else\n      m_pdata->m_has_recursions = false;\n   // create nested startmaps:\n   create_startmaps(m_pdata->m_first_state);\n   // create main startmap:\n   std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));\n   m_pdata->m_can_be_null = 0;\n\n   m_bad_repeats = 0;\n   if(m_has_recursions)\n      m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n   create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all);\n   // get the restart type:\n   m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);\n   // optimise a leading repeat if there is one:\n   probe_leading_repeat(m_pdata->m_first_state);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)\n{\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_recurse:\n         m_has_recursions = true;\n         if(state->next.i)\n            state->next.p = getaddress(state->next.i, state);\n         else\n            state->next.p = 0;\n         break;\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         // set the state_id of this repeat:\n         static_cast<re_repeat*>(state)->state_id = m_repeater_id++;\n         BOOST_FALLTHROUGH;\n      case syntax_element_alt:\n         std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));\n         static_cast<re_alt*>(state)->can_be_null = 0;\n         BOOST_FALLTHROUGH;\n      case syntax_element_jump:\n         static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);\n         BOOST_FALLTHROUGH;\n      default:\n         if(state->next.i)\n            state->next.p = getaddress(state->next.i, state);\n         else\n            state->next.p = 0;\n      }\n      state = state->next.p;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state)\n{\n   re_syntax_base* base = state;\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_assert_backref:\n         {\n            // just check that the index is valid:\n            int idx = static_cast<const re_brace*>(state)->index;\n            if(idx < 0)\n            {\n               idx = -idx-1;\n               if(idx >= hash_value_mask)\n               {\n                  idx = m_pdata->get_id(idx);\n                  if(idx <= 0)\n                  {\n                     // check of sub-expression that doesn't exist:\n                     if(0 == this->m_pdata->m_status) // update the error code if not already set\n                        this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n                     //\n                     // clear the expression, we should be empty:\n                     //\n                     this->m_pdata->m_expression = 0;\n                     this->m_pdata->m_expression_len = 0;\n                     //\n                     // and throw if required:\n                     //\n                     if(0 == (this->flags() & regex_constants::no_except))\n                     {\n                        std::string message = \"Encountered a forward reference to a marked sub-expression that does not exist.\";\n                        boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                        e.raise();\n                     }\n                  }\n               }\n            }\n         }\n         break;\n      case syntax_element_recurse:\n         {\n            bool ok = false;\n            re_syntax_base* p = base;\n            std::ptrdiff_t idx = static_cast<re_jump*>(state)->alt.i;\n            if(idx >= hash_value_mask)\n            {\n               //\n               // There may be more than one capture group with this hash, just do what Perl\n               // does and recurse to the leftmost:\n               //\n               idx = m_pdata->get_id(static_cast<int>(idx));\n            }\n            if(idx < 0)\n            {\n               ok = false;\n            }\n            else\n            {\n               while(p)\n               {\n                  if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idx))\n                  {\n                     //\n                     // We've found the target of the recursion, set the jump target:\n                     //\n                     static_cast<re_jump*>(state)->alt.p = p;\n                     ok = true;\n                     // \n                     // Now scan the target for nested repeats:\n                     //\n                     p = p->next.p;\n                     int next_rep_id = 0;\n                     while(p)\n                     {\n                        switch(p->type)\n                        {\n                        case syntax_element_rep:\n                        case syntax_element_dot_rep:\n                        case syntax_element_char_rep:\n                        case syntax_element_short_set_rep:\n                        case syntax_element_long_set_rep:\n                           next_rep_id = static_cast<re_repeat*>(p)->state_id;\n                           break;\n                        case syntax_element_endmark:\n                           if(static_cast<const re_brace*>(p)->index == idx)\n                              next_rep_id = -1;\n                           break;\n                        default:\n                           break;\n                        }\n                        if(next_rep_id)\n                           break;\n                        p = p->next.p;\n                     }\n                     if(next_rep_id > 0)\n                     {\n                        static_cast<re_recurse*>(state)->state_id = next_rep_id - 1;\n                     }\n\n                     break;\n                  }\n                  p = p->next.p;\n               }\n            }\n            if(!ok)\n            {\n               // recursion to sub-expression that doesn't exist:\n               if(0 == this->m_pdata->m_status) // update the error code if not already set\n                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n               //\n               // clear the expression, we should be empty:\n               //\n               this->m_pdata->m_expression = 0;\n               this->m_pdata->m_expression_len = 0;\n               //\n               // and throw if required:\n               //\n               if(0 == (this->flags() & regex_constants::no_except))\n               {\n                  std::string message = \"Encountered a forward reference to a recursive sub-expression that does not exist.\";\n                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                  e.raise();\n               }\n            }\n         }\n         break;\n      default:\n         break;\n      }\n      state = state->next.p;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)\n{\n   // non-recursive implementation:\n   // create the last map in the machine first, so that earlier maps\n   // can make use of the result...\n   //\n   // This was originally a recursive implementation, but that caused stack\n   // overflows with complex expressions on small stacks (think COM+).\n\n   // start by saving the case setting:\n   bool l_icase = m_icase;\n   std::vector<std::pair<bool, re_syntax_base*> > v;\n\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_toggle_case:\n         // we need to track case changes here:\n         m_icase = static_cast<re_case*>(state)->icase;\n         state = state->next.p;\n         continue;\n      case syntax_element_alt:\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         // just push the state onto our stack for now:\n         v.push_back(std::pair<bool, re_syntax_base*>(m_icase, state));\n         state = state->next.p;\n         break;\n      case syntax_element_backstep:\n         // we need to calculate how big the backstep is:\n         static_cast<re_brace*>(state)->index\n            = this->calculate_backstep(state->next.p);\n         if(static_cast<re_brace*>(state)->index < 0)\n         {\n            // Oops error:\n            if(0 == this->m_pdata->m_status) // update the error code if not already set\n               this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n            //\n            // clear the expression, we should be empty:\n            //\n            this->m_pdata->m_expression = 0;\n            this->m_pdata->m_expression_len = 0;\n            //\n            // and throw if required:\n            //\n            if(0 == (this->flags() & regex_constants::no_except))\n            {\n               std::string message = \"Invalid lookbehind assertion encountered in the regular expression.\";\n               boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n               e.raise();\n            }\n         }\n         BOOST_FALLTHROUGH;\n      default:\n         state = state->next.p;\n      }\n   }\n\n   // now work through our list, building all the maps as we go:\n   while(!v.empty())\n   {\n      // Initialize m_recursion_checks if we need it:\n      if(m_has_recursions)\n         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n\n      const std::pair<bool, re_syntax_base*>& p = v.back();\n      m_icase = p.first;\n      state = p.second;\n      v.pop_back();\n\n      // Build maps:\n      m_bad_repeats = 0;\n      create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);\n      m_bad_repeats = 0;\n\n      if(m_has_recursions)\n         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n      create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);\n      // adjust the type of the state to allow for faster matching:\n      state->type = this->get_repeat_type(state);\n   }\n   // restore case sensitivity:\n   m_icase = l_icase;\n}\n\ntemplate <class charT, class traits>\nint basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)\n{\n   typedef typename traits::char_class_type m_type;\n   int result = 0;\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n         {\n            state = static_cast<re_jump*>(state->next.p)->alt.p->next.p;\n            continue;\n         }\n         else if(static_cast<re_brace*>(state)->index == -3)\n         {\n            state = state->next.p->next.p;\n            continue;\n         }\n         break;\n      case syntax_element_endmark:\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n            return result;\n         break;\n      case syntax_element_literal:\n         result += static_cast<re_literal*>(state)->length;\n         break;\n      case syntax_element_wild:\n      case syntax_element_set:\n         result += 1;\n         break;\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_backref:\n      case syntax_element_rep:\n      case syntax_element_combining:\n      case syntax_element_long_set_rep:\n      case syntax_element_backstep:\n         {\n            re_repeat* rep = static_cast<re_repeat *>(state);\n            // adjust the type of the state to allow for faster matching:\n            state->type = this->get_repeat_type(state);\n            if((state->type == syntax_element_dot_rep) \n               || (state->type == syntax_element_char_rep)\n               || (state->type == syntax_element_short_set_rep))\n            {\n               if(rep->max != rep->min)\n                  return -1;\n               result += static_cast<int>(rep->min);\n               state = rep->alt.p;\n               continue;\n            }\n            else if(state->type == syntax_element_long_set_rep)\n            {\n               BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);\n               if(static_cast<re_set_long<m_type>*>(rep->next.p)->singleton == 0)\n                  return -1;\n               if(rep->max != rep->min)\n                  return -1;\n               result += static_cast<int>(rep->min);\n               state = rep->alt.p;\n               continue;\n            }\n         }\n         return -1;\n      case syntax_element_long_set:\n         if(static_cast<re_set_long<m_type>*>(state)->singleton == 0)\n            return -1;\n         result += 1;\n         break;\n      case syntax_element_jump:\n         state = static_cast<re_jump*>(state)->alt.p;\n         continue;\n      case syntax_element_alt:\n         {\n            int r1 = calculate_backstep(state->next.p);\n            int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p);\n            if((r1 < 0) || (r1 != r2))\n               return -1;\n            return result + r1;\n         }\n      default:\n         break;\n      }\n      state = state->next.p;\n   }\n   return -1;\n}\n\nstruct recursion_saver\n{\n   std::vector<unsigned char> saved_state;\n   std::vector<unsigned char>* state;\n   recursion_saver(std::vector<unsigned char>* p) : saved_state(*p), state(p) {}\n   ~recursion_saver()\n   {\n      state->swap(saved_state);\n   }\n};\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)\n{\n   recursion_saver saved_recursions(&m_recursion_checks);\n   int not_last_jump = 1;\n   re_syntax_base* recursion_start = 0;\n   int recursion_sub = 0;\n   re_syntax_base* recursion_restart = 0;\n\n   // track case sensitivity:\n   bool l_icase = m_icase;\n\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_toggle_case:\n         l_icase = static_cast<re_case*>(state)->icase;\n         state = state->next.p;\n         break;\n      case syntax_element_literal:\n      {\n         // don't set anything in *pnull, set each element in l_map\n         // that could match the first character in the literal:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)\n                  l_map[i] |= mask;\n            }\n         }\n         return;\n      }\n      case syntax_element_end_line:\n      {\n         // next character must be a line separator (if there is one):\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            l_map[static_cast<unsigned>('\\n')] |= mask;\n            l_map[static_cast<unsigned>('\\r')] |= mask;\n            l_map[static_cast<unsigned>('\\f')] |= mask;\n            l_map[0x85] |= mask;\n         }\n         // now figure out if we can match a NULL string at this point:\n         if(pnull)\n            create_startmap(state->next.p, 0, pnull, mask);\n         return;\n      }\n      case syntax_element_recurse:\n         {\n            BOOST_REGEX_ASSERT(static_cast<const re_jump*>(state)->alt.p->type == syntax_element_startmark);\n            recursion_sub = static_cast<re_brace*>(static_cast<const re_jump*>(state)->alt.p)->index;\n            if(m_recursion_checks[recursion_sub] & 1u)\n            {\n               // Infinite recursion!!\n               if(0 == this->m_pdata->m_status) // update the error code if not already set\n                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n               //\n               // clear the expression, we should be empty:\n               //\n               this->m_pdata->m_expression = 0;\n               this->m_pdata->m_expression_len = 0;\n               //\n               // and throw if required:\n               //\n               if(0 == (this->flags() & regex_constants::no_except))\n               {\n                  std::string message = \"Encountered an infinite recursion.\";\n                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                  e.raise();\n               }\n            }\n            else if(recursion_start == 0)\n            {\n               recursion_start = state;\n               recursion_restart = state->next.p;\n               state = static_cast<re_jump*>(state)->alt.p;\n               m_recursion_checks[recursion_sub] |= 1u;\n               break;\n            }\n            m_recursion_checks[recursion_sub] |= 1u;\n            // can't handle nested recursion here...\n            BOOST_FALLTHROUGH;\n         }\n      case syntax_element_backref:\n         // can be null, and any character can match:\n         if(pnull)\n            *pnull |= mask;\n         BOOST_FALLTHROUGH;\n      case syntax_element_wild:\n      {\n         // can't be null, any character can match:\n         set_all_masks(l_map, mask);\n         return;\n      }\n      case syntax_element_accept:\n      case syntax_element_match:\n      {\n         // must be null, any character can match:\n         set_all_masks(l_map, mask);\n         if(pnull)\n            *pnull |= mask;\n         return;\n      }\n      case syntax_element_word_start:\n      {\n         // recurse, then AND with all the word characters:\n         create_startmap(state->next.p, l_map, pnull, mask);\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))\n                  l_map[i] &= static_cast<unsigned char>(~mask);\n            }\n         }\n         return;\n      }\n      case syntax_element_word_end:\n      {\n         // recurse, then AND with all the word characters:\n         create_startmap(state->next.p, l_map, pnull, mask);\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(m_traits.isctype(static_cast<charT>(i), m_word_mask))\n                  l_map[i] &= static_cast<unsigned char>(~mask);\n            }\n         }\n         return;\n      }\n      case syntax_element_buffer_end:\n      {\n         // we *must be null* :\n         if(pnull)\n            *pnull |= mask;\n         return;\n      }\n      case syntax_element_long_set:\n         if(l_map)\n         {\n            typedef typename traits::char_class_type m_type;\n            if(static_cast<re_set_long<m_type>*>(state)->singleton)\n            {\n               l_map[0] |= mask_init;\n               for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n               {\n                  charT c = static_cast<charT>(i);\n                  if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<m_type>*>(state), *m_pdata, l_icase))\n                     l_map[i] |= mask;\n               }\n            }\n            else\n               set_all_masks(l_map, mask);\n         }\n         return;\n      case syntax_element_set:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(static_cast<re_set*>(state)->_map[\n                  static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])\n                  l_map[i] |= mask;\n            }\n         }\n         return;\n      case syntax_element_jump:\n         // take the jump:\n         state = static_cast<re_alt*>(state)->alt.p;\n         not_last_jump = -1;\n         break;\n      case syntax_element_alt:\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         {\n            re_alt* rep = static_cast<re_alt*>(state);\n            if(rep->_map[0] & mask_init)\n            {\n               if(l_map)\n               {\n                  // copy previous results:\n                  l_map[0] |= mask_init;\n                  for(unsigned int i = 0; i <= UCHAR_MAX; ++i)\n                  {\n                     if(rep->_map[i] & mask_any)\n                        l_map[i] |= mask;\n                  }\n               }\n               if(pnull)\n               {\n                  if(rep->can_be_null & mask_any)\n                     *pnull |= mask;\n               }\n            }\n            else\n            {\n               // we haven't created a startmap for this alternative yet\n               // so take the union of the two options:\n               if(is_bad_repeat(state))\n               {\n                  set_all_masks(l_map, mask);\n                  if(pnull)\n                     *pnull |= mask;\n                  return;\n               }\n               set_bad_repeat(state);\n               create_startmap(state->next.p, l_map, pnull, mask);\n               if((state->type == syntax_element_alt)\n                  || (static_cast<re_repeat*>(state)->min == 0)\n                  || (not_last_jump == 0))\n                  create_startmap(rep->alt.p, l_map, pnull, mask);\n            }\n         }\n         return;\n      case syntax_element_soft_buffer_end:\n         // match newline or null:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            l_map[static_cast<unsigned>('\\n')] |= mask;\n            l_map[static_cast<unsigned>('\\r')] |= mask;\n         }\n         if(pnull)\n            *pnull |= mask;\n         return;\n      case syntax_element_endmark:\n         // need to handle independent subs as a special case:\n         if(static_cast<re_brace*>(state)->index < 0)\n         {\n            // can be null, any character can match:\n            set_all_masks(l_map, mask);\n            if(pnull)\n               *pnull |= mask;\n            return;\n         }\n         else if(recursion_start && (recursion_sub != 0) && (recursion_sub == static_cast<re_brace*>(state)->index))\n         {\n            // recursion termination:\n            recursion_start = 0;\n            state = recursion_restart;\n            break;\n         }\n\n         //\n         // Normally we just go to the next state... but if this sub-expression is\n         // the target of a recursion, then we might be ending a recursion, in which\n         // case we should check whatever follows that recursion, as well as whatever\n         // follows this state:\n         //\n         if(m_pdata->m_has_recursions && static_cast<re_brace*>(state)->index)\n         {\n            bool ok = false;\n            re_syntax_base* p = m_pdata->m_first_state;\n            while(p)\n            {\n               if(p->type == syntax_element_recurse)\n               {\n                  re_brace* p2 = static_cast<re_brace*>(static_cast<re_jump*>(p)->alt.p);\n                  if((p2->type == syntax_element_startmark) && (p2->index == static_cast<re_brace*>(state)->index))\n                  {\n                     ok = true;\n                     break;\n                  }\n               }\n               p = p->next.p;\n            }\n            if(ok && ((m_recursion_checks[static_cast<re_brace*>(state)->index] & 2u) == 0))\n            {\n               m_recursion_checks[static_cast<re_brace*>(state)->index] |= 2u;\n               create_startmap(p->next.p, l_map, pnull, mask);\n            }\n         }\n         state = state->next.p;\n         break;\n\n      case syntax_element_commit:\n         set_all_masks(l_map, mask);\n         // Continue scanning so we can figure out whether we can be null:\n         state = state->next.p;\n         break;\n      case syntax_element_startmark:\n         // need to handle independent subs as a special case:\n         if(static_cast<re_brace*>(state)->index == -3)\n         {\n            state = state->next.p->next.p;\n            break;\n         }\n         BOOST_FALLTHROUGH;\n      default:\n         state = state->next.p;\n      }\n      ++not_last_jump;\n   }\n}\n\ntemplate <class charT, class traits>\nunsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)\n{\n   //\n   // find out how the machine starts, so we can optimise the search:\n   //\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n      case syntax_element_endmark:\n         state = state->next.p;\n         continue;\n      case syntax_element_start_line:\n         return regbase::restart_line;\n      case syntax_element_word_start:\n         return regbase::restart_word;\n      case syntax_element_buffer_start:\n         return regbase::restart_buf;\n      case syntax_element_restart_continue:\n         return regbase::restart_continue;\n      default:\n         state = 0;\n         continue;\n      }\n   }\n   return regbase::restart_any;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::set_all_masks(unsigned char* bits, unsigned char mask)\n{\n   //\n   // set mask in all of bits elements, \n   // if bits[0] has mask_init not set then we can \n   // optimise this to a call to memset:\n   //\n   if(bits)\n   {\n      if(bits[0] == 0)\n         (std::memset)(bits, mask, 1u << CHAR_BIT);\n      else\n      {\n         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n            bits[i] |= mask;\n      }\n      bits[0] |= mask_init;\n   }\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)\n{\n   switch(pt->type)\n   {\n   case syntax_element_rep:\n   case syntax_element_dot_rep:\n   case syntax_element_char_rep:\n   case syntax_element_short_set_rep:\n   case syntax_element_long_set_rep:\n      {\n         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;\n         if(state_id >= sizeof(m_bad_repeats) * CHAR_BIT)\n            return true;  // run out of bits, assume we can't traverse this one.\n         static const boost::uintmax_t one = 1uL;\n         return m_bad_repeats & (one << state_id);\n      }\n   default:\n      return false;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)\n{\n   switch(pt->type)\n   {\n   case syntax_element_rep:\n   case syntax_element_dot_rep:\n   case syntax_element_char_rep:\n   case syntax_element_short_set_rep:\n   case syntax_element_long_set_rep:\n      {\n         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;\n         static const boost::uintmax_t one = 1uL;\n         if(state_id <= sizeof(m_bad_repeats) * CHAR_BIT)\n            m_bad_repeats |= (one << state_id);\n      }\n      break;\n   default:\n      break;\n   }\n}\n\ntemplate <class charT, class traits>\nsyntax_element_type basic_regex_creator<charT, traits>::get_repeat_type(re_syntax_base* state)\n{\n   typedef typename traits::char_class_type m_type;\n   if(state->type == syntax_element_rep)\n   {\n      // check to see if we are repeating a single state:\n      if(state->next.p->next.p->next.p == static_cast<re_alt*>(state)->alt.p)\n      {\n         switch(state->next.p->type)\n         {\n         case BOOST_REGEX_DETAIL_NS::syntax_element_wild:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_dot_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_literal:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_char_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_set:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_short_set_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_long_set:\n            if(static_cast<BOOST_REGEX_DETAIL_NS::re_set_long<m_type>*>(state->next.p)->singleton)\n               return BOOST_REGEX_DETAIL_NS::syntax_element_long_set_rep;\n            break;\n         default:\n            break;\n         }\n      }\n   }\n   return state->type;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* state)\n{\n   // enumerate our states, and see if we have a leading repeat \n   // for which failed search restarts can be optimized;\n   do\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n         if(static_cast<re_brace*>(state)->index >= 0)\n         {\n            state = state->next.p;\n            continue;\n         }\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#pragma warning(disable:6011)\n#endif\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n         {\n            // skip past the zero width assertion:\n            state = static_cast<const re_jump*>(state->next.p)->alt.p->next.p;\n            continue;\n         }\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n         if(static_cast<re_brace*>(state)->index == -3)\n         {\n            // Have to skip the leading jump state:\n            state = state->next.p->next.p;\n            continue;\n         }\n         return;\n      case syntax_element_endmark:\n      case syntax_element_start_line:\n      case syntax_element_end_line:\n      case syntax_element_word_boundary:\n      case syntax_element_within_word:\n      case syntax_element_word_start:\n      case syntax_element_word_end:\n      case syntax_element_buffer_start:\n      case syntax_element_buffer_end:\n      case syntax_element_restart_continue:\n         state = state->next.p;\n         break;\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         if(this->m_has_backrefs == 0)\n            static_cast<re_repeat*>(state)->leading = true;\n         BOOST_FALLTHROUGH;\n      default:\n         return;\n      }\n   }while(state);\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/basic_regex_parser.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_parser.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_parser.\n  */\n\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP\n#define BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable: 26812)\n#endif\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4244)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\ninline boost::intmax_t umax(mpl::false_ const&)\n{\n   // Get out clause here, just in case numeric_limits is unspecialized:\n   return std::numeric_limits<boost::intmax_t>::is_specialized ? (std::numeric_limits<boost::intmax_t>::max)() : INT_MAX;\n}\ninline boost::intmax_t umax(mpl::true_ const&)\n{\n   return (std::numeric_limits<std::size_t>::max)();\n}\n\ninline boost::intmax_t umax()\n{\n   return umax(mpl::bool_<std::numeric_limits<boost::intmax_t>::digits >= std::numeric_limits<std::size_t>::digits>());\n}\n\ntemplate <class charT, class traits>\nclass basic_regex_parser : public basic_regex_creator<charT, traits>\n{\npublic:\n   basic_regex_parser(regex_data<charT, traits>* data);\n   void parse(const charT* p1, const charT* p2, unsigned flags);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, const std::string& message)\n   {\n      fail(error_code, position, message, position);\n   }\n\n   bool parse_all();\n   bool parse_basic();\n   bool parse_extended();\n   bool parse_literal();\n   bool parse_open_paren();\n   bool parse_basic_escape();\n   bool parse_extended_escape();\n   bool parse_match_any();\n   bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());\n   bool parse_repeat_range(bool isbasic);\n   bool parse_alt();\n   bool parse_set();\n   bool parse_backref();\n   void parse_set_literal(basic_char_set<charT, traits>& char_set);\n   bool parse_inner_set(basic_char_set<charT, traits>& char_set);\n   bool parse_QE();\n   bool parse_perl_extension();\n   bool parse_perl_verb();\n   bool match_verb(const char*);\n   bool add_emacs_code(bool negate);\n   bool unwind_alts(std::ptrdiff_t last_paren_start);\n   digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);\n   charT unescape_character();\n   regex_constants::syntax_option_type parse_options();\n\nprivate:\n   typedef bool (basic_regex_parser::*parser_proc_type)();\n   typedef typename traits::string_type string_type;\n   typedef typename traits::char_class_type char_class_type;\n   parser_proc_type           m_parser_proc;    // the main parser to use\n   const charT*               m_base;           // the start of the string being parsed\n   const charT*               m_end;            // the end of the string being parsed\n   const charT*               m_position;       // our current parser position\n   unsigned                   m_mark_count;     // how many sub-expressions we have\n   int                        m_mark_reset;     // used to indicate that we're inside a (?|...) block.\n   unsigned                   m_max_mark;       // largest mark count seen inside a (?|...) block.\n   std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).\n   std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative\n   bool                       m_has_case_change; // true if somewhere in the current block the case has changed\n   unsigned                   m_recursion_count; // How many times we've called parse_all.\n#if defined(BOOST_MSVC) && defined(_M_IX86)\n   // This is an ugly warning suppression workaround (for warnings *inside* std::vector\n   // that can not otherwise be suppressed)...\n   BOOST_STATIC_ASSERT(sizeof(long) >= sizeof(void*));\n   std::vector<long>           m_alt_jumps;      // list of alternative in the current scope.\n#else\n   std::vector<std::ptrdiff_t> m_alt_jumps;      // list of alternative in the current scope.\n#endif\n\n   basic_regex_parser& operator=(const basic_regex_parser&);\n   basic_regex_parser(const basic_regex_parser&);\n};\n\ntemplate <class charT, class traits>\nbasic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)\n   : basic_regex_creator<charT, traits>(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), \n   m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0)\n{\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)\n{\n   // pass l_flags on to base class:\n   this->init(l_flags);\n   // set up pointers:\n   m_position = m_base = p1;\n   m_end = p2;\n   // empty strings are errors:\n   if((p1 == p2) && \n      (\n         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)\n         || (l_flags & regbase::no_empty_expressions)\n      )\n     )\n   {\n      fail(regex_constants::error_empty, 0);\n      return;\n   }\n   // select which parser to use:\n   switch(l_flags & regbase::main_option_type)\n   {\n   case regbase::perl_syntax_group:\n      {\n         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;\n         //\n         // Add a leading paren with index zero to give recursions a target:\n         //\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n         br->index = 0;\n         br->icase = this->flags() & regbase::icase;\n         break;\n      }\n   case regbase::basic_syntax_group:\n      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;\n      break;\n   case regbase::literal:\n      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;\n      break;\n   default:\n      // Oops, someone has managed to set more than one of the main option flags, \n      // so this must be an error:\n      fail(regex_constants::error_unknown, 0, \"An invalid combination of regular expression syntax flags was used.\");\n      return;\n   }\n\n   // parse all our characters:\n   bool result = parse_all();\n   //\n   // Unwind our alternatives:\n   //\n   unwind_alts(-1);\n   // reset l_flags as a global scope (?imsx) may have altered them:\n   this->flags(l_flags);\n   // if we haven't gobbled up all the characters then we must\n   // have had an unexpected ')' :\n   if(!result)\n   {\n      fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_position), \"Found a closing ) with no corresponding opening parenthesis.\");\n      return;\n   }\n   // if an error has been set then give up now:\n   if(this->m_pdata->m_status)\n      return;\n   // fill in our sub-expression count:\n   this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count;\n   this->finalize(p1, p2);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)\n{\n   // get the error message:\n   std::string message = this->m_pdata->m_ptraits->error_string(error_code);\n   fail(error_code, position, message);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos)\n{\n   if(0 == this->m_pdata->m_status) // update the error code if not already set\n      this->m_pdata->m_status = error_code;\n   m_position = m_end; // don't bother parsing anything else\n\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n   //\n   // Augment error message with the regular expression text:\n   //\n   if(start_pos == position)\n      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));\n   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));\n   if(error_code != regex_constants::error_empty)\n   {\n      if((start_pos != 0) || (end_pos != (m_end - m_base)))\n         message += \"  The error occurred while parsing the regular expression fragment: '\";\n      else\n         message += \"  The error occurred while parsing the regular expression: '\";\n      if(start_pos != end_pos)\n      {\n         message += std::string(m_base + start_pos, m_base + position);\n         message += \">>>HERE>>>\";\n         message += std::string(m_base + position, m_base + end_pos);\n      }\n      message += \"'.\";\n   }\n#endif\n\n#ifndef BOOST_NO_EXCEPTIONS\n   if(0 == (this->flags() & regex_constants::no_except))\n   {\n      boost::regex_error e(message, error_code, position);\n      e.raise();\n   }\n#else\n   (void)position; // suppress warnings.\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_all()\n{\n   if (++m_recursion_count > 400)\n   {\n      // exceeded internal limits\n      fail(boost::regex_constants::error_complexity, m_position - m_base, \"Exceeded nested brace limit.\");\n   }\n   bool result = true;\n   while(result && (m_position != m_end))\n   {\n      result = (this->*m_parser_proc)();\n   }\n   --m_recursion_count;\n   return result;\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4702)\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_basic()\n{\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_escape:\n      return parse_basic_escape();\n   case regex_constants::syntax_dot:\n      return parse_match_any();\n   case regex_constants::syntax_caret:\n      ++m_position;\n      this->append_state(syntax_element_start_line);\n      break;\n   case regex_constants::syntax_dollar:\n      ++m_position;\n      this->append_state(syntax_element_end_line);\n      break;\n   case regex_constants::syntax_star:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat();\n      }\n   case regex_constants::syntax_plus:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat(1);\n      }\n   case regex_constants::syntax_question:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat(0, 1);\n      }\n   case regex_constants::syntax_open_set:\n      return parse_set();\n   case regex_constants::syntax_newline:\n      if(this->flags() & regbase::newline_alt)\n         return parse_alt();\n      else\n         return parse_literal();\n   default:\n      return parse_literal();\n   }\n   return true;\n}\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable:26812)\n#endif\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_extended()\n{\n   bool result = true;\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_open_mark:\n      return parse_open_paren();\n   case regex_constants::syntax_close_mark:\n      return false;\n   case regex_constants::syntax_escape:\n      return parse_extended_escape();\n   case regex_constants::syntax_dot:\n      return parse_match_any();\n   case regex_constants::syntax_caret:\n      ++m_position;\n      this->append_state(\n         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));\n      break;\n   case regex_constants::syntax_dollar:\n      ++m_position;\n      this->append_state(\n         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));\n      break;\n   case regex_constants::syntax_star:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"*\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat();\n   case regex_constants::syntax_question:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"?\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat(0,1);\n   case regex_constants::syntax_plus:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"+\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat(1);\n   case regex_constants::syntax_open_brace:\n      ++m_position;\n      return parse_repeat_range(false);\n   case regex_constants::syntax_close_brace:\n      if((this->flags() & regbase::no_perl_ex) == regbase::no_perl_ex)\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, \"Found a closing repetition operator } with no corresponding {.\");\n         return false;\n      }\n      result = parse_literal();\n      break;\n   case regex_constants::syntax_or:\n      return parse_alt();\n   case regex_constants::syntax_open_set:\n      return parse_set();\n   case regex_constants::syntax_newline:\n      if(this->flags() & regbase::newline_alt)\n         return parse_alt();\n      else\n         return parse_literal();\n   case regex_constants::syntax_hash:\n      //\n      // If we have a mod_x flag set, then skip until\n      // we get to a newline character:\n      //\n      if((this->flags() \n         & (regbase::no_perl_ex|regbase::mod_x))\n         == regbase::mod_x)\n      {\n         while((m_position != m_end) && !is_separator(*m_position++)){}\n         return true;\n      }\n      BOOST_FALLTHROUGH;\n   default:\n      result = parse_literal();\n      break;\n   }\n   return result;\n}\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_literal()\n{\n   // append this as a literal provided it's not a space character\n   // or the perl option regbase::mod_x is not set:\n   if(\n      ((this->flags() \n         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) \n            != regbase::mod_x)\n      || !this->m_traits.isctype(*m_position, this->m_mask_space))\n         this->append_literal(*m_position);\n   ++m_position;\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_open_paren()\n{\n   //\n   // skip the '(' and error check:\n   //\n   if(++m_position == m_end)\n   {\n      fail(regex_constants::error_paren, m_position - m_base);\n      return false;\n   }\n   //\n   // begin by checking for a perl-style (?...) extension:\n   //\n   if(\n         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)\n         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))\n     )\n   {\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)\n         return parse_perl_extension();\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star)\n         return parse_perl_verb();\n   }\n   //\n   // update our mark count, and append the required state:\n   //\n   unsigned markid = 0;\n   if(0 == (this->flags() & regbase::nosubs))\n   {\n      markid = ++m_mark_count;\n#ifndef BOOST_NO_STD_DISTANCE\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));\n#else\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 1, 0));\n#endif\n   }\n   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   std::ptrdiff_t last_paren_start = this->getoffset(pb);\n   // back up insertion point for alternations, and set new point:\n   std::ptrdiff_t last_alt_point = m_alt_insert_point;\n   this->m_pdata->m_data.align();\n   m_alt_insert_point = this->m_pdata->m_data.size();\n   //\n   // back up the current flags in case we have a nested (?imsx) group:\n   //\n   regex_constants::syntax_option_type opts = this->flags();\n   bool old_case_change = m_has_case_change;\n   m_has_case_change = false; // no changes to this scope as yet...\n   //\n   // Back up branch reset data in case we have a nested (?|...)\n   //\n   int mark_reset = m_mark_reset;\n   m_mark_reset = -1;\n   //\n   // now recursively add more states, this will terminate when we get to a\n   // matching ')' :\n   //\n   parse_all();\n   //\n   // Unwind pushed alternatives:\n   //\n   if(0 == unwind_alts(last_paren_start))\n      return false;\n   //\n   // restore flags:\n   //\n   if(m_has_case_change)\n   {\n      // the case has changed in one or more of the alternatives\n      // within the scoped (...) block: we have to add a state\n      // to reset the case sensitivity:\n      static_cast<re_case*>(\n         this->append_state(syntax_element_toggle_case, sizeof(re_case))\n         )->icase = opts & regbase::icase;\n   }\n   this->flags(opts);\n   m_has_case_change = old_case_change;\n   //\n   // restore branch reset:\n   //\n   m_mark_reset = mark_reset;\n   //\n   // we either have a ')' or we have run out of characters prematurely:\n   //\n   if(m_position == m_end)\n   {\n      this->fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_end));\n      return false;\n   }\n   if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n      return false;\n#ifndef BOOST_NO_STD_DISTANCE\n   if(markid && (this->flags() & regbase::save_subexpression_location))\n      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);\n#else\n   if(markid && (this->flags() & regbase::save_subexpression_location))\n      this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base);\n#endif\n   ++m_position;\n   //\n   // append closing parenthesis state:\n   //\n   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   this->m_paren_start = last_paren_start;\n   //\n   // restore the alternate insertion point:\n   //\n   this->m_alt_insert_point = last_alt_point;\n   //\n   // allow backrefs to this mark:\n   //\n   if(markid > 0)\n      this->m_backrefs.set(markid);\n\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_basic_escape()\n{\n   if(++m_position == m_end)\n   {\n      fail(regex_constants::error_paren, m_position - m_base);\n      return false;\n   }\n   bool result = true;\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::syntax_open_mark:\n      return parse_open_paren();\n   case regex_constants::syntax_close_mark:\n      return false;\n   case regex_constants::syntax_plus:\n      if(this->flags() & regex_constants::bk_plus_qm)\n      {\n         ++m_position;\n         return parse_repeat(1);\n      }\n      else\n         return parse_literal();\n   case regex_constants::syntax_question:\n      if(this->flags() & regex_constants::bk_plus_qm)\n      {\n         ++m_position;\n         return parse_repeat(0, 1);\n      }\n      else\n         return parse_literal();\n   case regex_constants::syntax_open_brace:\n      if(this->flags() & regbase::no_intervals)\n         return parse_literal();\n      ++m_position;\n      return parse_repeat_range(true);\n   case regex_constants::syntax_close_brace:\n      if(this->flags() & regbase::no_intervals)\n         return parse_literal();\n      fail(regex_constants::error_brace, this->m_position - this->m_base, \"Found a closing repetition operator } with no corresponding {.\");\n      return false;\n   case regex_constants::syntax_or:\n      if(this->flags() & regbase::bk_vbar)\n         return parse_alt();\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::syntax_digit:\n      return parse_backref();\n   case regex_constants::escape_type_start_buffer:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_buffer_start);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_end_buffer:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_buffer_end);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_word_assert:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_boundary);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_not_word_assert:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_within_word);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_left_word:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_start);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_right_word:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_end);\n      }\n      else\n         result = parse_literal();\n      break;\n   default:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         bool negate = true;\n         switch(*m_position)\n         {\n         case 'w':\n            negate = false;\n            BOOST_FALLTHROUGH;\n         case 'W':\n            {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(this->m_word_mask);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            ++m_position;\n            return true;\n            }\n         case 's':\n            negate = false;\n            BOOST_FALLTHROUGH;\n         case 'S':\n            return add_emacs_code(negate);\n         case 'c':\n         case 'C':\n            // not supported yet:\n            fail(regex_constants::error_escape, m_position - m_base, \"The \\\\c and \\\\C escape sequences are not supported by POSIX basic regular expressions: try the Perl syntax instead.\");\n            return false;\n         default:\n            break;\n         }\n      }\n      result = parse_literal();\n      break;\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_extended_escape()\n{\n   ++m_position;\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_escape, m_position - m_base, \"Incomplete escape sequence found.\");\n      return false;\n   }\n   bool negate = false; // in case this is a character class escape: \\w \\d etc\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::escape_type_not_class:\n      negate = true;\n      BOOST_FALLTHROUGH;\n   case regex_constants::escape_type_class:\n      {\nescape_type_class_jump:\n         typedef typename traits::char_class_type m_type;\n         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n         if(m != 0)\n         {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(m);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            ++m_position;\n            return true;\n         }\n         //\n         // not a class, just a regular unknown escape:\n         //\n         this->append_literal(unescape_character());\n         break;\n      }\n   case regex_constants::syntax_digit:\n      return parse_backref();\n   case regex_constants::escape_type_left_word:\n      ++m_position;\n      this->append_state(syntax_element_word_start);\n      break;\n   case regex_constants::escape_type_right_word:\n      ++m_position;\n      this->append_state(syntax_element_word_end);\n      break;\n   case regex_constants::escape_type_start_buffer:\n      ++m_position;\n      this->append_state(syntax_element_buffer_start);\n      break;\n   case regex_constants::escape_type_end_buffer:\n      ++m_position;\n      this->append_state(syntax_element_buffer_end);\n      break;\n   case regex_constants::escape_type_word_assert:\n      ++m_position;\n      this->append_state(syntax_element_word_boundary);\n      break;\n   case regex_constants::escape_type_not_word_assert:\n      ++m_position;\n      this->append_state(syntax_element_within_word);\n      break;\n   case regex_constants::escape_type_Z:\n      ++m_position;\n      this->append_state(syntax_element_soft_buffer_end);\n      break;\n   case regex_constants::escape_type_Q:\n      return parse_QE();\n   case regex_constants::escape_type_C:\n      return parse_match_any();\n   case regex_constants::escape_type_X:\n      ++m_position;\n      this->append_state(syntax_element_combining);\n      break;\n   case regex_constants::escape_type_G:\n      ++m_position;\n      this->append_state(syntax_element_restart_continue);\n      break;\n   case regex_constants::escape_type_not_property:\n      negate = true;\n      BOOST_FALLTHROUGH;\n   case regex_constants::escape_type_property:\n      {\n         ++m_position;\n         char_class_type m;\n         if(m_position == m_end)\n         {\n            fail(regex_constants::error_escape, m_position - m_base, \"Incomplete property escape found.\");\n            return false;\n         }\n         // maybe have \\p{ddd}\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n         {\n            const charT* base = m_position;\n            // skip forward until we find enclosing brace:\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               fail(regex_constants::error_escape, m_position - m_base, \"Closing } missing from property escape sequence.\");\n               return false;\n            }\n            m = this->m_traits.lookup_classname(++base, m_position++);\n         }\n         else\n         {\n            m = this->m_traits.lookup_classname(m_position, m_position+1);\n            ++m_position;\n         }\n         if(m != 0)\n         {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(m);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            return true;\n         }\n         fail(regex_constants::error_ctype, m_position - m_base, \"Escape sequence was neither a valid property nor a valid character class name.\");\n         return false;\n      }\n   case regex_constants::escape_type_reset_start_mark:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n         pb->index = -5;\n         pb->icase = this->flags() & regbase::icase;\n         this->m_pdata->m_data.align();\n         ++m_position;\n         return true;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_line_ending:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         const charT* e = get_escape_R_string<charT>();\n         const charT* old_position = m_position;\n         const charT* old_end = m_end;\n         const charT* old_base = m_base;\n         m_position = e;\n         m_base = e;\n         m_end = e + traits::length(e);\n         bool r = parse_all();\n         m_position = ++old_position;\n         m_end = old_end;\n         m_base = old_base;\n         return r;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_extended_backref:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         bool have_brace = false;\n         bool negative = false;\n         static const char incomplete_message[] = \"Incomplete \\\\g escape found.\";\n         if(++m_position == m_end)\n         {\n            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n            return false;\n         }\n         // maybe have \\g{ddd}\n         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);\n         regex_constants::syntax_type syn_end = 0;\n         if((syn == regex_constants::syntax_open_brace) \n            || (syn == regex_constants::escape_type_left_word)\n            || (syn == regex_constants::escape_type_end_buffer))\n         {\n            if(++m_position == m_end)\n            {\n               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n               return false;\n            }\n            have_brace = true;\n            switch(syn)\n            {\n            case regex_constants::syntax_open_brace:\n               syn_end = regex_constants::syntax_close_brace;\n               break;\n            case regex_constants::escape_type_left_word:\n               syn_end = regex_constants::escape_type_right_word;\n               break;\n            default:\n               syn_end = regex_constants::escape_type_end_buffer;\n               break;\n            }\n         }\n         negative = (*m_position == static_cast<charT>('-'));\n         if((negative) && (++m_position == m_end))\n         {\n            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n            return false;\n         }\n         const charT* pc = m_position;\n         boost::intmax_t i = this->m_traits.toi(pc, m_end, 10);\n         if((i < 0) && syn_end)\n         {\n            // Check for a named capture, get the leftmost one if there is more than one:\n            const charT* base = m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))\n            {\n               ++m_position;\n            }\n            i = hash_value_from_capture_name(base, m_position);\n            pc = m_position;\n         }\n         if(negative)\n            i = 1 + (static_cast<boost::intmax_t>(m_mark_count) - i);\n         if(((i < hash_value_mask) && (i > 0) && (this->m_backrefs.test(i))) || ((i >= hash_value_mask) && (this->m_pdata->get_id(i) > 0) && (this->m_backrefs.test(this->m_pdata->get_id(i)))))\n         {\n            m_position = pc;\n            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));\n            pb->index = i;\n            pb->icase = this->flags() & regbase::icase;\n         }\n         else\n         {\n            fail(regex_constants::error_backref, m_position - m_base);\n            return false;\n         }\n         m_position = pc;\n         if(have_brace)\n         {\n            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))\n            {\n               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n               return false;\n            }\n            ++m_position;\n         }\n         return true;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_control_v:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n         goto escape_type_class_jump;\n      BOOST_FALLTHROUGH;\n   default:\n      this->append_literal(unescape_character());\n      break;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_match_any()\n{\n   //\n   // we have a '.' that can match any character:\n   //\n   ++m_position;\n   static_cast<re_dot*>(\n      this->append_state(syntax_element_wild, sizeof(re_dot))\n      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s \n      ? BOOST_REGEX_DETAIL_NS::force_not_newline \n         : this->flags() & regbase::mod_s ?\n            BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care);\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)\n{\n   bool greedy = true;\n   bool possessive = false;\n   std::size_t insert_point;\n   // \n   // when we get to here we may have a non-greedy ? mark still to come:\n   //\n   if((m_position != m_end) \n      && (\n            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))\n         )\n      )\n   {\n      // OK we have a perl or emacs regex, check for a '?':\n      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)\n      {\n         // whitespace skip:\n         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n            ++m_position;\n      }\n      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))\n      {\n         greedy = false;\n         ++m_position;\n      }\n      // for perl regexes only check for possessive ++ repeats.\n      if((m_position != m_end)\n         && (0 == (this->flags() & regbase::main_option_type)) \n         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))\n      {\n         possessive = true;\n         ++m_position;\n      }\n   }\n   if(0 == this->m_last_state)\n   {\n      fail(regex_constants::error_badrepeat, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_position), \"Nothing to repeat.\");\n      return false;\n   }\n   if(this->m_last_state->type == syntax_element_endmark)\n   {\n      // insert a repeat before the '(' matching the last ')':\n      insert_point = this->m_paren_start;\n   }\n   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))\n   {\n      // the last state was a literal with more than one character, split it in two:\n      re_literal* lit = static_cast<re_literal*>(this->m_last_state);\n      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];\n      lit->length -= 1;\n      // now append new state:\n      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));\n      lit->length = 1;\n      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;\n      insert_point = this->getoffset(this->m_last_state);\n   }\n   else\n   {\n      // repeat the last state whatever it was, need to add some error checking here:\n      switch(this->m_last_state->type)\n      {\n      case syntax_element_start_line:\n      case syntax_element_end_line:\n      case syntax_element_word_boundary:\n      case syntax_element_within_word:\n      case syntax_element_word_start:\n      case syntax_element_word_end:\n      case syntax_element_buffer_start:\n      case syntax_element_buffer_end:\n      case syntax_element_alt:\n      case syntax_element_soft_buffer_end:\n      case syntax_element_restart_continue:\n      case syntax_element_jump:\n      case syntax_element_startmark:\n      case syntax_element_backstep:\n      case syntax_element_toggle_case:\n         // can't legally repeat any of the above:\n         fail(regex_constants::error_badrepeat, m_position - m_base);\n         return false;\n      default:\n         // do nothing...\n         break;\n      }\n      insert_point = this->getoffset(this->m_last_state);\n   }\n   //\n   // OK we now know what to repeat, so insert the repeat around it:\n   //\n   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));\n   rep->min = low;\n   rep->max = high;\n   rep->greedy = greedy;\n   rep->leading = false;\n   // store our repeater position for later:\n   std::ptrdiff_t rep_off = this->getoffset(rep);\n   // and append a back jump to the repeat:\n   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));\n   jmp->alt.i = rep_off - this->getoffset(jmp);\n   this->m_pdata->m_data.align();\n   // now fill in the alt jump for the repeat:\n   rep = static_cast<re_repeat*>(this->getaddress(rep_off));\n   rep->alt.i = this->m_pdata->m_data.size() - rep_off;\n   //\n   // If the repeat is possessive then bracket the repeat with a (?>...)\n   // independent sub-expression construct:\n   //\n   if(possessive)\n   {\n      if(m_position != m_end)\n      {\n         //\n         // Check for illegal following quantifier, we have to do this here, because\n         // the extra states we insert below circumvents our usual error checking :-(\n         //\n         bool contin = false;\n         do\n         {\n            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)\n            {\n               // whitespace skip:\n               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n                  ++m_position;\n            }\n            if (m_position != m_end)\n            {\n               switch (this->m_traits.syntax_type(*m_position))\n               {\n               case regex_constants::syntax_star:\n               case regex_constants::syntax_plus:\n               case regex_constants::syntax_question:\n               case regex_constants::syntax_open_brace:\n                  fail(regex_constants::error_badrepeat, m_position - m_base);\n                  return false;\n               case regex_constants::syntax_open_mark:\n                  // Do we have a comment?  If so we need to skip it here...\n                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question\n                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)\n                  {\n                     while ((m_position != m_end)\n                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {\n                     }\n                     contin = true;\n                  }\n                  else\n                     contin = false;\n                  break;\n               default:\n                  contin = false;\n               }\n            }\n            else\n               contin = false;\n         } while (contin);\n      }\n      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));\n      pb->index = -3;\n      pb->icase = this->flags() & regbase::icase;\n      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);\n      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n      pb->index = -3;\n      pb->icase = this->flags() & regbase::icase;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)\n{\n   static const char incomplete_message[] = \"Missing } in quantified repetition.\";\n   //\n   // parse a repeat-range:\n   //\n   std::size_t min, max;\n   boost::intmax_t v;\n   // skip whitespace:\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   // get min:\n   v = this->m_traits.toi(m_position, m_end, 10);\n   // skip whitespace:\n   if((v < 0) || (v > umax()))\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   min = static_cast<std::size_t>(v);\n   // see if we have a comma:\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)\n   {\n      // move on and error check:\n      ++m_position;\n      // skip whitespace:\n      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n         ++m_position;\n      if(this->m_position == this->m_end)\n      {\n         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n         {\n            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n            return false;\n         }\n         // Treat the opening '{' as a literal character, rewind to start of error:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n         return parse_literal();\n      }\n      // get the value if any:\n      v = this->m_traits.toi(m_position, m_end, 10);\n      max = ((v >= 0) && (v < umax())) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();\n   }\n   else\n   {\n      // no comma, max = min:\n      max = min;\n   }\n   // skip whitespace:\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   // OK now check trailing }:\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   if(isbasic)\n   {\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)\n      {\n         ++m_position;\n         if(this->m_position == this->m_end)\n         {\n            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n            return false;\n         }\n      }\n      else\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n   }\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)\n      ++m_position;\n   else\n   {\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   //\n   // finally go and add the repeat, unless error:\n   //\n   if(min > max)\n   {\n      // Backtrack to error location:\n      m_position -= 2;\n      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;\n         ++m_position;\n      fail(regex_constants::error_badbrace, m_position - m_base);\n      return false;\n   }\n   return parse_repeat(min, max);\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_alt()\n{\n   //\n   // error check: if there have been no previous states,\n   // or if the last state was a '(' then error:\n   //\n   if(\n      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))\n      &&\n      !(\n         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)\n           &&\n         ((this->flags() & regbase::no_empty_expressions) == 0)\n        )\n      )\n   {\n      fail(regex_constants::error_empty, this->m_position - this->m_base, \"A regular expression cannot start with the alternation operator |.\");\n      return false;\n   }\n   //\n   // Reset mark count if required:\n   //\n   if(m_max_mark < m_mark_count)\n      m_max_mark = m_mark_count;\n   if(m_mark_reset >= 0)\n      m_mark_count = m_mark_reset;\n\n   ++m_position;\n   //\n   // we need to append a trailing jump: \n   //\n   re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump));\n   std::ptrdiff_t jump_offset = this->getoffset(pj);\n   //\n   // now insert the alternative:\n   //\n   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));\n   jump_offset += re_alt_size;\n   this->m_pdata->m_data.align();\n   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);\n   //\n   // update m_alt_insert_point so that the next alternate gets\n   // inserted at the start of the second of the two we've just created:\n   //\n   this->m_alt_insert_point = this->m_pdata->m_data.size();\n   //\n   // the start of this alternative must have a case changes state\n   // if the current block has messed around with case changes:\n   //\n   if(m_has_case_change)\n   {\n      static_cast<re_case*>(\n         this->append_state(syntax_element_toggle_case, sizeof(re_case))\n         )->icase = this->m_icase;\n   }\n   //\n   // push the alternative onto our stack, a recursive\n   // implementation here is easier to understand (and faster\n   // as it happens), but causes all kinds of stack overflow problems\n   // on programs with small stacks (COM+).\n   //\n   m_alt_jumps.push_back(jump_offset);\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_set()\n{\n   static const char incomplete_message[] = \"Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.\";\n   ++m_position;\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n      return false;\n   }\n   basic_char_set<charT, traits> char_set;\n\n   const charT* base = m_position;  // where the '[' was\n   const charT* item_base = m_position;  // where the '[' or '^' was\n\n   while(m_position != m_end)\n   {\n      switch(this->m_traits.syntax_type(*m_position))\n      {\n      case regex_constants::syntax_caret:\n         if(m_position == base)\n         {\n            char_set.negate();\n            ++m_position;\n            item_base = m_position;\n         }\n         else\n            parse_set_literal(char_set);\n         break;\n      case regex_constants::syntax_close_set:\n         if(m_position == item_base)\n         {\n            parse_set_literal(char_set);\n            break;\n         }\n         else\n         {\n            ++m_position;\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n         }\n         return true;\n      case regex_constants::syntax_open_set:\n         if(parse_inner_set(char_set))\n            break;\n         return true;\n      case regex_constants::syntax_escape:\n         {\n            // \n            // look ahead and see if this is a character class shortcut\n            // \\d \\w \\s etc...\n            //\n            ++m_position;\n            if(this->m_traits.escape_syntax_type(*m_position)\n               == regex_constants::escape_type_class)\n            {\n               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n               if(m != 0)\n               {\n                  char_set.add_class(m);\n                  ++m_position;\n                  break;\n               }\n            }\n            else if(this->m_traits.escape_syntax_type(*m_position)\n               == regex_constants::escape_type_not_class)\n            {\n               // negated character class:\n               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n               if(m != 0)\n               {\n                  char_set.add_negated_class(m);\n                  ++m_position;\n                  break;\n               }\n            }\n            // not a character class, just a regular escape:\n            --m_position;\n            parse_set_literal(char_set);\n            break;\n         }\n      default:\n         parse_set_literal(char_set);\n         break;\n      }\n   }\n   return m_position != m_end;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)\n{\n   static const char incomplete_message[] = \"Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.\";\n   //\n   // we have either a character class [:name:]\n   // a collating element [.name.]\n   // or an equivalence class [=name=]\n   //\n   if(m_end == ++m_position)\n   {\n      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n      return false;\n   }\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_dot:\n      //\n      // a collating element is treated as a literal:\n      //\n      --m_position;\n      parse_set_literal(char_set);\n      return true;\n   case regex_constants::syntax_colon:\n      {\n      // check that character classes are actually enabled:\n      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) \n         == (regbase::basic_syntax_group  | regbase::no_char_classes))\n      {\n         --m_position;\n         parse_set_literal(char_set);\n         return true;\n      }\n      // skip the ':'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching ':]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      //\n      // check for negated class:\n      //\n      bool negated = false;\n      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)\n      {\n         ++name_first;\n         negated = true;\n      }\n      typedef typename traits::char_class_type m_type;\n      m_type m = this->m_traits.lookup_classname(name_first, name_last);\n      if(m == 0)\n      {\n         if(char_set.empty() && (name_last - name_first == 1))\n         {\n            // maybe a special case:\n            ++m_position;\n            if( (m_position != m_end) \n               && (this->m_traits.syntax_type(*m_position) \n                  == regex_constants::syntax_close_set))\n            {\n               if(this->m_traits.escape_syntax_type(*name_first) \n                  == regex_constants::escape_type_left_word)\n               {\n                  ++m_position;\n                  this->append_state(syntax_element_word_start);\n                  return false;\n               }\n               if(this->m_traits.escape_syntax_type(*name_first) \n                  == regex_constants::escape_type_right_word)\n               {\n                  ++m_position;\n                  this->append_state(syntax_element_word_end);\n                  return false;\n               }\n            }\n         }\n         fail(regex_constants::error_ctype, name_first - m_base);\n         return false;\n      }\n      if(!negated)\n         char_set.add_class(m);\n      else\n         char_set.add_negated_class(m);\n      ++m_position;\n      break;\n   }\n   case regex_constants::syntax_equal:\n      {\n      // skip the '='\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching '=]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      string_type m = this->m_traits.lookup_collatename(name_first, name_last);\n      if(m.empty() || (m.size() > 2))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return false;\n      }\n      digraph<charT> d;\n      d.first = m[0];\n      if(m.size() > 1)\n         d.second = m[1];\n      else\n         d.second = 0;\n      char_set.add_equivalent(d);\n      ++m_position;\n      break;\n   }\n   default:\n      --m_position;\n      parse_set_literal(char_set);\n      break;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)\n{\n   digraph<charT> start_range(get_next_set_literal(char_set));\n   if(m_end == m_position)\n   {\n      fail(regex_constants::error_brack, m_position - m_base);\n      return;\n   }\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)\n   {\n      // we have a range:\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base);\n         return;\n      }\n      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)\n      {\n         digraph<charT> end_range = get_next_set_literal(char_set);\n         char_set.add_range(start_range, end_range);\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)\n         {\n            if(m_end == ++m_position)\n            {\n               fail(regex_constants::error_brack, m_position - m_base);\n               return;\n            }\n            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)\n            {\n               // trailing - :\n               --m_position;\n               return;\n            }\n            fail(regex_constants::error_range, m_position - m_base);\n            return;\n         }\n         return;\n      }\n      --m_position;\n   }\n   char_set.add_single(start_range);\n}\n\ntemplate <class charT, class traits>\ndigraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)\n{\n   digraph<charT> result;\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_dash:\n      if(!char_set.empty())\n      {\n         // see if we are at the end of the set:\n         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n         {\n            fail(regex_constants::error_range, m_position - m_base);\n            return result;\n         }\n         --m_position;\n      }\n      result.first = *m_position++;\n      return result;\n   case regex_constants::syntax_escape:\n      // check to see if escapes are supported first:\n      if(this->flags() & regex_constants::no_escape_in_lists)\n      {\n         result = *m_position++;\n         break;\n      }\n      ++m_position;\n      result = unescape_character();\n      break;\n   case regex_constants::syntax_open_set:\n   {\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, m_position - m_base);\n         return result;\n      }\n      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)\n      {\n         --m_position;\n         result.first = *m_position;\n         ++m_position;\n         return result;\n      }\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, m_position - m_base);\n         return result;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching ':]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      ++m_position;\n      string_type s = this->m_traits.lookup_collatename(name_first, name_last);\n      if(s.empty() || (s.size() > 2))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      result.first = s[0];\n      if(s.size() > 1)\n         result.second = s[1];\n      else\n         result.second = 0;\n      return result;\n   }\n   default:\n      result = *m_position++;\n   }\n   return result;\n}\n\n//\n// does a value fit in the specified charT type?\n//\ntemplate <class charT>\nbool valid_value(charT, boost::intmax_t v, const mpl::true_&)\n{\n   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;\n}\ntemplate <class charT>\nbool valid_value(charT, boost::intmax_t, const mpl::false_&)\n{\n   return true; // v will alsways fit in a charT\n}\ntemplate <class charT>\nbool valid_value(charT c, boost::intmax_t v)\n{\n   return valid_value(c, v, mpl::bool_<(sizeof(charT) < sizeof(boost::intmax_t))>());\n}\n\ntemplate <class charT, class traits>\ncharT basic_regex_parser<charT, traits>::unescape_character()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   charT result(0);\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_escape, m_position - m_base, \"Escape sequence terminated prematurely.\");\n      return false;\n   }\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::escape_type_control_a:\n      result = charT('\\a');\n      break;\n   case regex_constants::escape_type_e:\n      result = charT(27);\n      break;\n   case regex_constants::escape_type_control_f:\n      result = charT('\\f');\n      break;\n   case regex_constants::escape_type_control_n:\n      result = charT('\\n');\n      break;\n   case regex_constants::escape_type_control_r:\n      result = charT('\\r');\n      break;\n   case regex_constants::escape_type_control_t:\n      result = charT('\\t');\n      break;\n   case regex_constants::escape_type_control_v:\n      result = charT('\\v');\n      break;\n   case regex_constants::escape_type_word_assert:\n      result = charT('\\b');\n      break;\n   case regex_constants::escape_type_ascii_control:\n      ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"ASCII escape sequence terminated prematurely.\");\n         return result;\n      }\n      result = static_cast<charT>(*m_position % 32);\n      break;\n   case regex_constants::escape_type_hex:\n      ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"Hexadecimal escape sequence terminated prematurely.\");\n         return result;\n      }\n      // maybe have \\x{ddd}\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base, \"Missing } in hexadecimal escape sequence.\");\n            return result;\n         }\n         boost::intmax_t i = this->m_traits.toi(m_position, m_end, 16);\n         if((m_position == m_end)\n            || (i < 0)\n            || ((std::numeric_limits<charT>::is_specialized) && (i > (boost::intmax_t)(std::numeric_limits<charT>::max)()))\n            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_badbrace, m_position - m_base, \"Hexadecimal escape sequence was invalid.\");\n            return result;\n         }\n         ++m_position;\n         result = charT(i);\n      }\n      else\n      {\n         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));\n         boost::intmax_t i = this->m_traits.toi(m_position, m_position + len, 16);\n         if((i < 0)\n            || !valid_value(charT(0), i))\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base, \"Escape sequence did not encode a valid character.\");\n            return result;\n         }\n         result = charT(i);\n      }\n      return result;\n   case regex_constants::syntax_digit:\n      {\n      // an octal escape sequence, the first character must be a zero\n      // followed by up to 3 octal digits:\n      std::ptrdiff_t len = (std::min)(::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));\n      const charT* bp = m_position;\n      boost::intmax_t val = this->m_traits.toi(bp, bp + 1, 8);\n      if(val != 0)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         // Oops not an octal escape after all:\n         fail(regex_constants::error_escape, m_position - m_base, \"Invalid octal escape sequence.\");\n         return result;\n      }\n      val = this->m_traits.toi(m_position, m_position + len, 8);\n      if((val < 0) || (val > (boost::intmax_t)(std::numeric_limits<charT>::max)()))\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"Octal escape sequence is invalid.\");\n         return result;\n      }\n      return static_cast<charT>(val);\n      }\n   case regex_constants::escape_type_named_char:\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base);\n            return false;\n         }\n         // maybe have \\N{name}\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n         {\n            const charT* base = m_position;\n            // skip forward until we find enclosing brace:\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of escape:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n               fail(regex_constants::error_escape, m_position - m_base);\n               return false;\n            }\n            string_type s = this->m_traits.lookup_collatename(++base, m_position++);\n            if(s.empty())\n            {\n               // Rewind to start of escape:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n               fail(regex_constants::error_collate, m_position - m_base);\n               return false;\n            }\n            if(s.size() == 1)\n            {\n               return s[0];\n            }\n         }\n         // fall through is a failure:\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base);\n         return false;\n      }\n   default:\n      result = *m_position;\n      break;\n   }\n   ++m_position;\n   return result;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_backref()\n{\n   BOOST_REGEX_ASSERT(m_position != m_end);\n   const charT* pc = m_position;\n   boost::intmax_t i = this->m_traits.toi(pc, pc + 1, 10);\n   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))\n   {\n      // not a backref at all but an octal escape sequence:\n      charT c = unescape_character();\n      this->append_literal(c);\n   }\n   else if((i > 0) && (this->m_backrefs.test(i)))\n   {\n      m_position = pc;\n      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));\n      pb->index = i;\n      pb->icase = this->flags() & regbase::icase;\n   }\n   else\n   {\n      // Rewind to start of escape:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n      fail(regex_constants::error_backref, m_position - m_base);\n      return false;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_QE()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   //\n   // parse a \\Q...\\E sequence:\n   //\n   ++m_position; // skip the Q\n   const charT* start = m_position;\n   const charT* end;\n   do\n   {\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))\n         ++m_position;\n      if(m_position == m_end)\n      {\n         //  a \\Q...\\E sequence may terminate with the end of the expression:\n         end = m_position;\n         break;  \n      }\n      if(++m_position == m_end) // skip the escape\n      {\n         fail(regex_constants::error_escape, m_position - m_base, \"Unterminated \\\\Q...\\\\E sequence.\");\n         return false;\n      }\n      // check to see if it's a \\E:\n      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)\n      {\n         ++m_position;\n         end = m_position - 2;\n         break;\n      }\n      // otherwise go round again:\n   }while(true);\n   //\n   // now add all the character between the two escapes as literals:\n   //\n   while(start != end)\n   {\n      this->append_literal(*start);\n      ++start;\n   }\n   return true;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_perl_extension()\n{\n   if(++m_position == m_end)\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   }\n   //\n   // treat comments as a special case, as these\n   // are the only ones that don't start with a leading\n   // startmark state:\n   //\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)\n   {\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))\n      {}\n      return true;\n   }\n   //\n   // backup some state, and prepare the way:\n   //\n   int markid = 0;\n   std::ptrdiff_t jump_offset = 0;\n   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n   pb->icase = this->flags() & regbase::icase;\n   std::ptrdiff_t last_paren_start = this->getoffset(pb);\n   // back up insertion point for alternations, and set new point:\n   std::ptrdiff_t last_alt_point = m_alt_insert_point;\n   this->m_pdata->m_data.align();\n   m_alt_insert_point = this->m_pdata->m_data.size();\n   std::ptrdiff_t expected_alt_point = m_alt_insert_point;\n   bool restore_flags = true;\n   regex_constants::syntax_option_type old_flags = this->flags();\n   bool old_case_change = m_has_case_change;\n   m_has_case_change = false;\n   charT name_delim;\n   int mark_reset = m_mark_reset;\n   int max_mark = m_max_mark;\n   m_mark_reset = -1;\n   m_max_mark = m_mark_count;\n   boost::intmax_t v;\n   //\n   // select the actual extension used:\n   //\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_or:\n      m_mark_reset = m_mark_count;\n      BOOST_FALLTHROUGH;\n   case regex_constants::syntax_colon:\n      //\n      // a non-capturing mark:\n      //\n      pb->index = markid = 0;\n      ++m_position;\n      break;\n   case regex_constants::syntax_digit:\n      {\n      //\n      // a recursive subexpression:\n      //\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"The recursive sub-expression refers to an invalid marking group, or is unterminated.\");\n         return false;\n      }\ninsert_recursion:\n      pb->index = markid = 0;\n      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));\n      pr->alt.i = v;\n      pr->state_id = 0;\n      static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = this->flags() & regbase::icase;\n      break;\n      }\n   case regex_constants::syntax_plus:\n      //\n      // A forward-relative recursive subexpression:\n      //\n      ++m_position;\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      if ((std::numeric_limits<boost::intmax_t>::max)() - m_mark_count < v)\n      {\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      v += m_mark_count;\n      goto insert_recursion;\n   case regex_constants::syntax_dash:\n      //\n      // Possibly a backward-relative recursive subexpression:\n      //\n      ++m_position;\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if(v <= 0)\n      {\n         --m_position;\n         // Oops not a relative recursion at all, but a (?-imsx) group:\n         goto option_group_jump;\n      }\n      v = static_cast<boost::intmax_t>(m_mark_count) + 1 - v;\n      if(v <= 0)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      goto insert_recursion;\n   case regex_constants::syntax_equal:\n      pb->index = markid = -1;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::syntax_not:\n      pb->index = markid = -2;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::escape_type_left_word:\n      {\n         // a lookbehind assertion:\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);\n         if(t == regex_constants::syntax_not)\n            pb->index = markid = -2;\n         else if(t == regex_constants::syntax_equal)\n            pb->index = markid = -1;\n         else\n         {\n            // Probably a named capture which also starts (?< :\n            name_delim = '>';\n            --m_position;\n            goto named_capture_jump;\n         }\n         ++m_position;\n         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n         this->append_state(syntax_element_backstep, sizeof(re_brace));\n         this->m_pdata->m_data.align();\n         m_alt_insert_point = this->m_pdata->m_data.size();\n         break;\n      }\n   case regex_constants::escape_type_right_word:\n      //\n      // an independent sub-expression:\n      //\n      pb->index = markid = -3;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::syntax_open_mark:\n      {\n      // a conditional expression:\n      pb->index = markid = -4;\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(*m_position == charT('R'))\n      {\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(*m_position == charT('&'))\n         {\n            const charT* base = ++m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));\n         }\n         else\n         {\n            v = -this->m_traits.toi(m_position, m_end, 10);\n         }\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = v < 0 ? (v - 1) : 0;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if((*m_position == charT('\\'')) || (*m_position == charT('<')))\n      {\n         const charT* base = ++m_position;\n         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\\'')))\n            ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = v;\n         if(((*m_position != charT('>')) && (*m_position != charT('\\''))) || (++m_position == m_end))\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base, \"Unterminated named capture.\");\n            return false;\n         }\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if(*m_position == charT('D'))\n      {\n         const char* def = \"DEFINE\";\n         while(*def && (m_position != m_end) && (*m_position == charT(*def)))\n            ++m_position, ++def;\n         if((m_position == m_end) || *def)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = 9999; // special magic value!\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if(v > 0)\n      {\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = v;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else\n      {\n         // verify that we have a lookahead or lookbehind assert:\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)\n         {\n            if(++m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)\n               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            m_position -= 3;\n         }\n         else\n         {\n            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)\n               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            m_position -= 2;\n         }\n      }\n      break;\n      }\n   case regex_constants::syntax_close_mark:\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   case regex_constants::escape_type_end_buffer:\n      {\n      name_delim = *m_position;\nnamed_capture_jump:\n      markid = 0;\n      if(0 == (this->flags() & regbase::nosubs))\n      {\n         markid = ++m_mark_count;\n   #ifndef BOOST_NO_STD_DISTANCE\n         if(this->flags() & regbase::save_subexpression_location)\n            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));\n   #else\n         if(this->flags() & regbase::save_subexpression_location)\n            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>((m_position - m_base) - 2, 0));\n   #endif\n      }\n      pb->index = markid;\n      const charT* base = ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      while((m_position != m_end) && (*m_position != name_delim))\n         ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      this->m_pdata->set_name(base, m_position, markid);\n      ++m_position;\n      break;\n      }\n   default:\n      if(*m_position == charT('R'))\n      {\n         ++m_position;\n         v = 0;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         goto insert_recursion;\n      }\n      if(*m_position == charT('&'))\n      {\n         ++m_position;\n         const charT* base = m_position;\n         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n            ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n         goto insert_recursion;\n      }\n      if(*m_position == charT('P'))\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(*m_position == charT('>'))\n         {\n            ++m_position;\n            const charT* base = m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n            goto insert_recursion;\n         }\n      }\n      //\n      // lets assume that we have a (?imsx) group and try and parse it:\n      //\noption_group_jump:\n      regex_constants::syntax_option_type opts = parse_options();\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      // make a note of whether we have a case change:\n      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));\n      pb->index = markid = 0;\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)\n      {\n         // update flags and carry on as normal:\n         this->flags(opts);\n         restore_flags = false;\n         old_case_change |= m_has_case_change; // defer end of scope by one ')'\n      }\n      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)\n      {\n         // update flags and carry on until the matching ')' is found:\n         this->flags(opts);\n         ++m_position;\n      }\n      else\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n\n      // finally append a case change state if we need it:\n      if(m_has_case_change)\n      {\n         static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = opts & regbase::icase;\n      }\n\n   }\n   //\n   // now recursively add more states, this will terminate when we get to a\n   // matching ')' :\n   //\n   parse_all();\n   //\n   // Unwind alternatives:\n   //\n   if(0 == unwind_alts(last_paren_start))\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base, \"Invalid alternation operators within (?...) block.\");\n      return false;\n   }\n   //\n   // we either have a ')' or we have run out of characters prematurely:\n   //\n   if(m_position == m_end)\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      this->fail(regex_constants::error_paren, ::boost::BOOST_REGEX_DETAIL_NS::distance(m_base, m_end));\n      return false;\n   }\n   BOOST_REGEX_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);\n   ++m_position;\n   //\n   // restore the flags:\n   //\n   if(restore_flags)\n   {\n      // append a case change state if we need it:\n      if(m_has_case_change)\n      {\n         static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = old_flags & regbase::icase;\n      }\n      this->flags(old_flags);\n   }\n   //\n   // set up the jump pointer if we have one:\n   //\n   if(jump_offset)\n   {\n      this->m_pdata->m_data.align();\n      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));\n      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);\n      if((this->m_last_state == jmp) && (markid != -2))\n      {\n         // Oops... we didn't have anything inside the assertion.\n         // Note we don't get here for negated forward lookahead as (?!)\n         // does have some uses.\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"Invalid or empty zero width assertion.\");\n         return false;\n      }\n   }\n   //\n   // verify that if this is conditional expression, that we do have\n   // an alternative, if not add one:\n   //\n   if(markid == -4)\n   {\n      re_syntax_base* b = this->getaddress(expected_alt_point);\n      // Make sure we have exactly one alternative following this state:\n      if(b->type != syntax_element_alt)\n      {\n         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));\n         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);\n      }\n      else if(((std::ptrdiff_t)this->m_pdata->m_data.size() > (static_cast<re_alt*>(b)->alt.i + this->getoffset(b))) && (static_cast<re_alt*>(b)->alt.i > 0) && this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)\n      {\n         // Can't have seen more than one alternative:\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_bad_pattern, m_position - m_base, \"More than one alternation operator | was encountered inside a conditional expression.\");\n         return false;\n      }\n      else\n      {\n         // We must *not* have seen an alternative inside a (DEFINE) block:\n         b = this->getaddress(b->next.i, b);\n         if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_bad_pattern, m_position - m_base, \"Alternation operators are not allowed inside a DEFINE block.\");\n            return false;\n         }\n      }\n      // check for invalid repetition of next state:\n      b = this->getaddress(expected_alt_point);\n      b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);\n      if((b->type != syntax_element_assert_backref)\n         && (b->type != syntax_element_startmark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_badrepeat, m_position - m_base, \"A repetition operator cannot be applied to a zero-width assertion.\");\n         return false;\n      }\n   }\n   //\n   // append closing parenthesis state:\n   //\n   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   this->m_paren_start = last_paren_start;\n   //\n   // restore the alternate insertion point:\n   //\n   this->m_alt_insert_point = last_alt_point;\n   //\n   // and the case change data:\n   //\n   m_has_case_change = old_case_change;\n   //\n   // And the mark_reset data:\n   //\n   if(m_max_mark > m_mark_count)\n   {\n      m_mark_count = m_max_mark;\n   }\n   m_mark_reset = mark_reset;\n   m_max_mark = max_mark;\n\n\n   if(markid > 0)\n   {\n#ifndef BOOST_NO_STD_DISTANCE\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.at((std::size_t)markid - 1).second = std::distance(m_base, m_position) - 1;\n#else\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.at(markid - 1).second = (m_position - m_base) - 1;\n#endif\n      //\n      // allow backrefs to this mark:\n      //\n      this->m_backrefs.set(markid);\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::match_verb(const char* verb)\n{\n   while(*verb)\n   {\n      if(static_cast<charT>(*verb) != *m_position)\n      {\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(++m_position == m_end)\n      {\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      ++verb;\n   }\n   return true;\n}\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable:26812)\n#endif\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_perl_verb()\n{\n   if(++m_position == m_end)\n   {\n      // Rewind to start of (* sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   }\n   switch(*m_position)\n   {\n   case 'F':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if((this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark) || match_verb(\"AIL\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_fail);\n         return true;\n      }\n      break;\n   case 'A':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"CCEPT\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_accept);\n         return true;\n      }\n      break;\n   case 'C':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"OMMIT\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_commit;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'P':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"RUNE\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_prune;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'S':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"KIP\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_skip;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'T':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"HEN\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_then);\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   }\n   // Rewind to start of (* sequence:\n   --m_position;\n   while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n   fail(regex_constants::error_perl_extension, m_position - m_base);\n   return false;\n}\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)\n{\n   //\n   // parses an emacs style \\sx or \\Sx construct.\n   //\n   if(++m_position == m_end)\n   {\n      // Rewind to start of sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n      fail(regex_constants::error_escape, m_position - m_base);\n      return false;\n   }\n   basic_char_set<charT, traits> char_set;\n   if(negate)\n      char_set.negate();\n\n   static const charT s_punct[5] = { 'p', 'u', 'n', 'c', 't', };\n\n   switch(*m_position)\n   {\n   case 's':\n   case ' ':\n      char_set.add_class(this->m_mask_space);\n      break;\n   case 'w':\n      char_set.add_class(this->m_word_mask);\n      break;\n   case '_':\n      char_set.add_single(digraph<charT>(charT('$'))); \n      char_set.add_single(digraph<charT>(charT('&'))); \n      char_set.add_single(digraph<charT>(charT('*'))); \n      char_set.add_single(digraph<charT>(charT('+'))); \n      char_set.add_single(digraph<charT>(charT('-'))); \n      char_set.add_single(digraph<charT>(charT('_'))); \n      char_set.add_single(digraph<charT>(charT('<'))); \n      char_set.add_single(digraph<charT>(charT('>'))); \n      break;\n   case '.':\n      char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));\n      break;\n   case '(':\n      char_set.add_single(digraph<charT>(charT('('))); \n      char_set.add_single(digraph<charT>(charT('['))); \n      char_set.add_single(digraph<charT>(charT('{'))); \n      break;\n   case ')':\n      char_set.add_single(digraph<charT>(charT(')'))); \n      char_set.add_single(digraph<charT>(charT(']'))); \n      char_set.add_single(digraph<charT>(charT('}'))); \n      break;\n   case '\"':\n      char_set.add_single(digraph<charT>(charT('\"'))); \n      char_set.add_single(digraph<charT>(charT('\\''))); \n      char_set.add_single(digraph<charT>(charT('`'))); \n      break;\n   case '\\'':\n      char_set.add_single(digraph<charT>(charT('\\''))); \n      char_set.add_single(digraph<charT>(charT(','))); \n      char_set.add_single(digraph<charT>(charT('#'))); \n      break;\n   case '<':\n      char_set.add_single(digraph<charT>(charT(';'))); \n      break;\n   case '>':\n      char_set.add_single(digraph<charT>(charT('\\n'))); \n      char_set.add_single(digraph<charT>(charT('\\f'))); \n      break;\n   default:\n      fail(regex_constants::error_ctype, m_position - m_base);\n      return false;\n   }\n   if(0 == this->append_set(char_set))\n   {\n      fail(regex_constants::error_ctype, m_position - m_base);\n      return false;\n   }\n   ++m_position;\n   return true;\n}\n\ntemplate <class charT, class traits>\nregex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()\n{\n   // we have a (?imsx-imsx) group, convert it into a set of flags:\n   regex_constants::syntax_option_type f = this->flags();\n   bool breakout = false;\n   do\n   {\n      switch(*m_position)\n      {\n      case 's':\n         f |= regex_constants::mod_s;\n         f &= ~regex_constants::no_mod_s;\n         break;\n      case 'm':\n         f &= ~regex_constants::no_mod_m;\n         break;\n      case 'i':\n         f |= regex_constants::icase;\n         break;\n      case 'x':\n         f |= regex_constants::mod_x;\n         break;\n      default:\n         breakout = true;\n         continue;\n      }\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_paren, m_position - m_base);\n         return false;\n      }\n   }\n   while(!breakout);\n   \n   breakout = false;\n\n   if(*m_position == static_cast<charT>('-'))\n   {\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_paren, m_position - m_base);\n         return false;\n      }\n      do\n      {\n         switch(*m_position)\n         {\n         case 's':\n            f &= ~regex_constants::mod_s;\n            f |= regex_constants::no_mod_s;\n            break;\n         case 'm':\n            f |= regex_constants::no_mod_m;\n            break;\n         case 'i':\n            f &= ~regex_constants::icase;\n            break;\n         case 'x':\n            f &= ~regex_constants::mod_x;\n            break;\n         default:\n            breakout = true;\n            continue;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_paren, m_position - m_base);\n            return false;\n         }\n      }\n      while(!breakout);\n   }\n   return f;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_start)\n{\n   //\n   // If we didn't actually add any states after the last \n   // alternative then that's an error:\n   //\n   if((this->m_alt_insert_point == static_cast<std::ptrdiff_t>(this->m_pdata->m_data.size()))\n      && (!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start)\n      &&\n      !(\n         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)\n           &&\n         ((this->flags() & regbase::no_empty_expressions) == 0)\n        )\n      )\n   {\n      fail(regex_constants::error_empty, this->m_position - this->m_base, \"Can't terminate a sub-expression with an alternation operator |.\");\n      return false;\n   }\n   // \n   // Fix up our alternatives:\n   //\n   while((!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start))\n   {\n      //\n      // fix up the jump to point to the end of the states\n      // that we've just added:\n      //\n      std::ptrdiff_t jump_offset = m_alt_jumps.back();\n      m_alt_jumps.pop_back();\n      this->m_pdata->m_data.align();\n      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));\n      if (jmp->type != syntax_element_jump)\n      {\n         // Something really bad happened, this used to be an assert, \n         // but we'll make it an error just in case we should ever get here.\n         fail(regex_constants::error_unknown, this->m_position - this->m_base, \"Internal logic failed while compiling the expression, probably you added a repeat to something non-repeatable!\");\n         return false;\n      }\n      jmp->alt.i = this->m_pdata->m_data.size() - jump_offset;\n   }\n   return true;\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/c_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         c_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class that wraps the global C locale.\n  */\n\n#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n#ifndef BOOST_REGEX_WORKAROUND_HPP\n#include <boost/regex/v4/regex_workaround.hpp>\n#endif\n\n#include <cctype>\n\n#ifdef BOOST_NO_STDC_NAMESPACE\nnamespace std{\n   using ::strlen; using ::tolower;\n}\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103 4244)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n\n   namespace BOOST_REGEX_DETAIL_NS {\n\n      enum\n      {\n         char_class_space = 1 << 0,\n         char_class_print = 1 << 1,\n         char_class_cntrl = 1 << 2,\n         char_class_upper = 1 << 3,\n         char_class_lower = 1 << 4,\n         char_class_alpha = 1 << 5,\n         char_class_digit = 1 << 6,\n         char_class_punct = 1 << 7,\n         char_class_xdigit = 1 << 8,\n         char_class_alnum = char_class_alpha | char_class_digit,\n         char_class_graph = char_class_alnum | char_class_punct,\n         char_class_blank = 1 << 9,\n         char_class_word = 1 << 10,\n         char_class_unicode = 1 << 11,\n         char_class_horizontal = 1 << 12,\n         char_class_vertical = 1 << 13\n      };\n\n   }\n\ntemplate <class charT>\nstruct c_regex_traits;\n\ntemplate<>\nstruct c_regex_traits<char>\n{\n   c_regex_traits(){}\n   typedef char char_type;\n   typedef std::size_t size_type;\n   typedef std::string string_type;\n   struct locale_type{};\n   typedef boost::uint32_t char_class_type;\n\n   static size_type length(const char_type* p) \n   { \n      return (std::strlen)(p); \n   }\n\n   char translate(char c) const \n   { \n      return c; \n   }\n   char translate_nocase(char c) const \n   { \n      return static_cast<char>((std::tolower)(static_cast<unsigned char>(c))); \n   }\n\n   static string_type BOOST_REGEX_CALL transform(const char* p1, const char* p2);\n   static string_type BOOST_REGEX_CALL transform_primary(const char* p1, const char* p2);\n\n   static char_class_type BOOST_REGEX_CALL lookup_classname(const char* p1, const char* p2);\n   static string_type BOOST_REGEX_CALL lookup_collatename(const char* p1, const char* p2);\n\n   static bool BOOST_REGEX_CALL isctype(char, char_class_type);\n   static int BOOST_REGEX_CALL value(char, int);\n\n   locale_type imbue(locale_type l)\n   { return l; }\n   locale_type getloc()const\n   { return locale_type(); }\n\nprivate:\n   // this type is not copyable:\n   c_regex_traits(const c_regex_traits&);\n   c_regex_traits& operator=(const c_regex_traits&);\n};\n\n#ifndef BOOST_NO_WREGEX\ntemplate<>\nstruct c_regex_traits<wchar_t>\n{\n   c_regex_traits(){}\n   typedef wchar_t char_type;\n   typedef std::size_t size_type;\n   typedef std::wstring string_type;\n   struct locale_type{};\n   typedef boost::uint32_t char_class_type;\n\n   static size_type length(const char_type* p) \n   { \n      return (std::wcslen)(p); \n   }\n\n   wchar_t translate(wchar_t c) const \n   { \n      return c; \n   }\n   wchar_t translate_nocase(wchar_t c) const \n   { \n      return (std::towlower)(c); \n   }\n\n   static string_type BOOST_REGEX_CALL transform(const wchar_t* p1, const wchar_t* p2);\n   static string_type BOOST_REGEX_CALL transform_primary(const wchar_t* p1, const wchar_t* p2);\n\n   static char_class_type BOOST_REGEX_CALL lookup_classname(const wchar_t* p1, const wchar_t* p2);\n   static string_type BOOST_REGEX_CALL lookup_collatename(const wchar_t* p1, const wchar_t* p2);\n\n   static bool BOOST_REGEX_CALL isctype(wchar_t, char_class_type);\n   static int BOOST_REGEX_CALL value(wchar_t, int);\n\n   locale_type imbue(locale_type l)\n   { return l; }\n   locale_type getloc()const\n   { return locale_type(); }\n\nprivate:\n   // this type is not copyable:\n   c_regex_traits(const c_regex_traits&);\n   c_regex_traits& operator=(const c_regex_traits&);\n};\n\n#endif // BOOST_NO_WREGEX\n\ninline c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform(const char* p1, const char* p2)\n{\n   std::string result(10, ' ');\n   std::size_t s = result.size();\n   std::size_t r;\n   std::string src(p1, p2);\n   while (s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))\n   {\n#if defined(_CPPLIB_VER)\n      //\n      // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n      // to std::strxfrm, but only for certain locales :-(\n      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n      //\n      if (r == INT_MAX)\n      {\n         result.erase();\n         result.insert(result.begin(), static_cast<char>(0));\n         return result;\n      }\n#endif\n      result.append(r - s + 3, ' ');\n      s = result.size();\n   }\n   result.erase(r);\n   return result;\n}\n\ninline c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform_primary(const char* p1, const char* p2)\n{\n   static char s_delim;\n   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);\n   std::string result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch (s_collate_type)\n   {\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n   {\n      result.assign(p1, p2);\n      for (std::string::size_type i = 0; i < result.size(); ++i)\n         result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));\n      result = transform(&*result.begin(), &*result.begin() + result.size());\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:\n   {\n      // get a regular sort key, and then truncate it:\n      result = transform(p1, p2);\n      result.erase(s_delim);\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:\n      // get a regular sort key, and then truncate everything after the delim:\n      result = transform(p1, p2);\n      if ((!result.empty()) && (result[0] == s_delim))\n         break;\n      std::size_t i;\n      for (i = 0; i < result.size(); ++i)\n      {\n         if (result[i] == s_delim)\n            break;\n      }\n      result.erase(i);\n      break;\n   }\n   if (result.empty())\n      result = std::string(1, char(0));\n   return result;\n}\n\ninline c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   static const char_class_type masks[] =\n   {\n      0,\n      char_class_alnum,\n      char_class_alpha,\n      char_class_blank,\n      char_class_cntrl,\n      char_class_digit,\n      char_class_digit,\n      char_class_graph,\n      char_class_horizontal,\n      char_class_lower,\n      char_class_lower,\n      char_class_print,\n      char_class_punct,\n      char_class_space,\n      char_class_space,\n      char_class_upper,\n      char_class_unicode,\n      char_class_upper,\n      char_class_vertical,\n      char_class_alnum | char_class_word,\n      char_class_alnum | char_class_word,\n      char_class_xdigit,\n   };\n\n   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if (idx < 0)\n   {\n      std::string s(p1, p2);\n      for (std::string::size_type i = 0; i < s.size(); ++i)\n         s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));\n      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n   }\n   BOOST_REGEX_ASSERT(std::size_t(idx) + 1u < sizeof(masks) / sizeof(masks[0]));\n   return masks[idx + 1];\n}\n\ninline bool BOOST_REGEX_CALL c_regex_traits<char>::isctype(char c, char_class_type mask)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   return\n      ((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))\n      || ((mask & char_class_word) && (c == '_'))\n      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n      || ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != '\\v'));\n}\n\ninline c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)\n{\n   std::string s(p1, p2);\n   s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);\n   if (s.empty() && (p2 - p1 == 1))\n      s.append(1, *p1);\n   return s;\n}\n\ninline int BOOST_REGEX_CALL c_regex_traits<char>::value(char c, int radix)\n{\n   char b[2] = { c, '\\0', };\n   char* ep;\n   int result = std::strtol(b, &ep, radix);\n   if (ep == b)\n      return -1;\n   return result;\n}\n\n#ifndef BOOST_NO_WREGEX\n\ninline c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::transform(const wchar_t* p1, const wchar_t* p2)\n{\n   std::size_t r;\n   std::size_t s = 10;\n   std::wstring src(p1, p2);\n   std::wstring result(s, L' ');\n   while (s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s)))\n   {\n#if defined(_CPPLIB_VER)\n      //\n      // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n      // to std::strxfrm, but only for certain locales :-(\n      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n      //\n      if (r == INT_MAX)\n      {\n         result.erase();\n         result.insert(result.begin(), static_cast<wchar_t>(0));\n         return result;\n      }\n#endif\n      result.append(r - s + 3, L' ');\n      s = result.size();\n   }\n   result.erase(r);\n   return result;\n}\n\ninline c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::transform_primary(const wchar_t* p1, const wchar_t* p2)\n{\n   static wchar_t s_delim;\n   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<const c_regex_traits<wchar_t>*>(0), &s_delim);\n   std::wstring result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch (s_collate_type)\n   {\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n   {\n      result.assign(p1, p2);\n      for (std::wstring::size_type i = 0; i < result.size(); ++i)\n         result[i] = (std::towlower)(result[i]);\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:\n   {\n      // get a regular sort key, and then truncate it:\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      result.erase(s_delim);\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:\n      // get a regular sort key, and then truncate everything after the delim:\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      if ((!result.empty()) && (result[0] == s_delim))\n         break;\n      std::size_t i;\n      for (i = 0; i < result.size(); ++i)\n      {\n         if (result[i] == s_delim)\n            break;\n      }\n      result.erase(i);\n      break;\n   }\n   if (result.empty())\n      result = std::wstring(1, char(0));\n   return result;\n}\n\ninline c_regex_traits<wchar_t>::char_class_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::lookup_classname(const wchar_t* p1, const wchar_t* p2)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   static const char_class_type masks[] =\n   {\n      0,\n      char_class_alnum,\n      char_class_alpha,\n      char_class_blank,\n      char_class_cntrl,\n      char_class_digit,\n      char_class_digit,\n      char_class_graph,\n      char_class_horizontal,\n      char_class_lower,\n      char_class_lower,\n      char_class_print,\n      char_class_punct,\n      char_class_space,\n      char_class_space,\n      char_class_upper,\n      char_class_unicode,\n      char_class_upper,\n      char_class_vertical,\n      char_class_alnum | char_class_word,\n      char_class_alnum | char_class_word,\n      char_class_xdigit,\n   };\n\n   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if (idx < 0)\n   {\n      std::wstring s(p1, p2);\n      for (std::wstring::size_type i = 0; i < s.size(); ++i)\n         s[i] = (std::towlower)(s[i]);\n      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n   }\n   BOOST_REGEX_ASSERT(idx + 1 < static_cast<int>(sizeof(masks) / sizeof(masks[0])));\n   return masks[idx + 1];\n}\n\ninline bool BOOST_REGEX_CALL c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_type mask)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   return\n      ((mask & char_class_space) && (std::iswspace)(c))\n      || ((mask & char_class_print) && (std::iswprint)(c))\n      || ((mask & char_class_cntrl) && (std::iswcntrl)(c))\n      || ((mask & char_class_upper) && (std::iswupper)(c))\n      || ((mask & char_class_lower) && (std::iswlower)(c))\n      || ((mask & char_class_alpha) && (std::iswalpha)(c))\n      || ((mask & char_class_digit) && (std::iswdigit)(c))\n      || ((mask & char_class_punct) && (std::iswpunct)(c))\n      || ((mask & char_class_xdigit) && (std::iswxdigit)(c))\n      || ((mask & char_class_blank) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))\n      || ((mask & char_class_word) && (c == '_'))\n      || ((mask & char_class_unicode) && (c & ~static_cast<wchar_t>(0xff)))\n      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == L'\\v')))\n      || ((mask & char_class_horizontal) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != L'\\v'));\n}\n\ninline c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2)\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4244)\n#endif\n   std::string name(p1, p2);\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n   name = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(name);\n   if (!name.empty())\n      return string_type(name.begin(), name.end());\n   if (p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ninline int BOOST_REGEX_CALL c_regex_traits<wchar_t>::value(wchar_t c, int radix)\n{\n#ifdef BOOST_BORLANDC\n   // workaround for broken wcstol:\n   if ((std::iswxdigit)(c) == 0)\n      return -1;\n#endif\n   wchar_t b[2] = { c, '\\0', };\n   wchar_t* ep;\n   int result = std::wcstol(b, &ep, radix);\n   if (ep == b)\n      return -1;\n   return result;\n}\n\n#endif\n\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/char_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         char_regex_traits.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.\n  */\n\n\n#ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP\n#define BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n\nnamespace deprecated{\n//\n// class char_regex_traits_i\n// provides case insensitive traits classes (deprecated):\ntemplate <class charT>\nclass char_regex_traits_i : public regex_traits<charT> {};\n\ntemplate<>\nclass char_regex_traits_i<char> : public regex_traits<char>\n{\npublic:\n   typedef char char_type;\n   typedef unsigned char uchar_type;\n   typedef unsigned int size_type;\n   typedef regex_traits<char> base_type;\n\n};\n\n#ifndef BOOST_NO_WREGEX\ntemplate<>\nclass char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>\n{\npublic:\n   typedef wchar_t char_type;\n   typedef unsigned short uchar_type;\n   typedef unsigned int size_type;\n   typedef regex_traits<wchar_t> base_type;\n\n};\n#endif\n} // namespace deprecated\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif // include\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/cpp_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004 John Maddock\n * Copyright 2011 Garmin Ltd. or its subsidiaries\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         cpp_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class cpp_regex_traits.\n  */\n\n#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED\n\n#include <boost/config.hpp>\n#include <boost/integer.hpp>\n#include <boost/type_traits/make_unsigned.hpp>\n\n#ifndef BOOST_NO_STD_LOCALE\n\n#ifndef BOOST_RE_PAT_EXCEPT_HPP\n#include <boost/regex/pattern_except.hpp>\n#endif\n#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n#include <boost/regex/v4/regex_traits_defaults.hpp>\n#endif\n#ifdef BOOST_HAS_THREADS\n#include <boost/regex/pending/static_mutex.hpp>\n#endif\n#ifndef BOOST_REGEX_PRIMARY_TRANSFORM\n#include <boost/regex/v4/primary_transform.hpp>\n#endif\n#ifndef BOOST_REGEX_OBJECT_CACHE_HPP\n#include <boost/regex/v4/object_cache.hpp>\n#endif\n\n#include <climits>\n#include <ios>\n#include <istream>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4786 4251)\n#endif\n\nnamespace boost{ \n\n//\n// forward declaration is needed by some compilers:\n//\ntemplate <class charT>\nclass cpp_regex_traits;\n   \nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// class parser_buf:\n// acts as a stream buffer which wraps around a pair of pointers:\n//\ntemplate <class charT,\n          class traits = ::std::char_traits<charT> >\nclass parser_buf : public ::std::basic_streambuf<charT, traits>\n{\n   typedef ::std::basic_streambuf<charT, traits> base_type;\n   typedef typename base_type::int_type int_type;\n   typedef typename base_type::char_type char_type;\n   typedef typename base_type::pos_type pos_type;\n   typedef ::std::streamsize streamsize;\n   typedef typename base_type::off_type off_type;\npublic:\n   parser_buf() : base_type() { setbuf(0, 0); }\n   const charT* getnext() { return this->gptr(); }\nprotected:\n   std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) BOOST_OVERRIDE;\n   typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) BOOST_OVERRIDE;\n   typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) BOOST_OVERRIDE;\nprivate:\n   parser_buf& operator=(const parser_buf&);\n   parser_buf(const parser_buf&);\n};\n\ntemplate<class charT, class traits>\nstd::basic_streambuf<charT, traits>*\nparser_buf<charT, traits>::setbuf(char_type* s, streamsize n)\n{\n   this->setg(s, s, s + n);\n   return this;\n}\n\ntemplate<class charT, class traits>\ntypename parser_buf<charT, traits>::pos_type\nparser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)\n{\n   typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;\n\n   if(which & ::std::ios_base::out)\n      return pos_type(off_type(-1));\n   std::ptrdiff_t size = this->egptr() - this->eback();\n   std::ptrdiff_t pos = this->gptr() - this->eback();\n   charT* g = this->eback();\n   switch(static_cast<cast_type>(way))\n   {\n   case ::std::ios_base::beg:\n      if((off < 0) || (off > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + off, g + size);\n      break;\n   case ::std::ios_base::end:\n      if((off < 0) || (off > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + size - off, g + size);\n      break;\n   case ::std::ios_base::cur:\n   {\n      std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);\n      if((newpos < 0) || (newpos > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + newpos, g + size);\n      break;\n   }\n   default: ;\n   }\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n   return static_cast<pos_type>(this->gptr() - this->eback());\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate<class charT, class traits>\ntypename parser_buf<charT, traits>::pos_type\nparser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)\n{\n   if(which & ::std::ios_base::out)\n      return pos_type(off_type(-1));\n   off_type size = static_cast<off_type>(this->egptr() - this->eback());\n   charT* g = this->eback();\n   if(off_type(sp) <= size)\n   {\n      this->setg(g, g + off_type(sp), g + size);\n   }\n   return pos_type(off_type(-1));\n}\n\n//\n// class cpp_regex_traits_base:\n// acts as a container for locale and the facets we are using.\n//\ntemplate <class charT>\nstruct cpp_regex_traits_base\n{\n   cpp_regex_traits_base(const std::locale& l)\n   { (void)imbue(l); }\n   std::locale imbue(const std::locale& l);\n\n   std::locale m_locale;\n   std::ctype<charT> const* m_pctype;\n#ifndef BOOST_NO_STD_MESSAGES\n   std::messages<charT> const* m_pmessages;\n#endif\n   std::collate<charT> const* m_pcollate;\n\n   bool operator<(const cpp_regex_traits_base& b)const\n   {\n      if(m_pctype == b.m_pctype)\n      {\n#ifndef BOOST_NO_STD_MESSAGES\n         if(m_pmessages == b.m_pmessages)\n         {\n            return m_pcollate < b.m_pcollate;\n         }\n         return m_pmessages < b.m_pmessages;\n#else\n         return m_pcollate < b.m_pcollate;\n#endif\n      }\n      return m_pctype < b.m_pctype;\n   }\n   bool operator==(const cpp_regex_traits_base& b)const\n   {\n      return (m_pctype == b.m_pctype) \n#ifndef BOOST_NO_STD_MESSAGES\n         && (m_pmessages == b.m_pmessages) \n#endif\n         && (m_pcollate == b.m_pcollate);\n   }\n};\n\ntemplate <class charT>\nstd::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)\n{\n   std::locale result(m_locale);\n   m_locale = l;\n   m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);\n#ifndef BOOST_NO_STD_MESSAGES\n   m_pmessages = BOOST_HAS_FACET(std::messages<charT>, l) ? &BOOST_USE_FACET(std::messages<charT>, l) : 0;\n#endif\n   m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);\n   return result;\n}\n\n//\n// class cpp_regex_traits_char_layer:\n// implements methods that require specialization for narrow characters:\n//\ntemplate <class charT>\nclass cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>\n{\n   typedef std::basic_string<charT> string_type;\n   typedef std::map<charT, regex_constants::syntax_type> map_type;\n   typedef typename map_type::const_iterator map_iterator_type;\npublic:\n   cpp_regex_traits_char_layer(const std::locale& l)\n      : cpp_regex_traits_base<charT>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)\n      : cpp_regex_traits_base<charT>(b)\n   {\n      init();\n   }\n   void init();\n\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      return ((i == m_char_map.end()) ? 0 : i->second);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      if(i == m_char_map.end())\n      {\n         if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;\n         if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;\n         return 0;\n      }\n      return i->second;\n   }\n\nprivate:\n   string_type get_default_message(regex_constants::syntax_type);\n   // TODO: use a hash table when available!\n   map_type m_char_map;\n};\n\ntemplate <class charT>\nvoid cpp_regex_traits_char_layer<charT>::init()\n{\n   // we need to start by initialising our syntax map so we know which\n   // character is used for which purpose:\n#ifndef BOOST_NO_STD_MESSAGES\n#ifndef __IBMCPP__\n   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());\n   if((!cat_name.empty()) && (this->m_pmessages != 0))\n   {\n      cat = this->m_pmessages->open(\n         cat_name, \n         this->m_locale);\n      if((int)cat < 0)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if((int)cat >= 0)\n   {\n#ifndef BOOST_NO_EXCEPTIONS\n      try{\n#endif\n         for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));\n            for(typename string_type::size_type j = 0; j < mss.size(); ++j)\n            {\n               m_char_map[mss[j]] = i;\n            }\n         }\n         this->m_pmessages->close(cat);\n#ifndef BOOST_NO_EXCEPTIONS\n      }\n      catch(...)\n      {\n         if(this->m_pmessages)\n            this->m_pmessages->close(cat);\n         throw;\n      }\n#endif\n   }\n   else\n   {\n#endif\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         const char* ptr = get_default_syntax(i);\n         while(ptr && *ptr)\n         {\n            m_char_map[this->m_pctype->widen(*ptr)] = i;\n            ++ptr;\n         }\n      }\n#ifndef BOOST_NO_STD_MESSAGES\n   }\n#endif\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_char_layer<charT>::string_type \n   cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)\n{\n   const char* ptr = get_default_syntax(i);\n   string_type result;\n   while(ptr && *ptr)\n   {\n      result.append(1, this->m_pctype->widen(*ptr));\n      ++ptr;\n   }\n   return result;\n}\n\n//\n// specialized version for narrow characters:\n//\ntemplate <>\nclass cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>\n{\n   typedef std::string string_type;\npublic:\n   cpp_regex_traits_char_layer(const std::locale& l)\n   : cpp_regex_traits_base<char>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)\n   : cpp_regex_traits_base<char>(l)\n   {\n      init();\n   }\n\n   regex_constants::syntax_type syntax_type(char c)const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(char c) const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n\nprivate:\n   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];\n   void init();\n};\n\n#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET\nenum\n{\n   char_class_space=1<<0, \n   char_class_print=1<<1, \n   char_class_cntrl=1<<2, \n   char_class_upper=1<<3, \n   char_class_lower=1<<4,\n   char_class_alpha=1<<5, \n   char_class_digit=1<<6, \n   char_class_punct=1<<7, \n   char_class_xdigit=1<<8,\n   char_class_alnum=char_class_alpha|char_class_digit, \n   char_class_graph=char_class_alnum|char_class_punct,\n   char_class_blank=1<<9,\n   char_class_word=1<<10,\n   char_class_unicode=1<<11,\n   char_class_horizontal_space=1<<12,\n   char_class_vertical_space=1<<13\n};\n\n#endif\n\n//\n// class cpp_regex_traits_implementation:\n// provides pimpl implementation for cpp_regex_traits.\n//\ntemplate <class charT>\nclass cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>\n{\npublic:\n   typedef typename cpp_regex_traits<charT>::char_class_type      char_class_type;\n   typedef typename std::ctype<charT>::mask                       native_mask_type;\n   typedef typename boost::make_unsigned<native_mask_type>::type  unsigned_native_mask_type;\n#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET\n   BOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);\n   BOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);\n   BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);\n   BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);\n   BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);\n#endif\n\n   typedef std::basic_string<charT> string_type;\n   typedef charT char_type;\n   //cpp_regex_traits_implementation();\n   cpp_regex_traits_implementation(const std::locale& l)\n      : cpp_regex_traits_char_layer<charT>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)\n      : cpp_regex_traits_char_layer<charT>(l)\n   {\n      init();\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      if(!m_error_strings.empty())\n      {\n         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);\n         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;\n      }\n      return get_default_error_string(n);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      char_class_type result = lookup_classname_imp(p1, p2);\n      if(result == 0)\n      {\n         string_type temp(p1, p2);\n         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());\n         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());\n      }\n      return result;\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const;\n   string_type transform_primary(const charT* p1, const charT* p2) const;\n   string_type transform(const charT* p1, const charT* p2) const;\nprivate:\n   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID\n   std::map<string_type, char_class_type>  m_custom_class_names; // character class names\n   std::map<string_type, string_type>      m_custom_collate_names; // collating element names\n   unsigned                       m_collate_type;    // the form of the collation string\n   charT                          m_collate_delim;   // the collation group delimiter\n   //\n   // helpers:\n   //\n   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;\n   void init();\n#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET\npublic:\n   bool isctype(charT c, char_class_type m)const;\n#endif\n};\n\n#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET\n#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;\n\n#endif\n#endif\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const\n{\n   //\n   // PRECONDITIONS:\n   //\n   // A bug in gcc 3.2 (and maybe other versions as well) treats\n   // p1 as a null terminated string, for efficiency reasons \n   // we work around this elsewhere, but just assert here that\n   // we adhere to gcc's (buggy) preconditions...\n   //\n   BOOST_REGEX_ASSERT(*p2 == 0);\n   string_type result;\n#if defined(_CPPLIB_VER)\n   //\n   // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n   // to std::collate::transform, but only for certain locales :-(\n   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n   //\n   if(*p1 == 0)\n   {\n      return string_type(1, charT(0));\n   }\n#endif\n   //\n   // swallowing all exceptions here is a bad idea\n   // however at least one std lib will always throw\n   // std::bad_alloc for certain arguments...\n   //\n#ifndef BOOST_NO_EXCEPTIONS\n   try{\n#endif\n      //\n      // What we do here depends upon the format of the sort key returned by\n      // sort key returned by this->transform:\n      //\n      switch(m_collate_type)\n      {\n      case sort_C:\n      case sort_unknown:\n         // the best we can do is translate to lower case, then get a regular sort key:\n         {\n            result.assign(p1, p2);\n            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());\n            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());\n            break;\n         }\n      case sort_fixed:\n         {\n            // get a regular sort key, and then truncate it:\n            result.assign(this->m_pcollate->transform(p1, p2));\n            result.erase(this->m_collate_delim);\n            break;\n         }\n      case sort_delim:\n            // get a regular sort key, and then truncate everything after the delim:\n            result.assign(this->m_pcollate->transform(p1, p2));\n            std::size_t i;\n            for(i = 0; i < result.size(); ++i)\n            {\n               if(result[i] == m_collate_delim)\n                  break;\n            }\n            result.erase(i);\n            break;\n      }\n#ifndef BOOST_NO_EXCEPTIONS\n   }catch(...){}\n#endif\n   while((!result.empty()) && (charT(0) == *result.rbegin()))\n      result.erase(result.size() - 1);\n   if(result.empty())\n   {\n      // character is ignorable at the primary level:\n      result = string_type(1, charT(0));\n   }\n   return result;\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const\n{\n   //\n   // PRECONDITIONS:\n   //\n   // A bug in gcc 3.2 (and maybe other versions as well) treats\n   // p1 as a null terminated string, for efficiency reasons \n   // we work around this elsewhere, but just assert here that\n   // we adhere to gcc's (buggy) preconditions...\n   //\n   BOOST_REGEX_ASSERT(*p2 == 0);\n   //\n   // swallowing all exceptions here is a bad idea\n   // however at least one std lib will always throw\n   // std::bad_alloc for certain arguments...\n   //\n   string_type result, result2;\n#if defined(_CPPLIB_VER)\n   //\n   // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n   // to std::collate::transform, but only for certain locales :-(\n   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n   //\n   if(*p1 == 0)\n   {\n      return result;\n   }\n#endif\n#ifndef BOOST_NO_EXCEPTIONS\n   try{\n#endif\n      result = this->m_pcollate->transform(p1, p2);\n      //\n      // Borland's STLPort version returns a NULL-terminated\n      // string that has garbage at the end - each call to\n      // std::collate<wchar_t>::transform returns a different string!\n      // So as a workaround, we'll truncate the string at the first NULL\n      // which _seems_ to work....\n#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x580)\n      result.erase(result.find(charT(0)));\n#else\n      //\n      // some implementations (Dinkumware) append unnecessary trailing \\0's:\n      while((!result.empty()) && (charT(0) == *result.rbegin()))\n         result.erase(result.size() - 1);\n#endif\n      //\n      // We may have NULL's used as separators between sections of the collate string,\n      // an example would be Boost.Locale.  We have no way to detect this case via\n      // #defines since this can be used with any compiler/platform combination.\n      // Unfortunately our state machine (which was devised when all implementations\n      // used underlying C language API's) can't cope with that case.  One workaround\n      // is to replace each character with 2, fortunately this code isn't used that\n      // much as this is now slower than before :-(\n      //\n      typedef typename make_unsigned<charT>::type uchar_type;\n      result2.reserve(result.size() * 2 + 2);\n      for(unsigned i = 0; i < result.size(); ++i)\n      {\n         if(static_cast<uchar_type>(result[i]) == (std::numeric_limits<uchar_type>::max)())\n         {\n            result2.append(1, charT((std::numeric_limits<uchar_type>::max)())).append(1, charT('b'));\n         }\n         else\n         {\n            result2.append(1, static_cast<charT>(1 + static_cast<uchar_type>(result[i]))).append(1, charT('b') - 1);\n         }\n      }\n      BOOST_REGEX_ASSERT(std::find(result2.begin(), result2.end(), charT(0)) == result2.end());\n#ifndef BOOST_NO_EXCEPTIONS\n   }\n   catch(...)\n   {\n   }\n#endif\n   return result2;\n}\n\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const\n{\n   typedef typename std::map<string_type, string_type>::const_iterator iter_type;\n   if(!m_custom_collate_names.empty())\n   {\n      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));\n      if(pos != m_custom_collate_names.end())\n         return pos->second;\n   }\n#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\\\n               && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0551)\n   std::string name(p1, p2);\n#else\n   std::string name;\n   const charT* p0 = p1;\n   while(p0 != p2)\n      name.append(1, char(*p0++));\n#endif\n   name = lookup_default_collate_name(name);\n#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\\\n               && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0551)\n   if(!name.empty())\n      return string_type(name.begin(), name.end());\n#else\n   if(!name.empty())\n   {\n      string_type result;\n      typedef std::string::const_iterator iter;\n      iter b = name.begin();\n      iter e = name.end();\n      while(b != e)\n         result.append(1, charT(*b++));\n      return result;\n   }\n#endif\n   if(p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ntemplate <class charT>\nvoid cpp_regex_traits_implementation<charT>::init()\n{\n#ifndef BOOST_NO_STD_MESSAGES\n#ifndef __IBMCPP__\n   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());\n   if((!cat_name.empty()) && (this->m_pmessages != 0))\n   {\n      cat = this->m_pmessages->open(\n         cat_name, \n         this->m_locale);\n      if((int)cat < 0)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if((int)cat >= 0)\n   {\n      //\n      // Error messages:\n      //\n      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); \n         i <= boost::regex_constants::error_unknown; \n         i = static_cast<boost::regex_constants::error_type>(i + 1))\n      {\n         const char* p = get_default_error_string(i);\n         string_type default_message;\n         while(*p)\n         {\n            default_message.append(1, this->m_pctype->widen(*p));\n            ++p;\n         }\n         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);\n         std::string result;\n         for(std::string::size_type j = 0; j < s.size(); ++j)\n         {\n            result.append(1, this->m_pctype->narrow(s[j], 0));\n         }\n         m_error_strings[i] = result;\n      }\n      //\n      // Custom class names:\n      //\n#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET\n      static const char_class_type masks[16] = \n      {\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alnum),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alpha),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::cntrl),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::digit),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::graph),\n         cpp_regex_traits_implementation<charT>::mask_horizontal,\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::lower),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::print),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::punct),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::space),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::upper),\n         cpp_regex_traits_implementation<charT>::mask_vertical,\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::xdigit),\n         cpp_regex_traits_implementation<charT>::mask_blank,\n         cpp_regex_traits_implementation<charT>::mask_word,\n         cpp_regex_traits_implementation<charT>::mask_unicode,\n      };\n#else\n      static const char_class_type masks[16] = \n      {\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_alnum,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_alpha,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_cntrl,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_digit,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_graph,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_horizontal_space,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_lower,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_print,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_punct,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_space,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_upper,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_vertical_space,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_xdigit,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_blank,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_word,\n         ::boost::BOOST_REGEX_DETAIL_NS::char_class_unicode,\n      };\n#endif\n      static const string_type null_string;\n      for(unsigned int j = 0; j <= 13; ++j)\n      {\n         string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));\n         if(!s.empty())\n            this->m_custom_class_names[s] = masks[j];\n      }\n   }\n#endif\n   //\n   // get the collation format used by m_pcollate:\n   //\n   m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type \n   cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const\n{\n#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET\n   static const char_class_type masks[22] = \n   {\n      0,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alpha),\n      cpp_regex_traits_implementation<charT>::mask_blank,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::cntrl),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::graph),\n      cpp_regex_traits_implementation<charT>::mask_horizontal,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::print),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::punct),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),\n      cpp_regex_traits_implementation<charT>::mask_unicode,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),\n      cpp_regex_traits_implementation<charT>::mask_vertical,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, \n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, \n      static_cast<unsigned_native_mask_type>(std::ctype<char>::xdigit),\n   };\n#else\n   static const char_class_type masks[22] = \n   {\n      0,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_alnum, \n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_alpha,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_blank,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_cntrl,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_digit,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_digit,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_graph,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_horizontal_space,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_lower,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_lower,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_print,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_punct,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_space,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_space,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_upper,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_unicode,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_upper,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_vertical_space,\n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_alnum | ::boost::BOOST_REGEX_DETAIL_NS::char_class_word, \n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_alnum | ::boost::BOOST_REGEX_DETAIL_NS::char_class_word, \n      ::boost::BOOST_REGEX_DETAIL_NS::char_class_xdigit,\n   };\n#endif\n   if(!m_custom_class_names.empty())\n   {\n      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;\n      map_iter pos = m_custom_class_names.find(string_type(p1, p2));\n      if(pos != m_custom_class_names.end())\n         return pos->second;\n   }\n   std::size_t state_id = 1 + BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   BOOST_REGEX_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));\n   return masks[state_id];\n}\n\n#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET\ntemplate <class charT>\nbool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const\n{\n   return\n      ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c)))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_word) && (c == '_'))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_unicode) && ::boost::BOOST_REGEX_DETAIL_NS::is_extended(c))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_vertical_space) && (is_separator(c) || (c == '\\v')))\n      || ((mask & ::boost::BOOST_REGEX_DETAIL_NS::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\\v')));\n}\n#endif\n\n\ntemplate <class charT>\ninline boost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)\n{\n   cpp_regex_traits_base<charT> key(l);\n   return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);\n}\n\n} // BOOST_REGEX_DETAIL_NS\n\ntemplate <class charT>\nclass cpp_regex_traits\n{\nprivate:\n   typedef std::ctype<charT>            ctype_type;\npublic:\n   typedef charT                        char_type;\n   typedef std::size_t                  size_type;\n   typedef std::basic_string<char_type> string_type;\n   typedef std::locale                  locale_type;\n   typedef boost::uint_least32_t        char_class_type;\n\n   struct boost_extensions_tag{};\n\n   cpp_regex_traits()\n      : m_pimpl(BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(std::locale()))\n   { }\n   static size_type length(const char_type* p)\n   {\n      return std::char_traits<charT>::length(p);\n   }\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      return m_pimpl->syntax_type(c);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      return m_pimpl->escape_syntax_type(c);\n   }\n   charT translate(charT c) const\n   {\n      return c;\n   }\n   charT translate_nocase(charT c) const\n   {\n      return m_pimpl->m_pctype->tolower(c);\n   }\n   charT translate(charT c, bool icase) const\n   {\n      return icase ? m_pimpl->m_pctype->tolower(c) : c;\n   }\n   charT tolower(charT c) const\n   {\n      return m_pimpl->m_pctype->tolower(c);\n   }\n   charT toupper(charT c) const\n   {\n      return m_pimpl->m_pctype->toupper(c);\n   }\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform(p1, p2);\n   }\n   string_type transform_primary(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform_primary(p1, p2);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_classname(p1, p2);\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_collatename(p1, p2);\n   }\n   bool isctype(charT c, char_class_type f) const\n   {\n#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET\n      typedef typename std::ctype<charT>::mask ctype_mask;\n\n      static const ctype_mask mask_base = \n         static_cast<ctype_mask>(\n            std::ctype<charT>::alnum \n            | std::ctype<charT>::alpha\n            | std::ctype<charT>::cntrl\n            | std::ctype<charT>::digit\n            | std::ctype<charT>::graph\n            | std::ctype<charT>::lower\n            | std::ctype<charT>::print\n            | std::ctype<charT>::punct\n            | std::ctype<charT>::space\n            | std::ctype<charT>::upper\n            | std::ctype<charT>::xdigit);\n\n      if((f & mask_base) \n         && (m_pimpl->m_pctype->is(\n            static_cast<ctype_mask>(f & mask_base), c)))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_blank) \n         && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)\n         && !BOOST_REGEX_DETAIL_NS::is_separator(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical) \n         && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_horizontal) \n         && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical))\n         return true;\n#ifdef __CYGWIN__\n      //\n      // Cygwin has a buggy ctype facet, see https://www.cygwin.com/ml/cygwin/2012-08/msg00178.html:\n      //\n      else if((f & std::ctype<charT>::xdigit) == std::ctype<charT>::xdigit)\n      {\n         if((c >= 'a') && (c <= 'f'))\n            return true;\n         if((c >= 'A') && (c <= 'F'))\n            return true;\n      }\n#endif\n      return false;\n#else\n      return m_pimpl->isctype(c, f);\n#endif\n   }\n   boost::intmax_t toi(const charT*& p1, const charT* p2, int radix)const;\n   int value(charT c, int radix)const\n   {\n      const charT* pc = &c;\n      return (int)toi(pc, pc + 1, radix);\n   }\n   locale_type imbue(locale_type l)\n   {\n      std::locale result(getloc());\n      m_pimpl = BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(l);\n      return result;\n   }\n   locale_type getloc()const\n   {\n      return m_pimpl->m_locale;\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      return m_pimpl->error_string(n);\n   }\n\n   //\n   // extension:\n   // set the name of the message catalog in use (defaults to \"boost_regex\").\n   //\n   static std::string catalog_name(const std::string& name);\n   static std::string get_catalog_name();\n\nprivate:\n   boost::shared_ptr<const BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT> > m_pimpl;\n   //\n   // catalog name handler:\n   //\n   static std::string& get_catalog_name_inst();\n\n#ifdef BOOST_HAS_THREADS\n   static static_mutex& get_mutex_inst();\n#endif\n};\n\n\ntemplate <class charT>\nboost::intmax_t cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const\n{\n   BOOST_REGEX_DETAIL_NS::parser_buf<charT>   sbuf;            // buffer for parsing numbers.\n   std::basic_istream<charT>      is(&sbuf);       // stream for parsing numbers.\n\n   // we do NOT want to parse any thousands separators inside the stream:\n   last = std::find(first, last, BOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());\n\n   sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));\n   is.clear();\n   if(std::abs(radix) == 16) is >> std::hex;\n   else if(std::abs(radix) == 8) is >> std::oct;\n   else is >> std::dec;\n   boost::intmax_t val;\n   if(is >> val)\n   {\n      first = first + ((last - first) - sbuf.in_avail());\n      return val;\n   }\n   else\n      return -1;\n}\n\ntemplate <class charT>\nstd::string cpp_regex_traits<charT>::catalog_name(const std::string& name)\n{\n#ifdef BOOST_HAS_THREADS\n   static_mutex::scoped_lock lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   get_catalog_name_inst() = name;\n   return result;\n}\n\ntemplate <class charT>\nstd::string& cpp_regex_traits<charT>::get_catalog_name_inst()\n{\n   static std::string s_name;\n   return s_name;\n}\n\ntemplate <class charT>\nstd::string cpp_regex_traits<charT>::get_catalog_name()\n{\n#ifdef BOOST_HAS_THREADS\n   static_mutex::scoped_lock lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   return result;\n}\n\n#ifdef BOOST_HAS_THREADS\ntemplate <class charT>\nstatic_mutex& cpp_regex_traits<charT>::get_mutex_inst()\n{\n   static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;\n   return s_mutex;\n}\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS {\n\n   inline void cpp_regex_traits_char_layer<char>::init()\n   {\n      // we need to start by initialising our syntax map so we know which\n      // character is used for which purpose:\n      std::memset(m_char_map, 0, sizeof(m_char_map));\n#ifndef BOOST_NO_STD_MESSAGES\n#ifndef __IBMCPP__\n      std::messages<char>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n      std::messages<char>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n      std::string cat_name(cpp_regex_traits<char>::get_catalog_name());\n      if ((!cat_name.empty()) && (m_pmessages != 0))\n      {\n         cat = this->m_pmessages->open(\n            cat_name,\n            this->m_locale);\n         if ((int)cat < 0)\n         {\n            std::string m(\"Unable to open message catalog: \");\n            std::runtime_error err(m + cat_name);\n            boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n         }\n      }\n      //\n      // if we have a valid catalog then load our messages:\n      //\n      if ((int)cat >= 0)\n      {\n#ifndef BOOST_NO_EXCEPTIONS\n         try {\n#endif\n            for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n            {\n               string_type mss = this->m_pmessages->get(cat, 0, i, get_default_syntax(i));\n               for (string_type::size_type j = 0; j < mss.size(); ++j)\n               {\n                  m_char_map[static_cast<unsigned char>(mss[j])] = i;\n               }\n            }\n            this->m_pmessages->close(cat);\n#ifndef BOOST_NO_EXCEPTIONS\n         }\n         catch (...)\n         {\n            this->m_pmessages->close(cat);\n            throw;\n         }\n#endif\n      }\n      else\n      {\n#endif\n         for (regex_constants::syntax_type j = 1; j < regex_constants::syntax_max; ++j)\n         {\n            const char* ptr = get_default_syntax(j);\n            while (ptr && *ptr)\n            {\n               m_char_map[static_cast<unsigned char>(*ptr)] = j;\n               ++ptr;\n            }\n         }\n#ifndef BOOST_NO_STD_MESSAGES\n      }\n#endif\n      //\n      // finish off by calculating our escape types:\n      //\n      unsigned char i = 'A';\n      do\n      {\n         if (m_char_map[i] == 0)\n         {\n            if (this->m_pctype->is(std::ctype_base::lower, i))\n               m_char_map[i] = regex_constants::escape_type_class;\n            else if (this->m_pctype->is(std::ctype_base::upper, i))\n               m_char_map[i] = regex_constants::escape_type_not_class;\n         }\n      } while (0xFF != i++);\n   }\n\n} // namespace detail\n\n\n} // boost\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/cregex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         cregex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares POSIX API functions\n  *                + boost::RegEx high level wrapper.\n  */\n\n#ifndef BOOST_RE_CREGEX_HPP_INCLUDED\n#define BOOST_RE_CREGEX_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n#include <boost/regex/v4/match_flags.hpp>\n#include <boost/regex/v4/error_type.hpp>\n\n#ifdef __cplusplus\n#include <cstddef>\n#else\n#include <stddef.h>\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n/* include these defs only for POSIX compatablity */\n#ifdef __cplusplus\nnamespace boost{\nextern \"C\" {\n#endif\n\n#if defined(__cplusplus) && !defined(BOOST_NO_STDC_NAMESPACE)\ntypedef std::ptrdiff_t regoff_t;\ntypedef std::size_t regsize_t;\n#else\ntypedef ptrdiff_t regoff_t;\ntypedef size_t regsize_t;\n#endif\n\ntypedef struct\n{\n   unsigned int re_magic;\n#ifdef __cplusplus\n   std::size_t  re_nsub;      /* number of parenthesized subexpressions */\n#else\n   size_t re_nsub; \n#endif\n   const char*  re_endp;       /* end pointer for REG_PEND */\n   void* guts;                /* none of your business :-) */\n   match_flag_type eflags;        /* none of your business :-) */\n} regex_tA;\n\n#ifndef BOOST_NO_WREGEX\ntypedef struct\n{\n   unsigned int re_magic;\n#ifdef __cplusplus\n   std::size_t  re_nsub;         /* number of parenthesized subexpressions */\n#else\n   size_t re_nsub;\n#endif\n   const wchar_t* re_endp;       /* end pointer for REG_PEND */\n   void* guts;                   /* none of your business :-) */\n   match_flag_type eflags;           /* none of your business :-) */\n} regex_tW;\n#endif\n\ntypedef struct\n{\n   regoff_t rm_so;      /* start of match */\n   regoff_t rm_eo;      /* end of match */\n} regmatch_t;\n\n/* regcomp() flags */\ntypedef enum{\n   REG_BASIC = 0000,\n   REG_EXTENDED = 0001,\n   REG_ICASE = 0002,\n   REG_NOSUB = 0004,\n   REG_NEWLINE = 0010,\n   REG_NOSPEC = 0020,\n   REG_PEND = 0040,\n   REG_DUMP = 0200,\n   REG_NOCOLLATE = 0400,\n   REG_ESCAPE_IN_LISTS = 01000,\n   REG_NEWLINE_ALT = 02000,\n   REG_PERLEX = 04000,\n\n   REG_PERL = REG_EXTENDED | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | REG_PERLEX,\n   REG_AWK = REG_EXTENDED | REG_ESCAPE_IN_LISTS,\n   REG_GREP = REG_BASIC | REG_NEWLINE_ALT,\n   REG_EGREP = REG_EXTENDED | REG_NEWLINE_ALT,\n\n   REG_ASSERT = 15,\n   REG_INVARG = 16,\n   REG_ATOI = 255,   /* convert name to number (!) */\n   REG_ITOA = 0400   /* convert number to name (!) */\n} reg_comp_flags;\n\n/* regexec() flags */\ntypedef enum{\n   REG_NOTBOL =    00001,\n   REG_NOTEOL =    00002,\n   REG_STARTEND =  00004\n} reg_exec_flags;\n\n/*\n * POSIX error codes:\n */\ntypedef unsigned reg_error_t;\ntypedef reg_error_t reg_errcode_t;  /* backwards compatibility */\n\nstatic const reg_error_t REG_NOERROR = 0;   /* Success.  */\nstatic const reg_error_t REG_NOMATCH = 1;   /* Didn't find a match (for regexec).  */\n\n  /* POSIX regcomp return error codes.  (In the order listed in the\n     standard.)  */\nstatic const reg_error_t REG_BADPAT = 2;    /* Invalid pattern.  */\nstatic const reg_error_t REG_ECOLLATE = 3;  /* Undefined collating element.  */\nstatic const reg_error_t REG_ECTYPE = 4;    /* Invalid character class name.  */\nstatic const reg_error_t REG_EESCAPE = 5;   /* Trailing backslash.  */\nstatic const reg_error_t REG_ESUBREG = 6;   /* Invalid back reference.  */\nstatic const reg_error_t REG_EBRACK = 7;    /* Unmatched left bracket.  */\nstatic const reg_error_t REG_EPAREN = 8;    /* Parenthesis imbalance.  */\nstatic const reg_error_t REG_EBRACE = 9;    /* Unmatched \\{.  */\nstatic const reg_error_t REG_BADBR = 10;    /* Invalid contents of \\{\\}.  */\nstatic const reg_error_t REG_ERANGE = 11;   /* Invalid range end.  */\nstatic const reg_error_t REG_ESPACE = 12;   /* Ran out of memory.  */\nstatic const reg_error_t REG_BADRPT = 13;   /* No preceding re for repetition op.  */\nstatic const reg_error_t REG_EEND = 14;     /* unexpected end of expression */\nstatic const reg_error_t REG_ESIZE = 15;    /* expression too big */\nstatic const reg_error_t REG_ERPAREN = 8;   /* = REG_EPAREN : unmatched right parenthesis */\nstatic const reg_error_t REG_EMPTY = 17;    /* empty expression */\nstatic const reg_error_t REG_E_MEMORY = 15; /* = REG_ESIZE : out of memory */\nstatic const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */\nstatic const reg_error_t REG_ESTACK = 19;   /* out of stack space */\nstatic const reg_error_t REG_E_PERL = 20;   /* Perl (?...) error */\nstatic const reg_error_t REG_E_UNKNOWN = 21; /* unknown error */\nstatic const reg_error_t REG_ENOSYS = 21;   /* = REG_E_UNKNOWN : Reserved. */\n\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA*, const char*, int);\nBOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int, const regex_tA*, char*, regsize_t);\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA*, const char*, regsize_t, regmatch_t*, int);\nBOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA*);\n\n#ifndef BOOST_NO_WREGEX\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW*, const wchar_t*, int);\nBOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int, const regex_tW*, wchar_t*, regsize_t);\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW*, const wchar_t*, regsize_t, regmatch_t*, int);\nBOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW*);\n#endif\n\n#ifdef UNICODE\n#define regcomp regcompW\n#define regerror regerrorW\n#define regexec regexecW\n#define regfree regfreeW\n#define regex_t regex_tW\n#else\n#define regcomp regcompA\n#define regerror regerrorA\n#define regexec regexecA\n#define regfree regfreeA\n#define regex_t regex_tA\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n} /* namespace */\n#endif\n\n#endif /* include guard */\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/error_type.hpp",
    "content": "/*\n *\n * Copyright (c) 2003-2005\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         error_type.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression error type enumerator.\n  */\n\n#ifndef BOOST_REGEX_ERROR_TYPE_HPP\n#define BOOST_REGEX_ERROR_TYPE_HPP\n\n#ifdef __cplusplus\nnamespace boost{\n#endif\n\n#ifdef __cplusplus\nnamespace regex_constants{\n\nenum error_type{\n\n   error_ok = 0,         /* not used */\n   error_no_match = 1,   /* not used */\n   error_bad_pattern = 2,\n   error_collate = 3,\n   error_ctype = 4,\n   error_escape = 5,\n   error_backref = 6,\n   error_brack = 7,\n   error_paren = 8,\n   error_brace = 9,\n   error_badbrace = 10,\n   error_range = 11,\n   error_space = 12,\n   error_badrepeat = 13,\n   error_end = 14,    /* not used */\n   error_size = 15,\n   error_right_paren = 16,  /* not used */\n   error_empty = 17,\n   error_complexity = 18,\n   error_stack = 19,\n   error_perl_extension = 20,\n   error_unknown = 21\n};\n\n}\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/icu.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         icu.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.\n  */\n\n#ifndef BOOST_REGEX_ICU_V4_HPP\n#define BOOST_REGEX_ICU_V4_HPP\n\n#include <boost/config.hpp>\n#include <unicode/utypes.h>\n#include <unicode/uchar.h>\n#include <unicode/coll.h>\n#include <boost/regex.hpp>\n#include <boost/regex/v4/unicode_iterator.hpp>\n#include <boost/mpl/int_fwd.hpp>\n#include <boost/static_assert.hpp>\n#include <bitset>\n\n#ifdef BOOST_MSVC\n#pragma warning (push)\n#pragma warning (disable: 4251)\n#endif\n\nnamespace boost {\n\n   namespace BOOST_REGEX_DETAIL_NS {\n\n      // \n      // Implementation details:\n      //\n      class icu_regex_traits_implementation\n      {\n         typedef UChar32                      char_type;\n         typedef std::size_t                  size_type;\n         typedef std::vector<char_type>       string_type;\n         typedef U_NAMESPACE_QUALIFIER Locale locale_type;\n         typedef boost::uint_least32_t        char_class_type;\n      public:\n         icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)\n            : m_locale(l)\n         {\n            UErrorCode success = U_ZERO_ERROR;\n            m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));\n            if (U_SUCCESS(success) == 0)\n               init_error();\n            m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);\n            success = U_ZERO_ERROR;\n            m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));\n            if (U_SUCCESS(success) == 0)\n               init_error();\n            m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);\n         }\n         U_NAMESPACE_QUALIFIER Locale getloc()const\n         {\n            return m_locale;\n         }\n         string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const\n         {\n            // TODO make thread safe!!!! :\n            typedef u32_to_u16_iterator<const char_type*, ::UChar> itt;\n            itt i(p1), j(p2);\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n            std::vector< ::UChar> t(i, j);\n#else\n            std::vector< ::UChar> t;\n            while (i != j)\n               t.push_back(*i++);\n#endif\n            ::uint8_t result[100];\n            ::int32_t len;\n            if (!t.empty())\n               len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), result, sizeof(result));\n            else\n               len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast< ::int32_t>(0), result, sizeof(result));\n            if (std::size_t(len) > sizeof(result))\n            {\n               scoped_array< ::uint8_t> presult(new ::uint8_t[len + 1]);\n               if (!t.empty())\n                  len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), presult.get(), len + 1);\n               else\n                  len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast< ::int32_t>(0), presult.get(), len + 1);\n               if ((0 == presult[len - 1]) && (len > 1))\n                  --len;\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n               return string_type(presult.get(), presult.get() + len);\n#else\n               string_type sresult;\n               ::uint8_t const* ia = presult.get();\n               ::uint8_t const* ib = presult.get() + len;\n               while (ia != ib)\n                  sresult.push_back(*ia++);\n               return sresult;\n#endif\n            }\n            if ((0 == result[len - 1]) && (len > 1))\n               --len;\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n            return string_type(result, result + len);\n#else\n            string_type sresult;\n            ::uint8_t const* ia = result;\n            ::uint8_t const* ib = result + len;\n            while (ia != ib)\n               sresult.push_back(*ia++);\n            return sresult;\n#endif\n         }\n         string_type transform(const char_type* p1, const char_type* p2) const\n         {\n            return do_transform(p1, p2, m_collator.get());\n         }\n         string_type transform_primary(const char_type* p1, const char_type* p2) const\n         {\n            return do_transform(p1, p2, m_primary_collator.get());\n         }\n      private:\n         void init_error()\n         {\n            std::runtime_error e(\"Could not initialize ICU resources\");\n            boost::throw_exception(e);\n         }\n         U_NAMESPACE_QUALIFIER Locale m_locale;                                  // The ICU locale that we're using\n         boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator;          // The full collation object\n         boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator;  // The primary collation object\n      };\n\n      inline boost::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)\n      {\n         return boost::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));\n      }\n\n   }\n\n   class icu_regex_traits\n   {\n   public:\n      typedef UChar32                      char_type;\n      typedef std::size_t                  size_type;\n      typedef std::vector<char_type>       string_type;\n      typedef U_NAMESPACE_QUALIFIER Locale locale_type;\n#ifdef BOOST_NO_INT64_T\n      typedef std::bitset<64>              char_class_type;\n#else\n      typedef boost::uint64_t              char_class_type;\n#endif\n\n      struct boost_extensions_tag {};\n\n      icu_regex_traits()\n         : m_pimpl(BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))\n      {\n      }\n      static size_type length(const char_type* p)\n      {\n         size_type result = 0;\n         while (*p)\n         {\n            ++p;\n            ++result;\n         }\n         return result;\n      }\n      ::boost::regex_constants::syntax_type syntax_type(char_type c)const\n      {\n         return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;\n      }\n      ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const\n      {\n         return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;\n      }\n      char_type translate(char_type c) const\n      {\n         return c;\n      }\n      char_type translate_nocase(char_type c) const\n      {\n         return ::u_foldCase(c, U_FOLD_CASE_DEFAULT);\n      }\n      char_type translate(char_type c, bool icase) const\n      {\n         return icase ? translate_nocase(c) : translate(c);\n      }\n      char_type tolower(char_type c) const\n      {\n         return ::u_tolower(c);\n      }\n      char_type toupper(char_type c) const\n      {\n         return ::u_toupper(c);\n      }\n      string_type transform(const char_type* p1, const char_type* p2) const\n      {\n         return m_pimpl->transform(p1, p2);\n      }\n      string_type transform_primary(const char_type* p1, const char_type* p2) const\n      {\n         return m_pimpl->transform_primary(p1, p2);\n      }\n      char_class_type lookup_classname(const char_type* p1, const char_type* p2) const\n      {\n         static const char_class_type mask_blank = char_class_type(1) << offset_blank;\n         static const char_class_type mask_space = char_class_type(1) << offset_space;\n         static const char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n         static const char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n         static const char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n         static const char_class_type mask_any = char_class_type(1) << offset_any;\n         static const char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n         static const char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n         static const char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n         static const char_class_type masks[] =\n         {\n            0,\n            U_GC_L_MASK | U_GC_ND_MASK,\n            U_GC_L_MASK,\n            mask_blank,\n            U_GC_CC_MASK | U_GC_CF_MASK | U_GC_ZL_MASK | U_GC_ZP_MASK,\n            U_GC_ND_MASK,\n            U_GC_ND_MASK,\n            (0x3FFFFFFFu) & ~(U_GC_CC_MASK | U_GC_CF_MASK | U_GC_CS_MASK | U_GC_CN_MASK | U_GC_Z_MASK),\n            mask_horizontal,\n            U_GC_LL_MASK,\n            U_GC_LL_MASK,\n            ~(U_GC_C_MASK),\n            U_GC_P_MASK,\n            char_class_type(U_GC_Z_MASK) | mask_space,\n            char_class_type(U_GC_Z_MASK) | mask_space,\n            U_GC_LU_MASK,\n            mask_unicode,\n            U_GC_LU_MASK,\n            mask_vertical,\n            char_class_type(U_GC_L_MASK | U_GC_ND_MASK | U_GC_MN_MASK) | mask_underscore,\n            char_class_type(U_GC_L_MASK | U_GC_ND_MASK | U_GC_MN_MASK) | mask_underscore,\n            char_class_type(U_GC_ND_MASK) | mask_xdigit,\n         };\n\n         int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n         if (idx >= 0)\n            return masks[idx + 1];\n         char_class_type result = lookup_icu_mask(p1, p2);\n         if (result != 0)\n            return result;\n\n         if (idx < 0)\n         {\n            string_type s(p1, p2);\n            string_type::size_type i = 0;\n            while (i < s.size())\n            {\n               s[i] = static_cast<char>((::u_tolower)(s[i]));\n               if (::u_isspace(s[i]) || (s[i] == '-') || (s[i] == '_'))\n                  s.erase(s.begin() + i, s.begin() + i + 1);\n               else\n               {\n                  s[i] = static_cast<char>((::u_tolower)(s[i]));\n                  ++i;\n               }\n            }\n            if (!s.empty())\n               idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n            if (idx >= 0)\n               return masks[idx + 1];\n            if (!s.empty())\n               result = lookup_icu_mask(&*s.begin(), &*s.begin() + s.size());\n            if (result != 0)\n               return result;\n         }\n         BOOST_ASSERT(std::size_t(idx + 1) < sizeof(masks) / sizeof(masks[0]));\n         return masks[idx + 1];\n      }\n      string_type lookup_collatename(const char_type* p1, const char_type* p2) const\n      {\n         string_type result;\n#ifdef BOOST_NO_CXX98_BINDERS\n         if (std::find_if(p1, p2, std::bind(std::greater< ::UChar32>(), std::placeholders::_1, 0x7f)) == p2)\n#else\n         if (std::find_if(p1, p2, std::bind2nd(std::greater< ::UChar32>(), 0x7f)) == p2)\n#endif\n         {\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n            std::string s(p1, p2);\n#else\n            std::string s;\n            const char_type* p3 = p1;\n            while (p3 != p2)\n               s.append(1, *p3++);\n#endif\n            // Try Unicode name:\n            UErrorCode err = U_ZERO_ERROR;\n            UChar32 c = ::u_charFromName(U_UNICODE_CHAR_NAME, s.c_str(), &err);\n            if (U_SUCCESS(err))\n            {\n               result.push_back(c);\n               return result;\n            }\n            // Try Unicode-extended name:\n            err = U_ZERO_ERROR;\n            c = ::u_charFromName(U_EXTENDED_CHAR_NAME, s.c_str(), &err);\n            if (U_SUCCESS(err))\n            {\n               result.push_back(c);\n               return result;\n            }\n            // try POSIX name:\n            s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n            result.assign(s.begin(), s.end());\n#else\n            result.clear();\n            std::string::const_iterator si, sj;\n            si = s.begin();\n            sj = s.end();\n            while (si != sj)\n               result.push_back(*si++);\n#endif\n         }\n         if (result.empty() && (p2 - p1 == 1))\n            result.push_back(*p1);\n         return result;\n      }\n      bool isctype(char_type c, char_class_type f) const\n      {\n         static const char_class_type mask_blank = char_class_type(1) << offset_blank;\n         static const char_class_type mask_space = char_class_type(1) << offset_space;\n         static const char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n         static const char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n         static const char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n         static const char_class_type mask_any = char_class_type(1) << offset_any;\n         static const char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n         static const char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n         static const char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n         // check for standard catagories first:\n         char_class_type m = char_class_type(static_cast<char_class_type>(1) << u_charType(c));\n         if ((m & f) != 0)\n            return true;\n         // now check for special cases:\n         if (((f & mask_blank) != 0) && u_isblank(c))\n            return true;\n         if (((f & mask_space) != 0) && u_isspace(c))\n            return true;\n         if (((f & mask_xdigit) != 0) && (u_digit(c, 16) >= 0))\n            return true;\n         if (((f & mask_unicode) != 0) && (c >= 0x100))\n            return true;\n         if (((f & mask_underscore) != 0) && (c == '_'))\n            return true;\n         if (((f & mask_any) != 0) && (c <= 0x10FFFF))\n            return true;\n         if (((f & mask_ascii) != 0) && (c <= 0x7F))\n            return true;\n         if (((f & mask_vertical) != 0) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == static_cast<char_type>('\\v')) || (m == U_GC_ZL_MASK) || (m == U_GC_ZP_MASK)))\n            return true;\n         if (((f & mask_horizontal) != 0) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && u_isspace(c) && (c != static_cast<char_type>('\\v')))\n            return true;\n         return false;\n      }\n      boost::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const\n      {\n         return BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n      }\n      int value(char_type c, int radix)const\n      {\n         return u_digit(c, static_cast< ::int8_t>(radix));\n      }\n      locale_type imbue(locale_type l)\n      {\n         locale_type result(m_pimpl->getloc());\n         m_pimpl = BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(l);\n         return result;\n      }\n      locale_type getloc()const\n      {\n         return locale_type();\n      }\n      std::string error_string(::boost::regex_constants::error_type n) const\n      {\n         return BOOST_REGEX_DETAIL_NS::get_default_error_string(n);\n      }\n   private:\n      icu_regex_traits(const icu_regex_traits&);\n      icu_regex_traits& operator=(const icu_regex_traits&);\n\n      //\n      // define the bitmasks offsets we need for additional character properties:\n      //\n      enum {\n         offset_blank = U_CHAR_CATEGORY_COUNT,\n         offset_space = U_CHAR_CATEGORY_COUNT + 1,\n         offset_xdigit = U_CHAR_CATEGORY_COUNT + 2,\n         offset_underscore = U_CHAR_CATEGORY_COUNT + 3,\n         offset_unicode = U_CHAR_CATEGORY_COUNT + 4,\n         offset_any = U_CHAR_CATEGORY_COUNT + 5,\n         offset_ascii = U_CHAR_CATEGORY_COUNT + 6,\n         offset_horizontal = U_CHAR_CATEGORY_COUNT + 7,\n         offset_vertical = U_CHAR_CATEGORY_COUNT + 8\n      };\n\n      static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2)\n      {\n         static const char_class_type mask_blank = char_class_type(1) << offset_blank;\n         static const char_class_type mask_space = char_class_type(1) << offset_space;\n         static const char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n         static const char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n         static const char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n         static const char_class_type mask_any = char_class_type(1) << offset_any;\n         static const char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n         static const char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n         static const char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n         static const ::UChar32 prop_name_table[] = {\n            /* any */  'a', 'n', 'y',\n            /* ascii */  'a', 's', 'c', 'i', 'i',\n            /* assigned */  'a', 's', 's', 'i', 'g', 'n', 'e', 'd',\n            /* c* */  'c', '*',\n            /* cc */  'c', 'c',\n            /* cf */  'c', 'f',\n            /* closepunctuation */  'c', 'l', 'o', 's', 'e', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* cn */  'c', 'n',\n            /* co */  'c', 'o',\n            /* connectorpunctuation */  'c', 'o', 'n', 'n', 'e', 'c', 't', 'o', 'r', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* control */  'c', 'o', 'n', 't', 'r', 'o', 'l',\n            /* cs */  'c', 's',\n            /* currencysymbol */  'c', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 's', 'y', 'm', 'b', 'o', 'l',\n            /* dashpunctuation */  'd', 'a', 's', 'h', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* decimaldigitnumber */  'd', 'e', 'c', 'i', 'm', 'a', 'l', 'd', 'i', 'g', 'i', 't', 'n', 'u', 'm', 'b', 'e', 'r',\n            /* enclosingmark */  'e', 'n', 'c', 'l', 'o', 's', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n            /* finalpunctuation */  'f', 'i', 'n', 'a', 'l', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* format */  'f', 'o', 'r', 'm', 'a', 't',\n            /* initialpunctuation */  'i', 'n', 'i', 't', 'i', 'a', 'l', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* l* */  'l', '*',\n            /* letter */  'l', 'e', 't', 't', 'e', 'r',\n            /* letternumber */  'l', 'e', 't', 't', 'e', 'r', 'n', 'u', 'm', 'b', 'e', 'r',\n            /* lineseparator */  'l', 'i', 'n', 'e', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n            /* ll */  'l', 'l',\n            /* lm */  'l', 'm',\n            /* lo */  'l', 'o',\n            /* lowercaseletter */  'l', 'o', 'w', 'e', 'r', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n            /* lt */  'l', 't',\n            /* lu */  'l', 'u',\n            /* m* */  'm', '*',\n            /* mark */  'm', 'a', 'r', 'k',\n            /* mathsymbol */  'm', 'a', 't', 'h', 's', 'y', 'm', 'b', 'o', 'l',\n            /* mc */  'm', 'c',\n            /* me */  'm', 'e',\n            /* mn */  'm', 'n',\n            /* modifierletter */  'm', 'o', 'd', 'i', 'f', 'i', 'e', 'r', 'l', 'e', 't', 't', 'e', 'r',\n            /* modifiersymbol */  'm', 'o', 'd', 'i', 'f', 'i', 'e', 'r', 's', 'y', 'm', 'b', 'o', 'l',\n            /* n* */  'n', '*',\n            /* nd */  'n', 'd',\n            /* nl */  'n', 'l',\n            /* no */  'n', 'o',\n            /* nonspacingmark */  'n', 'o', 'n', 's', 'p', 'a', 'c', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n            /* notassigned */  'n', 'o', 't', 'a', 's', 's', 'i', 'g', 'n', 'e', 'd',\n            /* number */  'n', 'u', 'm', 'b', 'e', 'r',\n            /* openpunctuation */  'o', 'p', 'e', 'n', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* other */  'o', 't', 'h', 'e', 'r',\n            /* otherletter */  'o', 't', 'h', 'e', 'r', 'l', 'e', 't', 't', 'e', 'r',\n            /* othernumber */  'o', 't', 'h', 'e', 'r', 'n', 'u', 'm', 'b', 'e', 'r',\n            /* otherpunctuation */  'o', 't', 'h', 'e', 'r', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* othersymbol */  'o', 't', 'h', 'e', 'r', 's', 'y', 'm', 'b', 'o', 'l',\n            /* p* */  'p', '*',\n            /* paragraphseparator */  'p', 'a', 'r', 'a', 'g', 'r', 'a', 'p', 'h', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n            /* pc */  'p', 'c',\n            /* pd */  'p', 'd',\n            /* pe */  'p', 'e',\n            /* pf */  'p', 'f',\n            /* pi */  'p', 'i',\n            /* po */  'p', 'o',\n            /* privateuse */  'p', 'r', 'i', 'v', 'a', 't', 'e', 'u', 's', 'e',\n            /* ps */  'p', 's',\n            /* punctuation */  'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n            /* s* */  's', '*',\n            /* sc */  's', 'c',\n            /* separator */  's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n            /* sk */  's', 'k',\n            /* sm */  's', 'm',\n            /* so */  's', 'o',\n            /* spaceseparator */  's', 'p', 'a', 'c', 'e', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n            /* spacingcombiningmark */  's', 'p', 'a', 'c', 'i', 'n', 'g', 'c', 'o', 'm', 'b', 'i', 'n', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n            /* surrogate */  's', 'u', 'r', 'r', 'o', 'g', 'a', 't', 'e',\n            /* symbol */  's', 'y', 'm', 'b', 'o', 'l',\n            /* titlecase */  't', 'i', 't', 'l', 'e', 'c', 'a', 's', 'e',\n            /* titlecaseletter */  't', 'i', 't', 'l', 'e', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n            /* uppercaseletter */  'u', 'p', 'p', 'e', 'r', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n            /* z* */  'z', '*',\n            /* zl */  'z', 'l',\n            /* zp */  'z', 'p',\n            /* zs */  'z', 's',\n         };\n\n         static const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32> range_data[] = {\n            { prop_name_table + 0, prop_name_table + 3, }, // any\n            { prop_name_table + 3, prop_name_table + 8, }, // ascii\n            { prop_name_table + 8, prop_name_table + 16, }, // assigned\n            { prop_name_table + 16, prop_name_table + 18, }, // c*\n            { prop_name_table + 18, prop_name_table + 20, }, // cc\n            { prop_name_table + 20, prop_name_table + 22, }, // cf\n            { prop_name_table + 22, prop_name_table + 38, }, // closepunctuation\n            { prop_name_table + 38, prop_name_table + 40, }, // cn\n            { prop_name_table + 40, prop_name_table + 42, }, // co\n            { prop_name_table + 42, prop_name_table + 62, }, // connectorpunctuation\n            { prop_name_table + 62, prop_name_table + 69, }, // control\n            { prop_name_table + 69, prop_name_table + 71, }, // cs\n            { prop_name_table + 71, prop_name_table + 85, }, // currencysymbol\n            { prop_name_table + 85, prop_name_table + 100, }, // dashpunctuation\n            { prop_name_table + 100, prop_name_table + 118, }, // decimaldigitnumber\n            { prop_name_table + 118, prop_name_table + 131, }, // enclosingmark\n            { prop_name_table + 131, prop_name_table + 147, }, // finalpunctuation\n            { prop_name_table + 147, prop_name_table + 153, }, // format\n            { prop_name_table + 153, prop_name_table + 171, }, // initialpunctuation\n            { prop_name_table + 171, prop_name_table + 173, }, // l*\n            { prop_name_table + 173, prop_name_table + 179, }, // letter\n            { prop_name_table + 179, prop_name_table + 191, }, // letternumber\n            { prop_name_table + 191, prop_name_table + 204, }, // lineseparator\n            { prop_name_table + 204, prop_name_table + 206, }, // ll\n            { prop_name_table + 206, prop_name_table + 208, }, // lm\n            { prop_name_table + 208, prop_name_table + 210, }, // lo\n            { prop_name_table + 210, prop_name_table + 225, }, // lowercaseletter\n            { prop_name_table + 225, prop_name_table + 227, }, // lt\n            { prop_name_table + 227, prop_name_table + 229, }, // lu\n            { prop_name_table + 229, prop_name_table + 231, }, // m*\n            { prop_name_table + 231, prop_name_table + 235, }, // mark\n            { prop_name_table + 235, prop_name_table + 245, }, // mathsymbol\n            { prop_name_table + 245, prop_name_table + 247, }, // mc\n            { prop_name_table + 247, prop_name_table + 249, }, // me\n            { prop_name_table + 249, prop_name_table + 251, }, // mn\n            { prop_name_table + 251, prop_name_table + 265, }, // modifierletter\n            { prop_name_table + 265, prop_name_table + 279, }, // modifiersymbol\n            { prop_name_table + 279, prop_name_table + 281, }, // n*\n            { prop_name_table + 281, prop_name_table + 283, }, // nd\n            { prop_name_table + 283, prop_name_table + 285, }, // nl\n            { prop_name_table + 285, prop_name_table + 287, }, // no\n            { prop_name_table + 287, prop_name_table + 301, }, // nonspacingmark\n            { prop_name_table + 301, prop_name_table + 312, }, // notassigned\n            { prop_name_table + 312, prop_name_table + 318, }, // number\n            { prop_name_table + 318, prop_name_table + 333, }, // openpunctuation\n            { prop_name_table + 333, prop_name_table + 338, }, // other\n            { prop_name_table + 338, prop_name_table + 349, }, // otherletter\n            { prop_name_table + 349, prop_name_table + 360, }, // othernumber\n            { prop_name_table + 360, prop_name_table + 376, }, // otherpunctuation\n            { prop_name_table + 376, prop_name_table + 387, }, // othersymbol\n            { prop_name_table + 387, prop_name_table + 389, }, // p*\n            { prop_name_table + 389, prop_name_table + 407, }, // paragraphseparator\n            { prop_name_table + 407, prop_name_table + 409, }, // pc\n            { prop_name_table + 409, prop_name_table + 411, }, // pd\n            { prop_name_table + 411, prop_name_table + 413, }, // pe\n            { prop_name_table + 413, prop_name_table + 415, }, // pf\n            { prop_name_table + 415, prop_name_table + 417, }, // pi\n            { prop_name_table + 417, prop_name_table + 419, }, // po\n            { prop_name_table + 419, prop_name_table + 429, }, // privateuse\n            { prop_name_table + 429, prop_name_table + 431, }, // ps\n            { prop_name_table + 431, prop_name_table + 442, }, // punctuation\n            { prop_name_table + 442, prop_name_table + 444, }, // s*\n            { prop_name_table + 444, prop_name_table + 446, }, // sc\n            { prop_name_table + 446, prop_name_table + 455, }, // separator\n            { prop_name_table + 455, prop_name_table + 457, }, // sk\n            { prop_name_table + 457, prop_name_table + 459, }, // sm\n            { prop_name_table + 459, prop_name_table + 461, }, // so\n            { prop_name_table + 461, prop_name_table + 475, }, // spaceseparator\n            { prop_name_table + 475, prop_name_table + 495, }, // spacingcombiningmark\n            { prop_name_table + 495, prop_name_table + 504, }, // surrogate\n            { prop_name_table + 504, prop_name_table + 510, }, // symbol\n            { prop_name_table + 510, prop_name_table + 519, }, // titlecase\n            { prop_name_table + 519, prop_name_table + 534, }, // titlecaseletter\n            { prop_name_table + 534, prop_name_table + 549, }, // uppercaseletter\n            { prop_name_table + 549, prop_name_table + 551, }, // z*\n            { prop_name_table + 551, prop_name_table + 553, }, // zl\n            { prop_name_table + 553, prop_name_table + 555, }, // zp\n            { prop_name_table + 555, prop_name_table + 557, }, // zs\n         };\n\n         static const icu_regex_traits::char_class_type icu_class_map[] = {\n            mask_any, // any\n            mask_ascii, // ascii\n            (0x3FFFFFFFu) & ~(U_GC_CN_MASK), // assigned\n            U_GC_C_MASK, // c*\n            U_GC_CC_MASK, // cc\n            U_GC_CF_MASK, // cf\n            U_GC_PE_MASK, // closepunctuation\n            U_GC_CN_MASK, // cn\n            U_GC_CO_MASK, // co\n            U_GC_PC_MASK, // connectorpunctuation\n            U_GC_CC_MASK, // control\n            U_GC_CS_MASK, // cs\n            U_GC_SC_MASK, // currencysymbol\n            U_GC_PD_MASK, // dashpunctuation\n            U_GC_ND_MASK, // decimaldigitnumber\n            U_GC_ME_MASK, // enclosingmark\n            U_GC_PF_MASK, // finalpunctuation\n            U_GC_CF_MASK, // format\n            U_GC_PI_MASK, // initialpunctuation\n            U_GC_L_MASK, // l*\n            U_GC_L_MASK, // letter\n            U_GC_NL_MASK, // letternumber\n            U_GC_ZL_MASK, // lineseparator\n            U_GC_LL_MASK, // ll\n            U_GC_LM_MASK, // lm\n            U_GC_LO_MASK, // lo\n            U_GC_LL_MASK, // lowercaseletter\n            U_GC_LT_MASK, // lt\n            U_GC_LU_MASK, // lu\n            U_GC_M_MASK, // m*\n            U_GC_M_MASK, // mark\n            U_GC_SM_MASK, // mathsymbol\n            U_GC_MC_MASK, // mc\n            U_GC_ME_MASK, // me\n            U_GC_MN_MASK, // mn\n            U_GC_LM_MASK, // modifierletter\n            U_GC_SK_MASK, // modifiersymbol\n            U_GC_N_MASK, // n*\n            U_GC_ND_MASK, // nd\n            U_GC_NL_MASK, // nl\n            U_GC_NO_MASK, // no\n            U_GC_MN_MASK, // nonspacingmark\n            U_GC_CN_MASK, // notassigned\n            U_GC_N_MASK, // number\n            U_GC_PS_MASK, // openpunctuation\n            U_GC_C_MASK, // other\n            U_GC_LO_MASK, // otherletter\n            U_GC_NO_MASK, // othernumber\n            U_GC_PO_MASK, // otherpunctuation\n            U_GC_SO_MASK, // othersymbol\n            U_GC_P_MASK, // p*\n            U_GC_ZP_MASK, // paragraphseparator\n            U_GC_PC_MASK, // pc\n            U_GC_PD_MASK, // pd\n            U_GC_PE_MASK, // pe\n            U_GC_PF_MASK, // pf\n            U_GC_PI_MASK, // pi\n            U_GC_PO_MASK, // po\n            U_GC_CO_MASK, // privateuse\n            U_GC_PS_MASK, // ps\n            U_GC_P_MASK, // punctuation\n            U_GC_S_MASK, // s*\n            U_GC_SC_MASK, // sc\n            U_GC_Z_MASK, // separator\n            U_GC_SK_MASK, // sk\n            U_GC_SM_MASK, // sm\n            U_GC_SO_MASK, // so\n            U_GC_ZS_MASK, // spaceseparator\n            U_GC_MC_MASK, // spacingcombiningmark\n            U_GC_CS_MASK, // surrogate\n            U_GC_S_MASK, // symbol\n            U_GC_LT_MASK, // titlecase\n            U_GC_LT_MASK, // titlecaseletter\n            U_GC_LU_MASK, // uppercaseletter\n            U_GC_Z_MASK, // z*\n            U_GC_ZL_MASK, // zl\n            U_GC_ZP_MASK, // zp\n            U_GC_ZS_MASK, // zs\n         };\n\n\n         const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* ranges_begin = range_data;\n         const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* ranges_end = range_data + (sizeof(range_data) / sizeof(range_data[0]));\n\n         BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32> t = { p1, p2, };\n         const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* p = std::lower_bound(ranges_begin, ranges_end, t);\n         if ((p != ranges_end) && (t == *p))\n            return icu_class_map[p - ranges_begin];\n         return 0;\n      }\n\n      boost::shared_ptr< ::boost::BOOST_REGEX_DETAIL_NS::icu_regex_traits_implementation> m_pimpl;\n   };\n\n} // namespace boost\n\nnamespace boost {\n\n   // types:\n   typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;\n   typedef match_results<const ::UChar32*> u32match;\n   typedef match_results<const ::UChar*> u16match;\n\n   //\n   // Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:\n   //\n   namespace BOOST_REGEX_DETAIL_NS {\n\n#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<1>*)\n      {\n         typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;\n         return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);\n      }\n\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<2>*)\n      {\n         typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;\n         return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);\n      }\n\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<4>*)\n      {\n         return u32regex(i, j, opt);\n      }\n#else\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<1>*)\n      {\n         typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;\n         typedef std::vector<UChar32> vector_type;\n         vector_type v;\n         conv_type a(i, i, j), b(j, i, j);\n         while (a != b)\n         {\n            v.push_back(*a);\n            ++a;\n         }\n         if (v.size())\n            return u32regex(&*v.begin(), v.size(), opt);\n         return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);\n      }\n\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<2>*)\n      {\n         typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;\n         typedef std::vector<UChar32> vector_type;\n         vector_type v;\n         conv_type a(i, i, j), b(j, i, j);\n         while (a != b)\n         {\n            v.push_back(*a);\n            ++a;\n         }\n         if (v.size())\n            return u32regex(&*v.begin(), v.size(), opt);\n         return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);\n      }\n\n      template <class InputIterator>\n      inline u32regex do_make_u32regex(InputIterator i,\n         InputIterator j,\n         boost::regex_constants::syntax_option_type opt,\n         const boost::mpl::int_<4>*)\n      {\n         typedef std::vector<UChar32> vector_type;\n         vector_type v;\n         while (i != j)\n         {\n            v.push_back((UChar32)(*i));\n            ++i;\n         }\n         if (v.size())\n            return u32regex(&*v.begin(), v.size(), opt);\n         return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);\n      }\n#endif\n   }\n\n   // BOOST_REGEX_UCHAR_IS_WCHAR_T\n   //\n   // Source inspection of unicode/umachine.h in ICU version 59 indicates that:\n   //\n   // On version 59, UChar is always char16_t in C++ mode (and uint16_t in C mode)\n   //\n   // On earlier versions, the logic is\n   //\n   // #if U_SIZEOF_WCHAR_T==2\n   //   typedef wchar_t OldUChar;\n   // #elif defined(__CHAR16_TYPE__)\n   //   typedef __CHAR16_TYPE__ OldUChar;\n   // #else\n   //   typedef uint16_t OldUChar;\n   // #endif\n   //\n   // That is, UChar is wchar_t only on versions below 59, when U_SIZEOF_WCHAR_T==2\n   //\n   // Hence,\n\n#define BOOST_REGEX_UCHAR_IS_WCHAR_T (U_ICU_VERSION_MAJOR_NUM < 59 && U_SIZEOF_WCHAR_T == 2)\n\n#if BOOST_REGEX_UCHAR_IS_WCHAR_T\n   BOOST_STATIC_ASSERT((boost::is_same<UChar, wchar_t>::value));\n#else\n   BOOST_STATIC_ASSERT(!(boost::is_same<UChar, wchar_t>::value));\n#endif\n\n   //\n   // Construction from an iterator pair:\n   //\n   template <class InputIterator>\n   inline u32regex make_u32regex(InputIterator i,\n      InputIterator j,\n      boost::regex_constants::syntax_option_type opt)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(i, j, opt, static_cast<boost::mpl::int_<sizeof(*i)> const*>(0));\n   }\n   //\n   // construction from UTF-8 nul-terminated strings:\n   //\n   inline u32regex make_u32regex(const char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<boost::mpl::int_<1> const*>(0));\n   }\n   inline u32regex make_u32regex(const unsigned char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<boost::mpl::int_<1> const*>(0));\n   }\n   //\n   // construction from UTF-16 nul-terminated strings:\n   //\n#ifndef BOOST_NO_WREGEX\n   inline u32regex make_u32regex(const wchar_t* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<boost::mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T\n   inline u32regex make_u32regex(const UChar* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<boost::mpl::int_<2> const*>(0));\n   }\n#endif\n   //\n   // construction from basic_string class-template:\n   //\n   template<class C, class T, class A>\n   inline u32regex make_u32regex(const std::basic_string<C, T, A>& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.begin(), s.end(), opt, static_cast<boost::mpl::int_<sizeof(C)> const*>(0));\n   }\n   //\n   // Construction from ICU string type:\n   //\n   inline u32regex make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<boost::mpl::int_<2> const*>(0));\n   }\n\n   //\n   // regex_match overloads that widen the character type as appropriate:\n   //\n   namespace BOOST_REGEX_DETAIL_NS {\n      template<class MR1, class MR2, class NSubs>\n      void copy_results(MR1& out, MR2 const& in, NSubs named_subs)\n      {\n         // copy results from an adapted MR2 match_results:\n         out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());\n         out.set_base(in.base().base());\n         out.set_named_subs(named_subs);\n         for (int i = 0; i < (int)in.size(); ++i)\n         {\n            if (in[i].matched || !i)\n            {\n               out.set_first(in[i].first.base(), i);\n               out.set_second(in[i].second.base(), i, in[i].matched);\n            }\n         }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n         // Copy full capture info as well:\n         for (int i = 0; i < (int)in.size(); ++i)\n         {\n            if (in[i].captures().size())\n            {\n               out[i].get_captures().assign(in[i].captures().size(), typename MR1::value_type());\n               for (int j = 0; j < (int)out[i].captures().size(); ++j)\n               {\n                  out[i].get_captures()[j].first = in[i].captures()[j].first.base();\n                  out[i].get_captures()[j].second = in[i].captures()[j].second.base();\n                  out[i].get_captures()[j].matched = in[i].captures()[j].matched;\n               }\n            }\n         }\n#endif\n      }\n\n      template <class BidiIterator, class Allocator>\n      inline bool do_regex_match(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         boost::mpl::int_<4> const*)\n      {\n         return ::boost::regex_match(first, last, m, e, flags);\n      }\n      template <class BidiIterator, class Allocator>\n      bool do_regex_match(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         boost::mpl::int_<2> const*)\n      {\n         typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;\n         typedef match_results<conv_type>                   match_type;\n         //typedef typename match_type::allocator_type        alloc_type;\n         match_type what;\n         bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);\n         // copy results across to m:\n         if (result) copy_results(m, what, e.get_named_subs());\n         return result;\n      }\n      template <class BidiIterator, class Allocator>\n      bool do_regex_match(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         boost::mpl::int_<1> const*)\n      {\n         typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;\n         typedef match_results<conv_type>                   match_type;\n         //typedef typename match_type::allocator_type        alloc_type;\n         match_type what;\n         bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);\n         // copy results across to m:\n         if (result) copy_results(m, what, e.get_named_subs());\n         return result;\n      }\n   } // namespace BOOST_REGEX_DETAIL_NS\n\n   template <class BidiIterator, class Allocator>\n   inline bool u32regex_match(BidiIterator first, BidiIterator last,\n      match_results<BidiIterator, Allocator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));\n   }\n   inline bool u32regex_match(const UChar* p,\n      match_results<const UChar*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));\n   }\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\n   inline bool u32regex_match(const wchar_t* p,\n      match_results<const wchar_t*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_match(const char* p,\n      match_results<const char*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_match(const unsigned char* p,\n      match_results<const unsigned char*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_match(const std::string& s,\n      match_results<std::string::const_iterator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n#ifndef BOOST_NO_STD_WSTRING\n   inline bool u32regex_match(const std::wstring& s,\n      match_results<std::wstring::const_iterator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      match_results<const UChar*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<2> const*>(0));\n   }\n   //\n   // regex_match overloads that do not return what matched:\n   //\n   template <class BidiIterator>\n   inline bool u32regex_match(BidiIterator first, BidiIterator last,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<BidiIterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));\n   }\n   inline bool u32regex_match(const UChar* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const UChar*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));\n   }\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\n   inline bool u32regex_match(const wchar_t* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const wchar_t*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_match(const char* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const char*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_match(const unsigned char* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const unsigned char*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p + std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_match(const std::string& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<std::string::const_iterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));\n   }\n#ifndef BOOST_NO_STD_WSTRING\n   inline bool u32regex_match(const std::wstring& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<std::wstring::const_iterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const UChar*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<2> const*>(0));\n   }\n\n   //\n   // regex_search overloads that widen the character type as appropriate:\n   //\n   namespace BOOST_REGEX_DETAIL_NS {\n      template <class BidiIterator, class Allocator>\n      inline bool do_regex_search(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         BidiIterator base,\n         boost::mpl::int_<4> const*)\n      {\n         return ::boost::regex_search(first, last, m, e, flags, base);\n      }\n      template <class BidiIterator, class Allocator>\n      bool do_regex_search(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         BidiIterator base,\n         boost::mpl::int_<2> const*)\n      {\n         typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;\n         typedef match_results<conv_type>                   match_type;\n         //typedef typename match_type::allocator_type        alloc_type;\n         match_type what;\n         bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));\n         // copy results across to m:\n         if (result) copy_results(m, what, e.get_named_subs());\n         return result;\n      }\n      template <class BidiIterator, class Allocator>\n      bool do_regex_search(BidiIterator first, BidiIterator last,\n         match_results<BidiIterator, Allocator>& m,\n         const u32regex& e,\n         match_flag_type flags,\n         BidiIterator base,\n         boost::mpl::int_<1> const*)\n      {\n         typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;\n         typedef match_results<conv_type>                   match_type;\n         //typedef typename match_type::allocator_type        alloc_type;\n         match_type what;\n         bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));\n         // copy results across to m:\n         if (result) copy_results(m, what, e.get_named_subs());\n         return result;\n      }\n   }\n\n   template <class BidiIterator, class Allocator>\n   inline bool u32regex_search(BidiIterator first, BidiIterator last,\n      match_results<BidiIterator, Allocator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));\n   }\n   template <class BidiIterator, class Allocator>\n   inline bool u32regex_search(BidiIterator first, BidiIterator last,\n      match_results<BidiIterator, Allocator>& m,\n      const u32regex& e,\n      match_flag_type flags,\n      BidiIterator base)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));\n   }\n   inline bool u32regex_search(const UChar* p,\n      match_results<const UChar*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));\n   }\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\n   inline bool u32regex_search(const wchar_t* p,\n      match_results<const wchar_t*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_search(const char* p,\n      match_results<const char*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_search(const unsigned char* p,\n      match_results<const unsigned char*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_search(const std::string& s,\n      match_results<std::string::const_iterator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));\n   }\n#ifndef BOOST_NO_STD_WSTRING\n   inline bool u32regex_search(const std::wstring& s,\n      match_results<std::wstring::const_iterator>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      match_results<const UChar*>& m,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<2> const*>(0));\n   }\n   template <class BidiIterator>\n   inline bool u32regex_search(BidiIterator first, BidiIterator last,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<BidiIterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));\n   }\n   inline bool u32regex_search(const UChar* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const UChar*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));\n   }\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\n   inline bool u32regex_search(const wchar_t* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const wchar_t*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_search(const char* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const char*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_search(const unsigned char* p,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const unsigned char*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p + std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));\n   }\n   inline bool u32regex_search(const std::string& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<std::string::const_iterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));\n   }\n#ifndef BOOST_NO_STD_WSTRING\n   inline bool u32regex_search(const std::wstring& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<std::wstring::const_iterator> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));\n   }\n#endif\n   inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      const u32regex& e,\n      match_flag_type flags = match_default)\n   {\n      match_results<const UChar*> m;\n      return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<2> const*>(0));\n   }\n\n   //\n   // overloads for regex_replace with utf-8 and utf-16 data types:\n   //\n   namespace BOOST_REGEX_DETAIL_NS {\n      template <class I>\n      inline std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >\n         make_utf32_seq(I i, I j, mpl::int_<1> const*)\n      {\n         return std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >(boost::u8_to_u32_iterator<I>(i, i, j), boost::u8_to_u32_iterator<I>(j, i, j));\n      }\n      template <class I>\n      inline std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >\n         make_utf32_seq(I i, I j, mpl::int_<2> const*)\n      {\n         return std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >(boost::u16_to_u32_iterator<I>(i, i, j), boost::u16_to_u32_iterator<I>(j, i, j));\n      }\n      template <class I>\n      inline std::pair< I, I >\n         make_utf32_seq(I i, I j, mpl::int_<4> const*)\n      {\n         return std::pair< I, I >(i, j);\n      }\n      template <class charT>\n      inline std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >\n         make_utf32_seq(const charT* p, mpl::int_<1> const*)\n      {\n         std::size_t len = std::strlen((const char*)p);\n         return std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >(boost::u8_to_u32_iterator<const charT*>(p, p, p + len), boost::u8_to_u32_iterator<const charT*>(p + len, p, p + len));\n      }\n      template <class charT>\n      inline std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >\n         make_utf32_seq(const charT* p, mpl::int_<2> const*)\n      {\n         std::size_t len = u_strlen((const UChar*)p);\n         return std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >(boost::u16_to_u32_iterator<const charT*>(p, p, p + len), boost::u16_to_u32_iterator<const charT*>(p + len, p, p + len));\n      }\n      template <class charT>\n      inline std::pair< const charT*, const charT* >\n         make_utf32_seq(const charT* p, mpl::int_<4> const*)\n      {\n         return std::pair< const charT*, const charT* >(p, p + icu_regex_traits::length((UChar32 const*)p));\n      }\n      template <class OutputIterator>\n      inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)\n      {\n         return o;\n      }\n      template <class OutputIterator>\n      inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)\n      {\n         return o;\n      }\n      template <class OutputIterator>\n      inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)\n      {\n         return o;\n      }\n\n      template <class OutputIterator, class I1, class I2>\n      OutputIterator do_regex_replace(OutputIterator out,\n         std::pair<I1, I1> const& in,\n         const u32regex& e,\n         const std::pair<I2, I2>& fmt,\n         match_flag_type flags\n      )\n      {\n         // unfortunately we have to copy the format string in order to pass in onward:\n         std::vector<UChar32> f;\n#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS\n         f.assign(fmt.first, fmt.second);\n#else\n         f.clear();\n         I2 pos = fmt.first;\n         while (pos != fmt.second)\n            f.push_back(*pos++);\n#endif\n\n         regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);\n         regex_iterator<I1, UChar32, icu_regex_traits> j;\n         if (i == j)\n         {\n            if (!(flags & regex_constants::format_no_copy))\n               out = BOOST_REGEX_DETAIL_NS::copy(in.first, in.second, out);\n         }\n         else\n         {\n            I1 last_m = in.first;\n            while (i != j)\n            {\n               if (!(flags & regex_constants::format_no_copy))\n                  out = BOOST_REGEX_DETAIL_NS::copy(i->prefix().first, i->prefix().second, out);\n               if (!f.empty())\n                  out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());\n               else\n                  out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());\n               last_m = (*i)[0].second;\n               if (flags & regex_constants::format_first_only)\n                  break;\n               ++i;\n            }\n            if (!(flags & regex_constants::format_no_copy))\n               out = BOOST_REGEX_DETAIL_NS::copy(last_m, in.second, out);\n         }\n         return out;\n      }\n      template <class BaseIterator>\n      inline const BaseIterator& extract_output_base(const BaseIterator& b)\n      {\n         return b;\n      }\n      template <class BaseIterator>\n      inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)\n      {\n         return b.base();\n      }\n      template <class BaseIterator>\n      inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)\n      {\n         return b.base();\n      }\n   }  // BOOST_REGEX_DETAIL_NS\n\n   template <class OutputIterator, class BidirectionalIterator, class charT>\n   inline OutputIterator u32regex_replace(OutputIterator out,\n      BidirectionalIterator first,\n      BidirectionalIterator last,\n      const u32regex& e,\n      const charT* fmt,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::extract_output_base\n      (\n         BOOST_REGEX_DETAIL_NS::do_regex_replace(\n            BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            e,\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),\n            flags)\n      );\n   }\n\n   template <class OutputIterator, class Iterator, class charT>\n   inline OutputIterator u32regex_replace(OutputIterator out,\n      Iterator first,\n      Iterator last,\n      const u32regex& e,\n      const std::basic_string<charT>& fmt,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::extract_output_base\n      (\n         BOOST_REGEX_DETAIL_NS::do_regex_replace(\n            BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            e,\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),\n            flags)\n      );\n   }\n\n   template <class OutputIterator, class Iterator>\n   inline OutputIterator u32regex_replace(OutputIterator out,\n      Iterator first,\n      Iterator last,\n      const u32regex& e,\n      const U_NAMESPACE_QUALIFIER UnicodeString& fmt,\n      match_flag_type flags = match_default)\n   {\n      return BOOST_REGEX_DETAIL_NS::extract_output_base\n      (\n         BOOST_REGEX_DETAIL_NS::do_regex_replace(\n            BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),\n            e,\n            BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),\n            flags)\n      );\n   }\n\n   template <class charT>\n   std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,\n      const u32regex& e,\n      const charT* fmt,\n      match_flag_type flags = match_default)\n   {\n      std::basic_string<charT> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n      u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);\n      return result;\n   }\n\n   template <class charT>\n   std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,\n      const u32regex& e,\n      const std::basic_string<charT>& fmt,\n      match_flag_type flags = match_default)\n   {\n      std::basic_string<charT> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n      u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);\n      return result;\n   }\n\n   namespace BOOST_REGEX_DETAIL_NS {\n\n      class unicode_string_out_iterator\n      {\n         U_NAMESPACE_QUALIFIER UnicodeString* out;\n      public:\n         unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}\n         unicode_string_out_iterator& operator++() { return *this; }\n         unicode_string_out_iterator& operator++(int) { return *this; }\n         unicode_string_out_iterator& operator*() { return *this; }\n         unicode_string_out_iterator& operator=(UChar v)\n         {\n            *out += v;\n            return *this;\n         }\n         typedef std::ptrdiff_t difference_type;\n         typedef UChar value_type;\n         typedef value_type* pointer;\n         typedef value_type& reference;\n         typedef std::output_iterator_tag iterator_category;\n      };\n\n   }\n\n   inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      const u32regex& e,\n      const UChar* fmt,\n      match_flag_type flags = match_default)\n   {\n      U_NAMESPACE_QUALIFIER UnicodeString result;\n      BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);\n      u32regex_replace(i, s.getBuffer(), s.getBuffer() + s.length(), e, fmt, flags);\n      return result;\n   }\n\n   inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n      const u32regex& e,\n      const U_NAMESPACE_QUALIFIER UnicodeString& fmt,\n      match_flag_type flags = match_default)\n   {\n      U_NAMESPACE_QUALIFIER UnicodeString result;\n      BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);\n      BOOST_REGEX_DETAIL_NS::do_regex_replace(\n         BOOST_REGEX_DETAIL_NS::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(s.getBuffer(), s.getBuffer() + s.length(), static_cast<mpl::int_<2> const*>(0)),\n         e,\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),\n         flags);\n      return result;\n   }\n\n} // namespace boost.\n\n#ifdef BOOST_MSVC\n#pragma warning (pop)\n#endif\n\n#include <boost/regex/v4/u32regex_iterator.hpp>\n#include <boost/regex/v4/u32regex_token_iterator.hpp>\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/indexed_bit_flag.hpp",
    "content": "/*\n *\n * Copyright (c) 2020\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_parser.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_parser.\n  */\n\n#include <boost/regex/config.hpp>\n#include <set>\n\n#ifndef BOOST_REGEX_V4_INDEXED_BIT_FLAG_HPP\n#define BOOST_REGEX_V4_INDEXED_BIT_FLAG_HPP\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\nclass indexed_bit_flag\n{\n   boost::uint64_t low_mask;\n   std::set<std::size_t> mask_set;\npublic:\n   indexed_bit_flag() : low_mask(0) {}\n   void set(std::size_t i)\n   {\n      if (i < std::numeric_limits<boost::uint64_t>::digits - 1)\n         low_mask |= static_cast<boost::uint64_t>(1u) << i;\n      else\n         mask_set.insert(i);\n   }\n   bool test(std::size_t i)\n   {\n      if (i < std::numeric_limits<boost::uint64_t>::digits - 1)\n         return low_mask & static_cast<boost::uint64_t>(1u) << i ? true : false;\n      else\n         return mask_set.find(i) != mask_set.end();\n   }\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/iterator_category.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_match.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Iterator traits for selecting an iterator type as\n  *                an integral constant expression.\n  */\n\n\n#ifndef BOOST_REGEX_ITERATOR_CATEGORY_HPP\n#define BOOST_REGEX_ITERATOR_CATEGORY_HPP\n\n#include <iterator>\n#include <boost/type_traits/is_convertible.hpp>\n#include <boost/type_traits/is_pointer.hpp>\n\nnamespace boost{\nnamespace detail{\n\ntemplate <class I>\nstruct is_random_imp\n{\n#ifndef BOOST_NO_STD_ITERATOR_TRAITS\nprivate:\n   typedef typename std::iterator_traits<I>::iterator_category cat;\npublic:\n   BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<cat*, std::random_access_iterator_tag*>::value));\n#else\n   BOOST_STATIC_CONSTANT(bool, value = false);\n#endif\n};\n\ntemplate <class I>\nstruct is_random_pointer_imp\n{\n   BOOST_STATIC_CONSTANT(bool, value = true);\n};\n\ntemplate <bool is_pointer_type>\nstruct is_random_imp_selector\n{\n   template <class I>\n   struct rebind\n   {\n      typedef is_random_imp<I> type;\n   };\n};\n\ntemplate <>\nstruct is_random_imp_selector<true>\n{\n   template <class I>\n   struct rebind\n   {\n      typedef is_random_pointer_imp<I> type;\n   };\n};\n\n}\n\ntemplate <class I>\nstruct is_random_access_iterator\n{\nprivate:\n   typedef detail::is_random_imp_selector< ::boost::is_pointer<I>::value> selector;\n   typedef typename selector::template rebind<I> bound_type;\n   typedef typename bound_type::type answer;\npublic:\n   BOOST_STATIC_CONSTANT(bool, value = answer::value);\n};\n\n#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION\ntemplate <class I>\nconst bool is_random_access_iterator<I>::value;\n#endif\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/iterator_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         iterator_traits.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares iterator traits workarounds.\n  */\n\n#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP\n#define BOOST_REGEX_V4_ITERATOR_TRAITS_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#if defined(BOOST_NO_STD_ITERATOR_TRAITS)\n\ntemplate <class T>\nstruct regex_iterator_traits \n{\n  typedef typename T::iterator_category iterator_category;\n  typedef typename T::value_type        value_type;\n#if !defined(BOOST_NO_STD_ITERATOR)\n  typedef typename T::difference_type   difference_type;\n  typedef typename T::pointer           pointer;\n  typedef typename T::reference         reference;\n#else\n  typedef std::ptrdiff_t                difference_type;\n  typedef value_type*                   pointer;\n  typedef value_type&                   reference;\n#endif\n};\n\ntemplate <class T>\nstruct pointer_iterator_traits\n{\n   typedef std::ptrdiff_t difference_type;\n   typedef T value_type;\n   typedef T* pointer;\n   typedef T& reference;\n   typedef std::random_access_iterator_tag iterator_category;\n};\ntemplate <class T>\nstruct const_pointer_iterator_traits\n{\n   typedef std::ptrdiff_t difference_type;\n   typedef T value_type;\n   typedef const T* pointer;\n   typedef const T& reference;\n   typedef std::random_access_iterator_tag iterator_category;\n};\n\ntemplate<>\nstruct regex_iterator_traits<char*> : pointer_iterator_traits<char>{};\ntemplate<>\nstruct regex_iterator_traits<const char*> : const_pointer_iterator_traits<char>{};\ntemplate<>\nstruct regex_iterator_traits<wchar_t*> : pointer_iterator_traits<wchar_t>{};\ntemplate<>\nstruct regex_iterator_traits<const wchar_t*> : const_pointer_iterator_traits<wchar_t>{};\n//\n// the follwoing are needed for ICU support:\n//\ntemplate<>\nstruct regex_iterator_traits<unsigned char*> : pointer_iterator_traits<char>{};\ntemplate<>\nstruct regex_iterator_traits<const unsigned char*> : const_pointer_iterator_traits<char>{};\ntemplate<>\nstruct regex_iterator_traits<int*> : pointer_iterator_traits<int>{};\ntemplate<>\nstruct regex_iterator_traits<const int*> : const_pointer_iterator_traits<int>{};\n\n#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T\ntemplate<>\nstruct regex_iterator_traits<unsigned short*> : pointer_iterator_traits<unsigned short>{};\ntemplate<>\nstruct regex_iterator_traits<const unsigned short*> : const_pointer_iterator_traits<unsigned short>{};\n#endif\n\n#if defined(__SGI_STL_PORT) && defined(__STL_DEBUG)\ntemplate<>\nstruct regex_iterator_traits<std::string::iterator> : pointer_iterator_traits<char>{};\ntemplate<>\nstruct regex_iterator_traits<std::string::const_iterator> : const_pointer_iterator_traits<char>{};\n#ifndef BOOST_NO_STD_WSTRING\ntemplate<>\nstruct regex_iterator_traits<std::wstring::iterator> : pointer_iterator_traits<wchar_t>{};\ntemplate<>\nstruct regex_iterator_traits<std::wstring::const_iterator> : const_pointer_iterator_traits<wchar_t>{};\n#endif // BOOST_NO_WSTRING\n#endif // stport\n\n#else\n\ntemplate <class T>\nstruct regex_iterator_traits : public std::iterator_traits<T> {};\n\n#endif\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/match_flags.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         match_flags.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares match_flags type.\n  */\n\n#ifndef BOOST_REGEX_V4_MATCH_FLAGS\n#define BOOST_REGEX_V4_MATCH_FLAGS\n\n#ifdef __cplusplus\n#  include <boost/cstdint.hpp>\n#endif\n\n#ifdef __cplusplus\nnamespace boost{\n   namespace regex_constants{\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable : 26812)\n#endif\n#endif\n\ntypedef enum _match_flags\n{\n   match_default = 0,\n   match_not_bol = 1,                                /* first is not start of line */\n   match_not_eol = match_not_bol << 1,               /* last is not end of line */\n   match_not_bob = match_not_eol << 1,               /* first is not start of buffer */\n   match_not_eob = match_not_bob << 1,               /* last is not end of buffer */\n   match_not_bow = match_not_eob << 1,               /* first is not start of word */\n   match_not_eow = match_not_bow << 1,               /* last is not end of word */\n   match_not_dot_newline = match_not_eow << 1,       /* \\n is not matched by '.' */\n   match_not_dot_null = match_not_dot_newline << 1,  /* '\\0' is not matched by '.' */\n   match_prev_avail = match_not_dot_null << 1,       /* *--first is a valid expression */\n   match_init = match_prev_avail << 1,               /* internal use */\n   match_any = match_init << 1,                      /* don't care what we match */\n   match_not_null = match_any << 1,                  /* string can't be null */\n   match_continuous = match_not_null << 1,           /* each grep match must continue from */\n                                                     /* uninterrupted from the previous one */\n   match_partial = match_continuous << 1,            /* find partial matches */\n   \n   match_stop = match_partial << 1,                  /* stop after first match (grep) V3 only */\n   match_not_initial_null = match_stop,              /* don't match initial null, V4 only */\n   match_all = match_stop << 1,                      /* must find the whole of input even if match_any is set */\n   match_perl = match_all << 1,                      /* Use perl matching rules */\n   match_posix = match_perl << 1,                    /* Use POSIX matching rules */\n   match_nosubs = match_posix << 1,                  /* don't trap marked subs */\n   match_extra = match_nosubs << 1,                  /* include full capture information for repeated captures */\n   match_single_line = match_extra << 1,             /* treat text as single line and ignore any \\n's when matching ^ and $. */\n   match_unused1 = match_single_line << 1,           /* unused */\n   match_unused2 = match_unused1 << 1,               /* unused */\n   match_unused3 = match_unused2 << 1,               /* unused */\n   match_max = match_unused3,\n\n   format_perl = 0,                                  /* perl style replacement */\n   format_default = 0,                               /* ditto. */\n   format_sed = match_max << 1,                      /* sed style replacement. */\n   format_all = format_sed << 1,                     /* enable all extensions to syntax. */\n   format_no_copy = format_all << 1,                 /* don't copy non-matching segments. */\n   format_first_only = format_no_copy << 1,          /* Only replace first occurrence. */\n   format_is_if = format_first_only << 1,            /* internal use only. */\n   format_literal = format_is_if << 1,               /* treat string as a literal */\n\n   match_not_any = match_not_bol | match_not_eol | match_not_bob \n      | match_not_eob | match_not_bow | match_not_eow | match_not_dot_newline \n      | match_not_dot_null | match_prev_avail | match_init | match_not_null\n      | match_continuous | match_partial | match_stop | match_not_initial_null \n      | match_stop | match_all | match_perl | match_posix | match_nosubs\n      | match_extra | match_single_line | match_unused1 | match_unused2 \n      | match_unused3 | match_max | format_perl | format_default | format_sed\n      | format_all | format_no_copy | format_first_only | format_is_if\n      | format_literal\n\n\n} match_flags;\n\n#if defined(BOOST_BORLANDC) || (defined(_MSC_VER) && (_MSC_VER <= 1310))\ntypedef unsigned long match_flag_type;\n#else\ntypedef match_flags match_flag_type;\n\n\n#ifdef __cplusplus\ninline match_flags operator&(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) & static_cast<boost::int32_t>(m2)); }\ninline match_flags operator|(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) | static_cast<boost::int32_t>(m2)); }\ninline match_flags operator^(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<boost::int32_t>(m1) ^ static_cast<boost::int32_t>(m2)); }\ninline match_flags operator~(match_flags m1)\n{ return static_cast<match_flags>(~static_cast<boost::int32_t>(m1)); }\ninline match_flags& operator&=(match_flags& m1, match_flags m2)\n{ m1 = m1&m2; return m1; }\ninline match_flags& operator|=(match_flags& m1, match_flags m2)\n{ m1 = m1|m2; return m1; }\ninline match_flags& operator^=(match_flags& m1, match_flags m2)\n{ m1 = m1^m2; return m1; }\n#endif\n#endif\n\n#ifdef __cplusplus\n} /* namespace regex_constants */\n/*\n * import names into boost for backwards compatibility:\n */\nusing regex_constants::match_flag_type;\nusing regex_constants::match_default;\nusing regex_constants::match_not_bol;\nusing regex_constants::match_not_eol;\nusing regex_constants::match_not_bob;\nusing regex_constants::match_not_eob;\nusing regex_constants::match_not_bow;\nusing regex_constants::match_not_eow;\nusing regex_constants::match_not_dot_newline;\nusing regex_constants::match_not_dot_null;\nusing regex_constants::match_prev_avail;\n/* using regex_constants::match_init; */\nusing regex_constants::match_any;\nusing regex_constants::match_not_null;\nusing regex_constants::match_continuous;\nusing regex_constants::match_partial;\n/*using regex_constants::match_stop; */\nusing regex_constants::match_all;\nusing regex_constants::match_perl;\nusing regex_constants::match_posix;\nusing regex_constants::match_nosubs;\nusing regex_constants::match_extra;\nusing regex_constants::match_single_line;\n/*using regex_constants::match_max; */\nusing regex_constants::format_all;\nusing regex_constants::format_sed;\nusing regex_constants::format_perl;\nusing regex_constants::format_default;\nusing regex_constants::format_no_copy;\nusing regex_constants::format_first_only;\n/*using regex_constants::format_is_if;*/\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n\n} /* namespace boost */\n#endif /* __cplusplus */\n#endif /* include guard */\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/match_results.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         match_results.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class match_results.\n  */\n\n#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP\n#define BOOST_REGEX_V4_MATCH_RESULTS_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#if BOOST_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#  if BOOST_MSVC < 1600\n#     pragma warning(disable : 4660)\n#  endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\nclass named_subexpressions;\n\n}\n\ntemplate <class BidiIterator, class Allocator>\nclass match_results\n{ \nprivate:\n#ifndef BOOST_NO_STD_ALLOCATOR\n   typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;\n#else\n   typedef          std::vector<sub_match<BidiIterator> >           vector_type;\n#endif\npublic: \n   typedef          sub_match<BidiIterator>                         value_type;\n#ifndef BOOST_NO_CXX11_ALLOCATOR\n   typedef typename std::allocator_traits<Allocator>::value_type const &    const_reference;\n#elif  !defined(BOOST_NO_STD_ALLOCATOR) && !(defined(BOOST_MSVC) && defined(_STLPORT_VERSION))\n   typedef typename Allocator::const_reference                              const_reference;\n#else\n   typedef          const value_type&                                       const_reference;\n#endif\n   typedef          const_reference                                         reference;\n   typedef typename vector_type::const_iterator                             const_iterator;\n   typedef          const_iterator                                          iterator;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<\n                                    BidiIterator>::difference_type          difference_type;\n#ifdef BOOST_NO_CXX11_ALLOCATOR\n   typedef typename Allocator::size_type                                    size_type;\n#else\n   typedef typename std::allocator_traits<Allocator>::size_type             size_type;\n#endif\n   typedef          Allocator                                               allocator_type;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<\n                                    BidiIterator>::value_type               char_type;\n   typedef          std::basic_string<char_type>                            string_type;\n   typedef          BOOST_REGEX_DETAIL_NS::named_subexpressions                         named_sub_type;\n\n   // construct/copy/destroy:\n   explicit match_results(const Allocator& a = Allocator())\n#ifndef BOOST_NO_STD_ALLOCATOR\n      : m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}\n#else\n      : m_subs(), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }\n#endif\n   //\n   // IMPORTANT: in the code below, the crazy looking checks around m_is_singular are\n   // all required because it is illegal to copy a singular iterator.\n   // See https://svn.boost.org/trac/boost/ticket/3632.\n   //\n   match_results(const match_results& m)\n      : m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)\n   {\n      if(!m_is_singular)\n      {\n         m_base = m.m_base;\n         m_null = m.m_null;\n      }\n   }\n   match_results& operator=(const match_results& m)\n   {\n      m_subs = m.m_subs;\n      m_named_subs = m.m_named_subs;\n      m_last_closed_paren = m.m_last_closed_paren;\n      m_is_singular = m.m_is_singular;\n      if(!m_is_singular)\n      {\n         m_base = m.m_base;\n         m_null = m.m_null;\n      }\n      return *this;\n   }\n   ~match_results(){}\n\n   // size:\n   size_type size() const\n   { return empty() ? 0 : m_subs.size() - 2; }\n   size_type max_size() const\n   { return m_subs.max_size(); }\n   bool empty() const\n   { return m_subs.size() < 2; }\n   // element access:\n   difference_type length(int sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      if((sub < (int)m_subs.size()) && (sub > 0))\n         return m_subs[sub].length();\n      return 0;\n   }\n   difference_type length(const char_type* sub) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      const char_type* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return length(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT>\n   difference_type length(const charT* sub) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      const charT* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return length(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT, class Traits, class A>\n   difference_type length(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return length(sub.c_str());\n   }\n   difference_type position(size_type sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      if(sub < m_subs.size())\n      {\n         const sub_match<BidiIterator>& s = m_subs[sub];\n         if(s.matched || (sub == 2))\n         {\n            return ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)(m_base), (BidiIterator)(s.first));\n         }\n      }\n      return ~static_cast<difference_type>(0);\n   }\n   difference_type position(const char_type* sub) const\n   {\n      const char_type* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return position(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT>\n   difference_type position(const charT* sub) const\n   {\n      const charT* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return position(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT, class Traits, class A>\n   difference_type position(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return position(sub.c_str());\n   }\n   string_type str(int sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      string_type result;\n      if(sub < (int)m_subs.size() && (sub > 0))\n      {\n         const sub_match<BidiIterator>& s = m_subs[sub];\n         if(s.matched)\n         {\n            result = s.str();\n         }\n      }\n      return result;\n   }\n   string_type str(const char_type* sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class Traits, class A>\n   string_type str(const std::basic_string<char_type, Traits, A>& sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class charT>\n   string_type str(const charT* sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class charT, class Traits, class A>\n   string_type str(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return (*this)[sub].str();\n   }\n   const_reference operator[](int sub) const\n   {\n      if(m_is_singular && m_subs.empty())\n         raise_logic_error();\n      sub += 2;\n      if(sub < (int)m_subs.size() && (sub >= 0))\n      {\n         return m_subs[sub];\n      }\n      return m_null;\n   }\n   //\n   // Named sub-expressions:\n   //\n   const_reference named_subexpression(const char_type* i, const char_type* j) const\n   {\n      //\n      // Scan for the leftmost *matched* subexpression with the specified named:\n      //\n      if(m_is_singular)\n         raise_logic_error();\n      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);\n      while((r.first != r.second) && ((*this)[r.first->index].matched == false))\n         ++r.first;\n      return r.first != r.second ? (*this)[r.first->index] : m_null;\n   }\n   template <class charT>\n   const_reference named_subexpression(const charT* i, const charT* j) const\n   {\n      BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));\n      if(i == j)\n         return m_null;\n      std::vector<char_type> s;\n      while(i != j)\n         s.insert(s.end(), *i++);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n   int named_subexpression_index(const char_type* i, const char_type* j) const\n   {\n      //\n      // Scan for the leftmost *matched* subexpression with the specified named.\n      // If none found then return the leftmost expression with that name,\n      // otherwise an invalid index:\n      //\n      if(m_is_singular)\n         raise_logic_error();\n      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;\n      s = r = m_named_subs->equal_range(i, j);\n      while((r.first != r.second) && ((*this)[r.first->index].matched == false))\n         ++r.first;\n      if(r.first == r.second)\n         r = s;\n      return r.first != r.second ? r.first->index : -20;\n   }\n   template <class charT>\n   int named_subexpression_index(const charT* i, const charT* j) const\n   {\n      BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));\n      if(i == j)\n         return -20;\n      std::vector<char_type> s;\n      while(i != j)\n         s.insert(s.end(), *i++);\n      return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());\n   }\n   template <class Traits, class A>\n   const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const\n   {\n      return named_subexpression(s.c_str(), s.c_str() + s.size());\n   }\n   const_reference operator[](const char_type* p) const\n   {\n      const char_type* e = p;\n      while(*e) ++e;\n      return named_subexpression(p, e);\n   }\n\n   template <class charT>\n   const_reference operator[](const charT* p) const\n   {\n      BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));\n      if(*p == 0)\n         return m_null;\n      std::vector<char_type> s;\n      while(*p)\n         s.insert(s.end(), *p++);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n   template <class charT, class Traits, class A>\n   const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const\n   {\n      BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));\n      if(ns.empty())\n         return m_null;\n      std::vector<char_type> s;\n      for(unsigned i = 0; i < ns.size(); ++i)\n         s.insert(s.end(), ns[i]);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n\n   const_reference prefix() const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[-1];\n   }\n\n   const_reference suffix() const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[-2];\n   }\n   const_iterator begin() const\n   {\n      return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();\n   }\n   const_iterator end() const\n   {\n      return m_subs.end();\n   }\n   // format:\n   template <class OutputIterator, class Functor>\n   OutputIterator format(OutputIterator out,\n                         Functor fmt,\n                         match_flag_type flags = format_default) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;\n      F func(fmt);\n      return func(*this, out, flags);\n   }\n   template <class Functor>\n   string_type format(Functor fmt, match_flag_type flags = format_default) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      std::basic_string<char_type> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);\n\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;\n      F func(fmt);\n\n      func(*this, i, flags);\n      return result;\n   }\n   // format with locale:\n   template <class OutputIterator, class Functor, class RegexT>\n   OutputIterator format(OutputIterator out,\n                         Functor fmt,\n                         match_flag_type flags,\n                         const RegexT& re) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;\n      F func(fmt);\n      return func(*this, out, flags, re.get_traits());\n   }\n   template <class RegexT, class Functor>\n   string_type format(Functor fmt,\n                      match_flag_type flags,\n                      const RegexT& re) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;\n      std::basic_string<char_type> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);\n\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;\n      F func(fmt);\n\n      func(*this, i, flags, re.get_traits());\n      return result;\n   }\n\n   const_reference get_last_closed_paren()const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];\n   }\n\n   allocator_type get_allocator() const\n   {\n#ifndef BOOST_NO_STD_ALLOCATOR\n      return m_subs.get_allocator();\n#else\n     return allocator_type();\n#endif\n   }\n   void swap(match_results& that)\n   {\n      std::swap(m_subs, that.m_subs);\n      std::swap(m_named_subs, that.m_named_subs);\n      std::swap(m_last_closed_paren, that.m_last_closed_paren);\n      if(m_is_singular)\n      {\n         if(!that.m_is_singular)\n         {\n            m_base = that.m_base;\n            m_null = that.m_null;\n         }\n      }\n      else if(that.m_is_singular)\n      {\n         that.m_base = m_base;\n         that.m_null = m_null;\n      }\n      else\n      {\n         std::swap(m_base, that.m_base);\n         std::swap(m_null, that.m_null);\n      }\n      std::swap(m_is_singular, that.m_is_singular);\n   }\n   bool operator==(const match_results& that)const\n   {\n      if(m_is_singular)\n      {\n         return that.m_is_singular;\n      }\n      else if(that.m_is_singular)\n      {\n         return false;\n      }\n      return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);\n   }\n   bool operator!=(const match_results& that)const\n   { return !(*this == that); }\n\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;\n\n   const capture_sequence_type& captures(int i)const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[i].captures();\n   }\n#endif\n\n   //\n   // private access functions:\n   void BOOST_REGEX_CALL set_second(BidiIterator i)\n   {\n      BOOST_REGEX_ASSERT(m_subs.size() > 2);\n      m_subs[2].second = i;\n      m_subs[2].matched = true;\n      m_subs[0].first = i;\n      m_subs[0].matched = (m_subs[0].first != m_subs[0].second);\n      m_null.first = i;\n      m_null.second = i;\n      m_null.matched = false;\n      m_is_singular = false;\n   }\n\n   void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)\n   {\n      if(pos)\n         m_last_closed_paren = static_cast<int>(pos);\n      pos += 2;\n      BOOST_REGEX_ASSERT(m_subs.size() > pos);\n      m_subs[pos].second = i;\n      m_subs[pos].matched = m;\n      if((pos == 2) && !escape_k)\n      {\n         m_subs[0].first = i;\n         m_subs[0].matched = (m_subs[0].first != m_subs[0].second);\n         m_null.first = i;\n         m_null.second = i;\n         m_null.matched = false;\n         m_is_singular = false;\n      }\n   }\n   void BOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)\n   {\n      value_type v(j);\n      size_type len = m_subs.size();\n      if(len > n + 2)\n      {\n         m_subs.erase(m_subs.begin()+n+2, m_subs.end());\n         std::fill(m_subs.begin(), m_subs.end(), v);\n      }\n      else\n      {\n         std::fill(m_subs.begin(), m_subs.end(), v);\n         if(n+2 != len)\n            m_subs.insert(m_subs.end(), n+2-len, v);\n      }\n      m_subs[1].first = i;\n      m_last_closed_paren = 0;\n   }\n   void BOOST_REGEX_CALL set_base(BidiIterator pos)\n   {\n      m_base = pos;\n   }\n   BidiIterator base()const\n   {\n      return m_base;\n   }\n   void BOOST_REGEX_CALL set_first(BidiIterator i)\n   {\n      BOOST_REGEX_ASSERT(m_subs.size() > 2);\n      // set up prefix:\n      m_subs[1].second = i;\n      m_subs[1].matched = (m_subs[1].first != i);\n      // set up $0:\n      m_subs[2].first = i;\n      // zero out everything else:\n      for(size_type n = 3; n < m_subs.size(); ++n)\n      {\n         m_subs[n].first = m_subs[n].second = m_subs[0].second;\n         m_subs[n].matched = false;\n      }\n   }\n   void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)\n   {\n      BOOST_REGEX_ASSERT(pos+2 < m_subs.size());\n      if(pos || escape_k)\n      {\n         m_subs[pos+2].first = i;\n         if(escape_k)\n         {\n            m_subs[1].second = i;\n            m_subs[1].matched = (m_subs[1].first != m_subs[1].second);\n         }\n      }\n      else\n         set_first(i);\n   }\n   void BOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);\n\n   void BOOST_REGEX_CALL set_named_subs(boost::shared_ptr<named_sub_type> subs)\n   {\n      m_named_subs = subs;\n   }\n\nprivate:\n   //\n   // Error handler called when an uninitialized match_results is accessed:\n   //\n   static void raise_logic_error()\n   {\n      std::logic_error e(\"Attempt to access an uninitialized boost::match_results<> class.\");\n      boost::throw_exception(e);\n   }\n\n\n   vector_type            m_subs;                      // subexpressions\n   BidiIterator   m_base;                              // where the search started from\n   sub_match<BidiIterator> m_null;                     // a null match\n   boost::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object\n   int m_last_closed_paren;                            // Last ) to be seen - used for formatting\n   bool m_is_singular;                                 // True if our stored iterators are singular\n};\n\ntemplate <class BidiIterator, class Allocator>\nvoid BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)\n{\n   if(m_is_singular)\n   {\n      *this = m;\n      return;\n   }\n   const_iterator p1, p2;\n   p1 = begin();\n   p2 = m.begin();\n   //\n   // Distances are measured from the start of *this* match, unless this isn't\n   // a valid match in which case we use the start of the whole sequence.  Note that\n   // no subsequent match-candidate can ever be to the left of the first match found.\n   // This ensures that when we are using bidirectional iterators, that distances \n   // measured are as short as possible, and therefore as efficient as possible\n   // to compute.  Finally note that we don't use the \"matched\" data member to test\n   // whether a sub-expression is a valid match, because partial matches set this\n   // to false for sub-expression 0.\n   //\n   BidiIterator l_end = this->suffix().second;\n   BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;\n   difference_type len1 = 0;\n   difference_type len2 = 0;\n   difference_type base1 = 0;\n   difference_type base2 = 0;\n   std::size_t i;\n   for(i = 0; i < size(); ++i, ++p1, ++p2)\n   {\n      //\n      // Leftmost takes priority over longest; handle special cases\n      // where distances need not be computed first (an optimisation\n      // for bidirectional iterators: ensure that we don't accidently\n      // compute the length of the whole sequence, as this can be really\n      // expensive).\n      //\n      if(p1->first == l_end)\n      {\n         if(p2->first != l_end)\n         {\n            // p2 must be better than p1, and no need to calculate\n            // actual distances:\n            base1 = 1;\n            base2 = 0;\n            break;\n         }\n         else\n         {\n            // *p1 and *p2 are either unmatched or match end-of sequence,\n            // either way no need to calculate distances:\n            if((p1->matched == false) && (p2->matched == true))\n               break;\n            if((p1->matched == true) && (p2->matched == false))\n               return;\n            continue;\n         }\n      }\n      else if(p2->first == l_end)\n      {\n         // p1 better than p2, and no need to calculate distances:\n         return;\n      }\n      base1 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p1->first);\n      base2 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p2->first);\n      BOOST_REGEX_ASSERT(base1 >= 0);\n      BOOST_REGEX_ASSERT(base2 >= 0);\n      if(base1 < base2) return;\n      if(base2 < base1) break;\n\n      len1 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p1->first, (BidiIterator)p1->second);\n      len2 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p2->first, (BidiIterator)p2->second);\n      BOOST_REGEX_ASSERT(len1 >= 0);\n      BOOST_REGEX_ASSERT(len2 >= 0);\n      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))\n         break;\n      if((p1->matched == true) && (p2->matched == false))\n         return;\n   }\n   if(i == size())\n      return;\n   if(base2 < base1)\n      *this = m;\n   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )\n      *this = m;\n}\n\ntemplate <class BidiIterator, class Allocator>\nvoid swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)\n{\n   a.swap(b);\n}\n\n#ifndef BOOST_NO_STD_LOCALE\ntemplate <class charT, class traits, class BidiIterator, class Allocator>\nstd::basic_ostream<charT, traits>&\n   operator << (std::basic_ostream<charT, traits>& os,\n                const match_results<BidiIterator, Allocator>& s)\n{\n   return (os << s.str());\n}\n#else\ntemplate <class BidiIterator, class Allocator>\nstd::ostream& operator << (std::ostream& os,\n                           const match_results<BidiIterator, Allocator>& s)\n{\n   return (os << s.str());\n}\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/mem_block_cache.hpp",
    "content": " /*\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         mem_block_cache.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: memory block cache used by the non-recursive matcher.\n  */\n\n#ifndef BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP\n#define BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP\n\n#include <new>\n#ifdef BOOST_HAS_THREADS\n#include <boost/regex/pending/static_mutex.hpp>\n#endif\n\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n\n#ifndef BOOST_NO_CXX11_HDR_ATOMIC\n  #include <atomic>\n  #if ATOMIC_POINTER_LOCK_FREE == 2\n    #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE\n    #define BOOST_REGEX_ATOMIC_POINTER std::atomic\n  #endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */\nstruct mem_block_cache\n{\n  std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];\n\n   ~mem_block_cache()\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       if (cache[i].load()) ::operator delete(cache[i].load());\n     }\n   }\n   void* get()\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       void* p = cache[i].load();\n       if (p != NULL) {\n         if (cache[i].compare_exchange_strong(p, NULL)) return p;\n       }\n     }\n     return ::operator new(BOOST_REGEX_BLOCKSIZE);\n   }\n   void put(void* ptr)\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       void* p = cache[i].load();\n       if (p == NULL) {\n         if (cache[i].compare_exchange_strong(p, ptr)) return;\n       }\n     }\n     ::operator delete(ptr);\n   }\n\n   static mem_block_cache& instance()\n   {\n      static mem_block_cache block_cache = { { {nullptr} } };\n      return block_cache;\n   }\n};\n\n\n#else /* lock-based implementation */\n\n\nstruct mem_block_node\n{\n   mem_block_node* next;\n};\n\nstruct mem_block_cache\n{\n   // this member has to be statically initialsed:\n   mem_block_node* next;\n   unsigned cached_blocks;\n#ifdef BOOST_HAS_THREADS\n   boost::static_mutex mut;\n#endif\n\n   ~mem_block_cache()\n   {\n      while(next)\n      {\n         mem_block_node* old = next;\n         next = next->next;\n         ::operator delete(old);\n      }\n   }\n   void* get()\n   {\n#ifdef BOOST_HAS_THREADS\n      boost::static_mutex::scoped_lock g(mut);\n#endif\n     if(next)\n      {\n         mem_block_node* result = next;\n         next = next->next;\n         --cached_blocks;\n         return result;\n      }\n      return ::operator new(BOOST_REGEX_BLOCKSIZE);\n   }\n   void put(void* p)\n   {\n#ifdef BOOST_HAS_THREADS\n      boost::static_mutex::scoped_lock g(mut);\n#endif\n      if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)\n      {\n         ::operator delete(p);\n      }\n      else\n      {\n         mem_block_node* old = static_cast<mem_block_node*>(p);\n         old->next = next;\n         next = old;\n         ++cached_blocks;\n      }\n   }\n   static mem_block_cache& instance()\n   {\n#ifdef BOOST_HAS_THREADS\n      static mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };\n#else\n      static mem_block_cache block_cache = { 0, 0, };\n#endif\n      return block_cache;\n   }\n};\n#endif\n\n#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0\n\ninline void* BOOST_REGEX_CALL get_mem_block()\n{\n   return ::operator new(BOOST_REGEX_BLOCKSIZE);\n}\n\ninline void BOOST_REGEX_CALL put_mem_block(void* p)\n{\n   ::operator delete(p);\n}\n\n#else\n\ninline void* BOOST_REGEX_CALL get_mem_block()\n{\n   return mem_block_cache::instance().get();\n}\n\ninline void BOOST_REGEX_CALL put_mem_block(void* p)\n{\n   mem_block_cache::instance().put(p);\n}\n\n#endif\n}\n} // namespace boost\n\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/object_cache.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         object_cache.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Implements a generic object cache.\n  */\n\n#ifndef BOOST_REGEX_OBJECT_CACHE_HPP\n#define BOOST_REGEX_OBJECT_CACHE_HPP\n\n#include <boost/regex/config.hpp>\n#include <boost/shared_ptr.hpp>\n#include <map>\n#include <list>\n#include <stdexcept>\n#include <string>\n#ifdef BOOST_HAS_THREADS\n#include <boost/regex/pending/static_mutex.hpp>\n#endif\n\nnamespace boost{\n\ntemplate <class Key, class Object>\nclass object_cache\n{\npublic:\n   typedef std::pair< ::boost::shared_ptr<Object const>, Key const*> value_type;\n   typedef std::list<value_type> list_type;\n   typedef typename list_type::iterator list_iterator;\n   typedef std::map<Key, list_iterator> map_type;\n   typedef typename map_type::iterator map_iterator;\n   typedef typename list_type::size_type size_type;\n   static boost::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size);\n\nprivate:\n   static boost::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size);\n\n   struct data\n   {\n      list_type   cont;\n      map_type    index;\n   };\n\n   // Needed by compilers not implementing the resolution to DR45. For reference,\n   // see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.\n   friend struct data;\n};\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4702)\n#endif\ntemplate <class Key, class Object>\nboost::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size)\n{\n#ifdef BOOST_HAS_THREADS\n   static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT;\n   boost::static_mutex::scoped_lock l(mut);\n   if (l)\n   {\n      return do_get(k, l_max_cache_size);\n   }\n   //\n   // what do we do if the lock fails?\n   // for now just throw, but we should never really get here...\n   //\n   ::boost::throw_exception(std::runtime_error(\"Error in thread safety code: could not acquire a lock\"));\n#if defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION) || defined(BOOST_NO_EXCEPTIONS)\n   return boost::shared_ptr<Object>();\n#endif\n#else\n   return do_get(k, l_max_cache_size);\n#endif\n}\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class Key, class Object>\nboost::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size)\n{\n   typedef typename object_cache<Key, Object>::data object_data;\n   typedef typename map_type::size_type map_size_type;\n   static object_data s_data;\n\n   //\n   // see if the object is already in the cache:\n   //\n   map_iterator mpos = s_data.index.find(k);\n   if(mpos != s_data.index.end())\n   {\n      //\n      // Eureka! \n      // We have a cached item, bump it up the list and return it:\n      //\n      if(--(s_data.cont.end()) != mpos->second)\n      {\n         // splice out the item we want to move:\n         list_type temp;\n         temp.splice(temp.end(), s_data.cont, mpos->second);\n         // and now place it at the end of the list:\n         s_data.cont.splice(s_data.cont.end(), temp, temp.begin());\n         BOOST_REGEX_ASSERT(*(s_data.cont.back().second) == k);\n         // update index with new position:\n         mpos->second = --(s_data.cont.end());\n         BOOST_REGEX_ASSERT(&(mpos->first) == mpos->second->second);\n         BOOST_REGEX_ASSERT(&(mpos->first) == s_data.cont.back().second);\n      }\n      return s_data.cont.back().first;\n   }\n   //\n   // if we get here then the item is not in the cache,\n   // so create it:\n   //\n   boost::shared_ptr<Object const> result(new Object(k));\n   //\n   // Add it to the list, and index it:\n   //\n   s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));\n   s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));\n   s_data.cont.back().second = &(s_data.index.find(k)->first);\n   map_size_type s = s_data.index.size();\n   BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());\n   BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);\n   BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);\n   if(s > l_max_cache_size)\n   {\n      //\n      // We have too many items in the list, so we need to start\n      // popping them off the back of the list, but only if they're\n      // being held uniquely by us:\n      //\n      list_iterator pos = s_data.cont.begin();\n      list_iterator last = s_data.cont.end();\n      while((pos != last) && (s > l_max_cache_size))\n      {\n         if(pos->first.unique())\n         {\n            list_iterator condemmed(pos);\n            ++pos;\n            // now remove the items from our containers, \n            // then order has to be as follows:\n            BOOST_REGEX_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());\n            s_data.index.erase(*(condemmed->second));\n            s_data.cont.erase(condemmed); \n            --s;\n         }\n         else\n            ++pos;\n      }\n      BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());\n      BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);\n      BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);\n   }\n   return result;\n}\n\n}\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/pattern_except.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         pattern_except.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares pattern-matching exception classes.\n  */\n\n#ifndef BOOST_RE_V4_PAT_EXCEPT_HPP\n#define BOOST_RE_V4_PAT_EXCEPT_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#include <cstddef>\n#include <stdexcept>\n#include <boost/regex/v4/error_type.hpp>\n#include <boost/regex/v4/regex_traits_defaults.hpp>\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4275)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable : 26812)\n#endif\n#endif\nclass regex_error : public std::runtime_error\n{\npublic:\n   explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0)\n      : std::runtime_error(s)\n      , m_error_code(err)\n      , m_position(pos)\n   {\n   }\n   explicit regex_error(regex_constants::error_type err)\n      : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))\n      , m_error_code(err)\n      , m_position(0)\n   {\n   }\n   ~regex_error() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}\n   regex_constants::error_type code()const\n   { return m_error_code; }\n   std::ptrdiff_t position()const\n   { return m_position; }\n   void raise()const \n   {\n#ifndef BOOST_NO_EXCEPTIONS\n#ifndef BOOST_REGEX_STANDALONE\n      ::boost::throw_exception(*this);\n#else\n      throw* this;\n#endif\n#endif\n   }\nprivate:\n   regex_constants::error_type m_error_code;\n   std::ptrdiff_t m_position;\n};\n\ntypedef regex_error bad_pattern;\ntypedef regex_error bad_expression;\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class E>\ninline void raise_runtime_error(const E& ex)\n{\n#ifndef BOOST_REGEX_STANDALONE\n   ::boost::throw_exception(ex);\n#else\n   throw ex;\n#endif\n}\n\ntemplate <class traits>\nvoid raise_error(const traits& t, regex_constants::error_type code)\n{\n   (void)t;  // warning suppression\n   regex_error e(t.error_string(code), code, 0);\n   ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e);\n}\n\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/perl_matcher.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n#ifndef BOOST_REGEX_MATCHER_HPP\n#define BOOST_REGEX_MATCHER_HPP\n\n#include <boost/regex/v4/iterator_category.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#pragma warning(disable : 4251)\n#if BOOST_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#  if BOOST_MSVC < 1600\n#     pragma warning(disable : 4660)\n#  endif\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// error checking API:\n//\ninline void BOOST_REGEX_CALL verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf)\n{\n   //\n   // can't mix match_extra with POSIX matching rules:\n   //\n   if ((mf & match_extra) && (mf & match_posix))\n   {\n      std::logic_error msg(\"Usage Error: Can't mix regular expression captures with POSIX matching rules\");\n      throw_exception(msg);\n   }\n}\n//\n// function can_start:\n//\ntemplate <class charT>\ninline bool can_start(charT c, const unsigned char* map, unsigned char mask)\n{\n   return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));\n}\ninline bool can_start(char c, const unsigned char* map, unsigned char mask)\n{\n   return map[(unsigned char)c] & mask;\n}\ninline bool can_start(signed char c, const unsigned char* map, unsigned char mask)\n{\n   return map[(unsigned char)c] & mask;\n}\ninline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)\n{\n   return map[c] & mask;\n}\ninline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)\n{\n   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);\n}\n#if !defined(__hpux) && !defined(__WINSCW__)// WCHAR_MIN not usable in pp-directives.\n#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\ninline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)\n{\n   return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);\n}\n#endif\n#endif\n#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)\ninline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)\n{\n   return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));\n}\n#endif\n\n\n//\n// Unfortunately Rogue Waves standard library appears to have a bug\n// in std::basic_string::compare that results in erroneous answers\n// in some cases (tested with Borland C++ 5.1, Rogue Wave lib version\n// 0x020101) the test case was:\n// {39135,0} < {0xff,0}\n// which succeeds when it should not.\n//\n#ifndef _RWSTD_VER\ntemplate <class C, class T, class A>\ninline int string_compare(const std::basic_string<C,T,A>& s, const C* p)\n{ \n   if(0 == *p)\n   {\n      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))\n         return 0;\n   }\n   return s.compare(p); \n}\n#else\ntemplate <class C, class T, class A>\ninline int string_compare(const std::basic_string<C,T,A>& s, const C* p)\n{ \n   if(0 == *p)\n   {\n      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))\n         return 0;\n   }\n   return s.compare(p); \n}\ninline int string_compare(const std::string& s, const char* p)\n{ return std::strcmp(s.c_str(), p); }\n# ifndef BOOST_NO_WREGEX\ninline int string_compare(const std::wstring& s, const wchar_t* p)\n{ return std::wcscmp(s.c_str(), p); }\n#endif\n#endif\ntemplate <class Seq, class C>\ninline int string_compare(const Seq& s, const C* p)\n{\n   std::size_t i = 0;\n   while((i < s.size()) && (p[i] == s[i]))\n   {\n      ++i;\n   }\n   return (i == s.size()) ? -(int)p[i] : (int)s[i] - (int)p[i];\n}\n# define STR_COMP(s,p) string_compare(s,p)\n\ntemplate<class charT>\ninline const charT* re_skip_past_null(const charT* p)\n{\n  while (*p != static_cast<charT>(0)) ++p;\n  return ++p;\n}\n\ntemplate <class iterator, class charT, class traits_type, class char_classT>\niterator BOOST_REGEX_CALL re_is_set_member(iterator next, \n                          iterator last, \n                          const re_set_long<char_classT>* set_, \n                          const regex_data<charT, traits_type>& e, bool icase)\n{   \n   const charT* p = reinterpret_cast<const charT*>(set_+1);\n   iterator ptr;\n   unsigned int i;\n   //bool icase = e.m_flags & regex_constants::icase;\n\n   if(next == last) return next;\n\n   typedef typename traits_type::string_type traits_string_type;\n   const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);\n   \n   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never\n   // referenced\n   (void)traits_inst;\n\n   // try and match a single character, could be a multi-character\n   // collating element...\n   for(i = 0; i < set_->csingles; ++i)\n   {\n      ptr = next;\n      if(*p == static_cast<charT>(0))\n      {\n         // treat null string as special case:\n         if(traits_inst.translate(*ptr, icase))\n         {\n            ++p;\n            continue;\n         }\n         return set_->isnot ? next : (ptr == next) ? ++next : ptr;\n      }\n      else\n      {\n         while(*p && (ptr != last))\n         {\n            if(traits_inst.translate(*ptr, icase) != *p)\n               break;\n            ++p;\n            ++ptr;\n         }\n\n         if(*p == static_cast<charT>(0)) // if null we've matched\n            return set_->isnot ? next : (ptr == next) ? ++next : ptr;\n\n         p = re_skip_past_null(p);     // skip null\n      }\n   }\n\n   charT col = traits_inst.translate(*next, icase);\n\n\n   if(set_->cranges || set_->cequivalents)\n   {\n      traits_string_type s1;\n      //\n      // try and match a range, NB only a single character can match\n      if(set_->cranges)\n      {\n         if((e.m_flags & regex_constants::collate) == 0)\n            s1.assign(1, col);\n         else\n         {\n            charT a[2] = { col, charT(0), };\n            s1 = traits_inst.transform(a, a + 1);\n         }\n         for(i = 0; i < set_->cranges; ++i)\n         {\n            if(STR_COMP(s1, p) >= 0)\n            {\n               do{ ++p; }while(*p);\n               ++p;\n               if(STR_COMP(s1, p) <= 0)\n                  return set_->isnot ? next : ++next;\n            }\n            else\n            {\n               // skip first string\n               do{ ++p; }while(*p);\n               ++p;\n            }\n            // skip second string\n            do{ ++p; }while(*p);\n            ++p;\n         }\n      }\n      //\n      // try and match an equivalence class, NB only a single character can match\n      if(set_->cequivalents)\n      {\n         charT a[2] = { col, charT(0), };\n         s1 = traits_inst.transform_primary(a, a +1);\n         for(i = 0; i < set_->cequivalents; ++i)\n         {\n            if(STR_COMP(s1, p) == 0)\n               return set_->isnot ? next : ++next;\n            // skip string\n            do{ ++p; }while(*p);\n            ++p;\n         }\n      }\n   }\n   if(traits_inst.isctype(col, set_->cclasses) == true)\n      return set_->isnot ? next : ++next;\n   if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))\n      return set_->isnot ? next : ++next;\n   return set_->isnot ? ++next : next;\n}\n\ntemplate <class BidiIterator>\nclass repeater_count\n{\n   repeater_count** stack;\n   repeater_count* next;\n   int state_id;\n   std::size_t count;        // the number of iterations so far\n   BidiIterator start_pos;   // where the last repeat started\n\n   repeater_count* unwind_until(int n, repeater_count* p, int current_recursion_id)\n   { \n      while(p && (p->state_id != n))\n      {\n         if(-2 - current_recursion_id == p->state_id)\n            return 0;\n         p = p->next;\n         if(p && (p->state_id < 0))\n         {\n            p = unwind_until(p->state_id, p, current_recursion_id);\n            if(!p)\n               return p;\n            p = p->next;\n         }\n      }\n      return p;\n   }\npublic:\n   repeater_count(repeater_count** s) : stack(s), next(0), state_id(-1), count(0), start_pos() {}\n   \n   repeater_count(int i, repeater_count** s, BidiIterator start, int current_recursion_id)\n      : start_pos(start)\n   {\n      state_id = i;\n      stack = s;\n      next = *stack;\n      *stack = this;\n      if((state_id > next->state_id) && (next->state_id >= 0))\n         count = 0;\n      else\n      {\n         repeater_count* p = next;\n         p = unwind_until(state_id, p, current_recursion_id);\n         if(p)\n         {\n            count = p->count;\n            start_pos = p->start_pos;\n         }\n         else\n            count = 0;\n      }\n   }\n   ~repeater_count()\n   {\n      if(next)\n         *stack = next;\n   }\n   std::size_t get_count() { return count; }\n   int get_id() { return state_id; }\n   std::size_t operator++() { return ++count; }\n   bool check_null_repeat(const BidiIterator& pos, std::size_t max)\n   {\n      // this is called when we are about to start a new repeat,\n      // if the last one was NULL move our count to max,\n      // otherwise save the current position.\n      bool result = (count == 0) ? false : (pos == start_pos);\n      if(result)\n         count = max;\n      else\n         start_pos = pos;\n      return result;\n   }\n};\n\nstruct saved_state;\n\nenum saved_state_type\n{\n   saved_type_end = 0,\n   saved_type_paren = 1,\n   saved_type_recurse = 2,\n   saved_type_assertion = 3,\n   saved_state_alt = 4,\n   saved_state_repeater_count = 5,\n   saved_state_extra_block = 6,\n   saved_state_greedy_single_repeat = 7,\n   saved_state_rep_slow_dot = 8,\n   saved_state_rep_fast_dot = 9,\n   saved_state_rep_char = 10,\n   saved_state_rep_short_set = 11,\n   saved_state_rep_long_set = 12,\n   saved_state_non_greedy_long_repeat = 13, \n   saved_state_count = 14\n};\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable:26495)\n#endif\n#endif\ntemplate <class Results>\nstruct recursion_info\n{\n   typedef typename Results::value_type value_type;\n   typedef typename value_type::iterator iterator;\n   int idx;\n   const re_syntax_base* preturn_address;\n   Results results;\n   repeater_count<iterator>* repeater_stack;\n   iterator location_of_start;\n};\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class BidiIterator, class Allocator, class traits>\nclass perl_matcher\n{\npublic:\n   typedef typename traits::char_type char_type;\n   typedef perl_matcher<BidiIterator, Allocator, traits> self_type;\n   typedef bool (self_type::*matcher_proc_type)();\n   typedef std::size_t traits_size_type;\n   typedef typename is_byte<char_type>::width_type width_type;\n   typedef typename regex_iterator_traits<BidiIterator>::difference_type difference_type;\n   typedef match_results<BidiIterator, Allocator> results_type;\n\n   perl_matcher(BidiIterator first, BidiIterator end, \n      match_results<BidiIterator, Allocator>& what, \n      const basic_regex<char_type, traits>& e,\n      match_flag_type f,\n      BidiIterator l_base)\n      :  m_result(what), base(first), last(end), \n         position(first), backstop(l_base), re(e), traits_inst(e.get_traits()), \n         m_independent(false), next_count(&rep_obj), rep_obj(&next_count)\n#ifdef BOOST_REGEX_NON_RECURSIVE\n      , m_recursions(0)\n#endif\n   {\n      construct_init(e, f);\n   }\n\n   bool match();\n   bool find();\n\n   void setf(match_flag_type f)\n   { m_match_flags |= f; }\n   void unsetf(match_flag_type f)\n   { m_match_flags &= ~f; }\n\nprivate:\n   void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);\n\n   bool find_imp();\n   bool match_imp();\n#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD\n   typedef bool (perl_matcher::*protected_proc_type)();\n   bool protected_call(protected_proc_type);\n#endif\n   void estimate_max_state_count(std::random_access_iterator_tag*);\n   void estimate_max_state_count(void*);\n   bool match_prefix();\n   bool match_all_states();\n\n   // match procs, stored in s_match_vtable:\n   bool match_startmark();\n   bool match_endmark();\n   bool match_literal();\n   bool match_start_line();\n   bool match_end_line();\n   bool match_wild();\n   bool match_match();\n   bool match_word_boundary();\n   bool match_within_word();\n   bool match_word_start();\n   bool match_word_end();\n   bool match_buffer_start();\n   bool match_buffer_end();\n   bool match_backref();\n   bool match_long_set();\n   bool match_set();\n   bool match_jump();\n   bool match_alt();\n   bool match_rep();\n   bool match_combining();\n   bool match_soft_buffer_end();\n   bool match_restart_continue();\n   bool match_long_set_repeat();\n   bool match_set_repeat();\n   bool match_char_repeat();\n   bool match_dot_repeat_fast();\n   bool match_dot_repeat_slow();\n   bool match_dot_repeat_dispatch()\n   {\n      return ::boost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();\n   }\n   bool match_backstep();\n   bool match_assert_backref();\n   bool match_toggle_case();\n#ifdef BOOST_REGEX_RECURSIVE\n   bool backtrack_till_match(std::size_t count);\n#endif\n   bool match_recursion();\n   bool match_fail();\n   bool match_accept();\n   bool match_commit();\n   bool match_then();\n   bool skip_until_paren(int index, bool match = true);\n\n   // find procs stored in s_find_vtable:\n   bool find_restart_any();\n   bool find_restart_word();\n   bool find_restart_line();\n   bool find_restart_buf();\n   bool find_restart_lit();\n\nprivate:\n   // final result structure to be filled in:\n   match_results<BidiIterator, Allocator>& m_result;\n   // temporary result for POSIX matches:\n   scoped_ptr<match_results<BidiIterator, Allocator> > m_temp_match;\n   // pointer to actual result structure to fill in:\n   match_results<BidiIterator, Allocator>* m_presult;\n   // start of sequence being searched:\n   BidiIterator base;\n   // end of sequence being searched:\n   BidiIterator last; \n   // current character being examined:\n   BidiIterator position;\n   // where to restart next search after failed match attempt:\n   BidiIterator restart;\n   // where the current search started from, acts as base for $` during grep:\n   BidiIterator search_base;\n   // how far we can go back when matching lookbehind:\n   BidiIterator backstop;\n   // the expression being examined:\n   const basic_regex<char_type, traits>& re;\n   // the expression's traits class:\n   const ::boost::regex_traits_wrapper<traits>& traits_inst;\n   // the next state in the machine being matched:\n   const re_syntax_base* pstate;\n   // matching flags in use:\n   match_flag_type m_match_flags;\n   // how many states we have examined so far:\n   std::ptrdiff_t state_count;\n   // max number of states to examine before giving up:\n   std::ptrdiff_t max_state_count;\n   // whether we should ignore case or not:\n   bool icase;\n   // set to true when (position == last), indicates that we may have a partial match:\n   bool m_has_partial_match;\n   // set to true whenever we get a match:\n   bool m_has_found_match;\n   // set to true whenever we're inside an independent sub-expression:\n   bool m_independent;\n   // the current repeat being examined:\n   repeater_count<BidiIterator>* next_count;\n   // the first repeat being examined (top of linked list):\n   repeater_count<BidiIterator> rep_obj;\n   // the mask to pass when matching word boundaries:\n   typename traits::char_class_type m_word_mask;\n   // the bitmask to use when determining whether a match_any matches a newline or not:\n   unsigned char match_any_mask;\n   // recursion information:\n   std::vector<recursion_info<results_type> > recursion_stack;\n#ifdef BOOST_REGEX_RECURSIVE\n   // Set to false by a (*COMMIT):\n   bool m_can_backtrack;\n   bool m_have_accept;\n   bool m_have_then;\n#endif\n#ifdef BOOST_REGEX_NON_RECURSIVE\n   //\n   // additional members for non-recursive version:\n   //\n   typedef bool (self_type::*unwind_proc_type)(bool);\n\n   void extend_stack();\n   bool unwind(bool);\n   bool unwind_end(bool);\n   bool unwind_paren(bool);\n   bool unwind_recursion_stopper(bool);\n   bool unwind_assertion(bool);\n   bool unwind_alt(bool);\n   bool unwind_repeater_counter(bool);\n   bool unwind_extra_block(bool);\n   bool unwind_greedy_single_repeat(bool);\n   bool unwind_slow_dot_repeat(bool);\n   bool unwind_fast_dot_repeat(bool);\n   bool unwind_char_repeat(bool);\n   bool unwind_short_set_repeat(bool);\n   bool unwind_long_set_repeat(bool);\n   bool unwind_non_greedy_repeat(bool);\n   bool unwind_recursion(bool);\n   bool unwind_recursion_pop(bool);\n   bool unwind_commit(bool);\n   bool unwind_then(bool);\n   bool unwind_case(bool);\n   void destroy_single_repeat();\n   void push_matched_paren(int index, const sub_match<BidiIterator>& sub);\n   void push_recursion_stopper();\n   void push_assertion(const re_syntax_base* ps, bool positive);\n   void push_alt(const re_syntax_base* ps);\n   void push_repeater_count(int i, repeater_count<BidiIterator>** s);\n   void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);\n   void push_non_greedy_repeat(const re_syntax_base* ps);\n   void push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2);\n   void push_recursion_pop();\n   void push_case_change(bool);\n\n   // pointer to base of stack:\n   saved_state* m_stack_base;\n   // pointer to current stack position:\n   saved_state* m_backup_state;\n   // how many memory blocks have we used up?:\n   unsigned used_block_count;\n   // determines what value to return when unwinding from recursion,\n   // allows for mixed recursive/non-recursive algorithm:\n   bool m_recursive_result;\n   // We have unwound to a lookahead/lookbehind, used by COMMIT/PRUNE/SKIP:\n   bool m_unwound_lookahead;\n   // We have unwound to an alternative, used by THEN:\n   bool m_unwound_alt;\n   // We are unwinding a commit - used by independent subs to determine whether to stop there or carry on unwinding:\n   //bool m_unwind_commit;\n   // Recursion limit:\n   unsigned m_recursions;\n#endif\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable:26495)\n#endif\n#endif\n   // these operations aren't allowed, so are declared private,\n   // bodies are provided to keep explicit-instantiation requests happy:\n   perl_matcher& operator=(const perl_matcher&)\n   {\n      return *this;\n   }\n   perl_matcher(const perl_matcher& that)\n      : m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n//\n// include the implementation of perl_matcher:\n//\n#ifdef BOOST_REGEX_RECURSIVE\n#include <boost/regex/v4/perl_matcher_recursive.hpp>\n#else\n#include <boost/regex/v4/perl_matcher_non_recursive.hpp>\n#endif\n// this one has to be last:\n#include <boost/regex/v4/perl_matcher_common.hpp>\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/perl_matcher_common.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         perl_matcher_common.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Definitions of perl_matcher member functions that are \n  *                common to both the recursive and non-recursive versions.\n  */\n\n#ifndef BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP\n#define BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#if BOOST_MSVC >= 1800\n#pragma warning(disable: 26812)\n#endif\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_BORLANDC\n#  pragma option push -w-8008 -w-8066\n#endif\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#pragma warning(disable:26812)\n#endif\n   template <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)\n{ \n   typedef typename regex_iterator_traits<BidiIterator>::iterator_category category;\n   typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;\n   \n   if(e.empty())\n   {\n      // precondition failure: e is not a valid regex.\n      std::invalid_argument ex(\"Invalid regular expression object\");\n      boost::throw_exception(ex);\n   }\n   pstate = 0;\n   m_match_flags = f;\n   estimate_max_state_count(static_cast<category*>(0));\n   expression_flag_type re_f = re.flags();\n   icase = re_f & regex_constants::icase;\n   if(!(m_match_flags & (match_perl|match_posix)))\n   {\n      if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)\n         m_match_flags |= match_perl;\n      else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))\n         m_match_flags |= match_perl;\n      else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))\n         m_match_flags |= match_perl;\n      else\n         m_match_flags |= match_posix;\n   }\n   if(m_match_flags & match_posix)\n   {\n      m_temp_match.reset(new match_results<BidiIterator, Allocator>());\n      m_presult = m_temp_match.get();\n   }\n   else\n      m_presult = &m_result;\n#ifdef BOOST_REGEX_NON_RECURSIVE\n   m_stack_base = 0;\n   m_backup_state = 0;\n#elif defined(BOOST_REGEX_RECURSIVE)\n   m_can_backtrack = true;\n   m_have_accept = false;\n#endif\n   // find the value to use for matching word boundaries:\n   m_word_mask = re.get_data().m_word_mask; \n   // find bitmask to use for matching '.':\n   match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline);\n   // Disable match_any if requested in the state machine:\n   if(e.get_data().m_disable_match_any)\n      m_match_flags &= regex_constants::match_not_any;\n}\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)\n{\n   //\n   // How many states should we allow our machine to visit before giving up?\n   // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)\n   // where N is the length of the string, and S is the number of states\n   // in the machine.  It's tempting to up this to O(N^2S) or even O(N^2S^2)\n   // but these take unreasonably amounts of time to bale out in pathological\n   // cases.\n   //\n   // Calculate NS^2 first:\n   //\n   static const std::ptrdiff_t k = 100000;\n   std::ptrdiff_t dist = boost::BOOST_REGEX_DETAIL_NS::distance(base, last);\n   if(dist == 0)\n      dist = 1;\n   std::ptrdiff_t states = re.size();\n   if(states == 0)\n      states = 1;\n   if ((std::numeric_limits<std::ptrdiff_t>::max)() / states < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= states;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states += k;\n\n   max_state_count = states;\n\n   //\n   // Now calculate N^2:\n   //\n   states = dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states += k;\n   //\n   // N^2 can be a very large number indeed, to prevent things getting out\n   // of control, cap the max states:\n   //\n   if(states > BOOST_REGEX_MAX_STATE_COUNT)\n      states = BOOST_REGEX_MAX_STATE_COUNT;\n   //\n   // If (the possibly capped) N^2 is larger than our first estimate,\n   // use this instead:\n   //\n   if(states > max_state_count)\n      max_state_count = states;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)\n{\n   // we don't know how long the sequence is:\n   max_state_count = BOOST_REGEX_MAX_STATE_COUNT;\n}\n\n#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(\n   protected_proc_type proc)\n{\n   ::boost::BOOST_REGEX_DETAIL_NS::concrete_protected_call\n      <perl_matcher<BidiIterator, Allocator, traits> >\n      obj(this, proc);\n   return obj.execute();\n\n}\n#endif\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::match()\n{\n#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD\n   return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);\n#else\n   return match_imp();\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_imp()\n{\n   // initialise our stack if we are non-recursive:\n#ifdef BOOST_REGEX_NON_RECURSIVE\n   save_state_init init(&m_stack_base, &m_backup_state);\n   used_block_count = BOOST_REGEX_MAX_BLOCKS;\n#if !defined(BOOST_NO_EXCEPTIONS)\n   try{\n#endif\n#endif\n\n   // reset our state machine:\n   position = base;\n   search_base = base;\n   state_count = 0;\n   m_match_flags |= regex_constants::match_all;\n   m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);\n   m_presult->set_base(base);\n   m_presult->set_named_subs(this->re.get_named_subs());\n   if(m_match_flags & match_posix)\n      m_result = *m_presult;\n   verify_options(re.flags(), m_match_flags);\n   if(0 == match_prefix())\n      return false;\n   return (m_result[0].second == last) && (m_result[0].first == base);\n\n#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)\n   }\n   catch(...)\n   {\n      // unwind all pushed states, apart from anything else this\n      // ensures that all the states are correctly destructed\n      // not just the memory freed.\n      while(unwind(true)){}\n      throw;\n   }\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::find()\n{\n#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD\n   return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);\n#else\n   return find_imp();\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_imp()\n{\n   static matcher_proc_type const s_find_vtable[7] = \n   {\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,\n   };\n\n   // initialise our stack if we are non-recursive:\n#ifdef BOOST_REGEX_NON_RECURSIVE\n   save_state_init init(&m_stack_base, &m_backup_state);\n   used_block_count = BOOST_REGEX_MAX_BLOCKS;\n#if !defined(BOOST_NO_EXCEPTIONS)\n   try{\n#endif\n#endif\n\n   state_count = 0;\n   if((m_match_flags & regex_constants::match_init) == 0)\n   {\n      // reset our state machine:\n      search_base = position = base;\n      pstate = re.get_first_state();\n      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);\n      m_presult->set_base(base);\n      m_presult->set_named_subs(this->re.get_named_subs());\n      m_match_flags |= regex_constants::match_init;\n   }\n   else\n   {\n      // start again:\n      search_base = position = m_result[0].second;\n      // If last match was null and match_not_null was not set then increment\n      // our start position, otherwise we go into an infinite loop:\n      if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))\n      {\n         if(position == last)\n            return false;\n         else \n            ++position;\n      }\n      // reset $` start:\n      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);\n      //if((base != search_base) && (base == backstop))\n      //   m_match_flags |= match_prev_avail;\n   }\n   if(m_match_flags & match_posix)\n   {\n      m_result.set_size(static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);\n      m_result.set_base(base);\n   }\n\n   verify_options(re.flags(), m_match_flags);\n   // find out what kind of expression we have:\n   unsigned type = (m_match_flags & match_continuous) ? \n      static_cast<unsigned int>(regbase::restart_continue) \n         : static_cast<unsigned int>(re.get_restart_type());\n\n   // call the appropriate search routine:\n   matcher_proc_type proc = s_find_vtable[type];\n   return (this->*proc)();\n\n#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)\n   }\n   catch(...)\n   {\n      // unwind all pushed states, apart from anything else this\n      // ensures that all the states are correctly destructed\n      // not just the memory freed.\n      while(unwind(true)){}\n      throw;\n   }\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()\n{\n   m_has_partial_match = false;\n   m_has_found_match = false;\n   pstate = re.get_first_state();\n   m_presult->set_first(position);\n   restart = position;\n   match_all_states();\n   if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))\n   {\n      m_has_found_match = true;\n      m_presult->set_second(last, 0, false);\n      position = last;\n      if((m_match_flags & match_posix) == match_posix)\n      {\n         m_result.maybe_assign(*m_presult);\n      }\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   if(m_has_found_match && (match_extra & m_match_flags))\n   {\n      //\n      // we have a match, reverse the capture information:\n      //\n      for(unsigned i = 0; i < m_presult->size(); ++i)\n      {\n         typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();\n         std::reverse(seq.begin(), seq.end());\n      }\n   }\n#endif\n   if(!m_has_found_match)\n      position = restart; // reset search postion\n#ifdef BOOST_REGEX_RECURSIVE\n   m_can_backtrack = true; // reset for further searches\n#endif\n   return m_has_found_match;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_literal()\n{\n   unsigned int len = static_cast<const re_literal*>(pstate)->length;\n   const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);\n   //\n   // compare string with what we stored in\n   // our records:\n   for(unsigned int i = 0; i < len; ++i, ++position)\n   {\n      if((position == last) || (traits_inst.translate(*position, icase) != what[i]))\n         return false;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()\n{\n   if(position == backstop)\n   {\n      if((m_match_flags & match_prev_avail) == 0)\n      {\n         if((m_match_flags & match_not_bol) == 0)\n         {\n            pstate = pstate->next.p;\n            return true;\n         }\n         return false;\n      }\n   }\n   else if(m_match_flags & match_single_line)\n      return false;\n\n   // check the previous value character:\n   BidiIterator t(position);\n   --t;\n   if(position != last)\n   {\n      if(is_separator(*t) && !((*t == static_cast<char_type>('\\r')) && (*position == static_cast<char_type>('\\n'))) )\n      {\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   else if(is_separator(*t))\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()\n{\n   if(position != last)\n   {\n      if(m_match_flags & match_single_line)\n         return false;\n      // we're not yet at the end so *first is always valid:\n      if(is_separator(*position))\n      {\n         if((position != backstop) || (m_match_flags & match_prev_avail))\n         {\n            // check that we're not in the middle of \\r\\n sequence\n            BidiIterator t(position);\n            --t;\n            if((*t == static_cast<char_type>('\\r')) && (*position == static_cast<char_type>('\\n')))\n            {\n               return false;\n            }\n         }\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   else if((m_match_flags & match_not_eol) == 0)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_wild()\n{\n   if(position == last) \n      return false;\n   if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))\n      return false;\n   if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))\n      return false;\n   pstate = pstate->next.p;\n   ++position;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()\n{\n   bool b; // indcates whether next character is a word character\n   if(position != last)\n   {\n      // prev and this character must be opposites:\n      b = traits_inst.isctype(*position, m_word_mask);\n   }\n   else\n   {\n      if (m_match_flags & match_not_eow)\n         return false;\n      b = false;\n   }\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n   {\n      if(m_match_flags & match_not_bow)\n         return false;\n      else\n         b ^= false;\n   }\n   else\n   {\n      --position;\n      b ^= traits_inst.isctype(*position, m_word_mask);\n      ++position;\n   }\n   if(b)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false; // no match if we get to here...\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()\n{\n   if(position == last)\n      return false;\n   // both prev and this character must be m_word_mask:\n   bool prev = traits_inst.isctype(*position, m_word_mask);\n   {\n      bool b;\n      if((position == backstop) && ((m_match_flags & match_prev_avail) == 0)) \n         return false;\n      else\n      {\n         --position;\n         b = traits_inst.isctype(*position, m_word_mask);\n         ++position;\n      }\n      if(b == prev)\n      {\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()\n{\n   if(position == last)\n      return false; // can't be starting a word if we're already at the end of input\n   if(!traits_inst.isctype(*position, m_word_mask))\n      return false; // next character isn't a word character\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n   {\n      if(m_match_flags & match_not_bow)\n         return false; // no previous input\n   }\n   else\n   {\n      // otherwise inside buffer:\n      BidiIterator t(position);\n      --t;\n      if(traits_inst.isctype(*t, m_word_mask))\n         return false; // previous character not non-word\n   }\n   // OK we have a match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()\n{\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n      return false;  // start of buffer can't be end of word\n   BidiIterator t(position);\n   --t;\n   if(traits_inst.isctype(*t, m_word_mask) == false)\n      return false;  // previous character wasn't a word character\n\n   if(position == last)\n   {\n      if(m_match_flags & match_not_eow)\n         return false; // end of buffer but not end of word\n   }\n   else\n   {\n      // otherwise inside buffer:\n      if(traits_inst.isctype(*position, m_word_mask))\n         return false; // next character is a word character\n   }\n   pstate = pstate->next.p;\n   return true;      // if we fall through to here then we've succeeded\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()\n{\n   if((position != backstop) || (m_match_flags & match_not_bob))\n      return false;\n   // OK match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()\n{\n   if((position != last) || (m_match_flags & match_not_eob))\n      return false;\n   // OK match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_backref()\n{\n   //\n   // Compare with what we previously matched.\n   // Note that this succeeds if the backref did not partisipate\n   // in the match, this is in line with ECMAScript, but not Perl\n   // or PCRE.\n   //\n   int index = static_cast<const re_brace*>(pstate)->index;\n   if(index >= hash_value_mask)\n   {\n      named_subexpressions::range_type r = re.get_data().equal_range(index);\n      BOOST_REGEX_ASSERT(r.first != r.second);\n      do\n      {\n         index = r.first->index;\n         ++r.first;\n      }while((r.first != r.second) && ((*m_presult)[index].matched != true));\n   }\n\n   if((m_match_flags & match_perl) && !(*m_presult)[index].matched)\n      return false;\n\n   BidiIterator i = (*m_presult)[index].first;\n   BidiIterator j = (*m_presult)[index].second;\n   while(i != j)\n   {\n      if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))\n         return false;\n      ++i;\n      ++position;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()\n{\n   typedef typename traits::char_class_type char_class_type;\n   // let the traits class do the work:\n   if(position == last)\n      return false;\n   BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);\n   if(t != position)\n   {\n      pstate = pstate->next.p;\n      position = t;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_set()\n{\n   if(position == last)\n      return false;\n   if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n   {\n      pstate = pstate->next.p;\n      ++position;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_jump()\n{\n   pstate = static_cast<const re_jump*>(pstate)->alt.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_combining()\n{\n   if(position == last)\n      return false;\n   if(is_combining(traits_inst.translate(*position, icase)))\n      return false;\n   ++position;\n   while((position != last) && is_combining(traits_inst.translate(*position, icase)))\n      ++position;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()\n{\n   if(m_match_flags & match_not_eob)\n      return false;\n   BidiIterator p(position);\n   while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;\n   if(p != last)\n      return false;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()\n{\n   if(position == search_base)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   if( ::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      std::ptrdiff_t maxlen = ::boost::BOOST_REGEX_DETAIL_NS::distance(backstop, position);\n      if(maxlen < static_cast<const re_brace*>(pstate)->index)\n         return false;\n      std::advance(position, -static_cast<const re_brace*>(pstate)->index);\n   }\n   else\n   {\n      int c = static_cast<const re_brace*>(pstate)->index;\n      while(c--)\n      {\n         if(position == backstop)\n            return false;\n         --position;\n      }\n   }\n   pstate = pstate->next.p;\n   return true;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()\n{\n   // return true if marked sub-expression N has been matched:\n   int index = static_cast<const re_brace*>(pstate)->index;\n   bool result = false;\n   if(index == 9999)\n   {\n      // Magic value for a (DEFINE) block:\n      return false;\n   }\n   else if(index > 0)\n   {\n      // Have we matched subexpression \"index\"?\n      // Check if index is a hash value:\n      if(index >= hash_value_mask)\n      {\n         named_subexpressions::range_type r = re.get_data().equal_range(index);\n         while(r.first != r.second)\n         {\n            if((*m_presult)[r.first->index].matched)\n            {\n               result = true;\n               break;\n            }\n            ++r.first;\n         }\n      }\n      else\n      {\n         result = (*m_presult)[index].matched;\n      }\n      pstate = pstate->next.p;\n   }\n   else\n   {\n      // Have we recursed into subexpression \"index\"?\n      // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.\n      int idx = -(index+1);\n      if(idx >= hash_value_mask)\n      {\n         named_subexpressions::range_type r = re.get_data().equal_range(idx);\n         int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;\n         while(r.first != r.second)\n         {\n            result |= (stack_index == r.first->index);\n            if(result)break;\n            ++r.first;\n         }\n      }\n      else\n      {\n         result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));\n      }\n      pstate = pstate->next.p;\n   }\n   return result;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_fail()\n{\n   // Just force a backtrack:\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_accept()\n{\n   if(!recursion_stack.empty())\n   {\n      return skip_until_paren(recursion_stack.back().idx);\n   }\n   else\n   {\n      return skip_until_paren(INT_MAX);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   const unsigned char* _map = re.get_map();\n   while(true)\n   {\n      // skip everything we can't match:\n      while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )\n         ++position;\n      if(position == last)\n      {\n         // run out of characters, try a null match if possible:\n         if(re.can_be_null())\n            return match_prefix();\n         break;\n      }\n      // now try and obtain a match:\n      if(match_prefix())\n         return true;\n      if(position == last)\n         return false;\n      ++position;\n   }\n   return false;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   // do search optimised for word starts:\n   const unsigned char* _map = re.get_map();\n   if((m_match_flags & match_prev_avail) || (position != base))\n      --position;\n   else if(match_prefix())\n      return true;\n   do\n   {\n      while((position != last) && traits_inst.isctype(*position, m_word_mask))\n         ++position;\n      while((position != last) && !traits_inst.isctype(*position, m_word_mask))\n         ++position;\n      if(position == last)\n         break;\n\n      if(can_start(*position, _map, (unsigned char)mask_any) )\n      {\n         if(match_prefix())\n            return true;\n      }\n      if(position == last)\n         break;\n   } while(true);\n   return false;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()\n{\n   // do search optimised for line starts:\n   const unsigned char* _map = re.get_map();\n   if(match_prefix())\n      return true;\n   while(position != last)\n   {\n      while((position != last) && !is_separator(*position))\n         ++position;\n      if(position == last)\n         return false;\n      ++position;\n      if(position == last)\n      {\n         if(re.can_be_null() && match_prefix())\n            return true;\n         return false;\n      }\n\n      if( can_start(*position, _map, (unsigned char)mask_any) )\n      {\n         if(match_prefix())\n            return true;\n      }\n      if(position == last)\n         return false;\n      //++position;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()\n{\n   if((position == base) && ((m_match_flags & match_not_bob) == 0))\n      return match_prefix();\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()\n{\n#if 0\n   if(position == last)\n      return false; // can't possibly match if we're at the end already\n\n   unsigned type = (m_match_flags & match_continuous) ? \n      static_cast<unsigned int>(regbase::restart_continue) \n         : static_cast<unsigned int>(re.get_restart_type());\n\n   const kmp_info<char_type>* info = access::get_kmp(re);\n   int len = info->len;\n   const char_type* x = info->pstr;\n   int j = 0; \n   while (position != last) \n   {\n      while((j > -1) && (x[j] != traits_inst.translate(*position, icase))) \n         j = info->kmp_next[j];\n      ++position;\n      ++j;\n      if(j >= len) \n      {\n         if(type == regbase::restart_fixed_lit)\n         {\n            std::advance(position, -j);\n            restart = position;\n            std::advance(restart, len);\n            m_result.set_first(position);\n            m_result.set_second(restart);\n            position = restart;\n            return true;\n         }\n         else\n         {\n            restart = position;\n            std::advance(position, -j);\n            if(match_prefix())\n               return true;\n            else\n            {\n               for(int k = 0; (restart != position) && (k < j); ++k, --restart)\n                     {} // dwa 10/20/2000 - warning suppression for MWCW\n               if(restart != last)\n                  ++restart;\n               position = restart;\n               j = 0;  //we could do better than this...\n            }\n         }\n      }\n   }\n   if((m_match_flags & match_partial) && (position == last) && j)\n   {\n      // we need to check for a partial match:\n      restart = position;\n      std::advance(position, -j);\n      return match_prefix();\n   }\n#endif\n   return false;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\n#ifdef BOOST_BORLANDC\n#  pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/perl_matcher_non_recursive.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         perl_matcher_common.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Definitions of perl_matcher member functions that are \n  *                specific to the non-recursive implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP\n#define BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP\n\n#include <boost/regex/v4/mem_block_cache.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#  pragma warning(disable: 4706)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class T>\ninline void inplace_destroy(T* p)\n{\n   (void)p;  // warning suppression\n   p->~T();\n}\n\nstruct saved_state\n{\n   union{\n      unsigned int state_id;\n      // this padding ensures correct alignment on 64-bit platforms:\n      std::size_t padding1;\n      std::ptrdiff_t padding2;\n      void* padding3;\n   };\n   saved_state(unsigned i) : state_id(i) {}\n};\n\ntemplate <class BidiIterator>\nstruct saved_matched_paren : public saved_state\n{\n   int index;\n   sub_match<BidiIterator> sub;\n   saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_position : public saved_state\n{\n   const re_syntax_base* pstate;\n   BidiIterator position;\n   saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_assertion : public saved_position<BidiIterator>\n{\n   bool positive;\n   saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos) \n      : saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_repeater : public saved_state\n{\n   repeater_count<BidiIterator> count;\n   saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start, int current_recursion_id)\n      : saved_state(saved_state_repeater_count), count(i, s, start, current_recursion_id){}\n};\n\nstruct saved_extra_block : public saved_state\n{\n   saved_state *base, *end;\n   saved_extra_block(saved_state* b, saved_state* e) \n      : saved_state(saved_state_extra_block), base(b), end(e) {}\n};\n\nstruct save_state_init\n{\n   saved_state** stack;\n   save_state_init(saved_state** base, saved_state** end)\n      : stack(base)\n   {\n      *base = static_cast<saved_state*>(get_mem_block());\n      *end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+BOOST_REGEX_BLOCKSIZE);\n      --(*end);\n      (void) new (*end)saved_state(0);\n      BOOST_REGEX_ASSERT(*end > *base);\n   }\n   ~save_state_init()\n   {\n      put_mem_block(*stack);\n      *stack = 0;\n   }\n};\n\ntemplate <class BidiIterator>\nstruct saved_single_repeat : public saved_state\n{\n   std::size_t count;\n   const re_repeat* rep;\n   BidiIterator last_position;\n   saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id) \n      : saved_state(arg_id), count(c), rep(r), last_position(lp){}\n};\n\ntemplate <class Results>\nstruct saved_recursion : public saved_state\n{\n   saved_recursion(int idx, const re_syntax_base* p, Results* pr, Results* pr2) \n      : saved_state(14), recursion_id(idx), preturn_address(p), internal_results(*pr), prior_results(*pr2) {}\n   int recursion_id;\n   const re_syntax_base* preturn_address;\n   Results internal_results, prior_results;\n};\n\nstruct saved_change_case : public saved_state\n{\n   bool icase;\n   saved_change_case(bool c) : saved_state(18), icase(c) {}\n};\n\nstruct incrementer\n{\n   incrementer(unsigned* pu) : m_pu(pu) { ++*m_pu; }\n   ~incrementer() { --*m_pu; }\n   bool operator > (unsigned i) { return *m_pu > i; }\nprivate:\n   unsigned* m_pu;\n};\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()\n{\n   static matcher_proc_type const s_match_vtable[34] = \n   {\n      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_match,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,\n      // Although this next line *should* be evaluated at compile time, in practice\n      // some compilers (VC++) emit run-time initialisation which breaks thread\n      // safety, so use a dispatch function instead:\n      //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_fail,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_accept,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_commit,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_then,\n   };\n   incrementer inc(&m_recursions);\n   if(inc > 80)\n      raise_error(traits_inst, regex_constants::error_complexity);\n   push_recursion_stopper();\n   do{\n      while(pstate)\n      {\n         matcher_proc_type proc = s_match_vtable[pstate->type];\n         ++state_count;\n         if(!(this->*proc)())\n         {\n            if(state_count > max_state_count)\n               raise_error(traits_inst, regex_constants::error_complexity);\n            if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n               m_has_partial_match = true;\n            bool successful_unwind = unwind(false);\n            if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n               m_has_partial_match = true;\n            if(!successful_unwind)\n               return m_recursive_result;\n         }\n      }\n   }while(unwind(true));\n   return m_recursive_result;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::extend_stack()\n{\n   if(used_block_count)\n   {\n      --used_block_count;\n      saved_state* stack_base;\n      saved_state* backup_state;\n      stack_base = static_cast<saved_state*>(get_mem_block());\n      backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+BOOST_REGEX_BLOCKSIZE);\n      saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);\n      --block;\n      (void) new (block) saved_extra_block(m_stack_base, m_backup_state);\n      m_stack_base = stack_base;\n      m_backup_state = block;\n   }\n   else\n      raise_error(traits_inst, regex_constants::error_stack);\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)\n{\n   //BOOST_REGEX_ASSERT(index);\n   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_case_change(bool c)\n{\n   //BOOST_REGEX_ASSERT(index);\n   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_change_case*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_change_case(c);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()\n{\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(saved_type_recurse);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)\n{\n   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)\n{\n   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_repeater<BidiIterator>(i, s, position, this->recursion_stack.empty() ? (INT_MIN + 3) : this->recursion_stack.back().idx);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2)\n{\n   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_recursion<results_type>(idx, p, presults, presults2);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()\n{\n   // change our case sensitivity:\n   push_case_change(this->icase);\n   this->icase = static_cast<const re_case*>(pstate)->icase;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   switch(index)\n   {\n   case 0:\n      pstate = pstate->next.p;\n      break;\n   case -1:\n   case -2:\n      {\n         // forward lookahead assert:\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         push_assertion(next_pstate, index == -1);\n         break;\n      }\n   case -3:\n      {\n         // independent sub-expression, currently this is always recursive:\n         bool old_independent = m_independent;\n         m_independent = true;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         bool r = false;\n#if !defined(BOOST_NO_EXCEPTIONS)\n      try{\n#endif\n         r = match_all_states();\n         if(!r && !m_independent)\n         {\n            // Must be unwinding from a COMMIT/SKIP/PRUNE and the independent \n            // sub failed, need to unwind everything else:\n            while(unwind(false));\n            return false;\n         }\n#if !defined(BOOST_NO_EXCEPTIONS)\n      }\n      catch(...)\n      {\n         pstate = next_pstate;\n         // unwind all pushed states, apart from anything else this\n         // ensures that all the states are correctly destructed\n         // not just the memory freed.\n         while(unwind(true)) {}\n         throw;\n      }\n#endif\n      pstate = next_pstate;\n      m_independent = old_independent;\n#ifdef BOOST_REGEX_MATCH_EXTRA\n         if(r && (m_match_flags & match_extra))\n         {\n            //\n            // our captures have been stored in *m_presult\n            // we need to unpack them, and insert them\n            // back in the right order when we unwind the stack:\n            //\n            match_results<BidiIterator, Allocator> temp_match(*m_presult);\n            unsigned i;\n            for(i = 0; i < temp_match.size(); ++i)\n               (*m_presult)[i].get_captures().clear();\n            // match everything else:\n#if !defined(BOOST_NO_EXCEPTIONS)\n            try{\n#endif\n               r = match_all_states();\n#if !defined(BOOST_NO_EXCEPTIONS)\n            }\n            catch(...)\n            {\n               pstate = next_pstate;\n               // unwind all pushed states, apart from anything else this\n               // ensures that all the states are correctly destructed\n               // not just the memory freed.\n               while(unwind(true)) {}\n               throw;\n            }\n#endif\n         // now place the stored captures back:\n            for(i = 0; i < temp_match.size(); ++i)\n            {\n               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;\n               seq& s1 = (*m_presult)[i].get_captures();\n               const seq& s2 = temp_match[i].captures();\n               s1.insert(\n                  s1.end(), \n                  s2.begin(), \n                  s2.end());\n            }\n         }\n#endif\n         return r;\n      }\n   case -4:\n      {\n      // conditional expression:\n      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);\n      BOOST_REGEX_ASSERT(alt->type == syntax_element_alt);\n      pstate = alt->next.p;\n      if(pstate->type == syntax_element_assert_backref)\n      {\n         if(!match_assert_backref())\n            pstate = alt->alt.p;\n         break;\n      }\n      else\n      {\n         // zero width assertion, have to match this recursively:\n         BOOST_REGEX_ASSERT(pstate->type == syntax_element_startmark);\n         bool negated = static_cast<const re_brace*>(pstate)->index == -2;\n         BidiIterator saved_position = position;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n#if !defined(BOOST_NO_EXCEPTIONS)\n         try{\n#endif\n            bool r = match_all_states();\n            position = saved_position;\n            if(negated)\n               r = !r;\n            if(r)\n               pstate = next_pstate;\n            else\n               pstate = alt->alt.p;\n#if !defined(BOOST_NO_EXCEPTIONS)\n         }\n         catch(...)\n         {\n            pstate = next_pstate;\n            // unwind all pushed states, apart from anything else this\n            // ensures that all the states are correctly destructed\n            // not just the memory freed.\n            while(unwind(true)){}\n            throw;\n         }\n#endif\n         break;\n      }\n      }\n   case -5:\n      {\n         push_matched_paren(0, (*m_presult)[0]);\n         m_presult->set_first(position, 0, true);\n         pstate = pstate->next.p;\n         break;\n      }\n   default:\n   {\n      BOOST_REGEX_ASSERT(index > 0);\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         push_matched_paren(index, (*m_presult)[index]);\n         m_presult->set_first(position, index);\n      }\n      pstate = pstate->next.p;\n      break;\n   }\n   }\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_alt()\n{\n   bool take_first, take_second;\n   const re_alt* jmp = static_cast<const re_alt*>(pstate);\n\n   // find out which of these two alternatives we need to take:\n   if(position == last)\n   {\n      take_first = jmp->can_be_null & mask_take;\n      take_second = jmp->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);\n  }\n\n   if(take_first)\n   {\n      // we can take the first alternative,\n      // see if we need to push next alternative:\n      if(take_second)\n      {\n         push_alt(jmp->alt.p);\n      }\n      pstate = pstate->next.p;\n      return true;\n   }\n   if(take_second)\n   {\n      pstate = jmp->alt.p;\n      return true;\n   }\n   return false;  // neither option is possible\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_rep()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127 4244)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n\n   // find out which of these two alternatives we need to take:\n   bool take_first, take_second;\n   if(position == last)\n   {\n      take_first = rep->can_be_null & mask_take;\n      take_second = rep->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);\n   }\n\n   if((m_backup_state->state_id != saved_state_repeater_count) \n      || (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)\n      || (next_count->get_id() != rep->state_id))\n   {\n      // we're moving to a different repeat from the last\n      // one, so set up a counter object:\n      push_repeater_count(rep->state_id, &next_count);\n   }\n   //\n   // If we've had at least one repeat already, and the last one \n   // matched the NULL string then set the repeat count to\n   // maximum:\n   //\n   next_count->check_null_repeat(position, rep->max);\n\n   if(next_count->get_count() < rep->min)\n   {\n      // we must take the repeat:\n      if(take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n      return false;\n   }\n\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // try and take the repeat if we can:\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         if(take_second)\n         {\n            // store position in case we fail:\n            push_alt(rep->alt.p);\n         }\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n      else if(take_second)\n      {\n         pstate = rep->alt.p;\n         return true;\n      }\n      return false; // can't take anything, fail...\n   }\n   else // non-greedy\n   {\n      // try and skip the repeat if we can:\n      if(take_second)\n      {\n         if((next_count->get_count() < rep->max) && take_first)\n         {\n            // store position in case we fail:\n            push_non_greedy_repeat(rep->next.p);\n         }\n         pstate = rep->alt.p;\n         return true;\n      }\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n   }\n   return false;\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()\n{\n   std::size_t count = 0;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   re_syntax_base* psingle = rep->next.p;\n   // match compulsory repeats first:\n   while(count < rep->min)\n   {\n      pstate = psingle;\n      if(!match_wild())\n         return false;\n      ++count;\n   }\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // repeat for as long as we can:\n      while(count < rep->max)\n      {\n         pstate = psingle;\n         if(!match_wild())\n            break;\n         ++count;\n      }\n      // remember where we got to if this is a leading repeat:\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_slow_dot);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()\n{\n   if(m_match_flags & match_not_dot_null)\n      return match_dot_repeat_slow();\n   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)\n      return match_dot_repeat_slow();\n\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t count = static_cast<std::size_t>((std::min)(static_cast<std::size_t>(::boost::BOOST_REGEX_DETAIL_NS::distance(position, last)), greedy ? rep->max : rep->min));\n   if(rep->min > count)\n   {\n      position = last;\n      return false;  // not enough text left to match\n   }\n   std::advance(position, count);\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_fast_dot);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   BOOST_REGEX_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);\n   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && (traits_inst.translate(*position, icase) == what))\n      {\n         ++position;\n      }\n      count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_char);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n      }\n      count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_short_set);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   typedef typename traits::char_class_type m_type;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate->next.p);\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n      }\n      count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_long_set);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()\n{\n   BOOST_REGEX_ASSERT(pstate->type == syntax_element_recurse);\n   //\n   // See if we've seen this recursion before at this location, if we have then\n   // we need to prevent infinite recursion:\n   //\n   for(typename std::vector<recursion_info<results_type> >::reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)\n   {\n      if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)\n      {\n         if(i->location_of_start == position)\n            return false;\n         break;\n      }\n   }\n   //\n   // Backup call stack:\n   //\n   push_recursion_pop();\n   //\n   // Set new call stack:\n   //\n   if(recursion_stack.capacity() == 0)\n   {\n      recursion_stack.reserve(50);\n   }\n   recursion_stack.push_back(recursion_info<results_type>());\n   recursion_stack.back().preturn_address = pstate->next.p;\n   recursion_stack.back().results = *m_presult;\n   pstate = static_cast<const re_jump*>(pstate)->alt.p;\n   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;\n   recursion_stack.back().location_of_start = position;\n   //if(static_cast<const re_recurse*>(pstate)->state_id > 0)\n   {\n      push_repeater_count(-(2 + static_cast<const re_brace*>(pstate)->index), &next_count);\n   }\n\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   if(index > 0)\n   {\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         m_presult->set_second(position, index);\n      }\n      if(!recursion_stack.empty())\n      {\n         if(index == recursion_stack.back().idx)\n         {\n            pstate = recursion_stack.back().preturn_address;\n            *m_presult = recursion_stack.back().results;\n            push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);\n            recursion_stack.pop_back();\n            push_repeater_count(-(2 + index), &next_count);\n         }\n      }\n   }\n   else if((index < 0) && (index != -4))\n   {\n      // matched forward lookahead:\n      pstate = 0;\n      return true;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_match()\n{\n   if(!recursion_stack.empty())\n   {\n      BOOST_REGEX_ASSERT(0 == recursion_stack.back().idx);\n      pstate = recursion_stack.back().preturn_address;\n      push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);\n      *m_presult = recursion_stack.back().results;\n      recursion_stack.pop_back();\n      return true;\n   }\n   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))\n      return false;\n   if((m_match_flags & match_all) && (position != last))\n      return false;\n   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))\n      return false;\n   m_presult->set_second(position);\n   pstate = 0;\n   m_has_found_match = true;\n   if((m_match_flags & match_posix) == match_posix)\n   {\n      m_result.maybe_assign(*m_presult);\n      if((m_match_flags & match_any) == 0)\n         return false;\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   if(match_extra & m_match_flags)\n   {\n      for(unsigned i = 0; i < m_presult->size(); ++i)\n         if((*m_presult)[i].matched)\n            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);\n   }\n#endif\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_commit()\n{\n   // Ideally we would just junk all the states that are on the stack,\n   // however we might not unwind correctly in that case, so for now,\n   // just mark that we don't backtrack into whatever is left (or rather\n   // we'll unwind it unconditionally without pausing to try other matches).\n\n   switch(static_cast<const re_commit*>(pstate)->action)\n   {\n   case commit_commit:\n      restart = last;\n      break;\n   case commit_skip:\n      if(base != position)\n      {\n         restart = position;\n         // Have to decrement restart since it will get incremented again later:\n         --restart;\n      }\n      break;\n   case commit_prune:\n      break;\n   }\n\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(16);\n   m_backup_state = pmp;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_then()\n{\n   // Just leave a mark that we need to skip to next alternative:\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(17);\n   m_backup_state = pmp;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool have_match)\n{\n   while(pstate)\n   {\n      if(pstate->type == syntax_element_endmark)\n      {\n         if(static_cast<const re_brace*>(pstate)->index == index)\n         {\n            if(have_match)\n               return this->match_endmark();\n            pstate = pstate->next.p;\n            return true;\n         }\n         else\n         {\n            // Unenclosed closing ), occurs when (*ACCEPT) is inside some other \n            // parenthesis which may or may not have other side effects associated with it.\n            const re_syntax_base* sp = pstate;\n            match_endmark();\n            if(!pstate)\n            {\n               unwind(true);\n               // unwind may leave pstate NULL if we've unwound a forward lookahead, in which\n               // case just move to the next state and keep looking...\n               if (!pstate)\n                  pstate = sp->next.p;\n            }\n         }\n         continue;\n      }\n      else if(pstate->type == syntax_element_match)\n         return true;\n      else if(pstate->type == syntax_element_startmark)\n      {\n         int idx = static_cast<const re_brace*>(pstate)->index;\n         pstate = pstate->next.p;\n         skip_until_paren(idx, false);\n         continue;\n      }\n      pstate = pstate->next.p;\n   }\n   return true;\n}\n\n/****************************************************************************\n\nUnwind and associated procedures follow, these perform what normal stack\nunwinding does in the recursive implementation.\n\n****************************************************************************/\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)\n{\n   static unwind_proc_type const s_unwind_table[19] = \n   {\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_commit,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_then,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_case,\n   };\n\n   m_recursive_result = have_match;\n   m_unwound_lookahead = false;\n   m_unwound_alt = false;\n   unwind_proc_type unwinder;\n   bool cont;\n   //\n   // keep unwinding our stack until we have something to do:\n   //\n   do\n   {\n      unwinder = s_unwind_table[m_backup_state->state_id];\n      cont = (this->*unwinder)(m_recursive_result);\n   }while(cont);\n   //\n   // return true if we have more states to try:\n   //\n   return pstate ? true : false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)\n{\n   pstate = 0;   // nothing left to search\n   return false; // end of stack nothing more to search\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_case(bool)\n{\n   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);\n   icase = pmp->icase;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)\n{\n   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n   // restore previous values if no match was found:\n   if(!have_match)\n   {\n      m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);\n      m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   //\n   // we have a match, push the capture information onto the stack:\n   //\n   else if(pmp->sub.matched && (match_extra & m_match_flags))\n      ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);\n#endif\n   // unwind stack:\n   m_backup_state = pmp+1;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)\n{\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   pstate = 0;   // nothing left to search\n   return false; // end of stack nothing more to search\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)\n{\n   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n   pstate = pmp->pstate;\n   position = pmp->position;\n   bool result = (r == pmp->positive);\n   m_recursive_result = pmp->positive ? r : !r;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   m_unwound_lookahead = true;\n   return !result; // return false if the assertion was matched to stop search.\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   if(!r)\n   {\n      pstate = pmp->pstate;\n      position = pmp->position;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   m_unwound_alt = !r;\n   return r; \n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)\n{\n   ++used_block_count;\n   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)\n{\n   saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);\n   void* condemmed = m_stack_base;\n   m_stack_base = pmp->base;\n   m_backup_state = pmp->end;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);\n   put_mem_block(condemmed);\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()\n{\n   saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(p++);\n   m_backup_state = p;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n\n   count -= rep->min;\n   \n   if((m_match_flags & match_partial) && (position == last))\n      m_has_partial_match = true;\n\n   BOOST_REGEX_ASSERT(count);\n   position = pmp->last_position;\n\n   // backtrack till we can skip out:\n   do\n   {\n      --position;\n      --count;\n      ++state_count;\n   }while(count && !can_start(*position, rep->_map, mask_skip));\n\n   // if we've hit base, destroy this state:\n   if(count == 0)\n   {\n         destroy_single_repeat();\n         if(!can_start(*position, rep->_map, mask_skip))\n            return true;\n   }\n   else\n   {\n      pmp->count = count + rep->min;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_dot_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_wild);\n\n   BOOST_REGEX_ASSERT(count < rep->max);\n   pstate = rep->next.p;\n   position = pmp->last_position;\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(!match_wild())\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n\n   BOOST_REGEX_ASSERT(count < rep->max);\n   position = pmp->last_position;\n   if(position != last)\n   {\n\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         ++position;\n         ++count;\n         ++state_count;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }\n\n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_char_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_literal);\n   BOOST_REGEX_ASSERT(count < rep->max);\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(traits_inst.translate(*position, icase) != what)\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++ position;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_short_set_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_set);\n   BOOST_REGEX_ASSERT(count < rep->max);\n   \n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++ position;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)\n{\n   typedef typename traits::char_class_type m_type;\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r)\n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate);\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_long_set_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);\n   BOOST_REGEX_ASSERT(count < rep->max);\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(position == re_is_set_member(position, last, set, re.get_data(), icase))\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++position;\n         ++count;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state:\n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   if(!r)\n   {\n      position = pmp->position;\n      pstate = pmp->pstate;\n      ++(*next_count);\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return r;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)\n{\n   // We are backtracking back inside a recursion, need to push the info\n   // back onto the recursion stack, and do so unconditionally, otherwise\n   // we can get mismatched pushes and pops...\n   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n   if (!r)\n   {\n      recursion_stack.push_back(recursion_info<results_type>());\n      recursion_stack.back().idx = pmp->recursion_id;\n      recursion_stack.back().preturn_address = pmp->preturn_address;\n      recursion_stack.back().results = pmp->prior_results;\n      recursion_stack.back().location_of_start = position;\n      *m_presult = pmp->internal_results;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)\n{\n   // Backtracking out of a recursion, we must pop state off the recursion\n   // stack unconditionally to ensure matched pushes and pops:\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   if (!r && !recursion_stack.empty())\n   {\n      *m_presult = recursion_stack.back().results;\n      position = recursion_stack.back().location_of_start;\n      recursion_stack.pop_back();\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()\n{\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_state*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_state(15);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_commit(bool b)\n{\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   while(unwind(b) && !m_unwound_lookahead){}\n   if(m_unwound_lookahead && pstate)\n   {\n      //\n      // If we stop because we just unwound an assertion, put the\n      // commit state back on the stack again:\n      //\n      m_unwound_lookahead = false;\n      saved_state* pmp = m_backup_state;\n      --pmp;\n      if(pmp < m_stack_base)\n      {\n         extend_stack();\n         pmp = m_backup_state;\n         --pmp;\n      }\n      (void) new (pmp)saved_state(16);\n      m_backup_state = pmp;\n   }\n   // This prevents us from stopping when we exit from an independent sub-expression:\n   m_independent = false;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_then(bool b)\n{\n   // Unwind everything till we hit an alternative:\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   bool result = false;\n   while((result = unwind(b)) && !m_unwound_alt){}\n   // We're now pointing at the next alternative, need one more backtrack \n   // since *all* the other alternatives must fail once we've reached a THEN clause:\n   if(result && m_unwound_alt)\n      unwind(b);\n   return false;\n}\n\n/*\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_pop(bool r)\n{\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   if(!r)\n   {\n      --parenthesis_stack_position;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_pop()\n{\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_state*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_state(16);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_push(bool r)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   if(!r)\n   {\n      parenthesis_stack[parenthesis_stack_position++] = pmp->position;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_push(BidiIterator p)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_position<BidiIterator>(0, p, 17);\n   m_backup_state = pmp;\n}\n*/\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/perl_matcher_recursive.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         perl_matcher_common.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Definitions of perl_matcher member functions that are \n  *                specific to the recursive implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP\n#define BOOST_REGEX_V4_PERL_MATCHER_RECURSIVE_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4800)\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class BidiIterator>\nclass backup_subex\n{\n   int index;\n   sub_match<BidiIterator> sub;\npublic:\n   template <class A>\n   backup_subex(const match_results<BidiIterator, A>& w, int i)\n      : index(i), sub(w[i], false) {}\n   template <class A>\n   void restore(match_results<BidiIterator, A>& w)\n   {\n      w.set_first(sub.first, index, index == 0);\n      w.set_second(sub.second, index, sub.matched, index == 0);\n   }\n   const sub_match<BidiIterator>& get() { return sub; }\n};\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()\n{\n   static matcher_proc_type const s_match_vtable[34] = \n   {\n      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_match,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,\n      // Although this next line *should* be evaluated at compile time, in practice\n      // some compilers (VC++) emit run-time initialisation which breaks thread\n      // safety, so use a dispatch function instead:\n      //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_fail,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_accept,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_commit,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_then,\n   };\n\n   if(state_count > max_state_count)\n      raise_error(traits_inst, regex_constants::error_complexity);\n   while(pstate)\n   {\n      matcher_proc_type proc = s_match_vtable[pstate->type];\n      ++state_count;\n      if(!(this->*proc)())\n      {\n         if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n            m_has_partial_match = true;\n         return 0;\n      }\n   }\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   bool r = true;\n   switch(index)\n   {\n   case 0:\n      pstate = pstate->next.p;\n      break;\n   case -1:\n   case -2:\n      {\n         // forward lookahead assert:\n         BidiIterator old_position(position);\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         r = match_all_states();\n         pstate = next_pstate;\n         position = old_position;\n         if((r && (index != -1)) || (!r && (index != -2)))\n            r = false;\n         else\n            r = true;\n         if(r && m_have_accept)\n            r = skip_until_paren(INT_MAX);\n         break;\n      }\n   case -3:\n      {\n         // independent sub-expression:\n         bool old_independent = m_independent;\n         m_independent = true;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         bool can_backtrack = m_can_backtrack;\n         r = match_all_states();\n         if(r)\n            m_can_backtrack = can_backtrack;\n         pstate = next_pstate;\n         m_independent = old_independent;\n#ifdef BOOST_REGEX_MATCH_EXTRA\n         if(r && (m_match_flags & match_extra))\n         {\n            //\n            // our captures have been stored in *m_presult\n            // we need to unpack them, and insert them\n            // back in the right order when we unwind the stack:\n            //\n            unsigned i;\n            match_results<BidiIterator, Allocator> tm(*m_presult);\n            for(i = 0; i < tm.size(); ++i)\n               (*m_presult)[i].get_captures().clear();\n            // match everything else:\n            r = match_all_states();\n            // now place the stored captures back:\n            for(i = 0; i < tm.size(); ++i)\n            {\n               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;\n               seq& s1 = (*m_presult)[i].get_captures();\n               const seq& s2 = tm[i].captures();\n               s1.insert(\n                  s1.end(), \n                  s2.begin(), \n                  s2.end());\n            }\n         }\n#endif\n         if(r && m_have_accept)\n            r = skip_until_paren(INT_MAX);\n         break;\n      }\n   case -4:\n      {\n      // conditional expression:\n      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);\n      BOOST_REGEX_ASSERT(alt->type == syntax_element_alt);\n      pstate = alt->next.p;\n      if(pstate->type == syntax_element_assert_backref)\n      {\n         if(!match_assert_backref())\n            pstate = alt->alt.p;\n         break;\n      }\n      else\n      {\n         // zero width assertion, have to match this recursively:\n         BOOST_REGEX_ASSERT(pstate->type == syntax_element_startmark);\n         bool negated = static_cast<const re_brace*>(pstate)->index == -2;\n         BidiIterator saved_position = position;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         bool res = match_all_states();\n         position = saved_position;\n         if(negated)\n            res = !res;\n         if(res)\n            pstate = next_pstate;\n         else\n            pstate = alt->alt.p;\n         break;\n      }\n      }\n   case -5:\n      {\n         // Reset start of $0, since we have a \\K escape\n         backup_subex<BidiIterator> sub(*m_presult, 0);\n         m_presult->set_first(position, 0, true);\n         pstate = pstate->next.p;\n         r = match_all_states();\n         if(r == false)\n            sub.restore(*m_presult);\n         break;\n      }\n   default:\n   {\n      BOOST_REGEX_ASSERT(index > 0);\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         backup_subex<BidiIterator> sub(*m_presult, index);\n         m_presult->set_first(position, index);\n         pstate = pstate->next.p;\n         r = match_all_states();\n         if(r == false)\n            sub.restore(*m_presult);\n#ifdef BOOST_REGEX_MATCH_EXTRA\n         //\n         // we have a match, push the capture information onto the stack:\n         //\n         else if(sub.get().matched && (match_extra & m_match_flags))\n            ((*m_presult)[index]).get_captures().push_back(sub.get());\n#endif\n      }\n      else\n      {\n         pstate = pstate->next.p;\n      }\n      break;\n   }\n   }\n   return r;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_alt()\n{\n   bool take_first, take_second;\n   const re_alt* jmp = static_cast<const re_alt*>(pstate);\n\n   // find out which of these two alternatives we need to take:\n   if(position == last)\n   {\n      take_first = jmp->can_be_null & mask_take;\n      take_second = jmp->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);\n  }\n\n   if(take_first)\n   {\n      // we can take the first alternative,\n      // see if we need to push next alternative:\n      if(take_second)\n      {\n         BidiIterator oldposition(position);\n         const re_syntax_base* old_pstate = jmp->alt.p;\n         pstate = pstate->next.p;\n         bool oldcase = icase;\n         m_have_then = false;\n         if(!match_all_states())\n         {\n            pstate = old_pstate;\n            position = oldposition;\n            icase = oldcase;\n            if(m_have_then)\n            {\n               m_can_backtrack = true;\n               m_have_then = false;\n               return false;\n            }\n         }\n         m_have_then = false;\n         return m_can_backtrack;\n      }\n      pstate = pstate->next.p;\n      return true;\n   }\n   if(take_second)\n   {\n      pstate = jmp->alt.p;\n      return true;\n   }\n   return false;  // neither option is possible\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_rep()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127 4244)\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   //\n   // Always copy the repeat count, so that the state is restored\n   // when we exit this scope:\n   //\n   repeater_count<BidiIterator> r(rep->state_id, &next_count, position, this->recursion_stack.size() ? this->recursion_stack.back().idx : INT_MIN + 3);\n   //\n   // If we've had at least one repeat already, and the last one \n   // matched the NULL string then set the repeat count to\n   // maximum:\n   //\n   next_count->check_null_repeat(position, rep->max);\n\n   // find out which of these two alternatives we need to take:\n   bool take_first, take_second;\n   if(position == last)\n   {\n      take_first = rep->can_be_null & mask_take;\n      take_second = rep->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);\n   }\n\n   if(next_count->get_count() < rep->min)\n   {\n      // we must take the repeat:\n      if(take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return match_all_states();\n      }\n      return false;\n   }\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // try and take the repeat if we can:\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         // store position in case we fail:\n         BidiIterator pos = position;\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         if(match_all_states())\n            return true;\n         if(!m_can_backtrack)\n            return false;\n         // failed repeat, reset posistion and fall through for alternative:\n         position = pos;\n      }\n      if(take_second)\n      {\n         pstate = rep->alt.p;\n         return true;\n      }\n      return false; // can't take anything, fail...\n   }\n   else // non-greedy\n   {\n      // try and skip the repeat if we can:\n      if(take_second)\n      {\n         // store position in case we fail:\n         BidiIterator pos = position;\n         pstate = rep->alt.p;\n         if(match_all_states())\n            return true;\n         if(!m_can_backtrack)\n            return false;\n         // failed alternative, reset posistion and fall through for repeat:\n         position = pos;\n      }\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return match_all_states();\n      }\n   }\n   return false;\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   std::size_t count = 0;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   re_syntax_base* psingle = rep->next.p;\n   // match compulsary repeats first:\n   while(count < rep->min)\n   {\n      pstate = psingle;\n      if(!match_wild())\n         return false;\n      ++count;\n   }\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // normal repeat:\n      while(count < rep->max)\n      {\n         pstate = psingle;\n         if(!match_wild())\n            break;\n         ++count;\n      }\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      pstate = rep;\n      return backtrack_till_match(count - rep->min);\n   }\n   else\n   {\n      // non-greedy, keep trying till we get a match:\n      BidiIterator save_pos;\n      do\n      {\n         if((rep->leading) && (rep->max == UINT_MAX))\n            restart = position;\n         pstate = rep->alt.p;\n         save_pos = position;\n         ++state_count;\n         if(match_all_states())\n            return true;\n         if((count >= rep->max) || !m_can_backtrack)\n            return false;\n         ++count;\n         pstate = psingle;\n         position = save_pos;\n         if(!match_wild())\n            return false;\n      }while(true);\n   }\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   if(m_match_flags & match_not_dot_null)\n      return match_dot_repeat_slow();\n   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)\n      return match_dot_repeat_slow();\n   //\n   // start by working out how much we can skip:\n   //\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4267)\n#endif\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t count = (std::min)(static_cast<std::size_t>(::boost::BOOST_REGEX_DETAIL_NS::distance(position, last)), greedy ? rep->max : rep->min);\n   if(rep->min > count)\n   {\n      position = last;\n      return false;  // not enough text left to match\n   }\n   std::advance(position, count);\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n   if((rep->leading) && (count < rep->max) && greedy)\n      restart = position;\n   if(greedy)\n      return backtrack_till_match(count - rep->min);\n\n   // non-greedy, keep trying till we get a match:\n   BidiIterator save_pos;\n   do\n   {\n      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))\n      {\n         ++position;\n         ++count;\n      }\n      if((rep->leading) && (rep->max == UINT_MAX))\n         restart = position;\n      pstate = rep->alt.p;\n      save_pos = position;\n      ++state_count;\n      if(match_all_states())\n         return true;\n      if((count >= rep->max) || !m_can_backtrack)\n         return false;\n      if(save_pos == last)\n         return false;\n      position = ++save_pos;\n      ++count;\n   }while(true);\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#pragma warning(disable:4267)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   BOOST_REGEX_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);\n   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t count, desired;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      desired = \n         (std::min)(\n            (std::size_t)(greedy ? rep->max : rep->min),\n            (std::size_t)::boost::BOOST_REGEX_DETAIL_NS::distance(position, last));\n      count = desired;\n      ++desired;\n      if(icase)\n      {\n         while(--desired && (traits_inst.translate_nocase(*position) == what))\n         {\n            ++position;\n         }\n      }\n      else\n      {\n         while(--desired && (traits_inst.translate(*position) == what))\n         {\n            ++position;\n         }\n      }\n      count = count - desired;\n   }\n   else\n   {\n      count = 0;\n      desired = greedy ? rep->max : rep->min;\n      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))\n      {\n         ++position;\n         ++count;\n      }\n   }\n   if((rep->leading) && (count < rep->max) && greedy)\n      restart = position;\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n      return backtrack_till_match(count - rep->min);\n\n   // non-greedy, keep trying till we get a match:\n   BidiIterator save_pos;\n   do\n   {\n      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))\n      {\n         if((traits_inst.translate(*position, icase) == what))\n         {\n            ++position;\n            ++count;\n         }\n         else\n            return false;  // counldn't repeat even though it was the only option\n      }\n      if((rep->leading) && (rep->max == UINT_MAX))\n         restart = position;\n      pstate = rep->alt.p;\n      save_pos = position;\n      ++state_count;\n      if(match_all_states())\n         return true;\n      if((count >= rep->max) || !m_can_backtrack)\n         return false;\n      position = save_pos;\n      if(position == last)\n         return false;\n      if(traits_inst.translate(*position, icase) == what)\n      {\n         ++position;\n         ++count;\n      }\n      else\n      {\n         return false;\n      }\n   }while(true);\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n      }\n      count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n         ++count;\n      }\n   }\n   if((rep->leading) && (count < rep->max) && greedy)\n      restart = position;\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n      return backtrack_till_match(count - rep->min);\n\n   // non-greedy, keep trying till we get a match:\n   BidiIterator save_pos;\n   do\n   {\n      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))\n      {\n         if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n         {\n            ++position;\n            ++count;\n         }\n         else\n            return false;  // counldn't repeat even though it was the only option\n      }\n      if((rep->leading) && (rep->max == UINT_MAX))\n         restart = position;\n      pstate = rep->alt.p;\n      save_pos = position;\n      ++state_count;\n      if(match_all_states())\n         return true;\n      if((count >= rep->max) || !m_can_backtrack)\n         return false;\n      position = save_pos;\n      if(position == last)\n         return false;\n      if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n         ++count;\n      }\n      else\n      {\n         return false;\n      }\n   }while(true);\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   typedef typename traits::char_class_type char_class_type;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const re_set_long<char_class_type>* set = static_cast<const re_set_long<char_class_type>*>(pstate->next.p);\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : ::boost::BOOST_REGEX_DETAIL_NS::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n      }\n      count = (unsigned)::boost::BOOST_REGEX_DETAIL_NS::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n         ++count;\n      }\n   }\n   if((rep->leading) && (count < rep->max) && greedy)\n      restart = position;\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n      return backtrack_till_match(count - rep->min);\n\n   // non-greedy, keep trying till we get a match:\n   BidiIterator save_pos;\n   do\n   {\n      while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))\n      {\n         if(position != re_is_set_member(position, last, set, re.get_data(), icase))\n         {\n            ++position;\n            ++count;\n         }\n         else\n            return false;  // counldn't repeat even though it was the only option\n      }\n      if((rep->leading) && (rep->max == UINT_MAX))\n         restart = position;\n      pstate = rep->alt.p;\n      save_pos = position;\n      ++state_count;\n      if(match_all_states())\n         return true;\n      if((count >= rep->max) || !m_can_backtrack)\n         return false;\n      position = save_pos;\n      if(position == last)\n         return false;\n      if(position != re_is_set_member(position, last, set, re.get_data(), icase))\n      {\n         ++position;\n         ++count;\n      }\n      else\n      {\n         return false;\n      }\n   }while(true);\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::backtrack_till_match(std::size_t count)\n{\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   if(!m_can_backtrack)\n      return false;\n   if((m_match_flags & match_partial) && (position == last))\n      m_has_partial_match = true;\n\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   BidiIterator backtrack = position;\n   if(position == last)\n   {\n      if(rep->can_be_null & mask_skip) \n      {\n         pstate = rep->alt.p;\n         if(match_all_states())\n            return true;\n      }\n      if(count)\n      {\n         position = --backtrack;\n         --count;\n      }\n      else\n         return false;\n   }\n   do\n   {\n      while(count && !can_start(*position, rep->_map, mask_skip))\n      {\n         --position;\n         --count;\n         ++state_count;\n      }\n      pstate = rep->alt.p;\n      backtrack = position;\n      if(match_all_states())\n         return true;\n      if(count == 0)\n         return false;\n      position = --backtrack;\n      ++state_count;\n      --count;\n   }while(true);\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()\n{\n   BOOST_REGEX_ASSERT(pstate->type == syntax_element_recurse);\n   //\n   // Set new call stack:\n   //\n   if(recursion_stack.capacity() == 0)\n   {\n      recursion_stack.reserve(50);\n   }\n   //\n   // See if we've seen this recursion before at this location, if we have then\n   // we need to prevent infinite recursion:\n   //\n   for(typename std::vector<recursion_info<results_type> >::reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)\n   {\n      if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)\n      {\n         if(i->location_of_start == position)\n            return false;\n         break;\n      }\n   }\n   //\n   // Now get on with it:\n   //\n   recursion_stack.push_back(recursion_info<results_type>());\n   recursion_stack.back().preturn_address = pstate->next.p;\n   recursion_stack.back().results = *m_presult;\n   recursion_stack.back().repeater_stack = next_count;\n   recursion_stack.back().location_of_start = position;\n   pstate = static_cast<const re_jump*>(pstate)->alt.p;\n   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;\n\n   repeater_count<BidiIterator>* saved = next_count;\n   repeater_count<BidiIterator> r(&next_count); // resets all repeat counts since we're recursing and starting fresh on those\n   next_count = &r;\n   bool can_backtrack = m_can_backtrack;\n   bool result = match_all_states();\n   m_can_backtrack = can_backtrack;\n   next_count = saved;\n\n   if(!result)\n   {\n      next_count = recursion_stack.back().repeater_stack;\n      *m_presult = recursion_stack.back().results;\n      recursion_stack.pop_back();\n      return false;\n   }\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   if(index > 0)\n   {\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         m_presult->set_second(position, index);\n      }\n      if(!recursion_stack.empty())\n      {\n         if(index == recursion_stack.back().idx)\n         {\n            recursion_info<results_type> saved = recursion_stack.back();\n            recursion_stack.pop_back();\n            pstate = saved.preturn_address;\n            repeater_count<BidiIterator>* saved_count = next_count;\n            next_count = saved.repeater_stack;\n            *m_presult = saved.results;\n            if(!match_all_states())\n            {\n               recursion_stack.push_back(saved);\n               next_count = saved_count;\n               return false;\n            }\n         }\n      }\n   }\n   else if((index < 0) && (index != -4))\n   {\n      // matched forward lookahead:\n      pstate = 0;\n      return true;\n   }\n   pstate = pstate ? pstate->next.p : 0;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_match()\n{\n   if(!recursion_stack.empty())\n   {\n      BOOST_REGEX_ASSERT(0 == recursion_stack.back().idx);\n      const re_syntax_base* saved_state = pstate = recursion_stack.back().preturn_address;\n      *m_presult = recursion_stack.back().results;\n      recursion_stack.pop_back();\n      if(!match_all_states())\n      {\n         recursion_stack.push_back(recursion_info<results_type>());\n         recursion_stack.back().preturn_address = saved_state;\n         recursion_stack.back().results = *m_presult;\n         recursion_stack.back().location_of_start = position;\n         return false;\n      }\n      return true;\n   }\n   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))\n      return false;\n   if((m_match_flags & match_all) && (position != last))\n      return false;\n   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))\n      return false;\n   m_presult->set_second(position);\n   pstate = 0;\n   m_has_found_match = true;\n   if((m_match_flags & match_posix) == match_posix)\n   {\n      m_result.maybe_assign(*m_presult);\n      if((m_match_flags & match_any) == 0)\n         return false;\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   if(match_extra & m_match_flags)\n   {\n      for(unsigned i = 0; i < m_presult->size(); ++i)\n         if((*m_presult)[i].matched)\n            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);\n   }\n#endif\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_commit()\n{\n   m_can_backtrack = false;\n   int action = static_cast<const re_commit*>(pstate)->action;\n   switch(action)\n   {\n   case commit_commit:\n      restart = last;\n      break;\n   case commit_skip:\n      restart = position;\n      break;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_then()\n{\n   pstate = pstate->next.p;\n   if(match_all_states())\n      return true;\n   m_can_backtrack = false;\n   m_have_then = true;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()\n{\n   // change our case sensitivity:\n   bool oldcase = this->icase;\n   this->icase = static_cast<const re_case*>(pstate)->icase;\n   pstate = pstate->next.p;\n   bool result = match_all_states();\n   this->icase = oldcase;\n   return result;\n}\n\n\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool have_match)\n{\n   while(pstate)\n   {\n      if(pstate->type == syntax_element_endmark)\n      {\n         if(static_cast<const re_brace*>(pstate)->index == index)\n         {\n            if(have_match)\n               return this->match_endmark();\n            pstate = pstate->next.p;\n            return true;\n         }\n         else\n         {\n            // Unenclosed closing ), occurs when (*ACCEPT) is inside some other \n            // parenthesis which may or may not have other side effects associated with it.\n            bool r = match_endmark();\n            m_have_accept = true;\n            if(!pstate)\n               return r;\n         }\n         continue;\n      }\n      else if(pstate->type == syntax_element_match)\n         return true;\n      else if(pstate->type == syntax_element_startmark)\n      {\n         int idx = static_cast<const re_brace*>(pstate)->index;\n         pstate = pstate->next.p;\n         skip_until_paren(idx, false);\n         continue;\n      }\n      pstate = pstate->next.p;\n   }\n   return true;\n}\n\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/primary_transform.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE:        primary_transform.hpp\n  *   VERSION:     see <boost/version.hpp>\n  *   DESCRIPTION: Heuristically determines the sort string format in use\n  *                by the current locale.\n  */\n\n#ifndef BOOST_REGEX_PRIMARY_TRANSFORM\n#define BOOST_REGEX_PRIMARY_TRANSFORM\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n   namespace BOOST_REGEX_DETAIL_NS{\n\n\nenum{\n   sort_C,\n   sort_fixed,\n   sort_delim,\n   sort_unknown\n};\n\ntemplate <class S, class charT>\nunsigned count_chars(const S& s, charT c)\n{\n   //\n   // Count how many occurrences of character c occur\n   // in string s: if c is a delimeter between collation\n   // fields, then this should be the same value for all\n   // sort keys:\n   //\n   unsigned int count = 0;\n   for(unsigned pos = 0; pos < s.size(); ++pos)\n   {\n      if(s[pos] == c) ++count;\n   }\n   return count;\n}\n\n\ntemplate <class traits, class charT>\nunsigned find_sort_syntax(const traits* pt, charT* delim)\n{\n   //\n   // compare 'a' with 'A' to see how similar they are,\n   // should really use a-accute but we can't portably do that,\n   //\n   typedef typename traits::string_type string_type;\n   typedef typename traits::char_type char_type;\n\n   // Suppress incorrect warning for MSVC\n   (void)pt;\n\n   char_type a[2] = {'a', '\\0', };\n   string_type sa(pt->transform(a, a+1));\n   if(sa == a)\n   {\n      *delim = 0;\n      return sort_C;\n   }\n   char_type A[2] = { 'A', '\\0', };\n   string_type sA(pt->transform(A, A+1));\n   char_type c[2] = { ';', '\\0', };\n   string_type sc(pt->transform(c, c+1));\n\n   int pos = 0;\n   while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;\n   --pos;\n   if(pos < 0)\n   {\n      *delim = 0;\n      return sort_unknown;\n   }\n   //\n   // at this point sa[pos] is either the end of a fixed width field\n   // or the character that acts as a delimiter:\n   //\n   charT maybe_delim = sa[pos];\n   if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))\n   {\n      *delim = maybe_delim;\n      return sort_delim;\n   }\n   //\n   // OK doen't look like a delimiter, try for fixed width field:\n   //\n   if((sa.size() == sA.size()) && (sa.size() == sc.size()))\n   {\n      // note assumes that the fixed width field is less than\n      // (numeric_limits<charT>::max)(), should be true for all types\n      // I can't imagine 127 character fields...\n      *delim = static_cast<charT>(++pos);\n      return sort_fixed;\n   }\n   //\n   // don't know what it is:\n   //\n   *delim = 0;\n   return sort_unknown;\n}\n\n\n   } // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/protected_call.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_creator.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_creator which fills in\n  *                the data members of a regex_data object.\n  */\n\n#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP\n#define BOOST_REGEX_V4_PROTECTED_CALL_HPP\n\n#include <boost/config.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\nclass BOOST_REGEX_DECL abstract_protected_call\n{\npublic:\n   bool BOOST_REGEX_CALL execute()const;\n   // this stops gcc-4 from complaining:\n   virtual ~abstract_protected_call(){}\nprivate:\n   virtual bool call()const = 0;\n};\n\ntemplate <class T>\nclass concrete_protected_call\n   : public abstract_protected_call\n{\npublic:\n   typedef bool (T::*proc_type)();\n   concrete_protected_call(T* o, proc_type p)\n      : obj(o), proc(p) {}\nprivate:\n   bool call()const BOOST_OVERRIDE;\n   T* obj;\n   proc_type proc;\n};\n\ntemplate <class T>\nbool concrete_protected_call<T>::call()const\n{\n   return (obj->*proc)();\n}\n\n}\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regbase.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regbase.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares class regbase.\n  */\n\n#ifndef BOOST_REGEX_V4_REGBASE_HPP\n#define BOOST_REGEX_V4_REGBASE_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n//\n// class regbase\n// handles error codes and flags\n//\nclass BOOST_REGEX_DECL regbase\n{\npublic:\n   enum flag_type_\n   {\n      //\n      // Divide the flags up into logical groups:\n      // bits 0-7 indicate main synatx type.\n      // bits 8-15 indicate syntax subtype.\n      // bits 16-31 indicate options that are common to all\n      // regex syntaxes.\n      // In all cases the default is 0.\n      //\n      // Main synatx group:\n      //\n      perl_syntax_group = 0,                      // default\n      basic_syntax_group = 1,                     // POSIX basic\n      literal = 2,                                // all characters are literals\n      main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!\n      //\n      // options specific to perl group:\n      //\n      no_bk_refs = 1 << 8,                        // \\d not allowed\n      no_perl_ex = 1 << 9,                        // disable perl extensions\n      no_mod_m = 1 << 10,                         // disable Perl m modifier\n      mod_x = 1 << 11,                            // Perl x modifier\n      mod_s = 1 << 12,                            // force s modifier on (overrides match_not_dot_newline)\n      no_mod_s = 1 << 13,                         // force s modifier off (overrides match_not_dot_newline)\n\n      //\n      // options specific to basic group:\n      //\n      no_char_classes = 1 << 8,                   // [[:CLASS:]] not allowed\n      no_intervals = 1 << 9,                      // {x,y} not allowed\n      bk_plus_qm = 1 << 10,                       // uses \\+ and \\?\n      bk_vbar = 1 << 11,                          // use \\| for alternatives\n      emacs_ex = 1 << 12,                         // enables emacs extensions\n\n      //\n      // options common to all groups:\n      //\n      no_escape_in_lists = 1 << 16,                     // '\\' not special inside [...]\n      newline_alt = 1 << 17,                            // \\n is the same as |\n      no_except = 1 << 18,                              // no exception on error\n      failbit = 1 << 19,                                // error flag\n      icase = 1 << 20,                                  // characters are matched regardless of case\n      nocollate = 0,                                    // don't use locale specific collation (deprecated)\n      collate = 1 << 21,                                // use locale specific collation\n      nosubs = 1 << 22,                                 // don't mark sub-expressions\n      save_subexpression_location = 1 << 23,            // save subexpression locations\n      no_empty_expressions = 1 << 24,                   // no empty expressions allowed\n      optimize = 0,                                     // not really supported\n      \n\n\n      basic = basic_syntax_group | collate | no_escape_in_lists,\n      extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,\n      normal = 0,\n      emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,\n      awk = no_bk_refs | collate | no_perl_ex,\n      grep = basic | newline_alt,\n      egrep = extended | newline_alt,\n      sed = basic,\n      perl = normal,\n      ECMAScript = normal,\n      JavaScript = normal,\n      JScript = normal\n   };\n   typedef unsigned int flag_type;\n\n   enum restart_info\n   {\n      restart_any = 0,\n      restart_word = 1,\n      restart_line = 2,\n      restart_buf = 3,\n      restart_continue = 4,\n      restart_lit = 5,\n      restart_fixed_lit = 6, \n      restart_count = 7\n   };\n};\n\n//\n// provide std lib proposal compatible constants:\n//\nnamespace regex_constants{\n\n   enum flag_type_\n   {\n\n      no_except = ::boost::regbase::no_except,\n      failbit = ::boost::regbase::failbit,\n      literal = ::boost::regbase::literal,\n      icase = ::boost::regbase::icase,\n      nocollate = ::boost::regbase::nocollate,\n      collate = ::boost::regbase::collate,\n      nosubs = ::boost::regbase::nosubs,\n      optimize = ::boost::regbase::optimize,\n      bk_plus_qm = ::boost::regbase::bk_plus_qm,\n      bk_vbar = ::boost::regbase::bk_vbar,\n      no_intervals = ::boost::regbase::no_intervals,\n      no_char_classes = ::boost::regbase::no_char_classes,\n      no_escape_in_lists = ::boost::regbase::no_escape_in_lists,\n      no_mod_m = ::boost::regbase::no_mod_m,\n      mod_x = ::boost::regbase::mod_x,\n      mod_s = ::boost::regbase::mod_s,\n      no_mod_s = ::boost::regbase::no_mod_s,\n      save_subexpression_location = ::boost::regbase::save_subexpression_location,\n      no_empty_expressions = ::boost::regbase::no_empty_expressions,\n\n      basic = ::boost::regbase::basic,\n      extended = ::boost::regbase::extended,\n      normal = ::boost::regbase::normal,\n      emacs = ::boost::regbase::emacs,\n      awk = ::boost::regbase::awk,\n      grep = ::boost::regbase::grep,\n      egrep = ::boost::regbase::egrep,\n      sed = basic,\n      perl = normal,\n      ECMAScript = normal,\n      JavaScript = normal,\n      JScript = normal\n   };\n   typedef ::boost::regbase::flag_type syntax_option_type;\n\n} // namespace regex_constants\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares boost::basic_regex<> and associated\n  *                functions and classes. This header is the main\n  *                entry point for the template regex code.\n  */\n\n#ifndef BOOST_RE_REGEX_HPP_INCLUDED\n#define BOOST_RE_REGEX_HPP_INCLUDED\n\n#ifdef __cplusplus\n\n// what follows is all C++ don't include in C builds!!\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n#ifndef BOOST_REGEX_WORKAROUND_HPP\n#include <boost/regex/v4/regex_workaround.hpp>\n#endif\n\n#ifndef BOOST_REGEX_FWD_HPP\n#include <boost/regex_fwd.hpp>\n#endif\n#ifndef BOOST_REGEX_TRAITS_HPP\n#include <boost/regex/regex_traits.hpp>\n#endif\n#ifndef BOOST_REGEX_RAW_BUFFER_HPP\n#include <boost/regex/v4/error_type.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_MATCH_FLAGS\n#include <boost/regex/v4/match_flags.hpp>\n#endif\n#ifndef BOOST_REGEX_RAW_BUFFER_HPP\n#include <boost/regex/v4/regex_raw_buffer.hpp>\n#endif\n#ifndef BOOST_RE_PAT_EXCEPT_HPP\n#include <boost/regex/pattern_except.hpp>\n#endif\n\n#ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP\n#include <boost/regex/v4/char_regex_traits.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_STATES_HPP\n#include <boost/regex/v4/states.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_REGBASE_HPP\n#include <boost/regex/v4/regbase.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP\n#include <boost/regex/v4/iterator_traits.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP\n#include <boost/regex/v4/basic_regex.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP\n#include <boost/regex/v4/basic_regex_creator.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP\n#include <boost/regex/v4/basic_regex_parser.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_SUB_MATCH_HPP\n#include <boost/regex/v4/sub_match.hpp>\n#endif\n#ifndef BOOST_REGEX_FORMAT_HPP\n#include <boost/regex/v4/regex_format.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP\n#include <boost/regex/v4/match_results.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP\n#include <boost/regex/v4/protected_call.hpp>\n#endif\n#ifndef BOOST_REGEX_MATCHER_HPP\n#include <boost/regex/v4/perl_matcher.hpp>\n#endif\n\n\nnamespace boost{\n#ifdef BOOST_REGEX_NO_FWD\ntypedef basic_regex<char, regex_traits<char> > regex;\n#ifndef BOOST_NO_WREGEX\ntypedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;\n#endif\n#endif\n\ntypedef match_results<const char*> cmatch;\ntypedef match_results<std::string::const_iterator> smatch;\n#ifndef BOOST_NO_WREGEX\ntypedef match_results<const wchar_t*> wcmatch;\ntypedef match_results<std::wstring::const_iterator> wsmatch;\n#endif\n\n} // namespace boost\n#ifndef BOOST_REGEX_MATCH_HPP\n#include <boost/regex/v4/regex_match.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_REGEX_SEARCH_HPP\n#include <boost/regex/v4/regex_search.hpp>\n#endif\n#ifndef BOOST_REGEX_ITERATOR_HPP\n#include <boost/regex/v4/regex_iterator.hpp>\n#endif\n#ifndef BOOST_REGEX_TOKEN_ITERATOR_HPP\n#include <boost/regex/v4/regex_token_iterator.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_REGEX_GREP_HPP\n#include <boost/regex/v4/regex_grep.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_REGEX_REPLACE_HPP\n#include <boost/regex/v4/regex_replace.hpp>\n#endif\n#ifndef BOOST_REGEX_V4_REGEX_MERGE_HPP\n#include <boost/regex/v4/regex_merge.hpp>\n#endif\n#ifndef BOOST_REGEX_SPLIT_HPP\n#include <boost/regex/v4/regex_split.hpp>\n#endif\n\n#endif  // __cplusplus\n\n#endif  // include\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_format.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009 John Maddock\n * Copyright 2008 Eric Niebler. \n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_FORMAT_HPP\n#define BOOST_REGEX_FORMAT_HPP\n\n#include <boost/type_traits/is_pointer.hpp>\n#include <boost/type_traits/is_function.hpp>\n#include <boost/type_traits/is_class.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include <boost/type_traits/is_convertible.hpp>\n#include <boost/type_traits/remove_pointer.hpp>\n#include <boost/type_traits/remove_cv.hpp>\n#include <boost/mpl/if.hpp>\n#include <boost/mpl/and.hpp>\n#include <boost/mpl/not.hpp>\n#ifndef BOOST_NO_SFINAE\n#include <boost/mpl/has_xxx.hpp>\n#endif\n#include <boost/ref.hpp>\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n//\n// Forward declaration:\n//\n   template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >\nclass match_results;\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// struct trivial_format_traits:\n// defines minimum localisation support for formatting\n// in the case that the actual regex traits is unavailable.\n//\ntemplate <class charT>\nstruct trivial_format_traits\n{\n   typedef charT char_type;\n\n   static std::ptrdiff_t length(const charT* p)\n   {\n      return global_length(p);\n   }\n   static charT tolower(charT c)\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);\n   }\n   static charT toupper(charT c)\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);\n   }\n   static int value(const charT c, int radix)\n   {\n      int result = global_value(c);\n      return result >= radix ? -1 : result;\n   }\n   int toi(const charT*& p1, const charT* p2, int radix)const\n   {\n      return (int)global_toi(p1, p2, radix, *this);\n   }\n};\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#pragma warning(disable:26812)\n#endif\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nclass basic_regex_formatter\n{\npublic:\n   typedef typename traits::char_type char_type;\n   basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)\n      : m_traits(t), m_results(r), m_out(o), m_position(), m_end(), m_flags(), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}\n   OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);\n   OutputIterator format(ForwardIter p1, match_flag_type f)\n   {\n      return format(p1, p1 + m_traits.length(p1), f);\n   }\nprivate:\n   typedef typename Results::value_type sub_match_type;\n   enum output_state\n   {\n      output_copy,\n      output_next_lower,\n      output_next_upper,\n      output_lower,\n      output_upper,\n      output_none\n   };\n\n   void put(char_type c);\n   void put(const sub_match_type& sub);\n   void format_all();\n   void format_perl();\n   void format_escape();\n   void format_conditional();\n   void format_until_scope_end();\n   bool handle_perl_verb(bool have_brace);\n\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::false_&)\n   {\n      std::vector<char_type> v(i, j);\n      return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())\n         : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));\n   }\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::true_&)\n   {\n      return this->m_results.named_subexpression(i, j);\n   }\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)\n   {\n      typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;\n      return get_named_sub(i, j, tag_type());\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::false_&)\n   {\n      std::vector<char_type> v(i, j);\n      return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())\n         : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::true_&)\n   {\n      return this->m_results.named_subexpression_index(i, j);\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j)\n   {\n      typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;\n      return get_named_sub_index(i, j, tag_type());\n   }\n#ifdef BOOST_MSVC\n   // msvc-8.0 issues a spurious warning on the call to std::advance here:\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n   inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::false_&)\n   {\n      if(i != j)\n      {\n         std::vector<char_type> v(i, j);\n         const char_type* start = &v[0];\n         const char_type* pos = start;\n         int r = (int)m_traits.toi(pos, &v[0] + v.size(), base);\n         std::advance(i, pos - start);\n         return r;\n      }\n      return -1;\n   }\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n   inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::true_&)\n   {\n      return m_traits.toi(i, j, base);\n   }\n   inline int toi(ForwardIter& i, ForwardIter j, int base)\n   {\n#if defined(_MSC_VER) && defined(__INTEL_COMPILER) && ((__INTEL_COMPILER == 9999) || (__INTEL_COMPILER == 1210))\n      // Workaround for Intel support issue #656654.\n      // See also https://svn.boost.org/trac/boost/ticket/6359\n      return toi(i, j, base, mpl::false_());\n#else\n      typedef typename boost::is_convertible<ForwardIter, const char_type*&>::type tag_type;\n      return toi(i, j, base, tag_type());\n#endif\n   }\n\n   const traits&    m_traits;       // the traits class for localised formatting operations\n   const Results&   m_results;     // the match_results being used.\n   OutputIterator   m_out;         // where to send output.\n   ForwardIter      m_position;  // format string, current position\n   ForwardIter      m_end;       // format string end\n   match_flag_type  m_flags;      // format flags to use\n   output_state     m_state;      // what to do with the next character\n   output_state     m_restore_state;  // what state to restore to.\n   bool             m_have_conditional; // we are parsing a conditional\nprivate:\n   basic_regex_formatter(const basic_regex_formatter&);\n   basic_regex_formatter& operator=(const basic_regex_formatter&);\n};\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nOutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)\n{\n   m_position = p1;\n   m_end = p2;\n   m_flags = f;\n   format_all();\n   return m_out;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()\n{\n   // over and over:\n   while(m_position != m_end)\n   {\n      switch(*m_position)\n      {\n      case '&':\n         if(m_flags & ::boost::regex_constants::format_sed)\n         {\n            ++m_position;\n            put(m_results[0]);\n            break;\n         }\n         put(*m_position++);\n         break;\n      case '\\\\':\n         format_escape();\n         break;\n      case '(':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            ++m_position;\n            bool have_conditional = m_have_conditional;\n            m_have_conditional = false;\n            format_until_scope_end();\n            m_have_conditional = have_conditional;\n            if(m_position == m_end)\n               return;\n            BOOST_REGEX_ASSERT(*m_position == static_cast<char_type>(')'));\n            ++m_position;  // skip the closing ')'\n            break;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case ')':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            return;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case ':':\n         if((m_flags & boost::regex_constants::format_all) && m_have_conditional)\n         {\n            return;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case '?':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            ++m_position;\n            format_conditional();\n            break;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case '$':\n         if((m_flags & format_sed) == 0)\n         {\n            format_perl();\n            break;\n         }\n         // not a special character:\n         BOOST_FALLTHROUGH;\n      default:\n         put(*m_position);\n         ++m_position;\n         break;\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()\n{\n   //\n   // On entry *m_position points to a '$' character\n   // output the information that goes with it:\n   //\n   BOOST_REGEX_ASSERT(*m_position == '$');\n   //\n   // see if this is a trailing '$':\n   //\n   if(++m_position == m_end)\n   {\n      --m_position;\n      put(*m_position);\n      ++m_position;\n      return;\n   }\n   //\n   // OK find out what kind it is:\n   //\n   bool have_brace = false;\n   ForwardIter save_position = m_position;\n   switch(*m_position)\n   {\n   case '&':\n      ++m_position;\n      put(this->m_results[0]);\n      break;\n   case '`':\n      ++m_position;\n      put(this->m_results.prefix());\n      break;\n   case '\\'':\n      ++m_position;\n      put(this->m_results.suffix());\n      break;\n   case '$':\n      put(*m_position++);\n      break;\n   case '+':\n      if((++m_position != m_end) && (*m_position == '{'))\n      {\n         ForwardIter base = ++m_position;\n         while((m_position != m_end) && (*m_position != '}')) ++m_position;\n         if(m_position != m_end)\n         {\n            // Named sub-expression:\n            put(get_named_sub(base, m_position));\n            ++m_position;\n            break;\n         }\n         else\n         {\n            m_position = --base;\n         }\n      }\n      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);\n      break;\n   case '{':\n      have_brace = true;\n      ++m_position;\n      BOOST_FALLTHROUGH;\n   default:\n      // see if we have a number:\n      {\n         std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);\n         //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n         int v = this->toi(m_position, m_position + len, 10);\n         if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))\n         {\n            // Look for a Perl-5.10 verb:\n            if(!handle_perl_verb(have_brace))\n            {\n               // leave the $ as is, and carry on:\n               m_position = --save_position;\n               put(*m_position);\n               ++m_position;\n            }\n            break;\n         }\n         // otherwise output sub v:\n         put(this->m_results[v]);\n         if(have_brace)\n            ++m_position;\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nbool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)\n{\n   // \n   // We may have a capitalised string containing a Perl action:\n   //\n   static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };\n   static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };\n   static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };\n\n   if(m_position == m_end)\n      return false;\n   if(have_brace && (*m_position == '^'))\n      ++m_position;\n\n   std::ptrdiff_t max_len = m_end - m_position;\n\n   if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))\n   {\n      m_position += 5;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 5;\n            return false;\n         }\n      }\n      put(this->m_results[0]);\n      return true;\n   }\n   if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))\n   {\n      m_position += 8;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 8;\n            return false;\n         }\n      }\n      put(this->m_results.prefix());\n      return true;\n   }\n   if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))\n   {\n      m_position += 9;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 9;\n            return false;\n         }\n      }\n      put(this->m_results.suffix());\n      return true;\n   }\n   if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))\n   {\n      m_position += 16;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 16;\n            return false;\n         }\n      }\n      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);\n      return true;\n   }\n   if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))\n   {\n      m_position += 20;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 20;\n            return false;\n         }\n      }\n      put(this->m_results.get_last_closed_paren());\n      return true;\n   }\n   if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))\n   {\n      m_position += 2;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 2;\n            return false;\n         }\n      }\n      put(this->m_results.get_last_closed_paren());\n      return true;\n   }\n   return false;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()\n{\n   // skip the escape and check for trailing escape:\n   if(++m_position == m_end)\n   {\n      put(static_cast<char_type>('\\\\'));\n      return;\n   }\n   // now switch on the escape type:\n   switch(*m_position)\n   {\n   case 'a':\n      put(static_cast<char_type>('\\a'));\n      ++m_position;\n      break;\n   case 'f':\n      put(static_cast<char_type>('\\f'));\n      ++m_position;\n      break;\n   case 'n':\n      put(static_cast<char_type>('\\n'));\n      ++m_position;\n      break;\n   case 'r':\n      put(static_cast<char_type>('\\r'));\n      ++m_position;\n      break;\n   case 't':\n      put(static_cast<char_type>('\\t'));\n      ++m_position;\n      break;\n   case 'v':\n      put(static_cast<char_type>('\\v'));\n      ++m_position;\n      break;\n   case 'x':\n      if(++m_position == m_end)\n      {\n         put(static_cast<char_type>('x'));\n         return;\n      }\n      // maybe have \\x{ddd}\n      if(*m_position == static_cast<char_type>('{'))\n      {\n         ++m_position;\n         int val = this->toi(m_position, m_end, 16);\n         if(val < 0)\n         {\n            // invalid value treat everything as literals:\n            put(static_cast<char_type>('x'));\n            put(static_cast<char_type>('{'));\n            return;\n         }\n         if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))\n         {\n            --m_position;\n            while(*m_position != static_cast<char_type>('\\\\'))\n               --m_position;\n            ++m_position;\n            put(*m_position++);\n            return;\n         }\n         ++m_position;\n         put(static_cast<char_type>(val));\n         return;\n      }\n      else\n      {\n         std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);\n         len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n         int val = this->toi(m_position, m_position + len, 16);\n         if(val < 0)\n         {\n            --m_position;\n            put(*m_position++);\n            return;\n         }\n         put(static_cast<char_type>(val));\n      }\n      break;\n   case 'c':\n      if(++m_position == m_end)\n      {\n         --m_position;\n         put(*m_position++);\n         return;\n      }\n      put(static_cast<char_type>(*m_position++ % 32));\n      break;\n   case 'e':\n      put(static_cast<char_type>(27));\n      ++m_position;\n      break;\n   default:\n      // see if we have a perl specific escape:\n      if((m_flags & boost::regex_constants::format_sed) == 0)\n      {\n         bool breakout = false;\n         switch(*m_position)\n         {\n         case 'l':\n            ++m_position;\n            m_restore_state = m_state;\n            m_state = output_next_lower;\n            breakout = true;\n            break;\n         case 'L':\n            ++m_position;\n            m_state = output_lower;\n            breakout = true;\n            break;\n         case 'u':\n            ++m_position;\n            m_restore_state = m_state;\n            m_state = output_next_upper;\n            breakout = true;\n            break;\n         case 'U':\n            ++m_position;\n            m_state = output_upper;\n            breakout = true;\n            break;\n         case 'E':\n            ++m_position;\n            m_state = output_copy;\n            breakout = true;\n            break;\n         }\n         if(breakout)\n            break;\n      }\n      // see if we have a \\n sed style backreference:\n      std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);\n      len = (std::min)(static_cast<std::ptrdiff_t>(1), len);\n      int v = this->toi(m_position, m_position+len, 10);\n      if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))\n      {\n         put(m_results[v]);\n         break;\n      }\n      else if(v == 0)\n      {\n         // octal ecape sequence:\n         --m_position;\n         len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);\n         len = (std::min)(static_cast<std::ptrdiff_t>(4), len);\n         v = this->toi(m_position, m_position + len, 8);\n         BOOST_REGEX_ASSERT(v >= 0);\n         put(static_cast<char_type>(v));\n         break;\n      }\n      // Otherwise output the character \"as is\":\n      put(*m_position++);\n      break;\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()\n{\n   if(m_position == m_end)\n   {\n      // oops trailing '?':\n      put(static_cast<char_type>('?'));\n      return;\n   }\n   int v;\n   if(*m_position == '{')\n   {\n      ForwardIter base = m_position;\n      ++m_position;\n      v = this->toi(m_position, m_end, 10);\n      if(v < 0)\n      {\n         // Try a named subexpression:\n         while((m_position != m_end) && (*m_position != '}'))\n            ++m_position;\n         v = this->get_named_sub_index(base + 1, m_position);\n      }\n      if((v < 0) || (*m_position != '}'))\n      {\n         m_position = base;\n         // oops trailing '?':\n         put(static_cast<char_type>('?'));\n         return;\n      }\n      // Skip trailing '}':\n      ++m_position;\n   }\n   else\n   {\n      std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);\n      len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n      v = this->toi(m_position, m_position + len, 10);\n   }\n   if(v < 0)\n   {\n      // oops not a number:\n      put(static_cast<char_type>('?'));\n      return;\n   }\n\n   // output varies depending upon whether sub-expression v matched or not:\n   if(m_results[v].matched)\n   {\n      m_have_conditional = true;\n      format_all();\n      m_have_conditional = false;\n      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))\n      {\n         // skip the ':':\n         ++m_position;\n         // save output state, then turn it off:\n         output_state saved_state = m_state;\n         m_state = output_none;\n         // format the rest of this scope:\n         format_until_scope_end();\n         // restore output state:\n         m_state = saved_state;\n      }\n   }\n   else\n   {\n      // save output state, then turn it off:\n      output_state saved_state = m_state;\n      m_state = output_none;\n      // format until ':' or ')':\n      m_have_conditional = true;\n      format_all();\n      m_have_conditional = false;\n      // restore state:\n      m_state = saved_state;\n      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))\n      {\n         // skip the ':':\n         ++m_position;\n         // format the rest of this scope:\n         format_until_scope_end();\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()\n{\n   do\n   {\n      format_all();\n      if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))\n         return;\n      put(*m_position++);\n   }while(m_position != m_end);\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)\n{\n   // write a single character to output\n   // according to which case translation mode we are in:\n   switch(this->m_state)\n   {\n   case output_none:\n      return;\n   case output_next_lower:\n      c = m_traits.tolower(c);\n      this->m_state = m_restore_state;\n      break;\n   case output_next_upper:\n      c = m_traits.toupper(c);\n      this->m_state = m_restore_state;\n      break;\n   case output_lower:\n      c = m_traits.tolower(c);\n      break;\n   case output_upper:\n      c = m_traits.toupper(c);\n      break;\n   default:\n      break;\n   }\n   *m_out = c;\n   ++m_out;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)\n{\n   typedef typename sub_match_type::iterator iterator_type;\n   iterator_type i = sub.first;\n   while(i != sub.second)\n   {\n      put(*i);\n      ++i;\n   }\n}\n\ntemplate <class S>\nclass string_out_iterator\n{\n   S* out;\npublic:\n   string_out_iterator(S& s) : out(&s) {}\n   string_out_iterator& operator++() { return *this; }\n   string_out_iterator& operator++(int) { return *this; }\n   string_out_iterator& operator*() { return *this; }\n   string_out_iterator& operator=(typename S::value_type v) \n   { \n      out->append(1, v); \n      return *this; \n   }\n\n   typedef std::ptrdiff_t difference_type;\n   typedef typename S::value_type value_type;\n   typedef value_type* pointer;\n   typedef value_type& reference;\n   typedef std::output_iterator_tag iterator_category;\n};\n\ntemplate <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>\nOutputIterator regex_format_imp(OutputIterator out,\n                          const match_results<Iterator, Alloc>& m,\n                          ForwardIter p1, ForwardIter p2,\n                          match_flag_type flags,\n                          const traits& t\n                         )\n{\n   if(flags & regex_constants::format_literal)\n   {\n      return BOOST_REGEX_DETAIL_NS::copy(p1, p2, out);\n   }\n\n   BOOST_REGEX_DETAIL_NS::basic_regex_formatter<\n      OutputIterator, \n      match_results<Iterator, Alloc>, \n      traits, ForwardIter> f(out, m, t);\n   return f.format(p1, p2, flags);\n}\n\n#ifndef BOOST_NO_SFINAE\n\nBOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator)\n\nstruct any_type \n{\n   template <class T>\n   any_type(const T&); \n   template <class T, class U>\n   any_type(const T&, const U&); \n   template <class T, class U, class V>\n   any_type(const T&, const U&, const V&); \n};\ntypedef char no_type;\ntypedef char (&unary_type)[2];\ntypedef char (&binary_type)[3];\ntypedef char (&ternary_type)[4];\n\nno_type check_is_formatter(unary_type, binary_type, ternary_type);\ntemplate<typename T>\nunary_type check_is_formatter(T const &, binary_type, ternary_type);\ntemplate<typename T>\nbinary_type check_is_formatter(unary_type, T const &, ternary_type);\ntemplate<typename T, typename U>\nbinary_type check_is_formatter(T const &, U const &, ternary_type);\ntemplate<typename T>\nternary_type check_is_formatter(unary_type, binary_type, T const &);\ntemplate<typename T, typename U>\nternary_type check_is_formatter(T const &, binary_type, U const &);\ntemplate<typename T, typename U>\nternary_type check_is_formatter(unary_type, T const &, U const &);\ntemplate<typename T, typename U, typename V>\nternary_type check_is_formatter(T const &, U const &, V const &);\n\nstruct unary_binary_ternary\n{\n    typedef unary_type (*unary_fun)(any_type);\n    typedef binary_type (*binary_fun)(any_type, any_type);\n    typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);\n    operator unary_fun();\n    operator binary_fun();\n    operator ternary_fun();\n};\n\ntemplate<typename Formatter, bool IsFunction = boost::is_function<Formatter>::value>\nstruct formatter_wrapper\n  : Formatter\n  , unary_binary_ternary\n{\n   formatter_wrapper(){}\n};\n\ntemplate<typename Formatter>\nstruct formatter_wrapper<Formatter, true>\n  : unary_binary_ternary\n{\n    operator Formatter *();\n};\n\ntemplate<typename Formatter>\nstruct formatter_wrapper<Formatter *, false>\n  : unary_binary_ternary\n{\n    operator Formatter *();\n};\n\ntemplate <class F, class M, class O>\nstruct format_traits_imp\n{\nprivate:\n   //\n   // F must be a pointer, a function, or a class with a function call operator:\n   //\n   BOOST_STATIC_ASSERT((::boost::is_pointer<F>::value || ::boost::is_function<F>::value || ::boost::is_class<F>::value));\n   static formatter_wrapper<typename unwrap_reference<F>::type> f;\n   static M m;\n   static O out;\n   static boost::regex_constants::match_flag_type flags;\npublic:\n   BOOST_STATIC_CONSTANT(int, value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags))));\n};\n\ntemplate <class F, class M, class O>\nstruct format_traits\n{\npublic:\n   // \n   // Type is mpl::int_<N> where N is one of:\n   //\n   // 0 : F is a pointer to a presumably null-terminated string.\n   // 1 : F is a character-container such as a std::string.\n   // 2 : F is a Unary Functor.\n   // 3 : F is a Binary Functor.\n   // 4 : F is a Ternary Functor.\n   //\n   typedef typename boost::mpl::if_<\n      boost::mpl::and_<boost::is_pointer<F>, boost::mpl::not_<boost::is_function<typename boost::remove_pointer<F>::type> > >,\n      boost::mpl::int_<0>,\n      typename boost::mpl::if_<\n         has_const_iterator<F>,\n         boost::mpl::int_<1>,\n         boost::mpl::int_<format_traits_imp<F, M, O>::value>\n      >::type\n   >::type type;\n   //\n   // This static assertion will fail if the functor passed does not accept\n   // the same type of arguments passed.\n   //\n   BOOST_STATIC_ASSERT( boost::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true);\n};\n\n#else // BOOST_NO_SFINAE\n\ntemplate <class F, class M, class O>\nstruct format_traits\n{\npublic:\n   // \n   // Type is mpl::int_<N> where N is one of:\n   //\n   // 0 : F is a pointer to a presumably null-terminated string.\n   // 1 : F is a character-container such as a std::string.\n   //\n   // Other options such as F being a Functor are not supported without\n   // SFINAE support.\n   //\n   typedef typename boost::mpl::if_<\n      boost::is_pointer<F>,\n      boost::mpl::int_<0>,\n      boost::mpl::int_<1>\n   >::type type;\n};\n\n#endif // BOOST_NO_SFINAE\n\ntemplate <class Base, class Match>\nstruct format_functor3\n{\n   format_functor3(Base b) : func(b) {}\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)\n   {\n      return boost::unwrap_ref(func)(m, i, f);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor3(const format_functor3&);\n   format_functor3& operator=(const format_functor3&);\n};\n\ntemplate <class Base, class Match>\nstruct format_functor2\n{\n   format_functor2(Base b) : func(b) {}\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)\n   {\n      return boost::unwrap_ref(func)(m, i);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor2(const format_functor2&);\n   format_functor2& operator=(const format_functor2&);\n};\n\ntemplate <class Base, class Match>\nstruct format_functor1\n{\n   format_functor1(Base b) : func(b) {}\n\n   template <class S, class OutputIter>\n   OutputIter do_format_string(const S& s, OutputIter i)\n   {\n      return BOOST_REGEX_DETAIL_NS::copy(s.begin(), s.end(), i);\n   }\n   template <class S, class OutputIter>\n   inline OutputIter do_format_string(const S* s, OutputIter i)\n   {\n      while(s && *s)\n      {\n         *i = *s;\n         ++i;\n         ++s;\n      }\n      return i;\n   }\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)\n   {\n      return do_format_string(boost::unwrap_ref(func)(m), i);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor1(const format_functor1&);\n   format_functor1& operator=(const format_functor1&);\n};\n\ntemplate <class charT, class Match, class Traits>\nstruct format_functor_c_string\n{\n   format_functor_c_string(const charT* ps) : func(ps) {}\n\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())\n   {\n      //typedef typename Match::char_type char_type;\n      const charT* end = func;\n      while(*end) ++end;\n      return regex_format_imp(i, m, func, end, f, t);\n   }\nprivate:\n   const charT* func;\n   format_functor_c_string(const format_functor_c_string&);\n   format_functor_c_string& operator=(const format_functor_c_string&);\n};\n\ntemplate <class Container, class Match, class Traits>\nstruct format_functor_container\n{\n   format_functor_container(const Container& c) : func(c) {}\n\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())\n   {\n      //typedef typename Match::char_type char_type;\n      return BOOST_REGEX_DETAIL_NS::regex_format_imp(i, m, func.begin(), func.end(), f, t);\n   }\nprivate:\n   const Container& func;\n   format_functor_container(const format_functor_container&);\n   format_functor_container& operator=(const format_functor_container&);\n};\n\ntemplate <class Func, class Match, class OutputIterator, class Traits = BOOST_REGEX_DETAIL_NS::trivial_format_traits<typename Match::char_type> >\nstruct compute_functor_type\n{\n   typedef typename format_traits<Func, Match, OutputIterator>::type tag;\n   typedef typename boost::remove_cv< typename boost::remove_pointer<Func>::type>::type maybe_char_type;\n\n   typedef typename mpl::if_<\n      ::boost::is_same<tag, mpl::int_<0> >, format_functor_c_string<maybe_char_type, Match, Traits>,\n      typename mpl::if_<\n         ::boost::is_same<tag, mpl::int_<1> >, format_functor_container<Func, Match, Traits>,\n         typename mpl::if_<\n            ::boost::is_same<tag, mpl::int_<2> >, format_functor1<Func, Match>,\n            typename mpl::if_<\n               ::boost::is_same<tag, mpl::int_<3> >, format_functor2<Func, Match>, \n               format_functor3<Func, Match>\n            >::type\n         >::type\n      >::type\n   >::type type;\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class OutputIterator, class Iterator, class Allocator, class Functor>\ninline OutputIterator regex_format(OutputIterator out,\n                          const match_results<Iterator, Allocator>& m,\n                          Functor fmt,\n                          match_flag_type flags = format_all\n                         )\n{\n   return m.format(out, fmt, flags);\n}\n\ntemplate <class Iterator, class Allocator, class Functor>\ninline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m, \n                                      Functor fmt, \n                                      match_flag_type flags = format_all)\n{\n   return m.format(fmt, flags);\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_FORMAT_HPP\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_fwd.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_fwd.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Forward declares boost::basic_regex<> and\n  *                associated typedefs.\n  */\n\n#ifndef BOOST_REGEX_FWD_HPP_INCLUDED\n#define BOOST_REGEX_FWD_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n//\n// define BOOST_REGEX_NO_FWD if this\n// header doesn't work!\n//\n#ifdef BOOST_REGEX_NO_FWD\n#  ifndef BOOST_RE_REGEX_HPP\n#     include <boost/regex.hpp>\n#  endif\n#else\n\nnamespace boost{\n\ntemplate <class charT>\nclass cpp_regex_traits;\ntemplate <class charT>\nstruct c_regex_traits;\ntemplate <class charT>\nclass w32_regex_traits;\n\n#ifdef BOOST_REGEX_USE_WIN32_LOCALE\ntemplate <class charT, class implementationT = w32_regex_traits<charT> >\nstruct regex_traits;\n#elif defined(BOOST_REGEX_USE_CPP_LOCALE)\ntemplate <class charT, class implementationT = cpp_regex_traits<charT> >\nstruct regex_traits;\n#else\ntemplate <class charT, class implementationT = c_regex_traits<charT> >\nstruct regex_traits;\n#endif\n\ntemplate <class charT, class traits = regex_traits<charT> >\nclass basic_regex;\n\ntypedef basic_regex<char, regex_traits<char> > regex;\n#ifndef BOOST_NO_WREGEX\ntypedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_NO_FWD\n\n#endif\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_grep.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_grep.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_grep implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_GREP_HPP\n#define BOOST_REGEX_V4_REGEX_GREP_HPP\n\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n//\n// regex_grep:\n// find all non-overlapping matches within the sequence first last:\n//\ntemplate <class Predicate, class BidiIterator, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, \n                               BidiIterator first, \n                               BidiIterator last, \n                               const basic_regex<charT, traits>& e, \n                               match_flag_type flags = match_default)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;\n\n   match_results<BidiIterator> m;\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);\n   unsigned int count = 0;\n   while(matcher.find())\n   {\n      ++count;\n      if(0 == foo(m))\n         return count; // caller doesn't want to go on\n      if(m[0].second == last)\n         return count; // we've reached the end, don't try and find an extra null match.\n      if(m.length() == 0)\n      {\n         if(m[0].second == last)\n            return count;\n         // we found a NULL-match, now try to find\n         // a non-NULL one at the same position:\n         match_results<BidiIterator, match_allocator_type> m2(m);\n         matcher.setf(match_not_null | match_continuous);\n         if(matcher.find())\n         {\n            ++count;\n            if(0 == foo(m))\n               return count;\n         }\n         else\n         {\n            // reset match back to where it was:\n            m = m2;\n         }\n         matcher.unsetf((match_not_null | match_continuous) & ~flags);\n      }\n   }\n   return count;\n}\n\n//\n// regex_grep convenience interfaces:\n#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING\n//\n// this isn't really a partial specialisation, but template function\n// overloading - if the compiler doesn't support partial specialisation\n// then it really won't support this either:\ntemplate <class Predicate, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, str, str + traits::length(str), e, flags);\n}\n\ntemplate <class Predicate, class ST, class SA, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_grep(foo, s.begin(), s.end(), e, flags);\n}\n#else  // partial specialisation\ninline unsigned int regex_grep(bool (*foo)(const cmatch&), const char* str, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, str, str + regex::traits_type::length(str), e, flags);\n}\n#ifndef BOOST_NO_WREGEX\ninline unsigned int regex_grep(bool (*foo)(const wcmatch&), const wchar_t* str, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, str, str + wregex::traits_type::length(str), e, flags);\n}\n#endif\ninline unsigned int regex_grep(bool (*foo)(const match_results<std::string::const_iterator>&), const std::string& s,\n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, s.begin(), s.end(), e, flags);\n}\n#if !defined(BOOST_NO_WREGEX)\ninline unsigned int regex_grep(bool (*foo)(const match_results<std::basic_string<wchar_t>::const_iterator>&), \n                     const std::basic_string<wchar_t>& s, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, s.begin(), s.end(), e, flags);\n}\n#endif\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V4_REGEX_GREP_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_ITERATOR_HPP\n#define BOOST_REGEX_V4_REGEX_ITERATOR_HPP\n\n#include <boost/shared_ptr.hpp>\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class BidirectionalIterator, \n          class charT,\n          class traits>\nclass regex_iterator_implementation \n{\n   typedef basic_regex<charT, traits> regex_type;\n\n   match_results<BidirectionalIterator> what;  // current match\n   BidirectionalIterator                base;  // start of sequence\n   BidirectionalIterator                end;   // end of sequence\n   const regex_type                     re;   // the expression\n   match_flag_type                      flags; // flags for matching\n\npublic:\n   regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)\n      : base(), end(last), re(*p), flags(f){}\n   regex_iterator_implementation(const regex_iterator_implementation& other)\n      :what(other.what), base(other.base), end(other.end), re(other.re), flags(other.flags){}\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      return regex_search(first, end, what, re, flags);\n   }\n   bool compare(const regex_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);\n   }\n   const match_results<BidirectionalIterator>& get()\n   { return what; }\n   bool next()\n   {\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail;\n      BidirectionalIterator next_start = what[0].second;\n      match_flag_type f(flags);\n      if(!what.length() || (f & regex_constants::match_posix))\n         f |= regex_constants::match_not_initial_null;\n      //if(base != next_start)\n      //   f |= regex_constants::match_not_bob;\n      bool result = regex_search(next_start, end, what, re, f, base);\n      if(result)\n         what.set_base(base);\n      return result;\n   }\nprivate:\n   regex_iterator_implementation& operator=(const regex_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator, \n          class charT = BOOST_DEDUCED_TYPENAME BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT> >\nclass regex_iterator \n{\nprivate:\n   typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;\n   typedef shared_ptr<impl> pimpl;\npublic:\n   typedef          basic_regex<charT, traits>                   regex_type;\n   typedef          match_results<BidirectionalIterator>                    value_type;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   regex_iterator(){}\n   regex_iterator(BidirectionalIterator a, BidirectionalIterator b, \n                  const regex_type& re, \n                  match_flag_type m = match_default)\n                  : pdata(new impl(&re, b, m))\n   {\n      if(!pdata->init(a))\n      {\n         pdata.reset();\n      }\n   }\n   regex_iterator(const regex_iterator& that)\n      : pdata(that.pdata) {}\n   regex_iterator& operator=(const regex_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const regex_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const regex_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   regex_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   regex_iterator operator++(int)\n   {\n      regex_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && !pdata.unique())\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef regex_iterator<const char*> cregex_iterator;\ntypedef regex_iterator<std::string::const_iterator> sregex_iterator;\n#ifndef BOOST_NO_WREGEX\ntypedef regex_iterator<const wchar_t*> wcregex_iterator;\ntypedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;\n#endif\n\n// make_regex_iterator:\ntemplate <class charT, class traits>\ninline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_match.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_match.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Regular expression matching algorithms.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n\n#ifndef BOOST_REGEX_MATCH_HPP\n#define BOOST_REGEX_MATCH_HPP\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n//\n// proc regex_match\n// returns true if the specified regular expression matches\n// the whole of the input.  Fills in what matched in m.\n//\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);\n   return matcher.match();\n}\ntemplate <class iterator, class charT, class traits>\nbool regex_match(iterator first, iterator last, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<iterator> m;\n   return regex_match(first, last, m, e, flags | regex_constants::match_any);\n}\n//\n// query_match convenience interfaces:\n#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING\n//\n// this isn't really a partial specialisation, but template function\n// overloading - if the compiler doesn't support partial specialisation\n// then it really won't support this either:\ntemplate <class charT, class Allocator, class traits>\ninline bool regex_match(const charT* str, \n                        match_results<const charT*, Allocator>& m, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + traits::length(str), m, e, flags);\n}\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\ninline bool regex_match(const std::basic_string<charT, ST, SA>& s, \n                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ntemplate <class charT, class traits>\ninline bool regex_match(const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const charT*> m;\n   return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);\n}\n\ntemplate <class ST, class SA, class charT, class traits>\ninline bool regex_match(const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;\n   match_results<iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#else  // partial ordering\ninline bool regex_match(const char* str, \n                        cmatch& m, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const char* str, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#ifndef BOOST_NO_STD_LOCALE\ninline bool regex_match(const char* str, \n                        cmatch& m, \n                        const basic_regex<char, cpp_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const char* str, \n                        const basic_regex<char, cpp_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_match(const char* str, \n                        cmatch& m, \n                        const basic_regex<char, c_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const char* str, \n                        const basic_regex<char, c_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\ninline bool regex_match(const char* str, \n                        cmatch& m, \n                        const basic_regex<char, w32_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const char* str, \n                        const basic_regex<char, w32_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return regex_match(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#endif\n#ifndef BOOST_NO_WREGEX\ninline bool regex_match(const wchar_t* str, \n                        wcmatch& m, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const wchar_t* str, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#ifndef BOOST_NO_STD_LOCALE\ninline bool regex_match(const wchar_t* str, \n                        wcmatch& m, \n                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const wchar_t* str, \n                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_match(const wchar_t* str, \n                        wcmatch& m, \n                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const wchar_t* str, \n                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\ninline bool regex_match(const wchar_t* str, \n                        wcmatch& m, \n                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_match(const wchar_t* str, \n                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return regex_match(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#endif\n#endif\ninline bool regex_match(const std::string& s, \n                        smatch& m,\n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::string& s, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#ifndef BOOST_NO_STD_LOCALE\ninline bool regex_match(const std::string& s, \n                        smatch& m,\n                        const basic_regex<char, cpp_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::string& s, \n                        const basic_regex<char, cpp_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_match(const std::string& s, \n                        smatch& m,\n                        const basic_regex<char, c_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::string& s, \n                        const basic_regex<char, c_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\ninline bool regex_match(const std::string& s, \n                        smatch& m,\n                        const basic_regex<char, w32_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::string& s, \n                        const basic_regex<char, w32_regex_traits<char> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#endif\n#if !defined(BOOST_NO_WREGEX)\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        match_results<std::basic_string<wchar_t>::const_iterator>& m,\n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::basic_string<wchar_t>::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#ifndef BOOST_NO_STD_LOCALE\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        match_results<std::basic_string<wchar_t>::const_iterator>& m,\n                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        const basic_regex<wchar_t, cpp_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::basic_string<wchar_t>::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        match_results<std::basic_string<wchar_t>::const_iterator>& m,\n                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        const basic_regex<wchar_t, c_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::basic_string<wchar_t>::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        match_results<std::basic_string<wchar_t>::const_iterator>& m,\n                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ninline bool regex_match(const std::basic_string<wchar_t>& s, \n                        const basic_regex<wchar_t, w32_regex_traits<wchar_t> >& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::basic_string<wchar_t>::const_iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#endif\n#endif\n\n#endif\n\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif   // BOOST_REGEX_MATCH_HPP\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_merge.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_MERGE_HPP\n#define BOOST_REGEX_V4_REGEX_MERGE_HPP\n\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class OutputIterator, class Iterator, class traits, class charT>\ninline OutputIterator regex_merge(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const basic_regex<charT, traits>& e, \n                         const charT* fmt, \n                         match_flag_type flags = match_default)\n{\n   return regex_replace(out, first, last, e, fmt, flags);\n}\n\ntemplate <class OutputIterator, class Iterator, class traits, class charT>\ninline OutputIterator regex_merge(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const basic_regex<charT, traits>& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_merge(out, first, last, e, fmt.c_str(), flags);\n}\n\ntemplate <class traits, class charT>\ninline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         const charT* fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_replace(s, e, fmt, flags);\n}\n\ntemplate <class traits, class charT>\ninline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_replace(s, e, fmt, flags);\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V4_REGEX_MERGE_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_raw_buffer.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_raw_buffer.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Raw character buffer for regex code.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_RAW_BUFFER_HPP\n#define BOOST_REGEX_RAW_BUFFER_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#include <algorithm>\n#include <cstddef>\n\nnamespace boost{\n   namespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nstruct empty_padding{};\n\nunion padding\n{\n   void* p;\n   unsigned int i;\n};\n\ntemplate <int N>\nstruct padding3\n{\n   enum{\n      padding_size = 8,\n      padding_mask = 7\n   };\n};\n\ntemplate<>\nstruct padding3<2>\n{\n   enum{\n      padding_size = 2,\n      padding_mask = 1\n   };\n};\n\ntemplate<>\nstruct padding3<4>\n{\n   enum{\n      padding_size = 4,\n      padding_mask = 3\n   };\n};\n\ntemplate<>\nstruct padding3<8>\n{\n   enum{\n      padding_size = 8,\n      padding_mask = 7\n   };\n};\n\ntemplate<>\nstruct padding3<16>\n{\n   enum{\n      padding_size = 16,\n      padding_mask = 15\n   };\n};\n\nenum{\n   padding_size = padding3<sizeof(padding)>::padding_size,\n   padding_mask = padding3<sizeof(padding)>::padding_mask\n};\n\n//\n// class raw_storage\n// basically this is a simplified vector<unsigned char>\n// this is used by basic_regex for expression storage\n//\n\nclass raw_storage\n{\npublic:\n   typedef std::size_t           size_type;\n   typedef unsigned char*        pointer;\nprivate:\n   pointer last, start, end;\npublic:\n\n   raw_storage();\n   raw_storage(size_type n);\n\n   ~raw_storage()\n   {\n      ::operator delete(start);\n   }\n\n   void BOOST_REGEX_CALL resize(size_type n)\n   {\n      size_type newsize = start ? last - start : 1024;\n      while (newsize < n)\n         newsize *= 2;\n      size_type datasize = end - start;\n      // extend newsize to WORD/DWORD boundary:\n      newsize = (newsize + padding_mask) & ~(padding_mask);\n\n      // allocate and copy data:\n      pointer ptr = static_cast<pointer>(::operator new(newsize));\n      BOOST_REGEX_NOEH_ASSERT(ptr)\n         if (start)\n            std::memcpy(ptr, start, datasize);\n\n      // get rid of old buffer:\n      ::operator delete(start);\n\n      // and set up pointers:\n      start = ptr;\n      end = ptr + datasize;\n      last = ptr + newsize;\n   }\n\n   void* BOOST_REGEX_CALL extend(size_type n)\n   {\n      if(size_type(last - end) < n)\n         resize(n + (end - start));\n      pointer result = end;\n      end += n;\n      return result;\n   }\n\n   void* BOOST_REGEX_CALL insert(size_type pos, size_type n)\n   {\n      BOOST_REGEX_ASSERT(pos <= size_type(end - start));\n      if (size_type(last - end) < n)\n         resize(n + (end - start));\n      void* result = start + pos;\n      std::memmove(start + pos + n, start + pos, (end - start) - pos);\n      end += n;\n      return result;\n   }\n\n   size_type BOOST_REGEX_CALL size()\n   {\n      return size_type(end - start);\n   }\n\n   size_type BOOST_REGEX_CALL capacity()\n   {\n      return size_type(last - start);\n   }\n\n   void* BOOST_REGEX_CALL data()const\n   {\n      return start;\n   }\n\n   size_type BOOST_REGEX_CALL index(void* ptr)\n   {\n      return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));\n   }\n\n   void BOOST_REGEX_CALL clear()\n   {\n      end = start;\n   }\n\n   void BOOST_REGEX_CALL align()\n   {\n      // move end up to a boundary:\n      end = start + (((end - start) + padding_mask) & ~padding_mask);\n   }\n   void swap(raw_storage& that)\n   {\n      std::swap(start, that.start);\n      std::swap(end, that.end);\n      std::swap(last, that.last);\n  }\n};\n\ninline raw_storage::raw_storage()\n{\n   last = start = end = 0;\n}\n\ninline raw_storage::raw_storage(size_type n)\n{\n   start = end = static_cast<pointer>(::operator new(n));\n   BOOST_REGEX_NOEH_ASSERT(start)\n   last = start + n;\n}\n\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#endif\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_replace.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_REPLACE_HPP\n#define BOOST_REGEX_V4_REGEX_REPLACE_HPP\n\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class OutputIterator, class BidirectionalIterator, class traits, class charT, class Formatter>\nOutputIterator regex_replace(OutputIterator out,\n                         BidirectionalIterator first,\n                         BidirectionalIterator last,\n                         const basic_regex<charT, traits>& e, \n                         Formatter fmt, \n                         match_flag_type flags = match_default)\n{\n   regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);\n   regex_iterator<BidirectionalIterator, charT, traits> j;\n   if(i == j)\n   {\n      if(!(flags & regex_constants::format_no_copy))\n         out = BOOST_REGEX_DETAIL_NS::copy(first, last, out);\n   }\n   else\n   {\n      BidirectionalIterator last_m(first);\n      while(i != j)\n      {\n         if(!(flags & regex_constants::format_no_copy))\n            out = BOOST_REGEX_DETAIL_NS::copy(i->prefix().first, i->prefix().second, out); \n         out = i->format(out, fmt, flags, e);\n         last_m = (*i)[0].second;\n         if(flags & regex_constants::format_first_only)\n            break;\n         ++i;\n      }\n      if(!(flags & regex_constants::format_no_copy))\n         out = BOOST_REGEX_DETAIL_NS::copy(last_m, last, out);\n   }\n   return out;\n}\n\ntemplate <class traits, class charT, class Formatter>\nstd::basic_string<charT> regex_replace(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         Formatter fmt,\n                         match_flag_type flags = match_default)\n{\n   std::basic_string<charT> result;\n   BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n   regex_replace(i, s.begin(), s.end(), e, fmt, flags);\n   return result;\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V4_REGEX_REPLACE_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_search.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_search.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_search implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_SEARCH_HPP\n#define BOOST_REGEX_V4_REGEX_SEARCH_HPP\n\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  match_results<BidiIterator, Allocator>& m, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags = match_default)\n{\n   return regex_search(first, last, m, e, flags, first);\n}\n\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  match_results<BidiIterator, Allocator>& m, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags,\n                  BidiIterator base)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);\n   return matcher.find();\n}\n\n//\n// regex_search convenience interfaces:\n#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING\n//\n// this isn't really a partial specialisation, but template function\n// overloading - if the compiler doesn't support partial specialisation\n// then it really won't support this either:\ntemplate <class charT, class Allocator, class traits>\ninline bool regex_search(const charT* str, \n                        match_results<const charT*, Allocator>& m, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + traits::length(str), m, e, flags);\n}\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\ninline bool regex_search(const std::basic_string<charT, ST, SA>& s, \n                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), m, e, flags);\n}\n#else  // partial overloads:\ninline bool regex_search(const char* str, \n                        cmatch& m, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + regex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_search(const char* first, const char* last, \n                  const regex& e, \n                  match_flag_type flags = match_default)\n{\n   cmatch m;\n   return regex_search(first, last, m, e, flags | regex_constants::match_any);\n}\n\n#ifndef BOOST_NO_WREGEX\ninline bool regex_search(const wchar_t* str, \n                        wcmatch& m, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + wregex::traits_type::length(str), m, e, flags);\n}\ninline bool regex_search(const wchar_t* first, const wchar_t* last, \n                  const wregex& e, \n                  match_flag_type flags = match_default)\n{\n   wcmatch m;\n   return regex_search(first, last, m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_search(const std::string& s, \n                        smatch& m,\n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), m, e, flags);\n}\n#if !defined(BOOST_NO_WREGEX)\ninline bool regex_search(const std::basic_string<wchar_t>& s, \n                        wsmatch& m,\n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), m, e, flags);\n}\n#endif\n\n#endif\n\ntemplate <class BidiIterator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags = match_default)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   match_results<BidiIterator> m;\n   typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);\n   return matcher.find();\n}\n\n#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING\n\ntemplate <class charT, class traits>\ninline bool regex_search(const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + traits::length(str), e, flags);\n}\n\ntemplate <class ST, class SA, class charT, class traits>\ninline bool regex_search(const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), e, flags);\n}\n#else  // non-template function overloads\ninline bool regex_search(const char* str, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   cmatch m;\n   return regex_search(str, str + regex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#ifndef BOOST_NO_WREGEX\ninline bool regex_search(const wchar_t* str, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   wcmatch m;\n   return regex_search(str, str + wregex::traits_type::length(str), m, e, flags | regex_constants::match_any);\n}\n#endif\ninline bool regex_search(const std::string& s, \n                        const regex& e, \n                        match_flag_type flags = match_default)\n{\n   smatch m;\n   return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n#if !defined(BOOST_NO_WREGEX)\ninline bool regex_search(const std::basic_string<wchar_t>& s, \n                        const wregex& e, \n                        match_flag_type flags = match_default)\n{\n   wsmatch m;\n   return regex_search(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n\n#endif // BOOST_NO_WREGEX\n\n#endif // partial overload\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V4_REGEX_SEARCH_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_split.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_split.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Implements regex_split and associated functions.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_SPLIT_HPP\n#define BOOST_REGEX_SPLIT_HPP\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class charT>\nconst basic_regex<charT>& get_default_expression(charT)\n{\n   static const charT expression_text[4] = { '\\\\', 's', '+', '\\00', };\n   static const basic_regex<charT> e(expression_text);\n   return e;\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\nclass split_pred\n{\n   typedef std::basic_string<charT, Traits1, Alloc1> string_type;\n   typedef typename string_type::const_iterator iterator_type;\n   iterator_type* p_last;\n   OutputIterator* p_out;\n   std::size_t* p_max;\n   std::size_t initial_max;\npublic:\n   split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)\n      : p_last(a), p_out(b), p_max(c), initial_max(*c) {}\n\n   bool operator()(const match_results<iterator_type>& what);\n};\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\nbool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()\n   (const match_results<iterator_type>& what)\n{\n   *p_last = what[0].second;\n   if(what.size() > 1)\n   {\n      // output sub-expressions only:\n      for(unsigned i = 1; i < what.size(); ++i)\n      {\n         *(*p_out) = what.str(i);\n         ++(*p_out);\n         if(0 == --*p_max) return false;\n      }\n      return *p_max != 0;\n   }\n   else\n   {\n      // output $` only if it's not-null or not at the start of the input:\n      const sub_match<iterator_type>& sub = what[-1];\n      if((sub.first != sub.second) || (*p_max != initial_max))\n      {\n         *(*p_out) = sub.str();\n         ++(*p_out);\n         return --*p_max;\n      }\n   }\n   //\n   // initial null, do nothing:\n   return true;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>\nstd::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s, \n                   const basic_regex<charT, Traits2>& e,\n                   match_flag_type flags,\n                   std::size_t max_split)\n{\n   typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator  ci_t;\n   //typedef typename match_results<ci_t>::allocator_type                        match_allocator;\n   ci_t last = s.begin();\n   std::size_t init_size = max_split;\n   BOOST_REGEX_DETAIL_NS::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);\n   ci_t i, j;\n   i = s.begin();\n   j = s.end();\n   regex_grep(pred, i, j, e, flags);\n   //\n   // if there is still input left, do a final push as long as max_split\n   // is not exhausted, and we're not splitting sub-expressions rather \n   // than whitespace:\n   if(max_split && (last != s.end()) && (e.mark_count() == 0))\n   {\n      *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());\n      ++out;\n      last = s.end();\n      --max_split;\n   }\n   //\n   // delete from the string everything that has been processed so far:\n   s.erase(0, last - s.begin());\n   //\n   // return the number of new records pushed:\n   return init_size - max_split;\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>\ninline std::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s, \n                   const basic_regex<charT, Traits2>& e,\n                   match_flag_type flags = match_default)\n{\n   return regex_split(out, s, e, flags, UINT_MAX);\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\ninline std::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s)\n{\n   return regex_split(out, s, BOOST_REGEX_DETAIL_NS::get_default_expression(charT(0)), match_default, UINT_MAX);\n}\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_token_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_token_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_token_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP\n#define BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP\n\n#include <boost/shared_ptr.hpp>\n#include <boost/detail/workaround.hpp>\n#if (BOOST_WORKAROUND(BOOST_BORLANDC, >= 0x560) && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))\n//\n// Borland C++ Builder 6, and Visual C++ 6,\n// can't cope with the array template constructor\n// so we have a template member that will accept any type as \n// argument, and then assert that is really is an array:\n//\n#include <boost/static_assert.hpp>\n#include <boost/type_traits/is_array.hpp>\n#endif\n\nnamespace boost{\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#pragma warning(push)\n#pragma warning(disable:4700)\n#endif\n\ntemplate <class BidirectionalIterator,\n          class charT,\n          class traits>\nclass regex_token_iterator_implementation \n{\n   typedef basic_regex<charT, traits> regex_type;\n   typedef sub_match<BidirectionalIterator>      value_type;\n\n   match_results<BidirectionalIterator> what;   // current match\n   BidirectionalIterator                base;    // start of search area\n   BidirectionalIterator                end;    // end of search area\n   const regex_type                     re;    // the expression\n   match_flag_type                      flags;  // match flags\n   value_type                           result; // the current string result\n   int                                  N;      // the current sub-expression being enumerated\n   std::vector<int>                     subs;   // the sub-expressions to enumerate\n\npublic:\n   regex_token_iterator_implementation(const regex_token_iterator_implementation& other)\n      : what(other.what), base(other.base), end(other.end), re(other.re), flags(other.flags), result(other.result), N(other.N), subs(other.subs) {}\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)\n      : end(last), re(*p), flags(f), N(0){ subs.push_back(sub); }\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)\n      : end(last), re(*p), flags(f), N(0), subs(v){}\n#if !BOOST_WORKAROUND(__HP_aCC, < 60700)\n#if (BOOST_WORKAROUND(BOOST_BORLANDC, >= 0x560) && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \\\n      || BOOST_WORKAROUND(__HP_aCC, < 60700)\n   template <class T>\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)\n      : end(last), re(*p), flags(f), N(0)\n   {\n      // assert that T really is an array:\n      BOOST_STATIC_ASSERT(::boost::is_array<T>::value);\n      const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);\n      for(std::size_t i = 0; i < array_size; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n#else\n   template <std::size_t CN>\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)\n      : end(last), re(*p), flags(f), N(0)\n   {\n      for(std::size_t i = 0; i < CN; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n#endif\n#endif\n   bool init(BidirectionalIterator first)\n   {\n      N = 0;\n      base = first;\n      if(regex_search(first, end, what, re, flags, base) == true)\n      {\n         N = 0;\n         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);\n         return true;\n      }\n      else if((subs[N] == -1) && (first != end))\n      {\n         result.first = first;\n         result.second = end;\n         result.matched = (first != end);\n         N = -1;\n         return true;\n      }\n      return false;\n   }\n   bool compare(const regex_token_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) \n         && (end == that.end) \n         && (flags == that.flags) \n         && (N == that.N) \n         && (what[0].first == that.what[0].first) \n         && (what[0].second == that.what[0].second);\n   }\n   const value_type& get()\n   { return result; }\n   bool next()\n   {\n      if(N == -1)\n         return false;\n      if(N+1 < (int)subs.size())\n      {\n         ++N;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      //if(what.prefix().first != what[0].second)\n      //   flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;\n      BidirectionalIterator last_end(what[0].second);\n      if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))\n      {\n         N =0;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      else if((last_end != end) && (subs[0] == -1))\n      {\n         N =-1;\n         result.first = last_end;\n         result.second = end;\n         result.matched = (last_end != end);\n         return true;\n      }\n      return false;\n   }\nprivate:\n   regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator, \n          class charT = BOOST_DEDUCED_TYPENAME BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT> >\nclass regex_token_iterator \n{\nprivate:\n   typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;\n   typedef shared_ptr<impl> pimpl;\npublic:\n   typedef          basic_regex<charT, traits>                   regex_type;\n   typedef          sub_match<BidirectionalIterator>                        value_type;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   regex_token_iterator(){}\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        int submatch = 0, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatch, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        const std::vector<int>& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#if !BOOST_WORKAROUND(__HP_aCC, < 60700)\n#if (BOOST_WORKAROUND(BOOST_BORLANDC, >= 0x560) && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \\\n      || BOOST_WORKAROUND(__HP_aCC, < 60700)\n   template <class T>\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const T& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#else\n   template <std::size_t N>\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const int (&submatches)[N], match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#endif\n#endif\n   regex_token_iterator(const regex_token_iterator& that)\n      : pdata(that.pdata) {}\n   regex_token_iterator& operator=(const regex_token_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const regex_token_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const regex_token_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   regex_token_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   regex_token_iterator operator++(int)\n   {\n      regex_token_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && !pdata.unique())\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef regex_token_iterator<const char*> cregex_token_iterator;\ntypedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;\n#ifndef BOOST_NO_WREGEX\ntypedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;\ntypedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;\n#endif\n\ntemplate <class charT, class traits>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <class charT, class traits, std::size_t N>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA, std::size_t N>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <class charT, class traits>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits classes.\n  */\n\n#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_REGEX_TRAITS_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n#ifndef BOOST_REGEX_WORKAROUND_HPP\n#include <boost/regex/v4/regex_workaround.hpp>\n#endif\n#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP\n#include <boost/regex/v4/syntax_type.hpp>\n#endif\n#ifndef BOOST_REGEX_ERROR_TYPE_HPP\n#include <boost/regex/v4/error_type.hpp>\n#endif\n#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n#include <boost/regex/v4/regex_traits_defaults.hpp>\n#endif\n#ifndef BOOST_NO_STD_LOCALE\n#  ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED\n#     include <boost/regex/v4/cpp_regex_traits.hpp>\n#  endif\n#endif\n#if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x560)\n#  ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED\n#     include <boost/regex/v4/c_regex_traits.hpp>\n#  endif\n#endif\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\n#  ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED\n#     include <boost/regex/v4/w32_regex_traits.hpp>\n#  endif\n#endif\n#ifndef BOOST_REGEX_FWD_HPP_INCLUDED\n#include <boost/regex_fwd.hpp>\n#endif\n\n#include \"boost/mpl/has_xxx.hpp\"\n#include <boost/static_assert.hpp>\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n\ntemplate <class charT, class implementationT >\nstruct regex_traits : public implementationT\n{\n   regex_traits() : implementationT() {}\n};\n\n//\n// class regex_traits_wrapper.\n// this is what our implementation will actually store;\n// it provides default implementations of the \"optional\"\n// interfaces that we support, in addition to the\n// required \"standard\" ones:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\n#if !BOOST_WORKAROUND(__HP_aCC, < 60000)\nBOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag)\n#else\ntemplate<class T>\nstruct has_boost_extensions_tag\n{\n   BOOST_STATIC_CONSTANT(bool, value = false);\n};\n#endif\n\ntemplate <class BaseT>\nstruct default_wrapper : public BaseT\n{\n   typedef typename BaseT::char_type char_type;\n   std::string error_string(::boost::regex_constants::error_type e)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(e);\n   }\n   ::boost::regex_constants::syntax_type syntax_type(char_type c)const\n   {\n      return ((c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;\n   }\n   ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const\n   {\n      return ((c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;\n   }\n   boost::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n   }\n   char_type translate(char_type c, bool icase)const\n   {\n      return (icase ? this->translate_nocase(c) : this->translate(c));\n   }\n   char_type translate(char_type c)const\n   {\n      return BaseT::translate(c);\n   }\n   char_type tolower(char_type c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);\n   }\n   char_type toupper(char_type c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);\n   }\n};\n\ntemplate <class BaseT, bool has_extensions>\nstruct compute_wrapper_base\n{\n   typedef BaseT type;\n};\n#if !BOOST_WORKAROUND(__HP_aCC, < 60000)\ntemplate <class BaseT>\nstruct compute_wrapper_base<BaseT, false>\n{\n   typedef default_wrapper<BaseT> type;\n};\n#else\ntemplate <>\nstruct compute_wrapper_base<c_regex_traits<char>, false>\n{\n   typedef default_wrapper<c_regex_traits<char> > type;\n};\n#ifndef BOOST_NO_WREGEX\ntemplate <>\nstruct compute_wrapper_base<c_regex_traits<wchar_t>, false>\n{\n   typedef default_wrapper<c_regex_traits<wchar_t> > type;\n};\n#endif\n#endif\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class BaseT>\nstruct regex_traits_wrapper \n   : public ::boost::BOOST_REGEX_DETAIL_NS::compute_wrapper_base<\n               BaseT, \n               ::boost::BOOST_REGEX_DETAIL_NS::has_boost_extensions_tag<BaseT>::value\n            >::type\n{\n   regex_traits_wrapper(){}\nprivate:\n   regex_traits_wrapper(const regex_traits_wrapper&);\n   regex_traits_wrapper& operator=(const regex_traits_wrapper&);\n};\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif // include\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_traits_defaults.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_traits_defaults.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares API's for access to regex_traits default properties.\n  */\n\n#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#include <boost/regex/config.hpp>\n#include <boost/cstdint.hpp>\n\n#include <cctype>\n#include <cwctype>\n#include <locale>\n\n#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP\n#include <boost/regex/v4/syntax_type.hpp>\n#endif\n#ifndef BOOST_REGEX_ERROR_TYPE_HPP\n#include <boost/regex/v4/error_type.hpp>\n#endif\n#include <boost/regex/v4/regex_workaround.hpp>\n#include <boost/type_traits/make_unsigned.hpp>\n#include <boost/utility/enable_if.hpp>\n\n#ifdef BOOST_NO_STDC_NAMESPACE\nnamespace std{\n   using ::strlen;\n}\n#endif\n\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n\n\n//\n// helpers to suppress warnings:\n//\ntemplate <class charT>\ninline bool is_extended(charT c)\n{\n   typedef typename make_unsigned<charT>::type unsigned_type; \n   return (sizeof(charT) > 1) && (static_cast<unsigned_type>(c) >= 256u); \n}\ninline bool is_extended(char)\n{ return false; }\n\ninline const char* BOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n)\n{\n   // if the user hasn't supplied a message catalog, then this supplies\n   // default \"messages\" for us to load in the range 1-100.\n   const char* messages[] = {\n         \"\",\n         \"(\",\n         \")\",\n         \"$\",\n         \"^\",\n         \".\",\n         \"*\",\n         \"+\",\n         \"?\",\n         \"[\",\n         \"]\",\n         \"|\",\n         \"\\\\\",\n         \"#\",\n         \"-\",\n         \"{\",\n         \"}\",\n         \"0123456789\",\n         \"b\",\n         \"B\",\n         \"<\",\n         \">\",\n         \"\",\n         \"\",\n         \"A`\",\n         \"z'\",\n         \"\\n\",\n         \",\",\n         \"a\",\n         \"f\",\n         \"n\",\n         \"r\",\n         \"t\",\n         \"v\",\n         \"x\",\n         \"c\",\n         \":\",\n         \"=\",\n         \"e\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"E\",\n         \"Q\",\n         \"X\",\n         \"C\",\n         \"Z\",\n         \"G\",\n         \"!\",\n         \"p\",\n         \"P\",\n         \"N\",\n         \"gk\",\n         \"K\",\n         \"R\",\n   };\n\n   return ((n >= (sizeof(messages) / sizeof(messages[1]))) ? \"\" : messages[n]);\n}\n\ninline const char* BOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n)\n{\n   static const char* const s_default_error_messages[] = {\n      \"Success\",                                                            /* REG_NOERROR 0 error_ok */\n      \"No match\",                                                           /* REG_NOMATCH 1 error_no_match */\n      \"Invalid regular expression.\",                                        /* REG_BADPAT 2 error_bad_pattern */\n      \"Invalid collation character.\",                                       /* REG_ECOLLATE 3 error_collate */\n      \"Invalid character class name, collating name, or character range.\",  /* REG_ECTYPE 4 error_ctype */\n      \"Invalid or unterminated escape sequence.\",                           /* REG_EESCAPE 5 error_escape */\n      \"Invalid back reference: specified capturing group does not exist.\",  /* REG_ESUBREG 6 error_backref */\n      \"Unmatched [ or [^ in character class declaration.\",                  /* REG_EBRACK 7 error_brack */\n      \"Unmatched marking parenthesis ( or \\\\(.\",                            /* REG_EPAREN 8 error_paren */\n      \"Unmatched quantified repeat operator { or \\\\{.\",                     /* REG_EBRACE 9 error_brace */\n      \"Invalid content of repeat range.\",                                   /* REG_BADBR 10 error_badbrace */\n      \"Invalid range end in character class\",                               /* REG_ERANGE 11 error_range */\n      \"Out of memory.\",                                                     /* REG_ESPACE 12 error_space NOT USED */\n      \"Invalid preceding regular expression prior to repetition operator.\", /* REG_BADRPT 13 error_badrepeat */\n      \"Premature end of regular expression\",                                /* REG_EEND 14 error_end NOT USED */\n      \"Regular expression is too large.\",                                   /* REG_ESIZE 15 error_size NOT USED */\n      \"Unmatched ) or \\\\)\",                                                 /* REG_ERPAREN 16 error_right_paren NOT USED */\n      \"Empty regular expression.\",                                          /* REG_EMPTY 17 error_empty */\n      \"The complexity of matching the regular expression exceeded predefined bounds.  \"\n      \"Try refactoring the regular expression to make each choice made by the state machine unambiguous.  \"\n      \"This exception is thrown to prevent \\\"eternal\\\" matches that take an \"\n      \"indefinite period time to locate.\",                                  /* REG_ECOMPLEXITY 18 error_complexity */\n      \"Ran out of stack space trying to match the regular expression.\",     /* REG_ESTACK 19 error_stack */\n      \"Invalid or unterminated Perl (?...) sequence.\",                      /* REG_E_PERL 20 error_perl */\n      \"Unknown error.\",                                                     /* REG_E_UNKNOWN 21 error_unknown */\n   };\n\n   return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[::boost::regex_constants::error_unknown] : s_default_error_messages[n];\n}\n\ninline regex_constants::syntax_type BOOST_REGEX_CALL get_default_syntax_type(char c)\n{\n   //\n   // char_syntax determines how the compiler treats a given character\n   // in a regular expression.\n   //\n   static regex_constants::syntax_type char_syntax[] = {\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_newline,     /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /* */    // 32\n      regex_constants::syntax_not,        /*!*/\n      regex_constants::syntax_char,        /*\"*/\n      regex_constants::syntax_hash,        /*#*/\n      regex_constants::syntax_dollar,        /*$*/\n      regex_constants::syntax_char,        /*%*/\n      regex_constants::syntax_char,        /*&*/\n      regex_constants::escape_type_end_buffer,  /*'*/\n      regex_constants::syntax_open_mark,        /*(*/\n      regex_constants::syntax_close_mark,        /*)*/\n      regex_constants::syntax_star,        /***/\n      regex_constants::syntax_plus,        /*+*/\n      regex_constants::syntax_comma,        /*,*/\n      regex_constants::syntax_dash,        /*-*/\n      regex_constants::syntax_dot,        /*.*/\n      regex_constants::syntax_char,        /*/*/\n      regex_constants::syntax_digit,        /*0*/\n      regex_constants::syntax_digit,        /*1*/\n      regex_constants::syntax_digit,        /*2*/\n      regex_constants::syntax_digit,        /*3*/\n      regex_constants::syntax_digit,        /*4*/\n      regex_constants::syntax_digit,        /*5*/\n      regex_constants::syntax_digit,        /*6*/\n      regex_constants::syntax_digit,        /*7*/\n      regex_constants::syntax_digit,        /*8*/\n      regex_constants::syntax_digit,        /*9*/\n      regex_constants::syntax_colon,        /*:*/\n      regex_constants::syntax_char,        /*;*/\n      regex_constants::escape_type_left_word, /*<*/\n      regex_constants::syntax_equal,        /*=*/\n      regex_constants::escape_type_right_word, /*>*/\n      regex_constants::syntax_question,        /*?*/\n      regex_constants::syntax_char,        /*@*/\n      regex_constants::syntax_char,        /*A*/\n      regex_constants::syntax_char,        /*B*/\n      regex_constants::syntax_char,        /*C*/\n      regex_constants::syntax_char,        /*D*/\n      regex_constants::syntax_char,        /*E*/\n      regex_constants::syntax_char,        /*F*/\n      regex_constants::syntax_char,        /*G*/\n      regex_constants::syntax_char,        /*H*/\n      regex_constants::syntax_char,        /*I*/\n      regex_constants::syntax_char,        /*J*/\n      regex_constants::syntax_char,        /*K*/\n      regex_constants::syntax_char,        /*L*/\n      regex_constants::syntax_char,        /*M*/\n      regex_constants::syntax_char,        /*N*/\n      regex_constants::syntax_char,        /*O*/\n      regex_constants::syntax_char,        /*P*/\n      regex_constants::syntax_char,        /*Q*/\n      regex_constants::syntax_char,        /*R*/\n      regex_constants::syntax_char,        /*S*/\n      regex_constants::syntax_char,        /*T*/\n      regex_constants::syntax_char,        /*U*/\n      regex_constants::syntax_char,        /*V*/\n      regex_constants::syntax_char,        /*W*/\n      regex_constants::syntax_char,        /*X*/\n      regex_constants::syntax_char,        /*Y*/\n      regex_constants::syntax_char,        /*Z*/\n      regex_constants::syntax_open_set,        /*[*/\n      regex_constants::syntax_escape,        /*\\*/\n      regex_constants::syntax_close_set,        /*]*/\n      regex_constants::syntax_caret,        /*^*/\n      regex_constants::syntax_char,        /*_*/\n      regex_constants::syntax_char,        /*`*/\n      regex_constants::syntax_char,        /*a*/\n      regex_constants::syntax_char,        /*b*/\n      regex_constants::syntax_char,        /*c*/\n      regex_constants::syntax_char,        /*d*/\n      regex_constants::syntax_char,        /*e*/\n      regex_constants::syntax_char,        /*f*/\n      regex_constants::syntax_char,        /*g*/\n      regex_constants::syntax_char,        /*h*/\n      regex_constants::syntax_char,        /*i*/\n      regex_constants::syntax_char,        /*j*/\n      regex_constants::syntax_char,        /*k*/\n      regex_constants::syntax_char,        /*l*/\n      regex_constants::syntax_char,        /*m*/\n      regex_constants::syntax_char,        /*n*/\n      regex_constants::syntax_char,        /*o*/\n      regex_constants::syntax_char,        /*p*/\n      regex_constants::syntax_char,        /*q*/\n      regex_constants::syntax_char,        /*r*/\n      regex_constants::syntax_char,        /*s*/\n      regex_constants::syntax_char,        /*t*/\n      regex_constants::syntax_char,        /*u*/\n      regex_constants::syntax_char,        /*v*/\n      regex_constants::syntax_char,        /*w*/\n      regex_constants::syntax_char,        /*x*/\n      regex_constants::syntax_char,        /*y*/\n      regex_constants::syntax_char,        /*z*/\n      regex_constants::syntax_open_brace,        /*{*/\n      regex_constants::syntax_or,        /*|*/\n      regex_constants::syntax_close_brace,        /*}*/\n      regex_constants::syntax_char,        /*~*/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n   };\n\n   return char_syntax[(unsigned char)c];\n}\n\ninline regex_constants::escape_syntax_type BOOST_REGEX_CALL get_default_escape_syntax_type(char c)\n{\n   //\n   // char_syntax determines how the compiler treats a given character\n   // in a regular expression.\n   //\n   static regex_constants::escape_syntax_type char_syntax[] = {\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,     /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /* */    // 32\n      regex_constants::escape_type_identity,        /*!*/\n      regex_constants::escape_type_identity,        /*\"*/\n      regex_constants::escape_type_identity,        /*#*/\n      regex_constants::escape_type_identity,        /*$*/\n      regex_constants::escape_type_identity,        /*%*/\n      regex_constants::escape_type_identity,        /*&*/\n      regex_constants::escape_type_end_buffer,        /*'*/\n      regex_constants::syntax_open_mark,        /*(*/\n      regex_constants::syntax_close_mark,        /*)*/\n      regex_constants::escape_type_identity,        /***/\n      regex_constants::syntax_plus,                 /*+*/\n      regex_constants::escape_type_identity,        /*,*/\n      regex_constants::escape_type_identity,        /*-*/\n      regex_constants::escape_type_identity,        /*.*/\n      regex_constants::escape_type_identity,        /*/*/\n      regex_constants::escape_type_decimal,        /*0*/\n      regex_constants::escape_type_backref,        /*1*/\n      regex_constants::escape_type_backref,        /*2*/\n      regex_constants::escape_type_backref,        /*3*/\n      regex_constants::escape_type_backref,        /*4*/\n      regex_constants::escape_type_backref,        /*5*/\n      regex_constants::escape_type_backref,        /*6*/\n      regex_constants::escape_type_backref,        /*7*/\n      regex_constants::escape_type_backref,        /*8*/\n      regex_constants::escape_type_backref,        /*9*/\n      regex_constants::escape_type_identity,        /*:*/\n      regex_constants::escape_type_identity,        /*;*/\n      regex_constants::escape_type_left_word,        /*<*/\n      regex_constants::escape_type_identity,        /*=*/\n      regex_constants::escape_type_right_word,        /*>*/\n      regex_constants::syntax_question,              /*?*/\n      regex_constants::escape_type_identity,         /*@*/\n      regex_constants::escape_type_start_buffer,     /*A*/\n      regex_constants::escape_type_not_word_assert,  /*B*/\n      regex_constants::escape_type_C,                /*C*/\n      regex_constants::escape_type_not_class,        /*D*/\n      regex_constants::escape_type_E,                /*E*/\n      regex_constants::escape_type_not_class,        /*F*/\n      regex_constants::escape_type_G,                /*G*/\n      regex_constants::escape_type_not_class,        /*H*/\n      regex_constants::escape_type_not_class,        /*I*/\n      regex_constants::escape_type_not_class,        /*J*/\n      regex_constants::escape_type_reset_start_mark, /*K*/\n      regex_constants::escape_type_not_class,        /*L*/\n      regex_constants::escape_type_not_class,        /*M*/\n      regex_constants::escape_type_named_char,       /*N*/\n      regex_constants::escape_type_not_class,        /*O*/\n      regex_constants::escape_type_not_property,     /*P*/\n      regex_constants::escape_type_Q,                /*Q*/\n      regex_constants::escape_type_line_ending,      /*R*/\n      regex_constants::escape_type_not_class,        /*S*/\n      regex_constants::escape_type_not_class,        /*T*/\n      regex_constants::escape_type_not_class,        /*U*/\n      regex_constants::escape_type_not_class,        /*V*/\n      regex_constants::escape_type_not_class,        /*W*/\n      regex_constants::escape_type_X,                /*X*/\n      regex_constants::escape_type_not_class,        /*Y*/\n      regex_constants::escape_type_Z,                /*Z*/\n      regex_constants::escape_type_identity,        /*[*/\n      regex_constants::escape_type_identity,        /*\\*/\n      regex_constants::escape_type_identity,        /*]*/\n      regex_constants::escape_type_identity,        /*^*/\n      regex_constants::escape_type_identity,        /*_*/\n      regex_constants::escape_type_start_buffer,        /*`*/\n      regex_constants::escape_type_control_a,        /*a*/\n      regex_constants::escape_type_word_assert,        /*b*/\n      regex_constants::escape_type_ascii_control,        /*c*/\n      regex_constants::escape_type_class,        /*d*/\n      regex_constants::escape_type_e,        /*e*/\n      regex_constants::escape_type_control_f,       /*f*/\n      regex_constants::escape_type_extended_backref,  /*g*/\n      regex_constants::escape_type_class,        /*h*/\n      regex_constants::escape_type_class,        /*i*/\n      regex_constants::escape_type_class,        /*j*/\n      regex_constants::escape_type_extended_backref, /*k*/\n      regex_constants::escape_type_class,        /*l*/\n      regex_constants::escape_type_class,        /*m*/\n      regex_constants::escape_type_control_n,       /*n*/\n      regex_constants::escape_type_class,           /*o*/\n      regex_constants::escape_type_property,        /*p*/\n      regex_constants::escape_type_class,           /*q*/\n      regex_constants::escape_type_control_r,       /*r*/\n      regex_constants::escape_type_class,           /*s*/\n      regex_constants::escape_type_control_t,       /*t*/\n      regex_constants::escape_type_class,         /*u*/\n      regex_constants::escape_type_control_v,       /*v*/\n      regex_constants::escape_type_class,           /*w*/\n      regex_constants::escape_type_hex,             /*x*/\n      regex_constants::escape_type_class,           /*y*/\n      regex_constants::escape_type_end_buffer,      /*z*/\n      regex_constants::syntax_open_brace,           /*{*/\n      regex_constants::syntax_or,                   /*|*/\n      regex_constants::syntax_close_brace,          /*}*/\n      regex_constants::escape_type_identity,        /*~*/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n   };\n\n   return char_syntax[(unsigned char)c];\n}\n\n// is charT c a combining character?\ninline bool BOOST_REGEX_CALL is_combining_implementation(boost::uint_least16_t c)\n{\n   const boost::uint_least16_t combining_ranges[] = { 0x0300, 0x0361,\n                           0x0483, 0x0486,\n                           0x0903, 0x0903,\n                           0x093E, 0x0940,\n                           0x0949, 0x094C,\n                           0x0982, 0x0983,\n                           0x09BE, 0x09C0,\n                           0x09C7, 0x09CC,\n                           0x09D7, 0x09D7,\n                           0x0A3E, 0x0A40,\n                           0x0A83, 0x0A83,\n                           0x0ABE, 0x0AC0,\n                           0x0AC9, 0x0ACC,\n                           0x0B02, 0x0B03,\n                           0x0B3E, 0x0B3E,\n                           0x0B40, 0x0B40,\n                           0x0B47, 0x0B4C,\n                           0x0B57, 0x0B57,\n                           0x0B83, 0x0B83,\n                           0x0BBE, 0x0BBF,\n                           0x0BC1, 0x0BCC,\n                           0x0BD7, 0x0BD7,\n                           0x0C01, 0x0C03,\n                           0x0C41, 0x0C44,\n                           0x0C82, 0x0C83,\n                           0x0CBE, 0x0CBE,\n                           0x0CC0, 0x0CC4,\n                           0x0CC7, 0x0CCB,\n                           0x0CD5, 0x0CD6,\n                           0x0D02, 0x0D03,\n                           0x0D3E, 0x0D40,\n                           0x0D46, 0x0D4C,\n                           0x0D57, 0x0D57,\n                           0x0F7F, 0x0F7F,\n                           0x20D0, 0x20E1,\n                           0x3099, 0x309A,\n                           0xFE20, 0xFE23,\n                           0xffff, 0xffff, };\n\n   const boost::uint_least16_t* p = combining_ranges + 1;\n   while (*p < c) p += 2;\n   --p;\n   if ((c >= *p) && (c <= *(p + 1)))\n      return true;\n   return false;\n}\n\ntemplate <class charT>\ninline bool is_combining(charT c)\n{\n   return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));\n}\ntemplate <>\ninline bool is_combining<char>(char)\n{\n   return false;\n}\ntemplate <>\ninline bool is_combining<signed char>(signed char)\n{\n   return false;\n}\ntemplate <>\ninline bool is_combining<unsigned char>(unsigned char)\n{\n   return false;\n}\n#if !defined(__hpux) && !defined(__WINSCW__) // can't use WCHAR_MAX/MIN in pp-directives\n#ifdef _MSC_VER\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return is_combining_implementation(static_cast<unsigned short>(c));\n}\n#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\n#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return is_combining_implementation(static_cast<unsigned short>(c));\n}\n#else\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));\n}\n#endif\n#endif\n#endif\n\n//\n// is a charT c a line separator?\n//\ntemplate <class charT>\ninline bool is_separator(charT c)\n{\n   return BOOST_REGEX_MAKE_BOOL(\n      (c == static_cast<charT>('\\n'))\n      || (c == static_cast<charT>('\\r'))\n      || (c == static_cast<charT>('\\f'))\n      || (static_cast<boost::uint16_t>(c) == 0x2028u)\n      || (static_cast<boost::uint16_t>(c) == 0x2029u)\n      || (static_cast<boost::uint16_t>(c) == 0x85u));\n}\ntemplate <>\ninline bool is_separator<char>(char c)\n{\n   return BOOST_REGEX_MAKE_BOOL((c == '\\n') || (c == '\\r') || (c == '\\f'));\n}\n\n//\n// get a default collating element:\n//\ninline std::string BOOST_REGEX_CALL lookup_default_collate_name(const std::string& name)\n{\n   //\n   // these are the POSIX collating names:\n   //\n   static const char* def_coll_names[] = {\n   \"NUL\", \"SOH\", \"STX\", \"ETX\", \"EOT\", \"ENQ\", \"ACK\", \"alert\", \"backspace\", \"tab\", \"newline\",\n   \"vertical-tab\", \"form-feed\", \"carriage-return\", \"SO\", \"SI\", \"DLE\", \"DC1\", \"DC2\", \"DC3\", \"DC4\", \"NAK\",\n   \"SYN\", \"ETB\", \"CAN\", \"EM\", \"SUB\", \"ESC\", \"IS4\", \"IS3\", \"IS2\", \"IS1\", \"space\", \"exclamation-mark\",\n   \"quotation-mark\", \"number-sign\", \"dollar-sign\", \"percent-sign\", \"ampersand\", \"apostrophe\",\n   \"left-parenthesis\", \"right-parenthesis\", \"asterisk\", \"plus-sign\", \"comma\", \"hyphen\",\n   \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\",\n   \"colon\", \"semicolon\", \"less-than-sign\", \"equals-sign\", \"greater-than-sign\",\n   \"question-mark\", \"commercial-at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\",\n   \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"left-square-bracket\", \"backslash\",\n   \"right-square-bracket\", \"circumflex\", \"underscore\", \"grave-accent\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\",\n   \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"left-curly-bracket\",\n   \"vertical-line\", \"right-curly-bracket\", \"tilde\", \"DEL\", \"\",\n   };\n\n   // these multi-character collating elements\n   // should keep most Western-European locales\n   // happy - we should really localise these a\n   // little more - but this will have to do for\n   // now:\n\n   static const char* def_multi_coll[] = {\n      \"ae\",\n      \"Ae\",\n      \"AE\",\n      \"ch\",\n      \"Ch\",\n      \"CH\",\n      \"ll\",\n      \"Ll\",\n      \"LL\",\n      \"ss\",\n      \"Ss\",\n      \"SS\",\n      \"nj\",\n      \"Nj\",\n      \"NJ\",\n      \"dz\",\n      \"Dz\",\n      \"DZ\",\n      \"lj\",\n      \"Lj\",\n      \"LJ\",\n      \"\",\n   };\n\n   unsigned int i = 0;\n   while (*def_coll_names[i])\n   {\n      if (def_coll_names[i] == name)\n      {\n         return std::string(1, char(i));\n      }\n      ++i;\n   }\n   i = 0;\n   while (*def_multi_coll[i])\n   {\n      if (def_multi_coll[i] == name)\n      {\n         return def_multi_coll[i];\n      }\n      ++i;\n   }\n   return std::string();\n}\n\n//\n// get the state_id of a character classification, the individual\n// traits classes then transform that state_id into a bitmask:\n//\ntemplate <class charT>\nstruct character_pointer_range\n{\n   const charT* p1;\n   const charT* p2;\n\n   bool operator < (const character_pointer_range& r)const\n   {\n      return std::lexicographical_compare(p1, p2, r.p1, r.p2);\n   }\n   bool operator == (const character_pointer_range& r)const\n   {\n      // Not only do we check that the ranges are of equal size before\n      // calling std::equal, but there is no other algorithm available:\n      // not even a non-standard MS one.  So forward to unchecked_equal\n      // in the MS case.\n      return ((p2 - p1) == (r.p2 - r.p1)) && BOOST_REGEX_DETAIL_NS::equal(p1, p2, r.p1);\n   }\n};\ntemplate <class charT>\nint get_default_class_id(const charT* p1, const charT* p2)\n{\n   static const charT data[73] = {\n      'a', 'l', 'n', 'u', 'm',\n      'a', 'l', 'p', 'h', 'a',\n      'b', 'l', 'a', 'n', 'k',\n      'c', 'n', 't', 'r', 'l',\n      'd', 'i', 'g', 'i', 't',\n      'g', 'r', 'a', 'p', 'h',\n      'l', 'o', 'w', 'e', 'r',\n      'p', 'r', 'i', 'n', 't',\n      'p', 'u', 'n', 'c', 't',\n      's', 'p', 'a', 'c', 'e',\n      'u', 'n', 'i', 'c', 'o', 'd', 'e',\n      'u', 'p', 'p', 'e', 'r',\n      'v',\n      'w', 'o', 'r', 'd',\n      'x', 'd', 'i', 'g', 'i', 't',\n   };\n\n   static const character_pointer_range<charT> ranges[21] =\n   {\n      {data+0, data+5,}, // alnum\n      {data+5, data+10,}, // alpha\n      {data+10, data+15,}, // blank\n      {data+15, data+20,}, // cntrl\n      {data+20, data+21,}, // d\n      {data+20, data+25,}, // digit\n      {data+25, data+30,}, // graph\n      {data+29, data+30,}, // h\n      {data+30, data+31,}, // l\n      {data+30, data+35,}, // lower\n      {data+35, data+40,}, // print\n      {data+40, data+45,}, // punct\n      {data+45, data+46,}, // s\n      {data+45, data+50,}, // space\n      {data+57, data+58,}, // u\n      {data+50, data+57,}, // unicode\n      {data+57, data+62,}, // upper\n      {data+62, data+63,}, // v\n      {data+63, data+64,}, // w\n      {data+63, data+67,}, // word\n      {data+67, data+73,}, // xdigit\n   };\n   const character_pointer_range<charT>* ranges_begin = ranges;\n   const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));\n\n   character_pointer_range<charT> t = { p1, p2, };\n   const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);\n   if((p != ranges_end) && (t == *p))\n      return static_cast<int>(p - ranges);\n   return -1;\n}\n\n//\n// helper functions:\n//\ntemplate <class charT>\nstd::ptrdiff_t global_length(const charT* p)\n{\n   std::ptrdiff_t n = 0;\n   while(*p)\n   {\n      ++p;\n      ++n;\n   }\n   return n;\n}\ntemplate<>\ninline std::ptrdiff_t global_length<char>(const char* p)\n{\n   return (std::strlen)(p);\n}\n#ifndef BOOST_NO_WREGEX\ntemplate<>\ninline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)\n{\n   return (std::ptrdiff_t)(std::wcslen)(p);\n}\n#endif\ntemplate <class charT>\ninline charT BOOST_REGEX_CALL global_lower(charT c)\n{\n   return c;\n}\ntemplate <class charT>\ninline charT BOOST_REGEX_CALL global_upper(charT c)\n{\n   return c;\n}\n\ninline char BOOST_REGEX_CALL do_global_lower(char c)\n{\n   return static_cast<char>((std::tolower)((unsigned char)c));\n}\n\ninline char BOOST_REGEX_CALL do_global_upper(char c)\n{\n   return static_cast<char>((std::toupper)((unsigned char)c));\n}\n#ifndef BOOST_NO_WREGEX\ninline wchar_t BOOST_REGEX_CALL do_global_lower(wchar_t c)\n{\n   return (std::towlower)(c);\n}\n\ninline wchar_t BOOST_REGEX_CALL do_global_upper(wchar_t c)\n{\n   return (std::towupper)(c);\n}\n#endif\n//\n// This sucks: declare template specialisations of global_lower/global_upper\n// that just forward to the non-template implementation functions.  We do\n// this because there is one compiler (Compaq Tru64 C++) that doesn't seem\n// to differentiate between templates and non-template overloads....\n// what's more, the primary template, plus all overloads have to be\n// defined in the same translation unit (if one is inline they all must be)\n// otherwise the \"local template instantiation\" compiler option can pick\n// the wrong instantiation when linking:\n//\ntemplate<> inline char BOOST_REGEX_CALL global_lower<char>(char c) { return do_global_lower(c); }\ntemplate<> inline char BOOST_REGEX_CALL global_upper<char>(char c) { return do_global_upper(c); }\n#ifndef BOOST_NO_WREGEX\ntemplate<> inline wchar_t BOOST_REGEX_CALL global_lower<wchar_t>(wchar_t c) { return do_global_lower(c); }\ntemplate<> inline wchar_t BOOST_REGEX_CALL global_upper<wchar_t>(wchar_t c) { return do_global_upper(c); }\n#endif\n\ntemplate <class charT>\nint global_value(charT c)\n{\n   static const charT zero = '0';\n   static const charT nine = '9';\n   static const charT a = 'a';\n   static const charT f = 'f';\n   static const charT A = 'A';\n   static const charT F = 'F';\n\n   if(c > f) return -1;\n   if(c >= a) return 10 + (c - a);\n   if(c > F) return -1;\n   if(c >= A) return 10 + (c - A);\n   if(c > nine) return -1;\n   if(c >= zero) return c - zero;\n   return -1;\n}\ntemplate <class charT, class traits>\nboost::intmax_t global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)\n{\n   (void)t; // warning suppression\n   boost::intmax_t limit = (std::numeric_limits<boost::intmax_t>::max)() / radix;\n   boost::intmax_t next_value = t.value(*p1, radix);\n   if((p1 == p2) || (next_value < 0) || (next_value >= radix))\n      return -1;\n   boost::intmax_t result = 0;\n   while(p1 != p2)\n   {\n      next_value = t.value(*p1, radix);\n      if((next_value < 0) || (next_value >= radix))\n         break;\n      result *= radix;\n      result += next_value;\n      ++p1;\n      if (result > limit)\n         return -1;\n   }\n   return result;\n}\n\ntemplate <class charT>\ninline typename boost::enable_if_c<(sizeof(charT) > 1), const charT*>::type get_escape_R_string()\n{\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4309 4245)\n#endif\n   static const charT e1[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\\x0D', '\\x0A', '?',\n      '|', '[', '\\x0A', '\\x0B', '\\x0C', static_cast<charT>(0x85), static_cast<charT>(0x2028),\n      static_cast<charT>(0x2029), ']', ')', ')', '\\0' };\n   static const charT e2[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\\x0D', '\\x0A', '?',\n      '|', '[', '\\x0A', '\\x0B', '\\x0C', static_cast<charT>(0x85), ']', ')', ')', '\\0' };\n\n   charT c = static_cast<charT>(0x2029u);\n   bool b = (static_cast<unsigned>(c) == 0x2029u);\n\n   return (b ? e1 : e2);\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n}\n\ntemplate <class charT>\ninline typename boost::disable_if_c<(sizeof(charT) > 1), const charT*>::type get_escape_R_string()\n{\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4309)\n#endif\n   static const charT e2[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\\x0D', '\\x0A', '?',\n      '|', '[', '\\x0A', '\\x0B', '\\x0C', '\\x85', ']', ')', ')', '\\0' };\n   return e2;\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n}\n\n} // BOOST_REGEX_DETAIL_NS\n} // boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/regex_workaround.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2005\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_workarounds.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares Misc workarounds.\n  */\n\n#ifndef BOOST_REGEX_WORKAROUND_HPP\n#define BOOST_REGEX_WORKAROUND_HPP\n\n#include <boost/config.hpp>\n#include <new>\n#include <cstring>\n#include <cstdlib>\n#include <cstddef>\n#include <cassert>\n#include <cstdio>\n#include <climits>\n#include <string>\n#include <stdexcept>\n#include <iterator>\n#include <algorithm>\n#include <iosfwd>\n#include <vector>\n#include <set>\n#include <map>\n#include <boost/limits.hpp>\n#include <boost/assert.hpp>\n#include <boost/cstdint.hpp>\n#include <boost/throw_exception.hpp>\n#include <boost/scoped_ptr.hpp>\n#include <boost/scoped_array.hpp>\n#include <boost/shared_ptr.hpp>\n#include <boost/mpl/bool_fwd.hpp>\n#include <boost/regex/config.hpp>\n#ifndef BOOST_NO_STD_LOCALE\n#   include <locale>\n#endif\n\n#if defined(BOOST_NO_STDC_NAMESPACE)\nnamespace std{\n   using ::sprintf; using ::strcpy; using ::strcat; using ::strlen;\n}\n#endif\n\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n#ifdef BOOST_NO_STD_DISTANCE\ntemplate <class T>\nstd::ptrdiff_t distance(const T& x, const T& y)\n{ return y - x; }\n#else\nusing std::distance;\n#endif\n}}\n\n\n#ifdef BOOST_REGEX_NO_BOOL\n#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)\n#else\n#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)\n#endif\n\n/*****************************************************************************\n *\n *  Fix broken namespace support:\n *\n ****************************************************************************/\n\n#if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)\n\nnamespace std{\n   using ::ptrdiff_t;\n   using ::size_t;\n   using ::abs;\n   using ::memset;\n   using ::memcpy;\n}\n\n#endif\n\n/*****************************************************************************\n *\n *  helper functions pointer_construct/pointer_destroy:\n *\n ****************************************************************************/\n\n#ifdef __cplusplus\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_MSVC\n#pragma warning (push)\n#pragma warning (disable : 4100)\n#endif\n\ntemplate <class T>\ninline void pointer_destroy(T* p)\n{ p->~T(); (void)p; }\n\n#ifdef BOOST_MSVC\n#pragma warning (pop)\n#endif\n\ntemplate <class T>\ninline void pointer_construct(T* p, const T& t)\n{ new (p) T(t); }\n\n}} // namespaces\n#endif\n\n/*****************************************************************************\n *\n *  helper function copy:\n *\n ****************************************************************************/\n\n#ifdef __cplusplus\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n#if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && BOOST_WORKAROUND(BOOST_MSVC, <1600) && defined(_CPPLIB_VER) && defined(BOOST_DINKUMWARE_STDLIB) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))\n   //\n   // MSVC 8 will either emit warnings or else refuse to compile\n   // code that makes perfectly legitimate use of std::copy, when\n   // the OutputIterator type is a user-defined class (apparently all user \n   // defined iterators are \"unsafe\").  This code works around that:\n   //\n   template<class InputIterator, class OutputIterator>\n   inline OutputIterator copy(\n      InputIterator first, \n      InputIterator last, \n      OutputIterator dest\n   )\n   {\n      return stdext::unchecked_copy(first, last, dest);\n   }\n   template<class InputIterator1, class InputIterator2>\n   inline bool equal(\n      InputIterator1 first, \n      InputIterator1 last, \n      InputIterator2 with\n   )\n   {\n      return stdext::unchecked_equal(first, last, with);\n   }\n#elif BOOST_WORKAROUND(BOOST_MSVC, > 1500)\n   //\n   // MSVC 10 will either emit warnings or else refuse to compile\n   // code that makes perfectly legitimate use of std::copy, when\n   // the OutputIterator type is a user-defined class (apparently all user \n   // defined iterators are \"unsafe\").  What's more Microsoft have removed their\n   // non-standard \"unchecked\" versions, even though their still in the MS\n   // documentation!! Work around this as best we can: \n   //\n   template<class InputIterator, class OutputIterator>\n   inline OutputIterator copy(\n      InputIterator first, \n      InputIterator last, \n      OutputIterator dest\n   )\n   {\n      while(first != last)\n         *dest++ = *first++;\n      return dest;\n   }\n   template<class InputIterator1, class InputIterator2>\n   inline bool equal(\n      InputIterator1 first, \n      InputIterator1 last, \n      InputIterator2 with\n   )\n   {\n      while(first != last)\n         if(*first++ != *with++) return false;\n      return true;\n   }\n#else \n   using std::copy; \n   using std::equal; \n#endif \n#if BOOST_WORKAROUND(BOOST_MSVC,>=1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__ \n\n   // use safe versions of strcpy etc:\n   using ::strcpy_s;\n   using ::strcat_s;\n#else\n   inline std::size_t strcpy_s(\n      char *strDestination,\n      std::size_t sizeInBytes,\n      const char *strSource \n   )\n   {\n     std::size_t lenSourceWithNull = std::strlen(strSource) + 1;\n     if (lenSourceWithNull > sizeInBytes)\n         return 1;\n     std::memcpy(strDestination, strSource, lenSourceWithNull);\n      return 0;\n   }\n   inline std::size_t strcat_s(\n      char *strDestination,\n      std::size_t sizeInBytes,\n      const char *strSource \n   )\n   {\n     std::size_t lenSourceWithNull = std::strlen(strSource) + 1;\n     std::size_t lenDestination = std::strlen(strDestination);\n     if (lenSourceWithNull + lenDestination > sizeInBytes)\n         return 1;\n     std::memcpy(strDestination + lenDestination, strSource, lenSourceWithNull);\n      return 0;\n   }\n\n#endif\n\n   inline void overflow_error_if_not_zero(std::size_t i)\n   {\n      if(i)\n      {\n         std::overflow_error e(\"String buffer too small\");\n         boost::throw_exception(e);\n      }\n   }\n\n}} // namespaces\n\n#endif // __cplusplus\n\n#endif // include guard\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/states.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         states.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares internal state machine structures.\n  */\n\n#ifndef BOOST_REGEX_V4_STATES_HPP\n#define BOOST_REGEX_V4_STATES_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n/*** mask_type *******************************************************\nWhenever we have a choice of two alternatives, we use an array of bytes\nto indicate which of the two alternatives it is possible to take for any\ngiven input character.  If mask_take is set, then we can take the next \nstate, and if mask_skip is set then we can take the alternative.\n***********************************************************************/\nenum mask_type\n{\n   mask_take = 1,\n   mask_skip = 2,\n   mask_init = 4,\n   mask_any = mask_skip | mask_take,\n   mask_all = mask_any\n};\n\n/*** helpers **********************************************************\nThese helpers let us use function overload resolution to detect whether\nwe have narrow or wide character strings:\n***********************************************************************/\nstruct _narrow_type{};\nstruct _wide_type{};\ntemplate <class charT> struct is_byte;\ntemplate<>             struct is_byte<char>         { typedef _narrow_type width_type; };\ntemplate<>             struct is_byte<unsigned char>{ typedef _narrow_type width_type; };\ntemplate<>             struct is_byte<signed char>  { typedef _narrow_type width_type; };\ntemplate <class charT> struct is_byte               { typedef _wide_type width_type; };\n\n/*** enum syntax_element_type ******************************************\nEvery record in the state machine falls into one of the following types:\n***********************************************************************/\nenum syntax_element_type\n{\n   // start of a marked sub-expression, or perl-style (?...) extension\n   syntax_element_startmark = 0,\n   // end of a marked sub-expression, or perl-style (?...) extension\n   syntax_element_endmark = syntax_element_startmark + 1,\n   // any sequence of literal characters\n   syntax_element_literal = syntax_element_endmark + 1,\n   // start of line assertion: ^\n   syntax_element_start_line = syntax_element_literal + 1,\n   // end of line assertion $\n   syntax_element_end_line = syntax_element_start_line + 1,\n   // match any character: .\n   syntax_element_wild = syntax_element_end_line + 1,\n   // end of expression: we have a match when we get here\n   syntax_element_match = syntax_element_wild + 1,\n   // perl style word boundary: \\b\n   syntax_element_word_boundary = syntax_element_match + 1,\n   // perl style within word boundary: \\B\n   syntax_element_within_word = syntax_element_word_boundary + 1,\n   // start of word assertion: \\<\n   syntax_element_word_start = syntax_element_within_word + 1,\n   // end of word assertion: \\>\n   syntax_element_word_end = syntax_element_word_start + 1,\n   // start of buffer assertion: \\`\n   syntax_element_buffer_start = syntax_element_word_end + 1,\n   // end of buffer assertion: \\'\n   syntax_element_buffer_end = syntax_element_buffer_start + 1,\n   // backreference to previously matched sub-expression\n   syntax_element_backref = syntax_element_buffer_end + 1,\n   // either a wide character set [..] or one with multicharacter collating elements:\n   syntax_element_long_set = syntax_element_backref + 1,\n   // narrow character set: [...]\n   syntax_element_set = syntax_element_long_set + 1,\n   // jump to a new state in the machine:\n   syntax_element_jump = syntax_element_set + 1,\n   // choose between two production states:\n   syntax_element_alt = syntax_element_jump + 1,\n   // a repeat\n   syntax_element_rep = syntax_element_alt + 1,\n   // match a combining character sequence\n   syntax_element_combining = syntax_element_rep + 1,\n   // perl style soft buffer end: \\z\n   syntax_element_soft_buffer_end = syntax_element_combining + 1,\n   // perl style continuation: \\G\n   syntax_element_restart_continue = syntax_element_soft_buffer_end + 1,\n   // single character repeats:\n   syntax_element_dot_rep = syntax_element_restart_continue + 1,\n   syntax_element_char_rep = syntax_element_dot_rep + 1,\n   syntax_element_short_set_rep = syntax_element_char_rep + 1,\n   syntax_element_long_set_rep = syntax_element_short_set_rep + 1,\n   // a backstep for lookbehind repeats:\n   syntax_element_backstep = syntax_element_long_set_rep + 1,\n   // an assertion that a mark was matched:\n   syntax_element_assert_backref = syntax_element_backstep + 1,\n   syntax_element_toggle_case = syntax_element_assert_backref + 1,\n   // a recursive expression:\n   syntax_element_recurse = syntax_element_toggle_case + 1,\n   // Verbs:\n   syntax_element_fail = syntax_element_recurse + 1,\n   syntax_element_accept = syntax_element_fail + 1,\n   syntax_element_commit = syntax_element_accept + 1,\n   syntax_element_then = syntax_element_commit + 1\n};\n\n#ifdef BOOST_REGEX_DEBUG\n// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion\nstd::ostream& operator<<(std::ostream&, syntax_element_type);\n#endif\n\nstruct re_syntax_base;\n\n/*** union offset_type ************************************************\nPoints to another state in the machine.  During machine construction\nwe use integral offsets, but these are converted to pointers before\nexecution of the machine.\n***********************************************************************/\nunion offset_type\n{\n   re_syntax_base*   p;\n   std::ptrdiff_t    i;\n};\n\n/*** struct re_syntax_base ********************************************\nBase class for all states in the machine.\n***********************************************************************/\nstruct re_syntax_base\n{\n   syntax_element_type   type;         // what kind of state this is\n   offset_type           next;         // next state in the machine\n};\n\n/*** struct re_brace **************************************************\nA marked parenthesis.\n***********************************************************************/\nstruct re_brace : public re_syntax_base\n{\n   // The index to match, can be zero (don't mark the sub-expression)\n   // or negative (for perl style (?...) extensions):\n   int index;\n   bool icase;\n};\n\n/*** struct re_dot **************************************************\nMatch anything.\n***********************************************************************/\nenum\n{\n   dont_care = 1,\n   force_not_newline = 0,\n   force_newline = 2,\n\n   test_not_newline = 2,\n   test_newline = 3\n};\nstruct re_dot : public re_syntax_base\n{\n   unsigned char mask;\n};\n\n/*** struct re_literal ************************************************\nA string of literals, following this structure will be an \narray of characters: charT[length]\n***********************************************************************/\nstruct re_literal : public re_syntax_base\n{\n   unsigned int length;\n};\n\n/*** struct re_case ************************************************\nIndicates whether we are moving to a case insensive block or not\n***********************************************************************/\nstruct re_case : public re_syntax_base\n{\n   bool icase;\n};\n\n/*** struct re_set_long ***********************************************\nA wide character set of characters, following this structure will be\nan array of type charT:\nFirst csingles null-terminated strings\nThen 2 * cranges NULL terminated strings\nThen cequivalents NULL terminated strings\n***********************************************************************/\ntemplate <class mask_type>\nstruct re_set_long : public re_syntax_base\n{\n   unsigned int            csingles, cranges, cequivalents;\n   mask_type               cclasses;\n   mask_type               cnclasses;\n   bool                    isnot;\n   bool                    singleton;\n};\n\n/*** struct re_set ****************************************************\nA set of narrow-characters, matches any of _map which is none-zero\n***********************************************************************/\nstruct re_set : public re_syntax_base\n{\n   unsigned char _map[1 << CHAR_BIT];\n};\n\n/*** struct re_jump ***************************************************\nJump to a new location in the machine (not next).\n***********************************************************************/\nstruct re_jump : public re_syntax_base\n{\n   offset_type     alt;                 // location to jump to\n};\n\n/*** struct re_alt ***************************************************\nJump to a new location in the machine (possibly next).\n***********************************************************************/\nstruct re_alt : public re_jump\n{\n   unsigned char   _map[1 << CHAR_BIT]; // which characters can take the jump\n   unsigned int    can_be_null;         // true if we match a NULL string\n};\n\n/*** struct re_repeat *************************************************\nRepeat a section of the machine\n***********************************************************************/\nstruct re_repeat : public re_alt\n{\n   std::size_t   min, max;  // min and max allowable repeats\n   int           state_id;        // Unique identifier for this repeat\n   bool          leading;   // True if this repeat is at the start of the machine (lets us optimize some searches)\n   bool          greedy;    // True if this is a greedy repeat\n};\n\n/*** struct re_recurse ************************************************\nRecurse to a particular subexpression.\n**********************************************************************/\nstruct re_recurse : public re_jump\n{\n   int state_id;             // identifier of first nested repeat within the recursion.\n};\n\n/*** struct re_commit *************************************************\nUsed for the PRUNE, SKIP and COMMIT verbs which basically differ only in what happens\nif no match is found and we start searching forward.\n**********************************************************************/\nenum commit_type\n{\n   commit_prune,\n   commit_skip,\n   commit_commit\n};\nstruct re_commit : public re_syntax_base\n{\n   commit_type action;\n};\n\n/*** enum re_jump_size_type *******************************************\nProvides compiled size of re_jump structure (allowing for trailing alignment).\nWe provide this so we know how manybytes to insert when constructing the machine\n(The value of padding_mask is defined in regex_raw_buffer.hpp).\n***********************************************************************/\nenum re_jump_size_type\n{\n   re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),\n   re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask),\n   re_alt_size = (sizeof(re_alt) + padding_mask) & ~(padding_mask)\n};\n\n/*** proc re_is_set_member *********************************************\nForward declaration: we'll need this one later...\n***********************************************************************/\n\ntemplate<class charT, class traits>\nstruct regex_data;\n\ntemplate <class iterator, class charT, class traits_type, class char_classT>\niterator BOOST_REGEX_CALL re_is_set_member(iterator next, \n                          iterator last, \n                          const re_set_long<char_classT>* set_, \n                          const regex_data<charT, traits_type>& e, bool icase);\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/sub_match.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         sub_match.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class sub_match.\n  */\n\n#ifndef BOOST_REGEX_V4_SUB_MATCH_HPP\n#define BOOST_REGEX_V4_SUB_MATCH_HPP\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\nnamespace boost{\n\ntemplate <class BidiIterator>\nstruct sub_match : public std::pair<BidiIterator, BidiIterator>\n{\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidiIterator>::value_type       value_type;\n#if defined(BOOST_NO_STD_ITERATOR_TRAITS)\n   typedef          std::ptrdiff_t                                                   difference_type;\n#else\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidiIterator>::difference_type  difference_type;\n#endif\n   typedef          BidiIterator                                                     iterator_type;\n   typedef          BidiIterator                                                     iterator;\n   typedef          BidiIterator                                                     const_iterator;\n\n   bool matched;\n\n   sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}\n   sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}\n#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\\\n               && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0551)\\\n               && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))\n   template <class T, class A>\n   operator std::basic_string<value_type, T, A> ()const\n   {\n      return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>();\n   }\n#else\n   operator std::basic_string<value_type> ()const\n   {\n      return str();\n   }\n#endif\n   difference_type BOOST_REGEX_CALL length()const\n   {\n      difference_type n = matched ? ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0;\n      return n;\n   }\n   std::basic_string<value_type> str()const\n   {\n      std::basic_string<value_type> result;\n      if(matched)\n      {\n         std::size_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)this->first, (BidiIterator)this->second);\n         result.reserve(len);\n         BidiIterator i = this->first;\n         while(i != this->second)\n         {\n            result.append(1, *i);\n            ++i;\n         }\n      }\n      return result;\n   }\n   int compare(const sub_match& s)const\n   {\n      if(matched != s.matched)\n         return static_cast<int>(matched) - static_cast<int>(s.matched);\n      return str().compare(s.str());\n   }\n   int compare(const std::basic_string<value_type>& s)const\n   {\n      return str().compare(s);\n   }\n   int compare(const value_type* p)const\n   {\n      return str().compare(p);\n   }\n\n   bool operator==(const sub_match& that)const\n   { return compare(that) == 0; }\n   bool BOOST_REGEX_CALL operator !=(const sub_match& that)const\n   { return compare(that) != 0; }\n   bool operator<(const sub_match& that)const\n   { return compare(that) < 0; }\n   bool operator>(const sub_match& that)const\n   { return compare(that) > 0; }\n   bool operator<=(const sub_match& that)const\n   { return compare(that) <= 0; }\n   bool operator>=(const sub_match& that)const\n   { return compare(that) >= 0; }\n\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;\n\n   const capture_sequence_type& captures()const\n   {\n      if(!m_captures) \n         m_captures.reset(new capture_sequence_type());\n      return *m_captures;\n   }\n   //\n   // Private implementation API: DO NOT USE!\n   //\n   capture_sequence_type& get_captures()const\n   {\n      if(!m_captures) \n         m_captures.reset(new capture_sequence_type());\n      return *m_captures;\n   }\n\nprivate:\n   mutable boost::scoped_ptr<capture_sequence_type> m_captures;\npublic:\n\n#endif\n   sub_match(const sub_match& that, bool \n#ifdef BOOST_REGEX_MATCH_EXTRA\n      deep_copy\n#endif\n      = true\n      ) \n      : std::pair<BidiIterator, BidiIterator>(that), \n        matched(that.matched) \n   {\n#ifdef BOOST_REGEX_MATCH_EXTRA\n      if(that.m_captures)\n         if(deep_copy)\n            m_captures.reset(new capture_sequence_type(*(that.m_captures)));\n#endif\n   }\n   sub_match& operator=(const sub_match& that)\n   {\n      this->first = that.first;\n      this->second = that.second;\n      matched = that.matched;\n#ifdef BOOST_REGEX_MATCH_EXTRA\n      if(that.m_captures)\n         get_captures() = *(that.m_captures);\n#endif\n      return *this;\n   }\n   //\n   // Make this type a range, for both Boost.Range, and C++11:\n   //\n   BidiIterator begin()const { return this->first; }\n   BidiIterator end()const { return this->second; }\n\n\n#ifdef BOOST_OLD_REGEX_H\n   //\n   // the following are deprecated, do not use!!\n   //\n   operator int()const;\n   operator unsigned int()const;\n   operator short()const\n   {\n      return (short)(int)(*this);\n   }\n   operator unsigned short()const\n   {\n      return (unsigned short)(unsigned int)(*this);\n   }\n#endif\n};\n\ntypedef sub_match<const char*> csub_match;\ntypedef sub_match<std::string::const_iterator> ssub_match;\n#ifndef BOOST_NO_WREGEX\ntypedef sub_match<const wchar_t*> wcsub_match;\ntypedef sub_match<std::wstring::const_iterator> wssub_match;\n#endif\n\n// comparison to std::basic_string<> part 1:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator == (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) == 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator != (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) != 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator < (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                 const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) < 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator <= (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) <= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator >= (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) >= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator > (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                 const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) > 0; }\n// comparison to std::basic_string<> part 2:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) <= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) >= 0; }\n// comparison to const charT* part 1:\ntemplate <class RandomAccessIterator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) <= 0; }\n// comparison to const charT* part 2:\ntemplate <class RandomAccessIterator>\ninline bool operator == (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) <= 0; }\n\n// comparison to const charT& part 1:\ntemplate <class RandomAccessIterator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) <= 0; }\n// comparison to const charT* part 2:\ntemplate <class RandomAccessIterator>\ninline bool operator == (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) <= 0; }\n\n// addition operators:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> \noperator + (const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;\n   result.reserve(s.size() + m.length() + 1);\n   return result.append(s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> \noperator + (const sub_match<RandomAccessIterator>& m,\n            const std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;\n   result.reserve(s.size() + m.length() + 1);\n   return result.append(m.first, m.second).append(s);\n}\n#if !(defined(__GNUC__) && defined(BOOST_NO_STD_LOCALE))\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(std::char_traits<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);\n   return result.append(s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m,\n            typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const * s)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(std::char_traits<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);\n   return result.append(m.first, m.second).append(s);\n}\n#else\n// worwaround versions:\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   return s + m.str();\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m,\n            typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const * s)\n{\n   return m.str() + s;\n}\n#endif\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m.length() + 2);\n   return result.append(1, s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m,\n            typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type const& s)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m.length() + 2);\n   return result.append(m.first, m.second).append(1, s);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m1,\n            const sub_match<RandomAccessIterator>& m2)\n{\n   std::basic_string<typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m1.length() + m2.length() + 1);\n   return result.append(m1.first, m1.second).append(m2.first, m2.second);\n}\n#ifndef BOOST_NO_STD_LOCALE\ntemplate <class charT, class traits, class RandomAccessIterator>\nstd::basic_ostream<charT, traits>&\n   operator << (std::basic_ostream<charT, traits>& os,\n                const sub_match<RandomAccessIterator>& s)\n{\n   return (os << s.str());\n}\n#else\ntemplate <class RandomAccessIterator>\nstd::ostream& operator << (std::ostream& os,\n                           const sub_match<RandomAccessIterator>& s)\n{\n   return (os << s.str());\n}\n#endif\n\n#ifdef BOOST_OLD_REGEX_H\nnamespace BOOST_REGEX_DETAIL_NS{\ntemplate <class BidiIterator, class charT>\nint do_toi(BidiIterator i, BidiIterator j, char c, int radix)\n{\n   std::string s(i, j);\n   char* p;\n   int result = std::strtol(s.c_str(), &p, radix);\n   if(*p)raise_regex_exception(\"Bad sub-expression\");\n   return result;\n}\n\n//\n// helper:\ntemplate <class I, class charT>\nint do_toi(I& i, I j, charT c)\n{\n   int result = 0;\n   while((i != j) && (isdigit(*i)))\n   {\n      result = result*10 + (*i - '0');\n      ++i;\n   }\n   return result;\n}\n}\n\n\ntemplate <class BidiIterator>\nsub_match<BidiIterator>::operator int()const\n{\n   BidiIterator i = first;\n   BidiIterator j = second;\n   if(i == j)raise_regex_exception(\"Bad sub-expression\");\n   int neg = 1;\n   if((i != j) && (*i == '-'))\n   {\n      neg = -1;\n      ++i;\n   }\n   neg *= BOOST_REGEX_DETAIL_NS::do_toi(i, j, *i);\n   if(i != j)raise_regex_exception(\"Bad sub-expression\");\n   return neg;\n}\ntemplate <class BidiIterator>\nsub_match<BidiIterator>::operator unsigned int()const\n{\n   BidiIterator i = first;\n   BidiIterator j = second;\n   if(i == j)\n      raise_regex_exception(\"Bad sub-expression\");\n   return BOOST_REGEX_DETAIL_NS::do_toi(i, j, *first);\n}\n#endif\n\n} // namespace boost\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/syntax_type.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         syntax_type.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression synatx type enumerator.\n  */\n\n#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP\n#define BOOST_REGEX_SYNTAX_TYPE_HPP\n\nnamespace boost{\nnamespace regex_constants{\n\ntypedef unsigned char syntax_type;\n\n//\n// values chosen are binary compatible with previous version:\n//\nstatic const syntax_type syntax_char = 0;\nstatic const syntax_type syntax_open_mark = 1;\nstatic const syntax_type syntax_close_mark = 2;\nstatic const syntax_type syntax_dollar = 3;\nstatic const syntax_type syntax_caret = 4;\nstatic const syntax_type syntax_dot = 5;\nstatic const syntax_type syntax_star = 6;\nstatic const syntax_type syntax_plus = 7;\nstatic const syntax_type syntax_question = 8;\nstatic const syntax_type syntax_open_set = 9;\nstatic const syntax_type syntax_close_set = 10;\nstatic const syntax_type syntax_or = 11;\nstatic const syntax_type syntax_escape = 12;\nstatic const syntax_type syntax_dash = 14;\nstatic const syntax_type syntax_open_brace = 15;\nstatic const syntax_type syntax_close_brace = 16;\nstatic const syntax_type syntax_digit = 17;\nstatic const syntax_type syntax_comma = 27;\nstatic const syntax_type syntax_equal = 37;\nstatic const syntax_type syntax_colon = 36;\nstatic const syntax_type syntax_not = 53;\n\n// extensions:\n\nstatic const syntax_type syntax_hash = 13;\nstatic const syntax_type syntax_newline = 26;\n\n// escapes:\n\ntypedef syntax_type escape_syntax_type;\n\nstatic const escape_syntax_type escape_type_word_assert = 18;\nstatic const escape_syntax_type escape_type_not_word_assert = 19;\nstatic const escape_syntax_type escape_type_control_f = 29;\nstatic const escape_syntax_type escape_type_control_n = 30;\nstatic const escape_syntax_type escape_type_control_r = 31;\nstatic const escape_syntax_type escape_type_control_t = 32;\nstatic const escape_syntax_type escape_type_control_v = 33;\nstatic const escape_syntax_type escape_type_ascii_control = 35;\nstatic const escape_syntax_type escape_type_hex = 34;\nstatic const escape_syntax_type escape_type_unicode = 0; // not used\nstatic const escape_syntax_type escape_type_identity = 0; // not used\nstatic const escape_syntax_type escape_type_backref = syntax_digit;\nstatic const escape_syntax_type escape_type_decimal = syntax_digit; // not used\nstatic const escape_syntax_type escape_type_class = 22; \nstatic const escape_syntax_type escape_type_not_class = 23; \n\n// extensions:\n\nstatic const escape_syntax_type escape_type_left_word = 20;\nstatic const escape_syntax_type escape_type_right_word = 21;\nstatic const escape_syntax_type escape_type_start_buffer = 24;                 // for \\`\nstatic const escape_syntax_type escape_type_end_buffer = 25;                   // for \\'\nstatic const escape_syntax_type escape_type_control_a = 28;                    // for \\a\nstatic const escape_syntax_type escape_type_e = 38;                            // for \\e\nstatic const escape_syntax_type escape_type_E = 47;                            // for \\Q\\E\nstatic const escape_syntax_type escape_type_Q = 48;                            // for \\Q\\E\nstatic const escape_syntax_type escape_type_X = 49;                            // for \\X\nstatic const escape_syntax_type escape_type_C = 50;                            // for \\C\nstatic const escape_syntax_type escape_type_Z = 51;                            // for \\Z\nstatic const escape_syntax_type escape_type_G = 52;                            // for \\G\n\nstatic const escape_syntax_type escape_type_property = 54;                     // for \\p\nstatic const escape_syntax_type escape_type_not_property = 55;                 // for \\P\nstatic const escape_syntax_type escape_type_named_char = 56;                   // for \\N\nstatic const escape_syntax_type escape_type_extended_backref = 57;             // for \\g\nstatic const escape_syntax_type escape_type_reset_start_mark = 58;             // for \\K\nstatic const escape_syntax_type escape_type_line_ending = 59;                  // for \\R\n\nstatic const escape_syntax_type syntax_max = 60;\n\n}\n}\n\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/u32regex_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         u32regex_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides u32regex_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_U32REGEX_ITERATOR_HPP\n#define BOOST_REGEX_V4_U32REGEX_ITERATOR_HPP\n\nnamespace boost{\n\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n\ntemplate <class BidirectionalIterator>\nclass u32regex_iterator_implementation \n{\n   typedef u32regex regex_type;\n\n   match_results<BidirectionalIterator> what;  // current match\n   BidirectionalIterator                base;  // start of sequence\n   BidirectionalIterator                end;   // end of sequence\n   const regex_type                     re;   // the expression\n   match_flag_type                      flags; // flags for matching\n\npublic:\n   u32regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)\n      : base(), end(last), re(*p), flags(f){}\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      return u32regex_search(first, end, what, re, flags, base);\n   }\n   bool compare(const u32regex_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);\n   }\n   const match_results<BidirectionalIterator>& get()\n   { return what; }\n   bool next()\n   {\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail;\n      BidirectionalIterator next_start = what[0].second;\n      match_flag_type f(flags);\n      if(!what.length())\n         f |= regex_constants::match_not_initial_null;\n      //if(base != next_start)\n      //   f |= regex_constants::match_not_bob;\n      bool result = u32regex_search(next_start, end, what, re, f, base);\n      if(result)\n         what.set_base(base);\n      return result;\n   }\nprivate:\n   u32regex_iterator_implementation& operator=(const u32regex_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator>\nclass u32regex_iterator \n{\nprivate:\n   typedef u32regex_iterator_implementation<BidirectionalIterator> impl;\n   typedef shared_ptr<impl> pimpl;\npublic:\n   typedef          u32regex                                                regex_type;\n   typedef          match_results<BidirectionalIterator>                    value_type;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   u32regex_iterator(){}\n   u32regex_iterator(BidirectionalIterator a, BidirectionalIterator b, \n                  const regex_type& re, \n                  match_flag_type m = match_default)\n                  : pdata(new impl(&re, b, m))\n   {\n      if(!pdata->init(a))\n      {\n         pdata.reset();\n      }\n   }\n   u32regex_iterator(const u32regex_iterator& that)\n      : pdata(that.pdata) {}\n   u32regex_iterator& operator=(const u32regex_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const u32regex_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const u32regex_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   u32regex_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   u32regex_iterator operator++(int)\n   {\n      u32regex_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && !pdata.unique())\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef u32regex_iterator<const char*> utf8regex_iterator;\ntypedef u32regex_iterator<const UChar*> utf16regex_iterator;\ntypedef u32regex_iterator<const UChar32*> utf32regex_iterator;\n\ninline u32regex_iterator<const char*> make_u32regex_iterator(const char* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const char*>(p, p+std::strlen(p), e, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_iterator<const wchar_t*> make_u32regex_iterator(const wchar_t* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const wchar_t*>(p, p+std::wcslen(p), e, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ninline u32regex_iterator<const UChar*> make_u32regex_iterator(const UChar* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const UChar*>(p, p+u_strlen(p), e, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_iterator<iter_type>(p.begin(), p.end(), e, m);\n}\ninline u32regex_iterator<const UChar*> make_u32regex_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, m);\n}\n\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/u32regex_token_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         u32regex_token_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides u32regex_token_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP\n#define BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP\n\n#if (BOOST_WORKAROUND(BOOST_BORLANDC, >= 0x560) && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))\n//\n// Borland C++ Builder 6, and Visual C++ 6,\n// can't cope with the array template constructor\n// so we have a template member that will accept any type as \n// argument, and then assert that is really is an array:\n//\n#include <boost/static_assert.hpp>\n#include <boost/type_traits/is_array.hpp>\n#endif\n\nnamespace boost{\n\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4700)\n#endif\n\ntemplate <class BidirectionalIterator>\nclass u32regex_token_iterator_implementation \n{\n   typedef u32regex                              regex_type;\n   typedef sub_match<BidirectionalIterator>      value_type;\n\n   match_results<BidirectionalIterator> what;   // current match\n   BidirectionalIterator                end;    // end of search area\n   BidirectionalIterator                base;   // start of search area\n   const regex_type                     re;     // the expression\n   match_flag_type                      flags;  // match flags\n   value_type                           result; // the current string result\n   int                                  N;      // the current sub-expression being enumerated\n   std::vector<int>                     subs;   // the sub-expressions to enumerate\n\npublic:\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)\n      : end(last), re(*p), flags(f){ subs.push_back(sub); }\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)\n      : end(last), re(*p), flags(f), subs(v){}\n#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \\\n      || BOOST_WORKAROUND(__HP_aCC, < 60700)\n   template <class T>\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)\n      : end(last), re(*p), flags(f)\n   {\n      // assert that T really is an array:\n      BOOST_STATIC_ASSERT(::boost::is_array<T>::value);\n      const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);\n      for(std::size_t i = 0; i < array_size; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n#else\n   template <std::size_t CN>\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)\n      : end(last), re(*p), flags(f)\n   {\n      for(std::size_t i = 0; i < CN; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n#endif\n\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      N = 0;\n      if(u32regex_search(first, end, what, re, flags, base) == true)\n      {\n         N = 0;\n         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);\n         return true;\n      }\n      else if((subs[N] == -1) && (first != end))\n      {\n         result.first = first;\n         result.second = end;\n         result.matched = (first != end);\n         N = -1;\n         return true;\n      }\n      return false;\n   }\n   bool compare(const u32regex_token_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) \n         && (end == that.end) \n         && (flags == that.flags) \n         && (N == that.N) \n         && (what[0].first == that.what[0].first) \n         && (what[0].second == that.what[0].second);\n   }\n   const value_type& get()\n   { return result; }\n   bool next()\n   {\n      if(N == -1)\n         return false;\n      if(N+1 < (int)subs.size())\n      {\n         ++N;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail | regex_constants::match_not_bob;\n      BidirectionalIterator last_end(what[0].second);\n      if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))\n      {\n         N =0;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      else if((last_end != end) && (subs[0] == -1))\n      {\n         N =-1;\n         result.first = last_end;\n         result.second = end;\n         result.matched = (last_end != end);\n         return true;\n      }\n      return false;\n   }\nprivate:\n   u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator>\nclass u32regex_token_iterator \n{\nprivate:\n   typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;\n   typedef shared_ptr<impl> pimpl;\npublic:\n   typedef          u32regex                                                regex_type;\n   typedef          sub_match<BidirectionalIterator>                        value_type;\n   typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   u32regex_token_iterator(){}\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        int submatch = 0, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatch, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        const std::vector<int>& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\\\n      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \\\n      || BOOST_WORKAROUND(__HP_aCC, < 60700)\n   template <class T>\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const T& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#else\n   template <std::size_t N>\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const int (&submatches)[N], match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n#endif\n   u32regex_token_iterator(const u32regex_token_iterator& that)\n      : pdata(that.pdata) {}\n   u32regex_token_iterator& operator=(const u32regex_token_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const u32regex_token_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const u32regex_token_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   u32regex_token_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   u32regex_token_iterator operator++(int)\n   {\n      u32regex_token_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && !pdata.unique())\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef u32regex_token_iterator<const char*> utf8regex_token_iterator;\ntypedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;\ntypedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;\n\n// construction from an integral sub_match state_id:\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n// construction from a reference to an array:\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc, std::size_t N>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n// construction from a vector of sub_match state_id's:\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n#ifdef BOOST_MSVC\n#  pragma warning(pop)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/unicode_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         unicode_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Iterator adapters for converting between different Unicode encodings.\n  */\n\n/****************************************************************************\n\nContents:\n~~~~~~~~~\n\n1) Read Only, Input Adapters:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\ntemplate <class BaseIterator, class U8Type = ::boost::uint8_t>\nclass u32_to_u8_iterator;\n\nAdapts sequence of UTF-32 code points to \"look like\" a sequence of UTF-8.\n\ntemplate <class BaseIterator, class U32Type = ::boost::uint32_t>\nclass u8_to_u32_iterator;\n\nAdapts sequence of UTF-8 code points to \"look like\" a sequence of UTF-32.\n\ntemplate <class BaseIterator, class U16Type = ::boost::uint16_t>\nclass u32_to_u16_iterator;\n\nAdapts sequence of UTF-32 code points to \"look like\" a sequence of UTF-16.\n\ntemplate <class BaseIterator, class U32Type = ::boost::uint32_t>\nclass u16_to_u32_iterator;\n\nAdapts sequence of UTF-16 code points to \"look like\" a sequence of UTF-32.\n\n2) Single pass output iterator adapters:\n\ntemplate <class BaseIterator>\nclass utf8_output_iterator;\n\nAccepts UTF-32 code points and forwards them on as UTF-8 code points.\n\ntemplate <class BaseIterator>\nclass utf16_output_iterator;\n\nAccepts UTF-32 code points and forwards them on as UTF-16 code points.\n\n****************************************************************************/\n\n#ifndef BOOST_REGEX_V4_UNICODE_ITERATOR_HPP\n#define BOOST_REGEX_V4_UNICODE_ITERATOR_HPP\n#include <boost/cstdint.hpp>\n#include <boost/regex/config.hpp>\n#include <boost/static_assert.hpp>\n#include <boost/throw_exception.hpp>\n#include <stdexcept>\n#ifndef BOOST_NO_STD_LOCALE\n#include <sstream>\n#include <ios>\n#endif\n#include <limits.h> // CHAR_BIT\n\n#ifdef BOOST_REGEX_CXX03\n\n#else\n#endif\n\nnamespace boost{\n\nnamespace detail{\n\nstatic const ::boost::uint16_t high_surrogate_base = 0xD7C0u;\nstatic const ::boost::uint16_t low_surrogate_base = 0xDC00u;\nstatic const ::boost::uint32_t ten_bit_mask = 0x3FFu;\n\ninline bool is_high_surrogate(::boost::uint16_t v)\n{\n   return (v & 0xFFFFFC00u) == 0xd800u;\n}\ninline bool is_low_surrogate(::boost::uint16_t v)\n{\n   return (v & 0xFFFFFC00u) == 0xdc00u;\n}\ntemplate <class T>\ninline bool is_surrogate(T v)\n{\n   return (v & 0xFFFFF800u) == 0xd800;\n}\n\ninline unsigned utf8_byte_count(boost::uint8_t c)\n{\n   // if the most significant bit with a zero in it is in position\n   // 8-N then there are N bytes in this UTF-8 sequence:\n   boost::uint8_t mask = 0x80u;\n   unsigned result = 0;\n   while(c & mask)\n   {\n      ++result;\n      mask >>= 1;\n   }\n   return (result == 0) ? 1 : ((result > 4) ? 4 : result);\n}\n\ninline unsigned utf8_trailing_byte_count(boost::uint8_t c)\n{\n   return utf8_byte_count(c) - 1;\n}\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4100)\n#endif\n#ifndef BOOST_NO_EXCEPTIONS\nBOOST_NORETURN\n#endif\ninline void invalid_utf32_code_point(::boost::uint32_t val)\n{\n#ifndef BOOST_NO_STD_LOCALE\n   std::stringstream ss;\n   ss << \"Invalid UTF-32 code point U+\" << std::showbase << std::hex << val << \" encountered while trying to encode UTF-16 sequence\";\n   std::out_of_range e(ss.str());\n#else\n   std::out_of_range e(\"Invalid UTF-32 code point encountered while trying to encode UTF-16 sequence\");\n#endif\n   boost::throw_exception(e);\n}\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n\n} // namespace detail\n\ntemplate <class BaseIterator, class U16Type = ::boost::uint16_t>\nclass u32_to_u16_iterator\n{\n#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);\n   BOOST_STATIC_ASSERT(sizeof(U16Type)*CHAR_BIT == 16);\n#endif\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U16Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_current == 2)\n         extract_current();\n      return m_values[m_current];\n   }\n   bool operator==(const u32_to_u16_iterator& that)const\n   {\n      if(m_position == that.m_position)\n      {\n         // Both m_currents must be equal, or both even\n         // this is the same as saying their sum must be even:\n         return (m_current + that.m_current) & 1u ? false : true;\n      }\n      return false;\n   }\n   bool operator!=(const u32_to_u16_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u32_to_u16_iterator& operator++()\n   {\n      // if we have a pending read then read now, so that we know whether\n      // to skip a position, or move to a low-surrogate:\n      if(m_current == 2)\n      {\n         // pending read:\n         extract_current();\n      }\n      // move to the next surrogate position:\n      ++m_current;\n      // if we've reached the end skip a position:\n      if(m_values[m_current] == 0)\n      {\n         m_current = 2;\n         ++m_position;\n      }\n      return *this;\n   }\n   u32_to_u16_iterator operator++(int)\n   {\n      u32_to_u16_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u32_to_u16_iterator& operator--()\n   {\n      if(m_current != 1)\n      {\n         // decrementing an iterator always leads to a valid position:\n         --m_position;\n         extract_current();\n         m_current = m_values[1] ? 1 : 0;\n      }\n      else\n      {\n         m_current = 0;\n      }\n      return *this;\n   }\n   u32_to_u16_iterator operator--(int)\n   {\n      u32_to_u16_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u32_to_u16_iterator() : m_position(), m_current(0)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n   }\n   u32_to_u16_iterator(BaseIterator b) : m_position(b), m_current(2)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n   }\nprivate:\n\n   void extract_current()const\n   {\n      // begin by checking for a code point out of range:\n      ::boost::uint32_t v = *m_position;\n      if(v >= 0x10000u)\n      {\n         if(v > 0x10FFFFu)\n            detail::invalid_utf32_code_point(*m_position);\n         // split into two surrogates:\n         m_values[0] = static_cast<U16Type>(v >> 10) + detail::high_surrogate_base;\n         m_values[1] = static_cast<U16Type>(v & detail::ten_bit_mask) + detail::low_surrogate_base;\n         m_current = 0;\n         BOOST_REGEX_ASSERT(detail::is_high_surrogate(m_values[0]));\n         BOOST_REGEX_ASSERT(detail::is_low_surrogate(m_values[1]));\n      }\n      else\n      {\n         // 16-bit code point:\n         m_values[0] = static_cast<U16Type>(*m_position);\n         m_values[1] = 0;\n         m_current = 0;\n         // value must not be a surrogate:\n         if(detail::is_surrogate(m_values[0]))\n            detail::invalid_utf32_code_point(*m_position);\n      }\n   }\n   BaseIterator m_position;\n   mutable U16Type m_values[3];\n   mutable unsigned m_current;\n};\n\ntemplate <class BaseIterator, class U32Type = ::boost::uint32_t>\nclass u16_to_u32_iterator\n{\n   // special values for pending iterator reads:\n   BOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);\n\n#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 16);\n   BOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);\n#endif\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U32Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_value == pending_read)\n         extract_current();\n      return m_value;\n   }\n   bool operator==(const u16_to_u32_iterator& that)const\n   {\n      return m_position == that.m_position;\n   }\n   bool operator!=(const u16_to_u32_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u16_to_u32_iterator& operator++()\n   {\n      // skip high surrogate first if there is one:\n      if(detail::is_high_surrogate(*m_position)) ++m_position;\n      ++m_position;\n      m_value = pending_read;\n      return *this;\n   }\n   u16_to_u32_iterator operator++(int)\n   {\n      u16_to_u32_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u16_to_u32_iterator& operator--()\n   {\n      --m_position;\n      // if we have a low surrogate then go back one more:\n      if(detail::is_low_surrogate(*m_position)) \n         --m_position;\n      m_value = pending_read;\n      return *this;\n   }\n   u16_to_u32_iterator operator--(int)\n   {\n      u16_to_u32_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u16_to_u32_iterator() : m_position()\n   {\n      m_value = pending_read;\n   }\n   u16_to_u32_iterator(BaseIterator b) : m_position(b)\n   {\n      m_value = pending_read;\n   }\n   //\n   // Range checked version:\n   //\n   u16_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)\n   {\n      m_value = pending_read;\n      //\n      // The range must not start with a low surrogate, or end in a high surrogate,\n      // otherwise we run the risk of running outside the underlying input range.\n      // Likewise b must not be located at a low surrogate.\n      //\n      boost::uint16_t val;\n      if(start != end)\n      {\n         if((b != start) && (b != end))\n         {\n            val = *b;\n            if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))\n               invalid_code_point(val);\n         }\n         val = *start;\n         if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))\n            invalid_code_point(val);\n         val = *--end;\n         if(detail::is_high_surrogate(val))\n            invalid_code_point(val);\n      }\n   }\nprivate:\n   static void invalid_code_point(::boost::uint16_t val)\n   {\n#ifndef BOOST_NO_STD_LOCALE\n      std::stringstream ss;\n      ss << \"Misplaced UTF-16 surrogate U+\" << std::showbase << std::hex << val << \" encountered while trying to encode UTF-32 sequence\";\n      std::out_of_range e(ss.str());\n#else\n      std::out_of_range e(\"Misplaced UTF-16 surrogate encountered while trying to encode UTF-32 sequence\");\n#endif\n      boost::throw_exception(e);\n   }\n   void extract_current()const\n   {\n      m_value = static_cast<U32Type>(static_cast< ::boost::uint16_t>(*m_position));\n      // if the last value is a high surrogate then adjust m_position and m_value as needed:\n      if(detail::is_high_surrogate(*m_position))\n      {\n         // precondition; next value must have be a low-surrogate:\n         BaseIterator next(m_position);\n         ::boost::uint16_t t = *++next;\n         if((t & 0xFC00u) != 0xDC00u)\n            invalid_code_point(t);\n         m_value = (m_value - detail::high_surrogate_base) << 10;\n         m_value |= (static_cast<U32Type>(static_cast< ::boost::uint16_t>(t)) & detail::ten_bit_mask);\n      }\n      // postcondition; result must not be a surrogate:\n      if(detail::is_surrogate(m_value))\n         invalid_code_point(static_cast< ::boost::uint16_t>(m_value));\n   }\n   BaseIterator m_position;\n   mutable U32Type m_value;\n};\n\ntemplate <class BaseIterator, class U8Type = ::boost::uint8_t>\nclass u32_to_u8_iterator\n{\n#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 32);\n   BOOST_STATIC_ASSERT(sizeof(U8Type)*CHAR_BIT == 8);\n#endif\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U8Type             value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_current == 4)\n         extract_current();\n      return m_values[m_current];\n   }\n   bool operator==(const u32_to_u8_iterator& that)const\n   {\n      if(m_position == that.m_position)\n      {\n         // either the m_current's must be equal, or one must be 0 and \n         // the other 4: which means neither must have bits 1 or 2 set:\n         return (m_current == that.m_current)\n            || (((m_current | that.m_current) & 3) == 0);\n      }\n      return false;\n   }\n   bool operator!=(const u32_to_u8_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u32_to_u8_iterator& operator++()\n   {\n      // if we have a pending read then read now, so that we know whether\n      // to skip a position, or move to a low-surrogate:\n      if(m_current == 4)\n      {\n         // pending read:\n         extract_current();\n      }\n      // move to the next surrogate position:\n      ++m_current;\n      // if we've reached the end skip a position:\n      if(m_values[m_current] == 0)\n      {\n         m_current = 4;\n         ++m_position;\n      }\n      return *this;\n   }\n   u32_to_u8_iterator operator++(int)\n   {\n      u32_to_u8_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u32_to_u8_iterator& operator--()\n   {\n      if((m_current & 3) == 0)\n      {\n         --m_position;\n         extract_current();\n         m_current = 3;\n         while(m_current && (m_values[m_current] == 0))\n            --m_current;\n      }\n      else\n         --m_current;\n      return *this;\n   }\n   u32_to_u8_iterator operator--(int)\n   {\n      u32_to_u8_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u32_to_u8_iterator() : m_position(), m_current(0)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n      m_values[3] = 0;\n      m_values[4] = 0;\n   }\n   u32_to_u8_iterator(BaseIterator b) : m_position(b), m_current(4)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n      m_values[3] = 0;\n      m_values[4] = 0;\n   }\nprivate:\n\n   void extract_current()const\n   {\n      boost::uint32_t c = *m_position;\n      if(c > 0x10FFFFu)\n         detail::invalid_utf32_code_point(c);\n      if(c < 0x80u)\n      {\n         m_values[0] = static_cast<unsigned char>(c);\n         m_values[1] = static_cast<unsigned char>(0u);\n         m_values[2] = static_cast<unsigned char>(0u);\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else if(c < 0x800u)\n      {\n         m_values[0] = static_cast<unsigned char>(0xC0u + (c >> 6));\n         m_values[1] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0u);\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else if(c < 0x10000u)\n      {\n         m_values[0] = static_cast<unsigned char>(0xE0u + (c >> 12));\n         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else\n      {\n         m_values[0] = static_cast<unsigned char>(0xF0u + (c >> 18));\n         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         m_values[3] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      m_current= 0;\n   }\n   BaseIterator m_position;\n   mutable U8Type m_values[5];\n   mutable unsigned m_current;\n};\n\ntemplate <class BaseIterator, class U32Type = ::boost::uint32_t>\nclass u8_to_u32_iterator\n{\n   // special values for pending iterator reads:\n   BOOST_STATIC_CONSTANT(U32Type, pending_read = 0xffffffffu);\n\n#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   BOOST_STATIC_ASSERT(sizeof(base_value_type)*CHAR_BIT == 8);\n   BOOST_STATIC_ASSERT(sizeof(U32Type)*CHAR_BIT == 32);\n#endif\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U32Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_value == pending_read)\n         extract_current();\n      return m_value;\n   }\n   bool operator==(const u8_to_u32_iterator& that)const\n   {\n      return m_position == that.m_position;\n   }\n   bool operator!=(const u8_to_u32_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u8_to_u32_iterator& operator++()\n   {\n      // We must not start with a continuation character:\n      if((static_cast<boost::uint8_t>(*m_position) & 0xC0) == 0x80)\n         invalid_sequence();\n      // skip high surrogate first if there is one:\n      unsigned c = detail::utf8_byte_count(*m_position);\n      if(m_value == pending_read)\n      {\n         // Since we haven't read in a value, we need to validate the code points:\n         for(unsigned i = 0; i < c; ++i)\n         {\n            ++m_position;\n            // We must have a continuation byte:\n            if((i != c - 1) && ((static_cast<boost::uint8_t>(*m_position) & 0xC0) != 0x80))\n               invalid_sequence();\n         }\n      }\n      else\n      {\n         std::advance(m_position, c);\n      }\n      m_value = pending_read;\n      return *this;\n   }\n   u8_to_u32_iterator operator++(int)\n   {\n      u8_to_u32_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u8_to_u32_iterator& operator--()\n   {\n      // Keep backtracking until we don't have a trailing character:\n      unsigned count = 0;\n      while((*--m_position & 0xC0u) == 0x80u) ++count;\n      // now check that the sequence was valid:\n      if(count != detail::utf8_trailing_byte_count(*m_position))\n         invalid_sequence();\n      m_value = pending_read;\n      return *this;\n   }\n   u8_to_u32_iterator operator--(int)\n   {\n      u8_to_u32_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u8_to_u32_iterator() : m_position()\n   {\n      m_value = pending_read;\n   }\n   u8_to_u32_iterator(BaseIterator b) : m_position(b)\n   {\n      m_value = pending_read;\n   }\n   //\n   // Checked constructor:\n   //\n   u8_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)\n   {\n      m_value = pending_read;\n      //\n      // We must not start with a continuation character, or end with a \n      // truncated UTF-8 sequence otherwise we run the risk of going past\n      // the start/end of the underlying sequence:\n      //\n      if(start != end)\n      {\n         unsigned char v = *start;\n         if((v & 0xC0u) == 0x80u)\n            invalid_sequence();\n         if((b != start) && (b != end) && ((*b & 0xC0u) == 0x80u))\n            invalid_sequence();\n         BaseIterator pos = end;\n         do\n         {\n            v = *--pos;\n         }\n         while((start != pos) && ((v & 0xC0u) == 0x80u));\n         std::ptrdiff_t extra = detail::utf8_byte_count(v);\n         if(std::distance(pos, end) < extra)\n            invalid_sequence();\n      }\n   }\nprivate:\n   static void invalid_sequence()\n   {\n      std::out_of_range e(\"Invalid UTF-8 sequence encountered while trying to encode UTF-32 character\");\n      boost::throw_exception(e);\n   }\n   void extract_current()const\n   {\n      m_value = static_cast<U32Type>(static_cast< ::boost::uint8_t>(*m_position));\n      // we must not have a continuation character:\n      if((m_value & 0xC0u) == 0x80u)\n         invalid_sequence();\n      // see how many extra bytes we have:\n      unsigned extra = detail::utf8_trailing_byte_count(*m_position);\n      // extract the extra bits, 6 from each extra byte:\n      BaseIterator next(m_position);\n      for(unsigned c = 0; c < extra; ++c)\n      {\n         ++next;\n         m_value <<= 6;\n         // We must have a continuation byte:\n         if((static_cast<boost::uint8_t>(*next) & 0xC0) != 0x80)\n            invalid_sequence();\n         m_value += static_cast<boost::uint8_t>(*next) & 0x3Fu;\n      }\n      // we now need to remove a few of the leftmost bits, but how many depends\n      // upon how many extra bytes we've extracted:\n      static const boost::uint32_t masks[4] = \n      {\n         0x7Fu,\n         0x7FFu,\n         0xFFFFu,\n         0x1FFFFFu,\n      };\n      m_value &= masks[extra];\n      // check the result is in range:\n      if(m_value > static_cast<U32Type>(0x10FFFFu))\n         invalid_sequence();\n      // The result must not be a surrogate:\n      if((m_value >= static_cast<U32Type>(0xD800)) && (m_value <= static_cast<U32Type>(0xDFFF)))\n         invalid_sequence();\n      // We should not have had an invalidly encoded UTF8 sequence:\n      if((extra > 0) && (m_value <= static_cast<U32Type>(masks[extra - 1])))\n         invalid_sequence();\n   }\n   BaseIterator m_position;\n   mutable U32Type m_value;\n};\n\ntemplate <class BaseIterator>\nclass utf16_output_iterator\n{\npublic:\n   typedef void                                   difference_type;\n   typedef void                                   value_type;\n   typedef boost::uint32_t*                       pointer;\n   typedef boost::uint32_t&                       reference;\n   typedef std::output_iterator_tag               iterator_category;\n\n   utf16_output_iterator(const BaseIterator& b)\n      : m_position(b){}\n   utf16_output_iterator(const utf16_output_iterator& that)\n      : m_position(that.m_position){}\n   utf16_output_iterator& operator=(const utf16_output_iterator& that)\n   {\n      m_position = that.m_position;\n      return *this;\n   }\n   const utf16_output_iterator& operator*()const\n   {\n      return *this;\n   }\n   void operator=(boost::uint32_t val)const\n   {\n      push(val);\n   }\n   utf16_output_iterator& operator++()\n   {\n      return *this;\n   }\n   utf16_output_iterator& operator++(int)\n   {\n      return *this;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\nprivate:\n   void push(boost::uint32_t v)const\n   {\n      if(v >= 0x10000u)\n      {\n         // begin by checking for a code point out of range:\n         if(v > 0x10FFFFu)\n            detail::invalid_utf32_code_point(v);\n         // split into two surrogates:\n         *m_position++ = static_cast<boost::uint16_t>(v >> 10) + detail::high_surrogate_base;\n         *m_position++ = static_cast<boost::uint16_t>(v & detail::ten_bit_mask) + detail::low_surrogate_base;\n      }\n      else\n      {\n         // 16-bit code point:\n         // value must not be a surrogate:\n         if(detail::is_surrogate(v))\n            detail::invalid_utf32_code_point(v);\n         *m_position++ = static_cast<boost::uint16_t>(v);\n      }\n   }\n   mutable BaseIterator m_position;\n};\n\ntemplate <class BaseIterator>\nclass utf8_output_iterator\n{\npublic:\n   typedef void                                   difference_type;\n   typedef void                                   value_type;\n   typedef boost::uint32_t*                       pointer;\n   typedef boost::uint32_t&                       reference;\n   typedef std::output_iterator_tag               iterator_category;\n\n   utf8_output_iterator(const BaseIterator& b)\n      : m_position(b){}\n   utf8_output_iterator(const utf8_output_iterator& that)\n      : m_position(that.m_position){}\n   utf8_output_iterator& operator=(const utf8_output_iterator& that)\n   {\n      m_position = that.m_position;\n      return *this;\n   }\n   const utf8_output_iterator& operator*()const\n   {\n      return *this;\n   }\n   void operator=(boost::uint32_t val)const\n   {\n      push(val);\n   }\n   utf8_output_iterator& operator++()\n   {\n      return *this;\n   }\n   utf8_output_iterator& operator++(int)\n   {\n      return *this;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\nprivate:\n   void push(boost::uint32_t c)const\n   {\n      if(c > 0x10FFFFu)\n         detail::invalid_utf32_code_point(c);\n      if(c < 0x80u)\n      {\n         *m_position++ = static_cast<unsigned char>(c);\n      }\n      else if(c < 0x800u)\n      {\n         *m_position++ = static_cast<unsigned char>(0xC0u + (c >> 6));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      else if(c < 0x10000u)\n      {\n         *m_position++ = static_cast<unsigned char>(0xE0u + (c >> 12));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      else\n      {\n         *m_position++ = static_cast<unsigned char>(0xF0u + (c >> 18));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n   }\n   mutable BaseIterator m_position;\n};\n\n} // namespace boost\n\n#endif // BOOST_REGEX_UNICODE_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v4/w32_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         w32_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class w32_regex_traits.\n  */\n\n#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_NO_WIN32_LOCALE\n\n#ifndef BOOST_RE_PAT_EXCEPT_HPP\n#include <boost/regex/pattern_except.hpp>\n#endif\n#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n#include <boost/regex/v4/regex_traits_defaults.hpp>\n#endif\n#ifdef BOOST_HAS_THREADS\n#include <boost/regex/pending/static_mutex.hpp>\n#endif\n#ifndef BOOST_REGEX_PRIMARY_TRANSFORM\n#include <boost/regex/v4/primary_transform.hpp>\n#endif\n#ifndef BOOST_REGEX_OBJECT_CACHE_HPP\n#include <boost/regex/v4/object_cache.hpp>\n#endif\n\n#define VC_EXTRALEAN\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n\n#if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(UNDER_CE)\n#pragma comment(lib, \"user32.lib\")\n#endif\n\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_PREFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable:4786)\n#if BOOST_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{ \n\n//\n// forward declaration is needed by some compilers:\n//\ntemplate <class charT>\nclass w32_regex_traits;\n   \nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// start by typedeffing the types we'll need:\n//\ntypedef ::boost::uint32_t lcid_type;   // placeholder for LCID.\ntypedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.\n\n//\n// then add wrappers around the actual Win32 API's (ie implementation hiding):\n//\nlcid_type BOOST_REGEX_CALL w32_get_default_locale();\nbool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);\n#ifndef BOOST_NO_WREGEX\nbool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);\n#endif\nbool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);\n#ifndef BOOST_NO_WREGEX\nbool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);\n#endif\ncat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);\nstd::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);\n#ifndef BOOST_NO_WREGEX\nstd::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);\n#endif\nstd::string BOOST_REGEX_CALL w32_transform(lcid_type state_id, const char* p1, const char* p2);\n#ifndef BOOST_NO_WREGEX\nstd::wstring BOOST_REGEX_CALL w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);\n#endif\nchar BOOST_REGEX_CALL w32_tolower(char c, lcid_type);\n#ifndef BOOST_NO_WREGEX\nwchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);\n#endif\nchar BOOST_REGEX_CALL w32_toupper(char c, lcid_type);\n#ifndef BOOST_NO_WREGEX\nwchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);\n#endif\nbool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);\n#ifndef BOOST_NO_WREGEX\nbool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);\n#endif\n//\n// class w32_regex_traits_base:\n// acts as a container for locale and the facets we are using.\n//\ntemplate <class charT>\nstruct w32_regex_traits_base\n{\n   w32_regex_traits_base(lcid_type l)\n   { imbue(l); }\n   lcid_type imbue(lcid_type l);\n\n   lcid_type m_locale;\n};\n\ntemplate <class charT>\ninline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)\n{\n   lcid_type result(m_locale);\n   m_locale = l;\n   return result;\n}\n\n//\n// class w32_regex_traits_char_layer:\n// implements methods that require specialisation for narrow characters:\n//\ntemplate <class charT>\nclass w32_regex_traits_char_layer : public w32_regex_traits_base<charT>\n{\n   typedef std::basic_string<charT> string_type;\n   typedef std::map<charT, regex_constants::syntax_type> map_type;\n   typedef typename map_type::const_iterator map_iterator_type;\npublic:\n   w32_regex_traits_char_layer(const lcid_type l);\n\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      return ((i == m_char_map.end()) ? 0 : i->second);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      if(i == m_char_map.end())\n      {\n         if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;\n         if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;\n         return 0;\n      }\n      return i->second;\n   }\n   charT tolower(charT c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_tolower(c, this->m_locale);\n   }\n   bool isctype(boost::uint32_t mask, charT c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, mask, c);\n   }\n\nprivate:\n   string_type get_default_message(regex_constants::syntax_type);\n   // TODO: use a hash table when available!\n   map_type m_char_map;\n};\n\ntemplate <class charT>\nw32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l) \n   : w32_regex_traits_base<charT>(l)\n{\n   // we need to start by initialising our syntax map so we know which\n   // character is used for which purpose:\n   cat_type cat;\n   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());\n   if(cat_name.size())\n   {\n      cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n      if(!cat)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if(cat)\n   {\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_message(i));\n         for(typename string_type::size_type j = 0; j < mss.size(); ++j)\n         {\n            this->m_char_map[mss[j]] = i;\n         }\n      }\n   }\n   else\n   {\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         const char* ptr = get_default_syntax(i);\n         while(ptr && *ptr)\n         {\n            this->m_char_map[static_cast<charT>(*ptr)] = i;\n            ++ptr;\n         }\n      }\n   }\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_char_layer<charT>::string_type \n   w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)\n{\n   const char* ptr = get_default_syntax(i);\n   string_type result;\n   while(ptr && *ptr)\n   {\n      result.append(1, static_cast<charT>(*ptr));\n      ++ptr;\n   }\n   return result;\n}\n\n//\n// specialised version for narrow characters:\n//\ntemplate <>\nclass w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>\n{\n   typedef std::string string_type;\npublic:\n   w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n   : w32_regex_traits_base<char>(l)\n   {\n      init<char>();\n   }\n\n   regex_constants::syntax_type syntax_type(char c)const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(char c) const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   char tolower(char c)const\n   {\n      return m_lower_map[static_cast<unsigned char>(c)];\n   }\n   bool isctype(boost::uint32_t mask, char c)const\n   {\n      return m_type_map[static_cast<unsigned char>(c)] & mask;\n   }\n\nprivate:\n   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];\n   char m_lower_map[1u << CHAR_BIT];\n   boost::uint16_t m_type_map[1u << CHAR_BIT];\n   template <class U>\n   void init();\n};\n\n//\n// class w32_regex_traits_implementation:\n// provides pimpl implementation for w32_regex_traits.\n//\ntemplate <class charT>\nclass w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>\n{\npublic:\n   typedef typename w32_regex_traits<charT>::char_class_type char_class_type;\n   BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1\n   BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2\n   BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 0x1000); // must be C1_DEFINED << 3\n   BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 0x2000); // must be C1_DEFINED << 4\n   BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff);  // all the masks used by the CT_CTYPE1 group\n\n   typedef std::basic_string<charT> string_type;\n   typedef charT char_type;\n   w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l);\n   std::string error_string(regex_constants::error_type n) const\n   {\n      if(!m_error_strings.empty())\n      {\n         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);\n         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;\n      }\n      return get_default_error_string(n);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      char_class_type result = lookup_classname_imp(p1, p2);\n      if(result == 0)\n      {\n         typedef typename string_type::size_type size_type;\n         string_type temp(p1, p2);\n         for(size_type i = 0; i < temp.size(); ++i)\n            temp[i] = this->tolower(temp[i]);\n         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());\n      }\n      return result;\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const;\n   string_type transform_primary(const charT* p1, const charT* p2) const;\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_locale, p1, p2);\n   }\nprivate:\n   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID\n   std::map<string_type, char_class_type>  m_custom_class_names; // character class names\n   std::map<string_type, string_type>      m_custom_collate_names; // collating element names\n   unsigned                       m_collate_type;    // the form of the collation string\n   charT                          m_collate_delim;   // the collation group delimiter\n   //\n   // helpers:\n   //\n   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;\n};\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::string_type \n   w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const\n{\n   string_type result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch(m_collate_type)\n   {\n   case sort_C:\n   case sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n      {\n         result.assign(p1, p2);\n         typedef typename string_type::size_type size_type;\n         for(size_type i = 0; i < result.size(); ++i)\n            result[i] = this->tolower(result[i]);\n         result = this->transform(&*result.begin(), &*result.begin() + result.size());\n         break;\n      }\n   case sort_fixed:\n      {\n         // get a regular sort key, and then truncate it:\n         result.assign(this->transform(p1, p2));\n         result.erase(this->m_collate_delim);\n         break;\n      }\n   case sort_delim:\n         // get a regular sort key, and then truncate everything after the delim:\n         result.assign(this->transform(p1, p2));\n         std::size_t i;\n         for(i = 0; i < result.size(); ++i)\n         {\n            if(result[i] == m_collate_delim)\n               break;\n         }\n         result.erase(i);\n         break;\n   }\n   if(result.empty())\n      result = string_type(1, charT(0));\n   return result;\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::string_type \n   w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const\n{\n   typedef typename std::map<string_type, string_type>::const_iterator iter_type;\n   if(m_custom_collate_names.size())\n   {\n      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));\n      if(pos != m_custom_collate_names.end())\n         return pos->second;\n   }\n#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\\\n               && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0551)\n   std::string name(p1, p2);\n#else\n   std::string name;\n   const charT* p0 = p1;\n   while(p0 != p2)\n      name.append(1, char(*p0++));\n#endif\n   name = lookup_default_collate_name(name);\n#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\\\n               && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x0551)\n   if(name.size())\n      return string_type(name.begin(), name.end());\n#else\n   if(name.size())\n   {\n      string_type result;\n      typedef std::string::const_iterator iter;\n      iter b = name.begin();\n      iter e = name.end();\n      while(b != e)\n         result.append(1, charT(*b++));\n      return result;\n   }\n#endif\n   if(p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ntemplate <class charT>\nw32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n: w32_regex_traits_char_layer<charT>(l)\n{\n   cat_type cat;\n   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());\n   if(cat_name.size())\n   {\n      cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n      if(!cat)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if(cat)\n   {\n      //\n      // Error messages:\n      //\n      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); \n         i <= boost::regex_constants::error_unknown; \n         i = static_cast<boost::regex_constants::error_type>(i + 1))\n      {\n         const char* p = get_default_error_string(i);\n         string_type default_message;\n         while(*p)\n         {\n            default_message.append(1, static_cast<charT>(*p));\n            ++p;\n         }\n         string_type s = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i+200, default_message);\n         std::string result;\n         for(std::string::size_type j = 0; j < s.size(); ++j)\n         {\n            result.append(1, static_cast<char>(s[j]));\n         }\n         m_error_strings[i] = result;\n      }\n      //\n      // Custom class names:\n      //\n      static const char_class_type masks[14] = \n      {\n         0x0104u, // C1_ALPHA | C1_DIGIT\n         0x0100u, // C1_ALPHA\n         0x0020u, // C1_CNTRL\n         0x0004u, // C1_DIGIT\n         (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE\n         0x0002u, // C1_LOWER\n         (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL\n         0x0010u, // C1_PUNCT\n         0x0008u, // C1_SPACE\n         0x0001u, // C1_UPPER\n         0x0080u, // C1_XDIGIT\n         0x0040u, // C1_BLANK\n         w32_regex_traits_implementation<charT>::mask_word,\n         w32_regex_traits_implementation<charT>::mask_unicode,\n      };\n      static const string_type null_string;\n      for(unsigned int j = 0; j <= 13; ++j)\n      {\n         string_type s(::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, j+300, null_string));\n         if(s.size())\n            this->m_custom_class_names[s] = masks[j];\n      }\n   }\n   //\n   // get the collation format used by m_pcollate:\n   //\n   m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::char_class_type \n   w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const\n{\n   static const char_class_type masks[22] = \n   {\n      0,\n      0x0104u, // C1_ALPHA | C1_DIGIT\n      0x0100u, // C1_ALPHA\n      0x0040u, // C1_BLANK\n      0x0020u, // C1_CNTRL\n      0x0004u, // C1_DIGIT\n      0x0004u, // C1_DIGIT\n      (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK\n      w32_regex_traits_implementation<charT>::mask_horizontal, \n      0x0002u, // C1_LOWER\n      0x0002u, // C1_LOWER\n      (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL\n      0x0010u, // C1_PUNCT\n      0x0008u, // C1_SPACE\n      0x0008u, // C1_SPACE\n      0x0001u, // C1_UPPER\n      w32_regex_traits_implementation<charT>::mask_unicode,\n      0x0001u, // C1_UPPER\n      w32_regex_traits_implementation<charT>::mask_vertical, \n      0x0104u | w32_regex_traits_implementation<charT>::mask_word, \n      0x0104u | w32_regex_traits_implementation<charT>::mask_word, \n      0x0080u, // C1_XDIGIT\n   };\n   if(m_custom_class_names.size())\n   {\n      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;\n      map_iter pos = m_custom_class_names.find(string_type(p1, p2));\n      if(pos != m_custom_class_names.end())\n         return pos->second;\n   }\n   std::size_t state_id = 1u + (std::size_t)BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if(state_id < sizeof(masks) / sizeof(masks[0]))\n      return masks[state_id];\n   return masks[0];\n}\n\n\ntemplate <class charT>\nboost::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n{\n   // TODO: create a cache for previously constructed objects.\n   return boost::object_cache< ::boost::BOOST_REGEX_DETAIL_NS::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);\n}\n\n} // BOOST_REGEX_DETAIL_NS\n\ntemplate <class charT>\nclass w32_regex_traits\n{\npublic:\n   typedef charT                         char_type;\n   typedef std::size_t                   size_type;\n   typedef std::basic_string<char_type>  string_type;\n   typedef ::boost::BOOST_REGEX_DETAIL_NS::lcid_type locale_type;\n   typedef boost::uint_least32_t         char_class_type;\n\n   struct boost_extensions_tag{};\n\n   w32_regex_traits()\n      : m_pimpl(BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(::boost::BOOST_REGEX_DETAIL_NS::w32_get_default_locale()))\n   { }\n   static size_type length(const char_type* p)\n   {\n      return std::char_traits<charT>::length(p);\n   }\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      return m_pimpl->syntax_type(c);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      return m_pimpl->escape_syntax_type(c);\n   }\n   charT translate(charT c) const\n   {\n      return c;\n   }\n   charT translate_nocase(charT c) const\n   {\n      return this->m_pimpl->tolower(c);\n   }\n   charT translate(charT c, bool icase) const\n   {\n      return icase ? this->m_pimpl->tolower(c) : c;\n   }\n   charT tolower(charT c) const\n   {\n      return this->m_pimpl->tolower(c);\n   }\n   charT toupper(charT c) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_toupper(c, this->m_pimpl->m_locale);\n   }\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_pimpl->m_locale, p1, p2);\n   }\n   string_type transform_primary(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform_primary(p1, p2);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_classname(p1, p2);\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_collatename(p1, p2);\n   }\n   bool isctype(charT c, char_class_type f) const\n   {\n      if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base) \n         && (this->m_pimpl->isctype(f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base, c)))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical)\n         && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_horizontal) \n         && this->isctype(c, 0x0008u) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical))\n         return true;\n      return false;\n   }\n   boost::intmax_t toi(const charT*& p1, const charT* p2, int radix)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n   }\n   int value(charT c, int radix)const\n   {\n      int result = (int)::boost::BOOST_REGEX_DETAIL_NS::global_value(c);\n      return result < radix ? result : -1;\n   }\n   locale_type imbue(locale_type l)\n   {\n      ::boost::BOOST_REGEX_DETAIL_NS::lcid_type result(getloc());\n      m_pimpl = BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(l);\n      return result;\n   }\n   locale_type getloc()const\n   {\n      return m_pimpl->m_locale;\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      return m_pimpl->error_string(n);\n   }\n\n   //\n   // extension:\n   // set the name of the message catalog in use (defaults to \"boost_regex\").\n   //\n   static std::string catalog_name(const std::string& name);\n   static std::string get_catalog_name();\n\nprivate:\n   boost::shared_ptr<const BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT> > m_pimpl;\n   //\n   // catalog name handler:\n   //\n   static std::string& get_catalog_name_inst();\n\n#ifdef BOOST_HAS_THREADS\n   static static_mutex& get_mutex_inst();\n#endif\n};\n\ntemplate <class charT>\nstd::string w32_regex_traits<charT>::catalog_name(const std::string& name)\n{\n#ifdef BOOST_HAS_THREADS\n   static_mutex::scoped_lock lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   get_catalog_name_inst() = name;\n   return result;\n}\n\ntemplate <class charT>\nstd::string& w32_regex_traits<charT>::get_catalog_name_inst()\n{\n   static std::string s_name;\n   return s_name;\n}\n\ntemplate <class charT>\nstd::string w32_regex_traits<charT>::get_catalog_name()\n{\n#ifdef BOOST_HAS_THREADS\n   static_mutex::scoped_lock lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   return result;\n}\n\n#ifdef BOOST_HAS_THREADS\ntemplate <class charT>\nstatic_mutex& w32_regex_traits<charT>::get_mutex_inst()\n{\n   static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;\n   return s_mutex;\n}\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS {\n\n#ifdef BOOST_NO_ANSI_APIS\n   inline UINT get_code_page_for_locale_id(lcid_type idx)\n   {\n      WCHAR code_page_string[7];\n      if (::GetLocaleInfoW(idx, LOCALE_IDEFAULTANSICODEPAGE, code_page_string, 7) == 0)\n         return 0;\n\n      return static_cast<UINT>(_wtol(code_page_string));\n}\n#endif\n\n   template <class U>\n   inline void w32_regex_traits_char_layer<char>::init()\n   {\n      // we need to start by initialising our syntax map so we know which\n      // character is used for which purpose:\n      std::memset(m_char_map, 0, sizeof(m_char_map));\n      cat_type cat;\n      std::string cat_name(w32_regex_traits<char>::get_catalog_name());\n      if (cat_name.size())\n      {\n         cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n         if (!cat)\n         {\n            std::string m(\"Unable to open message catalog: \");\n            std::runtime_error err(m + cat_name);\n            ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n         }\n      }\n      //\n      // if we have a valid catalog then load our messages:\n      //\n      if (cat)\n      {\n         for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_syntax(i));\n            for (string_type::size_type j = 0; j < mss.size(); ++j)\n            {\n               m_char_map[static_cast<unsigned char>(mss[j])] = i;\n            }\n         }\n      }\n      else\n      {\n         for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            const char* ptr = get_default_syntax(i);\n            while (ptr && *ptr)\n            {\n               m_char_map[static_cast<unsigned char>(*ptr)] = i;\n               ++ptr;\n            }\n         }\n      }\n      //\n      // finish off by calculating our escape types:\n      //\n      unsigned char i = 'A';\n      do\n      {\n         if (m_char_map[i] == 0)\n         {\n            if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0002u, (char)i))\n               m_char_map[i] = regex_constants::escape_type_class;\n            else if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0001u, (char)i))\n               m_char_map[i] = regex_constants::escape_type_not_class;\n         }\n      } while (0xFF != i++);\n\n      //\n      // fill in lower case map:\n      //\n      char char_map[1 << CHAR_BIT];\n      for (int ii = 0; ii < (1 << CHAR_BIT); ++ii)\n         char_map[ii] = static_cast<char>(ii);\n#ifndef BOOST_NO_ANSI_APIS\n      int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(r != 0);\n#else\n      UINT code_page = get_code_page_for_locale_id(this->m_locale);\n      BOOST_REGEX_ASSERT(code_page != 0);\n\n      WCHAR wide_char_map[1 << CHAR_BIT];\n      int conv_r = ::MultiByteToWideChar(code_page, 0, char_map, 1 << CHAR_BIT, wide_char_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(conv_r != 0);\n\n      WCHAR wide_lower_map[1 << CHAR_BIT];\n      int r = ::LCMapStringW(this->m_locale, LCMAP_LOWERCASE, wide_char_map, 1 << CHAR_BIT, wide_lower_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(r != 0);\n\n      conv_r = ::WideCharToMultiByte(code_page, 0, wide_lower_map, r, this->m_lower_map, 1 << CHAR_BIT, NULL, NULL);\n      BOOST_REGEX_ASSERT(conv_r != 0);\n#endif\n      if (r < (1 << CHAR_BIT))\n      {\n         // if we have multibyte characters then not all may have been given\n         // a lower case mapping:\n         for (int jj = r; jj < (1 << CHAR_BIT); ++jj)\n            this->m_lower_map[jj] = static_cast<char>(jj);\n      }\n\n#ifndef BOOST_NO_ANSI_APIS\n      r = ::GetStringTypeExA(this->m_locale, CT_CTYPE1, char_map, 1 << CHAR_BIT, this->m_type_map);\n#else\n      r = ::GetStringTypeExW(this->m_locale, CT_CTYPE1, wide_char_map, 1 << CHAR_BIT, this->m_type_map);\n#endif\n      BOOST_REGEX_ASSERT(0 != r);\n   }\n\n   inline lcid_type BOOST_REGEX_CALL w32_get_default_locale()\n   {\n      return ::GetUserDefaultLCID();\n   }\n\n   inline bool BOOST_REGEX_CALL w32_is_lower(char c, lcid_type idx)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      WORD mask;\n      if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER))\n         return true;\n      return false;\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      WCHAR wide_c;\n      if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      WORD mask;\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_LOWER))\n         return true;\n      return false;\n#endif\n   }\n\n   inline bool BOOST_REGEX_CALL w32_is_lower(wchar_t c, lcid_type idx)\n   {\n      WORD mask;\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER))\n         return true;\n      return false;\n   }\n\n   inline bool BOOST_REGEX_CALL w32_is_upper(char c, lcid_type idx)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      WORD mask;\n      if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER))\n         return true;\n      return false;\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      WCHAR wide_c;\n      if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      WORD mask;\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_UPPER))\n         return true;\n      return false;\n#endif\n   }\n\n   inline bool BOOST_REGEX_CALL w32_is_upper(wchar_t c, lcid_type idx)\n   {\n      WORD mask;\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER))\n         return true;\n      return false;\n   }\n\n   inline void free_module(void* mod)\n   {\n      ::FreeLibrary(static_cast<HMODULE>(mod));\n   }\n\n   inline cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      cat_type result(::LoadLibraryA(name.c_str()), &free_module);\n      return result;\n#else\n      LPWSTR wide_name = (LPWSTR)_alloca((name.size() + 1) * sizeof(WCHAR));\n      if (::MultiByteToWideChar(CP_ACP, 0, name.c_str(), name.size(), wide_name, name.size() + 1) == 0)\n         return cat_type();\n\n      cat_type result(::LoadLibraryW(wide_name), &free_module);\n      return result;\n#endif\n   }\n\n   inline std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::string& def)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      char buf[256];\n      if (0 == ::LoadStringA(\n         static_cast<HMODULE>(cat.get()),\n         i,\n         buf,\n         256\n      ))\n      {\n         return def;\n      }\n#else\n      WCHAR wbuf[256];\n      int r = ::LoadStringW(\n         static_cast<HMODULE>(cat.get()),\n         i,\n         wbuf,\n         256\n      );\n      if (r == 0)\n         return def;\n\n\n      int buf_size = 1 + ::WideCharToMultiByte(CP_ACP, 0, wbuf, r, NULL, 0, NULL, NULL);\n      LPSTR buf = (LPSTR)_alloca(buf_size);\n      if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0)\n         return def; // failed conversion.\n#endif\n      return std::string(buf);\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def)\n   {\n      wchar_t buf[256];\n      if (0 == ::LoadStringW(\n         static_cast<HMODULE>(cat.get()),\n         i,\n         buf,\n         256\n      ))\n      {\n         return def;\n      }\n      return std::wstring(buf);\n   }\n#endif\n   inline std::string BOOST_REGEX_CALL w32_transform(lcid_type idx, const char* p1, const char* p2)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      int bytes = ::LCMapStringA(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::string(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = ::LCMapStringA(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         &*result.begin(),  // destination buffer\n         bytes        // size of destination buffer\n      );\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return std::string(p1, p2);\n\n      int src_len = static_cast<int>(p2 - p1);\n      LPWSTR wide_p1 = (LPWSTR)_alloca((src_len + 1) * 2);\n      if (::MultiByteToWideChar(code_page, 0, p1, src_len, wide_p1, src_len + 1) == 0)\n         return std::string(p1, p2);\n\n      int bytes = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         wide_p1,  // source string\n         src_len,        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::string(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         wide_p1,  // source string\n         src_len,        // number of characters in source string\n         (LPWSTR) & *result.begin(),  // destination buffer\n         bytes        // size of destination buffer\n      );\n#endif\n      if (bytes > static_cast<int>(result.size()))\n         return std::string(p1, p2);\n      while (result.size() && result[result.size() - 1] == '\\0')\n      {\n         result.erase(result.size() - 1);\n      }\n      return result;\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline std::wstring BOOST_REGEX_CALL w32_transform(lcid_type idx, const wchar_t* p1, const wchar_t* p2)\n   {\n      int bytes = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::wstring(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_SORTKEY,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         reinterpret_cast<wchar_t*>(&*result.begin()),  // destination buffer *of bytes*\n         bytes        // size of destination buffer\n      );\n      if (bytes > static_cast<int>(result.size()))\n         return std::wstring(p1, p2);\n      while (result.size() && result[result.size() - 1] == L'\\0')\n      {\n         result.erase(result.size() - 1);\n      }\n      std::wstring r2;\n      for (std::string::size_type i = 0; i < result.size(); ++i)\n         r2.append(1, static_cast<wchar_t>(static_cast<unsigned char>(result[i])));\n      return r2;\n   }\n#endif\n   inline char BOOST_REGEX_CALL w32_tolower(char c, lcid_type idx)\n   {\n      char result[2];\n#ifndef BOOST_NO_ANSI_APIS\n      int b = ::LCMapStringA(\n         idx,       // locale identifier\n         LCMAP_LOWERCASE,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return c;\n\n      WCHAR wide_c;\n      if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return c;\n\n      WCHAR wide_result;\n      int b = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_LOWERCASE,  // mapping transformation type\n         &wide_c,  // source string\n         1,        // number of characters in source string\n         &wide_result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n\n      if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)\n         return c;  // No single byte lower case equivalent available\n#endif\n      return result[0];\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type idx)\n   {\n      wchar_t result[2];\n      int b = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_LOWERCASE,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n      return result[0];\n   }\n#endif\n   inline char BOOST_REGEX_CALL w32_toupper(char c, lcid_type idx)\n   {\n      char result[2];\n#ifndef BOOST_NO_ANSI_APIS\n      int b = ::LCMapStringA(\n         idx,       // locale identifier\n         LCMAP_UPPERCASE,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return c;\n\n      WCHAR wide_c;\n      if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return c;\n\n      WCHAR wide_result;\n      int b = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_UPPERCASE,  // mapping transformation type\n         &wide_c,  // source string\n         1,        // number of characters in source string\n         &wide_result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n\n      if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)\n         return c;  // No single byte upper case equivalent available.\n#endif\n      return result[0];\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type idx)\n   {\n      wchar_t result[2];\n      int b = ::LCMapStringW(\n         idx,       // locale identifier\n         LCMAP_UPPERCASE,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n      return result[0];\n   }\n#endif\n   inline bool BOOST_REGEX_CALL w32_is(lcid_type idx, boost::uint32_t m, char c)\n   {\n      WORD mask;\n#ifndef BOOST_NO_ANSI_APIS\n      if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))\n         return true;\n#else\n      UINT code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      WCHAR wide_c;\n      if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))\n         return true;\n#endif\n      if ((m & w32_regex_traits_implementation<char>::mask_word) && (c == '_'))\n         return true;\n      return false;\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline bool BOOST_REGEX_CALL w32_is(lcid_type idx, boost::uint32_t m, wchar_t c)\n   {\n      WORD mask;\n      if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base))\n         return true;\n      if ((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_'))\n         return true;\n      if ((m & w32_regex_traits_implementation<wchar_t>::mask_unicode) && (c > 0xff))\n         return true;\n      return false;\n   }\n#endif\n\n} // BOOST_REGEX_DETAIL_NS\n\n\n} // boost\n\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#ifdef BOOST_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4103)\n#endif\n#ifdef BOOST_HAS_ABI_HEADERS\n#  include BOOST_ABI_SUFFIX\n#endif\n#ifdef BOOST_MSVC\n#pragma warning(pop)\n#endif\n\n#endif // BOOST_REGEX_NO_WIN32_LOCALE\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/basic_regex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2004 John Maddock\n * Copyright 2011 Garmin Ltd. or its subsidiaries\n *\n * Distributed under the Boost Software License, Version 1.0.\n * (See accompanying file LICENSE_1_0.txt or copy at\n * http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org/ for most recent version.\n  *   FILE         basic_regex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex.\n  */\n\n#ifndef BOOST_REGEX_V5_BASIC_REGEX_HPP\n#define BOOST_REGEX_V5_BASIC_REGEX_HPP\n\n#include <vector>\n\nnamespace boost{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#if BOOST_REGEX_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#if BOOST_REGEX_MSVC < 1600\n#pragma warning(disable : 4660)\n#endif\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// forward declaration, we will need this one later:\n//\ntemplate <class charT, class traits>\nclass basic_regex_parser;\n\ntemplate <class I>\nvoid bubble_down_one(I first, I last)\n{\n   if(first != last)\n   {\n      I next = last - 1;\n      while((next != first) && (*next < *(next-1)))\n      {\n         (next-1)->swap(*next);\n         --next;\n      }\n   }\n}\n\nstatic const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);\n\ntemplate <class Iterator>\ninline int hash_value_from_capture_name(Iterator i, Iterator j)\n{\n   std::size_t r = 0;\n   while (i != j)\n   {\n      r ^= *i + 0x9e3779b9 + (r << 6) + (r >> 2);\n      ++i;\n   }\n   r %= ((std::numeric_limits<int>::max)());\n   return static_cast<int>(r) | hash_value_mask;\n}\n\nclass named_subexpressions\n{\npublic:\n   struct name\n   {\n      template <class charT>\n      name(const charT* i, const charT* j, int idx)\n         : index(idx) \n      { \n         hash = hash_value_from_capture_name(i, j); \n      }\n      name(int h, int idx)\n         : index(idx), hash(h)\n      { \n      }\n      int index;\n      int hash;\n      bool operator < (const name& other)const\n      {\n         return hash < other.hash;\n      }\n      bool operator == (const name& other)const\n      {\n         return hash == other.hash; \n      }\n      void swap(name& other)\n      {\n         std::swap(index, other.index);\n         std::swap(hash, other.hash);\n      }\n   };\n\n   typedef std::vector<name>::const_iterator const_iterator;\n   typedef std::pair<const_iterator, const_iterator> range_type;\n\n   named_subexpressions(){}\n\n   template <class charT>\n   void set_name(const charT* i, const charT* j, int index)\n   {\n      m_sub_names.push_back(name(i, j, index));\n      bubble_down_one(m_sub_names.begin(), m_sub_names.end());\n   }\n   template <class charT>\n   int get_id(const charT* i, const charT* j)const\n   {\n      name t(i, j, 0);\n      typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);\n      if((pos != m_sub_names.end()) && (*pos == t))\n      {\n         return pos->index;\n      }\n      return -1;\n   }\n   template <class charT>\n   range_type equal_range(const charT* i, const charT* j)const\n   {\n      name t(i, j, 0);\n      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);\n   }\n   int get_id(int h)const\n   {\n      name t(h, 0);\n      std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);\n      if((pos != m_sub_names.end()) && (*pos == t))\n      {\n         return pos->index;\n      }\n      return -1;\n   }\n   range_type equal_range(int h)const\n   {\n      name t(h, 0);\n      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);\n   }\nprivate:\n   std::vector<name> m_sub_names;\n};\n\n//\n// class regex_data:\n// represents the data we wish to expose to the matching algorithms.\n//\ntemplate <class charT, class traits>\nstruct regex_data : public named_subexpressions\n{\n   typedef regex_constants::syntax_option_type   flag_type;\n   typedef std::size_t                           size_type;  \n\n   regex_data(const ::std::shared_ptr<\n      ::boost::regex_traits_wrapper<traits> >& t) \n      : m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),\n         m_mark_count(0), m_first_state(0), m_restart_type(0),\n         m_startmap{ 0 },\n         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}\n   regex_data() \n      : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0), \n         m_mark_count(0), m_first_state(0), m_restart_type(0), \n      m_startmap{ 0 },\n         m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}\n\n   ::std::shared_ptr<\n      ::boost::regex_traits_wrapper<traits>\n      >                        m_ptraits;                 // traits class instance\n   flag_type                   m_flags;                   // flags with which we were compiled\n   int                         m_status;                  // error code (0 implies OK).\n   const charT*                m_expression;              // the original expression\n   std::ptrdiff_t              m_expression_len;          // the length of the original expression\n   size_type                   m_mark_count;              // the number of marked sub-expressions\n   BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine\n   unsigned                    m_restart_type;            // search optimisation type\n   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match\n   unsigned int                m_can_be_null;             // whether we can match a null string\n   BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed\n   typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character\n   std::vector<\n      std::pair<\n      std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.\n   bool                        m_has_recursions;          // whether we have recursive expressions;\n   bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.\n};\n//\n// class basic_regex_implementation\n// pimpl implementation class for basic_regex.\n//\ntemplate <class charT, class traits>\nclass basic_regex_implementation\n   : public regex_data<charT, traits>\n{\npublic:\n   typedef regex_constants::syntax_option_type   flag_type;\n   typedef std::ptrdiff_t                        difference_type;\n   typedef std::size_t                           size_type; \n   typedef typename traits::locale_type          locale_type;\n   typedef const charT*                          const_iterator;\n\n   basic_regex_implementation(){}\n   basic_regex_implementation(const ::std::shared_ptr<\n      ::boost::regex_traits_wrapper<traits> >& t)\n      : regex_data<charT, traits>(t) {}\n   void assign(const charT* arg_first,\n                          const charT* arg_last,\n                          flag_type f)\n   {\n      regex_data<charT, traits>* pdat = this;\n      basic_regex_parser<charT, traits> parser(pdat);\n      parser.parse(arg_first, arg_last, f);\n   }\n\n   locale_type  imbue(locale_type l)\n   { \n      return this->m_ptraits->imbue(l); \n   }\n   locale_type  getloc()const\n   { \n      return this->m_ptraits->getloc(); \n   }\n   std::basic_string<charT>  str()const\n   {\n      std::basic_string<charT> result;\n      if(this->m_status == 0)\n         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);\n      return result;\n   }\n   const_iterator  expression()const\n   {\n      return this->m_expression;\n   }\n   std::pair<const_iterator, const_iterator>  subexpression(std::size_t n)const\n   {\n      const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);\n      std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);\n      return p;\n   }\n   //\n   // begin, end:\n   const_iterator  begin()const\n   { \n      return (this->m_status ? 0 : this->m_expression); \n   }\n   const_iterator  end()const\n   { \n      return (this->m_status ? 0 : this->m_expression + this->m_expression_len); \n   }\n   flag_type  flags()const\n   {\n      return this->m_flags;\n   }\n   size_type  size()const\n   {\n      return this->m_expression_len;\n   }\n   int  status()const\n   {\n      return this->m_status;\n   }\n   size_type  mark_count()const\n   {\n      return this->m_mark_count - 1;\n   }\n   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const\n   {\n      return this->m_first_state;\n   }\n   unsigned get_restart_type()const\n   {\n      return this->m_restart_type;\n   }\n   const unsigned char* get_map()const\n   {\n      return this->m_startmap;\n   }\n   const ::boost::regex_traits_wrapper<traits>& get_traits()const\n   {\n      return *(this->m_ptraits);\n   }\n   bool can_be_null()const\n   {\n      return this->m_can_be_null;\n   }\n   const regex_data<charT, traits>& get_data()const\n   {\n      basic_regex_implementation<charT, traits> const* p = this;\n      return *static_cast<const regex_data<charT, traits>*>(p);\n   }\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n//\n// class basic_regex:\n// represents the compiled\n// regular expression:\n//\n\n#ifdef BOOST_REGEX_NO_FWD\ntemplate <class charT, class traits = regex_traits<charT> >\n#else\ntemplate <class charT, class traits >\n#endif\nclass basic_regex : public regbase\n{\npublic:\n   // typedefs:\n   typedef std::size_t                           traits_size_type;\n   typedef typename traits::string_type          traits_string_type;\n   typedef charT                                 char_type;\n   typedef traits                                traits_type;\n\n   typedef charT                                 value_type;\n   typedef charT&                                reference;\n   typedef const charT&                          const_reference;\n   typedef const charT*                          const_iterator;\n   typedef const_iterator                        iterator;\n   typedef std::ptrdiff_t                        difference_type;\n   typedef std::size_t                           size_type;   \n   typedef regex_constants::syntax_option_type   flag_type;\n   // locale_type\n   // placeholder for actual locale type used by the\n   // traits class to localise *this.\n   typedef typename traits::locale_type          locale_type;\n   \npublic:\n   explicit basic_regex(){}\n   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)\n   {\n      assign(p, f);\n   }\n   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n   {\n      assign(p1, p2, f);\n   }\n   basic_regex(const charT* p, size_type len, flag_type f)\n   {\n      assign(p, len, f);\n   }\n   basic_regex(const basic_regex& that)\n      : m_pimpl(that.m_pimpl) {}\n   ~basic_regex(){}\n   basic_regex&  operator=(const basic_regex& that)\n   {\n      return assign(that);\n   }\n   basic_regex&  operator=(const charT* ptr)\n   {\n      return assign(ptr);\n   }\n\n   //\n   // assign:\n   basic_regex& assign(const basic_regex& that)\n   { \n      m_pimpl = that.m_pimpl;\n      return *this; \n   }\n   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)\n   {\n      return assign(p, p + traits::length(p), f);\n   }\n   basic_regex& assign(const charT* p, size_type len, flag_type f)\n   {\n      return assign(p, p + len, f);\n   }\nprivate:\n   basic_regex& do_assign(const charT* p1,\n                          const charT* p2,\n                          flag_type f);\npublic:\n   basic_regex& assign(const charT* p1,\n                          const charT* p2,\n                          flag_type f = regex_constants::normal)\n   {\n      return do_assign(p1, p2, f);\n   }\n\n   template <class ST, class SA>\n   unsigned int  set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   { \n      return set_expression(p.data(), p.data() + p.size(), f); \n   }\n\n   template <class ST, class SA>\n   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   { \n      assign(p, f); \n   }\n\n   template <class InputIterator>\n   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)\n   {\n      typedef typename traits::string_type seq_type;\n      seq_type a(arg_first, arg_last);\n      if(!a.empty())\n         assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);\n      else\n         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);\n   }\n\n   template <class ST, class SA>\n   basic_regex&  operator=(const std::basic_string<charT, ST, SA>& p)\n   {\n      return assign(p.data(), p.data() + p.size(), regex_constants::normal);\n   }\n\n   template <class string_traits, class A>\n   basic_regex&  assign(\n       const std::basic_string<charT, string_traits, A>& s,\n       flag_type f = regex_constants::normal)\n   {\n      return assign(s.data(), s.data() + s.size(), f);\n   }\n\n   template <class InputIterator>\n   basic_regex&  assign(InputIterator arg_first,\n                          InputIterator arg_last,\n                          flag_type f = regex_constants::normal)\n   {\n      typedef typename traits::string_type seq_type;\n      seq_type a(arg_first, arg_last);\n      if(a.size())\n      {\n         const charT* p1 = &*a.begin();\n         const charT* p2 = &*a.begin() + a.size();\n         return assign(p1, p2, f);\n      }\n      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);\n   }\n\n   //\n   // locale:\n   locale_type  imbue(locale_type l);\n   locale_type  getloc()const\n   { \n      return m_pimpl.get() ? m_pimpl->getloc() : locale_type(); \n   }\n   //\n   // getflags:\n   // retained for backwards compatibility only, \"flags\"\n   // is now the preferred name:\n   flag_type  getflags()const\n   { \n      return flags();\n   }\n   flag_type  flags()const\n   { \n      return m_pimpl.get() ? m_pimpl->flags() : 0;\n   }\n   //\n   // str:\n   std::basic_string<charT>  str()const\n   {\n      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();\n   }\n   //\n   // begin, end, subexpression:\n   std::pair<const_iterator, const_iterator>  subexpression(std::size_t n)const\n   {\n#ifdef BOOST_REGEX_STANDALONE\n      if (!m_pimpl.get())\n         throw std::logic_error(\"Can't access subexpressions in an invalid regex.\");\n#else\n      if(!m_pimpl.get())\n         boost::throw_exception(std::logic_error(\"Can't access subexpressions in an invalid regex.\"));\n#endif\n      return m_pimpl->subexpression(n);\n   }\n   const_iterator  begin()const\n   { \n      return (m_pimpl.get() ? m_pimpl->begin() : 0); \n   }\n   const_iterator  end()const\n   { \n      return (m_pimpl.get() ? m_pimpl->end() : 0); \n   }\n   //\n   // swap:\n   void  swap(basic_regex& that)throw()\n   {\n      m_pimpl.swap(that.m_pimpl);\n   }\n   //\n   // size:\n   size_type  size()const\n   { \n      return (m_pimpl.get() ? m_pimpl->size() : 0); \n   }\n   //\n   // max_size:\n   size_type  max_size()const\n   { \n      return UINT_MAX; \n   }\n   //\n   // empty:\n   bool  empty()const\n   { \n      return (m_pimpl.get() ? 0 != m_pimpl->status() : true); \n   }\n\n   size_type  mark_count()const \n   { \n      return (m_pimpl.get() ? m_pimpl->mark_count() : 0); \n   }\n\n   int status()const\n   {\n      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);\n   }\n\n   int  compare(const basic_regex& that) const\n   {\n      if(m_pimpl.get() == that.m_pimpl.get())\n         return 0;\n      if(!m_pimpl.get())\n         return -1;\n      if(!that.m_pimpl.get())\n         return 1;\n      if(status() != that.status())\n         return status() - that.status();\n      if(flags() != that.flags())\n         return flags() - that.flags();\n      return str().compare(that.str());\n   }\n   bool  operator==(const basic_regex& e)const\n   { \n      return compare(e) == 0; \n   }\n   bool  operator != (const basic_regex& e)const\n   { \n      return compare(e) != 0; \n   }\n   bool  operator<(const basic_regex& e)const\n   { \n      return compare(e) < 0; \n   }\n   bool  operator>(const basic_regex& e)const\n   { \n      return compare(e) > 0; \n   }\n   bool  operator<=(const basic_regex& e)const\n   { \n      return compare(e) <= 0; \n   }\n   bool  operator>=(const basic_regex& e)const\n   { \n      return compare(e) >= 0; \n   }\n\n   //\n   // The following are deprecated as public interfaces\n   // but are available for compatibility with earlier versions.\n   const charT*  expression()const \n   { \n      return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0); \n   }\n   unsigned int  set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n   {\n      assign(p1, p2, f | regex_constants::no_except);\n      return status();\n   }\n   unsigned int  set_expression(const charT* p, flag_type f = regex_constants::normal) \n   { \n      assign(p, f | regex_constants::no_except); \n      return status();\n   }\n   unsigned int  error_code()const\n   {\n      return status();\n   }\n   //\n   // private access methods:\n   //\n   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_first_state();\n   }\n   unsigned get_restart_type()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_restart_type();\n   }\n   const unsigned char* get_map()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_map();\n   }\n   const ::boost::regex_traits_wrapper<traits>& get_traits()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_traits();\n   }\n   bool can_be_null()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->can_be_null();\n   }\n   const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const\n   {\n      BOOST_REGEX_ASSERT(0 != m_pimpl.get());\n      return m_pimpl->get_data();\n   }\n   std::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const\n   {\n      return m_pimpl;\n   }\n\nprivate:\n   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;\n};\n\n//\n// out of line members;\n// these are the only members that mutate the basic_regex object,\n// and are designed to provide the strong exception guarantee\n// (in the event of a throw, the state of the object remains unchanged).\n//\ntemplate <class charT, class traits>\nbasic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,\n                        const charT* p2,\n                        flag_type f)\n{\n   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;\n   if(!m_pimpl.get())\n   {\n      temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());\n   }\n   else\n   {\n      temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));\n   }\n   temp->assign(p1, p2, f);\n   temp.swap(m_pimpl);\n   return *this;\n}\n\ntemplate <class charT, class traits>\ntypename basic_regex<charT, traits>::locale_type  basic_regex<charT, traits>::imbue(locale_type l)\n{ \n   std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());\n   locale_type result = temp->imbue(l);\n   temp.swap(m_pimpl);\n   return result;\n}\n\n//\n// non-members:\n//\ntemplate <class charT, class traits>\nvoid swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)\n{\n   e1.swap(e2);\n}\n\ntemplate <class charT, class traits, class traits2>\nstd::basic_ostream<charT, traits>& \n   operator << (std::basic_ostream<charT, traits>& os, \n                const basic_regex<charT, traits2>& e)\n{\n   return (os << e.str());\n}\n\n//\n// class reg_expression:\n// this is provided for backwards compatibility only,\n// it is deprecated, no not use!\n//\n#ifdef BOOST_REGEX_NO_FWD\ntemplate <class charT, class traits = regex_traits<charT> >\n#else\ntemplate <class charT, class traits >\n#endif\nclass reg_expression : public basic_regex<charT, traits>\n{\npublic:\n   typedef typename basic_regex<charT, traits>::flag_type flag_type;\n   typedef typename basic_regex<charT, traits>::size_type size_type;\n   explicit reg_expression(){}\n   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)\n      : basic_regex<charT, traits>(p, f){}\n   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)\n      : basic_regex<charT, traits>(p1, p2, f){}\n   reg_expression(const charT* p, size_type len, flag_type f)\n      : basic_regex<charT, traits>(p, len, f){}\n   reg_expression(const reg_expression& that)\n      : basic_regex<charT, traits>(that) {}\n   ~reg_expression(){}\n   reg_expression&  operator=(const reg_expression& that)\n   {\n      return this->assign(that);\n   }\n\n   template <class ST, class SA>\n   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)\n   : basic_regex<charT, traits>(p, f)\n   { \n   }\n\n   template <class InputIterator>\n   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)\n   : basic_regex<charT, traits>(arg_first, arg_last, f)\n   {\n   }\n\n   template <class ST, class SA>\n   reg_expression&  operator=(const std::basic_string<charT, ST, SA>& p)\n   {\n      this->assign(p);\n      return *this;\n   }\n\n};\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning (pop)\n#endif\n\n} // namespace boost\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/basic_regex_creator.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_creator.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_creator which fills in\n  *                the data members of a regex_data object.\n  */\n\n#ifndef BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP\n#define BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable:4459)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\n#include <set>\n\nnamespace boost{\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class charT>\nstruct digraph : public std::pair<charT, charT>\n{\n   digraph() : std::pair<charT, charT>(charT(0), charT(0)){}\n   digraph(charT c1) : std::pair<charT, charT>(c1, charT(0)){}\n   digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)\n   {}\n   digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}\n   digraph<charT>& operator=(const digraph<charT>&) = default;\n   template <class Seq>\n   digraph(const Seq& s) : std::pair<charT, charT>()\n   {\n      BOOST_REGEX_ASSERT(s.size() <= 2);\n      BOOST_REGEX_ASSERT(s.size());\n      this->first = s[0];\n      this->second = (s.size() > 1) ? s[1] : 0;\n   }\n};\n\ntemplate <class charT, class traits>\nclass basic_char_set\n{\npublic:\n   typedef digraph<charT>                   digraph_type;\n   typedef typename traits::string_type     string_type;\n   typedef typename traits::char_class_type m_type;\n\n   basic_char_set()\n   {\n      m_negate = false;\n      m_has_digraphs = false;\n      m_classes = 0;\n      m_negated_classes = 0;\n      m_empty = true;\n   }\n\n   void add_single(const digraph_type& s)\n   {\n      m_singles.insert(s);\n      if(s.second)\n         m_has_digraphs = true;\n      m_empty = false;\n   }\n   void add_range(const digraph_type& first, const digraph_type& end)\n   {\n      m_ranges.push_back(first);\n      m_ranges.push_back(end);\n      if(first.second)\n      {\n         m_has_digraphs = true;\n         add_single(first);\n      }\n      if(end.second)\n      {\n         m_has_digraphs = true;\n         add_single(end);\n      }\n      m_empty = false;\n   }\n   void add_class(m_type m)\n   {\n      m_classes |= m;\n      m_empty = false;\n   }\n   void add_negated_class(m_type m)\n   {\n      m_negated_classes |= m;\n      m_empty = false;\n   }\n   void add_equivalent(const digraph_type& s)\n   {\n      m_equivalents.insert(s);\n      if(s.second)\n      {\n         m_has_digraphs = true;\n         add_single(s);\n      }\n      m_empty = false;\n   }\n   void negate()\n   { \n      m_negate = true;\n      //m_empty = false;\n   }\n\n   //\n   // accessor functions:\n   //\n   bool has_digraphs()const\n   {\n      return m_has_digraphs;\n   }\n   bool is_negated()const\n   {\n      return m_negate;\n   }\n   typedef typename std::vector<digraph_type>::const_iterator  list_iterator;\n   typedef typename std::set<digraph_type>::const_iterator     set_iterator;\n   set_iterator singles_begin()const\n   {\n      return m_singles.begin();\n   }\n   set_iterator singles_end()const\n   {\n      return m_singles.end();\n   }\n   list_iterator ranges_begin()const\n   {\n      return m_ranges.begin();\n   }\n   list_iterator ranges_end()const\n   {\n      return m_ranges.end();\n   }\n   set_iterator equivalents_begin()const\n   {\n      return m_equivalents.begin();\n   }\n   set_iterator equivalents_end()const\n   {\n      return m_equivalents.end();\n   }\n   m_type classes()const\n   {\n      return m_classes;\n   }\n   m_type negated_classes()const\n   {\n      return m_negated_classes;\n   }\n   bool empty()const\n   {\n      return m_empty;\n   }\nprivate:\n   std::set<digraph_type>    m_singles;         // a list of single characters to match\n   std::vector<digraph_type> m_ranges;          // a list of end points of our ranges\n   bool                      m_negate;          // true if the set is to be negated\n   bool                      m_has_digraphs;    // true if we have digraphs present\n   m_type                    m_classes;         // character classes to match\n   m_type                    m_negated_classes; // negated character classes to match\n   bool                      m_empty;           // whether we've added anything yet\n   std::set<digraph_type>    m_equivalents;     // a list of equivalence classes\n};\n   \ntemplate <class charT, class traits>\nclass basic_regex_creator\n{\npublic:\n   basic_regex_creator(regex_data<charT, traits>* data);\n   std::ptrdiff_t getoffset(void* addr)\n   {\n      return getoffset(addr, m_pdata->m_data.data());\n   }\n   std::ptrdiff_t getoffset(const void* addr, const void* base)\n   {\n      return static_cast<const char*>(addr) - static_cast<const char*>(base);\n   }\n   re_syntax_base* getaddress(std::ptrdiff_t off)\n   {\n      return getaddress(off, m_pdata->m_data.data());\n   }\n   re_syntax_base* getaddress(std::ptrdiff_t off, void* base)\n   {\n      return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));\n   }\n   void init(unsigned l_flags)\n   {\n      m_pdata->m_flags = l_flags;\n      m_icase = l_flags & regex_constants::icase;\n   }\n   regbase::flag_type flags()\n   {\n      return m_pdata->m_flags;\n   }\n   void flags(regbase::flag_type f)\n   {\n      m_pdata->m_flags = f;\n      if(m_icase != static_cast<bool>(f & regbase::icase))\n      {\n         m_icase = static_cast<bool>(f & regbase::icase);\n      }\n   }\n   re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));\n   re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));\n   re_literal* append_literal(charT c);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, false>*);\n   re_syntax_base* append_set(const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, true>*);\n   void finalize(const charT* p1, const charT* p2);\nprotected:\n   regex_data<charT, traits>*    m_pdata;              // pointer to the basic_regex_data struct we are filling in\n   const ::boost::regex_traits_wrapper<traits>&  \n                                 m_traits;             // convenience reference to traits class\n   re_syntax_base*               m_last_state;         // the last state we added\n   bool                          m_icase;              // true for case insensitive matches\n   unsigned                      m_repeater_id;        // the state_id of the next repeater\n   bool                          m_has_backrefs;       // true if there are actually any backrefs\n   std::uintmax_t                m_bad_repeats;        // bitmask of repeats we can't deduce a startmap for;\n   bool                          m_has_recursions;     // set when we have recursive expressions to fixup\n   std::vector<unsigned char>    m_recursion_checks;   // notes which recursions we've followed while analysing this expression\n   typename traits::char_class_type m_word_mask;       // mask used to determine if a character is a word character\n   typename traits::char_class_type m_mask_space;      // mask used to determine if a character is a word character\n   typename traits::char_class_type m_lower_mask;       // mask used to determine if a character is a lowercase character\n   typename traits::char_class_type m_upper_mask;      // mask used to determine if a character is an uppercase character\n   typename traits::char_class_type m_alpha_mask;      // mask used to determine if a character is an alphabetic character\nprivate:\n   basic_regex_creator& operator=(const basic_regex_creator&);\n   basic_regex_creator(const basic_regex_creator&);\n\n   void fixup_pointers(re_syntax_base* state);\n   void fixup_recursions(re_syntax_base* state);\n   void create_startmaps(re_syntax_base* state);\n   int calculate_backstep(re_syntax_base* state);\n   void create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask);\n   unsigned get_restart_type(re_syntax_base* state);\n   void set_all_masks(unsigned char* bits, unsigned char);\n   bool is_bad_repeat(re_syntax_base* pt);\n   void set_bad_repeat(re_syntax_base* pt);\n   syntax_element_type get_repeat_type(re_syntax_base* state);\n   void probe_leading_repeat(re_syntax_base* state);\n};\n\ntemplate <class charT, class traits>\nbasic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)\n   : m_pdata(data), m_traits(*(data->m_ptraits)), m_last_state(0), m_icase(false), m_repeater_id(0), \n   m_has_backrefs(false), m_bad_repeats(0), m_has_recursions(false), m_word_mask(0), m_mask_space(0), m_lower_mask(0), m_upper_mask(0), m_alpha_mask(0)\n{\n   m_pdata->m_data.clear();\n   m_pdata->m_status = ::boost::regex_constants::error_ok;\n   static const charT w = 'w';\n   static const charT s = 's';\n   static const charT l[5] = { 'l', 'o', 'w', 'e', 'r', };\n   static const charT u[5] = { 'u', 'p', 'p', 'e', 'r', };\n   static const charT a[5] = { 'a', 'l', 'p', 'h', 'a', };\n   m_word_mask = m_traits.lookup_classname(&w, &w +1);\n   m_mask_space = m_traits.lookup_classname(&s, &s +1);\n   m_lower_mask = m_traits.lookup_classname(l, l + 5);\n   m_upper_mask = m_traits.lookup_classname(u, u + 5);\n   m_alpha_mask = m_traits.lookup_classname(a, a + 5);\n   m_pdata->m_word_mask = m_word_mask;\n   BOOST_REGEX_ASSERT(m_word_mask != 0); \n   BOOST_REGEX_ASSERT(m_mask_space != 0); \n   BOOST_REGEX_ASSERT(m_lower_mask != 0); \n   BOOST_REGEX_ASSERT(m_upper_mask != 0); \n   BOOST_REGEX_ASSERT(m_alpha_mask != 0); \n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)\n{\n   // if the state is a backref then make a note of it:\n   if(t == syntax_element_backref)\n      this->m_has_backrefs = true;\n   // append a new state, start by aligning our last one:\n   m_pdata->m_data.align();\n   // set the offset to the next state in our last one:\n   if(m_last_state)\n      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);\n   // now actually extend our data:\n   m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));\n   // fill in boilerplate options in the new state:\n   m_last_state->next.i = 0;\n   m_last_state->type = t;\n   return m_last_state;\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)\n{\n   // append a new state, start by aligning our last one:\n   m_pdata->m_data.align();\n   // set the offset to the next state in our last one:\n   if(m_last_state)\n      m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);\n   // remember the last state position:\n   std::ptrdiff_t off = getoffset(m_last_state) + s;\n   // now actually insert our data:\n   re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));\n   // fill in boilerplate options in the new state:\n   new_state->next.i = s;\n   new_state->type = t;\n   m_last_state = getaddress(off);\n   return new_state;\n}\n\ntemplate <class charT, class traits>\nre_literal* basic_regex_creator<charT, traits>::append_literal(charT c)\n{\n   re_literal* result;\n   // start by seeing if we have an existing re_literal we can extend:\n   if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))\n   {\n      // no existing re_literal, create a new one:\n      result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));\n      result->length = 1;\n      *static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);\n   }\n   else\n   {\n      // we have an existing re_literal, extend it:\n      std::ptrdiff_t off = getoffset(m_last_state);\n      m_pdata->m_data.extend(sizeof(charT));\n      m_last_state = result = static_cast<re_literal*>(getaddress(off));\n      charT* characters = static_cast<charT*>(static_cast<void*>(result+1));\n      characters[result->length] = m_traits.translate(c, m_icase);\n      result->length += 1;\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\ninline re_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set)\n{\n   typedef std::integral_constant<bool, (sizeof(charT) == 1) > truth_type;\n   return char_set.has_digraphs() \n      ? append_set(char_set, static_cast<std::integral_constant<bool, false>*>(0))\n      : append_set(char_set, static_cast<truth_type*>(0));\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, false>*)\n{\n   typedef typename traits::string_type string_type;\n   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;\n   typedef typename basic_char_set<charT, traits>::set_iterator  set_iterator;\n   typedef typename traits::char_class_type m_type;\n   \n   re_set_long<m_type>* result = static_cast<re_set_long<m_type>*>(append_state(syntax_element_long_set, sizeof(re_set_long<m_type>)));\n   //\n   // fill in the basics:\n   //\n   result->csingles = static_cast<unsigned int>(std::distance(char_set.singles_begin(), char_set.singles_end()));\n   result->cranges = static_cast<unsigned int>(std::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;\n   result->cequivalents = static_cast<unsigned int>(std::distance(char_set.equivalents_begin(), char_set.equivalents_end()));\n   result->cclasses = char_set.classes();\n   result->cnclasses = char_set.negated_classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust classes as needed:\n      if(((result->cclasses & m_lower_mask) == m_lower_mask) || ((result->cclasses & m_upper_mask) == m_upper_mask))\n         result->cclasses |= m_alpha_mask;\n      if(((result->cnclasses & m_lower_mask) == m_lower_mask) || ((result->cnclasses & m_upper_mask) == m_upper_mask))\n         result->cnclasses |= m_alpha_mask;\n   }\n\n   result->isnot = char_set.is_negated();\n   result->singleton = !char_set.has_digraphs();\n   //\n   // remember where the state is for later:\n   //\n   std::ptrdiff_t offset = getoffset(result);\n   //\n   // now extend with all the singles:\n   //\n   item_iterator first, last;\n   set_iterator sfirst, slast;\n   sfirst = char_set.singles_begin();\n   slast = char_set.singles_end();\n   while(sfirst != slast)\n   {\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (sfirst->first == static_cast<charT>(0) ? 1 : sfirst->second ? 3 : 2)));\n      p[0] = m_traits.translate(sfirst->first, m_icase);\n      if(sfirst->first == static_cast<charT>(0))\n      {\n         p[0] = 0;\n      }\n      else if(sfirst->second)\n      {\n         p[1] = m_traits.translate(sfirst->second, m_icase);\n         p[2] = 0;\n      }\n      else\n         p[1] = 0;\n      ++sfirst;\n   }\n   //\n   // now extend with all the ranges:\n   //\n   first = char_set.ranges_begin();\n   last = char_set.ranges_end();\n   while(first != last)\n   {\n      // first grab the endpoints of the range:\n      digraph<charT> c1 = *first;\n      c1.first = this->m_traits.translate(c1.first, this->m_icase);\n      c1.second = this->m_traits.translate(c1.second, this->m_icase);\n      ++first;\n      digraph<charT> c2 = *first;\n      c2.first = this->m_traits.translate(c2.first, this->m_icase);\n      c2.second = this->m_traits.translate(c2.second, this->m_icase);\n      ++first;\n      string_type s1, s2;\n      // different actions now depending upon whether collation is turned on:\n      if(flags() & regex_constants::collate)\n      {\n         // we need to transform our range into sort keys:\n         charT a1[3] = { c1.first, c1.second, charT(0), };\n         charT a2[3] = { c2.first, c2.second, charT(0), };\n         s1 = this->m_traits.transform(a1, (a1[1] ? a1+2 : a1+1));\n         s2 = this->m_traits.transform(a2, (a2[1] ? a2+2 : a2+1));\n         if(s1.empty())\n            s1 = string_type(1, charT(0));\n         if(s2.empty())\n            s2 = string_type(1, charT(0));\n      }\n      else\n      {\n         if(c1.second)\n         {\n            s1.insert(s1.end(), c1.first);\n            s1.insert(s1.end(), c1.second);\n         }\n         else\n            s1 = string_type(1, c1.first);\n         if(c2.second)\n         {\n            s2.insert(s2.end(), c2.first);\n            s2.insert(s2.end(), c2.second);\n         }\n         else\n            s2.insert(s2.end(), c2.first);\n      }\n      if(s1 > s2)\n      {\n         // Oops error:\n         return 0;\n      }\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s1.size() + s2.size() + 2) ) );\n      BOOST_REGEX_DETAIL_NS::copy(s1.begin(), s1.end(), p);\n      p[s1.size()] = charT(0);\n      p += s1.size() + 1;\n      BOOST_REGEX_DETAIL_NS::copy(s2.begin(), s2.end(), p);\n      p[s2.size()] = charT(0);\n   }\n   //\n   // now process the equivalence classes:\n   //\n   sfirst = char_set.equivalents_begin();\n   slast = char_set.equivalents_end();\n   while(sfirst != slast)\n   {\n      string_type s;\n      if(sfirst->second)\n      {\n         charT cs[3] = { sfirst->first, sfirst->second, charT(0), };\n         s = m_traits.transform_primary(cs, cs+2);\n      }\n      else\n         s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);\n      if(s.empty())\n         return 0;  // invalid or unsupported equivalence class\n      charT* p = static_cast<charT*>(this->m_pdata->m_data.extend(sizeof(charT) * (s.size()+1) ) );\n      BOOST_REGEX_DETAIL_NS::copy(s.begin(), s.end(), p);\n      p[s.size()] = charT(0);\n      ++sfirst;\n   }\n   //\n   // finally reset the address of our last state:\n   //\n   m_last_state = result = static_cast<re_set_long<m_type>*>(getaddress(offset));\n   return result;\n}\n\ntemplate<class T>\ninline bool char_less(T t1, T t2)\n{\n   return t1 < t2;\n}\ninline bool char_less(char t1, char t2)\n{\n   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);\n}\ninline bool char_less(signed char t1, signed char t2)\n{\n   return static_cast<unsigned char>(t1) < static_cast<unsigned char>(t2);\n}\n\ntemplate <class charT, class traits>\nre_syntax_base* basic_regex_creator<charT, traits>::append_set(\n   const basic_char_set<charT, traits>& char_set, std::integral_constant<bool, true>*)\n{\n   typedef typename traits::string_type string_type;\n   typedef typename basic_char_set<charT, traits>::list_iterator item_iterator;\n   typedef typename basic_char_set<charT, traits>::set_iterator set_iterator;\n\n   re_set* result = static_cast<re_set*>(append_state(syntax_element_set, sizeof(re_set)));\n   bool negate = char_set.is_negated();\n   std::memset(result->_map, 0, sizeof(result->_map));\n   //\n   // handle singles first:\n   //\n   item_iterator first, last;\n   set_iterator sfirst, slast;\n   sfirst = char_set.singles_begin();\n   slast = char_set.singles_end();\n   while(sfirst != slast)\n   {\n      for(unsigned int i = 0; i < (1 << CHAR_BIT); ++i)\n      {\n         if(this->m_traits.translate(static_cast<charT>(i), this->m_icase)\n            == this->m_traits.translate(sfirst->first, this->m_icase))\n            result->_map[i] = true;\n      }\n      ++sfirst;\n   }\n   //\n   // OK now handle ranges:\n   //\n   first = char_set.ranges_begin();\n   last = char_set.ranges_end();\n   while(first != last)\n   {\n      // first grab the endpoints of the range:\n      charT c1 = this->m_traits.translate(first->first, this->m_icase);\n      ++first;\n      charT c2 = this->m_traits.translate(first->first, this->m_icase);\n      ++first;\n      // different actions now depending upon whether collation is turned on:\n      if(flags() & regex_constants::collate)\n      {\n         // we need to transform our range into sort keys:\n         charT c3[2] = { c1, charT(0), };\n         string_type s1 = this->m_traits.transform(c3, c3+1);\n         c3[0] = c2;\n         string_type s2 = this->m_traits.transform(c3, c3+1);\n         if(s1 > s2)\n         {\n            // Oops error:\n            return 0;\n         }\n         BOOST_REGEX_ASSERT(c3[1] == charT(0));\n         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n         {\n            c3[0] = static_cast<charT>(i);\n            string_type s3 = this->m_traits.transform(c3, c3 +1);\n            if((s1 <= s3) && (s3 <= s2))\n               result->_map[i] = true;\n         }\n      }\n      else\n      {\n         if(char_less(c2, c1))\n         {\n            // Oops error:\n            return 0;\n         }\n         // everything in range matches:\n         std::memset(result->_map + static_cast<unsigned char>(c1), true, static_cast<unsigned char>(1u) + static_cast<unsigned char>(static_cast<unsigned char>(c2) - static_cast<unsigned char>(c1)));\n      }\n   }\n   //\n   // and now the classes:\n   //\n   typedef typename traits::char_class_type m_type;\n   m_type m = char_set.classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust m as needed:\n      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))\n         m |= m_alpha_mask;\n   }\n   if(m != 0)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         if(this->m_traits.isctype(static_cast<charT>(i), m))\n            result->_map[i] = true;\n      }\n   }\n   //\n   // and now the negated classes:\n   //\n   m = char_set.negated_classes();\n   if(flags() & regbase::icase)\n   {\n      // adjust m as needed:\n      if(((m & m_lower_mask) == m_lower_mask) || ((m & m_upper_mask) == m_upper_mask))\n         m |= m_alpha_mask;\n   }\n   if(m != 0)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         if(0 == this->m_traits.isctype(static_cast<charT>(i), m))\n            result->_map[i] = true;\n      }\n   }\n   //\n   // now process the equivalence classes:\n   //\n   sfirst = char_set.equivalents_begin();\n   slast = char_set.equivalents_end();\n   while(sfirst != slast)\n   {\n      string_type s;\n      BOOST_REGEX_ASSERT(static_cast<charT>(0) == sfirst->second);\n      s = m_traits.transform_primary(&sfirst->first, &sfirst->first+1);\n      if(s.empty())\n         return 0;  // invalid or unsupported equivalence class\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         charT c[2] = { (static_cast<charT>(i)), charT(0), };\n         string_type s2 = this->m_traits.transform_primary(c, c+1);\n         if(s == s2)\n            result->_map[i] = true;\n      }\n      ++sfirst;\n   }\n   if(negate)\n   {\n      for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n      {\n         result->_map[i] = !(result->_map[i]);\n      }\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)\n{\n   if(this->m_pdata->m_status)\n      return;\n   // we've added all the states we need, now finish things off.\n   // start by adding a terminating state:\n   append_state(syntax_element_match);\n   // extend storage to store original expression:\n   std::ptrdiff_t len = p2 - p1;\n   m_pdata->m_expression_len = len;\n   charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));\n   m_pdata->m_expression = ps;\n   BOOST_REGEX_DETAIL_NS::copy(p1, p2, ps);\n   ps[p2 - p1] = 0;\n   // fill in our other data...\n   // successful parsing implies a zero status:\n   m_pdata->m_status = 0;\n   // get the first state of the machine:\n   m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());\n   // fixup pointers in the machine:\n   fixup_pointers(m_pdata->m_first_state);\n   if(m_has_recursions)\n   {\n      m_pdata->m_has_recursions = true;\n      fixup_recursions(m_pdata->m_first_state);\n      if(this->m_pdata->m_status)\n         return;\n   }\n   else\n      m_pdata->m_has_recursions = false;\n   // create nested startmaps:\n   create_startmaps(m_pdata->m_first_state);\n   // create main startmap:\n   std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));\n   m_pdata->m_can_be_null = 0;\n\n   m_bad_repeats = 0;\n   if(m_has_recursions)\n      m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n   create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all);\n   // get the restart type:\n   m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);\n   // optimise a leading repeat if there is one:\n   probe_leading_repeat(m_pdata->m_first_state);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)\n{\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_recurse:\n         m_has_recursions = true;\n         if(state->next.i)\n            state->next.p = getaddress(state->next.i, state);\n         else\n            state->next.p = 0;\n         break;\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         // set the state_id of this repeat:\n         static_cast<re_repeat*>(state)->state_id = m_repeater_id++;\n         BOOST_REGEX_FALLTHROUGH;\n      case syntax_element_alt:\n         std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));\n         static_cast<re_alt*>(state)->can_be_null = 0;\n         BOOST_REGEX_FALLTHROUGH;\n      case syntax_element_jump:\n         static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);\n         BOOST_REGEX_FALLTHROUGH;\n      default:\n         if(state->next.i)\n            state->next.p = getaddress(state->next.i, state);\n         else\n            state->next.p = 0;\n      }\n      state = state->next.p;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::fixup_recursions(re_syntax_base* state)\n{\n   re_syntax_base* base = state;\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_assert_backref:\n         {\n            // just check that the index is valid:\n            int idx = static_cast<const re_brace*>(state)->index;\n            if(idx < 0)\n            {\n               idx = -idx-1;\n               if(idx >= hash_value_mask)\n               {\n                  idx = m_pdata->get_id(idx);\n                  if(idx <= 0)\n                  {\n                     // check of sub-expression that doesn't exist:\n                     if(0 == this->m_pdata->m_status) // update the error code if not already set\n                        this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n                     //\n                     // clear the expression, we should be empty:\n                     //\n                     this->m_pdata->m_expression = 0;\n                     this->m_pdata->m_expression_len = 0;\n                     //\n                     // and throw if required:\n                     //\n                     if(0 == (this->flags() & regex_constants::no_except))\n                     {\n                        std::string message = \"Encountered a forward reference to a marked sub-expression that does not exist.\";\n                        boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                        e.raise();\n                     }\n                  }\n               }\n            }\n         }\n         break;\n      case syntax_element_recurse:\n         {\n            bool ok = false;\n            re_syntax_base* p = base;\n            std::ptrdiff_t idx = static_cast<re_jump*>(state)->alt.i;\n            if(idx >= hash_value_mask)\n            {\n               //\n               // There may be more than one capture group with this hash, just do what Perl\n               // does and recurse to the leftmost:\n               //\n               idx = m_pdata->get_id(static_cast<int>(idx));\n            }\n            if(idx < 0)\n            {\n               ok = false;\n            }\n            else\n            {\n               while(p)\n               {\n                  if((p->type == syntax_element_startmark) && (static_cast<re_brace*>(p)->index == idx))\n                  {\n                     //\n                     // We've found the target of the recursion, set the jump target:\n                     //\n                     static_cast<re_jump*>(state)->alt.p = p;\n                     ok = true;\n                     // \n                     // Now scan the target for nested repeats:\n                     //\n                     p = p->next.p;\n                     int next_rep_id = 0;\n                     while(p)\n                     {\n                        switch(p->type)\n                        {\n                        case syntax_element_rep:\n                        case syntax_element_dot_rep:\n                        case syntax_element_char_rep:\n                        case syntax_element_short_set_rep:\n                        case syntax_element_long_set_rep:\n                           next_rep_id = static_cast<re_repeat*>(p)->state_id;\n                           break;\n                        case syntax_element_endmark:\n                           if(static_cast<const re_brace*>(p)->index == idx)\n                              next_rep_id = -1;\n                           break;\n                        default:\n                           break;\n                        }\n                        if(next_rep_id)\n                           break;\n                        p = p->next.p;\n                     }\n                     if(next_rep_id > 0)\n                     {\n                        static_cast<re_recurse*>(state)->state_id = next_rep_id - 1;\n                     }\n\n                     break;\n                  }\n                  p = p->next.p;\n               }\n            }\n            if(!ok)\n            {\n               // recursion to sub-expression that doesn't exist:\n               if(0 == this->m_pdata->m_status) // update the error code if not already set\n                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n               //\n               // clear the expression, we should be empty:\n               //\n               this->m_pdata->m_expression = 0;\n               this->m_pdata->m_expression_len = 0;\n               //\n               // and throw if required:\n               //\n               if(0 == (this->flags() & regex_constants::no_except))\n               {\n                  std::string message = \"Encountered a forward reference to a recursive sub-expression that does not exist.\";\n                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                  e.raise();\n               }\n            }\n         }\n         break;\n      default:\n         break;\n      }\n      state = state->next.p;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)\n{\n   // non-recursive implementation:\n   // create the last map in the machine first, so that earlier maps\n   // can make use of the result...\n   //\n   // This was originally a recursive implementation, but that caused stack\n   // overflows with complex expressions on small stacks (think COM+).\n\n   // start by saving the case setting:\n   bool l_icase = m_icase;\n   std::vector<std::pair<bool, re_syntax_base*> > v;\n\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_toggle_case:\n         // we need to track case changes here:\n         m_icase = static_cast<re_case*>(state)->icase;\n         state = state->next.p;\n         continue;\n      case syntax_element_alt:\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         // just push the state onto our stack for now:\n         v.push_back(std::pair<bool, re_syntax_base*>(m_icase, state));\n         state = state->next.p;\n         break;\n      case syntax_element_backstep:\n         // we need to calculate how big the backstep is:\n         static_cast<re_brace*>(state)->index\n            = this->calculate_backstep(state->next.p);\n         if(static_cast<re_brace*>(state)->index < 0)\n         {\n            // Oops error:\n            if(0 == this->m_pdata->m_status) // update the error code if not already set\n               this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n            //\n            // clear the expression, we should be empty:\n            //\n            this->m_pdata->m_expression = 0;\n            this->m_pdata->m_expression_len = 0;\n            //\n            // and throw if required:\n            //\n            if(0 == (this->flags() & regex_constants::no_except))\n            {\n               std::string message = \"Invalid lookbehind assertion encountered in the regular expression.\";\n               boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n               e.raise();\n            }\n         }\n         BOOST_REGEX_FALLTHROUGH;\n      default:\n         state = state->next.p;\n      }\n   }\n\n   // now work through our list, building all the maps as we go:\n   while(!v.empty())\n   {\n      // Initialize m_recursion_checks if we need it:\n      if(m_has_recursions)\n         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n\n      const std::pair<bool, re_syntax_base*>& p = v.back();\n      m_icase = p.first;\n      state = p.second;\n      v.pop_back();\n\n      // Build maps:\n      m_bad_repeats = 0;\n      create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);\n      m_bad_repeats = 0;\n\n      if(m_has_recursions)\n         m_recursion_checks.assign(1 + m_pdata->m_mark_count, 0u);\n      create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);\n      // adjust the type of the state to allow for faster matching:\n      state->type = this->get_repeat_type(state);\n   }\n   // restore case sensitivity:\n   m_icase = l_icase;\n}\n\ntemplate <class charT, class traits>\nint basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state)\n{\n   typedef typename traits::char_class_type m_type;\n   int result = 0;\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n         {\n            state = static_cast<re_jump*>(state->next.p)->alt.p->next.p;\n            continue;\n         }\n         else if(static_cast<re_brace*>(state)->index == -3)\n         {\n            state = state->next.p->next.p;\n            continue;\n         }\n         break;\n      case syntax_element_endmark:\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n            return result;\n         break;\n      case syntax_element_literal:\n         result += static_cast<re_literal*>(state)->length;\n         break;\n      case syntax_element_wild:\n      case syntax_element_set:\n         result += 1;\n         break;\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_backref:\n      case syntax_element_rep:\n      case syntax_element_combining:\n      case syntax_element_long_set_rep:\n      case syntax_element_backstep:\n         {\n            re_repeat* rep = static_cast<re_repeat *>(state);\n            // adjust the type of the state to allow for faster matching:\n            state->type = this->get_repeat_type(state);\n            if((state->type == syntax_element_dot_rep) \n               || (state->type == syntax_element_char_rep)\n               || (state->type == syntax_element_short_set_rep))\n            {\n               if(rep->max != rep->min)\n                  return -1;\n               if (static_cast<std::size_t>((std::numeric_limits<int>::max)() - result) < rep->min)\n                  return -1; // protection against overflow, we can't calculate a backstep in this case and the expression is probably ill-formed.\n               result += static_cast<int>(rep->min);\n               state = rep->alt.p;\n               continue;\n            }\n            else if(state->type == syntax_element_long_set_rep)\n            {\n               BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);\n               if(static_cast<re_set_long<m_type>*>(rep->next.p)->singleton == 0)\n                  return -1;\n               if(rep->max != rep->min)\n                  return -1;\n               result += static_cast<int>(rep->min);\n               state = rep->alt.p;\n               continue;\n            }\n         }\n         return -1;\n      case syntax_element_long_set:\n         if(static_cast<re_set_long<m_type>*>(state)->singleton == 0)\n            return -1;\n         result += 1;\n         break;\n      case syntax_element_jump:\n         state = static_cast<re_jump*>(state)->alt.p;\n         continue;\n      case syntax_element_alt:\n         {\n            int r1 = calculate_backstep(state->next.p);\n            int r2 = calculate_backstep(static_cast<re_alt*>(state)->alt.p);\n            if((r1 < 0) || (r1 != r2))\n               return -1;\n            return result + r1;\n         }\n      default:\n         break;\n      }\n      state = state->next.p;\n   }\n   return -1;\n}\n\nstruct recursion_saver\n{\n   std::vector<unsigned char> saved_state;\n   std::vector<unsigned char>* state;\n   recursion_saver(std::vector<unsigned char>* p) : saved_state(*p), state(p) {}\n   ~recursion_saver()\n   {\n      state->swap(saved_state);\n   }\n};\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)\n{\n   recursion_saver saved_recursions(&m_recursion_checks);\n   int not_last_jump = 1;\n   re_syntax_base* recursion_start = 0;\n   int recursion_sub = 0;\n   re_syntax_base* recursion_restart = 0;\n\n   // track case sensitivity:\n   bool l_icase = m_icase;\n\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_toggle_case:\n         l_icase = static_cast<re_case*>(state)->icase;\n         state = state->next.p;\n         break;\n      case syntax_element_literal:\n      {\n         // don't set anything in *pnull, set each element in l_map\n         // that could match the first character in the literal:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)\n                  l_map[i] |= mask;\n            }\n         }\n         return;\n      }\n      case syntax_element_end_line:\n      {\n         // next character must be a line separator (if there is one):\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            l_map[static_cast<unsigned>('\\n')] |= mask;\n            l_map[static_cast<unsigned>('\\r')] |= mask;\n            l_map[static_cast<unsigned>('\\f')] |= mask;\n            l_map[0x85] |= mask;\n         }\n         // now figure out if we can match a NULL string at this point:\n         if(pnull)\n            create_startmap(state->next.p, 0, pnull, mask);\n         return;\n      }\n      case syntax_element_recurse:\n         {\n            BOOST_REGEX_ASSERT(static_cast<const re_jump*>(state)->alt.p->type == syntax_element_startmark);\n            recursion_sub = static_cast<re_brace*>(static_cast<const re_jump*>(state)->alt.p)->index;\n            if(m_recursion_checks[recursion_sub] & 1u)\n            {\n               // Infinite recursion!!\n               if(0 == this->m_pdata->m_status) // update the error code if not already set\n                  this->m_pdata->m_status = boost::regex_constants::error_bad_pattern;\n               //\n               // clear the expression, we should be empty:\n               //\n               this->m_pdata->m_expression = 0;\n               this->m_pdata->m_expression_len = 0;\n               //\n               // and throw if required:\n               //\n               if(0 == (this->flags() & regex_constants::no_except))\n               {\n                  std::string message = \"Encountered an infinite recursion.\";\n                  boost::regex_error e(message, boost::regex_constants::error_bad_pattern, 0);\n                  e.raise();\n               }\n            }\n            else if(recursion_start == 0)\n            {\n               recursion_start = state;\n               recursion_restart = state->next.p;\n               state = static_cast<re_jump*>(state)->alt.p;\n               m_recursion_checks[recursion_sub] |= 1u;\n               break;\n            }\n            m_recursion_checks[recursion_sub] |= 1u;\n            // can't handle nested recursion here...\n            BOOST_REGEX_FALLTHROUGH;\n         }\n      case syntax_element_backref:\n         // can be null, and any character can match:\n         if(pnull)\n            *pnull |= mask;\n         BOOST_REGEX_FALLTHROUGH;\n      case syntax_element_wild:\n      {\n         // can't be null, any character can match:\n         set_all_masks(l_map, mask);\n         return;\n      }\n      case syntax_element_accept:\n      case syntax_element_match:\n      {\n         // must be null, any character can match:\n         set_all_masks(l_map, mask);\n         if(pnull)\n            *pnull |= mask;\n         return;\n      }\n      case syntax_element_word_start:\n      {\n         // recurse, then AND with all the word characters:\n         create_startmap(state->next.p, l_map, pnull, mask);\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(!m_traits.isctype(static_cast<charT>(i), m_word_mask))\n                  l_map[i] &= static_cast<unsigned char>(~mask);\n            }\n         }\n         return;\n      }\n      case syntax_element_word_end:\n      {\n         // recurse, then AND with all the word characters:\n         create_startmap(state->next.p, l_map, pnull, mask);\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(m_traits.isctype(static_cast<charT>(i), m_word_mask))\n                  l_map[i] &= static_cast<unsigned char>(~mask);\n            }\n         }\n         return;\n      }\n      case syntax_element_buffer_end:\n      {\n         // we *must be null* :\n         if(pnull)\n            *pnull |= mask;\n         return;\n      }\n      case syntax_element_long_set:\n         if(l_map)\n         {\n            typedef typename traits::char_class_type m_type;\n            if(static_cast<re_set_long<m_type>*>(state)->singleton)\n            {\n               l_map[0] |= mask_init;\n               for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n               {\n                  charT c = static_cast<charT>(i);\n                  if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<m_type>*>(state), *m_pdata, l_icase))\n                     l_map[i] |= mask;\n               }\n            }\n            else\n               set_all_masks(l_map, mask);\n         }\n         return;\n      case syntax_element_set:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)\n            {\n               if(static_cast<re_set*>(state)->_map[\n                  static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])\n                  l_map[i] |= mask;\n            }\n         }\n         return;\n      case syntax_element_jump:\n         // take the jump:\n         state = static_cast<re_alt*>(state)->alt.p;\n         not_last_jump = -1;\n         break;\n      case syntax_element_alt:\n      case syntax_element_rep:\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         {\n            re_alt* rep = static_cast<re_alt*>(state);\n            if(rep->_map[0] & mask_init)\n            {\n               if(l_map)\n               {\n                  // copy previous results:\n                  l_map[0] |= mask_init;\n                  for(unsigned int i = 0; i <= UCHAR_MAX; ++i)\n                  {\n                     if(rep->_map[i] & mask_any)\n                        l_map[i] |= mask;\n                  }\n               }\n               if(pnull)\n               {\n                  if(rep->can_be_null & mask_any)\n                     *pnull |= mask;\n               }\n            }\n            else\n            {\n               // we haven't created a startmap for this alternative yet\n               // so take the union of the two options:\n               if(is_bad_repeat(state))\n               {\n                  set_all_masks(l_map, mask);\n                  if(pnull)\n                     *pnull |= mask;\n                  return;\n               }\n               set_bad_repeat(state);\n               create_startmap(state->next.p, l_map, pnull, mask);\n               if((state->type == syntax_element_alt)\n                  || (static_cast<re_repeat*>(state)->min == 0)\n                  || (not_last_jump == 0))\n                  create_startmap(rep->alt.p, l_map, pnull, mask);\n            }\n         }\n         return;\n      case syntax_element_soft_buffer_end:\n         // match newline or null:\n         if(l_map)\n         {\n            l_map[0] |= mask_init;\n            l_map[static_cast<unsigned>('\\n')] |= mask;\n            l_map[static_cast<unsigned>('\\r')] |= mask;\n         }\n         if(pnull)\n            *pnull |= mask;\n         return;\n      case syntax_element_endmark:\n         // need to handle independent subs as a special case:\n         if(static_cast<re_brace*>(state)->index < 0)\n         {\n            // can be null, any character can match:\n            set_all_masks(l_map, mask);\n            if(pnull)\n               *pnull |= mask;\n            return;\n         }\n         else if(recursion_start && (recursion_sub != 0) && (recursion_sub == static_cast<re_brace*>(state)->index))\n         {\n            // recursion termination:\n            recursion_start = 0;\n            state = recursion_restart;\n            break;\n         }\n\n         //\n         // Normally we just go to the next state... but if this sub-expression is\n         // the target of a recursion, then we might be ending a recursion, in which\n         // case we should check whatever follows that recursion, as well as whatever\n         // follows this state:\n         //\n         if(m_pdata->m_has_recursions && static_cast<re_brace*>(state)->index)\n         {\n            bool ok = false;\n            re_syntax_base* p = m_pdata->m_first_state;\n            while(p)\n            {\n               if(p->type == syntax_element_recurse)\n               {\n                  re_brace* p2 = static_cast<re_brace*>(static_cast<re_jump*>(p)->alt.p);\n                  if((p2->type == syntax_element_startmark) && (p2->index == static_cast<re_brace*>(state)->index))\n                  {\n                     ok = true;\n                     break;\n                  }\n               }\n               p = p->next.p;\n            }\n            if(ok && ((m_recursion_checks[static_cast<re_brace*>(state)->index] & 2u) == 0))\n            {\n               m_recursion_checks[static_cast<re_brace*>(state)->index] |= 2u;\n               create_startmap(p->next.p, l_map, pnull, mask);\n            }\n         }\n         state = state->next.p;\n         break;\n\n      case syntax_element_commit:\n         set_all_masks(l_map, mask);\n         // Continue scanning so we can figure out whether we can be null:\n         state = state->next.p;\n         break;\n      case syntax_element_startmark:\n         // need to handle independent subs as a special case:\n         if(static_cast<re_brace*>(state)->index == -3)\n         {\n            state = state->next.p->next.p;\n            break;\n         }\n         BOOST_REGEX_FALLTHROUGH;\n      default:\n         state = state->next.p;\n      }\n      ++not_last_jump;\n   }\n}\n\ntemplate <class charT, class traits>\nunsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)\n{\n   //\n   // find out how the machine starts, so we can optimise the search:\n   //\n   while(state)\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n      case syntax_element_endmark:\n         state = state->next.p;\n         continue;\n      case syntax_element_start_line:\n         return regbase::restart_line;\n      case syntax_element_word_start:\n         return regbase::restart_word;\n      case syntax_element_buffer_start:\n         return regbase::restart_buf;\n      case syntax_element_restart_continue:\n         return regbase::restart_continue;\n      default:\n         state = 0;\n         continue;\n      }\n   }\n   return regbase::restart_any;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::set_all_masks(unsigned char* bits, unsigned char mask)\n{\n   //\n   // set mask in all of bits elements, \n   // if bits[0] has mask_init not set then we can \n   // optimise this to a call to memset:\n   //\n   if(bits)\n   {\n      if(bits[0] == 0)\n         (std::memset)(bits, mask, 1u << CHAR_BIT);\n      else\n      {\n         for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)\n            bits[i] |= mask;\n      }\n      bits[0] |= mask_init;\n   }\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)\n{\n   switch(pt->type)\n   {\n   case syntax_element_rep:\n   case syntax_element_dot_rep:\n   case syntax_element_char_rep:\n   case syntax_element_short_set_rep:\n   case syntax_element_long_set_rep:\n      {\n         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;\n         if(state_id >= sizeof(m_bad_repeats) * CHAR_BIT)\n            return true;  // run out of bits, assume we can't traverse this one.\n         static const std::uintmax_t one = 1uL;\n         return m_bad_repeats & (one << state_id);\n      }\n   default:\n      return false;\n   }\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)\n{\n   switch(pt->type)\n   {\n   case syntax_element_rep:\n   case syntax_element_dot_rep:\n   case syntax_element_char_rep:\n   case syntax_element_short_set_rep:\n   case syntax_element_long_set_rep:\n      {\n         unsigned state_id = static_cast<re_repeat*>(pt)->state_id;\n         static const std::uintmax_t one = 1uL;\n         if(state_id <= sizeof(m_bad_repeats) * CHAR_BIT)\n            m_bad_repeats |= (one << state_id);\n      }\n      break;\n   default:\n      break;\n   }\n}\n\ntemplate <class charT, class traits>\nsyntax_element_type basic_regex_creator<charT, traits>::get_repeat_type(re_syntax_base* state)\n{\n   typedef typename traits::char_class_type m_type;\n   if(state->type == syntax_element_rep)\n   {\n      // check to see if we are repeating a single state:\n      if(state->next.p->next.p->next.p == static_cast<re_alt*>(state)->alt.p)\n      {\n         switch(state->next.p->type)\n         {\n         case BOOST_REGEX_DETAIL_NS::syntax_element_wild:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_dot_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_literal:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_char_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_set:\n            return BOOST_REGEX_DETAIL_NS::syntax_element_short_set_rep;\n         case BOOST_REGEX_DETAIL_NS::syntax_element_long_set:\n            if(static_cast<BOOST_REGEX_DETAIL_NS::re_set_long<m_type>*>(state->next.p)->singleton)\n               return BOOST_REGEX_DETAIL_NS::syntax_element_long_set_rep;\n            break;\n         default:\n            break;\n         }\n      }\n   }\n   return state->type;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_creator<charT, traits>::probe_leading_repeat(re_syntax_base* state)\n{\n   // enumerate our states, and see if we have a leading repeat \n   // for which failed search restarts can be optimized;\n   do\n   {\n      switch(state->type)\n      {\n      case syntax_element_startmark:\n         if(static_cast<re_brace*>(state)->index >= 0)\n         {\n            state = state->next.p;\n            continue;\n         }\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable:6011)\n#endif\n         if((static_cast<re_brace*>(state)->index == -1)\n            || (static_cast<re_brace*>(state)->index == -2))\n         {\n            // skip past the zero width assertion:\n            state = static_cast<const re_jump*>(state->next.p)->alt.p->next.p;\n            continue;\n         }\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n         if(static_cast<re_brace*>(state)->index == -3)\n         {\n            // Have to skip the leading jump state:\n            state = state->next.p->next.p;\n            continue;\n         }\n         return;\n      case syntax_element_endmark:\n      case syntax_element_start_line:\n      case syntax_element_end_line:\n      case syntax_element_word_boundary:\n      case syntax_element_within_word:\n      case syntax_element_word_start:\n      case syntax_element_word_end:\n      case syntax_element_buffer_start:\n      case syntax_element_buffer_end:\n      case syntax_element_restart_continue:\n         state = state->next.p;\n         break;\n      case syntax_element_dot_rep:\n      case syntax_element_char_rep:\n      case syntax_element_short_set_rep:\n      case syntax_element_long_set_rep:\n         if(this->m_has_backrefs == 0)\n            static_cast<re_repeat*>(state)->leading = true;\n         BOOST_REGEX_FALLTHROUGH;\n      default:\n         return;\n      }\n   }while(state);\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/basic_regex_parser.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         basic_regex_parser.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class basic_regex_parser.\n  */\n\n#ifndef BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP\n#define BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4244 4459)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\ninline std::intmax_t umax(std::integral_constant<bool, false> const&)\n{\n   // Get out clause here, just in case numeric_limits is unspecialized:\n   return std::numeric_limits<std::intmax_t>::is_specialized ? (std::numeric_limits<std::intmax_t>::max)() : INT_MAX;\n}\ninline std::intmax_t umax(std::integral_constant<bool, true> const&)\n{\n   return (std::numeric_limits<std::size_t>::max)();\n}\n\ninline std::intmax_t umax()\n{\n   return umax(std::integral_constant<bool, std::numeric_limits<std::intmax_t>::digits >= std::numeric_limits<std::size_t>::digits>());\n}\n\ntemplate <class charT, class traits>\nclass basic_regex_parser : public basic_regex_creator<charT, traits>\n{\npublic:\n   basic_regex_parser(regex_data<charT, traits>* data);\n   void parse(const charT* p1, const charT* p2, unsigned flags);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos);\n   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, const std::string& message)\n   {\n      fail(error_code, position, message, position);\n   }\n\n   bool parse_all();\n   bool parse_basic();\n   bool parse_extended();\n   bool parse_literal();\n   bool parse_open_paren();\n   bool parse_basic_escape();\n   bool parse_extended_escape();\n   bool parse_match_any();\n   bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());\n   bool parse_repeat_range(bool isbasic);\n   bool parse_alt();\n   bool parse_set();\n   bool parse_backref();\n   void parse_set_literal(basic_char_set<charT, traits>& char_set);\n   bool parse_inner_set(basic_char_set<charT, traits>& char_set);\n   bool parse_QE();\n   bool parse_perl_extension();\n   bool parse_perl_verb();\n   bool match_verb(const char*);\n   bool add_emacs_code(bool negate);\n   bool unwind_alts(std::ptrdiff_t last_paren_start);\n   digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);\n   charT unescape_character();\n   regex_constants::syntax_option_type parse_options();\n\nprivate:\n   typedef bool (basic_regex_parser::*parser_proc_type)();\n   typedef typename traits::string_type string_type;\n   typedef typename traits::char_class_type char_class_type;\n   parser_proc_type           m_parser_proc;    // the main parser to use\n   const charT*               m_base;           // the start of the string being parsed\n   const charT*               m_end;            // the end of the string being parsed\n   const charT*               m_position;       // our current parser position\n   unsigned                   m_mark_count;     // how many sub-expressions we have\n   int                        m_mark_reset;     // used to indicate that we're inside a (?|...) block.\n   unsigned                   m_max_mark;       // largest mark count seen inside a (?|...) block.\n   std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).\n   std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative\n   bool                       m_has_case_change; // true if somewhere in the current block the case has changed\n   unsigned                   m_recursion_count; // How many times we've called parse_all.\n   unsigned                   m_max_backref;     // Largest index of any backref.\n#if defined(BOOST_REGEX_MSVC) && defined(_M_IX86)\n   // This is an ugly warning suppression workaround (for warnings *inside* std::vector\n   // that can not otherwise be suppressed)...\n   static_assert(sizeof(long) >= sizeof(void*), \"Long isn't long enough!\");\n   std::vector<long>           m_alt_jumps;      // list of alternative in the current scope.\n#else\n   std::vector<std::ptrdiff_t> m_alt_jumps;      // list of alternative in the current scope.\n#endif\n\n   basic_regex_parser& operator=(const basic_regex_parser&);\n   basic_regex_parser(const basic_regex_parser&);\n};\n\ntemplate <class charT, class traits>\nbasic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)\n   : basic_regex_creator<charT, traits>(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), \n   m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0), m_max_backref(0)\n{\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)\n{\n   // pass l_flags on to base class:\n   this->init(l_flags);\n   // set up pointers:\n   m_position = m_base = p1;\n   m_end = p2;\n   // empty strings are errors:\n   if((p1 == p2) && \n      (\n         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)\n         || (l_flags & regbase::no_empty_expressions)\n      )\n     )\n   {\n      fail(regex_constants::error_empty, 0);\n      return;\n   }\n   // select which parser to use:\n   switch(l_flags & regbase::main_option_type)\n   {\n   case regbase::perl_syntax_group:\n      {\n         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;\n         //\n         // Add a leading paren with index zero to give recursions a target:\n         //\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n         br->index = 0;\n         br->icase = this->flags() & regbase::icase;\n         break;\n      }\n   case regbase::basic_syntax_group:\n      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;\n      break;\n   case regbase::literal:\n      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;\n      break;\n   default:\n      // Oops, someone has managed to set more than one of the main option flags, \n      // so this must be an error:\n      fail(regex_constants::error_unknown, 0, \"An invalid combination of regular expression syntax flags was used.\");\n      return;\n   }\n\n   // parse all our characters:\n   bool result = parse_all();\n   //\n   // Unwind our alternatives:\n   //\n   unwind_alts(-1);\n   // reset l_flags as a global scope (?imsx) may have altered them:\n   this->flags(l_flags);\n   // if we haven't gobbled up all the characters then we must\n   // have had an unexpected ')' :\n   if(!result)\n   {\n      fail(regex_constants::error_paren, std::distance(m_base, m_position), \"Found a closing ) with no corresponding opening parenthesis.\");\n      return;\n   }\n   // if an error has been set then give up now:\n   if(this->m_pdata->m_status)\n      return;\n   // fill in our sub-expression count:\n   this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count;\n   //\n   // Check we don't have backreferences to sub-expressions which don't exist:\n   //\n   if (m_max_backref > m_mark_count)\n   {\n      fail(regex_constants::error_backref, std::distance(m_base, m_position), \"Found a backreference to a non-existant sub-expression.\");\n   }\n   this->finalize(p1, p2);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)\n{\n   // get the error message:\n   std::string message = this->m_pdata->m_ptraits->error_string(error_code);\n   fail(error_code, position, message);\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos)\n{\n   if(0 == this->m_pdata->m_status) // update the error code if not already set\n      this->m_pdata->m_status = error_code;\n   m_position = m_end; // don't bother parsing anything else\n\n   //\n   // Augment error message with the regular expression text:\n   //\n   if(start_pos == position)\n      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));\n   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));\n   if(error_code != regex_constants::error_empty)\n   {\n      if((start_pos != 0) || (end_pos != (m_end - m_base)))\n         message += \"  The error occurred while parsing the regular expression fragment: '\";\n      else\n         message += \"  The error occurred while parsing the regular expression: '\";\n      if(start_pos != end_pos)\n      {\n         message += std::string(m_base + start_pos, m_base + position);\n         message += \">>>HERE>>>\";\n         message += std::string(m_base + position, m_base + end_pos);\n      }\n      message += \"'.\";\n   }\n\n#ifndef BOOST_NO_EXCEPTIONS\n   if(0 == (this->flags() & regex_constants::no_except))\n   {\n      boost::regex_error e(message, error_code, position);\n      e.raise();\n   }\n#else\n   (void)position; // suppress warnings.\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_all()\n{\n   if (++m_recursion_count > 400)\n   {\n      // exceeded internal limits\n      fail(boost::regex_constants::error_complexity, m_position - m_base, \"Exceeded nested brace limit.\");\n   }\n   bool result = true;\n   while(result && (m_position != m_end))\n   {\n      result = (this->*m_parser_proc)();\n   }\n   --m_recursion_count;\n   return result;\n}\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4702)\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_basic()\n{\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_escape:\n      return parse_basic_escape();\n   case regex_constants::syntax_dot:\n      return parse_match_any();\n   case regex_constants::syntax_caret:\n      ++m_position;\n      this->append_state(syntax_element_start_line);\n      break;\n   case regex_constants::syntax_dollar:\n      ++m_position;\n      this->append_state(syntax_element_end_line);\n      break;\n   case regex_constants::syntax_star:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat();\n      }\n   case regex_constants::syntax_plus:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat(1);\n      }\n   case regex_constants::syntax_question:\n      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))\n         return parse_literal();\n      else\n      {\n         ++m_position;\n         return parse_repeat(0, 1);\n      }\n   case regex_constants::syntax_open_set:\n      return parse_set();\n   case regex_constants::syntax_newline:\n      if(this->flags() & regbase::newline_alt)\n         return parse_alt();\n      else\n         return parse_literal();\n   default:\n      return parse_literal();\n   }\n   return true;\n}\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable:26812)\n#endif\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_extended()\n{\n   bool result = true;\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_open_mark:\n      return parse_open_paren();\n   case regex_constants::syntax_close_mark:\n      return false;\n   case regex_constants::syntax_escape:\n      return parse_extended_escape();\n   case regex_constants::syntax_dot:\n      return parse_match_any();\n   case regex_constants::syntax_caret:\n      ++m_position;\n      this->append_state(\n         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));\n      break;\n   case regex_constants::syntax_dollar:\n      ++m_position;\n      this->append_state(\n         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));\n      break;\n   case regex_constants::syntax_star:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"*\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat();\n   case regex_constants::syntax_question:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"?\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat(0,1);\n   case regex_constants::syntax_plus:\n      if(m_position == this->m_base)\n      {\n         fail(regex_constants::error_badrepeat, 0, \"The repeat operator \\\"+\\\" cannot start a regular expression.\");\n         return false;\n      }\n      ++m_position;\n      return parse_repeat(1);\n   case regex_constants::syntax_open_brace:\n      ++m_position;\n      return parse_repeat_range(false);\n   case regex_constants::syntax_close_brace:\n      if((this->flags() & regbase::no_perl_ex) == regbase::no_perl_ex)\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, \"Found a closing repetition operator } with no corresponding {.\");\n         return false;\n      }\n      result = parse_literal();\n      break;\n   case regex_constants::syntax_or:\n      return parse_alt();\n   case regex_constants::syntax_open_set:\n      return parse_set();\n   case regex_constants::syntax_newline:\n      if(this->flags() & regbase::newline_alt)\n         return parse_alt();\n      else\n         return parse_literal();\n   case regex_constants::syntax_hash:\n      //\n      // If we have a mod_x flag set, then skip until\n      // we get to a newline character:\n      //\n      if((this->flags() \n         & (regbase::no_perl_ex|regbase::mod_x))\n         == regbase::mod_x)\n      {\n         while((m_position != m_end) && !is_separator(*m_position++)){}\n         return true;\n      }\n      BOOST_REGEX_FALLTHROUGH;\n   default:\n      result = parse_literal();\n      break;\n   }\n   return result;\n}\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_literal()\n{\n   // append this as a literal provided it's not a space character\n   // or the perl option regbase::mod_x is not set:\n   if(\n      ((this->flags() \n         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) \n            != regbase::mod_x)\n      || !this->m_traits.isctype(*m_position, this->m_mask_space))\n         this->append_literal(*m_position);\n   ++m_position;\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_open_paren()\n{\n   //\n   // skip the '(' and error check:\n   //\n   if(++m_position == m_end)\n   {\n      fail(regex_constants::error_paren, m_position - m_base);\n      return false;\n   }\n   //\n   // begin by checking for a perl-style (?...) extension:\n   //\n   if(\n         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)\n         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))\n     )\n   {\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)\n         return parse_perl_extension();\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star)\n         return parse_perl_verb();\n   }\n   //\n   // update our mark count, and append the required state:\n   //\n   unsigned markid = 0;\n   if(0 == (this->flags() & regbase::nosubs))\n   {\n      markid = ++m_mark_count;\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));\n   }\n   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   std::ptrdiff_t last_paren_start = this->getoffset(pb);\n   // back up insertion point for alternations, and set new point:\n   std::ptrdiff_t last_alt_point = m_alt_insert_point;\n   this->m_pdata->m_data.align();\n   m_alt_insert_point = this->m_pdata->m_data.size();\n   //\n   // back up the current flags in case we have a nested (?imsx) group:\n   //\n   regex_constants::syntax_option_type opts = this->flags();\n   bool old_case_change = m_has_case_change;\n   m_has_case_change = false; // no changes to this scope as yet...\n   //\n   // Back up branch reset data in case we have a nested (?|...)\n   //\n   int mark_reset = m_mark_reset;\n   m_mark_reset = -1;\n   //\n   // now recursively add more states, this will terminate when we get to a\n   // matching ')' :\n   //\n   parse_all();\n   //\n   // Unwind pushed alternatives:\n   //\n   if(0 == unwind_alts(last_paren_start))\n      return false;\n   //\n   // restore flags:\n   //\n   if(m_has_case_change)\n   {\n      // the case has changed in one or more of the alternatives\n      // within the scoped (...) block: we have to add a state\n      // to reset the case sensitivity:\n      static_cast<re_case*>(\n         this->append_state(syntax_element_toggle_case, sizeof(re_case))\n         )->icase = opts & regbase::icase;\n   }\n   this->flags(opts);\n   m_has_case_change = old_case_change;\n   //\n   // restore branch reset:\n   //\n   m_mark_reset = mark_reset;\n   //\n   // we either have a ')' or we have run out of characters prematurely:\n   //\n   if(m_position == m_end)\n   {\n      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));\n      return false;\n   }\n   if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n      return false;\n   if(markid && (this->flags() & regbase::save_subexpression_location))\n      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);\n   ++m_position;\n   //\n   // append closing parenthesis state:\n   //\n   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   this->m_paren_start = last_paren_start;\n   //\n   // restore the alternate insertion point:\n   //\n   this->m_alt_insert_point = last_alt_point;\n\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_basic_escape()\n{\n   if(++m_position == m_end)\n   {\n      fail(regex_constants::error_paren, m_position - m_base);\n      return false;\n   }\n   bool result = true;\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::syntax_open_mark:\n      return parse_open_paren();\n   case regex_constants::syntax_close_mark:\n      return false;\n   case regex_constants::syntax_plus:\n      if(this->flags() & regex_constants::bk_plus_qm)\n      {\n         ++m_position;\n         return parse_repeat(1);\n      }\n      else\n         return parse_literal();\n   case regex_constants::syntax_question:\n      if(this->flags() & regex_constants::bk_plus_qm)\n      {\n         ++m_position;\n         return parse_repeat(0, 1);\n      }\n      else\n         return parse_literal();\n   case regex_constants::syntax_open_brace:\n      if(this->flags() & regbase::no_intervals)\n         return parse_literal();\n      ++m_position;\n      return parse_repeat_range(true);\n   case regex_constants::syntax_close_brace:\n      if(this->flags() & regbase::no_intervals)\n         return parse_literal();\n      fail(regex_constants::error_brace, this->m_position - this->m_base, \"Found a closing repetition operator } with no corresponding {.\");\n      return false;\n   case regex_constants::syntax_or:\n      if(this->flags() & regbase::bk_vbar)\n         return parse_alt();\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::syntax_digit:\n      return parse_backref();\n   case regex_constants::escape_type_start_buffer:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_buffer_start);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_end_buffer:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_buffer_end);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_word_assert:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_boundary);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_not_word_assert:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_within_word);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_left_word:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_start);\n      }\n      else\n         result = parse_literal();\n      break;\n   case regex_constants::escape_type_right_word:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         ++m_position;\n         this->append_state(syntax_element_word_end);\n      }\n      else\n         result = parse_literal();\n      break;\n   default:\n      if(this->flags() & regbase::emacs_ex)\n      {\n         bool negate = true;\n         switch(*m_position)\n         {\n         case 'w':\n            negate = false;\n            BOOST_REGEX_FALLTHROUGH;\n         case 'W':\n            {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(this->m_word_mask);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            ++m_position;\n            return true;\n            }\n         case 's':\n            negate = false;\n            BOOST_REGEX_FALLTHROUGH;\n         case 'S':\n            return add_emacs_code(negate);\n         case 'c':\n         case 'C':\n            // not supported yet:\n            fail(regex_constants::error_escape, m_position - m_base, \"The \\\\c and \\\\C escape sequences are not supported by POSIX basic regular expressions: try the Perl syntax instead.\");\n            return false;\n         default:\n            break;\n         }\n      }\n      result = parse_literal();\n      break;\n   }\n   return result;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_extended_escape()\n{\n   ++m_position;\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_escape, m_position - m_base, \"Incomplete escape sequence found.\");\n      return false;\n   }\n   bool negate = false; // in case this is a character class escape: \\w \\d etc\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::escape_type_not_class:\n      negate = true;\n      BOOST_REGEX_FALLTHROUGH;\n   case regex_constants::escape_type_class:\n      {\nescape_type_class_jump:\n         typedef typename traits::char_class_type m_type;\n         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n         if(m != 0)\n         {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(m);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            ++m_position;\n            return true;\n         }\n         //\n         // not a class, just a regular unknown escape:\n         //\n         this->append_literal(unescape_character());\n         break;\n      }\n   case regex_constants::syntax_digit:\n      return parse_backref();\n   case regex_constants::escape_type_left_word:\n      ++m_position;\n      this->append_state(syntax_element_word_start);\n      break;\n   case regex_constants::escape_type_right_word:\n      ++m_position;\n      this->append_state(syntax_element_word_end);\n      break;\n   case regex_constants::escape_type_start_buffer:\n      ++m_position;\n      this->append_state(syntax_element_buffer_start);\n      break;\n   case regex_constants::escape_type_end_buffer:\n      ++m_position;\n      this->append_state(syntax_element_buffer_end);\n      break;\n   case regex_constants::escape_type_word_assert:\n      ++m_position;\n      this->append_state(syntax_element_word_boundary);\n      break;\n   case regex_constants::escape_type_not_word_assert:\n      ++m_position;\n      this->append_state(syntax_element_within_word);\n      break;\n   case regex_constants::escape_type_Z:\n      ++m_position;\n      this->append_state(syntax_element_soft_buffer_end);\n      break;\n   case regex_constants::escape_type_Q:\n      return parse_QE();\n   case regex_constants::escape_type_C:\n      return parse_match_any();\n   case regex_constants::escape_type_X:\n      ++m_position;\n      this->append_state(syntax_element_combining);\n      break;\n   case regex_constants::escape_type_G:\n      ++m_position;\n      this->append_state(syntax_element_restart_continue);\n      break;\n   case regex_constants::escape_type_not_property:\n      negate = true;\n      BOOST_REGEX_FALLTHROUGH;\n   case regex_constants::escape_type_property:\n      {\n         ++m_position;\n         char_class_type m;\n         if(m_position == m_end)\n         {\n            fail(regex_constants::error_escape, m_position - m_base, \"Incomplete property escape found.\");\n            return false;\n         }\n         // maybe have \\p{ddd}\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n         {\n            const charT* base = m_position;\n            // skip forward until we find enclosing brace:\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               fail(regex_constants::error_escape, m_position - m_base, \"Closing } missing from property escape sequence.\");\n               return false;\n            }\n            m = this->m_traits.lookup_classname(++base, m_position++);\n         }\n         else\n         {\n            m = this->m_traits.lookup_classname(m_position, m_position+1);\n            ++m_position;\n         }\n         if(m != 0)\n         {\n            basic_char_set<charT, traits> char_set;\n            if(negate)\n               char_set.negate();\n            char_set.add_class(m);\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n            return true;\n         }\n         fail(regex_constants::error_ctype, m_position - m_base, \"Escape sequence was neither a valid property nor a valid character class name.\");\n         return false;\n      }\n   case regex_constants::escape_type_reset_start_mark:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n         pb->index = -5;\n         pb->icase = this->flags() & regbase::icase;\n         this->m_pdata->m_data.align();\n         ++m_position;\n         return true;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_line_ending:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         const charT* e = get_escape_R_string<charT>();\n         const charT* old_position = m_position;\n         const charT* old_end = m_end;\n         const charT* old_base = m_base;\n         m_position = e;\n         m_base = e;\n         m_end = e + traits::length(e);\n         bool r = parse_all();\n         m_position = ++old_position;\n         m_end = old_end;\n         m_base = old_base;\n         return r;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_extended_backref:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n      {\n         bool have_brace = false;\n         bool negative = false;\n         static const char incomplete_message[] = \"Incomplete \\\\g escape found.\";\n         if(++m_position == m_end)\n         {\n            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n            return false;\n         }\n         // maybe have \\g{ddd}\n         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);\n         regex_constants::syntax_type syn_end = 0;\n         if((syn == regex_constants::syntax_open_brace) \n            || (syn == regex_constants::escape_type_left_word)\n            || (syn == regex_constants::escape_type_end_buffer))\n         {\n            if(++m_position == m_end)\n            {\n               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n               return false;\n            }\n            have_brace = true;\n            switch(syn)\n            {\n            case regex_constants::syntax_open_brace:\n               syn_end = regex_constants::syntax_close_brace;\n               break;\n            case regex_constants::escape_type_left_word:\n               syn_end = regex_constants::escape_type_right_word;\n               break;\n            default:\n               syn_end = regex_constants::escape_type_end_buffer;\n               break;\n            }\n         }\n         negative = (*m_position == static_cast<charT>('-'));\n         if((negative) && (++m_position == m_end))\n         {\n            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n            return false;\n         }\n         const charT* pc = m_position;\n         std::intmax_t i = this->m_traits.toi(pc, m_end, 10);\n         if((i < 0) && syn_end)\n         {\n            // Check for a named capture, get the leftmost one if there is more than one:\n            const charT* base = m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))\n            {\n               ++m_position;\n            }\n            i = hash_value_from_capture_name(base, m_position);\n            pc = m_position;\n         }\n         if(negative)\n            i = 1 + (static_cast<std::intmax_t>(m_mark_count) - i);\n         if(((i < hash_value_mask) && (i > 0)) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0)))\n         {\n            m_position = pc;\n            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));\n            pb->index = (int)i;\n            pb->icase = this->flags() & regbase::icase;\n            if ((i > m_max_backref) && (i < hash_value_mask))\n               m_max_backref = i;\n         }\n         else\n         {\n            fail(regex_constants::error_backref, m_position - m_base);\n            return false;\n         }\n         m_position = pc;\n         if(have_brace)\n         {\n            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))\n            {\n               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);\n               return false;\n            }\n            ++m_position;\n         }\n         return true;\n      }\n      goto escape_type_class_jump;\n   case regex_constants::escape_type_control_v:\n      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n         goto escape_type_class_jump;\n      BOOST_REGEX_FALLTHROUGH;\n   default:\n      this->append_literal(unescape_character());\n      break;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_match_any()\n{\n   //\n   // we have a '.' that can match any character:\n   //\n   ++m_position;\n   static_cast<re_dot*>(\n      this->append_state(syntax_element_wild, sizeof(re_dot))\n      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s \n      ? BOOST_REGEX_DETAIL_NS::force_not_newline \n         : this->flags() & regbase::mod_s ?\n            BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care);\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)\n{\n   bool greedy = true;\n   bool possessive = false;\n   std::size_t insert_point;\n   // \n   // when we get to here we may have a non-greedy ? mark still to come:\n   //\n   if((m_position != m_end) \n      && (\n            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))\n            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))\n         )\n      )\n   {\n      // OK we have a perl or emacs regex, check for a '?':\n      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)\n      {\n         // whitespace skip:\n         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n            ++m_position;\n      }\n      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))\n      {\n         greedy = false;\n         ++m_position;\n      }\n      // for perl regexes only check for possessive ++ repeats.\n      if((m_position != m_end)\n         && (0 == (this->flags() & regbase::main_option_type)) \n         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))\n      {\n         possessive = true;\n         ++m_position;\n      }\n   }\n   if(0 == this->m_last_state)\n   {\n      fail(regex_constants::error_badrepeat, std::distance(m_base, m_position), \"Nothing to repeat.\");\n      return false;\n   }\n   if(this->m_last_state->type == syntax_element_endmark)\n   {\n      // insert a repeat before the '(' matching the last ')':\n      insert_point = this->m_paren_start;\n   }\n   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))\n   {\n      // the last state was a literal with more than one character, split it in two:\n      re_literal* lit = static_cast<re_literal*>(this->m_last_state);\n      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];\n      lit->length -= 1;\n      // now append new state:\n      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));\n      lit->length = 1;\n      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;\n      insert_point = this->getoffset(this->m_last_state);\n   }\n   else\n   {\n      // repeat the last state whatever it was, need to add some error checking here:\n      switch(this->m_last_state->type)\n      {\n      case syntax_element_start_line:\n      case syntax_element_end_line:\n      case syntax_element_word_boundary:\n      case syntax_element_within_word:\n      case syntax_element_word_start:\n      case syntax_element_word_end:\n      case syntax_element_buffer_start:\n      case syntax_element_buffer_end:\n      case syntax_element_alt:\n      case syntax_element_soft_buffer_end:\n      case syntax_element_restart_continue:\n      case syntax_element_jump:\n      case syntax_element_startmark:\n      case syntax_element_backstep:\n      case syntax_element_toggle_case:\n         // can't legally repeat any of the above:\n         fail(regex_constants::error_badrepeat, m_position - m_base);\n         return false;\n      default:\n         // do nothing...\n         break;\n      }\n      insert_point = this->getoffset(this->m_last_state);\n   }\n   //\n   // OK we now know what to repeat, so insert the repeat around it:\n   //\n   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));\n   rep->min = low;\n   rep->max = high;\n   rep->greedy = greedy;\n   rep->leading = false;\n   // store our repeater position for later:\n   std::ptrdiff_t rep_off = this->getoffset(rep);\n   // and append a back jump to the repeat:\n   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));\n   jmp->alt.i = rep_off - this->getoffset(jmp);\n   this->m_pdata->m_data.align();\n   // now fill in the alt jump for the repeat:\n   rep = static_cast<re_repeat*>(this->getaddress(rep_off));\n   rep->alt.i = this->m_pdata->m_data.size() - rep_off;\n   //\n   // If the repeat is possessive then bracket the repeat with a (?>...)\n   // independent sub-expression construct:\n   //\n   if(possessive)\n   {\n      if(m_position != m_end)\n      {\n         //\n         // Check for illegal following quantifier, we have to do this here, because\n         // the extra states we insert below circumvents our usual error checking :-(\n         //\n         bool contin = false;\n         do\n         {\n            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)\n            {\n               // whitespace skip:\n               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n                  ++m_position;\n            }\n            if (m_position != m_end)\n            {\n               switch (this->m_traits.syntax_type(*m_position))\n               {\n               case regex_constants::syntax_star:\n               case regex_constants::syntax_plus:\n               case regex_constants::syntax_question:\n               case regex_constants::syntax_open_brace:\n                  fail(regex_constants::error_badrepeat, m_position - m_base);\n                  return false;\n               case regex_constants::syntax_open_mark:\n                  // Do we have a comment?  If so we need to skip it here...\n                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question\n                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)\n                  {\n                     while ((m_position != m_end)\n                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {\n                     }\n                     contin = true;\n                  }\n                  else\n                     contin = false;\n                  break;\n               default:\n                  contin = false;\n               }\n            }\n            else\n               contin = false;\n         } while (contin);\n      }\n      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));\n      pb->index = -3;\n      pb->icase = this->flags() & regbase::icase;\n      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);\n      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n      pb->index = -3;\n      pb->icase = this->flags() & regbase::icase;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)\n{\n   static const char incomplete_message[] = \"Missing } in quantified repetition.\";\n   //\n   // parse a repeat-range:\n   //\n   std::size_t min, max;\n   std::intmax_t v;\n   // skip whitespace:\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   // get min:\n   v = this->m_traits.toi(m_position, m_end, 10);\n   // skip whitespace:\n   if((v < 0) || (v > umax()))\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   min = static_cast<std::size_t>(v);\n   // see if we have a comma:\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)\n   {\n      // move on and error check:\n      ++m_position;\n      // skip whitespace:\n      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n         ++m_position;\n      if(this->m_position == this->m_end)\n      {\n         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n         {\n            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n            return false;\n         }\n         // Treat the opening '{' as a literal character, rewind to start of error:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n         return parse_literal();\n      }\n      // get the value if any:\n      v = this->m_traits.toi(m_position, m_end, 10);\n      max = ((v >= 0) && (v < umax())) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();\n   }\n   else\n   {\n      // no comma, max = min:\n      max = min;\n   }\n   // skip whitespace:\n   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))\n      ++m_position;\n   // OK now check trailing }:\n   if(this->m_position == this->m_end)\n   {\n      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   if(isbasic)\n   {\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)\n      {\n         ++m_position;\n         if(this->m_position == this->m_end)\n         {\n            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n            return false;\n         }\n      }\n      else\n      {\n         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);\n         return false;\n      }\n   }\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)\n      ++m_position;\n   else\n   {\n      // Treat the opening '{' as a literal character, rewind to start of error:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;\n      return parse_literal();\n   }\n   //\n   // finally go and add the repeat, unless error:\n   //\n   if(min > max)\n   {\n      // Backtrack to error location:\n      m_position -= 2;\n      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;\n         ++m_position;\n      fail(regex_constants::error_badbrace, m_position - m_base);\n      return false;\n   }\n   return parse_repeat(min, max);\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_alt()\n{\n   //\n   // error check: if there have been no previous states,\n   // or if the last state was a '(' then error:\n   //\n   if(\n      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))\n      &&\n      !(\n         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)\n           &&\n         ((this->flags() & regbase::no_empty_expressions) == 0)\n        )\n      )\n   {\n      fail(regex_constants::error_empty, this->m_position - this->m_base, \"A regular expression cannot start with the alternation operator |.\");\n      return false;\n   }\n   //\n   // Reset mark count if required:\n   //\n   if(m_max_mark < m_mark_count)\n      m_max_mark = m_mark_count;\n   if(m_mark_reset >= 0)\n      m_mark_count = m_mark_reset;\n\n   ++m_position;\n   //\n   // we need to append a trailing jump: \n   //\n   re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump));\n   std::ptrdiff_t jump_offset = this->getoffset(pj);\n   //\n   // now insert the alternative:\n   //\n   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));\n   jump_offset += re_alt_size;\n   this->m_pdata->m_data.align();\n   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);\n   //\n   // update m_alt_insert_point so that the next alternate gets\n   // inserted at the start of the second of the two we've just created:\n   //\n   this->m_alt_insert_point = this->m_pdata->m_data.size();\n   //\n   // the start of this alternative must have a case changes state\n   // if the current block has messed around with case changes:\n   //\n   if(m_has_case_change)\n   {\n      static_cast<re_case*>(\n         this->append_state(syntax_element_toggle_case, sizeof(re_case))\n         )->icase = this->m_icase;\n   }\n   //\n   // push the alternative onto our stack, a recursive\n   // implementation here is easier to understand (and faster\n   // as it happens), but causes all kinds of stack overflow problems\n   // on programs with small stacks (COM+).\n   //\n   m_alt_jumps.push_back(jump_offset);\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_set()\n{\n   static const char incomplete_message[] = \"Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.\";\n   ++m_position;\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n      return false;\n   }\n   basic_char_set<charT, traits> char_set;\n\n   const charT* base = m_position;  // where the '[' was\n   const charT* item_base = m_position;  // where the '[' or '^' was\n\n   while(m_position != m_end)\n   {\n      switch(this->m_traits.syntax_type(*m_position))\n      {\n      case regex_constants::syntax_caret:\n         if(m_position == base)\n         {\n            char_set.negate();\n            ++m_position;\n            item_base = m_position;\n         }\n         else\n            parse_set_literal(char_set);\n         break;\n      case regex_constants::syntax_close_set:\n         if(m_position == item_base)\n         {\n            parse_set_literal(char_set);\n            break;\n         }\n         else\n         {\n            ++m_position;\n            if(0 == this->append_set(char_set))\n            {\n               fail(regex_constants::error_ctype, m_position - m_base);\n               return false;\n            }\n         }\n         return true;\n      case regex_constants::syntax_open_set:\n         if(parse_inner_set(char_set))\n            break;\n         return true;\n      case regex_constants::syntax_escape:\n         {\n            // \n            // look ahead and see if this is a character class shortcut\n            // \\d \\w \\s etc...\n            //\n            ++m_position;\n            if(this->m_traits.escape_syntax_type(*m_position)\n               == regex_constants::escape_type_class)\n            {\n               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n               if(m != 0)\n               {\n                  char_set.add_class(m);\n                  ++m_position;\n                  break;\n               }\n            }\n            else if(this->m_traits.escape_syntax_type(*m_position)\n               == regex_constants::escape_type_not_class)\n            {\n               // negated character class:\n               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);\n               if(m != 0)\n               {\n                  char_set.add_negated_class(m);\n                  ++m_position;\n                  break;\n               }\n            }\n            // not a character class, just a regular escape:\n            --m_position;\n            parse_set_literal(char_set);\n            break;\n         }\n      default:\n         parse_set_literal(char_set);\n         break;\n      }\n   }\n   return m_position != m_end;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)\n{\n   static const char incomplete_message[] = \"Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.\";\n   //\n   // we have either a character class [:name:]\n   // a collating element [.name.]\n   // or an equivalence class [=name=]\n   //\n   if(m_end == ++m_position)\n   {\n      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n      return false;\n   }\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_dot:\n      //\n      // a collating element is treated as a literal:\n      //\n      --m_position;\n      parse_set_literal(char_set);\n      return true;\n   case regex_constants::syntax_colon:\n      {\n      // check that character classes are actually enabled:\n      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) \n         == (regbase::basic_syntax_group  | regbase::no_char_classes))\n      {\n         --m_position;\n         parse_set_literal(char_set);\n         return true;\n      }\n      // skip the ':'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching ':]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      //\n      // check for negated class:\n      //\n      bool negated = false;\n      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)\n      {\n         ++name_first;\n         negated = true;\n      }\n      typedef typename traits::char_class_type m_type;\n      m_type m = this->m_traits.lookup_classname(name_first, name_last);\n      if(m == 0)\n      {\n         if(char_set.empty() && (name_last - name_first == 1))\n         {\n            // maybe a special case:\n            ++m_position;\n            if( (m_position != m_end) \n               && (this->m_traits.syntax_type(*m_position) \n                  == regex_constants::syntax_close_set))\n            {\n               if(this->m_traits.escape_syntax_type(*name_first) \n                  == regex_constants::escape_type_left_word)\n               {\n                  ++m_position;\n                  this->append_state(syntax_element_word_start);\n                  return false;\n               }\n               if(this->m_traits.escape_syntax_type(*name_first) \n                  == regex_constants::escape_type_right_word)\n               {\n                  ++m_position;\n                  this->append_state(syntax_element_word_end);\n                  return false;\n               }\n            }\n         }\n         fail(regex_constants::error_ctype, name_first - m_base);\n         return false;\n      }\n      if(!negated)\n         char_set.add_class(m);\n      else\n         char_set.add_negated_class(m);\n      ++m_position;\n      break;\n   }\n   case regex_constants::syntax_equal:\n      {\n      // skip the '='\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching '=]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);\n         return false;\n      }\n      string_type m = this->m_traits.lookup_collatename(name_first, name_last);\n      if(m.empty() || (m.size() > 2))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return false;\n      }\n      digraph<charT> d;\n      d.first = m[0];\n      if(m.size() > 1)\n         d.second = m[1];\n      else\n         d.second = 0;\n      char_set.add_equivalent(d);\n      ++m_position;\n      break;\n   }\n   default:\n      --m_position;\n      parse_set_literal(char_set);\n      break;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nvoid basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)\n{\n   digraph<charT> start_range(get_next_set_literal(char_set));\n   if(m_end == m_position)\n   {\n      fail(regex_constants::error_brack, m_position - m_base);\n      return;\n   }\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)\n   {\n      // we have a range:\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_brack, m_position - m_base);\n         return;\n      }\n      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)\n      {\n         digraph<charT> end_range = get_next_set_literal(char_set);\n         char_set.add_range(start_range, end_range);\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)\n         {\n            if(m_end == ++m_position)\n            {\n               fail(regex_constants::error_brack, m_position - m_base);\n               return;\n            }\n            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)\n            {\n               // trailing - :\n               --m_position;\n               return;\n            }\n            fail(regex_constants::error_range, m_position - m_base);\n            return;\n         }\n         return;\n      }\n      --m_position;\n   }\n   char_set.add_single(start_range);\n}\n\ntemplate <class charT, class traits>\ndigraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)\n{\n   digraph<charT> result;\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_dash:\n      if(!char_set.empty())\n      {\n         // see if we are at the end of the set:\n         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n         {\n            fail(regex_constants::error_range, m_position - m_base);\n            return result;\n         }\n         --m_position;\n      }\n      result.first = *m_position++;\n      return result;\n   case regex_constants::syntax_escape:\n      // check to see if escapes are supported first:\n      if(this->flags() & regex_constants::no_escape_in_lists)\n      {\n         result = *m_position++;\n         break;\n      }\n      ++m_position;\n      result = unescape_character();\n      break;\n   case regex_constants::syntax_open_set:\n   {\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, m_position - m_base);\n         return result;\n      }\n      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)\n      {\n         --m_position;\n         result.first = *m_position;\n         ++m_position;\n         return result;\n      }\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, m_position - m_base);\n         return result;\n      }\n      const charT* name_first = m_position;\n      // skip at least one character, then find the matching ':]'\n      if(m_end == ++m_position)\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) \n         ++m_position;\n      const charT* name_last = m_position;\n      if(m_end == m_position)\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      if((m_end == ++m_position) \n         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      ++m_position;\n      string_type s = this->m_traits.lookup_collatename(name_first, name_last);\n      if(s.empty() || (s.size() > 2))\n      {\n         fail(regex_constants::error_collate, name_first - m_base);\n         return result;\n      }\n      result.first = s[0];\n      if(s.size() > 1)\n         result.second = s[1];\n      else\n         result.second = 0;\n      return result;\n   }\n   default:\n      result = *m_position++;\n   }\n   return result;\n}\n\n//\n// does a value fit in the specified charT type?\n//\ntemplate <class charT>\nbool valid_value(charT, std::intmax_t v, const std::integral_constant<bool, true>&)\n{\n   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;\n}\ntemplate <class charT>\nbool valid_value(charT, std::intmax_t, const std::integral_constant<bool, false>&)\n{\n   return true; // v will alsways fit in a charT\n}\ntemplate <class charT>\nbool valid_value(charT c, std::intmax_t v)\n{\n   return valid_value(c, v, std::integral_constant<bool, (sizeof(charT) < sizeof(std::intmax_t))>());\n}\n\ntemplate <class charT, class traits>\ncharT basic_regex_parser<charT, traits>::unescape_character()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   charT result(0);\n   if(m_position == m_end)\n   {\n      fail(regex_constants::error_escape, m_position - m_base, \"Escape sequence terminated prematurely.\");\n      return false;\n   }\n   switch(this->m_traits.escape_syntax_type(*m_position))\n   {\n   case regex_constants::escape_type_control_a:\n      result = charT('\\a');\n      break;\n   case regex_constants::escape_type_e:\n      result = charT(27);\n      break;\n   case regex_constants::escape_type_control_f:\n      result = charT('\\f');\n      break;\n   case regex_constants::escape_type_control_n:\n      result = charT('\\n');\n      break;\n   case regex_constants::escape_type_control_r:\n      result = charT('\\r');\n      break;\n   case regex_constants::escape_type_control_t:\n      result = charT('\\t');\n      break;\n   case regex_constants::escape_type_control_v:\n      result = charT('\\v');\n      break;\n   case regex_constants::escape_type_word_assert:\n      result = charT('\\b');\n      break;\n   case regex_constants::escape_type_ascii_control:\n      ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"ASCII escape sequence terminated prematurely.\");\n         return result;\n      }\n      result = static_cast<charT>(*m_position % 32);\n      break;\n   case regex_constants::escape_type_hex:\n      ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"Hexadecimal escape sequence terminated prematurely.\");\n         return result;\n      }\n      // maybe have \\x{ddd}\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base, \"Missing } in hexadecimal escape sequence.\");\n            return result;\n         }\n         std::intmax_t i = this->m_traits.toi(m_position, m_end, 16);\n         if((m_position == m_end)\n            || (i < 0)\n            || ((std::numeric_limits<charT>::is_specialized) && (i > (std::intmax_t)(std::numeric_limits<charT>::max)()))\n            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_badbrace, m_position - m_base, \"Hexadecimal escape sequence was invalid.\");\n            return result;\n         }\n         ++m_position;\n         result = charT(i);\n      }\n      else\n      {\n         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));\n         std::intmax_t i = this->m_traits.toi(m_position, m_position + len, 16);\n         if((i < 0)\n            || !valid_value(charT(0), i))\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base, \"Escape sequence did not encode a valid character.\");\n            return result;\n         }\n         result = charT(i);\n      }\n      return result;\n   case regex_constants::syntax_digit:\n      {\n      // an octal escape sequence, the first character must be a zero\n      // followed by up to 3 octal digits:\n      std::ptrdiff_t len = (std::min)(std::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));\n      const charT* bp = m_position;\n      std::intmax_t val = this->m_traits.toi(bp, bp + 1, 8);\n      if(val != 0)\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         // Oops not an octal escape after all:\n         fail(regex_constants::error_escape, m_position - m_base, \"Invalid octal escape sequence.\");\n         return result;\n      }\n      val = this->m_traits.toi(m_position, m_position + len, 8);\n      if((val < 0) || (val > (std::intmax_t)(std::numeric_limits<charT>::max)()))\n      {\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base, \"Octal escape sequence is invalid.\");\n         return result;\n      }\n      return static_cast<charT>(val);\n      }\n   case regex_constants::escape_type_named_char:\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of escape:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n            fail(regex_constants::error_escape, m_position - m_base);\n            return false;\n         }\n         // maybe have \\N{name}\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)\n         {\n            const charT* base = m_position;\n            // skip forward until we find enclosing brace:\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of escape:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n               fail(regex_constants::error_escape, m_position - m_base);\n               return false;\n            }\n            string_type s = this->m_traits.lookup_collatename(++base, m_position++);\n            if(s.empty())\n            {\n               // Rewind to start of escape:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n               fail(regex_constants::error_collate, m_position - m_base);\n               return false;\n            }\n            if(s.size() == 1)\n            {\n               return s[0];\n            }\n         }\n         // fall through is a failure:\n         // Rewind to start of escape:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n         fail(regex_constants::error_escape, m_position - m_base);\n         return false;\n      }\n   default:\n      result = *m_position;\n      break;\n   }\n   ++m_position;\n   return result;\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_backref()\n{\n   BOOST_REGEX_ASSERT(m_position != m_end);\n   const charT* pc = m_position;\n   std::intmax_t i = this->m_traits.toi(pc, pc + 1, 10);\n   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))\n   {\n      // not a backref at all but an octal escape sequence:\n      charT c = unescape_character();\n      this->append_literal(c);\n   }\n   else if((i > 0))\n   {\n      m_position = pc;\n      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));\n      pb->index = (int)i;\n      pb->icase = this->flags() & regbase::icase;\n      if(i > m_max_backref)\n         m_max_backref = i;\n   }\n   else\n   {\n      // Rewind to start of escape:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n      fail(regex_constants::error_backref, m_position - m_base);\n      return false;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_QE()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   //\n   // parse a \\Q...\\E sequence:\n   //\n   ++m_position; // skip the Q\n   const charT* start = m_position;\n   const charT* end;\n   do\n   {\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))\n         ++m_position;\n      if(m_position == m_end)\n      {\n         //  a \\Q...\\E sequence may terminate with the end of the expression:\n         end = m_position;\n         break;  \n      }\n      if(++m_position == m_end) // skip the escape\n      {\n         fail(regex_constants::error_escape, m_position - m_base, \"Unterminated \\\\Q...\\\\E sequence.\");\n         return false;\n      }\n      // check to see if it's a \\E:\n      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)\n      {\n         ++m_position;\n         end = m_position - 2;\n         break;\n      }\n      // otherwise go round again:\n   }while(true);\n   //\n   // now add all the character between the two escapes as literals:\n   //\n   while(start != end)\n   {\n      this->append_literal(*start);\n      ++start;\n   }\n   return true;\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_perl_extension()\n{\n   if(++m_position == m_end)\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   }\n   //\n   // treat comments as a special case, as these\n   // are the only ones that don't start with a leading\n   // startmark state:\n   //\n   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)\n   {\n      while((m_position != m_end) \n         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))\n      {}\n      return true;\n   }\n   //\n   // backup some state, and prepare the way:\n   //\n   int markid = 0;\n   std::ptrdiff_t jump_offset = 0;\n   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));\n   pb->icase = this->flags() & regbase::icase;\n   std::ptrdiff_t last_paren_start = this->getoffset(pb);\n   // back up insertion point for alternations, and set new point:\n   std::ptrdiff_t last_alt_point = m_alt_insert_point;\n   this->m_pdata->m_data.align();\n   m_alt_insert_point = this->m_pdata->m_data.size();\n   std::ptrdiff_t expected_alt_point = m_alt_insert_point;\n   bool restore_flags = true;\n   regex_constants::syntax_option_type old_flags = this->flags();\n   bool old_case_change = m_has_case_change;\n   m_has_case_change = false;\n   charT name_delim;\n   int mark_reset = m_mark_reset;\n   int max_mark = m_max_mark;\n   m_mark_reset = -1;\n   m_max_mark = m_mark_count;\n   std::intmax_t v;\n   //\n   // select the actual extension used:\n   //\n   switch(this->m_traits.syntax_type(*m_position))\n   {\n   case regex_constants::syntax_or:\n      m_mark_reset = m_mark_count;\n      BOOST_REGEX_FALLTHROUGH;\n   case regex_constants::syntax_colon:\n      //\n      // a non-capturing mark:\n      //\n      pb->index = markid = 0;\n      ++m_position;\n      break;\n   case regex_constants::syntax_digit:\n      {\n      //\n      // a recursive subexpression:\n      //\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"The recursive sub-expression refers to an invalid marking group, or is unterminated.\");\n         return false;\n      }\ninsert_recursion:\n      pb->index = markid = 0;\n      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));\n      pr->alt.i = (std::ptrdiff_t)v;\n      pr->state_id = 0;\n      static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = this->flags() & regbase::icase;\n      break;\n      }\n   case regex_constants::syntax_plus:\n      //\n      // A forward-relative recursive subexpression:\n      //\n      ++m_position;\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      if ((std::numeric_limits<std::intmax_t>::max)() - m_mark_count < v)\n      {\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      v += m_mark_count;\n      goto insert_recursion;\n   case regex_constants::syntax_dash:\n      //\n      // Possibly a backward-relative recursive subexpression:\n      //\n      ++m_position;\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if(v <= 0)\n      {\n         --m_position;\n         // Oops not a relative recursion at all, but a (?-imsx) group:\n         goto option_group_jump;\n      }\n      v = static_cast<std::intmax_t>(m_mark_count) + 1 - v;\n      if(v <= 0)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"An invalid or unterminated recursive sub-expression.\");\n         return false;\n      }\n      goto insert_recursion;\n   case regex_constants::syntax_equal:\n      pb->index = markid = -1;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::syntax_not:\n      pb->index = markid = -2;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::escape_type_left_word:\n      {\n         // a lookbehind assertion:\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);\n         if(t == regex_constants::syntax_not)\n            pb->index = markid = -2;\n         else if(t == regex_constants::syntax_equal)\n            pb->index = markid = -1;\n         else\n         {\n            // Probably a named capture which also starts (?< :\n            name_delim = '>';\n            --m_position;\n            goto named_capture_jump;\n         }\n         ++m_position;\n         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n         this->append_state(syntax_element_backstep, sizeof(re_brace));\n         this->m_pdata->m_data.align();\n         m_alt_insert_point = this->m_pdata->m_data.size();\n         break;\n      }\n   case regex_constants::escape_type_right_word:\n      //\n      // an independent sub-expression:\n      //\n      pb->index = markid = -3;\n      ++m_position;\n      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));\n      this->m_pdata->m_data.align();\n      m_alt_insert_point = this->m_pdata->m_data.size();\n      break;\n   case regex_constants::syntax_open_mark:\n      {\n      // a conditional expression:\n      pb->index = markid = -4;\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      v = this->m_traits.toi(m_position, m_end, 10);\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(*m_position == charT('R'))\n      {\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(*m_position == charT('&'))\n         {\n            const charT* base = ++m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));\n         }\n         else\n         {\n            v = -this->m_traits.toi(m_position, m_end, 10);\n         }\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = v < 0 ? (int)(v - 1) : 0;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if((*m_position == charT('\\'')) || (*m_position == charT('<')))\n      {\n         const charT* base = ++m_position;\n         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\\'')))\n            ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = (int)v;\n         if(((*m_position != charT('>')) && (*m_position != charT('\\''))) || (++m_position == m_end))\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base, \"Unterminated named capture.\");\n            return false;\n         }\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if(*m_position == charT('D'))\n      {\n         const char* def = \"DEFINE\";\n         while(*def && (m_position != m_end) && (*m_position == charT(*def)))\n            ++m_position, ++def;\n         if((m_position == m_end) || *def)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = 9999; // special magic value!\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else if(v > 0)\n      {\n         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));\n         br->index = (int)v;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n      }\n      else\n      {\n         // verify that we have a lookahead or lookbehind assert:\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)\n         {\n            if(++m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)\n               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            m_position -= 3;\n         }\n         else\n         {\n            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)\n               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            m_position -= 2;\n         }\n      }\n      break;\n      }\n   case regex_constants::syntax_close_mark:\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   case regex_constants::escape_type_end_buffer:\n      {\n      name_delim = *m_position;\nnamed_capture_jump:\n      markid = 0;\n      if(0 == (this->flags() & regbase::nosubs))\n      {\n         markid = ++m_mark_count;\n         if(this->flags() & regbase::save_subexpression_location)\n            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));\n      }\n      pb->index = markid;\n      const charT* base = ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      while((m_position != m_end) && (*m_position != name_delim))\n         ++m_position;\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      this->m_pdata->set_name(base, m_position, markid);\n      ++m_position;\n      break;\n      }\n   default:\n      if(*m_position == charT('R'))\n      {\n         ++m_position;\n         v = 0;\n         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         goto insert_recursion;\n      }\n      if(*m_position == charT('&'))\n      {\n         ++m_position;\n         const charT* base = m_position;\n         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n            ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n         goto insert_recursion;\n      }\n      if(*m_position == charT('P'))\n      {\n         ++m_position;\n         if(m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         if(*m_position == charT('>'))\n         {\n            ++m_position;\n            const charT* base = m_position;\n            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n               ++m_position;\n            if(m_position == m_end)\n            {\n               // Rewind to start of (? sequence:\n               --m_position;\n               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n               fail(regex_constants::error_perl_extension, m_position - m_base);\n               return false;\n            }\n            v = static_cast<int>(hash_value_from_capture_name(base, m_position));\n            goto insert_recursion;\n         }\n      }\n      //\n      // lets assume that we have a (?imsx) group and try and parse it:\n      //\noption_group_jump:\n      regex_constants::syntax_option_type opts = parse_options();\n      if(m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      // make a note of whether we have a case change:\n      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));\n      pb->index = markid = 0;\n      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)\n      {\n         // update flags and carry on as normal:\n         this->flags(opts);\n         restore_flags = false;\n         old_case_change |= m_has_case_change; // defer end of scope by one ')'\n      }\n      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)\n      {\n         // update flags and carry on until the matching ')' is found:\n         this->flags(opts);\n         ++m_position;\n      }\n      else\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n\n      // finally append a case change state if we need it:\n      if(m_has_case_change)\n      {\n         static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = opts & regbase::icase;\n      }\n\n   }\n   //\n   // now recursively add more states, this will terminate when we get to a\n   // matching ')' :\n   //\n   parse_all();\n   //\n   // Unwind alternatives:\n   //\n   if(0 == unwind_alts(last_paren_start))\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base, \"Invalid alternation operators within (?...) block.\");\n      return false;\n   }\n   //\n   // we either have a ')' or we have run out of characters prematurely:\n   //\n   if(m_position == m_end)\n   {\n      // Rewind to start of (? sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));\n      return false;\n   }\n   BOOST_REGEX_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);\n   ++m_position;\n   //\n   // restore the flags:\n   //\n   if(restore_flags)\n   {\n      // append a case change state if we need it:\n      if(m_has_case_change)\n      {\n         static_cast<re_case*>(\n            this->append_state(syntax_element_toggle_case, sizeof(re_case))\n            )->icase = old_flags & regbase::icase;\n      }\n      this->flags(old_flags);\n   }\n   //\n   // set up the jump pointer if we have one:\n   //\n   if(jump_offset)\n   {\n      this->m_pdata->m_data.align();\n      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));\n      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);\n      if((this->m_last_state == jmp) && (markid != -2))\n      {\n         // Oops... we didn't have anything inside the assertion.\n         // Note we don't get here for negated forward lookahead as (?!)\n         // does have some uses.\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base, \"Invalid or empty zero width assertion.\");\n         return false;\n      }\n   }\n   //\n   // verify that if this is conditional expression, that we do have\n   // an alternative, if not add one:\n   //\n   if(markid == -4)\n   {\n      re_syntax_base* b = this->getaddress(expected_alt_point);\n      // Make sure we have exactly one alternative following this state:\n      if(b->type != syntax_element_alt)\n      {\n         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));\n         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);\n      }\n      else if(((std::ptrdiff_t)this->m_pdata->m_data.size() > (static_cast<re_alt*>(b)->alt.i + this->getoffset(b))) && (static_cast<re_alt*>(b)->alt.i > 0) && this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)\n      {\n         // Can't have seen more than one alternative:\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_bad_pattern, m_position - m_base, \"More than one alternation operator | was encountered inside a conditional expression.\");\n         return false;\n      }\n      else\n      {\n         // We must *not* have seen an alternative inside a (DEFINE) block:\n         b = this->getaddress(b->next.i, b);\n         if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_bad_pattern, m_position - m_base, \"Alternation operators are not allowed inside a DEFINE block.\");\n            return false;\n         }\n      }\n      // check for invalid repetition of next state:\n      b = this->getaddress(expected_alt_point);\n      b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);\n      if((b->type != syntax_element_assert_backref)\n         && (b->type != syntax_element_startmark))\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_badrepeat, m_position - m_base, \"A repetition operator cannot be applied to a zero-width assertion.\");\n         return false;\n      }\n   }\n   //\n   // append closing parenthesis state:\n   //\n   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));\n   pb->index = markid;\n   pb->icase = this->flags() & regbase::icase;\n   this->m_paren_start = last_paren_start;\n   //\n   // restore the alternate insertion point:\n   //\n   this->m_alt_insert_point = last_alt_point;\n   //\n   // and the case change data:\n   //\n   m_has_case_change = old_case_change;\n   //\n   // And the mark_reset data:\n   //\n   if(m_max_mark > m_mark_count)\n   {\n      m_mark_count = m_max_mark;\n   }\n   m_mark_reset = mark_reset;\n   m_max_mark = max_mark;\n\n\n   if(markid > 0)\n   {\n      if(this->flags() & regbase::save_subexpression_location)\n         this->m_pdata->m_subs.at((std::size_t)markid - 1).second = std::distance(m_base, m_position) - 1;\n   }\n   return true;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::match_verb(const char* verb)\n{\n   while(*verb)\n   {\n      if(static_cast<charT>(*verb) != *m_position)\n      {\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(++m_position == m_end)\n      {\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      ++verb;\n   }\n   return true;\n}\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable:26812)\n#endif\n#endif\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::parse_perl_verb()\n{\n   if(++m_position == m_end)\n   {\n      // Rewind to start of (* sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n      fail(regex_constants::error_perl_extension, m_position - m_base);\n      return false;\n   }\n   switch(*m_position)\n   {\n   case 'F':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if((this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark) || match_verb(\"AIL\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_fail);\n         return true;\n      }\n      break;\n   case 'A':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"CCEPT\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_accept);\n         return true;\n      }\n      break;\n   case 'C':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"OMMIT\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_commit;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'P':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"RUNE\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_prune;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'S':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"KIP\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         static_cast<re_commit*>(this->append_state(syntax_element_commit, sizeof(re_commit)))->action = commit_skip;\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   case 'T':\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (* sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_perl_extension, m_position - m_base);\n         return false;\n      }\n      if(match_verb(\"HEN\"))\n      {\n         if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))\n         {\n            // Rewind to start of (* sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_perl_extension, m_position - m_base);\n            return false;\n         }\n         ++m_position;\n         this->append_state(syntax_element_then);\n         this->m_pdata->m_disable_match_any = true;\n         return true;\n      }\n      break;\n   }\n   // Rewind to start of (* sequence:\n   --m_position;\n   while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n   fail(regex_constants::error_perl_extension, m_position - m_base);\n   return false;\n}\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::add_emacs_code(bool negate)\n{\n   //\n   // parses an emacs style \\sx or \\Sx construct.\n   //\n   if(++m_position == m_end)\n   {\n      // Rewind to start of sequence:\n      --m_position;\n      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;\n      fail(regex_constants::error_escape, m_position - m_base);\n      return false;\n   }\n   basic_char_set<charT, traits> char_set;\n   if(negate)\n      char_set.negate();\n\n   static const charT s_punct[5] = { 'p', 'u', 'n', 'c', 't', };\n\n   switch(*m_position)\n   {\n   case 's':\n   case ' ':\n      char_set.add_class(this->m_mask_space);\n      break;\n   case 'w':\n      char_set.add_class(this->m_word_mask);\n      break;\n   case '_':\n      char_set.add_single(digraph<charT>(charT('$'))); \n      char_set.add_single(digraph<charT>(charT('&'))); \n      char_set.add_single(digraph<charT>(charT('*'))); \n      char_set.add_single(digraph<charT>(charT('+'))); \n      char_set.add_single(digraph<charT>(charT('-'))); \n      char_set.add_single(digraph<charT>(charT('_'))); \n      char_set.add_single(digraph<charT>(charT('<'))); \n      char_set.add_single(digraph<charT>(charT('>'))); \n      break;\n   case '.':\n      char_set.add_class(this->m_traits.lookup_classname(s_punct, s_punct+5));\n      break;\n   case '(':\n      char_set.add_single(digraph<charT>(charT('('))); \n      char_set.add_single(digraph<charT>(charT('['))); \n      char_set.add_single(digraph<charT>(charT('{'))); \n      break;\n   case ')':\n      char_set.add_single(digraph<charT>(charT(')'))); \n      char_set.add_single(digraph<charT>(charT(']'))); \n      char_set.add_single(digraph<charT>(charT('}'))); \n      break;\n   case '\"':\n      char_set.add_single(digraph<charT>(charT('\"'))); \n      char_set.add_single(digraph<charT>(charT('\\''))); \n      char_set.add_single(digraph<charT>(charT('`'))); \n      break;\n   case '\\'':\n      char_set.add_single(digraph<charT>(charT('\\''))); \n      char_set.add_single(digraph<charT>(charT(','))); \n      char_set.add_single(digraph<charT>(charT('#'))); \n      break;\n   case '<':\n      char_set.add_single(digraph<charT>(charT(';'))); \n      break;\n   case '>':\n      char_set.add_single(digraph<charT>(charT('\\n'))); \n      char_set.add_single(digraph<charT>(charT('\\f'))); \n      break;\n   default:\n      fail(regex_constants::error_ctype, m_position - m_base);\n      return false;\n   }\n   if(0 == this->append_set(char_set))\n   {\n      fail(regex_constants::error_ctype, m_position - m_base);\n      return false;\n   }\n   ++m_position;\n   return true;\n}\n\ntemplate <class charT, class traits>\nregex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()\n{\n   // we have a (?imsx-imsx) group, convert it into a set of flags:\n   regex_constants::syntax_option_type f = this->flags();\n   bool breakout = false;\n   do\n   {\n      switch(*m_position)\n      {\n      case 's':\n         f |= regex_constants::mod_s;\n         f &= ~regex_constants::no_mod_s;\n         break;\n      case 'm':\n         f &= ~regex_constants::no_mod_m;\n         break;\n      case 'i':\n         f |= regex_constants::icase;\n         break;\n      case 'x':\n         f |= regex_constants::mod_x;\n         break;\n      default:\n         breakout = true;\n         continue;\n      }\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_paren, m_position - m_base);\n         return false;\n      }\n   }\n   while(!breakout);\n   \n   breakout = false;\n\n   if(*m_position == static_cast<charT>('-'))\n   {\n      if(++m_position == m_end)\n      {\n         // Rewind to start of (? sequence:\n         --m_position;\n         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n         fail(regex_constants::error_paren, m_position - m_base);\n         return false;\n      }\n      do\n      {\n         switch(*m_position)\n         {\n         case 's':\n            f &= ~regex_constants::mod_s;\n            f |= regex_constants::no_mod_s;\n            break;\n         case 'm':\n            f |= regex_constants::no_mod_m;\n            break;\n         case 'i':\n            f &= ~regex_constants::icase;\n            break;\n         case 'x':\n            f &= ~regex_constants::mod_x;\n            break;\n         default:\n            breakout = true;\n            continue;\n         }\n         if(++m_position == m_end)\n         {\n            // Rewind to start of (? sequence:\n            --m_position;\n            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;\n            fail(regex_constants::error_paren, m_position - m_base);\n            return false;\n         }\n      }\n      while(!breakout);\n   }\n   return f;\n}\n\ntemplate <class charT, class traits>\nbool basic_regex_parser<charT, traits>::unwind_alts(std::ptrdiff_t last_paren_start)\n{\n   //\n   // If we didn't actually add any states after the last \n   // alternative then that's an error:\n   //\n   if((this->m_alt_insert_point == static_cast<std::ptrdiff_t>(this->m_pdata->m_data.size()))\n      && (!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start)\n      &&\n      !(\n         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)\n           &&\n         ((this->flags() & regbase::no_empty_expressions) == 0)\n        )\n      )\n   {\n      fail(regex_constants::error_empty, this->m_position - this->m_base, \"Can't terminate a sub-expression with an alternation operator |.\");\n      return false;\n   }\n   // \n   // Fix up our alternatives:\n   //\n   while((!m_alt_jumps.empty()) && (m_alt_jumps.back() > last_paren_start))\n   {\n      //\n      // fix up the jump to point to the end of the states\n      // that we've just added:\n      //\n      std::ptrdiff_t jump_offset = m_alt_jumps.back();\n      m_alt_jumps.pop_back();\n      this->m_pdata->m_data.align();\n      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));\n      if (jmp->type != syntax_element_jump)\n      {\n         // Something really bad happened, this used to be an assert, \n         // but we'll make it an error just in case we should ever get here.\n         fail(regex_constants::error_unknown, this->m_position - this->m_base, \"Internal logic failed while compiling the expression, probably you added a repeat to something non-repeatable!\");\n         return false;\n      }\n      jmp->alt.i = this->m_pdata->m_data.size() - jump_offset;\n   }\n   return true;\n}\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/c_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         c_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class that wraps the global C locale.\n  */\n\n#ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_C_REGEX_TRAITS_HPP_INCLUDED\n\n#include <boost/regex/config.hpp>\n#include <boost/regex/v5/regex_workaround.hpp>\n#include <cctype>\n\nnamespace boost{\n\n   namespace BOOST_REGEX_DETAIL_NS {\n\n      enum\n      {\n         char_class_space = 1 << 0,\n         char_class_print = 1 << 1,\n         char_class_cntrl = 1 << 2,\n         char_class_upper = 1 << 3,\n         char_class_lower = 1 << 4,\n         char_class_alpha = 1 << 5,\n         char_class_digit = 1 << 6,\n         char_class_punct = 1 << 7,\n         char_class_xdigit = 1 << 8,\n         char_class_alnum = char_class_alpha | char_class_digit,\n         char_class_graph = char_class_alnum | char_class_punct,\n         char_class_blank = 1 << 9,\n         char_class_word = 1 << 10,\n         char_class_unicode = 1 << 11,\n         char_class_horizontal = 1 << 12,\n         char_class_vertical = 1 << 13\n      };\n\n   }\n\ntemplate <class charT>\nstruct c_regex_traits;\n\ntemplate<>\nstruct c_regex_traits<char>\n{\n   c_regex_traits(){}\n   typedef char char_type;\n   typedef std::size_t size_type;\n   typedef std::string string_type;\n   struct locale_type{};\n   typedef std::uint32_t char_class_type;\n\n   static size_type length(const char_type* p) \n   { \n      return (std::strlen)(p); \n   }\n\n   char translate(char c) const \n   { \n      return c; \n   }\n   char translate_nocase(char c) const \n   { \n      return static_cast<char>((std::tolower)(static_cast<unsigned char>(c))); \n   }\n\n   static string_type  transform(const char* p1, const char* p2);\n   static string_type  transform_primary(const char* p1, const char* p2);\n\n   static char_class_type  lookup_classname(const char* p1, const char* p2);\n   static string_type  lookup_collatename(const char* p1, const char* p2);\n\n   static bool  isctype(char, char_class_type);\n   static int  value(char, int);\n\n   locale_type imbue(locale_type l)\n   { return l; }\n   locale_type getloc()const\n   { return locale_type(); }\n\nprivate:\n   // this type is not copyable:\n   c_regex_traits(const c_regex_traits&);\n   c_regex_traits& operator=(const c_regex_traits&);\n};\n\n#ifndef BOOST_NO_WREGEX\ntemplate<>\nstruct c_regex_traits<wchar_t>\n{\n   c_regex_traits(){}\n   typedef wchar_t char_type;\n   typedef std::size_t size_type;\n   typedef std::wstring string_type;\n   struct locale_type{};\n   typedef std::uint32_t char_class_type;\n\n   static size_type length(const char_type* p) \n   { \n      return (std::wcslen)(p); \n   }\n\n   wchar_t translate(wchar_t c) const \n   { \n      return c; \n   }\n   wchar_t translate_nocase(wchar_t c) const \n   { \n      return (std::towlower)(c); \n   }\n\n   static string_type  transform(const wchar_t* p1, const wchar_t* p2);\n   static string_type  transform_primary(const wchar_t* p1, const wchar_t* p2);\n\n   static char_class_type  lookup_classname(const wchar_t* p1, const wchar_t* p2);\n   static string_type  lookup_collatename(const wchar_t* p1, const wchar_t* p2);\n\n   static bool  isctype(wchar_t, char_class_type);\n   static int  value(wchar_t, int);\n\n   locale_type imbue(locale_type l)\n   { return l; }\n   locale_type getloc()const\n   { return locale_type(); }\n\nprivate:\n   // this type is not copyable:\n   c_regex_traits(const c_regex_traits&);\n   c_regex_traits& operator=(const c_regex_traits&);\n};\n\n#endif // BOOST_NO_WREGEX\n\ninline c_regex_traits<char>::string_type  c_regex_traits<char>::transform(const char* p1, const char* p2)\n{\n   std::string result(10, ' ');\n   std::size_t s = result.size();\n   std::size_t r;\n   std::string src(p1, p2);\n   while (s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))\n   {\n#if defined(_CPPLIB_VER)\n      //\n      // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n      // to std::strxfrm, but only for certain locales :-(\n      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n      //\n      if (r == INT_MAX)\n      {\n         result.erase();\n         result.insert(result.begin(), static_cast<char>(0));\n         return result;\n      }\n#endif\n      result.append(r - s + 3, ' ');\n      s = result.size();\n   }\n   result.erase(r);\n   return result;\n}\n\ninline c_regex_traits<char>::string_type  c_regex_traits<char>::transform_primary(const char* p1, const char* p2)\n{\n   static char s_delim;\n   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);\n   std::string result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch (s_collate_type)\n   {\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n   {\n      result.assign(p1, p2);\n      for (std::string::size_type i = 0; i < result.size(); ++i)\n         result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));\n      result = transform(&*result.begin(), &*result.begin() + result.size());\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:\n   {\n      // get a regular sort key, and then truncate it:\n      result = transform(p1, p2);\n      result.erase(s_delim);\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:\n      // get a regular sort key, and then truncate everything after the delim:\n      result = transform(p1, p2);\n      if ((!result.empty()) && (result[0] == s_delim))\n         break;\n      std::size_t i;\n      for (i = 0; i < result.size(); ++i)\n      {\n         if (result[i] == s_delim)\n            break;\n      }\n      result.erase(i);\n      break;\n   }\n   if (result.empty())\n      result = std::string(1, char(0));\n   return result;\n}\n\ninline c_regex_traits<char>::char_class_type  c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   static const char_class_type masks[] =\n   {\n      0,\n      char_class_alnum,\n      char_class_alpha,\n      char_class_blank,\n      char_class_cntrl,\n      char_class_digit,\n      char_class_digit,\n      char_class_graph,\n      char_class_horizontal,\n      char_class_lower,\n      char_class_lower,\n      char_class_print,\n      char_class_punct,\n      char_class_space,\n      char_class_space,\n      char_class_upper,\n      char_class_unicode,\n      char_class_upper,\n      char_class_vertical,\n      char_class_alnum | char_class_word,\n      char_class_alnum | char_class_word,\n      char_class_xdigit,\n   };\n\n   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if (idx < 0)\n   {\n      std::string s(p1, p2);\n      for (std::string::size_type i = 0; i < s.size(); ++i)\n         s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));\n      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n   }\n   BOOST_REGEX_ASSERT(std::size_t(idx) + 1u < sizeof(masks) / sizeof(masks[0]));\n   return masks[idx + 1];\n}\n\ninline bool  c_regex_traits<char>::isctype(char c, char_class_type mask)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   return\n      ((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))\n      || ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))\n      || ((mask & char_class_word) && (c == '_'))\n      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n      || ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != '\\v'));\n}\n\ninline c_regex_traits<char>::string_type  c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)\n{\n   std::string s(p1, p2);\n   s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);\n   if (s.empty() && (p2 - p1 == 1))\n      s.append(1, *p1);\n   return s;\n}\n\ninline int  c_regex_traits<char>::value(char c, int radix)\n{\n   char b[2] = { c, '\\0', };\n   char* ep;\n   int result = std::strtol(b, &ep, radix);\n   if (ep == b)\n      return -1;\n   return result;\n}\n\n#ifndef BOOST_NO_WREGEX\n\ninline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::transform(const wchar_t* p1, const wchar_t* p2)\n{\n   std::size_t r;\n   std::size_t s = 10;\n   std::wstring src(p1, p2);\n   std::wstring result(s, L' ');\n   while (s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s)))\n   {\n#if defined(_CPPLIB_VER)\n      //\n      // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n      // to std::strxfrm, but only for certain locales :-(\n      // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n      //\n      if (r == INT_MAX)\n      {\n         result.erase();\n         result.insert(result.begin(), static_cast<wchar_t>(0));\n         return result;\n      }\n#endif\n      result.append(r - s + 3, L' ');\n      s = result.size();\n   }\n   result.erase(r);\n   return result;\n}\n\ninline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::transform_primary(const wchar_t* p1, const wchar_t* p2)\n{\n   static wchar_t s_delim;\n   static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<const c_regex_traits<wchar_t>*>(0), &s_delim);\n   std::wstring result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch (s_collate_type)\n   {\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n   {\n      result.assign(p1, p2);\n      for (std::wstring::size_type i = 0; i < result.size(); ++i)\n         result[i] = (std::towlower)(result[i]);\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:\n   {\n      // get a regular sort key, and then truncate it:\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      result.erase(s_delim);\n      break;\n   }\n   case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:\n      // get a regular sort key, and then truncate everything after the delim:\n      result = c_regex_traits<wchar_t>::transform(&*result.begin(), &*result.begin() + result.size());\n      if ((!result.empty()) && (result[0] == s_delim))\n         break;\n      std::size_t i;\n      for (i = 0; i < result.size(); ++i)\n      {\n         if (result[i] == s_delim)\n            break;\n      }\n      result.erase(i);\n      break;\n   }\n   if (result.empty())\n      result = std::wstring(1, char(0));\n   return result;\n}\n\ninline c_regex_traits<wchar_t>::char_class_type  c_regex_traits<wchar_t>::lookup_classname(const wchar_t* p1, const wchar_t* p2)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   static const char_class_type masks[] =\n   {\n      0,\n      char_class_alnum,\n      char_class_alpha,\n      char_class_blank,\n      char_class_cntrl,\n      char_class_digit,\n      char_class_digit,\n      char_class_graph,\n      char_class_horizontal,\n      char_class_lower,\n      char_class_lower,\n      char_class_print,\n      char_class_punct,\n      char_class_space,\n      char_class_space,\n      char_class_upper,\n      char_class_unicode,\n      char_class_upper,\n      char_class_vertical,\n      char_class_alnum | char_class_word,\n      char_class_alnum | char_class_word,\n      char_class_xdigit,\n   };\n\n   int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if (idx < 0)\n   {\n      std::wstring s(p1, p2);\n      for (std::wstring::size_type i = 0; i < s.size(); ++i)\n         s[i] = (std::towlower)(s[i]);\n      idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n   }\n   BOOST_REGEX_ASSERT(idx + 1 < static_cast<int>(sizeof(masks) / sizeof(masks[0])));\n   return masks[idx + 1];\n}\n\ninline bool  c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_type mask)\n{\n   using namespace BOOST_REGEX_DETAIL_NS;\n   return\n      ((mask & char_class_space) && (std::iswspace)(c))\n      || ((mask & char_class_print) && (std::iswprint)(c))\n      || ((mask & char_class_cntrl) && (std::iswcntrl)(c))\n      || ((mask & char_class_upper) && (std::iswupper)(c))\n      || ((mask & char_class_lower) && (std::iswlower)(c))\n      || ((mask & char_class_alpha) && (std::iswalpha)(c))\n      || ((mask & char_class_digit) && (std::iswdigit)(c))\n      || ((mask & char_class_punct) && (std::iswpunct)(c))\n      || ((mask & char_class_xdigit) && (std::iswxdigit)(c))\n      || ((mask & char_class_blank) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))\n      || ((mask & char_class_word) && (c == '_'))\n      || ((mask & char_class_unicode) && (c & ~static_cast<wchar_t>(0xff)))\n      || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == L'\\v')))\n      || ((mask & char_class_horizontal) && (std::iswspace)(c) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != L'\\v'));\n}\n\ninline c_regex_traits<wchar_t>::string_type  c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2)\n{\n   std::string name;\n   // Usual msvc warning suppression does not work here with std::string template constructor.... use a workaround instead:\n   for (const wchar_t* pos = p1; pos != p2; ++pos)\n      name.push_back((char)*pos);\n   name = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(name);\n   if (!name.empty())\n      return string_type(name.begin(), name.end());\n   if (p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ninline int  c_regex_traits<wchar_t>::value(wchar_t c, int radix)\n{\n#ifdef BOOST_BORLANDC\n   // workaround for broken wcstol:\n   if ((std::iswxdigit)(c) == 0)\n      return -1;\n#endif\n   wchar_t b[2] = { c, '\\0', };\n   wchar_t* ep;\n   int result = std::wcstol(b, &ep, radix);\n   if (ep == b)\n      return -1;\n   return result;\n}\n\n#endif\n\n}\n\n#endif\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/char_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         char_regex_traits.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.\n  */\n\n\n#ifndef BOOST_REGEX_V5_CHAR_REGEX_TRAITS_HPP\n#define BOOST_REGEX_V5_CHAR_REGEX_TRAITS_HPP\n\nnamespace boost{\n\nnamespace deprecated{\n//\n// class char_regex_traits_i\n// provides case insensitive traits classes (deprecated):\ntemplate <class charT>\nclass char_regex_traits_i : public regex_traits<charT> {};\n\ntemplate<>\nclass char_regex_traits_i<char> : public regex_traits<char>\n{\npublic:\n   typedef char char_type;\n   typedef unsigned char uchar_type;\n   typedef unsigned int size_type;\n   typedef regex_traits<char> base_type;\n\n};\n\n#ifndef BOOST_NO_WREGEX\ntemplate<>\nclass char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>\n{\npublic:\n   typedef wchar_t char_type;\n   typedef unsigned short uchar_type;\n   typedef unsigned int size_type;\n   typedef regex_traits<wchar_t> base_type;\n\n};\n#endif\n} // namespace deprecated\n} // namespace boost\n\n#endif // include\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/cpp_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004 John Maddock\n * Copyright 2011 Garmin Ltd. or its subsidiaries\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         cpp_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class cpp_regex_traits.\n  */\n\n#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED\n\n#include <boost/regex/config.hpp>\n#include <cstdint>\n#include <locale>\n#include <type_traits>\n\n#include <boost/regex/pattern_except.hpp>\n#include <boost/regex/v5/regex_traits_defaults.hpp>\n\n#ifdef BOOST_HAS_THREADS\n#include <mutex>\n#endif\n#include <boost/regex/v5/primary_transform.hpp>\n#include <boost/regex/v5/object_cache.hpp>\n\n#include <climits>\n#include <ios>\n#include <istream>\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4786 4251)\n#endif\n\nnamespace boost{ \n\n//\n// forward declaration is needed by some compilers:\n//\ntemplate <class charT>\nclass cpp_regex_traits;\n   \nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// class parser_buf:\n// acts as a stream buffer which wraps around a pair of pointers:\n//\ntemplate <class charT,\n          class traits = ::std::char_traits<charT> >\nclass parser_buf : public ::std::basic_streambuf<charT, traits>\n{\n   typedef ::std::basic_streambuf<charT, traits> base_type;\n   typedef typename base_type::int_type int_type;\n   typedef typename base_type::char_type char_type;\n   typedef typename base_type::pos_type pos_type;\n   typedef ::std::streamsize streamsize;\n   typedef typename base_type::off_type off_type;\npublic:\n   parser_buf() : base_type() { setbuf(0, 0); }\n   const charT* getnext() { return this->gptr(); }\nprotected:\n   std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n) override;\n   typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) override;\n   typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) override;\nprivate:\n   parser_buf& operator=(const parser_buf&);\n   parser_buf(const parser_buf&);\n};\n\ntemplate<class charT, class traits>\nstd::basic_streambuf<charT, traits>*\nparser_buf<charT, traits>::setbuf(char_type* s, streamsize n)\n{\n   this->setg(s, s, s + n);\n   return this;\n}\n\ntemplate<class charT, class traits>\ntypename parser_buf<charT, traits>::pos_type\nparser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)\n{\n   if(which & ::std::ios_base::out)\n      return pos_type(off_type(-1));\n   std::ptrdiff_t size = this->egptr() - this->eback();\n   std::ptrdiff_t pos = this->gptr() - this->eback();\n   charT* g = this->eback();\n   switch(static_cast<std::intmax_t>(way))\n   {\n   case ::std::ios_base::beg:\n      if((off < 0) || (off > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + off, g + size);\n      break;\n   case ::std::ios_base::end:\n      if((off < 0) || (off > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + size - off, g + size);\n      break;\n   case ::std::ios_base::cur:\n   {\n      std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);\n      if((newpos < 0) || (newpos > size))\n         return pos_type(off_type(-1));\n      else\n         this->setg(g, g + newpos, g + size);\n      break;\n   }\n   default: ;\n   }\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n   return static_cast<pos_type>(this->gptr() - this->eback());\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate<class charT, class traits>\ntypename parser_buf<charT, traits>::pos_type\nparser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)\n{\n   if(which & ::std::ios_base::out)\n      return pos_type(off_type(-1));\n   off_type size = static_cast<off_type>(this->egptr() - this->eback());\n   charT* g = this->eback();\n   if(off_type(sp) <= size)\n   {\n      this->setg(g, g + off_type(sp), g + size);\n   }\n   return pos_type(off_type(-1));\n}\n\n//\n// class cpp_regex_traits_base:\n// acts as a container for locale and the facets we are using.\n//\ntemplate <class charT>\nstruct cpp_regex_traits_base\n{\n   cpp_regex_traits_base(const std::locale& l)\n   { (void)imbue(l); }\n   std::locale imbue(const std::locale& l);\n\n   std::locale m_locale;\n   std::ctype<charT> const* m_pctype;\n   std::messages<charT> const* m_pmessages;\n   std::collate<charT> const* m_pcollate;\n\n   bool operator<(const cpp_regex_traits_base& b)const\n   {\n      if(m_pctype == b.m_pctype)\n      {\n         if(m_pmessages == b.m_pmessages)\n         {\n            return m_pcollate < b.m_pcollate;\n         }\n         return m_pmessages < b.m_pmessages;\n      }\n      return m_pctype < b.m_pctype;\n   }\n   bool operator==(const cpp_regex_traits_base& b)const\n   {\n      return (m_pctype == b.m_pctype) \n         && (m_pmessages == b.m_pmessages) \n         && (m_pcollate == b.m_pcollate);\n   }\n};\n\ntemplate <class charT>\nstd::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)\n{\n   std::locale result(m_locale);\n   m_locale = l;\n   m_pctype = &std::use_facet<std::ctype<charT>>(l);\n   m_pmessages = std::has_facet<std::messages<charT> >(l) ? &std::use_facet<std::messages<charT> >(l) : 0;\n   m_pcollate = &std::use_facet<std::collate<charT> >(l);\n   return result;\n}\n\n//\n// class cpp_regex_traits_char_layer:\n// implements methods that require specialization for narrow characters:\n//\ntemplate <class charT>\nclass cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>\n{\n   typedef std::basic_string<charT> string_type;\n   typedef std::map<charT, regex_constants::syntax_type> map_type;\n   typedef typename map_type::const_iterator map_iterator_type;\npublic:\n   cpp_regex_traits_char_layer(const std::locale& l)\n      : cpp_regex_traits_base<charT>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)\n      : cpp_regex_traits_base<charT>(b)\n   {\n      init();\n   }\n   void init();\n\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      return ((i == m_char_map.end()) ? 0 : i->second);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      if(i == m_char_map.end())\n      {\n         if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;\n         if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;\n         return 0;\n      }\n      return i->second;\n   }\n\nprivate:\n   string_type get_default_message(regex_constants::syntax_type);\n   // TODO: use a hash table when available!\n   map_type m_char_map;\n};\n\ntemplate <class charT>\nvoid cpp_regex_traits_char_layer<charT>::init()\n{\n   // we need to start by initialising our syntax map so we know which\n   // character is used for which purpose:\n#ifndef __IBMCPP__\n   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());\n   if((!cat_name.empty()) && (this->m_pmessages != 0))\n   {\n      cat = this->m_pmessages->open(\n         cat_name, \n         this->m_locale);\n      if((int)cat < 0)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if((int)cat >= 0)\n   {\n#ifndef BOOST_NO_EXCEPTIONS\n      try{\n#endif\n         for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));\n            for(typename string_type::size_type j = 0; j < mss.size(); ++j)\n            {\n               m_char_map[mss[j]] = i;\n            }\n         }\n         this->m_pmessages->close(cat);\n#ifndef BOOST_NO_EXCEPTIONS\n      }\n      catch(...)\n      {\n         if(this->m_pmessages)\n            this->m_pmessages->close(cat);\n         throw;\n      }\n#endif\n   }\n   else\n   {\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         const char* ptr = get_default_syntax(i);\n         while(ptr && *ptr)\n         {\n            m_char_map[this->m_pctype->widen(*ptr)] = i;\n            ++ptr;\n         }\n      }\n   }\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_char_layer<charT>::string_type \n   cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)\n{\n   const char* ptr = get_default_syntax(i);\n   string_type result;\n   while(ptr && *ptr)\n   {\n      result.append(1, this->m_pctype->widen(*ptr));\n      ++ptr;\n   }\n   return result;\n}\n\n//\n// specialized version for narrow characters:\n//\ntemplate <>\nclass cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>\n{\n   typedef std::string string_type;\npublic:\n   cpp_regex_traits_char_layer(const std::locale& l)\n   : cpp_regex_traits_base<char>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)\n   : cpp_regex_traits_base<char>(l)\n   {\n      init();\n   }\n\n   regex_constants::syntax_type syntax_type(char c)const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(char c) const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n\nprivate:\n   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];\n   void init();\n};\n\n//\n// class cpp_regex_traits_implementation:\n// provides pimpl implementation for cpp_regex_traits.\n//\ntemplate <class charT>\nclass cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>\n{\npublic:\n   typedef typename cpp_regex_traits<charT>::char_class_type      char_class_type;\n   typedef typename std::ctype<charT>::mask                       native_mask_type;\n   typedef typename std::make_unsigned<native_mask_type>::type    unsigned_native_mask_type;\n   static const char_class_type mask_blank = 1u << 24;\n   static const char_class_type mask_word = 1u << 25;\n   static const char_class_type mask_unicode = 1u << 26;\n   static const char_class_type mask_horizontal = 1u << 27;\n   static const char_class_type mask_vertical = 1u << 28;\n\n   typedef std::basic_string<charT> string_type;\n   typedef charT char_type;\n   //cpp_regex_traits_implementation();\n   cpp_regex_traits_implementation(const std::locale& l)\n      : cpp_regex_traits_char_layer<charT>(l)\n   {\n      init();\n   }\n   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)\n      : cpp_regex_traits_char_layer<charT>(l)\n   {\n      init();\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      if(!m_error_strings.empty())\n      {\n         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);\n         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;\n      }\n      return get_default_error_string(n);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      char_class_type result = lookup_classname_imp(p1, p2);\n      if(result == 0)\n      {\n         string_type temp(p1, p2);\n         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());\n         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());\n      }\n      return result;\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const;\n   string_type transform_primary(const charT* p1, const charT* p2) const;\n   string_type transform(const charT* p1, const charT* p2) const;\nprivate:\n   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID\n   std::map<string_type, char_class_type>  m_custom_class_names; // character class names\n   std::map<string_type, string_type>      m_custom_collate_names; // collating element names\n   unsigned                       m_collate_type;    // the form of the collation string\n   charT                          m_collate_delim;   // the collation group delimiter\n   //\n   // helpers:\n   //\n   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;\n   void init();\n};\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const\n{\n   //\n   // PRECONDITIONS:\n   //\n   // A bug in gcc 3.2 (and maybe other versions as well) treats\n   // p1 as a null terminated string, for efficiency reasons \n   // we work around this elsewhere, but just assert here that\n   // we adhere to gcc's (buggy) preconditions...\n   //\n   BOOST_REGEX_ASSERT(*p2 == 0);\n   string_type result;\n#if defined(_CPPLIB_VER)\n   //\n   // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n   // to std::collate::transform, but only for certain locales :-(\n   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n   //\n   if(*p1 == 0)\n   {\n      return string_type(1, charT(0));\n   }\n#endif\n   //\n   // swallowing all exceptions here is a bad idea\n   // however at least one std lib will always throw\n   // std::bad_alloc for certain arguments...\n   //\n#ifndef BOOST_NO_EXCEPTIONS\n   try{\n#endif\n      //\n      // What we do here depends upon the format of the sort key returned by\n      // sort key returned by this->transform:\n      //\n      switch(m_collate_type)\n      {\n      case sort_C:\n      case sort_unknown:\n         // the best we can do is translate to lower case, then get a regular sort key:\n         {\n            result.assign(p1, p2);\n            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());\n            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());\n            break;\n         }\n      case sort_fixed:\n         {\n            // get a regular sort key, and then truncate it:\n            result.assign(this->m_pcollate->transform(p1, p2));\n            result.erase(this->m_collate_delim);\n            break;\n         }\n      case sort_delim:\n            // get a regular sort key, and then truncate everything after the delim:\n            result.assign(this->m_pcollate->transform(p1, p2));\n            std::size_t i;\n            for(i = 0; i < result.size(); ++i)\n            {\n               if(result[i] == m_collate_delim)\n                  break;\n            }\n            result.erase(i);\n            break;\n      }\n#ifndef BOOST_NO_EXCEPTIONS\n   }catch(...){}\n#endif\n   while((!result.empty()) && (charT(0) == *result.rbegin()))\n      result.erase(result.size() - 1);\n   if(result.empty())\n   {\n      // character is ignorable at the primary level:\n      result = string_type(1, charT(0));\n   }\n   return result;\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const\n{\n   //\n   // PRECONDITIONS:\n   //\n   // A bug in gcc 3.2 (and maybe other versions as well) treats\n   // p1 as a null terminated string, for efficiency reasons \n   // we work around this elsewhere, but just assert here that\n   // we adhere to gcc's (buggy) preconditions...\n   //\n   BOOST_REGEX_ASSERT(*p2 == 0);\n   //\n   // swallowing all exceptions here is a bad idea\n   // however at least one std lib will always throw\n   // std::bad_alloc for certain arguments...\n   //\n   string_type result, result2;\n#if defined(_CPPLIB_VER)\n   //\n   // A bug in VC11 and 12 causes the program to hang if we pass a null-string\n   // to std::collate::transform, but only for certain locales :-(\n   // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).\n   //\n   if(*p1 == 0)\n   {\n      return result;\n   }\n#endif\n#ifndef BOOST_NO_EXCEPTIONS\n   try{\n#endif\n      result = this->m_pcollate->transform(p1, p2);\n      //\n      // some implementations (Dinkumware) append unnecessary trailing \\0's:\n      while((!result.empty()) && (charT(0) == *result.rbegin()))\n         result.erase(result.size() - 1);\n      //\n      // We may have NULL's used as separators between sections of the collate string,\n      // an example would be Boost.Locale.  We have no way to detect this case via\n      // #defines since this can be used with any compiler/platform combination.\n      // Unfortunately our state machine (which was devised when all implementations\n      // used underlying C language API's) can't cope with that case.  One workaround\n      // is to replace each character with 2, fortunately this code isn't used that\n      // much as this is now slower than before :-(\n      //\n      typedef typename std::make_unsigned<charT>::type uchar_type;\n      result2.reserve(result.size() * 2 + 2);\n      for(unsigned i = 0; i < result.size(); ++i)\n      {\n         if(static_cast<uchar_type>(result[i]) == (std::numeric_limits<uchar_type>::max)())\n         {\n            result2.append(1, charT((std::numeric_limits<uchar_type>::max)())).append(1, charT('b'));\n         }\n         else\n         {\n            result2.append(1, static_cast<charT>(1 + static_cast<uchar_type>(result[i]))).append(1, charT('b') - 1);\n         }\n      }\n      BOOST_REGEX_ASSERT(std::find(result2.begin(), result2.end(), charT(0)) == result2.end());\n#ifndef BOOST_NO_EXCEPTIONS\n   }\n   catch(...)\n   {\n   }\n#endif\n   return result2;\n}\n\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::string_type \n   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const\n{\n   typedef typename std::map<string_type, string_type>::const_iterator iter_type;\n   if(!m_custom_collate_names.empty())\n   {\n      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));\n      if(pos != m_custom_collate_names.end())\n         return pos->second;\n   }\n   std::string name(p1, p2);\n   name = lookup_default_collate_name(name);\n   if(!name.empty())\n      return string_type(name.begin(), name.end());\n   if(p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ntemplate <class charT>\nvoid cpp_regex_traits_implementation<charT>::init()\n{\n#ifndef __IBMCPP__\n   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());\n   if((!cat_name.empty()) && (this->m_pmessages != 0))\n   {\n      cat = this->m_pmessages->open(\n         cat_name, \n         this->m_locale);\n      if((int)cat < 0)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if((int)cat >= 0)\n   {\n      //\n      // Error messages:\n      //\n      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); \n         i <= boost::regex_constants::error_unknown; \n         i = static_cast<boost::regex_constants::error_type>(i + 1))\n      {\n         const char* p = get_default_error_string(i);\n         string_type default_message;\n         while(*p)\n         {\n            default_message.append(1, this->m_pctype->widen(*p));\n            ++p;\n         }\n         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);\n         std::string result;\n         for(std::string::size_type j = 0; j < s.size(); ++j)\n         {\n            result.append(1, this->m_pctype->narrow(s[j], 0));\n         }\n         m_error_strings[i] = result;\n      }\n      //\n      // Custom class names:\n      //\n      static const char_class_type masks[16] = \n      {\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alnum),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::alpha),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::cntrl),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::digit),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::graph),\n         cpp_regex_traits_implementation<charT>::mask_horizontal,\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::lower),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::print),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::punct),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::space),\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::upper),\n         cpp_regex_traits_implementation<charT>::mask_vertical,\n         static_cast<unsigned_native_mask_type>(std::ctype<charT>::xdigit),\n         cpp_regex_traits_implementation<charT>::mask_blank,\n         cpp_regex_traits_implementation<charT>::mask_word,\n         cpp_regex_traits_implementation<charT>::mask_unicode,\n      };\n      static const string_type null_string;\n      for(unsigned int j = 0; j <= 13; ++j)\n      {\n         string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));\n         if(!s.empty())\n            this->m_custom_class_names[s] = masks[j];\n      }\n   }\n   //\n   // get the collation format used by m_pcollate:\n   //\n   m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);\n}\n\ntemplate <class charT>\ntypename cpp_regex_traits_implementation<charT>::char_class_type \n   cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const\n{\n   static const char_class_type masks[22] = \n   {\n      0,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alpha),\n      cpp_regex_traits_implementation<charT>::mask_blank,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::cntrl),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::digit),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::graph),\n      cpp_regex_traits_implementation<charT>::mask_horizontal,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::lower),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::print),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::punct),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::space),\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),\n      cpp_regex_traits_implementation<charT>::mask_unicode,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::upper),\n      cpp_regex_traits_implementation<charT>::mask_vertical,\n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, \n      static_cast<unsigned_native_mask_type>(std::ctype<char>::alnum) | cpp_regex_traits_implementation<charT>::mask_word, \n      static_cast<unsigned_native_mask_type>(std::ctype<char>::xdigit),\n   };\n   if(!m_custom_class_names.empty())\n   {\n      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;\n      map_iter pos = m_custom_class_names.find(string_type(p1, p2));\n      if(pos != m_custom_class_names.end())\n         return pos->second;\n   }\n   std::size_t state_id = 1 + BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   BOOST_REGEX_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));\n   return masks[state_id];\n}\n\ntemplate <class charT>\ninline std::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)\n{\n   cpp_regex_traits_base<charT> key(l);\n   return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);\n}\n\n} // BOOST_REGEX_DETAIL_NS\n\ntemplate <class charT>\nclass cpp_regex_traits\n{\nprivate:\n   typedef std::ctype<charT>            ctype_type;\npublic:\n   typedef charT                        char_type;\n   typedef std::size_t                  size_type;\n   typedef std::basic_string<char_type> string_type;\n   typedef std::locale                  locale_type;\n   typedef std::uint_least32_t          char_class_type;\n\n   struct boost_extensions_tag{};\n\n   cpp_regex_traits()\n      : m_pimpl(BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(std::locale()))\n   { }\n   static size_type length(const char_type* p)\n   {\n      return std::char_traits<charT>::length(p);\n   }\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      return m_pimpl->syntax_type(c);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      return m_pimpl->escape_syntax_type(c);\n   }\n   charT translate(charT c) const\n   {\n      return c;\n   }\n   charT translate_nocase(charT c) const\n   {\n      return m_pimpl->m_pctype->tolower(c);\n   }\n   charT translate(charT c, bool icase) const\n   {\n      return icase ? m_pimpl->m_pctype->tolower(c) : c;\n   }\n   charT tolower(charT c) const\n   {\n      return m_pimpl->m_pctype->tolower(c);\n   }\n   charT toupper(charT c) const\n   {\n      return m_pimpl->m_pctype->toupper(c);\n   }\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform(p1, p2);\n   }\n   string_type transform_primary(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform_primary(p1, p2);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_classname(p1, p2);\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_collatename(p1, p2);\n   }\n   bool isctype(charT c, char_class_type f) const\n   {\n      typedef typename std::ctype<charT>::mask ctype_mask;\n\n      static const ctype_mask mask_base = \n         static_cast<ctype_mask>(\n            std::ctype<charT>::alnum \n            | std::ctype<charT>::alpha\n            | std::ctype<charT>::cntrl\n            | std::ctype<charT>::digit\n            | std::ctype<charT>::graph\n            | std::ctype<charT>::lower\n            | std::ctype<charT>::print\n            | std::ctype<charT>::punct\n            | std::ctype<charT>::space\n            | std::ctype<charT>::upper\n            | std::ctype<charT>::xdigit);\n\n      if((f & mask_base) \n         && (m_pimpl->m_pctype->is(\n            static_cast<ctype_mask>(f & mask_base), c)))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_blank) \n         && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)\n         && !BOOST_REGEX_DETAIL_NS::is_separator(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical) \n         && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_horizontal) \n         && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT>::mask_vertical))\n         return true;\n#ifdef __CYGWIN__\n      //\n      // Cygwin has a buggy ctype facet, see https://www.cygwin.com/ml/cygwin/2012-08/msg00178.html:\n      //\n      else if((f & std::ctype<charT>::xdigit) == std::ctype<charT>::xdigit)\n      {\n         if((c >= 'a') && (c <= 'f'))\n            return true;\n         if((c >= 'A') && (c <= 'F'))\n            return true;\n      }\n#endif\n      return false;\n   }\n   std::intmax_t toi(const charT*& p1, const charT* p2, int radix)const;\n   int value(charT c, int radix)const\n   {\n      const charT* pc = &c;\n      return (int)toi(pc, pc + 1, radix);\n   }\n   locale_type imbue(locale_type l)\n   {\n      std::locale result(getloc());\n      m_pimpl = BOOST_REGEX_DETAIL_NS::create_cpp_regex_traits<charT>(l);\n      return result;\n   }\n   locale_type getloc()const\n   {\n      return m_pimpl->m_locale;\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      return m_pimpl->error_string(n);\n   }\n\n   //\n   // extension:\n   // set the name of the message catalog in use (defaults to \"boost_regex\").\n   //\n   static std::string catalog_name(const std::string& name);\n   static std::string get_catalog_name();\n\nprivate:\n   std::shared_ptr<const BOOST_REGEX_DETAIL_NS::cpp_regex_traits_implementation<charT> > m_pimpl;\n   //\n   // catalog name handler:\n   //\n   static std::string& get_catalog_name_inst();\n\n#ifdef BOOST_HAS_THREADS\n   static std::mutex& get_mutex_inst();\n#endif\n};\n\n\ntemplate <class charT>\nstd::intmax_t cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const\n{\n   BOOST_REGEX_DETAIL_NS::parser_buf<charT>   sbuf;            // buffer for parsing numbers.\n   std::basic_istream<charT>      is(&sbuf);       // stream for parsing numbers.\n\n   // we do NOT want to parse any thousands separators inside the stream:\n   last = std::find(first, last, std::use_facet<std::numpunct<charT>>(is.getloc()).thousands_sep());\n\n   sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));\n   is.clear();\n   if(std::abs(radix) == 16) is >> std::hex;\n   else if(std::abs(radix) == 8) is >> std::oct;\n   else is >> std::dec;\n   std::intmax_t val;\n   if(is >> val)\n   {\n      first = first + ((last - first) - sbuf.in_avail());\n      return val;\n   }\n   else\n      return -1;\n}\n\ntemplate <class charT>\nstd::string cpp_regex_traits<charT>::catalog_name(const std::string& name)\n{\n#ifdef BOOST_HAS_THREADS\n   std::lock_guard<std::mutex> lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   get_catalog_name_inst() = name;\n   return result;\n}\n\ntemplate <class charT>\nstd::string& cpp_regex_traits<charT>::get_catalog_name_inst()\n{\n   static std::string s_name;\n   return s_name;\n}\n\ntemplate <class charT>\nstd::string cpp_regex_traits<charT>::get_catalog_name()\n{\n#ifdef BOOST_HAS_THREADS\n   std::lock_guard<std::mutex> lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   return result;\n}\n\n#ifdef BOOST_HAS_THREADS\ntemplate <class charT>\nstd::mutex& cpp_regex_traits<charT>::get_mutex_inst()\n{\n   static std::mutex s_mutex;\n   return s_mutex;\n}\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS {\n\n   inline void cpp_regex_traits_char_layer<char>::init()\n   {\n      // we need to start by initialising our syntax map so we know which\n      // character is used for which purpose:\n      std::memset(m_char_map, 0, sizeof(m_char_map));\n#ifndef __IBMCPP__\n      std::messages<char>::catalog cat = static_cast<std::messages<char>::catalog>(-1);\n#else\n      std::messages<char>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);\n#endif\n      std::string cat_name(cpp_regex_traits<char>::get_catalog_name());\n      if ((!cat_name.empty()) && (m_pmessages != 0))\n      {\n         cat = this->m_pmessages->open(\n            cat_name,\n            this->m_locale);\n         if ((int)cat < 0)\n         {\n            std::string m(\"Unable to open message catalog: \");\n            std::runtime_error err(m + cat_name);\n            boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n         }\n      }\n      //\n      // if we have a valid catalog then load our messages:\n      //\n      if ((int)cat >= 0)\n      {\n#ifndef BOOST_NO_EXCEPTIONS\n         try {\n#endif\n            for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n            {\n               string_type mss = this->m_pmessages->get(cat, 0, i, get_default_syntax(i));\n               for (string_type::size_type j = 0; j < mss.size(); ++j)\n               {\n                  m_char_map[static_cast<unsigned char>(mss[j])] = i;\n               }\n            }\n            this->m_pmessages->close(cat);\n#ifndef BOOST_NO_EXCEPTIONS\n         }\n         catch (...)\n         {\n            this->m_pmessages->close(cat);\n            throw;\n         }\n#endif\n      }\n      else\n      {\n         for (regex_constants::syntax_type j = 1; j < regex_constants::syntax_max; ++j)\n         {\n            const char* ptr = get_default_syntax(j);\n            while (ptr && *ptr)\n            {\n               m_char_map[static_cast<unsigned char>(*ptr)] = j;\n               ++ptr;\n            }\n         }\n      }\n      //\n      // finish off by calculating our escape types:\n      //\n      unsigned char i = 'A';\n      do\n      {\n         if (m_char_map[i] == 0)\n         {\n            if (this->m_pctype->is(std::ctype_base::lower, i))\n               m_char_map[i] = regex_constants::escape_type_class;\n            else if (this->m_pctype->is(std::ctype_base::upper, i))\n               m_char_map[i] = regex_constants::escape_type_not_class;\n         }\n      } while (0xFF != i++);\n   }\n\n} // namespace detail\n\n\n} // boost\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/cregex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         cregex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares POSIX API functions\n  *                + boost::RegEx high level wrapper.\n  */\n\n#ifndef BOOST_RE_CREGEX_HPP_INCLUDED\n#define BOOST_RE_CREGEX_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n#include <boost/regex/v5/match_flags.hpp>\n#include <boost/regex/v5/error_type.hpp>\n\n#ifndef BOOST_REGEX_STANDALONE\n#if !defined(BOOST_REGEX_NO_LIB) && !defined(BOOST_REGEX_SOURCE) && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus)\n#  define BOOST_LIB_NAME boost_regex\n#  if defined(BOOST_REGEX_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)\n#     define BOOST_DYN_LINK\n#  endif\n#  ifdef BOOST_REGEX_DIAG\n#     define BOOST_LIB_DIAGNOSTIC\n#  endif\n#  include <boost/config/auto_link.hpp>\n#endif\n#endif\n\n#ifdef __cplusplus\n#include <cstddef>\n#else\n#include <stddef.h>\n#endif\n\n/* include these defs only for POSIX compatablity */\n#ifdef __cplusplus\nnamespace boost{\nextern \"C\" {\n#endif\n\n#if defined(__cplusplus)\ntypedef std::ptrdiff_t regoff_t;\ntypedef std::size_t regsize_t;\n#else\ntypedef ptrdiff_t regoff_t;\ntypedef size_t regsize_t;\n#endif\n\ntypedef struct\n{\n   unsigned int re_magic;\n#ifdef __cplusplus\n   std::size_t  re_nsub;      /* number of parenthesized subexpressions */\n#else\n   size_t re_nsub; \n#endif\n   const char*  re_endp;       /* end pointer for REG_PEND */\n   void* guts;                /* none of your business :-) */\n   match_flag_type eflags;        /* none of your business :-) */\n} regex_tA;\n\n#ifndef BOOST_NO_WREGEX\ntypedef struct\n{\n   unsigned int re_magic;\n#ifdef __cplusplus\n   std::size_t  re_nsub;         /* number of parenthesized subexpressions */\n#else\n   size_t re_nsub;\n#endif\n   const wchar_t* re_endp;       /* end pointer for REG_PEND */\n   void* guts;                   /* none of your business :-) */\n   match_flag_type eflags;           /* none of your business :-) */\n} regex_tW;\n#endif\n\ntypedef struct\n{\n   regoff_t rm_so;      /* start of match */\n   regoff_t rm_eo;      /* end of match */\n} regmatch_t;\n\n/* regcomp() flags */\ntypedef enum{\n   REG_BASIC = 0000,\n   REG_EXTENDED = 0001,\n   REG_ICASE = 0002,\n   REG_NOSUB = 0004,\n   REG_NEWLINE = 0010,\n   REG_NOSPEC = 0020,\n   REG_PEND = 0040,\n   REG_DUMP = 0200,\n   REG_NOCOLLATE = 0400,\n   REG_ESCAPE_IN_LISTS = 01000,\n   REG_NEWLINE_ALT = 02000,\n   REG_PERLEX = 04000,\n\n   REG_PERL = REG_EXTENDED | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | REG_PERLEX,\n   REG_AWK = REG_EXTENDED | REG_ESCAPE_IN_LISTS,\n   REG_GREP = REG_BASIC | REG_NEWLINE_ALT,\n   REG_EGREP = REG_EXTENDED | REG_NEWLINE_ALT,\n\n   REG_ASSERT = 15,\n   REG_INVARG = 16,\n   REG_ATOI = 255,   /* convert name to number (!) */\n   REG_ITOA = 0400   /* convert number to name (!) */\n} reg_comp_flags;\n\n/* regexec() flags */\ntypedef enum{\n   REG_NOTBOL =    00001,\n   REG_NOTEOL =    00002,\n   REG_STARTEND =  00004\n} reg_exec_flags;\n\n/*\n * POSIX error codes:\n */\ntypedef unsigned reg_error_t;\ntypedef reg_error_t reg_errcode_t;  /* backwards compatibility */\n\nstatic const reg_error_t REG_NOERROR = 0;   /* Success.  */\nstatic const reg_error_t REG_NOMATCH = 1;   /* Didn't find a match (for regexec).  */\n\n  /* POSIX regcomp return error codes.  (In the order listed in the\n     standard.)  */\nstatic const reg_error_t REG_BADPAT = 2;    /* Invalid pattern.  */\nstatic const reg_error_t REG_ECOLLATE = 3;  /* Undefined collating element.  */\nstatic const reg_error_t REG_ECTYPE = 4;    /* Invalid character class name.  */\nstatic const reg_error_t REG_EESCAPE = 5;   /* Trailing backslash.  */\nstatic const reg_error_t REG_ESUBREG = 6;   /* Invalid back reference.  */\nstatic const reg_error_t REG_EBRACK = 7;    /* Unmatched left bracket.  */\nstatic const reg_error_t REG_EPAREN = 8;    /* Parenthesis imbalance.  */\nstatic const reg_error_t REG_EBRACE = 9;    /* Unmatched \\{.  */\nstatic const reg_error_t REG_BADBR = 10;    /* Invalid contents of \\{\\}.  */\nstatic const reg_error_t REG_ERANGE = 11;   /* Invalid range end.  */\nstatic const reg_error_t REG_ESPACE = 12;   /* Ran out of memory.  */\nstatic const reg_error_t REG_BADRPT = 13;   /* No preceding re for repetition op.  */\nstatic const reg_error_t REG_EEND = 14;     /* unexpected end of expression */\nstatic const reg_error_t REG_ESIZE = 15;    /* expression too big */\nstatic const reg_error_t REG_ERPAREN = 8;   /* = REG_EPAREN : unmatched right parenthesis */\nstatic const reg_error_t REG_EMPTY = 17;    /* empty expression */\nstatic const reg_error_t REG_E_MEMORY = 15; /* = REG_ESIZE : out of memory */\nstatic const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */\nstatic const reg_error_t REG_ESTACK = 19;   /* out of stack space */\nstatic const reg_error_t REG_E_PERL = 20;   /* Perl (?...) error */\nstatic const reg_error_t REG_E_UNKNOWN = 21; /* unknown error */\nstatic const reg_error_t REG_ENOSYS = 21;   /* = REG_E_UNKNOWN : Reserved. */\n\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA*, const char*, int);\nBOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int, const regex_tA*, char*, regsize_t);\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA*, const char*, regsize_t, regmatch_t*, int);\nBOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA*);\n\n#ifndef BOOST_NO_WREGEX\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW*, const wchar_t*, int);\nBOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int, const regex_tW*, wchar_t*, regsize_t);\nBOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW*, const wchar_t*, regsize_t, regmatch_t*, int);\nBOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW*);\n#endif\n\n#ifdef UNICODE\n#define regcomp regcompW\n#define regerror regerrorW\n#define regexec regexecW\n#define regfree regfreeW\n#define regex_t regex_tW\n#else\n#define regcomp regcompA\n#define regerror regerrorA\n#define regexec regexecA\n#define regfree regfreeA\n#define regex_t regex_tA\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n} /* namespace */\n#endif\n\n#endif /* include guard */\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/error_type.hpp",
    "content": "/*\n *\n * Copyright (c) 2003-2005\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         error_type.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression error type enumerator.\n  */\n\n#ifndef BOOST_REGEX_ERROR_TYPE_HPP\n#define BOOST_REGEX_ERROR_TYPE_HPP\n\n#ifdef __cplusplus\nnamespace boost{\n#endif\n\n#ifdef __cplusplus\nnamespace regex_constants{\n\nenum error_type{\n\n   error_ok = 0,         /* not used */\n   error_no_match = 1,   /* not used */\n   error_bad_pattern = 2,\n   error_collate = 3,\n   error_ctype = 4,\n   error_escape = 5,\n   error_backref = 6,\n   error_brack = 7,\n   error_paren = 8,\n   error_brace = 9,\n   error_badbrace = 10,\n   error_range = 11,\n   error_space = 12,\n   error_badrepeat = 13,\n   error_end = 14,    /* not used */\n   error_size = 15,\n   error_right_paren = 16,  /* not used */\n   error_empty = 17,\n   error_complexity = 18,\n   error_stack = 19,\n   error_perl_extension = 20,\n   error_unknown = 21\n};\n\n}\n}\n#endif /* __cplusplus */\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/icu.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         icu.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.\n  */\n\n#ifndef BOOST_REGEX_ICU_V5_HPP\n#define BOOST_REGEX_ICU_V5_HPP\n\n#include <unicode/utypes.h>\n#include <unicode/uchar.h>\n#include <unicode/coll.h>\n#include <type_traits>\n#include <functional>\n#include <boost/regex.hpp>\n#include <boost/regex/v5/unicode_iterator.hpp>\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning (push)\n#pragma warning (disable: 4251)\n#endif\n\nnamespace boost{\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\n// \n// Implementation details:\n//\nclass icu_regex_traits_implementation\n{\n   typedef UChar32                      char_type;\n   typedef std::size_t                  size_type;\n   typedef std::vector<char_type>       string_type;\n   typedef U_NAMESPACE_QUALIFIER Locale locale_type;\n   typedef std::uint_least32_t          char_class_type;\npublic:\n   icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)\n      : m_locale(l)\n   {\n      UErrorCode success = U_ZERO_ERROR;\n      m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));\n      if(U_SUCCESS(success) == 0)\n         init_error();\n      m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);\n      success = U_ZERO_ERROR;\n      m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));\n      if(U_SUCCESS(success) == 0)\n         init_error();\n      m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);\n   }\n   U_NAMESPACE_QUALIFIER Locale getloc()const\n   {\n      return m_locale;\n   }\n   string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const\n   {\n      // TODO make thread safe!!!! :\n      typedef u32_to_u16_iterator<const char_type*, ::UChar> itt;\n      itt i(p1), j(p2);\n      std::vector< ::UChar> t(i, j);\n      std::uint8_t result[100];\n      std::int32_t len;\n      if (!t.empty())\n         len = pcoll->getSortKey(&*t.begin(), static_cast<std::int32_t>(t.size()), result, sizeof(result));\n      else\n         len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast<std::int32_t>(0), result, sizeof(result));\n      if (std::size_t(len) > sizeof(result))\n      {\n         std::unique_ptr< std::uint8_t[]> presult(new ::uint8_t[len + 1]);\n         if (!t.empty())\n            len = pcoll->getSortKey(&*t.begin(), static_cast<std::int32_t>(t.size()), presult.get(), len + 1);\n         else\n            len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast<std::int32_t>(0), presult.get(), len + 1);\n         if ((0 == presult[len - 1]) && (len > 1))\n            --len;\n         return string_type(presult.get(), presult.get() + len);\n      }\n      if ((0 == result[len - 1]) && (len > 1))\n         --len;\n      return string_type(result, result + len);\n   }\n   string_type transform(const char_type* p1, const char_type* p2) const\n   {\n      return do_transform(p1, p2, m_collator.get());\n   }\n   string_type transform_primary(const char_type* p1, const char_type* p2) const\n   {\n      return do_transform(p1, p2, m_primary_collator.get());\n   }\nprivate:\n   void init_error()\n   {\n      std::runtime_error e(\"Could not initialize ICU resources\");\n#ifndef BOOST_REGEX_STANDALONE\n      boost::throw_exception(e);\n#else\n      throw e;\n#endif\n   }\n   U_NAMESPACE_QUALIFIER Locale m_locale;                                  // The ICU locale that we're using\n   std::unique_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator;          // The full collation object\n   std::unique_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator;  // The primary collation object\n};\ninline std::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)\n{\n   return std::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));\n}\n\n}\n\nclass icu_regex_traits\n{\npublic:\n   typedef UChar32                      char_type;\n   typedef std::size_t                  size_type;\n   typedef std::vector<char_type>       string_type;\n   typedef U_NAMESPACE_QUALIFIER Locale locale_type;\n   typedef std::uint64_t                char_class_type;\n\n   struct boost_extensions_tag{};\n\n   icu_regex_traits()\n      : m_pimpl(BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))\n   {\n   }\n   static size_type length(const char_type* p)\n   {\n      size_type result = 0;\n      while (*p)\n      {\n         ++p;\n         ++result;\n      }\n      return result;\n   }\n\n   ::boost::regex_constants::syntax_type syntax_type(char_type c)const\n   {\n      return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;\n   }\n   ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const\n   {\n      return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;\n   }\n   char_type translate(char_type c) const\n   {\n      return c;\n   }\n   char_type translate_nocase(char_type c) const\n   {\n      return ::u_foldCase(c, U_FOLD_CASE_DEFAULT);\n   }\n   char_type translate(char_type c, bool icase) const\n   {\n      return icase ? translate_nocase(c) : translate(c);\n   }\n   char_type tolower(char_type c) const\n   {\n      return ::u_tolower(c);\n   }\n   char_type toupper(char_type c) const\n   {\n      return ::u_toupper(c);\n   }\n   string_type transform(const char_type* p1, const char_type* p2) const\n   {\n      return m_pimpl->transform(p1, p2);\n   }\n   string_type transform_primary(const char_type* p1, const char_type* p2) const\n   {\n      return m_pimpl->transform_primary(p1, p2);\n   }\n   char_class_type lookup_classname(const char_type* p1, const char_type* p2) const\n   {\n      constexpr char_class_type mask_blank = char_class_type(1) << offset_blank;\n      constexpr char_class_type mask_space = char_class_type(1) << offset_space;\n      constexpr char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n      constexpr char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n      constexpr char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n      //constexpr char_class_type mask_any = char_class_type(1) << offset_any;\n      //constexpr char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n      constexpr char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n      constexpr char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n      static const char_class_type masks[] =\n      {\n         0,\n         U_GC_L_MASK | U_GC_ND_MASK,\n         U_GC_L_MASK,\n         mask_blank,\n         U_GC_CC_MASK | U_GC_CF_MASK | U_GC_ZL_MASK | U_GC_ZP_MASK,\n         U_GC_ND_MASK,\n         U_GC_ND_MASK,\n         (0x3FFFFFFFu) & ~(U_GC_CC_MASK | U_GC_CF_MASK | U_GC_CS_MASK | U_GC_CN_MASK | U_GC_Z_MASK),\n         mask_horizontal,\n         U_GC_LL_MASK,\n         U_GC_LL_MASK,\n         ~(U_GC_C_MASK),\n         U_GC_P_MASK,\n         char_class_type(U_GC_Z_MASK) | mask_space,\n         char_class_type(U_GC_Z_MASK) | mask_space,\n         U_GC_LU_MASK,\n         mask_unicode,\n         U_GC_LU_MASK,\n         mask_vertical,\n         char_class_type(U_GC_L_MASK | U_GC_ND_MASK | U_GC_MN_MASK) | mask_underscore,\n         char_class_type(U_GC_L_MASK | U_GC_ND_MASK | U_GC_MN_MASK) | mask_underscore,\n         char_class_type(U_GC_ND_MASK) | mask_xdigit,\n      };\n\n      int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n      if (idx >= 0)\n         return masks[idx + 1];\n      char_class_type result = lookup_icu_mask(p1, p2);\n      if (result != 0)\n         return result;\n\n      if (idx < 0)\n      {\n         string_type s(p1, p2);\n         string_type::size_type i = 0;\n         while (i < s.size())\n         {\n            s[i] = static_cast<char>((::u_tolower)(s[i]));\n            if (::u_isspace(s[i]) || (s[i] == '-') || (s[i] == '_'))\n               s.erase(s.begin() + i, s.begin() + i + 1);\n            else\n            {\n               s[i] = static_cast<char>((::u_tolower)(s[i]));\n               ++i;\n            }\n         }\n         if (!s.empty())\n            idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());\n         if (idx >= 0)\n            return masks[idx + 1];\n         if (!s.empty())\n            result = lookup_icu_mask(&*s.begin(), &*s.begin() + s.size());\n         if (result != 0)\n            return result;\n      }\n      BOOST_REGEX_ASSERT(std::size_t(idx + 1) < sizeof(masks) / sizeof(masks[0]));\n      return masks[idx + 1];\n   }\n   string_type lookup_collatename(const char_type* p1, const char_type* p2) const\n   {\n      string_type result;\n      if (std::find_if(p1, p2, std::bind(std::greater< ::UChar32>(), std::placeholders::_1, 0x7f)) == p2)\n      {\n         std::string s(p1, p2);\n         // Try Unicode name:\n         UErrorCode err = U_ZERO_ERROR;\n         UChar32 c = ::u_charFromName(U_UNICODE_CHAR_NAME, s.c_str(), &err);\n         if (U_SUCCESS(err))\n         {\n            result.push_back(c);\n            return result;\n         }\n         // Try Unicode-extended name:\n         err = U_ZERO_ERROR;\n         c = ::u_charFromName(U_EXTENDED_CHAR_NAME, s.c_str(), &err);\n         if (U_SUCCESS(err))\n         {\n            result.push_back(c);\n            return result;\n         }\n         // try POSIX name:\n         s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);\n         result.assign(s.begin(), s.end());\n      }\n      if (result.empty() && (p2 - p1 == 1))\n         result.push_back(*p1);\n      return result;\n   }\n   bool isctype(char_type c, char_class_type f) const\n   {\n      constexpr char_class_type mask_blank = char_class_type(1) << offset_blank;\n      constexpr char_class_type mask_space = char_class_type(1) << offset_space;\n      constexpr char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n      constexpr char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n      constexpr char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n      constexpr char_class_type mask_any = char_class_type(1) << offset_any;\n      constexpr char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n      constexpr char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n      constexpr char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n      // check for standard catagories first:\n      char_class_type m = char_class_type(static_cast<char_class_type>(1) << u_charType(c));\n      if ((m & f) != 0)\n         return true;\n      // now check for special cases:\n      if (((f & mask_blank) != 0) && u_isblank(c))\n         return true;\n      if (((f & mask_space) != 0) && u_isspace(c))\n         return true;\n      if (((f & mask_xdigit) != 0) && (u_digit(c, 16) >= 0))\n         return true;\n      if (((f & mask_unicode) != 0) && (c >= 0x100))\n         return true;\n      if (((f & mask_underscore) != 0) && (c == '_'))\n         return true;\n      if (((f & mask_any) != 0) && (c <= 0x10FFFF))\n         return true;\n      if (((f & mask_ascii) != 0) && (c <= 0x7F))\n         return true;\n      if (((f & mask_vertical) != 0) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == static_cast<char_type>('\\v')) || (m == U_GC_ZL_MASK) || (m == U_GC_ZP_MASK)))\n         return true;\n      if (((f & mask_horizontal) != 0) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && u_isspace(c) && (c != static_cast<char_type>('\\v')))\n         return true;\n      return false;\n   }\n   std::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const\n   {\n      return BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n   }\n   int value(char_type c, int radix)const\n   {\n      return u_digit(c, static_cast< std::int8_t>(radix));\n   }\n   locale_type imbue(locale_type l)\n   {\n      locale_type result(m_pimpl->getloc());\n      m_pimpl = BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(l);\n      return result;\n   }\n   locale_type getloc()const\n   {\n      return locale_type();\n   }\n   std::string error_string(::boost::regex_constants::error_type n) const\n   {\n      return BOOST_REGEX_DETAIL_NS::get_default_error_string(n);\n   }\nprivate:\n   icu_regex_traits(const icu_regex_traits&);\n   icu_regex_traits& operator=(const icu_regex_traits&);\n\n   //\n   // define the bitmasks offsets we need for additional character properties:\n   //\n   enum{\n      offset_blank = U_CHAR_CATEGORY_COUNT,\n      offset_space = U_CHAR_CATEGORY_COUNT+1,\n      offset_xdigit = U_CHAR_CATEGORY_COUNT+2,\n      offset_underscore = U_CHAR_CATEGORY_COUNT+3,\n      offset_unicode = U_CHAR_CATEGORY_COUNT+4,\n      offset_any = U_CHAR_CATEGORY_COUNT+5,\n      offset_ascii = U_CHAR_CATEGORY_COUNT+6,\n      offset_horizontal = U_CHAR_CATEGORY_COUNT+7,\n      offset_vertical = U_CHAR_CATEGORY_COUNT+8\n   };\n\n   static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2)\n   {\n      //constexpr char_class_type mask_blank = char_class_type(1) << offset_blank;\n      //constexpr char_class_type mask_space = char_class_type(1) << offset_space;\n      //constexpr char_class_type mask_xdigit = char_class_type(1) << offset_xdigit;\n      //constexpr char_class_type mask_underscore = char_class_type(1) << offset_underscore;\n      //constexpr char_class_type mask_unicode = char_class_type(1) << offset_unicode;\n      constexpr char_class_type mask_any = char_class_type(1) << offset_any;\n      constexpr char_class_type mask_ascii = char_class_type(1) << offset_ascii;\n      //constexpr char_class_type mask_horizontal = char_class_type(1) << offset_horizontal;\n      //constexpr char_class_type mask_vertical = char_class_type(1) << offset_vertical;\n\n      static const ::UChar32 prop_name_table[] = {\n         /* any */  'a', 'n', 'y',\n         /* ascii */  'a', 's', 'c', 'i', 'i',\n         /* assigned */  'a', 's', 's', 'i', 'g', 'n', 'e', 'd',\n         /* c* */  'c', '*',\n         /* cc */  'c', 'c',\n         /* cf */  'c', 'f',\n         /* closepunctuation */  'c', 'l', 'o', 's', 'e', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* cn */  'c', 'n',\n         /* co */  'c', 'o',\n         /* connectorpunctuation */  'c', 'o', 'n', 'n', 'e', 'c', 't', 'o', 'r', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* control */  'c', 'o', 'n', 't', 'r', 'o', 'l',\n         /* cs */  'c', 's',\n         /* currencysymbol */  'c', 'u', 'r', 'r', 'e', 'n', 'c', 'y', 's', 'y', 'm', 'b', 'o', 'l',\n         /* dashpunctuation */  'd', 'a', 's', 'h', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* decimaldigitnumber */  'd', 'e', 'c', 'i', 'm', 'a', 'l', 'd', 'i', 'g', 'i', 't', 'n', 'u', 'm', 'b', 'e', 'r',\n         /* enclosingmark */  'e', 'n', 'c', 'l', 'o', 's', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n         /* finalpunctuation */  'f', 'i', 'n', 'a', 'l', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* format */  'f', 'o', 'r', 'm', 'a', 't',\n         /* initialpunctuation */  'i', 'n', 'i', 't', 'i', 'a', 'l', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* l* */  'l', '*',\n         /* letter */  'l', 'e', 't', 't', 'e', 'r',\n         /* letternumber */  'l', 'e', 't', 't', 'e', 'r', 'n', 'u', 'm', 'b', 'e', 'r',\n         /* lineseparator */  'l', 'i', 'n', 'e', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n         /* ll */  'l', 'l',\n         /* lm */  'l', 'm',\n         /* lo */  'l', 'o',\n         /* lowercaseletter */  'l', 'o', 'w', 'e', 'r', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n         /* lt */  'l', 't',\n         /* lu */  'l', 'u',\n         /* m* */  'm', '*',\n         /* mark */  'm', 'a', 'r', 'k',\n         /* mathsymbol */  'm', 'a', 't', 'h', 's', 'y', 'm', 'b', 'o', 'l',\n         /* mc */  'm', 'c',\n         /* me */  'm', 'e',\n         /* mn */  'm', 'n',\n         /* modifierletter */  'm', 'o', 'd', 'i', 'f', 'i', 'e', 'r', 'l', 'e', 't', 't', 'e', 'r',\n         /* modifiersymbol */  'm', 'o', 'd', 'i', 'f', 'i', 'e', 'r', 's', 'y', 'm', 'b', 'o', 'l',\n         /* n* */  'n', '*',\n         /* nd */  'n', 'd',\n         /* nl */  'n', 'l',\n         /* no */  'n', 'o',\n         /* nonspacingmark */  'n', 'o', 'n', 's', 'p', 'a', 'c', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n         /* notassigned */  'n', 'o', 't', 'a', 's', 's', 'i', 'g', 'n', 'e', 'd',\n         /* number */  'n', 'u', 'm', 'b', 'e', 'r',\n         /* openpunctuation */  'o', 'p', 'e', 'n', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* other */  'o', 't', 'h', 'e', 'r',\n         /* otherletter */  'o', 't', 'h', 'e', 'r', 'l', 'e', 't', 't', 'e', 'r',\n         /* othernumber */  'o', 't', 'h', 'e', 'r', 'n', 'u', 'm', 'b', 'e', 'r',\n         /* otherpunctuation */  'o', 't', 'h', 'e', 'r', 'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* othersymbol */  'o', 't', 'h', 'e', 'r', 's', 'y', 'm', 'b', 'o', 'l',\n         /* p* */  'p', '*',\n         /* paragraphseparator */  'p', 'a', 'r', 'a', 'g', 'r', 'a', 'p', 'h', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n         /* pc */  'p', 'c',\n         /* pd */  'p', 'd',\n         /* pe */  'p', 'e',\n         /* pf */  'p', 'f',\n         /* pi */  'p', 'i',\n         /* po */  'p', 'o',\n         /* privateuse */  'p', 'r', 'i', 'v', 'a', 't', 'e', 'u', 's', 'e',\n         /* ps */  'p', 's',\n         /* punctuation */  'p', 'u', 'n', 'c', 't', 'u', 'a', 't', 'i', 'o', 'n',\n         /* s* */  's', '*',\n         /* sc */  's', 'c',\n         /* separator */  's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n         /* sk */  's', 'k',\n         /* sm */  's', 'm',\n         /* so */  's', 'o',\n         /* spaceseparator */  's', 'p', 'a', 'c', 'e', 's', 'e', 'p', 'a', 'r', 'a', 't', 'o', 'r',\n         /* spacingcombiningmark */  's', 'p', 'a', 'c', 'i', 'n', 'g', 'c', 'o', 'm', 'b', 'i', 'n', 'i', 'n', 'g', 'm', 'a', 'r', 'k',\n         /* surrogate */  's', 'u', 'r', 'r', 'o', 'g', 'a', 't', 'e',\n         /* symbol */  's', 'y', 'm', 'b', 'o', 'l',\n         /* titlecase */  't', 'i', 't', 'l', 'e', 'c', 'a', 's', 'e',\n         /* titlecaseletter */  't', 'i', 't', 'l', 'e', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n         /* uppercaseletter */  'u', 'p', 'p', 'e', 'r', 'c', 'a', 's', 'e', 'l', 'e', 't', 't', 'e', 'r',\n         /* z* */  'z', '*',\n         /* zl */  'z', 'l',\n         /* zp */  'z', 'p',\n         /* zs */  'z', 's',\n      };\n\n      static const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32> range_data[] = {\n         { prop_name_table + 0, prop_name_table + 3, }, // any\n         { prop_name_table + 3, prop_name_table + 8, }, // ascii\n         { prop_name_table + 8, prop_name_table + 16, }, // assigned\n         { prop_name_table + 16, prop_name_table + 18, }, // c*\n         { prop_name_table + 18, prop_name_table + 20, }, // cc\n         { prop_name_table + 20, prop_name_table + 22, }, // cf\n         { prop_name_table + 22, prop_name_table + 38, }, // closepunctuation\n         { prop_name_table + 38, prop_name_table + 40, }, // cn\n         { prop_name_table + 40, prop_name_table + 42, }, // co\n         { prop_name_table + 42, prop_name_table + 62, }, // connectorpunctuation\n         { prop_name_table + 62, prop_name_table + 69, }, // control\n         { prop_name_table + 69, prop_name_table + 71, }, // cs\n         { prop_name_table + 71, prop_name_table + 85, }, // currencysymbol\n         { prop_name_table + 85, prop_name_table + 100, }, // dashpunctuation\n         { prop_name_table + 100, prop_name_table + 118, }, // decimaldigitnumber\n         { prop_name_table + 118, prop_name_table + 131, }, // enclosingmark\n         { prop_name_table + 131, prop_name_table + 147, }, // finalpunctuation\n         { prop_name_table + 147, prop_name_table + 153, }, // format\n         { prop_name_table + 153, prop_name_table + 171, }, // initialpunctuation\n         { prop_name_table + 171, prop_name_table + 173, }, // l*\n         { prop_name_table + 173, prop_name_table + 179, }, // letter\n         { prop_name_table + 179, prop_name_table + 191, }, // letternumber\n         { prop_name_table + 191, prop_name_table + 204, }, // lineseparator\n         { prop_name_table + 204, prop_name_table + 206, }, // ll\n         { prop_name_table + 206, prop_name_table + 208, }, // lm\n         { prop_name_table + 208, prop_name_table + 210, }, // lo\n         { prop_name_table + 210, prop_name_table + 225, }, // lowercaseletter\n         { prop_name_table + 225, prop_name_table + 227, }, // lt\n         { prop_name_table + 227, prop_name_table + 229, }, // lu\n         { prop_name_table + 229, prop_name_table + 231, }, // m*\n         { prop_name_table + 231, prop_name_table + 235, }, // mark\n         { prop_name_table + 235, prop_name_table + 245, }, // mathsymbol\n         { prop_name_table + 245, prop_name_table + 247, }, // mc\n         { prop_name_table + 247, prop_name_table + 249, }, // me\n         { prop_name_table + 249, prop_name_table + 251, }, // mn\n         { prop_name_table + 251, prop_name_table + 265, }, // modifierletter\n         { prop_name_table + 265, prop_name_table + 279, }, // modifiersymbol\n         { prop_name_table + 279, prop_name_table + 281, }, // n*\n         { prop_name_table + 281, prop_name_table + 283, }, // nd\n         { prop_name_table + 283, prop_name_table + 285, }, // nl\n         { prop_name_table + 285, prop_name_table + 287, }, // no\n         { prop_name_table + 287, prop_name_table + 301, }, // nonspacingmark\n         { prop_name_table + 301, prop_name_table + 312, }, // notassigned\n         { prop_name_table + 312, prop_name_table + 318, }, // number\n         { prop_name_table + 318, prop_name_table + 333, }, // openpunctuation\n         { prop_name_table + 333, prop_name_table + 338, }, // other\n         { prop_name_table + 338, prop_name_table + 349, }, // otherletter\n         { prop_name_table + 349, prop_name_table + 360, }, // othernumber\n         { prop_name_table + 360, prop_name_table + 376, }, // otherpunctuation\n         { prop_name_table + 376, prop_name_table + 387, }, // othersymbol\n         { prop_name_table + 387, prop_name_table + 389, }, // p*\n         { prop_name_table + 389, prop_name_table + 407, }, // paragraphseparator\n         { prop_name_table + 407, prop_name_table + 409, }, // pc\n         { prop_name_table + 409, prop_name_table + 411, }, // pd\n         { prop_name_table + 411, prop_name_table + 413, }, // pe\n         { prop_name_table + 413, prop_name_table + 415, }, // pf\n         { prop_name_table + 415, prop_name_table + 417, }, // pi\n         { prop_name_table + 417, prop_name_table + 419, }, // po\n         { prop_name_table + 419, prop_name_table + 429, }, // privateuse\n         { prop_name_table + 429, prop_name_table + 431, }, // ps\n         { prop_name_table + 431, prop_name_table + 442, }, // punctuation\n         { prop_name_table + 442, prop_name_table + 444, }, // s*\n         { prop_name_table + 444, prop_name_table + 446, }, // sc\n         { prop_name_table + 446, prop_name_table + 455, }, // separator\n         { prop_name_table + 455, prop_name_table + 457, }, // sk\n         { prop_name_table + 457, prop_name_table + 459, }, // sm\n         { prop_name_table + 459, prop_name_table + 461, }, // so\n         { prop_name_table + 461, prop_name_table + 475, }, // spaceseparator\n         { prop_name_table + 475, prop_name_table + 495, }, // spacingcombiningmark\n         { prop_name_table + 495, prop_name_table + 504, }, // surrogate\n         { prop_name_table + 504, prop_name_table + 510, }, // symbol\n         { prop_name_table + 510, prop_name_table + 519, }, // titlecase\n         { prop_name_table + 519, prop_name_table + 534, }, // titlecaseletter\n         { prop_name_table + 534, prop_name_table + 549, }, // uppercaseletter\n         { prop_name_table + 549, prop_name_table + 551, }, // z*\n         { prop_name_table + 551, prop_name_table + 553, }, // zl\n         { prop_name_table + 553, prop_name_table + 555, }, // zp\n         { prop_name_table + 555, prop_name_table + 557, }, // zs\n      };\n\n      static const icu_regex_traits::char_class_type icu_class_map[] = {\n         mask_any, // any\n         mask_ascii, // ascii\n         (0x3FFFFFFFu) & ~(U_GC_CN_MASK), // assigned\n         U_GC_C_MASK, // c*\n         U_GC_CC_MASK, // cc\n         U_GC_CF_MASK, // cf\n         U_GC_PE_MASK, // closepunctuation\n         U_GC_CN_MASK, // cn\n         U_GC_CO_MASK, // co\n         U_GC_PC_MASK, // connectorpunctuation\n         U_GC_CC_MASK, // control\n         U_GC_CS_MASK, // cs\n         U_GC_SC_MASK, // currencysymbol\n         U_GC_PD_MASK, // dashpunctuation\n         U_GC_ND_MASK, // decimaldigitnumber\n         U_GC_ME_MASK, // enclosingmark\n         U_GC_PF_MASK, // finalpunctuation\n         U_GC_CF_MASK, // format\n         U_GC_PI_MASK, // initialpunctuation\n         U_GC_L_MASK, // l*\n         U_GC_L_MASK, // letter\n         U_GC_NL_MASK, // letternumber\n         U_GC_ZL_MASK, // lineseparator\n         U_GC_LL_MASK, // ll\n         U_GC_LM_MASK, // lm\n         U_GC_LO_MASK, // lo\n         U_GC_LL_MASK, // lowercaseletter\n         U_GC_LT_MASK, // lt\n         U_GC_LU_MASK, // lu\n         U_GC_M_MASK, // m*\n         U_GC_M_MASK, // mark\n         U_GC_SM_MASK, // mathsymbol\n         U_GC_MC_MASK, // mc\n         U_GC_ME_MASK, // me\n         U_GC_MN_MASK, // mn\n         U_GC_LM_MASK, // modifierletter\n         U_GC_SK_MASK, // modifiersymbol\n         U_GC_N_MASK, // n*\n         U_GC_ND_MASK, // nd\n         U_GC_NL_MASK, // nl\n         U_GC_NO_MASK, // no\n         U_GC_MN_MASK, // nonspacingmark\n         U_GC_CN_MASK, // notassigned\n         U_GC_N_MASK, // number\n         U_GC_PS_MASK, // openpunctuation\n         U_GC_C_MASK, // other\n         U_GC_LO_MASK, // otherletter\n         U_GC_NO_MASK, // othernumber\n         U_GC_PO_MASK, // otherpunctuation\n         U_GC_SO_MASK, // othersymbol\n         U_GC_P_MASK, // p*\n         U_GC_ZP_MASK, // paragraphseparator\n         U_GC_PC_MASK, // pc\n         U_GC_PD_MASK, // pd\n         U_GC_PE_MASK, // pe\n         U_GC_PF_MASK, // pf\n         U_GC_PI_MASK, // pi\n         U_GC_PO_MASK, // po\n         U_GC_CO_MASK, // privateuse\n         U_GC_PS_MASK, // ps\n         U_GC_P_MASK, // punctuation\n         U_GC_S_MASK, // s*\n         U_GC_SC_MASK, // sc\n         U_GC_Z_MASK, // separator\n         U_GC_SK_MASK, // sk\n         U_GC_SM_MASK, // sm\n         U_GC_SO_MASK, // so\n         U_GC_ZS_MASK, // spaceseparator\n         U_GC_MC_MASK, // spacingcombiningmark\n         U_GC_CS_MASK, // surrogate\n         U_GC_S_MASK, // symbol\n         U_GC_LT_MASK, // titlecase\n         U_GC_LT_MASK, // titlecaseletter\n         U_GC_LU_MASK, // uppercaseletter\n         U_GC_Z_MASK, // z*\n         U_GC_ZL_MASK, // zl\n         U_GC_ZP_MASK, // zp\n         U_GC_ZS_MASK, // zs\n      };\n\n\n      const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* ranges_begin = range_data;\n      const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* ranges_end = range_data + (sizeof(range_data) / sizeof(range_data[0]));\n\n      BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32> t = { p1, p2, };\n      const BOOST_REGEX_DETAIL_NS::character_pointer_range< ::UChar32>* p = std::lower_bound(ranges_begin, ranges_end, t);\n      if ((p != ranges_end) && (t == *p))\n         return icu_class_map[p - ranges_begin];\n      return 0;\n   }\n   std::shared_ptr< ::boost::BOOST_REGEX_DETAIL_NS::icu_regex_traits_implementation> m_pimpl;\n};\n\n} // namespace boost\n\nnamespace boost{\n\n// types:\ntypedef basic_regex< ::UChar32, icu_regex_traits> u32regex;\ntypedef match_results<const ::UChar32*> u32match;\ntypedef match_results<const ::UChar*> u16match;\n\n//\n// Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class InputIterator>\ninline u32regex do_make_u32regex(InputIterator i, \n                              InputIterator j, \n                              boost::regex_constants::syntax_option_type opt, \n                              const std::integral_constant<int, 1>*)\n{\n   typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;\n   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);\n}\n\ntemplate <class InputIterator>\ninline u32regex do_make_u32regex(InputIterator i, \n                              InputIterator j, \n                              boost::regex_constants::syntax_option_type opt, \n                              const std::integral_constant<int, 2>*)\n{\n   typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;\n   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);\n}\n\ntemplate <class InputIterator>\ninline u32regex do_make_u32regex(InputIterator i, \n                              InputIterator j, \n                              boost::regex_constants::syntax_option_type opt, \n                              const std::integral_constant<int, 4>*)\n{\n   return u32regex(i, j, opt);\n}\n}\n\n// BOOST_REGEX_UCHAR_IS_WCHAR_T\n//\n// Source inspection of unicode/umachine.h in ICU version 59 indicates that:\n//\n// On version 59, UChar is always char16_t in C++ mode (and uint16_t in C mode)\n//\n// On earlier versions, the logic is\n//\n// #if U_SIZEOF_WCHAR_T==2\n//   typedef wchar_t OldUChar;\n// #elif defined(__CHAR16_TYPE__)\n//   typedef __CHAR16_TYPE__ OldUChar;\n// #else\n//   typedef uint16_t OldUChar;\n// #endif\n//\n// That is, UChar is wchar_t only on versions below 59, when U_SIZEOF_WCHAR_T==2\n//\n// Hence,\n\n#define BOOST_REGEX_UCHAR_IS_WCHAR_T (U_ICU_VERSION_MAJOR_NUM < 59 && U_SIZEOF_WCHAR_T == 2)\n\n#if BOOST_REGEX_UCHAR_IS_WCHAR_T\n  static_assert((std::is_same<UChar, wchar_t>::value), \"Configuration logic has failed!\");\n#else\n  static_assert(!(std::is_same<UChar, wchar_t>::value), \"Configuration logic has failed!\");\n#endif\n\n//\n// Construction from an iterator pair:\n//\ntemplate <class InputIterator>\ninline u32regex make_u32regex(InputIterator i, \n                              InputIterator j, \n                              boost::regex_constants::syntax_option_type opt)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(i, j, opt, static_cast<std::integral_constant<int, sizeof(*i)> const*>(0));\n}\n//\n// construction from UTF-8 nul-terminated strings:\n//\ninline u32regex make_u32regex(const char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline u32regex make_u32regex(const unsigned char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<std::integral_constant<int, 1> const*>(0));\n}\n//\n// construction from UTF-16 nul-terminated strings:\n//\n#ifndef BOOST_NO_WREGEX\ninline u32regex make_u32regex(const wchar_t* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T\ninline u32regex make_u32regex(const UChar* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n#endif\n//\n// construction from basic_string class-template:\n//\ntemplate<class C, class T, class A>\ninline u32regex make_u32regex(const std::basic_string<C, T, A>& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.begin(), s.end(), opt, static_cast<std::integral_constant<int, sizeof(C)> const*>(0));\n}\n//\n// Construction from ICU string type:\n//\ninline u32regex make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)\n{\n   return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n\n//\n// regex_match overloads that widen the character type as appropriate:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\ntemplate<class MR1, class MR2, class NSubs>\nvoid copy_results(MR1& out, MR2 const& in, NSubs named_subs)\n{\n   // copy results from an adapted MR2 match_results:\n   out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());\n   out.set_base(in.base().base());\n   out.set_named_subs(named_subs);\n   for(int i = 0; i < (int)in.size(); ++i)\n   {\n      if(in[i].matched || !i)\n      {\n         out.set_first(in[i].first.base(), i);\n         out.set_second(in[i].second.base(), i, in[i].matched);\n      }\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   // Copy full capture info as well:\n   for(int i = 0; i < (int)in.size(); ++i)\n   {\n      if(in[i].captures().size())\n      {\n         out[i].get_captures().assign(in[i].captures().size(), typename MR1::value_type());\n         for(int j = 0; j < (int)out[i].captures().size(); ++j)\n         {\n            out[i].get_captures()[j].first = in[i].captures()[j].first.base();\n            out[i].get_captures()[j].second = in[i].captures()[j].second.base();\n            out[i].get_captures()[j].matched = in[i].captures()[j].matched;\n         }\n      }\n   }\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator>\ninline bool do_regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 std::integral_constant<int, 4> const*)\n{\n   return ::boost::regex_match(first, last, m, e, flags);\n}\ntemplate <class BidiIterator, class Allocator>\nbool do_regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 std::integral_constant<int, 2> const*)\n{\n   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;\n   typedef match_results<conv_type>                   match_type;\n   //typedef typename match_type::allocator_type        alloc_type;\n   match_type what;\n   bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);\n   // copy results across to m:\n   if(result) copy_results(m, what, e.get_named_subs());\n   return result;\n}\ntemplate <class BidiIterator, class Allocator>\nbool do_regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 std::integral_constant<int, 1> const*)\n{\n   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;\n   typedef match_results<conv_type>                   match_type;\n   //typedef typename match_type::allocator_type        alloc_type;\n   match_type what;\n   bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);\n   // copy results across to m:\n   if(result) copy_results(m, what, e.get_named_subs());\n   return result;\n}\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class BidiIterator, class Allocator>\ninline bool u32regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0));\n}\ninline bool u32regex_match(const UChar* p, \n                 match_results<const UChar*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\ninline bool u32regex_match(const wchar_t* p, \n                 match_results<const wchar_t*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_match(const char* p, \n                 match_results<const char*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_match(const unsigned char* p, \n                 match_results<const unsigned char*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_match(const std::string& s, \n                        match_results<std::string::const_iterator>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\n#ifndef BOOST_NO_STD_WSTRING\ninline bool u32regex_match(const std::wstring& s, \n                        match_results<std::wstring::const_iterator>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, \n                        match_results<const UChar*>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n//\n// regex_match overloads that do not return what matched:\n//\ntemplate <class BidiIterator>\ninline bool u32regex_match(BidiIterator first, BidiIterator last, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<BidiIterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0));\n}\ninline bool u32regex_match(const UChar* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const UChar*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\ninline bool u32regex_match(const wchar_t* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_match(const char* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_match(const unsigned char* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const unsigned char*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_match(const std::string& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<std::integral_constant<int, 1> const*>(0));\n}\n#ifndef BOOST_NO_STD_WSTRING\ninline bool u32regex_match(const std::wstring& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::wstring::const_iterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const UChar*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n\n//\n// regex_search overloads that widen the character type as appropriate:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\ntemplate <class BidiIterator, class Allocator>\ninline bool do_regex_search(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 BidiIterator base,\n                 std::integral_constant<int, 4> const*)\n{\n   return ::boost::regex_search(first, last, m, e, flags, base);\n}\ntemplate <class BidiIterator, class Allocator>\nbool do_regex_search(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 BidiIterator base,\n                 std::integral_constant<int, 2> const*)\n{\n   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;\n   typedef match_results<conv_type>                   match_type;\n   //typedef typename match_type::allocator_type        alloc_type;\n   match_type what;\n   bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));\n   // copy results across to m:\n   if(result) copy_results(m, what, e.get_named_subs());\n   return result;\n}\ntemplate <class BidiIterator, class Allocator>\nbool do_regex_search(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 BidiIterator base,\n                 std::integral_constant<int, 1> const*)\n{\n   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;\n   typedef match_results<conv_type>                   match_type;\n   //typedef typename match_type::allocator_type        alloc_type;\n   match_type what;\n   bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));\n   // copy results across to m:\n   if(result) copy_results(m, what, e.get_named_subs());\n   return result;\n}\n}\n\ntemplate <class BidiIterator, class Allocator>\ninline bool u32regex_search(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0));\n}\ntemplate <class BidiIterator, class Allocator>\ninline bool u32regex_search(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const u32regex& e, \n                 match_flag_type flags,\n                 BidiIterator base)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, base, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0));\n}\ninline bool u32regex_search(const UChar* p, \n                 match_results<const UChar*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\ninline bool u32regex_search(const wchar_t* p, \n                 match_results<const wchar_t*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_search(const char* p, \n                 match_results<const char*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_search(const unsigned char* p, \n                 match_results<const unsigned char*>& m, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_search(const std::string& s, \n                        match_results<std::string::const_iterator>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<std::integral_constant<int, 1> const*>(0));\n}\n#ifndef BOOST_NO_STD_WSTRING\ninline bool u32regex_search(const std::wstring& s, \n                        match_results<std::wstring::const_iterator>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, \n                        match_results<const UChar*>& m, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<std::integral_constant<int, 2> const*>(0));\n}\ntemplate <class BidiIterator>\ninline bool u32regex_search(BidiIterator first, BidiIterator last, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<BidiIterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0));\n}\ninline bool u32regex_search(const UChar* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const UChar*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<std::integral_constant<int, 2> const*>(0));\n}\n#if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)\ninline bool u32regex_search(const wchar_t* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const wchar_t*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_search(const char* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const char*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_search(const unsigned char* p, \n                 const u32regex& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<const unsigned char*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<std::integral_constant<int, 1> const*>(0));\n}\ninline bool u32regex_search(const std::string& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::string::const_iterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<std::integral_constant<int, 1> const*>(0));\n}\n#ifndef BOOST_NO_STD_WSTRING\ninline bool u32regex_search(const std::wstring& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<std::wstring::const_iterator> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<std::integral_constant<int, sizeof(wchar_t)> const*>(0));\n}\n#endif\ninline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, \n                        const u32regex& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const UChar*> m;\n   return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<std::integral_constant<int, 2> const*>(0));\n}\n\n//\n// overloads for regex_replace with utf-8 and utf-16 data types:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\ntemplate <class I>\ninline std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >\n   make_utf32_seq(I i, I j, std::integral_constant<int, 1> const*)\n{\n   return std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >(boost::u8_to_u32_iterator<I>(i, i, j), boost::u8_to_u32_iterator<I>(j, i, j));\n}\ntemplate <class I>\ninline std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >\n   make_utf32_seq(I i, I j, std::integral_constant<int, 2> const*)\n{\n   return std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >(boost::u16_to_u32_iterator<I>(i, i, j), boost::u16_to_u32_iterator<I>(j, i, j));\n}\ntemplate <class I>\ninline std::pair< I, I >\n   make_utf32_seq(I i, I j, std::integral_constant<int, 4> const*)\n{\n   return std::pair< I, I >(i, j);\n}\ntemplate <class charT>\ninline std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >\n   make_utf32_seq(const charT* p, std::integral_constant<int, 1> const*)\n{\n   std::size_t len = std::strlen((const char*)p);\n   return std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >(boost::u8_to_u32_iterator<const charT*>(p, p, p+len), boost::u8_to_u32_iterator<const charT*>(p+len, p, p+len));\n}\ntemplate <class charT>\ninline std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >\n   make_utf32_seq(const charT* p, std::integral_constant<int, 2> const*)\n{\n   std::size_t len = u_strlen((const UChar*)p);\n   return std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >(boost::u16_to_u32_iterator<const charT*>(p, p, p + len), boost::u16_to_u32_iterator<const charT*>(p+len, p, p + len));\n}\ntemplate <class charT>\ninline std::pair< const charT*, const charT* >\n   make_utf32_seq(const charT* p, std::integral_constant<int, 4> const*)\n{\n   return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));\n}\ntemplate <class OutputIterator>\ninline OutputIterator make_utf32_out(OutputIterator o, std::integral_constant<int, 4> const*)\n{\n   return o;\n}\ntemplate <class OutputIterator>\ninline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, std::integral_constant<int, 2> const*)\n{\n   return o;\n}\ntemplate <class OutputIterator>\ninline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, std::integral_constant<int, 1> const*)\n{\n   return o;\n}\n\ntemplate <class OutputIterator, class I1, class I2>\nOutputIterator do_regex_replace(OutputIterator out,\n                                 std::pair<I1, I1> const& in,\n                                 const u32regex& e, \n                                 const std::pair<I2, I2>& fmt, \n                                 match_flag_type flags\n                                 )\n{\n   // unfortunately we have to copy the format string in order to pass in onward:\n   std::vector<UChar32> f;\n   f.assign(fmt.first, fmt.second);\n   \n   regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);\n   regex_iterator<I1, UChar32, icu_regex_traits> j;\n   if(i == j)\n   {\n      if(!(flags & regex_constants::format_no_copy))\n         out = std::copy(in.first, in.second, out);\n   }\n   else\n   {\n      I1 last_m = in.first;\n      while(i != j)\n      {\n         if(!(flags & regex_constants::format_no_copy))\n            out = std::copy(i->prefix().first, i->prefix().second, out); \n         if(!f.empty())\n            out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());\n         else\n            out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());\n         last_m = (*i)[0].second;\n         if(flags & regex_constants::format_first_only)\n            break;\n         ++i;\n      }\n      if(!(flags & regex_constants::format_no_copy))\n         out = std::copy(last_m, in.second, out);\n   }\n   return out;\n}\ntemplate <class BaseIterator>\ninline const BaseIterator& extract_output_base(const BaseIterator& b)\n{\n   return b;\n}\ntemplate <class BaseIterator>\ninline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)\n{\n   return b.base();\n}\ntemplate <class BaseIterator>\ninline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)\n{\n   return b.base();\n}\n}  // BOOST_REGEX_DETAIL_NS\n\ntemplate <class OutputIterator, class BidirectionalIterator, class charT>\ninline OutputIterator u32regex_replace(OutputIterator out,\n                         BidirectionalIterator first,\n                         BidirectionalIterator last,\n                         const u32regex& e, \n                         const charT* fmt, \n                         match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::extract_output_base\n    (\n      BOOST_REGEX_DETAIL_NS::do_regex_replace(\n         BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         e,\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt, static_cast<std::integral_constant<int, sizeof(*fmt)> const*>(0)),\n         flags)\n      );\n}\n\ntemplate <class OutputIterator, class Iterator, class charT>\ninline OutputIterator u32regex_replace(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const u32regex& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::extract_output_base\n    (\n      BOOST_REGEX_DETAIL_NS::do_regex_replace(\n         BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         e,\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<std::integral_constant<int, sizeof(charT)> const*>(0)),\n         flags)\n      );\n}\n\ntemplate <class OutputIterator, class Iterator>\ninline OutputIterator u32regex_replace(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const u32regex& e, \n                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,\n                         match_flag_type flags = match_default)\n{\n   return BOOST_REGEX_DETAIL_NS::extract_output_base\n   (\n      BOOST_REGEX_DETAIL_NS::do_regex_replace(\n         BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<std::integral_constant<int, sizeof(*first)> const*>(0)),\n         e,\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<std::integral_constant<int, 2> const*>(0)),\n         flags)\n      );\n}\n\ntemplate <class charT>\nstd::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,\n                         const u32regex& e, \n                         const charT* fmt,\n                         match_flag_type flags = match_default)\n{\n   std::basic_string<charT> result;\n   BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n   u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);\n   return result;\n}\n\ntemplate <class charT>\nstd::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,\n                         const u32regex& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   std::basic_string<charT> result;\n   BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n   u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);\n   return result;\n}\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\nclass unicode_string_out_iterator\n{\n   U_NAMESPACE_QUALIFIER UnicodeString* out;\npublic:\n   unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}\n   unicode_string_out_iterator& operator++() { return *this; }\n   unicode_string_out_iterator& operator++(int) { return *this; }\n   unicode_string_out_iterator& operator*() { return *this; }\n   unicode_string_out_iterator& operator=(UChar v) \n   { \n      *out += v; \n      return *this; \n   }\n   typedef std::ptrdiff_t difference_type;\n   typedef UChar value_type;\n   typedef value_type* pointer;\n   typedef value_type& reference;\n   typedef std::output_iterator_tag iterator_category;\n};\n\n}\n\ninline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n                         const u32regex& e, \n                         const UChar* fmt,\n                         match_flag_type flags = match_default)\n{\n   U_NAMESPACE_QUALIFIER UnicodeString result;\n   BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);\n   u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);\n   return result;\n}\n\ninline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,\n                         const u32regex& e, \n                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,\n                         match_flag_type flags = match_default)\n{\n   U_NAMESPACE_QUALIFIER UnicodeString result;\n   BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);\n   BOOST_REGEX_DETAIL_NS::do_regex_replace(\n         BOOST_REGEX_DETAIL_NS::make_utf32_out(i, static_cast<std::integral_constant<int, 2> const*>(0)),\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<std::integral_constant<int, 2> const*>(0)),\n         e,\n         BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<std::integral_constant<int, 2> const*>(0)),\n         flags);\n   return result;\n}\n\n} // namespace boost.\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning (pop)\n#endif\n\n#include <boost/regex/v5/u32regex_iterator.hpp>\n#include <boost/regex/v5/u32regex_token_iterator.hpp>\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/iterator_category.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_match.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Iterator traits for selecting an iterator type as\n  *                an integral constant expression.\n  */\n\n\n#ifndef BOOST_REGEX_ITERATOR_CATEGORY_HPP\n#define BOOST_REGEX_ITERATOR_CATEGORY_HPP\n\n#include <iterator>\n#include <type_traits>\n\nnamespace boost{\nnamespace detail{\n\ntemplate <class I>\nstruct is_random_imp\n{\nprivate:\n   typedef typename std::iterator_traits<I>::iterator_category cat;\npublic:\n   static const bool value = (std::is_convertible<cat*, std::random_access_iterator_tag*>::value);\n};\n\ntemplate <class I>\nstruct is_random_pointer_imp\n{\n   static const bool value = true;\n};\n\ntemplate <bool is_pointer_type>\nstruct is_random_imp_selector\n{\n   template <class I>\n   struct rebind\n   {\n      typedef is_random_imp<I> type;\n   };\n};\n\ntemplate <>\nstruct is_random_imp_selector<true>\n{\n   template <class I>\n   struct rebind\n   {\n      typedef is_random_pointer_imp<I> type;\n   };\n};\n\n}\n\ntemplate <class I>\nstruct is_random_access_iterator\n{\nprivate:\n   typedef detail::is_random_imp_selector< std::is_pointer<I>::value> selector;\n   typedef typename selector::template rebind<I> bound_type;\n   typedef typename bound_type::type answer;\npublic:\n   static const bool value = answer::value;\n};\n\ntemplate <class I>\nconst bool is_random_access_iterator<I>::value;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/iterator_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         iterator_traits.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares iterator traits workarounds.\n  */\n\n#ifndef BOOST_REGEX_V5_ITERATOR_TRAITS_HPP\n#define BOOST_REGEX_V5_ITERATOR_TRAITS_HPP\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class T>\nstruct regex_iterator_traits : public std::iterator_traits<T> {};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/match_flags.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         match_flags.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares match_flags type.\n  */\n\n#ifndef BOOST_REGEX_V5_MATCH_FLAGS\n#define BOOST_REGEX_V5_MATCH_FLAGS\n\n#ifdef __cplusplus\n#  include <cstdint>\n#endif\n\n#ifdef __cplusplus\nnamespace boost{\n   namespace regex_constants{\n#endif\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable : 26812)\n#endif\n#endif\n\ntypedef enum _match_flags\n{\n   match_default = 0,\n   match_not_bol = 1,                                /* first is not start of line */\n   match_not_eol = match_not_bol << 1,               /* last is not end of line */\n   match_not_bob = match_not_eol << 1,               /* first is not start of buffer */\n   match_not_eob = match_not_bob << 1,               /* last is not end of buffer */\n   match_not_bow = match_not_eob << 1,               /* first is not start of word */\n   match_not_eow = match_not_bow << 1,               /* last is not end of word */\n   match_not_dot_newline = match_not_eow << 1,       /* \\n is not matched by '.' */\n   match_not_dot_null = match_not_dot_newline << 1,  /* '\\0' is not matched by '.' */\n   match_prev_avail = match_not_dot_null << 1,       /* *--first is a valid expression */\n   match_init = match_prev_avail << 1,               /* internal use */\n   match_any = match_init << 1,                      /* don't care what we match */\n   match_not_null = match_any << 1,                  /* string can't be null */\n   match_continuous = match_not_null << 1,           /* each grep match must continue from */\n                                                     /* uninterrupted from the previous one */\n   match_partial = match_continuous << 1,            /* find partial matches */\n   \n   match_stop = match_partial << 1,                  /* stop after first match (grep) V3 only */\n   match_not_initial_null = match_stop,              /* don't match initial null, V4 only */\n   match_all = match_stop << 1,                      /* must find the whole of input even if match_any is set */\n   match_perl = match_all << 1,                      /* Use perl matching rules */\n   match_posix = match_perl << 1,                    /* Use POSIX matching rules */\n   match_nosubs = match_posix << 1,                  /* don't trap marked subs */\n   match_extra = match_nosubs << 1,                  /* include full capture information for repeated captures */\n   match_single_line = match_extra << 1,             /* treat text as single line and ignore any \\n's when matching ^ and $. */\n   match_unused1 = match_single_line << 1,           /* unused */\n   match_unused2 = match_unused1 << 1,               /* unused */\n   match_unused3 = match_unused2 << 1,               /* unused */\n   match_max = match_unused3,\n\n   format_perl = 0,                                  /* perl style replacement */\n   format_default = 0,                               /* ditto. */\n   format_sed = match_max << 1,                      /* sed style replacement. */\n   format_all = format_sed << 1,                     /* enable all extensions to syntax. */\n   format_no_copy = format_all << 1,                 /* don't copy non-matching segments. */\n   format_first_only = format_no_copy << 1,          /* Only replace first occurrence. */\n   format_is_if = format_first_only << 1,            /* internal use only. */\n   format_literal = format_is_if << 1,               /* treat string as a literal */\n\n   match_not_any = match_not_bol | match_not_eol | match_not_bob \n      | match_not_eob | match_not_bow | match_not_eow | match_not_dot_newline \n      | match_not_dot_null | match_prev_avail | match_init | match_not_null\n      | match_continuous | match_partial | match_stop | match_not_initial_null \n      | match_stop | match_all | match_perl | match_posix | match_nosubs\n      | match_extra | match_single_line | match_unused1 | match_unused2 \n      | match_unused3 | match_max | format_perl | format_default | format_sed\n      | format_all | format_no_copy | format_first_only | format_is_if\n      | format_literal\n\n\n} match_flags;\n\ntypedef match_flags match_flag_type;\n\n#ifdef __cplusplus\ninline match_flags operator&(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) & static_cast<std::int32_t>(m2)); }\ninline match_flags operator|(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) | static_cast<std::int32_t>(m2)); }\ninline match_flags operator^(match_flags m1, match_flags m2)\n{ return static_cast<match_flags>(static_cast<std::int32_t>(m1) ^ static_cast<std::int32_t>(m2)); }\ninline match_flags operator~(match_flags m1)\n{ return static_cast<match_flags>(~static_cast<std::int32_t>(m1)); }\ninline match_flags& operator&=(match_flags& m1, match_flags m2)\n{ m1 = m1&m2; return m1; }\ninline match_flags& operator|=(match_flags& m1, match_flags m2)\n{ m1 = m1|m2; return m1; }\ninline match_flags& operator^=(match_flags& m1, match_flags m2)\n{ m1 = m1^m2; return m1; }\n#endif\n\n#ifdef __cplusplus\n} /* namespace regex_constants */\n/*\n * import names into boost for backwards compatibility:\n */\nusing regex_constants::match_flag_type;\nusing regex_constants::match_default;\nusing regex_constants::match_not_bol;\nusing regex_constants::match_not_eol;\nusing regex_constants::match_not_bob;\nusing regex_constants::match_not_eob;\nusing regex_constants::match_not_bow;\nusing regex_constants::match_not_eow;\nusing regex_constants::match_not_dot_newline;\nusing regex_constants::match_not_dot_null;\nusing regex_constants::match_prev_avail;\n/* using regex_constants::match_init; */\nusing regex_constants::match_any;\nusing regex_constants::match_not_null;\nusing regex_constants::match_continuous;\nusing regex_constants::match_partial;\n/*using regex_constants::match_stop; */\nusing regex_constants::match_all;\nusing regex_constants::match_perl;\nusing regex_constants::match_posix;\nusing regex_constants::match_nosubs;\nusing regex_constants::match_extra;\nusing regex_constants::match_single_line;\n/*using regex_constants::match_max; */\nusing regex_constants::format_all;\nusing regex_constants::format_sed;\nusing regex_constants::format_perl;\nusing regex_constants::format_default;\nusing regex_constants::format_no_copy;\nusing regex_constants::format_first_only;\n/*using regex_constants::format_is_if;*/\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n\n} /* namespace boost */\n#endif /* __cplusplus */\n#endif /* include guard */\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/match_results.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         match_results.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class match_results.\n  */\n\n#ifndef BOOST_REGEX_V5_MATCH_RESULTS_HPP\n#define BOOST_REGEX_V5_MATCH_RESULTS_HPP\n\nnamespace boost{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4251 4459)\n#if BOOST_REGEX_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#  if BOOST_REGEX_MSVC < 1600\n#     pragma warning(disable : 4660)\n#  endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\nclass named_subexpressions;\n\n}\n\ntemplate <class BidiIterator, class Allocator>\nclass match_results\n{ \nprivate:\n   typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;\npublic: \n   typedef          sub_match<BidiIterator>                         value_type;\n   typedef typename std::allocator_traits<Allocator>::value_type const &    const_reference;\n   typedef          const_reference                                         reference;\n   typedef typename vector_type::const_iterator                             const_iterator;\n   typedef          const_iterator                                          iterator;\n   typedef typename std::iterator_traits<\n                                    BidiIterator>::difference_type          difference_type;\n   typedef typename std::allocator_traits<Allocator>::size_type             size_type;\n   typedef          Allocator                                               allocator_type;\n   typedef typename std::iterator_traits<\n                                    BidiIterator>::value_type               char_type;\n   typedef          std::basic_string<char_type>                            string_type;\n   typedef          BOOST_REGEX_DETAIL_NS::named_subexpressions             named_sub_type;\n\n   // construct/copy/destroy:\n   explicit match_results(const Allocator& a = Allocator())\n      : m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}\n   //\n   // IMPORTANT: in the code below, the crazy looking checks around m_is_singular are\n   // all required because it is illegal to copy a singular iterator.\n   // See https://svn.boost.org/trac/boost/ticket/3632.\n   //\n   match_results(const match_results& m)\n      : m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)\n   {\n      if(!m_is_singular)\n      {\n         m_base = m.m_base;\n         m_null = m.m_null;\n      }\n   }\n   match_results& operator=(const match_results& m)\n   {\n      m_subs = m.m_subs;\n      m_named_subs = m.m_named_subs;\n      m_last_closed_paren = m.m_last_closed_paren;\n      m_is_singular = m.m_is_singular;\n      if(!m_is_singular)\n      {\n         m_base = m.m_base;\n         m_null = m.m_null;\n      }\n      return *this;\n   }\n   ~match_results(){}\n\n   // size:\n   size_type size() const\n   { return empty() ? 0 : m_subs.size() - 2; }\n   size_type max_size() const\n   { return m_subs.max_size(); }\n   bool empty() const\n   { return m_subs.size() < 2; }\n   // element access:\n   difference_type length(int sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      if((sub < (int)m_subs.size()) && (sub > 0))\n         return m_subs[sub].length();\n      return 0;\n   }\n   difference_type length(const char_type* sub) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      const char_type* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return length(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT>\n   difference_type length(const charT* sub) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      const charT* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return length(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT, class Traits, class A>\n   difference_type length(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return length(sub.c_str());\n   }\n   difference_type position(size_type sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      if(sub < m_subs.size())\n      {\n         const sub_match<BidiIterator>& s = m_subs[sub];\n         if(s.matched || (sub == 2))\n         {\n            return std::distance((BidiIterator)(m_base), (BidiIterator)(s.first));\n         }\n      }\n      return ~static_cast<difference_type>(0);\n   }\n   difference_type position(const char_type* sub) const\n   {\n      const char_type* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return position(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT>\n   difference_type position(const charT* sub) const\n   {\n      const charT* sub_end = sub;\n      while(*sub_end) ++sub_end;\n      return position(named_subexpression_index(sub, sub_end));\n   }\n   template <class charT, class Traits, class A>\n   difference_type position(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return position(sub.c_str());\n   }\n   string_type str(int sub = 0) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      sub += 2;\n      string_type result;\n      if(sub < (int)m_subs.size() && (sub > 0))\n      {\n         const sub_match<BidiIterator>& s = m_subs[sub];\n         if(s.matched)\n         {\n            result = s.str();\n         }\n      }\n      return result;\n   }\n   string_type str(const char_type* sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class Traits, class A>\n   string_type str(const std::basic_string<char_type, Traits, A>& sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class charT>\n   string_type str(const charT* sub) const\n   {\n      return (*this)[sub].str();\n   }\n   template <class charT, class Traits, class A>\n   string_type str(const std::basic_string<charT, Traits, A>& sub) const\n   {\n      return (*this)[sub].str();\n   }\n   const_reference operator[](int sub) const\n   {\n      if(m_is_singular && m_subs.empty())\n         raise_logic_error();\n      sub += 2;\n      if(sub < (int)m_subs.size() && (sub >= 0))\n      {\n         return m_subs[sub];\n      }\n      return m_null;\n   }\n   //\n   // Named sub-expressions:\n   //\n   const_reference named_subexpression(const char_type* i, const char_type* j) const\n   {\n      //\n      // Scan for the leftmost *matched* subexpression with the specified named:\n      //\n      if(m_is_singular)\n         raise_logic_error();\n      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);\n      while((r.first != r.second) && ((*this)[r.first->index].matched == false))\n         ++r.first;\n      return r.first != r.second ? (*this)[r.first->index] : m_null;\n   }\n   template <class charT>\n   const_reference named_subexpression(const charT* i, const charT* j) const\n   {\n      static_assert(sizeof(charT) <= sizeof(char_type), \"Failed internal logic\");\n      if(i == j)\n         return m_null;\n      std::vector<char_type> s;\n      while(i != j)\n         s.insert(s.end(), *i++);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n   int named_subexpression_index(const char_type* i, const char_type* j) const\n   {\n      //\n      // Scan for the leftmost *matched* subexpression with the specified named.\n      // If none found then return the leftmost expression with that name,\n      // otherwise an invalid index:\n      //\n      if(m_is_singular)\n         raise_logic_error();\n      BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;\n      s = r = m_named_subs->equal_range(i, j);\n      while((r.first != r.second) && ((*this)[r.first->index].matched == false))\n         ++r.first;\n      if(r.first == r.second)\n         r = s;\n      return r.first != r.second ? r.first->index : -20;\n   }\n   template <class charT>\n   int named_subexpression_index(const charT* i, const charT* j) const\n   {\n      static_assert(sizeof(charT) <= sizeof(char_type), \"Failed internal logic\");\n      if(i == j)\n         return -20;\n      std::vector<char_type> s;\n      while(i != j)\n         s.insert(s.end(), *i++);\n      return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());\n   }\n   template <class Traits, class A>\n   const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const\n   {\n      return named_subexpression(s.c_str(), s.c_str() + s.size());\n   }\n   const_reference operator[](const char_type* p) const\n   {\n      const char_type* e = p;\n      while(*e) ++e;\n      return named_subexpression(p, e);\n   }\n\n   template <class charT>\n   const_reference operator[](const charT* p) const\n   {\n      static_assert(sizeof(charT) <= sizeof(char_type), \"Failed internal logic\");\n      if(*p == 0)\n         return m_null;\n      std::vector<char_type> s;\n      while(*p)\n         s.insert(s.end(), *p++);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n   template <class charT, class Traits, class A>\n   const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const\n   {\n      static_assert(sizeof(charT) <= sizeof(char_type), \"Failed internal logic\");\n      if(ns.empty())\n         return m_null;\n      std::vector<char_type> s;\n      for(unsigned i = 0; i < ns.size(); ++i)\n         s.insert(s.end(), ns[i]);\n      return named_subexpression(&*s.begin(), &*s.begin() + s.size());\n   }\n\n   const_reference prefix() const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[-1];\n   }\n\n   const_reference suffix() const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[-2];\n   }\n   const_iterator begin() const\n   {\n      return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();\n   }\n   const_iterator end() const\n   {\n      return m_subs.end();\n   }\n   // format:\n   template <class OutputIterator, class Functor>\n   OutputIterator format(OutputIterator out,\n                         Functor fmt,\n                         match_flag_type flags = format_default) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;\n      F func(fmt);\n      return func(*this, out, flags);\n   }\n   template <class Functor>\n   string_type format(Functor fmt, match_flag_type flags = format_default) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      std::basic_string<char_type> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);\n\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;\n      F func(fmt);\n\n      func(*this, i, flags);\n      return result;\n   }\n   // format with locale:\n   template <class OutputIterator, class Functor, class RegexT>\n   OutputIterator format(OutputIterator out,\n                         Functor fmt,\n                         match_flag_type flags,\n                         const RegexT& re) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;\n      F func(fmt);\n      return func(*this, out, flags, re.get_traits());\n   }\n   template <class RegexT, class Functor>\n   string_type format(Functor fmt,\n                      match_flag_type flags,\n                      const RegexT& re) const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;\n      std::basic_string<char_type> result;\n      BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);\n\n      typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;\n      F func(fmt);\n\n      func(*this, i, flags, re.get_traits());\n      return result;\n   }\n\n   const_reference get_last_closed_paren()const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];\n   }\n\n   allocator_type get_allocator() const\n   {\n      return m_subs.get_allocator();\n   }\n   void swap(match_results& that)\n   {\n      std::swap(m_subs, that.m_subs);\n      std::swap(m_named_subs, that.m_named_subs);\n      std::swap(m_last_closed_paren, that.m_last_closed_paren);\n      if(m_is_singular)\n      {\n         if(!that.m_is_singular)\n         {\n            m_base = that.m_base;\n            m_null = that.m_null;\n         }\n      }\n      else if(that.m_is_singular)\n      {\n         that.m_base = m_base;\n         that.m_null = m_null;\n      }\n      else\n      {\n         std::swap(m_base, that.m_base);\n         std::swap(m_null, that.m_null);\n      }\n      std::swap(m_is_singular, that.m_is_singular);\n   }\n   bool operator==(const match_results& that)const\n   {\n      if(m_is_singular)\n      {\n         return that.m_is_singular;\n      }\n      else if(that.m_is_singular)\n      {\n         return false;\n      }\n      return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);\n   }\n   bool operator!=(const match_results& that)const\n   { return !(*this == that); }\n\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;\n\n   const capture_sequence_type& captures(int i)const\n   {\n      if(m_is_singular)\n         raise_logic_error();\n      return (*this)[i].captures();\n   }\n#endif\n\n   //\n   // private access functions:\n   void  set_second(BidiIterator i)\n   {\n      BOOST_REGEX_ASSERT(m_subs.size() > 2);\n      m_subs[2].second = i;\n      m_subs[2].matched = true;\n      m_subs[0].first = i;\n      m_subs[0].matched = (m_subs[0].first != m_subs[0].second);\n      m_null.first = i;\n      m_null.second = i;\n      m_null.matched = false;\n      m_is_singular = false;\n   }\n\n   void  set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)\n   {\n      if(pos)\n         m_last_closed_paren = static_cast<int>(pos);\n      pos += 2;\n      BOOST_REGEX_ASSERT(m_subs.size() > pos);\n      m_subs[pos].second = i;\n      m_subs[pos].matched = m;\n      if((pos == 2) && !escape_k)\n      {\n         m_subs[0].first = i;\n         m_subs[0].matched = (m_subs[0].first != m_subs[0].second);\n         m_null.first = i;\n         m_null.second = i;\n         m_null.matched = false;\n         m_is_singular = false;\n      }\n   }\n   void  set_size(size_type n, BidiIterator i, BidiIterator j)\n   {\n      value_type v(j);\n      size_type len = m_subs.size();\n      if(len > n + 2)\n      {\n         m_subs.erase(m_subs.begin()+n+2, m_subs.end());\n         std::fill(m_subs.begin(), m_subs.end(), v);\n      }\n      else\n      {\n         std::fill(m_subs.begin(), m_subs.end(), v);\n         if(n+2 != len)\n            m_subs.insert(m_subs.end(), n+2-len, v);\n      }\n      m_subs[1].first = i;\n      m_last_closed_paren = 0;\n   }\n   void  set_base(BidiIterator pos)\n   {\n      m_base = pos;\n   }\n   BidiIterator base()const\n   {\n      return m_base;\n   }\n   void  set_first(BidiIterator i)\n   {\n      BOOST_REGEX_ASSERT(m_subs.size() > 2);\n      // set up prefix:\n      m_subs[1].second = i;\n      m_subs[1].matched = (m_subs[1].first != i);\n      // set up $0:\n      m_subs[2].first = i;\n      // zero out everything else:\n      for(size_type n = 3; n < m_subs.size(); ++n)\n      {\n         m_subs[n].first = m_subs[n].second = m_subs[0].second;\n         m_subs[n].matched = false;\n      }\n   }\n   void  set_first(BidiIterator i, size_type pos, bool escape_k = false)\n   {\n      BOOST_REGEX_ASSERT(pos+2 < m_subs.size());\n      if(pos || escape_k)\n      {\n         m_subs[pos+2].first = i;\n         if(escape_k)\n         {\n            m_subs[1].second = i;\n            m_subs[1].matched = (m_subs[1].first != m_subs[1].second);\n         }\n      }\n      else\n         set_first(i);\n   }\n   void  maybe_assign(const match_results<BidiIterator, Allocator>& m);\n\n   void  set_named_subs(std::shared_ptr<named_sub_type> subs)\n   {\n      m_named_subs = subs;\n   }\n\nprivate:\n   //\n   // Error handler called when an uninitialized match_results is accessed:\n   //\n   static void raise_logic_error()\n   {\n      std::logic_error e(\"Attempt to access an uninitialized boost::match_results<> class.\");\n#ifndef BOOST_REGEX_STANDALONE\n      boost::throw_exception(e);\n#else\n      throw e;\n#endif\n   }\n\n\n   vector_type            m_subs;                      // subexpressions\n   BidiIterator   m_base;                              // where the search started from\n   sub_match<BidiIterator> m_null;                     // a null match\n   std::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object\n   int m_last_closed_paren;                            // Last ) to be seen - used for formatting\n   bool m_is_singular;                                 // True if our stored iterators are singular\n};\n\ntemplate <class BidiIterator, class Allocator>\nvoid  match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)\n{\n   if(m_is_singular)\n   {\n      *this = m;\n      return;\n   }\n   const_iterator p1, p2;\n   p1 = begin();\n   p2 = m.begin();\n   //\n   // Distances are measured from the start of *this* match, unless this isn't\n   // a valid match in which case we use the start of the whole sequence.  Note that\n   // no subsequent match-candidate can ever be to the left of the first match found.\n   // This ensures that when we are using bidirectional iterators, that distances \n   // measured are as short as possible, and therefore as efficient as possible\n   // to compute.  Finally note that we don't use the \"matched\" data member to test\n   // whether a sub-expression is a valid match, because partial matches set this\n   // to false for sub-expression 0.\n   //\n   BidiIterator l_end = this->suffix().second;\n   BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;\n   difference_type len1 = 0;\n   difference_type len2 = 0;\n   difference_type base1 = 0;\n   difference_type base2 = 0;\n   std::size_t i;\n   for(i = 0; i < size(); ++i, ++p1, ++p2)\n   {\n      //\n      // Leftmost takes priority over longest; handle special cases\n      // where distances need not be computed first (an optimisation\n      // for bidirectional iterators: ensure that we don't accidently\n      // compute the length of the whole sequence, as this can be really\n      // expensive).\n      //\n      if(p1->first == l_end)\n      {\n         if(p2->first != l_end)\n         {\n            // p2 must be better than p1, and no need to calculate\n            // actual distances:\n            base1 = 1;\n            base2 = 0;\n            break;\n         }\n         else\n         {\n            // *p1 and *p2 are either unmatched or match end-of sequence,\n            // either way no need to calculate distances:\n            if((p1->matched == false) && (p2->matched == true))\n               break;\n            if((p1->matched == true) && (p2->matched == false))\n               return;\n            continue;\n         }\n      }\n      else if(p2->first == l_end)\n      {\n         // p1 better than p2, and no need to calculate distances:\n         return;\n      }\n      base1 = std::distance(l_base, p1->first);\n      base2 = std::distance(l_base, p2->first);\n      BOOST_REGEX_ASSERT(base1 >= 0);\n      BOOST_REGEX_ASSERT(base2 >= 0);\n      if(base1 < base2) return;\n      if(base2 < base1) break;\n\n      len1 = std::distance((BidiIterator)p1->first, (BidiIterator)p1->second);\n      len2 = std::distance((BidiIterator)p2->first, (BidiIterator)p2->second);\n      BOOST_REGEX_ASSERT(len1 >= 0);\n      BOOST_REGEX_ASSERT(len2 >= 0);\n      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))\n         break;\n      if((p1->matched == true) && (p2->matched == false))\n         return;\n   }\n   if(i == size())\n      return;\n   if(base2 < base1)\n      *this = m;\n   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )\n      *this = m;\n}\n\ntemplate <class BidiIterator, class Allocator>\nvoid swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)\n{\n   a.swap(b);\n}\n\ntemplate <class charT, class traits, class BidiIterator, class Allocator>\nstd::basic_ostream<charT, traits>&\n   operator << (std::basic_ostream<charT, traits>& os,\n                const match_results<BidiIterator, Allocator>& s)\n{\n   return (os << s.str());\n}\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n} // namespace boost\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/mem_block_cache.hpp",
    "content": " /*\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         mem_block_cache.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: memory block cache used by the non-recursive matcher.\n  */\n\n#ifndef BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP\n#define BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP\n\n#include <new>\n#ifdef BOOST_HAS_THREADS\n#include <mutex>\n#endif\n\n#ifndef BOOST_NO_CXX11_HDR_ATOMIC\n  #include <atomic>\n  #if ATOMIC_POINTER_LOCK_FREE == 2\n    #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE\n    #define BOOST_REGEX_ATOMIC_POINTER std::atomic\n  #endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#if BOOST_REGEX_MAX_CACHE_BLOCKS != 0\n#ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */\nstruct mem_block_cache\n{\n  std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];\n\n   ~mem_block_cache()\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       if (cache[i].load()) ::operator delete(cache[i].load());\n     }\n   }\n   void* get()\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       void* p = cache[i].load();\n       if (p != NULL) {\n         if (cache[i].compare_exchange_strong(p, NULL)) return p;\n       }\n     }\n     return ::operator new(BOOST_REGEX_BLOCKSIZE);\n   }\n   void put(void* ptr)\n   {\n     for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {\n       void* p = cache[i].load();\n       if (p == NULL) {\n         if (cache[i].compare_exchange_strong(p, ptr)) return;\n       }\n     }\n     ::operator delete(ptr);\n   }\n\n   static mem_block_cache& instance()\n   {\n      static mem_block_cache block_cache = { { {nullptr} } };\n      return block_cache;\n   }\n};\n\n\n#else /* lock-based implementation */\n\n\nstruct mem_block_node\n{\n   mem_block_node* next;\n};\n\nstruct mem_block_cache\n{\n   // this member has to be statically initialsed:\n   mem_block_node* next { nullptr };\n   unsigned cached_blocks { 0 };\n#ifdef BOOST_HAS_THREADS\n   std::mutex mut;\n#endif\n\n   ~mem_block_cache()\n   {\n      while(next)\n      {\n         mem_block_node* old = next;\n         next = next->next;\n         ::operator delete(old);\n      }\n   }\n   void* get()\n   {\n#ifdef BOOST_HAS_THREADS\n      std::lock_guard<std::mutex> g(mut);\n#endif\n     if(next)\n      {\n         mem_block_node* result = next;\n         next = next->next;\n         --cached_blocks;\n         return result;\n      }\n      return ::operator new(BOOST_REGEX_BLOCKSIZE);\n   }\n   void put(void* p)\n   {\n#ifdef BOOST_HAS_THREADS\n      std::lock_guard<std::mutex> g(mut);\n#endif\n      if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)\n      {\n         ::operator delete(p);\n      }\n      else\n      {\n         mem_block_node* old = static_cast<mem_block_node*>(p);\n         old->next = next;\n         next = old;\n         ++cached_blocks;\n      }\n   }\n   static mem_block_cache& instance()\n   {\n      static mem_block_cache block_cache;\n      return block_cache;\n   }\n};\n#endif\n#endif\n\n#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0\n\ninline void*  get_mem_block()\n{\n   return ::operator new(BOOST_REGEX_BLOCKSIZE);\n}\n\ninline void  put_mem_block(void* p)\n{\n   ::operator delete(p);\n}\n\n#else\n\ninline void*  get_mem_block()\n{\n   return mem_block_cache::instance().get();\n}\n\ninline void  put_mem_block(void* p)\n{\n   mem_block_cache::instance().put(p);\n}\n\n#endif\n}\n} // namespace boost\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/object_cache.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         object_cache.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Implements a generic object cache.\n  */\n\n#ifndef BOOST_REGEX_OBJECT_CACHE_HPP\n#define BOOST_REGEX_OBJECT_CACHE_HPP\n\n#include <boost/regex/config.hpp>\n#include <memory>\n#include <map>\n#include <list>\n#include <stdexcept>\n#include <string>\n#ifdef BOOST_HAS_THREADS\n#include <mutex>\n#endif\n\nnamespace boost{\n\ntemplate <class Key, class Object>\nclass object_cache\n{\npublic:\n   typedef std::pair< ::std::shared_ptr<Object const>, Key const*> value_type;\n   typedef std::list<value_type> list_type;\n   typedef typename list_type::iterator list_iterator;\n   typedef std::map<Key, list_iterator> map_type;\n   typedef typename map_type::iterator map_iterator;\n   typedef typename list_type::size_type size_type;\n   static std::shared_ptr<Object const> get(const Key& k, size_type l_max_cache_size);\n\nprivate:\n   static std::shared_ptr<Object const> do_get(const Key& k, size_type l_max_cache_size);\n\n   struct data\n   {\n      list_type   cont;\n      map_type    index;\n   };\n\n   // Needed by compilers not implementing the resolution to DR45. For reference,\n   // see http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.\n   friend struct data;\n};\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable: 4702)\n#endif\ntemplate <class Key, class Object>\nstd::shared_ptr<Object const> object_cache<Key, Object>::get(const Key& k, size_type l_max_cache_size)\n{\n#ifdef BOOST_HAS_THREADS\n   static std::mutex mut;\n   std::lock_guard<std::mutex> l(mut);\n   return do_get(k, l_max_cache_size);\n#else\n   return do_get(k, l_max_cache_size);\n#endif\n}\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\ntemplate <class Key, class Object>\nstd::shared_ptr<Object const> object_cache<Key, Object>::do_get(const Key& k, size_type l_max_cache_size)\n{\n   typedef typename object_cache<Key, Object>::data object_data;\n   typedef typename map_type::size_type map_size_type;\n   static object_data s_data;\n\n   //\n   // see if the object is already in the cache:\n   //\n   map_iterator mpos = s_data.index.find(k);\n   if(mpos != s_data.index.end())\n   {\n      //\n      // Eureka! \n      // We have a cached item, bump it up the list and return it:\n      //\n      if(--(s_data.cont.end()) != mpos->second)\n      {\n         // splice out the item we want to move:\n         list_type temp;\n         temp.splice(temp.end(), s_data.cont, mpos->second);\n         // and now place it at the end of the list:\n         s_data.cont.splice(s_data.cont.end(), temp, temp.begin());\n         BOOST_REGEX_ASSERT(*(s_data.cont.back().second) == k);\n         // update index with new position:\n         mpos->second = --(s_data.cont.end());\n         BOOST_REGEX_ASSERT(&(mpos->first) == mpos->second->second);\n         BOOST_REGEX_ASSERT(&(mpos->first) == s_data.cont.back().second);\n      }\n      return s_data.cont.back().first;\n   }\n   //\n   // if we get here then the item is not in the cache,\n   // so create it:\n   //\n   std::shared_ptr<Object const> result(new Object(k));\n   //\n   // Add it to the list, and index it:\n   //\n   s_data.cont.push_back(value_type(result, static_cast<Key const*>(0)));\n   s_data.index.insert(std::make_pair(k, --(s_data.cont.end())));\n   s_data.cont.back().second = &(s_data.index.find(k)->first);\n   map_size_type s = s_data.index.size();\n   BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());\n   BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);\n   BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);\n   if(s > l_max_cache_size)\n   {\n      //\n      // We have too many items in the list, so we need to start\n      // popping them off the back of the list, but only if they're\n      // being held uniquely by us:\n      //\n      list_iterator pos = s_data.cont.begin();\n      list_iterator last = s_data.cont.end();\n      while((pos != last) && (s > l_max_cache_size))\n      {\n         if(pos->first.use_count() == 1)\n         {\n            list_iterator condemmed(pos);\n            ++pos;\n            // now remove the items from our containers, \n            // then order has to be as follows:\n            BOOST_REGEX_ASSERT(s_data.index.find(*(condemmed->second)) != s_data.index.end());\n            s_data.index.erase(*(condemmed->second));\n            s_data.cont.erase(condemmed); \n            --s;\n         }\n         else\n            ++pos;\n      }\n      BOOST_REGEX_ASSERT(s_data.index[k]->first.get() == result.get());\n      BOOST_REGEX_ASSERT(&(s_data.index.find(k)->first) == s_data.cont.back().second);\n      BOOST_REGEX_ASSERT(s_data.index.find(k)->first == k);\n   }\n   return result;\n}\n\n}\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/pattern_except.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         pattern_except.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares pattern-matching exception classes.\n  */\n\n#ifndef BOOST_RE_V5_PAT_EXCEPT_HPP\n#define BOOST_RE_V5_PAT_EXCEPT_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#include <cstddef>\n#include <stdexcept>\n#include <boost/regex/v5/error_type.hpp>\n#include <boost/regex/v5/regex_traits_defaults.hpp>\n\nnamespace boost{\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable : 4275)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable : 26812 4459)\n#endif\n#endif\nclass regex_error : public std::runtime_error\n{\npublic:\n   explicit regex_error(const std::string& s, regex_constants::error_type err = regex_constants::error_unknown, std::ptrdiff_t pos = 0)\n      : std::runtime_error(s)\n      , m_error_code(err)\n      , m_position(pos)\n   {\n   }\n   explicit regex_error(regex_constants::error_type err)\n      : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))\n      , m_error_code(err)\n      , m_position(0)\n   {\n   }\n   ~regex_error() noexcept override {}\n   regex_constants::error_type code()const\n   { return m_error_code; }\n   std::ptrdiff_t position()const\n   { return m_position; }\n   void raise()const \n   {\n#ifndef BOOST_NO_EXCEPTIONS\n#ifndef BOOST_REGEX_STANDALONE\n      ::boost::throw_exception(*this);\n#else\n      throw* this;\n#endif\n#endif\n   }\nprivate:\n   regex_constants::error_type m_error_code;\n   std::ptrdiff_t m_position;\n};\n\ntypedef regex_error bad_pattern;\ntypedef regex_error bad_expression;\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class E>\ninline void raise_runtime_error(const E& ex)\n{\n#ifndef BOOST_REGEX_STANDALONE\n   ::boost::throw_exception(ex);\n#else\n   throw ex;\n#endif\n}\n\ntemplate <class traits>\nvoid raise_error(const traits& t, regex_constants::error_type code)\n{\n   (void)t;  // warning suppression\n   regex_error e(t.error_string(code), code, 0);\n   ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e);\n}\n\n}\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/perl_matcher.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n#ifndef BOOST_REGEX_MATCHER_HPP\n#define BOOST_REGEX_MATCHER_HPP\n\n#include <boost/regex/v5/iterator_category.hpp>\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable : 4251 4459)\n#if BOOST_REGEX_MSVC < 1700\n#     pragma warning(disable : 4231)\n#endif\n#  if BOOST_REGEX_MSVC < 1600\n#     pragma warning(disable : 4660)\n#  endif\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// error checking API:\n//\ninline void  verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf)\n{\n   //\n   // can't mix match_extra with POSIX matching rules:\n   //\n   if ((mf & match_extra) && (mf & match_posix))\n   {\n      std::logic_error msg(\"Usage Error: Can't mix regular expression captures with POSIX matching rules\");\n#ifndef BOOST_REGEX_STANDALONE\n      throw_exception(msg);\n#else\n      throw msg;\n#endif\n   }\n}\n//\n// function can_start:\n//\ntemplate <class charT>\ninline bool can_start(charT c, const unsigned char* map, unsigned char mask)\n{\n   return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));\n}\ninline bool can_start(char c, const unsigned char* map, unsigned char mask)\n{\n   return map[(unsigned char)c] & mask;\n}\ninline bool can_start(signed char c, const unsigned char* map, unsigned char mask)\n{\n   return map[(unsigned char)c] & mask;\n}\ninline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)\n{\n   return map[c] & mask;\n}\ninline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)\n{\n   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);\n}\n#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\ninline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)\n{\n   return ((c >= static_cast<wchar_t>(1u << CHAR_BIT)) ? true : map[c] & mask);\n}\n#endif\n#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)\ninline bool can_start(unsigned int c, const unsigned char* map, unsigned char mask)\n{\n   return (((c >= static_cast<unsigned int>(1u << CHAR_BIT)) ? true : map[c] & mask));\n}\n#endif\n\ntemplate <class C, class T, class A>\ninline int string_compare(const std::basic_string<C,T,A>& s, const C* p)\n{ \n   if(0 == *p)\n   {\n      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))\n         return 0;\n   }\n   return s.compare(p); \n}\ntemplate <class Seq, class C>\ninline int string_compare(const Seq& s, const C* p)\n{\n   std::size_t i = 0;\n   while((i < s.size()) && (p[i] == s[i]))\n   {\n      ++i;\n   }\n   return (i == s.size()) ? -(int)p[i] : (int)s[i] - (int)p[i];\n}\n# define STR_COMP(s,p) string_compare(s,p)\n\ntemplate<class charT>\ninline const charT* re_skip_past_null(const charT* p)\n{\n  while (*p != static_cast<charT>(0)) ++p;\n  return ++p;\n}\n\ntemplate <class iterator, class charT, class traits_type, class char_classT>\niterator  re_is_set_member(iterator next, \n                          iterator last, \n                          const re_set_long<char_classT>* set_, \n                          const regex_data<charT, traits_type>& e, bool icase)\n{   \n   const charT* p = reinterpret_cast<const charT*>(set_+1);\n   iterator ptr;\n   unsigned int i;\n   //bool icase = e.m_flags & regex_constants::icase;\n\n   if(next == last) return next;\n\n   typedef typename traits_type::string_type traits_string_type;\n   const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);\n   \n   // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never\n   // referenced\n   (void)traits_inst;\n\n   // try and match a single character, could be a multi-character\n   // collating element...\n   for(i = 0; i < set_->csingles; ++i)\n   {\n      ptr = next;\n      if(*p == static_cast<charT>(0))\n      {\n         // treat null string as special case:\n         if(traits_inst.translate(*ptr, icase))\n         {\n            ++p;\n            continue;\n         }\n         return set_->isnot ? next : (ptr == next) ? ++next : ptr;\n      }\n      else\n      {\n         while(*p && (ptr != last))\n         {\n            if(traits_inst.translate(*ptr, icase) != *p)\n               break;\n            ++p;\n            ++ptr;\n         }\n\n         if(*p == static_cast<charT>(0)) // if null we've matched\n            return set_->isnot ? next : (ptr == next) ? ++next : ptr;\n\n         p = re_skip_past_null(p);     // skip null\n      }\n   }\n\n   charT col = traits_inst.translate(*next, icase);\n\n\n   if(set_->cranges || set_->cequivalents)\n   {\n      traits_string_type s1;\n      //\n      // try and match a range, NB only a single character can match\n      if(set_->cranges)\n      {\n         if((e.m_flags & regex_constants::collate) == 0)\n            s1.assign(1, col);\n         else\n         {\n            charT a[2] = { col, charT(0), };\n            s1 = traits_inst.transform(a, a + 1);\n         }\n         for(i = 0; i < set_->cranges; ++i)\n         {\n            if(STR_COMP(s1, p) >= 0)\n            {\n               do{ ++p; }while(*p);\n               ++p;\n               if(STR_COMP(s1, p) <= 0)\n                  return set_->isnot ? next : ++next;\n            }\n            else\n            {\n               // skip first string\n               do{ ++p; }while(*p);\n               ++p;\n            }\n            // skip second string\n            do{ ++p; }while(*p);\n            ++p;\n         }\n      }\n      //\n      // try and match an equivalence class, NB only a single character can match\n      if(set_->cequivalents)\n      {\n         charT a[2] = { col, charT(0), };\n         s1 = traits_inst.transform_primary(a, a +1);\n         for(i = 0; i < set_->cequivalents; ++i)\n         {\n            if(STR_COMP(s1, p) == 0)\n               return set_->isnot ? next : ++next;\n            // skip string\n            do{ ++p; }while(*p);\n            ++p;\n         }\n      }\n   }\n   if(traits_inst.isctype(col, set_->cclasses) == true)\n      return set_->isnot ? next : ++next;\n   if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))\n      return set_->isnot ? next : ++next;\n   return set_->isnot ? ++next : next;\n}\n\ntemplate <class BidiIterator>\nclass repeater_count\n{\n   repeater_count** stack;\n   repeater_count* next;\n   int state_id;\n   std::size_t count;        // the number of iterations so far\n   BidiIterator start_pos;   // where the last repeat started\n\n   repeater_count* unwind_until(int n, repeater_count* p, int current_recursion_id)\n   { \n      while(p && (p->state_id != n))\n      {\n         if(-2 - current_recursion_id == p->state_id)\n            return 0;\n         p = p->next;\n         if(p && (p->state_id < 0))\n         {\n            p = unwind_until(p->state_id, p, current_recursion_id);\n            if(!p)\n               return p;\n            p = p->next;\n         }\n      }\n      return p;\n   }\npublic:\n   repeater_count(repeater_count** s) : stack(s), next(0), state_id(-1), count(0), start_pos() {}\n   \n   repeater_count(int i, repeater_count** s, BidiIterator start, int current_recursion_id)\n      : start_pos(start)\n   {\n      state_id = i;\n      stack = s;\n      next = *stack;\n      *stack = this;\n      if((state_id > next->state_id) && (next->state_id >= 0))\n         count = 0;\n      else\n      {\n         repeater_count* p = next;\n         p = unwind_until(state_id, p, current_recursion_id);\n         if(p)\n         {\n            count = p->count;\n            start_pos = p->start_pos;\n         }\n         else\n            count = 0;\n      }\n   }\n   ~repeater_count()\n   {\n      if(next)\n         *stack = next;\n   }\n   std::size_t get_count() { return count; }\n   int get_id() { return state_id; }\n   std::size_t operator++() { return ++count; }\n   bool check_null_repeat(const BidiIterator& pos, std::size_t max)\n   {\n      // this is called when we are about to start a new repeat,\n      // if the last one was NULL move our count to max,\n      // otherwise save the current position.\n      bool result = (count == 0) ? false : (pos == start_pos);\n      if(result)\n         count = max;\n      else\n         start_pos = pos;\n      return result;\n   }\n};\n\nstruct saved_state;\n\nenum saved_state_type\n{\n   saved_type_end = 0,\n   saved_type_paren = 1,\n   saved_type_recurse = 2,\n   saved_type_assertion = 3,\n   saved_state_alt = 4,\n   saved_state_repeater_count = 5,\n   saved_state_extra_block = 6,\n   saved_state_greedy_single_repeat = 7,\n   saved_state_rep_slow_dot = 8,\n   saved_state_rep_fast_dot = 9,\n   saved_state_rep_char = 10,\n   saved_state_rep_short_set = 11,\n   saved_state_rep_long_set = 12,\n   saved_state_non_greedy_long_repeat = 13, \n   saved_state_count = 14\n};\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable:26495)\n#endif\n#endif\ntemplate <class Results>\nstruct recursion_info\n{\n   typedef typename Results::value_type value_type;\n   typedef typename value_type::iterator iterator;\n   int idx;\n   const re_syntax_base* preturn_address;\n   Results results;\n   repeater_count<iterator>* repeater_stack;\n   iterator location_of_start;\n};\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class BidiIterator, class Allocator, class traits>\nclass perl_matcher\n{\npublic:\n   typedef typename traits::char_type char_type;\n   typedef perl_matcher<BidiIterator, Allocator, traits> self_type;\n   typedef bool (self_type::*matcher_proc_type)();\n   typedef std::size_t traits_size_type;\n   typedef typename is_byte<char_type>::width_type width_type;\n   typedef typename std::iterator_traits<BidiIterator>::difference_type difference_type;\n   typedef match_results<BidiIterator, Allocator> results_type;\n\n   perl_matcher(BidiIterator first, BidiIterator end, \n      match_results<BidiIterator, Allocator>& what, \n      const basic_regex<char_type, traits>& e,\n      match_flag_type f,\n      BidiIterator l_base)\n      :  m_result(what), base(first), last(end), \n         position(first), backstop(l_base), re(e), traits_inst(e.get_traits()), \n         m_independent(false), next_count(&rep_obj), rep_obj(&next_count)\n      , m_recursions(0)\n   {\n      construct_init(e, f);\n   }\n\n   bool match();\n   bool find();\n\n   void setf(match_flag_type f)\n   { m_match_flags |= f; }\n   void unsetf(match_flag_type f)\n   { m_match_flags &= ~f; }\n\nprivate:\n   void construct_init(const basic_regex<char_type, traits>& e, match_flag_type f);\n\n   bool find_imp();\n   bool match_imp();\n   void estimate_max_state_count(std::random_access_iterator_tag*);\n   void estimate_max_state_count(void*);\n   bool match_prefix();\n   bool match_all_states();\n\n   // match procs, stored in s_match_vtable:\n   bool match_startmark();\n   bool match_endmark();\n   bool match_literal();\n   bool match_start_line();\n   bool match_end_line();\n   bool match_wild();\n   bool match_match();\n   bool match_word_boundary();\n   bool match_within_word();\n   bool match_word_start();\n   bool match_word_end();\n   bool match_buffer_start();\n   bool match_buffer_end();\n   bool match_backref();\n   bool match_long_set();\n   bool match_set();\n   bool match_jump();\n   bool match_alt();\n   bool match_rep();\n   bool match_combining();\n   bool match_soft_buffer_end();\n   bool match_restart_continue();\n   bool match_long_set_repeat();\n   bool match_set_repeat();\n   bool match_char_repeat();\n   bool match_dot_repeat_fast();\n   bool match_dot_repeat_slow();\n   bool match_dot_repeat_dispatch()\n   {\n      return ::boost::is_random_access_iterator<BidiIterator>::value ? match_dot_repeat_fast() : match_dot_repeat_slow();\n   }\n   bool match_backstep();\n   bool match_assert_backref();\n   bool match_toggle_case();\n   bool match_recursion();\n   bool match_fail();\n   bool match_accept();\n   bool match_commit();\n   bool match_then();\n   bool skip_until_paren(int index, bool match = true);\n\n   // find procs stored in s_find_vtable:\n   bool find_restart_any();\n   bool find_restart_word();\n   bool find_restart_line();\n   bool find_restart_buf();\n   bool find_restart_lit();\n\nprivate:\n   // final result structure to be filled in:\n   match_results<BidiIterator, Allocator>& m_result;\n   // temporary result for POSIX matches:\n   std::unique_ptr<match_results<BidiIterator, Allocator> > m_temp_match;\n   // pointer to actual result structure to fill in:\n   match_results<BidiIterator, Allocator>* m_presult;\n   // start of sequence being searched:\n   BidiIterator base;\n   // end of sequence being searched:\n   BidiIterator last; \n   // current character being examined:\n   BidiIterator position;\n   // where to restart next search after failed match attempt:\n   BidiIterator restart;\n   // where the current search started from, acts as base for $` during grep:\n   BidiIterator search_base;\n   // how far we can go back when matching lookbehind:\n   BidiIterator backstop;\n   // the expression being examined:\n   const basic_regex<char_type, traits>& re;\n   // the expression's traits class:\n   const ::boost::regex_traits_wrapper<traits>& traits_inst;\n   // the next state in the machine being matched:\n   const re_syntax_base* pstate;\n   // matching flags in use:\n   match_flag_type m_match_flags;\n   // how many states we have examined so far:\n   std::ptrdiff_t state_count;\n   // max number of states to examine before giving up:\n   std::ptrdiff_t max_state_count;\n   // whether we should ignore case or not:\n   bool icase;\n   // set to true when (position == last), indicates that we may have a partial match:\n   bool m_has_partial_match;\n   // set to true whenever we get a match:\n   bool m_has_found_match;\n   // set to true whenever we're inside an independent sub-expression:\n   bool m_independent;\n   // the current repeat being examined:\n   repeater_count<BidiIterator>* next_count;\n   // the first repeat being examined (top of linked list):\n   repeater_count<BidiIterator> rep_obj;\n   // the mask to pass when matching word boundaries:\n   typename traits::char_class_type m_word_mask;\n   // the bitmask to use when determining whether a match_any matches a newline or not:\n   unsigned char match_any_mask;\n   // recursion information:\n   std::vector<recursion_info<results_type> > recursion_stack;\n   //\n   // additional members for non-recursive version:\n   //\n   typedef bool (self_type::*unwind_proc_type)(bool);\n\n   void extend_stack();\n   bool unwind(bool);\n   bool unwind_end(bool);\n   bool unwind_paren(bool);\n   bool unwind_recursion_stopper(bool);\n   bool unwind_assertion(bool);\n   bool unwind_alt(bool);\n   bool unwind_repeater_counter(bool);\n   bool unwind_extra_block(bool);\n   bool unwind_greedy_single_repeat(bool);\n   bool unwind_slow_dot_repeat(bool);\n   bool unwind_fast_dot_repeat(bool);\n   bool unwind_char_repeat(bool);\n   bool unwind_short_set_repeat(bool);\n   bool unwind_long_set_repeat(bool);\n   bool unwind_non_greedy_repeat(bool);\n   bool unwind_recursion(bool);\n   bool unwind_recursion_pop(bool);\n   bool unwind_commit(bool);\n   bool unwind_then(bool);\n   bool unwind_case(bool);\n   void destroy_single_repeat();\n   void push_matched_paren(int index, const sub_match<BidiIterator>& sub);\n   void push_recursion_stopper();\n   void push_assertion(const re_syntax_base* ps, bool positive);\n   void push_alt(const re_syntax_base* ps);\n   void push_repeater_count(int i, repeater_count<BidiIterator>** s);\n   void push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id);\n   void push_non_greedy_repeat(const re_syntax_base* ps);\n   void push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2);\n   void push_recursion_pop();\n   void push_case_change(bool);\n\n   // pointer to base of stack:\n   saved_state* m_stack_base;\n   // pointer to current stack position:\n   saved_state* m_backup_state;\n   // how many memory blocks have we used up?:\n   unsigned used_block_count;\n   // determines what value to return when unwinding from recursion,\n   // allows for mixed recursive/non-recursive algorithm:\n   bool m_recursive_result;\n   // We have unwound to a lookahead/lookbehind, used by COMMIT/PRUNE/SKIP:\n   bool m_unwound_lookahead;\n   // We have unwound to an alternative, used by THEN:\n   bool m_unwound_alt;\n   // We are unwinding a commit - used by independent subs to determine whether to stop there or carry on unwinding:\n   //bool m_unwind_commit;\n   // Recursion limit:\n   unsigned m_recursions;\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#if BOOST_REGEX_MSVC >= 1800\n#pragma warning(disable:26495)\n#endif\n#endif\n   // these operations aren't allowed, so are declared private,\n   // bodies are provided to keep explicit-instantiation requests happy:\n   perl_matcher& operator=(const perl_matcher&)\n   {\n      return *this;\n   }\n   perl_matcher(const perl_matcher& that)\n      : m_result(that.m_result), re(that.re), traits_inst(that.traits_inst), rep_obj(0) {}\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n} // namespace boost\n\n//\n// include the implementation of perl_matcher:\n//\n#include <boost/regex/v5/perl_matcher_non_recursive.hpp>\n// this one has to be last:\n#include <boost/regex/v5/perl_matcher_common.hpp>\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/perl_matcher_common.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         perl_matcher_common.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Definitions of perl_matcher member functions that are \n  *                common to both the recursive and non-recursive versions.\n  */\n\n#ifndef BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP\n#define BOOST_REGEX_V5_PERL_MATCHER_COMMON_HPP\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable:4459)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable:26812)\n#endif\n   template <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)\n{ \n   typedef typename std::iterator_traits<BidiIterator>::iterator_category category;\n   typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;\n   \n   if(e.empty())\n   {\n      // precondition failure: e is not a valid regex.\n      std::invalid_argument ex(\"Invalid regular expression object\");\n#ifndef BOOST_REGEX_STANDALONE\n      boost::throw_exception(ex);\n#else\n      throw e;\n#endif\n   }\n   pstate = 0;\n   m_match_flags = f;\n   estimate_max_state_count(static_cast<category*>(0));\n   expression_flag_type re_f = re.flags();\n   icase = re_f & regex_constants::icase;\n   if(!(m_match_flags & (match_perl|match_posix)))\n   {\n      if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)\n         m_match_flags |= match_perl;\n      else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))\n         m_match_flags |= match_perl;\n      else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))\n         m_match_flags |= match_perl;\n      else\n         m_match_flags |= match_posix;\n   }\n   if(m_match_flags & match_posix)\n   {\n      m_temp_match.reset(new match_results<BidiIterator, Allocator>());\n      m_presult = m_temp_match.get();\n   }\n   else\n      m_presult = &m_result;\n   m_stack_base = 0;\n   m_backup_state = 0;\n   // find the value to use for matching word boundaries:\n   m_word_mask = re.get_data().m_word_mask; \n   // find bitmask to use for matching '.':\n   match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline);\n   // Disable match_any if requested in the state machine:\n   if(e.get_data().m_disable_match_any)\n      m_match_flags &= regex_constants::match_not_any;\n}\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)\n{\n   //\n   // How many states should we allow our machine to visit before giving up?\n   // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)\n   // where N is the length of the string, and S is the number of states\n   // in the machine.  It's tempting to up this to O(N^2S) or even O(N^2S^2)\n   // but these take unreasonably amounts of time to bale out in pathological\n   // cases.\n   //\n   // Calculate NS^2 first:\n   //\n   static const std::ptrdiff_t k = 100000;\n   std::ptrdiff_t dist = std::distance(base, last);\n   if(dist == 0)\n      dist = 1;\n   std::ptrdiff_t states = re.size();\n   if(states == 0)\n      states = 1;\n   if ((std::numeric_limits<std::ptrdiff_t>::max)() / states < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= states;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states += k;\n\n   max_state_count = states;\n\n   //\n   // Now calculate N^2:\n   //\n   states = dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states *= dist;\n   if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)\n   {\n      max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);\n      return;\n   }\n   states += k;\n   //\n   // N^2 can be a very large number indeed, to prevent things getting out\n   // of control, cap the max states:\n   //\n   if(states > BOOST_REGEX_MAX_STATE_COUNT)\n      states = BOOST_REGEX_MAX_STATE_COUNT;\n   //\n   // If (the possibly capped) N^2 is larger than our first estimate,\n   // use this instead:\n   //\n   if(states > max_state_count)\n      max_state_count = states;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)\n{\n   // we don't know how long the sequence is:\n   max_state_count = BOOST_REGEX_MAX_STATE_COUNT;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::match()\n{\n   return match_imp();\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_imp()\n{\n   // initialise our stack if we are non-recursive:\n   save_state_init init(&m_stack_base, &m_backup_state);\n   used_block_count = BOOST_REGEX_MAX_BLOCKS;\n#if !defined(BOOST_NO_EXCEPTIONS)\n   try{\n#endif\n\n   // reset our state machine:\n   position = base;\n   search_base = base;\n   state_count = 0;\n   m_match_flags |= regex_constants::match_all;\n   m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);\n   m_presult->set_base(base);\n   m_presult->set_named_subs(this->re.get_named_subs());\n   if(m_match_flags & match_posix)\n      m_result = *m_presult;\n   verify_options(re.flags(), m_match_flags);\n   if(0 == match_prefix())\n      return false;\n   return (m_result[0].second == last) && (m_result[0].first == base);\n\n#if !defined(BOOST_NO_EXCEPTIONS)\n   }\n   catch(...)\n   {\n      // unwind all pushed states, apart from anything else this\n      // ensures that all the states are correctly destructed\n      // not just the memory freed.\n      while(unwind(true)){}\n      throw;\n   }\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::find()\n{\n   return find_imp();\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_imp()\n{\n   static matcher_proc_type const s_find_vtable[7] = \n   {\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,\n      &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,\n   };\n\n   // initialise our stack if we are non-recursive:\n   save_state_init init(&m_stack_base, &m_backup_state);\n   used_block_count = BOOST_REGEX_MAX_BLOCKS;\n#if !defined(BOOST_NO_EXCEPTIONS)\n   try{\n#endif\n\n   state_count = 0;\n   if((m_match_flags & regex_constants::match_init) == 0)\n   {\n      // reset our state machine:\n      search_base = position = base;\n      pstate = re.get_first_state();\n      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);\n      m_presult->set_base(base);\n      m_presult->set_named_subs(this->re.get_named_subs());\n      m_match_flags |= regex_constants::match_init;\n   }\n   else\n   {\n      // start again:\n      search_base = position = m_result[0].second;\n      // If last match was null and match_not_null was not set then increment\n      // our start position, otherwise we go into an infinite loop:\n      if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))\n      {\n         if(position == last)\n            return false;\n         else \n            ++position;\n      }\n      // reset $` start:\n      m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);\n      //if((base != search_base) && (base == backstop))\n      //   m_match_flags |= match_prev_avail;\n   }\n   if(m_match_flags & match_posix)\n   {\n      m_result.set_size(static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);\n      m_result.set_base(base);\n   }\n\n   verify_options(re.flags(), m_match_flags);\n   // find out what kind of expression we have:\n   unsigned type = (m_match_flags & match_continuous) ? \n      static_cast<unsigned int>(regbase::restart_continue) \n         : static_cast<unsigned int>(re.get_restart_type());\n\n   // call the appropriate search routine:\n   matcher_proc_type proc = s_find_vtable[type];\n   return (this->*proc)();\n\n#if !defined(BOOST_NO_EXCEPTIONS)\n   }\n   catch(...)\n   {\n      // unwind all pushed states, apart from anything else this\n      // ensures that all the states are correctly destructed\n      // not just the memory freed.\n      while(unwind(true)){}\n      throw;\n   }\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()\n{\n   m_has_partial_match = false;\n   m_has_found_match = false;\n   pstate = re.get_first_state();\n   m_presult->set_first(position);\n   restart = position;\n   match_all_states();\n   if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))\n   {\n      m_has_found_match = true;\n      m_presult->set_second(last, 0, false);\n      position = last;\n      if((m_match_flags & match_posix) == match_posix)\n      {\n         m_result.maybe_assign(*m_presult);\n      }\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   if(m_has_found_match && (match_extra & m_match_flags))\n   {\n      //\n      // we have a match, reverse the capture information:\n      //\n      for(unsigned i = 0; i < m_presult->size(); ++i)\n      {\n         typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();\n         std::reverse(seq.begin(), seq.end());\n      }\n   }\n#endif\n   if(!m_has_found_match)\n      position = restart; // reset search postion\n   return m_has_found_match;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_literal()\n{\n   unsigned int len = static_cast<const re_literal*>(pstate)->length;\n   const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);\n   //\n   // compare string with what we stored in\n   // our records:\n   for(unsigned int i = 0; i < len; ++i, ++position)\n   {\n      if((position == last) || (traits_inst.translate(*position, icase) != what[i]))\n         return false;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()\n{\n   if(position == backstop)\n   {\n      if((m_match_flags & match_prev_avail) == 0)\n      {\n         if((m_match_flags & match_not_bol) == 0)\n         {\n            pstate = pstate->next.p;\n            return true;\n         }\n         return false;\n      }\n   }\n   else if(m_match_flags & match_single_line)\n      return false;\n\n   // check the previous value character:\n   BidiIterator t(position);\n   --t;\n   if(position != last)\n   {\n      if(is_separator(*t) && !((*t == static_cast<char_type>('\\r')) && (*position == static_cast<char_type>('\\n'))) )\n      {\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   else if(is_separator(*t))\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()\n{\n   if(position != last)\n   {\n      if(m_match_flags & match_single_line)\n         return false;\n      // we're not yet at the end so *first is always valid:\n      if(is_separator(*position))\n      {\n         if((position != backstop) || (m_match_flags & match_prev_avail))\n         {\n            // check that we're not in the middle of \\r\\n sequence\n            BidiIterator t(position);\n            --t;\n            if((*t == static_cast<char_type>('\\r')) && (*position == static_cast<char_type>('\\n')))\n            {\n               return false;\n            }\n         }\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   else if((m_match_flags & match_not_eol) == 0)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_wild()\n{\n   if(position == last) \n      return false;\n   if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))\n      return false;\n   if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))\n      return false;\n   pstate = pstate->next.p;\n   ++position;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()\n{\n   bool b; // indcates whether next character is a word character\n   if(position != last)\n   {\n      // prev and this character must be opposites:\n      b = traits_inst.isctype(*position, m_word_mask);\n   }\n   else\n   {\n      if (m_match_flags & match_not_eow)\n         return false;\n      b = false;\n   }\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n   {\n      if(m_match_flags & match_not_bow)\n         return false;\n      else\n         b ^= false;\n   }\n   else\n   {\n      --position;\n      b ^= traits_inst.isctype(*position, m_word_mask);\n      ++position;\n   }\n   if(b)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false; // no match if we get to here...\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()\n{\n   bool b = !match_word_boundary();\n   if(b)\n      pstate = pstate->next.p;\n   return b;\n   /*\n   if(position == last)\n      return false;\n   // both prev and this character must be m_word_mask:\n   bool prev = traits_inst.isctype(*position, m_word_mask);\n   {\n      bool b;\n      if((position == backstop) && ((m_match_flags & match_prev_avail) == 0)) \n         return false;\n      else\n      {\n         --position;\n         b = traits_inst.isctype(*position, m_word_mask);\n         ++position;\n      }\n      if(b == prev)\n      {\n         pstate = pstate->next.p;\n         return true;\n      }\n   }\n   return false;\n   */\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()\n{\n   if(position == last)\n      return false; // can't be starting a word if we're already at the end of input\n   if(!traits_inst.isctype(*position, m_word_mask))\n      return false; // next character isn't a word character\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n   {\n      if(m_match_flags & match_not_bow)\n         return false; // no previous input\n   }\n   else\n   {\n      // otherwise inside buffer:\n      BidiIterator t(position);\n      --t;\n      if(traits_inst.isctype(*t, m_word_mask))\n         return false; // previous character not non-word\n   }\n   // OK we have a match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()\n{\n   if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))\n      return false;  // start of buffer can't be end of word\n   BidiIterator t(position);\n   --t;\n   if(traits_inst.isctype(*t, m_word_mask) == false)\n      return false;  // previous character wasn't a word character\n\n   if(position == last)\n   {\n      if(m_match_flags & match_not_eow)\n         return false; // end of buffer but not end of word\n   }\n   else\n   {\n      // otherwise inside buffer:\n      if(traits_inst.isctype(*position, m_word_mask))\n         return false; // next character is a word character\n   }\n   pstate = pstate->next.p;\n   return true;      // if we fall through to here then we've succeeded\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()\n{\n   if((position != backstop) || (m_match_flags & match_not_bob))\n      return false;\n   // OK match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()\n{\n   if((position != last) || (m_match_flags & match_not_eob))\n      return false;\n   // OK match:\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_backref()\n{\n   //\n   // Compare with what we previously matched.\n   // Note that this succeeds if the backref did not partisipate\n   // in the match, this is in line with ECMAScript, but not Perl\n   // or PCRE.\n   //\n   int index = static_cast<const re_brace*>(pstate)->index;\n   if(index >= hash_value_mask)\n   {\n      named_subexpressions::range_type r = re.get_data().equal_range(index);\n      BOOST_REGEX_ASSERT(r.first != r.second);\n      do\n      {\n         index = r.first->index;\n         ++r.first;\n      }while((r.first != r.second) && ((*m_presult)[index].matched != true));\n   }\n\n   if((m_match_flags & match_perl) && !(*m_presult)[index].matched)\n      return false;\n\n   BidiIterator i = (*m_presult)[index].first;\n   BidiIterator j = (*m_presult)[index].second;\n   while(i != j)\n   {\n      if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))\n         return false;\n      ++i;\n      ++position;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()\n{\n   typedef typename traits::char_class_type char_class_type;\n   // let the traits class do the work:\n   if(position == last)\n      return false;\n   BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);\n   if(t != position)\n   {\n      pstate = pstate->next.p;\n      position = t;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_set()\n{\n   if(position == last)\n      return false;\n   if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n   {\n      pstate = pstate->next.p;\n      ++position;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_jump()\n{\n   pstate = static_cast<const re_jump*>(pstate)->alt.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_combining()\n{\n   if(position == last)\n      return false;\n   if(is_combining(traits_inst.translate(*position, icase)))\n      return false;\n   ++position;\n   while((position != last) && is_combining(traits_inst.translate(*position, icase)))\n      ++position;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()\n{\n   if(m_match_flags & match_not_eob)\n      return false;\n   BidiIterator p(position);\n   while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;\n   if(p != last)\n      return false;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()\n{\n   if(position == search_base)\n   {\n      pstate = pstate->next.p;\n      return true;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   if( ::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      std::ptrdiff_t maxlen = std::distance(backstop, position);\n      if(maxlen < static_cast<const re_brace*>(pstate)->index)\n         return false;\n      std::advance(position, -static_cast<const re_brace*>(pstate)->index);\n   }\n   else\n   {\n      int c = static_cast<const re_brace*>(pstate)->index;\n      while(c--)\n      {\n         if(position == backstop)\n            return false;\n         --position;\n      }\n   }\n   pstate = pstate->next.p;\n   return true;\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()\n{\n   // return true if marked sub-expression N has been matched:\n   int index = static_cast<const re_brace*>(pstate)->index;\n   bool result = false;\n   if(index == 9999)\n   {\n      // Magic value for a (DEFINE) block:\n      return false;\n   }\n   else if(index > 0)\n   {\n      // Have we matched subexpression \"index\"?\n      // Check if index is a hash value:\n      if(index >= hash_value_mask)\n      {\n         named_subexpressions::range_type r = re.get_data().equal_range(index);\n         while(r.first != r.second)\n         {\n            if((*m_presult)[r.first->index].matched)\n            {\n               result = true;\n               break;\n            }\n            ++r.first;\n         }\n      }\n      else\n      {\n         result = (*m_presult)[index].matched;\n      }\n      pstate = pstate->next.p;\n   }\n   else\n   {\n      // Have we recursed into subexpression \"index\"?\n      // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.\n      int idx = -(index+1);\n      if(idx >= hash_value_mask)\n      {\n         named_subexpressions::range_type r = re.get_data().equal_range(idx);\n         int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;\n         while(r.first != r.second)\n         {\n            result |= (stack_index == r.first->index);\n            if(result)break;\n            ++r.first;\n         }\n      }\n      else\n      {\n         result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));\n      }\n      pstate = pstate->next.p;\n   }\n   return result;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_fail()\n{\n   // Just force a backtrack:\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_accept()\n{\n   if(!recursion_stack.empty())\n   {\n      return skip_until_paren(recursion_stack.back().idx);\n   }\n   else\n   {\n      return skip_until_paren(INT_MAX);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   const unsigned char* _map = re.get_map();\n   while(true)\n   {\n      // skip everything we can't match:\n      while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )\n         ++position;\n      if(position == last)\n      {\n         // run out of characters, try a null match if possible:\n         if(re.can_be_null())\n            return match_prefix();\n         break;\n      }\n      // now try and obtain a match:\n      if(match_prefix())\n         return true;\n      if(position == last)\n         return false;\n      ++position;\n   }\n   return false;\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n   // do search optimised for word starts:\n   const unsigned char* _map = re.get_map();\n   if((m_match_flags & match_prev_avail) || (position != base))\n      --position;\n   else if(match_prefix())\n      return true;\n   do\n   {\n      while((position != last) && traits_inst.isctype(*position, m_word_mask))\n         ++position;\n      while((position != last) && !traits_inst.isctype(*position, m_word_mask))\n         ++position;\n      if(position == last)\n         break;\n\n      if(can_start(*position, _map, (unsigned char)mask_any) )\n      {\n         if(match_prefix())\n            return true;\n      }\n      if(position == last)\n         break;\n   } while(true);\n   return false;\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()\n{\n   // do search optimised for line starts:\n   const unsigned char* _map = re.get_map();\n   if(match_prefix())\n      return true;\n   while(position != last)\n   {\n      while((position != last) && !is_separator(*position))\n         ++position;\n      if(position == last)\n         return false;\n      ++position;\n      if(position == last)\n      {\n         if(re.can_be_null() && match_prefix())\n            return true;\n         return false;\n      }\n\n      if( can_start(*position, _map, (unsigned char)mask_any) )\n      {\n         if(match_prefix())\n            return true;\n      }\n      if(position == last)\n         return false;\n      //++position;\n   }\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()\n{\n   if((position == base) && ((m_match_flags & match_not_bob) == 0))\n      return match_prefix();\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()\n{\n   return false;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/perl_matcher_non_recursive.hpp",
    "content": "/*\n *\n * Copyright (c) 2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         perl_matcher_common.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Definitions of perl_matcher member functions that are \n  *                specific to the non-recursive implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_PERL_MATCHER_NON_RECURSIVE_HPP\n#define BOOST_REGEX_V5_PERL_MATCHER_NON_RECURSIVE_HPP\n\n#include <boost/regex/v5/mem_block_cache.hpp>\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#  pragma warning(disable: 4706 4459)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class T>\ninline void inplace_destroy(T* p)\n{\n   (void)p;  // warning suppression\n   p->~T();\n}\n\nstruct saved_state\n{\n   union{\n      unsigned int state_id;\n      // this padding ensures correct alignment on 64-bit platforms:\n      std::size_t padding1;\n      std::ptrdiff_t padding2;\n      void* padding3;\n   };\n   saved_state(unsigned i) : state_id(i) {}\n};\n\ntemplate <class BidiIterator>\nstruct saved_matched_paren : public saved_state\n{\n   int index;\n   sub_match<BidiIterator> sub;\n   saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_position : public saved_state\n{\n   const re_syntax_base* pstate;\n   BidiIterator position;\n   saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_assertion : public saved_position<BidiIterator>\n{\n   bool positive;\n   saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos) \n      : saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){}\n};\n\ntemplate <class BidiIterator>\nstruct saved_repeater : public saved_state\n{\n   repeater_count<BidiIterator> count;\n   saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start, int current_recursion_id)\n      : saved_state(saved_state_repeater_count), count(i, s, start, current_recursion_id){}\n};\n\nstruct saved_extra_block : public saved_state\n{\n   saved_state *base, *end;\n   saved_extra_block(saved_state* b, saved_state* e) \n      : saved_state(saved_state_extra_block), base(b), end(e) {}\n};\n\nstruct save_state_init\n{\n   saved_state** stack;\n   save_state_init(saved_state** base, saved_state** end)\n      : stack(base)\n   {\n      *base = static_cast<saved_state*>(get_mem_block());\n      *end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+BOOST_REGEX_BLOCKSIZE);\n      --(*end);\n      (void) new (*end)saved_state(0);\n      BOOST_REGEX_ASSERT(*end > *base);\n   }\n   ~save_state_init()\n   {\n      put_mem_block(*stack);\n      *stack = 0;\n   }\n};\n\ntemplate <class BidiIterator>\nstruct saved_single_repeat : public saved_state\n{\n   std::size_t count;\n   const re_repeat* rep;\n   BidiIterator last_position;\n   saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id) \n      : saved_state(arg_id), count(c), rep(r), last_position(lp){}\n};\n\ntemplate <class Results>\nstruct saved_recursion : public saved_state\n{\n   saved_recursion(int idx, const re_syntax_base* p, Results* pr, Results* pr2) \n      : saved_state(14), recursion_id(idx), preturn_address(p), internal_results(*pr), prior_results(*pr2) {}\n   int recursion_id;\n   const re_syntax_base* preturn_address;\n   Results internal_results, prior_results;\n};\n\nstruct saved_change_case : public saved_state\n{\n   bool icase;\n   saved_change_case(bool c) : saved_state(18), icase(c) {}\n};\n\nstruct incrementer\n{\n   incrementer(unsigned* pu) : m_pu(pu) { ++*m_pu; }\n   ~incrementer() { --*m_pu; }\n   bool operator > (unsigned i) { return *m_pu > i; }\nprivate:\n   unsigned* m_pu;\n};\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()\n{\n   static matcher_proc_type const s_match_vtable[34] = \n   {\n      (&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_endmark,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_literal,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_start_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_end_line,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_wild,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_match,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_within_word,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_word_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_jump,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_alt,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_rep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_combining,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,\n      // Although this next line *should* be evaluated at compile time, in practice\n      // some compilers (VC++) emit run-time initialisation which breaks thread\n      // safety, so use a dispatch function instead:\n      //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),\n      &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_backstep,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_fail,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_accept,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_commit,\n      &perl_matcher<BidiIterator, Allocator, traits>::match_then,\n   };\n   incrementer inc(&m_recursions);\n   if(inc > 80)\n      raise_error(traits_inst, regex_constants::error_complexity);\n   push_recursion_stopper();\n   do{\n      while(pstate)\n      {\n         matcher_proc_type proc = s_match_vtable[pstate->type];\n         ++state_count;\n         if(!(this->*proc)())\n         {\n            if(state_count > max_state_count)\n               raise_error(traits_inst, regex_constants::error_complexity);\n            if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n               m_has_partial_match = true;\n            bool successful_unwind = unwind(false);\n            if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n               m_has_partial_match = true;\n            if(!successful_unwind)\n               return m_recursive_result;\n         }\n      }\n   }while(unwind(true));\n   return m_recursive_result;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::extend_stack()\n{\n   if(used_block_count)\n   {\n      --used_block_count;\n      saved_state* stack_base;\n      saved_state* backup_state;\n      stack_base = static_cast<saved_state*>(get_mem_block());\n      backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+BOOST_REGEX_BLOCKSIZE);\n      saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);\n      --block;\n      (void) new (block) saved_extra_block(m_stack_base, m_backup_state);\n      m_stack_base = stack_base;\n      m_backup_state = block;\n   }\n   else\n      raise_error(traits_inst, regex_constants::error_stack);\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)\n{\n   //BOOST_REGEX_ASSERT(index);\n   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_case_change(bool c)\n{\n   //BOOST_REGEX_ASSERT(index);\n   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_change_case*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_change_case(c);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()\n{\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(saved_type_recurse);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)\n{\n   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)\n{\n   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_repeater<BidiIterator>(i, s, position, this->recursion_stack.empty() ? (INT_MIN + 3) : this->recursion_stack.back().idx);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults, results_type* presults2)\n{\n   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_recursion<results_type>(idx, p, presults, presults2);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()\n{\n   // change our case sensitivity:\n   push_case_change(this->icase);\n   this->icase = static_cast<const re_case*>(pstate)->icase;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   switch(index)\n   {\n   case 0:\n      pstate = pstate->next.p;\n      break;\n   case -1:\n   case -2:\n      {\n         // forward lookahead assert:\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         push_assertion(next_pstate, index == -1);\n         break;\n      }\n   case -3:\n      {\n         // independent sub-expression, currently this is always recursive:\n         bool old_independent = m_independent;\n         m_independent = true;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n         bool r = false;\n#if !defined(BOOST_NO_EXCEPTIONS)\n      try{\n#endif\n         r = match_all_states();\n         if(!r && !m_independent)\n         {\n            // Must be unwinding from a COMMIT/SKIP/PRUNE and the independent \n            // sub failed, need to unwind everything else:\n            while (m_backup_state->state_id)\n               unwind(false);\n            return false;\n         }\n#if !defined(BOOST_NO_EXCEPTIONS)\n      }\n      catch(...)\n      {\n         pstate = next_pstate;\n         // unwind all pushed states, apart from anything else this\n         // ensures that all the states are correctly destructed\n         // not just the memory freed.\n         while(unwind(true)) {}\n         throw;\n      }\n#endif\n      pstate = next_pstate;\n      m_independent = old_independent;\n#ifdef BOOST_REGEX_MATCH_EXTRA\n         if(r && (m_match_flags & match_extra))\n         {\n            //\n            // our captures have been stored in *m_presult\n            // we need to unpack them, and insert them\n            // back in the right order when we unwind the stack:\n            //\n            match_results<BidiIterator, Allocator> temp_match(*m_presult);\n            unsigned i;\n            for(i = 0; i < temp_match.size(); ++i)\n               (*m_presult)[i].get_captures().clear();\n            // match everything else:\n#if !defined(BOOST_NO_EXCEPTIONS)\n            try{\n#endif\n               r = match_all_states();\n#if !defined(BOOST_NO_EXCEPTIONS)\n            }\n            catch(...)\n            {\n               pstate = next_pstate;\n               // unwind all pushed states, apart from anything else this\n               // ensures that all the states are correctly destructed\n               // not just the memory freed.\n               while(unwind(true)) {}\n               throw;\n            }\n#endif\n         // now place the stored captures back:\n            for(i = 0; i < temp_match.size(); ++i)\n            {\n               typedef typename sub_match<BidiIterator>::capture_sequence_type seq;\n               seq& s1 = (*m_presult)[i].get_captures();\n               const seq& s2 = temp_match[i].captures();\n               s1.insert(\n                  s1.end(), \n                  s2.begin(), \n                  s2.end());\n            }\n         }\n#endif\n         return r;\n      }\n   case -4:\n      {\n      // conditional expression:\n      const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);\n      BOOST_REGEX_ASSERT(alt->type == syntax_element_alt);\n      pstate = alt->next.p;\n      if(pstate->type == syntax_element_assert_backref)\n      {\n         if(!match_assert_backref())\n            pstate = alt->alt.p;\n         break;\n      }\n      else\n      {\n         // zero width assertion, have to match this recursively:\n         BOOST_REGEX_ASSERT(pstate->type == syntax_element_startmark);\n         bool negated = static_cast<const re_brace*>(pstate)->index == -2;\n         BidiIterator saved_position = position;\n         const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;\n         pstate = pstate->next.p->next.p;\n#if !defined(BOOST_NO_EXCEPTIONS)\n         try{\n#endif\n            bool r = match_all_states();\n            position = saved_position;\n            if(negated)\n               r = !r;\n            if(r)\n               pstate = next_pstate;\n            else\n               pstate = alt->alt.p;\n#if !defined(BOOST_NO_EXCEPTIONS)\n         }\n         catch(...)\n         {\n            pstate = next_pstate;\n            // unwind all pushed states, apart from anything else this\n            // ensures that all the states are correctly destructed\n            // not just the memory freed.\n            while(unwind(true)){}\n            throw;\n         }\n#endif\n         break;\n      }\n      }\n   case -5:\n      {\n         push_matched_paren(0, (*m_presult)[0]);\n         m_presult->set_first(position, 0, true);\n         pstate = pstate->next.p;\n         break;\n      }\n   default:\n   {\n      BOOST_REGEX_ASSERT(index > 0);\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         push_matched_paren(index, (*m_presult)[index]);\n         m_presult->set_first(position, index);\n      }\n      pstate = pstate->next.p;\n      break;\n   }\n   }\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_alt()\n{\n   bool take_first, take_second;\n   const re_alt* jmp = static_cast<const re_alt*>(pstate);\n\n   // find out which of these two alternatives we need to take:\n   if(position == last)\n   {\n      take_first = jmp->can_be_null & mask_take;\n      take_second = jmp->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);\n  }\n\n   if(take_first)\n   {\n      // we can take the first alternative,\n      // see if we need to push next alternative:\n      if(take_second)\n      {\n         push_alt(jmp->alt.p);\n      }\n      pstate = pstate->next.p;\n      return true;\n   }\n   if(take_second)\n   {\n      pstate = jmp->alt.p;\n      return true;\n   }\n   return false;  // neither option is possible\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_rep()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127 4244)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n\n   // find out which of these two alternatives we need to take:\n   bool take_first, take_second;\n   if(position == last)\n   {\n      take_first = rep->can_be_null & mask_take;\n      take_second = rep->can_be_null & mask_skip;\n   }\n   else\n   {\n      take_first = can_start(*position, rep->_map, (unsigned char)mask_take);\n      take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);\n   }\n\n   if((m_backup_state->state_id != saved_state_repeater_count) \n      || (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)\n      || (next_count->get_id() != rep->state_id))\n   {\n      // we're moving to a different repeat from the last\n      // one, so set up a counter object:\n      push_repeater_count(rep->state_id, &next_count);\n   }\n   //\n   // If we've had at least one repeat already, and the last one \n   // matched the NULL string then set the repeat count to\n   // maximum:\n   //\n   next_count->check_null_repeat(position, rep->max);\n\n   if(next_count->get_count() < rep->min)\n   {\n      // we must take the repeat:\n      if(take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n      return false;\n   }\n\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // try and take the repeat if we can:\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         if(take_second)\n         {\n            // store position in case we fail:\n            push_alt(rep->alt.p);\n         }\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n      else if(take_second)\n      {\n         pstate = rep->alt.p;\n         return true;\n      }\n      return false; // can't take anything, fail...\n   }\n   else // non-greedy\n   {\n      // try and skip the repeat if we can:\n      if(take_second)\n      {\n         if((next_count->get_count() < rep->max) && take_first)\n         {\n            // store position in case we fail:\n            push_non_greedy_repeat(rep->next.p);\n         }\n         pstate = rep->alt.p;\n         return true;\n      }\n      if((next_count->get_count() < rep->max) && take_first)\n      {\n         // increase the counter:\n         ++(*next_count);\n         pstate = rep->next.p;\n         return true;\n      }\n   }\n   return false;\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()\n{\n   std::size_t count = 0;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   re_syntax_base* psingle = rep->next.p;\n   // match compulsory repeats first:\n   while(count < rep->min)\n   {\n      pstate = psingle;\n      if(!match_wild())\n         return false;\n      ++count;\n   }\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   if(greedy)\n   {\n      // repeat for as long as we can:\n      while(count < rep->max)\n      {\n         pstate = psingle;\n         if(!match_wild())\n            break;\n         ++count;\n      }\n      // remember where we got to if this is a leading repeat:\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_slow_dot);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()\n{\n   if(m_match_flags & match_not_dot_null)\n      return match_dot_repeat_slow();\n   if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)\n      return match_dot_repeat_slow();\n\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t count = static_cast<std::size_t>((std::min)(static_cast<std::size_t>(std::distance(position, last)), greedy ? rep->max : rep->min));\n   if(rep->min > count)\n   {\n      position = last;\n      return false;  // not enough text left to match\n   }\n   std::advance(position, count);\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_fast_dot);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   BOOST_REGEX_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);\n   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && (traits_inst.translate(*position, icase) == what))\n      {\n         ++position;\n      }\n      count = (unsigned)std::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_char);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n      }\n      count = (unsigned)std::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_short_set);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()\n{\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4127)\n#endif\n#ifdef BOOST_BORLANDC\n#pragma option push -w-8008 -w-8066 -w-8004\n#endif\n   typedef typename traits::char_class_type m_type;\n   const re_repeat* rep = static_cast<const re_repeat*>(pstate);\n   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate->next.p);\n   std::size_t count = 0;\n   //\n   // start by working out how much we can skip:\n   //\n   bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);   \n   std::size_t desired = greedy ? rep->max : rep->min;\n   if(::boost::is_random_access_iterator<BidiIterator>::value)\n   {\n      BidiIterator end = position;\n      // Move end forward by \"desired\", preferably without using distance or advance if we can\n      // as these can be slow for some iterator types.\n      std::size_t len = (desired == (std::numeric_limits<std::size_t>::max)()) ? 0u : std::distance(position, last);\n      if(desired >= len)\n         end = last;\n      else\n         std::advance(end, desired);\n      BidiIterator origin(position);\n      while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n      }\n      count = (unsigned)std::distance(origin, position);\n   }\n   else\n   {\n      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))\n      {\n         ++position;\n         ++count;\n      }\n   }\n\n   if(count < rep->min)\n      return false;\n\n   if(greedy)\n   {\n      if((rep->leading) && (count < rep->max))\n         restart = position;\n      // push backtrack info if available:\n      if(count - rep->min)\n         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);\n      // jump to next state:\n      pstate = rep->alt.p;\n      return true;\n   }\n   else\n   {\n      // non-greedy, push state and return true if we can skip:\n      if(count < rep->max)\n         push_single_repeat(count, rep, position, saved_state_rep_long_set);\n      pstate = rep->alt.p;\n      return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);\n   }\n#ifdef BOOST_BORLANDC\n#pragma option pop\n#endif\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()\n{\n   BOOST_REGEX_ASSERT(pstate->type == syntax_element_recurse);\n   //\n   // See if we've seen this recursion before at this location, if we have then\n   // we need to prevent infinite recursion:\n   //\n   for(typename std::vector<recursion_info<results_type> >::reverse_iterator i = recursion_stack.rbegin(); i != recursion_stack.rend(); ++i)\n   {\n      if(i->idx == static_cast<const re_brace*>(static_cast<const re_jump*>(pstate)->alt.p)->index)\n      {\n         if(i->location_of_start == position)\n            return false;\n         break;\n      }\n   }\n   //\n   // Backup call stack:\n   //\n   push_recursion_pop();\n   //\n   // Set new call stack:\n   //\n   if(recursion_stack.capacity() == 0)\n   {\n      recursion_stack.reserve(50);\n   }\n   recursion_stack.push_back(recursion_info<results_type>());\n   recursion_stack.back().preturn_address = pstate->next.p;\n   recursion_stack.back().results = *m_presult;\n   pstate = static_cast<const re_jump*>(pstate)->alt.p;\n   recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;\n   recursion_stack.back().location_of_start = position;\n   //if(static_cast<const re_recurse*>(pstate)->state_id > 0)\n   {\n      push_repeater_count(-(2 + static_cast<const re_brace*>(pstate)->index), &next_count);\n   }\n\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()\n{\n   int index = static_cast<const re_brace*>(pstate)->index;\n   icase = static_cast<const re_brace*>(pstate)->icase;\n   if(index > 0)\n   {\n      if((m_match_flags & match_nosubs) == 0)\n      {\n         m_presult->set_second(position, index);\n      }\n      if(!recursion_stack.empty())\n      {\n         if(index == recursion_stack.back().idx)\n         {\n            pstate = recursion_stack.back().preturn_address;\n            *m_presult = recursion_stack.back().results;\n            push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);\n            recursion_stack.pop_back();\n            push_repeater_count(-(2 + index), &next_count);\n         }\n      }\n   }\n   else if((index < 0) && (index != -4))\n   {\n      // matched forward lookahead:\n      pstate = 0;\n      return true;\n   }\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_match()\n{\n   if(!recursion_stack.empty())\n   {\n      BOOST_REGEX_ASSERT(0 == recursion_stack.back().idx);\n      pstate = recursion_stack.back().preturn_address;\n      push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, m_presult, &recursion_stack.back().results);\n      *m_presult = recursion_stack.back().results;\n      recursion_stack.pop_back();\n      return true;\n   }\n   if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))\n      return false;\n   if((m_match_flags & match_all) && (position != last))\n      return false;\n   if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))\n      return false;\n   m_presult->set_second(position);\n   pstate = 0;\n   m_has_found_match = true;\n   if((m_match_flags & match_posix) == match_posix)\n   {\n      m_result.maybe_assign(*m_presult);\n      if((m_match_flags & match_any) == 0)\n         return false;\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   if(match_extra & m_match_flags)\n   {\n      for(unsigned i = 0; i < m_presult->size(); ++i)\n         if((*m_presult)[i].matched)\n            ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);\n   }\n#endif\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_commit()\n{\n   // Ideally we would just junk all the states that are on the stack,\n   // however we might not unwind correctly in that case, so for now,\n   // just mark that we don't backtrack into whatever is left (or rather\n   // we'll unwind it unconditionally without pausing to try other matches).\n\n   switch(static_cast<const re_commit*>(pstate)->action)\n   {\n   case commit_commit:\n      restart = last;\n      break;\n   case commit_skip:\n      if(base != position)\n      {\n         restart = position;\n         // Have to decrement restart since it will get incremented again later:\n         --restart;\n      }\n      break;\n   case commit_prune:\n      break;\n   }\n\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(16);\n   m_backup_state = pmp;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::match_then()\n{\n   // Just leave a mark that we need to skip to next alternative:\n   saved_state* pmp = m_backup_state;\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = m_backup_state;\n      --pmp;\n   }\n   (void) new (pmp)saved_state(17);\n   m_backup_state = pmp;\n   pstate = pstate->next.p;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool have_match)\n{\n   while(pstate)\n   {\n      if(pstate->type == syntax_element_endmark)\n      {\n         if(static_cast<const re_brace*>(pstate)->index == index)\n         {\n            if(have_match)\n               return this->match_endmark();\n            pstate = pstate->next.p;\n            return true;\n         }\n         else\n         {\n            // Unenclosed closing ), occurs when (*ACCEPT) is inside some other \n            // parenthesis which may or may not have other side effects associated with it.\n            const re_syntax_base* sp = pstate;\n            match_endmark();\n            if(!pstate)\n            {\n               unwind(true);\n               // unwind may leave pstate NULL if we've unwound a forward lookahead, in which\n               // case just move to the next state and keep looking...\n               if (!pstate)\n                  pstate = sp->next.p;\n            }\n         }\n         continue;\n      }\n      else if(pstate->type == syntax_element_match)\n         return true;\n      else if(pstate->type == syntax_element_startmark)\n      {\n         int idx = static_cast<const re_brace*>(pstate)->index;\n         pstate = pstate->next.p;\n         skip_until_paren(idx, false);\n         continue;\n      }\n      pstate = pstate->next.p;\n   }\n   return true;\n}\n\n/****************************************************************************\n\nUnwind and associated procedures follow, these perform what normal stack\nunwinding does in the recursive implementation.\n\n****************************************************************************/\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)\n{\n   static unwind_proc_type const s_unwind_table[19] = \n   {\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_end,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_commit,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_then,\n      &perl_matcher<BidiIterator, Allocator, traits>::unwind_case,\n   };\n\n   m_recursive_result = have_match;\n   m_unwound_lookahead = false;\n   m_unwound_alt = false;\n   unwind_proc_type unwinder;\n   bool cont;\n   //\n   // keep unwinding our stack until we have something to do:\n   //\n   do\n   {\n      unwinder = s_unwind_table[m_backup_state->state_id];\n      cont = (this->*unwinder)(m_recursive_result);\n   }while(cont);\n   //\n   // return true if we have more states to try:\n   //\n   return pstate ? true : false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)\n{\n   pstate = 0;   // nothing left to search\n   return false; // end of stack nothing more to search\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_case(bool)\n{\n   saved_change_case* pmp = static_cast<saved_change_case*>(m_backup_state);\n   icase = pmp->icase;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)\n{\n   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);\n   // restore previous values if no match was found:\n   if(!have_match)\n   {\n      m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);\n      m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);\n   }\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   //\n   // we have a match, push the capture information onto the stack:\n   //\n   else if(pmp->sub.matched && (match_extra & m_match_flags))\n      ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);\n#endif\n   // unwind stack:\n   m_backup_state = pmp+1;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)\n{\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   pstate = 0;   // nothing left to search\n   return false; // end of stack nothing more to search\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)\n{\n   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);\n   pstate = pmp->pstate;\n   position = pmp->position;\n   bool result = (r == pmp->positive);\n   m_recursive_result = pmp->positive ? r : !r;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   m_unwound_lookahead = true;\n   return !result; // return false if the assertion was matched to stop search.\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   if(!r)\n   {\n      pstate = pmp->pstate;\n      position = pmp->position;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   m_unwound_alt = !r;\n   return r; \n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)\n{\n   saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)\n{\n   ++used_block_count;\n   saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);\n   void* condemmed = m_stack_base;\n   m_stack_base = pmp->base;\n   m_backup_state = pmp->end;\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp);\n   put_mem_block(condemmed);\n   return true; // keep looking\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\ninline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()\n{\n   saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(p++);\n   m_backup_state = p;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n\n   count -= rep->min;\n   \n   if((m_match_flags & match_partial) && (position == last))\n      m_has_partial_match = true;\n\n   BOOST_REGEX_ASSERT(count);\n   position = pmp->last_position;\n\n   // backtrack till we can skip out:\n   do\n   {\n      --position;\n      --count;\n      ++state_count;\n   }while(count && !can_start(*position, rep->_map, mask_skip));\n\n   // if we've hit base, destroy this state:\n   if(count == 0)\n   {\n         destroy_single_repeat();\n         if(!can_start(*position, rep->_map, mask_skip))\n            return true;\n   }\n   else\n   {\n      pmp->count = count + rep->min;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_dot_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_wild);\n\n   BOOST_REGEX_ASSERT(count < rep->max);\n   pstate = rep->next.p;\n   position = pmp->last_position;\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(!match_wild())\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n\n   BOOST_REGEX_ASSERT(count < rep->max);\n   position = pmp->last_position;\n   if(position != last)\n   {\n\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         ++position;\n         ++count;\n         ++state_count;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }\n\n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_char_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_literal);\n   BOOST_REGEX_ASSERT(count < rep->max);\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(traits_inst.translate(*position, icase) != what)\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++ position;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)\n{\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r) \n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_short_set_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_set);\n   BOOST_REGEX_ASSERT(count < rep->max);\n   \n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++count;\n         ++ position;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)\n{\n   typedef typename traits::char_class_type m_type;\n   saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);\n\n   // if we have a match, just discard this state:\n   if(r)\n   {\n      destroy_single_repeat();\n      return true;\n   }\n\n   const re_repeat* rep = pmp->rep;\n   std::size_t count = pmp->count;\n   pstate = rep->next.p;\n   const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate);\n   position = pmp->last_position;\n\n   BOOST_REGEX_ASSERT(rep->type == syntax_element_long_set_rep);\n   BOOST_REGEX_ASSERT(rep->next.p != 0);\n   BOOST_REGEX_ASSERT(rep->alt.p != 0);\n   BOOST_REGEX_ASSERT(rep->next.p->type == syntax_element_long_set);\n   BOOST_REGEX_ASSERT(count < rep->max);\n\n   if(position != last)\n   {\n      // wind forward until we can skip out of the repeat:\n      do\n      {\n         if(position == re_is_set_member(position, last, set, re.get_data(), icase))\n         {\n            // failed repeat match, discard this state and look for another:\n            destroy_single_repeat();\n            return true;\n         }\n         ++position;\n         ++count;\n         ++state_count;\n         pstate = rep->next.p;\n      }while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));\n   }   \n   // remember where we got to if this is a leading repeat:\n   if((rep->leading) && (count < rep->max))\n      restart = position;\n   if(position == last)\n   {\n      // can't repeat any more, remove the pushed state:\n      destroy_single_repeat();\n      if((m_match_flags & match_partial) && (position == last) && (position != search_base))\n         m_has_partial_match = true;\n      if(0 == (rep->can_be_null & mask_skip))\n         return true;\n   }\n   else if(count == rep->max)\n   {\n      // can't repeat any more, remove the pushed state: \n      destroy_single_repeat();\n      if(!can_start(*position, rep->_map, mask_skip))\n         return true;\n   }\n   else\n   {\n      pmp->count = count;\n      pmp->last_position = position;\n   }\n   pstate = rep->alt.p;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)\n{\n   saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);\n   if(!r)\n   {\n      position = pmp->position;\n      pstate = pmp->pstate;\n      ++(*next_count);\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return r;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)\n{\n   // We are backtracking back inside a recursion, need to push the info\n   // back onto the recursion stack, and do so unconditionally, otherwise\n   // we can get mismatched pushes and pops...\n   saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);\n   if (!r)\n   {\n      recursion_stack.push_back(recursion_info<results_type>());\n      recursion_stack.back().idx = pmp->recursion_id;\n      recursion_stack.back().preturn_address = pmp->preturn_address;\n      recursion_stack.back().results = pmp->prior_results;\n      recursion_stack.back().location_of_start = position;\n      *m_presult = pmp->internal_results;\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)\n{\n   // Backtracking out of a recursion, we must pop state off the recursion\n   // stack unconditionally to ensure matched pushes and pops:\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   if (!r && !recursion_stack.empty())\n   {\n      *m_presult = recursion_stack.back().results;\n      position = recursion_stack.back().location_of_start;\n      recursion_stack.pop_back();\n   }\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++);\n   m_backup_state = pmp;\n   return true;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nvoid perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()\n{\n   saved_state* pmp = static_cast<saved_state*>(m_backup_state);\n   --pmp;\n   if(pmp < m_stack_base)\n   {\n      extend_stack();\n      pmp = static_cast<saved_state*>(m_backup_state);\n      --pmp;\n   }\n   (void) new (pmp)saved_state(15);\n   m_backup_state = pmp;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_commit(bool b)\n{\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   while(unwind(b) && !m_unwound_lookahead){}\n   if(m_unwound_lookahead && pstate)\n   {\n      //\n      // If we stop because we just unwound an assertion, put the\n      // commit state back on the stack again:\n      //\n      m_unwound_lookahead = false;\n      saved_state* pmp = m_backup_state;\n      --pmp;\n      if(pmp < m_stack_base)\n      {\n         extend_stack();\n         pmp = m_backup_state;\n         --pmp;\n      }\n      (void) new (pmp)saved_state(16);\n      m_backup_state = pmp;\n   }\n   // This prevents us from stopping when we exit from an independent sub-expression:\n   m_independent = false;\n   return false;\n}\n\ntemplate <class BidiIterator, class Allocator, class traits>\nbool perl_matcher<BidiIterator, Allocator, traits>::unwind_then(bool b)\n{\n   // Unwind everything till we hit an alternative:\n   boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(m_backup_state++);\n   bool result = false;\n   result = unwind(b);\n   while(result && !m_unwound_alt)\n   {\n      result = unwind(b);\n   }\n   // We're now pointing at the next alternative, need one more backtrack \n   // since *all* the other alternatives must fail once we've reached a THEN clause:\n   if(result && m_unwound_alt)\n      unwind(b);\n   return false;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/primary_transform.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE:        primary_transform.hpp\n  *   VERSION:     see <boost/version.hpp>\n  *   DESCRIPTION: Heuristically determines the sort string format in use\n  *                by the current locale.\n  */\n\n#ifndef BOOST_REGEX_PRIMARY_TRANSFORM\n#define BOOST_REGEX_PRIMARY_TRANSFORM\n\nnamespace boost{\n   namespace BOOST_REGEX_DETAIL_NS{\n\n\nenum{\n   sort_C,\n   sort_fixed,\n   sort_delim,\n   sort_unknown\n};\n\ntemplate <class S, class charT>\nunsigned count_chars(const S& s, charT c)\n{\n   //\n   // Count how many occurrences of character c occur\n   // in string s: if c is a delimeter between collation\n   // fields, then this should be the same value for all\n   // sort keys:\n   //\n   unsigned int count = 0;\n   for(unsigned pos = 0; pos < s.size(); ++pos)\n   {\n      if(s[pos] == c) ++count;\n   }\n   return count;\n}\n\n\ntemplate <class traits, class charT>\nunsigned find_sort_syntax(const traits* pt, charT* delim)\n{\n   //\n   // compare 'a' with 'A' to see how similar they are,\n   // should really use a-accute but we can't portably do that,\n   //\n   typedef typename traits::string_type string_type;\n   typedef typename traits::char_type char_type;\n\n   // Suppress incorrect warning for MSVC\n   (void)pt;\n\n   char_type a[2] = {'a', '\\0', };\n   string_type sa(pt->transform(a, a+1));\n   if(sa == a)\n   {\n      *delim = 0;\n      return sort_C;\n   }\n   char_type A[2] = { 'A', '\\0', };\n   string_type sA(pt->transform(A, A+1));\n   char_type c[2] = { ';', '\\0', };\n   string_type sc(pt->transform(c, c+1));\n\n   int pos = 0;\n   while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos;\n   --pos;\n   if(pos < 0)\n   {\n      *delim = 0;\n      return sort_unknown;\n   }\n   //\n   // at this point sa[pos] is either the end of a fixed width field\n   // or the character that acts as a delimiter:\n   //\n   charT maybe_delim = sa[pos];\n   if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim)))\n   {\n      *delim = maybe_delim;\n      return sort_delim;\n   }\n   //\n   // OK doen't look like a delimiter, try for fixed width field:\n   //\n   if((sa.size() == sA.size()) && (sa.size() == sc.size()))\n   {\n      // note assumes that the fixed width field is less than\n      // (numeric_limits<charT>::max)(), should be true for all types\n      // I can't imagine 127 character fields...\n      *delim = static_cast<charT>(++pos);\n      return sort_fixed;\n   }\n   //\n   // don't know what it is:\n   //\n   *delim = 0;\n   return sort_unknown;\n}\n\n\n   } // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#endif\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regbase.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regbase.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares class regbase.\n  */\n\n#ifndef BOOST_REGEX_V5_REGBASE_HPP\n#define BOOST_REGEX_V5_REGBASE_HPP\n\nnamespace boost{\n//\n// class regbase\n// handles error codes and flags\n//\nclass regbase\n{\npublic:\n   enum flag_type_\n   {\n      //\n      // Divide the flags up into logical groups:\n      // bits 0-7 indicate main synatx type.\n      // bits 8-15 indicate syntax subtype.\n      // bits 16-31 indicate options that are common to all\n      // regex syntaxes.\n      // In all cases the default is 0.\n      //\n      // Main synatx group:\n      //\n      perl_syntax_group = 0,                      // default\n      basic_syntax_group = 1,                     // POSIX basic\n      literal = 2,                                // all characters are literals\n      main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!\n      //\n      // options specific to perl group:\n      //\n      no_bk_refs = 1 << 8,                        // \\d not allowed\n      no_perl_ex = 1 << 9,                        // disable perl extensions\n      no_mod_m = 1 << 10,                         // disable Perl m modifier\n      mod_x = 1 << 11,                            // Perl x modifier\n      mod_s = 1 << 12,                            // force s modifier on (overrides match_not_dot_newline)\n      no_mod_s = 1 << 13,                         // force s modifier off (overrides match_not_dot_newline)\n\n      //\n      // options specific to basic group:\n      //\n      no_char_classes = 1 << 8,                   // [[:CLASS:]] not allowed\n      no_intervals = 1 << 9,                      // {x,y} not allowed\n      bk_plus_qm = 1 << 10,                       // uses \\+ and \\?\n      bk_vbar = 1 << 11,                          // use \\| for alternatives\n      emacs_ex = 1 << 12,                         // enables emacs extensions\n\n      //\n      // options common to all groups:\n      //\n      no_escape_in_lists = 1 << 16,                     // '\\' not special inside [...]\n      newline_alt = 1 << 17,                            // \\n is the same as |\n      no_except = 1 << 18,                              // no exception on error\n      failbit = 1 << 19,                                // error flag\n      icase = 1 << 20,                                  // characters are matched regardless of case\n      nocollate = 0,                                    // don't use locale specific collation (deprecated)\n      collate = 1 << 21,                                // use locale specific collation\n      nosubs = 1 << 22,                                 // don't mark sub-expressions\n      save_subexpression_location = 1 << 23,            // save subexpression locations\n      no_empty_expressions = 1 << 24,                   // no empty expressions allowed\n      optimize = 0,                                     // not really supported\n      \n\n\n      basic = basic_syntax_group | collate | no_escape_in_lists,\n      extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,\n      normal = 0,\n      emacs = basic_syntax_group | collate | emacs_ex | bk_vbar,\n      awk = no_bk_refs | collate | no_perl_ex,\n      grep = basic | newline_alt,\n      egrep = extended | newline_alt,\n      sed = basic,\n      perl = normal,\n      ECMAScript = normal,\n      JavaScript = normal,\n      JScript = normal\n   };\n   typedef unsigned int flag_type;\n\n   enum restart_info\n   {\n      restart_any = 0,\n      restart_word = 1,\n      restart_line = 2,\n      restart_buf = 3,\n      restart_continue = 4,\n      restart_lit = 5,\n      restart_fixed_lit = 6, \n      restart_count = 7\n   };\n};\n\n//\n// provide std lib proposal compatible constants:\n//\nnamespace regex_constants{\n\n   enum flag_type_\n   {\n\n      no_except = ::boost::regbase::no_except,\n      failbit = ::boost::regbase::failbit,\n      literal = ::boost::regbase::literal,\n      icase = ::boost::regbase::icase,\n      nocollate = ::boost::regbase::nocollate,\n      collate = ::boost::regbase::collate,\n      nosubs = ::boost::regbase::nosubs,\n      optimize = ::boost::regbase::optimize,\n      bk_plus_qm = ::boost::regbase::bk_plus_qm,\n      bk_vbar = ::boost::regbase::bk_vbar,\n      no_intervals = ::boost::regbase::no_intervals,\n      no_char_classes = ::boost::regbase::no_char_classes,\n      no_escape_in_lists = ::boost::regbase::no_escape_in_lists,\n      no_mod_m = ::boost::regbase::no_mod_m,\n      mod_x = ::boost::regbase::mod_x,\n      mod_s = ::boost::regbase::mod_s,\n      no_mod_s = ::boost::regbase::no_mod_s,\n      save_subexpression_location = ::boost::regbase::save_subexpression_location,\n      no_empty_expressions = ::boost::regbase::no_empty_expressions,\n\n      basic = ::boost::regbase::basic,\n      extended = ::boost::regbase::extended,\n      normal = ::boost::regbase::normal,\n      emacs = ::boost::regbase::emacs,\n      awk = ::boost::regbase::awk,\n      grep = ::boost::regbase::grep,\n      egrep = ::boost::regbase::egrep,\n      sed = basic,\n      perl = normal,\n      ECMAScript = normal,\n      JavaScript = normal,\n      JScript = normal\n   };\n   typedef ::boost::regbase::flag_type syntax_option_type;\n\n} // namespace regex_constants\n\n} // namespace boost\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares boost::basic_regex<> and associated\n  *                functions and classes. This header is the main\n  *                entry point for the template regex code.\n  */\n\n#ifndef BOOST_RE_REGEX_HPP_INCLUDED\n#define BOOST_RE_REGEX_HPP_INCLUDED\n\n#ifdef __cplusplus\n\n// what follows is all C++ don't include in C builds!!\n\n#include <boost/regex/config.hpp>\n#include <boost/regex/v5/regex_workaround.hpp>\n#include <boost/regex_fwd.hpp>\n#include <boost/regex/regex_traits.hpp>\n#include <boost/regex/v5/error_type.hpp>\n#include <boost/regex/v5/match_flags.hpp>\n#include <boost/regex/v5/regex_raw_buffer.hpp>\n#include <boost/regex/pattern_except.hpp>\n#include <boost/regex/v5/char_regex_traits.hpp>\n#include <boost/regex/v5/states.hpp>\n#include <boost/regex/v5/regbase.hpp>\n#include <boost/regex/v5/basic_regex.hpp>\n#include <boost/regex/v5/basic_regex_creator.hpp>\n#include <boost/regex/v5/basic_regex_parser.hpp>\n#include <boost/regex/v5/sub_match.hpp>\n#include <boost/regex/v5/regex_format.hpp>\n#include <boost/regex/v5/match_results.hpp>\n#include <boost/regex/v5/perl_matcher.hpp>\n\nnamespace boost{\n#ifdef BOOST_REGEX_NO_FWD\ntypedef basic_regex<char, regex_traits<char> > regex;\n#ifndef BOOST_NO_WREGEX\ntypedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;\n#endif\n#endif\n\ntypedef match_results<const char*> cmatch;\ntypedef match_results<std::string::const_iterator> smatch;\n#ifndef BOOST_NO_WREGEX\ntypedef match_results<const wchar_t*> wcmatch;\ntypedef match_results<std::wstring::const_iterator> wsmatch;\n#endif\n\n} // namespace boost\n\n#include <boost/regex/v5/regex_match.hpp>\n#include <boost/regex/v5/regex_search.hpp>\n#include <boost/regex/v5/regex_iterator.hpp>\n#include <boost/regex/v5/regex_token_iterator.hpp>\n#include <boost/regex/v5/regex_grep.hpp>\n#include <boost/regex/v5/regex_replace.hpp>\n#include <boost/regex/v5/regex_merge.hpp>\n#include <boost/regex/v5/regex_split.hpp>\n\n#endif  // __cplusplus\n\n#endif  // include\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_format.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009 John Maddock\n * Copyright 2008 Eric Niebler. \n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_FORMAT_HPP\n#define BOOST_REGEX_FORMAT_HPP\n\n#include <type_traits>\n#include <functional>\n\nnamespace boost{\n\n//\n// Forward declaration:\n//\n   template <class BidiIterator, class Allocator = typename std::vector<sub_match<BidiIterator> >::allocator_type >\nclass match_results;\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// struct trivial_format_traits:\n// defines minimum localisation support for formatting\n// in the case that the actual regex traits is unavailable.\n//\ntemplate <class charT>\nstruct trivial_format_traits\n{\n   typedef charT char_type;\n\n   static std::ptrdiff_t length(const charT* p)\n   {\n      return global_length(p);\n   }\n   static charT tolower(charT c)\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);\n   }\n   static charT toupper(charT c)\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);\n   }\n   static int value(const charT c, int radix)\n   {\n      int result = global_value(c);\n      return result >= radix ? -1 : result;\n   }\n   int toi(const charT*& p1, const charT* p2, int radix)const\n   {\n      return (int)global_toi(p1, p2, radix, *this);\n   }\n};\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#pragma warning(disable:26812)\n#endif\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nclass basic_regex_formatter\n{\npublic:\n   typedef typename traits::char_type char_type;\n   basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)\n      : m_traits(t), m_results(r), m_out(o), m_position(), m_end(), m_flags(), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}\n   OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);\n   OutputIterator format(ForwardIter p1, match_flag_type f)\n   {\n      return format(p1, p1 + m_traits.length(p1), f);\n   }\nprivate:\n   typedef typename Results::value_type sub_match_type;\n   enum output_state\n   {\n      output_copy,\n      output_next_lower,\n      output_next_upper,\n      output_lower,\n      output_upper,\n      output_none\n   };\n\n   void put(char_type c);\n   void put(const sub_match_type& sub);\n   void format_all();\n   void format_perl();\n   void format_escape();\n   void format_conditional();\n   void format_until_scope_end();\n   bool handle_perl_verb(bool have_brace);\n\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const std::integral_constant<bool, false>&)\n   {\n      std::vector<char_type> v(i, j);\n      return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())\n         : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));\n   }\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const std::integral_constant<bool, true>&)\n   {\n      return this->m_results.named_subexpression(i, j);\n   }\n   inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)\n   {\n      typedef typename std::is_convertible<ForwardIter, const char_type*>::type tag_type;\n      return get_named_sub(i, j, tag_type());\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const std::integral_constant<bool, false>&)\n   {\n      std::vector<char_type> v(i, j);\n      return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())\n         : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j, const std::integral_constant<bool, true>&)\n   {\n      return this->m_results.named_subexpression_index(i, j);\n   }\n   inline int get_named_sub_index(ForwardIter i, ForwardIter j)\n   {\n      typedef typename std::is_convertible<ForwardIter, const char_type*>::type tag_type;\n      return get_named_sub_index(i, j, tag_type());\n   }\n#ifdef BOOST_REGEX_MSVC\n   // msvc-8.0 issues a spurious warning on the call to std::advance here:\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n   inline int toi(ForwardIter& i, ForwardIter j, int base, const std::integral_constant<bool, false>&)\n   {\n      if(i != j)\n      {\n         std::vector<char_type> v(i, j);\n         const char_type* start = &v[0];\n         const char_type* pos = start;\n         int r = (int)m_traits.toi(pos, &v[0] + v.size(), base);\n         std::advance(i, pos - start);\n         return r;\n      }\n      return -1;\n   }\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n   inline int toi(ForwardIter& i, ForwardIter j, int base, const std::integral_constant<bool, true>&)\n   {\n      return m_traits.toi(i, j, base);\n   }\n   inline int toi(ForwardIter& i, ForwardIter j, int base)\n   {\n#if defined(_MSC_VER) && defined(__INTEL_COMPILER) && ((__INTEL_COMPILER == 9999) || (__INTEL_COMPILER == 1210))\n      // Workaround for Intel support issue #656654.\n      // See also https://svn.boost.org/trac/boost/ticket/6359\n      return toi(i, j, base, std::integral_constant<bool, false>());\n#else\n      typedef typename std::is_convertible<ForwardIter, const char_type*&>::type tag_type;\n      return toi(i, j, base, tag_type());\n#endif\n   }\n\n   const traits&    m_traits;       // the traits class for localised formatting operations\n   const Results&   m_results;     // the match_results being used.\n   OutputIterator   m_out;         // where to send output.\n   ForwardIter      m_position;  // format string, current position\n   ForwardIter      m_end;       // format string end\n   match_flag_type  m_flags;      // format flags to use\n   output_state     m_state;      // what to do with the next character\n   output_state     m_restore_state;  // what state to restore to.\n   bool             m_have_conditional; // we are parsing a conditional\nprivate:\n   basic_regex_formatter(const basic_regex_formatter&);\n   basic_regex_formatter& operator=(const basic_regex_formatter&);\n};\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nOutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)\n{\n   m_position = p1;\n   m_end = p2;\n   m_flags = f;\n   format_all();\n   return m_out;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()\n{\n   // over and over:\n   while(m_position != m_end)\n   {\n      switch(*m_position)\n      {\n      case '&':\n         if(m_flags & ::boost::regex_constants::format_sed)\n         {\n            ++m_position;\n            put(m_results[0]);\n            break;\n         }\n         put(*m_position++);\n         break;\n      case '\\\\':\n         format_escape();\n         break;\n      case '(':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            ++m_position;\n            bool have_conditional = m_have_conditional;\n            m_have_conditional = false;\n            format_until_scope_end();\n            m_have_conditional = have_conditional;\n            if(m_position == m_end)\n               return;\n            BOOST_REGEX_ASSERT(*m_position == static_cast<char_type>(')'));\n            ++m_position;  // skip the closing ')'\n            break;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case ')':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            return;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case ':':\n         if((m_flags & boost::regex_constants::format_all) && m_have_conditional)\n         {\n            return;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case '?':\n         if(m_flags & boost::regex_constants::format_all)\n         {\n            ++m_position;\n            format_conditional();\n            break;\n         }\n         put(*m_position);\n         ++m_position;\n         break;\n      case '$':\n         if((m_flags & format_sed) == 0)\n         {\n            format_perl();\n            break;\n         }\n         // not a special character:\n         BOOST_REGEX_FALLTHROUGH;\n      default:\n         put(*m_position);\n         ++m_position;\n         break;\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()\n{\n   //\n   // On entry *m_position points to a '$' character\n   // output the information that goes with it:\n   //\n   BOOST_REGEX_ASSERT(*m_position == '$');\n   //\n   // see if this is a trailing '$':\n   //\n   if(++m_position == m_end)\n   {\n      --m_position;\n      put(*m_position);\n      ++m_position;\n      return;\n   }\n   //\n   // OK find out what kind it is:\n   //\n   bool have_brace = false;\n   ForwardIter save_position = m_position;\n   switch(*m_position)\n   {\n   case '&':\n      ++m_position;\n      put(this->m_results[0]);\n      break;\n   case '`':\n      ++m_position;\n      put(this->m_results.prefix());\n      break;\n   case '\\'':\n      ++m_position;\n      put(this->m_results.suffix());\n      break;\n   case '$':\n      put(*m_position++);\n      break;\n   case '+':\n      if((++m_position != m_end) && (*m_position == '{'))\n      {\n         ForwardIter base = ++m_position;\n         while((m_position != m_end) && (*m_position != '}')) ++m_position;\n         if(m_position != m_end)\n         {\n            // Named sub-expression:\n            put(get_named_sub(base, m_position));\n            ++m_position;\n            break;\n         }\n         else\n         {\n            m_position = --base;\n         }\n      }\n      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);\n      break;\n   case '{':\n      have_brace = true;\n      ++m_position;\n      BOOST_REGEX_FALLTHROUGH;\n   default:\n      // see if we have a number:\n      {\n         std::ptrdiff_t len = std::distance(m_position, m_end);\n         //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n         int v = this->toi(m_position, m_position + len, 10);\n         if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))\n         {\n            // Look for a Perl-5.10 verb:\n            if(!handle_perl_verb(have_brace))\n            {\n               // leave the $ as is, and carry on:\n               m_position = --save_position;\n               put(*m_position);\n               ++m_position;\n            }\n            break;\n         }\n         // otherwise output sub v:\n         put(this->m_results[v]);\n         if(have_brace)\n            ++m_position;\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nbool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)\n{\n   // \n   // We may have a capitalised string containing a Perl action:\n   //\n   static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };\n   static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };\n   static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };\n   static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };\n\n   if(m_position == m_end)\n      return false;\n   if(have_brace && (*m_position == '^'))\n      ++m_position;\n\n   std::ptrdiff_t max_len = m_end - m_position;\n\n   if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))\n   {\n      m_position += 5;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 5;\n            return false;\n         }\n      }\n      put(this->m_results[0]);\n      return true;\n   }\n   if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))\n   {\n      m_position += 8;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 8;\n            return false;\n         }\n      }\n      put(this->m_results.prefix());\n      return true;\n   }\n   if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))\n   {\n      m_position += 9;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 9;\n            return false;\n         }\n      }\n      put(this->m_results.suffix());\n      return true;\n   }\n   if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))\n   {\n      m_position += 16;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 16;\n            return false;\n         }\n      }\n      put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);\n      return true;\n   }\n   if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))\n   {\n      m_position += 20;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 20;\n            return false;\n         }\n      }\n      put(this->m_results.get_last_closed_paren());\n      return true;\n   }\n   if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))\n   {\n      m_position += 2;\n      if(have_brace)\n      {\n         if((m_position != m_end) && (*m_position == '}'))\n            ++m_position;\n         else\n         {\n            m_position -= 2;\n            return false;\n         }\n      }\n      put(this->m_results.get_last_closed_paren());\n      return true;\n   }\n   return false;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()\n{\n   // skip the escape and check for trailing escape:\n   if(++m_position == m_end)\n   {\n      put(static_cast<char_type>('\\\\'));\n      return;\n   }\n   // now switch on the escape type:\n   switch(*m_position)\n   {\n   case 'a':\n      put(static_cast<char_type>('\\a'));\n      ++m_position;\n      break;\n   case 'f':\n      put(static_cast<char_type>('\\f'));\n      ++m_position;\n      break;\n   case 'n':\n      put(static_cast<char_type>('\\n'));\n      ++m_position;\n      break;\n   case 'r':\n      put(static_cast<char_type>('\\r'));\n      ++m_position;\n      break;\n   case 't':\n      put(static_cast<char_type>('\\t'));\n      ++m_position;\n      break;\n   case 'v':\n      put(static_cast<char_type>('\\v'));\n      ++m_position;\n      break;\n   case 'x':\n      if(++m_position == m_end)\n      {\n         put(static_cast<char_type>('x'));\n         return;\n      }\n      // maybe have \\x{ddd}\n      if(*m_position == static_cast<char_type>('{'))\n      {\n         ++m_position;\n         int val = this->toi(m_position, m_end, 16);\n         if(val < 0)\n         {\n            // invalid value treat everything as literals:\n            put(static_cast<char_type>('x'));\n            put(static_cast<char_type>('{'));\n            return;\n         }\n         if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))\n         {\n            --m_position;\n            while(*m_position != static_cast<char_type>('\\\\'))\n               --m_position;\n            ++m_position;\n            put(*m_position++);\n            return;\n         }\n         ++m_position;\n         put(static_cast<char_type>(val));\n         return;\n      }\n      else\n      {\n         std::ptrdiff_t len = std::distance(m_position, m_end);\n         len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n         int val = this->toi(m_position, m_position + len, 16);\n         if(val < 0)\n         {\n            --m_position;\n            put(*m_position++);\n            return;\n         }\n         put(static_cast<char_type>(val));\n      }\n      break;\n   case 'c':\n      if(++m_position == m_end)\n      {\n         --m_position;\n         put(*m_position++);\n         return;\n      }\n      put(static_cast<char_type>(*m_position++ % 32));\n      break;\n   case 'e':\n      put(static_cast<char_type>(27));\n      ++m_position;\n      break;\n   default:\n      // see if we have a perl specific escape:\n      if((m_flags & boost::regex_constants::format_sed) == 0)\n      {\n         bool breakout = false;\n         switch(*m_position)\n         {\n         case 'l':\n            ++m_position;\n            m_restore_state = m_state;\n            m_state = output_next_lower;\n            breakout = true;\n            break;\n         case 'L':\n            ++m_position;\n            m_state = output_lower;\n            breakout = true;\n            break;\n         case 'u':\n            ++m_position;\n            m_restore_state = m_state;\n            m_state = output_next_upper;\n            breakout = true;\n            break;\n         case 'U':\n            ++m_position;\n            m_state = output_upper;\n            breakout = true;\n            break;\n         case 'E':\n            ++m_position;\n            m_state = output_copy;\n            breakout = true;\n            break;\n         }\n         if(breakout)\n            break;\n      }\n      // see if we have a \\n sed style backreference:\n      std::ptrdiff_t len = std::distance(m_position, m_end);\n      len = (std::min)(static_cast<std::ptrdiff_t>(1), len);\n      int v = this->toi(m_position, m_position+len, 10);\n      if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))\n      {\n         put(m_results[v]);\n         break;\n      }\n      else if(v == 0)\n      {\n         // octal ecape sequence:\n         --m_position;\n         len = std::distance(m_position, m_end);\n         len = (std::min)(static_cast<std::ptrdiff_t>(4), len);\n         v = this->toi(m_position, m_position + len, 8);\n         BOOST_REGEX_ASSERT(v >= 0);\n         put(static_cast<char_type>(v));\n         break;\n      }\n      // Otherwise output the character \"as is\":\n      put(*m_position++);\n      break;\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()\n{\n   if(m_position == m_end)\n   {\n      // oops trailing '?':\n      put(static_cast<char_type>('?'));\n      return;\n   }\n   int v;\n   if(*m_position == '{')\n   {\n      ForwardIter base = m_position;\n      ++m_position;\n      v = this->toi(m_position, m_end, 10);\n      if(v < 0)\n      {\n         // Try a named subexpression:\n         while((m_position != m_end) && (*m_position != '}'))\n            ++m_position;\n         v = this->get_named_sub_index(base + 1, m_position);\n      }\n      if((v < 0) || (*m_position != '}'))\n      {\n         m_position = base;\n         // oops trailing '?':\n         put(static_cast<char_type>('?'));\n         return;\n      }\n      // Skip trailing '}':\n      ++m_position;\n   }\n   else\n   {\n      std::ptrdiff_t len = std::distance(m_position, m_end);\n      len = (std::min)(static_cast<std::ptrdiff_t>(2), len);\n      v = this->toi(m_position, m_position + len, 10);\n   }\n   if(v < 0)\n   {\n      // oops not a number:\n      put(static_cast<char_type>('?'));\n      return;\n   }\n\n   // output varies depending upon whether sub-expression v matched or not:\n   if(m_results[v].matched)\n   {\n      m_have_conditional = true;\n      format_all();\n      m_have_conditional = false;\n      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))\n      {\n         // skip the ':':\n         ++m_position;\n         // save output state, then turn it off:\n         output_state saved_state = m_state;\n         m_state = output_none;\n         // format the rest of this scope:\n         format_until_scope_end();\n         // restore output state:\n         m_state = saved_state;\n      }\n   }\n   else\n   {\n      // save output state, then turn it off:\n      output_state saved_state = m_state;\n      m_state = output_none;\n      // format until ':' or ')':\n      m_have_conditional = true;\n      format_all();\n      m_have_conditional = false;\n      // restore state:\n      m_state = saved_state;\n      if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))\n      {\n         // skip the ':':\n         ++m_position;\n         // format the rest of this scope:\n         format_until_scope_end();\n      }\n   }\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()\n{\n   do\n   {\n      format_all();\n      if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))\n         return;\n      put(*m_position++);\n   }while(m_position != m_end);\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)\n{\n   // write a single character to output\n   // according to which case translation mode we are in:\n   switch(this->m_state)\n   {\n   case output_none:\n      return;\n   case output_next_lower:\n      c = m_traits.tolower(c);\n      this->m_state = m_restore_state;\n      break;\n   case output_next_upper:\n      c = m_traits.toupper(c);\n      this->m_state = m_restore_state;\n      break;\n   case output_lower:\n      c = m_traits.tolower(c);\n      break;\n   case output_upper:\n      c = m_traits.toupper(c);\n      break;\n   default:\n      break;\n   }\n   *m_out = c;\n   ++m_out;\n}\n\ntemplate <class OutputIterator, class Results, class traits, class ForwardIter>\nvoid basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)\n{\n   typedef typename sub_match_type::iterator iterator_type;\n   iterator_type i = sub.first;\n   while(i != sub.second)\n   {\n      put(*i);\n      ++i;\n   }\n}\n\ntemplate <class S>\nclass string_out_iterator\n{\n   S* out;\npublic:\n   string_out_iterator(S& s) : out(&s) {}\n   string_out_iterator& operator++() { return *this; }\n   string_out_iterator& operator++(int) { return *this; }\n   string_out_iterator& operator*() { return *this; }\n   string_out_iterator& operator=(typename S::value_type v) \n   { \n      out->append(1, v); \n      return *this; \n   }\n\n   typedef std::ptrdiff_t difference_type;\n   typedef typename S::value_type value_type;\n   typedef value_type* pointer;\n   typedef value_type& reference;\n   typedef std::output_iterator_tag iterator_category;\n};\n\ntemplate <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>\nOutputIterator regex_format_imp(OutputIterator out,\n                          const match_results<Iterator, Alloc>& m,\n                          ForwardIter p1, ForwardIter p2,\n                          match_flag_type flags,\n                          const traits& t\n                         )\n{\n   if(flags & regex_constants::format_literal)\n   {\n      return BOOST_REGEX_DETAIL_NS::copy(p1, p2, out);\n   }\n\n   BOOST_REGEX_DETAIL_NS::basic_regex_formatter<\n      OutputIterator, \n      match_results<Iterator, Alloc>, \n      traits, ForwardIter> f(out, m, t);\n   return f.format(p1, p2, flags);\n}\n\ntemplate <class T>\nstruct has_const_iterator\n{\n   template <class U>\n   static typename U::const_iterator tester(U*);\n   static char tester(...);\n\n   static T* get();\n\n   static const bool value = sizeof(tester(get())) != sizeof(char);\n};\n\nstruct any_type \n{\n   template <class T>\n   any_type(const T&); \n   template <class T, class U>\n   any_type(const T&, const U&); \n   template <class T, class U, class V>\n   any_type(const T&, const U&, const V&); \n};\ntypedef char no_type;\ntypedef char (&unary_type)[2];\ntypedef char (&binary_type)[3];\ntypedef char (&ternary_type)[4];\n\nno_type check_is_formatter(unary_type, binary_type, ternary_type);\ntemplate<typename T>\nunary_type check_is_formatter(T const &, binary_type, ternary_type);\ntemplate<typename T>\nbinary_type check_is_formatter(unary_type, T const &, ternary_type);\ntemplate<typename T, typename U>\nbinary_type check_is_formatter(T const &, U const &, ternary_type);\ntemplate<typename T>\nternary_type check_is_formatter(unary_type, binary_type, T const &);\ntemplate<typename T, typename U>\nternary_type check_is_formatter(T const &, binary_type, U const &);\ntemplate<typename T, typename U>\nternary_type check_is_formatter(unary_type, T const &, U const &);\ntemplate<typename T, typename U, typename V>\nternary_type check_is_formatter(T const &, U const &, V const &);\n\nstruct unary_binary_ternary\n{\n    typedef unary_type (*unary_fun)(any_type);\n    typedef binary_type (*binary_fun)(any_type, any_type);\n    typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);\n    operator unary_fun();\n    operator binary_fun();\n    operator ternary_fun();\n};\n\ntemplate<typename Formatter, bool IsFunction = std::is_function<Formatter>::value>\nstruct formatter_wrapper\n  : Formatter\n  , unary_binary_ternary\n{\n   formatter_wrapper(){}\n};\n\ntemplate<typename Formatter>\nstruct formatter_wrapper<Formatter, true>\n  : unary_binary_ternary\n{\n    operator Formatter *();\n};\n\ntemplate<typename Formatter>\nstruct formatter_wrapper<Formatter *, false>\n  : unary_binary_ternary\n{\n    operator Formatter *();\n};\n\ntemplate <class T>\nstruct do_unwrap_reference\n{\n   typedef T type;\n};\ntemplate <class T>\nstruct do_unwrap_reference<std::reference_wrapper<T> >\n{\n   typedef T type;\n};\n\ntemplate <class T>\nT& do_unwrap_ref(T& r) { return r; }\ntemplate <class T>\nT& do_unwrap_ref(std::reference_wrapper<T> const& r) { return r.get(); }\n\ntemplate <class F, class M, class O>\nstruct format_traits_imp\n{\nprivate:\n   //\n   // F must be a pointer, a function, or a class with a function call operator:\n   //\n   static_assert((::std::is_pointer<F>::value || ::std::is_function<F>::value || ::std::is_class<F>::value), \"The functor must be a pointer or a class with a function call operator\");\n   static formatter_wrapper<typename do_unwrap_reference<F>::type> f;\n   static M m;\n   static O out;\n   static boost::regex_constants::match_flag_type flags;\npublic:\n   static const int value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags)));\n};\n\ntemplate <class F, class M, class O>\nstruct format_traits\n{\npublic:\n   // \n   // Type is std::integral_constant<int, N> where N is one of:\n   //\n   // 0 : F is a pointer to a presumably null-terminated string.\n   // 1 : F is a character-container such as a std::string.\n   // 2 : F is a Unary Functor.\n   // 3 : F is a Binary Functor.\n   // 4 : F is a Ternary Functor.\n   //\n   typedef typename std::conditional<\n      std::is_pointer<F>::value && !std::is_function<typename std::remove_pointer<F>::type>::value,\n      std::integral_constant<int, 0>,\n      typename std::conditional<\n         has_const_iterator<F>::value,\n         std::integral_constant<int, 1>,\n         std::integral_constant<int, format_traits_imp<F, M, O>::value>\n      >::type\n   >::type type;\n   //\n   // This static assertion will fail if the functor passed does not accept\n   // the same type of arguments passed.\n   //\n   static_assert( std::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true, \"Argument mismatch in Functor type\");\n};\n\ntemplate <class Base, class Match>\nstruct format_functor3\n{\n   format_functor3(Base b) : func(b) {}\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)\n   {\n      return do_unwrap_ref(func)(m, i, f);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor3(const format_functor3&);\n   format_functor3& operator=(const format_functor3&);\n};\n\ntemplate <class Base, class Match>\nstruct format_functor2\n{\n   format_functor2(Base b) : func(b) {}\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)\n   {\n      return do_unwrap_ref(func)(m, i);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor2(const format_functor2&);\n   format_functor2& operator=(const format_functor2&);\n};\n\ntemplate <class Base, class Match>\nstruct format_functor1\n{\n   format_functor1(Base b) : func(b) {}\n\n   template <class S, class OutputIter>\n   OutputIter do_format_string(const S& s, OutputIter i)\n   {\n      return std::copy(s.begin(), s.end(), i);\n   }\n   template <class S, class OutputIter>\n   inline OutputIter do_format_string(const S* s, OutputIter i)\n   {\n      while(s && *s)\n      {\n         *i = *s;\n         ++i;\n         ++s;\n      }\n      return i;\n   }\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)\n   {\n      return do_format_string(do_unwrap_ref(func)(m), i);\n   }\n   template <class OutputIter, class Traits>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)\n   {\n      return (*this)(m, i, f);\n   }\nprivate:\n   Base func;\n   format_functor1(const format_functor1&);\n   format_functor1& operator=(const format_functor1&);\n};\n\ntemplate <class charT, class Match, class Traits>\nstruct format_functor_c_string\n{\n   format_functor_c_string(const charT* ps) : func(ps) {}\n\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())\n   {\n      //typedef typename Match::char_type char_type;\n      const charT* end = func;\n      while(*end) ++end;\n      return regex_format_imp(i, m, func, end, f, t);\n   }\nprivate:\n   const charT* func;\n   format_functor_c_string(const format_functor_c_string&);\n   format_functor_c_string& operator=(const format_functor_c_string&);\n};\n\ntemplate <class Container, class Match, class Traits>\nstruct format_functor_container\n{\n   format_functor_container(const Container& c) : func(c) {}\n\n   template <class OutputIter>\n   OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())\n   {\n      //typedef typename Match::char_type char_type;\n      return BOOST_REGEX_DETAIL_NS::regex_format_imp(i, m, func.begin(), func.end(), f, t);\n   }\nprivate:\n   const Container& func;\n   format_functor_container(const format_functor_container&);\n   format_functor_container& operator=(const format_functor_container&);\n};\n\ntemplate <class Func, class Match, class OutputIterator, class Traits = BOOST_REGEX_DETAIL_NS::trivial_format_traits<typename Match::char_type> >\nstruct compute_functor_type\n{\n   typedef typename format_traits<Func, Match, OutputIterator>::type tag;\n   typedef typename std::remove_cv< typename std::remove_pointer<Func>::type>::type maybe_char_type;\n\n   typedef typename std::conditional<\n      tag::value == 0, format_functor_c_string<maybe_char_type, Match, Traits>,\n      typename std::conditional<\n         tag::value == 1, format_functor_container<Func, Match, Traits>,\n         typename std::conditional<\n            tag::value == 2, format_functor1<Func, Match>,\n            typename std::conditional<\n               tag::value == 3, format_functor2<Func, Match>,\n               format_functor3<Func, Match>\n            >::type\n         >::type\n      >::type\n   >::type type;\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class OutputIterator, class Iterator, class Allocator, class Functor>\ninline OutputIterator regex_format(OutputIterator out,\n                          const match_results<Iterator, Allocator>& m,\n                          Functor fmt,\n                          match_flag_type flags = format_all\n                         )\n{\n   return m.format(out, fmt, flags);\n}\n\ntemplate <class Iterator, class Allocator, class Functor>\ninline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m, \n                                      Functor fmt, \n                                      match_flag_type flags = format_all)\n{\n   return m.format(fmt, flags);\n}\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_FORMAT_HPP\n\n\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_fwd.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_fwd.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Forward declares boost::basic_regex<> and\n  *                associated typedefs.\n  */\n\n#ifndef BOOST_REGEX_FWD_HPP_INCLUDED\n#define BOOST_REGEX_FWD_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n//\n// define BOOST_REGEX_NO_FWD if this\n// header doesn't work!\n//\n#ifdef BOOST_REGEX_NO_FWD\n#  ifndef BOOST_RE_REGEX_HPP\n#     include <boost/regex.hpp>\n#  endif\n#else\n\nnamespace boost{\n\ntemplate <class charT>\nclass cpp_regex_traits;\ntemplate <class charT>\nstruct c_regex_traits;\ntemplate <class charT>\nclass w32_regex_traits;\n\n#ifdef BOOST_REGEX_USE_WIN32_LOCALE\ntemplate <class charT, class implementationT = w32_regex_traits<charT> >\nstruct regex_traits;\n#elif defined(BOOST_REGEX_USE_CPP_LOCALE)\ntemplate <class charT, class implementationT = cpp_regex_traits<charT> >\nstruct regex_traits;\n#else\ntemplate <class charT, class implementationT = c_regex_traits<charT> >\nstruct regex_traits;\n#endif\n\ntemplate <class charT, class traits = regex_traits<charT> >\nclass basic_regex;\n\ntypedef basic_regex<char, regex_traits<char> > regex;\n#ifndef BOOST_NO_WREGEX\ntypedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;\n#endif\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_NO_FWD\n\n#endif\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_grep.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_grep.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_grep implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_GREP_HPP\n#define BOOST_REGEX_V5_REGEX_GREP_HPP\n\n\nnamespace boost{\n\n//\n// regex_grep:\n// find all non-overlapping matches within the sequence first last:\n//\ntemplate <class Predicate, class BidiIterator, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, \n                               BidiIterator first, \n                               BidiIterator last, \n                               const basic_regex<charT, traits>& e, \n                               match_flag_type flags = match_default)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;\n\n   match_results<BidiIterator> m;\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);\n   unsigned int count = 0;\n   while(matcher.find())\n   {\n      ++count;\n      if(0 == foo(m))\n         return count; // caller doesn't want to go on\n      if(m[0].second == last)\n         return count; // we've reached the end, don't try and find an extra null match.\n      if(m.length() == 0)\n      {\n         if(m[0].second == last)\n            return count;\n         // we found a NULL-match, now try to find\n         // a non-NULL one at the same position:\n         match_results<BidiIterator, match_allocator_type> m2(m);\n         matcher.setf(match_not_null | match_continuous);\n         if(matcher.find())\n         {\n            ++count;\n            if(0 == foo(m))\n               return count;\n         }\n         else\n         {\n            // reset match back to where it was:\n            m = m2;\n         }\n         matcher.unsetf((match_not_null | match_continuous) & ~flags);\n      }\n   }\n   return count;\n}\n\n//\n// regex_grep convenience interfaces:\n//\ntemplate <class Predicate, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_grep(foo, str, str + traits::length(str), e, flags);\n}\n\ntemplate <class Predicate, class ST, class SA, class charT, class traits>\ninline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_grep(foo, s.begin(), s.end(), e, flags);\n}\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V5_REGEX_GREP_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_ITERATOR_HPP\n#define BOOST_REGEX_V5_REGEX_ITERATOR_HPP\n\n#include <memory>\n\nnamespace boost{\n\ntemplate <class BidirectionalIterator, \n          class charT,\n          class traits>\nclass regex_iterator_implementation \n{\n   typedef basic_regex<charT, traits> regex_type;\n\n   match_results<BidirectionalIterator> what;  // current match\n   BidirectionalIterator                base;  // start of sequence\n   BidirectionalIterator                end;   // end of sequence\n   const regex_type                     re;   // the expression\n   match_flag_type                      flags; // flags for matching\n\npublic:\n   regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)\n      : base(), end(last), re(*p), flags(f){}\n   regex_iterator_implementation(const regex_iterator_implementation& other)\n      :what(other.what), base(other.base), end(other.end), re(other.re), flags(other.flags){}\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      return regex_search(first, end, what, re, flags);\n   }\n   bool compare(const regex_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);\n   }\n   const match_results<BidirectionalIterator>& get()\n   { return what; }\n   bool next()\n   {\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail;\n      BidirectionalIterator next_start = what[0].second;\n      match_flag_type f(flags);\n      if(!what.length() || (f & regex_constants::match_posix))\n         f |= regex_constants::match_not_initial_null;\n      //if(base != next_start)\n      //   f |= regex_constants::match_not_bob;\n      bool result = regex_search(next_start, end, what, re, f, base);\n      if(result)\n         what.set_base(base);\n      return result;\n   }\nprivate:\n   regex_iterator_implementation& operator=(const regex_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator, \n          class charT = typename std::iterator_traits<BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT> >\nclass regex_iterator \n{\nprivate:\n   typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;\n   typedef std::shared_ptr<impl> pimpl;\npublic:\n   typedef          basic_regex<charT, traits>                   regex_type;\n   typedef          match_results<BidirectionalIterator>                    value_type;\n   typedef typename std::iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   regex_iterator(){}\n   regex_iterator(BidirectionalIterator a, BidirectionalIterator b, \n                  const regex_type& re, \n                  match_flag_type m = match_default)\n                  : pdata(new impl(&re, b, m))\n   {\n      if(!pdata->init(a))\n      {\n         pdata.reset();\n      }\n   }\n   regex_iterator(const regex_iterator& that)\n      : pdata(that.pdata) {}\n   regex_iterator& operator=(const regex_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const regex_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const regex_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   regex_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   regex_iterator operator++(int)\n   {\n      regex_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && (pdata.use_count() > 1))\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef regex_iterator<const char*> cregex_iterator;\ntypedef regex_iterator<std::string::const_iterator> sregex_iterator;\n#ifndef BOOST_NO_WREGEX\ntypedef regex_iterator<const wchar_t*> wcregex_iterator;\ntypedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;\n#endif\n\n// make_regex_iterator:\ntemplate <class charT, class traits>\ninline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);\n}\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V5_REGEX_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_match.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_match.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Regular expression matching algorithms.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n\n#ifndef BOOST_REGEX_MATCH_HPP\n#define BOOST_REGEX_MATCH_HPP\n\nnamespace boost{\n\n//\n// proc regex_match\n// returns true if the specified regular expression matches\n// the whole of the input.  Fills in what matched in m.\n//\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_match(BidiIterator first, BidiIterator last, \n                 match_results<BidiIterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);\n   return matcher.match();\n}\ntemplate <class iterator, class charT, class traits>\nbool regex_match(iterator first, iterator last, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   match_results<iterator> m;\n   return regex_match(first, last, m, e, flags | regex_constants::match_any);\n}\n//\n// query_match convenience interfaces:\n//\ntemplate <class charT, class Allocator, class traits>\ninline bool regex_match(const charT* str, \n                        match_results<const charT*, Allocator>& m, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_match(str, str + traits::length(str), m, e, flags);\n}\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\ninline bool regex_match(const std::basic_string<charT, ST, SA>& s, \n                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_match(s.begin(), s.end(), m, e, flags);\n}\ntemplate <class charT, class traits>\ninline bool regex_match(const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   match_results<const charT*> m;\n   return regex_match(str, str + traits::length(str), m, e, flags | regex_constants::match_any);\n}\n\ntemplate <class ST, class SA, class charT, class traits>\ninline bool regex_match(const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;\n   match_results<iterator> m;\n   return regex_match(s.begin(), s.end(), m, e, flags | regex_constants::match_any);\n}\n\n\n} // namespace boost\n\n#endif   // BOOST_REGEX_MATCH_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_merge.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_MERGE_HPP\n#define BOOST_REGEX_V5_REGEX_MERGE_HPP\n\n\nnamespace boost{\n\ntemplate <class OutputIterator, class Iterator, class traits, class charT>\ninline OutputIterator regex_merge(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const basic_regex<charT, traits>& e, \n                         const charT* fmt, \n                         match_flag_type flags = match_default)\n{\n   return regex_replace(out, first, last, e, fmt, flags);\n}\n\ntemplate <class OutputIterator, class Iterator, class traits, class charT>\ninline OutputIterator regex_merge(OutputIterator out,\n                         Iterator first,\n                         Iterator last,\n                         const basic_regex<charT, traits>& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_merge(out, first, last, e, fmt.c_str(), flags);\n}\n\ntemplate <class traits, class charT>\ninline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         const charT* fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_replace(s, e, fmt, flags);\n}\n\ntemplate <class traits, class charT>\ninline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         const std::basic_string<charT>& fmt,\n                         match_flag_type flags = match_default)\n{\n   return regex_replace(s, e, fmt, flags);\n}\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V5_REGEX_MERGE_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_raw_buffer.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_raw_buffer.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Raw character buffer for regex code.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_RAW_BUFFER_HPP\n#define BOOST_REGEX_RAW_BUFFER_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#include <algorithm>\n#include <cstddef>\n\nnamespace boost{\n   namespace BOOST_REGEX_DETAIL_NS{\n\nstruct empty_padding{};\n\nunion padding\n{\n   void* p;\n   unsigned int i;\n};\n\ntemplate <int N>\nstruct padding3\n{\n   enum{\n      padding_size = 8,\n      padding_mask = 7\n   };\n};\n\ntemplate<>\nstruct padding3<2>\n{\n   enum{\n      padding_size = 2,\n      padding_mask = 1\n   };\n};\n\ntemplate<>\nstruct padding3<4>\n{\n   enum{\n      padding_size = 4,\n      padding_mask = 3\n   };\n};\n\ntemplate<>\nstruct padding3<8>\n{\n   enum{\n      padding_size = 8,\n      padding_mask = 7\n   };\n};\n\ntemplate<>\nstruct padding3<16>\n{\n   enum{\n      padding_size = 16,\n      padding_mask = 15\n   };\n};\n\nenum{\n   padding_size = padding3<sizeof(padding)>::padding_size,\n   padding_mask = padding3<sizeof(padding)>::padding_mask\n};\n\n//\n// class raw_storage\n// basically this is a simplified vector<unsigned char>\n// this is used by basic_regex for expression storage\n//\n\nclass raw_storage\n{\npublic:\n   typedef std::size_t           size_type;\n   typedef unsigned char*        pointer;\nprivate:\n   pointer last, start, end;\npublic:\n\n   raw_storage();\n   raw_storage(size_type n);\n\n   ~raw_storage()\n   {\n      ::operator delete(start);\n   }\n\n   void  resize(size_type n)\n   {\n      size_type newsize = start ? last - start : 1024;\n      while (newsize < n)\n         newsize *= 2;\n      size_type datasize = end - start;\n      // extend newsize to WORD/DWORD boundary:\n      newsize = (newsize + padding_mask) & ~(padding_mask);\n\n      // allocate and copy data:\n      pointer ptr = static_cast<pointer>(::operator new(newsize));\n      BOOST_REGEX_NOEH_ASSERT(ptr)\n         if (start)\n            std::memcpy(ptr, start, datasize);\n\n      // get rid of old buffer:\n      ::operator delete(start);\n\n      // and set up pointers:\n      start = ptr;\n      end = ptr + datasize;\n      last = ptr + newsize;\n   }\n\n   void*  extend(size_type n)\n   {\n      if(size_type(last - end) < n)\n         resize(n + (end - start));\n      pointer result = end;\n      end += n;\n      return result;\n   }\n\n   void*  insert(size_type pos, size_type n)\n   {\n      BOOST_REGEX_ASSERT(pos <= size_type(end - start));\n      if (size_type(last - end) < n)\n         resize(n + (end - start));\n      void* result = start + pos;\n      std::memmove(start + pos + n, start + pos, (end - start) - pos);\n      end += n;\n      return result;\n   }\n\n   size_type  size()\n   {\n      return size_type(end - start);\n   }\n\n   size_type  capacity()\n   {\n      return size_type(last - start);\n   }\n\n   void*  data()const\n   {\n      return start;\n   }\n\n   size_type  index(void* ptr)\n   {\n      return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));\n   }\n\n   void  clear()\n   {\n      end = start;\n   }\n\n   void  align()\n   {\n      // move end up to a boundary:\n      end = start + (((end - start) + padding_mask) & ~padding_mask);\n   }\n   void swap(raw_storage& that)\n   {\n      std::swap(start, that.start);\n      std::swap(end, that.end);\n      std::swap(last, that.last);\n  }\n};\n\ninline raw_storage::raw_storage()\n{\n   last = start = end = 0;\n}\n\ninline raw_storage::raw_storage(size_type n)\n{\n   start = end = static_cast<pointer>(::operator new(n));\n   BOOST_REGEX_NOEH_ASSERT(start)\n   last = start + n;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n} // namespace boost\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_replace.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2009\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_format.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides formatting output routines for search and replace\n  *                operations.  Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_REPLACE_HPP\n#define BOOST_REGEX_V5_REGEX_REPLACE_HPP\n\n\nnamespace boost{\n\ntemplate <class OutputIterator, class BidirectionalIterator, class traits, class charT, class Formatter>\nOutputIterator regex_replace(OutputIterator out,\n                         BidirectionalIterator first,\n                         BidirectionalIterator last,\n                         const basic_regex<charT, traits>& e, \n                         Formatter fmt, \n                         match_flag_type flags = match_default)\n{\n   regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);\n   regex_iterator<BidirectionalIterator, charT, traits> j;\n   if(i == j)\n   {\n      if(!(flags & regex_constants::format_no_copy))\n         out = BOOST_REGEX_DETAIL_NS::copy(first, last, out);\n   }\n   else\n   {\n      BidirectionalIterator last_m(first);\n      while(i != j)\n      {\n         if(!(flags & regex_constants::format_no_copy))\n            out = BOOST_REGEX_DETAIL_NS::copy(i->prefix().first, i->prefix().second, out);\n         out = i->format(out, fmt, flags, e);\n         last_m = (*i)[0].second;\n         if(flags & regex_constants::format_first_only)\n            break;\n         ++i;\n      }\n      if(!(flags & regex_constants::format_no_copy))\n         out = BOOST_REGEX_DETAIL_NS::copy(last_m, last, out);\n   }\n   return out;\n}\n\ntemplate <class traits, class charT, class Formatter>\nstd::basic_string<charT> regex_replace(const std::basic_string<charT>& s,\n                         const basic_regex<charT, traits>& e, \n                         Formatter fmt,\n                         match_flag_type flags = match_default)\n{\n   std::basic_string<charT> result;\n   BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);\n   regex_replace(i, s.begin(), s.end(), e, fmt, flags);\n   return result;\n}\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V5_REGEX_REPLACE_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_search.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_search.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_search implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_SEARCH_HPP\n#define BOOST_REGEX_V5_REGEX_SEARCH_HPP\n\n\nnamespace boost{\n\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  match_results<BidiIterator, Allocator>& m, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags = match_default)\n{\n   return regex_search(first, last, m, e, flags, first);\n}\n\ntemplate <class BidiIterator, class Allocator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  match_results<BidiIterator, Allocator>& m, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags,\n                  BidiIterator base)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);\n   return matcher.find();\n}\n\n//\n// regex_search convenience interfaces:\n//\ntemplate <class charT, class Allocator, class traits>\ninline bool regex_search(const charT* str, \n                        match_results<const charT*, Allocator>& m, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + traits::length(str), m, e, flags);\n}\n\ntemplate <class ST, class SA, class Allocator, class charT, class traits>\ninline bool regex_search(const std::basic_string<charT, ST, SA>& s, \n                 match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), m, e, flags);\n}\n\ntemplate <class BidiIterator, class charT, class traits>\nbool regex_search(BidiIterator first, BidiIterator last, \n                  const basic_regex<charT, traits>& e, \n                  match_flag_type flags = match_default)\n{\n   if(e.flags() & regex_constants::failbit)\n      return false;\n\n   match_results<BidiIterator> m;\n   typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;\n   BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);\n   return matcher.find();\n}\n\ntemplate <class charT, class traits>\ninline bool regex_search(const charT* str, \n                        const basic_regex<charT, traits>& e, \n                        match_flag_type flags = match_default)\n{\n   return regex_search(str, str + traits::length(str), e, flags);\n}\n\ntemplate <class ST, class SA, class charT, class traits>\ninline bool regex_search(const std::basic_string<charT, ST, SA>& s, \n                 const basic_regex<charT, traits>& e, \n                 match_flag_type flags = match_default)\n{\n   return regex_search(s.begin(), s.end(), e, flags);\n}\n\n} // namespace boost\n\n#endif  // BOOST_REGEX_V5_REGEX_SEARCH_HPP\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_split.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_split.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Implements regex_split and associated functions.\n  *                Note this is an internal header file included\n  *                by regex.hpp, do not include on its own.\n  */\n\n#ifndef BOOST_REGEX_SPLIT_HPP\n#define BOOST_REGEX_SPLIT_HPP\n\nnamespace boost{\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS{\n\ntemplate <class charT>\nconst basic_regex<charT>& get_default_expression(charT)\n{\n   static const charT expression_text[4] = { '\\\\', 's', '+', '\\00', };\n   static const basic_regex<charT> e(expression_text);\n   return e;\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\nclass split_pred\n{\n   typedef std::basic_string<charT, Traits1, Alloc1> string_type;\n   typedef typename string_type::const_iterator iterator_type;\n   iterator_type* p_last;\n   OutputIterator* p_out;\n   std::size_t* p_max;\n   std::size_t initial_max;\npublic:\n   split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)\n      : p_last(a), p_out(b), p_max(c), initial_max(*c) {}\n\n   bool operator()(const match_results<iterator_type>& what);\n};\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\nbool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()\n   (const match_results<iterator_type>& what)\n{\n   *p_last = what[0].second;\n   if(what.size() > 1)\n   {\n      // output sub-expressions only:\n      for(unsigned i = 1; i < what.size(); ++i)\n      {\n         *(*p_out) = what.str(i);\n         ++(*p_out);\n         if(0 == --*p_max) return false;\n      }\n      return *p_max != 0;\n   }\n   else\n   {\n      // output $` only if it's not-null or not at the start of the input:\n      const sub_match<iterator_type>& sub = what[-1];\n      if((sub.first != sub.second) || (*p_max != initial_max))\n      {\n         *(*p_out) = sub.str();\n         ++(*p_out);\n         return --*p_max;\n      }\n   }\n   //\n   // initial null, do nothing:\n   return true;\n}\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>\nstd::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s, \n                   const basic_regex<charT, Traits2>& e,\n                   match_flag_type flags,\n                   std::size_t max_split)\n{\n   typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator  ci_t;\n   //typedef typename match_results<ci_t>::allocator_type                        match_allocator;\n   ci_t last = s.begin();\n   std::size_t init_size = max_split;\n   BOOST_REGEX_DETAIL_NS::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);\n   ci_t i, j;\n   i = s.begin();\n   j = s.end();\n   regex_grep(pred, i, j, e, flags);\n   //\n   // if there is still input left, do a final push as long as max_split\n   // is not exhausted, and we're not splitting sub-expressions rather \n   // than whitespace:\n   if(max_split && (last != s.end()) && (e.mark_count() == 0))\n   {\n      *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());\n      ++out;\n      last = s.end();\n      --max_split;\n   }\n   //\n   // delete from the string everything that has been processed so far:\n   s.erase(0, last - s.begin());\n   //\n   // return the number of new records pushed:\n   return init_size - max_split;\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>\ninline std::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s, \n                   const basic_regex<charT, Traits2>& e,\n                   match_flag_type flags = match_default)\n{\n   return regex_split(out, s, e, flags, UINT_MAX);\n}\n\ntemplate <class OutputIterator, class charT, class Traits1, class Alloc1>\ninline std::size_t regex_split(OutputIterator out,\n                   std::basic_string<charT, Traits1, Alloc1>& s)\n{\n   return regex_split(out, s, BOOST_REGEX_DETAIL_NS::get_default_expression(charT(0)), match_default, UINT_MAX);\n}\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_token_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_token_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides regex_token_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP\n#define BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP\n\n#include <memory>\n\nnamespace boost{\n\ntemplate <class BidirectionalIterator,\n          class charT,\n          class traits>\nclass regex_token_iterator_implementation \n{\n   typedef basic_regex<charT, traits> regex_type;\n   typedef sub_match<BidirectionalIterator>      value_type;\n\n   match_results<BidirectionalIterator> what;   // current match\n   BidirectionalIterator                base;    // start of search area\n   BidirectionalIterator                end;    // end of search area\n   const regex_type                     re;    // the expression\n   match_flag_type                      flags;  // match flags\n   value_type                           result; // the current string result\n   int                                  N;      // the current sub-expression being enumerated\n   std::vector<int>                     subs;   // the sub-expressions to enumerate\n\npublic:\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)\n      : end(last), re(*p), flags(f), N(0){ subs.push_back(sub); }\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)\n      : end(last), re(*p), flags(f), N(0), subs(v){}\n   template <std::size_t CN>\n   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)\n      : end(last), re(*p), flags(f), N(0)\n   {\n      for(std::size_t i = 0; i < CN; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n   regex_token_iterator_implementation(const regex_token_iterator_implementation& other) = default;\n   bool init(BidirectionalIterator first)\n   {\n      N = 0;\n      base = first;\n      if(regex_search(first, end, what, re, flags, base) == true)\n      {\n         N = 0;\n         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);\n         return true;\n      }\n      else if((subs[N] == -1) && (first != end))\n      {\n         result.first = first;\n         result.second = end;\n         result.matched = (first != end);\n         N = -1;\n         return true;\n      }\n      return false;\n   }\n   bool compare(const regex_token_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) \n         && (end == that.end) \n         && (flags == that.flags) \n         && (N == that.N) \n         && (what[0].first == that.what[0].first) \n         && (what[0].second == that.what[0].second);\n   }\n   const value_type& get()\n   { return result; }\n   bool next()\n   {\n      if(N == -1)\n         return false;\n      if(N+1 < (int)subs.size())\n      {\n         ++N;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      //if(what.prefix().first != what[0].second)\n      //   flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;\n      BidirectionalIterator last_end(what[0].second);\n      if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))\n      {\n         N =0;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      else if((last_end != end) && (subs[0] == -1))\n      {\n         N =-1;\n         result.first = last_end;\n         result.second = end;\n         result.matched = (last_end != end);\n         return true;\n      }\n      return false;\n   }\nprivate:\n   regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator, \n          class charT = typename std::iterator_traits<BidirectionalIterator>::value_type,\n          class traits = regex_traits<charT> >\nclass regex_token_iterator \n{\nprivate:\n   typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;\n   typedef std::shared_ptr<impl> pimpl;\npublic:\n   typedef          basic_regex<charT, traits>                   regex_type;\n   typedef          sub_match<BidirectionalIterator>                        value_type;\n   typedef typename std::iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   regex_token_iterator(){}\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        int submatch = 0, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatch, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        const std::vector<int>& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   template <std::size_t N>\n   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const int (&submatches)[N], match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   regex_token_iterator(const regex_token_iterator& that)\n      : pdata(that.pdata) {}\n   regex_token_iterator& operator=(const regex_token_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const regex_token_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const regex_token_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   regex_token_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   regex_token_iterator operator++(int)\n   {\n      regex_token_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && (pdata.use_count() > 1))\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef regex_token_iterator<const char*> cregex_token_iterator;\ntypedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;\n#ifndef BOOST_NO_WREGEX\ntypedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;\ntypedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;\n#endif\n\ntemplate <class charT, class traits>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <class charT, class traits, std::size_t N>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA, std::size_t N>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <class charT, class traits>\ninline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);\n}\ntemplate <class charT, class traits, class ST, class SA>\ninline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);\n}\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits classes.\n  */\n\n#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_REGEX_TRAITS_HPP_INCLUDED\n\n#include <boost/regex/config.hpp>\n#include <boost/regex/v5/regex_workaround.hpp>\n#include <boost/regex/v5/syntax_type.hpp>\n#include <boost/regex/v5/error_type.hpp>\n#include <boost/regex/v5/regex_traits_defaults.hpp>\n#include <boost/regex/v5/cpp_regex_traits.hpp>\n#include <boost/regex/v5/c_regex_traits.hpp>\n#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)\n#     include <boost/regex/v5/w32_regex_traits.hpp>\n#endif\n#include <boost/regex_fwd.hpp>\n\nnamespace boost{\n\ntemplate <class charT, class implementationT >\nstruct regex_traits : public implementationT\n{\n   regex_traits() : implementationT() {}\n};\n\n//\n// class regex_traits_wrapper.\n// this is what our implementation will actually store;\n// it provides default implementations of the \"optional\"\n// interfaces that we support, in addition to the\n// required \"standard\" ones:\n//\nnamespace BOOST_REGEX_DETAIL_NS{\n\n   template <class T>\n   struct has_boost_extensions_tag\n   {\n      template <class U>\n      static double checker(U*, typename U::boost_extensions_tag* = nullptr);\n      static char   checker(...);\n      static T* get();\n\n      static const bool value = sizeof(checker(get())) > 1;\n   };\n   \n\ntemplate <class BaseT>\nstruct default_wrapper : public BaseT\n{\n   typedef typename BaseT::char_type char_type;\n   std::string error_string(::boost::regex_constants::error_type e)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(e);\n   }\n   ::boost::regex_constants::syntax_type syntax_type(char_type c)const\n   {\n      return (char_type(c & 0x7f) == c) ? get_default_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::syntax_char;\n   }\n   ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c)const\n   {\n      return (char_type(c & 0x7f) == c) ? get_default_escape_syntax_type(static_cast<char>(c)) : ::boost::regex_constants::escape_type_identity;\n   }\n   std::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n   }\n   char_type translate(char_type c, bool icase)const\n   {\n      return (icase ? this->translate_nocase(c) : this->translate(c));\n   }\n   char_type translate(char_type c)const\n   {\n      return BaseT::translate(c);\n   }\n   char_type tolower(char_type c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);\n   }\n   char_type toupper(char_type c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);\n   }\n};\n\ntemplate <class BaseT, bool has_extensions>\nstruct compute_wrapper_base\n{\n   typedef BaseT type;\n};\ntemplate <class BaseT>\nstruct compute_wrapper_base<BaseT, false>\n{\n   typedef default_wrapper<BaseT> type;\n};\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\ntemplate <class BaseT>\nstruct regex_traits_wrapper \n   : public ::boost::BOOST_REGEX_DETAIL_NS::compute_wrapper_base<\n               BaseT, \n               ::boost::BOOST_REGEX_DETAIL_NS::has_boost_extensions_tag<BaseT>::value\n            >::type\n{\n   regex_traits_wrapper(){}\nprivate:\n   regex_traits_wrapper(const regex_traits_wrapper&);\n   regex_traits_wrapper& operator=(const regex_traits_wrapper&);\n};\n\n} // namespace boost\n\n#endif // include\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_traits_defaults.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the\n * Boost Software License, Version 1.0. (See accompanying file\n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_traits_defaults.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares API's for access to regex_traits default properties.\n  */\n\n#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED\n\n#include <boost/regex/config.hpp>\n\n#include <boost/regex/v5/syntax_type.hpp>\n#include <boost/regex/v5/error_type.hpp>\n#include <boost/regex/v5/regex_workaround.hpp>\n#include <type_traits>\n#include <cstdint>\n#include <cctype>\n#include <locale>\n#include <cwctype>\n#include <limits>\n\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n\n\n//\n// helpers to suppress warnings:\n//\ntemplate <class charT>\ninline bool is_extended(charT c)\n{\n   typedef typename std::make_unsigned<charT>::type unsigned_type; \n   return (sizeof(charT) > 1) && (static_cast<unsigned_type>(c) >= 256u); \n}\ninline bool is_extended(char)\n{ return false; }\n\ninline const char*  get_default_syntax(regex_constants::syntax_type n)\n{\n   // if the user hasn't supplied a message catalog, then this supplies\n   // default \"messages\" for us to load in the range 1-100.\n   const char* messages[] = {\n         \"\",\n         \"(\",\n         \")\",\n         \"$\",\n         \"^\",\n         \".\",\n         \"*\",\n         \"+\",\n         \"?\",\n         \"[\",\n         \"]\",\n         \"|\",\n         \"\\\\\",\n         \"#\",\n         \"-\",\n         \"{\",\n         \"}\",\n         \"0123456789\",\n         \"b\",\n         \"B\",\n         \"<\",\n         \">\",\n         \"\",\n         \"\",\n         \"A`\",\n         \"z'\",\n         \"\\n\",\n         \",\",\n         \"a\",\n         \"f\",\n         \"n\",\n         \"r\",\n         \"t\",\n         \"v\",\n         \"x\",\n         \"c\",\n         \":\",\n         \"=\",\n         \"e\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"\",\n         \"E\",\n         \"Q\",\n         \"X\",\n         \"C\",\n         \"Z\",\n         \"G\",\n         \"!\",\n         \"p\",\n         \"P\",\n         \"N\",\n         \"gk\",\n         \"K\",\n         \"R\",\n   };\n\n   return ((n >= (sizeof(messages) / sizeof(messages[1]))) ? \"\" : messages[n]);\n}\n\ninline const char*  get_default_error_string(regex_constants::error_type n)\n{\n   static const char* const s_default_error_messages[] = {\n      \"Success\",                                                            /* REG_NOERROR 0 error_ok */\n      \"No match\",                                                           /* REG_NOMATCH 1 error_no_match */\n      \"Invalid regular expression.\",                                        /* REG_BADPAT 2 error_bad_pattern */\n      \"Invalid collation character.\",                                       /* REG_ECOLLATE 3 error_collate */\n      \"Invalid character class name, collating name, or character range.\",  /* REG_ECTYPE 4 error_ctype */\n      \"Invalid or unterminated escape sequence.\",                           /* REG_EESCAPE 5 error_escape */\n      \"Invalid back reference: specified capturing group does not exist.\",  /* REG_ESUBREG 6 error_backref */\n      \"Unmatched [ or [^ in character class declaration.\",                  /* REG_EBRACK 7 error_brack */\n      \"Unmatched marking parenthesis ( or \\\\(.\",                            /* REG_EPAREN 8 error_paren */\n      \"Unmatched quantified repeat operator { or \\\\{.\",                     /* REG_EBRACE 9 error_brace */\n      \"Invalid content of repeat range.\",                                   /* REG_BADBR 10 error_badbrace */\n      \"Invalid range end in character class\",                               /* REG_ERANGE 11 error_range */\n      \"Out of memory.\",                                                     /* REG_ESPACE 12 error_space NOT USED */\n      \"Invalid preceding regular expression prior to repetition operator.\", /* REG_BADRPT 13 error_badrepeat */\n      \"Premature end of regular expression\",                                /* REG_EEND 14 error_end NOT USED */\n      \"Regular expression is too large.\",                                   /* REG_ESIZE 15 error_size NOT USED */\n      \"Unmatched ) or \\\\)\",                                                 /* REG_ERPAREN 16 error_right_paren NOT USED */\n      \"Empty regular expression.\",                                          /* REG_EMPTY 17 error_empty */\n      \"The complexity of matching the regular expression exceeded predefined bounds.  \"\n      \"Try refactoring the regular expression to make each choice made by the state machine unambiguous.  \"\n      \"This exception is thrown to prevent \\\"eternal\\\" matches that take an \"\n      \"indefinite period time to locate.\",                                  /* REG_ECOMPLEXITY 18 error_complexity */\n      \"Ran out of stack space trying to match the regular expression.\",     /* REG_ESTACK 19 error_stack */\n      \"Invalid or unterminated Perl (?...) sequence.\",                      /* REG_E_PERL 20 error_perl */\n      \"Unknown error.\",                                                     /* REG_E_UNKNOWN 21 error_unknown */\n   };\n\n   return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[::boost::regex_constants::error_unknown] : s_default_error_messages[n];\n}\n\ninline regex_constants::syntax_type  get_default_syntax_type(char c)\n{\n   //\n   // char_syntax determines how the compiler treats a given character\n   // in a regular expression.\n   //\n   static regex_constants::syntax_type char_syntax[] = {\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_newline,     /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /* */    // 32\n      regex_constants::syntax_not,        /*!*/\n      regex_constants::syntax_char,        /*\"*/\n      regex_constants::syntax_hash,        /*#*/\n      regex_constants::syntax_dollar,        /*$*/\n      regex_constants::syntax_char,        /*%*/\n      regex_constants::syntax_char,        /*&*/\n      regex_constants::escape_type_end_buffer,  /*'*/\n      regex_constants::syntax_open_mark,        /*(*/\n      regex_constants::syntax_close_mark,        /*)*/\n      regex_constants::syntax_star,        /***/\n      regex_constants::syntax_plus,        /*+*/\n      regex_constants::syntax_comma,        /*,*/\n      regex_constants::syntax_dash,        /*-*/\n      regex_constants::syntax_dot,        /*.*/\n      regex_constants::syntax_char,        /*/*/\n      regex_constants::syntax_digit,        /*0*/\n      regex_constants::syntax_digit,        /*1*/\n      regex_constants::syntax_digit,        /*2*/\n      regex_constants::syntax_digit,        /*3*/\n      regex_constants::syntax_digit,        /*4*/\n      regex_constants::syntax_digit,        /*5*/\n      regex_constants::syntax_digit,        /*6*/\n      regex_constants::syntax_digit,        /*7*/\n      regex_constants::syntax_digit,        /*8*/\n      regex_constants::syntax_digit,        /*9*/\n      regex_constants::syntax_colon,        /*:*/\n      regex_constants::syntax_char,        /*;*/\n      regex_constants::escape_type_left_word, /*<*/\n      regex_constants::syntax_equal,        /*=*/\n      regex_constants::escape_type_right_word, /*>*/\n      regex_constants::syntax_question,        /*?*/\n      regex_constants::syntax_char,        /*@*/\n      regex_constants::syntax_char,        /*A*/\n      regex_constants::syntax_char,        /*B*/\n      regex_constants::syntax_char,        /*C*/\n      regex_constants::syntax_char,        /*D*/\n      regex_constants::syntax_char,        /*E*/\n      regex_constants::syntax_char,        /*F*/\n      regex_constants::syntax_char,        /*G*/\n      regex_constants::syntax_char,        /*H*/\n      regex_constants::syntax_char,        /*I*/\n      regex_constants::syntax_char,        /*J*/\n      regex_constants::syntax_char,        /*K*/\n      regex_constants::syntax_char,        /*L*/\n      regex_constants::syntax_char,        /*M*/\n      regex_constants::syntax_char,        /*N*/\n      regex_constants::syntax_char,        /*O*/\n      regex_constants::syntax_char,        /*P*/\n      regex_constants::syntax_char,        /*Q*/\n      regex_constants::syntax_char,        /*R*/\n      regex_constants::syntax_char,        /*S*/\n      regex_constants::syntax_char,        /*T*/\n      regex_constants::syntax_char,        /*U*/\n      regex_constants::syntax_char,        /*V*/\n      regex_constants::syntax_char,        /*W*/\n      regex_constants::syntax_char,        /*X*/\n      regex_constants::syntax_char,        /*Y*/\n      regex_constants::syntax_char,        /*Z*/\n      regex_constants::syntax_open_set,        /*[*/\n      regex_constants::syntax_escape,        /*\\*/\n      regex_constants::syntax_close_set,        /*]*/\n      regex_constants::syntax_caret,        /*^*/\n      regex_constants::syntax_char,        /*_*/\n      regex_constants::syntax_char,        /*`*/\n      regex_constants::syntax_char,        /*a*/\n      regex_constants::syntax_char,        /*b*/\n      regex_constants::syntax_char,        /*c*/\n      regex_constants::syntax_char,        /*d*/\n      regex_constants::syntax_char,        /*e*/\n      regex_constants::syntax_char,        /*f*/\n      regex_constants::syntax_char,        /*g*/\n      regex_constants::syntax_char,        /*h*/\n      regex_constants::syntax_char,        /*i*/\n      regex_constants::syntax_char,        /*j*/\n      regex_constants::syntax_char,        /*k*/\n      regex_constants::syntax_char,        /*l*/\n      regex_constants::syntax_char,        /*m*/\n      regex_constants::syntax_char,        /*n*/\n      regex_constants::syntax_char,        /*o*/\n      regex_constants::syntax_char,        /*p*/\n      regex_constants::syntax_char,        /*q*/\n      regex_constants::syntax_char,        /*r*/\n      regex_constants::syntax_char,        /*s*/\n      regex_constants::syntax_char,        /*t*/\n      regex_constants::syntax_char,        /*u*/\n      regex_constants::syntax_char,        /*v*/\n      regex_constants::syntax_char,        /*w*/\n      regex_constants::syntax_char,        /*x*/\n      regex_constants::syntax_char,        /*y*/\n      regex_constants::syntax_char,        /*z*/\n      regex_constants::syntax_open_brace,        /*{*/\n      regex_constants::syntax_or,        /*|*/\n      regex_constants::syntax_close_brace,        /*}*/\n      regex_constants::syntax_char,        /*~*/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n      regex_constants::syntax_char,        /**/\n   };\n\n   return char_syntax[(unsigned char)c];\n}\n\ninline regex_constants::escape_syntax_type  get_default_escape_syntax_type(char c)\n{\n   //\n   // char_syntax determines how the compiler treats a given character\n   // in a regular expression.\n   //\n   static regex_constants::escape_syntax_type char_syntax[] = {\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,     /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /* */    // 32\n      regex_constants::escape_type_identity,        /*!*/\n      regex_constants::escape_type_identity,        /*\"*/\n      regex_constants::escape_type_identity,        /*#*/\n      regex_constants::escape_type_identity,        /*$*/\n      regex_constants::escape_type_identity,        /*%*/\n      regex_constants::escape_type_identity,        /*&*/\n      regex_constants::escape_type_end_buffer,        /*'*/\n      regex_constants::syntax_open_mark,        /*(*/\n      regex_constants::syntax_close_mark,        /*)*/\n      regex_constants::escape_type_identity,        /***/\n      regex_constants::syntax_plus,                 /*+*/\n      regex_constants::escape_type_identity,        /*,*/\n      regex_constants::escape_type_identity,        /*-*/\n      regex_constants::escape_type_identity,        /*.*/\n      regex_constants::escape_type_identity,        /*/*/\n      regex_constants::escape_type_decimal,        /*0*/\n      regex_constants::escape_type_backref,        /*1*/\n      regex_constants::escape_type_backref,        /*2*/\n      regex_constants::escape_type_backref,        /*3*/\n      regex_constants::escape_type_backref,        /*4*/\n      regex_constants::escape_type_backref,        /*5*/\n      regex_constants::escape_type_backref,        /*6*/\n      regex_constants::escape_type_backref,        /*7*/\n      regex_constants::escape_type_backref,        /*8*/\n      regex_constants::escape_type_backref,        /*9*/\n      regex_constants::escape_type_identity,        /*:*/\n      regex_constants::escape_type_identity,        /*;*/\n      regex_constants::escape_type_left_word,        /*<*/\n      regex_constants::escape_type_identity,        /*=*/\n      regex_constants::escape_type_right_word,        /*>*/\n      regex_constants::syntax_question,              /*?*/\n      regex_constants::escape_type_identity,         /*@*/\n      regex_constants::escape_type_start_buffer,     /*A*/\n      regex_constants::escape_type_not_word_assert,  /*B*/\n      regex_constants::escape_type_C,                /*C*/\n      regex_constants::escape_type_not_class,        /*D*/\n      regex_constants::escape_type_E,                /*E*/\n      regex_constants::escape_type_not_class,        /*F*/\n      regex_constants::escape_type_G,                /*G*/\n      regex_constants::escape_type_not_class,        /*H*/\n      regex_constants::escape_type_not_class,        /*I*/\n      regex_constants::escape_type_not_class,        /*J*/\n      regex_constants::escape_type_reset_start_mark, /*K*/\n      regex_constants::escape_type_not_class,        /*L*/\n      regex_constants::escape_type_not_class,        /*M*/\n      regex_constants::escape_type_named_char,       /*N*/\n      regex_constants::escape_type_not_class,        /*O*/\n      regex_constants::escape_type_not_property,     /*P*/\n      regex_constants::escape_type_Q,                /*Q*/\n      regex_constants::escape_type_line_ending,      /*R*/\n      regex_constants::escape_type_not_class,        /*S*/\n      regex_constants::escape_type_not_class,        /*T*/\n      regex_constants::escape_type_not_class,        /*U*/\n      regex_constants::escape_type_not_class,        /*V*/\n      regex_constants::escape_type_not_class,        /*W*/\n      regex_constants::escape_type_X,                /*X*/\n      regex_constants::escape_type_not_class,        /*Y*/\n      regex_constants::escape_type_Z,                /*Z*/\n      regex_constants::escape_type_identity,        /*[*/\n      regex_constants::escape_type_identity,        /*\\*/\n      regex_constants::escape_type_identity,        /*]*/\n      regex_constants::escape_type_identity,        /*^*/\n      regex_constants::escape_type_identity,        /*_*/\n      regex_constants::escape_type_start_buffer,        /*`*/\n      regex_constants::escape_type_control_a,        /*a*/\n      regex_constants::escape_type_word_assert,        /*b*/\n      regex_constants::escape_type_ascii_control,        /*c*/\n      regex_constants::escape_type_class,        /*d*/\n      regex_constants::escape_type_e,        /*e*/\n      regex_constants::escape_type_control_f,       /*f*/\n      regex_constants::escape_type_extended_backref,  /*g*/\n      regex_constants::escape_type_class,        /*h*/\n      regex_constants::escape_type_class,        /*i*/\n      regex_constants::escape_type_class,        /*j*/\n      regex_constants::escape_type_extended_backref, /*k*/\n      regex_constants::escape_type_class,        /*l*/\n      regex_constants::escape_type_class,        /*m*/\n      regex_constants::escape_type_control_n,       /*n*/\n      regex_constants::escape_type_class,           /*o*/\n      regex_constants::escape_type_property,        /*p*/\n      regex_constants::escape_type_class,           /*q*/\n      regex_constants::escape_type_control_r,       /*r*/\n      regex_constants::escape_type_class,           /*s*/\n      regex_constants::escape_type_control_t,       /*t*/\n      regex_constants::escape_type_class,         /*u*/\n      regex_constants::escape_type_control_v,       /*v*/\n      regex_constants::escape_type_class,           /*w*/\n      regex_constants::escape_type_hex,             /*x*/\n      regex_constants::escape_type_class,           /*y*/\n      regex_constants::escape_type_end_buffer,      /*z*/\n      regex_constants::syntax_open_brace,           /*{*/\n      regex_constants::syntax_or,                   /*|*/\n      regex_constants::syntax_close_brace,          /*}*/\n      regex_constants::escape_type_identity,        /*~*/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n      regex_constants::escape_type_identity,        /**/\n   };\n\n   return char_syntax[(unsigned char)c];\n}\n\n// is charT c a combining character?\ninline bool  is_combining_implementation(std::uint_least16_t c)\n{\n   const std::uint_least16_t combining_ranges[] = { 0x0300, 0x0361,\n                           0x0483, 0x0486,\n                           0x0903, 0x0903,\n                           0x093E, 0x0940,\n                           0x0949, 0x094C,\n                           0x0982, 0x0983,\n                           0x09BE, 0x09C0,\n                           0x09C7, 0x09CC,\n                           0x09D7, 0x09D7,\n                           0x0A3E, 0x0A40,\n                           0x0A83, 0x0A83,\n                           0x0ABE, 0x0AC0,\n                           0x0AC9, 0x0ACC,\n                           0x0B02, 0x0B03,\n                           0x0B3E, 0x0B3E,\n                           0x0B40, 0x0B40,\n                           0x0B47, 0x0B4C,\n                           0x0B57, 0x0B57,\n                           0x0B83, 0x0B83,\n                           0x0BBE, 0x0BBF,\n                           0x0BC1, 0x0BCC,\n                           0x0BD7, 0x0BD7,\n                           0x0C01, 0x0C03,\n                           0x0C41, 0x0C44,\n                           0x0C82, 0x0C83,\n                           0x0CBE, 0x0CBE,\n                           0x0CC0, 0x0CC4,\n                           0x0CC7, 0x0CCB,\n                           0x0CD5, 0x0CD6,\n                           0x0D02, 0x0D03,\n                           0x0D3E, 0x0D40,\n                           0x0D46, 0x0D4C,\n                           0x0D57, 0x0D57,\n                           0x0F7F, 0x0F7F,\n                           0x20D0, 0x20E1,\n                           0x3099, 0x309A,\n                           0xFE20, 0xFE23,\n                           0xffff, 0xffff, };\n\n   const std::uint_least16_t* p = combining_ranges + 1;\n   while (*p < c) p += 2;\n   --p;\n   if ((c >= *p) && (c <= *(p + 1)))\n      return true;\n   return false;\n}\n\ntemplate <class charT>\ninline bool is_combining(charT c)\n{\n   return (c <= static_cast<charT>(0)) ? false : ((c >= static_cast<charT>((std::numeric_limits<uint_least16_t>::max)())) ? false : is_combining_implementation(static_cast<unsigned short>(c)));\n}\ntemplate <>\ninline bool is_combining<char>(char)\n{\n   return false;\n}\ntemplate <>\ninline bool is_combining<signed char>(signed char)\n{\n   return false;\n}\ntemplate <>\ninline bool is_combining<unsigned char>(unsigned char)\n{\n   return false;\n}\n#ifdef _MSC_VER\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return is_combining_implementation(static_cast<unsigned short>(c));\n}\n#elif !defined(__DECCXX) && !defined(__osf__) && !defined(__OSF__) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\n#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return is_combining_implementation(static_cast<unsigned short>(c));\n}\n#else\ntemplate<>\ninline bool is_combining<wchar_t>(wchar_t c)\n{\n   return (c >= (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c));\n}\n#endif\n#endif\n\n//\n// is a charT c a line separator?\n//\ntemplate <class charT>\ninline bool is_separator(charT c)\n{\n   return BOOST_REGEX_MAKE_BOOL(\n      (c == static_cast<charT>('\\n'))\n      || (c == static_cast<charT>('\\r'))\n      || (c == static_cast<charT>('\\f'))\n      || (static_cast<std::uint16_t>(c) == 0x2028u)\n      || (static_cast<std::uint16_t>(c) == 0x2029u)\n      || (static_cast<std::uint16_t>(c) == 0x85u));\n}\ntemplate <>\ninline bool is_separator<char>(char c)\n{\n   return BOOST_REGEX_MAKE_BOOL((c == '\\n') || (c == '\\r') || (c == '\\f'));\n}\n\n//\n// get a default collating element:\n//\ninline std::string  lookup_default_collate_name(const std::string& name)\n{\n   //\n   // these are the POSIX collating names:\n   //\n   static const char* def_coll_names[] = {\n   \"NUL\", \"SOH\", \"STX\", \"ETX\", \"EOT\", \"ENQ\", \"ACK\", \"alert\", \"backspace\", \"tab\", \"newline\",\n   \"vertical-tab\", \"form-feed\", \"carriage-return\", \"SO\", \"SI\", \"DLE\", \"DC1\", \"DC2\", \"DC3\", \"DC4\", \"NAK\",\n   \"SYN\", \"ETB\", \"CAN\", \"EM\", \"SUB\", \"ESC\", \"IS4\", \"IS3\", \"IS2\", \"IS1\", \"space\", \"exclamation-mark\",\n   \"quotation-mark\", \"number-sign\", \"dollar-sign\", \"percent-sign\", \"ampersand\", \"apostrophe\",\n   \"left-parenthesis\", \"right-parenthesis\", \"asterisk\", \"plus-sign\", \"comma\", \"hyphen\",\n   \"period\", \"slash\", \"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\",\n   \"colon\", \"semicolon\", \"less-than-sign\", \"equals-sign\", \"greater-than-sign\",\n   \"question-mark\", \"commercial-at\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\",\n   \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"left-square-bracket\", \"backslash\",\n   \"right-square-bracket\", \"circumflex\", \"underscore\", \"grave-accent\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\",\n   \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"left-curly-bracket\",\n   \"vertical-line\", \"right-curly-bracket\", \"tilde\", \"DEL\", \"\",\n   };\n\n   // these multi-character collating elements\n   // should keep most Western-European locales\n   // happy - we should really localise these a\n   // little more - but this will have to do for\n   // now:\n\n   static const char* def_multi_coll[] = {\n      \"ae\",\n      \"Ae\",\n      \"AE\",\n      \"ch\",\n      \"Ch\",\n      \"CH\",\n      \"ll\",\n      \"Ll\",\n      \"LL\",\n      \"ss\",\n      \"Ss\",\n      \"SS\",\n      \"nj\",\n      \"Nj\",\n      \"NJ\",\n      \"dz\",\n      \"Dz\",\n      \"DZ\",\n      \"lj\",\n      \"Lj\",\n      \"LJ\",\n      \"\",\n   };\n\n   unsigned int i = 0;\n   while (*def_coll_names[i])\n   {\n      if (def_coll_names[i] == name)\n      {\n         return std::string(1, char(i));\n      }\n      ++i;\n   }\n   i = 0;\n   while (*def_multi_coll[i])\n   {\n      if (def_multi_coll[i] == name)\n      {\n         return def_multi_coll[i];\n      }\n      ++i;\n   }\n   return std::string();\n}\n\n//\n// get the state_id of a character classification, the individual\n// traits classes then transform that state_id into a bitmask:\n//\ntemplate <class charT>\nstruct character_pointer_range\n{\n   const charT* p1;\n   const charT* p2;\n\n   bool operator < (const character_pointer_range& r)const\n   {\n      return std::lexicographical_compare(p1, p2, r.p1, r.p2);\n   }\n   bool operator == (const character_pointer_range& r)const\n   {\n      // Not only do we check that the ranges are of equal size before\n      // calling std::equal, but there is no other algorithm available:\n      // not even a non-standard MS one.  So forward to unchecked_equal\n      // in the MS case.\n#ifdef __cpp_lib_robust_nonmodifying_seq_ops\n      return std::equal(p1, p2, r.p1, r.p2);\n#elif defined(BOOST_REGEX_MSVC)\n      if (((p2 - p1) != (r.p2 - r.p1)))\n         return false;\n      const charT* with = r.p1;\n      const charT* pos = p1;\n      while (pos != p2)\n         if (*pos++ != *with++) return false;\n      return true;\n\n#else\n      return ((p2 - p1) == (r.p2 - r.p1)) && std::equal(p1, p2, r.p1);\n#endif\n   }\n};\ntemplate <class charT>\nint get_default_class_id(const charT* p1, const charT* p2)\n{\n   static const charT data[73] = {\n      'a', 'l', 'n', 'u', 'm',\n      'a', 'l', 'p', 'h', 'a',\n      'b', 'l', 'a', 'n', 'k',\n      'c', 'n', 't', 'r', 'l',\n      'd', 'i', 'g', 'i', 't',\n      'g', 'r', 'a', 'p', 'h',\n      'l', 'o', 'w', 'e', 'r',\n      'p', 'r', 'i', 'n', 't',\n      'p', 'u', 'n', 'c', 't',\n      's', 'p', 'a', 'c', 'e',\n      'u', 'n', 'i', 'c', 'o', 'd', 'e',\n      'u', 'p', 'p', 'e', 'r',\n      'v',\n      'w', 'o', 'r', 'd',\n      'x', 'd', 'i', 'g', 'i', 't',\n   };\n\n   static const character_pointer_range<charT> ranges[21] =\n   {\n      {data+0, data+5,}, // alnum\n      {data+5, data+10,}, // alpha\n      {data+10, data+15,}, // blank\n      {data+15, data+20,}, // cntrl\n      {data+20, data+21,}, // d\n      {data+20, data+25,}, // digit\n      {data+25, data+30,}, // graph\n      {data+29, data+30,}, // h\n      {data+30, data+31,}, // l\n      {data+30, data+35,}, // lower\n      {data+35, data+40,}, // print\n      {data+40, data+45,}, // punct\n      {data+45, data+46,}, // s\n      {data+45, data+50,}, // space\n      {data+57, data+58,}, // u\n      {data+50, data+57,}, // unicode\n      {data+57, data+62,}, // upper\n      {data+62, data+63,}, // v\n      {data+63, data+64,}, // w\n      {data+63, data+67,}, // word\n      {data+67, data+73,}, // xdigit\n   };\n   const character_pointer_range<charT>* ranges_begin = ranges;\n   const character_pointer_range<charT>* ranges_end = ranges + (sizeof(ranges)/sizeof(ranges[0]));\n\n   character_pointer_range<charT> t = { p1, p2, };\n   const character_pointer_range<charT>* p = std::lower_bound(ranges_begin, ranges_end, t);\n   if((p != ranges_end) && (t == *p))\n      return static_cast<int>(p - ranges);\n   return -1;\n}\n\n//\n// helper functions:\n//\ntemplate <class charT>\nstd::ptrdiff_t global_length(const charT* p)\n{\n   std::ptrdiff_t n = 0;\n   while(*p)\n   {\n      ++p;\n      ++n;\n   }\n   return n;\n}\ntemplate<>\ninline std::ptrdiff_t global_length<char>(const char* p)\n{\n   return (std::strlen)(p);\n}\n#ifndef BOOST_NO_WREGEX\ntemplate<>\ninline std::ptrdiff_t global_length<wchar_t>(const wchar_t* p)\n{\n   return (std::ptrdiff_t)(std::wcslen)(p);\n}\n#endif\ntemplate <class charT>\ninline charT  global_lower(charT c)\n{\n   return c;\n}\ntemplate <class charT>\ninline charT  global_upper(charT c)\n{\n   return c;\n}\n\ninline char  do_global_lower(char c)\n{\n   return static_cast<char>((std::tolower)((unsigned char)c));\n}\n\ninline char  do_global_upper(char c)\n{\n   return static_cast<char>((std::toupper)((unsigned char)c));\n}\n#ifndef BOOST_NO_WREGEX\ninline wchar_t  do_global_lower(wchar_t c)\n{\n   return (std::towlower)(c);\n}\n\ninline wchar_t  do_global_upper(wchar_t c)\n{\n   return (std::towupper)(c);\n}\n#endif\n//\n// This sucks: declare template specialisations of global_lower/global_upper\n// that just forward to the non-template implementation functions.  We do\n// this because there is one compiler (Compaq Tru64 C++) that doesn't seem\n// to differentiate between templates and non-template overloads....\n// what's more, the primary template, plus all overloads have to be\n// defined in the same translation unit (if one is inline they all must be)\n// otherwise the \"local template instantiation\" compiler option can pick\n// the wrong instantiation when linking:\n//\ntemplate<> inline char  global_lower<char>(char c) { return do_global_lower(c); }\ntemplate<> inline char  global_upper<char>(char c) { return do_global_upper(c); }\n#ifndef BOOST_NO_WREGEX\ntemplate<> inline wchar_t  global_lower<wchar_t>(wchar_t c) { return do_global_lower(c); }\ntemplate<> inline wchar_t  global_upper<wchar_t>(wchar_t c) { return do_global_upper(c); }\n#endif\n\ntemplate <class charT>\nint global_value(charT c)\n{\n   static const charT zero = '0';\n   static const charT nine = '9';\n   static const charT a = 'a';\n   static const charT f = 'f';\n   static const charT A = 'A';\n   static const charT F = 'F';\n\n   if(c > f) return -1;\n   if(c >= a) return 10 + (c - a);\n   if(c > F) return -1;\n   if(c >= A) return 10 + (c - A);\n   if(c > nine) return -1;\n   if(c >= zero) return c - zero;\n   return -1;\n}\ntemplate <class charT, class traits>\nstd::intmax_t global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)\n{\n   (void)t; // warning suppression\n   std::intmax_t limit = (std::numeric_limits<std::intmax_t>::max)() / radix;\n   std::intmax_t next_value = t.value(*p1, radix);\n   if((p1 == p2) || (next_value < 0) || (next_value >= radix))\n      return -1;\n   std::intmax_t result = 0;\n   while(p1 != p2)\n   {\n      next_value = t.value(*p1, radix);\n      if((next_value < 0) || (next_value >= radix))\n         break;\n      result *= radix;\n      result += next_value;\n      ++p1;\n      if (result > limit)\n         return -1;\n   }\n   return result;\n}\n\ntemplate <class charT>\ninline typename std::enable_if<(sizeof(charT) > 1), const charT*>::type get_escape_R_string()\n{\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4309 4245)\n#endif\n   static const charT e1[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\\x0D', '\\x0A', '?',\n      '|', '[', '\\x0A', '\\x0B', '\\x0C', static_cast<charT>(0x85), static_cast<charT>(0x2028),\n      static_cast<charT>(0x2029), ']', ')', ')', '\\0' };\n   static const charT e2[] = { '(', '?', '-', 'x', ':', '(', '?', '>', '\\x0D', '\\x0A', '?',\n      '|', '[', '\\x0A', '\\x0B', '\\x0C', static_cast<charT>(0x85), ']', ')', ')', '\\0' };\n\n   charT c = static_cast<charT>(0x2029u);\n   bool b = (static_cast<unsigned>(c) == 0x2029u);\n\n   return (b ? e1 : e2);\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n}\n\ntemplate <class charT>\ninline typename std::enable_if<(sizeof(charT) == 1), const charT*>::type get_escape_R_string()\n{\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4309 4245)\n#endif\n   static const charT e2[] = { \n      static_cast<charT>('('), \n      static_cast<charT>('?'), \n      static_cast<charT>('-'), \n      static_cast<charT>('x'), \n      static_cast<charT>(':'), \n      static_cast<charT>('('), \n      static_cast<charT>('?'), \n      static_cast<charT>('>'), \n      static_cast<charT>('\\x0D'), \n      static_cast<charT>('\\x0A'), \n      static_cast<charT>('?'),\n      static_cast<charT>('|'), \n      static_cast<charT>('['), \n      static_cast<charT>('\\x0A'), \n      static_cast<charT>('\\x0B'), \n      static_cast<charT>('\\x0C'), \n      static_cast<charT>('\\x85'), \n      static_cast<charT>(']'), \n      static_cast<charT>(')'), \n      static_cast<charT>(')'), \n      static_cast<charT>('\\0') \n   };\n   return e2;\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n}\n\n} // BOOST_REGEX_DETAIL_NS\n} // boost\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/regex_workaround.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2005\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         regex_workarounds.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares Misc workarounds.\n  */\n\n#ifndef BOOST_REGEX_WORKAROUND_HPP\n#define BOOST_REGEX_WORKAROUND_HPP\n\n#include <boost/regex/config.hpp>\n#include <algorithm>\n#include <stdexcept>\n#include <cstring>\n\n#ifndef BOOST_REGEX_STANDALONE\n#include <boost/detail/workaround.hpp>\n#include <boost/throw_exception.hpp>\n#endif\n\n#ifdef BOOST_REGEX_NO_BOOL\n#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)\n#else\n#  define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)\n#endif\n\n/*****************************************************************************\n *\n *  helper functions pointer_construct/pointer_destroy:\n *\n ****************************************************************************/\n\n#ifdef __cplusplus\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning (push)\n#pragma warning (disable : 4100)\n#endif\n\ntemplate <class T>\ninline void pointer_destroy(T* p)\n{ p->~T(); (void)p; }\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning (pop)\n#endif\n\ntemplate <class T>\ninline void pointer_construct(T* p, const T& t)\n{ new (p) T(t); }\n\n}} // namespaces\n#endif\n\n/*****************************************************************************\n *\n *  helper function copy:\n *\n ****************************************************************************/\n\n#if defined(BOOST_WORKAROUND)\n#if BOOST_WORKAROUND(BOOST_REGEX_MSVC, >= 1400) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__\n#define BOOST_REGEX_HAS_STRCPY_S\n#endif\n#endif\n\n#ifdef __cplusplus\nnamespace boost{ namespace BOOST_REGEX_DETAIL_NS{\n\n#if defined(BOOST_REGEX_MSVC) && (BOOST_REGEX_MSVC < 1910)\n   //\n   // MSVC 10 will either emit warnings or else refuse to compile\n   // code that makes perfectly legitimate use of std::copy, when\n   // the OutputIterator type is a user-defined class (apparently all user \n   // defined iterators are \"unsafe\").  What's more Microsoft have removed their\n   // non-standard \"unchecked\" versions, even though they are still in the MS\n   // documentation!! Work around this as best we can: \n   //\n   template<class InputIterator, class OutputIterator>\n   inline OutputIterator copy(\n      InputIterator first,\n      InputIterator last,\n      OutputIterator dest\n   )\n   {\n      while (first != last)\n         *dest++ = *first++;\n      return dest;\n   }\n#else \n   using std::copy;\n#endif \n\n\n#if defined(BOOST_REGEX_HAS_STRCPY_S)\n\n   // use safe versions of strcpy etc:\n   using ::strcpy_s;\n   using ::strcat_s;\n#else\n   inline std::size_t strcpy_s(\n      char *strDestination,\n      std::size_t sizeInBytes,\n      const char *strSource \n   )\n   {\n     std::size_t lenSourceWithNull = std::strlen(strSource) + 1;\n     if (lenSourceWithNull > sizeInBytes)\n         return 1;\n     std::memcpy(strDestination, strSource, lenSourceWithNull);\n      return 0;\n   }\n   inline std::size_t strcat_s(\n      char *strDestination,\n      std::size_t sizeInBytes,\n      const char *strSource \n   )\n   {\n     std::size_t lenSourceWithNull = std::strlen(strSource) + 1;\n     std::size_t lenDestination = std::strlen(strDestination);\n     if (lenSourceWithNull + lenDestination > sizeInBytes)\n         return 1;\n     std::memcpy(strDestination + lenDestination, strSource, lenSourceWithNull);\n      return 0;\n   }\n\n#endif\n\n   inline void overflow_error_if_not_zero(std::size_t i)\n   {\n      if(i)\n      {\n         std::overflow_error e(\"String buffer too small\");\n#ifndef BOOST_REGEX_STANDALONE\n         boost::throw_exception(e);\n#else\n         throw e;\n#endif\n      }\n   }\n\n}} // namespaces\n\n#endif // __cplusplus\n\n#endif // include guard\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/states.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         states.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares internal state machine structures.\n  */\n\n#ifndef BOOST_REGEX_V5_STATES_HPP\n#define BOOST_REGEX_V5_STATES_HPP\n\nnamespace boost{\nnamespace BOOST_REGEX_DETAIL_NS{\n\n/*** mask_type *******************************************************\nWhenever we have a choice of two alternatives, we use an array of bytes\nto indicate which of the two alternatives it is possible to take for any\ngiven input character.  If mask_take is set, then we can take the next \nstate, and if mask_skip is set then we can take the alternative.\n***********************************************************************/\nenum mask_type\n{\n   mask_take = 1,\n   mask_skip = 2,\n   mask_init = 4,\n   mask_any = mask_skip | mask_take,\n   mask_all = mask_any\n};\n\n/*** helpers **********************************************************\nThese helpers let us use function overload resolution to detect whether\nwe have narrow or wide character strings:\n***********************************************************************/\nstruct _narrow_type{};\nstruct _wide_type{};\ntemplate <class charT> struct is_byte;\ntemplate<>             struct is_byte<char>         { typedef _narrow_type width_type; };\ntemplate<>             struct is_byte<unsigned char>{ typedef _narrow_type width_type; };\ntemplate<>             struct is_byte<signed char>  { typedef _narrow_type width_type; };\ntemplate <class charT> struct is_byte               { typedef _wide_type width_type; };\n\n/*** enum syntax_element_type ******************************************\nEvery record in the state machine falls into one of the following types:\n***********************************************************************/\nenum syntax_element_type\n{\n   // start of a marked sub-expression, or perl-style (?...) extension\n   syntax_element_startmark = 0,\n   // end of a marked sub-expression, or perl-style (?...) extension\n   syntax_element_endmark = syntax_element_startmark + 1,\n   // any sequence of literal characters\n   syntax_element_literal = syntax_element_endmark + 1,\n   // start of line assertion: ^\n   syntax_element_start_line = syntax_element_literal + 1,\n   // end of line assertion $\n   syntax_element_end_line = syntax_element_start_line + 1,\n   // match any character: .\n   syntax_element_wild = syntax_element_end_line + 1,\n   // end of expression: we have a match when we get here\n   syntax_element_match = syntax_element_wild + 1,\n   // perl style word boundary: \\b\n   syntax_element_word_boundary = syntax_element_match + 1,\n   // perl style within word boundary: \\B\n   syntax_element_within_word = syntax_element_word_boundary + 1,\n   // start of word assertion: \\<\n   syntax_element_word_start = syntax_element_within_word + 1,\n   // end of word assertion: \\>\n   syntax_element_word_end = syntax_element_word_start + 1,\n   // start of buffer assertion: \\`\n   syntax_element_buffer_start = syntax_element_word_end + 1,\n   // end of buffer assertion: \\'\n   syntax_element_buffer_end = syntax_element_buffer_start + 1,\n   // backreference to previously matched sub-expression\n   syntax_element_backref = syntax_element_buffer_end + 1,\n   // either a wide character set [..] or one with multicharacter collating elements:\n   syntax_element_long_set = syntax_element_backref + 1,\n   // narrow character set: [...]\n   syntax_element_set = syntax_element_long_set + 1,\n   // jump to a new state in the machine:\n   syntax_element_jump = syntax_element_set + 1,\n   // choose between two production states:\n   syntax_element_alt = syntax_element_jump + 1,\n   // a repeat\n   syntax_element_rep = syntax_element_alt + 1,\n   // match a combining character sequence\n   syntax_element_combining = syntax_element_rep + 1,\n   // perl style soft buffer end: \\z\n   syntax_element_soft_buffer_end = syntax_element_combining + 1,\n   // perl style continuation: \\G\n   syntax_element_restart_continue = syntax_element_soft_buffer_end + 1,\n   // single character repeats:\n   syntax_element_dot_rep = syntax_element_restart_continue + 1,\n   syntax_element_char_rep = syntax_element_dot_rep + 1,\n   syntax_element_short_set_rep = syntax_element_char_rep + 1,\n   syntax_element_long_set_rep = syntax_element_short_set_rep + 1,\n   // a backstep for lookbehind repeats:\n   syntax_element_backstep = syntax_element_long_set_rep + 1,\n   // an assertion that a mark was matched:\n   syntax_element_assert_backref = syntax_element_backstep + 1,\n   syntax_element_toggle_case = syntax_element_assert_backref + 1,\n   // a recursive expression:\n   syntax_element_recurse = syntax_element_toggle_case + 1,\n   // Verbs:\n   syntax_element_fail = syntax_element_recurse + 1,\n   syntax_element_accept = syntax_element_fail + 1,\n   syntax_element_commit = syntax_element_accept + 1,\n   syntax_element_then = syntax_element_commit + 1\n};\n\n#ifdef BOOST_REGEX_DEBUG\n// dwa 09/26/00 - This is needed to suppress warnings about an ambiguous conversion\nstd::ostream& operator<<(std::ostream&, syntax_element_type);\n#endif\n\nstruct re_syntax_base;\n\n/*** union offset_type ************************************************\nPoints to another state in the machine.  During machine construction\nwe use integral offsets, but these are converted to pointers before\nexecution of the machine.\n***********************************************************************/\nunion offset_type\n{\n   re_syntax_base*   p;\n   std::ptrdiff_t    i;\n};\n\n/*** struct re_syntax_base ********************************************\nBase class for all states in the machine.\n***********************************************************************/\nstruct re_syntax_base\n{\n   syntax_element_type   type;         // what kind of state this is\n   offset_type           next;         // next state in the machine\n};\n\n/*** struct re_brace **************************************************\nA marked parenthesis.\n***********************************************************************/\nstruct re_brace : public re_syntax_base\n{\n   // The index to match, can be zero (don't mark the sub-expression)\n   // or negative (for perl style (?...) extensions):\n   int index;\n   bool icase;\n};\n\n/*** struct re_dot **************************************************\nMatch anything.\n***********************************************************************/\nenum\n{\n   dont_care = 1,\n   force_not_newline = 0,\n   force_newline = 2,\n\n   test_not_newline = 2,\n   test_newline = 3\n};\nstruct re_dot : public re_syntax_base\n{\n   unsigned char mask;\n};\n\n/*** struct re_literal ************************************************\nA string of literals, following this structure will be an \narray of characters: charT[length]\n***********************************************************************/\nstruct re_literal : public re_syntax_base\n{\n   unsigned int length;\n};\n\n/*** struct re_case ************************************************\nIndicates whether we are moving to a case insensive block or not\n***********************************************************************/\nstruct re_case : public re_syntax_base\n{\n   bool icase;\n};\n\n/*** struct re_set_long ***********************************************\nA wide character set of characters, following this structure will be\nan array of type charT:\nFirst csingles null-terminated strings\nThen 2 * cranges NULL terminated strings\nThen cequivalents NULL terminated strings\n***********************************************************************/\ntemplate <class mask_type>\nstruct re_set_long : public re_syntax_base\n{\n   unsigned int            csingles, cranges, cequivalents;\n   mask_type               cclasses;\n   mask_type               cnclasses;\n   bool                    isnot;\n   bool                    singleton;\n};\n\n/*** struct re_set ****************************************************\nA set of narrow-characters, matches any of _map which is none-zero\n***********************************************************************/\nstruct re_set : public re_syntax_base\n{\n   unsigned char _map[1 << CHAR_BIT];\n};\n\n/*** struct re_jump ***************************************************\nJump to a new location in the machine (not next).\n***********************************************************************/\nstruct re_jump : public re_syntax_base\n{\n   offset_type     alt;                 // location to jump to\n};\n\n/*** struct re_alt ***************************************************\nJump to a new location in the machine (possibly next).\n***********************************************************************/\nstruct re_alt : public re_jump\n{\n   unsigned char   _map[1 << CHAR_BIT]; // which characters can take the jump\n   unsigned int    can_be_null;         // true if we match a NULL string\n};\n\n/*** struct re_repeat *************************************************\nRepeat a section of the machine\n***********************************************************************/\nstruct re_repeat : public re_alt\n{\n   std::size_t   min, max;  // min and max allowable repeats\n   int           state_id;        // Unique identifier for this repeat\n   bool          leading;   // True if this repeat is at the start of the machine (lets us optimize some searches)\n   bool          greedy;    // True if this is a greedy repeat\n};\n\n/*** struct re_recurse ************************************************\nRecurse to a particular subexpression.\n**********************************************************************/\nstruct re_recurse : public re_jump\n{\n   int state_id;             // identifier of first nested repeat within the recursion.\n};\n\n/*** struct re_commit *************************************************\nUsed for the PRUNE, SKIP and COMMIT verbs which basically differ only in what happens\nif no match is found and we start searching forward.\n**********************************************************************/\nenum commit_type\n{\n   commit_prune,\n   commit_skip,\n   commit_commit\n};\nstruct re_commit : public re_syntax_base\n{\n   commit_type action;\n};\n\n/*** enum re_jump_size_type *******************************************\nProvides compiled size of re_jump structure (allowing for trailing alignment).\nWe provide this so we know how manybytes to insert when constructing the machine\n(The value of padding_mask is defined in regex_raw_buffer.hpp).\n***********************************************************************/\nenum re_jump_size_type\n{\n   re_jump_size = (sizeof(re_jump) + padding_mask) & ~(padding_mask),\n   re_repeater_size = (sizeof(re_repeat) + padding_mask) & ~(padding_mask),\n   re_alt_size = (sizeof(re_alt) + padding_mask) & ~(padding_mask)\n};\n\n/*** proc re_is_set_member *********************************************\nForward declaration: we'll need this one later...\n***********************************************************************/\n\ntemplate<class charT, class traits>\nstruct regex_data;\n\ntemplate <class iterator, class charT, class traits_type, class char_classT>\niterator  re_is_set_member(iterator next, \n                          iterator last, \n                          const re_set_long<char_classT>* set_, \n                          const regex_data<charT, traits_type>& e, bool icase);\n\n} // namespace BOOST_REGEX_DETAIL_NS\n\n} // namespace boost\n\n#endif\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/sub_match.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         sub_match.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares template class sub_match.\n  */\n\n#ifndef BOOST_REGEX_V5_SUB_MATCH_HPP\n#define BOOST_REGEX_V5_SUB_MATCH_HPP\n\nnamespace boost{\n\ntemplate <class BidiIterator>\nstruct sub_match : public std::pair<BidiIterator, BidiIterator>\n{\n   typedef typename std::iterator_traits<BidiIterator>::value_type       value_type;\n   typedef typename std::iterator_traits<BidiIterator>::difference_type  difference_type;\n   typedef          BidiIterator                                                     iterator_type;\n   typedef          BidiIterator                                                     iterator;\n   typedef          BidiIterator                                                     const_iterator;\n\n   bool matched;\n\n   sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}\n   sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}\n   template <class T, class A>\n   operator std::basic_string<value_type, T, A> ()const\n   {\n      return matched ? std::basic_string<value_type, T, A>(this->first, this->second) : std::basic_string<value_type, T, A>();\n   }\n   difference_type  length()const\n   {\n      difference_type n = matched ? std::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0;\n      return n;\n   }\n   std::basic_string<value_type> str()const\n   {\n      std::basic_string<value_type> result;\n      if(matched)\n      {\n         std::size_t len = std::distance((BidiIterator)this->first, (BidiIterator)this->second);\n         result.reserve(len);\n         BidiIterator i = this->first;\n         while(i != this->second)\n         {\n            result.append(1, *i);\n            ++i;\n         }\n      }\n      return result;\n   }\n   int compare(const sub_match& s)const\n   {\n      if(matched != s.matched)\n         return static_cast<int>(matched) - static_cast<int>(s.matched);\n      return str().compare(s.str());\n   }\n   int compare(const std::basic_string<value_type>& s)const\n   {\n      return str().compare(s);\n   }\n   int compare(const value_type* p)const\n   {\n      return str().compare(p);\n   }\n\n   bool operator==(const sub_match& that)const\n   { return compare(that) == 0; }\n   bool  operator !=(const sub_match& that)const\n   { return compare(that) != 0; }\n   bool operator<(const sub_match& that)const\n   { return compare(that) < 0; }\n   bool operator>(const sub_match& that)const\n   { return compare(that) > 0; }\n   bool operator<=(const sub_match& that)const\n   { return compare(that) <= 0; }\n   bool operator>=(const sub_match& that)const\n   { return compare(that) >= 0; }\n\n#ifdef BOOST_REGEX_MATCH_EXTRA\n   typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;\n\n   const capture_sequence_type& captures()const\n   {\n      if(!m_captures) \n         m_captures.reset(new capture_sequence_type());\n      return *m_captures;\n   }\n   //\n   // Private implementation API: DO NOT USE!\n   //\n   capture_sequence_type& get_captures()const\n   {\n      if(!m_captures) \n         m_captures.reset(new capture_sequence_type());\n      return *m_captures;\n   }\n\nprivate:\n   mutable std::unique_ptr<capture_sequence_type> m_captures;\npublic:\n\n#endif\n   sub_match(const sub_match& that, bool \n#ifdef BOOST_REGEX_MATCH_EXTRA\n      deep_copy\n#endif\n      = true\n      ) \n      : std::pair<BidiIterator, BidiIterator>(that), \n        matched(that.matched) \n   {\n#ifdef BOOST_REGEX_MATCH_EXTRA\n      if(that.m_captures)\n         if(deep_copy)\n            m_captures.reset(new capture_sequence_type(*(that.m_captures)));\n#endif\n   }\n   sub_match& operator=(const sub_match& that)\n   {\n      this->first = that.first;\n      this->second = that.second;\n      matched = that.matched;\n#ifdef BOOST_REGEX_MATCH_EXTRA\n      if(that.m_captures)\n         get_captures() = *(that.m_captures);\n#endif\n      return *this;\n   }\n   //\n   // Make this type a range, for both Boost.Range, and C++11:\n   //\n   BidiIterator begin()const { return this->first; }\n   BidiIterator end()const { return this->second; }\n};\n\ntypedef sub_match<const char*> csub_match;\ntypedef sub_match<std::string::const_iterator> ssub_match;\n#ifndef BOOST_NO_WREGEX\ntypedef sub_match<const wchar_t*> wcsub_match;\ntypedef sub_match<std::wstring::const_iterator> wssub_match;\n#endif\n\n// comparison to std::basic_string<> part 1:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator == (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) == 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator != (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) != 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator < (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                 const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) < 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator <= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) <= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator >= (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) >= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator > (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                 const sub_match<RandomAccessIterator>& m)\n{ return s.compare(m.str()) > 0; }\n// comparison to std::basic_string<> part 2:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) <= 0; }\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{ return m.str().compare(s) >= 0; }\n// comparison to const charT* part 1:\ntemplate <class RandomAccessIterator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const* s)\n{ return m.str().compare(s) <= 0; }\n// comparison to const charT* part 2:\ntemplate <class RandomAccessIterator>\ninline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(s) <= 0; }\n\n// comparison to const charT& part 1:\ntemplate <class RandomAccessIterator>\ninline bool operator == (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (const sub_match<RandomAccessIterator>& m,\n                  typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{ return m.str().compare(0, m.length(), &s, 1) <= 0; }\n// comparison to const charT* part 2:\ntemplate <class RandomAccessIterator>\ninline bool operator == (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) == 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator != (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) != 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator < (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) > 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator > (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) < 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator <= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) >= 0; }\ntemplate <class RandomAccessIterator>\ninline bool operator >= (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{ return m.str().compare(0, m.length(), &s, 1) <= 0; }\n\n// addition operators:\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> \noperator + (const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;\n   result.reserve(s.size() + m.length() + 1);\n   return result.append(s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator, class traits, class Allocator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> \noperator + (const sub_match<RandomAccessIterator>& m,\n            const std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;\n   result.reserve(s.size() + m.length() + 1);\n   return result.append(m.first, m.second).append(s);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> \noperator + (typename std::iterator_traits<RandomAccessIterator>::value_type const* s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);\n   return result.append(s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m,\n            typename std::iterator_traits<RandomAccessIterator>::value_type const * s)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(std::char_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);\n   return result.append(m.first, m.second).append(s);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> \noperator + (typename std::iterator_traits<RandomAccessIterator>::value_type const& s,\n                  const sub_match<RandomAccessIterator>& m)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m.length() + 2);\n   return result.append(1, s).append(m.first, m.second);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m,\n            typename std::iterator_traits<RandomAccessIterator>::value_type const& s)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m.length() + 2);\n   return result.append(m.first, m.second).append(1, s);\n}\ntemplate <class RandomAccessIterator>\ninline std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> \noperator + (const sub_match<RandomAccessIterator>& m1,\n            const sub_match<RandomAccessIterator>& m2)\n{\n   std::basic_string<typename std::iterator_traits<RandomAccessIterator>::value_type> result;\n   result.reserve(m1.length() + m2.length() + 1);\n   return result.append(m1.first, m1.second).append(m2.first, m2.second);\n}\ntemplate <class charT, class traits, class RandomAccessIterator>\nstd::basic_ostream<charT, traits>&\n   operator << (std::basic_ostream<charT, traits>& os,\n                const sub_match<RandomAccessIterator>& s)\n{\n   return (os << s.str());\n}\n\n} // namespace boost\n\n#endif\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/syntax_type.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         syntax_type.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression synatx type enumerator.\n  */\n\n#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP\n#define BOOST_REGEX_SYNTAX_TYPE_HPP\n\nnamespace boost{\nnamespace regex_constants{\n\ntypedef unsigned char syntax_type;\n\n//\n// values chosen are binary compatible with previous version:\n//\nstatic const syntax_type syntax_char = 0;\nstatic const syntax_type syntax_open_mark = 1;\nstatic const syntax_type syntax_close_mark = 2;\nstatic const syntax_type syntax_dollar = 3;\nstatic const syntax_type syntax_caret = 4;\nstatic const syntax_type syntax_dot = 5;\nstatic const syntax_type syntax_star = 6;\nstatic const syntax_type syntax_plus = 7;\nstatic const syntax_type syntax_question = 8;\nstatic const syntax_type syntax_open_set = 9;\nstatic const syntax_type syntax_close_set = 10;\nstatic const syntax_type syntax_or = 11;\nstatic const syntax_type syntax_escape = 12;\nstatic const syntax_type syntax_dash = 14;\nstatic const syntax_type syntax_open_brace = 15;\nstatic const syntax_type syntax_close_brace = 16;\nstatic const syntax_type syntax_digit = 17;\nstatic const syntax_type syntax_comma = 27;\nstatic const syntax_type syntax_equal = 37;\nstatic const syntax_type syntax_colon = 36;\nstatic const syntax_type syntax_not = 53;\n\n// extensions:\n\nstatic const syntax_type syntax_hash = 13;\nstatic const syntax_type syntax_newline = 26;\n\n// escapes:\n\ntypedef syntax_type escape_syntax_type;\n\nstatic const escape_syntax_type escape_type_word_assert = 18;\nstatic const escape_syntax_type escape_type_not_word_assert = 19;\nstatic const escape_syntax_type escape_type_control_f = 29;\nstatic const escape_syntax_type escape_type_control_n = 30;\nstatic const escape_syntax_type escape_type_control_r = 31;\nstatic const escape_syntax_type escape_type_control_t = 32;\nstatic const escape_syntax_type escape_type_control_v = 33;\nstatic const escape_syntax_type escape_type_ascii_control = 35;\nstatic const escape_syntax_type escape_type_hex = 34;\nstatic const escape_syntax_type escape_type_unicode = 0; // not used\nstatic const escape_syntax_type escape_type_identity = 0; // not used\nstatic const escape_syntax_type escape_type_backref = syntax_digit;\nstatic const escape_syntax_type escape_type_decimal = syntax_digit; // not used\nstatic const escape_syntax_type escape_type_class = 22; \nstatic const escape_syntax_type escape_type_not_class = 23; \n\n// extensions:\n\nstatic const escape_syntax_type escape_type_left_word = 20;\nstatic const escape_syntax_type escape_type_right_word = 21;\nstatic const escape_syntax_type escape_type_start_buffer = 24;                 // for \\`\nstatic const escape_syntax_type escape_type_end_buffer = 25;                   // for \\'\nstatic const escape_syntax_type escape_type_control_a = 28;                    // for \\a\nstatic const escape_syntax_type escape_type_e = 38;                            // for \\e\nstatic const escape_syntax_type escape_type_E = 47;                            // for \\Q\\E\nstatic const escape_syntax_type escape_type_Q = 48;                            // for \\Q\\E\nstatic const escape_syntax_type escape_type_X = 49;                            // for \\X\nstatic const escape_syntax_type escape_type_C = 50;                            // for \\C\nstatic const escape_syntax_type escape_type_Z = 51;                            // for \\Z\nstatic const escape_syntax_type escape_type_G = 52;                            // for \\G\n\nstatic const escape_syntax_type escape_type_property = 54;                     // for \\p\nstatic const escape_syntax_type escape_type_not_property = 55;                 // for \\P\nstatic const escape_syntax_type escape_type_named_char = 56;                   // for \\N\nstatic const escape_syntax_type escape_type_extended_backref = 57;             // for \\g\nstatic const escape_syntax_type escape_type_reset_start_mark = 58;             // for \\K\nstatic const escape_syntax_type escape_type_line_ending = 59;                  // for \\R\n\nstatic const escape_syntax_type syntax_max = 60;\n\n}\n}\n\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/u32regex_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         u32regex_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides u32regex_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_U32REGEX_ITERATOR_HPP\n#define BOOST_REGEX_V5_U32REGEX_ITERATOR_HPP\n\nnamespace boost{\n\ntemplate <class BidirectionalIterator>\nclass u32regex_iterator_implementation \n{\n   typedef u32regex regex_type;\n\n   match_results<BidirectionalIterator> what;  // current match\n   BidirectionalIterator                base;  // start of sequence\n   BidirectionalIterator                end;   // end of sequence\n   const regex_type                     re;   // the expression\n   match_flag_type                      flags; // flags for matching\n\npublic:\n   u32regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)\n      : base(), end(last), re(*p), flags(f){}\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      return u32regex_search(first, end, what, re, flags, base);\n   }\n   bool compare(const u32regex_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);\n   }\n   const match_results<BidirectionalIterator>& get()\n   { return what; }\n   bool next()\n   {\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail;\n      BidirectionalIterator next_start = what[0].second;\n      match_flag_type f(flags);\n      if(!what.length())\n         f |= regex_constants::match_not_initial_null;\n      //if(base != next_start)\n      //   f |= regex_constants::match_not_bob;\n      bool result = u32regex_search(next_start, end, what, re, f, base);\n      if(result)\n         what.set_base(base);\n      return result;\n   }\nprivate:\n   u32regex_iterator_implementation& operator=(const u32regex_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator>\nclass u32regex_iterator \n{\nprivate:\n   typedef u32regex_iterator_implementation<BidirectionalIterator> impl;\n   typedef std::shared_ptr<impl> pimpl;\npublic:\n   typedef          u32regex                                                regex_type;\n   typedef          match_results<BidirectionalIterator>                    value_type;\n   typedef typename std::iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   u32regex_iterator(){}\n   u32regex_iterator(BidirectionalIterator a, BidirectionalIterator b, \n                  const regex_type& re, \n                  match_flag_type m = match_default)\n                  : pdata(new impl(&re, b, m))\n   {\n      if(!pdata->init(a))\n      {\n         pdata.reset();\n      }\n   }\n   u32regex_iterator(const u32regex_iterator& that)\n      : pdata(that.pdata) {}\n   u32regex_iterator& operator=(const u32regex_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const u32regex_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const u32regex_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   u32regex_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   u32regex_iterator operator++(int)\n   {\n      u32regex_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && (pdata.use_count() > 1))\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef u32regex_iterator<const char*> utf8regex_iterator;\ntypedef u32regex_iterator<const UChar*> utf16regex_iterator;\ntypedef u32regex_iterator<const UChar32*> utf32regex_iterator;\n\ninline u32regex_iterator<const char*> make_u32regex_iterator(const char* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const char*>(p, p+std::strlen(p), e, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_iterator<const wchar_t*> make_u32regex_iterator(const wchar_t* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const wchar_t*>(p, p+std::wcslen(p), e, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ninline u32regex_iterator<const UChar*> make_u32regex_iterator(const UChar* p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const UChar*>(p, p+u_strlen(p), e, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_iterator<iter_type>(p.begin(), p.end(), e, m);\n}\ninline u32regex_iterator<const UChar*> make_u32regex_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, m);\n}\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V5_REGEX_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/u32regex_token_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2003\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         u32regex_token_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Provides u32regex_token_iterator implementation.\n  */\n\n#ifndef BOOST_REGEX_V5_U32REGEX_TOKEN_ITERATOR_HPP\n#define BOOST_REGEX_V5_U32REGEX_TOKEN_ITERATOR_HPP\n\nnamespace boost{\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(push)\n#  pragma warning(disable:4700)\n#endif\n\ntemplate <class BidirectionalIterator>\nclass u32regex_token_iterator_implementation \n{\n   typedef u32regex                              regex_type;\n   typedef sub_match<BidirectionalIterator>      value_type;\n\n   match_results<BidirectionalIterator> what;   // current match\n   BidirectionalIterator                end;    // end of search area\n   BidirectionalIterator                base;   // start of search area\n   const regex_type                     re;     // the expression\n   match_flag_type                      flags;  // match flags\n   value_type                           result; // the current string result\n   int                                  N;      // the current sub-expression being enumerated\n   std::vector<int>                     subs;   // the sub-expressions to enumerate\n\npublic:\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)\n      : end(last), re(*p), flags(f){ subs.push_back(sub); }\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)\n      : end(last), re(*p), flags(f), subs(v){}\n   template <std::size_t CN>\n   u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)\n      : end(last), re(*p), flags(f)\n   {\n      for(std::size_t i = 0; i < CN; ++i)\n      {\n         subs.push_back(submatches[i]);\n      }\n   }\n\n   bool init(BidirectionalIterator first)\n   {\n      base = first;\n      N = 0;\n      if(u32regex_search(first, end, what, re, flags, base) == true)\n      {\n         N = 0;\n         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);\n         return true;\n      }\n      else if((subs[N] == -1) && (first != end))\n      {\n         result.first = first;\n         result.second = end;\n         result.matched = (first != end);\n         N = -1;\n         return true;\n      }\n      return false;\n   }\n   bool compare(const u32regex_token_iterator_implementation& that)\n   {\n      if(this == &that) return true;\n      return (&re.get_data() == &that.re.get_data()) \n         && (end == that.end) \n         && (flags == that.flags) \n         && (N == that.N) \n         && (what[0].first == that.what[0].first) \n         && (what[0].second == that.what[0].second);\n   }\n   const value_type& get()\n   { return result; }\n   bool next()\n   {\n      if(N == -1)\n         return false;\n      if(N+1 < (int)subs.size())\n      {\n         ++N;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      //if(what.prefix().first != what[0].second)\n      //   flags |= match_prev_avail | regex_constants::match_not_bob;\n      BidirectionalIterator last_end(what[0].second);\n      if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))\n      {\n         N =0;\n         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);\n         return true;\n      }\n      else if((last_end != end) && (subs[0] == -1))\n      {\n         N =-1;\n         result.first = last_end;\n         result.second = end;\n         result.matched = (last_end != end);\n         return true;\n      }\n      return false;\n   }\nprivate:\n   u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);\n};\n\ntemplate <class BidirectionalIterator>\nclass u32regex_token_iterator \n{\nprivate:\n   typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;\n   typedef std::shared_ptr<impl> pimpl;\npublic:\n   typedef          u32regex                                                regex_type;\n   typedef          sub_match<BidirectionalIterator>                        value_type;\n   typedef typename std::iterator_traits<BidirectionalIterator>::difference_type \n                                                                            difference_type;\n   typedef          const value_type*                                       pointer;\n   typedef          const value_type&                                       reference; \n   typedef          std::forward_iterator_tag                               iterator_category;\n   \n   u32regex_token_iterator(){}\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        int submatch = 0, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatch, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, \n                        const std::vector<int>& submatches, match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   template <std::size_t N>\n   u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,\n                        const int (&submatches)[N], match_flag_type m = match_default)\n                        : pdata(new impl(&re, b, submatches, m))\n   {\n      if(!pdata->init(a))\n         pdata.reset();\n   }\n   u32regex_token_iterator(const u32regex_token_iterator& that)\n      : pdata(that.pdata) {}\n   u32regex_token_iterator& operator=(const u32regex_token_iterator& that)\n   {\n      pdata = that.pdata;\n      return *this;\n   }\n   bool operator==(const u32regex_token_iterator& that)const\n   { \n      if((pdata.get() == 0) || (that.pdata.get() == 0))\n         return pdata.get() == that.pdata.get();\n      return pdata->compare(*(that.pdata.get())); \n   }\n   bool operator!=(const u32regex_token_iterator& that)const\n   { return !(*this == that); }\n   const value_type& operator*()const\n   { return pdata->get(); }\n   const value_type* operator->()const\n   { return &(pdata->get()); }\n   u32regex_token_iterator& operator++()\n   {\n      cow();\n      if(0 == pdata->next())\n      {\n         pdata.reset();\n      }\n      return *this;\n   }\n   u32regex_token_iterator operator++(int)\n   {\n      u32regex_token_iterator result(*this);\n      ++(*this);\n      return result;\n   }\nprivate:\n\n   pimpl pdata;\n\n   void cow()\n   {\n      // copy-on-write\n      if(pdata.get() && (pdata.use_count() > 1))\n      {\n         pdata.reset(new impl(*(pdata.get())));\n      }\n   }\n};\n\ntypedef u32regex_token_iterator<const char*> utf8regex_token_iterator;\ntypedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;\ntypedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;\n\n// construction from an integral sub_match state_id:\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n// construction from a reference to an array:\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(BOOST_REGEX_UCHAR_IS_WCHAR_T)\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc, std::size_t N>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ntemplate <std::size_t N>\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n// construction from a vector of sub_match state_id's:\ninline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);\n}\n#ifndef BOOST_NO_WREGEX\ninline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);\n}\n#endif\n#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);\n}\n#endif\ntemplate <class charT, class Traits, class Alloc>\ninline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;\n   return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, submatch, m);\n}\ninline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const U_NAMESPACE_QUALIFIER UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)\n{\n   return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);\n}\n\n#ifdef BOOST_REGEX_MSVC\n#  pragma warning(pop)\n#endif\n\n} // namespace boost\n\n#endif // BOOST_REGEX_V5_REGEX_TOKEN_ITERATOR_HPP\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/unicode_iterator.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         unicode_iterator.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Iterator adapters for converting between different Unicode encodings.\n  */\n\n/****************************************************************************\n\nContents:\n~~~~~~~~~\n\n1) Read Only, Input Adapters:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\ntemplate <class BaseIterator, class U8Type = std::uint8_t>\nclass u32_to_u8_iterator;\n\nAdapts sequence of UTF-32 code points to \"look like\" a sequence of UTF-8.\n\ntemplate <class BaseIterator, class U32Type = std::uint32_t>\nclass u8_to_u32_iterator;\n\nAdapts sequence of UTF-8 code points to \"look like\" a sequence of UTF-32.\n\ntemplate <class BaseIterator, class U16Type = std::uint16_t>\nclass u32_to_u16_iterator;\n\nAdapts sequence of UTF-32 code points to \"look like\" a sequence of UTF-16.\n\ntemplate <class BaseIterator, class U32Type = std::uint32_t>\nclass u16_to_u32_iterator;\n\nAdapts sequence of UTF-16 code points to \"look like\" a sequence of UTF-32.\n\n2) Single pass output iterator adapters:\n\ntemplate <class BaseIterator>\nclass utf8_output_iterator;\n\nAccepts UTF-32 code points and forwards them on as UTF-8 code points.\n\ntemplate <class BaseIterator>\nclass utf16_output_iterator;\n\nAccepts UTF-32 code points and forwards them on as UTF-16 code points.\n\n****************************************************************************/\n\n#ifndef BOOST_REGEX_UNICODE_ITERATOR_HPP\n#define BOOST_REGEX_UNICODE_ITERATOR_HPP\n#include <cstdint>\n#include <boost/regex/config.hpp>\n#include <stdexcept>\n#include <sstream>\n#include <ios>\n#include <limits.h> // CHAR_BIT\n\n#ifndef BOOST_REGEX_STANDALONE\n#include <boost/throw_exception.hpp>\n#endif\n\nnamespace boost{\n\nnamespace detail{\n\nstatic const std::uint16_t high_surrogate_base = 0xD7C0u;\nstatic const std::uint16_t low_surrogate_base = 0xDC00u;\nstatic const std::uint32_t ten_bit_mask = 0x3FFu;\n\ninline bool is_high_surrogate(std::uint16_t v)\n{\n   return (v & 0xFFFFFC00u) == 0xd800u;\n}\ninline bool is_low_surrogate(std::uint16_t v)\n{\n   return (v & 0xFFFFFC00u) == 0xdc00u;\n}\ntemplate <class T>\ninline bool is_surrogate(T v)\n{\n   return (v & 0xFFFFF800u) == 0xd800;\n}\n\ninline unsigned utf8_byte_count(std::uint8_t c)\n{\n   // if the most significant bit with a zero in it is in position\n   // 8-N then there are N bytes in this UTF-8 sequence:\n   std::uint8_t mask = 0x80u;\n   unsigned result = 0;\n   while(c & mask)\n   {\n      ++result;\n      mask >>= 1;\n   }\n   return (result == 0) ? 1 : ((result > 4) ? 4 : result);\n}\n\ninline unsigned utf8_trailing_byte_count(std::uint8_t c)\n{\n   return utf8_byte_count(c) - 1;\n}\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4100)\n#endif\n#ifndef BOOST_NO_EXCEPTIONS\nBOOST_REGEX_NORETURN\n#endif\ninline void invalid_utf32_code_point(std::uint32_t val)\n{\n   std::stringstream ss;\n   ss << \"Invalid UTF-32 code point U+\" << std::showbase << std::hex << val << \" encountered while trying to encode UTF-16 sequence\";\n   std::out_of_range e(ss.str());\n#ifndef BOOST_REGEX_STANDALONE\n   boost::throw_exception(e);\n#else\n   throw e;\n#endif\n}\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n\n} // namespace detail\n\ntemplate <class BaseIterator, class U16Type = std::uint16_t>\nclass u32_to_u16_iterator\n{\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   static_assert(sizeof(base_value_type)*CHAR_BIT == 32, \"Incorrectly sized template argument\");\n   static_assert(sizeof(U16Type)*CHAR_BIT == 16, \"Incorrectly sized template argument\");\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U16Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_current == 2)\n         extract_current();\n      return m_values[m_current];\n   }\n   bool operator==(const u32_to_u16_iterator& that)const\n   {\n      if(m_position == that.m_position)\n      {\n         // Both m_currents must be equal, or both even\n         // this is the same as saying their sum must be even:\n         return (m_current + that.m_current) & 1u ? false : true;\n      }\n      return false;\n   }\n   bool operator!=(const u32_to_u16_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u32_to_u16_iterator& operator++()\n   {\n      // if we have a pending read then read now, so that we know whether\n      // to skip a position, or move to a low-surrogate:\n      if(m_current == 2)\n      {\n         // pending read:\n         extract_current();\n      }\n      // move to the next surrogate position:\n      ++m_current;\n      // if we've reached the end skip a position:\n      if(m_values[m_current] == 0)\n      {\n         m_current = 2;\n         ++m_position;\n      }\n      return *this;\n   }\n   u32_to_u16_iterator operator++(int)\n   {\n      u32_to_u16_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u32_to_u16_iterator& operator--()\n   {\n      if(m_current != 1)\n      {\n         // decrementing an iterator always leads to a valid position:\n         --m_position;\n         extract_current();\n         m_current = m_values[1] ? 1 : 0;\n      }\n      else\n      {\n         m_current = 0;\n      }\n      return *this;\n   }\n   u32_to_u16_iterator operator--(int)\n   {\n      u32_to_u16_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u32_to_u16_iterator() : m_position(), m_current(0)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n   }\n   u32_to_u16_iterator(BaseIterator b) : m_position(b), m_current(2)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n   }\nprivate:\n\n   void extract_current()const\n   {\n      // begin by checking for a code point out of range:\n      std::uint32_t v = *m_position;\n      if(v >= 0x10000u)\n      {\n         if(v > 0x10FFFFu)\n            detail::invalid_utf32_code_point(*m_position);\n         // split into two surrogates:\n         m_values[0] = static_cast<U16Type>(v >> 10) + detail::high_surrogate_base;\n         m_values[1] = static_cast<U16Type>(v & detail::ten_bit_mask) + detail::low_surrogate_base;\n         m_current = 0;\n         BOOST_REGEX_ASSERT(detail::is_high_surrogate(m_values[0]));\n         BOOST_REGEX_ASSERT(detail::is_low_surrogate(m_values[1]));\n      }\n      else\n      {\n         // 16-bit code point:\n         m_values[0] = static_cast<U16Type>(*m_position);\n         m_values[1] = 0;\n         m_current = 0;\n         // value must not be a surrogate:\n         if(detail::is_surrogate(m_values[0]))\n            detail::invalid_utf32_code_point(*m_position);\n      }\n   }\n   BaseIterator m_position;\n   mutable U16Type m_values[3];\n   mutable unsigned m_current;\n};\n\ntemplate <class BaseIterator, class U32Type = std::uint32_t>\nclass u16_to_u32_iterator\n{\n   // special values for pending iterator reads:\n   static const U32Type pending_read = 0xffffffffu;\n\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   static_assert(sizeof(base_value_type)*CHAR_BIT == 16, \"Incorrectly sized template argument\");\n   static_assert(sizeof(U32Type)*CHAR_BIT == 32, \"Incorrectly sized template argument\");\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U32Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_value == pending_read)\n         extract_current();\n      return m_value;\n   }\n   bool operator==(const u16_to_u32_iterator& that)const\n   {\n      return m_position == that.m_position;\n   }\n   bool operator!=(const u16_to_u32_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u16_to_u32_iterator& operator++()\n   {\n      // skip high surrogate first if there is one:\n      if(detail::is_high_surrogate(*m_position)) ++m_position;\n      ++m_position;\n      m_value = pending_read;\n      return *this;\n   }\n   u16_to_u32_iterator operator++(int)\n   {\n      u16_to_u32_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u16_to_u32_iterator& operator--()\n   {\n      --m_position;\n      // if we have a low surrogate then go back one more:\n      if(detail::is_low_surrogate(*m_position)) \n         --m_position;\n      m_value = pending_read;\n      return *this;\n   }\n   u16_to_u32_iterator operator--(int)\n   {\n      u16_to_u32_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u16_to_u32_iterator() : m_position()\n   {\n      m_value = pending_read;\n   }\n   u16_to_u32_iterator(BaseIterator b) : m_position(b)\n   {\n      m_value = pending_read;\n   }\n   //\n   // Range checked version:\n   //\n   u16_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)\n   {\n      m_value = pending_read;\n      //\n      // The range must not start with a low surrogate, or end in a high surrogate,\n      // otherwise we run the risk of running outside the underlying input range.\n      // Likewise b must not be located at a low surrogate.\n      //\n      std::uint16_t val;\n      if(start != end)\n      {\n         if((b != start) && (b != end))\n         {\n            val = *b;\n            if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))\n               invalid_code_point(val);\n         }\n         val = *start;\n         if(detail::is_surrogate(val) && ((val & 0xFC00u) == 0xDC00u))\n            invalid_code_point(val);\n         val = *--end;\n         if(detail::is_high_surrogate(val))\n            invalid_code_point(val);\n      }\n   }\nprivate:\n   static void invalid_code_point(std::uint16_t val)\n   {\n      std::stringstream ss;\n      ss << \"Misplaced UTF-16 surrogate U+\" << std::showbase << std::hex << val << \" encountered while trying to encode UTF-32 sequence\";\n      std::out_of_range e(ss.str());\n#ifndef BOOST_REGEX_STANDALONE\n      boost::throw_exception(e);\n#else\n      throw e;\n#endif\n   }\n   void extract_current()const\n   {\n      m_value = static_cast<U32Type>(static_cast< std::uint16_t>(*m_position));\n      // if the last value is a high surrogate then adjust m_position and m_value as needed:\n      if(detail::is_high_surrogate(*m_position))\n      {\n         // precondition; next value must have be a low-surrogate:\n         BaseIterator next(m_position);\n         std::uint16_t t = *++next;\n         if((t & 0xFC00u) != 0xDC00u)\n            invalid_code_point(t);\n         m_value = (m_value - detail::high_surrogate_base) << 10;\n         m_value |= (static_cast<U32Type>(static_cast< std::uint16_t>(t)) & detail::ten_bit_mask);\n      }\n      // postcondition; result must not be a surrogate:\n      if(detail::is_surrogate(m_value))\n         invalid_code_point(static_cast< std::uint16_t>(m_value));\n   }\n   BaseIterator m_position;\n   mutable U32Type m_value;\n};\n\ntemplate <class BaseIterator, class U8Type = std::uint8_t>\nclass u32_to_u8_iterator\n{\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   static_assert(sizeof(base_value_type)*CHAR_BIT == 32, \"Incorrectly sized template argument\");\n   static_assert(sizeof(U8Type)*CHAR_BIT == 8, \"Incorrectly sized template argument\");\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U8Type             value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_current == 4)\n         extract_current();\n      return m_values[m_current];\n   }\n   bool operator==(const u32_to_u8_iterator& that)const\n   {\n      if(m_position == that.m_position)\n      {\n         // either the m_current's must be equal, or one must be 0 and \n         // the other 4: which means neither must have bits 1 or 2 set:\n         return (m_current == that.m_current)\n            || (((m_current | that.m_current) & 3) == 0);\n      }\n      return false;\n   }\n   bool operator!=(const u32_to_u8_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u32_to_u8_iterator& operator++()\n   {\n      // if we have a pending read then read now, so that we know whether\n      // to skip a position, or move to a low-surrogate:\n      if(m_current == 4)\n      {\n         // pending read:\n         extract_current();\n      }\n      // move to the next surrogate position:\n      ++m_current;\n      // if we've reached the end skip a position:\n      if(m_values[m_current] == 0)\n      {\n         m_current = 4;\n         ++m_position;\n      }\n      return *this;\n   }\n   u32_to_u8_iterator operator++(int)\n   {\n      u32_to_u8_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u32_to_u8_iterator& operator--()\n   {\n      if((m_current & 3) == 0)\n      {\n         --m_position;\n         extract_current();\n         m_current = 3;\n         while(m_current && (m_values[m_current] == 0))\n            --m_current;\n      }\n      else\n         --m_current;\n      return *this;\n   }\n   u32_to_u8_iterator operator--(int)\n   {\n      u32_to_u8_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u32_to_u8_iterator() : m_position(), m_current(0)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n      m_values[3] = 0;\n      m_values[4] = 0;\n   }\n   u32_to_u8_iterator(BaseIterator b) : m_position(b), m_current(4)\n   {\n      m_values[0] = 0;\n      m_values[1] = 0;\n      m_values[2] = 0;\n      m_values[3] = 0;\n      m_values[4] = 0;\n   }\nprivate:\n\n   void extract_current()const\n   {\n      std::uint32_t c = *m_position;\n      if(c > 0x10FFFFu)\n         detail::invalid_utf32_code_point(c);\n      if(c < 0x80u)\n      {\n         m_values[0] = static_cast<unsigned char>(c);\n         m_values[1] = static_cast<unsigned char>(0u);\n         m_values[2] = static_cast<unsigned char>(0u);\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else if(c < 0x800u)\n      {\n         m_values[0] = static_cast<unsigned char>(0xC0u + (c >> 6));\n         m_values[1] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0u);\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else if(c < 0x10000u)\n      {\n         m_values[0] = static_cast<unsigned char>(0xE0u + (c >> 12));\n         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n         m_values[3] = static_cast<unsigned char>(0u);\n      }\n      else\n      {\n         m_values[0] = static_cast<unsigned char>(0xF0u + (c >> 18));\n         m_values[1] = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));\n         m_values[2] = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         m_values[3] = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      m_current= 0;\n   }\n   BaseIterator m_position;\n   mutable U8Type m_values[5];\n   mutable unsigned m_current;\n};\n\ntemplate <class BaseIterator, class U32Type = std::uint32_t>\nclass u8_to_u32_iterator\n{\n   // special values for pending iterator reads:\n   static const U32Type pending_read = 0xffffffffu;\n\n   typedef typename std::iterator_traits<BaseIterator>::value_type base_value_type;\n\n   static_assert(sizeof(base_value_type)*CHAR_BIT == 8, \"Incorrectly sized template argument\");\n   static_assert(sizeof(U32Type)*CHAR_BIT == 32, \"Incorrectly sized template argument\");\n\npublic:\n   typedef std::ptrdiff_t     difference_type;\n   typedef U32Type            value_type;\n   typedef value_type const*  pointer;\n   typedef value_type const   reference;\n   typedef std::bidirectional_iterator_tag iterator_category;\n\n   reference operator*()const\n   {\n      if(m_value == pending_read)\n         extract_current();\n      return m_value;\n   }\n   bool operator==(const u8_to_u32_iterator& that)const\n   {\n      return m_position == that.m_position;\n   }\n   bool operator!=(const u8_to_u32_iterator& that)const\n   {\n      return !(*this == that);\n   }\n   u8_to_u32_iterator& operator++()\n   {\n      // We must not start with a continuation character:\n      if((static_cast<std::uint8_t>(*m_position) & 0xC0) == 0x80)\n         invalid_sequence();\n      // skip high surrogate first if there is one:\n      unsigned c = detail::utf8_byte_count(*m_position);\n      if(m_value == pending_read)\n      {\n         // Since we haven't read in a value, we need to validate the code points:\n         for(unsigned i = 0; i < c; ++i)\n         {\n            ++m_position;\n            // We must have a continuation byte:\n            if((i != c - 1) && ((static_cast<std::uint8_t>(*m_position) & 0xC0) != 0x80))\n               invalid_sequence();\n         }\n      }\n      else\n      {\n         std::advance(m_position, c);\n      }\n      m_value = pending_read;\n      return *this;\n   }\n   u8_to_u32_iterator operator++(int)\n   {\n      u8_to_u32_iterator r(*this);\n      ++(*this);\n      return r;\n   }\n   u8_to_u32_iterator& operator--()\n   {\n      // Keep backtracking until we don't have a trailing character:\n      unsigned count = 0;\n      while((*--m_position & 0xC0u) == 0x80u) ++count;\n      // now check that the sequence was valid:\n      if(count != detail::utf8_trailing_byte_count(*m_position))\n         invalid_sequence();\n      m_value = pending_read;\n      return *this;\n   }\n   u8_to_u32_iterator operator--(int)\n   {\n      u8_to_u32_iterator r(*this);\n      --(*this);\n      return r;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\n   // construct:\n   u8_to_u32_iterator() : m_position()\n   {\n      m_value = pending_read;\n   }\n   u8_to_u32_iterator(BaseIterator b) : m_position(b)\n   {\n      m_value = pending_read;\n   }\n   //\n   // Checked constructor:\n   //\n   u8_to_u32_iterator(BaseIterator b, BaseIterator start, BaseIterator end) : m_position(b)\n   {\n      m_value = pending_read;\n      //\n      // We must not start with a continuation character, or end with a \n      // truncated UTF-8 sequence otherwise we run the risk of going past\n      // the start/end of the underlying sequence:\n      //\n      if(start != end)\n      {\n         unsigned char v = *start;\n         if((v & 0xC0u) == 0x80u)\n            invalid_sequence();\n         if((b != start) && (b != end) && ((*b & 0xC0u) == 0x80u))\n            invalid_sequence();\n         BaseIterator pos = end;\n         do\n         {\n            v = *--pos;\n         }\n         while((start != pos) && ((v & 0xC0u) == 0x80u));\n         std::ptrdiff_t extra = detail::utf8_byte_count(v);\n         if(std::distance(pos, end) < extra)\n            invalid_sequence();\n      }\n   }\nprivate:\n   static void invalid_sequence()\n   {\n      std::out_of_range e(\"Invalid UTF-8 sequence encountered while trying to encode UTF-32 character\");\n#ifndef BOOST_REGEX_STANDALONE\n      boost::throw_exception(e);\n#else\n      throw e;\n#endif\n   }\n   void extract_current()const\n   {\n      m_value = static_cast<U32Type>(static_cast< std::uint8_t>(*m_position));\n      // we must not have a continuation character:\n      if((m_value & 0xC0u) == 0x80u)\n         invalid_sequence();\n      // see how many extra bytes we have:\n      unsigned extra = detail::utf8_trailing_byte_count(*m_position);\n      // extract the extra bits, 6 from each extra byte:\n      BaseIterator next(m_position);\n      for(unsigned c = 0; c < extra; ++c)\n      {\n         ++next;\n         m_value <<= 6;\n         // We must have a continuation byte:\n         if((static_cast<std::uint8_t>(*next) & 0xC0) != 0x80)\n            invalid_sequence();\n         m_value += static_cast<std::uint8_t>(*next) & 0x3Fu;\n      }\n      // we now need to remove a few of the leftmost bits, but how many depends\n      // upon how many extra bytes we've extracted:\n      static const std::uint32_t masks[4] = \n      {\n         0x7Fu,\n         0x7FFu,\n         0xFFFFu,\n         0x1FFFFFu,\n      };\n      m_value &= masks[extra];\n      // check the result is in range:\n      if(m_value > static_cast<U32Type>(0x10FFFFu))\n         invalid_sequence();\n      // The result must not be a surrogate:\n      if((m_value >= static_cast<U32Type>(0xD800)) && (m_value <= static_cast<U32Type>(0xDFFF)))\n         invalid_sequence();\n      // We should not have had an invalidly encoded UTF8 sequence:\n      if((extra > 0) && (m_value <= static_cast<U32Type>(masks[extra - 1])))\n         invalid_sequence();\n   }\n   BaseIterator m_position;\n   mutable U32Type m_value;\n};\n\ntemplate <class BaseIterator>\nclass utf16_output_iterator\n{\npublic:\n   typedef void                                   difference_type;\n   typedef void                                   value_type;\n   typedef std::uint32_t*                         pointer;\n   typedef std::uint32_t&                         reference;\n   typedef std::output_iterator_tag               iterator_category;\n\n   utf16_output_iterator(const BaseIterator& b)\n      : m_position(b){}\n   utf16_output_iterator(const utf16_output_iterator& that)\n      : m_position(that.m_position){}\n   utf16_output_iterator& operator=(const utf16_output_iterator& that)\n   {\n      m_position = that.m_position;\n      return *this;\n   }\n   const utf16_output_iterator& operator*()const\n   {\n      return *this;\n   }\n   void operator=(std::uint32_t val)const\n   {\n      push(val);\n   }\n   utf16_output_iterator& operator++()\n   {\n      return *this;\n   }\n   utf16_output_iterator& operator++(int)\n   {\n      return *this;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\nprivate:\n   void push(std::uint32_t v)const\n   {\n      if(v >= 0x10000u)\n      {\n         // begin by checking for a code point out of range:\n         if(v > 0x10FFFFu)\n            detail::invalid_utf32_code_point(v);\n         // split into two surrogates:\n         *m_position++ = static_cast<std::uint16_t>(v >> 10) + detail::high_surrogate_base;\n         *m_position++ = static_cast<std::uint16_t>(v & detail::ten_bit_mask) + detail::low_surrogate_base;\n      }\n      else\n      {\n         // 16-bit code point:\n         // value must not be a surrogate:\n         if(detail::is_surrogate(v))\n            detail::invalid_utf32_code_point(v);\n         *m_position++ = static_cast<std::uint16_t>(v);\n      }\n   }\n   mutable BaseIterator m_position;\n};\n\ntemplate <class BaseIterator>\nclass utf8_output_iterator\n{\npublic:\n   typedef void                                   difference_type;\n   typedef void                                   value_type;\n   typedef std::uint32_t*                       pointer;\n   typedef std::uint32_t&                       reference;\n   typedef std::output_iterator_tag               iterator_category;\n\n   utf8_output_iterator(const BaseIterator& b)\n      : m_position(b){}\n   utf8_output_iterator(const utf8_output_iterator& that)\n      : m_position(that.m_position){}\n   utf8_output_iterator& operator=(const utf8_output_iterator& that)\n   {\n      m_position = that.m_position;\n      return *this;\n   }\n   const utf8_output_iterator& operator*()const\n   {\n      return *this;\n   }\n   void operator=(std::uint32_t val)const\n   {\n      push(val);\n   }\n   utf8_output_iterator& operator++()\n   {\n      return *this;\n   }\n   utf8_output_iterator& operator++(int)\n   {\n      return *this;\n   }\n   BaseIterator base()const\n   {\n      return m_position;\n   }\nprivate:\n   void push(std::uint32_t c)const\n   {\n      if(c > 0x10FFFFu)\n         detail::invalid_utf32_code_point(c);\n      if(c < 0x80u)\n      {\n         *m_position++ = static_cast<unsigned char>(c);\n      }\n      else if(c < 0x800u)\n      {\n         *m_position++ = static_cast<unsigned char>(0xC0u + (c >> 6));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      else if(c < 0x10000u)\n      {\n         *m_position++ = static_cast<unsigned char>(0xE0u + (c >> 12));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n      else\n      {\n         *m_position++ = static_cast<unsigned char>(0xF0u + (c >> 18));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 12) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + ((c >> 6) & 0x3Fu));\n         *m_position++ = static_cast<unsigned char>(0x80u + (c & 0x3Fu));\n      }\n   }\n   mutable BaseIterator m_position;\n};\n\n} // namespace boost\n\n#endif // BOOST_REGEX_UNICODE_ITERATOR_HPP\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex/v5/w32_regex_traits.hpp",
    "content": "/*\n *\n * Copyright (c) 2004\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org for most recent version.\n  *   FILE         w32_regex_traits.hpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares regular expression traits class w32_regex_traits.\n  */\n\n#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED\n#define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED\n\n#ifndef BOOST_REGEX_NO_WIN32_LOCALE\n\n#include <boost/regex/pattern_except.hpp>\n#include <boost/regex/v5/regex_traits_defaults.hpp>\n#ifdef BOOST_HAS_THREADS\n#include <mutex>\n#endif\n#include <boost/regex/v5/primary_transform.hpp>\n#include <boost/regex/v5/object_cache.hpp>\n\n#if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(UNDER_CE)\n#pragma comment(lib, \"user32.lib\")\n#endif\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(push)\n#pragma warning(disable:4786)\n#if BOOST_REGEX_MSVC < 1910\n#pragma warning(disable:4800)\n#endif\n#endif\n\n#ifndef BASETYPES\n//\n// windows.h not included, so lets forward declare what we need:\n//\n#ifndef NO_STRICT\n#ifndef STRICT\n#define STRICT 1\n#endif\n#endif\n\n#if defined(STRICT)\n#define BOOST_RE_DETAIL_DECLARE_HANDLE(x) struct x##__; typedef struct x##__ *x\n#else\n#define BOOST_RE_DETAIL_DECLARE_HANDLE(x) typedef void* x\n#endif\n//\n// This must be in the global namespace:\n//\nextern \"C\" {\n\n   BOOST_RE_DETAIL_DECLARE_HANDLE(HINSTANCE);\n   typedef HINSTANCE HMODULE;\n}\n#endif\n\nnamespace boost{ \n\n//\n// forward declaration is needed by some compilers:\n//\ntemplate <class charT>\nclass w32_regex_traits;\n   \nnamespace BOOST_REGEX_DETAIL_NS{\n\n//\n// start by typedeffing the types we'll need:\n//\ntypedef unsigned long lcid_type;        // placeholder for LCID.\ntypedef std::shared_ptr<void> cat_type; // placeholder for dll HANDLE.\n\n//\n// then add wrappers around the actual Win32 API's (ie implementation hiding):\n//\nlcid_type  w32_get_default_locale();\nbool  w32_is_lower(char, lcid_type);\n#ifndef BOOST_NO_WREGEX\nbool  w32_is_lower(wchar_t, lcid_type);\n#endif\nbool  w32_is_upper(char, lcid_type);\n#ifndef BOOST_NO_WREGEX\nbool  w32_is_upper(wchar_t, lcid_type);\n#endif\ncat_type  w32_cat_open(const std::string& name);\nstd::string  w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);\n#ifndef BOOST_NO_WREGEX\nstd::wstring  w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);\n#endif\nstd::string  w32_transform(lcid_type state_id, const char* p1, const char* p2);\n#ifndef BOOST_NO_WREGEX\nstd::wstring  w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);\n#endif\nchar  w32_tolower(char c, lcid_type);\n#ifndef BOOST_NO_WREGEX\nwchar_t  w32_tolower(wchar_t c, lcid_type);\n#endif\nchar  w32_toupper(char c, lcid_type);\n#ifndef BOOST_NO_WREGEX\nwchar_t  w32_toupper(wchar_t c, lcid_type);\n#endif\nbool  w32_is(lcid_type, std::uint32_t mask, char c);\n#ifndef BOOST_NO_WREGEX\nbool  w32_is(lcid_type, std::uint32_t mask, wchar_t c);\n#endif\n\n#ifndef BASETYPES\n//\n// Forward declarations of the small number of windows types and API's we use:\n//\n\n#if !defined(__LP64__)\nusing dword = unsigned long;\n#else\nusing DWORD = unsigned int;\n#endif\nusing word = unsigned short;\nusing lctype = dword;\n\nstatic constexpr dword ct_ctype1 = 0x00000001;\nstatic constexpr dword c1_upper = 0x0001;      // upper case\nstatic constexpr dword c1_lower = 0x0002;      // lower case\nstatic constexpr dword c1_digit = 0x0004;      // decimal digits\nstatic constexpr dword c1_space = 0x0008;      // spacing characters\nstatic constexpr dword c1_punct = 0x0010;      // punctuation characters\nstatic constexpr dword c1_cntrl = 0x0020;      // control characters\nstatic constexpr dword c1_blank = 0x0040;      // blank characters\nstatic constexpr dword c1_xdigit = 0x0080;      // other digits\nstatic constexpr dword c1_alpha = 0x0100;      // any linguistic character\nstatic constexpr dword c1_defined = 0x0200;      // defined character\nstatic constexpr unsigned int cp_acp = 0;\nstatic constexpr dword lcmap_lowercase = 0x00000100;\nstatic constexpr dword lcmap_uppercase = 0x00000200;\nstatic constexpr dword lcmap_sortkey = 0x00000400;  // WC sort key (normalize)\nstatic constexpr lctype locale_idefaultansicodepage = 0x00001004;\n\n# ifdef UNDER_CE\n#  ifndef WINAPI\n#   ifndef _WIN32_WCE_EMULATION\n#    define BOOST_RE_STDCALL __cdecl     // Note this doesn't match the desktop definition\n#   else\n#    define BOOST_RE_STDCALL __stdcall\n#   endif\n#  endif\n# else\n#  if defined(_M_IX86) || defined(__i386__)\n#   define BOOST_RE_STDCALL __stdcall\n#  else\n    // On architectures other than 32-bit x86 __stdcall is ignored. Clang also issues a warning.\n#   define BOOST_RE_STDCALL\n#  endif\n# endif\n\n#if defined (WIN32_PLATFORM_PSPC)\n#define BOOST_RE_IMPORT __declspec( dllimport )\n#elif defined (_WIN32_WCE)\n#define BOOST_RE_IMPORT\n#else\n#define BOOST_RE_IMPORT __declspec( dllimport )\n#endif\n\nextern \"C\" {\n\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL FreeLibrary(HMODULE hLibModule);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringA(lcid_type Locale, dword dwMapFlags, const char* lpSrcStr, int cchSrc, char* lpDestStr, int cchDest);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL MultiByteToWideChar(unsigned int CodePage, dword dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL WideCharToMultiByte(unsigned int CodePage, dword dwFlags, const wchar_t* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cbMultiByte, const char* lpDefaultChar, int* lpUsedDefaultChar);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType);\n   BOOST_RE_IMPORT lcid_type BOOST_RE_STDCALL GetUserDefaultLCID();\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType);\n   BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryA(const char* lpLibFileName);\n   BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryW(const wchar_t* lpLibFileName);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringW(HINSTANCE hInstance, unsigned int uID, wchar_t* lpBuffer, int cchBufferMax);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringA(HINSTANCE hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax);\n   BOOST_RE_IMPORT int BOOST_RE_STDCALL GetLocaleInfoW(lcid_type Locale, lctype LCType, wchar_t* lpLCData, int cchData);\n}\n\n#else\n//\n// We have windows.h already included:\n//\nusing dword = DWORD;\nusing word = WORD;\nusing lctype = LCTYPE;\n\nstatic constexpr dword ct_ctype1 = 0x00000001;\nstatic constexpr dword c1_upper = 0x0001;      // upper case\nstatic constexpr dword c1_lower = 0x0002;      // lower case\nstatic constexpr dword c1_digit = 0x0004;      // decimal digits\nstatic constexpr dword c1_space = 0x0008;      // spacing characters\nstatic constexpr dword c1_punct = 0x0010;      // punctuation characters\nstatic constexpr dword c1_cntrl = 0x0020;      // control characters\nstatic constexpr dword c1_blank = 0x0040;      // blank characters\nstatic constexpr dword c1_xdigit = 0x0080;      // other digits\nstatic constexpr dword c1_alpha = 0x0100;      // any linguistic character\nstatic constexpr dword c1_defined = 0x0200;      // defined character\nstatic constexpr unsigned int cp_acp = 0;\nstatic constexpr dword lcmap_lowercase = 0x00000100;\nstatic constexpr dword lcmap_uppercase = 0x00000200;\nstatic constexpr dword lcmap_sortkey = 0x00000400;  // WC sort key (normalize)\nstatic constexpr lctype locale_idefaultansicodepage = 0x00001004;\n\nusing ::FreeLibrary;\nusing ::LCMapStringA;\nusing ::LCMapStringW;\nusing ::MultiByteToWideChar;\nusing ::LCMapStringW;\nusing ::WideCharToMultiByte;\nusing ::GetStringTypeExA;\nusing ::GetStringTypeExW;\nusing ::GetUserDefaultLCID;\nusing ::GetStringTypeExA;\nusing ::GetStringTypeExW;\nusing ::LoadLibraryA;\nusing ::LoadLibraryW;\nusing ::LoadStringW;\nusing ::LoadStringA;\nusing ::GetLocaleInfoW;\n\n#endif\n//\n// class w32_regex_traits_base:\n// acts as a container for locale and the facets we are using.\n//\ntemplate <class charT>\nstruct w32_regex_traits_base\n{\n   w32_regex_traits_base(lcid_type l)\n   { imbue(l); }\n   lcid_type imbue(lcid_type l);\n\n   lcid_type m_locale;\n};\n\ntemplate <class charT>\ninline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)\n{\n   lcid_type result(m_locale);\n   m_locale = l;\n   return result;\n}\n\n//\n// class w32_regex_traits_char_layer:\n// implements methods that require specialisation for narrow characters:\n//\ntemplate <class charT>\nclass w32_regex_traits_char_layer : public w32_regex_traits_base<charT>\n{\n   typedef std::basic_string<charT> string_type;\n   typedef std::map<charT, regex_constants::syntax_type> map_type;\n   typedef typename map_type::const_iterator map_iterator_type;\npublic:\n   w32_regex_traits_char_layer(const lcid_type l);\n\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      return ((i == m_char_map.end()) ? 0 : i->second);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      map_iterator_type i = m_char_map.find(c);\n      if(i == m_char_map.end())\n      {\n         if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;\n         if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;\n         return 0;\n      }\n      return i->second;\n   }\n   charT tolower(charT c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_tolower(c, this->m_locale);\n   }\n   bool isctype(std::uint32_t mask, charT c)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, mask, c);\n   }\n\nprivate:\n   string_type get_default_message(regex_constants::syntax_type);\n   // TODO: use a hash table when available!\n   map_type m_char_map;\n};\n\ntemplate <class charT>\nw32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l) \n   : w32_regex_traits_base<charT>(l)\n{\n   // we need to start by initialising our syntax map so we know which\n   // character is used for which purpose:\n   cat_type cat;\n   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());\n   if(cat_name.size())\n   {\n      cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n      if(!cat)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if(cat)\n   {\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_message(i));\n         for(typename string_type::size_type j = 0; j < mss.size(); ++j)\n         {\n            this->m_char_map[mss[j]] = i;\n         }\n      }\n   }\n   else\n   {\n      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n      {\n         const char* ptr = get_default_syntax(i);\n         while(ptr && *ptr)\n         {\n            this->m_char_map[static_cast<charT>(*ptr)] = i;\n            ++ptr;\n         }\n      }\n   }\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_char_layer<charT>::string_type \n   w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)\n{\n   const char* ptr = get_default_syntax(i);\n   string_type result;\n   while(ptr && *ptr)\n   {\n      result.append(1, static_cast<charT>(*ptr));\n      ++ptr;\n   }\n   return result;\n}\n\n//\n// specialised version for narrow characters:\n//\ntemplate <>\nclass w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>\n{\n   typedef std::string string_type;\npublic:\n   w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n   : w32_regex_traits_base<char>(l)\n   {\n      init<char>();\n   }\n\n   regex_constants::syntax_type syntax_type(char c)const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(char c) const\n   {\n      return m_char_map[static_cast<unsigned char>(c)];\n   }\n   char tolower(char c)const\n   {\n      return m_lower_map[static_cast<unsigned char>(c)];\n   }\n   bool isctype(std::uint32_t mask, char c)const\n   {\n      return m_type_map[static_cast<unsigned char>(c)] & mask;\n   }\n\nprivate:\n   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];\n   char m_lower_map[1u << CHAR_BIT];\n   std::uint16_t m_type_map[1u << CHAR_BIT];\n   template <class U>\n   void init();\n};\n\n//\n// class w32_regex_traits_implementation:\n// provides pimpl implementation for w32_regex_traits.\n//\ntemplate <class charT>\nclass w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>\n{\npublic:\n   typedef typename w32_regex_traits<charT>::char_class_type char_class_type;\n   static const char_class_type mask_word = 0x0400; // must be C1_DEFINED << 1\n   static const char_class_type mask_unicode = 0x0800; // must be C1_DEFINED << 2\n   static const char_class_type mask_horizontal = 0x1000; // must be C1_DEFINED << 3\n   static const char_class_type mask_vertical = 0x2000; // must be C1_DEFINED << 4\n   static const char_class_type mask_base = 0x3ff;  // all the masks used by the CT_CTYPE1 group\n\n   typedef std::basic_string<charT> string_type;\n   typedef charT char_type;\n   w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l);\n   std::string error_string(regex_constants::error_type n) const\n   {\n      if(!m_error_strings.empty())\n      {\n         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);\n         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;\n      }\n      return get_default_error_string(n);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      char_class_type result = lookup_classname_imp(p1, p2);\n      if(result == 0)\n      {\n         typedef typename string_type::size_type size_type;\n         string_type temp(p1, p2);\n         for(size_type i = 0; i < temp.size(); ++i)\n            temp[i] = this->tolower(temp[i]);\n         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());\n      }\n      return result;\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const;\n   string_type transform_primary(const charT* p1, const charT* p2) const;\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_locale, p1, p2);\n   }\nprivate:\n   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID\n   std::map<string_type, char_class_type>  m_custom_class_names; // character class names\n   std::map<string_type, string_type>      m_custom_collate_names; // collating element names\n   unsigned                       m_collate_type;    // the form of the collation string\n   charT                          m_collate_delim;   // the collation group delimiter\n   //\n   // helpers:\n   //\n   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;\n};\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::string_type \n   w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const\n{\n   string_type result;\n   //\n   // What we do here depends upon the format of the sort key returned by\n   // sort key returned by this->transform:\n   //\n   switch(m_collate_type)\n   {\n   case sort_C:\n   case sort_unknown:\n      // the best we can do is translate to lower case, then get a regular sort key:\n      {\n         result.assign(p1, p2);\n         typedef typename string_type::size_type size_type;\n         for(size_type i = 0; i < result.size(); ++i)\n            result[i] = this->tolower(result[i]);\n         result = this->transform(&*result.begin(), &*result.begin() + result.size());\n         break;\n      }\n   case sort_fixed:\n      {\n         // get a regular sort key, and then truncate it:\n         result.assign(this->transform(p1, p2));\n         result.erase(this->m_collate_delim);\n         break;\n      }\n   case sort_delim:\n         // get a regular sort key, and then truncate everything after the delim:\n         result.assign(this->transform(p1, p2));\n         std::size_t i;\n         for(i = 0; i < result.size(); ++i)\n         {\n            if(result[i] == m_collate_delim)\n               break;\n         }\n         result.erase(i);\n         break;\n   }\n   if(result.empty())\n      result = string_type(1, charT(0));\n   return result;\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::string_type \n   w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const\n{\n   typedef typename std::map<string_type, string_type>::const_iterator iter_type;\n   if(m_custom_collate_names.size())\n   {\n      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));\n      if(pos != m_custom_collate_names.end())\n         return pos->second;\n   }\n   std::string name(p1, p2);\n   name = lookup_default_collate_name(name);\n   if(name.size())\n      return string_type(name.begin(), name.end());\n   if(p2 - p1 == 1)\n      return string_type(1, *p1);\n   return string_type();\n}\n\ntemplate <class charT>\nw32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n: w32_regex_traits_char_layer<charT>(l)\n{\n   cat_type cat;\n   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());\n   if(cat_name.size())\n   {\n      cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n      if(!cat)\n      {\n         std::string m(\"Unable to open message catalog: \");\n         std::runtime_error err(m + cat_name);\n         boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n      }\n   }\n   //\n   // if we have a valid catalog then load our messages:\n   //\n   if(cat)\n   {\n      //\n      // Error messages:\n      //\n      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); \n         i <= boost::regex_constants::error_unknown; \n         i = static_cast<boost::regex_constants::error_type>(i + 1))\n      {\n         const char* p = get_default_error_string(i);\n         string_type default_message;\n         while(*p)\n         {\n            default_message.append(1, static_cast<charT>(*p));\n            ++p;\n         }\n         string_type s = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i+200, default_message);\n         std::string result;\n         for(std::string::size_type j = 0; j < s.size(); ++j)\n         {\n            result.append(1, static_cast<char>(s[j]));\n         }\n         m_error_strings[i] = result;\n      }\n      //\n      // Custom class names:\n      //\n      static const char_class_type masks[14] = \n      {\n         0x0104u, // C1_ALPHA | C1_DIGIT\n         0x0100u, // C1_ALPHA\n         0x0020u, // C1_CNTRL\n         0x0004u, // C1_DIGIT\n         (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE\n         0x0002u, // C1_LOWER\n         (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL\n         0x0010u, // C1_PUNCT\n         0x0008u, // C1_SPACE\n         0x0001u, // C1_UPPER\n         0x0080u, // C1_XDIGIT\n         0x0040u, // C1_BLANK\n         w32_regex_traits_implementation<charT>::mask_word,\n         w32_regex_traits_implementation<charT>::mask_unicode,\n      };\n      static const string_type null_string;\n      for(unsigned int j = 0; j <= 13; ++j)\n      {\n         string_type s(::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, j+300, null_string));\n         if(s.size())\n            this->m_custom_class_names[s] = masks[j];\n      }\n   }\n   //\n   // get the collation format used by m_pcollate:\n   //\n   m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);\n}\n\ntemplate <class charT>\ntypename w32_regex_traits_implementation<charT>::char_class_type \n   w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const\n{\n   static const char_class_type masks[22] = \n   {\n      0,\n      0x0104u, // C1_ALPHA | C1_DIGIT\n      0x0100u, // C1_ALPHA\n      0x0040u, // C1_BLANK\n      0x0020u, // C1_CNTRL\n      0x0004u, // C1_DIGIT\n      0x0004u, // C1_DIGIT\n      (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK\n      w32_regex_traits_implementation<charT>::mask_horizontal, \n      0x0002u, // C1_LOWER\n      0x0002u, // C1_LOWER\n      (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL\n      0x0010u, // C1_PUNCT\n      0x0008u, // C1_SPACE\n      0x0008u, // C1_SPACE\n      0x0001u, // C1_UPPER\n      w32_regex_traits_implementation<charT>::mask_unicode,\n      0x0001u, // C1_UPPER\n      w32_regex_traits_implementation<charT>::mask_vertical, \n      0x0104u | w32_regex_traits_implementation<charT>::mask_word, \n      0x0104u | w32_regex_traits_implementation<charT>::mask_word, \n      0x0080u, // C1_XDIGIT\n   };\n   if(m_custom_class_names.size())\n   {\n      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;\n      map_iter pos = m_custom_class_names.find(string_type(p1, p2));\n      if(pos != m_custom_class_names.end())\n         return pos->second;\n   }\n   std::size_t state_id = 1u + (std::size_t)BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);\n   if(state_id < sizeof(masks) / sizeof(masks[0]))\n      return masks[state_id];\n   return masks[0];\n}\n\n\ntemplate <class charT>\nstd::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)\n{\n   // TODO: create a cache for previously constructed objects.\n   return boost::object_cache< ::boost::BOOST_REGEX_DETAIL_NS::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);\n}\n\n} // BOOST_REGEX_DETAIL_NS\n\ntemplate <class charT>\nclass w32_regex_traits\n{\npublic:\n   typedef charT                         char_type;\n   typedef std::size_t                   size_type;\n   typedef std::basic_string<char_type>  string_type;\n   typedef ::boost::BOOST_REGEX_DETAIL_NS::lcid_type locale_type;\n   typedef std::uint_least32_t         char_class_type;\n\n   struct boost_extensions_tag{};\n\n   w32_regex_traits()\n      : m_pimpl(BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(::boost::BOOST_REGEX_DETAIL_NS::w32_get_default_locale()))\n   { }\n   static size_type length(const char_type* p)\n   {\n      return std::char_traits<charT>::length(p);\n   }\n   regex_constants::syntax_type syntax_type(charT c)const\n   {\n      return m_pimpl->syntax_type(c);\n   }\n   regex_constants::escape_syntax_type escape_syntax_type(charT c) const\n   {\n      return m_pimpl->escape_syntax_type(c);\n   }\n   charT translate(charT c) const\n   {\n      return c;\n   }\n   charT translate_nocase(charT c) const\n   {\n      return this->m_pimpl->tolower(c);\n   }\n   charT translate(charT c, bool icase) const\n   {\n      return icase ? this->m_pimpl->tolower(c) : c;\n   }\n   charT tolower(charT c) const\n   {\n      return this->m_pimpl->tolower(c);\n   }\n   charT toupper(charT c) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_toupper(c, this->m_pimpl->m_locale);\n   }\n   string_type transform(const charT* p1, const charT* p2) const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_pimpl->m_locale, p1, p2);\n   }\n   string_type transform_primary(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->transform_primary(p1, p2);\n   }\n   char_class_type lookup_classname(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_classname(p1, p2);\n   }\n   string_type lookup_collatename(const charT* p1, const charT* p2) const\n   {\n      return m_pimpl->lookup_collatename(p1, p2);\n   }\n   bool isctype(charT c, char_class_type f) const\n   {\n      if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base) \n         && (this->m_pimpl->isctype(f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base, c)))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical)\n         && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\\v')))\n         return true;\n      else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_horizontal) \n         && this->isctype(c, 0x0008u) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical))\n         return true;\n      return false;\n   }\n   std::intmax_t toi(const charT*& p1, const charT* p2, int radix)const\n   {\n      return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);\n   }\n   int value(charT c, int radix)const\n   {\n      int result = (int)::boost::BOOST_REGEX_DETAIL_NS::global_value(c);\n      return result < radix ? result : -1;\n   }\n   locale_type imbue(locale_type l)\n   {\n      ::boost::BOOST_REGEX_DETAIL_NS::lcid_type result(getloc());\n      m_pimpl = BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(l);\n      return result;\n   }\n   locale_type getloc()const\n   {\n      return m_pimpl->m_locale;\n   }\n   std::string error_string(regex_constants::error_type n) const\n   {\n      return m_pimpl->error_string(n);\n   }\n\n   //\n   // extension:\n   // set the name of the message catalog in use (defaults to \"boost_regex\").\n   //\n   static std::string catalog_name(const std::string& name);\n   static std::string get_catalog_name();\n\nprivate:\n   std::shared_ptr<const BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT> > m_pimpl;\n   //\n   // catalog name handler:\n   //\n   static std::string& get_catalog_name_inst();\n\n#ifdef BOOST_HAS_THREADS\n   static std::mutex& get_mutex_inst();\n#endif\n};\n\ntemplate <class charT>\nstd::string w32_regex_traits<charT>::catalog_name(const std::string& name)\n{\n#ifdef BOOST_HAS_THREADS\n   std::lock_guard<std::mutex> lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   get_catalog_name_inst() = name;\n   return result;\n}\n\ntemplate <class charT>\nstd::string& w32_regex_traits<charT>::get_catalog_name_inst()\n{\n   static std::string s_name;\n   return s_name;\n}\n\ntemplate <class charT>\nstd::string w32_regex_traits<charT>::get_catalog_name()\n{\n#ifdef BOOST_HAS_THREADS\n   std::lock_guard<std::mutex> lk(get_mutex_inst());\n#endif\n   std::string result(get_catalog_name_inst());\n   return result;\n}\n\n#ifdef BOOST_HAS_THREADS\ntemplate <class charT>\nstd::mutex& w32_regex_traits<charT>::get_mutex_inst()\n{\n   static std::mutex s_mutex;\n   return s_mutex;\n}\n#endif\n\nnamespace BOOST_REGEX_DETAIL_NS {\n\n#ifdef BOOST_NO_ANSI_APIS\n   inline unsigned int get_code_page_for_locale_id(lcid_type idx)\n   {\n      wchar_t code_page_string[7];\n      if (boost::BOOST_REGEX_DETAIL_NS::GetLocaleInfoW(idx, locale_idefaultansicodepage, code_page_string, 7) == 0)\n         return 0;\n\n      return static_cast<unsigned int>(_wtol(code_page_string));\n}\n#endif\n\n   template <class U>\n   inline void w32_regex_traits_char_layer<char>::init()\n   {\n      // we need to start by initialising our syntax map so we know which\n      // character is used for which purpose:\n      std::memset(m_char_map, 0, sizeof(m_char_map));\n      cat_type cat;\n      std::string cat_name(w32_regex_traits<char>::get_catalog_name());\n      if (cat_name.size())\n      {\n         cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);\n         if (!cat)\n         {\n            std::string m(\"Unable to open message catalog: \");\n            std::runtime_error err(m + cat_name);\n            ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);\n         }\n      }\n      //\n      // if we have a valid catalog then load our messages:\n      //\n      if (cat)\n      {\n         for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_syntax(i));\n            for (string_type::size_type j = 0; j < mss.size(); ++j)\n            {\n               m_char_map[static_cast<unsigned char>(mss[j])] = i;\n            }\n         }\n      }\n      else\n      {\n         for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)\n         {\n            const char* ptr = get_default_syntax(i);\n            while (ptr && *ptr)\n            {\n               m_char_map[static_cast<unsigned char>(*ptr)] = i;\n               ++ptr;\n            }\n         }\n      }\n      //\n      // finish off by calculating our escape types:\n      //\n      unsigned char i = 'A';\n      do\n      {\n         if (m_char_map[i] == 0)\n         {\n            if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0002u, (char)i))\n               m_char_map[i] = regex_constants::escape_type_class;\n            else if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0001u, (char)i))\n               m_char_map[i] = regex_constants::escape_type_not_class;\n         }\n      } while (0xFF != i++);\n\n      //\n      // fill in lower case map:\n      //\n      char char_map[1 << CHAR_BIT];\n      for (int ii = 0; ii < (1 << CHAR_BIT); ++ii)\n         char_map[ii] = static_cast<char>(ii);\n#ifndef BOOST_NO_ANSI_APIS\n      int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(this->m_locale, lcmap_lowercase, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(r != 0);\n#else\n      unsigned int code_page = get_code_page_for_locale_id(this->m_locale);\n      BOOST_REGEX_ASSERT(code_page != 0);\n\n      wchar_t wide_char_map[1 << CHAR_BIT];\n      int conv_r = boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, char_map, 1 << CHAR_BIT, wide_char_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(conv_r != 0);\n\n      wchar_t wide_lower_map[1 << CHAR_BIT];\n      int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(this->m_locale, lcmap_lowercase, wide_char_map, 1 << CHAR_BIT, wide_lower_map, 1 << CHAR_BIT);\n      BOOST_REGEX_ASSERT(r != 0);\n\n      conv_r = boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, wide_lower_map, r, this->m_lower_map, 1 << CHAR_BIT, NULL, NULL);\n      BOOST_REGEX_ASSERT(conv_r != 0);\n#endif\n      if (r < (1 << CHAR_BIT))\n      {\n         // if we have multibyte characters then not all may have been given\n         // a lower case mapping:\n         for (int jj = r; jj < (1 << CHAR_BIT); ++jj)\n            this->m_lower_map[jj] = static_cast<char>(jj);\n      }\n\n#ifndef BOOST_NO_ANSI_APIS\n      r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(this->m_locale, ct_ctype1, char_map, 1 << CHAR_BIT, this->m_type_map);\n#else\n      r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(this->m_locale, ct_ctype1, wide_char_map, 1 << CHAR_BIT, this->m_type_map);\n#endif\n      BOOST_REGEX_ASSERT(0 != r);\n   }\n\n   inline lcid_type  w32_get_default_locale()\n   {\n      return boost::BOOST_REGEX_DETAIL_NS::GetUserDefaultLCID();\n   }\n\n   inline bool  w32_is_lower(char c, lcid_type idx)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower))\n         return true;\n      return false;\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      wchar_t wide_c;\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_lower))\n         return true;\n      return false;\n#endif\n   }\n\n   inline bool  w32_is_lower(wchar_t c, lcid_type idx)\n   {\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower))\n         return true;\n      return false;\n   }\n\n   inline bool  w32_is_upper(char c, lcid_type idx)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper))\n         return true;\n      return false;\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      wchar_t wide_c;\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_upper))\n         return true;\n      return false;\n#endif\n   }\n\n   inline bool  w32_is_upper(wchar_t c, lcid_type idx)\n   {\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper))\n         return true;\n      return false;\n   }\n\n   inline void free_module(void* mod)\n   {\n      boost::BOOST_REGEX_DETAIL_NS::FreeLibrary(static_cast<HMODULE>(mod));\n   }\n\n   inline cat_type  w32_cat_open(const std::string& name)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryA(name.c_str()), &free_module);\n      return result;\n#else\n      wchar_t* wide_name = (wchar_t*)_alloca((name.size() + 1) * sizeof(wchar_t));\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(cp_acp, 0, name.c_str(), (int)name.size(), wide_name, (int)(name.size() + 1)) == 0)\n         return cat_type();\n\n      cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryW(wide_name), &free_module);\n      return result;\n#endif\n   }\n\n   inline std::string  w32_cat_get(const cat_type& cat, lcid_type, int i, const std::string& def)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      char buf[256];\n      if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringA(\n         static_cast<HMODULE>(cat.get()),\n         i,\n         buf,\n         256\n      ))\n      {\n         return def;\n      }\n#else\n      wchar_t wbuf[256];\n      int r = boost::BOOST_REGEX_DETAIL_NS::LoadStringW(\n         static_cast<HMODULE>(cat.get()),\n         i,\n         wbuf,\n         256\n      );\n      if (r == 0)\n         return def;\n\n\n      int buf_size = 1 + boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, NULL, 0, NULL, NULL);\n      char* buf = (char*)_alloca(buf_size);\n      if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0)\n         return def; // failed conversion.\n#endif\n      return std::string(buf);\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline std::wstring  w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def)\n   {\n      wchar_t buf[256];\n      if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringW(static_cast<HMODULE>(cat.get()), i, buf, 256))\n      {\n         return def;\n      }\n      return std::wstring(buf);\n   }\n#endif\n   inline std::string  w32_transform(lcid_type idx, const char* p1, const char* p2)\n   {\n#ifndef BOOST_NO_ANSI_APIS\n      int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::string(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         &*result.begin(),  // destination buffer\n         bytes        // size of destination buffer\n      );\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return std::string(p1, p2);\n\n      int src_len = static_cast<int>(p2 - p1);\n      wchar_t* wide_p1 = (wchar_t*)_alloca((src_len + 1) * 2);\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, p1, src_len, wide_p1, src_len + 1) == 0)\n         return std::string(p1, p2);\n\n      int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         wide_p1,  // source string\n         src_len,        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::string(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         wide_p1,  // source string\n         src_len,        // number of characters in source string\n         (wchar_t*) & *result.begin(),  // destination buffer\n         bytes        // size of destination buffer\n      );\n#endif\n      if (bytes > static_cast<int>(result.size()))\n         return std::string(p1, p2);\n      while (result.size() && result[result.size() - 1] == '\\0')\n      {\n         result.erase(result.size() - 1);\n      }\n      return result;\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline std::wstring  w32_transform(lcid_type idx, const wchar_t* p1, const wchar_t* p2)\n   {\n      int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         0,  // destination buffer\n         0        // size of destination buffer\n      );\n      if (!bytes)\n         return std::wstring(p1, p2);\n      std::string result(++bytes, '\\0');\n      bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_sortkey,  // mapping transformation type\n         p1,  // source string\n         static_cast<int>(p2 - p1),        // number of characters in source string\n         reinterpret_cast<wchar_t*>(&*result.begin()),  // destination buffer *of bytes*\n         bytes        // size of destination buffer\n      );\n      if (bytes > static_cast<int>(result.size()))\n         return std::wstring(p1, p2);\n      while (result.size() && result[result.size() - 1] == L'\\0')\n      {\n         result.erase(result.size() - 1);\n      }\n      std::wstring r2;\n      for (std::string::size_type i = 0; i < result.size(); ++i)\n         r2.append(1, static_cast<wchar_t>(static_cast<unsigned char>(result[i])));\n      return r2;\n   }\n#endif\n   inline char  w32_tolower(char c, lcid_type idx)\n   {\n      char result[2];\n#ifndef BOOST_NO_ANSI_APIS\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(\n         idx,       // locale identifier\n         lcmap_lowercase,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return c;\n\n      wchar_t wide_c;\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return c;\n\n      wchar_t  wide_result;\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_lowercase,  // mapping transformation type\n         &wide_c,  // source string\n         1,        // number of characters in source string\n         &wide_result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n\n      if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)\n         return c;  // No single byte lower case equivalent available\n#endif\n      return result[0];\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline wchar_t  w32_tolower(wchar_t c, lcid_type idx)\n   {\n      wchar_t result[2];\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_lowercase,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n      return result[0];\n   }\n#endif\n   inline char  w32_toupper(char c, lcid_type idx)\n   {\n      char result[2];\n#ifndef BOOST_NO_ANSI_APIS\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(\n         idx,       // locale identifier\n         lcmap_uppercase,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return c;\n\n      wchar_t wide_c;\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return c;\n\n      wchar_t wide_result;\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_uppercase,  // mapping transformation type\n         &wide_c,  // source string\n         1,        // number of characters in source string\n         &wide_result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n\n      if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)\n         return c;  // No single byte upper case equivalent available.\n#endif\n      return result[0];\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline wchar_t  w32_toupper(wchar_t c, lcid_type idx)\n   {\n      wchar_t result[2];\n      int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(\n         idx,       // locale identifier\n         lcmap_uppercase,  // mapping transformation type\n         &c,  // source string\n         1,        // number of characters in source string\n         result,  // destination buffer\n         1);        // size of destination buffer\n      if (b == 0)\n         return c;\n      return result[0];\n   }\n#endif\n   inline bool  w32_is(lcid_type idx, std::uint32_t m, char c)\n   {\n      word mask;\n#ifndef BOOST_NO_ANSI_APIS\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))\n         return true;\n#else\n      unsigned int code_page = get_code_page_for_locale_id(idx);\n      if (code_page == 0)\n         return false;\n\n      wchar_t wide_c;\n      if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)\n         return false;\n\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))\n         return true;\n#endif\n      if ((m & w32_regex_traits_implementation<char>::mask_word) && (c == '_'))\n         return true;\n      return false;\n   }\n\n#ifndef BOOST_NO_WREGEX\n   inline bool  w32_is(lcid_type idx, std::uint32_t m, wchar_t c)\n   {\n      word mask;\n      if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base))\n         return true;\n      if ((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_'))\n         return true;\n      if ((m & w32_regex_traits_implementation<wchar_t>::mask_unicode) && (c > 0xff))\n         return true;\n      return false;\n   }\n#endif\n\n} // BOOST_REGEX_DETAIL_NS\n\n\n} // boost\n\n#ifdef BOOST_REGEX_MSVC\n#pragma warning(pop)\n#endif\n\n#endif // BOOST_REGEX_NO_WIN32_LOCALE\n\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex.h",
    "content": "/*\n *\n * Copyright (c) 1998-2000\n * Dr John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n \n /*\n  *   LOCATION:    see http://www.boost.org/libs/regex for documentation.\n  *   FILE         regex.h\n  *   VERSION      3.12\n  *   DESCRIPTION: Declares POSIX API functions\n  */\n\n#ifndef BOOST_RE_REGEX_H\n#define BOOST_RE_REGEX_H\n\n#include <boost/cregex.hpp>\n\n/*\n*  add using declarations to bring POSIX API functions into\n* global scope, only if this is C++ (and not C).\n*/\n#ifdef __cplusplus\n\nusing boost::regoff_t;\nusing boost::regex_tA;\nusing boost::regmatch_t;\nusing boost::REG_BASIC;\nusing boost::REG_EXTENDED;\nusing boost::REG_ICASE;\nusing boost::REG_NOSUB;\nusing boost::REG_NEWLINE;\nusing boost::REG_NOSPEC;\nusing boost::REG_PEND;\nusing boost::REG_DUMP;\nusing boost::REG_NOCOLLATE;\nusing boost::REG_ESCAPE_IN_LISTS;\nusing boost::REG_NEWLINE_ALT;\nusing boost::REG_PERL;\nusing boost::REG_AWK;\nusing boost::REG_GREP;\nusing boost::REG_EGREP;\nusing boost::REG_ASSERT;\nusing boost::REG_INVARG;\nusing boost::REG_ATOI;\nusing boost::REG_ITOA;\n\nusing boost::REG_NOTBOL;\nusing boost::REG_NOTEOL;\nusing boost::REG_STARTEND;\n\nusing boost::reg_comp_flags;\nusing boost::reg_exec_flags;\nusing boost::regcompA;\nusing boost::regerrorA;\nusing boost::regexecA;\nusing boost::regfreeA;\n\n#ifndef BOOST_NO_WREGEX\nusing boost::regcompW;\nusing boost::regerrorW;\nusing boost::regexecW;\nusing boost::regfreeW;\nusing boost::regex_tW;\n#endif\n\nusing boost::REG_NOERROR;\nusing boost::REG_NOMATCH;\nusing boost::REG_BADPAT;\nusing boost::REG_ECOLLATE;\nusing boost::REG_ECTYPE;\nusing boost::REG_EESCAPE;\nusing boost::REG_ESUBREG;\nusing boost::REG_EBRACK;\nusing boost::REG_EPAREN;\nusing boost::REG_EBRACE;\nusing boost::REG_BADBR;\nusing boost::REG_ERANGE;\nusing boost::REG_ESPACE;\nusing boost::REG_BADRPT;\nusing boost::REG_EEND;\nusing boost::REG_ESIZE;\nusing boost::REG_ERPAREN;\nusing boost::REG_EMPTY;\nusing boost::REG_E_MEMORY;\nusing boost::REG_E_UNKNOWN;\nusing boost::reg_errcode_t;\n\n#endif /* __cplusplus */\n\n#endif /* BOOST_RE_REGEX_H */\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org/libs/regex for documentation.\n  *   FILE         regex.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Declares boost::basic_regex<> and associated\n  *                functions and classes. This header is the main\n  *                entry point for the template regex code.\n  */\n\n\n/* start with C compatibility API */\n\n#ifndef BOOST_RE_REGEX_HPP\n#define BOOST_RE_REGEX_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/regex.hpp>\n#else\n#include <boost/regex/v5/regex.hpp>\n#endif\n\n#endif  // include\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/boost-regex/include/boost/regex_fwd.hpp",
    "content": "/*\n *\n * Copyright (c) 1998-2002\n * John Maddock\n *\n * Use, modification and distribution are subject to the \n * Boost Software License, Version 1.0. (See accompanying file \n * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n *\n */\n\n /*\n  *   LOCATION:    see http://www.boost.org/libs/regex for documentation.\n  *   FILE         regex_fwd.cpp\n  *   VERSION      see <boost/version.hpp>\n  *   DESCRIPTION: Forward declares boost::basic_regex<> and\n  *                associated typedefs.\n  */\n\n#ifndef BOOST_REGEX_FWD_HPP\n#define BOOST_REGEX_FWD_HPP\n\n#ifndef BOOST_REGEX_CONFIG_HPP\n#include <boost/regex/config.hpp>\n#endif\n\n#ifdef BOOST_REGEX_CXX03\n#include <boost/regex/v4/regex_fwd.hpp>\n#else\n#include <boost/regex/v5/regex_fwd.hpp>\n#endif\n\n#endif\n\n\n\n\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/CMakeLists.txt",
    "content": "# Require CMake 3.10. If available, use the policies up to CMake 3.22.\ncmake_minimum_required (VERSION 3.10...3.22)\n\nproject (benchmark VERSION 1.8.5 LANGUAGES CXX)\n\noption(BENCHMARK_ENABLE_TESTING \"Enable testing of the benchmark library.\" ON)\noption(BENCHMARK_ENABLE_EXCEPTIONS \"Enable the use of exceptions in the benchmark library.\" ON)\noption(BENCHMARK_ENABLE_LTO \"Enable link time optimisation of the benchmark library.\" OFF)\noption(BENCHMARK_USE_LIBCXX \"Build and test using libc++ as the standard library.\" OFF)\noption(BENCHMARK_ENABLE_WERROR \"Build Release candidates with -Werror.\" ON)\noption(BENCHMARK_FORCE_WERROR \"Build Release candidates with -Werror regardless of compiler issues.\" OFF)\n\nif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"PGI\")\n  # PGC++ maybe reporting false positives.\n  set(BENCHMARK_ENABLE_WERROR OFF)\nendif()\nif(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"NVHPC\")\n  set(BENCHMARK_ENABLE_WERROR OFF)\nendif()\nif(BENCHMARK_FORCE_WERROR)\n  set(BENCHMARK_ENABLE_WERROR ON)\nendif(BENCHMARK_FORCE_WERROR)\n\nif(NOT (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL \"MSVC\"))\n  option(BENCHMARK_BUILD_32_BITS \"Build a 32 bit version of the library.\" OFF)\nelse()\n  set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL \"Build a 32 bit version of the library - unsupported when using MSVC)\" FORCE)\nendif()\noption(BENCHMARK_ENABLE_INSTALL \"Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)\" ON)\noption(BENCHMARK_ENABLE_DOXYGEN \"Build documentation with Doxygen.\" OFF)\noption(BENCHMARK_INSTALL_DOCS \"Enable installation of documentation.\" ON)\n\n# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which\n# may require downloading the source code.\noption(BENCHMARK_DOWNLOAD_DEPENDENCIES \"Allow the downloading and in-tree building of unmet dependencies\" OFF)\n\n# This option can be used to disable building and running unit tests which depend on gtest\n# in cases where it is not possible to build or find a valid version of gtest.\noption(BENCHMARK_ENABLE_GTEST_TESTS \"Enable building the unit tests which depend on gtest\" ON)\noption(BENCHMARK_USE_BUNDLED_GTEST \"Use bundled GoogleTest. If disabled, the find_package(GTest) will be used.\" ON)\n\noption(BENCHMARK_ENABLE_LIBPFM \"Enable performance counters provided by libpfm\" OFF)\n\n# Export only public symbols\nset(CMAKE_CXX_VISIBILITY_PRESET hidden)\nset(CMAKE_VISIBILITY_INLINES_HIDDEN ON)\n\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n    # As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and\n    # cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the\n    # undocumented, but working variable.\n    # See https://gitlab.kitware.com/cmake/cmake/-/issues/15170\n    set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID})\n    if(${CMAKE_SYSTEM_PROCESSOR} MATCHES \"ARM\")\n      set(CMAKE_CROSSCOMPILING TRUE)\n    endif()\nendif()\n\nset(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)\nfunction(should_enable_assembly_tests)\n  if(CMAKE_BUILD_TYPE)\n    string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)\n    if (${CMAKE_BUILD_TYPE_LOWER} MATCHES \"coverage\")\n      # FIXME: The --coverage flag needs to be removed when building assembly\n      # tests for this to work.\n      return()\n    endif()\n  endif()\n  if (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL \"MSVC\")\n    return()\n  elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64\")\n    return()\n  elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)\n    # FIXME: Make these work on 32 bit builds\n    return()\n  elseif(BENCHMARK_BUILD_32_BITS)\n     # FIXME: Make these work on 32 bit builds\n    return()\n  endif()\n  find_program(LLVM_FILECHECK_EXE FileCheck)\n  if (LLVM_FILECHECK_EXE)\n    set(LLVM_FILECHECK_EXE \"${LLVM_FILECHECK_EXE}\" CACHE PATH \"llvm filecheck\" FORCE)\n    message(STATUS \"LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}\")\n  else()\n    message(STATUS \"Failed to find LLVM FileCheck\")\n    return()\n  endif()\n  set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)\nendfunction()\nshould_enable_assembly_tests()\n\n# This option disables the building and running of the assembly verification tests\noption(BENCHMARK_ENABLE_ASSEMBLY_TESTS \"Enable building and running the assembly tests\"\n    ${ENABLE_ASSEMBLY_TESTS_DEFAULT})\n\n# Make sure we can import out CMake functions\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules\")\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\")\n\n\n# Read the git tags to determine the project version\ninclude(GetGitVersion)\nget_git_version(GIT_VERSION)\n\n# If no git version can be determined, use the version\n# from the project() command\nif (\"${GIT_VERSION}\" STREQUAL \"v0.0.0\")\n  set(VERSION \"v${benchmark_VERSION}\")\nelse()\n  set(VERSION \"${GIT_VERSION}\")\nendif()\n\n# Normalize version: drop \"v\" prefix, replace first \"-\" with \".\",\n# drop everything after second \"-\" (including said \"-\").\nstring(STRIP ${VERSION} VERSION)\nif(VERSION MATCHES v[^-]*-)\n   string(REGEX REPLACE \"v([^-]*)-([0-9]+)-.*\" \"\\\\1.\\\\2\"  NORMALIZED_VERSION ${VERSION})\nelse()\n   string(REGEX REPLACE \"v(.*)\" \"\\\\1\" NORMALIZED_VERSION ${VERSION})\nendif()\n\n# Tell the user what versions we are using\nmessage(STATUS \"Google Benchmark version: ${VERSION}, normalized to ${NORMALIZED_VERSION}\")\n\n# The version of the libraries\nset(GENERIC_LIB_VERSION ${NORMALIZED_VERSION})\nstring(SUBSTRING ${NORMALIZED_VERSION} 0 1 GENERIC_LIB_SOVERSION)\n\n# Import our CMake modules\ninclude(AddCXXCompilerFlag)\ninclude(CheckCXXCompilerFlag)\ninclude(CheckLibraryExists)\ninclude(CXXFeatureCheck)\n\ncheck_library_exists(rt shm_open \"\" HAVE_LIB_RT)\n\nif (BENCHMARK_BUILD_32_BITS)\n  add_required_cxx_compiler_flag(-m32)\nendif()\n\nset(BENCHMARK_CXX_STANDARD 14)\n\nset(CMAKE_CXX_STANDARD ${BENCHMARK_CXX_STANDARD})\nset(CMAKE_CXX_STANDARD_REQUIRED YES)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nif (MSVC)\n  # Turn compiler warnings up to 11\n  string(REGEX REPLACE \"[-/]W[1-4]\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /W4\")\n  add_definitions(-D_CRT_SECURE_NO_WARNINGS)\n\n  if (NOT BENCHMARK_ENABLE_EXCEPTIONS)\n    add_cxx_compiler_flag(-EHs-)\n    add_cxx_compiler_flag(-EHa-)\n    add_definitions(-D_HAS_EXCEPTIONS=0)\n  endif()\n  # Link time optimisation\n  if (BENCHMARK_ENABLE_LTO)\n    set(CMAKE_CXX_FLAGS_RELEASE \"${CMAKE_CXX_FLAGS_RELEASE} /GL\")\n    set(CMAKE_STATIC_LINKER_FLAGS_RELEASE \"${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG\")\n    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE \"${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG\")\n    set(CMAKE_EXE_LINKER_FLAGS_RELEASE \"${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG\")\n\n    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO \"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n    string(REGEX REPLACE \"[-/]INCREMENTAL\" \"/INCREMENTAL:NO\" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}\")\n    set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO \"${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG\")\n\n    set(CMAKE_CXX_FLAGS_MINSIZEREL \"${CMAKE_CXX_FLAGS_MINSIZEREL} /GL\")\n    set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL \"${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n    set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL \"${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n    set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL \"${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG\")\n  endif()\nelse()\n  # Turn on Large-file Support\n  add_definitions(-D_FILE_OFFSET_BITS=64)\n  add_definitions(-D_LARGEFILE64_SOURCE)\n  add_definitions(-D_LARGEFILE_SOURCE)\n  # Turn compiler warnings up to 11\n  add_cxx_compiler_flag(-Wall)\n  add_cxx_compiler_flag(-Wextra)\n  add_cxx_compiler_flag(-Wshadow)\n  add_cxx_compiler_flag(-Wfloat-equal)\n  add_cxx_compiler_flag(-Wold-style-cast)\n  add_cxx_compiler_flag(-Wconversion)\n  if(BENCHMARK_ENABLE_WERROR)\n      add_cxx_compiler_flag(-Werror)\n  endif()\n  if (NOT BENCHMARK_ENABLE_TESTING)\n    # Disable warning when compiling tests as gtest does not use 'override'.\n    add_cxx_compiler_flag(-Wsuggest-override)\n  endif()\n  add_cxx_compiler_flag(-pedantic)\n  add_cxx_compiler_flag(-pedantic-errors)\n  add_cxx_compiler_flag(-Wshorten-64-to-32)\n  add_cxx_compiler_flag(-fstrict-aliasing)\n  # Disable warnings regarding deprecated parts of the library while building\n  # and testing those parts of the library.\n  add_cxx_compiler_flag(-Wno-deprecated-declarations)\n  if (CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\" OR CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n    # Intel silently ignores '-Wno-deprecated-declarations',\n    # warning no. 1786 must be explicitly disabled.\n    # See #631 for rationale.\n    add_cxx_compiler_flag(-wd1786)\n    add_cxx_compiler_flag(-fno-finite-math-only)\n  endif()\n  # Disable deprecation warnings for release builds (when -Werror is enabled).\n  if(BENCHMARK_ENABLE_WERROR)\n      add_cxx_compiler_flag(-Wno-deprecated)\n  endif()\n  if (NOT BENCHMARK_ENABLE_EXCEPTIONS)\n    add_cxx_compiler_flag(-fno-exceptions)\n  endif()\n\n  if (HAVE_CXX_FLAG_FSTRICT_ALIASING)\n    if (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\") #ICC17u2: Many false positives for Wstrict-aliasing\n      add_cxx_compiler_flag(-Wstrict-aliasing)\n    endif()\n  endif()\n  # ICC17u2: overloaded virtual function \"benchmark::Fixture::SetUp\" is only partially overridden\n  # (because of deprecated overload)\n  add_cxx_compiler_flag(-wd654)\n  add_cxx_compiler_flag(-Wthread-safety)\n  if (HAVE_CXX_FLAG_WTHREAD_SAFETY)\n    cxx_feature_check(THREAD_SAFETY_ATTRIBUTES \"-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include\")\n  endif()\n\n  # On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a\n  # predefined macro, which turns on all of the wonderful libc extensions.\n  # However g++ doesn't do this in Cygwin so we have to define it ourselves\n  # since we depend on GNU/POSIX/BSD extensions.\n  if (CYGWIN)\n    add_definitions(-D_GNU_SOURCE=1)\n  endif()\n\n  if (QNXNTO)\n    add_definitions(-D_QNX_SOURCE)\n  endif()\n\n  # Link time optimisation\n  if (BENCHMARK_ENABLE_LTO)\n    add_cxx_compiler_flag(-flto)\n    add_cxx_compiler_flag(-Wno-lto-type-mismatch)\n    if (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\")\n      find_program(GCC_AR gcc-ar)\n      if (GCC_AR)\n        set(CMAKE_AR ${GCC_AR})\n      endif()\n      find_program(GCC_RANLIB gcc-ranlib)\n      if (GCC_RANLIB)\n        set(CMAKE_RANLIB ${GCC_RANLIB})\n      endif()\n    elseif(\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n      include(llvm-toolchain)\n    endif()\n  endif()\n\n  # Coverage build type\n  set(BENCHMARK_CXX_FLAGS_COVERAGE \"${CMAKE_CXX_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used by the C++ compiler during coverage builds.\"\n    FORCE)\n  set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE \"${CMAKE_EXE_LINKER_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used for linking binaries during coverage builds.\"\n    FORCE)\n  set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE \"${CMAKE_SHARED_LINKER_FLAGS_DEBUG}\"\n    CACHE STRING \"Flags used by the shared libraries linker during coverage builds.\"\n    FORCE)\n  mark_as_advanced(\n    BENCHMARK_CXX_FLAGS_COVERAGE\n    BENCHMARK_EXE_LINKER_FLAGS_COVERAGE\n    BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE)\n  set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\" CACHE STRING\n    \"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.\")\n  add_cxx_compiler_flag(--coverage COVERAGE)\nendif()\n\nif (BENCHMARK_USE_LIBCXX)\n  if (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n    add_cxx_compiler_flag(-stdlib=libc++)\n  elseif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\" OR\n          \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Intel\" OR\n          \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"IntelLLVM\")\n    add_cxx_compiler_flag(-nostdinc++)\n    message(WARNING \"libc++ header path must be manually specified using CMAKE_CXX_FLAGS\")\n    # Adding -nodefaultlibs directly to CMAKE_<TYPE>_LINKER_FLAGS will break\n    # configuration checks such as 'find_package(Threads)'\n    list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)\n    # -lc++ cannot be added directly to CMAKE_<TYPE>_LINKER_FLAGS because\n    # linker flags appear before all linker inputs and -lc++ must appear after.\n    list(APPEND BENCHMARK_CXX_LIBRARIES c++)\n  else()\n    message(FATAL_ERROR \"-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler\")\n  endif()\nendif(BENCHMARK_USE_LIBCXX)\n\nset(EXTRA_CXX_FLAGS \"\")\nif (WIN32 AND \"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n  # Clang on Windows fails to compile the regex feature check under C++11\n  set(EXTRA_CXX_FLAGS \"-DCMAKE_CXX_STANDARD=14\")\nendif()\n\n# C++ feature checks\n# Determine the correct regular expression engine to use\ncxx_feature_check(STD_REGEX ${EXTRA_CXX_FLAGS})\ncxx_feature_check(GNU_POSIX_REGEX ${EXTRA_CXX_FLAGS})\ncxx_feature_check(POSIX_REGEX ${EXTRA_CXX_FLAGS})\nif(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)\n  message(FATAL_ERROR \"Failed to determine the source files for the regular expression backend\")\nendif()\nif (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX\n        AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)\n  message(WARNING \"Using std::regex with exceptions disabled is not fully supported\")\nendif()\n\ncxx_feature_check(STEADY_CLOCK)\n# Ensure we have pthreads\nset(THREADS_PREFER_PTHREAD_FLAG ON)\nfind_package(Threads REQUIRED)\ncxx_feature_check(PTHREAD_AFFINITY)\n\nif (BENCHMARK_ENABLE_LIBPFM)\n  find_package(PFM REQUIRED)\nendif()\n\n# Set up directories\ninclude_directories(${PROJECT_SOURCE_DIR}/include)\n\n# Build the targets\nadd_subdirectory(src)\n\nif (BENCHMARK_ENABLE_TESTING)\n  enable_testing()\n  if (BENCHMARK_ENABLE_GTEST_TESTS AND\n      NOT (TARGET gtest AND TARGET gtest_main AND\n           TARGET gmock AND TARGET gmock_main))\n    if (BENCHMARK_USE_BUNDLED_GTEST)\n      include(GoogleTest)\n    else()\n      find_package(GTest CONFIG REQUIRED)\n      add_library(gtest ALIAS GTest::gtest)\n      add_library(gtest_main ALIAS GTest::gtest_main)\n      add_library(gmock ALIAS GTest::gmock)\n      add_library(gmock_main ALIAS GTest::gmock_main)\n    endif()\n  endif()\n  add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/AddCXXCompilerFlag.cmake",
    "content": "# - Adds a compiler flag if it is supported by the compiler\n#\n# This function checks that the supplied compiler flag is supported and then\n# adds it to the corresponding compiler flags\n#\n#  add_cxx_compiler_flag(<FLAG> [<VARIANT>])\n#\n# - Example\n#\n# include(AddCXXCompilerFlag)\n# add_cxx_compiler_flag(-Wall)\n# add_cxx_compiler_flag(-no-strict-aliasing RELEASE)\n# Requires CMake 2.6+\n\nif(__add_cxx_compiler_flag)\n  return()\nendif()\nset(__add_cxx_compiler_flag INCLUDED)\n\ninclude(CheckCXXCompilerFlag)\n\nfunction(mangle_compiler_flag FLAG OUTPUT)\n  string(TOUPPER \"HAVE_CXX_FLAG_${FLAG}\" SANITIZED_FLAG)\n  string(REPLACE \"+\" \"X\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  string(REGEX REPLACE \"[^A-Za-z_0-9]\" \"_\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  string(REGEX REPLACE \"_+\" \"_\" SANITIZED_FLAG ${SANITIZED_FLAG})\n  set(${OUTPUT} \"${SANITIZED_FLAG}\" PARENT_SCOPE)\nendfunction(mangle_compiler_flag)\n\nfunction(add_cxx_compiler_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\n  if(${MANGLED_FLAG})\n    if(ARGC GREATER 1)\n      set(VARIANT ${ARGV1})\n      string(TOUPPER \"_${VARIANT}\" VARIANT)\n    else()\n      set(VARIANT \"\")\n    endif()\n    set(CMAKE_CXX_FLAGS${VARIANT} \"${CMAKE_CXX_FLAGS${VARIANT}} ${BENCHMARK_CXX_FLAGS${VARIANT}} ${FLAG}\" PARENT_SCOPE)\n  endif()\nendfunction()\n\nfunction(add_required_cxx_compiler_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\n  if(${MANGLED_FLAG})\n    if(ARGC GREATER 1)\n      set(VARIANT ${ARGV1})\n      string(TOUPPER \"_${VARIANT}\" VARIANT)\n    else()\n      set(VARIANT \"\")\n    endif()\n    set(CMAKE_CXX_FLAGS${VARIANT} \"${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_MODULE_LINKER_FLAGS \"${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}\" PARENT_SCOPE)\n    set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} ${FLAG}\" PARENT_SCOPE)\n  else()\n    message(FATAL_ERROR \"Required flag '${FLAG}' is not supported by the compiler\")\n  endif()\nendfunction()\n\nfunction(check_cxx_warning_flag FLAG)\n  mangle_compiler_flag(\"${FLAG}\" MANGLED_FLAG)\n  set(OLD_CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS}\")\n  # Add -Werror to ensure the compiler generates an error if the warning flag\n  # doesn't exist.\n  set(CMAKE_REQUIRED_FLAGS \"${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}\")\n  check_cxx_compiler_flag(\"${FLAG}\" ${MANGLED_FLAG})\n  set(CMAKE_REQUIRED_FLAGS \"${OLD_CMAKE_REQUIRED_FLAGS}\")\nendfunction()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/CXXFeatureCheck.cmake",
    "content": "# - Compile and run code to check for C++ features\n#\n# This functions compiles a source file under the `cmake` folder\n# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake\n# environment\n#\n#  cxx_feature_check(<FLAG> [<VARIANT>])\n#\n# - Example\n#\n# include(CXXFeatureCheck)\n# cxx_feature_check(STD_REGEX)\n# Requires CMake 2.8.12+\n\nif(__cxx_feature_check)\n  return()\nendif()\nset(__cxx_feature_check INCLUDED)\n\noption(CXXFEATURECHECK_DEBUG OFF)\n\nfunction(cxx_feature_check FILE)\n  string(TOLOWER ${FILE} FILE)\n  string(TOUPPER ${FILE} VAR)\n  string(TOUPPER \"HAVE_${VAR}\" FEATURE)\n  if (DEFINED HAVE_${VAR})\n    set(HAVE_${VAR} 1 PARENT_SCOPE)\n    add_definitions(-DHAVE_${VAR})\n    return()\n  endif()\n\n  set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\n  if (ARGC GREATER 1)\n    message(STATUS \"Enabling additional flags: ${ARGV1}\")\n    list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})\n  endif()\n\n  if (NOT DEFINED COMPILE_${FEATURE})\n    if(CMAKE_CROSSCOMPILING)\n      message(STATUS \"Cross-compiling to test ${FEATURE}\")\n      try_compile(COMPILE_${FEATURE}\n              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp\n              CXX_STANDARD 11\n              CXX_STANDARD_REQUIRED ON\n              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}\n              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}\n              OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)\n      if(COMPILE_${FEATURE})\n        message(WARNING\n              \"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0\")\n        set(RUN_${FEATURE} 0 CACHE INTERNAL \"\")\n      else()\n        set(RUN_${FEATURE} 1 CACHE INTERNAL \"\")\n      endif()\n    else()\n      message(STATUS \"Compiling and running to test ${FEATURE}\")\n      try_run(RUN_${FEATURE} COMPILE_${FEATURE}\n              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp\n              CXX_STANDARD 11\n              CXX_STANDARD_REQUIRED ON\n              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}\n              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}\n              COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)\n    endif()\n  endif()\n\n  if(RUN_${FEATURE} EQUAL 0)\n    message(STATUS \"Performing Test ${FEATURE} -- success\")\n    set(HAVE_${VAR} 1 PARENT_SCOPE)\n    add_definitions(-DHAVE_${VAR})\n  else()\n    if(NOT COMPILE_${FEATURE})\n      if(CXXFEATURECHECK_DEBUG)\n        message(STATUS \"Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}\")\n      else()\n        message(STATUS \"Performing Test ${FEATURE} -- failed to compile\")\n      endif()\n    else()\n      message(STATUS \"Performing Test ${FEATURE} -- compiled but failed to run\")\n    endif()\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/Config.cmake.in",
    "content": "@PACKAGE_INIT@\n\ninclude (CMakeFindDependencyMacro)\n\nfind_dependency (Threads)\n\nif (@BENCHMARK_ENABLE_LIBPFM@)\n    find_dependency (PFM)\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake\")\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/GetGitVersion.cmake",
    "content": "# - Returns a version string from Git tags\n#\n# This function inspects the annotated git tags for the project and returns a string\n# into a CMake variable\n#\n#  get_git_version(<var>)\n#\n# - Example\n#\n# include(GetGitVersion)\n# get_git_version(GIT_VERSION)\n#\n# Requires CMake 2.8.11+\nfind_package(Git)\n\nif(__get_git_version)\n  return()\nendif()\nset(__get_git_version INCLUDED)\n\nfunction(get_git_version var)\n  if(GIT_EXECUTABLE)\n      execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match \"v[0-9]*.[0-9]*.[0-9]*\" --abbrev=8 --dirty\n          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n          RESULT_VARIABLE status\n          OUTPUT_VARIABLE GIT_VERSION\n          ERROR_QUIET)\n      if(status)\n          set(GIT_VERSION \"v0.0.0\")\n      endif()\n  else()\n      set(GIT_VERSION \"v0.0.0\")\n  endif()\n\n  set(${var} ${GIT_VERSION} PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/GoogleTest.cmake",
    "content": "# Download and unpack googletest at configure time\nset(GOOGLETEST_PREFIX \"${benchmark_BINARY_DIR}/third_party/googletest\")\nconfigure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY)\n\nset(GOOGLETEST_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/googletest\" CACHE PATH \"\") # Mind the quotes\nexecute_process(COMMAND ${CMAKE_COMMAND} -G \"${CMAKE_GENERATOR}\"\n  -DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH=${GOOGLETEST_PATH} .\n  RESULT_VARIABLE result\n  WORKING_DIRECTORY ${GOOGLETEST_PREFIX}\n)\n\nif(result)\n  message(FATAL_ERROR \"CMake step for googletest failed: ${result}\")\nendif()\n\nexecute_process(\n  COMMAND ${CMAKE_COMMAND} --build .\n  RESULT_VARIABLE result\n  WORKING_DIRECTORY ${GOOGLETEST_PREFIX}\n)\n\nif(result)\n  message(FATAL_ERROR \"Build step for googletest failed: ${result}\")\nendif()\n\n# Prevent overriding the parent project's compiler/linker\n# settings on Windows\nset(gtest_force_shared_crt ON CACHE BOOL \"\" FORCE)\n\ninclude(${GOOGLETEST_PREFIX}/googletest-paths.cmake)\n\n# Add googletest directly to our build. This defines\n# the gtest and gtest_main targets.\nadd_subdirectory(${GOOGLETEST_SOURCE_DIR}\n                 ${GOOGLETEST_BINARY_DIR}\n                 EXCLUDE_FROM_ALL)\n\n# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.\nif (MSVC)\n  target_compile_options(gtest PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gtest_main PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gmock PRIVATE \"/wd4244\" \"/wd4722\")\n  target_compile_options(gmock_main PRIVATE \"/wd4244\" \"/wd4722\")\nelse()\n  target_compile_options(gtest PRIVATE \"-w\")\n  target_compile_options(gtest_main PRIVATE \"-w\")\n  target_compile_options(gmock PRIVATE \"-w\")\n  target_compile_options(gmock_main PRIVATE \"-w\")\nendif()\n\nif(NOT DEFINED GTEST_COMPILE_COMMANDS)\n    set(GTEST_COMPILE_COMMANDS ON)\nendif()\n\nset_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\nset_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/GoogleTest.cmake.in",
    "content": "cmake_minimum_required(VERSION 2.8.12)\n\nproject(googletest-download NONE)\n\n# Enable ExternalProject CMake module\ninclude(ExternalProject)\n\noption(ALLOW_DOWNLOADING_GOOGLETEST \"If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet\" OFF)\nset(GOOGLETEST_PATH \"/usr/src/googletest\" CACHE PATH\n                    \"Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs\")\n\n# Download and install GoogleTest\n\nmessage(STATUS \"Looking for Google Test sources\")\nmessage(STATUS \"Looking for Google Test sources in ${GOOGLETEST_PATH}\")\nif(EXISTS \"${GOOGLETEST_PATH}\"            AND IS_DIRECTORY \"${GOOGLETEST_PATH}\"            AND EXISTS \"${GOOGLETEST_PATH}/CMakeLists.txt\" AND\n   EXISTS \"${GOOGLETEST_PATH}/googletest\" AND IS_DIRECTORY \"${GOOGLETEST_PATH}/googletest\" AND EXISTS \"${GOOGLETEST_PATH}/googletest/CMakeLists.txt\" AND\n   EXISTS \"${GOOGLETEST_PATH}/googlemock\" AND IS_DIRECTORY \"${GOOGLETEST_PATH}/googlemock\" AND EXISTS \"${GOOGLETEST_PATH}/googlemock/CMakeLists.txt\")\n  message(STATUS \"Found Google Test in ${GOOGLETEST_PATH}\")\n\n  ExternalProject_Add(\n    googletest\n    PREFIX            \"${CMAKE_BINARY_DIR}\"\n    DOWNLOAD_DIR      \"${CMAKE_BINARY_DIR}/download\"\n    SOURCE_DIR        \"${GOOGLETEST_PATH}\" # use existing src dir.\n    BINARY_DIR        \"${CMAKE_BINARY_DIR}/build\"\n    CONFIGURE_COMMAND \"\"\n    BUILD_COMMAND     \"\"\n    INSTALL_COMMAND   \"\"\n    TEST_COMMAND      \"\"\n  )\nelse()\n  if(NOT ALLOW_DOWNLOADING_GOOGLETEST)\n    message(SEND_ERROR \"Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable BENCHMARK_DOWNLOAD_DEPENDENCIES, or disable BENCHMARK_USE_BUNDLED_GTEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.\")\n    return()\n  else()\n    message(WARNING \"Did not find Google Test sources! Fetching from web...\")\n    ExternalProject_Add(\n      googletest\n      GIT_REPOSITORY    https://github.com/google/googletest.git\n      GIT_TAG           \"release-1.11.0\"\n      PREFIX            \"${CMAKE_BINARY_DIR}\"\n      STAMP_DIR         \"${CMAKE_BINARY_DIR}/stamp\"\n      DOWNLOAD_DIR      \"${CMAKE_BINARY_DIR}/download\"\n      SOURCE_DIR        \"${CMAKE_BINARY_DIR}/src\"\n      BINARY_DIR        \"${CMAKE_BINARY_DIR}/build\"\n      CONFIGURE_COMMAND \"\"\n      BUILD_COMMAND     \"\"\n      INSTALL_COMMAND   \"\"\n      TEST_COMMAND      \"\"\n    )\n  endif()\nendif()\n\nExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR)\nfile(WRITE googletest-paths.cmake\n\"set(GOOGLETEST_SOURCE_DIR \\\"${SOURCE_DIR}\\\")\nset(GOOGLETEST_BINARY_DIR \\\"${BINARY_DIR}\\\")\n\")\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/Modules/FindLLVMAr.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMAR_EXECUTABLE\n  NAMES llvm-ar\n  DOC \"The llvm-ar executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMAr\n  DEFAULT_MSG\n  LLVMAR_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMAr PROPERTIES\n  URL https://llvm.org/docs/CommandGuide/llvm-ar.html\n  DESCRIPTION \"create, modify, and extract from archives\"\n)\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/Modules/FindLLVMNm.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMNM_EXECUTABLE\n  NAMES llvm-nm\n  DOC \"The llvm-nm executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMNm\n  DEFAULT_MSG\n  LLVMNM_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMNm PROPERTIES\n  URL https://llvm.org/docs/CommandGuide/llvm-nm.html\n  DESCRIPTION \"list LLVM bitcode and object file’s symbol table\"\n)\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/Modules/FindLLVMRanLib.cmake",
    "content": "include(FeatureSummary)\n\nfind_program(LLVMRANLIB_EXECUTABLE\n  NAMES llvm-ranlib\n  DOC \"The llvm-ranlib executable\"\n  )\n\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(LLVMRanLib\n  DEFAULT_MSG\n  LLVMRANLIB_EXECUTABLE)\n\nSET_PACKAGE_PROPERTIES(LLVMRanLib PROPERTIES\n  DESCRIPTION \"generate index for LLVM archive\"\n)\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/Modules/FindPFM.cmake",
    "content": "# If successful, the following variables will be defined:\n# PFM_FOUND.\n# PFM_LIBRARIES\n# PFM_INCLUDE_DIRS\n# the following target will be defined:\n# PFM::libpfm\n\ninclude(FeatureSummary)\ninclude(FindPackageHandleStandardArgs)\n\nset_package_properties(PFM PROPERTIES\n                       URL http://perfmon2.sourceforge.net/\n                       DESCRIPTION \"A helper library to develop monitoring tools\"\n                       PURPOSE \"Used to program specific performance monitoring events\")\n\nfind_library(PFM_LIBRARY NAMES pfm)\nfind_path(PFM_INCLUDE_DIR NAMES perfmon/pfmlib.h)\n\nfind_package_handle_standard_args(PFM REQUIRED_VARS PFM_LIBRARY PFM_INCLUDE_DIR)\n\nif (PFM_FOUND AND NOT TARGET PFM::libpfm)\n    add_library(PFM::libpfm UNKNOWN IMPORTED)\n    set_target_properties(PFM::libpfm PROPERTIES\n        IMPORTED_LOCATION \"${PFM_LIBRARY}\"\n        INTERFACE_INCLUDE_DIRECTORIES \"${PFM_INCLUDE_DIR}\")\nendif()\n\nmark_as_advanced(PFM_LIBRARY PFM_INCLUDE_DIR)\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/benchmark.pc.in",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=${prefix}\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: @PROJECT_NAME@\nDescription: Google microbenchmark framework\nVersion: @VERSION@\n\nLibs: -L${libdir} -lbenchmark\nLibs.private: -lpthread @BENCHMARK_PRIVATE_LINK_LIBRARIES@\nCflags: -I${includedir}\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/benchmark_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\n\nName: @PROJECT_NAME@\nDescription: Google microbenchmark framework (with main() function)\nVersion: @VERSION@\nRequires: benchmark\nLibs: -L${libdir} -lbenchmark_main\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/gnu_posix_regex.cpp",
    "content": "#include <gnuregex.h>\n#include <string>\nint main() {\n  std::string str = \"test0159\";\n  regex_t re;\n  int ec = regcomp(&re, \"^[a-z]+[0-9]+$\", REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    return ec;\n  }\n  return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;\n}\n\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/llvm-toolchain.cmake",
    "content": "find_package(LLVMAr REQUIRED)\nset(CMAKE_AR \"${LLVMAR_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n\nfind_package(LLVMNm REQUIRED)\nset(CMAKE_NM \"${LLVMNM_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n\nfind_package(LLVMRanLib REQUIRED)\nset(CMAKE_RANLIB \"${LLVMRANLIB_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/posix_regex.cpp",
    "content": "#include <regex.h>\n#include <string>\nint main() {\n  std::string str = \"test0159\";\n  regex_t re;\n  int ec = regcomp(&re, \"^[a-z]+[0-9]+$\", REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    return ec;\n  }\n  int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;\n  regfree(&re);\n  return ret;\n}\n\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/pthread_affinity.cpp",
    "content": "#include <pthread.h>\nint main() {\n  cpu_set_t set;\n  CPU_ZERO(&set);\n  for (int i = 0; i < CPU_SETSIZE; ++i) {\n    CPU_SET(i, &set);\n    CPU_CLR(i, &set);\n  }\n  pthread_t self = pthread_self();\n  int ret;\n  ret = pthread_getaffinity_np(self, sizeof(set), &set);\n  if (ret != 0) return ret;\n  ret = pthread_setaffinity_np(self, sizeof(set), &set);\n  if (ret != 0) return ret;\n  return 0;\n}\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/split_list.cmake",
    "content": "macro(split_list listname)\n  string(REPLACE \";\" \" \" ${listname} \"${${listname}}\")\nendmacro()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/std_regex.cpp",
    "content": "#include <regex>\n#include <string>\nint main() {\n  const std::string str = \"test0159\";\n  std::regex re;\n  re = std::regex(\"^[a-z]+[0-9]+$\",\n       std::regex_constants::extended | std::regex_constants::nosubs);\n  return std::regex_search(str, re) ? 0 : -1;\n}\n\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/steady_clock.cpp",
    "content": "#include <chrono>\n\nint main() {\n    typedef std::chrono::steady_clock Clock;\n    Clock::time_point tp = Clock::now();\n    ((void)tp);\n}\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/cmake/thread_safety_attributes.cpp",
    "content": "#define HAVE_THREAD_SAFETY_ATTRIBUTES\n#include \"../src/mutex.h\"\n\nint main() {}\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/include/benchmark/benchmark.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Support for registering benchmarks for functions.\n\n/* Example usage:\n// Define a function that executes the code to be measured a\n// specified number of times:\nstatic void BM_StringCreation(benchmark::State& state) {\n  for (auto _ : state)\n    std::string empty_string;\n}\n\n// Register the function as a benchmark\nBENCHMARK(BM_StringCreation);\n\n// Define another benchmark\nstatic void BM_StringCopy(benchmark::State& state) {\n  std::string x = \"hello\";\n  for (auto _ : state)\n    std::string copy(x);\n}\nBENCHMARK(BM_StringCopy);\n\n// Augment the main() program to invoke benchmarks if specified\n// via the --benchmark_filter command line flag.  E.g.,\n//       my_unittest --benchmark_filter=all\n//       my_unittest --benchmark_filter=BM_StringCreation\n//       my_unittest --benchmark_filter=String\n//       my_unittest --benchmark_filter='Copy|Creation'\nint main(int argc, char** argv) {\n  benchmark::Initialize(&argc, argv);\n  benchmark::RunSpecifiedBenchmarks();\n  benchmark::Shutdown();\n  return 0;\n}\n\n// Sometimes a family of microbenchmarks can be implemented with\n// just one routine that takes an extra argument to specify which\n// one of the family of benchmarks to run.  For example, the following\n// code defines a family of microbenchmarks for measuring the speed\n// of memcpy() calls of different lengths:\n\nstatic void BM_memcpy(benchmark::State& state) {\n  char* src = new char[state.range(0)]; char* dst = new char[state.range(0)];\n  memset(src, 'x', state.range(0));\n  for (auto _ : state)\n    memcpy(dst, src, state.range(0));\n  state.SetBytesProcessed(state.iterations() * state.range(0));\n  delete[] src; delete[] dst;\n}\nBENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);\n\n// The preceding code is quite repetitive, and can be replaced with the\n// following short-hand.  The following invocation will pick a few\n// appropriate arguments in the specified range and will generate a\n// microbenchmark for each such argument.\nBENCHMARK(BM_memcpy)->Range(8, 8<<10);\n\n// You might have a microbenchmark that depends on two inputs.  For\n// example, the following code defines a family of microbenchmarks for\n// measuring the speed of set insertion.\nstatic void BM_SetInsert(benchmark::State& state) {\n  set<int> data;\n  for (auto _ : state) {\n    state.PauseTiming();\n    data = ConstructRandomSet(state.range(0));\n    state.ResumeTiming();\n    for (int j = 0; j < state.range(1); ++j)\n      data.insert(RandomNumber());\n  }\n}\nBENCHMARK(BM_SetInsert)\n   ->Args({1<<10, 128})\n   ->Args({2<<10, 128})\n   ->Args({4<<10, 128})\n   ->Args({8<<10, 128})\n   ->Args({1<<10, 512})\n   ->Args({2<<10, 512})\n   ->Args({4<<10, 512})\n   ->Args({8<<10, 512});\n\n// The preceding code is quite repetitive, and can be replaced with\n// the following short-hand.  The following macro will pick a few\n// appropriate arguments in the product of the two specified ranges\n// and will generate a microbenchmark for each such pair.\nBENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});\n\n// For more complex patterns of inputs, passing a custom function\n// to Apply allows programmatic specification of an\n// arbitrary set of arguments to run the microbenchmark on.\n// The following example enumerates a dense range on\n// one parameter, and a sparse range on the second.\nstatic void CustomArguments(benchmark::internal::Benchmark* b) {\n  for (int i = 0; i <= 10; ++i)\n    for (int j = 32; j <= 1024*1024; j *= 8)\n      b->Args({i, j});\n}\nBENCHMARK(BM_SetInsert)->Apply(CustomArguments);\n\n// Templated microbenchmarks work the same way:\n// Produce then consume 'size' messages 'iters' times\n// Measures throughput in the absence of multiprogramming.\ntemplate <class Q> int BM_Sequential(benchmark::State& state) {\n  Q q;\n  typename Q::value_type v;\n  for (auto _ : state) {\n    for (int i = state.range(0); i--; )\n      q.push(v);\n    for (int e = state.range(0); e--; )\n      q.Wait(&v);\n  }\n  // actually messages, not bytes:\n  state.SetBytesProcessed(state.iterations() * state.range(0));\n}\nBENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);\n\nUse `Benchmark::MinTime(double t)` to set the minimum time used to run the\nbenchmark. This option overrides the `benchmark_min_time` flag.\n\nvoid BM_test(benchmark::State& state) {\n ... body ...\n}\nBENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.\n\nIn a multithreaded test, it is guaranteed that none of the threads will start\nuntil all have reached the loop start, and all will have finished before any\nthread exits the loop body. As such, any global setup or teardown you want to\ndo can be wrapped in a check against the thread index:\n\nstatic void BM_MultiThreaded(benchmark::State& state) {\n  if (state.thread_index() == 0) {\n    // Setup code here.\n  }\n  for (auto _ : state) {\n    // Run the test as normal.\n  }\n  if (state.thread_index() == 0) {\n    // Teardown code here.\n  }\n}\nBENCHMARK(BM_MultiThreaded)->Threads(4);\n\n\nIf a benchmark runs a few milliseconds it may be hard to visually compare the\nmeasured times, since the output data is given in nanoseconds per default. In\norder to manually set the time unit, you can specify it manually:\n\nBENCHMARK(BM_test)->Unit(benchmark::kMillisecond);\n*/\n\n#ifndef BENCHMARK_BENCHMARK_H_\n#define BENCHMARK_BENCHMARK_H_\n\n// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.\n#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)\n#define BENCHMARK_HAS_CXX11\n#endif\n\n// This _MSC_VER check should detect VS 2017 v15.3 and newer.\n#if __cplusplus >= 201703L || \\\n    (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)\n#define BENCHMARK_HAS_CXX17\n#endif\n\n#include <stdint.h>\n\n#include <algorithm>\n#include <cassert>\n#include <cstddef>\n#include <iosfwd>\n#include <limits>\n#include <map>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"benchmark/export.h\"\n\n#if defined(BENCHMARK_HAS_CXX11)\n#include <atomic>\n#include <initializer_list>\n#include <type_traits>\n#include <utility>\n#endif\n\n#if defined(_MSC_VER)\n#include <intrin.h>  // for _ReadWriteBarrier\n#endif\n\n#ifndef BENCHMARK_HAS_CXX11\n#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&);                         \\\n  TypeName& operator=(const TypeName&)\n#else\n#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \\\n  TypeName(const TypeName&) = delete;                \\\n  TypeName& operator=(const TypeName&) = delete\n#endif\n\n#ifdef BENCHMARK_HAS_CXX17\n#define BENCHMARK_UNUSED [[maybe_unused]]\n#elif defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_UNUSED __attribute__((unused))\n#else\n#define BENCHMARK_UNUSED\n#endif\n\n// Used to annotate functions, methods and classes so they\n// are not optimized by the compiler. Useful for tests\n// where you expect loops to stay in place churning cycles\n#if defined(__clang__)\n#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))\n#elif defined(__GNUC__) || defined(__GNUG__)\n#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))\n#else\n// MSVC & Intel do not have a no-optimize attribute, only line pragmas\n#define BENCHMARK_DONT_OPTIMIZE\n#endif\n\n#if defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))\n#elif defined(_MSC_VER) && !defined(__clang__)\n#define BENCHMARK_ALWAYS_INLINE __forceinline\n#define __func__ __FUNCTION__\n#else\n#define BENCHMARK_ALWAYS_INLINE\n#endif\n\n#define BENCHMARK_INTERNAL_TOSTRING2(x) #x\n#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)\n\n// clang-format off\n#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)\n#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)\n#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING \\\n  _Pragma(\"GCC diagnostic push\")             \\\n  _Pragma(\"GCC diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma(\"GCC diagnostic pop\")\n#elif defined(__NVCOMPILER)\n#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)\n#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING \\\n  _Pragma(\"diagnostic push\") \\\n  _Pragma(\"diag_suppress deprecated_entity_with_custom_message\")\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma(\"diagnostic pop\")\n#else\n#define BENCHMARK_BUILTIN_EXPECT(x, y) x\n#define BENCHMARK_DEPRECATED_MSG(msg)\n#define BENCHMARK_WARNING_MSG(msg)                           \\\n  __pragma(message(__FILE__ \"(\" BENCHMARK_INTERNAL_TOSTRING( \\\n      __LINE__) \") : warning note: \" msg))\n#define BENCHMARK_DISABLE_DEPRECATED_WARNING\n#define BENCHMARK_RESTORE_DEPRECATED_WARNING\n#endif\n// clang-format on\n\n#if defined(__GNUC__) && !defined(__clang__)\n#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n#endif\n\n#ifndef __has_builtin\n#define __has_builtin(x) 0\n#endif\n\n#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)\n#define BENCHMARK_UNREACHABLE() __builtin_unreachable()\n#elif defined(_MSC_VER)\n#define BENCHMARK_UNREACHABLE() __assume(false)\n#else\n#define BENCHMARK_UNREACHABLE() ((void)0)\n#endif\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_OVERRIDE override\n#else\n#define BENCHMARK_OVERRIDE\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n// C4251: <symbol> needs to have dll-interface to be used by clients of class\n#pragma warning(disable : 4251)\n#endif\n\nnamespace benchmark {\nclass BenchmarkReporter;\n\n// Default number of minimum benchmark running time in seconds.\nconst char kDefaultMinTimeStr[] = \"0.5s\";\n\n// Returns the version of the library.\nBENCHMARK_EXPORT std::string GetBenchmarkVersion();\n\nBENCHMARK_EXPORT void PrintDefaultHelp();\n\nBENCHMARK_EXPORT void Initialize(int* argc, char** argv,\n                                 void (*HelperPrinterf)() = PrintDefaultHelp);\nBENCHMARK_EXPORT void Shutdown();\n\n// Report to stdout all arguments in 'argv' as unrecognized except the first.\n// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).\nBENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);\n\n// Returns the current value of --benchmark_filter.\nBENCHMARK_EXPORT std::string GetBenchmarkFilter();\n\n// Sets a new value to --benchmark_filter. (This will override this flag's\n// current value).\n// Should be called after `benchmark::Initialize()`, as\n// `benchmark::Initialize()` will override the flag's value.\nBENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);\n\n// Returns the current value of --v (command line value for verbosity).\nBENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();\n\n// Creates a default display reporter. Used by the library when no display\n// reporter is provided, but also made available for external use in case a\n// custom reporter should respect the `--benchmark_format` flag as a fallback\nBENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();\n\n// Generate a list of benchmarks matching the specified --benchmark_filter flag\n// and if --benchmark_list_tests is specified return after printing the name\n// of each matching benchmark. Otherwise run each matching benchmark and\n// report the results.\n//\n// spec : Specify the benchmarks to run. If users do not specify this arg,\n//        then the value of FLAGS_benchmark_filter\n//        will be used.\n//\n// The second and third overload use the specified 'display_reporter' and\n//  'file_reporter' respectively. 'file_reporter' will write to the file\n//  specified\n//   by '--benchmark_out'. If '--benchmark_out' is not given the\n//  'file_reporter' is ignored.\n//\n// RETURNS: The number of matching benchmarks.\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);\n\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);\n\nBENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(\n    BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);\nBENCHMARK_EXPORT size_t\nRunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                       BenchmarkReporter* file_reporter, std::string spec);\n\n// TimeUnit is passed to a benchmark in order to specify the order of magnitude\n// for the measured time.\nenum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };\n\nBENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();\n\n// Sets the default time unit the benchmarks use\n// Has to be called before the benchmark loop to take effect\nBENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);\n\n// If a MemoryManager is registered (via RegisterMemoryManager()),\n// it can be used to collect and report allocation metrics for a run of the\n// benchmark.\nclass MemoryManager {\n public:\n  static const int64_t TombstoneValue;\n\n  struct Result {\n    Result()\n        : num_allocs(0),\n          max_bytes_used(0),\n          total_allocated_bytes(TombstoneValue),\n          net_heap_growth(TombstoneValue) {}\n\n    // The number of allocations made in total between Start and Stop.\n    int64_t num_allocs;\n\n    // The peak memory use between Start and Stop.\n    int64_t max_bytes_used;\n\n    // The total memory allocated, in bytes, between Start and Stop.\n    // Init'ed to TombstoneValue if metric not available.\n    int64_t total_allocated_bytes;\n\n    // The net changes in memory, in bytes, between Start and Stop.\n    // ie., total_allocated_bytes - total_deallocated_bytes.\n    // Init'ed to TombstoneValue if metric not available.\n    int64_t net_heap_growth;\n  };\n\n  virtual ~MemoryManager() {}\n\n  // Implement this to start recording allocation information.\n  virtual void Start() = 0;\n\n  // Implement this to stop recording and fill out the given Result structure.\n  virtual void Stop(Result& result) = 0;\n};\n\n// Register a MemoryManager instance that will be used to collect and report\n// allocation measurements for benchmark runs.\nBENCHMARK_EXPORT\nvoid RegisterMemoryManager(MemoryManager* memory_manager);\n\n// If a ProfilerManager is registered (via RegisterProfilerManager()), the\n// benchmark will be run an additional time under the profiler to collect and\n// report profile metrics for the run of the benchmark.\nclass ProfilerManager {\n public:\n  virtual ~ProfilerManager() {}\n\n  // This is called after `Setup()` code and right before the benchmark is run.\n  virtual void AfterSetupStart() = 0;\n\n  // This is called before `Teardown()` code and right after the benchmark\n  // completes.\n  virtual void BeforeTeardownStop() = 0;\n};\n\n// Register a ProfilerManager instance that will be used to collect and report\n// profile measurements for benchmark runs.\nBENCHMARK_EXPORT\nvoid RegisterProfilerManager(ProfilerManager* profiler_manager);\n\n// Add a key-value pair to output as part of the context stanza in the report.\nBENCHMARK_EXPORT\nvoid AddCustomContext(const std::string& key, const std::string& value);\n\nnamespace internal {\nclass Benchmark;\nclass BenchmarkImp;\nclass BenchmarkFamilies;\n\nBENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();\n\nBENCHMARK_EXPORT\nvoid UseCharPointer(char const volatile*);\n\n// Take ownership of the pointer and register the benchmark. Return the\n// registered benchmark.\nBENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);\n\n// Ensure that the standard streams are properly initialized in every TU.\nBENCHMARK_EXPORT int InitializeStreams();\nBENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();\n\n}  // namespace internal\n\n#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \\\n    defined(__EMSCRIPTEN__)\n#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY\n#endif\n\n// Force the compiler to flush pending writes to global memory. Acts as an\n// effective read/write barrier\n#ifdef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {\n  std::atomic_signal_fence(std::memory_order_acq_rel);\n}\n#endif\n\n// The DoNotOptimize(...) function can be used to prevent a value or\n// expression from being optimized away by the compiler. This function is\n// intended to add little to no overhead.\n// See: https://youtu.be/nXaxk27zwlk?t=2441\n#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY\n#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"r,m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n#if defined(__clang__)\n  asm volatile(\"\" : \"+r,m\"(value) : : \"memory\");\n#else\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n#endif\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n#if defined(__clang__)\n  asm volatile(\"\" : \"+r,m\"(value) : : \"memory\");\n#else\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n#endif\n}\n#endif\n#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)\n// Workaround for a bug with full argument copy overhead with GCC.\n// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"r,m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&\n                            (sizeof(Tp) <= sizeof(Tp*))>::type\n    DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m,r\"(value) : : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE\n    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||\n                            (sizeof(Tp) > sizeof(Tp*))>::type\n    DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\n#else\n// Fallback for GCC < 5. Can add some overhead because the compiler is forced\n// to use memory operations instead of operations with registers.\n// TODO: Remove if GCC < 5 will be unsupported.\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  asm volatile(\"\" : : \"m\"(value) : \"memory\");\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n  asm volatile(\"\" : \"+m\"(value) : : \"memory\");\n}\n#endif\n#endif\n\n#ifndef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {\n  asm volatile(\"\" : : : \"memory\");\n}\n#endif\n#elif defined(_MSC_VER)\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n  _ReadWriteBarrier();\n}\n\n#ifndef BENCHMARK_HAS_CXX11\ninline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }\n#endif\n#else\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n#else\ntemplate <class Tp>\nBENCHMARK_DEPRECATED_MSG(\n    \"The const-ref version of this method can permit \"\n    \"undesired compiler optimizations in benchmarks\")\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n\ntemplate <class Tp>\ninline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {\n  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));\n}\n#endif\n// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11.\n#endif\n\n// This class is used for user-defined counters.\nclass Counter {\n public:\n  enum Flags {\n    kDefaults = 0,\n    // Mark the counter as a rate. It will be presented divided\n    // by the duration of the benchmark.\n    kIsRate = 1 << 0,\n    // Mark the counter as a thread-average quantity. It will be\n    // presented divided by the number of threads.\n    kAvgThreads = 1 << 1,\n    // Mark the counter as a thread-average rate. See above.\n    kAvgThreadsRate = kIsRate | kAvgThreads,\n    // Mark the counter as a constant value, valid/same for *every* iteration.\n    // When reporting, it will be *multiplied* by the iteration count.\n    kIsIterationInvariant = 1 << 2,\n    // Mark the counter as a constant rate.\n    // When reporting, it will be *multiplied* by the iteration count\n    // and then divided by the duration of the benchmark.\n    kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,\n    // Mark the counter as a iteration-average quantity.\n    // It will be presented divided by the number of iterations.\n    kAvgIterations = 1 << 3,\n    // Mark the counter as a iteration-average rate. See above.\n    kAvgIterationsRate = kIsRate | kAvgIterations,\n\n    // In the end, invert the result. This is always done last!\n    kInvert = 1 << 31\n  };\n\n  enum OneK {\n    // 1'000 items per 1k\n    kIs1000 = 1000,\n    // 1'024 items per 1k\n    kIs1024 = 1024\n  };\n\n  double value;\n  Flags flags;\n  OneK oneK;\n\n  BENCHMARK_ALWAYS_INLINE\n  Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)\n      : value(v), flags(f), oneK(k) {}\n\n  BENCHMARK_ALWAYS_INLINE operator double const &() const { return value; }\n  BENCHMARK_ALWAYS_INLINE operator double&() { return value; }\n};\n\n// A helper for user code to create unforeseen combinations of Flags, without\n// having to do this cast manually each time, or providing this operator.\nCounter::Flags inline operator|(const Counter::Flags& LHS,\n                                const Counter::Flags& RHS) {\n  return static_cast<Counter::Flags>(static_cast<int>(LHS) |\n                                     static_cast<int>(RHS));\n}\n\n// This is the container for the user-defined counters.\ntypedef std::map<std::string, Counter> UserCounters;\n\n// BigO is passed to a benchmark in order to specify the asymptotic\n// computational\n// complexity for the benchmark. In case oAuto is selected, complexity will be\n// calculated automatically to the best fit.\nenum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };\n\ntypedef int64_t ComplexityN;\n\ntypedef int64_t IterationCount;\n\nenum StatisticUnit { kTime, kPercentage };\n\n// BigOFunc is passed to a benchmark in order to specify the asymptotic\n// computational complexity for the benchmark.\ntypedef double(BigOFunc)(ComplexityN);\n\n// StatisticsFunc is passed to a benchmark in order to compute some descriptive\n// statistics over all the measurements of some type\ntypedef double(StatisticsFunc)(const std::vector<double>&);\n\nnamespace internal {\nstruct Statistics {\n  std::string name_;\n  StatisticsFunc* compute_;\n  StatisticUnit unit_;\n\n  Statistics(const std::string& name, StatisticsFunc* compute,\n             StatisticUnit unit = kTime)\n      : name_(name), compute_(compute), unit_(unit) {}\n};\n\nclass BenchmarkInstance;\nclass ThreadTimer;\nclass ThreadManager;\nclass PerfCountersMeasurement;\n\nenum AggregationReportMode\n#if defined(BENCHMARK_HAS_CXX11)\n    : unsigned\n#else\n#endif\n{\n  // The mode has not been manually specified\n  ARM_Unspecified = 0,\n  // The mode is user-specified.\n  // This may or may not be set when the following bit-flags are set.\n  ARM_Default = 1U << 0U,\n  // File reporter should only output aggregates.\n  ARM_FileReportAggregatesOnly = 1U << 1U,\n  // Display reporter should only output aggregates\n  ARM_DisplayReportAggregatesOnly = 1U << 2U,\n  // Both reporters should only display aggregates.\n  ARM_ReportAggregatesOnly =\n      ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly\n};\n\nenum Skipped\n#if defined(BENCHMARK_HAS_CXX11)\n    : unsigned\n#endif\n{\n  NotSkipped = 0,\n  SkippedWithMessage,\n  SkippedWithError\n};\n\n}  // namespace internal\n\n// State is passed to a running Benchmark and contains state for the\n// benchmark to use.\nclass BENCHMARK_EXPORT State {\n public:\n  struct StateIterator;\n  friend struct StateIterator;\n\n  // Returns iterators used to run each iteration of a benchmark using a\n  // C++11 ranged-based for loop. These functions should not be called directly.\n  //\n  // REQUIRES: The benchmark has not started running yet. Neither begin nor end\n  // have been called previously.\n  //\n  // NOTE: KeepRunning may not be used after calling either of these functions.\n  inline BENCHMARK_ALWAYS_INLINE StateIterator begin();\n  inline BENCHMARK_ALWAYS_INLINE StateIterator end();\n\n  // Returns true if the benchmark should continue through another iteration.\n  // NOTE: A benchmark may not return from the test until KeepRunning() has\n  // returned false.\n  inline bool KeepRunning();\n\n  // Returns true iff the benchmark should run n more iterations.\n  // REQUIRES: 'n' > 0.\n  // NOTE: A benchmark must not return from the test until KeepRunningBatch()\n  // has returned false.\n  // NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.\n  //\n  // Intended usage:\n  //   while (state.KeepRunningBatch(1000)) {\n  //     // process 1000 elements\n  //   }\n  inline bool KeepRunningBatch(IterationCount n);\n\n  // REQUIRES: timer is running and 'SkipWithMessage(...)' or\n  //   'SkipWithError(...)' has not been called by the current thread.\n  // Stop the benchmark timer.  If not called, the timer will be\n  // automatically stopped after the last iteration of the benchmark loop.\n  //\n  // For threaded benchmarks the PauseTiming() function only pauses the timing\n  // for the current thread.\n  //\n  // NOTE: The \"real time\" measurement is per-thread. If different threads\n  // report different measurements the largest one is reported.\n  //\n  // NOTE: PauseTiming()/ResumeTiming() are relatively\n  // heavyweight, and so their use should generally be avoided\n  // within each benchmark iteration, if possible.\n  void PauseTiming();\n\n  // REQUIRES: timer is not running and 'SkipWithMessage(...)' or\n  //   'SkipWithError(...)' has not been called by the current thread.\n  // Start the benchmark timer.  The timer is NOT running on entrance to the\n  // benchmark function. It begins running after control flow enters the\n  // benchmark loop.\n  //\n  // NOTE: PauseTiming()/ResumeTiming() are relatively\n  // heavyweight, and so their use should generally be avoided\n  // within each benchmark iteration, if possible.\n  void ResumeTiming();\n\n  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been\n  //            called previously by the current thread.\n  // Report the benchmark as resulting in being skipped with the specified\n  // 'msg'.\n  // After this call the user may explicitly 'return' from the benchmark.\n  //\n  // If the ranged-for style of benchmark loop is used, the user must explicitly\n  // break from the loop, otherwise all future iterations will be run.\n  // If the 'KeepRunning()' loop is used the current thread will automatically\n  // exit the loop at the end of the current iteration.\n  //\n  // For threaded benchmarks only the current thread stops executing and future\n  // calls to `KeepRunning()` will block until all threads have completed\n  // the `KeepRunning()` loop. If multiple threads report being skipped only the\n  // first skip message is used.\n  //\n  // NOTE: Calling 'SkipWithMessage(...)' does not cause the benchmark to exit\n  // the current scope immediately. If the function is called from within\n  // the 'KeepRunning()' loop the current iteration will finish. It is the users\n  // responsibility to exit the scope as needed.\n  void SkipWithMessage(const std::string& msg);\n\n  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been\n  //            called previously by the current thread.\n  // Report the benchmark as resulting in an error with the specified 'msg'.\n  // After this call the user may explicitly 'return' from the benchmark.\n  //\n  // If the ranged-for style of benchmark loop is used, the user must explicitly\n  // break from the loop, otherwise all future iterations will be run.\n  // If the 'KeepRunning()' loop is used the current thread will automatically\n  // exit the loop at the end of the current iteration.\n  //\n  // For threaded benchmarks only the current thread stops executing and future\n  // calls to `KeepRunning()` will block until all threads have completed\n  // the `KeepRunning()` loop. If multiple threads report an error only the\n  // first error message is used.\n  //\n  // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit\n  // the current scope immediately. If the function is called from within\n  // the 'KeepRunning()' loop the current iteration will finish. It is the users\n  // responsibility to exit the scope as needed.\n  void SkipWithError(const std::string& msg);\n\n  // Returns true if 'SkipWithMessage(...)' or 'SkipWithError(...)' was called.\n  bool skipped() const { return internal::NotSkipped != skipped_; }\n\n  // Returns true if an error has been reported with 'SkipWithError(...)'.\n  bool error_occurred() const { return internal::SkippedWithError == skipped_; }\n\n  // REQUIRES: called exactly once per iteration of the benchmarking loop.\n  // Set the manually measured time for this benchmark iteration, which\n  // is used instead of automatically measured time if UseManualTime() was\n  // specified.\n  //\n  // For threaded benchmarks the final value will be set to the largest\n  // reported values.\n  void SetIterationTime(double seconds);\n\n  // Set the number of bytes processed by the current benchmark\n  // execution.  This routine is typically called once at the end of a\n  // throughput oriented benchmark.\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  BENCHMARK_ALWAYS_INLINE\n  void SetBytesProcessed(int64_t bytes) {\n    counters[\"bytes_per_second\"] =\n        Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  int64_t bytes_processed() const {\n    if (counters.find(\"bytes_per_second\") != counters.end())\n      return static_cast<int64_t>(counters.at(\"bytes_per_second\"));\n    return 0;\n  }\n\n  // If this routine is called with complexity_n > 0 and complexity report is\n  // requested for the\n  // family benchmark, then current benchmark will be part of the computation\n  // and complexity_n will\n  // represent the length of N.\n  BENCHMARK_ALWAYS_INLINE\n  void SetComplexityN(ComplexityN complexity_n) {\n    complexity_n_ = complexity_n;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  ComplexityN complexity_length_n() const { return complexity_n_; }\n\n  // If this routine is called with items > 0, then an items/s\n  // label is printed on the benchmark report line for the currently\n  // executing benchmark. It is typically called at the end of a processing\n  // benchmark where a processing items/second output is desired.\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  BENCHMARK_ALWAYS_INLINE\n  void SetItemsProcessed(int64_t items) {\n    counters[\"items_per_second\"] =\n        Counter(static_cast<double>(items), benchmark::Counter::kIsRate);\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  int64_t items_processed() const {\n    if (counters.find(\"items_per_second\") != counters.end())\n      return static_cast<int64_t>(counters.at(\"items_per_second\"));\n    return 0;\n  }\n\n  // If this routine is called, the specified label is printed at the\n  // end of the benchmark report line for the currently executing\n  // benchmark.  Example:\n  //  static void BM_Compress(benchmark::State& state) {\n  //    ...\n  //    double compress = input_size / output_size;\n  //    state.SetLabel(StrFormat(\"compress:%.1f%%\", 100.0*compression));\n  //  }\n  // Produces output that looks like:\n  //  BM_Compress   50         50   14115038  compress:27.3%\n  //\n  // REQUIRES: a benchmark has exited its benchmarking loop.\n  void SetLabel(const std::string& label);\n\n  // Range arguments for this run. CHECKs if the argument has been set.\n  BENCHMARK_ALWAYS_INLINE\n  int64_t range(std::size_t pos = 0) const {\n    assert(range_.size() > pos);\n    return range_[pos];\n  }\n\n  BENCHMARK_DEPRECATED_MSG(\"use 'range(0)' instead\")\n  int64_t range_x() const { return range(0); }\n\n  BENCHMARK_DEPRECATED_MSG(\"use 'range(1)' instead\")\n  int64_t range_y() const { return range(1); }\n\n  // Number of threads concurrently executing the benchmark.\n  BENCHMARK_ALWAYS_INLINE\n  int threads() const { return threads_; }\n\n  // Index of the executing thread. Values from [0, threads).\n  BENCHMARK_ALWAYS_INLINE\n  int thread_index() const { return thread_index_; }\n\n  BENCHMARK_ALWAYS_INLINE\n  IterationCount iterations() const {\n    if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {\n      return 0;\n    }\n    return max_iterations - total_iterations_ + batch_leftover_;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  std::string name() const { return name_; }\n\n private:\n  // items we expect on the first cache line (ie 64 bytes of the struct)\n  // When total_iterations_ is 0, KeepRunning() and friends will return false.\n  // May be larger than max_iterations.\n  IterationCount total_iterations_;\n\n  // When using KeepRunningBatch(), batch_leftover_ holds the number of\n  // iterations beyond max_iters that were run. Used to track\n  // completed_iterations_ accurately.\n  IterationCount batch_leftover_;\n\n public:\n  const IterationCount max_iterations;\n\n private:\n  bool started_;\n  bool finished_;\n  internal::Skipped skipped_;\n\n  // items we don't need on the first cache line\n  std::vector<int64_t> range_;\n\n  ComplexityN complexity_n_;\n\n public:\n  // Container for user-defined counters.\n  UserCounters counters;\n\n private:\n  State(std::string name, IterationCount max_iters,\n        const std::vector<int64_t>& ranges, int thread_i, int n_threads,\n        internal::ThreadTimer* timer, internal::ThreadManager* manager,\n        internal::PerfCountersMeasurement* perf_counters_measurement);\n\n  void StartKeepRunning();\n  // Implementation of KeepRunning() and KeepRunningBatch().\n  // is_batch must be true unless n is 1.\n  inline bool KeepRunningInternal(IterationCount n, bool is_batch);\n  void FinishKeepRunning();\n\n  const std::string name_;\n  const int thread_index_;\n  const int threads_;\n\n  internal::ThreadTimer* const timer_;\n  internal::ThreadManager* const manager_;\n  internal::PerfCountersMeasurement* const perf_counters_measurement_;\n\n  friend class internal::BenchmarkInstance;\n};\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {\n  return KeepRunningInternal(1, /*is_batch=*/false);\n}\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {\n  return KeepRunningInternal(n, /*is_batch=*/true);\n}\n\ninline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,\n                                                               bool is_batch) {\n  // total_iterations_ is set to 0 by the constructor, and always set to a\n  // nonzero value by StartKepRunning().\n  assert(n > 0);\n  // n must be 1 unless is_batch is true.\n  assert(is_batch || n == 1);\n  if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {\n    total_iterations_ -= n;\n    return true;\n  }\n  if (!started_) {\n    StartKeepRunning();\n    if (!skipped() && total_iterations_ >= n) {\n      total_iterations_ -= n;\n      return true;\n    }\n  }\n  // For non-batch runs, total_iterations_ must be 0 by now.\n  if (is_batch && total_iterations_ != 0) {\n    batch_leftover_ = n - total_iterations_;\n    total_iterations_ = 0;\n    return true;\n  }\n  FinishKeepRunning();\n  return false;\n}\n\nstruct State::StateIterator {\n  struct BENCHMARK_UNUSED Value {};\n  typedef std::forward_iterator_tag iterator_category;\n  typedef Value value_type;\n  typedef Value reference;\n  typedef Value pointer;\n  typedef std::ptrdiff_t difference_type;\n\n private:\n  friend class State;\n  BENCHMARK_ALWAYS_INLINE\n  StateIterator() : cached_(0), parent_() {}\n\n  BENCHMARK_ALWAYS_INLINE\n  explicit StateIterator(State* st)\n      : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}\n\n public:\n  BENCHMARK_ALWAYS_INLINE\n  Value operator*() const { return Value(); }\n\n  BENCHMARK_ALWAYS_INLINE\n  StateIterator& operator++() {\n    assert(cached_ > 0);\n    --cached_;\n    return *this;\n  }\n\n  BENCHMARK_ALWAYS_INLINE\n  bool operator!=(StateIterator const&) const {\n    if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;\n    parent_->FinishKeepRunning();\n    return false;\n  }\n\n private:\n  IterationCount cached_;\n  State* const parent_;\n};\n\ninline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {\n  return StateIterator(this);\n}\ninline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {\n  StartKeepRunning();\n  return StateIterator();\n}\n\nnamespace internal {\n\ntypedef void(Function)(State&);\n\n// ------------------------------------------------------\n// Benchmark registration object.  The BENCHMARK() macro expands\n// into an internal::Benchmark* object.  Various methods can\n// be called on this object to change the properties of the benchmark.\n// Each method returns \"this\" so that multiple method calls can\n// chained into one expression.\nclass BENCHMARK_EXPORT Benchmark {\n public:\n  virtual ~Benchmark();\n\n  // Note: the following methods all return \"this\" so that multiple\n  // method calls can be chained together in one expression.\n\n  // Specify the name of the benchmark\n  Benchmark* Name(const std::string& name);\n\n  // Run this benchmark once with \"x\" as the extra argument passed\n  // to the function.\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* Arg(int64_t x);\n\n  // Run this benchmark with the given time unit for the generated output report\n  Benchmark* Unit(TimeUnit unit);\n\n  // Run this benchmark once for a number of values picked from the\n  // range [start..limit].  (start and limit are always picked.)\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* Range(int64_t start, int64_t limit);\n\n  // Run this benchmark once for all values in the range [start..limit] with\n  // specific step\n  // REQUIRES: The function passed to the constructor must accept an arg1.\n  Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);\n\n  // Run this benchmark once with \"args\" as the extra arguments passed\n  // to the function.\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* Args(const std::vector<int64_t>& args);\n\n  // Equivalent to Args({x, y})\n  // NOTE: This is a legacy C++03 interface provided for compatibility only.\n  //   New code should use 'Args'.\n  Benchmark* ArgPair(int64_t x, int64_t y) {\n    std::vector<int64_t> args;\n    args.push_back(x);\n    args.push_back(y);\n    return Args(args);\n  }\n\n  // Run this benchmark once for a number of values picked from the\n  // ranges [start..limit].  (starts and limits are always picked.)\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t> >& ranges);\n\n  // Run this benchmark once for each combination of values in the (cartesian)\n  // product of the supplied argument lists.\n  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...\n  Benchmark* ArgsProduct(const std::vector<std::vector<int64_t> >& arglists);\n\n  // Equivalent to ArgNames({name})\n  Benchmark* ArgName(const std::string& name);\n\n  // Set the argument names to display in the benchmark name. If not called,\n  // only argument values will be shown.\n  Benchmark* ArgNames(const std::vector<std::string>& names);\n\n  // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).\n  // NOTE: This is a legacy C++03 interface provided for compatibility only.\n  //   New code should use 'Ranges'.\n  Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {\n    std::vector<std::pair<int64_t, int64_t> > ranges;\n    ranges.push_back(std::make_pair(lo1, hi1));\n    ranges.push_back(std::make_pair(lo2, hi2));\n    return Ranges(ranges);\n  }\n\n  // Have \"setup\" and/or \"teardown\" invoked once for every benchmark run.\n  // If the benchmark is multi-threaded (will run in k threads concurrently),\n  // the setup callback will be be invoked exactly once (not k times) before\n  // each run with k threads. Time allowing (e.g. for a short benchmark), there\n  // may be multiple such runs per benchmark, each run with its own\n  // \"setup\"/\"teardown\".\n  //\n  // If the benchmark uses different size groups of threads (e.g. via\n  // ThreadRange), the above will be true for each size group.\n  //\n  // The callback will be passed a State object, which includes the number\n  // of threads, thread-index, benchmark arguments, etc.\n  //\n  // The callback must not be NULL or self-deleting.\n  Benchmark* Setup(void (*setup)(const benchmark::State&));\n  Benchmark* Teardown(void (*teardown)(const benchmark::State&));\n\n  // Pass this benchmark object to *func, which can customize\n  // the benchmark by calling various methods like Arg, Args,\n  // Threads, etc.\n  Benchmark* Apply(void (*func)(Benchmark* benchmark));\n\n  // Set the range multiplier for non-dense range. If not called, the range\n  // multiplier kRangeMultiplier will be used.\n  Benchmark* RangeMultiplier(int multiplier);\n\n  // Set the minimum amount of time to use when running this benchmark. This\n  // option overrides the `benchmark_min_time` flag.\n  // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark.\n  Benchmark* MinTime(double t);\n\n  // Set the minimum amount of time to run the benchmark before taking runtimes\n  // of this benchmark into account. This\n  // option overrides the `benchmark_min_warmup_time` flag.\n  // REQUIRES: `t >= 0` and `Iterations` has not been called on this benchmark.\n  Benchmark* MinWarmUpTime(double t);\n\n  // Specify the amount of iterations that should be run by this benchmark.\n  // This option overrides the `benchmark_min_time` flag.\n  // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark.\n  //\n  // NOTE: This function should only be used when *exact* iteration control is\n  //   needed and never to control or limit how long a benchmark runs, where\n  // `--benchmark_min_time=<N>s` or `MinTime(...)` should be used instead.\n  Benchmark* Iterations(IterationCount n);\n\n  // Specify the amount of times to repeat this benchmark. This option overrides\n  // the `benchmark_repetitions` flag.\n  // REQUIRES: `n > 0`\n  Benchmark* Repetitions(int n);\n\n  // Specify if each repetition of the benchmark should be reported separately\n  // or if only the final statistics should be reported. If the benchmark\n  // is not repeated then the single result is always reported.\n  // Applies to *ALL* reporters (display and file).\n  Benchmark* ReportAggregatesOnly(bool value = true);\n\n  // Same as ReportAggregatesOnly(), but applies to display reporter only.\n  Benchmark* DisplayAggregatesOnly(bool value = true);\n\n  // By default, the CPU time is measured only for the main thread, which may\n  // be unrepresentative if the benchmark uses threads internally. If called,\n  // the total CPU time spent by all the threads will be measured instead.\n  // By default, only the main thread CPU time will be measured.\n  Benchmark* MeasureProcessCPUTime();\n\n  // If a particular benchmark should use the Wall clock instead of the CPU time\n  // (be it either the CPU time of the main thread only (default), or the\n  // total CPU usage of the benchmark), call this method. If called, the elapsed\n  // (wall) time will be used to control how many iterations are run, and in the\n  // printing of items/second or MB/seconds values.\n  // If not called, the CPU time used by the benchmark will be used.\n  Benchmark* UseRealTime();\n\n  // If a benchmark must measure time manually (e.g. if GPU execution time is\n  // being\n  // measured), call this method. If called, each benchmark iteration should\n  // call\n  // SetIterationTime(seconds) to report the measured time, which will be used\n  // to control how many iterations are run, and in the printing of items/second\n  // or MB/second values.\n  Benchmark* UseManualTime();\n\n  // Set the asymptotic computational complexity for the benchmark. If called\n  // the asymptotic computational complexity will be shown on the output.\n  Benchmark* Complexity(BigO complexity = benchmark::oAuto);\n\n  // Set the asymptotic computational complexity for the benchmark. If called\n  // the asymptotic computational complexity will be shown on the output.\n  Benchmark* Complexity(BigOFunc* complexity);\n\n  // Add this statistics to be computed over all the values of benchmark run\n  Benchmark* ComputeStatistics(const std::string& name,\n                               StatisticsFunc* statistics,\n                               StatisticUnit unit = kTime);\n\n  // Support for running multiple copies of the same benchmark concurrently\n  // in multiple threads.  This may be useful when measuring the scaling\n  // of some piece of code.\n\n  // Run one instance of this benchmark concurrently in t threads.\n  Benchmark* Threads(int t);\n\n  // Pick a set of values T from [min_threads,max_threads].\n  // min_threads and max_threads are always included in T.  Run this\n  // benchmark once for each value in T.  The benchmark run for a\n  // particular value t consists of t threads running the benchmark\n  // function concurrently.  For example, consider:\n  //    BENCHMARK(Foo)->ThreadRange(1,16);\n  // This will run the following benchmarks:\n  //    Foo in 1 thread\n  //    Foo in 2 threads\n  //    Foo in 4 threads\n  //    Foo in 8 threads\n  //    Foo in 16 threads\n  Benchmark* ThreadRange(int min_threads, int max_threads);\n\n  // For each value n in the range, run this benchmark once using n threads.\n  // min_threads and max_threads are always included in the range.\n  // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts\n  // a benchmark with 1, 4, 7 and 8 threads.\n  Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);\n\n  // Equivalent to ThreadRange(NumCPUs(), NumCPUs())\n  Benchmark* ThreadPerCpu();\n\n  virtual void Run(State& state) = 0;\n\n  TimeUnit GetTimeUnit() const;\n\n protected:\n  explicit Benchmark(const std::string& name);\n  void SetName(const std::string& name);\n\n public:\n  const char* GetName() const;\n  int ArgsCnt() const;\n  const char* GetArgName(int arg) const;\n\n private:\n  friend class BenchmarkFamilies;\n  friend class BenchmarkInstance;\n\n  std::string name_;\n  AggregationReportMode aggregation_report_mode_;\n  std::vector<std::string> arg_names_;       // Args for all benchmark runs\n  std::vector<std::vector<int64_t> > args_;  // Args for all benchmark runs\n\n  TimeUnit time_unit_;\n  bool use_default_time_unit_;\n\n  int range_multiplier_;\n  double min_time_;\n  double min_warmup_time_;\n  IterationCount iterations_;\n  int repetitions_;\n  bool measure_process_cpu_time_;\n  bool use_real_time_;\n  bool use_manual_time_;\n  BigO complexity_;\n  BigOFunc* complexity_lambda_;\n  std::vector<Statistics> statistics_;\n  std::vector<int> thread_counts_;\n\n  typedef void (*callback_function)(const benchmark::State&);\n  callback_function setup_;\n  callback_function teardown_;\n\n  Benchmark(Benchmark const&)\n#if defined(BENCHMARK_HAS_CXX11)\n      = delete\n#endif\n      ;\n\n  Benchmark& operator=(Benchmark const&)\n#if defined(BENCHMARK_HAS_CXX11)\n      = delete\n#endif\n      ;\n};\n\n}  // namespace internal\n\n// Create and register a benchmark with the specified 'name' that invokes\n// the specified functor 'fn'.\n//\n// RETURNS: A pointer to the registered benchmark.\ninternal::Benchmark* RegisterBenchmark(const std::string& name,\n                                       internal::Function* fn);\n\n#if defined(BENCHMARK_HAS_CXX11)\ntemplate <class Lambda>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);\n#endif\n\n// Remove all registered benchmarks. All pointers to previously registered\n// benchmarks are invalidated.\nBENCHMARK_EXPORT void ClearRegisteredBenchmarks();\n\nnamespace internal {\n// The class used to hold all Benchmarks created from static function.\n// (ie those created using the BENCHMARK(...) macros.\nclass BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {\n public:\n  FunctionBenchmark(const std::string& name, Function* func)\n      : Benchmark(name), func_(func) {}\n\n  void Run(State& st) BENCHMARK_OVERRIDE;\n\n private:\n  Function* func_;\n};\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Lambda>\nclass LambdaBenchmark : public Benchmark {\n public:\n  void Run(State& st) BENCHMARK_OVERRIDE { lambda_(st); }\n\n private:\n  template <class OLambda>\n  LambdaBenchmark(const std::string& name, OLambda&& lam)\n      : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}\n\n  LambdaBenchmark(LambdaBenchmark const&) = delete;\n\n  template <class Lam>  // NOLINTNEXTLINE(readability-redundant-declaration)\n  friend Benchmark* ::benchmark::RegisterBenchmark(const std::string&, Lam&&);\n\n  Lambda lambda_;\n};\n#endif\n}  // namespace internal\n\ninline internal::Benchmark* RegisterBenchmark(const std::string& name,\n                                              internal::Function* fn) {\n  // FIXME: this should be a `std::make_unique<>()` but we don't have C++14.\n  // codechecker_intentional [cplusplus.NewDeleteLeaks]\n  return internal::RegisterBenchmarkInternal(\n      ::new internal::FunctionBenchmark(name, fn));\n}\n\n#ifdef BENCHMARK_HAS_CXX11\ntemplate <class Lambda>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {\n  using BenchType =\n      internal::LambdaBenchmark<typename std::decay<Lambda>::type>;\n  // FIXME: this should be a `std::make_unique<>()` but we don't have C++14.\n  // codechecker_intentional [cplusplus.NewDeleteLeaks]\n  return internal::RegisterBenchmarkInternal(\n      ::new BenchType(name, std::forward<Lambda>(fn)));\n}\n#endif\n\n#if defined(BENCHMARK_HAS_CXX11) && \\\n    (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)\ntemplate <class Lambda, class... Args>\ninternal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,\n                                       Args&&... args) {\n  return benchmark::RegisterBenchmark(\n      name, [=](benchmark::State& st) { fn(st, args...); });\n}\n#else\n#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK\n#endif\n\n// The base class for all fixture tests.\nclass Fixture : public internal::Benchmark {\n public:\n  Fixture() : internal::Benchmark(\"\") {}\n\n  void Run(State& st) BENCHMARK_OVERRIDE {\n    this->SetUp(st);\n    this->BenchmarkCase(st);\n    this->TearDown(st);\n  }\n\n  // These will be deprecated ...\n  virtual void SetUp(const State&) {}\n  virtual void TearDown(const State&) {}\n  // ... In favor of these.\n  virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }\n  virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }\n\n protected:\n  virtual void BenchmarkCase(State&) = 0;\n};\n}  // namespace benchmark\n\n// ------------------------------------------------------\n// Macro to register benchmarks\n\n// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1\n// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be\n// empty. If X is empty the expression becomes (+1 == +0).\n#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)\n#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__\n#else\n#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__\n#endif\n\n// Helpers for generating unique variable names\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_PRIVATE_NAME(...)                                      \\\n  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \\\n                           __VA_ARGS__)\n#else\n#define BENCHMARK_PRIVATE_NAME(n) \\\n  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)\n#endif  // BENCHMARK_HAS_CXX11\n\n#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)\n#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c\n// Helper for concatenation with macro name expansion\n#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \\\n  BaseClass##_##Method##_Benchmark\n\n#define BENCHMARK_PRIVATE_DECLARE(n)                                 \\\n  static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \\\n      BENCHMARK_UNUSED\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK(...)                                               \\\n  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =                           \\\n      (::benchmark::internal::RegisterBenchmarkInternal(             \\\n          new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \\\n                                                       __VA_ARGS__)))\n#else\n#define BENCHMARK(n)                                     \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(#n, n)))\n#endif  // BENCHMARK_HAS_CXX11\n\n// Old-style macros\n#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))\n#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})\n#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))\n#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))\n#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \\\n  BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})\n\n#ifdef BENCHMARK_HAS_CXX11\n\n// Register a benchmark which invokes the function specified by `func`\n// with the additional arguments specified by `...`.\n//\n// For example:\n//\n// template <class ...ExtraArgs>`\n// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {\n//  [...]\n//}\n// /* Registers a benchmark named \"BM_takes_args/int_string_test` */\n// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string(\"abc\"));\n#define BENCHMARK_CAPTURE(func, test_case_name, ...)     \\\n  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(  \\\n              #func \"/\" #test_case_name,                 \\\n              [](::benchmark::State& st) { func(st, __VA_ARGS__); })))\n\n#endif  // BENCHMARK_HAS_CXX11\n\n// This will register a benchmark for a templatized function.  For example:\n//\n// template<int arg>\n// void BM_Foo(int iters);\n//\n// BENCHMARK_TEMPLATE(BM_Foo, 1);\n//\n// will register BM_Foo<1> as a benchmark.\n#define BENCHMARK_TEMPLATE1(n, a)                        \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(#n \"<\" #a \">\", n<a>)))\n\n#define BENCHMARK_TEMPLATE2(n, a, b)                                         \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                                             \\\n      (::benchmark::internal::RegisterBenchmarkInternal(                     \\\n          new ::benchmark::internal::FunctionBenchmark(#n \"<\" #a \",\" #b \">\", \\\n                                                       n<a, b>)))\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE(n, ...)                       \\\n  BENCHMARK_PRIVATE_DECLARE(n) =                         \\\n      (::benchmark::internal::RegisterBenchmarkInternal( \\\n          new ::benchmark::internal::FunctionBenchmark(  \\\n              #n \"<\" #__VA_ARGS__ \">\", n<__VA_ARGS__>)))\n#else\n#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)\n#endif\n\n#ifdef BENCHMARK_HAS_CXX11\n// This will register a benchmark for a templatized function,\n// with the additional arguments specified by `...`.\n//\n// For example:\n//\n// template <typename T, class ...ExtraArgs>`\n// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {\n//  [...]\n//}\n// /* Registers a benchmark named \"BM_takes_args<void>/int_string_test` */\n// BENCHMARK_TEMPLATE1_CAPTURE(BM_takes_args, void, int_string_test, 42,\n//                             std::string(\"abc\"));\n#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \\\n  BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)\n\n#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \\\n  BENCHMARK_PRIVATE_DECLARE(func) =                                  \\\n      (::benchmark::internal::RegisterBenchmarkInternal(             \\\n          new ::benchmark::internal::FunctionBenchmark(              \\\n              #func \"<\" #a \",\" #b \">\"                                \\\n                    \"/\" #test_case_name,                             \\\n              [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))\n#endif  // BENCHMARK_HAS_CXX11\n\n#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method)          \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass {   \\\n   public:                                                      \\\n    BaseClass##_##Method##_Benchmark() {                        \\\n      this->SetName(#BaseClass \"/\" #Method);                    \\\n    }                                                           \\\n                                                                \\\n   protected:                                                   \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \\\n  };\n\n#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<a> {    \\\n   public:                                                          \\\n    BaseClass##_##Method##_Benchmark() {                            \\\n      this->SetName(#BaseClass \"<\" #a \">/\" #Method);                \\\n    }                                                               \\\n                                                                    \\\n   protected:                                                       \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;     \\\n  };\n\n#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> {    \\\n   public:                                                             \\\n    BaseClass##_##Method##_Benchmark() {                               \\\n      this->SetName(#BaseClass \"<\" #a \",\" #b \">/\" #Method);            \\\n    }                                                                  \\\n                                                                       \\\n   protected:                                                          \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;        \\\n  };\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...)       \\\n  class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \\\n   public:                                                                 \\\n    BaseClass##_##Method##_Benchmark() {                                   \\\n      this->SetName(#BaseClass \"<\" #__VA_ARGS__ \">/\" #Method);             \\\n    }                                                                      \\\n                                                                           \\\n   protected:                                                              \\\n    void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE;            \\\n  };\n#else\n#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a)\n#endif\n\n#define BENCHMARK_DEFINE_F(BaseClass, Method)    \\\n  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)    \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b)    \\\n  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...)            \\\n  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n#else\n#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \\\n  BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)\n#endif\n\n#define BENCHMARK_REGISTER_F(BaseClass, Method) \\\n  BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))\n\n#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \\\n  BENCHMARK_PRIVATE_DECLARE(TestName) =        \\\n      (::benchmark::internal::RegisterBenchmarkInternal(new TestName()))\n\n// This macro will define and register a benchmark within a fixture class.\n#define BENCHMARK_F(BaseClass, Method)           \\\n  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);       \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)           \\\n  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                    \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b)           \\\n  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                       \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n\n#ifdef BENCHMARK_HAS_CXX11\n#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...)                   \\\n  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \\\n  BENCHMARK_REGISTER_F(BaseClass, Method);                             \\\n  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase\n#else\n#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \\\n  BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)\n#endif\n\n// Helper macro to create a main routine in a test that runs the benchmarks\n// Note the workaround for Hexagon simulator passing argc != 0, argv = NULL.\n#define BENCHMARK_MAIN()                                                \\\n  int main(int argc, char** argv) {                                     \\\n    char arg0_default[] = \"benchmark\";                                  \\\n    char* args_default = arg0_default;                                  \\\n    if (!argv) {                                                        \\\n      argc = 1;                                                         \\\n      argv = &args_default;                                             \\\n    }                                                                   \\\n    ::benchmark::Initialize(&argc, argv);                               \\\n    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \\\n    ::benchmark::RunSpecifiedBenchmarks();                              \\\n    ::benchmark::Shutdown();                                            \\\n    return 0;                                                           \\\n  }                                                                     \\\n  int main(int, char**)\n\n// ------------------------------------------------------\n// Benchmark Reporters\n\nnamespace benchmark {\n\nstruct BENCHMARK_EXPORT CPUInfo {\n  struct CacheInfo {\n    std::string type;\n    int level;\n    int size;\n    int num_sharing;\n  };\n\n  enum Scaling { UNKNOWN, ENABLED, DISABLED };\n\n  int num_cpus;\n  Scaling scaling;\n  double cycles_per_second;\n  std::vector<CacheInfo> caches;\n  std::vector<double> load_avg;\n\n  static const CPUInfo& Get();\n\n private:\n  CPUInfo();\n  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);\n};\n\n// Adding Struct for System Information\nstruct BENCHMARK_EXPORT SystemInfo {\n  std::string name;\n  static const SystemInfo& Get();\n\n private:\n  SystemInfo();\n  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);\n};\n\n// BenchmarkName contains the components of the Benchmark's name\n// which allows individual fields to be modified or cleared before\n// building the final name using 'str()'.\nstruct BENCHMARK_EXPORT BenchmarkName {\n  std::string function_name;\n  std::string args;\n  std::string min_time;\n  std::string min_warmup_time;\n  std::string iterations;\n  std::string repetitions;\n  std::string time_type;\n  std::string threads;\n\n  // Return the full name of the benchmark with each non-empty\n  // field separated by a '/'\n  std::string str() const;\n};\n\n// Interface for custom benchmark result printers.\n// By default, benchmark reports are printed to stdout. However an application\n// can control the destination of the reports by calling\n// RunSpecifiedBenchmarks and passing it a custom reporter object.\n// The reporter object must implement the following interface.\nclass BENCHMARK_EXPORT BenchmarkReporter {\n public:\n  struct Context {\n    CPUInfo const& cpu_info;\n    SystemInfo const& sys_info;\n    // The number of chars in the longest benchmark name.\n    size_t name_field_width;\n    static const char* executable_name;\n    Context();\n  };\n\n  struct BENCHMARK_EXPORT Run {\n    static const int64_t no_repetition_index = -1;\n    enum RunType { RT_Iteration, RT_Aggregate };\n\n    Run()\n        : run_type(RT_Iteration),\n          aggregate_unit(kTime),\n          skipped(internal::NotSkipped),\n          iterations(1),\n          threads(1),\n          time_unit(GetDefaultTimeUnit()),\n          real_accumulated_time(0),\n          cpu_accumulated_time(0),\n          max_heapbytes_used(0),\n          use_real_time_for_initial_big_o(false),\n          complexity(oNone),\n          complexity_lambda(),\n          complexity_n(0),\n          report_big_o(false),\n          report_rms(false),\n          memory_result(NULL),\n          allocs_per_iter(0.0) {}\n\n    std::string benchmark_name() const;\n    BenchmarkName run_name;\n    int64_t family_index;\n    int64_t per_family_instance_index;\n    RunType run_type;\n    std::string aggregate_name;\n    StatisticUnit aggregate_unit;\n    std::string report_label;  // Empty if not set by benchmark.\n    internal::Skipped skipped;\n    std::string skip_message;\n\n    IterationCount iterations;\n    int64_t threads;\n    int64_t repetition_index;\n    int64_t repetitions;\n    TimeUnit time_unit;\n    double real_accumulated_time;\n    double cpu_accumulated_time;\n\n    // Return a value representing the real time per iteration in the unit\n    // specified by 'time_unit'.\n    // NOTE: If 'iterations' is zero the returned value represents the\n    // accumulated time.\n    double GetAdjustedRealTime() const;\n\n    // Return a value representing the cpu time per iteration in the unit\n    // specified by 'time_unit'.\n    // NOTE: If 'iterations' is zero the returned value represents the\n    // accumulated time.\n    double GetAdjustedCPUTime() const;\n\n    // This is set to 0.0 if memory tracing is not enabled.\n    double max_heapbytes_used;\n\n    // By default Big-O is computed for CPU time, but that is not what you want\n    // to happen when manual time was requested, which is stored as real time.\n    bool use_real_time_for_initial_big_o;\n\n    // Keep track of arguments to compute asymptotic complexity\n    BigO complexity;\n    BigOFunc* complexity_lambda;\n    ComplexityN complexity_n;\n\n    // what statistics to compute from the measurements\n    const std::vector<internal::Statistics>* statistics;\n\n    // Inform print function whether the current run is a complexity report\n    bool report_big_o;\n    bool report_rms;\n\n    UserCounters counters;\n\n    // Memory metrics.\n    const MemoryManager::Result* memory_result;\n    double allocs_per_iter;\n  };\n\n  struct PerFamilyRunReports {\n    PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}\n\n    // How many runs will all instances of this benchmark perform?\n    int num_runs_total;\n\n    // How many runs have happened already?\n    int num_runs_done;\n\n    // The reports about (non-errneous!) runs of this family.\n    std::vector<BenchmarkReporter::Run> Runs;\n  };\n\n  // Construct a BenchmarkReporter with the output stream set to 'std::cout'\n  // and the error stream set to 'std::cerr'\n  BenchmarkReporter();\n\n  // Called once for every suite of benchmarks run.\n  // The parameter \"context\" contains information that the\n  // reporter may wish to use when generating its report, for example the\n  // platform under which the benchmarks are running. The benchmark run is\n  // never started if this function returns false, allowing the reporter\n  // to skip runs based on the context information.\n  virtual bool ReportContext(const Context& context) = 0;\n\n  // Called once for each group of benchmark runs, gives information about\n  // the configurations of the runs.\n  virtual void ReportRunsConfig(double /*min_time*/,\n                                bool /*has_explicit_iters*/,\n                                IterationCount /*iters*/) {}\n\n  // Called once for each group of benchmark runs, gives information about\n  // cpu-time and heap memory usage during the benchmark run. If the group\n  // of runs contained more than two entries then 'report' contains additional\n  // elements representing the mean and standard deviation of those runs.\n  // Additionally if this group of runs was the last in a family of benchmarks\n  // 'reports' contains additional entries representing the asymptotic\n  // complexity and RMS of that benchmark family.\n  virtual void ReportRuns(const std::vector<Run>& report) = 0;\n\n  // Called once and only once after ever group of benchmarks is run and\n  // reported.\n  virtual void Finalize() {}\n\n  // REQUIRES: The object referenced by 'out' is valid for the lifetime\n  // of the reporter.\n  void SetOutputStream(std::ostream* out) {\n    assert(out);\n    output_stream_ = out;\n  }\n\n  // REQUIRES: The object referenced by 'err' is valid for the lifetime\n  // of the reporter.\n  void SetErrorStream(std::ostream* err) {\n    assert(err);\n    error_stream_ = err;\n  }\n\n  std::ostream& GetOutputStream() const { return *output_stream_; }\n\n  std::ostream& GetErrorStream() const { return *error_stream_; }\n\n  virtual ~BenchmarkReporter();\n\n  // Write a human readable string to 'out' representing the specified\n  // 'context'.\n  // REQUIRES: 'out' is non-null.\n  static void PrintBasicContext(std::ostream* out, Context const& context);\n\n private:\n  std::ostream* output_stream_;\n  std::ostream* error_stream_;\n};\n\n// Simple reporter that outputs benchmark data to the console. This is the\n// default reporter used by RunSpecifiedBenchmarks().\nclass BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {\n public:\n  enum OutputOptions {\n    OO_None = 0,\n    OO_Color = 1,\n    OO_Tabular = 2,\n    OO_ColorTabular = OO_Color | OO_Tabular,\n    OO_Defaults = OO_ColorTabular\n  };\n  explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)\n      : output_options_(opts_), name_field_width_(0), printed_header_(false) {}\n\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n\n protected:\n  virtual void PrintRunData(const Run& report);\n  virtual void PrintHeader(const Run& report);\n\n  OutputOptions output_options_;\n  size_t name_field_width_;\n  UserCounters prev_counters_;\n  bool printed_header_;\n};\n\nclass BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {\n public:\n  JSONReporter() : first_report_(true) {}\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n  void Finalize() BENCHMARK_OVERRIDE;\n\n private:\n  void PrintRunData(const Run& report);\n\n  bool first_report_;\n};\n\nclass BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(\n    \"The CSV Reporter will be removed in a future release\") CSVReporter\n    : public BenchmarkReporter {\n public:\n  CSVReporter() : printed_header_(false) {}\n  bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;\n  void ReportRuns(const std::vector<Run>& reports) BENCHMARK_OVERRIDE;\n\n private:\n  void PrintRunData(const Run& report);\n\n  bool printed_header_;\n  std::set<std::string> user_counter_names_;\n};\n\ninline const char* GetTimeUnitString(TimeUnit unit) {\n  switch (unit) {\n    case kSecond:\n      return \"s\";\n    case kMillisecond:\n      return \"ms\";\n    case kMicrosecond:\n      return \"us\";\n    case kNanosecond:\n      return \"ns\";\n  }\n  BENCHMARK_UNREACHABLE();\n}\n\ninline double GetTimeUnitMultiplier(TimeUnit unit) {\n  switch (unit) {\n    case kSecond:\n      return 1;\n    case kMillisecond:\n      return 1e3;\n    case kMicrosecond:\n      return 1e6;\n    case kNanosecond:\n      return 1e9;\n  }\n  BENCHMARK_UNREACHABLE();\n}\n\n// Creates a list of integer values for the given range and multiplier.\n// This can be used together with ArgsProduct() to allow multiple ranges\n// with different multipliers.\n// Example:\n// ArgsProduct({\n//   CreateRange(0, 1024, /*multi=*/32),\n//   CreateRange(0, 100, /*multi=*/4),\n//   CreateDenseRange(0, 4, /*step=*/1),\n// });\nBENCHMARK_EXPORT\nstd::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);\n\n// Creates a list of integer values for the given range and step.\nBENCHMARK_EXPORT\nstd::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);\n\n}  // namespace benchmark\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#endif  // BENCHMARK_BENCHMARK_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/include/benchmark/export.h",
    "content": "#ifndef BENCHMARK_EXPORT_H\n#define BENCHMARK_EXPORT_H\n\n#if defined(_WIN32)\n#define EXPORT_ATTR __declspec(dllexport)\n#define IMPORT_ATTR __declspec(dllimport)\n#define NO_EXPORT_ATTR\n#define DEPRECATED_ATTR __declspec(deprecated)\n#else  // _WIN32\n#define EXPORT_ATTR __attribute__((visibility(\"default\")))\n#define IMPORT_ATTR __attribute__((visibility(\"default\")))\n#define NO_EXPORT_ATTR __attribute__((visibility(\"hidden\")))\n#define DEPRECATE_ATTR __attribute__((__deprecated__))\n#endif  // _WIN32\n\n#ifdef BENCHMARK_STATIC_DEFINE\n#define BENCHMARK_EXPORT\n#define BENCHMARK_NO_EXPORT\n#else  // BENCHMARK_STATIC_DEFINE\n#ifndef BENCHMARK_EXPORT\n#ifdef benchmark_EXPORTS\n/* We are building this library */\n#define BENCHMARK_EXPORT EXPORT_ATTR\n#else  // benchmark_EXPORTS\n/* We are using this library */\n#define BENCHMARK_EXPORT IMPORT_ATTR\n#endif  // benchmark_EXPORTS\n#endif  // !BENCHMARK_EXPORT\n\n#ifndef BENCHMARK_NO_EXPORT\n#define BENCHMARK_NO_EXPORT NO_EXPORT_ATTR\n#endif  // !BENCHMARK_NO_EXPORT\n#endif  // BENCHMARK_STATIC_DEFINE\n\n#ifndef BENCHMARK_DEPRECATED\n#define BENCHMARK_DEPRECATED DEPRECATE_ATTR\n#endif  // BENCHMARK_DEPRECATED\n\n#ifndef BENCHMARK_DEPRECATED_EXPORT\n#define BENCHMARK_DEPRECATED_EXPORT BENCHMARK_EXPORT BENCHMARK_DEPRECATED\n#endif  // BENCHMARK_DEPRECATED_EXPORT\n\n#ifndef BENCHMARK_DEPRECATED_NO_EXPORT\n#define BENCHMARK_DEPRECATED_NO_EXPORT BENCHMARK_NO_EXPORT BENCHMARK_DEPRECATED\n#endif  // BENCHMARK_DEPRECATED_EXPORT\n\n#endif /* BENCHMARK_EXPORT_H */\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/CMakeLists.txt",
    "content": "#Allow the source files to find headers in src /\ninclude(GNUInstallDirs)\ninclude_directories(${PROJECT_SOURCE_DIR}/src)\n\nif (DEFINED BENCHMARK_CXX_LINKER_FLAGS)\n  list(APPEND CMAKE_SHARED_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\n  list(APPEND CMAKE_MODULE_LINKER_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})\nendif()\n\nfile(GLOB\n  SOURCE_FILES\n    *.cc\n    ${PROJECT_SOURCE_DIR}/include/benchmark/*.h\n    ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\nfile(GLOB BENCHMARK_MAIN \"benchmark_main.cc\")\nforeach(item ${BENCHMARK_MAIN})\n  list(REMOVE_ITEM SOURCE_FILES \"${item}\")\nendforeach()\n\nadd_library(benchmark ${SOURCE_FILES})\nadd_library(benchmark::benchmark ALIAS benchmark)\nset_target_properties(benchmark PROPERTIES\n  OUTPUT_NAME \"benchmark\"\n  VERSION ${GENERIC_LIB_VERSION}\n  SOVERSION ${GENERIC_LIB_SOVERSION}\n)\ntarget_include_directories(benchmark PUBLIC\n  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>\n)\n\nset_property(\n  SOURCE benchmark.cc\n  APPEND\n  PROPERTY COMPILE_DEFINITIONS\n  BENCHMARK_VERSION=\"${VERSION}\"\n)\n\n# libpfm, if available\nif (PFM_FOUND)\n  target_link_libraries(benchmark PRIVATE PFM::libpfm)\n  target_compile_definitions(benchmark PRIVATE -DHAVE_LIBPFM)\nendif()\n\n# pthread affinity, if available\nif(HAVE_PTHREAD_AFFINITY)\n  target_compile_definitions(benchmark PRIVATE -DBENCHMARK_HAS_PTHREAD_AFFINITY)\nendif()\n\n# Link threads.\ntarget_link_libraries(benchmark PRIVATE Threads::Threads)\n\ntarget_link_libraries(benchmark PRIVATE ${BENCHMARK_CXX_LIBRARIES})\n\nif(HAVE_LIB_RT)\n  target_link_libraries(benchmark PRIVATE rt)\nendif(HAVE_LIB_RT)\n\n\n# We need extra libraries on Windows\nif(${CMAKE_SYSTEM_NAME} MATCHES \"Windows\")\n  target_link_libraries(benchmark PRIVATE shlwapi)\nendif()\n\n# We need extra libraries on Solaris\nif(${CMAKE_SYSTEM_NAME} MATCHES \"SunOS\")\n  target_link_libraries(benchmark PRIVATE kstat)\n  set(BENCHMARK_PRIVATE_LINK_LIBRARIES -lkstat)\nendif()\n\nif (NOT BUILD_SHARED_LIBS)\n  target_compile_definitions(benchmark PUBLIC -DBENCHMARK_STATIC_DEFINE)\nendif()\n\n# Benchmark main library\nadd_library(benchmark_main \"benchmark_main.cc\")\nadd_library(benchmark::benchmark_main ALIAS benchmark_main)\nset_target_properties(benchmark_main PROPERTIES\n  OUTPUT_NAME \"benchmark_main\"\n  VERSION ${GENERIC_LIB_VERSION}\n  SOVERSION ${GENERIC_LIB_SOVERSION}\n  DEFINE_SYMBOL benchmark_EXPORTS\n)\ntarget_link_libraries(benchmark_main PUBLIC benchmark::benchmark)\n\nset(generated_dir \"${PROJECT_BINARY_DIR}\")\n\nset(version_config \"${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake\")\nset(project_config \"${generated_dir}/${PROJECT_NAME}Config.cmake\")\nset(pkg_config \"${generated_dir}/${PROJECT_NAME}.pc\")\nset(pkg_config_main \"${generated_dir}/${PROJECT_NAME}_main.pc\")\nset(targets_to_export benchmark benchmark_main)\nset(targets_export_name \"${PROJECT_NAME}Targets\")\n\nset(namespace \"${PROJECT_NAME}::\")\n\ninclude(CMakePackageConfigHelpers)\n\nconfigure_package_config_file (\n  ${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in\n  ${project_config}\n  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\n  NO_SET_AND_CHECK_MACRO\n  NO_CHECK_REQUIRED_COMPONENTS_MACRO\n)\nwrite_basic_package_version_file(\n  \"${version_config}\" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion\n)\n\nconfigure_file(\"${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in\" \"${pkg_config}\" @ONLY)\nconfigure_file(\"${PROJECT_SOURCE_DIR}/cmake/benchmark_main.pc.in\" \"${pkg_config_main}\" @ONLY)\n\nexport (\n  TARGETS ${targets_to_export}\n  NAMESPACE \"${namespace}\"\n  FILE ${generated_dir}/${targets_export_name}.cmake\n)\n\nif (BENCHMARK_ENABLE_INSTALL)\n  # Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)\n  install(\n    TARGETS ${targets_to_export}\n    EXPORT ${targets_export_name}\n    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}\n    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})\n\n  install(\n    DIRECTORY \"${PROJECT_SOURCE_DIR}/include/benchmark\"\n              \"${PROJECT_BINARY_DIR}/include/benchmark\"\n    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}\n    FILES_MATCHING PATTERN \"*.*h\")\n\n  install(\n      FILES \"${project_config}\" \"${version_config}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\n\n  install(\n      FILES \"${pkg_config}\" \"${pkg_config_main}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n\n  install(\n      EXPORT \"${targets_export_name}\"\n      NAMESPACE \"${namespace}\"\n      DESTINATION \"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}\")\nendif()\n\nif (BENCHMARK_ENABLE_DOXYGEN)\n  find_package(Doxygen REQUIRED)\n  set(DOXYGEN_QUIET YES)\n  set(DOXYGEN_RECURSIVE YES)\n  set(DOXYGEN_GENERATE_HTML YES)\n  set(DOXYGEN_GENERATE_MAN NO)\n  set(DOXYGEN_MARKDOWN_SUPPORT YES)\n  set(DOXYGEN_BUILTIN_STL_SUPPORT YES)\n  set(DOXYGEN_EXTRACT_PACKAGE YES)\n  set(DOXYGEN_EXTRACT_STATIC YES)\n  set(DOXYGEN_SHOW_INCLUDE_FILES YES)\n  set(DOXYGEN_BINARY_TOC YES)\n  set(DOXYGEN_TOC_EXPAND YES)\n  set(DOXYGEN_USE_MDFILE_AS_MAINPAGE \"index.md\")\n  doxygen_add_docs(benchmark_doxygen\n    docs\n    include\n    src\n    ALL\n    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n    COMMENT \"Building documentation with Doxygen.\")\n  if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_DOCS)\n    install(\n      DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/html/\"\n      DESTINATION ${CMAKE_INSTALL_DOCDIR})\n  endif()\nelse()\n  if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_DOCS)\n    install(\n      DIRECTORY \"${PROJECT_SOURCE_DIR}/docs/\"\n      DESTINATION ${CMAKE_INSTALL_DOCDIR})\n  endif()\nendif()\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/arraysize.h",
    "content": "#ifndef BENCHMARK_ARRAYSIZE_H_\n#define BENCHMARK_ARRAYSIZE_H_\n\n#include \"internal_macros.h\"\n\nnamespace benchmark {\nnamespace internal {\n// The arraysize(arr) macro returns the # of elements in an array arr.\n// The expression is a compile-time constant, and therefore can be\n// used in defining new arrays, for example.  If you use arraysize on\n// a pointer by mistake, you will get a compile-time error.\n//\n\n// This template function declaration is used in defining arraysize.\n// Note that the function doesn't need an implementation, as we only\n// use its type.\ntemplate <typename T, size_t N>\nchar (&ArraySizeHelper(T (&array)[N]))[N];\n\n// That gcc wants both of these prototypes seems mysterious. VC, for\n// its part, can't decide which to use (another mystery). Matching of\n// template overloads: the final frontier.\n#ifndef COMPILER_MSVC\ntemplate <typename T, size_t N>\nchar (&ArraySizeHelper(const T (&array)[N]))[N];\n#endif\n\n#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array)))\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_ARRAYSIZE_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark/benchmark.h\"\n\n#include \"benchmark_api_internal.h\"\n#include \"benchmark_runner.h\"\n#include \"internal_macros.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <fstream>\n#include <iostream>\n#include <limits>\n#include <map>\n#include <memory>\n#include <random>\n#include <string>\n#include <thread>\n#include <utility>\n\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"perf_counters.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"thread_manager.h\"\n#include \"thread_timer.h\"\n\nnamespace benchmark {\n// Print a list of benchmarks. This option overrides all other options.\nBM_DEFINE_bool(benchmark_list_tests, false);\n\n// A regular expression that specifies the set of benchmarks to execute.  If\n// this flag is empty, or if this flag is the string \\\"all\\\", all benchmarks\n// linked into the binary are run.\nBM_DEFINE_string(benchmark_filter, \"\");\n\n// Specification of how long to run the benchmark.\n//\n// It can be either an exact number of iterations (specified as `<integer>x`),\n// or a minimum number of seconds (specified as `<float>s`). If the latter\n// format (ie., min seconds) is used, the system may run the benchmark longer\n// until the results are considered significant.\n//\n// For backward compatibility, the `s` suffix may be omitted, in which case,\n// the specified number is interpreted as the number of seconds.\n//\n// For cpu-time based tests, this is the lower bound\n// on the total cpu time used by all threads that make up the test.  For\n// real-time based tests, this is the lower bound on the elapsed time of the\n// benchmark execution, regardless of number of threads.\nBM_DEFINE_string(benchmark_min_time, kDefaultMinTimeStr);\n\n// Minimum number of seconds a benchmark should be run before results should be\n// taken into account. This e.g can be necessary for benchmarks of code which\n// needs to fill some form of cache before performance is of interest.\n// Note: results gathered within this period are discarded and not used for\n// reported result.\nBM_DEFINE_double(benchmark_min_warmup_time, 0.0);\n\n// The number of runs of each benchmark. If greater than 1, the mean and\n// standard deviation of the runs will be reported.\nBM_DEFINE_int32(benchmark_repetitions, 1);\n\n// If set, enable random interleaving of repetitions of all benchmarks.\n// See http://github.com/google/benchmark/issues/1051 for details.\nBM_DEFINE_bool(benchmark_enable_random_interleaving, false);\n\n// Report the result of each benchmark repetitions. When 'true' is specified\n// only the mean, standard deviation, and other statistics are reported for\n// repeated benchmarks. Affects all reporters.\nBM_DEFINE_bool(benchmark_report_aggregates_only, false);\n\n// Display the result of each benchmark repetitions. When 'true' is specified\n// only the mean, standard deviation, and other statistics are displayed for\n// repeated benchmarks. Unlike benchmark_report_aggregates_only, only affects\n// the display reporter, but  *NOT* file reporter, which will still contain\n// all the output.\nBM_DEFINE_bool(benchmark_display_aggregates_only, false);\n\n// The format to use for console output.\n// Valid values are 'console', 'json', or 'csv'.\nBM_DEFINE_string(benchmark_format, \"console\");\n\n// The format to use for file output.\n// Valid values are 'console', 'json', or 'csv'.\nBM_DEFINE_string(benchmark_out_format, \"json\");\n\n// The file to write additional output to.\nBM_DEFINE_string(benchmark_out, \"\");\n\n// Whether to use colors in the output.  Valid values:\n// 'true'/'yes'/1, 'false'/'no'/0, and 'auto'. 'auto' means to use colors if\n// the output is being sent to a terminal and the TERM environment variable is\n// set to a terminal type that supports colors.\nBM_DEFINE_string(benchmark_color, \"auto\");\n\n// Whether to use tabular format when printing user counters to the console.\n// Valid values: 'true'/'yes'/1, 'false'/'no'/0.  Defaults to false.\nBM_DEFINE_bool(benchmark_counters_tabular, false);\n\n// List of additional perf counters to collect, in libpfm format. For more\n// information about libpfm: https://man7.org/linux/man-pages/man3/libpfm.3.html\nBM_DEFINE_string(benchmark_perf_counters, \"\");\n\n// Extra context to include in the output formatted as comma-separated key-value\n// pairs. Kept internal as it's only used for parsing from env/command line.\nBM_DEFINE_kvpairs(benchmark_context, {});\n\n// Set the default time unit to use for reports\n// Valid values are 'ns', 'us', 'ms' or 's'\nBM_DEFINE_string(benchmark_time_unit, \"\");\n\n// The level of verbose logging to output\nBM_DEFINE_int32(v, 0);\n\nnamespace internal {\n\nstd::map<std::string, std::string>* global_context = nullptr;\n\nBENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext() {\n  return global_context;\n}\n\nstatic void const volatile* volatile global_force_escape_pointer;\n\n// FIXME: Verify if LTO still messes this up?\nvoid UseCharPointer(char const volatile* const v) {\n  // We want to escape the pointer `v` so that the compiler can not eliminate\n  // computations that produced it. To do that, we escape the pointer by storing\n  // it into a volatile variable, since generally, volatile store, is not\n  // something the compiler is allowed to elide.\n  global_force_escape_pointer = reinterpret_cast<void const volatile*>(v);\n}\n\n}  // namespace internal\n\nState::State(std::string name, IterationCount max_iters,\n             const std::vector<int64_t>& ranges, int thread_i, int n_threads,\n             internal::ThreadTimer* timer, internal::ThreadManager* manager,\n             internal::PerfCountersMeasurement* perf_counters_measurement)\n    : total_iterations_(0),\n      batch_leftover_(0),\n      max_iterations(max_iters),\n      started_(false),\n      finished_(false),\n      skipped_(internal::NotSkipped),\n      range_(ranges),\n      complexity_n_(0),\n      name_(std::move(name)),\n      thread_index_(thread_i),\n      threads_(n_threads),\n      timer_(timer),\n      manager_(manager),\n      perf_counters_measurement_(perf_counters_measurement) {\n  BM_CHECK(max_iterations != 0) << \"At least one iteration must be run\";\n  BM_CHECK_LT(thread_index_, threads_)\n      << \"thread_index must be less than threads\";\n\n  // Add counters with correct flag now.  If added with `counters[name]` in\n  // `PauseTiming`, a new `Counter` will be inserted the first time, which\n  // won't have the flag.  Inserting them now also reduces the allocations\n  // during the benchmark.\n  if (perf_counters_measurement_) {\n    for (const std::string& counter_name :\n         perf_counters_measurement_->names()) {\n      counters[counter_name] = Counter(0.0, Counter::kAvgIterations);\n    }\n  }\n\n  // Note: The use of offsetof below is technically undefined until C++17\n  // because State is not a standard layout type. However, all compilers\n  // currently provide well-defined behavior as an extension (which is\n  // demonstrated since constexpr evaluation must diagnose all undefined\n  // behavior). However, GCC and Clang also warn about this use of offsetof,\n  // which must be suppressed.\n#if defined(__INTEL_COMPILER)\n#pragma warning push\n#pragma warning(disable : 1875)\n#elif defined(__GNUC__) || defined(__clang__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Winvalid-offsetof\"\n#endif\n#if defined(__NVCC__)\n#pragma nv_diagnostic push\n#pragma nv_diag_suppress 1427\n#endif\n#if defined(__NVCOMPILER)\n#pragma diagnostic push\n#pragma diag_suppress offset_in_non_POD_nonstandard\n#endif\n  // Offset tests to ensure commonly accessed data is on the first cache line.\n  const int cache_line_size = 64;\n  static_assert(\n      offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), \"\");\n#if defined(__INTEL_COMPILER)\n#pragma warning pop\n#elif defined(__GNUC__) || defined(__clang__)\n#pragma GCC diagnostic pop\n#endif\n#if defined(__NVCC__)\n#pragma nv_diagnostic pop\n#endif\n#if defined(__NVCOMPILER)\n#pragma diagnostic pop\n#endif\n}\n\nvoid State::PauseTiming() {\n  // Add in time accumulated so far\n  BM_CHECK(started_ && !finished_ && !skipped());\n  timer_->StopTimer();\n  if (perf_counters_measurement_) {\n    std::vector<std::pair<std::string, double>> measurements;\n    if (!perf_counters_measurement_->Stop(measurements)) {\n      BM_CHECK(false) << \"Perf counters read the value failed.\";\n    }\n    for (const auto& name_and_measurement : measurements) {\n      const std::string& name = name_and_measurement.first;\n      const double measurement = name_and_measurement.second;\n      // Counter was inserted with `kAvgIterations` flag by the constructor.\n      assert(counters.find(name) != counters.end());\n      counters[name].value += measurement;\n    }\n  }\n}\n\nvoid State::ResumeTiming() {\n  BM_CHECK(started_ && !finished_ && !skipped());\n  timer_->StartTimer();\n  if (perf_counters_measurement_) {\n    perf_counters_measurement_->Start();\n  }\n}\n\nvoid State::SkipWithMessage(const std::string& msg) {\n  skipped_ = internal::SkippedWithMessage;\n  {\n    MutexLock l(manager_->GetBenchmarkMutex());\n    if (internal::NotSkipped == manager_->results.skipped_) {\n      manager_->results.skip_message_ = msg;\n      manager_->results.skipped_ = skipped_;\n    }\n  }\n  total_iterations_ = 0;\n  if (timer_->running()) timer_->StopTimer();\n}\n\nvoid State::SkipWithError(const std::string& msg) {\n  skipped_ = internal::SkippedWithError;\n  {\n    MutexLock l(manager_->GetBenchmarkMutex());\n    if (internal::NotSkipped == manager_->results.skipped_) {\n      manager_->results.skip_message_ = msg;\n      manager_->results.skipped_ = skipped_;\n    }\n  }\n  total_iterations_ = 0;\n  if (timer_->running()) timer_->StopTimer();\n}\n\nvoid State::SetIterationTime(double seconds) {\n  timer_->SetIterationTime(seconds);\n}\n\nvoid State::SetLabel(const std::string& label) {\n  MutexLock l(manager_->GetBenchmarkMutex());\n  manager_->results.report_label_ = label;\n}\n\nvoid State::StartKeepRunning() {\n  BM_CHECK(!started_ && !finished_);\n  started_ = true;\n  total_iterations_ = skipped() ? 0 : max_iterations;\n  manager_->StartStopBarrier();\n  if (!skipped()) ResumeTiming();\n}\n\nvoid State::FinishKeepRunning() {\n  BM_CHECK(started_ && (!finished_ || skipped()));\n  if (!skipped()) {\n    PauseTiming();\n  }\n  // Total iterations has now wrapped around past 0. Fix this.\n  total_iterations_ = 0;\n  finished_ = true;\n  manager_->StartStopBarrier();\n}\n\nnamespace internal {\nnamespace {\n\n// Flushes streams after invoking reporter methods that write to them. This\n// ensures users get timely updates even when streams are not line-buffered.\nvoid FlushStreams(BenchmarkReporter* reporter) {\n  if (!reporter) return;\n  std::flush(reporter->GetOutputStream());\n  std::flush(reporter->GetErrorStream());\n}\n\n// Reports in both display and file reporters.\nvoid Report(BenchmarkReporter* display_reporter,\n            BenchmarkReporter* file_reporter, const RunResults& run_results) {\n  auto report_one = [](BenchmarkReporter* reporter, bool aggregates_only,\n                       const RunResults& results) {\n    assert(reporter);\n    // If there are no aggregates, do output non-aggregates.\n    aggregates_only &= !results.aggregates_only.empty();\n    if (!aggregates_only) reporter->ReportRuns(results.non_aggregates);\n    if (!results.aggregates_only.empty())\n      reporter->ReportRuns(results.aggregates_only);\n  };\n\n  report_one(display_reporter, run_results.display_report_aggregates_only,\n             run_results);\n  if (file_reporter)\n    report_one(file_reporter, run_results.file_report_aggregates_only,\n               run_results);\n\n  FlushStreams(display_reporter);\n  FlushStreams(file_reporter);\n}\n\nvoid RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,\n                   BenchmarkReporter* display_reporter,\n                   BenchmarkReporter* file_reporter) {\n  // Note the file_reporter can be null.\n  BM_CHECK(display_reporter != nullptr);\n\n  // Determine the width of the name field using a minimum width of 10.\n  bool might_have_aggregates = FLAGS_benchmark_repetitions > 1;\n  size_t name_field_width = 10;\n  size_t stat_field_width = 0;\n  for (const BenchmarkInstance& benchmark : benchmarks) {\n    name_field_width =\n        std::max<size_t>(name_field_width, benchmark.name().str().size());\n    might_have_aggregates |= benchmark.repetitions() > 1;\n\n    for (const auto& Stat : benchmark.statistics())\n      stat_field_width = std::max<size_t>(stat_field_width, Stat.name_.size());\n  }\n  if (might_have_aggregates) name_field_width += 1 + stat_field_width;\n\n  // Print header here\n  BenchmarkReporter::Context context;\n  context.name_field_width = name_field_width;\n\n  // Keep track of running times of all instances of each benchmark family.\n  std::map<int /*family_index*/, BenchmarkReporter::PerFamilyRunReports>\n      per_family_reports;\n\n  if (display_reporter->ReportContext(context) &&\n      (!file_reporter || file_reporter->ReportContext(context))) {\n    FlushStreams(display_reporter);\n    FlushStreams(file_reporter);\n\n    size_t num_repetitions_total = 0;\n\n    // This perfcounters object needs to be created before the runners vector\n    // below so it outlasts their lifetime.\n    PerfCountersMeasurement perfcounters(\n        StrSplit(FLAGS_benchmark_perf_counters, ','));\n\n    // Vector of benchmarks to run\n    std::vector<internal::BenchmarkRunner> runners;\n    runners.reserve(benchmarks.size());\n\n    // Count the number of benchmarks with threads to warn the user in case\n    // performance counters are used.\n    int benchmarks_with_threads = 0;\n\n    // Loop through all benchmarks\n    for (const BenchmarkInstance& benchmark : benchmarks) {\n      BenchmarkReporter::PerFamilyRunReports* reports_for_family = nullptr;\n      if (benchmark.complexity() != oNone)\n        reports_for_family = &per_family_reports[benchmark.family_index()];\n      benchmarks_with_threads += (benchmark.threads() > 1);\n      runners.emplace_back(benchmark, &perfcounters, reports_for_family);\n      int num_repeats_of_this_instance = runners.back().GetNumRepeats();\n      num_repetitions_total +=\n          static_cast<size_t>(num_repeats_of_this_instance);\n      if (reports_for_family)\n        reports_for_family->num_runs_total += num_repeats_of_this_instance;\n    }\n    assert(runners.size() == benchmarks.size() && \"Unexpected runner count.\");\n\n    // The use of performance counters with threads would be unintuitive for\n    // the average user so we need to warn them about this case\n    if ((benchmarks_with_threads > 0) && (perfcounters.num_counters() > 0)) {\n      GetErrorLogInstance()\n          << \"***WARNING*** There are \" << benchmarks_with_threads\n          << \" benchmarks with threads and \" << perfcounters.num_counters()\n          << \" performance counters were requested. Beware counters will \"\n             \"reflect the combined usage across all \"\n             \"threads.\\n\";\n    }\n\n    std::vector<size_t> repetition_indices;\n    repetition_indices.reserve(num_repetitions_total);\n    for (size_t runner_index = 0, num_runners = runners.size();\n         runner_index != num_runners; ++runner_index) {\n      const internal::BenchmarkRunner& runner = runners[runner_index];\n      std::fill_n(std::back_inserter(repetition_indices),\n                  runner.GetNumRepeats(), runner_index);\n    }\n    assert(repetition_indices.size() == num_repetitions_total &&\n           \"Unexpected number of repetition indexes.\");\n\n    if (FLAGS_benchmark_enable_random_interleaving) {\n      std::random_device rd;\n      std::mt19937 g(rd());\n      std::shuffle(repetition_indices.begin(), repetition_indices.end(), g);\n    }\n\n    for (size_t repetition_index : repetition_indices) {\n      internal::BenchmarkRunner& runner = runners[repetition_index];\n      runner.DoOneRepetition();\n      if (runner.HasRepeatsRemaining()) continue;\n      // FIXME: report each repetition separately, not all of them in bulk.\n\n      display_reporter->ReportRunsConfig(\n          runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());\n      if (file_reporter)\n        file_reporter->ReportRunsConfig(\n            runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());\n\n      RunResults run_results = runner.GetResults();\n\n      // Maybe calculate complexity report\n      if (const auto* reports_for_family = runner.GetReportsForFamily()) {\n        if (reports_for_family->num_runs_done ==\n            reports_for_family->num_runs_total) {\n          auto additional_run_stats = ComputeBigO(reports_for_family->Runs);\n          run_results.aggregates_only.insert(run_results.aggregates_only.end(),\n                                             additional_run_stats.begin(),\n                                             additional_run_stats.end());\n          per_family_reports.erase(\n              static_cast<int>(reports_for_family->Runs.front().family_index));\n        }\n      }\n\n      Report(display_reporter, file_reporter, run_results);\n    }\n  }\n  display_reporter->Finalize();\n  if (file_reporter) file_reporter->Finalize();\n  FlushStreams(display_reporter);\n  FlushStreams(file_reporter);\n}\n\n// Disable deprecated warnings temporarily because we need to reference\n// CSVReporter but don't want to trigger -Werror=-Wdeprecated-declarations\nBENCHMARK_DISABLE_DEPRECATED_WARNING\n\nstd::unique_ptr<BenchmarkReporter> CreateReporter(\n    std::string const& name, ConsoleReporter::OutputOptions output_opts) {\n  typedef std::unique_ptr<BenchmarkReporter> PtrType;\n  if (name == \"console\") {\n    return PtrType(new ConsoleReporter(output_opts));\n  }\n  if (name == \"json\") {\n    return PtrType(new JSONReporter());\n  }\n  if (name == \"csv\") {\n    return PtrType(new CSVReporter());\n  }\n  std::cerr << \"Unexpected format: '\" << name << \"'\\n\";\n  std::exit(1);\n}\n\nBENCHMARK_RESTORE_DEPRECATED_WARNING\n\n}  // end namespace\n\nbool IsZero(double n) {\n  return std::abs(n) < std::numeric_limits<double>::epsilon();\n}\n\nConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {\n  int output_opts = ConsoleReporter::OO_Defaults;\n  auto is_benchmark_color = [force_no_color]() -> bool {\n    if (force_no_color) {\n      return false;\n    }\n    if (FLAGS_benchmark_color == \"auto\") {\n      return IsColorTerminal();\n    }\n    return IsTruthyFlagValue(FLAGS_benchmark_color);\n  };\n  if (is_benchmark_color()) {\n    output_opts |= ConsoleReporter::OO_Color;\n  } else {\n    output_opts &= ~ConsoleReporter::OO_Color;\n  }\n  if (FLAGS_benchmark_counters_tabular) {\n    output_opts |= ConsoleReporter::OO_Tabular;\n  } else {\n    output_opts &= ~ConsoleReporter::OO_Tabular;\n  }\n  return static_cast<ConsoleReporter::OutputOptions>(output_opts);\n}\n\n}  // end namespace internal\n\nBenchmarkReporter* CreateDefaultDisplayReporter() {\n  static auto default_display_reporter =\n      internal::CreateReporter(FLAGS_benchmark_format,\n                               internal::GetOutputOptions())\n          .release();\n  return default_display_reporter;\n}\n\nsize_t RunSpecifiedBenchmarks() {\n  return RunSpecifiedBenchmarks(nullptr, nullptr, FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(std::string spec) {\n  return RunSpecifiedBenchmarks(nullptr, nullptr, std::move(spec));\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) {\n  return RunSpecifiedBenchmarks(display_reporter, nullptr,\n                                FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              std::string spec) {\n  return RunSpecifiedBenchmarks(display_reporter, nullptr, std::move(spec));\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              BenchmarkReporter* file_reporter) {\n  return RunSpecifiedBenchmarks(display_reporter, file_reporter,\n                                FLAGS_benchmark_filter);\n}\n\nsize_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,\n                              BenchmarkReporter* file_reporter,\n                              std::string spec) {\n  if (spec.empty() || spec == \"all\")\n    spec = \".\";  // Regexp that matches all benchmarks\n\n  // Setup the reporters\n  std::ofstream output_file;\n  std::unique_ptr<BenchmarkReporter> default_display_reporter;\n  std::unique_ptr<BenchmarkReporter> default_file_reporter;\n  if (!display_reporter) {\n    default_display_reporter.reset(CreateDefaultDisplayReporter());\n    display_reporter = default_display_reporter.get();\n  }\n  auto& Out = display_reporter->GetOutputStream();\n  auto& Err = display_reporter->GetErrorStream();\n\n  std::string const& fname = FLAGS_benchmark_out;\n  if (fname.empty() && file_reporter) {\n    Err << \"A custom file reporter was provided but \"\n           \"--benchmark_out=<file> was not specified.\"\n        << std::endl;\n    Out.flush();\n    Err.flush();\n    std::exit(1);\n  }\n  if (!fname.empty()) {\n    output_file.open(fname);\n    if (!output_file.is_open()) {\n      Err << \"invalid file name: '\" << fname << \"'\" << std::endl;\n      Out.flush();\n      Err.flush();\n      std::exit(1);\n    }\n    if (!file_reporter) {\n      default_file_reporter = internal::CreateReporter(\n          FLAGS_benchmark_out_format, FLAGS_benchmark_counters_tabular\n                                          ? ConsoleReporter::OO_Tabular\n                                          : ConsoleReporter::OO_None);\n      file_reporter = default_file_reporter.get();\n    }\n    file_reporter->SetOutputStream(&output_file);\n    file_reporter->SetErrorStream(&output_file);\n  }\n\n  std::vector<internal::BenchmarkInstance> benchmarks;\n  if (!FindBenchmarksInternal(spec, &benchmarks, &Err)) {\n    Out.flush();\n    Err.flush();\n    return 0;\n  }\n\n  if (benchmarks.empty()) {\n    Err << \"Failed to match any benchmarks against regex: \" << spec << \"\\n\";\n    Out.flush();\n    Err.flush();\n    return 0;\n  }\n\n  if (FLAGS_benchmark_list_tests) {\n    for (auto const& benchmark : benchmarks)\n      Out << benchmark.name().str() << \"\\n\";\n  } else {\n    internal::RunBenchmarks(benchmarks, display_reporter, file_reporter);\n  }\n\n  Out.flush();\n  Err.flush();\n  return benchmarks.size();\n}\n\nnamespace {\n// stores the time unit benchmarks use by default\nTimeUnit default_time_unit = kNanosecond;\n}  // namespace\n\nTimeUnit GetDefaultTimeUnit() { return default_time_unit; }\n\nvoid SetDefaultTimeUnit(TimeUnit unit) { default_time_unit = unit; }\n\nstd::string GetBenchmarkFilter() { return FLAGS_benchmark_filter; }\n\nvoid SetBenchmarkFilter(std::string value) {\n  FLAGS_benchmark_filter = std::move(value);\n}\n\nint32_t GetBenchmarkVerbosity() { return FLAGS_v; }\n\nvoid RegisterMemoryManager(MemoryManager* manager) {\n  internal::memory_manager = manager;\n}\n\nvoid RegisterProfilerManager(ProfilerManager* manager) {\n  internal::profiler_manager = manager;\n}\n\nvoid AddCustomContext(const std::string& key, const std::string& value) {\n  if (internal::global_context == nullptr) {\n    internal::global_context = new std::map<std::string, std::string>();\n  }\n  if (!internal::global_context->emplace(key, value).second) {\n    std::cerr << \"Failed to add custom context \\\"\" << key << \"\\\" as it already \"\n              << \"exists with value \\\"\" << value << \"\\\"\\n\";\n  }\n}\n\nnamespace internal {\n\nvoid (*HelperPrintf)();\n\nvoid PrintUsageAndExit() {\n  HelperPrintf();\n  exit(0);\n}\n\nvoid SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {\n  if (time_unit_flag == \"s\") {\n    return SetDefaultTimeUnit(kSecond);\n  }\n  if (time_unit_flag == \"ms\") {\n    return SetDefaultTimeUnit(kMillisecond);\n  }\n  if (time_unit_flag == \"us\") {\n    return SetDefaultTimeUnit(kMicrosecond);\n  }\n  if (time_unit_flag == \"ns\") {\n    return SetDefaultTimeUnit(kNanosecond);\n  }\n  if (!time_unit_flag.empty()) {\n    PrintUsageAndExit();\n  }\n}\n\nvoid ParseCommandLineFlags(int* argc, char** argv) {\n  using namespace benchmark;\n  BenchmarkReporter::Context::executable_name =\n      (argc && *argc > 0) ? argv[0] : \"unknown\";\n  for (int i = 1; argc && i < *argc; ++i) {\n    if (ParseBoolFlag(argv[i], \"benchmark_list_tests\",\n                      &FLAGS_benchmark_list_tests) ||\n        ParseStringFlag(argv[i], \"benchmark_filter\", &FLAGS_benchmark_filter) ||\n        ParseStringFlag(argv[i], \"benchmark_min_time\",\n                        &FLAGS_benchmark_min_time) ||\n        ParseDoubleFlag(argv[i], \"benchmark_min_warmup_time\",\n                        &FLAGS_benchmark_min_warmup_time) ||\n        ParseInt32Flag(argv[i], \"benchmark_repetitions\",\n                       &FLAGS_benchmark_repetitions) ||\n        ParseBoolFlag(argv[i], \"benchmark_enable_random_interleaving\",\n                      &FLAGS_benchmark_enable_random_interleaving) ||\n        ParseBoolFlag(argv[i], \"benchmark_report_aggregates_only\",\n                      &FLAGS_benchmark_report_aggregates_only) ||\n        ParseBoolFlag(argv[i], \"benchmark_display_aggregates_only\",\n                      &FLAGS_benchmark_display_aggregates_only) ||\n        ParseStringFlag(argv[i], \"benchmark_format\", &FLAGS_benchmark_format) ||\n        ParseStringFlag(argv[i], \"benchmark_out\", &FLAGS_benchmark_out) ||\n        ParseStringFlag(argv[i], \"benchmark_out_format\",\n                        &FLAGS_benchmark_out_format) ||\n        ParseStringFlag(argv[i], \"benchmark_color\", &FLAGS_benchmark_color) ||\n        ParseBoolFlag(argv[i], \"benchmark_counters_tabular\",\n                      &FLAGS_benchmark_counters_tabular) ||\n        ParseStringFlag(argv[i], \"benchmark_perf_counters\",\n                        &FLAGS_benchmark_perf_counters) ||\n        ParseKeyValueFlag(argv[i], \"benchmark_context\",\n                          &FLAGS_benchmark_context) ||\n        ParseStringFlag(argv[i], \"benchmark_time_unit\",\n                        &FLAGS_benchmark_time_unit) ||\n        ParseInt32Flag(argv[i], \"v\", &FLAGS_v)) {\n      for (int j = i; j != *argc - 1; ++j) argv[j] = argv[j + 1];\n\n      --(*argc);\n      --i;\n    } else if (IsFlag(argv[i], \"help\")) {\n      PrintUsageAndExit();\n    }\n  }\n  for (auto const* flag :\n       {&FLAGS_benchmark_format, &FLAGS_benchmark_out_format}) {\n    if (*flag != \"console\" && *flag != \"json\" && *flag != \"csv\") {\n      PrintUsageAndExit();\n    }\n  }\n  SetDefaultTimeUnitFromFlag(FLAGS_benchmark_time_unit);\n  if (FLAGS_benchmark_color.empty()) {\n    PrintUsageAndExit();\n  }\n  for (const auto& kv : FLAGS_benchmark_context) {\n    AddCustomContext(kv.first, kv.second);\n  }\n}\n\nint InitializeStreams() {\n  static std::ios_base::Init init;\n  return 0;\n}\n\n}  // end namespace internal\n\nstd::string GetBenchmarkVersion() {\n#ifdef BENCHMARK_VERSION\n  return {BENCHMARK_VERSION};\n#else\n  return {\"\"};\n#endif\n}\n\nvoid PrintDefaultHelp() {\n  fprintf(stdout,\n          \"benchmark\"\n          \" [--benchmark_list_tests={true|false}]\\n\"\n          \"          [--benchmark_filter=<regex>]\\n\"\n          \"          [--benchmark_min_time=`<integer>x` OR `<float>s` ]\\n\"\n          \"          [--benchmark_min_warmup_time=<min_warmup_time>]\\n\"\n          \"          [--benchmark_repetitions=<num_repetitions>]\\n\"\n          \"          [--benchmark_enable_random_interleaving={true|false}]\\n\"\n          \"          [--benchmark_report_aggregates_only={true|false}]\\n\"\n          \"          [--benchmark_display_aggregates_only={true|false}]\\n\"\n          \"          [--benchmark_format=<console|json|csv>]\\n\"\n          \"          [--benchmark_out=<filename>]\\n\"\n          \"          [--benchmark_out_format=<json|console|csv>]\\n\"\n          \"          [--benchmark_color={auto|true|false}]\\n\"\n          \"          [--benchmark_counters_tabular={true|false}]\\n\"\n#if defined HAVE_LIBPFM\n          \"          [--benchmark_perf_counters=<counter>,...]\\n\"\n#endif\n          \"          [--benchmark_context=<key>=<value>,...]\\n\"\n          \"          [--benchmark_time_unit={ns|us|ms|s}]\\n\"\n          \"          [--v=<verbosity>]\\n\");\n}\n\nvoid Initialize(int* argc, char** argv, void (*HelperPrintf)()) {\n  internal::HelperPrintf = HelperPrintf;\n  internal::ParseCommandLineFlags(argc, argv);\n  internal::LogLevel() = FLAGS_v;\n}\n\nvoid Shutdown() { delete internal::global_context; }\n\nbool ReportUnrecognizedArguments(int argc, char** argv) {\n  for (int i = 1; i < argc; ++i) {\n    fprintf(stderr, \"%s: error: unrecognized command-line flag: %s\\n\", argv[0],\n            argv[i]);\n  }\n  return argc > 1;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_api_internal.cc",
    "content": "#include \"benchmark_api_internal.h\"\n\n#include <cinttypes>\n\n#include \"string_util.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nBenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,\n                                     int per_family_instance_idx,\n                                     const std::vector<int64_t>& args,\n                                     int thread_count)\n    : benchmark_(*benchmark),\n      family_index_(family_idx),\n      per_family_instance_index_(per_family_instance_idx),\n      aggregation_report_mode_(benchmark_.aggregation_report_mode_),\n      args_(args),\n      time_unit_(benchmark_.GetTimeUnit()),\n      measure_process_cpu_time_(benchmark_.measure_process_cpu_time_),\n      use_real_time_(benchmark_.use_real_time_),\n      use_manual_time_(benchmark_.use_manual_time_),\n      complexity_(benchmark_.complexity_),\n      complexity_lambda_(benchmark_.complexity_lambda_),\n      statistics_(benchmark_.statistics_),\n      repetitions_(benchmark_.repetitions_),\n      min_time_(benchmark_.min_time_),\n      min_warmup_time_(benchmark_.min_warmup_time_),\n      iterations_(benchmark_.iterations_),\n      threads_(thread_count) {\n  name_.function_name = benchmark_.name_;\n\n  size_t arg_i = 0;\n  for (const auto& arg : args) {\n    if (!name_.args.empty()) {\n      name_.args += '/';\n    }\n\n    if (arg_i < benchmark->arg_names_.size()) {\n      const auto& arg_name = benchmark_.arg_names_[arg_i];\n      if (!arg_name.empty()) {\n        name_.args += StrFormat(\"%s:\", arg_name.c_str());\n      }\n    }\n\n    name_.args += StrFormat(\"%\" PRId64, arg);\n    ++arg_i;\n  }\n\n  if (!IsZero(benchmark->min_time_)) {\n    name_.min_time = StrFormat(\"min_time:%0.3f\", benchmark_.min_time_);\n  }\n\n  if (!IsZero(benchmark->min_warmup_time_)) {\n    name_.min_warmup_time =\n        StrFormat(\"min_warmup_time:%0.3f\", benchmark_.min_warmup_time_);\n  }\n\n  if (benchmark_.iterations_ != 0) {\n    name_.iterations = StrFormat(\n        \"iterations:%lu\", static_cast<unsigned long>(benchmark_.iterations_));\n  }\n\n  if (benchmark_.repetitions_ != 0) {\n    name_.repetitions = StrFormat(\"repeats:%d\", benchmark_.repetitions_);\n  }\n\n  if (benchmark_.measure_process_cpu_time_) {\n    name_.time_type = \"process_time\";\n  }\n\n  if (benchmark_.use_manual_time_) {\n    if (!name_.time_type.empty()) {\n      name_.time_type += '/';\n    }\n    name_.time_type += \"manual_time\";\n  } else if (benchmark_.use_real_time_) {\n    if (!name_.time_type.empty()) {\n      name_.time_type += '/';\n    }\n    name_.time_type += \"real_time\";\n  }\n\n  if (!benchmark_.thread_counts_.empty()) {\n    name_.threads = StrFormat(\"threads:%d\", threads_);\n  }\n\n  setup_ = benchmark_.setup_;\n  teardown_ = benchmark_.teardown_;\n}\n\nState BenchmarkInstance::Run(\n    IterationCount iters, int thread_id, internal::ThreadTimer* timer,\n    internal::ThreadManager* manager,\n    internal::PerfCountersMeasurement* perf_counters_measurement) const {\n  State st(name_.function_name, iters, args_, thread_id, threads_, timer,\n           manager, perf_counters_measurement);\n  benchmark_.Run(st);\n  return st;\n}\n\nvoid BenchmarkInstance::Setup() const {\n  if (setup_) {\n    State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,\n             nullptr, nullptr, nullptr);\n    setup_(st);\n  }\n}\n\nvoid BenchmarkInstance::Teardown() const {\n  if (teardown_) {\n    State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,\n             nullptr, nullptr, nullptr);\n    teardown_(st);\n  }\n}\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_api_internal.h",
    "content": "#ifndef BENCHMARK_API_INTERNAL_H\n#define BENCHMARK_API_INTERNAL_H\n\n#include <cmath>\n#include <iosfwd>\n#include <limits>\n#include <memory>\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"commandlineflags.h\"\n\nnamespace benchmark {\nnamespace internal {\n\n// Information kept per benchmark we may want to run\nclass BenchmarkInstance {\n public:\n  BenchmarkInstance(Benchmark* benchmark, int family_index,\n                    int per_family_instance_index,\n                    const std::vector<int64_t>& args, int threads);\n\n  const BenchmarkName& name() const { return name_; }\n  int family_index() const { return family_index_; }\n  int per_family_instance_index() const { return per_family_instance_index_; }\n  AggregationReportMode aggregation_report_mode() const {\n    return aggregation_report_mode_;\n  }\n  TimeUnit time_unit() const { return time_unit_; }\n  bool measure_process_cpu_time() const { return measure_process_cpu_time_; }\n  bool use_real_time() const { return use_real_time_; }\n  bool use_manual_time() const { return use_manual_time_; }\n  BigO complexity() const { return complexity_; }\n  BigOFunc* complexity_lambda() const { return complexity_lambda_; }\n  const std::vector<Statistics>& statistics() const { return statistics_; }\n  int repetitions() const { return repetitions_; }\n  double min_time() const { return min_time_; }\n  double min_warmup_time() const { return min_warmup_time_; }\n  IterationCount iterations() const { return iterations_; }\n  int threads() const { return threads_; }\n  void Setup() const;\n  void Teardown() const;\n\n  State Run(IterationCount iters, int thread_id, internal::ThreadTimer* timer,\n            internal::ThreadManager* manager,\n            internal::PerfCountersMeasurement* perf_counters_measurement) const;\n\n private:\n  BenchmarkName name_;\n  Benchmark& benchmark_;\n  const int family_index_;\n  const int per_family_instance_index_;\n  AggregationReportMode aggregation_report_mode_;\n  const std::vector<int64_t>& args_;\n  TimeUnit time_unit_;\n  bool measure_process_cpu_time_;\n  bool use_real_time_;\n  bool use_manual_time_;\n  BigO complexity_;\n  BigOFunc* complexity_lambda_;\n  UserCounters counters_;\n  const std::vector<Statistics>& statistics_;\n  int repetitions_;\n  double min_time_;\n  double min_warmup_time_;\n  IterationCount iterations_;\n  int threads_;  // Number of concurrent threads to us\n\n  typedef void (*callback_function)(const benchmark::State&);\n  callback_function setup_ = nullptr;\n  callback_function teardown_ = nullptr;\n};\n\nbool FindBenchmarksInternal(const std::string& re,\n                            std::vector<BenchmarkInstance>* benchmarks,\n                            std::ostream* Err);\n\nbool IsZero(double n);\n\nBENCHMARK_EXPORT\nConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false);\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_API_INTERNAL_H\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_main.cc",
    "content": "// Copyright 2018 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark/benchmark.h\"\n\nBENCHMARK_EXPORT int main(int, char**);\nBENCHMARK_MAIN();\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_name.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <benchmark/benchmark.h>\n\nnamespace benchmark {\n\nnamespace {\n\n// Compute the total size of a pack of std::strings\nsize_t size_impl() { return 0; }\n\ntemplate <typename Head, typename... Tail>\nsize_t size_impl(const Head& head, const Tail&... tail) {\n  return head.size() + size_impl(tail...);\n}\n\n// Join a pack of std::strings using a delimiter\n// TODO: use absl::StrJoin\nvoid join_impl(std::string&, char) {}\n\ntemplate <typename Head, typename... Tail>\nvoid join_impl(std::string& s, const char delimiter, const Head& head,\n               const Tail&... tail) {\n  if (!s.empty() && !head.empty()) {\n    s += delimiter;\n  }\n\n  s += head;\n\n  join_impl(s, delimiter, tail...);\n}\n\ntemplate <typename... Ts>\nstd::string join(char delimiter, const Ts&... ts) {\n  std::string s;\n  s.reserve(sizeof...(Ts) + size_impl(ts...));\n  join_impl(s, delimiter, ts...);\n  return s;\n}\n}  // namespace\n\nBENCHMARK_EXPORT\nstd::string BenchmarkName::str() const {\n  return join('/', function_name, args, min_time, min_warmup_time, iterations,\n              repetitions, time_type, threads);\n}\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_register.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark_register.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <cinttypes>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <memory>\n#include <numeric>\n#include <sstream>\n#include <thread>\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark_api_internal.h\"\n#include \"check.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nnamespace {\n// For non-dense Range, intermediate values are powers of kRangeMultiplier.\nstatic constexpr int kRangeMultiplier = 8;\n\n// The size of a benchmark family determines is the number of inputs to repeat\n// the benchmark on. If this is \"large\" then warn the user during configuration.\nstatic constexpr size_t kMaxFamilySize = 100;\n\nstatic constexpr char kDisabledPrefix[] = \"DISABLED_\";\n}  // end namespace\n\nnamespace internal {\n\n//=============================================================================//\n//                         BenchmarkFamilies\n//=============================================================================//\n\n// Class for managing registered benchmarks.  Note that each registered\n// benchmark identifies a family of related benchmarks to run.\nclass BenchmarkFamilies {\n public:\n  static BenchmarkFamilies* GetInstance();\n\n  // Registers a benchmark family and returns the index assigned to it.\n  size_t AddBenchmark(std::unique_ptr<Benchmark> family);\n\n  // Clear all registered benchmark families.\n  void ClearBenchmarks();\n\n  // Extract the list of benchmark instances that match the specified\n  // regular expression.\n  bool FindBenchmarks(std::string re,\n                      std::vector<BenchmarkInstance>* benchmarks,\n                      std::ostream* Err);\n\n private:\n  BenchmarkFamilies() {}\n\n  std::vector<std::unique_ptr<Benchmark>> families_;\n  Mutex mutex_;\n};\n\nBenchmarkFamilies* BenchmarkFamilies::GetInstance() {\n  static BenchmarkFamilies instance;\n  return &instance;\n}\n\nsize_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {\n  MutexLock l(mutex_);\n  size_t index = families_.size();\n  families_.push_back(std::move(family));\n  return index;\n}\n\nvoid BenchmarkFamilies::ClearBenchmarks() {\n  MutexLock l(mutex_);\n  families_.clear();\n  families_.shrink_to_fit();\n}\n\nbool BenchmarkFamilies::FindBenchmarks(\n    std::string spec, std::vector<BenchmarkInstance>* benchmarks,\n    std::ostream* ErrStream) {\n  BM_CHECK(ErrStream);\n  auto& Err = *ErrStream;\n  // Make regular expression out of command-line flag\n  std::string error_msg;\n  Regex re;\n  bool is_negative_filter = false;\n  if (spec[0] == '-') {\n    spec.replace(0, 1, \"\");\n    is_negative_filter = true;\n  }\n  if (!re.Init(spec, &error_msg)) {\n    Err << \"Could not compile benchmark re: \" << error_msg << std::endl;\n    return false;\n  }\n\n  // Special list of thread counts to use when none are specified\n  const std::vector<int> one_thread = {1};\n\n  int next_family_index = 0;\n\n  MutexLock l(mutex_);\n  for (std::unique_ptr<Benchmark>& family : families_) {\n    int family_index = next_family_index;\n    int per_family_instance_index = 0;\n\n    // Family was deleted or benchmark doesn't match\n    if (!family) continue;\n\n    if (family->ArgsCnt() == -1) {\n      family->Args({});\n    }\n    const std::vector<int>* thread_counts =\n        (family->thread_counts_.empty()\n             ? &one_thread\n             : &static_cast<const std::vector<int>&>(family->thread_counts_));\n    const size_t family_size = family->args_.size() * thread_counts->size();\n    // The benchmark will be run at least 'family_size' different inputs.\n    // If 'family_size' is very large warn the user.\n    if (family_size > kMaxFamilySize) {\n      Err << \"The number of inputs is very large. \" << family->name_\n          << \" will be repeated at least \" << family_size << \" times.\\n\";\n    }\n    // reserve in the special case the regex \".\", since we know the final\n    // family size.  this doesn't take into account any disabled benchmarks\n    // so worst case we reserve more than we need.\n    if (spec == \".\") benchmarks->reserve(benchmarks->size() + family_size);\n\n    for (auto const& args : family->args_) {\n      for (int num_threads : *thread_counts) {\n        BenchmarkInstance instance(family.get(), family_index,\n                                   per_family_instance_index, args,\n                                   num_threads);\n\n        const auto full_name = instance.name().str();\n        if (full_name.rfind(kDisabledPrefix, 0) != 0 &&\n            ((re.Match(full_name) && !is_negative_filter) ||\n             (!re.Match(full_name) && is_negative_filter))) {\n          benchmarks->push_back(std::move(instance));\n\n          ++per_family_instance_index;\n\n          // Only bump the next family index once we've estabilished that\n          // at least one instance of this family will be run.\n          if (next_family_index == family_index) ++next_family_index;\n        }\n      }\n    }\n  }\n  return true;\n}\n\nBenchmark* RegisterBenchmarkInternal(Benchmark* bench) {\n  std::unique_ptr<Benchmark> bench_ptr(bench);\n  BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();\n  families->AddBenchmark(std::move(bench_ptr));\n  return bench;\n}\n\n// FIXME: This function is a hack so that benchmark.cc can access\n// `BenchmarkFamilies`\nbool FindBenchmarksInternal(const std::string& re,\n                            std::vector<BenchmarkInstance>* benchmarks,\n                            std::ostream* Err) {\n  return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);\n}\n\n//=============================================================================//\n//                               Benchmark\n//=============================================================================//\n\nBenchmark::Benchmark(const std::string& name)\n    : name_(name),\n      aggregation_report_mode_(ARM_Unspecified),\n      time_unit_(GetDefaultTimeUnit()),\n      use_default_time_unit_(true),\n      range_multiplier_(kRangeMultiplier),\n      min_time_(0),\n      min_warmup_time_(0),\n      iterations_(0),\n      repetitions_(0),\n      measure_process_cpu_time_(false),\n      use_real_time_(false),\n      use_manual_time_(false),\n      complexity_(oNone),\n      complexity_lambda_(nullptr),\n      setup_(nullptr),\n      teardown_(nullptr) {\n  ComputeStatistics(\"mean\", StatisticsMean);\n  ComputeStatistics(\"median\", StatisticsMedian);\n  ComputeStatistics(\"stddev\", StatisticsStdDev);\n  ComputeStatistics(\"cv\", StatisticsCV, kPercentage);\n}\n\nBenchmark::~Benchmark() {}\n\nBenchmark* Benchmark::Name(const std::string& name) {\n  SetName(name);\n  return this;\n}\n\nBenchmark* Benchmark::Arg(int64_t x) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  args_.push_back({x});\n  return this;\n}\n\nBenchmark* Benchmark::Unit(TimeUnit unit) {\n  time_unit_ = unit;\n  use_default_time_unit_ = false;\n  return this;\n}\n\nBenchmark* Benchmark::Range(int64_t start, int64_t limit) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  std::vector<int64_t> arglist;\n  AddRange(&arglist, start, limit, range_multiplier_);\n\n  for (int64_t i : arglist) {\n    args_.push_back({i});\n  }\n  return this;\n}\n\nBenchmark* Benchmark::Ranges(\n    const std::vector<std::pair<int64_t, int64_t>>& ranges) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));\n  std::vector<std::vector<int64_t>> arglists(ranges.size());\n  for (std::size_t i = 0; i < ranges.size(); i++) {\n    AddRange(&arglists[i], ranges[i].first, ranges[i].second,\n             range_multiplier_);\n  }\n\n  ArgsProduct(arglists);\n\n  return this;\n}\n\nBenchmark* Benchmark::ArgsProduct(\n    const std::vector<std::vector<int64_t>>& arglists) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(arglists.size()));\n\n  std::vector<std::size_t> indices(arglists.size());\n  const std::size_t total = std::accumulate(\n      std::begin(arglists), std::end(arglists), std::size_t{1},\n      [](const std::size_t res, const std::vector<int64_t>& arglist) {\n        return res * arglist.size();\n      });\n  std::vector<int64_t> args;\n  args.reserve(arglists.size());\n  for (std::size_t i = 0; i < total; i++) {\n    for (std::size_t arg = 0; arg < arglists.size(); arg++) {\n      args.push_back(arglists[arg][indices[arg]]);\n    }\n    args_.push_back(args);\n    args.clear();\n\n    std::size_t arg = 0;\n    do {\n      indices[arg] = (indices[arg] + 1) % arglists[arg].size();\n    } while (indices[arg++] == 0 && arg < arglists.size());\n  }\n\n  return this;\n}\n\nBenchmark* Benchmark::ArgName(const std::string& name) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  arg_names_ = {name};\n  return this;\n}\n\nBenchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(names.size()));\n  arg_names_ = names;\n  return this;\n}\n\nBenchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);\n  BM_CHECK_LE(start, limit);\n  for (int64_t arg = start; arg <= limit; arg += step) {\n    args_.push_back({arg});\n  }\n  return this;\n}\n\nBenchmark* Benchmark::Args(const std::vector<int64_t>& args) {\n  BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(args.size()));\n  args_.push_back(args);\n  return this;\n}\n\nBenchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {\n  custom_arguments(this);\n  return this;\n}\n\nBenchmark* Benchmark::Setup(void (*setup)(const benchmark::State&)) {\n  BM_CHECK(setup != nullptr);\n  setup_ = setup;\n  return this;\n}\n\nBenchmark* Benchmark::Teardown(void (*teardown)(const benchmark::State&)) {\n  BM_CHECK(teardown != nullptr);\n  teardown_ = teardown;\n  return this;\n}\n\nBenchmark* Benchmark::RangeMultiplier(int multiplier) {\n  BM_CHECK(multiplier > 1);\n  range_multiplier_ = multiplier;\n  return this;\n}\n\nBenchmark* Benchmark::MinTime(double t) {\n  BM_CHECK(t > 0.0);\n  BM_CHECK(iterations_ == 0);\n  min_time_ = t;\n  return this;\n}\n\nBenchmark* Benchmark::MinWarmUpTime(double t) {\n  BM_CHECK(t >= 0.0);\n  BM_CHECK(iterations_ == 0);\n  min_warmup_time_ = t;\n  return this;\n}\n\nBenchmark* Benchmark::Iterations(IterationCount n) {\n  BM_CHECK(n > 0);\n  BM_CHECK(IsZero(min_time_));\n  BM_CHECK(IsZero(min_warmup_time_));\n  iterations_ = n;\n  return this;\n}\n\nBenchmark* Benchmark::Repetitions(int n) {\n  BM_CHECK(n > 0);\n  repetitions_ = n;\n  return this;\n}\n\nBenchmark* Benchmark::ReportAggregatesOnly(bool value) {\n  aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;\n  return this;\n}\n\nBenchmark* Benchmark::DisplayAggregatesOnly(bool value) {\n  // If we were called, the report mode is no longer 'unspecified', in any case.\n  aggregation_report_mode_ = static_cast<AggregationReportMode>(\n      aggregation_report_mode_ | ARM_Default);\n\n  if (value) {\n    aggregation_report_mode_ = static_cast<AggregationReportMode>(\n        aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);\n  } else {\n    aggregation_report_mode_ = static_cast<AggregationReportMode>(\n        aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);\n  }\n\n  return this;\n}\n\nBenchmark* Benchmark::MeasureProcessCPUTime() {\n  // Can be used together with UseRealTime() / UseManualTime().\n  measure_process_cpu_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::UseRealTime() {\n  BM_CHECK(!use_manual_time_)\n      << \"Cannot set UseRealTime and UseManualTime simultaneously.\";\n  use_real_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::UseManualTime() {\n  BM_CHECK(!use_real_time_)\n      << \"Cannot set UseRealTime and UseManualTime simultaneously.\";\n  use_manual_time_ = true;\n  return this;\n}\n\nBenchmark* Benchmark::Complexity(BigO complexity) {\n  complexity_ = complexity;\n  return this;\n}\n\nBenchmark* Benchmark::Complexity(BigOFunc* complexity) {\n  complexity_lambda_ = complexity;\n  complexity_ = oLambda;\n  return this;\n}\n\nBenchmark* Benchmark::ComputeStatistics(const std::string& name,\n                                        StatisticsFunc* statistics,\n                                        StatisticUnit unit) {\n  statistics_.emplace_back(name, statistics, unit);\n  return this;\n}\n\nBenchmark* Benchmark::Threads(int t) {\n  BM_CHECK_GT(t, 0);\n  thread_counts_.push_back(t);\n  return this;\n}\n\nBenchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {\n  BM_CHECK_GT(min_threads, 0);\n  BM_CHECK_GE(max_threads, min_threads);\n\n  AddRange(&thread_counts_, min_threads, max_threads, 2);\n  return this;\n}\n\nBenchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads,\n                                       int stride) {\n  BM_CHECK_GT(min_threads, 0);\n  BM_CHECK_GE(max_threads, min_threads);\n  BM_CHECK_GE(stride, 1);\n\n  for (auto i = min_threads; i < max_threads; i += stride) {\n    thread_counts_.push_back(i);\n  }\n  thread_counts_.push_back(max_threads);\n  return this;\n}\n\nBenchmark* Benchmark::ThreadPerCpu() {\n  thread_counts_.push_back(CPUInfo::Get().num_cpus);\n  return this;\n}\n\nvoid Benchmark::SetName(const std::string& name) { name_ = name; }\n\nconst char* Benchmark::GetName() const { return name_.c_str(); }\n\nint Benchmark::ArgsCnt() const {\n  if (args_.empty()) {\n    if (arg_names_.empty()) return -1;\n    return static_cast<int>(arg_names_.size());\n  }\n  return static_cast<int>(args_.front().size());\n}\n\nconst char* Benchmark::GetArgName(int arg) const {\n  BM_CHECK_GE(arg, 0);\n  size_t uarg = static_cast<size_t>(arg);\n  BM_CHECK_LT(uarg, arg_names_.size());\n  return arg_names_[uarg].c_str();\n}\n\nTimeUnit Benchmark::GetTimeUnit() const {\n  return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;\n}\n\n//=============================================================================//\n//                            FunctionBenchmark\n//=============================================================================//\n\nvoid FunctionBenchmark::Run(State& st) { func_(st); }\n\n}  // end namespace internal\n\nvoid ClearRegisteredBenchmarks() {\n  internal::BenchmarkFamilies::GetInstance()->ClearBenchmarks();\n}\n\nstd::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi) {\n  std::vector<int64_t> args;\n  internal::AddRange(&args, lo, hi, multi);\n  return args;\n}\n\nstd::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step) {\n  BM_CHECK_LE(start, limit);\n  std::vector<int64_t> args;\n  for (int64_t arg = start; arg <= limit; arg += step) {\n    args.push_back(arg);\n  }\n  return args;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_register.h",
    "content": "#ifndef BENCHMARK_REGISTER_H\n#define BENCHMARK_REGISTER_H\n\n#include <algorithm>\n#include <limits>\n#include <vector>\n\n#include \"check.h\"\n\nnamespace benchmark {\nnamespace internal {\n\n// Append the powers of 'mult' in the closed interval [lo, hi].\n// Returns iterator to the start of the inserted range.\ntemplate <typename T>\ntypename std::vector<T>::iterator AddPowers(std::vector<T>* dst, T lo, T hi,\n                                            int mult) {\n  BM_CHECK_GE(lo, 0);\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_GE(mult, 2);\n\n  const size_t start_offset = dst->size();\n\n  static const T kmax = std::numeric_limits<T>::max();\n\n  // Space out the values in multiples of \"mult\"\n  for (T i = static_cast<T>(1); i <= hi; i = static_cast<T>(i * mult)) {\n    if (i >= lo) {\n      dst->push_back(i);\n    }\n    // Break the loop here since multiplying by\n    // 'mult' would move outside of the range of T\n    if (i > kmax / mult) break;\n  }\n\n  return dst->begin() + static_cast<int>(start_offset);\n}\n\ntemplate <typename T>\nvoid AddNegatedPowers(std::vector<T>* dst, T lo, T hi, int mult) {\n  // We negate lo and hi so we require that they cannot be equal to 'min'.\n  BM_CHECK_GT(lo, std::numeric_limits<T>::min());\n  BM_CHECK_GT(hi, std::numeric_limits<T>::min());\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_LE(hi, 0);\n\n  // Add positive powers, then negate and reverse.\n  // Casts necessary since small integers get promoted\n  // to 'int' when negating.\n  const auto lo_complement = static_cast<T>(-lo);\n  const auto hi_complement = static_cast<T>(-hi);\n\n  const auto it = AddPowers(dst, hi_complement, lo_complement, mult);\n\n  std::for_each(it, dst->end(), [](T& t) { t = static_cast<T>(t * -1); });\n  std::reverse(it, dst->end());\n}\n\ntemplate <typename T>\nvoid AddRange(std::vector<T>* dst, T lo, T hi, int mult) {\n  static_assert(std::is_integral<T>::value && std::is_signed<T>::value,\n                \"Args type must be a signed integer\");\n\n  BM_CHECK_GE(hi, lo);\n  BM_CHECK_GE(mult, 2);\n\n  // Add \"lo\"\n  dst->push_back(lo);\n\n  // Handle lo == hi as a special case, so we then know\n  // lo < hi and so it is safe to add 1 to lo and subtract 1\n  // from hi without falling outside of the range of T.\n  if (lo == hi) return;\n\n  // Ensure that lo_inner <= hi_inner below.\n  if (lo + 1 == hi) {\n    dst->push_back(hi);\n    return;\n  }\n\n  // Add all powers of 'mult' in the range [lo+1, hi-1] (inclusive).\n  const auto lo_inner = static_cast<T>(lo + 1);\n  const auto hi_inner = static_cast<T>(hi - 1);\n\n  // Insert negative values\n  if (lo_inner < 0) {\n    AddNegatedPowers(dst, lo_inner, std::min(hi_inner, T{-1}), mult);\n  }\n\n  // Treat 0 as a special case (see discussion on #762).\n  if (lo < 0 && hi >= 0) {\n    dst->push_back(0);\n  }\n\n  // Insert positive values\n  if (hi_inner > 0) {\n    AddPowers(dst, std::max(lo_inner, T{1}), hi_inner, mult);\n  }\n\n  // Add \"hi\" (if different from last value).\n  if (hi != dst->back()) {\n    dst->push_back(hi);\n  }\n}\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_REGISTER_H\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_runner.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"benchmark_runner.h\"\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark_api_internal.h\"\n#include \"internal_macros.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <climits>\n#include <cmath>\n#include <condition_variable>\n#include <cstdio>\n#include <cstdlib>\n#include <fstream>\n#include <iostream>\n#include <limits>\n#include <memory>\n#include <string>\n#include <thread>\n#include <utility>\n\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n#include \"perf_counters.h\"\n#include \"re.h\"\n#include \"statistics.h\"\n#include \"string_util.h\"\n#include \"thread_manager.h\"\n#include \"thread_timer.h\"\n\nnamespace benchmark {\n\nnamespace internal {\n\nMemoryManager* memory_manager = nullptr;\n\nProfilerManager* profiler_manager = nullptr;\n\nnamespace {\n\nstatic constexpr IterationCount kMaxIterations = 1000000000000;\nconst double kDefaultMinTime =\n    std::strtod(::benchmark::kDefaultMinTimeStr, /*p_end*/ nullptr);\n\nBenchmarkReporter::Run CreateRunReport(\n    const benchmark::internal::BenchmarkInstance& b,\n    const internal::ThreadManager::Result& results,\n    IterationCount memory_iterations,\n    const MemoryManager::Result* memory_result, double seconds,\n    int64_t repetition_index, int64_t repeats) {\n  // Create report about this benchmark run.\n  BenchmarkReporter::Run report;\n\n  report.run_name = b.name();\n  report.family_index = b.family_index();\n  report.per_family_instance_index = b.per_family_instance_index();\n  report.skipped = results.skipped_;\n  report.skip_message = results.skip_message_;\n  report.report_label = results.report_label_;\n  // This is the total iterations across all threads.\n  report.iterations = results.iterations;\n  report.time_unit = b.time_unit();\n  report.threads = b.threads();\n  report.repetition_index = repetition_index;\n  report.repetitions = repeats;\n\n  if (!report.skipped) {\n    if (b.use_manual_time()) {\n      report.real_accumulated_time = results.manual_time_used;\n    } else {\n      report.real_accumulated_time = results.real_time_used;\n    }\n    report.use_real_time_for_initial_big_o = b.use_manual_time();\n    report.cpu_accumulated_time = results.cpu_time_used;\n    report.complexity_n = results.complexity_n;\n    report.complexity = b.complexity();\n    report.complexity_lambda = b.complexity_lambda();\n    report.statistics = &b.statistics();\n    report.counters = results.counters;\n\n    if (memory_iterations > 0) {\n      assert(memory_result != nullptr);\n      report.memory_result = memory_result;\n      report.allocs_per_iter =\n          memory_iterations ? static_cast<double>(memory_result->num_allocs) /\n                                  static_cast<double>(memory_iterations)\n                            : 0;\n    }\n\n    internal::Finish(&report.counters, results.iterations, seconds,\n                     b.threads());\n  }\n  return report;\n}\n\n// Execute one thread of benchmark b for the specified number of iterations.\n// Adds the stats collected for the thread into manager->results.\nvoid RunInThread(const BenchmarkInstance* b, IterationCount iters,\n                 int thread_id, ThreadManager* manager,\n                 PerfCountersMeasurement* perf_counters_measurement) {\n  internal::ThreadTimer timer(\n      b->measure_process_cpu_time()\n          ? internal::ThreadTimer::CreateProcessCpuTime()\n          : internal::ThreadTimer::Create());\n\n  State st =\n      b->Run(iters, thread_id, &timer, manager, perf_counters_measurement);\n  BM_CHECK(st.skipped() || st.iterations() >= st.max_iterations)\n      << \"Benchmark returned before State::KeepRunning() returned false!\";\n  {\n    MutexLock l(manager->GetBenchmarkMutex());\n    internal::ThreadManager::Result& results = manager->results;\n    results.iterations += st.iterations();\n    results.cpu_time_used += timer.cpu_time_used();\n    results.real_time_used += timer.real_time_used();\n    results.manual_time_used += timer.manual_time_used();\n    results.complexity_n += st.complexity_length_n();\n    internal::Increment(&results.counters, st.counters);\n  }\n  manager->NotifyThreadComplete();\n}\n\ndouble ComputeMinTime(const benchmark::internal::BenchmarkInstance& b,\n                      const BenchTimeType& iters_or_time) {\n  if (!IsZero(b.min_time())) return b.min_time();\n  // If the flag was used to specify number of iters, then return the default\n  // min_time.\n  if (iters_or_time.tag == BenchTimeType::ITERS) return kDefaultMinTime;\n\n  return iters_or_time.time;\n}\n\nIterationCount ComputeIters(const benchmark::internal::BenchmarkInstance& b,\n                            const BenchTimeType& iters_or_time) {\n  if (b.iterations() != 0) return b.iterations();\n\n  // We've already concluded that this flag is currently used to pass\n  // iters but do a check here again anyway.\n  BM_CHECK(iters_or_time.tag == BenchTimeType::ITERS);\n  return iters_or_time.iters;\n}\n\n}  // end namespace\n\nBenchTimeType ParseBenchMinTime(const std::string& value) {\n  BenchTimeType ret;\n\n  if (value.empty()) {\n    ret.tag = BenchTimeType::TIME;\n    ret.time = 0.0;\n    return ret;\n  }\n\n  if (value.back() == 'x') {\n    char* p_end;\n    // Reset errno before it's changed by strtol.\n    errno = 0;\n    IterationCount num_iters = std::strtol(value.c_str(), &p_end, 10);\n\n    // After a valid parse, p_end should have been set to\n    // point to the 'x' suffix.\n    BM_CHECK(errno == 0 && p_end != nullptr && *p_end == 'x')\n        << \"Malformed iters value passed to --benchmark_min_time: `\" << value\n        << \"`. Expected --benchmark_min_time=<integer>x.\";\n\n    ret.tag = BenchTimeType::ITERS;\n    ret.iters = num_iters;\n    return ret;\n  }\n\n  bool has_suffix = value.back() == 's';\n  if (!has_suffix) {\n    BM_VLOG(0) << \"Value passed to --benchmark_min_time should have a suffix. \"\n                  \"Eg., `30s` for 30-seconds.\";\n  }\n\n  char* p_end;\n  // Reset errno before it's changed by strtod.\n  errno = 0;\n  double min_time = std::strtod(value.c_str(), &p_end);\n\n  // After a successful parse, p_end should point to the suffix 's',\n  // or the end of the string if the suffix was omitted.\n  BM_CHECK(errno == 0 && p_end != nullptr &&\n           ((has_suffix && *p_end == 's') || *p_end == '\\0'))\n      << \"Malformed seconds value passed to --benchmark_min_time: `\" << value\n      << \"`. Expected --benchmark_min_time=<float>x.\";\n\n  ret.tag = BenchTimeType::TIME;\n  ret.time = min_time;\n\n  return ret;\n}\n\nBenchmarkRunner::BenchmarkRunner(\n    const benchmark::internal::BenchmarkInstance& b_,\n    PerfCountersMeasurement* pcm_,\n    BenchmarkReporter::PerFamilyRunReports* reports_for_family_)\n    : b(b_),\n      reports_for_family(reports_for_family_),\n      parsed_benchtime_flag(ParseBenchMinTime(FLAGS_benchmark_min_time)),\n      min_time(ComputeMinTime(b_, parsed_benchtime_flag)),\n      min_warmup_time((!IsZero(b.min_time()) && b.min_warmup_time() > 0.0)\n                          ? b.min_warmup_time()\n                          : FLAGS_benchmark_min_warmup_time),\n      warmup_done(!(min_warmup_time > 0.0)),\n      repeats(b.repetitions() != 0 ? b.repetitions()\n                                   : FLAGS_benchmark_repetitions),\n      has_explicit_iteration_count(b.iterations() != 0 ||\n                                   parsed_benchtime_flag.tag ==\n                                       BenchTimeType::ITERS),\n      pool(static_cast<size_t>(b.threads() - 1)),\n      iters(has_explicit_iteration_count\n                ? ComputeIters(b_, parsed_benchtime_flag)\n                : 1),\n      perf_counters_measurement_ptr(pcm_) {\n  run_results.display_report_aggregates_only =\n      (FLAGS_benchmark_report_aggregates_only ||\n       FLAGS_benchmark_display_aggregates_only);\n  run_results.file_report_aggregates_only =\n      FLAGS_benchmark_report_aggregates_only;\n  if (b.aggregation_report_mode() != internal::ARM_Unspecified) {\n    run_results.display_report_aggregates_only =\n        (b.aggregation_report_mode() &\n         internal::ARM_DisplayReportAggregatesOnly);\n    run_results.file_report_aggregates_only =\n        (b.aggregation_report_mode() & internal::ARM_FileReportAggregatesOnly);\n    BM_CHECK(FLAGS_benchmark_perf_counters.empty() ||\n             (perf_counters_measurement_ptr->num_counters() == 0))\n        << \"Perf counters were requested but could not be set up.\";\n  }\n}\n\nBenchmarkRunner::IterationResults BenchmarkRunner::DoNIterations() {\n  BM_VLOG(2) << \"Running \" << b.name().str() << \" for \" << iters << \"\\n\";\n\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(b.threads()));\n\n  // Run all but one thread in separate threads\n  for (std::size_t ti = 0; ti < pool.size(); ++ti) {\n    pool[ti] = std::thread(&RunInThread, &b, iters, static_cast<int>(ti + 1),\n                           manager.get(), perf_counters_measurement_ptr);\n  }\n  // And run one thread here directly.\n  // (If we were asked to run just one thread, we don't create new threads.)\n  // Yes, we need to do this here *after* we start the separate threads.\n  RunInThread(&b, iters, 0, manager.get(), perf_counters_measurement_ptr);\n\n  // The main thread has finished. Now let's wait for the other threads.\n  manager->WaitForAllThreads();\n  for (std::thread& thread : pool) thread.join();\n\n  IterationResults i;\n  // Acquire the measurements/counters from the manager, UNDER THE LOCK!\n  {\n    MutexLock l(manager->GetBenchmarkMutex());\n    i.results = manager->results;\n  }\n\n  // And get rid of the manager.\n  manager.reset();\n\n  // Adjust real/manual time stats since they were reported per thread.\n  i.results.real_time_used /= b.threads();\n  i.results.manual_time_used /= b.threads();\n  // If we were measuring whole-process CPU usage, adjust the CPU time too.\n  if (b.measure_process_cpu_time()) i.results.cpu_time_used /= b.threads();\n\n  BM_VLOG(2) << \"Ran in \" << i.results.cpu_time_used << \"/\"\n             << i.results.real_time_used << \"\\n\";\n\n  // By using KeepRunningBatch a benchmark can iterate more times than\n  // requested, so take the iteration count from i.results.\n  i.iters = i.results.iterations / b.threads();\n\n  // Base decisions off of real time if requested by this benchmark.\n  i.seconds = i.results.cpu_time_used;\n  if (b.use_manual_time()) {\n    i.seconds = i.results.manual_time_used;\n  } else if (b.use_real_time()) {\n    i.seconds = i.results.real_time_used;\n  }\n\n  return i;\n}\n\nIterationCount BenchmarkRunner::PredictNumItersNeeded(\n    const IterationResults& i) const {\n  // See how much iterations should be increased by.\n  // Note: Avoid division by zero with max(seconds, 1ns).\n  double multiplier = GetMinTimeToApply() * 1.4 / std::max(i.seconds, 1e-9);\n  // If our last run was at least 10% of FLAGS_benchmark_min_time then we\n  // use the multiplier directly.\n  // Otherwise we use at most 10 times expansion.\n  // NOTE: When the last run was at least 10% of the min time the max\n  // expansion should be 14x.\n  const bool is_significant = (i.seconds / GetMinTimeToApply()) > 0.1;\n  multiplier = is_significant ? multiplier : 10.0;\n\n  // So what seems to be the sufficiently-large iteration count? Round up.\n  const IterationCount max_next_iters = static_cast<IterationCount>(\n      std::llround(std::max(multiplier * static_cast<double>(i.iters),\n                            static_cast<double>(i.iters) + 1.0)));\n  // But we do have *some* limits though..\n  const IterationCount next_iters = std::min(max_next_iters, kMaxIterations);\n\n  BM_VLOG(3) << \"Next iters: \" << next_iters << \", \" << multiplier << \"\\n\";\n  return next_iters;  // round up before conversion to integer.\n}\n\nbool BenchmarkRunner::ShouldReportIterationResults(\n    const IterationResults& i) const {\n  // Determine if this run should be reported;\n  // Either it has run for a sufficient amount of time\n  // or because an error was reported.\n  return i.results.skipped_ ||\n         i.iters >= kMaxIterations ||  // Too many iterations already.\n         i.seconds >=\n             GetMinTimeToApply() ||  // The elapsed time is large enough.\n         // CPU time is specified but the elapsed real time greatly exceeds\n         // the minimum time.\n         // Note that user provided timers are except from this test.\n         ((i.results.real_time_used >= 5 * GetMinTimeToApply()) &&\n          !b.use_manual_time());\n}\n\ndouble BenchmarkRunner::GetMinTimeToApply() const {\n  // In order to re-use functionality to run and measure benchmarks for running\n  // a warmup phase of the benchmark, we need a way of telling whether to apply\n  // min_time or min_warmup_time. This function will figure out if we are in the\n  // warmup phase and therefore need to apply min_warmup_time or if we already\n  // in the benchmarking phase and min_time needs to be applied.\n  return warmup_done ? min_time : min_warmup_time;\n}\n\nvoid BenchmarkRunner::FinishWarmUp(const IterationCount& i) {\n  warmup_done = true;\n  iters = i;\n}\n\nvoid BenchmarkRunner::RunWarmUp() {\n  // Use the same mechanisms for warming up the benchmark as used for actually\n  // running and measuring the benchmark.\n  IterationResults i_warmup;\n  // Dont use the iterations determined in the warmup phase for the actual\n  // measured benchmark phase. While this may be a good starting point for the\n  // benchmark and it would therefore get rid of the need to figure out how many\n  // iterations are needed if min_time is set again, this may also be a complete\n  // wrong guess since the warmup loops might be considerably slower (e.g\n  // because of caching effects).\n  const IterationCount i_backup = iters;\n\n  for (;;) {\n    b.Setup();\n    i_warmup = DoNIterations();\n    b.Teardown();\n\n    const bool finish = ShouldReportIterationResults(i_warmup);\n\n    if (finish) {\n      FinishWarmUp(i_backup);\n      break;\n    }\n\n    // Although we are running \"only\" a warmup phase where running enough\n    // iterations at once without measuring time isn't as important as it is for\n    // the benchmarking phase, we still do it the same way as otherwise it is\n    // very confusing for the user to know how to choose a proper value for\n    // min_warmup_time if a different approach on running it is used.\n    iters = PredictNumItersNeeded(i_warmup);\n    assert(iters > i_warmup.iters &&\n           \"if we did more iterations than we want to do the next time, \"\n           \"then we should have accepted the current iteration run.\");\n  }\n}\n\nMemoryManager::Result* BenchmarkRunner::RunMemoryManager(\n    IterationCount memory_iterations) {\n  // TODO(vyng): Consider making BenchmarkReporter::Run::memory_result an\n  // optional so we don't have to own the Result here.\n  // Can't do it now due to cxx03.\n  memory_results.push_back(MemoryManager::Result());\n  MemoryManager::Result* memory_result = &memory_results.back();\n  memory_manager->Start();\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(1));\n  b.Setup();\n  RunInThread(&b, memory_iterations, 0, manager.get(),\n              perf_counters_measurement_ptr);\n  manager->WaitForAllThreads();\n  manager.reset();\n  b.Teardown();\n  memory_manager->Stop(*memory_result);\n  return memory_result;\n}\n\nvoid BenchmarkRunner::RunProfilerManager() {\n  // TODO: Provide a way to specify the number of iterations.\n  IterationCount profile_iterations = 1;\n  std::unique_ptr<internal::ThreadManager> manager;\n  manager.reset(new internal::ThreadManager(1));\n  b.Setup();\n  profiler_manager->AfterSetupStart();\n  RunInThread(&b, profile_iterations, 0, manager.get(),\n              /*perf_counters_measurement_ptr=*/nullptr);\n  manager->WaitForAllThreads();\n  profiler_manager->BeforeTeardownStop();\n  manager.reset();\n  b.Teardown();\n}\n\nvoid BenchmarkRunner::DoOneRepetition() {\n  assert(HasRepeatsRemaining() && \"Already done all repetitions?\");\n\n  const bool is_the_first_repetition = num_repetitions_done == 0;\n\n  // In case a warmup phase is requested by the benchmark, run it now.\n  // After running the warmup phase the BenchmarkRunner should be in a state as\n  // this warmup never happened except the fact that warmup_done is set. Every\n  // other manipulation of the BenchmarkRunner instance would be a bug! Please\n  // fix it.\n  if (!warmup_done) RunWarmUp();\n\n  IterationResults i;\n  // We *may* be gradually increasing the length (iteration count)\n  // of the benchmark until we decide the results are significant.\n  // And once we do, we report those last results and exit.\n  // Please do note that the if there are repetitions, the iteration count\n  // is *only* calculated for the *first* repetition, and other repetitions\n  // simply use that precomputed iteration count.\n  for (;;) {\n    b.Setup();\n    i = DoNIterations();\n    b.Teardown();\n\n    // Do we consider the results to be significant?\n    // If we are doing repetitions, and the first repetition was already done,\n    // it has calculated the correct iteration time, so we have run that very\n    // iteration count just now. No need to calculate anything. Just report.\n    // Else, the normal rules apply.\n    const bool results_are_significant = !is_the_first_repetition ||\n                                         has_explicit_iteration_count ||\n                                         ShouldReportIterationResults(i);\n\n    if (results_are_significant) break;  // Good, let's report them!\n\n    // Nope, bad iteration. Let's re-estimate the hopefully-sufficient\n    // iteration count, and run the benchmark again...\n\n    iters = PredictNumItersNeeded(i);\n    assert(iters > i.iters &&\n           \"if we did more iterations than we want to do the next time, \"\n           \"then we should have accepted the current iteration run.\");\n  }\n\n  // Produce memory measurements if requested.\n  MemoryManager::Result* memory_result = nullptr;\n  IterationCount memory_iterations = 0;\n  if (memory_manager != nullptr) {\n    // Only run a few iterations to reduce the impact of one-time\n    // allocations in benchmarks that are not properly managed.\n    memory_iterations = std::min<IterationCount>(16, iters);\n    memory_result = RunMemoryManager(memory_iterations);\n  }\n\n  if (profiler_manager != nullptr) {\n    RunProfilerManager();\n  }\n\n  // Ok, now actually report.\n  BenchmarkReporter::Run report =\n      CreateRunReport(b, i.results, memory_iterations, memory_result, i.seconds,\n                      num_repetitions_done, repeats);\n\n  if (reports_for_family) {\n    ++reports_for_family->num_runs_done;\n    if (!report.skipped) reports_for_family->Runs.push_back(report);\n  }\n\n  run_results.non_aggregates.push_back(report);\n\n  ++num_repetitions_done;\n}\n\nRunResults&& BenchmarkRunner::GetResults() {\n  assert(!HasRepeatsRemaining() && \"Did not run all repetitions yet?\");\n\n  // Calculate additional statistics over the repetitions of this instance.\n  run_results.aggregates_only = ComputeStats(run_results.non_aggregates);\n\n  return std::move(run_results);\n}\n\n}  // end namespace internal\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/benchmark_runner.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_RUNNER_H_\n#define BENCHMARK_RUNNER_H_\n\n#include <thread>\n#include <vector>\n\n#include \"benchmark_api_internal.h\"\n#include \"internal_macros.h\"\n#include \"perf_counters.h\"\n#include \"thread_manager.h\"\n\nnamespace benchmark {\n\nBM_DECLARE_string(benchmark_min_time);\nBM_DECLARE_double(benchmark_min_warmup_time);\nBM_DECLARE_int32(benchmark_repetitions);\nBM_DECLARE_bool(benchmark_report_aggregates_only);\nBM_DECLARE_bool(benchmark_display_aggregates_only);\nBM_DECLARE_string(benchmark_perf_counters);\n\nnamespace internal {\n\nextern MemoryManager* memory_manager;\nextern ProfilerManager* profiler_manager;\n\nstruct RunResults {\n  std::vector<BenchmarkReporter::Run> non_aggregates;\n  std::vector<BenchmarkReporter::Run> aggregates_only;\n\n  bool display_report_aggregates_only = false;\n  bool file_report_aggregates_only = false;\n};\n\nstruct BENCHMARK_EXPORT BenchTimeType {\n  enum { ITERS, TIME } tag;\n  union {\n    IterationCount iters;\n    double time;\n  };\n};\n\nBENCHMARK_EXPORT\nBenchTimeType ParseBenchMinTime(const std::string& value);\n\nclass BenchmarkRunner {\n public:\n  BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_,\n                  benchmark::internal::PerfCountersMeasurement* pmc_,\n                  BenchmarkReporter::PerFamilyRunReports* reports_for_family);\n\n  int GetNumRepeats() const { return repeats; }\n\n  bool HasRepeatsRemaining() const {\n    return GetNumRepeats() != num_repetitions_done;\n  }\n\n  void DoOneRepetition();\n\n  RunResults&& GetResults();\n\n  BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const {\n    return reports_for_family;\n  }\n\n  double GetMinTime() const { return min_time; }\n\n  bool HasExplicitIters() const { return has_explicit_iteration_count; }\n\n  IterationCount GetIters() const { return iters; }\n\n private:\n  RunResults run_results;\n\n  const benchmark::internal::BenchmarkInstance& b;\n  BenchmarkReporter::PerFamilyRunReports* reports_for_family;\n\n  BenchTimeType parsed_benchtime_flag;\n  const double min_time;\n  const double min_warmup_time;\n  bool warmup_done;\n  const int repeats;\n  const bool has_explicit_iteration_count;\n\n  int num_repetitions_done = 0;\n\n  std::vector<std::thread> pool;\n\n  std::vector<MemoryManager::Result> memory_results;\n\n  IterationCount iters;  // preserved between repetitions!\n  // So only the first repetition has to find/calculate it,\n  // the other repetitions will just use that precomputed iteration count.\n\n  PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr;\n\n  struct IterationResults {\n    internal::ThreadManager::Result results;\n    IterationCount iters;\n    double seconds;\n  };\n  IterationResults DoNIterations();\n\n  MemoryManager::Result* RunMemoryManager(IterationCount memory_iterations);\n\n  void RunProfilerManager();\n\n  IterationCount PredictNumItersNeeded(const IterationResults& i) const;\n\n  bool ShouldReportIterationResults(const IterationResults& i) const;\n\n  double GetMinTimeToApply() const;\n\n  void FinishWarmUp(const IterationCount& i);\n\n  void RunWarmUp();\n};\n\n}  // namespace internal\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_RUNNER_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/check.cc",
    "content": "#include \"check.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nstatic AbortHandlerT* handler = &std::abort;\n\nBENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; }\n\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/check.h",
    "content": "#ifndef CHECK_H_\n#define CHECK_H_\n\n#include <cmath>\n#include <cstdlib>\n#include <ostream>\n\n#include \"benchmark/export.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n\n#if defined(__GNUC__) || defined(__clang__)\n#define BENCHMARK_NOEXCEPT noexcept\n#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)\n#elif defined(_MSC_VER) && !defined(__clang__)\n#if _MSC_VER >= 1900\n#define BENCHMARK_NOEXCEPT noexcept\n#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)\n#else\n#define BENCHMARK_NOEXCEPT\n#define BENCHMARK_NOEXCEPT_OP(x)\n#endif\n#define __func__ __FUNCTION__\n#else\n#define BENCHMARK_NOEXCEPT\n#define BENCHMARK_NOEXCEPT_OP(x)\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\ntypedef void(AbortHandlerT)();\n\nBENCHMARK_EXPORT\nAbortHandlerT*& GetAbortHandler();\n\nBENCHMARK_NORETURN inline void CallAbortHandler() {\n  GetAbortHandler()();\n  std::abort();  // fallback to enforce noreturn\n}\n\n// CheckHandler is the class constructed by failing BM_CHECK macros.\n// CheckHandler will log information about the failures and abort when it is\n// destructed.\nclass CheckHandler {\n public:\n  CheckHandler(const char* check, const char* file, const char* func, int line)\n      : log_(GetErrorLogInstance()) {\n    log_ << file << \":\" << line << \": \" << func << \": Check `\" << check\n         << \"' failed. \";\n  }\n\n  LogType& GetLog() { return log_; }\n\n#if defined(COMPILER_MSVC)\n#pragma warning(push)\n#pragma warning(disable : 4722)\n#endif\n  BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {\n    log_ << std::endl;\n    CallAbortHandler();\n  }\n#if defined(COMPILER_MSVC)\n#pragma warning(pop)\n#endif\n\n  CheckHandler& operator=(const CheckHandler&) = delete;\n  CheckHandler(const CheckHandler&) = delete;\n  CheckHandler() = delete;\n\n private:\n  LogType& log_;\n};\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n// The BM_CHECK macro returns a std::ostream object that can have extra\n// information written to it.\n#ifndef NDEBUG\n#define BM_CHECK(b)                                                          \\\n  (b ? ::benchmark::internal::GetNullLogInstance()                           \\\n     : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \\\n           .GetLog())\n#else\n#define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()\n#endif\n\n// clang-format off\n// preserve whitespacing between operators for alignment\n#define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))\n#define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))\n#define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))\n#define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))\n#define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))\n#define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))\n\n#define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) <  (eps))\n#define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))\n#define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))\n#define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))\n#define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) >  (eps))\n#define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) >  (eps))\n//clang-format on\n\n#endif  // CHECK_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/colorprint.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"colorprint.h\"\n\n#include <cstdarg>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <memory>\n#include <string>\n\n#include \"check.h\"\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#include <io.h>\n#include <windows.h>\n#else\n#include <unistd.h>\n#endif  // BENCHMARK_OS_WINDOWS\n\nnamespace benchmark {\nnamespace {\n#ifdef BENCHMARK_OS_WINDOWS\ntypedef WORD PlatformColorCode;\n#else\ntypedef const char* PlatformColorCode;\n#endif\n\nPlatformColorCode GetPlatformColorCode(LogColor color) {\n#ifdef BENCHMARK_OS_WINDOWS\n  switch (color) {\n    case COLOR_RED:\n      return FOREGROUND_RED;\n    case COLOR_GREEN:\n      return FOREGROUND_GREEN;\n    case COLOR_YELLOW:\n      return FOREGROUND_RED | FOREGROUND_GREEN;\n    case COLOR_BLUE:\n      return FOREGROUND_BLUE;\n    case COLOR_MAGENTA:\n      return FOREGROUND_BLUE | FOREGROUND_RED;\n    case COLOR_CYAN:\n      return FOREGROUND_BLUE | FOREGROUND_GREEN;\n    case COLOR_WHITE:  // fall through to default\n    default:\n      return 0;\n  }\n#else\n  switch (color) {\n    case COLOR_RED:\n      return \"1\";\n    case COLOR_GREEN:\n      return \"2\";\n    case COLOR_YELLOW:\n      return \"3\";\n    case COLOR_BLUE:\n      return \"4\";\n    case COLOR_MAGENTA:\n      return \"5\";\n    case COLOR_CYAN:\n      return \"6\";\n    case COLOR_WHITE:\n      return \"7\";\n    default:\n      return nullptr;\n  };\n#endif\n}\n\n}  // end namespace\n\nstd::string FormatString(const char* msg, va_list args) {\n  // we might need a second shot at this, so pre-emptivly make a copy\n  va_list args_cp;\n  va_copy(args_cp, args);\n\n  std::size_t size = 256;\n  char local_buff[256];\n  auto ret = vsnprintf(local_buff, size, msg, args_cp);\n\n  va_end(args_cp);\n\n  // currently there is no error handling for failure, so this is hack.\n  BM_CHECK(ret >= 0);\n\n  if (ret == 0) {  // handle empty expansion\n    return {};\n  }\n  if (static_cast<size_t>(ret) < size) {\n    return local_buff;\n  }\n  // we did not provide a long enough buffer on our first attempt.\n  size = static_cast<size_t>(ret) + 1;  // + 1 for the null byte\n  std::unique_ptr<char[]> buff(new char[size]);\n  ret = vsnprintf(buff.get(), size, msg, args);\n  BM_CHECK(ret > 0 && (static_cast<size_t>(ret)) < size);\n  return buff.get();\n}\n\nstd::string FormatString(const char* msg, ...) {\n  va_list args;\n  va_start(args, msg);\n  auto tmp = FormatString(msg, args);\n  va_end(args);\n  return tmp;\n}\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  ColorPrintf(out, color, fmt, args);\n  va_end(args);\n}\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt,\n                 va_list args) {\n#ifdef BENCHMARK_OS_WINDOWS\n  ((void)out);  // suppress unused warning\n\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\n\n  // Gets the current text color.\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\n  const WORD old_color_attrs = buffer_info.wAttributes;\n\n  // We need to flush the stream buffers into the console before each\n  // SetConsoleTextAttribute call lest it affect the text that is already\n  // printed but has not yet reached the console.\n  out.flush();\n  SetConsoleTextAttribute(stdout_handle,\n                          GetPlatformColorCode(color) | FOREGROUND_INTENSITY);\n  out << FormatString(fmt, args);\n\n  out.flush();\n  // Restores the text color.\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\n#else\n  const char* color_code = GetPlatformColorCode(color);\n  if (color_code) out << FormatString(\"\\033[0;3%sm\", color_code);\n  out << FormatString(fmt, args) << \"\\033[m\";\n#endif\n}\n\nbool IsColorTerminal() {\n#if BENCHMARK_OS_WINDOWS\n  // On Windows the TERM variable is usually not set, but the\n  // console there does support colors.\n  return 0 != _isatty(_fileno(stdout));\n#else\n  // On non-Windows platforms, we rely on the TERM variable. This list of\n  // supported TERM values is copied from Google Test:\n  // <https://github.com/google/googletest/blob/v1.13.0/googletest/src/gtest.cc#L3225-L3259>.\n  const char* const SUPPORTED_TERM_VALUES[] = {\n      \"xterm\",\n      \"xterm-color\",\n      \"xterm-256color\",\n      \"screen\",\n      \"screen-256color\",\n      \"tmux\",\n      \"tmux-256color\",\n      \"rxvt-unicode\",\n      \"rxvt-unicode-256color\",\n      \"linux\",\n      \"cygwin\",\n      \"xterm-kitty\",\n      \"alacritty\",\n      \"foot\",\n      \"foot-extra\",\n      \"wezterm\",\n  };\n\n  const char* const term = getenv(\"TERM\");\n\n  bool term_supports_color = false;\n  for (const char* candidate : SUPPORTED_TERM_VALUES) {\n    if (term && 0 == strcmp(term, candidate)) {\n      term_supports_color = true;\n      break;\n    }\n  }\n\n  return 0 != isatty(fileno(stdout)) && term_supports_color;\n#endif  // BENCHMARK_OS_WINDOWS\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/colorprint.h",
    "content": "#ifndef BENCHMARK_COLORPRINT_H_\n#define BENCHMARK_COLORPRINT_H_\n\n#include <cstdarg>\n#include <iostream>\n#include <string>\n\nnamespace benchmark {\nenum LogColor {\n  COLOR_DEFAULT,\n  COLOR_RED,\n  COLOR_GREEN,\n  COLOR_YELLOW,\n  COLOR_BLUE,\n  COLOR_MAGENTA,\n  COLOR_CYAN,\n  COLOR_WHITE\n};\n\nstd::string FormatString(const char* msg, va_list args);\nstd::string FormatString(const char* msg, ...);\n\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt,\n                 va_list args);\nvoid ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);\n\n// Returns true if stdout appears to be a terminal that supports colored\n// output, false otherwise.\nbool IsColorTerminal();\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COLORPRINT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/commandlineflags.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"commandlineflags.h\"\n\n#include <algorithm>\n#include <cctype>\n#include <cstdlib>\n#include <cstring>\n#include <iostream>\n#include <limits>\n#include <map>\n#include <utility>\n\n#include \"../src/string_util.h\"\n\nnamespace benchmark {\nnamespace {\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\n// the result to *value and returns true; otherwise leaves *value\n// unchanged and returns false.\nbool ParseInt32(const std::string& src_text, const char* str, int32_t* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const long long_value = strtol(str, &end, 10);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    std::cerr << src_text << \" is expected to be a 32-bit integer, \"\n              << \"but actually has value \\\"\" << str << \"\\\".\\n\";\n    return false;\n  }\n\n  // Is the parsed value in the range of an Int32?\n  const int32_t result = static_cast<int32_t>(long_value);\n  if (long_value == std::numeric_limits<long>::max() ||\n      long_value == std::numeric_limits<long>::min() ||\n      // The parsed value overflows as a long.  (strtol() returns\n      // LONG_MAX or LONG_MIN when the input overflows.)\n      result != long_value\n      // The parsed value overflows as an Int32.\n  ) {\n    std::cerr << src_text << \" is expected to be a 32-bit integer, \"\n              << \"but actually has value \\\"\" << str << \"\\\", \"\n              << \"which overflows.\\n\";\n    return false;\n  }\n\n  *value = result;\n  return true;\n}\n\n// Parses 'str' for a double.  If successful, writes the result to *value and\n// returns true; otherwise leaves *value unchanged and returns false.\nbool ParseDouble(const std::string& src_text, const char* str, double* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const double double_value = strtod(str, &end);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    std::cerr << src_text << \" is expected to be a double, \"\n              << \"but actually has value \\\"\" << str << \"\\\".\\n\";\n    return false;\n  }\n\n  *value = double_value;\n  return true;\n}\n\n// Parses 'str' into KV pairs. If successful, writes the result to *value and\n// returns true; otherwise leaves *value unchanged and returns false.\nbool ParseKvPairs(const std::string& src_text, const char* str,\n                  std::map<std::string, std::string>* value) {\n  std::map<std::string, std::string> kvs;\n  for (const auto& kvpair : StrSplit(str, ',')) {\n    const auto kv = StrSplit(kvpair, '=');\n    if (kv.size() != 2) {\n      std::cerr << src_text << \" is expected to be a comma-separated list of \"\n                << \"<key>=<value> strings, but actually has value \\\"\" << str\n                << \"\\\".\\n\";\n      return false;\n    }\n    if (!kvs.emplace(kv[0], kv[1]).second) {\n      std::cerr << src_text << \" is expected to contain unique keys but key \\\"\"\n                << kv[0] << \"\\\" was repeated.\\n\";\n      return false;\n    }\n  }\n\n  *value = kvs;\n  return true;\n}\n\n// Returns the name of the environment variable corresponding to the\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\n// \"BENCHMARK_FOO\" in the open-source version.\nstatic std::string FlagToEnvVar(const char* flag) {\n  const std::string flag_str(flag);\n\n  std::string env_var;\n  for (size_t i = 0; i != flag_str.length(); ++i)\n    env_var += static_cast<char>(::toupper(flag_str.c_str()[i]));\n\n  return env_var;\n}\n\n}  // namespace\n\nBENCHMARK_EXPORT\nbool BoolFromEnv(const char* flag, bool default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  return value_str == nullptr ? default_val : IsTruthyFlagValue(value_str);\n}\n\nBENCHMARK_EXPORT\nint32_t Int32FromEnv(const char* flag, int32_t default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  int32_t value = default_val;\n  if (value_str == nullptr ||\n      !ParseInt32(std::string(\"Environment variable \") + env_var, value_str,\n                  &value)) {\n    return default_val;\n  }\n  return value;\n}\n\nBENCHMARK_EXPORT\ndouble DoubleFromEnv(const char* flag, double default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n  double value = default_val;\n  if (value_str == nullptr ||\n      !ParseDouble(std::string(\"Environment variable \") + env_var, value_str,\n                   &value)) {\n    return default_val;\n  }\n  return value;\n}\n\nBENCHMARK_EXPORT\nconst char* StringFromEnv(const char* flag, const char* default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value = getenv(env_var.c_str());\n  return value == nullptr ? default_val : value;\n}\n\nBENCHMARK_EXPORT\nstd::map<std::string, std::string> KvPairsFromEnv(\n    const char* flag, std::map<std::string, std::string> default_val) {\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value_str = getenv(env_var.c_str());\n\n  if (value_str == nullptr) return default_val;\n\n  std::map<std::string, std::string> value;\n  if (!ParseKvPairs(\"Environment variable \" + env_var, value_str, &value)) {\n    return default_val;\n  }\n  return value;\n}\n\n// Parses a string as a command line flag.  The string should have\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\n// part can be omitted.\n//\n// Returns the value of the flag, or nullptr if the parsing failed.\nconst char* ParseFlagValue(const char* str, const char* flag,\n                           bool def_optional) {\n  // str and flag must not be nullptr.\n  if (str == nullptr || flag == nullptr) return nullptr;\n\n  // The flag must start with \"--\".\n  const std::string flag_str = std::string(\"--\") + std::string(flag);\n  const size_t flag_len = flag_str.length();\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) return flag_end;\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\nBENCHMARK_EXPORT\nbool ParseBoolFlag(const char* str, const char* flag, bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = IsTruthyFlagValue(value_str);\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(std::string(\"The value of flag --\") + flag, value_str,\n                    value);\n}\n\nBENCHMARK_EXPORT\nbool ParseDoubleFlag(const char* str, const char* flag, double* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseDouble(std::string(\"The value of flag --\") + flag, value_str,\n                     value);\n}\n\nBENCHMARK_EXPORT\nbool ParseStringFlag(const char* str, const char* flag, std::string* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  *value = value_str;\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool ParseKeyValueFlag(const char* str, const char* flag,\n                       std::map<std::string, std::string>* value) {\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  if (value_str == nullptr) return false;\n\n  for (const auto& kvpair : StrSplit(value_str, ',')) {\n    const auto kv = StrSplit(kvpair, '=');\n    if (kv.size() != 2) return false;\n    value->emplace(kv[0], kv[1]);\n  }\n\n  return true;\n}\n\nBENCHMARK_EXPORT\nbool IsFlag(const char* str, const char* flag) {\n  return (ParseFlagValue(str, flag, true) != nullptr);\n}\n\nBENCHMARK_EXPORT\nbool IsTruthyFlagValue(const std::string& value) {\n  if (value.size() == 1) {\n    char v = value[0];\n    return isalnum(v) &&\n           !(v == '0' || v == 'f' || v == 'F' || v == 'n' || v == 'N');\n  }\n  if (!value.empty()) {\n    std::string value_lower(value);\n    std::transform(value_lower.begin(), value_lower.end(), value_lower.begin(),\n                   [](char c) { return static_cast<char>(::tolower(c)); });\n    return !(value_lower == \"false\" || value_lower == \"no\" ||\n             value_lower == \"off\");\n  }\n  return true;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/commandlineflags.h",
    "content": "#ifndef BENCHMARK_COMMANDLINEFLAGS_H_\n#define BENCHMARK_COMMANDLINEFLAGS_H_\n\n#include <cstdint>\n#include <map>\n#include <string>\n\n#include \"benchmark/export.h\"\n\n// Macro for referencing flags.\n#define FLAG(name) FLAGS_##name\n\n// Macros for declaring flags.\n#define BM_DECLARE_bool(name) BENCHMARK_EXPORT extern bool FLAG(name)\n#define BM_DECLARE_int32(name) BENCHMARK_EXPORT extern int32_t FLAG(name)\n#define BM_DECLARE_double(name) BENCHMARK_EXPORT extern double FLAG(name)\n#define BM_DECLARE_string(name) BENCHMARK_EXPORT extern std::string FLAG(name)\n#define BM_DECLARE_kvpairs(name) \\\n  BENCHMARK_EXPORT extern std::map<std::string, std::string> FLAG(name)\n\n// Macros for defining flags.\n#define BM_DEFINE_bool(name, default_val) \\\n  BENCHMARK_EXPORT bool FLAG(name) = benchmark::BoolFromEnv(#name, default_val)\n#define BM_DEFINE_int32(name, default_val) \\\n  BENCHMARK_EXPORT int32_t FLAG(name) =    \\\n      benchmark::Int32FromEnv(#name, default_val)\n#define BM_DEFINE_double(name, default_val) \\\n  BENCHMARK_EXPORT double FLAG(name) =      \\\n      benchmark::DoubleFromEnv(#name, default_val)\n#define BM_DEFINE_string(name, default_val) \\\n  BENCHMARK_EXPORT std::string FLAG(name) = \\\n      benchmark::StringFromEnv(#name, default_val)\n#define BM_DEFINE_kvpairs(name, default_val)                       \\\n  BENCHMARK_EXPORT std::map<std::string, std::string> FLAG(name) = \\\n      benchmark::KvPairsFromEnv(#name, default_val)\n\nnamespace benchmark {\n\n// Parses a bool from the environment variable corresponding to the given flag.\n//\n// If the variable exists, returns IsTruthyFlagValue() value;  if not,\n// returns the given default value.\nBENCHMARK_EXPORT\nbool BoolFromEnv(const char* flag, bool default_val);\n\n// Parses an Int32 from the environment variable corresponding to the given\n// flag.\n//\n// If the variable exists, returns ParseInt32() value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nint32_t Int32FromEnv(const char* flag, int32_t default_val);\n\n// Parses an Double from the environment variable corresponding to the given\n// flag.\n//\n// If the variable exists, returns ParseDouble();  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\ndouble DoubleFromEnv(const char* flag, double default_val);\n\n// Parses a string from the environment variable corresponding to the given\n// flag.\n//\n// If variable exists, returns its value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nconst char* StringFromEnv(const char* flag, const char* default_val);\n\n// Parses a set of kvpairs from the environment variable corresponding to the\n// given flag.\n//\n// If variable exists, returns its value;  if not, returns\n// the given default value.\nBENCHMARK_EXPORT\nstd::map<std::string, std::string> KvPairsFromEnv(\n    const char* flag, std::map<std::string, std::string> default_val);\n\n// Parses a string for a bool flag, in the form of either\n// \"--flag=value\" or \"--flag\".\n//\n// In the former case, the value is taken as true if it passes IsTruthyValue().\n//\n// In the latter case, the value is taken as true.\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseBoolFlag(const char* str, const char* flag, bool* value);\n\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseInt32Flag(const char* str, const char* flag, int32_t* value);\n\n// Parses a string for a Double flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseDoubleFlag(const char* str, const char* flag, double* value);\n\n// Parses a string for a string flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nBENCHMARK_EXPORT\nbool ParseStringFlag(const char* str, const char* flag, std::string* value);\n\n// Parses a string for a kvpairs flag in the form \"--flag=key=value,key=value\"\n//\n// On success, stores the value of the flag in *value and returns true. On\n// failure returns false, though *value may have been mutated.\nBENCHMARK_EXPORT\nbool ParseKeyValueFlag(const char* str, const char* flag,\n                       std::map<std::string, std::string>* value);\n\n// Returns true if the string matches the flag.\nBENCHMARK_EXPORT\nbool IsFlag(const char* str, const char* flag);\n\n// Returns true unless value starts with one of: '0', 'f', 'F', 'n' or 'N', or\n// some non-alphanumeric character. Also returns false if the value matches\n// one of 'no', 'false', 'off' (case-insensitive). As a special case, also\n// returns true if value is the empty string.\nBENCHMARK_EXPORT\nbool IsTruthyFlagValue(const std::string& value);\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COMMANDLINEFLAGS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/complexity.cc",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Source project : https://github.com/ismaelJimenez/cpp.leastsq\n// Adapted to be used with google benchmark\n\n#include \"complexity.h\"\n\n#include <algorithm>\n#include <cmath>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n\nnamespace benchmark {\n\n// Internal function to calculate the different scalability forms\nBigOFunc* FittingCurve(BigO complexity) {\n  switch (complexity) {\n    case oN:\n      return [](IterationCount n) -> double { return static_cast<double>(n); };\n    case oNSquared:\n      return [](IterationCount n) -> double { return std::pow(n, 2); };\n    case oNCubed:\n      return [](IterationCount n) -> double { return std::pow(n, 3); };\n    case oLogN:\n      return [](IterationCount n) -> double {\n        return std::log2(static_cast<double>(n));\n      };\n    case oNLogN:\n      return [](IterationCount n) -> double {\n        return static_cast<double>(n) * std::log2(static_cast<double>(n));\n      };\n    case o1:\n    default:\n      return [](IterationCount) { return 1.0; };\n  }\n}\n\n// Function to return an string for the calculated complexity\nstd::string GetBigOString(BigO complexity) {\n  switch (complexity) {\n    case oN:\n      return \"N\";\n    case oNSquared:\n      return \"N^2\";\n    case oNCubed:\n      return \"N^3\";\n    case oLogN:\n      return \"lgN\";\n    case oNLogN:\n      return \"NlgN\";\n    case o1:\n      return \"(1)\";\n    default:\n      return \"f(N)\";\n  }\n}\n\n// Find the coefficient for the high-order term in the running time, by\n// minimizing the sum of squares of relative error, for the fitting curve\n// given by the lambda expression.\n//   - n             : Vector containing the size of the benchmark tests.\n//   - time          : Vector containing the times for the benchmark tests.\n//   - fitting_curve : lambda expression (e.g. [](ComplexityN n) {return n; };).\n\n// For a deeper explanation on the algorithm logic, please refer to\n// https://en.wikipedia.org/wiki/Least_squares#Least_squares,_regression_analysis_and_statistics\n\nLeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,\n                       const std::vector<double>& time,\n                       BigOFunc* fitting_curve) {\n  double sigma_gn_squared = 0.0;\n  double sigma_time = 0.0;\n  double sigma_time_gn = 0.0;\n\n  // Calculate least square fitting parameter\n  for (size_t i = 0; i < n.size(); ++i) {\n    double gn_i = fitting_curve(n[i]);\n    sigma_gn_squared += gn_i * gn_i;\n    sigma_time += time[i];\n    sigma_time_gn += time[i] * gn_i;\n  }\n\n  LeastSq result;\n  result.complexity = oLambda;\n\n  // Calculate complexity.\n  result.coef = sigma_time_gn / sigma_gn_squared;\n\n  // Calculate RMS\n  double rms = 0.0;\n  for (size_t i = 0; i < n.size(); ++i) {\n    double fit = result.coef * fitting_curve(n[i]);\n    rms += std::pow((time[i] - fit), 2);\n  }\n\n  // Normalized RMS by the mean of the observed values\n  double mean = sigma_time / static_cast<double>(n.size());\n  result.rms = std::sqrt(rms / static_cast<double>(n.size())) / mean;\n\n  return result;\n}\n\n// Find the coefficient for the high-order term in the running time, by\n// minimizing the sum of squares of relative error.\n//   - n          : Vector containing the size of the benchmark tests.\n//   - time       : Vector containing the times for the benchmark tests.\n//   - complexity : If different than oAuto, the fitting curve will stick to\n//                  this one. If it is oAuto, it will be calculated the best\n//                  fitting curve.\nLeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,\n                       const std::vector<double>& time, const BigO complexity) {\n  BM_CHECK_EQ(n.size(), time.size());\n  BM_CHECK_GE(n.size(), 2);  // Do not compute fitting curve is less than two\n                             // benchmark runs are given\n  BM_CHECK_NE(complexity, oNone);\n\n  LeastSq best_fit;\n\n  if (complexity == oAuto) {\n    std::vector<BigO> fit_curves = {oLogN, oN, oNLogN, oNSquared, oNCubed};\n\n    // Take o1 as default best fitting curve\n    best_fit = MinimalLeastSq(n, time, FittingCurve(o1));\n    best_fit.complexity = o1;\n\n    // Compute all possible fitting curves and stick to the best one\n    for (const auto& fit : fit_curves) {\n      LeastSq current_fit = MinimalLeastSq(n, time, FittingCurve(fit));\n      if (current_fit.rms < best_fit.rms) {\n        best_fit = current_fit;\n        best_fit.complexity = fit;\n      }\n    }\n  } else {\n    best_fit = MinimalLeastSq(n, time, FittingCurve(complexity));\n    best_fit.complexity = complexity;\n  }\n\n  return best_fit;\n}\n\nstd::vector<BenchmarkReporter::Run> ComputeBigO(\n    const std::vector<BenchmarkReporter::Run>& reports) {\n  typedef BenchmarkReporter::Run Run;\n  std::vector<Run> results;\n\n  if (reports.size() < 2) return results;\n\n  // Accumulators.\n  std::vector<ComplexityN> n;\n  std::vector<double> real_time;\n  std::vector<double> cpu_time;\n\n  // Populate the accumulators.\n  for (const Run& run : reports) {\n    BM_CHECK_GT(run.complexity_n, 0)\n        << \"Did you forget to call SetComplexityN?\";\n    n.push_back(run.complexity_n);\n    real_time.push_back(run.real_accumulated_time /\n                        static_cast<double>(run.iterations));\n    cpu_time.push_back(run.cpu_accumulated_time /\n                       static_cast<double>(run.iterations));\n  }\n\n  LeastSq result_cpu;\n  LeastSq result_real;\n\n  if (reports[0].complexity == oLambda) {\n    result_cpu = MinimalLeastSq(n, cpu_time, reports[0].complexity_lambda);\n    result_real = MinimalLeastSq(n, real_time, reports[0].complexity_lambda);\n  } else {\n    const BigO* InitialBigO = &reports[0].complexity;\n    const bool use_real_time_for_initial_big_o =\n        reports[0].use_real_time_for_initial_big_o;\n    if (use_real_time_for_initial_big_o) {\n      result_real = MinimalLeastSq(n, real_time, *InitialBigO);\n      InitialBigO = &result_real.complexity;\n      // The Big-O complexity for CPU time must have the same Big-O function!\n    }\n    result_cpu = MinimalLeastSq(n, cpu_time, *InitialBigO);\n    InitialBigO = &result_cpu.complexity;\n    if (!use_real_time_for_initial_big_o) {\n      result_real = MinimalLeastSq(n, real_time, *InitialBigO);\n    }\n  }\n\n  // Drop the 'args' when reporting complexity.\n  auto run_name = reports[0].run_name;\n  run_name.args.clear();\n\n  // Get the data from the accumulator to BenchmarkReporter::Run's.\n  Run big_o;\n  big_o.run_name = run_name;\n  big_o.family_index = reports[0].family_index;\n  big_o.per_family_instance_index = reports[0].per_family_instance_index;\n  big_o.run_type = BenchmarkReporter::Run::RT_Aggregate;\n  big_o.repetitions = reports[0].repetitions;\n  big_o.repetition_index = Run::no_repetition_index;\n  big_o.threads = reports[0].threads;\n  big_o.aggregate_name = \"BigO\";\n  big_o.aggregate_unit = StatisticUnit::kTime;\n  big_o.report_label = reports[0].report_label;\n  big_o.iterations = 0;\n  big_o.real_accumulated_time = result_real.coef;\n  big_o.cpu_accumulated_time = result_cpu.coef;\n  big_o.report_big_o = true;\n  big_o.complexity = result_cpu.complexity;\n\n  // All the time results are reported after being multiplied by the\n  // time unit multiplier. But since RMS is a relative quantity it\n  // should not be multiplied at all. So, here, we _divide_ it by the\n  // multiplier so that when it is multiplied later the result is the\n  // correct one.\n  double multiplier = GetTimeUnitMultiplier(reports[0].time_unit);\n\n  // Only add label to mean/stddev if it is same for all runs\n  Run rms;\n  rms.run_name = run_name;\n  rms.family_index = reports[0].family_index;\n  rms.per_family_instance_index = reports[0].per_family_instance_index;\n  rms.run_type = BenchmarkReporter::Run::RT_Aggregate;\n  rms.aggregate_name = \"RMS\";\n  rms.aggregate_unit = StatisticUnit::kPercentage;\n  rms.report_label = big_o.report_label;\n  rms.iterations = 0;\n  rms.repetition_index = Run::no_repetition_index;\n  rms.repetitions = reports[0].repetitions;\n  rms.threads = reports[0].threads;\n  rms.real_accumulated_time = result_real.rms / multiplier;\n  rms.cpu_accumulated_time = result_cpu.rms / multiplier;\n  rms.report_rms = true;\n  rms.complexity = result_cpu.complexity;\n  // don't forget to keep the time unit, or we won't be able to\n  // recover the correct value.\n  rms.time_unit = reports[0].time_unit;\n\n  results.push_back(big_o);\n  results.push_back(rms);\n  return results;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/complexity.h",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Source project : https://github.com/ismaelJimenez/cpp.leastsq\n// Adapted to be used with google benchmark\n\n#ifndef COMPLEXITY_H_\n#define COMPLEXITY_H_\n\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// Return a vector containing the bigO and RMS information for the specified\n// list of reports. If 'reports.size() < 2' an empty vector is returned.\nstd::vector<BenchmarkReporter::Run> ComputeBigO(\n    const std::vector<BenchmarkReporter::Run>& reports);\n\n// This data structure will contain the result returned by MinimalLeastSq\n//   - coef        : Estimated coefficient for the high-order term as\n//                   interpolated from data.\n//   - rms         : Normalized Root Mean Squared Error.\n//   - complexity  : Scalability form (e.g. oN, oNLogN). In case a scalability\n//                   form has been provided to MinimalLeastSq this will return\n//                   the same value. In case BigO::oAuto has been selected, this\n//                   parameter will return the best fitting curve detected.\n\nstruct LeastSq {\n  LeastSq() : coef(0.0), rms(0.0), complexity(oNone) {}\n\n  double coef;\n  double rms;\n  BigO complexity;\n};\n\n// Function to return an string for the calculated complexity\nstd::string GetBigOString(BigO complexity);\n\n}  // end namespace benchmark\n\n#endif  // COMPLEXITY_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/console_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cstdint>\n#include <cstdio>\n#include <cstring>\n#include <iostream>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"colorprint.h\"\n#include \"commandlineflags.h\"\n#include \"complexity.h\"\n#include \"counter.h\"\n#include \"internal_macros.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nBENCHMARK_EXPORT\nbool ConsoleReporter::ReportContext(const Context& context) {\n  name_field_width_ = context.name_field_width;\n  printed_header_ = false;\n  prev_counters_.clear();\n\n  PrintBasicContext(&GetErrorStream(), context);\n\n#ifdef BENCHMARK_OS_WINDOWS\n  if ((output_options_ & OO_Color)) {\n    auto stdOutBuf = std::cout.rdbuf();\n    auto outStreamBuf = GetOutputStream().rdbuf();\n    if (stdOutBuf != outStreamBuf) {\n      GetErrorStream()\n          << \"Color printing is only supported for stdout on windows.\"\n             \" Disabling color printing\\n\";\n      output_options_ = static_cast<OutputOptions>(output_options_ & ~OO_Color);\n    }\n  }\n#endif\n\n  return true;\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::PrintHeader(const Run& run) {\n  std::string str =\n      FormatString(\"%-*s %13s %15s %12s\", static_cast<int>(name_field_width_),\n                   \"Benchmark\", \"Time\", \"CPU\", \"Iterations\");\n  if (!run.counters.empty()) {\n    if (output_options_ & OO_Tabular) {\n      for (auto const& c : run.counters) {\n        str += FormatString(\" %10s\", c.first.c_str());\n      }\n    } else {\n      str += \" UserCounters...\";\n    }\n  }\n  std::string line = std::string(str.length(), '-');\n  GetOutputStream() << line << \"\\n\" << str << \"\\n\" << line << \"\\n\";\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {\n  for (const auto& run : reports) {\n    // print the header:\n    // --- if none was printed yet\n    bool print_header = !printed_header_;\n    // --- or if the format is tabular and this run\n    //     has different fields from the prev header\n    print_header |= (output_options_ & OO_Tabular) &&\n                    (!internal::SameNames(run.counters, prev_counters_));\n    if (print_header) {\n      printed_header_ = true;\n      prev_counters_ = run.counters;\n      PrintHeader(run);\n    }\n    // As an alternative to printing the headers like this, we could sort\n    // the benchmarks by header and then print. But this would require\n    // waiting for the full results before printing, or printing twice.\n    PrintRunData(run);\n  }\n}\n\nstatic void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt,\n                             ...) {\n  va_list args;\n  va_start(args, fmt);\n  out << FormatString(fmt, args);\n  va_end(args);\n}\n\nstatic std::string FormatTime(double time) {\n  // For the time columns of the console printer 13 digits are reserved. One of\n  // them is a space and max two of them are the time unit (e.g ns). That puts\n  // us at 10 digits usable for the number.\n  // Align decimal places...\n  if (time < 1.0) {\n    return FormatString(\"%10.3f\", time);\n  }\n  if (time < 10.0) {\n    return FormatString(\"%10.2f\", time);\n  }\n  if (time < 100.0) {\n    return FormatString(\"%10.1f\", time);\n  }\n  // Assuming the time is at max 9.9999e+99 and we have 10 digits for the\n  // number, we get 10-1(.)-1(e)-1(sign)-2(exponent) = 5 digits to print.\n  if (time > 9999999999 /*max 10 digit number*/) {\n    return FormatString(\"%1.4e\", time);\n  }\n  return FormatString(\"%10.0f\", time);\n}\n\nBENCHMARK_EXPORT\nvoid ConsoleReporter::PrintRunData(const Run& result) {\n  typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...);\n  auto& Out = GetOutputStream();\n  PrinterFn* printer = (output_options_ & OO_Color)\n                           ? static_cast<PrinterFn*>(ColorPrintf)\n                           : IgnoreColorPrint;\n  auto name_color =\n      (result.report_big_o || result.report_rms) ? COLOR_BLUE : COLOR_GREEN;\n  printer(Out, name_color, \"%-*s \", name_field_width_,\n          result.benchmark_name().c_str());\n\n  if (internal::SkippedWithError == result.skipped) {\n    printer(Out, COLOR_RED, \"ERROR OCCURRED: \\'%s\\'\",\n            result.skip_message.c_str());\n    printer(Out, COLOR_DEFAULT, \"\\n\");\n    return;\n  } else if (internal::SkippedWithMessage == result.skipped) {\n    printer(Out, COLOR_WHITE, \"SKIPPED: \\'%s\\'\", result.skip_message.c_str());\n    printer(Out, COLOR_DEFAULT, \"\\n\");\n    return;\n  }\n\n  const double real_time = result.GetAdjustedRealTime();\n  const double cpu_time = result.GetAdjustedCPUTime();\n  const std::string real_time_str = FormatTime(real_time);\n  const std::string cpu_time_str = FormatTime(cpu_time);\n\n  if (result.report_big_o) {\n    std::string big_o = GetBigOString(result.complexity);\n    printer(Out, COLOR_YELLOW, \"%10.2f %-4s %10.2f %-4s \", real_time,\n            big_o.c_str(), cpu_time, big_o.c_str());\n  } else if (result.report_rms) {\n    printer(Out, COLOR_YELLOW, \"%10.0f %-4s %10.0f %-4s \", real_time * 100, \"%\",\n            cpu_time * 100, \"%\");\n  } else if (result.run_type != Run::RT_Aggregate ||\n             result.aggregate_unit == StatisticUnit::kTime) {\n    const char* timeLabel = GetTimeUnitString(result.time_unit);\n    printer(Out, COLOR_YELLOW, \"%s %-4s %s %-4s \", real_time_str.c_str(),\n            timeLabel, cpu_time_str.c_str(), timeLabel);\n  } else {\n    assert(result.aggregate_unit == StatisticUnit::kPercentage);\n    printer(Out, COLOR_YELLOW, \"%10.2f %-4s %10.2f %-4s \",\n            (100. * result.real_accumulated_time), \"%\",\n            (100. * result.cpu_accumulated_time), \"%\");\n  }\n\n  if (!result.report_big_o && !result.report_rms) {\n    printer(Out, COLOR_CYAN, \"%10lld\", result.iterations);\n  }\n\n  for (auto& c : result.counters) {\n    const std::size_t cNameLen =\n        std::max(std::string::size_type(10), c.first.length());\n    std::string s;\n    const char* unit = \"\";\n    if (result.run_type == Run::RT_Aggregate &&\n        result.aggregate_unit == StatisticUnit::kPercentage) {\n      s = StrFormat(\"%.2f\", 100. * c.second.value);\n      unit = \"%\";\n    } else {\n      s = HumanReadableNumber(c.second.value, c.second.oneK);\n      if (c.second.flags & Counter::kIsRate)\n        unit = (c.second.flags & Counter::kInvert) ? \"s\" : \"/s\";\n    }\n    if (output_options_ & OO_Tabular) {\n      printer(Out, COLOR_DEFAULT, \" %*s%s\", cNameLen - strlen(unit), s.c_str(),\n              unit);\n    } else {\n      printer(Out, COLOR_DEFAULT, \" %s=%s%s\", c.first.c_str(), s.c_str(), unit);\n    }\n  }\n\n  if (!result.report_label.empty()) {\n    printer(Out, COLOR_DEFAULT, \" %s\", result.report_label.c_str());\n  }\n\n  printer(Out, COLOR_DEFAULT, \"\\n\");\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/counter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"counter.h\"\n\nnamespace benchmark {\nnamespace internal {\n\ndouble Finish(Counter const& c, IterationCount iterations, double cpu_time,\n              double num_threads) {\n  double v = c.value;\n  if (c.flags & Counter::kIsRate) {\n    v /= cpu_time;\n  }\n  if (c.flags & Counter::kAvgThreads) {\n    v /= num_threads;\n  }\n  if (c.flags & Counter::kIsIterationInvariant) {\n    v *= static_cast<double>(iterations);\n  }\n  if (c.flags & Counter::kAvgIterations) {\n    v /= static_cast<double>(iterations);\n  }\n\n  if (c.flags & Counter::kInvert) {  // Invert is *always* last.\n    v = 1.0 / v;\n  }\n  return v;\n}\n\nvoid Finish(UserCounters* l, IterationCount iterations, double cpu_time,\n            double num_threads) {\n  for (auto& c : *l) {\n    c.second.value = Finish(c.second, iterations, cpu_time, num_threads);\n  }\n}\n\nvoid Increment(UserCounters* l, UserCounters const& r) {\n  // add counters present in both or just in *l\n  for (auto& c : *l) {\n    auto it = r.find(c.first);\n    if (it != r.end()) {\n      c.second.value = c.second + it->second;\n    }\n  }\n  // add counters present in r, but not in *l\n  for (auto const& tc : r) {\n    auto it = l->find(tc.first);\n    if (it == l->end()) {\n      (*l)[tc.first] = tc.second;\n    }\n  }\n}\n\nbool SameNames(UserCounters const& l, UserCounters const& r) {\n  if (&l == &r) return true;\n  if (l.size() != r.size()) {\n    return false;\n  }\n  for (auto const& c : l) {\n    if (r.find(c.first) == r.end()) {\n      return false;\n    }\n  }\n  return true;\n}\n\n}  // end namespace internal\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/counter.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_COUNTER_H_\n#define BENCHMARK_COUNTER_H_\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// these counter-related functions are hidden to reduce API surface.\nnamespace internal {\nvoid Finish(UserCounters* l, IterationCount iterations, double time,\n            double num_threads);\nvoid Increment(UserCounters* l, UserCounters const& r);\nbool SameNames(UserCounters const& l, UserCounters const& r);\n}  // end namespace internal\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_COUNTER_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/csv_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"complexity.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\n// File format reference: http://edoceo.com/utilitas/csv-file-format.\n\nnamespace benchmark {\n\nnamespace {\nstd::vector<std::string> elements = {\n    \"name\",           \"iterations\",       \"real_time\",        \"cpu_time\",\n    \"time_unit\",      \"bytes_per_second\", \"items_per_second\", \"label\",\n    \"error_occurred\", \"error_message\"};\n}  // namespace\n\nstd::string CsvEscape(const std::string& s) {\n  std::string tmp;\n  tmp.reserve(s.size() + 2);\n  for (char c : s) {\n    switch (c) {\n      case '\"':\n        tmp += \"\\\"\\\"\";\n        break;\n      default:\n        tmp += c;\n        break;\n    }\n  }\n  return '\"' + tmp + '\"';\n}\n\nBENCHMARK_EXPORT\nbool CSVReporter::ReportContext(const Context& context) {\n  PrintBasicContext(&GetErrorStream(), context);\n  return true;\n}\n\nBENCHMARK_EXPORT\nvoid CSVReporter::ReportRuns(const std::vector<Run>& reports) {\n  std::ostream& Out = GetOutputStream();\n\n  if (!printed_header_) {\n    // save the names of all the user counters\n    for (const auto& run : reports) {\n      for (const auto& cnt : run.counters) {\n        if (cnt.first == \"bytes_per_second\" || cnt.first == \"items_per_second\")\n          continue;\n        user_counter_names_.insert(cnt.first);\n      }\n    }\n\n    // print the header\n    for (auto B = elements.begin(); B != elements.end();) {\n      Out << *B++;\n      if (B != elements.end()) Out << \",\";\n    }\n    for (auto B = user_counter_names_.begin();\n         B != user_counter_names_.end();) {\n      Out << \",\\\"\" << *B++ << \"\\\"\";\n    }\n    Out << \"\\n\";\n\n    printed_header_ = true;\n  } else {\n    // check that all the current counters are saved in the name set\n    for (const auto& run : reports) {\n      for (const auto& cnt : run.counters) {\n        if (cnt.first == \"bytes_per_second\" || cnt.first == \"items_per_second\")\n          continue;\n        BM_CHECK(user_counter_names_.find(cnt.first) !=\n                 user_counter_names_.end())\n            << \"All counters must be present in each run. \"\n            << \"Counter named \\\"\" << cnt.first\n            << \"\\\" was not in a run after being added to the header\";\n      }\n    }\n  }\n\n  // print results for each run\n  for (const auto& run : reports) {\n    PrintRunData(run);\n  }\n}\n\nBENCHMARK_EXPORT\nvoid CSVReporter::PrintRunData(const Run& run) {\n  std::ostream& Out = GetOutputStream();\n  Out << CsvEscape(run.benchmark_name()) << \",\";\n  if (run.skipped) {\n    Out << std::string(elements.size() - 3, ',');\n    Out << std::boolalpha << (internal::SkippedWithError == run.skipped) << \",\";\n    Out << CsvEscape(run.skip_message) << \"\\n\";\n    return;\n  }\n\n  // Do not print iteration on bigO and RMS report\n  if (!run.report_big_o && !run.report_rms) {\n    Out << run.iterations;\n  }\n  Out << \",\";\n\n  if (run.run_type != Run::RT_Aggregate ||\n      run.aggregate_unit == StatisticUnit::kTime) {\n    Out << run.GetAdjustedRealTime() << \",\";\n    Out << run.GetAdjustedCPUTime() << \",\";\n  } else {\n    assert(run.aggregate_unit == StatisticUnit::kPercentage);\n    Out << run.real_accumulated_time << \",\";\n    Out << run.cpu_accumulated_time << \",\";\n  }\n\n  // Do not print timeLabel on bigO and RMS report\n  if (run.report_big_o) {\n    Out << GetBigOString(run.complexity);\n  } else if (!run.report_rms &&\n             run.aggregate_unit != StatisticUnit::kPercentage) {\n    Out << GetTimeUnitString(run.time_unit);\n  }\n  Out << \",\";\n\n  if (run.counters.find(\"bytes_per_second\") != run.counters.end()) {\n    Out << run.counters.at(\"bytes_per_second\");\n  }\n  Out << \",\";\n  if (run.counters.find(\"items_per_second\") != run.counters.end()) {\n    Out << run.counters.at(\"items_per_second\");\n  }\n  Out << \",\";\n  if (!run.report_label.empty()) {\n    Out << CsvEscape(run.report_label);\n  }\n  Out << \",,\";  // for error_occurred and error_message\n\n  // Print user counters\n  for (const auto& ucn : user_counter_names_) {\n    auto it = run.counters.find(ucn);\n    if (it == run.counters.end()) {\n      Out << \",\";\n    } else {\n      Out << \",\" << it->second;\n    }\n  }\n  Out << '\\n';\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/cycleclock.h",
    "content": "// ----------------------------------------------------------------------\n// CycleClock\n//    A CycleClock tells you the current time in Cycles.  The \"time\"\n//    is actually time since power-on.  This is like time() but doesn't\n//    involve a system call and is much more precise.\n//\n// NOTE: Not all cpu/platform/kernel combinations guarantee that this\n// clock increments at a constant rate or is synchronized across all logical\n// cpus in a system.\n//\n// If you need the above guarantees, please consider using a different\n// API. There are efforts to provide an interface which provides a millisecond\n// granularity and implemented as a memory read. A memory read is generally\n// cheaper than the CycleClock for many architectures.\n//\n// Also, in some out of order CPU implementations, the CycleClock is not\n// serializing. So if you're trying to count at cycles granularity, your\n// data might be inaccurate due to out of order instruction execution.\n// ----------------------------------------------------------------------\n\n#ifndef BENCHMARK_CYCLECLOCK_H_\n#define BENCHMARK_CYCLECLOCK_H_\n\n#include <cstdint>\n\n#include \"benchmark/benchmark.h\"\n#include \"internal_macros.h\"\n\n#if defined(BENCHMARK_OS_MACOSX)\n#include <mach/mach_time.h>\n#endif\n// For MSVC, we want to use '_asm rdtsc' when possible (since it works\n// with even ancient MSVC compilers), and when not possible the\n// __rdtsc intrinsic, declared in <intrin.h>.  Unfortunately, in some\n// environments, <windows.h> and <intrin.h> have conflicting\n// declarations of some other intrinsics, breaking compilation.\n// Therefore, we simply declare __rdtsc ourselves. See also\n// http://connect.microsoft.com/VisualStudio/feedback/details/262047\n#if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \\\n    !defined(_M_ARM64EC)\nextern \"C\" uint64_t __rdtsc();\n#pragma intrinsic(__rdtsc)\n#endif\n\n#if !defined(BENCHMARK_OS_WINDOWS) || defined(BENCHMARK_OS_MINGW)\n#include <sys/time.h>\n#include <time.h>\n#endif\n\n#ifdef BENCHMARK_OS_EMSCRIPTEN\n#include <emscripten.h>\n#endif\n\nnamespace benchmark {\n// NOTE: only i386 and x86_64 have been well tested.\n// PPC, sparc, alpha, and ia64 are based on\n//    http://peter.kuscsik.com/wordpress/?p=14\n// with modifications by m3b.  See also\n//    https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h\nnamespace cycleclock {\n// This should return the number of cycles since power-on.  Thread-safe.\ninline BENCHMARK_ALWAYS_INLINE int64_t Now() {\n#if defined(BENCHMARK_OS_MACOSX)\n  // this goes at the top because we need ALL Macs, regardless of\n  // architecture, to return the number of \"mach time units\" that\n  // have passed since startup.  See sysinfo.cc where\n  // InitializeSystemInfo() sets the supposed cpu clock frequency of\n  // macs to the number of mach time units per second, not actual\n  // CPU clock frequency (which can change in the face of CPU\n  // frequency scaling).  Also note that when the Mac sleeps, this\n  // counter pauses; it does not continue counting, nor does it\n  // reset to zero.\n  return static_cast<int64_t>(mach_absolute_time());\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // this goes above x86-specific code because old versions of Emscripten\n  // define __x86_64__, although they have nothing to do with it.\n  return static_cast<int64_t>(emscripten_get_now() * 1e+6);\n#elif defined(__i386__)\n  int64_t ret;\n  __asm__ volatile(\"rdtsc\" : \"=A\"(ret));\n  return ret;\n#elif defined(__x86_64__) || defined(__amd64__)\n  uint64_t low, high;\n  __asm__ volatile(\"rdtsc\" : \"=a\"(low), \"=d\"(high));\n  return static_cast<int64_t>((high << 32) | low);\n#elif defined(__powerpc__) || defined(__ppc__)\n  // This returns a time-base, which is not always precisely a cycle-count.\n#if defined(__powerpc64__) || defined(__ppc64__)\n  int64_t tb;\n  asm volatile(\"mfspr %0, 268\" : \"=r\"(tb));\n  return tb;\n#else\n  uint32_t tbl, tbu0, tbu1;\n  asm volatile(\n      \"mftbu %0\\n\"\n      \"mftb %1\\n\"\n      \"mftbu %2\"\n      : \"=r\"(tbu0), \"=r\"(tbl), \"=r\"(tbu1));\n  tbl &= -static_cast<int32_t>(tbu0 == tbu1);\n  // high 32 bits in tbu1; low 32 bits in tbl  (tbu0 is no longer needed)\n  return (static_cast<uint64_t>(tbu1) << 32) | tbl;\n#endif\n#elif defined(__sparc__)\n  int64_t tick;\n  asm(\".byte 0x83, 0x41, 0x00, 0x00\");\n  asm(\"mov   %%g1, %0\" : \"=r\"(tick));\n  return tick;\n#elif defined(__ia64__)\n  int64_t itc;\n  asm(\"mov %0 = ar.itc\" : \"=r\"(itc));\n  return itc;\n#elif defined(COMPILER_MSVC) && defined(_M_IX86)\n  // Older MSVC compilers (like 7.x) don't seem to support the\n  // __rdtsc intrinsic properly, so I prefer to use _asm instead\n  // when I know it will work.  Otherwise, I'll use __rdtsc and hope\n  // the code is being compiled with a non-ancient compiler.\n  _asm rdtsc\n#elif defined(COMPILER_MSVC) && (defined(_M_ARM64) || defined(_M_ARM64EC))\n  // See // https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics\n  // and https://reviews.llvm.org/D53115\n  int64_t virtual_timer_value;\n  virtual_timer_value = _ReadStatusReg(ARM64_CNTVCT);\n  return virtual_timer_value;\n#elif defined(COMPILER_MSVC)\n  return __rdtsc();\n#elif defined(BENCHMARK_OS_NACL)\n  // Native Client validator on x86/x86-64 allows RDTSC instructions,\n  // and this case is handled above. Native Client validator on ARM\n  // rejects MRC instructions (used in the ARM-specific sequence below),\n  // so we handle it here. Portable Native Client compiles to\n  // architecture-agnostic bytecode, which doesn't provide any\n  // cycle counter access mnemonics.\n\n  // Native Client does not provide any API to access cycle counter.\n  // Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday\n  // because is provides nanosecond resolution (which is noticeable at\n  // least for PNaCl modules running on x86 Mac & Linux).\n  // Initialize to always return 0 if clock_gettime fails.\n  struct timespec ts = {0, 0};\n  clock_gettime(CLOCK_MONOTONIC, &ts);\n  return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;\n#elif defined(__aarch64__)\n  // System timer of ARMv8 runs at a different frequency than the CPU's.\n  // The frequency is fixed, typically in the range 1-50MHz.  It can be\n  // read at CNTFRQ special register.  We assume the OS has set up\n  // the virtual timer properly.\n  int64_t virtual_timer_value;\n  asm volatile(\"mrs %0, cntvct_el0\" : \"=r\"(virtual_timer_value));\n  return virtual_timer_value;\n#elif defined(__ARM_ARCH)\n  // V6 is the earliest arch that has a standard cyclecount\n  // Native Client validator doesn't allow MRC instructions.\n#if (__ARM_ARCH >= 6)\n  uint32_t pmccntr;\n  uint32_t pmuseren;\n  uint32_t pmcntenset;\n  // Read the user mode perf monitor counter access permissions.\n  asm volatile(\"mrc p15, 0, %0, c9, c14, 0\" : \"=r\"(pmuseren));\n  if (pmuseren & 1) {  // Allows reading perfmon counters for user mode code.\n    asm volatile(\"mrc p15, 0, %0, c9, c12, 1\" : \"=r\"(pmcntenset));\n    if (pmcntenset & 0x80000000ul) {  // Is it counting?\n      asm volatile(\"mrc p15, 0, %0, c9, c13, 0\" : \"=r\"(pmccntr));\n      // The counter is set up to count every 64th cycle\n      return static_cast<int64_t>(pmccntr) * 64;  // Should optimize to << 6\n    }\n  }\n#endif\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__mips__) || defined(__m68k__)\n  // mips apparently only allows rdtsc for superusers, so we fall\n  // back to gettimeofday.  It's possible clock_gettime would be better.\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__loongarch__) || defined(__csky__)\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__s390__)  // Covers both s390 and s390x.\n  // Return the CPU clock.\n  uint64_t tsc;\n#if defined(BENCHMARK_OS_ZOS)\n  // z/OS HLASM syntax.\n  asm(\" stck %0\" : \"=m\"(tsc) : : \"cc\");\n#else\n  // Linux on Z syntax.\n  asm(\"stck %0\" : \"=Q\"(tsc) : : \"cc\");\n#endif\n  return tsc;\n#elif defined(__riscv)  // RISC-V\n  // Use RDTIME (and RDTIMEH on riscv32).\n  // RDCYCLE is a privileged instruction since Linux 6.6.\n#if __riscv_xlen == 32\n  uint32_t cycles_lo, cycles_hi0, cycles_hi1;\n  // This asm also includes the PowerPC overflow handling strategy, as above.\n  // Implemented in assembly because Clang insisted on branching.\n  asm volatile(\n      \"rdtimeh %0\\n\"\n      \"rdtime %1\\n\"\n      \"rdtimeh %2\\n\"\n      \"sub %0, %0, %2\\n\"\n      \"seqz %0, %0\\n\"\n      \"sub %0, zero, %0\\n\"\n      \"and %1, %1, %0\\n\"\n      : \"=r\"(cycles_hi0), \"=r\"(cycles_lo), \"=r\"(cycles_hi1));\n  return static_cast<int64_t>((static_cast<uint64_t>(cycles_hi1) << 32) |\n                              cycles_lo);\n#else\n  uint64_t cycles;\n  asm volatile(\"rdtime %0\" : \"=r\"(cycles));\n  return static_cast<int64_t>(cycles);\n#endif\n#elif defined(__e2k__) || defined(__elbrus__)\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#elif defined(__hexagon__)\n  uint64_t pcycle;\n  asm volatile(\"%0 = C15:14\" : \"=r\"(pcycle));\n  return static_cast<double>(pcycle);\n#elif defined(__alpha__)\n  // Alpha has a cycle counter, the PCC register, but it is an unsigned 32-bit\n  // integer and thus wraps every ~4s, making using it for tick counts\n  // unreliable beyond this time range.  The real-time clock is low-precision,\n  // roughtly ~1ms, but it is the only option that can reasonable count\n  // indefinitely.\n  struct timeval tv;\n  gettimeofday(&tv, nullptr);\n  return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#else\n  // The soft failover to a generic implementation is automatic only for ARM.\n  // For other platforms the developer is expected to make an attempt to create\n  // a fast implementation and use generic version if nothing better is\n  // available.\n#error You need to define CycleTimer for your OS and CPU\n#endif\n}\n}  // end namespace cycleclock\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_CYCLECLOCK_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/internal_macros.h",
    "content": "#ifndef BENCHMARK_INTERNAL_MACROS_H_\n#define BENCHMARK_INTERNAL_MACROS_H_\n\n/* Needed to detect STL */\n#include <cstdlib>\n\n// clang-format off\n\n#ifndef __has_feature\n#define __has_feature(x) 0\n#endif\n\n#if defined(__clang__)\n  #if !defined(COMPILER_CLANG)\n    #define COMPILER_CLANG\n  #endif\n#elif defined(_MSC_VER)\n  #if !defined(COMPILER_MSVC)\n    #define COMPILER_MSVC\n  #endif\n#elif defined(__GNUC__)\n  #if !defined(COMPILER_GCC)\n    #define COMPILER_GCC\n  #endif\n#endif\n\n#if __has_feature(cxx_attributes)\n  #define BENCHMARK_NORETURN [[noreturn]]\n#elif defined(__GNUC__)\n  #define BENCHMARK_NORETURN __attribute__((noreturn))\n#elif defined(COMPILER_MSVC)\n  #define BENCHMARK_NORETURN __declspec(noreturn)\n#else\n  #define BENCHMARK_NORETURN\n#endif\n\n#if defined(__CYGWIN__)\n  #define BENCHMARK_OS_CYGWIN 1\n#elif defined(_WIN32)\n  #define BENCHMARK_OS_WINDOWS 1\n  // WINAPI_FAMILY_PARTITION is defined in winapifamily.h.\n  // We include windows.h which implicitly includes winapifamily.h for compatibility.\n  #ifndef NOMINMAX\n    #define NOMINMAX\n  #endif\n  #include <windows.h>\n  #if defined(WINAPI_FAMILY_PARTITION)\n    #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)\n      #define BENCHMARK_OS_WINDOWS_WIN32 1\n    #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)\n      #define BENCHMARK_OS_WINDOWS_RT 1\n    #endif\n  #endif\n  #if defined(__MINGW32__)\n    #define BENCHMARK_OS_MINGW 1\n  #endif\n#elif defined(__APPLE__)\n  #define BENCHMARK_OS_APPLE 1\n  #include \"TargetConditionals.h\"\n  #if defined(TARGET_OS_MAC)\n    #define BENCHMARK_OS_MACOSX 1\n    #if defined(TARGET_OS_IPHONE)\n      #define BENCHMARK_OS_IOS 1\n    #endif\n  #endif\n#elif defined(__FreeBSD__)\n  #define BENCHMARK_OS_FREEBSD 1\n#elif defined(__NetBSD__)\n  #define BENCHMARK_OS_NETBSD 1\n#elif defined(__OpenBSD__)\n  #define BENCHMARK_OS_OPENBSD 1\n#elif defined(__DragonFly__)\n  #define BENCHMARK_OS_DRAGONFLY 1\n#elif defined(__linux__)\n  #define BENCHMARK_OS_LINUX 1\n#elif defined(__native_client__)\n  #define BENCHMARK_OS_NACL 1\n#elif defined(__EMSCRIPTEN__)\n  #define BENCHMARK_OS_EMSCRIPTEN 1\n#elif defined(__rtems__)\n  #define BENCHMARK_OS_RTEMS 1\n#elif defined(__Fuchsia__)\n#define BENCHMARK_OS_FUCHSIA 1\n#elif defined (__SVR4) && defined (__sun)\n#define BENCHMARK_OS_SOLARIS 1\n#elif defined(__QNX__)\n#define BENCHMARK_OS_QNX 1\n#elif defined(__MVS__)\n#define BENCHMARK_OS_ZOS 1\n#elif defined(__hexagon__)\n#define BENCHMARK_OS_QURT 1\n#endif\n\n#if defined(__ANDROID__) && defined(__GLIBCXX__)\n#define BENCHMARK_STL_ANDROID_GNUSTL 1\n#endif\n\n#if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \\\n     && !defined(__EXCEPTIONS)\n  #define BENCHMARK_HAS_NO_EXCEPTIONS\n#endif\n\n#if defined(COMPILER_CLANG) || defined(COMPILER_GCC)\n  #define BENCHMARK_MAYBE_UNUSED __attribute__((unused))\n#else\n  #define BENCHMARK_MAYBE_UNUSED\n#endif\n\n// clang-format on\n\n#endif  // BENCHMARK_INTERNAL_MACROS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/json_reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n#include <iomanip>  // for setprecision\n#include <iostream>\n#include <limits>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"complexity.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace {\n\nstd::string StrEscape(const std::string& s) {\n  std::string tmp;\n  tmp.reserve(s.size());\n  for (char c : s) {\n    switch (c) {\n      case '\\b':\n        tmp += \"\\\\b\";\n        break;\n      case '\\f':\n        tmp += \"\\\\f\";\n        break;\n      case '\\n':\n        tmp += \"\\\\n\";\n        break;\n      case '\\r':\n        tmp += \"\\\\r\";\n        break;\n      case '\\t':\n        tmp += \"\\\\t\";\n        break;\n      case '\\\\':\n        tmp += \"\\\\\\\\\";\n        break;\n      case '\"':\n        tmp += \"\\\\\\\"\";\n        break;\n      default:\n        tmp += c;\n        break;\n    }\n  }\n  return tmp;\n}\n\nstd::string FormatKV(std::string const& key, std::string const& value) {\n  return StrFormat(\"\\\"%s\\\": \\\"%s\\\"\", StrEscape(key).c_str(),\n                   StrEscape(value).c_str());\n}\n\nstd::string FormatKV(std::string const& key, const char* value) {\n  return StrFormat(\"\\\"%s\\\": \\\"%s\\\"\", StrEscape(key).c_str(),\n                   StrEscape(value).c_str());\n}\n\nstd::string FormatKV(std::string const& key, bool value) {\n  return StrFormat(\"\\\"%s\\\": %s\", StrEscape(key).c_str(),\n                   value ? \"true\" : \"false\");\n}\n\nstd::string FormatKV(std::string const& key, int64_t value) {\n  std::stringstream ss;\n  ss << '\"' << StrEscape(key) << \"\\\": \" << value;\n  return ss.str();\n}\n\nstd::string FormatKV(std::string const& key, double value) {\n  std::stringstream ss;\n  ss << '\"' << StrEscape(key) << \"\\\": \";\n\n  if (std::isnan(value))\n    ss << (value < 0 ? \"-\" : \"\") << \"NaN\";\n  else if (std::isinf(value))\n    ss << (value < 0 ? \"-\" : \"\") << \"Infinity\";\n  else {\n    const auto max_digits10 =\n        std::numeric_limits<decltype(value)>::max_digits10;\n    const auto max_fractional_digits10 = max_digits10 - 1;\n    ss << std::scientific << std::setprecision(max_fractional_digits10)\n       << value;\n  }\n  return ss.str();\n}\n\nint64_t RoundDouble(double v) { return std::lround(v); }\n\n}  // end namespace\n\nbool JSONReporter::ReportContext(const Context& context) {\n  std::ostream& out = GetOutputStream();\n\n  out << \"{\\n\";\n  std::string inner_indent(2, ' ');\n\n  // Open context block and print context information.\n  out << inner_indent << \"\\\"context\\\": {\\n\";\n  std::string indent(4, ' ');\n\n  std::string walltime_value = LocalDateTimeString();\n  out << indent << FormatKV(\"date\", walltime_value) << \",\\n\";\n\n  out << indent << FormatKV(\"host_name\", context.sys_info.name) << \",\\n\";\n\n  if (Context::executable_name) {\n    out << indent << FormatKV(\"executable\", Context::executable_name) << \",\\n\";\n  }\n\n  CPUInfo const& info = context.cpu_info;\n  out << indent << FormatKV(\"num_cpus\", static_cast<int64_t>(info.num_cpus))\n      << \",\\n\";\n  out << indent\n      << FormatKV(\"mhz_per_cpu\",\n                  RoundDouble(info.cycles_per_second / 1000000.0))\n      << \",\\n\";\n  if (CPUInfo::Scaling::UNKNOWN != info.scaling) {\n    out << indent\n        << FormatKV(\"cpu_scaling_enabled\",\n                    info.scaling == CPUInfo::Scaling::ENABLED ? true : false)\n        << \",\\n\";\n  }\n\n  out << indent << \"\\\"caches\\\": [\\n\";\n  indent = std::string(6, ' ');\n  std::string cache_indent(8, ' ');\n  for (size_t i = 0; i < info.caches.size(); ++i) {\n    auto& CI = info.caches[i];\n    out << indent << \"{\\n\";\n    out << cache_indent << FormatKV(\"type\", CI.type) << \",\\n\";\n    out << cache_indent << FormatKV(\"level\", static_cast<int64_t>(CI.level))\n        << \",\\n\";\n    out << cache_indent << FormatKV(\"size\", static_cast<int64_t>(CI.size))\n        << \",\\n\";\n    out << cache_indent\n        << FormatKV(\"num_sharing\", static_cast<int64_t>(CI.num_sharing))\n        << \"\\n\";\n    out << indent << \"}\";\n    if (i != info.caches.size() - 1) out << \",\";\n    out << \"\\n\";\n  }\n  indent = std::string(4, ' ');\n  out << indent << \"],\\n\";\n  out << indent << \"\\\"load_avg\\\": [\";\n  for (auto it = info.load_avg.begin(); it != info.load_avg.end();) {\n    out << *it++;\n    if (it != info.load_avg.end()) out << \",\";\n  }\n  out << \"],\\n\";\n\n  out << indent << FormatKV(\"library_version\", GetBenchmarkVersion());\n  out << \",\\n\";\n\n#if defined(NDEBUG)\n  const char build_type[] = \"release\";\n#else\n  const char build_type[] = \"debug\";\n#endif\n  out << indent << FormatKV(\"library_build_type\", build_type);\n  out << \",\\n\";\n\n  // NOTE: our json schema is not strictly tied to the library version!\n  out << indent << FormatKV(\"json_schema_version\", int64_t(1));\n\n  std::map<std::string, std::string>* global_context =\n      internal::GetGlobalContext();\n\n  if (global_context != nullptr) {\n    for (const auto& kv : *global_context) {\n      out << \",\\n\";\n      out << indent << FormatKV(kv.first, kv.second);\n    }\n  }\n  out << \"\\n\";\n\n  // Close context block and open the list of benchmarks.\n  out << inner_indent << \"},\\n\";\n  out << inner_indent << \"\\\"benchmarks\\\": [\\n\";\n  return true;\n}\n\nvoid JSONReporter::ReportRuns(std::vector<Run> const& reports) {\n  if (reports.empty()) {\n    return;\n  }\n  std::string indent(4, ' ');\n  std::ostream& out = GetOutputStream();\n  if (!first_report_) {\n    out << \",\\n\";\n  }\n  first_report_ = false;\n\n  for (auto it = reports.begin(); it != reports.end(); ++it) {\n    out << indent << \"{\\n\";\n    PrintRunData(*it);\n    out << indent << '}';\n    auto it_cp = it;\n    if (++it_cp != reports.end()) {\n      out << \",\\n\";\n    }\n  }\n}\n\nvoid JSONReporter::Finalize() {\n  // Close the list of benchmarks and the top level object.\n  GetOutputStream() << \"\\n  ]\\n}\\n\";\n}\n\nvoid JSONReporter::PrintRunData(Run const& run) {\n  std::string indent(6, ' ');\n  std::ostream& out = GetOutputStream();\n  out << indent << FormatKV(\"name\", run.benchmark_name()) << \",\\n\";\n  out << indent << FormatKV(\"family_index\", run.family_index) << \",\\n\";\n  out << indent\n      << FormatKV(\"per_family_instance_index\", run.per_family_instance_index)\n      << \",\\n\";\n  out << indent << FormatKV(\"run_name\", run.run_name.str()) << \",\\n\";\n  out << indent << FormatKV(\"run_type\", [&run]() -> const char* {\n    switch (run.run_type) {\n      case BenchmarkReporter::Run::RT_Iteration:\n        return \"iteration\";\n      case BenchmarkReporter::Run::RT_Aggregate:\n        return \"aggregate\";\n    }\n    BENCHMARK_UNREACHABLE();\n  }()) << \",\\n\";\n  out << indent << FormatKV(\"repetitions\", run.repetitions) << \",\\n\";\n  if (run.run_type != BenchmarkReporter::Run::RT_Aggregate) {\n    out << indent << FormatKV(\"repetition_index\", run.repetition_index)\n        << \",\\n\";\n  }\n  out << indent << FormatKV(\"threads\", run.threads) << \",\\n\";\n  if (run.run_type == BenchmarkReporter::Run::RT_Aggregate) {\n    out << indent << FormatKV(\"aggregate_name\", run.aggregate_name) << \",\\n\";\n    out << indent << FormatKV(\"aggregate_unit\", [&run]() -> const char* {\n      switch (run.aggregate_unit) {\n        case StatisticUnit::kTime:\n          return \"time\";\n        case StatisticUnit::kPercentage:\n          return \"percentage\";\n      }\n      BENCHMARK_UNREACHABLE();\n    }()) << \",\\n\";\n  }\n  if (internal::SkippedWithError == run.skipped) {\n    out << indent << FormatKV(\"error_occurred\", true) << \",\\n\";\n    out << indent << FormatKV(\"error_message\", run.skip_message) << \",\\n\";\n  } else if (internal::SkippedWithMessage == run.skipped) {\n    out << indent << FormatKV(\"skipped\", true) << \",\\n\";\n    out << indent << FormatKV(\"skip_message\", run.skip_message) << \",\\n\";\n  }\n  if (!run.report_big_o && !run.report_rms) {\n    out << indent << FormatKV(\"iterations\", run.iterations) << \",\\n\";\n    if (run.run_type != Run::RT_Aggregate ||\n        run.aggregate_unit == StatisticUnit::kTime) {\n      out << indent << FormatKV(\"real_time\", run.GetAdjustedRealTime())\n          << \",\\n\";\n      out << indent << FormatKV(\"cpu_time\", run.GetAdjustedCPUTime());\n    } else {\n      assert(run.aggregate_unit == StatisticUnit::kPercentage);\n      out << indent << FormatKV(\"real_time\", run.real_accumulated_time)\n          << \",\\n\";\n      out << indent << FormatKV(\"cpu_time\", run.cpu_accumulated_time);\n    }\n    out << \",\\n\"\n        << indent << FormatKV(\"time_unit\", GetTimeUnitString(run.time_unit));\n  } else if (run.report_big_o) {\n    out << indent << FormatKV(\"cpu_coefficient\", run.GetAdjustedCPUTime())\n        << \",\\n\";\n    out << indent << FormatKV(\"real_coefficient\", run.GetAdjustedRealTime())\n        << \",\\n\";\n    out << indent << FormatKV(\"big_o\", GetBigOString(run.complexity)) << \",\\n\";\n    out << indent << FormatKV(\"time_unit\", GetTimeUnitString(run.time_unit));\n  } else if (run.report_rms) {\n    out << indent << FormatKV(\"rms\", run.GetAdjustedCPUTime());\n  }\n\n  for (auto& c : run.counters) {\n    out << \",\\n\" << indent << FormatKV(c.first, c.second);\n  }\n\n  if (run.memory_result) {\n    const MemoryManager::Result memory_result = *run.memory_result;\n    out << \",\\n\" << indent << FormatKV(\"allocs_per_iter\", run.allocs_per_iter);\n    out << \",\\n\"\n        << indent << FormatKV(\"max_bytes_used\", memory_result.max_bytes_used);\n\n    auto report_if_present = [&out, &indent](const std::string& label,\n                                             int64_t val) {\n      if (val != MemoryManager::TombstoneValue)\n        out << \",\\n\" << indent << FormatKV(label, val);\n    };\n\n    report_if_present(\"total_allocated_bytes\",\n                      memory_result.total_allocated_bytes);\n    report_if_present(\"net_heap_growth\", memory_result.net_heap_growth);\n  }\n\n  if (!run.report_label.empty()) {\n    out << \",\\n\" << indent << FormatKV(\"label\", run.report_label);\n  }\n  out << '\\n';\n}\n\nconst int64_t MemoryManager::TombstoneValue =\n    std::numeric_limits<int64_t>::max();\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/log.h",
    "content": "#ifndef BENCHMARK_LOG_H_\n#define BENCHMARK_LOG_H_\n\n#include <iostream>\n#include <ostream>\n\n// NOTE: this is also defined in benchmark.h but we're trying to avoid a\n// dependency.\n// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.\n#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)\n#define BENCHMARK_HAS_CXX11\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\ntypedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);\n\nclass LogType {\n  friend LogType& GetNullLogInstance();\n  friend LogType& GetErrorLogInstance();\n\n  // FIXME: Add locking to output.\n  template <class Tp>\n  friend LogType& operator<<(LogType&, Tp const&);\n  friend LogType& operator<<(LogType&, EndLType*);\n\n private:\n  LogType(std::ostream* out) : out_(out) {}\n  std::ostream* out_;\n\n  // NOTE: we could use BENCHMARK_DISALLOW_COPY_AND_ASSIGN but we shouldn't have\n  // a dependency on benchmark.h from here.\n#ifndef BENCHMARK_HAS_CXX11\n  LogType(const LogType&);\n  LogType& operator=(const LogType&);\n#else\n  LogType(const LogType&) = delete;\n  LogType& operator=(const LogType&) = delete;\n#endif\n};\n\ntemplate <class Tp>\nLogType& operator<<(LogType& log, Tp const& value) {\n  if (log.out_) {\n    *log.out_ << value;\n  }\n  return log;\n}\n\ninline LogType& operator<<(LogType& log, EndLType* m) {\n  if (log.out_) {\n    *log.out_ << m;\n  }\n  return log;\n}\n\ninline int& LogLevel() {\n  static int log_level = 0;\n  return log_level;\n}\n\ninline LogType& GetNullLogInstance() {\n  static LogType null_log(static_cast<std::ostream*>(nullptr));\n  return null_log;\n}\n\ninline LogType& GetErrorLogInstance() {\n  static LogType error_log(&std::clog);\n  return error_log;\n}\n\ninline LogType& GetLogInstanceForLevel(int level) {\n  if (level <= LogLevel()) {\n    return GetErrorLogInstance();\n  }\n  return GetNullLogInstance();\n}\n\n}  // end namespace internal\n}  // end namespace benchmark\n\n// clang-format off\n#define BM_VLOG(x)                                                               \\\n  (::benchmark::internal::GetLogInstanceForLevel(x) << \"-- LOG(\" << x << \"):\" \\\n                                                                         \" \")\n// clang-format on\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/mutex.h",
    "content": "#ifndef BENCHMARK_MUTEX_H_\n#define BENCHMARK_MUTEX_H_\n\n#include <condition_variable>\n#include <mutex>\n\n#include \"check.h\"\n\n// Enable thread safety attributes only with clang.\n// The attributes can be safely erased when compiling with other compilers.\n#if defined(HAVE_THREAD_SAFETY_ATTRIBUTES)\n#define THREAD_ANNOTATION_ATTRIBUTE_(x) __attribute__((x))\n#else\n#define THREAD_ANNOTATION_ATTRIBUTE_(x)  // no-op\n#endif\n\n#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(capability(x))\n\n#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE_(scoped_lockable)\n\n#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE_(guarded_by(x))\n\n#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE_(pt_guarded_by(x))\n\n#define ACQUIRED_BEFORE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquired_before(__VA_ARGS__))\n\n#define ACQUIRED_AFTER(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquired_after(__VA_ARGS__))\n\n#define REQUIRES(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(requires_capability(__VA_ARGS__))\n\n#define REQUIRES_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(requires_shared_capability(__VA_ARGS__))\n\n#define ACQUIRE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquire_capability(__VA_ARGS__))\n\n#define ACQUIRE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(acquire_shared_capability(__VA_ARGS__))\n\n#define RELEASE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(release_capability(__VA_ARGS__))\n\n#define RELEASE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(release_shared_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(try_acquire_capability(__VA_ARGS__))\n\n#define TRY_ACQUIRE_SHARED(...) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(try_acquire_shared_capability(__VA_ARGS__))\n\n#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE_(locks_excluded(__VA_ARGS__))\n\n#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(assert_capability(x))\n\n#define ASSERT_SHARED_CAPABILITY(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE_(assert_shared_capability(x))\n\n#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE_(lock_returned(x))\n\n#define NO_THREAD_SAFETY_ANALYSIS \\\n  THREAD_ANNOTATION_ATTRIBUTE_(no_thread_safety_analysis)\n\nnamespace benchmark {\n\ntypedef std::condition_variable Condition;\n\n// NOTE: Wrappers for std::mutex and std::unique_lock are provided so that\n// we can annotate them with thread safety attributes and use the\n// -Wthread-safety warning with clang. The standard library types cannot be\n// used directly because they do not provide the required annotations.\nclass CAPABILITY(\"mutex\") Mutex {\n public:\n  Mutex() {}\n\n  void lock() ACQUIRE() { mut_.lock(); }\n  void unlock() RELEASE() { mut_.unlock(); }\n  std::mutex& native_handle() { return mut_; }\n\n private:\n  std::mutex mut_;\n};\n\nclass SCOPED_CAPABILITY MutexLock {\n  typedef std::unique_lock<std::mutex> MutexLockImp;\n\n public:\n  MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) {}\n  ~MutexLock() RELEASE() {}\n  MutexLockImp& native_handle() { return ml_; }\n\n private:\n  MutexLockImp ml_;\n};\n\nclass Barrier {\n public:\n  Barrier(int num_threads) : running_threads_(num_threads) {}\n\n  // Called by each thread\n  bool wait() EXCLUDES(lock_) {\n    bool last_thread = false;\n    {\n      MutexLock ml(lock_);\n      last_thread = createBarrier(ml);\n    }\n    if (last_thread) phase_condition_.notify_all();\n    return last_thread;\n  }\n\n  void removeThread() EXCLUDES(lock_) {\n    MutexLock ml(lock_);\n    --running_threads_;\n    if (entered_ != 0) phase_condition_.notify_all();\n  }\n\n private:\n  Mutex lock_;\n  Condition phase_condition_;\n  int running_threads_;\n\n  // State for barrier management\n  int phase_number_ = 0;\n  int entered_ = 0;  // Number of threads that have entered this barrier\n\n  // Enter the barrier and wait until all other threads have also\n  // entered the barrier.  Returns iff this is the last thread to\n  // enter the barrier.\n  bool createBarrier(MutexLock& ml) REQUIRES(lock_) {\n    BM_CHECK_LT(entered_, running_threads_);\n    entered_++;\n    if (entered_ < running_threads_) {\n      // Wait for all threads to enter\n      int phase_number_cp = phase_number_;\n      auto cb = [this, phase_number_cp]() {\n        return this->phase_number_ > phase_number_cp ||\n               entered_ == running_threads_;  // A thread has aborted in error\n      };\n      phase_condition_.wait(ml.native_handle(), cb);\n      if (phase_number_ > phase_number_cp) return false;\n      // else (running_threads_ == entered_) and we are the last thread.\n    }\n    // Last thread has reached the barrier\n    phase_number_++;\n    entered_ = 0;\n    return true;\n  }\n};\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_MUTEX_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/perf_counters.cc",
    "content": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"perf_counters.h\"\n\n#include <cstring>\n#include <memory>\n#include <vector>\n\n#if defined HAVE_LIBPFM\n#include \"perfmon/pfmlib.h\"\n#include \"perfmon/pfmlib_perf_event.h\"\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\nconstexpr size_t PerfCounterValues::kMaxCounters;\n\n#if defined HAVE_LIBPFM\n\nsize_t PerfCounterValues::Read(const std::vector<int>& leaders) {\n  // Create a pointer for multiple reads\n  const size_t bufsize = values_.size() * sizeof(values_[0]);\n  char* ptr = reinterpret_cast<char*>(values_.data());\n  size_t size = bufsize;\n  for (int lead : leaders) {\n    auto read_bytes = ::read(lead, ptr, size);\n    if (read_bytes >= ssize_t(sizeof(uint64_t))) {\n      // Actual data bytes are all bytes minus initial padding\n      std::size_t data_bytes =\n          static_cast<std::size_t>(read_bytes) - sizeof(uint64_t);\n      // This should be very cheap since it's in hot cache\n      std::memmove(ptr, ptr + sizeof(uint64_t), data_bytes);\n      // Increment our counters\n      ptr += data_bytes;\n      size -= data_bytes;\n    } else {\n      int err = errno;\n      GetErrorLogInstance() << \"Error reading lead \" << lead << \" errno:\" << err\n                            << \" \" << ::strerror(err) << \"\\n\";\n      return 0;\n    }\n  }\n  return (bufsize - size) / sizeof(uint64_t);\n}\n\nconst bool PerfCounters::kSupported = true;\n\n// Initializes libpfm only on the first call.  Returns whether that single\n// initialization was successful.\nbool PerfCounters::Initialize() {\n  // Function-scope static gets initialized only once on first call.\n  static const bool success = []() {\n    return pfm_initialize() == PFM_SUCCESS;\n  }();\n  return success;\n}\n\nbool PerfCounters::IsCounterSupported(const std::string& name) {\n  Initialize();\n  perf_event_attr_t attr;\n  std::memset(&attr, 0, sizeof(attr));\n  pfm_perf_encode_arg_t arg;\n  std::memset(&arg, 0, sizeof(arg));\n  arg.attr = &attr;\n  const int mode = PFM_PLM3;  // user mode only\n  int ret = pfm_get_os_event_encoding(name.c_str(), mode, PFM_OS_PERF_EVENT_EXT,\n                                      &arg);\n  return (ret == PFM_SUCCESS);\n}\n\nPerfCounters PerfCounters::Create(\n    const std::vector<std::string>& counter_names) {\n  if (!counter_names.empty()) {\n    Initialize();\n  }\n\n  // Valid counters will populate these arrays but we start empty\n  std::vector<std::string> valid_names;\n  std::vector<int> counter_ids;\n  std::vector<int> leader_ids;\n\n  // Resize to the maximum possible\n  valid_names.reserve(counter_names.size());\n  counter_ids.reserve(counter_names.size());\n\n  const int kCounterMode = PFM_PLM3;  // user mode only\n\n  // Group leads will be assigned on demand. The idea is that once we cannot\n  // create a counter descriptor, the reason is that this group has maxed out\n  // so we set the group_id again to -1 and retry - giving the algorithm a\n  // chance to create a new group leader to hold the next set of counters.\n  int group_id = -1;\n\n  // Loop through all performance counters\n  for (size_t i = 0; i < counter_names.size(); ++i) {\n    // we are about to push into the valid names vector\n    // check if we did not reach the maximum\n    if (valid_names.size() == PerfCounterValues::kMaxCounters) {\n      // Log a message if we maxed out and stop adding\n      GetErrorLogInstance()\n          << counter_names.size() << \" counters were requested. The maximum is \"\n          << PerfCounterValues::kMaxCounters << \" and \" << valid_names.size()\n          << \" were already added. All remaining counters will be ignored\\n\";\n      // stop the loop and return what we have already\n      break;\n    }\n\n    // Check if this name is empty\n    const auto& name = counter_names[i];\n    if (name.empty()) {\n      GetErrorLogInstance()\n          << \"A performance counter name was the empty string\\n\";\n      continue;\n    }\n\n    // Here first means first in group, ie the group leader\n    const bool is_first = (group_id < 0);\n\n    // This struct will be populated by libpfm from the counter string\n    // and then fed into the syscall perf_event_open\n    struct perf_event_attr attr {};\n    attr.size = sizeof(attr);\n\n    // This is the input struct to libpfm.\n    pfm_perf_encode_arg_t arg{};\n    arg.attr = &attr;\n    const int pfm_get = pfm_get_os_event_encoding(name.c_str(), kCounterMode,\n                                                  PFM_OS_PERF_EVENT, &arg);\n    if (pfm_get != PFM_SUCCESS) {\n      GetErrorLogInstance()\n          << \"Unknown performance counter name: \" << name << \"\\n\";\n      continue;\n    }\n\n    // We then proceed to populate the remaining fields in our attribute struct\n    // Note: the man page for perf_event_create suggests inherit = true and\n    // read_format = PERF_FORMAT_GROUP don't work together, but that's not the\n    // case.\n    attr.disabled = is_first;\n    attr.inherit = true;\n    attr.pinned = is_first;\n    attr.exclude_kernel = true;\n    attr.exclude_user = false;\n    attr.exclude_hv = true;\n\n    // Read all counters in a group in one read.\n    attr.read_format = PERF_FORMAT_GROUP;  //| PERF_FORMAT_TOTAL_TIME_ENABLED |\n                                           // PERF_FORMAT_TOTAL_TIME_RUNNING;\n\n    int id = -1;\n    while (id < 0) {\n      static constexpr size_t kNrOfSyscallRetries = 5;\n      // Retry syscall as it was interrupted often (b/64774091).\n      for (size_t num_retries = 0; num_retries < kNrOfSyscallRetries;\n           ++num_retries) {\n        id = perf_event_open(&attr, 0, -1, group_id, 0);\n        if (id >= 0 || errno != EINTR) {\n          break;\n        }\n      }\n      if (id < 0) {\n        // If the file descriptor is negative we might have reached a limit\n        // in the current group. Set the group_id to -1 and retry\n        if (group_id >= 0) {\n          // Create a new group\n          group_id = -1;\n        } else {\n          // At this point we have already retried to set a new group id and\n          // failed. We then give up.\n          break;\n        }\n      }\n    }\n\n    // We failed to get a new file descriptor. We might have reached a hard\n    // hardware limit that cannot be resolved even with group multiplexing\n    if (id < 0) {\n      GetErrorLogInstance() << \"***WARNING** Failed to get a file descriptor \"\n                               \"for performance counter \"\n                            << name << \". Ignoring\\n\";\n\n      // We give up on this counter but try to keep going\n      // as the others would be fine\n      continue;\n    }\n    if (group_id < 0) {\n      // This is a leader, store and assign it to the current file descriptor\n      leader_ids.push_back(id);\n      group_id = id;\n    }\n    // This is a valid counter, add it to our descriptor's list\n    counter_ids.push_back(id);\n    valid_names.push_back(name);\n  }\n\n  // Loop through all group leaders activating them\n  // There is another option of starting ALL counters in a process but\n  // that would be far reaching an intrusion. If the user is using PMCs\n  // by themselves then this would have a side effect on them. It is\n  // friendlier to loop through all groups individually.\n  for (int lead : leader_ids) {\n    if (ioctl(lead, PERF_EVENT_IOC_ENABLE) != 0) {\n      // This should never happen but if it does, we give up on the\n      // entire batch as recovery would be a mess.\n      GetErrorLogInstance() << \"***WARNING*** Failed to start counters. \"\n                               \"Claring out all counters.\\n\";\n\n      // Close all peformance counters\n      for (int id : counter_ids) {\n        ::close(id);\n      }\n\n      // Return an empty object so our internal state is still good and\n      // the process can continue normally without impact\n      return NoCounters();\n    }\n  }\n\n  return PerfCounters(std::move(valid_names), std::move(counter_ids),\n                      std::move(leader_ids));\n}\n\nvoid PerfCounters::CloseCounters() const {\n  if (counter_ids_.empty()) {\n    return;\n  }\n  for (int lead : leader_ids_) {\n    ioctl(lead, PERF_EVENT_IOC_DISABLE);\n  }\n  for (int fd : counter_ids_) {\n    close(fd);\n  }\n}\n#else   // defined HAVE_LIBPFM\nsize_t PerfCounterValues::Read(const std::vector<int>&) { return 0; }\n\nconst bool PerfCounters::kSupported = false;\n\nbool PerfCounters::Initialize() { return false; }\n\nbool PerfCounters::IsCounterSupported(const std::string&) { return false; }\n\nPerfCounters PerfCounters::Create(\n    const std::vector<std::string>& counter_names) {\n  if (!counter_names.empty()) {\n    GetErrorLogInstance() << \"Performance counters not supported.\\n\";\n  }\n  return NoCounters();\n}\n\nvoid PerfCounters::CloseCounters() const {}\n#endif  // defined HAVE_LIBPFM\n\nPerfCountersMeasurement::PerfCountersMeasurement(\n    const std::vector<std::string>& counter_names)\n    : start_values_(counter_names.size()), end_values_(counter_names.size()) {\n  counters_ = PerfCounters::Create(counter_names);\n}\n\nPerfCounters& PerfCounters::operator=(PerfCounters&& other) noexcept {\n  if (this != &other) {\n    CloseCounters();\n\n    counter_ids_ = std::move(other.counter_ids_);\n    leader_ids_ = std::move(other.leader_ids_);\n    counter_names_ = std::move(other.counter_names_);\n  }\n  return *this;\n}\n}  // namespace internal\n}  // namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/perf_counters.h",
    "content": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_PERF_COUNTERS_H\n#define BENCHMARK_PERF_COUNTERS_H\n\n#include <array>\n#include <cstdint>\n#include <cstring>\n#include <memory>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"log.h\"\n#include \"mutex.h\"\n\n#ifndef BENCHMARK_OS_WINDOWS\n#include <unistd.h>\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n// C4251: <symbol> needs to have dll-interface to be used by clients of class\n#pragma warning(disable : 4251)\n#endif\n\nnamespace benchmark {\nnamespace internal {\n\n// Typically, we can only read a small number of counters. There is also a\n// padding preceding counter values, when reading multiple counters with one\n// syscall (which is desirable). PerfCounterValues abstracts these details.\n// The implementation ensures the storage is inlined, and allows 0-based\n// indexing into the counter values.\n// The object is used in conjunction with a PerfCounters object, by passing it\n// to Snapshot(). The Read() method relocates individual reads, discarding\n// the initial padding from each group leader in the values buffer such that\n// all user accesses through the [] operator are correct.\nclass BENCHMARK_EXPORT PerfCounterValues {\n public:\n  explicit PerfCounterValues(size_t nr_counters) : nr_counters_(nr_counters) {\n    BM_CHECK_LE(nr_counters_, kMaxCounters);\n  }\n\n  // We are reading correctly now so the values don't need to skip padding\n  uint64_t operator[](size_t pos) const { return values_[pos]; }\n\n  // Increased the maximum to 32 only since the buffer\n  // is std::array<> backed\n  static constexpr size_t kMaxCounters = 32;\n\n private:\n  friend class PerfCounters;\n  // Get the byte buffer in which perf counters can be captured.\n  // This is used by PerfCounters::Read\n  std::pair<char*, size_t> get_data_buffer() {\n    return {reinterpret_cast<char*>(values_.data()),\n            sizeof(uint64_t) * (kPadding + nr_counters_)};\n  }\n\n  // This reading is complex and as the goal of this class is to\n  // abstract away the intrincacies of the reading process, this is\n  // a better place for it\n  size_t Read(const std::vector<int>& leaders);\n\n  // Move the padding to 2 due to the reading algorithm (1st padding plus a\n  // current read padding)\n  static constexpr size_t kPadding = 2;\n  std::array<uint64_t, kPadding + kMaxCounters> values_;\n  const size_t nr_counters_;\n};\n\n// Collect PMU counters. The object, once constructed, is ready to be used by\n// calling read(). PMU counter collection is enabled from the time create() is\n// called, to obtain the object, until the object's destructor is called.\nclass BENCHMARK_EXPORT PerfCounters final {\n public:\n  // True iff this platform supports performance counters.\n  static const bool kSupported;\n\n  // Returns an empty object\n  static PerfCounters NoCounters() { return PerfCounters(); }\n\n  ~PerfCounters() { CloseCounters(); }\n  PerfCounters() = default;\n  PerfCounters(PerfCounters&&) = default;\n  PerfCounters(const PerfCounters&) = delete;\n  PerfCounters& operator=(PerfCounters&&) noexcept;\n  PerfCounters& operator=(const PerfCounters&) = delete;\n\n  // Platform-specific implementations may choose to do some library\n  // initialization here.\n  static bool Initialize();\n\n  // Check if the given counter is supported, if the app wants to\n  // check before passing\n  static bool IsCounterSupported(const std::string& name);\n\n  // Return a PerfCounters object ready to read the counters with the names\n  // specified. The values are user-mode only. The counter name format is\n  // implementation and OS specific.\n  // In case of failure, this method will in the worst case return an\n  // empty object whose state will still be valid.\n  static PerfCounters Create(const std::vector<std::string>& counter_names);\n\n  // Take a snapshot of the current value of the counters into the provided\n  // valid PerfCounterValues storage. The values are populated such that:\n  // names()[i]'s value is (*values)[i]\n  BENCHMARK_ALWAYS_INLINE bool Snapshot(PerfCounterValues* values) const {\n#ifndef BENCHMARK_OS_WINDOWS\n    assert(values != nullptr);\n    return values->Read(leader_ids_) == counter_ids_.size();\n#else\n    (void)values;\n    return false;\n#endif\n  }\n\n  const std::vector<std::string>& names() const { return counter_names_; }\n  size_t num_counters() const { return counter_names_.size(); }\n\n private:\n  PerfCounters(const std::vector<std::string>& counter_names,\n               std::vector<int>&& counter_ids, std::vector<int>&& leader_ids)\n      : counter_ids_(std::move(counter_ids)),\n        leader_ids_(std::move(leader_ids)),\n        counter_names_(counter_names) {}\n\n  void CloseCounters() const;\n\n  std::vector<int> counter_ids_;\n  std::vector<int> leader_ids_;\n  std::vector<std::string> counter_names_;\n};\n\n// Typical usage of the above primitives.\nclass BENCHMARK_EXPORT PerfCountersMeasurement final {\n public:\n  PerfCountersMeasurement(const std::vector<std::string>& counter_names);\n\n  size_t num_counters() const { return counters_.num_counters(); }\n\n  std::vector<std::string> names() const { return counters_.names(); }\n\n  BENCHMARK_ALWAYS_INLINE bool Start() {\n    if (num_counters() == 0) return true;\n    // Tell the compiler to not move instructions above/below where we take\n    // the snapshot.\n    ClobberMemory();\n    valid_read_ &= counters_.Snapshot(&start_values_);\n    ClobberMemory();\n\n    return valid_read_;\n  }\n\n  BENCHMARK_ALWAYS_INLINE bool Stop(\n      std::vector<std::pair<std::string, double>>& measurements) {\n    if (num_counters() == 0) return true;\n    // Tell the compiler to not move instructions above/below where we take\n    // the snapshot.\n    ClobberMemory();\n    valid_read_ &= counters_.Snapshot(&end_values_);\n    ClobberMemory();\n\n    for (size_t i = 0; i < counters_.names().size(); ++i) {\n      double measurement = static_cast<double>(end_values_[i]) -\n                           static_cast<double>(start_values_[i]);\n      measurements.push_back({counters_.names()[i], measurement});\n    }\n\n    return valid_read_;\n  }\n\n private:\n  PerfCounters counters_;\n  bool valid_read_ = true;\n  PerfCounterValues start_values_;\n  PerfCounterValues end_values_;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#endif  // BENCHMARK_PERF_COUNTERS_H\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/re.h",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef BENCHMARK_RE_H_\n#define BENCHMARK_RE_H_\n\n#include \"internal_macros.h\"\n\n// clang-format off\n\n#if !defined(HAVE_STD_REGEX) && \\\n    !defined(HAVE_GNU_POSIX_REGEX) && \\\n    !defined(HAVE_POSIX_REGEX)\n  // No explicit regex selection; detect based on builtin hints.\n  #if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)\n    #define HAVE_POSIX_REGEX 1\n  #elif __cplusplus >= 199711L\n    #define HAVE_STD_REGEX 1\n  #endif\n#endif\n\n// Prefer C regex libraries when compiling w/o exceptions so that we can\n// correctly report errors.\n#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \\\n    defined(HAVE_STD_REGEX) && \\\n    (defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))\n  #undef HAVE_STD_REGEX\n#endif\n\n#if defined(HAVE_STD_REGEX)\n  #include <regex>\n#elif defined(HAVE_GNU_POSIX_REGEX)\n  #include <gnuregex.h>\n#elif defined(HAVE_POSIX_REGEX)\n  #include <regex.h>\n#else\n#error No regular expression backend was found!\n#endif\n\n// clang-format on\n\n#include <string>\n\n#include \"check.h\"\n\nnamespace benchmark {\n\n// A wrapper around the POSIX regular expression API that provides automatic\n// cleanup\nclass Regex {\n public:\n  Regex() : init_(false) {}\n\n  ~Regex();\n\n  // Compile a regular expression matcher from spec.  Returns true on success.\n  //\n  // On failure (and if error is not nullptr), error is populated with a human\n  // readable error message if an error occurs.\n  bool Init(const std::string& spec, std::string* error);\n\n  // Returns whether str matches the compiled regular expression.\n  bool Match(const std::string& str);\n\n private:\n  bool init_;\n// Underlying regular expression object\n#if defined(HAVE_STD_REGEX)\n  std::regex re_;\n#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)\n  regex_t re_;\n#else\n#error No regular expression backend implementation available\n#endif\n};\n\n#if defined(HAVE_STD_REGEX)\n\ninline bool Regex::Init(const std::string& spec, std::string* error) {\n#ifdef BENCHMARK_HAS_NO_EXCEPTIONS\n  ((void)error);  // suppress unused warning\n#else\n  try {\n#endif\n  re_ = std::regex(spec, std::regex_constants::extended);\n  init_ = true;\n#ifndef BENCHMARK_HAS_NO_EXCEPTIONS\n}\ncatch (const std::regex_error& e) {\n  if (error) {\n    *error = e.what();\n  }\n}\n#endif\nreturn init_;\n}\n\ninline Regex::~Regex() {}\n\ninline bool Regex::Match(const std::string& str) {\n  if (!init_) {\n    return false;\n  }\n  return std::regex_search(str, re_);\n}\n\n#else\ninline bool Regex::Init(const std::string& spec, std::string* error) {\n  int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB);\n  if (ec != 0) {\n    if (error) {\n      size_t needed = regerror(ec, &re_, nullptr, 0);\n      char* errbuf = new char[needed];\n      regerror(ec, &re_, errbuf, needed);\n\n      // regerror returns the number of bytes necessary to null terminate\n      // the string, so we move that when assigning to error.\n      BM_CHECK_NE(needed, 0);\n      error->assign(errbuf, needed - 1);\n\n      delete[] errbuf;\n    }\n\n    return false;\n  }\n\n  init_ = true;\n  return true;\n}\n\ninline Regex::~Regex() {\n  if (init_) {\n    regfree(&re_);\n  }\n}\n\ninline bool Regex::Match(const std::string& str) {\n  if (!init_) {\n    return false;\n  }\n  return regexec(&re_, str.c_str(), 0, nullptr, 0) == 0;\n}\n#endif\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_RE_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/reporter.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include <cstdlib>\n#include <iostream>\n#include <map>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\n\nBenchmarkReporter::BenchmarkReporter()\n    : output_stream_(&std::cout), error_stream_(&std::cerr) {}\n\nBenchmarkReporter::~BenchmarkReporter() {}\n\nvoid BenchmarkReporter::PrintBasicContext(std::ostream *out,\n                                          Context const &context) {\n  BM_CHECK(out) << \"cannot be null\";\n  auto &Out = *out;\n\n#ifndef BENCHMARK_OS_QURT\n  // Date/time information is not available on QuRT.\n  // Attempting to get it via this call cause the binary to crash.\n  Out << LocalDateTimeString() << \"\\n\";\n#endif\n\n  if (context.executable_name)\n    Out << \"Running \" << context.executable_name << \"\\n\";\n\n  const CPUInfo &info = context.cpu_info;\n  Out << \"Run on (\" << info.num_cpus << \" X \"\n      << (info.cycles_per_second / 1000000.0) << \" MHz CPU \"\n      << ((info.num_cpus > 1) ? \"s\" : \"\") << \")\\n\";\n  if (info.caches.size() != 0) {\n    Out << \"CPU Caches:\\n\";\n    for (auto &CInfo : info.caches) {\n      Out << \"  L\" << CInfo.level << \" \" << CInfo.type << \" \"\n          << (CInfo.size / 1024) << \" KiB\";\n      if (CInfo.num_sharing != 0)\n        Out << \" (x\" << (info.num_cpus / CInfo.num_sharing) << \")\";\n      Out << \"\\n\";\n    }\n  }\n  if (!info.load_avg.empty()) {\n    Out << \"Load Average: \";\n    for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {\n      Out << StrFormat(\"%.2f\", *It++);\n      if (It != info.load_avg.end()) Out << \", \";\n    }\n    Out << \"\\n\";\n  }\n\n  std::map<std::string, std::string> *global_context =\n      internal::GetGlobalContext();\n\n  if (global_context != nullptr) {\n    for (const auto &kv : *global_context) {\n      Out << kv.first << \": \" << kv.second << \"\\n\";\n    }\n  }\n\n  if (CPUInfo::Scaling::ENABLED == info.scaling) {\n    Out << \"***WARNING*** CPU scaling is enabled, the benchmark \"\n           \"real time measurements may be noisy and will incur extra \"\n           \"overhead.\\n\";\n  }\n\n#ifndef NDEBUG\n  Out << \"***WARNING*** Library was built as DEBUG. Timings may be \"\n         \"affected.\\n\";\n#endif\n}\n\n// No initializer because it's already initialized to NULL.\nconst char *BenchmarkReporter::Context::executable_name;\n\nBenchmarkReporter::Context::Context()\n    : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}\n\nstd::string BenchmarkReporter::Run::benchmark_name() const {\n  std::string name = run_name.str();\n  if (run_type == RT_Aggregate) {\n    name += \"_\" + aggregate_name;\n  }\n  return name;\n}\n\ndouble BenchmarkReporter::Run::GetAdjustedRealTime() const {\n  double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);\n  if (iterations != 0) new_time /= static_cast<double>(iterations);\n  return new_time;\n}\n\ndouble BenchmarkReporter::Run::GetAdjustedCPUTime() const {\n  double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit);\n  if (iterations != 0) new_time /= static_cast<double>(iterations);\n  return new_time;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/statistics.cc",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"statistics.h\"\n\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n\nnamespace benchmark {\n\nauto StatisticsSum = [](const std::vector<double>& v) {\n  return std::accumulate(v.begin(), v.end(), 0.0);\n};\n\ndouble StatisticsMean(const std::vector<double>& v) {\n  if (v.empty()) return 0.0;\n  return StatisticsSum(v) * (1.0 / static_cast<double>(v.size()));\n}\n\ndouble StatisticsMedian(const std::vector<double>& v) {\n  if (v.size() < 3) return StatisticsMean(v);\n  std::vector<double> copy(v);\n\n  auto center = copy.begin() + v.size() / 2;\n  std::nth_element(copy.begin(), center, copy.end());\n\n  // Did we have an odd number of samples?  If yes, then center is the median.\n  // If not, then we are looking for the average between center and the value\n  // before.  Instead of resorting, we just look for the max value before it,\n  // which is not necessarily the element immediately preceding `center` Since\n  // `copy` is only partially sorted by `nth_element`.\n  if (v.size() % 2 == 1) return *center;\n  auto center2 = std::max_element(copy.begin(), center);\n  return (*center + *center2) / 2.0;\n}\n\n// Return the sum of the squares of this sample set\nauto SumSquares = [](const std::vector<double>& v) {\n  return std::inner_product(v.begin(), v.end(), v.begin(), 0.0);\n};\n\nauto Sqr = [](const double dat) { return dat * dat; };\nauto Sqrt = [](const double dat) {\n  // Avoid NaN due to imprecision in the calculations\n  if (dat < 0.0) return 0.0;\n  return std::sqrt(dat);\n};\n\ndouble StatisticsStdDev(const std::vector<double>& v) {\n  const auto mean = StatisticsMean(v);\n  if (v.empty()) return mean;\n\n  // Sample standard deviation is undefined for n = 1\n  if (v.size() == 1) return 0.0;\n\n  const double avg_squares =\n      SumSquares(v) * (1.0 / static_cast<double>(v.size()));\n  return Sqrt(static_cast<double>(v.size()) /\n              (static_cast<double>(v.size()) - 1.0) *\n              (avg_squares - Sqr(mean)));\n}\n\ndouble StatisticsCV(const std::vector<double>& v) {\n  if (v.size() < 2) return 0.0;\n\n  const auto stddev = StatisticsStdDev(v);\n  const auto mean = StatisticsMean(v);\n\n  if (std::fpclassify(mean) == FP_ZERO) return 0.0;\n\n  return stddev / mean;\n}\n\nstd::vector<BenchmarkReporter::Run> ComputeStats(\n    const std::vector<BenchmarkReporter::Run>& reports) {\n  typedef BenchmarkReporter::Run Run;\n  std::vector<Run> results;\n\n  auto error_count = std::count_if(reports.begin(), reports.end(),\n                                   [](Run const& run) { return run.skipped; });\n\n  if (reports.size() - static_cast<size_t>(error_count) < 2) {\n    // We don't report aggregated data if there was a single run.\n    return results;\n  }\n\n  // Accumulators.\n  std::vector<double> real_accumulated_time_stat;\n  std::vector<double> cpu_accumulated_time_stat;\n\n  real_accumulated_time_stat.reserve(reports.size());\n  cpu_accumulated_time_stat.reserve(reports.size());\n\n  // All repetitions should be run with the same number of iterations so we\n  // can take this information from the first benchmark.\n  const IterationCount run_iterations = reports.front().iterations;\n  // create stats for user counters\n  struct CounterStat {\n    Counter c;\n    std::vector<double> s;\n  };\n  std::map<std::string, CounterStat> counter_stats;\n  for (Run const& r : reports) {\n    for (auto const& cnt : r.counters) {\n      auto it = counter_stats.find(cnt.first);\n      if (it == counter_stats.end()) {\n        it = counter_stats\n                 .emplace(cnt.first,\n                          CounterStat{cnt.second, std::vector<double>{}})\n                 .first;\n        it->second.s.reserve(reports.size());\n      } else {\n        BM_CHECK_EQ(it->second.c.flags, cnt.second.flags);\n      }\n    }\n  }\n\n  // Populate the accumulators.\n  for (Run const& run : reports) {\n    BM_CHECK_EQ(reports[0].benchmark_name(), run.benchmark_name());\n    BM_CHECK_EQ(run_iterations, run.iterations);\n    if (run.skipped) continue;\n    real_accumulated_time_stat.emplace_back(run.real_accumulated_time);\n    cpu_accumulated_time_stat.emplace_back(run.cpu_accumulated_time);\n    // user counters\n    for (auto const& cnt : run.counters) {\n      auto it = counter_stats.find(cnt.first);\n      BM_CHECK_NE(it, counter_stats.end());\n      it->second.s.emplace_back(cnt.second);\n    }\n  }\n\n  // Only add label if it is same for all runs\n  std::string report_label = reports[0].report_label;\n  for (std::size_t i = 1; i < reports.size(); i++) {\n    if (reports[i].report_label != report_label) {\n      report_label = \"\";\n      break;\n    }\n  }\n\n  const double iteration_rescale_factor =\n      double(reports.size()) / double(run_iterations);\n\n  for (const auto& Stat : *reports[0].statistics) {\n    // Get the data from the accumulator to BenchmarkReporter::Run's.\n    Run data;\n    data.run_name = reports[0].run_name;\n    data.family_index = reports[0].family_index;\n    data.per_family_instance_index = reports[0].per_family_instance_index;\n    data.run_type = BenchmarkReporter::Run::RT_Aggregate;\n    data.threads = reports[0].threads;\n    data.repetitions = reports[0].repetitions;\n    data.repetition_index = Run::no_repetition_index;\n    data.aggregate_name = Stat.name_;\n    data.aggregate_unit = Stat.unit_;\n    data.report_label = report_label;\n\n    // It is incorrect to say that an aggregate is computed over\n    // run's iterations, because those iterations already got averaged.\n    // Similarly, if there are N repetitions with 1 iterations each,\n    // an aggregate will be computed over N measurements, not 1.\n    // Thus it is best to simply use the count of separate reports.\n    data.iterations = static_cast<IterationCount>(reports.size());\n\n    data.real_accumulated_time = Stat.compute_(real_accumulated_time_stat);\n    data.cpu_accumulated_time = Stat.compute_(cpu_accumulated_time_stat);\n\n    if (data.aggregate_unit == StatisticUnit::kTime) {\n      // We will divide these times by data.iterations when reporting, but the\n      // data.iterations is not necessarily the scale of these measurements,\n      // because in each repetition, these timers are sum over all the iters.\n      // And if we want to say that the stats are over N repetitions and not\n      // M iterations, we need to multiply these by (N/M).\n      data.real_accumulated_time *= iteration_rescale_factor;\n      data.cpu_accumulated_time *= iteration_rescale_factor;\n    }\n\n    data.time_unit = reports[0].time_unit;\n\n    // user counters\n    for (auto const& kv : counter_stats) {\n      // Do *NOT* rescale the custom counters. They are already properly scaled.\n      const auto uc_stat = Stat.compute_(kv.second.s);\n      auto c = Counter(uc_stat, counter_stats[kv.first].c.flags,\n                       counter_stats[kv.first].c.oneK);\n      data.counters[kv.first] = c;\n    }\n\n    results.push_back(data);\n  }\n\n  return results;\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/statistics.h",
    "content": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#ifndef STATISTICS_H_\n#define STATISTICS_H_\n\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\n\n// Return a vector containing the mean, median and standard deviation\n// information (and any user-specified info) for the specified list of reports.\n// If 'reports' contains less than two non-errored runs an empty vector is\n// returned\nBENCHMARK_EXPORT\nstd::vector<BenchmarkReporter::Run> ComputeStats(\n    const std::vector<BenchmarkReporter::Run>& reports);\n\nBENCHMARK_EXPORT\ndouble StatisticsMean(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsMedian(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsStdDev(const std::vector<double>& v);\nBENCHMARK_EXPORT\ndouble StatisticsCV(const std::vector<double>& v);\n\n}  // end namespace benchmark\n\n#endif  // STATISTICS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/string_util.cc",
    "content": "#include \"string_util.h\"\n\n#include <array>\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n#include <cerrno>\n#endif\n#include <cmath>\n#include <cstdarg>\n#include <cstdio>\n#include <memory>\n#include <sstream>\n\n#include \"arraysize.h\"\n#include \"benchmark/benchmark.h\"\n\nnamespace benchmark {\nnamespace {\n// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.\nconst char* const kBigSIUnits[] = {\"k\", \"M\", \"G\", \"T\", \"P\", \"E\", \"Z\", \"Y\"};\n// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.\nconst char* const kBigIECUnits[] = {\"Ki\", \"Mi\", \"Gi\", \"Ti\",\n                                    \"Pi\", \"Ei\", \"Zi\", \"Yi\"};\n// milli, micro, nano, pico, femto, atto, zepto, yocto.\nconst char* const kSmallSIUnits[] = {\"m\", \"u\", \"n\", \"p\", \"f\", \"a\", \"z\", \"y\"};\n\n// We require that all three arrays have the same size.\nstatic_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),\n              \"SI and IEC unit arrays must be the same size\");\nstatic_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),\n              \"Small SI and Big SI unit arrays must be the same size\");\n\nstatic const int64_t kUnitsSize = arraysize(kBigSIUnits);\n\nvoid ToExponentAndMantissa(double val, int precision, double one_k,\n                           std::string* mantissa, int64_t* exponent) {\n  std::stringstream mantissa_stream;\n\n  if (val < 0) {\n    mantissa_stream << \"-\";\n    val = -val;\n  }\n\n  // Adjust threshold so that it never excludes things which can't be rendered\n  // in 'precision' digits.\n  const double adjusted_threshold =\n      std::max(1.0, 1.0 / std::pow(10.0, precision));\n  const double big_threshold = (adjusted_threshold * one_k) - 1;\n  const double small_threshold = adjusted_threshold;\n  // Values in ]simple_threshold,small_threshold[ will be printed as-is\n  const double simple_threshold = 0.01;\n\n  if (val > big_threshold) {\n    // Positive powers\n    double scaled = val;\n    for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {\n      scaled /= one_k;\n      if (scaled <= big_threshold) {\n        mantissa_stream << scaled;\n        *exponent = static_cast<int64_t>(i + 1);\n        *mantissa = mantissa_stream.str();\n        return;\n      }\n    }\n    mantissa_stream << val;\n    *exponent = 0;\n  } else if (val < small_threshold) {\n    // Negative powers\n    if (val < simple_threshold) {\n      double scaled = val;\n      for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {\n        scaled *= one_k;\n        if (scaled >= small_threshold) {\n          mantissa_stream << scaled;\n          *exponent = -static_cast<int64_t>(i + 1);\n          *mantissa = mantissa_stream.str();\n          return;\n        }\n      }\n    }\n    mantissa_stream << val;\n    *exponent = 0;\n  } else {\n    mantissa_stream << val;\n    *exponent = 0;\n  }\n  *mantissa = mantissa_stream.str();\n}\n\nstd::string ExponentToPrefix(int64_t exponent, bool iec) {\n  if (exponent == 0) return \"\";\n\n  const int64_t index = (exponent > 0 ? exponent - 1 : -exponent - 1);\n  if (index >= kUnitsSize) return \"\";\n\n  const char* const* array =\n      (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);\n\n  return std::string(array[index]);\n}\n\nstd::string ToBinaryStringFullySpecified(double value, int precision,\n                                         Counter::OneK one_k) {\n  std::string mantissa;\n  int64_t exponent;\n  ToExponentAndMantissa(value, precision,\n                        one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa,\n                        &exponent);\n  return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);\n}\n\nstd::string StrFormatImp(const char* msg, va_list args) {\n  // we might need a second shot at this, so pre-emptivly make a copy\n  va_list args_cp;\n  va_copy(args_cp, args);\n\n  // TODO(ericwf): use std::array for first attempt to avoid one memory\n  // allocation guess what the size might be\n  std::array<char, 256> local_buff;\n\n  // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation\n  // in the android-ndk\n  auto ret = vsnprintf(local_buff.data(), local_buff.size(), msg, args_cp);\n\n  va_end(args_cp);\n\n  // handle empty expansion\n  if (ret == 0) return std::string{};\n  if (static_cast<std::size_t>(ret) < local_buff.size())\n    return std::string(local_buff.data());\n\n  // we did not provide a long enough buffer on our first attempt.\n  // add 1 to size to account for null-byte in size cast to prevent overflow\n  std::size_t size = static_cast<std::size_t>(ret) + 1;\n  auto buff_ptr = std::unique_ptr<char[]>(new char[size]);\n  // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation\n  // in the android-ndk\n  vsnprintf(buff_ptr.get(), size, msg, args);\n  return std::string(buff_ptr.get());\n}\n\n}  // end namespace\n\nstd::string HumanReadableNumber(double n, Counter::OneK one_k) {\n  return ToBinaryStringFullySpecified(n, 1, one_k);\n}\n\nstd::string StrFormat(const char* format, ...) {\n  va_list args;\n  va_start(args, format);\n  std::string tmp = StrFormatImp(format, args);\n  va_end(args);\n  return tmp;\n}\n\nstd::vector<std::string> StrSplit(const std::string& str, char delim) {\n  if (str.empty()) return {};\n  std::vector<std::string> ret;\n  size_t first = 0;\n  size_t next = str.find(delim);\n  for (; next != std::string::npos;\n       first = next + 1, next = str.find(delim, first)) {\n    ret.push_back(str.substr(first, next - first));\n  }\n  ret.push_back(str.substr(first));\n  return ret;\n}\n\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n/*\n * GNU STL in Android NDK lacks support for some C++11 functions, including\n * stoul, stoi, stod. We reimplement them here using C functions strtoul,\n * strtol, strtod. Note that reimplemented functions are in benchmark::\n * namespace, not std:: namespace.\n */\nunsigned long stoul(const std::string& str, size_t* pos, int base) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const unsigned long result = strtoul(strStart, &strEnd, base);\n\n  const int strtoulErrno = errno;\n  /* Restore previous errno */\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtoulErrno == ERANGE) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of unsigned long\");\n  } else if (strEnd == strStart || strtoulErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return result;\n}\n\nint stoi(const std::string& str, size_t* pos, int base) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const long result = strtol(strStart, &strEnd, base);\n\n  const int strtolErrno = errno;\n  /* Restore previous errno */\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtolErrno == ERANGE || long(int(result)) != result) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of int\");\n  } else if (strEnd == strStart || strtolErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return int(result);\n}\n\ndouble stod(const std::string& str, size_t* pos) {\n  /* Record previous errno */\n  const int oldErrno = errno;\n  errno = 0;\n\n  const char* strStart = str.c_str();\n  char* strEnd = const_cast<char*>(strStart);\n  const double result = strtod(strStart, &strEnd);\n\n  /* Restore previous errno */\n  const int strtodErrno = errno;\n  errno = oldErrno;\n\n  /* Check for errors and return */\n  if (strtodErrno == ERANGE) {\n    throw std::out_of_range(\"stoul failed: \" + str +\n                            \" is outside of range of int\");\n  } else if (strEnd == strStart || strtodErrno != 0) {\n    throw std::invalid_argument(\"stoul failed: \" + str + \" is not an integer\");\n  }\n  if (pos != nullptr) {\n    *pos = static_cast<size_t>(strEnd - strStart);\n  }\n  return result;\n}\n#endif\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/string_util.h",
    "content": "#ifndef BENCHMARK_STRING_UTIL_H_\n#define BENCHMARK_STRING_UTIL_H_\n\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"benchmark/benchmark.h\"\n#include \"benchmark/export.h\"\n#include \"check.h\"\n#include \"internal_macros.h\"\n\nnamespace benchmark {\n\nBENCHMARK_EXPORT\nstd::string HumanReadableNumber(double n, Counter::OneK one_k);\n\nBENCHMARK_EXPORT\n#if defined(__MINGW32__)\n__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2)))\n#elif defined(__GNUC__)\n__attribute__((format(printf, 1, 2)))\n#endif\nstd::string\nStrFormat(const char* format, ...);\n\ninline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {\n  return out;\n}\n\ntemplate <class First, class... Rest>\ninline std::ostream& StrCatImp(std::ostream& out, First&& f, Rest&&... rest) {\n  out << std::forward<First>(f);\n  return StrCatImp(out, std::forward<Rest>(rest)...);\n}\n\ntemplate <class... Args>\ninline std::string StrCat(Args&&... args) {\n  std::ostringstream ss;\n  StrCatImp(ss, std::forward<Args>(args)...);\n  return ss.str();\n}\n\nBENCHMARK_EXPORT\nstd::vector<std::string> StrSplit(const std::string& str, char delim);\n\n// Disable lint checking for this block since it re-implements C functions.\n// NOLINTBEGIN\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n/*\n * GNU STL in Android NDK lacks support for some C++11 functions, including\n * stoul, stoi, stod. We reimplement them here using C functions strtoul,\n * strtol, strtod. Note that reimplemented functions are in benchmark::\n * namespace, not std:: namespace.\n */\nunsigned long stoul(const std::string& str, size_t* pos = nullptr,\n                    int base = 10);\nint stoi(const std::string& str, size_t* pos = nullptr, int base = 10);\ndouble stod(const std::string& str, size_t* pos = nullptr);\n#else\nusing std::stod;   // NOLINT(misc-unused-using-decls)\nusing std::stoi;   // NOLINT(misc-unused-using-decls)\nusing std::stoul;  // NOLINT(misc-unused-using-decls)\n#endif\n// NOLINTEND\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_STRING_UTIL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/sysinfo.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#if !defined(WINVER) || WINVER < 0x0600\n#undef WINVER\n#define WINVER 0x0600\n#endif  // WINVER handling\n#include <shlwapi.h>\n#undef StrCat  // Don't let StrCat in string_util.h be renamed to lstrcatA\n#include <versionhelpers.h>\n#include <windows.h>\n\n#include <codecvt>\n#else\n#include <fcntl.h>\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <sys/types.h>  // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD\n#include <unistd.h>\n#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX || \\\n    defined BENCHMARK_OS_NETBSD || defined BENCHMARK_OS_OPENBSD || \\\n    defined BENCHMARK_OS_DRAGONFLY\n#define BENCHMARK_HAS_SYSCTL\n#include <sys/sysctl.h>\n#endif\n#endif\n#if defined(BENCHMARK_OS_SOLARIS)\n#include <kstat.h>\n#include <netdb.h>\n#endif\n#if defined(BENCHMARK_OS_QNX)\n#include <sys/syspage.h>\n#endif\n#if defined(BENCHMARK_OS_QURT)\n#include <qurt.h>\n#endif\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n#include <pthread.h>\n#endif\n\n#include <algorithm>\n#include <array>\n#include <bitset>\n#include <cerrno>\n#include <climits>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <iterator>\n#include <limits>\n#include <locale>\n#include <memory>\n#include <random>\n#include <sstream>\n#include <utility>\n\n#include \"benchmark/benchmark.h\"\n#include \"check.h\"\n#include \"cycleclock.h\"\n#include \"internal_macros.h\"\n#include \"log.h\"\n#include \"string_util.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace {\n\nvoid PrintImp(std::ostream& out) { out << std::endl; }\n\ntemplate <class First, class... Rest>\nvoid PrintImp(std::ostream& out, First&& f, Rest&&... rest) {\n  out << std::forward<First>(f);\n  PrintImp(out, std::forward<Rest>(rest)...);\n}\n\ntemplate <class... Args>\nBENCHMARK_NORETURN void PrintErrorAndDie(Args&&... args) {\n  PrintImp(std::cerr, std::forward<Args>(args)...);\n  std::exit(EXIT_FAILURE);\n}\n\n#ifdef BENCHMARK_HAS_SYSCTL\n\n/// ValueUnion - A type used to correctly alias the byte-for-byte output of\n/// `sysctl` with the result type it's to be interpreted as.\nstruct ValueUnion {\n  union DataT {\n    int32_t int32_value;\n    int64_t int64_value;\n    // For correct aliasing of union members from bytes.\n    char bytes[8];\n  };\n  using DataPtr = std::unique_ptr<DataT, decltype(&std::free)>;\n\n  // The size of the data union member + its trailing array size.\n  std::size_t size;\n  DataPtr buff;\n\n public:\n  ValueUnion() : size(0), buff(nullptr, &std::free) {}\n\n  explicit ValueUnion(std::size_t buff_size)\n      : size(sizeof(DataT) + buff_size),\n        buff(::new (std::malloc(size)) DataT(), &std::free) {}\n\n  ValueUnion(ValueUnion&& other) = default;\n\n  explicit operator bool() const { return bool(buff); }\n\n  char* data() const { return buff->bytes; }\n\n  std::string GetAsString() const { return std::string(data()); }\n\n  int64_t GetAsInteger() const {\n    if (size == sizeof(buff->int32_value))\n      return buff->int32_value;\n    else if (size == sizeof(buff->int64_value))\n      return buff->int64_value;\n    BENCHMARK_UNREACHABLE();\n  }\n\n  template <class T, int N>\n  std::array<T, N> GetAsArray() {\n    const int arr_size = sizeof(T) * N;\n    BM_CHECK_LE(arr_size, size);\n    std::array<T, N> arr;\n    std::memcpy(arr.data(), data(), arr_size);\n    return arr;\n  }\n};\n\nValueUnion GetSysctlImp(std::string const& name) {\n#if defined BENCHMARK_OS_OPENBSD\n  int mib[2];\n\n  mib[0] = CTL_HW;\n  if ((name == \"hw.ncpu\") || (name == \"hw.cpuspeed\")) {\n    ValueUnion buff(sizeof(int));\n\n    if (name == \"hw.ncpu\") {\n      mib[1] = HW_NCPU;\n    } else {\n      mib[1] = HW_CPUSPEED;\n    }\n\n    if (sysctl(mib, 2, buff.data(), &buff.size, nullptr, 0) == -1) {\n      return ValueUnion();\n    }\n    return buff;\n  }\n  return ValueUnion();\n#else\n  std::size_t cur_buff_size = 0;\n  if (sysctlbyname(name.c_str(), nullptr, &cur_buff_size, nullptr, 0) == -1)\n    return ValueUnion();\n\n  ValueUnion buff(cur_buff_size);\n  if (sysctlbyname(name.c_str(), buff.data(), &buff.size, nullptr, 0) == 0)\n    return buff;\n  return ValueUnion();\n#endif\n}\n\nBENCHMARK_MAYBE_UNUSED\nbool GetSysctl(std::string const& name, std::string* out) {\n  out->clear();\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  out->assign(buff.data());\n  return true;\n}\n\ntemplate <class Tp,\n          class = typename std::enable_if<std::is_integral<Tp>::value>::type>\nbool GetSysctl(std::string const& name, Tp* out) {\n  *out = 0;\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  *out = static_cast<Tp>(buff.GetAsInteger());\n  return true;\n}\n\ntemplate <class Tp, size_t N>\nbool GetSysctl(std::string const& name, std::array<Tp, N>* out) {\n  auto buff = GetSysctlImp(name);\n  if (!buff) return false;\n  *out = buff.GetAsArray<Tp, N>();\n  return true;\n}\n#endif\n\ntemplate <class ArgT>\nbool ReadFromFile(std::string const& fname, ArgT* arg) {\n  *arg = ArgT();\n  std::ifstream f(fname.c_str());\n  if (!f.is_open()) return false;\n  f >> *arg;\n  return f.good();\n}\n\nCPUInfo::Scaling CpuScaling(int num_cpus) {\n  // We don't have a valid CPU count, so don't even bother.\n  if (num_cpus <= 0) return CPUInfo::Scaling::UNKNOWN;\n#if defined(BENCHMARK_OS_QNX)\n  return CPUInfo::Scaling::UNKNOWN;\n#elif !defined(BENCHMARK_OS_WINDOWS)\n  // On Linux, the CPUfreq subsystem exposes CPU information as files on the\n  // local file system. If reading the exported files fails, then we may not be\n  // running on Linux, so we silently ignore all the read errors.\n  std::string res;\n  for (int cpu = 0; cpu < num_cpus; ++cpu) {\n    std::string governor_file =\n        StrCat(\"/sys/devices/system/cpu/cpu\", cpu, \"/cpufreq/scaling_governor\");\n    if (ReadFromFile(governor_file, &res) && res != \"performance\")\n      return CPUInfo::Scaling::ENABLED;\n  }\n  return CPUInfo::Scaling::DISABLED;\n#else\n  return CPUInfo::Scaling::UNKNOWN;\n#endif\n}\n\nint CountSetBitsInCPUMap(std::string val) {\n  auto CountBits = [](std::string part) {\n    using CPUMask = std::bitset<sizeof(std::uintptr_t) * CHAR_BIT>;\n    part = \"0x\" + part;\n    CPUMask mask(benchmark::stoul(part, nullptr, 16));\n    return static_cast<int>(mask.count());\n  };\n  std::size_t pos;\n  int total = 0;\n  while ((pos = val.find(',')) != std::string::npos) {\n    total += CountBits(val.substr(0, pos));\n    val = val.substr(pos + 1);\n  }\n  if (!val.empty()) {\n    total += CountBits(val);\n  }\n  return total;\n}\n\nBENCHMARK_MAYBE_UNUSED\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesFromKVFS() {\n  std::vector<CPUInfo::CacheInfo> res;\n  std::string dir = \"/sys/devices/system/cpu/cpu0/cache/\";\n  int idx = 0;\n  while (true) {\n    CPUInfo::CacheInfo info;\n    std::string fpath = StrCat(dir, \"index\", idx++, \"/\");\n    std::ifstream f(StrCat(fpath, \"size\").c_str());\n    if (!f.is_open()) break;\n    std::string suffix;\n    f >> info.size;\n    if (f.fail())\n      PrintErrorAndDie(\"Failed while reading file '\", fpath, \"size'\");\n    if (f.good()) {\n      f >> suffix;\n      if (f.bad())\n        PrintErrorAndDie(\n            \"Invalid cache size format: failed to read size suffix\");\n      else if (f && suffix != \"K\")\n        PrintErrorAndDie(\"Invalid cache size format: Expected bytes \", suffix);\n      else if (suffix == \"K\")\n        info.size *= 1024;\n    }\n    if (!ReadFromFile(StrCat(fpath, \"type\"), &info.type))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"type\");\n    if (!ReadFromFile(StrCat(fpath, \"level\"), &info.level))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"level\");\n    std::string map_str;\n    if (!ReadFromFile(StrCat(fpath, \"shared_cpu_map\"), &map_str))\n      PrintErrorAndDie(\"Failed to read from file \", fpath, \"shared_cpu_map\");\n    info.num_sharing = CountSetBitsInCPUMap(map_str);\n    res.push_back(info);\n  }\n\n  return res;\n}\n\n#ifdef BENCHMARK_OS_MACOSX\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesMacOSX() {\n  std::vector<CPUInfo::CacheInfo> res;\n  std::array<int, 4> cache_counts{{0, 0, 0, 0}};\n  GetSysctl(\"hw.cacheconfig\", &cache_counts);\n\n  struct {\n    std::string name;\n    std::string type;\n    int level;\n    int num_sharing;\n  } cases[] = {{\"hw.l1dcachesize\", \"Data\", 1, cache_counts[1]},\n               {\"hw.l1icachesize\", \"Instruction\", 1, cache_counts[1]},\n               {\"hw.l2cachesize\", \"Unified\", 2, cache_counts[2]},\n               {\"hw.l3cachesize\", \"Unified\", 3, cache_counts[3]}};\n  for (auto& c : cases) {\n    int val;\n    if (!GetSysctl(c.name, &val)) continue;\n    CPUInfo::CacheInfo info;\n    info.type = c.type;\n    info.level = c.level;\n    info.size = val;\n    info.num_sharing = c.num_sharing;\n    res.push_back(std::move(info));\n  }\n  return res;\n}\n#elif defined(BENCHMARK_OS_WINDOWS)\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {\n  std::vector<CPUInfo::CacheInfo> res;\n  DWORD buffer_size = 0;\n  using PInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION;\n  using CInfo = CACHE_DESCRIPTOR;\n\n  using UPtr = std::unique_ptr<PInfo, decltype(&std::free)>;\n  GetLogicalProcessorInformation(nullptr, &buffer_size);\n  UPtr buff(static_cast<PInfo*>(std::malloc(buffer_size)), &std::free);\n  if (!GetLogicalProcessorInformation(buff.get(), &buffer_size))\n    PrintErrorAndDie(\"Failed during call to GetLogicalProcessorInformation: \",\n                     GetLastError());\n\n  PInfo* it = buff.get();\n  PInfo* end = buff.get() + (buffer_size / sizeof(PInfo));\n\n  for (; it != end; ++it) {\n    if (it->Relationship != RelationCache) continue;\n    using BitSet = std::bitset<sizeof(ULONG_PTR) * CHAR_BIT>;\n    BitSet b(it->ProcessorMask);\n    // To prevent duplicates, only consider caches where CPU 0 is specified\n    if (!b.test(0)) continue;\n    const CInfo& cache = it->Cache;\n    CPUInfo::CacheInfo C;\n    C.num_sharing = static_cast<int>(b.count());\n    C.level = cache.Level;\n    C.size = static_cast<int>(cache.Size);\n    C.type = \"Unknown\";\n    switch (cache.Type) {\n      case CacheUnified:\n        C.type = \"Unified\";\n        break;\n      case CacheInstruction:\n        C.type = \"Instruction\";\n        break;\n      case CacheData:\n        C.type = \"Data\";\n        break;\n      case CacheTrace:\n        C.type = \"Trace\";\n        break;\n    }\n    res.push_back(C);\n  }\n  return res;\n}\n#elif BENCHMARK_OS_QNX\nstd::vector<CPUInfo::CacheInfo> GetCacheSizesQNX() {\n  std::vector<CPUInfo::CacheInfo> res;\n  struct cacheattr_entry* cache = SYSPAGE_ENTRY(cacheattr);\n  uint32_t const elsize = SYSPAGE_ELEMENT_SIZE(cacheattr);\n  int num = SYSPAGE_ENTRY_SIZE(cacheattr) / elsize;\n  for (int i = 0; i < num; ++i) {\n    CPUInfo::CacheInfo info;\n    switch (cache->flags) {\n      case CACHE_FLAG_INSTR:\n        info.type = \"Instruction\";\n        info.level = 1;\n        break;\n      case CACHE_FLAG_DATA:\n        info.type = \"Data\";\n        info.level = 1;\n        break;\n      case CACHE_FLAG_UNIFIED:\n        info.type = \"Unified\";\n        info.level = 2;\n        break;\n      case CACHE_FLAG_SHARED:\n        info.type = \"Shared\";\n        info.level = 3;\n        break;\n      default:\n        continue;\n        break;\n    }\n    info.size = cache->line_size * cache->num_lines;\n    info.num_sharing = 0;\n    res.push_back(std::move(info));\n    cache = SYSPAGE_ARRAY_ADJ_OFFSET(cacheattr, cache, elsize);\n  }\n  return res;\n}\n#endif\n\nstd::vector<CPUInfo::CacheInfo> GetCacheSizes() {\n#ifdef BENCHMARK_OS_MACOSX\n  return GetCacheSizesMacOSX();\n#elif defined(BENCHMARK_OS_WINDOWS)\n  return GetCacheSizesWindows();\n#elif defined(BENCHMARK_OS_QNX)\n  return GetCacheSizesQNX();\n#elif defined(BENCHMARK_OS_QURT)\n  return std::vector<CPUInfo::CacheInfo>();\n#else\n  return GetCacheSizesFromKVFS();\n#endif\n}\n\nstd::string GetSystemName() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  std::string str;\n  static constexpr int COUNT = MAX_COMPUTERNAME_LENGTH + 1;\n  TCHAR hostname[COUNT] = {'\\0'};\n  DWORD DWCOUNT = COUNT;\n  if (!GetComputerName(hostname, &DWCOUNT)) return std::string(\"\");\n#ifndef UNICODE\n  str = std::string(hostname, DWCOUNT);\n#else\n  // `WideCharToMultiByte` returns `0` when conversion fails.\n  int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname,\n                                DWCOUNT, NULL, 0, NULL, NULL);\n  str.resize(len);\n  WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],\n                      str.size(), NULL, NULL);\n#endif\n  return str;\n#elif defined(BENCHMARK_OS_QURT)\n  std::string str = \"Hexagon DSP\";\n  qurt_arch_version_t arch_version_struct;\n  if (qurt_sysenv_get_arch_version(&arch_version_struct) == QURT_EOK) {\n    str += \" v\";\n    str += std::to_string(arch_version_struct.arch_version);\n  }\n  return str;\n#else\n#ifndef HOST_NAME_MAX\n#ifdef BENCHMARK_HAS_SYSCTL  // BSD/Mac doesn't have HOST_NAME_MAX defined\n#define HOST_NAME_MAX 64\n#elif defined(BENCHMARK_OS_NACL)\n#define HOST_NAME_MAX 64\n#elif defined(BENCHMARK_OS_QNX)\n#define HOST_NAME_MAX 154\n#elif defined(BENCHMARK_OS_RTEMS)\n#define HOST_NAME_MAX 256\n#elif defined(BENCHMARK_OS_SOLARIS)\n#define HOST_NAME_MAX MAXHOSTNAMELEN\n#elif defined(BENCHMARK_OS_ZOS)\n#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX\n#else\n#pragma message(\"HOST_NAME_MAX not defined. using 64\")\n#define HOST_NAME_MAX 64\n#endif\n#endif  // def HOST_NAME_MAX\n  char hostname[HOST_NAME_MAX];\n  int retVal = gethostname(hostname, HOST_NAME_MAX);\n  if (retVal != 0) return std::string(\"\");\n  return std::string(hostname);\n#endif  // Catch-all POSIX block.\n}\n\nint GetNumCPUsImpl() {\n#ifdef BENCHMARK_HAS_SYSCTL\n  int num_cpu = -1;\n  if (GetSysctl(\"hw.ncpu\", &num_cpu)) return num_cpu;\n  PrintErrorAndDie(\"Err: \", strerror(errno));\n#elif defined(BENCHMARK_OS_WINDOWS)\n  SYSTEM_INFO sysinfo;\n  // Use memset as opposed to = {} to avoid GCC missing initializer false\n  // positives.\n  std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO));\n  GetSystemInfo(&sysinfo);\n  // number of logical processors in the current group\n  return static_cast<int>(sysinfo.dwNumberOfProcessors);\n#elif defined(BENCHMARK_OS_SOLARIS)\n  // Returns -1 in case of a failure.\n  long num_cpu = sysconf(_SC_NPROCESSORS_ONLN);\n  if (num_cpu < 0) {\n    PrintErrorAndDie(\"sysconf(_SC_NPROCESSORS_ONLN) failed with error: \",\n                     strerror(errno));\n  }\n  return (int)num_cpu;\n#elif defined(BENCHMARK_OS_QNX)\n  return static_cast<int>(_syspage_ptr->num_cpu);\n#elif defined(BENCHMARK_OS_QURT)\n  qurt_sysenv_max_hthreads_t hardware_threads;\n  if (qurt_sysenv_get_max_hw_threads(&hardware_threads) != QURT_EOK) {\n    hardware_threads.max_hthreads = 1;\n  }\n  return hardware_threads.max_hthreads;\n#else\n  int num_cpus = 0;\n  int max_id = -1;\n  std::ifstream f(\"/proc/cpuinfo\");\n  if (!f.is_open()) {\n    std::cerr << \"Failed to open /proc/cpuinfo\\n\";\n    return -1;\n  }\n#if defined(__alpha__)\n  const std::string Key = \"cpus detected\";\n#else\n  const std::string Key = \"processor\";\n#endif\n  std::string ln;\n  while (std::getline(f, ln)) {\n    if (ln.empty()) continue;\n    std::size_t split_idx = ln.find(':');\n    std::string value;\n#if defined(__s390__)\n    // s390 has another format in /proc/cpuinfo\n    // it needs to be parsed differently\n    if (split_idx != std::string::npos)\n      value = ln.substr(Key.size() + 1, split_idx - Key.size() - 1);\n#else\n    if (split_idx != std::string::npos) value = ln.substr(split_idx + 1);\n#endif\n    if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) {\n      num_cpus++;\n      if (!value.empty()) {\n        const int cur_id = benchmark::stoi(value);\n        max_id = std::max(cur_id, max_id);\n      }\n    }\n  }\n  if (f.bad()) {\n    PrintErrorAndDie(\"Failure reading /proc/cpuinfo\");\n  }\n  if (!f.eof()) {\n    PrintErrorAndDie(\"Failed to read to end of /proc/cpuinfo\");\n  }\n  f.close();\n\n  if ((max_id + 1) != num_cpus) {\n    fprintf(stderr,\n            \"CPU ID assignments in /proc/cpuinfo seem messed up.\"\n            \" This is usually caused by a bad BIOS.\\n\");\n  }\n  return num_cpus;\n#endif\n  BENCHMARK_UNREACHABLE();\n}\n\nint GetNumCPUs() {\n  const int num_cpus = GetNumCPUsImpl();\n  if (num_cpus < 1) {\n    std::cerr << \"Unable to extract number of CPUs.  If your platform uses \"\n                 \"/proc/cpuinfo, custom support may need to be added.\\n\";\n  }\n  return num_cpus;\n}\n\nclass ThreadAffinityGuard final {\n public:\n  ThreadAffinityGuard() : reset_affinity(SetAffinity()) {\n    if (!reset_affinity)\n      std::cerr << \"***WARNING*** Failed to set thread affinity. Estimated CPU \"\n                   \"frequency may be incorrect.\"\n                << std::endl;\n  }\n\n  ~ThreadAffinityGuard() {\n    if (!reset_affinity) return;\n\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n    int ret = pthread_setaffinity_np(self, sizeof(previous_affinity),\n                                     &previous_affinity);\n    if (ret == 0) return;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n    DWORD_PTR ret = SetThreadAffinityMask(self, previous_affinity);\n    if (ret != 0) return;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n    PrintErrorAndDie(\"Failed to reset thread affinity\");\n  }\n\n  ThreadAffinityGuard(ThreadAffinityGuard&&) = delete;\n  ThreadAffinityGuard(const ThreadAffinityGuard&) = delete;\n  ThreadAffinityGuard& operator=(ThreadAffinityGuard&&) = delete;\n  ThreadAffinityGuard& operator=(const ThreadAffinityGuard&) = delete;\n\n private:\n  bool SetAffinity() {\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n    int ret;\n    self = pthread_self();\n    ret = pthread_getaffinity_np(self, sizeof(previous_affinity),\n                                 &previous_affinity);\n    if (ret != 0) return false;\n\n    cpu_set_t affinity;\n    memcpy(&affinity, &previous_affinity, sizeof(affinity));\n\n    bool is_first_cpu = true;\n\n    for (int i = 0; i < CPU_SETSIZE; ++i)\n      if (CPU_ISSET(i, &affinity)) {\n        if (is_first_cpu)\n          is_first_cpu = false;\n        else\n          CPU_CLR(i, &affinity);\n      }\n\n    if (is_first_cpu) return false;\n\n    ret = pthread_setaffinity_np(self, sizeof(affinity), &affinity);\n    return ret == 0;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n    self = GetCurrentThread();\n    DWORD_PTR mask = static_cast<DWORD_PTR>(1) << GetCurrentProcessorNumber();\n    previous_affinity = SetThreadAffinityMask(self, mask);\n    return previous_affinity != 0;\n#else\n    return false;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n  }\n\n#if defined(BENCHMARK_HAS_PTHREAD_AFFINITY)\n  pthread_t self;\n  cpu_set_t previous_affinity;\n#elif defined(BENCHMARK_OS_WINDOWS_WIN32)\n  HANDLE self;\n  DWORD_PTR previous_affinity;\n#endif  // def BENCHMARK_HAS_PTHREAD_AFFINITY\n  bool reset_affinity;\n};\n\ndouble GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) {\n  // Currently, scaling is only used on linux path here,\n  // suppress diagnostics about it being unused on other paths.\n  (void)scaling;\n\n#if defined BENCHMARK_OS_LINUX || defined BENCHMARK_OS_CYGWIN\n  long freq;\n\n  // If the kernel is exporting the tsc frequency use that. There are issues\n  // where cpuinfo_max_freq cannot be relied on because the BIOS may be\n  // exporintg an invalid p-state (on x86) or p-states may be used to put the\n  // processor in a new mode (turbo mode). Essentially, those frequencies\n  // cannot always be relied upon. The same reasons apply to /proc/cpuinfo as\n  // well.\n  if (ReadFromFile(\"/sys/devices/system/cpu/cpu0/tsc_freq_khz\", &freq)\n      // If CPU scaling is disabled, use the *current* frequency.\n      // Note that we specifically don't want to read cpuinfo_cur_freq,\n      // because it is only readable by root.\n      || (scaling == CPUInfo::Scaling::DISABLED &&\n          ReadFromFile(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq\",\n                       &freq))\n      // Otherwise, if CPU scaling may be in effect, we want to use\n      // the *maximum* frequency, not whatever CPU speed some random processor\n      // happens to be using now.\n      || ReadFromFile(\"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\",\n                      &freq)) {\n    // The value is in kHz (as the file name suggests).  For example, on a\n    // 2GHz warpstation, the file contains the value \"2000000\".\n    return static_cast<double>(freq) * 1000.0;\n  }\n\n  const double error_value = -1;\n  double bogo_clock = error_value;\n\n  std::ifstream f(\"/proc/cpuinfo\");\n  if (!f.is_open()) {\n    std::cerr << \"failed to open /proc/cpuinfo\\n\";\n    return error_value;\n  }\n\n  auto StartsWithKey = [](std::string const& Value, std::string const& Key) {\n    if (Key.size() > Value.size()) return false;\n    auto Cmp = [&](char X, char Y) {\n      return std::tolower(X) == std::tolower(Y);\n    };\n    return std::equal(Key.begin(), Key.end(), Value.begin(), Cmp);\n  };\n\n  std::string ln;\n  while (std::getline(f, ln)) {\n    if (ln.empty()) continue;\n    std::size_t split_idx = ln.find(':');\n    std::string value;\n    if (split_idx != std::string::npos) value = ln.substr(split_idx + 1);\n    // When parsing the \"cpu MHz\" and \"bogomips\" (fallback) entries, we only\n    // accept positive values. Some environments (virtual machines) report zero,\n    // which would cause infinite looping in WallTime_Init.\n    if (StartsWithKey(ln, \"cpu MHz\")) {\n      if (!value.empty()) {\n        double cycles_per_second = benchmark::stod(value) * 1000000.0;\n        if (cycles_per_second > 0) return cycles_per_second;\n      }\n    } else if (StartsWithKey(ln, \"bogomips\")) {\n      if (!value.empty()) {\n        bogo_clock = benchmark::stod(value) * 1000000.0;\n        if (bogo_clock < 0.0) bogo_clock = error_value;\n      }\n    }\n  }\n  if (f.bad()) {\n    std::cerr << \"Failure reading /proc/cpuinfo\\n\";\n    return error_value;\n  }\n  if (!f.eof()) {\n    std::cerr << \"Failed to read to end of /proc/cpuinfo\\n\";\n    return error_value;\n  }\n  f.close();\n  // If we found the bogomips clock, but nothing better, we'll use it (but\n  // we're not happy about it); otherwise, fallback to the rough estimation\n  // below.\n  if (bogo_clock >= 0.0) return bogo_clock;\n\n#elif defined BENCHMARK_HAS_SYSCTL\n  constexpr auto* freqStr =\n#if defined(BENCHMARK_OS_FREEBSD) || defined(BENCHMARK_OS_NETBSD)\n      \"machdep.tsc_freq\";\n#elif defined BENCHMARK_OS_OPENBSD\n      \"hw.cpuspeed\";\n#elif defined BENCHMARK_OS_DRAGONFLY\n      \"hw.tsc_frequency\";\n#else\n      \"hw.cpufrequency\";\n#endif\n  unsigned long long hz = 0;\n#if defined BENCHMARK_OS_OPENBSD\n  if (GetSysctl(freqStr, &hz)) return static_cast<double>(hz * 1000000);\n#else\n  if (GetSysctl(freqStr, &hz)) return static_cast<double>(hz);\n#endif\n  fprintf(stderr, \"Unable to determine clock rate from sysctl: %s: %s\\n\",\n          freqStr, strerror(errno));\n  fprintf(stderr,\n          \"This does not affect benchmark measurements, only the \"\n          \"metadata output.\\n\");\n\n#elif defined BENCHMARK_OS_WINDOWS_WIN32\n  // In NT, read MHz from the registry. If we fail to do so or we're in win9x\n  // then make a crude estimate.\n  DWORD data, data_size = sizeof(data);\n  if (IsWindowsXPOrGreater() &&\n      SUCCEEDED(\n          SHGetValueA(HKEY_LOCAL_MACHINE,\n                      \"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n                      \"~MHz\", nullptr, &data, &data_size)))\n    return static_cast<double>(static_cast<int64_t>(data) *\n                               static_cast<int64_t>(1000 * 1000));  // was mhz\n#elif defined(BENCHMARK_OS_SOLARIS)\n  kstat_ctl_t* kc = kstat_open();\n  if (!kc) {\n    std::cerr << \"failed to open /dev/kstat\\n\";\n    return -1;\n  }\n  kstat_t* ksp = kstat_lookup(kc, const_cast<char*>(\"cpu_info\"), -1,\n                              const_cast<char*>(\"cpu_info0\"));\n  if (!ksp) {\n    std::cerr << \"failed to lookup in /dev/kstat\\n\";\n    return -1;\n  }\n  if (kstat_read(kc, ksp, NULL) < 0) {\n    std::cerr << \"failed to read from /dev/kstat\\n\";\n    return -1;\n  }\n  kstat_named_t* knp = (kstat_named_t*)kstat_data_lookup(\n      ksp, const_cast<char*>(\"current_clock_Hz\"));\n  if (!knp) {\n    std::cerr << \"failed to lookup data in /dev/kstat\\n\";\n    return -1;\n  }\n  if (knp->data_type != KSTAT_DATA_UINT64) {\n    std::cerr << \"current_clock_Hz is of unexpected data type: \"\n              << knp->data_type << \"\\n\";\n    return -1;\n  }\n  double clock_hz = knp->value.ui64;\n  kstat_close(kc);\n  return clock_hz;\n#elif defined(BENCHMARK_OS_QNX)\n  return static_cast<double>(\n      static_cast<int64_t>(SYSPAGE_ENTRY(cpuinfo)->speed) *\n      static_cast<int64_t>(1000 * 1000));\n#elif defined(BENCHMARK_OS_QURT)\n  // QuRT doesn't provide any API to query Hexagon frequency.\n  return 1000000000;\n#endif\n  // If we've fallen through, attempt to roughly estimate the CPU clock rate.\n\n  // Make sure to use the same cycle counter when starting and stopping the\n  // cycle timer. We just pin the current thread to a cpu in the previous\n  // affinity set.\n  ThreadAffinityGuard affinity_guard;\n\n  static constexpr double estimate_time_s = 1.0;\n  const double start_time = ChronoClockNow();\n  const auto start_ticks = cycleclock::Now();\n\n  // Impose load instead of calling sleep() to make sure the cycle counter\n  // works.\n  using PRNG = std::minstd_rand;\n  using Result = PRNG::result_type;\n  PRNG rng(static_cast<Result>(start_ticks));\n\n  Result state = 0;\n\n  do {\n    static constexpr size_t batch_size = 10000;\n    rng.discard(batch_size);\n    state += rng();\n\n  } while (ChronoClockNow() - start_time < estimate_time_s);\n\n  DoNotOptimize(state);\n\n  const auto end_ticks = cycleclock::Now();\n  const double end_time = ChronoClockNow();\n\n  return static_cast<double>(end_ticks - start_ticks) / (end_time - start_time);\n  // Reset the affinity of current thread when the lifetime of affinity_guard\n  // ends.\n}\n\nstd::vector<double> GetLoadAvg() {\n#if (defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) ||     \\\n     defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD ||      \\\n     defined BENCHMARK_OS_OPENBSD || defined BENCHMARK_OS_DRAGONFLY) && \\\n    !(defined(__ANDROID__) && __ANDROID_API__ < 29)\n  static constexpr int kMaxSamples = 3;\n  std::vector<double> res(kMaxSamples, 0.0);\n  const size_t nelem = static_cast<size_t>(getloadavg(res.data(), kMaxSamples));\n  if (nelem < 1) {\n    res.clear();\n  } else {\n    res.resize(nelem);\n  }\n  return res;\n#else\n  return {};\n#endif\n}\n\n}  // end namespace\n\nconst CPUInfo& CPUInfo::Get() {\n  static const CPUInfo* info = new CPUInfo();\n  return *info;\n}\n\nCPUInfo::CPUInfo()\n    : num_cpus(GetNumCPUs()),\n      scaling(CpuScaling(num_cpus)),\n      cycles_per_second(GetCPUCyclesPerSecond(scaling)),\n      caches(GetCacheSizes()),\n      load_avg(GetLoadAvg()) {}\n\nconst SystemInfo& SystemInfo::Get() {\n  static const SystemInfo* info = new SystemInfo();\n  return *info;\n}\n\nSystemInfo::SystemInfo() : name(GetSystemName()) {}\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/thread_manager.h",
    "content": "#ifndef BENCHMARK_THREAD_MANAGER_H\n#define BENCHMARK_THREAD_MANAGER_H\n\n#include <atomic>\n\n#include \"benchmark/benchmark.h\"\n#include \"mutex.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nclass ThreadManager {\n public:\n  explicit ThreadManager(int num_threads)\n      : alive_threads_(num_threads), start_stop_barrier_(num_threads) {}\n\n  Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {\n    return benchmark_mutex_;\n  }\n\n  bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {\n    return start_stop_barrier_.wait();\n  }\n\n  void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {\n    start_stop_barrier_.removeThread();\n    if (--alive_threads_ == 0) {\n      MutexLock lock(end_cond_mutex_);\n      end_condition_.notify_all();\n    }\n  }\n\n  void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {\n    MutexLock lock(end_cond_mutex_);\n    end_condition_.wait(lock.native_handle(),\n                        [this]() { return alive_threads_ == 0; });\n  }\n\n  struct Result {\n    IterationCount iterations = 0;\n    double real_time_used = 0;\n    double cpu_time_used = 0;\n    double manual_time_used = 0;\n    int64_t complexity_n = 0;\n    std::string report_label_;\n    std::string skip_message_;\n    internal::Skipped skipped_ = internal::NotSkipped;\n    UserCounters counters;\n  };\n  GUARDED_BY(GetBenchmarkMutex()) Result results;\n\n private:\n  mutable Mutex benchmark_mutex_;\n  std::atomic<int> alive_threads_;\n  Barrier start_stop_barrier_;\n  Mutex end_cond_mutex_;\n  Condition end_condition_;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_THREAD_MANAGER_H\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/thread_timer.h",
    "content": "#ifndef BENCHMARK_THREAD_TIMER_H\n#define BENCHMARK_THREAD_TIMER_H\n\n#include \"check.h\"\n#include \"timers.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nclass ThreadTimer {\n  explicit ThreadTimer(bool measure_process_cpu_time_)\n      : measure_process_cpu_time(measure_process_cpu_time_) {}\n\n public:\n  static ThreadTimer Create() {\n    return ThreadTimer(/*measure_process_cpu_time_=*/false);\n  }\n  static ThreadTimer CreateProcessCpuTime() {\n    return ThreadTimer(/*measure_process_cpu_time_=*/true);\n  }\n\n  // Called by each thread\n  void StartTimer() {\n    running_ = true;\n    start_real_time_ = ChronoClockNow();\n    start_cpu_time_ = ReadCpuTimerOfChoice();\n  }\n\n  // Called by each thread\n  void StopTimer() {\n    BM_CHECK(running_);\n    running_ = false;\n    real_time_used_ += ChronoClockNow() - start_real_time_;\n    // Floating point error can result in the subtraction producing a negative\n    // time. Guard against that.\n    cpu_time_used_ +=\n        std::max<double>(ReadCpuTimerOfChoice() - start_cpu_time_, 0);\n  }\n\n  // Called by each thread\n  void SetIterationTime(double seconds) { manual_time_used_ += seconds; }\n\n  bool running() const { return running_; }\n\n  // REQUIRES: timer is not running\n  double real_time_used() const {\n    BM_CHECK(!running_);\n    return real_time_used_;\n  }\n\n  // REQUIRES: timer is not running\n  double cpu_time_used() const {\n    BM_CHECK(!running_);\n    return cpu_time_used_;\n  }\n\n  // REQUIRES: timer is not running\n  double manual_time_used() const {\n    BM_CHECK(!running_);\n    return manual_time_used_;\n  }\n\n private:\n  double ReadCpuTimerOfChoice() const {\n    if (measure_process_cpu_time) return ProcessCPUUsage();\n    return ThreadCPUUsage();\n  }\n\n  // should the thread, or the process, time be measured?\n  const bool measure_process_cpu_time;\n\n  bool running_ = false;        // Is the timer running\n  double start_real_time_ = 0;  // If running_\n  double start_cpu_time_ = 0;   // If running_\n\n  // Accumulated time so far (does not contain current slice if running_)\n  double real_time_used_ = 0;\n  double cpu_time_used_ = 0;\n  // Manually set iteration time. User sets this with SetIterationTime(seconds).\n  double manual_time_used_ = 0;\n};\n\n}  // namespace internal\n}  // namespace benchmark\n\n#endif  // BENCHMARK_THREAD_TIMER_H\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/timers.cc",
    "content": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#include \"timers.h\"\n\n#include \"internal_macros.h\"\n\n#ifdef BENCHMARK_OS_WINDOWS\n#include <shlwapi.h>\n#undef StrCat  // Don't let StrCat in string_util.h be renamed to lstrcatA\n#include <versionhelpers.h>\n#include <windows.h>\n#else\n#include <fcntl.h>\n#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\n#include <sys/resource.h>\n#endif\n#include <sys/time.h>\n#include <sys/types.h>  // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD\n#include <unistd.h>\n#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_DRAGONFLY || \\\n    defined BENCHMARK_OS_MACOSX\n#include <sys/sysctl.h>\n#endif\n#if defined(BENCHMARK_OS_MACOSX)\n#include <mach/mach_init.h>\n#include <mach/mach_port.h>\n#include <mach/thread_act.h>\n#endif\n#if defined(BENCHMARK_OS_QURT)\n#include <qurt.h>\n#endif\n#endif\n\n#ifdef BENCHMARK_OS_EMSCRIPTEN\n#include <emscripten.h>\n#endif\n\n#include <cerrno>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <ctime>\n#include <iostream>\n#include <limits>\n#include <mutex>\n\n#include \"check.h\"\n#include \"log.h\"\n#include \"string_util.h\"\n\nnamespace benchmark {\n\n// Suppress unused warnings on helper functions.\n#if defined(__GNUC__)\n#pragma GCC diagnostic ignored \"-Wunused-function\"\n#endif\n#if defined(__NVCOMPILER)\n#pragma diag_suppress declared_but_not_referenced\n#endif\n\nnamespace {\n#if defined(BENCHMARK_OS_WINDOWS)\ndouble MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {\n  ULARGE_INTEGER kernel;\n  ULARGE_INTEGER user;\n  kernel.HighPart = kernel_time.dwHighDateTime;\n  kernel.LowPart = kernel_time.dwLowDateTime;\n  user.HighPart = user_time.dwHighDateTime;\n  user.LowPart = user_time.dwLowDateTime;\n  return (static_cast<double>(kernel.QuadPart) +\n          static_cast<double>(user.QuadPart)) *\n         1e-7;\n}\n#elif !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)\ndouble MakeTime(struct rusage const& ru) {\n  return (static_cast<double>(ru.ru_utime.tv_sec) +\n          static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +\n          static_cast<double>(ru.ru_stime.tv_sec) +\n          static_cast<double>(ru.ru_stime.tv_usec) * 1e-6);\n}\n#endif\n#if defined(BENCHMARK_OS_MACOSX)\ndouble MakeTime(thread_basic_info_data_t const& info) {\n  return (static_cast<double>(info.user_time.seconds) +\n          static_cast<double>(info.user_time.microseconds) * 1e-6 +\n          static_cast<double>(info.system_time.seconds) +\n          static_cast<double>(info.system_time.microseconds) * 1e-6);\n}\n#endif\n#if defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_THREAD_CPUTIME_ID)\ndouble MakeTime(struct timespec const& ts) {\n  return static_cast<double>(ts.tv_sec) +\n         (static_cast<double>(ts.tv_nsec) * 1e-9);\n}\n#endif\n\nBENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) {\n  std::cerr << \"ERROR: \" << msg << std::endl;\n  std::exit(EXIT_FAILURE);\n}\n\n}  // end namespace\n\ndouble ProcessCPUUsage() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  HANDLE proc = GetCurrentProcess();\n  FILETIME creation_time;\n  FILETIME exit_time;\n  FILETIME kernel_time;\n  FILETIME user_time;\n  if (GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time,\n                      &user_time))\n    return MakeTime(kernel_time, user_time);\n  DiagnoseAndExit(\"GetProccessTimes() failed\");\n#elif defined(BENCHMARK_OS_QURT)\n  // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,\n  // and doesn't appear to work on at least some devices (eg Samsung S22),\n  // so let's use the actually-documented and apparently-equivalent\n  // qurt_sysclock_get_hw_ticks() call instead.\n  return static_cast<double>(\n             qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *\n         1.0e-6;\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten.\n  // Use Emscripten-specific API. Reported CPU time would be exactly the\n  // same as total time, but this is ok because there aren't long-latency\n  // synchronous system calls in Emscripten.\n  return emscripten_get_now() * 1e-3;\n#elif defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX)\n  // FIXME We want to use clock_gettime, but its not available in MacOS 10.11.\n  // See https://github.com/google/benchmark/pull/292\n  struct timespec spec;\n  if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0)\n    return MakeTime(spec);\n  DiagnoseAndExit(\"clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed\");\n#else\n  struct rusage ru;\n  if (getrusage(RUSAGE_SELF, &ru) == 0) return MakeTime(ru);\n  DiagnoseAndExit(\"getrusage(RUSAGE_SELF, ...) failed\");\n#endif\n}\n\ndouble ThreadCPUUsage() {\n#if defined(BENCHMARK_OS_WINDOWS)\n  HANDLE this_thread = GetCurrentThread();\n  FILETIME creation_time;\n  FILETIME exit_time;\n  FILETIME kernel_time;\n  FILETIME user_time;\n  GetThreadTimes(this_thread, &creation_time, &exit_time, &kernel_time,\n                 &user_time);\n  return MakeTime(kernel_time, user_time);\n#elif defined(BENCHMARK_OS_QURT)\n  // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,\n  // and doesn't appear to work on at least some devices (eg Samsung S22),\n  // so let's use the actually-documented and apparently-equivalent\n  // qurt_sysclock_get_hw_ticks() call instead.\n  return static_cast<double>(\n             qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *\n         1.0e-6;\n#elif defined(BENCHMARK_OS_MACOSX)\n  // FIXME We want to use clock_gettime, but its not available in MacOS 10.11.\n  // See https://github.com/google/benchmark/pull/292\n  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;\n  thread_basic_info_data_t info;\n  mach_port_t thread = pthread_mach_thread_np(pthread_self());\n  if (thread_info(thread, THREAD_BASIC_INFO,\n                  reinterpret_cast<thread_info_t>(&info),\n                  &count) == KERN_SUCCESS) {\n    return MakeTime(info);\n  }\n  DiagnoseAndExit(\"ThreadCPUUsage() failed when evaluating thread_info\");\n#elif defined(BENCHMARK_OS_EMSCRIPTEN)\n  // Emscripten doesn't support traditional threads\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_RTEMS)\n  // RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See\n  // https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_ZOS)\n  // z/OS doesn't support CLOCK_THREAD_CPUTIME_ID.\n  return ProcessCPUUsage();\n#elif defined(BENCHMARK_OS_SOLARIS)\n  struct rusage ru;\n  if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru);\n  DiagnoseAndExit(\"getrusage(RUSAGE_LWP, ...) failed\");\n#elif defined(CLOCK_THREAD_CPUTIME_ID)\n  struct timespec ts;\n  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);\n  DiagnoseAndExit(\"clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed\");\n#else\n#error Per-thread timing is not available on your system.\n#endif\n}\n\nstd::string LocalDateTimeString() {\n  // Write the local time in RFC3339 format yyyy-mm-ddTHH:MM:SS+/-HH:MM.\n  typedef std::chrono::system_clock Clock;\n  std::time_t now = Clock::to_time_t(Clock::now());\n  const std::size_t kTzOffsetLen = 6;\n  const std::size_t kTimestampLen = 19;\n\n  std::size_t tz_len;\n  std::size_t timestamp_len;\n  long int offset_minutes;\n  char tz_offset_sign = '+';\n  // tz_offset is set in one of three ways:\n  // * strftime with %z - This either returns empty or the ISO 8601 time.  The\n  // maximum length an\n  //   ISO 8601 string can be is 7 (e.g. -03:30, plus trailing zero).\n  // * snprintf with %c%02li:%02li - The maximum length is 41 (one for %c, up to\n  // 19 for %02li,\n  //   one for :, up to 19 %02li, plus trailing zero).\n  // * A fixed string of \"-00:00\".  The maximum length is 7 (-00:00, plus\n  // trailing zero).\n  //\n  // Thus, the maximum size this needs to be is 41.\n  char tz_offset[41];\n  // Long enough buffer to avoid format-overflow warnings\n  char storage[128];\n\n#if defined(BENCHMARK_OS_WINDOWS)\n  std::tm* timeinfo_p = ::localtime(&now);\n#else\n  std::tm timeinfo;\n  std::tm* timeinfo_p = &timeinfo;\n  ::localtime_r(&now, &timeinfo);\n#endif\n\n  tz_len = std::strftime(tz_offset, sizeof(tz_offset), \"%z\", timeinfo_p);\n\n  if (tz_len < kTzOffsetLen && tz_len > 1) {\n    // Timezone offset was written. strftime writes offset as +HHMM or -HHMM,\n    // RFC3339 specifies an offset as +HH:MM or -HH:MM. To convert, we parse\n    // the offset as an integer, then reprint it to a string.\n\n    offset_minutes = ::strtol(tz_offset, NULL, 10);\n    if (offset_minutes < 0) {\n      offset_minutes *= -1;\n      tz_offset_sign = '-';\n    }\n\n    tz_len = static_cast<size_t>(\n        ::snprintf(tz_offset, sizeof(tz_offset), \"%c%02li:%02li\",\n                   tz_offset_sign, offset_minutes / 100, offset_minutes % 100));\n    BM_CHECK(tz_len == kTzOffsetLen);\n    ((void)tz_len);  // Prevent unused variable warning in optimized build.\n  } else {\n    // Unknown offset. RFC3339 specifies that unknown local offsets should be\n    // written as UTC time with -00:00 timezone.\n#if defined(BENCHMARK_OS_WINDOWS)\n    // Potential race condition if another thread calls localtime or gmtime.\n    timeinfo_p = ::gmtime(&now);\n#else\n    ::gmtime_r(&now, &timeinfo);\n#endif\n\n    strncpy(tz_offset, \"-00:00\", kTzOffsetLen + 1);\n  }\n\n  timestamp_len =\n      std::strftime(storage, sizeof(storage), \"%Y-%m-%dT%H:%M:%S\", timeinfo_p);\n  BM_CHECK(timestamp_len == kTimestampLen);\n  // Prevent unused variable warning in optimized build.\n  ((void)kTimestampLen);\n\n  std::strncat(storage, tz_offset, sizeof(storage) - timestamp_len - 1);\n  return std::string(storage);\n}\n\n}  // end namespace benchmark\n"
  },
  {
    "path": "vendor/noa/vendor/googlebenchmark/src/timers.h",
    "content": "#ifndef BENCHMARK_TIMERS_H\n#define BENCHMARK_TIMERS_H\n\n#include <chrono>\n#include <string>\n\nnamespace benchmark {\n\n// Return the CPU usage of the current process\ndouble ProcessCPUUsage();\n\n// Return the CPU usage of the children of the current process\ndouble ChildrenCPUUsage();\n\n// Return the CPU usage of the current thread\ndouble ThreadCPUUsage();\n\n#if defined(BENCHMARK_OS_QURT)\n\n// std::chrono::now() can return 0 on some Hexagon devices;\n// this reads the value of a 56-bit, 19.2MHz hardware counter\n// and converts it to seconds. Unlike std::chrono, this doesn't\n// return an absolute time, but since ChronoClockNow() is only used\n// to compute elapsed time, this shouldn't matter.\nstruct QuRTClock {\n  typedef uint64_t rep;\n  typedef std::ratio<1, 19200000> period;\n  typedef std::chrono::duration<rep, period> duration;\n  typedef std::chrono::time_point<QuRTClock> time_point;\n  static const bool is_steady = false;\n\n  static time_point now() {\n    unsigned long long count;\n    asm volatile(\" %0 = c31:30 \" : \"=r\"(count));\n    return time_point(static_cast<duration>(count));\n  }\n};\n\n#else\n\n#if defined(HAVE_STEADY_CLOCK)\ntemplate <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>\nstruct ChooseSteadyClock {\n  typedef std::chrono::high_resolution_clock type;\n};\n\ntemplate <>\nstruct ChooseSteadyClock<false> {\n  typedef std::chrono::steady_clock type;\n};\n#endif  // HAVE_STEADY_CLOCK\n\n#endif\n\nstruct ChooseClockType {\n#if defined(BENCHMARK_OS_QURT)\n  typedef QuRTClock type;\n#elif defined(HAVE_STEADY_CLOCK)\n  typedef ChooseSteadyClock<>::type type;\n#else\n  typedef std::chrono::high_resolution_clock type;\n#endif\n};\n\ninline double ChronoClockNow() {\n  typedef ChooseClockType::type ClockType;\n  using FpSeconds = std::chrono::duration<double, std::chrono::seconds::period>;\n  return FpSeconds(ClockType::now().time_since_epoch()).count();\n}\n\nstd::string LocalDateTimeString();\n\n}  // end namespace benchmark\n\n#endif  // BENCHMARK_TIMERS_H\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/CMakeLists.txt",
    "content": "# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n\ncmake_minimum_required(VERSION 3.13)\n\nproject(googletest-distribution)\nset(GOOGLETEST_VERSION 1.14.0)\n\nif(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)\n  set(CMAKE_CXX_EXTENSIONS OFF)\nendif()\n\nenable_testing()\n\ninclude(CMakeDependentOption)\ninclude(GNUInstallDirs)\n\n# Note that googlemock target already builds googletest.\noption(BUILD_GMOCK \"Builds the googlemock subproject\" ON)\noption(INSTALL_GTEST \"Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)\" ON)\noption(GTEST_HAS_ABSL \"Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build.\" OFF)\n\nif(GTEST_HAS_ABSL)\n  if(NOT TARGET absl::base)\n    find_package(absl REQUIRED)\n  endif()\n  if(NOT TARGET re2::re2)\n    find_package(re2 REQUIRED)\n  endif()\nendif()\n\nif(BUILD_GMOCK)\n  add_subdirectory( googlemock )\nelse()\n  add_subdirectory( googletest )\nendif()\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/LICENSE",
    "content": "Copyright 2008, Google Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n    * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/CMakeLists.txt",
    "content": "########################################################################\n# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n#\n# CMake build script for Google Mock.\n#\n# To run the tests for Google Mock itself on Linux, use 'make test' or\n# ctest. You can select which tests to run using 'ctest -R regex'.\n# For more options, run 'ctest --help'.\n\noption(gmock_build_tests \"Build all of Google Mock's own tests.\" OFF)\n\n# A directory to find Google Test sources.\nif (EXISTS \"${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt\")\n  set(gtest_dir gtest)\nelse()\n  set(gtest_dir ../googletest)\nendif()\n\n# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().\ninclude(\"${gtest_dir}/cmake/hermetic_build.cmake\" OPTIONAL)\n\nif (COMMAND pre_project_set_up_hermetic_build)\n  # Google Test also calls hermetic setup functions from add_subdirectory,\n  # although its changes will not affect things at the current scope.\n  pre_project_set_up_hermetic_build()\nendif()\n\n########################################################################\n#\n# Project-wide settings\n\n# Name of the project.\n#\n# CMake files in this project can refer to the root source directory\n# as ${gmock_SOURCE_DIR} and to the root binary directory as\n# ${gmock_BINARY_DIR}.\n# Language \"C\" is required for find_package(Threads).\ncmake_minimum_required(VERSION 3.13)\nproject(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)\n\nif (COMMAND set_up_hermetic_build)\n  set_up_hermetic_build()\nendif()\n\n# Instructs CMake to process Google Test's CMakeLists.txt and add its\n# targets to the current scope. We are placing Google Test's binary\n# directory in a subdirectory of our own as VC compilation may break\n# if they are the same (the default).\nadd_subdirectory(\"${gtest_dir}\" \"${gmock_BINARY_DIR}/${gtest_dir}\")\n\n\n# These commands only run if this is the main project\nif(CMAKE_PROJECT_NAME STREQUAL \"gmock\" OR CMAKE_PROJECT_NAME STREQUAL \"googletest-distribution\")\n  # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to\n  # make it prominent in the GUI.\n  option(BUILD_SHARED_LIBS \"Build shared libraries (DLLs).\" OFF)\nelse()\n  mark_as_advanced(gmock_build_tests)\nendif()\n\n# Although Google Test's CMakeLists.txt calls this function, the\n# changes there don't affect the current scope. Therefore we have to\n# call it again here.\nconfig_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake\n\n# Adds Google Mock's and Google Test's header directories to the search path.\n# Get Google Test's include dirs from the target, gtest_SOURCE_DIR is broken\n# when using fetch-content with the name \"GTest\".\nget_target_property(gtest_include_dirs gtest INCLUDE_DIRECTORIES)\nset(gmock_build_include_dirs\n  \"${gmock_SOURCE_DIR}/include\"\n  \"${gmock_SOURCE_DIR}\"\n  \"${gtest_include_dirs}\")\ninclude_directories(${gmock_build_include_dirs})\n\n########################################################################\n#\n# Defines the gmock & gmock_main libraries. User tests should link\n# with one of them.\n\n# Google Mock libraries. We build them using more strict warnings than what\n# are used for other targets, to ensure that Google Mock can be compiled by\n# a user aggressive about warnings.\nif (MSVC)\n  cxx_library(gmock\n              \"${cxx_strict}\"\n              \"${gtest_dir}/src/gtest-all.cc\"\n              src/gmock-all.cc)\n\n  cxx_library(gmock_main\n              \"${cxx_strict}\"\n              \"${gtest_dir}/src/gtest-all.cc\"\n              src/gmock-all.cc\n              src/gmock_main.cc)\nelse()\n  cxx_library(gmock \"${cxx_strict}\" src/gmock-all.cc)\n  target_link_libraries(gmock PUBLIC gtest)\n  set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION})\n  cxx_library(gmock_main \"${cxx_strict}\" src/gmock_main.cc)\n  target_link_libraries(gmock_main PUBLIC gmock)\n  set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION})\nendif()\n\nstring(REPLACE \";\" \"$<SEMICOLON>\" dirs \"${gmock_build_include_dirs}\")\ntarget_include_directories(gmock SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\ntarget_include_directories(gmock_main SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\n\n########################################################################\n#\n# Install rules.\ninstall_project(gmock gmock_main)\n\n########################################################################\n#\n# Google Mock's own tests.\n#\n# You can skip this section if you aren't interested in testing\n# Google Mock itself.\n#\n# The tests are not built by default. To build them, set the\n# gmock_build_tests option to ON. You can do it by running ccmake\n# or specifying the -Dgmock_build_tests=ON flag when running cmake.\n\nif (gmock_build_tests)\n  # This must be set in the root directory for the tests to be run by\n  # 'make test' or ctest.\n  enable_testing()\n\n  if (MINGW OR CYGWIN)\n    add_compile_options(\"-Wa,-mbig-obj\")\n  endif()\n\n  ############################################################\n  # C++ tests built with standard compiler flags.\n\n  cxx_test(gmock-actions_test gmock_main)\n  cxx_test(gmock-cardinalities_test gmock_main)\n  cxx_test(gmock_ex_test gmock_main)\n  cxx_test(gmock-function-mocker_test gmock_main)\n  cxx_test(gmock-internal-utils_test gmock_main)\n  cxx_test(gmock-matchers-arithmetic_test gmock_main)\n  cxx_test(gmock-matchers-comparisons_test gmock_main)\n  cxx_test(gmock-matchers-containers_test gmock_main)\n  cxx_test(gmock-matchers-misc_test gmock_main)\n  cxx_test(gmock-more-actions_test gmock_main)\n  cxx_test(gmock-nice-strict_test gmock_main)\n  cxx_test(gmock-port_test gmock_main)\n  cxx_test(gmock-spec-builders_test gmock_main)\n  cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc)\n  cxx_test(gmock_test gmock_main)\n\n  if (DEFINED GTEST_HAS_PTHREAD)\n    cxx_test(gmock_stress_test gmock)\n  endif()\n\n  # gmock_all_test is commented to save time building and running tests.\n  # Uncomment if necessary.\n  # cxx_test(gmock_all_test gmock_main)\n\n  ############################################################\n  # C++ tests built with non-standard compiler flags.\n\n  if (MSVC)\n    cxx_library(gmock_main_no_exception \"${cxx_no_exception}\"\n      \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n    cxx_library(gmock_main_no_rtti \"${cxx_no_rtti}\"\n      \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n  else()\n    cxx_library(gmock_main_no_exception \"${cxx_no_exception}\" src/gmock_main.cc)\n    target_link_libraries(gmock_main_no_exception PUBLIC gmock)\n\n    cxx_library(gmock_main_no_rtti \"${cxx_no_rtti}\" src/gmock_main.cc)\n    target_link_libraries(gmock_main_no_rtti PUBLIC gmock)\n  endif()\n  cxx_test_with_flags(gmock-more-actions_no_exception_test \"${cxx_no_exception}\"\n    gmock_main_no_exception test/gmock-more-actions_test.cc)\n\n  cxx_test_with_flags(gmock_no_rtti_test \"${cxx_no_rtti}\"\n    gmock_main_no_rtti test/gmock-spec-builders_test.cc)\n\n  cxx_shared_library(shared_gmock_main \"${cxx_default}\"\n    \"${gtest_dir}/src/gtest-all.cc\" src/gmock-all.cc src/gmock_main.cc)\n\n  # Tests that a binary can be built with Google Mock as a shared library. On\n  # some system configurations, it may not possible to run the binary without\n  # knowing more details about the system configurations. We do not try to run\n  # this binary. To get a more robust shared library coverage, configure with\n  # -DBUILD_SHARED_LIBS=ON.\n  cxx_executable_with_flags(shared_gmock_test_ \"${cxx_default}\"\n    shared_gmock_main test/gmock-spec-builders_test.cc)\n  set_target_properties(shared_gmock_test_\n    PROPERTIES\n    COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n\n  ############################################################\n  # Python tests.\n\n  cxx_executable(gmock_leak_test_ test gmock_main)\n  py_test(gmock_leak_test)\n\n  cxx_executable(gmock_output_test_ test gmock)\n  py_test(gmock_output_test)\nendif()\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/cmake/gmock.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gmock\nDescription: GoogleMock (without main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gtest = @PROJECT_VERSION@\nLibs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/cmake/gmock_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gmock_main\nDescription: GoogleMock (with main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gmock = @PROJECT_VERSION@\nLibs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-actions.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// The ACTION* family of macros can be used in a namespace scope to\n// define custom actions easily.  The syntax:\n//\n//   ACTION(name) { statements; }\n//\n// will define an action with the given name that executes the\n// statements.  The value returned by the statements will be used as\n// the return value of the action.  Inside the statements, you can\n// refer to the K-th (0-based) argument of the mock function by\n// 'argK', and refer to its type by 'argK_type'.  For example:\n//\n//   ACTION(IncrementArg1) {\n//     arg1_type temp = arg1;\n//     return ++(*temp);\n//   }\n//\n// allows you to write\n//\n//   ...WillOnce(IncrementArg1());\n//\n// You can also refer to the entire argument tuple and its type by\n// 'args' and 'args_type', and refer to the mock function type and its\n// return type by 'function_type' and 'return_type'.\n//\n// Note that you don't need to specify the types of the mock function\n// arguments.  However rest assured that your code is still type-safe:\n// you'll get a compiler error if *arg1 doesn't support the ++\n// operator, or if the type of ++(*arg1) isn't compatible with the\n// mock function's return type, for example.\n//\n// Sometimes you'll want to parameterize the action.   For that you can use\n// another macro:\n//\n//   ACTION_P(name, param_name) { statements; }\n//\n// For example:\n//\n//   ACTION_P(Add, n) { return arg0 + n; }\n//\n// will allow you to write:\n//\n//   ...WillOnce(Add(5));\n//\n// Note that you don't need to provide the type of the parameter\n// either.  If you need to reference the type of a parameter named\n// 'foo', you can write 'foo_type'.  For example, in the body of\n// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type\n// of 'n'.\n//\n// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support\n// multi-parameter actions.\n//\n// For the purpose of typing, you can view\n//\n//   ACTION_Pk(Foo, p1, ..., pk) { ... }\n//\n// as shorthand for\n//\n//   template <typename p1_type, ..., typename pk_type>\n//   FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }\n//\n// In particular, you can provide the template type arguments\n// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);\n// although usually you can rely on the compiler to infer the types\n// for you automatically.  You can assign the result of expression\n// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,\n// pk_type>.  This can be useful when composing actions.\n//\n// You can also overload actions with different numbers of parameters:\n//\n//   ACTION_P(Plus, a) { ... }\n//   ACTION_P2(Plus, a, b) { ... }\n//\n// While it's tempting to always use the ACTION* macros when defining\n// a new action, you should also consider implementing ActionInterface\n// or using MakePolymorphicAction() instead, especially if you need to\n// use the action a lot.  While these approaches require more work,\n// they give you more control on the types of the mock function\n// arguments and the action parameters, which in general leads to\n// better compiler error messages that pay off in the long run.  They\n// also allow overloading actions based on parameter types (as opposed\n// to just based on the number of parameters).\n//\n// CAVEAT:\n//\n// ACTION*() can only be used in a namespace scope as templates cannot be\n// declared inside of a local class.\n// Users can, however, define any local functors (e.g. a lambda) that\n// can be used as actions.\n//\n// MORE INFORMATION:\n//\n// To learn more about using these macros, please search for 'ACTION' on\n// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n\n#ifndef _WIN32_WCE\n#include <errno.h>\n#endif\n\n#include <algorithm>\n#include <exception>\n#include <functional>\n#include <memory>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <utility>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gmock/internal/gmock-pp.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\nnamespace testing {\n\n// To implement an action Foo, define:\n//   1. a class FooAction that implements the ActionInterface interface, and\n//   2. a factory function that creates an Action object from a\n//      const FooAction*.\n//\n// The two-level delegation design follows that of Matcher, providing\n// consistency for extension developers.  It also eases ownership\n// management as Action objects can now be copied like plain values.\n\nnamespace internal {\n\n// BuiltInDefaultValueGetter<T, true>::Get() returns a\n// default-constructed T value.  BuiltInDefaultValueGetter<T,\n// false>::Get() crashes with an error.\n//\n// This primary template is used when kDefaultConstructible is true.\ntemplate <typename T, bool kDefaultConstructible>\nstruct BuiltInDefaultValueGetter {\n  static T Get() { return T(); }\n};\ntemplate <typename T>\nstruct BuiltInDefaultValueGetter<T, false> {\n  static T Get() {\n    Assert(false, __FILE__, __LINE__,\n           \"Default action undefined for the function return type.\");\n#if defined(__GNUC__) || defined(__clang__)\n    __builtin_unreachable();\n#elif defined(_MSC_VER)\n    __assume(0);\n#else\n    return Invalid<T>();\n    // The above statement will never be reached, but is required in\n    // order for this function to compile.\n#endif\n  }\n};\n\n// BuiltInDefaultValue<T>::Get() returns the \"built-in\" default value\n// for type T, which is NULL when T is a raw pointer type, 0 when T is\n// a numeric type, false when T is bool, or \"\" when T is string or\n// std::string.  In addition, in C++11 and above, it turns a\n// default-constructed T value if T is default constructible.  For any\n// other type T, the built-in default T value is undefined, and the\n// function will abort the process.\ntemplate <typename T>\nclass BuiltInDefaultValue {\n public:\n  // This function returns true if and only if type T has a built-in default\n  // value.\n  static bool Exists() { return ::std::is_default_constructible<T>::value; }\n\n  static T Get() {\n    return BuiltInDefaultValueGetter<\n        T, ::std::is_default_constructible<T>::value>::Get();\n  }\n};\n\n// This partial specialization says that we use the same built-in\n// default value for T and const T.\ntemplate <typename T>\nclass BuiltInDefaultValue<const T> {\n public:\n  static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }\n  static T Get() { return BuiltInDefaultValue<T>::Get(); }\n};\n\n// This partial specialization defines the default values for pointer\n// types.\ntemplate <typename T>\nclass BuiltInDefaultValue<T*> {\n public:\n  static bool Exists() { return true; }\n  static T* Get() { return nullptr; }\n};\n\n// The following specializations define the default values for\n// specific types we care about.\n#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \\\n  template <>                                                     \\\n  class BuiltInDefaultValue<type> {                               \\\n   public:                                                        \\\n    static bool Exists() { return true; }                         \\\n    static type Get() { return value; }                           \\\n  }\n\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, );  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, \"\");\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\\0');\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\\0');\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\\0');\n\n// There's no need for a default action for signed wchar_t, as that\n// type is the same as wchar_t for gcc, and invalid for MSVC.\n//\n// There's also no need for a default action for unsigned wchar_t, as\n// that type is the same as unsigned int for gcc, and invalid for\n// MSVC.\n#if GMOCK_WCHAR_T_IS_NATIVE_\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U);  // NOLINT\n#endif\n\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U);  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0);     // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL);     // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L);        // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0);  // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0);    // NOLINT\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);\nGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);\n\n#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_\n\n// Partial implementations of metaprogramming types from the standard library\n// not available in C++11.\n\ntemplate <typename P>\nstruct negation\n    // NOLINTNEXTLINE\n    : std::integral_constant<bool, bool(!P::value)> {};\n\n// Base case: with zero predicates the answer is always true.\ntemplate <typename...>\nstruct conjunction : std::true_type {};\n\n// With a single predicate, the answer is that predicate.\ntemplate <typename P1>\nstruct conjunction<P1> : P1 {};\n\n// With multiple predicates the answer is the first predicate if that is false,\n// and we recurse otherwise.\ntemplate <typename P1, typename... Ps>\nstruct conjunction<P1, Ps...>\n    : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {};\n\ntemplate <typename...>\nstruct disjunction : std::false_type {};\n\ntemplate <typename P1>\nstruct disjunction<P1> : P1 {};\n\ntemplate <typename P1, typename... Ps>\nstruct disjunction<P1, Ps...>\n    // NOLINTNEXTLINE\n    : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {};\n\ntemplate <typename...>\nusing void_t = void;\n\n// Detects whether an expression of type `From` can be implicitly converted to\n// `To` according to [conv]. In C++17, [conv]/3 defines this as follows:\n//\n//     An expression e can be implicitly converted to a type T if and only if\n//     the declaration T t=e; is well-formed, for some invented temporary\n//     variable t ([dcl.init]).\n//\n// [conv]/2 implies we can use function argument passing to detect whether this\n// initialization is valid.\n//\n// Note that this is distinct from is_convertible, which requires this be valid:\n//\n//     To test() {\n//       return declval<From>();\n//     }\n//\n// In particular, is_convertible doesn't give the correct answer when `To` and\n// `From` are the same non-moveable type since `declval<From>` will be an rvalue\n// reference, defeating the guaranteed copy elision that would otherwise make\n// this function work.\n//\n// REQUIRES: `From` is not cv void.\ntemplate <typename From, typename To>\nstruct is_implicitly_convertible {\n private:\n  // A function that accepts a parameter of type T. This can be called with type\n  // U successfully only if U is implicitly convertible to T.\n  template <typename T>\n  static void Accept(T);\n\n  // A function that creates a value of type T.\n  template <typename T>\n  static T Make();\n\n  // An overload be selected when implicit conversion from T to To is possible.\n  template <typename T, typename = decltype(Accept<To>(Make<T>()))>\n  static std::true_type TestImplicitConversion(int);\n\n  // A fallback overload selected in all other cases.\n  template <typename T>\n  static std::false_type TestImplicitConversion(...);\n\n public:\n  using type = decltype(TestImplicitConversion<From>(0));\n  static constexpr bool value = type::value;\n};\n\n// Like std::invoke_result_t from C++17, but works only for objects with call\n// operators (not e.g. member function pointers, which we don't need specific\n// support for in OnceAction because std::function deals with them).\ntemplate <typename F, typename... Args>\nusing call_result_t = decltype(std::declval<F>()(std::declval<Args>()...));\n\ntemplate <typename Void, typename R, typename F, typename... Args>\nstruct is_callable_r_impl : std::false_type {};\n\n// Specialize the struct for those template arguments where call_result_t is\n// well-formed. When it's not, the generic template above is chosen, resulting\n// in std::false_type.\ntemplate <typename R, typename F, typename... Args>\nstruct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>\n    : std::conditional<\n          std::is_void<R>::value,  //\n          std::true_type,          //\n          is_implicitly_convertible<call_result_t<F, Args...>, R>>::type {};\n\n// Like std::is_invocable_r from C++17, but works only for objects with call\n// operators. See the note on call_result_t.\ntemplate <typename R, typename F, typename... Args>\nusing is_callable_r = is_callable_r_impl<void, R, F, Args...>;\n\n// Like std::as_const from C++17.\ntemplate <typename T>\ntypename std::add_const<T>::type& as_const(T& t) {\n  return t;\n}\n\n}  // namespace internal\n\n// Specialized for function types below.\ntemplate <typename F>\nclass OnceAction;\n\n// An action that can only be used once.\n//\n// This is accepted by WillOnce, which doesn't require the underlying action to\n// be copy-constructible (only move-constructible), and promises to invoke it as\n// an rvalue reference. This allows the action to work with move-only types like\n// std::move_only_function in a type-safe manner.\n//\n// For example:\n//\n//     // Assume we have some API that needs to accept a unique pointer to some\n//     // non-copyable object Foo.\n//     void AcceptUniquePointer(std::unique_ptr<Foo> foo);\n//\n//     // We can define an action that provides a Foo to that API. Because It\n//     // has to give away its unique pointer, it must not be called more than\n//     // once, so its call operator is &&-qualified.\n//     struct ProvideFoo {\n//       std::unique_ptr<Foo> foo;\n//\n//       void operator()() && {\n//         AcceptUniquePointer(std::move(Foo));\n//       }\n//     };\n//\n//     // This action can be used with WillOnce.\n//     EXPECT_CALL(mock, Call)\n//         .WillOnce(ProvideFoo{std::make_unique<Foo>(...)});\n//\n//     // But a call to WillRepeatedly will fail to compile. This is correct,\n//     // since the action cannot correctly be used repeatedly.\n//     EXPECT_CALL(mock, Call)\n//         .WillRepeatedly(ProvideFoo{std::make_unique<Foo>(...)});\n//\n// A less-contrived example would be an action that returns an arbitrary type,\n// whose &&-qualified call operator is capable of dealing with move-only types.\ntemplate <typename Result, typename... Args>\nclass OnceAction<Result(Args...)> final {\n private:\n  // True iff we can use the given callable type (or lvalue reference) directly\n  // via StdFunctionAdaptor.\n  template <typename Callable>\n  using IsDirectlyCompatible = internal::conjunction<\n      // It must be possible to capture the callable in StdFunctionAdaptor.\n      std::is_constructible<typename std::decay<Callable>::type, Callable>,\n      // The callable must be compatible with our signature.\n      internal::is_callable_r<Result, typename std::decay<Callable>::type,\n                              Args...>>;\n\n  // True iff we can use the given callable type via StdFunctionAdaptor once we\n  // ignore incoming arguments.\n  template <typename Callable>\n  using IsCompatibleAfterIgnoringArguments = internal::conjunction<\n      // It must be possible to capture the callable in a lambda.\n      std::is_constructible<typename std::decay<Callable>::type, Callable>,\n      // The callable must be invocable with zero arguments, returning something\n      // convertible to Result.\n      internal::is_callable_r<Result, typename std::decay<Callable>::type>>;\n\n public:\n  // Construct from a callable that is directly compatible with our mocked\n  // signature: it accepts our function type's arguments and returns something\n  // convertible to our result type.\n  template <typename Callable,\n            typename std::enable_if<\n                internal::conjunction<\n                    // Teach clang on macOS that we're not talking about a\n                    // copy/move constructor here. Otherwise it gets confused\n                    // when checking the is_constructible requirement of our\n                    // traits above.\n                    internal::negation<std::is_same<\n                        OnceAction, typename std::decay<Callable>::type>>,\n                    IsDirectlyCompatible<Callable>>  //\n                ::value,\n                int>::type = 0>\n  OnceAction(Callable&& callable)  // NOLINT\n      : function_(StdFunctionAdaptor<typename std::decay<Callable>::type>(\n            {}, std::forward<Callable>(callable))) {}\n\n  // As above, but for a callable that ignores the mocked function's arguments.\n  template <typename Callable,\n            typename std::enable_if<\n                internal::conjunction<\n                    // Teach clang on macOS that we're not talking about a\n                    // copy/move constructor here. Otherwise it gets confused\n                    // when checking the is_constructible requirement of our\n                    // traits above.\n                    internal::negation<std::is_same<\n                        OnceAction, typename std::decay<Callable>::type>>,\n                    // Exclude callables for which the overload above works.\n                    // We'd rather provide the arguments if possible.\n                    internal::negation<IsDirectlyCompatible<Callable>>,\n                    IsCompatibleAfterIgnoringArguments<Callable>>::value,\n                int>::type = 0>\n  OnceAction(Callable&& callable)  // NOLINT\n                                   // Call the constructor above with a callable\n                                   // that ignores the input arguments.\n      : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{\n            std::forward<Callable>(callable)}) {}\n\n  // We are naturally copyable because we store only an std::function, but\n  // semantically we should not be copyable.\n  OnceAction(const OnceAction&) = delete;\n  OnceAction& operator=(const OnceAction&) = delete;\n  OnceAction(OnceAction&&) = default;\n\n  // Invoke the underlying action callable with which we were constructed,\n  // handing it the supplied arguments.\n  Result Call(Args... args) && {\n    return function_(std::forward<Args>(args)...);\n  }\n\n private:\n  // An adaptor that wraps a callable that is compatible with our signature and\n  // being invoked as an rvalue reference so that it can be used as an\n  // StdFunctionAdaptor. This throws away type safety, but that's fine because\n  // this is only used by WillOnce, which we know calls at most once.\n  //\n  // Once we have something like std::move_only_function from C++23, we can do\n  // away with this.\n  template <typename Callable>\n  class StdFunctionAdaptor final {\n   public:\n    // A tag indicating that the (otherwise universal) constructor is accepting\n    // the callable itself, instead of e.g. stealing calls for the move\n    // constructor.\n    struct CallableTag final {};\n\n    template <typename F>\n    explicit StdFunctionAdaptor(CallableTag, F&& callable)\n        : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {}\n\n    // Rather than explicitly returning Result, we return whatever the wrapped\n    // callable returns. This allows for compatibility with existing uses like\n    // the following, when the mocked function returns void:\n    //\n    //     EXPECT_CALL(mock_fn_, Call)\n    //         .WillOnce([&] {\n    //            [...]\n    //            return 0;\n    //         });\n    //\n    // Such a callable can be turned into std::function<void()>. If we use an\n    // explicit return type of Result here then it *doesn't* work with\n    // std::function, because we'll get a \"void function should not return a\n    // value\" error.\n    //\n    // We need not worry about incompatible result types because the SFINAE on\n    // OnceAction already checks this for us. std::is_invocable_r_v itself makes\n    // the same allowance for void result types.\n    template <typename... ArgRefs>\n    internal::call_result_t<Callable, ArgRefs...> operator()(\n        ArgRefs&&... args) const {\n      return std::move(*callable_)(std::forward<ArgRefs>(args)...);\n    }\n\n   private:\n    // We must put the callable on the heap so that we are copyable, which\n    // std::function needs.\n    std::shared_ptr<Callable> callable_;\n  };\n\n  // An adaptor that makes a callable that accepts zero arguments callable with\n  // our mocked arguments.\n  template <typename Callable>\n  struct IgnoreIncomingArguments {\n    internal::call_result_t<Callable> operator()(Args&&...) {\n      return std::move(callable)();\n    }\n\n    Callable callable;\n  };\n\n  std::function<Result(Args...)> function_;\n};\n\n// When an unexpected function call is encountered, Google Mock will\n// let it return a default value if the user has specified one for its\n// return type, or if the return type has a built-in default value;\n// otherwise Google Mock won't know what value to return and will have\n// to abort the process.\n//\n// The DefaultValue<T> class allows a user to specify the\n// default value for a type T that is both copyable and publicly\n// destructible (i.e. anything that can be used as a function return\n// type).  The usage is:\n//\n//   // Sets the default value for type T to be foo.\n//   DefaultValue<T>::Set(foo);\ntemplate <typename T>\nclass DefaultValue {\n public:\n  // Sets the default value for type T; requires T to be\n  // copy-constructable and have a public destructor.\n  static void Set(T x) {\n    delete producer_;\n    producer_ = new FixedValueProducer(x);\n  }\n\n  // Provides a factory function to be called to generate the default value.\n  // This method can be used even if T is only move-constructible, but it is not\n  // limited to that case.\n  typedef T (*FactoryFunction)();\n  static void SetFactory(FactoryFunction factory) {\n    delete producer_;\n    producer_ = new FactoryValueProducer(factory);\n  }\n\n  // Unsets the default value for type T.\n  static void Clear() {\n    delete producer_;\n    producer_ = nullptr;\n  }\n\n  // Returns true if and only if the user has set the default value for type T.\n  static bool IsSet() { return producer_ != nullptr; }\n\n  // Returns true if T has a default return value set by the user or there\n  // exists a built-in default value.\n  static bool Exists() {\n    return IsSet() || internal::BuiltInDefaultValue<T>::Exists();\n  }\n\n  // Returns the default value for type T if the user has set one;\n  // otherwise returns the built-in default value. Requires that Exists()\n  // is true, which ensures that the return value is well-defined.\n  static T Get() {\n    return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()\n                                : producer_->Produce();\n  }\n\n private:\n  class ValueProducer {\n   public:\n    virtual ~ValueProducer() = default;\n    virtual T Produce() = 0;\n  };\n\n  class FixedValueProducer : public ValueProducer {\n   public:\n    explicit FixedValueProducer(T value) : value_(value) {}\n    T Produce() override { return value_; }\n\n   private:\n    const T value_;\n    FixedValueProducer(const FixedValueProducer&) = delete;\n    FixedValueProducer& operator=(const FixedValueProducer&) = delete;\n  };\n\n  class FactoryValueProducer : public ValueProducer {\n   public:\n    explicit FactoryValueProducer(FactoryFunction factory)\n        : factory_(factory) {}\n    T Produce() override { return factory_(); }\n\n   private:\n    const FactoryFunction factory_;\n    FactoryValueProducer(const FactoryValueProducer&) = delete;\n    FactoryValueProducer& operator=(const FactoryValueProducer&) = delete;\n  };\n\n  static ValueProducer* producer_;\n};\n\n// This partial specialization allows a user to set default values for\n// reference types.\ntemplate <typename T>\nclass DefaultValue<T&> {\n public:\n  // Sets the default value for type T&.\n  static void Set(T& x) {  // NOLINT\n    address_ = &x;\n  }\n\n  // Unsets the default value for type T&.\n  static void Clear() { address_ = nullptr; }\n\n  // Returns true if and only if the user has set the default value for type T&.\n  static bool IsSet() { return address_ != nullptr; }\n\n  // Returns true if T has a default return value set by the user or there\n  // exists a built-in default value.\n  static bool Exists() {\n    return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();\n  }\n\n  // Returns the default value for type T& if the user has set one;\n  // otherwise returns the built-in default value if there is one;\n  // otherwise aborts the process.\n  static T& Get() {\n    return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()\n                               : *address_;\n  }\n\n private:\n  static T* address_;\n};\n\n// This specialization allows DefaultValue<void>::Get() to\n// compile.\ntemplate <>\nclass DefaultValue<void> {\n public:\n  static bool Exists() { return true; }\n  static void Get() {}\n};\n\n// Points to the user-set default value for type T.\ntemplate <typename T>\ntypename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;\n\n// Points to the user-set default value for type T&.\ntemplate <typename T>\nT* DefaultValue<T&>::address_ = nullptr;\n\n// Implement this interface to define an action for function type F.\ntemplate <typename F>\nclass ActionInterface {\n public:\n  typedef typename internal::Function<F>::Result Result;\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n  ActionInterface() = default;\n  virtual ~ActionInterface() = default;\n\n  // Performs the action.  This method is not const, as in general an\n  // action can have side effects and be stateful.  For example, a\n  // get-the-next-element-from-the-collection action will need to\n  // remember the current element.\n  virtual Result Perform(const ArgumentTuple& args) = 0;\n\n private:\n  ActionInterface(const ActionInterface&) = delete;\n  ActionInterface& operator=(const ActionInterface&) = delete;\n};\n\ntemplate <typename F>\nclass Action;\n\n// An Action<R(Args...)> is a copyable and IMMUTABLE (except by assignment)\n// object that represents an action to be taken when a mock function of type\n// R(Args...) is called. The implementation of Action<T> is just a\n// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! You\n// can view an object implementing ActionInterface<F> as a concrete action\n// (including its current state), and an Action<F> object as a handle to it.\ntemplate <typename R, typename... Args>\nclass Action<R(Args...)> {\n private:\n  using F = R(Args...);\n\n  // Adapter class to allow constructing Action from a legacy ActionInterface.\n  // New code should create Actions from functors instead.\n  struct ActionAdapter {\n    // Adapter must be copyable to satisfy std::function requirements.\n    ::std::shared_ptr<ActionInterface<F>> impl_;\n\n    template <typename... InArgs>\n    typename internal::Function<F>::Result operator()(InArgs&&... args) {\n      return impl_->Perform(\n          ::std::forward_as_tuple(::std::forward<InArgs>(args)...));\n    }\n  };\n\n  template <typename G>\n  using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;\n\n public:\n  typedef typename internal::Function<F>::Result Result;\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n  // Constructs a null Action.  Needed for storing Action objects in\n  // STL containers.\n  Action() = default;\n\n  // Construct an Action from a specified callable.\n  // This cannot take std::function directly, because then Action would not be\n  // directly constructible from lambda (it would require two conversions).\n  template <\n      typename G,\n      typename = typename std::enable_if<internal::disjunction<\n          IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>,\n                                                        G>>::value>::type>\n  Action(G&& fun) {  // NOLINT\n    Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());\n  }\n\n  // Constructs an Action from its implementation.\n  explicit Action(ActionInterface<F>* impl)\n      : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}\n\n  // This constructor allows us to turn an Action<Func> object into an\n  // Action<F>, as long as F's arguments can be implicitly converted\n  // to Func's and Func's return type can be implicitly converted to F's.\n  template <typename Func>\n  Action(const Action<Func>& action)  // NOLINT\n      : fun_(action.fun_) {}\n\n  // Returns true if and only if this is the DoDefault() action.\n  bool IsDoDefault() const { return fun_ == nullptr; }\n\n  // Performs the action.  Note that this method is const even though\n  // the corresponding method in ActionInterface is not.  The reason\n  // is that a const Action<F> means that it cannot be re-bound to\n  // another concrete action, not that the concrete action it binds to\n  // cannot change state.  (Think of the difference between a const\n  // pointer and a pointer to const.)\n  Result Perform(ArgumentTuple args) const {\n    if (IsDoDefault()) {\n      internal::IllegalDoDefault(__FILE__, __LINE__);\n    }\n    return internal::Apply(fun_, ::std::move(args));\n  }\n\n  // An action can be used as a OnceAction, since it's obviously safe to call it\n  // once.\n  operator OnceAction<F>() const {  // NOLINT\n    // Return a OnceAction-compatible callable that calls Perform with the\n    // arguments it is provided. We could instead just return fun_, but then\n    // we'd need to handle the IsDoDefault() case separately.\n    struct OA {\n      Action<F> action;\n\n      R operator()(Args... args) && {\n        return action.Perform(\n            std::forward_as_tuple(std::forward<Args>(args)...));\n      }\n    };\n\n    return OA{*this};\n  }\n\n private:\n  template <typename G>\n  friend class Action;\n\n  template <typename G>\n  void Init(G&& g, ::std::true_type) {\n    fun_ = ::std::forward<G>(g);\n  }\n\n  template <typename G>\n  void Init(G&& g, ::std::false_type) {\n    fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};\n  }\n\n  template <typename FunctionImpl>\n  struct IgnoreArgs {\n    template <typename... InArgs>\n    Result operator()(const InArgs&...) const {\n      return function_impl();\n    }\n\n    FunctionImpl function_impl;\n  };\n\n  // fun_ is an empty function if and only if this is the DoDefault() action.\n  ::std::function<F> fun_;\n};\n\n// The PolymorphicAction class template makes it easy to implement a\n// polymorphic action (i.e. an action that can be used in mock\n// functions of than one type, e.g. Return()).\n//\n// To define a polymorphic action, a user first provides a COPYABLE\n// implementation class that has a Perform() method template:\n//\n//   class FooAction {\n//    public:\n//     template <typename Result, typename ArgumentTuple>\n//     Result Perform(const ArgumentTuple& args) const {\n//       // Processes the arguments and returns a result, using\n//       // std::get<N>(args) to get the N-th (0-based) argument in the tuple.\n//     }\n//     ...\n//   };\n//\n// Then the user creates the polymorphic action using\n// MakePolymorphicAction(object) where object has type FooAction.  See\n// the definition of Return(void) and SetArgumentPointee<N>(value) for\n// complete examples.\ntemplate <typename Impl>\nclass PolymorphicAction {\n public:\n  explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}\n\n  template <typename F>\n  operator Action<F>() const {\n    return Action<F>(new MonomorphicImpl<F>(impl_));\n  }\n\n private:\n  template <typename F>\n  class MonomorphicImpl : public ActionInterface<F> {\n   public:\n    typedef typename internal::Function<F>::Result Result;\n    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}\n\n    Result Perform(const ArgumentTuple& args) override {\n      return impl_.template Perform<Result>(args);\n    }\n\n   private:\n    Impl impl_;\n  };\n\n  Impl impl_;\n};\n\n// Creates an Action from its implementation and returns it.  The\n// created Action object owns the implementation.\ntemplate <typename F>\nAction<F> MakeAction(ActionInterface<F>* impl) {\n  return Action<F>(impl);\n}\n\n// Creates a polymorphic action from its implementation.  This is\n// easier to use than the PolymorphicAction<Impl> constructor as it\n// doesn't require you to explicitly write the template argument, e.g.\n//\n//   MakePolymorphicAction(foo);\n// vs\n//   PolymorphicAction<TypeOfFoo>(foo);\ntemplate <typename Impl>\ninline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {\n  return PolymorphicAction<Impl>(impl);\n}\n\nnamespace internal {\n\n// Helper struct to specialize ReturnAction to execute a move instead of a copy\n// on return. Useful for move-only types, but could be used on any type.\ntemplate <typename T>\nstruct ByMoveWrapper {\n  explicit ByMoveWrapper(T value) : payload(std::move(value)) {}\n  T payload;\n};\n\n// The general implementation of Return(R). Specializations follow below.\ntemplate <typename R>\nclass ReturnAction final {\n public:\n  explicit ReturnAction(R value) : value_(std::move(value)) {}\n\n  template <typename U, typename... Args,\n            typename = typename std::enable_if<conjunction<\n                // See the requirements documented on Return.\n                negation<std::is_same<void, U>>,  //\n                negation<std::is_reference<U>>,   //\n                std::is_convertible<R, U>,        //\n                std::is_move_constructible<U>>::value>::type>\n  operator OnceAction<U(Args...)>() && {  // NOLINT\n    return Impl<U>(std::move(value_));\n  }\n\n  template <typename U, typename... Args,\n            typename = typename std::enable_if<conjunction<\n                // See the requirements documented on Return.\n                negation<std::is_same<void, U>>,   //\n                negation<std::is_reference<U>>,    //\n                std::is_convertible<const R&, U>,  //\n                std::is_copy_constructible<U>>::value>::type>\n  operator Action<U(Args...)>() const {  // NOLINT\n    return Impl<U>(value_);\n  }\n\n private:\n  // Implements the Return(x) action for a mock function that returns type U.\n  template <typename U>\n  class Impl final {\n   public:\n    // The constructor used when the return value is allowed to move from the\n    // input value (i.e. we are converting to OnceAction).\n    explicit Impl(R&& input_value)\n        : state_(new State(std::move(input_value))) {}\n\n    // The constructor used when the return value is not allowed to move from\n    // the input value (i.e. we are converting to Action).\n    explicit Impl(const R& input_value) : state_(new State(input_value)) {}\n\n    U operator()() && { return std::move(state_->value); }\n    U operator()() const& { return state_->value; }\n\n   private:\n    // We put our state on the heap so that the compiler-generated copy/move\n    // constructors work correctly even when U is a reference-like type. This is\n    // necessary only because we eagerly create State::value (see the note on\n    // that symbol for details). If we instead had only the input value as a\n    // member then the default constructors would work fine.\n    //\n    // For example, when R is std::string and U is std::string_view, value is a\n    // reference to the string backed by input_value. The copy constructor would\n    // copy both, so that we wind up with a new input_value object (with the\n    // same contents) and a reference to the *old* input_value object rather\n    // than the new one.\n    struct State {\n      explicit State(const R& input_value_in)\n          : input_value(input_value_in),\n            // Make an implicit conversion to Result before initializing the U\n            // object we store, avoiding calling any explicit constructor of U\n            // from R.\n            //\n            // This simulates the language rules: a function with return type U\n            // that does `return R()` requires R to be implicitly convertible to\n            // U, and uses that path for the conversion, even U Result has an\n            // explicit constructor from R.\n            value(ImplicitCast_<U>(internal::as_const(input_value))) {}\n\n      // As above, but for the case where we're moving from the ReturnAction\n      // object because it's being used as a OnceAction.\n      explicit State(R&& input_value_in)\n          : input_value(std::move(input_value_in)),\n            // For the same reason as above we make an implicit conversion to U\n            // before initializing the value.\n            //\n            // Unlike above we provide the input value as an rvalue to the\n            // implicit conversion because this is a OnceAction: it's fine if it\n            // wants to consume the input value.\n            value(ImplicitCast_<U>(std::move(input_value))) {}\n\n      // A copy of the value originally provided by the user. We retain this in\n      // addition to the value of the mock function's result type below in case\n      // the latter is a reference-like type. See the std::string_view example\n      // in the documentation on Return.\n      R input_value;\n\n      // The value we actually return, as the type returned by the mock function\n      // itself.\n      //\n      // We eagerly initialize this here, rather than lazily doing the implicit\n      // conversion automatically each time Perform is called, for historical\n      // reasons: in 2009-11, commit a070cbd91c (Google changelist 13540126)\n      // made the Action<U()> conversion operator eagerly convert the R value to\n      // U, but without keeping the R alive. This broke the use case discussed\n      // in the documentation for Return, making reference-like types such as\n      // std::string_view not safe to use as U where the input type R is a\n      // value-like type such as std::string.\n      //\n      // The example the commit gave was not very clear, nor was the issue\n      // thread (https://github.com/google/googlemock/issues/86), but it seems\n      // the worry was about reference-like input types R that flatten to a\n      // value-like type U when being implicitly converted. An example of this\n      // is std::vector<bool>::reference, which is often a proxy type with an\n      // reference to the underlying vector:\n      //\n      //     // Helper method: have the mock function return bools according\n      //     // to the supplied script.\n      //     void SetActions(MockFunction<bool(size_t)>& mock,\n      //                     const std::vector<bool>& script) {\n      //       for (size_t i = 0; i < script.size(); ++i) {\n      //         EXPECT_CALL(mock, Call(i)).WillOnce(Return(script[i]));\n      //       }\n      //     }\n      //\n      //     TEST(Foo, Bar) {\n      //       // Set actions using a temporary vector, whose operator[]\n      //       // returns proxy objects that references that will be\n      //       // dangling once the call to SetActions finishes and the\n      //       // vector is destroyed.\n      //       MockFunction<bool(size_t)> mock;\n      //       SetActions(mock, {false, true});\n      //\n      //       EXPECT_FALSE(mock.AsStdFunction()(0));\n      //       EXPECT_TRUE(mock.AsStdFunction()(1));\n      //     }\n      //\n      // This eager conversion helps with a simple case like this, but doesn't\n      // fully make these types work in general. For example the following still\n      // uses a dangling reference:\n      //\n      //     TEST(Foo, Baz) {\n      //       MockFunction<std::vector<std::string>()> mock;\n      //\n      //       // Return the same vector twice, and then the empty vector\n      //       // thereafter.\n      //       auto action = Return(std::initializer_list<std::string>{\n      //           \"taco\", \"burrito\",\n      //       });\n      //\n      //       EXPECT_CALL(mock, Call)\n      //           .WillOnce(action)\n      //           .WillOnce(action)\n      //           .WillRepeatedly(Return(std::vector<std::string>{}));\n      //\n      //       EXPECT_THAT(mock.AsStdFunction()(),\n      //                   ElementsAre(\"taco\", \"burrito\"));\n      //       EXPECT_THAT(mock.AsStdFunction()(),\n      //                   ElementsAre(\"taco\", \"burrito\"));\n      //       EXPECT_THAT(mock.AsStdFunction()(), IsEmpty());\n      //     }\n      //\n      U value;\n    };\n\n    const std::shared_ptr<State> state_;\n  };\n\n  R value_;\n};\n\n// A specialization of ReturnAction<R> when R is ByMoveWrapper<T> for some T.\n//\n// This version applies the type system-defeating hack of moving from T even in\n// the const call operator, checking at runtime that it isn't called more than\n// once, since the user has declared their intent to do so by using ByMove.\ntemplate <typename T>\nclass ReturnAction<ByMoveWrapper<T>> final {\n public:\n  explicit ReturnAction(ByMoveWrapper<T> wrapper)\n      : state_(new State(std::move(wrapper.payload))) {}\n\n  T operator()() const {\n    GTEST_CHECK_(!state_->called)\n        << \"A ByMove() action must be performed at most once.\";\n\n    state_->called = true;\n    return std::move(state_->value);\n  }\n\n private:\n  // We store our state on the heap so that we are copyable as required by\n  // Action, despite the fact that we are stateful and T may not be copyable.\n  struct State {\n    explicit State(T&& value_in) : value(std::move(value_in)) {}\n\n    T value;\n    bool called = false;\n  };\n\n  const std::shared_ptr<State> state_;\n};\n\n// Implements the ReturnNull() action.\nclass ReturnNullAction {\n public:\n  // Allows ReturnNull() to be used in any pointer-returning function. In C++11\n  // this is enforced by returning nullptr, and in non-C++11 by asserting a\n  // pointer type on compile time.\n  template <typename Result, typename ArgumentTuple>\n  static Result Perform(const ArgumentTuple&) {\n    return nullptr;\n  }\n};\n\n// Implements the Return() action.\nclass ReturnVoidAction {\n public:\n  // Allows Return() to be used in any void-returning function.\n  template <typename Result, typename ArgumentTuple>\n  static void Perform(const ArgumentTuple&) {\n    static_assert(std::is_void<Result>::value, \"Result should be void.\");\n  }\n};\n\n// Implements the polymorphic ReturnRef(x) action, which can be used\n// in any function that returns a reference to the type of x,\n// regardless of the argument types.\ntemplate <typename T>\nclass ReturnRefAction {\n public:\n  // Constructs a ReturnRefAction object from the reference to be returned.\n  explicit ReturnRefAction(T& ref) : ref_(ref) {}  // NOLINT\n\n  // This template type conversion operator allows ReturnRef(x) to be\n  // used in ANY function that returns a reference to x's type.\n  template <typename F>\n  operator Action<F>() const {\n    typedef typename Function<F>::Result Result;\n    // Asserts that the function return type is a reference.  This\n    // catches the user error of using ReturnRef(x) when Return(x)\n    // should be used, and generates some helpful error message.\n    static_assert(std::is_reference<Result>::value,\n                  \"use Return instead of ReturnRef to return a value\");\n    return Action<F>(new Impl<F>(ref_));\n  }\n\n private:\n  // Implements the ReturnRef(x) action for a particular function type F.\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename Function<F>::Result Result;\n    typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(T& ref) : ref_(ref) {}  // NOLINT\n\n    Result Perform(const ArgumentTuple&) override { return ref_; }\n\n   private:\n    T& ref_;\n  };\n\n  T& ref_;\n};\n\n// Implements the polymorphic ReturnRefOfCopy(x) action, which can be\n// used in any function that returns a reference to the type of x,\n// regardless of the argument types.\ntemplate <typename T>\nclass ReturnRefOfCopyAction {\n public:\n  // Constructs a ReturnRefOfCopyAction object from the reference to\n  // be returned.\n  explicit ReturnRefOfCopyAction(const T& value) : value_(value) {}  // NOLINT\n\n  // This template type conversion operator allows ReturnRefOfCopy(x) to be\n  // used in ANY function that returns a reference to x's type.\n  template <typename F>\n  operator Action<F>() const {\n    typedef typename Function<F>::Result Result;\n    // Asserts that the function return type is a reference.  This\n    // catches the user error of using ReturnRefOfCopy(x) when Return(x)\n    // should be used, and generates some helpful error message.\n    static_assert(std::is_reference<Result>::value,\n                  \"use Return instead of ReturnRefOfCopy to return a value\");\n    return Action<F>(new Impl<F>(value_));\n  }\n\n private:\n  // Implements the ReturnRefOfCopy(x) action for a particular function type F.\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename Function<F>::Result Result;\n    typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(const T& value) : value_(value) {}  // NOLINT\n\n    Result Perform(const ArgumentTuple&) override { return value_; }\n\n   private:\n    T value_;\n  };\n\n  const T value_;\n};\n\n// Implements the polymorphic ReturnRoundRobin(v) action, which can be\n// used in any function that returns the element_type of v.\ntemplate <typename T>\nclass ReturnRoundRobinAction {\n public:\n  explicit ReturnRoundRobinAction(std::vector<T> values) {\n    GTEST_CHECK_(!values.empty())\n        << \"ReturnRoundRobin requires at least one element.\";\n    state_->values = std::move(values);\n  }\n\n  template <typename... Args>\n  T operator()(Args&&...) const {\n    return state_->Next();\n  }\n\n private:\n  struct State {\n    T Next() {\n      T ret_val = values[i++];\n      if (i == values.size()) i = 0;\n      return ret_val;\n    }\n\n    std::vector<T> values;\n    size_t i = 0;\n  };\n  std::shared_ptr<State> state_ = std::make_shared<State>();\n};\n\n// Implements the polymorphic DoDefault() action.\nclass DoDefaultAction {\n public:\n  // This template type conversion operator allows DoDefault() to be\n  // used in any function.\n  template <typename F>\n  operator Action<F>() const {\n    return Action<F>();\n  }  // NOLINT\n};\n\n// Implements the Assign action to set a given pointer referent to a\n// particular value.\ntemplate <typename T1, typename T2>\nclass AssignAction {\n public:\n  AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}\n\n  template <typename Result, typename ArgumentTuple>\n  void Perform(const ArgumentTuple& /* args */) const {\n    *ptr_ = value_;\n  }\n\n private:\n  T1* const ptr_;\n  const T2 value_;\n};\n\n#ifndef GTEST_OS_WINDOWS_MOBILE\n\n// Implements the SetErrnoAndReturn action to simulate return from\n// various system calls and libc functions.\ntemplate <typename T>\nclass SetErrnoAndReturnAction {\n public:\n  SetErrnoAndReturnAction(int errno_value, T result)\n      : errno_(errno_value), result_(result) {}\n  template <typename Result, typename ArgumentTuple>\n  Result Perform(const ArgumentTuple& /* args */) const {\n    errno = errno_;\n    return result_;\n  }\n\n private:\n  const int errno_;\n  const T result_;\n};\n\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n// Implements the SetArgumentPointee<N>(x) action for any function\n// whose N-th argument (0-based) is a pointer to x's type.\ntemplate <size_t N, typename A, typename = void>\nstruct SetArgumentPointeeAction {\n  A value;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *::std::get<N>(std::tie(args...)) = value;\n  }\n};\n\n// Implements the Invoke(object_ptr, &Class::Method) action.\ntemplate <class Class, typename MethodPtr>\nstruct InvokeMethodAction {\n  Class* const obj_ptr;\n  const MethodPtr method_ptr;\n\n  template <typename... Args>\n  auto operator()(Args&&... args) const\n      -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {\n    return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);\n  }\n};\n\n// Implements the InvokeWithoutArgs(f) action.  The template argument\n// FunctionImpl is the implementation type of f, which can be either a\n// function pointer or a functor.  InvokeWithoutArgs(f) can be used as an\n// Action<F> as long as f's type is compatible with F.\ntemplate <typename FunctionImpl>\nstruct InvokeWithoutArgsAction {\n  FunctionImpl function_impl;\n\n  // Allows InvokeWithoutArgs(f) to be used as any action whose type is\n  // compatible with f.\n  template <typename... Args>\n  auto operator()(const Args&...) -> decltype(function_impl()) {\n    return function_impl();\n  }\n};\n\n// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.\ntemplate <class Class, typename MethodPtr>\nstruct InvokeMethodWithoutArgsAction {\n  Class* const obj_ptr;\n  const MethodPtr method_ptr;\n\n  using ReturnType =\n      decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());\n\n  template <typename... Args>\n  ReturnType operator()(const Args&...) const {\n    return (obj_ptr->*method_ptr)();\n  }\n};\n\n// Implements the IgnoreResult(action) action.\ntemplate <typename A>\nclass IgnoreResultAction {\n public:\n  explicit IgnoreResultAction(const A& action) : action_(action) {}\n\n  template <typename F>\n  operator Action<F>() const {\n    // Assert statement belongs here because this is the best place to verify\n    // conditions on F. It produces the clearest error messages\n    // in most compilers.\n    // Impl really belongs in this scope as a local class but can't\n    // because MSVC produces duplicate symbols in different translation units\n    // in this case. Until MS fixes that bug we put Impl into the class scope\n    // and put the typedef both here (for use in assert statement) and\n    // in the Impl class. But both definitions must be the same.\n    typedef typename internal::Function<F>::Result Result;\n\n    // Asserts at compile time that F returns void.\n    static_assert(std::is_void<Result>::value, \"Result type should be void.\");\n\n    return Action<F>(new Impl<F>(action_));\n  }\n\n private:\n  template <typename F>\n  class Impl : public ActionInterface<F> {\n   public:\n    typedef typename internal::Function<F>::Result Result;\n    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n\n    explicit Impl(const A& action) : action_(action) {}\n\n    void Perform(const ArgumentTuple& args) override {\n      // Performs the action and ignores its result.\n      action_.Perform(args);\n    }\n\n   private:\n    // Type OriginalFunction is the same as F except that its return\n    // type is IgnoredValue.\n    typedef\n        typename internal::Function<F>::MakeResultIgnoredValue OriginalFunction;\n\n    const Action<OriginalFunction> action_;\n  };\n\n  const A action_;\n};\n\ntemplate <typename InnerAction, size_t... I>\nstruct WithArgsAction {\n  InnerAction inner_action;\n\n  // The signature of the function as seen by the inner action, given an out\n  // action with the given result and argument types.\n  template <typename R, typename... Args>\n  using InnerSignature =\n      R(typename std::tuple_element<I, std::tuple<Args...>>::type...);\n\n  // Rather than a call operator, we must define conversion operators to\n  // particular action types. This is necessary for embedded actions like\n  // DoDefault(), which rely on an action conversion operators rather than\n  // providing a call operator because even with a particular set of arguments\n  // they don't have a fixed return type.\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<InnerAction,\n                              // Unfortunately we can't use the InnerSignature\n                              // alias here; MSVC complains about the I\n                              // parameter pack not being expanded (error C3520)\n                              // despite it being expanded in the type alias.\n                              // TupleElement is also an MSVC workaround.\n                              // See its definition for details.\n                              OnceAction<R(internal::TupleElement<\n                                           I, std::tuple<Args...>>...)>>::value,\n          int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    struct OA {\n      OnceAction<InnerSignature<R, Args...>> inner_action;\n\n      R operator()(Args&&... args) && {\n        return std::move(inner_action)\n            .Call(std::get<I>(\n                std::forward_as_tuple(std::forward<Args>(args)...))...);\n      }\n    };\n\n    return OA{std::move(inner_action)};\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<const InnerAction&,\n                              // Unfortunately we can't use the InnerSignature\n                              // alias here; MSVC complains about the I\n                              // parameter pack not being expanded (error C3520)\n                              // despite it being expanded in the type alias.\n                              // TupleElement is also an MSVC workaround.\n                              // See its definition for details.\n                              Action<R(internal::TupleElement<\n                                       I, std::tuple<Args...>>...)>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    Action<InnerSignature<R, Args...>> converted(inner_action);\n\n    return [converted](Args&&... args) -> R {\n      return converted.Perform(std::forward_as_tuple(\n          std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));\n    };\n  }\n};\n\ntemplate <typename... Actions>\nclass DoAllAction;\n\n// Base case: only a single action.\ntemplate <typename FinalAction>\nclass DoAllAction<FinalAction> {\n public:\n  struct UserConstructorTag {};\n\n  template <typename T>\n  explicit DoAllAction(UserConstructorTag, T&& action)\n      : final_action_(std::forward<T>(action)) {}\n\n  // Rather than a call operator, we must define conversion operators to\n  // particular action types. This is necessary for embedded actions like\n  // DoDefault(), which rely on an action conversion operators rather than\n  // providing a call operator because even with a particular set of arguments\n  // they don't have a fixed return type.\n\n  template <typename R, typename... Args,\n            typename std::enable_if<\n                std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,\n                int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    return std::move(final_action_);\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          std::is_convertible<const FinalAction&, Action<R(Args...)>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    return final_action_;\n  }\n\n private:\n  FinalAction final_action_;\n};\n\n// Recursive case: support N actions by calling the initial action and then\n// calling through to the base class containing N-1 actions.\ntemplate <typename InitialAction, typename... OtherActions>\nclass DoAllAction<InitialAction, OtherActions...>\n    : private DoAllAction<OtherActions...> {\n private:\n  using Base = DoAllAction<OtherActions...>;\n\n  // The type of reference that should be provided to an initial action for a\n  // mocked function parameter of type T.\n  //\n  // There are two quirks here:\n  //\n  //  *  Unlike most forwarding functions, we pass scalars through by value.\n  //     This isn't strictly necessary because an lvalue reference would work\n  //     fine too and be consistent with other non-reference types, but it's\n  //     perhaps less surprising.\n  //\n  //     For example if the mocked function has signature void(int), then it\n  //     might seem surprising for the user's initial action to need to be\n  //     convertible to Action<void(const int&)>. This is perhaps less\n  //     surprising for a non-scalar type where there may be a performance\n  //     impact, or it might even be impossible, to pass by value.\n  //\n  //  *  More surprisingly, `const T&` is often not a const reference type.\n  //     By the reference collapsing rules in C++17 [dcl.ref]/6, if T refers to\n  //     U& or U&& for some non-scalar type U, then InitialActionArgType<T> is\n  //     U&. In other words, we may hand over a non-const reference.\n  //\n  //     So for example, given some non-scalar type Obj we have the following\n  //     mappings:\n  //\n  //            T               InitialActionArgType<T>\n  //         -------            -----------------------\n  //         Obj                const Obj&\n  //         Obj&               Obj&\n  //         Obj&&              Obj&\n  //         const Obj          const Obj&\n  //         const Obj&         const Obj&\n  //         const Obj&&        const Obj&\n  //\n  //     In other words, the initial actions get a mutable view of an non-scalar\n  //     argument if and only if the mock function itself accepts a non-const\n  //     reference type. They are never given an rvalue reference to an\n  //     non-scalar type.\n  //\n  //     This situation makes sense if you imagine use with a matcher that is\n  //     designed to write through a reference. For example, if the caller wants\n  //     to fill in a reference argument and then return a canned value:\n  //\n  //         EXPECT_CALL(mock, Call)\n  //             .WillOnce(DoAll(SetArgReferee<0>(17), Return(19)));\n  //\n  template <typename T>\n  using InitialActionArgType =\n      typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;\n\n public:\n  struct UserConstructorTag {};\n\n  template <typename T, typename... U>\n  explicit DoAllAction(UserConstructorTag, T&& initial_action,\n                       U&&... other_actions)\n      : Base({}, std::forward<U>(other_actions)...),\n        initial_action_(std::forward<T>(initial_action)) {}\n\n  template <typename R, typename... Args,\n            typename std::enable_if<\n                conjunction<\n                    // Both the initial action and the rest must support\n                    // conversion to OnceAction.\n                    std::is_convertible<\n                        InitialAction,\n                        OnceAction<void(InitialActionArgType<Args>...)>>,\n                    std::is_convertible<Base, OnceAction<R(Args...)>>>::value,\n                int>::type = 0>\n  operator OnceAction<R(Args...)>() && {  // NOLINT\n    // Return an action that first calls the initial action with arguments\n    // filtered through InitialActionArgType, then forwards arguments directly\n    // to the base class to deal with the remaining actions.\n    struct OA {\n      OnceAction<void(InitialActionArgType<Args>...)> initial_action;\n      OnceAction<R(Args...)> remaining_actions;\n\n      R operator()(Args... args) && {\n        std::move(initial_action)\n            .Call(static_cast<InitialActionArgType<Args>>(args)...);\n\n        return std::move(remaining_actions).Call(std::forward<Args>(args)...);\n      }\n    };\n\n    return OA{\n        std::move(initial_action_),\n        std::move(static_cast<Base&>(*this)),\n    };\n  }\n\n  template <\n      typename R, typename... Args,\n      typename std::enable_if<\n          conjunction<\n              // Both the initial action and the rest must support conversion to\n              // Action.\n              std::is_convertible<const InitialAction&,\n                                  Action<void(InitialActionArgType<Args>...)>>,\n              std::is_convertible<const Base&, Action<R(Args...)>>>::value,\n          int>::type = 0>\n  operator Action<R(Args...)>() const {  // NOLINT\n    // Return an action that first calls the initial action with arguments\n    // filtered through InitialActionArgType, then forwards arguments directly\n    // to the base class to deal with the remaining actions.\n    struct OA {\n      Action<void(InitialActionArgType<Args>...)> initial_action;\n      Action<R(Args...)> remaining_actions;\n\n      R operator()(Args... args) const {\n        initial_action.Perform(std::forward_as_tuple(\n            static_cast<InitialActionArgType<Args>>(args)...));\n\n        return remaining_actions.Perform(\n            std::forward_as_tuple(std::forward<Args>(args)...));\n      }\n    };\n\n    return OA{\n        initial_action_,\n        static_cast<const Base&>(*this),\n    };\n  }\n\n private:\n  InitialAction initial_action_;\n};\n\ntemplate <typename T, typename... Params>\nstruct ReturnNewAction {\n  T* operator()() const {\n    return internal::Apply(\n        [](const Params&... unpacked_params) {\n          return new T(unpacked_params...);\n        },\n        params);\n  }\n  std::tuple<Params...> params;\n};\n\ntemplate <size_t k>\nstruct ReturnArgAction {\n  template <typename... Args,\n            typename = typename std::enable_if<(k < sizeof...(Args))>::type>\n  auto operator()(Args&&... args) const -> decltype(std::get<k>(\n      std::forward_as_tuple(std::forward<Args>(args)...))) {\n    return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));\n  }\n};\n\ntemplate <size_t k, typename Ptr>\nstruct SaveArgAction {\n  Ptr pointer;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *pointer = std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <size_t k, typename Ptr>\nstruct SaveArgPointeeAction {\n  Ptr pointer;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    *pointer = *std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <size_t k, typename T>\nstruct SetArgRefereeAction {\n  T value;\n\n  template <typename... Args>\n  void operator()(Args&&... args) const {\n    using argk_type =\n        typename ::std::tuple_element<k, std::tuple<Args...>>::type;\n    static_assert(std::is_lvalue_reference<argk_type>::value,\n                  \"Argument must be a reference type.\");\n    std::get<k>(std::tie(args...)) = value;\n  }\n};\n\ntemplate <size_t k, typename I1, typename I2>\nstruct SetArrayArgumentAction {\n  I1 first;\n  I2 last;\n\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    auto value = std::get<k>(std::tie(args...));\n    for (auto it = first; it != last; ++it, (void)++value) {\n      *value = *it;\n    }\n  }\n};\n\ntemplate <size_t k>\nstruct DeleteArgAction {\n  template <typename... Args>\n  void operator()(const Args&... args) const {\n    delete std::get<k>(std::tie(args...));\n  }\n};\n\ntemplate <typename Ptr>\nstruct ReturnPointeeAction {\n  Ptr pointer;\n  template <typename... Args>\n  auto operator()(const Args&...) const -> decltype(*pointer) {\n    return *pointer;\n  }\n};\n\n#if GTEST_HAS_EXCEPTIONS\ntemplate <typename T>\nstruct ThrowAction {\n  T exception;\n  // We use a conversion operator to adapt to any return type.\n  template <typename R, typename... Args>\n  operator Action<R(Args...)>() const {  // NOLINT\n    T copy = exception;\n    return [copy](Args...) -> R { throw copy; };\n  }\n};\nstruct RethrowAction {\n  std::exception_ptr exception;\n  template <typename R, typename... Args>\n  operator Action<R(Args...)>() const {  // NOLINT\n    return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };\n  }\n};\n#endif  // GTEST_HAS_EXCEPTIONS\n\n}  // namespace internal\n\n// An Unused object can be implicitly constructed from ANY value.\n// This is handy when defining actions that ignore some or all of the\n// mock function arguments.  For example, given\n//\n//   MOCK_METHOD3(Foo, double(const string& label, double x, double y));\n//   MOCK_METHOD3(Bar, double(int index, double x, double y));\n//\n// instead of\n//\n//   double DistanceToOriginWithLabel(const string& label, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   double DistanceToOriginWithIndex(int index, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   ...\n//   EXPECT_CALL(mock, Foo(\"abc\", _, _))\n//       .WillOnce(Invoke(DistanceToOriginWithLabel));\n//   EXPECT_CALL(mock, Bar(5, _, _))\n//       .WillOnce(Invoke(DistanceToOriginWithIndex));\n//\n// you could write\n//\n//   // We can declare any uninteresting argument as Unused.\n//   double DistanceToOrigin(Unused, double x, double y) {\n//     return sqrt(x*x + y*y);\n//   }\n//   ...\n//   EXPECT_CALL(mock, Foo(\"abc\", _, _)).WillOnce(Invoke(DistanceToOrigin));\n//   EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));\ntypedef internal::IgnoredValue Unused;\n\n// Creates an action that does actions a1, a2, ..., sequentially in\n// each invocation. All but the last action will have a readonly view of the\n// arguments.\ntemplate <typename... Action>\ninternal::DoAllAction<typename std::decay<Action>::type...> DoAll(\n    Action&&... action) {\n  return internal::DoAllAction<typename std::decay<Action>::type...>(\n      {}, std::forward<Action>(action)...);\n}\n\n// WithArg<k>(an_action) creates an action that passes the k-th\n// (0-based) argument of the mock function to an_action and performs\n// it.  It adapts an action accepting one argument to one that accepts\n// multiple arguments.  For convenience, we also provide\n// WithArgs<k>(an_action) (defined below) as a synonym.\ntemplate <size_t k, typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type, k> WithArg(\n    InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes\n// the selected arguments of the mock function to an_action and\n// performs it.  It serves as an adaptor between actions with\n// different argument lists.\ntemplate <size_t k, size_t... ks, typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>\nWithArgs(InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// WithoutArgs(inner_action) can be used in a mock function with a\n// non-empty argument list to perform inner_action, which takes no\n// argument.  In other words, it adapts an action accepting no\n// argument to one that accepts (and ignores) arguments.\ntemplate <typename InnerAction>\ninternal::WithArgsAction<typename std::decay<InnerAction>::type> WithoutArgs(\n    InnerAction&& action) {\n  return {std::forward<InnerAction>(action)};\n}\n\n// Creates an action that returns a value.\n//\n// The returned type can be used with a mock function returning a non-void,\n// non-reference type U as follows:\n//\n//  *  If R is convertible to U and U is move-constructible, then the action can\n//     be used with WillOnce.\n//\n//  *  If const R& is convertible to U and U is copy-constructible, then the\n//     action can be used with both WillOnce and WillRepeatedly.\n//\n// The mock expectation contains the R value from which the U return value is\n// constructed (a move/copy of the argument to Return). This means that the R\n// value will survive at least until the mock object's expectations are cleared\n// or the mock object is destroyed, meaning that U can safely be a\n// reference-like type such as std::string_view:\n//\n//     // The mock function returns a view of a copy of the string fed to\n//     // Return. The view is valid even after the action is performed.\n//     MockFunction<std::string_view()> mock;\n//     EXPECT_CALL(mock, Call).WillOnce(Return(std::string(\"taco\")));\n//     const std::string_view result = mock.AsStdFunction()();\n//     EXPECT_EQ(\"taco\", result);\n//\ntemplate <typename R>\ninternal::ReturnAction<R> Return(R value) {\n  return internal::ReturnAction<R>(std::move(value));\n}\n\n// Creates an action that returns NULL.\ninline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {\n  return MakePolymorphicAction(internal::ReturnNullAction());\n}\n\n// Creates an action that returns from a void function.\ninline PolymorphicAction<internal::ReturnVoidAction> Return() {\n  return MakePolymorphicAction(internal::ReturnVoidAction());\n}\n\n// Creates an action that returns the reference to a variable.\ntemplate <typename R>\ninline internal::ReturnRefAction<R> ReturnRef(R& x) {  // NOLINT\n  return internal::ReturnRefAction<R>(x);\n}\n\n// Prevent using ReturnRef on reference to temporary.\ntemplate <typename R, R* = nullptr>\ninternal::ReturnRefAction<R> ReturnRef(R&&) = delete;\n\n// Creates an action that returns the reference to a copy of the\n// argument.  The copy is created when the action is constructed and\n// lives as long as the action.\ntemplate <typename R>\ninline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {\n  return internal::ReturnRefOfCopyAction<R>(x);\n}\n\n// DEPRECATED: use Return(x) directly with WillOnce.\n//\n// Modifies the parent action (a Return() action) to perform a move of the\n// argument instead of a copy.\n// Return(ByMove()) actions can only be executed once and will assert this\n// invariant.\ntemplate <typename R>\ninternal::ByMoveWrapper<R> ByMove(R x) {\n  return internal::ByMoveWrapper<R>(std::move(x));\n}\n\n// Creates an action that returns an element of `vals`. Calling this action will\n// repeatedly return the next value from `vals` until it reaches the end and\n// will restart from the beginning.\ntemplate <typename T>\ninternal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {\n  return internal::ReturnRoundRobinAction<T>(std::move(vals));\n}\n\n// Creates an action that returns an element of `vals`. Calling this action will\n// repeatedly return the next value from `vals` until it reaches the end and\n// will restart from the beginning.\ntemplate <typename T>\ninternal::ReturnRoundRobinAction<T> ReturnRoundRobin(\n    std::initializer_list<T> vals) {\n  return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));\n}\n\n// Creates an action that does the default action for the give mock function.\ninline internal::DoDefaultAction DoDefault() {\n  return internal::DoDefaultAction();\n}\n\n// Creates an action that sets the variable pointed by the N-th\n// (0-based) function argument to 'value'.\ntemplate <size_t N, typename T>\ninternal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {\n  return {std::move(value)};\n}\n\n// The following version is DEPRECATED.\ntemplate <size_t N, typename T>\ninternal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {\n  return {std::move(value)};\n}\n\n// Creates an action that sets a pointer referent to a given value.\ntemplate <typename T1, typename T2>\nPolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {\n  return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));\n}\n\n#ifndef GTEST_OS_WINDOWS_MOBILE\n\n// Creates an action that sets errno and returns the appropriate error.\ntemplate <typename T>\nPolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(\n    int errval, T result) {\n  return MakePolymorphicAction(\n      internal::SetErrnoAndReturnAction<T>(errval, result));\n}\n\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n// Various overloads for Invoke().\n\n// Legacy function.\n// Actions can now be implicitly constructed from callables. No need to create\n// wrapper objects.\n// This function exists for backwards compatibility.\ntemplate <typename FunctionImpl>\ntypename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {\n  return std::forward<FunctionImpl>(function_impl);\n}\n\n// Creates an action that invokes the given method on the given object\n// with the mock function's arguments.\ntemplate <class Class, typename MethodPtr>\ninternal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,\n                                                      MethodPtr method_ptr) {\n  return {obj_ptr, method_ptr};\n}\n\n// Creates an action that invokes 'function_impl' with no argument.\ntemplate <typename FunctionImpl>\ninternal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>\nInvokeWithoutArgs(FunctionImpl function_impl) {\n  return {std::move(function_impl)};\n}\n\n// Creates an action that invokes the given method on the given object\n// with no argument.\ntemplate <class Class, typename MethodPtr>\ninternal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(\n    Class* obj_ptr, MethodPtr method_ptr) {\n  return {obj_ptr, method_ptr};\n}\n\n// Creates an action that performs an_action and throws away its\n// result.  In other words, it changes the return type of an_action to\n// void.  an_action MUST NOT return void, or the code won't compile.\ntemplate <typename A>\ninline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {\n  return internal::IgnoreResultAction<A>(an_action);\n}\n\n// Creates a reference wrapper for the given L-value.  If necessary,\n// you can explicitly specify the type of the reference.  For example,\n// suppose 'derived' is an object of type Derived, ByRef(derived)\n// would wrap a Derived&.  If you want to wrap a const Base& instead,\n// where Base is a base class of Derived, just write:\n//\n//   ByRef<const Base>(derived)\n//\n// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.\n// However, it may still be used for consistency with ByMove().\ntemplate <typename T>\ninline ::std::reference_wrapper<T> ByRef(T& l_value) {  // NOLINT\n  return ::std::reference_wrapper<T>(l_value);\n}\n\n// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new\n// instance of type T, constructed on the heap with constructor arguments\n// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.\ntemplate <typename T, typename... Params>\ninternal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew(\n    Params&&... params) {\n  return {std::forward_as_tuple(std::forward<Params>(params)...)};\n}\n\n// Action ReturnArg<k>() returns the k-th argument of the mock function.\ntemplate <size_t k>\ninternal::ReturnArgAction<k> ReturnArg() {\n  return {};\n}\n\n// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the\n// mock function to *pointer.\ntemplate <size_t k, typename Ptr>\ninternal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {\n  return {pointer};\n}\n\n// Action SaveArgPointee<k>(pointer) saves the value pointed to\n// by the k-th (0-based) argument of the mock function to *pointer.\ntemplate <size_t k, typename Ptr>\ninternal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) {\n  return {pointer};\n}\n\n// Action SetArgReferee<k>(value) assigns 'value' to the variable\n// referenced by the k-th (0-based) argument of the mock function.\ntemplate <size_t k, typename T>\ninternal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee(\n    T&& value) {\n  return {std::forward<T>(value)};\n}\n\n// Action SetArrayArgument<k>(first, last) copies the elements in\n// source range [first, last) to the array pointed to by the k-th\n// (0-based) argument, which can be either a pointer or an\n// iterator. The action does not take ownership of the elements in the\n// source range.\ntemplate <size_t k, typename I1, typename I2>\ninternal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first,\n                                                             I2 last) {\n  return {first, last};\n}\n\n// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock\n// function.\ntemplate <size_t k>\ninternal::DeleteArgAction<k> DeleteArg() {\n  return {};\n}\n\n// This action returns the value pointed to by 'pointer'.\ntemplate <typename Ptr>\ninternal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {\n  return {pointer};\n}\n\n#if GTEST_HAS_EXCEPTIONS\n// Action Throw(exception) can be used in a mock function of any type\n// to throw the given exception.  Any copyable value can be thrown,\n// except for std::exception_ptr, which is likely a mistake if\n// thrown directly.\ntemplate <typename T>\ntypename std::enable_if<\n    !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,\n    internal::ThrowAction<typename std::decay<T>::type>>::type\nThrow(T&& exception) {\n  return {std::forward<T>(exception)};\n}\n// Action Rethrow(exception_ptr) can be used in a mock function of any type\n// to rethrow any exception_ptr. Note that the same object is thrown each time.\ninline internal::RethrowAction Rethrow(std::exception_ptr exception) {\n  return {std::move(exception)};\n}\n#endif  // GTEST_HAS_EXCEPTIONS\n\nnamespace internal {\n\n// A macro from the ACTION* family (defined later in gmock-generated-actions.h)\n// defines an action that can be used in a mock function.  Typically,\n// these actions only care about a subset of the arguments of the mock\n// function.  For example, if such an action only uses the second\n// argument, it can be used in any mock function that takes >= 2\n// arguments where the type of the second argument is compatible.\n//\n// Therefore, the action implementation must be prepared to take more\n// arguments than it needs.  The ExcessiveArg type is used to\n// represent those excessive arguments.  In order to keep the compiler\n// error messages tractable, we define it in the testing namespace\n// instead of testing::internal.  However, this is an INTERNAL TYPE\n// and subject to change without notice, so a user MUST NOT USE THIS\n// TYPE DIRECTLY.\nstruct ExcessiveArg {};\n\n// Builds an implementation of an Action<> for some particular signature, using\n// a class defined by an ACTION* macro.\ntemplate <typename F, typename Impl>\nstruct ActionImpl;\n\ntemplate <typename Impl>\nstruct ImplBase {\n  struct Holder {\n    // Allows each copy of the Action<> to get to the Impl.\n    explicit operator const Impl&() const { return *ptr; }\n    std::shared_ptr<Impl> ptr;\n  };\n  using type = typename std::conditional<std::is_constructible<Impl>::value,\n                                         Impl, Holder>::type;\n};\n\ntemplate <typename R, typename... Args, typename Impl>\nstruct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {\n  using Base = typename ImplBase<Impl>::type;\n  using function_type = R(Args...);\n  using args_type = std::tuple<Args...>;\n\n  ActionImpl() = default;  // Only defined if appropriate for Base.\n  explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} {}\n\n  R operator()(Args&&... arg) const {\n    static constexpr size_t kMaxArgs =\n        sizeof...(Args) <= 10 ? sizeof...(Args) : 10;\n    return Apply(std::make_index_sequence<kMaxArgs>{},\n                 std::make_index_sequence<10 - kMaxArgs>{},\n                 args_type{std::forward<Args>(arg)...});\n  }\n\n  template <std::size_t... arg_id, std::size_t... excess_id>\n  R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,\n          const args_type& args) const {\n    // Impl need not be specific to the signature of action being implemented;\n    // only the implementing function body needs to have all of the specific\n    // types instantiated.  Up to 10 of the args that are provided by the\n    // args_type get passed, followed by a dummy of unspecified type for the\n    // remainder up to 10 explicit args.\n    static constexpr ExcessiveArg kExcessArg{};\n    return static_cast<const Impl&>(*this)\n        .template gmock_PerformImpl<\n            /*function_type=*/function_type, /*return_type=*/R,\n            /*args_type=*/args_type,\n            /*argN_type=*/\n            typename std::tuple_element<arg_id, args_type>::type...>(\n            /*args=*/args, std::get<arg_id>(args)...,\n            ((void)excess_id, kExcessArg)...);\n  }\n};\n\n// Stores a default-constructed Impl as part of the Action<>'s\n// std::function<>. The Impl should be trivial to copy.\ntemplate <typename F, typename Impl>\n::testing::Action<F> MakeAction() {\n  return ::testing::Action<F>(ActionImpl<F, Impl>());\n}\n\n// Stores just the one given instance of Impl.\ntemplate <typename F, typename Impl>\n::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {\n  return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));\n}\n\n#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \\\n  , GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i\n#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                               \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \\\n      GMOCK_INTERNAL_ARG_UNUSED, , 10)\n\n#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i\n#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \\\n  const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10)\n\n#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type\n#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \\\n  GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10))\n\n#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type\n#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params))\n\n#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type\n#define GMOCK_ACTION_TYPE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params))\n\n#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \\\n  , param##_type gmock_p##i\n#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params))\n\n#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \\\n  , std::forward<param##_type>(gmock_p##i)\n#define GMOCK_ACTION_GVALUE_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params))\n\n#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \\\n  , param(::std::forward<param##_type>(gmock_p##i))\n#define GMOCK_ACTION_INIT_PARAMS_(params) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params))\n\n#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param;\n#define GMOCK_ACTION_FIELD_PARAMS_(params) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params)\n\n#define GMOCK_INTERNAL_ACTION(name, full_name, params)                         \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  class full_name {                                                            \\\n   public:                                                                     \\\n    explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))               \\\n        : impl_(std::make_shared<gmock_Impl>(                                  \\\n              GMOCK_ACTION_GVALUE_PARAMS_(params))) {}                         \\\n    full_name(const full_name&) = default;                                     \\\n    full_name(full_name&&) noexcept = default;                                 \\\n    template <typename F>                                                      \\\n    operator ::testing::Action<F>() const {                                    \\\n      return ::testing::internal::MakeAction<F>(impl_);                        \\\n    }                                                                          \\\n                                                                               \\\n   private:                                                                    \\\n    class gmock_Impl {                                                         \\\n     public:                                                                   \\\n      explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params))            \\\n          : GMOCK_ACTION_INIT_PARAMS_(params) {}                               \\\n      template <typename function_type, typename return_type,                  \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \\\n      GMOCK_ACTION_FIELD_PARAMS_(params)                                       \\\n    };                                                                         \\\n    std::shared_ptr<const gmock_Impl> impl_;                                   \\\n  };                                                                           \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \\\n      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_;        \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name(                    \\\n      GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) {                              \\\n    return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>(                       \\\n        GMOCK_ACTION_GVALUE_PARAMS_(params));                                  \\\n  }                                                                            \\\n  template <GMOCK_ACTION_TYPENAME_PARAMS_(params)>                             \\\n  template <typename function_type, typename return_type, typename args_type,  \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \\\n  return_type                                                                  \\\n  full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl::gmock_PerformImpl( \\\n      GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const\n\n}  // namespace internal\n\n// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored.\n#define ACTION(name)                                                          \\\n  class name##Action {                                                        \\\n   public:                                                                    \\\n    explicit name##Action() noexcept {}                                       \\\n    name##Action(const name##Action&) noexcept {}                             \\\n    template <typename F>                                                     \\\n    operator ::testing::Action<F>() const {                                   \\\n      return ::testing::internal::MakeAction<F, gmock_Impl>();                \\\n    }                                                                         \\\n                                                                              \\\n   private:                                                                   \\\n    class gmock_Impl {                                                        \\\n     public:                                                                  \\\n      template <typename function_type, typename return_type,                 \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>        \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \\\n    };                                                                        \\\n  };                                                                          \\\n  inline name##Action name() GTEST_MUST_USE_RESULT_;                          \\\n  inline name##Action name() { return name##Action(); }                       \\\n  template <typename function_type, typename return_type, typename args_type, \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                \\\n  return_type name##Action::gmock_Impl::gmock_PerformImpl(                    \\\n      GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const\n\n#define ACTION_P(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))\n\n#define ACTION_P2(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))\n\n#define ACTION_P3(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))\n\n#define ACTION_P4(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))\n\n#define ACTION_P5(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))\n\n#define ACTION_P6(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))\n\n#define ACTION_P7(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))\n\n#define ACTION_P8(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))\n\n#define ACTION_P9(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))\n\n#define ACTION_P10(name, ...) \\\n  GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-cardinalities.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some commonly used cardinalities.  More\n// cardinalities can be defined by the user implementing the\n// CardinalityInterface interface if necessary.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n\n#include <limits.h>\n\n#include <memory>\n#include <ostream>  // NOLINT\n\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// To implement a cardinality Foo, define:\n//   1. a class FooCardinality that implements the\n//      CardinalityInterface interface, and\n//   2. a factory function that creates a Cardinality object from a\n//      const FooCardinality*.\n//\n// The two-level delegation design follows that of Matcher, providing\n// consistency for extension developers.  It also eases ownership\n// management as Cardinality objects can now be copied like plain values.\n\n// The implementation of a cardinality.\nclass CardinalityInterface {\n public:\n  virtual ~CardinalityInterface() = default;\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  virtual int ConservativeLowerBound() const { return 0; }\n  virtual int ConservativeUpperBound() const { return INT_MAX; }\n\n  // Returns true if and only if call_count calls will satisfy this\n  // cardinality.\n  virtual bool IsSatisfiedByCallCount(int call_count) const = 0;\n\n  // Returns true if and only if call_count calls will saturate this\n  // cardinality.\n  virtual bool IsSaturatedByCallCount(int call_count) const = 0;\n\n  // Describes self to an ostream.\n  virtual void DescribeTo(::std::ostream* os) const = 0;\n};\n\n// A Cardinality is a copyable and IMMUTABLE (except by assignment)\n// object that specifies how many times a mock function is expected to\n// be called.  The implementation of Cardinality is just a std::shared_ptr\n// to const CardinalityInterface. Don't inherit from Cardinality!\nclass GTEST_API_ Cardinality {\n public:\n  // Constructs a null cardinality.  Needed for storing Cardinality\n  // objects in STL containers.\n  Cardinality() = default;\n\n  // Constructs a Cardinality from its implementation.\n  explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }\n  int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }\n\n  // Returns true if and only if call_count calls will satisfy this\n  // cardinality.\n  bool IsSatisfiedByCallCount(int call_count) const {\n    return impl_->IsSatisfiedByCallCount(call_count);\n  }\n\n  // Returns true if and only if call_count calls will saturate this\n  // cardinality.\n  bool IsSaturatedByCallCount(int call_count) const {\n    return impl_->IsSaturatedByCallCount(call_count);\n  }\n\n  // Returns true if and only if call_count calls will over-saturate this\n  // cardinality, i.e. exceed the maximum number of allowed calls.\n  bool IsOverSaturatedByCallCount(int call_count) const {\n    return impl_->IsSaturatedByCallCount(call_count) &&\n           !impl_->IsSatisfiedByCallCount(call_count);\n  }\n\n  // Describes self to an ostream\n  void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }\n\n  // Describes the given actual call count to an ostream.\n  static void DescribeActualCallCountTo(int actual_call_count,\n                                        ::std::ostream* os);\n\n private:\n  std::shared_ptr<const CardinalityInterface> impl_;\n};\n\n// Creates a cardinality that allows at least n calls.\nGTEST_API_ Cardinality AtLeast(int n);\n\n// Creates a cardinality that allows at most n calls.\nGTEST_API_ Cardinality AtMost(int n);\n\n// Creates a cardinality that allows any number of calls.\nGTEST_API_ Cardinality AnyNumber();\n\n// Creates a cardinality that allows between min and max calls.\nGTEST_API_ Cardinality Between(int min, int max);\n\n// Creates a cardinality that allows exactly n calls.\nGTEST_API_ Cardinality Exactly(int n);\n\n// Creates a cardinality from its implementation.\ninline Cardinality MakeCardinality(const CardinalityInterface* c) {\n  return Cardinality(c);\n}\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-function-mocker.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements MOCK_METHOD.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n\n#include <cstddef>\n#include <type_traits>  // IWYU pragma: keep\n#include <utility>      // IWYU pragma: keep\n\n#include \"gmock/gmock-spec-builders.h\"\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-pp.h\"\n\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing identity_t = T;\n\ntemplate <typename Pattern>\nstruct ThisRefAdjuster {\n  template <typename T>\n  using AdjustT = typename std::conditional<\n      std::is_const<typename std::remove_reference<Pattern>::type>::value,\n      typename std::conditional<std::is_lvalue_reference<Pattern>::value,\n                                const T&, const T&&>::type,\n      typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&,\n                                T&&>::type>::type;\n\n  template <typename MockType>\n  static AdjustT<MockType> Adjust(const MockType& mock) {\n    return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock));\n  }\n};\n\nconstexpr bool PrefixOf(const char* a, const char* b) {\n  return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {\n  return N <= M && internal::PrefixOf(prefix, str);\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {\n  return N <= M && internal::PrefixOf(suffix, str + M - N);\n}\n\ntemplate <size_t N, size_t M>\nconstexpr bool Equals(const char (&a)[N], const char (&b)[M]) {\n  return N == M && internal::PrefixOf(a, b);\n}\n\ntemplate <size_t N>\nconstexpr bool ValidateSpec(const char (&spec)[N]) {\n  return internal::Equals(\"const\", spec) ||\n         internal::Equals(\"override\", spec) ||\n         internal::Equals(\"final\", spec) ||\n         internal::Equals(\"noexcept\", spec) ||\n         (internal::StartsWith(\"noexcept(\", spec) &&\n          internal::EndsWith(\")\", spec)) ||\n         internal::Equals(\"ref(&)\", spec) ||\n         internal::Equals(\"ref(&&)\", spec) ||\n         (internal::StartsWith(\"Calltype(\", spec) &&\n          internal::EndsWith(\")\", spec));\n}\n\n}  // namespace internal\n\n// The style guide prohibits \"using\" statements in a namespace scope\n// inside a header file.  However, the FunctionMocker class template\n// is meant to be defined in the ::testing namespace.  The following\n// line is just a trick for working around a bug in MSVC 8.0, which\n// cannot handle it if we define FunctionMocker in ::testing.\nusing internal::FunctionMocker;\n}  // namespace testing\n\n#define MOCK_METHOD(...)                                               \\\n  GMOCK_INTERNAL_WARNING_PUSH()                                        \\\n  GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-member-function\")    \\\n  GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \\\n  GMOCK_INTERNAL_WARNING_POP()\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \\\n  GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec)  \\\n  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args);                                \\\n  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec);                                \\\n  GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(                                   \\\n      GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args));        \\\n  GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec)                                  \\\n  GMOCK_INTERNAL_MOCK_METHOD_IMPL(                                         \\\n      GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec),  \\\n      GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \\\n      GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec),                             \\\n      GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec),                             \\\n      GMOCK_INTERNAL_GET_REF_SPEC(_Spec),                                  \\\n      (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \\\n  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)\n\n#define GMOCK_INTERNAL_WRONG_ARITY(...)                                      \\\n  static_assert(                                                             \\\n      false,                                                                 \\\n      \"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, \"             \\\n      \"_MethodName, _Args and optionally _Spec. _Args and _Spec must be \"    \\\n      \"enclosed in parentheses. If _Ret is a type with unprotected commas, \" \\\n      \"it must also be enclosed in parentheses.\")\n\n#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \\\n  static_assert(                                  \\\n      GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple),        \\\n      GMOCK_PP_STRINGIZE(_Tuple) \" should be enclosed in parentheses.\")\n\n#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...)                 \\\n  static_assert(                                                       \\\n      std::is_function<__VA_ARGS__>::value,                            \\\n      \"Signature must be a function type, maybe return type contains \" \\\n      \"unprotected comma.\");                                           \\\n  static_assert(                                                       \\\n      ::testing::tuple_size<typename ::testing::internal::Function<    \\\n              __VA_ARGS__>::ArgumentTuple>::value == _N,               \\\n      \"This method does not take \" GMOCK_PP_STRINGIZE(                 \\\n          _N) \" arguments. Parenthesize all types with unprotected commas.\")\n\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)\n\n#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness,           \\\n                                        _Override, _Final, _NoexceptSpec,      \\\n                                        _CallType, _RefSpec, _Signature)       \\\n  typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS(               \\\n      _Signature)>::Result                                                     \\\n  GMOCK_INTERNAL_EXPAND(_CallType)                                             \\\n      _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N))   \\\n          GMOCK_PP_IF(_Constness, const, )                                     \\\n              _RefSpec _NoexceptSpec GMOCK_PP_IF(_Override, override, )        \\\n                  GMOCK_PP_IF(_Final, final, ) {                               \\\n    GMOCK_MOCKER_(_N, _Constness, _MethodName)                                 \\\n        .SetOwnerAndName(this, #_MethodName);                                  \\\n    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \\\n        .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N));  \\\n  }                                                                            \\\n  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \\\n      GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N))       \\\n      GMOCK_PP_IF(_Constness, const, ) _RefSpec {                              \\\n    GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this);            \\\n    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \\\n        .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N));         \\\n  }                                                                            \\\n  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \\\n      const ::testing::internal::WithoutMatchers&,                             \\\n      GMOCK_PP_IF(_Constness, const, )::testing::internal::Function<           \\\n          GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \\\n    return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF(                   \\\n        _Constness, const, ) int _RefSpec>::Adjust(*this)                      \\\n        .gmock_##_MethodName(GMOCK_PP_REPEAT(                                  \\\n            GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N));               \\\n  }                                                                            \\\n  mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)>        \\\n  GMOCK_MOCKER_(_N, _Constness, _MethodName)\n\n#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__\n\n// Valid modifiers.\n#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))\n\n#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(                       \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))\n\n#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))\n\n#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple)\n\n#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem)          \\\n  GMOCK_PP_IF(                                                          \\\n      GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \\\n      _elem, )\n\n#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple)\n\n#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem)          \\\n  GMOCK_PP_IF(                                                          \\\n      GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \\\n      GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )\n\n#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)\n\n#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem)                       \\\n  GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \\\n              GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )\n\n#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \\\n  static_assert(                                                     \\\n      ::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)),  \\\n      \"Token \\'\" GMOCK_PP_STRINGIZE(                                 \\\n          _elem) \"\\' cannot be recognized as a valid specification \" \\\n                 \"modifier. Is a ',' missing?\");\n#else\n#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem)                 \\\n  static_assert(                                                               \\\n      (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) +         \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) +      \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) +         \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) +      \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) +           \\\n       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \\\n      GMOCK_PP_STRINGIZE(                                                      \\\n          _elem) \" cannot be recognized as a valid specification modifier.\");\n#endif  // GMOCK_INTERNAL_STRICT_SPEC_ASSERT\n\n// Modifiers implementation.\n#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_CONST_I_const ,\n\n#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,\n\n#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,\n\n#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,\n\n#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_REF_I_ref ,\n\n#define GMOCK_INTERNAL_UNPACK_ref(x) x\n\n#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \\\n  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)\n\n#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,\n\n#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__\n\n// Note: The use of `identity_t` here allows _Ret to represent return types that\n// would normally need to be specified in a different way. For example, a method\n// returning a function pointer must be written as\n//\n// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)\n//\n// But we only support placing the return type at the beginning. To handle this,\n// we wrap all calls in identity_t, so that a declaration will be expanded to\n//\n// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)\n//\n// This allows us to work around the syntactic oddities of function/method\n// types.\n#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)                                 \\\n  ::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \\\n                                              GMOCK_PP_REMOVE_PARENS,         \\\n                                              GMOCK_PP_IDENTITY)(_Ret)>(      \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))\n\n#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem)                          \\\n  GMOCK_PP_COMMA_IF(_i)                                                \\\n  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \\\n              GMOCK_PP_IDENTITY)                                       \\\n  (_elem)\n\n#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _)            \\\n  GMOCK_PP_COMMA_IF(_i)                                        \\\n  GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \\\n  GMOCK_PP_COMMA_IF(_i)                               \\\n  ::std::forward<GMOCK_INTERNAL_ARG_O(                \\\n      _i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)\n\n#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _)        \\\n  GMOCK_PP_COMMA_IF(_i)                                            \\\n  GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \\\n  GMOCK_PP_COMMA_IF(_i)                             \\\n  gmock_a##_i\n\n#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \\\n  GMOCK_PP_COMMA_IF(_i)                                      \\\n  ::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()\n\n#define GMOCK_INTERNAL_ARG_O(_i, ...) \\\n  typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type\n\n#define GMOCK_INTERNAL_MATCHER_O(_i, ...)                          \\\n  const ::testing::Matcher<typename ::testing::internal::Function< \\\n      __VA_ARGS__>::template Arg<_i>::type>&\n\n#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__)\n#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__)\n#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__)\n#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__)\n#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__)\n#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__)\n#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__)\n#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__)\n#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__)\n#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__)\n#define MOCK_METHOD10(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__)\n#define MOCK_CONST_METHOD1(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__)\n#define MOCK_CONST_METHOD2(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__)\n#define MOCK_CONST_METHOD3(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__)\n#define MOCK_CONST_METHOD4(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__)\n#define MOCK_CONST_METHOD5(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__)\n#define MOCK_CONST_METHOD6(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__)\n#define MOCK_CONST_METHOD7(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__)\n#define MOCK_CONST_METHOD8(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__)\n#define MOCK_CONST_METHOD9(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__)\n#define MOCK_CONST_METHOD10(m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__)\n\n#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__)\n#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__)\n#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__)\n#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__)\n#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__)\n#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__)\n#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__)\n#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__)\n#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__)\n#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__)\n#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__)\n\n#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__)\n#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__)\n#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__)\n#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__)\n#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__)\n#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__)\n#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__)\n#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__)\n#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__)\n#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__)\n#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \\\n  GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__)\n\n#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n\n#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \\\n  MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)\n\n#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \\\n  GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(                                  \\\n      args_num, ::testing::internal::identity_t<__VA_ARGS__>);            \\\n  GMOCK_INTERNAL_MOCK_METHOD_IMPL(                                        \\\n      args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, ,          \\\n      (::testing::internal::identity_t<__VA_ARGS__>))\n\n#define GMOCK_MOCKER_(arity, constness, Method) \\\n  GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-matchers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// The MATCHER* family of macros can be used in a namespace scope to\n// define custom matchers easily.\n//\n// Basic Usage\n// ===========\n//\n// The syntax\n//\n//   MATCHER(name, description_string) { statements; }\n//\n// defines a matcher with the given name that executes the statements,\n// which must return a bool to indicate if the match succeeds.  Inside\n// the statements, you can refer to the value being matched by 'arg',\n// and refer to its type by 'arg_type'.\n//\n// The description string documents what the matcher does, and is used\n// to generate the failure message when the match fails.  Since a\n// MATCHER() is usually defined in a header file shared by multiple\n// C++ source files, we require the description to be a C-string\n// literal to avoid possible side effects.  It can be empty, in which\n// case we'll use the sequence of words in the matcher name as the\n// description.\n//\n// For example:\n//\n//   MATCHER(IsEven, \"\") { return (arg % 2) == 0; }\n//\n// allows you to write\n//\n//   // Expects mock_foo.Bar(n) to be called where n is even.\n//   EXPECT_CALL(mock_foo, Bar(IsEven()));\n//\n// or,\n//\n//   // Verifies that the value of some_expression is even.\n//   EXPECT_THAT(some_expression, IsEven());\n//\n// If the above assertion fails, it will print something like:\n//\n//   Value of: some_expression\n//   Expected: is even\n//     Actual: 7\n//\n// where the description \"is even\" is automatically calculated from the\n// matcher name IsEven.\n//\n// Argument Type\n// =============\n//\n// Note that the type of the value being matched (arg_type) is\n// determined by the context in which you use the matcher and is\n// supplied to you by the compiler, so you don't need to worry about\n// declaring it (nor can you).  This allows the matcher to be\n// polymorphic.  For example, IsEven() can be used to match any type\n// where the value of \"(arg % 2) == 0\" can be implicitly converted to\n// a bool.  In the \"Bar(IsEven())\" example above, if method Bar()\n// takes an int, 'arg_type' will be int; if it takes an unsigned long,\n// 'arg_type' will be unsigned long; and so on.\n//\n// Parameterizing Matchers\n// =======================\n//\n// Sometimes you'll want to parameterize the matcher.  For that you\n// can use another macro:\n//\n//   MATCHER_P(name, param_name, description_string) { statements; }\n//\n// For example:\n//\n//   MATCHER_P(HasAbsoluteValue, value, \"\") { return abs(arg) == value; }\n//\n// will allow you to write:\n//\n//   EXPECT_THAT(Blah(\"a\"), HasAbsoluteValue(n));\n//\n// which may lead to this message (assuming n is 10):\n//\n//   Value of: Blah(\"a\")\n//   Expected: has absolute value 10\n//     Actual: -9\n//\n// Note that both the matcher description and its parameter are\n// printed, making the message human-friendly.\n//\n// In the matcher definition body, you can write 'foo_type' to\n// reference the type of a parameter named 'foo'.  For example, in the\n// body of MATCHER_P(HasAbsoluteValue, value) above, you can write\n// 'value_type' to refer to the type of 'value'.\n//\n// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to\n// support multi-parameter matchers.\n//\n// Describing Parameterized Matchers\n// =================================\n//\n// The last argument to MATCHER*() is a string-typed expression.  The\n// expression can reference all of the matcher's parameters and a\n// special bool-typed variable named 'negation'.  When 'negation' is\n// false, the expression should evaluate to the matcher's description;\n// otherwise it should evaluate to the description of the negation of\n// the matcher.  For example,\n//\n//   using testing::PrintToString;\n//\n//   MATCHER_P2(InClosedRange, low, hi,\n//       std::string(negation ? \"is not\" : \"is\") + \" in range [\" +\n//       PrintToString(low) + \", \" + PrintToString(hi) + \"]\") {\n//     return low <= arg && arg <= hi;\n//   }\n//   ...\n//   EXPECT_THAT(3, InClosedRange(4, 6));\n//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));\n//\n// would generate two failures that contain the text:\n//\n//   Expected: is in range [4, 6]\n//   ...\n//   Expected: is not in range [2, 4]\n//\n// If you specify \"\" as the description, the failure message will\n// contain the sequence of words in the matcher name followed by the\n// parameter values printed as a tuple.  For example,\n//\n//   MATCHER_P2(InClosedRange, low, hi, \"\") { ... }\n//   ...\n//   EXPECT_THAT(3, InClosedRange(4, 6));\n//   EXPECT_THAT(3, Not(InClosedRange(2, 4)));\n//\n// would generate two failures that contain the text:\n//\n//   Expected: in closed range (4, 6)\n//   ...\n//   Expected: not (in closed range (2, 4))\n//\n// Types of Matcher Parameters\n// ===========================\n//\n// For the purpose of typing, you can view\n//\n//   MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }\n//\n// as shorthand for\n//\n//   template <typename p1_type, ..., typename pk_type>\n//   FooMatcherPk<p1_type, ..., pk_type>\n//   Foo(p1_type p1, ..., pk_type pk) { ... }\n//\n// When you write Foo(v1, ..., vk), the compiler infers the types of\n// the parameters v1, ..., and vk for you.  If you are not happy with\n// the result of the type inference, you can specify the types by\n// explicitly instantiating the template, as in Foo<long, bool>(5,\n// false).  As said earlier, you don't get to (or need to) specify\n// 'arg_type' as that's determined by the context in which the matcher\n// is used.  You can assign the result of expression Foo(p1, ..., pk)\n// to a variable of type FooMatcherPk<p1_type, ..., pk_type>.  This\n// can be useful when composing matchers.\n//\n// While you can instantiate a matcher template with reference types,\n// passing the parameters by pointer usually makes your code more\n// readable.  If, however, you still want to pass a parameter by\n// reference, be aware that in the failure message generated by the\n// matcher you will see the value of the referenced object but not its\n// address.\n//\n// Explaining Match Results\n// ========================\n//\n// Sometimes the matcher description alone isn't enough to explain why\n// the match has failed or succeeded.  For example, when expecting a\n// long string, it can be very helpful to also print the diff between\n// the expected string and the actual one.  To achieve that, you can\n// optionally stream additional information to a special variable\n// named result_listener, whose type is a pointer to class\n// MatchResultListener:\n//\n//   MATCHER_P(EqualsLongString, str, \"\") {\n//     if (arg == str) return true;\n//\n//     *result_listener << \"the difference: \"\n///                     << DiffStrings(str, arg);\n//     return false;\n//   }\n//\n// Overloading Matchers\n// ====================\n//\n// You can overload matchers with different numbers of parameters:\n//\n//   MATCHER_P(Blah, a, description_string1) { ... }\n//   MATCHER_P2(Blah, a, b, description_string2) { ... }\n//\n// Caveats\n// =======\n//\n// When defining a new matcher, you should also consider implementing\n// MatcherInterface or using MakePolymorphicMatcher().  These\n// approaches require more work than the MATCHER* macros, but also\n// give you more control on the types of the value being matched and\n// the matcher parameters, which may leads to better compiler error\n// messages when the matcher is used wrong.  They also allow\n// overloading matchers based on parameter types (as opposed to just\n// based on the number of parameters).\n//\n// MATCHER*() can only be used in a namespace scope as templates cannot be\n// declared inside of a local class.\n//\n// More Information\n// ================\n//\n// To learn more about using these macros, please search for 'MATCHER'\n// on\n// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md\n//\n// This file also implements some commonly used argument matchers.  More\n// matchers can be defined by the user implementing the\n// MatcherInterface<T> interface if necessary.\n//\n// See googletest/include/gtest/gtest-matchers.h for the definition of class\n// Matcher, class MatcherInterface, and others.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n\n#include <algorithm>\n#include <cmath>\n#include <exception>\n#include <functional>\n#include <initializer_list>\n#include <ios>\n#include <iterator>\n#include <limits>\n#include <memory>\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gmock/internal/gmock-pp.h\"\n#include \"gtest/gtest.h\"\n\n// MSVC warning C5046 is new as of VS2017 version 15.8.\n#if defined(_MSC_VER) && _MSC_VER >= 1915\n#define GMOCK_MAYBE_5046_ 5046\n#else\n#define GMOCK_MAYBE_5046_\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by\n                              clients of class B */\n    /* Symbol involving type with internal linkage not defined */)\n\nnamespace testing {\n\n// To implement a matcher Foo for type T, define:\n//   1. a class FooMatcherImpl that implements the\n//      MatcherInterface<T> interface, and\n//   2. a factory function that creates a Matcher<T> object from a\n//      FooMatcherImpl*.\n//\n// The two-level delegation design makes it possible to allow a user\n// to write \"v\" instead of \"Eq(v)\" where a Matcher is expected, which\n// is impossible if we pass matchers by pointers.  It also eases\n// ownership management as Matcher objects can now be copied like\n// plain values.\n\n// A match result listener that stores the explanation in a string.\nclass StringMatchResultListener : public MatchResultListener {\n public:\n  StringMatchResultListener() : MatchResultListener(&ss_) {}\n\n  // Returns the explanation accumulated so far.\n  std::string str() const { return ss_.str(); }\n\n  // Clears the explanation accumulated so far.\n  void Clear() { ss_.str(\"\"); }\n\n private:\n  ::std::stringstream ss_;\n\n  StringMatchResultListener(const StringMatchResultListener&) = delete;\n  StringMatchResultListener& operator=(const StringMatchResultListener&) =\n      delete;\n};\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// The MatcherCastImpl class template is a helper for implementing\n// MatcherCast().  We need this helper in order to partially\n// specialize the implementation of MatcherCast() (C++ allows\n// class/struct templates to be partially specialized, but not\n// function templates.).\n\n// This general version is used when MatcherCast()'s argument is a\n// polymorphic matcher (i.e. something that can be converted to a\n// Matcher but is not one yet; for example, Eq(value)) or a value (for\n// example, \"hello\").\ntemplate <typename T, typename M>\nclass MatcherCastImpl {\n public:\n  static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {\n    // M can be a polymorphic matcher, in which case we want to use\n    // its conversion operator to create Matcher<T>.  Or it can be a value\n    // that should be passed to the Matcher<T>'s constructor.\n    //\n    // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a\n    // polymorphic matcher because it'll be ambiguous if T has an implicit\n    // constructor from M (this usually happens when T has an implicit\n    // constructor from any type).\n    //\n    // It won't work to unconditionally implicit_cast\n    // polymorphic_matcher_or_value to Matcher<T> because it won't trigger\n    // a user-defined conversion from M to T if one exists (assuming M is\n    // a value).\n    return CastImpl(polymorphic_matcher_or_value,\n                    std::is_convertible<M, Matcher<T>>{},\n                    std::is_convertible<M, T>{});\n  }\n\n private:\n  template <bool Ignore>\n  static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,\n                             std::true_type /* convertible_to_matcher */,\n                             std::integral_constant<bool, Ignore>) {\n    // M is implicitly convertible to Matcher<T>, which means that either\n    // M is a polymorphic matcher or Matcher<T> has an implicit constructor\n    // from M.  In both cases using the implicit conversion will produce a\n    // matcher.\n    //\n    // Even if T has an implicit constructor from M, it won't be called because\n    // creating Matcher<T> would require a chain of two user-defined conversions\n    // (first to create T from M and then to create Matcher<T> from T).\n    return polymorphic_matcher_or_value;\n  }\n\n  // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic\n  // matcher. It's a value of a type implicitly convertible to T. Use direct\n  // initialization to create a matcher.\n  static Matcher<T> CastImpl(const M& value,\n                             std::false_type /* convertible_to_matcher */,\n                             std::true_type /* convertible_to_T */) {\n    return Matcher<T>(ImplicitCast_<T>(value));\n  }\n\n  // M can't be implicitly converted to either Matcher<T> or T. Attempt to use\n  // polymorphic matcher Eq(value) in this case.\n  //\n  // Note that we first attempt to perform an implicit cast on the value and\n  // only fall back to the polymorphic Eq() matcher afterwards because the\n  // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end\n  // which might be undefined even when Rhs is implicitly convertible to Lhs\n  // (e.g. std::pair<const int, int> vs. std::pair<int, int>).\n  //\n  // We don't define this method inline as we need the declaration of Eq().\n  static Matcher<T> CastImpl(const M& value,\n                             std::false_type /* convertible_to_matcher */,\n                             std::false_type /* convertible_to_T */);\n};\n\n// This more specialized version is used when MatcherCast()'s argument\n// is already a Matcher.  This only compiles when type T can be\n// statically converted to type U.\ntemplate <typename T, typename U>\nclass MatcherCastImpl<T, Matcher<U>> {\n public:\n  static Matcher<T> Cast(const Matcher<U>& source_matcher) {\n    return Matcher<T>(new Impl(source_matcher));\n  }\n\n private:\n  class Impl : public MatcherInterface<T> {\n   public:\n    explicit Impl(const Matcher<U>& source_matcher)\n        : source_matcher_(source_matcher) {}\n\n    // We delegate the matching logic to the source matcher.\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      using FromType = typename std::remove_cv<typename std::remove_pointer<\n          typename std::remove_reference<T>::type>::type>::type;\n      using ToType = typename std::remove_cv<typename std::remove_pointer<\n          typename std::remove_reference<U>::type>::type>::type;\n      // Do not allow implicitly converting base*/& to derived*/&.\n      static_assert(\n          // Do not trigger if only one of them is a pointer. That implies a\n          // regular conversion and not a down_cast.\n          (std::is_pointer<typename std::remove_reference<T>::type>::value !=\n           std::is_pointer<typename std::remove_reference<U>::type>::value) ||\n              std::is_same<FromType, ToType>::value ||\n              !std::is_base_of<FromType, ToType>::value,\n          \"Can't implicitly convert from <base> to <derived>\");\n\n      // Do the cast to `U` explicitly if necessary.\n      // Otherwise, let implicit conversions do the trick.\n      using CastType =\n          typename std::conditional<std::is_convertible<T&, const U&>::value,\n                                    T&, U>::type;\n\n      return source_matcher_.MatchAndExplain(static_cast<CastType>(x),\n                                             listener);\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      source_matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      source_matcher_.DescribeNegationTo(os);\n    }\n\n   private:\n    const Matcher<U> source_matcher_;\n  };\n};\n\n// This even more specialized version is used for efficiently casting\n// a matcher to its own type.\ntemplate <typename T>\nclass MatcherCastImpl<T, Matcher<T>> {\n public:\n  static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }\n};\n\n// Template specialization for parameterless Matcher.\ntemplate <typename Derived>\nclass MatcherBaseImpl {\n public:\n  MatcherBaseImpl() = default;\n\n  template <typename T>\n  operator ::testing::Matcher<T>() const {  // NOLINT(runtime/explicit)\n    return ::testing::Matcher<T>(new\n                                 typename Derived::template gmock_Impl<T>());\n  }\n};\n\n// Template specialization for Matcher with parameters.\ntemplate <template <typename...> class Derived, typename... Ts>\nclass MatcherBaseImpl<Derived<Ts...>> {\n public:\n  // Mark the constructor explicit for single argument T to avoid implicit\n  // conversions.\n  template <typename E = std::enable_if<sizeof...(Ts) == 1>,\n            typename E::type* = nullptr>\n  explicit MatcherBaseImpl(Ts... params)\n      : params_(std::forward<Ts>(params)...) {}\n  template <typename E = std::enable_if<sizeof...(Ts) != 1>,\n            typename = typename E::type>\n  MatcherBaseImpl(Ts... params)  // NOLINT\n      : params_(std::forward<Ts>(params)...) {}\n\n  template <typename F>\n  operator ::testing::Matcher<F>() const {  // NOLINT(runtime/explicit)\n    return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{});\n  }\n\n private:\n  template <typename F, std::size_t... tuple_ids>\n  ::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const {\n    return ::testing::Matcher<F>(\n        new typename Derived<Ts...>::template gmock_Impl<F>(\n            std::get<tuple_ids>(params_)...));\n  }\n\n  const std::tuple<Ts...> params_;\n};\n\n}  // namespace internal\n\n// In order to be safe and clear, casting between different matcher\n// types is done explicitly via MatcherCast<T>(m), which takes a\n// matcher m and returns a Matcher<T>.  It compiles only when T can be\n// statically converted to the argument type of m.\ntemplate <typename T, typename M>\ninline Matcher<T> MatcherCast(const M& matcher) {\n  return internal::MatcherCastImpl<T, M>::Cast(matcher);\n}\n\n// This overload handles polymorphic matchers and values only since\n// monomorphic matchers are handled by the next one.\ntemplate <typename T, typename M>\ninline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {\n  return MatcherCast<T>(polymorphic_matcher_or_value);\n}\n\n// This overload handles monomorphic matchers.\n//\n// In general, if type T can be implicitly converted to type U, we can\n// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is\n// contravariant): just keep a copy of the original Matcher<U>, convert the\n// argument from type T to U, and then pass it to the underlying Matcher<U>.\n// The only exception is when U is a reference and T is not, as the\n// underlying Matcher<U> may be interested in the argument's address, which\n// is not preserved in the conversion from T to U.\ntemplate <typename T, typename U>\ninline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {\n  // Enforce that T can be implicitly converted to U.\n  static_assert(std::is_convertible<const T&, const U&>::value,\n                \"T must be implicitly convertible to U\");\n  // Enforce that we are not converting a non-reference type T to a reference\n  // type U.\n  static_assert(std::is_reference<T>::value || !std::is_reference<U>::value,\n                \"cannot convert non reference arg to reference\");\n  // In case both T and U are arithmetic types, enforce that the\n  // conversion is not lossy.\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;\n  constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;\n  constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;\n  static_assert(\n      kTIsOther || kUIsOther ||\n          (internal::LosslessArithmeticConvertible<RawT, RawU>::value),\n      \"conversion of arithmetic types must be lossless\");\n  return MatcherCast<T>(matcher);\n}\n\n// A<T>() returns a matcher that matches any value of type T.\ntemplate <typename T>\nMatcher<T> A();\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// If the explanation is not empty, prints it to the ostream.\ninline void PrintIfNotEmpty(const std::string& explanation,\n                            ::std::ostream* os) {\n  if (!explanation.empty() && os != nullptr) {\n    *os << \", \" << explanation;\n  }\n}\n\n// Returns true if the given type name is easy to read by a human.\n// This is used to decide whether printing the type of a value might\n// be helpful.\ninline bool IsReadableTypeName(const std::string& type_name) {\n  // We consider a type name readable if it's short or doesn't contain\n  // a template or function type.\n  return (type_name.length() <= 20 ||\n          type_name.find_first_of(\"<(\") == std::string::npos);\n}\n\n// Matches the value against the given matcher, prints the value and explains\n// the match result to the listener. Returns the match result.\n// 'listener' must not be NULL.\n// Value cannot be passed by const reference, because some matchers take a\n// non-const argument.\ntemplate <typename Value, typename T>\nbool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,\n                          MatchResultListener* listener) {\n  if (!listener->IsInterested()) {\n    // If the listener is not interested, we do not need to construct the\n    // inner explanation.\n    return matcher.Matches(value);\n  }\n\n  StringMatchResultListener inner_listener;\n  const bool match = matcher.MatchAndExplain(value, &inner_listener);\n\n  UniversalPrint(value, listener->stream());\n#if GTEST_HAS_RTTI\n  const std::string& type_name = GetTypeName<Value>();\n  if (IsReadableTypeName(type_name))\n    *listener->stream() << \" (of type \" << type_name << \")\";\n#endif\n  PrintIfNotEmpty(inner_listener.str(), listener->stream());\n\n  return match;\n}\n\n// An internal helper class for doing compile-time loop on a tuple's\n// fields.\ntemplate <size_t N>\nclass TuplePrefix {\n public:\n  // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true\n  // if and only if the first N fields of matcher_tuple matches\n  // the first N fields of value_tuple, respectively.\n  template <typename MatcherTuple, typename ValueTuple>\n  static bool Matches(const MatcherTuple& matcher_tuple,\n                      const ValueTuple& value_tuple) {\n    return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) &&\n           std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple));\n  }\n\n  // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os)\n  // describes failures in matching the first N fields of matchers\n  // against the first N fields of values.  If there is no failure,\n  // nothing will be streamed to os.\n  template <typename MatcherTuple, typename ValueTuple>\n  static void ExplainMatchFailuresTo(const MatcherTuple& matchers,\n                                     const ValueTuple& values,\n                                     ::std::ostream* os) {\n    // First, describes failures in the first N - 1 fields.\n    TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);\n\n    // Then describes the failure (if any) in the (N - 1)-th (0-based)\n    // field.\n    typename std::tuple_element<N - 1, MatcherTuple>::type matcher =\n        std::get<N - 1>(matchers);\n    typedef typename std::tuple_element<N - 1, ValueTuple>::type Value;\n    const Value& value = std::get<N - 1>(values);\n    StringMatchResultListener listener;\n    if (!matcher.MatchAndExplain(value, &listener)) {\n      *os << \"  Expected arg #\" << N - 1 << \": \";\n      std::get<N - 1>(matchers).DescribeTo(os);\n      *os << \"\\n           Actual: \";\n      // We remove the reference in type Value to prevent the\n      // universal printer from printing the address of value, which\n      // isn't interesting to the user most of the time.  The\n      // matcher's MatchAndExplain() method handles the case when\n      // the address is interesting.\n      internal::UniversalPrint(value, os);\n      PrintIfNotEmpty(listener.str(), os);\n      *os << \"\\n\";\n    }\n  }\n};\n\n// The base case.\ntemplate <>\nclass TuplePrefix<0> {\n public:\n  template <typename MatcherTuple, typename ValueTuple>\n  static bool Matches(const MatcherTuple& /* matcher_tuple */,\n                      const ValueTuple& /* value_tuple */) {\n    return true;\n  }\n\n  template <typename MatcherTuple, typename ValueTuple>\n  static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */,\n                                     const ValueTuple& /* values */,\n                                     ::std::ostream* /* os */) {}\n};\n\n// TupleMatches(matcher_tuple, value_tuple) returns true if and only if\n// all matchers in matcher_tuple match the corresponding fields in\n// value_tuple.  It is a compiler error if matcher_tuple and\n// value_tuple have different number of fields or incompatible field\n// types.\ntemplate <typename MatcherTuple, typename ValueTuple>\nbool TupleMatches(const MatcherTuple& matcher_tuple,\n                  const ValueTuple& value_tuple) {\n  // Makes sure that matcher_tuple and value_tuple have the same\n  // number of fields.\n  static_assert(std::tuple_size<MatcherTuple>::value ==\n                    std::tuple_size<ValueTuple>::value,\n                \"matcher and value have different numbers of fields\");\n  return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple,\n                                                                  value_tuple);\n}\n\n// Describes failures in matching matchers against values.  If there\n// is no failure, nothing will be streamed to os.\ntemplate <typename MatcherTuple, typename ValueTuple>\nvoid ExplainMatchFailureTupleTo(const MatcherTuple& matchers,\n                                const ValueTuple& values, ::std::ostream* os) {\n  TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(\n      matchers, values, os);\n}\n\n// TransformTupleValues and its helper.\n//\n// TransformTupleValuesHelper hides the internal machinery that\n// TransformTupleValues uses to implement a tuple traversal.\ntemplate <typename Tuple, typename Func, typename OutIter>\nclass TransformTupleValuesHelper {\n private:\n  typedef ::std::tuple_size<Tuple> TupleSize;\n\n public:\n  // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'.\n  // Returns the final value of 'out' in case the caller needs it.\n  static OutIter Run(Func f, const Tuple& t, OutIter out) {\n    return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out);\n  }\n\n private:\n  template <typename Tup, size_t kRemainingSize>\n  struct IterateOverTuple {\n    OutIter operator()(Func f, const Tup& t, OutIter out) const {\n      *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t));\n      return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);\n    }\n  };\n  template <typename Tup>\n  struct IterateOverTuple<Tup, 0> {\n    OutIter operator()(Func /* f */, const Tup& /* t */, OutIter out) const {\n      return out;\n    }\n  };\n};\n\n// Successively invokes 'f(element)' on each element of the tuple 't',\n// appending each result to the 'out' iterator. Returns the final value\n// of 'out'.\ntemplate <typename Tuple, typename Func, typename OutIter>\nOutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {\n  return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);\n}\n\n// Implements _, a matcher that matches any value of any\n// type.  This is a polymorphic matcher, so we need a template type\n// conversion operator to make it appearing as a Matcher<T> for any\n// type T.\nclass AnythingMatcher {\n public:\n  using is_gtest_matcher = void;\n\n  template <typename T>\n  bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {\n    return true;\n  }\n  void DescribeTo(std::ostream* os) const { *os << \"is anything\"; }\n  void DescribeNegationTo(::std::ostream* os) const {\n    // This is mostly for completeness' sake, as it's not very useful\n    // to write Not(A<bool>()).  However we cannot completely rule out\n    // such a possibility, and it doesn't hurt to be prepared.\n    *os << \"never matches\";\n  }\n};\n\n// Implements the polymorphic IsNull() matcher, which matches any raw or smart\n// pointer that is NULL.\nclass IsNullMatcher {\n public:\n  template <typename Pointer>\n  bool MatchAndExplain(const Pointer& p,\n                       MatchResultListener* /* listener */) const {\n    return p == nullptr;\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"is NULL\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"isn't NULL\"; }\n};\n\n// Implements the polymorphic NotNull() matcher, which matches any raw or smart\n// pointer that is not NULL.\nclass NotNullMatcher {\n public:\n  template <typename Pointer>\n  bool MatchAndExplain(const Pointer& p,\n                       MatchResultListener* /* listener */) const {\n    return p != nullptr;\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"isn't NULL\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"is NULL\"; }\n};\n\n// Ref(variable) matches any argument that is a reference to\n// 'variable'.  This matcher is polymorphic as it can match any\n// super type of the type of 'variable'.\n//\n// The RefMatcher template class implements Ref(variable).  It can\n// only be instantiated with a reference type.  This prevents a user\n// from mistakenly using Ref(x) to match a non-reference function\n// argument.  For example, the following will righteously cause a\n// compiler error:\n//\n//   int n;\n//   Matcher<int> m1 = Ref(n);   // This won't compile.\n//   Matcher<int&> m2 = Ref(n);  // This will compile.\ntemplate <typename T>\nclass RefMatcher;\n\ntemplate <typename T>\nclass RefMatcher<T&> {\n  // Google Mock is a generic framework and thus needs to support\n  // mocking any function types, including those that take non-const\n  // reference arguments.  Therefore the template parameter T (and\n  // Super below) can be instantiated to either a const type or a\n  // non-const type.\n public:\n  // RefMatcher() takes a T& instead of const T&, as we want the\n  // compiler to catch using Ref(const_value) as a matcher for a\n  // non-const reference.\n  explicit RefMatcher(T& x) : object_(x) {}  // NOLINT\n\n  template <typename Super>\n  operator Matcher<Super&>() const {\n    // By passing object_ (type T&) to Impl(), which expects a Super&,\n    // we make sure that Super is a super type of T.  In particular,\n    // this catches using Ref(const_value) as a matcher for a\n    // non-const reference, as you cannot implicitly convert a const\n    // reference to a non-const reference.\n    return MakeMatcher(new Impl<Super>(object_));\n  }\n\n private:\n  template <typename Super>\n  class Impl : public MatcherInterface<Super&> {\n   public:\n    explicit Impl(Super& x) : object_(x) {}  // NOLINT\n\n    // MatchAndExplain() takes a Super& (as opposed to const Super&)\n    // in order to match the interface MatcherInterface<Super&>.\n    bool MatchAndExplain(Super& x,\n                         MatchResultListener* listener) const override {\n      *listener << \"which is located @\" << static_cast<const void*>(&x);\n      return &x == &object_;\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"references the variable \";\n      UniversalPrinter<Super&>::Print(object_, os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not reference the variable \";\n      UniversalPrinter<Super&>::Print(object_, os);\n    }\n\n   private:\n    const Super& object_;\n  };\n\n  T& object_;\n};\n\n// Polymorphic helper functions for narrow and wide string matchers.\ninline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {\n  return String::CaseInsensitiveCStringEquals(lhs, rhs);\n}\n\ninline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,\n                                         const wchar_t* rhs) {\n  return String::CaseInsensitiveWideCStringEquals(lhs, rhs);\n}\n\n// String comparison for narrow or wide strings that can have embedded NUL\n// characters.\ntemplate <typename StringType>\nbool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) {\n  // Are the heads equal?\n  if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {\n    return false;\n  }\n\n  // Skip the equal heads.\n  const typename StringType::value_type nul = 0;\n  const size_t i1 = s1.find(nul), i2 = s2.find(nul);\n\n  // Are we at the end of either s1 or s2?\n  if (i1 == StringType::npos || i2 == StringType::npos) {\n    return i1 == i2;\n  }\n\n  // Are the tails equal?\n  return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));\n}\n\n// String matchers.\n\n// Implements equality-based string matchers like StrEq, StrCaseNe, and etc.\ntemplate <typename StringType>\nclass StrEqualityMatcher {\n public:\n  StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)\n      : string_(std::move(str)),\n        expect_eq_(expect_eq),\n        case_sensitive_(case_sensitive) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    if (s == nullptr) {\n      return !expect_eq_;\n    }\n    return MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    const bool eq = case_sensitive_ ? s2 == string_\n                                    : CaseInsensitiveStringEquals(s2, string_);\n    return expect_eq_ == eq;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    DescribeToHelper(expect_eq_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    DescribeToHelper(!expect_eq_, os);\n  }\n\n private:\n  void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {\n    *os << (expect_eq ? \"is \" : \"isn't \");\n    *os << \"equal to \";\n    if (!case_sensitive_) {\n      *os << \"(ignoring case) \";\n    }\n    UniversalPrint(string_, os);\n  }\n\n  const StringType string_;\n  const bool expect_eq_;\n  const bool case_sensitive_;\n};\n\n// Implements the polymorphic HasSubstr(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass HasSubstrMatcher {\n public:\n  explicit HasSubstrMatcher(const StringType& substring)\n      : substring_(substring) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    return StringType(s).find(substring_) != StringType::npos;\n  }\n\n  // Describes what this matcher matches.\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"has substring \";\n    UniversalPrint(substring_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"has no substring \";\n    UniversalPrint(substring_, os);\n  }\n\n private:\n  const StringType substring_;\n};\n\n// Implements the polymorphic StartsWith(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass StartsWithMatcher {\n public:\n  explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    return s2.length() >= prefix_.length() &&\n           s2.substr(0, prefix_.length()) == prefix_;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"starts with \";\n    UniversalPrint(prefix_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't start with \";\n    UniversalPrint(prefix_, os);\n  }\n\n private:\n  const StringType prefix_;\n};\n\n// Implements the polymorphic EndsWith(substring) matcher, which\n// can be used as a Matcher<T> as long as T can be converted to a\n// string.\ntemplate <typename StringType>\nclass EndsWithMatcher {\n public:\n  explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    // This should fail to compile if StringView is used with wide\n    // strings.\n    const StringType& str = std::string(s);\n    return MatchAndExplain(str, listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(StringType(s), listener);\n  }\n\n  // Matches anything that can convert to StringType.\n  //\n  // This is a template, not just a plain function with const StringType&,\n  // because StringView has some interfering non-explicit constructors.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const StringType s2(s);\n    return s2.length() >= suffix_.length() &&\n           s2.substr(s2.length() - suffix_.length()) == suffix_;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"ends with \";\n    UniversalPrint(suffix_, os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't end with \";\n    UniversalPrint(suffix_, os);\n  }\n\n private:\n  const StringType suffix_;\n};\n\n// Implements the polymorphic WhenBase64Unescaped(matcher) matcher, which can be\n// used as a Matcher<T> as long as T can be converted to a string.\nclass WhenBase64UnescapedMatcher {\n public:\n  using is_gtest_matcher = void;\n\n  explicit WhenBase64UnescapedMatcher(\n      const Matcher<const std::string&>& internal_matcher)\n      : internal_matcher_(internal_matcher) {}\n\n  // Matches anything that can convert to std::string.\n  template <typename MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* listener) const {\n    const std::string s2(s);  // NOLINT (needed for working with string_view).\n    std::string unescaped;\n    if (!internal::Base64Unescape(s2, &unescaped)) {\n      if (listener != nullptr) {\n        *listener << \"is not a valid base64 escaped string\";\n      }\n      return false;\n    }\n    return MatchPrintAndExplain(unescaped, internal_matcher_, listener);\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"matches after Base64Unescape \";\n    internal_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"does not match after Base64Unescape \";\n    internal_matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<const std::string&> internal_matcher_;\n};\n\n// Implements a matcher that compares the two fields of a 2-tuple\n// using one of the ==, <=, <, etc, operators.  The two fields being\n// compared don't have to have the same type.\n//\n// The matcher defined here is polymorphic (for example, Eq() can be\n// used to match a std::tuple<int, short>, a std::tuple<const long&, double>,\n// etc).  Therefore we use a template type conversion operator in the\n// implementation.\ntemplate <typename D, typename Op>\nclass PairMatchBase {\n public:\n  template <typename T1, typename T2>\n  operator Matcher<::std::tuple<T1, T2>>() const {\n    return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);\n  }\n  template <typename T1, typename T2>\n  operator Matcher<const ::std::tuple<T1, T2>&>() const {\n    return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>);\n  }\n\n private:\n  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT\n    return os << D::Desc();\n  }\n\n  template <typename Tuple>\n  class Impl : public MatcherInterface<Tuple> {\n   public:\n    bool MatchAndExplain(Tuple args,\n                         MatchResultListener* /* listener */) const override {\n      return Op()(::std::get<0>(args), ::std::get<1>(args));\n    }\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"are \" << GetDesc;\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"aren't \" << GetDesc;\n    }\n  };\n};\n\nclass Eq2Matcher : public PairMatchBase<Eq2Matcher, std::equal_to<>> {\n public:\n  static const char* Desc() { return \"an equal pair\"; }\n};\nclass Ne2Matcher : public PairMatchBase<Ne2Matcher, std::not_equal_to<>> {\n public:\n  static const char* Desc() { return \"an unequal pair\"; }\n};\nclass Lt2Matcher : public PairMatchBase<Lt2Matcher, std::less<>> {\n public:\n  static const char* Desc() { return \"a pair where the first < the second\"; }\n};\nclass Gt2Matcher : public PairMatchBase<Gt2Matcher, std::greater<>> {\n public:\n  static const char* Desc() { return \"a pair where the first > the second\"; }\n};\nclass Le2Matcher : public PairMatchBase<Le2Matcher, std::less_equal<>> {\n public:\n  static const char* Desc() { return \"a pair where the first <= the second\"; }\n};\nclass Ge2Matcher : public PairMatchBase<Ge2Matcher, std::greater_equal<>> {\n public:\n  static const char* Desc() { return \"a pair where the first >= the second\"; }\n};\n\n// Implements the Not(...) matcher for a particular argument type T.\n// We do not nest it inside the NotMatcher class template, as that\n// will prevent different instantiations of NotMatcher from sharing\n// the same NotMatcherImpl<T> class.\ntemplate <typename T>\nclass NotMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {}\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    return !matcher_.MatchAndExplain(x, listener);\n  }\n\n  void DescribeTo(::std::ostream* os) const override {\n    matcher_.DescribeNegationTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<T> matcher_;\n};\n\n// Implements the Not(m) matcher, which matches a value that doesn't\n// match matcher m.\ntemplate <typename InnerMatcher>\nclass NotMatcher {\n public:\n  explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}\n\n  // This template type conversion operator allows Not(m) to be used\n  // to match any type m can match.\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));\n  }\n\n private:\n  InnerMatcher matcher_;\n};\n\n// Implements the AllOf(m1, m2) matcher for a particular argument type\n// T. We do not nest it inside the BothOfMatcher class template, as\n// that will prevent different instantiations of BothOfMatcher from\n// sharing the same BothOfMatcherImpl<T> class.\ntemplate <typename T>\nclass AllOfMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit AllOfMatcherImpl(std::vector<Matcher<T>> matchers)\n      : matchers_(std::move(matchers)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") and (\";\n      matchers_[i].DescribeTo(os);\n    }\n    *os << \")\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") or (\";\n      matchers_[i].DescribeNegationTo(os);\n    }\n    *os << \")\";\n  }\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    // If either matcher1_ or matcher2_ doesn't match x, we only need\n    // to explain why one of them fails.\n    std::string all_match_result;\n\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      StringMatchResultListener slistener;\n      if (matchers_[i].MatchAndExplain(x, &slistener)) {\n        if (all_match_result.empty()) {\n          all_match_result = slistener.str();\n        } else {\n          std::string result = slistener.str();\n          if (!result.empty()) {\n            all_match_result += \", and \";\n            all_match_result += result;\n          }\n        }\n      } else {\n        *listener << slistener.str();\n        return false;\n      }\n    }\n\n    // Otherwise we need to explain why *both* of them match.\n    *listener << all_match_result;\n    return true;\n  }\n\n private:\n  const std::vector<Matcher<T>> matchers_;\n};\n\n// VariadicMatcher is used for the variadic implementation of\n// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).\n// CombiningMatcher<T> is used to recursively combine the provided matchers\n// (of type Args...).\ntemplate <template <typename T> class CombiningMatcher, typename... Args>\nclass VariadicMatcher {\n public:\n  VariadicMatcher(const Args&... matchers)  // NOLINT\n      : matchers_(matchers...) {\n    static_assert(sizeof...(Args) > 0, \"Must have at least one matcher.\");\n  }\n\n  VariadicMatcher(const VariadicMatcher&) = default;\n  VariadicMatcher& operator=(const VariadicMatcher&) = delete;\n\n  // This template type conversion operator allows an\n  // VariadicMatcher<Matcher1, Matcher2...> object to match any type that\n  // all of the provided matchers (Matcher1, Matcher2, ...) can match.\n  template <typename T>\n  operator Matcher<T>() const {\n    std::vector<Matcher<T>> values;\n    CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());\n    return Matcher<T>(new CombiningMatcher<T>(std::move(values)));\n  }\n\n private:\n  template <typename T, size_t I>\n  void CreateVariadicMatcher(std::vector<Matcher<T>>* values,\n                             std::integral_constant<size_t, I>) const {\n    values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));\n    CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());\n  }\n\n  template <typename T>\n  void CreateVariadicMatcher(\n      std::vector<Matcher<T>>*,\n      std::integral_constant<size_t, sizeof...(Args)>) const {}\n\n  std::tuple<Args...> matchers_;\n};\n\ntemplate <typename... Args>\nusing AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;\n\n// Implements the AnyOf(m1, m2) matcher for a particular argument type\n// T.  We do not nest it inside the AnyOfMatcher class template, as\n// that will prevent different instantiations of AnyOfMatcher from\n// sharing the same EitherOfMatcherImpl<T> class.\ntemplate <typename T>\nclass AnyOfMatcherImpl : public MatcherInterface<const T&> {\n public:\n  explicit AnyOfMatcherImpl(std::vector<Matcher<T>> matchers)\n      : matchers_(std::move(matchers)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") or (\";\n      matchers_[i].DescribeTo(os);\n    }\n    *os << \")\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"(\";\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      if (i != 0) *os << \") and (\";\n      matchers_[i].DescribeNegationTo(os);\n    }\n    *os << \")\";\n  }\n\n  bool MatchAndExplain(const T& x,\n                       MatchResultListener* listener) const override {\n    std::string no_match_result;\n\n    // If either matcher1_ or matcher2_ matches x, we just need to\n    // explain why *one* of them matches.\n    for (size_t i = 0; i < matchers_.size(); ++i) {\n      StringMatchResultListener slistener;\n      if (matchers_[i].MatchAndExplain(x, &slistener)) {\n        *listener << slistener.str();\n        return true;\n      } else {\n        if (no_match_result.empty()) {\n          no_match_result = slistener.str();\n        } else {\n          std::string result = slistener.str();\n          if (!result.empty()) {\n            no_match_result += \", and \";\n            no_match_result += result;\n          }\n        }\n      }\n    }\n\n    // Otherwise we need to explain why *both* of them fail.\n    *listener << no_match_result;\n    return false;\n  }\n\n private:\n  const std::vector<Matcher<T>> matchers_;\n};\n\n// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).\ntemplate <typename... Args>\nusing AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;\n\n// ConditionalMatcher is the implementation of Conditional(cond, m1, m2)\ntemplate <typename MatcherTrue, typename MatcherFalse>\nclass ConditionalMatcher {\n public:\n  ConditionalMatcher(bool condition, MatcherTrue matcher_true,\n                     MatcherFalse matcher_false)\n      : condition_(condition),\n        matcher_true_(std::move(matcher_true)),\n        matcher_false_(std::move(matcher_false)) {}\n\n  template <typename T>\n  operator Matcher<T>() const {  // NOLINT(runtime/explicit)\n    return condition_ ? SafeMatcherCast<T>(matcher_true_)\n                      : SafeMatcherCast<T>(matcher_false_);\n  }\n\n private:\n  bool condition_;\n  MatcherTrue matcher_true_;\n  MatcherFalse matcher_false_;\n};\n\n// Wrapper for implementation of Any/AllOfArray().\ntemplate <template <class> class MatcherImpl, typename T>\nclass SomeOfArrayMatcher {\n public:\n  // Constructs the matcher from a sequence of element values or\n  // element matchers.\n  template <typename Iter>\n  SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}\n\n  template <typename U>\n  operator Matcher<U>() const {  // NOLINT\n    using RawU = typename std::decay<U>::type;\n    std::vector<Matcher<RawU>> matchers;\n    matchers.reserve(matchers_.size());\n    for (const auto& matcher : matchers_) {\n      matchers.push_back(MatcherCast<RawU>(matcher));\n    }\n    return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));\n  }\n\n private:\n  const ::std::vector<T> matchers_;\n};\n\ntemplate <typename T>\nusing AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;\n\ntemplate <typename T>\nusing AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;\n\n// Used for implementing Truly(pred), which turns a predicate into a\n// matcher.\ntemplate <typename Predicate>\nclass TrulyMatcher {\n public:\n  explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}\n\n  // This method template allows Truly(pred) to be used as a matcher\n  // for type T where T is the argument type of predicate 'pred'.  The\n  // argument is passed by reference as the predicate may be\n  // interested in the address of the argument.\n  template <typename T>\n  bool MatchAndExplain(T& x,  // NOLINT\n                       MatchResultListener* listener) const {\n    // Without the if-statement, MSVC sometimes warns about converting\n    // a value to bool (warning 4800).\n    //\n    // We cannot write 'return !!predicate_(x);' as that doesn't work\n    // when predicate_(x) returns a class convertible to bool but\n    // having no operator!().\n    if (predicate_(x)) return true;\n    *listener << \"didn't satisfy the given predicate\";\n    return false;\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"satisfies the given predicate\";\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't satisfy the given predicate\";\n  }\n\n private:\n  Predicate predicate_;\n};\n\n// Used for implementing Matches(matcher), which turns a matcher into\n// a predicate.\ntemplate <typename M>\nclass MatcherAsPredicate {\n public:\n  explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}\n\n  // This template operator() allows Matches(m) to be used as a\n  // predicate on type T where m is a matcher on type T.\n  //\n  // The argument x is passed by reference instead of by value, as\n  // some matcher may be interested in its address (e.g. as in\n  // Matches(Ref(n))(x)).\n  template <typename T>\n  bool operator()(const T& x) const {\n    // We let matcher_ commit to a particular type here instead of\n    // when the MatcherAsPredicate object was constructed.  This\n    // allows us to write Matches(m) where m is a polymorphic matcher\n    // (e.g. Eq(5)).\n    //\n    // If we write Matcher<T>(matcher_).Matches(x) here, it won't\n    // compile when matcher_ has type Matcher<const T&>; if we write\n    // Matcher<const T&>(matcher_).Matches(x) here, it won't compile\n    // when matcher_ has type Matcher<T>; if we just write\n    // matcher_.Matches(x), it won't compile when matcher_ is\n    // polymorphic, e.g. Eq(5).\n    //\n    // MatcherCast<const T&>() is necessary for making the code work\n    // in all of the above situations.\n    return MatcherCast<const T&>(matcher_).Matches(x);\n  }\n\n private:\n  M matcher_;\n};\n\n// For implementing ASSERT_THAT() and EXPECT_THAT().  The template\n// argument M must be a type that can be converted to a matcher.\ntemplate <typename M>\nclass PredicateFormatterFromMatcher {\n public:\n  explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}\n\n  // This template () operator allows a PredicateFormatterFromMatcher\n  // object to act as a predicate-formatter suitable for using with\n  // Google Test's EXPECT_PRED_FORMAT1() macro.\n  template <typename T>\n  AssertionResult operator()(const char* value_text, const T& x) const {\n    // We convert matcher_ to a Matcher<const T&> *now* instead of\n    // when the PredicateFormatterFromMatcher object was constructed,\n    // as matcher_ may be polymorphic (e.g. NotNull()) and we won't\n    // know which type to instantiate it to until we actually see the\n    // type of x here.\n    //\n    // We write SafeMatcherCast<const T&>(matcher_) instead of\n    // Matcher<const T&>(matcher_), as the latter won't compile when\n    // matcher_ has type Matcher<T> (e.g. An<int>()).\n    // We don't write MatcherCast<const T&> either, as that allows\n    // potentially unsafe downcasting of the matcher argument.\n    const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);\n\n    // The expected path here is that the matcher should match (i.e. that most\n    // tests pass) so optimize for this case.\n    if (matcher.Matches(x)) {\n      return AssertionSuccess();\n    }\n\n    ::std::stringstream ss;\n    ss << \"Value of: \" << value_text << \"\\n\"\n       << \"Expected: \";\n    matcher.DescribeTo(&ss);\n\n    // Rerun the matcher to \"PrintAndExplain\" the failure.\n    StringMatchResultListener listener;\n    if (MatchPrintAndExplain(x, matcher, &listener)) {\n      ss << \"\\n  The matcher failed on the initial attempt; but passed when \"\n            \"rerun to generate the explanation.\";\n    }\n    ss << \"\\n  Actual: \" << listener.str();\n    return AssertionFailure() << ss.str();\n  }\n\n private:\n  const M matcher_;\n};\n\n// A helper function for converting a matcher to a predicate-formatter\n// without the user needing to explicitly write the type.  This is\n// used for implementing ASSERT_THAT() and EXPECT_THAT().\n// Implementation detail: 'matcher' is received by-value to force decaying.\ntemplate <typename M>\ninline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher(\n    M matcher) {\n  return PredicateFormatterFromMatcher<M>(std::move(matcher));\n}\n\n// Implements the polymorphic IsNan() matcher, which matches any floating type\n// value that is Nan.\nclass IsNanMatcher {\n public:\n  template <typename FloatType>\n  bool MatchAndExplain(const FloatType& f,\n                       MatchResultListener* /* listener */) const {\n    return (::std::isnan)(f);\n  }\n\n  void DescribeTo(::std::ostream* os) const { *os << \"is NaN\"; }\n  void DescribeNegationTo(::std::ostream* os) const { *os << \"isn't NaN\"; }\n};\n\n// Implements the polymorphic floating point equality matcher, which matches\n// two float values using ULP-based approximation or, optionally, a\n// user-specified epsilon.  The template is meant to be instantiated with\n// FloatType being either float or double.\ntemplate <typename FloatType>\nclass FloatingEqMatcher {\n public:\n  // Constructor for FloatingEqMatcher.\n  // The matcher's input will be compared with expected.  The matcher treats two\n  // NANs as equal if nan_eq_nan is true.  Otherwise, under IEEE standards,\n  // equality comparisons between NANs will always return false.  We specify a\n  // negative max_abs_error_ term to indicate that ULP-based approximation will\n  // be used for comparison.\n  FloatingEqMatcher(FloatType expected, bool nan_eq_nan)\n      : expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {}\n\n  // Constructor that supports a user-specified max_abs_error that will be used\n  // for comparison instead of ULP-based approximation.  The max absolute\n  // should be non-negative.\n  FloatingEqMatcher(FloatType expected, bool nan_eq_nan,\n                    FloatType max_abs_error)\n      : expected_(expected),\n        nan_eq_nan_(nan_eq_nan),\n        max_abs_error_(max_abs_error) {\n    GTEST_CHECK_(max_abs_error >= 0)\n        << \", where max_abs_error is\" << max_abs_error;\n  }\n\n  // Implements floating point equality matcher as a Matcher<T>.\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n   public:\n    Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error)\n        : expected_(expected),\n          nan_eq_nan_(nan_eq_nan),\n          max_abs_error_(max_abs_error) {}\n\n    bool MatchAndExplain(T value,\n                         MatchResultListener* listener) const override {\n      const FloatingPoint<FloatType> actual(value), expected(expected_);\n\n      // Compares NaNs first, if nan_eq_nan_ is true.\n      if (actual.is_nan() || expected.is_nan()) {\n        if (actual.is_nan() && expected.is_nan()) {\n          return nan_eq_nan_;\n        }\n        // One is nan; the other is not nan.\n        return false;\n      }\n      if (HasMaxAbsError()) {\n        // We perform an equality check so that inf will match inf, regardless\n        // of error bounds.  If the result of value - expected_ would result in\n        // overflow or if either value is inf, the default result is infinity,\n        // which should only match if max_abs_error_ is also infinity.\n        if (value == expected_) {\n          return true;\n        }\n\n        const FloatType diff = value - expected_;\n        if (::std::fabs(diff) <= max_abs_error_) {\n          return true;\n        }\n\n        if (listener->IsInterested()) {\n          *listener << \"which is \" << diff << \" from \" << expected_;\n        }\n        return false;\n      } else {\n        return actual.AlmostEquals(expected);\n      }\n    }\n\n    void DescribeTo(::std::ostream* os) const override {\n      // os->precision() returns the previously set precision, which we\n      // store to restore the ostream to its original configuration\n      // after outputting.\n      const ::std::streamsize old_precision =\n          os->precision(::std::numeric_limits<FloatType>::digits10 + 2);\n      if (FloatingPoint<FloatType>(expected_).is_nan()) {\n        if (nan_eq_nan_) {\n          *os << \"is NaN\";\n        } else {\n          *os << \"never matches\";\n        }\n      } else {\n        *os << \"is approximately \" << expected_;\n        if (HasMaxAbsError()) {\n          *os << \" (absolute error <= \" << max_abs_error_ << \")\";\n        }\n      }\n      os->precision(old_precision);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      // As before, get original precision.\n      const ::std::streamsize old_precision =\n          os->precision(::std::numeric_limits<FloatType>::digits10 + 2);\n      if (FloatingPoint<FloatType>(expected_).is_nan()) {\n        if (nan_eq_nan_) {\n          *os << \"isn't NaN\";\n        } else {\n          *os << \"is anything\";\n        }\n      } else {\n        *os << \"isn't approximately \" << expected_;\n        if (HasMaxAbsError()) {\n          *os << \" (absolute error > \" << max_abs_error_ << \")\";\n        }\n      }\n      // Restore original precision.\n      os->precision(old_precision);\n    }\n\n   private:\n    bool HasMaxAbsError() const { return max_abs_error_ >= 0; }\n\n    const FloatType expected_;\n    const bool nan_eq_nan_;\n    // max_abs_error will be used for value comparison when >= 0.\n    const FloatType max_abs_error_;\n  };\n\n  // The following 3 type conversion operators allow FloatEq(expected) and\n  // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a\n  // Matcher<const float&>, or a Matcher<float&>, but nothing else.\n  operator Matcher<FloatType>() const {\n    return MakeMatcher(\n        new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n  operator Matcher<const FloatType&>() const {\n    return MakeMatcher(\n        new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n  operator Matcher<FloatType&>() const {\n    return MakeMatcher(\n        new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));\n  }\n\n private:\n  const FloatType expected_;\n  const bool nan_eq_nan_;\n  // max_abs_error will be used for value comparison when >= 0.\n  const FloatType max_abs_error_;\n};\n\n// A 2-tuple (\"binary\") wrapper around FloatingEqMatcher:\n// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)\n// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)\n// against y. The former implements \"Eq\", the latter \"Near\". At present, there\n// is no version that compares NaNs as equal.\ntemplate <typename FloatType>\nclass FloatingEq2Matcher {\n public:\n  FloatingEq2Matcher() { Init(-1, false); }\n\n  explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }\n\n  explicit FloatingEq2Matcher(FloatType max_abs_error) {\n    Init(max_abs_error, false);\n  }\n\n  FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {\n    Init(max_abs_error, nan_eq_nan);\n  }\n\n  template <typename T1, typename T2>\n  operator Matcher<::std::tuple<T1, T2>>() const {\n    return MakeMatcher(\n        new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_));\n  }\n  template <typename T1, typename T2>\n  operator Matcher<const ::std::tuple<T1, T2>&>() const {\n    return MakeMatcher(\n        new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));\n  }\n\n private:\n  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT\n    return os << \"an almost-equal pair\";\n  }\n\n  template <typename Tuple>\n  class Impl : public MatcherInterface<Tuple> {\n   public:\n    Impl(FloatType max_abs_error, bool nan_eq_nan)\n        : max_abs_error_(max_abs_error), nan_eq_nan_(nan_eq_nan) {}\n\n    bool MatchAndExplain(Tuple args,\n                         MatchResultListener* listener) const override {\n      if (max_abs_error_ == -1) {\n        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_);\n        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(\n            ::std::get<1>(args), listener);\n      } else {\n        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_,\n                                        max_abs_error_);\n        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(\n            ::std::get<1>(args), listener);\n      }\n    }\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"are \" << GetDesc;\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"aren't \" << GetDesc;\n    }\n\n   private:\n    FloatType max_abs_error_;\n    const bool nan_eq_nan_;\n  };\n\n  void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {\n    max_abs_error_ = max_abs_error_val;\n    nan_eq_nan_ = nan_eq_nan_val;\n  }\n  FloatType max_abs_error_;\n  bool nan_eq_nan_;\n};\n\n// Implements the Pointee(m) matcher for matching a pointer whose\n// pointee matches matcher m.  The pointer can be either raw or smart.\ntemplate <typename InnerMatcher>\nclass PointeeMatcher {\n public:\n  explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}\n\n  // This type conversion operator template allows Pointee(m) to be\n  // used as a matcher for any pointer type whose pointee type is\n  // compatible with the inner matcher, where type Pointer can be\n  // either a raw pointer or a smart pointer.\n  //\n  // The reason we do this instead of relying on\n  // MakePolymorphicMatcher() is that the latter is not flexible\n  // enough for implementing the DescribeTo() method of Pointee().\n  template <typename Pointer>\n  operator Matcher<Pointer>() const {\n    return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular pointer type.\n  template <typename Pointer>\n  class Impl : public MatcherInterface<Pointer> {\n   public:\n    using Pointee =\n        typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(\n            Pointer)>::element_type;\n\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<const Pointee&>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"points to a value that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not point to a value that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(Pointer pointer,\n                         MatchResultListener* listener) const override {\n      if (GetRawPointer(pointer) == nullptr) return false;\n\n      *listener << \"which points to \";\n      return MatchPrintAndExplain(*pointer, matcher_, listener);\n    }\n\n   private:\n    const Matcher<const Pointee&> matcher_;\n  };\n\n  const InnerMatcher matcher_;\n};\n\n// Implements the Pointer(m) matcher\n// Implements the Pointer(m) matcher for matching a pointer that matches matcher\n// m.  The pointer can be either raw or smart, and will match `m` against the\n// raw pointer.\ntemplate <typename InnerMatcher>\nclass PointerMatcher {\n public:\n  explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}\n\n  // This type conversion operator template allows Pointer(m) to be\n  // used as a matcher for any pointer type whose pointer type is\n  // compatible with the inner matcher, where type PointerType can be\n  // either a raw pointer or a smart pointer.\n  //\n  // The reason we do this instead of relying on\n  // MakePolymorphicMatcher() is that the latter is not flexible\n  // enough for implementing the DescribeTo() method of Pointer().\n  template <typename PointerType>\n  operator Matcher<PointerType>() const {  // NOLINT\n    return Matcher<PointerType>(new Impl<const PointerType&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular pointer type.\n  template <typename PointerType>\n  class Impl : public MatcherInterface<PointerType> {\n   public:\n    using Pointer =\n        const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(\n            PointerType)>::element_type*;\n\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<Pointer>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"is a pointer that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"is not a pointer that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(PointerType pointer,\n                         MatchResultListener* listener) const override {\n      *listener << \"which is a pointer that \";\n      Pointer p = GetRawPointer(pointer);\n      return MatchPrintAndExplain(p, matcher_, listener);\n    }\n\n   private:\n    Matcher<Pointer> matcher_;\n  };\n\n  const InnerMatcher matcher_;\n};\n\n#if GTEST_HAS_RTTI\n// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or\n// reference that matches inner_matcher when dynamic_cast<T> is applied.\n// The result of dynamic_cast<To> is forwarded to the inner matcher.\n// If To is a pointer and the cast fails, the inner matcher will receive NULL.\n// If To is a reference and the cast fails, this matcher returns false\n// immediately.\ntemplate <typename To>\nclass WhenDynamicCastToMatcherBase {\n public:\n  explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)\n      : matcher_(matcher) {}\n\n  void DescribeTo(::std::ostream* os) const {\n    GetCastTypeDescription(os);\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    GetCastTypeDescription(os);\n    matcher_.DescribeNegationTo(os);\n  }\n\n protected:\n  const Matcher<To> matcher_;\n\n  static std::string GetToName() { return GetTypeName<To>(); }\n\n private:\n  static void GetCastTypeDescription(::std::ostream* os) {\n    *os << \"when dynamic_cast to \" << GetToName() << \", \";\n  }\n};\n\n// Primary template.\n// To is a pointer. Cast and forward the result.\ntemplate <typename To>\nclass WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {\n public:\n  explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)\n      : WhenDynamicCastToMatcherBase<To>(matcher) {}\n\n  template <typename From>\n  bool MatchAndExplain(From from, MatchResultListener* listener) const {\n    To to = dynamic_cast<To>(from);\n    return MatchPrintAndExplain(to, this->matcher_, listener);\n  }\n};\n\n// Specialize for references.\n// In this case we return false if the dynamic_cast fails.\ntemplate <typename To>\nclass WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {\n public:\n  explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)\n      : WhenDynamicCastToMatcherBase<To&>(matcher) {}\n\n  template <typename From>\n  bool MatchAndExplain(From& from, MatchResultListener* listener) const {\n    // We don't want an std::bad_cast here, so do the cast with pointers.\n    To* to = dynamic_cast<To*>(&from);\n    if (to == nullptr) {\n      *listener << \"which cannot be dynamic_cast to \" << this->GetToName();\n      return false;\n    }\n    return MatchPrintAndExplain(*to, this->matcher_, listener);\n  }\n};\n#endif  // GTEST_HAS_RTTI\n\n// Implements the Field() matcher for matching a field (i.e. member\n// variable) of an object.\ntemplate <typename Class, typename FieldType>\nclass FieldMatcher {\n public:\n  FieldMatcher(FieldType Class::*field,\n               const Matcher<const FieldType&>& matcher)\n      : field_(field), matcher_(matcher), whose_field_(\"whose given field \") {}\n\n  FieldMatcher(const std::string& field_name, FieldType Class::*field,\n               const Matcher<const FieldType&>& matcher)\n      : field_(field),\n        matcher_(matcher),\n        whose_field_(\"whose field `\" + field_name + \"` \") {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_field_;\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_field_;\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {\n    // FIXME: The dispatch on std::is_pointer was introduced as a workaround for\n    // a compiler bug, and can now be removed.\n    return MatchAndExplainImpl(\n        typename std::is_pointer<typename std::remove_const<T>::type>::type(),\n        value, listener);\n  }\n\n private:\n  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,\n                           const Class& obj,\n                           MatchResultListener* listener) const {\n    *listener << whose_field_ << \"is \";\n    return MatchPrintAndExplain(obj.*field_, matcher_, listener);\n  }\n\n  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,\n                           MatchResultListener* listener) const {\n    if (p == nullptr) return false;\n\n    *listener << \"which points to an object \";\n    // Since *p has a field, it must be a class/struct/union type and\n    // thus cannot be a pointer.  Therefore we pass false_type() as\n    // the first argument.\n    return MatchAndExplainImpl(std::false_type(), *p, listener);\n  }\n\n  const FieldType Class::*field_;\n  const Matcher<const FieldType&> matcher_;\n\n  // Contains either \"whose given field \" if the name of the field is unknown\n  // or \"whose field `name_of_field` \" if the name is known.\n  const std::string whose_field_;\n};\n\n// Implements the Property() matcher for matching a property\n// (i.e. return value of a getter method) of an object.\n//\n// Property is a const-qualified member function of Class returning\n// PropertyType.\ntemplate <typename Class, typename PropertyType, typename Property>\nclass PropertyMatcher {\n public:\n  typedef const PropertyType& RefToConstProperty;\n\n  PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)\n      : property_(property),\n        matcher_(matcher),\n        whose_property_(\"whose given property \") {}\n\n  PropertyMatcher(const std::string& property_name, Property property,\n                  const Matcher<RefToConstProperty>& matcher)\n      : property_(property),\n        matcher_(matcher),\n        whose_property_(\"whose property `\" + property_name + \"` \") {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_property_;\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"is an object \" << whose_property_;\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {\n    return MatchAndExplainImpl(\n        typename std::is_pointer<typename std::remove_const<T>::type>::type(),\n        value, listener);\n  }\n\n private:\n  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,\n                           const Class& obj,\n                           MatchResultListener* listener) const {\n    *listener << whose_property_ << \"is \";\n    // Cannot pass the return value (for example, int) to MatchPrintAndExplain,\n    // which takes a non-const reference as argument.\n    RefToConstProperty result = (obj.*property_)();\n    return MatchPrintAndExplain(result, matcher_, listener);\n  }\n\n  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,\n                           MatchResultListener* listener) const {\n    if (p == nullptr) return false;\n\n    *listener << \"which points to an object \";\n    // Since *p has a property method, it must be a class/struct/union\n    // type and thus cannot be a pointer.  Therefore we pass\n    // false_type() as the first argument.\n    return MatchAndExplainImpl(std::false_type(), *p, listener);\n  }\n\n  Property property_;\n  const Matcher<RefToConstProperty> matcher_;\n\n  // Contains either \"whose given property \" if the name of the property is\n  // unknown or \"whose property `name_of_property` \" if the name is known.\n  const std::string whose_property_;\n};\n\n// Type traits specifying various features of different functors for ResultOf.\n// The default template specifies features for functor objects.\ntemplate <typename Functor>\nstruct CallableTraits {\n  typedef Functor StorageType;\n\n  static void CheckIsValid(Functor /* functor */) {}\n\n  template <typename T>\n  static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) {\n    return f(arg);\n  }\n};\n\n// Specialization for function pointers.\ntemplate <typename ArgType, typename ResType>\nstruct CallableTraits<ResType (*)(ArgType)> {\n  typedef ResType ResultType;\n  typedef ResType (*StorageType)(ArgType);\n\n  static void CheckIsValid(ResType (*f)(ArgType)) {\n    GTEST_CHECK_(f != nullptr)\n        << \"NULL function pointer is passed into ResultOf().\";\n  }\n  template <typename T>\n  static ResType Invoke(ResType (*f)(ArgType), T arg) {\n    return (*f)(arg);\n  }\n};\n\n// Implements the ResultOf() matcher for matching a return value of a\n// unary function of an object.\ntemplate <typename Callable, typename InnerMatcher>\nclass ResultOfMatcher {\n public:\n  ResultOfMatcher(Callable callable, InnerMatcher matcher)\n      : ResultOfMatcher(/*result_description=*/\"\", std::move(callable),\n                        std::move(matcher)) {}\n\n  ResultOfMatcher(const std::string& result_description, Callable callable,\n                  InnerMatcher matcher)\n      : result_description_(result_description),\n        callable_(std::move(callable)),\n        matcher_(std::move(matcher)) {\n    CallableTraits<Callable>::CheckIsValid(callable_);\n  }\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(\n        new Impl<const T&>(result_description_, callable_, matcher_));\n  }\n\n private:\n  typedef typename CallableTraits<Callable>::StorageType CallableStorageType;\n\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n    using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>(\n        std::declval<CallableStorageType>(), std::declval<T>()));\n\n   public:\n    template <typename M>\n    Impl(const std::string& result_description,\n         const CallableStorageType& callable, const M& matcher)\n        : result_description_(result_description),\n          callable_(callable),\n          matcher_(MatcherCast<ResultType>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      if (result_description_.empty()) {\n        *os << \"is mapped by the given callable to a value that \";\n      } else {\n        *os << \"whose \" << result_description_ << \" \";\n      }\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      if (result_description_.empty()) {\n        *os << \"is mapped by the given callable to a value that \";\n      } else {\n        *os << \"whose \" << result_description_ << \" \";\n      }\n      matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(T obj, MatchResultListener* listener) const override {\n      if (result_description_.empty()) {\n        *listener << \"which is mapped by the given callable to \";\n      } else {\n        *listener << \"whose \" << result_description_ << \" is \";\n      }\n      // Cannot pass the return value directly to MatchPrintAndExplain, which\n      // takes a non-const reference as argument.\n      // Also, specifying template argument explicitly is needed because T could\n      // be a non-const reference (e.g. Matcher<Uncopyable&>).\n      ResultType result =\n          CallableTraits<Callable>::template Invoke<T>(callable_, obj);\n      return MatchPrintAndExplain(result, matcher_, listener);\n    }\n\n   private:\n    const std::string result_description_;\n    // Functors often define operator() as non-const method even though\n    // they are actually stateless. But we need to use them even when\n    // 'this' is a const pointer. It's the user's responsibility not to\n    // use stateful callables with ResultOf(), which doesn't guarantee\n    // how many times the callable will be invoked.\n    mutable CallableStorageType callable_;\n    const Matcher<ResultType> matcher_;\n  };  // class Impl\n\n  const std::string result_description_;\n  const CallableStorageType callable_;\n  const InnerMatcher matcher_;\n};\n\n// Implements a matcher that checks the size of an STL-style container.\ntemplate <typename SizeMatcher>\nclass SizeIsMatcher {\n public:\n  explicit SizeIsMatcher(const SizeMatcher& size_matcher)\n      : size_matcher_(size_matcher) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(new Impl<const Container&>(size_matcher_));\n  }\n\n  template <typename Container>\n  class Impl : public MatcherInterface<Container> {\n   public:\n    using SizeType = decltype(std::declval<Container>().size());\n    explicit Impl(const SizeMatcher& size_matcher)\n        : size_matcher_(MatcherCast<SizeType>(size_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"has a size that \";\n      size_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"has a size that \";\n      size_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Container container,\n                         MatchResultListener* listener) const override {\n      SizeType size = container.size();\n      StringMatchResultListener size_listener;\n      const bool result = size_matcher_.MatchAndExplain(size, &size_listener);\n      *listener << \"whose size \" << size\n                << (result ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(size_listener.str(), listener->stream());\n      return result;\n    }\n\n   private:\n    const Matcher<SizeType> size_matcher_;\n  };\n\n private:\n  const SizeMatcher size_matcher_;\n};\n\n// Implements a matcher that checks the begin()..end() distance of an STL-style\n// container.\ntemplate <typename DistanceMatcher>\nclass BeginEndDistanceIsMatcher {\n public:\n  explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)\n      : distance_matcher_(distance_matcher) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(new Impl<const Container&>(distance_matcher_));\n  }\n\n  template <typename Container>\n  class Impl : public MatcherInterface<Container> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        Container)>\n        ContainerView;\n    typedef typename std::iterator_traits<\n        typename ContainerView::type::const_iterator>::difference_type\n        DistanceType;\n    explicit Impl(const DistanceMatcher& distance_matcher)\n        : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"distance between begin() and end() \";\n      distance_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"distance between begin() and end() \";\n      distance_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Container container,\n                         MatchResultListener* listener) const override {\n      using std::begin;\n      using std::end;\n      DistanceType distance = std::distance(begin(container), end(container));\n      StringMatchResultListener distance_listener;\n      const bool result =\n          distance_matcher_.MatchAndExplain(distance, &distance_listener);\n      *listener << \"whose distance between begin() and end() \" << distance\n                << (result ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(distance_listener.str(), listener->stream());\n      return result;\n    }\n\n   private:\n    const Matcher<DistanceType> distance_matcher_;\n  };\n\n private:\n  const DistanceMatcher distance_matcher_;\n};\n\n// Implements an equality matcher for any STL-style container whose elements\n// support ==. This matcher is like Eq(), but its failure explanations provide\n// more detailed information that is useful when the container is used as a set.\n// The failure message reports elements that are in one of the operands but not\n// the other. The failure messages do not report duplicate or out-of-order\n// elements in the containers (which don't properly matter to sets, but can\n// occur if the containers are vectors or lists, for example).\n//\n// Uses the container's const_iterator, value_type, operator ==,\n// begin(), and end().\ntemplate <typename Container>\nclass ContainerEqMatcher {\n public:\n  typedef internal::StlContainerView<Container> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n\n  static_assert(!std::is_const<Container>::value,\n                \"Container type must not be const\");\n  static_assert(!std::is_reference<Container>::value,\n                \"Container type must not be a reference\");\n\n  // We make a copy of expected in case the elements in it are modified\n  // after this matcher is created.\n  explicit ContainerEqMatcher(const Container& expected)\n      : expected_(View::Copy(expected)) {}\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << \"equals \";\n    UniversalPrint(expected_, os);\n  }\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"does not equal \";\n    UniversalPrint(expected_, os);\n  }\n\n  template <typename LhsContainer>\n  bool MatchAndExplain(const LhsContainer& lhs,\n                       MatchResultListener* listener) const {\n    typedef internal::StlContainerView<\n        typename std::remove_const<LhsContainer>::type>\n        LhsView;\n    StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n    if (lhs_stl_container == expected_) return true;\n\n    ::std::ostream* const os = listener->stream();\n    if (os != nullptr) {\n      // Something is different. Check for extra values first.\n      bool printed_header = false;\n      for (auto it = lhs_stl_container.begin(); it != lhs_stl_container.end();\n           ++it) {\n        if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==\n            expected_.end()) {\n          if (printed_header) {\n            *os << \", \";\n          } else {\n            *os << \"which has these unexpected elements: \";\n            printed_header = true;\n          }\n          UniversalPrint(*it, os);\n        }\n      }\n\n      // Now check for missing values.\n      bool printed_header2 = false;\n      for (auto it = expected_.begin(); it != expected_.end(); ++it) {\n        if (internal::ArrayAwareFind(lhs_stl_container.begin(),\n                                     lhs_stl_container.end(),\n                                     *it) == lhs_stl_container.end()) {\n          if (printed_header2) {\n            *os << \", \";\n          } else {\n            *os << (printed_header ? \",\\nand\" : \"which\")\n                << \" doesn't have these expected elements: \";\n            printed_header2 = true;\n          }\n          UniversalPrint(*it, os);\n        }\n      }\n    }\n\n    return false;\n  }\n\n private:\n  const StlContainer expected_;\n};\n\n// A comparator functor that uses the < operator to compare two values.\nstruct LessComparator {\n  template <typename T, typename U>\n  bool operator()(const T& lhs, const U& rhs) const {\n    return lhs < rhs;\n  }\n};\n\n// Implements WhenSortedBy(comparator, container_matcher).\ntemplate <typename Comparator, typename ContainerMatcher>\nclass WhenSortedByMatcher {\n public:\n  WhenSortedByMatcher(const Comparator& comparator,\n                      const ContainerMatcher& matcher)\n      : comparator_(comparator), matcher_(matcher) {}\n\n  template <typename LhsContainer>\n  operator Matcher<LhsContainer>() const {\n    return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_));\n  }\n\n  template <typename LhsContainer>\n  class Impl : public MatcherInterface<LhsContainer> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        LhsContainer)>\n        LhsView;\n    typedef typename LhsView::type LhsStlContainer;\n    typedef typename LhsView::const_reference LhsStlContainerReference;\n    // Transforms std::pair<const Key, Value> into std::pair<Key, Value>\n    // so that we can match associative containers.\n    typedef\n        typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type\n            LhsValue;\n\n    Impl(const Comparator& comparator, const ContainerMatcher& matcher)\n        : comparator_(comparator), matcher_(matcher) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"(when sorted) \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"(when sorted) \";\n      matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(LhsContainer lhs,\n                         MatchResultListener* listener) const override {\n      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n      ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),\n                                               lhs_stl_container.end());\n      ::std::sort(sorted_container.begin(), sorted_container.end(),\n                  comparator_);\n\n      if (!listener->IsInterested()) {\n        // If the listener is not interested, we do not need to\n        // construct the inner explanation.\n        return matcher_.Matches(sorted_container);\n      }\n\n      *listener << \"which is \";\n      UniversalPrint(sorted_container, listener->stream());\n      *listener << \" when sorted\";\n\n      StringMatchResultListener inner_listener;\n      const bool match =\n          matcher_.MatchAndExplain(sorted_container, &inner_listener);\n      PrintIfNotEmpty(inner_listener.str(), listener->stream());\n      return match;\n    }\n\n   private:\n    const Comparator comparator_;\n    const Matcher<const ::std::vector<LhsValue>&> matcher_;\n\n    Impl(const Impl&) = delete;\n    Impl& operator=(const Impl&) = delete;\n  };\n\n private:\n  const Comparator comparator_;\n  const ContainerMatcher matcher_;\n};\n\n// Implements Pointwise(tuple_matcher, rhs_container).  tuple_matcher\n// must be able to be safely cast to Matcher<std::tuple<const T1&, const\n// T2&> >, where T1 and T2 are the types of elements in the LHS\n// container and the RHS container respectively.\ntemplate <typename TupleMatcher, typename RhsContainer>\nclass PointwiseMatcher {\n  static_assert(\n      !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,\n      \"use UnorderedPointwise with hash tables\");\n\n public:\n  typedef internal::StlContainerView<RhsContainer> RhsView;\n  typedef typename RhsView::type RhsStlContainer;\n  typedef typename RhsStlContainer::value_type RhsValue;\n\n  static_assert(!std::is_const<RhsContainer>::value,\n                \"RhsContainer type must not be const\");\n  static_assert(!std::is_reference<RhsContainer>::value,\n                \"RhsContainer type must not be a reference\");\n\n  // Like ContainerEq, we make a copy of rhs in case the elements in\n  // it are modified after this matcher is created.\n  PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)\n      : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {}\n\n  template <typename LhsContainer>\n  operator Matcher<LhsContainer>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,\n        \"use UnorderedPointwise with hash tables\");\n\n    return Matcher<LhsContainer>(\n        new Impl<const LhsContainer&>(tuple_matcher_, rhs_));\n  }\n\n  template <typename LhsContainer>\n  class Impl : public MatcherInterface<LhsContainer> {\n   public:\n    typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(\n        LhsContainer)>\n        LhsView;\n    typedef typename LhsView::type LhsStlContainer;\n    typedef typename LhsView::const_reference LhsStlContainerReference;\n    typedef typename LhsStlContainer::value_type LhsValue;\n    // We pass the LHS value and the RHS value to the inner matcher by\n    // reference, as they may be expensive to copy.  We must use tuple\n    // instead of pair here, as a pair cannot hold references (C++ 98,\n    // 20.2.2 [lib.pairs]).\n    typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;\n\n    Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)\n        // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.\n        : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),\n          rhs_(rhs) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"contains \" << rhs_.size()\n          << \" values, where each value and its corresponding value in \";\n      UniversalPrinter<RhsStlContainer>::Print(rhs_, os);\n      *os << \" \";\n      mono_tuple_matcher_.DescribeTo(os);\n    }\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"doesn't contain exactly \" << rhs_.size()\n          << \" values, or contains a value x at some index i\"\n          << \" where x and the i-th value of \";\n      UniversalPrint(rhs_, os);\n      *os << \" \";\n      mono_tuple_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(LhsContainer lhs,\n                         MatchResultListener* listener) const override {\n      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);\n      const size_t actual_size = lhs_stl_container.size();\n      if (actual_size != rhs_.size()) {\n        *listener << \"which contains \" << actual_size << \" values\";\n        return false;\n      }\n\n      auto left = lhs_stl_container.begin();\n      auto right = rhs_.begin();\n      for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {\n        if (listener->IsInterested()) {\n          StringMatchResultListener inner_listener;\n          // Create InnerMatcherArg as a temporarily object to avoid it outlives\n          // *left and *right. Dereference or the conversion to `const T&` may\n          // return temp objects, e.g. for vector<bool>.\n          if (!mono_tuple_matcher_.MatchAndExplain(\n                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),\n                                  ImplicitCast_<const RhsValue&>(*right)),\n                  &inner_listener)) {\n            *listener << \"where the value pair (\";\n            UniversalPrint(*left, listener->stream());\n            *listener << \", \";\n            UniversalPrint(*right, listener->stream());\n            *listener << \") at index #\" << i << \" don't match\";\n            PrintIfNotEmpty(inner_listener.str(), listener->stream());\n            return false;\n          }\n        } else {\n          if (!mono_tuple_matcher_.Matches(\n                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),\n                                  ImplicitCast_<const RhsValue&>(*right))))\n            return false;\n        }\n      }\n\n      return true;\n    }\n\n   private:\n    const Matcher<InnerMatcherArg> mono_tuple_matcher_;\n    const RhsStlContainer rhs_;\n  };\n\n private:\n  const TupleMatcher tuple_matcher_;\n  const RhsStlContainer rhs_;\n};\n\n// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.\ntemplate <typename Container>\nclass QuantifierMatcherImpl : public MatcherInterface<Container> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  template <typename InnerMatcher>\n  explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)\n      : inner_matcher_(\n            testing::SafeMatcherCast<const Element&>(inner_matcher)) {}\n\n  // Checks whether:\n  // * All elements in the container match, if all_elements_should_match.\n  // * Any element in the container matches, if !all_elements_should_match.\n  bool MatchAndExplainImpl(bool all_elements_should_match, Container container,\n                           MatchResultListener* listener) const {\n    StlContainerReference stl_container = View::ConstReference(container);\n    size_t i = 0;\n    for (auto it = stl_container.begin(); it != stl_container.end();\n         ++it, ++i) {\n      StringMatchResultListener inner_listener;\n      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);\n\n      if (matches != all_elements_should_match) {\n        *listener << \"whose element #\" << i\n                  << (matches ? \" matches\" : \" doesn't match\");\n        PrintIfNotEmpty(inner_listener.str(), listener->stream());\n        return !all_elements_should_match;\n      }\n    }\n    return all_elements_should_match;\n  }\n\n  bool MatchAndExplainImpl(const Matcher<size_t>& count_matcher,\n                           Container container,\n                           MatchResultListener* listener) const {\n    StlContainerReference stl_container = View::ConstReference(container);\n    size_t i = 0;\n    std::vector<size_t> match_elements;\n    for (auto it = stl_container.begin(); it != stl_container.end();\n         ++it, ++i) {\n      StringMatchResultListener inner_listener;\n      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);\n      if (matches) {\n        match_elements.push_back(i);\n      }\n    }\n    if (listener->IsInterested()) {\n      if (match_elements.empty()) {\n        *listener << \"has no element that matches\";\n      } else if (match_elements.size() == 1) {\n        *listener << \"whose element #\" << match_elements[0] << \" matches\";\n      } else {\n        *listener << \"whose elements (\";\n        std::string sep = \"\";\n        for (size_t e : match_elements) {\n          *listener << sep << e;\n          sep = \", \";\n        }\n        *listener << \") match\";\n      }\n    }\n    StringMatchResultListener count_listener;\n    if (count_matcher.MatchAndExplain(match_elements.size(), &count_listener)) {\n      *listener << \" and whose match quantity of \" << match_elements.size()\n                << \" matches\";\n      PrintIfNotEmpty(count_listener.str(), listener->stream());\n      return true;\n    } else {\n      if (match_elements.empty()) {\n        *listener << \" and\";\n      } else {\n        *listener << \" but\";\n      }\n      *listener << \" whose match quantity of \" << match_elements.size()\n                << \" does not match\";\n      PrintIfNotEmpty(count_listener.str(), listener->stream());\n      return false;\n    }\n  }\n\n protected:\n  const Matcher<const Element&> inner_matcher_;\n};\n\n// Implements Contains(element_matcher) for the given argument type Container.\n// Symmetric to EachMatcherImpl.\ntemplate <typename Container>\nclass ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit ContainsMatcherImpl(InnerMatcher inner_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"contains at least one element that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"doesn't contain any element that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(false, container, listener);\n  }\n};\n\n// Implements Each(element_matcher) for the given argument type Container.\n// Symmetric to ContainsMatcherImpl.\ntemplate <typename Container>\nclass EachMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit EachMatcherImpl(InnerMatcher inner_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"only contains elements that \";\n    this->inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"contains some element that \";\n    this->inner_matcher_.DescribeNegationTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(true, container, listener);\n  }\n};\n\n// Implements Contains(element_matcher).Times(n) for the given argument type\n// Container.\ntemplate <typename Container>\nclass ContainsTimesMatcherImpl : public QuantifierMatcherImpl<Container> {\n public:\n  template <typename InnerMatcher>\n  explicit ContainsTimesMatcherImpl(InnerMatcher inner_matcher,\n                                    Matcher<size_t> count_matcher)\n      : QuantifierMatcherImpl<Container>(inner_matcher),\n        count_matcher_(std::move(count_matcher)) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"quantity of elements that match \";\n    this->inner_matcher_.DescribeTo(os);\n    *os << \" \";\n    count_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"quantity of elements that match \";\n    this->inner_matcher_.DescribeTo(os);\n    *os << \" \";\n    count_matcher_.DescribeNegationTo(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    return this->MatchAndExplainImpl(count_matcher_, container, listener);\n  }\n\n private:\n  const Matcher<size_t> count_matcher_;\n};\n\n// Implements polymorphic Contains(element_matcher).Times(n).\ntemplate <typename M>\nclass ContainsTimesMatcher {\n public:\n  explicit ContainsTimesMatcher(M m, Matcher<size_t> count_matcher)\n      : inner_matcher_(m), count_matcher_(std::move(count_matcher)) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(new ContainsTimesMatcherImpl<const Container&>(\n        inner_matcher_, count_matcher_));\n  }\n\n private:\n  const M inner_matcher_;\n  const Matcher<size_t> count_matcher_;\n};\n\n// Implements polymorphic Contains(element_matcher).\ntemplate <typename M>\nclass ContainsMatcher {\n public:\n  explicit ContainsMatcher(M m) : inner_matcher_(m) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(\n        new ContainsMatcherImpl<const Container&>(inner_matcher_));\n  }\n\n  ContainsTimesMatcher<M> Times(Matcher<size_t> count_matcher) const {\n    return ContainsTimesMatcher<M>(inner_matcher_, std::move(count_matcher));\n  }\n\n private:\n  const M inner_matcher_;\n};\n\n// Implements polymorphic Each(element_matcher).\ntemplate <typename M>\nclass EachMatcher {\n public:\n  explicit EachMatcher(M m) : inner_matcher_(m) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {  // NOLINT\n    return Matcher<Container>(\n        new EachMatcherImpl<const Container&>(inner_matcher_));\n  }\n\n private:\n  const M inner_matcher_;\n};\n\n// Use go/ranked-overloads for dispatching.\nstruct Rank0 {};\nstruct Rank1 : Rank0 {};\n\nnamespace pair_getters {\nusing std::get;\ntemplate <typename T>\nauto First(T& x, Rank0) -> decltype(get<0>(x)) {  // NOLINT\n  return get<0>(x);\n}\ntemplate <typename T>\nauto First(T& x, Rank1) -> decltype((x.first)) {  // NOLINT\n  return x.first;\n}\n\ntemplate <typename T>\nauto Second(T& x, Rank0) -> decltype(get<1>(x)) {  // NOLINT\n  return get<1>(x);\n}\ntemplate <typename T>\nauto Second(T& x, Rank1) -> decltype((x.second)) {  // NOLINT\n  return x.second;\n}\n}  // namespace pair_getters\n\n// Implements Key(inner_matcher) for the given argument pair type.\n// Key(inner_matcher) matches an std::pair whose 'first' field matches\n// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an\n// std::map that contains at least one element whose key is >= 5.\ntemplate <typename PairType>\nclass KeyMatcherImpl : public MatcherInterface<PairType> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;\n  typedef typename RawPairType::first_type KeyType;\n\n  template <typename InnerMatcher>\n  explicit KeyMatcherImpl(InnerMatcher inner_matcher)\n      : inner_matcher_(\n            testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {}\n\n  // Returns true if and only if 'key_value.first' (the key) matches the inner\n  // matcher.\n  bool MatchAndExplain(PairType key_value,\n                       MatchResultListener* listener) const override {\n    StringMatchResultListener inner_listener;\n    const bool match = inner_matcher_.MatchAndExplain(\n        pair_getters::First(key_value, Rank1()), &inner_listener);\n    const std::string explanation = inner_listener.str();\n    if (!explanation.empty()) {\n      *listener << \"whose first field is a value \" << explanation;\n    }\n    return match;\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"has a key that \";\n    inner_matcher_.DescribeTo(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"doesn't have a key that \";\n    inner_matcher_.DescribeTo(os);\n  }\n\n private:\n  const Matcher<const KeyType&> inner_matcher_;\n};\n\n// Implements polymorphic Key(matcher_for_key).\ntemplate <typename M>\nclass KeyMatcher {\n public:\n  explicit KeyMatcher(M m) : matcher_for_key_(m) {}\n\n  template <typename PairType>\n  operator Matcher<PairType>() const {\n    return Matcher<PairType>(\n        new KeyMatcherImpl<const PairType&>(matcher_for_key_));\n  }\n\n private:\n  const M matcher_for_key_;\n};\n\n// Implements polymorphic Address(matcher_for_address).\ntemplate <typename InnerMatcher>\nclass AddressMatcher {\n public:\n  explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}\n\n  template <typename Type>\n  operator Matcher<Type>() const {  // NOLINT\n    return Matcher<Type>(new Impl<const Type&>(matcher_));\n  }\n\n private:\n  // The monomorphic implementation that works for a particular object type.\n  template <typename Type>\n  class Impl : public MatcherInterface<Type> {\n   public:\n    using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;\n    explicit Impl(const InnerMatcher& matcher)\n        : matcher_(MatcherCast<Address>(matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"has address that \";\n      matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"does not have address that \";\n      matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(Type object,\n                         MatchResultListener* listener) const override {\n      *listener << \"which has address \";\n      Address address = std::addressof(object);\n      return MatchPrintAndExplain(address, matcher_, listener);\n    }\n\n   private:\n    const Matcher<Address> matcher_;\n  };\n  const InnerMatcher matcher_;\n};\n\n// Implements Pair(first_matcher, second_matcher) for the given argument pair\n// type with its two matchers. See Pair() function below.\ntemplate <typename PairType>\nclass PairMatcherImpl : public MatcherInterface<PairType> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;\n  typedef typename RawPairType::first_type FirstType;\n  typedef typename RawPairType::second_type SecondType;\n\n  template <typename FirstMatcher, typename SecondMatcher>\n  PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)\n      : first_matcher_(\n            testing::SafeMatcherCast<const FirstType&>(first_matcher)),\n        second_matcher_(\n            testing::SafeMatcherCast<const SecondType&>(second_matcher)) {}\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"has a first field that \";\n    first_matcher_.DescribeTo(os);\n    *os << \", and has a second field that \";\n    second_matcher_.DescribeTo(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"has a first field that \";\n    first_matcher_.DescribeNegationTo(os);\n    *os << \", or has a second field that \";\n    second_matcher_.DescribeNegationTo(os);\n  }\n\n  // Returns true if and only if 'a_pair.first' matches first_matcher and\n  // 'a_pair.second' matches second_matcher.\n  bool MatchAndExplain(PairType a_pair,\n                       MatchResultListener* listener) const override {\n    if (!listener->IsInterested()) {\n      // If the listener is not interested, we don't need to construct the\n      // explanation.\n      return first_matcher_.Matches(pair_getters::First(a_pair, Rank1())) &&\n             second_matcher_.Matches(pair_getters::Second(a_pair, Rank1()));\n    }\n    StringMatchResultListener first_inner_listener;\n    if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank1()),\n                                        &first_inner_listener)) {\n      *listener << \"whose first field does not match\";\n      PrintIfNotEmpty(first_inner_listener.str(), listener->stream());\n      return false;\n    }\n    StringMatchResultListener second_inner_listener;\n    if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank1()),\n                                         &second_inner_listener)) {\n      *listener << \"whose second field does not match\";\n      PrintIfNotEmpty(second_inner_listener.str(), listener->stream());\n      return false;\n    }\n    ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),\n                   listener);\n    return true;\n  }\n\n private:\n  void ExplainSuccess(const std::string& first_explanation,\n                      const std::string& second_explanation,\n                      MatchResultListener* listener) const {\n    *listener << \"whose both fields match\";\n    if (!first_explanation.empty()) {\n      *listener << \", where the first field is a value \" << first_explanation;\n    }\n    if (!second_explanation.empty()) {\n      *listener << \", \";\n      if (!first_explanation.empty()) {\n        *listener << \"and \";\n      } else {\n        *listener << \"where \";\n      }\n      *listener << \"the second field is a value \" << second_explanation;\n    }\n  }\n\n  const Matcher<const FirstType&> first_matcher_;\n  const Matcher<const SecondType&> second_matcher_;\n};\n\n// Implements polymorphic Pair(first_matcher, second_matcher).\ntemplate <typename FirstMatcher, typename SecondMatcher>\nclass PairMatcher {\n public:\n  PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)\n      : first_matcher_(first_matcher), second_matcher_(second_matcher) {}\n\n  template <typename PairType>\n  operator Matcher<PairType>() const {\n    return Matcher<PairType>(\n        new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));\n  }\n\n private:\n  const FirstMatcher first_matcher_;\n  const SecondMatcher second_matcher_;\n};\n\ntemplate <typename T, size_t... I>\nauto UnpackStructImpl(const T& t, std::index_sequence<I...>,\n                      int) -> decltype(std::tie(get<I>(t)...)) {\n  static_assert(std::tuple_size<T>::value == sizeof...(I),\n                \"Number of arguments doesn't match the number of fields.\");\n  return std::tie(get<I>(t)...);\n}\n\n#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) {\n  const auto& [a] = t;\n  return std::tie(a);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) {\n  const auto& [a, b] = t;\n  return std::tie(a, b);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) {\n  const auto& [a, b, c] = t;\n  return std::tie(a, b, c);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) {\n  const auto& [a, b, c, d] = t;\n  return std::tie(a, b, c, d);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) {\n  const auto& [a, b, c, d, e] = t;\n  return std::tie(a, b, c, d, e);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) {\n  const auto& [a, b, c, d, e, f] = t;\n  return std::tie(a, b, c, d, e, f);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) {\n  const auto& [a, b, c, d, e, f, g] = t;\n  return std::tie(a, b, c, d, e, f, g);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) {\n  const auto& [a, b, c, d, e, f, g, h] = t;\n  return std::tie(a, b, c, d, e, f, g, h);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);\n}\ntemplate <typename T>\nauto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) {\n  const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;\n  return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);\n}\n#endif  // defined(__cpp_structured_bindings)\n\ntemplate <size_t I, typename T>\nauto UnpackStruct(const T& t)\n    -> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) {\n  return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0);\n}\n\n// Helper function to do comma folding in C++11.\n// The array ensures left-to-right order of evaluation.\n// Usage: VariadicExpand({expr...});\ntemplate <typename T, size_t N>\nvoid VariadicExpand(const T (&)[N]) {}\n\ntemplate <typename Struct, typename StructSize>\nclass FieldsAreMatcherImpl;\n\ntemplate <typename Struct, size_t... I>\nclass FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>\n    : public MatcherInterface<Struct> {\n  using UnpackedType =\n      decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));\n  using MatchersType = std::tuple<\n      Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>;\n\n public:\n  template <typename Inner>\n  explicit FieldsAreMatcherImpl(const Inner& matchers)\n      : matchers_(testing::SafeMatcherCast<\n                  const typename std::tuple_element<I, UnpackedType>::type&>(\n            std::get<I>(matchers))...) {}\n\n  void DescribeTo(::std::ostream* os) const override {\n    const char* separator = \"\";\n    VariadicExpand(\n        {(*os << separator << \"has field #\" << I << \" that \",\n          std::get<I>(matchers_).DescribeTo(os), separator = \", and \")...});\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    const char* separator = \"\";\n    VariadicExpand({(*os << separator << \"has field #\" << I << \" that \",\n                     std::get<I>(matchers_).DescribeNegationTo(os),\n                     separator = \", or \")...});\n  }\n\n  bool MatchAndExplain(Struct t, MatchResultListener* listener) const override {\n    return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener);\n  }\n\n private:\n  bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const {\n    if (!listener->IsInterested()) {\n      // If the listener is not interested, we don't need to construct the\n      // explanation.\n      bool good = true;\n      VariadicExpand({good = good && std::get<I>(matchers_).Matches(\n                                         std::get<I>(tuple))...});\n      return good;\n    }\n\n    size_t failed_pos = ~size_t{};\n\n    std::vector<StringMatchResultListener> inner_listener(sizeof...(I));\n\n    VariadicExpand(\n        {failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(\n                                        std::get<I>(tuple), &inner_listener[I])\n             ? failed_pos = I\n             : 0 ...});\n    if (failed_pos != ~size_t{}) {\n      *listener << \"whose field #\" << failed_pos << \" does not match\";\n      PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream());\n      return false;\n    }\n\n    *listener << \"whose all elements match\";\n    const char* separator = \", where\";\n    for (size_t index = 0; index < sizeof...(I); ++index) {\n      const std::string str = inner_listener[index].str();\n      if (!str.empty()) {\n        *listener << separator << \" field #\" << index << \" is a value \" << str;\n        separator = \", and\";\n      }\n    }\n\n    return true;\n  }\n\n  MatchersType matchers_;\n};\n\ntemplate <typename... Inner>\nclass FieldsAreMatcher {\n public:\n  explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {}\n\n  template <typename Struct>\n  operator Matcher<Struct>() const {  // NOLINT\n    return Matcher<Struct>(\n        new FieldsAreMatcherImpl<const Struct&,\n                                 std::index_sequence_for<Inner...>>(matchers_));\n  }\n\n private:\n  std::tuple<Inner...> matchers_;\n};\n\n// Implements ElementsAre() and ElementsAreArray().\ntemplate <typename Container>\nclass ElementsAreMatcherImpl : public MatcherInterface<Container> {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef internal::StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  // Constructs the matcher from a sequence of element values or\n  // element matchers.\n  template <typename InputIter>\n  ElementsAreMatcherImpl(InputIter first, InputIter last) {\n    while (first != last) {\n      matchers_.push_back(MatcherCast<const Element&>(*first++));\n    }\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    if (count() == 0) {\n      *os << \"is empty\";\n    } else if (count() == 1) {\n      *os << \"has 1 element that \";\n      matchers_[0].DescribeTo(os);\n    } else {\n      *os << \"has \" << Elements(count()) << \" where\\n\";\n      for (size_t i = 0; i != count(); ++i) {\n        *os << \"element #\" << i << \" \";\n        matchers_[i].DescribeTo(os);\n        if (i + 1 < count()) {\n          *os << \",\\n\";\n        }\n      }\n    }\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    if (count() == 0) {\n      *os << \"isn't empty\";\n      return;\n    }\n\n    *os << \"doesn't have \" << Elements(count()) << \", or\\n\";\n    for (size_t i = 0; i != count(); ++i) {\n      *os << \"element #\" << i << \" \";\n      matchers_[i].DescribeNegationTo(os);\n      if (i + 1 < count()) {\n        *os << \", or\\n\";\n      }\n    }\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    // To work with stream-like \"containers\", we must only walk\n    // through the elements in one pass.\n\n    const bool listener_interested = listener->IsInterested();\n\n    // explanations[i] is the explanation of the element at index i.\n    ::std::vector<std::string> explanations(count());\n    StlContainerReference stl_container = View::ConstReference(container);\n    auto it = stl_container.begin();\n    size_t exam_pos = 0;\n    bool mismatch_found = false;  // Have we found a mismatched element yet?\n\n    // Go through the elements and matchers in pairs, until we reach\n    // the end of either the elements or the matchers, or until we find a\n    // mismatch.\n    for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) {\n      bool match;  // Does the current element match the current matcher?\n      if (listener_interested) {\n        StringMatchResultListener s;\n        match = matchers_[exam_pos].MatchAndExplain(*it, &s);\n        explanations[exam_pos] = s.str();\n      } else {\n        match = matchers_[exam_pos].Matches(*it);\n      }\n\n      if (!match) {\n        mismatch_found = true;\n        break;\n      }\n    }\n    // If mismatch_found is true, 'exam_pos' is the index of the mismatch.\n\n    // Find how many elements the actual container has.  We avoid\n    // calling size() s.t. this code works for stream-like \"containers\"\n    // that don't define size().\n    size_t actual_count = exam_pos;\n    for (; it != stl_container.end(); ++it) {\n      ++actual_count;\n    }\n\n    if (actual_count != count()) {\n      // The element count doesn't match.  If the container is empty,\n      // there's no need to explain anything as Google Mock already\n      // prints the empty container.  Otherwise we just need to show\n      // how many elements there actually are.\n      if (listener_interested && (actual_count != 0)) {\n        *listener << \"which has \" << Elements(actual_count);\n      }\n      return false;\n    }\n\n    if (mismatch_found) {\n      // The element count matches, but the exam_pos-th element doesn't match.\n      if (listener_interested) {\n        *listener << \"whose element #\" << exam_pos << \" doesn't match\";\n        PrintIfNotEmpty(explanations[exam_pos], listener->stream());\n      }\n      return false;\n    }\n\n    // Every element matches its expectation.  We need to explain why\n    // (the obvious ones can be skipped).\n    if (listener_interested) {\n      bool reason_printed = false;\n      for (size_t i = 0; i != count(); ++i) {\n        const std::string& s = explanations[i];\n        if (!s.empty()) {\n          if (reason_printed) {\n            *listener << \",\\nand \";\n          }\n          *listener << \"whose element #\" << i << \" matches, \" << s;\n          reason_printed = true;\n        }\n      }\n    }\n    return true;\n  }\n\n private:\n  static Message Elements(size_t count) {\n    return Message() << count << (count == 1 ? \" element\" : \" elements\");\n  }\n\n  size_t count() const { return matchers_.size(); }\n\n  ::std::vector<Matcher<const Element&>> matchers_;\n};\n\n// Connectivity matrix of (elements X matchers), in element-major order.\n// Initially, there are no edges.\n// Use NextGraph() to iterate over all possible edge configurations.\n// Use Randomize() to generate a random edge configuration.\nclass GTEST_API_ MatchMatrix {\n public:\n  MatchMatrix(size_t num_elements, size_t num_matchers)\n      : num_elements_(num_elements),\n        num_matchers_(num_matchers),\n        matched_(num_elements_ * num_matchers_, 0) {}\n\n  size_t LhsSize() const { return num_elements_; }\n  size_t RhsSize() const { return num_matchers_; }\n  bool HasEdge(size_t ilhs, size_t irhs) const {\n    return matched_[SpaceIndex(ilhs, irhs)] == 1;\n  }\n  void SetEdge(size_t ilhs, size_t irhs, bool b) {\n    matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0;\n  }\n\n  // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number,\n  // adds 1 to that number; returns false if incrementing the graph left it\n  // empty.\n  bool NextGraph();\n\n  void Randomize();\n\n  std::string DebugString() const;\n\n private:\n  size_t SpaceIndex(size_t ilhs, size_t irhs) const {\n    return ilhs * num_matchers_ + irhs;\n  }\n\n  size_t num_elements_;\n  size_t num_matchers_;\n\n  // Each element is a char interpreted as bool. They are stored as a\n  // flattened array in lhs-major order, use 'SpaceIndex()' to translate\n  // a (ilhs, irhs) matrix coordinate into an offset.\n  ::std::vector<char> matched_;\n};\n\ntypedef ::std::pair<size_t, size_t> ElementMatcherPair;\ntypedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;\n\n// Returns a maximum bipartite matching for the specified graph 'g'.\n// The matching is represented as a vector of {element, matcher} pairs.\nGTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g);\n\nstruct UnorderedMatcherRequire {\n  enum Flags {\n    Superset = 1 << 0,\n    Subset = 1 << 1,\n    ExactMatch = Superset | Subset,\n  };\n};\n\n// Untyped base class for implementing UnorderedElementsAre.  By\n// putting logic that's not specific to the element type here, we\n// reduce binary bloat and increase compilation speed.\nclass GTEST_API_ UnorderedElementsAreMatcherImplBase {\n protected:\n  explicit UnorderedElementsAreMatcherImplBase(\n      UnorderedMatcherRequire::Flags matcher_flags)\n      : match_flags_(matcher_flags) {}\n\n  // A vector of matcher describers, one for each element matcher.\n  // Does not own the describers (and thus can be used only when the\n  // element matchers are alive).\n  typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec;\n\n  // Describes this UnorderedElementsAre matcher.\n  void DescribeToImpl(::std::ostream* os) const;\n\n  // Describes the negation of this UnorderedElementsAre matcher.\n  void DescribeNegationToImpl(::std::ostream* os) const;\n\n  bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,\n                         const MatchMatrix& matrix,\n                         MatchResultListener* listener) const;\n\n  bool FindPairing(const MatchMatrix& matrix,\n                   MatchResultListener* listener) const;\n\n  MatcherDescriberVec& matcher_describers() { return matcher_describers_; }\n\n  static Message Elements(size_t n) {\n    return Message() << n << \" element\" << (n == 1 ? \"\" : \"s\");\n  }\n\n  UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }\n\n private:\n  UnorderedMatcherRequire::Flags match_flags_;\n  MatcherDescriberVec matcher_describers_;\n};\n\n// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and\n// IsSupersetOf.\ntemplate <typename Container>\nclass UnorderedElementsAreMatcherImpl\n    : public MatcherInterface<Container>,\n      public UnorderedElementsAreMatcherImplBase {\n public:\n  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n  typedef internal::StlContainerView<RawContainer> View;\n  typedef typename View::type StlContainer;\n  typedef typename View::const_reference StlContainerReference;\n  typedef typename StlContainer::value_type Element;\n\n  template <typename InputIter>\n  UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,\n                                  InputIter first, InputIter last)\n      : UnorderedElementsAreMatcherImplBase(matcher_flags) {\n    for (; first != last; ++first) {\n      matchers_.push_back(MatcherCast<const Element&>(*first));\n    }\n    for (const auto& m : matchers_) {\n      matcher_describers().push_back(m.GetDescriber());\n    }\n  }\n\n  // Describes what this matcher does.\n  void DescribeTo(::std::ostream* os) const override {\n    return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);\n  }\n\n  // Describes what the negation of this matcher does.\n  void DescribeNegationTo(::std::ostream* os) const override {\n    return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);\n  }\n\n  bool MatchAndExplain(Container container,\n                       MatchResultListener* listener) const override {\n    StlContainerReference stl_container = View::ConstReference(container);\n    ::std::vector<std::string> element_printouts;\n    MatchMatrix matrix =\n        AnalyzeElements(stl_container.begin(), stl_container.end(),\n                        &element_printouts, listener);\n\n    return VerifyMatchMatrix(element_printouts, matrix, listener) &&\n           FindPairing(matrix, listener);\n  }\n\n private:\n  template <typename ElementIter>\n  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,\n                              ::std::vector<std::string>* element_printouts,\n                              MatchResultListener* listener) const {\n    element_printouts->clear();\n    ::std::vector<char> did_match;\n    size_t num_elements = 0;\n    DummyMatchResultListener dummy;\n    for (; elem_first != elem_last; ++num_elements, ++elem_first) {\n      if (listener->IsInterested()) {\n        element_printouts->push_back(PrintToString(*elem_first));\n      }\n      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {\n        did_match.push_back(\n            matchers_[irhs].MatchAndExplain(*elem_first, &dummy));\n      }\n    }\n\n    MatchMatrix matrix(num_elements, matchers_.size());\n    ::std::vector<char>::const_iterator did_match_iter = did_match.begin();\n    for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {\n      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {\n        matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);\n      }\n    }\n    return matrix;\n  }\n\n  ::std::vector<Matcher<const Element&>> matchers_;\n};\n\n// Functor for use in TransformTuple.\n// Performs MatcherCast<Target> on an input argument of any type.\ntemplate <typename Target>\nstruct CastAndAppendTransform {\n  template <typename Arg>\n  Matcher<Target> operator()(const Arg& a) const {\n    return MatcherCast<Target>(a);\n  }\n};\n\n// Implements UnorderedElementsAre.\ntemplate <typename MatcherTuple>\nclass UnorderedElementsAreMatcher {\n public:\n  explicit UnorderedElementsAreMatcher(const MatcherTuple& args)\n      : matchers_(args) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n    typedef typename internal::StlContainerView<RawContainer>::type View;\n    typedef typename View::value_type Element;\n    typedef ::std::vector<Matcher<const Element&>> MatcherVec;\n    MatcherVec matchers;\n    matchers.reserve(::std::tuple_size<MatcherTuple>::value);\n    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,\n                         ::std::back_inserter(matchers));\n    return Matcher<Container>(\n        new UnorderedElementsAreMatcherImpl<const Container&>(\n            UnorderedMatcherRequire::ExactMatch, matchers.begin(),\n            matchers.end()));\n  }\n\n private:\n  const MatcherTuple matchers_;\n};\n\n// Implements ElementsAre.\ntemplate <typename MatcherTuple>\nclass ElementsAreMatcher {\n public:\n  explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||\n            ::std::tuple_size<MatcherTuple>::value < 2,\n        \"use UnorderedElementsAre with hash tables\");\n\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;\n    typedef typename internal::StlContainerView<RawContainer>::type View;\n    typedef typename View::value_type Element;\n    typedef ::std::vector<Matcher<const Element&>> MatcherVec;\n    MatcherVec matchers;\n    matchers.reserve(::std::tuple_size<MatcherTuple>::value);\n    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,\n                         ::std::back_inserter(matchers));\n    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(\n        matchers.begin(), matchers.end()));\n  }\n\n private:\n  const MatcherTuple matchers_;\n};\n\n// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().\ntemplate <typename T>\nclass UnorderedElementsAreArrayMatcher {\n public:\n  template <typename Iter>\n  UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,\n                                   Iter first, Iter last)\n      : match_flags_(match_flags), matchers_(first, last) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    return Matcher<Container>(\n        new UnorderedElementsAreMatcherImpl<const Container&>(\n            match_flags_, matchers_.begin(), matchers_.end()));\n  }\n\n private:\n  UnorderedMatcherRequire::Flags match_flags_;\n  ::std::vector<T> matchers_;\n};\n\n// Implements ElementsAreArray().\ntemplate <typename T>\nclass ElementsAreArrayMatcher {\n public:\n  template <typename Iter>\n  ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}\n\n  template <typename Container>\n  operator Matcher<Container>() const {\n    static_assert(\n        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,\n        \"use UnorderedElementsAreArray with hash tables\");\n\n    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(\n        matchers_.begin(), matchers_.end()));\n  }\n\n private:\n  const ::std::vector<T> matchers_;\n};\n\n// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second\n// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,\n// second) is a polymorphic matcher that matches a value x if and only if\n// tm matches tuple (x, second).  Useful for implementing\n// UnorderedPointwise() in terms of UnorderedElementsAreArray().\n//\n// BoundSecondMatcher is copyable and assignable, as we need to put\n// instances of this class in a vector when implementing\n// UnorderedPointwise().\ntemplate <typename Tuple2Matcher, typename Second>\nclass BoundSecondMatcher {\n public:\n  BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)\n      : tuple2_matcher_(tm), second_value_(second) {}\n\n  BoundSecondMatcher(const BoundSecondMatcher& other) = default;\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));\n  }\n\n  // We have to define this for UnorderedPointwise() to compile in\n  // C++98 mode, as it puts BoundSecondMatcher instances in a vector,\n  // which requires the elements to be assignable in C++98.  The\n  // compiler cannot generate the operator= for us, as Tuple2Matcher\n  // and Second may not be assignable.\n  //\n  // However, this should never be called, so the implementation just\n  // need to assert.\n  void operator=(const BoundSecondMatcher& /*rhs*/) {\n    GTEST_LOG_(FATAL) << \"BoundSecondMatcher should never be assigned.\";\n  }\n\n private:\n  template <typename T>\n  class Impl : public MatcherInterface<T> {\n   public:\n    typedef ::std::tuple<T, Second> ArgTuple;\n\n    Impl(const Tuple2Matcher& tm, const Second& second)\n        : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),\n          second_value_(second) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"and \";\n      UniversalPrint(second_value_, os);\n      *os << \" \";\n      mono_tuple2_matcher_.DescribeTo(os);\n    }\n\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),\n                                                  listener);\n    }\n\n   private:\n    const Matcher<const ArgTuple&> mono_tuple2_matcher_;\n    const Second second_value_;\n  };\n\n  const Tuple2Matcher tuple2_matcher_;\n  const Second second_value_;\n};\n\n// Given a 2-tuple matcher tm and a value second,\n// MatcherBindSecond(tm, second) returns a matcher that matches a\n// value x if and only if tm matches tuple (x, second).  Useful for\n// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray().\ntemplate <typename Tuple2Matcher, typename Second>\nBoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(\n    const Tuple2Matcher& tm, const Second& second) {\n  return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);\n}\n\n// Returns the description for a matcher defined using the MATCHER*()\n// macro where the user-supplied description string is \"\", if\n// 'negation' is false; otherwise returns the description of the\n// negation of the matcher.  'param_values' contains a list of strings\n// that are the print-out of the matcher's parameters.\nGTEST_API_ std::string FormatMatcherDescription(\n    bool negation, const char* matcher_name,\n    const std::vector<const char*>& param_names, const Strings& param_values);\n\n// Implements a matcher that checks the value of a optional<> type variable.\ntemplate <typename ValueMatcher>\nclass OptionalMatcher {\n public:\n  explicit OptionalMatcher(const ValueMatcher& value_matcher)\n      : value_matcher_(value_matcher) {}\n\n  template <typename Optional>\n  operator Matcher<Optional>() const {\n    return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));\n  }\n\n  template <typename Optional>\n  class Impl : public MatcherInterface<Optional> {\n   public:\n    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;\n    typedef typename OptionalView::value_type ValueType;\n    explicit Impl(const ValueMatcher& value_matcher)\n        : value_matcher_(MatcherCast<ValueType>(value_matcher)) {}\n\n    void DescribeTo(::std::ostream* os) const override {\n      *os << \"value \";\n      value_matcher_.DescribeTo(os);\n    }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      *os << \"value \";\n      value_matcher_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(Optional optional,\n                         MatchResultListener* listener) const override {\n      if (!optional) {\n        *listener << \"which is not engaged\";\n        return false;\n      }\n      const ValueType& value = *optional;\n      StringMatchResultListener value_listener;\n      const bool match = value_matcher_.MatchAndExplain(value, &value_listener);\n      *listener << \"whose value \" << PrintToString(value)\n                << (match ? \" matches\" : \" doesn't match\");\n      PrintIfNotEmpty(value_listener.str(), listener->stream());\n      return match;\n    }\n\n   private:\n    const Matcher<ValueType> value_matcher_;\n  };\n\n private:\n  const ValueMatcher value_matcher_;\n};\n\nnamespace variant_matcher {\n// Overloads to allow VariantMatcher to do proper ADL lookup.\ntemplate <typename T>\nvoid holds_alternative() {}\ntemplate <typename T>\nvoid get() {}\n\n// Implements a matcher that checks the value of a variant<> type variable.\ntemplate <typename T>\nclass VariantMatcher {\n public:\n  explicit VariantMatcher(::testing::Matcher<const T&> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  template <typename Variant>\n  bool MatchAndExplain(const Variant& value,\n                       ::testing::MatchResultListener* listener) const {\n    using std::get;\n    if (!listener->IsInterested()) {\n      return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));\n    }\n\n    if (!holds_alternative<T>(value)) {\n      *listener << \"whose value is not of type '\" << GetTypeName() << \"'\";\n      return false;\n    }\n\n    const T& elem = get<T>(value);\n    StringMatchResultListener elem_listener;\n    const bool match = matcher_.MatchAndExplain(elem, &elem_listener);\n    *listener << \"whose value \" << PrintToString(elem)\n              << (match ? \" matches\" : \" doesn't match\");\n    PrintIfNotEmpty(elem_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"is a variant<> with value of type '\" << GetTypeName()\n        << \"' and the value \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"is a variant<> with value of type other than '\" << GetTypeName()\n        << \"' or the value \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  static std::string GetTypeName() {\n#if GTEST_HAS_RTTI\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(\n        return internal::GetTypeName<T>());\n#endif\n    return \"the element type\";\n  }\n\n  const ::testing::Matcher<const T&> matcher_;\n};\n\n}  // namespace variant_matcher\n\nnamespace any_cast_matcher {\n\n// Overloads to allow AnyCastMatcher to do proper ADL lookup.\ntemplate <typename T>\nvoid any_cast() {}\n\n// Implements a matcher that any_casts the value.\ntemplate <typename T>\nclass AnyCastMatcher {\n public:\n  explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)\n      : matcher_(matcher) {}\n\n  template <typename AnyType>\n  bool MatchAndExplain(const AnyType& value,\n                       ::testing::MatchResultListener* listener) const {\n    if (!listener->IsInterested()) {\n      const T* ptr = any_cast<T>(&value);\n      return ptr != nullptr && matcher_.Matches(*ptr);\n    }\n\n    const T* elem = any_cast<T>(&value);\n    if (elem == nullptr) {\n      *listener << \"whose value is not of type '\" << GetTypeName() << \"'\";\n      return false;\n    }\n\n    StringMatchResultListener elem_listener;\n    const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);\n    *listener << \"whose value \" << PrintToString(*elem)\n              << (match ? \" matches\" : \" doesn't match\");\n    PrintIfNotEmpty(elem_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"is an 'any' type with value of type '\" << GetTypeName()\n        << \"' and the value \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"is an 'any' type with value of type other than '\" << GetTypeName()\n        << \"' or the value \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  static std::string GetTypeName() {\n#if GTEST_HAS_RTTI\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(\n        return internal::GetTypeName<T>());\n#endif\n    return \"the element type\";\n  }\n\n  const ::testing::Matcher<const T&> matcher_;\n};\n\n}  // namespace any_cast_matcher\n\n// Implements the Args() matcher.\ntemplate <class ArgsTuple, size_t... k>\nclass ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {\n public:\n  using RawArgsTuple = typename std::decay<ArgsTuple>::type;\n  using SelectedArgs =\n      std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>;\n  using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>;\n\n  template <typename InnerMatcher>\n  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)\n      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}\n\n  bool MatchAndExplain(ArgsTuple args,\n                       MatchResultListener* listener) const override {\n    // Workaround spurious C4100 on MSVC<=15.7 when k is empty.\n    (void)args;\n    const SelectedArgs& selected_args =\n        std::forward_as_tuple(std::get<k>(args)...);\n    if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args);\n\n    PrintIndices(listener->stream());\n    *listener << \"are \" << PrintToString(selected_args);\n\n    StringMatchResultListener inner_listener;\n    const bool match =\n        inner_matcher_.MatchAndExplain(selected_args, &inner_listener);\n    PrintIfNotEmpty(inner_listener.str(), listener->stream());\n    return match;\n  }\n\n  void DescribeTo(::std::ostream* os) const override {\n    *os << \"are a tuple \";\n    PrintIndices(os);\n    inner_matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const override {\n    *os << \"are a tuple \";\n    PrintIndices(os);\n    inner_matcher_.DescribeNegationTo(os);\n  }\n\n private:\n  // Prints the indices of the selected fields.\n  static void PrintIndices(::std::ostream* os) {\n    *os << \"whose fields (\";\n    const char* sep = \"\";\n    // Workaround spurious C4189 on MSVC<=15.7 when k is empty.\n    (void)sep;\n    // The static_cast to void is needed to silence Clang's -Wcomma warning.\n    // This pattern looks suspiciously like we may have mismatched parentheses\n    // and may have been trying to use the first operation of the comma operator\n    // as a member of the array, so Clang warns that we may have made a mistake.\n    const char* dummy[] = {\n        \"\", (static_cast<void>(*os << sep << \"#\" << k), sep = \", \")...};\n    (void)dummy;\n    *os << \") \";\n  }\n\n  MonomorphicInnerMatcher inner_matcher_;\n};\n\ntemplate <class InnerMatcher, size_t... k>\nclass ArgsMatcher {\n public:\n  explicit ArgsMatcher(InnerMatcher inner_matcher)\n      : inner_matcher_(std::move(inner_matcher)) {}\n\n  template <typename ArgsTuple>\n  operator Matcher<ArgsTuple>() const {  // NOLINT\n    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_));\n  }\n\n private:\n  InnerMatcher inner_matcher_;\n};\n\n}  // namespace internal\n\n// ElementsAreArray(iterator_first, iterator_last)\n// ElementsAreArray(pointer, count)\n// ElementsAreArray(array)\n// ElementsAreArray(container)\n// ElementsAreArray({ e1, e2, ..., en })\n//\n// The ElementsAreArray() functions are like ElementsAre(...), except\n// that they are given a homogeneous sequence rather than taking each\n// element as a function argument. The sequence can be specified as an\n// array, a pointer and count, a vector, an initializer list, or an\n// STL iterator range. In each of these cases, the underlying sequence\n// can be either a sequence of values or a sequence of matchers.\n//\n// All forms of ElementsAreArray() make a copy of the input matcher sequence.\n\ntemplate <typename Iter>\ninline internal::ElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nElementsAreArray(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::ElementsAreArrayMatcher<T>(first, last);\n}\n\ntemplate <typename T>\ninline auto ElementsAreArray(const T* pointer, size_t count)\n    -> decltype(ElementsAreArray(pointer, pointer + count)) {\n  return ElementsAreArray(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline auto ElementsAreArray(const T (&array)[N])\n    -> decltype(ElementsAreArray(array, N)) {\n  return ElementsAreArray(array, N);\n}\n\ntemplate <typename Container>\ninline auto ElementsAreArray(const Container& container)\n    -> decltype(ElementsAreArray(container.begin(), container.end())) {\n  return ElementsAreArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline auto ElementsAreArray(::std::initializer_list<T> xs)\n    -> decltype(ElementsAreArray(xs.begin(), xs.end())) {\n  return ElementsAreArray(xs.begin(), xs.end());\n}\n\n// UnorderedElementsAreArray(iterator_first, iterator_last)\n// UnorderedElementsAreArray(pointer, count)\n// UnorderedElementsAreArray(array)\n// UnorderedElementsAreArray(container)\n// UnorderedElementsAreArray({ e1, e2, ..., en })\n//\n// UnorderedElementsAreArray() verifies that a bijective mapping onto a\n// collection of matchers exists.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nUnorderedElementsAreArray(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::ExactMatch, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    const T* pointer, size_t count) {\n  return UnorderedElementsAreArray(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    const T (&array)[N]) {\n  return UnorderedElementsAreArray(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nUnorderedElementsAreArray(const Container& container) {\n  return UnorderedElementsAreArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(\n    ::std::initializer_list<T> xs) {\n  return UnorderedElementsAreArray(xs.begin(), xs.end());\n}\n\n// _ is a matcher that matches anything of any type.\n//\n// This definition is fine as:\n//\n//   1. The C++ standard permits using the name _ in a namespace that\n//      is not the global namespace or ::std.\n//   2. The AnythingMatcher class has no data member or constructor,\n//      so it's OK to create global variables of this type.\n//   3. c-style has approved of using _ in this case.\nconst internal::AnythingMatcher _ = {};\n// Creates a matcher that matches any value of the given type T.\ntemplate <typename T>\ninline Matcher<T> A() {\n  return _;\n}\n\n// Creates a matcher that matches any value of the given type T.\ntemplate <typename T>\ninline Matcher<T> An() {\n  return _;\n}\n\ntemplate <typename T, typename M>\nMatcher<T> internal::MatcherCastImpl<T, M>::CastImpl(\n    const M& value, std::false_type /* convertible_to_matcher */,\n    std::false_type /* convertible_to_T */) {\n  return Eq(value);\n}\n\n// Creates a polymorphic matcher that matches any NULL pointer.\ninline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {\n  return MakePolymorphicMatcher(internal::IsNullMatcher());\n}\n\n// Creates a polymorphic matcher that matches any non-NULL pointer.\n// This is convenient as Not(NULL) doesn't compile (the compiler\n// thinks that that expression is comparing a pointer with an integer).\ninline PolymorphicMatcher<internal::NotNullMatcher> NotNull() {\n  return MakePolymorphicMatcher(internal::NotNullMatcher());\n}\n\n// Creates a polymorphic matcher that matches any argument that\n// references variable x.\ntemplate <typename T>\ninline internal::RefMatcher<T&> Ref(T& x) {  // NOLINT\n  return internal::RefMatcher<T&>(x);\n}\n\n// Creates a polymorphic matcher that matches any NaN floating point.\ninline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {\n  return MakePolymorphicMatcher(internal::IsNanMatcher());\n}\n\n// Creates a matcher that matches any double argument approximately\n// equal to rhs, where two NANs are considered unequal.\ninline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {\n  return internal::FloatingEqMatcher<double>(rhs, false);\n}\n\n// Creates a matcher that matches any double argument approximately\n// equal to rhs, including NaN values when rhs is NaN.\ninline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {\n  return internal::FloatingEqMatcher<double>(rhs, true);\n}\n\n// Creates a matcher that matches any double argument approximately equal to\n// rhs, up to the specified max absolute error bound, where two NANs are\n// considered unequal.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<double> DoubleNear(double rhs,\n                                                      double max_abs_error) {\n  return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);\n}\n\n// Creates a matcher that matches any double argument approximately equal to\n// rhs, up to the specified max absolute error bound, including NaN values when\n// rhs is NaN.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear(\n    double rhs, double max_abs_error) {\n  return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error);\n}\n\n// Creates a matcher that matches any float argument approximately\n// equal to rhs, where two NANs are considered unequal.\ninline internal::FloatingEqMatcher<float> FloatEq(float rhs) {\n  return internal::FloatingEqMatcher<float>(rhs, false);\n}\n\n// Creates a matcher that matches any float argument approximately\n// equal to rhs, including NaN values when rhs is NaN.\ninline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {\n  return internal::FloatingEqMatcher<float>(rhs, true);\n}\n\n// Creates a matcher that matches any float argument approximately equal to\n// rhs, up to the specified max absolute error bound, where two NANs are\n// considered unequal.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<float> FloatNear(float rhs,\n                                                    float max_abs_error) {\n  return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error);\n}\n\n// Creates a matcher that matches any float argument approximately equal to\n// rhs, up to the specified max absolute error bound, including NaN values when\n// rhs is NaN.  The max absolute error bound must be non-negative.\ninline internal::FloatingEqMatcher<float> NanSensitiveFloatNear(\n    float rhs, float max_abs_error) {\n  return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error);\n}\n\n// Creates a matcher that matches a pointer (raw or smart) that points\n// to a value that matches inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::PointeeMatcher<InnerMatcher> Pointee(\n    const InnerMatcher& inner_matcher) {\n  return internal::PointeeMatcher<InnerMatcher>(inner_matcher);\n}\n\n#if GTEST_HAS_RTTI\n// Creates a matcher that matches a pointer or reference that matches\n// inner_matcher when dynamic_cast<To> is applied.\n// The result of dynamic_cast<To> is forwarded to the inner matcher.\n// If To is a pointer and the cast fails, the inner matcher will receive NULL.\n// If To is a reference and the cast fails, this matcher returns false\n// immediately.\ntemplate <typename To>\ninline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To>>\nWhenDynamicCastTo(const Matcher<To>& inner_matcher) {\n  return MakePolymorphicMatcher(\n      internal::WhenDynamicCastToMatcher<To>(inner_matcher));\n}\n#endif  // GTEST_HAS_RTTI\n\n// Creates a matcher that matches an object whose given field matches\n// 'matcher'.  For example,\n//   Field(&Foo::number, Ge(5))\n// matches a Foo object x if and only if x.number >= 5.\ntemplate <typename Class, typename FieldType, typename FieldMatcher>\ninline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(\n    FieldType Class::*field, const FieldMatcher& matcher) {\n  return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(\n      field, MatcherCast<const FieldType&>(matcher)));\n  // The call to MatcherCast() is required for supporting inner\n  // matchers of compatible types.  For example, it allows\n  //   Field(&Foo::bar, m)\n  // to compile where bar is an int32 and m is a matcher for int64.\n}\n\n// Same as Field() but also takes the name of the field to provide better error\n// messages.\ntemplate <typename Class, typename FieldType, typename FieldMatcher>\ninline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(\n    const std::string& field_name, FieldType Class::*field,\n    const FieldMatcher& matcher) {\n  return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(\n      field_name, field, MatcherCast<const FieldType&>(matcher)));\n}\n\n// Creates a matcher that matches an object whose given property\n// matches 'matcher'.  For example,\n//   Property(&Foo::str, StartsWith(\"hi\"))\n// matches a Foo object x if and only if x.str() starts with \"hi\".\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const>>\nProperty(PropertyType (Class::*property)() const,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const>(\n          property, MatcherCast<const PropertyType&>(matcher)));\n  // The call to MatcherCast() is required for supporting inner\n  // matchers of compatible types.  For example, it allows\n  //   Property(&Foo::bar, m)\n  // to compile where bar() returns an int32 and m is a matcher for int64.\n}\n\n// Same as Property() above, but also takes the name of the property to provide\n// better error messages.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const>>\nProperty(const std::string& property_name,\n         PropertyType (Class::*property)() const,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const>(\n          property_name, property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// The same as above but for reference-qualified member functions.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const&>>\nProperty(PropertyType (Class::*property)() const&,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const&>(\n          property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// Three-argument form for reference-qualified member functions.\ntemplate <typename Class, typename PropertyType, typename PropertyMatcher>\ninline PolymorphicMatcher<internal::PropertyMatcher<\n    Class, PropertyType, PropertyType (Class::*)() const&>>\nProperty(const std::string& property_name,\n         PropertyType (Class::*property)() const&,\n         const PropertyMatcher& matcher) {\n  return MakePolymorphicMatcher(\n      internal::PropertyMatcher<Class, PropertyType,\n                                PropertyType (Class::*)() const&>(\n          property_name, property, MatcherCast<const PropertyType&>(matcher)));\n}\n\n// Creates a matcher that matches an object if and only if the result of\n// applying a callable to x matches 'matcher'. For example,\n//   ResultOf(f, StartsWith(\"hi\"))\n// matches a Foo object x if and only if f(x) starts with \"hi\".\n// `callable` parameter can be a function, function pointer, or a functor. It is\n// required to keep no state affecting the results of the calls on it and make\n// no assumptions about how many calls will be made. Any state it keeps must be\n// protected from the concurrent access.\ntemplate <typename Callable, typename InnerMatcher>\ninternal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(\n    Callable callable, InnerMatcher matcher) {\n  return internal::ResultOfMatcher<Callable, InnerMatcher>(std::move(callable),\n                                                           std::move(matcher));\n}\n\n// Same as ResultOf() above, but also takes a description of the `callable`\n// result to provide better error messages.\ntemplate <typename Callable, typename InnerMatcher>\ninternal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(\n    const std::string& result_description, Callable callable,\n    InnerMatcher matcher) {\n  return internal::ResultOfMatcher<Callable, InnerMatcher>(\n      result_description, std::move(callable), std::move(matcher));\n}\n\n// String matchers.\n\n// Matches a string equal to str.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrEq(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), true, true));\n}\n\n// Matches a string not equal to str.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrNe(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), false, true));\n}\n\n// Matches a string equal to str, ignoring case.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseEq(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::string>(std::string(str), true, false));\n}\n\n// Matches a string not equal to str, ignoring case.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseNe(\n    const internal::StringLike<T>& str) {\n  return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>(\n      std::string(str), false, false));\n}\n\n// Creates a matcher that matches any string, std::string, or C string\n// that contains the given substring.\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::HasSubstrMatcher<std::string>> HasSubstr(\n    const internal::StringLike<T>& substring) {\n  return MakePolymorphicMatcher(\n      internal::HasSubstrMatcher<std::string>(std::string(substring)));\n}\n\n// Matches a string that starts with 'prefix' (case-sensitive).\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::StartsWithMatcher<std::string>> StartsWith(\n    const internal::StringLike<T>& prefix) {\n  return MakePolymorphicMatcher(\n      internal::StartsWithMatcher<std::string>(std::string(prefix)));\n}\n\n// Matches a string that ends with 'suffix' (case-sensitive).\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::EndsWithMatcher<std::string>> EndsWith(\n    const internal::StringLike<T>& suffix) {\n  return MakePolymorphicMatcher(\n      internal::EndsWithMatcher<std::string>(std::string(suffix)));\n}\n\n#if GTEST_HAS_STD_WSTRING\n// Wide string matchers.\n\n// Matches a string equal to str.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrEq(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, true, true));\n}\n\n// Matches a string not equal to str.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrNe(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, false, true));\n}\n\n// Matches a string equal to str, ignoring case.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseEq(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, true, false));\n}\n\n// Matches a string not equal to str, ignoring case.\ninline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseNe(\n    const std::wstring& str) {\n  return MakePolymorphicMatcher(\n      internal::StrEqualityMatcher<std::wstring>(str, false, false));\n}\n\n// Creates a matcher that matches any ::wstring, std::wstring, or C wide string\n// that contains the given substring.\ninline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring>> HasSubstr(\n    const std::wstring& substring) {\n  return MakePolymorphicMatcher(\n      internal::HasSubstrMatcher<std::wstring>(substring));\n}\n\n// Matches a string that starts with 'prefix' (case-sensitive).\ninline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring>> StartsWith(\n    const std::wstring& prefix) {\n  return MakePolymorphicMatcher(\n      internal::StartsWithMatcher<std::wstring>(prefix));\n}\n\n// Matches a string that ends with 'suffix' (case-sensitive).\ninline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring>> EndsWith(\n    const std::wstring& suffix) {\n  return MakePolymorphicMatcher(\n      internal::EndsWithMatcher<std::wstring>(suffix));\n}\n\n#endif  // GTEST_HAS_STD_WSTRING\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field == the second field.\ninline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field >= the second field.\ninline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field > the second field.\ninline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field <= the second field.\ninline internal::Le2Matcher Le() { return internal::Le2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field < the second field.\ninline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where the\n// first field != the second field.\ninline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatEq(first field) matches the second field.\ninline internal::FloatingEq2Matcher<float> FloatEq() {\n  return internal::FloatingEq2Matcher<float>();\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleEq(first field) matches the second field.\ninline internal::FloatingEq2Matcher<double> DoubleEq() {\n  return internal::FloatingEq2Matcher<double>();\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatEq(first field) matches the second field with NaN equality.\ninline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {\n  return internal::FloatingEq2Matcher<float>(true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleEq(first field) matches the second field with NaN equality.\ninline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {\n  return internal::FloatingEq2Matcher<double>(true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatNear(first field, max_abs_error) matches the second field.\ninline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {\n  return internal::FloatingEq2Matcher<float>(max_abs_error);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleNear(first field, max_abs_error) matches the second field.\ninline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {\n  return internal::FloatingEq2Matcher<double>(max_abs_error);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// FloatNear(first field, max_abs_error) matches the second field with NaN\n// equality.\ninline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(\n    float max_abs_error) {\n  return internal::FloatingEq2Matcher<float>(max_abs_error, true);\n}\n\n// Creates a polymorphic matcher that matches a 2-tuple where\n// DoubleNear(first field, max_abs_error) matches the second field with NaN\n// equality.\ninline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(\n    double max_abs_error) {\n  return internal::FloatingEq2Matcher<double>(max_abs_error, true);\n}\n\n// Creates a matcher that matches any value of type T that m doesn't\n// match.\ntemplate <typename InnerMatcher>\ninline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {\n  return internal::NotMatcher<InnerMatcher>(m);\n}\n\n// Returns a matcher that matches anything that satisfies the given\n// predicate.  The predicate can be any unary function or functor\n// whose return type can be implicitly converted to bool.\ntemplate <typename Predicate>\ninline PolymorphicMatcher<internal::TrulyMatcher<Predicate>> Truly(\n    Predicate pred) {\n  return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));\n}\n\n// Returns a matcher that matches the container size. The container must\n// support both size() and size_type which all STL-like containers provide.\n// Note that the parameter 'size' can be a value of type size_type as well as\n// matcher. For instance:\n//   EXPECT_THAT(container, SizeIs(2));     // Checks container has 2 elements.\n//   EXPECT_THAT(container, SizeIs(Le(2));  // Checks container has at most 2.\ntemplate <typename SizeMatcher>\ninline internal::SizeIsMatcher<SizeMatcher> SizeIs(\n    const SizeMatcher& size_matcher) {\n  return internal::SizeIsMatcher<SizeMatcher>(size_matcher);\n}\n\n// Returns a matcher that matches the distance between the container's begin()\n// iterator and its end() iterator, i.e. the size of the container. This matcher\n// can be used instead of SizeIs with containers such as std::forward_list which\n// do not implement size(). The container must provide const_iterator (with\n// valid iterator_traits), begin() and end().\ntemplate <typename DistanceMatcher>\ninline internal::BeginEndDistanceIsMatcher<DistanceMatcher> BeginEndDistanceIs(\n    const DistanceMatcher& distance_matcher) {\n  return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);\n}\n\n// Returns a matcher that matches an equal container.\n// This matcher behaves like Eq(), but in the event of mismatch lists the\n// values that are included in one container but not the other. (Duplicate\n// values and order differences are not explained.)\ntemplate <typename Container>\ninline PolymorphicMatcher<\n    internal::ContainerEqMatcher<typename std::remove_const<Container>::type>>\nContainerEq(const Container& rhs) {\n  return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));\n}\n\n// Returns a matcher that matches a container that, when sorted using\n// the given comparator, matches container_matcher.\ntemplate <typename Comparator, typename ContainerMatcher>\ninline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> WhenSortedBy(\n    const Comparator& comparator, const ContainerMatcher& container_matcher) {\n  return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(\n      comparator, container_matcher);\n}\n\n// Returns a matcher that matches a container that, when sorted using\n// the < operator, matches container_matcher.\ntemplate <typename ContainerMatcher>\ninline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>\nWhenSorted(const ContainerMatcher& container_matcher) {\n  return internal::WhenSortedByMatcher<internal::LessComparator,\n                                       ContainerMatcher>(\n      internal::LessComparator(), container_matcher);\n}\n\n// Matches an STL-style container or a native array that contains the\n// same number of elements as in rhs, where its i-th element and rhs's\n// i-th element (as a pair) satisfy the given pair matcher, for all i.\n// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const\n// T1&, const T2&> >, where T1 and T2 are the types of elements in the\n// LHS container and the RHS container respectively.\ntemplate <typename TupleMatcher, typename Container>\ninline internal::PointwiseMatcher<TupleMatcher,\n                                  typename std::remove_const<Container>::type>\nPointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {\n  return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,\n                                                             rhs);\n}\n\n// Supports the Pointwise(m, {a, b, c}) syntax.\ntemplate <typename TupleMatcher, typename T>\ninline internal::PointwiseMatcher<TupleMatcher, std::vector<T>> Pointwise(\n    const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {\n  return Pointwise(tuple_matcher, std::vector<T>(rhs));\n}\n\n// UnorderedPointwise(pair_matcher, rhs) matches an STL-style\n// container or a native array that contains the same number of\n// elements as in rhs, where in some permutation of the container, its\n// i-th element and rhs's i-th element (as a pair) satisfy the given\n// pair matcher, for all i.  Tuple2Matcher must be able to be safely\n// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are\n// the types of elements in the LHS container and the RHS container\n// respectively.\n//\n// This is like Pointwise(pair_matcher, rhs), except that the element\n// order doesn't matter.\ntemplate <typename Tuple2Matcher, typename RhsContainer>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename internal::BoundSecondMatcher<\n        Tuple2Matcher,\n        typename internal::StlContainerView<\n            typename std::remove_const<RhsContainer>::type>::type::value_type>>\nUnorderedPointwise(const Tuple2Matcher& tuple2_matcher,\n                   const RhsContainer& rhs_container) {\n  // RhsView allows the same code to handle RhsContainer being a\n  // STL-style container and it being a native C-style array.\n  typedef typename internal::StlContainerView<RhsContainer> RhsView;\n  typedef typename RhsView::type RhsStlContainer;\n  typedef typename RhsStlContainer::value_type Second;\n  const RhsStlContainer& rhs_stl_container =\n      RhsView::ConstReference(rhs_container);\n\n  // Create a matcher for each element in rhs_container.\n  ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second>> matchers;\n  for (auto it = rhs_stl_container.begin(); it != rhs_stl_container.end();\n       ++it) {\n    matchers.push_back(internal::MatcherBindSecond(tuple2_matcher, *it));\n  }\n\n  // Delegate the work to UnorderedElementsAreArray().\n  return UnorderedElementsAreArray(matchers);\n}\n\n// Supports the UnorderedPointwise(m, {a, b, c}) syntax.\ntemplate <typename Tuple2Matcher, typename T>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename internal::BoundSecondMatcher<Tuple2Matcher, T>>\nUnorderedPointwise(const Tuple2Matcher& tuple2_matcher,\n                   std::initializer_list<T> rhs) {\n  return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));\n}\n\n// Matches an STL-style container or a native array that contains at\n// least one element matching the given value or matcher.\n//\n// Examples:\n//   ::std::set<int> page_ids;\n//   page_ids.insert(3);\n//   page_ids.insert(1);\n//   EXPECT_THAT(page_ids, Contains(1));\n//   EXPECT_THAT(page_ids, Contains(Gt(2)));\n//   EXPECT_THAT(page_ids, Not(Contains(4)));  // See below for Times(0)\n//\n//   ::std::map<int, size_t> page_lengths;\n//   page_lengths[1] = 100;\n//   EXPECT_THAT(page_lengths,\n//               Contains(::std::pair<const int, size_t>(1, 100)));\n//\n//   const char* user_ids[] = { \"joe\", \"mike\", \"tom\" };\n//   EXPECT_THAT(user_ids, Contains(Eq(::std::string(\"tom\"))));\n//\n// The matcher supports a modifier `Times` that allows to check for arbitrary\n// occurrences including testing for absence with Times(0).\n//\n// Examples:\n//   ::std::vector<int> ids;\n//   ids.insert(1);\n//   ids.insert(1);\n//   ids.insert(3);\n//   EXPECT_THAT(ids, Contains(1).Times(2));      // 1 occurs 2 times\n//   EXPECT_THAT(ids, Contains(2).Times(0));      // 2 is not present\n//   EXPECT_THAT(ids, Contains(3).Times(Ge(1)));  // 3 occurs at least once\n\ntemplate <typename M>\ninline internal::ContainsMatcher<M> Contains(M matcher) {\n  return internal::ContainsMatcher<M>(matcher);\n}\n\n// IsSupersetOf(iterator_first, iterator_last)\n// IsSupersetOf(pointer, count)\n// IsSupersetOf(array)\n// IsSupersetOf(container)\n// IsSupersetOf({e1, e2, ..., en})\n//\n// IsSupersetOf() verifies that a surjective partial mapping onto a collection\n// of matchers exists. In other words, a container matches\n// IsSupersetOf({e1, ..., en}) if and only if there is a permutation\n// {y1, ..., yn} of some of the container's elements where y1 matches e1,\n// ..., and yn matches en. Obviously, the size of the container must be >= n\n// in order to have a match. Examples:\n//\n// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and\n//   1 matches Ne(0).\n// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches\n//   both Eq(1) and Lt(2). The reason is that different matchers must be used\n//   for elements in different slots of the container.\n// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches\n//   Eq(1) and (the second) 1 matches Lt(2).\n// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)\n//   Gt(1) and 3 matches (the second) Gt(1).\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nIsSupersetOf(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::Superset, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    const T* pointer, size_t count) {\n  return IsSupersetOf(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    const T (&array)[N]) {\n  return IsSupersetOf(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nIsSupersetOf(const Container& container) {\n  return IsSupersetOf(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(\n    ::std::initializer_list<T> xs) {\n  return IsSupersetOf(xs.begin(), xs.end());\n}\n\n// IsSubsetOf(iterator_first, iterator_last)\n// IsSubsetOf(pointer, count)\n// IsSubsetOf(array)\n// IsSubsetOf(container)\n// IsSubsetOf({e1, e2, ..., en})\n//\n// IsSubsetOf() verifies that an injective mapping onto a collection of matchers\n// exists.  In other words, a container matches IsSubsetOf({e1, ..., en}) if and\n// only if there is a subset of matchers {m1, ..., mk} which would match the\n// container using UnorderedElementsAre.  Obviously, the size of the container\n// must be <= n in order to have a match. Examples:\n//\n// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).\n// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1\n//   matches Lt(0).\n// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both\n//   match Gt(0). The reason is that different matchers must be used for\n//   elements in different slots of the container.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nIsSubsetOf(Iter first, Iter last) {\n  typedef typename ::std::iterator_traits<Iter>::value_type T;\n  return internal::UnorderedElementsAreArrayMatcher<T>(\n      internal::UnorderedMatcherRequire::Subset, first, last);\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    const T* pointer, size_t count) {\n  return IsSubsetOf(pointer, pointer + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    const T (&array)[N]) {\n  return IsSubsetOf(array, N);\n}\n\ntemplate <typename Container>\ninline internal::UnorderedElementsAreArrayMatcher<\n    typename Container::value_type>\nIsSubsetOf(const Container& container) {\n  return IsSubsetOf(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(\n    ::std::initializer_list<T> xs) {\n  return IsSubsetOf(xs.begin(), xs.end());\n}\n\n// Matches an STL-style container or a native array that contains only\n// elements matching the given value or matcher.\n//\n// Each(m) is semantically equivalent to `Not(Contains(Not(m)))`. Only\n// the messages are different.\n//\n// Examples:\n//   ::std::set<int> page_ids;\n//   // Each(m) matches an empty container, regardless of what m is.\n//   EXPECT_THAT(page_ids, Each(Eq(1)));\n//   EXPECT_THAT(page_ids, Each(Eq(77)));\n//\n//   page_ids.insert(3);\n//   EXPECT_THAT(page_ids, Each(Gt(0)));\n//   EXPECT_THAT(page_ids, Not(Each(Gt(4))));\n//   page_ids.insert(1);\n//   EXPECT_THAT(page_ids, Not(Each(Lt(2))));\n//\n//   ::std::map<int, size_t> page_lengths;\n//   page_lengths[1] = 100;\n//   page_lengths[2] = 200;\n//   page_lengths[3] = 300;\n//   EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));\n//   EXPECT_THAT(page_lengths, Each(Key(Le(3))));\n//\n//   const char* user_ids[] = { \"joe\", \"mike\", \"tom\" };\n//   EXPECT_THAT(user_ids, Not(Each(Eq(::std::string(\"tom\")))));\ntemplate <typename M>\ninline internal::EachMatcher<M> Each(M matcher) {\n  return internal::EachMatcher<M>(matcher);\n}\n\n// Key(inner_matcher) matches an std::pair whose 'first' field matches\n// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an\n// std::map that contains at least one element whose key is >= 5.\ntemplate <typename M>\ninline internal::KeyMatcher<M> Key(M inner_matcher) {\n  return internal::KeyMatcher<M>(inner_matcher);\n}\n\n// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field\n// matches first_matcher and whose 'second' field matches second_matcher.  For\n// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), \"foo\"))) can be used\n// to match a std::map<int, string> that contains exactly one element whose key\n// is >= 5 and whose value equals \"foo\".\ntemplate <typename FirstMatcher, typename SecondMatcher>\ninline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair(\n    FirstMatcher first_matcher, SecondMatcher second_matcher) {\n  return internal::PairMatcher<FirstMatcher, SecondMatcher>(first_matcher,\n                                                            second_matcher);\n}\n\nnamespace no_adl {\n// Conditional() creates a matcher that conditionally uses either the first or\n// second matcher provided. For example, we could create an `equal if, and only\n// if' matcher using the Conditional wrapper as follows:\n//\n//   EXPECT_THAT(result, Conditional(condition, Eq(expected), Ne(expected)));\ntemplate <typename MatcherTrue, typename MatcherFalse>\ninternal::ConditionalMatcher<MatcherTrue, MatcherFalse> Conditional(\n    bool condition, MatcherTrue matcher_true, MatcherFalse matcher_false) {\n  return internal::ConditionalMatcher<MatcherTrue, MatcherFalse>(\n      condition, std::move(matcher_true), std::move(matcher_false));\n}\n\n// FieldsAre(matchers...) matches piecewise the fields of compatible structs.\n// These include those that support `get<I>(obj)`, and when structured bindings\n// are enabled any class that supports them.\n// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types.\ntemplate <typename... M>\ninternal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre(\n    M&&... matchers) {\n  return internal::FieldsAreMatcher<typename std::decay<M>::type...>(\n      std::forward<M>(matchers)...);\n}\n\n// Creates a matcher that matches a pointer (raw or smart) that matches\n// inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::PointerMatcher<InnerMatcher> Pointer(\n    const InnerMatcher& inner_matcher) {\n  return internal::PointerMatcher<InnerMatcher>(inner_matcher);\n}\n\n// Creates a matcher that matches an object that has an address that matches\n// inner_matcher.\ntemplate <typename InnerMatcher>\ninline internal::AddressMatcher<InnerMatcher> Address(\n    const InnerMatcher& inner_matcher) {\n  return internal::AddressMatcher<InnerMatcher>(inner_matcher);\n}\n\n// Matches a base64 escaped string, when the unescaped string matches the\n// internal matcher.\ntemplate <typename MatcherType>\ninternal::WhenBase64UnescapedMatcher WhenBase64Unescaped(\n    const MatcherType& internal_matcher) {\n  return internal::WhenBase64UnescapedMatcher(internal_matcher);\n}\n}  // namespace no_adl\n\n// Returns a predicate that is satisfied by anything that matches the\n// given matcher.\ntemplate <typename M>\ninline internal::MatcherAsPredicate<M> Matches(M matcher) {\n  return internal::MatcherAsPredicate<M>(matcher);\n}\n\n// Returns true if and only if the value matches the matcher.\ntemplate <typename T, typename M>\ninline bool Value(const T& value, M matcher) {\n  return testing::Matches(matcher)(value);\n}\n\n// Matches the value against the given matcher and explains the match\n// result to listener.\ntemplate <typename T, typename M>\ninline bool ExplainMatchResult(M matcher, const T& value,\n                               MatchResultListener* listener) {\n  return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);\n}\n\n// Returns a string representation of the given matcher.  Useful for description\n// strings of matchers defined using MATCHER_P* macros that accept matchers as\n// their arguments.  For example:\n//\n// MATCHER_P(XAndYThat, matcher,\n//           \"X that \" + DescribeMatcher<int>(matcher, negation) +\n//               (negation ? \" or\" : \" and\") + \" Y that \" +\n//               DescribeMatcher<double>(matcher, negation)) {\n//   return ExplainMatchResult(matcher, arg.x(), result_listener) &&\n//          ExplainMatchResult(matcher, arg.y(), result_listener);\n// }\ntemplate <typename T, typename M>\nstd::string DescribeMatcher(const M& matcher, bool negation = false) {\n  ::std::stringstream ss;\n  Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);\n  if (negation) {\n    monomorphic_matcher.DescribeNegationTo(&ss);\n  } else {\n    monomorphic_matcher.DescribeTo(&ss);\n  }\n  return ss.str();\n}\n\ntemplate <typename... Args>\ninternal::ElementsAreMatcher<\n    std::tuple<typename std::decay<const Args&>::type...>>\nElementsAre(const Args&... matchers) {\n  return internal::ElementsAreMatcher<\n      std::tuple<typename std::decay<const Args&>::type...>>(\n      std::make_tuple(matchers...));\n}\n\ntemplate <typename... Args>\ninternal::UnorderedElementsAreMatcher<\n    std::tuple<typename std::decay<const Args&>::type...>>\nUnorderedElementsAre(const Args&... matchers) {\n  return internal::UnorderedElementsAreMatcher<\n      std::tuple<typename std::decay<const Args&>::type...>>(\n      std::make_tuple(matchers...));\n}\n\n// Define variadic matcher versions.\ntemplate <typename... Args>\ninternal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(\n    const Args&... matchers) {\n  return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(\n      matchers...);\n}\n\ntemplate <typename... Args>\ninternal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(\n    const Args&... matchers) {\n  return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(\n      matchers...);\n}\n\n// AnyOfArray(array)\n// AnyOfArray(pointer, count)\n// AnyOfArray(container)\n// AnyOfArray({ e1, e2, ..., en })\n// AnyOfArray(iterator_first, iterator_last)\n//\n// AnyOfArray() verifies whether a given value matches any member of a\n// collection of matchers.\n//\n// AllOfArray(array)\n// AllOfArray(pointer, count)\n// AllOfArray(container)\n// AllOfArray({ e1, e2, ..., en })\n// AllOfArray(iterator_first, iterator_last)\n//\n// AllOfArray() verifies whether a given value matches all members of a\n// collection of matchers.\n//\n// The matchers can be specified as an array, a pointer and count, a container,\n// an initializer list, or an STL iterator range. In each of these cases, the\n// underlying matchers can be either values or matchers.\n\ntemplate <typename Iter>\ninline internal::AnyOfArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nAnyOfArray(Iter first, Iter last) {\n  return internal::AnyOfArrayMatcher<\n      typename ::std::iterator_traits<Iter>::value_type>(first, last);\n}\n\ntemplate <typename Iter>\ninline internal::AllOfArrayMatcher<\n    typename ::std::iterator_traits<Iter>::value_type>\nAllOfArray(Iter first, Iter last) {\n  return internal::AllOfArrayMatcher<\n      typename ::std::iterator_traits<Iter>::value_type>(first, last);\n}\n\ntemplate <typename T>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) {\n  return AnyOfArray(ptr, ptr + count);\n}\n\ntemplate <typename T>\ninline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) {\n  return AllOfArray(ptr, ptr + count);\n}\n\ntemplate <typename T, size_t N>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) {\n  return AnyOfArray(array, N);\n}\n\ntemplate <typename T, size_t N>\ninline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) {\n  return AllOfArray(array, N);\n}\n\ntemplate <typename Container>\ninline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray(\n    const Container& container) {\n  return AnyOfArray(container.begin(), container.end());\n}\n\ntemplate <typename Container>\ninline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray(\n    const Container& container) {\n  return AllOfArray(container.begin(), container.end());\n}\n\ntemplate <typename T>\ninline internal::AnyOfArrayMatcher<T> AnyOfArray(\n    ::std::initializer_list<T> xs) {\n  return AnyOfArray(xs.begin(), xs.end());\n}\n\ntemplate <typename T>\ninline internal::AllOfArrayMatcher<T> AllOfArray(\n    ::std::initializer_list<T> xs) {\n  return AllOfArray(xs.begin(), xs.end());\n}\n\n// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected\n// fields of it matches a_matcher.  C++ doesn't support default\n// arguments for function templates, so we have to overload it.\ntemplate <size_t... k, typename InnerMatcher>\ninternal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args(\n    InnerMatcher&& matcher) {\n  return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>(\n      std::forward<InnerMatcher>(matcher));\n}\n\n// AllArgs(m) is a synonym of m.  This is useful in\n//\n//   EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));\n//\n// which is easier to read than\n//\n//   EXPECT_CALL(foo, Bar(_, _)).With(Eq());\ntemplate <typename InnerMatcher>\ninline InnerMatcher AllArgs(const InnerMatcher& matcher) {\n  return matcher;\n}\n\n// Returns a matcher that matches the value of an optional<> type variable.\n// The matcher implementation only uses '!arg' and requires that the optional<>\n// type has a 'value_type' member type and that '*arg' is of type 'value_type'\n// and is printable using 'PrintToString'. It is compatible with\n// std::optional/std::experimental::optional.\n// Note that to compare an optional type variable against nullopt you should\n// use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the\n// optional value contains an optional itself.\ntemplate <typename ValueMatcher>\ninline internal::OptionalMatcher<ValueMatcher> Optional(\n    const ValueMatcher& value_matcher) {\n  return internal::OptionalMatcher<ValueMatcher>(value_matcher);\n}\n\n// Returns a matcher that matches the value of a absl::any type variable.\ntemplate <typename T>\nPolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T>> AnyWith(\n    const Matcher<const T&>& matcher) {\n  return MakePolymorphicMatcher(\n      internal::any_cast_matcher::AnyCastMatcher<T>(matcher));\n}\n\n// Returns a matcher that matches the value of a variant<> type variable.\n// The matcher implementation uses ADL to find the holds_alternative and get\n// functions.\n// It is compatible with std::variant.\ntemplate <typename T>\nPolymorphicMatcher<internal::variant_matcher::VariantMatcher<T>> VariantWith(\n    const Matcher<const T&>& matcher) {\n  return MakePolymorphicMatcher(\n      internal::variant_matcher::VariantMatcher<T>(matcher));\n}\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Anything inside the `internal` namespace is internal to the implementation\n// and must not be used in user code!\nnamespace internal {\n\nclass WithWhatMatcherImpl {\n public:\n  WithWhatMatcherImpl(Matcher<std::string> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"contains .what() that \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"contains .what() that does not \";\n    matcher_.DescribeTo(os);\n  }\n\n  template <typename Err>\n  bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {\n    *listener << \"which contains .what() (of value = \" << err.what()\n              << \") that \";\n    return matcher_.MatchAndExplain(err.what(), listener);\n  }\n\n private:\n  const Matcher<std::string> matcher_;\n};\n\ninline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(\n    Matcher<std::string> m) {\n  return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));\n}\n\ntemplate <typename Err>\nclass ExceptionMatcherImpl {\n  class NeverThrown {\n   public:\n    const char* what() const noexcept {\n      return \"this exception should never be thrown\";\n    }\n  };\n\n  // If the matchee raises an exception of a wrong type, we'd like to\n  // catch it and print its message and type. To do that, we add an additional\n  // catch clause:\n  //\n  //     try { ... }\n  //     catch (const Err&) { /* an expected exception */ }\n  //     catch (const std::exception&) { /* exception of a wrong type */ }\n  //\n  // However, if the `Err` itself is `std::exception`, we'd end up with two\n  // identical `catch` clauses:\n  //\n  //     try { ... }\n  //     catch (const std::exception&) { /* an expected exception */ }\n  //     catch (const std::exception&) { /* exception of a wrong type */ }\n  //\n  // This can cause a warning or an error in some compilers. To resolve\n  // the issue, we use a fake error type whenever `Err` is `std::exception`:\n  //\n  //     try { ... }\n  //     catch (const std::exception&) { /* an expected exception */ }\n  //     catch (const NeverThrown&) { /* exception of a wrong type */ }\n  using DefaultExceptionType = typename std::conditional<\n      std::is_same<typename std::remove_cv<\n                       typename std::remove_reference<Err>::type>::type,\n                   std::exception>::value,\n      const NeverThrown&, const std::exception&>::type;\n\n public:\n  ExceptionMatcherImpl(Matcher<const Err&> matcher)\n      : matcher_(std::move(matcher)) {}\n\n  void DescribeTo(std::ostream* os) const {\n    *os << \"throws an exception which is a \" << GetTypeName<Err>();\n    *os << \" which \";\n    matcher_.DescribeTo(os);\n  }\n\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << \"throws an exception which is not a \" << GetTypeName<Err>();\n    *os << \" which \";\n    matcher_.DescribeNegationTo(os);\n  }\n\n  template <typename T>\n  bool MatchAndExplain(T&& x, MatchResultListener* listener) const {\n    try {\n      (void)(std::forward<T>(x)());\n    } catch (const Err& err) {\n      *listener << \"throws an exception which is a \" << GetTypeName<Err>();\n      *listener << \" \";\n      return matcher_.MatchAndExplain(err, listener);\n    } catch (DefaultExceptionType err) {\n#if GTEST_HAS_RTTI\n      *listener << \"throws an exception of type \" << GetTypeName(typeid(err));\n      *listener << \" \";\n#else\n      *listener << \"throws an std::exception-derived type \";\n#endif\n      *listener << \"with description \\\"\" << err.what() << \"\\\"\";\n      return false;\n    } catch (...) {\n      *listener << \"throws an exception of an unknown type\";\n      return false;\n    }\n\n    *listener << \"does not throw any exception\";\n    return false;\n  }\n\n private:\n  const Matcher<const Err&> matcher_;\n};\n\n}  // namespace internal\n\n// Throws()\n// Throws(exceptionMatcher)\n// ThrowsMessage(messageMatcher)\n//\n// This matcher accepts a callable and verifies that when invoked, it throws\n// an exception with the given type and properties.\n//\n// Examples:\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       Throws<std::runtime_error>());\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       ThrowsMessage<std::runtime_error>(HasSubstr(\"message\")));\n//\n//   EXPECT_THAT(\n//       []() { throw std::runtime_error(\"message\"); },\n//       Throws<std::runtime_error>(\n//           Property(&std::runtime_error::what, HasSubstr(\"message\"))));\n\ntemplate <typename Err>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {\n  return MakePolymorphicMatcher(\n      internal::ExceptionMatcherImpl<Err>(A<const Err&>()));\n}\n\ntemplate <typename Err, typename ExceptionMatcher>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(\n    const ExceptionMatcher& exception_matcher) {\n  // Using matcher cast allows users to pass a matcher of a more broad type.\n  // For example user may want to pass Matcher<std::exception>\n  // to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.\n  return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(\n      SafeMatcherCast<const Err&>(exception_matcher)));\n}\n\ntemplate <typename Err, typename MessageMatcher>\nPolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(\n    MessageMatcher&& message_matcher) {\n  static_assert(std::is_base_of<std::exception, Err>::value,\n                \"expected an std::exception-derived type\");\n  return Throws<Err>(internal::WithWhat(\n      MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));\n}\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// These macros allow using matchers to check values in Google Test\n// tests.  ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)\n// succeed if and only if the value matches the matcher.  If the assertion\n// fails, the value and the description of the matcher will be printed.\n#define ASSERT_THAT(value, matcher) \\\n  ASSERT_PRED_FORMAT1(              \\\n      ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)\n#define EXPECT_THAT(value, matcher) \\\n  EXPECT_PRED_FORMAT1(              \\\n      ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)\n\n// MATCHER* macros itself are listed below.\n#define MATCHER(name, description)                                            \\\n  class name##Matcher                                                         \\\n      : public ::testing::internal::MatcherBaseImpl<name##Matcher> {          \\\n   public:                                                                    \\\n    template <typename arg_type>                                              \\\n    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {  \\\n     public:                                                                  \\\n      gmock_Impl() {}                                                         \\\n      bool MatchAndExplain(                                                   \\\n          const arg_type& arg,                                                \\\n          ::testing::MatchResultListener* result_listener) const override;    \\\n      void DescribeTo(::std::ostream* gmock_os) const override {              \\\n        *gmock_os << FormatDescription(false);                                \\\n      }                                                                       \\\n      void DescribeNegationTo(::std::ostream* gmock_os) const override {      \\\n        *gmock_os << FormatDescription(true);                                 \\\n      }                                                                       \\\n                                                                              \\\n     private:                                                                 \\\n      ::std::string FormatDescription(bool negation) const {                  \\\n        /* NOLINTNEXTLINE readability-redundant-string-init */                \\\n        ::std::string gmock_description = (description);                      \\\n        if (!gmock_description.empty()) {                                     \\\n          return gmock_description;                                           \\\n        }                                                                     \\\n        return ::testing::internal::FormatMatcherDescription(negation, #name, \\\n                                                             {}, {});         \\\n      }                                                                       \\\n    };                                                                        \\\n  };                                                                          \\\n  inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH()                          \\\n      GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-function\")              \\\n          GMOCK_INTERNAL_WARNING_CLANG(ignored, \"-Wunused-member-function\")   \\\n              name GMOCK_INTERNAL_WARNING_POP()() {                           \\\n    return {};                                                                \\\n  }                                                                           \\\n  template <typename arg_type>                                                \\\n  bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(                  \\\n      const arg_type& arg,                                                    \\\n      GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener*   \\\n          result_listener) const\n\n#define MATCHER_P(name, p0, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))\n#define MATCHER_P2(name, p0, p1, description)                            \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (#p0, #p1), \\\n                         (p0, p1))\n#define MATCHER_P3(name, p0, p1, p2, description)                             \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (#p0, #p1, #p2), \\\n                         (p0, p1, p2))\n#define MATCHER_P4(name, p0, p1, p2, p3, description)        \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, \\\n                         (#p0, #p1, #p2, #p3), (p0, p1, p2, p3))\n#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)    \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \\\n                         (#p0, #p1, #p2, #p3, #p4), (p0, p1, p2, p3, p4))\n#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description,  \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5),      \\\n                         (p0, p1, p2, p3, p4, p5))\n#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description,      \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6),     \\\n                         (p0, p1, p2, p3, p4, p5, p6))\n#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description,          \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7),    \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7))\n#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description,              \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8),   \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7, p8))\n#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \\\n  GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description,                  \\\n                         (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8, #p9),   \\\n                         (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))\n\n#define GMOCK_INTERNAL_MATCHER(name, full_name, description, arg_names, args)  \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  class full_name : public ::testing::internal::MatcherBaseImpl<               \\\n                        full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \\\n   public:                                                                     \\\n    using full_name::MatcherBaseImpl::MatcherBaseImpl;                         \\\n    template <typename arg_type>                                               \\\n    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {   \\\n     public:                                                                   \\\n      explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args))          \\\n          : GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {}                       \\\n      bool MatchAndExplain(                                                    \\\n          const arg_type& arg,                                                 \\\n          ::testing::MatchResultListener* result_listener) const override;     \\\n      void DescribeTo(::std::ostream* gmock_os) const override {               \\\n        *gmock_os << FormatDescription(false);                                 \\\n      }                                                                        \\\n      void DescribeNegationTo(::std::ostream* gmock_os) const override {       \\\n        *gmock_os << FormatDescription(true);                                  \\\n      }                                                                        \\\n      GMOCK_INTERNAL_MATCHER_MEMBERS(args)                                     \\\n                                                                               \\\n     private:                                                                  \\\n      ::std::string FormatDescription(bool negation) const {                   \\\n        ::std::string gmock_description;                                       \\\n        gmock_description = (description);                                     \\\n        if (!gmock_description.empty()) {                                      \\\n          return gmock_description;                                            \\\n        }                                                                      \\\n        return ::testing::internal::FormatMatcherDescription(                  \\\n            negation, #name, {GMOCK_PP_REMOVE_PARENS(arg_names)},              \\\n            ::testing::internal::UniversalTersePrintTupleFieldsToStrings(      \\\n                ::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>(        \\\n                    GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args))));             \\\n      }                                                                        \\\n    };                                                                         \\\n  };                                                                           \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name(             \\\n      GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) {                            \\\n    return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>(                \\\n        GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args));                              \\\n  }                                                                            \\\n  template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \\\n  template <typename arg_type>                                                 \\\n  bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::                   \\\n      gmock_Impl<arg_type>::MatchAndExplain(                                   \\\n          const arg_type& arg,                                                 \\\n          GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::                    \\\n              MatchResultListener* result_listener) const\n\n#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \\\n  GMOCK_PP_TAIL(                                     \\\n      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args))\n#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \\\n  , typename arg##_type\n\n#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args))\n#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \\\n  , arg##_type\n\n#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \\\n  GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH(     \\\n      GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args))\n#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \\\n  , arg##_type gmock_p##i\n\n#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args))\n#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \\\n  , arg(::std::forward<arg##_type>(gmock_p##i))\n\n#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \\\n  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args)\n#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \\\n  const arg##_type arg;\n\n#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args))\n#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg\n\n#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \\\n  GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))\n#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg) \\\n  , ::std::forward<arg##_type>(gmock_p##i)\n\n// To prevent ADL on certain functions we put them on a separate namespace.\nusing namespace no_adl;  // NOLINT\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046\n\n// Include any custom callback matchers added by the local installation.\n// We must include this header at the end to make sure it can use the\n// declarations from this file.\n#include \"gmock/internal/custom/gmock-matchers.h\"\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-more-actions.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some commonly used variadic actions.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n\n#include <memory>\n#include <utility>\n\n#include \"gmock/gmock-actions.h\"\n#include \"gmock/internal/gmock-port.h\"\n\n// Include any custom callback actions added by the local installation.\n#include \"gmock/internal/custom/gmock-generated-actions.h\"\n\n// Sometimes you want to give an action explicit template parameters\n// that cannot be inferred from its value parameters.  ACTION() and\n// ACTION_P*() don't support that.  ACTION_TEMPLATE() remedies that\n// and can be viewed as an extension to ACTION() and ACTION_P*().\n//\n// The syntax:\n//\n//   ACTION_TEMPLATE(ActionName,\n//                   HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),\n//                   AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }\n//\n// defines an action template that takes m explicit template\n// parameters and n value parameters.  name_i is the name of the i-th\n// template parameter, and kind_i specifies whether it's a typename,\n// an integral constant, or a template.  p_i is the name of the i-th\n// value parameter.\n//\n// Example:\n//\n//   // DuplicateArg<k, T>(output) converts the k-th argument of the mock\n//   // function to type T and copies it to *output.\n//   ACTION_TEMPLATE(DuplicateArg,\n//                   HAS_2_TEMPLATE_PARAMS(int, k, typename, T),\n//                   AND_1_VALUE_PARAMS(output)) {\n//     *output = T(::std::get<k>(args));\n//   }\n//   ...\n//     int n;\n//     EXPECT_CALL(mock, Foo(_, _))\n//         .WillOnce(DuplicateArg<1, unsigned char>(&n));\n//\n// To create an instance of an action template, write:\n//\n//   ActionName<t1, ..., t_m>(v1, ..., v_n)\n//\n// where the ts are the template arguments and the vs are the value\n// arguments.  The value argument types are inferred by the compiler.\n// If you want to explicitly specify the value argument types, you can\n// provide additional template arguments:\n//\n//   ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)\n//\n// where u_i is the desired type of v_i.\n//\n// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the\n// number of value parameters, but not on the number of template\n// parameters.  Without the restriction, the meaning of the following\n// is unclear:\n//\n//   OverloadedAction<int, bool>(x);\n//\n// Are we using a single-template-parameter action where 'bool' refers\n// to the type of x, or are we using a two-template-parameter action\n// where the compiler is asked to infer the type of x?\n//\n// Implementation notes:\n//\n// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and\n// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for\n// implementing ACTION_TEMPLATE.  The main trick we use is to create\n// new macro invocations when expanding a macro.  For example, we have\n//\n//   #define ACTION_TEMPLATE(name, template_params, value_params)\n//       ... GMOCK_INTERNAL_DECL_##template_params ...\n//\n// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)\n// to expand to\n//\n//       ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...\n//\n// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the\n// preprocessor will continue to expand it to\n//\n//       ... typename T ...\n//\n// This technique conforms to the C++ standard and is portable.  It\n// allows us to implement action templates using O(N) code, where N is\n// the maximum number of template/value parameters supported.  Without\n// using it, we'd have to devote O(N^2) amount of code to implement all\n// combinations of m and n.\n\n// Declares the template parameters.\n#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0\n#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \\\n  kind0 name0, kind1 name1\n#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2)               \\\n  kind0 name0, kind1 name1, kind2 name2\n#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3\n#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4\n#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3, \\\n                                                  kind4, name4, kind5, name5) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5\n#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6)                                           \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6\n#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7)                             \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7\n#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8)               \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7, kind8 name8\n#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(                       \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \\\n  kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4,        \\\n      kind5 name5, kind6 name6, kind7 name7, kind8 name8, kind9 name9\n\n// Lists the template parameters.\n#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0\n#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \\\n  name0, name1\n#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2)               \\\n  name0, name1, name2\n#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3) \\\n  name0, name1, name2, name3\n#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \\\n  name0, name1, name2, name3, name4\n#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \\\n                                                  kind2, name2, kind3, name3, \\\n                                                  kind4, name4, kind5, name5) \\\n  name0, name1, name2, name3, name4, name5\n#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6)                                           \\\n  name0, name1, name2, name3, name4, name5, name6\n#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7)                             \\\n  name0, name1, name2, name3, name4, name5, name6, name7\n#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(                        \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8)               \\\n  name0, name1, name2, name3, name4, name5, name6, name7, name8\n#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(                       \\\n    kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \\\n    kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \\\n  name0, name1, name2, name3, name4, name5, name6, name7, name8, name9\n\n// Declares the types of value parameters.\n#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) \\\n  , typename p0##_type, typename p1##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,     \\\n      typename p3##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,         \\\n      typename p3##_type, typename p4##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6)                     \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7)                 \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type, typename p7##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7, p8)             \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,             \\\n      typename p3##_type, typename p4##_type, typename p5##_type,           \\\n      typename p6##_type, typename p7##_type, typename p8##_type\n#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                     p6, p7, p8, p9)         \\\n  , typename p0##_type, typename p1##_type, typename p2##_type,              \\\n      typename p3##_type, typename p4##_type, typename p5##_type,            \\\n      typename p6##_type, typename p7##_type, typename p8##_type,            \\\n      typename p9##_type\n\n// Initializes the value parameters.\n#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS() ()\n#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0) \\\n  (p0##_type gmock_p0) : p0(::std::move(gmock_p0))\n#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1)             \\\n      : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1))\n#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)     \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2) \\\n      : p0(::std::move(gmock_p0)),                             \\\n        p1(::std::move(gmock_p1)),                             \\\n        p2(::std::move(gmock_p2))\n#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \\\n   p3##_type gmock_p3)                                         \\\n      : p0(::std::move(gmock_p0)),                             \\\n        p1(::std::move(gmock_p1)),                             \\\n        p2(::std::move(gmock_p2)),                             \\\n        p3(::std::move(gmock_p3))\n#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,     \\\n   p3##_type gmock_p3, p4##_type gmock_p4)                         \\\n      : p0(::std::move(gmock_p0)),                                 \\\n        p1(::std::move(gmock_p1)),                                 \\\n        p2(::std::move(gmock_p2)),                                 \\\n        p3(::std::move(gmock_p3)),                                 \\\n        p4(::std::move(gmock_p4))\n#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,         \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)         \\\n      : p0(::std::move(gmock_p0)),                                     \\\n        p1(::std::move(gmock_p1)),                                     \\\n        p2(::std::move(gmock_p2)),                                     \\\n        p3(::std::move(gmock_p3)),                                     \\\n        p4(::std::move(gmock_p4)),                                     \\\n        p5(::std::move(gmock_p5))\n#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,             \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,             \\\n   p6##_type gmock_p6)                                                     \\\n      : p0(::std::move(gmock_p0)),                                         \\\n        p1(::std::move(gmock_p1)),                                         \\\n        p2(::std::move(gmock_p2)),                                         \\\n        p3(::std::move(gmock_p3)),                                         \\\n        p4(::std::move(gmock_p4)),                                         \\\n        p5(::std::move(gmock_p5)),                                         \\\n        p6(::std::move(gmock_p6))\n#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,                 \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,                 \\\n   p6##_type gmock_p6, p7##_type gmock_p7)                                     \\\n      : p0(::std::move(gmock_p0)),                                             \\\n        p1(::std::move(gmock_p1)),                                             \\\n        p2(::std::move(gmock_p2)),                                             \\\n        p3(::std::move(gmock_p3)),                                             \\\n        p4(::std::move(gmock_p4)),                                             \\\n        p5(::std::move(gmock_p5)),                                             \\\n        p6(::std::move(gmock_p6)),                                             \\\n        p7(::std::move(gmock_p7))\n#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,                 \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,                 \\\n   p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)                 \\\n      : p0(::std::move(gmock_p0)),                                             \\\n        p1(::std::move(gmock_p1)),                                             \\\n        p2(::std::move(gmock_p2)),                                             \\\n        p3(::std::move(gmock_p3)),                                             \\\n        p4(::std::move(gmock_p4)),                                             \\\n        p5(::std::move(gmock_p5)),                                             \\\n        p6(::std::move(gmock_p6)),                                             \\\n        p7(::std::move(gmock_p7)),                                             \\\n        p8(::std::move(gmock_p8))\n#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2,              \\\n   p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5,              \\\n   p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8,              \\\n   p9##_type gmock_p9)                                                      \\\n      : p0(::std::move(gmock_p0)),                                          \\\n        p1(::std::move(gmock_p1)),                                          \\\n        p2(::std::move(gmock_p2)),                                          \\\n        p3(::std::move(gmock_p3)),                                          \\\n        p4(::std::move(gmock_p4)),                                          \\\n        p5(::std::move(gmock_p5)),                                          \\\n        p6(::std::move(gmock_p6)),                                          \\\n        p7(::std::move(gmock_p7)),                                          \\\n        p8(::std::move(gmock_p8)),                                          \\\n        p9(::std::move(gmock_p9))\n\n// Defines the copy constructor\n#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \\\n  {}  // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134\n#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default;\n#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default;\n\n// Declares the fields for storing the value parameters.\n#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;\n#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) \\\n  p0##_type p0;                                        \\\n  p1##_type p1;\n#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  p0##_type p0;                                            \\\n  p1##_type p1;                                            \\\n  p2##_type p2;\n#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  p0##_type p0;                                                \\\n  p1##_type p1;                                                \\\n  p2##_type p2;                                                \\\n  p3##_type p3;\n#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0##_type p0;                                                    \\\n  p1##_type p1;                                                    \\\n  p2##_type p2;                                                    \\\n  p3##_type p3;                                                    \\\n  p4##_type p4;\n#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  p0##_type p0;                                                        \\\n  p1##_type p1;                                                        \\\n  p2##_type p2;                                                        \\\n  p3##_type p3;                                                        \\\n  p4##_type p4;                                                        \\\n  p5##_type p5;\n#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0##_type p0;                                                            \\\n  p1##_type p1;                                                            \\\n  p2##_type p2;                                                            \\\n  p3##_type p3;                                                            \\\n  p4##_type p4;                                                            \\\n  p5##_type p5;                                                            \\\n  p6##_type p6;\n#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0##_type p0;                                                                \\\n  p1##_type p1;                                                                \\\n  p2##_type p2;                                                                \\\n  p3##_type p3;                                                                \\\n  p4##_type p4;                                                                \\\n  p5##_type p5;                                                                \\\n  p6##_type p6;                                                                \\\n  p7##_type p7;\n#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0##_type p0;                                                                \\\n  p1##_type p1;                                                                \\\n  p2##_type p2;                                                                \\\n  p3##_type p3;                                                                \\\n  p4##_type p4;                                                                \\\n  p5##_type p5;                                                                \\\n  p6##_type p6;                                                                \\\n  p7##_type p7;                                                                \\\n  p8##_type p8;\n#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0##_type p0;                                                             \\\n  p1##_type p1;                                                             \\\n  p2##_type p2;                                                             \\\n  p3##_type p3;                                                             \\\n  p4##_type p4;                                                             \\\n  p5##_type p5;                                                             \\\n  p6##_type p6;                                                             \\\n  p7##_type p7;                                                             \\\n  p8##_type p8;                                                             \\\n  p9##_type p9;\n\n// Lists the value parameters.\n#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0\n#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1\n#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2\n#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3\n#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0, p1, p2, p3, p4\n#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  p0, p1, p2, p3, p4, p5\n#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0, p1, p2, p3, p4, p5, p6\n#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0, p1, p2, p3, p4, p5, p6, p7\n#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0, p1, p2, p3, p4, p5, p6, p7, p8\n#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0, p1, p2, p3, p4, p5, p6, p7, p8, p9\n\n// Lists the value parameter types.\n#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) \\\n  , p0##_type, p1##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  , p0##_type, p1##_type, p2##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6)                     \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, p6##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7)                 \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,       \\\n      p6##_type, p7##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                    p6, p7, p8)             \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,       \\\n      p6##_type, p7##_type, p8##_type\n#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \\\n                                                     p6, p7, p8, p9)         \\\n  , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type,        \\\n      p6##_type, p7##_type, p8##_type, p9##_type\n\n// Declares the value parameters.\n#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0\n#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) \\\n  p0##_type p0, p1##_type p1\n#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) \\\n  p0##_type p0, p1##_type p1, p2##_type p2\n#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3\n#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4\n#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)  \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \\\n      p5##_type p5\n#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,    \\\n      p5##_type p5, p6##_type p6\n#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,        \\\n      p5##_type p5, p6##_type p6, p7##_type p7\n#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \\\n                                               p8)                             \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,        \\\n      p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8\n#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8, p9)                 \\\n  p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4,     \\\n      p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, p9##_type p9\n\n// The suffix of the class template implementing the action template.\n#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()\n#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P\n#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2\n#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3\n#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4\n#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5\n#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6\n#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7\n#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7)                         \\\n  P8\n#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                p7, p8)                     \\\n  P9\n#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \\\n                                                 p7, p8, p9)                 \\\n  P10\n\n// The name of the class template implementing the action template.\n#define GMOCK_ACTION_CLASS_(name, value_params) \\\n  GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)\n\n#define ACTION_TEMPLATE(name, template_params, value_params)                   \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  class GMOCK_ACTION_CLASS_(name, value_params) {                              \\\n   public:                                                                     \\\n    explicit GMOCK_ACTION_CLASS_(name, value_params)(                          \\\n        GMOCK_INTERNAL_DECL_##value_params)                                    \\\n        GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),    \\\n                    = default;                                                 \\\n                    ,                                                          \\\n                    : impl_(std::make_shared<gmock_Impl>(                      \\\n                        GMOCK_INTERNAL_LIST_##value_params)){})                \\\n            GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \\\n                name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_      \\\n        ##value_params                                                         \\\n        GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_(           \\\n            name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_         \\\n        ##value_params template <typename F>                                   \\\n        operator ::testing::Action<F>() const {                                \\\n      return GMOCK_PP_IF(                                                      \\\n          GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params),              \\\n          (::testing::internal::MakeAction<F, gmock_Impl>()),                  \\\n          (::testing::internal::MakeAction<F>(impl_)));                        \\\n    }                                                                          \\\n                                                                               \\\n   private:                                                                    \\\n    class gmock_Impl {                                                         \\\n     public:                                                                   \\\n      explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}                \\\n      template <typename function_type, typename return_type,                  \\\n                typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>         \\\n      return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const;  \\\n      GMOCK_INTERNAL_DEFN_##value_params                                       \\\n    };                                                                         \\\n    GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), ,      \\\n                std::shared_ptr<const gmock_Impl> impl_;)                      \\\n  };                                                                           \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  GMOCK_ACTION_CLASS_(                                                         \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \\\n      name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_;         \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  inline GMOCK_ACTION_CLASS_(                                                  \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>         \\\n  name(GMOCK_INTERNAL_DECL_##value_params) {                                   \\\n    return GMOCK_ACTION_CLASS_(                                                \\\n        name, value_params)<GMOCK_INTERNAL_LIST_##template_params              \\\n                                GMOCK_INTERNAL_LIST_TYPE_##value_params>(      \\\n        GMOCK_INTERNAL_LIST_##value_params);                                   \\\n  }                                                                            \\\n  template <GMOCK_INTERNAL_DECL_##template_params                              \\\n                GMOCK_INTERNAL_DECL_TYPE_##value_params>                       \\\n  template <typename function_type, typename return_type, typename args_type,  \\\n            GMOCK_ACTION_TEMPLATE_ARGS_NAMES_>                                 \\\n  return_type GMOCK_ACTION_CLASS_(                                             \\\n      name, value_params)<GMOCK_INTERNAL_LIST_##template_params                \\\n                              GMOCK_INTERNAL_LIST_TYPE_##value_params>::       \\\n      gmock_Impl::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_)  \\\n          const\n\nnamespace testing {\n\n// The ACTION*() macros trigger warning C4100 (unreferenced formal\n// parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in\n// the macro definition, as the warnings are generated when the macro\n// is expanded and macro expansion cannot contain #pragma.  Therefore\n// we suppress them here.\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\nnamespace internal {\n\n// internal::InvokeArgument - a helper for InvokeArgument action.\n// The basic overloads are provided here for generic functors.\n// Overloads for other custom-callables are provided in the\n// internal/custom/gmock-generated-actions.h header.\ntemplate <typename F, typename... Args>\nauto InvokeArgument(F &&f,\n                    Args... args) -> decltype(std::forward<F>(f)(args...)) {\n  return std::forward<F>(f)(args...);\n}\n\ntemplate <std::size_t index, typename... Params>\nstruct InvokeArgumentAction {\n  template <typename... Args,\n            typename = typename std::enable_if<(index < sizeof...(Args))>::type>\n  auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(\n      std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),\n      std::declval<const Params &>()...)) {\n    internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},\n                                               std::forward<Args>(args)...);\n    return params.Apply([&](const Params &...unpacked_params) {\n      auto &&callable = std::move(args_tuple.template Get<index>());\n      return internal::InvokeArgument(\n          std::forward<decltype(callable)>(callable), unpacked_params...);\n    });\n  }\n\n  internal::FlatTuple<Params...> params;\n};\n\n}  // namespace internal\n\n// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th\n// (0-based) argument, which must be a k-ary callable, of the mock\n// function, with arguments a1, a2, ..., a_k.\n//\n// Notes:\n//\n//   1. The arguments are passed by value by default.  If you need to\n//   pass an argument by reference, wrap it inside std::ref().  For\n//   example,\n//\n//     InvokeArgument<1>(5, string(\"Hello\"), std::ref(foo))\n//\n//   passes 5 and string(\"Hello\") by value, and passes foo by\n//   reference.\n//\n//   2. If the callable takes an argument by reference but std::ref() is\n//   not used, it will receive the reference to a copy of the value,\n//   instead of the original value.  For example, when the 0-th\n//   argument of the mock function takes a const string&, the action\n//\n//     InvokeArgument<0>(string(\"Hello\"))\n//\n//   makes a copy of the temporary string(\"Hello\") object and passes a\n//   reference of the copy, instead of the original temporary object,\n//   to the callable.  This makes it easy for a user to define an\n//   InvokeArgument action from temporary values and have it performed\n//   later.\ntemplate <std::size_t index, typename... Params>\ninternal::InvokeArgumentAction<index, typename std::decay<Params>::type...>\nInvokeArgument(Params &&...params) {\n  return {internal::FlatTuple<typename std::decay<Params>::type...>(\n      internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};\n}\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-more-matchers.h",
    "content": "// Copyright 2013, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements some matchers that depend on gmock-matchers.h.\n//\n// Note that tests are implemented in gmock-matchers_test.cc rather than\n// gmock-more-matchers-test.cc.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n\n#include <ostream>\n#include <string>\n\n#include \"gmock/gmock-matchers.h\"\n\nnamespace testing {\n\n// Silence C4100 (unreferenced formal\n// parameter) for MSVC\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\n// and silence C4800 (C4800: 'int *const ': forcing value\n// to bool 'true' or 'false') for MSVC 14\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)\n#endif\n\nnamespace internal {\n\n// Implements the polymorphic IsEmpty matcher, which\n// can be used as a Matcher<T> as long as T is either a container that defines\n// empty() and size() (e.g. std::vector or std::string), or a C-style string.\nclass IsEmptyMatcher {\n public:\n  // Matches anything that defines empty() and size().\n  template <typename MatcheeContainerType>\n  bool MatchAndExplain(const MatcheeContainerType& c,\n                       MatchResultListener* listener) const {\n    if (c.empty()) {\n      return true;\n    }\n    *listener << \"whose size is \" << c.size();\n    return false;\n  }\n\n  // Matches C-style strings.\n  bool MatchAndExplain(const char* s, MatchResultListener* listener) const {\n    return MatchAndExplain(std::string(s), listener);\n  }\n\n  // Describes what this matcher matches.\n  void DescribeTo(std::ostream* os) const { *os << \"is empty\"; }\n\n  void DescribeNegationTo(std::ostream* os) const { *os << \"isn't empty\"; }\n};\n\n}  // namespace internal\n\n// Creates a polymorphic matcher that matches an empty container or C-style\n// string. The container must support both size() and empty(), which all\n// STL-like containers provide.\ninline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() {\n  return MakePolymorphicMatcher(internal::IsEmptyMatcher());\n}\n\n// Define a matcher that matches a value that evaluates in boolean\n// context to true.  Useful for types that define \"explicit operator\n// bool\" operators and so can't be compared for equality with true\n// and false.\nMATCHER(IsTrue, negation ? \"is false\" : \"is true\") {\n  return static_cast<bool>(arg);\n}\n\n// Define a matcher that matches a value that evaluates in boolean\n// context to false.  Useful for types that define \"explicit operator\n// bool\" operators and so can't be compared for equality with true\n// and false.\nMATCHER(IsFalse, negation ? \"is true\" : \"is false\") {\n  return !static_cast<bool>(arg);\n}\n\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4800\n#endif\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-nice-strict.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Implements class templates NiceMock, NaggyMock, and StrictMock.\n//\n// Given a mock class MockFoo that is created using Google Mock,\n// NiceMock<MockFoo> is a subclass of MockFoo that allows\n// uninteresting calls (i.e. calls to mock methods that have no\n// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo\n// that prints a warning when an uninteresting call occurs, and\n// StrictMock<MockFoo> is a subclass of MockFoo that treats all\n// uninteresting calls as errors.\n//\n// Currently a mock is naggy by default, so MockFoo and\n// NaggyMock<MockFoo> behave like the same.  However, we will soon\n// switch the default behavior of mocks to be nice, as that in general\n// leads to more maintainable tests.  When that happens, MockFoo will\n// stop behaving like NaggyMock<MockFoo> and start behaving like\n// NiceMock<MockFoo>.\n//\n// NiceMock, NaggyMock, and StrictMock \"inherit\" the constructors of\n// their respective base class.  Therefore you can write\n// NiceMock<MockFoo>(5, \"a\") to construct a nice mock where MockFoo\n// has a constructor that accepts (int, const char*), for example.\n//\n// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,\n// and StrictMock<MockFoo> only works for mock methods defined using\n// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.\n// If a mock method is defined in a base class of MockFoo, the \"nice\"\n// or \"strict\" modifier may not affect it, depending on the compiler.\n// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT\n// supported.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n\n#include <cstdint>\n#include <type_traits>\n\n#include \"gmock/gmock-spec-builders.h\"\n#include \"gmock/internal/gmock-port.h\"\n\nnamespace testing {\ntemplate <class MockClass>\nclass NiceMock;\ntemplate <class MockClass>\nclass NaggyMock;\ntemplate <class MockClass>\nclass StrictMock;\n\nnamespace internal {\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const NiceMock<T>&);\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const NaggyMock<T>&);\ntemplate <typename T>\nstd::true_type StrictnessModifierProbe(const StrictMock<T>&);\nstd::false_type StrictnessModifierProbe(...);\n\ntemplate <typename T>\nconstexpr bool HasStrictnessModifier() {\n  return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;\n}\n\n// Base classes that register and deregister with testing::Mock to alter the\n// default behavior around uninteresting calls. Inheriting from one of these\n// classes first and then MockClass ensures the MockClass constructor is run\n// after registration, and that the MockClass destructor runs before\n// deregistration. This guarantees that MockClass's constructor and destructor\n// run with the same level of strictness as its instance methods.\n\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \\\n    (defined(_MSC_VER) || defined(__clang__))\n// We need to mark these classes with this declspec to ensure that\n// the empty base class optimization is performed.\n#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)\n#else\n#define GTEST_INTERNAL_EMPTY_BASE_CLASS\n#endif\n\ntemplate <typename Base>\nclass NiceMockImpl {\n public:\n  NiceMockImpl() {\n    ::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~NiceMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\ntemplate <typename Base>\nclass NaggyMockImpl {\n public:\n  NaggyMockImpl() {\n    ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~NaggyMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\ntemplate <typename Base>\nclass StrictMockImpl {\n public:\n  StrictMockImpl() {\n    ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));\n  }\n\n  ~StrictMockImpl() {\n    ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));\n  }\n};\n\n}  // namespace internal\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock\n    : private internal::NiceMockImpl<MockClass>,\n      public MockClass {\n public:\n  static_assert(!internal::HasStrictnessModifier<MockClass>(),\n                \"Can't apply NiceMock to a class hierarchy that already has a \"\n                \"strictness modifier. See \"\n                \"https://google.github.io/googletest/\"\n                \"gmock_cook_book.html#NiceStrictNaggy\");\n  NiceMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  NiceMock(const NiceMock&) = delete;\n  NiceMock& operator=(const NiceMock&) = delete;\n};\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock\n    : private internal::NaggyMockImpl<MockClass>,\n      public MockClass {\n  static_assert(!internal::HasStrictnessModifier<MockClass>(),\n                \"Can't apply NaggyMock to a class hierarchy that already has a \"\n                \"strictness modifier. See \"\n                \"https://google.github.io/googletest/\"\n                \"gmock_cook_book.html#NiceStrictNaggy\");\n\n public:\n  NaggyMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  NaggyMock(const NaggyMock&) = delete;\n  NaggyMock& operator=(const NaggyMock&) = delete;\n};\n\ntemplate <class MockClass>\nclass GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock\n    : private internal::StrictMockImpl<MockClass>,\n      public MockClass {\n public:\n  static_assert(\n      !internal::HasStrictnessModifier<MockClass>(),\n      \"Can't apply StrictMock to a class hierarchy that already has a \"\n      \"strictness modifier. See \"\n      \"https://google.github.io/googletest/\"\n      \"gmock_cook_book.html#NiceStrictNaggy\");\n  StrictMock() : MockClass() {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  // Ideally, we would inherit base class's constructors through a using\n  // declaration, which would preserve their visibility. However, many existing\n  // tests rely on the fact that current implementation reexports protected\n  // constructors as public. These tests would need to be cleaned up first.\n\n  // Single argument constructor is special-cased so that it can be\n  // made explicit.\n  template <typename A>\n  explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n  template <typename TArg1, typename TArg2, typename... An>\n  StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)\n      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),\n                  std::forward<An>(args)...) {\n    static_assert(sizeof(*this) == sizeof(MockClass),\n                  \"The impl subclass shouldn't introduce any padding\");\n  }\n\n private:\n  StrictMock(const StrictMock&) = delete;\n  StrictMock& operator=(const StrictMock&) = delete;\n};\n\n#undef GTEST_INTERNAL_EMPTY_BASE_CLASS\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock-spec-builders.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements the ON_CALL() and EXPECT_CALL() macros.\n//\n// A user can use the ON_CALL() macro to specify the default action of\n// a mock method.  The syntax is:\n//\n//   ON_CALL(mock_object, Method(argument-matchers))\n//       .With(multi-argument-matcher)\n//       .WillByDefault(action);\n//\n//  where the .With() clause is optional.\n//\n// A user can use the EXPECT_CALL() macro to specify an expectation on\n// a mock method.  The syntax is:\n//\n//   EXPECT_CALL(mock_object, Method(argument-matchers))\n//       .With(multi-argument-matchers)\n//       .Times(cardinality)\n//       .InSequence(sequences)\n//       .After(expectations)\n//       .WillOnce(action)\n//       .WillRepeatedly(action)\n//       .RetiresOnSaturation();\n//\n// where all clauses are optional, and .InSequence()/.After()/\n// .WillOnce() can appear any number of times.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n\n#include <cstdint>\n#include <functional>\n#include <map>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/gmock-actions.h\"\n#include \"gmock/gmock-cardinalities.h\"\n#include \"gmock/gmock-matchers.h\"\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>  // NOLINT\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// An abstract handle of an expectation.\nclass Expectation;\n\n// A set of expectation handles.\nclass ExpectationSet;\n\n// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION\n// and MUST NOT BE USED IN USER CODE!!!\nnamespace internal {\n\n// Implements a mock function.\ntemplate <typename F>\nclass FunctionMocker;\n\n// Base class for expectations.\nclass ExpectationBase;\n\n// Implements an expectation.\ntemplate <typename F>\nclass TypedExpectation;\n\n// Helper class for testing the Expectation class template.\nclass ExpectationTester;\n\n// Helper classes for implementing NiceMock, StrictMock, and NaggyMock.\ntemplate <typename MockClass>\nclass NiceMockImpl;\ntemplate <typename MockClass>\nclass StrictMockImpl;\ntemplate <typename MockClass>\nclass NaggyMockImpl;\n\n// Protects the mock object registry (in class Mock), all function\n// mockers, and all expectations.\n//\n// The reason we don't use more fine-grained protection is: when a\n// mock function Foo() is called, it needs to consult its expectations\n// to see which one should be picked.  If another thread is allowed to\n// call a mock function (either Foo() or a different one) at the same\n// time, it could affect the \"retired\" attributes of Foo()'s\n// expectations when InSequence() is used, and thus affect which\n// expectation gets picked.  Therefore, we sequence all mock function\n// calls to ensure the integrity of the mock objects' states.\nGTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);\n\n// Abstract base class of FunctionMocker.  This is the\n// type-agnostic part of the function mocker interface.  Its pure\n// virtual methods are implemented by FunctionMocker.\nclass GTEST_API_ UntypedFunctionMockerBase {\n public:\n  UntypedFunctionMockerBase();\n  virtual ~UntypedFunctionMockerBase();\n\n  // Verifies that all expectations on this mock function have been\n  // satisfied.  Reports one or more Google Test non-fatal failures\n  // and returns false if not.\n  bool VerifyAndClearExpectationsLocked()\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Clears the ON_CALL()s set on this mock function.\n  virtual void ClearDefaultActionsLocked()\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0;\n\n  // In all of the following Untyped* functions, it's the caller's\n  // responsibility to guarantee the correctness of the arguments'\n  // types.\n\n  // Writes a message that the call is uninteresting (i.e. neither\n  // explicitly expected nor explicitly unexpected) to the given\n  // ostream.\n  virtual void UntypedDescribeUninterestingCall(const void* untyped_args,\n                                                ::std::ostream* os) const\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;\n\n  // Returns the expectation that matches the given function arguments\n  // (or NULL is there's no match); when a match is found,\n  // untyped_action is set to point to the action that should be\n  // performed (or NULL if the action is \"do default\"), and\n  // is_excessive is modified to indicate whether the call exceeds the\n  // expected number.\n  virtual const ExpectationBase* UntypedFindMatchingExpectation(\n      const void* untyped_args, const void** untyped_action, bool* is_excessive,\n      ::std::ostream* what, ::std::ostream* why)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;\n\n  // Prints the given function arguments to the ostream.\n  virtual void UntypedPrintArgs(const void* untyped_args,\n                                ::std::ostream* os) const = 0;\n\n  // Sets the mock object this mock method belongs to, and registers\n  // this information in the global mock registry.  Will be called\n  // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock\n  // method.\n  void RegisterOwner(const void* mock_obj) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Sets the mock object this mock method belongs to, and sets the\n  // name of the mock function.  Will be called upon each invocation\n  // of this mock function.\n  void SetOwnerAndName(const void* mock_obj, const char* name)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Returns the mock object this mock method belongs to.  Must be\n  // called after RegisterOwner() or SetOwnerAndName() has been\n  // called.\n  const void* MockObject() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n  // Returns the name of this mock method.  Must be called after\n  // SetOwnerAndName() has been called.\n  const char* Name() const GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n\n protected:\n  typedef std::vector<const void*> UntypedOnCallSpecs;\n\n  using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;\n\n  struct UninterestingCallCleanupHandler;\n  struct FailureCleanupHandler;\n\n  // Returns an Expectation object that references and co-owns exp,\n  // which must be an expectation on this mock function.\n  Expectation GetHandleOf(ExpectationBase* exp);\n\n  // Address of the mock object this mock method belongs to.  Only\n  // valid after this mock method has been called or\n  // ON_CALL/EXPECT_CALL has been invoked on it.\n  const void* mock_obj_;  // Protected by g_gmock_mutex.\n\n  // Name of the function being mocked.  Only valid after this mock\n  // method has been called.\n  const char* name_;  // Protected by g_gmock_mutex.\n\n  // All default action specs for this function mocker.\n  UntypedOnCallSpecs untyped_on_call_specs_;\n\n  // All expectations for this function mocker.\n  //\n  // It's undefined behavior to interleave expectations (EXPECT_CALLs\n  // or ON_CALLs) and mock function calls.  Also, the order of\n  // expectations is important.  Therefore it's a logic race condition\n  // to read/write untyped_expectations_ concurrently.  In order for\n  // tools like tsan to catch concurrent read/write accesses to\n  // untyped_expectations, we deliberately leave accesses to it\n  // unprotected.\n  UntypedExpectations untyped_expectations_;\n};  // class UntypedFunctionMockerBase\n\n// Untyped base class for OnCallSpec<F>.\nclass UntypedOnCallSpecBase {\n public:\n  // The arguments are the location of the ON_CALL() statement.\n  UntypedOnCallSpecBase(const char* a_file, int a_line)\n      : file_(a_file), line_(a_line), last_clause_(kNone) {}\n\n  // Where in the source file was the default action spec defined?\n  const char* file() const { return file_; }\n  int line() const { return line_; }\n\n protected:\n  // Gives each clause in the ON_CALL() statement a name.\n  enum Clause {\n    // Do not change the order of the enum members!  The run-time\n    // syntax checking relies on it.\n    kNone,\n    kWith,\n    kWillByDefault\n  };\n\n  // Asserts that the ON_CALL() statement has a certain property.\n  void AssertSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Assert(property, file_, line_, failure_message);\n  }\n\n  // Expects that the ON_CALL() statement has a certain property.\n  void ExpectSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Expect(property, file_, line_, failure_message);\n  }\n\n  const char* file_;\n  int line_;\n\n  // The last clause in the ON_CALL() statement as seen so far.\n  // Initially kNone and changes as the statement is parsed.\n  Clause last_clause_;\n};  // class UntypedOnCallSpecBase\n\n// This template class implements an ON_CALL spec.\ntemplate <typename F>\nclass OnCallSpec : public UntypedOnCallSpecBase {\n public:\n  typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n\n  // Constructs an OnCallSpec object from the information inside\n  // the parenthesis of an ON_CALL() statement.\n  OnCallSpec(const char* a_file, int a_line,\n             const ArgumentMatcherTuple& matchers)\n      : UntypedOnCallSpecBase(a_file, a_line),\n        matchers_(matchers),\n        // By default, extra_matcher_ should match anything.  However,\n        // we cannot initialize it with _ as that causes ambiguity between\n        // Matcher's copy and move constructor for some argument types.\n        extra_matcher_(A<const ArgumentTuple&>()) {}\n\n  // Implements the .With() clause.\n  OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {\n    // Makes sure this is called at most once.\n    ExpectSpecProperty(last_clause_ < kWith,\n                       \".With() cannot appear \"\n                       \"more than once in an ON_CALL().\");\n    last_clause_ = kWith;\n\n    extra_matcher_ = m;\n    return *this;\n  }\n\n  // Implements the .WillByDefault() clause.\n  OnCallSpec& WillByDefault(const Action<F>& action) {\n    ExpectSpecProperty(last_clause_ < kWillByDefault,\n                       \".WillByDefault() must appear \"\n                       \"exactly once in an ON_CALL().\");\n    last_clause_ = kWillByDefault;\n\n    ExpectSpecProperty(!action.IsDoDefault(),\n                       \"DoDefault() cannot be used in ON_CALL().\");\n    action_ = action;\n    return *this;\n  }\n\n  // Returns true if and only if the given arguments match the matchers.\n  bool Matches(const ArgumentTuple& args) const {\n    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);\n  }\n\n  // Returns the action specified by the user.\n  const Action<F>& GetAction() const {\n    AssertSpecProperty(last_clause_ == kWillByDefault,\n                       \".WillByDefault() must appear exactly \"\n                       \"once in an ON_CALL().\");\n    return action_;\n  }\n\n private:\n  // The information in statement\n  //\n  //   ON_CALL(mock_object, Method(matchers))\n  //       .With(multi-argument-matcher)\n  //       .WillByDefault(action);\n  //\n  // is recorded in the data members like this:\n  //\n  //   source file that contains the statement => file_\n  //   line number of the statement            => line_\n  //   matchers                                => matchers_\n  //   multi-argument-matcher                  => extra_matcher_\n  //   action                                  => action_\n  ArgumentMatcherTuple matchers_;\n  Matcher<const ArgumentTuple&> extra_matcher_;\n  Action<F> action_;\n};  // class OnCallSpec\n\n// Possible reactions on uninteresting calls.\nenum CallReaction {\n  kAllow,\n  kWarn,\n  kFail,\n};\n\n}  // namespace internal\n\n// Utilities for manipulating mock objects.\nclass GTEST_API_ Mock {\n public:\n  // The following public methods can be called concurrently.\n\n  // Tells Google Mock to ignore mock_obj when checking for leaked\n  // mock objects.\n  static void AllowLeak(const void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies and clears all expectations on the given mock object.\n  // If the expectations aren't satisfied, generates one or more\n  // Google Test non-fatal failures and returns false.\n  static bool VerifyAndClearExpectations(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies all expectations on the given mock object and clears its\n  // default actions and expectations.  Returns true if and only if the\n  // verification was successful.\n  static bool VerifyAndClear(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Returns whether the mock was created as a naggy mock (default)\n  static bool IsNaggy(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n  // Returns whether the mock was created as a nice mock\n  static bool IsNice(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n  // Returns whether the mock was created as a strict mock\n  static bool IsStrict(void* mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n private:\n  friend class internal::UntypedFunctionMockerBase;\n\n  // Needed for a function mocker to register itself (so that we know\n  // how to clear a mock object).\n  template <typename F>\n  friend class internal::FunctionMocker;\n\n  template <typename MockClass>\n  friend class internal::NiceMockImpl;\n  template <typename MockClass>\n  friend class internal::NaggyMockImpl;\n  template <typename MockClass>\n  friend class internal::StrictMockImpl;\n\n  // Tells Google Mock to allow uninteresting calls on the given mock\n  // object.\n  static void AllowUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock to warn the user about uninteresting calls on\n  // the given mock object.\n  static void WarnUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock to fail uninteresting calls on the given mock\n  // object.\n  static void FailUninterestingCalls(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock the given mock object is being destroyed and\n  // its entry in the call-reaction table should be removed.\n  static void UnregisterCallReaction(uintptr_t mock_obj)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Returns the reaction Google Mock will have on uninteresting calls\n  // made on the given mock object.\n  static internal::CallReaction GetReactionOnUninterestingCalls(\n      const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Verifies that all expectations on the given mock object have been\n  // satisfied.  Reports one or more Google Test non-fatal failures\n  // and returns false if not.\n  static bool VerifyAndClearExpectationsLocked(void* mock_obj)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n\n  // Clears all ON_CALL()s set on the given mock object.\n  static void ClearDefaultActionsLocked(void* mock_obj)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n\n  // Registers a mock object and a mock method it owns.\n  static void Register(const void* mock_obj,\n                       internal::UntypedFunctionMockerBase* mocker)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Tells Google Mock where in the source code mock_obj is used in an\n  // ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this\n  // information helps the user identify which object it is.\n  static void RegisterUseByOnCallOrExpectCall(const void* mock_obj,\n                                              const char* file, int line)\n      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);\n\n  // Unregisters a mock method; removes the owning mock object from\n  // the registry when the last mock method associated with it has\n  // been unregistered.  This is called only in the destructor of\n  // FunctionMocker.\n  static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);\n};  // class Mock\n\n// An abstract handle of an expectation.  Useful in the .After()\n// clause of EXPECT_CALL() for setting the (partial) order of\n// expectations.  The syntax:\n//\n//   Expectation e1 = EXPECT_CALL(...)...;\n//   EXPECT_CALL(...).After(e1)...;\n//\n// sets two expectations where the latter can only be matched after\n// the former has been satisfied.\n//\n// Notes:\n//   - This class is copyable and has value semantics.\n//   - Constness is shallow: a const Expectation object itself cannot\n//     be modified, but the mutable methods of the ExpectationBase\n//     object it references can be called via expectation_base().\n\nclass GTEST_API_ Expectation {\n public:\n  // Constructs a null object that doesn't reference any expectation.\n  Expectation();\n  Expectation(Expectation&&) = default;\n  Expectation(const Expectation&) = default;\n  Expectation& operator=(Expectation&&) = default;\n  Expectation& operator=(const Expectation&) = default;\n  ~Expectation();\n\n  // This single-argument ctor must not be explicit, in order to support the\n  //   Expectation e = EXPECT_CALL(...);\n  // syntax.\n  //\n  // A TypedExpectation object stores its pre-requisites as\n  // Expectation objects, and needs to call the non-const Retire()\n  // method on the ExpectationBase objects they reference.  Therefore\n  // Expectation must receive a *non-const* reference to the\n  // ExpectationBase object.\n  Expectation(internal::ExpectationBase& exp);  // NOLINT\n\n  // The compiler-generated copy ctor and operator= work exactly as\n  // intended, so we don't need to define our own.\n\n  // Returns true if and only if rhs references the same expectation as this\n  // object does.\n  bool operator==(const Expectation& rhs) const {\n    return expectation_base_ == rhs.expectation_base_;\n  }\n\n  bool operator!=(const Expectation& rhs) const { return !(*this == rhs); }\n\n private:\n  friend class ExpectationSet;\n  friend class Sequence;\n  friend class ::testing::internal::ExpectationBase;\n  friend class ::testing::internal::UntypedFunctionMockerBase;\n\n  template <typename F>\n  friend class ::testing::internal::FunctionMocker;\n\n  template <typename F>\n  friend class ::testing::internal::TypedExpectation;\n\n  // This comparator is needed for putting Expectation objects into a set.\n  class Less {\n   public:\n    bool operator()(const Expectation& lhs, const Expectation& rhs) const {\n      return lhs.expectation_base_.get() < rhs.expectation_base_.get();\n    }\n  };\n\n  typedef ::std::set<Expectation, Less> Set;\n\n  Expectation(\n      const std::shared_ptr<internal::ExpectationBase>& expectation_base);\n\n  // Returns the expectation this object references.\n  const std::shared_ptr<internal::ExpectationBase>& expectation_base() const {\n    return expectation_base_;\n  }\n\n  // A shared_ptr that co-owns the expectation this handle references.\n  std::shared_ptr<internal::ExpectationBase> expectation_base_;\n};\n\n// A set of expectation handles.  Useful in the .After() clause of\n// EXPECT_CALL() for setting the (partial) order of expectations.  The\n// syntax:\n//\n//   ExpectationSet es;\n//   es += EXPECT_CALL(...)...;\n//   es += EXPECT_CALL(...)...;\n//   EXPECT_CALL(...).After(es)...;\n//\n// sets three expectations where the last one can only be matched\n// after the first two have both been satisfied.\n//\n// This class is copyable and has value semantics.\nclass ExpectationSet {\n public:\n  // A bidirectional iterator that can read a const element in the set.\n  typedef Expectation::Set::const_iterator const_iterator;\n\n  // An object stored in the set.  This is an alias of Expectation.\n  typedef Expectation::Set::value_type value_type;\n\n  // Constructs an empty set.\n  ExpectationSet() = default;\n\n  // This single-argument ctor must not be explicit, in order to support the\n  //   ExpectationSet es = EXPECT_CALL(...);\n  // syntax.\n  ExpectationSet(internal::ExpectationBase& exp) {  // NOLINT\n    *this += Expectation(exp);\n  }\n\n  // This single-argument ctor implements implicit conversion from\n  // Expectation and thus must not be explicit.  This allows either an\n  // Expectation or an ExpectationSet to be used in .After().\n  ExpectationSet(const Expectation& e) {  // NOLINT\n    *this += e;\n  }\n\n  // The compiler-generator ctor and operator= works exactly as\n  // intended, so we don't need to define our own.\n\n  // Returns true if and only if rhs contains the same set of Expectation\n  // objects as this does.\n  bool operator==(const ExpectationSet& rhs) const {\n    return expectations_ == rhs.expectations_;\n  }\n\n  bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); }\n\n  // Implements the syntax\n  //   expectation_set += EXPECT_CALL(...);\n  ExpectationSet& operator+=(const Expectation& e) {\n    expectations_.insert(e);\n    return *this;\n  }\n\n  int size() const { return static_cast<int>(expectations_.size()); }\n\n  const_iterator begin() const { return expectations_.begin(); }\n  const_iterator end() const { return expectations_.end(); }\n\n private:\n  Expectation::Set expectations_;\n};\n\n// Sequence objects are used by a user to specify the relative order\n// in which the expectations should match.  They are copyable (we rely\n// on the compiler-defined copy constructor and assignment operator).\nclass GTEST_API_ Sequence {\n public:\n  // Constructs an empty sequence.\n  Sequence() : last_expectation_(new Expectation) {}\n\n  // Adds an expectation to this sequence.  The caller must ensure\n  // that no other thread is accessing this Sequence object.\n  void AddExpectation(const Expectation& expectation) const;\n\n private:\n  // The last expectation in this sequence.\n  std::shared_ptr<Expectation> last_expectation_;\n};  // class Sequence\n\n// An object of this type causes all EXPECT_CALL() statements\n// encountered in its scope to be put in an anonymous sequence.  The\n// work is done in the constructor and destructor.  You should only\n// create an InSequence object on the stack.\n//\n// The sole purpose for this class is to support easy definition of\n// sequential expectations, e.g.\n//\n//   {\n//     InSequence dummy;  // The name of the object doesn't matter.\n//\n//     // The following expectations must match in the order they appear.\n//     EXPECT_CALL(a, Bar())...;\n//     EXPECT_CALL(a, Baz())...;\n//     ...\n//     EXPECT_CALL(b, Xyz())...;\n//   }\n//\n// You can create InSequence objects in multiple threads, as long as\n// they are used to affect different mock objects.  The idea is that\n// each thread can create and set up its own mocks as if it's the only\n// thread.  However, for clarity of your tests we recommend you to set\n// up mocks in the main thread unless you have a good reason not to do\n// so.\nclass GTEST_API_ InSequence {\n public:\n  InSequence();\n  ~InSequence();\n\n private:\n  bool sequence_created_;\n\n  InSequence(const InSequence&) = delete;\n  InSequence& operator=(const InSequence&) = delete;\n};\n\nnamespace internal {\n\n// Points to the implicit sequence introduced by a living InSequence\n// object (if any) in the current thread or NULL.\nGTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;\n\n// Base class for implementing expectations.\n//\n// There are two reasons for having a type-agnostic base class for\n// Expectation:\n//\n//   1. We need to store collections of expectations of different\n//   types (e.g. all pre-requisites of a particular expectation, all\n//   expectations in a sequence).  Therefore these expectation objects\n//   must share a common base class.\n//\n//   2. We can avoid binary code bloat by moving methods not depending\n//   on the template argument of Expectation to the base class.\n//\n// This class is internal and mustn't be used by user code directly.\nclass GTEST_API_ ExpectationBase {\n public:\n  // source_text is the EXPECT_CALL(...) source that created this Expectation.\n  ExpectationBase(const char* file, int line, const std::string& source_text);\n\n  virtual ~ExpectationBase();\n\n  // Where in the source file was the expectation spec defined?\n  const char* file() const { return file_; }\n  int line() const { return line_; }\n  const char* source_text() const { return source_text_.c_str(); }\n  // Returns the cardinality specified in the expectation spec.\n  const Cardinality& cardinality() const { return cardinality_; }\n\n  // Describes the source file location of this expectation.\n  void DescribeLocationTo(::std::ostream* os) const {\n    *os << FormatFileLocation(file(), line()) << \" \";\n  }\n\n  // Describes how many times a function call matching this\n  // expectation has occurred.\n  void DescribeCallCountTo(::std::ostream* os) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // If this mock method has an extra matcher (i.e. .With(matcher)),\n  // describes it to the ostream.\n  virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;\n\n  // Do not rely on this for correctness.\n  // This is only for making human-readable test output easier to understand.\n  void UntypedDescription(std::string description) {\n    description_ = std::move(description);\n  }\n\n protected:\n  friend class ::testing::Expectation;\n  friend class UntypedFunctionMockerBase;\n\n  enum Clause {\n    // Don't change the order of the enum members!\n    kNone,\n    kWith,\n    kTimes,\n    kInSequence,\n    kAfter,\n    kWillOnce,\n    kWillRepeatedly,\n    kRetiresOnSaturation\n  };\n\n  typedef std::vector<const void*> UntypedActions;\n\n  // Returns an Expectation object that references and co-owns this\n  // expectation.\n  virtual Expectation GetHandle() = 0;\n\n  // Asserts that the EXPECT_CALL() statement has the given property.\n  void AssertSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Assert(property, file_, line_, failure_message);\n  }\n\n  // Expects that the EXPECT_CALL() statement has the given property.\n  void ExpectSpecProperty(bool property,\n                          const std::string& failure_message) const {\n    Expect(property, file_, line_, failure_message);\n  }\n\n  // Explicitly specifies the cardinality of this expectation.  Used\n  // by the subclasses to implement the .Times() clause.\n  void SpecifyCardinality(const Cardinality& cardinality);\n\n  // Returns true if and only if the user specified the cardinality\n  // explicitly using a .Times().\n  bool cardinality_specified() const { return cardinality_specified_; }\n\n  // Sets the cardinality of this expectation spec.\n  void set_cardinality(const Cardinality& a_cardinality) {\n    cardinality_ = a_cardinality;\n  }\n\n  // The following group of methods should only be called after the\n  // EXPECT_CALL() statement, and only when g_gmock_mutex is held by\n  // the current thread.\n\n  // Retires all pre-requisites of this expectation.\n  void RetireAllPreRequisites() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Returns true if and only if this expectation is retired.\n  bool is_retired() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return retired_;\n  }\n\n  // Retires this expectation.\n  void Retire() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    retired_ = true;\n  }\n\n  // Returns a human-readable description of this expectation.\n  // Do not rely on this for correctness. It is only for human readability.\n  const std::string& GetDescription() const { return description_; }\n\n  // Returns true if and only if this expectation is satisfied.\n  bool IsSatisfied() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsSatisfiedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if this expectation is saturated.\n  bool IsSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsSaturatedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if this expectation is over-saturated.\n  bool IsOverSaturated() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return cardinality().IsOverSaturatedByCallCount(call_count_);\n  }\n\n  // Returns true if and only if all pre-requisites of this expectation are\n  // satisfied.\n  bool AllPrerequisitesAreSatisfied() const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Adds unsatisfied pre-requisites of this expectation to 'result'.\n  void FindUnsatisfiedPrerequisites(ExpectationSet* result) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);\n\n  // Returns the number this expectation has been invoked.\n  int call_count() const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return call_count_;\n  }\n\n  // Increments the number this expectation has been invoked.\n  void IncrementCallCount() GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    call_count_++;\n  }\n\n  // Checks the action count (i.e. the number of WillOnce() and\n  // WillRepeatedly() clauses) against the cardinality if this hasn't\n  // been done before.  Prints a warning if there are too many or too\n  // few actions.\n  void CheckActionCountIfNotDone() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n  friend class ::testing::Sequence;\n  friend class ::testing::internal::ExpectationTester;\n\n  template <typename Function>\n  friend class TypedExpectation;\n\n  // Implements the .Times() clause.\n  void UntypedTimes(const Cardinality& a_cardinality);\n\n  // This group of fields are part of the spec and won't change after\n  // an EXPECT_CALL() statement finishes.\n  const char* file_;               // The file that contains the expectation.\n  int line_;                       // The line number of the expectation.\n  const std::string source_text_;  // The EXPECT_CALL(...) source text.\n  std::string description_;        // User-readable name for the expectation.\n  // True if and only if the cardinality is specified explicitly.\n  bool cardinality_specified_;\n  Cardinality cardinality_;  // The cardinality of the expectation.\n  // The immediate pre-requisites (i.e. expectations that must be\n  // satisfied before this expectation can be matched) of this\n  // expectation.  We use std::shared_ptr in the set because we want an\n  // Expectation object to be co-owned by its FunctionMocker and its\n  // successors.  This allows multiple mock objects to be deleted at\n  // different times.\n  ExpectationSet immediate_prerequisites_;\n\n  // This group of fields are the current state of the expectation,\n  // and can change as the mock function is called.\n  int call_count_;  // How many times this expectation has been invoked.\n  bool retired_;    // True if and only if this expectation has retired.\n  UntypedActions untyped_actions_;\n  bool extra_matcher_specified_;\n  bool repeated_action_specified_;  // True if a WillRepeatedly() was specified.\n  bool retires_on_saturation_;\n  Clause last_clause_;\n  mutable bool action_count_checked_;  // Under mutex_.\n  mutable Mutex mutex_;                // Protects action_count_checked_.\n};                                     // class ExpectationBase\n\ntemplate <typename F>\nclass TypedExpectation;\n\n// Implements an expectation for the given function type.\ntemplate <typename R, typename... Args>\nclass TypedExpectation<R(Args...)> : public ExpectationBase {\n private:\n  using F = R(Args...);\n\n public:\n  typedef typename Function<F>::ArgumentTuple ArgumentTuple;\n  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n  typedef typename Function<F>::Result Result;\n\n  TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,\n                   const std::string& a_source_text,\n                   const ArgumentMatcherTuple& m)\n      : ExpectationBase(a_file, a_line, a_source_text),\n        owner_(owner),\n        matchers_(m),\n        // By default, extra_matcher_ should match anything.  However,\n        // we cannot initialize it with _ as that causes ambiguity between\n        // Matcher's copy and move constructor for some argument types.\n        extra_matcher_(A<const ArgumentTuple&>()),\n        repeated_action_(DoDefault()) {}\n\n  ~TypedExpectation() override {\n    // Check the validity of the action count if it hasn't been done\n    // yet (for example, if the expectation was never used).\n    CheckActionCountIfNotDone();\n    for (UntypedActions::const_iterator it = untyped_actions_.begin();\n         it != untyped_actions_.end(); ++it) {\n      delete static_cast<const Action<F>*>(*it);\n    }\n  }\n\n  // Implements the .With() clause.\n  TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) {\n    if (last_clause_ == kWith) {\n      ExpectSpecProperty(false,\n                         \".With() cannot appear \"\n                         \"more than once in an EXPECT_CALL().\");\n    } else {\n      ExpectSpecProperty(last_clause_ < kWith,\n                         \".With() must be the first \"\n                         \"clause in an EXPECT_CALL().\");\n    }\n    last_clause_ = kWith;\n\n    extra_matcher_ = m;\n    extra_matcher_specified_ = true;\n    return *this;\n  }\n\n  // Do not rely on this for correctness.\n  // This is only for making human-readable test output easier to understand.\n  TypedExpectation& Description(std::string name) {\n    ExpectationBase::UntypedDescription(std::move(name));\n    return *this;\n  }\n\n  // Implements the .Times() clause.\n  TypedExpectation& Times(const Cardinality& a_cardinality) {\n    ExpectationBase::UntypedTimes(a_cardinality);\n    return *this;\n  }\n\n  // Implements the .Times() clause.\n  TypedExpectation& Times(int n) { return Times(Exactly(n)); }\n\n  // Implements the .InSequence() clause.\n  TypedExpectation& InSequence(const Sequence& s) {\n    ExpectSpecProperty(last_clause_ <= kInSequence,\n                       \".InSequence() cannot appear after .After(),\"\n                       \" .WillOnce(), .WillRepeatedly(), or \"\n                       \".RetiresOnSaturation().\");\n    last_clause_ = kInSequence;\n\n    s.AddExpectation(GetHandle());\n    return *this;\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) {\n    return InSequence(s1).InSequence(s2);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3) {\n    return InSequence(s1, s2).InSequence(s3);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3, const Sequence& s4) {\n    return InSequence(s1, s2, s3).InSequence(s4);\n  }\n  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,\n                               const Sequence& s3, const Sequence& s4,\n                               const Sequence& s5) {\n    return InSequence(s1, s2, s3, s4).InSequence(s5);\n  }\n\n  // Implements that .After() clause.\n  TypedExpectation& After(const ExpectationSet& s) {\n    ExpectSpecProperty(last_clause_ <= kAfter,\n                       \".After() cannot appear after .WillOnce(),\"\n                       \" .WillRepeatedly(), or \"\n                       \".RetiresOnSaturation().\");\n    last_clause_ = kAfter;\n\n    for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) {\n      immediate_prerequisites_ += *it;\n    }\n    return *this;\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) {\n    return After(s1).After(s2);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3) {\n    return After(s1, s2).After(s3);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3, const ExpectationSet& s4) {\n    return After(s1, s2, s3).After(s4);\n  }\n  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,\n                          const ExpectationSet& s3, const ExpectationSet& s4,\n                          const ExpectationSet& s5) {\n    return After(s1, s2, s3, s4).After(s5);\n  }\n\n  // Preferred, type-safe overload: consume anything that can be directly\n  // converted to a OnceAction, except for Action<F> objects themselves.\n  TypedExpectation& WillOnce(OnceAction<F> once_action) {\n    // Call the overload below, smuggling the OnceAction as a copyable callable.\n    // We know this is safe because a WillOnce action will not be called more\n    // than once.\n    return WillOnce(Action<F>(ActionAdaptor{\n        std::make_shared<OnceAction<F>>(std::move(once_action)),\n    }));\n  }\n\n  // Fallback overload: accept Action<F> objects and those actions that define\n  // `operator Action<F>` but not `operator OnceAction<F>`.\n  //\n  // This is templated in order to cause the overload above to be preferred\n  // when the input is convertible to either type.\n  template <int&... ExplicitArgumentBarrier, typename = void>\n  TypedExpectation& WillOnce(Action<F> action) {\n    ExpectSpecProperty(last_clause_ <= kWillOnce,\n                       \".WillOnce() cannot appear after \"\n                       \".WillRepeatedly() or .RetiresOnSaturation().\");\n    last_clause_ = kWillOnce;\n\n    untyped_actions_.push_back(new Action<F>(std::move(action)));\n\n    if (!cardinality_specified()) {\n      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));\n    }\n    return *this;\n  }\n\n  // Implements the .WillRepeatedly() clause.\n  TypedExpectation& WillRepeatedly(const Action<F>& action) {\n    if (last_clause_ == kWillRepeatedly) {\n      ExpectSpecProperty(false,\n                         \".WillRepeatedly() cannot appear \"\n                         \"more than once in an EXPECT_CALL().\");\n    } else {\n      ExpectSpecProperty(last_clause_ < kWillRepeatedly,\n                         \".WillRepeatedly() cannot appear \"\n                         \"after .RetiresOnSaturation().\");\n    }\n    last_clause_ = kWillRepeatedly;\n    repeated_action_specified_ = true;\n\n    repeated_action_ = action;\n    if (!cardinality_specified()) {\n      set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size())));\n    }\n\n    // Now that no more action clauses can be specified, we check\n    // whether their count makes sense.\n    CheckActionCountIfNotDone();\n    return *this;\n  }\n\n  // Implements the .RetiresOnSaturation() clause.\n  TypedExpectation& RetiresOnSaturation() {\n    ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,\n                       \".RetiresOnSaturation() cannot appear \"\n                       \"more than once.\");\n    last_clause_ = kRetiresOnSaturation;\n    retires_on_saturation_ = true;\n\n    // Now that no more action clauses can be specified, we check\n    // whether their count makes sense.\n    CheckActionCountIfNotDone();\n    return *this;\n  }\n\n  // Returns the matchers for the arguments as specified inside the\n  // EXPECT_CALL() macro.\n  const ArgumentMatcherTuple& matchers() const { return matchers_; }\n\n  // Returns the matcher specified by the .With() clause.\n  const Matcher<const ArgumentTuple&>& extra_matcher() const {\n    return extra_matcher_;\n  }\n\n  // Returns the action specified by the .WillRepeatedly() clause.\n  const Action<F>& repeated_action() const { return repeated_action_; }\n\n  // If this mock method has an extra matcher (i.e. .With(matcher)),\n  // describes it to the ostream.\n  void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {\n    if (extra_matcher_specified_) {\n      *os << \"    Expected args: \";\n      extra_matcher_.DescribeTo(os);\n      *os << \"\\n\";\n    }\n  }\n\n private:\n  template <typename Function>\n  friend class FunctionMocker;\n\n  // An adaptor that turns a OneAction<F> into something compatible with\n  // Action<F>. Must be called at most once.\n  struct ActionAdaptor {\n    std::shared_ptr<OnceAction<R(Args...)>> once_action;\n\n    R operator()(Args&&... args) const {\n      return std::move(*once_action).Call(std::forward<Args>(args)...);\n    }\n  };\n\n  // Returns an Expectation object that references and co-owns this\n  // expectation.\n  Expectation GetHandle() override { return owner_->GetHandleOf(this); }\n\n  // The following methods will be called only after the EXPECT_CALL()\n  // statement finishes and when the current thread holds\n  // g_gmock_mutex.\n\n  // Returns true if and only if this expectation matches the given arguments.\n  bool Matches(const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);\n  }\n\n  // Returns true if and only if this expectation should handle the given\n  // arguments.\n  bool ShouldHandleArguments(const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    // In case the action count wasn't checked when the expectation\n    // was defined (e.g. if this expectation has no WillRepeatedly()\n    // or RetiresOnSaturation() clause), we check it when the\n    // expectation is used for the first time.\n    CheckActionCountIfNotDone();\n    return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args);\n  }\n\n  // Describes the result of matching the arguments against this\n  // expectation to the given ostream.\n  void ExplainMatchResultTo(const ArgumentTuple& args, ::std::ostream* os) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    if (is_retired()) {\n      *os << \"         Expected: the expectation is active\\n\"\n          << \"           Actual: it is retired\\n\";\n    } else if (!Matches(args)) {\n      if (!TupleMatches(matchers_, args)) {\n        ExplainMatchFailureTupleTo(matchers_, args, os);\n      }\n      StringMatchResultListener listener;\n      if (!extra_matcher_.MatchAndExplain(args, &listener)) {\n        *os << \"    Expected args: \";\n        extra_matcher_.DescribeTo(os);\n        *os << \"\\n           Actual: don't match\";\n\n        internal::PrintIfNotEmpty(listener.str(), os);\n        *os << \"\\n\";\n      }\n    } else if (!AllPrerequisitesAreSatisfied()) {\n      *os << \"         Expected: all pre-requisites are satisfied\\n\"\n          << \"           Actual: the following immediate pre-requisites \"\n          << \"are not satisfied:\\n\";\n      ExpectationSet unsatisfied_prereqs;\n      FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);\n      int i = 0;\n      for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();\n           it != unsatisfied_prereqs.end(); ++it) {\n        it->expectation_base()->DescribeLocationTo(os);\n        *os << \"pre-requisite #\" << i++ << \"\\n\";\n      }\n      *os << \"                   (end of pre-requisites)\\n\";\n    } else {\n      // This line is here just for completeness' sake.  It will never\n      // be executed as currently the ExplainMatchResultTo() function\n      // is called only when the mock function call does NOT match the\n      // expectation.\n      *os << \"The call matches the expectation.\\n\";\n    }\n  }\n\n  // Returns the action that should be taken for the current invocation.\n  const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,\n                                    const ArgumentTuple& args) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const int count = call_count();\n    Assert(count >= 1, __FILE__, __LINE__,\n           \"call_count() is <= 0 when GetCurrentAction() is \"\n           \"called - this should never happen.\");\n\n    const int action_count = static_cast<int>(untyped_actions_.size());\n    if (action_count > 0 && !repeated_action_specified_ &&\n        count > action_count) {\n      // If there is at least one WillOnce() and no WillRepeatedly(),\n      // we warn the user when the WillOnce() clauses ran out.\n      ::std::stringstream ss;\n      DescribeLocationTo(&ss);\n      ss << \"Actions ran out in \" << source_text() << \"...\\n\"\n         << \"Called \" << count << \" times, but only \" << action_count\n         << \" WillOnce()\" << (action_count == 1 ? \" is\" : \"s are\")\n         << \" specified - \";\n      mocker->DescribeDefaultActionTo(args, &ss);\n      Log(kWarning, ss.str(), 1);\n    }\n\n    return count <= action_count\n               ? *static_cast<const Action<F>*>(\n                     untyped_actions_[static_cast<size_t>(count - 1)])\n               : repeated_action();\n  }\n\n  // Given the arguments of a mock function call, if the call will\n  // over-saturate this expectation, returns the default action;\n  // otherwise, returns the next action in this expectation.  Also\n  // describes *what* happened to 'what', and explains *why* Google\n  // Mock does it to 'why'.  This method is not const as it calls\n  // IncrementCallCount().  A return value of NULL means the default\n  // action.\n  const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,\n                                         const ArgumentTuple& args,\n                                         ::std::ostream* what,\n                                         ::std::ostream* why)\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const ::std::string& expectation_description = GetDescription();\n    if (IsSaturated()) {\n      // We have an excessive call.\n      IncrementCallCount();\n      *what << \"Mock function \";\n      if (!expectation_description.empty()) {\n        *what << \"\\\"\" << expectation_description << \"\\\" \";\n      }\n      *what << \"called more times than expected - \";\n      mocker->DescribeDefaultActionTo(args, what);\n      DescribeCallCountTo(why);\n\n      return nullptr;\n    }\n\n    IncrementCallCount();\n    RetireAllPreRequisites();\n\n    if (retires_on_saturation_ && IsSaturated()) {\n      Retire();\n    }\n\n    // Must be done after IncrementCount()!\n    *what << \"Mock function \";\n    if (!expectation_description.empty()) {\n      *what << \"\\\"\" << expectation_description << \"\\\" \";\n    }\n    *what << \"call matches \" << source_text() << \"...\\n\";\n    return &(GetCurrentAction(mocker, args));\n  }\n\n  // All the fields below won't change once the EXPECT_CALL()\n  // statement finishes.\n  FunctionMocker<F>* const owner_;\n  ArgumentMatcherTuple matchers_;\n  Matcher<const ArgumentTuple&> extra_matcher_;\n  Action<F> repeated_action_;\n\n  TypedExpectation(const TypedExpectation&) = delete;\n  TypedExpectation& operator=(const TypedExpectation&) = delete;\n};  // class TypedExpectation\n\n// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for\n// specifying the default behavior of, or expectation on, a mock\n// function.\n\n// Note: class MockSpec really belongs to the ::testing namespace.\n// However if we define it in ::testing, MSVC will complain when\n// classes in ::testing::internal declare it as a friend class\n// template.  To workaround this compiler bug, we define MockSpec in\n// ::testing::internal and import it into ::testing.\n\n// Logs a message including file and line number information.\nGTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,\n                                const char* file, int line,\n                                const std::string& message);\n\ntemplate <typename F>\nclass MockSpec {\n public:\n  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;\n  typedef\n      typename internal::Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;\n\n  // Constructs a MockSpec object, given the function mocker object\n  // that the spec is associated with.\n  MockSpec(internal::FunctionMocker<F>* function_mocker,\n           const ArgumentMatcherTuple& matchers)\n      : function_mocker_(function_mocker), matchers_(matchers) {}\n\n  // Adds a new default action spec to the function mocker and returns\n  // the newly created spec.\n  internal::OnCallSpec<F>& InternalDefaultActionSetAt(const char* file,\n                                                      int line, const char* obj,\n                                                      const char* call) {\n    LogWithLocation(internal::kInfo, file, line,\n                    std::string(\"ON_CALL(\") + obj + \", \" + call + \") invoked\");\n    return function_mocker_->AddNewOnCallSpec(file, line, matchers_);\n  }\n\n  // Adds a new expectation spec to the function mocker and returns\n  // the newly created spec.\n  internal::TypedExpectation<F>& InternalExpectedAt(const char* file, int line,\n                                                    const char* obj,\n                                                    const char* call) {\n    const std::string source_text(std::string(\"EXPECT_CALL(\") + obj + \", \" +\n                                  call + \")\");\n    LogWithLocation(internal::kInfo, file, line, source_text + \" invoked\");\n    return function_mocker_->AddNewExpectation(file, line, source_text,\n                                               matchers_);\n  }\n\n  // This operator overload is used to swallow the superfluous parameter list\n  // introduced by the ON/EXPECT_CALL macros. See the macro comments for more\n  // explanation.\n  MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {\n    return *this;\n  }\n\n private:\n  template <typename Function>\n  friend class internal::FunctionMocker;\n\n  // The function mocker that owns this spec.\n  internal::FunctionMocker<F>* const function_mocker_;\n  // The argument matchers specified in the spec.\n  ArgumentMatcherTuple matchers_;\n};  // class MockSpec\n\n// Wrapper type for generically holding an ordinary value or lvalue reference.\n// If T is not a reference type, it must be copyable or movable.\n// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless\n// T is a move-only value type (which means that it will always be copyable\n// if the current platform does not support move semantics).\n//\n// The primary template defines handling for values, but function header\n// comments describe the contract for the whole template (including\n// specializations).\ntemplate <typename T>\nclass ReferenceOrValueWrapper {\n public:\n  // Constructs a wrapper from the given value/reference.\n  explicit ReferenceOrValueWrapper(T value) : value_(std::move(value)) {}\n\n  // Unwraps and returns the underlying value/reference, exactly as\n  // originally passed. The behavior of calling this more than once on\n  // the same object is unspecified.\n  T Unwrap() { return std::move(value_); }\n\n  // Provides nondestructive access to the underlying value/reference.\n  // Always returns a const reference (more precisely,\n  // const std::add_lvalue_reference<T>::type). The behavior of calling this\n  // after calling Unwrap on the same object is unspecified.\n  const T& Peek() const { return value_; }\n\n private:\n  T value_;\n};\n\n// Specialization for lvalue reference types. See primary template\n// for documentation.\ntemplate <typename T>\nclass ReferenceOrValueWrapper<T&> {\n public:\n  // Workaround for debatable pass-by-reference lint warning (c-library-team\n  // policy precludes NOLINT in this context)\n  typedef T& reference;\n  explicit ReferenceOrValueWrapper(reference ref) : value_ptr_(&ref) {}\n  T& Unwrap() { return *value_ptr_; }\n  const T& Peek() const { return *value_ptr_; }\n\n private:\n  T* value_ptr_;\n};\n\n// Prints the held value as an action's result to os.\ntemplate <typename T>\nvoid PrintAsActionResult(const T& result, std::ostream& os) {\n  os << \"\\n          Returns: \";\n  // T may be a reference type, so we don't use UniversalPrint().\n  UniversalPrinter<T>::Print(result, &os);\n}\n\n// Reports an uninteresting call (whose description is in msg) in the\n// manner specified by 'reaction'.\nGTEST_API_ void ReportUninterestingCall(CallReaction reaction,\n                                        const std::string& msg);\n\n// A generic RAII type that runs a user-provided function in its destructor.\nclass Cleanup final {\n public:\n  explicit Cleanup(std::function<void()> f) : f_(std::move(f)) {}\n  ~Cleanup() { f_(); }\n\n private:\n  std::function<void()> f_;\n};\n\nstruct UntypedFunctionMockerBase::UninterestingCallCleanupHandler {\n  CallReaction reaction;\n  std::stringstream& ss;\n\n  ~UninterestingCallCleanupHandler() {\n    ReportUninterestingCall(reaction, ss.str());\n  }\n};\n\nstruct UntypedFunctionMockerBase::FailureCleanupHandler {\n  std::stringstream& ss;\n  std::stringstream& why;\n  std::stringstream& loc;\n  const ExpectationBase* untyped_expectation;\n  bool found;\n  bool is_excessive;\n\n  ~FailureCleanupHandler() {\n    ss << \"\\n\" << why.str();\n\n    if (!found) {\n      // No expectation matches this call - reports a failure.\n      Expect(false, nullptr, -1, ss.str());\n    } else if (is_excessive) {\n      // We had an upper-bound violation and the failure message is in ss.\n      Expect(false, untyped_expectation->file(), untyped_expectation->line(),\n             ss.str());\n    } else {\n      // We had an expected call and the matching expectation is\n      // described in ss.\n      Log(kInfo, loc.str() + ss.str(), 2);\n    }\n  }\n};\n\ntemplate <typename F>\nclass FunctionMocker;\n\ntemplate <typename R, typename... Args>\nclass FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {\n  using F = R(Args...);\n\n public:\n  using Result = R;\n  using ArgumentTuple = std::tuple<Args...>;\n  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;\n\n  FunctionMocker() = default;\n\n  // There is no generally useful and implementable semantics of\n  // copying a mock object, so copying a mock is usually a user error.\n  // Thus we disallow copying function mockers.  If the user really\n  // wants to copy a mock object, they should implement their own copy\n  // operation, for example:\n  //\n  //   class MockFoo : public Foo {\n  //    public:\n  //     // Defines a copy constructor explicitly.\n  //     MockFoo(const MockFoo& src) {}\n  //     ...\n  //   };\n  FunctionMocker(const FunctionMocker&) = delete;\n  FunctionMocker& operator=(const FunctionMocker&) = delete;\n\n  // The destructor verifies that all expectations on this mock\n  // function have been satisfied.  If not, it will report Google Test\n  // non-fatal failures for the violations.\n  ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    MutexLock l(&g_gmock_mutex);\n    VerifyAndClearExpectationsLocked();\n    Mock::UnregisterLocked(this);\n    ClearDefaultActionsLocked();\n  }\n\n  // Returns the ON_CALL spec that matches this mock function with the\n  // given arguments; returns NULL if no matching ON_CALL is found.\n  // L = *\n  const OnCallSpec<F>* FindOnCallSpec(const ArgumentTuple& args) const {\n    for (UntypedOnCallSpecs::const_reverse_iterator it =\n             untyped_on_call_specs_.rbegin();\n         it != untyped_on_call_specs_.rend(); ++it) {\n      const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);\n      if (spec->Matches(args)) return spec;\n    }\n\n    return nullptr;\n  }\n\n  // Performs the default action of this mock function on the given\n  // arguments and returns the result. Asserts (or throws if\n  // exceptions are enabled) with a helpful call description if there\n  // is no valid return value. This method doesn't depend on the\n  // mutable state of this object, and thus can be called concurrently\n  // without locking.\n  // L = *\n  Result PerformDefaultAction(ArgumentTuple&& args,\n                              const std::string& call_description) const {\n    const OnCallSpec<F>* const spec = this->FindOnCallSpec(args);\n    if (spec != nullptr) {\n      return spec->GetAction().Perform(std::move(args));\n    }\n    const std::string message =\n        call_description +\n        \"\\n    The mock function has no default action \"\n        \"set, and its return type has no default value set.\";\n#if GTEST_HAS_EXCEPTIONS\n    if (!DefaultValue<Result>::Exists()) {\n      throw std::runtime_error(message);\n    }\n#else\n    Assert(DefaultValue<Result>::Exists(), \"\", -1, message);\n#endif\n    return DefaultValue<Result>::Get();\n  }\n\n  // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():\n  // clears the ON_CALL()s set on this mock function.\n  void ClearDefaultActionsLocked() override\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n\n    // Deleting our default actions may trigger other mock objects to be\n    // deleted, for example if an action contains a reference counted smart\n    // pointer to that mock object, and that is the last reference. So if we\n    // delete our actions within the context of the global mutex we may deadlock\n    // when this method is called again. Instead, make a copy of the set of\n    // actions to delete, clear our set within the mutex, and then delete the\n    // actions outside of the mutex.\n    UntypedOnCallSpecs specs_to_delete;\n    untyped_on_call_specs_.swap(specs_to_delete);\n\n    g_gmock_mutex.Unlock();\n    for (UntypedOnCallSpecs::const_iterator it = specs_to_delete.begin();\n         it != specs_to_delete.end(); ++it) {\n      delete static_cast<const OnCallSpec<F>*>(*it);\n    }\n\n    // Lock the mutex again, since the caller expects it to be locked when we\n    // return.\n    g_gmock_mutex.Lock();\n  }\n\n  // Returns the result of invoking this mock function with the given\n  // arguments.  This function can be safely called from multiple\n  // threads concurrently.\n  Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    return InvokeWith(ArgumentTuple(std::forward<Args>(args)...));\n  }\n\n  MockSpec<F> With(Matcher<Args>... m) {\n    return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));\n  }\n\n protected:\n  template <typename Function>\n  friend class MockSpec;\n\n  // Adds and returns a default action spec for this mock function.\n  OnCallSpec<F>& AddNewOnCallSpec(const char* file, int line,\n                                  const ArgumentMatcherTuple& m)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);\n    OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);\n    untyped_on_call_specs_.push_back(on_call_spec);\n    return *on_call_spec;\n  }\n\n  // Adds and returns an expectation spec for this mock function.\n  TypedExpectation<F>& AddNewExpectation(const char* file, int line,\n                                         const std::string& source_text,\n                                         const ArgumentMatcherTuple& m)\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);\n    TypedExpectation<F>* const expectation =\n        new TypedExpectation<F>(this, file, line, source_text, m);\n    const std::shared_ptr<ExpectationBase> untyped_expectation(expectation);\n    // See the definition of untyped_expectations_ for why access to\n    // it is unprotected here.\n    untyped_expectations_.push_back(untyped_expectation);\n\n    // Adds this expectation into the implicit sequence if there is one.\n    Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();\n    if (implicit_sequence != nullptr) {\n      implicit_sequence->AddExpectation(Expectation(untyped_expectation));\n    }\n\n    return *expectation;\n  }\n\n private:\n  template <typename Func>\n  friend class TypedExpectation;\n\n  // Some utilities needed for implementing UntypedInvokeWith().\n\n  // Describes what default action will be performed for the given\n  // arguments.\n  // L = *\n  void DescribeDefaultActionTo(const ArgumentTuple& args,\n                               ::std::ostream* os) const {\n    const OnCallSpec<F>* const spec = FindOnCallSpec(args);\n\n    if (spec == nullptr) {\n      *os << (std::is_void<Result>::value ? \"returning directly.\\n\"\n                                          : \"returning default value.\\n\");\n    } else {\n      *os << \"taking default action specified at:\\n\"\n          << FormatFileLocation(spec->file(), spec->line()) << \"\\n\";\n    }\n  }\n\n  // Writes a message that the call is uninteresting (i.e. neither\n  // explicitly expected nor explicitly unexpected) to the given\n  // ostream.\n  void UntypedDescribeUninterestingCall(const void* untyped_args,\n                                        ::std::ostream* os) const override\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    *os << \"Uninteresting mock function call - \";\n    DescribeDefaultActionTo(args, os);\n    *os << \"    Function call: \" << Name();\n    UniversalPrint(args, os);\n  }\n\n  // Returns the expectation that matches the given function arguments\n  // (or NULL is there's no match); when a match is found,\n  // untyped_action is set to point to the action that should be\n  // performed (or NULL if the action is \"do default\"), and\n  // is_excessive is modified to indicate whether the call exceeds the\n  // expected number.\n  //\n  // Critical section: We must find the matching expectation and the\n  // corresponding action that needs to be taken in an ATOMIC\n  // transaction.  Otherwise another thread may call this mock\n  // method in the middle and mess up the state.\n  //\n  // However, performing the action has to be left out of the critical\n  // section.  The reason is that we have no control on what the\n  // action does (it can invoke an arbitrary user function or even a\n  // mock function) and excessive locking could cause a dead lock.\n  const ExpectationBase* UntypedFindMatchingExpectation(\n      const void* untyped_args, const void** untyped_action, bool* is_excessive,\n      ::std::ostream* what, ::std::ostream* why) override\n      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    MutexLock l(&g_gmock_mutex);\n    TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);\n    if (exp == nullptr) {  // A match wasn't found.\n      this->FormatUnexpectedCallMessageLocked(args, what, why);\n      return nullptr;\n    }\n\n    // This line must be done before calling GetActionForArguments(),\n    // which will increment the call count for *exp and thus affect\n    // its saturation status.\n    *is_excessive = exp->IsSaturated();\n    const Action<F>* action = exp->GetActionForArguments(this, args, what, why);\n    if (action != nullptr && action->IsDoDefault())\n      action = nullptr;  // Normalize \"do default\" to NULL.\n    *untyped_action = action;\n    return exp;\n  }\n\n  // Prints the given function arguments to the ostream.\n  void UntypedPrintArgs(const void* untyped_args,\n                        ::std::ostream* os) const override {\n    const ArgumentTuple& args =\n        *static_cast<const ArgumentTuple*>(untyped_args);\n    UniversalPrint(args, os);\n  }\n\n  // Returns the expectation that matches the arguments, or NULL if no\n  // expectation matches them.\n  TypedExpectation<F>* FindMatchingExpectationLocked(const ArgumentTuple& args)\n      const GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    // See the definition of untyped_expectations_ for why access to\n    // it is unprotected here.\n    for (typename UntypedExpectations::const_reverse_iterator it =\n             untyped_expectations_.rbegin();\n         it != untyped_expectations_.rend(); ++it) {\n      TypedExpectation<F>* const exp =\n          static_cast<TypedExpectation<F>*>(it->get());\n      if (exp->ShouldHandleArguments(args)) {\n        return exp;\n      }\n    }\n    return nullptr;\n  }\n\n  // Returns a message that the arguments don't match any expectation.\n  void FormatUnexpectedCallMessageLocked(const ArgumentTuple& args,\n                                         ::std::ostream* os,\n                                         ::std::ostream* why) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    *os << \"\\nUnexpected mock function call - \";\n    DescribeDefaultActionTo(args, os);\n    PrintTriedExpectationsLocked(args, why);\n  }\n\n  // Prints a list of expectations that have been tried against the\n  // current mock function call.\n  void PrintTriedExpectationsLocked(const ArgumentTuple& args,\n                                    ::std::ostream* why) const\n      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n    g_gmock_mutex.AssertHeld();\n    const size_t count = untyped_expectations_.size();\n    *why << \"Google Mock tried the following \" << count << \" \"\n         << (count == 1 ? \"expectation, but it didn't match\"\n                        : \"expectations, but none matched\")\n         << \":\\n\";\n    for (size_t i = 0; i < count; i++) {\n      TypedExpectation<F>* const expectation =\n          static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());\n      *why << \"\\n\";\n      expectation->DescribeLocationTo(why);\n      if (count > 1) {\n        *why << \"tried expectation #\" << i << \": \";\n      }\n      *why << expectation->source_text() << \"...\\n\";\n      expectation->ExplainMatchResultTo(args, why);\n      expectation->DescribeCallCountTo(why);\n    }\n  }\n\n  // Performs the given action (or the default if it's null) with the given\n  // arguments and returns the action's result.\n  // L = *\n  R PerformAction(const void* untyped_action, ArgumentTuple&& args,\n                  const std::string& call_description) const {\n    if (untyped_action == nullptr) {\n      return PerformDefaultAction(std::move(args), call_description);\n    }\n\n    // Make a copy of the action before performing it, in case the\n    // action deletes the mock object (and thus deletes itself).\n    const Action<F> action = *static_cast<const Action<F>*>(untyped_action);\n    return action.Perform(std::move(args));\n  }\n\n  // Is it possible to store an object of the supplied type in a local variable\n  // for the sake of printing it, then return it on to the caller?\n  template <typename T>\n  using can_print_result = internal::conjunction<\n      // void can't be stored as an object (and we also don't need to print it).\n      internal::negation<std::is_void<T>>,\n      // Non-moveable types can't be returned on to the user, so there's no way\n      // for us to intercept and print them.\n      std::is_move_constructible<T>>;\n\n  // Perform the supplied action, printing the result to os.\n  template <typename T = R,\n            typename std::enable_if<can_print_result<T>::value, int>::type = 0>\n  R PerformActionAndPrintResult(const void* const untyped_action,\n                                ArgumentTuple&& args,\n                                const std::string& call_description,\n                                std::ostream& os) {\n    R result = PerformAction(untyped_action, std::move(args), call_description);\n\n    PrintAsActionResult(result, os);\n    return std::forward<R>(result);\n  }\n\n  // An overload for when it's not possible to print the result. In this case we\n  // simply perform the action.\n  template <typename T = R,\n            typename std::enable_if<\n                internal::negation<can_print_result<T>>::value, int>::type = 0>\n  R PerformActionAndPrintResult(const void* const untyped_action,\n                                ArgumentTuple&& args,\n                                const std::string& call_description,\n                                std::ostream&) {\n    return PerformAction(untyped_action, std::move(args), call_description);\n  }\n\n  // Returns the result of invoking this mock function with the given\n  // arguments. This function can be safely called from multiple\n  // threads concurrently.\n  R InvokeWith(ArgumentTuple&& args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);\n};  // class FunctionMocker\n\n// Calculates the result of invoking this mock function with the given\n// arguments, prints it, and returns it.\ntemplate <typename R, typename... Args>\nR FunctionMocker<R(Args...)>::InvokeWith(ArgumentTuple&& args)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  // See the definition of untyped_expectations_ for why access to it\n  // is unprotected here.\n  if (untyped_expectations_.size() == 0) {\n    // No expectation is set on this mock method - we have an\n    // uninteresting call.\n\n    // We must get Google Mock's reaction on uninteresting calls\n    // made on this mock object BEFORE performing the action,\n    // because the action may DELETE the mock object and make the\n    // following expression meaningless.\n    const CallReaction reaction =\n        Mock::GetReactionOnUninterestingCalls(MockObject());\n\n    // True if and only if we need to print this call's arguments and return\n    // value.  This definition must be kept in sync with\n    // the behavior of ReportUninterestingCall().\n    const bool need_to_report_uninteresting_call =\n        // If the user allows this uninteresting call, we print it\n        // only when they want informational messages.\n        reaction == kAllow ? LogIsVisible(kInfo) :\n                           // If the user wants this to be a warning, we print\n                           // it only when they want to see warnings.\n            reaction == kWarn\n            ? LogIsVisible(kWarning)\n            :\n            // Otherwise, the user wants this to be an error, and we\n            // should always print detailed information in the error.\n            true;\n\n    if (!need_to_report_uninteresting_call) {\n      // Perform the action without printing the call information.\n      return this->PerformDefaultAction(\n          std::move(args), \"Function call: \" + std::string(Name()));\n    }\n\n    // Warns about the uninteresting call.\n    ::std::stringstream ss;\n    this->UntypedDescribeUninterestingCall(&args, &ss);\n\n    // Perform the action, print the result, and then report the uninteresting\n    // call.\n    //\n    // We use RAII to do the latter in case R is void or a non-moveable type. In\n    // either case we can't assign it to a local variable.\n    //\n    // Note that std::bind() is essential here.\n    // We *don't* use any local callback types (like lambdas).\n    // Doing so slows down compilation dramatically because the *constructor* of\n    // std::function<T> is re-instantiated with different template\n    // parameters each time.\n    const UninterestingCallCleanupHandler report_uninteresting_call = {\n        reaction, ss\n    };\n\n    return PerformActionAndPrintResult(nullptr, std::move(args), ss.str(), ss);\n  }\n\n  bool is_excessive = false;\n  ::std::stringstream ss;\n  ::std::stringstream why;\n  ::std::stringstream loc;\n  const void* untyped_action = nullptr;\n\n  // The UntypedFindMatchingExpectation() function acquires and\n  // releases g_gmock_mutex.\n\n  const ExpectationBase* const untyped_expectation =\n      this->UntypedFindMatchingExpectation(&args, &untyped_action,\n                                           &is_excessive, &ss, &why);\n  const bool found = untyped_expectation != nullptr;\n\n  // True if and only if we need to print the call's arguments\n  // and return value.\n  // This definition must be kept in sync with the uses of Expect()\n  // and Log() in this function.\n  const bool need_to_report_call =\n      !found || is_excessive || LogIsVisible(kInfo);\n  if (!need_to_report_call) {\n    // Perform the action without printing the call information.\n    return PerformAction(untyped_action, std::move(args), \"\");\n  }\n\n  ss << \"    Function call: \" << Name();\n  this->UntypedPrintArgs(&args, &ss);\n\n  // In case the action deletes a piece of the expectation, we\n  // generate the message beforehand.\n  if (found && !is_excessive) {\n    untyped_expectation->DescribeLocationTo(&loc);\n  }\n\n  // Perform the action, print the result, and then fail or log in whatever way\n  // is appropriate.\n  //\n  // We use RAII to do the latter in case R is void or a non-moveable type. In\n  // either case we can't assign it to a local variable.\n  //\n  // Note that we *don't* use any local callback types (like lambdas) here.\n  // Doing so slows down compilation dramatically because the *constructor* of\n  // std::function<T> is re-instantiated with different template\n  // parameters each time.\n  const FailureCleanupHandler handle_failures = {\n      ss, why, loc, untyped_expectation, found, is_excessive\n  };\n\n  return PerformActionAndPrintResult(untyped_action, std::move(args), ss.str(),\n                                     ss);\n}\n\n}  // namespace internal\n\nnamespace internal {\n\ntemplate <typename F>\nclass MockFunction;\n\ntemplate <typename R, typename... Args>\nclass MockFunction<R(Args...)> {\n public:\n  MockFunction(const MockFunction&) = delete;\n  MockFunction& operator=(const MockFunction&) = delete;\n\n  std::function<R(Args...)> AsStdFunction() {\n    return [this](Args... args) -> R {\n      return this->Call(std::forward<Args>(args)...);\n    };\n  }\n\n  // Implementation detail: the expansion of the MOCK_METHOD macro.\n  R Call(Args... args) {\n    mock_.SetOwnerAndName(this, \"Call\");\n    return mock_.Invoke(std::forward<Args>(args)...);\n  }\n\n  MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {\n    mock_.RegisterOwner(this);\n    return mock_.With(std::move(m)...);\n  }\n\n  MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {\n    return this->gmock_Call(::testing::A<Args>()...);\n  }\n\n protected:\n  MockFunction() = default;\n  ~MockFunction() = default;\n\n private:\n  FunctionMocker<R(Args...)> mock_;\n};\n\n/*\nThe SignatureOf<F> struct is a meta-function returning function signature\ncorresponding to the provided F argument.\n\nIt makes use of MockFunction easier by allowing it to accept more F arguments\nthan just function signatures.\n\nSpecializations provided here cover a signature type itself and any template\nthat can be parameterized with a signature, including std::function and\nboost::function.\n*/\n\ntemplate <typename F, typename = void>\nstruct SignatureOf;\n\ntemplate <typename R, typename... Args>\nstruct SignatureOf<R(Args...)> {\n  using type = R(Args...);\n};\n\ntemplate <template <typename> class C, typename F>\nstruct SignatureOf<C<F>,\n                   typename std::enable_if<std::is_function<F>::value>::type>\n    : SignatureOf<F> {};\n\ntemplate <typename F>\nusing SignatureOfT = typename SignatureOf<F>::type;\n\n}  // namespace internal\n\n// A MockFunction<F> type has one mock method whose type is\n// internal::SignatureOfT<F>.  It is useful when you just want your\n// test code to emit some messages and have Google Mock verify the\n// right messages are sent (and perhaps at the right times).  For\n// example, if you are exercising code:\n//\n//   Foo(1);\n//   Foo(2);\n//   Foo(3);\n//\n// and want to verify that Foo(1) and Foo(3) both invoke\n// mock.Bar(\"a\"), but Foo(2) doesn't invoke anything, you can write:\n//\n// TEST(FooTest, InvokesBarCorrectly) {\n//   MyMock mock;\n//   MockFunction<void(string check_point_name)> check;\n//   {\n//     InSequence s;\n//\n//     EXPECT_CALL(mock, Bar(\"a\"));\n//     EXPECT_CALL(check, Call(\"1\"));\n//     EXPECT_CALL(check, Call(\"2\"));\n//     EXPECT_CALL(mock, Bar(\"a\"));\n//   }\n//   Foo(1);\n//   check.Call(\"1\");\n//   Foo(2);\n//   check.Call(\"2\");\n//   Foo(3);\n// }\n//\n// The expectation spec says that the first Bar(\"a\") must happen\n// before check point \"1\", the second Bar(\"a\") must happen after check\n// point \"2\", and nothing should happen between the two check\n// points. The explicit check points make it easy to tell which\n// Bar(\"a\") is called by which call to Foo().\n//\n// MockFunction<F> can also be used to exercise code that accepts\n// std::function<internal::SignatureOfT<F>> callbacks. To do so, use\n// AsStdFunction() method to create std::function proxy forwarding to\n// original object's Call. Example:\n//\n// TEST(FooTest, RunsCallbackWithBarArgument) {\n//   MockFunction<int(string)> callback;\n//   EXPECT_CALL(callback, Call(\"bar\")).WillOnce(Return(1));\n//   Foo(callback.AsStdFunction());\n// }\n//\n// The internal::SignatureOfT<F> indirection allows to use other types\n// than just function signature type. This is typically useful when\n// providing a mock for a predefined std::function type. Example:\n//\n// using FilterPredicate = std::function<bool(string)>;\n// void MyFilterAlgorithm(FilterPredicate predicate);\n//\n// TEST(FooTest, FilterPredicateAlwaysAccepts) {\n//   MockFunction<FilterPredicate> predicateMock;\n//   EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));\n//   MyFilterAlgorithm(predicateMock.AsStdFunction());\n// }\ntemplate <typename F>\nclass MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> {\n  using Base = internal::MockFunction<internal::SignatureOfT<F>>;\n\n public:\n  using Base::Base;\n};\n\n// The style guide prohibits \"using\" statements in a namespace scope\n// inside a header file.  However, the MockSpec class template is\n// meant to be defined in the ::testing namespace.  The following line\n// is just a trick for working around a bug in MSVC 8.0, which cannot\n// handle it if we define MockSpec in ::testing.\nusing internal::MockSpec;\n\n// Const(x) is a convenient function for obtaining a const reference\n// to x.  This is useful for setting expectations on an overloaded\n// const mock method, e.g.\n//\n//   class MockFoo : public FooInterface {\n//    public:\n//     MOCK_METHOD0(Bar, int());\n//     MOCK_CONST_METHOD0(Bar, int&());\n//   };\n//\n//   MockFoo foo;\n//   // Expects a call to non-const MockFoo::Bar().\n//   EXPECT_CALL(foo, Bar());\n//   // Expects a call to const MockFoo::Bar().\n//   EXPECT_CALL(Const(foo), Bar());\ntemplate <typename T>\ninline const T& Const(const T& x) {\n  return x;\n}\n\n// Constructs an Expectation object that references and co-owns exp.\ninline Expectation::Expectation(internal::ExpectationBase& exp)  // NOLINT\n    : expectation_base_(exp.GetHandle().expectation_base()) {}\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is\n// required to avoid compile errors when the name of the method used in call is\n// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro\n// tests in internal/gmock-spec-builders_test.cc for more details.\n//\n// This macro supports statements both with and without parameter matchers. If\n// the parameter list is omitted, gMock will accept any parameters, which allows\n// tests to be written that don't need to encode the number of method\n// parameter. This technique may only be used for non-overloaded methods.\n//\n//   // These are the same:\n//   ON_CALL(mock, NoArgsMethod()).WillByDefault(...);\n//   ON_CALL(mock, NoArgsMethod).WillByDefault(...);\n//\n//   // As are these:\n//   ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...);\n//   ON_CALL(mock, TwoArgsMethod).WillByDefault(...);\n//\n//   // Can also specify args if you want, of course:\n//   ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...);\n//\n//   // Overloads work as long as you specify parameters:\n//   ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...);\n//   ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...);\n//\n//   // Oops! Which overload did you want?\n//   ON_CALL(mock, OverloadedMethod).WillByDefault(...);\n//     => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous\n//\n// How this works: The mock class uses two overloads of the gmock_Method\n// expectation setter method plus an operator() overload on the MockSpec object.\n// In the matcher list form, the macro expands to:\n//\n//   // This statement:\n//   ON_CALL(mock, TwoArgsMethod(_, 45))...\n//\n//   // ...expands to:\n//   mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)...\n//   |-------------v---------------||------------v-------------|\n//       invokes first overload        swallowed by operator()\n//\n//   // ...which is essentially:\n//   mock.gmock_TwoArgsMethod(_, 45)...\n//\n// Whereas the form without a matcher list:\n//\n//   // This statement:\n//   ON_CALL(mock, TwoArgsMethod)...\n//\n//   // ...expands to:\n//   mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)...\n//   |-----------------------v--------------------------|\n//                 invokes second overload\n//\n//   // ...which is essentially:\n//   mock.gmock_TwoArgsMethod(_, _)...\n//\n// The WithoutMatchers() argument is used to disambiguate overloads and to\n// block the caller from accidentally invoking the second overload directly. The\n// second argument is an internal type derived from the method signature. The\n// failure to disambiguate two overloads of this method in the ON_CALL statement\n// is how we block callers from setting expectations on overloaded methods.\n#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call)                    \\\n  ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \\\n                             nullptr)                                   \\\n      .Setter(__FILE__, __LINE__, #mock_expr, #call)\n\n#define ON_CALL(obj, call) \\\n  GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)\n\n#define EXPECT_CALL(obj, call) \\\n  GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/gmock.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This is the main header file a user should include.\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n\n// This file implements the following syntax:\n//\n//   ON_CALL(mock_object, Method(...))\n//     .With(...) ?\n//     .WillByDefault(...);\n//\n// where With() is optional and WillByDefault() must appear exactly\n// once.\n//\n//   EXPECT_CALL(mock_object, Method(...))\n//     .With(...) ?\n//     .Times(...) ?\n//     .InSequence(...) *\n//     .WillOnce(...) *\n//     .WillRepeatedly(...) ?\n//     .RetiresOnSaturation() ? ;\n//\n// where all clauses are optional and WillOnce() can be repeated.\n\n#include \"gmock/gmock-actions.h\"  // IWYU pragma: export\n#include \"gmock/gmock-cardinalities.h\"  // IWYU pragma: export\n#include \"gmock/gmock-function-mocker.h\"  // IWYU pragma: export\n#include \"gmock/gmock-matchers.h\"  // IWYU pragma: export\n#include \"gmock/gmock-more-actions.h\"  // IWYU pragma: export\n#include \"gmock/gmock-more-matchers.h\"  // IWYU pragma: export\n#include \"gmock/gmock-nice-strict.h\"  // IWYU pragma: export\n#include \"gmock/gmock-spec-builders.h\"  // IWYU pragma: export\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gmock/internal/gmock-port.h\"\n\n// Declares Google Mock flags that we want a user to use programmatically.\nGMOCK_DECLARE_bool_(catch_leaked_mocks);\nGMOCK_DECLARE_string_(verbose);\nGMOCK_DECLARE_int32_(default_mock_behavior);\n\nnamespace testing {\n\n// Initializes Google Mock.  This must be called before running the\n// tests.  In particular, it parses the command line for the flags\n// that Google Mock recognizes.  Whenever a Google Mock flag is seen,\n// it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Mock flag variables are\n// updated.\n//\n// Since Google Test is needed for Google Mock to work, this function\n// also initializes Google Test and parses its flags, if that hasn't\n// been done.\nGTEST_API_ void InitGoogleMock(int* argc, char** argv);\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleMock();\n\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/custom/README.md",
    "content": "# Customization Points\n\nThe custom directory is an injection point for custom user configurations.\n\n## Header `gmock-port.h`\n\nThe following macros can be defined:\n\n### Flag related macros:\n\n*   `GMOCK_DECLARE_bool_(name)`\n*   `GMOCK_DECLARE_int32_(name)`\n*   `GMOCK_DECLARE_string_(name)`\n*   `GMOCK_DEFINE_bool_(name, default_val, doc)`\n*   `GMOCK_DEFINE_int32_(name, default_val, doc)`\n*   `GMOCK_DEFINE_string_(name, default_val, doc)`\n*   `GMOCK_FLAG_GET(flag_name)`\n*   `GMOCK_FLAG_SET(flag_name, value)`\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h",
    "content": "// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Injection point for custom user configurations. See README for details\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/custom/gmock-port.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file defines some utilities useful for implementing Google\n// Mock.  They are subject to change without notice, so please DO NOT\n// USE THEM IN USER CODE.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n\n#include <stdio.h>\n\n#include <ostream>  // NOLINT\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\n\ntemplate <typename>\nclass Matcher;\n\nnamespace internal {\n\n// Silence MSVC C4100 (unreferenced formal parameter) and\n// C4805('==': unsafe mix of type 'const int' and type 'const bool')\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)\n\n// Joins a vector of strings as if they are fields of a tuple; returns\n// the joined string.\nGTEST_API_ std::string JoinAsKeyValueTuple(\n    const std::vector<const char*>& names, const Strings& values);\n\n// Converts an identifier name to a space-separated list of lower-case\n// words.  Each maximum substring of the form [A-Za-z][a-z]*|\\d+ is\n// treated as one word.  For example, both \"FooBar123\" and\n// \"foo_bar_123\" are converted to \"foo bar 123\".\nGTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);\n\n// GetRawPointer(p) returns the raw pointer underlying p when p is a\n// smart pointer, or returns p itself when p is already a raw pointer.\n// The following default implementation is for the smart pointer case.\ntemplate <typename Pointer>\ninline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {\n  return p.get();\n}\n// This overload version is for std::reference_wrapper, which does not work with\n// the overload above, as it does not have an `element_type`.\ntemplate <typename Element>\ninline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {\n  return &r.get();\n}\n\n// This overloaded version is for the raw pointer case.\ntemplate <typename Element>\ninline Element* GetRawPointer(Element* p) {\n  return p;\n}\n\n// Default definitions for all compilers.\n// NOTE: If you implement support for other compilers, make sure to avoid\n// unexpected overlaps.\n// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)\n#define GMOCK_INTERNAL_WARNING_PUSH()\n#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)\n#define GMOCK_INTERNAL_WARNING_POP()\n\n#if defined(__clang__)\n#undef GMOCK_INTERNAL_WARNING_PUSH\n#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma(\"clang diagnostic push\")\n#undef GMOCK_INTERNAL_WARNING_CLANG\n#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \\\n  _Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))\n#undef GMOCK_INTERNAL_WARNING_POP\n#define GMOCK_INTERNAL_WARNING_POP() _Pragma(\"clang diagnostic pop\")\n#endif\n\n// MSVC treats wchar_t as a native type usually, but treats it as the\n// same as unsigned short when the compiler option /Zc:wchar_t- is\n// specified.  It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t\n// is a native type.\n#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)\n// wchar_t is a typedef.\n#else\n#define GMOCK_WCHAR_T_IS_NATIVE_ 1\n#endif\n\n// In what follows, we use the term \"kind\" to indicate whether a type\n// is bool, an integer type (excluding bool), a floating-point type,\n// or none of them.  This categorization is useful for determining\n// when a matcher argument type can be safely converted to another\n// type in the implementation of SafeMatcherCast.\nenum TypeKind { kBool, kInteger, kFloatingPoint, kOther };\n\n// KindOf<T>::value is the kind of type T.\ntemplate <typename T>\nstruct KindOf {\n  enum { value = kOther };  // The default kind.\n};\n\n// This macro declares that the kind of 'type' is 'kind'.\n#define GMOCK_DECLARE_KIND_(type, kind) \\\n  template <>                           \\\n  struct KindOf<type> {                 \\\n    enum { value = kind };              \\\n  }\n\nGMOCK_DECLARE_KIND_(bool, kBool);\n\n// All standard integer types.\nGMOCK_DECLARE_KIND_(char, kInteger);\nGMOCK_DECLARE_KIND_(signed char, kInteger);\nGMOCK_DECLARE_KIND_(unsigned char, kInteger);\nGMOCK_DECLARE_KIND_(short, kInteger);           // NOLINT\nGMOCK_DECLARE_KIND_(unsigned short, kInteger);  // NOLINT\nGMOCK_DECLARE_KIND_(int, kInteger);\nGMOCK_DECLARE_KIND_(unsigned int, kInteger);\nGMOCK_DECLARE_KIND_(long, kInteger);                // NOLINT\nGMOCK_DECLARE_KIND_(unsigned long, kInteger);       // NOLINT\nGMOCK_DECLARE_KIND_(long long, kInteger);           // NOLINT\nGMOCK_DECLARE_KIND_(unsigned long long, kInteger);  // NOLINT\n\n#if GMOCK_WCHAR_T_IS_NATIVE_\nGMOCK_DECLARE_KIND_(wchar_t, kInteger);\n#endif\n\n// All standard floating-point types.\nGMOCK_DECLARE_KIND_(float, kFloatingPoint);\nGMOCK_DECLARE_KIND_(double, kFloatingPoint);\nGMOCK_DECLARE_KIND_(long double, kFloatingPoint);\n\n#undef GMOCK_DECLARE_KIND_\n\n// Evaluates to the kind of 'type'.\n#define GMOCK_KIND_OF_(type)                   \\\n  static_cast< ::testing::internal::TypeKind>( \\\n      ::testing::internal::KindOf<type>::value)\n\n// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value\n// is true if and only if arithmetic type From can be losslessly converted to\n// arithmetic type To.\n//\n// It's the user's responsibility to ensure that both From and To are\n// raw (i.e. has no CV modifier, is not a pointer, and is not a\n// reference) built-in arithmetic types, kFromKind is the kind of\n// From, and kToKind is the kind of To; the value is\n// implementation-defined when the above pre-condition is violated.\ntemplate <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>\nusing LosslessArithmeticConvertibleImpl = std::integral_constant<\n    bool,\n    // clang-format off\n      // Converting from bool is always lossless\n      (kFromKind == kBool) ? true\n      // Converting between any other type kinds will be lossy if the type\n      // kinds are not the same.\n    : (kFromKind != kToKind) ? false\n    : (kFromKind == kInteger &&\n       // Converting between integers of different widths is allowed so long\n       // as the conversion does not go from signed to unsigned.\n      (((sizeof(From) < sizeof(To)) &&\n        !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||\n       // Converting between integers of the same width only requires the\n       // two types to have the same signedness.\n       ((sizeof(From) == sizeof(To)) &&\n        (std::is_signed<From>::value == std::is_signed<To>::value)))\n       ) ? true\n      // Floating point conversions are lossless if and only if `To` is at least\n      // as wide as `From`.\n    : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true\n    : false\n    // clang-format on\n    >;\n\n// LosslessArithmeticConvertible<From, To>::value is true if and only if\n// arithmetic type From can be losslessly converted to arithmetic type To.\n//\n// It's the user's responsibility to ensure that both From and To are\n// raw (i.e. has no CV modifier, is not a pointer, and is not a\n// reference) built-in arithmetic types; the value is\n// implementation-defined when the above pre-condition is violated.\ntemplate <typename From, typename To>\nusing LosslessArithmeticConvertible =\n    LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,\n                                      GMOCK_KIND_OF_(To), To>;\n\n// This interface knows how to report a Google Mock failure (either\n// non-fatal or fatal).\nclass FailureReporterInterface {\n public:\n  // The type of a failure (either non-fatal or fatal).\n  enum FailureType { kNonfatal, kFatal };\n\n  virtual ~FailureReporterInterface() = default;\n\n  // Reports a failure that occurred at the given source file location.\n  virtual void ReportFailure(FailureType type, const char* file, int line,\n                             const std::string& message) = 0;\n};\n\n// Returns the failure reporter used by Google Mock.\nGTEST_API_ FailureReporterInterface* GetFailureReporter();\n\n// Asserts that condition is true; aborts the process with the given\n// message if condition is false.  We cannot use LOG(FATAL) or CHECK()\n// as Google Mock might be used to mock the log sink itself.  We\n// inline this function to prevent it from showing up in the stack\n// trace.\ninline void Assert(bool condition, const char* file, int line,\n                   const std::string& msg) {\n  if (!condition) {\n    GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,\n                                        line, msg);\n  }\n}\ninline void Assert(bool condition, const char* file, int line) {\n  Assert(condition, file, line, \"Assertion failed.\");\n}\n\n// Verifies that condition is true; generates a non-fatal failure if\n// condition is false.\ninline void Expect(bool condition, const char* file, int line,\n                   const std::string& msg) {\n  if (!condition) {\n    GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,\n                                        file, line, msg);\n  }\n}\ninline void Expect(bool condition, const char* file, int line) {\n  Expect(condition, file, line, \"Expectation failed.\");\n}\n\n// Severity level of a log.\nenum LogSeverity { kInfo = 0, kWarning = 1 };\n\n// Valid values for the --gmock_verbose flag.\n\n// All logs (informational and warnings) are printed.\nconst char kInfoVerbosity[] = \"info\";\n// Only warnings are printed.\nconst char kWarningVerbosity[] = \"warning\";\n// No logs are printed.\nconst char kErrorVerbosity[] = \"error\";\n\n// Returns true if and only if a log with the given severity is visible\n// according to the --gmock_verbose flag.\nGTEST_API_ bool LogIsVisible(LogSeverity severity);\n\n// Prints the given message to stdout if and only if 'severity' >= the level\n// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=\n// 0, also prints the stack trace excluding the top\n// stack_frames_to_skip frames.  In opt mode, any positive\n// stack_frames_to_skip is treated as 0, since we don't know which\n// function calls will be inlined by the compiler and need to be\n// conservative.\nGTEST_API_ void Log(LogSeverity severity, const std::string& message,\n                    int stack_frames_to_skip);\n\n// A marker class that is used to resolve parameterless expectations to the\n// correct overload. This must not be instantiable, to prevent client code from\n// accidentally resolving to the overload; for example:\n//\n//    ON_CALL(mock, Method({}, nullptr))...\n//\nclass WithoutMatchers {\n private:\n  WithoutMatchers() {}\n  friend GTEST_API_ WithoutMatchers GetWithoutMatchers();\n};\n\n// Internal use only: access the singleton instance of WithoutMatchers.\nGTEST_API_ WithoutMatchers GetWithoutMatchers();\n\n// Invalid<T>() is usable as an expression of type T, but will terminate\n// the program with an assertion failure if actually run.  This is useful\n// when a value of type T is needed for compilation, but the statement\n// will not really be executed (or we don't care if the statement\n// crashes).\ntemplate <typename T>\ninline T Invalid() {\n  Assert(/*condition=*/false, /*file=*/\"\", /*line=*/-1,\n         \"Internal error: attempt to return invalid value\");\n#if defined(__GNUC__) || defined(__clang__)\n  __builtin_unreachable();\n#elif defined(_MSC_VER)\n  __assume(0);\n#else\n  return Invalid<T>();\n#endif\n}\n\n// Given a raw type (i.e. having no top-level reference or const\n// modifier) RawContainer that's either an STL-style container or a\n// native array, class StlContainerView<RawContainer> has the\n// following members:\n//\n//   - type is a type that provides an STL-style container view to\n//     (i.e. implements the STL container concept for) RawContainer;\n//   - const_reference is a type that provides a reference to a const\n//     RawContainer;\n//   - ConstReference(raw_container) returns a const reference to an STL-style\n//     container view to raw_container, which is a RawContainer.\n//   - Copy(raw_container) returns an STL-style container view of a\n//     copy of raw_container, which is a RawContainer.\n//\n// This generic version is used when RawContainer itself is already an\n// STL-style container.\ntemplate <class RawContainer>\nclass StlContainerView {\n public:\n  typedef RawContainer type;\n  typedef const type& const_reference;\n\n  static const_reference ConstReference(const RawContainer& container) {\n    static_assert(!std::is_const<RawContainer>::value,\n                  \"RawContainer type must not be const\");\n    return container;\n  }\n  static type Copy(const RawContainer& container) { return container; }\n};\n\n// This specialization is used when RawContainer is a native array type.\ntemplate <typename Element, size_t N>\nclass StlContainerView<Element[N]> {\n public:\n  typedef typename std::remove_const<Element>::type RawElement;\n  typedef internal::NativeArray<RawElement> type;\n  // NativeArray<T> can represent a native array either by value or by\n  // reference (selected by a constructor argument), so 'const type'\n  // can be used to reference a const native array.  We cannot\n  // 'typedef const type& const_reference' here, as that would mean\n  // ConstReference() has to return a reference to a local variable.\n  typedef const type const_reference;\n\n  static const_reference ConstReference(const Element (&array)[N]) {\n    static_assert(std::is_same<Element, RawElement>::value,\n                  \"Element type must not be const\");\n    return type(array, N, RelationToSourceReference());\n  }\n  static type Copy(const Element (&array)[N]) {\n    return type(array, N, RelationToSourceCopy());\n  }\n};\n\n// This specialization is used when RawContainer is a native array\n// represented as a (pointer, size) tuple.\ntemplate <typename ElementPointer, typename Size>\nclass StlContainerView< ::std::tuple<ElementPointer, Size> > {\n public:\n  typedef typename std::remove_const<\n      typename std::pointer_traits<ElementPointer>::element_type>::type\n      RawElement;\n  typedef internal::NativeArray<RawElement> type;\n  typedef const type const_reference;\n\n  static const_reference ConstReference(\n      const ::std::tuple<ElementPointer, Size>& array) {\n    return type(std::get<0>(array), std::get<1>(array),\n                RelationToSourceReference());\n  }\n  static type Copy(const ::std::tuple<ElementPointer, Size>& array) {\n    return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());\n  }\n};\n\n// The following specialization prevents the user from instantiating\n// StlContainer with a reference type.\ntemplate <typename T>\nclass StlContainerView<T&>;\n\n// A type transform to remove constness from the first part of a pair.\n// Pairs like that are used as the value_type of associative containers,\n// and this transform produces a similar but assignable pair.\ntemplate <typename T>\nstruct RemoveConstFromKey {\n  typedef T type;\n};\n\n// Partially specialized to remove constness from std::pair<const K, V>.\ntemplate <typename K, typename V>\nstruct RemoveConstFromKey<std::pair<const K, V> > {\n  typedef std::pair<K, V> type;\n};\n\n// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to\n// reduce code size.\nGTEST_API_ void IllegalDoDefault(const char* file, int line);\n\ntemplate <typename F, typename Tuple, size_t... Idx>\nauto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)\n    -> decltype(std::forward<F>(f)(\n        std::get<Idx>(std::forward<Tuple>(args))...)) {\n  return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);\n}\n\n// Apply the function to a tuple of arguments.\ntemplate <typename F, typename Tuple>\nauto Apply(F&& f, Tuple&& args)\n    -> decltype(ApplyImpl(\n        std::forward<F>(f), std::forward<Tuple>(args),\n        std::make_index_sequence<std::tuple_size<\n            typename std::remove_reference<Tuple>::type>::value>())) {\n  return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),\n                   std::make_index_sequence<std::tuple_size<\n                       typename std::remove_reference<Tuple>::type>::value>());\n}\n\n// Template struct Function<F>, where F must be a function type, contains\n// the following typedefs:\n//\n//   Result:               the function's return type.\n//   Arg<N>:               the type of the N-th argument, where N starts with 0.\n//   ArgumentTuple:        the tuple type consisting of all parameters of F.\n//   ArgumentMatcherTuple: the tuple type consisting of Matchers for all\n//                         parameters of F.\n//   MakeResultVoid:       the function type obtained by substituting void\n//                         for the return type of F.\n//   MakeResultIgnoredValue:\n//                         the function type obtained by substituting Something\n//                         for the return type of F.\ntemplate <typename T>\nstruct Function;\n\ntemplate <typename R, typename... Args>\nstruct Function<R(Args...)> {\n  using Result = R;\n  static constexpr size_t ArgumentCount = sizeof...(Args);\n  template <size_t I>\n  using Arg = ElemFromList<I, Args...>;\n  using ArgumentTuple = std::tuple<Args...>;\n  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;\n  using MakeResultVoid = void(Args...);\n  using MakeResultIgnoredValue = IgnoredValue(Args...);\n};\n\n#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL\ntemplate <typename R, typename... Args>\nconstexpr size_t Function<R(Args...)>::ArgumentCount;\n#endif\n\n// Workaround for MSVC error C2039: 'type': is not a member of 'std'\n// when std::tuple_element is used.\n// See: https://github.com/google/googletest/issues/3931\n// Can be replaced with std::tuple_element_t in C++14.\ntemplate <size_t I, typename T>\nusing TupleElement = typename std::tuple_element<I, T>::type;\n\nbool Base64Unescape(const std::string& encoded, std::string* decoded);\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100 4805\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/gmock-port.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Low-level types and utilities for porting Google Mock to various\n// platforms.  All macros ending with _ and symbols defined in an\n// internal namespace are subject to change without notice.  Code\n// outside Google Mock MUST NOT USE THEM DIRECTLY.  Macros that don't\n// end with _ are part of Google Mock's public API and can be used by\n// code outside Google Mock.\n\n// IWYU pragma: private, include \"gmock/gmock.h\"\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n\n#include <assert.h>\n#include <stdlib.h>\n#include <cstdint>\n#include <iostream>\n\n// Most of the utilities needed for porting Google Mock are also\n// required for Google Test and are defined in gtest-port.h.\n//\n// Note to maintainers: to reduce code duplication, prefer adding\n// portability utilities to Google Test's gtest-port.h instead of\n// here, as Google Mock depends on Google Test.  Only add a utility\n// here if it's truly specific to Google Mock.\n\n#include \"gmock/internal/custom/gmock-port.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#include \"absl/flags/declare.h\"\n#include \"absl/flags/flag.h\"\n#endif\n\n// For MS Visual C++, check the compiler version. At least VS 2015 is\n// required to compile Google Mock.\n#if defined(_MSC_VER) && _MSC_VER < 1900\n#error \"At least Visual C++ 2015 (14.0) is required to compile Google Mock.\"\n#endif\n\n// Macro for referencing flags.  This is public as we want the user to\n// use this syntax to reference Google Mock flags.\n#define GMOCK_FLAG_NAME_(name) gmock_##name\n#define GMOCK_FLAG(name) FLAGS_gmock_##name\n\n// Pick a command line flags implementation.\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n// Macros for defining flags.\n#define GMOCK_DEFINE_bool_(name, default_val, doc) \\\n  ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc)\n#define GMOCK_DEFINE_int32_(name, default_val, doc) \\\n  ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc)\n#define GMOCK_DEFINE_string_(name, default_val, doc) \\\n  ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc)\n\n// Macros for declaring flags.\n#define GMOCK_DECLARE_bool_(name) \\\n  ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))\n#define GMOCK_DECLARE_int32_(name) \\\n  ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))\n#define GMOCK_DECLARE_string_(name) \\\n  ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))\n\n#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))\n#define GMOCK_FLAG_SET(name, value) \\\n  (void)(::absl::SetFlag(&GMOCK_FLAG(name), value))\n\n#else  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n// Macros for defining flags.\n#define GMOCK_DEFINE_bool_(name, default_val, doc)  \\\n  namespace testing {                               \\\n  GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DEFINE_int32_(name, default_val, doc)    \\\n  namespace testing {                                  \\\n  GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \\\n  }                                                    \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DEFINE_string_(name, default_val, doc)         \\\n  namespace testing {                                        \\\n  GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \\\n  }                                                          \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n// Macros for declaring flags.\n#define GMOCK_DECLARE_bool_(name)          \\\n  namespace testing {                      \\\n  GTEST_API_ extern bool GMOCK_FLAG(name); \\\n  }                                        \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DECLARE_int32_(name)            \\\n  namespace testing {                         \\\n  GTEST_API_ extern int32_t GMOCK_FLAG(name); \\\n  }                                           \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GMOCK_DECLARE_string_(name)                 \\\n  namespace testing {                               \\\n  GTEST_API_ extern ::std::string GMOCK_FLAG(name); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)\n#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)\n\n#endif  // defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/include/gmock/internal/gmock-pp.h",
    "content": "#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n\n// Expands and concatenates the arguments. Constructed macros reevaluate.\n#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)\n\n// Expands and stringifies the only argument.\n#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)\n\n// Returns empty. Given a variadic number of arguments.\n#define GMOCK_PP_EMPTY(...)\n\n// Returns a comma. Given a variadic number of arguments.\n#define GMOCK_PP_COMMA(...) ,\n\n// Returns the only argument.\n#define GMOCK_PP_IDENTITY(_1) _1\n\n// Evaluates to the number of arguments after expansion.\n//\n//   #define PAIR x, y\n//\n//   GMOCK_PP_NARG() => 1\n//   GMOCK_PP_NARG(x) => 1\n//   GMOCK_PP_NARG(x, y) => 2\n//   GMOCK_PP_NARG(PAIR) => 2\n//\n// Requires: the number of arguments after expansion is at most 15.\n#define GMOCK_PP_NARG(...) \\\n  GMOCK_PP_INTERNAL_16TH(  \\\n      (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))\n\n// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise\n// returns 0. Requires no more than 15 unprotected commas.\n#define GMOCK_PP_HAS_COMMA(...) \\\n  GMOCK_PP_INTERNAL_16TH(       \\\n      (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))\n\n// Returns the first argument.\n#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))\n\n// Returns the tail. A variadic list of all arguments minus the first. Requires\n// at least one argument.\n#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))\n\n// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)\n#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \\\n  GMOCK_PP_IDENTITY(                        \\\n      GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))\n\n// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise\n// evaluates to `0`.\n//\n// Requires: * the number of arguments after expansion is at most 15.\n//           * If the argument is a macro, it must be able to be called with one\n//             argument.\n//\n// Implementation details:\n//\n// There is one case when it generates a compile error: if the argument is macro\n// that cannot be called with one argument.\n//\n//   #define M(a, b)  // it doesn't matter what it expands to\n//\n//   // Expected: expands to `0`.\n//   // Actual: compile error.\n//   GMOCK_PP_IS_EMPTY(M)\n//\n// There are 4 cases tested:\n//\n// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.\n// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.\n// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.\n//   Expected 0\n// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in\n//   parenthesis, or is a macro that ()-evaluates to comma. Expected 1.\n//\n// We trigger detection on '0001', i.e. on empty.\n#define GMOCK_PP_IS_EMPTY(...)                                               \\\n  GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__),                \\\n                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \\\n                             GMOCK_PP_HAS_COMMA(__VA_ARGS__()),              \\\n                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))\n\n// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.\n#define GMOCK_PP_IF(_Cond, _Then, _Else) \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)\n\n// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.\n//\n// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c\n// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f\n//\n#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \\\n  GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))\n\n// Evaluates to the number of arguments after expansion. Identifies 'empty' as\n// 0.\n//\n//   #define PAIR x, y\n//\n//   GMOCK_PP_NARG0() => 0\n//   GMOCK_PP_NARG0(x) => 1\n//   GMOCK_PP_NARG0(x, y) => 2\n//   GMOCK_PP_NARG0(PAIR) => 2\n//\n// Requires: * the number of arguments after expansion is at most 15.\n//           * If the argument is a macro, it must be able to be called with one\n//             argument.\n#define GMOCK_PP_NARG0(...) \\\n  GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))\n\n// Expands to 1 if the first argument starts with something in parentheses,\n// otherwise to 0.\n#define GMOCK_PP_IS_BEGIN_PARENS(...)                              \\\n  GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \\\n                             GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))\n\n// Expands to 1 is there is only one argument and it is enclosed in parentheses.\n#define GMOCK_PP_IS_ENCLOSED_PARENS(...)             \\\n  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \\\n              GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)\n\n// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.\n#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__\n\n// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,\n// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.\n// Requires: * |_Macro| can be called with 3 arguments.\n//           * |_Tuple| expansion has no more than 15 elements.\n#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple)                        \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \\\n  (0, _Macro, _Data, _Tuple)\n\n// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )\n// Empty if _K = 0.\n// Requires: * |_Macro| can be called with 3 arguments.\n//           * |_K| literal between 0 and 15\n#define GMOCK_PP_REPEAT(_Macro, _Data, _N)           \\\n  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \\\n  (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)\n\n// Increments the argument, requires the argument to be between 0 and 15.\n#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)\n\n// Returns comma if _i != 0. Requires _i to be between 0 and 15.\n#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)\n\n// Internal details follow. Do not use any of these symbols outside of this\n// file or we will break your code.\n#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )\n#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2\n#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__\n#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5\n#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4)                             \\\n  GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \\\n                                             _1, _2, _3, _4))\n#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,\n#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then\n#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else\n\n// Because of MSVC treating a token with a comma in it as a single token when\n// passed to another macro, we need to force it to evaluate it as multiple\n// tokens. We do that by using a \"IDENTITY(MACRO PARENTHESIZED_ARGS)\" macro. We\n// define one per possible macro that relies on this behavior. Note \"_Args\" must\n// be parenthesized.\n#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \\\n                                        _10, _11, _12, _13, _14, _15, _16,  \\\n                                        ...)                                \\\n  _16\n#define GMOCK_PP_INTERNAL_16TH(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)\n#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1\n#define GMOCK_PP_INTERNAL_HEAD(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)\n#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__\n#define GMOCK_PP_INTERNAL_TAIL(_Args) \\\n  GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)\n\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,\n#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \\\n  0,\n#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__\n#define GMOCK_PP_INTERNAL_INC_0 1\n#define GMOCK_PP_INTERNAL_INC_1 2\n#define GMOCK_PP_INTERNAL_INC_2 3\n#define GMOCK_PP_INTERNAL_INC_3 4\n#define GMOCK_PP_INTERNAL_INC_4 5\n#define GMOCK_PP_INTERNAL_INC_5 6\n#define GMOCK_PP_INTERNAL_INC_6 7\n#define GMOCK_PP_INTERNAL_INC_7 8\n#define GMOCK_PP_INTERNAL_INC_8 9\n#define GMOCK_PP_INTERNAL_INC_9 10\n#define GMOCK_PP_INTERNAL_INC_10 11\n#define GMOCK_PP_INTERNAL_INC_11 12\n#define GMOCK_PP_INTERNAL_INC_12 13\n#define GMOCK_PP_INTERNAL_INC_13 14\n#define GMOCK_PP_INTERNAL_INC_14 15\n#define GMOCK_PP_INTERNAL_INC_15 16\n#define GMOCK_PP_INTERNAL_COMMA_IF_0\n#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,\n#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,\n#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \\\n  _Macro(_i, _Data, _element)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple)    \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data,    \\\n                                    (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple)   \\\n  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \\\n  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data,   \\\n                                     (GMOCK_PP_TAIL _Tuple))\n\n#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock-all.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// Google C++ Mocking Framework (Google Mock)\n//\n// This file #includes all Google Mock implementation .cc files.  The\n// purpose is to allow a user to build Google Mock by compiling this\n// file alone.\n\n// This line ensures that gmock.h can be compiled on its own, even\n// when it's fused.\n#include \"gmock/gmock.h\"\n\n// The following lines pull in the real gmock *.cc files.\n#include \"src/gmock-cardinalities.cc\"\n#include \"src/gmock-internal-utils.cc\"\n#include \"src/gmock-matchers.cc\"\n#include \"src/gmock-spec-builders.cc\"\n#include \"src/gmock.cc\"\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock-cardinalities.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements cardinalities.\n\n#include \"gmock/gmock-cardinalities.h\"\n\n#include <limits.h>\n\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\n\nnamespace {\n\n// Implements the Between(m, n) cardinality.\nclass BetweenCardinalityImpl : public CardinalityInterface {\n public:\n  BetweenCardinalityImpl(int min, int max)\n      : min_(min >= 0 ? min : 0), max_(max >= min_ ? max : min_) {\n    std::stringstream ss;\n    if (min < 0) {\n      ss << \"The invocation lower bound must be >= 0, \"\n         << \"but is actually \" << min << \".\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    } else if (max < 0) {\n      ss << \"The invocation upper bound must be >= 0, \"\n         << \"but is actually \" << max << \".\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    } else if (min > max) {\n      ss << \"The invocation upper bound (\" << max\n         << \") must be >= the invocation lower bound (\" << min << \").\";\n      internal::Expect(false, __FILE__, __LINE__, ss.str());\n    }\n  }\n\n  // Conservative estimate on the lower/upper bound of the number of\n  // calls allowed.\n  int ConservativeLowerBound() const override { return min_; }\n  int ConservativeUpperBound() const override { return max_; }\n\n  bool IsSatisfiedByCallCount(int call_count) const override {\n    return min_ <= call_count && call_count <= max_;\n  }\n\n  bool IsSaturatedByCallCount(int call_count) const override {\n    return call_count >= max_;\n  }\n\n  void DescribeTo(::std::ostream* os) const override;\n\n private:\n  const int min_;\n  const int max_;\n\n  BetweenCardinalityImpl(const BetweenCardinalityImpl&) = delete;\n  BetweenCardinalityImpl& operator=(const BetweenCardinalityImpl&) = delete;\n};\n\n// Formats \"n times\" in a human-friendly way.\ninline std::string FormatTimes(int n) {\n  if (n == 1) {\n    return \"once\";\n  } else if (n == 2) {\n    return \"twice\";\n  } else {\n    std::stringstream ss;\n    ss << n << \" times\";\n    return ss.str();\n  }\n}\n\n// Describes the Between(m, n) cardinality in human-friendly text.\nvoid BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {\n  if (min_ == 0) {\n    if (max_ == 0) {\n      *os << \"never called\";\n    } else if (max_ == INT_MAX) {\n      *os << \"called any number of times\";\n    } else {\n      *os << \"called at most \" << FormatTimes(max_);\n    }\n  } else if (min_ == max_) {\n    *os << \"called \" << FormatTimes(min_);\n  } else if (max_ == INT_MAX) {\n    *os << \"called at least \" << FormatTimes(min_);\n  } else {\n    // 0 < min_ < max_ < INT_MAX\n    *os << \"called between \" << min_ << \" and \" << max_ << \" times\";\n  }\n}\n\n}  // Unnamed namespace\n\n// Describes the given call count to an ostream.\nvoid Cardinality::DescribeActualCallCountTo(int actual_call_count,\n                                            ::std::ostream* os) {\n  if (actual_call_count > 0) {\n    *os << \"called \" << FormatTimes(actual_call_count);\n  } else {\n    *os << \"never called\";\n  }\n}\n\n// Creates a cardinality that allows at least n calls.\nGTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }\n\n// Creates a cardinality that allows at most n calls.\nGTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }\n\n// Creates a cardinality that allows any number of calls.\nGTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }\n\n// Creates a cardinality that allows between min and max calls.\nGTEST_API_ Cardinality Between(int min, int max) {\n  return Cardinality(new BetweenCardinalityImpl(min, max));\n}\n\n// Creates a cardinality that allows exactly n calls.\nGTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock-internal-utils.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file defines some utilities useful for implementing Google\n// Mock.  They are subject to change without notice, so please DO NOT\n// USE THEM IN USER CODE.\n\n#include \"gmock/internal/gmock-internal-utils.h\"\n\n#include <ctype.h>\n\n#include <array>\n#include <cctype>\n#include <cstdint>\n#include <cstring>\n#include <iostream>\n#include <ostream>  // NOLINT\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"gmock/gmock.h\"\n#include \"gmock/internal/gmock-port.h\"\n#include \"gtest/gtest.h\"\n\nnamespace testing {\nnamespace internal {\n\n// Joins a vector of strings as if they are fields of a tuple; returns\n// the joined string.\nGTEST_API_ std::string JoinAsKeyValueTuple(\n    const std::vector<const char*>& names, const Strings& values) {\n  GTEST_CHECK_(names.size() == values.size());\n  if (values.empty()) {\n    return \"\";\n  }\n  const auto build_one = [&](const size_t i) {\n    return std::string(names[i]) + \": \" + values[i];\n  };\n  std::string result = \"(\" + build_one(0);\n  for (size_t i = 1; i < values.size(); i++) {\n    result += \", \";\n    result += build_one(i);\n  }\n  result += \")\";\n  return result;\n}\n\n// Converts an identifier name to a space-separated list of lower-case\n// words.  Each maximum substring of the form [A-Za-z][a-z]*|\\d+ is\n// treated as one word.  For example, both \"FooBar123\" and\n// \"foo_bar_123\" are converted to \"foo bar 123\".\nGTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {\n  std::string result;\n  char prev_char = '\\0';\n  for (const char* p = id_name; *p != '\\0'; prev_char = *(p++)) {\n    // We don't care about the current locale as the input is\n    // guaranteed to be a valid C++ identifier name.\n    const bool starts_new_word = IsUpper(*p) ||\n                                 (!IsAlpha(prev_char) && IsLower(*p)) ||\n                                 (!IsDigit(prev_char) && IsDigit(*p));\n\n    if (IsAlNum(*p)) {\n      if (starts_new_word && !result.empty()) result += ' ';\n      result += ToLower(*p);\n    }\n  }\n  return result;\n}\n\n// This class reports Google Mock failures as Google Test failures.  A\n// user can define another class in a similar fashion if they intend to\n// use Google Mock with a testing framework other than Google Test.\nclass GoogleTestFailureReporter : public FailureReporterInterface {\n public:\n  void ReportFailure(FailureType type, const char* file, int line,\n                     const std::string& message) override {\n    AssertHelper(type == kFatal ? TestPartResult::kFatalFailure\n                                : TestPartResult::kNonFatalFailure,\n                 file, line, message.c_str()) = Message();\n    if (type == kFatal) {\n      posix::Abort();\n    }\n  }\n};\n\n// Returns the global failure reporter.  Will create a\n// GoogleTestFailureReporter and return it the first time called.\nGTEST_API_ FailureReporterInterface* GetFailureReporter() {\n  // Points to the global failure reporter used by Google Mock.  gcc\n  // guarantees that the following use of failure_reporter is\n  // thread-safe.  We may need to add additional synchronization to\n  // protect failure_reporter if we port Google Mock to other\n  // compilers.\n  static FailureReporterInterface* const failure_reporter =\n      new GoogleTestFailureReporter();\n  return failure_reporter;\n}\n\n// Protects global resources (stdout in particular) used by Log().\nstatic GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);\n\n// Returns true if and only if a log with the given severity is visible\n// according to the --gmock_verbose flag.\nGTEST_API_ bool LogIsVisible(LogSeverity severity) {\n  if (GMOCK_FLAG_GET(verbose) == kInfoVerbosity) {\n    // Always show the log if --gmock_verbose=info.\n    return true;\n  } else if (GMOCK_FLAG_GET(verbose) == kErrorVerbosity) {\n    // Always hide it if --gmock_verbose=error.\n    return false;\n  } else {\n    // If --gmock_verbose is neither \"info\" nor \"error\", we treat it\n    // as \"warning\" (its default value).\n    return severity == kWarning;\n  }\n}\n\n// Prints the given message to stdout if and only if 'severity' >= the level\n// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=\n// 0, also prints the stack trace excluding the top\n// stack_frames_to_skip frames.  In opt mode, any positive\n// stack_frames_to_skip is treated as 0, since we don't know which\n// function calls will be inlined by the compiler and need to be\n// conservative.\nGTEST_API_ void Log(LogSeverity severity, const std::string& message,\n                    int stack_frames_to_skip) {\n  if (!LogIsVisible(severity)) return;\n\n  // Ensures that logs from different threads don't interleave.\n  MutexLock l(&g_log_mutex);\n\n  if (severity == kWarning) {\n    // Prints a GMOCK WARNING marker to make the warnings easily searchable.\n    std::cout << \"\\nGMOCK WARNING:\";\n  }\n  // Pre-pends a new-line to message if it doesn't start with one.\n  if (message.empty() || message[0] != '\\n') {\n    std::cout << \"\\n\";\n  }\n  std::cout << message;\n  if (stack_frames_to_skip >= 0) {\n#ifdef NDEBUG\n    // In opt mode, we have to be conservative and skip no stack frame.\n    const int actual_to_skip = 0;\n#else\n    // In dbg mode, we can do what the caller tell us to do (plus one\n    // for skipping this function's stack frame).\n    const int actual_to_skip = stack_frames_to_skip + 1;\n#endif  // NDEBUG\n\n    // Appends a new-line to message if it doesn't end with one.\n    if (!message.empty() && *message.rbegin() != '\\n') {\n      std::cout << \"\\n\";\n    }\n    std::cout << \"Stack trace:\\n\"\n              << ::testing::internal::GetCurrentOsStackTraceExceptTop(\n                     actual_to_skip);\n  }\n  std::cout << ::std::flush;\n}\n\nGTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }\n\nGTEST_API_ void IllegalDoDefault(const char* file, int line) {\n  internal::Assert(\n      false, file, line,\n      \"You are using DoDefault() inside a composite action like \"\n      \"DoAll() or WithArgs().  This is not supported for technical \"\n      \"reasons.  Please instead spell out the default action, or \"\n      \"assign the default action to an Action variable and use \"\n      \"the variable in various places.\");\n}\n\nconstexpr char UndoWebSafeEncoding(char c) {\n  return c == '-' ? '+' : c == '_' ? '/' : c;\n}\n\nconstexpr char UnBase64Impl(char c, const char* const base64, char carry) {\n  return *base64 == 0 ? static_cast<char>(65)\n         : *base64 == c\n             ? carry\n             : UnBase64Impl(c, base64 + 1, static_cast<char>(carry + 1));\n}\n\ntemplate <size_t... I>\nconstexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>,\n                                             const char* const base64) {\n  return {\n      {UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}};\n}\n\nconstexpr std::array<char, 256> UnBase64(const char* const base64) {\n  return UnBase64Impl(std::make_index_sequence<256>{}, base64);\n}\n\nstatic constexpr char kBase64[] =\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nstatic constexpr std::array<char, 256> kUnBase64 = UnBase64(kBase64);\n\nbool Base64Unescape(const std::string& encoded, std::string* decoded) {\n  decoded->clear();\n  size_t encoded_len = encoded.size();\n  decoded->reserve(3 * (encoded_len / 4) + (encoded_len % 4));\n  int bit_pos = 0;\n  char dst = 0;\n  for (int src : encoded) {\n    if (std::isspace(src) || src == '=') {\n      continue;\n    }\n    char src_bin = kUnBase64[static_cast<size_t>(src)];\n    if (src_bin >= 64) {\n      decoded->clear();\n      return false;\n    }\n    if (bit_pos == 0) {\n      dst |= static_cast<char>(src_bin << 2);\n      bit_pos = 6;\n    } else {\n      dst |= static_cast<char>(src_bin >> (bit_pos - 2));\n      decoded->push_back(dst);\n      dst = static_cast<char>(src_bin << (10 - bit_pos));\n      bit_pos = (bit_pos + 6) % 8;\n    }\n  }\n  return true;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock-matchers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements Matcher<const string&>, Matcher<string>, and\n// utilities for defining matchers.\n\n#include \"gmock/gmock-matchers.h\"\n\n#include <string.h>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n\nnamespace testing {\nnamespace internal {\n\n// Returns the description for a matcher defined using the MATCHER*()\n// macro where the user-supplied description string is \"\", if\n// 'negation' is false; otherwise returns the description of the\n// negation of the matcher.  'param_values' contains a list of strings\n// that are the print-out of the matcher's parameters.\nGTEST_API_ std::string FormatMatcherDescription(\n    bool negation, const char* matcher_name,\n    const std::vector<const char*>& param_names, const Strings& param_values) {\n  std::string result = ConvertIdentifierNameToWords(matcher_name);\n  if (!param_values.empty()) {\n    result += \" \" + JoinAsKeyValueTuple(param_names, param_values);\n  }\n  return negation ? \"not (\" + result + \")\" : result;\n}\n\n// FindMaxBipartiteMatching and its helper class.\n//\n// Uses the well-known Ford-Fulkerson max flow method to find a maximum\n// bipartite matching. Flow is considered to be from left to right.\n// There is an implicit source node that is connected to all of the left\n// nodes, and an implicit sink node that is connected to all of the\n// right nodes. All edges have unit capacity.\n//\n// Neither the flow graph nor the residual flow graph are represented\n// explicitly. Instead, they are implied by the information in 'graph' and\n// a vector<int> called 'left_' whose elements are initialized to the\n// value kUnused. This represents the initial state of the algorithm,\n// where the flow graph is empty, and the residual flow graph has the\n// following edges:\n//   - An edge from source to each left_ node\n//   - An edge from each right_ node to sink\n//   - An edge from each left_ node to each right_ node, if the\n//     corresponding edge exists in 'graph'.\n//\n// When the TryAugment() method adds a flow, it sets left_[l] = r for some\n// nodes l and r. This induces the following changes:\n//   - The edges (source, l), (l, r), and (r, sink) are added to the\n//     flow graph.\n//   - The same three edges are removed from the residual flow graph.\n//   - The reverse edges (l, source), (r, l), and (sink, r) are added\n//     to the residual flow graph, which is a directional graph\n//     representing unused flow capacity.\n//\n// When the method augments a flow (moving left_[l] from some r1 to some\n// other r2), this can be thought of as \"undoing\" the above steps with\n// respect to r1 and \"redoing\" them with respect to r2.\n//\n// It bears repeating that the flow graph and residual flow graph are\n// never represented explicitly, but can be derived by looking at the\n// information in 'graph' and in left_.\n//\n// As an optimization, there is a second vector<int> called right_ which\n// does not provide any new information. Instead, it enables more\n// efficient queries about edges entering or leaving the right-side nodes\n// of the flow or residual flow graphs. The following invariants are\n// maintained:\n//\n// left[l] == kUnused or right[left[l]] == l\n// right[r] == kUnused or left[right[r]] == r\n//\n// . [ source ]                                        .\n// .   |||                                             .\n// .   |||                                             .\n// .   ||\\--> left[0]=1  ---\\    right[0]=-1 ----\\     .\n// .   ||                   |                    |     .\n// .   |\\---> left[1]=-1    \\--> right[1]=0  ---\\|     .\n// .   |                                        ||     .\n// .   \\----> left[2]=2  ------> right[2]=2  --\\||     .\n// .                                           |||     .\n// .         elements           matchers       vvv     .\n// .                                         [ sink ]  .\n//\n// See Also:\n//   [1] Cormen, et al (2001). \"Section 26.2: The Ford-Fulkerson method\".\n//       \"Introduction to Algorithms (Second ed.)\", pp. 651-664.\n//   [2] \"Ford-Fulkerson algorithm\", Wikipedia,\n//       'https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'\nclass MaxBipartiteMatchState {\n public:\n  explicit MaxBipartiteMatchState(const MatchMatrix& graph)\n      : graph_(&graph),\n        left_(graph_->LhsSize(), kUnused),\n        right_(graph_->RhsSize(), kUnused) {}\n\n  // Returns the edges of a maximal match, each in the form {left, right}.\n  ElementMatcherPairs Compute() {\n    // 'seen' is used for path finding { 0: unseen, 1: seen }.\n    ::std::vector<char> seen;\n    // Searches the residual flow graph for a path from each left node to\n    // the sink in the residual flow graph, and if one is found, add flow\n    // to the graph. It's okay to search through the left nodes once. The\n    // edge from the implicit source node to each previously-visited left\n    // node will have flow if that left node has any path to the sink\n    // whatsoever. Subsequent augmentations can only add flow to the\n    // network, and cannot take away that previous flow unit from the source.\n    // Since the source-to-left edge can only carry one flow unit (or,\n    // each element can be matched to only one matcher), there is no need\n    // to visit the left nodes more than once looking for augmented paths.\n    // The flow is known to be possible or impossible by looking at the\n    // node once.\n    for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {\n      // Reset the path-marking vector and try to find a path from\n      // source to sink starting at the left_[ilhs] node.\n      GTEST_CHECK_(left_[ilhs] == kUnused)\n          << \"ilhs: \" << ilhs << \", left_[ilhs]: \" << left_[ilhs];\n      // 'seen' initialized to 'graph_->RhsSize()' copies of 0.\n      seen.assign(graph_->RhsSize(), 0);\n      TryAugment(ilhs, &seen);\n    }\n    ElementMatcherPairs result;\n    for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {\n      size_t irhs = left_[ilhs];\n      if (irhs == kUnused) continue;\n      result.push_back(ElementMatcherPair(ilhs, irhs));\n    }\n    return result;\n  }\n\n private:\n  static const size_t kUnused = static_cast<size_t>(-1);\n\n  // Perform a depth-first search from left node ilhs to the sink.  If a\n  // path is found, flow is added to the network by linking the left and\n  // right vector elements corresponding each segment of the path.\n  // Returns true if a path to sink was found, which means that a unit of\n  // flow was added to the network. The 'seen' vector elements correspond\n  // to right nodes and are marked to eliminate cycles from the search.\n  //\n  // Left nodes will only be explored at most once because they\n  // are accessible from at most one right node in the residual flow\n  // graph.\n  //\n  // Note that left_[ilhs] is the only element of left_ that TryAugment will\n  // potentially transition from kUnused to another value. Any other\n  // left_ element holding kUnused before TryAugment will be holding it\n  // when TryAugment returns.\n  //\n  bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {\n    for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {\n      if ((*seen)[irhs]) continue;\n      if (!graph_->HasEdge(ilhs, irhs)) continue;\n      // There's an available edge from ilhs to irhs.\n      (*seen)[irhs] = 1;\n      // Next a search is performed to determine whether\n      // this edge is a dead end or leads to the sink.\n      //\n      // right_[irhs] == kUnused means that there is residual flow from\n      // right node irhs to the sink, so we can use that to finish this\n      // flow path and return success.\n      //\n      // Otherwise there is residual flow to some ilhs. We push flow\n      // along that path and call ourselves recursively to see if this\n      // ultimately leads to sink.\n      if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {\n        // Add flow from left_[ilhs] to right_[irhs].\n        left_[ilhs] = irhs;\n        right_[irhs] = ilhs;\n        return true;\n      }\n    }\n    return false;\n  }\n\n  const MatchMatrix* graph_;  // not owned\n  // Each element of the left_ vector represents a left hand side node\n  // (i.e. an element) and each element of right_ is a right hand side\n  // node (i.e. a matcher). The values in the left_ vector indicate\n  // outflow from that node to a node on the right_ side. The values\n  // in the right_ indicate inflow, and specify which left_ node is\n  // feeding that right_ node, if any. For example, left_[3] == 1 means\n  // there's a flow from element #3 to matcher #1. Such a flow would also\n  // be redundantly represented in the right_ vector as right_[1] == 3.\n  // Elements of left_ and right_ are either kUnused or mutually\n  // referent. Mutually referent means that left_[right_[i]] = i and\n  // right_[left_[i]] = i.\n  ::std::vector<size_t> left_;\n  ::std::vector<size_t> right_;\n};\n\nconst size_t MaxBipartiteMatchState::kUnused;\n\nGTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {\n  return MaxBipartiteMatchState(g).Compute();\n}\n\nstatic void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,\n                                     ::std::ostream* stream) {\n  typedef ElementMatcherPairs::const_iterator Iter;\n  ::std::ostream& os = *stream;\n  os << \"{\";\n  const char* sep = \"\";\n  for (Iter it = pairs.begin(); it != pairs.end(); ++it) {\n    os << sep << \"\\n  (\" << \"element #\" << it->first << \", \" << \"matcher #\"\n       << it->second << \")\";\n    sep = \",\";\n  }\n  os << \"\\n}\";\n}\n\nbool MatchMatrix::NextGraph() {\n  for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {\n    for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {\n      char& b = matched_[SpaceIndex(ilhs, irhs)];\n      if (!b) {\n        b = 1;\n        return true;\n      }\n      b = 0;\n    }\n  }\n  return false;\n}\n\nvoid MatchMatrix::Randomize() {\n  for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {\n    for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {\n      char& b = matched_[SpaceIndex(ilhs, irhs)];\n      b = static_cast<char>(rand() & 1);  // NOLINT\n    }\n  }\n}\n\nstd::string MatchMatrix::DebugString() const {\n  ::std::stringstream ss;\n  const char* sep = \"\";\n  for (size_t i = 0; i < LhsSize(); ++i) {\n    ss << sep;\n    for (size_t j = 0; j < RhsSize(); ++j) {\n      ss << HasEdge(i, j);\n    }\n    sep = \";\";\n  }\n  return ss.str();\n}\n\nvoid UnorderedElementsAreMatcherImplBase::DescribeToImpl(\n    ::std::ostream* os) const {\n  switch (match_flags()) {\n    case UnorderedMatcherRequire::ExactMatch:\n      if (matcher_describers_.empty()) {\n        *os << \"is empty\";\n        return;\n      }\n      if (matcher_describers_.size() == 1) {\n        *os << \"has \" << Elements(1) << \" and that element \";\n        matcher_describers_[0]->DescribeTo(os);\n        return;\n      }\n      *os << \"has \" << Elements(matcher_describers_.size())\n          << \" and there exists some permutation of elements such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Superset:\n      *os << \"a surjection from elements to requirements exists such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Subset:\n      *os << \"an injection from elements to requirements exists such that:\\n\";\n      break;\n  }\n\n  const char* sep = \"\";\n  for (size_t i = 0; i != matcher_describers_.size(); ++i) {\n    *os << sep;\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      *os << \" - element #\" << i << \" \";\n    } else {\n      *os << \" - an element \";\n    }\n    matcher_describers_[i]->DescribeTo(os);\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      sep = \", and\\n\";\n    } else {\n      sep = \"\\n\";\n    }\n  }\n}\n\nvoid UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(\n    ::std::ostream* os) const {\n  switch (match_flags()) {\n    case UnorderedMatcherRequire::ExactMatch:\n      if (matcher_describers_.empty()) {\n        *os << \"isn't empty\";\n        return;\n      }\n      if (matcher_describers_.size() == 1) {\n        *os << \"doesn't have \" << Elements(1) << \", or has \" << Elements(1)\n            << \" that \";\n        matcher_describers_[0]->DescribeNegationTo(os);\n        return;\n      }\n      *os << \"doesn't have \" << Elements(matcher_describers_.size())\n          << \", or there exists no permutation of elements such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Superset:\n      *os << \"no surjection from elements to requirements exists such that:\\n\";\n      break;\n    case UnorderedMatcherRequire::Subset:\n      *os << \"no injection from elements to requirements exists such that:\\n\";\n      break;\n  }\n  const char* sep = \"\";\n  for (size_t i = 0; i != matcher_describers_.size(); ++i) {\n    *os << sep;\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      *os << \" - element #\" << i << \" \";\n    } else {\n      *os << \" - an element \";\n    }\n    matcher_describers_[i]->DescribeTo(os);\n    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {\n      sep = \", and\\n\";\n    } else {\n      sep = \"\\n\";\n    }\n  }\n}\n\n// Checks that all matchers match at least one element, and that all\n// elements match at least one matcher. This enables faster matching\n// and better error reporting.\n// Returns false, writing an explanation to 'listener', if and only\n// if the success criteria are not met.\nbool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(\n    const ::std::vector<std::string>& element_printouts,\n    const MatchMatrix& matrix, MatchResultListener* listener) const {\n  if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {\n    return true;\n  }\n\n  const bool is_exact_match_with_size_discrepency =\n      match_flags() == UnorderedMatcherRequire::ExactMatch &&\n      matrix.LhsSize() != matrix.RhsSize();\n  if (is_exact_match_with_size_discrepency) {\n    // The element count doesn't match.  If the container is empty,\n    // there's no need to explain anything as Google Mock already\n    // prints the empty container. Otherwise we just need to show\n    // how many elements there actually are.\n    if (matrix.LhsSize() != 0 && listener->IsInterested()) {\n      *listener << \"which has \" << Elements(matrix.LhsSize()) << \"\\n\";\n    }\n  }\n\n  bool result = !is_exact_match_with_size_discrepency;\n  ::std::vector<char> element_matched(matrix.LhsSize(), 0);\n  ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);\n\n  for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {\n    for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {\n      char matched = matrix.HasEdge(ilhs, irhs);\n      element_matched[ilhs] |= matched;\n      matcher_matched[irhs] |= matched;\n    }\n  }\n\n  if (match_flags() & UnorderedMatcherRequire::Superset) {\n    const char* sep =\n        \"where the following matchers don't match any elements:\\n\";\n    for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {\n      if (matcher_matched[mi]) continue;\n      result = false;\n      if (listener->IsInterested()) {\n        *listener << sep << \"matcher #\" << mi << \": \";\n        matcher_describers_[mi]->DescribeTo(listener->stream());\n        sep = \",\\n\";\n      }\n    }\n  }\n\n  if (match_flags() & UnorderedMatcherRequire::Subset) {\n    const char* sep =\n        \"where the following elements don't match any matchers:\\n\";\n    const char* outer_sep = \"\";\n    if (!result) {\n      outer_sep = \"\\nand \";\n    }\n    for (size_t ei = 0; ei < element_matched.size(); ++ei) {\n      if (element_matched[ei]) continue;\n      result = false;\n      if (listener->IsInterested()) {\n        *listener << outer_sep << sep << \"element #\" << ei << \": \"\n                  << element_printouts[ei];\n        sep = \",\\n\";\n        outer_sep = \"\";\n      }\n    }\n  }\n  return result;\n}\n\nbool UnorderedElementsAreMatcherImplBase::FindPairing(\n    const MatchMatrix& matrix, MatchResultListener* listener) const {\n  ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);\n\n  size_t max_flow = matches.size();\n  if ((match_flags() & UnorderedMatcherRequire::Superset) &&\n      max_flow < matrix.RhsSize()) {\n    if (listener->IsInterested()) {\n      *listener << \"where no permutation of the elements can satisfy all \"\n                   \"matchers, and the closest match is \"\n                << max_flow << \" of \" << matrix.RhsSize()\n                << \" matchers with the pairings:\\n\";\n      LogElementMatcherPairVec(matches, listener->stream());\n    }\n    return false;\n  }\n  if ((match_flags() & UnorderedMatcherRequire::Subset) &&\n      max_flow < matrix.LhsSize()) {\n    if (listener->IsInterested()) {\n      *listener\n          << \"where not all elements can be matched, and the closest match is \"\n          << max_flow << \" of \" << matrix.RhsSize()\n          << \" matchers with the pairings:\\n\";\n      LogElementMatcherPairVec(matches, listener->stream());\n    }\n    return false;\n  }\n\n  if (matches.size() > 1) {\n    if (listener->IsInterested()) {\n      const char* sep = \"where:\\n\";\n      for (size_t mi = 0; mi < matches.size(); ++mi) {\n        *listener << sep << \" - element #\" << matches[mi].first\n                  << \" is matched by matcher #\" << matches[mi].second;\n        sep = \",\\n\";\n      }\n    }\n  }\n  return true;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock-spec-builders.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Mock - a framework for writing C++ mock classes.\n//\n// This file implements the spec builder syntax (ON_CALL and\n// EXPECT_CALL).\n\n#include \"gmock/gmock-spec-builders.h\"\n\n#include <stdlib.h>\n\n#include <iostream>  // NOLINT\n#include <map>\n#include <memory>\n#include <set>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\n#include \"gmock/gmock.h\"\n#include \"gtest/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC)\n#include <unistd.h>  // NOLINT\n#endif\n#ifdef GTEST_OS_QURT\n#include <qurt_event.h>\n#endif\n\n// Silence C4800 (C4800: 'int *const ': forcing value\n// to bool 'true' or 'false') for MSVC 15\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)\n#endif\n\nnamespace testing {\nnamespace internal {\n\n// Protects the mock object registry (in class Mock), all function\n// mockers, and all expectations.\nGTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);\n\n// Logs a message including file and line number information.\nGTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,\n                                const char* file, int line,\n                                const std::string& message) {\n  ::std::ostringstream s;\n  s << internal::FormatFileLocation(file, line) << \" \" << message\n    << ::std::endl;\n  Log(severity, s.str(), 0);\n}\n\n// Constructs an ExpectationBase object.\nExpectationBase::ExpectationBase(const char* a_file, int a_line,\n                                 const std::string& a_source_text)\n    : file_(a_file),\n      line_(a_line),\n      source_text_(a_source_text),\n      cardinality_specified_(false),\n      cardinality_(Exactly(1)),\n      call_count_(0),\n      retired_(false),\n      extra_matcher_specified_(false),\n      repeated_action_specified_(false),\n      retires_on_saturation_(false),\n      last_clause_(kNone),\n      action_count_checked_(false) {}\n\n// Destructs an ExpectationBase object.\nExpectationBase::~ExpectationBase() = default;\n\n// Explicitly specifies the cardinality of this expectation.  Used by\n// the subclasses to implement the .Times() clause.\nvoid ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {\n  cardinality_specified_ = true;\n  cardinality_ = a_cardinality;\n}\n\n// Retires all pre-requisites of this expectation.\nvoid ExpectationBase::RetireAllPreRequisites()\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  if (is_retired()) {\n    // We can take this short-cut as we never retire an expectation\n    // until we have retired all its pre-requisites.\n    return;\n  }\n\n  ::std::vector<ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      ExpectationBase* next = it->expectation_base().get();\n      if (!next->is_retired()) {\n        next->Retire();\n        expectations.push_back(next);\n      }\n    }\n  }\n}\n\n// Returns true if and only if all pre-requisites of this expectation\n// have been satisfied.\nbool ExpectationBase::AllPrerequisitesAreSatisfied() const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  ::std::vector<const ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    const ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      const ExpectationBase* next = it->expectation_base().get();\n      if (!next->IsSatisfied()) return false;\n      expectations.push_back(next);\n    }\n  }\n  return true;\n}\n\n// Adds unsatisfied pre-requisites of this expectation to 'result'.\nvoid ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  ::std::vector<const ExpectationBase*> expectations(1, this);\n  while (!expectations.empty()) {\n    const ExpectationBase* exp = expectations.back();\n    expectations.pop_back();\n\n    for (ExpectationSet::const_iterator it =\n             exp->immediate_prerequisites_.begin();\n         it != exp->immediate_prerequisites_.end(); ++it) {\n      const ExpectationBase* next = it->expectation_base().get();\n\n      if (next->IsSatisfied()) {\n        // If *it is satisfied and has a call count of 0, some of its\n        // pre-requisites may not be satisfied yet.\n        if (next->call_count_ == 0) {\n          expectations.push_back(next);\n        }\n      } else {\n        // Now that we know next is unsatisfied, we are not so interested\n        // in whether its pre-requisites are satisfied.  Therefore we\n        // don't iterate into it here.\n        *result += *it;\n      }\n    }\n  }\n}\n\n// Describes how many times a function call matching this\n// expectation has occurred.\nvoid ExpectationBase::DescribeCallCountTo(::std::ostream* os) const\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n\n  // Describes how many times the function is expected to be called.\n  *os << \"         Expected: to be \";\n  cardinality().DescribeTo(os);\n  *os << \"\\n           Actual: \";\n  Cardinality::DescribeActualCallCountTo(call_count(), os);\n\n  // Describes the state of the expectation (e.g. is it satisfied?\n  // is it active?).\n  *os << \" - \"\n      << (IsOverSaturated() ? \"over-saturated\"\n          : IsSaturated()   ? \"saturated\"\n          : IsSatisfied()   ? \"satisfied\"\n                            : \"unsatisfied\")\n      << \" and \" << (is_retired() ? \"retired\" : \"active\");\n}\n\n// Checks the action count (i.e. the number of WillOnce() and\n// WillRepeatedly() clauses) against the cardinality if this hasn't\n// been done before.  Prints a warning if there are too many or too\n// few actions.\nvoid ExpectationBase::CheckActionCountIfNotDone() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  bool should_check = false;\n  {\n    MutexLock l(&mutex_);\n    if (!action_count_checked_) {\n      action_count_checked_ = true;\n      should_check = true;\n    }\n  }\n\n  if (should_check) {\n    if (!cardinality_specified_) {\n      // The cardinality was inferred - no need to check the action\n      // count against it.\n      return;\n    }\n\n    // The cardinality was explicitly specified.\n    const int action_count = static_cast<int>(untyped_actions_.size());\n    const int upper_bound = cardinality().ConservativeUpperBound();\n    const int lower_bound = cardinality().ConservativeLowerBound();\n    bool too_many;  // True if there are too many actions, or false\n    // if there are too few.\n    if (action_count > upper_bound ||\n        (action_count == upper_bound && repeated_action_specified_)) {\n      too_many = true;\n    } else if (0 < action_count && action_count < lower_bound &&\n               !repeated_action_specified_) {\n      too_many = false;\n    } else {\n      return;\n    }\n\n    ::std::stringstream ss;\n    DescribeLocationTo(&ss);\n    ss << \"Too \" << (too_many ? \"many\" : \"few\") << \" actions specified in \"\n       << source_text() << \"...\\n\"\n       << \"Expected to be \";\n    cardinality().DescribeTo(&ss);\n    ss << \", but has \" << (too_many ? \"\" : \"only \") << action_count\n       << \" WillOnce()\" << (action_count == 1 ? \"\" : \"s\");\n    if (repeated_action_specified_) {\n      ss << \" and a WillRepeatedly()\";\n    }\n    ss << \".\";\n    Log(kWarning, ss.str(), -1);  // -1 means \"don't print stack trace\".\n  }\n}\n\n// Implements the .Times() clause.\nvoid ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {\n  if (last_clause_ == kTimes) {\n    ExpectSpecProperty(false,\n                       \".Times() cannot appear \"\n                       \"more than once in an EXPECT_CALL().\");\n  } else {\n    ExpectSpecProperty(\n        last_clause_ < kTimes,\n        \".Times() may only appear *before* .InSequence(), .WillOnce(), \"\n        \".WillRepeatedly(), or .RetiresOnSaturation(), not after.\");\n  }\n  last_clause_ = kTimes;\n\n  SpecifyCardinality(a_cardinality);\n}\n\n// Points to the implicit sequence introduced by a living InSequence\n// object (if any) in the current thread or NULL.\nGTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;\n\n// Reports an uninteresting call (whose description is in msg) in the\n// manner specified by 'reaction'.\nvoid ReportUninterestingCall(CallReaction reaction, const std::string& msg) {\n  // Include a stack trace only if --gmock_verbose=info is specified.\n  const int stack_frames_to_skip =\n      GMOCK_FLAG_GET(verbose) == kInfoVerbosity ? 3 : -1;\n  switch (reaction) {\n    case kAllow:\n      Log(kInfo, msg, stack_frames_to_skip);\n      break;\n    case kWarn:\n      Log(kWarning,\n          msg +\n              \"\\nNOTE: You can safely ignore the above warning unless this \"\n              \"call should not happen.  Do not suppress it by blindly adding \"\n              \"an EXPECT_CALL() if you don't mean to enforce the call.  \"\n              \"See \"\n              \"https://github.com/google/googletest/blob/main/docs/\"\n              \"gmock_cook_book.md#\"\n              \"knowing-when-to-expect-useoncall for details.\\n\",\n          stack_frames_to_skip);\n      break;\n    default:  // FAIL\n      Expect(false, nullptr, -1, msg);\n  }\n}\n\nUntypedFunctionMockerBase::UntypedFunctionMockerBase()\n    : mock_obj_(nullptr), name_(\"\") {}\n\nUntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;\n\n// Sets the mock object this mock method belongs to, and registers\n// this information in the global mock registry.  Will be called\n// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock\n// method.\nvoid UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  {\n    MutexLock l(&g_gmock_mutex);\n    mock_obj_ = mock_obj;\n  }\n  Mock::Register(mock_obj, this);\n}\n\n// Sets the mock object this mock method belongs to, and sets the name\n// of the mock function.  Will be called upon each invocation of this\n// mock function.\nvoid UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,\n                                                const char* name)\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  // We protect name_ under g_gmock_mutex in case this mock function\n  // is called from two threads concurrently.\n  MutexLock l(&g_gmock_mutex);\n  mock_obj_ = mock_obj;\n  name_ = name;\n}\n\n// Returns the name of the function being mocked.  Must be called\n// after RegisterOwner() or SetOwnerAndName() has been called.\nconst void* UntypedFunctionMockerBase::MockObject() const\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  const void* mock_obj;\n  {\n    // We protect mock_obj_ under g_gmock_mutex in case this mock\n    // function is called from two threads concurrently.\n    MutexLock l(&g_gmock_mutex);\n    Assert(mock_obj_ != nullptr, __FILE__, __LINE__,\n           \"MockObject() must not be called before RegisterOwner() or \"\n           \"SetOwnerAndName() has been called.\");\n    mock_obj = mock_obj_;\n  }\n  return mock_obj;\n}\n\n// Returns the name of this mock method.  Must be called after\n// SetOwnerAndName() has been called.\nconst char* UntypedFunctionMockerBase::Name() const\n    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {\n  const char* name;\n  {\n    // We protect name_ under g_gmock_mutex in case this mock\n    // function is called from two threads concurrently.\n    MutexLock l(&g_gmock_mutex);\n    Assert(name_ != nullptr, __FILE__, __LINE__,\n           \"Name() must not be called before SetOwnerAndName() has \"\n           \"been called.\");\n    name = name_;\n  }\n  return name;\n}\n\n// Returns an Expectation object that references and co-owns exp,\n// which must be an expectation on this mock function.\nExpectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {\n  // See the definition of untyped_expectations_ for why access to it\n  // is unprotected here.\n  for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();\n       it != untyped_expectations_.end(); ++it) {\n    if (it->get() == exp) {\n      return Expectation(*it);\n    }\n  }\n\n  Assert(false, __FILE__, __LINE__, \"Cannot find expectation.\");\n  return Expectation();\n  // The above statement is just to make the code compile, and will\n  // never be executed.\n}\n\n// Verifies that all expectations on this mock function have been\n// satisfied.  Reports one or more Google Test non-fatal failures\n// and returns false if not.\nbool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {\n  g_gmock_mutex.AssertHeld();\n  bool expectations_met = true;\n  for (UntypedExpectations::const_iterator it = untyped_expectations_.begin();\n       it != untyped_expectations_.end(); ++it) {\n    ExpectationBase* const untyped_expectation = it->get();\n    if (untyped_expectation->IsOverSaturated()) {\n      // There was an upper-bound violation.  Since the error was\n      // already reported when it occurred, there is no need to do\n      // anything here.\n      expectations_met = false;\n    } else if (!untyped_expectation->IsSatisfied()) {\n      expectations_met = false;\n      ::std::stringstream ss;\n\n      const ::std::string& expectation_name =\n          untyped_expectation->GetDescription();\n      ss << \"Actual function \";\n      if (!expectation_name.empty()) {\n        ss << \"\\\"\" << expectation_name << \"\\\" \";\n      }\n      ss << \"call count doesn't match \" << untyped_expectation->source_text()\n         << \"...\\n\";\n      // No need to show the source file location of the expectation\n      // in the description, as the Expect() call that follows already\n      // takes care of it.\n      untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);\n      untyped_expectation->DescribeCallCountTo(&ss);\n      Expect(false, untyped_expectation->file(), untyped_expectation->line(),\n             ss.str());\n    }\n  }\n\n  // Deleting our expectations may trigger other mock objects to be deleted, for\n  // example if an action contains a reference counted smart pointer to that\n  // mock object, and that is the last reference. So if we delete our\n  // expectations within the context of the global mutex we may deadlock when\n  // this method is called again. Instead, make a copy of the set of\n  // expectations to delete, clear our set within the mutex, and then clear the\n  // copied set outside of it.\n  UntypedExpectations expectations_to_delete;\n  untyped_expectations_.swap(expectations_to_delete);\n\n  g_gmock_mutex.Unlock();\n  expectations_to_delete.clear();\n  g_gmock_mutex.Lock();\n\n  return expectations_met;\n}\n\nstatic CallReaction intToCallReaction(int mock_behavior) {\n  if (mock_behavior >= kAllow && mock_behavior <= kFail) {\n    return static_cast<internal::CallReaction>(mock_behavior);\n  }\n  return kWarn;\n}\n\n}  // namespace internal\n\n// Class Mock.\n\nnamespace {\n\ntypedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;\n\n// The current state of a mock object.  Such information is needed for\n// detecting leaked mock objects and explicitly verifying a mock's\n// expectations.\nstruct MockObjectState {\n  MockObjectState()\n      : first_used_file(nullptr), first_used_line(-1), leakable(false) {}\n\n  // Where in the source file an ON_CALL or EXPECT_CALL is first\n  // invoked on this mock object.\n  const char* first_used_file;\n  int first_used_line;\n  ::std::string first_used_test_suite;\n  ::std::string first_used_test;\n  bool leakable;  // true if and only if it's OK to leak the object.\n  FunctionMockers function_mockers;  // All registered methods of the object.\n};\n\n// A global registry holding the state of all mock objects that are\n// alive.  A mock object is added to this registry the first time\n// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it.  It\n// is removed from the registry in the mock object's destructor.\nclass MockObjectRegistry {\n public:\n  // Maps a mock object (identified by its address) to its state.\n  typedef std::map<const void*, MockObjectState> StateMap;\n\n  // This destructor will be called when a program exits, after all\n  // tests in it have been run.  By then, there should be no mock\n  // object alive.  Therefore we report any living object as test\n  // failure, unless the user explicitly asked us to ignore it.\n  ~MockObjectRegistry() {\n    if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;\n    internal::MutexLock l(&internal::g_gmock_mutex);\n\n    int leaked_count = 0;\n    for (StateMap::const_iterator it = states_.begin(); it != states_.end();\n         ++it) {\n      if (it->second.leakable)  // The user said it's fine to leak this object.\n        continue;\n\n      // FIXME: Print the type of the leaked object.\n      // This can help the user identify the leaked object.\n      std::cout << \"\\n\";\n      const MockObjectState& state = it->second;\n      std::cout << internal::FormatFileLocation(state.first_used_file,\n                                                state.first_used_line);\n      std::cout << \" ERROR: this mock object\";\n      if (!state.first_used_test.empty()) {\n        std::cout << \" (used in test \" << state.first_used_test_suite << \".\"\n                  << state.first_used_test << \")\";\n      }\n      std::cout << \" should be deleted but never is. Its address is @\"\n                << it->first << \".\";\n      leaked_count++;\n    }\n    if (leaked_count > 0) {\n      std::cout << \"\\nERROR: \" << leaked_count << \" leaked mock \"\n                << (leaked_count == 1 ? \"object\" : \"objects\")\n                << \" found at program exit. Expectations on a mock object are \"\n                   \"verified when the object is destructed. Leaking a mock \"\n                   \"means that its expectations aren't verified, which is \"\n                   \"usually a test bug. If you really intend to leak a mock, \"\n                   \"you can suppress this error using \"\n                   \"testing::Mock::AllowLeak(mock_object), or you may use a \"\n                   \"fake or stub instead of a mock.\\n\";\n      std::cout.flush();\n      ::std::cerr.flush();\n      // RUN_ALL_TESTS() has already returned when this destructor is\n      // called.  Therefore we cannot use the normal Google Test\n      // failure reporting mechanism.\n#ifdef GTEST_OS_QURT\n      qurt_exception_raise_fatal();\n#else\n      _Exit(1);  // We cannot call exit() as it is not reentrant and\n                 // may already have been called.\n#endif\n    }\n  }\n\n  StateMap& states() { return states_; }\n\n private:\n  StateMap states_;\n};\n\n// Protected by g_gmock_mutex.\nMockObjectRegistry g_mock_object_registry;\n\n// Maps a mock object to the reaction Google Mock should have when an\n// uninteresting method is called.  Protected by g_gmock_mutex.\nstd::unordered_map<uintptr_t, internal::CallReaction>&\nUninterestingCallReactionMap() {\n  static auto* map = new std::unordered_map<uintptr_t, internal::CallReaction>;\n  return *map;\n}\n\n// Sets the reaction Google Mock should have when an uninteresting\n// method of the given mock object is called.\nvoid SetReactionOnUninterestingCalls(uintptr_t mock_obj,\n                                     internal::CallReaction reaction)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  UninterestingCallReactionMap()[mock_obj] = reaction;\n}\n\n}  // namespace\n\n// Tells Google Mock to allow uninteresting calls on the given mock\n// object.\nvoid Mock::AllowUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);\n}\n\n// Tells Google Mock to warn the user about uninteresting calls on the\n// given mock object.\nvoid Mock::WarnUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);\n}\n\n// Tells Google Mock to fail uninteresting calls on the given mock\n// object.\nvoid Mock::FailUninterestingCalls(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  SetReactionOnUninterestingCalls(mock_obj, internal::kFail);\n}\n\n// Tells Google Mock the given mock object is being destroyed and its\n// entry in the call-reaction table should be removed.\nvoid Mock::UnregisterCallReaction(uintptr_t mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));\n}\n\n// Returns the reaction Google Mock will have on uninteresting calls\n// made on the given mock object.\ninternal::CallReaction Mock::GetReactionOnUninterestingCalls(\n    const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  return (UninterestingCallReactionMap().count(\n              reinterpret_cast<uintptr_t>(mock_obj)) == 0)\n             ? internal::intToCallReaction(\n                   GMOCK_FLAG_GET(default_mock_behavior))\n             : UninterestingCallReactionMap()[reinterpret_cast<uintptr_t>(\n                   mock_obj)];\n}\n\n// Tells Google Mock to ignore mock_obj when checking for leaked mock\n// objects.\nvoid Mock::AllowLeak(const void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  g_mock_object_registry.states()[mock_obj].leakable = true;\n}\n\n// Verifies and clears all expectations on the given mock object.  If\n// the expectations aren't satisfied, generates one or more Google\n// Test non-fatal failures and returns false.\nbool Mock::VerifyAndClearExpectations(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  return VerifyAndClearExpectationsLocked(mock_obj);\n}\n\n// Verifies all expectations on the given mock object and clears its\n// default actions and expectations.  Returns true if and only if the\n// verification was successful.\nbool Mock::VerifyAndClear(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  ClearDefaultActionsLocked(mock_obj);\n  return VerifyAndClearExpectationsLocked(mock_obj);\n}\n\n// Verifies and clears all expectations on the given mock object.  If\n// the expectations aren't satisfied, generates one or more Google\n// Test non-fatal failures and returns false.\nbool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n  if (g_mock_object_registry.states().count(mock_obj) == 0) {\n    // No EXPECT_CALL() was set on the given mock object.\n    return true;\n  }\n\n  // Verifies and clears the expectations on each mock method in the\n  // given mock object.\n  bool expectations_met = true;\n  FunctionMockers& mockers =\n      g_mock_object_registry.states()[mock_obj].function_mockers;\n  for (FunctionMockers::const_iterator it = mockers.begin();\n       it != mockers.end(); ++it) {\n    if (!(*it)->VerifyAndClearExpectationsLocked()) {\n      expectations_met = false;\n    }\n  }\n\n  // We don't clear the content of mockers, as they may still be\n  // needed by ClearDefaultActionsLocked().\n  return expectations_met;\n}\n\nbool Mock::IsNaggy(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;\n}\nbool Mock::IsNice(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;\n}\nbool Mock::IsStrict(void* mock_obj)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;\n}\n\n// Registers a mock object and a mock method it owns.\nvoid Mock::Register(const void* mock_obj,\n                    internal::UntypedFunctionMockerBase* mocker)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);\n}\n\n// Tells Google Mock where in the source code mock_obj is used in an\n// ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this\n// information helps the user identify which object it is.\nvoid Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,\n                                           const char* file, int line)\n    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {\n  internal::MutexLock l(&internal::g_gmock_mutex);\n  MockObjectState& state = g_mock_object_registry.states()[mock_obj];\n  if (state.first_used_file == nullptr) {\n    state.first_used_file = file;\n    state.first_used_line = line;\n    const TestInfo* const test_info =\n        UnitTest::GetInstance()->current_test_info();\n    if (test_info != nullptr) {\n      state.first_used_test_suite = test_info->test_suite_name();\n      state.first_used_test = test_info->name();\n    }\n  }\n}\n\n// Unregisters a mock method; removes the owning mock object from the\n// registry when the last mock method associated with it has been\n// unregistered.  This is called only in the destructor of\n// FunctionMockerBase.\nvoid Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n  for (MockObjectRegistry::StateMap::iterator it =\n           g_mock_object_registry.states().begin();\n       it != g_mock_object_registry.states().end(); ++it) {\n    FunctionMockers& mockers = it->second.function_mockers;\n    if (mockers.erase(mocker) > 0) {\n      // mocker was in mockers and has been just removed.\n      if (mockers.empty()) {\n        g_mock_object_registry.states().erase(it);\n      }\n      return;\n    }\n  }\n}\n\n// Clears all ON_CALL()s set on the given mock object.\nvoid Mock::ClearDefaultActionsLocked(void* mock_obj)\n    GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {\n  internal::g_gmock_mutex.AssertHeld();\n\n  if (g_mock_object_registry.states().count(mock_obj) == 0) {\n    // No ON_CALL() was set on the given mock object.\n    return;\n  }\n\n  // Clears the default actions for each mock method in the given mock\n  // object.\n  FunctionMockers& mockers =\n      g_mock_object_registry.states()[mock_obj].function_mockers;\n  for (FunctionMockers::const_iterator it = mockers.begin();\n       it != mockers.end(); ++it) {\n    (*it)->ClearDefaultActionsLocked();\n  }\n\n  // We don't clear the content of mockers, as they may still be\n  // needed by VerifyAndClearExpectationsLocked().\n}\n\nExpectation::Expectation() = default;\n\nExpectation::Expectation(\n    const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)\n    : expectation_base_(an_expectation_base) {}\n\nExpectation::~Expectation() = default;\n\n// Adds an expectation to a sequence.\nvoid Sequence::AddExpectation(const Expectation& expectation) const {\n  if (*last_expectation_ != expectation) {\n    if (last_expectation_->expectation_base() != nullptr) {\n      expectation.expectation_base()->immediate_prerequisites_ +=\n          *last_expectation_;\n    }\n    *last_expectation_ = expectation;\n  }\n}\n\n// Creates the implicit sequence if there isn't one.\nInSequence::InSequence() {\n  if (internal::g_gmock_implicit_sequence.get() == nullptr) {\n    internal::g_gmock_implicit_sequence.set(new Sequence);\n    sequence_created_ = true;\n  } else {\n    sequence_created_ = false;\n  }\n}\n\n// Deletes the implicit sequence if it was created by the constructor\n// of this object.\nInSequence::~InSequence() {\n  if (sequence_created_) {\n    delete internal::g_gmock_implicit_sequence.get();\n    internal::g_gmock_implicit_sequence.set(nullptr);\n  }\n}\n\n}  // namespace testing\n\n#if defined(_MSC_VER) && (_MSC_VER == 1900)\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4800\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gmock/gmock.h\"\n\n#include <string>\n\n#include \"gmock/internal/gmock-port.h\"\n\nGMOCK_DEFINE_bool_(catch_leaked_mocks, true,\n                   \"true if and only if Google Mock should report leaked \"\n                   \"mock objects as failures.\");\n\nGMOCK_DEFINE_string_(verbose, testing::internal::kWarningVerbosity,\n                     \"Controls how verbose Google Mock's output is.\"\n                     \"  Valid values:\\n\"\n                     \"  info    - prints all messages.\\n\"\n                     \"  warning - prints warnings and errors.\\n\"\n                     \"  error   - prints errors only.\");\n\nGMOCK_DEFINE_int32_(default_mock_behavior, 1,\n                    \"Controls the default behavior of mocks.\"\n                    \"  Valid values:\\n\"\n                    \"  0 - by default, mocks act as NiceMocks.\\n\"\n                    \"  1 - by default, mocks act as NaggyMocks.\\n\"\n                    \"  2 - by default, mocks act as StrictMocks.\");\n\nnamespace testing {\nnamespace internal {\n\n// Parses a string as a command line flag.  The string should have the\n// format \"--gmock_flag=value\".  When def_optional is true, the\n// \"=value\" part can be omitted.\n//\n// Returns the value of the flag, or NULL if the parsing failed.\nstatic const char* ParseGoogleMockFlagValue(const char* str,\n                                            const char* flag_name,\n                                            bool def_optional) {\n  // str and flag must not be NULL.\n  if (str == nullptr || flag_name == nullptr) return nullptr;\n\n  // The flag must start with \"--gmock_\".\n  const std::string flag_name_str = std::string(\"--gmock_\") + flag_name;\n  const size_t flag_name_len = flag_name_str.length();\n  if (strncmp(str, flag_name_str.c_str(), flag_name_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_name_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) {\n    return flag_end;\n  }\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\n// Parses a string for a Google Mock bool flag, in the form of\n// \"--gmock_flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\n  return true;\n}\n\n// Parses a string for a Google Mock string flag, in the form of\n// \"--gmock_flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\ntemplate <typename String>\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                String* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  *value = value_str;\n  return true;\n}\n\nstatic bool ParseGoogleMockFlag(const char* str, const char* flag_name,\n                                int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseGoogleMockFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(Message() << \"The value of flag --\" << flag_name, value_str,\n                    value);\n}\n\n// The internal implementation of InitGoogleMock().\n//\n// The type parameter CharType can be instantiated to either char or\n// wchar_t.\ntemplate <typename CharType>\nvoid InitGoogleMockImpl(int* argc, CharType** argv) {\n  // Makes sure Google Test is initialized.  InitGoogleTest() is\n  // idempotent, so it's fine if the user has already called it.\n  InitGoogleTest(argc, argv);\n  if (*argc <= 0) return;\n\n  for (int i = 1; i != *argc; i++) {\n    const std::string arg_string = StreamableToString(argv[i]);\n    const char* const arg = arg_string.c_str();\n\n    // Do we see a Google Mock flag?\n    bool found_gmock_flag = false;\n\n#define GMOCK_INTERNAL_PARSE_FLAG(flag_name)            \\\n  if (!found_gmock_flag) {                              \\\n    auto value = GMOCK_FLAG_GET(flag_name);             \\\n    if (ParseGoogleMockFlag(arg, #flag_name, &value)) { \\\n      GMOCK_FLAG_SET(flag_name, value);                 \\\n      found_gmock_flag = true;                          \\\n    }                                                   \\\n  }\n\n    GMOCK_INTERNAL_PARSE_FLAG(catch_leaked_mocks)\n    GMOCK_INTERNAL_PARSE_FLAG(verbose)\n    GMOCK_INTERNAL_PARSE_FLAG(default_mock_behavior)\n\n    if (found_gmock_flag) {\n      // Yes.  Shift the remainder of the argv list left by one.  Note\n      // that argv has (*argc + 1) elements, the last one always being\n      // NULL.  The following loop moves the trailing NULL element as\n      // well.\n      for (int j = i; j != *argc; j++) {\n        argv[j] = argv[j + 1];\n      }\n\n      // Decrements the argument count.\n      (*argc)--;\n\n      // We also need to decrement the iterator as we just removed\n      // an element.\n      i--;\n    }\n  }\n}\n\n}  // namespace internal\n\n// Initializes Google Mock.  This must be called before running the\n// tests.  In particular, it parses a command line for the flags that\n// Google Mock recognizes.  Whenever a Google Mock flag is seen, it is\n// removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Mock flag variables are\n// updated.\n//\n// Since Google Test is needed for Google Mock to work, this function\n// also initializes Google Test and parses its flags, if that hasn't\n// been done.\nGTEST_API_ void InitGoogleMock(int* argc, char** argv) {\n  internal::InitGoogleMockImpl(argc, argv);\n}\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {\n  internal::InitGoogleMockImpl(argc, argv);\n}\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleMock() {\n  // Since Arduino doesn't have a command line, fake out the argc/argv arguments\n  int argc = 1;\n  const auto arg0 = \"dummy\";\n  char* argv0 = const_cast<char*>(arg0);\n  char** argv = &argv0;\n\n  internal::InitGoogleMockImpl(&argc, argv);\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googlemock/src/gmock_main.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include <iostream>\n\n#include \"gmock/gmock.h\"\n#include \"gtest/gtest.h\"\n\n#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \\\n    (defined(GTEST_OS_NRF52) && defined(ARDUINO))\n#ifdef GTEST_OS_ESP8266\nextern \"C\" {\n#endif\nvoid setup() {\n  // Since Google Mock depends on Google Test, InitGoogleMock() is\n  // also responsible for initializing Google Test.  Therefore there's\n  // no need for calling testing::InitGoogleTest() separately.\n  testing::InitGoogleMock();\n}\nvoid loop() { RUN_ALL_TESTS(); }\n#ifdef GTEST_OS_ESP8266\n}\n#endif\n\n#else\n\n// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which\n// causes a link error when _tmain is defined in a static library and UNICODE\n// is enabled. For this reason instead of _tmain, main function is used on\n// Windows. See the following link to track the current status of this bug:\n// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library\n// // NOLINT\n#ifdef GTEST_OS_WINDOWS_MOBILE\n#include <tchar.h>  // NOLINT\n\nGTEST_API_ int _tmain(int argc, TCHAR** argv) {\n#else\nGTEST_API_ int main(int argc, char** argv) {\n#endif  // GTEST_OS_WINDOWS_MOBILE\n  std::cout << \"Running main() from gmock_main.cc\\n\";\n  // Since Google Mock depends on Google Test, InitGoogleMock() is\n  // also responsible for initializing Google Test.  Therefore there's\n  // no need for calling testing::InitGoogleTest() separately.\n  testing::InitGoogleMock(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/CMakeLists.txt",
    "content": "########################################################################\n# Note: CMake support is community-based. The maintainers do not use CMake\n# internally.\n#\n# CMake build script for Google Test.\n#\n# To run the tests for Google Test itself on Linux, use 'make test' or\n# ctest. You can select which tests to run using 'ctest -R regex'.\n# For more options, run 'ctest --help'.\n\n# When other libraries are using a shared version of runtime libraries,\n# Google Test also has to use one.\noption(\n  gtest_force_shared_crt\n  \"Use shared (DLL) run-time lib even when Google Test is built as static lib.\"\n  OFF)\n\noption(gtest_build_tests \"Build all of gtest's own tests.\" OFF)\n\noption(gtest_build_samples \"Build gtest's sample programs.\" OFF)\n\noption(gtest_disable_pthreads \"Disable uses of pthreads in gtest.\" OFF)\n\noption(\n  gtest_hide_internal_symbols\n  \"Build gtest with internal symbols hidden in shared libraries.\"\n  OFF)\n\n# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().\ninclude(cmake/hermetic_build.cmake OPTIONAL)\n\nif (COMMAND pre_project_set_up_hermetic_build)\n  pre_project_set_up_hermetic_build()\nendif()\n\n########################################################################\n#\n# Project-wide settings.\n\n# Name of the project.\n#\n# CMake files in this project can refer to the root source directory\n# as ${gtest_SOURCE_DIR} and to the root binary directory as\n# ${gtest_BINARY_DIR}.\n# Language \"C\" is required for find_package(Threads).\n\n# Project version.\n\ncmake_minimum_required(VERSION 3.13)\nproject(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)\n\nif (COMMAND set_up_hermetic_build)\n  set_up_hermetic_build()\nendif()\n\n# These commands only run if this is the main project.\nif(CMAKE_PROJECT_NAME STREQUAL \"gtest\" OR CMAKE_PROJECT_NAME STREQUAL \"googletest-distribution\")\n\n  # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to\n  # make it prominent in the GUI.\n  option(BUILD_SHARED_LIBS \"Build shared libraries (DLLs).\" OFF)\n\nelse()\n\n  mark_as_advanced(\n    gtest_force_shared_crt\n    gtest_build_tests\n    gtest_build_samples\n    gtest_disable_pthreads\n    gtest_hide_internal_symbols)\n\nendif()\n\n\nif (gtest_hide_internal_symbols)\n  set(CMAKE_CXX_VISIBILITY_PRESET hidden)\n  set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)\nendif()\n\n# Define helper functions and macros used by Google Test.\ninclude(cmake/internal_utils.cmake)\n\nconfig_compiler_and_linker()  # Defined in internal_utils.cmake.\n\n# Needed to set the namespace for both the export targets and the\n# alias libraries.\nset(cmake_package_name GTest CACHE INTERNAL \"\")\n\n# Create the CMake package file descriptors.\nif (INSTALL_GTEST)\n  include(CMakePackageConfigHelpers)\n  set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL \"\")\n  set(generated_dir \"${CMAKE_CURRENT_BINARY_DIR}/generated\" CACHE INTERNAL \"\")\n  set(cmake_files_install_dir \"${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}\")\n  set(version_file \"${generated_dir}/${cmake_package_name}ConfigVersion.cmake\")\n  write_basic_package_version_file(${version_file} VERSION ${GOOGLETEST_VERSION} COMPATIBILITY AnyNewerVersion)\n  install(EXPORT ${targets_export_name}\n    COMPONENT \"${PROJECT_NAME}\"\n    NAMESPACE ${cmake_package_name}::\n    DESTINATION ${cmake_files_install_dir})\n  set(config_file \"${generated_dir}/${cmake_package_name}Config.cmake\")\n  configure_package_config_file(\"${gtest_SOURCE_DIR}/cmake/Config.cmake.in\"\n    \"${config_file}\" INSTALL_DESTINATION ${cmake_files_install_dir})\n  install(FILES ${version_file} ${config_file}\n    COMPONENT \"${PROJECT_NAME}\"\n    DESTINATION ${cmake_files_install_dir})\nendif()\n\n# Where Google Test's .h files can be found.\nset(gtest_build_include_dirs\n  \"${gtest_SOURCE_DIR}/include\"\n  \"${gtest_SOURCE_DIR}\")\ninclude_directories(${gtest_build_include_dirs})\n\n########################################################################\n#\n# Defines the gtest & gtest_main libraries. User tests should link\n# with one of them.\n\n# Google Test libraries. We build them using more strict warnings than what\n# are used for other targets, to ensure that gtest can be compiled by a user\n# aggressive about warnings.\ncxx_library(gtest \"${cxx_strict}\" src/gtest-all.cc)\nset_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})\nif(GTEST_HAS_ABSL)\n  target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1)\n  target_link_libraries(gtest PUBLIC\n    absl::failure_signal_handler\n    absl::stacktrace\n    absl::symbolize\n    absl::flags_parse\n    absl::flags_reflection\n    absl::flags_usage\n    absl::strings\n    absl::any\n    absl::optional\n    absl::variant\n    re2::re2\n  )\nendif()\ncxx_library(gtest_main \"${cxx_strict}\" src/gtest_main.cc)\nset_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION})\nstring(REPLACE \";\" \"$<SEMICOLON>\" dirs \"${gtest_build_include_dirs}\")\ntarget_include_directories(gtest SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\ntarget_include_directories(gtest_main SYSTEM INTERFACE\n  \"$<BUILD_INTERFACE:${dirs}>\"\n  \"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>\")\nif(CMAKE_SYSTEM_NAME MATCHES \"QNX\" AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 7.1)\n  target_link_libraries(gtest PUBLIC regex)\nendif()\ntarget_link_libraries(gtest_main PUBLIC gtest)\n\n########################################################################\n#\n# Install rules.\ninstall_project(gtest gtest_main)\n\n########################################################################\n#\n# Samples on how to link user tests with gtest or gtest_main.\n#\n# They are not built by default. To build them, set the\n# gtest_build_samples option to ON. You can do it by running ccmake\n# or specifying the -Dgtest_build_samples=ON flag when running cmake.\n\nif (gtest_build_samples)\n  cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)\n  cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)\n  cxx_executable(sample3_unittest samples gtest_main)\n  cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)\n  cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)\n  cxx_executable(sample6_unittest samples gtest_main)\n  cxx_executable(sample7_unittest samples gtest_main)\n  cxx_executable(sample8_unittest samples gtest_main)\n  cxx_executable(sample9_unittest samples gtest)\n  cxx_executable(sample10_unittest samples gtest)\nendif()\n\n########################################################################\n#\n# Google Test's own tests.\n#\n# You can skip this section if you aren't interested in testing\n# Google Test itself.\n#\n# The tests are not built by default. To build them, set the\n# gtest_build_tests option to ON. You can do it by running ccmake\n# or specifying the -Dgtest_build_tests=ON flag when running cmake.\n\nif (gtest_build_tests)\n  # This must be set in the root directory for the tests to be run by\n  # 'make test' or ctest.\n  enable_testing()\n\n  ############################################################\n  # C++ tests built with standard compiler flags.\n\n  cxx_test(googletest-death-test-test gtest_main)\n  cxx_test(gtest_environment_test gtest)\n  cxx_test(googletest-filepath-test gtest_main)\n  cxx_test(googletest-listener-test gtest_main)\n  cxx_test(gtest_main_unittest gtest_main)\n  cxx_test(googletest-message-test gtest_main)\n  cxx_test(gtest_no_test_unittest gtest)\n  cxx_test(googletest-options-test gtest_main)\n  cxx_test(googletest-param-test-test gtest\n    test/googletest-param-test2-test.cc)\n  cxx_test(googletest-port-test gtest_main)\n  cxx_test(gtest_pred_impl_unittest gtest_main)\n  cxx_test(gtest_premature_exit_test gtest\n    test/gtest_premature_exit_test.cc)\n  cxx_test(googletest-printers-test gtest_main)\n  cxx_test(gtest_prod_test gtest_main\n    test/production.cc)\n  cxx_test(gtest_repeat_test gtest)\n  cxx_test(gtest_sole_header_test gtest_main)\n  cxx_test(gtest_stress_test gtest)\n  cxx_test(googletest-test-part-test gtest_main)\n  cxx_test(gtest_throw_on_failure_ex_test gtest)\n  cxx_test(gtest-typed-test_test gtest_main\n    test/gtest-typed-test2_test.cc)\n  cxx_test(gtest_unittest gtest_main)\n  cxx_test(gtest-unittest-api_test gtest)\n  cxx_test(gtest_skip_in_environment_setup_test gtest_main)\n  cxx_test(gtest_skip_test gtest_main)\n\n  ############################################################\n  # C++ tests built with non-standard compiler flags.\n\n  # MSVC 7.1 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310)\n    cxx_library(gtest_no_exception \"${cxx_no_exception}\"\n      src/gtest-all.cc)\n    cxx_library(gtest_main_no_exception \"${cxx_no_exception}\"\n      src/gtest-all.cc src/gtest_main.cc)\n  endif()\n  cxx_library(gtest_main_no_rtti \"${cxx_no_rtti}\"\n    src/gtest-all.cc src/gtest_main.cc)\n\n  cxx_test_with_flags(gtest-death-test_ex_nocatch_test\n    \"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0\"\n    gtest test/googletest-death-test_ex_test.cc)\n  cxx_test_with_flags(gtest-death-test_ex_catch_test\n    \"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1\"\n    gtest test/googletest-death-test_ex_test.cc)\n\n  cxx_test_with_flags(gtest_no_rtti_unittest \"${cxx_no_rtti}\"\n    gtest_main_no_rtti test/gtest_unittest.cc)\n\n  cxx_shared_library(gtest_dll \"${cxx_default}\"\n    src/gtest-all.cc src/gtest_main.cc)\n\n  cxx_executable_with_flags(gtest_dll_test_ \"${cxx_default}\"\n    gtest_dll test/gtest_all_test.cc)\n  set_target_properties(gtest_dll_test_\n                        PROPERTIES\n                        COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n\n  ############################################################\n  # Python tests.\n\n  cxx_executable(googletest-break-on-failure-unittest_ test gtest)\n  py_test(googletest-break-on-failure-unittest)\n\n  py_test(gtest_skip_check_output_test)\n  py_test(gtest_skip_environment_check_output_test)\n\n  # Visual Studio .NET 2003 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003\n    cxx_executable_with_flags(\n      googletest-catch-exceptions-no-ex-test_\n      \"${cxx_no_exception}\"\n      gtest_main_no_exception\n      test/googletest-catch-exceptions-test_.cc)\n  endif()\n\n  cxx_executable_with_flags(\n    googletest-catch-exceptions-ex-test_\n    \"${cxx_exception}\"\n    gtest_main\n    test/googletest-catch-exceptions-test_.cc)\n  py_test(googletest-catch-exceptions-test)\n\n  cxx_executable(googletest-color-test_ test gtest)\n  py_test(googletest-color-test)\n\n  cxx_executable(googletest-env-var-test_ test gtest)\n  py_test(googletest-env-var-test)\n\n  cxx_executable(googletest-filter-unittest_ test gtest)\n  py_test(googletest-filter-unittest)\n\n  cxx_executable(gtest_help_test_ test gtest_main)\n  py_test(gtest_help_test)\n\n  cxx_executable(googletest-list-tests-unittest_ test gtest)\n  py_test(googletest-list-tests-unittest)\n\n  cxx_executable(googletest-output-test_ test gtest)\n  py_test(googletest-output-test --no_stacktrace_support)\n\n  cxx_executable(googletest-shuffle-test_ test gtest)\n  py_test(googletest-shuffle-test)\n\n  # MSVC 7.1 does not support STL with exceptions disabled.\n  if (NOT MSVC OR MSVC_VERSION GREATER 1310)\n    cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)\n    set_target_properties(googletest-throw-on-failure-test_\n      PROPERTIES\n      COMPILE_FLAGS \"${cxx_no_exception}\")\n    py_test(googletest-throw-on-failure-test)\n  endif()\n\n  cxx_executable(googletest-uninitialized-test_ test gtest)\n  py_test(googletest-uninitialized-test)\n\n  cxx_executable(gtest_list_output_unittest_ test gtest)\n  py_test(gtest_list_output_unittest)\n\n  cxx_executable(gtest_xml_outfile1_test_ test gtest_main)\n  cxx_executable(gtest_xml_outfile2_test_ test gtest_main)\n  py_test(gtest_xml_outfiles_test)\n  py_test(googletest-json-outfiles-test)\n\n  cxx_executable(gtest_xml_output_unittest_ test gtest)\n  py_test(gtest_xml_output_unittest --no_stacktrace_support)\n  py_test(googletest-json-output-unittest --no_stacktrace_support)\nendif()\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/cmake/Config.cmake.in",
    "content": "@PACKAGE_INIT@\ninclude(CMakeFindDependencyMacro)\nif (@GTEST_HAS_PTHREAD@)\n  set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)\n  find_dependency(Threads)\nendif()\nif (@GTEST_HAS_ABSL@)\n  find_dependency(absl)\n  find_dependency(re2)\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake\")\ncheck_required_components(\"@project_name@\")\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/cmake/gtest.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gtest\nDescription: GoogleTest (without main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nLibs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/cmake/gtest_main.pc.in",
    "content": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\n\nName: gtest_main\nDescription: GoogleTest (with main() function)\nVersion: @PROJECT_VERSION@\nURL: https://github.com/google/googletest\nRequires: gtest = @PROJECT_VERSION@\nLibs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@\nCflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/cmake/internal_utils.cmake",
    "content": "# Defines functions and macros useful for building Google Test and\n# Google Mock.\n#\n# Note:\n#\n# - This file will be run twice when building Google Mock (once via\n#   Google Test's CMakeLists.txt, and once via Google Mock's).\n#   Therefore it shouldn't have any side effects other than defining\n#   the functions and macros.\n#\n# - The functions/macros defined in this file may depend on Google\n#   Test and Google Mock's option() definitions, and thus must be\n#   called *after* the options have been defined.\n\n# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.\n#\n# This must be a macro(), as inside a function string() can only\n# update variables in the function scope.\nmacro(fix_default_compiler_settings_)\n  if (CMAKE_CXX_COMPILER_ID MATCHES \"MSVC|Clang\")\n    # For MSVC and Clang, CMake sets certain flags to defaults we want to\n    # override.\n    # This replacement code is taken from sample in the CMake Wiki at\n    # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace.\n    foreach (flag_var\n             CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE\n             CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO\n             CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE\n             CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)\n      if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)\n        # When Google Test is built as a shared library, it should also use\n        # shared runtime libraries. Otherwise, it may end up with multiple\n        # copies of runtime library data in different modules, resulting in\n        # hard-to-find crashes. When it is built as a static library, it is\n        # preferable to use CRT as static libraries, as we don't have to rely\n        # on CRT DLLs being available. CMake always defaults to using shared\n        # CRT libraries, so we override that default here.\n        string(REPLACE \"/MD\" \"-MT\" ${flag_var} \"${${flag_var}}\")\n\n        # When using Ninja with Clang, static builds pass -D_DLL on Windows.\n        # This is incorrect and should not happen, so we fix that here.\n        string(REPLACE \"-D_DLL\" \"\" ${flag_var} \"${${flag_var}}\")\n      endif()\n\n      # We prefer more strict warning checking for building Google Test.\n      # Replaces /W3 with /W4 in defaults.\n      string(REPLACE \"/W3\" \"/W4\" ${flag_var} \"${${flag_var}}\")\n\n      # Prevent D9025 warning for targets that have exception handling\n      # turned off (/EHs-c- flag). Where required, exceptions are explicitly\n      # re-enabled using the cxx_exception_flags variable.\n      string(REPLACE \"/EHsc\" \"\" ${flag_var} \"${${flag_var}}\")\n    endforeach()\n  endif()\nendmacro()\n\n# Defines the compiler/linker flags used to build Google Test and\n# Google Mock. You can tweak these definitions to suit your need. A\n# variable's value is empty before it's explicitly assigned to.\nmacro(config_compiler_and_linker)\n  # Note: pthreads on MinGW is not supported, even if available\n  # instead, we use windows threading primitives.\n  unset(GTEST_HAS_PTHREAD)\n  if (NOT gtest_disable_pthreads AND NOT MINGW)\n    # Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.\n    find_package(Threads)\n    if (CMAKE_USE_PTHREADS_INIT)\n      set(GTEST_HAS_PTHREAD ON)\n    endif()\n  endif()\n\n  fix_default_compiler_settings_()\n  if (MSVC)\n    # Newlines inside flags variables break CMake's NMake generator.\n    # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.\n    set(cxx_base_flags \"-GS -W4 -WX -wd4251 -wd4275 -nologo -J\")\n    set(cxx_base_flags \"${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32\")\n    set(cxx_base_flags \"${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN\")\n    set(cxx_exception_flags \"-EHsc -D_HAS_EXCEPTIONS=1\")\n    set(cxx_no_exception_flags \"-EHs-c- -D_HAS_EXCEPTIONS=0\")\n    set(cxx_no_rtti_flags \"-GR-\")\n    # Suppress \"unreachable code\" warning,\n    # https://stackoverflow.com/questions/3232669 explains the issue.\n    set(cxx_base_flags \"${cxx_base_flags} -wd4702\")\n    # Ensure MSVC treats source files as UTF-8 encoded.\n    if(CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\")\n      set(cxx_base_flags \"${cxx_base_flags} -utf-8\")\n    endif()\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n      set(cxx_base_flags \"${cxx_base_flags} /fp:precise -Wno-inconsistent-missing-override -Wno-microsoft-exception-spec -Wno-unused-function -Wno-unused-but-set-variable\")\n    endif()\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" OR\n      CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n    set(cxx_base_flags \"-Wall -Wshadow -Wconversion -Wundef\")\n    set(cxx_exception_flags \"-fexceptions\")\n    set(cxx_no_exception_flags \"-fno-exceptions\")\n    set(cxx_strict_flags \"-W -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wunused-parameter -Wcast-align -Winline -Wredundant-decls\")\n    set(cxx_no_rtti_flags \"-fno-rtti\")\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\")\n      set(cxx_strict_flags \"${cxx_strict_flags} -Wchar-subscripts\")\n    endif()\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\")\n      set(cxx_base_flags \"${cxx_base_flags} -Wno-implicit-float-size-conversion -ffp-model=precise\")\n    endif()\n  elseif (CMAKE_COMPILER_IS_GNUCXX)\n    set(cxx_base_flags \"-Wall -Wshadow -Wundef\")\n    if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)\n      set(cxx_base_flags \"${cxx_base_flags} -Wno-error=dangling-else\")\n    endif()\n    set(cxx_exception_flags \"-fexceptions\")\n    set(cxx_no_exception_flags \"-fno-exceptions\")\n    # Until version 4.3.2, GCC doesn't define a macro to indicate\n    # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI\n    # explicitly.\n    set(cxx_no_rtti_flags \"-fno-rtti -DGTEST_HAS_RTTI=0\")\n    set(cxx_strict_flags\n      \"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"SunPro\")\n    set(cxx_exception_flags \"-features=except\")\n    # Sun Pro doesn't provide macros to indicate whether exceptions and\n    # RTTI are enabled, so we define GTEST_HAS_* explicitly.\n    set(cxx_no_exception_flags \"-features=no%except -DGTEST_HAS_EXCEPTIONS=0\")\n    set(cxx_no_rtti_flags \"-features=no%rtti -DGTEST_HAS_RTTI=0\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"VisualAge\" OR\n      CMAKE_CXX_COMPILER_ID STREQUAL \"XL\")\n    # CMake 2.8 changes Visual Age's compiler ID to \"XL\".\n    set(cxx_exception_flags \"-qeh\")\n    set(cxx_no_exception_flags \"-qnoeh\")\n    # Until version 9.0, Visual Age doesn't define a macro to indicate\n    # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI\n    # explicitly.\n    set(cxx_no_rtti_flags \"-qnortti -DGTEST_HAS_RTTI=0\")\n  elseif (CMAKE_CXX_COMPILER_ID STREQUAL \"HP\")\n    set(cxx_base_flags \"-AA -mt\")\n    set(cxx_exception_flags \"-DGTEST_HAS_EXCEPTIONS=1\")\n    set(cxx_no_exception_flags \"+noeh -DGTEST_HAS_EXCEPTIONS=0\")\n    # RTTI can not be disabled in HP aCC compiler.\n    set(cxx_no_rtti_flags \"\")\n  endif()\n\n  # The pthreads library is available and allowed?\n  if (DEFINED GTEST_HAS_PTHREAD)\n    set(GTEST_HAS_PTHREAD_MACRO \"-DGTEST_HAS_PTHREAD=1\")\n  else()\n    set(GTEST_HAS_PTHREAD_MACRO \"-DGTEST_HAS_PTHREAD=0\")\n  endif()\n  set(cxx_base_flags \"${cxx_base_flags} ${GTEST_HAS_PTHREAD_MACRO}\")\n\n  # For building gtest's own tests and samples.\n  set(cxx_exception \"${cxx_base_flags} ${cxx_exception_flags}\")\n  set(cxx_no_exception\n    \"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}\")\n  set(cxx_default \"${cxx_exception}\")\n  set(cxx_no_rtti \"${cxx_default} ${cxx_no_rtti_flags}\")\n\n  # For building the gtest libraries.\n  set(cxx_strict \"${cxx_default} ${cxx_strict_flags}\")\nendmacro()\n\n# Defines the gtest & gtest_main libraries. User tests should link\n# with one of them.\nfunction(cxx_library_with_type name type cxx_flags)\n  # type can be either STATIC or SHARED to denote a static or shared library.\n  # ARGN refers to additional arguments after 'cxx_flags'.\n  add_library(${name} ${type} ${ARGN})\n  add_library(${cmake_package_name}::${name} ALIAS ${name})\n  set_target_properties(${name}\n    PROPERTIES\n    COMPILE_FLAGS \"${cxx_flags}\")\n  # Set the output directory for build artifacts.\n  set_target_properties(${name}\n    PROPERTIES\n    RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\"\n    LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\"\n    ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\"\n    PDB_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\"\n    COMPILE_PDB_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/lib\")\n  # Make PDBs match library name.\n  get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX)\n  set_target_properties(${name}\n    PROPERTIES\n    PDB_NAME \"${name}\"\n    PDB_NAME_DEBUG \"${name}${pdb_debug_postfix}\"\n    COMPILE_PDB_NAME \"${name}\"\n    COMPILE_PDB_NAME_DEBUG \"${name}${pdb_debug_postfix}\")\n\n  if (BUILD_SHARED_LIBS OR type STREQUAL \"SHARED\")\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_DEFINITIONS \"GTEST_CREATE_SHARED_LIBRARY=1\")\n    target_compile_definitions(${name} INTERFACE\n      $<INSTALL_INTERFACE:GTEST_LINKED_AS_SHARED_LIBRARY=1>)\n  endif()\n  if (DEFINED GTEST_HAS_PTHREAD)\n    target_link_libraries(${name} PUBLIC Threads::Threads)\n  endif()\n\n  target_compile_features(${name} PUBLIC cxx_std_14)\nendfunction()\n\n########################################################################\n#\n# Helper functions for creating build targets.\n\nfunction(cxx_shared_library name cxx_flags)\n  cxx_library_with_type(${name} SHARED \"${cxx_flags}\" ${ARGN})\nendfunction()\n\nfunction(cxx_library name cxx_flags)\n  cxx_library_with_type(${name} \"\" \"${cxx_flags}\" ${ARGN})\nendfunction()\n\n# cxx_executable_with_flags(name cxx_flags libs srcs...)\n#\n# Creates a named C++ executable that depends on the given libraries and\n# is built from the given source files with the given compiler flags.\nfunction(cxx_executable_with_flags name cxx_flags libs)\n  add_executable(${name} ${ARGN})\n  if (MSVC)\n    # BigObj required for tests.\n    set(cxx_flags \"${cxx_flags} -bigobj\")\n  endif()\n  if (cxx_flags)\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_FLAGS \"${cxx_flags}\")\n  endif()\n  if (BUILD_SHARED_LIBS)\n    set_target_properties(${name}\n      PROPERTIES\n      COMPILE_DEFINITIONS \"GTEST_LINKED_AS_SHARED_LIBRARY=1\")\n  endif()\n  # To support mixing linking in static and dynamic libraries, link each\n  # library in with an extra call to target_link_libraries.\n  foreach (lib \"${libs}\")\n    target_link_libraries(${name} ${lib})\n  endforeach()\nendfunction()\n\n# cxx_executable(name dir lib srcs...)\n#\n# Creates a named target that depends on the given libs and is built\n# from the given source files. dir/name.cc is implicitly included in\n# the source file list.\nfunction(cxx_executable name dir libs)\n  cxx_executable_with_flags(\n    ${name} \"${cxx_default}\" \"${libs}\" \"${dir}/${name}.cc\" ${ARGN})\nendfunction()\n\nif(gtest_build_tests)\n  find_package(Python3)\nendif()\n\n# cxx_test_with_flags(name cxx_flags libs srcs...)\n#\n# Creates a named C++ test that depends on the given libs and is built\n# from the given source files with the given compiler flags.\nfunction(cxx_test_with_flags name cxx_flags libs)\n  cxx_executable_with_flags(${name} \"${cxx_flags}\" \"${libs}\" ${ARGN})\n    add_test(NAME ${name} COMMAND \"$<TARGET_FILE:${name}>\")\nendfunction()\n\n# cxx_test(name libs srcs...)\n#\n# Creates a named test target that depends on the given libs and is\n# built from the given source files. Unlike cxx_test_with_flags,\n# test/name.cc is already implicitly included in the source file list.\nfunction(cxx_test name libs)\n  cxx_test_with_flags(\"${name}\" \"${cxx_default}\" \"${libs}\"\n    \"test/${name}.cc\" ${ARGN})\nendfunction()\n\n# py_test(name)\n#\n# Creates a Python test with the given name whose main module is in\n# test/name.py. It does nothing if Python is not installed.\nfunction(py_test name)\n  if (NOT Python3_Interpreter_FOUND)\n    return()\n  endif()\n\n  get_cmake_property(is_multi \"GENERATOR_IS_MULTI_CONFIG\")\n  set(build_dir \"${CMAKE_CURRENT_BINARY_DIR}\")\n  if (is_multi)\n    set(build_dir \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>\")\n  endif()\n\n  add_test(NAME ${name}\n      COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py\n          --build_dir=${build_dir} ${ARGN})\n\n  # Make the Python import path consistent between Bazel and CMake.\n  set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR})\nendfunction()\n\n# install_project(targets...)\n#\n# Installs the specified targets and configures the associated pkgconfig files.\nfunction(install_project)\n  if(INSTALL_GTEST)\n    install(DIRECTORY \"${PROJECT_SOURCE_DIR}/include/\"\n      COMPONENT \"${PROJECT_NAME}\"\n      DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}\")\n    # Install the project targets.\n    install(TARGETS ${ARGN}\n      EXPORT ${targets_export_name}\n      COMPONENT \"${PROJECT_NAME}\"\n      RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n      ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n      LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\")\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"MSVC\")\n      # Install PDBs.\n      foreach(t ${ARGN})\n        get_target_property(t_pdb_name ${t} COMPILE_PDB_NAME)\n        get_target_property(t_pdb_name_debug ${t} COMPILE_PDB_NAME_DEBUG)\n        get_target_property(t_pdb_output_directory ${t} PDB_OUTPUT_DIRECTORY)\n        install(FILES\n          \"${t_pdb_output_directory}/\\${CMAKE_INSTALL_CONFIG_NAME}/$<$<CONFIG:Debug>:${t_pdb_name_debug}>$<$<NOT:$<CONFIG:Debug>>:${t_pdb_name}>.pdb\"\n          COMPONENT \"${PROJECT_NAME}\"\n          DESTINATION ${CMAKE_INSTALL_LIBDIR}\n          OPTIONAL)\n      endforeach()\n    endif()\n    # Configure and install pkgconfig files.\n    foreach(t ${ARGN})\n      set(configured_pc \"${generated_dir}/${t}.pc\")\n      configure_file(\"${PROJECT_SOURCE_DIR}/cmake/${t}.pc.in\"\n        \"${configured_pc}\" @ONLY)\n      install(FILES \"${configured_pc}\"\n        COMPONENT \"${PROJECT_NAME}\"\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n    endforeach()\n  endif()\nendfunction()\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/cmake/libgtest.la.in",
    "content": "# libgtest.la - a libtool library file\n# Generated by libtool (GNU libtool) 2.4.6\n\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# Names of this library.\nlibrary_names='libgtest.so'\n\n# Is this an already installed library?\ninstalled=yes\n\n# Should we warn about portability when linking against -modules?\nshouldnotlink=no\n\n# Files to dlopen/dlpreopen\ndlopen=''\ndlpreopen=''\n\n# Directory that this library needs to be installed in:\nlibdir='@CMAKE_INSTALL_FULL_LIBDIR@'\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-assertion-result.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements the AssertionResult type.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n\n#include <memory>\n#include <ostream>\n#include <string>\n#include <type_traits>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251                                   \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// A class for indicating whether an assertion was successful.  When\n// the assertion wasn't successful, the AssertionResult object\n// remembers a non-empty message that describes how it failed.\n//\n// To create an instance of this class, use one of the factory functions\n// (AssertionSuccess() and AssertionFailure()).\n//\n// This class is useful for two purposes:\n//   1. Defining predicate functions to be used with Boolean test assertions\n//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts\n//   2. Defining predicate-format functions to be\n//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).\n//\n// For example, if you define IsEven predicate:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))\n// will print the message\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false (5 is odd)\n//   Expected: true\n//\n// instead of a more opaque\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false\n//   Expected: true\n//\n// in case IsEven is a simple Boolean predicate.\n//\n// If you expect your predicate to be reused and want to support informative\n// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up\n// about half as often as positive ones in our tests), supply messages for\n// both success and failure cases:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess() << n << \" is even\";\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print\n//\n//   Value of: IsEven(Fib(6))\n//     Actual: true (8 is even)\n//   Expected: false\n//\n// NB: Predicates that support negative Boolean assertions have reduced\n// performance in positive ones so be careful not to use them in tests\n// that have lots (tens of thousands) of positive Boolean assertions.\n//\n// To use this class with EXPECT_PRED_FORMAT assertions such as:\n//\n//   // Verifies that Foo() returns an even number.\n//   EXPECT_PRED_FORMAT1(IsEven, Foo());\n//\n// you need to define:\n//\n//   testing::AssertionResult IsEven(const char* expr, int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure()\n//         << \"Expected: \" << expr << \" is even\\n  Actual: it's \" << n;\n//   }\n//\n// If Foo() returns 5, you will see the following message:\n//\n//   Expected: Foo() is even\n//     Actual: it's 5\n\nclass GTEST_API_ AssertionResult {\n public:\n  // Copy constructor.\n  // Used in EXPECT_TRUE/FALSE(assertion_result).\n  AssertionResult(const AssertionResult& other);\n\n// C4800 is a level 3 warning in Visual Studio 2015 and earlier.\n// This warning is not emitted in Visual Studio 2017.\n// This warning is off by default starting in Visual Studio 2019 but can be\n// enabled with command-line options.\n#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)\n#endif\n\n  // Used in the EXPECT_TRUE/FALSE(bool_expression).\n  //\n  // T must be contextually convertible to bool.\n  //\n  // The second parameter prevents this overload from being considered if\n  // the argument is implicitly convertible to AssertionResult. In that case\n  // we want AssertionResult's copy constructor to be used.\n  template <typename T>\n  explicit AssertionResult(\n      const T& success,\n      typename std::enable_if<\n          !std::is_convertible<T, AssertionResult>::value>::type*\n      /*enabler*/\n      = nullptr)\n      : success_(success) {}\n\n#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n  // Assignment operator.\n  AssertionResult& operator=(AssertionResult other) {\n    swap(other);\n    return *this;\n  }\n\n  // Returns true if and only if the assertion succeeded.\n  operator bool() const { return success_; }  // NOLINT\n\n  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\n  AssertionResult operator!() const;\n\n  // Returns the text streamed into this AssertionResult. Test assertions\n  // use it when they fail (i.e., the predicate's outcome doesn't match the\n  // assertion's expectation). When nothing has been streamed into the\n  // object, returns an empty string.\n  const char* message() const {\n    return message_ != nullptr ? message_->c_str() : \"\";\n  }\n  // Deprecated; please use message() instead.\n  const char* failure_message() const { return message(); }\n\n  // Streams a custom failure message into this object.\n  template <typename T>\n  AssertionResult& operator<<(const T& value) {\n    AppendMessage(Message() << value);\n    return *this;\n  }\n\n  // Allows streaming basic output manipulators such as endl or flush into\n  // this object.\n  AssertionResult& operator<<(\n      ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {\n    AppendMessage(Message() << basic_manipulator);\n    return *this;\n  }\n\n private:\n  // Appends the contents of message to message_.\n  void AppendMessage(const Message& a_message) {\n    if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();\n    message_->append(a_message.GetString().c_str());\n  }\n\n  // Swap the contents of this AssertionResult with other.\n  void swap(AssertionResult& other);\n\n  // Stores result of the assertion predicate.\n  bool success_;\n  // Stores the message describing the condition in case the expectation\n  // construct is not satisfied with the predicate's outcome.\n  // Referenced via a pointer to avoid taking too much stack frame space\n  // with test assertions.\n  std::unique_ptr< ::std::string> message_;\n};\n\n// Makes a successful assertion result.\nGTEST_API_ AssertionResult AssertionSuccess();\n\n// Makes a failed assertion result.\nGTEST_API_ AssertionResult AssertionFailure();\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << msg.\nGTEST_API_ AssertionResult AssertionFailure(const Message& msg);\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-death-test.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the public API for death tests.  It is\n// #included by gtest.h so a user doesn't need to include this\n// directly.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n\n#include \"gtest/internal/gtest-death-test-internal.h\"\n\n// This flag controls the style of death tests.  Valid values are \"threadsafe\",\n// meaning that the death test child process will re-execute the test binary\n// from the start, running only a single death test, or \"fast\",\n// meaning that the child process will execute the test logic immediately\n// after forking.\nGTEST_DECLARE_string_(death_test_style);\n\nnamespace testing {\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nnamespace internal {\n\n// Returns a Boolean value indicating whether the caller is currently\n// executing in the context of the death test child process.  Tools such as\n// Valgrind heap checkers may need this to modify their behavior in death\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\n// implementation of death tests.  User code MUST NOT use it.\nGTEST_API_ bool InDeathTestChild();\n\n}  // namespace internal\n\n// The following macros are useful for writing death tests.\n\n// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is\n// executed:\n//\n//   1. It generates a warning if there is more than one active\n//   thread.  This is because it's safe to fork() or clone() only\n//   when there is a single thread.\n//\n//   2. The parent process clone()s a sub-process and runs the death\n//   test in it; the sub-process exits with code 0 at the end of the\n//   death test, if it hasn't exited already.\n//\n//   3. The parent process waits for the sub-process to terminate.\n//\n//   4. The parent process checks the exit code and error message of\n//   the sub-process.\n//\n// Examples:\n//\n//   ASSERT_DEATH(server.SendMessage(56, \"Hello\"), \"Invalid port number\");\n//   for (int i = 0; i < 5; i++) {\n//     EXPECT_DEATH(server.ProcessRequest(i),\n//                  \"Invalid request .* in ProcessRequest()\")\n//                  << \"Failed to die on request \" << i;\n//   }\n//\n//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), \"Exiting\");\n//\n//   bool KilledBySIGHUP(int exit_code) {\n//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;\n//   }\n//\n//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, \"Hanging up!\");\n//\n// The final parameter to each of these macros is a matcher applied to any data\n// the sub-process wrote to stderr.  For compatibility with existing tests, a\n// bare string is interpreted as a regular expression matcher.\n//\n// On the regular expressions used in death tests:\n//\n//   On POSIX-compliant systems (*nix), we use the <regex.h> library,\n//   which uses the POSIX extended regex syntax.\n//\n//   On other platforms (e.g. Windows or Mac), we only support a simple regex\n//   syntax implemented as part of Google Test.  This limited\n//   implementation should be enough most of the time when writing\n//   death tests; though it lacks many features you can find in PCRE\n//   or POSIX extended regex syntax.  For example, we don't support\n//   union (\"x|y\"), grouping (\"(xy)\"), brackets (\"[xy]\"), and\n//   repetition count (\"x{5,7}\"), among others.\n//\n//   Below is the syntax that we do support.  We chose it to be a\n//   subset of both PCRE and POSIX extended regex, so it's easy to\n//   learn wherever you come from.  In the following: 'A' denotes a\n//   literal character, period (.), or a single \\\\ escape sequence;\n//   'x' and 'y' denote regular expressions; 'm' and 'n' are for\n//   natural numbers.\n//\n//     c     matches any literal character c\n//     \\\\d   matches any decimal digit\n//     \\\\D   matches any character that's not a decimal digit\n//     \\\\f   matches \\f\n//     \\\\n   matches \\n\n//     \\\\r   matches \\r\n//     \\\\s   matches any ASCII whitespace, including \\n\n//     \\\\S   matches any character that's not a whitespace\n//     \\\\t   matches \\t\n//     \\\\v   matches \\v\n//     \\\\w   matches any letter, _, or decimal digit\n//     \\\\W   matches any character that \\\\w doesn't match\n//     \\\\c   matches any literal character c, which must be a punctuation\n//     .     matches any single character except \\n\n//     A?    matches 0 or 1 occurrences of A\n//     A*    matches 0 or many occurrences of A\n//     A+    matches 1 or many occurrences of A\n//     ^     matches the beginning of a string (not that of each line)\n//     $     matches the end of a string (not that of each line)\n//     xy    matches x followed by y\n//\n//   If you accidentally use PCRE or POSIX extended regex features\n//   not implemented by us, you will get a run-time failure.  In that\n//   case, please try to rewrite your regular expression within the\n//   above syntax.\n//\n//   This implementation is *not* meant to be as highly tuned or robust\n//   as a compiled regex library, but should perform well enough for a\n//   death test, which already incurs significant overhead by launching\n//   a child process.\n//\n// Known caveats:\n//\n//   A \"threadsafe\" style death test obtains the path to the test\n//   program from argv[0] and re-executes it in the sub-process.  For\n//   simplicity, the current implementation doesn't search the PATH\n//   when launching the sub-process.  This means that the user must\n//   invoke the test program via a path that contains at least one\n//   path separator (e.g. path/to/foo_test and\n//   /absolute/path/to/bar_test are fine, but foo_test is not).  This\n//   is rarely a problem as people usually don't put the test binary\n//   directory in PATH.\n//\n\n// Asserts that a given `statement` causes the program to exit, with an\n// integer exit status that satisfies `predicate`, and emitting error output\n// that matches `matcher`.\n#define ASSERT_EXIT(statement, predicate, matcher) \\\n  GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)\n\n// Like `ASSERT_EXIT`, but continues on to successive tests in the\n// test suite, if any:\n#define EXPECT_EXIT(statement, predicate, matcher) \\\n  GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)\n\n// Asserts that a given `statement` causes the program to exit, either by\n// explicitly exiting with a nonzero exit code or being killed by a\n// signal, and emitting error output that matches `matcher`.\n#define ASSERT_DEATH(statement, matcher) \\\n  ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)\n\n// Like `ASSERT_DEATH`, but continues on to successive tests in the\n// test suite, if any:\n#define EXPECT_DEATH(statement, matcher) \\\n  EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)\n\n// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:\n\n// Tests that an exit code describes a normal exit with a given exit code.\nclass GTEST_API_ ExitedWithCode {\n public:\n  explicit ExitedWithCode(int exit_code);\n  ExitedWithCode(const ExitedWithCode&) = default;\n  void operator=(const ExitedWithCode& other) = delete;\n  bool operator()(int exit_status) const;\n\n private:\n  const int exit_code_;\n};\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// Tests that an exit code describes an exit due to termination by a\n// given signal.\nclass GTEST_API_ KilledBySignal {\n public:\n  explicit KilledBySignal(int signum);\n  bool operator()(int exit_status) const;\n\n private:\n  const int signum_;\n};\n#endif  // !GTEST_OS_WINDOWS\n\n// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.\n// The death testing framework causes this to have interesting semantics,\n// since the sideeffects of the call are only visible in opt mode, and not\n// in debug mode.\n//\n// In practice, this can be used to test functions that utilize the\n// LOG(DFATAL) macro using the following style:\n//\n// int DieInDebugOr12(int* sideeffect) {\n//   if (sideeffect) {\n//     *sideeffect = 12;\n//   }\n//   LOG(DFATAL) << \"death\";\n//   return 12;\n// }\n//\n// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {\n//   int sideeffect = 0;\n//   // Only asserts in dbg.\n//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), \"death\");\n//\n// #ifdef NDEBUG\n//   // opt-mode has sideeffect visible.\n//   EXPECT_EQ(12, sideeffect);\n// #else\n//   // dbg-mode no visible sideeffect.\n//   EXPECT_EQ(0, sideeffect);\n// #endif\n// }\n//\n// This will assert that DieInDebugReturn12InOpt() crashes in debug\n// mode, usually due to a DCHECK or LOG(DFATAL), but returns the\n// appropriate fallback value (12 in this case) in opt mode. If you\n// need to test that a function has appropriate side-effects in opt\n// mode, include assertions against the side-effects.  A general\n// pattern for this is:\n//\n// EXPECT_DEBUG_DEATH({\n//   // Side-effects here will have an effect after this statement in\n//   // opt mode, but none in debug mode.\n//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));\n// }, \"death\");\n//\n#ifdef NDEBUG\n\n#define EXPECT_DEBUG_DEATH(statement, regex) \\\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\n\n#define ASSERT_DEBUG_DEATH(statement, regex) \\\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\n\n#else\n\n#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)\n\n#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)\n\n#endif  // NDEBUG for EXPECT_DEBUG_DEATH\n#endif  // GTEST_HAS_DEATH_TEST\n\n// This macro is used for implementing macros such as\n// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where\n// death tests are not supported. Those macros must compile on such systems\n// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters\n// on systems that support death tests. This allows one to write such a macro on\n// a system that does not support death tests and be sure that it will compile\n// on a death-test supporting system. It is exposed publicly so that systems\n// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST\n// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and\n// ASSERT_DEATH_IF_SUPPORTED.\n//\n// Parameters:\n//   statement -  A statement that a macro such as EXPECT_DEATH would test\n//                for program termination. This macro has to make sure this\n//                statement is compiled but not executed, to ensure that\n//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain\n//                parameter if and only if EXPECT_DEATH compiles with it.\n//   regex_or_matcher -  A regex that a macro such as EXPECT_DEATH would use\n//                to test the output of statement.  This parameter has to be\n//                compiled but not evaluated by this macro, to ensure that\n//                this macro only accepts expressions that a macro such as\n//                EXPECT_DEATH would accept.\n//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED\n//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.\n//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not\n//                compile inside functions where ASSERT_DEATH doesn't\n//                compile.\n//\n//  The branch that has an always false condition is used to ensure that\n//  statement and regex are compiled (and thus syntactically correct) but\n//  never executed. The unreachable code macro protects the terminator\n//  statement from generating an 'unreachable code' warning in case\n//  statement unconditionally returns or throws. The Message constructor at\n//  the end allows the syntax of streaming additional messages into the\n//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.\n#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator)  \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                \\\n  if (::testing::internal::AlwaysTrue()) {                                     \\\n    GTEST_LOG_(WARNING) << \"Death tests are not supported on this platform.\\n\" \\\n                        << \"Statement '\" #statement \"' cannot be verified.\";   \\\n  } else if (::testing::internal::AlwaysFalse()) {                             \\\n    ::testing::internal::MakeDeathTestMatcher(regex_or_matcher);               \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);                 \\\n    terminator;                                                                \\\n  } else                                                                       \\\n    ::testing::Message()\n\n// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and\n// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if\n// death tests are supported; otherwise they just issue a warning.  This is\n// useful when you are combining death test assertions with normal test\n// assertions in one test.\n#ifdef GTEST_HAS_DEATH_TEST\n#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n  EXPECT_DEATH(statement, regex)\n#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n  ASSERT_DEATH(statement, regex)\n#else\n#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n  GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )\n#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n  GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)\n#endif\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-matchers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements just enough of the matcher interface to allow\n// EXPECT_DEATH and friends to accept a matcher argument.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n\n#include <atomic>\n#include <functional>\n#include <memory>\n#include <ostream>\n#include <string>\n#include <type_traits>\n\n#include \"gtest/gtest-printers.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n// MSVC warning C5046 is new as of VS2017 version 15.8.\n#if defined(_MSC_VER) && _MSC_VER >= 1915\n#define GTEST_MAYBE_5046_ 5046\n#else\n#define GTEST_MAYBE_5046_\n#endif\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by\n                              clients of class B */\n    /* Symbol involving type with internal linkage not defined */)\n\nnamespace testing {\n\n// To implement a matcher Foo for type T, define:\n//   1. a class FooMatcherMatcher that implements the matcher interface:\n//     using is_gtest_matcher = void;\n//     bool MatchAndExplain(const T&, std::ostream*);\n//       (MatchResultListener* can also be used instead of std::ostream*)\n//     void DescribeTo(std::ostream*);\n//     void DescribeNegationTo(std::ostream*);\n//\n//   2. a factory function that creates a Matcher<T> object from a\n//      FooMatcherMatcher.\n\nclass MatchResultListener {\n public:\n  // Creates a listener object with the given underlying ostream.  The\n  // listener does not own the ostream, and does not dereference it\n  // in the constructor or destructor.\n  explicit MatchResultListener(::std::ostream* os) : stream_(os) {}\n  virtual ~MatchResultListener() = 0;  // Makes this class abstract.\n\n  // Streams x to the underlying ostream; does nothing if the ostream\n  // is NULL.\n  template <typename T>\n  MatchResultListener& operator<<(const T& x) {\n    if (stream_ != nullptr) *stream_ << x;\n    return *this;\n  }\n\n  // Returns the underlying ostream.\n  ::std::ostream* stream() { return stream_; }\n\n  // Returns true if and only if the listener is interested in an explanation\n  // of the match result.  A matcher's MatchAndExplain() method can use\n  // this information to avoid generating the explanation when no one\n  // intends to hear it.\n  bool IsInterested() const { return stream_ != nullptr; }\n\n private:\n  ::std::ostream* const stream_;\n\n  MatchResultListener(const MatchResultListener&) = delete;\n  MatchResultListener& operator=(const MatchResultListener&) = delete;\n};\n\ninline MatchResultListener::~MatchResultListener() = default;\n\n// An instance of a subclass of this knows how to describe itself as a\n// matcher.\nclass GTEST_API_ MatcherDescriberInterface {\n public:\n  virtual ~MatcherDescriberInterface() = default;\n\n  // Describes this matcher to an ostream.  The function should print\n  // a verb phrase that describes the property a value matching this\n  // matcher should have.  The subject of the verb phrase is the value\n  // being matched.  For example, the DescribeTo() method of the Gt(7)\n  // matcher prints \"is greater than 7\".\n  virtual void DescribeTo(::std::ostream* os) const = 0;\n\n  // Describes the negation of this matcher to an ostream.  For\n  // example, if the description of this matcher is \"is greater than\n  // 7\", the negated description could be \"is not greater than 7\".\n  // You are not required to override this when implementing\n  // MatcherInterface, but it is highly advised so that your matcher\n  // can produce good error messages.\n  virtual void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"not (\";\n    DescribeTo(os);\n    *os << \")\";\n  }\n};\n\n// The implementation of a matcher.\ntemplate <typename T>\nclass MatcherInterface : public MatcherDescriberInterface {\n public:\n  // Returns true if and only if the matcher matches x; also explains the\n  // match result to 'listener' if necessary (see the next paragraph), in\n  // the form of a non-restrictive relative clause (\"which ...\",\n  // \"whose ...\", etc) that describes x.  For example, the\n  // MatchAndExplain() method of the Pointee(...) matcher should\n  // generate an explanation like \"which points to ...\".\n  //\n  // Implementations of MatchAndExplain() should add an explanation of\n  // the match result *if and only if* they can provide additional\n  // information that's not already present (or not obvious) in the\n  // print-out of x and the matcher's description.  Whether the match\n  // succeeds is not a factor in deciding whether an explanation is\n  // needed, as sometimes the caller needs to print a failure message\n  // when the match succeeds (e.g. when the matcher is used inside\n  // Not()).\n  //\n  // For example, a \"has at least 10 elements\" matcher should explain\n  // what the actual element count is, regardless of the match result,\n  // as it is useful information to the reader; on the other hand, an\n  // \"is empty\" matcher probably only needs to explain what the actual\n  // size is when the match fails, as it's redundant to say that the\n  // size is 0 when the value is already known to be empty.\n  //\n  // You should override this method when defining a new matcher.\n  //\n  // It's the responsibility of the caller (Google Test) to guarantee\n  // that 'listener' is not NULL.  This helps to simplify a matcher's\n  // implementation when it doesn't care about the performance, as it\n  // can talk to 'listener' without checking its validity first.\n  // However, in order to implement dummy listeners efficiently,\n  // listener->stream() may be NULL.\n  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;\n\n  // Inherits these methods from MatcherDescriberInterface:\n  //   virtual void DescribeTo(::std::ostream* os) const = 0;\n  //   virtual void DescribeNegationTo(::std::ostream* os) const;\n};\n\nnamespace internal {\n\n// A match result listener that ignores the explanation.\nclass DummyMatchResultListener : public MatchResultListener {\n public:\n  DummyMatchResultListener() : MatchResultListener(nullptr) {}\n\n private:\n  DummyMatchResultListener(const DummyMatchResultListener&) = delete;\n  DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;\n};\n\n// A match result listener that forwards the explanation to a given\n// ostream.  The difference between this and MatchResultListener is\n// that the former is concrete.\nclass StreamMatchResultListener : public MatchResultListener {\n public:\n  explicit StreamMatchResultListener(::std::ostream* os)\n      : MatchResultListener(os) {}\n\n private:\n  StreamMatchResultListener(const StreamMatchResultListener&) = delete;\n  StreamMatchResultListener& operator=(const StreamMatchResultListener&) =\n      delete;\n};\n\nstruct SharedPayloadBase {\n  std::atomic<int> ref{1};\n  void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }\n  bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }\n};\n\ntemplate <typename T>\nstruct SharedPayload : SharedPayloadBase {\n  explicit SharedPayload(const T& v) : value(v) {}\n  explicit SharedPayload(T&& v) : value(std::move(v)) {}\n\n  static void Destroy(SharedPayloadBase* shared) {\n    delete static_cast<SharedPayload*>(shared);\n  }\n\n  T value;\n};\n\n// An internal class for implementing Matcher<T>, which will derive\n// from it.  We put functionalities common to all Matcher<T>\n// specializations here to avoid code duplication.\ntemplate <typename T>\nclass MatcherBase : private MatcherDescriberInterface {\n public:\n  // Returns true if and only if the matcher matches x; also explains the\n  // match result to 'listener'.\n  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {\n    GTEST_CHECK_(vtable_ != nullptr);\n    return vtable_->match_and_explain(*this, x, listener);\n  }\n\n  // Returns true if and only if this matcher matches x.\n  bool Matches(const T& x) const {\n    DummyMatchResultListener dummy;\n    return MatchAndExplain(x, &dummy);\n  }\n\n  // Describes this matcher to an ostream.\n  void DescribeTo(::std::ostream* os) const final {\n    GTEST_CHECK_(vtable_ != nullptr);\n    vtable_->describe(*this, os, false);\n  }\n\n  // Describes the negation of this matcher to an ostream.\n  void DescribeNegationTo(::std::ostream* os) const final {\n    GTEST_CHECK_(vtable_ != nullptr);\n    vtable_->describe(*this, os, true);\n  }\n\n  // Explains why x matches, or doesn't match, the matcher.\n  void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {\n    StreamMatchResultListener listener(os);\n    MatchAndExplain(x, &listener);\n  }\n\n  // Returns the describer for this matcher object; retains ownership\n  // of the describer, which is only guaranteed to be alive when\n  // this matcher object is alive.\n  const MatcherDescriberInterface* GetDescriber() const {\n    if (vtable_ == nullptr) return nullptr;\n    return vtable_->get_describer(*this);\n  }\n\n protected:\n  MatcherBase() : vtable_(nullptr), buffer_() {}\n\n  // Constructs a matcher from its implementation.\n  template <typename U>\n  explicit MatcherBase(const MatcherInterface<U>* impl)\n      : vtable_(nullptr), buffer_() {\n    Init(impl);\n  }\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  MatcherBase(M&& m) : vtable_(nullptr), buffer_() {  // NOLINT\n    Init(std::forward<M>(m));\n  }\n\n  MatcherBase(const MatcherBase& other)\n      : vtable_(other.vtable_), buffer_(other.buffer_) {\n    if (IsShared()) buffer_.shared->Ref();\n  }\n\n  MatcherBase& operator=(const MatcherBase& other) {\n    if (this == &other) return *this;\n    Destroy();\n    vtable_ = other.vtable_;\n    buffer_ = other.buffer_;\n    if (IsShared()) buffer_.shared->Ref();\n    return *this;\n  }\n\n  MatcherBase(MatcherBase&& other)\n      : vtable_(other.vtable_), buffer_(other.buffer_) {\n    other.vtable_ = nullptr;\n  }\n\n  MatcherBase& operator=(MatcherBase&& other) {\n    if (this == &other) return *this;\n    Destroy();\n    vtable_ = other.vtable_;\n    buffer_ = other.buffer_;\n    other.vtable_ = nullptr;\n    return *this;\n  }\n\n  ~MatcherBase() override { Destroy(); }\n\n private:\n  struct VTable {\n    bool (*match_and_explain)(const MatcherBase&, const T&,\n                              MatchResultListener*);\n    void (*describe)(const MatcherBase&, std::ostream*, bool negation);\n    // Returns the captured object if it implements the interface, otherwise\n    // returns the MatcherBase itself.\n    const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);\n    // Called on shared instances when the reference count reaches 0.\n    void (*shared_destroy)(SharedPayloadBase*);\n  };\n\n  bool IsShared() const {\n    return vtable_ != nullptr && vtable_->shared_destroy != nullptr;\n  }\n\n  // If the implementation uses a listener, call that.\n  template <typename P>\n  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,\n                                  MatchResultListener* listener)\n      -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {\n    return P::Get(m).MatchAndExplain(value, listener->stream());\n  }\n\n  template <typename P>\n  static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,\n                                  MatchResultListener* listener)\n      -> decltype(P::Get(m).MatchAndExplain(value, listener)) {\n    return P::Get(m).MatchAndExplain(value, listener);\n  }\n\n  template <typename P>\n  static void DescribeImpl(const MatcherBase& m, std::ostream* os,\n                           bool negation) {\n    if (negation) {\n      P::Get(m).DescribeNegationTo(os);\n    } else {\n      P::Get(m).DescribeTo(os);\n    }\n  }\n\n  template <typename P>\n  static const MatcherDescriberInterface* GetDescriberImpl(\n      const MatcherBase& m) {\n    // If the impl is a MatcherDescriberInterface, then return it.\n    // Otherwise use MatcherBase itself.\n    // This allows us to implement the GetDescriber() function without support\n    // from the impl, but some users really want to get their impl back when\n    // they call GetDescriber().\n    // We use std::get on a tuple as a workaround of not having `if constexpr`.\n    return std::get<(\n        std::is_convertible<decltype(&P::Get(m)),\n                            const MatcherDescriberInterface*>::value\n            ? 1\n            : 0)>(std::make_tuple(&m, &P::Get(m)));\n  }\n\n  template <typename P>\n  const VTable* GetVTable() {\n    static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,\n                                       &DescribeImpl<P>, &GetDescriberImpl<P>,\n                                       P::shared_destroy};\n    return &kVTable;\n  }\n\n  union Buffer {\n    // Add some types to give Buffer some common alignment/size use cases.\n    void* ptr;\n    double d;\n    int64_t i;\n    // And add one for the out-of-line cases.\n    SharedPayloadBase* shared;\n  };\n\n  void Destroy() {\n    if (IsShared() && buffer_.shared->Unref()) {\n      vtable_->shared_destroy(buffer_.shared);\n    }\n  }\n\n  template <typename M>\n  static constexpr bool IsInlined() {\n    return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&\n           std::is_trivially_copy_constructible<M>::value &&\n           std::is_trivially_destructible<M>::value;\n  }\n\n  template <typename M, bool = MatcherBase::IsInlined<M>()>\n  struct ValuePolicy {\n    static const M& Get(const MatcherBase& m) {\n      // When inlined along with Init, need to be explicit to avoid violating\n      // strict aliasing rules.\n      const M* ptr =\n          static_cast<const M*>(static_cast<const void*>(&m.buffer_));\n      return *ptr;\n    }\n    static void Init(MatcherBase& m, M impl) {\n      ::new (static_cast<void*>(&m.buffer_)) M(impl);\n    }\n    static constexpr auto shared_destroy = nullptr;\n  };\n\n  template <typename M>\n  struct ValuePolicy<M, false> {\n    using Shared = SharedPayload<M>;\n    static const M& Get(const MatcherBase& m) {\n      return static_cast<Shared*>(m.buffer_.shared)->value;\n    }\n    template <typename Arg>\n    static void Init(MatcherBase& m, Arg&& arg) {\n      m.buffer_.shared = new Shared(std::forward<Arg>(arg));\n    }\n    static constexpr auto shared_destroy = &Shared::Destroy;\n  };\n\n  template <typename U, bool B>\n  struct ValuePolicy<const MatcherInterface<U>*, B> {\n    using M = const MatcherInterface<U>;\n    using Shared = SharedPayload<std::unique_ptr<M>>;\n    static const M& Get(const MatcherBase& m) {\n      return *static_cast<Shared*>(m.buffer_.shared)->value;\n    }\n    static void Init(MatcherBase& m, M* impl) {\n      m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));\n    }\n\n    static constexpr auto shared_destroy = &Shared::Destroy;\n  };\n\n  template <typename M>\n  void Init(M&& m) {\n    using MM = typename std::decay<M>::type;\n    using Policy = ValuePolicy<MM>;\n    vtable_ = GetVTable<Policy>();\n    Policy::Init(*this, std::forward<M>(m));\n  }\n\n  const VTable* vtable_;\n  Buffer buffer_;\n};\n\n}  // namespace internal\n\n// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)\n// object that can check whether a value of type T matches.  The\n// implementation of Matcher<T> is just a std::shared_ptr to const\n// MatcherInterface<T>.  Don't inherit from Matcher!\ntemplate <typename T>\nclass Matcher : public internal::MatcherBase<T> {\n public:\n  // Constructs a null matcher.  Needed for storing Matcher objects in STL\n  // containers.  A default-constructed matcher is not yet initialized.  You\n  // cannot use it until a valid value has been assigned to it.\n  explicit Matcher() {}  // NOLINT\n\n  // Constructs a matcher from its implementation.\n  explicit Matcher(const MatcherInterface<const T&>* impl)\n      : internal::MatcherBase<T>(impl) {}\n\n  template <typename U>\n  explicit Matcher(\n      const MatcherInterface<U>* impl,\n      typename std::enable_if<!std::is_same<U, const U&>::value>::type* =\n          nullptr)\n      : internal::MatcherBase<T>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}  // NOLINT\n\n  // Implicit constructor here allows people to write\n  // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes\n  Matcher(T value);  // NOLINT\n};\n\n// The following two specializations allow the user to write str\n// instead of Eq(str) and \"foo\" instead of Eq(\"foo\") when a std::string\n// matcher is expected.\ntemplate <>\nclass GTEST_API_ Matcher<const std::string&>\n    : public internal::MatcherBase<const std::string&> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const std::string&>* impl)\n      : internal::MatcherBase<const std::string&>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n};\n\ntemplate <>\nclass GTEST_API_ Matcher<std::string>\n    : public internal::MatcherBase<std::string> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const std::string&>* impl)\n      : internal::MatcherBase<std::string>(impl) {}\n  explicit Matcher(const MatcherInterface<std::string>* impl)\n      : internal::MatcherBase<std::string>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<std::string>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n};\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// The following two specializations allow the user to write str\n// instead of Eq(str) and \"foo\" instead of Eq(\"foo\") when a absl::string_view\n// matcher is expected.\ntemplate <>\nclass GTEST_API_ Matcher<const internal::StringView&>\n    : public internal::MatcherBase<const internal::StringView&> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)\n      : internal::MatcherBase<const internal::StringView&>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {\n  }\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n\n  // Allows the user to pass absl::string_views or std::string_views directly.\n  Matcher(internal::StringView s);  // NOLINT\n};\n\ntemplate <>\nclass GTEST_API_ Matcher<internal::StringView>\n    : public internal::MatcherBase<internal::StringView> {\n public:\n  Matcher() = default;\n\n  explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)\n      : internal::MatcherBase<internal::StringView>(impl) {}\n  explicit Matcher(const MatcherInterface<internal::StringView>* impl)\n      : internal::MatcherBase<internal::StringView>(impl) {}\n\n  template <typename M, typename = typename std::remove_reference<\n                            M>::type::is_gtest_matcher>\n  Matcher(M&& m)  // NOLINT\n      : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}\n\n  // Allows the user to write str instead of Eq(str) sometimes, where\n  // str is a std::string object.\n  Matcher(const std::string& s);  // NOLINT\n\n  // Allows the user to write \"foo\" instead of Eq(\"foo\") sometimes.\n  Matcher(const char* s);  // NOLINT\n\n  // Allows the user to pass absl::string_views or std::string_views directly.\n  Matcher(internal::StringView s);  // NOLINT\n};\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n// Prints a matcher in a human-readable format.\ntemplate <typename T>\nstd::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {\n  matcher.DescribeTo(&os);\n  return os;\n}\n\n// The PolymorphicMatcher class template makes it easy to implement a\n// polymorphic matcher (i.e. a matcher that can match values of more\n// than one type, e.g. Eq(n) and NotNull()).\n//\n// To define a polymorphic matcher, a user should provide an Impl\n// class that has a DescribeTo() method and a DescribeNegationTo()\n// method, and define a member function (or member function template)\n//\n//   bool MatchAndExplain(const Value& value,\n//                        MatchResultListener* listener) const;\n//\n// See the definition of NotNull() for a complete example.\ntemplate <class Impl>\nclass PolymorphicMatcher {\n public:\n  explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}\n\n  // Returns a mutable reference to the underlying matcher\n  // implementation object.\n  Impl& mutable_impl() { return impl_; }\n\n  // Returns an immutable reference to the underlying matcher\n  // implementation object.\n  const Impl& impl() const { return impl_; }\n\n  template <typename T>\n  operator Matcher<T>() const {\n    return Matcher<T>(new MonomorphicImpl<const T&>(impl_));\n  }\n\n private:\n  template <typename T>\n  class MonomorphicImpl : public MatcherInterface<T> {\n   public:\n    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}\n\n    void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }\n\n    void DescribeNegationTo(::std::ostream* os) const override {\n      impl_.DescribeNegationTo(os);\n    }\n\n    bool MatchAndExplain(T x, MatchResultListener* listener) const override {\n      return impl_.MatchAndExplain(x, listener);\n    }\n\n   private:\n    const Impl impl_;\n  };\n\n  Impl impl_;\n};\n\n// Creates a matcher from its implementation.\n// DEPRECATED: Especially in the generic code, prefer:\n//   Matcher<T>(new MyMatcherImpl<const T&>(...));\n//\n// MakeMatcher may create a Matcher that accepts its argument by value, which\n// leads to unnecessary copies & lack of support for non-copyable types.\ntemplate <typename T>\ninline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {\n  return Matcher<T>(impl);\n}\n\n// Creates a polymorphic matcher from its implementation.  This is\n// easier to use than the PolymorphicMatcher<Impl> constructor as it\n// doesn't require you to explicitly write the template argument, e.g.\n//\n//   MakePolymorphicMatcher(foo);\n// vs\n//   PolymorphicMatcher<TypeOfFoo>(foo);\ntemplate <class Impl>\ninline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {\n  return PolymorphicMatcher<Impl>(impl);\n}\n\nnamespace internal {\n// Implements a matcher that compares a given value with a\n// pre-supplied value using one of the ==, <=, <, etc, operators.  The\n// two values being compared don't have to have the same type.\n//\n// The matcher defined here is polymorphic (for example, Eq(5) can be\n// used to match an int, a short, a double, etc).  Therefore we use\n// a template type conversion operator in the implementation.\n//\n// The following template definition assumes that the Rhs parameter is\n// a \"bare\" type (i.e. neither 'const T' nor 'T&').\ntemplate <typename D, typename Rhs, typename Op>\nclass ComparisonBase {\n public:\n  explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}\n\n  using is_gtest_matcher = void;\n\n  template <typename Lhs>\n  bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {\n    return Op()(lhs, Unwrap(rhs_));\n  }\n  void DescribeTo(std::ostream* os) const {\n    *os << D::Desc() << \" \";\n    UniversalPrint(Unwrap(rhs_), os);\n  }\n  void DescribeNegationTo(std::ostream* os) const {\n    *os << D::NegatedDesc() << \" \";\n    UniversalPrint(Unwrap(rhs_), os);\n  }\n\n private:\n  template <typename T>\n  static const T& Unwrap(const T& v) {\n    return v;\n  }\n  template <typename T>\n  static const T& Unwrap(std::reference_wrapper<T> v) {\n    return v;\n  }\n\n  Rhs rhs_;\n};\n\ntemplate <typename Rhs>\nclass EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {\n public:\n  explicit EqMatcher(const Rhs& rhs)\n      : ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}\n  static const char* Desc() { return \"is equal to\"; }\n  static const char* NegatedDesc() { return \"isn't equal to\"; }\n};\ntemplate <typename Rhs>\nclass NeMatcher\n    : public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {\n public:\n  explicit NeMatcher(const Rhs& rhs)\n      : ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}\n  static const char* Desc() { return \"isn't equal to\"; }\n  static const char* NegatedDesc() { return \"is equal to\"; }\n};\ntemplate <typename Rhs>\nclass LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {\n public:\n  explicit LtMatcher(const Rhs& rhs)\n      : ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}\n  static const char* Desc() { return \"is <\"; }\n  static const char* NegatedDesc() { return \"isn't <\"; }\n};\ntemplate <typename Rhs>\nclass GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {\n public:\n  explicit GtMatcher(const Rhs& rhs)\n      : ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}\n  static const char* Desc() { return \"is >\"; }\n  static const char* NegatedDesc() { return \"isn't >\"; }\n};\ntemplate <typename Rhs>\nclass LeMatcher\n    : public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {\n public:\n  explicit LeMatcher(const Rhs& rhs)\n      : ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}\n  static const char* Desc() { return \"is <=\"; }\n  static const char* NegatedDesc() { return \"isn't <=\"; }\n};\ntemplate <typename Rhs>\nclass GeMatcher\n    : public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {\n public:\n  explicit GeMatcher(const Rhs& rhs)\n      : ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}\n  static const char* Desc() { return \"is >=\"; }\n  static const char* NegatedDesc() { return \"isn't >=\"; }\n};\n\ntemplate <typename T, typename = typename std::enable_if<\n                          std::is_constructible<std::string, T>::value>::type>\nusing StringLike = T;\n\n// Implements polymorphic matchers MatchesRegex(regex) and\n// ContainsRegex(regex), which can be used as a Matcher<T> as long as\n// T can be converted to a string.\nclass MatchesRegexMatcher {\n public:\n  MatchesRegexMatcher(const RE* regex, bool full_match)\n      : regex_(regex), full_match_(full_match) {}\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  bool MatchAndExplain(const internal::StringView& s,\n                       MatchResultListener* listener) const {\n    return MatchAndExplain(std::string(s), listener);\n  }\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n  // Accepts pointer types, particularly:\n  //   const char*\n  //   char*\n  //   const wchar_t*\n  //   wchar_t*\n  template <typename CharType>\n  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {\n    return s != nullptr && MatchAndExplain(std::string(s), listener);\n  }\n\n  // Matches anything that can convert to std::string.\n  //\n  // This is a template, not just a plain function with const std::string&,\n  // because absl::string_view has some interfering non-explicit constructors.\n  template <class MatcheeStringType>\n  bool MatchAndExplain(const MatcheeStringType& s,\n                       MatchResultListener* /* listener */) const {\n    const std::string s2(s);\n    return full_match_ ? RE::FullMatch(s2, *regex_)\n                       : RE::PartialMatch(s2, *regex_);\n  }\n\n  void DescribeTo(::std::ostream* os) const {\n    *os << (full_match_ ? \"matches\" : \"contains\") << \" regular expression \";\n    UniversalPrinter<std::string>::Print(regex_->pattern(), os);\n  }\n\n  void DescribeNegationTo(::std::ostream* os) const {\n    *os << \"doesn't \" << (full_match_ ? \"match\" : \"contain\")\n        << \" regular expression \";\n    UniversalPrinter<std::string>::Print(regex_->pattern(), os);\n  }\n\n private:\n  const std::shared_ptr<const RE> regex_;\n  const bool full_match_;\n};\n}  // namespace internal\n\n// Matches a string that fully matches regular expression 'regex'.\n// The matcher takes ownership of 'regex'.\ninline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(\n    const internal::RE* regex) {\n  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));\n}\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(\n    const internal::StringLike<T>& regex) {\n  return MatchesRegex(new internal::RE(std::string(regex)));\n}\n\n// Matches a string that contains regular expression 'regex'.\n// The matcher takes ownership of 'regex'.\ninline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(\n    const internal::RE* regex) {\n  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));\n}\ntemplate <typename T = std::string>\nPolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(\n    const internal::StringLike<T>& regex) {\n  return ContainsRegex(new internal::RE(std::string(regex)));\n}\n\n// Creates a polymorphic matcher that matches anything equal to x.\n// Note: if the parameter of Eq() were declared as const T&, Eq(\"foo\")\n// wouldn't compile.\ntemplate <typename T>\ninline internal::EqMatcher<T> Eq(T x) {\n  return internal::EqMatcher<T>(x);\n}\n\n// Constructs a Matcher<T> from a 'value' of type T.  The constructed\n// matcher matches any value that's equal to 'value'.\ntemplate <typename T>\nMatcher<T>::Matcher(T value) {\n  *this = Eq(value);\n}\n\n// Creates a monomorphic matcher that matches anything with type Lhs\n// and equal to rhs.  A user may need to use this instead of Eq(...)\n// in order to resolve an overloading ambiguity.\n//\n// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))\n// or Matcher<T>(x), but more readable than the latter.\n//\n// We could define similar monomorphic matchers for other comparison\n// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do\n// it yet as those are used much less than Eq() in practice.  A user\n// can always write Matcher<T>(Lt(5)) to be explicit about the type,\n// for example.\ntemplate <typename Lhs, typename Rhs>\ninline Matcher<Lhs> TypedEq(const Rhs& rhs) {\n  return Eq(rhs);\n}\n\n// Creates a polymorphic matcher that matches anything >= x.\ntemplate <typename Rhs>\ninline internal::GeMatcher<Rhs> Ge(Rhs x) {\n  return internal::GeMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything > x.\ntemplate <typename Rhs>\ninline internal::GtMatcher<Rhs> Gt(Rhs x) {\n  return internal::GtMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything <= x.\ntemplate <typename Rhs>\ninline internal::LeMatcher<Rhs> Le(Rhs x) {\n  return internal::LeMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything < x.\ntemplate <typename Rhs>\ninline internal::LtMatcher<Rhs> Lt(Rhs x) {\n  return internal::LtMatcher<Rhs>(x);\n}\n\n// Creates a polymorphic matcher that matches anything != x.\ntemplate <typename Rhs>\ninline internal::NeMatcher<Rhs> Ne(Rhs x) {\n  return internal::NeMatcher<Rhs>(x);\n}\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-message.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the Message class.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n\n#include <limits>\n#include <memory>\n#include <ostream>\n#include <sstream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_HAS_ABSL\n#include <type_traits>\n\n#include \"absl/strings/has_absl_stringify.h\"\n#include \"absl/strings/str_cat.h\"\n#endif  // GTEST_HAS_ABSL\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Ensures that there is at least one operator<< in the global namespace.\n// See Message& operator<<(...) below for why.\nvoid operator<<(const testing::internal::Secret&, int);\n\nnamespace testing {\n\n// The Message class works like an ostream repeater.\n//\n// Typical usage:\n//\n//   1. You stream a bunch of values to a Message object.\n//      It will remember the text in a stringstream.\n//   2. Then you stream the Message object to an ostream.\n//      This causes the text in the Message to be streamed\n//      to the ostream.\n//\n// For example;\n//\n//   testing::Message foo;\n//   foo << 1 << \" != \" << 2;\n//   std::cout << foo;\n//\n// will print \"1 != 2\".\n//\n// Message is not intended to be inherited from.  In particular, its\n// destructor is not virtual.\n//\n// Note that stringstream behaves differently in gcc and in MSVC.  You\n// can stream a NULL char pointer to it in the former, but not in the\n// latter (it causes an access violation if you do).  The Message\n// class hides this difference by treating a NULL char pointer as\n// \"(null)\".\nclass GTEST_API_ Message {\n private:\n  // The type of basic IO manipulators (endl, ends, and flush) for\n  // narrow streams.\n  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);\n\n public:\n  // Constructs an empty Message.\n  Message();\n\n  // Copy constructor.\n  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT\n    *ss_ << msg.GetString();\n  }\n\n  // Constructs a Message from a C-string.\n  explicit Message(const char* str) : ss_(new ::std::stringstream) {\n    *ss_ << str;\n  }\n\n  // Streams a non-pointer value to this object. If building a version of\n  // GoogleTest with ABSL, this overload is only enabled if the value does not\n  // have an AbslStringify definition.\n  template <\n      typename T\n#ifdef GTEST_HAS_ABSL\n      ,\n      typename std::enable_if<!absl::HasAbslStringify<T>::value,  // NOLINT\n                              int>::type = 0\n#endif  // GTEST_HAS_ABSL\n      >\n  inline Message& operator<<(const T& val) {\n        // Some libraries overload << for STL containers.  These\n    // overloads are defined in the global namespace instead of ::std.\n    //\n    // C++'s symbol lookup rule (i.e. Koenig lookup) says that these\n    // overloads are visible in either the std namespace or the global\n    // namespace, but not other namespaces, including the testing\n    // namespace which Google Test's Message class is in.\n    //\n    // To allow STL containers (and other types that has a << operator\n    // defined in the global namespace) to be used in Google Test\n    // assertions, testing::Message must access the custom << operator\n    // from the global namespace.  With this using declaration,\n    // overloads of << defined in the global namespace and those\n    // visible via Koenig lookup are both exposed in this function.\n    using ::operator<<;\n    *ss_ << val;\n    return *this;\n  }\n\n#ifdef GTEST_HAS_ABSL\n  // Streams a non-pointer value with an AbslStringify definition to this\n  // object.\n  template <typename T,\n            typename std::enable_if<absl::HasAbslStringify<T>::value,  // NOLINT\n                                    int>::type = 0>\n  inline Message& operator<<(const T& val) {\n    // ::operator<< is needed here for a similar reason as with the non-Abseil\n    // version above\n    using ::operator<<;\n    *ss_ << absl::StrCat(val);\n    return *this;\n  }\n#endif  // GTEST_HAS_ABSL\n\n  // Streams a pointer value to this object.\n  //\n  // This function is an overload of the previous one.  When you\n  // stream a pointer to a Message, this definition will be used as it\n  // is more specialized.  (The C++ Standard, section\n  // [temp.func.order].)  If you stream a non-pointer, then the\n  // previous definition will be used.\n  //\n  // The reason for this overload is that streaming a NULL pointer to\n  // ostream is undefined behavior.  Depending on the compiler, you\n  // may get \"0\", \"(nil)\", \"(null)\", or an access violation.  To\n  // ensure consistent result across compilers, we always treat NULL\n  // as \"(null)\".\n  template <typename T>\n  inline Message& operator<<(T* const& pointer) {  // NOLINT\n    if (pointer == nullptr) {\n      *ss_ << \"(null)\";\n    } else {\n      *ss_ << pointer;\n    }\n    return *this;\n  }\n\n  // Since the basic IO manipulators are overloaded for both narrow\n  // and wide streams, we have to provide this specialized definition\n  // of operator <<, even though its body is the same as the\n  // templatized version above.  Without this definition, streaming\n  // endl or other basic IO manipulators to Message will confuse the\n  // compiler.\n  Message& operator<<(BasicNarrowIoManip val) {\n    *ss_ << val;\n    return *this;\n  }\n\n  // Instead of 1/0, we want to see true/false for bool values.\n  Message& operator<<(bool b) { return *this << (b ? \"true\" : \"false\"); }\n\n  // These two overloads allow streaming a wide C string to a Message\n  // using the UTF-8 encoding.\n  Message& operator<<(const wchar_t* wide_c_str);\n  Message& operator<<(wchar_t* wide_c_str);\n\n#if GTEST_HAS_STD_WSTRING\n  // Converts the given wide string to a narrow string using the UTF-8\n  // encoding, and streams the result to this Message object.\n  Message& operator<<(const ::std::wstring& wstr);\n#endif  // GTEST_HAS_STD_WSTRING\n\n  // Gets the text streamed to this object so far as an std::string.\n  // Each '\\0' character in the buffer is replaced with \"\\\\0\".\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  std::string GetString() const;\n\n private:\n  // We'll hold the text streamed to this object here.\n  const std::unique_ptr< ::std::stringstream> ss_;\n\n  // We declare (but don't implement) this to prevent the compiler\n  // from implementing the assignment operator.\n  void operator=(const Message&);\n};\n\n// Streams a Message to an ostream.\ninline std::ostream& operator<<(std::ostream& os, const Message& sb) {\n  return os << sb.GetString();\n}\n\nnamespace internal {\n\n// Converts a streamable value to an std::string.  A NULL pointer is\n// converted to \"(null)\".  When the input value is a ::string,\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\n// character in it is replaced with \"\\\\0\".\ntemplate <typename T>\nstd::string StreamableToString(const T& streamable) {\n  return (Message() << streamable).GetString();\n}\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-param-test.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Macros and functions for implementing parameterized tests\n// in Google C++ Testing and Mocking Framework (Google Test)\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n\n// Value-parameterized tests allow you to test your code with different\n// parameters without writing multiple copies of the same test.\n//\n// Here is how you use value-parameterized tests:\n\n#if 0\n\n// To write value-parameterized tests, first you should define a fixture\n// class. It is usually derived from testing::TestWithParam<T> (see below for\n// another inheritance scheme that's sometimes useful in more complicated\n// class hierarchies), where the type of your parameter values.\n// TestWithParam<T> is itself derived from testing::Test. T can be any\n// copyable type. If it's a raw pointer, you are responsible for managing the\n// lifespan of the pointed values.\n\nclass FooTest : public ::testing::TestWithParam<const char*> {\n  // You can implement all the usual class fixture members here.\n};\n\n// Then, use the TEST_P macro to define as many parameterized tests\n// for this fixture as you want. The _P suffix is for \"parameterized\"\n// or \"pattern\", whichever you prefer to think.\n\nTEST_P(FooTest, DoesBlah) {\n  // Inside a test, access the test parameter with the GetParam() method\n  // of the TestWithParam<T> class:\n  EXPECT_TRUE(foo.Blah(GetParam()));\n  ...\n}\n\nTEST_P(FooTest, HasBlahBlah) {\n  ...\n}\n\n// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test\n// case with any set of parameters you want. Google Test defines a number\n// of functions for generating test parameters. They return what we call\n// (surprise!) parameter generators. Here is a summary of them, which\n// are all in the testing namespace:\n//\n//\n//  Range(begin, end [, step]) - Yields values {begin, begin+step,\n//                               begin+step+step, ...}. The values do not\n//                               include end. step defaults to 1.\n//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.\n//  ValuesIn(container)        - Yields values from a C-style array, an STL\n//  ValuesIn(begin,end)          container, or an iterator range [begin, end).\n//  Bool()                     - Yields sequence {false, true}.\n//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product\n//                               for the math savvy) of the values generated\n//                               by the N generators.\n//\n// For more details, see comments at the definitions of these functions below\n// in this file.\n//\n// The following statement will instantiate tests from the FooTest test suite\n// each with parameter values \"meeny\", \"miny\", and \"moe\".\n\nINSTANTIATE_TEST_SUITE_P(InstantiationName,\n                         FooTest,\n                         Values(\"meeny\", \"miny\", \"moe\"));\n\n// To distinguish different instances of the pattern, (yes, you\n// can instantiate it more than once) the first argument to the\n// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the\n// actual test suite name. Remember to pick unique prefixes for different\n// instantiations. The tests from the instantiation above will have\n// these names:\n//\n//    * InstantiationName/FooTest.DoesBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.DoesBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.DoesBlah/2 for \"moe\"\n//    * InstantiationName/FooTest.HasBlahBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.HasBlahBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.HasBlahBlah/2 for \"moe\"\n//\n// You can use these names in --gtest_filter.\n//\n// This statement will instantiate all tests from FooTest again, each\n// with parameter values \"cat\" and \"dog\":\n\nconst char* pets[] = {\"cat\", \"dog\"};\nINSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));\n\n// The tests from the instantiation above will have these names:\n//\n//    * AnotherInstantiationName/FooTest.DoesBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.DoesBlah/1 for \"dog\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for \"dog\"\n//\n// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests\n// in the given test suite, whether their definitions come before or\n// AFTER the INSTANTIATE_TEST_SUITE_P statement.\n//\n// Please also note that generator expressions (including parameters to the\n// generators) are evaluated in InitGoogleTest(), after main() has started.\n// This allows the user on one hand, to adjust generator parameters in order\n// to dynamically determine a set of tests to run and on the other hand,\n// give the user a chance to inspect the generated tests with Google Test\n// reflection API before RUN_ALL_TESTS() is executed.\n//\n// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc\n// for more examples.\n//\n// In the future, we plan to publish the API for defining new parameter\n// generators. But for now this interface remains part of the internal\n// implementation and is subject to change.\n//\n//\n// A parameterized test fixture must be derived from testing::Test and from\n// testing::WithParamInterface<T>, where T is the type of the parameter\n// values. Inheriting from TestWithParam<T> satisfies that requirement because\n// TestWithParam<T> inherits from both Test and WithParamInterface. In more\n// complicated hierarchies, however, it is occasionally useful to inherit\n// separately from Test and WithParamInterface. For example:\n\nclass BaseTest : public ::testing::Test {\n  // You can inherit all the usual members for a non-parameterized test\n  // fixture here.\n};\n\nclass DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {\n  // The usual test fixture members go here too.\n};\n\nTEST_F(BaseTest, HasFoo) {\n  // This is an ordinary non-parameterized test.\n}\n\nTEST_P(DerivedTest, DoesBlah) {\n  // GetParam works just the same here as if you inherit from TestWithParam.\n  EXPECT_TRUE(foo.Blah(GetParam()));\n}\n\n#endif  // 0\n\n#include <iterator>\n#include <utility>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-param-util.h\"  // IWYU pragma: export\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// Functions producing parameter generators.\n//\n// Google Test uses these generators to produce parameters for value-\n// parameterized tests. When a parameterized test suite is instantiated\n// with a particular generator, Google Test creates and runs tests\n// for each element in the sequence produced by the generator.\n//\n// In the following sample, tests from test suite FooTest are instantiated\n// each three times with parameter values 3, 5, and 8:\n//\n// class FooTest : public TestWithParam<int> { ... };\n//\n// TEST_P(FooTest, TestThis) {\n// }\n// TEST_P(FooTest, TestThat) {\n// }\n// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));\n//\n\n// Range() returns generators providing sequences of values in a range.\n//\n// Synopsis:\n// Range(start, end)\n//   - returns a generator producing a sequence of values {start, start+1,\n//     start+2, ..., }.\n// Range(start, end, step)\n//   - returns a generator producing a sequence of values {start, start+step,\n//     start+step+step, ..., }.\n// Notes:\n//   * The generated sequences never include end. For example, Range(1, 5)\n//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)\n//     returns a generator producing {1, 3, 5, 7}.\n//   * start and end must have the same type. That type may be any integral or\n//     floating-point type or a user defined type satisfying these conditions:\n//     * It must be assignable (have operator=() defined).\n//     * It must have operator+() (operator+(int-compatible type) for\n//       two-operand version).\n//     * It must have operator<() defined.\n//     Elements in the resulting sequences will also have that type.\n//   * Condition start < end must be satisfied in order for resulting sequences\n//     to contain any elements.\n//\ntemplate <typename T, typename IncrementT>\ninternal::ParamGenerator<T> Range(T start, T end, IncrementT step) {\n  return internal::ParamGenerator<T>(\n      new internal::RangeGenerator<T, IncrementT>(start, end, step));\n}\n\ntemplate <typename T>\ninternal::ParamGenerator<T> Range(T start, T end) {\n  return Range(start, end, 1);\n}\n\n// ValuesIn() function allows generation of tests with parameters coming from\n// a container.\n//\n// Synopsis:\n// ValuesIn(const T (&array)[N])\n//   - returns a generator producing sequences with elements from\n//     a C-style array.\n// ValuesIn(const Container& container)\n//   - returns a generator producing sequences with elements from\n//     an STL-style container.\n// ValuesIn(Iterator begin, Iterator end)\n//   - returns a generator producing sequences with elements from\n//     a range [begin, end) defined by a pair of STL-style iterators. These\n//     iterators can also be plain C pointers.\n//\n// Please note that ValuesIn copies the values from the containers\n// passed in and keeps them to generate tests in RUN_ALL_TESTS().\n//\n// Examples:\n//\n// This instantiates tests from test suite StringTest\n// each with C-string values of \"foo\", \"bar\", and \"baz\":\n//\n// const char* strings[] = {\"foo\", \"bar\", \"baz\"};\n// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));\n//\n// This instantiates tests from test suite StlStringTest\n// each with STL strings with values \"a\" and \"b\":\n//\n// ::std::vector< ::std::string> GetParameterStrings() {\n//   ::std::vector< ::std::string> v;\n//   v.push_back(\"a\");\n//   v.push_back(\"b\");\n//   return v;\n// }\n//\n// INSTANTIATE_TEST_SUITE_P(CharSequence,\n//                          StlStringTest,\n//                          ValuesIn(GetParameterStrings()));\n//\n//\n// This will also instantiate tests from CharTest\n// each with parameter values 'a' and 'b':\n//\n// ::std::list<char> GetParameterChars() {\n//   ::std::list<char> list;\n//   list.push_back('a');\n//   list.push_back('b');\n//   return list;\n// }\n// ::std::list<char> l = GetParameterChars();\n// INSTANTIATE_TEST_SUITE_P(CharSequence2,\n//                          CharTest,\n//                          ValuesIn(l.begin(), l.end()));\n//\ntemplate <typename ForwardIterator>\ninternal::ParamGenerator<\n    typename std::iterator_traits<ForwardIterator>::value_type>\nValuesIn(ForwardIterator begin, ForwardIterator end) {\n  typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;\n  return internal::ParamGenerator<ParamType>(\n      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));\n}\n\ntemplate <typename T, size_t N>\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {\n  return ValuesIn(array, array + N);\n}\n\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container) {\n  return ValuesIn(container.begin(), container.end());\n}\n\n// Values() allows generating tests from explicitly specified list of\n// parameters.\n//\n// Synopsis:\n// Values(T v1, T v2, ..., T vN)\n//   - returns a generator producing sequences with elements v1, v2, ..., vN.\n//\n// For example, this instantiates tests from test suite BarTest each\n// with values \"one\", \"two\", and \"three\":\n//\n// INSTANTIATE_TEST_SUITE_P(NumSequence,\n//                          BarTest,\n//                          Values(\"one\", \"two\", \"three\"));\n//\n// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.\n// The exact type of values will depend on the type of parameter in BazTest.\n//\n// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));\n//\n//\ntemplate <typename... T>\ninternal::ValueArray<T...> Values(T... v) {\n  return internal::ValueArray<T...>(std::move(v)...);\n}\n\n// Bool() allows generating tests with parameters in a set of (false, true).\n//\n// Synopsis:\n// Bool()\n//   - returns a generator producing sequences with elements {false, true}.\n//\n// It is useful when testing code that depends on Boolean flags. Combinations\n// of multiple flags can be tested when several Bool()'s are combined using\n// Combine() function.\n//\n// In the following example all tests in the test suite FlagDependentTest\n// will be instantiated twice with parameters false and true.\n//\n// class FlagDependentTest : public testing::TestWithParam<bool> {\n//   virtual void SetUp() {\n//     external_flag = GetParam();\n//   }\n// }\n// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());\n//\ninline internal::ParamGenerator<bool> Bool() { return Values(false, true); }\n\n// Combine() allows the user to combine two or more sequences to produce\n// values of a Cartesian product of those sequences' elements.\n//\n// Synopsis:\n// Combine(gen1, gen2, ..., genN)\n//   - returns a generator producing sequences with elements coming from\n//     the Cartesian product of elements from the sequences generated by\n//     gen1, gen2, ..., genN. The sequence elements will have a type of\n//     std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types\n//     of elements from sequences produces by gen1, gen2, ..., genN.\n//\n// Example:\n//\n// This will instantiate tests in test suite AnimalTest each one with\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\n//\n// enum Color { BLACK, GRAY, WHITE };\n// class AnimalTest\n//     : public testing::TestWithParam<std::tuple<const char*, Color> > {...};\n//\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\n//\n// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,\n//                          Combine(Values(\"cat\", \"dog\"),\n//                                  Values(BLACK, WHITE)));\n//\n// This will instantiate tests in FlagDependentTest with all variations of two\n// Boolean flags:\n//\n// class FlagDependentTest\n//     : public testing::TestWithParam<std::tuple<bool, bool> > {\n//   virtual void SetUp() {\n//     // Assigns external_flag_1 and external_flag_2 values from the tuple.\n//     std::tie(external_flag_1, external_flag_2) = GetParam();\n//   }\n// };\n//\n// TEST_P(FlagDependentTest, TestFeature1) {\n//   // Test your code using external_flag_1 and external_flag_2 here.\n// }\n// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,\n//                          Combine(Bool(), Bool()));\n//\ntemplate <typename... Generator>\ninternal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {\n  return internal::CartesianProductHolder<Generator...>(g...);\n}\n\n// ConvertGenerator() wraps a parameter generator in order to cast each produced\n// value through a known type before supplying it to the test suite\n//\n// Synopsis:\n// ConvertGenerator<T>(gen)\n//   - returns a generator producing the same elements as generated by gen, but\n//     each element is static_cast to type T before being returned\n//\n// It is useful when using the Combine() function to get the generated\n// parameters in a custom type instead of std::tuple\n//\n// Example:\n//\n// This will instantiate tests in test suite AnimalTest each one with\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\n//\n// enum Color { BLACK, GRAY, WHITE };\n// struct ParamType {\n//   using TupleT = std::tuple<const char*, Color>;\n//   std::string animal;\n//   Color color;\n//   ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}\n// };\n// class AnimalTest\n//     : public testing::TestWithParam<ParamType> {...};\n//\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\n//\n// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,\n//                          ConvertGenerator<ParamType::TupleT>(\n//                              Combine(Values(\"cat\", \"dog\"),\n//                                      Values(BLACK, WHITE))));\n//\ntemplate <typename T>\ninternal::ParamConverterGenerator<T> ConvertGenerator(\n    internal::ParamGenerator<T> gen) {\n  return internal::ParamConverterGenerator<T>(gen);\n}\n\n#define TEST_P(test_suite_name, test_name)                                     \\\n  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \\\n      : public test_suite_name,                                                \\\n        private ::testing::internal::GTestNonCopyable {                        \\\n   public:                                                                     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {}                    \\\n    void TestBody() override;                                                  \\\n                                                                               \\\n   private:                                                                    \\\n    static int AddToRegistry() {                                               \\\n      ::testing::UnitTest::GetInstance()                                       \\\n          ->parameterized_test_registry()                                      \\\n          .GetTestSuitePatternHolder<test_suite_name>(                         \\\n              GTEST_STRINGIFY_(test_suite_name),                               \\\n              ::testing::internal::CodeLocation(__FILE__, __LINE__))           \\\n          ->AddTestPattern(                                                    \\\n              GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name),  \\\n              new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \\\n                  test_suite_name, test_name)>(),                              \\\n              ::testing::internal::CodeLocation(__FILE__, __LINE__));          \\\n      return 0;                                                                \\\n    }                                                                          \\\n    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \\\n  };                                                                           \\\n  int GTEST_TEST_CLASS_NAME_(test_suite_name,                                  \\\n                             test_name)::gtest_registering_dummy_ =            \\\n      GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry();     \\\n  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()\n\n// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify\n// generator and an optional function or functor that generates custom test name\n// suffixes based on the test parameters. Such a function or functor should\n// accept one argument of type testing::TestParamInfo<class ParamType>, and\n// return std::string.\n//\n// testing::PrintToStringParamName is a builtin test suffix generator that\n// returns the value of testing::PrintToString(GetParam()).\n//\n// Note: test names must be non-empty, unique, and may only contain ASCII\n// alphanumeric characters or underscore. Because PrintToString adds quotes\n// to std::string and C strings, it won't work for these types.\n\n#define GTEST_EXPAND_(arg) arg\n#define GTEST_GET_FIRST_(first, ...) first\n#define GTEST_GET_SECOND_(first, second, ...) second\n\n#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...)               \\\n  static ::testing::internal::ParamGenerator<test_suite_name::ParamType>     \\\n      gtest_##prefix##test_suite_name##_EvalGenerator_() {                   \\\n    return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_));       \\\n  }                                                                          \\\n  static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_(  \\\n      const ::testing::TestParamInfo<test_suite_name::ParamType>& info) {    \\\n    if (::testing::internal::AlwaysFalse()) {                                \\\n      ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_(     \\\n          __VA_ARGS__,                                                       \\\n          ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \\\n          DUMMY_PARAM_)));                                                   \\\n      auto t = std::make_tuple(__VA_ARGS__);                                 \\\n      static_assert(std::tuple_size<decltype(t)>::value <= 2,                \\\n                    \"Too Many Args!\");                                       \\\n    }                                                                        \\\n    return ((GTEST_EXPAND_(GTEST_GET_SECOND_(                                \\\n        __VA_ARGS__,                                                         \\\n        ::testing::internal::DefaultParamName<test_suite_name::ParamType>,   \\\n        DUMMY_PARAM_))))(info);                                              \\\n  }                                                                          \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int                           \\\n      gtest_##prefix##test_suite_name##_dummy_ =                             \\\n          ::testing::UnitTest::GetInstance()                                 \\\n              ->parameterized_test_registry()                                \\\n              .GetTestSuitePatternHolder<test_suite_name>(                   \\\n                  GTEST_STRINGIFY_(test_suite_name),                         \\\n                  ::testing::internal::CodeLocation(__FILE__, __LINE__))     \\\n              ->AddTestSuiteInstantiation(                                   \\\n                  GTEST_STRINGIFY_(prefix),                                  \\\n                  &gtest_##prefix##test_suite_name##_EvalGenerator_,         \\\n                  &gtest_##prefix##test_suite_name##_EvalGenerateName_,      \\\n                  __FILE__, __LINE__)\n\n// Allow Marking a Parameterized test class as not needing to be instantiated.\n#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T)                  \\\n  namespace gtest_do_not_use_outside_namespace_scope {}                   \\\n  static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \\\n      GTEST_STRINGIFY_(T))\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define INSTANTIATE_TEST_CASE_P                                            \\\n  static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \\\n                \"\");                                                       \\\n  INSTANTIATE_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-printers.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test - The Google C++ Testing and Mocking Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// A user can teach this function how to print a class type T by\n// defining either operator<<() or PrintTo() in the namespace that\n// defines T.  More specifically, the FIRST defined function in the\n// following list will be used (assuming T is defined in namespace\n// foo):\n//\n//   1. foo::PrintTo(const T&, ostream*)\n//   2. operator<<(ostream&, const T&) defined in either foo or the\n//      global namespace.\n// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.\n// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an\n//   alternative presentation in test results is of interest.\n//\n// However if T is an STL-style container then it is printed element-wise\n// unless foo::PrintTo(const T&, ostream*) is defined. Note that\n// operator<<() is ignored for container types.\n//\n// If none of the above is defined, it will print the debug string of\n// the value if it is a protocol buffer, or print the raw bytes in the\n// value otherwise.\n//\n// To aid debugging: when T is a reference type, the address of the\n// value is also printed; when T is a (const) char pointer, both the\n// pointer value and the NUL-terminated string it points to are\n// printed.\n//\n// We also provide some convenient wrappers:\n//\n//   // Prints a value to a string.  For a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   std::string ::testing::PrintToString(const T& value);\n//\n//   // Prints a value tersely: for a reference type, the referenced\n//   // value (but not the address) is printed; for a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);\n//\n//   // Prints value using the type inferred by the compiler.  The difference\n//   // from UniversalTersePrint() is that this function prints both the\n//   // pointer and the NUL-terminated string for a (const or not) char pointer.\n//   void ::testing::internal::UniversalPrint(const T& value, ostream*);\n//\n//   // Prints the fields of a tuple tersely to a string vector, one\n//   // element for each field. Tuple support must be enabled in\n//   // gtest-port.h.\n//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(\n//       const Tuple& value);\n//\n// Known limitation:\n//\n// The print primitives print the elements of an STL-style container\n// using the compiler-inferred type of *iter where iter is a\n// const_iterator of the container.  When const_iterator is an input\n// iterator but not a forward iterator, this inferred type may not\n// match value_type, and the print output may be incorrect.  In\n// practice, this is rarely a problem as for most containers\n// const_iterator is a forward iterator.  We'll fix this if there's an\n// actual need for it.  Note that this fix cannot rely on value_type\n// being defined as many user-defined container types don't have\n// value_type.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n\n#include <functional>\n#include <memory>\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <typeinfo>\n#include <utility>\n#include <vector>\n\n#ifdef GTEST_HAS_ABSL\n#include \"absl/strings/has_absl_stringify.h\"\n#include \"absl/strings/str_cat.h\"\n#endif  // GTEST_HAS_ABSL\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#if GTEST_INTERNAL_HAS_STD_SPAN\n#include <span>  // NOLINT\n#endif           // GTEST_INTERNAL_HAS_STD_SPAN\n\nnamespace testing {\n\n// Definitions in the internal* namespaces are subject to change without notice.\n// DO NOT USE THEM IN USER CODE!\nnamespace internal {\n\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os);\n\ntemplate <typename T>\nstruct IsStdSpan {\n  static constexpr bool value = false;\n};\n\n#if GTEST_INTERNAL_HAS_STD_SPAN\ntemplate <typename E>\nstruct IsStdSpan<std::span<E>> {\n  static constexpr bool value = true;\n};\n#endif  // GTEST_INTERNAL_HAS_STD_SPAN\n\n// Used to print an STL-style container when the user doesn't define\n// a PrintTo() for it.\n//\n// NOTE: Since std::span does not have const_iterator until C++23, it would\n// fail IsContainerTest before C++23. However, IsContainerTest only uses\n// the presence of const_iterator to avoid treating iterators as containers\n// because of iterator::iterator. Which means std::span satisfies the *intended*\n// condition of IsContainerTest.\nstruct ContainerPrinter {\n  template <typename T,\n            typename = typename std::enable_if<\n                ((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&\n                 !IsRecursiveContainer<T>::value) ||\n                IsStdSpan<T>::value>::type>\n  static void PrintValue(const T& container, std::ostream* os) {\n    const size_t kMaxCount = 32;  // The maximum number of elements to print.\n    *os << '{';\n    size_t count = 0;\n    for (auto&& elem : container) {\n      if (count > 0) {\n        *os << ',';\n        if (count == kMaxCount) {  // Enough has been printed.\n          *os << \" ...\";\n          break;\n        }\n      }\n      *os << ' ';\n      // We cannot call PrintTo(elem, os) here as PrintTo() doesn't\n      // handle `elem` being a native array.\n      internal::UniversalPrint(elem, os);\n      ++count;\n    }\n\n    if (count > 0) {\n      *os << ' ';\n    }\n    *os << '}';\n  }\n};\n\n// Used to print a pointer that is neither a char pointer nor a member\n// pointer, when the user doesn't define PrintTo() for it.  (A member\n// variable pointer or member function pointer doesn't really point to\n// a location in the address space.  Their representation is\n// implementation-defined.  Therefore they will be printed as raw\n// bytes.)\nstruct FunctionPointerPrinter {\n  template <typename T, typename = typename std::enable_if<\n                            std::is_function<T>::value>::type>\n  static void PrintValue(T* p, ::std::ostream* os) {\n    if (p == nullptr) {\n      *os << \"NULL\";\n    } else {\n      // T is a function type, so '*os << p' doesn't do what we want\n      // (it just prints p as bool).  We want to print p as a const\n      // void*.\n      *os << reinterpret_cast<const void*>(p);\n    }\n  }\n};\n\nstruct PointerPrinter {\n  template <typename T>\n  static void PrintValue(T* p, ::std::ostream* os) {\n    if (p == nullptr) {\n      *os << \"NULL\";\n    } else {\n      // T is not a function type.  We just call << to print p,\n      // relying on ADL to pick up user-defined << for their pointer\n      // types, if any.\n      *os << p;\n    }\n  }\n};\n\nnamespace internal_stream_operator_without_lexical_name_lookup {\n\n// The presence of an operator<< here will terminate lexical scope lookup\n// straight away (even though it cannot be a match because of its argument\n// types). Thus, the two operator<< calls in StreamPrinter will find only ADL\n// candidates.\nstruct LookupBlocker {};\nvoid operator<<(LookupBlocker, LookupBlocker);\n\nstruct StreamPrinter {\n  template <typename T,\n            // Don't accept member pointers here. We'd print them via implicit\n            // conversion to bool, which isn't useful.\n            typename = typename std::enable_if<\n                !std::is_member_pointer<T>::value>::type>\n  // Only accept types for which we can find a streaming operator via\n  // ADL (possibly involving implicit conversions).\n  // (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name\n  // lookup properly when we do it in the template parameter list.)\n  static auto PrintValue(const T& value,\n                         ::std::ostream* os) -> decltype((void)(*os << value)) {\n    // Call streaming operator found by ADL, possibly with implicit conversions\n    // of the arguments.\n    *os << value;\n  }\n};\n\n}  // namespace internal_stream_operator_without_lexical_name_lookup\n\nstruct ProtobufPrinter {\n  // We print a protobuf using its ShortDebugString() when the string\n  // doesn't exceed this many characters; otherwise we print it using\n  // DebugString() for better readability.\n  static const size_t kProtobufOneLinerMaxLength = 50;\n\n  template <typename T,\n            typename = typename std::enable_if<\n                internal::HasDebugStringAndShortDebugString<T>::value>::type>\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    std::string pretty_str = value.ShortDebugString();\n    if (pretty_str.length() > kProtobufOneLinerMaxLength) {\n      pretty_str = \"\\n\" + value.DebugString();\n    }\n    *os << (\"<\" + pretty_str + \">\");\n  }\n};\n\nstruct ConvertibleToIntegerPrinter {\n  // Since T has no << operator or PrintTo() but can be implicitly\n  // converted to BiggestInt, we print it as a BiggestInt.\n  //\n  // Most likely T is an enum type (either named or unnamed), in which\n  // case printing it as an integer is the desired behavior.  In case\n  // T is not an enum, printing it as an integer is the best we can do\n  // given that it has no user-defined printer.\n  static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {\n    *os << value;\n  }\n};\n\nstruct ConvertibleToStringViewPrinter {\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n  static void PrintValue(internal::StringView value, ::std::ostream* os) {\n    internal::UniversalPrint(value, os);\n  }\n#endif\n};\n\n#ifdef GTEST_HAS_ABSL\nstruct ConvertibleToAbslStringifyPrinter {\n  template <typename T,\n            typename = typename std::enable_if<\n                absl::HasAbslStringify<T>::value>::type>  // NOLINT\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    *os << absl::StrCat(value);\n  }\n};\n#endif  // GTEST_HAS_ABSL\n\n// Prints the given number of bytes in the given object to the given\n// ostream.\nGTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,\n                                     size_t count, ::std::ostream* os);\nstruct RawBytesPrinter {\n  // SFINAE on `sizeof` to make sure we have a complete type.\n  template <typename T, size_t = sizeof(T)>\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    PrintBytesInObjectTo(\n        static_cast<const unsigned char*>(\n            // Load bearing cast to void* to support iOS\n            reinterpret_cast<const void*>(std::addressof(value))),\n        sizeof(value), os);\n  }\n};\n\nstruct FallbackPrinter {\n  template <typename T>\n  static void PrintValue(const T&, ::std::ostream* os) {\n    *os << \"(incomplete type)\";\n  }\n};\n\n// Try every printer in order and return the first one that works.\ntemplate <typename T, typename E, typename Printer, typename... Printers>\nstruct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};\n\ntemplate <typename T, typename Printer, typename... Printers>\nstruct FindFirstPrinter<\n    T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),\n    Printer, Printers...> {\n  using type = Printer;\n};\n\n// Select the best printer in the following order:\n//  - Print containers (they have begin/end/etc).\n//  - Print function pointers.\n//  - Print object pointers.\n//  - Print protocol buffers.\n//  - Use the stream operator, if available.\n//  - Print types convertible to BiggestInt.\n//  - Print types convertible to StringView, if available.\n//  - Fallback to printing the raw bytes of the object.\ntemplate <typename T>\nvoid PrintWithFallback(const T& value, ::std::ostream* os) {\n  using Printer = typename FindFirstPrinter<\n      T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,\n      ProtobufPrinter,\n#ifdef GTEST_HAS_ABSL\n      ConvertibleToAbslStringifyPrinter,\n#endif  // GTEST_HAS_ABSL\n      internal_stream_operator_without_lexical_name_lookup::StreamPrinter,\n      ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,\n      RawBytesPrinter, FallbackPrinter>::type;\n  Printer::PrintValue(value, os);\n}\n\n// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a\n// value of type ToPrint that is an operand of a comparison assertion\n// (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in\n// the comparison, and is used to help determine the best way to\n// format the value.  In particular, when the value is a C string\n// (char pointer) and the other operand is an STL string object, we\n// want to format the C string as a string, since we know it is\n// compared by value with the string object.  If the value is a char\n// pointer but the other operand is not an STL string object, we don't\n// know whether the pointer is supposed to point to a NUL-terminated\n// string, and thus want to print it as a pointer to be safe.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n// The default case.\ntemplate <typename ToPrint, typename OtherOperand>\nclass FormatForComparison {\n public:\n  static ::std::string Format(const ToPrint& value) {\n    return ::testing::PrintToString(value);\n  }\n};\n\n// Array.\ntemplate <typename ToPrint, size_t N, typename OtherOperand>\nclass FormatForComparison<ToPrint[N], OtherOperand> {\n public:\n  static ::std::string Format(const ToPrint* value) {\n    return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);\n  }\n};\n\n// By default, print C string as pointers to be safe, as we don't know\n// whether they actually point to a NUL-terminated string.\n\n#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \\\n  template <typename OtherOperand>                                      \\\n  class FormatForComparison<CharType*, OtherOperand> {                  \\\n   public:                                                              \\\n    static ::std::string Format(CharType* value) {                      \\\n      return ::testing::PrintToString(static_cast<const void*>(value)); \\\n    }                                                                   \\\n  }\n\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);\n#ifdef __cpp_lib_char8_t\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);\n#endif\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);\n\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_\n\n// If a C string is compared with an STL string object, we know it's meant\n// to point to a NUL-terminated string, and thus can print it as a string.\n\n#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \\\n  template <>                                                            \\\n  class FormatForComparison<CharType*, OtherStringType> {                \\\n   public:                                                               \\\n    static ::std::string Format(CharType* value) {                       \\\n      return ::testing::PrintToString(value);                            \\\n    }                                                                    \\\n  }\n\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);\n#ifdef __cpp_lib_char8_t\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);\n#endif\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);\n#endif\n\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_\n\n// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)\n// operand to be used in a failure message.  The type (but not value)\n// of the other operand may affect the format.  This allows us to\n// print a char* as a raw pointer when it is compared against another\n// char* or void*, and print it as a C string when it is compared\n// against an std::string object, for example.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename T1, typename T2>\nstd::string FormatForComparisonFailureMessage(const T1& value,\n                                              const T2& /* other_operand */) {\n  return FormatForComparison<T1, T2>::Format(value);\n}\n\n// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given\n// value to the given ostream.  The caller must ensure that\n// 'ostream_ptr' is not NULL, or the behavior is undefined.\n//\n// We define UniversalPrinter as a class template (as opposed to a\n// function template), as we need to partially specialize it for\n// reference types, which cannot be done with function templates.\ntemplate <typename T>\nclass UniversalPrinter;\n\n// Prints the given value using the << operator if it has one;\n// otherwise prints the bytes in it.  This is what\n// UniversalPrinter<T>::Print() does when PrintTo() is not specialized\n// or overloaded for type T.\n//\n// A user can override this behavior for a class type Foo by defining\n// an overload of PrintTo() in the namespace where Foo is defined.  We\n// give the user this option as sometimes defining a << operator for\n// Foo is not desirable (e.g. the coding style may prevent doing it,\n// or there is already a << operator but it doesn't do what the user\n// wants).\ntemplate <typename T>\nvoid PrintTo(const T& value, ::std::ostream* os) {\n  internal::PrintWithFallback(value, os);\n}\n\n// The following list of PrintTo() overloads tells\n// UniversalPrinter<T>::Print() how to print standard types (built-in\n// types, strings, plain arrays, and pointers).\n\n// Overloads for various char types.\nGTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);\nGTEST_API_ void PrintTo(signed char c, ::std::ostream* os);\ninline void PrintTo(char c, ::std::ostream* os) {\n  // When printing a plain char, we always treat it as unsigned.  This\n  // way, the output won't be affected by whether the compiler thinks\n  // char is signed or not.\n  PrintTo(static_cast<unsigned char>(c), os);\n}\n\n// Overloads for other simple built-in types.\ninline void PrintTo(bool x, ::std::ostream* os) {\n  *os << (x ? \"true\" : \"false\");\n}\n\n// Overload for wchar_t type.\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its decimal code (except for L'\\0').\n// The L'\\0' char is printed as \"L'\\\\0'\". The decimal code is printed\n// as signed integer when wchar_t is implemented by the compiler\n// as a signed type and is printed as an unsigned integer when wchar_t\n// is implemented as an unsigned type.\nGTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);\n\nGTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);\ninline void PrintTo(char16_t c, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<char32_t>(c), os);\n}\n#ifdef __cpp_lib_char8_t\ninline void PrintTo(char8_t c, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<char32_t>(c), os);\n}\n#endif\n\n// gcc/clang __{u,}int128_t\n#if defined(__SIZEOF_INT128__)\nGTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);\nGTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);\n#endif  // __SIZEOF_INT128__\n\n// The default resolution used to print floating-point values uses only\n// 6 digits, which can be confusing if a test compares two values whose\n// difference lies in the 7th digit.  So we'd like to print out numbers\n// in full precision.\n// However if the value is something simple like 1.1, full will print a\n// long string like 1.100000001 due to floating-point numbers not using\n// a base of 10.  This routiune returns an appropriate resolution for a\n// given floating-point number, that is, 6 if it will be accurate, or a\n// max_digits10 value (full precision) if it won't,  for values between\n// 0.0001 and one million.\n// It does this by computing what those digits would be (by multiplying\n// by an appropriate power of 10), then dividing by that power again to\n// see if gets the original value back.\n// A similar algorithm applies for values larger than one million; note\n// that for those values, we must divide to get a six-digit number, and\n// then multiply to possibly get the original value again.\ntemplate <typename FloatType>\nint AppropriateResolution(FloatType val) {\n  int full = std::numeric_limits<FloatType>::max_digits10;\n  if (val < 0) val = -val;\n\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wfloat-equal\"\n#endif\n  if (val < 1000000) {\n    FloatType mulfor6 = 1e10;\n    // Without these static casts, the template instantiation for float would\n    // fail to compile when -Wdouble-promotion is enabled, as the arithmetic and\n    // comparison logic would promote floats to doubles.\n    if (val >= static_cast<FloatType>(100000.0)) {  // 100,000 to 999,999\n      mulfor6 = 1.0;\n    } else if (val >= static_cast<FloatType>(10000.0)) {\n      mulfor6 = 1e1;\n    } else if (val >= static_cast<FloatType>(1000.0)) {\n      mulfor6 = 1e2;\n    } else if (val >= static_cast<FloatType>(100.0)) {\n      mulfor6 = 1e3;\n    } else if (val >= static_cast<FloatType>(10.0)) {\n      mulfor6 = 1e4;\n    } else if (val >= static_cast<FloatType>(1.0)) {\n      mulfor6 = 1e5;\n    } else if (val >= static_cast<FloatType>(0.1)) {\n      mulfor6 = 1e6;\n    } else if (val >= static_cast<FloatType>(0.01)) {\n      mulfor6 = 1e7;\n    } else if (val >= static_cast<FloatType>(0.001)) {\n      mulfor6 = 1e8;\n    } else if (val >= static_cast<FloatType>(0.0001)) {\n      mulfor6 = 1e9;\n    }\n    if (static_cast<FloatType>(static_cast<int32_t>(\n            val * mulfor6 + (static_cast<FloatType>(0.5)))) /\n            mulfor6 ==\n        val)\n      return 6;\n  } else if (val < static_cast<FloatType>(1e10)) {\n    FloatType divfor6 = static_cast<FloatType>(1.0);\n    if (val >= static_cast<FloatType>(1e9)) {  // 1,000,000,000 to 9,999,999,999\n      divfor6 = 10000;\n    } else if (val >=\n               static_cast<FloatType>(1e8)) {  // 100,000,000 to 999,999,999\n      divfor6 = 1000;\n    } else if (val >=\n               static_cast<FloatType>(1e7)) {  // 10,000,000 to 99,999,999\n      divfor6 = 100;\n    } else if (val >= static_cast<FloatType>(1e6)) {  // 1,000,000 to 9,999,999\n      divfor6 = 10;\n    }\n    if (static_cast<FloatType>(static_cast<int32_t>(\n            val / divfor6 + (static_cast<FloatType>(0.5)))) *\n            divfor6 ==\n        val)\n      return 6;\n  }\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n  return full;\n}\n\ninline void PrintTo(float f, ::std::ostream* os) {\n  auto old_precision = os->precision();\n  os->precision(AppropriateResolution(f));\n  *os << f;\n  os->precision(old_precision);\n}\n\ninline void PrintTo(double d, ::std::ostream* os) {\n  auto old_precision = os->precision();\n  os->precision(AppropriateResolution(d));\n  *os << d;\n  os->precision(old_precision);\n}\n\n// Overloads for C strings.\nGTEST_API_ void PrintTo(const char* s, ::std::ostream* os);\ninline void PrintTo(char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char*>(s), os);\n}\n\n// signed/unsigned char is often used for representing binary data, so\n// we print pointers to it as void* to be safe.\ninline void PrintTo(const signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(const unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\n#ifdef __cpp_lib_char8_t\n// Overloads for u8 strings.\nGTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);\ninline void PrintTo(char8_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char8_t*>(s), os);\n}\n#endif\n// Overloads for u16 strings.\nGTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);\ninline void PrintTo(char16_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char16_t*>(s), os);\n}\n// Overloads for u32 strings.\nGTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);\ninline void PrintTo(char32_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char32_t*>(s), os);\n}\n\n// MSVC can be configured to define wchar_t as a typedef of unsigned\n// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native\n// type.  When wchar_t is a typedef, defining an overload for const\n// wchar_t* would cause unsigned short* be printed as a wide string,\n// possibly causing invalid memory accesses.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Overloads for wide C strings\nGTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);\ninline void PrintTo(wchar_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const wchar_t*>(s), os);\n}\n#endif\n\n// Overload for C arrays.  Multi-dimensional arrays are printed\n// properly.\n\n// Prints the given number of elements in an array, without printing\n// the curly braces.\ntemplate <typename T>\nvoid PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {\n  UniversalPrint(a[0], os);\n  for (size_t i = 1; i != count; i++) {\n    *os << \", \";\n    UniversalPrint(a[i], os);\n  }\n}\n\n// Overloads for ::std::string.\nGTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::string& s, ::std::ostream* os) {\n  PrintStringTo(s, os);\n}\n\n// Overloads for ::std::u8string\n#ifdef __cpp_lib_char8_t\nGTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {\n  PrintU8StringTo(s, os);\n}\n#endif\n\n// Overloads for ::std::u16string\nGTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {\n  PrintU16StringTo(s, os);\n}\n\n// Overloads for ::std::u32string\nGTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);\ninline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {\n  PrintU32StringTo(s, os);\n}\n\n// Overloads for ::std::wstring.\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);\ninline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {\n  PrintWideStringTo(s, os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// Overload for internal::StringView.\ninline void PrintTo(internal::StringView sp, ::std::ostream* os) {\n  PrintTo(::std::string(sp), os);\n}\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\ninline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << \"(nullptr)\"; }\n\n#if GTEST_HAS_RTTI\ninline void PrintTo(const std::type_info& info, std::ostream* os) {\n  *os << internal::GetTypeName(info);\n}\n#endif  // GTEST_HAS_RTTI\n\ntemplate <typename T>\nvoid PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {\n  UniversalPrinter<T&>::Print(ref.get(), os);\n}\n\ninline const void* VoidifyPointer(const void* p) { return p; }\ninline const void* VoidifyPointer(volatile const void* p) {\n  return const_cast<const void*>(p);\n}\n\ntemplate <typename T, typename Ptr>\nvoid PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {\n  if (ptr == nullptr) {\n    *os << \"(nullptr)\";\n  } else {\n    // We can't print the value. Just print the pointer..\n    *os << \"(\" << (VoidifyPointer)(ptr.get()) << \")\";\n  }\n}\ntemplate <typename T, typename Ptr,\n          typename = typename std::enable_if<!std::is_void<T>::value &&\n                                             !std::is_array<T>::value>::type>\nvoid PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {\n  if (ptr == nullptr) {\n    *os << \"(nullptr)\";\n  } else {\n    *os << \"(ptr = \" << (VoidifyPointer)(ptr.get()) << \", value = \";\n    UniversalPrinter<T>::Print(*ptr, os);\n    *os << \")\";\n  }\n}\n\ntemplate <typename T, typename D>\nvoid PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {\n  (PrintSmartPointer<T>)(ptr, os, 0);\n}\n\ntemplate <typename T>\nvoid PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {\n  (PrintSmartPointer<T>)(ptr, os, 0);\n}\n\n// Helper function for printing a tuple.  T must be instantiated with\n// a tuple type.\ntemplate <typename T>\nvoid PrintTupleTo(const T&, std::integral_constant<size_t, 0>,\n                  ::std::ostream*) {}\n\ntemplate <typename T, size_t I>\nvoid PrintTupleTo(const T& t, std::integral_constant<size_t, I>,\n                  ::std::ostream* os) {\n  PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);\n  GTEST_INTENTIONAL_CONST_COND_PUSH_()\n  if (I > 1) {\n    GTEST_INTENTIONAL_CONST_COND_POP_()\n    *os << \", \";\n  }\n  UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(\n      std::get<I - 1>(t), os);\n}\n\ntemplate <typename... Types>\nvoid PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {\n  *os << \"(\";\n  PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);\n  *os << \")\";\n}\n\n// Overload for std::pair.\ntemplate <typename T1, typename T2>\nvoid PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {\n  *os << '(';\n  // We cannot use UniversalPrint(value.first, os) here, as T1 may be\n  // a reference type.  The same for printing value.second.\n  UniversalPrinter<T1>::Print(value.first, os);\n  *os << \", \";\n  UniversalPrinter<T2>::Print(value.second, os);\n  *os << ')';\n}\n\n// Implements printing a non-reference type T by letting the compiler\n// pick the right overload of PrintTo() for T.\ntemplate <typename T>\nclass UniversalPrinter {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)\n\n  // Note: we deliberately don't call this PrintTo(), as that name\n  // conflicts with ::testing::internal::PrintTo in the body of the\n  // function.\n  static void Print(const T& value, ::std::ostream* os) {\n    // By default, ::testing::internal::PrintTo() is used for printing\n    // the value.\n    //\n    // Thanks to Koenig look-up, if T is a class and has its own\n    // PrintTo() function defined in its namespace, that function will\n    // be visible here.  Since it is more specific than the generic ones\n    // in ::testing::internal, it will be picked by the compiler in the\n    // following statement - exactly what we want.\n    PrintTo(value, os);\n  }\n\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n};\n\n// Remove any const-qualifiers before passing a type to UniversalPrinter.\ntemplate <typename T>\nclass UniversalPrinter<const T> : public UniversalPrinter<T> {};\n\n#if GTEST_INTERNAL_HAS_ANY\n\n// Printer for std::any / absl::any\n\ntemplate <>\nclass UniversalPrinter<Any> {\n public:\n  static void Print(const Any& value, ::std::ostream* os) {\n    if (value.has_value()) {\n      *os << \"value of type \" << GetTypeName(value);\n    } else {\n      *os << \"no value\";\n    }\n  }\n\n private:\n  static std::string GetTypeName(const Any& value) {\n#if GTEST_HAS_RTTI\n    return internal::GetTypeName(value.type());\n#else\n    static_cast<void>(value);  // possibly unused\n    return \"<unknown_type>\";\n#endif  // GTEST_HAS_RTTI\n  }\n};\n\n#endif  // GTEST_INTERNAL_HAS_ANY\n\n#if GTEST_INTERNAL_HAS_OPTIONAL\n\n// Printer for std::optional / absl::optional\n\ntemplate <typename T>\nclass UniversalPrinter<Optional<T>> {\n public:\n  static void Print(const Optional<T>& value, ::std::ostream* os) {\n    *os << '(';\n    if (!value) {\n      *os << \"nullopt\";\n    } else {\n      UniversalPrint(*value, os);\n    }\n    *os << ')';\n  }\n};\n\ntemplate <>\nclass UniversalPrinter<decltype(Nullopt())> {\n public:\n  static void Print(decltype(Nullopt()), ::std::ostream* os) {\n    *os << \"(nullopt)\";\n  }\n};\n\n#endif  // GTEST_INTERNAL_HAS_OPTIONAL\n\n#if GTEST_INTERNAL_HAS_VARIANT\n\n// Printer for std::variant / absl::variant\n\ntemplate <typename... T>\nclass UniversalPrinter<Variant<T...>> {\n public:\n  static void Print(const Variant<T...>& value, ::std::ostream* os) {\n    *os << '(';\n#ifdef GTEST_HAS_ABSL\n    absl::visit(Visitor{os, value.index()}, value);\n#else\n    std::visit(Visitor{os, value.index()}, value);\n#endif  // GTEST_HAS_ABSL\n    *os << ')';\n  }\n\n private:\n  struct Visitor {\n    template <typename U>\n    void operator()(const U& u) const {\n      *os << \"'\" << GetTypeName<U>() << \"(index = \" << index\n          << \")' with value \";\n      UniversalPrint(u, os);\n    }\n    ::std::ostream* os;\n    std::size_t index;\n  };\n};\n\n#endif  // GTEST_INTERNAL_HAS_VARIANT\n\n// UniversalPrintArray(begin, len, os) prints an array of 'len'\n// elements, starting at address 'begin'.\ntemplate <typename T>\nvoid UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {\n  if (len == 0) {\n    *os << \"{}\";\n  } else {\n    *os << \"{ \";\n    const size_t kThreshold = 18;\n    const size_t kChunkSize = 8;\n    // If the array has more than kThreshold elements, we'll have to\n    // omit some details by printing only the first and the last\n    // kChunkSize elements.\n    if (len <= kThreshold) {\n      PrintRawArrayTo(begin, len, os);\n    } else {\n      PrintRawArrayTo(begin, kChunkSize, os);\n      *os << \", ..., \";\n      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);\n    }\n    *os << \" }\";\n  }\n}\n// This overload prints a (const) char array compactly.\nGTEST_API_ void UniversalPrintArray(const char* begin, size_t len,\n                                    ::std::ostream* os);\n\n#ifdef __cpp_lib_char8_t\n// This overload prints a (const) char8_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,\n                                    ::std::ostream* os);\n#endif\n\n// This overload prints a (const) char16_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// This overload prints a (const) char32_t array compactly.\nGTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// This overload prints a (const) wchar_t array compactly.\nGTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,\n                                    ::std::ostream* os);\n\n// Implements printing an array type T[N].\ntemplate <typename T, size_t N>\nclass UniversalPrinter<T[N]> {\n public:\n  // Prints the given array, omitting some elements when there are too\n  // many.\n  static void Print(const T (&a)[N], ::std::ostream* os) {\n    UniversalPrintArray(a, N, os);\n  }\n};\n\n// Implements printing a reference type T&.\ntemplate <typename T>\nclass UniversalPrinter<T&> {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)\n\n  static void Print(const T& value, ::std::ostream* os) {\n    // Prints the address of the value.  We use reinterpret_cast here\n    // as static_cast doesn't compile when T is a function type.\n    *os << \"@\" << reinterpret_cast<const void*>(&value) << \" \";\n\n    // Then prints the value itself.\n    UniversalPrint(value, os);\n  }\n\n  GTEST_DISABLE_MSC_WARNINGS_POP_()\n};\n\n// Prints a value tersely: for a reference type, the referenced value\n// (but not the address) is printed; for a (const) char pointer, the\n// NUL-terminated string (but not the pointer) is printed.\n\ntemplate <typename T>\nclass UniversalTersePrinter {\n public:\n  static void Print(const T& value, ::std::ostream* os) {\n    UniversalPrint(value, os);\n  }\n};\ntemplate <typename T>\nclass UniversalTersePrinter<T&> {\n public:\n  static void Print(const T& value, ::std::ostream* os) {\n    UniversalPrint(value, os);\n  }\n};\ntemplate <typename T>\nclass UniversalTersePrinter<std::reference_wrapper<T>> {\n public:\n  static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {\n    UniversalTersePrinter<T>::Print(value.get(), os);\n  }\n};\ntemplate <typename T, size_t N>\nclass UniversalTersePrinter<T[N]> {\n public:\n  static void Print(const T (&value)[N], ::std::ostream* os) {\n    UniversalPrinter<T[N]>::Print(value, os);\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<const char*> {\n public:\n  static void Print(const char* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(std::string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {\n};\n\n#ifdef __cpp_lib_char8_t\ntemplate <>\nclass UniversalTersePrinter<const char8_t*> {\n public:\n  static void Print(const char8_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u8string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char8_t*>\n    : public UniversalTersePrinter<const char8_t*> {};\n#endif\n\ntemplate <>\nclass UniversalTersePrinter<const char16_t*> {\n public:\n  static void Print(const char16_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u16string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char16_t*>\n    : public UniversalTersePrinter<const char16_t*> {};\n\ntemplate <>\nclass UniversalTersePrinter<const char32_t*> {\n public:\n  static void Print(const char32_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::u32string(str), os);\n    }\n  }\n};\ntemplate <>\nclass UniversalTersePrinter<char32_t*>\n    : public UniversalTersePrinter<const char32_t*> {};\n\n#if GTEST_HAS_STD_WSTRING\ntemplate <>\nclass UniversalTersePrinter<const wchar_t*> {\n public:\n  static void Print(const wchar_t* str, ::std::ostream* os) {\n    if (str == nullptr) {\n      *os << \"NULL\";\n    } else {\n      UniversalPrint(::std::wstring(str), os);\n    }\n  }\n};\n#endif\n\ntemplate <>\nclass UniversalTersePrinter<wchar_t*> {\n public:\n  static void Print(wchar_t* str, ::std::ostream* os) {\n    UniversalTersePrinter<const wchar_t*>::Print(str, os);\n  }\n};\n\ntemplate <typename T>\nvoid UniversalTersePrint(const T& value, ::std::ostream* os) {\n  UniversalTersePrinter<T>::Print(value, os);\n}\n\n// Prints a value using the type inferred by the compiler.  The\n// difference between this and UniversalTersePrint() is that for a\n// (const) char pointer, this prints both the pointer and the\n// NUL-terminated string.\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os) {\n  // A workarond for the bug in VC++ 7.1 that prevents us from instantiating\n  // UniversalPrinter with T directly.\n  typedef T T1;\n  UniversalPrinter<T1>::Print(value, os);\n}\n\ntypedef ::std::vector<::std::string> Strings;\n\n// Tersely prints the first N fields of a tuple to a string vector,\n// one element for each field.\ntemplate <typename Tuple>\nvoid TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,\n                               Strings*) {}\ntemplate <typename Tuple, size_t I>\nvoid TersePrintPrefixToStrings(const Tuple& t,\n                               std::integral_constant<size_t, I>,\n                               Strings* strings) {\n  TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),\n                            strings);\n  ::std::stringstream ss;\n  UniversalTersePrint(std::get<I - 1>(t), &ss);\n  strings->push_back(ss.str());\n}\n\n// Prints the fields of a tuple tersely to a string vector, one\n// element for each field.  See the comment before\n// UniversalTersePrint() for how we define \"tersely\".\ntemplate <typename Tuple>\nStrings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {\n  Strings result;\n  TersePrintPrefixToStrings(\n      value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),\n      &result);\n  return result;\n}\n\n}  // namespace internal\n\ntemplate <typename T>\n::std::string PrintToString(const T& value) {\n  ::std::stringstream ss;\n  internal::UniversalTersePrinter<T>::Print(value, &ss);\n  return ss.str();\n}\n\n}  // namespace testing\n\n// Include any custom printer added by the local installation.\n// We must include this header at the end to make sure it can use the\n// declarations from this file.\n#include \"gtest/internal/custom/gtest-printers.h\"\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-spi.h",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Utilities for testing Google Test itself and code that uses Google Test\n// (e.g. frameworks built on top of Google Test).\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n\n#include <string>\n\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// This helper class can be used to mock out Google Test failure reporting\n// so that we can test Google Test or code that builds on Google Test.\n//\n// An object of this class appends a TestPartResult object to the\n// TestPartResultArray object given in the constructor whenever a Google Test\n// failure is reported. It can either intercept only failures that are\n// generated in the same thread that created this object or it can intercept\n// all generated failures. The scope of this mock object can be controlled with\n// the second argument to the two arguments constructor.\nclass GTEST_API_ ScopedFakeTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  // The two possible mocking modes of this object.\n  enum InterceptMode {\n    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.\n    INTERCEPT_ALL_THREADS           // Intercepts all failures.\n  };\n\n  // The c'tor sets this object as the test part result reporter used\n  // by Google Test.  The 'result' parameter specifies where to report the\n  // results. This reporter will only catch failures generated in the current\n  // thread. DEPRECATED\n  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);\n\n  // Same as above, but you can choose the interception scope of this object.\n  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,\n                                   TestPartResultArray* result);\n\n  // The d'tor restores the previous test part result reporter.\n  ~ScopedFakeTestPartResultReporter() override;\n\n  // Appends the TestPartResult object to the TestPartResultArray\n  // received in the constructor.\n  //\n  // This method is from the TestPartResultReporterInterface\n  // interface.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  void Init();\n\n  const InterceptMode intercept_mode_;\n  TestPartResultReporterInterface* old_reporter_;\n  TestPartResultArray* const result_;\n\n  ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =\n      delete;\n  ScopedFakeTestPartResultReporter& operator=(\n      const ScopedFakeTestPartResultReporter&) = delete;\n};\n\nnamespace internal {\n\n// A helper class for implementing EXPECT_FATAL_FAILURE() and\n// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nclass GTEST_API_ SingleFailureChecker {\n public:\n  // The constructor remembers the arguments.\n  SingleFailureChecker(const TestPartResultArray* results,\n                       TestPartResult::Type type, const std::string& substr);\n  ~SingleFailureChecker();\n\n private:\n  const TestPartResultArray* const results_;\n  const TestPartResult::Type type_;\n  const std::string substr_;\n\n  SingleFailureChecker(const SingleFailureChecker&) = delete;\n  SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// A set of macros for testing Google Test assertions or code that's expected\n// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but\n// not a non-fatal failure, as from EXPECT_EQ).  It verifies that the given\n// statement will cause exactly one fatal Google Test failure with 'substr'\n// being part of the failure message.\n//\n// There are two different versions of this macro. EXPECT_FATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - 'statement' cannot reference local non-static variables or\n//     non-static members of the current object.\n//   - 'statement' cannot return a value.\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in\n// gtest_unittest.cc will fail to compile if we do that.\n#define EXPECT_FATAL_FAILURE(statement, substr)                               \\\n  do {                                                                        \\\n    class GTestExpectFatalFailureHelper {                                     \\\n     public:                                                                  \\\n      static void Execute() { statement; }                                    \\\n    };                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::                       \\\n              INTERCEPT_ONLY_CURRENT_THREAD,                                  \\\n          &gtest_failures);                                                   \\\n      GTestExpectFatalFailureHelper::Execute();                               \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr)                \\\n  do {                                                                        \\\n    class GTestExpectFatalFailureHelper {                                     \\\n     public:                                                                  \\\n      static void Execute() { statement; }                                    \\\n    };                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \\\n          &gtest_failures);                                                   \\\n      GTestExpectFatalFailureHelper::Execute();                               \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n// A macro for testing Google Test assertions or code that's expected to\n// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,\n// but not from an ASSERT_EQ). It asserts that the given statement will cause\n// exactly one non-fatal Google Test failure with 'substr' being part of the\n// failure message.\n//\n// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// 'statement' is allowed to reference local variables and members of\n// the current object.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  If we do that, the code won't compile when the user gives\n// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that\n// expands to code containing an unprotected comma.  The\n// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc\n// catches that.\n//\n// For the same reason, we have to write\n//   if (::testing::internal::AlwaysTrue()) { statement; }\n// instead of\n//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n// to avoid an MSVC warning on unreachable code.\n#define EXPECT_NONFATAL_FAILURE(statement, substr)                    \\\n  do {                                                                \\\n    ::testing::TestPartResultArray gtest_failures;                    \\\n    ::testing::internal::SingleFailureChecker gtest_checker(          \\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\n        (substr));                                                    \\\n    {                                                                 \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(     \\\n          ::testing::ScopedFakeTestPartResultReporter::               \\\n              INTERCEPT_ONLY_CURRENT_THREAD,                          \\\n          &gtest_failures);                                           \\\n      if (::testing::internal::AlwaysTrue()) {                        \\\n        statement;                                                    \\\n      }                                                               \\\n    }                                                                 \\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr)             \\\n  do {                                                                        \\\n    ::testing::TestPartResultArray gtest_failures;                            \\\n    ::testing::internal::SingleFailureChecker gtest_checker(                  \\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure,         \\\n        (substr));                                                            \\\n    {                                                                         \\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(             \\\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \\\n          &gtest_failures);                                                   \\\n      if (::testing::internal::AlwaysTrue()) {                                \\\n        statement;                                                            \\\n      }                                                                       \\\n    }                                                                         \\\n  } while (::testing::internal::AlwaysFalse())\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-test-part.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n\n#include <iosfwd>\n#include <ostream>\n#include <string>\n#include <vector>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\nnamespace testing {\n\n// A copyable object representing the result of a test part (i.e. an\n// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).\n//\n// Don't inherit from TestPartResult as its destructor is not virtual.\nclass GTEST_API_ TestPartResult {\n public:\n  // The possible outcomes of a test part (i.e. an assertion or an\n  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).\n  enum Type {\n    kSuccess,          // Succeeded.\n    kNonFatalFailure,  // Failed but the test can continue.\n    kFatalFailure,     // Failed and the test should be terminated.\n    kSkip              // Skipped.\n  };\n\n  // C'tor.  TestPartResult does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestPartResult object.\n  TestPartResult(Type a_type, const char* a_file_name, int a_line_number,\n                 const char* a_message)\n      : type_(a_type),\n        file_name_(a_file_name == nullptr ? \"\" : a_file_name),\n        line_number_(a_line_number),\n        summary_(ExtractSummary(a_message)),\n        message_(a_message) {}\n\n  // Gets the outcome of the test part.\n  Type type() const { return type_; }\n\n  // Gets the name of the source file where the test part took place, or\n  // NULL if it's unknown.\n  const char* file_name() const {\n    return file_name_.empty() ? nullptr : file_name_.c_str();\n  }\n\n  // Gets the line in the source file where the test part took place,\n  // or -1 if it's unknown.\n  int line_number() const { return line_number_; }\n\n  // Gets the summary of the failure message.\n  const char* summary() const { return summary_.c_str(); }\n\n  // Gets the message associated with the test part.\n  const char* message() const { return message_.c_str(); }\n\n  // Returns true if and only if the test part was skipped.\n  bool skipped() const { return type_ == kSkip; }\n\n  // Returns true if and only if the test part passed.\n  bool passed() const { return type_ == kSuccess; }\n\n  // Returns true if and only if the test part non-fatally failed.\n  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }\n\n  // Returns true if and only if the test part fatally failed.\n  bool fatally_failed() const { return type_ == kFatalFailure; }\n\n  // Returns true if and only if the test part failed.\n  bool failed() const { return fatally_failed() || nonfatally_failed(); }\n\n private:\n  Type type_;\n\n  // Gets the summary of the failure message by omitting the stack\n  // trace in it.\n  static std::string ExtractSummary(const char* message);\n\n  // The name of the source file where the test part took place, or\n  // \"\" if the source file is unknown.\n  std::string file_name_;\n  // The line in the source file where the test part took place, or -1\n  // if the line number is unknown.\n  int line_number_;\n  std::string summary_;  // The test failure summary.\n  std::string message_;  // The test failure message.\n};\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result);\n\n// An array of TestPartResult objects.\n//\n// Don't inherit from TestPartResultArray as its destructor is not\n// virtual.\nclass GTEST_API_ TestPartResultArray {\n public:\n  TestPartResultArray() = default;\n\n  // Appends the given TestPartResult to the array.\n  void Append(const TestPartResult& result);\n\n  // Returns the TestPartResult at the given index (0-based).\n  const TestPartResult& GetTestPartResult(int index) const;\n\n  // Returns the number of TestPartResult objects in the array.\n  int size() const;\n\n private:\n  std::vector<TestPartResult> array_;\n\n  TestPartResultArray(const TestPartResultArray&) = delete;\n  TestPartResultArray& operator=(const TestPartResultArray&) = delete;\n};\n\n// This interface knows how to report a test part result.\nclass GTEST_API_ TestPartResultReporterInterface {\n public:\n  virtual ~TestPartResultReporterInterface() = default;\n\n  virtual void ReportTestPartResult(const TestPartResult& result) = 0;\n};\n\nnamespace internal {\n\n// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a\n// statement generates new fatal failures. To do so it registers itself as the\n// current test part result reporter. Besides checking if fatal failures were\n// reported, it only delegates the reporting to the former result reporter.\n// The original result reporter is restored in the destructor.\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nclass GTEST_API_ HasNewFatalFailureHelper\n    : public TestPartResultReporterInterface {\n public:\n  HasNewFatalFailureHelper();\n  ~HasNewFatalFailureHelper() override;\n  void ReportTestPartResult(const TestPartResult& result) override;\n  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }\n\n private:\n  bool has_new_fatal_failure_;\n  TestPartResultReporterInterface* original_reporter_;\n\n  HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;\n  HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest-typed-test.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n\n// This header implements typed tests and type-parameterized tests.\n\n// Typed (aka type-driven) tests repeat the same test for types in a\n// list.  You must know which types you want to test with when writing\n// typed tests. Here's how you do it:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n public:\n  ...\n  typedef std::list<T> List;\n  static T shared_;\n  T value_;\n};\n\n// Next, associate a list of types with the test suite, which will be\n// repeated for each type in the list.  The typedef is necessary for\n// the macro to parse correctly.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nTYPED_TEST_SUITE(FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   TYPED_TEST_SUITE(FooTest, int);\n\n// Then, use TYPED_TEST() instead of TEST_F() to define as many typed\n// tests for this test suite as you want.\nTYPED_TEST(FooTest, DoesBlah) {\n  // Inside a test, refer to the special name TypeParam to get the type\n  // parameter.  Since we are inside a derived class template, C++ requires\n  // us to visit the members of FooTest via 'this'.\n  TypeParam n = this->value_;\n\n  // To visit static members of the fixture, add the TestFixture::\n  // prefix.\n  n += TestFixture::shared_;\n\n  // To refer to typedefs in the fixture, add the \"typename\n  // TestFixture::\" prefix.\n  typename TestFixture::List values;\n  values.push_back(n);\n  ...\n}\n\nTYPED_TEST(FooTest, HasPropertyA) { ... }\n\n// TYPED_TEST_SUITE takes an optional third argument which allows to specify a\n// class that generates custom test name suffixes based on the type. This should\n// be a class which has a static template function GetName(int index) returning\n// a string for each type. The provided integer index equals the index of the\n// type in the provided type list. In many cases the index can be ignored.\n//\n// For example:\n//   class MyTypeNames {\n//    public:\n//     template <typename T>\n//     static std::string GetName(int) {\n//       if (std::is_same<T, char>()) return \"char\";\n//       if (std::is_same<T, int>()) return \"int\";\n//       if (std::is_same<T, unsigned int>()) return \"unsignedInt\";\n//     }\n//   };\n//   TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);\n\n#endif  // 0\n\n// Type-parameterized tests are abstract test patterns parameterized\n// by a type.  Compared with typed tests, type-parameterized tests\n// allow you to define the test pattern without knowing what the type\n// parameters are.  The defined pattern can be instantiated with\n// different types any number of times, in any number of translation\n// units.\n//\n// If you are designing an interface or concept, you can define a\n// suite of type-parameterized tests to verify properties that any\n// valid implementation of the interface/concept should have.  Then,\n// each implementation can easily instantiate the test suite to verify\n// that it conforms to the requirements, without having to write\n// similar tests repeatedly.  Here's an example:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n  ...\n};\n\n// Next, declare that you will define a type-parameterized test suite\n// (the _P suffix is for \"parameterized\" or \"pattern\", whichever you\n// prefer):\nTYPED_TEST_SUITE_P(FooTest);\n\n// Then, use TYPED_TEST_P() to define as many type-parameterized tests\n// for this type-parameterized test suite as you want.\nTYPED_TEST_P(FooTest, DoesBlah) {\n  // Inside a test, refer to TypeParam to get the type parameter.\n  TypeParam n = 0;\n  ...\n}\n\nTYPED_TEST_P(FooTest, HasPropertyA) { ... }\n\n// Now the tricky part: you need to register all test patterns before\n// you can instantiate them.  The first argument of the macro is the\n// test suite name; the rest are the names of the tests in this test\n// case.\nREGISTER_TYPED_TEST_SUITE_P(FooTest,\n                            DoesBlah, HasPropertyA);\n\n// Finally, you are free to instantiate the pattern with the types you\n// want.  If you put the above code in a header file, you can #include\n// it in multiple C++ source files and instantiate it multiple times.\n//\n// To distinguish different instances of the pattern, the first\n// argument to the INSTANTIATE_* macro is a prefix that will be added\n// to the actual test suite name.  Remember to pick unique prefixes for\n// different instances.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nINSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);\n//\n// Similar to the optional argument of TYPED_TEST_SUITE above,\n// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to\n// generate custom names.\n//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);\n\n#endif  // 0\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n#include \"gtest/internal/gtest-type-util.h\"\n\n// Implements typed tests.\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the typedef for the type parameters of the\n// given test suite.\n#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_\n\n// Expands to the name of the typedef for the NameGenerator, responsible for\n// creating the suffixes of the name.\n#define GTEST_NAME_GENERATOR_(TestSuiteName) \\\n  gtest_type_params_##TestSuiteName##_NameGenerator\n\n#define TYPED_TEST_SUITE(CaseName, Types, ...)                          \\\n  typedef ::testing::internal::GenerateTypeList<Types>::type            \\\n      GTEST_TYPE_PARAMS_(CaseName);                                     \\\n  typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \\\n  GTEST_NAME_GENERATOR_(CaseName)\n\n#define TYPED_TEST(CaseName, TestName)                                       \\\n  static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1,                      \\\n                \"test-name must not be empty\");                              \\\n  template <typename gtest_TypeParam_>                                       \\\n  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                           \\\n      : public CaseName<gtest_TypeParam_> {                                  \\\n   private:                                                                  \\\n    typedef CaseName<gtest_TypeParam_> TestFixture;                          \\\n    typedef gtest_TypeParam_ TypeParam;                                      \\\n    void TestBody() override;                                                \\\n  };                                                                         \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \\\n      gtest_##CaseName##_##TestName##_registered_ =                          \\\n          ::testing::internal::TypeParameterizedTest<                        \\\n              CaseName,                                                      \\\n              ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(       \\\n                  CaseName, TestName)>,                                      \\\n              GTEST_TYPE_PARAMS_(                                            \\\n                  CaseName)>::Register(\"\",                                   \\\n                                       ::testing::internal::CodeLocation(    \\\n                                           __FILE__, __LINE__),              \\\n                                       GTEST_STRINGIFY_(CaseName),           \\\n                                       GTEST_STRINGIFY_(TestName), 0,        \\\n                                       ::testing::internal::GenerateNames<   \\\n                                           GTEST_NAME_GENERATOR_(CaseName),  \\\n                                           GTEST_TYPE_PARAMS_(CaseName)>()); \\\n  template <typename gtest_TypeParam_>                                       \\\n  void GTEST_TEST_CLASS_NAME_(CaseName,                                      \\\n                              TestName)<gtest_TypeParam_>::TestBody()\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define TYPED_TEST_CASE                                                \\\n  static_assert(::testing::internal::TypedTestCaseIsDeprecated(), \"\"); \\\n  TYPED_TEST_SUITE\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Implements type-parameterized tests.\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the namespace name that the type-parameterized tests for\n// the given type-parameterized test suite are defined in.  The exact\n// name of the namespace is subject to change without notice.\n#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the variable used to remember the names of\n// the defined tests in the given test suite.\n#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \\\n  gtest_typed_test_suite_p_state_##TestSuiteName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.\n//\n// Expands to the name of the variable used to remember the names of\n// the registered tests in the given test suite.\n#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \\\n  gtest_registered_test_names_##TestSuiteName##_\n\n// The variables defined in the type-parameterized test macros are\n// static as typically these macros are used in a .h file that can be\n// #included in multiple translation units linked together.\n#define TYPED_TEST_SUITE_P(SuiteName)              \\\n  static ::testing::internal::TypedTestSuitePState \\\n  GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define TYPED_TEST_CASE_P                                                 \\\n  static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), \"\"); \\\n  TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#define TYPED_TEST_P(SuiteName, TestName)                         \\\n  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                   \\\n  template <typename gtest_TypeParam_>                            \\\n  class TestName : public SuiteName<gtest_TypeParam_> {           \\\n   private:                                                       \\\n    typedef SuiteName<gtest_TypeParam_> TestFixture;              \\\n    typedef gtest_TypeParam_ TypeParam;                           \\\n    void TestBody() override;                                     \\\n  };                                                              \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool               \\\n      gtest_##TestName##_defined_ =                               \\\n          GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \\\n              __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName),    \\\n              GTEST_STRINGIFY_(TestName));                        \\\n  }                                                               \\\n  template <typename gtest_TypeParam_>                            \\\n  void GTEST_SUITE_NAMESPACE_(                                    \\\n      SuiteName)::TestName<gtest_TypeParam_>::TestBody()\n\n// Note: this won't work correctly if the trailing arguments are macros.\n#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...)                         \\\n  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                             \\\n  typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_;      \\\n  }                                                                         \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const            \\\n  GTEST_REGISTERED_TEST_NAMES_(SuiteName) =                                 \\\n      GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \\\n          GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define REGISTER_TYPED_TEST_CASE_P                                           \\\n  static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \\\n                \"\");                                                         \\\n  REGISTER_TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)        \\\n  static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1,                        \\\n                \"test-suit-prefix must not be empty\");                       \\\n  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \\\n      gtest_##Prefix##_##SuiteName =                                         \\\n          ::testing::internal::TypeParameterizedTestSuite<                   \\\n              SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \\\n              ::testing::internal::GenerateTypeList<Types>::type>::          \\\n              Register(                                                      \\\n                  GTEST_STRINGIFY_(Prefix),                                  \\\n                  ::testing::internal::CodeLocation(__FILE__, __LINE__),     \\\n                  &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName),               \\\n                  GTEST_STRINGIFY_(SuiteName),                               \\\n                  GTEST_REGISTERED_TEST_NAMES_(SuiteName),                   \\\n                  ::testing::internal::GenerateNames<                        \\\n                      ::testing::internal::NameGeneratorSelector<            \\\n                          __VA_ARGS__>::type,                                \\\n                      ::testing::internal::GenerateTypeList<Types>::type>())\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n#define INSTANTIATE_TYPED_TEST_CASE_P                                      \\\n  static_assert(                                                           \\\n      ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), \"\"); \\\n  INSTANTIATE_TYPED_TEST_SUITE_P\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the public API for Google Test.  It should be\n// included by any test program that uses Google Test.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n//\n// Acknowledgment: Google Test borrowed the idea of automatic test\n// registration from Barthelemy Dagenais' (barthelemy@prologique.com)\n// easyUnit framework.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n\n#include <cstddef>\n#include <cstdint>\n#include <limits>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <vector>\n\n#include \"gtest/gtest-assertion-result.h\"  // IWYU pragma: export\n#include \"gtest/gtest-death-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest-matchers.h\"  // IWYU pragma: export\n#include \"gtest/gtest-message.h\"  // IWYU pragma: export\n#include \"gtest/gtest-param-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest-printers.h\"  // IWYU pragma: export\n#include \"gtest/gtest-test-part.h\"  // IWYU pragma: export\n#include \"gtest/gtest-typed-test.h\"  // IWYU pragma: export\n#include \"gtest/gtest_pred_impl.h\"  // IWYU pragma: export\n#include \"gtest/gtest_prod.h\"  // IWYU pragma: export\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Declares the flags.\n\n// This flag temporary enables the disabled tests.\nGTEST_DECLARE_bool_(also_run_disabled_tests);\n\n// This flag brings the debugger on an assertion failure.\nGTEST_DECLARE_bool_(break_on_failure);\n\n// This flag controls whether Google Test catches all test-thrown exceptions\n// and logs them as failures.\nGTEST_DECLARE_bool_(catch_exceptions);\n\n// This flag enables using colors in terminal output. Available values are\n// \"yes\" to enable colors, \"no\" (disable colors), or \"auto\" (the default)\n// to let Google Test decide.\nGTEST_DECLARE_string_(color);\n\n// This flag controls whether the test runner should continue execution past\n// first failure.\nGTEST_DECLARE_bool_(fail_fast);\n\n// This flag sets up the filter to select by name using a glob pattern\n// the tests to run. If the filter is not given all tests are executed.\nGTEST_DECLARE_string_(filter);\n\n// This flag controls whether Google Test installs a signal handler that dumps\n// debugging information when fatal signals are raised.\nGTEST_DECLARE_bool_(install_failure_signal_handler);\n\n// This flag causes the Google Test to list tests. None of the tests listed\n// are actually run if the flag is provided.\nGTEST_DECLARE_bool_(list_tests);\n\n// This flag controls whether Google Test emits a detailed XML report to a file\n// in addition to its normal textual output.\nGTEST_DECLARE_string_(output);\n\n// This flags control whether Google Test prints only test failures.\nGTEST_DECLARE_bool_(brief);\n\n// This flags control whether Google Test prints the elapsed time for each\n// test.\nGTEST_DECLARE_bool_(print_time);\n\n// This flags control whether Google Test prints UTF8 characters as text.\nGTEST_DECLARE_bool_(print_utf8);\n\n// This flag specifies the random number seed.\nGTEST_DECLARE_int32_(random_seed);\n\n// This flag sets how many times the tests are repeated. The default value\n// is 1. If the value is -1 the tests are repeating forever.\nGTEST_DECLARE_int32_(repeat);\n\n// This flag controls whether Google Test Environments are recreated for each\n// repeat of the tests. The default value is true. If set to false the global\n// test Environment objects are only set up once, for the first iteration, and\n// only torn down once, for the last.\nGTEST_DECLARE_bool_(recreate_environments_when_repeating);\n\n// This flag controls whether Google Test includes Google Test internal\n// stack frames in failure stack traces.\nGTEST_DECLARE_bool_(show_internal_stack_frames);\n\n// When this flag is specified, tests' order is randomized on every iteration.\nGTEST_DECLARE_bool_(shuffle);\n\n// This flag specifies the maximum number of stack frames to be\n// printed in a failure message.\nGTEST_DECLARE_int32_(stack_trace_depth);\n\n// When this flag is specified, a failed assertion will throw an\n// exception if exceptions are enabled, or exit the program with a\n// non-zero code otherwise. For use with an external test framework.\nGTEST_DECLARE_bool_(throw_on_failure);\n\n// When this flag is set with a \"host:port\" string, on supported\n// platforms test results are streamed to the specified port on\n// the specified host machine.\nGTEST_DECLARE_string_(stream_result_to);\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_\nGTEST_DECLARE_string_(flagfile);\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_\n\nnamespace testing {\n\n// Silence C4100 (unreferenced formal parameter) and 4805\n// unsafe mix of type 'const int' and type 'const bool'\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4805 4100)\n\n// The upper limit for valid stack trace depths.\nconst int kMaxStackTraceDepth = 100;\n\nnamespace internal {\n\nclass AssertHelper;\nclass DefaultGlobalTestPartResultReporter;\nclass ExecDeathTest;\nclass NoExecDeathTest;\nclass FinalSuccessChecker;\nclass GTestFlagSaver;\nclass StreamingListenerTest;\nclass TestResultAccessor;\nclass TestEventListenersAccessor;\nclass TestEventRepeater;\nclass UnitTestRecordPropertyTestHelper;\nclass WindowsDeathTest;\nclass FuchsiaDeathTest;\nclass UnitTestImpl* GetUnitTestImpl();\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const std::string& message);\nstd::set<std::string>* GetIgnoredParameterizedTestSuites();\n\n// A base class that prevents subclasses from being copyable.\n// We do this instead of using '= delete' so as to avoid triggering warnings\n// inside user code regarding any of our declarations.\nclass GTestNonCopyable {\n public:\n  GTestNonCopyable() = default;\n  GTestNonCopyable(const GTestNonCopyable&) = delete;\n  GTestNonCopyable& operator=(const GTestNonCopyable&) = delete;\n  ~GTestNonCopyable() = default;\n};\n\n}  // namespace internal\n\n// The friend relationship of some of these classes is cyclic.\n// If we don't forward declare them the compiler might confuse the classes\n// in friendship clauses with same named classes on the scope.\nclass Test;\nclass TestSuite;\n\n// Old API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nusing TestCase = TestSuite;\n#endif\nclass TestInfo;\nclass UnitTest;\n\n// The abstract class that all tests inherit from.\n//\n// In Google Test, a unit test program contains one or many TestSuites, and\n// each TestSuite contains one or many Tests.\n//\n// When you define a test using the TEST macro, you don't need to\n// explicitly derive from Test - the TEST macro automatically does\n// this for you.\n//\n// The only time you derive from Test is when defining a test fixture\n// to be used in a TEST_F.  For example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     void SetUp() override { ... }\n//     void TearDown() override { ... }\n//     ...\n//   };\n//\n//   TEST_F(FooTest, Bar) { ... }\n//   TEST_F(FooTest, Baz) { ... }\n//\n// Test is not copyable.\nclass GTEST_API_ Test {\n public:\n  friend class TestInfo;\n\n  // The d'tor is virtual as we intend to inherit from Test.\n  virtual ~Test();\n\n  // Sets up the stuff shared by all tests in this test suite.\n  //\n  // Google Test will call Foo::SetUpTestSuite() before running the first\n  // test in test suite Foo.  Hence a sub-class can define its own\n  // SetUpTestSuite() method to shadow the one defined in the super\n  // class.\n  static void SetUpTestSuite() {}\n\n  // Tears down the stuff shared by all tests in this test suite.\n  //\n  // Google Test will call Foo::TearDownTestSuite() after running the last\n  // test in test suite Foo.  Hence a sub-class can define its own\n  // TearDownTestSuite() method to shadow the one defined in the super\n  // class.\n  static void TearDownTestSuite() {}\n\n  // Legacy API is deprecated but still available. Use SetUpTestSuite and\n  // TearDownTestSuite instead.\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  static void TearDownTestCase() {}\n  static void SetUpTestCase() {}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns true if and only if the current test has a fatal failure.\n  static bool HasFatalFailure();\n\n  // Returns true if and only if the current test has a non-fatal failure.\n  static bool HasNonfatalFailure();\n\n  // Returns true if and only if the current test was skipped.\n  static bool IsSkipped();\n\n  // Returns true if and only if the current test has a (either fatal or\n  // non-fatal) failure.\n  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }\n\n  // Logs a property for the current test, test suite, or for the entire\n  // invocation of the test program when used outside of the context of a\n  // test suite.  Only the last value for a given key is remembered.  These\n  // are public static so they can be called from utility functions that are\n  // not members of the test fixture.  Calls to RecordProperty made during\n  // lifespan of the test (from the moment its constructor starts to the\n  // moment its destructor finishes) will be output in XML as attributes of\n  // the <testcase> element.  Properties recorded from fixture's\n  // SetUpTestSuite or TearDownTestSuite are logged as attributes of the\n  // corresponding <testsuite> element.  Calls to RecordProperty made in the\n  // global context (before or after invocation of RUN_ALL_TESTS and from\n  // SetUp/TearDown method of Environment objects registered with Google\n  // Test) will be output as attributes of the <testsuites> element.\n  static void RecordProperty(const std::string& key, const std::string& value);\n  // We do not define a custom serialization except for values that can be\n  // converted to int64_t, but other values could be logged in this way.\n  template <typename T, std::enable_if_t<std::is_convertible<T, int64_t>::value,\n                                         bool> = true>\n  static void RecordProperty(const std::string& key, const T& value) {\n    RecordProperty(key, (Message() << value).GetString());\n  }\n\n protected:\n  // Creates a Test object.\n  Test();\n\n  // Sets up the test fixture.\n  virtual void SetUp();\n\n  // Tears down the test fixture.\n  virtual void TearDown();\n\n private:\n  // Returns true if and only if the current test has the same fixture class\n  // as the first test in the current test suite.\n  static bool HasSameFixtureClass();\n\n  // Runs the test after the test fixture has been set up.\n  //\n  // A sub-class must implement this to define the test logic.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.\n  // Instead, use the TEST or TEST_F macro.\n  virtual void TestBody() = 0;\n\n  // Sets up, executes, and tears down the test.\n  void Run();\n\n  // Deletes self.  We deliberately pick an unusual name for this\n  // internal method to avoid clashing with names used in user TESTs.\n  void DeleteSelf_() { delete this; }\n\n  const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;\n\n  // Often a user misspells SetUp() as Setup() and spends a long time\n  // wondering why it is never called by Google Test.  The declaration of\n  // the following method is solely for catching such an error at\n  // compile time:\n  //\n  //   - The return type is deliberately chosen to be not void, so it\n  //   will be a conflict if void Setup() is declared in the user's\n  //   test fixture.\n  //\n  //   - This method is private, so it will be another compiler error\n  //   if the method is called from the user's test fixture.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION.\n  //\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }\n\n  // We disallow copying Tests.\n  Test(const Test&) = delete;\n  Test& operator=(const Test&) = delete;\n};\n\ntypedef internal::TimeInMillis TimeInMillis;\n\n// A copyable object representing a user specified test property which can be\n// output as a key/value string pair.\n//\n// Don't inherit from TestProperty as its destructor is not virtual.\nclass TestProperty {\n public:\n  // C'tor.  TestProperty does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestProperty object.\n  TestProperty(const std::string& a_key, const std::string& a_value)\n      : key_(a_key), value_(a_value) {}\n\n  // Gets the user supplied key.\n  const char* key() const { return key_.c_str(); }\n\n  // Gets the user supplied value.\n  const char* value() const { return value_.c_str(); }\n\n  // Sets a new value, overriding the one supplied in the constructor.\n  void SetValue(const std::string& new_value) { value_ = new_value; }\n\n private:\n  // The key supplied by the user.\n  std::string key_;\n  // The value supplied by the user.\n  std::string value_;\n};\n\n// The result of a single Test.  This includes a list of\n// TestPartResults, a list of TestProperties, a count of how many\n// death tests there are in the Test, and how much time it took to run\n// the Test.\n//\n// TestResult is not copyable.\nclass GTEST_API_ TestResult {\n public:\n  // Creates an empty TestResult.\n  TestResult();\n\n  // D'tor.  Do not inherit from TestResult.\n  ~TestResult();\n\n  // Gets the number of all test parts.  This is the sum of the number\n  // of successful test parts and the number of failed test parts.\n  int total_part_count() const;\n\n  // Returns the number of the test properties.\n  int test_property_count() const;\n\n  // Returns true if and only if the test passed (i.e. no test part failed).\n  bool Passed() const { return !Skipped() && !Failed(); }\n\n  // Returns true if and only if the test was skipped.\n  bool Skipped() const;\n\n  // Returns true if and only if the test failed.\n  bool Failed() const;\n\n  // Returns true if and only if the test fatally failed.\n  bool HasFatalFailure() const;\n\n  // Returns true if and only if the test has a non-fatal failure.\n  bool HasNonfatalFailure() const;\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Gets the time of the test case start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Returns the i-th test part result among all the results. i can range from 0\n  // to total_part_count() - 1. If i is not in that range, aborts the program.\n  const TestPartResult& GetTestPartResult(int i) const;\n\n  // Returns the i-th test property. i can range from 0 to\n  // test_property_count() - 1. If i is not in that range, aborts the\n  // program.\n  const TestProperty& GetTestProperty(int i) const;\n\n private:\n  friend class TestInfo;\n  friend class TestSuite;\n  friend class UnitTest;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::ExecDeathTest;\n  friend class internal::TestResultAccessor;\n  friend class internal::UnitTestImpl;\n  friend class internal::WindowsDeathTest;\n  friend class internal::FuchsiaDeathTest;\n\n  // Gets the vector of TestPartResults.\n  const std::vector<TestPartResult>& test_part_results() const {\n    return test_part_results_;\n  }\n\n  // Gets the vector of TestProperties.\n  const std::vector<TestProperty>& test_properties() const {\n    return test_properties_;\n  }\n\n  // Sets the start time.\n  void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }\n\n  // Sets the elapsed time.\n  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }\n\n  // Adds a test property to the list. The property is validated and may add\n  // a non-fatal failure if invalid (e.g., if it conflicts with reserved\n  // key names). If a property is already recorded for the same key, the\n  // value will be updated, rather than storing multiple values for the same\n  // key.  xml_element specifies the element for which the property is being\n  // recorded and is used for validation.\n  void RecordProperty(const std::string& xml_element,\n                      const TestProperty& test_property);\n\n  // Adds a failure if the key is a reserved attribute of Google Test\n  // testsuite tags.  Returns true if the property is valid.\n  // FIXME: Validate attribute names are legal and human readable.\n  static bool ValidateTestProperty(const std::string& xml_element,\n                                   const TestProperty& test_property);\n\n  // Adds a test part result to the list.\n  void AddTestPartResult(const TestPartResult& test_part_result);\n\n  // Returns the death test count.\n  int death_test_count() const { return death_test_count_; }\n\n  // Increments the death test count, returning the new count.\n  int increment_death_test_count() { return ++death_test_count_; }\n\n  // Clears the test part results.\n  void ClearTestPartResults();\n\n  // Clears the object.\n  void Clear();\n\n  // Protects mutable state of the property vector and of owned\n  // properties, whose values may be updated.\n  internal::Mutex test_properties_mutex_;\n\n  // The vector of TestPartResults\n  std::vector<TestPartResult> test_part_results_;\n  // The vector of TestProperties\n  std::vector<TestProperty> test_properties_;\n  // Running count of death tests.\n  int death_test_count_;\n  // The start time, in milliseconds since UNIX Epoch.\n  TimeInMillis start_timestamp_;\n  // The elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n  // We disallow copying TestResult.\n  TestResult(const TestResult&) = delete;\n  TestResult& operator=(const TestResult&) = delete;\n};  // class TestResult\n\n// A TestInfo object stores the following information about a test:\n//\n//   Test suite name\n//   Test name\n//   Whether the test should be run\n//   A function pointer that creates the test object when invoked\n//   Test result\n//\n// The constructor of TestInfo registers itself with the UnitTest\n// singleton such that the RUN_ALL_TESTS() macro knows which tests to\n// run.\nclass GTEST_API_ TestInfo {\n public:\n  // Destructs a TestInfo object.  This function is not virtual, so\n  // don't inherit from TestInfo.\n  ~TestInfo();\n\n  // Returns the test suite name.\n  const char* test_suite_name() const { return test_suite_name_.c_str(); }\n\n// Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const char* test_case_name() const { return test_suite_name(); }\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns the test name.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a typed\n  // or a type-parameterized test.\n  const char* type_param() const {\n    if (type_param_ != nullptr) return type_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns the text representation of the value parameter, or NULL if this\n  // is not a value-parameterized test.\n  const char* value_param() const {\n    if (value_param_ != nullptr) return value_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns the file name where this test is defined.\n  const char* file() const { return location_.file.c_str(); }\n\n  // Returns the line where this test is defined.\n  int line() const { return location_.line; }\n\n  // Return true if this test should not be run because it's in another shard.\n  bool is_in_another_shard() const { return is_in_another_shard_; }\n\n  // Returns true if this test should run, that is if the test is not\n  // disabled (or it is disabled but the also_run_disabled_tests flag has\n  // been specified) and its full name matches the user-specified filter.\n  //\n  // Google Test allows the user to filter the tests by their full names.\n  // The full name of a test Bar in test suite Foo is defined as\n  // \"Foo.Bar\".  Only the tests that match the filter will run.\n  //\n  // A filter is a colon-separated list of glob (not regex) patterns,\n  // optionally followed by a '-' and a colon-separated list of\n  // negative patterns (tests to exclude).  A test is run if it\n  // matches one of the positive patterns and does not match any of\n  // the negative patterns.\n  //\n  // For example, *A*:Foo.* is a filter that matches any string that\n  // contains the character 'A' or starts with \"Foo.\".\n  bool should_run() const { return should_run_; }\n\n  // Returns true if and only if this test will appear in the XML report.\n  bool is_reportable() const {\n    // The XML report includes tests matching the filter, excluding those\n    // run in other shards.\n    return matches_filter_ && !is_in_another_shard_;\n  }\n\n  // Returns the result of the test.\n  const TestResult* result() const { return &result_; }\n\n private:\n#ifdef GTEST_HAS_DEATH_TEST\n  friend class internal::DefaultDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n  friend class Test;\n  friend class TestSuite;\n  friend class internal::UnitTestImpl;\n  friend class internal::StreamingListenerTest;\n  friend TestInfo* internal::MakeAndRegisterTestInfo(\n      std::string test_suite_name, const char* name, const char* type_param,\n      const char* value_param, internal::CodeLocation code_location,\n      internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,\n      internal::TearDownTestSuiteFunc tear_down_tc,\n      internal::TestFactoryBase* factory);\n\n  // Constructs a TestInfo object. The newly constructed instance assumes\n  // ownership of the factory object.\n  TestInfo(std::string test_suite_name, std::string name,\n           const char* a_type_param,   // NULL if not a type-parameterized test\n           const char* a_value_param,  // NULL if not a value-parameterized test\n           internal::CodeLocation a_code_location,\n           internal::TypeId fixture_class_id,\n           internal::TestFactoryBase* factory);\n\n  // Increments the number of death tests encountered in this test so\n  // far.\n  int increment_death_test_count() {\n    return result_.increment_death_test_count();\n  }\n\n  // Creates the test object, runs it, records its result, and then\n  // deletes it.\n  void Run();\n\n  // Skip and records the test result for this object.\n  void Skip();\n\n  static void ClearTestResult(TestInfo* test_info) {\n    test_info->result_.Clear();\n  }\n\n  // These fields are immutable properties of the test.\n  const std::string test_suite_name_;  // test suite name\n  const std::string name_;             // Test name\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const std::unique_ptr<const ::std::string> type_param_;\n  // Text representation of the value parameter, or NULL if this is not a\n  // value-parameterized test.\n  const std::unique_ptr<const ::std::string> value_param_;\n  internal::CodeLocation location_;\n  const internal::TypeId fixture_class_id_;  // ID of the test fixture class\n  bool should_run_;           // True if and only if this test should run\n  bool is_disabled_;          // True if and only if this test is disabled\n  bool matches_filter_;       // True if this test matches the\n                              // user-specified filter.\n  bool is_in_another_shard_;  // Will be run in another shard.\n  internal::TestFactoryBase* const factory_;  // The factory that creates\n                                              // the test object\n\n  // This field is mutable and needs to be reset before running the\n  // test for the second time.\n  TestResult result_;\n\n  TestInfo(const TestInfo&) = delete;\n  TestInfo& operator=(const TestInfo&) = delete;\n};\n\n// A test suite, which consists of a vector of TestInfos.\n//\n// TestSuite is not copyable.\nclass GTEST_API_ TestSuite {\n public:\n  // Creates a TestSuite with the given name.\n  //\n  // TestSuite does NOT have a default constructor.  Always use this\n  // constructor to create a TestSuite object.\n  //\n  // Arguments:\n  //\n  //   name:         name of the test suite\n  //   a_type_param: the name of the test's type parameter, or NULL if\n  //                 this is not a type-parameterized test.\n  //   set_up_tc:    pointer to the function that sets up the test suite\n  //   tear_down_tc: pointer to the function that tears down the test suite\n  TestSuite(const std::string& name, const char* a_type_param,\n            internal::SetUpTestSuiteFunc set_up_tc,\n            internal::TearDownTestSuiteFunc tear_down_tc);\n\n  // Destructor of TestSuite.\n  virtual ~TestSuite();\n\n  // Gets the name of the TestSuite.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a\n  // type-parameterized test suite.\n  const char* type_param() const {\n    if (type_param_ != nullptr) return type_param_->c_str();\n    return nullptr;\n  }\n\n  // Returns true if any test in this test suite should run.\n  bool should_run() const { return should_run_; }\n\n  // Gets the number of successful tests in this test suite.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests in this test suite.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests in this test suite.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests in this test suite.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Get the number of tests in this test suite that should run.\n  int test_to_run_count() const;\n\n  // Gets the number of all tests in this test suite.\n  int total_test_count() const;\n\n  // Returns true if and only if the test suite passed.\n  bool Passed() const { return !Failed(); }\n\n  // Returns true if and only if the test suite failed.\n  bool Failed() const {\n    return failed_test_count() > 0 || ad_hoc_test_result().Failed();\n  }\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Gets the time of the test suite start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  const TestInfo* GetTestInfo(int i) const;\n\n  // Returns the TestResult that holds test properties recorded during\n  // execution of SetUpTestSuite and TearDownTestSuite.\n  const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }\n\n private:\n  friend class Test;\n  friend class internal::UnitTestImpl;\n\n  // Gets the (mutable) vector of TestInfos in this TestSuite.\n  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }\n\n  // Gets the (immutable) vector of TestInfos in this TestSuite.\n  const std::vector<TestInfo*>& test_info_list() const {\n    return test_info_list_;\n  }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  TestInfo* GetMutableTestInfo(int i);\n\n  // Sets the should_run member.\n  void set_should_run(bool should) { should_run_ = should; }\n\n  // Adds a TestInfo to this test suite.  Will delete the TestInfo upon\n  // destruction of the TestSuite object.\n  void AddTestInfo(TestInfo* test_info);\n\n  // Clears the results of all tests in this test suite.\n  void ClearResult();\n\n  // Clears the results of all tests in the given test suite.\n  static void ClearTestSuiteResult(TestSuite* test_suite) {\n    test_suite->ClearResult();\n  }\n\n  // Runs every test in this TestSuite.\n  void Run();\n\n  // Skips the execution of tests under this TestSuite\n  void Skip();\n\n  // Runs SetUpTestSuite() for this TestSuite.  This wrapper is needed\n  // for catching exceptions thrown from SetUpTestSuite().\n  void RunSetUpTestSuite() {\n    if (set_up_tc_ != nullptr) {\n      (*set_up_tc_)();\n    }\n  }\n\n  // Runs TearDownTestSuite() for this TestSuite.  This wrapper is\n  // needed for catching exceptions thrown from TearDownTestSuite().\n  void RunTearDownTestSuite() {\n    if (tear_down_tc_ != nullptr) {\n      (*tear_down_tc_)();\n    }\n  }\n\n  // Returns true if and only if test passed.\n  static bool TestPassed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Passed();\n  }\n\n  // Returns true if and only if test skipped.\n  static bool TestSkipped(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Skipped();\n  }\n\n  // Returns true if and only if test failed.\n  static bool TestFailed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Failed();\n  }\n\n  // Returns true if and only if the test is disabled and will be reported in\n  // the XML report.\n  static bool TestReportableDisabled(const TestInfo* test_info) {\n    return test_info->is_reportable() && test_info->is_disabled_;\n  }\n\n  // Returns true if and only if test is disabled.\n  static bool TestDisabled(const TestInfo* test_info) {\n    return test_info->is_disabled_;\n  }\n\n  // Returns true if and only if this test will appear in the XML report.\n  static bool TestReportable(const TestInfo* test_info) {\n    return test_info->is_reportable();\n  }\n\n  // Returns true if the given test should run.\n  static bool ShouldRunTest(const TestInfo* test_info) {\n    return test_info->should_run();\n  }\n\n  // Shuffles the tests in this test suite.\n  void ShuffleTests(internal::Random* random);\n\n  // Restores the test order to before the first shuffle.\n  void UnshuffleTests();\n\n  // Name of the test suite.\n  std::string name_;\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const std::unique_ptr<const ::std::string> type_param_;\n  // The vector of TestInfos in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestInfo*> test_info_list_;\n  // Provides a level of indirection for the test list to allow easy\n  // shuffling and restoring the test order.  The i-th element in this\n  // vector is the index of the i-th test in the shuffled test list.\n  std::vector<int> test_indices_;\n  // Pointer to the function that sets up the test suite.\n  internal::SetUpTestSuiteFunc set_up_tc_;\n  // Pointer to the function that tears down the test suite.\n  internal::TearDownTestSuiteFunc tear_down_tc_;\n  // True if and only if any test in this test suite should run.\n  bool should_run_;\n  // The start time, in milliseconds since UNIX Epoch.\n  TimeInMillis start_timestamp_;\n  // Elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n  // Holds test properties recorded during execution of SetUpTestSuite and\n  // TearDownTestSuite.\n  TestResult ad_hoc_test_result_;\n\n  // We disallow copying TestSuites.\n  TestSuite(const TestSuite&) = delete;\n  TestSuite& operator=(const TestSuite&) = delete;\n};\n\n// An Environment object is capable of setting up and tearing down an\n// environment.  You should subclass this to define your own\n// environment(s).\n//\n// An Environment object does the set-up and tear-down in virtual\n// methods SetUp() and TearDown() instead of the constructor and the\n// destructor, as:\n//\n//   1. You cannot safely throw from a destructor.  This is a problem\n//      as in some cases Google Test is used where exceptions are enabled, and\n//      we may want to implement ASSERT_* using exceptions where they are\n//      available.\n//   2. You cannot use ASSERT_* directly in a constructor or\n//      destructor.\nclass Environment {\n public:\n  // The d'tor is virtual as we need to subclass Environment.\n  virtual ~Environment() = default;\n\n  // Override this to define how to set up the environment.\n  virtual void SetUp() {}\n\n  // Override this to define how to tear down the environment.\n  virtual void TearDown() {}\n\n private:\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }\n};\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Exception which can be thrown from TestEventListener::OnTestPartResult.\nclass GTEST_API_ AssertionException\n    : public internal::GoogleTestFailureException {\n public:\n  explicit AssertionException(const TestPartResult& result)\n      : GoogleTestFailureException(result) {}\n};\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// The interface for tracing execution of tests. The methods are organized in\n// the order the corresponding events are fired.\nclass TestEventListener {\n public:\n  virtual ~TestEventListener() = default;\n\n  // Fired before any test activity starts.\n  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;\n\n  // Fired before each iteration of tests starts.  There may be more than\n  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration\n  // index, starting from 0.\n  virtual void OnTestIterationStart(const UnitTest& unit_test,\n                                    int iteration) = 0;\n\n  // Fired before environment set-up for each iteration of tests starts.\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment set-up for each iteration of tests ends.\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;\n\n  // Fired before the test suite starts.\n  virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Fired before the test starts.\n  virtual void OnTestStart(const TestInfo& test_info) = 0;\n\n  // Fired when a test is disabled\n  virtual void OnTestDisabled(const TestInfo& /*test_info*/) {}\n\n  // Fired after a failed assertion or a SUCCEED() invocation.\n  // If you want to throw an exception from this function to skip to the next\n  // TEST, it must be AssertionException defined above, or inherited from it.\n  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;\n\n  // Fired after the test ends.\n  virtual void OnTestEnd(const TestInfo& test_info) = 0;\n\n  // Fired after the test suite ends.\n  virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Fired before environment tear-down for each iteration of tests starts.\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment tear-down for each iteration of tests ends.\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;\n\n  // Fired after each iteration of tests finishes.\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0;\n\n  // Fired after all test activities have ended.\n  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;\n};\n\n// The convenience class for users who need to override just one or two\n// methods and are not concerned that a possible change to a signature of\n// the methods they override will not be caught during the build.  For\n// comments about each method please see the definition of TestEventListener\n// above.\nclass EmptyTestEventListener : public TestEventListener {\n public:\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& /*unit_test*/,\n                            int /*iteration*/) override {}\n  void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& /*test_case*/) override {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnTestStart(const TestInfo& /*test_info*/) override {}\n  void OnTestDisabled(const TestInfo& /*test_info*/) override {}\n  void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}\n  void OnTestEnd(const TestInfo& /*test_info*/) override {}\n  void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& /*test_case*/) override {}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& /*unit_test*/,\n                          int /*iteration*/) override {}\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n};\n\n// TestEventListeners lets users add listeners to track events in Google Test.\nclass GTEST_API_ TestEventListeners {\n public:\n  TestEventListeners();\n  ~TestEventListeners();\n\n  // Appends an event listener to the end of the list. Google Test assumes\n  // the ownership of the listener (i.e. it will delete the listener when\n  // the test program finishes).\n  void Append(TestEventListener* listener);\n\n  // Removes the given event listener from the list and returns it.  It then\n  // becomes the caller's responsibility to delete the listener. Returns\n  // NULL if the listener is not found in the list.\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Returns the standard listener responsible for the default console\n  // output.  Can be removed from the listeners list to shut down default\n  // console output.  Note that removing this object from the listener list\n  // with Release transfers its ownership to the caller and makes this\n  // function return NULL the next time.\n  TestEventListener* default_result_printer() const {\n    return default_result_printer_;\n  }\n\n  // Returns the standard listener responsible for the default XML output\n  // controlled by the --gtest_output=xml flag.  Can be removed from the\n  // listeners list by users who want to shut down the default XML output\n  // controlled by this flag and substitute it with custom one.  Note that\n  // removing this object from the listener list with Release transfers its\n  // ownership to the caller and makes this function return NULL the next\n  // time.\n  TestEventListener* default_xml_generator() const {\n    return default_xml_generator_;\n  }\n\n  // Controls whether events will be forwarded by the repeater to the\n  // listeners in the list.\n  void SuppressEventForwarding(bool);\n\n private:\n  friend class TestSuite;\n  friend class TestInfo;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::NoExecDeathTest;\n  friend class internal::TestEventListenersAccessor;\n  friend class internal::UnitTestImpl;\n\n  // Returns repeater that broadcasts the TestEventListener events to all\n  // subscribers.\n  TestEventListener* repeater();\n\n  // Sets the default_result_printer attribute to the provided listener.\n  // The listener is also added to the listener list and previous\n  // default_result_printer is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultResultPrinter(TestEventListener* listener);\n\n  // Sets the default_xml_generator attribute to the provided listener.  The\n  // listener is also added to the listener list and previous\n  // default_xml_generator is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultXmlGenerator(TestEventListener* listener);\n\n  // Controls whether events will be forwarded by the repeater to the\n  // listeners in the list.\n  bool EventForwardingEnabled() const;\n\n  // The actual list of listeners.\n  internal::TestEventRepeater* repeater_;\n  // Listener responsible for the standard result output.\n  TestEventListener* default_result_printer_;\n  // Listener responsible for the creation of the XML output file.\n  TestEventListener* default_xml_generator_;\n\n  // We disallow copying TestEventListeners.\n  TestEventListeners(const TestEventListeners&) = delete;\n  TestEventListeners& operator=(const TestEventListeners&) = delete;\n};\n\n// A UnitTest consists of a vector of TestSuites.\n//\n// This is a singleton class.  The only instance of UnitTest is\n// created when UnitTest::GetInstance() is first called.  This\n// instance is never deleted.\n//\n// UnitTest is not copyable.\n//\n// This class is thread-safe as long as the methods are called\n// according to their specification.\nclass GTEST_API_ UnitTest {\n public:\n  // Gets the singleton UnitTest object.  The first time this method\n  // is called, a UnitTest object is constructed and returned.\n  // Consecutive calls will return the same object.\n  static UnitTest* GetInstance();\n\n  // Runs all tests in this UnitTest object and prints the result.\n  // Returns 0 if successful, or 1 otherwise.\n  //\n  // This method can only be called from the main thread.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  int Run() GTEST_MUST_USE_RESULT_;\n\n  // Returns the working directory when the first TEST() or TEST_F()\n  // was executed.  The UnitTest object owns the string.\n  const char* original_working_dir() const;\n\n  // Returns the TestSuite object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n// Legacy API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_);\n#endif\n\n  // Returns the TestInfo object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Returns the random seed used at the start of the current test run.\n  int random_seed() const;\n\n  // Returns the ParameterizedTestSuiteRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry()\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Gets the number of successful test suites.\n  int successful_test_suite_count() const;\n\n  // Gets the number of failed test suites.\n  int failed_test_suite_count() const;\n\n  // Gets the number of all test suites.\n  int total_test_suite_count() const;\n\n  // Gets the number of all test suites that contain at least one test\n  // that should run.\n  int test_suite_to_run_count() const;\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  int successful_test_case_count() const;\n  int failed_test_case_count() const;\n  int total_test_case_count() const;\n  int test_case_to_run_count() const;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const;\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const;\n\n  // Returns true if and only if the unit test passed (i.e. all test suites\n  // passed).\n  bool Passed() const;\n\n  // Returns true if and only if the unit test failed (i.e. some test suite\n  // failed or something outside of all tests failed).\n  bool Failed() const;\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  const TestSuite* GetTestSuite(int i) const;\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* GetTestCase(int i) const;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Returns the TestResult containing information on test failures and\n  // properties logged outside of individual test suites.\n  const TestResult& ad_hoc_test_result() const;\n\n  // Returns the list of event listeners that can be used to track events\n  // inside Google Test.\n  TestEventListeners& listeners();\n\n private:\n  // Registers and returns a global test environment.  When a test\n  // program is run, all global test environments will be set-up in\n  // the order they were registered.  After all tests in the program\n  // have finished, all global test environments will be torn-down in\n  // the *reverse* order they were registered.\n  //\n  // The UnitTest object takes ownership of the given environment.\n  //\n  // This method can only be called from the main thread.\n  Environment* AddEnvironment(Environment* env);\n\n  // Adds a TestPartResult to the current TestResult object.  All\n  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)\n  // eventually call this to report their results.  The user code\n  // should use the assertion macros instead of calling this directly.\n  void AddTestPartResult(TestPartResult::Type result_type,\n                         const char* file_name, int line_number,\n                         const std::string& message,\n                         const std::string& os_stack_trace)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Adds a TestProperty to the current TestResult object when invoked from\n  // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked\n  // from SetUpTestSuite or TearDownTestSuite, or to the global property set\n  // when invoked elsewhere.  If the result already contains a property with\n  // the same key, the value will be updated.\n  void RecordProperty(const std::string& key, const std::string& value);\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  TestSuite* GetMutableTestSuite(int i);\n\n  // Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest()\n  // should be called immediately before Google Test calls user code. It saves\n  // some information about the current stack that CurrentStackTrace() will use\n  // to find and hide Google Test stack frames.\n  void UponLeavingGTest();\n\n  // Sets the TestSuite object for the test that's currently running.\n  void set_current_test_suite(TestSuite* a_current_test_suite)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Sets the TestInfo object for the test that's currently running.\n  void set_current_test_info(TestInfo* a_current_test_info)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Accessors for the implementation object.\n  internal::UnitTestImpl* impl() { return impl_; }\n  const internal::UnitTestImpl* impl() const { return impl_; }\n\n  // These classes and functions are friends as they need to access private\n  // members of UnitTest.\n  friend class ScopedTrace;\n  friend class Test;\n  friend class TestInfo;\n  friend class TestSuite;\n  friend class internal::AssertHelper;\n  friend class internal::StreamingListenerTest;\n  friend class internal::UnitTestRecordPropertyTestHelper;\n  friend Environment* AddGlobalTestEnvironment(Environment* env);\n  friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites();\n  friend internal::UnitTestImpl* internal::GetUnitTestImpl();\n  friend void internal::ReportFailureInUnknownLocation(\n      TestPartResult::Type result_type, const std::string& message);\n\n  // Creates an empty UnitTest.\n  UnitTest();\n\n  // D'tor\n  virtual ~UnitTest();\n\n  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n  // Google Test trace stack.\n  void PushGTestTrace(const internal::TraceInfo& trace)\n      GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Pops a trace from the per-thread Google Test trace stack.\n  void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_);\n\n  // Protects mutable state in *impl_.  This is mutable as some const\n  // methods need to lock it too.\n  mutable internal::Mutex mutex_;\n\n  // Opaque implementation object.  This field is never changed once\n  // the object is constructed.  We don't mark it as const here, as\n  // doing so will cause a warning in the constructor of UnitTest.\n  // Mutable state in *impl_ is protected by mutex_.\n  internal::UnitTestImpl* impl_;\n\n  // We disallow copying UnitTest.\n  UnitTest(const UnitTest&) = delete;\n  UnitTest& operator=(const UnitTest&) = delete;\n};\n\n// A convenient wrapper for adding an environment for the test\n// program.\n//\n// You should call this before RUN_ALL_TESTS() is called, probably in\n// main().  If you use gtest_main, you need to call this before main()\n// starts for it to take effect.  For example, you can define a global\n// variable like this:\n//\n//   testing::Environment* const foo_env =\n//       testing::AddGlobalTestEnvironment(new FooEnvironment);\n//\n// However, we strongly recommend you to write your own main() and\n// call AddGlobalTestEnvironment() there, as relying on initialization\n// of global variables makes the code harder to read and may cause\n// problems when you register multiple environments from different\n// translation units and the environments have dependencies among them\n// (remember that the compiler doesn't guarantee the order in which\n// global variables from different translation units are initialized).\ninline Environment* AddGlobalTestEnvironment(Environment* env) {\n  return UnitTest::GetInstance()->AddEnvironment(env);\n}\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nGTEST_API_ void InitGoogleTest(int* argc, char** argv);\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nGTEST_API_ void InitGoogleTest();\n\nnamespace internal {\n\n// Separate the error generating code from the code path to reduce the stack\n// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers\n// when calling EXPECT_* in a tight loop.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperEQFailure(const char* lhs_expression,\n                                   const char* rhs_expression, const T1& lhs,\n                                   const T2& rhs) {\n  return EqFailure(lhs_expression, rhs_expression,\n                   FormatForComparisonFailureMessage(lhs, rhs),\n                   FormatForComparisonFailureMessage(rhs, lhs), false);\n}\n\n// This block of code defines operator==/!=\n// to block lexical scope lookup.\n// It prevents using invalid operator==/!= defined at namespace scope.\nstruct faketype {};\ninline bool operator==(faketype, faketype) { return true; }\ninline bool operator!=(faketype, faketype) { return false; }\n\n// The helper function for {ASSERT|EXPECT}_EQ.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperEQ(const char* lhs_expression,\n                            const char* rhs_expression, const T1& lhs,\n                            const T2& rhs) {\n  if (lhs == rhs) {\n    return AssertionSuccess();\n  }\n\n  return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);\n}\n\nclass EqHelper {\n public:\n  // This templatized version is for the general case.\n  template <\n      typename T1, typename T2,\n      // Disable this overload for cases where one argument is a pointer\n      // and the other is the null pointer constant.\n      typename std::enable_if<!std::is_integral<T1>::value ||\n                              !std::is_pointer<T2>::value>::type* = nullptr>\n  static AssertionResult Compare(const char* lhs_expression,\n                                 const char* rhs_expression, const T1& lhs,\n                                 const T2& rhs) {\n    return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);\n  }\n\n  // With this overloaded version, we allow anonymous enums to be used\n  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous\n  // enums can be implicitly cast to BiggestInt.\n  //\n  // Even though its body looks the same as the above version, we\n  // cannot merge the two, as it will make anonymous enums unhappy.\n  static AssertionResult Compare(const char* lhs_expression,\n                                 const char* rhs_expression, BiggestInt lhs,\n                                 BiggestInt rhs) {\n    return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);\n  }\n\n  template <typename T>\n  static AssertionResult Compare(\n      const char* lhs_expression, const char* rhs_expression,\n      // Handle cases where '0' is used as a null pointer literal.\n      std::nullptr_t /* lhs */, T* rhs) {\n    // We already know that 'lhs' is a null pointer.\n    return CmpHelperEQ(lhs_expression, rhs_expression, static_cast<T*>(nullptr),\n                       rhs);\n  }\n};\n\n// Separate the error generating code from the code path to reduce the stack\n// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers\n// when calling EXPECT_OP in a tight loop.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,\n                                   const T1& val1, const T2& val2,\n                                   const char* op) {\n  return AssertionFailure()\n         << \"Expected: (\" << expr1 << \") \" << op << \" (\" << expr2\n         << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\n         << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\n}\n\n// A macro for implementing the helper functions needed to implement\n// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste\n// of similar code.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)                                \\\n  template <typename T1, typename T2>                                      \\\n  AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\n                                     const T1& val1, const T2& val2) {     \\\n    if (val1 op val2) {                                                    \\\n      return AssertionSuccess();                                           \\\n    } else {                                                               \\\n      return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);            \\\n    }                                                                      \\\n  }\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n// Implements the helper function for {ASSERT|EXPECT}_NE\nGTEST_IMPL_CMP_HELPER_(NE, !=)\n// Implements the helper function for {ASSERT|EXPECT}_LE\nGTEST_IMPL_CMP_HELPER_(LE, <=)\n// Implements the helper function for {ASSERT|EXPECT}_LT\nGTEST_IMPL_CMP_HELPER_(LT, <)\n// Implements the helper function for {ASSERT|EXPECT}_GE\nGTEST_IMPL_CMP_HELPER_(GE, >=)\n// Implements the helper function for {ASSERT|EXPECT}_GT\nGTEST_IMPL_CMP_HELPER_(GT, >)\n\n#undef GTEST_IMPL_CMP_HELPER_\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression,\n                                              const char* s2_expression,\n                                              const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const char* s1, const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                              const char* s2_expression,\n                                              const char* s1, const char* s2);\n\n// Helper function for *_STREQ on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const wchar_t* s1, const wchar_t* s2);\n\n// Helper function for *_STRNE on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const wchar_t* s1, const wchar_t* s2);\n\n}  // namespace internal\n\n// IsSubstring() and IsNotSubstring() are intended to be used as the\n// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by\n// themselves.  They check whether needle is a substring of haystack\n// (NULL is considered a substring of itself only), and return an\n// appropriate error message when they fail.\n//\n// The {needle,haystack}_expr arguments are the stringified\n// expressions that generated the two real arguments.\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const char* needle,\n                                       const char* haystack);\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const wchar_t* needle,\n                                       const wchar_t* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const char* needle,\n                                          const char* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const wchar_t* needle,\n                                          const wchar_t* haystack);\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const ::std::string& needle,\n                                       const ::std::string& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const ::std::string& needle,\n                                          const ::std::string& haystack);\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ AssertionResult IsSubstring(const char* needle_expr,\n                                       const char* haystack_expr,\n                                       const ::std::wstring& needle,\n                                       const ::std::wstring& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,\n                                          const char* haystack_expr,\n                                          const ::std::wstring& needle,\n                                          const ::std::wstring& haystack);\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n// Helper template function for comparing floating-points.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename RawType>\nAssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,\n                                         const char* rhs_expression,\n                                         RawType lhs_value, RawType rhs_value) {\n  const FloatingPoint<RawType> lhs(lhs_value), rhs(rhs_value);\n\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  ::std::stringstream lhs_ss;\n  lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);\n  lhs_ss << lhs_value;\n\n  ::std::stringstream rhs_ss;\n  rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);\n  rhs_ss << rhs_value;\n\n  return EqFailure(lhs_expression, rhs_expression,\n                   StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),\n                   false);\n}\n\n// Helper function for implementing ASSERT_NEAR.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,\n                                                const char* expr2,\n                                                const char* abs_error_expr,\n                                                double val1, double val2,\n                                                double abs_error);\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n// A class that enables one to stream messages to assertion macros\nclass GTEST_API_ AssertHelper {\n public:\n  // Constructor.\n  AssertHelper(TestPartResult::Type type, const char* file, int line,\n               const char* message);\n  ~AssertHelper();\n\n  // Message assignment is a semantic trick to enable assertion\n  // streaming; see the GTEST_MESSAGE_ macro below.\n  void operator=(const Message& message) const;\n\n private:\n  // We put our data in a struct so that the size of the AssertHelper class can\n  // be as small as possible.  This is important because gcc is incapable of\n  // re-using stack space even for temporary variables, so every EXPECT_EQ\n  // reserves stack space for another AssertHelper.\n  struct AssertHelperData {\n    AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num,\n                     const char* msg)\n        : type(t), file(srcfile), line(line_num), message(msg) {}\n\n    TestPartResult::Type const type;\n    const char* const file;\n    int const line;\n    std::string const message;\n\n   private:\n    AssertHelperData(const AssertHelperData&) = delete;\n    AssertHelperData& operator=(const AssertHelperData&) = delete;\n  };\n\n  AssertHelperData* const data_;\n\n  AssertHelper(const AssertHelper&) = delete;\n  AssertHelper& operator=(const AssertHelper&) = delete;\n};\n\n}  // namespace internal\n\n// The pure interface class that all value-parameterized tests inherit from.\n// A value-parameterized class must inherit from both ::testing::Test and\n// ::testing::WithParamInterface. In most cases that just means inheriting\n// from ::testing::TestWithParam, but more complicated test hierarchies\n// may need to inherit from Test and WithParamInterface at different levels.\n//\n// This interface has support for accessing the test parameter value via\n// the GetParam() method.\n//\n// Use it with one of the parameter generator defining functions, like Range(),\n// Values(), ValuesIn(), Bool(), Combine(), and ConvertGenerator<T>().\n//\n// class FooTest : public ::testing::TestWithParam<int> {\n//  protected:\n//   FooTest() {\n//     // Can use GetParam() here.\n//   }\n//   ~FooTest() override {\n//     // Can use GetParam() here.\n//   }\n//   void SetUp() override {\n//     // Can use GetParam() here.\n//   }\n//   void TearDown override {\n//     // Can use GetParam() here.\n//   }\n// };\n// TEST_P(FooTest, DoesBar) {\n//   // Can use GetParam() method here.\n//   Foo foo;\n//   ASSERT_TRUE(foo.DoesBar(GetParam()));\n// }\n// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));\n\ntemplate <typename T>\nclass WithParamInterface {\n public:\n  typedef T ParamType;\n  virtual ~WithParamInterface() = default;\n\n  // The current parameter value. Is also available in the test fixture's\n  // constructor.\n  static const ParamType& GetParam() {\n    GTEST_CHECK_(parameter_ != nullptr)\n        << \"GetParam() can only be called inside a value-parameterized test \"\n        << \"-- did you intend to write TEST_P instead of TEST_F?\";\n    return *parameter_;\n  }\n\n private:\n  // Sets parameter value. The caller is responsible for making sure the value\n  // remains alive and unchanged throughout the current test.\n  static void SetParam(const ParamType* parameter) { parameter_ = parameter; }\n\n  // Static value used for accessing parameter during a test lifetime.\n  static const ParamType* parameter_;\n\n  // TestClass must be a subclass of WithParamInterface<T> and Test.\n  template <class TestClass>\n  friend class internal::ParameterizedTestFactory;\n};\n\ntemplate <typename T>\nconst T* WithParamInterface<T>::parameter_ = nullptr;\n\n// Most value-parameterized classes can ignore the existence of\n// WithParamInterface, and can just inherit from ::testing::TestWithParam.\n\ntemplate <typename T>\nclass TestWithParam : public Test, public WithParamInterface<T> {};\n\n// Macros for indicating success/failure in test code.\n\n// Skips test in runtime.\n// Skipping test aborts current function.\n// Skipped tests are neither successful nor failed.\n#define GTEST_SKIP() GTEST_SKIP_(\"\")\n\n// ADD_FAILURE unconditionally adds a failure to the current test.\n// SUCCEED generates a success - it doesn't automatically make the\n// current test successful, as a test is only successful when it has\n// no failure.\n//\n// EXPECT_* verifies that a certain condition is satisfied.  If not,\n// it behaves like ADD_FAILURE.  In particular:\n//\n//   EXPECT_TRUE  verifies that a Boolean condition is true.\n//   EXPECT_FALSE verifies that a Boolean condition is false.\n//\n// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except\n// that they will also abort the current function on failure.  People\n// usually want the fail-fast behavior of FAIL and ASSERT_*, but those\n// writing data-driven tests often find themselves using ADD_FAILURE\n// and EXPECT_* more.\n\n// Generates a nonfatal failure with a generic message.\n#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_(\"Failed\")\n\n// Generates a nonfatal failure at the given source file location with\n// a generic message.\n#define ADD_FAILURE_AT(file, line)        \\\n  GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\n                    ::testing::TestPartResult::kNonFatalFailure)\n\n// Generates a fatal failure with a generic message.\n#define GTEST_FAIL() GTEST_FATAL_FAILURE_(\"Failed\")\n\n// Like GTEST_FAIL(), but at the given source file location.\n#define GTEST_FAIL_AT(file, line)                \\\n  return GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\n                           ::testing::TestPartResult::kFatalFailure)\n\n// Define this macro to 1 to omit the definition of FAIL(), which is a\n// generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)\n#define FAIL() GTEST_FAIL()\n#define FAIL_AT(file, line) GTEST_FAIL_AT(file, line)\n#endif\n\n// Generates a success with a generic message.\n#define GTEST_SUCCEED() GTEST_SUCCESS_(\"Succeeded\")\n\n// Define this macro to 1 to omit the definition of SUCCEED(), which\n// is a generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_SUCCEED) && GTEST_DONT_DEFINE_SUCCEED)\n#define SUCCEED() GTEST_SUCCEED()\n#endif\n\n// Macros for testing exceptions.\n//\n//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):\n//         Tests that the statement throws the expected exception.\n//    * {ASSERT|EXPECT}_NO_THROW(statement):\n//         Tests that the statement doesn't throw any exception.\n//    * {ASSERT|EXPECT}_ANY_THROW(statement):\n//         Tests that the statement throws an exception.\n\n#define EXPECT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)\n#define ASSERT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)\n#define ASSERT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)\n\n// Boolean assertions. Condition can be either a Boolean expression or an\n// AssertionResult. For more information on how to use AssertionResult with\n// these macros see comments on that class.\n#define GTEST_EXPECT_TRUE(condition)                      \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define GTEST_EXPECT_FALSE(condition)                        \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define GTEST_ASSERT_TRUE(condition) \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)\n#define GTEST_ASSERT_FALSE(condition)                        \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_FATAL_FAILURE_)\n\n// Define these macros to 1 to omit the definition of the corresponding\n// EXPECT or ASSERT, which clashes with some users' own code.\n\n#if !(defined(GTEST_DONT_DEFINE_EXPECT_TRUE) && GTEST_DONT_DEFINE_EXPECT_TRUE)\n#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_EXPECT_FALSE) && GTEST_DONT_DEFINE_EXPECT_FALSE)\n#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_TRUE) && GTEST_DONT_DEFINE_ASSERT_TRUE)\n#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_FALSE) && GTEST_DONT_DEFINE_ASSERT_FALSE)\n#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition)\n#endif\n\n// Macros for testing equalities and inequalities.\n//\n//    * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2\n//    * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2\n//    * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2\n//    * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2\n//    * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2\n//    * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2\n//\n// When they are not, Google Test prints both the tested expressions and\n// their actual values.  The values must be compatible built-in types,\n// or you will get a compiler error.  By \"compatible\" we mean that the\n// values can be compared by the respective operator.\n//\n// Note:\n//\n//   1. It is possible to make a user-defined type work with\n//   {ASSERT|EXPECT}_??(), but that requires overloading the\n//   comparison operators and is thus discouraged by the Google C++\n//   Usage Guide.  Therefore, you are advised to use the\n//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are\n//   equal.\n//\n//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on\n//   pointers (in particular, C strings).  Therefore, if you use it\n//   with two C strings, you are testing how their locations in memory\n//   are related, not how their content is related.  To compare two C\n//   strings by content, use {ASSERT|EXPECT}_STR*().\n//\n//   3. {ASSERT|EXPECT}_EQ(v1, v2) is preferred to\n//   {ASSERT|EXPECT}_TRUE(v1 == v2), as the former tells you\n//   what the actual value is when it fails, and similarly for the\n//   other comparisons.\n//\n//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()\n//   evaluate their arguments, which is undefined.\n//\n//   5. These macros evaluate their arguments exactly once.\n//\n// Examples:\n//\n//   EXPECT_NE(Foo(), 5);\n//   EXPECT_EQ(a_pointer, NULL);\n//   ASSERT_LT(i, array_size);\n//   ASSERT_GT(records.size(), 0) << \"There is no record left.\";\n\n#define EXPECT_EQ(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)\n#define EXPECT_NE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\n#define EXPECT_LE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define EXPECT_LT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define EXPECT_GE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define EXPECT_GT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n#define GTEST_ASSERT_EQ(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)\n#define GTEST_ASSERT_NE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\n#define GTEST_ASSERT_LE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define GTEST_ASSERT_LT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define GTEST_ASSERT_GE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define GTEST_ASSERT_GT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of\n// ASSERT_XY(), which clashes with some users' own code.\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_EQ) && GTEST_DONT_DEFINE_ASSERT_EQ)\n#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_NE) && GTEST_DONT_DEFINE_ASSERT_NE)\n#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_LE) && GTEST_DONT_DEFINE_ASSERT_LE)\n#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_LT) && GTEST_DONT_DEFINE_ASSERT_LT)\n#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_GE) && GTEST_DONT_DEFINE_ASSERT_GE)\n#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)\n#endif\n\n#if !(defined(GTEST_DONT_DEFINE_ASSERT_GT) && GTEST_DONT_DEFINE_ASSERT_GT)\n#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)\n#endif\n\n// C-string Comparisons.  All tests treat NULL and any non-NULL string\n// as different.  Two NULLs are equal.\n//\n//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2\n//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2\n//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case\n//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case\n//\n// For wide or narrow string objects, you can use the\n// {ASSERT|EXPECT}_??() macros.\n//\n// Don't depend on the order in which the arguments are evaluated,\n// which is undefined.\n//\n// These macros evaluate their arguments exactly once.\n\n#define EXPECT_STREQ(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)\n#define EXPECT_STRNE(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define EXPECT_STRCASEEQ(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)\n#define EXPECT_STRCASENE(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n#define ASSERT_STREQ(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2)\n#define ASSERT_STRNE(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define ASSERT_STRCASEEQ(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2)\n#define ASSERT_STRCASENE(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n// Macros for comparing floating-point numbers.\n//\n//    * {ASSERT|EXPECT}_FLOAT_EQ(val1, val2):\n//         Tests that two float values are almost equal.\n//    * {ASSERT|EXPECT}_DOUBLE_EQ(val1, val2):\n//         Tests that two double values are almost equal.\n//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):\n//         Tests that v1 and v2 are within the given distance to each other.\n//\n// Google Test uses ULP-based comparison to automatically pick a default\n// error bound that is appropriate for the operands.  See the\n// FloatingPoint template class in gtest-internal.h if you are\n// interested in the implementation details.\n\n#define EXPECT_FLOAT_EQ(val1, val2)                                         \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      val1, val2)\n\n#define EXPECT_DOUBLE_EQ(val1, val2)                                         \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      val1, val2)\n\n#define ASSERT_FLOAT_EQ(val1, val2)                                         \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      val1, val2)\n\n#define ASSERT_DOUBLE_EQ(val1, val2)                                         \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      val1, val2)\n\n#define EXPECT_NEAR(val1, val2, abs_error)                                   \\\n  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \\\n                      abs_error)\n\n#define ASSERT_NEAR(val1, val2, abs_error)                                   \\\n  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \\\n                      abs_error)\n\n// These predicate format functions work on floating-point values, and\n// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.\n//\n//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nGTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,\n                                   float val1, float val2);\nGTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,\n                                    double val1, double val2);\n\n#ifdef GTEST_OS_WINDOWS\n\n// Macros that test for HRESULT failure and success, these are only useful\n// on Windows, and rely on Windows SDK macros and APIs to compile.\n//\n//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)\n//\n// When expr unexpectedly fails or succeeds, Google Test prints the\n// expected result and the actual result with both a human-readable\n// string representation of the error, if available, as well as the\n// hex result code.\n#define EXPECT_HRESULT_SUCCEEDED(expr) \\\n  EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n#define ASSERT_HRESULT_SUCCEEDED(expr) \\\n  ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n#define EXPECT_HRESULT_FAILED(expr) \\\n  EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n#define ASSERT_HRESULT_FAILED(expr) \\\n  ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n#endif  // GTEST_OS_WINDOWS\n\n// Macros that execute statement and check that it doesn't generate new fatal\n// failures in the current thread.\n//\n//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);\n//\n// Examples:\n//\n//   EXPECT_NO_FATAL_FAILURE(Process());\n//   ASSERT_NO_FATAL_FAILURE(Process()) << \"Process() failed\";\n//\n#define ASSERT_NO_FATAL_FAILURE(statement) \\\n  GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)\n#define EXPECT_NO_FATAL_FAILURE(statement) \\\n  GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)\n\n// Causes a trace (including the given source file path and line number,\n// and the given message) to be included in every test failure message generated\n// by code in the scope of the lifetime of an instance of this class. The effect\n// is undone with the destruction of the instance.\n//\n// The message argument can be anything streamable to std::ostream.\n//\n// Example:\n//   testing::ScopedTrace trace(\"file.cc\", 123, \"message\");\n//\nclass GTEST_API_ ScopedTrace {\n public:\n  // The c'tor pushes the given source file location and message onto\n  // a trace stack maintained by Google Test.\n\n  // Template version. Uses Message() to convert the values into strings.\n  // Slow, but flexible.\n  template <typename T>\n  ScopedTrace(const char* file, int line, const T& message) {\n    PushTrace(file, line, (Message() << message).GetString());\n  }\n\n  // Optimize for some known types.\n  ScopedTrace(const char* file, int line, const char* message) {\n    PushTrace(file, line, message ? message : \"(null)\");\n  }\n\n  ScopedTrace(const char* file, int line, const std::string& message) {\n    PushTrace(file, line, message);\n  }\n\n  // The d'tor pops the info pushed by the c'tor.\n  //\n  // Note that the d'tor is not virtual in order to be efficient.\n  // Don't inherit from ScopedTrace!\n  ~ScopedTrace();\n\n private:\n  void PushTrace(const char* file, int line, std::string message);\n\n  ScopedTrace(const ScopedTrace&) = delete;\n  ScopedTrace& operator=(const ScopedTrace&) = delete;\n};\n\n// Causes a trace (including the source file path, the current line\n// number, and the given message) to be included in every test failure\n// message generated by code in the current scope.  The effect is\n// undone when the control leaves the current scope.\n//\n// The message argument can be anything streamable to std::ostream.\n//\n// In the implementation, we include the current line number as part\n// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s\n// to appear in the same block - as long as they are on different\n// lines.\n//\n// Assuming that each thread maintains its own stack of traces.\n// Therefore, a SCOPED_TRACE() would (correctly) only affect the\n// assertions in its own thread.\n#define SCOPED_TRACE(message)                                               \\\n  const ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \\\n      __FILE__, __LINE__, (message))\n\n// Compile-time assertion for type equality.\n// StaticAssertTypeEq<type1, type2>() compiles if and only if type1 and type2\n// are the same type.  The value it returns is not interesting.\n//\n// Instead of making StaticAssertTypeEq a class template, we make it a\n// function template that invokes a helper class template.  This\n// prevents a user from misusing StaticAssertTypeEq<T1, T2> by\n// defining objects of that type.\n//\n// CAVEAT:\n//\n// When used inside a method of a class template,\n// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is\n// instantiated.  For example, given:\n//\n//   template <typename T> class Foo {\n//    public:\n//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }\n//   };\n//\n// the code:\n//\n//   void Test1() { Foo<bool> foo; }\n//\n// will NOT generate a compiler error, as Foo<bool>::Bar() is never\n// actually instantiated.  Instead, you need:\n//\n//   void Test2() { Foo<bool> foo; foo.Bar(); }\n//\n// to cause a compiler error.\ntemplate <typename T1, typename T2>\nconstexpr bool StaticAssertTypeEq() noexcept {\n  static_assert(std::is_same<T1, T2>::value, \"T1 and T2 are not the same type\");\n  return true;\n}\n\n// Defines a test.\n//\n// The first parameter is the name of the test suite, and the second\n// parameter is the name of the test within the test suite.\n//\n// The convention is to end the test suite name with \"Test\".  For\n// example, a test suite for the Foo class can be named FooTest.\n//\n// Test code should appear between braces after an invocation of\n// this macro.  Example:\n//\n//   TEST(FooTest, InitializesCorrectly) {\n//     Foo foo;\n//     EXPECT_TRUE(foo.StatusIsOK());\n//   }\n\n// Note that we call GetTestTypeId() instead of GetTypeId<\n// ::testing::Test>() here to get the type ID of testing::Test.  This\n// is to work around a suspected linker bug when using Google Test as\n// a framework on Mac OS X.  The bug causes GetTypeId<\n// ::testing::Test>() to return different values depending on whether\n// the call is from the Google Test framework itself or from user test\n// code.  GetTestTypeId() is guaranteed to always return the same\n// value, as it always calls GetTypeId<>() from the Google Test\n// framework.\n#define GTEST_TEST(test_suite_name, test_name)             \\\n  GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \\\n              ::testing::internal::GetTestTypeId())\n\n// Define this macro to 1 to omit the definition of TEST(), which\n// is a generic name and clashes with some other libraries.\n#if !(defined(GTEST_DONT_DEFINE_TEST) && GTEST_DONT_DEFINE_TEST)\n#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)\n#endif\n\n// Defines a test that uses a test fixture.\n//\n// The first parameter is the name of the test fixture class, which\n// also doubles as the test suite name.  The second parameter is the\n// name of the test within the test suite.\n//\n// A test fixture class must be declared earlier.  The user should put\n// the test code between braces after using this macro.  Example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     void SetUp() override { b_.AddElement(3); }\n//\n//     Foo a_;\n//     Foo b_;\n//   };\n//\n//   TEST_F(FooTest, InitializesCorrectly) {\n//     EXPECT_TRUE(a_.StatusIsOK());\n//   }\n//\n//   TEST_F(FooTest, ReturnsElementCountCorrectly) {\n//     EXPECT_EQ(a_.size(), 0);\n//     EXPECT_EQ(b_.size(), 1);\n//   }\n#define GTEST_TEST_F(test_fixture, test_name)        \\\n  GTEST_TEST_(test_fixture, test_name, test_fixture, \\\n              ::testing::internal::GetTypeId<test_fixture>())\n#if !(defined(GTEST_DONT_DEFINE_TEST_F) && GTEST_DONT_DEFINE_TEST_F)\n#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name)\n#endif\n\n// Returns a path to a temporary directory, which should be writable. It is\n// implementation-dependent whether or not the path is terminated by the\n// directory-separator character.\nGTEST_API_ std::string TempDir();\n\n// Returns a path to a directory that contains ancillary data files that might\n// be used by tests. It is implementation dependent whether or not the path is\n// terminated by the directory-separator character. The directory and the files\n// in it should be considered read-only.\nGTEST_API_ std::string SrcDir();\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4805 4100\n\n// Dynamically registers a test with the framework.\n//\n// This is an advanced API only to be used when the `TEST` macros are\n// insufficient. The macros should be preferred when possible, as they avoid\n// most of the complexity of calling this function.\n//\n// The `factory` argument is a factory callable (move-constructible) object or\n// function pointer that creates a new instance of the Test object. It\n// handles ownership to the caller. The signature of the callable is\n// `Fixture*()`, where `Fixture` is the test fixture class for the test. All\n// tests registered with the same `test_suite_name` must return the same\n// fixture type. This is checked at runtime.\n//\n// The framework will infer the fixture class from the factory and will call\n// the `SetUpTestSuite` and `TearDownTestSuite` for it.\n//\n// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is\n// undefined.\n//\n// Use case example:\n//\n// class MyFixture : public ::testing::Test {\n//  public:\n//   // All of these optional, just like in regular macro usage.\n//   static void SetUpTestSuite() { ... }\n//   static void TearDownTestSuite() { ... }\n//   void SetUp() override { ... }\n//   void TearDown() override { ... }\n// };\n//\n// class MyTest : public MyFixture {\n//  public:\n//   explicit MyTest(int data) : data_(data) {}\n//   void TestBody() override { ... }\n//\n//  private:\n//   int data_;\n// };\n//\n// void RegisterMyTests(const std::vector<int>& values) {\n//   for (int v : values) {\n//     ::testing::RegisterTest(\n//         \"MyFixture\", (\"Test\" + std::to_string(v)).c_str(), nullptr,\n//         std::to_string(v).c_str(),\n//         __FILE__, __LINE__,\n//         // Important to use the fixture type as the return type here.\n//         [=]() -> MyFixture* { return new MyTest(v); });\n//   }\n// }\n// ...\n// int main(int argc, char** argv) {\n//   ::testing::InitGoogleTest(&argc, argv);\n//   std::vector<int> values_to_test = LoadValuesFromConfig();\n//   RegisterMyTests(values_to_test);\n//   ...\n//   return RUN_ALL_TESTS();\n// }\n//\ntemplate <int&... ExplicitParameterBarrier, typename Factory>\nTestInfo* RegisterTest(const char* test_suite_name, const char* test_name,\n                       const char* type_param, const char* value_param,\n                       const char* file, int line, Factory factory) {\n  using TestT = typename std::remove_pointer<decltype(factory())>::type;\n\n  class FactoryImpl : public internal::TestFactoryBase {\n   public:\n    explicit FactoryImpl(Factory f) : factory_(std::move(f)) {}\n    Test* CreateTest() override { return factory_(); }\n\n   private:\n    Factory factory_;\n  };\n\n  return internal::MakeAndRegisterTestInfo(\n      test_suite_name, test_name, type_param, value_param,\n      internal::CodeLocation(file, line), internal::GetTypeId<TestT>(),\n      internal::SuiteApiResolver<TestT>::GetSetUpCaseOrSuite(file, line),\n      internal::SuiteApiResolver<TestT>::GetTearDownCaseOrSuite(file, line),\n      new FactoryImpl{std::move(factory)});\n}\n\n}  // namespace testing\n\n// Use this function in main() to run all tests.  It returns 0 if all\n// tests are successful, or 1 otherwise.\n//\n// RUN_ALL_TESTS() should be invoked after the command line has been\n// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any\n// installed environments and should only be called once per binary.\n//\n// This function was formerly a macro; thus, it is in the global\n// namespace and has an all-caps name.\nint RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;\n\ninline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); }\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest_pred_impl.h",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Implements a family of generic predicate assertion macros.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n\n#include \"gtest/gtest-assertion-result.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// This header implements a family of generic predicate assertion\n// macros:\n//\n//   ASSERT_PRED_FORMAT1(pred_format, v1)\n//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)\n//   ...\n//\n// where pred_format is a function or functor that takes n (in the\n// case of ASSERT_PRED_FORMATn) values and their source expression\n// text, and returns a testing::AssertionResult.  See the definition\n// of ASSERT_EQ in gtest.h for an example.\n//\n// If you don't care about formatting, you can use the more\n// restrictive version:\n//\n//   ASSERT_PRED1(pred, v1)\n//   ASSERT_PRED2(pred, v1, v2)\n//   ...\n//\n// where pred is an n-ary function or functor that returns bool,\n// and the values v1, v2, ..., must support the << operator for\n// streaming to std::ostream.\n//\n// We also define the EXPECT_* variations.\n//\n// For now we only support predicates whose arity is at most 5.\n// Please email googletestframework@googlegroups.com if you need\n// support for higher arities.\n\n// GTEST_ASSERT_ is the basic statement to which all of the assertions\n// in this file reduce.  Don't use this in your code.\n\n#define GTEST_ASSERT_(expression, on_failure)                   \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                 \\\n  if (const ::testing::AssertionResult gtest_ar = (expression)) \\\n    ;                                                           \\\n  else                                                          \\\n    on_failure(gtest_ar.failure_message())\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1>\nAssertionResult AssertPred1Helper(const char* pred_text, const char* e1,\n                                  Pred pred, const T1& v1) {\n  if (pred(v1)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, v1), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\n#define GTEST_PRED1_(pred, v1, on_failure) \\\n  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)\n\n// Unary predicate assertion macros.\n#define EXPECT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2>\nAssertionResult AssertPred2Helper(const char* pred_text, const char* e1,\n                                  const char* e2, Pred pred, const T1& v1,\n                                  const T2& v2) {\n  if (pred(v1, v2)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\n#define GTEST_PRED2_(pred, v1, v2, on_failure)                               \\\n  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \\\n                on_failure)\n\n// Binary predicate assertion macros.\n#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3>\nAssertionResult AssertPred3Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3, Pred pred,\n                                  const T1& v1, const T2& v2, const T3& v3) {\n  if (pred(v1, v2, v3)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\n#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)                          \\\n  GTEST_ASSERT_(                                                            \\\n      ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \\\n      on_failure)\n\n// Ternary predicate assertion macros.\n#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3, typename T4>\nAssertionResult AssertPred4Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3,\n                                  const char* e4, Pred pred, const T1& v1,\n                                  const T2& v2, const T3& v3, const T4& v4) {\n  if (pred(v1, v2, v3, v4)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3 << \", \" << e4\n         << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3) << \"\\n\"\n         << e4 << \" evaluates to \" << ::testing::PrintToString(v4);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\n#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)                        \\\n  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \\\n                                             v1, v2, v3, v4),                 \\\n                on_failure)\n\n// 4-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\ntemplate <typename Pred, typename T1, typename T2, typename T3, typename T4,\n          typename T5>\nAssertionResult AssertPred5Helper(const char* pred_text, const char* e1,\n                                  const char* e2, const char* e3,\n                                  const char* e4, const char* e5, Pred pred,\n                                  const T1& v1, const T2& v2, const T3& v3,\n                                  const T4& v4, const T5& v5) {\n  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();\n\n  return AssertionFailure()\n         << pred_text << \"(\" << e1 << \", \" << e2 << \", \" << e3 << \", \" << e4\n         << \", \" << e5 << \") evaluates to false, where\"\n         << \"\\n\"\n         << e1 << \" evaluates to \" << ::testing::PrintToString(v1) << \"\\n\"\n         << e2 << \" evaluates to \" << ::testing::PrintToString(v2) << \"\\n\"\n         << e3 << \" evaluates to \" << ::testing::PrintToString(v3) << \"\\n\"\n         << e4 << \" evaluates to \" << ::testing::PrintToString(v4) << \"\\n\"\n         << e5 << \" evaluates to \" << ::testing::PrintToString(v5);\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)  \\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\n#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)                   \\\n  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \\\n                                             pred, v1, v2, v3, v4, v5),      \\\n                on_failure)\n\n// 5-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/gtest_prod.h",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google C++ Testing and Mocking Framework definitions useful in production\n// code.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n\n// When you need to test the private or protected members of a class,\n// use the FRIEND_TEST macro to declare your tests as friends of the\n// class.  For example:\n//\n// class MyClass {\n//  private:\n//   void PrivateMethod();\n//   FRIEND_TEST(MyClassTest, PrivateMethodWorks);\n// };\n//\n// class MyClassTest : public testing::Test {\n//   // ...\n// };\n//\n// TEST_F(MyClassTest, PrivateMethodWorks) {\n//   // Can call MyClass::PrivateMethod() here.\n// }\n//\n// Note: The test class must be in the same namespace as the class being tested.\n// For example, putting MyClassTest in an anonymous namespace will not work.\n\n#define FRIEND_TEST(test_case_name, test_name) \\\n  friend class test_case_name##_##test_name##_Test\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/custom/README.md",
    "content": "# Customization Points\n\nThe custom directory is an injection point for custom user configurations.\n\n## Header `gtest.h`\n\n### The following macros can be defined:\n\n*   `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of\n    `OsStackTraceGetterInterface`.\n*   `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See\n    `testing::TempDir` for semantics and signature.\n\n## Header `gtest-port.h`\n\nThe following macros can be defined:\n\n### Logging:\n\n*   `GTEST_LOG_(severity)`\n*   `GTEST_CHECK_(condition)`\n*   Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.\n\n### Threading:\n\n*   `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.\n*   `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`\n    are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`\n    and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`\n*   `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`\n*   `GTEST_LOCK_EXCLUDED_(locks)`\n\n### Underlying library support features\n\n*   `GTEST_HAS_CXXABI_H_`\n\n### Exporting API symbols:\n\n*   `GTEST_API_` - Specifier for exported symbols.\n\n## Header `gtest-printers.h`\n\n*   See documentation at `gtest/gtest-printers.h` for details on how to define a\n    custom printer.\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/custom/gtest-port.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/custom/gtest-printers.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// This file provides an injection point for custom printers in a local\n// installation of gTest.\n// It will be included from gtest-printers.h and the overrides in this file\n// will be visible to everyone.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/custom/gtest.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Injection point for custom user configurations. See README for details\n//\n// ** Custom implementation starts here **\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines internal utilities needed for implementing\n// death tests.  They are subject to change without notice.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n\n#include <stdio.h>\n\n#include <memory>\n#include <string>\n\n#include \"gtest/gtest-matchers.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nGTEST_DECLARE_string_(internal_run_death_test);\n\nnamespace testing {\nnamespace internal {\n\n// Name of the flag (needed for parsing Google Test flag).\nconst char kInternalRunDeathTestFlag[] = \"internal_run_death_test\";\n\n// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads\n// and interpreted as a regex (rather than an Eq matcher) for legacy\n// compatibility.\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    ::testing::internal::RE regex) {\n  return ContainsRegex(regex.pattern());\n}\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {\n  return ContainsRegex(regex);\n}\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    const ::std::string& regex) {\n  return ContainsRegex(regex);\n}\n\n// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's\n// used directly.\ninline Matcher<const ::std::string&> MakeDeathTestMatcher(\n    Matcher<const ::std::string&> matcher) {\n  return matcher;\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// DeathTest is a class that hides much of the complexity of the\n// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method\n// returns a concrete class that depends on the prevailing death test\n// style, as defined by the --gtest_death_test_style and/or\n// --gtest_internal_run_death_test flags.\n\n// In describing the results of death tests, these terms are used with\n// the corresponding definitions:\n//\n// exit status:  The integer exit information in the format specified\n//               by wait(2)\n// exit code:    The integer code passed to exit(3), _Exit(2), or\n//               returned from main()\nclass GTEST_API_ DeathTest {\n public:\n  // Create returns false if there was an error determining the\n  // appropriate action to take for the current death test; for example,\n  // if the gtest_death_test_style flag is set to an invalid value.\n  // The LastMessage method will return a more detailed message in that\n  // case.  Otherwise, the DeathTest pointer pointed to by the \"test\"\n  // argument is set.  If the death test should be skipped, the pointer\n  // is set to NULL; otherwise, it is set to the address of a new concrete\n  // DeathTest object that controls the execution of the current test.\n  static bool Create(const char* statement, Matcher<const std::string&> matcher,\n                     const char* file, int line, DeathTest** test);\n  DeathTest();\n  virtual ~DeathTest() = default;\n\n  // A helper class that aborts a death test when it's deleted.\n  class ReturnSentinel {\n   public:\n    explicit ReturnSentinel(DeathTest* test) : test_(test) {}\n    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }\n\n   private:\n    DeathTest* const test_;\n    ReturnSentinel(const ReturnSentinel&) = delete;\n    ReturnSentinel& operator=(const ReturnSentinel&) = delete;\n  };\n\n  // An enumeration of possible roles that may be taken when a death\n  // test is encountered.  EXECUTE means that the death test logic should\n  // be executed immediately.  OVERSEE means that the program should prepare\n  // the appropriate environment for a child process to execute the death\n  // test, then wait for it to complete.\n  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };\n\n  // An enumeration of the three reasons that a test might be aborted.\n  enum AbortReason {\n    TEST_ENCOUNTERED_RETURN_STATEMENT,\n    TEST_THREW_EXCEPTION,\n    TEST_DID_NOT_DIE\n  };\n\n  // Assumes one of the above roles.\n  virtual TestRole AssumeRole() = 0;\n\n  // Waits for the death test to finish and returns its status.\n  virtual int Wait() = 0;\n\n  // Returns true if the death test passed; that is, the test process\n  // exited during the test, its exit status matches a user-supplied\n  // predicate, and its stderr output matches a user-supplied regular\n  // expression.\n  // The user-supplied predicate may be a macro expression rather\n  // than a function pointer or functor, or else Wait and Passed could\n  // be combined.\n  virtual bool Passed(bool exit_status_ok) = 0;\n\n  // Signals that the death test did not die as expected.\n  virtual void Abort(AbortReason reason) = 0;\n\n  // Returns a human-readable outcome message regarding the outcome of\n  // the last death test.\n  static const char* LastMessage();\n\n  static void set_last_death_test_message(const std::string& message);\n\n private:\n  // A string containing a description of the outcome of the last death test.\n  static std::string last_death_test_message_;\n\n  DeathTest(const DeathTest&) = delete;\n  DeathTest& operator=(const DeathTest&) = delete;\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Factory interface for death tests.  May be mocked out for testing.\nclass DeathTestFactory {\n public:\n  virtual ~DeathTestFactory() = default;\n  virtual bool Create(const char* statement,\n                      Matcher<const std::string&> matcher, const char* file,\n                      int line, DeathTest** test) = 0;\n};\n\n// A concrete DeathTestFactory implementation for normal use.\nclass DefaultDeathTestFactory : public DeathTestFactory {\n public:\n  bool Create(const char* statement, Matcher<const std::string&> matcher,\n              const char* file, int line, DeathTest** test) override;\n};\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nGTEST_API_ bool ExitedUnsuccessfully(int exit_status);\n\n// Traps C++ exceptions escaping statement and reports them as test\n// failures. Note that trapping SEH exceptions is not implemented here.\n#if GTEST_HAS_EXCEPTIONS\n#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test)           \\\n  try {                                                                      \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);               \\\n  } catch (const ::std::exception& gtest_exception) {                        \\\n    fprintf(                                                                 \\\n        stderr,                                                              \\\n        \"\\n%s: Caught std::exception-derived exception escaping the \"        \\\n        \"death test statement. Exception message: %s\\n\",                     \\\n        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \\\n        gtest_exception.what());                                             \\\n    fflush(stderr);                                                          \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  } catch (...) {                                                            \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  }\n\n#else\n#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\n  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n\n#endif\n\n// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,\n// ASSERT_EXIT*, and EXPECT_EXIT*.\n#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail)        \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                \\\n  if (::testing::internal::AlwaysTrue()) {                                     \\\n    ::testing::internal::DeathTest* gtest_dt;                                  \\\n    if (!::testing::internal::DeathTest::Create(                               \\\n            #statement,                                                        \\\n            ::testing::internal::MakeDeathTestMatcher(regex_or_matcher),       \\\n            __FILE__, __LINE__, &gtest_dt)) {                                  \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                        \\\n    }                                                                          \\\n    if (gtest_dt != nullptr) {                                                 \\\n      std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \\\n      switch (gtest_dt->AssumeRole()) {                                        \\\n        case ::testing::internal::DeathTest::OVERSEE_TEST:                     \\\n          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) {                \\\n            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                  \\\n          }                                                                    \\\n          break;                                                               \\\n        case ::testing::internal::DeathTest::EXECUTE_TEST: {                   \\\n          const ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \\\n              gtest_dt);                                                       \\\n          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt);            \\\n          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE);   \\\n          break;                                                               \\\n        }                                                                      \\\n      }                                                                        \\\n    }                                                                          \\\n  } else                                                                       \\\n    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__)                                \\\n        : fail(::testing::internal::DeathTest::LastMessage())\n// The symbol \"fail\" here expands to something into which a message\n// can be streamed.\n\n// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in\n// NDEBUG mode. In this case we need the statements to be executed and the macro\n// must accept a streamed message even though the message is never printed.\n// The regex object is not evaluated, but it is used to prevent \"unused\"\n// warnings and to avoid an expression that doesn't compile in debug mode.\n#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher)    \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                  \\\n  if (::testing::internal::AlwaysTrue()) {                       \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);   \\\n  } else if (!::testing::internal::AlwaysTrue()) {               \\\n    ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \\\n  } else                                                         \\\n    ::testing::Message()\n\n// A class representing the parsed contents of the\n// --gtest_internal_run_death_test flag, as it existed when\n// RUN_ALL_TESTS was called.\nclass InternalRunDeathTestFlag {\n public:\n  InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,\n                           int a_write_fd)\n      : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}\n\n  ~InternalRunDeathTestFlag() {\n    if (write_fd_ >= 0) posix::Close(write_fd_);\n  }\n\n  const std::string& file() const { return file_; }\n  int line() const { return line_; }\n  int index() const { return index_; }\n  int write_fd() const { return write_fd_; }\n\n private:\n  std::string file_;\n  int line_;\n  int index_;\n  int write_fd_;\n\n  InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;\n  InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;\n};\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-filepath.h",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test filepath utilities\n//\n// This header file declares classes and functions used internally by\n// Google Test.  They are subject to change without notice.\n//\n// This file is #included in gtest/internal/gtest-internal.h.\n// Do not include this header file separately!\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n\n#include <string>\n#include <utility>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"gtest/internal/gtest-string.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n#if GTEST_HAS_FILE_SYSTEM\n\nnamespace testing {\nnamespace internal {\n\n// FilePath - a class for file and directory pathname manipulation which\n// handles platform-specific conventions (like the pathname separator).\n// Used for helper functions for naming files in a directory for xml output.\n// Except for Set methods, all methods are const or static, which provides an\n// \"immutable value object\" -- useful for peace of mind.\n// A FilePath with a value ending in a path separator (\"like/this/\") represents\n// a directory, otherwise it is assumed to represent a file. In either case,\n// it may or may not represent an actual file or directory in the file system.\n// Names are NOT checked for syntax correctness -- no checking for illegal\n// characters, malformed paths, etc.\n\nclass GTEST_API_ FilePath {\n public:\n  FilePath() : pathname_(\"\") {}\n  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}\n  FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}\n\n  explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {\n    Normalize();\n  }\n\n  FilePath& operator=(const FilePath& rhs) {\n    Set(rhs);\n    return *this;\n  }\n  FilePath& operator=(FilePath&& rhs) noexcept {\n    pathname_ = std::move(rhs.pathname_);\n    return *this;\n  }\n\n  void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }\n\n  const std::string& string() const { return pathname_; }\n  const char* c_str() const { return pathname_.c_str(); }\n\n  // Returns the current working directory, or \"\" if unsuccessful.\n  static FilePath GetCurrentDir();\n\n  // Given directory = \"dir\", base_name = \"test\", number = 0,\n  // extension = \"xml\", returns \"dir/test.xml\". If number is greater\n  // than zero (e.g., 12), returns \"dir/test_12.xml\".\n  // On Windows platform, uses \\ as the separator rather than /.\n  static FilePath MakeFileName(const FilePath& directory,\n                               const FilePath& base_name, int number,\n                               const char* extension);\n\n  // Given directory = \"dir\", relative_path = \"test.xml\",\n  // returns \"dir/test.xml\".\n  // On Windows, uses \\ as the separator rather than /.\n  static FilePath ConcatPaths(const FilePath& directory,\n                              const FilePath& relative_path);\n\n  // Returns a pathname for a file that does not currently exist. The pathname\n  // will be directory/base_name.extension or\n  // directory/base_name_<number>.extension if directory/base_name.extension\n  // already exists. The number will be incremented until a pathname is found\n  // that does not already exist.\n  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n  // There could be a race condition if two or more processes are calling this\n  // function at the same time -- they could both pick the same filename.\n  static FilePath GenerateUniqueFileName(const FilePath& directory,\n                                         const FilePath& base_name,\n                                         const char* extension);\n\n  // Returns true if and only if the path is \"\".\n  bool IsEmpty() const { return pathname_.empty(); }\n\n  // If input name has a trailing separator character, removes it and returns\n  // the name, otherwise return the name string unmodified.\n  // On Windows platform, uses \\ as the separator, other platforms use /.\n  FilePath RemoveTrailingPathSeparator() const;\n\n  // Returns a copy of the FilePath with the directory part removed.\n  // Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n  // FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n  // the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n  // returns an empty FilePath (\"\").\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveDirectoryName() const;\n\n  // RemoveFileName returns the directory path with the filename removed.\n  // Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n  // If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n  // FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n  // not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveFileName() const;\n\n  // Returns a copy of the FilePath with the case-insensitive extension removed.\n  // Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n  // FilePath(\"dir/file\"). If a case-insensitive extension is not\n  // found, returns a copy of the original FilePath.\n  FilePath RemoveExtension(const char* extension) const;\n\n  // Creates directories so that path exists. Returns true if successful or if\n  // the directories already exist; returns false if unable to create\n  // directories for any reason. Will also return false if the FilePath does\n  // not represent a directory (that is, it doesn't end with a path separator).\n  bool CreateDirectoriesRecursively() const;\n\n  // Create the directory so that path exists. Returns true if successful or\n  // if the directory already exists; returns false if unable to create the\n  // directory for any reason, including if the parent directory does not\n  // exist. Not named \"CreateDirectory\" because that's a macro on Windows.\n  bool CreateFolder() const;\n\n  // Returns true if FilePath describes something in the file-system,\n  // either a file, directory, or whatever, and that something exists.\n  bool FileOrDirectoryExists() const;\n\n  // Returns true if pathname describes a directory in the file-system\n  // that exists.\n  bool DirectoryExists() const;\n\n  // Returns true if FilePath ends with a path separator, which indicates that\n  // it is intended to represent a directory. Returns false otherwise.\n  // This does NOT check that a directory (or file) actually exists.\n  bool IsDirectory() const;\n\n  // Returns true if pathname describes a root directory. (Windows has one\n  // root directory per disk drive.)\n  bool IsRootDirectory() const;\n\n  // Returns true if pathname describes an absolute path.\n  bool IsAbsolutePath() const;\n\n private:\n  // Replaces multiple consecutive separators with a single separator.\n  // For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n  // redundancies that might be in a pathname involving \".\" or \"..\".\n  //\n  // A pathname with multiple consecutive separators may occur either through\n  // user error or as a result of some scripts or APIs that generate a pathname\n  // with a trailing separator. On other platforms the same API or script\n  // may NOT generate a pathname with a trailing \"/\". Then elsewhere that\n  // pathname may have another \"/\" and pathname components added to it,\n  // without checking for the separator already being there.\n  // The script language and operating system may allow paths like \"foo//bar\"\n  // but some of the functions in FilePath will not handle that correctly. In\n  // particular, RemoveTrailingPathSeparator() only removes one separator, and\n  // it is called in CreateDirectoriesRecursively() assuming that it will change\n  // a pathname from directory syntax (trailing separator) to filename syntax.\n  //\n  // On Windows this method also replaces the alternate path separator '/' with\n  // the primary path separator '\\\\', so that for example \"bar\\\\/\\\\foo\" becomes\n  // \"bar\\\\foo\".\n\n  void Normalize();\n\n  // Returns a pointer to the last occurrence of a valid path separator in\n  // the FilePath. On Windows, for example, both '/' and '\\' are valid path\n  // separators. Returns NULL if no path separator was found.\n  const char* FindLastPathSeparator() const;\n\n  // Returns the length of the path root, including the directory separator at\n  // the end of the prefix. Returns zero by definition if the path is relative.\n  // Examples:\n  // - [Windows] \"..\\Sibling\" => 0\n  // - [Windows] \"\\Windows\" => 1\n  // - [Windows] \"C:/Windows\\Notepad.exe\" => 3\n  // - [Windows] \"\\\\Host\\Share\\C$/Windows\" => 13\n  // - [UNIX] \"/bin\" => 1\n  size_t CalculateRootLength() const;\n\n  std::string pathname_;\n};  // class FilePath\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-internal.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file declares functions and macros used internally by\n// Google Test.  They are subject to change without notice.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_LINUX\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <unistd.h>\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>\n#endif\n\n#include <ctype.h>\n#include <float.h>\n#include <string.h>\n\n#include <cstdint>\n#include <functional>\n#include <limits>\n#include <map>\n#include <set>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-filepath.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"gtest/internal/gtest-type-util.h\"\n\n// Due to C++ preprocessor weirdness, we need double indirection to\n// concatenate two tokens when one of them is __LINE__.  Writing\n//\n//   foo ## __LINE__\n//\n// will result in the token foo__LINE__, instead of foo followed by\n// the current line number.  For more details, see\n// https://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6\n#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)\n#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar\n\n// Stringifies its argument.\n// Work around a bug in visual studio which doesn't accept code like this:\n//\n//   #define GTEST_STRINGIFY_(name) #name\n//   #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...\n//   MACRO(, x, y)\n//\n// Complaining about the argument to GTEST_STRINGIFY_ being empty.\n// This is allowed by the spec.\n#define GTEST_STRINGIFY_HELPER_(name, ...) #name\n#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )\n\nnamespace proto2 {\nclass MessageLite;\n}\n\nnamespace testing {\n\n// Forward declarations.\n\nclass AssertionResult;  // Result of an assertion.\nclass Message;          // Represents a failure message.\nclass Test;             // Represents a test.\nclass TestInfo;         // Information about a test.\nclass TestPartResult;   // Result of a test part.\nclass UnitTest;         // A collection of test suites.\n\ntemplate <typename T>\n::std::string PrintToString(const T& value);\n\nnamespace internal {\n\nstruct TraceInfo;    // Information about a trace point.\nclass TestInfoImpl;  // Opaque implementation of TestInfo\nclass UnitTestImpl;  // Opaque implementation of UnitTest\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nGTEST_API_ extern const char kStackTraceMarker[];\n\n// An IgnoredValue object can be implicitly constructed from ANY value.\nclass IgnoredValue {\n  struct Sink {};\n\n public:\n  // This constructor template allows any value to be implicitly\n  // converted to IgnoredValue.  The object has no data member and\n  // doesn't try to remember anything about the argument.  We\n  // deliberately omit the 'explicit' keyword in order to allow the\n  // conversion to be implicit.\n  // Disable the conversion if T already has a magical conversion operator.\n  // Otherwise we get ambiguity.\n  template <typename T,\n            typename std::enable_if<!std::is_convertible<T, Sink>::value,\n                                    int>::type = 0>\n  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)\n};\n\n// Appends the user-supplied message to the Google-Test-generated message.\nGTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,\n                                         const Message& user_msg);\n\n#if GTEST_HAS_EXCEPTIONS\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(\n    4275 /* an exported class was derived from a class that was not exported */)\n\n// This exception is thrown by (and only by) a failed Google Test\n// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions\n// are enabled).  We derive it from std::runtime_error, which is for\n// errors presumably detectable only at run time.  Since\n// std::runtime_error inherits from std::exception, many testing\n// frameworks know how to extract and print the message inside it.\nclass GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {\n public:\n  explicit GoogleTestFailureException(const TestPartResult& failure);\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4275\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\nnamespace edit_distance {\n// Returns the optimal edits to go from 'left' to 'right'.\n// All edits cost the same, with replace having lower priority than\n// add/remove.\n// Simple implementation of the Wagner-Fischer algorithm.\n// See https://en.wikipedia.org/wiki/Wagner-Fischer_algorithm\nenum EditType { kMatch, kAdd, kRemove, kReplace };\nGTEST_API_ std::vector<EditType> CalculateOptimalEdits(\n    const std::vector<size_t>& left, const std::vector<size_t>& right);\n\n// Same as above, but the input is represented as strings.\nGTEST_API_ std::vector<EditType> CalculateOptimalEdits(\n    const std::vector<std::string>& left,\n    const std::vector<std::string>& right);\n\n// Create a diff of the input strings in Unified diff format.\nGTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,\n                                         const std::vector<std::string>& right,\n                                         size_t context = 2);\n\n}  // namespace edit_distance\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   expected_expression: \"foo\"\n//   actual_expression:   \"bar\"\n//   expected_value:      \"5\"\n//   actual_value:        \"6\"\n//\n// The ignoring_case parameter is true if and only if the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\n// be inserted into the message.\nGTEST_API_ AssertionResult EqFailure(const char* expected_expression,\n                                     const char* actual_expression,\n                                     const std::string& expected_value,\n                                     const std::string& actual_value,\n                                     bool ignoring_case);\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nGTEST_API_ std::string GetBoolAssertionFailureMessage(\n    const AssertionResult& assertion_result, const char* expression_text,\n    const char* actual_predicate_value, const char* expected_predicate_value);\n\n// This template class represents an IEEE floating-point number\n// (either single-precision or double-precision, depending on the\n// template parameters).\n//\n// The purpose of this class is to do more sophisticated number\n// comparison.  (Due to round-off error, etc, it's very unlikely that\n// two floating-points will be equal exactly.  Hence a naive\n// comparison by the == operation often doesn't work.)\n//\n// Format of IEEE floating-point:\n//\n//   The most-significant bit being the leftmost, an IEEE\n//   floating-point looks like\n//\n//     sign_bit exponent_bits fraction_bits\n//\n//   Here, sign_bit is a single bit that designates the sign of the\n//   number.\n//\n//   For float, there are 8 exponent bits and 23 fraction bits.\n//\n//   For double, there are 11 exponent bits and 52 fraction bits.\n//\n//   More details can be found at\n//   https://en.wikipedia.org/wiki/IEEE_floating-point_standard.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\ntemplate <typename RawType>\nclass FloatingPoint {\n public:\n  // Defines the unsigned integer type that has the same size as the\n  // floating point number.\n  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;\n\n  // Constants.\n\n  // # of bits in a number.\n  static const size_t kBitCount = 8 * sizeof(RawType);\n\n  // # of fraction bits in a number.\n  static const size_t kFractionBitCount =\n      std::numeric_limits<RawType>::digits - 1;\n\n  // # of exponent bits in a number.\n  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;\n\n  // The mask for the sign bit.\n  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);\n\n  // The mask for the fraction bits.\n  static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>\n                                       (kExponentBitCount + 1);\n\n  // The mask for the exponent bits.\n  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);\n\n  // How many ULP's (Units in the Last Place) we want to tolerate when\n  // comparing two numbers.  The larger the value, the more error we\n  // allow.  A 0 value means that two numbers must be exactly the same\n  // to be considered equal.\n  //\n  // The maximum error of a single floating-point operation is 0.5\n  // units in the last place.  On Intel CPU's, all floating-point\n  // calculations are done with 80-bit precision, while double has 64\n  // bits.  Therefore, 4 should be enough for ordinary use.\n  //\n  // See the following article for more details on ULP:\n  // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/\n  static const uint32_t kMaxUlps = 4;\n\n  // Constructs a FloatingPoint from a raw floating-point number.\n  //\n  // On an Intel CPU, passing a non-normalized NAN (Not a Number)\n  // around may change its bits, although the new value is guaranteed\n  // to be also a NAN.  Therefore, don't expect this constructor to\n  // preserve the bits in x when x is a NAN.\n  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }\n\n  // Static methods\n\n  // Reinterprets a bit pattern as a floating-point number.\n  //\n  // This function is needed to test the AlmostEquals() method.\n  static RawType ReinterpretBits(const Bits bits) {\n    FloatingPoint fp(0);\n    fp.u_.bits_ = bits;\n    return fp.u_.value_;\n  }\n\n  // Returns the floating-point number that represent positive infinity.\n  static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }\n\n  // Non-static methods\n\n  // Returns the bits that represents this number.\n  const Bits& bits() const { return u_.bits_; }\n\n  // Returns the exponent bits of this number.\n  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }\n\n  // Returns the fraction bits of this number.\n  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }\n\n  // Returns the sign bit of this number.\n  Bits sign_bit() const { return kSignBitMask & u_.bits_; }\n\n  // Returns true if and only if this is NAN (not a number).\n  bool is_nan() const {\n    // It's a NAN if the exponent bits are all ones and the fraction\n    // bits are not entirely zeros.\n    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);\n  }\n\n  // Returns true if and only if this number is at most kMaxUlps ULP's away\n  // from rhs.  In particular, this function:\n  //\n  //   - returns false if either number is (or both are) NAN.\n  //   - treats really large numbers as almost equal to infinity.\n  //   - thinks +0.0 and -0.0 are 0 DLP's apart.\n  bool AlmostEquals(const FloatingPoint& rhs) const {\n    // The IEEE standard says that any comparison operation involving\n    // a NAN must return false.\n    if (is_nan() || rhs.is_nan()) return false;\n\n    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=\n           kMaxUlps;\n  }\n\n private:\n  // The data type used to store the actual floating-point number.\n  union FloatingPointUnion {\n    RawType value_;  // The raw floating-point number.\n    Bits bits_;      // The bits that represent the number.\n  };\n\n  // Converts an integer from the sign-and-magnitude representation to\n  // the biased representation.  More precisely, let N be 2 to the\n  // power of (kBitCount - 1), an integer x is represented by the\n  // unsigned number x + N.\n  //\n  // For instance,\n  //\n  //   -N + 1 (the most negative number representable using\n  //          sign-and-magnitude) is represented by 1;\n  //   0      is represented by N; and\n  //   N - 1  (the biggest number representable using\n  //          sign-and-magnitude) is represented by 2N - 1.\n  //\n  // Read https://en.wikipedia.org/wiki/Signed_number_representations\n  // for more details on signed number representations.\n  static Bits SignAndMagnitudeToBiased(const Bits& sam) {\n    if (kSignBitMask & sam) {\n      // sam represents a negative number.\n      return ~sam + 1;\n    } else {\n      // sam represents a positive number.\n      return kSignBitMask | sam;\n    }\n  }\n\n  // Given two numbers in the sign-and-magnitude representation,\n  // returns the distance between them as an unsigned number.\n  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,\n                                                     const Bits& sam2) {\n    const Bits biased1 = SignAndMagnitudeToBiased(sam1);\n    const Bits biased2 = SignAndMagnitudeToBiased(sam2);\n    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);\n  }\n\n  FloatingPointUnion u_;\n};\n\n// Typedefs the instances of the FloatingPoint template class that we\n// care to use.\ntypedef FloatingPoint<float> Float;\ntypedef FloatingPoint<double> Double;\n\n// In order to catch the mistake of putting tests that use different\n// test fixture classes in the same test suite, we need to assign\n// unique IDs to fixture classes and compare them.  The TypeId type is\n// used to hold such IDs.  The user should treat TypeId as an opaque\n// type: the only operation allowed on TypeId values is to compare\n// them for equality using the == operator.\ntypedef const void* TypeId;\n\ntemplate <typename T>\nclass TypeIdHelper {\n public:\n  // dummy_ must not have a const type.  Otherwise an overly eager\n  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge\n  // TypeIdHelper<T>::dummy_ for different Ts as an \"optimization\".\n  static bool dummy_;\n};\n\ntemplate <typename T>\nbool TypeIdHelper<T>::dummy_ = false;\n\n// GetTypeId<T>() returns the ID of type T.  Different values will be\n// returned for different types.  Calling the function twice with the\n// same type argument is guaranteed to return the same ID.\ntemplate <typename T>\nTypeId GetTypeId() {\n  // The compiler is required to allocate a different\n  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate\n  // the template.  Therefore, the address of dummy_ is guaranteed to\n  // be unique.\n  return &(TypeIdHelper<T>::dummy_);\n}\n\n// Returns the type ID of ::testing::Test.  Always call this instead\n// of GetTypeId< ::testing::Test>() to get the type ID of\n// ::testing::Test, as the latter may give the wrong result due to a\n// suspected linker bug when compiling Google Test as a Mac OS X\n// framework.\nGTEST_API_ TypeId GetTestTypeId();\n\n// Defines the abstract factory interface that creates instances\n// of a Test object.\nclass TestFactoryBase {\n public:\n  virtual ~TestFactoryBase() = default;\n\n  // Creates a test instance to run. The instance is both created and destroyed\n  // within TestInfoImpl::Run()\n  virtual Test* CreateTest() = 0;\n\n protected:\n  TestFactoryBase() {}\n\n private:\n  TestFactoryBase(const TestFactoryBase&) = delete;\n  TestFactoryBase& operator=(const TestFactoryBase&) = delete;\n};\n\n// This class provides implementation of TestFactoryBase interface.\n// It is used in TEST and TEST_F macros.\ntemplate <class TestClass>\nclass TestFactoryImpl : public TestFactoryBase {\n public:\n  Test* CreateTest() override { return new TestClass; }\n};\n\n#ifdef GTEST_OS_WINDOWS\n\n// Predicate-formatters for implementing the HRESULT checking macros\n// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}\n// We pass a long instead of HRESULT to avoid causing an\n// include dependency for the HRESULT type.\nGTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,\n                                            long hr);  // NOLINT\nGTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,\n                                            long hr);  // NOLINT\n\n#endif  // GTEST_OS_WINDOWS\n\n// Types of SetUpTestSuite() and TearDownTestSuite() functions.\nusing SetUpTestSuiteFunc = void (*)();\nusing TearDownTestSuiteFunc = void (*)();\n\nstruct CodeLocation {\n  CodeLocation(std::string a_file, int a_line)\n      : file(std::move(a_file)), line(a_line) {}\n\n  std::string file;\n  int line;\n};\n\n//  Helper to identify which setup function for TestCase / TestSuite to call.\n//  Only one function is allowed, either TestCase or TestSute but not both.\n\n// Utility functions to help SuiteApiResolver\nusing SetUpTearDownSuiteFuncType = void (*)();\n\ninline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(\n    SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {\n  return a == def ? nullptr : a;\n}\n\ntemplate <typename T>\n//  Note that SuiteApiResolver inherits from T because\n//  SetUpTestSuite()/TearDownTestSuite() could be protected. This way\n//  SuiteApiResolver can access them.\nstruct SuiteApiResolver : T {\n  // testing::Test is only forward declared at this point. So we make it a\n  // dependent class for the compiler to be OK with it.\n  using Test =\n      typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;\n\n  static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,\n                                                        int line_num) {\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n    SetUpTearDownSuiteFuncType test_case_fp =\n        GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);\n    SetUpTearDownSuiteFuncType test_suite_fp =\n        GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);\n\n    GTEST_CHECK_(!test_case_fp || !test_suite_fp)\n        << \"Test can not provide both SetUpTestSuite and SetUpTestCase, please \"\n           \"make sure there is only one present at \"\n        << filename << \":\" << line_num;\n\n    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;\n#else\n    (void)(filename);\n    (void)(line_num);\n    return &T::SetUpTestSuite;\n#endif\n  }\n\n  static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,\n                                                           int line_num) {\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n    SetUpTearDownSuiteFuncType test_case_fp =\n        GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);\n    SetUpTearDownSuiteFuncType test_suite_fp =\n        GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);\n\n    GTEST_CHECK_(!test_case_fp || !test_suite_fp)\n        << \"Test can not provide both TearDownTestSuite and TearDownTestCase,\"\n           \" please make sure there is only one present at\"\n        << filename << \":\" << line_num;\n\n    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;\n#else\n    (void)(filename);\n    (void)(line_num);\n    return &T::TearDownTestSuite;\n#endif\n  }\n};\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_suite_name:  name of the test suite\n//   name:             name of the test\n//   type_param:       the name of the test's type parameter, or NULL if\n//                     this is not a typed or a type-parameterized test.\n//   value_param:      text representation of the test's value parameter,\n//                     or NULL if this is not a value-parameterized test.\n//   code_location:    code location where the test is defined\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test suite\n//   tear_down_tc:     pointer to the function that tears down the test suite\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nGTEST_API_ TestInfo* MakeAndRegisterTestInfo(\n    std::string test_suite_name, const char* name, const char* type_param,\n    const char* value_param, CodeLocation code_location,\n    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,\n    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nGTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// State of the definition of a type-parameterized test suite.\nclass GTEST_API_ TypedTestSuitePState {\n public:\n  TypedTestSuitePState() : registered_(false) {}\n\n  // Adds the given test name to defined_test_names_ and return true\n  // if the test suite hasn't been registered; otherwise aborts the\n  // program.\n  bool AddTestName(const char* file, int line, const char* case_name,\n                   const char* test_name) {\n    if (registered_) {\n      fprintf(stderr,\n              \"%s Test %s must be defined before \"\n              \"REGISTER_TYPED_TEST_SUITE_P(%s, ...).\\n\",\n              FormatFileLocation(file, line).c_str(), test_name, case_name);\n      fflush(stderr);\n      posix::Abort();\n    }\n    registered_tests_.emplace(test_name, CodeLocation(file, line));\n    return true;\n  }\n\n  bool TestExists(const std::string& test_name) const {\n    return registered_tests_.count(test_name) > 0;\n  }\n\n  const CodeLocation& GetCodeLocation(const std::string& test_name) const {\n    RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);\n    GTEST_CHECK_(it != registered_tests_.end());\n    return it->second;\n  }\n\n  // Verifies that registered_tests match the test names in\n  // defined_test_names_; returns registered_tests if successful, or\n  // aborts the program otherwise.\n  const char* VerifyRegisteredTestNames(const char* test_suite_name,\n                                        const char* file, int line,\n                                        const char* registered_tests);\n\n private:\n  typedef ::std::map<std::string, CodeLocation, std::less<>> RegisteredTestsMap;\n\n  bool registered_;\n  RegisteredTestsMap registered_tests_;\n};\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nusing TypedTestCasePState = TypedTestSuitePState;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n// Skips to the first non-space char after the first comma in 'str';\n// returns NULL if no comma is found in 'str'.\ninline const char* SkipComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  if (comma == nullptr) {\n    return nullptr;\n  }\n  while (IsSpace(*(++comma))) {\n  }\n  return comma;\n}\n\n// Returns the prefix of 'str' before the first comma in it; returns\n// the entire string if it contains no comma.\ninline std::string GetPrefixUntilComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  return comma == nullptr ? str : std::string(str, comma);\n}\n\n// Splits a given string on a given delimiter, populating a given\n// vector with the fields.\nvoid SplitString(const ::std::string& str, char delimiter,\n                 ::std::vector<::std::string>* dest);\n\n// The default argument to the template below for the case when the user does\n// not provide a name generator.\nstruct DefaultNameGenerator {\n  template <typename T>\n  static std::string GetName(int i) {\n    return StreamableToString(i);\n  }\n};\n\ntemplate <typename Provided = DefaultNameGenerator>\nstruct NameGeneratorSelector {\n  typedef Provided type;\n};\n\ntemplate <typename NameGenerator>\nvoid GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}\n\ntemplate <typename NameGenerator, typename Types>\nvoid GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {\n  result->push_back(NameGenerator::template GetName<typename Types::Head>(i));\n  GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,\n                                          i + 1);\n}\n\ntemplate <typename NameGenerator, typename Types>\nstd::vector<std::string> GenerateNames() {\n  std::vector<std::string> result;\n  GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);\n  return result;\n}\n\n// TypeParameterizedTest<Fixture, TestSel, Types>::Register()\n// registers a list of type-parameterized tests with Google Test.  The\n// return value is insignificant - we just need to return something\n// such that we can call this function in a namespace scope.\n//\n// Implementation note: The GTEST_TEMPLATE_ macro declares a template\n// template parameter.  It's defined in gtest-type-util.h.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>\nclass TypeParameterizedTest {\n public:\n  // 'index' is the index of the test in the type list 'Types'\n  // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,\n  // Types).  Valid values for 'index' are [0, N - 1] where N is the\n  // length of Types.\n  static bool Register(const char* prefix, CodeLocation code_location,\n                       const char* case_name, const char* test_names, int index,\n                       const std::vector<std::string>& type_names =\n                           GenerateNames<DefaultNameGenerator, Types>()) {\n    typedef typename Types::Head Type;\n    typedef Fixture<Type> FixtureClass;\n    typedef typename GTEST_BIND_(TestSel, Type) TestClass;\n\n    // First, registers the first type-parameterized test in the type\n    // list.\n    MakeAndRegisterTestInfo(\n        (std::string(prefix) + (prefix[0] == '\\0' ? \"\" : \"/\") + case_name +\n         \"/\" + type_names[static_cast<size_t>(index)]),\n        StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),\n        GetTypeName<Type>().c_str(),\n        nullptr,  // No value parameter.\n        code_location, GetTypeId<FixtureClass>(),\n        SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(\n            code_location.file.c_str(), code_location.line),\n        SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(\n            code_location.file.c_str(), code_location.line),\n        new TestFactoryImpl<TestClass>);\n\n    // Next, recurses (at compile time) with the tail of the type list.\n    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::\n        Register(prefix, std::move(code_location), case_name, test_names,\n                 index + 1, type_names);\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel>\nclass TypeParameterizedTest<Fixture, TestSel, internal::None> {\n public:\n  static bool Register(const char* /*prefix*/, CodeLocation,\n                       const char* /*case_name*/, const char* /*test_names*/,\n                       int /*index*/,\n                       const std::vector<std::string>& =\n                           std::vector<std::string>() /*type_names*/) {\n    return true;\n  }\n};\n\nGTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,\n                                                   CodeLocation code_location);\nGTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(\n    const char* case_name);\n\n// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()\n// registers *all combinations* of 'Tests' and 'Types' with Google\n// Test.  The return value is insignificant - we just need to return\n// something such that we can call this function in a namespace scope.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>\nclass TypeParameterizedTestSuite {\n public:\n  static bool Register(const char* prefix, CodeLocation code_location,\n                       const TypedTestSuitePState* state, const char* case_name,\n                       const char* test_names,\n                       const std::vector<std::string>& type_names =\n                           GenerateNames<DefaultNameGenerator, Types>()) {\n    RegisterTypeParameterizedTestSuiteInstantiation(case_name);\n    std::string test_name =\n        StripTrailingSpaces(GetPrefixUntilComma(test_names));\n    if (!state->TestExists(test_name)) {\n      fprintf(stderr, \"Failed to get code location for test %s.%s at %s.\",\n              case_name, test_name.c_str(),\n              FormatFileLocation(code_location.file.c_str(), code_location.line)\n                  .c_str());\n      fflush(stderr);\n      posix::Abort();\n    }\n    const CodeLocation& test_location = state->GetCodeLocation(test_name);\n\n    typedef typename Tests::Head Head;\n\n    // First, register the first test in 'Test' for each type in 'Types'.\n    TypeParameterizedTest<Fixture, Head, Types>::Register(\n        prefix, test_location, case_name, test_names, 0, type_names);\n\n    // Next, recurses (at compile time) with the tail of the test list.\n    return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,\n                                      Types>::Register(prefix,\n                                                       std::move(code_location),\n                                                       state, case_name,\n                                                       SkipComma(test_names),\n                                                       type_names);\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Types>\nclass TypeParameterizedTestSuite<Fixture, internal::None, Types> {\n public:\n  static bool Register(const char* /*prefix*/, const CodeLocation&,\n                       const TypedTestSuitePState* /*state*/,\n                       const char* /*case_name*/, const char* /*test_names*/,\n                       const std::vector<std::string>& =\n                           std::vector<std::string>() /*type_names*/) {\n    return true;\n  }\n};\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nGTEST_API_ std::string GetCurrentOsStackTraceExceptTop(int skip_count);\n\n// Helpers for suppressing warnings on unreachable code or constant\n// condition.\n\n// Always returns true.\nGTEST_API_ bool AlwaysTrue();\n\n// Always returns false.\ninline bool AlwaysFalse() { return !AlwaysTrue(); }\n\n// Helper for suppressing false warning from Clang on a const char*\n// variable declared in a conditional expression always being NULL in\n// the else branch.\nstruct GTEST_API_ ConstCharPtr {\n  ConstCharPtr(const char* str) : value(str) {}\n  operator bool() const { return true; }\n  const char* value;\n};\n\n// Helper for declaring std::string within 'if' statement\n// in pre C++17 build environment.\nstruct TrueWithString {\n  TrueWithString() = default;\n  explicit TrueWithString(const char* str) : value(str) {}\n  explicit TrueWithString(const std::string& str) : value(str) {}\n  explicit operator bool() const { return true; }\n  std::string value;\n};\n\n// A simple Linear Congruential Generator for generating random\n// numbers with a uniform distribution.  Unlike rand() and srand(), it\n// doesn't use global state (and therefore can't interfere with user\n// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,\n// but it's good enough for our purposes.\nclass GTEST_API_ Random {\n public:\n  static const uint32_t kMaxRange = 1u << 31;\n\n  explicit Random(uint32_t seed) : state_(seed) {}\n\n  void Reseed(uint32_t seed) { state_ = seed; }\n\n  // Generates a random number from [0, range).  Crashes if 'range' is\n  // 0 or greater than kMaxRange.\n  uint32_t Generate(uint32_t range);\n\n private:\n  uint32_t state_;\n  Random(const Random&) = delete;\n  Random& operator=(const Random&) = delete;\n};\n\n// Turns const U&, U&, const U, and U all into U.\n#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \\\n  typename std::remove_const<typename std::remove_reference<T>::type>::type\n\n// HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant\n// that's true if and only if T has methods DebugString() and ShortDebugString()\n// that return std::string.\ntemplate <typename T>\nclass HasDebugStringAndShortDebugString {\n private:\n  template <typename C>\n  static auto CheckDebugString(C*) -> typename std::is_same<\n      std::string, decltype(std::declval<const C>().DebugString())>::type;\n  template <typename>\n  static std::false_type CheckDebugString(...);\n\n  template <typename C>\n  static auto CheckShortDebugString(C*) -> typename std::is_same<\n      std::string, decltype(std::declval<const C>().ShortDebugString())>::type;\n  template <typename>\n  static std::false_type CheckShortDebugString(...);\n\n  using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));\n  using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));\n\n public:\n  static constexpr bool value =\n      HasDebugStringType::value && HasShortDebugStringType::value;\n};\n\n#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL\ntemplate <typename T>\nconstexpr bool HasDebugStringAndShortDebugString<T>::value;\n#endif\n\n// When the compiler sees expression IsContainerTest<C>(0), if C is an\n// STL-style container class, the first overload of IsContainerTest\n// will be viable (since both C::iterator* and C::const_iterator* are\n// valid types and NULL can be implicitly converted to them).  It will\n// be picked over the second overload as 'int' is a perfect match for\n// the type of argument 0.  If C::iterator or C::const_iterator is not\n// a valid type, the first overload is not viable, and the second\n// overload will be picked.  Therefore, we can determine whether C is\n// a container class by checking the type of IsContainerTest<C>(0).\n// The value of the expression is insignificant.\n//\n// In C++11 mode we check the existence of a const_iterator and that an\n// iterator is properly implemented for the container.\n//\n// For pre-C++11 that we look for both C::iterator and C::const_iterator.\n// The reason is that C++ injects the name of a class as a member of the\n// class itself (e.g. you can refer to class iterator as either\n// 'iterator' or 'iterator::iterator').  If we look for C::iterator\n// only, for example, we would mistakenly think that a class named\n// iterator is an STL container.\n//\n// Also note that the simpler approach of overloading\n// IsContainerTest(typename C::const_iterator*) and\n// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.\ntypedef int IsContainer;\ntemplate <class C,\n          class Iterator = decltype(::std::declval<const C&>().begin()),\n          class = decltype(::std::declval<const C&>().end()),\n          class = decltype(++::std::declval<Iterator&>()),\n          class = decltype(*::std::declval<Iterator>()),\n          class = typename C::const_iterator>\nIsContainer IsContainerTest(int /* dummy */) {\n  return 0;\n}\n\ntypedef char IsNotContainer;\ntemplate <class C>\nIsNotContainer IsContainerTest(long /* dummy */) {\n  return '\\0';\n}\n\n// Trait to detect whether a type T is a hash table.\n// The heuristic used is that the type contains an inner type `hasher` and does\n// not contain an inner type `reverse_iterator`.\n// If the container is iterable in reverse, then order might actually matter.\ntemplate <typename T>\nstruct IsHashTable {\n private:\n  template <typename U>\n  static char test(typename U::hasher*, typename U::reverse_iterator*);\n  template <typename U>\n  static int test(typename U::hasher*, ...);\n  template <typename U>\n  static char test(...);\n\n public:\n  static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);\n};\n\ntemplate <typename T>\nconst bool IsHashTable<T>::value;\n\ntemplate <typename C,\n          bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>\nstruct IsRecursiveContainerImpl;\n\ntemplate <typename C>\nstruct IsRecursiveContainerImpl<C, false> : public std::false_type {};\n\n// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to\n// obey the same inconsistencies as the IsContainerTest, namely check if\n// something is a container is relying on only const_iterator in C++11 and\n// is relying on both const_iterator and iterator otherwise\ntemplate <typename C>\nstruct IsRecursiveContainerImpl<C, true> {\n  using value_type = decltype(*std::declval<typename C::const_iterator>());\n  using type =\n      std::is_same<typename std::remove_const<\n                       typename std::remove_reference<value_type>::type>::type,\n                   C>;\n};\n\n// IsRecursiveContainer<Type> is a unary compile-time predicate that\n// evaluates whether C is a recursive container type. A recursive container\n// type is a container type whose value_type is equal to the container type\n// itself. An example for a recursive container type is\n// boost::filesystem::path, whose iterator has a value_type that is equal to\n// boost::filesystem::path.\ntemplate <typename C>\nstruct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};\n\n// Utilities for native arrays.\n\n// ArrayEq() compares two k-dimensional native arrays using the\n// elements' operator==, where k can be any integer >= 0.  When k is\n// 0, ArrayEq() degenerates into comparing a single pair of values.\n\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline bool ArrayEq(const T& lhs, const U& rhs) {\n  return lhs == rhs;\n}\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {\n  return internal::ArrayEq(lhs, N, rhs);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous ArrayEq() function, arrays with different sizes would\n// lead to different copies of the template code.\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs) {\n  for (size_t i = 0; i != size; i++) {\n    if (!internal::ArrayEq(lhs[i], rhs[i])) return false;\n  }\n  return true;\n}\n\n// Finds the first element in the iterator range [begin, end) that\n// equals elem.  Element may be a native array type itself.\ntemplate <typename Iter, typename Element>\nIter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {\n  for (Iter it = begin; it != end; ++it) {\n    if (internal::ArrayEq(*it, elem)) return it;\n  }\n  return end;\n}\n\n// CopyArray() copies a k-dimensional native array using the elements'\n// operator=, where k can be any integer >= 0.  When k is 0,\n// CopyArray() degenerates into copying a single value.\n\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline void CopyArray(const T& from, U* to) {\n  *to = from;\n}\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline void CopyArray(const T (&from)[N], U (*to)[N]) {\n  internal::CopyArray(from, N, *to);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous CopyArray() function, arrays with different sizes\n// would lead to different copies of the template code.\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to) {\n  for (size_t i = 0; i != size; i++) {\n    internal::CopyArray(from[i], to + i);\n  }\n}\n\n// The relation between an NativeArray object (see below) and the\n// native array it represents.\n// We use 2 different structs to allow non-copyable types to be used, as long\n// as RelationToSourceReference() is passed.\nstruct RelationToSourceReference {};\nstruct RelationToSourceCopy {};\n\n// Adapts a native array to a read-only STL-style container.  Instead\n// of the complete STL container concept, this adaptor only implements\n// members useful for Google Mock's container matchers.  New members\n// should be added as needed.  To simplify the implementation, we only\n// support Element being a raw type (i.e. having no top-level const or\n// reference modifier).  It's the client's responsibility to satisfy\n// this requirement.  Element can be an array type itself (hence\n// multi-dimensional arrays are supported).\ntemplate <typename Element>\nclass NativeArray {\n public:\n  // STL-style container typedefs.\n  typedef Element value_type;\n  typedef Element* iterator;\n  typedef const Element* const_iterator;\n\n  // Constructs from a native array. References the source.\n  NativeArray(const Element* array, size_t count, RelationToSourceReference) {\n    InitRef(array, count);\n  }\n\n  // Constructs from a native array. Copies the source.\n  NativeArray(const Element* array, size_t count, RelationToSourceCopy) {\n    InitCopy(array, count);\n  }\n\n  // Copy constructor.\n  NativeArray(const NativeArray& rhs) {\n    (this->*rhs.clone_)(rhs.array_, rhs.size_);\n  }\n\n  ~NativeArray() {\n    if (clone_ != &NativeArray::InitRef) delete[] array_;\n  }\n\n  // STL-style container methods.\n  size_t size() const { return size_; }\n  const_iterator begin() const { return array_; }\n  const_iterator end() const { return array_ + size_; }\n  bool operator==(const NativeArray& rhs) const {\n    return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());\n  }\n\n private:\n  static_assert(!std::is_const<Element>::value, \"Type must not be const\");\n  static_assert(!std::is_reference<Element>::value,\n                \"Type must not be a reference\");\n\n  // Initializes this object with a copy of the input.\n  void InitCopy(const Element* array, size_t a_size) {\n    Element* const copy = new Element[a_size];\n    CopyArray(array, a_size, copy);\n    array_ = copy;\n    size_ = a_size;\n    clone_ = &NativeArray::InitCopy;\n  }\n\n  // Initializes this object with a reference of the input.\n  void InitRef(const Element* array, size_t a_size) {\n    array_ = array;\n    size_ = a_size;\n    clone_ = &NativeArray::InitRef;\n  }\n\n  const Element* array_;\n  size_t size_;\n  void (NativeArray::*clone_)(const Element*, size_t);\n};\n\ntemplate <size_t>\nstruct Ignore {\n  Ignore(...);  // NOLINT\n};\n\ntemplate <typename>\nstruct ElemFromListImpl;\ntemplate <size_t... I>\nstruct ElemFromListImpl<std::index_sequence<I...>> {\n  // We make Ignore a template to solve a problem with MSVC.\n  // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but\n  // MSVC doesn't understand how to deal with that pack expansion.\n  // Use `0 * I` to have a single instantiation of Ignore.\n  template <typename R>\n  static R Apply(Ignore<0 * I>..., R (*)(), ...);\n};\n\ntemplate <size_t N, typename... T>\nstruct ElemFromList {\n  using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(\n      static_cast<T (*)()>(nullptr)...));\n};\n\nstruct FlatTupleConstructTag {};\n\ntemplate <typename... T>\nclass FlatTuple;\n\ntemplate <typename Derived, size_t I>\nstruct FlatTupleElemBase;\n\ntemplate <typename... T, size_t I>\nstruct FlatTupleElemBase<FlatTuple<T...>, I> {\n  using value_type = typename ElemFromList<I, T...>::type;\n  FlatTupleElemBase() = default;\n  template <typename Arg>\n  explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)\n      : value(std::forward<Arg>(t)) {}\n  value_type value;\n};\n\ntemplate <typename Derived, typename Idx>\nstruct FlatTupleBase;\n\ntemplate <size_t... Idx, typename... T>\nstruct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>\n    : FlatTupleElemBase<FlatTuple<T...>, Idx>... {\n  using Indices = std::index_sequence<Idx...>;\n  FlatTupleBase() = default;\n  template <typename... Args>\n  explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)\n      : FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},\n                                                std::forward<Args>(args))... {}\n\n  template <size_t I>\n  const typename ElemFromList<I, T...>::type& Get() const {\n    return FlatTupleElemBase<FlatTuple<T...>, I>::value;\n  }\n\n  template <size_t I>\n  typename ElemFromList<I, T...>::type& Get() {\n    return FlatTupleElemBase<FlatTuple<T...>, I>::value;\n  }\n\n  template <typename F>\n  auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {\n    return std::forward<F>(f)(Get<Idx>()...);\n  }\n\n  template <typename F>\n  auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {\n    return std::forward<F>(f)(Get<Idx>()...);\n  }\n};\n\n// Analog to std::tuple but with different tradeoffs.\n// This class minimizes the template instantiation depth, thus allowing more\n// elements than std::tuple would. std::tuple has been seen to require an\n// instantiation depth of more than 10x the number of elements in some\n// implementations.\n// FlatTuple and ElemFromList are not recursive and have a fixed depth\n// regardless of T...\n// std::make_index_sequence, on the other hand, it is recursive but with an\n// instantiation depth of O(ln(N)).\ntemplate <typename... T>\nclass FlatTuple\n    : private FlatTupleBase<FlatTuple<T...>,\n                            std::make_index_sequence<sizeof...(T)>> {\n  using Indices =\n      typename FlatTupleBase<FlatTuple<T...>,\n                             std::make_index_sequence<sizeof...(T)>>::Indices;\n\n public:\n  FlatTuple() = default;\n  template <typename... Args>\n  explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)\n      : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}\n\n  using FlatTuple::FlatTupleBase::Apply;\n  using FlatTuple::FlatTupleBase::Get;\n};\n\n// Utility functions to be called with static_assert to induce deprecation\n// warnings.\nGTEST_INTERNAL_DEPRECATED(\n    \"INSTANTIATE_TEST_CASE_P is deprecated, please use \"\n    \"INSTANTIATE_TEST_SUITE_P\")\nconstexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"TYPED_TEST_CASE_P is deprecated, please use \"\n    \"TYPED_TEST_SUITE_P\")\nconstexpr bool TypedTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"TYPED_TEST_CASE is deprecated, please use \"\n    \"TYPED_TEST_SUITE\")\nconstexpr bool TypedTestCaseIsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"REGISTER_TYPED_TEST_CASE_P is deprecated, please use \"\n    \"REGISTER_TYPED_TEST_SUITE_P\")\nconstexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }\n\nGTEST_INTERNAL_DEPRECATED(\n    \"INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use \"\n    \"INSTANTIATE_TYPED_TEST_SUITE_P\")\nconstexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }\n\n}  // namespace internal\n}  // namespace testing\n\nnamespace std {\n// Some standard library implementations use `struct tuple_size` and some use\n// `class tuple_size`. Clang warns about the mismatch.\n// https://reviews.llvm.org/D55466\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmismatched-tags\"\n#endif\ntemplate <typename... Ts>\nstruct tuple_size<testing::internal::FlatTuple<Ts...>>\n    : std::integral_constant<size_t, sizeof...(Ts)> {};\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n}  // namespace std\n\n#define GTEST_MESSAGE_AT_(file, line, message, result_type)             \\\n  ::testing::internal::AssertHelper(result_type, file, line, message) = \\\n      ::testing::Message()\n\n#define GTEST_MESSAGE_(message, result_type) \\\n  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)\n\n#define GTEST_FATAL_FAILURE_(message) \\\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)\n\n#define GTEST_NONFATAL_FAILURE_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)\n\n#define GTEST_SUCCESS_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)\n\n#define GTEST_SKIP_(message) \\\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)\n\n// Suppress MSVC warning 4072 (unreachable code) for the code following\n// statement if it returns or throws (or doesn't return or throw in some\n// situations).\n// NOTE: The \"else\" is important to keep this expansion to prevent a top-level\n// \"else\" from attaching to our \"if\".\n#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \\\n  if (::testing::internal::AlwaysTrue()) {                        \\\n    statement;                                                    \\\n  } else                     /* NOLINT */                         \\\n    static_assert(true, \"\")  // User must have a semicolon after expansion.\n\n#if GTEST_HAS_EXCEPTIONS\n\nnamespace testing {\nnamespace internal {\n\nclass NeverThrown {\n public:\n  const char* what() const noexcept {\n    return \"this exception should never be thrown\";\n  }\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#if GTEST_HAS_RTTI\n\n#define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))\n\n#else  // GTEST_HAS_RTTI\n\n#define GTEST_EXCEPTION_TYPE_(e) \\\n  std::string { \"an std::exception-derived error\" }\n\n#endif  // GTEST_HAS_RTTI\n\n#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)   \\\n  catch (typename std::conditional<                                            \\\n         std::is_same<typename std::remove_cv<typename std::remove_reference<  \\\n                          expected_exception>::type>::type,                    \\\n                      std::exception>::value,                                  \\\n         const ::testing::internal::NeverThrown&, const std::exception&>::type \\\n             e) {                                                              \\\n    gtest_msg.value = \"Expected: \" #statement                                  \\\n                      \" throws an exception of type \" #expected_exception      \\\n                      \".\\n  Actual: it throws \";                               \\\n    gtest_msg.value += GTEST_EXCEPTION_TYPE_(e);                               \\\n    gtest_msg.value += \" with description \\\"\";                                 \\\n    gtest_msg.value += e.what();                                               \\\n    gtest_msg.value += \"\\\".\";                                                  \\\n    goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);                \\\n  }\n\n#else  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_THROW_(statement, expected_exception, fail)              \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                             \\\n  if (::testing::internal::TrueWithString gtest_msg{}) {                    \\\n    bool gtest_caught_expected = false;                                     \\\n    try {                                                                   \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);            \\\n    } catch (expected_exception const&) {                                   \\\n      gtest_caught_expected = true;                                         \\\n    }                                                                       \\\n    GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)    \\\n    catch (...) {                                                           \\\n      gtest_msg.value = \"Expected: \" #statement                             \\\n                        \" throws an exception of type \" #expected_exception \\\n                        \".\\n  Actual: it throws a different type.\";         \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \\\n    }                                                                       \\\n    if (!gtest_caught_expected) {                                           \\\n      gtest_msg.value = \"Expected: \" #statement                             \\\n                        \" throws an exception of type \" #expected_exception \\\n                        \".\\n  Actual: it throws nothing.\";                  \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \\\n    }                                                                       \\\n  } else /*NOLINT*/                                                         \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__)                   \\\n        : fail(gtest_msg.value.c_str())\n\n#if GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()                \\\n  catch (std::exception const& e) {                               \\\n    gtest_msg.value = \"it throws \";                               \\\n    gtest_msg.value += GTEST_EXCEPTION_TYPE_(e);                  \\\n    gtest_msg.value += \" with description \\\"\";                    \\\n    gtest_msg.value += e.what();                                  \\\n    gtest_msg.value += \"\\\".\";                                     \\\n    goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \\\n  }\n\n#else  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#define GTEST_TEST_NO_THROW_(statement, fail)                            \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                          \\\n  if (::testing::internal::TrueWithString gtest_msg{}) {                 \\\n    try {                                                                \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);         \\\n    }                                                                    \\\n    GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()                           \\\n    catch (...) {                                                        \\\n      gtest_msg.value = \"it throws.\";                                    \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__);      \\\n    }                                                                    \\\n  } else                                                                 \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__)              \\\n        : fail((\"Expected: \" #statement \" doesn't throw an exception.\\n\" \\\n                \"  Actual: \" +                                           \\\n                gtest_msg.value)                                         \\\n                   .c_str())\n\n#define GTEST_TEST_ANY_THROW_(statement, fail)                       \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                      \\\n  if (::testing::internal::AlwaysTrue()) {                           \\\n    bool gtest_caught_any = false;                                   \\\n    try {                                                            \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);     \\\n    } catch (...) {                                                  \\\n      gtest_caught_any = true;                                       \\\n    }                                                                \\\n    if (!gtest_caught_any) {                                         \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \\\n    }                                                                \\\n  } else                                                             \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__)         \\\n        : fail(\"Expected: \" #statement                               \\\n               \" throws an exception.\\n\"                             \\\n               \"  Actual: it doesn't.\")\n\n// Implements Boolean test assertions such as EXPECT_TRUE. expression can be\n// either a boolean expression or an AssertionResult. text is a textual\n// representation of expression as it was passed into the EXPECT_TRUE.\n#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                       \\\n  if (const ::testing::AssertionResult gtest_ar_ =                    \\\n          ::testing::AssertionResult(expression))                     \\\n    ;                                                                 \\\n  else                                                                \\\n    fail(::testing::internal::GetBoolAssertionFailureMessage(         \\\n             gtest_ar_, text, #actual, #expected)                     \\\n             .c_str())\n\n#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail)               \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                     \\\n  if (::testing::internal::AlwaysTrue()) {                          \\\n    const ::testing::internal::HasNewFatalFailureHelper             \\\n        gtest_fatal_failure_checker;                                \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);      \\\n    if (gtest_fatal_failure_checker.has_new_fatal_failure()) {      \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \\\n    }                                                               \\\n  } else /* NOLINT */                                               \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__)         \\\n        : fail(\"Expected: \" #statement                              \\\n               \" doesn't generate new fatal \"                       \\\n               \"failures in the current thread.\\n\"                  \\\n               \"  Actual: it does.\")\n\n// Expands to the name of the class that implements the given test.\n#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \\\n  test_suite_name##_##test_name##_Test\n\n// Helper macro for defining tests.\n#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id)       \\\n  static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1,                 \\\n                \"test_suite_name must not be empty\");                          \\\n  static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1,                       \\\n                \"test_name must not be empty\");                                \\\n  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \\\n      : public parent_class {                                                  \\\n   public:                                                                     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default;            \\\n    ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default;  \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                         \\\n    (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete;     \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=(            \\\n        const GTEST_TEST_CLASS_NAME_(test_suite_name,                          \\\n                                     test_name) &) = delete; /* NOLINT */      \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                         \\\n    (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \\\n    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=(            \\\n        GTEST_TEST_CLASS_NAME_(test_suite_name,                                \\\n                               test_name) &&) noexcept = delete; /* NOLINT */  \\\n                                                                               \\\n   private:                                                                    \\\n    void TestBody() override;                                                  \\\n    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const    \\\n        test_info_;                                                            \\\n  };                                                                           \\\n                                                                               \\\n  ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,           \\\n                                                    test_name)::test_info_ =   \\\n      ::testing::internal::MakeAndRegisterTestInfo(                            \\\n          #test_suite_name, #test_name, nullptr, nullptr,                      \\\n          ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id),  \\\n          ::testing::internal::SuiteApiResolver<                               \\\n              parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__),          \\\n          ::testing::internal::SuiteApiResolver<                               \\\n              parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__),       \\\n          new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_(     \\\n              test_suite_name, test_name)>);                                   \\\n  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-param-util.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Type and function utilities for implementing parameterized tests.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n\n#include <ctype.h>\n\n#include <cassert>\n#include <iterator>\n#include <map>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-printers.h\"\n#include \"gtest/gtest-test-part.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n// Input to a parameterized test name generator, describing a test parameter.\n// Consists of the parameter value and the integer parameter index.\ntemplate <class ParamType>\nstruct TestParamInfo {\n  TestParamInfo(const ParamType& a_param, size_t an_index)\n      : param(a_param), index(an_index) {}\n  ParamType param;\n  size_t index;\n};\n\n// A builtin parameterized test name generator which returns the result of\n// testing::PrintToString.\nstruct PrintToStringParamName {\n  template <class ParamType>\n  std::string operator()(const TestParamInfo<ParamType>& info) const {\n    return PrintToString(info.param);\n  }\n};\n\nnamespace internal {\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n// Utility Functions\n\n// Outputs a message explaining invalid registration of different\n// fixture class for the same test suite. This may happen when\n// TEST_P macro is used to define two tests with the same name\n// but in different namespaces.\nGTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,\n                                           const CodeLocation& code_location);\n\ntemplate <typename>\nclass ParamGeneratorInterface;\ntemplate <typename>\nclass ParamGenerator;\n\n// Interface for iterating over elements provided by an implementation\n// of ParamGeneratorInterface<T>.\ntemplate <typename T>\nclass ParamIteratorInterface {\n public:\n  virtual ~ParamIteratorInterface() = default;\n  // A pointer to the base generator instance.\n  // Used only for the purposes of iterator comparison\n  // to make sure that two iterators belong to the same generator.\n  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;\n  // Advances iterator to point to the next element\n  // provided by the generator. The caller is responsible\n  // for not calling Advance() on an iterator equal to\n  // BaseGenerator()->End().\n  virtual void Advance() = 0;\n  // Clones the iterator object. Used for implementing copy semantics\n  // of ParamIterator<T>.\n  virtual ParamIteratorInterface* Clone() const = 0;\n  // Dereferences the current iterator and provides (read-only) access\n  // to the pointed value. It is the caller's responsibility not to call\n  // Current() on an iterator equal to BaseGenerator()->End().\n  // Used for implementing ParamGenerator<T>::operator*().\n  virtual const T* Current() const = 0;\n  // Determines whether the given iterator and other point to the same\n  // element in the sequence generated by the generator.\n  // Used for implementing ParamGenerator<T>::operator==().\n  virtual bool Equals(const ParamIteratorInterface& other) const = 0;\n};\n\n// Class iterating over elements provided by an implementation of\n// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>\n// and implements the const forward iterator concept.\ntemplate <typename T>\nclass ParamIterator {\n public:\n  typedef T value_type;\n  typedef const T& reference;\n  typedef ptrdiff_t difference_type;\n\n  // ParamIterator assumes ownership of the impl_ pointer.\n  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}\n  ParamIterator& operator=(const ParamIterator& other) {\n    if (this != &other) impl_.reset(other.impl_->Clone());\n    return *this;\n  }\n\n  const T& operator*() const { return *impl_->Current(); }\n  const T* operator->() const { return impl_->Current(); }\n  // Prefix version of operator++.\n  ParamIterator& operator++() {\n    impl_->Advance();\n    return *this;\n  }\n  // Postfix version of operator++.\n  ParamIterator operator++(int /*unused*/) {\n    ParamIteratorInterface<T>* clone = impl_->Clone();\n    impl_->Advance();\n    return ParamIterator(clone);\n  }\n  bool operator==(const ParamIterator& other) const {\n    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);\n  }\n  bool operator!=(const ParamIterator& other) const {\n    return !(*this == other);\n  }\n\n private:\n  friend class ParamGenerator<T>;\n  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}\n  std::unique_ptr<ParamIteratorInterface<T>> impl_;\n};\n\n// ParamGeneratorInterface<T> is the binary interface to access generators\n// defined in other translation units.\ntemplate <typename T>\nclass ParamGeneratorInterface {\n public:\n  typedef T ParamType;\n\n  virtual ~ParamGeneratorInterface() = default;\n\n  // Generator interface definition\n  virtual ParamIteratorInterface<T>* Begin() const = 0;\n  virtual ParamIteratorInterface<T>* End() const = 0;\n};\n\n// Wraps ParamGeneratorInterface<T> and provides general generator syntax\n// compatible with the STL Container concept.\n// This class implements copy initialization semantics and the contained\n// ParamGeneratorInterface<T> instance is shared among all copies\n// of the original object. This is possible because that instance is immutable.\ntemplate <typename T>\nclass ParamGenerator {\n public:\n  typedef ParamIterator<T> iterator;\n\n  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}\n  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}\n\n  ParamGenerator& operator=(const ParamGenerator& other) {\n    impl_ = other.impl_;\n    return *this;\n  }\n\n  iterator begin() const { return iterator(impl_->Begin()); }\n  iterator end() const { return iterator(impl_->End()); }\n\n private:\n  std::shared_ptr<const ParamGeneratorInterface<T>> impl_;\n};\n\n// Generates values from a range of two comparable values. Can be used to\n// generate sequences of user-defined types that implement operator+() and\n// operator<().\n// This class is used in the Range() function.\ntemplate <typename T, typename IncrementT>\nclass RangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  RangeGenerator(T begin, T end, IncrementT step)\n      : begin_(begin),\n        end_(end),\n        step_(step),\n        end_index_(CalculateEndIndex(begin, end, step)) {}\n  ~RangeGenerator() override = default;\n\n  ParamIteratorInterface<T>* Begin() const override {\n    return new Iterator(this, begin_, 0, step_);\n  }\n  ParamIteratorInterface<T>* End() const override {\n    return new Iterator(this, end_, end_index_, step_);\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,\n             IncrementT step)\n        : base_(base), value_(value), index_(index), step_(step) {}\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<T>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      value_ = static_cast<T>(value_ + step_);\n      index_++;\n    }\n    ParamIteratorInterface<T>* Clone() const override {\n      return new Iterator(*this);\n    }\n    const T* Current() const override { return &value_; }\n    bool Equals(const ParamIteratorInterface<T>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const int other_index =\n          CheckedDowncastToActualType<const Iterator>(&other)->index_;\n      return index_ == other_index;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : ParamIteratorInterface<T>(),\n          base_(other.base_),\n          value_(other.value_),\n          index_(other.index_),\n          step_(other.step_) {}\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<T>* const base_;\n    T value_;\n    int index_;\n    const IncrementT step_;\n  };  // class RangeGenerator::Iterator\n\n  static int CalculateEndIndex(const T& begin, const T& end,\n                               const IncrementT& step) {\n    int end_index = 0;\n    for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;\n    return end_index;\n  }\n\n  // No implementation - assignment is unsupported.\n  void operator=(const RangeGenerator& other);\n\n  const T begin_;\n  const T end_;\n  const IncrementT step_;\n  // The index for the end() iterator. All the elements in the generated\n  // sequence are indexed (0-based) to aid iterator comparison.\n  const int end_index_;\n};  // class RangeGenerator\n\n// Generates values from a pair of STL-style iterators. Used in the\n// ValuesIn() function. The elements are copied from the source range\n// since the source can be located on the stack, and the generator\n// is likely to persist beyond that stack frame.\ntemplate <typename T>\nclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  template <typename ForwardIterator>\n  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)\n      : container_(begin, end) {}\n  ~ValuesInIteratorRangeGenerator() override = default;\n\n  ParamIteratorInterface<T>* Begin() const override {\n    return new Iterator(this, container_.begin());\n  }\n  ParamIteratorInterface<T>* End() const override {\n    return new Iterator(this, container_.end());\n  }\n\n private:\n  typedef typename ::std::vector<T> ContainerType;\n\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base,\n             typename ContainerType::const_iterator iterator)\n        : base_(base), iterator_(iterator) {}\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<T>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      ++iterator_;\n      value_.reset();\n    }\n    ParamIteratorInterface<T>* Clone() const override {\n      return new Iterator(*this);\n    }\n    // We need to use cached value referenced by iterator_ because *iterator_\n    // can return a temporary object (and of type other then T), so just\n    // having \"return &*iterator_;\" doesn't work.\n    // value_ is updated here and not in Advance() because Advance()\n    // can advance iterator_ beyond the end of the range, and we cannot\n    // detect that fact. The client code, on the other hand, is\n    // responsible for not calling Current() on an out-of-range iterator.\n    const T* Current() const override {\n      if (value_.get() == nullptr) value_.reset(new T(*iterator_));\n      return value_.get();\n    }\n    bool Equals(const ParamIteratorInterface<T>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      return iterator_ ==\n             CheckedDowncastToActualType<const Iterator>(&other)->iterator_;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        // The explicit constructor call suppresses a false warning\n        // emitted by gcc when supplied with the -Wextra option.\n        : ParamIteratorInterface<T>(),\n          base_(other.base_),\n          iterator_(other.iterator_) {}\n\n    const ParamGeneratorInterface<T>* const base_;\n    typename ContainerType::const_iterator iterator_;\n    // A cached value of *iterator_. We keep it here to allow access by\n    // pointer in the wrapping iterator's operator->().\n    // value_ needs to be mutable to be accessed in Current().\n    // Use of std::unique_ptr helps manage cached value's lifetime,\n    // which is bound by the lifespan of the iterator itself.\n    mutable std::unique_ptr<const T> value_;\n  };  // class ValuesInIteratorRangeGenerator::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const ValuesInIteratorRangeGenerator& other);\n\n  const ContainerType container_;\n};  // class ValuesInIteratorRangeGenerator\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Default parameterized test name generator, returns a string containing the\n// integer test parameter index.\ntemplate <class ParamType>\nstd::string DefaultParamName(const TestParamInfo<ParamType>& info) {\n  return std::to_string(info.index);\n}\n\ntemplate <typename T = int>\nvoid TestNotEmpty() {\n  static_assert(sizeof(T) == 0, \"Empty arguments are not allowed.\");\n}\ntemplate <typename T = int>\nvoid TestNotEmpty(const T&) {}\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Stores a parameter value and later creates tests parameterized with that\n// value.\ntemplate <class TestClass>\nclass ParameterizedTestFactory : public TestFactoryBase {\n public:\n  typedef typename TestClass::ParamType ParamType;\n  explicit ParameterizedTestFactory(ParamType parameter)\n      : parameter_(parameter) {}\n  Test* CreateTest() override {\n    TestClass::SetParam(&parameter_);\n    return new TestClass();\n  }\n\n private:\n  const ParamType parameter_;\n\n  ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;\n  ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactoryBase is a base class for meta-factories that create\n// test factories for passing into MakeAndRegisterTestInfo function.\ntemplate <class ParamType>\nclass TestMetaFactoryBase {\n public:\n  virtual ~TestMetaFactoryBase() = default;\n\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactory creates test factories for passing into\n// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives\n// ownership of test factory pointer, same factory object cannot be passed\n// into that method twice. But ParameterizedTestSuiteInfo is going to call\n// it for each Test/Parameter value combination. Thus it needs meta factory\n// creator class.\ntemplate <class TestSuite>\nclass TestMetaFactory\n    : public TestMetaFactoryBase<typename TestSuite::ParamType> {\n public:\n  using ParamType = typename TestSuite::ParamType;\n\n  TestMetaFactory() = default;\n\n  TestFactoryBase* CreateTestFactory(ParamType parameter) override {\n    return new ParameterizedTestFactory<TestSuite>(parameter);\n  }\n\n private:\n  TestMetaFactory(const TestMetaFactory&) = delete;\n  TestMetaFactory& operator=(const TestMetaFactory&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteInfoBase is a generic interface\n// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase\n// accumulates test information provided by TEST_P macro invocations\n// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations\n// and uses that information to register all resulting test instances\n// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds\n// a collection of pointers to the ParameterizedTestSuiteInfo objects\n// and calls RegisterTests() on each of them when asked.\nclass ParameterizedTestSuiteInfoBase {\n public:\n  virtual ~ParameterizedTestSuiteInfoBase() = default;\n\n  // Base part of test suite name for display purposes.\n  virtual const std::string& GetTestSuiteName() const = 0;\n  // Test suite id to verify identity.\n  virtual TypeId GetTestSuiteTypeId() const = 0;\n  // UnitTest class invokes this method to register tests in this\n  // test suite right before running them in RUN_ALL_TESTS macro.\n  // This method should not be called more than once on any single\n  // instance of a ParameterizedTestSuiteInfoBase derived class.\n  virtual void RegisterTests() = 0;\n\n protected:\n  ParameterizedTestSuiteInfoBase() {}\n\n private:\n  ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =\n      delete;\n  ParameterizedTestSuiteInfoBase& operator=(\n      const ParameterizedTestSuiteInfoBase&) = delete;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Report a the name of a test_suit as safe to ignore\n// as the side effect of construction of this type.\nstruct GTEST_API_ MarkAsIgnored {\n  explicit MarkAsIgnored(const char* test_suite);\n};\n\nGTEST_API_ void InsertSyntheticTestCase(const std::string& name,\n                                        CodeLocation location, bool has_test_p);\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P\n// macro invocations for a particular test suite and generators\n// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that\n// test suite. It registers tests with all values generated by all\n// generators when asked.\ntemplate <class TestSuite>\nclass ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {\n public:\n  // ParamType and GeneratorCreationFunc are private types but are required\n  // for declarations of public methods AddTestPattern() and\n  // AddTestSuiteInstantiation().\n  using ParamType = typename TestSuite::ParamType;\n  // A function that returns an instance of appropriate generator type.\n  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();\n  using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);\n\n  explicit ParameterizedTestSuiteInfo(std::string name,\n                                      CodeLocation code_location)\n      : test_suite_name_(std::move(name)),\n        code_location_(std::move(code_location)) {}\n\n  // Test suite base name for display purposes.\n  const std::string& GetTestSuiteName() const override {\n    return test_suite_name_;\n  }\n  // Test suite id to verify identity.\n  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }\n  // TEST_P macro uses AddTestPattern() to record information\n  // about a single test in a LocalTestInfo structure.\n  // test_suite_name is the base name of the test suite (without invocation\n  // prefix). test_base_name is the name of an individual test without\n  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is\n  // test suite base name and DoBar is test base name.\n  void AddTestPattern(const char*,\n                      const char* test_base_name,\n                      TestMetaFactoryBase<ParamType>* meta_factory,\n                      CodeLocation code_location) {\n    tests_.emplace_back(\n        new TestInfo(test_base_name, meta_factory, std::move(code_location)));\n  }\n  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information\n  // about a generator.\n  int AddTestSuiteInstantiation(std::string instantiation_name,\n                                GeneratorCreationFunc* func,\n                                ParamNameGeneratorFunc* name_func,\n                                const char* file, int line) {\n    instantiations_.emplace_back(std::move(instantiation_name), func, name_func,\n                                 file, line);\n    return 0;  // Return value used only to run this method in namespace scope.\n  }\n  // UnitTest class invokes this method to register tests in this test suite\n  // right before running tests in RUN_ALL_TESTS macro.\n  // This method should not be called more than once on any single\n  // instance of a ParameterizedTestSuiteInfoBase derived class.\n  // UnitTest has a guard to prevent from calling this method more than once.\n  void RegisterTests() override {\n    bool generated_instantiations = false;\n\n    std::string test_suite_name;\n    std::string test_name;\n    for (const std::shared_ptr<TestInfo>& test_info : tests_) {\n      for (const InstantiationInfo& instantiation : instantiations_) {\n        const std::string& instantiation_name = instantiation.name;\n        ParamGenerator<ParamType> generator((*instantiation.generator)());\n        ParamNameGeneratorFunc* name_func = instantiation.name_func;\n        const char* file = instantiation.file;\n        int line = instantiation.line;\n\n        if (!instantiation_name.empty())\n          test_suite_name = instantiation_name + \"/\";\n        else\n          test_suite_name.clear();\n        test_suite_name += test_suite_name_;\n\n        size_t i = 0;\n        std::set<std::string> test_param_names;\n        for (const auto& param : generator) {\n          generated_instantiations = true;\n\n          test_name.clear();\n\n          std::string param_name =\n              name_func(TestParamInfo<ParamType>(param, i));\n\n          GTEST_CHECK_(IsValidParamName(param_name))\n              << \"Parameterized test name '\" << param_name\n              << \"' is invalid (contains spaces, dashes, or any \"\n                 \"non-alphanumeric characters other than underscores), in \"\n              << file << \" line \" << line << \"\" << std::endl;\n\n          GTEST_CHECK_(test_param_names.count(param_name) == 0)\n              << \"Duplicate parameterized test name '\" << param_name << \"', in \"\n              << file << \" line \" << line << std::endl;\n\n          if (!test_info->test_base_name.empty()) {\n            test_name.append(test_info->test_base_name).append(\"/\");\n          }\n          test_name += param_name;\n\n          test_param_names.insert(std::move(param_name));\n\n          MakeAndRegisterTestInfo(\n              test_suite_name, test_name.c_str(),\n              nullptr,  // No type parameter.\n              PrintToString(param).c_str(), test_info->code_location,\n              GetTestSuiteTypeId(),\n              SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),\n              SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),\n              test_info->test_meta_factory->CreateTestFactory(param));\n          ++i;\n        }  // for param\n      }  // for instantiation\n    }  // for test_info\n\n    if (!generated_instantiations) {\n      // There are no generaotrs, or they all generate nothing ...\n      InsertSyntheticTestCase(GetTestSuiteName(), code_location_,\n                              !tests_.empty());\n    }\n  }  // RegisterTests\n\n private:\n  // LocalTestInfo structure keeps information about a single test registered\n  // with TEST_P macro.\n  struct TestInfo {\n    TestInfo(const char* a_test_base_name,\n             TestMetaFactoryBase<ParamType>* a_test_meta_factory,\n             CodeLocation a_code_location)\n        : test_base_name(a_test_base_name),\n          test_meta_factory(a_test_meta_factory),\n          code_location(std::move(a_code_location)) {}\n\n    const std::string test_base_name;\n    const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;\n    const CodeLocation code_location;\n  };\n  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;\n  // Records data received from INSTANTIATE_TEST_SUITE_P macros:\n  //  <Instantiation name, Sequence generator creation function,\n  //     Name generator function, Source file, Source line>\n  struct InstantiationInfo {\n    InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,\n                      ParamNameGeneratorFunc* name_func_in, const char* file_in,\n                      int line_in)\n        : name(std::move(name_in)),\n          generator(generator_in),\n          name_func(name_func_in),\n          file(file_in),\n          line(line_in) {}\n\n    std::string name;\n    GeneratorCreationFunc* generator;\n    ParamNameGeneratorFunc* name_func;\n    const char* file;\n    int line;\n  };\n  typedef ::std::vector<InstantiationInfo> InstantiationContainer;\n\n  static bool IsValidParamName(const std::string& name) {\n    // Check for empty string\n    if (name.empty()) return false;\n\n    // Check for invalid characters\n    for (std::string::size_type index = 0; index < name.size(); ++index) {\n      if (!IsAlNum(name[index]) && name[index] != '_') return false;\n    }\n\n    return true;\n  }\n\n  const std::string test_suite_name_;\n  CodeLocation code_location_;\n  TestInfoContainer tests_;\n  InstantiationContainer instantiations_;\n\n  ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;\n  ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =\n      delete;\n};  // class ParameterizedTestSuiteInfo\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\ntemplate <class TestCase>\nusing ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestSuiteRegistry contains a map of\n// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P\n// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding\n// ParameterizedTestSuiteInfo descriptors.\nclass ParameterizedTestSuiteRegistry {\n public:\n  ParameterizedTestSuiteRegistry() = default;\n  ~ParameterizedTestSuiteRegistry() {\n    for (auto& test_suite_info : test_suite_infos_) {\n      delete test_suite_info;\n    }\n  }\n\n  // Looks up or creates and returns a structure containing information about\n  // tests and instantiations of a particular test suite.\n  template <class TestSuite>\n  ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(\n      std::string test_suite_name, CodeLocation code_location) {\n    ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;\n\n    auto item_it = suite_name_to_info_index_.find(test_suite_name);\n    if (item_it != suite_name_to_info_index_.end()) {\n      auto* test_suite_info = test_suite_infos_[item_it->second];\n      if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {\n        // Complain about incorrect usage of Google Test facilities\n        // and terminate the program since we cannot guaranty correct\n        // test suite setup and tear-down in this case.\n        ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);\n        posix::Abort();\n      } else {\n        // At this point we are sure that the object we found is of the same\n        // type we are looking for, so we downcast it to that type\n        // without further checks.\n        typed_test_info =\n            CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(\n                test_suite_info);\n      }\n    }\n    if (typed_test_info == nullptr) {\n      typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(\n          test_suite_name, std::move(code_location));\n      suite_name_to_info_index_.emplace(std::move(test_suite_name),\n                                        test_suite_infos_.size());\n      test_suite_infos_.push_back(typed_test_info);\n    }\n    return typed_test_info;\n  }\n  void RegisterTests() {\n    for (auto& test_suite_info : test_suite_infos_) {\n      test_suite_info->RegisterTests();\n    }\n  }\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  template <class TestCase>\n  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(\n      std::string test_case_name, CodeLocation code_location) {\n    return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),\n                                               std::move(code_location));\n  }\n\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n private:\n  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;\n\n  TestSuiteInfoContainer test_suite_infos_;\n  ::std::unordered_map<std::string, size_t> suite_name_to_info_index_;\n\n  ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =\n      delete;\n  ParameterizedTestSuiteRegistry& operator=(\n      const ParameterizedTestSuiteRegistry&) = delete;\n};\n\n// Keep track of what type-parameterized test suite are defined and\n// where as well as which are intatiated. This allows susequently\n// identifying suits that are defined but never used.\nclass TypeParameterizedTestSuiteRegistry {\n public:\n  // Add a suite definition\n  void RegisterTestSuite(const char* test_suite_name,\n                         CodeLocation code_location);\n\n  // Add an instantiation of a suit.\n  void RegisterInstantiation(const char* test_suite_name);\n\n  // For each suit repored as defined but not reported as instantiation,\n  // emit a test that reports that fact (configurably, as an error).\n  void CheckForInstantiations();\n\n private:\n  struct TypeParameterizedTestSuiteInfo {\n    explicit TypeParameterizedTestSuiteInfo(CodeLocation c)\n        : code_location(std::move(c)), instantiated(false) {}\n\n    CodeLocation code_location;\n    bool instantiated;\n  };\n\n  std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;\n};\n\n}  // namespace internal\n\n// Forward declarations of ValuesIn(), which is implemented in\n// include/gtest/gtest-param-test.h.\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container);\n\nnamespace internal {\n// Used in the Values() function to provide polymorphic capabilities.\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)\n\ntemplate <typename... Ts>\nclass ValueArray {\n public:\n  explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {  // NOLINT\n    return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));\n  }\n\n private:\n  template <typename T, size_t... I>\n  std::vector<T> MakeVector(std::index_sequence<I...>) const {\n    return std::vector<T>{static_cast<T>(v_.template Get<I>())...};\n  }\n\n  FlatTuple<Ts...> v_;\n};\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4100\n\ntemplate <typename... T>\nclass CartesianProductGenerator\n    : public ParamGeneratorInterface<::std::tuple<T...>> {\n public:\n  typedef ::std::tuple<T...> ParamType;\n\n  CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)\n      : generators_(g) {}\n  ~CartesianProductGenerator() override = default;\n\n  ParamIteratorInterface<ParamType>* Begin() const override {\n    return new Iterator(this, generators_, false);\n  }\n  ParamIteratorInterface<ParamType>* End() const override {\n    return new Iterator(this, generators_, true);\n  }\n\n private:\n  template <class I>\n  class IteratorImpl;\n  template <size_t... I>\n  class IteratorImpl<std::index_sequence<I...>>\n      : public ParamIteratorInterface<ParamType> {\n   public:\n    IteratorImpl(const ParamGeneratorInterface<ParamType>* base,\n                 const std::tuple<ParamGenerator<T>...>& generators,\n                 bool is_end)\n        : base_(base),\n          begin_(std::get<I>(generators).begin()...),\n          end_(std::get<I>(generators).end()...),\n          current_(is_end ? end_ : begin_) {\n      ComputeCurrentValue();\n    }\n    ~IteratorImpl() override = default;\n\n    const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    void Advance() override {\n      assert(!AtEnd());\n      // Advance the last iterator.\n      ++std::get<sizeof...(T) - 1>(current_);\n      // if that reaches end, propagate that up.\n      AdvanceIfEnd<sizeof...(T) - 1>();\n      ComputeCurrentValue();\n    }\n    ParamIteratorInterface<ParamType>* Clone() const override {\n      return new IteratorImpl(*this);\n    }\n\n    const ParamType* Current() const override { return current_value_.get(); }\n\n    bool Equals(const ParamIteratorInterface<ParamType>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const IteratorImpl* typed_other =\n          CheckedDowncastToActualType<const IteratorImpl>(&other);\n\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      if (AtEnd() && typed_other->AtEnd()) return true;\n\n      bool same = true;\n      bool dummy[] = {\n          (same = same && std::get<I>(current_) ==\n                              std::get<I>(typed_other->current_))...};\n      (void)dummy;\n      return same;\n    }\n\n   private:\n    template <size_t ThisI>\n    void AdvanceIfEnd() {\n      if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;\n\n      bool last = ThisI == 0;\n      if (last) {\n        // We are done. Nothing else to propagate.\n        return;\n      }\n\n      constexpr size_t NextI = ThisI - (ThisI != 0);\n      std::get<ThisI>(current_) = std::get<ThisI>(begin_);\n      ++std::get<NextI>(current_);\n      AdvanceIfEnd<NextI>();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);\n    }\n    bool AtEnd() const {\n      bool at_end = false;\n      bool dummy[] = {\n          (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};\n      (void)dummy;\n      return at_end;\n    }\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    std::tuple<typename ParamGenerator<T>::iterator...> begin_;\n    std::tuple<typename ParamGenerator<T>::iterator...> end_;\n    std::tuple<typename ParamGenerator<T>::iterator...> current_;\n    std::shared_ptr<ParamType> current_value_;\n  };\n\n  using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;\n\n  std::tuple<ParamGenerator<T>...> generators_;\n};\n\ntemplate <class... Gen>\nclass CartesianProductHolder {\n public:\n  CartesianProductHolder(const Gen&... g) : generators_(g...) {}\n  template <typename... T>\n  operator ParamGenerator<::std::tuple<T...>>() const {\n    return ParamGenerator<::std::tuple<T...>>(\n        new CartesianProductGenerator<T...>(generators_));\n  }\n\n private:\n  std::tuple<Gen...> generators_;\n};\n\ntemplate <typename From, typename To>\nclass ParamGeneratorConverter : public ParamGeneratorInterface<To> {\n public:\n  ParamGeneratorConverter(ParamGenerator<From> gen)  // NOLINT\n      : generator_(std::move(gen)) {}\n\n  ParamIteratorInterface<To>* Begin() const override {\n    return new Iterator(this, generator_.begin(), generator_.end());\n  }\n  ParamIteratorInterface<To>* End() const override {\n    return new Iterator(this, generator_.end(), generator_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<To> {\n   public:\n    Iterator(const ParamGeneratorInterface<To>* base, ParamIterator<From> it,\n             ParamIterator<From> end)\n        : base_(base), it_(it), end_(end) {\n      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));\n    }\n    ~Iterator() override = default;\n\n    const ParamGeneratorInterface<To>* BaseGenerator() const override {\n      return base_;\n    }\n    void Advance() override {\n      ++it_;\n      if (it_ != end_) value_ = std::make_shared<To>(static_cast<To>(*it_));\n    }\n    ParamIteratorInterface<To>* Clone() const override {\n      return new Iterator(*this);\n    }\n    const To* Current() const override { return value_.get(); }\n    bool Equals(const ParamIteratorInterface<To>& other) const override {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const ParamIterator<From> other_it =\n          CheckedDowncastToActualType<const Iterator>(&other)->it_;\n      return it_ == other_it;\n    }\n\n   private:\n    Iterator(const Iterator& other) = default;\n\n    const ParamGeneratorInterface<To>* const base_;\n    ParamIterator<From> it_;\n    ParamIterator<From> end_;\n    std::shared_ptr<To> value_;\n  };  // class ParamGeneratorConverter::Iterator\n\n  ParamGenerator<From> generator_;\n};  // class ParamGeneratorConverter\n\ntemplate <class Gen>\nclass ParamConverterGenerator {\n public:\n  ParamConverterGenerator(ParamGenerator<Gen> g)  // NOLINT\n      : generator_(std::move(g)) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {  // NOLINT\n    return ParamGenerator<T>(new ParamGeneratorConverter<Gen, T>(generator_));\n  }\n\n private:\n  ParamGenerator<Gen> generator_;\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-port-arch.h",
    "content": "// Copyright 2015, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file defines the GTEST_OS_* macro.\n// It is separate from gtest-port.h so that custom/gtest-port.h can include it.\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n\n// Determines the platform on which Google Test is compiled.\n#ifdef __CYGWIN__\n#define GTEST_OS_CYGWIN 1\n#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)\n#define GTEST_OS_WINDOWS_MINGW 1\n#define GTEST_OS_WINDOWS 1\n#elif defined _WIN32\n#define GTEST_OS_WINDOWS 1\n#ifdef _WIN32_WCE\n#define GTEST_OS_WINDOWS_MOBILE 1\n#elif defined(WINAPI_FAMILY)\n#include <winapifamily.h>\n#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)\n#define GTEST_OS_WINDOWS_PHONE 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)\n#define GTEST_OS_WINDOWS_RT 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)\n#define GTEST_OS_WINDOWS_PHONE 1\n#define GTEST_OS_WINDOWS_TV_TITLE 1\n#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)\n#define GTEST_OS_WINDOWS_GAMES 1\n#else\n// WINAPI_FAMILY defined but no known partition matched.\n// Default to desktop.\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#endif\n#else\n#define GTEST_OS_WINDOWS_DESKTOP 1\n#endif  // _WIN32_WCE\n#elif defined __OS2__\n#define GTEST_OS_OS2 1\n#elif defined __APPLE__\n#define GTEST_OS_MAC 1\n#include <TargetConditionals.h>\n#if TARGET_OS_IPHONE\n#define GTEST_OS_IOS 1\n#endif\n#elif defined __DragonFly__\n#define GTEST_OS_DRAGONFLY 1\n#elif defined __FreeBSD__\n#define GTEST_OS_FREEBSD 1\n#elif defined __Fuchsia__\n#define GTEST_OS_FUCHSIA 1\n#elif defined(__GNU__)\n#define GTEST_OS_GNU_HURD 1\n#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)\n#define GTEST_OS_GNU_KFREEBSD 1\n#elif defined __linux__\n#define GTEST_OS_LINUX 1\n#if defined __ANDROID__\n#define GTEST_OS_LINUX_ANDROID 1\n#endif\n#elif defined __MVS__\n#define GTEST_OS_ZOS 1\n#elif defined(__sun) && defined(__SVR4)\n#define GTEST_OS_SOLARIS 1\n#elif defined(_AIX)\n#define GTEST_OS_AIX 1\n#elif defined(__hpux)\n#define GTEST_OS_HPUX 1\n#elif defined __native_client__\n#define GTEST_OS_NACL 1\n#elif defined __NetBSD__\n#define GTEST_OS_NETBSD 1\n#elif defined __OpenBSD__\n#define GTEST_OS_OPENBSD 1\n#elif defined __QNX__\n#define GTEST_OS_QNX 1\n#elif defined(__HAIKU__)\n#define GTEST_OS_HAIKU 1\n#elif defined ESP8266\n#define GTEST_OS_ESP8266 1\n#elif defined ESP32\n#define GTEST_OS_ESP32 1\n#elif defined(__XTENSA__)\n#define GTEST_OS_XTENSA 1\n#elif defined(__hexagon__)\n#define GTEST_OS_QURT 1\n#elif defined(CPU_QN9090) || defined(CPU_QN9090HN)\n#define GTEST_OS_NXP_QN9090 1\n#elif defined(NRF52)\n#define GTEST_OS_NRF52 1\n#endif  // __CYGWIN__\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-port.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Low-level types and utilities for porting Google Test to various\n// platforms.  All macros ending with _ and symbols defined in an\n// internal namespace are subject to change without notice.  Code\n// outside Google Test MUST NOT USE THEM DIRECTLY.  Macros that don't\n// end with _ are part of Google Test's public API and can be used by\n// code outside Google Test.\n//\n// This file is fundamental to Google Test.  All other Google Test source\n// files are expected to #include this.  Therefore, it cannot #include\n// any other Google Test header.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n\n// Environment-describing macros\n// -----------------------------\n//\n// Google Test can be used in many different environments.  Macros in\n// this section tell Google Test what kind of environment it is being\n// used in, such that Google Test can provide environment-specific\n// features and implementations.\n//\n// Google Test tries to automatically detect the properties of its\n// environment, so users usually don't need to worry about these\n// macros.  However, the automatic detection is not perfect.\n// Sometimes it's necessary for a user to define some of the following\n// macros in the build script to override Google Test's decisions.\n//\n// If the user doesn't define a macro in the list, Google Test will\n// provide a default definition.  After this header is #included, all\n// macros in this list will be defined to either 1 or 0.\n//\n// Notes to maintainers:\n//   - Each macro here is a user-tweakable knob; do not grow the list\n//     lightly.\n//   - Use #if to key off these macros.  Don't use #ifdef or \"#if\n//     defined(...)\", which will not work as these macros are ALWAYS\n//     defined.\n//\n//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)\n//                              is/isn't available.\n//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions\n//                              are enabled.\n//   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular\n//                              expressions are/aren't available.\n//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>\n//                              is/isn't available.\n//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't\n//                              enabled.\n//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that\n//                              std::wstring does/doesn't work (Google Test can\n//                              be used where std::wstring is unavailable).\n//   GTEST_HAS_FILE_SYSTEM    - Define it to 1/0 to indicate whether or not a\n//                              file system is/isn't available.\n//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the\n//                              compiler supports Microsoft's \"Structured\n//                              Exception Handling\".\n//   GTEST_HAS_STREAM_REDIRECTION\n//                            - Define it to 1/0 to indicate whether the\n//                              platform supports I/O stream redirection using\n//                              dup() and dup2().\n//   GTEST_LINKED_AS_SHARED_LIBRARY\n//                            - Define to 1 when compiling tests that use\n//                              Google Test as a shared library (known as\n//                              DLL on Windows).\n//   GTEST_CREATE_SHARED_LIBRARY\n//                            - Define to 1 when compiling Google Test itself\n//                              as a shared library.\n//   GTEST_DEFAULT_DEATH_TEST_STYLE\n//                            - The default value of --gtest_death_test_style.\n//                              The legacy default has been \"fast\" in the open\n//                              source version since 2008. The recommended value\n//                              is \"threadsafe\", and can be set in\n//                              custom/gtest-port.h.\n\n// Platform-indicating macros\n// --------------------------\n//\n// Macros indicating the platform on which Google Test is being used\n// (a macro is defined to 1 if compiled on the given platform;\n// otherwise UNDEFINED -- it's never defined to 0.).  Google Test\n// defines these macros automatically.  Code outside Google Test MUST\n// NOT define them.\n//\n//   GTEST_OS_AIX      - IBM AIX\n//   GTEST_OS_CYGWIN   - Cygwin\n//   GTEST_OS_DRAGONFLY - DragonFlyBSD\n//   GTEST_OS_FREEBSD  - FreeBSD\n//   GTEST_OS_FUCHSIA  - Fuchsia\n//   GTEST_OS_GNU_HURD - GNU/Hurd\n//   GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD\n//   GTEST_OS_HAIKU    - Haiku\n//   GTEST_OS_HPUX     - HP-UX\n//   GTEST_OS_LINUX    - Linux\n//     GTEST_OS_LINUX_ANDROID - Google Android\n//   GTEST_OS_MAC      - Mac OS X\n//     GTEST_OS_IOS    - iOS\n//   GTEST_OS_NACL     - Google Native Client (NaCl)\n//   GTEST_OS_NETBSD   - NetBSD\n//   GTEST_OS_OPENBSD  - OpenBSD\n//   GTEST_OS_OS2      - OS/2\n//   GTEST_OS_QNX      - QNX\n//   GTEST_OS_SOLARIS  - Sun Solaris\n//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)\n//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop\n//     GTEST_OS_WINDOWS_MINGW    - MinGW\n//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile\n//     GTEST_OS_WINDOWS_PHONE    - Windows Phone\n//     GTEST_OS_WINDOWS_RT       - Windows Store App/WinRT\n//   GTEST_OS_ZOS      - z/OS\n//\n// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the\n// most stable support.  Since core members of the Google Test project\n// don't have access to other platforms, support for them may be less\n// stable.  If you notice any problems on your platform, please notify\n// googletestframework@googlegroups.com (patches for fixing them are\n// even more welcome!).\n//\n// It is possible that none of the GTEST_OS_* macros are defined.\n\n// Feature-indicating macros\n// -------------------------\n//\n// Macros indicating which Google Test features are available (a macro\n// is defined to 1 if the corresponding feature is supported;\n// otherwise UNDEFINED -- it's never defined to 0.).  Google Test\n// defines these macros automatically.  Code outside Google Test MUST\n// NOT define them.\n//\n// These macros are public so that portable tests can be written.\n// Such tests typically surround code using a feature with an #ifdef\n// which controls that code.  For example:\n//\n// #ifdef GTEST_HAS_DEATH_TEST\n//   EXPECT_DEATH(DoSomethingDeadly());\n// #endif\n//\n//   GTEST_HAS_DEATH_TEST   - death tests\n//   GTEST_HAS_TYPED_TEST   - typed tests\n//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests\n//   GTEST_IS_THREADSAFE    - Google Test is thread-safe.\n//   GTEST_USES_RE2         - the RE2 regular expression library is used\n//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with\n//                            GTEST_HAS_POSIX_RE (see above) which users can\n//                            define themselves.\n//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;\n//                            the above RE\\b(s) are mutually exclusive.\n//   GTEST_HAS_ABSL         - Google Test is compiled with Abseil.\n\n// Misc public macros\n// ------------------\n//\n//   GTEST_FLAG(flag_name)  - references the variable corresponding to\n//                            the given Google Test flag.\n\n// Internal utilities\n// ------------------\n//\n// The following macros and utilities are for Google Test's INTERNAL\n// use only.  Code outside Google Test MUST NOT USE THEM DIRECTLY.\n//\n// Macros for basic C++ coding:\n//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.\n//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.\n//   GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is\n//                                        suppressed (constant conditional).\n//   GTEST_INTENTIONAL_CONST_COND_POP_  - finish code section where MSVC C4127\n//                                        is suppressed.\n//   GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or\n//                            UniversalPrinter<absl::any> specializations.\n//                            Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>\n//   or\n//                                 UniversalPrinter<absl::optional>\n//                                 specializations. Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_STD_SPAN - for enabling UniversalPrinter<std::span>\n//                                 specializations. Always defined to 0 or 1\n//   GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or\n//                                    Matcher<absl::string_view>\n//                                    specializations. Always defined to 0 or 1.\n//   GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or\n//                                UniversalPrinter<absl::variant>\n//                                specializations. Always defined to 0 or 1.\n//   GTEST_USE_OWN_FLAGFILE_FLAG_ - Always defined to 0 or 1.\n//   GTEST_HAS_CXXABI_H_ - Always defined to 0 or 1.\n//   GTEST_CAN_STREAM_RESULTS_ - Always defined to 0 or 1.\n//   GTEST_HAS_ALT_PATH_SEP_ - Always defined to 0 or 1.\n//   GTEST_WIDE_STRING_USES_UTF16_ - Always defined to 0 or 1.\n//   GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Always defined to 0 or 1.\n//   GTEST_HAS_NOTIFICATION_- Always defined to 0 or 1.\n//\n// Synchronization:\n//   Mutex, MutexLock, ThreadLocal, GetThreadCount()\n//                            - synchronization primitives.\n//\n// Regular expressions:\n//   RE             - a simple regular expression class using\n//                     1) the RE2 syntax on all platforms when built with RE2\n//                        and Abseil as dependencies\n//                     2) the POSIX Extended Regular Expression syntax on\n//                        UNIX-like platforms,\n//                     3) A reduced regular exception syntax on other platforms,\n//                        including Windows.\n// Logging:\n//   GTEST_LOG_()   - logs messages at the specified severity level.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n//\n// Stdout and stderr capturing:\n//   CaptureStdout()     - starts capturing stdout.\n//   GetCapturedStdout() - stops capturing stdout and returns the captured\n//                         string.\n//   CaptureStderr()     - starts capturing stderr.\n//   GetCapturedStderr() - stops capturing stderr and returns the captured\n//                         string.\n//\n// Integer types:\n//   TypeWithSize   - maps an integer to a int type.\n//   TimeInMillis   - integers of known sizes.\n//   BiggestInt     - the biggest signed integer type.\n//\n// Command-line utilities:\n//   GetInjectableArgvs() - returns the command line as a vector of strings.\n//\n// Environment variable utilities:\n//   GetEnv()             - gets the value of an environment variable.\n//   BoolFromGTestEnv()   - parses a bool environment variable.\n//   Int32FromGTestEnv()  - parses an int32_t environment variable.\n//   StringFromGTestEnv() - parses a string environment variable.\n//\n// Deprecation warnings:\n//   GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as\n//                                        deprecated; calling a marked function\n//                                        should generate a compiler warning\n\n// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can\n// potentially be used as an #include guard.\n#if defined(_MSVC_LANG)\n#define GTEST_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG\n#elif defined(__cplusplus)\n#define GTEST_INTERNAL_CPLUSPLUS_LANG __cplusplus\n#endif\n\n#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \\\n    GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L\n#error C++ versions less than C++14 are not supported.\n#endif\n\n// MSVC >= 19.11 (VS 2017 Update 3) supports __has_include.\n#ifdef __has_include\n#define GTEST_INTERNAL_HAS_INCLUDE __has_include\n#else\n#define GTEST_INTERNAL_HAS_INCLUDE(...) 0\n#endif\n\n// Detect C++ feature test macros as gracefully as possible.\n// MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros.\n#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \\\n    (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<version>))\n#include <version>  // C++20 and later\n#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE(<ciso646>))\n#include <ciso646>  // Pre-C++20\n#endif\n\n#include <ctype.h>   // for isspace, etc\n#include <stddef.h>  // for ptrdiff_t\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cerrno>\n// #include <condition_variable>  // Guarded by GTEST_IS_THREADSAFE below\n#include <cstdint>\n#include <iostream>\n#include <limits>\n#include <locale>\n#include <memory>\n#include <ostream>\n#include <string>\n// #include <mutex>  // Guarded by GTEST_IS_THREADSAFE below\n#include <tuple>\n#include <type_traits>\n#include <vector>\n\n#ifndef _WIN32_WCE\n#include <sys/stat.h>\n#include <sys/types.h>\n#endif  // !_WIN32_WCE\n\n#if defined __APPLE__\n#include <AvailabilityMacros.h>\n#include <TargetConditionals.h>\n#endif\n\n#include \"gtest/internal/custom/gtest-port.h\"\n#include \"gtest/internal/gtest-port-arch.h\"\n\n#ifndef GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n#define GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ 0\n#endif\n\n#ifndef GTEST_HAS_NOTIFICATION_\n#define GTEST_HAS_NOTIFICATION_ 0\n#endif\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#define GTEST_INTERNAL_HAS_ABSL_FLAGS  // Used only in this file.\n#include \"absl/flags/declare.h\"\n#include \"absl/flags/flag.h\"\n#include \"absl/flags/reflection.h\"\n#endif\n\n#if !defined(GTEST_DEV_EMAIL_)\n#define GTEST_DEV_EMAIL_ \"googletestframework@@googlegroups.com\"\n#define GTEST_FLAG_PREFIX_ \"gtest_\"\n#define GTEST_FLAG_PREFIX_DASH_ \"gtest-\"\n#define GTEST_FLAG_PREFIX_UPPER_ \"GTEST_\"\n#define GTEST_NAME_ \"Google Test\"\n#define GTEST_PROJECT_URL_ \"https://github.com/google/googletest/\"\n#endif  // !defined(GTEST_DEV_EMAIL_)\n\n#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_)\n#define GTEST_INIT_GOOGLE_TEST_NAME_ \"testing::InitGoogleTest\"\n#endif  // !defined(GTEST_INIT_GOOGLE_TEST_NAME_)\n\n// Determines the version of gcc that is used to compile this.\n#ifdef __GNUC__\n// 40302 means version 4.3.2.\n#define GTEST_GCC_VER_ \\\n  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)\n#endif  // __GNUC__\n\n// Macros for disabling Microsoft Visual C++ warnings.\n//\n//   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)\n//   /* code that triggers warnings C4800 and C4385 */\n//   GTEST_DISABLE_MSC_WARNINGS_POP_()\n#if defined(_MSC_VER)\n#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \\\n  __pragma(warning(push)) __pragma(warning(disable : warnings))\n#define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop))\n#else\n// Not all compilers are MSVC\n#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)\n#define GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n// Clang on Windows does not understand MSVC's pragma warning.\n// We need clang-specific way to disable function deprecation warning.\n#ifdef __clang__\n#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_()                            \\\n  _Pragma(\"clang diagnostic push\")                                      \\\n      _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-declarations\\\"\") \\\n          _Pragma(\"clang diagnostic ignored \\\"-Wdeprecated-implementations\\\"\")\n#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma(\"clang diagnostic pop\")\n#else\n#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \\\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)\n#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()\n#endif\n\n// Brings in definitions for functions used in the testing::internal::posix\n// namespace (read, write, close, chdir, isatty, stat). We do not currently\n// use them on Windows Mobile.\n#ifdef GTEST_OS_WINDOWS\n#ifndef GTEST_OS_WINDOWS_MOBILE\n#include <direct.h>\n#include <io.h>\n#endif\n// In order to avoid having to include <windows.h>, use forward declaration\n#if defined(GTEST_OS_WINDOWS_MINGW) && !defined(__MINGW64_VERSION_MAJOR)\n// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two\n// separate (equivalent) structs, instead of using typedef\ntypedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;\n#else\n// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.\n// This assumption is verified by\n// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.\ntypedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;\n#endif\n#elif defined(GTEST_OS_XTENSA)\n#include <unistd.h>\n// Xtensa toolchains define strcasecmp in the string.h header instead of\n// strings.h. string.h is already included.\n#else\n// This assumes that non-Windows OSes provide unistd.h. For OSes where this\n// is not the case, we need to include headers that provide the functions\n// mentioned above.\n#include <strings.h>\n#include <unistd.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_LINUX_ANDROID\n// Used to define __ANDROID_API__ matching the target NDK API level.\n#include <android/api-level.h>  // NOLINT\n#endif\n\n// Defines this to true if and only if Google Test can use POSIX regular\n// expressions.\n#ifndef GTEST_HAS_POSIX_RE\n#ifdef GTEST_OS_LINUX_ANDROID\n// On Android, <regex.h> is only available starting with Gingerbread.\n#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)\n#else\n#if !(defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_XTENSA) || \\\n      defined(GTEST_OS_QURT))\n#define GTEST_HAS_POSIX_RE 1\n#else\n#define GTEST_HAS_POSIX_RE 0\n#endif\n#endif  // GTEST_OS_LINUX_ANDROID\n#endif\n\n// Select the regular expression implementation.\n#ifdef GTEST_HAS_ABSL\n// When using Abseil, RE2 is required.\n#include \"absl/strings/string_view.h\"\n#include \"re2/re2.h\"\n#define GTEST_USES_RE2 1\n#elif GTEST_HAS_POSIX_RE\n#include <regex.h>  // NOLINT\n#define GTEST_USES_POSIX_RE 1\n#else\n// Use our own simple regex implementation.\n#define GTEST_USES_SIMPLE_RE 1\n#endif\n\n#ifndef GTEST_HAS_EXCEPTIONS\n// The user didn't tell us whether exceptions are enabled, so we need\n// to figure it out.\n#if defined(_MSC_VER) && defined(_CPPUNWIND)\n// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__BORLANDC__)\n// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS\n// macro to enable exceptions, so we'll do the same.\n// Assumes that exceptions are enabled by default.\n#ifndef _HAS_EXCEPTIONS\n#define _HAS_EXCEPTIONS 1\n#endif  // _HAS_EXCEPTIONS\n#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS\n#elif defined(__clang__)\n// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang\n// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files,\n// there can be cleanups for ObjC exceptions which also need cleanups, even if\n// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which\n// checks for C++ exceptions starting at clang r206352, but which checked for\n// cleanups prior to that. To reliably check for C++ exception availability with\n// clang, check for\n// __EXCEPTIONS && __has_feature(cxx_exceptions).\n#if defined(__EXCEPTIONS) && __EXCEPTIONS && __has_feature(cxx_exceptions)\n#define GTEST_HAS_EXCEPTIONS 1\n#else\n#define GTEST_HAS_EXCEPTIONS 0\n#endif\n#elif defined(__GNUC__) && defined(__EXCEPTIONS) && __EXCEPTIONS\n// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__SUNPRO_CC)\n// Sun Pro CC supports exceptions.  However, there is no compile-time way of\n// detecting whether they are enabled or not.  Therefore, we assume that\n// they are enabled unless the user tells us otherwise.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__IBMCPP__) && defined(__EXCEPTIONS) && __EXCEPTIONS\n// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled.\n#define GTEST_HAS_EXCEPTIONS 1\n#elif defined(__HP_aCC)\n// Exception handling is in effect by default in HP aCC compiler. It has to\n// be turned of by +noeh compiler option if desired.\n#define GTEST_HAS_EXCEPTIONS 1\n#else\n// For other compilers, we assume exceptions are disabled to be\n// conservative.\n#define GTEST_HAS_EXCEPTIONS 0\n#endif  // defined(_MSC_VER) || defined(__BORLANDC__)\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#ifndef GTEST_HAS_STD_WSTRING\n// The user didn't tell us whether ::std::wstring is available, so we need\n// to figure it out.\n// Cygwin 1.7 and below doesn't support ::std::wstring.\n// Solaris' libc++ doesn't support it either.  Android has\n// no support for it at least as recent as Froyo (2.2).\n#if (!(defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_CYGWIN) || \\\n       defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) ||        \\\n       defined(GTEST_OS_ESP32) || defined(GTEST_OS_ESP8266) ||        \\\n       defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) ||          \\\n       defined(GTEST_OS_NXP_QN9090) || defined(GTEST_OS_NRF52)))\n#define GTEST_HAS_STD_WSTRING 1\n#else\n#define GTEST_HAS_STD_WSTRING 0\n#endif\n#endif  // GTEST_HAS_STD_WSTRING\n\n#ifndef GTEST_HAS_FILE_SYSTEM\n// Most platforms support a file system.\n#define GTEST_HAS_FILE_SYSTEM 1\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Determines whether RTTI is available.\n#ifndef GTEST_HAS_RTTI\n// The user didn't tell us whether RTTI is enabled, so we need to\n// figure it out.\n\n#ifdef _MSC_VER\n\n#ifdef _CPPRTTI  // MSVC defines this macro if and only if RTTI is enabled.\n#define GTEST_HAS_RTTI 1\n#else\n#define GTEST_HAS_RTTI 0\n#endif\n\n// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is\n// enabled.\n#elif defined(__GNUC__)\n\n#ifdef __GXX_RTTI\n// When building against STLport with the Android NDK and with\n// -frtti -fno-exceptions, the build fails at link time with undefined\n// references to __cxa_bad_typeid. Note sure if STL or toolchain bug,\n// so disable RTTI when detected.\n#if defined(GTEST_OS_LINUX_ANDROID) && defined(_STLPORT_MAJOR) && \\\n    !defined(__EXCEPTIONS)\n#define GTEST_HAS_RTTI 0\n#else\n#define GTEST_HAS_RTTI 1\n#endif  // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS\n#else\n#define GTEST_HAS_RTTI 0\n#endif  // __GXX_RTTI\n\n// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends\n// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the\n// first version with C++ support.\n#elif defined(__clang__)\n\n#define GTEST_HAS_RTTI __has_feature(cxx_rtti)\n\n// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if\n// both the typeid and dynamic_cast features are present.\n#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)\n\n#ifdef __RTTI_ALL__\n#define GTEST_HAS_RTTI 1\n#else\n#define GTEST_HAS_RTTI 0\n#endif\n\n#else\n\n// For all other compilers, we assume RTTI is enabled.\n#define GTEST_HAS_RTTI 1\n\n#endif  // _MSC_VER\n\n#endif  // GTEST_HAS_RTTI\n\n// It's this header's responsibility to #include <typeinfo> when RTTI\n// is enabled.\n#if GTEST_HAS_RTTI\n#include <typeinfo>\n#endif\n\n// Determines whether Google Test can use the pthreads library.\n#ifndef GTEST_HAS_PTHREAD\n// The user didn't tell us explicitly, so we make reasonable assumptions about\n// which platforms have pthreads support.\n//\n// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0\n// to your compiler flags.\n#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) ||              \\\n     defined(GTEST_OS_HPUX) || defined(GTEST_OS_QNX) ||               \\\n     defined(GTEST_OS_FREEBSD) || defined(GTEST_OS_NACL) ||           \\\n     defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) ||         \\\n     defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n     defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) ||          \\\n     defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) ||       \\\n     defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS))\n#define GTEST_HAS_PTHREAD 1\n#else\n#define GTEST_HAS_PTHREAD 0\n#endif\n#endif  // GTEST_HAS_PTHREAD\n\n#if GTEST_HAS_PTHREAD\n// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is\n// true.\n#include <pthread.h>  // NOLINT\n\n// For timespec and nanosleep, used below.\n#include <time.h>  // NOLINT\n#endif\n\n// Determines whether clone(2) is supported.\n// Usually it will only be available on Linux, excluding\n// Linux on the Itanium architecture.\n// Also see https://linux.die.net/man/2/clone.\n#ifndef GTEST_HAS_CLONE\n// The user didn't tell us, so we need to figure it out.\n\n#if defined(GTEST_OS_LINUX) && !defined(__ia64__)\n#if defined(GTEST_OS_LINUX_ANDROID)\n// On Android, clone() became available at different API levels for each 32-bit\n// architecture.\n#if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \\\n    (defined(__mips__) && __ANDROID_API__ >= 12) ||                    \\\n    (defined(__i386__) && __ANDROID_API__ >= 17)\n#define GTEST_HAS_CLONE 1\n#else\n#define GTEST_HAS_CLONE 0\n#endif\n#else\n#define GTEST_HAS_CLONE 1\n#endif\n#else\n#define GTEST_HAS_CLONE 0\n#endif  // GTEST_OS_LINUX && !defined(__ia64__)\n\n#endif  // GTEST_HAS_CLONE\n\n// Determines whether to support stream redirection. This is used to test\n// output correctness and to implement death tests.\n#ifndef GTEST_HAS_STREAM_REDIRECTION\n// By default, we assume that stream redirection is supported on all\n// platforms except known mobile / embedded ones. Also, if the port doesn't have\n// a file system, stream redirection is not supported.\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) ||     \\\n    defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) ||               \\\n    defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM\n#define GTEST_HAS_STREAM_REDIRECTION 0\n#else\n#define GTEST_HAS_STREAM_REDIRECTION 1\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\n// Determines whether to support death tests.\n// pops up a dialog window that cannot be suppressed programmatically.\n#if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) ||           \\\n     defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) ||            \\\n     (defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) ||             \\\n     (defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) ||               \\\n     defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) ||      \\\n     defined(GTEST_OS_HPUX) || defined(GTEST_OS_OPENBSD) ||           \\\n     defined(GTEST_OS_QNX) || defined(GTEST_OS_FREEBSD) ||            \\\n     defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) ||         \\\n     defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n     defined(GTEST_OS_HAIKU) || defined(GTEST_OS_GNU_HURD))\n// Death tests require a file system to work properly.\n#if GTEST_HAS_FILE_SYSTEM\n#define GTEST_HAS_DEATH_TEST 1\n#endif  // GTEST_HAS_FILE_SYSTEM\n#endif\n\n// Determines whether to support type-driven tests.\n\n// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,\n// Sun Pro CC, IBM Visual Age, and HP aCC support.\n#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \\\n    defined(__IBMCPP__) || defined(__HP_aCC)\n#define GTEST_HAS_TYPED_TEST 1\n#define GTEST_HAS_TYPED_TEST_P 1\n#endif\n\n// Determines whether the system compiler uses UTF-16 for encoding wide strings.\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \\\n    defined(GTEST_OS_AIX) || defined(GTEST_OS_OS2)\n#define GTEST_WIDE_STRING_USES_UTF16_ 1\n#else\n#define GTEST_WIDE_STRING_USES_UTF16_ 0\n#endif\n\n// Determines whether test results can be streamed to a socket.\n#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_GNU_KFREEBSD) || \\\n    defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) ||  \\\n    defined(GTEST_OS_NETBSD) || defined(GTEST_OS_OPENBSD) ||     \\\n    defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_MAC)\n#define GTEST_CAN_STREAM_RESULTS_ 1\n#else\n#define GTEST_CAN_STREAM_RESULTS_ 0\n#endif\n\n// Defines some utility macros.\n\n// The GNU compiler emits a warning if nested \"if\" statements are followed by\n// an \"else\" statement and braces are not used to explicitly disambiguate the\n// \"else\" binding.  This leads to problems with code like:\n//\n//   if (gate)\n//     ASSERT_*(condition) << \"Some message\";\n//\n// The \"switch (0) case 0:\" idiom is used to suppress this.\n#ifdef __INTEL_COMPILER\n#define GTEST_AMBIGUOUS_ELSE_BLOCKER_\n#else\n#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  switch (0)                          \\\n  case 0:                             \\\n  default:  // NOLINT\n#endif\n\n// GTEST_HAVE_ATTRIBUTE_\n//\n// A function-like feature checking macro that is a wrapper around\n// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a\n// nonzero constant integer if the attribute is supported or 0 if not.\n//\n// It evaluates to zero if `__has_attribute` is not defined by the compiler.\n//\n// GCC: https://gcc.gnu.org/gcc-5/changes.html\n// Clang: https://clang.llvm.org/docs/LanguageExtensions.html\n#ifdef __has_attribute\n#define GTEST_HAVE_ATTRIBUTE_(x) __has_attribute(x)\n#else\n#define GTEST_HAVE_ATTRIBUTE_(x) 0\n#endif\n\n// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE\n//\n// A function-like feature checking macro that accepts C++11 style attributes.\n// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6\n// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't\n// find `__has_cpp_attribute`, will evaluate to 0.\n#if defined(__has_cpp_attribute)\n// NOTE: requiring __cplusplus above should not be necessary, but\n// works around https://bugs.llvm.org/show_bug.cgi?id=23435.\n#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)\n#else\n#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0\n#endif\n\n// GTEST_HAVE_FEATURE_\n//\n// A function-like feature checking macro that is a wrapper around\n// `__has_feature`.\n#ifdef __has_feature\n#define GTEST_HAVE_FEATURE_(x) __has_feature(x)\n#else\n#define GTEST_HAVE_FEATURE_(x) 0\n#endif\n\n// Use this annotation after a variable or parameter declaration to tell the\n// compiler the variable/parameter may be used.\n// Example:\n//\n//   GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar();\n//\n// This can be removed once we only support only C++17 or newer and\n// [[maybe_unused]] is available on all supported platforms.\n#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused)\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]\n#elif GTEST_HAVE_ATTRIBUTE_(unused)\n// This is inferior to [[maybe_unused]] as it can produce a\n// -Wused-but-marked-unused warning on optionally used symbols, but it is all we\n// have.\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__))\n#else\n#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED\n#endif\n\n// Use this annotation before a function that takes a printf format string.\n#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT)\n// MinGW has two different printf implementations. Ensure the format macro\n// matches the selected implementation. See\n// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \\\n  __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))\n#elif GTEST_HAVE_ATTRIBUTE_(format)\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \\\n  __attribute__((format(printf, string_index, first_to_check)))\n#else\n#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)\n#endif\n\n// Tell the compiler to warn about unused return values for functions declared\n// with this macro.  The macro should be used on function declarations\n// following the argument list:\n//\n//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;\n#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result)\n#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result))\n#else\n#define GTEST_MUST_USE_RESULT_\n#endif\n\n// MS C++ compiler emits warning when a conditional expression is compile time\n// constant. In some contexts this warning is false positive and needs to be\n// suppressed. Use the following two macros in such cases:\n//\n// GTEST_INTENTIONAL_CONST_COND_PUSH_()\n// while (true) {\n// GTEST_INTENTIONAL_CONST_COND_POP_()\n// }\n#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \\\n  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127)\n#define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()\n\n// Determine whether the compiler supports Microsoft's Structured Exception\n// Handling.  This is supported by several Windows compilers but generally\n// does not exist on any other system.\n#ifndef GTEST_HAS_SEH\n// The user didn't tell us, so we need to figure it out.\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\n// These two compilers are known to support SEH.\n#define GTEST_HAS_SEH 1\n#else\n// Assume no SEH.\n#define GTEST_HAS_SEH 0\n#endif\n\n#endif  // GTEST_HAS_SEH\n\n#ifndef GTEST_IS_THREADSAFE\n\n#if (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ ||                              \\\n     (defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n      !defined(GTEST_OS_WINDOWS_RT)) ||                                \\\n     GTEST_HAS_PTHREAD)\n#define GTEST_IS_THREADSAFE 1\n#endif\n\n#endif  // GTEST_IS_THREADSAFE\n\n#ifdef GTEST_IS_THREADSAFE\n// Some platforms don't support including these threading related headers.\n#include <condition_variable>  // NOLINT\n#include <mutex>               // NOLINT\n#endif                         // GTEST_IS_THREADSAFE\n\n// GTEST_API_ qualifies all symbols that must be exported. The definitions below\n// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in\n// gtest/internal/custom/gtest-port.h\n#ifndef GTEST_API_\n\n#ifdef _MSC_VER\n#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY\n#define GTEST_API_ __declspec(dllimport)\n#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY\n#define GTEST_API_ __declspec(dllexport)\n#endif\n#elif GTEST_HAVE_ATTRIBUTE_(visibility)\n#define GTEST_API_ __attribute__((visibility(\"default\")))\n#endif  // _MSC_VER\n\n#endif  // GTEST_API_\n\n#ifndef GTEST_API_\n#define GTEST_API_\n#endif  // GTEST_API_\n\n#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE\n#define GTEST_DEFAULT_DEATH_TEST_STYLE \"fast\"\n#endif  // GTEST_DEFAULT_DEATH_TEST_STYLE\n\n#if GTEST_HAVE_ATTRIBUTE_(noinline)\n// Ask the compiler to never inline a given function.\n#define GTEST_NO_INLINE_ __attribute__((noinline))\n#else\n#define GTEST_NO_INLINE_\n#endif\n\n#if GTEST_HAVE_ATTRIBUTE_(disable_tail_calls)\n// Ask the compiler not to perform tail call optimization inside\n// the marked function.\n#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))\n#elif defined(__GNUC__) && !defined(__NVCOMPILER)\n#define GTEST_NO_TAIL_CALL_ \\\n  __attribute__((optimize(\"no-optimize-sibling-calls\")))\n#else\n#define GTEST_NO_TAIL_CALL_\n#endif\n\n// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.\n#if !defined(GTEST_HAS_CXXABI_H_)\n#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))\n#define GTEST_HAS_CXXABI_H_ 1\n#else\n#define GTEST_HAS_CXXABI_H_ 0\n#endif\n#endif\n\n// A function level attribute to disable checking for use of uninitialized\n// memory when built with MemorySanitizer.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_memory)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_\n#endif\n\n// A function level attribute to disable AddressSanitizer instrumentation.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_address)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \\\n  __attribute__((no_sanitize_address))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n#endif\n\n// A function level attribute to disable HWAddressSanitizer instrumentation.\n#if GTEST_HAVE_FEATURE_(hwaddress_sanitizer) && \\\n    GTEST_HAVE_ATTRIBUTE_(no_sanitize)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \\\n  __attribute__((no_sanitize(\"hwaddress\")))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n#endif\n\n// A function level attribute to disable ThreadSanitizer instrumentation.\n#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_thread)\n#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute((no_sanitize_thread))\n#else\n#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_\n#endif\n\nnamespace testing {\n\nclass Message;\n\n// Legacy imports for backwards compatibility.\n// New code should use std:: names directly.\nusing std::get;\nusing std::make_tuple;\nusing std::tuple;\nusing std::tuple_element;\nusing std::tuple_size;\n\nnamespace internal {\n\n// A secret type that Google Test users don't know about.  It has no\n// accessible constructors on purpose.  Therefore it's impossible to create a\n// Secret object, which is what we want.\nclass Secret {\n  Secret(const Secret&) = delete;\n};\n\n// A helper for suppressing warnings on constant condition.  It just\n// returns 'condition'.\nGTEST_API_ bool IsTrue(bool condition);\n\n// Defines RE.\n\n#ifdef GTEST_USES_RE2\n\n// This is almost `using RE = ::RE2`, except it is copy-constructible, and it\n// needs to disambiguate the `std::string`, `absl::string_view`, and `const\n// char*` constructors.\nclass GTEST_API_ RE {\n public:\n  RE(absl::string_view regex) : regex_(regex) {}                  // NOLINT\n  RE(const char* regex) : RE(absl::string_view(regex)) {}         // NOLINT\n  RE(const std::string& regex) : RE(absl::string_view(regex)) {}  // NOLINT\n  RE(const RE& other) : RE(other.pattern()) {}\n\n  const std::string& pattern() const { return regex_.pattern(); }\n\n  static bool FullMatch(absl::string_view str, const RE& re) {\n    return RE2::FullMatch(str, re.regex_);\n  }\n  static bool PartialMatch(absl::string_view str, const RE& re) {\n    return RE2::PartialMatch(str, re.regex_);\n  }\n\n private:\n  RE2 regex_;\n};\n\n#elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_SIMPLE_RE)\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended\n// Regular Expression syntax.\nclass GTEST_API_ RE {\n public:\n  // A copy constructor is required by the Standard to initialize object\n  // references from r-values.\n  RE(const RE& other) { Init(other.pattern()); }\n\n  // Constructs an RE from a string.\n  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT\n\n  RE(const char* regex) { Init(regex); }  // NOLINT\n  ~RE();\n\n  // Returns the string representation of the regex.\n  const char* pattern() const { return pattern_.c_str(); }\n\n  // FullMatch(str, re) returns true if and only if regular expression re\n  // matches the entire str.\n  // PartialMatch(str, re) returns true if and only if regular expression re\n  // matches a substring of str (including str itself).\n  static bool FullMatch(const ::std::string& str, const RE& re) {\n    return FullMatch(str.c_str(), re);\n  }\n  static bool PartialMatch(const ::std::string& str, const RE& re) {\n    return PartialMatch(str.c_str(), re);\n  }\n\n  static bool FullMatch(const char* str, const RE& re);\n  static bool PartialMatch(const char* str, const RE& re);\n\n private:\n  void Init(const char* regex);\n  std::string pattern_;\n  bool is_valid_;\n\n#ifdef GTEST_USES_POSIX_RE\n\n  regex_t full_regex_;     // For FullMatch().\n  regex_t partial_regex_;  // For PartialMatch().\n\n#else  // GTEST_USES_SIMPLE_RE\n\n  std::string full_pattern_;  // For FullMatch();\n\n#endif\n};\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n#endif  // ::testing::internal::RE implementation\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line);\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\n                                                               int line);\n\n// Defines logging utilities:\n//   GTEST_LOG_(severity) - logs messages at the specified severity level. The\n//                          message itself is streamed into the macro.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n\nenum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL };\n\n// Formats log entry severity, provides a stream object for streaming the\n// log message, and terminates the message with a newline when going out of\n// scope.\nclass GTEST_API_ GTestLog {\n public:\n  GTestLog(GTestLogSeverity severity, const char* file, int line);\n\n  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\n  ~GTestLog();\n\n  ::std::ostream& GetStream() { return ::std::cerr; }\n\n private:\n  const GTestLogSeverity severity_;\n\n  GTestLog(const GTestLog&) = delete;\n  GTestLog& operator=(const GTestLog&) = delete;\n};\n\n#if !defined(GTEST_LOG_)\n\n#define GTEST_LOG_(severity)                                           \\\n  ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \\\n                                __FILE__, __LINE__)                    \\\n      .GetStream()\n\ninline void LogToStderr() {}\ninline void FlushInfoLog() { fflush(nullptr); }\n\n#endif  // !defined(GTEST_LOG_)\n\n#if !defined(GTEST_CHECK_)\n// INTERNAL IMPLEMENTATION - DO NOT USE.\n//\n// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition\n// is not satisfied.\n//  Synopsis:\n//    GTEST_CHECK_(boolean_condition);\n//     or\n//    GTEST_CHECK_(boolean_condition) << \"Additional message\";\n//\n//    This checks the condition and if the condition is not satisfied\n//    it prints message about the condition violation, including the\n//    condition itself, plus additional message streamed into it, if any,\n//    and then it aborts the program. It aborts the program irrespective of\n//    whether it is built in the debug mode or not.\n#define GTEST_CHECK_(condition)               \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_               \\\n  if (::testing::internal::IsTrue(condition)) \\\n    ;                                         \\\n  else                                        \\\n    GTEST_LOG_(FATAL) << \"Condition \" #condition \" failed. \"\n#endif  // !defined(GTEST_CHECK_)\n\n// An all-mode assert to verify that the given POSIX-style function\n// call returns 0 (indicating success).  Known limitation: this\n// doesn't expand to a balanced 'if' statement, so enclose the macro\n// in {} if you need to use it as the only statement in an 'if'\n// branch.\n#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \\\n  if (const int gtest_error = (posix_call))    \\\n  GTEST_LOG_(FATAL) << #posix_call << \"failed with error \" << gtest_error\n\n// Transforms \"T\" into \"const T&\" according to standard reference collapsing\n// rules (this is only needed as a backport for C++98 compilers that do not\n// support reference collapsing). Specifically, it transforms:\n//\n//   char         ==> const char&\n//   const char   ==> const char&\n//   char&        ==> char&\n//   const char&  ==> const char&\n//\n// Note that the non-const reference will not have \"const\" added. This is\n// standard, and necessary so that \"T\" can always bind to \"const T&\".\ntemplate <typename T>\nstruct ConstRef {\n  typedef const T& type;\n};\ntemplate <typename T>\nstruct ConstRef<T&> {\n  typedef T& type;\n};\n\n// The argument T must depend on some template parameters.\n#define GTEST_REFERENCE_TO_CONST_(T) \\\n  typename ::testing::internal::ConstRef<T>::type\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Use ImplicitCast_ as a safe version of static_cast for upcasting in\n// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a\n// const Foo*).  When you use ImplicitCast_, the compiler checks that\n// the cast is safe.  Such explicit ImplicitCast_s are necessary in\n// surprisingly many situations where C++ demands an exact type match\n// instead of an argument type convertible to a target type.\n//\n// The syntax for using ImplicitCast_ is the same as for static_cast:\n//\n//   ImplicitCast_<ToType>(expr)\n//\n// ImplicitCast_ would have been part of the C++ standard library,\n// but the proposal was submitted too late.  It will probably make\n// its way into the language in the future.\n//\n// This relatively ugly name is intentional. It prevents clashes with\n// similar functions users may have (e.g., implicit_cast). The internal\n// namespace alone is not enough because the function can be found by ADL.\ntemplate <typename To>\ninline To ImplicitCast_(To x) {\n  return x;\n}\n\n// Downcasts the pointer of type Base to Derived.\n// Derived must be a subclass of Base. The parameter MUST\n// point to a class of type Derived, not any subclass of it.\n// When RTTI is available, the function performs a runtime\n// check to enforce this.\ntemplate <class Derived, class Base>\nDerived* CheckedDowncastToActualType(Base* base) {\n  static_assert(std::is_base_of<Base, Derived>::value,\n                \"target type not derived from source type\");\n#if GTEST_HAS_RTTI\n  GTEST_CHECK_(base == nullptr || dynamic_cast<Derived*>(base) != nullptr);\n#endif\n  return static_cast<Derived*>(base);\n}\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Defines the stderr capturer:\n//   CaptureStdout     - starts capturing stdout.\n//   GetCapturedStdout - stops capturing stdout and returns the captured string.\n//   CaptureStderr     - starts capturing stderr.\n//   GetCapturedStderr - stops capturing stderr and returns the captured string.\n//\nGTEST_API_ void CaptureStdout();\nGTEST_API_ std::string GetCapturedStdout();\nGTEST_API_ void CaptureStderr();\nGTEST_API_ std::string GetCapturedStderr();\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n// Returns the size (in bytes) of a file.\nGTEST_API_ size_t GetFileSize(FILE* file);\n\n// Reads the entire content of a file as a string.\nGTEST_API_ std::string ReadEntireFile(FILE* file);\n\n// All command line arguments.\nGTEST_API_ std::vector<std::string> GetArgvs();\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nstd::vector<std::string> GetInjectableArgvs();\n// Deprecated: pass the args vector by value instead.\nvoid SetInjectableArgvs(const std::vector<std::string>* new_argvs);\nvoid SetInjectableArgvs(const std::vector<std::string>& new_argvs);\nvoid ClearInjectableArgvs();\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Defines synchronization primitives.\n#ifdef GTEST_IS_THREADSAFE\n\n#ifdef GTEST_OS_WINDOWS\n// Provides leak-safe Windows kernel handle ownership.\n// Used in death tests and in threading support.\nclass GTEST_API_ AutoHandle {\n public:\n  // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to\n  // avoid including <windows.h> in this header file. Including <windows.h> is\n  // undesirable because it defines a lot of symbols and macros that tend to\n  // conflict with client code. This assumption is verified by\n  // WindowsTypesTest.HANDLEIsVoidStar.\n  typedef void* Handle;\n  AutoHandle();\n  explicit AutoHandle(Handle handle);\n\n  ~AutoHandle();\n\n  Handle Get() const;\n  void Reset();\n  void Reset(Handle handle);\n\n private:\n  // Returns true if and only if the handle is a valid handle object that can be\n  // closed.\n  bool IsCloseable() const;\n\n  Handle handle_;\n\n  AutoHandle(const AutoHandle&) = delete;\n  AutoHandle& operator=(const AutoHandle&) = delete;\n};\n#endif\n\n#if GTEST_HAS_NOTIFICATION_\n// Notification has already been imported into the namespace.\n// Nothing to do here.\n\n#else\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Allows a controller thread to pause execution of newly created\n// threads until notified.  Instances of this class must be created\n// and destroyed in the controller thread.\n//\n// This class is only for testing Google Test's own constructs. Do not\n// use it in user tests, either directly or indirectly.\n// TODO(b/203539622): Replace unconditionally with absl::Notification.\nclass GTEST_API_ Notification {\n public:\n  Notification() : notified_(false) {}\n  Notification(const Notification&) = delete;\n  Notification& operator=(const Notification&) = delete;\n\n  // Notifies all threads created with this notification to start. Must\n  // be called from the controller thread.\n  void Notify() {\n    std::lock_guard<std::mutex> lock(mu_);\n    notified_ = true;\n    cv_.notify_all();\n  }\n\n  // Blocks until the controller thread notifies. Must be called from a test\n  // thread.\n  void WaitForNotification() {\n    std::unique_lock<std::mutex> lock(mu_);\n    cv_.wait(lock, [this]() { return notified_; });\n  }\n\n private:\n  std::mutex mu_;\n  std::condition_variable cv_;\n  bool notified_;\n};\nGTEST_DISABLE_MSC_WARNINGS_POP_()  // 4251\n#endif  // GTEST_HAS_NOTIFICATION_\n\n// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD\n// defined, but we don't want to use MinGW's pthreads implementation, which\n// has conformance problems with some versions of the POSIX standard.\n#if GTEST_HAS_PTHREAD && !defined(GTEST_OS_WINDOWS_MINGW)\n\n// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.\n// Consequently, it cannot select a correct instantiation of ThreadWithParam\n// in order to call its Run(). Introducing ThreadWithParamBase as a\n// non-templated base class for ThreadWithParam allows us to bypass this\n// problem.\nclass ThreadWithParamBase {\n public:\n  virtual ~ThreadWithParamBase() = default;\n  virtual void Run() = 0;\n};\n\n// pthread_create() accepts a pointer to a function type with the C linkage.\n// According to the Standard (7.5/1), function types with different linkages\n// are different even if they are otherwise identical.  Some compilers (for\n// example, SunStudio) treat them as different types.  Since class methods\n// cannot be defined with C-linkage we need to define a free C-function to\n// pass into pthread_create().\nextern \"C\" inline void* ThreadFuncWithCLinkage(void* thread) {\n  static_cast<ThreadWithParamBase*>(thread)->Run();\n  return nullptr;\n}\n\n// Helper class for testing Google Test's multi-threading constructs.\n// To use it, write:\n//\n//   void ThreadFunc(int param) { /* Do things with param */ }\n//   Notification thread_can_start;\n//   ...\n//   // The thread_can_start parameter is optional; you can supply NULL.\n//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);\n//   thread_can_start.Notify();\n//\n// These classes are only for testing Google Test's own constructs. Do\n// not use them in user tests, either directly or indirectly.\ntemplate <typename T>\nclass ThreadWithParam : public ThreadWithParamBase {\n public:\n  typedef void UserThreadFunc(T);\n\n  ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)\n      : func_(func),\n        param_(param),\n        thread_can_start_(thread_can_start),\n        finished_(false) {\n    ThreadWithParamBase* const base = this;\n    // The thread can be created only after all fields except thread_\n    // have been initialized.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base));\n  }\n  ~ThreadWithParam() override { Join(); }\n\n  void Join() {\n    if (!finished_) {\n      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr));\n      finished_ = true;\n    }\n  }\n\n  void Run() override {\n    if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification();\n    func_(param_);\n  }\n\n private:\n  UserThreadFunc* const func_;  // User-supplied thread function.\n  const T param_;  // User-supplied parameter to the thread function.\n  // When non-NULL, used to block execution until the controller thread\n  // notifies.\n  Notification* const thread_can_start_;\n  bool finished_;  // true if and only if we know that the thread function has\n                   // finished.\n  pthread_t thread_;  // The native thread object.\n\n  ThreadWithParam(const ThreadWithParam&) = delete;\n  ThreadWithParam& operator=(const ThreadWithParam&) = delete;\n};\n#endif  // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD ||\n        // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n\n#if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n// Mutex and ThreadLocal have already been imported into the namespace.\n// Nothing to do here.\n\n#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT)\n\n// Mutex implements mutex on Windows platforms.  It is used in conjunction\n// with class MutexLock:\n//\n//   Mutex mutex;\n//   ...\n//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the\n//                            // end of the current scope.\n//\n// A static Mutex *must* be defined or declared using one of the following\n// macros:\n//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);\n//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);\n//\n// (A non-static Mutex is defined/declared in the usual way).\nclass GTEST_API_ Mutex {\n public:\n  enum MutexType { kStatic = 0, kDynamic = 1 };\n  // We rely on kStaticMutex being 0 as it is to what the linker initializes\n  // type_ in static mutexes.  critical_section_ will be initialized lazily\n  // in ThreadSafeLazyInit().\n  enum StaticConstructorSelector { kStaticMutex = 0 };\n\n  // This constructor intentionally does nothing.  It relies on type_ being\n  // statically initialized to 0 (effectively setting it to kStatic) and on\n  // ThreadSafeLazyInit() to lazily initialize the rest of the members.\n  explicit Mutex(StaticConstructorSelector /*dummy*/) {}\n\n  Mutex();\n  ~Mutex();\n\n  void Lock();\n\n  void Unlock();\n\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\n  // with high probability.\n  void AssertHeld();\n\n private:\n  // Initializes owner_thread_id_ and critical_section_ in static mutexes.\n  void ThreadSafeLazyInit();\n\n  // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503,\n  // we assume that 0 is an invalid value for thread IDs.\n  unsigned int owner_thread_id_;\n\n  // For static mutexes, we rely on these members being initialized to zeros\n  // by the linker.\n  MutexType type_;\n  long critical_section_init_phase_;  // NOLINT\n  GTEST_CRITICAL_SECTION* critical_section_;\n\n  Mutex(const Mutex&) = delete;\n  Mutex& operator=(const Mutex&) = delete;\n};\n\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::Mutex mutex\n\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\n  ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex)\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }\n\n  ~GTestMutexLock() { mutex_->Unlock(); }\n\n private:\n  Mutex* const mutex_;\n\n  GTestMutexLock(const GTestMutexLock&) = delete;\n  GTestMutexLock& operator=(const GTestMutexLock&) = delete;\n};\n\ntypedef GTestMutexLock MutexLock;\n\n// Base class for ValueHolder<T>.  Allows a caller to hold and delete a value\n// without knowing its type.\nclass ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() {}\n};\n\n// Provides a way for a thread to send notifications to a ThreadLocal\n// regardless of its parameter type.\nclass ThreadLocalBase {\n public:\n  // Creates a new ValueHolder<T> object holding a default value passed to\n  // this ThreadLocal<T>'s constructor and returns it.  It is the caller's\n  // responsibility not to call this when the ThreadLocal<T> instance already\n  // has a value on the current thread.\n  virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;\n\n protected:\n  ThreadLocalBase() {}\n  virtual ~ThreadLocalBase() {}\n\n private:\n  ThreadLocalBase(const ThreadLocalBase&) = delete;\n  ThreadLocalBase& operator=(const ThreadLocalBase&) = delete;\n};\n\n// Maps a thread to a set of ThreadLocals that have values instantiated on that\n// thread and notifies them when the thread exits.  A ThreadLocal instance is\n// expected to persist until all threads it has values on have terminated.\nclass GTEST_API_ ThreadLocalRegistry {\n public:\n  // Registers thread_local_instance as having value on the current thread.\n  // Returns a value that can be used to identify the thread from other threads.\n  static ThreadLocalValueHolderBase* GetValueOnCurrentThread(\n      const ThreadLocalBase* thread_local_instance);\n\n  // Invoked when a ThreadLocal instance is destroyed.\n  static void OnThreadLocalDestroyed(\n      const ThreadLocalBase* thread_local_instance);\n};\n\nclass GTEST_API_ ThreadWithParamBase {\n public:\n  void Join();\n\n protected:\n  class Runnable {\n   public:\n    virtual ~Runnable() {}\n    virtual void Run() = 0;\n  };\n\n  ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start);\n  virtual ~ThreadWithParamBase();\n\n private:\n  AutoHandle thread_;\n};\n\n// Helper class for testing Google Test's multi-threading constructs.\ntemplate <typename T>\nclass ThreadWithParam : public ThreadWithParamBase {\n public:\n  typedef void UserThreadFunc(T);\n\n  ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)\n      : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {}\n  virtual ~ThreadWithParam() {}\n\n private:\n  class RunnableImpl : public Runnable {\n   public:\n    RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {}\n    virtual ~RunnableImpl() {}\n    virtual void Run() { func_(param_); }\n\n   private:\n    UserThreadFunc* const func_;\n    const T param_;\n\n    RunnableImpl(const RunnableImpl&) = delete;\n    RunnableImpl& operator=(const RunnableImpl&) = delete;\n  };\n\n  ThreadWithParam(const ThreadWithParam&) = delete;\n  ThreadWithParam& operator=(const ThreadWithParam&) = delete;\n};\n\n// Implements thread-local storage on Windows systems.\n//\n//   // Thread 1\n//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.\n//\n//   // Thread 2\n//   tl.set(150);  // Changes the value for thread 2 only.\n//   EXPECT_EQ(150, tl.get());\n//\n//   // Thread 1\n//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.\n//   tl.set(200);\n//   EXPECT_EQ(200, tl.get());\n//\n// The template type argument T must have a public copy constructor.\n// In addition, the default ThreadLocal constructor requires T to have\n// a public default constructor.\n//\n// The users of a TheadLocal instance have to make sure that all but one\n// threads (including the main one) using that instance have exited before\n// destroying it. Otherwise, the per-thread objects managed for them by the\n// ThreadLocal instance are not guaranteed to be destroyed on all platforms.\n//\n// Google Test only uses global ThreadLocal objects.  That means they\n// will die after main() has returned.  Therefore, no per-thread\n// object managed by Google Test will be leaked as long as all threads\n// using Google Test have exited when main() returns.\ntemplate <typename T>\nclass ThreadLocal : public ThreadLocalBase {\n public:\n  ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}\n  explicit ThreadLocal(const T& value)\n      : default_factory_(new InstanceValueHolderFactory(value)) {}\n\n  ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of T.  Can be deleted via its base class without the caller\n  // knowing the type of T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    ValueHolder() : value_() {}\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    ValueHolder(const ValueHolder&) = delete;\n    ValueHolder& operator=(const ValueHolder&) = delete;\n  };\n\n  T* GetOrCreateValue() const {\n    return static_cast<ValueHolder*>(\n               ThreadLocalRegistry::GetValueOnCurrentThread(this))\n        ->pointer();\n  }\n\n  ThreadLocalValueHolderBase* NewValueForCurrentThread() const override {\n    return default_factory_->MakeNewHolder();\n  }\n\n  class ValueHolderFactory {\n   public:\n    ValueHolderFactory() {}\n    virtual ~ValueHolderFactory() {}\n    virtual ValueHolder* MakeNewHolder() const = 0;\n\n   private:\n    ValueHolderFactory(const ValueHolderFactory&) = delete;\n    ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;\n  };\n\n  class DefaultValueHolderFactory : public ValueHolderFactory {\n   public:\n    DefaultValueHolderFactory() {}\n    ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }\n\n   private:\n    DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;\n    DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =\n        delete;\n  };\n\n  class InstanceValueHolderFactory : public ValueHolderFactory {\n   public:\n    explicit InstanceValueHolderFactory(const T& value) : value_(value) {}\n    ValueHolder* MakeNewHolder() const override {\n      return new ValueHolder(value_);\n    }\n\n   private:\n    const T value_;  // The value for each thread.\n\n    InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;\n    InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =\n        delete;\n  };\n\n  std::unique_ptr<ValueHolderFactory> default_factory_;\n\n  ThreadLocal(const ThreadLocal&) = delete;\n  ThreadLocal& operator=(const ThreadLocal&) = delete;\n};\n\n#elif GTEST_HAS_PTHREAD\n\n// MutexBase and Mutex implement mutex on pthreads-based platforms.\nclass MutexBase {\n public:\n  // Acquires this mutex.\n  void Lock() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));\n    owner_ = pthread_self();\n    has_owner_ = true;\n  }\n\n  // Releases this mutex.\n  void Unlock() {\n    // Since the lock is being released the owner_ field should no longer be\n    // considered valid. We don't protect writing to has_owner_ here, as it's\n    // the caller's responsibility to ensure that the current thread holds the\n    // mutex when this is called.\n    has_owner_ = false;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));\n  }\n\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\n  // with high probability.\n  void AssertHeld() const {\n    GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))\n        << \"The current thread is not holding the mutex @\" << this;\n  }\n\n  // A static mutex may be used before main() is entered.  It may even\n  // be used before the dynamic initialization stage.  Therefore we\n  // must be able to initialize a static mutex object at link time.\n  // This means MutexBase has to be a POD and its member variables\n  // have to be public.\n public:\n  pthread_mutex_t mutex_;  // The underlying pthread mutex.\n  // has_owner_ indicates whether the owner_ field below contains a valid thread\n  // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All\n  // accesses to the owner_ field should be protected by a check of this field.\n  // An alternative might be to memset() owner_ to all zeros, but there's no\n  // guarantee that a zero'd pthread_t is necessarily invalid or even different\n  // from pthread_self().\n  bool has_owner_;\n  pthread_t owner_;  // The thread holding the mutex.\n};\n\n// Forward-declares a static mutex.\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::MutexBase mutex\n\n// Defines and statically (i.e. at link time) initializes a static mutex.\n// The initialization list here does not explicitly initialize each field,\n// instead relying on default initialization for the unspecified fields. In\n// particular, the owner_ field (a pthread_t) is not explicitly initialized.\n// This allows initialization to work whether pthread_t is a scalar or struct.\n// The flag -Wmissing-field-initializers must not be specified for this to work.\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\n  ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}\n\n// The Mutex class can only be used for mutexes created at runtime. It\n// shares its API with MutexBase otherwise.\nclass Mutex : public MutexBase {\n public:\n  Mutex() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));\n    has_owner_ = false;\n  }\n  ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }\n\n private:\n  Mutex(const Mutex&) = delete;\n  Mutex& operator=(const Mutex&) = delete;\n};\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); }\n\n  ~GTestMutexLock() { mutex_->Unlock(); }\n\n private:\n  MutexBase* const mutex_;\n\n  GTestMutexLock(const GTestMutexLock&) = delete;\n  GTestMutexLock& operator=(const GTestMutexLock&) = delete;\n};\n\ntypedef GTestMutexLock MutexLock;\n\n// Helpers for ThreadLocal.\n\n// pthread_key_create() requires DeleteThreadLocalValue() to have\n// C-linkage.  Therefore it cannot be templatized to access\n// ThreadLocal<T>.  Hence the need for class\n// ThreadLocalValueHolderBase.\nclass GTEST_API_ ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() = default;\n};\n\n// Called by pthread to delete thread-local data stored by\n// pthread_setspecific().\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\n}\n\n// Implements thread-local storage on pthreads-based systems.\ntemplate <typename T>\nclass GTEST_API_ ThreadLocal {\n public:\n  ThreadLocal()\n      : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}\n  explicit ThreadLocal(const T& value)\n      : key_(CreateKey()),\n        default_factory_(new InstanceValueHolderFactory(value)) {}\n\n  ~ThreadLocal() {\n    // Destroys the managed object for the current thread, if any.\n    DeleteThreadLocalValue(pthread_getspecific(key_));\n\n    // Releases resources associated with the key.  This will *not*\n    // delete managed objects for other threads.\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));\n  }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of type T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    ValueHolder() : value_() {}\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    ValueHolder(const ValueHolder&) = delete;\n    ValueHolder& operator=(const ValueHolder&) = delete;\n  };\n\n  static pthread_key_t CreateKey() {\n    pthread_key_t key;\n    // When a thread exits, DeleteThreadLocalValue() will be called on\n    // the object managed for that thread.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_key_create(&key, &DeleteThreadLocalValue));\n    return key;\n  }\n\n  T* GetOrCreateValue() const {\n    ThreadLocalValueHolderBase* const holder =\n        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));\n    if (holder != nullptr) {\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\n    }\n\n    ValueHolder* const new_holder = default_factory_->MakeNewHolder();\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));\n    return new_holder->pointer();\n  }\n\n  class ValueHolderFactory {\n   public:\n    ValueHolderFactory() = default;\n    virtual ~ValueHolderFactory() = default;\n    virtual ValueHolder* MakeNewHolder() const = 0;\n\n   private:\n    ValueHolderFactory(const ValueHolderFactory&) = delete;\n    ValueHolderFactory& operator=(const ValueHolderFactory&) = delete;\n  };\n\n  class DefaultValueHolderFactory : public ValueHolderFactory {\n   public:\n    DefaultValueHolderFactory() = default;\n    ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }\n\n   private:\n    DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete;\n    DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) =\n        delete;\n  };\n\n  class InstanceValueHolderFactory : public ValueHolderFactory {\n   public:\n    explicit InstanceValueHolderFactory(const T& value) : value_(value) {}\n    ValueHolder* MakeNewHolder() const override {\n      return new ValueHolder(value_);\n    }\n\n   private:\n    const T value_;  // The value for each thread.\n\n    InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete;\n    InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) =\n        delete;\n  };\n\n  // A key pthreads uses for looking up per-thread values.\n  const pthread_key_t key_;\n  std::unique_ptr<ValueHolderFactory> default_factory_;\n\n  ThreadLocal(const ThreadLocal&) = delete;\n  ThreadLocal& operator=(const ThreadLocal&) = delete;\n};\n\n#endif  // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_\n\n#else  // GTEST_IS_THREADSAFE\n\n// A dummy implementation of synchronization primitives (mutex, lock,\n// and thread-local variable).  Necessary for compiling Google Test where\n// mutex is not supported - using Google Test in multiple threads is not\n// supported on such platforms.\n\nclass Mutex {\n public:\n  Mutex() {}\n  void Lock() {}\n  void Unlock() {}\n  void AssertHeld() const {}\n};\n\n#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  extern ::testing::internal::Mutex mutex\n\n#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex\n\n// We cannot name this class MutexLock because the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms. That macro is used as a defensive measure to prevent against\n// inadvertent misuses of MutexLock like \"MutexLock(&mu)\" rather than\n// \"MutexLock l(&mu)\".  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(Mutex*) {}  // NOLINT\n};\n\ntypedef GTestMutexLock MutexLock;\n\ntemplate <typename T>\nclass GTEST_API_ ThreadLocal {\n public:\n  ThreadLocal() : value_() {}\n  explicit ThreadLocal(const T& value) : value_(value) {}\n  T* pointer() { return &value_; }\n  const T* pointer() const { return &value_; }\n  const T& get() const { return value_; }\n  void set(const T& value) { value_ = value; }\n\n private:\n  T value_;\n};\n\n#endif  // GTEST_IS_THREADSAFE\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nGTEST_API_ size_t GetThreadCount();\n\n#ifdef GTEST_OS_WINDOWS\n#define GTEST_PATH_SEP_ \"\\\\\"\n#define GTEST_HAS_ALT_PATH_SEP_ 1\n#else\n#define GTEST_PATH_SEP_ \"/\"\n#define GTEST_HAS_ALT_PATH_SEP_ 0\n#endif  // GTEST_OS_WINDOWS\n\n// Utilities for char.\n\n// isspace(int ch) and friends accept an unsigned char or EOF.  char\n// may be signed, depending on the compiler (or compiler flags).\n// Therefore we need to cast a char to unsigned char before calling\n// isspace(), etc.\n\ninline bool IsAlpha(char ch) {\n  return isalpha(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsAlNum(char ch) {\n  return isalnum(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsDigit(char ch) {\n  return isdigit(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsLower(char ch) {\n  return islower(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsSpace(char ch) {\n  return isspace(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsUpper(char ch) {\n  return isupper(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsXDigit(char ch) {\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\n}\n#ifdef __cpp_lib_char8_t\ninline bool IsXDigit(char8_t ch) {\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\n}\n#endif\ninline bool IsXDigit(char16_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\ninline bool IsXDigit(char32_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\ninline bool IsXDigit(wchar_t ch) {\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\n  return ch == low_byte && isxdigit(low_byte) != 0;\n}\n\ninline char ToLower(char ch) {\n  return static_cast<char>(tolower(static_cast<unsigned char>(ch)));\n}\ninline char ToUpper(char ch) {\n  return static_cast<char>(toupper(static_cast<unsigned char>(ch)));\n}\n\ninline std::string StripTrailingSpaces(std::string str) {\n  std::string::iterator it = str.end();\n  while (it != str.begin() && IsSpace(*--it)) it = str.erase(it);\n  return str;\n}\n\n// The testing::internal::posix namespace holds wrappers for common\n// POSIX functions.  These wrappers hide the differences between\n// Windows/MSVC and POSIX systems.  Since some compilers define these\n// standard functions as macros, the wrapper cannot have the same name\n// as the wrapped function.\n\nnamespace posix {\n\n// File system porting.\n// Note: Not every I/O-related function is related to file systems, so don't\n// just disable all of them here. For example, fileno() and isatty(), etc. must\n// always be available in order to detect if a pipe points to a terminal.\n#ifdef GTEST_OS_WINDOWS\n\ntypedef struct _stat StatStruct;\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\ninline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }\n// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this\n// time and thus not defined there.\n#else\ninline int FileNo(FILE* file) { return _fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }\ninline int RmDir(const char* dir) { return _rmdir(dir); }\ninline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; }\n#endif\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n#elif defined(GTEST_OS_ESP8266)\ntypedef struct stat StatStruct;\n\ninline int FileNo(FILE* file) { return fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) {\n  // stat function not implemented on ESP8266\n  return 0;\n}\ninline int RmDir(const char* dir) { return rmdir(dir); }\ninline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }\n#endif\n\n#else\n\ntypedef struct stat StatStruct;\n\ninline int FileNo(FILE* file) { return fileno(file); }\n#if GTEST_HAS_FILE_SYSTEM\ninline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }\n#ifdef GTEST_OS_QURT\n// QuRT doesn't support any directory functions, including rmdir\ninline int RmDir(const char*) { return 0; }\n#else\ninline int RmDir(const char* dir) { return rmdir(dir); }\n#endif\ninline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }\n#endif\n\n#endif  // GTEST_OS_WINDOWS\n\n// Other functions with a different name on Windows.\n\n#ifdef GTEST_OS_WINDOWS\n\n#ifdef __BORLANDC__\ninline int DoIsATTY(int fd) { return isatty(fd); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return stricmp(s1, s2);\n}\n#else  // !__BORLANDC__\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_ZOS) || \\\n    defined(GTEST_OS_IOS) || defined(GTEST_OS_WINDOWS_PHONE) ||  \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(ESP_PLATFORM)\ninline int DoIsATTY(int /* fd */) { return 0; }\n#else\ninline int DoIsATTY(int fd) { return _isatty(fd); }\n#endif  // GTEST_OS_WINDOWS_MOBILE\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return _stricmp(s1, s2);\n}\n#endif  // __BORLANDC__\n\n#else\n\ninline int DoIsATTY(int fd) { return isatty(fd); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return strcasecmp(s1, s2);\n}\n\n#endif  // GTEST_OS_WINDOWS\n\ninline int IsATTY(int fd) {\n  // DoIsATTY might change errno (for example ENOTTY in case you redirect stdout\n  // to a file on Linux), which is unexpected, so save the previous value, and\n  // restore it after the call.\n  int savedErrno = errno;\n  int isAttyValue = DoIsATTY(fd);\n  errno = savedErrno;\n\n  return isAttyValue;\n}\n\n// Functions deprecated by MSVC 8.0.\n\nGTEST_DISABLE_MSC_DEPRECATED_PUSH_()\n\n// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and\n// StrError() aren't needed on Windows CE at this time and thus not\n// defined there.\n#if GTEST_HAS_FILE_SYSTEM\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) &&     \\\n    !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) &&               \\\n    !defined(GTEST_OS_QURT)\ninline int ChDir(const char* dir) { return chdir(dir); }\n#endif\ninline FILE* FOpen(const char* path, const char* mode) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW)\n  struct wchar_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t> {};\n  std::wstring_convert<wchar_codecvt> converter;\n  std::wstring wide_path = converter.from_bytes(path);\n  std::wstring wide_mode = converter.from_bytes(mode);\n  return _wfopen(wide_path.c_str(), wide_mode.c_str());\n#else   // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW\n  return fopen(path, mode);\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW\n}\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline FILE* FReopen(const char* path, const char* mode, FILE* stream) {\n  return freopen(path, mode, stream);\n}\ninline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\ninline int FClose(FILE* fp) { return fclose(fp); }\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline int Read(int fd, void* buf, unsigned int count) {\n  return static_cast<int>(read(fd, buf, count));\n}\ninline int Write(int fd, const void* buf, unsigned int count) {\n  return static_cast<int>(write(fd, buf, count));\n}\ninline int Close(int fd) { return close(fd); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)\ninline const char* StrError(int errnum) { return strerror(errnum); }\n#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT\n\ninline const char* GetEnv(const char* name) {\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) ||               \\\n    defined(GTEST_OS_QURT)\n  // We are on an embedded platform, which has no environment variables.\n  static_cast<void>(name);  // To prevent 'unused argument' warning.\n  return nullptr;\n#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)\n  // Environment variables which we programmatically clear will be set to the\n  // empty string rather than unset (NULL).  Handle that case.\n  const char* const env = getenv(name);\n  return (env != nullptr && env[0] != '\\0') ? env : nullptr;\n#else\n  return getenv(name);\n#endif\n}\n\nGTEST_DISABLE_MSC_DEPRECATED_POP_()\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Windows CE has no C library. The abort() function is used in\n// several places in Google Test. This implementation provides a reasonable\n// imitation of standard behaviour.\n[[noreturn]] void Abort();\n#else\n[[noreturn]] inline void Abort() { abort(); }\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n}  // namespace posix\n\n// MSVC \"deprecates\" snprintf and issues warnings wherever it is used.  In\n// order to avoid these warnings, we need to use _snprintf or _snprintf_s on\n// MSVC-based platforms.  We map the GTEST_SNPRINTF_ macro to the appropriate\n// function in order to achieve that.  We use macro definition here because\n// snprintf is a variadic function.\n#if defined(_MSC_VER) && !defined(GTEST_OS_WINDOWS_MOBILE)\n// MSVC 2005 and above support variadic macros.\n#define GTEST_SNPRINTF_(buffer, size, format, ...) \\\n  _snprintf_s(buffer, size, size, format, __VA_ARGS__)\n#elif defined(_MSC_VER)\n// Windows CE does not define _snprintf_s\n#define GTEST_SNPRINTF_ _snprintf\n#else\n#define GTEST_SNPRINTF_ snprintf\n#endif\n\n// The biggest signed integer type the compiler supports.\n//\n// long long is guaranteed to be at least 64-bits in C++11.\nusing BiggestInt = long long;  // NOLINT\n\n// The maximum number a BiggestInt can represent.\nconstexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();\n\n// This template class serves as a compile-time function from size to\n// type.  It maps a size in bytes to a primitive type with that\n// size. e.g.\n//\n//   TypeWithSize<4>::UInt\n//\n// is typedef-ed to be unsigned int (unsigned integer made up of 4\n// bytes).\n//\n// Such functionality should belong to STL, but I cannot find it\n// there.\n//\n// Google Test uses this class in the implementation of floating-point\n// comparison.\n//\n// For now it only handles UInt (unsigned int) as that's all Google Test\n// needs.  Other types can be easily added in the future if need\n// arises.\ntemplate <size_t size>\nclass TypeWithSize {\n public:\n  // This prevents the user from using TypeWithSize<N> with incorrect\n  // values of N.\n  using UInt = void;\n};\n\n// The specialization for size 4.\ntemplate <>\nclass TypeWithSize<4> {\n public:\n  using Int = std::int32_t;\n  using UInt = std::uint32_t;\n};\n\n// The specialization for size 8.\ntemplate <>\nclass TypeWithSize<8> {\n public:\n  using Int = std::int64_t;\n  using UInt = std::uint64_t;\n};\n\n// Integer types of known sizes.\nusing TimeInMillis = int64_t;  // Represents time in milliseconds.\n\n// Utilities for command line flags and environment variables.\n\n// Macro for referencing flags.\n#if !defined(GTEST_FLAG)\n#define GTEST_FLAG_NAME_(name) gtest_##name\n#define GTEST_FLAG(name) FLAGS_gtest_##name\n#endif  // !defined(GTEST_FLAG)\n\n// Pick a command line flags implementation.\n#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Macros for defining flags.\n#define GTEST_DEFINE_bool_(name, default_val, doc) \\\n  ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc)\n#define GTEST_DEFINE_int32_(name, default_val, doc) \\\n  ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc)\n#define GTEST_DEFINE_string_(name, default_val, doc) \\\n  ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc)\n\n// Macros for declaring flags.\n#define GTEST_DECLARE_bool_(name) \\\n  ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name))\n#define GTEST_DECLARE_int32_(name) \\\n  ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name))\n#define GTEST_DECLARE_string_(name) \\\n  ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name))\n\n#define GTEST_FLAG_SAVER_ ::absl::FlagSaver\n\n#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name))\n#define GTEST_FLAG_SET(name, value) \\\n  (void)(::absl::SetFlag(&GTEST_FLAG(name), value))\n#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0\n\n#undef GTEST_INTERNAL_HAS_ABSL_FLAGS\n#else  // ndef GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Macros for defining flags.\n#define GTEST_DEFINE_bool_(name, default_val, doc)  \\\n  namespace testing {                               \\\n  GTEST_API_ bool GTEST_FLAG(name) = (default_val); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DEFINE_int32_(name, default_val, doc)         \\\n  namespace testing {                                       \\\n  GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \\\n  }                                                         \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DEFINE_string_(name, default_val, doc)         \\\n  namespace testing {                                        \\\n  GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \\\n  }                                                          \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n// Macros for declaring flags.\n#define GTEST_DECLARE_bool_(name)          \\\n  namespace testing {                      \\\n  GTEST_API_ extern bool GTEST_FLAG(name); \\\n  }                                        \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DECLARE_int32_(name)                 \\\n  namespace testing {                              \\\n  GTEST_API_ extern std::int32_t GTEST_FLAG(name); \\\n  }                                                \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n#define GTEST_DECLARE_string_(name)                 \\\n  namespace testing {                               \\\n  GTEST_API_ extern ::std::string GTEST_FLAG(name); \\\n  }                                                 \\\n  static_assert(true, \"no-op to require trailing semicolon\")\n\n#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver\n\n#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name)\n#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value)\n#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1\n\n#endif  // GTEST_INTERNAL_HAS_ABSL_FLAGS\n\n// Thread annotations\n#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)\n#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)\n#define GTEST_LOCK_EXCLUDED_(locks)\n#endif  // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_)\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes the result\n// to *value and returns true; otherwise leaves *value unchanged and returns\n// false.\nGTEST_API_ bool ParseInt32(const Message& src_text, const char* str,\n                           int32_t* value);\n\n// Parses a bool/int32_t/string from the environment variable\n// corresponding to the given Google Test flag.\nbool BoolFromGTestEnv(const char* flag, bool default_val);\nGTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val);\nstd::string OutputFlagAlsoCheckEnvVar();\nconst char* StringFromGTestEnv(const char* flag, const char* default_val);\n\n}  // namespace internal\n}  // namespace testing\n\n#if !defined(GTEST_INTERNAL_DEPRECATED)\n\n// Internal Macro to mark an API deprecated, for googletest usage only\n// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or\n// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of\n// a deprecated entity will trigger a warning when compiled with\n// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).\n// For msvc /W3 option will need to be used\n// Note that for 'other' compilers this macro evaluates to nothing to prevent\n// compilations errors.\n#if defined(_MSC_VER)\n#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))\n#elif defined(__GNUC__)\n#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))\n#else\n#define GTEST_INTERNAL_DEPRECATED(message)\n#endif\n\n#endif  // !defined(GTEST_INTERNAL_DEPRECATED)\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::any for UniversalPrinter<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_ANY 1\n#include \"absl/types/any.h\"\nnamespace testing {\nnamespace internal {\nusing Any = ::absl::any;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_any) || (GTEST_INTERNAL_HAS_INCLUDE(<any>) &&        \\\n                               GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L && \\\n                               (!defined(_MSC_VER) || GTEST_HAS_RTTI))\n// Otherwise for C++17 and higher use std::any for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_ANY 1\n#include <any>\nnamespace testing {\nnamespace internal {\nusing Any = ::std::any;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::any is not\n// supported.\n#endif  // __cpp_lib_any\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_ANY\n#define GTEST_INTERNAL_HAS_ANY 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::optional for UniversalPrinter<> specializations if\n// googletest is built with absl support.\n#define GTEST_INTERNAL_HAS_OPTIONAL 1\n#include \"absl/types/optional.h\"\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing Optional = ::absl::optional<T>;\ninline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; }\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_optional) || (GTEST_INTERNAL_HAS_INCLUDE(<optional>) && \\\n                                    GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_OPTIONAL 1\n#include <optional>\nnamespace testing {\nnamespace internal {\ntemplate <typename T>\nusing Optional = ::std::optional<T>;\ninline ::std::nullopt_t Nullopt() { return ::std::nullopt; }\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::optional is not\n// supported.\n#endif  // __cpp_lib_optional\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_OPTIONAL\n#define GTEST_INTERNAL_HAS_OPTIONAL 0\n#endif\n\n#if defined(__cpp_lib_span) || (GTEST_INTERNAL_HAS_INCLUDE(<span>) && \\\n                                GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L)\n#define GTEST_INTERNAL_HAS_STD_SPAN 1\n#endif  // __cpp_lib_span\n\n#ifndef GTEST_INTERNAL_HAS_STD_SPAN\n#define GTEST_INTERNAL_HAS_STD_SPAN 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::string_view for Matcher<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_STRING_VIEW 1\n#include \"absl/strings/string_view.h\"\nnamespace testing {\nnamespace internal {\nusing StringView = ::absl::string_view;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_string_view) ||             \\\n    (GTEST_INTERNAL_HAS_INCLUDE(<string_view>) && \\\n     GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::string_view for Matcher<>\n// specializations.\n#define GTEST_INTERNAL_HAS_STRING_VIEW 1\n#include <string_view>\nnamespace testing {\nnamespace internal {\nusing StringView = ::std::string_view;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::string_view is not\n// supported.\n#endif  // __cpp_lib_string_view\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_STRING_VIEW\n#define GTEST_INTERNAL_HAS_STRING_VIEW 0\n#endif\n\n#ifdef GTEST_HAS_ABSL\n// Always use absl::variant for UniversalPrinter<> specializations if googletest\n// is built with absl support.\n#define GTEST_INTERNAL_HAS_VARIANT 1\n#include \"absl/types/variant.h\"\nnamespace testing {\nnamespace internal {\ntemplate <typename... T>\nusing Variant = ::absl::variant<T...>;\n}  // namespace internal\n}  // namespace testing\n#else\n#if defined(__cpp_lib_variant) || (GTEST_INTERNAL_HAS_INCLUDE(<variant>) && \\\n                                   GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L)\n// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>\n// specializations.\n#define GTEST_INTERNAL_HAS_VARIANT 1\n#include <variant>\nnamespace testing {\nnamespace internal {\ntemplate <typename... T>\nusing Variant = ::std::variant<T...>;\n}  // namespace internal\n}  // namespace testing\n// The case where absl is configured NOT to alias std::variant is not supported.\n#endif  // __cpp_lib_variant\n#endif  // GTEST_HAS_ABSL\n\n#ifndef GTEST_INTERNAL_HAS_VARIANT\n#define GTEST_INTERNAL_HAS_VARIANT 0\n#endif\n\n#if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \\\n    (defined(GTEST_INTERNAL_CPLUSPLUS_LANG) &&                        \\\n     GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L)\n#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1\n#endif\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-string.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This header file declares the String class and functions used internally by\n// Google Test.  They are subject to change without notice. They should not used\n// by code external to Google Test.\n//\n// This header file is #included by gtest-internal.h.\n// It should not be #included by other files.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n\n#ifdef __BORLANDC__\n// string.h is not guaranteed to provide strcpy on C++ Builder.\n#include <mem.h>\n#endif\n\n#include <string.h>\n\n#include <cstdint>\n#include <sstream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\nnamespace internal {\n\n// String - an abstract class holding static string utilities.\nclass GTEST_API_ String {\n public:\n  // Static utility methods\n\n  // Clones a 0-terminated C string, allocating memory using new.  The\n  // caller is responsible for deleting the return value using\n  // delete[].  Returns the cloned string, or NULL if the input is\n  // NULL.\n  //\n  // This is different from strdup() in string.h, which allocates\n  // memory using malloc().\n  static const char* CloneCString(const char* c_str);\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be\n  // able to pass strings to Win32 APIs on CE we need to convert them\n  // to 'Unicode', UTF-16.\n\n  // Creates a UTF-16 wide string from the given ANSI string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the wide string, or NULL if the\n  // input is NULL.\n  //\n  // The wide string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static LPCWSTR AnsiToUtf16(const char* c_str);\n\n  // Creates an ANSI string from the given wide string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the ANSI string, or NULL if the\n  // input is NULL.\n  //\n  // The returned string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static const char* Utf16ToAnsi(LPCWSTR utf16_str);\n#endif\n\n  // Compares two C strings.  Returns true if and only if they have the same\n  // content.\n  //\n  // Unlike strcmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CStringEquals(const char* lhs, const char* rhs);\n\n  // Converts a wide C string to a String using the UTF-8 encoding.\n  // NULL will be converted to \"(null)\".  If an error occurred during\n  // the conversion, \"(failed to convert from wide string)\" is\n  // returned.\n  static std::string ShowWideCString(const wchar_t* wide_c_str);\n\n  // Compares two wide C strings.  Returns true if and only if they have the\n  // same content.\n  //\n  // Unlike wcscmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);\n\n  // Compares two C strings, ignoring case.  Returns true if and only if\n  // they have the same content.\n  //\n  // Unlike strcasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);\n\n  // Compares two wide C strings, ignoring case.  Returns true if and only if\n  // they have the same content.\n  //\n  // Unlike wcscasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL wide C string,\n  // including the empty string.\n  // NB: The implementations on different platforms slightly differ.\n  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n  // environment variable. On GNU platform this method uses wcscasecmp\n  // which compares according to LC_CTYPE category of the current locale.\n  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n  // current locale.\n  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                               const wchar_t* rhs);\n\n  // Returns true if and only if the given string ends with the given suffix,\n  // ignoring case. Any string is considered to end with an empty suffix.\n  static bool EndsWithCaseInsensitive(const std::string& str,\n                                      const std::string& suffix);\n\n  // Formats an int value as \"%02d\".\n  static std::string FormatIntWidth2(int value);  // \"%02d\" for width == 2\n\n  // Formats an int value to given width with leading zeros.\n  static std::string FormatIntWidthN(int value, int width);\n\n  // Formats an int value as \"%X\".\n  static std::string FormatHexInt(int value);\n\n  // Formats an int value as \"%X\".\n  static std::string FormatHexUInt32(uint32_t value);\n\n  // Formats a byte as \"%02X\".\n  static std::string FormatByte(unsigned char value);\n\n private:\n  String();  // Not meant to be instantiated.\n};           // class String\n\n// Gets the content of the stringstream's buffer as an std::string.  Each '\\0'\n// character in the buffer is replaced with \"\\\\0\".\nGTEST_API_ std::string StringStreamToString(::std::stringstream* stream);\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/include/gtest/internal/gtest-type-util.h",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Type utilities needed for implementing typed and type-parameterized\n// tests.\n\n// IWYU pragma: private, include \"gtest/gtest.h\"\n// IWYU pragma: friend gtest/.*\n// IWYU pragma: friend gmock/.*\n\n#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n\n#include <string>\n#include <type_traits>\n#include <typeinfo>\n\n#include \"gtest/internal/gtest-port.h\"\n\n// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using\n// libstdc++ (which is where cxxabi.h comes from).\n#if GTEST_HAS_CXXABI_H_\n#include <cxxabi.h>\n#elif defined(__HP_aCC)\n#include <acxx_demangle.h>\n#endif  // GTEST_HASH_CXXABI_H_\n\nnamespace testing {\nnamespace internal {\n\n// Canonicalizes a given name with respect to the Standard C++ Library.\n// This handles removing the inline namespace within `std` that is\n// used by various standard libraries (e.g., `std::__1`).  Names outside\n// of namespace std are returned unmodified.\ninline std::string CanonicalizeForStdLibVersioning(std::string s) {\n  static const char prefix[] = \"std::__\";\n  if (s.compare(0, strlen(prefix), prefix) == 0) {\n    std::string::size_type end = s.find(\"::\", strlen(prefix));\n    if (end != s.npos) {\n      // Erase everything between the initial `std` and the second `::`.\n      s.erase(strlen(\"std\"), end - strlen(\"std\"));\n    }\n  }\n\n  // Strip redundant spaces in typename to match MSVC\n  // For example, std::pair<int, bool> -> std::pair<int,bool>\n  static const char to_search[] = \", \";\n  static const char replace_str[] = \",\";\n  size_t pos = 0;\n  while (true) {\n    // Get the next occurrence from the current position\n    pos = s.find(to_search, pos);\n    if (pos == std::string::npos) {\n      break;\n    }\n    // Replace this occurrence of substring\n    s.replace(pos, strlen(to_search), replace_str);\n    pos += strlen(replace_str);\n  }\n  return s;\n}\n\n#if GTEST_HAS_RTTI\n// GetTypeName(const std::type_info&) returns a human-readable name of type T.\ninline std::string GetTypeName(const std::type_info& type) {\n  const char* const name = type.name();\n#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)\n  int status = 0;\n  // gcc's implementation of typeid(T).name() mangles the type name,\n  // so we have to demangle it.\n#if GTEST_HAS_CXXABI_H_\n  using abi::__cxa_demangle;\n#endif  // GTEST_HAS_CXXABI_H_\n  char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);\n  const std::string name_str(status == 0 ? readable_name : name);\n  free(readable_name);\n  return CanonicalizeForStdLibVersioning(name_str);\n#elif defined(_MSC_VER)\n  // Strip struct and class due to differences between\n  // MSVC and other compilers. std::pair<int,bool> is printed as\n  // \"struct std::pair<int,bool>\" when using MSVC vs \"std::pair<int, bool>\" with\n  // other compilers.\n  std::string s = name;\n  // Only strip the leading \"struct \" and \"class \", so uses rfind == 0 to\n  // ensure that\n  if (s.rfind(\"struct \", 0) == 0) {\n    s = s.substr(strlen(\"struct \"));\n  } else if (s.rfind(\"class \", 0) == 0) {\n    s = s.substr(strlen(\"class \"));\n  }\n  return s;\n#else\n  return name;\n#endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC\n}\n#endif  // GTEST_HAS_RTTI\n\n// GetTypeName<T>() returns a human-readable name of type T if and only if\n// RTTI is enabled, otherwise it returns a dummy type name.\n// NB: This function is also used in Google Mock, so don't move it inside of\n// the typed-test-only section below.\ntemplate <typename T>\nstd::string GetTypeName() {\n#if GTEST_HAS_RTTI\n  return GetTypeName(typeid(T));\n#else\n  return \"<type>\";\n#endif  // GTEST_HAS_RTTI\n}\n\n// A unique type indicating an empty node\nstruct None {};\n\n#define GTEST_TEMPLATE_ \\\n  template <typename T> \\\n  class\n\n// The template \"selector\" struct TemplateSel<Tmpl> is used to\n// represent Tmpl, which must be a class template with one type\n// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined\n// as the type Tmpl<T>.  This allows us to actually instantiate the\n// template \"selected\" by TemplateSel<Tmpl>.\n//\n// This trick is necessary for simulating typedef for class templates,\n// which C++ doesn't support directly.\ntemplate <GTEST_TEMPLATE_ Tmpl>\nstruct TemplateSel {\n  template <typename T>\n  struct Bind {\n    typedef Tmpl<T> type;\n  };\n};\n\n#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type\n\ntemplate <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>\nstruct Templates {\n  using Head = TemplateSel<Head_>;\n  using Tail = Templates<Tail_...>;\n};\n\ntemplate <GTEST_TEMPLATE_ Head_>\nstruct Templates<Head_> {\n  using Head = TemplateSel<Head_>;\n  using Tail = None;\n};\n\n// Tuple-like type lists\ntemplate <typename Head_, typename... Tail_>\nstruct Types {\n  using Head = Head_;\n  using Tail = Types<Tail_...>;\n};\n\ntemplate <typename Head_>\nstruct Types<Head_> {\n  using Head = Head_;\n  using Tail = None;\n};\n\n// Helper metafunctions to tell apart a single type from types\n// generated by ::testing::Types\ntemplate <typename... Ts>\nstruct ProxyTypeList {\n  using type = Types<Ts...>;\n};\n\ntemplate <typename>\nstruct is_proxy_type_list : std::false_type {};\n\ntemplate <typename... Ts>\nstruct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};\n\n// Generator which conditionally creates type lists.\n// It recognizes if a requested type list should be created\n// and prevents creating a new type list nested within another one.\ntemplate <typename T>\nstruct GenerateTypeList {\n private:\n  using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,\n                                          ProxyTypeList<T>>::type;\n\n public:\n  using type = typename proxy::type;\n};\n\n}  // namespace internal\n\ntemplate <typename... Ts>\nusing Types = internal::ProxyTypeList<Ts...>;\n\n}  // namespace testing\n\n#endif  // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-all.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// Google C++ Testing and Mocking Framework (Google Test)\n//\n// Sometimes it's desirable to build Google Test by compiling a single file.\n// This file serves this purpose.\n\n// This line ensures that gtest.h can be compiled on its own, even\n// when it's fused.\n#include \"gtest/gtest.h\"\n\n// The following lines pull in the real gtest *.cc files.\n#include \"src/gtest-assertion-result.cc\"\n#include \"src/gtest-death-test.cc\"\n#include \"src/gtest-filepath.cc\"\n#include \"src/gtest-matchers.cc\"\n#include \"src/gtest-port.cc\"\n#include \"src/gtest-printers.cc\"\n#include \"src/gtest-test-part.cc\"\n#include \"src/gtest-typed-test.cc\"\n#include \"src/gtest.cc\"\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-assertion-result.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file defines the AssertionResult type.\n\n#include \"gtest/gtest-assertion-result.h\"\n\n#include <string>\n#include <utility>\n\n#include \"gtest/gtest-message.h\"\n\nnamespace testing {\n\n// AssertionResult constructors.\n// Used in EXPECT_TRUE/FALSE(assertion_result).\nAssertionResult::AssertionResult(const AssertionResult& other)\n    : success_(other.success_),\n      message_(other.message_ != nullptr\n                   ? new ::std::string(*other.message_)\n                   : static_cast< ::std::string*>(nullptr)) {}\n\n// Swaps two AssertionResults.\nvoid AssertionResult::swap(AssertionResult& other) {\n  using std::swap;\n  swap(success_, other.success_);\n  swap(message_, other.message_);\n}\n\n// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\nAssertionResult AssertionResult::operator!() const {\n  AssertionResult negation(!success_);\n  if (message_ != nullptr) negation << *message_;\n  return negation;\n}\n\n// Makes a successful assertion result.\nAssertionResult AssertionSuccess() { return AssertionResult(true); }\n\n// Makes a failed assertion result.\nAssertionResult AssertionFailure() { return AssertionResult(false); }\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << message.\nAssertionResult AssertionFailure(const Message& message) {\n  return AssertionFailure() << message;\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-death-test.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// This file implements death tests.\n\n#include \"gtest/gtest-death-test.h\"\n\n#include <stdlib.h>\n\n#include <functional>\n#include <memory>\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"gtest/internal/custom/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_HAS_DEATH_TEST\n\n#ifdef GTEST_OS_MAC\n#include <crt_externs.h>\n#endif  // GTEST_OS_MAC\n\n#include <errno.h>\n#include <fcntl.h>\n#include <limits.h>\n\n#ifdef GTEST_OS_LINUX\n#include <signal.h>\n#endif  // GTEST_OS_LINUX\n\n#include <stdarg.h>\n\n#ifdef GTEST_OS_WINDOWS\n#include <windows.h>\n#else\n#include <sys/mman.h>\n#include <sys/wait.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_QNX\n#include <spawn.h>\n#endif  // GTEST_OS_QNX\n\n#ifdef GTEST_OS_FUCHSIA\n#include <lib/fdio/fd.h>\n#include <lib/fdio/io.h>\n#include <lib/fdio/spawn.h>\n#include <lib/zx/channel.h>\n#include <lib/zx/port.h>\n#include <lib/zx/process.h>\n#include <lib/zx/socket.h>\n#include <zircon/processargs.h>\n#include <zircon/syscalls.h>\n#include <zircon/syscalls/policy.h>\n#include <zircon/syscalls/port.h>\n#endif  // GTEST_OS_FUCHSIA\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\n// Constants.\n\n// The default death test style.\n//\n// This is defined in internal/gtest-port.h as \"fast\", but can be overridden by\n// a definition in internal/custom/gtest-port.h. The recommended value, which is\n// used internally at Google, is \"threadsafe\".\nstatic const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;\n\n}  // namespace testing\n\nGTEST_DEFINE_string_(\n    death_test_style,\n    testing::internal::StringFromGTestEnv(\"death_test_style\",\n                                          testing::kDefaultDeathTestStyle),\n    \"Indicates how to run a death test in a forked child process: \"\n    \"\\\"threadsafe\\\" (child process re-executes the test binary \"\n    \"from the beginning, running only the specific death test) or \"\n    \"\\\"fast\\\" (child process runs the death test immediately \"\n    \"after forking).\");\n\nGTEST_DEFINE_bool_(\n    death_test_use_fork,\n    testing::internal::BoolFromGTestEnv(\"death_test_use_fork\", false),\n    \"Instructs to use fork()/_Exit() instead of clone() in death tests. \"\n    \"Ignored and always uses fork() on POSIX systems where clone() is not \"\n    \"implemented. Useful when running under valgrind or similar tools if \"\n    \"those do not support clone(). Valgrind 3.3.1 will just fail if \"\n    \"it sees an unsupported combination of clone() flags. \"\n    \"It is not recommended to use this flag w/o valgrind though it will \"\n    \"work in 99% of the cases. Once valgrind is fixed, this flag will \"\n    \"most likely be removed.\");\n\nGTEST_DEFINE_string_(\n    internal_run_death_test, \"\",\n    \"Indicates the file, line number, temporal index of \"\n    \"the single death test to run, and a file descriptor to \"\n    \"which a success code may be sent, all separated by \"\n    \"the '|' characters.  This flag is specified if and only if the \"\n    \"current process is a sub-process launched for running a thread-safe \"\n    \"death test.  FOR INTERNAL USE ONLY.\");\n\nnamespace testing {\n\n#ifdef GTEST_HAS_DEATH_TEST\n\nnamespace internal {\n\n// Valid only for fast death tests. Indicates the code is running in the\n// child process of a fast style death test.\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\nstatic bool g_in_fast_death_test_child = false;\n#endif\n\n// Returns a Boolean value indicating whether the caller is currently\n// executing in the context of the death test child process.  Tools such as\n// Valgrind heap checkers may need this to modify their behavior in death\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\n// implementation of death tests.  User code MUST NOT use it.\nbool InDeathTestChild() {\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  // On Windows and Fuchsia, death tests are thread-safe regardless of the value\n  // of the death_test_style flag.\n  return !GTEST_FLAG_GET(internal_run_death_test).empty();\n\n#else\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\")\n    return !GTEST_FLAG_GET(internal_run_death_test).empty();\n  else\n    return g_in_fast_death_test_child;\n#endif\n}\n\n}  // namespace internal\n\n// ExitedWithCode constructor.\nExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {}\n\n// ExitedWithCode function-call operator.\nbool ExitedWithCode::operator()(int exit_status) const {\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  return exit_status == exit_code_;\n\n#else\n\n  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;\n\n#endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA\n}\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// KilledBySignal constructor.\nKilledBySignal::KilledBySignal(int signum) : signum_(signum) {}\n\n// KilledBySignal function-call operator.\nbool KilledBySignal::operator()(int exit_status) const {\n#if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)\n  {\n    bool result;\n    if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) {\n      return result;\n    }\n  }\n#endif  // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)\n  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;\n}\n#endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA\n\nnamespace internal {\n\n// Utilities needed for death tests.\n\n// Generates a textual description of a given exit code, in the format\n// specified by wait(2).\nstatic std::string ExitSummary(int exit_code) {\n  Message m;\n\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_FUCHSIA)\n\n  m << \"Exited with exit status \" << exit_code;\n\n#else\n\n  if (WIFEXITED(exit_code)) {\n    m << \"Exited with exit status \" << WEXITSTATUS(exit_code);\n  } else if (WIFSIGNALED(exit_code)) {\n    m << \"Terminated by signal \" << WTERMSIG(exit_code);\n  }\n#ifdef WCOREDUMP\n  if (WCOREDUMP(exit_code)) {\n    m << \" (core dumped)\";\n  }\n#endif\n#endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA\n\n  return m.GetString();\n}\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nbool ExitedUnsuccessfully(int exit_status) {\n  return !ExitedWithCode(0)(exit_status);\n}\n\n#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)\n// Generates a textual failure message when a death test finds more than\n// one thread running, or cannot determine the number of threads, prior\n// to executing the given statement.  It is the responsibility of the\n// caller not to pass a thread_count of 1.\nstatic std::string DeathTestThreadWarning(size_t thread_count) {\n  Message msg;\n  msg << \"Death tests use fork(), which is unsafe particularly\"\n      << \" in a threaded context. For this test, \" << GTEST_NAME_ << \" \";\n  if (thread_count == 0) {\n    msg << \"couldn't detect the number of threads.\";\n  } else {\n    msg << \"detected \" << thread_count << \" threads.\";\n  }\n  msg << \" See \"\n         \"https://github.com/google/googletest/blob/main/docs/\"\n         \"advanced.md#death-tests-and-threads\"\n      << \" for more explanation and suggested solutions, especially if\"\n      << \" this is the last message you see before your test times out.\";\n  return msg.GetString();\n}\n#endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA\n\n// Flag characters for reporting a death test that did not die.\nstatic const char kDeathTestLived = 'L';\nstatic const char kDeathTestReturned = 'R';\nstatic const char kDeathTestThrew = 'T';\nstatic const char kDeathTestInternalError = 'I';\n\n#ifdef GTEST_OS_FUCHSIA\n\n// File descriptor used for the pipe in the child process.\nstatic const int kFuchsiaReadPipeFd = 3;\n\n#endif\n\n// An enumeration describing all of the possible ways that a death test can\n// conclude.  DIED means that the process died while executing the test\n// code; LIVED means that process lived beyond the end of the test code;\n// RETURNED means that the test statement attempted to execute a return\n// statement, which is not allowed; THREW means that the test statement\n// returned control by throwing an exception.  IN_PROGRESS means the test\n// has not yet concluded.\nenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };\n\n// Routine for aborting the program which is safe to call from an\n// exec-style death test child process, in which case the error\n// message is propagated back to the parent process.  Otherwise, the\n// message is simply printed to stderr.  In either case, the program\n// then exits with status 1.\n[[noreturn]] static void DeathTestAbort(const std::string& message) {\n  // On a POSIX system, this function may be called from a threadsafe-style\n  // death test child process, which operates on a very small stack.  Use\n  // the heap for any additional non-minuscule memory requirements.\n  const InternalRunDeathTestFlag* const flag =\n      GetUnitTestImpl()->internal_run_death_test_flag();\n  if (flag != nullptr) {\n    FILE* parent = posix::FDOpen(flag->write_fd(), \"w\");\n    fputc(kDeathTestInternalError, parent);\n    fprintf(parent, \"%s\", message.c_str());\n    fflush(parent);\n    _Exit(1);\n  } else {\n    fprintf(stderr, \"%s\", message.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n\n// A replacement for CHECK that calls DeathTestAbort if the assertion\n// fails.\n#define GTEST_DEATH_TEST_CHECK_(expression)                              \\\n  do {                                                                   \\\n    if (!::testing::internal::IsTrue(expression)) {                      \\\n      DeathTestAbort(::std::string(\"CHECK failed: File \") + __FILE__ +   \\\n                     \", line \" +                                         \\\n                     ::testing::internal::StreamableToString(__LINE__) + \\\n                     \": \" + #expression);                                \\\n    }                                                                    \\\n  } while (::testing::internal::AlwaysFalse())\n\n// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for\n// evaluating any system call that fulfills two conditions: it must return\n// -1 on failure, and set errno to EINTR when it is interrupted and\n// should be tried again.  The macro expands to a loop that repeatedly\n// evaluates the expression as long as it evaluates to -1 and sets\n// errno to EINTR.  If the expression evaluates to -1 but errno is\n// something other than EINTR, DeathTestAbort is called.\n#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression)                      \\\n  do {                                                                   \\\n    int gtest_retval;                                                    \\\n    do {                                                                 \\\n      gtest_retval = (expression);                                       \\\n    } while (gtest_retval == -1 && errno == EINTR);                      \\\n    if (gtest_retval == -1) {                                            \\\n      DeathTestAbort(::std::string(\"CHECK failed: File \") + __FILE__ +   \\\n                     \", line \" +                                         \\\n                     ::testing::internal::StreamableToString(__LINE__) + \\\n                     \": \" + #expression + \" != -1\");                     \\\n    }                                                                    \\\n  } while (::testing::internal::AlwaysFalse())\n\n// Returns the message describing the last system error in errno.\nstd::string GetLastErrnoDescription() {\n  return errno == 0 ? \"\" : posix::StrError(errno);\n}\n\n// This is called from a death test parent process to read a failure\n// message from the death test child process and log it with the FATAL\n// severity. On Windows, the message is read from a pipe handle. On other\n// platforms, it is read from a file descriptor.\nstatic void FailFromInternalError(int fd) {\n  Message error;\n  char buffer[256];\n  int num_read;\n\n  do {\n    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {\n      buffer[num_read] = '\\0';\n      error << buffer;\n    }\n  } while (num_read == -1 && errno == EINTR);\n\n  if (num_read == 0) {\n    GTEST_LOG_(FATAL) << error.GetString();\n  } else {\n    const int last_error = errno;\n    GTEST_LOG_(FATAL) << \"Error while reading death test internal: \"\n                      << GetLastErrnoDescription() << \" [\" << last_error << \"]\";\n  }\n}\n\n// Death test constructor.  Increments the running death test count\n// for the current test.\nDeathTest::DeathTest() {\n  TestInfo* const info = GetUnitTestImpl()->current_test_info();\n  if (info == nullptr) {\n    DeathTestAbort(\n        \"Cannot run a death test outside of a TEST or \"\n        \"TEST_F construct\");\n  }\n}\n\n// Creates and returns a death test by dispatching to the current\n// death test factory.\nbool DeathTest::Create(const char* statement,\n                       Matcher<const std::string&> matcher, const char* file,\n                       int line, DeathTest** test) {\n  return GetUnitTestImpl()->death_test_factory()->Create(\n      statement, std::move(matcher), file, line, test);\n}\n\nconst char* DeathTest::LastMessage() {\n  return last_death_test_message_.c_str();\n}\n\nvoid DeathTest::set_last_death_test_message(const std::string& message) {\n  last_death_test_message_ = message;\n}\n\nstd::string DeathTest::last_death_test_message_;\n\n// Provides cross platform implementation for some death functionality.\nclass DeathTestImpl : public DeathTest {\n protected:\n  DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)\n      : statement_(a_statement),\n        matcher_(std::move(matcher)),\n        spawned_(false),\n        status_(-1),\n        outcome_(IN_PROGRESS),\n        read_fd_(-1),\n        write_fd_(-1) {}\n\n  // read_fd_ is expected to be closed and cleared by a derived class.\n  ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }\n\n  void Abort(AbortReason reason) override;\n  bool Passed(bool status_ok) override;\n\n  const char* statement() const { return statement_; }\n  bool spawned() const { return spawned_; }\n  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }\n  int status() const { return status_; }\n  void set_status(int a_status) { status_ = a_status; }\n  DeathTestOutcome outcome() const { return outcome_; }\n  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }\n  int read_fd() const { return read_fd_; }\n  void set_read_fd(int fd) { read_fd_ = fd; }\n  int write_fd() const { return write_fd_; }\n  void set_write_fd(int fd) { write_fd_ = fd; }\n\n  // Called in the parent process only. Reads the result code of the death\n  // test child process via a pipe, interprets it to set the outcome_\n  // member, and closes read_fd_.  Outputs diagnostics and terminates in\n  // case of unexpected codes.\n  void ReadAndInterpretStatusByte();\n\n  // Returns stderr output from the child process.\n  virtual std::string GetErrorLogs();\n\n private:\n  // The textual content of the code this object is testing.  This class\n  // doesn't own this string and should not attempt to delete it.\n  const char* const statement_;\n  // A matcher that's expected to match the stderr output by the child process.\n  Matcher<const std::string&> matcher_;\n  // True if the death test child process has been successfully spawned.\n  bool spawned_;\n  // The exit status of the child process.\n  int status_;\n  // How the death test concluded.\n  DeathTestOutcome outcome_;\n  // Descriptor to the read end of the pipe to the child process.  It is\n  // always -1 in the child process.  The child keeps its write end of the\n  // pipe in write_fd_.\n  int read_fd_;\n  // Descriptor to the child's write end of the pipe to the parent process.\n  // It is always -1 in the parent process.  The parent keeps its end of the\n  // pipe in read_fd_.\n  int write_fd_;\n};\n\n// Called in the parent process only. Reads the result code of the death\n// test child process via a pipe, interprets it to set the outcome_\n// member, and closes read_fd_.  Outputs diagnostics and terminates in\n// case of unexpected codes.\nvoid DeathTestImpl::ReadAndInterpretStatusByte() {\n  char flag;\n  int bytes_read;\n\n  // The read() here blocks until data is available (signifying the\n  // failure of the death test) or until the pipe is closed (signifying\n  // its success), so it's okay to call this in the parent before\n  // the child process has exited.\n  do {\n    bytes_read = posix::Read(read_fd(), &flag, 1);\n  } while (bytes_read == -1 && errno == EINTR);\n\n  if (bytes_read == 0) {\n    set_outcome(DIED);\n  } else if (bytes_read == 1) {\n    switch (flag) {\n      case kDeathTestReturned:\n        set_outcome(RETURNED);\n        break;\n      case kDeathTestThrew:\n        set_outcome(THREW);\n        break;\n      case kDeathTestLived:\n        set_outcome(LIVED);\n        break;\n      case kDeathTestInternalError:\n        FailFromInternalError(read_fd());  // Does not return.\n        break;\n      default:\n        GTEST_LOG_(FATAL) << \"Death test child process reported \"\n                          << \"unexpected status byte (\"\n                          << static_cast<unsigned int>(flag) << \")\";\n    }\n  } else {\n    GTEST_LOG_(FATAL) << \"Read from death test child process failed: \"\n                      << GetLastErrnoDescription();\n  }\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));\n  set_read_fd(-1);\n}\n\nstd::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); }\n\n// Signals that the death test code which should have exited, didn't.\n// Should be called only in a death test child process.\n// Writes a status byte to the child's status file descriptor, then\n// calls _Exit(1).\nvoid DeathTestImpl::Abort(AbortReason reason) {\n  // The parent process considers the death test to be a failure if\n  // it finds any data in our pipe.  So, here we write a single flag byte\n  // to the pipe, then exit.\n  const char status_ch = reason == TEST_DID_NOT_DIE       ? kDeathTestLived\n                         : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew\n                                                          : kDeathTestReturned;\n\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));\n  // We are leaking the descriptor here because on some platforms (i.e.,\n  // when built as Windows DLL), destructors of global objects will still\n  // run after calling _Exit(). On such systems, write_fd_ will be\n  // indirectly closed from the destructor of UnitTestImpl, causing double\n  // close if it is also closed here. On debug configurations, double close\n  // may assert. As there are no in-process buffers to flush here, we are\n  // relying on the OS to close the descriptor after the process terminates\n  // when the destructors are not run.\n  _Exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)\n}\n\n// Returns an indented copy of stderr output for a death test.\n// This makes distinguishing death test output lines from regular log lines\n// much easier.\nstatic ::std::string FormatDeathTestOutput(const ::std::string& output) {\n  ::std::string ret;\n  for (size_t at = 0;;) {\n    const size_t line_end = output.find('\\n', at);\n    ret += \"[  DEATH   ] \";\n    if (line_end == ::std::string::npos) {\n      ret += output.substr(at);\n      break;\n    }\n    ret += output.substr(at, line_end + 1 - at);\n    at = line_end + 1;\n  }\n  return ret;\n}\n\n// Assesses the success or failure of a death test, using both private\n// members which have previously been set, and one argument:\n//\n// Private data members:\n//   outcome:  An enumeration describing how the death test\n//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test\n//             fails in the latter three cases.\n//   status:   The exit status of the child process. On *nix, it is in the\n//             in the format specified by wait(2). On Windows, this is the\n//             value supplied to the ExitProcess() API or a numeric code\n//             of the exception that terminated the program.\n//   matcher_: A matcher that's expected to match the stderr output by the child\n//             process.\n//\n// Argument:\n//   status_ok: true if exit_status is acceptable in the context of\n//              this particular death test, which fails if it is false\n//\n// Returns true if and only if all of the above conditions are met.  Otherwise,\n// the first failing condition, in the order given above, is the one that is\n// reported. Also sets the last death test message string.\nbool DeathTestImpl::Passed(bool status_ok) {\n  if (!spawned()) return false;\n\n  const std::string error_message = GetErrorLogs();\n\n  bool success = false;\n  Message buffer;\n\n  buffer << \"Death test: \" << statement() << \"\\n\";\n  switch (outcome()) {\n    case LIVED:\n      buffer << \"    Result: failed to die.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case THREW:\n      buffer << \"    Result: threw an exception.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case RETURNED:\n      buffer << \"    Result: illegal return in test statement.\\n\"\n             << \" Error msg:\\n\"\n             << FormatDeathTestOutput(error_message);\n      break;\n    case DIED:\n      if (status_ok) {\n        if (matcher_.Matches(error_message)) {\n          success = true;\n        } else {\n          std::ostringstream stream;\n          matcher_.DescribeTo(&stream);\n          buffer << \"    Result: died but not with expected error.\\n\"\n                 << \"  Expected: \" << stream.str() << \"\\n\"\n                 << \"Actual msg:\\n\"\n                 << FormatDeathTestOutput(error_message);\n        }\n      } else {\n        buffer << \"    Result: died but not with expected exit code:\\n\"\n               << \"            \" << ExitSummary(status()) << \"\\n\"\n               << \"Actual msg:\\n\"\n               << FormatDeathTestOutput(error_message);\n      }\n      break;\n    case IN_PROGRESS:\n    default:\n      GTEST_LOG_(FATAL)\n          << \"DeathTest::Passed somehow called before conclusion of test\";\n  }\n\n  DeathTest::set_last_death_test_message(buffer.GetString());\n  return success;\n}\n\n#ifndef GTEST_OS_WINDOWS\n// Note: The return value points into args, so the return value's lifetime is\n// bound to that of args.\nstatic std::vector<char*> CreateArgvFromArgs(std::vector<std::string>& args) {\n  std::vector<char*> result;\n  result.reserve(args.size() + 1);\n  for (auto& arg : args) {\n    result.push_back(&arg[0]);\n  }\n  result.push_back(nullptr);  // Extra null terminator.\n  return result;\n}\n#endif\n\n#ifdef GTEST_OS_WINDOWS\n// WindowsDeathTest implements death tests on Windows. Due to the\n// specifics of starting new processes on Windows, death tests there are\n// always threadsafe, and Google Test considers the\n// --gtest_death_test_style=fast setting to be equivalent to\n// --gtest_death_test_style=threadsafe there.\n//\n// A few implementation notes:  Like the Linux version, the Windows\n// implementation uses pipes for child-to-parent communication. But due to\n// the specifics of pipes on Windows, some extra steps are required:\n//\n// 1. The parent creates a communication pipe and stores handles to both\n//    ends of it.\n// 2. The parent starts the child and provides it with the information\n//    necessary to acquire the handle to the write end of the pipe.\n// 3. The child acquires the write end of the pipe and signals the parent\n//    using a Windows event.\n// 4. Now the parent can release the write end of the pipe on its side. If\n//    this is done before step 3, the object's reference count goes down to\n//    0 and it is destroyed, preventing the child from acquiring it. The\n//    parent now has to release it, or read operations on the read end of\n//    the pipe will not return when the child terminates.\n// 5. The parent reads child's output through the pipe (outcome code and\n//    any possible error messages) from the pipe, and its stderr and then\n//    determines whether to fail the test.\n//\n// Note: to distinguish Win32 API calls from the local method and function\n// calls, the former are explicitly resolved in the global namespace.\n//\nclass WindowsDeathTest : public DeathTestImpl {\n public:\n  WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                   const char* file, int line)\n      : DeathTestImpl(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n\n  // All of these virtual functions are inherited from DeathTest.\n  virtual int Wait();\n  virtual TestRole AssumeRole();\n\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n  // Handle to the write end of the pipe to the child process.\n  AutoHandle write_handle_;\n  // Child process handle.\n  AutoHandle child_handle_;\n  // Event the child process uses to signal the parent that it has\n  // acquired the handle to the write end of the pipe. After seeing this\n  // event the parent can release its own handles to make sure its\n  // ReadFile() calls return when the child terminates.\n  AutoHandle event_handle_;\n};\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint WindowsDeathTest::Wait() {\n  if (!spawned()) return 0;\n\n  // Wait until the child either signals that it has acquired the write end\n  // of the pipe or it dies.\n  const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()};\n  switch (::WaitForMultipleObjects(2, wait_handles,\n                                   FALSE,  // Waits for any of the handles.\n                                   INFINITE)) {\n    case WAIT_OBJECT_0:\n    case WAIT_OBJECT_0 + 1:\n      break;\n    default:\n      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.\n  }\n\n  // The child has acquired the write end of the pipe or exited.\n  // We release the handle on our side and continue.\n  write_handle_.Reset();\n  event_handle_.Reset();\n\n  ReadAndInterpretStatusByte();\n\n  // Waits for the child process to exit if it haven't already. This\n  // returns immediately if the child has already exited, regardless of\n  // whether previous calls to WaitForMultipleObjects synchronized on this\n  // handle or not.\n  GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 ==\n                          ::WaitForSingleObject(child_handle_.Get(), INFINITE));\n  DWORD status_code;\n  GTEST_DEATH_TEST_CHECK_(\n      ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);\n  child_handle_.Reset();\n  set_status(static_cast<int>(status_code));\n  return status();\n}\n\n// The AssumeRole process for a Windows death test.  It creates a child\n// process with the same executable as the current process to run the\n// death test.  The child process is given the --gtest_filter and\n// --gtest_internal_run_death_test flags such that it knows to run the\n// current death test only.\nDeathTest::TestRole WindowsDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\n    // processing.\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  // WindowsDeathTest uses an anonymous pipe to communicate results of\n  // a death test.\n  SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),\n                                                 nullptr, TRUE};\n  HANDLE read_handle, write_handle;\n  GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,\n                                       &handles_are_inheritable,\n                                       0)  // Default buffer size.\n                          != FALSE);\n  set_read_fd(\n      ::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), O_RDONLY));\n  write_handle_.Reset(write_handle);\n  event_handle_.Reset(::CreateEvent(\n      &handles_are_inheritable,\n      TRUE,       // The event will automatically reset to non-signaled state.\n      FALSE,      // The initial state is non-signalled.\n      nullptr));  // The even is unnamed.\n  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag =\n      std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n      \"internal_run_death_test=\" + file_ + \"|\" + StreamableToString(line_) +\n      \"|\" + StreamableToString(death_test_index) + \"|\" +\n      StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +\n      // size_t has the same width as pointers on both 32-bit and 64-bit\n      // Windows platforms.\n      // See https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.\n      \"|\" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + \"|\" +\n      StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));\n\n  char executable_path[_MAX_PATH + 1];  // NOLINT\n  GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,\n                                                                executable_path,\n                                                                _MAX_PATH));\n\n  std::string command_line = std::string(::GetCommandLineA()) + \" \" +\n                             filter_flag + \" \\\"\" + internal_flag + \"\\\"\";\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // Flush the log buffers since the log streams are shared with the child.\n  FlushInfoLog();\n\n  // The child process will share the standard handles with the parent.\n  STARTUPINFOA startup_info;\n  memset(&startup_info, 0, sizeof(STARTUPINFO));\n  startup_info.dwFlags = STARTF_USESTDHANDLES;\n  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);\n  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);\n  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);\n\n  PROCESS_INFORMATION process_info;\n  GTEST_DEATH_TEST_CHECK_(\n      ::CreateProcessA(\n          executable_path, const_cast<char*>(command_line.c_str()),\n          nullptr,  // Returned process handle is not inheritable.\n          nullptr,  // Returned thread handle is not inheritable.\n          TRUE,  // Child inherits all inheritable handles (for write_handle_).\n          0x0,   // Default creation flags.\n          nullptr,  // Inherit the parent's environment.\n          UnitTest::GetInstance()->original_working_dir(), &startup_info,\n          &process_info) != FALSE);\n  child_handle_.Reset(process_info.hProcess);\n  ::CloseHandle(process_info.hThread);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\n#elif defined(GTEST_OS_FUCHSIA)\n\nclass FuchsiaDeathTest : public DeathTestImpl {\n public:\n  FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                   const char* file, int line)\n      : DeathTestImpl(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n\n  // All of these virtual functions are inherited from DeathTest.\n  int Wait() override;\n  TestRole AssumeRole() override;\n  std::string GetErrorLogs() override;\n\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n  // The stderr data captured by the child process.\n  std::string captured_stderr_;\n\n  zx::process child_process_;\n  zx::channel exception_channel_;\n  zx::socket stderr_socket_;\n};\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint FuchsiaDeathTest::Wait() {\n  const int kProcessKey = 0;\n  const int kSocketKey = 1;\n  const int kExceptionKey = 2;\n\n  if (!spawned()) return 0;\n\n  // Create a port to wait for socket/task/exception events.\n  zx_status_t status_zx;\n  zx::port port;\n  status_zx = zx::port::create(0, &port);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for the child process to terminate.\n  status_zx =\n      child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for the socket to be readable or closed.\n  status_zx = stderr_socket_.wait_async(\n      port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  // Register to wait for an exception.\n  status_zx = exception_channel_.wait_async(port, kExceptionKey,\n                                            ZX_CHANNEL_READABLE, 0);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  bool process_terminated = false;\n  bool socket_closed = false;\n  do {\n    zx_port_packet_t packet = {};\n    status_zx = port.wait(zx::time::infinite(), &packet);\n    GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n    if (packet.key == kExceptionKey) {\n      // Process encountered an exception. Kill it directly rather than\n      // letting other handlers process the event. We will get a kProcessKey\n      // event when the process actually terminates.\n      status_zx = child_process_.kill();\n      GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n    } else if (packet.key == kProcessKey) {\n      // Process terminated.\n      GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));\n      GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);\n      process_terminated = true;\n    } else if (packet.key == kSocketKey) {\n      GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));\n      if (packet.signal.observed & ZX_SOCKET_READABLE) {\n        // Read data from the socket.\n        constexpr size_t kBufferSize = 1024;\n        do {\n          size_t old_length = captured_stderr_.length();\n          size_t bytes_read = 0;\n          captured_stderr_.resize(old_length + kBufferSize);\n          status_zx =\n              stderr_socket_.read(0, &captured_stderr_.front() + old_length,\n                                  kBufferSize, &bytes_read);\n          captured_stderr_.resize(old_length + bytes_read);\n        } while (status_zx == ZX_OK);\n        if (status_zx == ZX_ERR_PEER_CLOSED) {\n          socket_closed = true;\n        } else {\n          GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);\n          status_zx = stderr_socket_.wait_async(\n              port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0);\n          GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n        }\n      } else {\n        GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);\n        socket_closed = true;\n      }\n    }\n  } while (!process_terminated && !socket_closed);\n\n  ReadAndInterpretStatusByte();\n\n  zx_info_process_t buffer;\n  status_zx = child_process_.get_info(ZX_INFO_PROCESS, &buffer, sizeof(buffer),\n                                      nullptr, nullptr);\n  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);\n\n  GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED);\n  set_status(static_cast<int>(buffer.return_code));\n  return status();\n}\n\n// The AssumeRole process for a Fuchsia death test.  It creates a child\n// process with the same executable as the current process to run the\n// death test.  The child process is given the --gtest_filter and\n// --gtest_internal_run_death_test flags such that it knows to run the\n// current death test only.\nDeathTest::TestRole FuchsiaDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\n    // processing.\n    set_write_fd(kFuchsiaReadPipeFd);\n    return EXECUTE_TEST;\n  }\n\n  // Flush the log buffers since the log streams are shared with the child.\n  FlushInfoLog();\n\n  // Build the child process command line.\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                    kInternalRunDeathTestFlag + \"=\" + file_ +\n                                    \"|\" + StreamableToString(line_) + \"|\" +\n                                    StreamableToString(death_test_index);\n\n  std::vector<std::string> args = GetInjectableArgvs();\n  args.push_back(filter_flag);\n  args.push_back(internal_flag);\n\n  // Build the pipe for communication with the child.\n  zx_status_t status;\n  zx_handle_t child_pipe_handle;\n  int child_pipe_fd;\n  status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n  set_read_fd(child_pipe_fd);\n\n  // Set the pipe handle for the child.\n  fdio_spawn_action_t spawn_actions[2] = {};\n  fdio_spawn_action_t* add_handle_action = &spawn_actions[0];\n  add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;\n  add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd);\n  add_handle_action->h.handle = child_pipe_handle;\n\n  // Create a socket pair will be used to receive the child process' stderr.\n  zx::socket stderr_producer_socket;\n  status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);\n  GTEST_DEATH_TEST_CHECK_(status >= 0);\n  int stderr_producer_fd = -1;\n  status =\n      fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);\n  GTEST_DEATH_TEST_CHECK_(status >= 0);\n\n  // Make the stderr socket nonblocking.\n  GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);\n\n  fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];\n  add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;\n  add_stderr_action->fd.local_fd = stderr_producer_fd;\n  add_stderr_action->fd.target_fd = STDERR_FILENO;\n\n  // Create a child job.\n  zx_handle_t child_job = ZX_HANDLE_INVALID;\n  status = zx_job_create(zx_job_default(), 0, &child_job);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n  zx_policy_basic_t policy;\n  policy.condition = ZX_POL_NEW_ANY;\n  policy.policy = ZX_POL_ACTION_ALLOW;\n  status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC,\n                             &policy, 1);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  // Create an exception channel attached to the |child_job|, to allow\n  // us to suppress the system default exception handler from firing.\n  status = zx_task_create_exception_channel(\n      child_job, 0, exception_channel_.reset_and_get_address());\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  // Spawn the child process.\n  // Note: The test component must have `fuchsia.process.Launcher` declared\n  // in its manifest. (Fuchsia integration tests require creating a\n  // \"Fuchsia Test Component\" which contains a \"Fuchsia Component Manifest\")\n  // Launching processes is a privileged operation in Fuchsia, and the\n  // declaration indicates that the ability is required for the component.\n  std::vector<char*> argv = CreateArgvFromArgs(args);\n  status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(),\n                          nullptr, 2, spawn_actions,\n                          child_process_.reset_and_get_address(), nullptr);\n  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);\n\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\nstd::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; }\n\n#else  // We are neither on Windows, nor on Fuchsia.\n\n// ForkingDeathTest provides implementations for most of the abstract\n// methods of the DeathTest interface.  Only the AssumeRole method is\n// left undefined.\nclass ForkingDeathTest : public DeathTestImpl {\n public:\n  ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);\n\n  // All of these virtual functions are inherited from DeathTest.\n  int Wait() override;\n\n protected:\n  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }\n\n private:\n  // PID of child process during death test; 0 in the child process itself.\n  pid_t child_pid_;\n};\n\n// Constructs a ForkingDeathTest.\nForkingDeathTest::ForkingDeathTest(const char* a_statement,\n                                   Matcher<const std::string&> matcher)\n    : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint ForkingDeathTest::Wait() {\n  if (!spawned()) return 0;\n\n  ReadAndInterpretStatusByte();\n\n  int status_value;\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));\n  set_status(status_value);\n  return status_value;\n}\n\n// A concrete death test class that forks, then immediately runs the test\n// in the child process.\nclass NoExecDeathTest : public ForkingDeathTest {\n public:\n  NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)\n      : ForkingDeathTest(a_statement, std::move(matcher)) {}\n  TestRole AssumeRole() override;\n};\n\n// The AssumeRole process for a fork-and-run death test.  It implements a\n// straightforward fork, with a simple pipe to transmit the status byte.\nDeathTest::TestRole NoExecDeathTest::AssumeRole() {\n  const size_t thread_count = GetThreadCount();\n  if (thread_count != 1) {\n    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n\n  DeathTest::set_last_death_test_message(\"\");\n  CaptureStderr();\n  // When we fork the process below, the log file buffers are copied, but the\n  // file descriptors are shared.  We flush all log files here so that closing\n  // the file descriptors in the child process doesn't throw off the\n  // synchronization between descriptors and buffers in the parent process.\n  // This is as close to the fork as possible to avoid a race condition in case\n  // there are multiple threads running before the death test, and another\n  // thread writes to the log file.\n  FlushInfoLog();\n\n  const pid_t child_pid = fork();\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  set_child_pid(child_pid);\n  if (child_pid == 0) {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));\n    set_write_fd(pipe_fd[1]);\n    // Redirects all logging to stderr in the child process to prevent\n    // concurrent writes to the log files.  We capture stderr in the parent\n    // process and append the child process' output to a log.\n    LogToStderr();\n    // Event forwarding to the listeners of event listener API mush be shut\n    // down in death test subprocesses.\n    GetUnitTestImpl()->listeners()->SuppressEventForwarding(true);\n    g_in_fast_death_test_child = true;\n    return EXECUTE_TEST;\n  } else {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n    set_read_fd(pipe_fd[0]);\n    set_spawned(true);\n    return OVERSEE_TEST;\n  }\n}\n\n// A concrete death test class that forks and re-executes the main\n// program from the beginning, with command-line flags set that cause\n// only this specific death test to be run.\nclass ExecDeathTest : public ForkingDeathTest {\n public:\n  ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,\n                const char* file, int line)\n      : ForkingDeathTest(a_statement, std::move(matcher)),\n        file_(file),\n        line_(line) {}\n  TestRole AssumeRole() override;\n\n private:\n  static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {\n    ::std::vector<std::string> args = GetInjectableArgvs();\n#if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)\n    ::std::vector<std::string> extra_args =\n        GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();\n    args.insert(args.end(), extra_args.begin(), extra_args.end());\n#endif  // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)\n    return args;\n  }\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n};\n\n// A struct that encompasses the arguments to the child process of a\n// threadsafe-style death test process.\nstruct ExecDeathTestArgs {\n  char* const* argv;  // Command-line arguments for the child's call to exec\n  int close_fd;       // File descriptor to close; the read end of a pipe\n};\n\n#ifdef GTEST_OS_QNX\nextern \"C\" char** environ;\n#else   // GTEST_OS_QNX\n// The main function for a threadsafe-style death test child process.\n// This function is called in a clone()-ed process and thus must avoid\n// any potentially unsafe operations like malloc or libc functions.\nstatic int ExecDeathTestChildMain(void* child_arg) {\n  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));\n\n  // We need to execute the test program in the same environment where\n  // it was originally invoked.  Therefore we change to the original\n  // working directory first.\n  const char* const original_dir =\n      UnitTest::GetInstance()->original_working_dir();\n  // We can safely call chdir() as it's a direct system call.\n  if (chdir(original_dir) != 0) {\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir +\n                   \"\\\") failed: \" + GetLastErrnoDescription());\n    return EXIT_FAILURE;\n  }\n\n  // We can safely call execv() as it's almost a direct system call. We\n  // cannot use execvp() as it's a libc function and thus potentially\n  // unsafe.  Since execv() doesn't search the PATH, the user must\n  // invoke the test program via a valid path that contains at least\n  // one path separator.\n  execv(args->argv[0], args->argv);\n  DeathTestAbort(std::string(\"execv(\") + args->argv[0] + \", ...) in \" +\n                 original_dir + \" failed: \" + GetLastErrnoDescription());\n  return EXIT_FAILURE;\n}\n#endif  // GTEST_OS_QNX\n\n#if GTEST_HAS_CLONE\n// Two utility routines that together determine the direction the stack\n// grows.\n// This could be accomplished more elegantly by a single recursive\n// function, but we want to guard against the unlikely possibility of\n// a smart compiler optimizing the recursion away.\n//\n// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining\n// StackLowerThanAddress into StackGrowsDown, which then doesn't give\n// correct answer.\nstatic void StackLowerThanAddress(const void* ptr,\n                                  bool* result) GTEST_NO_INLINE_;\n// Make sure sanitizers do not tamper with the stack here.\n// Ideally, we want to use `__builtin_frame_address` instead of a local variable\n// address with sanitizer disabled, but it does not work when the\n// compiler optimizes the stack frame out, which happens on PowerPC targets.\n// HWAddressSanitizer add a random tag to the MSB of the local variable address,\n// making comparison result unpredictable.\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nstatic void StackLowerThanAddress(const void* ptr, bool* result) {\n  int dummy = 0;\n  *result = std::less<const void*>()(&dummy, ptr);\n}\n\n// Make sure AddressSanitizer does not tamper with the stack here.\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nstatic bool StackGrowsDown() {\n  int dummy = 0;\n  bool result;\n  StackLowerThanAddress(&dummy, &result);\n  return result;\n}\n#endif  // GTEST_HAS_CLONE\n\n// Spawns a child process with the same executable as the current process in\n// a thread-safe manner and instructs it to run the death test.  The\n// implementation uses fork(2) + exec.  On systems where clone(2) is\n// available, it is used instead, being slightly more thread-safe.  On QNX,\n// fork supports only single-threaded environments, so this function uses\n// spawn(2) there instead.  The function dies with an error message if\n// anything goes wrong.\nstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {\n  ExecDeathTestArgs args = {argv, close_fd};\n  pid_t child_pid = -1;\n\n#ifdef GTEST_OS_QNX\n  // Obtains the current directory and sets it to be closed in the child\n  // process.\n  const int cwd_fd = open(\".\", O_RDONLY);\n  GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));\n  // We need to execute the test program in the same environment where\n  // it was originally invoked.  Therefore we change to the original\n  // working directory first.\n  const char* const original_dir =\n      UnitTest::GetInstance()->original_working_dir();\n  // We can safely call chdir() as it's a direct system call.\n  if (chdir(original_dir) != 0) {\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir +\n                   \"\\\") failed: \" + GetLastErrnoDescription());\n    return EXIT_FAILURE;\n  }\n\n  int fd_flags;\n  // Set close_fd to be closed after spawn.\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC));\n  struct inheritance inherit = {0};\n  // spawn is a system call.\n  child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ);\n  // Restores the current working directory.\n  GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));\n\n#else  // GTEST_OS_QNX\n#ifdef GTEST_OS_LINUX\n  // When a SIGPROF signal is received while fork() or clone() are executing,\n  // the process may hang. To avoid this, we ignore SIGPROF here and re-enable\n  // it after the call to fork()/clone() is complete.\n  struct sigaction saved_sigprof_action;\n  struct sigaction ignore_sigprof_action;\n  memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));\n  sigemptyset(&ignore_sigprof_action.sa_mask);\n  ignore_sigprof_action.sa_handler = SIG_IGN;\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_CLONE\n  const bool use_fork = GTEST_FLAG_GET(death_test_use_fork);\n\n  if (!use_fork) {\n    static const bool stack_grows_down = StackGrowsDown();\n    const auto stack_size = static_cast<size_t>(getpagesize() * 2);\n    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.\n    void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,\n                             MAP_ANON | MAP_PRIVATE, -1, 0);\n    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);\n\n    // Maximum stack alignment in bytes:  For a downward-growing stack, this\n    // amount is subtracted from size of the stack space to get an address\n    // that is within the stack space and is aligned on all systems we care\n    // about.  As far as I know there is no ABI with stack alignment greater\n    // than 64.  We assume stack and stack_size already have alignment of\n    // kMaxStackAlignment.\n    const size_t kMaxStackAlignment = 64;\n    void* const stack_top =\n        static_cast<char*>(stack) +\n        (stack_grows_down ? stack_size - kMaxStackAlignment : 0);\n    GTEST_DEATH_TEST_CHECK_(\n        static_cast<size_t>(stack_size) > kMaxStackAlignment &&\n        reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0);\n\n    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);\n\n    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);\n  }\n#else\n  const bool use_fork = true;\n#endif  // GTEST_HAS_CLONE\n\n  if (use_fork && (child_pid = fork()) == 0) {\n    _Exit(ExecDeathTestChildMain(&args));\n  }\n#endif  // GTEST_OS_QNX\n#ifdef GTEST_OS_LINUX\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\n      sigaction(SIGPROF, &saved_sigprof_action, nullptr));\n#endif  // GTEST_OS_LINUX\n\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  return child_pid;\n}\n\n// The AssumeRole process for a fork-and-exec death test.  It re-executes the\n// main program from the beginning, setting the --gtest_filter\n// and --gtest_internal_run_death_test flags to cause only the current\n// death test to be re-run.\nDeathTest::TestRole ExecDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != nullptr) {\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n  // Clear the close-on-exec flag on the write end of the pipe, lest\n  // it be closed when the child process does an exec:\n  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);\n\n  const std::string filter_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                  \"filter=\" + info->test_suite_name() + \".\" +\n                                  info->name();\n  const std::string internal_flag = std::string(\"--\") + GTEST_FLAG_PREFIX_ +\n                                    \"internal_run_death_test=\" + file_ + \"|\" +\n                                    StreamableToString(line_) + \"|\" +\n                                    StreamableToString(death_test_index) + \"|\" +\n                                    StreamableToString(pipe_fd[1]);\n  std::vector<std::string> args = GetArgvsForDeathTestChildProcess();\n  args.push_back(filter_flag);\n  args.push_back(internal_flag);\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // See the comment in NoExecDeathTest::AssumeRole for why the next line\n  // is necessary.\n  FlushInfoLog();\n\n  std::vector<char*> argv = CreateArgvFromArgs(args);\n  const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n  set_child_pid(child_pid);\n  set_read_fd(pipe_fd[0]);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\n#endif  // !GTEST_OS_WINDOWS\n\n// Creates a concrete DeathTest-derived class that depends on the\n// --gtest_death_test_style flag, and sets the pointer pointed to\n// by the \"test\" argument to its address.  If the test should be\n// skipped, sets that pointer to NULL.  Returns true, unless the\n// flag is set to an invalid value.\nbool DefaultDeathTestFactory::Create(const char* statement,\n                                     Matcher<const std::string&> matcher,\n                                     const char* file, int line,\n                                     DeathTest** test) {\n  UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const int death_test_index =\n      impl->current_test_info()->increment_death_test_count();\n\n  if (flag != nullptr) {\n    if (death_test_index > flag->index()) {\n      DeathTest::set_last_death_test_message(\n          \"Death test count (\" + StreamableToString(death_test_index) +\n          \") somehow exceeded expected maximum (\" +\n          StreamableToString(flag->index()) + \")\");\n      return false;\n    }\n\n    if (!(flag->file() == file && flag->line() == line &&\n          flag->index() == death_test_index)) {\n      *test = nullptr;\n      return true;\n    }\n  }\n\n#ifdef GTEST_OS_WINDOWS\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\" ||\n      GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new WindowsDeathTest(statement, std::move(matcher), file, line);\n  }\n\n#elif defined(GTEST_OS_FUCHSIA)\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\" ||\n      GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);\n  }\n\n#else\n\n  if (GTEST_FLAG_GET(death_test_style) == \"threadsafe\") {\n    *test = new ExecDeathTest(statement, std::move(matcher), file, line);\n  } else if (GTEST_FLAG_GET(death_test_style) == \"fast\") {\n    *test = new NoExecDeathTest(statement, std::move(matcher));\n  }\n\n#endif  // GTEST_OS_WINDOWS\n\n  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.\n    DeathTest::set_last_death_test_message(\"Unknown death test style \\\"\" +\n                                           GTEST_FLAG_GET(death_test_style) +\n                                           \"\\\" encountered\");\n    return false;\n  }\n\n  return true;\n}\n\n#ifdef GTEST_OS_WINDOWS\n// Recreates the pipe and event handles from the provided parameters,\n// signals the event, and returns a file descriptor wrapped around the pipe\n// handle. This function is called in the child process only.\nstatic int GetStatusFileDescriptor(unsigned int parent_process_id,\n                                   size_t write_handle_as_size_t,\n                                   size_t event_handle_as_size_t) {\n  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,\n                                                 FALSE,  // Non-inheritable.\n                                                 parent_process_id));\n  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {\n    DeathTestAbort(\"Unable to open parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));\n\n  const HANDLE write_handle = reinterpret_cast<HANDLE>(write_handle_as_size_t);\n  HANDLE dup_write_handle;\n\n  // The newly initialized handle is accessible only in the parent\n  // process. To obtain one accessible within the child, we need to use\n  // DuplicateHandle.\n  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,\n                         ::GetCurrentProcess(), &dup_write_handle,\n                         0x0,    // Requested privileges ignored since\n                                 // DUPLICATE_SAME_ACCESS is used.\n                         FALSE,  // Request non-inheritable handler.\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(\"Unable to duplicate the pipe handle \" +\n                   StreamableToString(write_handle_as_size_t) +\n                   \" from the parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);\n  HANDLE dup_event_handle;\n\n  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,\n                         ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE,\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(\"Unable to duplicate the event handle \" +\n                   StreamableToString(event_handle_as_size_t) +\n                   \" from the parent process \" +\n                   StreamableToString(parent_process_id));\n  }\n\n  const int write_fd =\n      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);\n  if (write_fd == -1) {\n    DeathTestAbort(\"Unable to convert pipe handle \" +\n                   StreamableToString(write_handle_as_size_t) +\n                   \" to a file descriptor\");\n  }\n\n  // Signals the parent that the write end of the pipe has been acquired\n  // so the parent can release its own write end.\n  ::SetEvent(dup_event_handle);\n\n  return write_fd;\n}\n#endif  // GTEST_OS_WINDOWS\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {\n  if (GTEST_FLAG_GET(internal_run_death_test).empty()) return nullptr;\n\n  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we\n  // can use it here.\n  int line = -1;\n  int index = -1;\n  ::std::vector< ::std::string> fields;\n  SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields);\n  int write_fd = -1;\n\n#ifdef GTEST_OS_WINDOWS\n\n  unsigned int parent_process_id = 0;\n  size_t write_handle_as_size_t = 0;\n  size_t event_handle_as_size_t = 0;\n\n  if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index) ||\n      !ParseNaturalNumber(fields[3], &parent_process_id) ||\n      !ParseNaturalNumber(fields[4], &write_handle_as_size_t) ||\n      !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n  write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t,\n                                     event_handle_as_size_t);\n\n#elif defined(GTEST_OS_FUCHSIA)\n\n  if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n\n#else\n\n  if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) ||\n      !ParseNaturalNumber(fields[2], &index) ||\n      !ParseNaturalNumber(fields[3], &write_fd)) {\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\n                   GTEST_FLAG_GET(internal_run_death_test));\n  }\n\n#endif  // GTEST_OS_WINDOWS\n\n  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);\n}\n\n}  // namespace internal\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-filepath.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/internal/gtest-filepath.h\"\n\n#include <stdlib.h>\n\n#include <iterator>\n#include <string>\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n#include <windows.h>\n#elif defined(GTEST_OS_WINDOWS)\n#include <direct.h>\n#include <io.h>\n#else\n#include <limits.h>\n\n#include <climits>  // Some Linux distributions define PATH_MAX here.\n#endif              // GTEST_OS_WINDOWS_MOBILE\n\n#include \"gtest/internal/gtest-string.h\"\n\n#ifdef GTEST_OS_WINDOWS\n#define GTEST_PATH_MAX_ _MAX_PATH\n#elif defined(PATH_MAX)\n#define GTEST_PATH_MAX_ PATH_MAX\n#elif defined(_XOPEN_PATH_MAX)\n#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX\n#else\n#define GTEST_PATH_MAX_ _POSIX_PATH_MAX\n#endif  // GTEST_OS_WINDOWS\n\n#if GTEST_HAS_FILE_SYSTEM\n\nnamespace testing {\nnamespace internal {\n\n#ifdef GTEST_OS_WINDOWS\n// On Windows, '\\\\' is the standard path separator, but many tools and the\n// Windows API also accept '/' as an alternate path separator. Unless otherwise\n// noted, a file path can contain either kind of path separators, or a mixture\n// of them.\nconst char kPathSeparator = '\\\\';\nconst char kAlternatePathSeparator = '/';\nconst char kAlternatePathSeparatorString[] = \"/\";\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Windows CE doesn't have a current directory. You should not use\n// the current directory in tests on Windows CE, but this at least\n// provides a reasonable fallback.\nconst char kCurrentDirectoryString[] = \"\\\\\";\n// Windows CE doesn't define INVALID_FILE_ATTRIBUTES\nconst DWORD kInvalidFileAttributes = 0xffffffff;\n#else\nconst char kCurrentDirectoryString[] = \".\\\\\";\n#endif  // GTEST_OS_WINDOWS_MOBILE\n#else\nconst char kPathSeparator = '/';\nconst char kCurrentDirectoryString[] = \"./\";\n#endif  // GTEST_OS_WINDOWS\n\n// Returns whether the given character is a valid path separator.\nstatic bool IsPathSeparator(char c) {\n#if GTEST_HAS_ALT_PATH_SEP_\n  return (c == kPathSeparator) || (c == kAlternatePathSeparator);\n#else\n  return c == kPathSeparator;\n#endif\n}\n\n// Returns the current working directory, or \"\" if unsuccessful.\nFilePath FilePath::GetCurrentDir() {\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \\\n    defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) ||           \\\n    defined(GTEST_OS_ESP32) || defined(GTEST_OS_XTENSA) ||                 \\\n    defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) ||              \\\n    defined(GTEST_OS_NRF52)\n  // These platforms do not have a current directory, so we just return\n  // something reasonable.\n  return FilePath(kCurrentDirectoryString);\n#elif defined(GTEST_OS_WINDOWS)\n  char cwd[GTEST_PATH_MAX_ + 1] = {'\\0'};\n  return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? \"\" : cwd);\n#else\n  char cwd[GTEST_PATH_MAX_ + 1] = {'\\0'};\n  char* result = getcwd(cwd, sizeof(cwd));\n#ifdef GTEST_OS_NACL\n  // getcwd will likely fail in NaCl due to the sandbox, so return something\n  // reasonable. The user may have provided a shim implementation for getcwd,\n  // however, so fallback only when failure is detected.\n  return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);\n#endif  // GTEST_OS_NACL\n  return FilePath(result == nullptr ? \"\" : cwd);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns a copy of the FilePath with the case-insensitive extension removed.\n// Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n// FilePath(\"dir/file\"). If a case-insensitive extension is not\n// found, returns a copy of the original FilePath.\nFilePath FilePath::RemoveExtension(const char* extension) const {\n  const std::string dot_extension = std::string(\".\") + extension;\n  if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {\n    return FilePath(\n        pathname_.substr(0, pathname_.length() - dot_extension.length()));\n  }\n  return *this;\n}\n\n// Returns a pointer to the last occurrence of a valid path separator in\n// the FilePath. On Windows, for example, both '/' and '\\' are valid path\n// separators. Returns NULL if no path separator was found.\nconst char* FilePath::FindLastPathSeparator() const {\n  const char* const last_sep = strrchr(c_str(), kPathSeparator);\n#if GTEST_HAS_ALT_PATH_SEP_\n  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);\n  // Comparing two pointers of which only one is NULL is undefined.\n  if (last_alt_sep != nullptr &&\n      (last_sep == nullptr || last_alt_sep > last_sep)) {\n    return last_alt_sep;\n  }\n#endif\n  return last_sep;\n}\n\nsize_t FilePath::CalculateRootLength() const {\n  const auto& path = pathname_;\n  auto s = path.begin();\n  auto end = path.end();\n#ifdef GTEST_OS_WINDOWS\n  if (end - s >= 2 && s[1] == ':' && (end - s == 2 || IsPathSeparator(s[2])) &&\n      (('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) {\n    // A typical absolute path like \"C:\\Windows\" or \"D:\"\n    s += 2;\n    if (s != end) {\n      ++s;\n    }\n  } else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1)) &&\n             !IsPathSeparator(*(s + 2))) {\n    // Move past the \"\\\\\" prefix in a UNC path like \"\\\\Server\\Share\\Folder\"\n    s += 2;\n    // Skip 2 components and their following separators (\"Server\\\" and \"Share\\\")\n    for (int i = 0; i < 2; ++i) {\n      while (s != end) {\n        bool stop = IsPathSeparator(*s);\n        ++s;\n        if (stop) {\n          break;\n        }\n      }\n    }\n  } else if (s != end && IsPathSeparator(*s)) {\n    // A drive-rooted path like \"\\Windows\"\n    ++s;\n  }\n#else\n  if (s != end && IsPathSeparator(*s)) {\n    ++s;\n  }\n#endif\n  return static_cast<size_t>(s - path.begin());\n}\n\n// Returns a copy of the FilePath with the directory part removed.\n// Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n// FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n// the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n// returns an empty FilePath (\"\").\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveDirectoryName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  return last_sep ? FilePath(last_sep + 1) : *this;\n}\n\n// RemoveFileName returns the directory path with the filename removed.\n// Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n// If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n// FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n// not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveFileName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  std::string dir;\n  if (last_sep) {\n    dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));\n  } else {\n    dir = kCurrentDirectoryString;\n  }\n  return FilePath(dir);\n}\n\n// Helper functions for naming files in a directory for xml output.\n\n// Given directory = \"dir\", base_name = \"test\", number = 0,\n// extension = \"xml\", returns \"dir/test.xml\". If number is greater\n// than zero (e.g., 12), returns \"dir/test_12.xml\".\n// On Windows platform, uses \\ as the separator rather than /.\nFilePath FilePath::MakeFileName(const FilePath& directory,\n                                const FilePath& base_name, int number,\n                                const char* extension) {\n  std::string file;\n  if (number == 0) {\n    file = base_name.string() + \".\" + extension;\n  } else {\n    file =\n        base_name.string() + \"_\" + StreamableToString(number) + \".\" + extension;\n  }\n  return ConcatPaths(directory, FilePath(file));\n}\n\n// Given directory = \"dir\", relative_path = \"test.xml\", returns \"dir/test.xml\".\n// On Windows, uses \\ as the separator rather than /.\nFilePath FilePath::ConcatPaths(const FilePath& directory,\n                               const FilePath& relative_path) {\n  if (directory.IsEmpty()) return relative_path;\n  const FilePath dir(directory.RemoveTrailingPathSeparator());\n  return FilePath(dir.string() + kPathSeparator + relative_path.string());\n}\n\n// Returns true if pathname describes something findable in the file-system,\n// either a file, directory, or whatever.\nbool FilePath::FileOrDirectoryExists() const {\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete[] unicode;\n  return attributes != kInvalidFileAttributes;\n#else\n  posix::StatStruct file_stat{};\n  return posix::Stat(pathname_.c_str(), &file_stat) == 0;\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns true if pathname describes a directory in the file-system\n// that exists.\nbool FilePath::DirectoryExists() const {\n  bool result = false;\n#ifdef GTEST_OS_WINDOWS\n  // Don't strip off trailing separator if path is a root directory on\n  // Windows (like \"C:\\\\\").\n  const FilePath& path(IsRootDirectory() ? *this\n                                         : RemoveTrailingPathSeparator());\n#else\n  const FilePath& path(*this);\n#endif\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete[] unicode;\n  if ((attributes != kInvalidFileAttributes) &&\n      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {\n    result = true;\n  }\n#else\n  posix::StatStruct file_stat{};\n  result =\n      posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  return result;\n}\n\n// Returns true if pathname describes a root directory. (Windows has one\n// root directory per disk drive. UNC share roots are also included.)\nbool FilePath::IsRootDirectory() const {\n  size_t root_length = CalculateRootLength();\n  return root_length > 0 && root_length == pathname_.size() &&\n         IsPathSeparator(pathname_[root_length - 1]);\n}\n\n// Returns true if pathname describes an absolute path.\nbool FilePath::IsAbsolutePath() const { return CalculateRootLength() > 0; }\n\n// Returns a pathname for a file that does not currently exist. The pathname\n// will be directory/base_name.extension or\n// directory/base_name_<number>.extension if directory/base_name.extension\n// already exists. The number will be incremented until a pathname is found\n// that does not already exist.\n// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n// There could be a race condition if two or more processes are calling this\n// function at the same time -- they could both pick the same filename.\nFilePath FilePath::GenerateUniqueFileName(const FilePath& directory,\n                                          const FilePath& base_name,\n                                          const char* extension) {\n  FilePath full_pathname;\n  int number = 0;\n  do {\n    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));\n  } while (full_pathname.FileOrDirectoryExists());\n  return full_pathname;\n}\n\n// Returns true if FilePath ends with a path separator, which indicates that\n// it is intended to represent a directory. Returns false otherwise.\n// This does NOT check that a directory (or file) actually exists.\nbool FilePath::IsDirectory() const {\n  return !pathname_.empty() &&\n         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);\n}\n\n// Create directories so that path exists. Returns true if successful or if\n// the directories already exist; returns false if unable to create directories\n// for any reason.\nbool FilePath::CreateDirectoriesRecursively() const {\n  if (!this->IsDirectory()) {\n    return false;\n  }\n\n  if (pathname_.empty() || this->DirectoryExists()) {\n    return true;\n  }\n\n  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());\n  return parent.CreateDirectoriesRecursively() && this->CreateFolder();\n}\n\n// Create the directory so that path exists. Returns true if successful or\n// if the directory already exists; returns false if unable to create the\n// directory for any reason, including if the parent directory does not\n// exist. Not named \"CreateDirectory\" because that's a macro on Windows.\nbool FilePath::CreateFolder() const {\n#ifdef GTEST_OS_WINDOWS_MOBILE\n  FilePath removed_sep(this->RemoveTrailingPathSeparator());\n  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());\n  int result = CreateDirectory(unicode, nullptr) ? 0 : -1;\n  delete[] unicode;\n#elif defined(GTEST_OS_WINDOWS)\n  int result = _mkdir(pathname_.c_str());\n#elif defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \\\n    defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) ||  \\\n    defined(GTEST_OS_NRF52)\n  // do nothing\n  int result = 0;\n#else\n  int result = mkdir(pathname_.c_str(), 0777);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  if (result == -1) {\n    return this->DirectoryExists();  // An error is OK if the directory exists.\n  }\n  return true;  // No error.\n}\n\n// If input name has a trailing separator character, remove it and return the\n// name, otherwise return the name string unmodified.\n// On Windows platform, uses \\ as the separator, other platforms use /.\nFilePath FilePath::RemoveTrailingPathSeparator() const {\n  return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))\n                       : *this;\n}\n\n// Removes any redundant separators that might be in the pathname.\n// For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n// redundancies that might be in a pathname involving \".\" or \"..\".\n// Note that \"\\\\Host\\Share\" does not contain a redundancy on Windows!\nvoid FilePath::Normalize() {\n  auto out = pathname_.begin();\n\n  auto i = pathname_.cbegin();\n#ifdef GTEST_OS_WINDOWS\n  // UNC paths are treated specially\n  if (pathname_.end() - i >= 3 && IsPathSeparator(*i) &&\n      IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) {\n    *(out++) = kPathSeparator;\n    *(out++) = kPathSeparator;\n  }\n#endif\n  while (i != pathname_.end()) {\n    const char character = *i;\n    if (!IsPathSeparator(character)) {\n      *(out++) = character;\n    } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {\n      *(out++) = kPathSeparator;\n    }\n    ++i;\n  }\n\n  pathname_.erase(out, pathname_.end());\n}\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_HAS_FILE_SYSTEM\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-internal-inl.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Utility functions and classes used by the Google C++ testing framework.//\n// This file contains purely Google Test's internal implementation.  Please\n// DO NOT #INCLUDE IT IN A USER PROGRAM.\n\n#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n\n#ifndef _WIN32_WCE\n#include <errno.h>\n#endif  // !_WIN32_WCE\n#include <stddef.h>\n#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.\n#include <string.h>  // For memmove.\n\n#include <algorithm>\n#include <cstdint>\n#include <memory>\n#include <set>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\n#include \"gtest/internal/gtest-port.h\"\n\n#if GTEST_CAN_STREAM_RESULTS_\n#include <arpa/inet.h>  // NOLINT\n#include <netdb.h>      // NOLINT\n#endif\n\n#ifdef GTEST_OS_WINDOWS\n#include <windows.h>  // NOLINT\n#endif                // GTEST_OS_WINDOWS\n\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/gtest.h\"\n\nGTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \\\n/* class A needs to have dll-interface to be used by clients of class B */)\n\n// Declares the flags.\n//\n// We don't want the users to modify this flag in the code, but want\n// Google Test's own unit tests to be able to access it. Therefore we\n// declare it here as opposed to in gtest.h.\nGTEST_DECLARE_bool_(death_test_use_fork);\n\nnamespace testing {\nnamespace internal {\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nGTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;\n\n// A valid random seed must be in [1, kMaxRandomSeed].\nconst int kMaxRandomSeed = 99999;\n\n// g_help_flag is true if and only if the --help flag or an equivalent form\n// is specified on the command line.\nGTEST_API_ extern bool g_help_flag;\n\n// Returns the current time in milliseconds.\nGTEST_API_ TimeInMillis GetTimeInMillis();\n\n// Returns true if and only if Google Test should use colors in the output.\nGTEST_API_ bool ShouldUseColor(bool stdout_is_tty);\n\n// Formats the given time in milliseconds as seconds. If the input is an exact N\n// seconds, the output has a trailing decimal point (e.g., \"N.\" instead of \"N\").\nGTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);\n\n// Converts the given time in milliseconds to a date string in the ISO 8601\n// format, without the timezone information.  N.B.: due to the use the\n// non-reentrant localtime() function, this function is not thread safe.  Do\n// not use it in any code that can be called from multiple threads.\nGTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);\n\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nGTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);\n\n// Returns a random seed in range [1, kMaxRandomSeed] based on the\n// given --gtest_random_seed flag value.\ninline int GetRandomSeedFromFlag(int32_t random_seed_flag) {\n  const unsigned int raw_seed =\n      (random_seed_flag == 0) ? static_cast<unsigned int>(GetTimeInMillis())\n                              : static_cast<unsigned int>(random_seed_flag);\n\n  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that\n  // it's easy to type.\n  const int normalized_seed =\n      static_cast<int>((raw_seed - 1U) %\n                       static_cast<unsigned int>(kMaxRandomSeed)) +\n      1;\n  return normalized_seed;\n}\n\n// Returns the first valid random seed after 'seed'.  The behavior is\n// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is\n// considered to be 1.\ninline int GetNextRandomSeed(int seed) {\n  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)\n      << \"Invalid random seed \" << seed << \" - must be in [1, \"\n      << kMaxRandomSeed << \"].\";\n  const int next_seed = seed + 1;\n  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;\n}\n\n// This class saves the values of all Google Test flags in its c'tor, and\n// restores them in its d'tor.\nclass GTestFlagSaver {\n public:\n  // The c'tor.\n  GTestFlagSaver() {\n    also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);\n    break_on_failure_ = GTEST_FLAG_GET(break_on_failure);\n    catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);\n    color_ = GTEST_FLAG_GET(color);\n    death_test_style_ = GTEST_FLAG_GET(death_test_style);\n    death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);\n    fail_fast_ = GTEST_FLAG_GET(fail_fast);\n    filter_ = GTEST_FLAG_GET(filter);\n    internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);\n    list_tests_ = GTEST_FLAG_GET(list_tests);\n    output_ = GTEST_FLAG_GET(output);\n    brief_ = GTEST_FLAG_GET(brief);\n    print_time_ = GTEST_FLAG_GET(print_time);\n    print_utf8_ = GTEST_FLAG_GET(print_utf8);\n    random_seed_ = GTEST_FLAG_GET(random_seed);\n    repeat_ = GTEST_FLAG_GET(repeat);\n    recreate_environments_when_repeating_ =\n        GTEST_FLAG_GET(recreate_environments_when_repeating);\n    shuffle_ = GTEST_FLAG_GET(shuffle);\n    stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth);\n    stream_result_to_ = GTEST_FLAG_GET(stream_result_to);\n    throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure);\n  }\n\n  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.\n  ~GTestFlagSaver() {\n    GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);\n    GTEST_FLAG_SET(break_on_failure, break_on_failure_);\n    GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);\n    GTEST_FLAG_SET(color, color_);\n    GTEST_FLAG_SET(death_test_style, death_test_style_);\n    GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);\n    GTEST_FLAG_SET(filter, filter_);\n    GTEST_FLAG_SET(fail_fast, fail_fast_);\n    GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);\n    GTEST_FLAG_SET(list_tests, list_tests_);\n    GTEST_FLAG_SET(output, output_);\n    GTEST_FLAG_SET(brief, brief_);\n    GTEST_FLAG_SET(print_time, print_time_);\n    GTEST_FLAG_SET(print_utf8, print_utf8_);\n    GTEST_FLAG_SET(random_seed, random_seed_);\n    GTEST_FLAG_SET(repeat, repeat_);\n    GTEST_FLAG_SET(recreate_environments_when_repeating,\n                   recreate_environments_when_repeating_);\n    GTEST_FLAG_SET(shuffle, shuffle_);\n    GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_);\n    GTEST_FLAG_SET(stream_result_to, stream_result_to_);\n    GTEST_FLAG_SET(throw_on_failure, throw_on_failure_);\n  }\n\n private:\n  // Fields for saving the original values of flags.\n  bool also_run_disabled_tests_;\n  bool break_on_failure_;\n  bool catch_exceptions_;\n  std::string color_;\n  std::string death_test_style_;\n  bool death_test_use_fork_;\n  bool fail_fast_;\n  std::string filter_;\n  std::string internal_run_death_test_;\n  bool list_tests_;\n  std::string output_;\n  bool brief_;\n  bool print_time_;\n  bool print_utf8_;\n  int32_t random_seed_;\n  int32_t repeat_;\n  bool recreate_environments_when_repeating_;\n  bool shuffle_;\n  int32_t stack_trace_depth_;\n  std::string stream_result_to_;\n  bool throw_on_failure_;\n};\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type UInt32 because wchar_t may not be\n// wide enough to contain a code point.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\nGTEST_API_ std::string CodePointToUtf8(uint32_t code_point);\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nGTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);\n\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded();\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (e.g., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nGTEST_API_ bool ShouldShard(const char* total_shards_str,\n                            const char* shard_index_str,\n                            bool in_subprocess_for_death_test);\n\n// Parses the environment variable var as a 32-bit integer. If it is unset,\n// returns default_val. If it is not a 32-bit integer, prints an error and\n// and aborts.\nGTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val);\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true if and only if the test should be run on this shard. The test id\n// is some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nGTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index,\n                                     int test_id);\n\n// STL container utilities.\n\n// Returns the number of elements in the given container that satisfy\n// the given predicate.\ntemplate <class Container, typename Predicate>\ninline int CountIf(const Container& c, Predicate predicate) {\n  // Implemented as an explicit loop since std::count_if() in libCstd on\n  // Solaris has a non-standard signature.\n  int count = 0;\n  for (auto it = c.begin(); it != c.end(); ++it) {\n    if (predicate(*it)) ++count;\n  }\n  return count;\n}\n\n// Applies a function/functor to each element in the container.\ntemplate <class Container, typename Functor>\nvoid ForEach(const Container& c, Functor functor) {\n  std::for_each(c.begin(), c.end(), functor);\n}\n\n// Returns the i-th element of the vector, or default_value if i is not\n// in range [0, v.size()).\ntemplate <typename E>\ninline E GetElementOr(const std::vector<E>& v, int i, E default_value) {\n  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value\n                                                    : v[static_cast<size_t>(i)];\n}\n\n// Performs an in-place shuffle of a range of the vector's elements.\n// 'begin' and 'end' are element indices as an STL-style range;\n// i.e. [begin, end) are shuffled, where 'end' == size() means to\n// shuffle to the end of the vector.\ntemplate <typename E>\nvoid ShuffleRange(internal::Random* random, int begin, int end,\n                  std::vector<E>* v) {\n  const int size = static_cast<int>(v->size());\n  GTEST_CHECK_(0 <= begin && begin <= size)\n      << \"Invalid shuffle range start \" << begin << \": must be in range [0, \"\n      << size << \"].\";\n  GTEST_CHECK_(begin <= end && end <= size)\n      << \"Invalid shuffle range finish \" << end << \": must be in range [\"\n      << begin << \", \" << size << \"].\";\n\n  // Fisher-Yates shuffle, from\n  // https://en.wikipedia.org/wiki/Fisher-Yates_shuffle\n  for (int range_width = end - begin; range_width >= 2; range_width--) {\n    const int last_in_range = begin + range_width - 1;\n    const int selected =\n        begin +\n        static_cast<int>(random->Generate(static_cast<uint32_t>(range_width)));\n    std::swap((*v)[static_cast<size_t>(selected)],\n              (*v)[static_cast<size_t>(last_in_range)]);\n  }\n}\n\n// Performs an in-place shuffle of the vector's elements.\ntemplate <typename E>\ninline void Shuffle(internal::Random* random, std::vector<E>* v) {\n  ShuffleRange(random, 0, static_cast<int>(v->size()), v);\n}\n\n// A function for deleting an object.  Handy for being used as a\n// functor.\ntemplate <typename T>\nstatic void Delete(T* x) {\n  delete x;\n}\n\n// A predicate that checks the key of a TestProperty against a known key.\n//\n// TestPropertyKeyIs is copyable.\nclass TestPropertyKeyIs {\n public:\n  // Constructor.\n  //\n  // TestPropertyKeyIs has NO default constructor.\n  explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}\n\n  // Returns true if and only if the test name of test property matches on key_.\n  bool operator()(const TestProperty& test_property) const {\n    return test_property.key() == key_;\n  }\n\n private:\n  std::string key_;\n};\n\n// Class UnitTestOptions.\n//\n// This class contains functions for processing options the user\n// specifies when running the tests.  It has only static members.\n//\n// In most cases, the user can specify an option using either an\n// environment variable or a command line flag.  E.g. you can set the\n// test filter using either GTEST_FILTER or --gtest_filter.  If both\n// the variable and the flag are present, the latter overrides the\n// former.\nclass GTEST_API_ UnitTestOptions {\n public:\n  // Functions for processing the gtest_output flag.\n\n  // Returns the output format, or \"\" for normal printed output.\n  static std::string GetOutputFormat();\n\n  // Returns the absolute path of the requested output file, or the\n  // default (test_detail.xml in the original working directory) if\n  // none was explicitly specified.\n  static std::string GetAbsolutePathToOutputFile();\n\n  // Functions for processing the gtest_filter flag.\n\n  // Returns true if and only if the user-specified filter matches the test\n  // suite name and the test name.\n  static bool FilterMatchesTest(const std::string& test_suite_name,\n                                const std::string& test_name);\n\n#ifdef GTEST_OS_WINDOWS\n  // Function for supporting the gtest_catch_exception flag.\n\n  // Returns EXCEPTION_EXECUTE_HANDLER if given SEH exception was handled, or\n  // EXCEPTION_CONTINUE_SEARCH otherwise.\n  // This function is useful as an __except condition.\n  static int GTestProcessSEH(DWORD seh_code, const char* location);\n#endif  // GTEST_OS_WINDOWS\n\n  // Returns true if \"name\" matches the ':' separated list of glob-style\n  // filters in \"filter\".\n  static bool MatchesFilter(const std::string& name, const char* filter);\n};\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the current application's name, removing directory path if that\n// is present.  Used by UnitTestOptions::GetOutputFile.\nGTEST_API_ FilePath GetCurrentExecutableName();\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// The role interface for getting the OS stack trace as a string.\nclass OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetterInterface() = default;\n  virtual ~OsStackTraceGetterInterface() = default;\n\n  // Returns the current OS stack trace as an std::string.  Parameters:\n  //\n  //   max_depth  - the maximum number of stack frames to be included\n  //                in the trace.\n  //   skip_count - the number of top frames to be skipped; doesn't count\n  //                against max_depth.\n  virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;\n\n  // UponLeavingGTest() should be called immediately before Google Test calls\n  // user code. It saves some information about the current stack that\n  // CurrentStackTrace() will use to find and hide Google Test stack frames.\n  virtual void UponLeavingGTest() = 0;\n\n  // This string is inserted in place of stack frames that are part of\n  // Google Test's implementation.\n  static const char* const kElidedFramesMarker;\n\n private:\n  OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete;\n  OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) =\n      delete;\n};\n\n// A working implementation of the OsStackTraceGetterInterface interface.\nclass OsStackTraceGetter : public OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetter() = default;\n\n  std::string CurrentStackTrace(int max_depth, int skip_count) override;\n  void UponLeavingGTest() override;\n\n private:\n#ifdef GTEST_HAS_ABSL\n  Mutex mutex_;  // Protects all internal state.\n\n  // We save the stack frame below the frame that calls user code.\n  // We do this because the address of the frame immediately below\n  // the user code changes between the call to UponLeavingGTest()\n  // and any calls to the stack trace code from within the user code.\n  void* caller_frame_ = nullptr;\n#endif  // GTEST_HAS_ABSL\n\n  OsStackTraceGetter(const OsStackTraceGetter&) = delete;\n  OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete;\n};\n\n// Information about a Google Test trace point.\nstruct TraceInfo {\n  const char* file;\n  int line;\n  std::string message;\n};\n\n// This is the default global test part result reporter used in UnitTestImpl.\n// This class should only be used by UnitTestImpl.\nclass DefaultGlobalTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. Reports the test part\n  // result in the current test.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  DefaultGlobalTestPartResultReporter(\n      const DefaultGlobalTestPartResultReporter&) = delete;\n  DefaultGlobalTestPartResultReporter& operator=(\n      const DefaultGlobalTestPartResultReporter&) = delete;\n};\n\n// This is the default per thread test part result reporter used in\n// UnitTestImpl. This class should only be used by UnitTestImpl.\nclass DefaultPerThreadTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. The implementation just\n  // delegates to the current global test part result reporter of *unit_test_.\n  void ReportTestPartResult(const TestPartResult& result) override;\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  DefaultPerThreadTestPartResultReporter(\n      const DefaultPerThreadTestPartResultReporter&) = delete;\n  DefaultPerThreadTestPartResultReporter& operator=(\n      const DefaultPerThreadTestPartResultReporter&) = delete;\n};\n\n// The private implementation of the UnitTest class.  We don't protect\n// the methods under a mutex, as this class is not accessible by a\n// user and the UnitTest class that delegates work to this class does\n// proper locking.\nclass GTEST_API_ UnitTestImpl {\n public:\n  explicit UnitTestImpl(UnitTest* parent);\n  virtual ~UnitTestImpl();\n\n  // There are two different ways to register your own TestPartResultReporter.\n  // You can register your own reporter to listen either only for test results\n  // from the current thread or for results from all threads.\n  // By default, each per-thread test result reporter just passes a new\n  // TestPartResult to the global test result reporter, which registers the\n  // test part result for the currently running test.\n\n  // Returns the global test part result reporter.\n  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();\n\n  // Sets the global test part result reporter.\n  void SetGlobalTestPartResultReporter(\n      TestPartResultReporterInterface* reporter);\n\n  // Returns the test part result reporter for the current thread.\n  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();\n\n  // Sets the test part result reporter for the current thread.\n  void SetTestPartResultReporterForCurrentThread(\n      TestPartResultReporterInterface* reporter);\n\n  // Gets the number of successful test suites.\n  int successful_test_suite_count() const;\n\n  // Gets the number of failed test suites.\n  int failed_test_suite_count() const;\n\n  // Gets the number of all test suites.\n  int total_test_suite_count() const;\n\n  // Gets the number of all test suites that contain at least one test\n  // that should run.\n  int test_suite_to_run_count() const;\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of skipped tests.\n  int skipped_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests that will be reported in the XML report.\n  int reportable_disabled_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of tests to be printed in the XML report.\n  int reportable_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp() const { return start_timestamp_; }\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Returns true if and only if the unit test passed (i.e. all test suites\n  // passed).\n  bool Passed() const { return !Failed(); }\n\n  // Returns true if and only if the unit test failed (i.e. some test suite\n  // failed or something outside of all tests failed).\n  bool Failed() const {\n    return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();\n  }\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  const TestSuite* GetTestSuite(int i) const {\n    const int index = GetElementOr(test_suite_indices_, i, -1);\n    return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];\n  }\n\n  //  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Gets the i-th test suite among all the test suites. i can range from 0 to\n  // total_test_suite_count() - 1. If i is not in that range, returns NULL.\n  TestSuite* GetMutableSuiteCase(int i) {\n    const int index = GetElementOr(test_suite_indices_, i, -1);\n    return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];\n  }\n\n  // Provides access to the event listener list.\n  TestEventListeners* listeners() { return &listeners_; }\n\n  // Returns the TestResult for the test that's currently running, or\n  // the TestResult for the ad hoc test if no test is running.\n  TestResult* current_test_result();\n\n  // Returns the TestResult for the ad hoc test.\n  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }\n\n  // Sets the OS stack trace getter.\n  //\n  // Does nothing if the input and the current OS stack trace getter\n  // are the same; otherwise, deletes the old getter and makes the\n  // input the current getter.\n  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);\n\n  // Returns the current OS stack trace getter if it is not NULL;\n  // otherwise, creates an OsStackTraceGetter, makes it the current\n  // getter, and returns it.\n  OsStackTraceGetterInterface* os_stack_trace_getter();\n\n  // Returns the current OS stack trace as an std::string.\n  //\n  // The maximum number of stack frames to be included is specified by\n  // the gtest_stack_trace_depth flag.  The skip_count parameter\n  // specifies the number of top frames to be skipped, which doesn't\n  // count against the number of frames to be included.\n  //\n  // For example, if Foo() calls Bar(), which in turn calls\n  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.\n  std::string CurrentOsStackTraceExceptTop(int skip_count)\n      GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_;\n\n  // Finds and returns a TestSuite with the given name.  If one doesn't\n  // exist, creates one and returns it.\n  //\n  // Arguments:\n  //\n  //   test_suite_name: name of the test suite\n  //   type_param:      the name of the test's type parameter, or NULL if\n  //                    this is not a typed or a type-parameterized test.\n  //   set_up_tc:       pointer to the function that sets up the test suite\n  //   tear_down_tc:    pointer to the function that tears down the test suite\n  TestSuite* GetTestSuite(const std::string& test_suite_name,\n                          const char* type_param,\n                          internal::SetUpTestSuiteFunc set_up_tc,\n                          internal::TearDownTestSuiteFunc tear_down_tc);\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  TestCase* GetTestCase(const std::string& test_case_name,\n                        const char* type_param,\n                        internal::SetUpTestSuiteFunc set_up_tc,\n                        internal::TearDownTestSuiteFunc tear_down_tc) {\n    return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);\n  }\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  // Adds a TestInfo to the unit test.\n  //\n  // Arguments:\n  //\n  //   set_up_tc:    pointer to the function that sets up the test suite\n  //   tear_down_tc: pointer to the function that tears down the test suite\n  //   test_info:    the TestInfo object\n  void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,\n                   internal::TearDownTestSuiteFunc tear_down_tc,\n                   TestInfo* test_info) {\n#if GTEST_HAS_FILE_SYSTEM\n    // In order to support thread-safe death tests, we need to\n    // remember the original working directory when the test program\n    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as\n    // the user may have changed the current directory before calling\n    // RUN_ALL_TESTS().  Therefore we capture the current directory in\n    // AddTestInfo(), which is called to register a TEST or TEST_F\n    // before main() is reached.\n    if (original_working_dir_.IsEmpty()) {\n      original_working_dir_ = FilePath::GetCurrentDir();\n      GTEST_CHECK_(!original_working_dir_.IsEmpty())\n          << \"Failed to get the current working directory.\";\n    }\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n    GetTestSuite(test_info->test_suite_name_, test_info->type_param(),\n                 set_up_tc, tear_down_tc)\n        ->AddTestInfo(test_info);\n  }\n\n  // Returns ParameterizedTestSuiteRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {\n    return parameterized_test_registry_;\n  }\n\n  std::set<std::string>* ignored_parameterized_test_suites() {\n    return &ignored_parameterized_test_suites_;\n  }\n\n  // Returns TypeParameterizedTestSuiteRegistry object used to keep track of\n  // type-parameterized tests and instantiations of them.\n  internal::TypeParameterizedTestSuiteRegistry&\n  type_parameterized_test_registry() {\n    return type_parameterized_test_registry_;\n  }\n\n  // Registers all parameterized tests defined using TEST_P and\n  // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter\n  // combination. This method can be called more then once; it has guards\n  // protecting from registering the tests more then once.  If\n  // value-parameterized tests are disabled, RegisterParameterizedTests is\n  // present but does nothing.\n  void RegisterParameterizedTests();\n\n  // Runs all tests in this UnitTest object, prints the result, and\n  // returns true if all tests are successful.  If any exception is\n  // thrown during a test, this test is considered to be failed, but\n  // the rest of the tests will still be run.\n  bool RunAllTests();\n\n  // Clears the results of all tests, except the ad hoc tests.\n  void ClearNonAdHocTestResult() {\n    ForEach(test_suites_, TestSuite::ClearTestSuiteResult);\n  }\n\n  // Clears the results of ad-hoc test assertions.\n  void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); }\n\n  // Adds a TestProperty to the current TestResult object when invoked in a\n  // context of a test or a test suite, or to the global property set. If the\n  // result already contains a property with the same key, the value will be\n  // updated.\n  void RecordProperty(const TestProperty& test_property);\n\n  enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL };\n\n  // Matches the full name of each test against the user-specified\n  // filter to decide whether the test should run, then records the\n  // result in each TestSuite and TestInfo object.\n  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests\n  // based on sharding variables in the environment.\n  // Returns the number of tests that should run.\n  int FilterTests(ReactionToSharding shard_tests);\n\n  // Prints the names of the tests matching the user-specified filter flag.\n  void ListTestsMatchingFilter();\n\n  const TestSuite* current_test_suite() const { return current_test_suite_; }\n  TestInfo* current_test_info() { return current_test_info_; }\n  const TestInfo* current_test_info() const { return current_test_info_; }\n\n  // Returns the vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*>& environments() { return environments_; }\n\n  // Getters for the per-thread Google Test trace stack.\n  std::vector<TraceInfo>& gtest_trace_stack() {\n    return *(gtest_trace_stack_.pointer());\n  }\n  const std::vector<TraceInfo>& gtest_trace_stack() const {\n    return gtest_trace_stack_.get();\n  }\n\n#ifdef GTEST_HAS_DEATH_TEST\n  void InitDeathTestSubprocessControlInfo() {\n    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());\n  }\n  // Returns a pointer to the parsed --gtest_internal_run_death_test\n  // flag, or NULL if that flag was not specified.\n  // This information is useful only in a death test child process.\n  // Must not be called before a call to InitGoogleTest.\n  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {\n    return internal_run_death_test_flag_.get();\n  }\n\n  // Returns a pointer to the current death test factory.\n  internal::DeathTestFactory* death_test_factory() {\n    return death_test_factory_.get();\n  }\n\n  void SuppressTestEventsIfInSubprocess();\n\n  friend class ReplaceDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // Initializes the event listener performing XML output as specified by\n  // UnitTestOptions. Must not be called before InitGoogleTest.\n  void ConfigureXmlOutput();\n\n#if GTEST_CAN_STREAM_RESULTS_\n  // Initializes the event listener for streaming test results to a socket.\n  // Must not be called before InitGoogleTest.\n  void ConfigureStreamingOutput();\n#endif\n\n  // Performs initialization dependent upon flag values obtained in\n  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n  // this function is also called from RunAllTests.  Since this function can be\n  // called more than once, it has to be idempotent.\n  void PostFlagParsingInit();\n\n  // Gets the random seed used at the start of the current test iteration.\n  int random_seed() const { return random_seed_; }\n\n  // Gets the random number generator.\n  internal::Random* random() { return &random_; }\n\n  // Shuffles all test suites, and the tests within each test suite,\n  // making sure that death tests are still run first.\n  void ShuffleTests();\n\n  // Restores the test suites and tests to their order before the first shuffle.\n  void UnshuffleTests();\n\n  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment\n  // UnitTest::Run() starts.\n  bool catch_exceptions() const { return catch_exceptions_; }\n\n private:\n  struct CompareTestSuitesByPointer {\n    bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {\n      return lhs->name_ < rhs->name_;\n    }\n  };\n\n  friend class ::testing::UnitTest;\n\n  // Used by UnitTest::Run() to capture the state of\n  // GTEST_FLAG(catch_exceptions) at the moment it starts.\n  void set_catch_exceptions(bool value) { catch_exceptions_ = value; }\n\n  // Sets the TestSuite object for the test that's currently running.\n  void set_current_test_suite(TestSuite* a_current_test_suite) {\n    current_test_suite_ = a_current_test_suite;\n  }\n\n  // Sets the TestInfo object for the test that's currently running.  If\n  // current_test_info is NULL, the assertion results will be stored in\n  // ad_hoc_test_result_.\n  void set_current_test_info(TestInfo* a_current_test_info) {\n    current_test_info_ = a_current_test_info;\n  }\n\n  // The UnitTest object that owns this implementation object.\n  UnitTest* const parent_;\n\n#if GTEST_HAS_FILE_SYSTEM\n  // The working directory when the first TEST() or TEST_F() was\n  // executed.\n  internal::FilePath original_working_dir_;\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n  // The default test part result reporters.\n  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;\n  DefaultPerThreadTestPartResultReporter\n      default_per_thread_test_part_result_reporter_;\n\n  // Points to (but doesn't own) the global test part result reporter.\n  TestPartResultReporterInterface* global_test_part_result_reporter_;\n\n  // Protects read and write access to global_test_part_result_reporter_.\n  internal::Mutex global_test_part_result_reporter_mutex_;\n\n  // Points to (but doesn't own) the per-thread test part result reporter.\n  internal::ThreadLocal<TestPartResultReporterInterface*>\n      per_thread_test_part_result_reporter_;\n\n  // The vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*> environments_;\n\n  // The vector of TestSuites in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestSuite*> test_suites_;\n\n  // The set of TestSuites by name.\n  std::unordered_map<std::string, TestSuite*> test_suites_by_name_;\n\n  // Provides a level of indirection for the test suite list to allow\n  // easy shuffling and restoring the test suite order.  The i-th\n  // element of this vector is the index of the i-th test suite in the\n  // shuffled order.\n  std::vector<int> test_suite_indices_;\n\n  // ParameterizedTestRegistry object used to register value-parameterized\n  // tests.\n  internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;\n  internal::TypeParameterizedTestSuiteRegistry\n      type_parameterized_test_registry_;\n\n  // The set holding the name of parameterized\n  // test suites that may go uninstantiated.\n  std::set<std::string> ignored_parameterized_test_suites_;\n\n  // Indicates whether RegisterParameterizedTests() has been called already.\n  bool parameterized_tests_registered_;\n\n  // Index of the last death test suite registered.  Initially -1.\n  int last_death_test_suite_;\n\n  // This points to the TestSuite for the currently running test.  It\n  // changes as Google Test goes through one test suite after another.\n  // When no test is running, this is set to NULL and Google Test\n  // stores assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestSuite* current_test_suite_;\n\n  // This points to the TestInfo for the currently running test.  It\n  // changes as Google Test goes through one test after another.  When\n  // no test is running, this is set to NULL and Google Test stores\n  // assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestInfo* current_test_info_;\n\n  // Normally, a user only writes assertions inside a TEST or TEST_F,\n  // or inside a function called by a TEST or TEST_F.  Since Google\n  // Test keeps track of which test is current running, it can\n  // associate such an assertion with the test it belongs to.\n  //\n  // If an assertion is encountered when no TEST or TEST_F is running,\n  // Google Test attributes the assertion result to an imaginary \"ad hoc\"\n  // test, and records the result in ad_hoc_test_result_.\n  TestResult ad_hoc_test_result_;\n\n  // The list of event listeners that can be used to track events inside\n  // Google Test.\n  TestEventListeners listeners_;\n\n  // The OS stack trace getter.  Will be deleted when the UnitTest\n  // object is destructed.  By default, an OsStackTraceGetter is used,\n  // but the user can set this field to use a custom getter if that is\n  // desired.\n  OsStackTraceGetterInterface* os_stack_trace_getter_;\n\n  // True if and only if PostFlagParsingInit() has been called.\n  bool post_flag_parse_init_performed_;\n\n  // The random number seed used at the beginning of the test run.\n  int random_seed_;\n\n  // Our random number generator.\n  internal::Random random_;\n\n  // The time of the test program start, in ms from the start of the\n  // UNIX epoch.\n  TimeInMillis start_timestamp_;\n\n  // How long the test took to run, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n#ifdef GTEST_HAS_DEATH_TEST\n  // The decomposed components of the gtest_internal_run_death_test flag,\n  // parsed when RUN_ALL_TESTS is called.\n  std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;\n  std::unique_ptr<internal::DeathTestFactory> death_test_factory_;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // A per-thread stack of traces created by the SCOPED_TRACE() macro.\n  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;\n\n  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()\n  // starts.\n  bool catch_exceptions_;\n\n  UnitTestImpl(const UnitTestImpl&) = delete;\n  UnitTestImpl& operator=(const UnitTestImpl&) = delete;\n};  // class UnitTestImpl\n\n// Convenience function for accessing the global UnitTest\n// implementation object.\ninline UnitTestImpl* GetUnitTestImpl() {\n  return UnitTest::GetInstance()->impl();\n}\n\n#ifdef GTEST_USES_SIMPLE_RE\n\n// Internal helper functions for implementing the simple regular\n// expression matcher.\nGTEST_API_ bool IsInSet(char ch, const char* str);\nGTEST_API_ bool IsAsciiDigit(char ch);\nGTEST_API_ bool IsAsciiPunct(char ch);\nGTEST_API_ bool IsRepeat(char ch);\nGTEST_API_ bool IsAsciiWhiteSpace(char ch);\nGTEST_API_ bool IsAsciiWordChar(char ch);\nGTEST_API_ bool IsValidEscape(char ch);\nGTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);\nGTEST_API_ bool ValidateRegex(const char* regex);\nGTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);\nGTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,\n                                              char repeat, const char* regex,\n                                              const char* str);\nGTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);\n\n#endif  // GTEST_USES_SIMPLE_RE\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);\n\n#ifdef GTEST_HAS_DEATH_TEST\n\n// Returns the message describing the last system error, regardless of the\n// platform.\nGTEST_API_ std::string GetLastErrnoDescription();\n\n// Attempts to parse a string into a positive integer pointed to by the\n// number parameter.  Returns true if that is possible.\n// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use\n// it here.\ntemplate <typename Integer>\nbool ParseNaturalNumber(const ::std::string& str, Integer* number) {\n  // Fail fast if the given string does not begin with a digit;\n  // this bypasses strtoXXX's \"optional leading whitespace and plus\n  // or minus sign\" semantics, which are undesirable here.\n  if (str.empty() || !IsDigit(str[0])) {\n    return false;\n  }\n  errno = 0;\n\n  char* end;\n  // BiggestConvertible is the largest integer type that system-provided\n  // string-to-number conversion routines can return.\n  using BiggestConvertible = unsigned long long;  // NOLINT\n\n  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);  // NOLINT\n  const bool parse_success = *end == '\\0' && errno == 0;\n\n  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));\n\n  const Integer result = static_cast<Integer>(parsed);\n  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {\n    *number = result;\n    return true;\n  }\n  return false;\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// TestResult contains some private methods that should be hidden from\n// Google Test user but are required for testing. This class allow our tests\n// to access them.\n//\n// This class is supplied only for the purpose of testing Google Test's own\n// constructs. Do not use it in user tests, either directly or indirectly.\nclass TestResultAccessor {\n public:\n  static void RecordProperty(TestResult* test_result,\n                             const std::string& xml_element,\n                             const TestProperty& property) {\n    test_result->RecordProperty(xml_element, property);\n  }\n\n  static void ClearTestPartResults(TestResult* test_result) {\n    test_result->ClearTestPartResults();\n  }\n\n  static const std::vector<testing::TestPartResult>& test_part_results(\n      const TestResult& test_result) {\n    return test_result.test_part_results();\n  }\n};\n\n#if GTEST_CAN_STREAM_RESULTS_\n\n// Streams test results to the given port on the given host machine.\nclass StreamingListener : public EmptyTestEventListener {\n public:\n  // Abstract base class for writing strings to a socket.\n  class AbstractSocketWriter {\n   public:\n    virtual ~AbstractSocketWriter() = default;\n\n    // Sends a string to the socket.\n    virtual void Send(const std::string& message) = 0;\n\n    // Closes the socket.\n    virtual void CloseConnection() {}\n\n    // Sends a string and a newline to the socket.\n    void SendLn(const std::string& message) { Send(message + \"\\n\"); }\n  };\n\n  // Concrete class for actually writing strings to a socket.\n  class SocketWriter : public AbstractSocketWriter {\n   public:\n    SocketWriter(const std::string& host, const std::string& port)\n        : sockfd_(-1), host_name_(host), port_num_(port) {\n      MakeConnection();\n    }\n\n    ~SocketWriter() override {\n      if (sockfd_ != -1) CloseConnection();\n    }\n\n    // Sends a string to the socket.\n    void Send(const std::string& message) override {\n      GTEST_CHECK_(sockfd_ != -1)\n          << \"Send() can be called only when there is a connection.\";\n\n      const auto len = static_cast<size_t>(message.length());\n      if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {\n        GTEST_LOG_(WARNING) << \"stream_result_to: failed to stream to \"\n                            << host_name_ << \":\" << port_num_;\n      }\n    }\n\n   private:\n    // Creates a client socket and connects to the server.\n    void MakeConnection();\n\n    // Closes the socket.\n    void CloseConnection() override {\n      GTEST_CHECK_(sockfd_ != -1)\n          << \"CloseConnection() can be called only when there is a connection.\";\n\n      close(sockfd_);\n      sockfd_ = -1;\n    }\n\n    int sockfd_;  // socket file descriptor\n    const std::string host_name_;\n    const std::string port_num_;\n\n    SocketWriter(const SocketWriter&) = delete;\n    SocketWriter& operator=(const SocketWriter&) = delete;\n  };  // class SocketWriter\n\n  // Escapes '=', '&', '%', and '\\n' characters in str as \"%xx\".\n  static std::string UrlEncode(const char* str);\n\n  StreamingListener(const std::string& host, const std::string& port)\n      : socket_writer_(new SocketWriter(host, port)) {\n    Start();\n  }\n\n  explicit StreamingListener(AbstractSocketWriter* socket_writer)\n      : socket_writer_(socket_writer) {\n    Start();\n  }\n\n  void OnTestProgramStart(const UnitTest& /* unit_test */) override {\n    SendLn(\"event=TestProgramStart\");\n  }\n\n  void OnTestProgramEnd(const UnitTest& unit_test) override {\n    // Note that Google Test current only report elapsed time for each\n    // test iteration, not for the entire test program.\n    SendLn(\"event=TestProgramEnd&passed=\" + FormatBool(unit_test.Passed()));\n\n    // Notify the streaming server to stop.\n    socket_writer_->CloseConnection();\n  }\n\n  void OnTestIterationStart(const UnitTest& /* unit_test */,\n                            int iteration) override {\n    SendLn(\"event=TestIterationStart&iteration=\" +\n           StreamableToString(iteration));\n  }\n\n  void OnTestIterationEnd(const UnitTest& unit_test,\n                          int /* iteration */) override {\n    SendLn(\"event=TestIterationEnd&passed=\" + FormatBool(unit_test.Passed()) +\n           \"&elapsed_time=\" + StreamableToString(unit_test.elapsed_time()) +\n           \"ms\");\n  }\n\n  // Note that \"event=TestCaseStart\" is a wire format and has to remain\n  // \"case\" for compatibility\n  void OnTestSuiteStart(const TestSuite& test_suite) override {\n    SendLn(std::string(\"event=TestCaseStart&name=\") + test_suite.name());\n  }\n\n  // Note that \"event=TestCaseEnd\" is a wire format and has to remain\n  // \"case\" for compatibility\n  void OnTestSuiteEnd(const TestSuite& test_suite) override {\n    SendLn(\"event=TestCaseEnd&passed=\" + FormatBool(test_suite.Passed()) +\n           \"&elapsed_time=\" + StreamableToString(test_suite.elapsed_time()) +\n           \"ms\");\n  }\n\n  void OnTestStart(const TestInfo& test_info) override {\n    SendLn(std::string(\"event=TestStart&name=\") + test_info.name());\n  }\n\n  void OnTestEnd(const TestInfo& test_info) override {\n    SendLn(\"event=TestEnd&passed=\" +\n           FormatBool((test_info.result())->Passed()) + \"&elapsed_time=\" +\n           StreamableToString((test_info.result())->elapsed_time()) + \"ms\");\n  }\n\n  void OnTestPartResult(const TestPartResult& test_part_result) override {\n    const char* file_name = test_part_result.file_name();\n    if (file_name == nullptr) file_name = \"\";\n    SendLn(\"event=TestPartResult&file=\" + UrlEncode(file_name) +\n           \"&line=\" + StreamableToString(test_part_result.line_number()) +\n           \"&message=\" + UrlEncode(test_part_result.message()));\n  }\n\n private:\n  // Sends the given message and a newline to the socket.\n  void SendLn(const std::string& message) { socket_writer_->SendLn(message); }\n\n  // Called at the start of streaming to notify the receiver what\n  // protocol we are using.\n  void Start() { SendLn(\"gtest_streaming_protocol_version=1.0\"); }\n\n  std::string FormatBool(bool value) { return value ? \"1\" : \"0\"; }\n\n  const std::unique_ptr<AbstractSocketWriter> socket_writer_;\n\n  StreamingListener(const StreamingListener&) = delete;\n  StreamingListener& operator=(const StreamingListener&) = delete;\n};  // class StreamingListener\n\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n}  // namespace internal\n}  // namespace testing\n\nGTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251\n\n#endif  // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-matchers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// The Google C++ Testing and Mocking Framework (Google Test)\n//\n// This file implements just enough of the matcher interface to allow\n// EXPECT_DEATH and friends to accept a matcher argument.\n\n#include \"gtest/gtest-matchers.h\"\n\n#include <string>\n\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-port.h\"\n\nnamespace testing {\n\n// Constructs a matcher that matches a const std::string& whose value is\n// equal to s.\nMatcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a const std::string& whose value is\n// equal to s.\nMatcher<const std::string&>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a std::string whose value is equal to\n// s.\nMatcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a std::string whose value is equal to\n// s.\nMatcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }\n\n#if GTEST_INTERNAL_HAS_STRING_VIEW\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(const std::string& s) {\n  *this = Eq(s);\n}\n\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a const StringView& whose value is\n// equal to s.\nMatcher<const internal::StringView&>::Matcher(internal::StringView s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); }\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(const char* s) {\n  *this = Eq(std::string(s));\n}\n\n// Constructs a matcher that matches a StringView whose value is equal to\n// s.\nMatcher<internal::StringView>::Matcher(internal::StringView s) {\n  *this = Eq(std::string(s));\n}\n#endif  // GTEST_INTERNAL_HAS_STRING_VIEW\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-port.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/internal/gtest-port.h\"\n\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <cstdint>\n#include <fstream>\n#include <memory>\n#include <ostream>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifdef GTEST_OS_WINDOWS\n#include <io.h>\n#include <sys/stat.h>\n#include <windows.h>\n\n#include <map>  // Used in ThreadLocal.\n#ifdef _MSC_VER\n#include <crtdbg.h>\n#endif  // _MSC_VER\n#else\n#include <unistd.h>\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_MAC\n#include <mach/mach_init.h>\n#include <mach/task.h>\n#include <mach/vm_map.h>\n#endif  // GTEST_OS_MAC\n\n#if defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) ||   \\\n    defined(GTEST_OS_GNU_KFREEBSD) || defined(GTEST_OS_NETBSD) || \\\n    defined(GTEST_OS_OPENBSD)\n#include <sys/sysctl.h>\n#if defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) || \\\n    defined(GTEST_OS_GNU_KFREEBSD)\n#include <sys/user.h>\n#endif\n#endif\n\n#ifdef GTEST_OS_QNX\n#include <devctl.h>\n#include <fcntl.h>\n#include <sys/procfs.h>\n#endif  // GTEST_OS_QNX\n\n#ifdef GTEST_OS_AIX\n#include <procinfo.h>\n#include <sys/types.h>\n#endif  // GTEST_OS_AIX\n\n#ifdef GTEST_OS_FUCHSIA\n#include <zircon/process.h>\n#include <zircon/syscalls.h>\n#endif  // GTEST_OS_FUCHSIA\n\n#include \"gtest/gtest-message.h\"\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/internal/gtest-internal.h\"\n#include \"gtest/internal/gtest-string.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\nnamespace internal {\n\n#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_GNU_HURD)\n\nnamespace {\ntemplate <typename T>\nT ReadProcFileField(const std::string& filename, int field) {\n  std::string dummy;\n  std::ifstream file(filename.c_str());\n  while (field-- > 0) {\n    file >> dummy;\n  }\n  T output = 0;\n  file >> output;\n  return output;\n}\n}  // namespace\n\n// Returns the number of active threads, or 0 when there is an error.\nsize_t GetThreadCount() {\n  const std::string filename =\n      (Message() << \"/proc/\" << getpid() << \"/stat\").GetString();\n  return ReadProcFileField<size_t>(filename, 19);\n}\n\n#elif defined(GTEST_OS_MAC)\n\nsize_t GetThreadCount() {\n  const task_t task = mach_task_self();\n  mach_msg_type_number_t thread_count;\n  thread_act_array_t thread_list;\n  const kern_return_t status = task_threads(task, &thread_list, &thread_count);\n  if (status == KERN_SUCCESS) {\n    // task_threads allocates resources in thread_list and we need to free them\n    // to avoid leaks.\n    vm_deallocate(task, reinterpret_cast<vm_address_t>(thread_list),\n                  sizeof(thread_t) * thread_count);\n    return static_cast<size_t>(thread_count);\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_FREEBSD) || \\\n    defined(GTEST_OS_GNU_KFREEBSD) || defined(GTEST_OS_NETBSD)\n\n#ifdef GTEST_OS_NETBSD\n#undef KERN_PROC\n#define KERN_PROC KERN_PROC2\n#define kinfo_proc kinfo_proc2\n#endif\n\n#ifdef GTEST_OS_DRAGONFLY\n#define KP_NLWP(kp) (kp.kp_nthreads)\n#elif defined(GTEST_OS_FREEBSD) || defined(GTEST_OS_GNU_KFREEBSD)\n#define KP_NLWP(kp) (kp.ki_numthreads)\n#elif defined(GTEST_OS_NETBSD)\n#define KP_NLWP(kp) (kp.p_nlwps)\n#endif\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  int mib[] = {\n      CTL_KERN,\n      KERN_PROC,\n      KERN_PROC_PID,\n      getpid(),\n#ifdef GTEST_OS_NETBSD\n      sizeof(struct kinfo_proc),\n      1,\n#endif\n  };\n  u_int miblen = sizeof(mib) / sizeof(mib[0]);\n  struct kinfo_proc info;\n  size_t size = sizeof(info);\n  if (sysctl(mib, miblen, &info, &size, NULL, 0)) {\n    return 0;\n  }\n  return static_cast<size_t>(KP_NLWP(info));\n}\n#elif defined(GTEST_OS_OPENBSD)\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  int mib[] = {\n      CTL_KERN,\n      KERN_PROC,\n      KERN_PROC_PID | KERN_PROC_SHOW_THREADS,\n      getpid(),\n      sizeof(struct kinfo_proc),\n      0,\n  };\n  u_int miblen = sizeof(mib) / sizeof(mib[0]);\n\n  // get number of structs\n  size_t size;\n  if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {\n    return 0;\n  }\n\n  mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4]));\n\n  // populate array of structs\n  std::vector<struct kinfo_proc> info(mib[5]);\n  if (sysctl(mib, miblen, info.data(), &size, NULL, 0)) {\n    return 0;\n  }\n\n  // exclude empty members\n  size_t nthreads = 0;\n  for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) {\n    if (info[i].p_tid != -1) nthreads++;\n  }\n  return nthreads;\n}\n\n#elif defined(GTEST_OS_QNX)\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  const int fd = open(\"/proc/self/as\", O_RDONLY);\n  if (fd < 0) {\n    return 0;\n  }\n  procfs_info process_info;\n  const int status =\n      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);\n  close(fd);\n  if (status == EOK) {\n    return static_cast<size_t>(process_info.num_threads);\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_AIX)\n\nsize_t GetThreadCount() {\n  struct procentry64 entry;\n  pid_t pid = getpid();\n  int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);\n  if (status == 1) {\n    return entry.pi_thcount;\n  } else {\n    return 0;\n  }\n}\n\n#elif defined(GTEST_OS_FUCHSIA)\n\nsize_t GetThreadCount() {\n  int dummy_buffer;\n  size_t avail;\n  zx_status_t status =\n      zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS,\n                         &dummy_buffer, 0, nullptr, &avail);\n  if (status == ZX_OK) {\n    return avail;\n  } else {\n    return 0;\n  }\n}\n\n#else\n\nsize_t GetThreadCount() {\n  // There's no portable way to detect the number of threads, so we just\n  // return 0 to indicate that we cannot detect it.\n  return 0;\n}\n\n#endif  // GTEST_OS_LINUX\n\n#if defined(GTEST_IS_THREADSAFE) && defined(GTEST_OS_WINDOWS)\n\nAutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}\n\nAutoHandle::AutoHandle(Handle handle) : handle_(handle) {}\n\nAutoHandle::~AutoHandle() { Reset(); }\n\nAutoHandle::Handle AutoHandle::Get() const { return handle_; }\n\nvoid AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); }\n\nvoid AutoHandle::Reset(HANDLE handle) {\n  // Resetting with the same handle we already own is invalid.\n  if (handle_ != handle) {\n    if (IsCloseable()) {\n      ::CloseHandle(handle_);\n    }\n    handle_ = handle;\n  } else {\n    GTEST_CHECK_(!IsCloseable())\n        << \"Resetting a valid handle to itself is likely a programmer error \"\n           \"and thus not allowed.\";\n  }\n}\n\nbool AutoHandle::IsCloseable() const {\n  // Different Windows APIs may use either of these values to represent an\n  // invalid handle.\n  return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;\n}\n\nMutex::Mutex()\n    : owner_thread_id_(0),\n      type_(kDynamic),\n      critical_section_init_phase_(0),\n      critical_section_(new CRITICAL_SECTION) {\n  ::InitializeCriticalSection(critical_section_);\n}\n\nMutex::~Mutex() {\n  // Static mutexes are leaked intentionally. It is not thread-safe to try\n  // to clean them up.\n  if (type_ == kDynamic) {\n    ::DeleteCriticalSection(critical_section_);\n    delete critical_section_;\n    critical_section_ = nullptr;\n  }\n}\n\nvoid Mutex::Lock() {\n  ThreadSafeLazyInit();\n  ::EnterCriticalSection(critical_section_);\n  owner_thread_id_ = ::GetCurrentThreadId();\n}\n\nvoid Mutex::Unlock() {\n  ThreadSafeLazyInit();\n  // We don't protect writing to owner_thread_id_ here, as it's the\n  // caller's responsibility to ensure that the current thread holds the\n  // mutex when this is called.\n  owner_thread_id_ = 0;\n  ::LeaveCriticalSection(critical_section_);\n}\n\n// Does nothing if the current thread holds the mutex. Otherwise, crashes\n// with high probability.\nvoid Mutex::AssertHeld() {\n  ThreadSafeLazyInit();\n  GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())\n      << \"The current thread is not holding the mutex @\" << this;\n}\n\nnamespace {\n\n#ifdef _MSC_VER\n// Use the RAII idiom to flag mem allocs that are intentionally never\n// deallocated. The motivation is to silence the false positive mem leaks\n// that are reported by the debug version of MS's CRT which can only detect\n// if an alloc is missing a matching deallocation.\n// Example:\n//    MemoryIsNotDeallocated memory_is_not_deallocated;\n//    critical_section_ = new CRITICAL_SECTION;\n//\nclass MemoryIsNotDeallocated {\n public:\n  MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {\n    old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);\n    // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT\n    // doesn't report mem leak if there's no matching deallocation.\n    (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);\n  }\n\n  ~MemoryIsNotDeallocated() {\n    // Restore the original _CRTDBG_ALLOC_MEM_DF flag\n    (void)_CrtSetDbgFlag(old_crtdbg_flag_);\n  }\n\n private:\n  int old_crtdbg_flag_;\n\n  MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete;\n  MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete;\n};\n#endif  // _MSC_VER\n\n}  // namespace\n\n// Initializes owner_thread_id_ and critical_section_ in static mutexes.\nvoid Mutex::ThreadSafeLazyInit() {\n  // Dynamic mutexes are initialized in the constructor.\n  if (type_ == kStatic) {\n    switch (\n        ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {\n      case 0:\n        // If critical_section_init_phase_ was 0 before the exchange, we\n        // are the first to test it and need to perform the initialization.\n        owner_thread_id_ = 0;\n        {\n          // Use RAII to flag that following mem alloc is never deallocated.\n#ifdef _MSC_VER\n          MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n          critical_section_ = new CRITICAL_SECTION;\n        }\n        ::InitializeCriticalSection(critical_section_);\n        // Updates the critical_section_init_phase_ to 2 to signal\n        // initialization complete.\n        GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_,\n                                                  2L, 1L) == 1L);\n        break;\n      case 1:\n        // Somebody else is already initializing the mutex; spin until they\n        // are done.\n        while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L,\n                                            2L) != 2L) {\n          // Possibly yields the rest of the thread's time slice to other\n          // threads.\n          ::Sleep(0);\n        }\n        break;\n\n      case 2:\n        break;  // The mutex is already initialized and ready for use.\n\n      default:\n        GTEST_CHECK_(false)\n            << \"Unexpected value of critical_section_init_phase_ \"\n            << \"while initializing a static mutex.\";\n    }\n  }\n}\n\nnamespace {\n\nclass ThreadWithParamSupport : public ThreadWithParamBase {\n public:\n  static HANDLE CreateThread(Runnable* runnable,\n                             Notification* thread_can_start) {\n    ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);\n    DWORD thread_id;\n    HANDLE thread_handle = ::CreateThread(\n        nullptr,  // Default security.\n        0,        // Default stack size.\n        &ThreadWithParamSupport::ThreadMain,\n        param,        // Parameter to ThreadMainStatic\n        0x0,          // Default creation flags.\n        &thread_id);  // Need a valid pointer for the call to work under Win98.\n    GTEST_CHECK_(thread_handle != nullptr)\n        << \"CreateThread failed with error \" << ::GetLastError() << \".\";\n    if (thread_handle == nullptr) {\n      delete param;\n    }\n    return thread_handle;\n  }\n\n private:\n  struct ThreadMainParam {\n    ThreadMainParam(Runnable* runnable, Notification* thread_can_start)\n        : runnable_(runnable), thread_can_start_(thread_can_start) {}\n    std::unique_ptr<Runnable> runnable_;\n    // Does not own.\n    Notification* thread_can_start_;\n  };\n\n  static DWORD WINAPI ThreadMain(void* ptr) {\n    // Transfers ownership.\n    std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));\n    if (param->thread_can_start_ != nullptr)\n      param->thread_can_start_->WaitForNotification();\n    param->runnable_->Run();\n    return 0;\n  }\n\n  // Prohibit instantiation.\n  ThreadWithParamSupport();\n\n  ThreadWithParamSupport(const ThreadWithParamSupport&) = delete;\n  ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete;\n};\n\n}  // namespace\n\nThreadWithParamBase::ThreadWithParamBase(Runnable* runnable,\n                                         Notification* thread_can_start)\n    : thread_(\n          ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {}\n\nThreadWithParamBase::~ThreadWithParamBase() { Join(); }\n\nvoid ThreadWithParamBase::Join() {\n  GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)\n      << \"Failed to join the thread with error \" << ::GetLastError() << \".\";\n}\n\n// Maps a thread to a set of ThreadIdToThreadLocals that have values\n// instantiated on that thread and notifies them when the thread exits.  A\n// ThreadLocal instance is expected to persist until all threads it has\n// values on have terminated.\nclass ThreadLocalRegistryImpl {\n public:\n  // Registers thread_local_instance as having value on the current thread.\n  // Returns a value that can be used to identify the thread from other threads.\n  static ThreadLocalValueHolderBase* GetValueOnCurrentThread(\n      const ThreadLocalBase* thread_local_instance) {\n#ifdef _MSC_VER\n    MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n    DWORD current_thread = ::GetCurrentThreadId();\n    MutexLock lock(&mutex_);\n    ThreadIdToThreadLocals* const thread_to_thread_locals =\n        GetThreadLocalsMapLocked();\n    ThreadIdToThreadLocals::iterator thread_local_pos =\n        thread_to_thread_locals->find(current_thread);\n    if (thread_local_pos == thread_to_thread_locals->end()) {\n      thread_local_pos =\n          thread_to_thread_locals\n              ->insert(std::make_pair(current_thread, ThreadLocalValues()))\n              .first;\n      StartWatcherThreadFor(current_thread);\n    }\n    ThreadLocalValues& thread_local_values = thread_local_pos->second;\n    ThreadLocalValues::iterator value_pos =\n        thread_local_values.find(thread_local_instance);\n    if (value_pos == thread_local_values.end()) {\n      value_pos =\n          thread_local_values\n              .insert(std::make_pair(\n                  thread_local_instance,\n                  std::shared_ptr<ThreadLocalValueHolderBase>(\n                      thread_local_instance->NewValueForCurrentThread())))\n              .first;\n    }\n    return value_pos->second.get();\n  }\n\n  static void OnThreadLocalDestroyed(\n      const ThreadLocalBase* thread_local_instance) {\n    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;\n    // Clean up the ThreadLocalValues data structure while holding the lock, but\n    // defer the destruction of the ThreadLocalValueHolderBases.\n    {\n      MutexLock lock(&mutex_);\n      ThreadIdToThreadLocals* const thread_to_thread_locals =\n          GetThreadLocalsMapLocked();\n      for (ThreadIdToThreadLocals::iterator it =\n               thread_to_thread_locals->begin();\n           it != thread_to_thread_locals->end(); ++it) {\n        ThreadLocalValues& thread_local_values = it->second;\n        ThreadLocalValues::iterator value_pos =\n            thread_local_values.find(thread_local_instance);\n        if (value_pos != thread_local_values.end()) {\n          value_holders.push_back(value_pos->second);\n          thread_local_values.erase(value_pos);\n          // This 'if' can only be successful at most once, so theoretically we\n          // could break out of the loop here, but we don't bother doing so.\n        }\n      }\n    }\n    // Outside the lock, let the destructor for 'value_holders' deallocate the\n    // ThreadLocalValueHolderBases.\n  }\n\n  static void OnThreadExit(DWORD thread_id) {\n    GTEST_CHECK_(thread_id != 0) << ::GetLastError();\n    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;\n    // Clean up the ThreadIdToThreadLocals data structure while holding the\n    // lock, but defer the destruction of the ThreadLocalValueHolderBases.\n    {\n      MutexLock lock(&mutex_);\n      ThreadIdToThreadLocals* const thread_to_thread_locals =\n          GetThreadLocalsMapLocked();\n      ThreadIdToThreadLocals::iterator thread_local_pos =\n          thread_to_thread_locals->find(thread_id);\n      if (thread_local_pos != thread_to_thread_locals->end()) {\n        ThreadLocalValues& thread_local_values = thread_local_pos->second;\n        for (ThreadLocalValues::iterator value_pos =\n                 thread_local_values.begin();\n             value_pos != thread_local_values.end(); ++value_pos) {\n          value_holders.push_back(value_pos->second);\n        }\n        thread_to_thread_locals->erase(thread_local_pos);\n      }\n    }\n    // Outside the lock, let the destructor for 'value_holders' deallocate the\n    // ThreadLocalValueHolderBases.\n  }\n\n private:\n  // In a particular thread, maps a ThreadLocal object to its value.\n  typedef std::map<const ThreadLocalBase*,\n                   std::shared_ptr<ThreadLocalValueHolderBase> >\n      ThreadLocalValues;\n  // Stores all ThreadIdToThreadLocals having values in a thread, indexed by\n  // thread's ID.\n  typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;\n\n  struct WatcherThreadParams {\n    DWORD thread_id;\n    HANDLE handle;\n    Notification has_initialized;\n  };\n\n  static void StartWatcherThreadFor(DWORD thread_id) {\n    // The returned handle will be kept in thread_map and closed by\n    // watcher_thread in WatcherThreadFunc.\n    HANDLE thread =\n        ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);\n    GTEST_CHECK_(thread != nullptr);\n\n    WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;\n    watcher_thread_params->thread_id = thread_id;\n    watcher_thread_params->handle = thread;\n\n    // We need to pass a valid thread ID pointer into CreateThread for it\n    // to work correctly under Win98.\n    DWORD watcher_thread_id;\n    HANDLE watcher_thread =\n        ::CreateThread(nullptr,  // Default security.\n                       0,        // Default stack size\n                       &ThreadLocalRegistryImpl::WatcherThreadFunc,\n                       reinterpret_cast<LPVOID>(watcher_thread_params),\n                       CREATE_SUSPENDED, &watcher_thread_id);\n    GTEST_CHECK_(watcher_thread != nullptr)\n        << \"CreateThread failed with error \" << ::GetLastError() << \".\";\n    // Give the watcher thread the same priority as ours to avoid being\n    // blocked by it.\n    ::SetThreadPriority(watcher_thread,\n                        ::GetThreadPriority(::GetCurrentThread()));\n    ::ResumeThread(watcher_thread);\n    ::CloseHandle(watcher_thread);\n\n    // Wait for the watcher thread to start to avoid race conditions.\n    // One specific race condition that can happen is that we have returned\n    // from main and have started to tear down, the newly spawned watcher\n    // thread may access already-freed variables, like global shared_ptrs.\n    watcher_thread_params->has_initialized.WaitForNotification();\n  }\n\n  // Monitors exit from a given thread and notifies those\n  // ThreadIdToThreadLocals about thread termination.\n  static DWORD WINAPI WatcherThreadFunc(LPVOID param) {\n    WatcherThreadParams* watcher_thread_params =\n        reinterpret_cast<WatcherThreadParams*>(param);\n    watcher_thread_params->has_initialized.Notify();\n    GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle,\n                                       INFINITE) == WAIT_OBJECT_0);\n    OnThreadExit(watcher_thread_params->thread_id);\n    ::CloseHandle(watcher_thread_params->handle);\n    delete watcher_thread_params;\n    return 0;\n  }\n\n  // Returns map of thread local instances.\n  static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {\n    mutex_.AssertHeld();\n#ifdef _MSC_VER\n    MemoryIsNotDeallocated memory_is_not_deallocated;\n#endif  // _MSC_VER\n    static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();\n    return map;\n  }\n\n  // Protects access to GetThreadLocalsMapLocked() and its return value.\n  static Mutex mutex_;\n  // Protects access to GetThreadMapLocked() and its return value.\n  static Mutex thread_map_mutex_;\n};\n\nMutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);  // NOLINT\nMutex ThreadLocalRegistryImpl::thread_map_mutex_(\n    Mutex::kStaticMutex);  // NOLINT\n\nThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(\n    const ThreadLocalBase* thread_local_instance) {\n  return ThreadLocalRegistryImpl::GetValueOnCurrentThread(\n      thread_local_instance);\n}\n\nvoid ThreadLocalRegistry::OnThreadLocalDestroyed(\n    const ThreadLocalBase* thread_local_instance) {\n  ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);\n}\n\n#endif  // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS\n\n#ifdef GTEST_USES_POSIX_RE\n\n// Implements RE.  Currently only needed for death tests.\n\nRE::~RE() {\n  if (is_valid_) {\n    // regfree'ing an invalid regex might crash because the content\n    // of the regex is undefined. Since the regex's are essentially\n    // the same, one cannot be valid (or invalid) without the other\n    // being so too.\n    regfree(&partial_regex_);\n    regfree(&full_regex_);\n  }\n}\n\n// Returns true if and only if regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;\n}\n\n// Returns true if and only if regular expression re matches a substring of\n// str (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  pattern_ = regex;\n\n  // NetBSD (and Android, which takes its regex implemntation from NetBSD) does\n  // not include the GNU regex extensions (such as Perl style character classes\n  // like \\w) in REG_EXTENDED. REG_EXTENDED is only specified to include the\n  // [[:alpha:]] style character classes. Enable REG_GNU wherever it is defined\n  // so users can use those extensions.\n#if defined(REG_GNU)\n  constexpr int reg_flags = REG_EXTENDED | REG_GNU;\n#else\n  constexpr int reg_flags = REG_EXTENDED;\n#endif\n\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match.\n  const size_t full_regex_len = strlen(regex) + 10;\n  char* const full_pattern = new char[full_regex_len];\n\n  snprintf(full_pattern, full_regex_len, \"^(%s)$\", regex);\n  is_valid_ = regcomp(&full_regex_, full_pattern, reg_flags) == 0;\n  // We want to call regcomp(&partial_regex_, ...) even if the\n  // previous expression returns false.  Otherwise partial_regex_ may\n  // not be properly initialized can may cause trouble when it's\n  // freed.\n  //\n  // Some implementation of POSIX regex (e.g. on at least some\n  // versions of Cygwin) doesn't accept the empty string as a valid\n  // regex.  We change it to an equivalent form \"()\" to be safe.\n  if (is_valid_) {\n    const char* const partial_regex = (*regex == '\\0') ? \"()\" : regex;\n    is_valid_ = regcomp(&partial_regex_, partial_regex, reg_flags) == 0;\n  }\n  EXPECT_TRUE(is_valid_)\n      << \"Regular expression \\\"\" << regex\n      << \"\\\" is not a valid POSIX Extended regular expression.\";\n\n  delete[] full_pattern;\n}\n\n#elif defined(GTEST_USES_SIMPLE_RE)\n\n// Returns true if and only if ch appears anywhere in str (excluding the\n// terminating '\\0' character).\nbool IsInSet(char ch, const char* str) {\n  return ch != '\\0' && strchr(str, ch) != nullptr;\n}\n\n// Returns true if and only if ch belongs to the given classification.\n// Unlike similar functions in <ctype.h>, these aren't affected by the\n// current locale.\nbool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }\nbool IsAsciiPunct(char ch) {\n  return IsInSet(ch, \"^-!\\\"#$%&'()*+,./:;<=>?@[\\\\]_`{|}~\");\n}\nbool IsRepeat(char ch) { return IsInSet(ch, \"?*+\"); }\nbool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, \" \\f\\n\\r\\t\\v\"); }\nbool IsAsciiWordChar(char ch) {\n  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||\n         ('0' <= ch && ch <= '9') || ch == '_';\n}\n\n// Returns true if and only if \"\\\\c\" is a supported escape sequence.\nbool IsValidEscape(char c) {\n  return (IsAsciiPunct(c) || IsInSet(c, \"dDfnrsStvwW\"));\n}\n\n// Returns true if and only if the given atom (specified by escaped and\n// pattern) matches ch.  The result is undefined if the atom is invalid.\nbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {\n  if (escaped) {  // \"\\\\p\" where p is pattern_char.\n    switch (pattern_char) {\n      case 'd':\n        return IsAsciiDigit(ch);\n      case 'D':\n        return !IsAsciiDigit(ch);\n      case 'f':\n        return ch == '\\f';\n      case 'n':\n        return ch == '\\n';\n      case 'r':\n        return ch == '\\r';\n      case 's':\n        return IsAsciiWhiteSpace(ch);\n      case 'S':\n        return !IsAsciiWhiteSpace(ch);\n      case 't':\n        return ch == '\\t';\n      case 'v':\n        return ch == '\\v';\n      case 'w':\n        return IsAsciiWordChar(ch);\n      case 'W':\n        return !IsAsciiWordChar(ch);\n    }\n    return IsAsciiPunct(pattern_char) && pattern_char == ch;\n  }\n\n  return (pattern_char == '.' && ch != '\\n') || pattern_char == ch;\n}\n\n// Helper function used by ValidateRegex() to format error messages.\nstatic std::string FormatRegexSyntaxError(const char* regex, int index) {\n  return (Message() << \"Syntax error at index \" << index\n                    << \" in simple regular expression \\\"\" << regex << \"\\\": \")\n      .GetString();\n}\n\n// Generates non-fatal failures and returns false if regex is invalid;\n// otherwise returns true.\nbool ValidateRegex(const char* regex) {\n  if (regex == nullptr) {\n    ADD_FAILURE() << \"NULL is not a valid simple regular expression.\";\n    return false;\n  }\n\n  bool is_valid = true;\n\n  // True if and only if ?, *, or + can follow the previous atom.\n  bool prev_repeatable = false;\n  for (int i = 0; regex[i]; i++) {\n    if (regex[i] == '\\\\') {  // An escape sequence\n      i++;\n      if (regex[i] == '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"'\\\\' cannot appear at the end.\";\n        return false;\n      }\n\n      if (!IsValidEscape(regex[i])) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"invalid escape sequence \\\"\\\\\" << regex[i] << \"\\\".\";\n        is_valid = false;\n      }\n      prev_repeatable = true;\n    } else {  // Not an escape sequence.\n      const char ch = regex[i];\n\n      if (ch == '^' && i > 0) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'^' can only appear at the beginning.\";\n        is_valid = false;\n      } else if (ch == '$' && regex[i + 1] != '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'$' can only appear at the end.\";\n        is_valid = false;\n      } else if (IsInSet(ch, \"()[]{}|\")) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << \"'\" << ch\n                      << \"' is unsupported.\";\n        is_valid = false;\n      } else if (IsRepeat(ch) && !prev_repeatable) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << \"'\" << ch\n                      << \"' can only follow a repeatable token.\";\n        is_valid = false;\n      }\n\n      prev_repeatable = !IsInSet(ch, \"^$?*+\");\n    }\n  }\n\n  return is_valid;\n}\n\n// Matches a repeated regex atom followed by a valid simple regular\n// expression.  The regex atom is defined as c if escaped is false,\n// or \\c otherwise.  repeat is the repetition meta character (?, *,\n// or +).  The behavior is undefined if str contains too many\n// characters to be indexable by size_t, in which case the test will\n// probably time out anyway.  We are fine with this limitation as\n// std::string has it too.\nbool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,\n                                   const char* regex, const char* str) {\n  const size_t min_count = (repeat == '+') ? 1 : 0;\n  const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;\n  // We cannot call numeric_limits::max() as it conflicts with the\n  // max() macro on Windows.\n\n  for (size_t i = 0; i <= max_count; ++i) {\n    // We know that the atom matches each of the first i characters in str.\n    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {\n      // We have enough matches at the head, and the tail matches too.\n      // Since we only care about *whether* the pattern matches str\n      // (as opposed to *how* it matches), there is no need to find a\n      // greedy match.\n      return true;\n    }\n    if (str[i] == '\\0' || !AtomMatchesChar(escaped, c, str[i])) return false;\n  }\n  return false;\n}\n\n// Returns true if and only if regex matches a prefix of str. regex must\n// be a valid simple regular expression and not start with \"^\", or the\n// result is undefined.\nbool MatchRegexAtHead(const char* regex, const char* str) {\n  if (*regex == '\\0')  // An empty regex matches a prefix of anything.\n    return true;\n\n  // \"$\" only matches the end of a string.  Note that regex being\n  // valid guarantees that there's nothing after \"$\" in it.\n  if (*regex == '$') return *str == '\\0';\n\n  // Is the first thing in regex an escape sequence?\n  const bool escaped = *regex == '\\\\';\n  if (escaped) ++regex;\n  if (IsRepeat(regex[1])) {\n    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so\n    // here's an indirect recursion.  It terminates as the regex gets\n    // shorter in each recursion.\n    return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,\n                                         str);\n  } else {\n    // regex isn't empty, isn't \"$\", and doesn't start with a\n    // repetition.  We match the first atom of regex with the first\n    // character of str and recurse.\n    return (*str != '\\0') && AtomMatchesChar(escaped, *regex, *str) &&\n           MatchRegexAtHead(regex + 1, str + 1);\n  }\n}\n\n// Returns true if and only if regex matches any substring of str.  regex must\n// be a valid simple regular expression, or the result is undefined.\n//\n// The algorithm is recursive, but the recursion depth doesn't exceed\n// the regex length, so we won't need to worry about running out of\n// stack space normally.  In rare cases the time complexity can be\n// exponential with respect to the regex length + the string length,\n// but usually it's must faster (often close to linear).\nbool MatchRegexAnywhere(const char* regex, const char* str) {\n  if (regex == nullptr || str == nullptr) return false;\n\n  if (*regex == '^') return MatchRegexAtHead(regex + 1, str);\n\n  // A successful match can be anywhere in str.\n  do {\n    if (MatchRegexAtHead(regex, str)) return true;\n  } while (*str++ != '\\0');\n  return false;\n}\n\n// Implements the RE class.\n\nRE::~RE() = default;\n\n// Returns true if and only if regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str);\n}\n\n// Returns true if and only if regular expression re matches a substring of\n// str (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str);\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  full_pattern_.clear();\n  pattern_.clear();\n\n  if (regex != nullptr) {\n    pattern_ = regex;\n  }\n\n  is_valid_ = ValidateRegex(regex);\n  if (!is_valid_) {\n    // No need to calculate the full pattern when the regex is invalid.\n    return;\n  }\n\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match: we need space to prepend a '^' and append a '$'.\n  full_pattern_.reserve(pattern_.size() + 2);\n\n  if (pattern_.empty() || pattern_.front() != '^') {\n    full_pattern_.push_back('^');  // Makes sure full_pattern_ starts with '^'.\n  }\n\n  full_pattern_.append(pattern_);\n\n  if (pattern_.empty() || pattern_.back() != '$') {\n    full_pattern_.push_back('$');  // Makes sure full_pattern_ ends with '$'.\n  }\n}\n\n#endif  // GTEST_USES_POSIX_RE\n\nconst char kUnknownFile[] = \"unknown file\";\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {\n  const std::string file_name(file == nullptr ? kUnknownFile : file);\n\n  if (line < 0) {\n    return file_name + \":\";\n  }\n#ifdef _MSC_VER\n  return file_name + \"(\" + StreamableToString(line) + \"):\";\n#else\n  return file_name + \":\" + StreamableToString(line) + \":\";\n#endif  // _MSC_VER\n}\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\n// Note that FormatCompilerIndependentFileLocation() does NOT append colon\n// to the file location it produces, unlike FormatFileLocation().\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\n                                                               int line) {\n  const std::string file_name(file == nullptr ? kUnknownFile : file);\n\n  if (line < 0)\n    return file_name;\n  else\n    return file_name + \":\" + StreamableToString(line);\n}\n\nGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)\n    : severity_(severity) {\n  const char* const marker = severity == GTEST_INFO      ? \"[  INFO ]\"\n                             : severity == GTEST_WARNING ? \"[WARNING]\"\n                             : severity == GTEST_ERROR   ? \"[ ERROR ]\"\n                                                         : \"[ FATAL ]\";\n  GetStream() << ::std::endl\n              << marker << \" \" << FormatFileLocation(file, line).c_str()\n              << \": \";\n}\n\n// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\nGTestLog::~GTestLog() {\n  GetStream() << ::std::endl;\n  if (severity_ == GTEST_FATAL) {\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Disable Microsoft deprecation warnings for POSIX functions called from\n// this class (creat, dup, dup2, and close)\nGTEST_DISABLE_MSC_DEPRECATED_PUSH_()\n\nnamespace {\n\n#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)\nbool EndsWithPathSeparator(const std::string& path) {\n  return !path.empty() && path.back() == GTEST_PATH_SEP_[0];\n}\n#endif\n\n}  // namespace\n\n// Object that captures an output stream (stdout/stderr).\nclass CapturedStream {\n public:\n  // The ctor redirects the stream to a temporary file.\n  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {\n#ifdef GTEST_OS_WINDOWS\n    char temp_dir_path[MAX_PATH + 1] = {'\\0'};   // NOLINT\n    char temp_file_path[MAX_PATH + 1] = {'\\0'};  // NOLINT\n\n    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);\n    const UINT success = ::GetTempFileNameA(temp_dir_path, \"gtest_redir\",\n                                            0,  // Generate unique file name.\n                                            temp_file_path);\n    GTEST_CHECK_(success != 0)\n        << \"Unable to create a temporary file in \" << temp_dir_path;\n    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);\n    GTEST_CHECK_(captured_fd != -1)\n        << \"Unable to open temporary file \" << temp_file_path;\n    filename_ = temp_file_path;\n#else\n    // There's no guarantee that a test has write access to the current\n    // directory, so we create the temporary file in a temporary directory.\n    std::string name_template;\n\n#ifdef GTEST_OS_LINUX_ANDROID\n    // Note: Android applications are expected to call the framework's\n    // Context.getExternalStorageDirectory() method through JNI to get\n    // the location of the world-writable SD Card directory. However,\n    // this requires a Context handle, which cannot be retrieved\n    // globally from native code. Doing so also precludes running the\n    // code as part of a regular standalone executable, which doesn't\n    // run in a Dalvik process (e.g. when running it through 'adb shell').\n    //\n    // The location /data/local/tmp is directly accessible from native code.\n    // '/sdcard' and other variants cannot be relied on, as they are not\n    // guaranteed to be mounted, or may have a delay in mounting.\n    //\n    // However, prefer using the TMPDIR environment variable if set, as newer\n    // devices may have /data/local/tmp read-only.\n    name_template = TempDir();\n    if (!EndsWithPathSeparator(name_template))\n      name_template.push_back(GTEST_PATH_SEP_[0]);\n\n#elif defined(GTEST_OS_IOS)\n    char user_temp_dir[PATH_MAX + 1];\n\n    // Documented alternative to NSTemporaryDirectory() (for obtaining creating\n    // a temporary directory) at\n    // https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10\n    //\n    // _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not\n    // documented in the confstr() man page at\n    // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr\n    // but are still available, according to the WebKit patches at\n    // https://trac.webkit.org/changeset/262004/webkit\n    // https://trac.webkit.org/changeset/263705/webkit\n    //\n    // The confstr() implementation falls back to getenv(\"TMPDIR\"). See\n    // https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html\n    ::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));\n\n    name_template = user_temp_dir;\n    if (!EndsWithPathSeparator(name_template))\n      name_template.push_back(GTEST_PATH_SEP_[0]);\n#else\n    name_template = \"/tmp/\";\n#endif\n    name_template.append(\"gtest_captured_stream.XXXXXX\");\n\n    // mkstemp() modifies the string bytes in place, and does not go beyond the\n    // string's length. This results in well-defined behavior in C++17.\n    //\n    // The const_cast is needed below C++17. The constraints on std::string\n    // implementations in C++11 and above make assumption behind the const_cast\n    // fairly safe.\n    const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));\n    if (captured_fd == -1) {\n      GTEST_LOG_(WARNING)\n          << \"Failed to create tmp file \" << name_template\n          << \" for test; does the test have access to the /tmp directory?\";\n    }\n    filename_ = std::move(name_template);\n#endif  // GTEST_OS_WINDOWS\n    fflush(nullptr);\n    dup2(captured_fd, fd_);\n    close(captured_fd);\n  }\n\n  ~CapturedStream() { remove(filename_.c_str()); }\n\n  std::string GetCapturedString() {\n    if (uncaptured_fd_ != -1) {\n      // Restores the original stream.\n      fflush(nullptr);\n      dup2(uncaptured_fd_, fd_);\n      close(uncaptured_fd_);\n      uncaptured_fd_ = -1;\n    }\n\n    FILE* const file = posix::FOpen(filename_.c_str(), \"r\");\n    if (file == nullptr) {\n      GTEST_LOG_(FATAL) << \"Failed to open tmp file \" << filename_\n                        << \" for capturing stream.\";\n    }\n    const std::string content = ReadEntireFile(file);\n    posix::FClose(file);\n    return content;\n  }\n\n private:\n  const int fd_;  // A stream to capture.\n  int uncaptured_fd_;\n  // Name of the temporary file holding the stderr output.\n  ::std::string filename_;\n\n  CapturedStream(const CapturedStream&) = delete;\n  CapturedStream& operator=(const CapturedStream&) = delete;\n};\n\nGTEST_DISABLE_MSC_DEPRECATED_POP_()\n\nstatic CapturedStream* g_captured_stderr = nullptr;\nstatic CapturedStream* g_captured_stdout = nullptr;\n\n// Starts capturing an output stream (stdout/stderr).\nstatic void CaptureStream(int fd, const char* stream_name,\n                          CapturedStream** stream) {\n  if (*stream != nullptr) {\n    GTEST_LOG_(FATAL) << \"Only one \" << stream_name\n                      << \" capturer can exist at a time.\";\n  }\n  *stream = new CapturedStream(fd);\n}\n\n// Stops capturing the output stream and returns the captured string.\nstatic std::string GetCapturedStream(CapturedStream** captured_stream) {\n  const std::string content = (*captured_stream)->GetCapturedString();\n\n  delete *captured_stream;\n  *captured_stream = nullptr;\n\n  return content;\n}\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\n// MSVC and C++Builder do not provide a definition of STDERR_FILENO.\nconst int kStdOutFileno = 1;\nconst int kStdErrFileno = 2;\n#else\nconst int kStdOutFileno = STDOUT_FILENO;\nconst int kStdErrFileno = STDERR_FILENO;\n#endif  // defined(_MSC_VER) || defined(__BORLANDC__)\n\n// Starts capturing stdout.\nvoid CaptureStdout() {\n  CaptureStream(kStdOutFileno, \"stdout\", &g_captured_stdout);\n}\n\n// Starts capturing stderr.\nvoid CaptureStderr() {\n  CaptureStream(kStdErrFileno, \"stderr\", &g_captured_stderr);\n}\n\n// Stops capturing stdout and returns the captured string.\nstd::string GetCapturedStdout() {\n  return GetCapturedStream(&g_captured_stdout);\n}\n\n// Stops capturing stderr and returns the captured string.\nstd::string GetCapturedStderr() {\n  return GetCapturedStream(&g_captured_stderr);\n}\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\nsize_t GetFileSize(FILE* file) {\n  fseek(file, 0, SEEK_END);\n  return static_cast<size_t>(ftell(file));\n}\n\nstd::string ReadEntireFile(FILE* file) {\n  const size_t file_size = GetFileSize(file);\n  char* const buffer = new char[file_size];\n\n  size_t bytes_last_read = 0;  // # of bytes read in the last fread()\n  size_t bytes_read = 0;       // # of bytes read so far\n\n  fseek(file, 0, SEEK_SET);\n\n  // Keeps reading the file until we cannot read further or the\n  // pre-determined file size is reached.\n  do {\n    bytes_last_read =\n        fread(buffer + bytes_read, 1, file_size - bytes_read, file);\n    bytes_read += bytes_last_read;\n  } while (bytes_last_read > 0 && bytes_read < file_size);\n\n  const std::string content(buffer, bytes_read);\n  delete[] buffer;\n\n  return content;\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\nstatic const std::vector<std::string>* g_injected_test_argvs =\n    nullptr;  // Owned.\n\nstd::vector<std::string> GetInjectableArgvs() {\n  if (g_injected_test_argvs != nullptr) {\n    return *g_injected_test_argvs;\n  }\n  return GetArgvs();\n}\n\nvoid SetInjectableArgvs(const std::vector<std::string>* new_argvs) {\n  if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;\n  g_injected_test_argvs = new_argvs;\n}\n\nvoid SetInjectableArgvs(const std::vector<std::string>& new_argvs) {\n  SetInjectableArgvs(\n      new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));\n}\n\nvoid ClearInjectableArgvs() {\n  delete g_injected_test_argvs;\n  g_injected_test_argvs = nullptr;\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\nnamespace posix {\nvoid Abort() {\n  DebugBreak();\n  TerminateProcess(GetCurrentProcess(), 1);\n}\n}  // namespace posix\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Returns the name of the environment variable corresponding to the\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\n// \"GTEST_FOO\" in the open-source version.\nstatic std::string FlagToEnvVar(const char* flag) {\n  const std::string full_flag =\n      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();\n\n  Message env_var;\n  for (size_t i = 0; i != full_flag.length(); i++) {\n    env_var << ToUpper(full_flag.c_str()[i]);\n  }\n\n  return env_var.GetString();\n}\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\n// the result to *value and returns true; otherwise leaves *value\n// unchanged and returns false.\nbool ParseInt32(const Message& src_text, const char* str, int32_t* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = nullptr;\n  const long long_value = strtol(str, &end, 10);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\"\n        << \" has value \\\"\" << str << \"\\\".\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  // Is the parsed value in the range of an int32_t?\n  const auto result = static_cast<int32_t>(long_value);\n  if (long_value == LONG_MAX || long_value == LONG_MIN ||\n      // The parsed value overflows as a long.  (strtol() returns\n      // LONG_MAX or LONG_MIN when the input overflows.)\n      result != long_value\n      // The parsed value overflows as an int32_t.\n  ) {\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\" << \" has value \"\n        << str << \", which overflows.\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  *value = result;\n  return true;\n}\n\n// Reads and returns the Boolean environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\n//\n// The value is considered true if and only if it's not \"0\".\nbool BoolFromGTestEnv(const char* flag, bool default_value) {\n#if defined(GTEST_GET_BOOL_FROM_ENV_)\n  return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  return string_value == nullptr ? default_value\n                                 : strcmp(string_value, \"0\") != 0;\n#endif  // defined(GTEST_GET_BOOL_FROM_ENV_)\n}\n\n// Reads and returns a 32-bit integer stored in the environment\n// variable corresponding to the given flag; if it isn't set or\n// doesn't represent a valid 32-bit integer, returns default_value.\nint32_t Int32FromGTestEnv(const char* flag, int32_t default_value) {\n#if defined(GTEST_GET_INT32_FROM_ENV_)\n  return GTEST_GET_INT32_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  if (string_value == nullptr) {\n    // The environment variable is not set.\n    return default_value;\n  }\n\n  int32_t result = default_value;\n  if (!ParseInt32(Message() << \"Environment variable \" << env_var, string_value,\n                  &result)) {\n    printf(\"The default value %s is used.\\n\",\n           (Message() << default_value).GetString().c_str());\n    fflush(stdout);\n    return default_value;\n  }\n\n  return result;\n#endif  // defined(GTEST_GET_INT32_FROM_ENV_)\n}\n\n// As a special case for the 'output' flag, if GTEST_OUTPUT is not\n// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build\n// system.  The value of XML_OUTPUT_FILE is a filename without the\n// \"xml:\" prefix of GTEST_OUTPUT.\n// Note that this is meant to be called at the call site so it does\n// not check that the flag is 'output'\n// In essence this checks an env variable called XML_OUTPUT_FILE\n// and if it is set we prepend \"xml:\" to its value, if it not set we return \"\"\nstd::string OutputFlagAlsoCheckEnvVar() {\n  std::string default_value_for_output_flag = \"\";\n  const char* xml_output_file_env = posix::GetEnv(\"XML_OUTPUT_FILE\");\n  if (nullptr != xml_output_file_env) {\n    default_value_for_output_flag = std::string(\"xml:\") + xml_output_file_env;\n  }\n  return default_value_for_output_flag;\n}\n\n// Reads and returns the string environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\nconst char* StringFromGTestEnv(const char* flag, const char* default_value) {\n#if defined(GTEST_GET_STRING_FROM_ENV_)\n  return GTEST_GET_STRING_FROM_ENV_(flag, default_value);\n#else\n  const std::string env_var = FlagToEnvVar(flag);\n  const char* const value = posix::GetEnv(env_var.c_str());\n  return value == nullptr ? default_value : value;\n#endif  // defined(GTEST_GET_STRING_FROM_ENV_)\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-printers.cc",
    "content": "// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Google Test - The Google C++ Testing and Mocking Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// It uses the << operator when possible, and prints the bytes in the\n// object otherwise.  A user can override its behavior for a class\n// type Foo by defining either operator<<(::std::ostream&, const Foo&)\n// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that\n// defines Foo.\n\n#include \"gtest/gtest-printers.h\"\n\n#include <stdio.h>\n\n#include <cctype>\n#include <cstdint>\n#include <cwchar>\n#include <iomanip>\n#include <ios>\n#include <ostream>  // NOLINT\n#include <string>\n#include <type_traits>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\nnamespace {\n\nusing ::std::ostream;\n\n// Prints a segment of bytes in the given object.\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_\nGTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\nGTEST_ATTRIBUTE_NO_SANITIZE_THREAD_\nvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,\n                                size_t count, ostream* os) {\n  char text[5] = \"\";\n  for (size_t i = 0; i != count; i++) {\n    const size_t j = start + i;\n    if (i != 0) {\n      // Organizes the bytes into groups of 2 for easy parsing by\n      // human.\n      if ((j % 2) == 0)\n        *os << ' ';\n      else\n        *os << '-';\n    }\n    GTEST_SNPRINTF_(text, sizeof(text), \"%02X\", obj_bytes[j]);\n    *os << text;\n  }\n}\n\n// Prints the bytes in the given value to the given ostream.\nvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,\n                              ostream* os) {\n  // Tells the user how big the object is.\n  *os << count << \"-byte object <\";\n\n  const size_t kThreshold = 132;\n  const size_t kChunkSize = 64;\n  // If the object size is bigger than kThreshold, we'll have to omit\n  // some details by printing only the first and the last kChunkSize\n  // bytes.\n  if (count < kThreshold) {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);\n  } else {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);\n    *os << \" ... \";\n    // Rounds up to 2-byte boundary.\n    const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;\n    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);\n  }\n  *os << \">\";\n}\n\n// Helpers for widening a character to char32_t. Since the standard does not\n// specify if char / wchar_t is signed or unsigned, it is important to first\n// convert it to the unsigned type of the same width before widening it to\n// char32_t.\ntemplate <typename CharType>\nchar32_t ToChar32(CharType in) {\n  return static_cast<char32_t>(\n      static_cast<typename std::make_unsigned<CharType>::type>(in));\n}\n\n}  // namespace\n\nnamespace internal {\n\n// Delegates to PrintBytesInObjectToImpl() to print the bytes in the\n// given object.  The delegation simplifies the implementation, which\n// uses the << operator and thus is easier done outside of the\n// ::testing::internal namespace, which contains a << operator that\n// sometimes conflicts with the one in STL.\nvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,\n                          ostream* os) {\n  PrintBytesInObjectToImpl(obj_bytes, count, os);\n}\n\n// Depending on the value of a char (or wchar_t), we print it in one\n// of three formats:\n//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),\n//   - as a hexadecimal escape sequence (e.g. '\\x7F'), or\n//   - as a special escape sequence (e.g. '\\r', '\\n').\nenum CharFormat { kAsIs, kHexEscape, kSpecialEscape };\n\n// Returns true if c is a printable ASCII character.  We test the\n// value of c directly instead of calling isprint(), which is buggy on\n// Windows Mobile.\ninline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; }\n\n// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a\n// character literal without the quotes, escaping it when necessary; returns how\n// c was formatted.\ntemplate <typename Char>\nstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {\n  const char32_t u_c = ToChar32(c);\n  switch (u_c) {\n    case L'\\0':\n      *os << \"\\\\0\";\n      break;\n    case L'\\'':\n      *os << \"\\\\'\";\n      break;\n    case L'\\\\':\n      *os << \"\\\\\\\\\";\n      break;\n    case L'\\a':\n      *os << \"\\\\a\";\n      break;\n    case L'\\b':\n      *os << \"\\\\b\";\n      break;\n    case L'\\f':\n      *os << \"\\\\f\";\n      break;\n    case L'\\n':\n      *os << \"\\\\n\";\n      break;\n    case L'\\r':\n      *os << \"\\\\r\";\n      break;\n    case L'\\t':\n      *os << \"\\\\t\";\n      break;\n    case L'\\v':\n      *os << \"\\\\v\";\n      break;\n    default:\n      if (IsPrintableAscii(u_c)) {\n        *os << static_cast<char>(c);\n        return kAsIs;\n      } else {\n        ostream::fmtflags flags = os->flags();\n        *os << \"\\\\x\" << std::hex << std::uppercase << static_cast<int>(u_c);\n        os->flags(flags);\n        return kHexEscape;\n      }\n  }\n  return kSpecialEscape;\n}\n\n// Prints a char32_t c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {\n  switch (c) {\n    case L'\\'':\n      *os << \"'\";\n      return kAsIs;\n    case L'\"':\n      *os << \"\\\\\\\"\";\n      return kSpecialEscape;\n    default:\n      return PrintAsCharLiteralTo(c, os);\n  }\n}\n\nstatic const char* GetCharWidthPrefix(char) { return \"\"; }\n\nstatic const char* GetCharWidthPrefix(signed char) { return \"\"; }\n\nstatic const char* GetCharWidthPrefix(unsigned char) { return \"\"; }\n\n#ifdef __cpp_lib_char8_t\nstatic const char* GetCharWidthPrefix(char8_t) { return \"u8\"; }\n#endif\n\nstatic const char* GetCharWidthPrefix(char16_t) { return \"u\"; }\n\nstatic const char* GetCharWidthPrefix(char32_t) { return \"U\"; }\n\nstatic const char* GetCharWidthPrefix(wchar_t) { return \"L\"; }\n\n// Prints a char c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsStringLiteralTo(char c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\n#ifdef __cpp_lib_char8_t\nstatic CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n#endif\n\nstatic CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\nstatic CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {\n  return PrintAsStringLiteralTo(ToChar32(c), os);\n}\n\n// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t)\n// and its code. '\\0' is printed as \"'\\\\0'\", other unprintable characters are\n// also properly escaped using the standard C++ escape sequence.\ntemplate <typename Char>\nvoid PrintCharAndCodeTo(Char c, ostream* os) {\n  // First, print c as a literal in the most readable form we can find.\n  *os << GetCharWidthPrefix(c) << \"'\";\n  const CharFormat format = PrintAsCharLiteralTo(c, os);\n  *os << \"'\";\n\n  // To aid user debugging, we also print c's code in decimal, unless\n  // it's 0 (in which case c was printed as '\\\\0', making the code\n  // obvious).\n  if (c == 0) return;\n  *os << \" (\" << static_cast<int>(c);\n\n  // For more convenience, we print c's code again in hexadecimal,\n  // unless c was already printed in the form '\\x##' or the code is in\n  // [1, 9].\n  if (format == kHexEscape || (1 <= c && c <= 9)) {\n    // Do nothing.\n  } else {\n    *os << \", 0x\" << String::FormatHexInt(static_cast<int>(c));\n  }\n  *os << \")\";\n}\n\nvoid PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }\nvoid PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }\n\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its code.  L'\\0' is printed as \"L'\\\\0'\".\nvoid PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); }\n\n// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well.\nvoid PrintTo(char32_t c, ::std::ostream* os) {\n  *os << std::hex << \"U+\" << std::uppercase << std::setfill('0') << std::setw(4)\n      << static_cast<uint32_t>(c);\n}\n\n// gcc/clang __{u,}int128_t\n#if defined(__SIZEOF_INT128__)\nvoid PrintTo(__uint128_t v, ::std::ostream* os) {\n  if (v == 0) {\n    *os << \"0\";\n    return;\n  }\n\n  // Buffer large enough for ceil(log10(2^128))==39 and the null terminator\n  char buf[40];\n  char* p = buf + sizeof(buf);\n\n  // Some configurations have a __uint128_t, but no support for built in\n  // division. Do manual long division instead.\n\n  uint64_t high = static_cast<uint64_t>(v >> 64);\n  uint64_t low = static_cast<uint64_t>(v);\n\n  *--p = 0;\n  while (high != 0 || low != 0) {\n    uint64_t high_mod = high % 10;\n    high = high / 10;\n    // This is the long division algorithm specialized for a divisor of 10 and\n    // only two elements.\n    // Notable values:\n    //   2^64 / 10 == 1844674407370955161\n    //   2^64 % 10 == 6\n    const uint64_t carry = 6 * high_mod + low % 10;\n    low = low / 10 + high_mod * 1844674407370955161 + carry / 10;\n\n    char digit = static_cast<char>(carry % 10);\n    *--p = static_cast<char>('0' + digit);\n  }\n  *os << p;\n}\nvoid PrintTo(__int128_t v, ::std::ostream* os) {\n  __uint128_t uv = static_cast<__uint128_t>(v);\n  if (v < 0) {\n    *os << \"-\";\n    uv = -uv;\n  }\n  PrintTo(uv, os);\n}\n#endif  // __SIZEOF_INT128__\n\n// Prints the given array of characters to the ostream.  CharType must be either\n// char, char8_t, char16_t, char32_t, or wchar_t.\n// The array starts at begin, the length is len, it may include '\\0' characters\n// and may not be NUL-terminated.\ntemplate <typename CharType>\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n    GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n        GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat\n        PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {\n  const char* const quote_prefix = GetCharWidthPrefix(*begin);\n  *os << quote_prefix << \"\\\"\";\n  bool is_previous_hex = false;\n  CharFormat print_format = kAsIs;\n  for (size_t index = 0; index < len; ++index) {\n    const CharType cur = begin[index];\n    if (is_previous_hex && IsXDigit(cur)) {\n      // Previous character is of '\\x..' form and this character can be\n      // interpreted as another hexadecimal digit in its number. Break string to\n      // disambiguate.\n      *os << \"\\\" \" << quote_prefix << \"\\\"\";\n    }\n    is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;\n    // Remember if any characters required hex escaping.\n    if (is_previous_hex) {\n      print_format = kHexEscape;\n    }\n  }\n  *os << \"\\\"\";\n  return print_format;\n}\n\n// Prints a (const) char/wchar_t array of 'len' elements, starting at address\n// 'begin'.  CharType must be either char or wchar_t.\ntemplate <typename CharType>\nGTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_\n    GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_\n        GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void\n        UniversalPrintCharArray(const CharType* begin, size_t len,\n                                ostream* os) {\n  // The code\n  //   const char kFoo[] = \"foo\";\n  // generates an array of 4, not 3, elements, with the last one being '\\0'.\n  //\n  // Therefore when printing a char array, we don't print the last element if\n  // it's '\\0', such that the output matches the string literal as it's\n  // written in the source code.\n  if (len > 0 && begin[len - 1] == '\\0') {\n    PrintCharsAsStringTo(begin, len - 1, os);\n    return;\n  }\n\n  // If, however, the last element in the array is not '\\0', e.g.\n  //    const char kFoo[] = { 'f', 'o', 'o' };\n  // we must print the entire array.  We also print a message to indicate\n  // that the array is not NUL-terminated.\n  PrintCharsAsStringTo(begin, len, os);\n  *os << \" (no terminating NUL)\";\n}\n\n// Prints a (const) char array of 'len' elements, starting at address 'begin'.\nvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n#ifdef __cpp_lib_char8_t\n// Prints a (const) char8_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n#endif\n\n// Prints a (const) char16_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n// Prints a (const) char32_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\n// Prints a (const) wchar_t array of 'len' elements, starting at address\n// 'begin'.\nvoid UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {\n  UniversalPrintCharArray(begin, len, os);\n}\n\nnamespace {\n\n// Prints a null-terminated C-style string to the ostream.\ntemplate <typename Char>\nvoid PrintCStringTo(const Char* s, ostream* os) {\n  if (s == nullptr) {\n    *os << \"NULL\";\n  } else {\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\n    PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os);\n  }\n}\n\n}  // anonymous namespace\n\nvoid PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); }\n\n#ifdef __cpp_lib_char8_t\nvoid PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); }\n#endif\n\nvoid PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }\n\nvoid PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); }\n\n// MSVC compiler can be configured to define whar_t as a typedef\n// of unsigned short. Defining an overload for const wchar_t* in that case\n// would cause pointers to unsigned shorts be printed as wide strings,\n// possibly accessing more memory than intended and causing invalid\n// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when\n// wchar_t is implemented as a native type.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Prints the given wide C string to the ostream.\nvoid PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }\n#endif  // wchar_t is native\n\nnamespace {\n\nbool ContainsUnprintableControlCodes(const char* str, size_t length) {\n  const unsigned char* s = reinterpret_cast<const unsigned char*>(str);\n\n  for (size_t i = 0; i < length; i++) {\n    unsigned char ch = *s++;\n    if (std::iscntrl(ch)) {\n      switch (ch) {\n        case '\\t':\n        case '\\n':\n        case '\\r':\n          break;\n        default:\n          return true;\n      }\n    }\n  }\n  return false;\n}\n\nbool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; }\n\nbool IsValidUTF8(const char* str, size_t length) {\n  const unsigned char* s = reinterpret_cast<const unsigned char*>(str);\n\n  for (size_t i = 0; i < length;) {\n    unsigned char lead = s[i++];\n\n    if (lead <= 0x7f) {\n      continue;  // single-byte character (ASCII) 0..7F\n    }\n    if (lead < 0xc2) {\n      return false;  // trail byte or non-shortest form\n    } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {\n      ++i;  // 2-byte character\n    } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&\n               IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&\n               // check for non-shortest form and surrogate\n               (lead != 0xe0 || s[i] >= 0xa0) &&\n               (lead != 0xed || s[i] < 0xa0)) {\n      i += 2;  // 3-byte character\n    } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&\n               IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&\n               IsUTF8TrailByte(s[i + 2]) &&\n               // check for non-shortest form\n               (lead != 0xf0 || s[i] >= 0x90) &&\n               (lead != 0xf4 || s[i] < 0x90)) {\n      i += 3;  // 4-byte character\n    } else {\n      return false;\n    }\n  }\n  return true;\n}\n\nvoid ConditionalPrintAsText(const char* str, size_t length, ostream* os) {\n  if (!ContainsUnprintableControlCodes(str, length) &&\n      IsValidUTF8(str, length)) {\n    *os << \"\\n    As Text: \\\"\" << str << \"\\\"\";\n  }\n}\n\n}  // anonymous namespace\n\nvoid PrintStringTo(const ::std::string& s, ostream* os) {\n  if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {\n    if (GTEST_FLAG_GET(print_utf8)) {\n      ConditionalPrintAsText(s.data(), s.size(), os);\n    }\n  }\n}\n\n#ifdef __cpp_lib_char8_t\nvoid PrintU8StringTo(const ::std::u8string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif\n\nvoid PrintU16StringTo(const ::std::u16string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n\nvoid PrintU32StringTo(const ::std::u32string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n\n#if GTEST_HAS_STD_WSTRING\nvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n}  // namespace internal\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-test-part.cc",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// The Google C++ Testing and Mocking Framework (Google Test)\n\n#include \"gtest/gtest-test-part.h\"\n\n#include <ostream>\n#include <string>\n\n#include \"gtest/internal/gtest-port.h\"\n#include \"src/gtest-internal-inl.h\"\n\nnamespace testing {\n\n// Gets the summary of the failure message by omitting the stack trace\n// in it.\nstd::string TestPartResult::ExtractSummary(const char* message) {\n  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);\n  return stack_trace == nullptr ? message : std::string(message, stack_trace);\n}\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result) {\n  return os << internal::FormatFileLocation(result.file_name(),\n                                            result.line_number())\n            << \" \"\n            << (result.type() == TestPartResult::kSuccess ? \"Success\"\n                : result.type() == TestPartResult::kSkip  ? \"Skipped\"\n                : result.type() == TestPartResult::kFatalFailure\n                    ? \"Fatal failure\"\n                    : \"Non-fatal failure\")\n            << \":\\n\"\n            << result.message() << std::endl;\n}\n\n// Appends a TestPartResult to the array.\nvoid TestPartResultArray::Append(const TestPartResult& result) {\n  array_.push_back(result);\n}\n\n// Returns the TestPartResult at the given index (0-based).\nconst TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {\n  if (index < 0 || index >= size()) {\n    printf(\"\\nInvalid index (%d) into TestPartResultArray.\\n\", index);\n    internal::posix::Abort();\n  }\n\n  return array_[static_cast<size_t>(index)];\n}\n\n// Returns the number of TestPartResult objects in the array.\nint TestPartResultArray::size() const {\n  return static_cast<int>(array_.size());\n}\n\nnamespace internal {\n\nHasNewFatalFailureHelper::HasNewFatalFailureHelper()\n    : has_new_fatal_failure_(false),\n      original_reporter_(\n          GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);\n}\n\nHasNewFatalFailureHelper::~HasNewFatalFailureHelper() {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(\n      original_reporter_);\n}\n\nvoid HasNewFatalFailureHelper::ReportTestPartResult(\n    const TestPartResult& result) {\n  if (result.fatally_failed()) has_new_fatal_failure_ = true;\n  original_reporter_->ReportTestPartResult(result);\n}\n\n}  // namespace internal\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest-typed-test.cc",
    "content": "// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"gtest/gtest-typed-test.h\"\n\n#include <set>\n#include <string>\n#include <vector>\n\n#include \"gtest/gtest.h\"\n\nnamespace testing {\nnamespace internal {\n\n// Skips to the first non-space char in str. Returns an empty string if str\n// contains only whitespace characters.\nstatic const char* SkipSpaces(const char* str) {\n  while (IsSpace(*str)) str++;\n  return str;\n}\n\nstatic std::vector<std::string> SplitIntoTestNames(const char* src) {\n  std::vector<std::string> name_vec;\n  src = SkipSpaces(src);\n  for (; src != nullptr; src = SkipComma(src)) {\n    name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));\n  }\n  return name_vec;\n}\n\n// Verifies that registered_tests match the test names in\n// registered_tests_; returns registered_tests if successful, or\n// aborts the program otherwise.\nconst char* TypedTestSuitePState::VerifyRegisteredTestNames(\n    const char* test_suite_name, const char* file, int line,\n    const char* registered_tests) {\n  RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));\n\n  typedef RegisteredTestsMap::const_iterator RegisteredTestIter;\n  registered_ = true;\n\n  std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);\n\n  Message errors;\n\n  std::set<std::string> tests;\n  for (std::vector<std::string>::const_iterator name_it = name_vec.begin();\n       name_it != name_vec.end(); ++name_it) {\n    const std::string& name = *name_it;\n    if (tests.count(name) != 0) {\n      errors << \"Test \" << name << \" is listed more than once.\\n\";\n      continue;\n    }\n\n    if (registered_tests_.count(name) != 0) {\n      tests.insert(name);\n    } else {\n      errors << \"No test named \" << name\n             << \" can be found in this test suite.\\n\";\n    }\n  }\n\n  for (RegisteredTestIter it = registered_tests_.begin();\n       it != registered_tests_.end(); ++it) {\n    if (tests.count(it->first) == 0) {\n      errors << \"You forgot to list test \" << it->first << \".\\n\";\n    }\n  }\n\n  const std::string& errors_str = errors.GetString();\n  if (!errors_str.empty()) {\n    fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\n            errors_str.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n\n  return registered_tests;\n}\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest.cc",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n//\n// The Google C++ Testing and Mocking Framework (Google Test)\n\n#include \"gtest/gtest.h\"\n\n#include <ctype.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include <wchar.h>\n#include <wctype.h>\n\n#include <algorithm>\n#include <chrono>  // NOLINT\n#include <cmath>\n#include <csignal>  // NOLINT: raise(3) is used on some platforms\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <initializer_list>\n#include <iomanip>\n#include <ios>\n#include <iostream>\n#include <iterator>\n#include <limits>\n#include <list>\n#include <map>\n#include <ostream>  // NOLINT\n#include <set>\n#include <sstream>\n#include <unordered_set>\n#include <utility>\n#include <vector>\n\n#include \"gtest/gtest-assertion-result.h\"\n#include \"gtest/gtest-spi.h\"\n#include \"gtest/internal/custom/gtest.h\"\n#include \"gtest/internal/gtest-port.h\"\n\n#ifdef GTEST_OS_LINUX\n\n#include <fcntl.h>   // NOLINT\n#include <limits.h>  // NOLINT\n#include <sched.h>   // NOLINT\n// Declares vsnprintf().  This header is not available on Windows.\n#include <strings.h>   // NOLINT\n#include <sys/mman.h>  // NOLINT\n#include <sys/time.h>  // NOLINT\n#include <unistd.h>    // NOLINT\n\n#include <string>\n\n#elif defined(GTEST_OS_ZOS)\n#include <sys/time.h>  // NOLINT\n\n// On z/OS we additionally need strings.h for strcasecmp.\n#include <strings.h>   // NOLINT\n\n#elif defined(GTEST_OS_WINDOWS_MOBILE)  // We are on Windows CE.\n\n#include <windows.h>  // NOLINT\n#undef min\n\n#elif defined(GTEST_OS_WINDOWS)  // We are on Windows proper.\n\n#include <windows.h>  // NOLINT\n#undef min\n\n#ifdef _MSC_VER\n#include <crtdbg.h>  // NOLINT\n#endif\n\n#include <io.h>         // NOLINT\n#include <sys/stat.h>   // NOLINT\n#include <sys/timeb.h>  // NOLINT\n#include <sys/types.h>  // NOLINT\n\n#ifdef GTEST_OS_WINDOWS_MINGW\n#include <sys/time.h>  // NOLINT\n#endif                 // GTEST_OS_WINDOWS_MINGW\n\n#else\n\n// cpplint thinks that the header is already included, so we want to\n// silence it.\n#include <sys/time.h>  // NOLINT\n#include <unistd.h>    // NOLINT\n\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_EXCEPTIONS\n#include <stdexcept>\n#endif\n\n#if GTEST_CAN_STREAM_RESULTS_\n#include <arpa/inet.h>   // NOLINT\n#include <netdb.h>       // NOLINT\n#include <sys/socket.h>  // NOLINT\n#include <sys/types.h>   // NOLINT\n#endif\n\n#include \"src/gtest-internal-inl.h\"\n\n#ifdef GTEST_OS_WINDOWS\n#define vsnprintf _vsnprintf\n#endif  // GTEST_OS_WINDOWS\n\n#ifdef GTEST_OS_MAC\n#ifndef GTEST_OS_IOS\n#include <crt_externs.h>\n#endif\n#endif\n\n#ifdef GTEST_HAS_ABSL\n#include \"absl/container/flat_hash_set.h\"\n#include \"absl/debugging/failure_signal_handler.h\"\n#include \"absl/debugging/stacktrace.h\"\n#include \"absl/debugging/symbolize.h\"\n#include \"absl/flags/parse.h\"\n#include \"absl/flags/usage.h\"\n#include \"absl/strings/str_cat.h\"\n#include \"absl/strings/str_replace.h\"\n#include \"absl/strings/string_view.h\"\n#include \"absl/strings/strip.h\"\n#endif  // GTEST_HAS_ABSL\n\n// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs\n// at the callsite.\n#if defined(__has_builtin)\n#define GTEST_HAS_BUILTIN(x) __has_builtin(x)\n#else\n#define GTEST_HAS_BUILTIN(x) 0\n#endif  // defined(__has_builtin)\n\n#if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS)\n#define GTEST_HAS_ABSL_FLAGS\n#endif\n\nnamespace testing {\n\nusing internal::CountIf;\nusing internal::ForEach;\nusing internal::GetElementOr;\nusing internal::Shuffle;\n\n// Constants.\n\n// A test whose test suite name or test name matches this filter is\n// disabled and not run.\nstatic const char kDisableTestFilter[] = \"DISABLED_*:*/DISABLED_*\";\n\n// A test suite whose name matches this filter is considered a death\n// test suite and will be run before test suites whose name doesn't\n// match this filter.\nstatic const char kDeathTestSuiteFilter[] = \"*DeathTest:*DeathTest/*\";\n\n// A test filter that matches everything.\nstatic const char kUniversalFilter[] = \"*\";\n\n// The default output format.\nstatic const char kDefaultOutputFormat[] = \"xml\";\n// The default output file.\nstatic const char kDefaultOutputFile[] = \"test_detail\";\n\n// The environment variable name for the test shard index.\nstatic const char kTestShardIndex[] = \"GTEST_SHARD_INDEX\";\n// The environment variable name for the total number of test shards.\nstatic const char kTestTotalShards[] = \"GTEST_TOTAL_SHARDS\";\n// The environment variable name for the test shard status file.\nstatic const char kTestShardStatusFile[] = \"GTEST_SHARD_STATUS_FILE\";\n\nnamespace internal {\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nconst char kStackTraceMarker[] = \"\\nStack trace:\\n\";\n\n// g_help_flag is true if and only if the --help flag or an equivalent form\n// is specified on the command line.\nbool g_help_flag = false;\n\n#if GTEST_HAS_FILE_SYSTEM\n// Utility function to Open File for Writing\nstatic FILE* OpenFileForWriting(const std::string& output_file) {\n  FILE* fileout = nullptr;\n  FilePath output_file_path(output_file);\n  FilePath output_dir(output_file_path.RemoveFileName());\n\n  if (output_dir.CreateDirectoriesRecursively()) {\n    fileout = posix::FOpen(output_file.c_str(), \"w\");\n  }\n  if (fileout == nullptr) {\n    GTEST_LOG_(FATAL) << \"Unable to open file \\\"\" << output_file << \"\\\"\";\n  }\n  return fileout;\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n}  // namespace internal\n\n// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY\n// environment variable.\nstatic const char* GetDefaultFilter() {\n  const char* const testbridge_test_only =\n      internal::posix::GetEnv(\"TESTBRIDGE_TEST_ONLY\");\n  if (testbridge_test_only != nullptr) {\n    return testbridge_test_only;\n  }\n  return kUniversalFilter;\n}\n\n// Bazel passes in the argument to '--test_runner_fail_fast' via the\n// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable.\nstatic bool GetDefaultFailFast() {\n  const char* const testbridge_test_runner_fail_fast =\n      internal::posix::GetEnv(\"TESTBRIDGE_TEST_RUNNER_FAIL_FAST\");\n  if (testbridge_test_runner_fail_fast != nullptr) {\n    return strcmp(testbridge_test_runner_fail_fast, \"1\") == 0;\n  }\n  return false;\n}\n\n}  // namespace testing\n\nGTEST_DEFINE_bool_(\n    fail_fast,\n    testing::internal::BoolFromGTestEnv(\"fail_fast\",\n                                        testing::GetDefaultFailFast()),\n    \"True if and only if a test failure should stop further test execution.\");\n\nGTEST_DEFINE_bool_(\n    also_run_disabled_tests,\n    testing::internal::BoolFromGTestEnv(\"also_run_disabled_tests\", false),\n    \"Run disabled tests too, in addition to the tests normally being run.\");\n\nGTEST_DEFINE_bool_(\n    break_on_failure,\n    testing::internal::BoolFromGTestEnv(\"break_on_failure\", false),\n    \"True if and only if a failed assertion should be a debugger \"\n    \"break-point.\");\n\nGTEST_DEFINE_bool_(catch_exceptions,\n                   testing::internal::BoolFromGTestEnv(\"catch_exceptions\",\n                                                       true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should catch exceptions and treat them as test failures.\");\n\nGTEST_DEFINE_string_(\n    color, testing::internal::StringFromGTestEnv(\"color\", \"auto\"),\n    \"Whether to use colors in the output.  Valid values: yes, no, \"\n    \"and auto.  'auto' means to use colors if the output is \"\n    \"being sent to a terminal and the TERM environment variable \"\n    \"is set to a terminal type that supports colors.\");\n\nGTEST_DEFINE_string_(\n    filter,\n    testing::internal::StringFromGTestEnv(\"filter\",\n                                          testing::GetDefaultFilter()),\n    \"A colon-separated list of glob (not regex) patterns \"\n    \"for filtering the tests to run, optionally followed by a \"\n    \"'-' and a : separated list of negative patterns (tests to \"\n    \"exclude).  A test is run if it matches one of the positive \"\n    \"patterns and does not match any of the negative patterns.\");\n\nGTEST_DEFINE_bool_(\n    install_failure_signal_handler,\n    testing::internal::BoolFromGTestEnv(\"install_failure_signal_handler\",\n                                        false),\n    \"If true and supported on the current platform, \" GTEST_NAME_\n    \" should \"\n    \"install a signal handler that dumps debugging information when fatal \"\n    \"signals are raised.\");\n\nGTEST_DEFINE_bool_(list_tests, false, \"List all tests without running them.\");\n\n// The net priority order after flag processing is thus:\n//   --gtest_output command line flag\n//   GTEST_OUTPUT environment variable\n//   XML_OUTPUT_FILE environment variable\n//   ''\nGTEST_DEFINE_string_(\n    output,\n    testing::internal::StringFromGTestEnv(\n        \"output\", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()),\n    \"A format (defaults to \\\"xml\\\" but can be specified to be \\\"json\\\"), \"\n    \"optionally followed by a colon and an output file name or directory. \"\n    \"A directory is indicated by a trailing pathname separator. \"\n    \"Examples: \\\"xml:filename.xml\\\", \\\"xml::directoryname/\\\". \"\n    \"If a directory is specified, output files will be created \"\n    \"within that directory, with file-names based on the test \"\n    \"executable's name and, if necessary, made unique by adding \"\n    \"digits.\");\n\nGTEST_DEFINE_bool_(\n    brief, testing::internal::BoolFromGTestEnv(\"brief\", false),\n    \"True if only test failures should be displayed in text output.\");\n\nGTEST_DEFINE_bool_(print_time,\n                   testing::internal::BoolFromGTestEnv(\"print_time\", true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should display elapsed time in text output.\");\n\nGTEST_DEFINE_bool_(print_utf8,\n                   testing::internal::BoolFromGTestEnv(\"print_utf8\", true),\n                   \"True if and only if \" GTEST_NAME_\n                   \" prints UTF8 characters as text.\");\n\nGTEST_DEFINE_int32_(\n    random_seed, testing::internal::Int32FromGTestEnv(\"random_seed\", 0),\n    \"Random number seed to use when shuffling test orders.  Must be in range \"\n    \"[1, 99999], or 0 to use a seed based on the current time.\");\n\nGTEST_DEFINE_int32_(\n    repeat, testing::internal::Int32FromGTestEnv(\"repeat\", 1),\n    \"How many times to repeat each test.  Specify a negative number \"\n    \"for repeating forever.  Useful for shaking out flaky tests.\");\n\nGTEST_DEFINE_bool_(\n    recreate_environments_when_repeating,\n    testing::internal::BoolFromGTestEnv(\"recreate_environments_when_repeating\",\n                                        false),\n    \"Controls whether global test environments are recreated for each repeat \"\n    \"of the tests. If set to false the global test environments are only set \"\n    \"up once, for the first iteration, and only torn down once, for the last. \"\n    \"Useful for shaking out flaky tests with stable, expensive test \"\n    \"environments. If --gtest_repeat is set to a negative number, meaning \"\n    \"there is no last run, the environments will always be recreated to avoid \"\n    \"leaks.\");\n\nGTEST_DEFINE_bool_(show_internal_stack_frames, false,\n                   \"True if and only if \" GTEST_NAME_\n                   \" should include internal stack frames when \"\n                   \"printing test failure stack traces.\");\n\nGTEST_DEFINE_bool_(shuffle,\n                   testing::internal::BoolFromGTestEnv(\"shuffle\", false),\n                   \"True if and only if \" GTEST_NAME_\n                   \" should randomize tests' order on every run.\");\n\nGTEST_DEFINE_int32_(\n    stack_trace_depth,\n    testing::internal::Int32FromGTestEnv(\"stack_trace_depth\",\n                                         testing::kMaxStackTraceDepth),\n    \"The maximum number of stack frames to print when an \"\n    \"assertion fails.  The valid range is 0 through 100, inclusive.\");\n\nGTEST_DEFINE_string_(\n    stream_result_to,\n    testing::internal::StringFromGTestEnv(\"stream_result_to\", \"\"),\n    \"This flag specifies the host name and the port number on which to stream \"\n    \"test results. Example: \\\"localhost:555\\\". The flag is effective only on \"\n    \"Linux and macOS.\");\n\nGTEST_DEFINE_bool_(\n    throw_on_failure,\n    testing::internal::BoolFromGTestEnv(\"throw_on_failure\", false),\n    \"When this flag is specified, a failed assertion will throw an exception \"\n    \"if exceptions are enabled or exit the program with a non-zero code \"\n    \"otherwise. For use with an external test framework.\");\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_\nGTEST_DEFINE_string_(\n    flagfile, testing::internal::StringFromGTestEnv(\"flagfile\", \"\"),\n    \"This flag specifies the flagfile to read command-line flags from.\");\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_\n\nnamespace testing {\nnamespace internal {\n\nconst uint32_t Random::kMaxRange;\n\n// Generates a random number from [0, range), using a Linear\n// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater\n// than kMaxRange.\nuint32_t Random::Generate(uint32_t range) {\n  // These constants are the same as are used in glibc's rand(3).\n  // Use wider types than necessary to prevent unsigned overflow diagnostics.\n  state_ = static_cast<uint32_t>(1103515245ULL * state_ + 12345U) % kMaxRange;\n\n  GTEST_CHECK_(range > 0) << \"Cannot generate a number in the range [0, 0).\";\n  GTEST_CHECK_(range <= kMaxRange)\n      << \"Generation of a number in [0, \" << range << \") was requested, \"\n      << \"but this can only generate numbers in [0, \" << kMaxRange << \").\";\n\n  // Converting via modulus introduces a bit of downward bias, but\n  // it's simple, and a linear congruential generator isn't too good\n  // to begin with.\n  return state_ % range;\n}\n\n// GTestIsInitialized() returns true if and only if the user has initialized\n// Google Test.  Useful for catching the user mistake of not initializing\n// Google Test before calling RUN_ALL_TESTS().\nstatic bool GTestIsInitialized() { return !GetArgvs().empty(); }\n\n// Iterates over a vector of TestSuites, keeping a running sum of the\n// results of calling a given int-returning method on each.\n// Returns the sum.\nstatic int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list,\n                                int (TestSuite::*method)() const) {\n  int sum = 0;\n  for (size_t i = 0; i < case_list.size(); i++) {\n    sum += (case_list[i]->*method)();\n  }\n  return sum;\n}\n\n// Returns true if and only if the test suite passed.\nstatic bool TestSuitePassed(const TestSuite* test_suite) {\n  return test_suite->should_run() && test_suite->Passed();\n}\n\n// Returns true if and only if the test suite failed.\nstatic bool TestSuiteFailed(const TestSuite* test_suite) {\n  return test_suite->should_run() && test_suite->Failed();\n}\n\n// Returns true if and only if test_suite contains at least one test that\n// should run.\nstatic bool ShouldRunTestSuite(const TestSuite* test_suite) {\n  return test_suite->should_run();\n}\n\nnamespace {\n\n// Returns true if test part results of type `type` should include a stack\n// trace.\nbool ShouldEmitStackTraceForResultType(TestPartResult::Type type) {\n  // Suppress emission of the stack trace for SUCCEED() since it likely never\n  // requires investigation, and GTEST_SKIP() since skipping is an intentional\n  // act by the developer rather than a failure requiring investigation.\n  return type != TestPartResult::kSuccess && type != TestPartResult::kSkip;\n}\n\n}  // namespace\n\n// AssertHelper constructor.\nAssertHelper::AssertHelper(TestPartResult::Type type, const char* file,\n                           int line, const char* message)\n    : data_(new AssertHelperData(type, file, line, message)) {}\n\nAssertHelper::~AssertHelper() { delete data_; }\n\n// Message assignment, for assertion streaming support.\nvoid AssertHelper::operator=(const Message& message) const {\n  UnitTest::GetInstance()->AddTestPartResult(\n      data_->type, data_->file, data_->line,\n      AppendUserMessage(data_->message, message),\n      ShouldEmitStackTraceForResultType(data_->type)\n          ? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1)\n          : \"\"\n      // Skips the stack frame for this function itself.\n  );  // NOLINT\n}\n\nnamespace {\n\n// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P\n// to creates test cases for it, a synthetic test case is\n// inserted to report ether an error or a log message.\n//\n// This configuration bit will likely be removed at some point.\nconstexpr bool kErrorOnUninstantiatedParameterizedTest = true;\nconstexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true;\n\n// A test that fails at a given file/line location with a given message.\nclass FailureTest : public Test {\n public:\n  explicit FailureTest(const CodeLocation& loc, std::string error_message,\n                       bool as_error)\n      : loc_(loc),\n        error_message_(std::move(error_message)),\n        as_error_(as_error) {}\n\n  void TestBody() override {\n    if (as_error_) {\n      AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(),\n                   loc_.line, \"\") = Message() << error_message_;\n    } else {\n      std::cout << error_message_ << std::endl;\n    }\n  }\n\n private:\n  const CodeLocation loc_;\n  const std::string error_message_;\n  const bool as_error_;\n};\n\n}  // namespace\n\nstd::set<std::string>* GetIgnoredParameterizedTestSuites() {\n  return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites();\n}\n\n// Add a given test_suit to the list of them allow to go un-instantiated.\nMarkAsIgnored::MarkAsIgnored(const char* test_suite) {\n  GetIgnoredParameterizedTestSuites()->insert(test_suite);\n}\n\n// If this parameterized test suite has no instantiations (and that\n// has not been marked as okay), emit a test case reporting that.\nvoid InsertSyntheticTestCase(const std::string& name, CodeLocation location,\n                             bool has_test_p) {\n  const auto& ignored = *GetIgnoredParameterizedTestSuites();\n  if (ignored.find(name) != ignored.end()) return;\n\n  const char kMissingInstantiation[] =  //\n      \" is defined via TEST_P, but never instantiated. None of the test \"\n      \"cases \"\n      \"will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only \"\n      \"ones provided expand to nothing.\"\n      \"\\n\\n\"\n      \"Ideally, TEST_P definitions should only ever be included as part of \"\n      \"binaries that intend to use them. (As opposed to, for example, being \"\n      \"placed in a library that may be linked in to get other utilities.)\";\n\n  const char kMissingTestCase[] =  //\n      \" is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are \"\n      \"defined via TEST_P . No test cases will run.\"\n      \"\\n\\n\"\n      \"Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from \"\n      \"code that always depend on code that provides TEST_P. Failing to do \"\n      \"so is often an indication of dead code, e.g. the last TEST_P was \"\n      \"removed but the rest got left behind.\";\n\n  std::string message =\n      \"Parameterized test suite \" + name +\n      (has_test_p ? kMissingInstantiation : kMissingTestCase) +\n      \"\\n\\n\"\n      \"To suppress this error for this test suite, insert the following line \"\n      \"(in a non-header) in the namespace it is defined in:\"\n      \"\\n\\n\"\n      \"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(\" +\n      name + \");\";\n\n  std::string full_name = \"UninstantiatedParameterizedTestSuite<\" + name + \">\";\n  RegisterTest(  //\n      \"GoogleTestVerification\", full_name.c_str(),\n      nullptr,  // No type parameter.\n      nullptr,  // No value parameter.\n      location.file.c_str(), location.line, [message, location] {\n        return new FailureTest(location, message,\n                               kErrorOnUninstantiatedParameterizedTest);\n      });\n}\n\nvoid RegisterTypeParameterizedTestSuite(const char* test_suite_name,\n                                        CodeLocation code_location) {\n  GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite(\n      test_suite_name, std::move(code_location));\n}\n\nvoid RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) {\n  GetUnitTestImpl()->type_parameterized_test_registry().RegisterInstantiation(\n      case_name);\n}\n\nvoid TypeParameterizedTestSuiteRegistry::RegisterTestSuite(\n    const char* test_suite_name, CodeLocation code_location) {\n  suites_.emplace(std::string(test_suite_name),\n                  TypeParameterizedTestSuiteInfo(std::move(code_location)));\n}\n\nvoid TypeParameterizedTestSuiteRegistry::RegisterInstantiation(\n    const char* test_suite_name) {\n  auto it = suites_.find(std::string(test_suite_name));\n  if (it != suites_.end()) {\n    it->second.instantiated = true;\n  } else {\n    GTEST_LOG_(ERROR) << \"Unknown type parameterized test suit '\"\n                      << test_suite_name << \"'\";\n  }\n}\n\nvoid TypeParameterizedTestSuiteRegistry::CheckForInstantiations() {\n  const auto& ignored = *GetIgnoredParameterizedTestSuites();\n  for (const auto& testcase : suites_) {\n    if (testcase.second.instantiated) continue;\n    if (ignored.find(testcase.first) != ignored.end()) continue;\n\n    std::string message =\n        \"Type parameterized test suite \" + testcase.first +\n        \" is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated \"\n        \"via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run.\"\n        \"\\n\\n\"\n        \"Ideally, TYPED_TEST_P definitions should only ever be included as \"\n        \"part of binaries that intend to use them. (As opposed to, for \"\n        \"example, being placed in a library that may be linked in to get \"\n        \"other \"\n        \"utilities.)\"\n        \"\\n\\n\"\n        \"To suppress this error for this test suite, insert the following \"\n        \"line \"\n        \"(in a non-header) in the namespace it is defined in:\"\n        \"\\n\\n\"\n        \"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(\" +\n        testcase.first + \");\";\n\n    std::string full_name =\n        \"UninstantiatedTypeParameterizedTestSuite<\" + testcase.first + \">\";\n    RegisterTest(  //\n        \"GoogleTestVerification\", full_name.c_str(),\n        nullptr,  // No type parameter.\n        nullptr,  // No value parameter.\n        testcase.second.code_location.file.c_str(),\n        testcase.second.code_location.line, [message, testcase] {\n          return new FailureTest(testcase.second.code_location, message,\n                                 kErrorOnUninstantiatedTypeParameterizedTest);\n        });\n  }\n}\n\n// A copy of all command line arguments.  Set by InitGoogleTest().\nstatic ::std::vector<std::string> g_argvs;\n\n::std::vector<std::string> GetArgvs() {\n#if defined(GTEST_CUSTOM_GET_ARGVS_)\n  // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or\n  // ::string. This code converts it to the appropriate type.\n  const auto& custom = GTEST_CUSTOM_GET_ARGVS_();\n  return ::std::vector<std::string>(custom.begin(), custom.end());\n#else   // defined(GTEST_CUSTOM_GET_ARGVS_)\n  return g_argvs;\n#endif  // defined(GTEST_CUSTOM_GET_ARGVS_)\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the current application's name, removing directory path if that\n// is present.\nFilePath GetCurrentExecutableName() {\n  FilePath result;\n\n#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_OS2)\n  result.Set(FilePath(GetArgvs()[0]).RemoveExtension(\"exe\"));\n#else\n  result.Set(FilePath(GetArgvs()[0]));\n#endif  // GTEST_OS_WINDOWS\n\n  return result.RemoveDirectoryName();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Functions for processing the gtest_output flag.\n\n// Returns the output format, or \"\" for normal printed output.\nstd::string UnitTestOptions::GetOutputFormat() {\n  std::string s = GTEST_FLAG_GET(output);\n  const char* const gtest_output_flag = s.c_str();\n  const char* const colon = strchr(gtest_output_flag, ':');\n  return (colon == nullptr)\n             ? std::string(gtest_output_flag)\n             : std::string(gtest_output_flag,\n                           static_cast<size_t>(colon - gtest_output_flag));\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the name of the requested output file, or the default if none\n// was explicitly specified.\nstd::string UnitTestOptions::GetAbsolutePathToOutputFile() {\n  std::string s = GTEST_FLAG_GET(output);\n  const char* const gtest_output_flag = s.c_str();\n\n  std::string format = GetOutputFormat();\n  if (format.empty()) format = std::string(kDefaultOutputFormat);\n\n  const char* const colon = strchr(gtest_output_flag, ':');\n  if (colon == nullptr)\n    return internal::FilePath::MakeFileName(\n               internal::FilePath(\n                   UnitTest::GetInstance()->original_working_dir()),\n               internal::FilePath(kDefaultOutputFile), 0, format.c_str())\n        .string();\n\n  internal::FilePath output_name(colon + 1);\n  if (!output_name.IsAbsolutePath())\n    output_name = internal::FilePath::ConcatPaths(\n        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),\n        internal::FilePath(colon + 1));\n\n  if (!output_name.IsDirectory()) return output_name.string();\n\n  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(\n      output_name, internal::GetCurrentExecutableName(),\n      GetOutputFormat().c_str()));\n  return result.string();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Returns true if and only if the wildcard pattern matches the string. Each\n// pattern consists of regular characters, single-character wildcards (?), and\n// multi-character wildcards (*).\n//\n// This function implements a linear-time string globbing algorithm based on\n// https://research.swtch.com/glob.\nstatic bool PatternMatchesString(const std::string& name_str,\n                                 const char* pattern, const char* pattern_end) {\n  const char* name = name_str.c_str();\n  const char* const name_begin = name;\n  const char* const name_end = name + name_str.size();\n\n  const char* pattern_next = pattern;\n  const char* name_next = name;\n\n  while (pattern < pattern_end || name < name_end) {\n    if (pattern < pattern_end) {\n      switch (*pattern) {\n        default:  // Match an ordinary character.\n          if (name < name_end && *name == *pattern) {\n            ++pattern;\n            ++name;\n            continue;\n          }\n          break;\n        case '?':  // Match any single character.\n          if (name < name_end) {\n            ++pattern;\n            ++name;\n            continue;\n          }\n          break;\n        case '*':\n          // Match zero or more characters. Start by skipping over the wildcard\n          // and matching zero characters from name. If that fails, restart and\n          // match one more character than the last attempt.\n          pattern_next = pattern;\n          name_next = name + 1;\n          ++pattern;\n          continue;\n      }\n    }\n    // Failed to match a character. Restart if possible.\n    if (name_begin < name_next && name_next <= name_end) {\n      pattern = pattern_next;\n      name = name_next;\n      continue;\n    }\n    return false;\n  }\n  return true;\n}\n\nnamespace {\n\nbool IsGlobPattern(const std::string& pattern) {\n  return std::any_of(pattern.begin(), pattern.end(),\n                     [](const char c) { return c == '?' || c == '*'; });\n}\n\nclass UnitTestFilter {\n public:\n  UnitTestFilter() = default;\n\n  // Constructs a filter from a string of patterns separated by `:`.\n  explicit UnitTestFilter(const std::string& filter) {\n    // By design \"\" filter matches \"\" string.\n    std::vector<std::string> all_patterns;\n    SplitString(filter, ':', &all_patterns);\n    const auto exact_match_patterns_begin = std::partition(\n        all_patterns.begin(), all_patterns.end(), &IsGlobPattern);\n\n    glob_patterns_.reserve(static_cast<size_t>(\n        std::distance(all_patterns.begin(), exact_match_patterns_begin)));\n    std::move(all_patterns.begin(), exact_match_patterns_begin,\n              std::inserter(glob_patterns_, glob_patterns_.begin()));\n    std::move(\n        exact_match_patterns_begin, all_patterns.end(),\n        std::inserter(exact_match_patterns_, exact_match_patterns_.begin()));\n  }\n\n  // Returns true if and only if name matches at least one of the patterns in\n  // the filter.\n  bool MatchesName(const std::string& name) const {\n    return exact_match_patterns_.find(name) != exact_match_patterns_.end() ||\n           std::any_of(glob_patterns_.begin(), glob_patterns_.end(),\n                       [&name](const std::string& pattern) {\n                         return PatternMatchesString(\n                             name, pattern.c_str(),\n                             pattern.c_str() + pattern.size());\n                       });\n  }\n\n private:\n  std::vector<std::string> glob_patterns_;\n  std::unordered_set<std::string> exact_match_patterns_;\n};\n\nclass PositiveAndNegativeUnitTestFilter {\n public:\n  // Constructs a positive and a negative filter from a string. The string\n  // contains a positive filter optionally followed by a '-' character and a\n  // negative filter. In case only a negative filter is provided the positive\n  // filter will be assumed \"*\".\n  // A filter is a list of patterns separated by ':'.\n  explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) {\n    std::vector<std::string> positive_and_negative_filters;\n\n    // NOTE: `SplitString` always returns a non-empty container.\n    SplitString(filter, '-', &positive_and_negative_filters);\n    const auto& positive_filter = positive_and_negative_filters.front();\n\n    if (positive_and_negative_filters.size() > 1) {\n      positive_filter_ = UnitTestFilter(\n          positive_filter.empty() ? kUniversalFilter : positive_filter);\n\n      // TODO(b/214626361): Fail on multiple '-' characters\n      // For the moment to preserve old behavior we concatenate the rest of the\n      // string parts with `-` as separator to generate the negative filter.\n      auto negative_filter_string = positive_and_negative_filters[1];\n      for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++)\n        negative_filter_string =\n            negative_filter_string + '-' + positive_and_negative_filters[i];\n      negative_filter_ = UnitTestFilter(negative_filter_string);\n    } else {\n      // In case we don't have a negative filter and positive filter is \"\"\n      // we do not use kUniversalFilter by design as opposed to when we have a\n      // negative filter.\n      positive_filter_ = UnitTestFilter(positive_filter);\n    }\n  }\n\n  // Returns true if and only if test name (this is generated by appending test\n  // suit name and test name via a '.' character) matches the positive filter\n  // and does not match the negative filter.\n  bool MatchesTest(const std::string& test_suite_name,\n                   const std::string& test_name) const {\n    return MatchesName(test_suite_name + \".\" + test_name);\n  }\n\n  // Returns true if and only if name matches the positive filter and does not\n  // match the negative filter.\n  bool MatchesName(const std::string& name) const {\n    return positive_filter_.MatchesName(name) &&\n           !negative_filter_.MatchesName(name);\n  }\n\n private:\n  UnitTestFilter positive_filter_;\n  UnitTestFilter negative_filter_;\n};\n}  // namespace\n\nbool UnitTestOptions::MatchesFilter(const std::string& name_str,\n                                    const char* filter) {\n  return UnitTestFilter(filter).MatchesName(name_str);\n}\n\n// Returns true if and only if the user-specified filter matches the test\n// suite name and the test name.\nbool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,\n                                        const std::string& test_name) {\n  // Split --gtest_filter at '-', if there is one, to separate into\n  // positive filter and negative filter portions\n  return PositiveAndNegativeUnitTestFilter(GTEST_FLAG_GET(filter))\n      .MatchesTest(test_suite_name, test_name);\n}\n\n#if GTEST_HAS_SEH\nstatic std::string FormatSehExceptionMessage(DWORD exception_code,\n                                             const char* location) {\n  Message message;\n  message << \"SEH exception with code 0x\" << std::setbase(16) << exception_code\n          << std::setbase(10) << \" thrown in \" << location << \".\";\n  return message.GetString();\n}\n\nint UnitTestOptions::GTestProcessSEH(DWORD seh_code, const char* location) {\n  // Google Test should handle a SEH exception if:\n  //   1. the user wants it to, AND\n  //   2. this is not a breakpoint exception or stack overflow, AND\n  //   3. this is not a C++ exception (VC++ implements them via SEH,\n  //      apparently).\n  //\n  // SEH exception code for C++ exceptions.\n  // (see https://support.microsoft.com/kb/185294 for more information).\n  const DWORD kCxxExceptionCode = 0xe06d7363;\n\n  if (!GTEST_FLAG_GET(catch_exceptions) || seh_code == kCxxExceptionCode ||\n      seh_code == EXCEPTION_BREAKPOINT ||\n      seh_code == EXCEPTION_STACK_OVERFLOW) {\n    return EXCEPTION_CONTINUE_SEARCH;  // Don't handle these exceptions\n  }\n\n  internal::ReportFailureInUnknownLocation(\n      TestPartResult::kFatalFailure,\n      FormatSehExceptionMessage(seh_code, location) +\n          \"\\n\"\n          \"Stack trace:\\n\" +\n          ::testing::internal::GetCurrentOsStackTraceExceptTop(1));\n\n  return EXCEPTION_EXECUTE_HANDLER;\n}\n#endif  // GTEST_HAS_SEH\n\n}  // namespace internal\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results. Intercepts only failures from the current thread.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    TestPartResultArray* result)\n    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) {\n  Init();\n}\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    InterceptMode intercept_mode, TestPartResultArray* result)\n    : intercept_mode_(intercept_mode), result_(result) {\n  Init();\n}\n\nvoid ScopedFakeTestPartResultReporter::Init() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    old_reporter_ = impl->GetGlobalTestPartResultReporter();\n    impl->SetGlobalTestPartResultReporter(this);\n  } else {\n    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();\n    impl->SetTestPartResultReporterForCurrentThread(this);\n  }\n}\n\n// The d'tor restores the test part result reporter used by Google Test\n// before.\nScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    impl->SetGlobalTestPartResultReporter(old_reporter_);\n  } else {\n    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);\n  }\n}\n\n// Increments the test part result count and remembers the result.\n// This method is from the TestPartResultReporterInterface interface.\nvoid ScopedFakeTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  result_->Append(result);\n}\n\nnamespace internal {\n\n// Returns the type ID of ::testing::Test.  We should always call this\n// instead of GetTypeId< ::testing::Test>() to get the type ID of\n// testing::Test.  This is to work around a suspected linker bug when\n// using Google Test as a framework on Mac OS X.  The bug causes\n// GetTypeId< ::testing::Test>() to return different values depending\n// on whether the call is from the Google Test framework itself or\n// from user test code.  GetTestTypeId() is guaranteed to always\n// return the same value, as it always calls GetTypeId<>() from the\n// gtest.cc, which is within the Google Test framework.\nTypeId GetTestTypeId() { return GetTypeId<Test>(); }\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nextern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();\n\n// This predicate-formatter checks that 'results' contains a test part\n// failure of the given type and that the failure message contains the\n// given substring.\nstatic AssertionResult HasOneFailure(const char* /* results_expr */,\n                                     const char* /* type_expr */,\n                                     const char* /* substr_expr */,\n                                     const TestPartResultArray& results,\n                                     TestPartResult::Type type,\n                                     const std::string& substr) {\n  const std::string expected(type == TestPartResult::kFatalFailure\n                                 ? \"1 fatal failure\"\n                                 : \"1 non-fatal failure\");\n  Message msg;\n  if (results.size() != 1) {\n    msg << \"Expected: \" << expected << \"\\n\"\n        << \"  Actual: \" << results.size() << \" failures\";\n    for (int i = 0; i < results.size(); i++) {\n      msg << \"\\n\" << results.GetTestPartResult(i);\n    }\n    return AssertionFailure() << msg;\n  }\n\n  const TestPartResult& r = results.GetTestPartResult(0);\n  if (r.type() != type) {\n    return AssertionFailure() << \"Expected: \" << expected << \"\\n\"\n                              << \"  Actual:\\n\"\n                              << r;\n  }\n\n  if (strstr(r.message(), substr.c_str()) == nullptr) {\n    return AssertionFailure()\n           << \"Expected: \" << expected << \" containing \\\"\" << substr << \"\\\"\\n\"\n           << \"  Actual:\\n\"\n           << r;\n  }\n\n  return AssertionSuccess();\n}\n\n// The constructor of SingleFailureChecker remembers where to look up\n// test part results, what type of failure we expect, and what\n// substring the failure message should contain.\nSingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results,\n                                           TestPartResult::Type type,\n                                           const std::string& substr)\n    : results_(results), type_(type), substr_(substr) {}\n\n// The destructor of SingleFailureChecker verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nSingleFailureChecker::~SingleFailureChecker() {\n  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);\n}\n\nDefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(\n    UnitTestImpl* unit_test)\n    : unit_test_(unit_test) {}\n\nvoid DefaultGlobalTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->current_test_result()->AddTestPartResult(result);\n  unit_test_->listeners()->repeater()->OnTestPartResult(result);\n}\n\nDefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(\n    UnitTestImpl* unit_test)\n    : unit_test_(unit_test) {}\n\nvoid DefaultPerThreadTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);\n}\n\n// Returns the global test part result reporter.\nTestPartResultReporterInterface*\nUnitTestImpl::GetGlobalTestPartResultReporter() {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  return global_test_part_result_reporter_;\n}\n\n// Sets the global test part result reporter.\nvoid UnitTestImpl::SetGlobalTestPartResultReporter(\n    TestPartResultReporterInterface* reporter) {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  global_test_part_result_reporter_ = reporter;\n}\n\n// Returns the test part result reporter for the current thread.\nTestPartResultReporterInterface*\nUnitTestImpl::GetTestPartResultReporterForCurrentThread() {\n  return per_thread_test_part_result_reporter_.get();\n}\n\n// Sets the test part result reporter for the current thread.\nvoid UnitTestImpl::SetTestPartResultReporterForCurrentThread(\n    TestPartResultReporterInterface* reporter) {\n  per_thread_test_part_result_reporter_.set(reporter);\n}\n\n// Gets the number of successful test suites.\nint UnitTestImpl::successful_test_suite_count() const {\n  return CountIf(test_suites_, TestSuitePassed);\n}\n\n// Gets the number of failed test suites.\nint UnitTestImpl::failed_test_suite_count() const {\n  return CountIf(test_suites_, TestSuiteFailed);\n}\n\n// Gets the number of all test suites.\nint UnitTestImpl::total_test_suite_count() const {\n  return static_cast<int>(test_suites_.size());\n}\n\n// Gets the number of all test suites that contain at least one test\n// that should run.\nint UnitTestImpl::test_suite_to_run_count() const {\n  return CountIf(test_suites_, ShouldRunTestSuite);\n}\n\n// Gets the number of successful tests.\nint UnitTestImpl::successful_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count);\n}\n\n// Gets the number of skipped tests.\nint UnitTestImpl::skipped_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count);\n}\n\n// Gets the number of failed tests.\nint UnitTestImpl::failed_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count);\n}\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint UnitTestImpl::reportable_disabled_test_count() const {\n  return SumOverTestSuiteList(test_suites_,\n                              &TestSuite::reportable_disabled_test_count);\n}\n\n// Gets the number of disabled tests.\nint UnitTestImpl::disabled_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count);\n}\n\n// Gets the number of tests to be printed in the XML report.\nint UnitTestImpl::reportable_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count);\n}\n\n// Gets the number of all tests.\nint UnitTestImpl::total_test_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count);\n}\n\n// Gets the number of tests that should run.\nint UnitTestImpl::test_to_run_count() const {\n  return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count);\n}\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n// trace but Bar() and CurrentOsStackTraceExceptTop() won't.\nstd::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {\n  return os_stack_trace_getter()->CurrentStackTrace(\n      static_cast<int>(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1\n      // Skips the user-specified number of frames plus this function\n      // itself.\n  );  // NOLINT\n}\n\n// A helper class for measuring elapsed times.\nclass Timer {\n public:\n  Timer() : start_(clock::now()) {}\n\n  // Return time elapsed in milliseconds since the timer was created.\n  TimeInMillis Elapsed() {\n    return std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() -\n                                                                 start_)\n        .count();\n  }\n\n private:\n  // Fall back to the system_clock when building with newlib on a system\n  // without a monotonic clock.\n#if defined(_NEWLIB_VERSION) && !defined(CLOCK_MONOTONIC)\n  using clock = std::chrono::system_clock;\n#else\n  using clock = std::chrono::steady_clock;\n#endif\n  clock::time_point start_;\n};\n\n// Returns a timestamp as milliseconds since the epoch. Note this time may jump\n// around subject to adjustments by the system, to measure elapsed time use\n// Timer instead.\nTimeInMillis GetTimeInMillis() {\n  return std::chrono::duration_cast<std::chrono::milliseconds>(\n             std::chrono::system_clock::now() -\n             std::chrono::system_clock::from_time_t(0))\n      .count();\n}\n\n// Utilities\n\n// class String.\n\n#ifdef GTEST_OS_WINDOWS_MOBILE\n// Creates a UTF-16 wide string from the given ANSI string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the wide string, or NULL if the\n// input is NULL.\nLPCWSTR String::AnsiToUtf16(const char* ansi) {\n  if (!ansi) return nullptr;\n  const int length = strlen(ansi);\n  const int unicode_length =\n      MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0);\n  WCHAR* unicode = new WCHAR[unicode_length + 1];\n  MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length);\n  unicode[unicode_length] = 0;\n  return unicode;\n}\n\n// Creates an ANSI string from the given wide string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the ANSI string, or NULL if the\n// input is NULL.\nconst char* String::Utf16ToAnsi(LPCWSTR utf16_str) {\n  if (!utf16_str) return nullptr;\n  const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr,\n                                              0, nullptr, nullptr);\n  char* ansi = new char[ansi_length + 1];\n  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr,\n                      nullptr);\n  ansi[ansi_length] = 0;\n  return ansi;\n}\n\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Compares two C strings.  Returns true if and only if they have the same\n// content.\n//\n// Unlike strcmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CStringEquals(const char* lhs, const char* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n  return strcmp(lhs, rhs) == 0;\n}\n\n#if GTEST_HAS_STD_WSTRING\n\n// Converts an array of wide chars to a narrow string using the UTF-8\n// encoding, and streams the result to the given Message object.\nstatic void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,\n                                     Message* msg) {\n  for (size_t i = 0; i != length;) {  // NOLINT\n    if (wstr[i] != L'\\0') {\n      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));\n      while (i != length && wstr[i] != L'\\0') i++;\n    } else {\n      *msg << '\\0';\n      i++;\n    }\n  }\n}\n\n#endif  // GTEST_HAS_STD_WSTRING\n\nvoid SplitString(const ::std::string& str, char delimiter,\n                 ::std::vector< ::std::string>* dest) {\n  ::std::vector< ::std::string> parsed;\n  ::std::string::size_type pos = 0;\n  while (::testing::internal::AlwaysTrue()) {\n    const ::std::string::size_type colon = str.find(delimiter, pos);\n    if (colon == ::std::string::npos) {\n      parsed.push_back(str.substr(pos));\n      break;\n    } else {\n      parsed.push_back(str.substr(pos, colon - pos));\n      pos = colon + 1;\n    }\n  }\n  dest->swap(parsed);\n}\n\n}  // namespace internal\n\n// Constructs an empty Message.\n// We allocate the stringstream separately because otherwise each use of\n// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's\n// stack frame leading to huge stack frames in some cases; gcc does not reuse\n// the stack space.\nMessage::Message() : ss_(new ::std::stringstream) {\n  // By default, we want there to be enough precision when printing\n  // a double to a Message.\n  *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);\n}\n\n// These two overloads allow streaming a wide C string to a Message\n// using the UTF-8 encoding.\nMessage& Message::operator<<(const wchar_t* wide_c_str) {\n  return *this << internal::String::ShowWideCString(wide_c_str);\n}\nMessage& Message::operator<<(wchar_t* wide_c_str) {\n  return *this << internal::String::ShowWideCString(wide_c_str);\n}\n\n#if GTEST_HAS_STD_WSTRING\n// Converts the given wide string to a narrow string using the UTF-8\n// encoding, and streams the result to this Message object.\nMessage& Message::operator<<(const ::std::wstring& wstr) {\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\n  return *this;\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n// Gets the text streamed to this object so far as an std::string.\n// Each '\\0' character in the buffer is replaced with \"\\\\0\".\nstd::string Message::GetString() const {\n  return internal::StringStreamToString(ss_.get());\n}\n\nnamespace internal {\n\nnamespace edit_distance {\nstd::vector<EditType> CalculateOptimalEdits(const std::vector<size_t>& left,\n                                            const std::vector<size_t>& right) {\n  std::vector<std::vector<double> > costs(\n      left.size() + 1, std::vector<double>(right.size() + 1));\n  std::vector<std::vector<EditType> > best_move(\n      left.size() + 1, std::vector<EditType>(right.size() + 1));\n\n  // Populate for empty right.\n  for (size_t l_i = 0; l_i < costs.size(); ++l_i) {\n    costs[l_i][0] = static_cast<double>(l_i);\n    best_move[l_i][0] = kRemove;\n  }\n  // Populate for empty left.\n  for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) {\n    costs[0][r_i] = static_cast<double>(r_i);\n    best_move[0][r_i] = kAdd;\n  }\n\n  for (size_t l_i = 0; l_i < left.size(); ++l_i) {\n    for (size_t r_i = 0; r_i < right.size(); ++r_i) {\n      if (left[l_i] == right[r_i]) {\n        // Found a match. Consume it.\n        costs[l_i + 1][r_i + 1] = costs[l_i][r_i];\n        best_move[l_i + 1][r_i + 1] = kMatch;\n        continue;\n      }\n\n      const double add = costs[l_i + 1][r_i];\n      const double remove = costs[l_i][r_i + 1];\n      const double replace = costs[l_i][r_i];\n      if (add < remove && add < replace) {\n        costs[l_i + 1][r_i + 1] = add + 1;\n        best_move[l_i + 1][r_i + 1] = kAdd;\n      } else if (remove < add && remove < replace) {\n        costs[l_i + 1][r_i + 1] = remove + 1;\n        best_move[l_i + 1][r_i + 1] = kRemove;\n      } else {\n        // We make replace a little more expensive than add/remove to lower\n        // their priority.\n        costs[l_i + 1][r_i + 1] = replace + 1.00001;\n        best_move[l_i + 1][r_i + 1] = kReplace;\n      }\n    }\n  }\n\n  // Reconstruct the best path. We do it in reverse order.\n  std::vector<EditType> best_path;\n  for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) {\n    EditType move = best_move[l_i][r_i];\n    best_path.push_back(move);\n    l_i -= move != kAdd;\n    r_i -= move != kRemove;\n  }\n  std::reverse(best_path.begin(), best_path.end());\n  return best_path;\n}\n\nnamespace {\n\n// Helper class to convert string into ids with deduplication.\nclass InternalStrings {\n public:\n  size_t GetId(const std::string& str) {\n    IdMap::iterator it = ids_.find(str);\n    if (it != ids_.end()) return it->second;\n    size_t id = ids_.size();\n    return ids_[str] = id;\n  }\n\n private:\n  typedef std::map<std::string, size_t> IdMap;\n  IdMap ids_;\n};\n\n}  // namespace\n\nstd::vector<EditType> CalculateOptimalEdits(\n    const std::vector<std::string>& left,\n    const std::vector<std::string>& right) {\n  std::vector<size_t> left_ids, right_ids;\n  {\n    InternalStrings intern_table;\n    for (size_t i = 0; i < left.size(); ++i) {\n      left_ids.push_back(intern_table.GetId(left[i]));\n    }\n    for (size_t i = 0; i < right.size(); ++i) {\n      right_ids.push_back(intern_table.GetId(right[i]));\n    }\n  }\n  return CalculateOptimalEdits(left_ids, right_ids);\n}\n\nnamespace {\n\n// Helper class that holds the state for one hunk and prints it out to the\n// stream.\n// It reorders adds/removes when possible to group all removes before all\n// adds. It also adds the hunk header before printint into the stream.\nclass Hunk {\n public:\n  Hunk(size_t left_start, size_t right_start)\n      : left_start_(left_start),\n        right_start_(right_start),\n        adds_(),\n        removes_(),\n        common_() {}\n\n  void PushLine(char edit, const char* line) {\n    switch (edit) {\n      case ' ':\n        ++common_;\n        FlushEdits();\n        hunk_.push_back(std::make_pair(' ', line));\n        break;\n      case '-':\n        ++removes_;\n        hunk_removes_.push_back(std::make_pair('-', line));\n        break;\n      case '+':\n        ++adds_;\n        hunk_adds_.push_back(std::make_pair('+', line));\n        break;\n    }\n  }\n\n  void PrintTo(std::ostream* os) {\n    PrintHeader(os);\n    FlushEdits();\n    for (std::list<std::pair<char, const char*> >::const_iterator it =\n             hunk_.begin();\n         it != hunk_.end(); ++it) {\n      *os << it->first << it->second << \"\\n\";\n    }\n  }\n\n  bool has_edits() const { return adds_ || removes_; }\n\n private:\n  void FlushEdits() {\n    hunk_.splice(hunk_.end(), hunk_removes_);\n    hunk_.splice(hunk_.end(), hunk_adds_);\n  }\n\n  // Print a unified diff header for one hunk.\n  // The format is\n  //   \"@@ -<left_start>,<left_length> +<right_start>,<right_length> @@\"\n  // where the left/right parts are omitted if unnecessary.\n  void PrintHeader(std::ostream* ss) const {\n    *ss << \"@@ \";\n    if (removes_) {\n      *ss << \"-\" << left_start_ << \",\" << (removes_ + common_);\n    }\n    if (removes_ && adds_) {\n      *ss << \" \";\n    }\n    if (adds_) {\n      *ss << \"+\" << right_start_ << \",\" << (adds_ + common_);\n    }\n    *ss << \" @@\\n\";\n  }\n\n  size_t left_start_, right_start_;\n  size_t adds_, removes_, common_;\n  std::list<std::pair<char, const char*> > hunk_, hunk_adds_, hunk_removes_;\n};\n\n}  // namespace\n\n// Create a list of diff hunks in Unified diff format.\n// Each hunk has a header generated by PrintHeader above plus a body with\n// lines prefixed with ' ' for no change, '-' for deletion and '+' for\n// addition.\n// 'context' represents the desired unchanged prefix/suffix around the diff.\n// If two hunks are close enough that their contexts overlap, then they are\n// joined into one hunk.\nstd::string CreateUnifiedDiff(const std::vector<std::string>& left,\n                              const std::vector<std::string>& right,\n                              size_t context) {\n  const std::vector<EditType> edits = CalculateOptimalEdits(left, right);\n\n  size_t l_i = 0, r_i = 0, edit_i = 0;\n  std::stringstream ss;\n  while (edit_i < edits.size()) {\n    // Find first edit.\n    while (edit_i < edits.size() && edits[edit_i] == kMatch) {\n      ++l_i;\n      ++r_i;\n      ++edit_i;\n    }\n\n    // Find the first line to include in the hunk.\n    const size_t prefix_context = std::min(l_i, context);\n    Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1);\n    for (size_t i = prefix_context; i > 0; --i) {\n      hunk.PushLine(' ', left[l_i - i].c_str());\n    }\n\n    // Iterate the edits until we found enough suffix for the hunk or the input\n    // is over.\n    size_t n_suffix = 0;\n    for (; edit_i < edits.size(); ++edit_i) {\n      if (n_suffix >= context) {\n        // Continue only if the next hunk is very close.\n        auto it = edits.begin() + static_cast<int>(edit_i);\n        while (it != edits.end() && *it == kMatch) ++it;\n        if (it == edits.end() ||\n            static_cast<size_t>(it - edits.begin()) - edit_i >= context) {\n          // There is no next edit or it is too far away.\n          break;\n        }\n      }\n\n      EditType edit = edits[edit_i];\n      // Reset count when a non match is found.\n      n_suffix = edit == kMatch ? n_suffix + 1 : 0;\n\n      if (edit == kMatch || edit == kRemove || edit == kReplace) {\n        hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str());\n      }\n      if (edit == kAdd || edit == kReplace) {\n        hunk.PushLine('+', right[r_i].c_str());\n      }\n\n      // Advance indices, depending on edit type.\n      l_i += edit != kAdd;\n      r_i += edit != kRemove;\n    }\n\n    if (!hunk.has_edits()) {\n      // We are done. We don't want this hunk.\n      break;\n    }\n\n    hunk.PrintTo(&ss);\n  }\n  return ss.str();\n}\n\n}  // namespace edit_distance\n\nnamespace {\n\n// The string representation of the values received in EqFailure() are already\n// escaped. Split them on escaped '\\n' boundaries. Leave all other escaped\n// characters the same.\nstd::vector<std::string> SplitEscapedString(const std::string& str) {\n  std::vector<std::string> lines;\n  size_t start = 0, end = str.size();\n  if (end > 2 && str[0] == '\"' && str[end - 1] == '\"') {\n    ++start;\n    --end;\n  }\n  bool escaped = false;\n  for (size_t i = start; i + 1 < end; ++i) {\n    if (escaped) {\n      escaped = false;\n      if (str[i] == 'n') {\n        lines.push_back(str.substr(start, i - start - 1));\n        start = i + 1;\n      }\n    } else {\n      escaped = str[i] == '\\\\';\n    }\n  }\n  lines.push_back(str.substr(start, end - start));\n  return lines;\n}\n\n}  // namespace\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   lhs_expression: \"foo\"\n//   rhs_expression: \"bar\"\n//   lhs_value:      \"5\"\n//   rhs_value:      \"6\"\n//\n// The ignoring_case parameter is true if and only if the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \"Ignoring case\" will\n// be inserted into the message.\nAssertionResult EqFailure(const char* lhs_expression,\n                          const char* rhs_expression,\n                          const std::string& lhs_value,\n                          const std::string& rhs_value, bool ignoring_case) {\n  Message msg;\n  msg << \"Expected equality of these values:\";\n  msg << \"\\n  \" << lhs_expression;\n  if (lhs_value != lhs_expression) {\n    msg << \"\\n    Which is: \" << lhs_value;\n  }\n  msg << \"\\n  \" << rhs_expression;\n  if (rhs_value != rhs_expression) {\n    msg << \"\\n    Which is: \" << rhs_value;\n  }\n\n  if (ignoring_case) {\n    msg << \"\\nIgnoring case\";\n  }\n\n  if (!lhs_value.empty() && !rhs_value.empty()) {\n    const std::vector<std::string> lhs_lines = SplitEscapedString(lhs_value);\n    const std::vector<std::string> rhs_lines = SplitEscapedString(rhs_value);\n    if (lhs_lines.size() > 1 || rhs_lines.size() > 1) {\n      msg << \"\\nWith diff:\\n\"\n          << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines);\n    }\n  }\n\n  return AssertionFailure() << msg;\n}\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nstd::string GetBoolAssertionFailureMessage(\n    const AssertionResult& assertion_result, const char* expression_text,\n    const char* actual_predicate_value, const char* expected_predicate_value) {\n  const char* actual_message = assertion_result.message();\n  Message msg;\n  msg << \"Value of: \" << expression_text\n      << \"\\n  Actual: \" << actual_predicate_value;\n  if (actual_message[0] != '\\0') msg << \" (\" << actual_message << \")\";\n  msg << \"\\nExpected: \" << expected_predicate_value;\n  return msg.GetString();\n}\n\n// Helper function for implementing ASSERT_NEAR.\nAssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2,\n                                     const char* abs_error_expr, double val1,\n                                     double val2, double abs_error) {\n  const double diff = fabs(val1 - val2);\n  if (diff <= abs_error) return AssertionSuccess();\n\n  // Find the value which is closest to zero.\n  const double min_abs = std::min(fabs(val1), fabs(val2));\n  // Find the distance to the next double from that value.\n  const double epsilon =\n      nextafter(min_abs, std::numeric_limits<double>::infinity()) - min_abs;\n  // Detect the case where abs_error is so small that EXPECT_NEAR is\n  // effectively the same as EXPECT_EQUAL, and give an informative error\n  // message so that the situation can be more easily understood without\n  // requiring exotic floating-point knowledge.\n  // Don't do an epsilon check if abs_error is zero because that implies\n  // that an equality check was actually intended.\n  if (!(std::isnan)(val1) && !(std::isnan)(val2) && abs_error > 0 &&\n      abs_error < epsilon) {\n    return AssertionFailure()\n           << \"The difference between \" << expr1 << \" and \" << expr2 << \" is \"\n           << diff << \", where\\n\"\n           << expr1 << \" evaluates to \" << val1 << \",\\n\"\n           << expr2 << \" evaluates to \" << val2 << \".\\nThe abs_error parameter \"\n           << abs_error_expr << \" evaluates to \" << abs_error\n           << \" which is smaller than the minimum distance between doubles for \"\n              \"numbers of this magnitude which is \"\n           << epsilon\n           << \", thus making this EXPECT_NEAR check equivalent to \"\n              \"EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead.\";\n  }\n  return AssertionFailure()\n         << \"The difference between \" << expr1 << \" and \" << expr2 << \" is \"\n         << diff << \", which exceeds \" << abs_error_expr << \", where\\n\"\n         << expr1 << \" evaluates to \" << val1 << \",\\n\"\n         << expr2 << \" evaluates to \" << val2 << \", and\\n\"\n         << abs_error_expr << \" evaluates to \" << abs_error << \".\";\n}\n\n// Helper template for implementing FloatLE() and DoubleLE().\ntemplate <typename RawType>\nAssertionResult FloatingPointLE(const char* expr1, const char* expr2,\n                                RawType val1, RawType val2) {\n  // Returns success if val1 is less than val2,\n  if (val1 < val2) {\n    return AssertionSuccess();\n  }\n\n  // or if val1 is almost equal to val2.\n  const FloatingPoint<RawType> lhs(val1), rhs(val2);\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  // Note that the above two checks will both fail if either val1 or\n  // val2 is NaN, as the IEEE floating-point standard requires that\n  // any predicate involving a NaN must return false.\n\n  ::std::stringstream val1_ss;\n  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val1;\n\n  ::std::stringstream val2_ss;\n  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val2;\n\n  return AssertionFailure()\n         << \"Expected: (\" << expr1 << \") <= (\" << expr2 << \")\\n\"\n         << \"  Actual: \" << StringStreamToString(&val1_ss) << \" vs \"\n         << StringStreamToString(&val2_ss);\n}\n\n}  // namespace internal\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult FloatLE(const char* expr1, const char* expr2, float val1,\n                        float val2) {\n  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);\n}\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult DoubleLE(const char* expr1, const char* expr2, double val1,\n                         double val2) {\n  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);\n}\n\nnamespace internal {\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\nAssertionResult CmpHelperSTREQ(const char* lhs_expression,\n                               const char* rhs_expression, const char* lhs,\n                               const char* rhs) {\n  if (String::CStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), false);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\nAssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression,\n                                   const char* rhs_expression, const char* lhs,\n                                   const char* rhs) {\n  if (String::CaseInsensitiveCStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), true);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression, const char* s1,\n                               const char* s2) {\n  if (!String::CStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure()\n           << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n           << \"), actual: \\\"\" << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\nAssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                   const char* s2_expression, const char* s1,\n                                   const char* s2) {\n  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure()\n           << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n           << \") (ignoring case), actual: \\\"\" << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n}  // namespace internal\n\nnamespace {\n\n// Helper functions for implementing IsSubString() and IsNotSubstring().\n\n// This group of overloaded functions return true if and only if needle\n// is a substring of haystack.  NULL is considered a substring of\n// itself only.\n\nbool IsSubstringPred(const char* needle, const char* haystack) {\n  if (needle == nullptr || haystack == nullptr) return needle == haystack;\n\n  return strstr(haystack, needle) != nullptr;\n}\n\nbool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {\n  if (needle == nullptr || haystack == nullptr) return needle == haystack;\n\n  return wcsstr(haystack, needle) != nullptr;\n}\n\n// StringType here can be either ::std::string or ::std::wstring.\ntemplate <typename StringType>\nbool IsSubstringPred(const StringType& needle, const StringType& haystack) {\n  return haystack.find(needle) != StringType::npos;\n}\n\n// This function implements either IsSubstring() or IsNotSubstring(),\n// depending on the value of the expected_to_be_substring parameter.\n// StringType here can be const char*, const wchar_t*, ::std::string,\n// or ::std::wstring.\ntemplate <typename StringType>\nAssertionResult IsSubstringImpl(bool expected_to_be_substring,\n                                const char* needle_expr,\n                                const char* haystack_expr,\n                                const StringType& needle,\n                                const StringType& haystack) {\n  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)\n    return AssertionSuccess();\n\n  const bool is_wide_string = sizeof(needle[0]) > 1;\n  const char* const begin_string_quote = is_wide_string ? \"L\\\"\" : \"\\\"\";\n  return AssertionFailure()\n         << \"Value of: \" << needle_expr << \"\\n\"\n         << \"  Actual: \" << begin_string_quote << needle << \"\\\"\\n\"\n         << \"Expected: \" << (expected_to_be_substring ? \"\" : \"not \")\n         << \"a substring of \" << haystack_expr << \"\\n\"\n         << \"Which is: \" << begin_string_quote << haystack << \"\\\"\";\n}\n\n}  // namespace\n\n// IsSubstring() and IsNotSubstring() check whether needle is a\n// substring of haystack (NULL is considered a substring of itself\n// only), and return an appropriate error message when they fail.\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const char* needle, const char* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const wchar_t* needle, const wchar_t* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr, const char* needle,\n                               const char* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr, const wchar_t* needle,\n                               const wchar_t* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const ::std::string& needle,\n                            const ::std::string& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr,\n                               const ::std::string& needle,\n                               const ::std::string& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\n#if GTEST_HAS_STD_WSTRING\nAssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,\n                            const ::std::wstring& needle,\n                            const ::std::wstring& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(const char* needle_expr,\n                               const char* haystack_expr,\n                               const ::std::wstring& needle,\n                               const ::std::wstring& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n#ifdef GTEST_OS_WINDOWS\n\nnamespace {\n\n// Helper function for IsHRESULT{SuccessFailure} predicates\nAssertionResult HRESULTFailureHelper(const char* expr, const char* expected,\n                                     long hr) {  // NOLINT\n#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_TV_TITLE)\n\n  // Windows CE doesn't support FormatMessage.\n  const char error_text[] = \"\";\n\n#else\n\n  // Looks up the human-readable system message for the HRESULT code\n  // and since we're not passing any params to FormatMessage, we don't\n  // want inserts expanded.\n  const DWORD kFlags =\n      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;\n  const DWORD kBufSize = 4096;\n  // Gets the system's human readable message string for this HRESULT.\n  char error_text[kBufSize] = {'\\0'};\n  DWORD message_length = ::FormatMessageA(kFlags,\n                                          0,  // no source, we're asking system\n                                          static_cast<DWORD>(hr),  // the error\n                                          0,  // no line width restrictions\n                                          error_text,  // output buffer\n                                          kBufSize,    // buf size\n                                          nullptr);  // no arguments for inserts\n  // Trims tailing white space (FormatMessage leaves a trailing CR-LF)\n  for (; message_length && IsSpace(error_text[message_length - 1]);\n       --message_length) {\n    error_text[message_length - 1] = '\\0';\n  }\n\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  const std::string error_hex(\"0x\" + String::FormatHexInt(hr));\n  return ::testing::AssertionFailure()\n         << \"Expected: \" << expr << \" \" << expected << \".\\n\"\n         << \"  Actual: \" << error_hex << \" \" << error_text << \"\\n\";\n}\n\n}  // namespace\n\nAssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT\n  if (SUCCEEDED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"succeeds\", hr);\n}\n\nAssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT\n  if (FAILED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"fails\", hr);\n}\n\n#endif  // GTEST_OS_WINDOWS\n\n// Utility functions for encoding Unicode text (wide strings) in\n// UTF-8.\n\n// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8\n// like this:\n//\n// Code-point length   Encoding\n//   0 -  7 bits       0xxxxxxx\n//   8 - 11 bits       110xxxxx 10xxxxxx\n//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx\n//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n\n// The maximum code-point a one-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1;\n\n// The maximum code-point a two-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1;\n\n// The maximum code-point a three-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint3 =\n    (static_cast<uint32_t>(1) << (4 + 2 * 6)) - 1;\n\n// The maximum code-point a four-byte UTF-8 sequence can represent.\nconstexpr uint32_t kMaxCodePoint4 =\n    (static_cast<uint32_t>(1) << (3 + 3 * 6)) - 1;\n\n// Chops off the n lowest bits from a bit pattern.  Returns the n\n// lowest bits.  As a side effect, the original bit pattern will be\n// shifted to the right by n bits.\ninline uint32_t ChopLowBits(uint32_t* bits, int n) {\n  const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1);\n  *bits >>= n;\n  return low_bits;\n}\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type uint32_t because wchar_t may not be\n// wide enough to contain a code point.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\nstd::string CodePointToUtf8(uint32_t code_point) {\n  if (code_point > kMaxCodePoint4) {\n    return \"(Invalid Unicode 0x\" + String::FormatHexUInt32(code_point) + \")\";\n  }\n\n  char str[5];  // Big enough for the largest valid code point.\n  if (code_point <= kMaxCodePoint1) {\n    str[1] = '\\0';\n    str[0] = static_cast<char>(code_point);  // 0xxxxxxx\n  } else if (code_point <= kMaxCodePoint2) {\n    str[2] = '\\0';\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx\n  } else if (code_point <= kMaxCodePoint3) {\n    str[3] = '\\0';\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx\n  } else {  // code_point <= kMaxCodePoint4\n    str[4] = '\\0';\n    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx\n  }\n  return str;\n}\n\n// The following two functions only make sense if the system\n// uses UTF-16 for wide string encoding. All supported systems\n// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16.\n\n// Determines if the arguments constitute UTF-16 surrogate pair\n// and thus should be combined into a single Unicode code point\n// using CreateCodePointFromUtf16SurrogatePair.\ninline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {\n  return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 &&\n         (second & 0xFC00) == 0xDC00;\n}\n\n// Creates a Unicode code point from UTF16 surrogate pair.\ninline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first,\n                                                      wchar_t second) {\n  const auto first_u = static_cast<uint32_t>(first);\n  const auto second_u = static_cast<uint32_t>(second);\n  const uint32_t mask = (1 << 10) - 1;\n  return (sizeof(wchar_t) == 2)\n             ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000\n             :\n             // This function should not be called when the condition is\n             // false, but we provide a sensible default in case it is.\n             first_u;\n}\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nstd::string WideStringToUtf8(const wchar_t* str, int num_chars) {\n  if (num_chars == -1) num_chars = static_cast<int>(wcslen(str));\n\n  ::std::stringstream stream;\n  for (int i = 0; i < num_chars; ++i) {\n    uint32_t unicode_code_point;\n\n    if (str[i] == L'\\0') {\n      break;\n    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {\n      unicode_code_point =\n          CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]);\n      i++;\n    } else {\n      unicode_code_point = static_cast<uint32_t>(str[i]);\n    }\n\n    stream << CodePointToUtf8(unicode_code_point);\n  }\n  return StringStreamToString(&stream);\n}\n\n// Converts a wide C string to an std::string using the UTF-8 encoding.\n// NULL will be converted to \"(null)\".\nstd::string String::ShowWideCString(const wchar_t* wide_c_str) {\n  if (wide_c_str == nullptr) return \"(null)\";\n\n  return internal::WideStringToUtf8(wide_c_str, -1);\n}\n\n// Compares two wide C strings.  Returns true if and only if they have the\n// same content.\n//\n// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n  return wcscmp(lhs, rhs) == 0;\n}\n\n// Helper function for *_STREQ on wide strings.\nAssertionResult CmpHelperSTREQ(const char* lhs_expression,\n                               const char* rhs_expression, const wchar_t* lhs,\n                               const wchar_t* rhs) {\n  if (String::WideCStringEquals(lhs, rhs)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs),\n                   PrintToString(rhs), false);\n}\n\n// Helper function for *_STRNE on wide strings.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression, const wchar_t* s1,\n                               const wchar_t* s2) {\n  if (!String::WideCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  }\n\n  return AssertionFailure()\n         << \"Expected: (\" << s1_expression << \") != (\" << s2_expression\n         << \"), actual: \" << PrintToString(s1) << \" vs \" << PrintToString(s2);\n}\n\n// Compares two C strings, ignoring case.  Returns true if and only if they have\n// the same content.\n//\n// Unlike strcasecmp(), this function can handle NULL argument(s).  A\n// NULL C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n  if (rhs == nullptr) return false;\n  return posix::StrCaseCmp(lhs, rhs) == 0;\n}\n\n// Compares two wide C strings, ignoring case.  Returns true if and only if they\n// have the same content.\n//\n// Unlike wcscasecmp(), this function can handle NULL argument(s).\n// A NULL C string is considered different to any non-NULL wide C string,\n// including the empty string.\n// NB: The implementations on different platforms slightly differ.\n// On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n// environment variable. On GNU platform this method uses wcscasecmp\n// which compares according to LC_CTYPE category of the current locale.\n// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n// current locale.\nbool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                              const wchar_t* rhs) {\n  if (lhs == nullptr) return rhs == nullptr;\n\n  if (rhs == nullptr) return false;\n\n#ifdef GTEST_OS_WINDOWS\n  return _wcsicmp(lhs, rhs) == 0;\n#elif defined(GTEST_OS_LINUX) && !defined(GTEST_OS_LINUX_ANDROID)\n  return wcscasecmp(lhs, rhs) == 0;\n#else\n  // Android, Mac OS X and Cygwin don't define wcscasecmp.\n  // Other unknown OSes may not define it either.\n  wint_t left, right;\n  do {\n    left = towlower(static_cast<wint_t>(*lhs++));\n    right = towlower(static_cast<wint_t>(*rhs++));\n  } while (left && left == right);\n  return left == right;\n#endif  // OS selector\n}\n\n// Returns true if and only if str ends with the given suffix, ignoring case.\n// Any string is considered to end with an empty suffix.\nbool String::EndsWithCaseInsensitive(const std::string& str,\n                                     const std::string& suffix) {\n  const size_t str_len = str.length();\n  const size_t suffix_len = suffix.length();\n  return (str_len >= suffix_len) &&\n         CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len,\n                                      suffix.c_str());\n}\n\n// Formats an int value as \"%02d\".\nstd::string String::FormatIntWidth2(int value) {\n  return FormatIntWidthN(value, 2);\n}\n\n// Formats an int value to given width with leading zeros.\nstd::string String::FormatIntWidthN(int value, int width) {\n  std::stringstream ss;\n  ss << std::setfill('0') << std::setw(width) << value;\n  return ss.str();\n}\n\n// Formats an int value as \"%X\".\nstd::string String::FormatHexUInt32(uint32_t value) {\n  std::stringstream ss;\n  ss << std::hex << std::uppercase << value;\n  return ss.str();\n}\n\n// Formats an int value as \"%X\".\nstd::string String::FormatHexInt(int value) {\n  return FormatHexUInt32(static_cast<uint32_t>(value));\n}\n\n// Formats a byte as \"%02X\".\nstd::string String::FormatByte(unsigned char value) {\n  std::stringstream ss;\n  ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase\n     << static_cast<unsigned int>(value);\n  return ss.str();\n}\n\n// Converts the buffer in a stringstream to an std::string, converting NUL\n// bytes to \"\\\\0\" along the way.\nstd::string StringStreamToString(::std::stringstream* ss) {\n  const ::std::string& str = ss->str();\n  const char* const start = str.c_str();\n  const char* const end = start + str.length();\n\n  std::string result;\n  result.reserve(static_cast<size_t>(2 * (end - start)));\n  for (const char* ch = start; ch != end; ++ch) {\n    if (*ch == '\\0') {\n      result += \"\\\\0\";  // Replaces NUL with \"\\\\0\";\n    } else {\n      result += *ch;\n    }\n  }\n\n  return result;\n}\n\n// Appends the user-supplied message to the Google-Test-generated message.\nstd::string AppendUserMessage(const std::string& gtest_msg,\n                              const Message& user_msg) {\n  // Appends the user message if it's non-empty.\n  const std::string user_msg_string = user_msg.GetString();\n  if (user_msg_string.empty()) {\n    return gtest_msg;\n  }\n  if (gtest_msg.empty()) {\n    return user_msg_string;\n  }\n  return gtest_msg + \"\\n\" + user_msg_string;\n}\n\n}  // namespace internal\n\n// class TestResult\n\n// Creates an empty TestResult.\nTestResult::TestResult()\n    : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}\n\n// D'tor.\nTestResult::~TestResult() = default;\n\n// Returns the i-th test part result among all the results. i can\n// range from 0 to total_part_count() - 1. If i is not in that range,\n// aborts the program.\nconst TestPartResult& TestResult::GetTestPartResult(int i) const {\n  if (i < 0 || i >= total_part_count()) internal::posix::Abort();\n  return test_part_results_.at(static_cast<size_t>(i));\n}\n\n// Returns the i-th test property. i can range from 0 to\n// test_property_count() - 1. If i is not in that range, aborts the\n// program.\nconst TestProperty& TestResult::GetTestProperty(int i) const {\n  if (i < 0 || i >= test_property_count()) internal::posix::Abort();\n  return test_properties_.at(static_cast<size_t>(i));\n}\n\n// Clears the test part results.\nvoid TestResult::ClearTestPartResults() { test_part_results_.clear(); }\n\n// Adds a test part result to the list.\nvoid TestResult::AddTestPartResult(const TestPartResult& test_part_result) {\n  test_part_results_.push_back(test_part_result);\n}\n\n// Adds a test property to the list. If a property with the same key as the\n// supplied property is already represented, the value of this test_property\n// replaces the old value for that key.\nvoid TestResult::RecordProperty(const std::string& xml_element,\n                                const TestProperty& test_property) {\n  if (!ValidateTestProperty(xml_element, test_property)) {\n    return;\n  }\n  internal::MutexLock lock(&test_properties_mutex_);\n  const std::vector<TestProperty>::iterator property_with_matching_key =\n      std::find_if(test_properties_.begin(), test_properties_.end(),\n                   internal::TestPropertyKeyIs(test_property.key()));\n  if (property_with_matching_key == test_properties_.end()) {\n    test_properties_.push_back(test_property);\n    return;\n  }\n  property_with_matching_key->SetValue(test_property.value());\n}\n\n// The list of reserved attributes used in the <testsuites> element of XML\n// output.\nstatic const char* const kReservedTestSuitesAttributes[] = {\n    \"disabled\",    \"errors\", \"failures\", \"name\",\n    \"random_seed\", \"tests\",  \"time\",     \"timestamp\"};\n\n// The list of reserved attributes used in the <testsuite> element of XML\n// output.\nstatic const char* const kReservedTestSuiteAttributes[] = {\n    \"disabled\", \"errors\", \"failures\",  \"name\",\n    \"tests\",    \"time\",   \"timestamp\", \"skipped\"};\n\n// The list of reserved attributes used in the <testcase> element of XML output.\nstatic const char* const kReservedTestCaseAttributes[] = {\n    \"classname\",  \"name\",        \"status\", \"time\",\n    \"type_param\", \"value_param\", \"file\",   \"line\"};\n\n// Use a slightly different set for allowed output to ensure existing tests can\n// still RecordProperty(\"result\") or RecordProperty(\"timestamp\")\nstatic const char* const kReservedOutputTestCaseAttributes[] = {\n    \"classname\",   \"name\", \"status\", \"time\",   \"type_param\",\n    \"value_param\", \"file\", \"line\",   \"result\", \"timestamp\"};\n\ntemplate <size_t kSize>\nstd::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {\n  return std::vector<std::string>(array, array + kSize);\n}\n\nstatic std::vector<std::string> GetReservedAttributesForElement(\n    const std::string& xml_element) {\n  if (xml_element == \"testsuites\") {\n    return ArrayAsVector(kReservedTestSuitesAttributes);\n  } else if (xml_element == \"testsuite\") {\n    return ArrayAsVector(kReservedTestSuiteAttributes);\n  } else if (xml_element == \"testcase\") {\n    return ArrayAsVector(kReservedTestCaseAttributes);\n  } else {\n    GTEST_CHECK_(false) << \"Unrecognized xml_element provided: \" << xml_element;\n  }\n  // This code is unreachable but some compilers may not realizes that.\n  return std::vector<std::string>();\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// TODO(jdesprez): Merge the two getReserved attributes once skip is improved\n// This function is only used when file systems are enabled.\nstatic std::vector<std::string> GetReservedOutputAttributesForElement(\n    const std::string& xml_element) {\n  if (xml_element == \"testsuites\") {\n    return ArrayAsVector(kReservedTestSuitesAttributes);\n  } else if (xml_element == \"testsuite\") {\n    return ArrayAsVector(kReservedTestSuiteAttributes);\n  } else if (xml_element == \"testcase\") {\n    return ArrayAsVector(kReservedOutputTestCaseAttributes);\n  } else {\n    GTEST_CHECK_(false) << \"Unrecognized xml_element provided: \" << xml_element;\n  }\n  // This code is unreachable but some compilers may not realizes that.\n  return std::vector<std::string>();\n}\n#endif\n\nstatic std::string FormatWordList(const std::vector<std::string>& words) {\n  Message word_list;\n  for (size_t i = 0; i < words.size(); ++i) {\n    if (i > 0 && words.size() > 2) {\n      word_list << \", \";\n    }\n    if (i == words.size() - 1) {\n      word_list << \"and \";\n    }\n    word_list << \"'\" << words[i] << \"'\";\n  }\n  return word_list.GetString();\n}\n\nstatic bool ValidateTestPropertyName(\n    const std::string& property_name,\n    const std::vector<std::string>& reserved_names) {\n  if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=\n      reserved_names.end()) {\n    ADD_FAILURE() << \"Reserved key used in RecordProperty(): \" << property_name\n                  << \" (\" << FormatWordList(reserved_names)\n                  << \" are reserved by \" << GTEST_NAME_ << \")\";\n    return false;\n  }\n  return true;\n}\n\n// Adds a failure if the key is a reserved attribute of the element named\n// xml_element.  Returns true if the property is valid.\nbool TestResult::ValidateTestProperty(const std::string& xml_element,\n                                      const TestProperty& test_property) {\n  return ValidateTestPropertyName(test_property.key(),\n                                  GetReservedAttributesForElement(xml_element));\n}\n\n// Clears the object.\nvoid TestResult::Clear() {\n  test_part_results_.clear();\n  test_properties_.clear();\n  death_test_count_ = 0;\n  elapsed_time_ = 0;\n}\n\n// Returns true off the test part was skipped.\nstatic bool TestPartSkipped(const TestPartResult& result) {\n  return result.skipped();\n}\n\n// Returns true if and only if the test was skipped.\nbool TestResult::Skipped() const {\n  return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0;\n}\n\n// Returns true if and only if the test failed.\nbool TestResult::Failed() const {\n  for (int i = 0; i < total_part_count(); ++i) {\n    if (GetTestPartResult(i).failed()) return true;\n  }\n  return false;\n}\n\n// Returns true if and only if the test part fatally failed.\nstatic bool TestPartFatallyFailed(const TestPartResult& result) {\n  return result.fatally_failed();\n}\n\n// Returns true if and only if the test fatally failed.\nbool TestResult::HasFatalFailure() const {\n  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;\n}\n\n// Returns true if and only if the test part non-fatally failed.\nstatic bool TestPartNonfatallyFailed(const TestPartResult& result) {\n  return result.nonfatally_failed();\n}\n\n// Returns true if and only if the test has a non-fatal failure.\nbool TestResult::HasNonfatalFailure() const {\n  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;\n}\n\n// Gets the number of all test parts.  This is the sum of the number\n// of successful test parts and the number of failed test parts.\nint TestResult::total_part_count() const {\n  return static_cast<int>(test_part_results_.size());\n}\n\n// Returns the number of the test properties.\nint TestResult::test_property_count() const {\n  return static_cast<int>(test_properties_.size());\n}\n\n// class Test\n\n// Creates a Test object.\n\n// The c'tor saves the states of all flags.\nTest::Test() : gtest_flag_saver_(new GTEST_FLAG_SAVER_) {}\n\n// The d'tor restores the states of all flags.  The actual work is\n// done by the d'tor of the gtest_flag_saver_ field, and thus not\n// visible here.\nTest::~Test() = default;\n\n// Sets up the test fixture.\n//\n// A sub-class may override this.\nvoid Test::SetUp() {}\n\n// Tears down the test fixture.\n//\n// A sub-class may override this.\nvoid Test::TearDown() {}\n\n// Allows user supplied key value pairs to be recorded for later output.\nvoid Test::RecordProperty(const std::string& key, const std::string& value) {\n  UnitTest::GetInstance()->RecordProperty(key, value);\n}\n\nnamespace internal {\n\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const std::string& message) {\n  // This function is a friend of UnitTest and as such has access to\n  // AddTestPartResult.\n  UnitTest::GetInstance()->AddTestPartResult(\n      result_type,\n      nullptr,  // No info about the source file where the exception occurred.\n      -1,       // We have no info on which line caused the exception.\n      message,\n      \"\");  // No stack trace, either.\n}\n\n}  // namespace internal\n\n// Google Test requires all tests in the same test suite to use the same test\n// fixture class.  This function checks if the current test has the\n// same fixture class as the first test in the current test suite.  If\n// yes, it returns true; otherwise it generates a Google Test failure and\n// returns false.\nbool Test::HasSameFixtureClass() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  const TestSuite* const test_suite = impl->current_test_suite();\n\n  // Info about the first test in the current test suite.\n  const TestInfo* const first_test_info = test_suite->test_info_list()[0];\n  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;\n  const char* const first_test_name = first_test_info->name();\n\n  // Info about the current test.\n  const TestInfo* const this_test_info = impl->current_test_info();\n  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;\n  const char* const this_test_name = this_test_info->name();\n\n  if (this_fixture_id != first_fixture_id) {\n    // Is the first test defined using TEST?\n    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();\n    // Is this test defined using TEST?\n    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();\n\n    if (first_is_TEST || this_is_TEST) {\n      // Both TEST and TEST_F appear in same test suite, which is incorrect.\n      // Tell the user how to fix this.\n\n      // Gets the name of the TEST and the name of the TEST_F.  Note\n      // that first_is_TEST and this_is_TEST cannot both be true, as\n      // the fixture IDs are different for the two tests.\n      const char* const TEST_name =\n          first_is_TEST ? first_test_name : this_test_name;\n      const char* const TEST_F_name =\n          first_is_TEST ? this_test_name : first_test_name;\n\n      ADD_FAILURE()\n          << \"All tests in the same test suite must use the same test fixture\\n\"\n          << \"class, so mixing TEST_F and TEST in the same test suite is\\n\"\n          << \"illegal.  In test suite \" << this_test_info->test_suite_name()\n          << \",\\n\"\n          << \"test \" << TEST_F_name << \" is defined using TEST_F but\\n\"\n          << \"test \" << TEST_name << \" is defined using TEST.  You probably\\n\"\n          << \"want to change the TEST to TEST_F or move it to another test\\n\"\n          << \"case.\";\n    } else {\n      // Two fixture classes with the same name appear in two different\n      // namespaces, which is not allowed. Tell the user how to fix this.\n      ADD_FAILURE()\n          << \"All tests in the same test suite must use the same test fixture\\n\"\n          << \"class.  However, in test suite \"\n          << this_test_info->test_suite_name() << \",\\n\"\n          << \"you defined test \" << first_test_name << \" and test \"\n          << this_test_name << \"\\n\"\n          << \"using two different test fixture classes.  This can happen if\\n\"\n          << \"the two classes are from different namespaces or translation\\n\"\n          << \"units and have the same name.  You should probably rename one\\n\"\n          << \"of the classes to put the tests into different test suites.\";\n    }\n    return false;\n  }\n\n  return true;\n}\n\nnamespace internal {\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Adds an \"exception thrown\" fatal failure to the current test.\nstatic std::string FormatCxxExceptionMessage(const char* description,\n                                             const char* location) {\n  Message message;\n  if (description != nullptr) {\n    message << \"C++ exception with description \\\"\" << description << \"\\\"\";\n  } else {\n    message << \"Unknown C++ exception\";\n  }\n  message << \" thrown in \" << location << \".\";\n\n  return message.GetString();\n}\n\nstatic std::string PrintTestPartResultToString(\n    const TestPartResult& test_part_result);\n\nGoogleTestFailureException::GoogleTestFailureException(\n    const TestPartResult& failure)\n    : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}\n\n#endif  // GTEST_HAS_EXCEPTIONS\n\n// We put these helper functions in the internal namespace as IBM's xlC\n// compiler rejects the code if they were declared static.\n\n// Runs the given method and handles SEH exceptions it throws, when\n// SEH is supported; returns the 0-value for type Result in case of an\n// SEH exception.  (Microsoft compilers cannot handle SEH and C++\n// exceptions in the same function.  Therefore, we provide a separate\n// wrapper function for handling SEH exceptions.)\ntemplate <class T, typename Result>\nResult HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(),\n                                              const char* location) {\n#if GTEST_HAS_SEH\n  __try {\n    return (object->*method)();\n  } __except (internal::UnitTestOptions::GTestProcessSEH(  // NOLINT\n      GetExceptionCode(), location)) {\n    return static_cast<Result>(0);\n  }\n#else\n  (void)location;\n  return (object->*method)();\n#endif  // GTEST_HAS_SEH\n}\n\n// Runs the given method and catches and reports C++ and/or SEH-style\n// exceptions, if they are supported; returns the 0-value for type\n// Result in case of an SEH exception.\ntemplate <class T, typename Result>\nResult HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(),\n                                           const char* location) {\n  // NOTE: The user code can affect the way in which Google Test handles\n  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before\n  // RUN_ALL_TESTS() starts. It is technically possible to check the flag\n  // after the exception is caught and either report or re-throw the\n  // exception based on the flag's value:\n  //\n  // try {\n  //   // Perform the test method.\n  // } catch (...) {\n  //   if (GTEST_FLAG_GET(catch_exceptions))\n  //     // Report the exception as failure.\n  //   else\n  //     throw;  // Re-throws the original exception.\n  // }\n  //\n  // However, the purpose of this flag is to allow the program to drop into\n  // the debugger when the exception is thrown. On most platforms, once the\n  // control enters the catch block, the exception origin information is\n  // lost and the debugger will stop the program at the point of the\n  // re-throw in this function -- instead of at the point of the original\n  // throw statement in the code under test.  For this reason, we perform\n  // the check early, sacrificing the ability to affect Google Test's\n  // exception handling in the method where the exception is thrown.\n  if (internal::GetUnitTestImpl()->catch_exceptions()) {\n#if GTEST_HAS_EXCEPTIONS\n    try {\n      return HandleSehExceptionsInMethodIfSupported(object, method, location);\n    } catch (const AssertionException&) {  // NOLINT\n      // This failure was reported already.\n    } catch (const internal::GoogleTestFailureException&) {  // NOLINT\n      // This exception type can only be thrown by a failed Google\n      // Test assertion with the intention of letting another testing\n      // framework catch it.  Therefore we just re-throw it.\n      throw;\n    } catch (const std::exception& e) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(e.what(), location));\n    } catch (...) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(nullptr, location));\n    }\n    return static_cast<Result>(0);\n#else\n    return HandleSehExceptionsInMethodIfSupported(object, method, location);\n#endif  // GTEST_HAS_EXCEPTIONS\n  } else {\n    return (object->*method)();\n  }\n}\n\n}  // namespace internal\n\n// Runs the test and updates the test result.\nvoid Test::Run() {\n  if (!HasSameFixtureClass()) return;\n\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, \"SetUp()\");\n  // We will run the test only if SetUp() was successful and didn't call\n  // GTEST_SKIP().\n  if (!HasFatalFailure() && !IsSkipped()) {\n    impl->os_stack_trace_getter()->UponLeavingGTest();\n    internal::HandleExceptionsInMethodIfSupported(this, &Test::TestBody,\n                                                  \"the test body\");\n  }\n\n  // However, we want to clean up as much as possible.  Hence we will\n  // always call TearDown(), even if SetUp() or the test body has\n  // failed.\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::TearDown,\n                                                \"TearDown()\");\n}\n\n// Returns true if and only if the current test has a fatal failure.\nbool Test::HasFatalFailure() {\n  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();\n}\n\n// Returns true if and only if the current test has a non-fatal failure.\nbool Test::HasNonfatalFailure() {\n  return internal::GetUnitTestImpl()\n      ->current_test_result()\n      ->HasNonfatalFailure();\n}\n\n// Returns true if and only if the current test was skipped.\nbool Test::IsSkipped() {\n  return internal::GetUnitTestImpl()->current_test_result()->Skipped();\n}\n\n// class TestInfo\n\n// Constructs a TestInfo object. It assumes ownership of the test factory\n// object.\nTestInfo::TestInfo(std::string a_test_suite_name, std::string a_name,\n                   const char* a_type_param, const char* a_value_param,\n                   internal::CodeLocation a_code_location,\n                   internal::TypeId fixture_class_id,\n                   internal::TestFactoryBase* factory)\n    : test_suite_name_(std::move(a_test_suite_name)),\n      name_(std::move(a_name)),\n      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),\n      value_param_(a_value_param ? new std::string(a_value_param) : nullptr),\n      location_(std::move(a_code_location)),\n      fixture_class_id_(fixture_class_id),\n      should_run_(false),\n      is_disabled_(false),\n      matches_filter_(false),\n      is_in_another_shard_(false),\n      factory_(factory),\n      result_() {}\n\n// Destructs a TestInfo object.\nTestInfo::~TestInfo() { delete factory_; }\n\nnamespace internal {\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_suite_name:  name of the test suite\n//   name:             name of the test\n//   type_param:       the name of the test's type parameter, or NULL if\n//                     this is not a typed or a type-parameterized test.\n//   value_param:      text representation of the test's value parameter,\n//                     or NULL if this is not a value-parameterized test.\n//   code_location:    code location where the test is defined\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test suite\n//   tear_down_tc:     pointer to the function that tears down the test suite\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nTestInfo* MakeAndRegisterTestInfo(\n    std::string test_suite_name, const char* name, const char* type_param,\n    const char* value_param, CodeLocation code_location,\n    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,\n    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {\n  TestInfo* const test_info =\n      new TestInfo(std::move(test_suite_name), name, type_param, value_param,\n                   std::move(code_location), fixture_class_id, factory);\n  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);\n  return test_info;\n}\n\nvoid ReportInvalidTestSuiteType(const char* test_suite_name,\n                                const CodeLocation& code_location) {\n  Message errors;\n  errors\n      << \"Attempted redefinition of test suite \" << test_suite_name << \".\\n\"\n      << \"All tests in the same test suite must use the same test fixture\\n\"\n      << \"class.  However, in test suite \" << test_suite_name << \", you tried\\n\"\n      << \"to define a test using a fixture class different from the one\\n\"\n      << \"used earlier. This can happen if the two fixture classes are\\n\"\n      << \"from different namespaces and have the same name. You should\\n\"\n      << \"probably rename one of the classes to put the tests into different\\n\"\n      << \"test suites.\";\n\n  GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),\n                                          code_location.line)\n                    << \" \" << errors.GetString();\n}\n\n// This method expands all parameterized tests registered with macros TEST_P\n// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.\n// This will be done just once during the program runtime.\nvoid UnitTestImpl::RegisterParameterizedTests() {\n  if (!parameterized_tests_registered_) {\n    parameterized_test_registry_.RegisterTests();\n    type_parameterized_test_registry_.CheckForInstantiations();\n    parameterized_tests_registered_ = true;\n  }\n}\n\n}  // namespace internal\n\n// Creates the test object, runs it, records its result, and then\n// deletes it.\nvoid TestInfo::Run() {\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n  if (!should_run_) {\n    if (is_disabled_ && matches_filter_) repeater->OnTestDisabled(*this);\n    return;\n  }\n\n  // Tells UnitTest where to store test result.\n  UnitTest::GetInstance()->set_current_test_info(this);\n\n  // Notifies the unit test event listeners that a test is about to start.\n  repeater->OnTestStart(*this);\n  result_.set_start_timestamp(internal::GetTimeInMillis());\n  internal::Timer timer;\n  UnitTest::GetInstance()->UponLeavingGTest();\n\n  // Creates the test object.\n  Test* const test = internal::HandleExceptionsInMethodIfSupported(\n      factory_, &internal::TestFactoryBase::CreateTest,\n      \"the test fixture's constructor\");\n\n  // Runs the test if the constructor didn't generate a fatal failure or invoke\n  // GTEST_SKIP().\n  // Note that the object will not be null\n  if (!Test::HasFatalFailure() && !Test::IsSkipped()) {\n    // This doesn't throw as all user code that can throw are wrapped into\n    // exception handling code.\n    test->Run();\n  }\n\n  if (test != nullptr) {\n    // Deletes the test object.\n    UnitTest::GetInstance()->UponLeavingGTest();\n    internal::HandleExceptionsInMethodIfSupported(\n        test, &Test::DeleteSelf_, \"the test fixture's destructor\");\n  }\n\n  result_.set_elapsed_time(timer.Elapsed());\n\n  // Notifies the unit test event listener that a test has just finished.\n  repeater->OnTestEnd(*this);\n\n  // Tells UnitTest to stop associating assertion results to this\n  // test.\n  UnitTest::GetInstance()->set_current_test_info(nullptr);\n}\n\n// Skip and records a skipped test result for this object.\nvoid TestInfo::Skip() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_info(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Notifies the unit test event listeners that a test is about to start.\n  repeater->OnTestStart(*this);\n\n  const TestPartResult test_part_result =\n      TestPartResult(TestPartResult::kSkip, this->file(), this->line(), \"\");\n  internal::GetUnitTestImpl()\n      ->GetTestPartResultReporterForCurrentThread()\n      ->ReportTestPartResult(test_part_result);\n\n  // Notifies the unit test event listener that a test has just finished.\n  repeater->OnTestEnd(*this);\n  UnitTest::GetInstance()->set_current_test_info(nullptr);\n}\n\n// class TestSuite\n\n// Gets the number of successful tests in this test suite.\nint TestSuite::successful_test_count() const {\n  return CountIf(test_info_list_, TestPassed);\n}\n\n// Gets the number of successful tests in this test suite.\nint TestSuite::skipped_test_count() const {\n  return CountIf(test_info_list_, TestSkipped);\n}\n\n// Gets the number of failed tests in this test suite.\nint TestSuite::failed_test_count() const {\n  return CountIf(test_info_list_, TestFailed);\n}\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint TestSuite::reportable_disabled_test_count() const {\n  return CountIf(test_info_list_, TestReportableDisabled);\n}\n\n// Gets the number of disabled tests in this test suite.\nint TestSuite::disabled_test_count() const {\n  return CountIf(test_info_list_, TestDisabled);\n}\n\n// Gets the number of tests to be printed in the XML report.\nint TestSuite::reportable_test_count() const {\n  return CountIf(test_info_list_, TestReportable);\n}\n\n// Get the number of tests in this test suite that should run.\nint TestSuite::test_to_run_count() const {\n  return CountIf(test_info_list_, ShouldRunTest);\n}\n\n// Gets the number of all tests.\nint TestSuite::total_test_count() const {\n  return static_cast<int>(test_info_list_.size());\n}\n\n// Creates a TestSuite with the given name.\n//\n// Arguments:\n//\n//   a_name:       name of the test suite\n//   a_type_param: the name of the test suite's type parameter, or NULL if\n//                 this is not a typed or a type-parameterized test suite.\n//   set_up_tc:    pointer to the function that sets up the test suite\n//   tear_down_tc: pointer to the function that tears down the test suite\nTestSuite::TestSuite(const std::string& a_name, const char* a_type_param,\n                     internal::SetUpTestSuiteFunc set_up_tc,\n                     internal::TearDownTestSuiteFunc tear_down_tc)\n    : name_(a_name),\n      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),\n      set_up_tc_(set_up_tc),\n      tear_down_tc_(tear_down_tc),\n      should_run_(false),\n      start_timestamp_(0),\n      elapsed_time_(0) {}\n\n// Destructor of TestSuite.\nTestSuite::~TestSuite() {\n  // Deletes every Test in the collection.\n  ForEach(test_info_list_, internal::Delete<TestInfo>);\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nconst TestInfo* TestSuite::GetTestInfo(int i) const {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nTestInfo* TestSuite::GetMutableTestInfo(int i) {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];\n}\n\n// Adds a test to this test suite.  Will delete the test upon\n// destruction of the TestSuite object.\nvoid TestSuite::AddTestInfo(TestInfo* test_info) {\n  test_info_list_.push_back(test_info);\n  test_indices_.push_back(static_cast<int>(test_indices_.size()));\n}\n\n// Runs every test in this TestSuite.\nvoid TestSuite::Run() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_suite(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Ensure our tests are in a deterministic order.\n  //\n  // We do this by sorting lexicographically on (file, line number), providing\n  // an order matching what the user can see in the source code.\n  //\n  // In the common case the line number comparison shouldn't be necessary,\n  // because the registrations made by the TEST macro are executed in order\n  // within a translation unit. But this is not true of the manual registration\n  // API, and in more exotic scenarios a single file may be part of multiple\n  // translation units.\n  std::stable_sort(test_info_list_.begin(), test_info_list_.end(),\n                   [](const TestInfo* const a, const TestInfo* const b) {\n                     if (const int result = std::strcmp(a->file(), b->file())) {\n                       return result < 0;\n                     }\n\n                     return a->line() < b->line();\n                   });\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteStart(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseStart(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestSuite::RunSetUpTestSuite, \"SetUpTestSuite()\");\n\n  const bool skip_all =\n      ad_hoc_test_result().Failed() || ad_hoc_test_result().Skipped();\n\n  start_timestamp_ = internal::GetTimeInMillis();\n  internal::Timer timer;\n  for (int i = 0; i < total_test_count(); i++) {\n    if (skip_all) {\n      GetMutableTestInfo(i)->Skip();\n    } else {\n      GetMutableTestInfo(i)->Run();\n    }\n    if (GTEST_FLAG_GET(fail_fast) &&\n        GetMutableTestInfo(i)->result()->Failed()) {\n      for (int j = i + 1; j < total_test_count(); j++) {\n        GetMutableTestInfo(j)->Skip();\n      }\n      break;\n    }\n  }\n  elapsed_time_ = timer.Elapsed();\n\n  UnitTest::GetInstance()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestSuite::RunTearDownTestSuite, \"TearDownTestSuite()\");\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteEnd(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseEnd(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->set_current_test_suite(nullptr);\n}\n\n// Skips all tests under this TestSuite.\nvoid TestSuite::Skip() {\n  if (!should_run_) return;\n\n  UnitTest::GetInstance()->set_current_test_suite(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteStart(*this);\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseStart(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  for (int i = 0; i < total_test_count(); i++) {\n    GetMutableTestInfo(i)->Skip();\n  }\n\n  // Call both legacy and the new API\n  repeater->OnTestSuiteEnd(*this);\n  // Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  repeater->OnTestCaseEnd(*this);\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  UnitTest::GetInstance()->set_current_test_suite(nullptr);\n}\n\n// Clears the results of all tests in this test suite.\nvoid TestSuite::ClearResult() {\n  ad_hoc_test_result_.Clear();\n  ForEach(test_info_list_, TestInfo::ClearTestResult);\n}\n\n// Shuffles the tests in this test suite.\nvoid TestSuite::ShuffleTests(internal::Random* random) {\n  Shuffle(random, &test_indices_);\n}\n\n// Restores the test order to before the first shuffle.\nvoid TestSuite::UnshuffleTests() {\n  for (size_t i = 0; i < test_indices_.size(); i++) {\n    test_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Formats a countable noun.  Depending on its quantity, either the\n// singular form or the plural form is used. e.g.\n//\n// FormatCountableNoun(1, \"formula\", \"formuli\") returns \"1 formula\".\n// FormatCountableNoun(5, \"book\", \"books\") returns \"5 books\".\nstatic std::string FormatCountableNoun(int count, const char* singular_form,\n                                       const char* plural_form) {\n  return internal::StreamableToString(count) + \" \" +\n         (count == 1 ? singular_form : plural_form);\n}\n\n// Formats the count of tests.\nstatic std::string FormatTestCount(int test_count) {\n  return FormatCountableNoun(test_count, \"test\", \"tests\");\n}\n\n// Formats the count of test suites.\nstatic std::string FormatTestSuiteCount(int test_suite_count) {\n  return FormatCountableNoun(test_suite_count, \"test suite\", \"test suites\");\n}\n\n// Converts a TestPartResult::Type enum to human-friendly string\n// representation.  Both kNonFatalFailure and kFatalFailure are translated\n// to \"Failure\", as the user usually doesn't care about the difference\n// between the two when viewing the test result.\nstatic const char* TestPartResultTypeToString(TestPartResult::Type type) {\n  switch (type) {\n    case TestPartResult::kSkip:\n      return \"Skipped\\n\";\n    case TestPartResult::kSuccess:\n      return \"Success\";\n\n    case TestPartResult::kNonFatalFailure:\n    case TestPartResult::kFatalFailure:\n#ifdef _MSC_VER\n      return \"error: \";\n#else\n      return \"Failure\\n\";\n#endif\n    default:\n      return \"Unknown result type\";\n  }\n}\n\nnamespace internal {\nnamespace {\nenum class GTestColor { kDefault, kRed, kGreen, kYellow };\n}  // namespace\n\n// Prints a TestPartResult to an std::string.\nstatic std::string PrintTestPartResultToString(\n    const TestPartResult& test_part_result) {\n  return (Message() << internal::FormatFileLocation(\n                           test_part_result.file_name(),\n                           test_part_result.line_number())\n                    << \" \"\n                    << TestPartResultTypeToString(test_part_result.type())\n                    << test_part_result.message())\n      .GetString();\n}\n\n// Prints a TestPartResult.\nstatic void PrintTestPartResult(const TestPartResult& test_part_result) {\n  const std::string& result = PrintTestPartResultToString(test_part_result);\n  printf(\"%s\\n\", result.c_str());\n  fflush(stdout);\n  // If the test program runs in Visual Studio or a debugger, the\n  // following statements add the test part result message to the Output\n  // window such that the user can double-click on it to jump to the\n  // corresponding source code location; otherwise they do nothing.\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE)\n  // We don't call OutputDebugString*() on Windows Mobile, as printing\n  // to stdout is done by OutputDebugString() there already - we don't\n  // want the same message printed twice.\n  ::OutputDebugStringA(result.c_str());\n  ::OutputDebugStringA(\"\\n\");\n#endif\n}\n\n// class PrettyUnitTestResultPrinter\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) &&       \\\n    !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)\n\n// Returns the character attribute for the given color.\nstatic WORD GetColorAttribute(GTestColor color) {\n  switch (color) {\n    case GTestColor::kRed:\n      return FOREGROUND_RED;\n    case GTestColor::kGreen:\n      return FOREGROUND_GREEN;\n    case GTestColor::kYellow:\n      return FOREGROUND_RED | FOREGROUND_GREEN;\n    default:\n      return 0;\n  }\n}\n\nstatic int GetBitOffset(WORD color_mask) {\n  if (color_mask == 0) return 0;\n\n  int bitOffset = 0;\n  while ((color_mask & 1) == 0) {\n    color_mask >>= 1;\n    ++bitOffset;\n  }\n  return bitOffset;\n}\n\nstatic WORD GetNewColor(GTestColor color, WORD old_color_attrs) {\n  // Let's reuse the BG\n  static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |\n                                      BACKGROUND_RED | BACKGROUND_INTENSITY;\n  static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |\n                                      FOREGROUND_RED | FOREGROUND_INTENSITY;\n  const WORD existing_bg = old_color_attrs & background_mask;\n\n  WORD new_color =\n      GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;\n  static const int bg_bitOffset = GetBitOffset(background_mask);\n  static const int fg_bitOffset = GetBitOffset(foreground_mask);\n\n  if (((new_color & background_mask) >> bg_bitOffset) ==\n      ((new_color & foreground_mask) >> fg_bitOffset)) {\n    new_color ^= FOREGROUND_INTENSITY;  // invert intensity\n  }\n  return new_color;\n}\n\n#else\n\n// Returns the ANSI color code for the given color. GTestColor::kDefault is\n// an invalid input.\nstatic const char* GetAnsiColorCode(GTestColor color) {\n  switch (color) {\n    case GTestColor::kRed:\n      return \"1\";\n    case GTestColor::kGreen:\n      return \"2\";\n    case GTestColor::kYellow:\n      return \"3\";\n    default:\n      assert(false);\n      return \"9\";\n  }\n}\n\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n\n// Returns true if and only if Google Test should use colors in the output.\nbool ShouldUseColor(bool stdout_is_tty) {\n  std::string c = GTEST_FLAG_GET(color);\n  const char* const gtest_color = c.c_str();\n\n  if (String::CaseInsensitiveCStringEquals(gtest_color, \"auto\")) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW)\n    // On Windows the TERM variable is usually not set, but the\n    // console there does support colors.\n    return stdout_is_tty;\n#else\n    // On non-Windows platforms, we rely on the TERM variable.\n    const char* const term = posix::GetEnv(\"TERM\");\n    const bool term_supports_color =\n        term != nullptr && (String::CStringEquals(term, \"xterm\") ||\n                            String::CStringEquals(term, \"xterm-color\") ||\n                            String::CStringEquals(term, \"xterm-kitty\") ||\n                            String::CStringEquals(term, \"alacritty\") ||\n                            String::CStringEquals(term, \"screen\") ||\n                            String::CStringEquals(term, \"tmux\") ||\n                            String::CStringEquals(term, \"rxvt-unicode\") ||\n                            String::CStringEquals(term, \"linux\") ||\n                            String::CStringEquals(term, \"cygwin\") ||\n                            String::EndsWithCaseInsensitive(term, \"-256color\"));\n    return stdout_is_tty && term_supports_color;\n#endif  // GTEST_OS_WINDOWS\n  }\n\n  return String::CaseInsensitiveCStringEquals(gtest_color, \"yes\") ||\n         String::CaseInsensitiveCStringEquals(gtest_color, \"true\") ||\n         String::CaseInsensitiveCStringEquals(gtest_color, \"t\") ||\n         String::CStringEquals(gtest_color, \"1\");\n  // We take \"yes\", \"true\", \"t\", and \"1\" as meaning \"yes\".  If the\n  // value is neither one of these nor \"auto\", we treat it as \"no\" to\n  // be conservative.\n}\n\n// Helpers for printing colored strings to stdout. Note that on Windows, we\n// cannot simply emit special characters and have the terminal change colors.\n// This routine must actually emit the characters rather than return a string\n// that would be colored when printed, as can be done on Linux.\n\nGTEST_ATTRIBUTE_PRINTF_(2, 3)\nstatic void ColoredPrintf(GTestColor color, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n\n  static const bool in_color_mode =\n      // We don't condition this on GTEST_HAS_FILE_SYSTEM because we still need\n      // to be able to detect terminal I/O regardless.\n      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);\n\n  const bool use_color = in_color_mode && (color != GTestColor::kDefault);\n\n  if (!use_color) {\n    vprintf(fmt, args);\n    va_end(args);\n    return;\n  }\n\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) &&       \\\n    !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW)\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\n\n  // Gets the current text color.\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\n  const WORD old_color_attrs = buffer_info.wAttributes;\n  const WORD new_color = GetNewColor(color, old_color_attrs);\n\n  // We need to flush the stream buffers into the console before each\n  // SetConsoleTextAttribute call lest it affect the text that is already\n  // printed but has not yet reached the console.\n  fflush(stdout);\n  SetConsoleTextAttribute(stdout_handle, new_color);\n\n  vprintf(fmt, args);\n\n  fflush(stdout);\n  // Restores the text color.\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\n#else\n  printf(\"\\033[0;3%sm\", GetAnsiColorCode(color));\n  vprintf(fmt, args);\n  printf(\"\\033[m\");  // Resets the terminal to default.\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n  va_end(args);\n}\n\n// Text printed in Google Test's text output and --gtest_list_tests\n// output to label the type parameter and value parameter for a test.\nstatic const char kTypeParamLabel[] = \"TypeParam\";\nstatic const char kValueParamLabel[] = \"GetParam()\";\n\nstatic void PrintFullTestCommentIfPresent(const TestInfo& test_info) {\n  const char* const type_param = test_info.type_param();\n  const char* const value_param = test_info.value_param();\n\n  if (type_param != nullptr || value_param != nullptr) {\n    printf(\", where \");\n    if (type_param != nullptr) {\n      printf(\"%s = %s\", kTypeParamLabel, type_param);\n      if (value_param != nullptr) printf(\" and \");\n    }\n    if (value_param != nullptr) {\n      printf(\"%s = %s\", kValueParamLabel, value_param);\n    }\n  }\n}\n\n// This class implements the TestEventListener interface.\n//\n// Class PrettyUnitTestResultPrinter is copyable.\nclass PrettyUnitTestResultPrinter : public TestEventListener {\n public:\n  PrettyUnitTestResultPrinter() = default;\n  static void PrintTestName(const char* test_suite, const char* test) {\n    printf(\"%s.%s\", test_suite, test);\n  }\n\n  // The following methods override what's in the TestEventListener class.\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;\n  void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& test_case) override;\n#else\n  void OnTestSuiteStart(const TestSuite& test_suite) override;\n#endif  // OnTestCaseStart\n\n  void OnTestStart(const TestInfo& test_info) override;\n  void OnTestDisabled(const TestInfo& test_info) override;\n\n  void OnTestPartResult(const TestPartResult& result) override;\n  void OnTestEnd(const TestInfo& test_info) override;\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& test_case) override;\n#else\n  void OnTestSuiteEnd(const TestSuite& test_suite) override;\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n\n private:\n  static void PrintFailedTests(const UnitTest& unit_test);\n  static void PrintFailedTestSuites(const UnitTest& unit_test);\n  static void PrintSkippedTests(const UnitTest& unit_test);\n};\n\n// Fired before each iteration of tests starts.\nvoid PrettyUnitTestResultPrinter::OnTestIterationStart(\n    const UnitTest& unit_test, int iteration) {\n  if (GTEST_FLAG_GET(repeat) != 1)\n    printf(\"\\nRepeating all tests (iteration %d) . . .\\n\\n\", iteration + 1);\n\n  std::string f = GTEST_FLAG_GET(filter);\n  const char* const filter = f.c_str();\n\n  // Prints the filter if it's not *.  This reminds the user that some\n  // tests may be skipped.\n  if (!String::CStringEquals(filter, kUniversalFilter)) {\n    ColoredPrintf(GTestColor::kYellow, \"Note: %s filter = %s\\n\", GTEST_NAME_,\n                  filter);\n  }\n\n  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {\n    const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);\n    ColoredPrintf(GTestColor::kYellow, \"Note: This is test shard %d of %s.\\n\",\n                  static_cast<int>(shard_index) + 1,\n                  internal::posix::GetEnv(kTestTotalShards));\n  }\n\n  if (GTEST_FLAG_GET(shuffle)) {\n    ColoredPrintf(GTestColor::kYellow,\n                  \"Note: Randomizing tests' orders with a seed of %d .\\n\",\n                  unit_test.random_seed());\n  }\n\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"Running %s from %s.\\n\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"Global test environment set-up.\\n\");\n  fflush(stdout);\n}\n\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nvoid PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {\n  const std::string counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s\", counts.c_str(), test_case.name());\n  if (test_case.type_param() == nullptr) {\n    printf(\"\\n\");\n  } else {\n    printf(\", where %s = %s\\n\", kTypeParamLabel, test_case.type_param());\n  }\n  fflush(stdout);\n}\n#else\nvoid PrettyUnitTestResultPrinter::OnTestSuiteStart(\n    const TestSuite& test_suite) {\n  const std::string counts =\n      FormatCountableNoun(test_suite.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s\", counts.c_str(), test_suite.name());\n  if (test_suite.type_param() == nullptr) {\n    printf(\"\\n\");\n  } else {\n    printf(\", where %s = %s\\n\", kTypeParamLabel, test_suite.type_param());\n  }\n  fflush(stdout);\n}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nvoid PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {\n  ColoredPrintf(GTestColor::kGreen, \"[ RUN      ] \");\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  printf(\"\\n\");\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) {\n  ColoredPrintf(GTestColor::kYellow, \"[ DISABLED ] \");\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  printf(\"\\n\");\n  fflush(stdout);\n}\n\n// Called after an assertion failure.\nvoid PrettyUnitTestResultPrinter::OnTestPartResult(\n    const TestPartResult& result) {\n  switch (result.type()) {\n    // If the test part succeeded, we don't need to do anything.\n    case TestPartResult::kSuccess:\n      return;\n    default:\n      // Print failure message from the assertion\n      // (e.g. expected this and got that).\n      PrintTestPartResult(result);\n      fflush(stdout);\n  }\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\n  if (test_info.result()->Passed()) {\n    ColoredPrintf(GTestColor::kGreen, \"[       OK ] \");\n  } else if (test_info.result()->Skipped()) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n  } else {\n    ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n  }\n  PrintTestName(test_info.test_suite_name(), test_info.name());\n  if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info);\n\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms)\\n\",\n           internal::StreamableToString(test_info.result()->elapsed_time())\n               .c_str());\n  } else {\n    printf(\"\\n\");\n  }\n  fflush(stdout);\n}\n\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nvoid PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {\n  if (!GTEST_FLAG_GET(print_time)) return;\n\n  const std::string counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s (%s ms total)\\n\\n\", counts.c_str(), test_case.name(),\n         internal::StreamableToString(test_case.elapsed_time()).c_str());\n  fflush(stdout);\n}\n#else\nvoid PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {\n  if (!GTEST_FLAG_GET(print_time)) return;\n\n  const std::string counts =\n      FormatCountableNoun(test_suite.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"%s from %s (%s ms total)\\n\\n\", counts.c_str(), test_suite.name(),\n         internal::StreamableToString(test_suite.elapsed_time()).c_str());\n  fflush(stdout);\n}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[----------] \");\n  printf(\"Global test environment tear-down\\n\");\n  fflush(stdout);\n}\n\n// Internal helper for printing the list of failed tests.\nvoid PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {\n  const int failed_test_count = unit_test.failed_test_count();\n  ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n  printf(\"%s, listed below:\\n\", FormatTestCount(failed_test_count).c_str());\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) {\n      continue;\n    }\n    for (int j = 0; j < test_suite.total_test_count(); ++j) {\n      const TestInfo& test_info = *test_suite.GetTestInfo(j);\n      if (!test_info.should_run() || !test_info.result()->Failed()) {\n        continue;\n      }\n      ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n      printf(\"%s.%s\", test_suite.name(), test_info.name());\n      PrintFullTestCommentIfPresent(test_info);\n      printf(\"\\n\");\n    }\n  }\n  printf(\"\\n%2d FAILED %s\\n\", failed_test_count,\n         failed_test_count == 1 ? \"TEST\" : \"TESTS\");\n}\n\n// Internal helper for printing the list of test suite failures not covered by\n// PrintFailedTests.\nvoid PrettyUnitTestResultPrinter::PrintFailedTestSuites(\n    const UnitTest& unit_test) {\n  int suite_failure_count = 0;\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run()) {\n      continue;\n    }\n    if (test_suite.ad_hoc_test_result().Failed()) {\n      ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n      printf(\"%s: SetUpTestSuite or TearDownTestSuite\\n\", test_suite.name());\n      ++suite_failure_count;\n    }\n  }\n  if (suite_failure_count > 0) {\n    printf(\"\\n%2d FAILED TEST %s\\n\", suite_failure_count,\n           suite_failure_count == 1 ? \"SUITE\" : \"SUITES\");\n  }\n}\n\n// Internal helper for printing the list of skipped tests.\nvoid PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count == 0) {\n    return;\n  }\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    const TestSuite& test_suite = *unit_test.GetTestSuite(i);\n    if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) {\n      continue;\n    }\n    for (int j = 0; j < test_suite.total_test_count(); ++j) {\n      const TestInfo& test_info = *test_suite.GetTestInfo(j);\n      if (!test_info.should_run() || !test_info.result()->Skipped()) {\n        continue;\n      }\n      ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n      printf(\"%s.%s\", test_suite.name(), test_info.name());\n      printf(\"\\n\");\n    }\n  }\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                     int /*iteration*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"%s from %s ran.\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms total)\",\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\n  }\n  printf(\"\\n\");\n  ColoredPrintf(GTestColor::kGreen, \"[  PASSED  ] \");\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\n\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count > 0) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n    printf(\"%s, listed below:\\n\", FormatTestCount(skipped_test_count).c_str());\n    PrintSkippedTests(unit_test);\n  }\n\n  if (!unit_test.Passed()) {\n    PrintFailedTests(unit_test);\n    PrintFailedTestSuites(unit_test);\n  }\n\n  int num_disabled = unit_test.reportable_disabled_test_count();\n  if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {\n    if (unit_test.Passed()) {\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\n    }\n    ColoredPrintf(GTestColor::kYellow, \"  YOU HAVE %d DISABLED %s\\n\\n\",\n                  num_disabled, num_disabled == 1 ? \"TEST\" : \"TESTS\");\n  }\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\n  fflush(stdout);\n}\n\n// End PrettyUnitTestResultPrinter\n\n// This class implements the TestEventListener interface.\n//\n// Class BriefUnitTestResultPrinter is copyable.\nclass BriefUnitTestResultPrinter : public TestEventListener {\n public:\n  BriefUnitTestResultPrinter() = default;\n  static void PrintTestName(const char* test_suite, const char* test) {\n    printf(\"%s.%s\", test_suite, test);\n  }\n\n  // The following methods override what's in the TestEventListener class.\n  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationStart(const UnitTest& /*unit_test*/,\n                            int /*iteration*/) override {}\n  void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestCase& /*test_case*/) override {}\n#else\n  void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}\n#endif  // OnTestCaseStart\n\n  void OnTestStart(const TestInfo& /*test_info*/) override {}\n  void OnTestDisabled(const TestInfo& /*test_info*/) override {}\n\n  void OnTestPartResult(const TestPartResult& result) override;\n  void OnTestEnd(const TestInfo& test_info) override;\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& /*test_case*/) override {}\n#else\n  void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}\n#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n  void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}\n  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}\n};\n\n// Called after an assertion failure.\nvoid BriefUnitTestResultPrinter::OnTestPartResult(\n    const TestPartResult& result) {\n  switch (result.type()) {\n    // If the test part succeeded, we don't need to do anything.\n    case TestPartResult::kSuccess:\n      return;\n    default:\n      // Print failure message from the assertion\n      // (e.g. expected this and got that).\n      PrintTestPartResult(result);\n      fflush(stdout);\n  }\n}\n\nvoid BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\n  if (test_info.result()->Failed()) {\n    ColoredPrintf(GTestColor::kRed, \"[  FAILED  ] \");\n    PrintTestName(test_info.test_suite_name(), test_info.name());\n    PrintFullTestCommentIfPresent(test_info);\n\n    if (GTEST_FLAG_GET(print_time)) {\n      printf(\" (%s ms)\\n\",\n             internal::StreamableToString(test_info.result()->elapsed_time())\n                 .c_str());\n    } else {\n      printf(\"\\n\");\n    }\n    fflush(stdout);\n  }\n}\n\nvoid BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                    int /*iteration*/) {\n  ColoredPrintf(GTestColor::kGreen, \"[==========] \");\n  printf(\"%s from %s ran.\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());\n  if (GTEST_FLAG_GET(print_time)) {\n    printf(\" (%s ms total)\",\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\n  }\n  printf(\"\\n\");\n  ColoredPrintf(GTestColor::kGreen, \"[  PASSED  ] \");\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\n\n  const int skipped_test_count = unit_test.skipped_test_count();\n  if (skipped_test_count > 0) {\n    ColoredPrintf(GTestColor::kGreen, \"[  SKIPPED ] \");\n    printf(\"%s.\\n\", FormatTestCount(skipped_test_count).c_str());\n  }\n\n  int num_disabled = unit_test.reportable_disabled_test_count();\n  if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) {\n    if (unit_test.Passed()) {\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\n    }\n    ColoredPrintf(GTestColor::kYellow, \"  YOU HAVE %d DISABLED %s\\n\\n\",\n                  num_disabled, num_disabled == 1 ? \"TEST\" : \"TESTS\");\n  }\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\n  fflush(stdout);\n}\n\n// End BriefUnitTestResultPrinter\n\n// class TestEventRepeater\n//\n// This class forwards events to other event listeners.\nclass TestEventRepeater : public TestEventListener {\n public:\n  TestEventRepeater() : forwarding_enabled_(true) {}\n  ~TestEventRepeater() override;\n  void Append(TestEventListener* listener);\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled() const { return forwarding_enabled_; }\n  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }\n\n  void OnTestProgramStart(const UnitTest& parameter) override;\n  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;\n  void OnEnvironmentsSetUpStart(const UnitTest& parameter) override;\n  void OnEnvironmentsSetUpEnd(const UnitTest& parameter) override;\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseStart(const TestSuite& parameter) override;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestSuiteStart(const TestSuite& parameter) override;\n  void OnTestStart(const TestInfo& parameter) override;\n  void OnTestDisabled(const TestInfo& parameter) override;\n  void OnTestPartResult(const TestPartResult& parameter) override;\n  void OnTestEnd(const TestInfo& parameter) override;\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestCaseEnd(const TestCase& parameter) override;\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n  void OnTestSuiteEnd(const TestSuite& parameter) override;\n  void OnEnvironmentsTearDownStart(const UnitTest& parameter) override;\n  void OnEnvironmentsTearDownEnd(const UnitTest& parameter) override;\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void OnTestProgramEnd(const UnitTest& parameter) override;\n\n private:\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled_;\n  // The list of listeners that receive events.\n  std::vector<TestEventListener*> listeners_;\n\n  TestEventRepeater(const TestEventRepeater&) = delete;\n  TestEventRepeater& operator=(const TestEventRepeater&) = delete;\n};\n\nTestEventRepeater::~TestEventRepeater() {\n  ForEach(listeners_, Delete<TestEventListener>);\n}\n\nvoid TestEventRepeater::Append(TestEventListener* listener) {\n  listeners_.push_back(listener);\n}\n\nTestEventListener* TestEventRepeater::Release(TestEventListener* listener) {\n  for (size_t i = 0; i < listeners_.size(); ++i) {\n    if (listeners_[i] == listener) {\n      listeners_.erase(listeners_.begin() + static_cast<int>(i));\n      return listener;\n    }\n  }\n\n  return nullptr;\n}\n\n// Since most methods are very similar, use macros to reduce boilerplate.\n// This defines a member that forwards the call to all listeners.\n#define GTEST_REPEATER_METHOD_(Name, Type)              \\\n  void TestEventRepeater::Name(const Type& parameter) { \\\n    if (forwarding_enabled_) {                          \\\n      for (size_t i = 0; i < listeners_.size(); i++) {  \\\n        listeners_[i]->Name(parameter);                 \\\n      }                                                 \\\n    }                                                   \\\n  }\n// This defines a member that forwards the call to all listeners in reverse\n// order.\n#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type)      \\\n  void TestEventRepeater::Name(const Type& parameter) { \\\n    if (forwarding_enabled_) {                          \\\n      for (size_t i = listeners_.size(); i != 0; i--) { \\\n        listeners_[i - 1]->Name(parameter);             \\\n      }                                                 \\\n    }                                                   \\\n  }\n\nGTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)\nGTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)\nGTEST_REPEATER_METHOD_(OnTestStart, TestInfo)\nGTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo)\nGTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)\nGTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite)\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nGTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)\n\n#undef GTEST_REPEATER_METHOD_\n#undef GTEST_REVERSE_REPEATER_METHOD_\n\nvoid TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,\n                                             int iteration) {\n  if (forwarding_enabled_) {\n    for (size_t i = 0; i < listeners_.size(); i++) {\n      listeners_[i]->OnTestIterationStart(unit_test, iteration);\n    }\n  }\n}\n\nvoid TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,\n                                           int iteration) {\n  if (forwarding_enabled_) {\n    for (size_t i = listeners_.size(); i > 0; i--) {\n      listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration);\n    }\n  }\n}\n\n// End TestEventRepeater\n\n#if GTEST_HAS_FILE_SYSTEM\n// This class generates an XML output file.\nclass XmlUnitTestResultPrinter : public EmptyTestEventListener {\n public:\n  explicit XmlUnitTestResultPrinter(const char* output_file);\n\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n  void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites);\n\n  // Prints an XML summary of all unit tests.\n  static void PrintXmlTestsList(std::ostream* stream,\n                                const std::vector<TestSuite*>& test_suites);\n\n private:\n  // Is c a whitespace character that is normalized to a space character\n  // when it appears in an XML attribute value?\n  static bool IsNormalizableWhitespace(unsigned char c) {\n    return c == '\\t' || c == '\\n' || c == '\\r';\n  }\n\n  // May c appear in a well-formed XML document?\n  // https://www.w3.org/TR/REC-xml/#charsets\n  static bool IsValidXmlCharacter(unsigned char c) {\n    return IsNormalizableWhitespace(c) || c >= 0x20;\n  }\n\n  // Returns an XML-escaped copy of the input string str.  If\n  // is_attribute is true, the text is meant to appear as an attribute\n  // value, and normalizable whitespace is preserved by replacing it\n  // with character references.\n  static std::string EscapeXml(const std::string& str, bool is_attribute);\n\n  // Returns the given string with all characters invalid in XML removed.\n  static std::string RemoveInvalidXmlCharacters(const std::string& str);\n\n  // Convenience wrapper around EscapeXml when str is an attribute value.\n  static std::string EscapeXmlAttribute(const std::string& str) {\n    return EscapeXml(str, true);\n  }\n\n  // Convenience wrapper around EscapeXml when str is not an attribute value.\n  static std::string EscapeXmlText(const char* str) {\n    return EscapeXml(str, false);\n  }\n\n  // Verifies that the given attribute belongs to the given element and\n  // streams the attribute as XML.\n  static void OutputXmlAttribute(std::ostream* stream,\n                                 const std::string& element_name,\n                                 const std::string& name,\n                                 const std::string& value);\n\n  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\n  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);\n\n  // Streams a test suite XML stanza containing the given test result.\n  //\n  // Requires: result.Failed()\n  static void OutputXmlTestSuiteForTestResult(::std::ostream* stream,\n                                              const TestResult& result);\n\n  // Streams an XML representation of a TestResult object.\n  static void OutputXmlTestResult(::std::ostream* stream,\n                                  const TestResult& result);\n\n  // Streams an XML representation of a TestInfo object.\n  static void OutputXmlTestInfo(::std::ostream* stream,\n                                const char* test_suite_name,\n                                const TestInfo& test_info);\n\n  // Prints an XML representation of a TestSuite object\n  static void PrintXmlTestSuite(::std::ostream* stream,\n                                const TestSuite& test_suite);\n\n  // Prints an XML summary of unit_test to output stream out.\n  static void PrintXmlUnitTest(::std::ostream* stream,\n                               const UnitTest& unit_test);\n\n  // Produces a string representing the test properties in a result as space\n  // delimited XML attributes based on the property key=\"value\" pairs.\n  // When the std::string is not empty, it includes a space at the beginning,\n  // to delimit this attribute from prior attributes.\n  static std::string TestPropertiesAsXmlAttributes(const TestResult& result);\n\n  // Streams an XML representation of the test properties of a TestResult\n  // object.\n  static void OutputXmlTestProperties(std::ostream* stream,\n                                      const TestResult& result);\n\n  // The output file.\n  const std::string output_file_;\n\n  XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete;\n  XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter&) = delete;\n};\n\n// Creates a new XmlUnitTestResultPrinter.\nXmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)\n    : output_file_(output_file) {\n  if (output_file_.empty()) {\n    GTEST_LOG_(FATAL) << \"XML output file may not be null\";\n  }\n}\n\n// Called after the unit test ends.\nvoid XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                  int /*iteration*/) {\n  FILE* xmlout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintXmlUnitTest(&stream, unit_test);\n  fprintf(xmlout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(xmlout);\n}\n\nvoid XmlUnitTestResultPrinter::ListTestsMatchingFilter(\n    const std::vector<TestSuite*>& test_suites) {\n  FILE* xmlout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintXmlTestsList(&stream, test_suites);\n  fprintf(xmlout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(xmlout);\n}\n\n// Returns an XML-escaped copy of the input string str.  If is_attribute\n// is true, the text is meant to appear as an attribute value, and\n// normalizable whitespace is preserved by replacing it with character\n// references.\n//\n// Invalid XML characters in str, if any, are stripped from the output.\n// It is expected that most, if not all, of the text processed by this\n// module will consist of ordinary English text.\n// If this module is ever modified to produce version 1.1 XML output,\n// most invalid characters can be retained using character references.\nstd::string XmlUnitTestResultPrinter::EscapeXml(const std::string& str,\n                                                bool is_attribute) {\n  Message m;\n\n  for (size_t i = 0; i < str.size(); ++i) {\n    const char ch = str[i];\n    switch (ch) {\n      case '<':\n        m << \"&lt;\";\n        break;\n      case '>':\n        m << \"&gt;\";\n        break;\n      case '&':\n        m << \"&amp;\";\n        break;\n      case '\\'':\n        if (is_attribute)\n          m << \"&apos;\";\n        else\n          m << '\\'';\n        break;\n      case '\"':\n        if (is_attribute)\n          m << \"&quot;\";\n        else\n          m << '\"';\n        break;\n      default:\n        if (IsValidXmlCharacter(static_cast<unsigned char>(ch))) {\n          if (is_attribute &&\n              IsNormalizableWhitespace(static_cast<unsigned char>(ch)))\n            m << \"&#x\" << String::FormatByte(static_cast<unsigned char>(ch))\n              << \";\";\n          else\n            m << ch;\n        }\n        break;\n    }\n  }\n\n  return m.GetString();\n}\n\n// Returns the given string with all characters invalid in XML removed.\n// Currently invalid characters are dropped from the string. An\n// alternative is to replace them with certain characters such as . or ?.\nstd::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(\n    const std::string& str) {\n  std::string output;\n  output.reserve(str.size());\n  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)\n    if (IsValidXmlCharacter(static_cast<unsigned char>(*it)))\n      output.push_back(*it);\n\n  return output;\n}\n\n// The following routines generate an XML representation of a UnitTest\n// object.\n//\n// This is how Google Test concepts map to the DTD:\n//\n// <testsuites name=\"AllTests\">        <-- corresponds to a UnitTest object\n//   <testsuite name=\"testcase-name\">  <-- corresponds to a TestSuite object\n//     <testcase name=\"test-name\">     <-- corresponds to a TestInfo object\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//                                     <-- individual assertion failures\n//     </testcase>\n//   </testsuite>\n// </testsuites>\n\n// Formats the given time in milliseconds as seconds.\nstd::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {\n  ::std::stringstream ss;\n  // For the exact N seconds, makes sure output has a trailing decimal point.\n  // Sets precision so that we won't have many trailing zeros (e.g., 300 ms\n  // will be just 0.3, 410 ms 0.41, and so on)\n  ss << std::fixed\n     << std::setprecision(\n            ms % 1000 == 0 ? 0 : (ms % 100 == 0 ? 1 : (ms % 10 == 0 ? 2 : 3)))\n     << std::showpoint;\n  ss << (static_cast<double>(ms) * 1e-3);\n  return ss.str();\n}\n\nstatic bool PortableLocaltime(time_t seconds, struct tm* out) {\n#if defined(_MSC_VER)\n  return localtime_s(out, &seconds) == 0;\n#elif defined(__MINGW32__) || defined(__MINGW64__)\n  // MINGW <time.h> provides neither localtime_r nor localtime_s, but uses\n  // Windows' localtime(), which has a thread-local tm buffer.\n  struct tm* tm_ptr = localtime(&seconds);  // NOLINT\n  if (tm_ptr == nullptr) return false;\n  *out = *tm_ptr;\n  return true;\n#elif defined(__STDC_LIB_EXT1__)\n  // Uses localtime_s when available as localtime_r is only available from\n  // C23 standard.\n  return localtime_s(&seconds, out) != nullptr;\n#else\n  return localtime_r(&seconds, out) != nullptr;\n#endif\n}\n\n// Converts the given epoch time in milliseconds to a date string in the ISO\n// 8601 format, without the timezone information.\nstd::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {\n  struct tm time_struct;\n  if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))\n    return \"\";\n  // YYYY-MM-DDThh:mm:ss.sss\n  return StreamableToString(time_struct.tm_year + 1900) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mon + 1) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mday) + \"T\" +\n         String::FormatIntWidth2(time_struct.tm_hour) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_min) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_sec) + \".\" +\n         String::FormatIntWidthN(static_cast<int>(ms % 1000), 3);\n}\n\n// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\nvoid XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,\n                                                     const char* data) {\n  const char* segment = data;\n  *stream << \"<![CDATA[\";\n  for (;;) {\n    const char* const next_segment = strstr(segment, \"]]>\");\n    if (next_segment != nullptr) {\n      stream->write(segment,\n                    static_cast<std::streamsize>(next_segment - segment));\n      *stream << \"]]>]]&gt;<![CDATA[\";\n      segment = next_segment + strlen(\"]]>\");\n    } else {\n      *stream << segment;\n      break;\n    }\n  }\n  *stream << \"]]>\";\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlAttribute(\n    std::ostream* stream, const std::string& element_name,\n    const std::string& name, const std::string& value) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Attribute \" << name << \" is not allowed for element <\" << element_name\n      << \">.\";\n\n  *stream << \" \" << name << \"=\\\"\" << EscapeXmlAttribute(value) << \"\\\"\";\n}\n\n// Streams a test suite XML stanza containing the given test result.\nvoid XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(\n    ::std::ostream* stream, const TestResult& result) {\n  // Output the boilerplate for a minimal test suite with one test.\n  *stream << \"  <testsuite\";\n  OutputXmlAttribute(stream, \"testsuite\", \"name\", \"NonTestSuiteFailure\");\n  OutputXmlAttribute(stream, \"testsuite\", \"tests\", \"1\");\n  OutputXmlAttribute(stream, \"testsuite\", \"failures\", \"1\");\n  OutputXmlAttribute(stream, \"testsuite\", \"disabled\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"skipped\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"errors\", \"0\");\n  OutputXmlAttribute(stream, \"testsuite\", \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, \"testsuite\", \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n  *stream << \">\";\n\n  // Output the boilerplate for a minimal test case with a single test.\n  *stream << \"    <testcase\";\n  OutputXmlAttribute(stream, \"testcase\", \"name\", \"\");\n  OutputXmlAttribute(stream, \"testcase\", \"status\", \"run\");\n  OutputXmlAttribute(stream, \"testcase\", \"result\", \"completed\");\n  OutputXmlAttribute(stream, \"testcase\", \"classname\", \"\");\n  OutputXmlAttribute(stream, \"testcase\", \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, \"testcase\", \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n\n  // Output the actual test result.\n  OutputXmlTestResult(stream, result);\n\n  // Complete the test suite.\n  *stream << \"  </testsuite>\\n\";\n}\n\n// Prints an XML representation of a TestInfo object.\nvoid XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,\n                                                 const char* test_suite_name,\n                                                 const TestInfo& test_info) {\n  const TestResult& result = *test_info.result();\n  const std::string kTestsuite = \"testcase\";\n\n  if (test_info.is_in_another_shard()) {\n    return;\n  }\n\n  *stream << \"    <testcase\";\n  OutputXmlAttribute(stream, kTestsuite, \"name\", test_info.name());\n\n  if (test_info.value_param() != nullptr) {\n    OutputXmlAttribute(stream, kTestsuite, \"value_param\",\n                       test_info.value_param());\n  }\n  if (test_info.type_param() != nullptr) {\n    OutputXmlAttribute(stream, kTestsuite, \"type_param\",\n                       test_info.type_param());\n  }\n\n  OutputXmlAttribute(stream, kTestsuite, \"file\", test_info.file());\n  OutputXmlAttribute(stream, kTestsuite, \"line\",\n                     StreamableToString(test_info.line()));\n  if (GTEST_FLAG_GET(list_tests)) {\n    *stream << \" />\\n\";\n    return;\n  }\n\n  OutputXmlAttribute(stream, kTestsuite, \"status\",\n                     test_info.should_run() ? \"run\" : \"notrun\");\n  OutputXmlAttribute(stream, kTestsuite, \"result\",\n                     test_info.should_run()\n                         ? (result.Skipped() ? \"skipped\" : \"completed\")\n                         : \"suppressed\");\n  OutputXmlAttribute(stream, kTestsuite, \"time\",\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\n  OutputXmlAttribute(\n      stream, kTestsuite, \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));\n  OutputXmlAttribute(stream, kTestsuite, \"classname\", test_suite_name);\n\n  OutputXmlTestResult(stream, result);\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream,\n                                                   const TestResult& result) {\n  int failures = 0;\n  int skips = 0;\n  for (int i = 0; i < result.total_part_count(); ++i) {\n    const TestPartResult& part = result.GetTestPartResult(i);\n    if (part.failed()) {\n      if (++failures == 1 && skips == 0) {\n        *stream << \">\\n\";\n      }\n      const std::string location =\n          internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                          part.line_number());\n      const std::string summary = location + \"\\n\" + part.summary();\n      *stream << \"      <failure message=\\\"\" << EscapeXmlAttribute(summary)\n              << \"\\\" type=\\\"\\\">\";\n      const std::string detail = location + \"\\n\" + part.message();\n      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());\n      *stream << \"</failure>\\n\";\n    } else if (part.skipped()) {\n      if (++skips == 1 && failures == 0) {\n        *stream << \">\\n\";\n      }\n      const std::string location =\n          internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                          part.line_number());\n      const std::string summary = location + \"\\n\" + part.summary();\n      *stream << \"      <skipped message=\\\"\"\n              << EscapeXmlAttribute(summary.c_str()) << \"\\\">\";\n      const std::string detail = location + \"\\n\" + part.message();\n      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());\n      *stream << \"</skipped>\\n\";\n    }\n  }\n\n  if (failures == 0 && skips == 0 && result.test_property_count() == 0) {\n    *stream << \" />\\n\";\n  } else {\n    if (failures == 0 && skips == 0) {\n      *stream << \">\\n\";\n    }\n    OutputXmlTestProperties(stream, result);\n    *stream << \"    </testcase>\\n\";\n  }\n}\n\n// Prints an XML representation of a TestSuite object\nvoid XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,\n                                                 const TestSuite& test_suite) {\n  const std::string kTestsuite = \"testsuite\";\n  *stream << \"  <\" << kTestsuite;\n  OutputXmlAttribute(stream, kTestsuite, \"name\", test_suite.name());\n  OutputXmlAttribute(stream, kTestsuite, \"tests\",\n                     StreamableToString(test_suite.reportable_test_count()));\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputXmlAttribute(stream, kTestsuite, \"failures\",\n                       StreamableToString(test_suite.failed_test_count()));\n    OutputXmlAttribute(\n        stream, kTestsuite, \"disabled\",\n        StreamableToString(test_suite.reportable_disabled_test_count()));\n    OutputXmlAttribute(stream, kTestsuite, \"skipped\",\n                       StreamableToString(test_suite.skipped_test_count()));\n\n    OutputXmlAttribute(stream, kTestsuite, \"errors\", \"0\");\n\n    OutputXmlAttribute(stream, kTestsuite, \"time\",\n                       FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));\n    OutputXmlAttribute(\n        stream, kTestsuite, \"timestamp\",\n        FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));\n    *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());\n  }\n  *stream << \">\\n\";\n  for (int i = 0; i < test_suite.total_test_count(); ++i) {\n    if (test_suite.GetTestInfo(i)->is_reportable())\n      OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));\n  }\n  *stream << \"  </\" << kTestsuite << \">\\n\";\n}\n\n// Prints an XML summary of unit_test to output stream out.\nvoid XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,\n                                                const UnitTest& unit_test) {\n  const std::string kTestsuites = \"testsuites\";\n\n  *stream << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n  *stream << \"<\" << kTestsuites;\n\n  OutputXmlAttribute(stream, kTestsuites, \"tests\",\n                     StreamableToString(unit_test.reportable_test_count()));\n  OutputXmlAttribute(stream, kTestsuites, \"failures\",\n                     StreamableToString(unit_test.failed_test_count()));\n  OutputXmlAttribute(\n      stream, kTestsuites, \"disabled\",\n      StreamableToString(unit_test.reportable_disabled_test_count()));\n  OutputXmlAttribute(stream, kTestsuites, \"errors\", \"0\");\n  OutputXmlAttribute(stream, kTestsuites, \"time\",\n                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));\n  OutputXmlAttribute(\n      stream, kTestsuites, \"timestamp\",\n      FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));\n\n  if (GTEST_FLAG_GET(shuffle)) {\n    OutputXmlAttribute(stream, kTestsuites, \"random_seed\",\n                       StreamableToString(unit_test.random_seed()));\n  }\n  *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());\n\n  OutputXmlAttribute(stream, kTestsuites, \"name\", \"AllTests\");\n  *stream << \">\\n\";\n\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)\n      PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));\n  }\n\n  // If there was a test failure outside of one of the test suites (like in a\n  // test environment) include that in the output.\n  if (unit_test.ad_hoc_test_result().Failed()) {\n    OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());\n  }\n\n  *stream << \"</\" << kTestsuites << \">\\n\";\n}\n\nvoid XmlUnitTestResultPrinter::PrintXmlTestsList(\n    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {\n  const std::string kTestsuites = \"testsuites\";\n\n  *stream << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n  *stream << \"<\" << kTestsuites;\n\n  int total_tests = 0;\n  for (auto test_suite : test_suites) {\n    total_tests += test_suite->total_test_count();\n  }\n  OutputXmlAttribute(stream, kTestsuites, \"tests\",\n                     StreamableToString(total_tests));\n  OutputXmlAttribute(stream, kTestsuites, \"name\", \"AllTests\");\n  *stream << \">\\n\";\n\n  for (auto test_suite : test_suites) {\n    PrintXmlTestSuite(stream, *test_suite);\n  }\n  *stream << \"</\" << kTestsuites << \">\\n\";\n}\n\n// Produces a string representing the test properties in a result as space\n// delimited XML attributes based on the property key=\"value\" pairs.\nstd::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(\n    const TestResult& result) {\n  Message attributes;\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    attributes << \" \" << property.key() << \"=\" << \"\\\"\"\n               << EscapeXmlAttribute(property.value()) << \"\\\"\";\n  }\n  return attributes.GetString();\n}\n\nvoid XmlUnitTestResultPrinter::OutputXmlTestProperties(\n    std::ostream* stream, const TestResult& result) {\n  const std::string kProperties = \"properties\";\n  const std::string kProperty = \"property\";\n\n  if (result.test_property_count() <= 0) {\n    return;\n  }\n\n  *stream << \"      <\" << kProperties << \">\\n\";\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    *stream << \"        <\" << kProperty;\n    *stream << \" name=\\\"\" << EscapeXmlAttribute(property.key()) << \"\\\"\";\n    *stream << \" value=\\\"\" << EscapeXmlAttribute(property.value()) << \"\\\"\";\n    *stream << \"/>\\n\";\n  }\n  *stream << \"      </\" << kProperties << \">\\n\";\n}\n\n// End XmlUnitTestResultPrinter\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if GTEST_HAS_FILE_SYSTEM\n// This class generates an JSON output file.\nclass JsonUnitTestResultPrinter : public EmptyTestEventListener {\n public:\n  explicit JsonUnitTestResultPrinter(const char* output_file);\n\n  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;\n\n  // Prints an JSON summary of all unit tests.\n  static void PrintJsonTestList(::std::ostream* stream,\n                                const std::vector<TestSuite*>& test_suites);\n\n private:\n  // Returns an JSON-escaped copy of the input string str.\n  static std::string EscapeJson(const std::string& str);\n\n  //// Verifies that the given attribute belongs to the given element and\n  //// streams the attribute as JSON.\n  static void OutputJsonKey(std::ostream* stream,\n                            const std::string& element_name,\n                            const std::string& name, const std::string& value,\n                            const std::string& indent, bool comma = true);\n  static void OutputJsonKey(std::ostream* stream,\n                            const std::string& element_name,\n                            const std::string& name, int value,\n                            const std::string& indent, bool comma = true);\n\n  // Streams a test suite JSON stanza containing the given test result.\n  //\n  // Requires: result.Failed()\n  static void OutputJsonTestSuiteForTestResult(::std::ostream* stream,\n                                               const TestResult& result);\n\n  // Streams a JSON representation of a TestResult object.\n  static void OutputJsonTestResult(::std::ostream* stream,\n                                   const TestResult& result);\n\n  // Streams a JSON representation of a TestInfo object.\n  static void OutputJsonTestInfo(::std::ostream* stream,\n                                 const char* test_suite_name,\n                                 const TestInfo& test_info);\n\n  // Prints a JSON representation of a TestSuite object\n  static void PrintJsonTestSuite(::std::ostream* stream,\n                                 const TestSuite& test_suite);\n\n  // Prints a JSON summary of unit_test to output stream out.\n  static void PrintJsonUnitTest(::std::ostream* stream,\n                                const UnitTest& unit_test);\n\n  // Produces a string representing the test properties in a result as\n  // a JSON dictionary.\n  static std::string TestPropertiesAsJson(const TestResult& result,\n                                          const std::string& indent);\n\n  // The output file.\n  const std::string output_file_;\n\n  JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete;\n  JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrinter&) =\n      delete;\n};\n\n// Creates a new JsonUnitTestResultPrinter.\nJsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)\n    : output_file_(output_file) {\n  if (output_file_.empty()) {\n    GTEST_LOG_(FATAL) << \"JSON output file may not be null\";\n  }\n}\n\nvoid JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                   int /*iteration*/) {\n  FILE* jsonout = OpenFileForWriting(output_file_);\n  std::stringstream stream;\n  PrintJsonUnitTest(&stream, unit_test);\n  fprintf(jsonout, \"%s\", StringStreamToString(&stream).c_str());\n  fclose(jsonout);\n}\n\n// Returns an JSON-escaped copy of the input string str.\nstd::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {\n  Message m;\n\n  for (size_t i = 0; i < str.size(); ++i) {\n    const char ch = str[i];\n    switch (ch) {\n      case '\\\\':\n      case '\"':\n      case '/':\n        m << '\\\\' << ch;\n        break;\n      case '\\b':\n        m << \"\\\\b\";\n        break;\n      case '\\t':\n        m << \"\\\\t\";\n        break;\n      case '\\n':\n        m << \"\\\\n\";\n        break;\n      case '\\f':\n        m << \"\\\\f\";\n        break;\n      case '\\r':\n        m << \"\\\\r\";\n        break;\n      default:\n        if (ch < ' ') {\n          m << \"\\\\u00\" << String::FormatByte(static_cast<unsigned char>(ch));\n        } else {\n          m << ch;\n        }\n        break;\n    }\n  }\n\n  return m.GetString();\n}\n\n// The following routines generate an JSON representation of a UnitTest\n// object.\n\n// Formats the given time in milliseconds as seconds.\nstatic std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {\n  ::std::stringstream ss;\n  ss << (static_cast<double>(ms) * 1e-3) << \"s\";\n  return ss.str();\n}\n\n// Converts the given epoch time in milliseconds to a date string in the\n// RFC3339 format, without the timezone information.\nstatic std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {\n  struct tm time_struct;\n  if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))\n    return \"\";\n  // YYYY-MM-DDThh:mm:ss\n  return StreamableToString(time_struct.tm_year + 1900) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mon + 1) + \"-\" +\n         String::FormatIntWidth2(time_struct.tm_mday) + \"T\" +\n         String::FormatIntWidth2(time_struct.tm_hour) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_min) + \":\" +\n         String::FormatIntWidth2(time_struct.tm_sec) + \"Z\";\n}\n\nstatic inline std::string Indent(size_t width) {\n  return std::string(width, ' ');\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonKey(std::ostream* stream,\n                                              const std::string& element_name,\n                                              const std::string& name,\n                                              const std::string& value,\n                                              const std::string& indent,\n                                              bool comma) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Key \\\"\" << name << \"\\\" is not allowed for value \\\"\" << element_name\n      << \"\\\".\";\n\n  *stream << indent << \"\\\"\" << name << \"\\\": \\\"\" << EscapeJson(value) << \"\\\"\";\n  if (comma) *stream << \",\\n\";\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonKey(\n    std::ostream* stream, const std::string& element_name,\n    const std::string& name, int value, const std::string& indent, bool comma) {\n  const std::vector<std::string>& allowed_names =\n      GetReservedOutputAttributesForElement(element_name);\n\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\n               allowed_names.end())\n      << \"Key \\\"\" << name << \"\\\" is not allowed for value \\\"\" << element_name\n      << \"\\\".\";\n\n  *stream << indent << \"\\\"\" << name << \"\\\": \" << StreamableToString(value);\n  if (comma) *stream << \",\\n\";\n}\n\n// Streams a test suite JSON stanza containing the given test result.\nvoid JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(\n    ::std::ostream* stream, const TestResult& result) {\n  // Output the boilerplate for a new test suite.\n  *stream << Indent(4) << \"{\\n\";\n  OutputJsonKey(stream, \"testsuite\", \"name\", \"NonTestSuiteFailure\", Indent(6));\n  OutputJsonKey(stream, \"testsuite\", \"tests\", 1, Indent(6));\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputJsonKey(stream, \"testsuite\", \"failures\", 1, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"disabled\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"skipped\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"errors\", 0, Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"time\",\n                  FormatTimeInMillisAsDuration(result.elapsed_time()),\n                  Indent(6));\n    OutputJsonKey(stream, \"testsuite\", \"timestamp\",\n                  FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                  Indent(6));\n  }\n  *stream << Indent(6) << \"\\\"testsuite\\\": [\\n\";\n\n  // Output the boilerplate for a new test case.\n  *stream << Indent(8) << \"{\\n\";\n  OutputJsonKey(stream, \"testcase\", \"name\", \"\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"status\", \"RUN\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"result\", \"COMPLETED\", Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"time\",\n                FormatTimeInMillisAsDuration(result.elapsed_time()),\n                Indent(10));\n  OutputJsonKey(stream, \"testcase\", \"classname\", \"\", Indent(10), false);\n  *stream << TestPropertiesAsJson(result, Indent(10));\n\n  // Output the actual test result.\n  OutputJsonTestResult(stream, result);\n\n  // Finish the test suite.\n  *stream << \"\\n\" << Indent(6) << \"]\\n\" << Indent(4) << \"}\";\n}\n\n// Prints a JSON representation of a TestInfo object.\nvoid JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,\n                                                   const char* test_suite_name,\n                                                   const TestInfo& test_info) {\n  const TestResult& result = *test_info.result();\n  const std::string kTestsuite = \"testcase\";\n  const std::string kIndent = Indent(10);\n\n  *stream << Indent(8) << \"{\\n\";\n  OutputJsonKey(stream, kTestsuite, \"name\", test_info.name(), kIndent);\n\n  if (test_info.value_param() != nullptr) {\n    OutputJsonKey(stream, kTestsuite, \"value_param\", test_info.value_param(),\n                  kIndent);\n  }\n  if (test_info.type_param() != nullptr) {\n    OutputJsonKey(stream, kTestsuite, \"type_param\", test_info.type_param(),\n                  kIndent);\n  }\n\n  OutputJsonKey(stream, kTestsuite, \"file\", test_info.file(), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"line\", test_info.line(), kIndent, false);\n  if (GTEST_FLAG_GET(list_tests)) {\n    *stream << \"\\n\" << Indent(8) << \"}\";\n    return;\n  } else {\n    *stream << \",\\n\";\n  }\n\n  OutputJsonKey(stream, kTestsuite, \"status\",\n                test_info.should_run() ? \"RUN\" : \"NOTRUN\", kIndent);\n  OutputJsonKey(stream, kTestsuite, \"result\",\n                test_info.should_run()\n                    ? (result.Skipped() ? \"SKIPPED\" : \"COMPLETED\")\n                    : \"SUPPRESSED\",\n                kIndent);\n  OutputJsonKey(stream, kTestsuite, \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),\n                kIndent);\n  OutputJsonKey(stream, kTestsuite, \"time\",\n                FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"classname\", test_suite_name, kIndent,\n                false);\n  *stream << TestPropertiesAsJson(result, kIndent);\n\n  OutputJsonTestResult(stream, result);\n}\n\nvoid JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream,\n                                                     const TestResult& result) {\n  const std::string kIndent = Indent(10);\n\n  {\n    int failures = 0;\n    for (int i = 0; i < result.total_part_count(); ++i) {\n      const TestPartResult& part = result.GetTestPartResult(i);\n      if (part.failed()) {\n        *stream << \",\\n\";\n        if (++failures == 1) {\n          *stream << kIndent << \"\\\"\" << \"failures\" << \"\\\": [\\n\";\n        }\n        const std::string location =\n            internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                            part.line_number());\n        const std::string message =\n            EscapeJson(location + \"\\n\" + part.message());\n        *stream << kIndent << \"  {\\n\"\n                << kIndent << \"    \\\"failure\\\": \\\"\" << message << \"\\\",\\n\"\n                << kIndent << \"    \\\"type\\\": \\\"\\\"\\n\"\n                << kIndent << \"  }\";\n      }\n    }\n\n    if (failures > 0) *stream << \"\\n\" << kIndent << \"]\";\n  }\n\n  {\n    int skipped = 0;\n    for (int i = 0; i < result.total_part_count(); ++i) {\n      const TestPartResult& part = result.GetTestPartResult(i);\n      if (part.skipped()) {\n        *stream << \",\\n\";\n        if (++skipped == 1) {\n          *stream << kIndent << \"\\\"\" << \"skipped\" << \"\\\": [\\n\";\n        }\n        const std::string location =\n            internal::FormatCompilerIndependentFileLocation(part.file_name(),\n                                                            part.line_number());\n        const std::string message =\n            EscapeJson(location + \"\\n\" + part.message());\n        *stream << kIndent << \"  {\\n\"\n                << kIndent << \"    \\\"message\\\": \\\"\" << message << \"\\\"\\n\"\n                << kIndent << \"  }\";\n      }\n    }\n\n    if (skipped > 0) *stream << \"\\n\" << kIndent << \"]\";\n  }\n\n  *stream << \"\\n\" << Indent(8) << \"}\";\n}\n\n// Prints an JSON representation of a TestSuite object\nvoid JsonUnitTestResultPrinter::PrintJsonTestSuite(\n    std::ostream* stream, const TestSuite& test_suite) {\n  const std::string kTestsuite = \"testsuite\";\n  const std::string kIndent = Indent(6);\n\n  *stream << Indent(4) << \"{\\n\";\n  OutputJsonKey(stream, kTestsuite, \"name\", test_suite.name(), kIndent);\n  OutputJsonKey(stream, kTestsuite, \"tests\", test_suite.reportable_test_count(),\n                kIndent);\n  if (!GTEST_FLAG_GET(list_tests)) {\n    OutputJsonKey(stream, kTestsuite, \"failures\",\n                  test_suite.failed_test_count(), kIndent);\n    OutputJsonKey(stream, kTestsuite, \"disabled\",\n                  test_suite.reportable_disabled_test_count(), kIndent);\n    OutputJsonKey(stream, kTestsuite, \"errors\", 0, kIndent);\n    OutputJsonKey(\n        stream, kTestsuite, \"timestamp\",\n        FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),\n        kIndent);\n    OutputJsonKey(stream, kTestsuite, \"time\",\n                  FormatTimeInMillisAsDuration(test_suite.elapsed_time()),\n                  kIndent, false);\n    *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent)\n            << \",\\n\";\n  }\n\n  *stream << kIndent << \"\\\"\" << kTestsuite << \"\\\": [\\n\";\n\n  bool comma = false;\n  for (int i = 0; i < test_suite.total_test_count(); ++i) {\n    if (test_suite.GetTestInfo(i)->is_reportable()) {\n      if (comma) {\n        *stream << \",\\n\";\n      } else {\n        comma = true;\n      }\n      OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));\n    }\n  }\n  *stream << \"\\n\" << kIndent << \"]\\n\" << Indent(4) << \"}\";\n}\n\n// Prints a JSON summary of unit_test to output stream out.\nvoid JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,\n                                                  const UnitTest& unit_test) {\n  const std::string kTestsuites = \"testsuites\";\n  const std::string kIndent = Indent(2);\n  *stream << \"{\\n\";\n\n  OutputJsonKey(stream, kTestsuites, \"tests\", unit_test.reportable_test_count(),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"failures\", unit_test.failed_test_count(),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"disabled\",\n                unit_test.reportable_disabled_test_count(), kIndent);\n  OutputJsonKey(stream, kTestsuites, \"errors\", 0, kIndent);\n  if (GTEST_FLAG_GET(shuffle)) {\n    OutputJsonKey(stream, kTestsuites, \"random_seed\", unit_test.random_seed(),\n                  kIndent);\n  }\n  OutputJsonKey(stream, kTestsuites, \"timestamp\",\n                FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),\n                kIndent);\n  OutputJsonKey(stream, kTestsuites, \"time\",\n                FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,\n                false);\n\n  *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)\n          << \",\\n\";\n\n  OutputJsonKey(stream, kTestsuites, \"name\", \"AllTests\", kIndent);\n  *stream << kIndent << \"\\\"\" << kTestsuites << \"\\\": [\\n\";\n\n  bool comma = false;\n  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {\n    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) {\n      if (comma) {\n        *stream << \",\\n\";\n      } else {\n        comma = true;\n      }\n      PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i));\n    }\n  }\n\n  // If there was a test failure outside of one of the test suites (like in a\n  // test environment) include that in the output.\n  if (unit_test.ad_hoc_test_result().Failed()) {\n    if (comma) {\n      *stream << \",\\n\";\n    }\n    OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());\n  }\n\n  *stream << \"\\n\"\n          << kIndent << \"]\\n\"\n          << \"}\\n\";\n}\n\nvoid JsonUnitTestResultPrinter::PrintJsonTestList(\n    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {\n  const std::string kTestsuites = \"testsuites\";\n  const std::string kIndent = Indent(2);\n  *stream << \"{\\n\";\n  int total_tests = 0;\n  for (auto test_suite : test_suites) {\n    total_tests += test_suite->total_test_count();\n  }\n  OutputJsonKey(stream, kTestsuites, \"tests\", total_tests, kIndent);\n\n  OutputJsonKey(stream, kTestsuites, \"name\", \"AllTests\", kIndent);\n  *stream << kIndent << \"\\\"\" << kTestsuites << \"\\\": [\\n\";\n\n  for (size_t i = 0; i < test_suites.size(); ++i) {\n    if (i != 0) {\n      *stream << \",\\n\";\n    }\n    PrintJsonTestSuite(stream, *test_suites[i]);\n  }\n\n  *stream << \"\\n\"\n          << kIndent << \"]\\n\"\n          << \"}\\n\";\n}\n// Produces a string representing the test properties in a result as\n// a JSON dictionary.\nstd::string JsonUnitTestResultPrinter::TestPropertiesAsJson(\n    const TestResult& result, const std::string& indent) {\n  Message attributes;\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    attributes << \",\\n\"\n               << indent << \"\\\"\" << property.key() << \"\\\": \" << \"\\\"\"\n               << EscapeJson(property.value()) << \"\\\"\";\n  }\n  return attributes.GetString();\n}\n\n// End JsonUnitTestResultPrinter\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n#if GTEST_CAN_STREAM_RESULTS_\n\n// Checks if str contains '=', '&', '%' or '\\n' characters. If yes,\n// replaces them by \"%xx\" where xx is their hexadecimal value. For\n// example, replaces \"=\" with \"%3D\".  This algorithm is O(strlen(str))\n// in both time and space -- important as the input str may contain an\n// arbitrarily long test failure message and stack trace.\nstd::string StreamingListener::UrlEncode(const char* str) {\n  std::string result;\n  result.reserve(strlen(str) + 1);\n  for (char ch = *str; ch != '\\0'; ch = *++str) {\n    switch (ch) {\n      case '%':\n      case '=':\n      case '&':\n      case '\\n':\n        result.push_back('%');\n        result.append(String::FormatByte(static_cast<unsigned char>(ch)));\n        break;\n      default:\n        result.push_back(ch);\n        break;\n    }\n  }\n  return result;\n}\n\nvoid StreamingListener::SocketWriter::MakeConnection() {\n  GTEST_CHECK_(sockfd_ == -1)\n      << \"MakeConnection() can't be called when there is already a connection.\";\n\n  addrinfo hints;\n  memset(&hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;  // To allow both IPv4 and IPv6 addresses.\n  hints.ai_socktype = SOCK_STREAM;\n  addrinfo* servinfo = nullptr;\n\n  // Use the getaddrinfo() to get a linked list of IP addresses for\n  // the given host name.\n  const int error_num =\n      getaddrinfo(host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);\n  if (error_num != 0) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: getaddrinfo() failed: \"\n                        << gai_strerror(error_num);\n  }\n\n  // Loop through all the results and connect to the first we can.\n  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr;\n       cur_addr = cur_addr->ai_next) {\n    sockfd_ = socket(cur_addr->ai_family, cur_addr->ai_socktype,\n                     cur_addr->ai_protocol);\n    if (sockfd_ != -1) {\n      // Connect the client socket to the server socket.\n      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {\n        close(sockfd_);\n        sockfd_ = -1;\n      }\n    }\n  }\n\n  freeaddrinfo(servinfo);  // all done with this structure\n\n  if (sockfd_ == -1) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: failed to connect to \"\n                        << host_name_ << \":\" << port_num_;\n  }\n}\n\n// End of class Streaming Listener\n#endif  // GTEST_CAN_STREAM_RESULTS__\n\n// class OsStackTraceGetter\n\nconst char* const OsStackTraceGetterInterface::kElidedFramesMarker =\n    \"... \" GTEST_NAME_ \" internal frames ...\";\n\nstd::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n#ifdef GTEST_HAS_ABSL\n  std::string result;\n\n  if (max_depth <= 0) {\n    return result;\n  }\n\n  max_depth = std::min(max_depth, kMaxStackTraceDepth);\n\n  std::vector<void*> raw_stack(max_depth);\n  // Skips the frames requested by the caller, plus this function.\n  const int raw_stack_size =\n      absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1);\n\n  void* caller_frame = nullptr;\n  {\n    MutexLock lock(&mutex_);\n    caller_frame = caller_frame_;\n  }\n\n  for (int i = 0; i < raw_stack_size; ++i) {\n    if (raw_stack[i] == caller_frame &&\n        !GTEST_FLAG_GET(show_internal_stack_frames)) {\n      // Add a marker to the trace and stop adding frames.\n      absl::StrAppend(&result, kElidedFramesMarker, \"\\n\");\n      break;\n    }\n\n    char tmp[1024];\n    const char* symbol = \"(unknown)\";\n    if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) {\n      symbol = tmp;\n    }\n\n    char line[1024];\n    snprintf(line, sizeof(line), \"  %p: %s\\n\", raw_stack[i], symbol);\n    result += line;\n  }\n\n  return result;\n\n#else   // !GTEST_HAS_ABSL\n  static_cast<void>(max_depth);\n  static_cast<void>(skip_count);\n  return \"\";\n#endif  // GTEST_HAS_ABSL\n}\n\nvoid OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {\n#ifdef GTEST_HAS_ABSL\n  void* caller_frame = nullptr;\n  if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) {\n    caller_frame = nullptr;\n  }\n\n  MutexLock lock(&mutex_);\n  caller_frame_ = caller_frame;\n#endif  // GTEST_HAS_ABSL\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n// A helper class that creates the premature-exit file in its\n// constructor and deletes the file in its destructor.\nclass ScopedPrematureExitFile {\n public:\n  explicit ScopedPrematureExitFile(const char* premature_exit_filepath)\n      : premature_exit_filepath_(\n            premature_exit_filepath ? premature_exit_filepath : \"\") {\n    // If a path to the premature-exit file is specified...\n    if (!premature_exit_filepath_.empty()) {\n      // create the file with a single \"0\" character in it.  I/O\n      // errors are ignored as there's nothing better we can do and we\n      // don't want to fail the test because of this.\n      FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), \"w\");\n      fwrite(\"0\", 1, 1, pfile);\n      fclose(pfile);\n    }\n  }\n\n  ~ScopedPrematureExitFile() {\n#ifndef GTEST_OS_ESP8266\n    if (!premature_exit_filepath_.empty()) {\n      int retval = remove(premature_exit_filepath_.c_str());\n      if (retval) {\n        GTEST_LOG_(ERROR) << \"Failed to remove premature exit filepath \\\"\"\n                          << premature_exit_filepath_ << \"\\\" with error \"\n                          << retval;\n      }\n    }\n#endif\n  }\n\n private:\n  const std::string premature_exit_filepath_;\n\n  ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete;\n  ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete;\n};\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace internal\n\n// class TestEventListeners\n\nTestEventListeners::TestEventListeners()\n    : repeater_(new internal::TestEventRepeater()),\n      default_result_printer_(nullptr),\n      default_xml_generator_(nullptr) {}\n\nTestEventListeners::~TestEventListeners() { delete repeater_; }\n\n// Returns the standard listener responsible for the default console\n// output.  Can be removed from the listeners list to shut down default\n// console output.  Note that removing this object from the listener list\n// with Release transfers its ownership to the user.\nvoid TestEventListeners::Append(TestEventListener* listener) {\n  repeater_->Append(listener);\n}\n\n// Removes the given event listener from the list and returns it.  It then\n// becomes the caller's responsibility to delete the listener. Returns\n// NULL if the listener is not found in the list.\nTestEventListener* TestEventListeners::Release(TestEventListener* listener) {\n  if (listener == default_result_printer_)\n    default_result_printer_ = nullptr;\n  else if (listener == default_xml_generator_)\n    default_xml_generator_ = nullptr;\n  return repeater_->Release(listener);\n}\n\n// Returns repeater that broadcasts the TestEventListener events to all\n// subscribers.\nTestEventListener* TestEventListeners::repeater() { return repeater_; }\n\n// Sets the default_result_printer attribute to the provided listener.\n// The listener is also added to the listener list and previous\n// default_result_printer is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {\n  if (default_result_printer_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_result_printer_);\n    default_result_printer_ = listener;\n    if (listener != nullptr) Append(listener);\n  }\n}\n\n// Sets the default_xml_generator attribute to the provided listener.  The\n// listener is also added to the listener list and previous\n// default_xml_generator is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {\n  if (default_xml_generator_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_xml_generator_);\n    default_xml_generator_ = listener;\n    if (listener != nullptr) Append(listener);\n  }\n}\n\n// Controls whether events will be forwarded by the repeater to the\n// listeners in the list.\nbool TestEventListeners::EventForwardingEnabled() const {\n  return repeater_->forwarding_enabled();\n}\n\nvoid TestEventListeners::SuppressEventForwarding(bool suppress) {\n  repeater_->set_forwarding_enabled(!suppress);\n}\n\n// class UnitTest\n\n// Gets the singleton UnitTest object.  The first time this method is\n// called, a UnitTest object is constructed and returned.  Consecutive\n// calls will return the same object.\n//\n// We don't protect this under mutex_ as a user is not supposed to\n// call this before main() starts, from which point on the return\n// value will never change.\nUnitTest* UnitTest::GetInstance() {\n  // CodeGear C++Builder insists on a public destructor for the\n  // default implementation.  Use this implementation to keep good OO\n  // design with private destructor.\n\n#if defined(__BORLANDC__)\n  static UnitTest* const instance = new UnitTest;\n  return instance;\n#else\n  static UnitTest instance;\n  return &instance;\n#endif  // defined(__BORLANDC__)\n}\n\n// Gets the number of successful test suites.\nint UnitTest::successful_test_suite_count() const {\n  return impl()->successful_test_suite_count();\n}\n\n// Gets the number of failed test suites.\nint UnitTest::failed_test_suite_count() const {\n  return impl()->failed_test_suite_count();\n}\n\n// Gets the number of all test suites.\nint UnitTest::total_test_suite_count() const {\n  return impl()->total_test_suite_count();\n}\n\n// Gets the number of all test suites that contain at least one test\n// that should run.\nint UnitTest::test_suite_to_run_count() const {\n  return impl()->test_suite_to_run_count();\n}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nint UnitTest::successful_test_case_count() const {\n  return impl()->successful_test_suite_count();\n}\nint UnitTest::failed_test_case_count() const {\n  return impl()->failed_test_suite_count();\n}\nint UnitTest::total_test_case_count() const {\n  return impl()->total_test_suite_count();\n}\nint UnitTest::test_case_to_run_count() const {\n  return impl()->test_suite_to_run_count();\n}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Gets the number of successful tests.\nint UnitTest::successful_test_count() const {\n  return impl()->successful_test_count();\n}\n\n// Gets the number of skipped tests.\nint UnitTest::skipped_test_count() const {\n  return impl()->skipped_test_count();\n}\n\n// Gets the number of failed tests.\nint UnitTest::failed_test_count() const { return impl()->failed_test_count(); }\n\n// Gets the number of disabled tests that will be reported in the XML report.\nint UnitTest::reportable_disabled_test_count() const {\n  return impl()->reportable_disabled_test_count();\n}\n\n// Gets the number of disabled tests.\nint UnitTest::disabled_test_count() const {\n  return impl()->disabled_test_count();\n}\n\n// Gets the number of tests to be printed in the XML report.\nint UnitTest::reportable_test_count() const {\n  return impl()->reportable_test_count();\n}\n\n// Gets the number of all tests.\nint UnitTest::total_test_count() const { return impl()->total_test_count(); }\n\n// Gets the number of tests that should run.\nint UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }\n\n// Gets the time of the test program start, in ms from the start of the\n// UNIX epoch.\ninternal::TimeInMillis UnitTest::start_timestamp() const {\n  return impl()->start_timestamp();\n}\n\n// Gets the elapsed time, in milliseconds.\ninternal::TimeInMillis UnitTest::elapsed_time() const {\n  return impl()->elapsed_time();\n}\n\n// Returns true if and only if the unit test passed (i.e. all test suites\n// passed).\nbool UnitTest::Passed() const { return impl()->Passed(); }\n\n// Returns true if and only if the unit test failed (i.e. some test suite\n// failed or something outside of all tests failed).\nbool UnitTest::Failed() const { return impl()->Failed(); }\n\n// Gets the i-th test suite among all the test suites. i can range from 0 to\n// total_test_suite_count() - 1. If i is not in that range, returns NULL.\nconst TestSuite* UnitTest::GetTestSuite(int i) const {\n  return impl()->GetTestSuite(i);\n}\n\n//  Legacy API is deprecated but still available\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nconst TestCase* UnitTest::GetTestCase(int i) const {\n  return impl()->GetTestCase(i);\n}\n#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_\n\n// Returns the TestResult containing information on test failures and\n// properties logged outside of individual test suites.\nconst TestResult& UnitTest::ad_hoc_test_result() const {\n  return *impl()->ad_hoc_test_result();\n}\n\n// Gets the i-th test suite among all the test suites. i can range from 0 to\n// total_test_suite_count() - 1. If i is not in that range, returns NULL.\nTestSuite* UnitTest::GetMutableTestSuite(int i) {\n  return impl()->GetMutableSuiteCase(i);\n}\n\nvoid UnitTest::UponLeavingGTest() {\n  impl()->os_stack_trace_getter()->UponLeavingGTest();\n}\n\n// Sets the TestSuite object for the test that's currently running.\nvoid UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {\n  internal::MutexLock lock(&mutex_);\n  impl_->set_current_test_suite(a_current_test_suite);\n}\n\n// Sets the TestInfo object for the test that's currently running.\nvoid UnitTest::set_current_test_info(TestInfo* a_current_test_info) {\n  internal::MutexLock lock(&mutex_);\n  impl_->set_current_test_info(a_current_test_info);\n}\n\n// Returns the list of event listeners that can be used to track events\n// inside Google Test.\nTestEventListeners& UnitTest::listeners() { return *impl()->listeners(); }\n\n// Registers and returns a global test environment.  When a test\n// program is run, all global test environments will be set-up in the\n// order they were registered.  After all tests in the program have\n// finished, all global test environments will be torn-down in the\n// *reverse* order they were registered.\n//\n// The UnitTest object takes ownership of the given environment.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nEnvironment* UnitTest::AddEnvironment(Environment* env) {\n  if (env == nullptr) {\n    return nullptr;\n  }\n\n  impl_->environments().push_back(env);\n  return env;\n}\n\n// Adds a TestPartResult to the current TestResult object.  All Google Test\n// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call\n// this to report their results.  The user code should use the\n// assertion macros instead of calling this directly.\nvoid UnitTest::AddTestPartResult(TestPartResult::Type result_type,\n                                 const char* file_name, int line_number,\n                                 const std::string& message,\n                                 const std::string& os_stack_trace)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  Message msg;\n  msg << message;\n\n  internal::MutexLock lock(&mutex_);\n  if (!impl_->gtest_trace_stack().empty()) {\n    msg << \"\\n\" << GTEST_NAME_ << \" trace:\";\n\n    for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) {\n      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];\n      msg << \"\\n\"\n          << internal::FormatFileLocation(trace.file, trace.line) << \" \"\n          << trace.message;\n    }\n  }\n\n  if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) {\n    msg << internal::kStackTraceMarker << os_stack_trace;\n  } else {\n    msg << \"\\n\";\n  }\n\n  const TestPartResult result = TestPartResult(\n      result_type, file_name, line_number, msg.GetString().c_str());\n  impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(\n      result);\n\n  if (result_type != TestPartResult::kSuccess &&\n      result_type != TestPartResult::kSkip) {\n    // gtest_break_on_failure takes precedence over\n    // gtest_throw_on_failure.  This allows a user to set the latter\n    // in the code (perhaps in order to use Google Test assertions\n    // with another testing framework) and specify the former on the\n    // command line for debugging.\n    if (GTEST_FLAG_GET(break_on_failure)) {\n#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT)\n      // Using DebugBreak on Windows allows gtest to still break into a debugger\n      // when a failure happens and both the --gtest_break_on_failure and\n      // the --gtest_catch_exceptions flags are specified.\n      DebugBreak();\n#elif (!defined(__native_client__)) &&            \\\n    ((defined(__clang__) || defined(__GNUC__)) && \\\n     (defined(__x86_64__) || defined(__i386__)))\n      // with clang/gcc we can achieve the same effect on x86 by invoking int3\n      asm(\"int3\");\n#elif GTEST_HAS_BUILTIN(__builtin_trap)\n      __builtin_trap();\n#elif defined(SIGTRAP)\n      raise(SIGTRAP);\n#else\n      // Dereference nullptr through a volatile pointer to prevent the compiler\n      // from removing. We use this rather than abort() or __builtin_trap() for\n      // portability: some debuggers don't correctly trap abort().\n      *static_cast<volatile int*>(nullptr) = 1;\n#endif  // GTEST_OS_WINDOWS\n    } else if (GTEST_FLAG_GET(throw_on_failure)) {\n#if GTEST_HAS_EXCEPTIONS\n      throw internal::GoogleTestFailureException(result);\n#else\n      // We cannot call abort() as it generates a pop-up in debug mode\n      // that cannot be suppressed in VC 7.1 or below.\n      exit(1);\n#endif\n    }\n  }\n}\n\n// Adds a TestProperty to the current TestResult object when invoked from\n// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked\n// from SetUpTestSuite or TearDownTestSuite, or to the global property set\n// when invoked elsewhere.  If the result already contains a property with\n// the same key, the value will be updated.\nvoid UnitTest::RecordProperty(const std::string& key,\n                              const std::string& value) {\n  impl_->RecordProperty(TestProperty(key, value));\n}\n\n// Runs all tests in this UnitTest object and prints the result.\n// Returns 0 if successful, or 1 otherwise.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nint UnitTest::Run() {\n#ifdef GTEST_HAS_DEATH_TEST\n  const bool in_death_test_child_process =\n      !GTEST_FLAG_GET(internal_run_death_test).empty();\n\n  // Google Test implements this protocol for catching that a test\n  // program exits before returning control to Google Test:\n  //\n  //   1. Upon start, Google Test creates a file whose absolute path\n  //      is specified by the environment variable\n  //      TEST_PREMATURE_EXIT_FILE.\n  //   2. When Google Test has finished its work, it deletes the file.\n  //\n  // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before\n  // running a Google-Test-based test program and check the existence\n  // of the file at the end of the test execution to see if it has\n  // exited prematurely.\n\n  // If we are in the child process of a death test, don't\n  // create/delete the premature exit file, as doing so is unnecessary\n  // and will confuse the parent process.  Otherwise, create/delete\n  // the file upon entering/leaving this function.  If the program\n  // somehow exits before this function has a chance to return, the\n  // premature-exit file will be left undeleted, causing a test runner\n  // that understands the premature-exit-file protocol to report the\n  // test as having failed.\n  const internal::ScopedPrematureExitFile premature_exit_file(\n      in_death_test_child_process\n          ? nullptr\n          : internal::posix::GetEnv(\"TEST_PREMATURE_EXIT_FILE\"));\n#else\n  const bool in_death_test_child_process = false;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be\n  // used for the duration of the program.\n  impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions));\n\n#ifdef GTEST_OS_WINDOWS\n  // Either the user wants Google Test to catch exceptions thrown by the\n  // tests or this is executing in the context of death test child\n  // process. In either case the user does not want to see pop-up dialogs\n  // about crashes - they are expected.\n  if (impl()->catch_exceptions() || in_death_test_child_process) {\n#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \\\n    !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES)\n    // SetErrorMode doesn't exist on CE.\n    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |\n                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\n#endif  // !GTEST_OS_WINDOWS_MOBILE\n\n#if (defined(_MSC_VER) || defined(GTEST_OS_WINDOWS_MINGW)) && \\\n    !defined(GTEST_OS_WINDOWS_MOBILE)\n    // Death test children can be terminated with _abort().  On Windows,\n    // _abort() can show a dialog with a warning message.  This forces the\n    // abort message to go to stderr instead.\n    _set_error_mode(_OUT_TO_STDERR);\n#endif\n\n#if defined(_MSC_VER) && !defined(GTEST_OS_WINDOWS_MOBILE)\n    // In the debug version, Visual Studio pops up a separate dialog\n    // offering a choice to debug the aborted program. We need to suppress\n    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement\n    // executed. Google Test will notify the user of any unexpected\n    // failure via stderr.\n    if (!GTEST_FLAG_GET(break_on_failure))\n      _set_abort_behavior(\n          0x0,                                    // Clear the following flags:\n          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.\n\n    // In debug mode, the Windows CRT can crash with an assertion over invalid\n    // input (e.g. passing an invalid file descriptor).  The default handling\n    // for these assertions is to pop up a dialog and wait for user input.\n    // Instead ask the CRT to dump such assertions to stderr non-interactively.\n    if (!IsDebuggerPresent()) {\n      (void)_CrtSetReportMode(_CRT_ASSERT,\n                              _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n      (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);\n    }\n#endif\n  }\n#else\n  (void)in_death_test_child_process;  // Needed inside the #if block above\n#endif  // GTEST_OS_WINDOWS\n\n  return internal::HandleExceptionsInMethodIfSupported(\n             impl(), &internal::UnitTestImpl::RunAllTests,\n             \"auxiliary test code (environments or event listeners)\")\n             ? 0\n             : 1;\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Returns the working directory when the first TEST() or TEST_F() was\n// executed.\nconst char* UnitTest::original_working_dir() const {\n  return impl_->original_working_dir_.c_str();\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Returns the TestSuite object for the test that's currently running,\n// or NULL if no test is running.\nconst TestSuite* UnitTest::current_test_suite() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_suite();\n}\n\n// Legacy API is still available but deprecated\n#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_\nconst TestCase* UnitTest::current_test_case() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_suite();\n}\n#endif\n\n// Returns the TestInfo object for the test that's currently running,\n// or NULL if no test is running.\nconst TestInfo* UnitTest::current_test_info() const\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_info();\n}\n\n// Returns the random seed used at the start of the current test run.\nint UnitTest::random_seed() const { return impl_->random_seed(); }\n\n// Returns ParameterizedTestSuiteRegistry object used to keep track of\n// value-parameterized tests and instantiate and register them.\ninternal::ParameterizedTestSuiteRegistry&\nUnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) {\n  return impl_->parameterized_test_registry();\n}\n\n// Creates an empty UnitTest.\nUnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); }\n\n// Destructor of UnitTest.\nUnitTest::~UnitTest() { delete impl_; }\n\n// Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n// Google Test trace stack.\nvoid UnitTest::PushGTestTrace(const internal::TraceInfo& trace)\n    GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().push_back(trace);\n}\n\n// Pops a trace from the per-thread Google Test trace stack.\nvoid UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().pop_back();\n}\n\nnamespace internal {\n\nUnitTestImpl::UnitTestImpl(UnitTest* parent)\n    : parent_(parent),\n      GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)\n          default_global_test_part_result_reporter_(this),\n      default_per_thread_test_part_result_reporter_(this),\n      GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_reporter_(\n          &default_global_test_part_result_reporter_),\n      per_thread_test_part_result_reporter_(\n          &default_per_thread_test_part_result_reporter_),\n      parameterized_test_registry_(),\n      parameterized_tests_registered_(false),\n      last_death_test_suite_(-1),\n      current_test_suite_(nullptr),\n      current_test_info_(nullptr),\n      ad_hoc_test_result_(),\n      os_stack_trace_getter_(nullptr),\n      post_flag_parse_init_performed_(false),\n      random_seed_(0),  // Will be overridden by the flag before first use.\n      random_(0),       // Will be reseeded before first use.\n      start_timestamp_(0),\n      elapsed_time_(0),\n#ifdef GTEST_HAS_DEATH_TEST\n      death_test_factory_(new DefaultDeathTestFactory),\n#endif\n      // Will be overridden by the flag before first use.\n      catch_exceptions_(false) {\n  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);\n}\n\nUnitTestImpl::~UnitTestImpl() {\n  // Deletes every TestSuite.\n  ForEach(test_suites_, internal::Delete<TestSuite>);\n\n  // Deletes every Environment.\n  ForEach(environments_, internal::Delete<Environment>);\n\n  delete os_stack_trace_getter_;\n}\n\n// Adds a TestProperty to the current TestResult object when invoked in a\n// context of a test, to current test suite's ad_hoc_test_result when invoke\n// from SetUpTestSuite/TearDownTestSuite, or to the global property set\n// otherwise.  If the result already contains a property with the same key,\n// the value will be updated.\nvoid UnitTestImpl::RecordProperty(const TestProperty& test_property) {\n  std::string xml_element;\n  TestResult* test_result;  // TestResult appropriate for property recording.\n\n  if (current_test_info_ != nullptr) {\n    xml_element = \"testcase\";\n    test_result = &(current_test_info_->result_);\n  } else if (current_test_suite_ != nullptr) {\n    xml_element = \"testsuite\";\n    test_result = &(current_test_suite_->ad_hoc_test_result_);\n  } else {\n    xml_element = \"testsuites\";\n    test_result = &ad_hoc_test_result_;\n  }\n  test_result->RecordProperty(xml_element, test_property);\n}\n\n#ifdef GTEST_HAS_DEATH_TEST\n// Disables event forwarding if the control is currently in a death test\n// subprocess. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::SuppressTestEventsIfInSubprocess() {\n  if (internal_run_death_test_flag_ != nullptr)\n    listeners()->SuppressEventForwarding(true);\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Initializes event listeners performing XML output as specified by\n// UnitTestOptions. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureXmlOutput() {\n  const std::string& output_format = UnitTestOptions::GetOutputFormat();\n#if GTEST_HAS_FILE_SYSTEM\n  if (output_format == \"xml\") {\n    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(\n        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\n  } else if (output_format == \"json\") {\n    listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(\n        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\n  } else if (!output_format.empty()) {\n    GTEST_LOG_(WARNING) << \"WARNING: unrecognized output format \\\"\"\n                        << output_format << \"\\\" ignored.\";\n  }\n#else\n  if (!output_format.empty()) {\n    GTEST_LOG_(ERROR) << \"ERROR: alternative output formats require \"\n                      << \"GTEST_HAS_FILE_SYSTEM to be enabled\";\n  }\n#endif  // GTEST_HAS_FILE_SYSTEM\n}\n\n#if GTEST_CAN_STREAM_RESULTS_\n// Initializes event listeners for streaming test results in string form.\n// Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureStreamingOutput() {\n  const std::string& target = GTEST_FLAG_GET(stream_result_to);\n  if (!target.empty()) {\n    const size_t pos = target.find(':');\n    if (pos != std::string::npos) {\n      listeners()->Append(\n          new StreamingListener(target.substr(0, pos), target.substr(pos + 1)));\n    } else {\n      GTEST_LOG_(WARNING) << \"unrecognized streaming target \\\"\" << target\n                          << \"\\\" ignored.\";\n    }\n  }\n}\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n// Performs initialization dependent upon flag values obtained in\n// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n// this function is also called from RunAllTests.  Since this function can be\n// called more than once, it has to be idempotent.\nvoid UnitTestImpl::PostFlagParsingInit() {\n  // Ensures that this function does not execute more than once.\n  if (!post_flag_parse_init_performed_) {\n    post_flag_parse_init_performed_ = true;\n\n#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)\n    // Register to send notifications about key process state changes.\n    listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());\n#endif  // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)\n\n#ifdef GTEST_HAS_DEATH_TEST\n    InitDeathTestSubprocessControlInfo();\n    SuppressTestEventsIfInSubprocess();\n#endif  // GTEST_HAS_DEATH_TEST\n\n    // Registers parameterized tests. This makes parameterized tests\n    // available to the UnitTest reflection API without running\n    // RUN_ALL_TESTS.\n    RegisterParameterizedTests();\n\n    // Configures listeners for XML output. This makes it possible for users\n    // to shut down the default XML output before invoking RUN_ALL_TESTS.\n    ConfigureXmlOutput();\n\n    if (GTEST_FLAG_GET(brief)) {\n      listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter);\n    }\n\n#if GTEST_CAN_STREAM_RESULTS_\n    // Configures listeners for streaming test results to the specified server.\n    ConfigureStreamingOutput();\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n#ifdef GTEST_HAS_ABSL\n    if (GTEST_FLAG_GET(install_failure_signal_handler)) {\n      absl::FailureSignalHandlerOptions options;\n      absl::InstallFailureSignalHandler(options);\n    }\n#endif  // GTEST_HAS_ABSL\n  }\n}\n\n// Finds and returns a TestSuite with the given name.  If one doesn't\n// exist, creates one and returns it.  It's the CALLER'S\n// RESPONSIBILITY to ensure that this function is only called WHEN THE\n// TESTS ARE NOT SHUFFLED.\n//\n// Arguments:\n//\n//   test_suite_name: name of the test suite\n//   type_param:      the name of the test suite's type parameter, or NULL if\n//                    this is not a typed or a type-parameterized test suite.\n//   set_up_tc:       pointer to the function that sets up the test suite\n//   tear_down_tc:    pointer to the function that tears down the test suite\nTestSuite* UnitTestImpl::GetTestSuite(\n    const std::string& test_suite_name, const char* type_param,\n    internal::SetUpTestSuiteFunc set_up_tc,\n    internal::TearDownTestSuiteFunc tear_down_tc) {\n  // During initialization, all TestInfos for a given suite are added in\n  // sequence. To optimize this case, see if the most recently added suite is\n  // the one being requested now.\n  if (!test_suites_.empty() &&\n      (*test_suites_.rbegin())->name_ == test_suite_name) {\n    return *test_suites_.rbegin();\n  }\n\n  // Fall back to searching the collection.\n  auto item_it = test_suites_by_name_.find(test_suite_name);\n  if (item_it != test_suites_by_name_.end()) {\n    return item_it->second;\n  }\n\n  // Not found. Create a new instance.\n  auto* const new_test_suite =\n      new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);\n  test_suites_by_name_.emplace(test_suite_name, new_test_suite);\n\n  const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter);\n  // Is this a death test suite?\n  if (death_test_suite_filter.MatchesName(test_suite_name)) {\n    // Yes.  Inserts the test suite after the last death test suite\n    // defined so far.  This only works when the test suites haven't\n    // been shuffled.  Otherwise we may end up running a death test\n    // after a non-death test.\n    ++last_death_test_suite_;\n    test_suites_.insert(test_suites_.begin() + last_death_test_suite_,\n                        new_test_suite);\n  } else {\n    // No.  Appends to the end of the list.\n    test_suites_.push_back(new_test_suite);\n  }\n\n  test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size()));\n  return new_test_suite;\n}\n\n// Helpers for setting up / tearing down the given environment.  They\n// are for use in the ForEach() function.\nstatic void SetUpEnvironment(Environment* env) { env->SetUp(); }\nstatic void TearDownEnvironment(Environment* env) { env->TearDown(); }\n\n// Runs all tests in this UnitTest object, prints the result, and\n// returns true if all tests are successful.  If any exception is\n// thrown during a test, the test is considered to be failed, but the\n// rest of the tests will still be run.\n//\n// When parameterized tests are enabled, it expands and registers\n// parameterized tests first in RegisterParameterizedTests().\n// All other functions called from RunAllTests() may safely assume that\n// parameterized tests are ready to be counted and run.\nbool UnitTestImpl::RunAllTests() {\n  // True if and only if Google Test is initialized before RUN_ALL_TESTS() is\n  // called.\n  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();\n\n  // Do not run any test if the --help flag was specified.\n  if (g_help_flag) return true;\n\n  // Repeats the call to the post-flag parsing initialization in case the\n  // user didn't call InitGoogleTest.\n  PostFlagParsingInit();\n\n#if GTEST_HAS_FILE_SYSTEM\n  // Even if sharding is not on, test runners may want to use the\n  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding\n  // protocol.\n  internal::WriteToShardStatusFileIfNeeded();\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n  // True if and only if we are in a subprocess for running a thread-safe-style\n  // death test.\n  bool in_subprocess_for_death_test = false;\n\n#ifdef GTEST_HAS_DEATH_TEST\n  in_subprocess_for_death_test = (internal_run_death_test_flag_ != nullptr);\n#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)\n  if (in_subprocess_for_death_test) {\n    GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();\n  }\n#endif  // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)\n#endif  // GTEST_HAS_DEATH_TEST\n\n  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,\n                                        in_subprocess_for_death_test);\n\n  // Compares the full test names with the filter to decide which\n  // tests to run.\n  const bool has_tests_to_run =\n      FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL\n                               : IGNORE_SHARDING_PROTOCOL) > 0;\n\n  // Lists the tests and exits if the --gtest_list_tests flag was specified.\n  if (GTEST_FLAG_GET(list_tests)) {\n    // This must be called *after* FilterTests() has been called.\n    ListTestsMatchingFilter();\n    return true;\n  }\n\n  random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed));\n\n  // True if and only if at least one test has failed.\n  bool failed = false;\n\n  TestEventListener* repeater = listeners()->repeater();\n\n  start_timestamp_ = GetTimeInMillis();\n  repeater->OnTestProgramStart(*parent_);\n\n  // How many times to repeat the tests?  We don't want to repeat them\n  // when we are inside the subprocess of a death test.\n  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);\n\n  // Repeats forever if the repeat count is negative.\n  const bool gtest_repeat_forever = repeat < 0;\n\n  // Should test environments be set up and torn down for each repeat, or only\n  // set up on the first and torn down on the last iteration? If there is no\n  // \"last\" iteration because the tests will repeat forever, always recreate the\n  // environments to avoid leaks in case one of the environments is using\n  // resources that are external to this process. Without this check there would\n  // be no way to clean up those external resources automatically.\n  const bool recreate_environments_when_repeating =\n      GTEST_FLAG_GET(recreate_environments_when_repeating) ||\n      gtest_repeat_forever;\n\n  for (int i = 0; gtest_repeat_forever || i != repeat; i++) {\n    // We want to preserve failures generated by ad-hoc test\n    // assertions executed before RUN_ALL_TESTS().\n    ClearNonAdHocTestResult();\n\n    Timer timer;\n\n    // Shuffles test suites and tests if requested.\n    if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {\n      random()->Reseed(static_cast<uint32_t>(random_seed_));\n      // This should be done before calling OnTestIterationStart(),\n      // such that a test event listener can see the actual test order\n      // in the event.\n      ShuffleTests();\n    }\n\n    // Tells the unit test event listeners that the tests are about to start.\n    repeater->OnTestIterationStart(*parent_, i);\n\n    // Runs each test suite if there is at least one test to run.\n    if (has_tests_to_run) {\n      // Sets up all environments beforehand. If test environments aren't\n      // recreated for each iteration, only do so on the first iteration.\n      if (i == 0 || recreate_environments_when_repeating) {\n        repeater->OnEnvironmentsSetUpStart(*parent_);\n        ForEach(environments_, SetUpEnvironment);\n        repeater->OnEnvironmentsSetUpEnd(*parent_);\n      }\n\n      // Runs the tests only if there was no fatal failure or skip triggered\n      // during global set-up.\n      if (Test::IsSkipped()) {\n        // Emit diagnostics when global set-up calls skip, as it will not be\n        // emitted by default.\n        TestResult& test_result =\n            *internal::GetUnitTestImpl()->current_test_result();\n        for (int j = 0; j < test_result.total_part_count(); ++j) {\n          const TestPartResult& test_part_result =\n              test_result.GetTestPartResult(j);\n          if (test_part_result.type() == TestPartResult::kSkip) {\n            const std::string& result = test_part_result.message();\n            printf(\"%s\\n\", result.c_str());\n          }\n        }\n        fflush(stdout);\n      } else if (!Test::HasFatalFailure()) {\n        for (int test_index = 0; test_index < total_test_suite_count();\n             test_index++) {\n          GetMutableSuiteCase(test_index)->Run();\n          if (GTEST_FLAG_GET(fail_fast) &&\n              GetMutableSuiteCase(test_index)->Failed()) {\n            for (int j = test_index + 1; j < total_test_suite_count(); j++) {\n              GetMutableSuiteCase(j)->Skip();\n            }\n            break;\n          }\n        }\n      } else if (Test::HasFatalFailure()) {\n        // If there was a fatal failure during the global setup then we know we\n        // aren't going to run any tests. Explicitly mark all of the tests as\n        // skipped to make this obvious in the output.\n        for (int test_index = 0; test_index < total_test_suite_count();\n             test_index++) {\n          GetMutableSuiteCase(test_index)->Skip();\n        }\n      }\n\n      // Tears down all environments in reverse order afterwards. If test\n      // environments aren't recreated for each iteration, only do so on the\n      // last iteration.\n      if (i == repeat - 1 || recreate_environments_when_repeating) {\n        repeater->OnEnvironmentsTearDownStart(*parent_);\n        std::for_each(environments_.rbegin(), environments_.rend(),\n                      TearDownEnvironment);\n        repeater->OnEnvironmentsTearDownEnd(*parent_);\n      }\n    }\n\n    elapsed_time_ = timer.Elapsed();\n\n    // Tells the unit test event listener that the tests have just finished.\n    repeater->OnTestIterationEnd(*parent_, i);\n\n    // Gets the result and clears it.\n    if (!Passed()) {\n      failed = true;\n    }\n\n    // Restores the original test order after the iteration.  This\n    // allows the user to quickly repro a failure that happens in the\n    // N-th iteration without repeating the first (N - 1) iterations.\n    // This is not enclosed in \"if (GTEST_FLAG(shuffle)) { ... }\", in\n    // case the user somehow changes the value of the flag somewhere\n    // (it's always safe to unshuffle the tests).\n    UnshuffleTests();\n\n    if (GTEST_FLAG_GET(shuffle)) {\n      // Picks a new random seed for each iteration.\n      random_seed_ = GetNextRandomSeed(random_seed_);\n    }\n  }\n\n  repeater->OnTestProgramEnd(*parent_);\n  // Destroy environments in normal code, not in static teardown.\n  bool delete_environment_on_teardown = true;\n  if (delete_environment_on_teardown) {\n    ForEach(environments_, internal::Delete<Environment>);\n    environments_.clear();\n  }\n\n  if (!gtest_is_initialized_before_run_all_tests) {\n    ColoredPrintf(\n        GTestColor::kRed,\n        \"\\nIMPORTANT NOTICE - DO NOT IGNORE:\\n\"\n        \"This test program did NOT call \" GTEST_INIT_GOOGLE_TEST_NAME_\n        \"() before calling RUN_ALL_TESTS(). This is INVALID. Soon \" GTEST_NAME_\n        \" will start to enforce the valid usage. \"\n        \"Please fix it ASAP, or IT WILL START TO FAIL.\\n\");  // NOLINT\n  }\n\n  return !failed;\n}\n\n#if GTEST_HAS_FILE_SYSTEM\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded() {\n  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);\n  if (test_shard_file != nullptr) {\n    FILE* const file = posix::FOpen(test_shard_file, \"w\");\n    if (file == nullptr) {\n      ColoredPrintf(GTestColor::kRed,\n                    \"Could not write to the test shard status file \\\"%s\\\" \"\n                    \"specified by the %s environment variable.\\n\",\n                    test_shard_file, kTestShardStatusFile);\n      fflush(stdout);\n      exit(EXIT_FAILURE);\n    }\n    fclose(file);\n  }\n}\n#endif  // GTEST_HAS_FILE_SYSTEM\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (i.e., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nbool ShouldShard(const char* total_shards_env, const char* shard_index_env,\n                 bool in_subprocess_for_death_test) {\n  if (in_subprocess_for_death_test) {\n    return false;\n  }\n\n  const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1);\n  const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1);\n\n  if (total_shards == -1 && shard_index == -1) {\n    return false;\n  } else if (total_shards == -1 && shard_index != -1) {\n    const Message msg = Message() << \"Invalid environment variables: you have \"\n                                  << kTestShardIndex << \" = \" << shard_index\n                                  << \", but have left \" << kTestTotalShards\n                                  << \" unset.\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (total_shards != -1 && shard_index == -1) {\n    const Message msg = Message()\n                        << \"Invalid environment variables: you have \"\n                        << kTestTotalShards << \" = \" << total_shards\n                        << \", but have left \" << kTestShardIndex << \" unset.\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (shard_index < 0 || shard_index >= total_shards) {\n    const Message msg =\n        Message() << \"Invalid environment variables: we require 0 <= \"\n                  << kTestShardIndex << \" < \" << kTestTotalShards\n                  << \", but you have \" << kTestShardIndex << \"=\" << shard_index\n                  << \", \" << kTestTotalShards << \"=\" << total_shards << \".\\n\";\n    ColoredPrintf(GTestColor::kRed, \"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  }\n\n  return total_shards > 1;\n}\n\n// Parses the environment variable var as an Int32. If it is unset,\n// returns default_val. If it is not an Int32, prints an error\n// and aborts.\nint32_t Int32FromEnvOrDie(const char* var, int32_t default_val) {\n  const char* str_val = posix::GetEnv(var);\n  if (str_val == nullptr) {\n    return default_val;\n  }\n\n  int32_t result;\n  if (!ParseInt32(Message() << \"The value of environment variable \" << var,\n                  str_val, &result)) {\n    exit(EXIT_FAILURE);\n  }\n  return result;\n}\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true if and only if the test should be run on this shard. The test id\n// is some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nbool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {\n  return (test_id % total_shards) == shard_index;\n}\n\n// Compares the name of each test with the user-specified filter to\n// decide whether the test should be run, then records the result in\n// each TestSuite and TestInfo object.\n// If shard_tests == true, further filters tests based on sharding\n// variables in the environment - see\n// https://github.com/google/googletest/blob/main/docs/advanced.md\n// . Returns the number of tests that should run.\nint UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {\n  const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL\n                                   ? Int32FromEnvOrDie(kTestTotalShards, -1)\n                                   : -1;\n  const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL\n                                  ? Int32FromEnvOrDie(kTestShardIndex, -1)\n                                  : -1;\n\n  const PositiveAndNegativeUnitTestFilter gtest_flag_filter(\n      GTEST_FLAG_GET(filter));\n  const UnitTestFilter disable_test_filter(kDisableTestFilter);\n  // num_runnable_tests are the number of tests that will\n  // run across all shards (i.e., match filter and are not disabled).\n  // num_selected_tests are the number of tests to be run on\n  // this shard.\n  int num_runnable_tests = 0;\n  int num_selected_tests = 0;\n  for (auto* test_suite : test_suites_) {\n    const std::string& test_suite_name = test_suite->name_;\n    test_suite->set_should_run(false);\n\n    for (TestInfo* test_info : test_suite->test_info_list()) {\n      const std::string& test_name = test_info->name_;\n      // A test is disabled if test suite name or test name matches\n      // kDisableTestFilter.\n      const bool is_disabled =\n          disable_test_filter.MatchesName(test_suite_name) ||\n          disable_test_filter.MatchesName(test_name);\n      test_info->is_disabled_ = is_disabled;\n\n      const bool matches_filter =\n          gtest_flag_filter.MatchesTest(test_suite_name, test_name);\n      test_info->matches_filter_ = matches_filter;\n\n      const bool is_runnable =\n          (GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) &&\n          matches_filter;\n\n      const bool is_in_another_shard =\n          shard_tests != IGNORE_SHARDING_PROTOCOL &&\n          !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);\n      test_info->is_in_another_shard_ = is_in_another_shard;\n      const bool is_selected = is_runnable && !is_in_another_shard;\n\n      num_runnable_tests += is_runnable;\n      num_selected_tests += is_selected;\n\n      test_info->should_run_ = is_selected;\n      test_suite->set_should_run(test_suite->should_run() || is_selected);\n    }\n  }\n  return num_selected_tests;\n}\n\n// Prints the given C-string on a single line by replacing all '\\n'\n// characters with string \"\\\\n\".  If the output takes more than\n// max_length characters, only prints the first max_length characters\n// and \"...\".\nstatic void PrintOnOneLine(const char* str, int max_length) {\n  if (str != nullptr) {\n    for (int i = 0; *str != '\\0'; ++str) {\n      if (i >= max_length) {\n        printf(\"...\");\n        break;\n      }\n      if (*str == '\\n') {\n        printf(\"\\\\n\");\n        i += 2;\n      } else {\n        printf(\"%c\", *str);\n        ++i;\n      }\n    }\n  }\n}\n\n// Prints the names of the tests matching the user-specified filter flag.\nvoid UnitTestImpl::ListTestsMatchingFilter() {\n  // Print at most this many characters for each type/value parameter.\n  const int kMaxParamLength = 250;\n\n  for (auto* test_suite : test_suites_) {\n    bool printed_test_suite_name = false;\n\n    for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {\n      const TestInfo* const test_info = test_suite->test_info_list()[j];\n      if (test_info->matches_filter_) {\n        if (!printed_test_suite_name) {\n          printed_test_suite_name = true;\n          printf(\"%s.\", test_suite->name());\n          if (test_suite->type_param() != nullptr) {\n            printf(\"  # %s = \", kTypeParamLabel);\n            // We print the type parameter on a single line to make\n            // the output easy to parse by a program.\n            PrintOnOneLine(test_suite->type_param(), kMaxParamLength);\n          }\n          printf(\"\\n\");\n        }\n        printf(\"  %s\", test_info->name());\n        if (test_info->value_param() != nullptr) {\n          printf(\"  # %s = \", kValueParamLabel);\n          // We print the value parameter on a single line to make the\n          // output easy to parse by a program.\n          PrintOnOneLine(test_info->value_param(), kMaxParamLength);\n        }\n        printf(\"\\n\");\n      }\n    }\n  }\n  fflush(stdout);\n#if GTEST_HAS_FILE_SYSTEM\n  const std::string& output_format = UnitTestOptions::GetOutputFormat();\n  if (output_format == \"xml\" || output_format == \"json\") {\n    FILE* fileout =\n        OpenFileForWriting(UnitTestOptions::GetAbsolutePathToOutputFile());\n    std::stringstream stream;\n    if (output_format == \"xml\") {\n      XmlUnitTestResultPrinter(\n          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())\n          .PrintXmlTestsList(&stream, test_suites_);\n    } else if (output_format == \"json\") {\n      JsonUnitTestResultPrinter(\n          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())\n          .PrintJsonTestList(&stream, test_suites_);\n    }\n    fprintf(fileout, \"%s\", StringStreamToString(&stream).c_str());\n    fclose(fileout);\n  }\n#endif  // GTEST_HAS_FILE_SYSTEM\n}\n\n// Sets the OS stack trace getter.\n//\n// Does nothing if the input and the current OS stack trace getter are\n// the same; otherwise, deletes the old getter and makes the input the\n// current getter.\nvoid UnitTestImpl::set_os_stack_trace_getter(\n    OsStackTraceGetterInterface* getter) {\n  if (os_stack_trace_getter_ != getter) {\n    delete os_stack_trace_getter_;\n    os_stack_trace_getter_ = getter;\n  }\n}\n\n// Returns the current OS stack trace getter if it is not NULL;\n// otherwise, creates an OsStackTraceGetter, makes it the current\n// getter, and returns it.\nOsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {\n  if (os_stack_trace_getter_ == nullptr) {\n#ifdef GTEST_OS_STACK_TRACE_GETTER_\n    os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;\n#else\n    os_stack_trace_getter_ = new OsStackTraceGetter;\n#endif  // GTEST_OS_STACK_TRACE_GETTER_\n  }\n\n  return os_stack_trace_getter_;\n}\n\n// Returns the most specific TestResult currently running.\nTestResult* UnitTestImpl::current_test_result() {\n  if (current_test_info_ != nullptr) {\n    return &current_test_info_->result_;\n  }\n  if (current_test_suite_ != nullptr) {\n    return &current_test_suite_->ad_hoc_test_result_;\n  }\n  return &ad_hoc_test_result_;\n}\n\n// Shuffles all test suites, and the tests within each test suite,\n// making sure that death tests are still run first.\nvoid UnitTestImpl::ShuffleTests() {\n  // Shuffles the death test suites.\n  ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_);\n\n  // Shuffles the non-death test suites.\n  ShuffleRange(random(), last_death_test_suite_ + 1,\n               static_cast<int>(test_suites_.size()), &test_suite_indices_);\n\n  // Shuffles the tests inside each test suite.\n  for (auto& test_suite : test_suites_) {\n    test_suite->ShuffleTests(random());\n  }\n}\n\n// Restores the test suites and tests to their order before the first shuffle.\nvoid UnitTestImpl::UnshuffleTests() {\n  for (size_t i = 0; i < test_suites_.size(); i++) {\n    // Unshuffles the tests in each test suite.\n    test_suites_[i]->UnshuffleTests();\n    // Resets the index of each test suite.\n    test_suite_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Returns the current OS stack trace as an std::string.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nGTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string\nGetCurrentOsStackTraceExceptTop(int skip_count) {\n  // We pass skip_count + 1 to skip this wrapper function in addition\n  // to what the user really wants to skip.\n  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);\n}\n\n// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to\n// suppress unreachable code warnings.\nnamespace {\nclass ClassUniqueToAlwaysTrue {};\n}  // namespace\n\nbool IsTrue(bool condition) { return condition; }\n\nbool AlwaysTrue() {\n#if GTEST_HAS_EXCEPTIONS\n  // This condition is always false so AlwaysTrue() never actually throws,\n  // but it makes the compiler think that it may throw.\n  if (IsTrue(false)) throw ClassUniqueToAlwaysTrue();\n#endif  // GTEST_HAS_EXCEPTIONS\n  return true;\n}\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nbool SkipPrefix(const char* prefix, const char** pstr) {\n  const size_t prefix_len = strlen(prefix);\n  if (strncmp(*pstr, prefix, prefix_len) == 0) {\n    *pstr += prefix_len;\n    return true;\n  }\n  return false;\n}\n\n// Parses a string as a command line flag.  The string should have\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\n// part can be omitted.\n//\n// Returns the value of the flag, or NULL if the parsing failed.\nstatic const char* ParseFlagValue(const char* str, const char* flag_name,\n                                  bool def_optional) {\n  // str and flag must not be NULL.\n  if (str == nullptr || flag_name == nullptr) return nullptr;\n\n  // The flag must start with \"--\" followed by GTEST_FLAG_PREFIX_.\n  const std::string flag_str =\n      std::string(\"--\") + GTEST_FLAG_PREFIX_ + flag_name;\n  const size_t flag_len = flag_str.length();\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) {\n    return flag_end;\n  }\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return nullptr;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\n// Parses a string for a bool flag, in the form of either\n// \"--flag=value\" or \"--flag\".\n//\n// In the former case, the value is taken as true as long as it does\n// not start with '0', 'f', or 'F'.\n//\n// In the latter case, the value is taken as true.\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nstatic bool ParseFlag(const char* str, const char* flag_name, bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Converts the string value to a bool.\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\n  return true;\n}\n\n// Parses a string for an int32_t flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nbool ParseFlag(const char* str, const char* flag_name, int32_t* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(Message() << \"The value of flag --\" << flag_name, value_str,\n                    value);\n}\n\n// Parses a string for a string flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\ntemplate <typename String>\nstatic bool ParseFlag(const char* str, const char* flag_name, String* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag_name, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == nullptr) return false;\n\n  // Sets *value to the value of the flag.\n  *value = value_str;\n  return true;\n}\n\n// Determines whether a string has a prefix that Google Test uses for its\n// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.\n// If Google Test detects that a command line flag has its prefix but is not\n// recognized, it will print its help message. Flags starting with\n// GTEST_INTERNAL_PREFIX_ followed by \"internal_\" are considered Google Test\n// internal flags and do not trigger the help message.\nstatic bool HasGoogleTestFlagPrefix(const char* str) {\n  return (SkipPrefix(\"--\", &str) || SkipPrefix(\"-\", &str) ||\n          SkipPrefix(\"/\", &str)) &&\n         !SkipPrefix(GTEST_FLAG_PREFIX_ \"internal_\", &str) &&\n         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||\n          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));\n}\n\n// Prints a string containing code-encoded text.  The following escape\n// sequences can be used in the string to control the text color:\n//\n//   @@    prints a single '@' character.\n//   @R    changes the color to red.\n//   @G    changes the color to green.\n//   @Y    changes the color to yellow.\n//   @D    changes to the default terminal text color.\n//\nstatic void PrintColorEncoded(const char* str) {\n  GTestColor color = GTestColor::kDefault;  // The current color.\n\n  // Conceptually, we split the string into segments divided by escape\n  // sequences.  Then we print one segment at a time.  At the end of\n  // each iteration, the str pointer advances to the beginning of the\n  // next segment.\n  for (;;) {\n    const char* p = strchr(str, '@');\n    if (p == nullptr) {\n      ColoredPrintf(color, \"%s\", str);\n      return;\n    }\n\n    ColoredPrintf(color, \"%s\", std::string(str, p).c_str());\n\n    const char ch = p[1];\n    str = p + 2;\n    if (ch == '@') {\n      ColoredPrintf(color, \"@\");\n    } else if (ch == 'D') {\n      color = GTestColor::kDefault;\n    } else if (ch == 'R') {\n      color = GTestColor::kRed;\n    } else if (ch == 'G') {\n      color = GTestColor::kGreen;\n    } else if (ch == 'Y') {\n      color = GTestColor::kYellow;\n    } else {\n      --str;\n    }\n  }\n}\n\nstatic const char kColorEncodedHelpMessage[] =\n    \"This program contains tests written using \" GTEST_NAME_\n    \". You can use the\\n\"\n    \"following command line flags to control its behavior:\\n\"\n    \"\\n\"\n    \"Test Selection:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"list_tests@D\\n\"\n    \"      List the names of all tests instead of running them. The name of\\n\"\n    \"      TEST(Foo, Bar) is \\\"Foo.Bar\\\".\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"filter=@YPOSITIVE_PATTERNS\"\n    \"[@G-@YNEGATIVE_PATTERNS]@D\\n\"\n    \"      Run only the tests whose name matches one of the positive patterns \"\n    \"but\\n\"\n    \"      none of the negative patterns. '?' matches any single character; \"\n    \"'*'\\n\"\n    \"      matches any substring; ':' separates two patterns.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"also_run_disabled_tests@D\\n\"\n    \"      Run all disabled tests too.\\n\"\n    \"\\n\"\n    \"Test Execution:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"repeat=@Y[COUNT]@D\\n\"\n    \"      Run the tests repeatedly; use a negative count to repeat forever.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"shuffle@D\\n\"\n    \"      Randomize tests' orders on every iteration.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"random_seed=@Y[NUMBER]@D\\n\"\n    \"      Random number seed to use for shuffling test orders (between 1 and\\n\"\n    \"      99999, or 0 to use a seed based on the current time).\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"recreate_environments_when_repeating@D\\n\"\n    \"      Sets up and tears down the global test environment on each repeat\\n\"\n    \"      of the test.\\n\"\n    \"\\n\"\n    \"Test Output:\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\\n\"\n    \"      Enable/disable colored output. The default is @Gauto@D.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"brief=1@D\\n\"\n    \"      Only print test failures.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"print_time=0@D\\n\"\n    \"      Don't print the elapsed time of each test.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G\" GTEST_PATH_SEP_\n    \"@Y|@G:@YFILE_PATH]@D\\n\"\n    \"      Generate a JSON or XML report in the given directory or with the \"\n    \"given\\n\"\n    \"      file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\\n\"\n#if GTEST_CAN_STREAM_RESULTS_\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"stream_result_to=@YHOST@G:@YPORT@D\\n\"\n    \"      Stream test results to the given server.\\n\"\n#endif  // GTEST_CAN_STREAM_RESULTS_\n    \"\\n\"\n    \"Assertion Behavior:\\n\"\n#if defined(GTEST_HAS_DEATH_TEST) && !defined(GTEST_OS_WINDOWS)\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\\n\"\n    \"      Set the default death test style.\\n\"\n#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"break_on_failure@D\\n\"\n    \"      Turn assertion failures into debugger break-points.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"throw_on_failure@D\\n\"\n    \"      Turn assertion failures into C++ exceptions for use by an external\\n\"\n    \"      test framework.\\n\"\n    \"  @G--\" GTEST_FLAG_PREFIX_\n    \"catch_exceptions=0@D\\n\"\n    \"      Do not report exceptions as test failures. Instead, allow them\\n\"\n    \"      to crash the program or throw a pop-up (on Windows).\\n\"\n    \"\\n\"\n    \"Except for @G--\" GTEST_FLAG_PREFIX_\n    \"list_tests@D, you can alternatively set \"\n    \"the corresponding\\n\"\n    \"environment variable of a flag (all letters in upper-case). For example, \"\n    \"to\\n\"\n    \"disable colored text output, you can either specify \"\n    \"@G--\" GTEST_FLAG_PREFIX_\n    \"color=no@D or set\\n\"\n    \"the @G\" GTEST_FLAG_PREFIX_UPPER_\n    \"COLOR@D environment variable to @Gno@D.\\n\"\n    \"\\n\"\n    \"For more information, please read the \" GTEST_NAME_\n    \" documentation at\\n\"\n    \"@G\" GTEST_PROJECT_URL_ \"@D. If you find a bug in \" GTEST_NAME_\n    \"\\n\"\n    \"(not one in your own code or tests), please report it to\\n\"\n    \"@G<\" GTEST_DEV_EMAIL_ \">@D.\\n\";\n\nstatic bool ParseGoogleTestFlag(const char* const arg) {\n#define GTEST_INTERNAL_PARSE_FLAG(flag_name)  \\\n  do {                                        \\\n    auto value = GTEST_FLAG_GET(flag_name);   \\\n    if (ParseFlag(arg, #flag_name, &value)) { \\\n      GTEST_FLAG_SET(flag_name, value);       \\\n      return true;                            \\\n    }                                         \\\n  } while (false)\n\n  GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests);\n  GTEST_INTERNAL_PARSE_FLAG(break_on_failure);\n  GTEST_INTERNAL_PARSE_FLAG(catch_exceptions);\n  GTEST_INTERNAL_PARSE_FLAG(color);\n  GTEST_INTERNAL_PARSE_FLAG(death_test_style);\n  GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);\n  GTEST_INTERNAL_PARSE_FLAG(fail_fast);\n  GTEST_INTERNAL_PARSE_FLAG(filter);\n  GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);\n  GTEST_INTERNAL_PARSE_FLAG(list_tests);\n  GTEST_INTERNAL_PARSE_FLAG(output);\n  GTEST_INTERNAL_PARSE_FLAG(brief);\n  GTEST_INTERNAL_PARSE_FLAG(print_time);\n  GTEST_INTERNAL_PARSE_FLAG(print_utf8);\n  GTEST_INTERNAL_PARSE_FLAG(random_seed);\n  GTEST_INTERNAL_PARSE_FLAG(repeat);\n  GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating);\n  GTEST_INTERNAL_PARSE_FLAG(shuffle);\n  GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth);\n  GTEST_INTERNAL_PARSE_FLAG(stream_result_to);\n  GTEST_INTERNAL_PARSE_FLAG(throw_on_failure);\n  return false;\n}\n\n#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\nstatic void LoadFlagsFromFile(const std::string& path) {\n  FILE* flagfile = posix::FOpen(path.c_str(), \"r\");\n  if (!flagfile) {\n    GTEST_LOG_(FATAL) << \"Unable to open file \\\"\" << GTEST_FLAG_GET(flagfile)\n                      << \"\\\"\";\n  }\n  std::string contents(ReadEntireFile(flagfile));\n  posix::FClose(flagfile);\n  std::vector<std::string> lines;\n  SplitString(contents, '\\n', &lines);\n  for (size_t i = 0; i < lines.size(); ++i) {\n    if (lines[i].empty()) continue;\n    if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;\n  }\n}\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.  The type parameter CharType can be\n// instantiated to either char or wchar_t.\ntemplate <typename CharType>\nvoid ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {\n  std::string flagfile_value;\n  for (int i = 1; i < *argc; i++) {\n    const std::string arg_string = StreamableToString(argv[i]);\n    const char* const arg = arg_string.c_str();\n\n    using internal::ParseFlag;\n\n    bool remove_flag = false;\n    if (ParseGoogleTestFlag(arg)) {\n      remove_flag = true;\n#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n    } else if (ParseFlag(arg, \"flagfile\", &flagfile_value)) {\n      GTEST_FLAG_SET(flagfile, flagfile_value);\n      LoadFlagsFromFile(flagfile_value);\n      remove_flag = true;\n#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM\n    } else if (arg_string == \"--help\" || HasGoogleTestFlagPrefix(arg)) {\n      // Both help flag and unrecognized Google Test flags (excluding\n      // internal ones) trigger help display.\n      g_help_flag = true;\n    }\n\n    if (remove_flag) {\n      // Shift the remainder of the argv list left by one.\n      for (int j = i + 1; j < *argc; ++j) {\n        argv[j - 1] = argv[j];\n      }\n\n      // Decrements the argument count.\n      (*argc)--;\n\n      // Terminate the array with nullptr.\n      argv[*argc] = nullptr;\n\n      // We also need to decrement the iterator as we just removed\n      // an element.\n      i--;\n    }\n  }\n\n  if (g_help_flag) {\n    // We print the help here instead of in RUN_ALL_TESTS(), as the\n    // latter may not be called at all if the user is using Google\n    // Test with another testing framework.\n    PrintColorEncoded(kColorEncodedHelpMessage);\n  }\n}\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test. This function updates argc and argv by removing\n// flags that are known to GoogleTest (including other user flags defined using\n// ABSL_FLAG if GoogleTest is built with GTEST_USE_ABSL). Other arguments\n// remain in place. Unrecognized flags are not reported and do not cause the\n// program to exit.\nvoid ParseGoogleTestFlagsOnly(int* argc, char** argv) {\n#ifdef GTEST_HAS_ABSL_FLAGS\n  if (*argc <= 0) return;\n\n  std::vector<char*> positional_args;\n  std::vector<absl::UnrecognizedFlag> unrecognized_flags;\n  absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags);\n  absl::flat_hash_set<absl::string_view> unrecognized;\n  for (const auto& flag : unrecognized_flags) {\n    unrecognized.insert(flag.flag_name);\n  }\n  absl::flat_hash_set<char*> positional;\n  for (const auto& arg : positional_args) {\n    positional.insert(arg);\n  }\n\n  int out_pos = 1;\n  int in_pos = 1;\n  for (; in_pos < *argc; ++in_pos) {\n    char* arg = argv[in_pos];\n    absl::string_view arg_str(arg);\n    if (absl::ConsumePrefix(&arg_str, \"--\")) {\n      // Flag-like argument. If the flag was unrecognized, keep it.\n      // If it was a GoogleTest flag, remove it.\n      if (unrecognized.contains(arg_str)) {\n        argv[out_pos++] = argv[in_pos];\n        continue;\n      }\n    }\n\n    if (arg_str.empty()) {\n      ++in_pos;\n      break;  // '--' indicates that the rest of the arguments are positional\n    }\n\n    // Probably a positional argument. If it is in fact positional, keep it.\n    // If it was a value for the flag argument, remove it.\n    if (positional.contains(arg)) {\n      argv[out_pos++] = arg;\n    }\n  }\n\n  // The rest are positional args for sure.\n  while (in_pos < *argc) {\n    argv[out_pos++] = argv[in_pos++];\n  }\n\n  *argc = out_pos;\n  argv[out_pos] = nullptr;\n#else\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n#endif\n\n  // Fix the value of *_NSGetArgc() on macOS, but if and only if\n  // *_NSGetArgv() == argv\n  // Only applicable to char** version of argv\n#ifdef GTEST_OS_MAC\n#ifndef GTEST_OS_IOS\n  if (*_NSGetArgv() == argv) {\n    *_NSGetArgc() = *argc;\n  }\n#endif\n#endif\n}\nvoid ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n}\n\n// The internal implementation of InitGoogleTest().\n//\n// The type parameter CharType can be instantiated to either char or\n// wchar_t.\ntemplate <typename CharType>\nvoid InitGoogleTestImpl(int* argc, CharType** argv) {\n  // We don't want to run the initialization code twice.\n  if (GTestIsInitialized()) return;\n\n  if (*argc <= 0) return;\n\n  g_argvs.clear();\n  for (int i = 0; i != *argc; i++) {\n    g_argvs.push_back(StreamableToString(argv[i]));\n  }\n\n#ifdef GTEST_HAS_ABSL\n  absl::InitializeSymbolizer(g_argvs[0].c_str());\n\n#ifdef GTEST_HAS_ABSL_FLAGS\n  // When using the Abseil Flags library, set the program usage message to the\n  // help message, but remove the color-encoding from the message first.\n  absl::SetProgramUsageMessage(absl::StrReplaceAll(\n      kColorEncodedHelpMessage,\n      {{\"@D\", \"\"}, {\"@R\", \"\"}, {\"@G\", \"\"}, {\"@Y\", \"\"}, {\"@@\", \"@\"}}));\n#endif  // GTEST_HAS_ABSL_FLAGS\n#endif  // GTEST_HAS_ABSL\n\n  ParseGoogleTestFlagsOnly(argc, argv);\n  GetUnitTestImpl()->PostFlagParsingInit();\n}\n\n}  // namespace internal\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nvoid InitGoogleTest(int* argc, char** argv) {\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nvoid InitGoogleTest(int* argc, wchar_t** argv) {\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n// This overloaded version can be used on Arduino/embedded platforms where\n// there is no argc/argv.\nvoid InitGoogleTest() {\n  // Since Arduino doesn't have a command line, fake out the argc/argv arguments\n  int argc = 1;\n  const auto arg0 = \"dummy\";\n  char* argv0 = const_cast<char*>(arg0);\n  char** argv = &argv0;\n\n#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv);\n#else   // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n  internal::InitGoogleTestImpl(&argc, argv);\n#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)\n}\n\n#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) || \\\n    !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n// Returns the value of the first environment variable that is set and contains\n// a non-empty string. If there are none, returns the \"fallback\" string. Adds\n// the director-separator character as a suffix if not provided in the\n// environment variable value.\nstatic std::string GetDirFromEnv(\n    std::initializer_list<const char*> environment_variables,\n    const char* fallback, char separator) {\n  for (const char* variable_name : environment_variables) {\n    const char* value = internal::posix::GetEnv(variable_name);\n    if (value != nullptr && value[0] != '\\0') {\n      if (value[strlen(value) - 1] != separator) {\n        return std::string(value).append(1, separator);\n      }\n      return value;\n    }\n  }\n  return fallback;\n}\n#endif\n\nstd::string TempDir() {\n#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)\n  return GTEST_CUSTOM_TEMPDIR_FUNCTION_();\n#elif defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_WINDOWS_MOBILE)\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TEMP\"}, \"\\\\temp\\\\\", '\\\\');\n#elif defined(GTEST_OS_LINUX_ANDROID)\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TMPDIR\"}, \"/data/local/tmp/\", '/');\n#else\n  return GetDirFromEnv({\"TEST_TMPDIR\", \"TMPDIR\"}, \"/tmp/\", '/');\n#endif\n}\n\n#if GTEST_HAS_FILE_SYSTEM && !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n// Returns the directory path (including terminating separator) of the current\n// executable as derived from argv[0].\nstatic std::string GetCurrentExecutableDirectory() {\n  internal::FilePath argv_0(internal::GetArgvs()[0]);\n  return argv_0.RemoveFileName().string();\n}\n#endif\n\n#if GTEST_HAS_FILE_SYSTEM\nstd::string SrcDir() {\n#if defined(GTEST_CUSTOM_SRCDIR_FUNCTION_)\n  return GTEST_CUSTOM_SRCDIR_FUNCTION_();\n#elif defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_WINDOWS_MOBILE)\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '\\\\');\n#elif defined(GTEST_OS_LINUX_ANDROID)\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '/');\n#else\n  return GetDirFromEnv({\"TEST_SRCDIR\"}, GetCurrentExecutableDirectory().c_str(),\n                       '/');\n#endif\n}\n#endif\n\n// Class ScopedTrace\n\n// Pushes the given source file location and message onto a per-thread\n// trace stack maintained by Google Test.\nvoid ScopedTrace::PushTrace(const char* file, int line, std::string message) {\n  internal::TraceInfo trace;\n  trace.file = file;\n  trace.line = line;\n  trace.message.swap(message);\n\n  UnitTest::GetInstance()->PushGTestTrace(trace);\n}\n\n// Pops the info pushed by the c'tor.\nScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {\n  UnitTest::GetInstance()->PopGTestTrace();\n}\n\n}  // namespace testing\n"
  },
  {
    "path": "vendor/noa/vendor/googletest/googletest/src/gtest_main.cc",
    "content": "// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include <cstdio>\n\n#include \"gtest/gtest.h\"\n\n#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \\\n    (defined(GTEST_OS_NRF52) && defined(ARDUINO))\n// Arduino-like platforms: program entry points are setup/loop instead of main.\n\n#ifdef GTEST_OS_ESP8266\nextern \"C\" {\n#endif\n\nvoid setup() { testing::InitGoogleTest(); }\n\nvoid loop() { RUN_ALL_TESTS(); }\n\n#ifdef GTEST_OS_ESP8266\n}\n#endif\n\n#elif defined(GTEST_OS_QURT)\n// QuRT: program entry point is main, but argc/argv are unusable.\n\nGTEST_API_ int main() {\n  printf(\"Running main() from %s\\n\", __FILE__);\n  testing::InitGoogleTest();\n  return RUN_ALL_TESTS();\n}\n#else\n// Normal platforms: program entry point is main, argc/argv are initialized.\n\nGTEST_API_ int main(int argc, char **argv) {\n  printf(\"Running main() from %s\\n\", __FILE__);\n  testing::InitGoogleTest(&argc, argv);\n  return RUN_ALL_TESTS();\n}\n#endif\n"
  },
  {
    "path": "vendor/noa/vendor/vendorpull/LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    Vendorpull - A simple vendoring package manager\n    Copyright (C) 2024  Juan Cruz Viotti\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published\n    by the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "vendor/noa/vendor/vendorpull/pull",
    "content": "#!/bin/sh\n\nset -o errexit\nset -o nounset\n\nROOT=\"$(git rev-parse --show-toplevel)\"\nDEPENDENCIES=\"$ROOT/DEPENDENCIES\"\nVENDOR=\"$ROOT/vendor\"\nPATCHES=\"$ROOT/patches\"\n\nfail() {\n  echo \"$1\" 1>&2\n  exit 1\n}\n\nlog() {\n  echo \"-- $1\" 1>&2\n}\n\n# $1 = name\n# $2 = url\n# $3 = version\n# $4 = tmp\nvendor() {\n  # Cloning\n  log \"Fetching $2@$3 into $4/$1\"\n  git clone --recurse-submodules --jobs 8 \"$2\" \"$4/$1\"\n  git -C \"$4/$1\" reset --hard \"$3\"\n\n  # Patching\n  if [ -d \"$PATCHES/$1\" ]\n  then\n    for patch in \"$PATCHES/$1\"/*.patch\n    do\n      log \"Patching $1: $patch\"\n      git -C \"$4/$1\" apply --3way \"$patch\"\n    done\n  fi\n\n  # Pruning\n  log \"Pruning $4/$1\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .git\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitignore\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .github\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitmodules\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitattributes\"\n  rm -rf \"$4/$1/.git\"\n  rm -rf \"$4/$1/.gitignore\"\n  rm -rf \"$4/$1/.github\"\n  rm -rf \"$4/$1/.gitmodules\"\n  rm -rf \"$4/$1/.gitattributes\"\n\n  # Masking\n  if [ -f \"$VENDOR/$1.mask\" ]\n  then\n    while read -r path\n    do\n      log \"Masking $1: $path\"\n      rm -rf \"$4/$1/${path:?}\"\n    done < \"$VENDOR/$1.mask\"\n  elif [ -f \"$4/$1/vendorpull.mask\" ]\n  then\n    while read -r path\n    do\n      log \"Masking $1: $path\"\n      rm -rf \"$4/$1/${path:?}\"\n    done < \"$4/$1/vendorpull.mask\"\n    rm -f \"$4/$1/vendorpull.mask\"\n  fi\n\n  # Swap\n  log \"Moving $4/$1 to $VENDOR/$1\"\n  rm -rf \"$VENDOR/${1:?}\"\n  mkdir -p \"$VENDOR\"\n  mv \"$4/$1\" \"$VENDOR/$1\"\n}\n\nif [ ! -f \"$DEPENDENCIES\" ]\nthen\n  fail \"File not found: $DEPENDENCIES\"\nfi\n\nDEPENDENCY=\"${1-}\"\nif [ -n \"$DEPENDENCY\" ]\nthen\n  LINE=\"$(grep \"^$DEPENDENCY \" < \"$DEPENDENCIES\" || true)\"\n  if [ -z \"$LINE\" ]\n  then\n    fail \"Unknown dependency: $DEPENDENCY\"\n  fi\n  NAME=\"$(echo \"$LINE\" | cut -d ' ' -f 1)\"\n  URL=\"$(echo \"$LINE\" | cut -d ' ' -f 2)\"\n  VERSION=\"$(echo \"$LINE\" | cut -d ' ' -f 3)\"\n  if [ -z \"$NAME\" ] || [ -z \"$URL\" ] || [ -z \"$VERSION\" ]\n  then\n    fail \"Invalid dependency definition: $DEPENDENCY\"\n  fi\n\n  TMP=\"$(mktemp -d -t vendorpull-clone-XXXXX)\"\n  log \"Setting up temporary directory at $TMP...\"\n  clean() { rm -rf \"$TMP\"; }\n  trap clean EXIT\n\n  vendor \"$NAME\" \"$URL\" \"$VERSION\" \"$TMP\"\nelse\n  TMP=\"$(mktemp -d -t vendorpull-clone-XXXXX)\"\n  log \"Setting up temporary directory at $TMP...\"\n  clean() { rm -rf \"$TMP\"; }\n  trap clean EXIT\n\n  while read -r line\n  do\n    NAME=\"$(echo \"$line\" | cut -d ' ' -f 1)\"\n    URL=\"$(echo \"$line\" | cut -d ' ' -f 2)\"\n    VERSION=\"$(echo \"$line\" | cut -d ' ' -f 3)\"\n    if [ -z \"$NAME\" ] || [ -z \"$URL\" ] || [ -z \"$VERSION\" ]\n    then\n      fail \"Invalid dependency definition\"\n    fi\n\n    vendor \"$NAME\" \"$URL\" \"$VERSION\" \"$TMP\"\n  done < \"$DEPENDENCIES\"\nfi\n"
  },
  {
    "path": "vendor/vendorpull/LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    Vendorpull - A simple vendoring package manager\n    Copyright (C) 2024  Juan Cruz Viotti\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published\n    by the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "vendor/vendorpull/pull",
    "content": "#!/bin/sh\n\nset -o errexit\nset -o nounset\n\nROOT=\"$(git rev-parse --show-toplevel)\"\nDEPENDENCIES=\"$ROOT/DEPENDENCIES\"\nVENDOR=\"$ROOT/vendor\"\nPATCHES=\"$ROOT/patches\"\n\nfail() {\n  echo \"$1\" 1>&2\n  exit 1\n}\n\nlog() {\n  echo \"-- $1\" 1>&2\n}\n\n# $1 = name\n# $2 = url\n# $3 = version\n# $4 = tmp\nvendor() {\n  # Cloning\n  log \"Fetching $2@$3 into $4/$1\"\n  git clone --recurse-submodules --jobs 8 \"$2\" \"$4/$1\"\n  git -C \"$4/$1\" reset --hard \"$3\"\n\n  # Patching\n  if [ -d \"$PATCHES/$1\" ]\n  then\n    for patch in \"$PATCHES/$1\"/*.patch\n    do\n      log \"Patching $1: $patch\"\n      git -C \"$4/$1\" apply --3way \"$patch\"\n    done\n  fi\n\n  # Pruning\n  log \"Pruning $4/$1\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .git\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitignore\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .github\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitmodules\"\n  git -C \"$4/$1\" submodule foreach \"rm -rf .gitattributes\"\n  rm -rf \"$4/$1/.git\"\n  rm -rf \"$4/$1/.gitignore\"\n  rm -rf \"$4/$1/.github\"\n  rm -rf \"$4/$1/.gitmodules\"\n  rm -rf \"$4/$1/.gitattributes\"\n\n  OUTPUT=\"$VENDOR/$1\"\n\n  # Masking\n  if [ -f \"$OUTPUT.mask\" ]\n  then\n    while read -r path\n    do\n      log \"Masking $1: $path\"\n      rm -rf \"$4/$1/${path:?}\"\n    done < \"$OUTPUT.mask\"\n  elif [ -f \"$4/$1/vendorpull.mask\" ]\n  then\n    while read -r path\n    do\n      log \"Masking $1: $path\"\n      rm -rf \"$4/$1/${path:?}\"\n    done < \"$4/$1/vendorpull.mask\"\n    rm -f \"$4/$1/vendorpull.mask\"\n  fi\n\n  # Swap\n  log \"Moving $4/$1 to $OUTPUT\"\n  rm -rf \"$OUTPUT\"\n  mkdir -p \"$(dirname \"$OUTPUT\")\"\n  mv \"$4/$1\" \"$OUTPUT\"\n}\n\nif [ ! -f \"$DEPENDENCIES\" ]\nthen\n  fail \"File not found: $DEPENDENCIES\"\nfi\n\nDEPENDENCY=\"${1-}\"\nif [ -n \"$DEPENDENCY\" ]\nthen\n  LINE=\"$(grep \"^$DEPENDENCY \" < \"$DEPENDENCIES\" || true)\"\n  if [ -z \"$LINE\" ]\n  then\n    fail \"Unknown dependency: $DEPENDENCY\"\n  fi\n  NAME=\"$(echo \"$LINE\" | cut -d ' ' -f 1)\"\n\n  PULL_LOCATION=\"${2-}\"\n  if [ -n \"$PULL_LOCATION\" ]\n  then\n    URL=\"$PULL_LOCATION\"\n  else\n    URL=\"$(echo \"$LINE\" | cut -d ' ' -f 2)\"\n  fi\n\n  VERSION=\"$(echo \"$LINE\" | cut -d ' ' -f 3)\"\n  if [ -z \"$NAME\" ] || [ -z \"$URL\" ] || [ -z \"$VERSION\" ]\n  then\n    fail \"Invalid dependency definition: $DEPENDENCY\"\n  fi\n\n  TMP=\"$(mktemp -d -t vendorpull-clone-XXXXX)\"\n  log \"Setting up temporary directory at $TMP...\"\n  clean() { rm -rf \"$TMP\"; }\n  trap clean EXIT\n\n  vendor \"$NAME\" \"$URL\" \"$VERSION\" \"$TMP\"\nelse\n  TMP=\"$(mktemp -d -t vendorpull-clone-XXXXX)\"\n  log \"Setting up temporary directory at $TMP...\"\n  clean() { rm -rf \"$TMP\"; }\n  trap clean EXIT\n\n  while read -r line\n  do\n    NAME=\"$(echo \"$line\" | cut -d ' ' -f 1)\"\n    URL=\"$(echo \"$line\" | cut -d ' ' -f 2)\"\n    VERSION=\"$(echo \"$line\" | cut -d ' ' -f 3)\"\n    if [ -z \"$NAME\" ] || [ -z \"$URL\" ] || [ -z \"$VERSION\" ]\n    then\n      fail \"Invalid dependency definition\"\n    fi\n\n    vendor \"$NAME\" \"$URL\" \"$VERSION\" \"$TMP\"\n  done < \"$DEPENDENCIES\"\nfi\n"
  },
  {
    "path": "vendor/vendorpull/upgrade",
    "content": "#!/bin/sh\n\nset -o errexit\nset -o nounset\n\nROOT=\"$(git rev-parse --show-toplevel)\"\nDEPENDENCIES=\"$ROOT/DEPENDENCIES\"\n\nfail() {\n  echo \"$1\" 1>&2\n  exit 1\n}\n\nlog() {\n  echo \"-- $1\" 1>&2\n}\n\nif [ ! -f \"$DEPENDENCIES\" ]\nthen\n  fail \"File not found: $DEPENDENCIES\"\nfi\n\nDEPENDENCY=\"${1-}\"\nif [ -z \"$DEPENDENCY\" ]\nthen\n  fail \"Usage: $0 <dependency>\"\nfi\n\nLINE=\"$(grep \"^$DEPENDENCY \" < \"$DEPENDENCIES\" || true)\"\nif [ -z \"$LINE\" ]\nthen\n  fail \"Unknown dependency: $DEPENDENCY\"\nfi\n\nNAME=\"$(echo \"$LINE\" | cut -d ' ' -f 1)\"\nURL=\"$(echo \"$LINE\" | cut -d ' ' -f 2)\"\nVERSION=\"$(echo \"$LINE\" | cut -d ' ' -f 3)\"\nif [ -z \"$NAME\" ] || [ -z \"$URL\" ] || [ -z \"$VERSION\" ]\nthen\n  fail \"Invalid dependency definition: $DEPENDENCY\"\nfi\n\nTMP=\"$(mktemp -d -t vendorpull-clone-XXXXX)\"\nlog \"Setting up temporary directory at $TMP...\"\nclean() { rm -rf \"$TMP\"; }\ntrap clean EXIT\n\nlog \"Fetching the tip of $URL into $TMP/$NAME\"\ngit clone --depth 1 --jobs 8 \"$URL\" \"$TMP/$NAME\"\n\n# Try to determine the tag, otherwise the commit hash\nNEW_VERSION=\"$(git -C \"$TMP/$NAME\" describe --tags --exact-match HEAD 2>/dev/null \\\n  || git -C \"$TMP/$NAME\" rev-parse HEAD)\"\n\nlog \"Upgrading $NAME to $NEW_VERSION\"\nawk -v name=\"$NAME\" -v version=\"$NEW_VERSION\" \\\n  '$1 == name {$3 = version} {print}' \\\n  DEPENDENCIES > \"$TMP/DEPENDENCIES\"\n\nmv \"$TMP/DEPENDENCIES\" \"$DEPENDENCIES\"\ngit diff \"$DEPENDENCIES\"\n"
  },
  {
    "path": "vendorpull.mask",
    "content": "doxygen\nassets\nMakefile\nREADME.markdown\ntest\nvendor\nwww\n.editorconfig\n.ackrc\n.gitattributes\n.cirrus.yml\nBrewfile\nBrewfile.lock.json\n"
  }
]